diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..c00d15c --- /dev/null +++ b/build.sh @@ -0,0 +1,104 @@ +#!/bin/bash +set -e + +# Build script for PacmanXG on Arch Linux +# Requires: fpc, msegui (mseide-msegui) or msegui source + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# --- Check / install dependencies --- +echo "=== Checking dependencies ===" + +if ! command -v fpc &>/dev/null; then + echo "Free Pascal Compiler (fpc) not found. Installing..." + sudo pacman -S --needed --noconfirm fpc +fi + +# MSEgui: check common install locations +MSEDIR="" +for candidate in \ + /usr/lib/mseide-msegui \ + /usr/local/lib/mseide-msegui \ + /opt/mseide-msegui \ + "$PWD/mseide-msegui" \ + "$HOME/mseide-msegui" \ + "$HOME/msegui"; do + if [ -d "$candidate/lib" ]; then + MSEDIR="$candidate/" + break + fi +done + +if [ -z "$MSEDIR" ]; then + echo "MSEgui libraries not found." + echo "" + echo "Install via AUR (e.g. with yay):" + echo " yay -S mseide-msegui" + echo "" + echo "Or clone manually:" + echo " git clone https://gitlab.com/mseide-msegui/mseide-msegui.git ~/mseide-msegui" + echo "" + echo "Then re-run this script." + exit 1 +fi + +MSELIBDIR="${MSEDIR}lib/common/" +TARGETOSDIR="linux" + +echo "=== Using MSEgui at: ${MSEDIR} ===" +echo "=== MSELIBDIR: ${MSELIBDIR} ===" + +# --- Gather unit directories --- +# From the .prj file: +# ${MSEDIR}lib/addon/*/ +# ${MSELIBDIR}kernel/$TARGETOSDIR/ +# ${MSELIBDIR}kernel/ +# ${MSELIBDIR}*/ +UNIT_ARGS="" + +# ${MSEDIR}lib/addon/*/ +for d in "${MSEDIR}"lib/addon/*/; do + [ -d "$d" ] && UNIT_ARGS+=" -Fu${d}" +done + +# ${MSELIBDIR}kernel/linux/ +[ -d "${MSELIBDIR}kernel/${TARGETOSDIR}" ] && \ + UNIT_ARGS+=" -Fu${MSELIBDIR}kernel/${TARGETOSDIR}/" + +# ${MSELIBDIR}kernel/ +[ -d "${MSELIBDIR}kernel" ] && \ + UNIT_ARGS+=" -Fu${MSELIBDIR}kernel/" + +# ${MSELIBDIR}*/ +for d in "${MSELIBDIR}"*/; do + [ -d "$d" ] && UNIT_ARGS+=" -Fu${d}" +done + +# Include paths (same as unit paths) +INC_ARGS="" +for d in "${MSELIBDIR}"*/; do + [ -d "$d" ] && INC_ARGS+=" -Fi${d}" +done +[ -d "${MSELIBDIR}kernel/${TARGETOSDIR}" ] && \ + INC_ARGS+=" -Fi${MSELIBDIR}kernel/${TARGETOSDIR}/" +[ -d "${MSELIBDIR}kernel" ] && \ + INC_ARGS+=" -Fi${MSELIBDIR}kernel/" + +# --- Compile --- +echo "=== Compiling pacmanxg ===" + +cd "$SCRIPT_DIR" + +fpc \ + -Mobjfpc \ + -Sh \ + -Fcutf8 \ + -O2 -XX -Xs -CX \ + $UNIT_ARGS \ + $INC_ARGS \ + -Fu"$SCRIPT_DIR" \ + -Fi"$SCRIPT_DIR" \ + -o"${SCRIPT_DIR}/pacmanxg" \ + "${SCRIPT_DIR}/pacmanxg.pas" + +echo "=== Build successful: ${SCRIPT_DIR}/pacmanxg ===" diff --git a/main.mfm b/main.mfm index a19dc3a..b48d423 100755 --- a/main.mfm +++ b/main.mfm @@ -4409,7 +4409,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'News' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left captiondist = 0 imagelist = timagelist1 imagenr = 31 @@ -4433,7 +4433,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'Package Management' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left captiondist = 0 imagelist = timagelist1 imagenr = 27 @@ -4456,7 +4456,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'Tasks' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left captiondist = 0 imagelist = timagelist1 imagenr = 19 @@ -4523,7 +4523,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'Logs' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left captiondist = 0 imagelist = timagelist1 imagenr = 18 @@ -4547,7 +4547,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'Settings' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left imagelist = timagelist1 imagenr = 7 onexecute = on_navigate_menu @@ -4569,7 +4569,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'Pacman key management' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left captiondist = 0 imagelist = timagelist1 imagenr = 39 diff --git a/main.pas b/main.pas index 633efb5..9ba66ff 100755 --- a/main.pas +++ b/main.pas @@ -2451,8 +2451,7 @@ procedure tmainfo.on_run_util(const sender: TObject); begin cmd := (findcomponent('d' + (sender as trichbutton).name) as tdropdownlistedit).value; cmd := check_util_cmdline(cmd); - shell(cmd + ' &'); - //Exec(cmd, false); + Exec(cmd + ' &', false); end; diff --git a/msefiledialog.pas b/msefiledialog.pas index cc99e04..4bb88fc 100755 --- a/msefiledialog.pas +++ b/msefiledialog.pas @@ -14,7 +14,7 @@ interface uses - mseglob,mseguiglob,msegui,mseforms,Classes,mseclasses,msewidgets,msegrids, + mseglob,mseguiglob,msegui,mseforms,mseclasses,msewidgets,msegrids, mselistbrowser,mseedit,msesimplewidgets,msedataedits,msedialog,msetypes, msestrings,msesystypes,msesys,msedispwidgets,msedatalist,msestat,msestatfile, msebitmap,msedatanodes,msefileutils,msedropdownlist,mseevent,msegraphedits, @@ -75,7 +75,7 @@ tfilelistview = class(tlistview) // procedure setoptions(const Value: listviewoptionsty); override; procedure docellevent(var info: celleventinfoty); override; public - constructor create(aowner: tcomponent); override; + constructor create(aowner: tmsecomponent); destructor destroy; override; procedure readlist; procedure updir; @@ -231,8 +231,7 @@ tfiledialogcontroller = class(tlinkedpersistent) end; const - defaultfiledialogoptionsedit = defaultoptionsedit+ - [oe_savevalue,oe_savestate,oe_saveoptions]; + defaultfiledialogoptionsedit = [oe1_savevalue,oe1_savestate,oe1_saveoptions]; type tfiledialog = class(tdialog,istatfile) @@ -240,8 +239,9 @@ tfiledialog = class(tdialog,istatfile) fcontroller: tfiledialogcontroller; fstatvarname: msestring; fstatfile: tstatfile; + fstatpriority: integer; fdialogkind: filedialogkindty; - foptionsedit: optionseditty; + foptionsedit: optionsedit1ty; procedure setcontroller(const value: tfiledialogcontroller); procedure setstatfile(const Value: tstatfile); protected @@ -251,8 +251,9 @@ tfiledialog = class(tdialog,istatfile) procedure statreading; procedure statread; function getstatvarname: msestring; + function getstatpriority: integer; public - constructor create(aowner: tcomponent); override; + constructor create(aowner: tmsecomponent); destructor destroy; override; function execute: modalresultty; overload; override; function execute(const akind: filedialogkindty): modalresultty; @@ -267,7 +268,7 @@ tfiledialog = class(tdialog,istatfile) property controller: tfiledialogcontroller read fcontroller write setcontroller; property dialogkind: filedialogkindty read fdialogkind write fdialogkind default fdk_none; - property optionsedit: optionseditty read foptionsedit write foptionsedit + property optionsedit: optionsedit1ty read foptionsedit write foptionsedit default defaultfiledialogoptionsedit; end; @@ -302,7 +303,7 @@ tcustomfilenameedit = class(tcustomdialogstringed) procedure updatecopytoclipboard(var atext: msestring); override; procedure updatepastefromclipboard(var atext: msestring); override; public - constructor create(aowner: tcomponent); override; + constructor create(aowner: tmsecomponent); destructor destroy; override; procedure componentevent(const event: tcomponentevent); override; property controller: tfiledialogcontroller read fcontroller write setcontroller; @@ -463,7 +464,7 @@ implementation uses msefiledialog_mfm,sysutils,msebits, msestringenter,msedirtree,msefiledialogres,msekeyboard, - msestockobjects,msesysintf,msearrayutils; + msestockobjects,msesysintf,msearrayutils,Classes; procedure getfileicon(const info: fileinfoty; var imagelist: timagelist; out imagenr: integer); @@ -718,7 +719,7 @@ function filedialog(var afilename: filenamety; { tfilelistview } -constructor tfilelistview.create(aowner: tcomponent); +constructor tfilelistview.create(aowner: tmsecomponent); begin fcaseinsensitive:= filesystemiscaseinsensitive; fincludeattrib:= [fa_all]; @@ -727,7 +728,7 @@ constructor tfilelistview.create(aowner: tcomponent); foptionsfile:= defaultfilelistviewoptions; ffilelist:= tfiledatalist.create; ffilelist.onchange:= {$ifdef FPC}@{$endif}filelistchanged; - inherited; + inherited create(aowner); options:= defaultlistviewoptionsfile; checkcasesensitive; end; @@ -2093,11 +2094,11 @@ function tfiledialogcontroller.getsyscommandline: filenamety; { tfiledialog } -constructor tfiledialog.create(aowner: tcomponent); +constructor tfiledialog.create(aowner: tmsecomponent); begin foptionsedit:= defaultfiledialogoptionsedit; fcontroller:= tfiledialogcontroller.create(nil); - inherited; + inherited create(aowner); end; destructor tfiledialog.destroy; @@ -2158,6 +2159,11 @@ function tfiledialog.getstatvarname: msestring; result:= fstatvarname; end; +function tfiledialog.getstatpriority: integer; +begin + result:= fstatpriority; +end; + procedure tfiledialog.setstatfile(const Value: tstatfile); begin setstatfilevar(istatfile(self),value,fstatfile); @@ -2195,10 +2201,10 @@ function tfilenameeditcontroller.execute(var avalue: msestring): boolean; { tcustomfilenameedit } -constructor tcustomfilenameedit.create(aowner: tcomponent); +constructor tcustomfilenameedit.create(aowner: tmsecomponent); begin fcontroller:= tfiledialogcontroller.create(self,{$ifdef FPC}@{$endif}formatchanged); - inherited; + inherited create(aowner); end; destructor tcustomfilenameedit.destroy; diff --git a/mseide-msegui/.gitignore b/mseide-msegui/.gitignore new file mode 100644 index 0000000..7c3dae9 --- /dev/null +++ b/mseide-msegui/.gitignore @@ -0,0 +1,9 @@ +*.o +*.ppu +*.dcu +*.~* +*.a +*.bak +*.bak? +*.rst +*.rsj \ No newline at end of file diff --git a/mseide-msegui/COPYING.GPL b/mseide-msegui/COPYING.GPL new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/mseide-msegui/COPYING.GPL @@ -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/mseide-msegui/COPYING.LGPL b/mseide-msegui/COPYING.LGPL new file mode 100644 index 0000000..b1e3f5a --- /dev/null +++ b/mseide-msegui/COPYING.LGPL @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 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. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; 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. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/mseide-msegui/COPYING.MSE b/mseide-msegui/COPYING.MSE new file mode 100644 index 0000000..e2eff9b --- /dev/null +++ b/mseide-msegui/COPYING.MSE @@ -0,0 +1,23 @@ +This is the file COPYING.MSE, it applies to the MSEgui Library. + +The source code of the MSEgui Library is +distributed under the Library GNU General Public License +(see the file COPYING) with the following modification: + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent modules, +and to copy and distribute the resulting executable under terms of your choice, +provided that you also meet, for each linked independent module, the terms +and conditions of the license of that module. An independent module is a module +which is not derived from or based on this library. If you modify this +library, you may extend this exception to your version of the library, but you are +not obligated to do so. If you do not wish to do so, delete this exception +statement from your version. + +If you didn't receive a copy of the file COPYING, contact: + Free Software Foundation + 675 Mass Ave + Cambridge, MA 02139 + USA + diff --git a/mseide-msegui/DEBUG.TXT b/mseide-msegui/DEBUG.TXT new file mode 100644 index 0000000..bc5bb86 --- /dev/null +++ b/mseide-msegui/DEBUG.TXT @@ -0,0 +1,42 @@ +MSEide debugging +**************** +Breakpoints don't work on win32 in units compiled with -CX +(create smartlinked units). It is recommended to use mingw gdb 6.8+ on win32. +String and dynamic array variables of units compiled with +-gv (Valgrind debug info) are displayed incorrect. +gdb 6.5 has bugs with threads and forking on linux. Please update to gdb 6.6+. +FPC 2.2+ projects must be compiled with -O- (no optimization) for debugging. + +Tips from IvankoB: +------------------ + +In win-32, when debugging MSEide as a slave project run within master +MSEide, there're possible +uncontrollable breakpoints on pressing the F12 key (in MSEide, this key +toggles design/code view +for form, datamodules and reports). These breakpoints are caused by the +win-32 internal debug +facilities activated by the F12 key too. To release this key for MSEide, +there's a solution: + +- run the REGEDIT.exe + +- set   +"HKLM\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\AeDebug\UserDebuggerHotKey" +to 0x2F +(it's the scancode of VK_HELP which is not present on most PC keyboards ) + +- reboot + +In win-32, WRITELN called from within a program won't be printed in the IDE +internal console (because of some STDIO flushing issues on pipes) +unless the below code is inserted at beginning of the startup file +of the program: + +{$ifdef mswindows} +     TextRec(Output).FlushFunc:= TextRec(Output).InOutFunc; +{$endif} + +Also, You should place {$apptype console} compiler directive at beginning +of each unit calling WRITELN otherwise You may either encounter "File not +found" exception or to see silent nothing. \ No newline at end of file diff --git a/mseide-msegui/README.TXT b/mseide-msegui/README.TXT new file mode 100644 index 0000000..1ed363a --- /dev/null +++ b/mseide-msegui/README.TXT @@ -0,0 +1,390 @@ +MSEide+MSEgui Pascal Cross Platform GUI Development System. + +2018-11-03 Version 4.6.2 +Copyright (c) 1999-2018 by Martin Schreiber + +- Compiles with FPC 3.0.2 or 3.0.4 +- For FreeBSD-x86_64, Linux-i386, Linux-x86_64, Linux-arm(Raspberry Pi), + Windows-i386, Windows-x86_64. +- Links to xlib and gdi32, no external widget library needed. +- Internal character encoding is utf-16. +- Uses anti aliased fonts on Linux (Xft). +- All screen drawing is double buffered. +- Has docking forms and MDI. +- Has embedded forms (similar to TFrame). +- Has sophisticated database access components and data edit widgets. +- Internationalization functionality with resource modules. +- Report generator. + +IDE: +- Integrated debugging. +- Source code highlighting. +- Source code navigation with support for include files. +- Code completion for classes. +- Integrated visual form designer with source code update for components and + events. +- Flexible and handy build system with switchable macros. +- Visual form inheritance. +- Integrated report designer. + +License: +IDE and tools are under GPL, library under modified LGPL like FPC-RTL. +Package maintainers may delete the files "apps/ide/COPYING.GPL", +"lib/common/COPYING.LGPL" and "lib/common/COPYING.MSE". + +Installation: +************* +1. Download and install FPC 3.0.2 or 3.0.4, you can get it from + https://www.freepascal.org/download.var +2. Download mseide_msegui_src_4_6_2.zip and the mseide_* archive + for your system. + https://sourceforge.net/projects/mseide-msegui/files/mseide-msegui/4.6.2/ +3. Extract them to a directory of your choice ('yourdirectory') . +4. Run 'yourdirectory/bin/mseide' on Linux and FreeBSD or + 'yourdirectory\bin\mseide.exe' on windows. +5. In 'Settings'-'Configure MSEide'-'${MSEDIR}' select 'yourdirectory/msegui'. +6. In 'Project'-'Open' select 'yourdirectory/msegui/apps/demo/demo.prj'. +7. 'Target'-'Continue'. + +If you get the error "/usr/bin/ld: cannot find -lX11" install the +libX11-devel or libX11-dev package or make a symbolic link +/usr/lib/libX11.so -> /usr/lib/libX11.so.6 +see +https://bugs.freepascal.org/view.php?id=32367 + +If you wish to to compile the IDE: + +1. In 'Project'-'Open' select 'yourdirectory/msegui/apps/ide/mseide.prj'. +2. 'Target'-'Continue'. + +Compiling MSEide from commandline on Linux and FreeBSD: +fpc -Fulib/common/* -Fulib/common/kernel/linux apps/ide/mseide.pas +On Windows: +fpc -Fulib\common\* -Fulib\common\kernel\windows apps\ide\mseide.pas + +If FPC crashes while compiling try on Linux and FreeBSD: +fpc -B -Fulib/common/* -Fulib/common/kernel/linux apps/ide/mseide.pas +On Windows: +fpc -B -Fulib\common\* -Fulib\common\kernel\windows apps\ide\mseide.pas + +Creating a new GUI project +************************** +'Project'-'New'-'From Template', select "default.prj" + +Creating a new console project +****************************** +'Project'-'New'-'From Template', select "console.prj" + +MSEgui command line parameters +****************************** +--FONTALIAS=,[,[,[,[,] + [,]]]] + Change the used fonts. Example for a 16 pixel height default font: + --FONTALIAS=stf_default,,16 + +--NOZEROLINES + Use 1-width lines instead of 0-width lines. X11 only. Workaround for buggy HW-accelerated + X-servers which don't draw lineends exactly. Can degrade performance, see + https://bugzilla.opensuse.org/show_bug.cgi?id=1021803 + +--NOZORDERHANDLING + Do not touch Z-order of the windows. + +--NORESTACKWINDOW + Do not use the NET_RESTACK_WINDOW protocol. + +--RESTACKWINDOW + Use the NET_RESTACK_WINDOW protocol. + +--NORECONFIGUREWMWINDOW + Do not use xreconfigurewmwindow() for window stacking operation. + +--RECONFIGUREWMWINDOW + Use xreconfigurewmwindow() for window stacking operation. + +--STACKMODEBELOWWORKAROUND + Necessary for windowmanagers with buggy xreconfigurewmwindow() handling. + +--NOSTACKMODEBELOWWORKAROUND + No workaround. + +--TOPLEVELRAISE + Use the top level frame window id instead of the application client window id + for window raise operation. Implies --NORESTACKWINDOW and + --NORECONFIGUREWMWINDOW. + +--NOSTATICGRAVITY + Simulates staticgravity for buggy window managers. + +MSEide command line parameters +****************************** +-np + Do not load a project. + +-ns + Do not use a skin, no fades. + +--globstatfile= + Use instead the default global MSEide status file. + +--macrogroup= + Use 'Project'-'Options'-'Macros'-'Active group' number , = 1..6. + +--macrodef=,{,,} + Macro definition, will be overridden by 'Project'-'Options'-'Macros'. Example: + --macrodef=MAC1,abc,MAC2,def + defines ${MAC1} with value 'abc' and ${MAC2} with value 'def'. +--storeglobalmacros + Store --macrodef defines as global 'Settings'-'Configure MSEide' macros and + terminate MSEide. + +MSEide environment variables +**************************** +Macros in 'Settings'-'Configure MSEide' can be overridden by environment +variables. They will be overriden by --macrodef and 'Project'-'Options'-'Macros'. +Possible names: +FPCDIR, FPCLIBDIR, MSEDIR, MSELIBDIR, SYNTAXDEFDIR, TEMPLATEDIR, +COMPSTOREDIR, COMPILER, DEBUGGER, EXEEXT, TARGET, TARGETOSDIR. + +MSEide project macros +********************* +Predefined project macros: +PROJECTNAME, PROJECTDIR, MAINFILE, TARGETFILE, +TARGETENV (in format for "env" unix command), TARGETPARAMS, +they can be overridden by 'Project'-'Options'-'Macros'. + +MSEide macro functions +********************** +${MAC_IFDEF(macroname)} returns the macro value if defined. +${MAC_IFDEF(macroname,notdefinedvalue)} returns the macro value if defined, + notdefinedvalue otherwise. +${MAC_IFDEF(macroname,notdefinedvalue,definedvalue)} + returns definedvalue if macroname is defined, notdefinedvalue otherwise. + +MSEide environment macros +************************* +${ENV_VAR(variablename)} returns the variable value if defined. +${ENV_VAR(variablename,notdefinedvalue)} returns the variable value if defined, + notdefinedvalue otherwise. +${ENV_VAR(variablename,notdefinedvalue,definedvalue)} + returns definedvalue if variablename is defined, notdefinedvalue otherwise. + +MSEide string macros +******************** +Macro format is ${STR_*(text)}. +STR_TRIM + Trim whitespace from the ends of text. +STR_TRIMLEFT + Trim whitespace from the beginning of text. +STR_TRIMRIGHT + Trim whitespace from the end of text. + +STR_COALESCE + Return first not empty value. Format is + ${STR_COALESCE(text[,text...])} or + ${STR_COALESCE("text"[,"text"...])} + +MSEide file macros +****************** +Macro format is ${FILE_*(fileparameter)} or ${FILE_*("fileparameter")}. +FILE_MSE convert to MSE format. +FILE_SYS convert to sys format. +FILE_PATH absolute path. +FILE_FILE no trailing path delimiter. +FILE_DIR trailing path delimiter. +FILE_NAME no directory part. +FILE_NAMEBASE no directory and no name extension part. +FILE_EXT file name extension. +FILE_NONAME directory part only. +FILE_NOEXT no file name extension. + +MSEide exec macros +****************** +${EXEC_OUT(commandline[,timeoutms])} + Executes commandline, returns the process output. Timeout in + milli seconds, default = 1000, -1 = infinite. + +MSEide macros in 'Project'-'Options'-'Debugger'-'xterm Command' +*************************************************************** +${PTS} expands to tty pts path. +${PTSN} expands to tty pts number. +${PTSH} expands to tty pts handle. +Entering an empty string restores the default. + +MSEide external tools parameters macros +*************************************** +Predefined macros in 'Project'-'Options'-'Tools'-'Parameters': +CURSOURCEFILE current source file. +CURMODULEFILE current *.mfm file. +CURSSELECTION selected text in source editor. +CURSWORD word at cursor in source editor +CURSDEFINITION} definition of the current token at cursor + (Ctrl+LClick destination), needs activated P-column + (Parse source before call) to be current. +CURCOMPONENTCLASS current selected component class in form editor. +CURPROPERTY current selected property in object inspector. + +Antialiased text with MSEgui 32 bit on 64 bit Linux +**************************************************** +MSEgui uses Xft for antialiased fonts on Linux. Please install lib32-libxft +package if necessary. + +Popup widgets behind the forms +****************************** +If the popup widgets are showed behind the forms, try to start the +MSEgui program with the option '--TOPLEVELRAISE'. Do *not* use this option +if is not necessary (KDE, Gnome... work well without). + +Display problems with Linux radeon and other EXA drivers +******************************************************** +If the display is distorted or slow add +Option "EXAPixmaps" "off" +to +Section "Device" +of xorg.conf, see +https://bugs.freedesktop.org/show_bug.cgi?id=69543 +https://bugs.freedesktop.org/show_bug.cgi?id=84253 +or use the proprietary video driver for your video chip. + +Flashing taskbar widgets in IceWM +********************************* +Newer revisions of IceWM let the taskbar icons of MSEgui applications flash. +Start the MSEgui application with the option '--TOPLEVELRAISE'. + +Invalid inputmanager for Ubuntu +******************************* +The utf-8 setup in Ubuntu seems to be incomplete. If you get the exception +"egui : Invalid inputmanager tinternalapplication ." at program start, try to +replace your language locale in /usr/share/X11/locale/locale.dir +by en_US as a workaround. Example for ru_RU.UTF-8: +replace +ru_RU.UTF-8/XLC_LOCALE ru_RU.UTF-8 +by +en_US.UTF-8/XLC_LOCALE ru_RU.UTF-8 + +Wrong window positions for Ubuntu 14.04 +*************************************** +Window positions in Unity are wrong because the Ubuntu windowmanager +does not support static_gravity: +http://askubuntu.com/questions/451903/wingravity-static-gravity-not-suppo +https://bugs.launchpad.net/ubuntu/+bug/1312044 +http://askubuntu.com/questions/457456/wingravity-static-gravity-not-supported-in-14-04 + +How to add custom components to MSEide +************************************** +There is a project 'apps/myide/mymseide.prj' as a demo. +Start MSEide, open project 'apps/myide/mymseide.prj', 'Project'-'Build', +'Target'-'Continue', +the IDE with the new component 'tmybutton' will be compiled and +started in the the debugger. +Binary name is 'mymseide' (linux) or 'mymseide.exe' (win32). + +If you wish to do it from scratch: + +- Create a register unit for your components + (see 'apps/myide/regmycomps.pas' for an example). +- Enter the unitname followed by a comma + ('myregunit,' if your regunitfile is 'myregunit.pas') in + a file named 'regcomponents.inc'. +- Build the IDE with -dmorecomponents as option. + +Component units integrated by this mechanism don't need to be GPL, see +apps/ide/COPYING.IDE + +If you want to add custom icons to your components: + +- Convert 24*24 pixel BMP or PNG files with tools/bmp2pas to + an icon unit ('*_bmp.pas'). +- Add the name of the icon unit to 'uses' in your register unit. + +How to run i18ndemo +******************* +- Start MSEide. +- 'Project'-'Open'-'yourdirectory/msegui/apps/i18ndemo/i18ndemo.prj'. +- 'Project'-'Make' to create the rsj files. +- 'Project'-'Open'-'yourdirectory/msegui/tools/i18n/msei18n.prj'. +- 'Target'-'Continue'. +In MSEi18n: + - Adjust 'Settings'-'Configure MSEi18n'-'${MSEDIR}' and ${COMPILER}. + - 'Open'-'yourdirectory/msegui/apps/i18ndemo/i18ndemo.trp' + - 'Make'. + - Close message window. + - Close MSEi18n. +- 'Project'-'Open'-'yourdirectory/msegui/apps/i18ndemo/i18ndemo.prj'. +- 'Target'-'Continue'. + +SQLite +****** +tsqlite3connection field type mapping: + + Type name SQLite storage class Field type Data type ++--------------------+---------------------+-------------+-------------+ +| INTEGER or INT | INTEGER 4 | ftinteger | integer | +| LARGEINT | INTEGER 8 | ftlargeint | largeint | +| BIGINT | INTEGER 8 | ftlargeint | largeint | +| WORD | INTEGER 2 | ftword | word | +| SMALLINT | INTEGER 2 | ftsmallint | smallint | +| BOOLEAN | INTEGER 2 | ftboolean | wordbool | +| FLOAT[...] or REAL | REAL | ftfloat | double | +| or DOUBLE[...] | | | | +| CURRENCY | REAL | ftcurrency | double! | +| DATETIME or | REAL | ftdatetime | tdatetime | +| TIMESTAMP | | | | +| DATE | REAL | ftdate | tdatetime | +| TIME | REAL | fttime | tdatetime | +| NUMERIC[...] | INTEGER 8 (*10'000) | ftbcd | currency | +| VARCHAR[(n)] | TEXT | ftstring | msestring | +| TEXT | TEXT | ftmemo | utf8 string | +| TEXT | TEXT dso_stringmemo | ftstring | msestring | +| BLOB | BLOB | ftblob | string | ++--------------------+---------------------+-------------+-------------+ + +ZeosLib +******* +In order to install the Zeos components add the path to the Zeos source to +'Project'-'Options'-'Make'-'Directories' and compile the IDE with +-dmse_with_zeoslib -dMSEgui. +There is a predefined IDE project apps/ide/mseide_zeos.prj, update 'Project'- +'Options'-'Macros' according to your installation. + +Crosscompiling and remote debugging i386/x84_64-linux -> arm-linux +*********************************************************** +For Raspberry Pi: +- Establish a ssh login without password (public key authentication). + +On the i386/x84_64-linux host: +- install the scp program +- download and extract + https://sourceforge.net/projects/mseide-msegui/files/fpcrossarm/crossfpc-i386_linux_eabihf_3_0_5.tar.gz + (or crossfpc-x86_64_linux_eabihf_3_0_5.tar.gz) + to . + +- Start MSEide, in 'Settings'-'Configure MSEide'-'Global Macros' add: + +Name Value + +CROSSMSEDIR +CROSSFPCDIR +CROSSFPCVERSION 3.0.5 +HOSTIP +REMOTEIP +REMOTEPORT +REMOTEUSER pi + +- 'Project'-'New'-'From Template', select "crossarmdefault.prj" or + "crossarmconsole.prj". +- Create the new project. +- 'Project'-'Options'-'Macros', set the TARGETPROJECTDIR value to the project + path in remote target, ex: "/home/pi/proj/testcase". +- Check the TARGETENV macro. +- If your application needs additional libraries copy them from Raspberry Pi + /lib/arm-linux-gnueabihf or /usr/lib/arm-linux-gnueabihf to + /eabihf/lib + +Press F9 and hope the best. ;-) +If there is a debugger timeout at startup enlarge the +'Project'-'Options'-'Target'-'Wait before connect' value. + +Have a lot of fun! + +Martin diff --git a/mseide-msegui/VERSION.TXT b/mseide-msegui/VERSION.TXT new file mode 100644 index 0000000..929c3d3 --- /dev/null +++ b/mseide-msegui/VERSION.TXT @@ -0,0 +1,675 @@ +MSEide+MSEgui breaking changes version history +********************************************** +Version 4.6.2 +2018-11-03 +2018-10-15 + tcustomframe.colorclient default value cl_transparent -> cl_default. + tdispframe default actualcolorclient() value cl_transparent -> cl_noedit. +2018-10-14 + getsubformeventty and initsubformeventty sender parameter TObject->ttabpage. +2018-09-25 + winidty = ptruint -> winidty = type ptruint. Existing IDE generated + eventhandlers with winidty parameter (createwinideventty, destroywinideventty) + must be updated (longword/qword -> winidty). +2018-09-23 + singlekeyshiftstatesmask -> shiftstatesrepeatmask. +2018-09-14 + optiondockty od_childicons -> optionformty odf_childicons. +2018-09-12 + tifi*clientcontroller.onvaluchanged properties are value type specific. +2017-12-22 + iassistiveserver.doactionexecute() has iassistiveclient parameter. + iassistiveserver.dofocuschanged() has iassistiveclient parameter. +2017-12-17 + iassitiveserver.clientmouseevent() -> doclientmouseevent() +2017-12-15 + initializedynlib(),releasdynlib() callback has data pointer parameter. + +Version 4.6 +2017-11-23 +2017-10-28 imagebufferinfoty -> maskedimagety. +2017-09-22 + tdatabutton.min -> valuemin, max -> valuemax. + tintegeredit.min -> valuemin, max -> valuemax. + tint64edit.min -> valuemin, max -> valuemax. + tenumedit.min -> valuemin, max -> valuemax. + trealedit.min -> valuemin, max -> valuemax. + tdatetimeedit.min -> valuemin, max -> valuemax. +2017-09-14 + Definition of the inner active area of buttons is made with + the new tframe property frameo_* instead of framei_*, + framei_* is used in order to adjust the caption rect. + ttabs.captionframe_* replaced by tframe.framei_*. +2017-07-13 + Definition of "msestring" moved from "msestrings" to "msetypes". +2017-04-14 + cellinfoty boolean flags replaced by celldrawstatesty set. + +Version 4.4.2 +2017-04-08 +2017-04-03 + cl_defaultrect -> cl_buttondefaultrect. +2017-03-30 + Changed parameter clipandmove -> clip, move in + beforeframepaintbackgroundeventty and beforeframepaintbackgroundeventty. +2017-02-20 + dno_append removed from tdbnavigator default options. + +Version 4.4 +2017-02-13 +2017-01-29 + tsqlresult.cols -> datacols. +2017-01-27 tlayouter.place_options plo_syncmaxautosize, + plo_synccaptiondistx,plo_synccaptiondisty, + plo_syncpaintwidth,plo_syncpaintheight -> + optionslayout lao_syncmaxautosize, + lao_synccaptiondistx,lao_synccaptiondisty, + lao_syncpaintwidth,lao_syncpaintheight. +2017-01-19 + msefbconnection.pas -> msefb3connection.pas. + tfbconnection -> tfb3connection. +2016-12-26 + timagelist.getimage returns bitmap- and maskbitmap-kind of imagelist. +2016-10-21 + tlistitem.drawimage() parameter order changed. +2016-10-02 + teditwidgetdatalink.options oed_syncedittonavigator default off. +2016-09-30 + Options belonging to bufdataset descendants only moved from + tdscontroller.options to tmsebufdataset.options. + "delayedapplycount" tdscontroller -> tmsebufdataset. +2016-09-28 + Frame buttons options fbo_disabled overrides readonly-state of widget. + For existing widgets which have been saved in readonly-state fbo_disabled must + be cleared one time in design mode. +2016-09-26 + TCustomSQLConnection DatabaseName, Password, UserName, HostName, Charset and + Role properties ansistring -> msestring. +2016-27-04 + ondrawcelleventty cellinfo parameter var instead of const. + +Version 4.2 +2016-02-24 +2015-12-23 + Endpoints of visible tframe.frameimage edges are always painted independently + of the hiddenedges state of neighbors. Copy the middle image to the end images + in order to restore the old appearance. +2015-11-23 + twidget.findwidget() -> findchild(). + twidget.findtagwidget() -> findtagchild(). + +Version 4.0 +2015-11-13 +2015-11-03 + tcustomface opacity values of alpha blending inverted, white is + full opaqueness of the elements. +2015-10-27 + tcustomframe.frameimage_offsetactivemouse, + frameimage_offsetactiveclicked, frameface_offsetactivemouse and + frameface_offsetactiveclicked removed. The resulting offset is now the sum + of all active offsets. +2015-10-24 + tslider.scrollbar.face moved to tcustomscrollbar, + disable tslider.scrollbar.face in order to show the pattern. + +Version 4.0beta1 +2015-09-30 + tfiledialog statvalues lastdir, filehistory, filefilter and fielefilterindext + moved to oe1_saveoptions section. +2015-09-27 + charencodingty ce_utf8n -> ce_utf8, please load broken forms into MSEide + in order to fix the *.mfm files. +2015-09-15 + Internal character encoding is utf-16 instead of UCS2. +2015-08-09 + applyrecupdateeventty asql parameter is msestring. +2015-08-08 + trystrto*mse() -> trystrto*(). +2015-07-02 + Commandline functions and params use msestring instead of string. + +Version 3.8 +2015-05-13 + tcustomapplication.locked() -> islockedthread(). +2015-02-04 + tselector.dropdownitems ->tdropdowndatacols, published properties removed. +2015-01-17 + tdscontroller.recnonullbased -> recnozerobased. +2014-12-26 + tskinfont has template property instead of individual properties. + +Version 3.6 +2014-11-25 +2014-11-19 + tdataedit.optionsedit oe_savevalue,oe_savestate,oe_saveoptions, + oe_checkvaluepaststatread -> optionsedit1 oe1_savevalue,oe1_savestate, + oe1_saveoptions,oe1_checkvalueafterstatread. + tfiledialog.optionseedit -> optionsedit1. +2014-11-16 + Type of "onshortcut" is "shortcuteventty" with an additional "origin" + parameter. +2014-10-14 + Dropdowncols fontcoloractive -> fontacitve. +2014-10-01 + tprocess.input tpipewriter -> tpipewriterpers, use tprocess.input.pipewriter. +2014-09-30 + Inplace tmacrolist.expandmacros() -> expandmacros1(). + +Version 3.4a +2014-08-20 +Version 3.4 +2014-08-15 +2014-07-15 + tpoorstringdatalist.addchars() processeditchars: boolean -> + aoptions: addcharoptionsty. + tcustomstringcol.addchars() processeditchars: boolean -> + aoptions: addcharoptionsty. +2014-06-26 + TField.ProviderFlags pfInInsert and pfInitInsert removed. + TField.Visible, ReadOnly, Required, ProviderFlags and + providerflags1 combined into TField.optionsfield property. +2014-06-08 + Separate TField.ProviderFlags pfInInsert, pfInUpdate. +2014-03-09 + Parameter monochrome -> kind for t*bitmap.create(). + t*bitmap.monochrome removed, use t*bitmap.kind instead. +2014-02-26 + params parameter for tmaskedbitmap.loadfrom*(). + +Version 3.2 +2014-01-30 +2014-01-27 + tcustomframe.*framewidth() -> *framedim(). + twidget.framewidth() -> framedim(). + +Version 3.0 +2013-09-27 +2013-07-14 + No #0 for last byte in tcanvas.dashes, + use cl_transparent colorbackground instead. +2013-07-02 + tcanvas.lineoptions -> tcanvas.options + +Version 3.0beta1 +2013-06-29 +2013-05-02 + sender parameter of ifi clientevents is tcustomificlientcontroller. +2013-04-30 + onsetvalue of ifi t*clientcontroller have a iificlient parameter. +2013-04-14 + transparency properties -> opacity. +2013-03-28 + treader.readset() settype parameter is type of set instead of type of enum. + twriter.writeset() settype parameter is type of set instead of type of enum. +2013-03-10 + tcustomgrid.optionsgrid og_noresetselect -> optionsgrid1 og1_noresetselect. +2013-03-03 + sender parameter of tcustomstringcol.oncopytoclipboard, onpastefromclipboard + is tcustomstringcol. + +2013-02-14 + tapplication.postevent() boolean parameters -> posteventoptionsty. + application.modallevel returns 0 instead of -1 for single loop stack. +2013-02-12 + t*dispwidget.onchange -> ondatachange. +2013-01-20 + Forking of classes.pp. Add "mclasses" after "classes" in uses. +2013-01-19 + Forking of db.pas. Change "db" -> "mdb" in uses. + +Version 2.8.6 +2012-12-31 + lib/common/kernel/i386-linux -> lib/common/kernel/linux. + lib/common/kernel/i386-win32 -> lib/common/kernel/windows. + There is a new settings macro ${TARGETOSDIR} which points to the new directory. + Please replace ${TARGET} by ${TARGETOSDIR} in your existing project options. +2012-12-18 + tstringcontainer -> tkeystringcontainer + +Version 2.8.4 +2012-12-14 +2012-12-13 + tpoorstringdatalist.addchars() returns added rowcount instead of rowindex. +2012-11-25 + tpopupmenu.additems() aseparator parameter removed, use tcustommenu.options + oe_noseparator. +2012-10-26 + optionsscrollty oscr_zoom -> oscr_zoomwidth,oscr_zoomheight. +2012-10-11 + onloaded called after loaded() of the children and self.loaded(). + oncreate called after children have been created but before loaded(). + oncreated called in afterconstruction(). +2012-10-08 + oncreate always called before onloaded independent of globalloading and inline + state. + treport oncreate <-> onloaded. +2012-09-14 + tcustommseform oncreate <-> onloaded. + tmsedatamodule oncreate <-> onloaded. +2012-09-13 + fieldarrayty -> fieldarty. +2012-09-07 + formatfloatmse() format 0.###f defines decimal places, use 0..###f for mantissa + digits. +2012-06-30 + Global syntax definition format for tsyntaxpainter changed: + keyworddefs = + KEYWORDDEFS keyworddefsname [stylename] newline + {{keyword} newline} + + Local syntax definition format for tsyntaxpainter changed: + keywords = + KEYWORDS [style] newline //style used as default + {keyworddefsname [style] newline} + +2012-04-14 + *cryptio* -> *cryptoio*. +2012-04-13 + mopenssl -> mseopenssl, uses dynlibinfoty, stadardised with other lib bindings. + BIO functions -> mseopensslbio. + +Version 2.8.2 +2012-04-01 +2012-02-01 + optionedit oe_autopoupmenu,oe_keyexecute-> + optionedit1 oe1_autopoupmenu,oe1_keyexecute-> +2012-01-27 + optionwidget ow_fontglyphheight,ow_fontlineheight,ow_autoscale -> + optionwidget1 ow1_fontglyphheight,ow1_fontlineheight,ow1_autoscale. + +Version 2.8 +2012-01-11 +2011-12-31 + tsqlresult inherits from tsqlstatement, options -> sqlresultoptionsty. + tsqlquery moved to msesqlquery.pas. +2011-12-25 + shiftstatemustinclude and shiftstatemustnotinclude parameters for iscellclick(), + same as iscellkeypress(). +2011-12-20 + Statfile multi line string values format unified. + rttistat ansi string value stored in binary. + +Version 2.8rc1 +2011-12-12 +2011-11-28 + tcustomgrid.gridframewidth removed, use frame.framei* instead. +2011-11-23 + execmse*() inactive,nostdhandle,tty,usepipewritehandle,sessionleader parameter + replaced by execoptionsty options parameter. + richstring formatset() functions -> *1() named. +2011-11-21 + tmsesqlquery.controller.options default = [dso_autoapply,dso_autocommitret]. +2011-11-19 + coloptionty co_sortdescent -> co_sortdescend +2011-11-17 + nowutc(), nowlocal() msesysutils.pas -> msedate.pas. +2011-11-05 + splitteroptionsty spo_nohshrinkzero -> spo_hshrinkzero. + splitteroptionsty spo_novshrinkzero -> spo_vshrinkzero. +2011-10-02 + Sender parameter in ttimer.ontimer is ttimer instead of tsimpletimer. +2011-09-30 + formatsettingsmse moved from msesys.pas to mseformatsettings.pas. +2011-09-29 + Deprecated bucket lists moved from msehash.pas to to msebucketlist.pas +2011-09-26 + Array utility functions msedatalist.pas -> msearrayutils.pas. + Library load functions msesys.pas -> msedynload.pas. +2011-09-17 + Unified parameter order for sort functions. +2011-06-27 + tdatasetcontroller.options dso_refreshwaitcursor -> dso_waitcursor. +2011-06-23 + handled parameter for stepeventty. +2011-06-01 + tdb*lookuplb.lookupbuffer, lookupkeyfieldno, lookupvaluefieldno moved to + datalink. +2011-05-20 + strscan() and msestrscan with integer result removed, use findchar() instead. +2011-05-19 + tfieldparamlink.slaveparams -> destparams. + tfieldparamlink.slavefields -> destfields. +2011-04-06 + dso_sync* options -> optionsmasterlink. +2011-03-30 + optionseditty moved to mseeditglob. +2011-03-29 + tvalueclientcontroller.datafield -> fieldname. +2011-03-26 + tfieldparamlink.datafield -> fieldname. +2011-03-13 + tskincontroller.toolbar_* -> toolar_horz_*, toolbar_vert_*. +2011-03-12 + tmse*field.providerflags1 pf1_refresh -> pf1_refreshinsert, pf1_refreshupdate. +2011-02-28 + Font handling functions moved to graphics/msefont.pas. + +Version 2.6 +2011-02-26 +2011-02-13 + tterminal.onprocfinished sender parameter is tterminal instead of tmseprocess. +2010-12-13 + tscrollingwidget.scrollpos -> tscrollboxframe.scrollpos. +2010-11-19 + Changed iobjectpicker and tpickwidget event properties. +2010-11-2 + No negative ttimer values for single shot, use options to_single instead. + +Version 2.4 +2010-11-01 +2010-10-22 + sys_homedir -> sys_apphomedir. + "~/" returns sys_userhomedir, use "^/" for application home directory. +2010-10-14 + tscrollingwidget.onchildscaled -> onlayout. +2010-09-10 + tmsecomponentarrayprop -> tmsecomponentlinkarrayprop, + tmsecomponentitem -> tmsecomponentlinkitem +2010-09-08 + trecordertrace.offset -> start. +2010-09-01 + tapplication.create() calls lock(). +2010-08-27 + Read versions of image format units have suffix "read", + example mseformatpng -> mseformatpngread. +2010-08-18 + DB single key locate() replaced by multi key version. +2010-06-5 + application.screensize -> application.screenrect. + +Version 2.4rc1 +2010-06-03 +2010-05-21 + No indirection for richstringty format colors. +2010-04-08 + optionswidgetty ow_noautosizing -> optionswidget1ty ow1_noautosizing. + coloptions1ty co1_active removed. + coloptionsty co_rowfont, co_rowcolor, co_zebracolor, co_rowcoloractive -> + coloptions1ty co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive. + Grid coloractive -> colorfocus. +2010-03-16 + key_* $10xx -> $01xx. + key_enter -> key_return. +2010-02-17 + twidget.optionswidget ow_canclosenil -> optionswidget1 ow1_canclosenil. +2010-02-11 + synchronizeprocty -> synchronizeeventty. + objectprocty -> proceventty. + tagprocty -> tageventty. + tevent -> tmseevent. +2010-02-09 + ttabs framei direction reversed. + ttabbar uses ow1_autoheight instead of ow_autoscale. + ttabwidget.options -> tab_options. +2010-02-06 + tdataedit.empty_textstyle -> empty_fontstyle. +2010-01-04 + Some definitions moved from msegrids.pas to msegridsglob.pas. +2009-12-15 + Default tcustomframe.colorframe = cl_black. +2009-12-13 + t*widget.valuescale -> valuerange, inverted. +2009-12-10 + ttrace.xseriesdata -> ydata. + ttrace.xoffset, yoffset -> xstart,ystart, sign reversed. + ttrace.xscale, yscale -> xrange, yrange. + tchart.dialshorz -> xdials. + tchart.dialsvert -> ydials. +2009-12-09 + ttrace.xseriescount-> maxcount. +2009-12-03 + tcustombutton.captionpos -> imagepos. + tcolheader.captionpos -> imagepos. + tcustomdatabutton.captionpos -> imagepos. + ttabs.captionpos -> imagepos. + ttabwidget.tab_captionpos -> tab_imagepos. +2009-11-25 + tcustomdialcontroller opposite reversed for gd_up, gd_down. +2009-11-24 + tcustomchart.dialhorz, dialvert -> array dialshorz, dialsvert. + dialoptionty do_rotatetext -> dialmarkeroptionty dmo_rotatetext and + dialtickoptionty dto_rotatetext. + tcustomdialcontroller.offset -> start. + +Version 2.2beta2 +2009-11-18 +2009-11-09 + comparprocty out result -> var result. +2009-11-01 + tfont.colorshadow -> shadow_color. +2009-10-19 + twidget.optionswidget ow_autosize, ow_autosizeanright, ow_autosizeanleft moved + to optionswidget1 ow1_autowidth, ow1_autoheight, ow1_autosizeanright, + ow1_autosizeanbottom. + Changed signature of endpickmoveeventty. +2009-09-16 + trichbutton has no stockglyph, use trichstockglyphbutton. +2009-08-05 + datatypty -> listdatatypety. +2009-07-31 + optiongridty og_merged -> og_colmerged. +2009-06-27 + tmsesqlquery.refresh does not restore recno, use controller.refresh(true). + +Version 2.2beta1 +2009-06-23 +2009-06-17 + msestringicomp1 -> msestringicompupper. + lstringicomp1 -> lstringicompupper. + tcustomgrid.getselectedrows -> tdatacols.selectedrows. +2009-06-02 + tgriddatalink.datafield -> fieldname_state. +2009-04-10 + Modified parameters for updateerroreventty (tmsebufdataset.onupdateerror). +2009-03-15 + tcalendardatetimeedit moved to msecalendardatetimeedit.pas. + tdbcalendardatetimeedit moved to msedbcalendardatetimeedit.pas. +2009-03-13 + Event handlers must be in "managed" area of the class + definition, between "class" and the first "private", "protected", + "public" or "published". +2009-03-02 + const modifiers for indexeventty parameters (datalist.pas). +2009-02-13 + titemedit.onmouseevent -> onclientmouseevent. +2009-02-12 + optiongridty og_rotaterow -> og_wraprow, additional og_wrapcol, + must be activated in existing projects. +2009-02-06 + checkvalueeventty, settexteventty, gettexteventty tdataedit -> tcustomdataedit. +2009-02-04 + tdatacol.onchange -> datacolchangeeventty. + +Version 2.0rc1 +2009-02-02 +2009-01-28 + tdb*grid.datasourec moved to tdb*grid.datalink. +2009-01-17 + mouseeventinfoty, mousewheeleventinfoty, keyeventinfoty moved to + mseguiglob.pas. +2009-01-12 + tdb*editwidget.datasource, optionsdb and datafield moved to + tdb*editwidget.datalink. +2008-12-16 + tmseform descendants without resources (no *.mfm file) must override + class function hasresource() and return false. + +Version 2.0beta2 +2008-12-15 +2008-10-25 + int64 parameter for tlookupbuffer.addrow and tlookupbuffer.addrows. +2008-10-16 + tcustomrealedit.asinteger returns minint for empty value. + +Version 2.0beta1 +2008-10-15 +2008-10-09 + New parameters leadingtext and handled in exceptioneventty. +2008-10-04 + shapestatety ss_* -> shs_* in in order to distinguish from shiftstate. +2008-09-02 + '[' is special char instead of '#' in string propertyediter. +2008-08-04 + tguiapplication.waitdialog aidleaction parameter is type waitidleeventty. + tthreadcomp.runwithwaitdialog moved to tguithreadcomp. +2008-05-31 + optioneditty oe_returntaborder -> optionwidgetty ow_keyreturntaborder + +Version 1.8rc1 +2008-05-24 +2008-05-14 + tsqlquery.executedirect uses write transaction. +2008-04-09 + treport.onbeforerender -> reporteventty. + treport.onafterrender -> onreportfinished. +2008-03-26 + tbuttonframe.options fbo_flat, fbo_noanim -> + tcustomframe.optionsskin fso_flat, fso_noanim. + +Version 1.8beta1 +2008-03-20 + gridcoordty parameter for griddataeventty. + gridcoordty parameter for griddatablockeventty. + griddatamovedeventty -> gridblockmovedeventty. + gridbeforedatablockeventty -> gridbeforeblockeventty. +2008-03-14 + syncminframewidth -> syncpaintwidth. + syncminframeheight -> syncpaintheight. +2008-03-11 + twidget.taborderedwidgets -> gettaborderedwidgets. +2008-03-09 + tcustomcaptionframe.captiondistouter -> options cfo_captiondistouter. + tcustomcaptionframe.captionnoclip -> options cfo_captionnoclip. +2008-03-04 + mseguithread.pas -> msethreadcomp.pas +2008-02-02 + tscrollbar.options sbo_flat and sbo_noanim moved to tframe.optionsskin. + tbutton.options bo_flat,bo_noanim,bo_nofocusrect,bo_nodefaultrect + moved to tframe.optionsskin. + tmenu.options mo_noanim moved to itemframetemplate.optionsskin. +2008-01-04 + tcustomdatabutton visible and enabled no more published. +2007-12-28 + tdbcontroller.onbeforeconnect,onconnecterror and onafterconnect moved to + tmdatabase. +2007-12-13 + tapplication.wakeupguithread -> wakeupmainthread. +2007-12-08 + optionsedit oe_autoapply moved to optiondb oed_autoapply. +2007-12-07 + cl_none changed from $80000000 to $80000006, $80000000 can not be used + as default property value. +2007-12-01 + tcoloredit.buttonellipse moved to frame. + tframebutton.visible,enabled and left no more published, use options. + +Version 1.6 +2007-11-19 +2007-10-29 + Refactoring for GUI independent MSEifi: + modalresultty moved to mseglob. + Action basics moved to mseact. + tactivator moved to mseapplication. + +2007-09-29 + sqlscripteventty -> sqlstatementeventty + sqlscripterroreventty -> sqlstatementerroreventty +2007-09-27 menuoptinonsty mo_flat -> mo_noanim. + +Version 1.4 +2007-09-06 + Default value of tdbnaviagator.options = [dno_confirmdelete,dno_append]. + tcustomrecordband.options bo_show*/bo_hide* -> optionsshow bos_show*/bos_hide* +2007-08-29 Defaultvalue of tmsebufdataset.packetrecords = -1. +2007-08-25 + tfieldlink.dataset -> destdataset. + tfieldlink.datafield -> destdatafield. + tfieldfiledlink.sourcedatafield -> datafield. + +Version 1.4beta1 +2007-08-07 Modified type of tmsebufdataset.onupdateerror. +2007-08-01 TDatabase -> tmdatabase, moved to msedatabase.pas. +2007-07-24 tspacer.offset_* -> dist_*. + +Version 1.2 +2007-06-15 + +Version 1.2rc2 +2007-05-17 tcustomrealedit.scale -> valuescale. +2007-05-07 tcustomprogressbar.scale -> valuescale. + +Version 1.2rc1 +2007-03-29 tdbimage renamed to tdbdataimage. + +Version 1.2beta2 +2007-03-22 tcustommseform.onloaded renamed to oneventloopstart. +2007-03-18 tgripframe.grip_colorbutton -> grip_colorglyph. +2007-02-23 Published properties tcolordropdownlistcontroller.cols, valuecol + and itemindex removed. +2007-02-21 tprintercanvas.firstpage, lastpage replaced by + tprintercanvas.pages. + +Version 1.2beta1 +2007-02-15 TSQLQuery.UpdateSQL,InsertSQL and DeleteSQL renamed to + SQLUpdate,SQLInsert and SQLDelete. +2007-02-06 tstockobjects.paintglyph order of parameters changed. +2007-02-06 timagelist.paint order of parameters changed. +2007-01-25 tprinter.ppmm -> tcanvas.ppmm. +2006-12-23 tfixrow.hints moved to tcolheader. +2006-12-22 Item order of tfixcols, tfixrows and tfixcolheaders reversed. +2006-11-22 tcustomlookupbuffer.options olbdb_invalidateonupdatedata -> + olbdb_invalidateifmodified. +2006-10-23 Function vartorealty. +2006-10-20 ttimestampfieldlink, tfieldlink, tdscontroller.post. + +Version 1.0rc1 +2006-10-19 oldb_invalidateonupdatedata -> olbdb_invalidateonupdatedata. +2006-10-18 Blob suport for tmibconnection and tmpqconnection. +2006-10-17 Calculated fields for tmbufdataset. +2006-10-16 tdbimage. +2006-10-15 tfieldfieldlink. +2006-09-27 tmsecomponent.linkedobjects, tobjeclinker.linkedobjects. +2006-09-25 tstatfile moved to msestatfile.pas. + tmsedatamodule moved to msedatamodules.pas. + Properties tstatfile.activator, tactivator.onactvateerror, + tdbcontroller.onbeforeconnect, onconnecterror. + tpostprintprinter clipping. +2006-09-23 tpostscriptprinter pattern support. + +Version 0.9b +2006-08-27 tsplitter.options spo_dockleft,spo_docktop,spo_dockright, + spo_dockbottom, default on. +2006-08-25 Property tscalingwidget.optionsscale, osc_expandx,osc_expandy, + osc_shrinkx,osc_shrinky, used in tgroupbox and tscrollbox. + tspacer. +2006-08-24 tintegerbutton renamed to tdatabutton, tdbdatabutton, + tdialogstringedit, tdbdialogstringedit. +2006-08-20 tprogressbar. +2006-08-18 tsequencelink. +2006-08-10 tpostscriptprinter imageprinting. +2006-07-29 foregroundcolor renamed to colorforeground. +2006-07-29 backgroundcolor renamed to colorbackground. +2006-07-22 Property tfilenamedit.dialogkind removed, + use controller.options fdo_save. +2006-07-19 tmsecomponent.helpcontext. +2006-07-19 tapplication.helpcontext. +2006-07-18 tcanvas.drawvect. +2006-07-13 msedrawtext.breaklines. +2006-07-12 tdbstringdisplb, tdbintegerdisplb, tdbrealdisplb, tdbdatetimedisplb. +2006-07-11 tcustomlookupbuffer.lookupinteger, lookuptext and lookupfloat. +2006-07-10 Switch to FPC 2.0.4, support for 2.0.2 and 2.0.3 removed. + +Version 0.9a +2006-07-08 tcustomedit.onkeydown. +2006-07-07 Field keyeventty.keynomod, holds unmodified key. +2006-07-06 property tgriddatalink.datafield, sets tcustomgrid.rowcolorstate and + rowfontstate according to tgriddadalink.field.asinteger. +2006-07-05 tinplaceedit.lasttextclipped. +2006-07-05 Default of tgroupbox.optionswidget + + [ow_arrrowfocusin,ow_arrowfocusout,ow_parenttabfocus,ow_subfocus]. +2006-07-05 Flag twidget.optionswidget ow_parenttabfocus. +2006-07-04 tdbcalendardatetimeedit. +2006-07-04 tcalendardatetimeedit. + +Version 0.9 +2006-07-01 First Sourceforge SVN release diff --git a/mseide-msegui/apps/demo/demo.pas b/mseide-msegui/apps/demo/demo.pas new file mode 100644 index 0000000..e300c20 --- /dev/null +++ b/mseide-msegui/apps/demo/demo.pas @@ -0,0 +1,8 @@ +program demo; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui,mseforms,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/apps/demo/demo.prj b/mseide-msegui/apps/demo/demo.prj new file mode 100644 index 0000000..37c6e8f --- /dev/null +++ b/mseide-msegui/apps/demo/demo.prj @@ -0,0 +1,1016 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/demo +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/demo/demo.prj +mainfile=demo.pas +targetfile=demo${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=1 + MAINFO +moduletypes=1 + TMAINFO +modulefiles=1 + /home/mse/packs/standard/git/mseide-msegui/apps/demo/main.mfm +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 983103 + 983103 + 983103 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=2 + 0,0 + 0,0 +bookmarks0=0 +bookmarks1=0 +sourcefiles=2 + /home/mse/packs/standard/git/mseide-msegui/apps/demo/main.pas + /home/mse/packs/standard/git/mseide-msegui/apps/demo/demo.pas +relpaths=2 + main.pas + demo.pas +ismoduletexts=2 + 0 + 0 +modules=1 + /home/mse/packs/standard/git/mseide-msegui/apps/demo/main.mfm +moduleoptions=1 + 0 +visiblemodules=1 + -1 +nomenumodules=1 + 0 +[sourcefo.tabwidget] +tabsize=125 +firsttab=0 +index=1 +[layout] +windowlayout=552 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/demo/demo.pas + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=2 + /home/mse/packs/standard/git/mseide-msegui/apps/demo/demo.pas + /home/mse/packs/standard/git/mseide-msegui/apps/demo/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=16507 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=153 + y=240 + cx=351 + cy=166 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/demo/main.mfm b/mseide-msegui/apps/demo/main.mfm new file mode 100644 index 0000000..763722e --- /dev/null +++ b/mseide-msegui/apps/demo/main.mfm @@ -0,0 +1,25 @@ +object mainfo: tmainfo + bounds_x = 153 + bounds_y = 240 + bounds_cx = 341 + bounds_cy = 166 + container.bounds = ( + 0 + 0 + 341 + 166 + ) + options = [fo_main, fo_terminateonclose, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + moduleclassname = 'tmseform' + object tbutton1: tbutton + bounds_x = 144 + bounds_y = 72 + bounds_cx = 50 + bounds_cy = 22 + state = [as_localcaption, as_localonexecute] + caption = 'Exit' + font.xscale = 1 + font.dummy = 0 + onexecute = exitonexecute + end +end diff --git a/mseide-msegui/apps/demo/main.pas b/mseide-msegui/apps/demo/main.pas new file mode 100644 index 0000000..517d9b8 --- /dev/null +++ b/mseide-msegui/apps/demo/main.pas @@ -0,0 +1,28 @@ +unit main; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + msegui,mseclasses,mseforms,msesimplewidgets; + +type + tmainfo = class(tmseform) + tbutton1: tbutton; + procedure exitonexecute(const sender: TObject); + end; + +var + mainfo: tmainfo; + +implementation +uses + main_mfm; + +procedure tmainfo.exitonexecute(const sender: TObject); +begin + application.terminated:= true; +end; + +end. diff --git a/mseide-msegui/apps/demo/main_mfm.pas b/mseide-msegui/apps/demo/main_mfm.pas new file mode 100644 index 0000000..caca492 --- /dev/null +++ b/mseide-msegui/apps/demo/main_mfm.pas @@ -0,0 +1,37 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..394] of byte end = + (size: 395; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,8, + 98,111,117,110,100,115,95,120,3,153,0,8,98,111,117,110,100,115,95,121, + 3,240,0,9,98,111,117,110,100,115,95,99,120,3,85,1,9,98,111,117, + 110,100,115,95,99,121,3,166,0,16,99,111,110,116,97,105,110,101,114,46, + 98,111,117,110,100,115,1,2,0,2,0,3,85,1,3,166,0,0,7,111, + 112,116,105,111,110,115,11,7,102,111,95,109,97,105,110,19,102,111,95,116, + 101,114,109,105,110,97,116,101,111,110,99,108,111,115,101,15,102,111,95,97, + 117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119, + 114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,12, + 102,111,95,115,97,118,101,115,116,97,116,101,0,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0, + 7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,49,8,98,111, + 117,110,100,115,95,120,3,144,0,8,98,111,117,110,100,115,95,121,2,72, + 9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95, + 99,121,2,22,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,4,69,120,105,116, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,10,102,111,110,116,46, + 100,117,109,109,121,2,0,9,111,110,101,120,101,99,117,116,101,7,13,101, + 120,105,116,111,110,101,120,101,99,117,116,101,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/apps/facedemo/facedemo.pas b/mseide-msegui/apps/facedemo/facedemo.pas new file mode 100644 index 0000000..098fa73 --- /dev/null +++ b/mseide-msegui/apps/facedemo/facedemo.pas @@ -0,0 +1,11 @@ +program facedemo; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef FPC} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui,mseforms,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/apps/facedemo/facedemo.prj b/mseide-msegui/apps/facedemo/facedemo.prj new file mode 100644 index 0000000..92abfd2 --- /dev/null +++ b/mseide-msegui/apps/facedemo/facedemo.prj @@ -0,0 +1,1015 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/facedemo +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/facedemo/facedemo.prj +mainfile=facedemo.pas +targetfile=facedemo${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=1 + MAINFO +moduletypes=1 + TMAINFO +modulefiles=1 + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/main.mfm +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 65599 + 196671 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=2 + 0,0 + 0,-1073741823 +bookmarks0=0 +bookmarks1=0 +sourcefiles=2 + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/main.pas + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/facedemo.pas +relpaths=2 + main.pas + facedemo.pas +ismoduletexts=2 + 0 + 0 +modules=1 + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/main.mfm +moduleoptions=1 + 0 +visiblemodules=1 + -1 +nomenumodules=1 + 0 +[sourcefo.tabwidget] +tabsize=60 +firsttab=0 +index=0 +[layout] +windowlayout=551 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=2 + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/facedemo.pas + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=16507 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=58 + y=273 + cx=648 + cy=286 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/facedemo/main.mfm b/mseide-msegui/apps/facedemo/main.mfm new file mode 100644 index 0000000..1e5b0c1 --- /dev/null +++ b/mseide-msegui/apps/facedemo/main.mfm @@ -0,0 +1,3558 @@ +object mainfo: tmainfo + visible = False + bounds_x = 58 + bounds_y = 273 + bounds_cx = 638 + bounds_cy = 286 + container.frame.levelo = -1 + container.frame.leveli = 1 + container.frame.framewidth = 1 + container.frame.colorframe = 13092491 + container.frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_colorframe] + container.frame.localprops1 = [] + container.face.image.alignment = [al_tiled] + container.face.image.opacity = 8355711 + container.face.image.image = { + 00000000000000009600000096000000380A0100000000000000000000000000 + 0000000000000000000000000000000000000000D8D8D801DBDBDB01DADADA02 + DBDBDB03D9D9D901DADADA01FFFFFF01DADADA02A9A9A901D9D9D901D8D8D801 + A9A9A901DADADA01DBDBDB01D9D9D901D7D7D701D9D9D901DCDCDC01D8D8D801 + DBDBDB01D8D8D801DBDBDB01DDDDDD01D8D8D801DBDBDB01D9D9D901FEFEFE01 + DCDCDC01D9D9D901DBDBDB01DADADA02D9D9D902DCDCDC01DBDBDB01DADADA03 + DCDCDC01DADADA02DCDCDC01DADADA09DBDBDB01DADADA01D9D9D902DADADA02 + DBDBDB01D9D9D902DBDBDB02D7D7D701DDDDDD01D9D9D902DBDBDB01DADADA01 + D9D9D901DADADA01D8D8D801DDDDDD01DBDBDB01DADADA01D9D9D901DBDBDB01 + FEFEFE02FFFFFF01A7A7A701DBDBDB01FFFFFF01DADADA01FFFFFF01FDFDFD01 + DADADA01A7A7A702FFFFFF01FEFEFE01FFFFFF01D8D8D801ABABAB01D9D9D902 + DADADA01FFFFFF01D9D9D901A9A9A901D8D8D801DCDCDC01D8D8D801FDFDFD01 + FFFFFF01DADADA01D9D9D902FFFFFF01D8D8D801DADADA01DBDBDB01DADADA01 + D9D9D901DBDBDB01DADADA09DCDCDC01A7A7A701A5A5A501A9A9A901D9D9D901 + DBDBDB01D9D9D901DADADA0FDDDDDD01D8D8D801DADADA01DDDDDD01D5D5D502 + DBDBDB02DADADA01FFFFFF01D8D8D801DBDBDB03D9D9D901DADADA02D7D7D701 + DADADA01DFDFDF01DBDBDB01DADADA03DBDBDB01DCDCDC01D4D4D401DFDFDF01 + DADADA01A8A8A801FFFFFF01D7D7D701DADADA01DBDBDB01DADADA01D9D9D901 + DCDCDC02D7D7D702D9D9D901D8D8D801DBDBDB01D9D9D902D8D8D801D9D9D901 + DADADA09D8D8D801DBDBDB01DDDDDD01DCDCDC01D8D8D801DDDDDD01D6D6D601 + DCDCDC01DADADA01DCDCDC01D8D8D801DBDBDB01DADADA01D9D9D901DADADA01 + DCDCDC02DADADA01DCDCDC01DADADA01D7D7D701D9D9D901D7D7D701DEDEDE01 + D8D8D801FFFFFF02FCFCFC01DADADA01FFFFFF01FDFDFD02FCFCFC01FFFFFF02 + AAAAAA01A8A8A801FEFEFE01FFFFFF01FBFBFB01DADADA01DCDCDC01D8D8D801 + DFDFDF01D9D9D901FDFDFD01DADADA01A7A7A701D9D9D901DADADA01DBDBDB01 + FFFFFF01FAFAFA01DADADA01DBDBDB02FCFCFC01FFFFFF01DADADA01D7D7D701 + DBDBDB01DADADA01D9D9D901DADADA09DBDBDB01A8A8A802ABABAB01A7A7A702 + DBDBDB01D9D9D901DADADA0ED9D9D901DADADA01D9D9D902DCDCDC01DEDEDE01 + DCDCDC01D9D9D901DADADA01DCDCDC01FFFFFF01D8D8D802FEFEFE01E0E0E001 + D7D7D701DBDBDB01D9D9D901AEAEAE01D4D4D401DADADA01A9A9A901D8D8D801 + DCDCDC01DADADA01D9D9D901DDDDDD01D8D8D801D5D5D501DDDDDD01DADADA02 + D9D9D901DCDCDC01A8A8A801DBDBDB01DADADA01D7D7D701DDDDDD02DBDBDB01 + D9D9D901DCDCDC01D9D9D901DDDDDD01DCDCDC01D9D9D901DADADA09DBDBDB01 + D9D9D901D7D7D701D8D8D801DADADA01D9D9D901DCDCDC01D7D7D701D8D8D801 + DCDCDC01D7D7D701DADADA02DCDCDC01D6D6D601D9D9D901D7D7D701DADADA03 + DCDCDC01D8D8D801DEDEDE01D5D5D501DBDBDB01D8D8D801FCFCFC01FFFFFF01 + DADADA01FDFDFD01DFDFDF01DADADA01FDFDFD01FFFFFF01D8D8D802DCDCDC01 + D8D8D802FFFFFF01DBDBDB01D9D9D901DBDBDB01D6D6D601D9D9D901FFFFFF01 + DDDDDD01A8A8A802DBDBDB01DADADA01D8D8D801DDDDDD01D9D9D902FFFFFF01 + FDFDFD02DCDCDC01DBDBDB01D9D9D901DBDBDB01DADADA01D9D9D901DADADA08 + D8D8D801DCDCDC01A9A9A901A5A5A501A6A6A601AAAAAA01A7A7A701AAAAAA01 + DADADA0FDCDCDC01DADADA01D8D8D801DBDBDB01D8D8D801D4D4D401DADADA01 + D9D9D901DADADA01A9A9A901D9D9D901DDDDDD01D8D8D801D6D6D601DDDDDD01 + D6D6D601DDDDDD01D7D7D701DCDCDC01DDDDDD01DBDBDB01DADADA02DCDCDC01 + D8D8D801A8A8A801FFFFFF01DBDBDB01D9D9D901DCDCDC01DADADA02AAAAAA01 + A6A6A601D7D7D701DBDBDB02D9D9D901D7D7D701DCDCDC01DBDBDB01D9D9D901 + D7D7D701D9D9D902D8D8D801DADADA09D8D8D801DBDBDB01DCDCDC02DADADA02 + D9D9D901DDDDDD01DADADA01D9D9D901DBDBDB02DADADA02DCDCDC01DBDBDB01 + D9D9D901DADADA02DCDCDC01D6D6D601DDDDDD01DBDBDB01DCDCDC01D8D8D801 + DBDBDB01D8D8D801DDDDDD01D7D7D701DEDEDE01D8D8D801D9D9D901DADADA01 + FFFFFF01FEFEFE01D6D6D601DEDEDE01D8D8D801DBDBDB01D9D9D903DDDDDD02 + DBDBDB01FEFEFE01DADADA01D8D8D801AAAAAA01A7A7A701A8A8A801DBDBDB01 + D9D9D901DCDCDC01D9D9D901DBDBDB01FFFFFF01FDFDFD01FCFCFC01DADADA01 + DDDDDD01D8D8D801DCDCDC01DADADA09DCDCDC01D9D9D902DDDDDD01A8A8A801 + ABABAB01A6A6A601D8D8D801DADADA0ED9D9D901D8D8D801DCDCDC01DADADA01 + D9D9D901DEDEDE01DCDCDC01D8D8D801DCDCDC01A7A7A702DBDBDB01D9D9D901 + DEDEDE01D9D9D901D8D8D801FFFFFF01DCDCDC01DBDBDB01FFFFFF01A4A4A401 + D9D9D901DBDBDB01D8D8D801D9D9D901DBDBDB01D7D7D701DBDBDB01D9D9D901 + D7D7D701DADADA01D9D9D901FFFFFF01D7D7D701DCDCDC01D9D9D901DDDDDD01 + D9D9D901D8D8D801DDDDDD01D6D6D601DCDCDC01D9D9D901DDDDDD01DBDBDB01 + DADADA01DCDCDC02DADADA08DEDEDE01D6D6D601D9D9D901DADADA01D9D9D901 + DADADA01D9D9D901A8A8A801D9D9D901DADADA01DBDBDB01D8D8D802DADADA01 + A9A9A901D9D9D901DCDCDC01DADADA01D6D6D601DCDCDC02D7D7D701DADADA01 + D8D8D801DBDBDB01DADADA01DBDBDB01D8D8D801DADADA01D9D9D901D8D8D801 + AAAAAA01FDFDFD01DADADA01DCDCDC01DADADA03DBDBDB01D9D9D901DDDDDD01 + DADADA01A3A3A301DDDDDD01DADADA01FEFEFE01FFFFFF01DCDCDC01D8D8D801 + A8A8A801D8D8D802D9D9D901DCDCDC01D8D8D801DBDBDB01FDFDFD01FFFFFF02 + FEFEFE01D8D8D801DBDBDB01D7D7D701DCDCDC01DADADA09D9D9D901DBDBDB01 + D6D6D601DBDBDB01D8D8D801DCDCDC02DADADA10DCDCDC01D7D7D701D8D8D801 + DADADA01D7D7D701DCDCDC01FFFFFF01D6D6D601ABABAB01DBDBDB01A5A5A501 + A7A7A701AAAAAA01A9A9A901DADADA01D8D8D802DBDBDB03DADADA01DBDBDB01 + FFFFFF01DCDCDC01DADADA01DBDBDB01DDDDDD01D9D9D901DBDBDB01FDFDFD01 + FFFFFF01A6A6A601DDDDDD01D6D6D601D8D8D801DBDBDB02D8D8D801DCDCDC01 + DBDBDB01D9D9D901DBDBDB01D9D9D902DBDBDB01D7D7D701DADADA08D8D8D801 + DCDCDC01D9D9D902DDDDDD01DADADA01D7D7D701D9D9D901DBDBDB01DADADA01 + D9D9D901DBDBDB01D7D7D701DDDDDD01D8D8D802D7D7D701DBDBDB02DADADA01 + D9D9D901DADADA01D9D9D901DCDCDC01DBDBDB01DADADA02D8D8D801DBDBDB01 + DDDDDD01D9D9D901DADADA02A6A6A601D9D9D901A6A6A601D8D8D801DEDEDE01 + DADADA01DBDBDB01A7A7A701A9A9A902A7A7A702D9D9D901FFFFFF01FEFEFE01 + FFFFFF01DBDBDB03DFDFDF01D6D6D601A9A9A901A7A7A702DBDBDB01FEFEFE01 + FFFFFF01DBDBDB01DCDCDC01D8D8D801DBDBDB01DADADA08DCDCDC01D9D9D901 + DCDCDC01DADADA01D8D8D801A9A9A901D9D9D901D8D8D801DADADA0EDBDBDB01 + D8D8D801DADADA01DBDBDB01DEDEDE01D7D7D701DCDCDC01FEFEFE01FFFFFF01 + DBDBDB01D8D8D801DADADA01DBDBDB01DADADA01DCDCDC01A6A6A601A8A8A802 + FFFFFF01DCDCDC01D7D7D701DADADA01D9D9D901DADADA01DBDBDB01D8D8D802 + DBDBDB01D6D6D601DADADA04D8D8D801D9D9D901DBDBDB01DCDCDC01D9D9D902 + DBDBDB01DCDCDC01D3D3D301DFDFDF01D8D8D801D9D9D901DADADA01DDDDDD01 + DCDCDC01DADADA0BD9D9D902FFFFFF01D7D7D701DBDBDB01D8D8D801DADADA01 + DCDCDC01D8D8D801FFFFFF01D9D9D902DDDDDD01DCDCDC01D7D7D701DADADA01 + DEDEDE01D7D7D701DBDBDB01A8A8A801A6A6A601A8A8A802DADADA02DCDCDC01 + FCFCFC01D7D7D701DDDDDD01DADADA01A8A8A801DCDCDC01DDDDDD01D7D7D701 + D9D9D901DADADA01D9D9D901DADADA01A7A7A702AAAAAA01A7A7A701DADADA01 + DDDDDD01FEFEFE01D8D8D801DDDDDD01A7A7A701D7D7D701D6D6D601A7A7A701 + ADADAD01D9D9D902DBDBDB01FDFDFD01FEFEFE01DCDCDC01D7D7D701DDDDDD01 + D8D8D801DADADA08D7D7D701DCDCDC01D7D7D701DADADA01DEDEDE01D8D8D801 + DBDBDB01DCDCDC01DADADA0FD9D9D901DCDCDC01D8D8D801DADADA01DDDDDD01 + D8D8D801DCDCDC01FCFCFC01DADADA01FFFFFF01FEFEFE01FFFFFF02D8D8D801 + DCDCDC01DADADA02A7A7A701A8A8A801D9D9D901DCDCDC01DADADA02A7A7A701 + A9A9A901DBDBDB01DADADA01D9D9D901DCDCDC01D9D9D901FFFFFF01DADADA03 + DBDBDB01D9D9D901DADADA01DBDBDB01D9D9D901A7A7A701ABABAB01DADADA01 + D9D9D901DDDDDD01D9D9D903DADADA08DCDCDC01D9D9D901DADADA01DCDCDC01 + D8D8D801D9D9D901DCDCDC01DADADA01DBDBDB02D9D9D901DBDBDB01D9D9D902 + DCDCDC01D9D9D902DCDCDC01D9D9D902DADADA01A6A6A601A9A9A901A8A8A803 + DADADA01D9D9D901DADADA01DCDCDC02FDFDFD01DBDBDB01FCFCFC01DADADA01 + D9D9D901DBDBDB01DCDCDC01FDFDFD01FFFFFF01DBDBDB01D8D8D801DDDDDD01 + A6A6A601DADADA01DBDBDB01D8D8D801DBDBDB01DCDCDC01D8D8D801D9D9D901 + DEDEDE01D7D7D701FFFFFF01D8D8D801FFFFFF01DCDCDC01D7D7D701FFFFFF02 + FAFAFA01DFDFDF01FCFCFC01FFFFFF01DADADA09DBDBDB01D8D8D801FFFFFF01 + D9D9D901DBDBDB01D9D9D901DADADA10D9D9D903DBDBDB02DADADA01D9D9D901 + DBDBDB01D8D8D801DBDBDB01DCDCDC01D9D9D901FFFFFF01FEFEFE01FFFFFF01 + DBDBDB02A6A6A601DBDBDB01A8A8A801DADADA01DCDCDC01DADADA01A9A9A901 + A6A6A601DADADA01D9D9D901DADADA01D9D9D901DBDBDB01D9D9D901DADADA01 + DBDBDB01D8D8D801DBDBDB03D7D7D701A9A9A901A7A7A701ABABAB01A5A5A501 + DADADA05DCDCDC01D9D9D901DDDDDD01D8D8D801DADADA02DBDBDB03DADADA01 + D9D9D901DDDDDD01D6D6D601DCDCDC01D8D8D801DCDCDC02D9D9D901DADADA01 + D8D8D801DADADA01DBDBDB02DADADA01D8D8D801DEDEDE01D9D9D901DBDBDB01 + FFFFFF01DBDBDB01D8D8D801DCDCDC01A7A7A701DDDDDD01D9D9D902DBDBDB01 + A7A7A701AAAAAA01FDFDFD01A8A8A801A9A9A901DADADA01D9D9D901DCDCDC01 + A7A7A701D9D9D901FFFFFF01D8D8D801DBDBDB01DADADA01A9A9A901DADADA01 + D9D9D901DEDEDE01A7A7A701D8D8D801AAAAAA01D8D8D801FEFEFE01FFFFFF01 + DADADA01D9D9D901DCDCDC01DBDBDB01DADADA01FEFEFE01FFFFFF03FDFDFD01 + FFFFFF02D9D9D901DADADA02D9D9D901DDDDDD01D7D7D701DCDCDC01FFFFFF01 + FEFEFE01D8D8D801DDDDDD01D9D9D901DADADA01DBDBDB01DADADA01DBDBDB01 + D9D9D901DBDBDB01D9D9D902DDDDDD01D8D8D801D9D9D902DBDBDB01DADADA01 + DCDCDC01D8D8D801DBDBDB01DADADA01DCDCDC01DDDDDD01DCDCDC01D8D8D802 + DADADA02A8A8A801DBDBDB01D8D8D801DADADA01D9D9D901DADADA01DEDEDE01 + D7D7D701FEFEFE01FFFFFF01DDDDDD01DADADA03FBFBFB01FFFFFF01DCDCDC01 + A7A7A701DCDCDC01DDDDDD01D5D5D501DFDFDF01D7D7D701DADADA01DBDBDB01 + D8D8D801D9D9D901DADADA01DBDBDB01D8D8D801FFFFFF02D8D8D801D7D7D701 + DDDDDD01D9D9D901DADADA02DBDBDB01D9D9D902D7D7D701DBDBDB01DADADA03 + DBDBDB01A6A6A602DBDBDB01DADADA01D8D8D801DCDCDC02D8D8D801D9D9D903 + DADADA01DEDEDE01D9D9D901D8D8D801DADADA01D9D9D901ACACAC01A3A3A301 + A7A7A701D9D9D901DADADA02FEFEFE01FFFFFF01A6A6A601DDDDDD01A5A5A501 + DBDBDB01A5A5A501A8A8A801A7A7A702DADADA01D9D9D901DCDCDC01DADADA01 + DBDBDB01A8A8A801D8D8D801D9D9D901FFFFFF01DBDBDB01A8A8A801A4A4A401 + D9D9D901DADADA01D6D6D601A9A9A901ACACAC01A7A7A701FDFDFD01DCDCDC01 + FFFFFF01DADADA01D9D9D902DADADA01D8D8D801DEDEDE01FDFDFD01DCDCDC01 + D9D9D901FFFFFF01FCFCFC02DBDBDB01DADADA01D8D8D801FFFFFF03FCFCFC01 + FDFDFD01DCDCDC02DADADA01D8D8D801D9D9D902DADADA01D7D7D701DBDBDB01 + D7D7D701DDDDDD01D8D8D801DCDCDC01D7D7D701DDDDDD01DADADA01DCDCDC01 + D9D9D901D7D7D701DBDBDB01D8D8D801D9D9D901D8D8D802D6D6D601DCDCDC01 + DEDEDE01D6D6D601DADADA02A7A7A701DFDFDF01DCDCDC01D9D9D901D8D8D801 + D9D9D901DADADA01FFFFFF01D8D8D801FFFFFF01D9D9D901DADADA01DDDDDD01 + FFFFFF02D7D7D701DBDBDB01DADADA01D7D7D701DDDDDD01D6D6D601DBDBDB02 + D8D8D801DCDCDC01DADADA01DBDBDB01D6D6D601FFFFFF04D7D7D701A7A7A701 + DBDBDB01D8D8D801D9D9D901DADADA01D9D9D901DBDBDB01DADADA01D9D9D901 + DCDCDC01D8D8D801D9D9D901DBDBDB01AAAAAA01ABABAB01DBDBDB01D9D9D901 + DADADA01DBDBDB01DADADA01DBDBDB01DADADA01DCDCDC01D9D9D902DBDBDB01 + D8D8D801DCDCDC01D8D8D801ABABAB01A9A9A901A7A7A701ABABAB01DADADA01 + FFFFFF03DADADA01A9A9A901D6D6D601DBDBDB01FFFFFF02AAAAAA01D9D9D901 + FFFFFF01DBDBDB01D8D8D801DBDBDB01FFFFFF01FDFDFD01AAAAAA01DBDBDB01 + FEFEFE02FDFDFD01DBDBDB01D8D8D801E0E0E001FDFDFD01FFFFFF02D8D8D801 + DADADA01DCDCDC01DADADA01D4D4D401DCDCDC01DEDEDE01DADADA01D8D8D801 + DEDEDE01D8D8D801DADADA01D9D9D901DCDCDC01DBDBDB01FFFFFF01DEDEDE01 + D8D8D801DADADA01DDDDDD01FEFEFE01D6D6D601D9D9D901DCDCDC02DADADA01 + D9D9D901D8D8D801DADADA01DBDBDB01DADADA02DCDCDC01D9D9D901A8A8A801 + DADADA01DDDDDD01DADADA01D9D9D901DADADA01D9D9D901DADADA01DCDCDC01 + DBDBDB01DCDCDC01E0E0E001DDDDDD01DBDBDB02DADADA01DCDCDC01D6D6D601 + FFFFFF01DBDBDB01A7A7A701ABABAB01D7D7D701D9D9D901DADADA01DCDCDC01 + D7D7D701DCDCDC01D9D9D901DADADA01D8D8D801DEDEDE01D8D8D802D9D9D901 + FEFEFE01DADADA01D8D8D801DEDEDE01DBDBDB01D8D8D801DCDCDC01DBDBDB01 + D8D8D801DBDBDB01D8D8D801DBDBDB01DADADA01DCDCDC01D9D9D902D8D8D801 + D5D5D501DBDBDB02DCDCDC01DBDBDB01D8D8D801DEDEDE01D9D9D901DADADA01 + DCDCDC01D9D9D901D8D8D801DBDBDB01FFFFFF01FEFEFE01D8D8D801D7D7D701 + DADADA01D9D9D901DDDDDD01D8D8D801D9D9D901DBDBDB02D7D7D701DADADA01 + DBDBDB01D9D9D901DCDCDC01DDDDDD01FCFCFC01DADADA01D7D7D701DEDEDE01 + D9D9D901D7D7D701DBDBDB01D8D8D801FFFFFF01D9D9D901FFFFFF01D9D9D901 + FEFEFE02FCFCFC02DBDBDB01D8D8D802DFDFDF01D9D9D902DCDCDC01FAFAFA01 + DEDEDE01FFFFFF03D8D8D801DCDCDC01D9D9D901FEFEFE02D8D8D801A9A9A901 + AAAAAA01DADADA01A9A9A901ACACAC01D9D9D901DADADA01D8D8D801DCDCDC01 + D4D4D401DDDDDD02D7D7D701DCDCDC01A5A5A501D9D9D901D7D7D701DADADA01 + A8A8A801D9D9D901D8D8D801DEDEDE01DADADA01D9D9D901D8D8D801D7D7D701 + DDDDDD01DEDEDE01D8D8D801DBDBDB01D7D7D701DADADA01D7D7D701DCDCDC01 + D8D8D801DBDBDB01D6D6D601D9D9D901DCDCDC01DADADA02D8D8D801DBDBDB01 + D8D8D802D9D9D901D7D7D701D8D8D801DCDCDC01DADADA01D9D9D901DCDCDC01 + DADADA01FDFDFD01A9A9A901A7A7A701DADADA01DEDEDE01DADADA01D9D9D901 + DCDCDC01D9D9D901DADADA01DCDCDC01D8D8D802DCDCDC01DADADA02DCDCDC02 + DBDBDB01D7D7D701DBDBDB03D8D8D801DADADA01D9D9D901DCDCDC01D5D5D501 + DADADA01D9D9D901DCDCDC01DADADA02FFFFFF01D9D9D901DCDCDC01D8D8D801 + DADADA01DCDCDC01D7D7D701DADADA01D8D8D802DCDCDC01DADADA01D9D9D901 + FFFFFF01FDFDFD01DEDEDE02D9D9D901DBDBDB01DADADA01D9D9D901DCDCDC01 + D7D7D701DADADA01DCDCDC01DBDBDB01DADADA01D8D8D801DBDBDB01FDFDFD01 + DEDEDE01D9D9D902DADADA01A7A7A701DBDBDB01AAAAAA02FEFEFE01DADADA01 + D7D7D701DADADA01DCDCDC01FDFDFD01FFFFFF01DADADA01DDDDDD01DBDBDB01 + DADADA01D9D9D901A8A8A801DADADA01DEDEDE01DADADA01A7A7A701D7D7D702 + D9D9D901DCDCDC01A8A8A801D9D9D901DBDBDB01DADADA01AAAAAA01D7D7D701 + DBDBDB01D7D7D701A7A7A701D9D9D901DADADA02DCDCDC01DADADA01DEDEDE01 + D9D9D903DBDBDB01DCDCDC02DEDEDE01D9D9D901AAAAAA01FDFDFD01DADADA02 + DCDCDC01DADADA01DCDCDC01D9D9D901DBDBDB01D7D7D701DCDCDC01DADADA01 + D8D8D801DCDCDC01FFFFFF01D7D7D701DCDCDC01DADADA01DBDBDB01DCDCDC01 + D8D8D801DADADA01DCDCDC01D9D9D901DBDBDB01DADADA01D9D9D901DBDBDB02 + DADADA03D8D8D801D9D9D901FFFFFF02D8D8D801E0E0E001D7D7D702D8D8D801 + DADADA01DCDCDC01D9D9D901DADADA02DBDBDB01DCDCDC01D9D9D901AAAAAA01 + D9D9D901D8D8D801D7D7D701DFDFDF01DADADA02D9D9D903DCDCDC01DADADA02 + DEDEDE01DADADA01DBDBDB01D9D9D901D7D7D701DDDDDD01DADADA01D7D7D701 + DDDDDD01D7D7D701DDDDDD01D7D7D701D9D9D901DDDDDD01DBDBDB01D9D9D901 + DBDBDB01DADADA01D8D8D801DADADA02D6D6D601D8D8D801D9D9D901DADADA02 + D9D9D901DBDBDB01DADADA01D9D9D901D8D8D801DBDBDB01D9D9D901DDDDDD01 + D5D5D501FFFFFF02FDFDFD01FFFFFF02DBDBDB01D7D7D701DBDBDB01D4D4D401 + ABABAB01A8A8A801A9A9A901AAAAAA01A3A3A301DDDDDD01DADADA01DDDDDD01 + D6D6D601D9D9D901DCDCDC01FFFFFF02A8A8A801AAAAAA01A6A6A601A9A9A901 + ABABAB01DEDEDE01D8D8D801D9D9D903DCDCDC01FFFFFF01D8D8D801A8A8A801 + DBDBDB01FFFFFF01DCDCDC01DBDBDB01A7A7A701A8A8A801D9D9D901A7A7A701 + D9D9D902DADADA01FFFFFF01D8D8D801FDFDFD01FEFEFE01D7D7D701A9A9A901 + A8A8A801DADADA01A8A8A801D9D9D901D8D8D801DADADA01D9D9D902D8D8D801 + DADADA01D7D7D701D9D9D901DEDEDE01D7D7D701A7A7A701DADADA02D8D8D801 + DCDCDC01DBDBDB01D9D9D901DBDBDB01D9D9D901A9A9A901DADADA01D9D9D901 + DBDBDB02DADADA01D9D9D901DBDBDB01DADADA01DDDDDD01D9D9D901DADADA01 + D9D9D902D8D8D801A8A8A801DEDEDE01DCDCDC01DBDBDB01D7D7D701DCDCDC01 + D8D8D801DDDDDD01D9D9D901D7D7D701DBDBDB01A6A6A601DCDCDC02DADADA01 + DBDBDB01D6D6D601DBDBDB01DEDEDE01DBDBDB01D8D8D801DBDBDB01D8D8D801 + DDDDDD01D8D8D802DDDDDD01D6D6D601DEDEDE01D7D7D701DADADA01D9D9D901 + DCDCDC01DADADA01D8D8D801DDDDDD01DADADA01D8D8D801DADADA01DDDDDD01 + D8D8D801D6D6D601DDDDDD01D9D9D902DDDDDD02DADADA01D9D9D901DBDBDB01 + D9D9D902DEDEDE01DADADA01DBDBDB01D9D9D901DBDBDB01D8D8D801FFFFFF02 + FEFEFE01FFFFFF01FBFBFB01DADADA01FCFCFC01FFFFFF01DBDBDB01DDDDDD01 + A6A6A601A9A9A901A5A5A501AAAAAA02A5A5A501A9A9A901DADADA01D9D9D901 + DEDEDE01FEFEFE02D9D9D901A7A7A701FFFFFF01DADADA01DCDCDC01D6D6D601 + D9D9D901D8D8D801DDDDDD02D8D8D801FEFEFE01D9D9D901DBDBDB01A9A9A901 + DADADA01DBDBDB01D8D8D801D9D9D901AAAAAA01A6A6A601AAAAAA01A8A8A801 + DBDBDB01DCDCDC01D6D6D601FFFFFF03DADADA01FFFFFF01DADADA03DBDBDB02 + DADADA01DDDDDD01DADADA01DBDBDB01DADADA01DCDCDC01DADADA01DCDCDC01 + D7D7D701DCDCDC01D9D9D901DDDDDD01D9D9D902DADADA01D6D6D601DBDBDB03 + A7A7A701A6A6A601DFDFDF01D6D6D601DBDBDB01DADADA03D9D9D902DCDCDC01 + D7D7D701DCDCDC02DADADA01D9D9D901A7A7A701DCDCDC01D8D8D801DADADA02 + DDDDDD01D6D6D601DBDBDB01FFFFFF01DADADA01D6D6D601DEDEDE01D7D7D701 + DCDCDC01D8D8D801DDDDDD01DADADA01D7D7D701DCDCDC01D9D9D901DBDBDB01 + DADADA01D7D7D701DBDBDB02DADADA01DCDCDC01D7D7D701DBDBDB01D9D9D901 + DCDCDC01D8D8D801D9D9D901DCDCDC01D8D8D802DCDCDC01D9D9D902DBDBDB01 + DCDCDC01D7D7D701DCDCDC01DADADA01D9D9D901DADADA01D9D9D901DBDBDB01 + DADADA03D9D9D902DADADA01DCDCDC01DADADA01D9D9D901DBDBDB01D8D8D801 + DBDBDB02DADADA01DCDCDC01DBDBDB01D9D9D901FEFEFE02FFFFFF01FEFEFE01 + DADADA01A9A9A901A6A6A601AAAAAA01A6A6A601AAAAAA01A8A8A801A6A6A601 + A9A9A901DBDBDB01DADADA01FFFFFF02FEFEFE01D9D9D901DCDCDC01D9D9D901 + DDDDDD01D9D9D901FCFCFC01DCDCDC01FFFFFF03DADADA01A8A8A801A7A7A701 + FFFFFF01D9D9D901A8A8A801D9D9D901DBDBDB01A8A8A801A9A9A901D9D9D901 + FFFFFF01DCDCDC01A7A7A701D9D9D901FFFFFF02D8D8D801FFFFFF01DDDDDD01 + D8D8D801DADADA02D8D8D801D9D9D901DCDCDC01D9D9D901DADADA01D9D9D901 + DCDCDC01FDFDFD01DADADA01DBDBDB01D8D8D801D9D9D901DCDCDC01DADADA01 + DEDEDE01DADADA01FDFDFD01DADADA06D9D9D901D8D8D801D9D9D901DCDCDC01 + FFFFFF02DCDCDC01D9D9D901FEFEFE01DDDDDD01D8D8D801A7A7A701DADADA01 + DDDDDD01DADADA01D9D9D901DADADA01A9A9A901A8A8A801D7D7D701DDDDDD01 + D9D9D901DADADA01DBDBDB01DADADA10D8D8D801D9D9D901DBDBDB02DADADA02 + D9D9D901DCDCDC01DBDBDB01D8D8D801DADADA01DBDBDB01D9D9D901DADADA02 + D9D9D901DADADA08D9D9D901DBDBDB01DADADA03DBDBDB01DADADA02DBDBDB01 + D8D8D801DBDBDB02FEFEFE01FFFFFF02FEFEFE01FFFFFF02D8D8D801AAAAAA01 + A7A7A701A8A8A801AAAAAA01A6A6A601DBDBDB01D8D8D801A9A9A901A7A7A701 + D8D8D801DCDCDC01D7D7D701FFFFFF01DADADA01DCDCDC01D9D9D901D8D8D801 + DEDEDE01A9A9A901D8D8D801FFFFFF01D9D9D902A9A9A901FEFEFE01DADADA01 + FFFFFF02A5A5A501A9A9A901A8A8A802A6A6A601A9A9A901DBDBDB01A9A9A902 + DADADA01D7D7D701DCDCDC01DBDBDB01D8D8D801DCDCDC01D8D8D801DBDBDB01 + DADADA08D9D9D901DCDCDC01D9D9D901DADADA01DBDBDB01D8D8D801D9D9D901 + FFFFFF01FEFEFE01DEDEDE01D7D7D701DADADA02DBDBDB01DCDCDC01DEDEDE01 + D9D9D901D7D7D701DADADA01A5A5A501DCDCDC01D8D8D801DADADA01FFFFFF01 + DBDBDB01A9A9A901D9D9D901D4D4D401DCDCDC02D9D9D902D8D8D801DFDFDF01 + D7D7D701DADADA01DDDDDD01D8D8D801DADADA10DCDCDC01DDDDDD01DBDBDB01 + D7D7D701D9D9D901DADADA01DDDDDD01D8D8D801DADADA01DDDDDD01DBDBDB01 + D9D9D903DCDCDC02DADADA08DDDDDD01D7D7D701DBDBDB01DCDCDC01D8D8D801 + D9D9D903DBDBDB01DCDCDC01D6D6D601DDDDDD01D7D7D701DBDBDB01FDFDFD01 + FFFFFF02FDFDFD02FFFFFF02FCFCFC01FFFFFF01DADADA01D9D9D901A9A9A901 + A8A8A802DADADA02DEDEDE01D7D7D701DADADA01D7D7D701DBDBDB02A6A6A601 + A3A3A301A9A9A901DBDBDB01FFFFFF01D9D9D901D8D8D801DDDDDD01FDFDFD01 + DCDCDC01F9F9F901FFFFFF01A4A4A401ABABAB01A8A8A801DDDDDD01D9D9D901 + A7A7A703DCDCDC01DADADA01D9D9D904DBDBDB01D9D9D901DADADA0ADBDBDB01 + D9D9D901DCDCDC01DADADA01DEDEDE01D7D7D701DDDDDD01D4D4D401DADADA01 + DBDBDB01D8D8D801DBDBDB01D6D6D601DBDBDB01DADADA01DCDCDC01DBDBDB01 + D9D9D902DDDDDD01A7A7A701FEFEFE01A5A5A501AAAAAA01DADADA01E0E0E001 + D5D5D501FFFFFF02FDFDFD01DCDCDC01D9D9D901DBDBDB01DADADA01D9D9D901 + DDDDDD01DADADA10D9D9D901D5D5D501D9D9D901DEDEDE01DADADA01D6D6D601 + DDDDDD01D8D8D801D7D7D701DADADA01D7D7D701DBDBDB01DEDEDE01D9D9D901 + D8D8D801DADADA09D5D5D501DDDDDD01DADADA01D9D9D901DBDBDB02D8D8D801 + DDDDDD01D6D6D601DADADA01DDDDDD01DADADA02DBDBDB01D9D9D901DBDBDB01 + FDFDFD01FFFFFF02FDFDFD01FFFFFF01FDFDFD01FFFFFF02D8D8D801DBDBDB01 + A8A8A801D8D8D801DFDFDF01D7D7D701A5A5A501DCDCDC01DBDBDB01D9D9D901 + DCDCDC01FEFEFE01DBDBDB01ABABAB01A9A9A901A8A8A801D9D9D901A9A9A901 + DBDBDB01A7A7A701AAAAAA01D8D8D801FFFFFF01FEFEFE01DCDCDC01D9D9D901 + FDFDFD01DADADA01DBDBDB01D8D8D801A9A9A901AAAAAA01A5A5A501AAAAAA01 + D9D9D901DADADA01DCDCDC01DEDEDE01D6D6D601DCDCDC01DADADA08D9D9D901 + D8D8D801DCDCDC01A7A7A701DADADA01DBDBDB01D5D5D501DEDEDE01D8D8D802 + DFDFDF01DBDBDB01D9D9D901DCDCDC01A9A9A901A7A7A701DCDCDC01FCFCFC01 + DBDBDB01DCDCDC01DADADA01D7D7D701A8A8A801E0E0E001A7A7A702D9D9D901 + D8D8D801ABABAB01A7A7A701A6A6A601DADADA02D9D9D901DBDBDB01DADADA01 + D9D9D902DADADA10DBDBDB01DEDEDE01DADADA01D7D7D701DCDCDC01DBDBDB01 + D8D8D801DADADA01DDDDDD01DBDBDB01DADADA02DBDBDB01D9D9D902DBDBDB01 + DADADA08DBDBDB01D9D9D902DCDCDC01D6D6D601DADADA01D9D9D902DEDEDE01 + D9D9D901A8A8A801A6A6A601A8A8A801AAAAAA01D9D9D901D8D8D801D7D7D701 + DEDEDE01DBDBDB01D9D9D901A8A8A801FFFFFF01FEFEFE01FFFFFF01DEDEDE01 + D9D9D901A8A8A802ABABAB01D7D7D701DCDCDC01D9D9D901DCDCDC01DBDBDB01 + FDFDFD01D9D9D901DCDCDC01D6D6D601A8A8A802DCDCDC01D9D9D901A8A8A801 + A9A9A901D9D9D901A8A8A801DADADA02FFFFFF01D8D8D801FFFFFF03DADADA01 + AAAAAA01A4A4A401A8A8A801D9D9D901AAAAAA01DBDBDB01DADADA01D6D6D601 + DADADA01D9D9D901DADADA08DDDDDD01DADADA02D8D8D801DBDBDB01D9D9D901 + DEDEDE01D8D8D801DCDCDC01DADADA02D7D7D701D9D9D901DCDCDC01DADADA01 + D8D8D801DBDBDB01DADADA01D9D9D901D8D8D801FFFFFF01DBDBDB01DADADA01 + D6D6D601A8A8A801AAAAAA01DADADA02A9A9A903DCDCDC01DADADA02DBDBDB01 + D8D8D801DADADA01DDDDDD01DADADA10D8D8D802DBDBDB01DADADA01D7D7D701 + DCDCDC01D9D9D901DBDBDB01D9D9D901D8D8D801DDDDDD01DADADA01D7D7D701 + DCDCDC02D9D9D901DADADA08DCDCDC01D7D7D701DBDBDB01D8D8D801DADADA01 + DDDDDD01DADADA02A6A6A601A4A4A401DEDEDE01A6A6A601D6D6D601A9A9A901 + D8D8D801DCDCDC01DADADA01DCDCDC01D5D5D501A8A8A801DCDCDC01A7A7A701 + FCFCFC01FEFEFE01D6D6D601A9A9A901A7A7A701AAAAAA01FBFBFB01DCDCDC01 + DBDBDB02D8D8D801DADADA01FFFFFF01DDDDDD01D5D5D501E0E0E001DFDFDF01 + D8D8D801D9D9D904AAAAAA01DBDBDB01D8D8D801DADADA01D9D9D901DADADA01 + FFFFFF02FDFDFD01DBDBDB01D8D8D801DEDEDE01D8D8D801DBDBDB01DADADA01 + A6A6A601D8D8D801DADADA01DEDEDE01DADADA09D8D8D801FDFDFD01DADADA01 + E0E0E001D8D8D801DDDDDD01DBDBDB01DADADA01D9D9D902DADADA01D9D9D901 + DADADA02D9D9D901DCDCDC01D9D9D901DCDCDC01D9D9D901DADADA01FFFFFF01 + D6D6D601DADADA01DCDCDC01ABABAB01D7D7D701FFFFFF02D5D5D501ABABAB01 + A6A6A601D9D9D901DADADA01D9D9D901DBDBDB01DCDCDC02D8D8D801DADADA10 + DBDBDB01D9D9D901DCDCDC01DBDBDB01D9D9D901DBDBDB01DADADA01D9D9D901 + DCDCDC01D7D7D701DADADA01DBDBDB01DADADA01DBDBDB01DADADA01D9D9D901 + DADADA08D8D8D801DDDDDD01D5D5D501DDDDDD01D9D9D901D8D8D801A8A8A801 + DADADA01FFFFFF01E0E0E001D6D6D601FFFFFF01AAAAAA01D8D8D801D9D9D901 + DCDCDC01DBDBDB01D4D4D401FFFFFF01A8A8A801D7D7D701AAAAAA01DBDBDB01 + FFFFFF01DBDBDB01FFFFFF01FEFEFE01D8D8D801DCDCDC01D7D7D701DADADA01 + D8D8D801DBDBDB01FFFFFF03DBDBDB01D5D5D501D9D9D901DADADA01FEFEFE01 + FFFFFF01ABABAB01DBDBDB01FEFEFE01FFFFFF01D7D7D701FFFFFF01DEDEDE01 + D7D7D701D8D8D801FFFFFF02FDFDFD01FFFFFF01D6D6D601FFFFFF01D7D7D701 + DADADA01DCDCDC01DEDEDE01D9D9D903DADADA08DDDDDD01DCDCDC02D8D8D804 + DBDBDB01DADADA01DDDDDD02DBDBDB02DADADA01DBDBDB01D9D9D901D8D8D801 + DEDEDE01DADADA02FCFCFC01DEDEDE01FEFEFE01FFFFFF01D9D9D901DBDBDB01 + FDFDFD01DADADA02A8A8A801A9A9A901D9D9D901DCDCDC01DADADA01D8D8D802 + D9D9D901DBDBDB01DADADA11DCDCDC01D6D6D601DCDCDC01DADADA01A6A6A601 + AAAAAA01DADADA01D7D7D701DFDFDF01D9D9D902DBDBDB01D6D6D601DADADA01 + DCDCDC01DADADA09DCDCDC01D9D9D901DADADA01DEDEDE01D8D8D801FDFDFD01 + FFFFFF01D8D8D801FDFDFD01DADADA02D9D9D901DADADA01DBDBDB01D9D9D901 + DADADA01FFFFFF01DADADA01FFFFFF01DDDDDD01A7A7A701FBFBFB01D9D9D901 + FCFCFC01FEFEFE01DCDCDC01DADADA01D9D9D901DADADA01DCDCDC02DADADA01 + FEFEFE02FFFFFF02D8D8D801FFFFFF04FAFAFA01A7A7A701FDFDFD01FFFFFF01 + DCDCDC01FCFCFC01A5A5A501AAAAAA01DADADA01FFFFFF01FDFDFD01FFFFFF01 + D8D8D801ABABAB01D8D8D801FFFFFF01DCDCDC01DADADA01D7D7D701DCDCDC01 + D9D9D901DBDBDB01DADADA09D7D7D701DBDBDB01D8D8D801DDDDDD01DCDCDC02 + D9D9D902DADADA01D8D8D802D9D9D901DBDBDB01DADADA01D9D9D901DBDBDB01 + D8D8D802DCDCDC01FFFFFF01FEFEFE01FFFFFF01D8D8D801DADADA01DBDBDB02 + DADADA01DCDCDC01A7A7A701AAAAAA01D9D9D901DBDBDB01D9D9D901DBDBDB01 + DCDCDC01D9D9D901DADADA11D9D9D901DCDCDC01D9D9D901DBDBDB01D9D9D901 + A7A7A701A8A8A802AAAAAA01D8D8D801DBDBDB01D9D9D901DCDCDC01D7D7D701 + DEDEDE01D8D8D801DADADA08D9D9D901DADADA01DBDBDB01D9D9D901FDFDFD01 + DCDCDC01DADADA01FFFFFF02DBDBDB01FFFFFF01D9D9D901DBDBDB01DADADA03 + D9D9D901FFFFFF01D8D8D801FDFDFD01DADADA02FFFFFF01DBDBDB01DADADA01 + DCDCDC01D9D9D902DADADA02D9D9D902DADADA01D9D9D901FFFFFF01D8D8D801 + FEFEFE01DCDCDC01D9D9D901DADADA01FEFEFE01FFFFFF01A9A9A901DCDCDC01 + DADADA02D9D9D901DBDBDB01A8A8A801A9A9A901DADADA01DBDBDB01D9D9D901 + DBDBDB02A7A7A701DBDBDB01D7D7D701D9D9D901DCDCDC01DADADA02DBDBDB01 + DADADA09DBDBDB01D9D9D901DADADA01DBDBDB01D9D9D902DBDBDB01DADADA01 + DBDBDB01D9D9D902DCDCDC01DBDBDB01D8D8D801D9D9D901DADADA01DBDBDB01 + DADADA01D9D9D901FEFEFE01DDDDDD01DADADA01DBDBDB01D9D9D902FEFEFE01 + DADADA01DDDDDD01D7D7D701A9A9A901A8A8A801D9D9D902DADADA01DCDCDC01 + DADADA01D9D9D901DADADA01D9D9D901DFDFDF01D7D7D701DADADA01DBDBDB01 + DADADA01D9D9D901DADADA03D9D9D902DBDBDB01DCDCDC01D8D8D801DCDCDC01 + DADADA01DBDBDB01D9D9D901FFFFFF02ABABAB01A6A6A601A8A8A801A9A9A901 + A8A8A801A9A9A901D9D9D901DCDCDC01DBDBDB01D9D9D901DBDBDB02DADADA01 + D9D9D902DDDDDD01D9D9D901DBDBDB02DCDCDC01D9D9D901DADADA02D9D9D901 + DBDBDB01DADADA01D8D8D801DBDBDB01FFFFFF01DBDBDB01D9D9D902DADADA01 + D8D8D801DBDBDB02DADADA01D8D8D801FFFFFF01A7A7A701DADADA01AAAAAA01 + D9D9D901DBDBDB01DADADA02D8D8D801DCDCDC01D8D8D801DBDBDB01D9D9D902 + DADADA01DBDBDB01FFFFFF01D8D8D801D9D9D901DEDEDE01D9D9D901DADADA01 + FFFFFF01D8D8D801DDDDDD01D9D9D901D8D8D801FFFFFF02DADADA03DBDBDB01 + D7D7D701FFFFFF01DBDBDB01D9D9D901DADADA11DBDBDB01D9D9D901DADADA02 + D9D9D901DADADA01D9D9D901DADADA06DCDCDC01D9D9D901D8D8D801FFFFFF01 + DCDCDC01DADADA01D8D8D801D7D7D701D9D9D901DADADA01FFFFFF02FDFDFD01 + FCFCFC01FFFFFF01A7A7A701D8D8D801DEDEDE01DDDDDD01D6D6D601DADADA01 + D9D9D901D8D8D801DCDCDC01D8D8D801DADADA01DCDCDC01DADADA01D9D9D901 + DCDCDC01D8D8D801DBDBDB01DADADA01D7D7D701DEDEDE01DBDBDB01D6D6D601 + DCDCDC01DBDBDB01D8D8D801DADADA02DCDCDC01FBFBFB01FCFCFC01DCDCDC01 + D8D8D801AAAAAA01A6A6A601DBDBDB01DCDCDC01D6D6D601DADADA01DDDDDD01 + D7D7D701DBDBDB01D9D9D901DBDBDB01DCDCDC01DADADA01D7D7D701DADADA01 + D7D7D701D9D9D902DADADA01DBDBDB01D9D9D901DCDCDC01A6A6A601A7A7A701 + DDDDDD01D9D9D901DBDBDB01D8D8D801DCDCDC01D4D4D401DBDBDB01DCDCDC01 + DADADA01D8D8D801DADADA01FFFFFF01D8D8D801DBDBDB01D7D7D701DADADA01 + D9D9D902DADADA01DCDCDC01DDDDDD01D9D9D901DCDCDC01DBDBDB01DADADA01 + DDDDDD01FBFBFB01DDDDDD01FEFEFE01DCDCDC01DADADA01D4D4D401DBDBDB01 + FEFEFE01DADADA01DCDCDC01D6D6D601DADADA01DCDCDC01FEFEFE01FDFDFD01 + DBDBDB01D7D7D701DADADA02DDDDDD01FDFDFD01D9D9D902DADADA10D8D8D801 + DCDCDC01D9D9D901DEDEDE01DBDBDB01D8D8D801DBDBDB01DCDCDC01DADADA06 + DBDBDB02DADADA01DCDCDC01D7D7D701D8D8D801DEDEDE01DCDCDC01D9D9D901 + DCDCDC01FDFDFD02DCDCDC01FFFFFF01FDFDFD01DBDBDB01DDDDDD01D6D6D601 + D8D8D801DDDDDD01DCDCDC01D8D8D801DCDCDC01D9D9D901DCDCDC01D8D8D801 + D7D7D701DEDEDE01DBDBDB01DADADA01D8D8D801DCDCDC01DBDBDB01DADADA01 + D9D9D901DDDDDD01D9D9D903DBDBDB01D9D9D901DADADA01D8D8D801FFFFFF02 + D6D6D601DEDEDE01D9D9D902DBDBDB01D9D9D901DBDBDB02D9D9D901DBDBDB01 + DADADA05DCDCDC01D8D8D801E0E0E001DBDBDB01DADADA03D9D9D901DADADA01 + A9A9A901A8A8A801DCDCDC01DDDDDD01D4D4D401DCDCDC01DDDDDD01DADADA01 + DBDBDB01D8D8D801DADADA01D7D7D701DBDBDB01FFFFFF01FAFAFA01FFFFFF01 + DBDBDB01D8D8D801DCDCDC02D9D9D902D6D6D601DBDBDB01DADADA01D7D7D701 + DDDDDD01D9D9D901DBDBDB01D8D8D801DADADA02DCDCDC01D9D9D901DCDCDC01 + DDDDDD01DADADA01D9D9D901DBDBDB01D9D9D901DBDBDB01D9D9D901DCDCDC01 + D7D7D701DCDCDC01D8D8D801DDDDDD01D5D5D501DBDBDB01DCDCDC01DADADA11 + DBDBDB01D8D8D801DCDCDC01D5D5D501DBDBDB01DCDCDC01DADADA01D7D7D701 + DADADA06D6D6D601DCDCDC01D9D9D901DADADA01DDDDDD01DADADA01D9D9D901 + D8D8D801DADADA01DBDBDB02DCDCDC01A6A6A601D9D9D901DEDEDE01D7D7D701 + D9D9D901DBDBDB01DADADA01DEDEDE01D4D4D401DDDDDD01DADADA02DBDBDB01 + D9D9D901DCDCDC01D8D8D803D9D9D901DADADA01A8A8A802DADADA01D6D6D601 + DBDBDB01D9D9D901DEDEDE01D9D9D901DCDCDC01D9D9D901DBDBDB01FDFDFD01 + FFFFFF01D9D9D902A7A7A701DDDDDD01D8D8D801DCDCDC01D9D9D901D7D7D701 + D8D8D801DCDCDC01DADADA01DDDDDD01D8D8D801D9D9D901DBDBDB01D8D8D801 + DCDCDC01D7D7D701D9D9D901DBDBDB03FFFFFF02D7D7D701DBDBDB01D9D9D902 + DDDDDD01D9D9D901D7D7D701DEDEDE01DADADA01D7D7D701DBDBDB02D8D8D801 + D9D9D901DCDCDC01D8D8D801DDDDDD01D9D9D902DBDBDB01DADADA01DBDBDB01 + DADADA01DDDDDD01D9D9D902DADADA01D9D9D902DDDDDD01DADADA01D8D8D801 + D7D7D701DDDDDD01D9D9D901D8D8D801DADADA01D8D8D801DDDDDD01D8D8D801 + DBDBDB02D7D7D701DCDCDC01DBDBDB01DADADA01DBDBDB01DADADA01DBDBDB01 + D9D9D902DADADA11D9D9D901DFDFDF01D8D8D801D9D9D902DBDBDB01DCDCDC01 + DADADA06DCDCDC01DADADA01D9D9D901DADADA01D8D8D801DBDBDB01D9D9D901 + DBDBDB01DCDCDC01D7D7D701FCFCFC01D7D7D701DBDBDB01A7A7A702A9A9A901 + A6A6A601ABABAB01A7A7A701D8D8D801D9D9D901DADADA01D9D9D901DDDDDD01 + DADADA01D8D8D801DBDBDB01DADADA02DFDFDF01D9D9D901DBDBDB01A8A8A801 + AAAAAA01DBDBDB02DDDDDD01DADADA01D9D9D904DCDCDC01FBFBFB01FFFFFF03 + DCDCDC01DADADA01D9D9D901D8D8D801DADADA01DEDEDE01DDDDDD01D7D7D701 + DADADA01D9D9D902DADADA02DDDDDD01D9D9D901DEDEDE01DADADA01DBDBDB01 + A5A5A501AAAAAA01FDFDFD01FFFFFF01DBDBDB01DADADA02D8D8D801DCDCDC01 + D7D7D701D9D9D901DADADA01D8D8D801DBDBDB01DADADA01DDDDDD01D7D7D701 + DCDCDC01DADADA02D9D9D901DCDCDC02D8D8D801DBDBDB02DCDCDC01D6D6D601 + D9D9D901DEDEDE01D8D8D801DCDCDC01D8D8D801D7D7D701DBDBDB02DADADA01 + D9D9D901DADADA01A9A9A901DBDBDB01DDDDDD01D6D6D601DBDBDB01D8D8D802 + DDDDDD01D6D6D601DCDCDC01D9D9D901D8D8D801DADADA02D7D7D701DEDEDE01 + DADADA10D9D9D901DBDBDB01D6D6D601DEDEDE01DBDBDB01D8D8D801DADADA01 + DCDCDC01DADADA08D9D9D901DADADA01DBDBDB01DADADA01DBDBDB02D7D7D701 + DEDEDE01FFFFFF02DBDBDB01DCDCDC01D9D9D901A7A7A702A9A9A901A8A8A801 + A9A9A901DBDBDB01D7D7D701DFDFDF01D7D7D701D9D9D901DDDDDD01DCDCDC01 + D8D8D801DADADA01D7D7D701FFFFFF02A7A7A702DADADA02D5D5D501DBDBDB01 + D8D8D801DCDCDC01DBDBDB01DADADA01DCDCDC01FFFFFF01FEFEFE01FFFFFF01 + DADADA01D8D8D801DADADA01DCDCDC02DADADA01D6D6D601DBDBDB02DCDCDC01 + DBDBDB02DADADA01D8D8D801DBDBDB01D7D7D701DADADA01DBDBDB02ABABAB01 + A6A6A601DCDCDC01D8D8D801DBDBDB01DADADA02DCDCDC01DBDBDB02DDDDDD01 + DADADA02D8D8D801DBDBDB01DADADA04DCDCDC02D7D7D701D8D8D801DADADA02 + D9D9D901D6D6D601DFDFDF01D8D8D801DBDBDB01DADADA01D9D9D901DADADA01 + DDDDDD01DCDCDC01D8D8D801DDDDDD01A9A9A901D9D9D901A7A7A701DCDCDC01 + D5D5D501A9A9A901A8A8A801A9A9A901DDDDDD01D9D9D902DEDEDE01D7D7D701 + DDDDDD01DADADA01D7D7D701DEDEDE01D6D6D601DADADA10DBDBDB01D9D9D901 + DCDCDC01D9D9D901DBDBDB02D9D9D901D7D7D701DADADA07D9D9D901D8D8D801 + DDDDDD01A8A8A801A7A7A701D8D8D801A6A6A601DBDBDB01D9D9D901D8D8D801 + FBFBFB01FFFFFF01FBFBFB01FFFFFF01DDDDDD01DBDBDB01A7A7A701A6A6A601 + AAAAAA01A7A7A701AAAAAA01A7A7A701DBDBDB01AAAAAA01A4A4A402DDDDDD01 + DBDBDB01DDDDDD01FFFFFF01FEFEFE01DBDBDB01A9A9A901D9D9D901DBDBDB01 + DEDEDE01DADADA01D7D7D701DBDBDB01D8D8D801DADADA01D7D7D701A6A6A601 + DEDEDE01D8D8D801D9D9D901DCDCDC01D9D9D901DADADA01D7D7D701DBDBDB01 + DDDDDD01DADADA01D7D7D701DBDBDB02D6D6D601DBDBDB01DFDFDF01D7D7D701 + DCDCDC01DADADA01FEFEFE01FDFDFD01DADADA01DBDBDB02A9A9A901A6A6A601 + D9D9D901DBDBDB01D8D8D801D9D9D903DBDBDB02D7D7D701DCDCDC01DADADA02 + D9D9D901DBDBDB01D8D8D802DEDEDE01DCDCDC01DBDBDB01D8D8D801DCDCDC01 + DADADA01D9D9D901DDDDDD01D7D7D701D9D9D902DCDCDC01D6D6D601D9D9D901 + DBDBDB01D9D9D901FCFCFC01A9A9A901A6A6A601ABABAB01DBDBDB01DADADA01 + A9A9A901A8A8A801A5A5A501DCDCDC01DADADA02D9D9D901D7D7D701DBDBDB01 + DADADA01DBDBDB02DADADA12D7D7D701DADADA01D9D9D901DADADA01DBDBDB01 + DCDCDC01DADADA06D9D9D901DBDBDB02D8D8D801D9D9D901AAAAAA01D9D9D901 + DBDBDB01DCDCDC01D7D7D701DADADA01DFDFDF01A4A4A401DDDDDD01D9D9D901 + D8D8D801DBDBDB01D8D8D801AAAAAA01A9A9A901D7D7D701DCDCDC01A7A7A701 + A8A8A801A7A7A701AAAAAA01DDDDDD01D7D7D701D9D9D902FFFFFF01DBDBDB01 + A9A9A901D9D9D901D8D8D801DBDBDB01D8D8D801D9D9D901DEDEDE01D8D8D801 + DCDCDC01D9D9D901DCDCDC01D9D9D901DADADA01D8D8D801DBDBDB01DADADA01 + DBDBDB01D9D9D901DADADA01DCDCDC01D8D8D801D9D9D901DEDEDE01D8D8D801 + D9D9D901DDDDDD01D8D8D801D9D9D901DBDBDB01A6A6A601DCDCDC01FFFFFF02 + DADADA01DDDDDD01A5A5A501DBDBDB01DCDCDC01DADADA03DCDCDC01DADADA01 + D9D9D901DADADA01D9D9D901DCDCDC01D8D8D801DADADA01D9D9D901DBDBDB01 + DADADA02DCDCDC01D8D8D801A7A7A701DCDCDC01D7D7D701DBDBDB02A7A7A701 + DADADA01DBDBDB01DADADA01D9D9D901DBDBDB01A8A8A801A9A9A901FDFDFD01 + DADADA01FFFFFF01D9D9D901AAAAAA01D8D8D801D7D7D701DEDEDE01A5A5A501 + A8A8A801ABABAB01A6A6A601DADADA02AAAAAA01A8A8A801DADADA01D9D9D901 + D8D8D801DBDBDB01DADADA12A8A8A801DEDEDE01D8D8D802DDDDDD01D7D7D701 + DADADA07D8D8D801FFFFFF01FDFDFD01D9D9D901DBDBDB01A7A7A701DCDCDC01 + D9D9D901DCDCDC01DADADA01A9A9A902DADADA01DBDBDB01FEFEFE01FFFFFF01 + DCDCDC01D8D8D801DCDCDC01FFFFFF01D8D8D801FFFFFF01DADADA01FFFFFF01 + D8D8D801A7A7A701A8A8A801DBDBDB01D8D8D801DBDBDB01DADADA01A8A8A801 + D8D8D801DADADA01DDDDDD01DADADA01D8D8D801DCDCDC01DADADA01DBDBDB01 + FFFFFF01DBDBDB01D9D9D902DADADA01D8D8D801DBDBDB01DADADA09DBDBDB02 + D9D9D901A8A8A801A7A7A701DCDCDC01D7D7D701DBDBDB02FFFFFF01D8D8D801 + DCDCDC01DBDBDB01DCDCDC01D9D9D901DADADA01D9D9D901DADADA01DBDBDB01 + D9D9D901DBDBDB01DCDCDC01DADADA02DEDEDE01D6D6D601DADADA01D9D9D901 + DDDDDD01D9D9D901DADADA01DCDCDC01A7A7A701DADADA01D9D9D901DADADA01 + DBDBDB01D7D7D701DCDCDC01DBDBDB01D8D8D801DBDBDB01DADADA01D9D9D901 + FFFFFF01FBFBFB01FFFFFF01A8A8A802DADADA01D9D9D902AAAAAA01A9A9A901 + A7A7A701D9D9D901DADADA01D8D8D801A8A8A801DDDDDD01DADADA01D7D7D701 + DCDCDC01D9D9D901DBDBDB01DADADA01DBDBDB01D8D8D801DCDCDC01D7D7D701 + DDDDDD01DADADA01DCDCDC01D9D9D902DDDDDD01D7D7D701D8D8D801DCDCDC01 + A7A7A701ACACAC01A4A4A401DBDBDB01DCDCDC01D9D9D901A8A8A801A6A6A601 + A7A7A701AAAAAA01A5A5A501DADADA01DDDDDD01D5D5D501DCDCDC01DADADA02 + FEFEFE01DDDDDD01D9D9D901A5A5A501DADADA02DCDCDC01FEFEFE01FDFDFD01 + D9D9D901D8D8D801DDDDDD01FFFFFF01FCFCFC01FFFFFF01A8A8A801A7A7A701 + FFFFFF02FEFEFE01FFFFFF01DADADA01A8A8A801ABABAB01D8D8D801DBDBDB01 + FFFFFF02D8D8D801DCDCDC01D8D8D801DCDCDC01D8D8D801D9D9D901DBDBDB01 + DADADA01D9D9D902DBDBDB01D8D8D801DCDCDC01D4D4D401DBDBDB01DCDCDC01 + DADADA09D9D9D901DBDBDB01D7D7D701FFFFFF01A7A7A701A9A9A901A4A4A401 + DFDFDF01DADADA01FDFDFD01D9D9D901ADADAD01D8D8D801D7D7D701A7A7A701 + DADADA01D9D9D901DCDCDC01D9D9D901DDDDDD01D8D8D801DCDCDC01D6D6D601 + D9D9D901DADADA01D7D7D701DEDEDE01DADADA01DDDDDD01FDFDFD01D8D8D801 + DDDDDD01D6D6D601ABABAB01FFFFFF01DEDEDE01D9D9D901DADADA01DDDDDD01 + D8D8D801FEFEFE01FFFFFF01D9D9D901D6D6D601DDDDDD01D8D8D801FFFFFF01 + D9D9D901DBDBDB01D6D6D601DEDEDE01D9D9D901DBDBDB01D8D8D801A7A7A701 + ABABAB01D6D6D601FFFFFF01DADADA01AAAAAA01A3A3A301DBDBDB02D9D9D901 + DDDDDD01D7D7D701A7A7A702DCDCDC01DADADA01D9D9D902DADADA01D8D8D801 + DBDBDB02D8D8D801E0E0E001DADADA01D7D7D701FFFFFF01D6D6D601DEDEDE01 + DADADA01D8D8D801A9A9A901A5A5A501ACACAC01AAAAAA01A3A3A301AAAAAA01 + D9D9D901D8D8D801DDDDDD01D7D7D701D9D9D901DCDCDC01FDFDFD01FFFFFF01 + D7D7D701DDDDDD01DADADA01DBDBDB01FDFDFD02DADADA01DDDDDD01A7A7A701 + AAAAAA01D7D7D701FFFFFF01DCDCDC01A7A7A701DADADA01D9D9D901DADADA01 + A7A7A701A8A8A801D5D5D501DEDEDE01A3A3A301DCDCDC02FBFBFB01FFFFFF01 + DDDDDD01D7D7D701DCDCDC01A8A8A801D8D8D801DADADA01E0E0E001D6D6D601 + DDDDDD02D4D4D401DCDCDC01DDDDDD01DADADA01DBDBDB01D8D8D801DADADA09 + DDDDDD01D8D8D801FFFFFF01FCFCFC01A8A8A801A9A9A901A8A8A801A5A5A501 + AAAAAA01DBDBDB01A9A9A901A6A6A601DBDBDB01DADADA01DFDFDF01DBDBDB02 + D8D8D801A8A8A801D8D8D801DCDCDC01D9D9D901D7D7D701DDDDDD01D9D9D901 + DFDFDF01D7D7D701D9D9D901DBDBDB01DADADA01DBDBDB01FBFBFB01DADADA01 + DBDBDB01A7A7A701D7D7D701D9D9D901D8D8D801DADADA01D9D9D901DBDBDB01 + D8D8D801D9D9D901DCDCDC01D9D9D901D6D6D601DBDBDB02D7D7D701DDDDDD01 + DADADA01D8D8D801DBDBDB01DCDCDC01A7A7A701A5A5A501ABABAB01D6D6D601 + A7A7A701A8A8A801A7A7A701A8A8A801A9A9A901A7A7A701A6A6A601AAAAAA01 + A8A8A801A7A7A701A6A6A601D9D9D901DCDCDC01DBDBDB01D9D9D901DADADA01 + DBDBDB01D9D9D901D8D8D801A9A9A901FFFFFF02FDFDFD01DEDEDE01D7D7D701 + D8D8D801FFFFFF01D9D9D904A9A9A902D8D8D801DEDEDE01D7D7D701DCDCDC02 + D7D7D701DADADA01FFFFFF01DBDBDB01DADADA01D9D9D902DEDEDE01DADADA02 + D9D9D901DCDCDC01A3A3A301ACACAC01D8D8D801DADADA01DEDEDE01D7D7D701 + DCDCDC01DBDBDB01A7A7A701DADADA01DEDEDE01A8A8A801DBDBDB01D8D8D801 + DADADA02A8A8A801D7D7D701DEDEDE01D7D7D701DBDBDB01DCDCDC01DADADA01 + D8D8D801DADADA01D9D9D902DDDDDD01D9D9D901D7D7D701DEDEDE01DADADA01 + D7D7D701DBDBDB01DADADA09D9D9D901FFFFFF02DCDCDC01A5A5A501A7A7A701 + ABABAB01A5A5A501DCDCDC01A9A9A901A6A6A601FFFFFF01D8D8D802A6A6A601 + DCDCDC01DADADA01DCDCDC01D8D8D801D9D9D901D8D8D801DFDFDF01D9D9D901 + DCDCDC01D6D6D601DCDCDC01DDDDDD01D9D9D902DEDEDE01FFFFFF01DADADA01 + D8D8D801DCDCDC01DBDBDB01DCDCDC01A5A5A501DCDCDC01DBDBDB02DCDCDC01 + DADADA02DBDBDB01FFFFFF01DBDBDB01D6D6D601FFFFFF01FAFAFA01DDDDDD01 + D8D8D801DADADA01D8D8D801D9D9D901AAAAAA01A9A9A901D9D9D901DEDEDE01 + A9A9A901A8A8A804DDDDDD01D5D5D501ABABAB02A9A9A901DCDCDC01DBDBDB01 + D9D9D901DFDFDF01D5D5D501DBDBDB01DADADA02D8D8D801DCDCDC01DADADA01 + DCDCDC01D9D9D901DADADA01FFFFFF02FEFEFE01DEDEDE01DADADA01D9D9D901 + A8A8A801DADADA01DCDCDC01D7D7D701D9D9D901DBDBDB01D8D8D801D9D9D901 + DBDBDB01D7D7D701D8D8D801DCDCDC01DADADA01D8D8D802D9D9D901DCDCDC01 + D9D9D901FFFFFF01AAAAAA01DADADA02D9D9D901DBDBDB02D9D9D901DADADA01 + DBDBDB01D9D9D901FFFFFF01D7D7D701DCDCDC01DBDBDB01DADADA01DBDBDB01 + DCDCDC01A7A7A701FDFDFD01DBDBDB02D7D7D702DADADA01DCDCDC01DADADA01 + D8D8D801DCDCDC01D7D7D701D9D9D901DADADA01D8D8D801DBDBDB01DADADA09 + D9D9D901DADADA01FFFFFF02FDFDFD01FFFFFF01DADADA01D8D8D801DADADA01 + DBDBDB01D7D7D701DCDCDC01DADADA01D8D8D801DFDFDF01D9D9D901FDFDFD01 + DCDCDC01D7D7D701DADADA01DFDFDF01D9D9D902A4A4A401A9A9A901DBDBDB01 + D8D8D801DBDBDB01D9D9D901DBDBDB01D9D9D902FFFFFF01DCDCDC01D8D8D801 + DDDDDD01D9D9D902DADADA01D8D8D801D9D9D901D6D6D601D9D9D901DADADA01 + FFFFFF01FCFCFC01FFFFFF04FCFCFC01DADADA01DCDCDC01DADADA01D8D8D801 + DBDBDB01D7D7D701DEDEDE01FBFBFB01FDFDFD01FFFFFF01D7D7D701DCDCDC01 + DADADA01D8D8D801DDDDDD01DADADA01A4A4A401A8A8A801A7A7A702DBDBDB01 + D6D6D601DDDDDD01DBDBDB01FDFDFD01DBDBDB01DCDCDC01D9D9D902D8D8D801 + DADADA02FFFFFF01FDFDFD01FFFFFF01FEFEFE01D8D8D801DADADA03D8D8D801 + DCDCDC01ABABAB01D7D7D701DEDEDE01DBDBDB01DADADA01DCDCDC01DEDEDE01 + D9D9D902FFFFFF01DADADA01FFFFFF01D7D7D701FFFFFF01D9D9D901FFFFFF01 + FEFEFE01DDDDDD01D7D7D701DADADA01A7A7A701DCDCDC01D7D7D701DDDDDD02 + D8D8D801DDDDDD01DBDBDB01D9D9D901FFFFFF01A7A7A702A9A9A901A8A8A801 + DADADA01DCDCDC01DDDDDD02DBDBDB01D7D7D701DBDBDB01DCDCDC01DBDBDB02 + DDDDDD01DADADA02D8D8D801DBDBDB01DADADA08DCDCDC01D9D9D901FEFEFE01 + FFFFFF06FDFDFD01DCDCDC01DBDBDB01D8D8D801FFFFFF01D8D8D801DADADA02 + DCDCDC01DADADA01DCDCDC01D9D9D901D5D5D501DFDFDF01AAAAAA01A8A8A801 + DADADA01DBDBDB01D7D7D701DCDCDC02D9D9D901DEDEDE01D7D7D701D8D8D801 + DBDBDB01FBFBFB01DEDEDE01D8D8D801DADADA01DCDCDC01DBDBDB01DDDDDD01 + D9D9D901DBDBDB01FFFFFF02D5D5D501DCDCDC01FBFBFB01FFFFFF01FDFDFD01 + DADADA01DBDBDB01DADADA02D9D9D901DCDCDC01D8D8D801DCDCDC01FFFFFF01 + D6D6D601FFFFFF01FDFDFD01D9D9D901FFFFFF01DBDBDB01D9D9D901AAAAAA01 + ABABAB01A6A6A601A7A7A701AAAAAA01ABABAB01D9D9D901DADADA01D8D8D801 + DDDDDD01D8D8D801DADADA02DBDBDB01DADADA01D8D8D801DADADA01FFFFFF02 + FCFCFC01DDDDDD01A9A9A901DBDBDB01A7A7A701A6A6A601DBDBDB01D6D6D601 + DADADA02DBDBDB01D6D6D601D9D9D901D4D4D401AAAAAA01DBDBDB01D7D7D701 + FEFEFE01FFFFFF01DADADA01FBFBFB01DEDEDE01FDFDFD01DCDCDC01D9D9D901 + FFFFFF02FCFCFC01FFFFFF02D8D8D801D7D7D701DBDBDB01D9D9D901DCDCDC01 + A7A7A701A8A8A801DCDCDC01A9A9A901A5A5A501DCDCDC01D8D8D801DBDBDB01 + A6A6A601DBDBDB01D9D9D901DCDCDC01D8D8D802D9D9D903DBDBDB02D7D7D701 + DCDCDC01DADADA0BD9D9D901FEFEFE01FFFFFF01FAFAFA01FEFEFE01DCDCDC01 + D9D9D901D8D8D801DCDCDC01D8D8D801D9D9D901DCDCDC01DBDBDB01DADADA01 + D7D7D701DBDBDB01D9D9D902FFFFFF01D7D7D701A6A6A601D8D8D801DBDBDB01 + DCDCDC01DADADA02D7D7D701DBDBDB01D6D6D601DCDCDC01D7D7D701DEDEDE01 + DCDCDC01D8D8D801DADADA01D9D9D903D8D8D801D9D9D901A8A8A801DBDBDB01 + D8D8D801DADADA01D8D8D801DADADA01FFFFFF02DBDBDB01D7D7D701DBDBDB02 + DADADA01A8A8A801A7A7A701A5A5A501FDFDFD01FFFFFF05D8D8D801DADADA01 + FFFFFF01FEFEFE01DCDCDC01D7D7D701D9D9D901A5A5A501D9D9D901DCDCDC02 + D8D8D801D7D7D701DEDEDE01D7D7D701DADADA01DBDBDB01DADADA01DBDBDB01 + D5D5D501FFFFFF02A8A8A802A7A7A701A8A8A801DCDCDC01D8D8D801DEDEDE01 + DCDCDC01D7D7D701D8D8D801DDDDDD01DBDBDB02A9A9A901D8D8D801DBDBDB01 + DADADA01D8D8D801DDDDDD01A9A9A901D7D7D701DCDCDC01D8D8D801DBDBDB01 + FDFDFD01DADADA01DDDDDD01FFFFFF01FDFDFD01DDDDDD01A8A8A801A7A7A701 + A9A9A901D7D7D701DCDCDC01D9D9D902D8D8D801ABABAB01A7A7A701DBDBDB01 + DADADA01D8D8D801DDDDDD01D7D7D701DADADA01DCDCDC01DADADA01DCDCDC01 + DADADA01D9D9D901DADADA01D9D9D901DCDCDC01D8D8D801DADADA08D9D9D901 + DBDBDB01D8D8D801DFDFDF01D7D7D701D8D8D801DEDEDE01D9D9D902DBDBDB02 + D8D8D801DBDBDB01DDDDDD01D8D8D801D9D9D902DDDDDD01D9D9D901D8D8D801 + DFDFDF01FDFDFD01FEFEFE01A9A9A901AAAAAA01DADADA01D9D9D902DBDBDB01 + DADADA01DBDBDB02DADADA01DBDBDB01D9D9D901D7D7D701DADADA01DBDBDB01 + D9D9D901DADADA01D9D9D901DEDEDE01A7A7A702A6A6A601DCDCDC01D9D9D901 + A8A8A801DADADA01FEFEFE01DBDBDB01DADADA01D9D9D901DBDBDB01D9D9D901 + DADADA02A8A8A801FFFFFF01DCDCDC01DADADA01FDFDFD01DADADA01FFFFFF01 + FEFEFE01FFFFFF01DADADA01D9D9D901FFFFFF01FDFDFD01DEDEDE01A8A8A801 + A9A9A901A8A8A801D9D9D902DCDCDC01D9D9D902DBDBDB01DADADA01D9D9D901 + DCDCDC01D8D8D801DCDCDC01FFFFFF02D8D8D801DBDBDB01DADADA01A7A7A701 + A9A9A901A7A7A701D9D9D901DBDBDB01DADADA02DBDBDB01FFFFFF01FBFBFB01 + FFFFFF01D9D9D901A9A9A902D9D9D901FDFDFD01DCDCDC01DBDBDB01D9D9D901 + DADADA03A8A8A802D7D7D701DCDCDC01A9A9A901A8A8A801A6A6A601FFFFFF01 + D8D8D801DADADA02D9D9D901A8A8A801AAAAAA01A9A9A901DADADA03D9D9D901 + DADADA01D9D9D901DADADA01D9D9D901DADADA03D9D9D901DCDCDC01D8D8D801 + DADADA11DBDBDB01D9D9D901DCDCDC01DADADA02DBDBDB01D8D8D801DADADA03 + DCDCDC01D6D6D601FFFFFF02D7D7D701AAAAAA01A8A8A801A5A5A501DCDCDC01 + DBDBDB01DADADA01D9D9D901DADADA03D8D8D801DDDDDD01DADADA01A8A8A801 + A7A7A701D9D9D901DADADA02DBDBDB01A8A8A801AAAAAA01A6A6A601A9A9A901 + AAAAAA01A5A5A501A9A9A901DBDBDB01D9D9D901DBDBDB01DADADA01D9D9D901 + DCDCDC01DADADA01DCDCDC01A4A4A401DCDCDC01DADADA02DBDBDB01DADADA01 + FFFFFF01FEFEFE01A8A8A802AAAAAA01A8A8A801D8D8D801DADADA01A9A9A901 + A8A8A801DADADA01D9D9D901DBDBDB01DADADA01D8D8D801DDDDDD01D9D9D901 + DBDBDB01DADADA01D9D9D901DCDCDC01D8D8D801FFFFFF02DADADA01D8D8D801 + DBDBDB01AAAAAA01A8A8A802DCDCDC01D9D9D902DCDCDC01D8D8D801FFFFFF02 + D6D6D601DDDDDD01A7A7A701FCFCFC01FFFFFF01DDDDDD02D5D5D501DADADA02 + FEFEFE01FFFFFF01D9D9D902E0E0E001FCFCFC01FFFFFF01FEFEFE01DBDBDB01 + DADADA01D9D9D901DBDBDB02DADADA01D7D7D701A9A9A901A8A8A801A7A7A701 + A8A8A801D9D9D901DADADA01DBDBDB01D8D8D801DCDCDC02DADADA01D7D7D701 + DBDBDB01DDDDDD01D5D5D501DCDCDC01DADADA12DCDCDC01D8D8D802D9D9D901 + DCDCDC02A9A9A901DADADA01DBDBDB01DADADA03FFFFFF01D9D9D901A7A7A701 + A9A9A901DCDCDC01D8D8D802DBDBDB02D9D9D901DBDBDB02D7D7D701DADADA02 + D8D8D801DCDCDC01DADADA01DBDBDB01FFFFFF01D9D9D902A7A7A701ABABAB01 + FDFDFD01A5A5A501ACACAC01D7D7D701DDDDDD01D7D7D701D9D9D901DDDDDD01 + FEFEFE01FDFDFD01DBDBDB01A8A8A802DCDCDC01DBDBDB01D8D8D803DADADA01 + FFFFFF02A8A8A801A2A2A201DBDBDB01DCDCDC01D7D7D701DCDCDC01A8A8A801 + D8D8D801DDDDDD01DBDBDB01D7D7D701DDDDDD01D9D9D901DBDBDB01D8D8D801 + DCDCDC02D8D8D801D9D9D901ACACAC01DADADA02FFFFFF02D4D4D401A9A9A901 + A7A7A701A6A6A601DADADA01DCDCDC01D9D9D901DCDCDC01DADADA02FFFFFF02 + DCDCDC01A9A9A901A8A8A801D9D9D901D7D7D701DDDDDD01DBDBDB01D8D8D801 + FFFFFF02D9D9D901D7D7D701FEFEFE01FFFFFF01DADADA01A9A9A901D9D9D901 + DCDCDC01DADADA02DBDBDB01DADADA02D8D8D801A8A8A801AAAAAA01A5A5A501 + DCDCDC01D8D8D801DFDFDF01D9D9D901D8D8D801D7D7D701DBDBDB01D9D9D901 + D7D7D701D9D9D901DCDCDC01DBDBDB01D9D9D901DADADA10D9D9D902DDDDDD01 + DADADA01DCDCDC01DEDEDE01D4D4D401A7A7A701DADADA01D6D6D601DADADA01 + DCDCDC01D8D8D801FDFDFD01DDDDDD01DBDBDB01D9D9D901D8D8D801DCDCDC02 + D9D9D901DADADA01A8A8A802A9A9A901DDDDDD01FDFDFD01FFFFFF01A6A6A601 + DADADA01DBDBDB01FEFEFE01FFFFFF02D9D9D901DCDCDC01FDFDFD01FFFFFF02 + D9D9D901DADADA01D8D8D801DDDDDD01DBDBDB01DADADA01DEDEDE01FBFBFB01 + DCDCDC01A5A5A501AAAAAA01A5A5A501D9D9D901DBDBDB01DDDDDD01DCDCDC01 + FEFEFE02DCDCDC01D6D6D601B0B0B001DBDBDB01D8D8D801DCDCDC01A5A5A501 + A8A8A801AAAAAA01A7A7A702DEDEDE01D8D8D801A7A7A701DBDBDB01DADADA02 + D8D8D801A8A8A801DADADA01D6D6D601DADADA01FFFFFF01FEFEFE01DBDBDB01 + D8D8D801DEDEDE01DADADA01DCDCDC01D8D8D801DCDCDC01DADADA01D8D8D801 + DCDCDC01DBDBDB01FDFDFD01D8D8D801D9D9D901A8A8A801A7A7A701DBDBDB01 + A8A8A801D9D9D901DBDBDB02A5A5A501A7A7A701DCDCDC01DBDBDB01DEDEDE01 + A4A4A401ABABAB01DADADA04D8D8D801DBDBDB03DCDCDC01DBDBDB01A5A5A501 + ACACAC01D9D9D901DCDCDC01D7D7D701DADADA01DCDCDC01DADADA01DBDBDB04 + DADADA01D7D7D701DBDBDB01DADADA10D8D8D801DBDBDB01DADADA02D8D8D801 + FFFFFF01DFDFDF01A8A8A801A9A9A901AAAAAA01ABABAB01A5A5A501FFFFFF01 + FEFEFE01FDFDFD01D8D8D801A8A8A801ACACAC01A8A8A801D7D7D701DCDCDC01 + DADADA01D9D9D901A8A8A801D7D7D701DBDBDB01DADADA01D7D7D701DDDDDD01 + DADADA02FFFFFF01FEFEFE01FBFBFB01FFFFFF01D9D9D901FFFFFF01FEFEFE01 + FCFCFC01DADADA01DDDDDD01DBDBDB01D9D9D901A6A6A601D9D9D901FCFCFC01 + FFFFFF02A9A9A901A7A7A702AAAAAA01DBDBDB01D8D8D801D6D6D601DCDCDC01 + FEFEFE01DBDBDB01DADADA01D6D6D601D9D9D901DBDBDB02A8A8A801A7A7A702 + AAAAAA01A8A8A801A7A7A701AAAAAA01D6D6D601DCDCDC02D8D8D801DDDDDD01 + DCDCDC01D9D9D901DDDDDD01A6A6A601A8A8A801FFFFFF01DBDBDB01D9D9D901 + FCFCFC01DBDBDB01D9D9D901DDDDDD01D8D8D801DCDCDC01DADADA02D6D6D601 + DBDBDB01FFFFFF02A9A9A902D8D8D801A9A9A901DBDBDB01D8D8D801A8A8A801 + DCDCDC01D8D8D801DDDDDD01DBDBDB01D6D6D601D9D9D901DBDBDB01D7D7D701 + D8D8D801DCDCDC01DEDEDE01D9D9D901DBDBDB01D6D6D601DADADA01D8D8D802 + A9A9A901A6A6A601DADADA01DCDCDC01D6D6D601DEDEDE01D6D6D601D9D9D901 + DBDBDB01D7D7D701DCDCDC01D9D9D901DADADA13DCDCDC01DADADA01D8D8D801 + DFDFDF01D6D6D601FFFFFF01D7D7D701DBDBDB01A8A8A801DBDBDB01A5A5A501 + A6A6A601D9D9D901FDFDFD01DEDEDE01DBDBDB01A6A6A601A5A5A501AAAAAA01 + DADADA01FFFFFF01FDFDFD01DCDCDC01A8A8A801DCDCDC01D9D9D901FFFFFF01 + DDDDDD01D6D6D601DCDCDC01D9D9D901DBDBDB01FFFFFF02D9D9D901DADADA01 + D8D8D801FFFFFF03D7D7D701DBDBDB01D8D8D801FEFEFE01DDDDDD01FFFFFF02 + FEFEFE01DADADA01A8A8A803A5A5A501D9D9D901E0E0E001FDFDFD01FFFFFF01 + DADADA01DBDBDB01D9D9D901DBDBDB01DADADA01D8D8D801D9D9D901DADADA01 + DBDBDB01A9A9A901A5A5A501DCDCDC01A8A8A801A9A9A901DBDBDB01D9D9D901 + FFFFFF01DADADA01FEFEFE01FFFFFF01D8D8D801A7A7A701FEFEFE02A9A9A902 + DBDBDB01D9D9D901DDDDDD01DADADA01D9D9D901D6D6D601DBDBDB01D9D9D901 + DDDDDD01DBDBDB01FCFCFC02ACACAC01FEFEFE01DADADA01DDDDDD01D7D7D701 + D9D9D901FFFFFF01AAAAAA01A6A6A602DADADA01DEDEDE01DBDBDB01D9D9D901 + DDDDDD01DADADA01D9D9D901D6D6D601DDDDDD01D9D9D901DCDCDC01DDDDDD01 + D8D8D801DADADA01AEAEAE01A6A6A601D6D6D601DDDDDD01DBDBDB03DCDCDC01 + D7D7D701DDDDDD01D6D6D601DADADA01AAAAAA01A6A6A601DDDDDD01DADADA10 + D9D9D901DBDBDB02D6D6D601DFDFDF01FEFEFE01FFFFFF03FDFDFD01A8A8A802 + DDDDDD01DCDCDC01FCFCFC01FEFEFE02DCDCDC01DADADA01DBDBDB01D9D9D901 + FFFFFF01D9D9D901D8D8D801DADADA01D9D9D902D8D8D801DCDCDC01DBDBDB01 + D9D9D901DADADA01D9D9D901DDDDDD01D8D8D801DCDCDC01DBDBDB01FDFDFD01 + FEFEFE02DCDCDC01DADADA01A8A8A801DCDCDC01D8D8D801D9D9D901D8D8D801 + DCDCDC01D9D9D901DADADA01A9A9A901A8A8A801A6A6A601ABABAB01A5A5A501 + FEFEFE02DBDBDB02D9D9D901DADADA01DBDBDB01DADADA01DBDBDB01DCDCDC01 + D8D8D801DADADA02A5A5A501A7A7A701DCDCDC01D7D7D701DADADA01FFFFFF01 + F9F9F901FEFEFE01FFFFFF02A7A7A701FFFFFF01DEDEDE01D5D5D501DBDBDB01 + DCDCDC01D8D8D801D7D7D701DADADA01DCDCDC01DBDBDB02D8D8D802DBDBDB01 + FFFFFF02D5D5D501FFFFFF01D9D9D901A8A8A801FFFFFF01DCDCDC01DADADA01 + A6A6A601ACACAC01DADADA01D9D9D902D6D6D601DADADA01D9D9D901DBDBDB03 + D9D9D901DBDBDB01D8D8D801DADADA01DBDBDB01DCDCDC01A2A2A201DCDCDC01 + DBDBDB02D9D9D902DBDBDB01D7D7D701DCDCDC01DBDBDB01D8D8D801A9A9A901 + A8A8A801A7A7A701A6A6A601DADADA10D9D9D901DADADA02DBDBDB01D9D9D902 + FFFFFF01D9D9D901FEFEFE01FFFFFF02A9A9A901A8A8A801D7D7D701FFFFFF01 + DBDBDB01FFFFFF01DCDCDC01DADADA01D8D8D801FFFFFF01FBFBFB01DBDBDB01 + DEDEDE01DADADA01DDDDDD01D9D9D901DBDBDB01D9D9D901D7D7D701DBDBDB01 + DADADA01D9D9D901DADADA01DEDEDE01D9D9D901D8D8D801DCDCDC01FEFEFE01 + FFFFFF01FEFEFE01DBDBDB02D9D9D901DADADA01DCDCDC01DADADA01FEFEFE01 + D8D8D801DBDBDB01DADADA01A7A7A701A8A8A801A9A9A901A7A7A701DBDBDB01 + FFFFFF01DCDCDC01DADADA01D8D8D801DBDBDB01D9D9D901DCDCDC01D8D8D801 + D7D7D701DDDDDD01DADADA01DBDBDB02ABABAB01A7A7A701AAAAAA01A8A8A801 + D6D6D601DDDDDD01DBDBDB01FFFFFF01D9D9D901DADADA01FFFFFF02DBDBDB01 + D7D7D701DBDBDB01DADADA01DBDBDB01DADADA02D8D8D801DDDDDD01D9D9D901 + DADADA02FFFFFF01D9D9D901DCDCDC01DADADA02FFFFFF01DDDDDD01FDFDFD01 + FEFEFE01D9D9D901DADADA02DBDBDB01DADADA01DDDDDD01DADADA03D9D9D901 + DCDCDC01D8D8D801D9D9D901DBDBDB01DADADA02D9D9D901ACACAC01DBDBDB01 + D9D9D903DBDBDB01DADADA01DCDCDC01D6D6D601DADADA01FFFFFF01DBDBDB01 + A7A7A701DBDBDB01D8D8D801DADADA10DCDCDC01D8D8D801DCDCDC01DADADA01 + D9D9D901DADADA01D9D9D901DADADA01FFFFFF02DBDBDB01DADADA01D7D7D701 + DEDEDE01D9D9D901A8A8A801D9D9D901DADADA02DBDBDB01D9D9D901DCDCDC01 + DBDBDB01D8D8D802DCDCDC01D9D9D901DADADA01D9D9D901DCDCDC01D9D9D901 + DBDBDB01DCDCDC01D8D8D801DADADA03DBDBDB01FFFFFF01FEFEFE01FFFFFF01 + D7D7D701DADADA01D9D9D901FFFFFF01FCFCFC01FFFFFF03D9D9D901D8D8D801 + DDDDDD01D7D7D701A7A7A701A9A9A901DADADA01DBDBDB01D7D7D701D9D9D901 + DEDEDE01D8D8D801DADADA01DCDCDC01DADADA01DBDBDB02D8D8D801DCDCDC01 + A6A6A601A9A9A901A7A7A702A9A9A901DADADA02D9D9D901FCFCFC01DEDEDE01 + FDFDFD01DBDBDB01D9D9D901DBDBDB01DCDCDC01DADADA02D9D9D901DADADA09 + DBDBDB01FEFEFE01DBDBDB01D8D8D801DCDCDC01FEFEFE01FFFFFF01DBDBDB01 + FCFCFC01FFFFFF01FDFDFD01D8D8D801DADADA01D9D9D901DADADA02DBDBDB01 + DDDDDD01D7D7D701DCDCDC01DADADA01D7D7D701DDDDDD01A9A9A901A7A7A701 + D9D9D901DBDBDB01DADADA03DBDBDB01D9D9D901DADADA01D9D9D901DCDCDC01 + D8D8D801FFFFFF01DDDDDD01D8D8D801D7D7D701DFDFDF01D8D8D801DBDBDB02 + D9D9D904DADADA02D8D8D801DCDCDC01D9D9D901DBDBDB01DADADA01D8D8D801 + DCDCDC01DADADA02D9D9D901DADADA01DCDCDC01DADADA01D9D9D901FFFFFF01 + FEFEFE01D7D7D701DBDBDB01FFFFFF01DDDDDD01D8D8D801DBDBDB01D8D8D801 + DBDBDB01D9D9D901D8D8D801DADADA03D9D9D901DBDBDB01D9D9D901DADADA01 + DCDCDC02DBDBDB01D9D9D901DBDBDB01D9D9D901DADADA02D9D9D901DADADA01 + D8D8D801DBDBDB01DADADA01A6A6A601DBDBDB01DADADA01D9D9D901AAAAAA01 + FBFBFB01FFFFFF02D6D6D601DBDBDB01DCDCDC01DADADA01DDDDDD01A8A8A801 + DADADA01D8D8D801DEDEDE01D9D9D902DCDCDC01D8D8D802DCDCDC01DADADA01 + D9D9D901DCDCDC01DADADA01D8D8D801DEDEDE01D7D7D701A9A9A901A8A8A801 + A9A9A901DDDDDD01D7D7D701DBDBDB01D9D9D901DADADA01D9D9D901DADADA0E + DEDEDE01D5D5D501DADADA01D9D9D901DBDBDB01D9D9D901FFFFFF01FDFDFD02 + FFFFFF01FAFAFA01FDFDFD01E2E2E201DADADA01D9D9D901DBDBDB01D9D9D901 + DCDCDC01D7D7D701DADADA01D9D9D901DCDCDC01DBDBDB01D8D8D801A7A7A701 + A8A8A801DBDBDB01A8A8A803DADADA01D8D8D801D9D9D901AAAAAA01DBDBDB01 + D8D8D801ACACAC01A7A7A701DADADA01DDDDDD01DBDBDB02DADADA01D8D8D801 + D7D7D701DDDDDD01DCDCDC01DBDBDB01DCDCDC01DADADA01DBDBDB01DADADA02 + DBDBDB01DADADA01D8D8D801DDDDDD01D7D7D701DCDCDC01DBDBDB01D9D9D903 + D8D8D801DBDBDB01DADADA01D9D9D901DADADA01DCDCDC01FBFBFB01D8D8D801 + A7A7A701DCDCDC01D6D6D601DCDCDC02DDDDDD01D8D8D801DBDBDB03D9D9D901 + DBDBDB01D6D6D601D9D9D901D8D8D802DCDCDC01DADADA01DBDBDB02DCDCDC01 + D9D9D901DBDBDB01DDDDDD01D8D8D801A8A8A801AAAAAA01A7A7A701A8A8A801 + D7D7D701D9D9D901DBDBDB01FFFFFF01FDFDFD01FFFFFF01DCDCDC01D5D5D501 + FFFFFF01FDFDFD01D8D8D801DCDCDC01DDDDDD01D6D6D601DCDCDC01DADADA01 + D8D8D801DEDEDE01DBDBDB01D7D7D701DADADA01DDDDDD01D6D6D601DADADA01 + FEFEFE01FFFFFF01D8D8D801AAAAAA01A7A7A701A8A8A801A5A5A501DCDCDC01 + DBDBDB02DADADA10D6D6D601DCDCDC01DBDBDB01DDDDDD01D8D8D801DCDCDC01 + FFFFFF01D9D9D902DFDFDF01FDFDFD01FFFFFF01D5D5D501DADADA01D9D9D901 + DBDBDB02D9D9D901DADADA01DFDFDF01D8D8D801D9D9D902DDDDDD01A6A6A601 + A8A8A801A7A7A701AAAAAA02A6A6A601AAAAAA01DADADA01FFFFFF01DCDCDC01 + D9D9D901A6A6A601A9A9A901A8A8A801D7D7D701DADADA01DBDBDB01D6D6D601 + D8D8D801E0E0E001A7A7A701A5A5A501DADADA03A5A5A501DBDBDB01D9D9D901 + DDDDDD01D6D6D601DADADA01DDDDDD01DBDBDB01D9D9D901DADADA02DDDDDD01 + DBDBDB03D9D9D901D8D8D801DBDBDB01D9D9D901DADADA01DCDCDC01DDDDDD01 + DBDBDB01A6A6A601DEDEDE01D8D8D801DADADA01D7D7D701DBDBDB01DDDDDD01 + D7D7D701D9D9D901DADADA01DCDCDC02DBDBDB01DCDCDC01DADADA02D7D7D701 + DEDEDE01D8D8D801D6D6D601A9A9A901A6A6A601D9D9D901FFFFFF01D9D9D901 + D7D7D701FFFFFF01FEFEFE01DDDDDD01DEDEDE01D8D8D801FEFEFE01FFFFFF01 + FEFEFE01D9D9D901DADADA01DDDDDD01FFFFFF04FEFEFE01FFFFFF01DBDBDB01 + DADADA01D9D9D901DBDBDB01DDDDDD01DADADA01D8D8D801DDDDDD01FFFFFF02 + FDFDFD01FFFFFF01FCFCFC01A9A9A901A8A8A801AAAAAA01A5A5A501DBDBDB01 + DADADA01DDDDDD01D7D7D701DADADA0EDBDBDB01DADADA02D8D8D801DADADA01 + D9D9D901DBDBDB02D8D8D802FFFFFF03DADADA01D9D9D902DADADA02D9D9D903 + DADADA01DCDCDC01D8D8D801A8A8A801DADADA01DCDCDC01D7D7D701A5A5A501 + AAAAAA01A5A5A501DDDDDD01D7D7D701DADADA02DCDCDC01A7A7A701A9A9A901 + DDDDDD01DADADA02DCDCDC01A7A7A703DDDDDD01D9D9D902D8D8D801DEDEDE01 + D7D7D701DBDBDB01D8D8D801DEDEDE01D9D9D902DADADA01DBDBDB01D8D8D801 + DADADA01D9D9D901D7D7D701DCDCDC01D8D8D801DCDCDC01DADADA02DDDDDD01 + D7D7D701DADADA01A3A3A301DBDBDB01A8A8A801DCDCDC01D8D8D801DBDBDB02 + D8D8D801DADADA01DCDCDC01A9A9A901D9D9D901D7D7D701DBDBDB01D8D8D802 + DEDEDE01D7D7D701D9D9D902DCDCDC01DBDBDB02DDDDDD01FEFEFE01FFFFFF03 + A5A5A501D9D9D901DBDBDB01D7D7D701D9D9D901DCDCDC01FFFFFF01FEFEFE01 + DCDCDC01D9D9D901FEFEFE02FFFFFF01DBDBDB01FFFFFF02DADADA01D9D9D901 + DBDBDB01DADADA01D8D8D801D7D7D701D9D9D904FFFFFF02FEFEFE01FFFFFF01 + FDFDFD01ABABAB01A5A5A501A9A9A901DEDEDE01D7D7D701D8D8D801DADADA0F + DBDBDB01D8D8D801D9D9D901ACACAC01D8D8D801DCDCDC01DBDBDB01D8D8D801 + DADADA01DBDBDB01FFFFFF01FCFCFC01FDFDFD01DBDBDB02D9D9D901D8D8D801 + DDDDDD01D7D7D701DCDCDC01DBDBDB01D8D8D801DCDCDC01DADADA01DBDBDB01 + D8D8D801DADADA03D9D9D901DEDEDE01FAFAFA01DCDCDC01D8D8D801DEDEDE01 + D7D7D701A7A7A701A6A6A601D7D7D701DCDCDC01DADADA01D9D9D901FFFFFF01 + DADADA01ACACAC01D9D9D901DCDCDC01FEFEFE01DDDDDD01D9D9D901DBDBDB01 + DADADA01D8D8D801DADADA01D9D9D901DCDCDC01DBDBDB01D7D7D701DADADA01 + DEDEDE01D7D7D701D9D9D901DCDCDC01D9D9D901DADADA01DDDDDD01D6D6D601 + D7D7D701DCDCDC01A8A8A801FFFFFF01D9D9D901DCDCDC01D7D7D701DADADA01 + D8D8D802DADADA01DBDBDB02D9D9D901D8D8D801DCDCDC01DDDDDD01D9D9D901 + DADADA01D8D8D801DDDDDD02D9D9D901FDFDFD01FFFFFF01D8D8D801DADADA01 + D8D8D801DADADA01D9D9D901DADADA01A7A7A701ABABAB01D7D7D701A9A9A901 + AAAAAA01D9D9D901FFFFFF03D8D8D801DBDBDB04D7D7D701FFFFFF03FCFCFC01 + DEDEDE01D9D9D901FFFFFF02DCDCDC01D9D9D901DBDBDB02D9D9D901FFFFFF02 + FEFEFE01FFFFFF01D9D9D901DADADA01D9D9D901DDDDDD01D8D8D801DDDDDD01 + DADADA0ED8D8D801E0E0E001A5A5A501A7A7A701DCDCDC01D8D8D802DBDBDB01 + DADADA01D9D9D901D8D8D801FFFFFF01FCFCFC01FFFFFF02D9D9D901DDDDDD01 + DADADA01DCDCDC01D8D8D801D5D5D501DEDEDE01D7D7D701DADADA01DBDBDB04 + FFFFFF01FDFDFD02FFFFFF02FEFEFE01D9D9D901DBDBDB01A7A7A701DCDCDC01 + DDDDDD01DADADA01FFFFFF03AAAAAA01A2A2A201A7A7A701D9D9D901A9A9A901 + D8D8D801D6D6D601DEDEDE01DCDCDC01D9D9D901DCDCDC01DADADA01D8D8D801 + DADADA01D8D8D801DBDBDB01DADADA01DDDDDD01DCDCDC01D4D4D401DDDDDD01 + A7A7A701D7D7D701DEDEDE01FFFFFF01FEFEFE01DBDBDB01FEFEFE01D8D8D802 + DBDBDB01DADADA01DEDEDE01DCDCDC01D7D7D701FFFFFF01D6D6D601DDDDDD01 + DADADA01A9A9A901A4A4A401D9D9D901DBDBDB01DADADA01D8D8D801D6D6D601 + DFDFDF01D8D8D801DADADA01DBDBDB01DADADA01DDDDDD01D8D8D801DBDBDB01 + A8A8A801AAAAAA01A6A6A601ACACAC01A6A6A602DADADA01D6D6D601DCDCDC01 + D8D8D801DBDBDB01D9D9D901FFFFFF01D7D7D701DADADA01FFFFFF01FBFBFB01 + FFFFFF01FBFBFB01DADADA01FFFFFF01FDFDFD01FFFFFF01D7D7D701D9D9D901 + DDDDDD01D8D8D801DADADA01D9D9D901D8D8D801FFFFFF02FEFEFE01DADADA01 + DBDBDB01D9D9D901DADADA01DBDBDB01D8D8D801DADADA0ED7D7D701FFFFFF01 + A8A8A802DADADA02DDDDDD01D9D9D901DCDCDC01D7D7D701DBDBDB01FFFFFF03 + FDFDFD01FFFFFF01FDFDFD01D7D7D701DCDCDC01DADADA01DEDEDE01DADADA01 + D8D8D801DCDCDC01D9D9D901FFFFFF01FDFDFD01DCDCDC01D7D7D701DDDDDD01 + FDFDFD01FFFFFF03DADADA01D8D8D801E0E0E001D8D8D801DADADA01D9D9D902 + FFFFFF01FCFCFC01DBDBDB01ACACAC01D9D9D902A9A9A901DBDBDB01DCDCDC01 + DADADA01D8D8D801D9D9D901DADADA01DBDBDB01DCDCDC01DADADA01DCDCDC01 + DBDBDB01D4D4D401DCDCDC01D8D8D801DBDBDB01D8D8D801DDDDDD01D7D7D701 + DADADA01FDFDFD01D8D8D801D9D9D901DADADA01DBDBDB02DDDDDD01D7D7D701 + D5D5D501DADADA01DCDCDC01A8A8A802DADADA01D7D7D701A8A8A801ABABAB01 + DADADA01D9D9D901DADADA01DBDBDB01DEDEDE01D8D8D802DCDCDC01D8D8D801 + DADADA01D8D8D801DCDCDC01D9D9D901D7D7D701DDDDDD01D8D8D801FDFDFD01 + DDDDDD01DBDBDB01DADADA01DBDBDB01DADADA02D8D8D801DDDDDD01A6A6A601 + DDDDDD01D9D9D901A8A8A801DBDBDB01DCDCDC01FEFEFE01FFFFFF01DADADA01 + DBDBDB01D9D9D901ACACAC01A9A9A901D5D5D501DDDDDD02D7D7D701DCDCDC01 + D7D7D701DBDBDB01D9D9D901DBDBDB01DADADA02DCDCDC02D9D9D901DADADA0E + FFFFFF02D9D9D901DADADA01DBDBDB01D8D8D801D9D9D901DADADA01D9D9D901 + DADADA01DBDBDB01DADADA01D9D9D901FFFFFF01FDFDFD01FFFFFF03FEFEFE01 + DADADA02D9D9D901FFFFFF01DADADA01FFFFFF02D5D5D501DDDDDD01DCDCDC01 + D7D7D701DCDCDC01DADADA01FFFFFF01D9D9D901DBDBDB01DADADA01D9D9D901 + DBDBDB01D8D8D801DBDBDB02FEFEFE01FFFFFF01FDFDFD01DADADA01FFFFFF01 + DBDBDB01D9D9D902DCDCDC01D9D9D902DBDBDB01DADADA01D9D9D902DBDBDB01 + D8D8D801DBDBDB01D9D9D902DBDBDB01FFFFFF01DBDBDB01D8D8D801DDDDDD01 + D8D8D801DBDBDB02DADADA01D9D9D901DADADA01DBDBDB01A5A5A501DCDCDC01 + A8A8A801AAAAAA01A5A5A501A7A7A701DBDBDB01FFFFFF02DBDBDB01D9D9D901 + DADADA04D8D8D801DCDCDC01DADADA02DCDCDC01D9D9D901FFFFFF01D9D9D901 + DDDDDD01FDFDFD01FEFEFE01FFFFFF02D9D9D901DBDBDB01DADADA01DBDBDB01 + D7D7D701D9D9D901DDDDDD01D9D9D901D8D8D801DCDCDC01A8A8A802D9D9D901 + FDFDFD01DCDCDC01DBDBDB01D7D7D701A8A8A802A7A7A702DBDBDB01DADADA01 + D6D6D601DBDBDB01DCDCDC01D9D9D901A9A9A901DADADA01D9D9D901DADADA02 + D8D8D801DADADA08DBDBDB01D8D8D801DDDDDD01DBDBDB02DADADA01D7D7D701 + DCDCDC01FFFFFF02D9D9D902DBDBDB01DADADA01DCDCDC01DADADA02DBDBDB01 + D9D9D901DCDCDC01DBDBDB01D9D9D901DADADA01FDFDFD01FFFFFF01FEFEFE02 + DADADA01FFFFFF02FEFEFE01DADADA02DBDBDB01D8D8D801DADADA01DBDBDB01 + D8D8D801DCDCDC01D9D9D901FEFEFE01DCDCDC01A9A9A901D9D9D901A8A8A801 + DBDBDB01D8D8D801DCDCDC01DADADA02FCFCFC01DCDCDC01D8D8D801FFFFFF01 + DADADA02D8D8D801DDDDDD01DADADA01D9D9D901A7A7A701DADADA02DBDBDB02 + DCDCDC01D7D7D701DBDBDB01DADADA01DBDBDB01D8D8D801DADADA03DEDEDE01 + D6D6D601A9A9A901DBDBDB01DADADA01DBDBDB01DCDCDC01A6A6A601A9A9A901 + A8A8A801DADADA01DBDBDB01A4A4A401DCDCDC01FFFFFF02D8D8D801DADADA01 + DCDCDC01DADADA01D9D9D901DCDCDC01D9D9D901DBDBDB01D9D9D902DDDDDD01 + D8D8D801D9D9D901DADADA01A7A7A701FDFDFD01DBDBDB01DADADA01DBDBDB01 + DADADA01D9D9D901DADADA03D9D9D901FFFFFF01DCDCDC01DADADA01FFFFFF01 + D9D9D901A9A9A901A5A5A501D9D9D901A7A7A701D9D9D901DBDBDB02FFFFFF01 + DCDCDC01D8D8D801DCDCDC01D7D7D701DCDCDC02D8D8D801DBDBDB01D9D9D901 + DCDCDC01D8D8D801DCDCDC01D8D8D801DADADA01DCDCDC01D9D9D902DADADA01 + D9D9D901DBDBDB01DDDDDD01D9D9D901D7D7D701DFDFDF01D6D6D601D8D8D801 + DADADA01D9D9D901DDDDDD01D8D8D802E1E1E101D7D7D701DBDBDB02D9D9D901 + D8D8D801DADADA01D8D8D801DADADA02D8D8D801D9D9D902DEDEDE01DBDBDB01 + D9D9D901FFFFFF03D9D9D901FEFEFE01DDDDDD01DADADA01D8D8D801DCDCDC01 + DBDBDB01D8D8D801D9D9D901DCDCDC01D7D7D701FFFFFF01FDFDFD01DCDCDC01 + D8D8D801DBDBDB01ACACAC01D9D9D901D7D7D701D9D9D902DCDCDC01DBDBDB01 + D7D7D701DBDBDB01D9D9D903DADADA01D6D6D601DDDDDD01DBDBDB01ADADAD01 + D8D8D802DBDBDB01D7D7D702E0E0E001D9D9D901DBDBDB02DCDCDC01A9A9A901 + D9D9D901DADADA01D8D8D801DBDBDB01D9D9D901DCDCDC01DBDBDB01FDFDFD01 + D8D8D801D9D9D901DADADA02D8D8D801A9A9A901DBDBDB01DADADA02AAAAAA01 + A8A8A801D8D8D801D9D9D901DBDBDB01D9D9D901D7D7D701DBDBDB01DCDCDC01 + DADADA01DBDBDB01DADADA01D8D8D801DDDDDD01A8A8A801A9A9A901DDDDDD01 + DADADA01D9D9D902DDDDDD01DADADA01DBDBDB02DADADA01DBDBDB02D8D8D801 + FFFFFF01FCFCFC01DEDEDE01D5D5D501E2E2E201D7D7D701DDDDDD01FFFFFF02 + FDFDFD02DADADA02DCDCDC01DDDDDD01D6D6D601D9D9D901FFFFFF01D8D8D801 + D9D9D902DCDCDC01DADADA01DCDCDC02D5D5D501DEDEDE01DDDDDD01D9D9D901 + DBDBDB01DADADA01D6D6D601DCDCDC01A8A8A801A7A7A701A9A9A901DBDBDB01 + DADADA01DBDBDB02DADADA01D8D8D801D9D9D901DBDBDB01D9D9D902DADADA01 + D8D8D801DDDDDD01DADADA01DDDDDD01DBDBDB01DADADA01DDDDDD01DADADA01 + D7D7D701D9D9D901DADADA01FFFFFF01DADADA01D6D6D601DADADA01DCDCDC01 + D7D7D701D8D8D801D9D9D901D8D8D801DADADA01DBDBDB01DADADA01DBDBDB01 + D9D9D901FFFFFF01FDFDFD01DBDBDB01DADADA02D6D6D601DADADA01E1E1E101 + D9D9D901D7D7D701D9D9D901DBDBDB01DCDCDC01DADADA01DDDDDD01D9D9D901 + DADADA01DCDCDC01DBDBDB01FEFEFE01D6D6D601D8D8D801DCDCDC01A8A8A802 + DCDCDC01DADADA02D7D7D701DCDCDC01D7D7D701D8D8D801A6A6A601DCDCDC02 + FFFFFF01DBDBDB01D9D9D901DADADA01D8D8D801FFFFFF02DEDEDE01D7D7D701 + DBDBDB01DADADA01D9D9D901DADADA01D9D9D901A3A3A301A8A8A801DADADA01 + DCDCDC01DBDBDB01D7D7D701DBDBDB03D9D9D901DADADA04DCDCDC01A5A5A501 + A8A8A801D6D6D601DADADA01DDDDDD01D9D9D902A7A7A701D9D9D901DCDCDC01 + D5D5D501DBDBDB02D9D9D901DCDCDC01FFFFFF01FBFBFB01DADADA01FEFEFE01 + DADADA01D9D9D901FEFEFE01DADADA01DDDDDD01DBDBDB01D9D9D901DADADA01 + D8D8D801D5D5D501DCDCDC01D9D9D901DADADA01DCDCDC01DBDBDB02D9D9D901 + D8D8D802DBDBDB01DCDCDC01D8D8D802A8A8A801A7A7A702DDDDDD01DADADA01 + DBDBDB01D9D9D901DBDBDB01D9D9D901DBDBDB01D8D8D802DADADA01DDDDDD01 + D8D8D801DCDCDC01D9D9D901DCDCDC02DADADA01D9D9D901DBDBDB01DADADA01 + D6D6D601DADADA01D8D8D801DEDEDE01D7D7D701DDDDDD01DCDCDC01D6D6D601 + DBDBDB01DEDEDE01D7D7D701DCDCDC01DADADA01DCDCDC02D9D9D901DBDBDB01 + DADADA01D8D8D801D9D9D901DCDCDC01D9D9D901DBDBDB01D7D7D701FFFFFF01 + DCDCDC01D9D9D901DDDDDD01D7D7D701DBDBDB01DADADA01DDDDDD01D9D9D902 + D6D6D601D8D8D801DCDCDC01D9D9D901A6A6A602FFFFFF01DEDEDE01D7D7D701 + A8A8A801AAAAAA01A7A7A701DADADA01DBDBDB01DADADA01DDDDDD01D7D7D701 + FFFFFF01DADADA01DDDDDD01DADADA01D7D7D701D9D9D902DCDCDC01DDDDDD01 + A9A9A901D8D8D801FEFEFE01FCFCFC01FFFFFF02D8D8D801DDDDDD01DADADA01 + FDFDFD01FFFFFF01A8A8A801D9D9D902DBDBDB01DCDCDC01D9D9D901DBDBDB01 + DADADA01D8D8D801DADADA01FFFFFF01DADADA01DBDBDB01D7D7D701A9A9A901 + AAAAAA01A8A8A801DCDCDC01DBDBDB01DADADA02A5A5A501DCDCDC01D9D9D901 + DFDFDF01DADADA01D9D9D901DCDCDC01D3D3D301DFDFDF01DBDBDB01DADADA01 + D8D8D801DEDEDE01D9D9D901DEDEDE01D8D8D801DADADA01D9D9D901DCDCDC01 + D8D8D801DBDBDB01DDDDDD01DCDCDC02D6D6D601D9D9D901D8D8D801DADADA01 + DBDBDB01DDDDDD01DADADA02D8D8D802DBDBDB01ABABAB01A9A9A902D6D6D601 + DADADA01FEFEFE01DCDCDC02D6D6D601D9D9D902DEDEDE01DBDBDB01D9D9D901 + D7D7D701DCDCDC01DADADA01DBDBDB01D8D8D801DCDCDC01D9D9D901D8D8D801 + DEDEDE01A9A9A901DEDEDE01D8D8D802DEDEDE01D6D6D601DBDBDB01DDDDDD01 + D8D8D802DBDBDB01D8D8D801D9D9D902DBDBDB02D7D7D701DFDFDF01DADADA02 + D9D9D901DCDCDC01FFFFFF01DADADA02D8D8D801DDDDDD01D6D6D601D8D8D801 + DCDCDC01DBDBDB01A7A7A701D6D6D601DFDFDF01DCDCDC02DADADA01DBDBDB01 + DADADA01DBDBDB02DADADA01FFFFFF01FDFDFD01DBDBDB01DADADA01DBDBDB01 + D7D7D701DBDBDB01D8D8D801DCDCDC01FFFFFF01D9D9D901D8D8D801DADADA01 + DFDFDF01A7A7A701AAAAAA01A7A7A701A5A5A501ACACAC01D9D9D901DFDFDF01 + FFFFFF01DBDBDB01DADADA01D8D8D801D9D9D901DADADA01DCDCDC01D6D6D601 + DCDCDC01D8D8D801DADADA01DCDCDC01D9D9D901DADADA03DBDBDB01FDFDFD01 + FEFEFE01FFFFFF01FDFDFD01DDDDDD01A9A9A901A6A6A601A8A8A801A7A7A701 + DBDBDB01FBFBFB01DDDDDD01DCDCDC01DADADA01D7D7D701D8D8D801DADADA01 + D7D7D701DBDBDB01DDDDDD01DADADA01D8D8D801DBDBDB01DDDDDD01D4D4D401 + DBDBDB02D9D9D901DDDDDD01DADADA01D7D7D701DBDBDB01D9D9D901D5D5D501 + DDDDDD01D6D6D601DDDDDD01D9D9D901DCDCDC01D8D8D801DBDBDB01D7D7D701 + D9D9D901DDDDDD01D8D8D801FFFFFF01D8D8D801DADADA01A6A6A601DADADA01 + DBDBDB01DADADA03D9D9D901DCDCDC01DBDBDB01DCDCDC01D6D6D601DADADA01 + DCDCDC01DBDBDB02D9D9D901DADADA01D6D6D601DDDDDD01DADADA01DDDDDD01 + D6D6D601AAAAAA01A5A5A501AAAAAA01DBDBDB02D9D9D901D4D4D401DEDEDE01 + D8D8D801DDDDDD01DADADA01DEDEDE01D6D6D601DCDCDC01A5A5A502DDDDDD01 + D8D8D801DCDCDC01D9D9D903DADADA03DBDBDB01DADADA01DDDDDD01DADADA01 + DBDBDB01D8D8D801DCDCDC01DDDDDD01D6D6D601D9D9D901DADADA01FEFEFE02 + DADADA01D9D9D902FFFFFF01FCFCFC01FFFFFF01D8D8D801DADADA03D9D9D901 + DDDDDD01D8D8D801D9D9D901A9A9A901DADADA02A6A6A602A9A9A901D8D8D801 + DADADA01A8A8A802A4A4A401ABABAB01A7A7A701A6A6A601DEDEDE01D7D7D701 + D9D9D901FFFFFF01DCDCDC01D8D8D801DEDEDE01DBDBDB01D9D9D901D8D8D801 + ABABAB01D8D8D801D9D9D901DCDCDC01FFFFFF01FDFDFD01FFFFFF01DADADA01 + D8D8D802A9A9A901A7A7A701A8A8A802DADADA01DBDBDB01D9D9D902DDDDDD01 + DADADA01D8D8D801DEDEDE01DBDBDB01DADADA01D8D8D801DBDBDB01D9D9D902 + DDDDDD01D9D9D901DBDBDB01D8D8D802DCDCDC01DEDEDE01D8D8D801DBDBDB02 + D9D9D901D8D8D801DBDBDB01DADADA02D8D8D801DBDBDB01DCDCDC01D8D8D802 + DCDCDC01FDFDFD01DCDCDC01DADADA03DCDCDC01D8D8D801DADADA01D7D7D701 + DCDCDC01D8D8D801DBDBDB01D9D9D901DEDEDE01D8D8D801D9D9D903DADADA01 + DCDCDC01DADADA01DBDBDB01D8D8D801FEFEFE01DBDBDB02DADADA01A4A4A401 + D9D9D901DADADA01DCDCDC02D9D9D901DADADA01D9D9D901DADADA01D8D8D801 + DCDCDC01DADADA01ABABAB01DCDCDC01D8D8D801D9D9D901DADADA02DDDDDD01 + D9D9D902DBDBDB01D7D7D701DCDCDC01DADADA01D9D9D901DDDDDD01FCFCFC01 + DCDCDC01DBDBDB01D8D8D801D9D9D901DBDBDB03DADADA01DBDBDB02D9D9D901 + DDDDDD01DBDBDB01D5D5D501E0E0E001DADADA01D9D9D901DCDCDC01DBDBDB01 + D7D7D701DEDEDE01DBDBDB01D6D6D601DBDBDB01FFFFFF01FEFEFE01DCDCDC02 + D9D9D901DBDBDB01DCDCDC01A7A7A701D8D8D801ABABAB01D8D8D801A8A8A801 + FEFEFE01FFFFFF01D5D5D501DADADA02D8D8D801D9D9D901DADADA01D6D6D601 + DCDCDC01DADADA03DBDBDB01D5D5D501ABABAB01D8D8D801DBDBDB01DDDDDD01 + DBDBDB01D8D8D801ADADAD01A7A7A701A5A5A501ABABAB01D6D6D601DBDBDB02 + DADADA01D8D8D801DDDDDD01D9D9D901A6A6A601DADADA01DCDCDC01DADADA01 + D9D9D901DADADA01D9D9D901DBDBDB03DADADA01D9D9D901D7D7D701DBDBDB01 + D7D7D701DDDDDD01D6D6D601DBDBDB01DCDCDC01D7D7D701DADADA02D8D8D801 + DDDDDD01D9D9D901DCDCDC01FEFEFE01FFFFFF01FCFCFC01DBDBDB02DADADA01 + D9D9D901DBDBDB02D9D9D901DBDBDB01D8D8D801DBDBDB02D7D7D701DCDCDC01 + DBDBDB03D9D9D901DADADA02D9D9D901DBDBDB01FFFFFF01FDFDFD01FFFFFF01 + DBDBDB01DDDDDD01A8A8A801A7A7A701D9D9D901DADADA01DBDBDB02DADADA01 + D8D8D801DBDBDB01FFFFFF01FEFEFE01DADADA01D8D8D801DADADA01DBDBDB01 + DDDDDD01D7D7D701DBDBDB01DADADA01D9D9D901DDDDDD01D8D8D801DCDCDC01 + D8D8D801DADADA02DCDCDC01DADADA01D8D8D801DBDBDB02DADADA01D7D7D701 + DDDDDD01D9D9D901DBDBDB01D7D7D701DCDCDC01D9D9D901DCDCDC01DBDBDB01 + D6D6D601D9D9D901DADADA03D9D9D901FFFFFF01DADADA01DBDBDB01FEFEFE02 + FFFFFF01D8D8D801FEFEFE01FFFFFF01D9D9D901DADADA01FFFFFF03DADADA01 + A8A8A801DCDCDC01D7D7D701DCDCDC01DADADA03A8A8A801D9D9D901FFFFFF01 + DADADA01D7D7D701AAAAAA01A8A8A802ABABAB01D6D6D601DBDBDB01DCDCDC01 + D8D8D801DBDBDB01DCDCDC01D6D6D601DCDCDC01A9A9A901A7A7A701DBDBDB01 + D9D9D902DADADA02DBDBDB01D9D9D901A8A8A801DBDBDB01D9D9D901DADADA01 + DBDBDB01D9D9D901DCDCDC01D7D7D701DADADA04DCDCDC01D7D7D701DCDCDC01 + D9D9D901DADADA02D8D8D801DCDCDC01DBDBDB01D9D9D901DBDBDB01DADADA02 + D9D9D901FFFFFF02DCDCDC01DADADA01A5A5A501ABABAB01D8D8D801DADADA01 + D9D9D901DEDEDE01DADADA01D7D7D701DDDDDD01DADADA01D6D6D601DCDCDC01 + D9D9D901DADADA04DFDFDF01D8D8D801DADADA01D8D8D801DBDBDB01FEFEFE01 + D9D9D901DADADA01DCDCDC01DADADA03D9D9D901A8A8A801DBDBDB01DADADA01 + DCDCDC01FFFFFF01D9D9D901DBDBDB02D8D8D801D9D9D901DBDBDB01DADADA01 + D8D8D801DBDBDB01DADADA01DDDDDD01D8D8D801DBDBDB01D9D9D902DCDCDC01 + D9D9D901DCDCDC01D7D7D701DDDDDD01DADADA02D9D9D901DCDCDC01DADADA02 + DBDBDB01DADADA01D9D9D901DBDBDB01D9D9D901DCDCDC01D9D9D901DADADA01 + D8D8D801DCDCDC01D6D6D601DCDCDC01DDDDDD01D7D7D701DBDBDB01FFFFFF01 + FCFCFC01FFFFFF03FEFEFE01FFFFFF02DADADA01FFFFFF01DADADA01ABABAB01 + A7A7A702A9A9A901D8D8D801ABABAB01A5A5A501A9A9A901DADADA02DBDBDB01 + D8D8D801A8A8A801A7A7A701DADADA01DCDCDC01D9D9D901DEDEDE01D7D7D701 + DCDCDC01DADADA01DBDBDB01D8D8D801DBDBDB01A9A9A901D8D8D801D9D9D901 + DCDCDC01D9D9D901DADADA01DCDCDC01D8D8D801DCDCDC01DADADA02D9D9D901 + DADADA01D8D8D801D9D9D901DBDBDB01DCDCDC01D8D8D801A8A8A801A7A7A703 + AAAAAA01A8A8A801DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DBDBDB01 + DADADA02D9D9D901DDDDDD01D9D9D901D7D7D701DBDBDB01DADADA01AAAAAA01 + A7A7A701ABABAB01D7D7D701DCDCDC01D9D9D901D8D8D801DCDCDC02D8D8D801 + DADADA01DFDFDF01D8D8D801DCDCDC01DDDDDD01D7D7D701DBDBDB01D8D8D801 + D6D6D601DDDDDD01DADADA01DCDCDC02D9D9D901FDFDFD01FFFFFF01DADADA01 + D6D6D601DADADA01D9D9D901DBDBDB01DADADA01A8A8A801A7A7A701D7D7D701 + D9D9D901DBDBDB01D8D8D802DCDCDC01DEDEDE01D8D8D801DBDBDB02DADADA01 + D8D8D801D7D7D701DADADA01DCDCDC01DADADA01DCDCDC01D6D6D601DCDCDC01 + D7D7D701DCDCDC01D9D9D902DADADA01DBDBDB01DADADA01D9D9D901DCDCDC01 + D8D8D801DCDCDC01DBDBDB01D9D9D901DCDCDC01D6D6D601DCDCDC01DDDDDD01 + DADADA01D8D8D801DEDEDE01D9D9D901A3A3A301AAAAAA01A7A7A701FCFCFC01 + DDDDDD01DBDBDB01FEFEFE01FFFFFF01D8D8D801DCDCDC01DADADA01DBDBDB01 + FDFDFD01A6A6A601D9D9D901AAAAAA01A9A9A901A8A8A801ABABAB01D7D7D701 + A8A8A801A7A7A701DEDEDE01DADADA01FEFEFE01FFFFFF01FEFEFE01DCDCDC01 + D7D7D701D9D9D901DADADA01D4D4D401DCDCDC01D9D9D902D8D8D801DFDFDF01 + D7D7D701DBDBDB01DDDDDD01DBDBDB02D9D9D901DADADA02FDFDFD01DBDBDB01 + A6A6A601A8A8A801AAAAAA01DBDBDB01DCDCDC01DADADA02A6A6A601A8A8A801 + A6A6A601AAAAAA01ABABAB01AAAAAA01A5A5A501DADADA01DCDCDC01DBDBDB01 + D8D8D801DDDDDD01D9D9D901DADADA01D9D9D902DBDBDB01D7D7D701D9D9D901 + DEDEDE01DADADA01FFFFFF01FDFDFD01A6A6A601D8D8D801DDDDDD01DADADA02 + DBDBDB01D8D8D801DEDEDE01D9D9D901DCDCDC01D7D7D701DADADA01D9D9D901 + D6D6D601DCDCDC01D8D8D801DDDDDD01DADADA01D8D8D801DADADA01D8D8D801 + D7D7D701DBDBDB01DCDCDC01DADADA01D8D8D801DDDDDD01DBDBDB01FFFFFF01 + D9D9D902AAAAAA01D7D7D701DBDBDB03DEDEDE01DBDBDB01D8D8D803DBDBDB01 + D9D9D901DADADA01DCDCDC01DEDEDE01D8D8D801DCDCDC01D7D7D701D9D9D901 + DFDFDF01D7D7D701DEDEDE01DADADA01DBDBDB01DADADA01DBDBDB01DADADA01 + D9D9D901DBDBDB01D8D8D801D9D9D901DBDBDB01DADADA01D9D9D901DCDCDC01 + DADADA02D9D9D901DADADA01DBDBDB01D7D7D701DADADA01AAAAAA01A9A9A901 + A7A7A701ABABAB01D9D9D901DADADA01D9D9D901D7D7D701A9A9A902DADADA01 + DBDBDB02DFDFDF01FDFDFD01D6D6D601AAAAAA01D6D6D601DADADA01DFDFDF01 + D7D7D701A9A9A901D8D8D802FDFDFD01FFFFFF01DADADA01FCFCFC01FFFFFF01 + DCDCDC01DADADA01DEDEDE01DCDCDC01DADADA01FFFFFF02FEFEFE01A9A9A901 + A7A7A701D8D8D801D5D5D501DDDDDD01DCDCDC01DBDBDB01DADADA01DEDEDE01 + DBDBDB01A6A6A601A8A8A801ACACAC01A4A4A401A9A9A901A5A5A501A7A7A701 + DCDCDC01D7D7D701DEDEDE01D6D6D601D8D8D801D9D9D901A8A8A801D9D9D901 + DDDDDD01D6D6D601DCDCDC01D9D9D901DADADA01DBDBDB01DADADA01DBDBDB01 + AAAAAA01D6D6D601DDDDDD01DBDBDB01FDFDFD01FFFFFF02DBDBDB01DDDDDD01 + D7D7D701DADADA01DCDCDC01D9D9D901DBDBDB01D6D6D601DBDBDB02DCDCDC01 + DADADA01D8D8D801DFDFDF01D6D6D601DCDCDC01D9D9D901ABABAB01A7A7A701 + D9D9D901DADADA01DDDDDD01D9D9D903DADADA01DCDCDC01D7D7D701A8A8A801 + FEFEFE01FFFFFF01D6D6D601E1E1E101D8D8D801DBDBDB02D8D8D802DBDBDB03 + D7D7D701A8A8A801A9A9A901DADADA01DBDBDB01D7D7D701DBDBDB01DADADA01 + DBDBDB01DADADA01D8D8D801D9D9D903DADADA01D8D8D801DEDEDE01DADADA01 + D9D9D901DCDCDC01DDDDDD01DADADA01D6D6D601DADADA01D7D7D701DDDDDD01 + D9D9D901D8D8D801DADADA02FFFFFF02D8D8D801A7A7A701A9A9A901A5A5A501 + DADADA01DCDCDC01A8A8A801ABABAB01A8A8A801D9D9D901DADADA01FFFFFF01 + A6A6A601DBDBDB01FEFEFE01FFFFFF02DADADA01FFFFFF01FCFCFC01AAAAAA01 + D9D9D901DBDBDB01DEDEDE01D9D9D901DADADA01FFFFFF02FEFEFE01D9D9D901 + D8D8D801D9D9D902D7D7D701FFFFFF02DADADA01A8A8A801ACACAC01A9A9A901 + DBDBDB01A7A7A701A5A5A501A7A7A701A6A6A601FEFEFE01FFFFFF01FDFDFD01 + A7A7A701A6A6A601ABABAB01A5A5A501DCDCDC01DADADA02DDDDDD01D6D6D601 + DDDDDD01DCDCDC01A8A8A801AAAAAA01DBDBDB01DADADA01DBDBDB01DADADA01 + D8D8D801DADADA02D8D8D801DBDBDB01D7D7D701DDDDDD01D6D6D601D9D9D901 + DCDCDC01FFFFFF01D9D9D901D8D8D802DCDCDC01D9D9D902D8D8D801AAAAAA01 + DBDBDB01DADADA01D6D6D601DCDCDC01DBDBDB02D9D9D902DCDCDC01A6A6A602 + AAAAAA01DADADA01D9D9D901DADADA01DCDCDC01D8D8D801DFDFDF01D8D8D802 + DDDDDD01A6A6A601FFFFFF01DDDDDD01DBDBDB01D5D5D501D8D8D801DDDDDD01 + D8D8D801DBDBDB01DADADA01DEDEDE01D6D6D601D8D8D801DEDEDE01A7A7A703 + DBDBDB01DDDDDD01D9D9D901DCDCDC01D8D8D801DBDBDB01DEDEDE01DBDBDB01 + A7A7A701DEDEDE01D8D8D801DBDBDB01D7D7D701DADADA01DDDDDD01DADADA01 + D7D7D701D9D9D901DBDBDB01DDDDDD01DBDBDB01DADADA02DBDBDB02D8D8D801 + FFFFFF01D8D8D801DCDCDC01D9D9D901A7A7A701AAAAAA01DBDBDB01A8A8A801 + D8D8D801D7D7D701DBDBDB01D8D8D801FFFFFF02D7D7D701D9D9D901DCDCDC01 + D7D7D701D9D9D901DEDEDE01A5A5A501D8D8D801A7A7A701DDDDDD01DADADA01 + D4D4D401FFFFFF01A7A7A702FBFBFB01FFFFFF01DBDBDB01DADADA02A7A7A701 + AAAAAA01DBDBDB01FEFEFE02D7D7D701D8D8D801DDDDDD01D6D6D601DADADA01 + ABABAB01AAAAAA01A8A8A801FFFFFF01FEFEFE01FFFFFF02D7D7D701D9D9D902 + DADADA01DBDBDB01D9D9D902DCDCDC01D8D8D801D7D7D701AAAAAA01A8A8A801 + D5D5D501DBDBDB01DCDCDC01D8D8D801DCDCDC01DADADA01DCDCDC01FFFFFF01 + DADADA02D9D9D901DBDBDB01DDDDDD01D8D8D801DADADA01DCDCDC01D8D8D801 + DFDFDF01DCDCDC01D9D9D901A9A9A902D8D8D801DADADA01DCDCDC01DADADA02 + D8D8D801DADADA01D9D9D901DBDBDB01D9D9D901FEFEFE01AAAAAA01A8A8A801 + A7A7A701DADADA01D8D8D801DCDCDC01D9D9D901D5D5D501DFDFDF01FEFEFE01 + D8D8D801DBDBDB01DADADA01D6D6D601DBDBDB01DCDCDC01DDDDDD01D9D9D901 + DCDCDC01DBDBDB01D8D8D801D7D7D701DBDBDB01FFFFFF01FDFDFD01DBDBDB01 + A8A8A801DBDBDB01D8D8D801DADADA01D9D9D902DFDFDF01D7D7D701D9D9D901 + DBDBDB01D7D7D701DCDCDC01DBDBDB01DADADA01DCDCDC01D9D9D901D8D8D801 + DBDBDB01DFDFDF01D7D7D701A9A9A901A6A6A601D8D8D801DBDBDB01D9D9D902 + DBDBDB01A7A7A701D8D8D801DBDBDB01DADADA02A9A9A901A8A8A801FFFFFF01 + D9D9D902DCDCDC01D8D8D801DEDEDE01FFFFFF02DADADA01A8A8A802DADADA01 + A8A8A801A9A9A901DBDBDB01AAAAAA01A6A6A601DADADA01D9D9D901FFFFFF01 + DBDBDB01D9D9D901ABABAB01DCDCDC01FFFFFF01FEFEFE01FFFFFF02D8D8D801 + DBDBDB01A6A6A601D8D8D801FFFFFF02D9D9D901FDFDFD01FFFFFF01FBFBFB01 + DBDBDB01A7A7A701DBDBDB01D9D9D901FFFFFF02FBFBFB01FFFFFF01DADADA03 + D9D9D901DBDBDB01DADADA01D8D8D801D9D9D901DDDDDD01A5A5A501ABABAB01 + DDDDDD01D6D6D601D9D9D901DDDDDD01D8D8D801DADADA01D9D9D901DADADA02 + DBDBDB01DADADA01D7D7D701DCDCDC01D9D9D901D8D8D801DBDBDB01DADADA01 + D4D4D401D9D9D901D8D8D801DBDBDB01A5A5A501ADADAD01A8A8A801A5A5A501 + DBDBDB01DADADA01DCDCDC01DBDBDB01A8A8A801DBDBDB01DADADA02A9A9A901 + A5A5A501AAAAAA01DDDDDD01D9D9D901D8D8D801D9D9D901DEDEDE01A4A4A401 + FFFFFF01DCDCDC01D9D9D901DBDBDB01DADADA02DBDBDB01D8D8D801D7D7D701 + DCDCDC01D9D9D901DDDDDD01DADADA02FCFCFC01FFFFFF02DADADA01A8A8A801 + D9D9D901DCDCDC01DADADA01DCDCDC01D7D7D701DBDBDB02D9D9D901E0E0E001 + D6D6D601D8D8D801D9D9D901DADADA02DCDCDC01D8D8D801D7D7D701A8A8A801 + A9A9A901AAAAAA01A5A5A501DADADA01DCDCDC01D7D7D701DBDBDB01FFFFFF01 + DADADA01D9D9D901D8D8D801DDDDDD01A7A7A701DBDBDB01D7D7D701DEDEDE01 + ACACAC01D4D4D401D9D9D901DADADA01D8D8D801FEFEFE01FFFFFF01DDDDDD01 + FEFEFE01DBDBDB01FFFFFF01FEFEFE01FFFFFF01DBDBDB01A9A9A901DADADA01 + A8A8A801FFFFFF01FEFEFE01DADADA01A6A6A601DADADA01FEFEFE01FFFFFF01 + FEFEFE01FBFBFB01DCDCDC01DBDBDB01DADADA01A7A7A701DCDCDC01D7D7D701 + D9D9D901FFFFFF02FEFEFE01FFFFFF01DBDBDB01DADADA02D8D8D801FEFEFE01 + FFFFFF01D9D9D901DADADA02DEDEDE01D9D9D901D8D8D801DCDCDC02DDDDDD01 + D5D5D501A8A8A801A7A7A701DBDBDB01DDDDDD01DCDCDC01D7D7D701DCDCDC01 + D8D8D801DBDBDB01DADADA01DBDBDB01DADADA01DBDBDB01DADADA02DBDBDB01 + DADADA01DBDBDB01DDDDDD01DCDCDC01DADADA02A9A9A901A5A5A501A8A8A801 + A7A7A701DCDCDC01DBDBDB01D9D9D902A7A7A701D9D9D901AAAAAA01D7D7D701 + DDDDDD01DBDBDB01A7A7A701DADADA01D9D9D901DADADA01D9D9D901DDDDDD01 + D8D8D801A8A8A801A7A7A701D9D9D901DADADA03DCDCDC01D9D9D901DBDBDB01 + DADADA02D9D9D901DBDBDB01DADADA01D9D9D901DCDCDC01FFFFFF01D6D6D601 + DBDBDB01A8A8A801DADADA01D9D9D901DCDCDC01D8D8D801DCDCDC01DDDDDD01 + A5A5A501DADADA03DBDBDB01DCDCDC01D9D9D903DBDBDB01FFFFFF01D9D9D901 + A7A7A701A6A6A601AAAAAA01DADADA01A7A7A701DCDCDC01FDFDFD01FEFEFE01 + DBDBDB01DADADA01DBDBDB01D9D9D901A8A8A801DBDBDB01D8D8D801A9A9A901 + D8D8D801DCDCDC02D9D9D901DBDBDB01FFFFFF01FEFEFE02FFFFFF02FDFDFD01 + FFFFFF02A6A6A601A7A7A701A9A9A901A8A8A802DADADA01FFFFFF01DBDBDB01 + A9A9A901D8D8D801D7D7D701DCDCDC01DDDDDD01FEFEFE02DBDBDB02D9D9D901 + DBDBDB01A9A9A901D8D8D801FFFFFF02D9D9D901DADADA02DBDBDB03FFFFFF01 + D7D7D701DADADA01DBDBDB01D5D5D501FFFFFF01D9D9D901DADADA01FEFEFE01 + FDFDFD01DDDDDD01A9A9A901A7A7A701AAAAAA01D7D7D701D9D9D901DDDDDD01 + D8D8D801DCDCDC01DADADA01D9D9D901DBDBDB01D9D9D901DBDBDB02D8D8D801 + DBDBDB01DADADA01D8D8D801D9D9D901DADADA01D9D9D901DCDCDC01DADADA01 + D9D9D901DBDBDB01DADADA02D9D9D901DCDCDC01D9D9D901DBDBDB01D9D9D901 + DADADA01DDDDDD01D3D3D301DEDEDE01DCDCDC01D9D9D901DBDBDB01DADADA01 + D7D7D701FFFFFF01DADADA01DCDCDC01ABABAB01D7D7D701D9D9D901DCDCDC01 + D9D9D901DBDBDB01DADADA01DDDDDD01D9D9D901DADADA01DBDBDB01D7D7D701 + DCDCDC01D9D9D901DBDBDB01D9D9D901FFFFFF01D9D9D901A8A8A801A6A6A601 + DADADA01DCDCDC01DBDBDB01FFFFFF01DADADA03D9D9D901DADADA01D9D9D901 + DADADA01DDDDDD01D9D9D901DADADA01FEFEFE01FDFDFD01DBDBDB01DCDCDC01 + A5A5A501DBDBDB02D8D8D801D9D9D901DBDBDB01DADADA02D9D9D901D8D8D801 + FFFFFF01FEFEFE01DADADA01DBDBDB01A6A6A601A7A7A701DBDBDB03D9D9D901 + FFFFFF01D7D7D701DCDCDC01AAAAAA01A6A6A601A9A9A902DBDBDB01A7A7A701 + DADADA01A9A9A901DADADA01A9A9A901D8D8D801FEFEFE01DCDCDC01DADADA01 + D8D8D801DEDEDE01D9D9D903FFFFFF01DBDBDB01DADADA02A8A8A801AAAAAA01 + A8A8A801A7A7A701DADADA01D9D9D901DADADA02D8D8D801D9D9D901FFFFFF02 + D7D7D701DADADA01D9D9D901FFFFFF01FCFCFC01FFFFFF01FEFEFE01FDFDFD01 + FFFFFF01FEFEFE01AAAAAA01A5A5A501DBDBDB04DADADA02DCDCDC01D5D5D501 + DDDDDD01DADADA01D9D9D901DADADA01DEDEDE01D9D9D902DCDCDC01DADADA02 + D9D9D901D7D7D701D8D8D801DBDBDB01A7A7A701D9D9D901DBDBDB01DCDCDC01 + FDFDFD01FFFFFF01DADADA01D9D9D902DDDDDD01DCDCDC01D9D9D902DBDBDB01 + DADADA01DDDDDD01DCDCDC01FEFEFE01D7D7D701A6A6A601D9D9D901DCDCDC01 + DBDBDB01DADADA01D8D8D801DDDDDD01D9D9D901D6D6D601DDDDDD01D8D8D801 + D7D7D701DFDFDF01DADADA01D6D6D601DCDCDC01D8D8D801FFFFFF01DADADA02 + ACACAC01D9D9D901D6D6D601D8D8D801FFFFFF01DBDBDB01DADADA01D9D9D901 + DDDDDD01D9D9D901DDDDDD01DADADA01D8D8D801DADADA01D9D9D901FFFFFF03 + D7D7D701DBDBDB01FCFCFC01FFFFFF01D8D8D801A7A7A701DCDCDC01D8D8D801 + DBDBDB01DDDDDD01DADADA01D8D8D802D7D7D701AAAAAA01A7A7A701A8A8A801 + DFDFDF01D2D2D201D9D9D901DBDBDB02DADADA01A7A7A702A8A8A801ABABAB01 + D5D5D501DADADA04FAFAFA01ABABAB01A7A7A701FFFFFF01D8D8D801DADADA01 + DCDCDC01D5D5D501DCDCDC01AAAAAA01A9A9A901D7D7D701DADADA01DBDBDB01 + D9D9D901A7A7A702A8A8A801A6A6A601DCDCDC01DBDBDB01D8D8D801DBDBDB02 + DCDCDC01FDFDFD01FCFCFC01FFFFFF01FEFEFE01D9D9D901FFFFFF02D6D6D601 + DADADA01FFFFFF01FEFEFE01FFFFFF01FDFDFD01DEDEDE01DCDCDC01D8D8D801 + D9D9D901D8D8D801DEDEDE01D7D7D701D8D8D801ABABAB01DBDBDB01D9D9D901 + D8D8D801DCDCDC01A2A2A201DADADA03D9D9D902DEDEDE01DADADA01DDDDDD01 + A8A8A801D9D9D902A6A6A601D9D9D901DFDFDF01D7D7D701D9D9D901DDDDDD01 + DADADA02A8A8A801D9D9D902A8A8A801A6A6A601D8D8D801DBDBDB01D8D8D801 + DCDCDC01A9A9A901DADADA02D8D8D801DBDBDB01DDDDDD01DADADA01D8D8D801 + DFDFDF01DADADA01D8D8D801A8A8A801D7D7D701D9D9D901DEDEDE01D7D7D701 + D8D8D801FEFEFE02D7D7D701DBDBDB01D8D8D801DEDEDE01DCDCDC01D8D8D801 + DDDDDD01DBDBDB01DCDCDC01D7D7D701DADADA01D8D8D801D9D9D901DCDCDC01 + D9D9D901DCDCDC01FEFEFE02D8D8D801A8A8A801AAAAAA01A9A9A901D7D7D701 + DEDEDE01FFFFFF01FDFDFD01FEFEFE01FFFFFF01A5A5A501A8A8A801DADADA01 + DDDDDD01D8D8D801DCDCDC01A7A7A701D7D7D701DCDCDC01DDDDDD02DADADA01 + FDFDFD01FFFFFF01DADADA01D7D7D701DDDDDD01DBDBDB02DADADA02A7A7A701 + DBDBDB01DEDEDE01D9D9D901A7A7A701DCDCDC01DBDBDB01DADADA01DBDBDB01 + DEDEDE01D9D9D901A7A7A701DBDBDB01DADADA01DDDDDD01DADADA02D8D8D801 + DADADA01A9A9A901AFAFAF01D6D6D601DBDBDB01DCDCDC01DADADA01D7D7D702 + FFFFFF02D9D9D901DADADA02D9D9D901D6D6D601DFDFDF01D9D9D901D8D8D801 + FFFFFF01FDFDFD01DCDCDC01D8D8D802DCDCDC01DBDBDB01D9D9D901DDDDDD01 + DCDCDC01A9A9A901DBDBDB01D7D7D701D8D8D801DDDDDD01D8D8D801DBDBDB01 + DEDEDE01DCDCDC01D9D9D901DBDBDB02D9D9D902FEFEFE01D7D7D701DBDBDB01 + DADADA01DFDFDF01A8A8A801D6D6D601DBDBDB01DCDCDC01D6D6D601DADADA01 + A7A7A701DADADA01A9A9A901AAAAAA01A8A8A801ABABAB01D9D9D901FFFFFF01 + FEFEFE01A7A7A701DBDBDB01DADADA02DDDDDD01D7D7D701A7A7A701A8A8A801 + DADADA02D8D8D801DDDDDD01A7A7A701DCDCDC01D9D9D902DDDDDD01DBDBDB02 + FFFFFF01DCDCDC01DADADA01DCDCDC01D8D8D802DBDBDB01A7A7A701D8D8D801 + DBDBDB02A9A9A901AAAAAA01D8D8D801D9D9D901DDDDDD01D9D9D902FFFFFF01 + DBDBDB01D9D9D901A6A6A601AAAAAA01D8D8D802FDFDFD01FFFFFF01DBDBDB01 + D9D9D901FFFFFF01DBDBDB01D9D9D901DADADA01DCDCDC01D7D7D701A9A9A901 + DDDDDD01D4D4D401DADADA01D9D9D902FFFFFF02DADADA01D9D9D901DCDCDC01 + D4D4D401DADADA01DBDBDB01DCDCDC01A9A9A901D9D9D901D7D7D701A9A9A901 + DADADA01A6A6A601D9D9D901DADADA01D8D8D801D9D9D901FFFFFF01A5A5A501 + ABABAB01DADADA01FCFCFC01DCDCDC01D8D8D801DBDBDB01DCDCDC01A4A4A401 + D6D6D601DADADA01DBDBDB01D7D7D701DBDBDB03DADADA01DBDBDB01A8A8A801 + A7A7A701D8D8D801DCDCDC01DDDDDD01D5D5D501DBDBDB01D9D9D901DBDBDB01 + DCDCDC01DBDBDB01DADADA01DCDCDC01DADADA01D9D9D901DCDCDC01D9D9D901 + FDFDFD01A5A5A501DBDBDB01DCDCDC01DADADA01FFFFFF01D9D9D901DDDDDD01 + D5D5D501D9D9D901DADADA01DBDBDB01D5D5D501DBDBDB01DDDDDD01D8D8D801 + DEDEDE01FFFFFF01FEFEFE02DBDBDB01DADADA01FFFFFF01FDFDFD01DDDDDD01 + DADADA01DBDBDB01DADADA01DCDCDC01D9D9D901A7A7A701A9A9A901A5A5A501 + FFFFFF02DBDBDB01D8D8D801DADADA01D9D9D902DBDBDB01DCDCDC01D8D8D801 + DBDBDB02FEFEFE01DBDBDB01D9D9D901D7D7D701DCDCDC01D9D9D901DADADA02 + D7D7D701DBDBDB01D8D8D801DADADA02DBDBDB01DCDCDC01DADADA01A8A8A801 + DCDCDC01DADADA02A8A8A801A9A9A901ABABAB01A7A7A701D7D7D701DBDBDB01 + FFFFFF01FEFEFE01FDFDFD01FFFFFF01DBDBDB01FCFCFC01DDDDDD01DBDBDB01 + DADADA01D7D7D701FFFFFF02D9D9D901FFFFFF01FCFCFC01FFFFFF01FEFEFE01 + DADADA02D8D8D801DCDCDC02D9D9D901DBDBDB01FFFFFF01FBFBFB01FEFEFE01 + DCDCDC01D9D9D901FFFFFF01DCDCDC01D8D8D801FDFDFD01FCFCFC01DCDCDC01 + FFFFFF01A6A6A601DBDBDB01ABABAB01A8A8A801D8D8D801DFDFDF01D5D5D501 + DADADA01DEDEDE01D7D7D701FFFFFF02D7D7D701DCDCDC01DBDBDB01D8D8D801 + DADADA01DFDFDF01D8D8D801DBDBDB01DDDDDD01DADADA03FFFFFF01D8D8D801 + A7A7A701DADADA01DBDBDB01D8D8D801DADADA01D9D9D902DADADA01DBDBDB01 + D7D7D701DADADA01D9D9D901DBDBDB01D7D7D701DEDEDE01D7D7D701FFFFFF01 + DBDBDB01DCDCDC01DADADA01D7D7D701DADADA03DBDBDB01DCDCDC01D7D7D701 + DCDCDC01DADADA01DFDFDF01D8D8D801A6A6A601DBDBDB01D9D9D902FEFEFE01 + DBDBDB01FFFFFF02FCFCFC01FFFFFF01D9D9D901A5A5A501FFFFFF01DBDBDB01 + D8D8D801DEDEDE01A7A7A701A6A6A601ABABAB01FFFFFF01D6D6D601DBDBDB01 + DADADA01DCDCDC01A7A7A701FFFFFF02D6D6D601DBDBDB01DDDDDD01D9D9D901 + FFFFFF01D8D8D801DDDDDD01D9D9D901DBDBDB01DADADA01D8D8D801DADADA01 + DBDBDB01D9D9D901D8D8D801DEDEDE01D9D9D902FDFDFD01DEDEDE01D7D7D701 + D9D9D901FEFEFE01FFFFFF01D9D9D901A7A7A701A6A6A601A4A4A401DFDFDF01 + D8D8D801DADADA01D8D8D801FFFFFF02FEFEFE01DDDDDD01D7D7D701D9D9D901 + DBDBDB01FEFEFE01DCDCDC01DBDBDB01FFFFFF03FDFDFD01FFFFFF01DADADA01 + D9D9D901DADADA01DEDEDE01D6D6D601D9D9D901DADADA01FFFFFF05FCFCFC01 + FFFFFF04FEFEFE01D8D8D801DBDBDB01A5A5A501A8A8A801A9A9A901FFFFFF01 + DCDCDC01FFFFFF02D9D9D901DBDBDB01FFFFFF01FEFEFE01FFFFFF01DADADA01 + D8D8D802DDDDDD01D7D7D701D8D8D801DADADA01D8D8D801D6D6D601DCDCDC01 + D8D8D801FFFFFF02D9D9D901DBDBDB01DADADA02D8D8D801DBDBDB01DADADA01 + D9D9D902DEDEDE01DCDCDC01D9D9D901DDDDDD01DCDCDC01D8D8D801DADADA01 + FEFEFE01DBDBDB01D8D8D801DBDBDB01DEDEDE01D8D8D801DBDBDB01D6D6D601 + D9D9D901DADADA01DCDCDC01DDDDDD01D8D8D801D9D9D901DBDBDB01DCDCDC02 + D9D9D901DBDBDB01FFFFFF01FEFEFE01DBDBDB01D9D9D901FFFFFF01FDFDFD01 + D9D9D901A9A9A901DBDBDB01D6D6D601DDDDDD01D7D7D701FFFFFF01AAAAAA01 + D7D7D701DADADA01DDDDDD01D9D9D901DCDCDC01D6D6D601ABABAB01A8A8A801 + D9D9D901DCDCDC01DADADA01D9D9D901D8D8D801DADADA01DDDDDD01D8D8D801 + D9D9D901D8D8D801DEDEDE01D6D6D601DBDBDB01DCDCDC01D9D9D901DCDCDC01 + D8D8D801DDDDDD01D9D9D901FFFFFF01D8D8D801DCDCDC01DADADA01FEFEFE01 + FFFFFF01FBFBFB01FFFFFF01A7A7A701A8A8A801D9D9D901DBDBDB01DADADA01 + DBDBDB01D8D8D802A6A6A601A9A9A901DDDDDD01D9D9D901A6A6A601AAAAAA01 + F9F9F901A7A7A701D9D9D901D8D8D801DADADA01A8A8A801D9D9D901DBDBDB01 + DADADA02A7A7A701D9D9D901DADADA01DCDCDC01DADADA01FCFCFC01FFFFFF01 + D8D8D801FEFEFE01FFFFFF01D9D9D901D7D7D701D8D8D801DBDBDB01FDFDFD01 + D9D9D901DEDEDE01DADADA01A6A6A601DADADA01FEFEFE01DADADA02D6D6D601 + DDDDDD01DADADA01FFFFFF02D9D9D901DBDBDB01A9A9A901DCDCDC01D8D8D801 + DBDBDB01DCDCDC01D9D9D901DBDBDB03D6D6D601FFFFFF01DADADA03D7D7D701 + DDDDDD01D9D9D901DBDBDB02D9D9D901D7D7D701DADADA01D7D7D701DDDDDD01 + A5A5A501A6A6A601ADADAD01D8D8D801D9D9D901DADADA01D8D8D801DBDBDB01 + DADADA03DBDBDB01DCDCDC01D9D9D901A8A8A801D7D7D701DCDCDC01FDFDFD02 + FFFFFF01DADADA01D8D8D801FFFFFF01D7D7D701DDDDDD01D8D8D801DCDCDC01 + FEFEFE01FFFFFF01DBDBDB01D9D9D901D8D8D801DCDCDC01DADADA01D9D9D901 + FFFFFF01DADADA01D9D9D901DCDCDC01D9D9D901DADADA01FFFFFF01DEDEDE01 + A5A5A501A8A8A801A9A9A901D9D9D901DBDBDB01D9D9D901DBDBDB02D8D8D801 + DBDBDB01DADADA02D7D7D701DCDCDC01DADADA01D8D8D801DBDBDB01D9D9D901 + DBDBDB01D8D8D801DADADA01DCDCDC01D7D7D701D9D9D901DCDCDC01D9D9D901 + FFFFFF02FDFDFD01A7A7A701AAAAAA01A7A7A701DADADA01D8D8D801DCDCDC01 + D8D8D801FFFFFF01D9D9D901D8D8D801FFFFFF01D9D9D901DADADA02AAAAAA01 + A8A8A802DADADA01D9D9D901DBDBDB01DCDCDC01D8D8D801D9D9D901A9A9A901 + A7A7A701DBDBDB02D9D9D901DADADA01DCDCDC01D9D9D901DCDCDC01DADADA01 + D7D7D701DDDDDD01DBDBDB02D8D8D801FFFFFF02D9D9D901FFFFFF01A6A6A601 + DBDBDB01DCDCDC01D8D8D801DADADA01ABABAB01D8D8D801DADADA01DCDCDC01 + FDFDFD01FFFFFF01D8D8D801A8A8A801DBDBDB01D9D9D901DBDBDB01D9D9D901 + DADADA02D8D8D801DADADA01DDDDDD01D8D8D801DADADA01DBDBDB01D9D9D901 + DDDDDD01D7D7D701DBDBDB02D8D8D801DCDCDC01DADADA01D9D9D901DBDBDB01 + D9D9D901DADADA01DBDBDB01D7D7D701DCDCDC02D9D9D901DBDBDB02D9D9D901 + DBDBDB02D8D8D801DADADA01DBDBDB01A9A9A901DADADA01FEFEFE01FFFFFF03 + DCDCDC01D9D9D901DADADA02DCDCDC01D7D7D701DADADA01D9D9D901FFFFFF02 + D8D8D801DADADA01DBDBDB01A7A7A701FCFCFC01DCDCDC01D9D9D901D8D8D801 + DCDCDC01DBDBDB01D9D9D901FFFFFF02A7A7A701A9A9A902A7A7A701DCDCDC01 + D9D9D901D8D8D801DBDBDB02DADADA09D9D9D901DADADA01DBDBDB01D6D6D601 + DCDCDC01DDDDDD01D9D9D901D8D8D801DEDEDE01FDFDFD01DCDCDC01A9A9A901 + A7A7A701A8A8A802DADADA01D9D9D901FFFFFF02DADADA02FFFFFF02A5A5A501 + DCDCDC01A9A9A901DADADA01DBDBDB01FDFDFD01DBDBDB02D9D9D901DADADA01 + FEFEFE01ABABAB01D7D7D701DBDBDB01D8D8D801DCDCDC01DADADA08DCDCDC01 + D8D8D801FFFFFF01FEFEFE01D9D9D901A9A9A901A6A6A601A9A9A901A7A7A701 + D9D9D901DCDCDC01D9D9D901DADADA02FDFDFD01FFFFFF01FEFEFE01A6A6A601 + AAAAAA01D9D9D901DBDBDB01D8D8D801DDDDDD01D9D9D902DBDBDB02D9D9D901 + DCDCDC01D8D8D802DCDCDC01DADADA01D8D8D801D7D7D701DDDDDD01DADADA02 + DEDEDE01D8D8D801FFFFFF01FEFEFE01FFFFFF01DCDCDC01D9D9D902DBDBDB01 + DADADA01DCDCDC01D8D8D801DBDBDB01DADADA01DBDBDB01DADADA01D7D7D701 + A9A9A901A7A7A701ABABAB01DADADA01D9D9D901DDDDDD01D9D9D901D8D8D801 + DADADA01D9D9D901DBDBDB01D9D9D901DDDDDD01DADADA01D9D9D901FDFDFD01 + FFFFFF01DDDDDD01D7D7D701DCDCDC01A7A7A701DCDCDC01D9D9D901DCDCDC01 + DADADA01D9D9D901DADADA02FDFDFD01FFFFFF01D9D9D901A7A7A701DCDCDC01 + DADADA01DDDDDD01DCDCDC01DBDBDB01D8D8D801DADADA0ADDDDDD01D9D9D902 + E1E1E101D6D6D602DADADA01DCDCDC01DADADA01D9D9D902DADADA01A6A6A601 + A9A9A901A8A8A801DADADA01DCDCDC01DBDBDB01D7D7D701DADADA01DCDCDC01 + D8D8D801DBDBDB01DCDCDC01D8D8D801FFFFFF01D9D9D901AAAAAA01DADADA01 + DCDCDC01D8D8D801DBDBDB01DCDCDC01D8D8D801D7D7D701DCDCDC01DBDBDB02 + D8D8D801DADADA09DBDBDB01DADADA01A9A9A901D7D7D701AAAAAA01A8A8A801 + A6A6A601AAAAAA01FFFFFF01D8D8D801D9D9D902DBDBDB01DCDCDC01DBDBDB01 + FFFFFF01DDDDDD01D7D7D702DCDCDC01D8D8D802A9A9A901DCDCDC01DADADA02 + DBDBDB01D6D6D601DBDBDB01DEDEDE01D8D8D801D9D9D901DEDEDE01DCDCDC01 + DBDBDB01D8D8D801A6A6A601D9D9D901DBDBDB02DADADA01DEDEDE01D7D7D701 + DCDCDC01DADADA01D8D8D801DADADA01D9D9D902DDDDDD01D7D7D701DBDBDB01 + D6D6D601FFFFFF01A9A9A901DCDCDC01D3D3D301DFDFDF01D8D8D801D9D9D901 + DADADA02DBDBDB01DDDDDD01D8D8D801DBDBDB01D9D9D901D8D8D801DBDBDB01 + DADADA01D8D8D803A7A7A703A8A8A801D8D8D801DBDBDB02D9D9D901D8D8D801 + FFFFFF01FBFBFB01DADADA01FFFFFF01D6D6D601DADADA01A8A8A801D4D4D401 + DEDEDE01DCDCDC01DADADA09D6D6D601DDDDDD01D9D9D902D7D7D701A6A6A601 + ACACAC01A8A8A801A7A7A701D8D8D801DFDFDF01D6D6D601DDDDDD01DBDBDB01 + A9A9A901D9D9D901DADADA01DBDBDB01A5A5A501AAAAAA01A5A5A501A8A8A801 + DCDCDC01D9D9D901DDDDDD01A5A5A501DDDDDD01A8A8A801A9A9A901A6A6A601 + DCDCDC01DADADA01D9D9D901FCFCFC01DCDCDC02D9D9D901DCDCDC01D5D5D501 + DDDDDD01DADADA08D9D9D901DDDDDD01D6D6D601DADADA01D9D9D902DCDCDC01 + A9A9A901DADADA01D5D5D501DADADA01DBDBDB01AAAAAA01D5D5D501DBDBDB01 + FDFDFD02D9D9D901DBDBDB02D7D7D701DEDEDE01DCDCDC01A7A7A701D7D7D701 + DDDDDD01D7D7D701DFDFDF01DCDCDC01D7D7D701DADADA02AAAAAA01A4A4A401 + DADADA01D8D8D801DBDBDB01DCDCDC01DADADA01DCDCDC01D9D9D901DBDBDB01 + D6D6D601DADADA03DCDCDC01DBDBDB02DCDCDC01D9D9D901DADADA01FFFFFF03 + D8D8D801DCDCDC01DBDBDB01D9D9D901DBDBDB01D9D9D902DCDCDC01DADADA01 + D8D8D801DADADA01D9D9D901DBDBDB01DCDCDC01A6A6A601D9D9D901E1E1E101 + DADADA01DCDCDC01A7A7A701D9D9D901DCDCDC01D8D8D801DCDCDC01D7D7D701 + DDDDDD01DBDBDB02F8F8F801FFFFFF01AAAAAA01A8A8A801A9A9A901DBDBDB01 + D9D9D901DEDEDE01D9D9D901D8D8D801DCDCDC01DADADA08DDDDDD01D7D7D701 + DBDBDB01DADADA01A9A9A901AAAAAA01A5A5A501A9A9A901DCDCDC01DADADA01 + FEFEFE01DDDDDD01D9D9D901D8D8D801A5A5A501DBDBDB01DCDCDC01A6A6A601 + ABABAB01A8A8A801AAAAAA01D7D7D701DADADA01DDDDDD01A7A7A701A8A8A801 + FEFEFE01A8A8A801A9A9A902A4A4A401DBDBDB01FFFFFF01DCDCDC01D9D9D901 + D8D8D801DBDBDB01D9D9D901DCDCDC01DADADA09FEFEFE01FFFFFF01DEDEDE01 + D9D9D901DDDDDD01DADADA01D7D7D701A6A6A602DEDEDE01A8A8A801D8D8D802 + DCDCDC02DBDBDB01DCDCDC01D9D9D901DEDEDE01A7A7A701DADADA01FFFFFF01 + D6D6D601DADADA01DBDBDB02DCDCDC01D4D4D401D9D9D901DEDEDE01D5D5D501 + DDDDDD01A6A6A601AAAAAA01DDDDDD01FDFDFD01DEDEDE01D9D9D901DBDBDB01 + D7D7D701A6A6A601ABABAB01A8A8A801DBDBDB01D9D9D902DBDBDB01D8D8D801 + DBDBDB01D9D9D901D8D8D801DCDCDC01D9D9D901FCFCFC01A9A9A901A7A7A701 + D6D6D601DCDCDC01D9D9D901DDDDDD01DBDBDB01DADADA01DCDCDC01D4D4D401 + DFDFDF01DBDBDB01DADADA02D9D9D901DDDDDD01D9D9D901D8D8D802DADADA01 + FFFFFF01FEFEFE01DCDCDC01D9D9D901D8D8D801DBDBDB01D9D9D902DCDCDC01 + FFFFFF01DADADA01D7D7D701A8A8A801FFFFFF01DBDBDB01D9D9D901DADADA01 + DDDDDD01D8D8D801DADADA09D9D9D901DADADA01A8A8A801D9D9D901DCDCDC01 + D8D8D801DCDCDC01D8D8D801D9D9D901D7D7D701DADADA01DBDBDB01DCDCDC01 + A7A7A701DEDEDE01D8D8D801FDFDFD01DDDDDD01D8D8D801DBDBDB01DADADA01 + DBDBDB01DDDDDD01D6D6D601A8A8A801D8D8D801DEDEDE01DCDCDC01A4A4A401 + ABABAB01AAAAAA01A7A7A701A4A4A401D9D9D901DADADA01DDDDDD01D5D5D501 + DADADA01DCDCDC01D9D9D901DADADA08FFFFFF01FEFEFE01FCFCFC01D9D9D902 + D8D8D801DDDDDD01A9A9A902A6A6A601FFFFFF01DBDBDB01DCDCDC01D8D8D803 + D9D9D901D7D7D701DCDCDC01D7D7D701DADADA01FFFFFF01D9D9D901DCDCDC02 + D7D7D701D8D8D801DFDFDF01DBDBDB01DCDCDC01FFFFFF02ACACAC01D7D7D701 + D8D8D801D9D9D902DBDBDB01D8D8D801ABABAB01A9A9A901A4A4A401DBDBDB03 + D8D8D801D9D9D901DCDCDC01DADADA01D9D9D901DEDEDE01D6D6D601D8D8D801 + DCDCDC01ABABAB01DADADA01DCDCDC01DBDBDB01D9D9D901D7D7D701D9D9D902 + DADADA01DBDBDB01DDDDDD01D5D5D501D8D8D801FFFFFF01DADADA01D7D7D701 + DBDBDB01DADADA01DCDCDC01A8A8A801D8D8D801DADADA03DBDBDB02DCDCDC01 + DADADA01DBDBDB01FFFFFF03D9D9D901D8D8D801DADADA01DDDDDD01DBDBDB01 + D6D6D601DCDCDC01DADADA09D8D8D801DDDDDD01D8D8D801DADADA01DBDBDB01 + DADADA02DBDBDB01A6A6A601DFDFDF01DBDBDB01D8D8D801D9D9D901DADADA01 + D8D8D801FFFFFF01FEFEFE01DBDBDB01D8D8D801D9D9D901DBDBDB01D7D7D701 + DCDCDC01DBDBDB01A9A9A901DADADA01FBFBFB01D9D9D901DDDDDD01D5D5D501 + A8A8A801AAAAAA01A9A9A902DCDCDC02DBDBDB01DADADA01DBDBDB01D9D9D901 + DADADA08FFFFFF01FEFEFE01DCDCDC01DBDBDB02DADADA01D7D7D701A9A9A901 + DADADA01D8D8D801D9D9D901DBDBDB01DADADA02DBDBDB01DCDCDC01DADADA01 + FFFFFF01D7D7D701DCDCDC01DEDEDE01A7A7A701D9D9D901DBDBDB01D9D9D901 + DCDCDC01DADADA03D7D7D701FEFEFE01FFFFFF01DADADA03DBDBDB02DADADA01 + DBDBDB01FDFDFD01FFFFFF01DCDCDC01DBDBDB01D9D9D902DBDBDB02D7D7D701 + DADADA02D7D7D701DCDCDC01FFFFFF02D5D5D501DADADA01DBDBDB01D9D9D901 + DCDCDC01D9D9D901DDDDDD01DCDCDC01DADADA02D8D8D801D9D9D901FFFFFF01 + DADADA01D7D7D701DCDCDC01DBDBDB01D8D8D801AAAAAA01D4D4D401DEDEDE01 + DBDBDB01D9D9D902DBDBDB01D7D7D701D9D9D901DADADA02A6A6A601FFFFFF01 + DADADA01DDDDDD01A7A7A701DBDBDB01D8D8D801D5D5D501E1E1E101DBDBDB01 + D7D7D701DADADA08FEFEFE02DBDBDB02D9D9D901DBDBDB01D9D9D902DCDCDC01 + D8D8D801D7D7D701DBDBDB01A8A8A801DEDEDE01DADADA01FEFEFE01FFFFFF01 + D8D8D801DDDDDD01D9D9D901DCDCDC01D9D9D901D8D8D801DADADA02FEFEFE01 + FFFFFF03DFDFDF01D8D8D801A6A6A601A5A5A501A9A9A901D9D9D901D6D6D601 + D8D8D801DCDCDC01DADADA01DCDCDC01DADADA08DBDBDB01FCFCFC01FFFFFF02 + A7A7A701DADADA01DCDCDC01D7D7D701A9A9A901DCDCDC01D5D5D501DCDCDC01 + D8D8D801D9D9D901DFDFDF01D6D6D601DADADA01D8D8D801DFDFDF01D6D6D601 + A6A6A601DADADA01D8D8D801DBDBDB01DADADA02D8D8D801DCDCDC01D4D4D401 + DDDDDD01FFFFFF01DBDBDB01DADADA03DCDCDC01D8D8D801D9D9D901FFFFFF02 + DADADA01D7D7D701DDDDDD01DBDBDB01DADADA01D9D9D901DDDDDD01D9D9D901 + DBDBDB01A7A7A701DEDEDE01FDFDFD01FFFFFF01DADADA01D9D9D901DBDBDB01 + D9D9D901D8D8D801DBDBDB01D9D9D902D8D8D801D9D9D901DBDBDB01DADADA01 + D9D9D901FEFEFE01DADADA01DCDCDC01DADADA02FFFFFF01DBDBDB01A9A9A901 + DADADA01A6A6A601DCDCDC01DADADA02DBDBDB01DDDDDD01DADADA01D8D8D801 + DDDDDD01D7D7D701DCDCDC01DADADA01D8D8D801DCDCDC01D9D9D901DDDDDD01 + D8D8D801D9D9D901DCDCDC01DADADA08FFFFFF01FDFDFD01DADADA01DCDCDC01 + D8D8D801DCDCDC01DADADA01DBDBDB01D8D8D801DBDBDB01DDDDDD01A9A9A901 + A6A6A601D9D9D901A8A8A801FFFFFF01FDFDFD01FFFFFF01FCFCFC01FFFFFF02 + DBDBDB01D8D8D801DBDBDB01DCDCDC01FEFEFE01FFFFFF01FDFDFD01FFFFFF01 + FEFEFE01FFFFFF01DBDBDB01A9A9A901D9D9D901DBDBDB03DADADA01D8D8D801 + DADADA09FFFFFF02FEFEFE02DBDBDB01D9D9D901D8D8D801AAAAAA01A7A7A701 + D9D9D901DCDCDC01DADADA03D9D9D901DBDBDB01DADADA02D9D9D901FFFFFF01 + DADADA02DBDBDB01D9D9D901DADADA01DBDBDB01DADADA02DDDDDD01D7D7D701 + DBDBDB01D8D8D801DADADA01D9D9D901DBDBDB01D8D8D801FFFFFF01A9A9A901 + D9D9D902DADADA01DCDCDC01D8D8D801D9D9D901DEDEDE01D8D8D801D9D9D901 + DBDBDB01D9D9D901A9A9A901D9D9D901D8D8D801DBDBDB02DADADA01D9D9D901 + DADADA03DCDCDC01DADADA02DCDCDC01D8D8D801DBDBDB01FEFEFE01FFFFFF01 + FEFEFE01FFFFFF02FEFEFE01DBDBDB01DADADA02DDDDDD01D9D9D902DCDCDC01 + D9D9D901DBDBDB01A7A7A701DBDBDB01DADADA01DBDBDB01D9D9D901FFFFFF01 + DBDBDB01D7D7D701DADADA01DDDDDD01D7D7D701D9D9D901DADADA02DCDCDC01 + DADADA01D9D9D901DADADA02DBDBDB01DADADA01D9D9D901FFFFFF01FEFEFE01 + DBDBDB01D9D9D901DCDCDC01D9D9D901DDDDDD01D7D7D701DADADA01D9D9D902 + A7A7A701DADADA01DBDBDB01A6A6A601FFFFFF04FDFDFD01FFFFFF01D9D9D901 + DCDCDC01A8A8A801DADADA02DBDBDB01FEFEFE01FFFFFF01FDFDFD01FFFFFF02 + DADADA09D8D8D801DADADA03A7A7A701ABABAB01D8D8D801DBDBDB01D9D9D901 + FDFDFD01FFFFFF01D7D7D701DADADA02AAAAAA01A8A8A801DBDBDB01A6A6A601 + ABABAB01D8D8D801DCDCDC01D8D8D801DBDBDB02D8D8D801FFFFFF01D9D9D902 + A5A5A501ABABAB01A6A6A601AAAAAA01D8D8D801DBDBDB01D9D9D901DCDCDC01 + D7D7D701DEDEDE01D8D8D801DADADA01DBDBDB01D8D8D801FFFFFF01A7A7A701 + A5A5A501DBDBDB02D9D9D901DBDBDB01D9D9D901DBDBDB01A8A8A801DADADA02 + FFFFFF01DBDBDB01A6A6A601DEDEDE01D7D7D701D8D8D801DBDBDB01D9D9D901 + DBDBDB02DADADA01D9D9D901DADADA01DBDBDB01DADADA01D8D8D801DDDDDD01 + DADADA01FEFEFE01FFFFFF03D8D8D801A9A9A901FFFFFF01D8D8D801FDFDFD01 + DBDBDB01DCDCDC01D9D9D901D8D8D801DCDCDC01D8D8D801A8A8A802A6A6A601 + A5A5A501A8A8A801D9D9D902DDDDDD01DBDBDB01D7D7D701DDDDDD02DBDBDB02 + D7D7D701DCDCDC01DBDBDB01D9D9D902DBDBDB01DADADA01DBDBDB01FEFEFE01 + DBDBDB01D6D6D601DEDEDE01D9D9D903DDDDDD01DADADA01DBDBDB02A7A7A701 + FFFFFF01D8D8D801DDDDDD01DBDBDB01DADADA01D6D6D601DDDDDD01FFFFFF01 + D8D8D801DDDDDD01A8A8A802DCDCDC01D8D8D801D9D9D901DCDCDC01D9D9D901 + FFFFFF01F9F9F901DCDCDC01DADADA08DBDBDB01DCDCDC01D9D9D901DBDBDB01 + D9D9D901DADADA01D9D9D901DEDEDE01DADADA01D7D7D701DCDCDC01DADADA01 + DCDCDC01DADADA01DCDCDC01A4A4A401A6A6A601A8A8A801ABABAB02D9D9D901 + D7D7D701DDDDDD01D8D8D802DCDCDC01D8D8D801DCDCDC01DDDDDD01A8A8A802 + A7A7A701D7D7D701DFDFDF01D9D9D902DBDBDB01D6D6D601DADADA01DCDCDC01 + D7D7D701DADADA01DDDDDD01FBFBFB01DCDCDC01DDDDDD01D9D9D901DADADA01 + DBDBDB01DCDCDC01DADADA01D9D9D901DBDBDB01D7D7D701DDDDDD01FDFDFD01 + D9D9D901A7A7A701D9D9D901DDDDDD01DADADA01DCDCDC01D9D9D902DADADA01 + D9D9D901DEDEDE01DADADA02D9D9D901DADADA01DBDBDB01D7D7D701DDDDDD01 + D9D9D901DADADA02DBDBDB01A6A6A601DADADA01DEDEDE01D8D8D801DADADA01 + DBDBDB02DCDCDC01FCFCFC01FFFFFF01D8D8D801A7A7A701ADADAD01AAAAAA01 + DADADA01D9D9D902D7D7D701DADADA01DCDCDC01D9D9D901DBDBDB01D6D6D601 + DADADA01DCDCDC01D8D8D802DDDDDD01D9D9D901D7D7D701DCDCDC01DADADA01 + D9D9D901DBDBDB01DADADA01D9D9D903DDDDDD01D8D8D801DADADA01D8D8D801 + A8A8A801DEDEDE01FEFEFE01D8D8D801D9D9D901D8D8D801DBDBDB01DDDDDD01 + D5D5D501FEFEFE01DADADA02A7A7A701D8D8D801D6D6D601DEDEDE01DADADA01 + D9D9D901DBDBDB02DDDDDD01D7D7D701DADADA08D8D8D801D9D9D901DCDCDC01 + FDFDFD01FFFFFF01D8D8D801DBDBDB01D6D6D601DADADA01DCDCDC01D9D9D901 + D8D8D801DBDBDB01D9D9D902AAAAAA01DADADA01DBDBDB01A4A4A401DADADA02 + DBDBDB01D8D8D801DCDCDC01D9D9D901DEDEDE01DBDBDB01FDFDFD02FEFEFE01 + DADADA02DCDCDC01D7D7D701DADADA01DBDBDB01DADADA01DBDBDB01DADADA01 + D9D9D901DEDEDE01DADADA01FBFBFB01FFFFFF01D8D8D801DADADA01D9D9D902 + D8D8D802FFFFFF01DEDEDE01D7D7D701DBDBDB01D7D7D701FFFFFF01DADADA01 + AAAAAA01A7A7A701D8D8D801DCDCDC01D8D8D801DADADA01DBDBDB01D7D7D701 + DDDDDD01D7D7D701DADADA01DBDBDB01D8D8D801DADADA01DDDDDD01A4A4A401 + DADADA01D9D9D901DADADA01FFFFFF01D8D8D801DCDCDC01DADADA01D4D4D401 + DFDFDF01D9D9D902DADADA01D9D9D901FEFEFE01DCDCDC01FFFFFF02D9D9D901 + A5A5A501DBDBDB01D9D9D902DCDCDC02DADADA01DBDBDB01D7D7D701DEDEDE01 + DADADA01D9D9D901DADADA01D9D9D901D8D8D801DEDEDE01DADADA02FDFDFD01 + FFFFFF01D9D9D901DADADA01DCDCDC01DBDBDB01DADADA01D9D9D901DBDBDB01 + DADADA01DBDBDB01A6A6A601A4A4A401DDDDDD01DCDCDC01DBDBDB01DDDDDD01 + DADADA01D8D8D801FFFFFF01DBDBDB01D8D8D801DBDBDB01A5A5A501DEDEDE01 + DDDDDD01A5A5A501A9A9A901AAAAAA01D9D9D901DADADA01D9D9D901DCDCDC01 + DADADA08DBDBDB01DDDDDD01D9D9D902DBDBDB01D8D8D801DCDCDC01DBDBDB01 + FEFEFE01FFFFFF01D7D7D701DBDBDB01D9D9D901DBDBDB01DADADA01D9D9D901 + DDDDDD01D8D8D801ACACAC01D9D9D901DBDBDB01DADADA01DBDBDB01D9D9D901 + DCDCDC01D8D8D801D6D6D601FFFFFF01DEDEDE01FEFEFE01A5A5A501DCDCDC01 + D9D9D901D8D8D801DDDDDD01DADADA01D7D7D701DCDCDC02D9D9D901D8D8D802 + DCDCDC01DADADA01D9D9D901DCDCDC01D8D8D801DCDCDC01DADADA01DBDBDB01 + D9D9D901D8D8D801DEDEDE01D9D9D902FEFEFE01DADADA01A4A4A401A9A9A901 + DDDDDD01D6D6D601DADADA01DBDBDB01D9D9D901DDDDDD01DBDBDB01DCDCDC01 + DADADA01D9D9D902DCDCDC01D9D9D901DDDDDD01DBDBDB01DDDDDD01D9D9D901 + FDFDFD01DDDDDD01D9D9D901DADADA01DCDCDC01D7D7D701DADADA01DEDEDE01 + D6D6D601DCDCDC01AAAAAA01FEFEFE01FFFFFF01FCFCFC01A7A7A701ADADAD01 + A6A6A601DADADA01DBDBDB01DADADA01D5D5D501DCDCDC01DBDBDB01D8D8D801 + A9A9A901A8A8A802ABABAB01AAAAAA01A8A8A801DADADA01D8D8D801FDFDFD01 + FFFFFF01FEFEFE01DADADA04DBDBDB01D9D9D901DBDBDB01D7D7D701ACACAC01 + A7A7A701ACACAC01A7A7A702D7D7D701D8D8D801DBDBDB01D8D8D801FFFFFF01 + DADADA01D9D9D901A8A8A801DBDBDB01D8D8D801DBDBDB01A6A6A601AAAAAA01 + A6A6A601DBDBDB02D9D9D901DADADA09D9D9D901D6D6D601DDDDDD01DCDCDC01 + D7D7D701DCDCDC01DADADA01D9D9D901FFFFFF02DBDBDB03D6D6D601DCDCDC01 + DBDBDB01DADADA01A6A6A601DBDBDB01DADADA01D7D7D701DDDDDD01D6D6D601 + DCDCDC01D9D9D901DCDCDC01DADADA01ABABAB01D9D9D901AAAAAA01A8A8A801 + D8D8D801DDDDDD01DBDBDB01DADADA02DBDBDB01D9D9D902DBDBDB01DCDCDC02 + D8D8D801DADADA03DBDBDB01D9D9D901DBDBDB02D8D8D801DCDCDC01DADADA01 + D6D6D601DDDDDD01FFFFFF02D9D9D901DCDCDC01DADADA01DDDDDD01DADADA01 + DCDCDC01D8D8D801DBDBDB01A4A4A401DADADA03DCDCDC01FFFFFF01DADADA01 + A6A6A602A5A5A501DADADA01DBDBDB01DADADA01DCDCDC01DADADA01DDDDDD01 + DADADA01D8D8D801DCDCDC01D7D7D701FFFFFF01A6A6A601A5A5A501FFFFFF01 + FEFEFE01ACACAC01D5D5D501AAAAAA01DADADA01DCDCDC01DBDBDB01D9D9D901 + DCDCDC01D7D7D701DADADA01A8A8A801A9A9A901A7A7A701A5A5A501A8A8A801 + A5A5A501D9D9D901DBDBDB01DCDCDC01FEFEFE01FFFFFF01D9D9D901DBDBDB01 + D9D9D901D6D6D601DEDEDE01D9D9D901DADADA01DEDEDE01D6D6D601A7A7A701 + A9A9A901A7A7A701AAAAAA01DADADA02A7A7A701FFFFFF01FCFCFC01FFFFFF01 + D8D8D801A8A8A801D9D9D901FFFFFF02DBDBDB01A5A5A501DCDCDC01DADADA01 + DBDBDB03DADADA09DCDCDC01DADADA02DCDCDC01D6D6D601DBDBDB01D9D9D901 + FAFAFA01FEFEFE01DBDBDB01D8D8D801D9D9D901DEDEDE01D9D9D901FEFEFE01 + FFFFFF01E0E0E001D7D7D701DADADA01DEDEDE01D8D8D801D9D9D901DADADA01 + D9D9D901DBDBDB01FFFFFF01A7A7A701FFFFFF01D4D4D401ACACAC01D8D8D801 + D7D7D701DADADA01D7D7D701DBDBDB01DEDEDE01D9D9D901D8D8D801DADADA02 + D8D8D801D9D9D901DDDDDD01D8D8D801D9D9D903DADADA02D9D9D901DBDBDB03 + D9D9D901FEFEFE01FBFBFB01DADADA01DBDBDB01D9D9D901DBDBDB01D5D5D501 + DDDDDD01DADADA02A5A5A501ACACAC01D9D9D901DADADA01D9D9D901A8A8A802 + DADADA01DCDCDC02DDDDDD01D6D6D601DADADA02D8D8D801D9D9D901DCDCDC01 + DBDBDB02DADADA01D9D9D902AAAAAA01FEFEFE01FFFFFF01FCFCFC01AAAAAA01 + DCDCDC01D8D8D801D6D6D601DDDDDD01DADADA02FFFFFF03D8D8D801DADADA02 + ABABAB01A9A9A902D7D7D701DCDCDC01FDFDFD01D6D6D601E0E0E001D7D7D701 + DBDBDB01DEDEDE01D7D7D701D9D9D901DADADA01D8D8D801DBDBDB01E0E0E001 + FCFCFC01A6A6A601DADADA01DBDBDB01DADADA01A8A8A801DADADA01D8D8D801 + DADADA01ABABAB01A5A5A501A7A7A701FFFFFF03DCDCDC01DBDBDB01DADADA03 + D8D8D801DADADA08D8D8D801DADADA01D8D8D801DADADA01DEDEDE01D9D9D901 + DADADA01DDDDDD01FFFFFF03D8D8D801DCDCDC01D9D9D901FCFCFC01FFFFFF01 + D7D7D701D6D6D601DCDCDC01DADADA03D9D9D901DBDBDB01DADADA01FFFFFF01 + FEFEFE01DADADA02DDDDDD01D8D8D801DDDDDD01DADADA01DDDDDD01DBDBDB01 + D9D9D903DCDCDC02DDDDDD01D7D7D701D9D9D901DBDBDB01D8D8D801DDDDDD01 + DCDCDC01DBDBDB01D9D9D901D7D7D701DEDEDE01DADADA01D7D7D701DDDDDD01 + DBDBDB01DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DADADA01DCDCDC01 + D6D6D601FFFFFF01DBDBDB01DADADA01D8D8D801ABABAB01A6A6A601A8A8A801 + FEFEFE01FFFFFF02D7D7D701DBDBDB01D9D9D902DCDCDC01DADADA01DBDBDB01 + D9D9D901DBDBDB01D9D9D901A8A8A801FFFFFF02DCDCDC01DADADA01FFFFFF01 + DADADA01FFFFFF01DBDBDB01A5A5A501DBDBDB03DADADA01D9D9D901FFFFFF02 + FEFEFE01FFFFFF01DADADA02A8A8A801A7A7A701A6A6A601ABABAB01D7D7D701 + FFFFFF01DCDCDC01D9D9D901DADADA02D6D6D601DDDDDD01DBDBDB01DADADA01 + DDDDDD01FDFDFD01D6D6D601FFFFFF01D8D8D801DCDCDC01FFFFFF01D9D9D901 + A7A7A702DCDCDC01DBDBDB01A5A5A501AAAAAA01A7A7A701D9D9D901FEFEFE01 + DADADA01DBDBDB01D8D8D801DADADA01DEDEDE01D7D7D701DCDCDC01DADADA08 + DCDCDC01D8D8D801DBDBDB01DADADA01D7D7D701A9A9A901DADADA01D8D8D801 + FEFEFE01FFFFFF03DADADA01A6A6A601DCDCDC01DADADA02DDDDDD01DADADA02 + D9D9D901DBDBDB01A8A8A801D9D9D901DBDBDB01FCFCFC01DDDDDD01D9D9D901 + FEFEFE01DADADA02D9D9D901DBDBDB01D8D8D801DADADA01DBDBDB01D9D9D901 + DADADA02D9D9D902DBDBDB02DADADA03D8D8D801D9D9D901DBDBDB01DCDCDC01 + D9D9D901D7D7D701DDDDDD01A6A6A601A5A5A501A9A9A901A8A8A801D7D7D701 + DBDBDB01D9D9D901DADADA01D9D9D901DCDCDC01FEFEFE01FFFFFF01D9D9D901 + DADADA01D7D7D701ABABAB01A7A7A701DCDCDC01D9D9D902DBDBDB01A6A6A601 + A8A8A801AAAAAA01A7A7A701A8A8A801A7A7A701DEDEDE01D4D4D401FFFFFF01 + DCDCDC01D9D9D901FEFEFE01DBDBDB01D8D8D801DCDCDC01FFFFFF01D9D9D901 + D7D7D701DDDDDD01D9D9D901DBDBDB01D9D9D901DADADA01D9D9D901DBDBDB01 + FFFFFF03DBDBDB01D8D8D801DCDCDC01A8A8A801A6A6A601ADADAD01FAFAFA01 + FFFFFF02DADADA01DBDBDB01D8D8D801DADADA01DBDBDB02DADADA01D9D9D901 + A8A8A801DBDBDB01D9D9D901D8D8D801DEDEDE01FFFFFF01D8D8D801DADADA01 + DBDBDB01D9D9D901DADADA01DBDBDB01A9A9A901A6A6A601A8A8A801A6A6A601 + DCDCDC01D8D8D801DBDBDB01DDDDDD01D9D9D902DADADA04DBDBDB01A7A7A701 + D9D9D901DBDBDB01A7A7A701DBDBDB01DADADA01DBDBDB01D9D9D901D8D8D801 + DEDEDE01D7D7D701D8D8D801DADADA01FFFFFF02FDFDFD01DCDCDC01D8D8D801 + DBDBDB03DADADA03DCDCDC02D9D9D902DCDCDC01FFFFFF01FDFDFD01DEDEDE01 + D7D7D701DDDDDD01DADADA01D9D9D901DADADA11DCDCDC01D8D8D801DBDBDB01 + D9D9D902AAAAAA01A8A8A802DCDCDC01D7D7D701DDDDDD01DBDBDB01D9D9D901 + A9A9A901A8A8A802DCDCDC01D9D9D901FDFDFD01FFFFFF02A4A4A401AAAAAA01 + DADADA01DBDBDB01D9D9D901DADADA01A3A3A301AAAAAA01A7A7A701AAAAAA01 + D7D7D701FFFFFF01DADADA01D9D9D901D7D7D701DEDEDE01DDDDDD01D7D7D701 + A7A7A701AAAAAA01D9D9D901DDDDDD01DBDBDB01D8D8D801D9D9D901DCDCDC01 + D9D9D901DADADA02D9D9D901FFFFFF01D8D8D802DCDCDC02DADADA01A7A7A701 + D8D8D801FFFFFF01FCFCFC01FEFEFE01D7D7D701DCDCDC01DEDEDE01D9D9D901 + DCDCDC01D8D8D801A9A9A901DADADA01DCDCDC01D9D9D901DBDBDB01DCDCDC01 + D7D7D701DBDBDB01DEDEDE01FFFFFF02D9D9D901D8D8D801D9D9D901DCDCDC01 + A8A8A801A9A9A901AAAAAA01DDDDDD01DBDBDB01D8D8D802D9D9D901DCDCDC03 + D6D6D601DCDCDC01D8D8D801AAAAAA01DADADA02A9A9A901A6A6A601DADADA01 + D9D9D901FFFFFF01DBDBDB01D7D7D701DBDBDB01DFDFDF01DBDBDB01D8D8D801 + FFFFFF02D6D6D601DEDEDE01DBDBDB01D9D9D901D8D8D801DADADA01DDDDDD01 + D7D7D701FEFEFE01D9D9D902DDDDDD01D8D8D801DCDCDC01DBDBDB01DADADA01 + DBDBDB01D9D9D901D8D8D801DDDDDD01DADADA10D8D8D801D7D7D701DEDEDE01 + FFFFFF02DCDCDC01FFFFFF01A6A6A601D8D8D801DDDDDD01DADADA01D8D8D801 + A9A9A901A6A6A601A9A9A902A8A8A801A7A7A701FFFFFF04DCDCDC01DADADA01 + FFFFFF01FEFEFE01FFFFFF04DCDCDC01D9D9D901DCDCDC01D9D9D901DADADA01 + D9D9D901DEDEDE01D6D6D601D7D7D701DDDDDD01A9A9A901A6A6A601D9D9D901 + DBDBDB01D9D9D901A7A7A701DADADA01D9D9D901D8D8D801DDDDDD01DADADA01 + D9D9D901DBDBDB01DADADA01DBDBDB01DADADA01D7D7D701DADADA01ABABAB01 + A8A8A801D8D8D801FFFFFF03D9D9D901DADADA01D7D7D701D6D6D601FFFFFF03 + D7D7D701DADADA02D9D9D901D8D8D801FEFEFE02FFFFFF02DDDDDD01DADADA01 + FFFFFF01FCFCFC01DCDCDC01A7A7A701AAAAAA01D3D3D301D9D9D901DBDBDB02 + DDDDDD01DADADA01D7D7D701D8D8D801DCDCDC01FFFFFF01DADADA01D8D8D801 + FEFEFE01D9D9D901DBDBDB01DADADA02DBDBDB01D8D8D801DCDCDC01D9D9D902 + D5D5D501DADADA01DCDCDC01D7D7D701DADADA01DCDCDC01D6D6D601D8D8D801 + DCDCDC01DBDBDB01DCDCDC01D6D6D601DEDEDE01DDDDDD01DADADA01D9D9D901 + DCDCDC01DADADA01D9D9D901DADADA01D9D9D901D8D8D801DCDCDC02D7D7D701 + DADADA10DBDBDB01DDDDDD01D3D3D301DBDBDB01FFFFFF01FCFCFC01FEFEFE01 + DCDCDC01D9D9D901DADADA01DDDDDD01D5D5D501FFFFFF02D7D7D701FFFFFF01 + FDFDFD01ACACAC01D6D6D601D9D9D901FEFEFE01FFFFFF01DADADA01D9D9D901 + DADADA01D9D9D901FCFCFC01FFFFFF03DADADA01D8D8D801DADADA01DEDEDE01 + DADADA01D9D9D901DADADA02FFFFFF01FCFCFC01FFFFFF01D9D9D901DBDBDB01 + DADADA01A7A7A701A9A9A902DBDBDB01AAAAAA01A7A7A701AAAAAA01DADADA01 + D9D9D901DADADA01DBDBDB01DADADA01D9D9D901A9A9A901A5A5A501A9A9A901 + D9D9D901FEFEFE01FDFDFD01FEFEFE01FFFFFF01FEFEFE01FFFFFF03D8D8D801 + DADADA02DBDBDB01D8D8D801FEFEFE01DDDDDD01A8A8A801A9A9A901FEFEFE01 + FDFDFD01FFFFFF04FEFEFE01DADADA01D7D7D701E1E1E101DCDCDC01DADADA01 + D8D8D801DADADA01D9D9D901DCDCDC01DADADA02FDFDFD01D7D7D701DEDEDE01 + FFFFFF01FEFEFE01DADADA01DBDBDB01D9D9D901DBDBDB01D9D9D901D8D8D801 + DDDDDD01D9D9D901DCDCDC01D9D9D901DCDCDC01D7D7D701DCDCDC01DFDFDF01 + D9D9D901DEDEDE01D8D8D801DADADA01D9D9D901DCDCDC01D9D9D902D7D7D701 + DCDCDC01D8D8D801DCDCDC01DADADA01DCDCDC01DDDDDD01D9D9D902DCDCDC01 + D9D9D901DADADA10DCDCDC01D8D8D801DBDBDB01FFFFFF01D6D6D601FFFFFF01 + DADADA01D7D7D701DBDBDB02FCFCFC01DFDFDF01DADADA01FFFFFF01DBDBDB01 + FEFEFE01A9A9A901A6A6A601ABABAB01DDDDDD01DBDBDB02DADADA01D9D9D902 + DEDEDE01DADADA01DDDDDD01DBDBDB01D8D8D801D9D9D901DCDCDC01D9D9D901 + D7D7D701DADADA01D8D8D801DCDCDC02FBFBFB01FFFFFF01DCDCDC01D9D9D901 + DADADA01FFFFFF01A7A7A701A8A8A801A7A7A703A8A8A801D7D7D701D8D8D801 + DFDFDF01DBDBDB01D8D8D801DBDBDB01DCDCDC01D9D9D901A9A9A901A7A7A701 + DBDBDB01DADADA01FFFFFF02FBFBFB01D7D7D701DDDDDD01D7D7D701D8D8D801 + DADADA01D9D9D901DCDCDC01D8D8D801FFFFFF01DFDFDF01D7D7D701A7A7A702 + DCDCDC01FFFFFF01A9A9A901A5A5A501D9D9D903DCDCDC01DADADA01D8D8D801 + D7D7D701DBDBDB01DCDCDC02D8D8D801DBDBDB02D9D9D902DEDEDE01D7D7D701 + D8D8D801DADADA01D9D9D901DADADA01DCDCDC01DADADA01D9D9D901DCDCDC01 + D5D5D501DDDDDD01D9D9D902DBDBDB01DCDCDC01D7D7D702D9D9D901D7D7D701 + DDDDDD01DCDCDC01D6D6D601DADADA01DCDCDC01D8D8D801DDDDDD01DCDCDC01 + DADADA02D8D8D802DADADA01DBDBDB01D9D9D902DCDCDC01DADADA10D9D9D901 + D7D7D701DDDDDD01D8D8D801DCDCDC01D7D7D701D9D9D901DEDEDE01DADADA01 + D9D9D902A7A7A701D6D6D601A6A6A601DBDBDB01DCDCDC01A9A9A901A7A7A702 + D8D8D802D9D9D901A7A7A701ADADAD01D7D7D701A6A6A601A9A9A901A4A4A401 + AAAAAA01DBDBDB01DADADA01DBDBDB04DDDDDD01D7D7D701A7A7A701A9A9A901 + DCDCDC01DBDBDB01DADADA01FBFBFB01FFFFFF02A9A9A901DDDDDD01D7D7D701 + DFDFDF01D9D9D901DCDCDC01DBDBDB02D6D6D601DADADA01DBDBDB01D8D8D801 + DADADA01A9A9A901AAAAAA01D8D8D801D9D9D901DADADA01D6D6D601E0E0E001 + DEDEDE01D8D8D802DDDDDD01DBDBDB01A9A9A901D8D8D802FFFFFF01FAFAFA01 + FFFFFF01DEDEDE01A8A8A801A9A9A901A5A5A501A6A6A601AFAFAF01A6A6A601 + AAAAAA01ACACAC01A5A5A501DBDBDB01DADADA02DBDBDB01DADADA02D9D9D901 + DADADA01D7D7D701D9D9D901DFDFDF01D8D8D801DBDBDB01DDDDDD01DBDBDB02 + D9D9D902DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DADADA01DBDBDB01 + D9D9D902DFDFDF01DBDBDB01DCDCDC02D9D9D902E1E1E101A5A5A501A8A8A801 + A7A7A701DBDBDB01D8D8D801DADADA01D8D8D801DEDEDE01DCDCDC01D8D8D801 + DADADA01DCDCDC01DADADA01D9D9D901DADADA10DBDBDB01DCDCDC01D8D8D801 + DBDBDB03DADADA01D7D7D701DADADA01FFFFFF02D6D6D601FFFFFF01A8A8A801 + DADADA01D7D7D701DADADA01AAAAAA01A7A7A701DCDCDC01DBDBDB01DADADA01 + DBDBDB01D6D6D601AAAAAA02A7A7A701ABABAB01DADADA01D9D9D901DADADA01 + D6D6D601DBDBDB01D8D8D801D6D6D601DDDDDD01D8D8D801A8A8A801A9A9A901 + D8D8D801D6D6D601DEDEDE01FFFFFF01FEFEFE01DCDCDC01D7D7D701DADADA01 + DCDCDC01D5D5D501DADADA01DBDBDB01DADADA01D7D7D701DCDCDC02DADADA01 + DFDFDF01DADADA01A6A6A601A7A7A701DCDCDC01DBDBDB01DADADA01FDFDFD01 + D8D8D801D6D6D601DDDDDD01DADADA01D8D8D801A7A7A702DCDCDC01DADADA01 + DCDCDC01FFFFFF01FAFAFA01DBDBDB01A6A6A601D9D9D902DFDFDF01D7D7D701 + DADADA01A5A5A501A8A8A801ABABAB01D9D9D901DADADA01DCDCDC01DBDBDB01 + DADADA03D9D9D901DDDDDD01DCDCDC01D9D9D901D8D8D802D9D9D901A8A8A801 + DADADA02DBDBDB01DADADA01DBDBDB02D7D7D701DBDBDB01D9D9D901DADADA01 + D6D6D601DCDCDC02D7D7D701DADADA01D9D9D901DCDCDC01D9D9D901D6D6D601 + DADADA01ACACAC01A7A7A701DBDBDB01D8D8D801DBDBDB01D8D8D801DADADA04 + D9D9D902DCDCDC01DADADA10D8D8D801DCDCDC01DADADA01DBDBDB01D9D9D901 + D6D6D601DEDEDE01DADADA01D9D9D901FCFCFC01FFFFFF02D6D6D601FEFEFE01 + DADADA01DDDDDD01DBDBDB01A5A5A501A8A8A801DCDCDC01FEFEFE01FDFDFD01 + D9D9D901FFFFFF01FEFEFE02FFFFFF01DADADA01D9D9D901DADADA02DBDBDB01 + D9D9D901DADADA01DBDBDB01FDFDFD01DADADA01A9A9A901A7A7A701DCDCDC01 + DADADA01A7A7A701A8A8A801DBDBDB01D8D8D801DCDCDC01D9D9D901FFFFFF02 + FEFEFE01FFFFFF01DADADA01DBDBDB01DADADA01D8D8D801DBDBDB01D7D7D701 + DDDDDD01A7A7A701ABABAB01A6A6A601DADADA01D7D7D701DFDFDF01D9D9D902 + DADADA01D8D8D801FFFFFF01DADADA01DBDBDB01DADADA01DBDBDB01D9D9D902 + FFFFFF01FEFEFE01DBDBDB01DADADA01FFFFFF01FEFEFE01FFFFFF03DBDBDB01 + D8D8D801DADADA04DBDBDB01D9D9D901DBDBDB01DADADA02D7D7D701DADADA01 + DCDCDC01DBDBDB02DADADA01A8A8A801DBDBDB01D7D7D701DDDDDD01D8D8D801 + DADADA02D8D8D801DBDBDB01DADADA01DCDCDC01D9D9D902DADADA02DCDCDC01 + D7D7D701FFFFFF02FEFEFE01DADADA01D9D9D901DADADA01DDDDDD01D8D8D801 + DBDBDB01DADADA01DBDBDB02D9D9D901DBDBDB01DCDCDC01D8D8D801DADADA13 + D8D8D801DCDCDC01DBDBDB01D6D6D601DCDCDC02DADADA02FEFEFE01FFFFFF02 + DBDBDB01D8D8D801D9D9D901ABABAB01A7A7A701D9D9D901FFFFFF03FDFDFD01 + FFFFFF01FEFEFE01D9D9D901DDDDDD01D6D6D601DCDCDC01DBDBDB01D8D8D801 + DCDCDC01D9D9D902DCDCDC01D8D8D801AAAAAA01ACACAC01A6A6A601A7A7A701 + A9A9A901D7D7D701DADADA01DBDBDB01DADADA02DBDBDB01FFFFFF01FDFDFD01 + FEFEFE01DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DADADA01DBDBDB01 + AAAAAA01A7A7A701A8A8A802D9D9D901DADADA01DDDDDD01D7D7D701DEDEDE01 + FDFDFD01FFFFFF01DCDCDC01DBDBDB01DADADA01D9D9D902FFFFFF01D8D8D801 + DCDCDC01D9D9D901D8D8D801DDDDDD01D9D9D902FFFFFF02D7D7D701DADADA02 + D9D9D901DBDBDB01DADADA01DBDBDB01DADADA01D8D8D801DADADA02DCDCDC01 + D9D9D901D8D8D801FEFEFE01DDDDDD01D9D9D901A9A9A901DADADA09DCDCDC01 + D6D6D601DBDBDB01DCDCDC01D9D9D901A8A8A801D9D9D901D8D8D801FFFFFF02 + D7D7D701DCDCDC01DADADA03DBDBDB01D9D9D901DBDBDB02DADADA03A9A9A901 + DADADA08D9D9D901DCDCDC01D8D8D801DCDCDC01D9D9D901DADADA01D8D8D801 + DBDBDB02D9D9D901DADADA03DCDCDC01DBDBDB02DADADA02DBDBDB01DADADA01 + FFFFFF01FEFEFE01FFFFFF03D9D9D901A8A8A801A9A9A901A7A7A702DCDCDC01 + D8D8D801D7D7D701DBDBDB02A8A8A801DCDCDC01DBDBDB02D9D9D901D7D7D701 + DDDDDD01FEFEFE01D7D7D701DEDEDE01A5A5A501A4A4A401DCDCDC01DDDDDD01 + DADADA01DEDEDE01D8D8D801DDDDDD01A6A6A602A9A9A901D8D8D801FFFFFF02 + D9D9D901DADADA01DBDBDB01DCDCDC01D8D8D801FFFFFF02D4D4D401A8A8A801 + AAAAAA01A9A9A901DDDDDD01D8D8D801D9D9D901DBDBDB01DADADA01DBDBDB01 + DCDCDC01D8D8D802DCDCDC02DBDBDB01D9D9D901FFFFFF01DADADA01D9D9D901 + DCDCDC01A7A7A701A9A9A902D7D7D701DBDBDB01A9A9A901ABABAB01DBDBDB01 + D7D7D701DBDBDB01D9D9D901D7D7D701DDDDDD01DADADA01DDDDDD01D9D9D901 + D8D8D801DEDEDE01D9D9D901DEDEDE01FBFBFB01DADADA01D9D9D901DADADA08 + DBDBDB01D9D9D901DDDDDD01D9D9D901DBDBDB01DADADA02A9A9A901AAAAAA01 + D9D9D901A7A7A701DDDDDD01D7D7D701DADADA02D9D9D901DBDBDB01D9D9D901 + D7D7D701D9D9D901DCDCDC01D7D7D701DBDBDB01D8D8D801DADADA08D6D6D601 + DBDBDB01DADADA01D9D9D901DADADA02ABABAB01DADADA01D9D9D901DCDCDC01 + D9D9D902DADADA01D8D8D802D9D9D901DBDBDB01DADADA01D7D7D701DCDCDC01 + FDFDFD01FFFFFF02FEFEFE01FDFDFD01DDDDDD01A7A7A702FFFFFF02A8A8A802 + ADADAD01D9D9D901D8D8D801D9D9D901DDDDDD01D6D6D601D7D7D701DCDCDC01 + DBDBDB01FFFFFF01DADADA01DCDCDC01DADADA01DCDCDC02D8D8D801DADADA02 + D6D6D601DEDEDE01D9D9D901DCDCDC01A9A9A901A7A7A701DCDCDC01FFFFFF01 + FEFEFE01D7D7D701DBDBDB01DADADA01D6D6D601FFFFFF01FDFDFD01FFFFFF02 + DBDBDB01A7A7A701A6A6A601D7D7D701DCDCDC02D8D8D801D9D9D901DADADA01 + D9D9D901DADADA01D6D6D601DDDDDD01D8D8D801FDFDFD01FFFFFF02FBFBFB01 + FFFFFF01FDFDFD01FEFEFE01DDDDDD01D8D8D801DADADA01DBDBDB01A8A8A801 + D7D7D701DCDCDC01DDDDDD01D7D7D701DBDBDB01AAAAAA01A5A5A501DBDBDB01 + D6D6D601DDDDDD01D9D9D902DADADA02FFFFFF01D9D9D901DADADA09D8D8D801 + DEDEDE01D7D7D701D8D8D801FFFFFF01DBDBDB01DADADA01D8D8D801DBDBDB01 + D7D7D701DADADA02D9D9D901DEDEDE01DCDCDC01DBDBDB01D8D8D801DBDBDB01 + DEDEDE01DBDBDB01D8D8D801FFFFFF01D5D5D501DBDBDB01DADADA08DBDBDB01 + DEDEDE01D9D9D901DADADA01DBDBDB01DADADA01D8D8D801D9D9D901DCDCDC01 + D9D9D901D8D8D801DBDBDB01DADADA01DBDBDB01DFDFDF01DADADA01D9D9D901 + DDDDDD01DADADA01D9D9D901DCDCDC01DADADA01D7D7D701DCDCDC01FFFFFF01 + FCFCFC01FFFFFF02D9D9D901D7D7D701D8D8D801D9D9D901D8D8D801FFFFFF01 + DCDCDC01D9D9D902DBDBDB01DDDDDD01DADADA01D8D8D801FEFEFE01D9D9D901 + DEDEDE01D5D5D501DADADA01D8D8D801DEDEDE01D8D8D801DBDBDB01DADADA01 + DCDCDC01D8D8D801DADADA01A9A9A901ABABAB01A5A5A501FDFDFD01FEFEFE01 + DEDEDE01D9D9D901DBDBDB01A9A9A901D8D8D801FFFFFF01FCFCFC01FFFFFF01 + DBDBDB01A5A5A501ACACAC01D9D9D901DCDCDC01D9D9D902DDDDDD01DCDCDC01 + DADADA01DCDCDC01DDDDDD01DADADA02D9D9D901FCFCFC01D8D8D801DCDCDC01 + FEFEFE01FFFFFF02DADADA01D8D8D801FFFFFF01FDFDFD01DBDBDB02D8D8D801 + D9D9D901DDDDDD01DCDCDC01A8A8A801A9A9A902DBDBDB01D7D7D701DDDDDD01 + DBDBDB02DADADA03DBDBDB01DADADA08DBDBDB01D9D9D902DEDEDE01DADADA01 + FFFFFF01FEFEFE01DDDDDD01FFFFFF01DADADA01D9D9D901DCDCDC02D7D7D701 + DADADA01D8D8D801DADADA01D9D9D901D8D8D802D9D9D901D7D7D701DCDCDC02 + DADADA09D6D6D601DBDBDB01D9D9D901FFFFFF01D7D7D701DCDCDC01DBDBDB01 + D7D7D701D9D9D901DCDCDC01DDDDDD01D9D9D901D8D8D801D9D9D901D8D8D801 + D9D9D901DBDBDB01DADADA02D9D9D901DADADA01D8D8D801DADADA01FDFDFD01 + FEFEFE01DDDDDD01D7D7D701DDDDDD01D9D9D901FFFFFF01DADADA01DCDCDC01 + D9D9D901DBDBDB01D9D9D901D8D8D801DCDCDC01D9D9D901D8D8D801FFFFFF02 + D9D9D902DCDCDC01D8D8D801D9D9D901DCDCDC01DADADA01DCDCDC02D8D8D801 + D9D9D901DCDCDC01A5A5A501A7A7A701A9A9A901FFFFFF01FDFDFD01FEFEFE01 + DBDBDB01A7A7A701A8A8A802D9D9D901FDFDFD01DBDBDB01DCDCDC01A7A7A702 + DCDCDC01D9D9D902DBDBDB01DADADA01D8D8D802DADADA01D8D8D801D9D9D901 + DDDDDD01D9D9D901E0E0E001D7D7D701DCDCDC03DADADA01D9D9D901DBDBDB01 + FFFFFF01DBDBDB01D8D8D801DADADA01DCDCDC01D9D9D901FDFDFD01FEFEFE01 + A6A6A601DBDBDB01D7D7D701DBDBDB01DCDCDC01DADADA01D6D6D601D9D9D901 + DDDDDD01D8D8D801DBDBDB01DADADA09DBDBDB01DADADA01DBDBDB01D8D8D802 + D9D9D901DCDCDC01D8D8D801DBDBDB03D7D7D701DADADA01D7D7D701DEDEDE01 + DBDBDB01DCDCDC01DADADA01DBDBDB01DEDEDE01D9D9D901DBDBDB01DCDCDC01 + D7D7D701DADADA09DDDDDD01D8D8D801DBDBDB01DADADA01DEDEDE01D6D6D601 + D9D9D901DCDCDC02DADADA01D7D7D701DBDBDB01DDDDDD01D8D8D801DCDCDC02 + D9D9D902DADADA01DCDCDC01DDDDDD01DCDCDC01D9D9D901DBDBDB02DADADA01 + DEDEDE01D7D7D701DCDCDC01D8D8D801DBDBDB01D9D9D901D7D7D701DBDBDB01 + DCDCDC01D9D9D901D8D8D801DADADA01D7D7D701FFFFFF02FEFEFE01D9D9D902 + DCDCDC02D9D9D901D7D7D701DCDCDC01D7D7D701D9D9D901DEDEDE01D6D6D601 + FFFFFF01D8D8D801DCDCDC01FFFFFF01FEFEFE02DEDEDE01A7A7A701A9A9A901 + A8A8A801AAAAAA01DBDBDB01DADADA01D7D7D701AAAAAA01A7A7A701D9D9D901 + DADADA01DCDCDC01DADADA01D8D8D801DCDCDC01DEDEDE01D8D8D801DBDBDB02 + DADADA01D9D9D902DCDCDC01D5D5D501DADADA02D7D7D701DADADA01D9D9D901 + DBDBDB02DADADA01DBDBDB01D8D8D801DBDBDB01FFFFFF03DDDDDD01DBDBDB01 + D8D8D801DADADA01D9D9D901DCDCDC02DBDBDB02D8D8D801D9D9D901DADADA08 + D8D8D801DCDCDC01DADADA01DBDBDB02DDDDDD01D9D9D901DBDBDB01D8D8D801 + DDDDDD01D8D8D801DEDEDE01DCDCDC01DADADA01D8D8D802DADADA02D9D9D901 + DADADA01D9D9D903DCDCDC01DADADA08D9D9D901DADADA03D8D8D802DDDDDD01 + DADADA01DBDBDB01D7D7D701DBDBDB02D8D8D801DBDBDB02D9D9D902D8D8D801 + DCDCDC01DADADA02D8D8D801DCDCDC01DBDBDB01D9D9D902D5D5D501D9D9D901 + DBDBDB01D6D6D601DBDBDB01DDDDDD01DADADA01DBDBDB01D9D9D901D8D8D801 + DBDBDB01DCDCDC01D9D9D901DDDDDD01FFFFFF02FCFCFC01FFFFFF02FDFDFD01 + DADADA01DBDBDB04FEFEFE01FFFFFF03D8D8D802DCDCDC01FEFEFE01FFFFFF01 + D7D7D701DBDBDB01A6A6A601A8A8A801D6D6D601DADADA02DCDCDC01A8A8A801 + DADADA01DCDCDC01D9D9D902DADADA04D8D8D801DBDBDB01D7D7D701DCDCDC01 + DADADA01DCDCDC01D8D8D801DBDBDB03DADADA01AAAAAA01DDDDDD01D7D7D701 + DADADA01D7D7D701DDDDDD02D7D7D701FEFEFE01DDDDDD01D7D7D701D9D9D901 + DADADA02D9D9D901DADADA02D8D8D801D9D9D901D7D7D701DDDDDD01DBDBDB01 + DADADA08DEDEDE01D8D8D801DBDBDB01DADADA01DBDBDB01DADADA01D8D8D801 + D9D9D901DDDDDD01D5D5D501DADADA01D9D9D901DADADA01DCDCDC01DADADA01 + DBDBDB01D8D8D801DCDCDC01D9D9D902DBDBDB01DCDCDC01D9D9D902DADADA08 + DDDDDD01D6D6D601DDDDDD01D8D8D801DADADA01DBDBDB03D8D8D801DCDCDC01 + D8D8D801DBDBDB01DCDCDC01D8D8D801DCDCDC01D9D9D901DCDCDC01DADADA01 + DBDBDB01DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DBDBDB02DDDDDD01 + D9D9D901DCDCDC01DADADA01A8A8A801A5A5A501DCDCDC01DADADA01DBDBDB01 + D9D9D901DADADA02D9D9D901DADADA01D9D9D901FDFDFD01FFFFFF01FEFEFE02 + DCDCDC01D9D9D901DBDBDB01DADADA01D9D9D901DADADA01FFFFFF01DADADA04 + DBDBDB01D8D8D801FFFFFF01DADADA01D9D9D901DCDCDC01DBDBDB02DCDCDC01 + D9D9D902DADADA01D8D8D801DCDCDC01D8D8D801DCDCDC01DBDBDB01D9D9D901 + DBDBDB02DADADA01DBDBDB01D9D9D901DADADA01D9D9D901DADADA03DCDCDC01 + D9D9D902AAAAAA01D7D7D701D9D9D901DCDCDC01DADADA01DCDCDC01D8D8D801 + D9D9D902DDDDDD01D8D8D801DCDCDC01D8D8D801DADADA02DBDBDB01DADADA02 + DBDBDB02D9D9D901DBDBDB01D9D9D901DADADA08D8D8D801DBDBDB01D7D7D701 + DDDDDD01D9D9D901D8D8D801DEDEDE01D9D9D901D8D8D801DFDFDF01D8D8D801 + D9D9D901DADADA01DBDBDB01D8D8D801DADADA01DBDBDB01D8D8D801DADADA01 + DCDCDC01D8D8D801DBDBDB01D8D8D801DCDCDC01DADADA08D8D8D801DEDEDE01 + D9D9D901D8D8D801DBDBDB02D7D7D701D9D9D901DBDBDB01DADADA01A8A8A801 + A9A9A901D7D7D701DCDCDC01D9D9D901DCDCDC01D9D9D901DADADA02DBDBDB01 + D9D9D901DADADA02DBDBDB01D8D8D801DCDCDC01DADADA01D8D8D801DCDCDC01 + D9D9D901DADADA03DBDBDB01DADADA02D8D8D801DADADA01D9D9D901DDDDDD01 + D8D8D801DCDCDC01D9D9D902FFFFFF02DADADA01DCDCDC01D9D9D901DBDBDB01 + D9D9D902DCDCDC01D9D9D901D8D8D801DDDDDD01DADADA01D9D9D901DBDBDB01 + DEDEDE01D5D5D501DBDBDB03D9D9D901DBDBDB01DADADA01D9D9D901DCDCDC01 + DADADA01D9D9D901DADADA02DBDBDB01D7D7D701DBDBDB01DADADA01DBDBDB02 + DADADA01D8D8D801DDDDDD01DBDBDB01D9D9D901DBDBDB01D9D9D901FFFFFF01 + A7A7A701ABABAB01DADADA03DBDBDB01DADADA01D9D9D901D8D8D801DCDCDC01 + D9D9D901DBDBDB01D9D9D901DBDBDB01DADADA09D9D9D901DBDBDB01DADADA02 + D9D9D901DCDCDC01D7D7D701DBDBDB01D8D8D801DDDDDD01DBDBDB01D9D9D901 + DADADA01D9D9D901DBDBDB01DADADA01DBDBDB01D9D9D901D8D8D801DCDCDC02 + D9D9D901DADADA01DBDBDB01DADADA02D8D8D801DBDBDB01D9D9D901DCDCDC01 + DADADA01DBDBDB01DADADA10D7D7D701DEDEDE01D8D8D801D9D9D901DCDCDC01 + D8D8D801DBDBDB01DCDCDC01DADADA0FD9D9D901AAAAAA01D6D6D601DBDBDB01 + DCDCDC01DBDBDB01DADADA01DBDBDB01D7D7D701DBDBDB01D8D8D801DADADA01 + FFFFFF01FCFCFC01FFFFFF01FEFEFE01FFFFFF02D6D6D601DCDCDC02D9D9D901 + DADADA01DEDEDE01D6D6D601DADADA01DEDEDE01D6D6D601DADADA02DDDDDD01 + DBDBDB01DADADA01D6D6D601DCDCDC01D9D9D901DCDCDC01D7D7D701DADADA01 + DDDDDD01D9D9D901D8D8D801D9D9D901DDDDDD01DADADA01D7D7D701A8A8A801 + D9D9D902DADADA01D7D7D701D8D8D801DADADA01DCDCDC01FDFDFD01DADADA01 + A5A5A501A4A4A401D9D9D901DDDDDD01DADADA01D7D7D701DBDBDB01DDDDDD02 + DADADA01D7D7D701DCDCDC01DADADA01D9D9D901DADADA09DBDBDB01D7D7D701 + D9D9D901DADADA01D8D8D801D9D9D901DFDFDF01D8D8D801DADADA01D7D7D701 + DDDDDD01D9D9D901DCDCDC01DADADA01DCDCDC01D9D9D902DCDCDC02D7D7D701 + DADADA01DCDCDC01D8D8D801D9D9D902DBDBDB01DCDCDC01DADADA02D8D8D801 + DBDBDB01D8D8D801DADADA10FFFFFF01F8F8F801E0E0E001D7D7D701DBDBDB01 + DADADA02D8D8D801DADADA0EDBDBDB01D8D8D801DBDBDB02D9D9D901DBDBDB02 + D9D9D901D7D7D701DFDFDF01D8D8D802DEDEDE01DDDDDD01FDFDFD01FFFFFF02 + D7D7D701DADADA01DEDEDE01D9D9D901A6A6A601AAAAAA01D9D9D901D8D8D801 + DBDBDB01DADADA04D9D9D901FFFFFF01FEFEFE01FFFFFF02D9D9D901DADADA01 + DBDBDB01DEDEDE01DBDBDB01D7D7D701DBDBDB01DCDCDC01DADADA01D6D6D601 + AAAAAA01A7A7A701A9A9A901A6A6A601DCDCDC01DADADA01DCDCDC01DBDBDB01 + D8D8D801D9D9D901FFFFFF02ADADAD01A9A9A901D9D9D901DBDBDB01DADADA01 + DCDCDC01A6A6A601A5A5A501D9D9D901D8D8D801DDDDDD01D8D8D801D9D9D902 + DBDBDB01DADADA09DBDBDB01DADADA01DCDCDC01DDDDDD01D8D8D802DBDBDB01 + DDDDDD01DADADA01D9D9D903DADADA01D8D8D801DBDBDB01D9D9D901DBDBDB02 + DADADA03DBDBDB01DCDCDC01DDDDDD01D8D8D803D9D9D901E0E0E001D6D6D601 + DEDEDE01DADADA10D9D9D901DEDEDE01D9D9D901DADADA01DDDDDD01D9D9D901 + DBDBDB02DADADA0EFEFEFE01DCDCDC01DBDBDB01DADADA01DCDCDC01D7D7D701 + D6D6D601DADADA01DBDBDB01D9D9D901DEDEDE01D9D9D901D8D8D801D6D6D601 + DBDBDB01D9D9D901DCDCDC01DBDBDB01D9D9D901D7D7D701AAAAAA01A8A8A801 + A5A5A501DBDBDB03DADADA01D9D9D901DADADA01DBDBDB01FDFDFD01FEFEFE01 + FFFFFF01FBFBFB01D7D7D701DEDEDE01D9D9D901DADADA01D7D7D701D9D9D901 + DDDDDD01DBDBDB01D9D9D901DADADA01DDDDDD01D7D7D701ABABAB01A7A7A701 + DBDBDB01D7D7D701DADADA01D7D7D701DDDDDD01DADADA01D8D8D801FFFFFF01 + FEFEFE01A6A6A601D7D7D701DADADA01A8A8A801D7D7D701DCDCDC01DBDBDB01 + AAAAAA01DADADA01DBDBDB01DDDDDD01D8D8D801DCDCDC01DBDBDB01D9D9D901 + DADADA08DCDCDC01D7D7D701D9D9D901DBDBDB01D7D7D701DDDDDD01D9D9D901 + DADADA01D8D8D801D9D9D901AAAAAA01DADADA02D9D9D901DADADA01DCDCDC01 + DBDBDB01D9D9D901D7D7D701DDDDDD01DADADA01D8D8D801DDDDDD01D6D6D601 + D7D7D701ABABAB01DBDBDB01A8A8A802DADADA01D6D6D601DADADA11D9D9D901 + DDDDDD01DADADA03D8D8D801DADADA01DBDBDB01DADADA0ED9D9D901DBDBDB01 + D7D7D701D9D9D901DADADA01DCDCDC01DBDBDB01DCDCDC02D8D8D801D7D7D701 + DBDBDB01DCDCDC01DBDBDB01A5A5A501DCDCDC01D8D8D801DCDCDC01AAAAAA01 + DADADA01DDDDDD01A5A5A501ABABAB01A7A7A701D7D7D701D9D9D901DCDCDC01 + D9D9D901DCDCDC02DADADA01DBDBDB01D9D9D901DDDDDD01DBDBDB01D7D7D701 + DADADA01DCDCDC01DADADA01DEDEDE01D7D7D701D9D9D903DCDCDC01D7D7D701 + DCDCDC01A7A7A701DADADA01DCDCDC01DADADA01A7A7A701A9A9A901D7D7D701 + DCDCDC01FFFFFF01FEFEFE01DBDBDB01ADADAD01A5A5A501ABABAB01DCDCDC01 + FDFDFD01D8D8D801DADADA01D7D7D701DCDCDC01D9D9D901DADADA03DBDBDB01 + DADADA08D9D9D901DBDBDB01D9D9D901DADADA01DBDBDB01DCDCDC01D9D9D901 + DADADA02DBDBDB01D9D9D901DBDBDB01DDDDDD01D7D7D701DDDDDD01D7D7D701 + DADADA03D9D9D901DBDBDB01DADADA01D9D9D901DDDDDD01DBDBDB01A6A6A601 + DBDBDB01D8D8D801D9D9D901DCDCDC01D9D9D901DBDBDB01DADADA12D8D8D801 + DADADA01DCDCDC01DBDBDB01DADADA01D8D8D801DADADA0FD9D9D901DEDEDE01 + DADADA01D9D9D902D8D8D801D9D9D901DBDBDB02D9D9D901D8D8D801DBDBDB03 + A7A7A701A9A9A901A5A5A501D7D7D701D9D9D901DBDBDB01A7A7A701ABABAB01 + D7D7D701DCDCDC01DEDEDE01D8D8D801D7D7D701D8D8D802DCDCDC01D7D7D701 + D6D6D601DADADA01DDDDDD01D9D9D901DEDEDE01D9D9D902D8D8D801DBDBDB01 + DEDEDE01A9A9A901D9D9D901DADADA01DEDEDE01A2A2A201A9A9A901D8D8D801 + DBDBDB01D9D9D901A7A7A701D9D9D901AEAEAE01A4A4A401DADADA01A8A8A802 + D4D4D401ADADAD01A4A4A401A6A6A601FFFFFF01DBDBDB01DADADA01DEDEDE01 + D9D9D901DBDBDB01D9D9D901DADADA01D9D9D901DBDBDB01DADADA09D9D9D901 + DDDDDD01DCDCDC01D8D8D801DCDCDC01D8D8D801A8A8A801FDFDFD01DADADA01 + D9D9D901DADADA01D8D8D801DCDCDC02DBDBDB02D9D9D901DDDDDD01D7D7D701 + DCDCDC01DBDBDB01D7D7D701FEFEFE01DBDBDB01FEFEFE02DCDCDC01D9D9D901 + A8A8A801DDDDDD01D9D9D901DADADA13D9D9D903DCDCDC01DDDDDD01DADADA10 + D5D5D501DEDEDE01DADADA01DCDCDC01DEDEDE01D7D7D701D9D9D901DBDBDB01 + D8D8D801DDDDDD01FFFFFF01DBDBDB01D8D8D801A8A8A801DBDBDB01D9D9D901 + DDDDDD01FEFEFE01FFFFFF01D9D9D901DBDBDB01D9D9D901D8D8D801DBDBDB01 + D9D9D901AEAEAE01A8A8A801A9A9A901D9D9D901DBDBDB01DEDEDE01D7D7D701 + DCDCDC01D6D6D601D9D9D901DDDDDD01D7D7D701DBDBDB01D7D7D701FEFEFE02 + FFFFFF02FEFEFE01DCDCDC01DADADA01DCDCDC01FDFDFD01FFFFFF01DCDCDC01 + D6D6D601A8A8A802A9A9A901DCDCDC01D8D8D801DBDBDB01DADADA01DCDCDC01 + DBDBDB01D8D8D801D9D9D902DADADA01D8D8D801DCDCDC01D9D9D901DDDDDD01 + DCDCDC01D7D7D701DADADA08DDDDDD01D8D8D801D7D7D701DADADA01D7D7D701 + DBDBDB02DCDCDC01ABABAB01A7A7A701DADADA01DBDBDB01DADADA01DCDCDC01 + D4D4D401DBDBDB02D8D8D801DCDCDC01D9D9D901DCDCDC01D9D9D901DBDBDB01 + FFFFFF01DADADA01DBDBDB01DADADA01DCDCDC01A8A8A801A5A5A501DADADA01 + DBDBDB01DADADA10DBDBDB01D9D9D901DADADA01DBDBDB02DCDCDC01D9D9D901 + D6D6D601DADADA0ED8D8D801DDDDDD01DCDCDC01D7D7D701DADADA02D7D7D701 + DCDCDC01DBDBDB01D9D9D901DBDBDB01DADADA01D7D7D701FFFFFF01DCDCDC01 + D8D8D802DDDDDD01DADADA01FEFEFE01FFFFFF01DBDBDB01D8D8D801DCDCDC02 + D7D7D701AAAAAA01A5A5A501A8A8A802DADADA01D9D9D902DBDBDB01D7D7D701 + DDDDDD01DADADA01D8D8D801DCDCDC01DBDBDB01FFFFFF03FEFEFE01FFFFFF01 + FDFDFD01DBDBDB01DADADA01D9D9D901FFFFFF01A5A5A501DADADA01FFFFFF01 + D7D7D701D9D9D901DADADA01D8D8D801DCDCDC01FFFFFF02D7D7D701D9D9D901 + DCDCDC01DADADA01D9D9D901AAAAAA01D8D8D801DCDCDC01DBDBDB01D7D7D701 + DBDBDB02DADADA08D7D7D701DDDDDD01DBDBDB01D8D8D801DDDDDD01FDFDFD01 + D9D9D902D8D8D801DADADA01DDDDDD01D6D6D601DDDDDD01D9D9D901DBDBDB01 + DCDCDC01DADADA02D9D9D901DADADA01D9D9D901DADADA01DCDCDC01D8D8D801 + DBDBDB01D8D8D801DADADA01FEFEFE01DBDBDB01DCDCDC01A7A7A702DADADA11 + D9D9D901DBDBDB02D8D8D801DADADA01DBDBDB02DADADA16DBDBDB01DADADA01 + D7D7D701DDDDDD01DCDCDC01FFFFFF01FEFEFE01DBDBDB01DADADA01A7A7A701 + A9A9A901FBFBFB01FFFFFF01DADADA02D9D9D901DCDCDC01FFFFFF01FDFDFD01 + DCDCDC01A6A6A601A9A9A901DDDDDD01D7D7D701DCDCDC01D9D9D901DCDCDC01 + D7D7D701DADADA01D9D9D901DBDBDB04DADADA01D8D8D801DBDBDB01D9D9D902 + DADADA01DCDCDC01D8D8D801DBDBDB01FEFEFE01DADADA01DCDCDC01DADADA01 + D9D9D902DBDBDB01DADADA01A6A6A601AAAAAA01DADADA01D9D9D901D8D8D801 + DBDBDB01DADADA02DBDBDB01D8D8D801DBDBDB02D8D8D801DADADA01DBDBDB02 + D7D7D701DDDDDD01DADADA01D8D8D801DBDBDB02DADADA01D9D9D903DADADA01 + FFFFFF02DADADA10DBDBDB01D9D9D901FFFFFF02D9D9D901DADADA01A7A7A701 + A8A8A801DBDBDB02DADADA01D9D9D901DADADA01D9D9D901DCDCDC01D9D9D902 + DBDBDB02DADADA01D9D9D901DADADA01D7D7D701DDDDDD01D9D9D901DADADA01 + D8D8D801DDDDDD01D7D7D701DADADA01DCDCDC01D7D7D701D9D9D901DBDBDB01 + DADADA01D8D8D801DDDDDD01D8D8D801DADADA01D8D8D801DADADA0EDBDBDB01 + D9D9D901DDDDDD01D8D8D801FBFBFB01FFFFFF01FEFEFE01DADADA01DDDDDD01 + A4A4A401DBDBDB01FFFFFF02FEFEFE01FDFDFD01FFFFFF01FCFCFC01FFFFFF01 + DADADA01FDFDFD01AAAAAA01D7D7D701D9D9D901DEDEDE01D7D7D701DBDBDB01 + D7D7D701DADADA01DDDDDD01DCDCDC01D8D8D801D7D7D701DADADA01D9D9D902 + DBDBDB03DCDCDC01DADADA01FDFDFD01FFFFFF01DBDBDB01DADADA01FFFFFF04 + DBDBDB01DADADA01DBDBDB01A7A7A701D8D8D802DCDCDC01FFFFFF01D9D9D902 + DADADA01D9D9D901DDDDDD01D8D8D801D9D9D901DBDBDB01D9D9D901D7D7D701 + D9D9D901DEDEDE01D8D8D802DEDEDE01DADADA01D7D7D701DBDBDB02DCDCDC01 + DBDBDB01DCDCDC01D6D6D601DBDBDB01DADADA10D8D8D801DBDBDB01DADADA02 + FFFFFF02ABABAB01A9A9A901D7D7D701DADADA01DBDBDB01DCDCDC01D8D8D801 + DFDFDF01D6D6D601DBDBDB01DCDCDC01D8D8D801DBDBDB01DCDCDC01D9D9D901 + AAAAAA02D7D7D701D9D9D901DCDCDC01DADADA02D9D9D901DADADA01DBDBDB01 + DEDEDE01DCDCDC01D8D8D801DCDCDC01DBDBDB01D7D7D701D9D9D901E0E0E001 + DBDBDB01DADADA0ED8D8D801DBDBDB01DADADA02ACACAC01D8D8D801DBDBDB01 + D9D9D901FFFFFF01DADADA01DBDBDB01FAFAFA01FFFFFF02FEFEFE01DCDCDC01 + DADADA01FFFFFF03D9D9D901DCDCDC01DBDBDB01D7D7D701DBDBDB01DADADA01 + DCDCDC01D9D9D901D7D7D701DADADA01D9D9D901DEDEDE01D7D7D701DDDDDD01 + DADADA01DBDBDB01D9D9D901DADADA01D6D6D601DBDBDB01AAAAAA01A6A6A601 + FFFFFF01FDFDFD01FFFFFF01FEFEFE01FDFDFD01FFFFFF01DBDBDB01FDFDFD01 + FFFFFF01DADADA01DCDCDC01DBDBDB01D7D7D701D9D9D901A9A9A901A8A8A801 + DADADA01DBDBDB01D8D8D801DCDCDC01DADADA01D8D8D801A8A8A801DCDCDC01 + DBDBDB01D6D6D601DADADA03D7D7D701DDDDDD01D7D7D701DADADA01D8D8D801 + D9D9D901D8D8D801DEDEDE01D9D9D901DADADA10DBDBDB03DADADA01FFFFFF02 + D3D3D301DCDCDC01DFDFDF01D8D8D801A7A7A701D7D7D701DBDBDB01DADADA01 + DBDBDB01D9D9D901D8D8D801DBDBDB01D7D7D701DEDEDE01A6A6A601A5A5A501 + ABABAB01DADADA01D9D9D903DADADA01DCDCDC01D9D9D902D8D8D801D7D7D701 + DBDBDB01D9D9D901DADADA03D8D8D801DADADA0FDBDBDB01DADADA02D9D9D901 + D6D6D601FFFFFF01DADADA01DCDCDC01D9D9D901DADADA02DEDEDE01D9D9D901 + DADADA01D7D7D701DADADA01FFFFFF01D7D7D701FFFFFF01DADADA01DBDBDB01 + D8D8D802DCDCDC01DBDBDB01D6D6D601DDDDDD01D9D9D901DADADA01DCDCDC01 + D7D7D701D9D9D901DDDDDD01D9D9D901A5A5A501D9D9D901DADADA01DCDCDC01 + DEDEDE01A8A8A802DCDCDC01A6A6A601DDDDDD01D7D7D701DBDBDB01DEDEDE01 + D7D7D701DADADA01FBFBFB01D8D8D801DBDBDB01D8D8D801DBDBDB01D9D9D901 + DBDBDB01A7A7A701A6A6A601DCDCDC01DBDBDB01D7D7D701DCDCDC01DBDBDB01 + DCDCDC02D7D7D701DCDCDC01DDDDDD01D8D8D801DBDBDB01D9D9D901DDDDDD01 + D8D8D801DADADA01DDDDDD01DBDBDB01DADADA01DCDCDC01D7D7D701DCDCDC01 + DADADA10D9D9D901DBDBDB01D7D7D701DADADA01FFFFFF01FDFDFD01DCDCDC01 + DDDDDD01D6D6D601D9D9D901DBDBDB01DEDEDE01DADADA01D7D7D701DEDEDE01 + D9D9D902DDDDDD01A7A7A701FFFFFF01FEFEFE01DDDDDD01D9D9D901DADADA01 + DEDEDE01D7D7D701DCDCDC01DDDDDD01D6D6D601DDDDDD01DBDBDB01A6A6A601 + ABABAB01D9D9D901DCDCDC01D9D9D901DADADA01DCDCDC01D9D9D901DADADA11 + FDFDFD01FFFFFF01FEFEFE01FFFFFF01D8D8D801D9D9D901DCDCDC02D7D7D702 + DEDEDE01D8D8D801DCDCDC01D9D9D901DCDCDC01D6D6D601DFDFDF01D6D6D601 + DDDDDD01DBDBDB04DCDCDC01D7D7D701DBDBDB01DADADA01DBDBDB01DCDCDC01 + D9D9D901DADADA01D8D8D801DDDDDD01DBDBDB01D9D9D901DCDCDC01FBFBFB01 + FFFFFF01DCDCDC01D5D5D501DCDCDC01D8D8D801D9D9D901D7D7D701DADADA01 + DCDCDC01D7D7D701E1E1E101D9D9D901DDDDDD01D9D9D901D7D7D701FFFFFF01 + FEFEFE01DCDCDC01DBDBDB01D9D9D901D7D7D701DADADA01AAAAAA01FDFDFD01 + DBDBDB01D9D9D901DDDDDD01D8D8D802DDDDDD01DADADA02D7D7D701DBDBDB01 + DADADA01D8D8D801DADADA02D6D6D601DDDDDD01D7D7D701DADADA10D9D9D901 + D8D8D801DEDEDE01DADADA01D9D9D901DADADA01DCDCDC01D6D6D601FFFFFF01 + D8D8D801DADADA01D9D9D901DADADA01D8D8D801A7A7A701D8D8D801DDDDDD01 + D8D8D801FFFFFF01FDFDFD01FFFFFF01DADADA01D8D8D801DCDCDC01D7D7D701 + DBDBDB01D8D8D801DBDBDB01DADADA01D9D9D902A9A9A901A5A5A501DADADA02 + DCDCDC01D9D9D902DDDDDD01DBDBDB01DADADA10DCDCDC01DBDBDB01FFFFFF01 + FBFBFB01DADADA01DCDCDC01D8D8D801DBDBDB02D9D9D901DADADA01D9D9D902 + DADADA02DCDCDC01D9D9D901DADADA01D9D9D901D8D8D801DADADA01D9D9D901 + D7D7D701DCDCDC01DBDBDB01D6D6D601DDDDDD01DADADA01A4A4A401AAAAAA01 + FFFFFF01DADADA01DBDBDB01DADADA01D8D8D801FCFCFC01FFFFFF02FDFDFD01 + DEDEDE01DADADA02DDDDDD01DBDBDB01D9D9D902DCDCDC01D5D5D501DBDBDB01 + D7D7D701DDDDDD01D9D9D901FDFDFD01FEFEFE01D9D9D901DBDBDB01D8D8D801 + E1E1E101DADADA01D9D9D902DADADA01DBDBDB01DADADA01A9A9A901A6A6A601 + D9D9D901DBDBDB01D8D8D801DEDEDE01A7A7A701A8A8A801DADADA01DCDCDC01 + DBDBDB01D9D9D901DEDEDE01DADADA11DCDCDC01DBDBDB01D7D7D701D8D8D801 + DBDBDB01D8D8D801DCDCDC01DBDBDB01D7D7D701DEDEDE01D8D8D801DADADA01 + DCDCDC01DADADA01ACACAC01A8A8A801FEFEFE01DADADA01D9D9D901DFDFDF01 + D6D6D601DBDBDB01DADADA01D8D8D801DBDBDB01DCDCDC01DADADA01D9D9D901 + DBDBDB01FEFEFE01FFFFFF01A6A6A601AAAAAA01DDDDDD01D8D8D801DADADA01 + DCDCDC01D8D8D801D9D9D901DADADA0FDBDBDB01D8D8D801DBDBDB01DCDCDC01 + D6D6D601DDDDDD01DBDBDB01D7D7D702DDDDDD01D8D8D801DBDBDB01DADADA01 + DEDEDE01D8D8D801DBDBDB02D7D7D701DEDEDE01DBDBDB01D9D9D901DFDFDF01 + DBDBDB01D7D7D701DADADA02D8D8D801DCDCDC01D8D8D801D9D9D901DCDCDC01 + D9D9D901DBDBDB01D8D8D801DADADA01DCDCDC01D9D9D901DDDDDD01DADADA01 + D9D9D901DADADA01D8D8D801DCDCDC01DBDBDB01D8D8D801D9D9D901DBDBDB01 + DADADA01D9D9D901DBDBDB01DDDDDD01D8D8D801D9D9D901DCDCDC01DBDBDB01 + DADADA01DBDBDB02D8D8D801FAFAFA01D9D9D901DDDDDD01D8D8D801DCDCDC01 + DADADA01D9D9D901DADADA02DBDBDB01DADADA01D9D9D901DADADA01DCDCDC01 + DBDBDB01D8D8D802D9D9D901DBDBDB01D6D6D601D8D8D801DADADA10D7D7D701 + DCDCDC02DBDBDB01DDDDDD01D6D6D601DBDBDB01D8D8D801DDDDDD01A6A6A601 + DADADA01D9D9D901FEFEFE01D9D9D901A6A6A601A8A8A801DADADA02DCDCDC01 + D5D5D501DBDBDB01DCDCDC01DBDBDB01DADADA01D8D8D801D9D9D901DADADA01 + DBDBDB01DCDCDC01FFFFFF01FAFAFA01ACACAC01A6A6A601D9D9D901DDDDDD01 + D8D8D801DBDBDB01DCDCDC01DADADA10DBDBDB03D7D7D701DCDCDC02D5D5D501 + DDDDDD01DBDBDB01D7D7D701DCDCDC01D9D9D902D8D8D801DADADA02DBDBDB01 + DADADA02D8D8D801DADADA01D7D7D701DBDBDB03D9D9D901DCDCDC01D7D7D701 + FFFFFF01FCFCFC01DCDCDC01D9D9D902DDDDDD01D9D9D901DADADA01DBDBDB01 + D8D8D801DBDBDB01D9D9D901DCDCDC01D8D8D801D9D9D901DADADA01DBDBDB02 + D9D9D901DBDBDB02D7D7D701DBDBDB01DCDCDC01D9D9D902DBDBDB01D9D9D902 + A8A8A801AAAAAA01DADADA01DBDBDB01DADADA01DBDBDB01DADADA01FDFDFD01 + FFFFFF01D8D8D801DBDBDB02D9D9D901FEFEFE01FFFFFF01D9D9D901DADADA02 + DBDBDB02D8D8D801DDDDDD01DADADA11DDDDDD01D6D6D601DCDCDC01D9D9D902 + DCDCDC01D9D9D901A9A9A901A8A8A801A9A9A901A8A8A802DADADA01DCDCDC01 + A7A7A701DBDBDB01DCDCDC01A5A5A501DBDBDB01DCDCDC01DBDBDB01D8D8D802 + A9A9A901DBDBDB01DADADA02D8D8D801DADADA01FDFDFD01FFFFFF01D8D8D801 + DADADA01DCDCDC01D8D8D801DBDBDB01D9D9D901DADADA02DBDBDB01DADADA10 + D8D8D801DBDBDB01DCDCDC01D9D9D902DBDBDB01DCDCDC01D8D8D801D9D9D901 + DCDCDC01DADADA01D9D9D901DCDCDC01D8D8D801DADADA21D9D9D901DCDCDC01 + D8D8D801DADADA01DDDDDD01D8D8D801DCDCDC01DDDDDD01D8D8D801D9D9D901 + DBDBDB01D9D9D901DCDCDC01D8D8D801DADADA01DBDBDB01DADADA01D8D8D801 + DBDBDB02D8D8D801DCDCDC01DADADA01DBDBDB01D8D8D801DBDBDB02D9D9D901 + DBDBDB01DADADA01D8D8D801DBDBDB01A9A9A901D9D9D902DBDBDB01DADADA01 + DCDCDC01DADADA01D9D9D901DCDCDC01D9D9D901DADADA02D7D7D701DEDEDE01 + D8D8D801D9D9D901DDDDDD01D8D8D801DCDCDC01D9D9D902DADADA01FFFFFF01 + A8A8A802A6A6A601ABABAB01DADADA02A7A7A701DADADA01DDDDDD01D6D6D601 + DCDCDC02D7D7D701DBDBDB01D9D9D901DBDBDB02D9D9D901DBDBDB01A8A8A801 + DBDBDB01FCFCFC01FFFFFF01DADADA02A9A9A901DADADA01DBDBDB01DADADA01 + DBDBDB02DADADA10DCDCDC01DBDBDB01D9D9D901D8D8D802DADADA01D9D9D901 + D8D8D801DDDDDD01DBDBDB01D7D7D701DBDBDB01D8D8D801D9D9D901DCDCDC01 + DADADA20DBDBDB01D8D8D801DADADA01DBDBDB01DEDEDE01D7D7D701DCDCDC01 + FEFEFE01FCFCFC01DEDEDE01DADADA02D9D9D901DADADA01DDDDDD01D8D8D801 + DCDCDC01D9D9D901DBDBDB01D9D9D901A7A7A701AAAAAA01D9D9D901DBDBDB01 + D9D9D901DBDBDB02D7D7D701D9D9D901DCDCDC01D9D9D901DADADA01D7D7D701 + DADADA01DBDBDB01DDDDDD01DADADA01D8D8D801D9D9D903DCDCDC01DADADA02 + D8D8D801DCDCDC01D7D7D701A9A9A901DADADA02D9D9D901D6D6D601DFDFDF01 + FEFEFE01FFFFFF01D9D9D901DBDBDB01DCDCDC02D7D7D701D9D9D901AAAAAA01 + A8A8A801FFFFFF01A8A8A801D9D9D901D8D8D801D9D9D901DBDBDB01FEFEFE01 + DDDDDD01D8D8D801DBDBDB02D7D7D701DADADA01DBDBDB01DADADA03D9D9D901 + A7A7A701D9D9D901D8D8D801DBDBDB01D8D8D801DBDBDB01DADADA0FD9D9D902 + DADADA01DBDBDB02DDDDDD02DADADA02D8D8D802D9D9D901DEDEDE01DADADA01 + D8D8D801DBDBDB01DADADA22DCDCDC01D7D7D701D8D8D801DADADA01D7D7D701 + DCDCDC02D7D7D701DCDCDC01DADADA01DBDBDB01D6D6D601DDDDDD01A9A9A901 + A5A5A501DADADA01AAAAAA01A8A8A801DCDCDC01A7A7A701D8D8D801D9D9D901 + DCDCDC01D9D9D901DADADA01DDDDDD01DADADA01D2D2D201DEDEDE01FFFFFF01 + DEDEDE01DADADA01D8D8D801D9D9D901DDDDDD01D7D7D701DEDEDE01DADADA01 + ABABAB01A5A5A501DCDCDC01D7D7D701DCDCDC01DADADA01A8A8A801A9A9A901 + AAAAAA01D9D9D901D8D8D801DCDCDC01D8D8D801DADADA01FFFFFF02D9D9D901 + DADADA01D8D8D801DBDBDB02AAAAAA01D6D6D601AAAAAA01A6A6A601DDDDDD01 + DCDCDC01DBDBDB01DADADA01DCDCDC01D8D8D801DADADA02FFFFFF01DBDBDB01 + D9D9D901D8D8D801DBDBDB01DCDCDC01FEFEFE01DCDCDC01AAAAAA01D9D9D901 + DEDEDE01DBDBDB02D9D9D901DADADA0FDCDCDC01D8D8D801DADADA02D9D9D901 + DADADA01D9D9D902DADADA02DDDDDD01DCDCDC01D6D6D601DADADA01DBDBDB01 + D9D9D901DADADA20D9D9D901D8D8D801DCDCDC01DADADA01D9D9D901DEDEDE01 + DCDCDC01D8D8D801D9D9D901DCDCDC01D8D8D802DDDDDD01D9D9D901DADADA01 + D8D8D801ABABAB01DBDBDB01FCFCFC01DEDEDE01D7D7D701DADADA01DBDBDB01 + DCDCDC01D8D8D801DDDDDD01DCDCDC01D7D7D701DBDBDB01DEDEDE01D8D8D801 + D7D7D701D8D8D802DEDEDE01D9D9D901D8D8D801A9A9A901A7A7A701A8A8A801 + A5A5A501A9A9A901A7A7A701DBDBDB01DADADA01FFFFFF01A5A5A501A8A8A801 + A4A4A401A8A8A801ABABAB01DDDDDD01D7D7D701FFFFFF02FEFEFE01FDFDFD01 + FFFFFF01DCDCDC01D6D6D601DDDDDD01A7A7A701DCDCDC01A5A5A501AAAAAA01 + DADADA01D7D7D701D9D9D901DADADA01A5A5A501DBDBDB01DCDCDC01A7A7A701 + A8A8A801DADADA01DBDBDB02DDDDDD01D7D7D701FEFEFE01D6D6D601DBDBDB01 + DADADA01D7D7D701D9D9D901DBDBDB01DDDDDD01D9D9D901DADADA0EDBDBDB01 + D9D9D901DCDCDC01D9D9D901D7D7D701DADADA02DCDCDC01DBDBDB01D8D8D801 + D7D7D701DBDBDB01D8D8D801DDDDDD01D9D9D901DEDEDE01DADADA21DCDCDC01 + DADADA01D8D8D801DBDBDB01D8D8D801D4D4D401DADADA01D8D8D801DBDBDB02 + D9D9D901DADADA01FEFEFE01FFFFFF01DDDDDD01FDFDFD01FFFFFF01D9D9D901 + FCFCFC01DBDBDB01DDDDDD01D9D9D901D8D8D801DBDBDB01D8D8D801DADADA01 + DBDBDB01D9D9D902DADADA01DEDEDE01DBDBDB01DADADA01DCDCDC01D7D7D701 + DCDCDC01A8A8A801D9D9D902A7A7A701A9A9A901AAAAAA01D8D8D801FEFEFE01 + FFFFFF01DBDBDB01A7A7A701ABABAB01AAAAAA01D8D8D801A5A5A501DFDFDF01 + D9D9D901FEFEFE01FFFFFF02FDFDFD01DADADA01DDDDDD01A6A6A601D7D7D701 + E1E1E101A8A8A802A6A6A601A9A9A901ABABAB01A9A9A903D9D9D901AAAAAA01 + A6A6A601A8A8A801DCDCDC01DADADA01D8D8D801DADADA01FFFFFF01DCDCDC01 + D9D9D901DADADA01DDDDDD01D7D7D701D9D9D901D8D8D801DDDDDD01DADADA0E + D8D8D801DADADA01DCDCDC01D9D9D901DBDBDB01DFDFDF01D8D8D802D9D9D901 + A5A5A501ADADAD01D9D9D901DADADA01DBDBDB01D9D9D901D6D6D601DADADA20 + D9D9D901DADADA01D9D9D902DCDCDC01DEDEDE01DCDCDC01D9D9D901DCDCDC01 + DADADA02D9D9D901D8D8D801DADADA01FFFFFF01D7D7D701DCDCDC01FFFFFF01 + DADADA01DCDCDC01DADADA02D8D8D801DDDDDD01DCDCDC01D7D7D701DADADA01 + DBDBDB01D8D8D801D9D9D903DBDBDB01D8D8D801DBDBDB01FFFFFF01FEFEFE01 + FDFDFD01DADADA01DBDBDB01DDDDDD01A6A6A601A7A7A701DCDCDC01FEFEFE01 + FCFCFC01DBDBDB01DADADA01D9D9D901A4A4A401AAAAAA01A9A9A901D8D8D801 + DBDBDB01D9D9D901DBDBDB01FFFFFF02D8D8D801D9D9D901DADADA01DDDDDD01 + D5D5D501A7A7A701A8A8A801A9A9A901A4A4A401DBDBDB01A7A7A701A5A5A501 + FDFDFD01FFFFFF01A7A7A701ABABAB01D9D9D901D7D7D701DBDBDB01A9A9A901 + A7A7A701D7D7D701DADADA01DEDEDE01D7D7D702DEDEDE01DBDBDB01DADADA01 + D8D8D801DADADA10DBDBDB01D8D8D801DBDBDB01DADADA01D4D4D401DDDDDD01 + DCDCDC01D7D7D701DCDCDC01D9D9D902DDDDDD01DADADA22DDDDDD01D8D8D801 + DADADA01DDDDDD01D5D5D502DBDBDB02D7D7D701A7A7A701DEDEDE01D9D9D901 + DCDCDC01D9D9D902DBDBDB01D7D7D701DADADA02D8D8D802DCDCDC01D8D8D801 + DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DADADA01DBDBDB01D9D9D901 + DBDBDB01DADADA01DBDBDB01D8D8D801FFFFFF01FAFAFA01FFFFFF01FDFDFD01 + FFFFFF02D7D7D701DADADA01D9D9D901FFFFFF02DCDCDC01D8D8D801AAAAAA01 + DBDBDB01A8A8A801A5A5A501A9A9A901DADADA01D8D8D801DADADA01FCFCFC01 + FFFFFF02DCDCDC01DADADA01D6D6D601DDDDDD02D8D8D801DCDCDC02D8D8D801 + DBDBDB01DCDCDC01FFFFFF01FDFDFD01D9D9D901D7D7D701DCDCDC01DADADA01 + DBDBDB01D8D8D801DEDEDE01DBDBDB01DADADA01D9D9D901DCDCDC01DADADA02 + DBDBDB01D9D9D901DBDBDB01DADADA0EDBDBDB01D9D9D901DBDBDB01DADADA02 + D7D7D701DEDEDE01FEFEFE01FFFFFF01DBDBDB01D9D9D901DADADA01DCDCDC01 + D8D8D801DBDBDB02DADADA20D8D8D801DBDBDB01DADADA02DBDBDB03D9D9D901 + DADADA01DBDBDB01D9D9D901D8D8D801DADADA01DCDCDC01D9D9D901DBDBDB01 + DCDCDC01DADADA01D9D9D901DCDCDC01DADADA02D9D9D901DBDBDB01D7D7D701 + DCDCDC01DBDBDB01D7D7D701DBDBDB02D6D6D601DADADA01D8D8D801DCDCDC01 + DADADA01D8D8D801FFFFFF02FEFEFE01FFFFFF01FEFEFE01DCDCDC01DBDBDB01 + A8A8A801DBDBDB01D7D7D701DBDBDB02D7D7D701DDDDDD01A8A8A801A9A9A901 + A8A8A801D9D9D901DCDCDC01DBDBDB01FFFFFF01FEFEFE01FFFFFF02DADADA03 + D8D8D801DADADA03D9D9D901A9A9A901D9D9D901FFFFFF02DADADA01ABABAB01 + D9D9D901FDFDFD01FFFFFF01DBDBDB01D8D8D801A8A8A802DADADA01DCDCDC01 + DBDBDB01D9D9D901DADADA01DBDBDB01DADADA3FDBDBDB01D9D9D901DBDBDB01 + DADADA02D7D7D701DEDEDE01FEFEFE01DADADA08DBDBDB01D6D6D601DCDCDC01 + D9D9D901DADADA01D7D7D701DDDDDD01DADADA01A8A8A802D8D8D801DADADA01 + D9D9D901DDDDDD01D9D9D901A6A6A601DCDCDC01D9D9D901DBDBDB01D7D7D701 + DDDDDD01D9D9D901D7D7D701DCDCDC02DADADA02A6A6A601DBDBDB01DADADA02 + DBDBDB01DADADA02DBDBDB01AAAAAA01A5A5A501DADADA04FDFDFD01FFFFFF03 + DADADA01DBDBDB01D9D9D901DBDBDB01DADADA02A7A7A701DADADA01D8D8D801 + FFFFFF01DADADA01A7A7A701A9A9A901AAAAAA01A6A6A601A8A8A801AAAAAA01 + A5A5A501A9A9A901A7A7A701A9A9A901D9D9D901D8D8D801D9D9D901DBDBDB02 + D9D9D901DADADA40DBDBDB01D8D8D801DBDBDB01DADADA01D4D4D401DDDDDD01 + DADADA08D8D8D801DDDDDD01D9D9D901DCDCDC01D9D9D901DDDDDD01D8D8D801 + D9D9D901A9A9A902DBDBDB01D8D8D801A7A7A701A6A6A602ACACAC01D6D6D601 + DBDBDB01DDDDDD01D8D8D801D7D7D701DEDEDE01DBDBDB01D9D9D902FEFEFE01 + FFFFFF01FEFEFE01D9D9D901DADADA01D9D9D901D8D8D801FFFFFF01FDFDFD01 + D9D9D901A7A7A701A9A9A901ADADAD01A4A4A401D9D9D901DBDBDB01D9D9D901 + FFFFFF03DADADA01D6D6D601DBDBDB01DADADA03A5A5A501E0E0E001D8D8D801 + D7D7D701DBDBDB01A9A9A901A6A6A601AAAAAA01A8A8A801A6A6A601DBDBDB02 + AAAAAA01ABABAB01A1A1A101A9A9A901DFDFDF01D9D9D902DBDBDB01DADADA3F + D8D8D801DADADA01DCDCDC01D9D9D901DBDBDB01DFDFDF01D8D8D802DADADA08 + DBDBDB01D8D8D801DADADA01D8D8D801D7D7D701DBDBDB01FFFFFF02D9D9D901 + DBDBDB01D8D8D801DBDBDB01A8A8A801DBDBDB01A6A6A602DDDDDD01DBDBDB01 + DADADA01DDDDDD01DCDCDC01D6D6D601DCDCDC01D9D9D901A6A6A601FFFFFF01 + FEFEFE01FFFFFF01DCDCDC01DADADA01FEFEFE01FFFFFF01FEFEFE01FFFFFF02 + A5A5A501A8A8A801A9A9A902DDDDDD01DADADA02DBDBDB01FEFEFE01FDFDFD01 + FFFFFF01DDDDDD01D9D9D901D7D7D701DCDCDC01A8A8A801AAAAAA01A5A5A501 + DBDBDB01DADADA01D8D8D801DADADA01D9D9D903DCDCDC01D9D9D901DDDDDD01 + D6D6D601A5A5A501DEDEDE01A7A7A701DADADA01D9D9D901D7D7D701DDDDDD01 + D8D8D801DADADA3EDBDBDB01D9D9D901DCDCDC01D9D9D901D7D7D701DADADA02 + DCDCDC01DADADA08D8D8D801DBDBDB01DADADA01DEDEDE01DBDBDB01DADADA01 + FFFFFF02D9D9D902FFFFFF02DADADA01DCDCDC01A8A8A802D6D6D601DCDCDC01 + D8D8D801D7D7D701D9D9D901DDDDDD01D9D9D901DCDCDC01A8A8A801DCDCDC01 + FEFEFE02D9D9D902DBDBDB01DADADA01FFFFFF01FCFCFC02DEDEDE01DCDCDC01 + A7A7A701A8A8A801D7D7D701D8D8D801DCDCDC01D8D8D801FFFFFF03D3D3D301 + DEDEDE01DDDDDD01D7D7D701A9A9A901A5A5A501A8A8A801DCDCDC01D9D9D901 + DCDCDC01DADADA02DFDFDF01D9D9D901D7D7D701DADADA01D9D9D901DDDDDD01 + D9D9D901DCDCDC01D6D6D601AAAAAA01DCDCDC01DBDBDB02D9D9D901DADADA3E + DCDCDC01D8D8D801DADADA02D9D9D901DADADA01D9D9D902DADADA08DEDEDE01 + D7D7D701D8D8D801DBDBDB01D7D7D701DCDCDC01D7D7D701AAAAAA01A9A9A901 + A8A8A801FEFEFE01FFFFFF02D8D8D801A8A8A801A9A9A901DBDBDB01D9D9D901 + DEDEDE01DCDCDC02D9D9D901FFFFFF01D9D9D901DCDCDC01D8D8D801FFFFFF02 + A9A9A901ACACAC01A6A6A601D9D9D902FFFFFF01DBDBDB01DADADA01D5D5D501 + ABABAB01A9A9A901DCDCDC01DDDDDD01DBDBDB01D9D9D901A8A8A801DBDBDB01 + FFFFFF01DCDCDC01D8D8D802D9D9D901E0E0E001A7A7A701DBDBDB01D9D9D901 + DCDCDC01D6D6D601D9D9D901DADADA01D7D7D701DADADA01DDDDDD02D6D6D601 + ABABAB01FFFFFF01DADADA01DCDCDC01A4A4A401D9D9D901DBDBDB01D8D8D801 + DADADA3FD9D9D902DADADA01DBDBDB02DDDDDD02DADADA09D9D9D902DEDEDE01 + D8D8D801D9D9D901DCDCDC01D9D9D901DBDBDB01A9A9A901A6A6A601FFFFFF02 + FBFBFB01DBDBDB01AAAAAA01A4A4A401DBDBDB01D9D9D901D8D8D801DBDBDB01 + D7D7D701A9A9A901DCDCDC01DADADA01D8D8D801DEDEDE01FEFEFE01FFFFFF01 + A3A3A301A8A8A801A9A9A901DADADA02FFFFFF01D9D9D902DCDCDC01A8A8A801 + A6A6A601A8A8A801A5A5A501D7D7D701DCDCDC01DADADA01FCFCFC01FDFDFD01 + DCDCDC01D9D9D901DBDBDB02D5D5D501DBDBDB02D9D9D901DADADA01DCDCDC01 + DBDBDB01DADADA01DBDBDB01DADADA01D9D9D901DADADA01DCDCDC01A5A5A501 + D8D8D801FFFFFF01DADADA01DCDCDC01DBDBDB01DADADA01D9D9D901DADADA40 + DCDCDC01DBDBDB01D9D9D901D8D8D802DADADA01D9D9D901DADADA08D9D9D901 + DBDBDB01D7D7D701DBDBDB01DEDEDE01FEFEFE01FDFDFD01D9D9D901A6A6A601 + ACACAC01A4A4A401DADADA01FFFFFF01FDFDFD01ABABAB01D9D9D901D7D7D701 + DADADA01D9D9D901DFDFDF01D9D9D901D8D8D801DBDBDB01DADADA03FFFFFF01 + D6D6D601DCDCDC01AAAAAA01A4A4A401AAAAAA01DBDBDB01D5D5D501DDDDDD01 + DADADA01DBDBDB01AAAAAA01A7A7A701A8A8A801A9A9A901FFFFFF02A9A9A901 + D6D6D601DFDFDF01D7D7D701DCDCDC02D9D9D901DADADA01DDDDDD01DADADA01 + D9D9D901DBDBDB01D8D8D801DADADA02DBDBDB01D9D9D901D8D8D801DCDCDC01 + A6A6A601ABABAB01A9A9A901FDFDFD01DBDBDB01D8D8D801A7A7A701DCDCDC01 + DADADA01D8D8D801DADADA40D8D8D801DBDBDB01DCDCDC01D9D9D902DBDBDB01 + DADADA08DBDBDB02DADADA01DBDBDB01D8D8D801DADADA01FFFFFF01D9D9D901 + DCDCDC01A6A6A601A9A9A901FFFFFF03D6D6D601AAAAAA01DCDCDC01DADADA01 + D9D9D901FBFBFB01FFFFFF01D9D9D901DBDBDB01DADADA03FDFDFD01FFFFFF01 + FEFEFE01A6A6A601ACACAC01A7A7A701D9D9D901DEDEDE01D8D8D801D9D9D901 + DBDBDB01D9D9D901DADADA01DBDBDB01D8D8D801DBDBDB01D9D9D901DADADA01 + DBDBDB01D8D8D801DBDBDB01D9D9D901D8D8D801DBDBDB01D9D9D901D7D7D701 + DBDBDB01D8D8D801DCDCDC01DADADA01D9D9D901DCDCDC01D7D7D701DDDDDD01 + DADADA01D9D9D901AAAAAA01A8A8A802DBDBDB01D8D8D801DDDDDD01D7D7D701 + ABABAB01D7D7D701DCDCDC01DADADA46DCDCDC01D7D7D701DADADA01DDDDDD01 + DADADA02DBDBDB01D9D9D902DCDCDC01D9D9D901DDDDDD01DADADA01FEFEFE01 + D9D9D901FFFFFF02DCDCDC01A8A8A801A6A6A601FFFFFF01DBDBDB01A7A7A701 + A9A9A901AAAAAA01A8A8A801DBDBDB01D8D8D801DADADA01D9D9D901DCDCDC01 + D9D9D901D8D8D801FFFFFF04DADADA01D9D9D901DCDCDC01DBDBDB01DCDCDC01 + DADADA01D7D7D701DADADA01D9D9D901FFFFFF01DADADA01D9D9D901FFFFFF01 + FEFEFE01D9D9D901D8D8D801DADADA01DBDBDB01DADADA0EDCDCDC01FFFFFF01 + D8D8D801DDDDDD01D9D9D901FFFFFF01DADADA01DBDBDB01DADADA01A7A7A701 + DBDBDB01DADADA46D9D9D901DFDFDF01D8D8D801DADADA01D8D8D801A6A6A601 + AAAAAA01DBDBDB01DCDCDC01D8D8D801D9D9D903FFFFFF01A9A9A901FDFDFD01 + FEFEFE01AAAAAA01A7A7A701ADADAD01DADADA01FDFDFD01DDDDDD01A6A6A601 + A5A5A501A8A8A801D7D7D701D9D9D901DDDDDD01D9D9D901D6D6D601DBDBDB01 + D9D9D901E0E0E001D9D9D901FEFEFE01FFFFFF01DADADA02D8D8D801DBDBDB01 + D6D6D601FFFFFF03DBDBDB01D7D7D701D8D8D801DBDBDB01D7D7D701DADADA01 + DEDEDE01DADADA01DBDBDB02D7D7D701DADADA08DBDBDB01DCDCDC01D9D9D901 + DBDBDB01DADADA01FFFFFF02DEDEDE01D9D9D901DADADA01DBDBDB01FFFFFF01 + DBDBDB01D9D9D901DBDBDB01D8D8D801DADADA46D8D8D801DADADA03DBDBDB01 + DADADA01A9A9A901A7A7A701A6A6A601DDDDDD01DBDBDB01DADADA01FFFFFF01 + DADADA01A5A5A501FFFFFF02D8D8D801A7A7A701A8A8A801D8D8D801FFFFFF01 + FDFDFD01FFFFFF01A9A9A901A8A8A801DDDDDD01DFDFDF01DADADA01D7D7D701 + DBDBDB01DADADA01DBDBDB01D7D7D701DADADA02FEFEFE02DADADA01DCDCDC01 + DBDBDB01D9D9D901FFFFFF01FEFEFE01D8D8D801DDDDDD01DCDCDC01DBDBDB01 + D9D9D901FFFFFF01DCDCDC01D7D7D701DADADA01D6D6D601DBDBDB02DADADA08 + D9D9D901DBDBDB01DADADA01D9D9D901D8D8D801D9D9D901DCDCDC01D7D7D701 + D9D9D901DCDCDC01D9D9D901D8D8D801FEFEFE01DADADA01DDDDDD01DADADA47 + DCDCDC01D8D8D801D9D9D901FEFEFE01FFFFFF01DCDCDC01D8D8D801D9D9D901 + DCDCDC01D8D8D801D9D9D901DADADA01FEFEFE01DCDCDC01DADADA01FEFEFE01 + FCFCFC01DADADA01AAAAAA01A5A5A501AAAAAA01FFFFFF01FEFEFE02A7A7A701 + DCDCDC01D6D6D601D7D7D701D9D9D901DBDBDB01A9A9A901DADADA01D9D9D901 + DBDBDB02FFFFFF01FDFDFD01DDDDDD01DADADA01D8D8D801A6A6A601AAAAAA01 + D8D8D801DADADA01DBDBDB01D7D7D701D9D9D902FFFFFF02D9D9D901DCDCDC01 + DADADA01DBDBDB01DCDCDC01D8D8D801DADADA09DCDCDC01DADADA01DDDDDD01 + DADADA01DDDDDD01D7D7D701DDDDDD01DBDBDB02D8D8D801DDDDDD02DADADA02 + D7D7D701DADADA46D9D9D901DADADA01DCDCDC01A9A9A901FFFFFF01FCFCFC01 + FFFFFF01DCDCDC01D9D9D902DADADA01DEDEDE01FEFEFE01A6A6A601ACACAC01 + FFFFFF02DBDBDB01DADADA01A9A9A901A7A7A702FFFFFF01D9D9D901A6A6A601 + ABABAB01DADADA01DCDCDC01DDDDDD01D9D9D901DADADA01D9D9D901DADADA01 + FFFFFF01DADADA01D8D8D801FFFFFF01D7D7D701D6D6D601DFDFDF01A8A8A801 + A9A9A901D8D8D801A9A9A901DADADA01D9D9D901DADADA01DBDBDB01FEFEFE01 + FFFFFF01DDDDDD01D8D8D802DBDBDB02D9D9D901DADADA08DDDDDD01D7D7D701 + A8A8A801D7D7D701A9A9A901DCDCDC01D7D7D701DADADA01D8D8D801DCDCDC01 + DBDBDB01D9D9D901D5D5D501D9D9D901DBDBDB02DADADA46D9D9D901DDDDDD01 + D8D8D801A7A7A701DADADA01DCDCDC01D6D6D601D9D9D901DDDDDD01DBDBDB01 + D9D9D901D8D8D801D9D9D901A9A9A901A3A3A301FFFFFF01FCFCFC01DBDBDB01 + D6D6D601AAAAAA01A8A8A801A5A5A501FEFEFE01ADADAD01A9A9A902DCDCDC01 + D7D7D701FCFCFC01DBDBDB01DADADA02DBDBDB01DADADA01D8D8D801FFFFFF02 + DADADA01DFDFDF01D7D7D701A8A8A801A6A6A601DBDBDB01AAAAAA01DADADA01 + DBDBDB02D8D8D801FEFEFE01FFFFFF01D9D9D901DBDBDB01DEDEDE01D7D7D701 + DBDBDB01D9D9D901DADADA08D9D9D901A9A9A902D8D8D801A8A8A801D8D8D801 + DBDBDB01DCDCDC01DBDBDB01D7D7D701DCDCDC01D6D6D601DCDCDC01DEDEDE01 + D8D8D801DBDBDB01DADADA06 + } + container.face.fade_pos.count = 2 + container.face.fade_pos.items = ( + 0 + 1 + ) + container.face.fade_color.count = 2 + container.face.fade_color.items = ( + 15590106 + 11906751 + ) + container.face.localprops = [fal_faopacity] + container.taborder = 1 + container.bounds = ( + 0 + 30 + 638 + 256 + ) + optionswindow = [wo_groupleader] + mainmenu = mainmenu1 + options = [fo_main, fo_terminateonclose, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + caption = 'MSEide + MSEgui' + moduleclassname = 'tmseform' + object tstringedit1: tstringedit + color = -2147483645 + frame.leveli = 1 + frame.framewidth = 2 + frame.colorframe = -2147483645 + frame.colorclient = -2147483645 + frame.caption = 'Caption &topleft' + frame.font.color = 29539 + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_xscale] + frame.localprops = [frl_leveli, frl_framewidth, frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 107 + bounds_y = 39 + bounds_cy = 43 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit2: tstringedit + color = -2147483645 + frame.leveli = 1 + frame.framewidth = 2 + frame.colorframe = -2147483645 + frame.colorclient = -2147483645 + frame.caption = 'Caption &top' + frame.captionpos = cp_top + frame.font.color = 37241 + frame.font.style = [fs_bold] + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_style, flp_xscale] + frame.localprops = [frl_leveli, frl_framewidth, frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + face.fade_pos.count = 2 + face.fade_pos.items = ( + 0 + 1 + ) + face.fade_color.count = 2 + face.fade_color.items = ( + 12378329 + 10592767 + ) + face.fade_opacity = 6250335 + face.localprops = [fal_faopacity] + taborder = 1 + bounds_x = 262 + bounds_y = 39 + bounds_cy = 43 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit3: tstringedit + color = -2147483645 + frame.levelo = 3 + frame.leveli = -1 + frame.framewidth = 2 + frame.colorframe = -2147483645 + frame.colorclient = -2147483645 + frame.caption = 'Caption &left' + frame.captionpos = cp_left + frame.font.color = -1610612730 + frame.font.style = [fs_bold, fs_italic] + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_style, flp_xscale] + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 81 + 0 + 0 + 0 + ) + face.fade_pos.count = 2 + face.fade_pos.items = ( + 0 + 1 + ) + face.fade_color.count = 2 + face.fade_color.items = ( + -1610612730 + -1610612731 + ) + face.fade_direction = gd_up + face.fade_opacity = 8355711 + face.localprops = [fal_fadirection, fal_faopacity] + taborder = 3 + bounds_x = 23 + bounds_y = 112 + bounds_cx = 181 + bounds_cy = 32 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit4: tstringedit + color = -2147483645 + frame.levelo = 0 + frame.frameimage_list = imli + frame.frameimage_offset = 24 + frame.colorclient = -2147483645 + frame.caption = 'Caption &bottom' + frame.captionpos = cp_bottom + frame.font.color = 12419927 + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_xscale] + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_frameimagelist, frl_frameimageoffset, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 0 + 17 + ) + taborder = 6 + bounds_x = 261 + bounds_y = 177 + bounds_cy = 49 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit5: tstringedit + color = -2147483645 + frame.levelo = 3 + frame.leveli = -1 + frame.framewidth = 2 + frame.colorframe = -2147483645 + frame.colorclient = -2147483645 + frame.caption = 'Caption botto&mright' + frame.captionpos = cp_bottomright + frame.font.color = 8876645 + frame.font.colorbackground = 13418736 + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_colorbackground, flp_xscale] + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 28 + 0 + 0 + 17 + ) + taborder = 5 + bounds_x = 76 + bounds_y = 176 + bounds_cx = 128 + bounds_cy = 49 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit6: tstringedit + color = -2147483645 + frame.levelo = 0 + frame.frameimage_list = imli + frame.frameimage_offset = 8 + frame.colorclient = -2147483645 + frame.caption = 'Caption &right' + frame.captionpos = cp_right + frame.font.color = 11372216 + frame.font.style = [fs_italic] + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_style, flp_xscale] + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_frameimagelist, frl_frameimageoffset, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 84 + 0 + ) + face.fade_pos.count = 2 + face.fade_pos.items = ( + 0 + 1 + ) + face.fade_color.count = 2 + face.fade_color.items = ( + -1610612730 + -1610612731 + ) + face.fade_direction = gd_up + face.fade_opacity = 8355711 + face.localprops = [fal_fadirection, fal_faopacity] + taborder = 4 + bounds_x = 261 + bounds_y = 113 + bounds_cx = 184 + bounds_cy = 32 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit7: tstringedit + color = -2147483645 + frame.levelo = -1 + frame.leveli = 1 + frame.framewidth = 2 + frame.colorframe = -2147483645 + frame.framei_left = 4 + frame.framei_right = 4 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_colorframe, frl_fileft, frl_firight, frl_colorclient] + frame.localprops1 = [] + face.options = [fao_alphafadeimage] + face.image.transparentcolor = -2147483642 + face.image.options = [bmo_masked] + face.image.alignment = [al_xcentered, al_ycentered, al_tiled] + face.image.image = { + 000000000200000064000000640000009C580000000000000000000000000000 + 0000000000000000000000000000000000000000AAD5BA01CFEDC901D4EDD901 + DBFBE801F3FEF41F63AD8C01637F6001CFEDC9013F6A49013693630108744201 + 57A07401BEE1C301E6EDDB01BCB7A4019C927401837654017A6D440272663C03 + 7A6D440272663C017A6D440172663C037A6D440172663C017C724C02887D5801 + 948B6D01A1987D01A49E84018376540140604201F3FEF407BEE1C301A9C3A101 + 7C724C01293916013E4C360151583F0158583401444D28012D3E1B018E937301 + B4DAC401F3FEF40BD2FADA01CFEDC90138543302153A1B0144886C017AC6A401 + BEF6DC01F3FEF402B6F5E401F3FEF41ABEF6DC014060420178A8840195D1AB01 + 33805501257C4C015BA47F01C1DCCC01E1E4D601B7B09C01908664017A6D4401 + 72663C0D7A6D44017C724C01887D5801948B6D01A49E8401B7B09C01A9A78401 + 50664C017EAA8E01F3FEF405B6F5E40163AD8C01153A1B015F754C0183B19401 + B3ECD501DBFBE801BCEACC01BEF6DC01DCFEF401BFD8B90178957401304B3401 + 64967001B6F5E401F3FEF404B6F5E401F3FEF401B3ECD50192C2A501637F6001 + 1F402401153A1B01BEF6DC01BAFEEF01B0E2C20178B08B01566C540129391601 + 78A88401BCEACC01F3FEF41CB0E2C201153A1B01A9C3A101AAD5BA0178A88401 + 96B99E01C7E4D101DCE2C301ACAE8A01888264017A6D44016B60340672663C06 + 7A6D44017C724C01887D5801948B6D01A9A78401BCB7A4028E9373012D3E1B01 + B3ECD501F3FEF404B0E2C20140604201566C54019AD5BA0194E6C4011E8F7601 + 0F8264011EAC8E0127BAA7011EAC8E01088C5D011881560195D1AB01BCEACC01 + 637F6001566C5401BEF6DC01F3FEF404A6CBAC012E492A015061410178957401 + A9C3A101B0E2C20126A28E01249772011C7A640144886C019DCCB401BCEACC01 + 44886C011F4024017BB79301B6F5E401F3FEF419B6F5E401F3FEF4019AD5BA01 + 2E492A0196B99E01F0FBEB01C7E4D101F0FBEB01CCCBBC01A1987D0183765401 + 6B603401655729056B60340472663C027A6D44017C724C01887D580190866401 + A9A78401B7B09C01C9C5B401B7B09C0172663C017CA08001F3FEF403B6F5E401 + AAD5BA01153A1B0179977E01D2FADA012281740158BC9C0152E1E0012CCAB401 + 0ACACA010DD7D00128E2CF0140EEC8012BCA9901257C4C017EAA8E01F0FBEB01 + 637F6002BEF6DC02F3FEF40196B99E012D3E1B018E937301CFEDC901AAD5BA01 + 7CA08001338055012BEEDF0112E2D0012CD4D1014CD6DC022281740158BC9C01 + B3ECD5014473580150664C01B0E2C201F3FEF41B9AD5BA01293916018E937301 + C6CCAA01D5D3C301AFA68F019086640172663C01574E2402584B1A0265572904 + 6B60340272663C017A6D44017C724C0183765401948B6D01A49E8401BCB7A401 + C9C5B401C4BFAB0190866401153A1B01BCFAD301F3FEF4039AD5BA0129391601 + 83B194017CD6B401148874014CD6DC010CB1CF01049FC40104A8C30107BFCB01 + 0ACACA011DEDD00128ECC10112C39501088C5D01488A5C01B4DAC401A8C5AC01 + 444D280185B79D01D2FADA01A6CBAC0129391601788B6D01E8F8DB0192C09B01 + 338055010B9664012BCA990129F7DE010DD7D00107BFCB0109B0C20104A8C301 + 0CB1CF0152E1E001228174018CCAB80185B79D012E492A0185B79D01F3FEF41B + B0E2C20150664C013E563C01887D580272663C01584B1A0145411501413C0C01 + 45411503584B1A02655729026B60340172663C02887D580190866401A49E8401 + B7B09C01C6CCAA01C4BFAB018E9373012E492A019AD5BA01F3FEF402B6F5E401 + BCEACC012E492A0178A8840198C9AB0126A28E012CD4D10104A8C301049FC401 + 0CB1CF021CD8DC012BEEDF0124E1B70110B58C01088C5D011881560163AD8C01 + C7E4D101C6CCAA017A6D4401385433017CA080015F754C0158583401ABB09401 + F0FBEB017BB793011881560106976D012BCA99011AD8B60129F7DE010DD7D001 + 0CB1CF01049FC401048DBF022CAACC014CD6DC0122817401BAFEEF0150664C01 + 68967C01BEF6DC01F3FEF41B98C9AB01447358011F40240129391601444D2801 + 545429015061410165572901413C0C0245411501584B1A02655729016B603401 + 72663C017C724C0190866401A1987D01B7B09C01C4BFAB01BCB7A401A1987D01 + 444D280196B99E01F3FEF4047CA0800157745601BCFAD301148874014CD6DC01 + 04A8C3020CB1CF0111CBD70124E4DE0112E2D00116C7A40109A06D0108744201 + 3693630178B08B01C1DCCC01E8F8DB01ABB094017A6D440145411501584B1A01 + 454115016B603401AFA68F01F0FBEB0195D1AB0146986E010874420122A47101 + 09A06D0114CB9A012BEEDF011CD8DC0113BDD7010797C701048DBF010482BC01 + 049AB40138CEDC0122817401B3ECD50144886C01637F6001B6F5E401F3FEF41B + BCFAD301BCEACC0195D1AB01A6CBAC0192C09B0178A88401789574016A8A6401 + 6B60340145411501413C0C0145411501655729027A6D4401887D58019C927401 + ACAE8A01BCB7A401ABB09401948B6D012E492A017BB79301F3FEF404B3ECD501 + 153A1B01BFD8B9010F82640148EDD40107BFCB0109B0C20113BDD7011CD8DC01 + 2BEEDF0115D5AC010BB18201088C5D010B7D4A01499F730192C2A501BCEACC01 + F0FBEB01C9C5B401948B6D0172663C01584B1A01413C0C01584B1A0172663C01 + A1987D01D5D3C301DBFBE80192C2A501499F7301087442010B7D4A01088C5D01 + 12BD92012BE3C40124E4DE0111CBD7010CB1CF010797C701048DBF0234C2D401 + 26A28E0194D6C401488A5C01668B6E01F3FEF401B6F5E401F3FEF41EBCFAD301 + 94E6C40198C9AB017EAA8E01637F60016B603401413C0C014541150165572901 + 7A6D4401888264019C927401A9A784019C9274017C724C012939160198C9AB01 + F3FEF4057BB7930157745601B0E2C2011EAC8E0128E2CF010ACACA010DD7D001 + 2BEEDF0112E2D00112BD920106976D01087442013693630163AD8C0195D1AB01 + D4EDD901E1EFE401CCCBBC01AFA68F01887D580172663C01574E2401584B1A01 + 655729017A6D4401948B6D01BCB7A401E6EDDB01D4EDD90192C2A50164967001 + 5FAB82010C8853010B7D4A010BB1820115D5AC012BEEDF011CD8DC0113BDD701 + 04A8C301049AB40104A8C30124CBC90126A28E019CEDC9015F754C017BB79301 + F3FEF4229CEDC90198C9AB0178A884015F754C0129391601444D28016B603401 + 7C724C0157745601566C48012E492A01637F6001BCEACC01F3FEF404BEF6DC01 + F3FEF401447358017EAA8E0163AD8C012BCCA8011DEDD00112E2D0012BEEDF01 + 15D5AC010AA67D010C885302499F730180BF9B01AAD5BA01E1EFE401EDF0E501 + CCCBBC01ABB09401948B6D01837654016B603402574E24016B60340172663C01 + 90866401A9A78401D5D3C301F0FBEB01C7E4D10192C2A50198C9AB015FAB8201 + 22895F010874420109A06D0112BD920110D6C40129F7DE011CD8DC0111CBD701 + 07BFCB0248EDD40112734C01BAFEEF011F402401B3ECD501F3FEF424B0E2C201 + 7EAA8E015F754C012E492A011F4024013854330168967C019AD5BA01F3FEF407 + BEF6DC011F402401A6CBAC013C8D64012BCCA8012BF9D20124E1B70112C39501 + 06976D010B7D4A01369363015FAB82019DCCB401C7E4D101DBFBE801EDF0E501 + CCCBBC01B7B09C018C987E01888264017A6D440172663C016B6034037A6D4401 + 887D5801A49E8401BCB7A401DBDACE01F3FEF401E1E4D601C7E4D1019DCCB401 + 63AD8C0146986E010B7D4A011179560109A06D0112BD92011AD8B6012BEEDF01 + 24E4DE0112E2D0012EEDD10128C4A40163AD8C017EAA8E0168967C01F3FEF401 + B6F5E401F3FEF425BCFAD302D2FADA01F3FEF409BEF6DC01153A1B01BFD8B901 + 3C8D640124B5920112BD920110A974010B7D4A01188156015BA47F0185B79D01 + B4DAC401D4EDD901F3FEF401DBDACE01C9C5B401B7B09C01A1987D0190866401 + 837654017A6D440172663C047C724C01887D5801948B6D01AFA68F01C9C5B401 + E1E4D601F3FEF402D4EDD901B1CCB90192C2A5015BA47F01369363010B7D4A01 + 0874420109A06D010BB1820114CB9A0124E1B7012BE3C4012ED3A40112734C01 + D2FADA011F402401BCFAD301F3FEF432BCFAD3012E492A01A8C5AC015BA47F01 + 257C4C010C8853010B7D4A0146986E017BB79301AAD5BA01D4EDD901F3FEF401 + E6EDDB01D5D3C301C2BAAC01AFA68F01A1987D0190866401887D580183765401 + 7A6D440272663C017A6D440283765401887D580190866401A49E8401ABB09401 + CCCBBC01E1E4D601DBDACE01F0FBEB02C1DCCC01AAD5BA0180BF9B015FAB8201 + 46986E01188156010B7D4A01117956010B96640109A06D012497720112734C01 + CFEDC90140604201B0E2C201F3FEF433637F600178957401BFD8B90146986E02 + 78B08B01AAD5BA01C7E4D101F3FEF401E1EFE401D5D3C301C9C5B401B7B09C01 + A49E84019C92740190866401887D58027C724C017A6D4406887D580190866401 + 9C927401A49E8401B7B09C01C9C5B401CCCBBC01DBDACE01EDF0E501F3FEF401 + E6EDDB01C1DCCC01AAD5BA0198C9AB0185B79D0163AD8C0146986E0142916E01 + 22895F013380550168967C01D2FADA0157745601A6CBAC01F3FEF4338CCAB801 + 50614101C7E4D101BEE1C301C0D8C401D2FADA01F0FBEB01D4EDD901D5D3C301 + C4BFAB01B7B09C01AFA68F01A1987D0190866402887D5801837654027C724C01 + 7A6D44017C724C017A6D44017C724C0283765402887D5801948B6D019C927401 + A9A78401B7B09C02C2BAAC01CCCBBC01E1E4D601EDF0E501F3FEF402D4EDD902 + BEE1C301AAD5BA01A6CBAC0198C9AB02BFD8B901D4EDD9013F6A4901AAD5BA01 + F3FEF433BEF6DC013F6A490188826401C6CCAA01BFD8B901CCCBBC01BCB7A401 + B7B09C01A49E8401A1987D019C927401948B6D019086640188826401887D5802 + 7C724C09887D580288826401948B6D019C927401A49E8402AFA68F01B7B09C01 + C4BFAB01CCCBBC01D5D3C301E1E4D601E6EDDB02F0FBEB01F3FEF401F0FBEB01 + F3FEF401F0FBEB01DCE2C301A49E84012E492A01BCEACC01F3FEF434B0E2C201 + 2D3E1B0150664C01887D5801888264019086640288826402887D580283765401 + 7C724C01837654017C724C057A6D44017C724C0183765401887D58017A6D4401 + 887D58017C724C01887D580190866401948B6D019C927403A49E8401AFA68F02 + BCB7A402C2BAAC01C9C5B404BCB7A401B7B09C01948B6D0150664C01566C4801 + F3FEF436B0E2C20157745601413C0C01545429016B60340172663C027A6D4401 + 7C724C057A6D44017C724C027A6D4401887D5801837654017C724C0183765401 + 7C724C0183765401887D580490866401948B6D0190866401948B6D029C927401 + A1987D01A49E8402AFA68F02A49E8402A1987D01948B6D01887D58016B603401 + 4541150178B08B01BEF6DC01F3FEF436B0E2C201668B6E0145411501413C0C01 + 655729016B60340172663C027A6D44037C724C02837654017C724C01887D5801 + 7A6D4401837654017C724C02887D580183765403887D580388826401887D5801 + 88826402948B6D0490866401948B6D0290866401887D58017C724C016B603401 + 584B1A015454290192C09B01F3FEF436B6F5E401F3FEF40198C9AB015F754C01 + 413C0C01584B1A01655729016B60340172663C017A6D44027C724C017A6D4401 + 7C724C02887D5801837654027A6D4401887D58027C724C01887D580183765402 + 7C724C01887D580183765401887D580183765401887D580688826401887D5801 + 7C724C0272663C016B60340165572901454115016B6034017BB79301F3FEF438 + 9CEDC9018E937301584B1A0145411501655729026B60340172663C017A6D4402 + 7C724C03837654017C724C0183765401887D580183765403887D58017A6D4401 + 887D580183765402887D580283765402887D58017C724C01887D58017C724C01 + 887D5801837654017C724C017A6D440365572902413C0C01545429017CA08001 + BCEACC01F3FEF41BB6F5E401F3FEF41BBEF6DC0178B08B015454290145411501 + 574E2401655729016B60340172663C017A6D44027C724C02837654017C724C01 + 83765401887D58017C724C01887D580183765401887D58017C724C01887D5802 + 837654067C724C01837654017C724C047A6D44017C724C017A6D44016B603401 + 65572901574E2401413C0C01454115016A8A640198C9AB01F3FEF43883B19401 + 566C4801413C0C01584B1A016557290172663C027A6D44027C724C0283765402 + 887D58017C724C0183765404887D5801837654017C724C0183765402887D5801 + 7C724C01837654017C724C01837654017C724C01887D58017C724C037A6D4402 + 72663C016B603402574E2401584B1A01413C0C015F754C0178B08B01B6F5E401 + F3FEF43792C09B01566C4801413C0C01584B1A01655729016B60340172663C01 + 7A6D44017C724C01887D580183765401887D580183765402887D580388826401 + 83765401887D580183765401887D5802837654047C724C01837654017C724C05 + 7A6D440272663C016B60340165572901574E2401584B1A01413C0C0154542901 + 7CA08001ADE2CE01A4EAD401F3FEF43698C9AB015F754C01413C0C01584B1A01 + 6557290172663C017A6D44017C724C01887D580183765401887D580288826402 + 887D580683765401887D58017C724C01887D58017C724C01887D58017C724C01 + 887D58017C724C047A6D44017C724C017A6D440272663C0265572902584B1A01 + 413C0C01545429016A8A64019AD5BA01F3FEF40DBEF6DC01B6F5E401BEF6DC01 + F3FEF42795D1AB015F754C01413C0C016557290172663C017C724C0183765401 + 887D580188826401948B6D019086640188826401948B6D0188826401948B6D02 + 887D58019086640188826401887D580283765402887D5801837654017C724C01 + 837654017C724C02837654017C724C017A6D44017C724C017A6D440172663C03 + 6B60340165572902584B1A01413C0C0147491B016496700198C9AB01F3FEF409 + B6F5E401BEF6DC01AAD5BA0178A884015F754C015858340138543301566C4801 + 7CA08001AAD5BA01BEF6DC01F3FEF423A9C3A10147491B01574E240172663C01 + 7C724C0188826401948B6D019C927402A1987D01A49E8401A1987D01A49E8401 + A1987D029C927401948B6D0288826402887D580383765401887D58017C724C04 + 7A6D44017C724C017A6D440472663C026B60340165572901584B1A02413C0C01 + 54542901789574019AD5BA01F3FEF408B6F5E40198C9AB01385433026A8A6401 + 78B08B01A9C3A10192C09B01A9A784016A8A64013854330144735801B0E2C201 + B6F5E401F3FEF41FB6F5E401F3FEF40183B194012D3E1B0150664C0190866401 + A1987D01AFA68F02BCB7A402B7B09C01BCB7A401B7B09C02AFA68F02A49E8401 + A1987D02948B6D03887D5801837654027C724C037A6D44017C724C037A6D4403 + 72663C026B60340265572901584B1A0145411501413C0C017A6D440178A88401 + A4EAD401F3FEF406B6F5E401BCEACC01637F60014060420183B19401DBFBE801 + 8FE0B70178B08B0157A074015FAB820192C09B01B0E2C201E8F8DB01788B6D01 + 1F402401A6CBAC01F3FEF42183B1940154542901948B6D01C4BFAB01D5D3C301 + DCE2C301E1E4D601DBDACE01DCE2C301E1E4D601DBDACE02CCCBBC02C9C5B401 + BCB7A401B7B09C019DA58D01A49E84019C9274018882640190866401887D5802 + 7C724C01837654017C724C017A6D44017C724C017A6D440572663C016B603402 + 65572901584B1A02413C0C0154542901668B6E0198C9AB01F3FEF406B6F5E401 + A4EAD40140604201637F6001CFEDC90192C09B01257C4C011E88540122A47102 + 16945B010F6D420144886C01A9C3A101F0FBEB01A49E8401153A1B01B0E2C201 + F3FEF42092C09B0138543301BCB7A401F0FBEB01E6EDDB01C7E4D102D4EDD902 + DBFBE801F3FEF402F0FBEB01E1EFE401DBDACE02CCCBBC01C2BAAC01AFA68F01 + A49E8401A1987D019086640188826401887D58017C724C037A6D44017C724C01 + 7A6D440372663C036B60340265572901584B1A01413C0C025F754C0178B08B01 + A4EAD401B6F5E401F3FEF405BEF6DC01637F6002DBFBE80157A074010C885301 + 23B07E0120BC920120B7800123B07E0116945B010F6D4201488A5C017BB79301 + D4EDD901C9C5B40150664C0178957401B6F5E401F3FEF41FB0E2C2012E492A01 + BCB7A401D4EDD9017BB7930178A884015FAB820161B88F017BB793017AC6A401 + 95D1AB01AAD5BA01C7E4D101D4EDD901F3FEF401F0FBEB01E1E4D601D5D3C301 + C9C5B401B7B09C01AFA68F019C92740190866401887D5801837654017C724C01 + 7A6D44057C724C0172663C017A6D440172663C016B603402574E2401584B1A01 + 413C0C0154542901789574019AD5BA01F3FEF40792C2A5013E563C01CFEDC901 + 78B08B010B7D4A0123B07E0120B7800110A974010B9664010B7D4A0246986E01 + 7BB79301AAD5BA01F3FEF401C4BFAB017C724C0140604201BEF6DC01F3FEF420 + 44735801788B6D01E8F8DB0157A074010F6D4201087442021881560122895F01 + 499F73015BA47F017BB7930198C9AB01B4DAC401C7E4D101F0FBEB01F3FEF401 + E1E4D601CCCBBC01BCB7A401AFA68F019C92740190866401887D580183765401 + 7C724C037A6D44017C724C027A6D44017C724C0172663C026B60340165572901 + 47491B01413C0C015F754C0192C2A501BEF6DC01F3FEF406BEF6DC01566C5401 + 8E937301B0E2C201338055011E8854010C885302087442011E885401499F7301 + 78B08B0198C9AB01C7E4D101F3FEF401D5D3C301A49E84016B60340154542901 + 9AD5BA01F3FEF4209AD5BA012E492A01C6CCAA0180BF9B0112734C0122A47101 + 23B07E0110A974010B9664010B7D4A021E885401499F73015FAB820180BF9B01 + AAD5BA01BCEACC01F3FEF401E6EDDB01D5D3C301BCB7A401AFA68F019C927401 + 887D580183765401887D5801837654017C724C01837654067C724C017A6D4401 + 6B603401584B1A01413C0C01649670019CEDC901F3FEF407B3ECD5012D3E1B01 + C6CCAA01A9C3A10133885A01257C4C011E885401369363015BA47F0180BF9B01 + A6CBAC01C7E4D101DBFBE801EDF0E501CCCBBC01AFA68F019086640165572901 + 444D280192C2A501F3FEF4217EAA8E013F6A4901D2FADA0146986E0120A98001 + 2ED3A40124E1B70115D5AC0112C395010BB182010B9664010B7D4A02499F7301 + 5FAB820192C09B01BFD8B901DBFBE801F0FBEB01DBDACE01BCB7A401A49E8401 + 948B6D018882640190866405948B6D029C927401948B6D019086640183765401 + 72663C01574E240147491B0192C2A501F3FEF4089AD5BA013E4C3601DCE2C301 + B1CCB9017CA0800183B194017BB7930198C9AB01C1DCCC01E1EFE401F0FBEB01 + DBFBE801DBDACE01C2BAAC019DA58D01948B6D017A6D4401574E2401413C0C01 + 6A8A6401B0E2C201F3FEF42178957401566C5401DBFBE8013693630123B07E01 + 40EEC8012BF9D20228ECC10115D5AC010BB1820109A06D010B7D4A0246986E01 + 61B88F01A6CBAC01C7E4D101F3FEF401DBDACE01C2BAAC01A49E84019C927401 + A49E8404B7B09C01AFA68F01B7B09C02ACAE8A01A9A78401A1987D01887D5801 + 444D2801637F6001BCFAD301F3FEF408AAD5BA01444D2801C6CCAA01E8F8DB01 + BEE1C301D4EDD901E8F8DB01F3FEF401EDF0E501DCE2C301D5D3C301C4BFAB01 + B7B09C01A49E84019C927401887D580172663C01655729014541150154542901 + 7CA08001AAD5BA01F3FEF401B6F5E401F3FEF41F7EAA8E0140604201B0E2C201 + 63AD8C0106976D012BE3C40140EEC8011DEDD0012BF9D20128ECC1011CD5A201 + 20B780010B9664010874420133885A0157A0740192C2A501C1DCCC01F3FEF401 + DBDACE01C4BFAB01AFA68F01C2BAAC01C4BFAB01C2BAAC01C9C5B401CCCBBC01 + D5D3C301DBDACE01D5D3C302C9C5B401A9A784017C724C01293916019AD5BA01 + F3FEF409A4EAD4012E492A01A1987D01BFD8B901E1E4D601DBDACE01D5D3C301 + C9C5B401C4BFAB01BCB7A401AFA68F01A49E84019C927401948B6D01887D5801 + 7C724C0172663C0165572901574E24014541150147491B01637F600192C09B01 + F3FEF420BEF6DC0183B1940147491B0178B08B01BCEACC0122895F011EAC8E01 + 40EEC8013FF9D2012BF9D20128ECC10124E1B70112C3950110A974010C885301 + 257C4C0157A0740196B99E01C1DCCC01F3FEF401DBDACE01C4BFAB01DCE2C301 + D5D3C301E1E4D602EDF0E502F0FBEB01EDF0E501DBDACE01BCB7A401637F6001 + 2939160198C9AB01F3FEF40ABEF6DC01444D28017A6D44018E937301A49E8403 + A1987D02948B6D029086640188826401837654017C724C017A6D440172663C01 + 6B60340165572901574E240245411501444D28017BB79301F3FEF401B6F5E401 + F3FEF419B6F5E401F3FEF401B6F5E401B0E2C20192C2A5017CA0800150614101 + 574E2401788B6D01ADE2CE017CD6B4011488740106976D0110B58C0116C7A401 + 2BCCA80112C3950123B07E0133885A0112734C01488A5C0183B19401DCE2C301 + F3FEF401DBDACE01CCCBBC01B7B09C01BCB7A401CCCBBC01DCE2C301E1E4D602 + DBDACE01C4BFAB01A1987D01506141013E563C01B0E2C201F3FEF40C78957401 + 47491B016B6034017A6D4401887D580488826401887D580183765401887D5801 + 7C724C027A6D440372663C027A6D440172663C0151583F0129391601C7E4D101 + F3FEF419BCFAD301A6CBAC016A8A6401293916013E4C3601566C4801637F6001 + 8E93730179977E017CA08001ABB09401A8C5AC01C7E4D101DCFEF401B0E2C201 + 85B79D015BA47F0146986E01649670015BA47F0192C09B01BEE1C301F0FBEB01 + DBDACE01ABB09401A1987D019C9274012D3E1B013E4C360151583F01566C5402 + 50664C0151583F012D3E1B01566C480195D1AB01D2FADA01F3FEF40D92C09B01 + 47491B0145411501655729016B60340172663C017A6D44017C724C067A6D4401 + 7C724C017A6D440183765402887D5801948B6D019C9274018E93730150614101 + 7BB79301F3FEF414B6F5E401F3FEF402B3ECD50178B08B011F40240140604201 + 78957401AAD5BA01DBFBE801B0E2C2017AC6A4017BB7930292C2A501B0E2C201 + DBFBE801C7E4D101B7B09C018E9373016A8A64018E9373017CA080027EAA8E01 + 668B6E015774560151583F012D3D2501444D2801566C480150664C01BEF6DC01 + A4EAD4019AD5BA018CCAB8019DCCB40198C9AB01ADE2CE01B6F5E401F3FEF410 + 95D1AB015F754C01413C0C01584B1A016557290272663C017A6D44017C724C01 + 7A6D44017C724C017A6D44017C724C017A6D44017C724C0183765401887D5801 + 88826401A1987D01B7B09C01C9C5B401C4BFAB0190866401637F6001F3FEF415 + BEF6DC0183B19401293916015774560192C2A501BAFEEF0158BC9C0111795601 + 06976D011EAC8E0116C7A4012BCCA80112BD920122A471010B7D4A0133885A01 + 92C09B01F0FBEB01ABB0940158583401566C480178A8840178B08B0183B19401 + 8CCAB8019AD5BA01A4EAD401B6F5E401F3FEF41B98C9AB01637F6001413C0C01 + 584B1A026B60340272663C017A6D44037C724C017A6D44017C724C0183765401 + 887D580188826401A49E8401B7B09C01D5D3C301EDF0E501E6EDDB018C987E01 + 50664C01F3FEF413BEF6DC019DCCB401385433014473580192C09B01A4EAD401 + 44886C011E8F760130D6BA0148EDD4012BE3C4011DEDD0022BF9D20128ECC101 + 14CB9A0122A471010874420142916E01A8C5AC01E8F8DB01948B6D0129391601 + BEE1C301F3FEF42198C9AB015F754C01413C0C02655729026B60340172663C03 + 7A6D44027C724C0283765401948B6D019C927401B7B09C01D5D3C301F0FBEB01 + EDF0E501F3FEF401A9A7840157745601BEF6DC01F3FEF411BCEACC017CA08001 + 2E492A0183B19401BCFAD301249E840247EFDC012CD4D1010ACACA020DD7D001 + 12E2D0012BF9D2012BE3C40114CB9A0110A974010B7D4A011881560178A88401 + AAD5BA01F0FBEB01A9A784015454290164967001DBFBE801F3FEF409B6F5E401 + F3FEF41680BF9B015F754C01413C0C01584B1A02655729016B60340272663C01 + 7A6D440172663C017A6D440283765401887D58019C927401AFA68F01CCCBBC01 + E1EFE402D5D3C301DBFBE801788B6D017CA08001F3FEF40EBEF6DC01F3FEF401 + B6F5E40198C9AB011F40240157745601BCEACC0180BF9B010F82640150DCD001 + 2CD4D1010ACACA0107BFCB0111CBD7011CD8DC012BEEDF011DEDD00115D5AC01 + 0BB18201088C5D010874420146986E017BB79301AAD5BA01F0FBEB01CCCBBC01 + 8E9373016B60340150614101A6CBAC01F3FEF401B6F5E401F3FEF404BEF6DC01 + F3FEF4017BB79301BCEACC01F3FEF41692C09B015F754C01413C0C01584B1A01 + 655729026B60340272663C027A6D44038376540190866401A1987D01BCB7A401 + DBDACE01F0FBEB01C0D8C401AFC6B701F0FBEB0150664C01AAD5BA01F3FEF40F + BCEACC0179977E012E492A0183B19401BEF6DC011488740124B5920152E1E001 + 0ACACA0107BFCB010ACACA010DD7D00124E4DE012BF9D20115D5AC010BB18201 + 0B9664010874420122895F015FAB820198C9AB01BCEACC01F0FBEB01D5D3C301 + AFA68F018882640154542901413C0C016A8A640192C09B0195D1AB01BEE1C301 + A6CBAC017CA08001637F6001577456018C987E015F754C01153A1B0196B99E01 + F3FEF414BEF6DC019AD5BA01637F6001413C0C02574E2401655729026B603402 + 72663C027A6D44017C724C01887D580190866401AFA68F01C9C5B401F0FBEB01 + C7E4D101AFC6B701D5D3C301AFC6B70129391601F3FEF40EB3ECD50183B19401 + 153A1B0157745601B0E2C2017AC6A4011179560144DABF0112E2D0010ACACA01 + 11CBD70224E4DE012BEEDF011AD8B60110B58C0106976D010874420122895F01 + 57A0740180BF9B01BFD8B901DBFBE801EDF0E501CCCBBC01ABB09401948B6D01 + 7A6D440165572901413C0C01584B1A015F754C016A8A6401566C480129391601 + 385433018376540190866401637F6001F0FBEB01A6CBAC01406042017CA08001 + F3FEF4149AD5BA01649670015454290145411501584B1A02655729016B603403 + 72663C027C724C01837654019C927401B7B09C01DBDACE01F0FBEB01CCCBBC01 + B1CCB901F3FEF401637F600185B79D01B6F5E401F3FEF40BBEE1C30196B99E01 + 2D3E1B0150664C017BB79301BCFAD301249772011EAC8E012BEEDF010DD7D001 + 0ACACA010DD7D00112E2D00129F7DE011AD8B60112C3950109A06D010B7D4A01 + 0C885301499F730178B08B019DCCB401D4EDD901F3FEF401E1E4D601C9C5B401 + AFA68F019C9274017C724C0172663C0165572901584B1A01413C0C0345411501 + 6B603401948B6D01A8C5AC01F0FBEB01F3FEF40146986E017BB79301E8F8DB01 + 3F6A49017CA08001F3FEF413A4EAD4017BB793015F754C0145411501413C0C01 + 584B1A02655729026B60340272663C017A6D4401887D5801A49E8401BCB7A401 + E6EDDB01EDF0E501C1DCCC01D4EDD901ABB094012E492A01F3FEF40ABEF6DC01 + AAD5BA0178957401153A1B01566C480178B08B01DBFBE80161B88F0111795601 + 2BCCA8011DEDD00112E2D0010DD7D00112E2D00129F7DE012BE3C40114CB9A01 + 10A974010C8853010B7D4A0146986E015FAB820192C2A501C1DCCC01F0FBEB02 + D5D3C301C2BAAC01A9A78401948B6D01887D58017A6D440172663C0165572901 + 574E2401584B1A02574E2401655729017C724C01A49E8401DBDACE01C7E4D101 + 96B99E0108744201257C4C0136936301DBFBE80150664C0196B99E01F3FEF413 + 9AD5BA017CA08001566C4801413C0C014541150147491B01584B1A0165572901 + 584B1A01655729016B60340172663C01887D5801A1987D01C9C5B401EDF0E501 + F0FBEB02C4BFAB012E492A01B0E2C201F3FEF406BEF6DC02AAD5BA017CA08001 + 2E492A01385433016A8A6401A6CBAC01BAFEEF0180BF9B010B7D4A0110B58C01 + 1DEDD00429F7DE011DEDD00112C395010BB18201088C5D010B7D4A0122895F01 + 5FAB820185B79D01B4DAC401E1EFE401F3FEF401E1E4D601CCCBBC01BCB7A401 + A49E84019C92740188826401837654017A6D440172663C016B60340165572904 + 72663C01887D5801B7B09C01E6EDDB01BFD8B9015BA47F010874420123B07E01 + 20A9800122895F01BCFAD3012E492A0194E6C401B6F5E401F3FEF4129AD5BA01 + 7CA080015F754C0147491B01413C0C0145411501413C0C01584B1A01574E2401 + 655729016B603401887D5801A1987D01C4BFAB01DBDACE01E1E4D601ABB09401 + 304B340198C9AB01F3FEF401B6F5E401F3FEF401BEF6DC01F3FEF401BEF6DC01 + 9AD5BA017CA080012E492A0138543301637F600192C09B01D2FADA019AD5BA01 + 499F73010F6D420120A9800124E1B7012BF9D20329F7DE0128ECC10114CB9A01 + 0BB18201088C5D010874420122895F01499F730185B79D019DCCB401D4EDD901 + F0FBEB01EDF0E501DBDACE01C4BFAB01ABB09401A1987D01948B6D0188826401 + 837654017C724C017A6D440172663C026B60340372663C017A6D440190866401 + AFA68F01E1E4D601C7E4D1017CA080010B7D4A0120B7800129DCAC0120BC9201 + 499F730198C9AB012E492A01BEF6DC01F3FEF4139AD5BA017EAA8E01788B6D01 + 72663C015454290145411501413C0C0247491B01655729017A6D4401948B6D01 + A9A78401ACAE8A01888264012D3E1B0198C9AB01F3FEF404BCEACC0196B99E01 + 506141012E492A01637F600196B99E01DBFBE80194E6C4015FAB820111795601 + 0B96640112BD920124E1B70128ECC1012BF9D20128ECC1021AD8B60112C39501 + 0AA67D01088C5D010874420122895F01499F730183B194019DCCB401C7E4D101 + F0FBEB01F3FEF401E1E4D601CCCBBC01BCB7A401AFA68F01A49E8401948B6D01 + 887D5801888264017C724C027A6D440272663C0583765401948B6D01AFA68F01 + E1E4D601D4EDD9017EAA8E010C88530109A06D0124E1B7013FF9D20124B59201 + 7AC6A401668B6E0178B08B01F3FEF4149CEDC90198C9AB017BB793017CA08001 + 6A8A64015F754C01506141014541150254542901506141022E492A01637F6001 + BCEACC01DBFBE801F3FEF401B6F5E401A4EAD4017BB793011F402401566C4801 + A9A78401BCFAD301B0E2C2015FAB8201257C4C01088C5D0123B07E012ED3A401 + 29DCAC0124E1B70315D5AC0112C395010BB1820106976D010C88530108744201 + 22895F01499F73017BB7930198C9AB01ADE2CE01EDF0E501F3FEF401E1E4D601 + D5D3C301C2BAAC01ABB09401A49E84019C9274019086640188826401887D5801 + 7C724C037A6D44067C724C0183765401948B6D01AFA68F01D5D3C301DBFBE801 + A8C5AC0122A471010B7D4A0116C7A4012BF9D2013FF9D201088C5D01DBFBE801 + 304B3401ADE2CE01F3FEF415B6F5E40194E6C4019AD5BA0198C9AB017BB79301 + 7CA080016A8A64015F754C01637F60017EAA8E01B0E2C201F3FEF403BEF6DC01 + A9C3A101444D280150664C0196B99E01DBFBE8017AC6A40133885A01088C5D01 + 23B07E0114CB9A012ED3A4011CD5A20129DCAC011CD5A20114CB9A0120B78001 + 10A9740109A06D010C885301087442010C885301369363015BA47F017BB79301 + 9DCCB401C1DCCC01E1EFE401F3FEF401EDF0E501D5D3C301C9C5B401BCB7A401 + AFA68F01A1987D01948B6D0190866402837654037C724C037A6D44017C724C01 + 7A6D44017C724C017A6D44017C724C01887D5801948B6D01A49E8401CCCBBC01 + F3FEF401B1CCB90161B88F01087442010BB1820128ECC1011DEDD0012BE3C401 + 42916E0180BF9B0144735801F3FEF422B3ECD5016A8A64013854330178A88401 + F0FBEB0180BF9B01257C4C010B96640120B780012BCA99011CD5A20114CB9A01 + 12C3950110B58C010BB182010B966401088C5D010B7D4A01087442010C885301 + 36936301499F730178B08B0192C2A5019DCCB401C7E4D101E1EFE401F3FEF401 + EDF0E501DBDACE01C9C5B401C2BAAC01AFA68F01A49E84019C927401948B6D01 + 90866401887D58027C724C03837654017C724C057A6D44017C724C0183765401 + 887D5801948B6D01A49E8401C4BFAB01E1EFE401E1E4D60195D1AB0124977201 + 088C5D011CD5A2012BF9D2011DEDD00124B5920194E6C4013F6A49019AD5BA01 + B6F5E401F3FEF41F92C2A5012D3E1B01637F6001BEE1C30195D1AB0133885A01 + 0C88530123B07E012BCA990112C3950120B780020B96640116945B010B7D4A01 + 087442010C8853013C8D6401499F73015BA47F017BB7930192C2A5019DCCB401 + C1DCCC01C7E4D101F3FEF401F0FBEB01E1EFE401D5D3C301C4BFAB01BCB7A401 + AFA68F01A49E84019C927401948B6D0190866401887D580188826401887D5801 + 7C724C01887D58027A6D4401837654017C724C0183765401887D58017A6D4401 + 83765401887D58017C724C01887D5802948B6D01A49E8401BCB7A401DBDACE01 + EDF0E501B0E2C20163AD8C01087442010BB182011DEDD0022BF9D20111795601 + 9AD5BA0138543301F3FEF41EBEF6DC017EAA8E0147491B017CA08001DBFBE801 + 78A884010F6D420122A4710120B7800209A06D010B9664010B7D4A0108744201 + 1881560146986E01499F73015FAB82017BB7930192C2A5019DCCB401B4DAC401 + C7E4D101D4EDD901F3FEF402E1EFE401DBDACE01D5D3C301C4BFAB01BCB7A401 + B7B09C01A49E8401A1987D019C927401948B6D019086640188826401887D5801 + 83765403887D58017C724C01887D5802837654027A6D4401887D58017C724C03 + 83765401887D5801888264019C927401B7B09C01D5D3C301F3FEF401D4EDD901 + 92C2A501369363010C88530112C3950129F7DE011DEDD00120BC92018FE0B701 + 5F754C0198C9AB01F3FEF41CBCEACC01637F60014060420192C09B01CFEDC901 + 46986E010B7D4A0122A471020B9664010C8853010874420122895F0146986E01 + 5FAB820185B79D0198C9AB019DCCB401C1DCCC01C7E4D101DBFBE801F3FEF402 + E1EFE401EDF0E501DBDACE01D5D3C301CCCBBC01C2BAAC01BCB7A401AFA68F01 + A49E84019C927402948B6D02887D5805837654027C724C01887D580183765402 + 887D58017C724C01887D580183765401887D580183765401887D580390866401 + 9C927401AFA68F01C4BFAB01EDF0E501F3FEF401B4DAC40161B88F010B7D4A01 + 10A9740124E1B7012BF9D20128ECC10112734C01B0E2C2011F402401BEF6DC01 + F3FEF419BEF6DC01A6CBAC011F4024015F754C01CFEDC90195D1AB0133805501 + 1E88540116945B020B7D4A02369363015FAB820180BF9B019AD5BA01B4DAC401 + D4EDD901F0FBEB01F3FEF401F0FBEB01E1EFE401DBDACE02D5D3C301C9C5B401 + C2BAAC02B7B09C01AFA68F02A49E84019C92740390866402887D580283765401 + 887D580183765402887D580183765402887D58017C724C0183765402887D5801 + 7C724C0183765404887D5802948B6D02A9A78401BCB7A401DBDACE01E1EFE402 + 98C9AB0146986E01087442010BB1820128ECC10140EEC80123B07E017CD6B401 + 5774560192C2A501B6F5E401F3FEF417BEF6DC017CA080012E492A017CA08001 + F0FBEB0178B08B01087442011E88540116945B01087442010B7D4A0136936301 + 83B1940195D1AB01C1DCCC01D4EDD901F3FEF401F0FBEB01E1E4D601DBDACE01 + CCCBBC02C4BFAB02B7B09C039DA58D01AFA68F01A49E8401A1987D029C927401 + 948B6D02888264019086640188826401887D580188826401887D580483765403 + 887D580383765402887D580283765401887D580183765401887D5803948B6D01 + A1987D01AFA68F01CCCBBC01E1E4D601F3FEF401C1DCCC0183B1940136936301 + 0C88530112C3950128ECC1012ED3A40122895F01B0E2C201153A1B01BEF6DC01 + F3FEF414BEF6DC01F3FEF401ADE2CE01406042013F6A4901A6CBAC01BEE1C301 + 46986E01257C4C0116945B02087442013693630178A8840195D1AB01BCEACC01 + F0FBEB01EDF0E501E1E4D601D5D3C301C4BFAB01BCB7A402AFA68F02A49E8402 + A1987D01A49E8401A1987D029C927403948B6D0488826401887D580188826401 + 887D580283765402887D580283765402887D580283765402887D580383765401 + 887D580383765401887D580188826401908664019C927401AFA68F01BCB7A401 + C9C5B401E1E4D601DBFBE801AAD5BA0163AD8C0118815601088C5D0112C39501 + 2ED3A40116945B0195D1AB016A8A640164967001F3FEF41592C2A50129391601 + 6A8A6401D2FADA0180BF9B01087442010B96640110A974010C88530108744201 + 369363017BB79301BEE1C301DBFBE801EDF0E501DBDACE01C9C5B401BCB7A401 + AFA68F01A9A78401A1987D019C927403948B6D019C927401948B6D049C927402 + 948B6D0488826401948B6D019086640188826401887D58018882640183765401 + 887D58028376540188826401887D580583765401887D580183765401887D5802 + 8376540288826401887D5802948B6D02A1987D01B7B09C01BCB7A401CCCBBC01 + F0FBEB01D4EDD9019AD5BA015BA47F011881560116945B0120B7800122A47101 + 36936301D2FADA014060420196B99E01F3FEF412B6F5E40183B194012E492A01 + 7EAA8E01BEF6DC0142916E010B96640120B7800216945B010B7D4A01499F7301 + 92C09B01B3ECD501F0FBEB01DBDACE01C2BAAC01AFA68F01A9A784019C927402 + 90866401948B6D0190866406948B6D01908664019C927401948B6D029C927401 + 948B6D019C92740290866401948B6D019086640188826401887D580188826401 + 887D580183765401887D580283765401887D580183765401887D580183765401 + 887D5805837654018882640183765401887D58028882640190866401948B6D01 + 9C927401A49E8401AFA68F01C2BAAC01DBDACE01EDF0E501E1EFE40195D1AB01 + 5BA47F01257C4C010C88530116945B010F6D420192C09B01C6CCAA012E492A01 + 7CA08001BCEACC01B6F5E401F3FEF40EBEF6DC017CA080013E563C01A6CBAC01 + 95D1AB010B7D4A010BB182012BCA990112C3950109A06D010874420136936301 + 7AC6A401D4EDD901E1EFE401D5D3C301B7B09C01AFA68F019C927401948B6D01 + 9086640188826401887D580488826401887D58018882640190866402948B6D01 + 9C927403A1987D039C927401A1987D019C92740190866401948B6D0190866401 + 887D58028882640183765401887D580283765401887D580483765401887D5802 + 83765401887D580488826401887D580290866401948B6D01A1987D01A49E8401 + AFA68F01C4BFAB01DBDACE01E1EFE4029DCCB4015FAB82013693630108744201 + 12734C013C8D6401BEE1C301C6CCAA01566C540129391601789574019DCCB401 + ADE2CE01BEF6DC01F3FEF401BEF6DC01F3FEF401B6F5E401F3FEF401B6F5E401 + F3FEF401B6F5E401F3FEF401B6F5E401A4EAD401637F600140604201B0E2C201 + 61B88F010F8264011CD5A20124E1B70129DCAC010BB182010B7D4A0136936301 + 80BF9B01D4EDD901EDF0E501CCCBBC01B7B09C019C927401948B6D0190866401 + 887D580183765402887D58017C724C0183765401887D58028882640190866402 + 948B6D029C927401A49E8402AFA68F04A49E84029C927401948B6D0290866401 + 88826401887D580183765401887D580583765401887D580383765401887D5801 + 88826401887D580188826401887D580390866402948B6D029C927401A1987D01 + AFA68F01C2BAAC01DBDACE01E6EDDB01DBFBE801B4DAC40185B79D01499F7301 + 3C8D64013693630178A88401B4DAC401D4EDD90196B99E01788B6D0150664C01 + 2E492A012939160150664C017CA0800192C09B01B0E2C201BCFAD301F3FEF403 + BCFAD301AAD5BA014060420157745601D2FADA015FAB82010AA67D012BE3C401 + 2BF9D20128ECC10112C39501088C5D010C88530178B08B01ADE2CE01F0FBEB01 + CCCBBC01B7B09C01A1987D01948B6D01887D5801837654037C724C0183765401 + 887D580283765401887D580290866401948B6D019C927401A1987D01A49E8401 + AFA68F01B7B09C01BCB7A401C2BAAC02BCB7A402B7B09C01AFA68F01A49E8401 + 9C927401948B6D02887D5803837654027C724C01837654028882640183765401 + 887D580583765401888264018376540188826402887D580190866401948B6D02 + 9C927401A49E8401AFA68F01BCB7A401CCCBBC01E1E4D601F3FEF401E1EFE401 + AAD5BA0185B79D0183B1940178A884017EAA8E01A8C5AC01C0D8C401E6EDDB01 + F0FBEB01DCE2C301C6CCAA01ACAE8A016A8A640144735801444D2801153A1B01 + 3F6A490168967C017CA08001577456012E492A0164967001DBFBE8011E8F7601 + 24B5920129F7DE012BF9D20215D5AC0109A06D010B7D4A015FAB82019AD5BA01 + F3FEF401DBDACE01B7B09C01A1987D01948B6D01887D58027C724C0183765401 + 7C724C01837654027C724C01887D58028882640190866401888264019C927401 + A1987D01AFA68F01BCB7A401C2BAAC01CCCBBC01D5D3C301DBDACE03D5D3C301 + CCCBBC01C2BAAC01B7B09C01AFA68F01A1987D01948B6D0288826401887D5802 + 83765402887D580183765403887D5803888264018376540188826401887D5801 + 88826401887D580290866404948B6D02A1987D01A49E8401B7B09C01C2BAAC01 + D5D3C301D4EDD901F3FEF401E1EFE401B4DAC401AFC6B70192C2A50183B19401 + 85B79D0183B1940178B08B017BB7930295D1AB01BFD8B901D2FADA02BFD8B901 + 78A8840178957401668B6E0178A88401B0E2C2018FE0B701117956012CCAB401 + 1DEDD00112E2D0011DEDD00124E1B7010BB182010874420146986E0192C2A501 + E1EFE401E1E4D601C9C5B401AFA68F019C92740188826401887D58017C724C02 + 837654017C724C0183765402887D580183765401887D58018882640190866401 + 9C927401A1987D01AFA68F01BCB7A401C9C5B401D5D3C301E1E4D601EDF0E501 + F3FEF403F0FBEB01E1EFE401DBDACE01CCCBBC01C2BAAC01AFA68F01A1987D01 + 9C9274019086640188826401887D580283765404887D58018882640183765402 + 887D580288826401887D580388826401887D58029086640188826402948B6D02 + 9C927401A49E8402B7B09C01C2BAAC01CCCBBC01E1E4D601F0FBEB02D4EDD901 + B4DAC40192C2A50183B1940178A8840164967001488A5C0233805502488A5C01 + 57A0740178B08B0180BF9B017AC6A4017BB793010F826401249E840140EEC801 + 12E2D0010DD7D0011DEDD00212C395010C88530122895F017BB79301C1DCCC01 + F3FEF401D5D3C301B7B09C01A1987D0190866401887D5801837654017C724C01 + 837654017C724C01887D580283765402887D58018882640190866401948B6D01 + A1987D01A49E8401B7B09C01CCCBBC01E1E4D601F0FBEB02D4EDD901C1DCCC01 + B4DAC402BCEACC01E1EFE401F3FEF401E1EFE401DBDACE01C9C5B401B7B09C01 + A49E84019C927401948B6D01887D580383765405887D580183765401887D5802 + 83765401887D580188826401887D580188826403887D580190866401948B6D01 + 88826401948B6D03A1987D02AFA68F01B7B09C01BCB7A401AFC6B701D5D3C301 + EDF0E501F3FEF401E1EFE401B4DAC4019DCCB40178B08B0157A074013C8D6401 + 257C4C01087442010B7D4A011E88540109A06D0122A471010BB1820116C7A401 + 28E2CF020DD7D00212E2D0012BF9D20116C7A4010B9664010B7D4A015FAB8201 + 9DCCB401DBFBE801DBDACE01C4BFAB01AFA68F01948B6D0190866401887D5801 + 83765401887D580183765401887D580183765401887D58018376540188826401 + 887D580190866401948B6D019C927401A49E8401B7B09C01CCCBBC01DBDACE01 + F3FEF401D4EDD901AAD5BA0192C2A50161B88F015FAB820178B08B0180BF9B01 + 92C09B01AAD5BA01E1EFE401F3FEF401E1E4D601CCCBBC01BCB7A401A49E8401 + 8E937301948B6D01887D58018882640183765405887D580288826401887D5805 + 88826401887D580188826401908664028882640190866401948B6D0188826401 + 948B6D029C927402A1987D01A49E8401AFA68F01BCB7A401C2BAAC01D5D3C301 + E1E4D601F3FEF401EDF0E501ADE2CE0198C9AB017BB7930157A0740133885A01 + 087442010C88530109A06D0120B7800129DCAC012BF9D2011DEDD00112E2D002 + 1DEDD0012BEEDF0112C3950109A06D010B7D4A0146986E0192C2A501D4EDD901 + F0FBEB01D5D3C301B7B09C01A1987D01948B6D01887D580283765403887D5805 + 88826402948B6D01A1987D01AFA68F01C2BAAC01DBDACE01F0FBEB01D4EDD901 + 9DCCB4015FAB82011E8F760111795601087442010F6D42010B7D4A0124977201 + 5BA47F017AC6A401B4DAC401DBFBE801E1EFE401D5D3C301BCB7A4019DA58D01 + 9C927401948B6D018882640283765401887D580383765401887D580388826402 + 948B6D0188826401948B6D018882640190866401948B6D069C927401948B6D02 + 9C927401908664019C927402A1987D01A49E8401B7B09C01C2BAAC01CCCBBC01 + E1E4D601EDF0E501F0FBEB01C7E4D1019DCCB40185B79D0157A0740136936301 + 08744201088C5D0120B780011CD5A20128ECC1011DEDD00224E1B70112C39501 + 0B966401087442013693630180BF9B01B4DAC401F3FEF401DBDACE01C2BAAC01 + AFA68F019C9274019086640283765401887D580283765401887D580183765401 + 887D580390866401948B6D019C927401A49E8401B7B09C01C9C5B401EDF0E501 + E1EFE4019DCCB4015FAB82010B7D4A01088C5D0110B58C0128C4A40127BAA701 + 1EAC8E010B96640112734C013693630163AD8C019DCCB401D4EDD901F0FBEB01 + DBDACE01C4BFAB01B7B09C01A1987D01948B6D0288826403887D580188826403 + 90866401948B6D0188826401948B6D0188826401948B6D04A49E8403A1987D04 + 8E937301948B6D0388826401948B6D019C927401A1987D01A49E8401AFA68F01 + BCB7A401C9C5B401E1E4D601E1EFE401F3FEF401D4EDD901AAD5BA0180BF9B01 + 5FAB820122895F010F6D4201088C5D010AA67D010BB1820209A06D01088C5D01 + 0B7D4A0146986E0183B19401AAD5BA01EDF0E501E6EDDB01CCCBBC01B7B09C01 + A1987D019C92740190866401887D580788826401887D58018882640190866402 + A1987D01A49E8401C2BAAC01D5D3C301F0FBEB01C7E4D10185B79D0122895F01 + 06976D0130D6BA0138E2DC0111CBD70138CEDC012BEEDF0124E1B7010BB18201 + 0C885301257C4C0157A0740192C09B01C7E4D101F0FBEB01E1E4D601CCCBBC01 + BCB7A4019DA58D01A1987D019C927401948B6D079C927403A1987D018C987E01 + A1987D018C987E01A1987D01B7B09C05AFA68F019DA58D01AFA68F01A1987D02 + 948B6D0388826402948B6D019C927401A49E8401AFA68F01BCB7A401C4BFAB01 + D5D3C301E6EDDB01F3FEF401E1EFE401B4DAC40192C2A50163AD8C0142916E01 + 188156010B7D4A0322895F015BA47F017BB7930194D6C401E1EFE401EDF0E501 + DBDACE01C2BAAC01AFA68F01A1987D018882640190866401887D580588826401 + 887D58039086640188826401948B6D01A1987D01ABB09401C4BFAB01E1E4D601 + F3FEF401AAD5BA015BA47F010874420124B592013CDAE4010797C7010574BB02 + 049FC4011CD8DC012EEDD10112C395010B96640108744201369363017BB79301 + AAD5BA01DBFBE801EDF0E501DBDACE01C9C5B401B7B09C01AFA68F02A49E8404 + 9DA58D01A49E84019DA58D01AFA68F02B7B09C01AFA68F01B7B09C03DBDACE01 + D5D3C301DBDACE01D5D3C302CCCBBC01C9C5B401C4BFAB01B7B09C01AFA68F01 + A49E84019C927401948B6D0188826401948B6D01888264019086640188826401 + 9C927401A1987D01AFA68F01B7B09C01C2BAAC01D5D3C301E1E4D601F0FBEB01 + DBFBE801BCEACC01A6CBAC0180BF9B0161B88F0163AD8C017BB7930185B79D01 + 98C9AB01C1DCCC01EDF0E501F0FBEB01E1E4D601C4BFAB01B7B09C01A49E8401 + 9C927401948B6D0190866401887D580190866401887D580590866401887D5801 + 90866401948B6D019C927401A49E8401AFA68F01C9C5B401EDF0E501E1EFE401 + 95D1AB0146986E010C88530130D6BA0113BDD7010574BB010442A702049AB401 + 3CDAE40150DCD0012ED3A40123B07E0116945B010874420133885A0178A88401 + A8C5AC01C7E4D101F0FBEB01EDF0E501E1E4D601CCCBBC01C9C5B402C2BAAC02 + C4BFAB04C9C5B401CCCBBC03D5D3C303F0FBEB01F3FEF401DBFBE801F3FEF403 + E1EFE401E1E4D601D5D3C301C4BFAB01B7B09C01A49E8401A1987D0190866401 + 948B6D01887D580188826402908664029C927402A49E8401ABB09401BCB7A401 + CCCBBC01DCE2C301EDF0E501F3FEF401E1EFE401C7E4D101C1DCCC02C7E4D101 + E1EFE401F3FEF401EDF0E501DBDACE01C9C5B401B7B09C01AFA68F01A1987D01 + 948B6D0188826401948B6D01908664018882640190866401887D580188826402 + 887D580188826401887D580190866401948B6D02A49E8401B7B09C01CCCBBC01 + E1E4D601EDF0E5018CCAB80146986E01088C5D0130D6BA0113BDD7010574BB01 + 0442A7010574BB0144BCC4011179560122895F01117956010F6D42023F6A4901 + 3380550142916E0178B08B0192C2A501B4DAC401D4EDD901DCFEF401F3FEF401 + EDF0E502E1EFE402E1E4D601E1EFE401EDF0E501F0FBEB03F3FEF40598C9AB01 + A8C5AC0192C2A50198C9AB01B1CCB901BFD8B901C7E4D101D4EDD901F3FEF401 + E6EDDB01D5D3C301C4BFAB01AFA68F01A49E8401948B6D0190866401887D5801 + 8882640183765401887D58018882640190866401948B6D019C927401A49E8401 + ABB09401B7B09C01C9C5B401DBDACE01E1E4D601EDF0E501F0FBEB03EDF0E501 + E1E4D601DBDACE01C9C5B401BCB7A401AFA68F01A1987D019C927401948B6D02 + 90866403887D580188826401887D580190866401887D580190866401887D5801 + 908664029C927401A49E8401AFA68F01CCCBBC01E1EFE4029DCCB40146986E01 + 0C8853012CCAB40138CEDC01049AB4010574BB015CD2FC017CCAC40180BF9B01 + 78B08B0195D1AB01D2FADA01BCFAD3018FE0B7017AC6A40180BF9B0192C09B02 + AFC6B701B1CCB901D5D3C301C7E4D101C1DCCC01E1EFE401E1E4D601C7E4D101 + E1EFE401DBDACE01C7E4D102C1DCCC01C0D8C403AAD5BA01B1CCB90257A07402 + 46986E016496700146986E0157A0740178B08B0192C09B01AAD5BA01E6EDDB01 + F0FBEB01DBDACE01C4BFAB01AFA68F019C927401948B6D01887D580183765401 + 887D580183765402887D5802908664029C927401A1987D01A9A78401ABB09401 + BCB7A401C9C5B401D5D3C303CCCBBC02C2BAAC01B7B09C01AFA68F01A49E8401 + A1987D019C927401948B6D0290866401887D580190866403887D580188826401 + 887D58018882640190866402948B6D019C927401A1987D01B7B09C01C9C5B401 + E1E4D601F0FBEB01AAD5BA01499F73010874420110B58C012BEEDF0107BFCB01 + 09B0C20144BCC401BAFEEF01153A1B017CA0800133805501153A1B0138543301 + 577456017CA08001A9C3A101DCE2C301F0FBEB02E6EDDB01DBDACE01C1DCCC01 + CCCBBC01B1CCB902A8C5AC0292C2A50196B99E0183B194017BB7930178B08B02 + 78A884015FAB820178A884015BA47F01488A5C0133805501488A5C0133805501 + 257C4C0233885A01488A5C015BA47F0192C09B01C1DCCC01F3FEF401E1E4D601 + C2BAAC01AFA68F019C92740190866401887D5801837654017C724C03887D5801 + 83765401887D5802948B6D019C927401A1987D01A49E8401AFA68F01B7B09C01 + BCB7A403B7B09C03AFA68F01A1987D029C927401948B6D0288826401948B6D02 + 887D580188826401948B6D01887D580190866401887D58019086640188826401 + 948B6D02A49E8401AFA68F01C4BFAB01E1E4D601F3FEF401B4DAC40178B08B01 + 0C88530106976D012BE3C40112E2D0010DD7D00127BAA701DCFEF40129391601 + DBFBE801F3FEF401D2FADA01BCEACC01AAD5BA017CA0800150664C012D3D2501 + 3E4C3601637F60018C987E01A9C3A101BEE1C301DBFBE802C7E4D101C0D8C401 + A6CBAC0192C09B0296B99E0183B1940178A884037CA0800178A8840157A07401 + CFEDC901B0E2C201AAD5BA0192C09B0178B08B01668B6E01257C4C0233805501 + 57A074017BB79301BEE1C301F3FEF401E1E4D601C2BAAC01A49E8401948B6D01 + 887D5801837654017C724C017A6D44017C724C017A6D44017C724C02887D5801 + 83765401887D58019C927401948B6D01A1987D01A49E8402B7B09C01AFA68F01 + B7B09C02A49E8403A1987D019C927401948B6D038882640190866404887D5801 + 88826401887D580190866403948B6D01A1987D01A9A78401BCB7A401DBDACE01 + F0FBEB01D4EDD90192C2A50146986E010B7D4A0112C395012BF9D2011DEDD001 + 28C4A401BCEACC011F402401BEF6DC01F3FEF406BCFAD301ADE2CE0192C2A501 + 44886C011F4024012E492A01566C4801888264018C987E01A9C3A101C6CCAA01 + E1E4D601E8F8DB02F0FBEB0750664C01566C5401637F60017CA0800198C9AB01 + DBFBE80195D1AB0157A07401338055026496700185B79D01C0D8C401F3FEF401 + D5D3C301BCB7A401A1987D0188826401837654017A6D440372663C017A6D4402 + 7C724C0283765402908664029C927401A49E8402B7B09C01AFA68F02B7B09C01 + AFA68F01A49E8402A1987D019C927402948B6D029086640288826401948B6D01 + 90866401887D580190866401887D580190866402948B6D019C927401A49E8401 + BCB7A401CCCBBC01E1E4D601F0FBEB01AAD5BA0163AD8C011881560109A06D01 + 29DCAC012BF9D2012BCA9901B0E2C2012E492A01BEF6DC01F3FEF409D2FADA01 + F3FEF401BCEACC01A6CBAC0196B99E01668B6E0150614101293916011F402401 + 2D3D25013E4C36033E563C013E4C36032E492A01ADE2CE027AC6A4017EAA8E01 + 38543301406042017EAA8E01F0FBEB0192C09B0142916E013C8D64015BA47F01 + 92C2A501C7E4D101F0FBEB01C9C5B401A49E8401948B6D01837654017A6D4401 + 72663C077C724C0288826401948B6D01A1987D01A49E8401B7B09C01BCB7A402 + C2BAAC01BCB7A401B7B09C02AFA68F01A49E8401A1987D019C927401948B6D02 + 8882640190866402887D580190866401887D580190866401887D580190866402 + 948B6D019C927401A1987D01AFA68F01C4BFAB01DBDACE01F0FBEB01D4EDD901 + 92C2A50146986E01087442010BB1820129DCAC0124B592018FE0B70138543301 + BEF6DC01F3FEF411BEF6DC03A4EAD404BEF6DC01B6F5E402F3FEF404DBFBE801 + AAD5BA0140604201566C4801A6CBAC01BCEACC0178B08B017CA0800183B19401 + B1CCB901EDF0E501E1E4D601B7B09C01948B6D01887D58017A6D44016B603401 + 655729046B60340172663C027C724C01837654019C927401A49E8401B7B09C01 + C4BFAB01C9C5B401D5D3C301CCCBBC02C9C5B401C2BAAC01BCB7A401AFA68F01 + A49E8401A1987D019C927401948B6D0290866403887D580190866401887D5801 + 88826401887D5801908664039C927401A49E8401ABB09401C9C5B401DBDACE01 + F3FEF401B4DAC4017BB793013C8D64010C88530120B7800116945B01BCEACC01 + 2E492A01BEF6DC01F3FEF421B3ECD50185B79D012E492A018C987E01D2FADA01 + C0D8C401A8C5AC01AFC6B701E6EDDB01EDF0E501C4BFAB01A1987D0183765401 + 72663C0165572902584B1A016557290472663C017C724C01908664018C987E01 + B7B09C01C9C5B401DBDACE01EDF0E502F0FBEB01E1EFE401DBDACE01D5D3C301 + C9C5B401B7B09C01AFA68F01A49E84019C927402948B6D018882640190866402 + 887D580190866401887D580190866402887D5801948B6D0190866401948B6D01 + A1987D01A49E8401BCB7A401C9C5B401E6EDDB01F0FBEB01B4DAC4015FAB8201 + 18815601257C4C02E8F8DB01153A1B01F3FEF424BCEACC014473580151583F01 + 7EAA8E01D4EDD901F3FEF401F0FBEB01E6EDDB01C4BFAB019C9274017A6D4401 + 6B603401584B1A0147491B0245411502584B1A01655729016B6034017C724C01 + 948B6D01B7B09C01D5D3C301F0FBEB01DBFBE801E1EFE401C7E4D101E1EFE401 + EDF0E501F3FEF401E1EFE401DBDACE01C9C5B401BCB7A401AFA68F01A49E8401 + 9C927401948B6D0190866402887D58019086640188826401887D580188826401 + 887D580390866402948B6D019C927401A49E8401BCB7A401CCCBBC01E1EFE401 + DBFBE801AAD5BA0178A88401369363017BB79301A9C3A10157745601F3FEF426 + 9DCCB401406042013E563C01788B6D01A49E8401A9A784019C927401887D5801 + 72663C01584B1A01413C0C0245411502413C0C0247491B01655729017C724C01 + A49E8401D5D3C301F0FBEB01B0E2C20198C9AB017BB7930180BF9B0192C2A501 + AAD5BA01C7E4D101F0FBEB01EDF0E501DBDACE01C2BAAC01B7B09C01A49E8401 + 9C927401948B6D018882640190866402887D580188826401887D580790866401 + 948B6D019C927401A49E8401AFA68F01C9C5B401DCE2C301F3FEF401C0D8C401 + AFC6B701E8F8DB01637F6001A8C5AC01F3FEF427DBFBE801B4DAC4017CA08001 + 38543301293916012D3E1B01293916012D3E1B0172663C01637F60018E937301 + 7CA08001649670016A8A64016B60340129391601584B1A0183765401ABB09401 + F0FBEB019DCCB40168967C0133885A010B7D4A011E88540146986E0163AD8C01 + 98C9AB01C1DCCC01F3FEF401E6EDDB01D5D3C301C2BAAC01AFA68F01A1987D01 + 9C927401948B6D0190866401887D580190866401887D580483765401887D5805 + 908664029C927401A49E8401BCB7A401D5D3C301E6EDDB01E8F8DB0196B99E01 + 153A1B01BCFAD301F3FEF426A4EAD401F3FEF404BCFAD301BEF6DC04F3FEF403 + BEF6DC01ADE2CE0192C2A50178957401293916016B603401ABB09401F0FBEB01 + 78A884010874420109A06D0122A471010B966401087442011E8854015FAB8201 + 95D1AB01E1E4D601F3FEF401E1E4D601C2BAAC01AFA68F01A49E84019C927401 + 9086640288826401887D58067C724C0183765403887D580183765401887D5801 + 8882640190866401948B6D01A1987D019DA58D01A49E84014060420183B19401 + F3FEF436BCFAD301F3FEF401AAD5BA015061410150664C01C0D8C4017BB79301 + 22895F012ED3A40128ECC1011CD5A2010BB182010B7D4A0122895F0178B08B01 + 94D6C401EDF0E501E1EFE401CCCBBC01B7B09C01A49E84019C927401948B6D01 + 90866401887D580188826401887D580183765401887D580283765401887D5802 + 7C724C047A6D440572663C01545429015F754C01F3FEF43ABCFAD301668B6E01 + 57745601DBFBE80122895F0129DCAC012EEDD10129F7DE0115D5AC0110A97401 + 08744201499F730192C2A501D4EDD901F3FEF401D5D3C301BCB7A401A49E8401 + 9C92740190866402887D580283765401887D58027C724C01887D58017C724C01 + 83765401887D58017C724C017A6D440372663C016B60340165572902413C0C01 + 566C4801B4DAC401F3FEF43BBEF6DC01637F60016A8A64017CD6B4011EAC8E01 + 1DEDD00112E2D0012BF9D20112C395010C88530122895F017BB79301C1DCCC01 + F3FEF401DBDACE01C4BFAB01AFA68F019C92740190866402887D580483765401 + 887D580183765401887D58017C724C037A6D440272663C016B60340165572901 + 584B1A01413C0C016557290178A88401F3FEF401B6F5E401F3FEF43BB0E2C201 + 153A1B01AAD5BA011881560147EFDC0112E2D0011DEDD0011AD8B60110A97401 + 0B7D4A015FAB8201AAD5BA01F3FEF401DBDACE01C4BFAB01A49E84019C927401 + 948B6D01887D580483765403887D58017A6D4401837654017C724C017A6D4402 + 72663C016B60340165572902413C0C025F754C0195D1AB01F3FEF43CB6F5E401 + F3FEF40185B79D01577456018FE0B70127BAA70110D6C40112E2D00129F7DE01 + 0BB1820108744201499F73019DCCB401DBFBE801E1E4D601C2BAAC01AFA68F01 + 9C9274018882640283765404887D580183765402887D58017C724C037A6D4401 + 72663C016B60340165572901584B1A0145411501413C0C01637F60019AD5BA01 + F3FEF43EADE2CE01153A1B01BCEACC01106E4C012EEDD1010DD7D0012BEEDF01 + 14CB9A010C8853013693630192C2A501E1EFE401E1E4D601C4BFAB01AFA68F01 + 948B6D0190866401887D5801888264017C724C01887D5801837654037A6D4401 + 7C724C027A6D440272663C026B60340165572901574E2401584B1A01413C0C01 + 5F754C0198C9AB01F3FEF43F7CA080016496700161B88F0144DABF010DD7D001 + 1DEDD00124E1B7010B96640122895F0180BF9B01D4EDD901E1EFE401C4BFAB01 + AFA68F01948B6D0188826401887D58017C724C01887D58017C724C0183765401 + 7C724C0183765401887D58017C724C037A6D440272663C016B603402584B1A02 + 413C0C016B6034017BB79301F3FEF43FBEE1C30138543301BAFEEF0124977201 + 28E2CF011DEDD0012BE3C40110A974010B7D4A017BB79301D4EDD901E6EDDB01 + C4BFAB019DA58D01948B6D0190866401837654027C724C01837654017C724C01 + 837654017C724C047A6D440272663C0265572902574E2401584B1A0145411502 + 7CA08001BEF6DC01F3FEF43F50664C017BB7930168967C012BE3C4011DEDD001 + 28ECC1010BB182010B7D4A0161B88F01C7E4D101E1EFE401C4BFAB01A49E8401 + 948B6D01887D5801837654017C724C01837654017C724C01837654017C724C04 + 7A6D440372663C026B60340265572902584B1A01413C0C0157745601BCFAD301 + F3FEF43F8CCAB80150664C01BCEACC010AA67D013FF9D2012BF9D2010BB18201 + 0B7D4A015FAB8201C7E4D101E6EDDB01C4BFAB01A49E84019086640183765402 + 7C724C077A6D44017C724C017A6D440272663C036B6034016557290354542901 + 2E492A01BCEACC01F3FEF43FB6F5E4013854330192C09B01249772012ED3A401 + 24E1B70112C39501087442015FAB8201C7E4D101E6EDDB01BCB7A401A1987D01 + 90866401837654017C724C05887D58017A6D44017C724C0372663C017A6D4401 + 72663C026B60340272663C026B60340229391601BCEACC01F3FEF44092C2A501 + 3F6A4901BCFAD301188156012BCA990120B780010B7D4A0157A07401ADE2CE01 + E6EDDB01C2BAAC019C92740188826401837654017A6D44017C724C017A6D4401 + 7C724C017A6D44027C724C017A6D440472663C067C724C01887D580172663C01 + 29391601BCEACC01B6F5E401F3FEF43FD2FADA014060420178B08B0161B88F01 + 0B9664010BB18201087442015BA47F01C7E4D101E6EDDB01B7B09C019C927401 + 837654017C724C017A6D440A72663C047A6D440283765401887D580190866401 + 7C724C012E492A01D2FADA01F3FEF41E0F000000F8FFFFFF1FF07F000C000000 + 3F010000F8FFFFFF1FFCFFA10F000000FF000000F0FFFFFF1FFEFFC30F000000 + FF030000E8FFFFFF8FFFFFEF0F000000FF070000C0FFFFFF8FFFFFFF0F000000 + FF0F000080FFFFFFE7FFFFFF0F000000FF3F000000FEFFFFC3FFFFFF0F000000 + FF7F000000FCFFFFE1FFFFFF0F000000FF7F01000080FFFFE0FFFFFF0F000000 + FFFF00000000FC7FE8FFFFFF0F000000FFFF01000000E01FF0FFFFFF0B000000 + FFFF050000000007F0FFFDFF07000000FEFF030000000000F07FFFFF0F000000 + FFFF030000000000E0DFFFFF0F000000F7FF030000000000E0FFFFFF0F000000 + 9FFF030000000000E0FFFFFF0F000000FFEB030000000000C0FFFFFF0F000000 + FFFF01000000000080FFFFFF0F000000FFFF03000000000000FFFFFF0F000000 + FFFF01000000000080FEFFFF0F000000FFFF01000000000000FEFFFF0F000000 + FFFF03000020000000FEFFFF0F000000FFFF03000000000000FCFFFF0F000000 + FFFF07000000000000FCFFFF0F000000FFFF0F000000000000FCFFFF0F000000 + FFFF07000700000000FCFFFF0F000000FFFF07F07F00000000FCFFFF0F000000 + FFFF07F8FF01000000FDFFFF0F000000FFFF07FEFF01000000FCFFFF0F000000 + FFFF03FFFF03000000FCCFFF0F000000FFFF07FFFF07000000FCFFFE0F000000 + FFFF01FFBF07000000F8FFF70F000000FFFF81FFDF07000000F8FFEF0F000000 + FFFF80FFFF07000000F0FFFF0F000000FF7F80FFFF0F000000E0FF7F0F000000 + FF7F80BFFF5F000000C0FFFF0E000000FF3F80FFFF3F000000C0FFFF0D000000 + FF1F80FFFF7F010000F4FFFF0D000000FF0F00FFFFFF000000FEFFFF0F000000 + FF0700FFFFFF000090FFFFFF0F000000FF0000FFFFFF0000E0FFFFFF01000000 + 000000FFFFFF0000F8FFFF0700000000000000FFFFDF0100FCFFFF0F00000000 + 020000FFFFFF0040FFFFFF2F04000000030000FFFFFF0080FFFFFFFF0F000000 + 070080FFFF7F00E0FFFFFFFF0F0000000F0000FFFFEF00F8FFFFFBFF07000000 + 1F0000FFFF3F00FFFFFFFFFF0F0000003F0000FEFF3FF0FFFF7FFFFF0F000000 + FF0000FCFF5FFDFFFFFFFFFF0F000000FF0000F8FF0FFFFFFFEFFFFF0F000000 + FF0000F0FFEFFFFFFFFBFFFF0F000000FF0100C0FFF1FFFFFFFEFFFF0B000000 + FF01000000F8FFFFBFFFFFFF0F000000FF07000000FCFFFFF7FFFFFF0F000000 + FF03000000FFFFFFFCFFFFFF07000000FF07000080FFFFCFFFFFFFFF0F000000 + FE0F0000E0FFFFFEFFFFFFFF0F000000FF1F0000F0FFEFFFFFFFFFFF0F000000 + FD1F0000FAFFFFFFFFFFFFFF0F000000FF1F0000FCFFFFFFFFFFFFFF0F000000 + FF3F0000FFFFFFFFFFFFFFFF0F000000FFFF0180FFFFFFFFFFFFFFFF0F000000 + FFFFAFEAFFFFFFFFFFFFFFFF0F000000FFFFFFF1FFFFFFFFFFFFFFFF0F000000 + 7FFFFFFFFFFBFFFFFFFFFFFF0F000000FFFDFFFFFFFFFFFFC7FFFFFF0F000000 + FFFFFFFFFFFDFFFFFFFEFFFF0F000000FFBFFFFFFFFFFF7FFFFBFFFF0F000000 + FFFFFEFFFFFFFFFFFFFFFFFF0F000000FFFFFFFF7FFFFFFFFFFFFFFF0F000000 + FFFFDFFFFFFFFFFFFFFFFFFF0F000000FFFF7FFFFFFFFFDFFFFFFFFF0F000000 + FFFFFFFFFFFFFFFFFFFFFFFF0F000000C5FFFFEFF7FFFFFFFFFFEF7F00000000 + FFFEFFFFFFFFFFFFFFFFFFFF0F000000FFFFFFFFFFFFFFFFFFFFFFFF0F000000 + FFF7FFFFFFFFFFDFFFFDFFFF0F000000FFEFFFFFFFFFFFFFFF81FFFF0F000000 + FFDFFFFFFFFFFFFFFF01F4FF0F000000FFFFFFFFFFFFFFFFFF0100FC0F000000 + F0FFFFFFFFFFFF7FFF01000000000000C0FFFFFFFFFFFFFFFF00000000000000 + 00DFFFFFBFFFFFFFFF0000000000000000FCFFFFFFFFFFFFFB00000000000000 + 00F8FFFFFFFEFFFFFF0000000000000000848FFFFFFDFFFF7F00000000000000 + 000000FAFFFFFFFF3F00000000000000000000F0FFFBFFFF3F00000000000000 + 000000E0FFFBFFFF5F00000000000000000000C0FFFBFFFF1F00000000000000 + 000000A0FFFFFFFF1F0000000000000000000080FFFFFFFF1F00000000000000 + 00000000FFFFFFFF1F0000000000000000000000FFFFFFFF3F00000000000000 + 00000000FEFFFFFF3F0000000000000000000000FEFFFFFF3F00000000000000 + 00000000FEFFFFFF3F0000000000000000000000FCFFFFFF7F00000000000000 + 00000000FCFFFFFF3F00000000000000 + } + face.fade_pos.count = 5 + face.fade_pos.items = ( + 0 + 0.2 + 0.5 + 0.8 + 1 + ) + face.fade_color.count = 5 + face.fade_color.items = ( + 16777215 + 8421504 + 4210752 + 8421504 + 16777215 + ) + face.fade_direction = gd_up + face.localprops = [fal_options, fal_fadirection, fal_faopacity] + taborder = 2 + bounds_x = 400 + bounds_y = 40 + bounds_cx = 132 + bounds_cy = 52 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit8: tstringedit + color = -2147483645 + frame.levelo = 0 + frame.framei_left = 4 + frame.framei_right = 4 + frame.frameimage_list = imli + frame.frameimage_offsetmouse = 8 + frame.frameimage_offsetclicked = 8 + frame.frameimage_offsetactive = 24 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_fileft, frl_firight, frl_frameimagelist, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_colorclient] + frame.localprops1 = [] + face.options = [fao_alphafadeimage] + face.image.alignment = [al_xcentered, al_ycentered, al_tiled] + face.image.image = { + 000000000000000020000000200000006C0B0000000000000000000000000000 + 0000000000000000000000000000000000000000BDBDBD01B5B5B501BDBDBD04 + C6C6C601CECECE01DEDEDE03D6D6D6019C9C9C0194949401CECECE01DEDEDE02 + B5B5B502BDBDBD01DEDEDE03D6D6D601C6C6C602BDBDBD01B5B5B502BDBDBD01 + 949494019C9C9C01BDBDBD01ADADAD029C9C9C01949494019C9C9C01A5A5A501 + BDBDBD01A5A5A5019C9C9C0194949402D6D6D60194949402DEDEDE01BDBDBD02 + B5B5B501BDBDBD019C9C9C02A5A5A501ADADAD01A5A5A5029C9C9C0194949401 + 9C9C9C01B5B5B5019C9C9C01CECECE02C6C6C601ADADAD01B5B5B501D6D6D601 + DEDEDE02CECECE01C6C6C601BDBDBD03DEDEDE01CECECE01ADADAD01BDBDBD01 + 9C9C9C01ADADAD01DEDEDE01CECECE01B5B5B501C6C6C603D6D6D601DEDEDE02 + CECECE0194949401B5B5B501D6D6D601BDBDBD01C6C6C601DEDEDE0194949401 + B5B5B502DEDEDE04BDBDBD01CECECE01DEDEDE03B5B5B5029C9C9C01D6D6D601 + DEDEDE03BDBDBD01CECECE01DEDEDE03CECECE019C9C9C01BDBDBD01B5B5B501 + DEDEDE01A5A5A501DEDEDE029C9C9C01BDBDBD02B5B5B503BDBDBD01B5B5B502 + BDBDBD01B5B5B501CECECE01D6D6D6019C9C9C01B5B5B501DEDEDE01BDBDBD01 + B5B5B501BDBDBD01B5B5B502BDBDBD01B5B5B5029C9C9C01949494019C9C9C01 + B5B5B501DEDEDE03C6C6C601A5A5A501DEDEDE01B5B5B501BDBDBD01A5A5A501 + 9C9C9C06BDBDBD02ADADAD0194949401DEDEDE019C9C9C01949494019C9C9C05 + ADADAD019C9C9C01CECECE01B5B5B50194949401DEDEDE03B5B5B50194949401 + DEDEDE01CECECE0194949402D6D6D601DEDEDE06A5A5A502BDBDBD01C6C6C601 + DEDEDE06BDBDBD03DEDEDE01BDBDBD0194949401DEDEDE03ADADAD0194949401 + DEDEDE02BDBDBD01B5B5B502D6D6D601DEDEDE03A5A5A501D6D6D6019C9C9C01 + BDBDBD019C9C9C01B5B5B502BDBDBD01DEDEDE03C6C6C6019C9C9C01A5A5A501 + DEDEDE02C6C6C601ADADAD01CECECE01DEDEDE0294949401B5B5B501DEDEDE02 + BDBDBD01A5A5A5019C9C9C01B5B5B501DEDEDE03C6C6C602A5A5A501D6D6D601 + B5B5B50194949401CECECE02DEDEDE02CECECE01A5A5A501B5B5B50194949401 + DEDEDE039C9C9C01BDBDBD01DEDEDE01C6C6C601B5B5B501C6C6C601DEDEDE02 + B5B5B50194949401C6C6C601A5A5A501ADADAD01BDBDBD03B5B5B5019C9C9C01 + DEDEDE01B5B5B501A5A5A501B5B5B503BDBDBD01A5A5A502BDBDBD019C9C9C01 + DEDEDE03A5A5A50194949401DEDEDE01B5B5B5019C9C9C01DEDEDE03ADADAD02 + DEDEDE01C6C6C6019C9C9C01ADADAD01949494029C9C9C02DEDEDE01B5B5B501 + ADADAD019C9C9C03B5B5B501A5A5A501DEDEDE01CECECE01BDBDBD01CECECE01 + DEDEDE02BDBDBD01A5A5A501D6D6D601ADADAD01BDBDBD01DEDEDE039C9C9C01 + B5B5B501DEDEDE02C6C6C601ADADAD019C9C9C01CECECE01BDBDBD019C9C9C01 + DEDEDE01B5B5B5019C9C9C01DEDEDE01BDBDBD01A5A5A501ADADAD01D6D6D601 + DEDEDE029C9C9C01BDBDBD01DEDEDE02D6D6D601A5A5A501D6D6D601DEDEDE05 + 9C9C9C01B5B5B501BDBDBD0194949402CECECE01A5A5A502D6D6D601A5A5A501 + C6C6C60194949401B5B5B501BDBDBD01A5A5A501C6C6C601ADADAD019C9C9C01 + A5A5A501B5B5B5019C9C9C01B5B5B501DEDEDE06CECECE01D6D6D601BDBDBD01 + 9C9C9C01B5B5B5019C9C9C02D6D6D601C6C6C60194949401B5B5B501BDBDBD01 + 9C9C9C01A5A5A501B5B5B5019C9C9C01BDBDBD01ADADAD01BDBDBD019C9C9C01 + A5A5A501CECECE01ADADAD019C9C9C01ADADAD019C9C9C01ADADAD01CECECE02 + DEDEDE02CECECE019C9C9C02A5A5A501B5B5B5019C9C9C01D6D6D601DEDEDE01 + B5B5B501CECECE02B5B5B50294949401BDBDBD01B5B5B502ADADAD01B5B5B501 + A5A5A501B5B5B501DEDEDE01ADADAD01C6C6C601DEDEDE01BDBDBD01B5B5B501 + 94949401ADADAD01A5A5A501B5B5B501DEDEDE019C9C9C01ADADAD01BDBDBD01 + D6D6D601DEDEDE06BDBDBD019C9C9C01DEDEDE01CECECE019C9C9C01BDBDBD02 + B5B5B501DEDEDE01B5B5B5019C9C9C01DEDEDE07C6C6C601ADADAD0294949401 + B5B5B5029C9C9C01B5B5B501CECECE02DEDEDE02CECECE01D6D6D601C6C6C601 + A5A5A501D6D6D601B5B5B501ADADAD01BDBDBD0294949401CECECE01B5B5B501 + 94949401DEDEDE01D6D6D601DEDEDE02CECECE02BDBDBD019C9C9C01A5A5A501 + 94949401BDBDBD01DEDEDE01ADADAD01BDBDBD0194949401ADADAD01A5A5A501 + B5B5B501BDBDBD01ADADAD01CECECE01BDBDBD01A5A5A50194949401B5B5B501 + ADADAD02A5A5A503ADADAD01B5B5B501CECECE01A5A5A501C6C6C601B5B5B501 + A5A5A5019C9C9C01ADADAD02A5A5A501CECECE01DEDEDE05C6C6C6019C9C9C02 + A5A5A504ADADAD01A5A5A501BDBDBD0194949401BDBDBD0194949401BDBDBD01 + 94949401B5B5B5019C9C9C01B5B5B5019C9C9C01BDBDBD019C9C9C01B5B5B502 + CECECE01DEDEDE04C6C6C601CECECE01DEDEDE039C9C9C01BDBDBD01D6D6D601 + BDBDBD01C6C6C601ADADAD01B5B5B501BDBDBD01C6C6C601ADADAD01CECECE01 + B5B5B501A5A5A501D6D6D601949494019C9C9C01D6D6D601BDBDBD01CECECE01 + DEDEDE0194949401B5B5B501DEDEDE03C6C6C601D6D6D601A5A5A501ADADAD01 + DEDEDE039C9C9C01B5B5B501DEDEDE01D6D6D601ADADAD02CECECE01B5B5B502 + 9C9C9C01DEDEDE01B5B5B5019C9C9C01BDBDBD02C6C6C6019C9C9C01C6C6C601 + DEDEDE02A5A5A501BDBDBD01DEDEDE02CECECE01B5B5B501CECECE01B5B5B501 + 9C9C9C01D6D6D601DEDEDE02B5B5B5019C9C9C01D6D6D601B5B5B501ADADAD01 + 9C9C9C02949494019C9C9C0194949401DEDEDE01B5B5B501ADADAD0194949403 + 9C9C9C01A5A5A501C6C6C602A5A5A501DEDEDE03BDBDBD0194949401DEDEDE01 + CECECE01A5A5A501BDBDBD01DEDEDE02B5B5B5019C9C9C01B5B5B5019C9C9C01 + CECECE01DEDEDE03BDBDBD019C9C9C01DEDEDE01B5B5B50194949401DEDEDE04 + B5B5B501A5A5A501BDBDBD0194949401DEDEDE0394949401B5B5B501DEDEDE02 + 9C9C9C01B5B5B501DEDEDE02BDBDBD02A5A5A501C6C6C601DEDEDE03A5A5A501 + D6D6D601ADADAD01C6C6C6019C9C9C01B5B5B501ADADAD01BDBDBD01DEDEDE03 + 9C9C9C01B5B5B5019C9C9C01DEDEDE02CECECE01ADADAD01C6C6C601DEDEDE02 + B5B5B50194949401DEDEDE02B5B5B501ADADAD01C6C6C601DEDEDE04C6C6C601 + D6D6D60194949401BDBDBD019C9C9C01BDBDBD01CECECE02DEDEDE049C9C9C02 + CECECE01DEDEDE01B5B5B5019C9C9C01DEDEDE03BDBDBD019C9C9C01DEDEDE01 + C6C6C601ADADAD01C6C6C601B5B5B502BDBDBD01B5B5B503CECECE01B5B5B502 + A5A5A501D6D6D601BDBDBD01B5B5B502BDBDBD01B5B5B502BDBDBD01ADADAD01 + 9C9C9C01DEDEDE01B5B5B50194949401DEDEDE03D6D6D601B5B5B501C6C6C601 + 949494019C9C9C01949494029C9C9C0194949404C6C6C601CECECE01A5A5A501 + B5B5B501DEDEDE01949494019C9C9C0494949403BDBDBD01B5B5B501A5A5A501 + B5B5B501DEDEDE02D6D6D601DEDEDE019C9C9C01ADADAD0194949401CECECE01 + DEDEDE08C6C6C601ADADAD019C9C9C01DEDEDE09B5B5B501BDBDBD01ADADAD01 + BDBDBD01DEDEDE01C6C6C602DEDEDE01949494019C9C9C01CECECE01DEDEDE04 + A5A5A501C6C6C601DEDEDE03A5A5A502BDBDBD01C6C6C601DEDEDE03A5A5A501 + C6C6C601DEDEDE04A5A5A501ADADAD01B5B5B501DEDEDE019C9C9C01D6D6D601 + 94949401ADADAD01BDBDBD02B5B5B502ADADAD01A5A5A5029C9C9C02DEDEDE01 + B5B5B501A5A5A501CECECE01B5B5B5019C9C9C01CECECE01C6C6C6019C9C9C01 + A5A5A503BDBDBD01B5B5B503C6C6C6019C9C9C01BDBDBD01DEDEDE0194949401 + A5A5A5019C9C9C01949494019C9C9C02A5A5A502BDBDBD01B5B5B502C6C6C601 + BDBDBD02B5B5B501DEDEDE01CECECE019C9C9C0194949401D6D6D601B5B5B504 + A5A5A502949494019C9C9C0294949401B5B5B5029C9C9C01CECECE01DEDEDE09 + CECECE01A5A5A501B5B5B501DEDEDE03CECECE01A5A5A502DEDEDE0AB5B5B502 + } + face.fade_pos.count = 3 + face.fade_pos.items = ( + 0 + 0.5 + 1 + ) + face.fade_color.count = 3 + face.fade_color.items = ( + 16777215 + 0 + 16777215 + ) + face.localprops = [fal_options, fal_faopacity] + taborder = 7 + bounds_x = 400 + bounds_y = 168 + bounds_cx = 132 + bounds_cy = 52 + statfile = tstatfile1 + reffontheight = 14 + end + object buttonface1: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612731 + -1610612732 + ) + template.fade_direction = gd_down + left = 16 + top = 72 + end + object mainmenu1: tmainmenu + popupframetemplate = popupframe + popupitemframetemplate = popupitemframe + popupitemfacetemplate = buttonface2 + popupitemframetemplateactive = popupitemframe + popupitemfacetemplateactive = buttonface2 + frametemplate = mainmenuframe + facetemplate = buttonface1 + itemframetemplate = mainmenuitemframe + itemfacetemplate = buttonface2 + itemframetemplateactive = mainmenuitemframe + itemfacetemplateactive = buttonface2 + menu.submenu.count = 4 + menu.submenu.items = < + item + submenu.count = 4 + submenu.items = < + item + submenu.count = 6 + submenu.items = < + item + caption = 'ewrgqeg qewr ' + state = [as_localcaption] + end + item + caption = 'qer qwetr' + state = [as_localcaption] + end + item + caption = 'uzkme56are' + state = [as_localcaption] + end + item + caption = 'w435 ertrh46' + state = [as_localcaption] + end + item + caption = '4w5gbsgfdbsw' + state = [as_localcaption] + end + item + caption = 'aerga aerg345 ' + state = [as_localcaption] + end> + caption = '&1111111111' + state = [as_localcaption] + end + item + caption = '&22222222' + state = [as_localcaption] + end + item + caption = '&333333333' + state = [as_localcaption] + end + item + caption = '&4444444444' + state = [as_localcaption] + end> + caption = '&Aaaaaaa' + state = [as_localcaption] + end + item + caption = '&Bbbbbb' + state = [as_localcaption] + end + item + caption = '&Cccccccc' + state = [as_localcaption] + end + item + caption = '&Ddddd' + state = [as_localcaption] + end> + left = 24 + top = 40 + end + object mainmenuframe: tframecomp + template.leveli = 1 + left = 144 + top = 36 + end + object mainmenuitemframe: tframecomp + template.levelo = -1 + template.leveli = 1 + template.framewidth = 2 + template.colorframe = -2147483645 + template.framei_left = 2 + template.framei_top = 2 + template.framei_right = 2 + template.framei_bottom = 2 + left = 288 + top = 36 + end + object buttonface2: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612731 + -1610612732 + ) + template.fade_direction = gd_up + left = 16 + top = 104 + end + object popupitemframe: tframecomp + template.levelo = -1 + template.leveli = 1 + template.framei_top = 1 + template.framei_bottom = 1 + left = 442 + top = 63 + end + object popupframe: tframecomp + template.levelo = 2 + template.framewidth = 1 + left = 443 + top = 35 + end + object tstatfile1: tstatfile + filename = 'status.sta' + left = 19 + top = 195 + end + object imli: timagelist + width = 4 + height = 4 + options = [] + count = 51 + left = 448 + top = 112 + image = { + 00000000000000002000000020000000200B0000000000000000000000000000 + 0000000000000000000000000000000000000000D5E7E901CEDFE401CADDE101 + C9DCE001CADDE101743C0001FCFDFD02CCDEE3017E4D1601CAC7BF01D6DFE201 + D5DEE104CDD7DB01BDBDB6017E4D1601E6F1F301DAE2E401D4DDE001743C0001 + E2EEF101CADDE101CBDEE201CEDFE401D5E7E901C9DCE004CEDFE401D0E1E601 + A8957A0183572501CADDE101743C0001FCFDFD02CFE1E501A087660193714A01 + B4AEA301C5D0D604B6B7B101906E4801A28B6A01EBF4F501DAE2E401D4DDE001 + 743C0001E2EEF1017E4D1601A0886701D2E4E802743C0004CBDEE201A8957A01 + A27D5501DDCFC001CADDE101743C0001FCFDFD02D4E6E901D8E9EC01AA997D01 + 83572501743C00047E4D1601A48C6C01EAF4F401EEF6F701DAE2E401D4DDE001 + 743C0001E2EEF101E8DFD501A27D5501A9957B01D5E7E901FFFFFF04CBDEE201 + 83572501DCCEBF01FEFEFE01CADDE101743C0001FCFDFD02DAEAED01DFEDEF01 + E7F1F301EDF5F601F0F6F804F2F7F801F2F8F901F1F7F801DEEDEF01DAE2E401 + D4DDE001743C0001E2EEF101FDFEFE01DBCEBF0183572501DAEAED01FEFEFE04 + D5E7E901CEDFE401CADDE101C9DCE001CADDE101743C0001F5D3BA01F6D3BA01 + CCDEE3017E4D1601E4AD89087E4D1601E6F1F301E4AD8902743C0001E2EEF101 + CADDE101CBDEE201CEDFE401D5E7E901C9DCE004CEDFE401D0E1E601A8957A01 + 83572501CADDE101743C0001F5D3BA01F6D3BA01CFE1E501A0876601854D2701 + C17D4D01EE826905854D2701A28B6A01EBF4F501E4AD8902743C0001E2EEF101 + 7E4D1601A0886701D2E4E802743C0004CBDEE201A8957A01854D2701FFE7CE01 + CADDE101743C0001F5D3BA01F6D3BA01D4E6E901D8E9EC01AA997D0183572501 + 743C00047E4D1601A48C6C01EAF4F401EEF6F701E4AD8902743C0001E2EEF101 + FFE7CE01854D2701A9957B01D5E7E901FFE7CE04CBDEE20183572501F6D4BC02 + CADDE101743C0001F5D3BA01F6D3BA01DAEAED01DFEDEF01E7F1F301EDF5F601 + EFF6F704F2F7F801F2F8F901F1F7F801DEEDEF01E4AD8902743C0001E2EEF101 + F6D4BC0283572501DAEAED01F6D4BC04D5E7E901CEDFE401CADDE101C9DCE001 + CBDEE201743C0001CFD8DA01D7DEE001CCDEE3017E4D1601C7C5BC01DEE6E601 + E3E9EA04DAD3CA01D2CEC4017E4D1601E6F1F301DFE5E602743C0001E2EEF101 + CADDE101CBDEE201CEDFE401D5E7E901C9DCE004CEDFE401D0E1E601A8957A01 + 83572501CBDEE201743C0001CFD8DA01D7DEE001CFE1E501A087660198754D01 + CBC1B201EEF1F204DAD3CA019B774F01A28B6A01EBF4F501DFE5E602743C0001 + E2EEF1017E4D1601A0886701D2E4E802743C0004CBDEE201A8957A018E6D4601 + ACA89D01CBDEE201743C0001CFD8DA01D7DEE001D4E6E901D8E9EC01AA997D01 + 83572501743C00047E4D1601A48C6C01EAF4F401EEF6F701DFE5E602743C0001 + E2EEF101B7B7B10192704901A9957B01D5E7E901C1CCD104CBDEE20183572501 + B1ABA001C6D0D601CBDEE201743C0001CFD8DA01D7DEE001DAEAED01DFEDEF01 + E7F1F301EDF5F601F0F7F804F2F7F801F2F8F901F1F7F801DEEDEF01DFE5E602 + 743C0001E2EEF101CED7DB01BDB5A90183572501DAEAED01CFD8DC04CFE3E501 + BBCED501B2C8D001B1C7CD01B2C8D001743C00019ADFFE0179D2FC01B8CCD401 + 7D4C140149B5EF0130B2F80130B3F80430B2F80147B5ED017D4C1401F5F9FA01 + 33B4F80135B4F801743C0001EEF5F701B2C8D001B6CBD101BBCED501CFE3E501 + A2BBC404BBCED501C8D9E1019F86650182542201B2C8D001743C00019ADFFE01 + 79D2FC01BFD2DA01997B5601718684010097E5066F8483019D825E01FAFCFC01 + 33B4F80135B4F801743C0001EEF5F7017D4C1401997C5701CCDFE301C6DBE001 + 743C0004B6CBD1019F866501A19E8D01D2E8EF01B2C8D001743C00019ADFFE01 + 79D2FC01CCE0E301D8E9EC01A28B6A0182542201743C00047D4C14019F846101 + F0F8F801FCFDFE0133B4F80135B4F801743C0001EEF5F701D3EDF801A19E8D01 + A0856501CFE3E501CFF0FF04B6CBD10182542201ADDCEE0179D2FC01B2C8D001 + 743C00019ADFFE0179D2FC01DCECEF01EAF3F401F6F9FB01FBFDFD01FFFFFF04 + FEFEFE02FDFEFE01E8F2F40133B4F80135B4F801743C0001EEF5F70179D2FC01 + ADDCEE0182542201DEECEF0189D8FD04CFE3E501BBCED501B2C8D001B1C7CD01 + B2C8D001743C00019ADFFE0179D2FC01B8CCD4017D4C140149B5EF0130B2F801 + 30B3F80430B2F80147B5ED017D4C1401F5F9FA0133B4F80135B4F801743C0001 + EEF5F701B2C8D001B6CBD101BBCED501CFE3E501A2BBC404BBCED501C8D9E101 + 9F86650182542201B2C8D001743C00019ADFFE0179D2FC01BFD2DA01997B5601 + 718684010097E5066F8483019D825E01FAFCFC0133B4F80135B4F801743C0001 + EEF5F7017D4C1401997C5701CCDFE301C6DBE001743C0004B6CBD1019F866501 + A19E8D01D2E8EF01B2C8D001743C00019ADFFE0179D2FC01CCE0E301D8E9EC01 + A28B6A0182542201743C00047D4C14019F846101F0F8F801FCFDFE0133B4F801 + 35B4F801743C0001EEF5F701D3EDF801A19E8D01A0856501CFE3E501CFF0FF04 + B6CBD10182542201ADDCEE0179D2FC01B2C8D001743C00019ADFFE0179D2FC01 + DCECEF01EAF3F401F6F9FB01FBFDFD01FFFFFF04FEFEFE02FDFEFE01E8F2F401 + 33B4F80135B4F801743C0001EEF5F70179D2FC01ADDCEE0182542201DEECEF01 + 89D8FD04D5E7E901CEDFE401CADDE101C9DCE001CBDEE201743C0001CFD8DA01 + D7DEE001CCDEE3017E4D1601C7C5BC01DEE6E601E3E9EA04DAD3CA01D2CEC401 + 7E4D1601E6F1F301DFE5E602743C0001E2EEF101CADDE101CBDEE201CEDFE401 + D5E7E901C9DCE004CEDFE401D0E1E601A8957A0183572501CBDEE201743C0001 + CFD8DA01D7DEE001CFE1E501A087660198754D01CBC1B201EEF1F204DAD3CA01 + 9B774F01A28B6A01EBF4F501DFE5E602743C0001E2EEF1017E4D1601A0886701 + D2E4E802743C0004CBDEE201A8957A018E6D4601ACA89D01CBDEE201743C0001 + CFD8DA01D7DEE001D4E6E901D8E9EC01AA997D0183572501743C00047E4D1601 + A48C6C01EAF4F401EEF6F701DFE5E602743C0001E2EEF101B7B7B10192704901 + A9957B01D5E7E901C1CCD104CBDEE20183572501B1ABA001C6D0D601CBDEE201 + 743C0001CFD8DA01D7DEE001DAEAED01DFEDEF01E7F1F301EDF5F601F0F7F804 + F2F7F801F2F8F901F1F7F801DEEDEF01DFE5E602743C0001E2EEF101CED7DB01 + BDB5A90183572501DAEAED01CFD8DC04C9DCE004FFFFFF08C9DCE004CADDE101 + CBDEE201CEDFE401D5E7E901E4AD8902743C0001E2EEF101E4AD89027E4D1601 + E6F1F301E4AD8904743C0004FFFFFF08743C00047E4D1601A0886701D2E4E802 + E4AD8902743C0001E2EEF101EE826901854D2701A28B6A01EBF4F501EE826904 + FFE7CE04FFFFFF08FFE7CE05854D2701A9957B01D5E7E901E4AD8902743C0001 + E2EEF1017E4D1601A48C6C01EAF4F401EEF6F701743C0004F6D4BC04FFFFFF08 + F6D4BC0683572501DAEAED01E4AD8902743C0001E2EEF101F2F7F801F2F8F901 + F1F7F801DEEDEF01EFF6F704CCDEE3017E4D1601E4AD8902CADDE101743C0001 + F5D3BA01F6D3BA01D5E7E901CEDFE401CADDE101C9DCE001D0D0D002CECECE01 + 7777770121212101060606012525250190909001D0D0D00200000001D0D0D003 + 00000001D0D0D00300000001D0D0D001CFE1E501A0876601854D2701C17D4D01 + CADDE101743C0001F5D3BA01F6D3BA01CEDFE401D0E1E601A8957A0183572501 + D0D0D014D4E6E901D8E9EC01AA997D0183572501CADDE101743C0001F5D3BA01 + F6D3BA01CBDEE201A8957A01854D2701FFE7CE01D0D0D014DAEAED01DFEDEF01 + E7F1F301EDF5F601CADDE101743C0001F5D3BA01F6D3BA01CBDEE20183572501 + F6D4BC02D0D0D009FFFFFF0180808001D0D0D009 + } + end +end diff --git a/mseide-msegui/apps/facedemo/main.pas b/mseide-msegui/apps/facedemo/main.pas new file mode 100644 index 0000000..2ad2e41 --- /dev/null +++ b/mseide-msegui/apps/facedemo/main.pas @@ -0,0 +1,34 @@ +unit main; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegui,mseclasses,mseforms,msemenus,msedataedits,msestat,msestatfile,msebitmap, + mseapplication,mseedit,mseglob,mseguiglob,mseificomp,mseificompglob,mseifiglob, + msestream,msestrings,msetypes,sysutils; + +type + tmainfo = class(tmseform) + buttonface1: tfacecomp; + mainmenu1: tmainmenu; + mainmenuframe: tframecomp; + mainmenuitemframe: tframecomp; + buttonface2: tfacecomp; + popupitemframe: tframecomp; + popupframe: tframecomp; + tstatfile1: tstatfile; + tstringedit1: tstringedit; + tstringedit2: tstringedit; + tstringedit3: tstringedit; + tstringedit4: tstringedit; + tstringedit5: tstringedit; + tstringedit6: tstringedit; + tstringedit7: tstringedit; + tstringedit8: tstringedit; + imli: timagelist; + end; +var + mainfo: tmainfo; +implementation +uses + main_mfm; +end. diff --git a/mseide-msegui/apps/facedemo/main_mfm.pas b/mseide-msegui/apps/facedemo/main_mfm.pas new file mode 100644 index 0000000..c27d404 --- /dev/null +++ b/mseide-msegui/apps/facedemo/main_mfm.pas @@ -0,0 +1,5367 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..106987] of byte end = + (size: 106988; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,58,8, + 98,111,117,110,100,115,95,121,3,17,1,9,98,111,117,110,100,115,95,99, + 120,3,126,2,9,98,111,117,110,100,115,95,99,121,3,30,1,22,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,22,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 101,118,101,108,105,2,1,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,102,114,97,109,101,119,105,100,116,104,2,1,26,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,99,111,108,111,114,102,114, + 97,109,101,4,139,198,199,0,26,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,14,102, + 114,108,95,102,114,97,109,101,119,105,100,116,104,14,102,114,108,95,99,111, + 108,111,114,102,114,97,109,101,0,27,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,30, + 99,111,110,116,97,105,110,101,114,46,102,97,99,101,46,105,109,97,103,101, + 46,97,108,105,103,110,109,101,110,116,11,8,97,108,95,116,105,108,101,100, + 0,28,99,111,110,116,97,105,110,101,114,46,102,97,99,101,46,105,109,97, + 103,101,46,111,112,97,99,105,116,121,4,127,127,127,0,26,99,111,110,116, + 97,105,110,101,114,46,102,97,99,101,46,105,109,97,103,101,46,105,109,97, + 103,101,10,108,10,1,0,0,0,0,0,0,0,0,0,150,0,0,0,150, + 0,0,0,56,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,216, + 216,216,1,219,219,219,1,218,218,218,2,219,219,219,3,217,217,217,1,218, + 218,218,1,255,255,255,1,218,218,218,2,169,169,169,1,217,217,217,1,216, + 216,216,1,169,169,169,1,218,218,218,1,219,219,219,1,217,217,217,1,215, + 215,215,1,217,217,217,1,220,220,220,1,216,216,216,1,219,219,219,1,216, + 216,216,1,219,219,219,1,221,221,221,1,216,216,216,1,219,219,219,1,217, + 217,217,1,254,254,254,1,220,220,220,1,217,217,217,1,219,219,219,1,218, + 218,218,2,217,217,217,2,220,220,220,1,219,219,219,1,218,218,218,3,220, + 220,220,1,218,218,218,2,220,220,220,1,218,218,218,9,219,219,219,1,218, + 218,218,1,217,217,217,2,218,218,218,2,219,219,219,1,217,217,217,2,219, + 219,219,2,215,215,215,1,221,221,221,1,217,217,217,2,219,219,219,1,218, + 218,218,1,217,217,217,1,218,218,218,1,216,216,216,1,221,221,221,1,219, + 219,219,1,218,218,218,1,217,217,217,1,219,219,219,1,254,254,254,2,255, + 255,255,1,167,167,167,1,219,219,219,1,255,255,255,1,218,218,218,1,255, + 255,255,1,253,253,253,1,218,218,218,1,167,167,167,2,255,255,255,1,254, + 254,254,1,255,255,255,1,216,216,216,1,171,171,171,1,217,217,217,2,218, + 218,218,1,255,255,255,1,217,217,217,1,169,169,169,1,216,216,216,1,220, + 220,220,1,216,216,216,1,253,253,253,1,255,255,255,1,218,218,218,1,217, + 217,217,2,255,255,255,1,216,216,216,1,218,218,218,1,219,219,219,1,218, + 218,218,1,217,217,217,1,219,219,219,1,218,218,218,9,220,220,220,1,167, + 167,167,1,165,165,165,1,169,169,169,1,217,217,217,1,219,219,219,1,217, + 217,217,1,218,218,218,15,221,221,221,1,216,216,216,1,218,218,218,1,221, + 221,221,1,213,213,213,2,219,219,219,2,218,218,218,1,255,255,255,1,216, + 216,216,1,219,219,219,3,217,217,217,1,218,218,218,2,215,215,215,1,218, + 218,218,1,223,223,223,1,219,219,219,1,218,218,218,3,219,219,219,1,220, + 220,220,1,212,212,212,1,223,223,223,1,218,218,218,1,168,168,168,1,255, + 255,255,1,215,215,215,1,218,218,218,1,219,219,219,1,218,218,218,1,217, + 217,217,1,220,220,220,2,215,215,215,2,217,217,217,1,216,216,216,1,219, + 219,219,1,217,217,217,2,216,216,216,1,217,217,217,1,218,218,218,9,216, + 216,216,1,219,219,219,1,221,221,221,1,220,220,220,1,216,216,216,1,221, + 221,221,1,214,214,214,1,220,220,220,1,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,1,218,218,218,1,217,217,217,1,218,218,218,1,220, + 220,220,2,218,218,218,1,220,220,220,1,218,218,218,1,215,215,215,1,217, + 217,217,1,215,215,215,1,222,222,222,1,216,216,216,1,255,255,255,2,252, + 252,252,1,218,218,218,1,255,255,255,1,253,253,253,2,252,252,252,1,255, + 255,255,2,170,170,170,1,168,168,168,1,254,254,254,1,255,255,255,1,251, + 251,251,1,218,218,218,1,220,220,220,1,216,216,216,1,223,223,223,1,217, + 217,217,1,253,253,253,1,218,218,218,1,167,167,167,1,217,217,217,1,218, + 218,218,1,219,219,219,1,255,255,255,1,250,250,250,1,218,218,218,1,219, + 219,219,2,252,252,252,1,255,255,255,1,218,218,218,1,215,215,215,1,219, + 219,219,1,218,218,218,1,217,217,217,1,218,218,218,9,219,219,219,1,168, + 168,168,2,171,171,171,1,167,167,167,2,219,219,219,1,217,217,217,1,218, + 218,218,14,217,217,217,1,218,218,218,1,217,217,217,2,220,220,220,1,222, + 222,222,1,220,220,220,1,217,217,217,1,218,218,218,1,220,220,220,1,255, + 255,255,1,216,216,216,2,254,254,254,1,224,224,224,1,215,215,215,1,219, + 219,219,1,217,217,217,1,174,174,174,1,212,212,212,1,218,218,218,1,169, + 169,169,1,216,216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,221, + 221,221,1,216,216,216,1,213,213,213,1,221,221,221,1,218,218,218,2,217, + 217,217,1,220,220,220,1,168,168,168,1,219,219,219,1,218,218,218,1,215, + 215,215,1,221,221,221,2,219,219,219,1,217,217,217,1,220,220,220,1,217, + 217,217,1,221,221,221,1,220,220,220,1,217,217,217,1,218,218,218,9,219, + 219,219,1,217,217,217,1,215,215,215,1,216,216,216,1,218,218,218,1,217, + 217,217,1,220,220,220,1,215,215,215,1,216,216,216,1,220,220,220,1,215, + 215,215,1,218,218,218,2,220,220,220,1,214,214,214,1,217,217,217,1,215, + 215,215,1,218,218,218,3,220,220,220,1,216,216,216,1,222,222,222,1,213, + 213,213,1,219,219,219,1,216,216,216,1,252,252,252,1,255,255,255,1,218, + 218,218,1,253,253,253,1,223,223,223,1,218,218,218,1,253,253,253,1,255, + 255,255,1,216,216,216,2,220,220,220,1,216,216,216,2,255,255,255,1,219, + 219,219,1,217,217,217,1,219,219,219,1,214,214,214,1,217,217,217,1,255, + 255,255,1,221,221,221,1,168,168,168,2,219,219,219,1,218,218,218,1,216, + 216,216,1,221,221,221,1,217,217,217,2,255,255,255,1,253,253,253,2,220, + 220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,218,218,218,8,216,216,216,1,220,220,220,1,169,169,169,1,165, + 165,165,1,166,166,166,1,170,170,170,1,167,167,167,1,170,170,170,1,218, + 218,218,15,220,220,220,1,218,218,218,1,216,216,216,1,219,219,219,1,216, + 216,216,1,212,212,212,1,218,218,218,1,217,217,217,1,218,218,218,1,169, + 169,169,1,217,217,217,1,221,221,221,1,216,216,216,1,214,214,214,1,221, + 221,221,1,214,214,214,1,221,221,221,1,215,215,215,1,220,220,220,1,221, + 221,221,1,219,219,219,1,218,218,218,2,220,220,220,1,216,216,216,1,168, + 168,168,1,255,255,255,1,219,219,219,1,217,217,217,1,220,220,220,1,218, + 218,218,2,170,170,170,1,166,166,166,1,215,215,215,1,219,219,219,2,217, + 217,217,1,215,215,215,1,220,220,220,1,219,219,219,1,217,217,217,1,215, + 215,215,1,217,217,217,2,216,216,216,1,218,218,218,9,216,216,216,1,219, + 219,219,1,220,220,220,2,218,218,218,2,217,217,217,1,221,221,221,1,218, + 218,218,1,217,217,217,1,219,219,219,2,218,218,218,2,220,220,220,1,219, + 219,219,1,217,217,217,1,218,218,218,2,220,220,220,1,214,214,214,1,221, + 221,221,1,219,219,219,1,220,220,220,1,216,216,216,1,219,219,219,1,216, + 216,216,1,221,221,221,1,215,215,215,1,222,222,222,1,216,216,216,1,217, + 217,217,1,218,218,218,1,255,255,255,1,254,254,254,1,214,214,214,1,222, + 222,222,1,216,216,216,1,219,219,219,1,217,217,217,3,221,221,221,2,219, + 219,219,1,254,254,254,1,218,218,218,1,216,216,216,1,170,170,170,1,167, + 167,167,1,168,168,168,1,219,219,219,1,217,217,217,1,220,220,220,1,217, + 217,217,1,219,219,219,1,255,255,255,1,253,253,253,1,252,252,252,1,218, + 218,218,1,221,221,221,1,216,216,216,1,220,220,220,1,218,218,218,9,220, + 220,220,1,217,217,217,2,221,221,221,1,168,168,168,1,171,171,171,1,166, + 166,166,1,216,216,216,1,218,218,218,14,217,217,217,1,216,216,216,1,220, + 220,220,1,218,218,218,1,217,217,217,1,222,222,222,1,220,220,220,1,216, + 216,216,1,220,220,220,1,167,167,167,2,219,219,219,1,217,217,217,1,222, + 222,222,1,217,217,217,1,216,216,216,1,255,255,255,1,220,220,220,1,219, + 219,219,1,255,255,255,1,164,164,164,1,217,217,217,1,219,219,219,1,216, + 216,216,1,217,217,217,1,219,219,219,1,215,215,215,1,219,219,219,1,217, + 217,217,1,215,215,215,1,218,218,218,1,217,217,217,1,255,255,255,1,215, + 215,215,1,220,220,220,1,217,217,217,1,221,221,221,1,217,217,217,1,216, + 216,216,1,221,221,221,1,214,214,214,1,220,220,220,1,217,217,217,1,221, + 221,221,1,219,219,219,1,218,218,218,1,220,220,220,2,218,218,218,8,222, + 222,222,1,214,214,214,1,217,217,217,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,168,168,168,1,217,217,217,1,218,218,218,1,219, + 219,219,1,216,216,216,2,218,218,218,1,169,169,169,1,217,217,217,1,220, + 220,220,1,218,218,218,1,214,214,214,1,220,220,220,2,215,215,215,1,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,1,219,219,219,1,216, + 216,216,1,218,218,218,1,217,217,217,1,216,216,216,1,170,170,170,1,253, + 253,253,1,218,218,218,1,220,220,220,1,218,218,218,3,219,219,219,1,217, + 217,217,1,221,221,221,1,218,218,218,1,163,163,163,1,221,221,221,1,218, + 218,218,1,254,254,254,1,255,255,255,1,220,220,220,1,216,216,216,1,168, + 168,168,1,216,216,216,2,217,217,217,1,220,220,220,1,216,216,216,1,219, + 219,219,1,253,253,253,1,255,255,255,2,254,254,254,1,216,216,216,1,219, + 219,219,1,215,215,215,1,220,220,220,1,218,218,218,9,217,217,217,1,219, + 219,219,1,214,214,214,1,219,219,219,1,216,216,216,1,220,220,220,2,218, + 218,218,16,220,220,220,1,215,215,215,1,216,216,216,1,218,218,218,1,215, + 215,215,1,220,220,220,1,255,255,255,1,214,214,214,1,171,171,171,1,219, + 219,219,1,165,165,165,1,167,167,167,1,170,170,170,1,169,169,169,1,218, + 218,218,1,216,216,216,2,219,219,219,3,218,218,218,1,219,219,219,1,255, + 255,255,1,220,220,220,1,218,218,218,1,219,219,219,1,221,221,221,1,217, + 217,217,1,219,219,219,1,253,253,253,1,255,255,255,1,166,166,166,1,221, + 221,221,1,214,214,214,1,216,216,216,1,219,219,219,2,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,217,217,217,2,219, + 219,219,1,215,215,215,1,218,218,218,8,216,216,216,1,220,220,220,1,217, + 217,217,2,221,221,221,1,218,218,218,1,215,215,215,1,217,217,217,1,219, + 219,219,1,218,218,218,1,217,217,217,1,219,219,219,1,215,215,215,1,221, + 221,221,1,216,216,216,2,215,215,215,1,219,219,219,2,218,218,218,1,217, + 217,217,1,218,218,218,1,217,217,217,1,220,220,220,1,219,219,219,1,218, + 218,218,2,216,216,216,1,219,219,219,1,221,221,221,1,217,217,217,1,218, + 218,218,2,166,166,166,1,217,217,217,1,166,166,166,1,216,216,216,1,222, + 222,222,1,218,218,218,1,219,219,219,1,167,167,167,1,169,169,169,2,167, + 167,167,2,217,217,217,1,255,255,255,1,254,254,254,1,255,255,255,1,219, + 219,219,3,223,223,223,1,214,214,214,1,169,169,169,1,167,167,167,2,219, + 219,219,1,254,254,254,1,255,255,255,1,219,219,219,1,220,220,220,1,216, + 216,216,1,219,219,219,1,218,218,218,8,220,220,220,1,217,217,217,1,220, + 220,220,1,218,218,218,1,216,216,216,1,169,169,169,1,217,217,217,1,216, + 216,216,1,218,218,218,14,219,219,219,1,216,216,216,1,218,218,218,1,219, + 219,219,1,222,222,222,1,215,215,215,1,220,220,220,1,254,254,254,1,255, + 255,255,1,219,219,219,1,216,216,216,1,218,218,218,1,219,219,219,1,218, + 218,218,1,220,220,220,1,166,166,166,1,168,168,168,2,255,255,255,1,220, + 220,220,1,215,215,215,1,218,218,218,1,217,217,217,1,218,218,218,1,219, + 219,219,1,216,216,216,2,219,219,219,1,214,214,214,1,218,218,218,4,216, + 216,216,1,217,217,217,1,219,219,219,1,220,220,220,1,217,217,217,2,219, + 219,219,1,220,220,220,1,211,211,211,1,223,223,223,1,216,216,216,1,217, + 217,217,1,218,218,218,1,221,221,221,1,220,220,220,1,218,218,218,11,217, + 217,217,2,255,255,255,1,215,215,215,1,219,219,219,1,216,216,216,1,218, + 218,218,1,220,220,220,1,216,216,216,1,255,255,255,1,217,217,217,2,221, + 221,221,1,220,220,220,1,215,215,215,1,218,218,218,1,222,222,222,1,215, + 215,215,1,219,219,219,1,168,168,168,1,166,166,166,1,168,168,168,2,218, + 218,218,2,220,220,220,1,252,252,252,1,215,215,215,1,221,221,221,1,218, + 218,218,1,168,168,168,1,220,220,220,1,221,221,221,1,215,215,215,1,217, + 217,217,1,218,218,218,1,217,217,217,1,218,218,218,1,167,167,167,2,170, + 170,170,1,167,167,167,1,218,218,218,1,221,221,221,1,254,254,254,1,216, + 216,216,1,221,221,221,1,167,167,167,1,215,215,215,1,214,214,214,1,167, + 167,167,1,173,173,173,1,217,217,217,2,219,219,219,1,253,253,253,1,254, + 254,254,1,220,220,220,1,215,215,215,1,221,221,221,1,216,216,216,1,218, + 218,218,8,215,215,215,1,220,220,220,1,215,215,215,1,218,218,218,1,222, + 222,222,1,216,216,216,1,219,219,219,1,220,220,220,1,218,218,218,15,217, + 217,217,1,220,220,220,1,216,216,216,1,218,218,218,1,221,221,221,1,216, + 216,216,1,220,220,220,1,252,252,252,1,218,218,218,1,255,255,255,1,254, + 254,254,1,255,255,255,2,216,216,216,1,220,220,220,1,218,218,218,2,167, + 167,167,1,168,168,168,1,217,217,217,1,220,220,220,1,218,218,218,2,167, + 167,167,1,169,169,169,1,219,219,219,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,1,255,255,255,1,218,218,218,3,219,219,219,1,217, + 217,217,1,218,218,218,1,219,219,219,1,217,217,217,1,167,167,167,1,171, + 171,171,1,218,218,218,1,217,217,217,1,221,221,221,1,217,217,217,3,218, + 218,218,8,220,220,220,1,217,217,217,1,218,218,218,1,220,220,220,1,216, + 216,216,1,217,217,217,1,220,220,220,1,218,218,218,1,219,219,219,2,217, + 217,217,1,219,219,219,1,217,217,217,2,220,220,220,1,217,217,217,2,220, + 220,220,1,217,217,217,2,218,218,218,1,166,166,166,1,169,169,169,1,168, + 168,168,3,218,218,218,1,217,217,217,1,218,218,218,1,220,220,220,2,253, + 253,253,1,219,219,219,1,252,252,252,1,218,218,218,1,217,217,217,1,219, + 219,219,1,220,220,220,1,253,253,253,1,255,255,255,1,219,219,219,1,216, + 216,216,1,221,221,221,1,166,166,166,1,218,218,218,1,219,219,219,1,216, + 216,216,1,219,219,219,1,220,220,220,1,216,216,216,1,217,217,217,1,222, + 222,222,1,215,215,215,1,255,255,255,1,216,216,216,1,255,255,255,1,220, + 220,220,1,215,215,215,1,255,255,255,2,250,250,250,1,223,223,223,1,252, + 252,252,1,255,255,255,1,218,218,218,9,219,219,219,1,216,216,216,1,255, + 255,255,1,217,217,217,1,219,219,219,1,217,217,217,1,218,218,218,16,217, + 217,217,3,219,219,219,2,218,218,218,1,217,217,217,1,219,219,219,1,216, + 216,216,1,219,219,219,1,220,220,220,1,217,217,217,1,255,255,255,1,254, + 254,254,1,255,255,255,1,219,219,219,2,166,166,166,1,219,219,219,1,168, + 168,168,1,218,218,218,1,220,220,220,1,218,218,218,1,169,169,169,1,166, + 166,166,1,218,218,218,1,217,217,217,1,218,218,218,1,217,217,217,1,219, + 219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,216,216,216,1,219, + 219,219,3,215,215,215,1,169,169,169,1,167,167,167,1,171,171,171,1,165, + 165,165,1,218,218,218,5,220,220,220,1,217,217,217,1,221,221,221,1,216, + 216,216,1,218,218,218,2,219,219,219,3,218,218,218,1,217,217,217,1,221, + 221,221,1,214,214,214,1,220,220,220,1,216,216,216,1,220,220,220,2,217, + 217,217,1,218,218,218,1,216,216,216,1,218,218,218,1,219,219,219,2,218, + 218,218,1,216,216,216,1,222,222,222,1,217,217,217,1,219,219,219,1,255, + 255,255,1,219,219,219,1,216,216,216,1,220,220,220,1,167,167,167,1,221, + 221,221,1,217,217,217,2,219,219,219,1,167,167,167,1,170,170,170,1,253, + 253,253,1,168,168,168,1,169,169,169,1,218,218,218,1,217,217,217,1,220, + 220,220,1,167,167,167,1,217,217,217,1,255,255,255,1,216,216,216,1,219, + 219,219,1,218,218,218,1,169,169,169,1,218,218,218,1,217,217,217,1,222, + 222,222,1,167,167,167,1,216,216,216,1,170,170,170,1,216,216,216,1,254, + 254,254,1,255,255,255,1,218,218,218,1,217,217,217,1,220,220,220,1,219, + 219,219,1,218,218,218,1,254,254,254,1,255,255,255,3,253,253,253,1,255, + 255,255,2,217,217,217,1,218,218,218,2,217,217,217,1,221,221,221,1,215, + 215,215,1,220,220,220,1,255,255,255,1,254,254,254,1,216,216,216,1,221, + 221,221,1,217,217,217,1,218,218,218,1,219,219,219,1,218,218,218,1,219, + 219,219,1,217,217,217,1,219,219,219,1,217,217,217,2,221,221,221,1,216, + 216,216,1,217,217,217,2,219,219,219,1,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,1,218,218,218,1,220,220,220,1,221,221,221,1,220, + 220,220,1,216,216,216,2,218,218,218,2,168,168,168,1,219,219,219,1,216, + 216,216,1,218,218,218,1,217,217,217,1,218,218,218,1,222,222,222,1,215, + 215,215,1,254,254,254,1,255,255,255,1,221,221,221,1,218,218,218,3,251, + 251,251,1,255,255,255,1,220,220,220,1,167,167,167,1,220,220,220,1,221, + 221,221,1,213,213,213,1,223,223,223,1,215,215,215,1,218,218,218,1,219, + 219,219,1,216,216,216,1,217,217,217,1,218,218,218,1,219,219,219,1,216, + 216,216,1,255,255,255,2,216,216,216,1,215,215,215,1,221,221,221,1,217, + 217,217,1,218,218,218,2,219,219,219,1,217,217,217,2,215,215,215,1,219, + 219,219,1,218,218,218,3,219,219,219,1,166,166,166,2,219,219,219,1,218, + 218,218,1,216,216,216,1,220,220,220,2,216,216,216,1,217,217,217,3,218, + 218,218,1,222,222,222,1,217,217,217,1,216,216,216,1,218,218,218,1,217, + 217,217,1,172,172,172,1,163,163,163,1,167,167,167,1,217,217,217,1,218, + 218,218,2,254,254,254,1,255,255,255,1,166,166,166,1,221,221,221,1,165, + 165,165,1,219,219,219,1,165,165,165,1,168,168,168,1,167,167,167,2,218, + 218,218,1,217,217,217,1,220,220,220,1,218,218,218,1,219,219,219,1,168, + 168,168,1,216,216,216,1,217,217,217,1,255,255,255,1,219,219,219,1,168, + 168,168,1,164,164,164,1,217,217,217,1,218,218,218,1,214,214,214,1,169, + 169,169,1,172,172,172,1,167,167,167,1,253,253,253,1,220,220,220,1,255, + 255,255,1,218,218,218,1,217,217,217,2,218,218,218,1,216,216,216,1,222, + 222,222,1,253,253,253,1,220,220,220,1,217,217,217,1,255,255,255,1,252, + 252,252,2,219,219,219,1,218,218,218,1,216,216,216,1,255,255,255,3,252, + 252,252,1,253,253,253,1,220,220,220,2,218,218,218,1,216,216,216,1,217, + 217,217,2,218,218,218,1,215,215,215,1,219,219,219,1,215,215,215,1,221, + 221,221,1,216,216,216,1,220,220,220,1,215,215,215,1,221,221,221,1,218, + 218,218,1,220,220,220,1,217,217,217,1,215,215,215,1,219,219,219,1,216, + 216,216,1,217,217,217,1,216,216,216,2,214,214,214,1,220,220,220,1,222, + 222,222,1,214,214,214,1,218,218,218,2,167,167,167,1,223,223,223,1,220, + 220,220,1,217,217,217,1,216,216,216,1,217,217,217,1,218,218,218,1,255, + 255,255,1,216,216,216,1,255,255,255,1,217,217,217,1,218,218,218,1,221, + 221,221,1,255,255,255,2,215,215,215,1,219,219,219,1,218,218,218,1,215, + 215,215,1,221,221,221,1,214,214,214,1,219,219,219,2,216,216,216,1,220, + 220,220,1,218,218,218,1,219,219,219,1,214,214,214,1,255,255,255,4,215, + 215,215,1,167,167,167,1,219,219,219,1,216,216,216,1,217,217,217,1,218, + 218,218,1,217,217,217,1,219,219,219,1,218,218,218,1,217,217,217,1,220, + 220,220,1,216,216,216,1,217,217,217,1,219,219,219,1,170,170,170,1,171, + 171,171,1,219,219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,1,220,220,220,1,217,217,217,2,219, + 219,219,1,216,216,216,1,220,220,220,1,216,216,216,1,171,171,171,1,169, + 169,169,1,167,167,167,1,171,171,171,1,218,218,218,1,255,255,255,3,218, + 218,218,1,169,169,169,1,214,214,214,1,219,219,219,1,255,255,255,2,170, + 170,170,1,217,217,217,1,255,255,255,1,219,219,219,1,216,216,216,1,219, + 219,219,1,255,255,255,1,253,253,253,1,170,170,170,1,219,219,219,1,254, + 254,254,2,253,253,253,1,219,219,219,1,216,216,216,1,224,224,224,1,253, + 253,253,1,255,255,255,2,216,216,216,1,218,218,218,1,220,220,220,1,218, + 218,218,1,212,212,212,1,220,220,220,1,222,222,222,1,218,218,218,1,216, + 216,216,1,222,222,222,1,216,216,216,1,218,218,218,1,217,217,217,1,220, + 220,220,1,219,219,219,1,255,255,255,1,222,222,222,1,216,216,216,1,218, + 218,218,1,221,221,221,1,254,254,254,1,214,214,214,1,217,217,217,1,220, + 220,220,2,218,218,218,1,217,217,217,1,216,216,216,1,218,218,218,1,219, + 219,219,1,218,218,218,2,220,220,220,1,217,217,217,1,168,168,168,1,218, + 218,218,1,221,221,221,1,218,218,218,1,217,217,217,1,218,218,218,1,217, + 217,217,1,218,218,218,1,220,220,220,1,219,219,219,1,220,220,220,1,224, + 224,224,1,221,221,221,1,219,219,219,2,218,218,218,1,220,220,220,1,214, + 214,214,1,255,255,255,1,219,219,219,1,167,167,167,1,171,171,171,1,215, + 215,215,1,217,217,217,1,218,218,218,1,220,220,220,1,215,215,215,1,220, + 220,220,1,217,217,217,1,218,218,218,1,216,216,216,1,222,222,222,1,216, + 216,216,2,217,217,217,1,254,254,254,1,218,218,218,1,216,216,216,1,222, + 222,222,1,219,219,219,1,216,216,216,1,220,220,220,1,219,219,219,1,216, + 216,216,1,219,219,219,1,216,216,216,1,219,219,219,1,218,218,218,1,220, + 220,220,1,217,217,217,2,216,216,216,1,213,213,213,1,219,219,219,2,220, + 220,220,1,219,219,219,1,216,216,216,1,222,222,222,1,217,217,217,1,218, + 218,218,1,220,220,220,1,217,217,217,1,216,216,216,1,219,219,219,1,255, + 255,255,1,254,254,254,1,216,216,216,1,215,215,215,1,218,218,218,1,217, + 217,217,1,221,221,221,1,216,216,216,1,217,217,217,1,219,219,219,2,215, + 215,215,1,218,218,218,1,219,219,219,1,217,217,217,1,220,220,220,1,221, + 221,221,1,252,252,252,1,218,218,218,1,215,215,215,1,222,222,222,1,217, + 217,217,1,215,215,215,1,219,219,219,1,216,216,216,1,255,255,255,1,217, + 217,217,1,255,255,255,1,217,217,217,1,254,254,254,2,252,252,252,2,219, + 219,219,1,216,216,216,2,223,223,223,1,217,217,217,2,220,220,220,1,250, + 250,250,1,222,222,222,1,255,255,255,3,216,216,216,1,220,220,220,1,217, + 217,217,1,254,254,254,2,216,216,216,1,169,169,169,1,170,170,170,1,218, + 218,218,1,169,169,169,1,172,172,172,1,217,217,217,1,218,218,218,1,216, + 216,216,1,220,220,220,1,212,212,212,1,221,221,221,2,215,215,215,1,220, + 220,220,1,165,165,165,1,217,217,217,1,215,215,215,1,218,218,218,1,168, + 168,168,1,217,217,217,1,216,216,216,1,222,222,222,1,218,218,218,1,217, + 217,217,1,216,216,216,1,215,215,215,1,221,221,221,1,222,222,222,1,216, + 216,216,1,219,219,219,1,215,215,215,1,218,218,218,1,215,215,215,1,220, + 220,220,1,216,216,216,1,219,219,219,1,214,214,214,1,217,217,217,1,220, + 220,220,1,218,218,218,2,216,216,216,1,219,219,219,1,216,216,216,2,217, + 217,217,1,215,215,215,1,216,216,216,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,218,218,218,1,253,253,253,1,169,169,169,1,167, + 167,167,1,218,218,218,1,222,222,222,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,1,218,218,218,1,220,220,220,1,216,216,216,2,220, + 220,220,1,218,218,218,2,220,220,220,2,219,219,219,1,215,215,215,1,219, + 219,219,3,216,216,216,1,218,218,218,1,217,217,217,1,220,220,220,1,213, + 213,213,1,218,218,218,1,217,217,217,1,220,220,220,1,218,218,218,2,255, + 255,255,1,217,217,217,1,220,220,220,1,216,216,216,1,218,218,218,1,220, + 220,220,1,215,215,215,1,218,218,218,1,216,216,216,2,220,220,220,1,218, + 218,218,1,217,217,217,1,255,255,255,1,253,253,253,1,222,222,222,2,217, + 217,217,1,219,219,219,1,218,218,218,1,217,217,217,1,220,220,220,1,215, + 215,215,1,218,218,218,1,220,220,220,1,219,219,219,1,218,218,218,1,216, + 216,216,1,219,219,219,1,253,253,253,1,222,222,222,1,217,217,217,2,218, + 218,218,1,167,167,167,1,219,219,219,1,170,170,170,2,254,254,254,1,218, + 218,218,1,215,215,215,1,218,218,218,1,220,220,220,1,253,253,253,1,255, + 255,255,1,218,218,218,1,221,221,221,1,219,219,219,1,218,218,218,1,217, + 217,217,1,168,168,168,1,218,218,218,1,222,222,222,1,218,218,218,1,167, + 167,167,1,215,215,215,2,217,217,217,1,220,220,220,1,168,168,168,1,217, + 217,217,1,219,219,219,1,218,218,218,1,170,170,170,1,215,215,215,1,219, + 219,219,1,215,215,215,1,167,167,167,1,217,217,217,1,218,218,218,2,220, + 220,220,1,218,218,218,1,222,222,222,1,217,217,217,3,219,219,219,1,220, + 220,220,2,222,222,222,1,217,217,217,1,170,170,170,1,253,253,253,1,218, + 218,218,2,220,220,220,1,218,218,218,1,220,220,220,1,217,217,217,1,219, + 219,219,1,215,215,215,1,220,220,220,1,218,218,218,1,216,216,216,1,220, + 220,220,1,255,255,255,1,215,215,215,1,220,220,220,1,218,218,218,1,219, + 219,219,1,220,220,220,1,216,216,216,1,218,218,218,1,220,220,220,1,217, + 217,217,1,219,219,219,1,218,218,218,1,217,217,217,1,219,219,219,2,218, + 218,218,3,216,216,216,1,217,217,217,1,255,255,255,2,216,216,216,1,224, + 224,224,1,215,215,215,2,216,216,216,1,218,218,218,1,220,220,220,1,217, + 217,217,1,218,218,218,2,219,219,219,1,220,220,220,1,217,217,217,1,170, + 170,170,1,217,217,217,1,216,216,216,1,215,215,215,1,223,223,223,1,218, + 218,218,2,217,217,217,3,220,220,220,1,218,218,218,2,222,222,222,1,218, + 218,218,1,219,219,219,1,217,217,217,1,215,215,215,1,221,221,221,1,218, + 218,218,1,215,215,215,1,221,221,221,1,215,215,215,1,221,221,221,1,215, + 215,215,1,217,217,217,1,221,221,221,1,219,219,219,1,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,218,218,218,2,214,214,214,1,216, + 216,216,1,217,217,217,1,218,218,218,2,217,217,217,1,219,219,219,1,218, + 218,218,1,217,217,217,1,216,216,216,1,219,219,219,1,217,217,217,1,221, + 221,221,1,213,213,213,1,255,255,255,2,253,253,253,1,255,255,255,2,219, + 219,219,1,215,215,215,1,219,219,219,1,212,212,212,1,171,171,171,1,168, + 168,168,1,169,169,169,1,170,170,170,1,163,163,163,1,221,221,221,1,218, + 218,218,1,221,221,221,1,214,214,214,1,217,217,217,1,220,220,220,1,255, + 255,255,2,168,168,168,1,170,170,170,1,166,166,166,1,169,169,169,1,171, + 171,171,1,222,222,222,1,216,216,216,1,217,217,217,3,220,220,220,1,255, + 255,255,1,216,216,216,1,168,168,168,1,219,219,219,1,255,255,255,1,220, + 220,220,1,219,219,219,1,167,167,167,1,168,168,168,1,217,217,217,1,167, + 167,167,1,217,217,217,2,218,218,218,1,255,255,255,1,216,216,216,1,253, + 253,253,1,254,254,254,1,215,215,215,1,169,169,169,1,168,168,168,1,218, + 218,218,1,168,168,168,1,217,217,217,1,216,216,216,1,218,218,218,1,217, + 217,217,2,216,216,216,1,218,218,218,1,215,215,215,1,217,217,217,1,222, + 222,222,1,215,215,215,1,167,167,167,1,218,218,218,2,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,217,217,217,1,169, + 169,169,1,218,218,218,1,217,217,217,1,219,219,219,2,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,1,221,221,221,1,217,217,217,1,218, + 218,218,1,217,217,217,2,216,216,216,1,168,168,168,1,222,222,222,1,220, + 220,220,1,219,219,219,1,215,215,215,1,220,220,220,1,216,216,216,1,221, + 221,221,1,217,217,217,1,215,215,215,1,219,219,219,1,166,166,166,1,220, + 220,220,2,218,218,218,1,219,219,219,1,214,214,214,1,219,219,219,1,222, + 222,222,1,219,219,219,1,216,216,216,1,219,219,219,1,216,216,216,1,221, + 221,221,1,216,216,216,2,221,221,221,1,214,214,214,1,222,222,222,1,215, + 215,215,1,218,218,218,1,217,217,217,1,220,220,220,1,218,218,218,1,216, + 216,216,1,221,221,221,1,218,218,218,1,216,216,216,1,218,218,218,1,221, + 221,221,1,216,216,216,1,214,214,214,1,221,221,221,1,217,217,217,2,221, + 221,221,2,218,218,218,1,217,217,217,1,219,219,219,1,217,217,217,2,222, + 222,222,1,218,218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,216, + 216,216,1,255,255,255,2,254,254,254,1,255,255,255,1,251,251,251,1,218, + 218,218,1,252,252,252,1,255,255,255,1,219,219,219,1,221,221,221,1,166, + 166,166,1,169,169,169,1,165,165,165,1,170,170,170,2,165,165,165,1,169, + 169,169,1,218,218,218,1,217,217,217,1,222,222,222,1,254,254,254,2,217, + 217,217,1,167,167,167,1,255,255,255,1,218,218,218,1,220,220,220,1,214, + 214,214,1,217,217,217,1,216,216,216,1,221,221,221,2,216,216,216,1,254, + 254,254,1,217,217,217,1,219,219,219,1,169,169,169,1,218,218,218,1,219, + 219,219,1,216,216,216,1,217,217,217,1,170,170,170,1,166,166,166,1,170, + 170,170,1,168,168,168,1,219,219,219,1,220,220,220,1,214,214,214,1,255, + 255,255,3,218,218,218,1,255,255,255,1,218,218,218,3,219,219,219,2,218, + 218,218,1,221,221,221,1,218,218,218,1,219,219,219,1,218,218,218,1,220, + 220,220,1,218,218,218,1,220,220,220,1,215,215,215,1,220,220,220,1,217, + 217,217,1,221,221,221,1,217,217,217,2,218,218,218,1,214,214,214,1,219, + 219,219,3,167,167,167,1,166,166,166,1,223,223,223,1,214,214,214,1,219, + 219,219,1,218,218,218,3,217,217,217,2,220,220,220,1,215,215,215,1,220, + 220,220,2,218,218,218,1,217,217,217,1,167,167,167,1,220,220,220,1,216, + 216,216,1,218,218,218,2,221,221,221,1,214,214,214,1,219,219,219,1,255, + 255,255,1,218,218,218,1,214,214,214,1,222,222,222,1,215,215,215,1,220, + 220,220,1,216,216,216,1,221,221,221,1,218,218,218,1,215,215,215,1,220, + 220,220,1,217,217,217,1,219,219,219,1,218,218,218,1,215,215,215,1,219, + 219,219,2,218,218,218,1,220,220,220,1,215,215,215,1,219,219,219,1,217, + 217,217,1,220,220,220,1,216,216,216,1,217,217,217,1,220,220,220,1,216, + 216,216,2,220,220,220,1,217,217,217,2,219,219,219,1,220,220,220,1,215, + 215,215,1,220,220,220,1,218,218,218,1,217,217,217,1,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,3,217,217,217,2,218,218,218,1,220, + 220,220,1,218,218,218,1,217,217,217,1,219,219,219,1,216,216,216,1,219, + 219,219,2,218,218,218,1,220,220,220,1,219,219,219,1,217,217,217,1,254, + 254,254,2,255,255,255,1,254,254,254,1,218,218,218,1,169,169,169,1,166, + 166,166,1,170,170,170,1,166,166,166,1,170,170,170,1,168,168,168,1,166, + 166,166,1,169,169,169,1,219,219,219,1,218,218,218,1,255,255,255,2,254, + 254,254,1,217,217,217,1,220,220,220,1,217,217,217,1,221,221,221,1,217, + 217,217,1,252,252,252,1,220,220,220,1,255,255,255,3,218,218,218,1,168, + 168,168,1,167,167,167,1,255,255,255,1,217,217,217,1,168,168,168,1,217, + 217,217,1,219,219,219,1,168,168,168,1,169,169,169,1,217,217,217,1,255, + 255,255,1,220,220,220,1,167,167,167,1,217,217,217,1,255,255,255,2,216, + 216,216,1,255,255,255,1,221,221,221,1,216,216,216,1,218,218,218,2,216, + 216,216,1,217,217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,217, + 217,217,1,220,220,220,1,253,253,253,1,218,218,218,1,219,219,219,1,216, + 216,216,1,217,217,217,1,220,220,220,1,218,218,218,1,222,222,222,1,218, + 218,218,1,253,253,253,1,218,218,218,6,217,217,217,1,216,216,216,1,217, + 217,217,1,220,220,220,1,255,255,255,2,220,220,220,1,217,217,217,1,254, + 254,254,1,221,221,221,1,216,216,216,1,167,167,167,1,218,218,218,1,221, + 221,221,1,218,218,218,1,217,217,217,1,218,218,218,1,169,169,169,1,168, + 168,168,1,215,215,215,1,221,221,221,1,217,217,217,1,218,218,218,1,219, + 219,219,1,218,218,218,16,216,216,216,1,217,217,217,1,219,219,219,2,218, + 218,218,2,217,217,217,1,220,220,220,1,219,219,219,1,216,216,216,1,218, + 218,218,1,219,219,219,1,217,217,217,1,218,218,218,2,217,217,217,1,218, + 218,218,8,217,217,217,1,219,219,219,1,218,218,218,3,219,219,219,1,218, + 218,218,2,219,219,219,1,216,216,216,1,219,219,219,2,254,254,254,1,255, + 255,255,2,254,254,254,1,255,255,255,2,216,216,216,1,170,170,170,1,167, + 167,167,1,168,168,168,1,170,170,170,1,166,166,166,1,219,219,219,1,216, + 216,216,1,169,169,169,1,167,167,167,1,216,216,216,1,220,220,220,1,215, + 215,215,1,255,255,255,1,218,218,218,1,220,220,220,1,217,217,217,1,216, + 216,216,1,222,222,222,1,169,169,169,1,216,216,216,1,255,255,255,1,217, + 217,217,2,169,169,169,1,254,254,254,1,218,218,218,1,255,255,255,2,165, + 165,165,1,169,169,169,1,168,168,168,2,166,166,166,1,169,169,169,1,219, + 219,219,1,169,169,169,2,218,218,218,1,215,215,215,1,220,220,220,1,219, + 219,219,1,216,216,216,1,220,220,220,1,216,216,216,1,219,219,219,1,218, + 218,218,8,217,217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,219, + 219,219,1,216,216,216,1,217,217,217,1,255,255,255,1,254,254,254,1,222, + 222,222,1,215,215,215,1,218,218,218,2,219,219,219,1,220,220,220,1,222, + 222,222,1,217,217,217,1,215,215,215,1,218,218,218,1,165,165,165,1,220, + 220,220,1,216,216,216,1,218,218,218,1,255,255,255,1,219,219,219,1,169, + 169,169,1,217,217,217,1,212,212,212,1,220,220,220,2,217,217,217,2,216, + 216,216,1,223,223,223,1,215,215,215,1,218,218,218,1,221,221,221,1,216, + 216,216,1,218,218,218,16,220,220,220,1,221,221,221,1,219,219,219,1,215, + 215,215,1,217,217,217,1,218,218,218,1,221,221,221,1,216,216,216,1,218, + 218,218,1,221,221,221,1,219,219,219,1,217,217,217,3,220,220,220,2,218, + 218,218,8,221,221,221,1,215,215,215,1,219,219,219,1,220,220,220,1,216, + 216,216,1,217,217,217,3,219,219,219,1,220,220,220,1,214,214,214,1,221, + 221,221,1,215,215,215,1,219,219,219,1,253,253,253,1,255,255,255,2,253, + 253,253,2,255,255,255,2,252,252,252,1,255,255,255,1,218,218,218,1,217, + 217,217,1,169,169,169,1,168,168,168,2,218,218,218,2,222,222,222,1,215, + 215,215,1,218,218,218,1,215,215,215,1,219,219,219,2,166,166,166,1,163, + 163,163,1,169,169,169,1,219,219,219,1,255,255,255,1,217,217,217,1,216, + 216,216,1,221,221,221,1,253,253,253,1,220,220,220,1,249,249,249,1,255, + 255,255,1,164,164,164,1,171,171,171,1,168,168,168,1,221,221,221,1,217, + 217,217,1,167,167,167,3,220,220,220,1,218,218,218,1,217,217,217,4,219, + 219,219,1,217,217,217,1,218,218,218,10,219,219,219,1,217,217,217,1,220, + 220,220,1,218,218,218,1,222,222,222,1,215,215,215,1,221,221,221,1,212, + 212,212,1,218,218,218,1,219,219,219,1,216,216,216,1,219,219,219,1,214, + 214,214,1,219,219,219,1,218,218,218,1,220,220,220,1,219,219,219,1,217, + 217,217,2,221,221,221,1,167,167,167,1,254,254,254,1,165,165,165,1,170, + 170,170,1,218,218,218,1,224,224,224,1,213,213,213,1,255,255,255,2,253, + 253,253,1,220,220,220,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,221,221,221,1,218,218,218,16,217,217,217,1,213,213,213,1,217, + 217,217,1,222,222,222,1,218,218,218,1,214,214,214,1,221,221,221,1,216, + 216,216,1,215,215,215,1,218,218,218,1,215,215,215,1,219,219,219,1,222, + 222,222,1,217,217,217,1,216,216,216,1,218,218,218,9,213,213,213,1,221, + 221,221,1,218,218,218,1,217,217,217,1,219,219,219,2,216,216,216,1,221, + 221,221,1,214,214,214,1,218,218,218,1,221,221,221,1,218,218,218,2,219, + 219,219,1,217,217,217,1,219,219,219,1,253,253,253,1,255,255,255,2,253, + 253,253,1,255,255,255,1,253,253,253,1,255,255,255,2,216,216,216,1,219, + 219,219,1,168,168,168,1,216,216,216,1,223,223,223,1,215,215,215,1,165, + 165,165,1,220,220,220,1,219,219,219,1,217,217,217,1,220,220,220,1,254, + 254,254,1,219,219,219,1,171,171,171,1,169,169,169,1,168,168,168,1,217, + 217,217,1,169,169,169,1,219,219,219,1,167,167,167,1,170,170,170,1,216, + 216,216,1,255,255,255,1,254,254,254,1,220,220,220,1,217,217,217,1,253, + 253,253,1,218,218,218,1,219,219,219,1,216,216,216,1,169,169,169,1,170, + 170,170,1,165,165,165,1,170,170,170,1,217,217,217,1,218,218,218,1,220, + 220,220,1,222,222,222,1,214,214,214,1,220,220,220,1,218,218,218,8,217, + 217,217,1,216,216,216,1,220,220,220,1,167,167,167,1,218,218,218,1,219, + 219,219,1,213,213,213,1,222,222,222,1,216,216,216,2,223,223,223,1,219, + 219,219,1,217,217,217,1,220,220,220,1,169,169,169,1,167,167,167,1,220, + 220,220,1,252,252,252,1,219,219,219,1,220,220,220,1,218,218,218,1,215, + 215,215,1,168,168,168,1,224,224,224,1,167,167,167,2,217,217,217,1,216, + 216,216,1,171,171,171,1,167,167,167,1,166,166,166,1,218,218,218,2,217, + 217,217,1,219,219,219,1,218,218,218,1,217,217,217,2,218,218,218,16,219, + 219,219,1,222,222,222,1,218,218,218,1,215,215,215,1,220,220,220,1,219, + 219,219,1,216,216,216,1,218,218,218,1,221,221,221,1,219,219,219,1,218, + 218,218,2,219,219,219,1,217,217,217,2,219,219,219,1,218,218,218,8,219, + 219,219,1,217,217,217,2,220,220,220,1,214,214,214,1,218,218,218,1,217, + 217,217,2,222,222,222,1,217,217,217,1,168,168,168,1,166,166,166,1,168, + 168,168,1,170,170,170,1,217,217,217,1,216,216,216,1,215,215,215,1,222, + 222,222,1,219,219,219,1,217,217,217,1,168,168,168,1,255,255,255,1,254, + 254,254,1,255,255,255,1,222,222,222,1,217,217,217,1,168,168,168,2,171, + 171,171,1,215,215,215,1,220,220,220,1,217,217,217,1,220,220,220,1,219, + 219,219,1,253,253,253,1,217,217,217,1,220,220,220,1,214,214,214,1,168, + 168,168,2,220,220,220,1,217,217,217,1,168,168,168,1,169,169,169,1,217, + 217,217,1,168,168,168,1,218,218,218,2,255,255,255,1,216,216,216,1,255, + 255,255,3,218,218,218,1,170,170,170,1,164,164,164,1,168,168,168,1,217, + 217,217,1,170,170,170,1,219,219,219,1,218,218,218,1,214,214,214,1,218, + 218,218,1,217,217,217,1,218,218,218,8,221,221,221,1,218,218,218,2,216, + 216,216,1,219,219,219,1,217,217,217,1,222,222,222,1,216,216,216,1,220, + 220,220,1,218,218,218,2,215,215,215,1,217,217,217,1,220,220,220,1,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,1,217,217,217,1,216, + 216,216,1,255,255,255,1,219,219,219,1,218,218,218,1,214,214,214,1,168, + 168,168,1,170,170,170,1,218,218,218,2,169,169,169,3,220,220,220,1,218, + 218,218,2,219,219,219,1,216,216,216,1,218,218,218,1,221,221,221,1,218, + 218,218,16,216,216,216,2,219,219,219,1,218,218,218,1,215,215,215,1,220, + 220,220,1,217,217,217,1,219,219,219,1,217,217,217,1,216,216,216,1,221, + 221,221,1,218,218,218,1,215,215,215,1,220,220,220,2,217,217,217,1,218, + 218,218,8,220,220,220,1,215,215,215,1,219,219,219,1,216,216,216,1,218, + 218,218,1,221,221,221,1,218,218,218,2,166,166,166,1,164,164,164,1,222, + 222,222,1,166,166,166,1,214,214,214,1,169,169,169,1,216,216,216,1,220, + 220,220,1,218,218,218,1,220,220,220,1,213,213,213,1,168,168,168,1,220, + 220,220,1,167,167,167,1,252,252,252,1,254,254,254,1,214,214,214,1,169, + 169,169,1,167,167,167,1,170,170,170,1,251,251,251,1,220,220,220,1,219, + 219,219,2,216,216,216,1,218,218,218,1,255,255,255,1,221,221,221,1,213, + 213,213,1,224,224,224,1,223,223,223,1,216,216,216,1,217,217,217,4,170, + 170,170,1,219,219,219,1,216,216,216,1,218,218,218,1,217,217,217,1,218, + 218,218,1,255,255,255,2,253,253,253,1,219,219,219,1,216,216,216,1,222, + 222,222,1,216,216,216,1,219,219,219,1,218,218,218,1,166,166,166,1,216, + 216,216,1,218,218,218,1,222,222,222,1,218,218,218,9,216,216,216,1,253, + 253,253,1,218,218,218,1,224,224,224,1,216,216,216,1,221,221,221,1,219, + 219,219,1,218,218,218,1,217,217,217,2,218,218,218,1,217,217,217,1,218, + 218,218,2,217,217,217,1,220,220,220,1,217,217,217,1,220,220,220,1,217, + 217,217,1,218,218,218,1,255,255,255,1,214,214,214,1,218,218,218,1,220, + 220,220,1,171,171,171,1,215,215,215,1,255,255,255,2,213,213,213,1,171, + 171,171,1,166,166,166,1,217,217,217,1,218,218,218,1,217,217,217,1,219, + 219,219,1,220,220,220,2,216,216,216,1,218,218,218,16,219,219,219,1,217, + 217,217,1,220,220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,218, + 218,218,1,217,217,217,1,220,220,220,1,215,215,215,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,8,216,216,216,1,221,221,221,1,213,213,213,1,221,221,221,1,217, + 217,217,1,216,216,216,1,168,168,168,1,218,218,218,1,255,255,255,1,224, + 224,224,1,214,214,214,1,255,255,255,1,170,170,170,1,216,216,216,1,217, + 217,217,1,220,220,220,1,219,219,219,1,212,212,212,1,255,255,255,1,168, + 168,168,1,215,215,215,1,170,170,170,1,219,219,219,1,255,255,255,1,219, + 219,219,1,255,255,255,1,254,254,254,1,216,216,216,1,220,220,220,1,215, + 215,215,1,218,218,218,1,216,216,216,1,219,219,219,1,255,255,255,3,219, + 219,219,1,213,213,213,1,217,217,217,1,218,218,218,1,254,254,254,1,255, + 255,255,1,171,171,171,1,219,219,219,1,254,254,254,1,255,255,255,1,215, + 215,215,1,255,255,255,1,222,222,222,1,215,215,215,1,216,216,216,1,255, + 255,255,2,253,253,253,1,255,255,255,1,214,214,214,1,255,255,255,1,215, + 215,215,1,218,218,218,1,220,220,220,1,222,222,222,1,217,217,217,3,218, + 218,218,8,221,221,221,1,220,220,220,2,216,216,216,4,219,219,219,1,218, + 218,218,1,221,221,221,2,219,219,219,2,218,218,218,1,219,219,219,1,217, + 217,217,1,216,216,216,1,222,222,222,1,218,218,218,2,252,252,252,1,222, + 222,222,1,254,254,254,1,255,255,255,1,217,217,217,1,219,219,219,1,253, + 253,253,1,218,218,218,2,168,168,168,1,169,169,169,1,217,217,217,1,220, + 220,220,1,218,218,218,1,216,216,216,2,217,217,217,1,219,219,219,1,218, + 218,218,17,220,220,220,1,214,214,214,1,220,220,220,1,218,218,218,1,166, + 166,166,1,170,170,170,1,218,218,218,1,215,215,215,1,223,223,223,1,217, + 217,217,2,219,219,219,1,214,214,214,1,218,218,218,1,220,220,220,1,218, + 218,218,9,220,220,220,1,217,217,217,1,218,218,218,1,222,222,222,1,216, + 216,216,1,253,253,253,1,255,255,255,1,216,216,216,1,253,253,253,1,218, + 218,218,2,217,217,217,1,218,218,218,1,219,219,219,1,217,217,217,1,218, + 218,218,1,255,255,255,1,218,218,218,1,255,255,255,1,221,221,221,1,167, + 167,167,1,251,251,251,1,217,217,217,1,252,252,252,1,254,254,254,1,220, + 220,220,1,218,218,218,1,217,217,217,1,218,218,218,1,220,220,220,2,218, + 218,218,1,254,254,254,2,255,255,255,2,216,216,216,1,255,255,255,4,250, + 250,250,1,167,167,167,1,253,253,253,1,255,255,255,1,220,220,220,1,252, + 252,252,1,165,165,165,1,170,170,170,1,218,218,218,1,255,255,255,1,253, + 253,253,1,255,255,255,1,216,216,216,1,171,171,171,1,216,216,216,1,255, + 255,255,1,220,220,220,1,218,218,218,1,215,215,215,1,220,220,220,1,217, + 217,217,1,219,219,219,1,218,218,218,9,215,215,215,1,219,219,219,1,216, + 216,216,1,221,221,221,1,220,220,220,2,217,217,217,2,218,218,218,1,216, + 216,216,2,217,217,217,1,219,219,219,1,218,218,218,1,217,217,217,1,219, + 219,219,1,216,216,216,2,220,220,220,1,255,255,255,1,254,254,254,1,255, + 255,255,1,216,216,216,1,218,218,218,1,219,219,219,2,218,218,218,1,220, + 220,220,1,167,167,167,1,170,170,170,1,217,217,217,1,219,219,219,1,217, + 217,217,1,219,219,219,1,220,220,220,1,217,217,217,1,218,218,218,17,217, + 217,217,1,220,220,220,1,217,217,217,1,219,219,219,1,217,217,217,1,167, + 167,167,1,168,168,168,2,170,170,170,1,216,216,216,1,219,219,219,1,217, + 217,217,1,220,220,220,1,215,215,215,1,222,222,222,1,216,216,216,1,218, + 218,218,8,217,217,217,1,218,218,218,1,219,219,219,1,217,217,217,1,253, + 253,253,1,220,220,220,1,218,218,218,1,255,255,255,2,219,219,219,1,255, + 255,255,1,217,217,217,1,219,219,219,1,218,218,218,3,217,217,217,1,255, + 255,255,1,216,216,216,1,253,253,253,1,218,218,218,2,255,255,255,1,219, + 219,219,1,218,218,218,1,220,220,220,1,217,217,217,2,218,218,218,2,217, + 217,217,2,218,218,218,1,217,217,217,1,255,255,255,1,216,216,216,1,254, + 254,254,1,220,220,220,1,217,217,217,1,218,218,218,1,254,254,254,1,255, + 255,255,1,169,169,169,1,220,220,220,1,218,218,218,2,217,217,217,1,219, + 219,219,1,168,168,168,1,169,169,169,1,218,218,218,1,219,219,219,1,217, + 217,217,1,219,219,219,2,167,167,167,1,219,219,219,1,215,215,215,1,217, + 217,217,1,220,220,220,1,218,218,218,2,219,219,219,1,218,218,218,9,219, + 219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,217,217,217,2,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,2,220,220,220,1,219, + 219,219,1,216,216,216,1,217,217,217,1,218,218,218,1,219,219,219,1,218, + 218,218,1,217,217,217,1,254,254,254,1,221,221,221,1,218,218,218,1,219, + 219,219,1,217,217,217,2,254,254,254,1,218,218,218,1,221,221,221,1,215, + 215,215,1,169,169,169,1,168,168,168,1,217,217,217,2,218,218,218,1,220, + 220,220,1,218,218,218,1,217,217,217,1,218,218,218,1,217,217,217,1,223, + 223,223,1,215,215,215,1,218,218,218,1,219,219,219,1,218,218,218,1,217, + 217,217,1,218,218,218,3,217,217,217,2,219,219,219,1,220,220,220,1,216, + 216,216,1,220,220,220,1,218,218,218,1,219,219,219,1,217,217,217,1,255, + 255,255,2,171,171,171,1,166,166,166,1,168,168,168,1,169,169,169,1,168, + 168,168,1,169,169,169,1,217,217,217,1,220,220,220,1,219,219,219,1,217, + 217,217,1,219,219,219,2,218,218,218,1,217,217,217,2,221,221,221,1,217, + 217,217,1,219,219,219,2,220,220,220,1,217,217,217,1,218,218,218,2,217, + 217,217,1,219,219,219,1,218,218,218,1,216,216,216,1,219,219,219,1,255, + 255,255,1,219,219,219,1,217,217,217,2,218,218,218,1,216,216,216,1,219, + 219,219,2,218,218,218,1,216,216,216,1,255,255,255,1,167,167,167,1,218, + 218,218,1,170,170,170,1,217,217,217,1,219,219,219,1,218,218,218,2,216, + 216,216,1,220,220,220,1,216,216,216,1,219,219,219,1,217,217,217,2,218, + 218,218,1,219,219,219,1,255,255,255,1,216,216,216,1,217,217,217,1,222, + 222,222,1,217,217,217,1,218,218,218,1,255,255,255,1,216,216,216,1,221, + 221,221,1,217,217,217,1,216,216,216,1,255,255,255,2,218,218,218,3,219, + 219,219,1,215,215,215,1,255,255,255,1,219,219,219,1,217,217,217,1,218, + 218,218,17,219,219,219,1,217,217,217,1,218,218,218,2,217,217,217,1,218, + 218,218,1,217,217,217,1,218,218,218,6,220,220,220,1,217,217,217,1,216, + 216,216,1,255,255,255,1,220,220,220,1,218,218,218,1,216,216,216,1,215, + 215,215,1,217,217,217,1,218,218,218,1,255,255,255,2,253,253,253,1,252, + 252,252,1,255,255,255,1,167,167,167,1,216,216,216,1,222,222,222,1,221, + 221,221,1,214,214,214,1,218,218,218,1,217,217,217,1,216,216,216,1,220, + 220,220,1,216,216,216,1,218,218,218,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,216,216,216,1,219,219,219,1,218,218,218,1,215, + 215,215,1,222,222,222,1,219,219,219,1,214,214,214,1,220,220,220,1,219, + 219,219,1,216,216,216,1,218,218,218,2,220,220,220,1,251,251,251,1,252, + 252,252,1,220,220,220,1,216,216,216,1,170,170,170,1,166,166,166,1,219, + 219,219,1,220,220,220,1,214,214,214,1,218,218,218,1,221,221,221,1,215, + 215,215,1,219,219,219,1,217,217,217,1,219,219,219,1,220,220,220,1,218, + 218,218,1,215,215,215,1,218,218,218,1,215,215,215,1,217,217,217,2,218, + 218,218,1,219,219,219,1,217,217,217,1,220,220,220,1,166,166,166,1,167, + 167,167,1,221,221,221,1,217,217,217,1,219,219,219,1,216,216,216,1,220, + 220,220,1,212,212,212,1,219,219,219,1,220,220,220,1,218,218,218,1,216, + 216,216,1,218,218,218,1,255,255,255,1,216,216,216,1,219,219,219,1,215, + 215,215,1,218,218,218,1,217,217,217,2,218,218,218,1,220,220,220,1,221, + 221,221,1,217,217,217,1,220,220,220,1,219,219,219,1,218,218,218,1,221, + 221,221,1,251,251,251,1,221,221,221,1,254,254,254,1,220,220,220,1,218, + 218,218,1,212,212,212,1,219,219,219,1,254,254,254,1,218,218,218,1,220, + 220,220,1,214,214,214,1,218,218,218,1,220,220,220,1,254,254,254,1,253, + 253,253,1,219,219,219,1,215,215,215,1,218,218,218,2,221,221,221,1,253, + 253,253,1,217,217,217,2,218,218,218,16,216,216,216,1,220,220,220,1,217, + 217,217,1,222,222,222,1,219,219,219,1,216,216,216,1,219,219,219,1,220, + 220,220,1,218,218,218,6,219,219,219,2,218,218,218,1,220,220,220,1,215, + 215,215,1,216,216,216,1,222,222,222,1,220,220,220,1,217,217,217,1,220, + 220,220,1,253,253,253,2,220,220,220,1,255,255,255,1,253,253,253,1,219, + 219,219,1,221,221,221,1,214,214,214,1,216,216,216,1,221,221,221,1,220, + 220,220,1,216,216,216,1,220,220,220,1,217,217,217,1,220,220,220,1,216, + 216,216,1,215,215,215,1,222,222,222,1,219,219,219,1,218,218,218,1,216, + 216,216,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,221, + 221,221,1,217,217,217,3,219,219,219,1,217,217,217,1,218,218,218,1,216, + 216,216,1,255,255,255,2,214,214,214,1,222,222,222,1,217,217,217,2,219, + 219,219,1,217,217,217,1,219,219,219,2,217,217,217,1,219,219,219,1,218, + 218,218,5,220,220,220,1,216,216,216,1,224,224,224,1,219,219,219,1,218, + 218,218,3,217,217,217,1,218,218,218,1,169,169,169,1,168,168,168,1,220, + 220,220,1,221,221,221,1,212,212,212,1,220,220,220,1,221,221,221,1,218, + 218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,215,215,215,1,219, + 219,219,1,255,255,255,1,250,250,250,1,255,255,255,1,219,219,219,1,216, + 216,216,1,220,220,220,2,217,217,217,2,214,214,214,1,219,219,219,1,218, + 218,218,1,215,215,215,1,221,221,221,1,217,217,217,1,219,219,219,1,216, + 216,216,1,218,218,218,2,220,220,220,1,217,217,217,1,220,220,220,1,221, + 221,221,1,218,218,218,1,217,217,217,1,219,219,219,1,217,217,217,1,219, + 219,219,1,217,217,217,1,220,220,220,1,215,215,215,1,220,220,220,1,216, + 216,216,1,221,221,221,1,213,213,213,1,219,219,219,1,220,220,220,1,218, + 218,218,17,219,219,219,1,216,216,216,1,220,220,220,1,213,213,213,1,219, + 219,219,1,220,220,220,1,218,218,218,1,215,215,215,1,218,218,218,6,214, + 214,214,1,220,220,220,1,217,217,217,1,218,218,218,1,221,221,221,1,218, + 218,218,1,217,217,217,1,216,216,216,1,218,218,218,1,219,219,219,2,220, + 220,220,1,166,166,166,1,217,217,217,1,222,222,222,1,215,215,215,1,217, + 217,217,1,219,219,219,1,218,218,218,1,222,222,222,1,212,212,212,1,221, + 221,221,1,218,218,218,2,219,219,219,1,217,217,217,1,220,220,220,1,216, + 216,216,3,217,217,217,1,218,218,218,1,168,168,168,2,218,218,218,1,214, + 214,214,1,219,219,219,1,217,217,217,1,222,222,222,1,217,217,217,1,220, + 220,220,1,217,217,217,1,219,219,219,1,253,253,253,1,255,255,255,1,217, + 217,217,2,167,167,167,1,221,221,221,1,216,216,216,1,220,220,220,1,217, + 217,217,1,215,215,215,1,216,216,216,1,220,220,220,1,218,218,218,1,221, + 221,221,1,216,216,216,1,217,217,217,1,219,219,219,1,216,216,216,1,220, + 220,220,1,215,215,215,1,217,217,217,1,219,219,219,3,255,255,255,2,215, + 215,215,1,219,219,219,1,217,217,217,2,221,221,221,1,217,217,217,1,215, + 215,215,1,222,222,222,1,218,218,218,1,215,215,215,1,219,219,219,2,216, + 216,216,1,217,217,217,1,220,220,220,1,216,216,216,1,221,221,221,1,217, + 217,217,2,219,219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,221, + 221,221,1,217,217,217,2,218,218,218,1,217,217,217,2,221,221,221,1,218, + 218,218,1,216,216,216,1,215,215,215,1,221,221,221,1,217,217,217,1,216, + 216,216,1,218,218,218,1,216,216,216,1,221,221,221,1,216,216,216,1,219, + 219,219,2,215,215,215,1,220,220,220,1,219,219,219,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,2,218,218,218,17,217, + 217,217,1,223,223,223,1,216,216,216,1,217,217,217,2,219,219,219,1,220, + 220,220,1,218,218,218,6,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,1,216,216,216,1,219,219,219,1,217,217,217,1,219,219,219,1,220, + 220,220,1,215,215,215,1,252,252,252,1,215,215,215,1,219,219,219,1,167, + 167,167,2,169,169,169,1,166,166,166,1,171,171,171,1,167,167,167,1,216, + 216,216,1,217,217,217,1,218,218,218,1,217,217,217,1,221,221,221,1,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,2,223,223,223,1,217, + 217,217,1,219,219,219,1,168,168,168,1,170,170,170,1,219,219,219,2,221, + 221,221,1,218,218,218,1,217,217,217,4,220,220,220,1,251,251,251,1,255, + 255,255,3,220,220,220,1,218,218,218,1,217,217,217,1,216,216,216,1,218, + 218,218,1,222,222,222,1,221,221,221,1,215,215,215,1,218,218,218,1,217, + 217,217,2,218,218,218,2,221,221,221,1,217,217,217,1,222,222,222,1,218, + 218,218,1,219,219,219,1,165,165,165,1,170,170,170,1,253,253,253,1,255, + 255,255,1,219,219,219,1,218,218,218,2,216,216,216,1,220,220,220,1,215, + 215,215,1,217,217,217,1,218,218,218,1,216,216,216,1,219,219,219,1,218, + 218,218,1,221,221,221,1,215,215,215,1,220,220,220,1,218,218,218,2,217, + 217,217,1,220,220,220,2,216,216,216,1,219,219,219,2,220,220,220,1,214, + 214,214,1,217,217,217,1,222,222,222,1,216,216,216,1,220,220,220,1,216, + 216,216,1,215,215,215,1,219,219,219,2,218,218,218,1,217,217,217,1,218, + 218,218,1,169,169,169,1,219,219,219,1,221,221,221,1,214,214,214,1,219, + 219,219,1,216,216,216,2,221,221,221,1,214,214,214,1,220,220,220,1,217, + 217,217,1,216,216,216,1,218,218,218,2,215,215,215,1,222,222,222,1,218, + 218,218,16,217,217,217,1,219,219,219,1,214,214,214,1,222,222,222,1,219, + 219,219,1,216,216,216,1,218,218,218,1,220,220,220,1,218,218,218,8,217, + 217,217,1,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,2,215, + 215,215,1,222,222,222,1,255,255,255,2,219,219,219,1,220,220,220,1,217, + 217,217,1,167,167,167,2,169,169,169,1,168,168,168,1,169,169,169,1,219, + 219,219,1,215,215,215,1,223,223,223,1,215,215,215,1,217,217,217,1,221, + 221,221,1,220,220,220,1,216,216,216,1,218,218,218,1,215,215,215,1,255, + 255,255,2,167,167,167,2,218,218,218,2,213,213,213,1,219,219,219,1,216, + 216,216,1,220,220,220,1,219,219,219,1,218,218,218,1,220,220,220,1,255, + 255,255,1,254,254,254,1,255,255,255,1,218,218,218,1,216,216,216,1,218, + 218,218,1,220,220,220,2,218,218,218,1,214,214,214,1,219,219,219,2,220, + 220,220,1,219,219,219,2,218,218,218,1,216,216,216,1,219,219,219,1,215, + 215,215,1,218,218,218,1,219,219,219,2,171,171,171,1,166,166,166,1,220, + 220,220,1,216,216,216,1,219,219,219,1,218,218,218,2,220,220,220,1,219, + 219,219,2,221,221,221,1,218,218,218,2,216,216,216,1,219,219,219,1,218, + 218,218,4,220,220,220,2,215,215,215,1,216,216,216,1,218,218,218,2,217, + 217,217,1,214,214,214,1,223,223,223,1,216,216,216,1,219,219,219,1,218, + 218,218,1,217,217,217,1,218,218,218,1,221,221,221,1,220,220,220,1,216, + 216,216,1,221,221,221,1,169,169,169,1,217,217,217,1,167,167,167,1,220, + 220,220,1,213,213,213,1,169,169,169,1,168,168,168,1,169,169,169,1,221, + 221,221,1,217,217,217,2,222,222,222,1,215,215,215,1,221,221,221,1,218, + 218,218,1,215,215,215,1,222,222,222,1,214,214,214,1,218,218,218,16,219, + 219,219,1,217,217,217,1,220,220,220,1,217,217,217,1,219,219,219,2,217, + 217,217,1,215,215,215,1,218,218,218,7,217,217,217,1,216,216,216,1,221, + 221,221,1,168,168,168,1,167,167,167,1,216,216,216,1,166,166,166,1,219, + 219,219,1,217,217,217,1,216,216,216,1,251,251,251,1,255,255,255,1,251, + 251,251,1,255,255,255,1,221,221,221,1,219,219,219,1,167,167,167,1,166, + 166,166,1,170,170,170,1,167,167,167,1,170,170,170,1,167,167,167,1,219, + 219,219,1,170,170,170,1,164,164,164,2,221,221,221,1,219,219,219,1,221, + 221,221,1,255,255,255,1,254,254,254,1,219,219,219,1,169,169,169,1,217, + 217,217,1,219,219,219,1,222,222,222,1,218,218,218,1,215,215,215,1,219, + 219,219,1,216,216,216,1,218,218,218,1,215,215,215,1,166,166,166,1,222, + 222,222,1,216,216,216,1,217,217,217,1,220,220,220,1,217,217,217,1,218, + 218,218,1,215,215,215,1,219,219,219,1,221,221,221,1,218,218,218,1,215, + 215,215,1,219,219,219,2,214,214,214,1,219,219,219,1,223,223,223,1,215, + 215,215,1,220,220,220,1,218,218,218,1,254,254,254,1,253,253,253,1,218, + 218,218,1,219,219,219,2,169,169,169,1,166,166,166,1,217,217,217,1,219, + 219,219,1,216,216,216,1,217,217,217,3,219,219,219,2,215,215,215,1,220, + 220,220,1,218,218,218,2,217,217,217,1,219,219,219,1,216,216,216,2,222, + 222,222,1,220,220,220,1,219,219,219,1,216,216,216,1,220,220,220,1,218, + 218,218,1,217,217,217,1,221,221,221,1,215,215,215,1,217,217,217,2,220, + 220,220,1,214,214,214,1,217,217,217,1,219,219,219,1,217,217,217,1,252, + 252,252,1,169,169,169,1,166,166,166,1,171,171,171,1,219,219,219,1,218, + 218,218,1,169,169,169,1,168,168,168,1,165,165,165,1,220,220,220,1,218, + 218,218,2,217,217,217,1,215,215,215,1,219,219,219,1,218,218,218,1,219, + 219,219,2,218,218,218,18,215,215,215,1,218,218,218,1,217,217,217,1,218, + 218,218,1,219,219,219,1,220,220,220,1,218,218,218,6,217,217,217,1,219, + 219,219,2,216,216,216,1,217,217,217,1,170,170,170,1,217,217,217,1,219, + 219,219,1,220,220,220,1,215,215,215,1,218,218,218,1,223,223,223,1,164, + 164,164,1,221,221,221,1,217,217,217,1,216,216,216,1,219,219,219,1,216, + 216,216,1,170,170,170,1,169,169,169,1,215,215,215,1,220,220,220,1,167, + 167,167,1,168,168,168,1,167,167,167,1,170,170,170,1,221,221,221,1,215, + 215,215,1,217,217,217,2,255,255,255,1,219,219,219,1,169,169,169,1,217, + 217,217,1,216,216,216,1,219,219,219,1,216,216,216,1,217,217,217,1,222, + 222,222,1,216,216,216,1,220,220,220,1,217,217,217,1,220,220,220,1,217, + 217,217,1,218,218,218,1,216,216,216,1,219,219,219,1,218,218,218,1,219, + 219,219,1,217,217,217,1,218,218,218,1,220,220,220,1,216,216,216,1,217, + 217,217,1,222,222,222,1,216,216,216,1,217,217,217,1,221,221,221,1,216, + 216,216,1,217,217,217,1,219,219,219,1,166,166,166,1,220,220,220,1,255, + 255,255,2,218,218,218,1,221,221,221,1,165,165,165,1,219,219,219,1,220, + 220,220,1,218,218,218,3,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,2,220,220,220,1,216,216,216,1,167, + 167,167,1,220,220,220,1,215,215,215,1,219,219,219,2,167,167,167,1,218, + 218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,219,219,219,1,168, + 168,168,1,169,169,169,1,253,253,253,1,218,218,218,1,255,255,255,1,217, + 217,217,1,170,170,170,1,216,216,216,1,215,215,215,1,222,222,222,1,165, + 165,165,1,168,168,168,1,171,171,171,1,166,166,166,1,218,218,218,2,170, + 170,170,1,168,168,168,1,218,218,218,1,217,217,217,1,216,216,216,1,219, + 219,219,1,218,218,218,18,168,168,168,1,222,222,222,1,216,216,216,2,221, + 221,221,1,215,215,215,1,218,218,218,7,216,216,216,1,255,255,255,1,253, + 253,253,1,217,217,217,1,219,219,219,1,167,167,167,1,220,220,220,1,217, + 217,217,1,220,220,220,1,218,218,218,1,169,169,169,2,218,218,218,1,219, + 219,219,1,254,254,254,1,255,255,255,1,220,220,220,1,216,216,216,1,220, + 220,220,1,255,255,255,1,216,216,216,1,255,255,255,1,218,218,218,1,255, + 255,255,1,216,216,216,1,167,167,167,1,168,168,168,1,219,219,219,1,216, + 216,216,1,219,219,219,1,218,218,218,1,168,168,168,1,216,216,216,1,218, + 218,218,1,221,221,221,1,218,218,218,1,216,216,216,1,220,220,220,1,218, + 218,218,1,219,219,219,1,255,255,255,1,219,219,219,1,217,217,217,2,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,9,219,219,219,2,217, + 217,217,1,168,168,168,1,167,167,167,1,220,220,220,1,215,215,215,1,219, + 219,219,2,255,255,255,1,216,216,216,1,220,220,220,1,219,219,219,1,220, + 220,220,1,217,217,217,1,218,218,218,1,217,217,217,1,218,218,218,1,219, + 219,219,1,217,217,217,1,219,219,219,1,220,220,220,1,218,218,218,2,222, + 222,222,1,214,214,214,1,218,218,218,1,217,217,217,1,221,221,221,1,217, + 217,217,1,218,218,218,1,220,220,220,1,167,167,167,1,218,218,218,1,217, + 217,217,1,218,218,218,1,219,219,219,1,215,215,215,1,220,220,220,1,219, + 219,219,1,216,216,216,1,219,219,219,1,218,218,218,1,217,217,217,1,255, + 255,255,1,251,251,251,1,255,255,255,1,168,168,168,2,218,218,218,1,217, + 217,217,2,170,170,170,1,169,169,169,1,167,167,167,1,217,217,217,1,218, + 218,218,1,216,216,216,1,168,168,168,1,221,221,221,1,218,218,218,1,215, + 215,215,1,220,220,220,1,217,217,217,1,219,219,219,1,218,218,218,1,219, + 219,219,1,216,216,216,1,220,220,220,1,215,215,215,1,221,221,221,1,218, + 218,218,1,220,220,220,1,217,217,217,2,221,221,221,1,215,215,215,1,216, + 216,216,1,220,220,220,1,167,167,167,1,172,172,172,1,164,164,164,1,219, + 219,219,1,220,220,220,1,217,217,217,1,168,168,168,1,166,166,166,1,167, + 167,167,1,170,170,170,1,165,165,165,1,218,218,218,1,221,221,221,1,213, + 213,213,1,220,220,220,1,218,218,218,2,254,254,254,1,221,221,221,1,217, + 217,217,1,165,165,165,1,218,218,218,2,220,220,220,1,254,254,254,1,253, + 253,253,1,217,217,217,1,216,216,216,1,221,221,221,1,255,255,255,1,252, + 252,252,1,255,255,255,1,168,168,168,1,167,167,167,1,255,255,255,2,254, + 254,254,1,255,255,255,1,218,218,218,1,168,168,168,1,171,171,171,1,216, + 216,216,1,219,219,219,1,255,255,255,2,216,216,216,1,220,220,220,1,216, + 216,216,1,220,220,220,1,216,216,216,1,217,217,217,1,219,219,219,1,218, + 218,218,1,217,217,217,2,219,219,219,1,216,216,216,1,220,220,220,1,212, + 212,212,1,219,219,219,1,220,220,220,1,218,218,218,9,217,217,217,1,219, + 219,219,1,215,215,215,1,255,255,255,1,167,167,167,1,169,169,169,1,164, + 164,164,1,223,223,223,1,218,218,218,1,253,253,253,1,217,217,217,1,173, + 173,173,1,216,216,216,1,215,215,215,1,167,167,167,1,218,218,218,1,217, + 217,217,1,220,220,220,1,217,217,217,1,221,221,221,1,216,216,216,1,220, + 220,220,1,214,214,214,1,217,217,217,1,218,218,218,1,215,215,215,1,222, + 222,222,1,218,218,218,1,221,221,221,1,253,253,253,1,216,216,216,1,221, + 221,221,1,214,214,214,1,171,171,171,1,255,255,255,1,222,222,222,1,217, + 217,217,1,218,218,218,1,221,221,221,1,216,216,216,1,254,254,254,1,255, + 255,255,1,217,217,217,1,214,214,214,1,221,221,221,1,216,216,216,1,255, + 255,255,1,217,217,217,1,219,219,219,1,214,214,214,1,222,222,222,1,217, + 217,217,1,219,219,219,1,216,216,216,1,167,167,167,1,171,171,171,1,214, + 214,214,1,255,255,255,1,218,218,218,1,170,170,170,1,163,163,163,1,219, + 219,219,2,217,217,217,1,221,221,221,1,215,215,215,1,167,167,167,2,220, + 220,220,1,218,218,218,1,217,217,217,2,218,218,218,1,216,216,216,1,219, + 219,219,2,216,216,216,1,224,224,224,1,218,218,218,1,215,215,215,1,255, + 255,255,1,214,214,214,1,222,222,222,1,218,218,218,1,216,216,216,1,169, + 169,169,1,165,165,165,1,172,172,172,1,170,170,170,1,163,163,163,1,170, + 170,170,1,217,217,217,1,216,216,216,1,221,221,221,1,215,215,215,1,217, + 217,217,1,220,220,220,1,253,253,253,1,255,255,255,1,215,215,215,1,221, + 221,221,1,218,218,218,1,219,219,219,1,253,253,253,2,218,218,218,1,221, + 221,221,1,167,167,167,1,170,170,170,1,215,215,215,1,255,255,255,1,220, + 220,220,1,167,167,167,1,218,218,218,1,217,217,217,1,218,218,218,1,167, + 167,167,1,168,168,168,1,213,213,213,1,222,222,222,1,163,163,163,1,220, + 220,220,2,251,251,251,1,255,255,255,1,221,221,221,1,215,215,215,1,220, + 220,220,1,168,168,168,1,216,216,216,1,218,218,218,1,224,224,224,1,214, + 214,214,1,221,221,221,2,212,212,212,1,220,220,220,1,221,221,221,1,218, + 218,218,1,219,219,219,1,216,216,216,1,218,218,218,9,221,221,221,1,216, + 216,216,1,255,255,255,1,252,252,252,1,168,168,168,1,169,169,169,1,168, + 168,168,1,165,165,165,1,170,170,170,1,219,219,219,1,169,169,169,1,166, + 166,166,1,219,219,219,1,218,218,218,1,223,223,223,1,219,219,219,2,216, + 216,216,1,168,168,168,1,216,216,216,1,220,220,220,1,217,217,217,1,215, + 215,215,1,221,221,221,1,217,217,217,1,223,223,223,1,215,215,215,1,217, + 217,217,1,219,219,219,1,218,218,218,1,219,219,219,1,251,251,251,1,218, + 218,218,1,219,219,219,1,167,167,167,1,215,215,215,1,217,217,217,1,216, + 216,216,1,218,218,218,1,217,217,217,1,219,219,219,1,216,216,216,1,217, + 217,217,1,220,220,220,1,217,217,217,1,214,214,214,1,219,219,219,2,215, + 215,215,1,221,221,221,1,218,218,218,1,216,216,216,1,219,219,219,1,220, + 220,220,1,167,167,167,1,165,165,165,1,171,171,171,1,214,214,214,1,167, + 167,167,1,168,168,168,1,167,167,167,1,168,168,168,1,169,169,169,1,167, + 167,167,1,166,166,166,1,170,170,170,1,168,168,168,1,167,167,167,1,166, + 166,166,1,217,217,217,1,220,220,220,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,169,169,169,1,255, + 255,255,2,253,253,253,1,222,222,222,1,215,215,215,1,216,216,216,1,255, + 255,255,1,217,217,217,4,169,169,169,2,216,216,216,1,222,222,222,1,215, + 215,215,1,220,220,220,2,215,215,215,1,218,218,218,1,255,255,255,1,219, + 219,219,1,218,218,218,1,217,217,217,2,222,222,222,1,218,218,218,2,217, + 217,217,1,220,220,220,1,163,163,163,1,172,172,172,1,216,216,216,1,218, + 218,218,1,222,222,222,1,215,215,215,1,220,220,220,1,219,219,219,1,167, + 167,167,1,218,218,218,1,222,222,222,1,168,168,168,1,219,219,219,1,216, + 216,216,1,218,218,218,2,168,168,168,1,215,215,215,1,222,222,222,1,215, + 215,215,1,219,219,219,1,220,220,220,1,218,218,218,1,216,216,216,1,218, + 218,218,1,217,217,217,2,221,221,221,1,217,217,217,1,215,215,215,1,222, + 222,222,1,218,218,218,1,215,215,215,1,219,219,219,1,218,218,218,9,217, + 217,217,1,255,255,255,2,220,220,220,1,165,165,165,1,167,167,167,1,171, + 171,171,1,165,165,165,1,220,220,220,1,169,169,169,1,166,166,166,1,255, + 255,255,1,216,216,216,2,166,166,166,1,220,220,220,1,218,218,218,1,220, + 220,220,1,216,216,216,1,217,217,217,1,216,216,216,1,223,223,223,1,217, + 217,217,1,220,220,220,1,214,214,214,1,220,220,220,1,221,221,221,1,217, + 217,217,2,222,222,222,1,255,255,255,1,218,218,218,1,216,216,216,1,220, + 220,220,1,219,219,219,1,220,220,220,1,165,165,165,1,220,220,220,1,219, + 219,219,2,220,220,220,1,218,218,218,2,219,219,219,1,255,255,255,1,219, + 219,219,1,214,214,214,1,255,255,255,1,250,250,250,1,221,221,221,1,216, + 216,216,1,218,218,218,1,216,216,216,1,217,217,217,1,170,170,170,1,169, + 169,169,1,217,217,217,1,222,222,222,1,169,169,169,1,168,168,168,4,221, + 221,221,1,213,213,213,1,171,171,171,2,169,169,169,1,220,220,220,1,219, + 219,219,1,217,217,217,1,223,223,223,1,213,213,213,1,219,219,219,1,218, + 218,218,2,216,216,216,1,220,220,220,1,218,218,218,1,220,220,220,1,217, + 217,217,1,218,218,218,1,255,255,255,2,254,254,254,1,222,222,222,1,218, + 218,218,1,217,217,217,1,168,168,168,1,218,218,218,1,220,220,220,1,215, + 215,215,1,217,217,217,1,219,219,219,1,216,216,216,1,217,217,217,1,219, + 219,219,1,215,215,215,1,216,216,216,1,220,220,220,1,218,218,218,1,216, + 216,216,2,217,217,217,1,220,220,220,1,217,217,217,1,255,255,255,1,170, + 170,170,1,218,218,218,2,217,217,217,1,219,219,219,2,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,1,255,255,255,1,215,215,215,1,220, + 220,220,1,219,219,219,1,218,218,218,1,219,219,219,1,220,220,220,1,167, + 167,167,1,253,253,253,1,219,219,219,2,215,215,215,2,218,218,218,1,220, + 220,220,1,218,218,218,1,216,216,216,1,220,220,220,1,215,215,215,1,217, + 217,217,1,218,218,218,1,216,216,216,1,219,219,219,1,218,218,218,9,217, + 217,217,1,218,218,218,1,255,255,255,2,253,253,253,1,255,255,255,1,218, + 218,218,1,216,216,216,1,218,218,218,1,219,219,219,1,215,215,215,1,220, + 220,220,1,218,218,218,1,216,216,216,1,223,223,223,1,217,217,217,1,253, + 253,253,1,220,220,220,1,215,215,215,1,218,218,218,1,223,223,223,1,217, + 217,217,2,164,164,164,1,169,169,169,1,219,219,219,1,216,216,216,1,219, + 219,219,1,217,217,217,1,219,219,219,1,217,217,217,2,255,255,255,1,220, + 220,220,1,216,216,216,1,221,221,221,1,217,217,217,2,218,218,218,1,216, + 216,216,1,217,217,217,1,214,214,214,1,217,217,217,1,218,218,218,1,255, + 255,255,1,252,252,252,1,255,255,255,4,252,252,252,1,218,218,218,1,220, + 220,220,1,218,218,218,1,216,216,216,1,219,219,219,1,215,215,215,1,222, + 222,222,1,251,251,251,1,253,253,253,1,255,255,255,1,215,215,215,1,220, + 220,220,1,218,218,218,1,216,216,216,1,221,221,221,1,218,218,218,1,164, + 164,164,1,168,168,168,1,167,167,167,2,219,219,219,1,214,214,214,1,221, + 221,221,1,219,219,219,1,253,253,253,1,219,219,219,1,220,220,220,1,217, + 217,217,2,216,216,216,1,218,218,218,2,255,255,255,1,253,253,253,1,255, + 255,255,1,254,254,254,1,216,216,216,1,218,218,218,3,216,216,216,1,220, + 220,220,1,171,171,171,1,215,215,215,1,222,222,222,1,219,219,219,1,218, + 218,218,1,220,220,220,1,222,222,222,1,217,217,217,2,255,255,255,1,218, + 218,218,1,255,255,255,1,215,215,215,1,255,255,255,1,217,217,217,1,255, + 255,255,1,254,254,254,1,221,221,221,1,215,215,215,1,218,218,218,1,167, + 167,167,1,220,220,220,1,215,215,215,1,221,221,221,2,216,216,216,1,221, + 221,221,1,219,219,219,1,217,217,217,1,255,255,255,1,167,167,167,2,169, + 169,169,1,168,168,168,1,218,218,218,1,220,220,220,1,221,221,221,2,219, + 219,219,1,215,215,215,1,219,219,219,1,220,220,220,1,219,219,219,2,221, + 221,221,1,218,218,218,2,216,216,216,1,219,219,219,1,218,218,218,8,220, + 220,220,1,217,217,217,1,254,254,254,1,255,255,255,6,253,253,253,1,220, + 220,220,1,219,219,219,1,216,216,216,1,255,255,255,1,216,216,216,1,218, + 218,218,2,220,220,220,1,218,218,218,1,220,220,220,1,217,217,217,1,213, + 213,213,1,223,223,223,1,170,170,170,1,168,168,168,1,218,218,218,1,219, + 219,219,1,215,215,215,1,220,220,220,2,217,217,217,1,222,222,222,1,215, + 215,215,1,216,216,216,1,219,219,219,1,251,251,251,1,222,222,222,1,216, + 216,216,1,218,218,218,1,220,220,220,1,219,219,219,1,221,221,221,1,217, + 217,217,1,219,219,219,1,255,255,255,2,213,213,213,1,220,220,220,1,251, + 251,251,1,255,255,255,1,253,253,253,1,218,218,218,1,219,219,219,1,218, + 218,218,2,217,217,217,1,220,220,220,1,216,216,216,1,220,220,220,1,255, + 255,255,1,214,214,214,1,255,255,255,1,253,253,253,1,217,217,217,1,255, + 255,255,1,219,219,219,1,217,217,217,1,170,170,170,1,171,171,171,1,166, + 166,166,1,167,167,167,1,170,170,170,1,171,171,171,1,217,217,217,1,218, + 218,218,1,216,216,216,1,221,221,221,1,216,216,216,1,218,218,218,2,219, + 219,219,1,218,218,218,1,216,216,216,1,218,218,218,1,255,255,255,2,252, + 252,252,1,221,221,221,1,169,169,169,1,219,219,219,1,167,167,167,1,166, + 166,166,1,219,219,219,1,214,214,214,1,218,218,218,2,219,219,219,1,214, + 214,214,1,217,217,217,1,212,212,212,1,170,170,170,1,219,219,219,1,215, + 215,215,1,254,254,254,1,255,255,255,1,218,218,218,1,251,251,251,1,222, + 222,222,1,253,253,253,1,220,220,220,1,217,217,217,1,255,255,255,2,252, + 252,252,1,255,255,255,2,216,216,216,1,215,215,215,1,219,219,219,1,217, + 217,217,1,220,220,220,1,167,167,167,1,168,168,168,1,220,220,220,1,169, + 169,169,1,165,165,165,1,220,220,220,1,216,216,216,1,219,219,219,1,166, + 166,166,1,219,219,219,1,217,217,217,1,220,220,220,1,216,216,216,2,217, + 217,217,3,219,219,219,2,215,215,215,1,220,220,220,1,218,218,218,11,217, + 217,217,1,254,254,254,1,255,255,255,1,250,250,250,1,254,254,254,1,220, + 220,220,1,217,217,217,1,216,216,216,1,220,220,220,1,216,216,216,1,217, + 217,217,1,220,220,220,1,219,219,219,1,218,218,218,1,215,215,215,1,219, + 219,219,1,217,217,217,2,255,255,255,1,215,215,215,1,166,166,166,1,216, + 216,216,1,219,219,219,1,220,220,220,1,218,218,218,2,215,215,215,1,219, + 219,219,1,214,214,214,1,220,220,220,1,215,215,215,1,222,222,222,1,220, + 220,220,1,216,216,216,1,218,218,218,1,217,217,217,3,216,216,216,1,217, + 217,217,1,168,168,168,1,219,219,219,1,216,216,216,1,218,218,218,1,216, + 216,216,1,218,218,218,1,255,255,255,2,219,219,219,1,215,215,215,1,219, + 219,219,2,218,218,218,1,168,168,168,1,167,167,167,1,165,165,165,1,253, + 253,253,1,255,255,255,5,216,216,216,1,218,218,218,1,255,255,255,1,254, + 254,254,1,220,220,220,1,215,215,215,1,217,217,217,1,165,165,165,1,217, + 217,217,1,220,220,220,2,216,216,216,1,215,215,215,1,222,222,222,1,215, + 215,215,1,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,213, + 213,213,1,255,255,255,2,168,168,168,2,167,167,167,1,168,168,168,1,220, + 220,220,1,216,216,216,1,222,222,222,1,220,220,220,1,215,215,215,1,216, + 216,216,1,221,221,221,1,219,219,219,2,169,169,169,1,216,216,216,1,219, + 219,219,1,218,218,218,1,216,216,216,1,221,221,221,1,169,169,169,1,215, + 215,215,1,220,220,220,1,216,216,216,1,219,219,219,1,253,253,253,1,218, + 218,218,1,221,221,221,1,255,255,255,1,253,253,253,1,221,221,221,1,168, + 168,168,1,167,167,167,1,169,169,169,1,215,215,215,1,220,220,220,1,217, + 217,217,2,216,216,216,1,171,171,171,1,167,167,167,1,219,219,219,1,218, + 218,218,1,216,216,216,1,221,221,221,1,215,215,215,1,218,218,218,1,220, + 220,220,1,218,218,218,1,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,218,218,218,8,217, + 217,217,1,219,219,219,1,216,216,216,1,223,223,223,1,215,215,215,1,216, + 216,216,1,222,222,222,1,217,217,217,2,219,219,219,2,216,216,216,1,219, + 219,219,1,221,221,221,1,216,216,216,1,217,217,217,2,221,221,221,1,217, + 217,217,1,216,216,216,1,223,223,223,1,253,253,253,1,254,254,254,1,169, + 169,169,1,170,170,170,1,218,218,218,1,217,217,217,2,219,219,219,1,218, + 218,218,1,219,219,219,2,218,218,218,1,219,219,219,1,217,217,217,1,215, + 215,215,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,217, + 217,217,1,222,222,222,1,167,167,167,2,166,166,166,1,220,220,220,1,217, + 217,217,1,168,168,168,1,218,218,218,1,254,254,254,1,219,219,219,1,218, + 218,218,1,217,217,217,1,219,219,219,1,217,217,217,1,218,218,218,2,168, + 168,168,1,255,255,255,1,220,220,220,1,218,218,218,1,253,253,253,1,218, + 218,218,1,255,255,255,1,254,254,254,1,255,255,255,1,218,218,218,1,217, + 217,217,1,255,255,255,1,253,253,253,1,222,222,222,1,168,168,168,1,169, + 169,169,1,168,168,168,1,217,217,217,2,220,220,220,1,217,217,217,2,219, + 219,219,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,220, + 220,220,1,255,255,255,2,216,216,216,1,219,219,219,1,218,218,218,1,167, + 167,167,1,169,169,169,1,167,167,167,1,217,217,217,1,219,219,219,1,218, + 218,218,2,219,219,219,1,255,255,255,1,251,251,251,1,255,255,255,1,217, + 217,217,1,169,169,169,2,217,217,217,1,253,253,253,1,220,220,220,1,219, + 219,219,1,217,217,217,1,218,218,218,3,168,168,168,2,215,215,215,1,220, + 220,220,1,169,169,169,1,168,168,168,1,166,166,166,1,255,255,255,1,216, + 216,216,1,218,218,218,2,217,217,217,1,168,168,168,1,170,170,170,1,169, + 169,169,1,218,218,218,3,217,217,217,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,218,218,218,3,217,217,217,1,220,220,220,1,216, + 216,216,1,218,218,218,17,219,219,219,1,217,217,217,1,220,220,220,1,218, + 218,218,2,219,219,219,1,216,216,216,1,218,218,218,3,220,220,220,1,214, + 214,214,1,255,255,255,2,215,215,215,1,170,170,170,1,168,168,168,1,165, + 165,165,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,3,216,216,216,1,221,221,221,1,218,218,218,1,168,168,168,1,167, + 167,167,1,217,217,217,1,218,218,218,2,219,219,219,1,168,168,168,1,170, + 170,170,1,166,166,166,1,169,169,169,1,170,170,170,1,165,165,165,1,169, + 169,169,1,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,220,220,220,1,218,218,218,1,220,220,220,1,164,164,164,1,220, + 220,220,1,218,218,218,2,219,219,219,1,218,218,218,1,255,255,255,1,254, + 254,254,1,168,168,168,2,170,170,170,1,168,168,168,1,216,216,216,1,218, + 218,218,1,169,169,169,1,168,168,168,1,218,218,218,1,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,221,221,221,1,217,217,217,1,219, + 219,219,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,255, + 255,255,2,218,218,218,1,216,216,216,1,219,219,219,1,170,170,170,1,168, + 168,168,2,220,220,220,1,217,217,217,2,220,220,220,1,216,216,216,1,255, + 255,255,2,214,214,214,1,221,221,221,1,167,167,167,1,252,252,252,1,255, + 255,255,1,221,221,221,2,213,213,213,1,218,218,218,2,254,254,254,1,255, + 255,255,1,217,217,217,2,224,224,224,1,252,252,252,1,255,255,255,1,254, + 254,254,1,219,219,219,1,218,218,218,1,217,217,217,1,219,219,219,2,218, + 218,218,1,215,215,215,1,169,169,169,1,168,168,168,1,167,167,167,1,168, + 168,168,1,217,217,217,1,218,218,218,1,219,219,219,1,216,216,216,1,220, + 220,220,2,218,218,218,1,215,215,215,1,219,219,219,1,221,221,221,1,213, + 213,213,1,220,220,220,1,218,218,218,18,220,220,220,1,216,216,216,2,217, + 217,217,1,220,220,220,2,169,169,169,1,218,218,218,1,219,219,219,1,218, + 218,218,3,255,255,255,1,217,217,217,1,167,167,167,1,169,169,169,1,220, + 220,220,1,216,216,216,2,219,219,219,2,217,217,217,1,219,219,219,2,215, + 215,215,1,218,218,218,2,216,216,216,1,220,220,220,1,218,218,218,1,219, + 219,219,1,255,255,255,1,217,217,217,2,167,167,167,1,171,171,171,1,253, + 253,253,1,165,165,165,1,172,172,172,1,215,215,215,1,221,221,221,1,215, + 215,215,1,217,217,217,1,221,221,221,1,254,254,254,1,253,253,253,1,219, + 219,219,1,168,168,168,2,220,220,220,1,219,219,219,1,216,216,216,3,218, + 218,218,1,255,255,255,2,168,168,168,1,162,162,162,1,219,219,219,1,220, + 220,220,1,215,215,215,1,220,220,220,1,168,168,168,1,216,216,216,1,221, + 221,221,1,219,219,219,1,215,215,215,1,221,221,221,1,217,217,217,1,219, + 219,219,1,216,216,216,1,220,220,220,2,216,216,216,1,217,217,217,1,172, + 172,172,1,218,218,218,2,255,255,255,2,212,212,212,1,169,169,169,1,167, + 167,167,1,166,166,166,1,218,218,218,1,220,220,220,1,217,217,217,1,220, + 220,220,1,218,218,218,2,255,255,255,2,220,220,220,1,169,169,169,1,168, + 168,168,1,217,217,217,1,215,215,215,1,221,221,221,1,219,219,219,1,216, + 216,216,1,255,255,255,2,217,217,217,1,215,215,215,1,254,254,254,1,255, + 255,255,1,218,218,218,1,169,169,169,1,217,217,217,1,220,220,220,1,218, + 218,218,2,219,219,219,1,218,218,218,2,216,216,216,1,168,168,168,1,170, + 170,170,1,165,165,165,1,220,220,220,1,216,216,216,1,223,223,223,1,217, + 217,217,1,216,216,216,1,215,215,215,1,219,219,219,1,217,217,217,1,215, + 215,215,1,217,217,217,1,220,220,220,1,219,219,219,1,217,217,217,1,218, + 218,218,16,217,217,217,2,221,221,221,1,218,218,218,1,220,220,220,1,222, + 222,222,1,212,212,212,1,167,167,167,1,218,218,218,1,214,214,214,1,218, + 218,218,1,220,220,220,1,216,216,216,1,253,253,253,1,221,221,221,1,219, + 219,219,1,217,217,217,1,216,216,216,1,220,220,220,2,217,217,217,1,218, + 218,218,1,168,168,168,2,169,169,169,1,221,221,221,1,253,253,253,1,255, + 255,255,1,166,166,166,1,218,218,218,1,219,219,219,1,254,254,254,1,255, + 255,255,2,217,217,217,1,220,220,220,1,253,253,253,1,255,255,255,2,217, + 217,217,1,218,218,218,1,216,216,216,1,221,221,221,1,219,219,219,1,218, + 218,218,1,222,222,222,1,251,251,251,1,220,220,220,1,165,165,165,1,170, + 170,170,1,165,165,165,1,217,217,217,1,219,219,219,1,221,221,221,1,220, + 220,220,1,254,254,254,2,220,220,220,1,214,214,214,1,176,176,176,1,219, + 219,219,1,216,216,216,1,220,220,220,1,165,165,165,1,168,168,168,1,170, + 170,170,1,167,167,167,2,222,222,222,1,216,216,216,1,167,167,167,1,219, + 219,219,1,218,218,218,2,216,216,216,1,168,168,168,1,218,218,218,1,214, + 214,214,1,218,218,218,1,255,255,255,1,254,254,254,1,219,219,219,1,216, + 216,216,1,222,222,222,1,218,218,218,1,220,220,220,1,216,216,216,1,220, + 220,220,1,218,218,218,1,216,216,216,1,220,220,220,1,219,219,219,1,253, + 253,253,1,216,216,216,1,217,217,217,1,168,168,168,1,167,167,167,1,219, + 219,219,1,168,168,168,1,217,217,217,1,219,219,219,2,165,165,165,1,167, + 167,167,1,220,220,220,1,219,219,219,1,222,222,222,1,164,164,164,1,171, + 171,171,1,218,218,218,4,216,216,216,1,219,219,219,3,220,220,220,1,219, + 219,219,1,165,165,165,1,172,172,172,1,217,217,217,1,220,220,220,1,215, + 215,215,1,218,218,218,1,220,220,220,1,218,218,218,1,219,219,219,4,218, + 218,218,1,215,215,215,1,219,219,219,1,218,218,218,16,216,216,216,1,219, + 219,219,1,218,218,218,2,216,216,216,1,255,255,255,1,223,223,223,1,168, + 168,168,1,169,169,169,1,170,170,170,1,171,171,171,1,165,165,165,1,255, + 255,255,1,254,254,254,1,253,253,253,1,216,216,216,1,168,168,168,1,172, + 172,172,1,168,168,168,1,215,215,215,1,220,220,220,1,218,218,218,1,217, + 217,217,1,168,168,168,1,215,215,215,1,219,219,219,1,218,218,218,1,215, + 215,215,1,221,221,221,1,218,218,218,2,255,255,255,1,254,254,254,1,251, + 251,251,1,255,255,255,1,217,217,217,1,255,255,255,1,254,254,254,1,252, + 252,252,1,218,218,218,1,221,221,221,1,219,219,219,1,217,217,217,1,166, + 166,166,1,217,217,217,1,252,252,252,1,255,255,255,2,169,169,169,1,167, + 167,167,2,170,170,170,1,219,219,219,1,216,216,216,1,214,214,214,1,220, + 220,220,1,254,254,254,1,219,219,219,1,218,218,218,1,214,214,214,1,217, + 217,217,1,219,219,219,2,168,168,168,1,167,167,167,2,170,170,170,1,168, + 168,168,1,167,167,167,1,170,170,170,1,214,214,214,1,220,220,220,2,216, + 216,216,1,221,221,221,1,220,220,220,1,217,217,217,1,221,221,221,1,166, + 166,166,1,168,168,168,1,255,255,255,1,219,219,219,1,217,217,217,1,252, + 252,252,1,219,219,219,1,217,217,217,1,221,221,221,1,216,216,216,1,220, + 220,220,1,218,218,218,2,214,214,214,1,219,219,219,1,255,255,255,2,169, + 169,169,2,216,216,216,1,169,169,169,1,219,219,219,1,216,216,216,1,168, + 168,168,1,220,220,220,1,216,216,216,1,221,221,221,1,219,219,219,1,214, + 214,214,1,217,217,217,1,219,219,219,1,215,215,215,1,216,216,216,1,220, + 220,220,1,222,222,222,1,217,217,217,1,219,219,219,1,214,214,214,1,218, + 218,218,1,216,216,216,2,169,169,169,1,166,166,166,1,218,218,218,1,220, + 220,220,1,214,214,214,1,222,222,222,1,214,214,214,1,217,217,217,1,219, + 219,219,1,215,215,215,1,220,220,220,1,217,217,217,1,218,218,218,19,220, + 220,220,1,218,218,218,1,216,216,216,1,223,223,223,1,214,214,214,1,255, + 255,255,1,215,215,215,1,219,219,219,1,168,168,168,1,219,219,219,1,165, + 165,165,1,166,166,166,1,217,217,217,1,253,253,253,1,222,222,222,1,219, + 219,219,1,166,166,166,1,165,165,165,1,170,170,170,1,218,218,218,1,255, + 255,255,1,253,253,253,1,220,220,220,1,168,168,168,1,220,220,220,1,217, + 217,217,1,255,255,255,1,221,221,221,1,214,214,214,1,220,220,220,1,217, + 217,217,1,219,219,219,1,255,255,255,2,217,217,217,1,218,218,218,1,216, + 216,216,1,255,255,255,3,215,215,215,1,219,219,219,1,216,216,216,1,254, + 254,254,1,221,221,221,1,255,255,255,2,254,254,254,1,218,218,218,1,168, + 168,168,3,165,165,165,1,217,217,217,1,224,224,224,1,253,253,253,1,255, + 255,255,1,218,218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,218, + 218,218,1,216,216,216,1,217,217,217,1,218,218,218,1,219,219,219,1,169, + 169,169,1,165,165,165,1,220,220,220,1,168,168,168,1,169,169,169,1,219, + 219,219,1,217,217,217,1,255,255,255,1,218,218,218,1,254,254,254,1,255, + 255,255,1,216,216,216,1,167,167,167,1,254,254,254,2,169,169,169,2,219, + 219,219,1,217,217,217,1,221,221,221,1,218,218,218,1,217,217,217,1,214, + 214,214,1,219,219,219,1,217,217,217,1,221,221,221,1,219,219,219,1,252, + 252,252,2,172,172,172,1,254,254,254,1,218,218,218,1,221,221,221,1,215, + 215,215,1,217,217,217,1,255,255,255,1,170,170,170,1,166,166,166,2,218, + 218,218,1,222,222,222,1,219,219,219,1,217,217,217,1,221,221,221,1,218, + 218,218,1,217,217,217,1,214,214,214,1,221,221,221,1,217,217,217,1,220, + 220,220,1,221,221,221,1,216,216,216,1,218,218,218,1,174,174,174,1,166, + 166,166,1,214,214,214,1,221,221,221,1,219,219,219,3,220,220,220,1,215, + 215,215,1,221,221,221,1,214,214,214,1,218,218,218,1,170,170,170,1,166, + 166,166,1,221,221,221,1,218,218,218,16,217,217,217,1,219,219,219,2,214, + 214,214,1,223,223,223,1,254,254,254,1,255,255,255,3,253,253,253,1,168, + 168,168,2,221,221,221,1,220,220,220,1,252,252,252,1,254,254,254,2,220, + 220,220,1,218,218,218,1,219,219,219,1,217,217,217,1,255,255,255,1,217, + 217,217,1,216,216,216,1,218,218,218,1,217,217,217,2,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,218,218,218,1,217,217,217,1,221, + 221,221,1,216,216,216,1,220,220,220,1,219,219,219,1,253,253,253,1,254, + 254,254,2,220,220,220,1,218,218,218,1,168,168,168,1,220,220,220,1,216, + 216,216,1,217,217,217,1,216,216,216,1,220,220,220,1,217,217,217,1,218, + 218,218,1,169,169,169,1,168,168,168,1,166,166,166,1,171,171,171,1,165, + 165,165,1,254,254,254,2,219,219,219,2,217,217,217,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,220,220,220,1,216,216,216,1,218, + 218,218,2,165,165,165,1,167,167,167,1,220,220,220,1,215,215,215,1,218, + 218,218,1,255,255,255,1,249,249,249,1,254,254,254,1,255,255,255,2,167, + 167,167,1,255,255,255,1,222,222,222,1,213,213,213,1,219,219,219,1,220, + 220,220,1,216,216,216,1,215,215,215,1,218,218,218,1,220,220,220,1,219, + 219,219,2,216,216,216,2,219,219,219,1,255,255,255,2,213,213,213,1,255, + 255,255,1,217,217,217,1,168,168,168,1,255,255,255,1,220,220,220,1,218, + 218,218,1,166,166,166,1,172,172,172,1,218,218,218,1,217,217,217,2,214, + 214,214,1,218,218,218,1,217,217,217,1,219,219,219,3,217,217,217,1,219, + 219,219,1,216,216,216,1,218,218,218,1,219,219,219,1,220,220,220,1,162, + 162,162,1,220,220,220,1,219,219,219,2,217,217,217,2,219,219,219,1,215, + 215,215,1,220,220,220,1,219,219,219,1,216,216,216,1,169,169,169,1,168, + 168,168,1,167,167,167,1,166,166,166,1,218,218,218,16,217,217,217,1,218, + 218,218,2,219,219,219,1,217,217,217,2,255,255,255,1,217,217,217,1,254, + 254,254,1,255,255,255,2,169,169,169,1,168,168,168,1,215,215,215,1,255, + 255,255,1,219,219,219,1,255,255,255,1,220,220,220,1,218,218,218,1,216, + 216,216,1,255,255,255,1,251,251,251,1,219,219,219,1,222,222,222,1,218, + 218,218,1,221,221,221,1,217,217,217,1,219,219,219,1,217,217,217,1,215, + 215,215,1,219,219,219,1,218,218,218,1,217,217,217,1,218,218,218,1,222, + 222,222,1,217,217,217,1,216,216,216,1,220,220,220,1,254,254,254,1,255, + 255,255,1,254,254,254,1,219,219,219,2,217,217,217,1,218,218,218,1,220, + 220,220,1,218,218,218,1,254,254,254,1,216,216,216,1,219,219,219,1,218, + 218,218,1,167,167,167,1,168,168,168,1,169,169,169,1,167,167,167,1,219, + 219,219,1,255,255,255,1,220,220,220,1,218,218,218,1,216,216,216,1,219, + 219,219,1,217,217,217,1,220,220,220,1,216,216,216,1,215,215,215,1,221, + 221,221,1,218,218,218,1,219,219,219,2,171,171,171,1,167,167,167,1,170, + 170,170,1,168,168,168,1,214,214,214,1,221,221,221,1,219,219,219,1,255, + 255,255,1,217,217,217,1,218,218,218,1,255,255,255,2,219,219,219,1,215, + 215,215,1,219,219,219,1,218,218,218,1,219,219,219,1,218,218,218,2,216, + 216,216,1,221,221,221,1,217,217,217,1,218,218,218,2,255,255,255,1,217, + 217,217,1,220,220,220,1,218,218,218,2,255,255,255,1,221,221,221,1,253, + 253,253,1,254,254,254,1,217,217,217,1,218,218,218,2,219,219,219,1,218, + 218,218,1,221,221,221,1,218,218,218,3,217,217,217,1,220,220,220,1,216, + 216,216,1,217,217,217,1,219,219,219,1,218,218,218,2,217,217,217,1,172, + 172,172,1,219,219,219,1,217,217,217,3,219,219,219,1,218,218,218,1,220, + 220,220,1,214,214,214,1,218,218,218,1,255,255,255,1,219,219,219,1,167, + 167,167,1,219,219,219,1,216,216,216,1,218,218,218,16,220,220,220,1,216, + 216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,218,218,218,1,217, + 217,217,1,218,218,218,1,255,255,255,2,219,219,219,1,218,218,218,1,215, + 215,215,1,222,222,222,1,217,217,217,1,168,168,168,1,217,217,217,1,218, + 218,218,2,219,219,219,1,217,217,217,1,220,220,220,1,219,219,219,1,216, + 216,216,2,220,220,220,1,217,217,217,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,1,219,219,219,1,220,220,220,1,216,216,216,1,218, + 218,218,3,219,219,219,1,255,255,255,1,254,254,254,1,255,255,255,1,215, + 215,215,1,218,218,218,1,217,217,217,1,255,255,255,1,252,252,252,1,255, + 255,255,3,217,217,217,1,216,216,216,1,221,221,221,1,215,215,215,1,167, + 167,167,1,169,169,169,1,218,218,218,1,219,219,219,1,215,215,215,1,217, + 217,217,1,222,222,222,1,216,216,216,1,218,218,218,1,220,220,220,1,218, + 218,218,1,219,219,219,2,216,216,216,1,220,220,220,1,166,166,166,1,169, + 169,169,1,167,167,167,2,169,169,169,1,218,218,218,2,217,217,217,1,252, + 252,252,1,222,222,222,1,253,253,253,1,219,219,219,1,217,217,217,1,219, + 219,219,1,220,220,220,1,218,218,218,2,217,217,217,1,218,218,218,9,219, + 219,219,1,254,254,254,1,219,219,219,1,216,216,216,1,220,220,220,1,254, + 254,254,1,255,255,255,1,219,219,219,1,252,252,252,1,255,255,255,1,253, + 253,253,1,216,216,216,1,218,218,218,1,217,217,217,1,218,218,218,2,219, + 219,219,1,221,221,221,1,215,215,215,1,220,220,220,1,218,218,218,1,215, + 215,215,1,221,221,221,1,169,169,169,1,167,167,167,1,217,217,217,1,219, + 219,219,1,218,218,218,3,219,219,219,1,217,217,217,1,218,218,218,1,217, + 217,217,1,220,220,220,1,216,216,216,1,255,255,255,1,221,221,221,1,216, + 216,216,1,215,215,215,1,223,223,223,1,216,216,216,1,219,219,219,2,217, + 217,217,4,218,218,218,2,216,216,216,1,220,220,220,1,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,220,220,220,1,218,218,218,2,217, + 217,217,1,218,218,218,1,220,220,220,1,218,218,218,1,217,217,217,1,255, + 255,255,1,254,254,254,1,215,215,215,1,219,219,219,1,255,255,255,1,221, + 221,221,1,216,216,216,1,219,219,219,1,216,216,216,1,219,219,219,1,217, + 217,217,1,216,216,216,1,218,218,218,3,217,217,217,1,219,219,219,1,217, + 217,217,1,218,218,218,1,220,220,220,2,219,219,219,1,217,217,217,1,219, + 219,219,1,217,217,217,1,218,218,218,2,217,217,217,1,218,218,218,1,216, + 216,216,1,219,219,219,1,218,218,218,1,166,166,166,1,219,219,219,1,218, + 218,218,1,217,217,217,1,170,170,170,1,251,251,251,1,255,255,255,2,214, + 214,214,1,219,219,219,1,220,220,220,1,218,218,218,1,221,221,221,1,168, + 168,168,1,218,218,218,1,216,216,216,1,222,222,222,1,217,217,217,2,220, + 220,220,1,216,216,216,2,220,220,220,1,218,218,218,1,217,217,217,1,220, + 220,220,1,218,218,218,1,216,216,216,1,222,222,222,1,215,215,215,1,169, + 169,169,1,168,168,168,1,169,169,169,1,221,221,221,1,215,215,215,1,219, + 219,219,1,217,217,217,1,218,218,218,1,217,217,217,1,218,218,218,14,222, + 222,222,1,213,213,213,1,218,218,218,1,217,217,217,1,219,219,219,1,217, + 217,217,1,255,255,255,1,253,253,253,2,255,255,255,1,250,250,250,1,253, + 253,253,1,226,226,226,1,218,218,218,1,217,217,217,1,219,219,219,1,217, + 217,217,1,220,220,220,1,215,215,215,1,218,218,218,1,217,217,217,1,220, + 220,220,1,219,219,219,1,216,216,216,1,167,167,167,1,168,168,168,1,219, + 219,219,1,168,168,168,3,218,218,218,1,216,216,216,1,217,217,217,1,170, + 170,170,1,219,219,219,1,216,216,216,1,172,172,172,1,167,167,167,1,218, + 218,218,1,221,221,221,1,219,219,219,2,218,218,218,1,216,216,216,1,215, + 215,215,1,221,221,221,1,220,220,220,1,219,219,219,1,220,220,220,1,218, + 218,218,1,219,219,219,1,218,218,218,2,219,219,219,1,218,218,218,1,216, + 216,216,1,221,221,221,1,215,215,215,1,220,220,220,1,219,219,219,1,217, + 217,217,3,216,216,216,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,1,220,220,220,1,251,251,251,1,216,216,216,1,167,167,167,1,220, + 220,220,1,214,214,214,1,220,220,220,2,221,221,221,1,216,216,216,1,219, + 219,219,3,217,217,217,1,219,219,219,1,214,214,214,1,217,217,217,1,216, + 216,216,2,220,220,220,1,218,218,218,1,219,219,219,2,220,220,220,1,217, + 217,217,1,219,219,219,1,221,221,221,1,216,216,216,1,168,168,168,1,170, + 170,170,1,167,167,167,1,168,168,168,1,215,215,215,1,217,217,217,1,219, + 219,219,1,255,255,255,1,253,253,253,1,255,255,255,1,220,220,220,1,213, + 213,213,1,255,255,255,1,253,253,253,1,216,216,216,1,220,220,220,1,221, + 221,221,1,214,214,214,1,220,220,220,1,218,218,218,1,216,216,216,1,222, + 222,222,1,219,219,219,1,215,215,215,1,218,218,218,1,221,221,221,1,214, + 214,214,1,218,218,218,1,254,254,254,1,255,255,255,1,216,216,216,1,170, + 170,170,1,167,167,167,1,168,168,168,1,165,165,165,1,220,220,220,1,219, + 219,219,2,218,218,218,16,214,214,214,1,220,220,220,1,219,219,219,1,221, + 221,221,1,216,216,216,1,220,220,220,1,255,255,255,1,217,217,217,2,223, + 223,223,1,253,253,253,1,255,255,255,1,213,213,213,1,218,218,218,1,217, + 217,217,1,219,219,219,2,217,217,217,1,218,218,218,1,223,223,223,1,216, + 216,216,1,217,217,217,2,221,221,221,1,166,166,166,1,168,168,168,1,167, + 167,167,1,170,170,170,2,166,166,166,1,170,170,170,1,218,218,218,1,255, + 255,255,1,220,220,220,1,217,217,217,1,166,166,166,1,169,169,169,1,168, + 168,168,1,215,215,215,1,218,218,218,1,219,219,219,1,214,214,214,1,216, + 216,216,1,224,224,224,1,167,167,167,1,165,165,165,1,218,218,218,3,165, + 165,165,1,219,219,219,1,217,217,217,1,221,221,221,1,214,214,214,1,218, + 218,218,1,221,221,221,1,219,219,219,1,217,217,217,1,218,218,218,2,221, + 221,221,1,219,219,219,3,217,217,217,1,216,216,216,1,219,219,219,1,217, + 217,217,1,218,218,218,1,220,220,220,1,221,221,221,1,219,219,219,1,166, + 166,166,1,222,222,222,1,216,216,216,1,218,218,218,1,215,215,215,1,219, + 219,219,1,221,221,221,1,215,215,215,1,217,217,217,1,218,218,218,1,220, + 220,220,2,219,219,219,1,220,220,220,1,218,218,218,2,215,215,215,1,222, + 222,222,1,216,216,216,1,214,214,214,1,169,169,169,1,166,166,166,1,217, + 217,217,1,255,255,255,1,217,217,217,1,215,215,215,1,255,255,255,1,254, + 254,254,1,221,221,221,1,222,222,222,1,216,216,216,1,254,254,254,1,255, + 255,255,1,254,254,254,1,217,217,217,1,218,218,218,1,221,221,221,1,255, + 255,255,4,254,254,254,1,255,255,255,1,219,219,219,1,218,218,218,1,217, + 217,217,1,219,219,219,1,221,221,221,1,218,218,218,1,216,216,216,1,221, + 221,221,1,255,255,255,2,253,253,253,1,255,255,255,1,252,252,252,1,169, + 169,169,1,168,168,168,1,170,170,170,1,165,165,165,1,219,219,219,1,218, + 218,218,1,221,221,221,1,215,215,215,1,218,218,218,14,219,219,219,1,218, + 218,218,2,216,216,216,1,218,218,218,1,217,217,217,1,219,219,219,2,216, + 216,216,2,255,255,255,3,218,218,218,1,217,217,217,2,218,218,218,2,217, + 217,217,3,218,218,218,1,220,220,220,1,216,216,216,1,168,168,168,1,218, + 218,218,1,220,220,220,1,215,215,215,1,165,165,165,1,170,170,170,1,165, + 165,165,1,221,221,221,1,215,215,215,1,218,218,218,2,220,220,220,1,167, + 167,167,1,169,169,169,1,221,221,221,1,218,218,218,2,220,220,220,1,167, + 167,167,3,221,221,221,1,217,217,217,2,216,216,216,1,222,222,222,1,215, + 215,215,1,219,219,219,1,216,216,216,1,222,222,222,1,217,217,217,2,218, + 218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,217,217,217,1,215, + 215,215,1,220,220,220,1,216,216,216,1,220,220,220,1,218,218,218,2,221, + 221,221,1,215,215,215,1,218,218,218,1,163,163,163,1,219,219,219,1,168, + 168,168,1,220,220,220,1,216,216,216,1,219,219,219,2,216,216,216,1,218, + 218,218,1,220,220,220,1,169,169,169,1,217,217,217,1,215,215,215,1,219, + 219,219,1,216,216,216,2,222,222,222,1,215,215,215,1,217,217,217,2,220, + 220,220,1,219,219,219,2,221,221,221,1,254,254,254,1,255,255,255,3,165, + 165,165,1,217,217,217,1,219,219,219,1,215,215,215,1,217,217,217,1,220, + 220,220,1,255,255,255,1,254,254,254,1,220,220,220,1,217,217,217,1,254, + 254,254,2,255,255,255,1,219,219,219,1,255,255,255,2,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,217, + 217,217,4,255,255,255,2,254,254,254,1,255,255,255,1,253,253,253,1,171, + 171,171,1,165,165,165,1,169,169,169,1,222,222,222,1,215,215,215,1,216, + 216,216,1,218,218,218,15,219,219,219,1,216,216,216,1,217,217,217,1,172, + 172,172,1,216,216,216,1,220,220,220,1,219,219,219,1,216,216,216,1,218, + 218,218,1,219,219,219,1,255,255,255,1,252,252,252,1,253,253,253,1,219, + 219,219,2,217,217,217,1,216,216,216,1,221,221,221,1,215,215,215,1,220, + 220,220,1,219,219,219,1,216,216,216,1,220,220,220,1,218,218,218,1,219, + 219,219,1,216,216,216,1,218,218,218,3,217,217,217,1,222,222,222,1,250, + 250,250,1,220,220,220,1,216,216,216,1,222,222,222,1,215,215,215,1,167, + 167,167,1,166,166,166,1,215,215,215,1,220,220,220,1,218,218,218,1,217, + 217,217,1,255,255,255,1,218,218,218,1,172,172,172,1,217,217,217,1,220, + 220,220,1,254,254,254,1,221,221,221,1,217,217,217,1,219,219,219,1,218, + 218,218,1,216,216,216,1,218,218,218,1,217,217,217,1,220,220,220,1,219, + 219,219,1,215,215,215,1,218,218,218,1,222,222,222,1,215,215,215,1,217, + 217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,221,221,221,1,214, + 214,214,1,215,215,215,1,220,220,220,1,168,168,168,1,255,255,255,1,217, + 217,217,1,220,220,220,1,215,215,215,1,218,218,218,1,216,216,216,2,218, + 218,218,1,219,219,219,2,217,217,217,1,216,216,216,1,220,220,220,1,221, + 221,221,1,217,217,217,1,218,218,218,1,216,216,216,1,221,221,221,2,217, + 217,217,1,253,253,253,1,255,255,255,1,216,216,216,1,218,218,218,1,216, + 216,216,1,218,218,218,1,217,217,217,1,218,218,218,1,167,167,167,1,171, + 171,171,1,215,215,215,1,169,169,169,1,170,170,170,1,217,217,217,1,255, + 255,255,3,216,216,216,1,219,219,219,4,215,215,215,1,255,255,255,3,252, + 252,252,1,222,222,222,1,217,217,217,1,255,255,255,2,220,220,220,1,217, + 217,217,1,219,219,219,2,217,217,217,1,255,255,255,2,254,254,254,1,255, + 255,255,1,217,217,217,1,218,218,218,1,217,217,217,1,221,221,221,1,216, + 216,216,1,221,221,221,1,218,218,218,14,216,216,216,1,224,224,224,1,165, + 165,165,1,167,167,167,1,220,220,220,1,216,216,216,2,219,219,219,1,218, + 218,218,1,217,217,217,1,216,216,216,1,255,255,255,1,252,252,252,1,255, + 255,255,2,217,217,217,1,221,221,221,1,218,218,218,1,220,220,220,1,216, + 216,216,1,213,213,213,1,222,222,222,1,215,215,215,1,218,218,218,1,219, + 219,219,4,255,255,255,1,253,253,253,2,255,255,255,2,254,254,254,1,217, + 217,217,1,219,219,219,1,167,167,167,1,220,220,220,1,221,221,221,1,218, + 218,218,1,255,255,255,3,170,170,170,1,162,162,162,1,167,167,167,1,217, + 217,217,1,169,169,169,1,216,216,216,1,214,214,214,1,222,222,222,1,220, + 220,220,1,217,217,217,1,220,220,220,1,218,218,218,1,216,216,216,1,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,1,221,221,221,1,220, + 220,220,1,212,212,212,1,221,221,221,1,167,167,167,1,215,215,215,1,222, + 222,222,1,255,255,255,1,254,254,254,1,219,219,219,1,254,254,254,1,216, + 216,216,2,219,219,219,1,218,218,218,1,222,222,222,1,220,220,220,1,215, + 215,215,1,255,255,255,1,214,214,214,1,221,221,221,1,218,218,218,1,169, + 169,169,1,164,164,164,1,217,217,217,1,219,219,219,1,218,218,218,1,216, + 216,216,1,214,214,214,1,223,223,223,1,216,216,216,1,218,218,218,1,219, + 219,219,1,218,218,218,1,221,221,221,1,216,216,216,1,219,219,219,1,168, + 168,168,1,170,170,170,1,166,166,166,1,172,172,172,1,166,166,166,2,218, + 218,218,1,214,214,214,1,220,220,220,1,216,216,216,1,219,219,219,1,217, + 217,217,1,255,255,255,1,215,215,215,1,218,218,218,1,255,255,255,1,251, + 251,251,1,255,255,255,1,251,251,251,1,218,218,218,1,255,255,255,1,253, + 253,253,1,255,255,255,1,215,215,215,1,217,217,217,1,221,221,221,1,216, + 216,216,1,218,218,218,1,217,217,217,1,216,216,216,1,255,255,255,2,254, + 254,254,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,219, + 219,219,1,216,216,216,1,218,218,218,14,215,215,215,1,255,255,255,1,168, + 168,168,2,218,218,218,2,221,221,221,1,217,217,217,1,220,220,220,1,215, + 215,215,1,219,219,219,1,255,255,255,3,253,253,253,1,255,255,255,1,253, + 253,253,1,215,215,215,1,220,220,220,1,218,218,218,1,222,222,222,1,218, + 218,218,1,216,216,216,1,220,220,220,1,217,217,217,1,255,255,255,1,253, + 253,253,1,220,220,220,1,215,215,215,1,221,221,221,1,253,253,253,1,255, + 255,255,3,218,218,218,1,216,216,216,1,224,224,224,1,216,216,216,1,218, + 218,218,1,217,217,217,2,255,255,255,1,252,252,252,1,219,219,219,1,172, + 172,172,1,217,217,217,2,169,169,169,1,219,219,219,1,220,220,220,1,218, + 218,218,1,216,216,216,1,217,217,217,1,218,218,218,1,219,219,219,1,220, + 220,220,1,218,218,218,1,220,220,220,1,219,219,219,1,212,212,212,1,220, + 220,220,1,216,216,216,1,219,219,219,1,216,216,216,1,221,221,221,1,215, + 215,215,1,218,218,218,1,253,253,253,1,216,216,216,1,217,217,217,1,218, + 218,218,1,219,219,219,2,221,221,221,1,215,215,215,1,213,213,213,1,218, + 218,218,1,220,220,220,1,168,168,168,2,218,218,218,1,215,215,215,1,168, + 168,168,1,171,171,171,1,218,218,218,1,217,217,217,1,218,218,218,1,219, + 219,219,1,222,222,222,1,216,216,216,2,220,220,220,1,216,216,216,1,218, + 218,218,1,216,216,216,1,220,220,220,1,217,217,217,1,215,215,215,1,221, + 221,221,1,216,216,216,1,253,253,253,1,221,221,221,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,2,216,216,216,1,221,221,221,1,166, + 166,166,1,221,221,221,1,217,217,217,1,168,168,168,1,219,219,219,1,220, + 220,220,1,254,254,254,1,255,255,255,1,218,218,218,1,219,219,219,1,217, + 217,217,1,172,172,172,1,169,169,169,1,213,213,213,1,221,221,221,2,215, + 215,215,1,220,220,220,1,215,215,215,1,219,219,219,1,217,217,217,1,219, + 219,219,1,218,218,218,2,220,220,220,2,217,217,217,1,218,218,218,14,255, + 255,255,2,217,217,217,1,218,218,218,1,219,219,219,1,216,216,216,1,217, + 217,217,1,218,218,218,1,217,217,217,1,218,218,218,1,219,219,219,1,218, + 218,218,1,217,217,217,1,255,255,255,1,253,253,253,1,255,255,255,3,254, + 254,254,1,218,218,218,2,217,217,217,1,255,255,255,1,218,218,218,1,255, + 255,255,2,213,213,213,1,221,221,221,1,220,220,220,1,215,215,215,1,220, + 220,220,1,218,218,218,1,255,255,255,1,217,217,217,1,219,219,219,1,218, + 218,218,1,217,217,217,1,219,219,219,1,216,216,216,1,219,219,219,2,254, + 254,254,1,255,255,255,1,253,253,253,1,218,218,218,1,255,255,255,1,219, + 219,219,1,217,217,217,2,220,220,220,1,217,217,217,2,219,219,219,1,218, + 218,218,1,217,217,217,2,219,219,219,1,216,216,216,1,219,219,219,1,217, + 217,217,2,219,219,219,1,255,255,255,1,219,219,219,1,216,216,216,1,221, + 221,221,1,216,216,216,1,219,219,219,2,218,218,218,1,217,217,217,1,218, + 218,218,1,219,219,219,1,165,165,165,1,220,220,220,1,168,168,168,1,170, + 170,170,1,165,165,165,1,167,167,167,1,219,219,219,1,255,255,255,2,219, + 219,219,1,217,217,217,1,218,218,218,4,216,216,216,1,220,220,220,1,218, + 218,218,2,220,220,220,1,217,217,217,1,255,255,255,1,217,217,217,1,221, + 221,221,1,253,253,253,1,254,254,254,1,255,255,255,2,217,217,217,1,219, + 219,219,1,218,218,218,1,219,219,219,1,215,215,215,1,217,217,217,1,221, + 221,221,1,217,217,217,1,216,216,216,1,220,220,220,1,168,168,168,2,217, + 217,217,1,253,253,253,1,220,220,220,1,219,219,219,1,215,215,215,1,168, + 168,168,2,167,167,167,2,219,219,219,1,218,218,218,1,214,214,214,1,219, + 219,219,1,220,220,220,1,217,217,217,1,169,169,169,1,218,218,218,1,217, + 217,217,1,218,218,218,2,216,216,216,1,218,218,218,8,219,219,219,1,216, + 216,216,1,221,221,221,1,219,219,219,2,218,218,218,1,215,215,215,1,220, + 220,220,1,255,255,255,2,217,217,217,2,219,219,219,1,218,218,218,1,220, + 220,220,1,218,218,218,2,219,219,219,1,217,217,217,1,220,220,220,1,219, + 219,219,1,217,217,217,1,218,218,218,1,253,253,253,1,255,255,255,1,254, + 254,254,2,218,218,218,1,255,255,255,2,254,254,254,1,218,218,218,2,219, + 219,219,1,216,216,216,1,218,218,218,1,219,219,219,1,216,216,216,1,220, + 220,220,1,217,217,217,1,254,254,254,1,220,220,220,1,169,169,169,1,217, + 217,217,1,168,168,168,1,219,219,219,1,216,216,216,1,220,220,220,1,218, + 218,218,2,252,252,252,1,220,220,220,1,216,216,216,1,255,255,255,1,218, + 218,218,2,216,216,216,1,221,221,221,1,218,218,218,1,217,217,217,1,167, + 167,167,1,218,218,218,2,219,219,219,2,220,220,220,1,215,215,215,1,219, + 219,219,1,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,3,222, + 222,222,1,214,214,214,1,169,169,169,1,219,219,219,1,218,218,218,1,219, + 219,219,1,220,220,220,1,166,166,166,1,169,169,169,1,168,168,168,1,218, + 218,218,1,219,219,219,1,164,164,164,1,220,220,220,1,255,255,255,2,216, + 216,216,1,218,218,218,1,220,220,220,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,1,219,219,219,1,217,217,217,2,221,221,221,1,216, + 216,216,1,217,217,217,1,218,218,218,1,167,167,167,1,253,253,253,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,3,217,217,217,1,255,255,255,1,220,220,220,1,218,218,218,1,255, + 255,255,1,217,217,217,1,169,169,169,1,165,165,165,1,217,217,217,1,167, + 167,167,1,217,217,217,1,219,219,219,2,255,255,255,1,220,220,220,1,216, + 216,216,1,220,220,220,1,215,215,215,1,220,220,220,2,216,216,216,1,219, + 219,219,1,217,217,217,1,220,220,220,1,216,216,216,1,220,220,220,1,216, + 216,216,1,218,218,218,1,220,220,220,1,217,217,217,2,218,218,218,1,217, + 217,217,1,219,219,219,1,221,221,221,1,217,217,217,1,215,215,215,1,223, + 223,223,1,214,214,214,1,216,216,216,1,218,218,218,1,217,217,217,1,221, + 221,221,1,216,216,216,2,225,225,225,1,215,215,215,1,219,219,219,2,217, + 217,217,1,216,216,216,1,218,218,218,1,216,216,216,1,218,218,218,2,216, + 216,216,1,217,217,217,2,222,222,222,1,219,219,219,1,217,217,217,1,255, + 255,255,3,217,217,217,1,254,254,254,1,221,221,221,1,218,218,218,1,216, + 216,216,1,220,220,220,1,219,219,219,1,216,216,216,1,217,217,217,1,220, + 220,220,1,215,215,215,1,255,255,255,1,253,253,253,1,220,220,220,1,216, + 216,216,1,219,219,219,1,172,172,172,1,217,217,217,1,215,215,215,1,217, + 217,217,2,220,220,220,1,219,219,219,1,215,215,215,1,219,219,219,1,217, + 217,217,3,218,218,218,1,214,214,214,1,221,221,221,1,219,219,219,1,173, + 173,173,1,216,216,216,2,219,219,219,1,215,215,215,2,224,224,224,1,217, + 217,217,1,219,219,219,2,220,220,220,1,169,169,169,1,217,217,217,1,218, + 218,218,1,216,216,216,1,219,219,219,1,217,217,217,1,220,220,220,1,219, + 219,219,1,253,253,253,1,216,216,216,1,217,217,217,1,218,218,218,2,216, + 216,216,1,169,169,169,1,219,219,219,1,218,218,218,2,170,170,170,1,168, + 168,168,1,216,216,216,1,217,217,217,1,219,219,219,1,217,217,217,1,215, + 215,215,1,219,219,219,1,220,220,220,1,218,218,218,1,219,219,219,1,218, + 218,218,1,216,216,216,1,221,221,221,1,168,168,168,1,169,169,169,1,221, + 221,221,1,218,218,218,1,217,217,217,2,221,221,221,1,218,218,218,1,219, + 219,219,2,218,218,218,1,219,219,219,2,216,216,216,1,255,255,255,1,252, + 252,252,1,222,222,222,1,213,213,213,1,226,226,226,1,215,215,215,1,221, + 221,221,1,255,255,255,2,253,253,253,2,218,218,218,2,220,220,220,1,221, + 221,221,1,214,214,214,1,217,217,217,1,255,255,255,1,216,216,216,1,217, + 217,217,2,220,220,220,1,218,218,218,1,220,220,220,2,213,213,213,1,222, + 222,222,1,221,221,221,1,217,217,217,1,219,219,219,1,218,218,218,1,214, + 214,214,1,220,220,220,1,168,168,168,1,167,167,167,1,169,169,169,1,219, + 219,219,1,218,218,218,1,219,219,219,2,218,218,218,1,216,216,216,1,217, + 217,217,1,219,219,219,1,217,217,217,2,218,218,218,1,216,216,216,1,221, + 221,221,1,218,218,218,1,221,221,221,1,219,219,219,1,218,218,218,1,221, + 221,221,1,218,218,218,1,215,215,215,1,217,217,217,1,218,218,218,1,255, + 255,255,1,218,218,218,1,214,214,214,1,218,218,218,1,220,220,220,1,215, + 215,215,1,216,216,216,1,217,217,217,1,216,216,216,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,255,255,255,1,253, + 253,253,1,219,219,219,1,218,218,218,2,214,214,214,1,218,218,218,1,225, + 225,225,1,217,217,217,1,215,215,215,1,217,217,217,1,219,219,219,1,220, + 220,220,1,218,218,218,1,221,221,221,1,217,217,217,1,218,218,218,1,220, + 220,220,1,219,219,219,1,254,254,254,1,214,214,214,1,216,216,216,1,220, + 220,220,1,168,168,168,2,220,220,220,1,218,218,218,2,215,215,215,1,220, + 220,220,1,215,215,215,1,216,216,216,1,166,166,166,1,220,220,220,2,255, + 255,255,1,219,219,219,1,217,217,217,1,218,218,218,1,216,216,216,1,255, + 255,255,2,222,222,222,1,215,215,215,1,219,219,219,1,218,218,218,1,217, + 217,217,1,218,218,218,1,217,217,217,1,163,163,163,1,168,168,168,1,218, + 218,218,1,220,220,220,1,219,219,219,1,215,215,215,1,219,219,219,3,217, + 217,217,1,218,218,218,4,220,220,220,1,165,165,165,1,168,168,168,1,214, + 214,214,1,218,218,218,1,221,221,221,1,217,217,217,2,167,167,167,1,217, + 217,217,1,220,220,220,1,213,213,213,1,219,219,219,2,217,217,217,1,220, + 220,220,1,255,255,255,1,251,251,251,1,218,218,218,1,254,254,254,1,218, + 218,218,1,217,217,217,1,254,254,254,1,218,218,218,1,221,221,221,1,219, + 219,219,1,217,217,217,1,218,218,218,1,216,216,216,1,213,213,213,1,220, + 220,220,1,217,217,217,1,218,218,218,1,220,220,220,1,219,219,219,2,217, + 217,217,1,216,216,216,2,219,219,219,1,220,220,220,1,216,216,216,2,168, + 168,168,1,167,167,167,2,221,221,221,1,218,218,218,1,219,219,219,1,217, + 217,217,1,219,219,219,1,217,217,217,1,219,219,219,1,216,216,216,2,218, + 218,218,1,221,221,221,1,216,216,216,1,220,220,220,1,217,217,217,1,220, + 220,220,2,218,218,218,1,217,217,217,1,219,219,219,1,218,218,218,1,214, + 214,214,1,218,218,218,1,216,216,216,1,222,222,222,1,215,215,215,1,221, + 221,221,1,220,220,220,1,214,214,214,1,219,219,219,1,222,222,222,1,215, + 215,215,1,220,220,220,1,218,218,218,1,220,220,220,2,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,217,217,217,1,220,220,220,1,217, + 217,217,1,219,219,219,1,215,215,215,1,255,255,255,1,220,220,220,1,217, + 217,217,1,221,221,221,1,215,215,215,1,219,219,219,1,218,218,218,1,221, + 221,221,1,217,217,217,2,214,214,214,1,216,216,216,1,220,220,220,1,217, + 217,217,1,166,166,166,2,255,255,255,1,222,222,222,1,215,215,215,1,168, + 168,168,1,170,170,170,1,167,167,167,1,218,218,218,1,219,219,219,1,218, + 218,218,1,221,221,221,1,215,215,215,1,255,255,255,1,218,218,218,1,221, + 221,221,1,218,218,218,1,215,215,215,1,217,217,217,2,220,220,220,1,221, + 221,221,1,169,169,169,1,216,216,216,1,254,254,254,1,252,252,252,1,255, + 255,255,2,216,216,216,1,221,221,221,1,218,218,218,1,253,253,253,1,255, + 255,255,1,168,168,168,1,217,217,217,2,219,219,219,1,220,220,220,1,217, + 217,217,1,219,219,219,1,218,218,218,1,216,216,216,1,218,218,218,1,255, + 255,255,1,218,218,218,1,219,219,219,1,215,215,215,1,169,169,169,1,170, + 170,170,1,168,168,168,1,220,220,220,1,219,219,219,1,218,218,218,2,165, + 165,165,1,220,220,220,1,217,217,217,1,223,223,223,1,218,218,218,1,217, + 217,217,1,220,220,220,1,211,211,211,1,223,223,223,1,219,219,219,1,218, + 218,218,1,216,216,216,1,222,222,222,1,217,217,217,1,222,222,222,1,216, + 216,216,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,219, + 219,219,1,221,221,221,1,220,220,220,2,214,214,214,1,217,217,217,1,216, + 216,216,1,218,218,218,1,219,219,219,1,221,221,221,1,218,218,218,2,216, + 216,216,2,219,219,219,1,171,171,171,1,169,169,169,2,214,214,214,1,218, + 218,218,1,254,254,254,1,220,220,220,2,214,214,214,1,217,217,217,2,222, + 222,222,1,219,219,219,1,217,217,217,1,215,215,215,1,220,220,220,1,218, + 218,218,1,219,219,219,1,216,216,216,1,220,220,220,1,217,217,217,1,216, + 216,216,1,222,222,222,1,169,169,169,1,222,222,222,1,216,216,216,2,222, + 222,222,1,214,214,214,1,219,219,219,1,221,221,221,1,216,216,216,2,219, + 219,219,1,216,216,216,1,217,217,217,2,219,219,219,2,215,215,215,1,223, + 223,223,1,218,218,218,2,217,217,217,1,220,220,220,1,255,255,255,1,218, + 218,218,2,216,216,216,1,221,221,221,1,214,214,214,1,216,216,216,1,220, + 220,220,1,219,219,219,1,167,167,167,1,214,214,214,1,223,223,223,1,220, + 220,220,2,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,2,218, + 218,218,1,255,255,255,1,253,253,253,1,219,219,219,1,218,218,218,1,219, + 219,219,1,215,215,215,1,219,219,219,1,216,216,216,1,220,220,220,1,255, + 255,255,1,217,217,217,1,216,216,216,1,218,218,218,1,223,223,223,1,167, + 167,167,1,170,170,170,1,167,167,167,1,165,165,165,1,172,172,172,1,217, + 217,217,1,223,223,223,1,255,255,255,1,219,219,219,1,218,218,218,1,216, + 216,216,1,217,217,217,1,218,218,218,1,220,220,220,1,214,214,214,1,220, + 220,220,1,216,216,216,1,218,218,218,1,220,220,220,1,217,217,217,1,218, + 218,218,3,219,219,219,1,253,253,253,1,254,254,254,1,255,255,255,1,253, + 253,253,1,221,221,221,1,169,169,169,1,166,166,166,1,168,168,168,1,167, + 167,167,1,219,219,219,1,251,251,251,1,221,221,221,1,220,220,220,1,218, + 218,218,1,215,215,215,1,216,216,216,1,218,218,218,1,215,215,215,1,219, + 219,219,1,221,221,221,1,218,218,218,1,216,216,216,1,219,219,219,1,221, + 221,221,1,212,212,212,1,219,219,219,2,217,217,217,1,221,221,221,1,218, + 218,218,1,215,215,215,1,219,219,219,1,217,217,217,1,213,213,213,1,221, + 221,221,1,214,214,214,1,221,221,221,1,217,217,217,1,220,220,220,1,216, + 216,216,1,219,219,219,1,215,215,215,1,217,217,217,1,221,221,221,1,216, + 216,216,1,255,255,255,1,216,216,216,1,218,218,218,1,166,166,166,1,218, + 218,218,1,219,219,219,1,218,218,218,3,217,217,217,1,220,220,220,1,219, + 219,219,1,220,220,220,1,214,214,214,1,218,218,218,1,220,220,220,1,219, + 219,219,2,217,217,217,1,218,218,218,1,214,214,214,1,221,221,221,1,218, + 218,218,1,221,221,221,1,214,214,214,1,170,170,170,1,165,165,165,1,170, + 170,170,1,219,219,219,2,217,217,217,1,212,212,212,1,222,222,222,1,216, + 216,216,1,221,221,221,1,218,218,218,1,222,222,222,1,214,214,214,1,220, + 220,220,1,165,165,165,2,221,221,221,1,216,216,216,1,220,220,220,1,217, + 217,217,3,218,218,218,3,219,219,219,1,218,218,218,1,221,221,221,1,218, + 218,218,1,219,219,219,1,216,216,216,1,220,220,220,1,221,221,221,1,214, + 214,214,1,217,217,217,1,218,218,218,1,254,254,254,2,218,218,218,1,217, + 217,217,2,255,255,255,1,252,252,252,1,255,255,255,1,216,216,216,1,218, + 218,218,3,217,217,217,1,221,221,221,1,216,216,216,1,217,217,217,1,169, + 169,169,1,218,218,218,2,166,166,166,2,169,169,169,1,216,216,216,1,218, + 218,218,1,168,168,168,2,164,164,164,1,171,171,171,1,167,167,167,1,166, + 166,166,1,222,222,222,1,215,215,215,1,217,217,217,1,255,255,255,1,220, + 220,220,1,216,216,216,1,222,222,222,1,219,219,219,1,217,217,217,1,216, + 216,216,1,171,171,171,1,216,216,216,1,217,217,217,1,220,220,220,1,255, + 255,255,1,253,253,253,1,255,255,255,1,218,218,218,1,216,216,216,2,169, + 169,169,1,167,167,167,1,168,168,168,2,218,218,218,1,219,219,219,1,217, + 217,217,2,221,221,221,1,218,218,218,1,216,216,216,1,222,222,222,1,219, + 219,219,1,218,218,218,1,216,216,216,1,219,219,219,1,217,217,217,2,221, + 221,221,1,217,217,217,1,219,219,219,1,216,216,216,2,220,220,220,1,222, + 222,222,1,216,216,216,1,219,219,219,2,217,217,217,1,216,216,216,1,219, + 219,219,1,218,218,218,2,216,216,216,1,219,219,219,1,220,220,220,1,216, + 216,216,2,220,220,220,1,253,253,253,1,220,220,220,1,218,218,218,3,220, + 220,220,1,216,216,216,1,218,218,218,1,215,215,215,1,220,220,220,1,216, + 216,216,1,219,219,219,1,217,217,217,1,222,222,222,1,216,216,216,1,217, + 217,217,3,218,218,218,1,220,220,220,1,218,218,218,1,219,219,219,1,216, + 216,216,1,254,254,254,1,219,219,219,2,218,218,218,1,164,164,164,1,217, + 217,217,1,218,218,218,1,220,220,220,2,217,217,217,1,218,218,218,1,217, + 217,217,1,218,218,218,1,216,216,216,1,220,220,220,1,218,218,218,1,171, + 171,171,1,220,220,220,1,216,216,216,1,217,217,217,1,218,218,218,2,221, + 221,221,1,217,217,217,2,219,219,219,1,215,215,215,1,220,220,220,1,218, + 218,218,1,217,217,217,1,221,221,221,1,252,252,252,1,220,220,220,1,219, + 219,219,1,216,216,216,1,217,217,217,1,219,219,219,3,218,218,218,1,219, + 219,219,2,217,217,217,1,221,221,221,1,219,219,219,1,213,213,213,1,224, + 224,224,1,218,218,218,1,217,217,217,1,220,220,220,1,219,219,219,1,215, + 215,215,1,222,222,222,1,219,219,219,1,214,214,214,1,219,219,219,1,255, + 255,255,1,254,254,254,1,220,220,220,2,217,217,217,1,219,219,219,1,220, + 220,220,1,167,167,167,1,216,216,216,1,171,171,171,1,216,216,216,1,168, + 168,168,1,254,254,254,1,255,255,255,1,213,213,213,1,218,218,218,2,216, + 216,216,1,217,217,217,1,218,218,218,1,214,214,214,1,220,220,220,1,218, + 218,218,3,219,219,219,1,213,213,213,1,171,171,171,1,216,216,216,1,219, + 219,219,1,221,221,221,1,219,219,219,1,216,216,216,1,173,173,173,1,167, + 167,167,1,165,165,165,1,171,171,171,1,214,214,214,1,219,219,219,2,218, + 218,218,1,216,216,216,1,221,221,221,1,217,217,217,1,166,166,166,1,218, + 218,218,1,220,220,220,1,218,218,218,1,217,217,217,1,218,218,218,1,217, + 217,217,1,219,219,219,3,218,218,218,1,217,217,217,1,215,215,215,1,219, + 219,219,1,215,215,215,1,221,221,221,1,214,214,214,1,219,219,219,1,220, + 220,220,1,215,215,215,1,218,218,218,2,216,216,216,1,221,221,221,1,217, + 217,217,1,220,220,220,1,254,254,254,1,255,255,255,1,252,252,252,1,219, + 219,219,2,218,218,218,1,217,217,217,1,219,219,219,2,217,217,217,1,219, + 219,219,1,216,216,216,1,219,219,219,2,215,215,215,1,220,220,220,1,219, + 219,219,3,217,217,217,1,218,218,218,2,217,217,217,1,219,219,219,1,255, + 255,255,1,253,253,253,1,255,255,255,1,219,219,219,1,221,221,221,1,168, + 168,168,1,167,167,167,1,217,217,217,1,218,218,218,1,219,219,219,2,218, + 218,218,1,216,216,216,1,219,219,219,1,255,255,255,1,254,254,254,1,218, + 218,218,1,216,216,216,1,218,218,218,1,219,219,219,1,221,221,221,1,215, + 215,215,1,219,219,219,1,218,218,218,1,217,217,217,1,221,221,221,1,216, + 216,216,1,220,220,220,1,216,216,216,1,218,218,218,2,220,220,220,1,218, + 218,218,1,216,216,216,1,219,219,219,2,218,218,218,1,215,215,215,1,221, + 221,221,1,217,217,217,1,219,219,219,1,215,215,215,1,220,220,220,1,217, + 217,217,1,220,220,220,1,219,219,219,1,214,214,214,1,217,217,217,1,218, + 218,218,3,217,217,217,1,255,255,255,1,218,218,218,1,219,219,219,1,254, + 254,254,2,255,255,255,1,216,216,216,1,254,254,254,1,255,255,255,1,217, + 217,217,1,218,218,218,1,255,255,255,3,218,218,218,1,168,168,168,1,220, + 220,220,1,215,215,215,1,220,220,220,1,218,218,218,3,168,168,168,1,217, + 217,217,1,255,255,255,1,218,218,218,1,215,215,215,1,170,170,170,1,168, + 168,168,2,171,171,171,1,214,214,214,1,219,219,219,1,220,220,220,1,216, + 216,216,1,219,219,219,1,220,220,220,1,214,214,214,1,220,220,220,1,169, + 169,169,1,167,167,167,1,219,219,219,1,217,217,217,2,218,218,218,2,219, + 219,219,1,217,217,217,1,168,168,168,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,1,220,220,220,1,215,215,215,1,218, + 218,218,4,220,220,220,1,215,215,215,1,220,220,220,1,217,217,217,1,218, + 218,218,2,216,216,216,1,220,220,220,1,219,219,219,1,217,217,217,1,219, + 219,219,1,218,218,218,2,217,217,217,1,255,255,255,2,220,220,220,1,218, + 218,218,1,165,165,165,1,171,171,171,1,216,216,216,1,218,218,218,1,217, + 217,217,1,222,222,222,1,218,218,218,1,215,215,215,1,221,221,221,1,218, + 218,218,1,214,214,214,1,220,220,220,1,217,217,217,1,218,218,218,4,223, + 223,223,1,216,216,216,1,218,218,218,1,216,216,216,1,219,219,219,1,254, + 254,254,1,217,217,217,1,218,218,218,1,220,220,220,1,218,218,218,3,217, + 217,217,1,168,168,168,1,219,219,219,1,218,218,218,1,220,220,220,1,255, + 255,255,1,217,217,217,1,219,219,219,2,216,216,216,1,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,219,219,219,1,218,218,218,1,221, + 221,221,1,216,216,216,1,219,219,219,1,217,217,217,2,220,220,220,1,217, + 217,217,1,220,220,220,1,215,215,215,1,221,221,221,1,218,218,218,2,217, + 217,217,1,220,220,220,1,218,218,218,2,219,219,219,1,218,218,218,1,217, + 217,217,1,219,219,219,1,217,217,217,1,220,220,220,1,217,217,217,1,218, + 218,218,1,216,216,216,1,220,220,220,1,214,214,214,1,220,220,220,1,221, + 221,221,1,215,215,215,1,219,219,219,1,255,255,255,1,252,252,252,1,255, + 255,255,3,254,254,254,1,255,255,255,2,218,218,218,1,255,255,255,1,218, + 218,218,1,171,171,171,1,167,167,167,2,169,169,169,1,216,216,216,1,171, + 171,171,1,165,165,165,1,169,169,169,1,218,218,218,2,219,219,219,1,216, + 216,216,1,168,168,168,1,167,167,167,1,218,218,218,1,220,220,220,1,217, + 217,217,1,222,222,222,1,215,215,215,1,220,220,220,1,218,218,218,1,219, + 219,219,1,216,216,216,1,219,219,219,1,169,169,169,1,216,216,216,1,217, + 217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,220,220,220,1,216, + 216,216,1,220,220,220,1,218,218,218,2,217,217,217,1,218,218,218,1,216, + 216,216,1,217,217,217,1,219,219,219,1,220,220,220,1,216,216,216,1,168, + 168,168,1,167,167,167,3,170,170,170,1,168,168,168,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,218, + 218,218,2,217,217,217,1,221,221,221,1,217,217,217,1,215,215,215,1,219, + 219,219,1,218,218,218,1,170,170,170,1,167,167,167,1,171,171,171,1,215, + 215,215,1,220,220,220,1,217,217,217,1,216,216,216,1,220,220,220,2,216, + 216,216,1,218,218,218,1,223,223,223,1,216,216,216,1,220,220,220,1,221, + 221,221,1,215,215,215,1,219,219,219,1,216,216,216,1,214,214,214,1,221, + 221,221,1,218,218,218,1,220,220,220,2,217,217,217,1,253,253,253,1,255, + 255,255,1,218,218,218,1,214,214,214,1,218,218,218,1,217,217,217,1,219, + 219,219,1,218,218,218,1,168,168,168,1,167,167,167,1,215,215,215,1,217, + 217,217,1,219,219,219,1,216,216,216,2,220,220,220,1,222,222,222,1,216, + 216,216,1,219,219,219,2,218,218,218,1,216,216,216,1,215,215,215,1,218, + 218,218,1,220,220,220,1,218,218,218,1,220,220,220,1,214,214,214,1,220, + 220,220,1,215,215,215,1,220,220,220,1,217,217,217,2,218,218,218,1,219, + 219,219,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,220,220,220,1,214,214,214,1,220, + 220,220,1,221,221,221,1,218,218,218,1,216,216,216,1,222,222,222,1,217, + 217,217,1,163,163,163,1,170,170,170,1,167,167,167,1,252,252,252,1,221, + 221,221,1,219,219,219,1,254,254,254,1,255,255,255,1,216,216,216,1,220, + 220,220,1,218,218,218,1,219,219,219,1,253,253,253,1,166,166,166,1,217, + 217,217,1,170,170,170,1,169,169,169,1,168,168,168,1,171,171,171,1,215, + 215,215,1,168,168,168,1,167,167,167,1,222,222,222,1,218,218,218,1,254, + 254,254,1,255,255,255,1,254,254,254,1,220,220,220,1,215,215,215,1,217, + 217,217,1,218,218,218,1,212,212,212,1,220,220,220,1,217,217,217,2,216, + 216,216,1,223,223,223,1,215,215,215,1,219,219,219,1,221,221,221,1,219, + 219,219,2,217,217,217,1,218,218,218,2,253,253,253,1,219,219,219,1,166, + 166,166,1,168,168,168,1,170,170,170,1,219,219,219,1,220,220,220,1,218, + 218,218,2,166,166,166,1,168,168,168,1,166,166,166,1,170,170,170,1,171, + 171,171,1,170,170,170,1,165,165,165,1,218,218,218,1,220,220,220,1,219, + 219,219,1,216,216,216,1,221,221,221,1,217,217,217,1,218,218,218,1,217, + 217,217,2,219,219,219,1,215,215,215,1,217,217,217,1,222,222,222,1,218, + 218,218,1,255,255,255,1,253,253,253,1,166,166,166,1,216,216,216,1,221, + 221,221,1,218,218,218,2,219,219,219,1,216,216,216,1,222,222,222,1,217, + 217,217,1,220,220,220,1,215,215,215,1,218,218,218,1,217,217,217,1,214, + 214,214,1,220,220,220,1,216,216,216,1,221,221,221,1,218,218,218,1,216, + 216,216,1,218,218,218,1,216,216,216,1,215,215,215,1,219,219,219,1,220, + 220,220,1,218,218,218,1,216,216,216,1,221,221,221,1,219,219,219,1,255, + 255,255,1,217,217,217,2,170,170,170,1,215,215,215,1,219,219,219,3,222, + 222,222,1,219,219,219,1,216,216,216,3,219,219,219,1,217,217,217,1,218, + 218,218,1,220,220,220,1,222,222,222,1,216,216,216,1,220,220,220,1,215, + 215,215,1,217,217,217,1,223,223,223,1,215,215,215,1,222,222,222,1,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,217, + 217,217,1,219,219,219,1,216,216,216,1,217,217,217,1,219,219,219,1,218, + 218,218,1,217,217,217,1,220,220,220,1,218,218,218,2,217,217,217,1,218, + 218,218,1,219,219,219,1,215,215,215,1,218,218,218,1,170,170,170,1,169, + 169,169,1,167,167,167,1,171,171,171,1,217,217,217,1,218,218,218,1,217, + 217,217,1,215,215,215,1,169,169,169,2,218,218,218,1,219,219,219,2,223, + 223,223,1,253,253,253,1,214,214,214,1,170,170,170,1,214,214,214,1,218, + 218,218,1,223,223,223,1,215,215,215,1,169,169,169,1,216,216,216,2,253, + 253,253,1,255,255,255,1,218,218,218,1,252,252,252,1,255,255,255,1,220, + 220,220,1,218,218,218,1,222,222,222,1,220,220,220,1,218,218,218,1,255, + 255,255,2,254,254,254,1,169,169,169,1,167,167,167,1,216,216,216,1,213, + 213,213,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,222, + 222,222,1,219,219,219,1,166,166,166,1,168,168,168,1,172,172,172,1,164, + 164,164,1,169,169,169,1,165,165,165,1,167,167,167,1,220,220,220,1,215, + 215,215,1,222,222,222,1,214,214,214,1,216,216,216,1,217,217,217,1,168, + 168,168,1,217,217,217,1,221,221,221,1,214,214,214,1,220,220,220,1,217, + 217,217,1,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,170, + 170,170,1,214,214,214,1,221,221,221,1,219,219,219,1,253,253,253,1,255, + 255,255,2,219,219,219,1,221,221,221,1,215,215,215,1,218,218,218,1,220, + 220,220,1,217,217,217,1,219,219,219,1,214,214,214,1,219,219,219,2,220, + 220,220,1,218,218,218,1,216,216,216,1,223,223,223,1,214,214,214,1,220, + 220,220,1,217,217,217,1,171,171,171,1,167,167,167,1,217,217,217,1,218, + 218,218,1,221,221,221,1,217,217,217,3,218,218,218,1,220,220,220,1,215, + 215,215,1,168,168,168,1,254,254,254,1,255,255,255,1,214,214,214,1,225, + 225,225,1,216,216,216,1,219,219,219,2,216,216,216,2,219,219,219,3,215, + 215,215,1,168,168,168,1,169,169,169,1,218,218,218,1,219,219,219,1,215, + 215,215,1,219,219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,216, + 216,216,1,217,217,217,3,218,218,218,1,216,216,216,1,222,222,222,1,218, + 218,218,1,217,217,217,1,220,220,220,1,221,221,221,1,218,218,218,1,214, + 214,214,1,218,218,218,1,215,215,215,1,221,221,221,1,217,217,217,1,216, + 216,216,1,218,218,218,2,255,255,255,2,216,216,216,1,167,167,167,1,169, + 169,169,1,165,165,165,1,218,218,218,1,220,220,220,1,168,168,168,1,171, + 171,171,1,168,168,168,1,217,217,217,1,218,218,218,1,255,255,255,1,166, + 166,166,1,219,219,219,1,254,254,254,1,255,255,255,2,218,218,218,1,255, + 255,255,1,252,252,252,1,170,170,170,1,217,217,217,1,219,219,219,1,222, + 222,222,1,217,217,217,1,218,218,218,1,255,255,255,2,254,254,254,1,217, + 217,217,1,216,216,216,1,217,217,217,2,215,215,215,1,255,255,255,2,218, + 218,218,1,168,168,168,1,172,172,172,1,169,169,169,1,219,219,219,1,167, + 167,167,1,165,165,165,1,167,167,167,1,166,166,166,1,254,254,254,1,255, + 255,255,1,253,253,253,1,167,167,167,1,166,166,166,1,171,171,171,1,165, + 165,165,1,220,220,220,1,218,218,218,2,221,221,221,1,214,214,214,1,221, + 221,221,1,220,220,220,1,168,168,168,1,170,170,170,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,1,216,216,216,1,218,218,218,2,216, + 216,216,1,219,219,219,1,215,215,215,1,221,221,221,1,214,214,214,1,217, + 217,217,1,220,220,220,1,255,255,255,1,217,217,217,1,216,216,216,2,220, + 220,220,1,217,217,217,2,216,216,216,1,170,170,170,1,219,219,219,1,218, + 218,218,1,214,214,214,1,220,220,220,1,219,219,219,2,217,217,217,2,220, + 220,220,1,166,166,166,2,170,170,170,1,218,218,218,1,217,217,217,1,218, + 218,218,1,220,220,220,1,216,216,216,1,223,223,223,1,216,216,216,2,221, + 221,221,1,166,166,166,1,255,255,255,1,221,221,221,1,219,219,219,1,213, + 213,213,1,216,216,216,1,221,221,221,1,216,216,216,1,219,219,219,1,218, + 218,218,1,222,222,222,1,214,214,214,1,216,216,216,1,222,222,222,1,167, + 167,167,3,219,219,219,1,221,221,221,1,217,217,217,1,220,220,220,1,216, + 216,216,1,219,219,219,1,222,222,222,1,219,219,219,1,167,167,167,1,222, + 222,222,1,216,216,216,1,219,219,219,1,215,215,215,1,218,218,218,1,221, + 221,221,1,218,218,218,1,215,215,215,1,217,217,217,1,219,219,219,1,221, + 221,221,1,219,219,219,1,218,218,218,2,219,219,219,2,216,216,216,1,255, + 255,255,1,216,216,216,1,220,220,220,1,217,217,217,1,167,167,167,1,170, + 170,170,1,219,219,219,1,168,168,168,1,216,216,216,1,215,215,215,1,219, + 219,219,1,216,216,216,1,255,255,255,2,215,215,215,1,217,217,217,1,220, + 220,220,1,215,215,215,1,217,217,217,1,222,222,222,1,165,165,165,1,216, + 216,216,1,167,167,167,1,221,221,221,1,218,218,218,1,212,212,212,1,255, + 255,255,1,167,167,167,2,251,251,251,1,255,255,255,1,219,219,219,1,218, + 218,218,2,167,167,167,1,170,170,170,1,219,219,219,1,254,254,254,2,215, + 215,215,1,216,216,216,1,221,221,221,1,214,214,214,1,218,218,218,1,171, + 171,171,1,170,170,170,1,168,168,168,1,255,255,255,1,254,254,254,1,255, + 255,255,2,215,215,215,1,217,217,217,2,218,218,218,1,219,219,219,1,217, + 217,217,2,220,220,220,1,216,216,216,1,215,215,215,1,170,170,170,1,168, + 168,168,1,213,213,213,1,219,219,219,1,220,220,220,1,216,216,216,1,220, + 220,220,1,218,218,218,1,220,220,220,1,255,255,255,1,218,218,218,2,217, + 217,217,1,219,219,219,1,221,221,221,1,216,216,216,1,218,218,218,1,220, + 220,220,1,216,216,216,1,223,223,223,1,220,220,220,1,217,217,217,1,169, + 169,169,2,216,216,216,1,218,218,218,1,220,220,220,1,218,218,218,2,216, + 216,216,1,218,218,218,1,217,217,217,1,219,219,219,1,217,217,217,1,254, + 254,254,1,170,170,170,1,168,168,168,1,167,167,167,1,218,218,218,1,216, + 216,216,1,220,220,220,1,217,217,217,1,213,213,213,1,223,223,223,1,254, + 254,254,1,216,216,216,1,219,219,219,1,218,218,218,1,214,214,214,1,219, + 219,219,1,220,220,220,1,221,221,221,1,217,217,217,1,220,220,220,1,219, + 219,219,1,216,216,216,1,215,215,215,1,219,219,219,1,255,255,255,1,253, + 253,253,1,219,219,219,1,168,168,168,1,219,219,219,1,216,216,216,1,218, + 218,218,1,217,217,217,2,223,223,223,1,215,215,215,1,217,217,217,1,219, + 219,219,1,215,215,215,1,220,220,220,1,219,219,219,1,218,218,218,1,220, + 220,220,1,217,217,217,1,216,216,216,1,219,219,219,1,223,223,223,1,215, + 215,215,1,169,169,169,1,166,166,166,1,216,216,216,1,219,219,219,1,217, + 217,217,2,219,219,219,1,167,167,167,1,216,216,216,1,219,219,219,1,218, + 218,218,2,169,169,169,1,168,168,168,1,255,255,255,1,217,217,217,2,220, + 220,220,1,216,216,216,1,222,222,222,1,255,255,255,2,218,218,218,1,168, + 168,168,2,218,218,218,1,168,168,168,1,169,169,169,1,219,219,219,1,170, + 170,170,1,166,166,166,1,218,218,218,1,217,217,217,1,255,255,255,1,219, + 219,219,1,217,217,217,1,171,171,171,1,220,220,220,1,255,255,255,1,254, + 254,254,1,255,255,255,2,216,216,216,1,219,219,219,1,166,166,166,1,216, + 216,216,1,255,255,255,2,217,217,217,1,253,253,253,1,255,255,255,1,251, + 251,251,1,219,219,219,1,167,167,167,1,219,219,219,1,217,217,217,1,255, + 255,255,2,251,251,251,1,255,255,255,1,218,218,218,3,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,217,217,217,1,221,221,221,1,165, + 165,165,1,171,171,171,1,221,221,221,1,214,214,214,1,217,217,217,1,221, + 221,221,1,216,216,216,1,218,218,218,1,217,217,217,1,218,218,218,2,219, + 219,219,1,218,218,218,1,215,215,215,1,220,220,220,1,217,217,217,1,216, + 216,216,1,219,219,219,1,218,218,218,1,212,212,212,1,217,217,217,1,216, + 216,216,1,219,219,219,1,165,165,165,1,173,173,173,1,168,168,168,1,165, + 165,165,1,219,219,219,1,218,218,218,1,220,220,220,1,219,219,219,1,168, + 168,168,1,219,219,219,1,218,218,218,2,169,169,169,1,165,165,165,1,170, + 170,170,1,221,221,221,1,217,217,217,1,216,216,216,1,217,217,217,1,222, + 222,222,1,164,164,164,1,255,255,255,1,220,220,220,1,217,217,217,1,219, + 219,219,1,218,218,218,2,219,219,219,1,216,216,216,1,215,215,215,1,220, + 220,220,1,217,217,217,1,221,221,221,1,218,218,218,2,252,252,252,1,255, + 255,255,2,218,218,218,1,168,168,168,1,217,217,217,1,220,220,220,1,218, + 218,218,1,220,220,220,1,215,215,215,1,219,219,219,2,217,217,217,1,224, + 224,224,1,214,214,214,1,216,216,216,1,217,217,217,1,218,218,218,2,220, + 220,220,1,216,216,216,1,215,215,215,1,168,168,168,1,169,169,169,1,170, + 170,170,1,165,165,165,1,218,218,218,1,220,220,220,1,215,215,215,1,219, + 219,219,1,255,255,255,1,218,218,218,1,217,217,217,1,216,216,216,1,221, + 221,221,1,167,167,167,1,219,219,219,1,215,215,215,1,222,222,222,1,172, + 172,172,1,212,212,212,1,217,217,217,1,218,218,218,1,216,216,216,1,254, + 254,254,1,255,255,255,1,221,221,221,1,254,254,254,1,219,219,219,1,255, + 255,255,1,254,254,254,1,255,255,255,1,219,219,219,1,169,169,169,1,218, + 218,218,1,168,168,168,1,255,255,255,1,254,254,254,1,218,218,218,1,166, + 166,166,1,218,218,218,1,254,254,254,1,255,255,255,1,254,254,254,1,251, + 251,251,1,220,220,220,1,219,219,219,1,218,218,218,1,167,167,167,1,220, + 220,220,1,215,215,215,1,217,217,217,1,255,255,255,2,254,254,254,1,255, + 255,255,1,219,219,219,1,218,218,218,2,216,216,216,1,254,254,254,1,255, + 255,255,1,217,217,217,1,218,218,218,2,222,222,222,1,217,217,217,1,216, + 216,216,1,220,220,220,2,221,221,221,1,213,213,213,1,168,168,168,1,167, + 167,167,1,219,219,219,1,221,221,221,1,220,220,220,1,215,215,215,1,220, + 220,220,1,216,216,216,1,219,219,219,1,218,218,218,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,2,219,219,219,1,218,218,218,1,219, + 219,219,1,221,221,221,1,220,220,220,1,218,218,218,2,169,169,169,1,165, + 165,165,1,168,168,168,1,167,167,167,1,220,220,220,1,219,219,219,1,217, + 217,217,2,167,167,167,1,217,217,217,1,170,170,170,1,215,215,215,1,221, + 221,221,1,219,219,219,1,167,167,167,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,221,221,221,1,216,216,216,1,168,168,168,1,167, + 167,167,1,217,217,217,1,218,218,218,3,220,220,220,1,217,217,217,1,219, + 219,219,1,218,218,218,2,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,220,220,220,1,255,255,255,1,214,214,214,1,219,219,219,1,168, + 168,168,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,220, + 220,220,1,221,221,221,1,165,165,165,1,218,218,218,3,219,219,219,1,220, + 220,220,1,217,217,217,3,219,219,219,1,255,255,255,1,217,217,217,1,167, + 167,167,1,166,166,166,1,170,170,170,1,218,218,218,1,167,167,167,1,220, + 220,220,1,253,253,253,1,254,254,254,1,219,219,219,1,218,218,218,1,219, + 219,219,1,217,217,217,1,168,168,168,1,219,219,219,1,216,216,216,1,169, + 169,169,1,216,216,216,1,220,220,220,2,217,217,217,1,219,219,219,1,255, + 255,255,1,254,254,254,2,255,255,255,2,253,253,253,1,255,255,255,2,166, + 166,166,1,167,167,167,1,169,169,169,1,168,168,168,2,218,218,218,1,255, + 255,255,1,219,219,219,1,169,169,169,1,216,216,216,1,215,215,215,1,220, + 220,220,1,221,221,221,1,254,254,254,2,219,219,219,2,217,217,217,1,219, + 219,219,1,169,169,169,1,216,216,216,1,255,255,255,2,217,217,217,1,218, + 218,218,2,219,219,219,3,255,255,255,1,215,215,215,1,218,218,218,1,219, + 219,219,1,213,213,213,1,255,255,255,1,217,217,217,1,218,218,218,1,254, + 254,254,1,253,253,253,1,221,221,221,1,169,169,169,1,167,167,167,1,170, + 170,170,1,215,215,215,1,217,217,217,1,221,221,221,1,216,216,216,1,220, + 220,220,1,218,218,218,1,217,217,217,1,219,219,219,1,217,217,217,1,219, + 219,219,2,216,216,216,1,219,219,219,1,218,218,218,1,216,216,216,1,217, + 217,217,1,218,218,218,1,217,217,217,1,220,220,220,1,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,2,217,217,217,1,220,220,220,1,217, + 217,217,1,219,219,219,1,217,217,217,1,218,218,218,1,221,221,221,1,211, + 211,211,1,222,222,222,1,220,220,220,1,217,217,217,1,219,219,219,1,218, + 218,218,1,215,215,215,1,255,255,255,1,218,218,218,1,220,220,220,1,171, + 171,171,1,215,215,215,1,217,217,217,1,220,220,220,1,217,217,217,1,219, + 219,219,1,218,218,218,1,221,221,221,1,217,217,217,1,218,218,218,1,219, + 219,219,1,215,215,215,1,220,220,220,1,217,217,217,1,219,219,219,1,217, + 217,217,1,255,255,255,1,217,217,217,1,168,168,168,1,166,166,166,1,218, + 218,218,1,220,220,220,1,219,219,219,1,255,255,255,1,218,218,218,3,217, + 217,217,1,218,218,218,1,217,217,217,1,218,218,218,1,221,221,221,1,217, + 217,217,1,218,218,218,1,254,254,254,1,253,253,253,1,219,219,219,1,220, + 220,220,1,165,165,165,1,219,219,219,2,216,216,216,1,217,217,217,1,219, + 219,219,1,218,218,218,2,217,217,217,1,216,216,216,1,255,255,255,1,254, + 254,254,1,218,218,218,1,219,219,219,1,166,166,166,1,167,167,167,1,219, + 219,219,3,217,217,217,1,255,255,255,1,215,215,215,1,220,220,220,1,170, + 170,170,1,166,166,166,1,169,169,169,2,219,219,219,1,167,167,167,1,218, + 218,218,1,169,169,169,1,218,218,218,1,169,169,169,1,216,216,216,1,254, + 254,254,1,220,220,220,1,218,218,218,1,216,216,216,1,222,222,222,1,217, + 217,217,3,255,255,255,1,219,219,219,1,218,218,218,2,168,168,168,1,170, + 170,170,1,168,168,168,1,167,167,167,1,218,218,218,1,217,217,217,1,218, + 218,218,2,216,216,216,1,217,217,217,1,255,255,255,2,215,215,215,1,218, + 218,218,1,217,217,217,1,255,255,255,1,252,252,252,1,255,255,255,1,254, + 254,254,1,253,253,253,1,255,255,255,1,254,254,254,1,170,170,170,1,165, + 165,165,1,219,219,219,4,218,218,218,2,220,220,220,1,213,213,213,1,221, + 221,221,1,218,218,218,1,217,217,217,1,218,218,218,1,222,222,222,1,217, + 217,217,2,220,220,220,1,218,218,218,2,217,217,217,1,215,215,215,1,216, + 216,216,1,219,219,219,1,167,167,167,1,217,217,217,1,219,219,219,1,220, + 220,220,1,253,253,253,1,255,255,255,1,218,218,218,1,217,217,217,2,221, + 221,221,1,220,220,220,1,217,217,217,2,219,219,219,1,218,218,218,1,221, + 221,221,1,220,220,220,1,254,254,254,1,215,215,215,1,166,166,166,1,217, + 217,217,1,220,220,220,1,219,219,219,1,218,218,218,1,216,216,216,1,221, + 221,221,1,217,217,217,1,214,214,214,1,221,221,221,1,216,216,216,1,215, + 215,215,1,223,223,223,1,218,218,218,1,214,214,214,1,220,220,220,1,216, + 216,216,1,255,255,255,1,218,218,218,2,172,172,172,1,217,217,217,1,214, + 214,214,1,216,216,216,1,255,255,255,1,219,219,219,1,218,218,218,1,217, + 217,217,1,221,221,221,1,217,217,217,1,221,221,221,1,218,218,218,1,216, + 216,216,1,218,218,218,1,217,217,217,1,255,255,255,3,215,215,215,1,219, + 219,219,1,252,252,252,1,255,255,255,1,216,216,216,1,167,167,167,1,220, + 220,220,1,216,216,216,1,219,219,219,1,221,221,221,1,218,218,218,1,216, + 216,216,2,215,215,215,1,170,170,170,1,167,167,167,1,168,168,168,1,223, + 223,223,1,210,210,210,1,217,217,217,1,219,219,219,2,218,218,218,1,167, + 167,167,2,168,168,168,1,171,171,171,1,213,213,213,1,218,218,218,4,250, + 250,250,1,171,171,171,1,167,167,167,1,255,255,255,1,216,216,216,1,218, + 218,218,1,220,220,220,1,213,213,213,1,220,220,220,1,170,170,170,1,169, + 169,169,1,215,215,215,1,218,218,218,1,219,219,219,1,217,217,217,1,167, + 167,167,2,168,168,168,1,166,166,166,1,220,220,220,1,219,219,219,1,216, + 216,216,1,219,219,219,2,220,220,220,1,253,253,253,1,252,252,252,1,255, + 255,255,1,254,254,254,1,217,217,217,1,255,255,255,2,214,214,214,1,218, + 218,218,1,255,255,255,1,254,254,254,1,255,255,255,1,253,253,253,1,222, + 222,222,1,220,220,220,1,216,216,216,1,217,217,217,1,216,216,216,1,222, + 222,222,1,215,215,215,1,216,216,216,1,171,171,171,1,219,219,219,1,217, + 217,217,1,216,216,216,1,220,220,220,1,162,162,162,1,218,218,218,3,217, + 217,217,2,222,222,222,1,218,218,218,1,221,221,221,1,168,168,168,1,217, + 217,217,2,166,166,166,1,217,217,217,1,223,223,223,1,215,215,215,1,217, + 217,217,1,221,221,221,1,218,218,218,2,168,168,168,1,217,217,217,2,168, + 168,168,1,166,166,166,1,216,216,216,1,219,219,219,1,216,216,216,1,220, + 220,220,1,169,169,169,1,218,218,218,2,216,216,216,1,219,219,219,1,221, + 221,221,1,218,218,218,1,216,216,216,1,223,223,223,1,218,218,218,1,216, + 216,216,1,168,168,168,1,215,215,215,1,217,217,217,1,222,222,222,1,215, + 215,215,1,216,216,216,1,254,254,254,2,215,215,215,1,219,219,219,1,216, + 216,216,1,222,222,222,1,220,220,220,1,216,216,216,1,221,221,221,1,219, + 219,219,1,220,220,220,1,215,215,215,1,218,218,218,1,216,216,216,1,217, + 217,217,1,220,220,220,1,217,217,217,1,220,220,220,1,254,254,254,2,216, + 216,216,1,168,168,168,1,170,170,170,1,169,169,169,1,215,215,215,1,222, + 222,222,1,255,255,255,1,253,253,253,1,254,254,254,1,255,255,255,1,165, + 165,165,1,168,168,168,1,218,218,218,1,221,221,221,1,216,216,216,1,220, + 220,220,1,167,167,167,1,215,215,215,1,220,220,220,1,221,221,221,2,218, + 218,218,1,253,253,253,1,255,255,255,1,218,218,218,1,215,215,215,1,221, + 221,221,1,219,219,219,2,218,218,218,2,167,167,167,1,219,219,219,1,222, + 222,222,1,217,217,217,1,167,167,167,1,220,220,220,1,219,219,219,1,218, + 218,218,1,219,219,219,1,222,222,222,1,217,217,217,1,167,167,167,1,219, + 219,219,1,218,218,218,1,221,221,221,1,218,218,218,2,216,216,216,1,218, + 218,218,1,169,169,169,1,175,175,175,1,214,214,214,1,219,219,219,1,220, + 220,220,1,218,218,218,1,215,215,215,2,255,255,255,2,217,217,217,1,218, + 218,218,2,217,217,217,1,214,214,214,1,223,223,223,1,217,217,217,1,216, + 216,216,1,255,255,255,1,253,253,253,1,220,220,220,1,216,216,216,2,220, + 220,220,1,219,219,219,1,217,217,217,1,221,221,221,1,220,220,220,1,169, + 169,169,1,219,219,219,1,215,215,215,1,216,216,216,1,221,221,221,1,216, + 216,216,1,219,219,219,1,222,222,222,1,220,220,220,1,217,217,217,1,219, + 219,219,2,217,217,217,2,254,254,254,1,215,215,215,1,219,219,219,1,218, + 218,218,1,223,223,223,1,168,168,168,1,214,214,214,1,219,219,219,1,220, + 220,220,1,214,214,214,1,218,218,218,1,167,167,167,1,218,218,218,1,169, + 169,169,1,170,170,170,1,168,168,168,1,171,171,171,1,217,217,217,1,255, + 255,255,1,254,254,254,1,167,167,167,1,219,219,219,1,218,218,218,2,221, + 221,221,1,215,215,215,1,167,167,167,1,168,168,168,1,218,218,218,2,216, + 216,216,1,221,221,221,1,167,167,167,1,220,220,220,1,217,217,217,2,221, + 221,221,1,219,219,219,2,255,255,255,1,220,220,220,1,218,218,218,1,220, + 220,220,1,216,216,216,2,219,219,219,1,167,167,167,1,216,216,216,1,219, + 219,219,2,169,169,169,1,170,170,170,1,216,216,216,1,217,217,217,1,221, + 221,221,1,217,217,217,2,255,255,255,1,219,219,219,1,217,217,217,1,166, + 166,166,1,170,170,170,1,216,216,216,2,253,253,253,1,255,255,255,1,219, + 219,219,1,217,217,217,1,255,255,255,1,219,219,219,1,217,217,217,1,218, + 218,218,1,220,220,220,1,215,215,215,1,169,169,169,1,221,221,221,1,212, + 212,212,1,218,218,218,1,217,217,217,2,255,255,255,2,218,218,218,1,217, + 217,217,1,220,220,220,1,212,212,212,1,218,218,218,1,219,219,219,1,220, + 220,220,1,169,169,169,1,217,217,217,1,215,215,215,1,169,169,169,1,218, + 218,218,1,166,166,166,1,217,217,217,1,218,218,218,1,216,216,216,1,217, + 217,217,1,255,255,255,1,165,165,165,1,171,171,171,1,218,218,218,1,252, + 252,252,1,220,220,220,1,216,216,216,1,219,219,219,1,220,220,220,1,164, + 164,164,1,214,214,214,1,218,218,218,1,219,219,219,1,215,215,215,1,219, + 219,219,3,218,218,218,1,219,219,219,1,168,168,168,1,167,167,167,1,216, + 216,216,1,220,220,220,1,221,221,221,1,213,213,213,1,219,219,219,1,217, + 217,217,1,219,219,219,1,220,220,220,1,219,219,219,1,218,218,218,1,220, + 220,220,1,218,218,218,1,217,217,217,1,220,220,220,1,217,217,217,1,253, + 253,253,1,165,165,165,1,219,219,219,1,220,220,220,1,218,218,218,1,255, + 255,255,1,217,217,217,1,221,221,221,1,213,213,213,1,217,217,217,1,218, + 218,218,1,219,219,219,1,213,213,213,1,219,219,219,1,221,221,221,1,216, + 216,216,1,222,222,222,1,255,255,255,1,254,254,254,2,219,219,219,1,218, + 218,218,1,255,255,255,1,253,253,253,1,221,221,221,1,218,218,218,1,219, + 219,219,1,218,218,218,1,220,220,220,1,217,217,217,1,167,167,167,1,169, + 169,169,1,165,165,165,1,255,255,255,2,219,219,219,1,216,216,216,1,218, + 218,218,1,217,217,217,2,219,219,219,1,220,220,220,1,216,216,216,1,219, + 219,219,2,254,254,254,1,219,219,219,1,217,217,217,1,215,215,215,1,220, + 220,220,1,217,217,217,1,218,218,218,2,215,215,215,1,219,219,219,1,216, + 216,216,1,218,218,218,2,219,219,219,1,220,220,220,1,218,218,218,1,168, + 168,168,1,220,220,220,1,218,218,218,2,168,168,168,1,169,169,169,1,171, + 171,171,1,167,167,167,1,215,215,215,1,219,219,219,1,255,255,255,1,254, + 254,254,1,253,253,253,1,255,255,255,1,219,219,219,1,252,252,252,1,221, + 221,221,1,219,219,219,1,218,218,218,1,215,215,215,1,255,255,255,2,217, + 217,217,1,255,255,255,1,252,252,252,1,255,255,255,1,254,254,254,1,218, + 218,218,2,216,216,216,1,220,220,220,2,217,217,217,1,219,219,219,1,255, + 255,255,1,251,251,251,1,254,254,254,1,220,220,220,1,217,217,217,1,255, + 255,255,1,220,220,220,1,216,216,216,1,253,253,253,1,252,252,252,1,220, + 220,220,1,255,255,255,1,166,166,166,1,219,219,219,1,171,171,171,1,168, + 168,168,1,216,216,216,1,223,223,223,1,213,213,213,1,218,218,218,1,222, + 222,222,1,215,215,215,1,255,255,255,2,215,215,215,1,220,220,220,1,219, + 219,219,1,216,216,216,1,218,218,218,1,223,223,223,1,216,216,216,1,219, + 219,219,1,221,221,221,1,218,218,218,3,255,255,255,1,216,216,216,1,167, + 167,167,1,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,217, + 217,217,2,218,218,218,1,219,219,219,1,215,215,215,1,218,218,218,1,217, + 217,217,1,219,219,219,1,215,215,215,1,222,222,222,1,215,215,215,1,255, + 255,255,1,219,219,219,1,220,220,220,1,218,218,218,1,215,215,215,1,218, + 218,218,3,219,219,219,1,220,220,220,1,215,215,215,1,220,220,220,1,218, + 218,218,1,223,223,223,1,216,216,216,1,166,166,166,1,219,219,219,1,217, + 217,217,2,254,254,254,1,219,219,219,1,255,255,255,2,252,252,252,1,255, + 255,255,1,217,217,217,1,165,165,165,1,255,255,255,1,219,219,219,1,216, + 216,216,1,222,222,222,1,167,167,167,1,166,166,166,1,171,171,171,1,255, + 255,255,1,214,214,214,1,219,219,219,1,218,218,218,1,220,220,220,1,167, + 167,167,1,255,255,255,2,214,214,214,1,219,219,219,1,221,221,221,1,217, + 217,217,1,255,255,255,1,216,216,216,1,221,221,221,1,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,218,218,218,1,219,219,219,1,217, + 217,217,1,216,216,216,1,222,222,222,1,217,217,217,2,253,253,253,1,222, + 222,222,1,215,215,215,1,217,217,217,1,254,254,254,1,255,255,255,1,217, + 217,217,1,167,167,167,1,166,166,166,1,164,164,164,1,223,223,223,1,216, + 216,216,1,218,218,218,1,216,216,216,1,255,255,255,2,254,254,254,1,221, + 221,221,1,215,215,215,1,217,217,217,1,219,219,219,1,254,254,254,1,220, + 220,220,1,219,219,219,1,255,255,255,3,253,253,253,1,255,255,255,1,218, + 218,218,1,217,217,217,1,218,218,218,1,222,222,222,1,214,214,214,1,217, + 217,217,1,218,218,218,1,255,255,255,5,252,252,252,1,255,255,255,4,254, + 254,254,1,216,216,216,1,219,219,219,1,165,165,165,1,168,168,168,1,169, + 169,169,1,255,255,255,1,220,220,220,1,255,255,255,2,217,217,217,1,219, + 219,219,1,255,255,255,1,254,254,254,1,255,255,255,1,218,218,218,1,216, + 216,216,2,221,221,221,1,215,215,215,1,216,216,216,1,218,218,218,1,216, + 216,216,1,214,214,214,1,220,220,220,1,216,216,216,1,255,255,255,2,217, + 217,217,1,219,219,219,1,218,218,218,2,216,216,216,1,219,219,219,1,218, + 218,218,1,217,217,217,2,222,222,222,1,220,220,220,1,217,217,217,1,221, + 221,221,1,220,220,220,1,216,216,216,1,218,218,218,1,254,254,254,1,219, + 219,219,1,216,216,216,1,219,219,219,1,222,222,222,1,216,216,216,1,219, + 219,219,1,214,214,214,1,217,217,217,1,218,218,218,1,220,220,220,1,221, + 221,221,1,216,216,216,1,217,217,217,1,219,219,219,1,220,220,220,2,217, + 217,217,1,219,219,219,1,255,255,255,1,254,254,254,1,219,219,219,1,217, + 217,217,1,255,255,255,1,253,253,253,1,217,217,217,1,169,169,169,1,219, + 219,219,1,214,214,214,1,221,221,221,1,215,215,215,1,255,255,255,1,170, + 170,170,1,215,215,215,1,218,218,218,1,221,221,221,1,217,217,217,1,220, + 220,220,1,214,214,214,1,171,171,171,1,168,168,168,1,217,217,217,1,220, + 220,220,1,218,218,218,1,217,217,217,1,216,216,216,1,218,218,218,1,221, + 221,221,1,216,216,216,1,217,217,217,1,216,216,216,1,222,222,222,1,214, + 214,214,1,219,219,219,1,220,220,220,1,217,217,217,1,220,220,220,1,216, + 216,216,1,221,221,221,1,217,217,217,1,255,255,255,1,216,216,216,1,220, + 220,220,1,218,218,218,1,254,254,254,1,255,255,255,1,251,251,251,1,255, + 255,255,1,167,167,167,1,168,168,168,1,217,217,217,1,219,219,219,1,218, + 218,218,1,219,219,219,1,216,216,216,2,166,166,166,1,169,169,169,1,221, + 221,221,1,217,217,217,1,166,166,166,1,170,170,170,1,249,249,249,1,167, + 167,167,1,217,217,217,1,216,216,216,1,218,218,218,1,168,168,168,1,217, + 217,217,1,219,219,219,1,218,218,218,2,167,167,167,1,217,217,217,1,218, + 218,218,1,220,220,220,1,218,218,218,1,252,252,252,1,255,255,255,1,216, + 216,216,1,254,254,254,1,255,255,255,1,217,217,217,1,215,215,215,1,216, + 216,216,1,219,219,219,1,253,253,253,1,217,217,217,1,222,222,222,1,218, + 218,218,1,166,166,166,1,218,218,218,1,254,254,254,1,218,218,218,2,214, + 214,214,1,221,221,221,1,218,218,218,1,255,255,255,2,217,217,217,1,219, + 219,219,1,169,169,169,1,220,220,220,1,216,216,216,1,219,219,219,1,220, + 220,220,1,217,217,217,1,219,219,219,3,214,214,214,1,255,255,255,1,218, + 218,218,3,215,215,215,1,221,221,221,1,217,217,217,1,219,219,219,2,217, + 217,217,1,215,215,215,1,218,218,218,1,215,215,215,1,221,221,221,1,165, + 165,165,1,166,166,166,1,173,173,173,1,216,216,216,1,217,217,217,1,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,3,219,219,219,1,220, + 220,220,1,217,217,217,1,168,168,168,1,215,215,215,1,220,220,220,1,253, + 253,253,2,255,255,255,1,218,218,218,1,216,216,216,1,255,255,255,1,215, + 215,215,1,221,221,221,1,216,216,216,1,220,220,220,1,254,254,254,1,255, + 255,255,1,219,219,219,1,217,217,217,1,216,216,216,1,220,220,220,1,218, + 218,218,1,217,217,217,1,255,255,255,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,1,218,218,218,1,255,255,255,1,222,222,222,1,165, + 165,165,1,168,168,168,1,169,169,169,1,217,217,217,1,219,219,219,1,217, + 217,217,1,219,219,219,2,216,216,216,1,219,219,219,1,218,218,218,2,215, + 215,215,1,220,220,220,1,218,218,218,1,216,216,216,1,219,219,219,1,217, + 217,217,1,219,219,219,1,216,216,216,1,218,218,218,1,220,220,220,1,215, + 215,215,1,217,217,217,1,220,220,220,1,217,217,217,1,255,255,255,2,253, + 253,253,1,167,167,167,1,170,170,170,1,167,167,167,1,218,218,218,1,216, + 216,216,1,220,220,220,1,216,216,216,1,255,255,255,1,217,217,217,1,216, + 216,216,1,255,255,255,1,217,217,217,1,218,218,218,2,170,170,170,1,168, + 168,168,2,218,218,218,1,217,217,217,1,219,219,219,1,220,220,220,1,216, + 216,216,1,217,217,217,1,169,169,169,1,167,167,167,1,219,219,219,2,217, + 217,217,1,218,218,218,1,220,220,220,1,217,217,217,1,220,220,220,1,218, + 218,218,1,215,215,215,1,221,221,221,1,219,219,219,2,216,216,216,1,255, + 255,255,2,217,217,217,1,255,255,255,1,166,166,166,1,219,219,219,1,220, + 220,220,1,216,216,216,1,218,218,218,1,171,171,171,1,216,216,216,1,218, + 218,218,1,220,220,220,1,253,253,253,1,255,255,255,1,216,216,216,1,168, + 168,168,1,219,219,219,1,217,217,217,1,219,219,219,1,217,217,217,1,218, + 218,218,2,216,216,216,1,218,218,218,1,221,221,221,1,216,216,216,1,218, + 218,218,1,219,219,219,1,217,217,217,1,221,221,221,1,215,215,215,1,219, + 219,219,2,216,216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,219, + 219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,215,215,215,1,220, + 220,220,2,217,217,217,1,219,219,219,2,217,217,217,1,219,219,219,2,216, + 216,216,1,218,218,218,1,219,219,219,1,169,169,169,1,218,218,218,1,254, + 254,254,1,255,255,255,3,220,220,220,1,217,217,217,1,218,218,218,2,220, + 220,220,1,215,215,215,1,218,218,218,1,217,217,217,1,255,255,255,2,216, + 216,216,1,218,218,218,1,219,219,219,1,167,167,167,1,252,252,252,1,220, + 220,220,1,217,217,217,1,216,216,216,1,220,220,220,1,219,219,219,1,217, + 217,217,1,255,255,255,2,167,167,167,1,169,169,169,2,167,167,167,1,220, + 220,220,1,217,217,217,1,216,216,216,1,219,219,219,2,218,218,218,9,217, + 217,217,1,218,218,218,1,219,219,219,1,214,214,214,1,220,220,220,1,221, + 221,221,1,217,217,217,1,216,216,216,1,222,222,222,1,253,253,253,1,220, + 220,220,1,169,169,169,1,167,167,167,1,168,168,168,2,218,218,218,1,217, + 217,217,1,255,255,255,2,218,218,218,2,255,255,255,2,165,165,165,1,220, + 220,220,1,169,169,169,1,218,218,218,1,219,219,219,1,253,253,253,1,219, + 219,219,2,217,217,217,1,218,218,218,1,254,254,254,1,171,171,171,1,215, + 215,215,1,219,219,219,1,216,216,216,1,220,220,220,1,218,218,218,8,220, + 220,220,1,216,216,216,1,255,255,255,1,254,254,254,1,217,217,217,1,169, + 169,169,1,166,166,166,1,169,169,169,1,167,167,167,1,217,217,217,1,220, + 220,220,1,217,217,217,1,218,218,218,2,253,253,253,1,255,255,255,1,254, + 254,254,1,166,166,166,1,170,170,170,1,217,217,217,1,219,219,219,1,216, + 216,216,1,221,221,221,1,217,217,217,2,219,219,219,2,217,217,217,1,220, + 220,220,1,216,216,216,2,220,220,220,1,218,218,218,1,216,216,216,1,215, + 215,215,1,221,221,221,1,218,218,218,2,222,222,222,1,216,216,216,1,255, + 255,255,1,254,254,254,1,255,255,255,1,220,220,220,1,217,217,217,2,219, + 219,219,1,218,218,218,1,220,220,220,1,216,216,216,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,1,215,215,215,1,169,169,169,1,167, + 167,167,1,171,171,171,1,218,218,218,1,217,217,217,1,221,221,221,1,217, + 217,217,1,216,216,216,1,218,218,218,1,217,217,217,1,219,219,219,1,217, + 217,217,1,221,221,221,1,218,218,218,1,217,217,217,1,253,253,253,1,255, + 255,255,1,221,221,221,1,215,215,215,1,220,220,220,1,167,167,167,1,220, + 220,220,1,217,217,217,1,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,2,253,253,253,1,255,255,255,1,217,217,217,1,167,167,167,1,220, + 220,220,1,218,218,218,1,221,221,221,1,220,220,220,1,219,219,219,1,216, + 216,216,1,218,218,218,10,221,221,221,1,217,217,217,2,225,225,225,1,214, + 214,214,2,218,218,218,1,220,220,220,1,218,218,218,1,217,217,217,2,218, + 218,218,1,166,166,166,1,169,169,169,1,168,168,168,1,218,218,218,1,220, + 220,220,1,219,219,219,1,215,215,215,1,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,1,220,220,220,1,216,216,216,1,255,255,255,1,217, + 217,217,1,170,170,170,1,218,218,218,1,220,220,220,1,216,216,216,1,219, + 219,219,1,220,220,220,1,216,216,216,1,215,215,215,1,220,220,220,1,219, + 219,219,2,216,216,216,1,218,218,218,9,219,219,219,1,218,218,218,1,169, + 169,169,1,215,215,215,1,170,170,170,1,168,168,168,1,166,166,166,1,170, + 170,170,1,255,255,255,1,216,216,216,1,217,217,217,2,219,219,219,1,220, + 220,220,1,219,219,219,1,255,255,255,1,221,221,221,1,215,215,215,2,220, + 220,220,1,216,216,216,2,169,169,169,1,220,220,220,1,218,218,218,2,219, + 219,219,1,214,214,214,1,219,219,219,1,222,222,222,1,216,216,216,1,217, + 217,217,1,222,222,222,1,220,220,220,1,219,219,219,1,216,216,216,1,166, + 166,166,1,217,217,217,1,219,219,219,2,218,218,218,1,222,222,222,1,215, + 215,215,1,220,220,220,1,218,218,218,1,216,216,216,1,218,218,218,1,217, + 217,217,2,221,221,221,1,215,215,215,1,219,219,219,1,214,214,214,1,255, + 255,255,1,169,169,169,1,220,220,220,1,211,211,211,1,223,223,223,1,216, + 216,216,1,217,217,217,1,218,218,218,2,219,219,219,1,221,221,221,1,216, + 216,216,1,219,219,219,1,217,217,217,1,216,216,216,1,219,219,219,1,218, + 218,218,1,216,216,216,3,167,167,167,3,168,168,168,1,216,216,216,1,219, + 219,219,2,217,217,217,1,216,216,216,1,255,255,255,1,251,251,251,1,218, + 218,218,1,255,255,255,1,214,214,214,1,218,218,218,1,168,168,168,1,212, + 212,212,1,222,222,222,1,220,220,220,1,218,218,218,9,214,214,214,1,221, + 221,221,1,217,217,217,2,215,215,215,1,166,166,166,1,172,172,172,1,168, + 168,168,1,167,167,167,1,216,216,216,1,223,223,223,1,214,214,214,1,221, + 221,221,1,219,219,219,1,169,169,169,1,217,217,217,1,218,218,218,1,219, + 219,219,1,165,165,165,1,170,170,170,1,165,165,165,1,168,168,168,1,220, + 220,220,1,217,217,217,1,221,221,221,1,165,165,165,1,221,221,221,1,168, + 168,168,1,169,169,169,1,166,166,166,1,220,220,220,1,218,218,218,1,217, + 217,217,1,252,252,252,1,220,220,220,2,217,217,217,1,220,220,220,1,213, + 213,213,1,221,221,221,1,218,218,218,8,217,217,217,1,221,221,221,1,214, + 214,214,1,218,218,218,1,217,217,217,2,220,220,220,1,169,169,169,1,218, + 218,218,1,213,213,213,1,218,218,218,1,219,219,219,1,170,170,170,1,213, + 213,213,1,219,219,219,1,253,253,253,2,217,217,217,1,219,219,219,2,215, + 215,215,1,222,222,222,1,220,220,220,1,167,167,167,1,215,215,215,1,221, + 221,221,1,215,215,215,1,223,223,223,1,220,220,220,1,215,215,215,1,218, + 218,218,2,170,170,170,1,164,164,164,1,218,218,218,1,216,216,216,1,219, + 219,219,1,220,220,220,1,218,218,218,1,220,220,220,1,217,217,217,1,219, + 219,219,1,214,214,214,1,218,218,218,3,220,220,220,1,219,219,219,2,220, + 220,220,1,217,217,217,1,218,218,218,1,255,255,255,3,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,217,217,217,2,220, + 220,220,1,218,218,218,1,216,216,216,1,218,218,218,1,217,217,217,1,219, + 219,219,1,220,220,220,1,166,166,166,1,217,217,217,1,225,225,225,1,218, + 218,218,1,220,220,220,1,167,167,167,1,217,217,217,1,220,220,220,1,216, + 216,216,1,220,220,220,1,215,215,215,1,221,221,221,1,219,219,219,2,248, + 248,248,1,255,255,255,1,170,170,170,1,168,168,168,1,169,169,169,1,219, + 219,219,1,217,217,217,1,222,222,222,1,217,217,217,1,216,216,216,1,220, + 220,220,1,218,218,218,8,221,221,221,1,215,215,215,1,219,219,219,1,218, + 218,218,1,169,169,169,1,170,170,170,1,165,165,165,1,169,169,169,1,220, + 220,220,1,218,218,218,1,254,254,254,1,221,221,221,1,217,217,217,1,216, + 216,216,1,165,165,165,1,219,219,219,1,220,220,220,1,166,166,166,1,171, + 171,171,1,168,168,168,1,170,170,170,1,215,215,215,1,218,218,218,1,221, + 221,221,1,167,167,167,1,168,168,168,1,254,254,254,1,168,168,168,1,169, + 169,169,2,164,164,164,1,219,219,219,1,255,255,255,1,220,220,220,1,217, + 217,217,1,216,216,216,1,219,219,219,1,217,217,217,1,220,220,220,1,218, + 218,218,9,254,254,254,1,255,255,255,1,222,222,222,1,217,217,217,1,221, + 221,221,1,218,218,218,1,215,215,215,1,166,166,166,2,222,222,222,1,168, + 168,168,1,216,216,216,2,220,220,220,2,219,219,219,1,220,220,220,1,217, + 217,217,1,222,222,222,1,167,167,167,1,218,218,218,1,255,255,255,1,214, + 214,214,1,218,218,218,1,219,219,219,2,220,220,220,1,212,212,212,1,217, + 217,217,1,222,222,222,1,213,213,213,1,221,221,221,1,166,166,166,1,170, + 170,170,1,221,221,221,1,253,253,253,1,222,222,222,1,217,217,217,1,219, + 219,219,1,215,215,215,1,166,166,166,1,171,171,171,1,168,168,168,1,219, + 219,219,1,217,217,217,2,219,219,219,1,216,216,216,1,219,219,219,1,217, + 217,217,1,216,216,216,1,220,220,220,1,217,217,217,1,252,252,252,1,169, + 169,169,1,167,167,167,1,214,214,214,1,220,220,220,1,217,217,217,1,221, + 221,221,1,219,219,219,1,218,218,218,1,220,220,220,1,212,212,212,1,223, + 223,223,1,219,219,219,1,218,218,218,2,217,217,217,1,221,221,221,1,217, + 217,217,1,216,216,216,2,218,218,218,1,255,255,255,1,254,254,254,1,220, + 220,220,1,217,217,217,1,216,216,216,1,219,219,219,1,217,217,217,2,220, + 220,220,1,255,255,255,1,218,218,218,1,215,215,215,1,168,168,168,1,255, + 255,255,1,219,219,219,1,217,217,217,1,218,218,218,1,221,221,221,1,216, + 216,216,1,218,218,218,9,217,217,217,1,218,218,218,1,168,168,168,1,217, + 217,217,1,220,220,220,1,216,216,216,1,220,220,220,1,216,216,216,1,217, + 217,217,1,215,215,215,1,218,218,218,1,219,219,219,1,220,220,220,1,167, + 167,167,1,222,222,222,1,216,216,216,1,253,253,253,1,221,221,221,1,216, + 216,216,1,219,219,219,1,218,218,218,1,219,219,219,1,221,221,221,1,214, + 214,214,1,168,168,168,1,216,216,216,1,222,222,222,1,220,220,220,1,164, + 164,164,1,171,171,171,1,170,170,170,1,167,167,167,1,164,164,164,1,217, + 217,217,1,218,218,218,1,221,221,221,1,213,213,213,1,218,218,218,1,220, + 220,220,1,217,217,217,1,218,218,218,8,255,255,255,1,254,254,254,1,252, + 252,252,1,217,217,217,2,216,216,216,1,221,221,221,1,169,169,169,2,166, + 166,166,1,255,255,255,1,219,219,219,1,220,220,220,1,216,216,216,3,217, + 217,217,1,215,215,215,1,220,220,220,1,215,215,215,1,218,218,218,1,255, + 255,255,1,217,217,217,1,220,220,220,2,215,215,215,1,216,216,216,1,223, + 223,223,1,219,219,219,1,220,220,220,1,255,255,255,2,172,172,172,1,215, + 215,215,1,216,216,216,1,217,217,217,2,219,219,219,1,216,216,216,1,171, + 171,171,1,169,169,169,1,164,164,164,1,219,219,219,3,216,216,216,1,217, + 217,217,1,220,220,220,1,218,218,218,1,217,217,217,1,222,222,222,1,214, + 214,214,1,216,216,216,1,220,220,220,1,171,171,171,1,218,218,218,1,220, + 220,220,1,219,219,219,1,217,217,217,1,215,215,215,1,217,217,217,2,218, + 218,218,1,219,219,219,1,221,221,221,1,213,213,213,1,216,216,216,1,255, + 255,255,1,218,218,218,1,215,215,215,1,219,219,219,1,218,218,218,1,220, + 220,220,1,168,168,168,1,216,216,216,1,218,218,218,3,219,219,219,2,220, + 220,220,1,218,218,218,1,219,219,219,1,255,255,255,3,217,217,217,1,216, + 216,216,1,218,218,218,1,221,221,221,1,219,219,219,1,214,214,214,1,220, + 220,220,1,218,218,218,9,216,216,216,1,221,221,221,1,216,216,216,1,218, + 218,218,1,219,219,219,1,218,218,218,2,219,219,219,1,166,166,166,1,223, + 223,223,1,219,219,219,1,216,216,216,1,217,217,217,1,218,218,218,1,216, + 216,216,1,255,255,255,1,254,254,254,1,219,219,219,1,216,216,216,1,217, + 217,217,1,219,219,219,1,215,215,215,1,220,220,220,1,219,219,219,1,169, + 169,169,1,218,218,218,1,251,251,251,1,217,217,217,1,221,221,221,1,213, + 213,213,1,168,168,168,1,170,170,170,1,169,169,169,2,220,220,220,2,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,8,255, + 255,255,1,254,254,254,1,220,220,220,1,219,219,219,2,218,218,218,1,215, + 215,215,1,169,169,169,1,218,218,218,1,216,216,216,1,217,217,217,1,219, + 219,219,1,218,218,218,2,219,219,219,1,220,220,220,1,218,218,218,1,255, + 255,255,1,215,215,215,1,220,220,220,1,222,222,222,1,167,167,167,1,217, + 217,217,1,219,219,219,1,217,217,217,1,220,220,220,1,218,218,218,3,215, + 215,215,1,254,254,254,1,255,255,255,1,218,218,218,3,219,219,219,2,218, + 218,218,1,219,219,219,1,253,253,253,1,255,255,255,1,220,220,220,1,219, + 219,219,1,217,217,217,2,219,219,219,2,215,215,215,1,218,218,218,2,215, + 215,215,1,220,220,220,1,255,255,255,2,213,213,213,1,218,218,218,1,219, + 219,219,1,217,217,217,1,220,220,220,1,217,217,217,1,221,221,221,1,220, + 220,220,1,218,218,218,2,216,216,216,1,217,217,217,1,255,255,255,1,218, + 218,218,1,215,215,215,1,220,220,220,1,219,219,219,1,216,216,216,1,170, + 170,170,1,212,212,212,1,222,222,222,1,219,219,219,1,217,217,217,2,219, + 219,219,1,215,215,215,1,217,217,217,1,218,218,218,2,166,166,166,1,255, + 255,255,1,218,218,218,1,221,221,221,1,167,167,167,1,219,219,219,1,216, + 216,216,1,213,213,213,1,225,225,225,1,219,219,219,1,215,215,215,1,218, + 218,218,8,254,254,254,2,219,219,219,2,217,217,217,1,219,219,219,1,217, + 217,217,2,220,220,220,1,216,216,216,1,215,215,215,1,219,219,219,1,168, + 168,168,1,222,222,222,1,218,218,218,1,254,254,254,1,255,255,255,1,216, + 216,216,1,221,221,221,1,217,217,217,1,220,220,220,1,217,217,217,1,216, + 216,216,1,218,218,218,2,254,254,254,1,255,255,255,3,223,223,223,1,216, + 216,216,1,166,166,166,1,165,165,165,1,169,169,169,1,217,217,217,1,214, + 214,214,1,216,216,216,1,220,220,220,1,218,218,218,1,220,220,220,1,218, + 218,218,8,219,219,219,1,252,252,252,1,255,255,255,2,167,167,167,1,218, + 218,218,1,220,220,220,1,215,215,215,1,169,169,169,1,220,220,220,1,213, + 213,213,1,220,220,220,1,216,216,216,1,217,217,217,1,223,223,223,1,214, + 214,214,1,218,218,218,1,216,216,216,1,223,223,223,1,214,214,214,1,166, + 166,166,1,218,218,218,1,216,216,216,1,219,219,219,1,218,218,218,2,216, + 216,216,1,220,220,220,1,212,212,212,1,221,221,221,1,255,255,255,1,219, + 219,219,1,218,218,218,3,220,220,220,1,216,216,216,1,217,217,217,1,255, + 255,255,2,218,218,218,1,215,215,215,1,221,221,221,1,219,219,219,1,218, + 218,218,1,217,217,217,1,221,221,221,1,217,217,217,1,219,219,219,1,167, + 167,167,1,222,222,222,1,253,253,253,1,255,255,255,1,218,218,218,1,217, + 217,217,1,219,219,219,1,217,217,217,1,216,216,216,1,219,219,219,1,217, + 217,217,2,216,216,216,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,254,254,254,1,218,218,218,1,220,220,220,1,218,218,218,2,255, + 255,255,1,219,219,219,1,169,169,169,1,218,218,218,1,166,166,166,1,220, + 220,220,1,218,218,218,2,219,219,219,1,221,221,221,1,218,218,218,1,216, + 216,216,1,221,221,221,1,215,215,215,1,220,220,220,1,218,218,218,1,216, + 216,216,1,220,220,220,1,217,217,217,1,221,221,221,1,216,216,216,1,217, + 217,217,1,220,220,220,1,218,218,218,8,255,255,255,1,253,253,253,1,218, + 218,218,1,220,220,220,1,216,216,216,1,220,220,220,1,218,218,218,1,219, + 219,219,1,216,216,216,1,219,219,219,1,221,221,221,1,169,169,169,1,166, + 166,166,1,217,217,217,1,168,168,168,1,255,255,255,1,253,253,253,1,255, + 255,255,1,252,252,252,1,255,255,255,2,219,219,219,1,216,216,216,1,219, + 219,219,1,220,220,220,1,254,254,254,1,255,255,255,1,253,253,253,1,255, + 255,255,1,254,254,254,1,255,255,255,1,219,219,219,1,169,169,169,1,217, + 217,217,1,219,219,219,3,218,218,218,1,216,216,216,1,218,218,218,9,255, + 255,255,2,254,254,254,2,219,219,219,1,217,217,217,1,216,216,216,1,170, + 170,170,1,167,167,167,1,217,217,217,1,220,220,220,1,218,218,218,3,217, + 217,217,1,219,219,219,1,218,218,218,2,217,217,217,1,255,255,255,1,218, + 218,218,2,219,219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,218, + 218,218,2,221,221,221,1,215,215,215,1,219,219,219,1,216,216,216,1,218, + 218,218,1,217,217,217,1,219,219,219,1,216,216,216,1,255,255,255,1,169, + 169,169,1,217,217,217,2,218,218,218,1,220,220,220,1,216,216,216,1,217, + 217,217,1,222,222,222,1,216,216,216,1,217,217,217,1,219,219,219,1,217, + 217,217,1,169,169,169,1,217,217,217,1,216,216,216,1,219,219,219,2,218, + 218,218,1,217,217,217,1,218,218,218,3,220,220,220,1,218,218,218,2,220, + 220,220,1,216,216,216,1,219,219,219,1,254,254,254,1,255,255,255,1,254, + 254,254,1,255,255,255,2,254,254,254,1,219,219,219,1,218,218,218,2,221, + 221,221,1,217,217,217,2,220,220,220,1,217,217,217,1,219,219,219,1,167, + 167,167,1,219,219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,255, + 255,255,1,219,219,219,1,215,215,215,1,218,218,218,1,221,221,221,1,215, + 215,215,1,217,217,217,1,218,218,218,2,220,220,220,1,218,218,218,1,217, + 217,217,1,218,218,218,2,219,219,219,1,218,218,218,1,217,217,217,1,255, + 255,255,1,254,254,254,1,219,219,219,1,217,217,217,1,220,220,220,1,217, + 217,217,1,221,221,221,1,215,215,215,1,218,218,218,1,217,217,217,2,167, + 167,167,1,218,218,218,1,219,219,219,1,166,166,166,1,255,255,255,4,253, + 253,253,1,255,255,255,1,217,217,217,1,220,220,220,1,168,168,168,1,218, + 218,218,2,219,219,219,1,254,254,254,1,255,255,255,1,253,253,253,1,255, + 255,255,2,218,218,218,9,216,216,216,1,218,218,218,3,167,167,167,1,171, + 171,171,1,216,216,216,1,219,219,219,1,217,217,217,1,253,253,253,1,255, + 255,255,1,215,215,215,1,218,218,218,2,170,170,170,1,168,168,168,1,219, + 219,219,1,166,166,166,1,171,171,171,1,216,216,216,1,220,220,220,1,216, + 216,216,1,219,219,219,2,216,216,216,1,255,255,255,1,217,217,217,2,165, + 165,165,1,171,171,171,1,166,166,166,1,170,170,170,1,216,216,216,1,219, + 219,219,1,217,217,217,1,220,220,220,1,215,215,215,1,222,222,222,1,216, + 216,216,1,218,218,218,1,219,219,219,1,216,216,216,1,255,255,255,1,167, + 167,167,1,165,165,165,1,219,219,219,2,217,217,217,1,219,219,219,1,217, + 217,217,1,219,219,219,1,168,168,168,1,218,218,218,2,255,255,255,1,219, + 219,219,1,166,166,166,1,222,222,222,1,215,215,215,1,216,216,216,1,219, + 219,219,1,217,217,217,1,219,219,219,2,218,218,218,1,217,217,217,1,218, + 218,218,1,219,219,219,1,218,218,218,1,216,216,216,1,221,221,221,1,218, + 218,218,1,254,254,254,1,255,255,255,3,216,216,216,1,169,169,169,1,255, + 255,255,1,216,216,216,1,253,253,253,1,219,219,219,1,220,220,220,1,217, + 217,217,1,216,216,216,1,220,220,220,1,216,216,216,1,168,168,168,2,166, + 166,166,1,165,165,165,1,168,168,168,1,217,217,217,2,221,221,221,1,219, + 219,219,1,215,215,215,1,221,221,221,2,219,219,219,2,215,215,215,1,220, + 220,220,1,219,219,219,1,217,217,217,2,219,219,219,1,218,218,218,1,219, + 219,219,1,254,254,254,1,219,219,219,1,214,214,214,1,222,222,222,1,217, + 217,217,3,221,221,221,1,218,218,218,1,219,219,219,2,167,167,167,1,255, + 255,255,1,216,216,216,1,221,221,221,1,219,219,219,1,218,218,218,1,214, + 214,214,1,221,221,221,1,255,255,255,1,216,216,216,1,221,221,221,1,168, + 168,168,2,220,220,220,1,216,216,216,1,217,217,217,1,220,220,220,1,217, + 217,217,1,255,255,255,1,249,249,249,1,220,220,220,1,218,218,218,8,219, + 219,219,1,220,220,220,1,217,217,217,1,219,219,219,1,217,217,217,1,218, + 218,218,1,217,217,217,1,222,222,222,1,218,218,218,1,215,215,215,1,220, + 220,220,1,218,218,218,1,220,220,220,1,218,218,218,1,220,220,220,1,164, + 164,164,1,166,166,166,1,168,168,168,1,171,171,171,2,217,217,217,1,215, + 215,215,1,221,221,221,1,216,216,216,2,220,220,220,1,216,216,216,1,220, + 220,220,1,221,221,221,1,168,168,168,2,167,167,167,1,215,215,215,1,223, + 223,223,1,217,217,217,2,219,219,219,1,214,214,214,1,218,218,218,1,220, + 220,220,1,215,215,215,1,218,218,218,1,221,221,221,1,251,251,251,1,220, + 220,220,1,221,221,221,1,217,217,217,1,218,218,218,1,219,219,219,1,220, + 220,220,1,218,218,218,1,217,217,217,1,219,219,219,1,215,215,215,1,221, + 221,221,1,253,253,253,1,217,217,217,1,167,167,167,1,217,217,217,1,221, + 221,221,1,218,218,218,1,220,220,220,1,217,217,217,2,218,218,218,1,217, + 217,217,1,222,222,222,1,218,218,218,2,217,217,217,1,218,218,218,1,219, + 219,219,1,215,215,215,1,221,221,221,1,217,217,217,1,218,218,218,2,219, + 219,219,1,166,166,166,1,218,218,218,1,222,222,222,1,216,216,216,1,218, + 218,218,1,219,219,219,2,220,220,220,1,252,252,252,1,255,255,255,1,216, + 216,216,1,167,167,167,1,173,173,173,1,170,170,170,1,218,218,218,1,217, + 217,217,2,215,215,215,1,218,218,218,1,220,220,220,1,217,217,217,1,219, + 219,219,1,214,214,214,1,218,218,218,1,220,220,220,1,216,216,216,2,221, + 221,221,1,217,217,217,1,215,215,215,1,220,220,220,1,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,1,217,217,217,3,221,221,221,1,216, + 216,216,1,218,218,218,1,216,216,216,1,168,168,168,1,222,222,222,1,254, + 254,254,1,216,216,216,1,217,217,217,1,216,216,216,1,219,219,219,1,221, + 221,221,1,213,213,213,1,254,254,254,1,218,218,218,2,167,167,167,1,216, + 216,216,1,214,214,214,1,222,222,222,1,218,218,218,1,217,217,217,1,219, + 219,219,2,221,221,221,1,215,215,215,1,218,218,218,8,216,216,216,1,217, + 217,217,1,220,220,220,1,253,253,253,1,255,255,255,1,216,216,216,1,219, + 219,219,1,214,214,214,1,218,218,218,1,220,220,220,1,217,217,217,1,216, + 216,216,1,219,219,219,1,217,217,217,2,170,170,170,1,218,218,218,1,219, + 219,219,1,164,164,164,1,218,218,218,2,219,219,219,1,216,216,216,1,220, + 220,220,1,217,217,217,1,222,222,222,1,219,219,219,1,253,253,253,2,254, + 254,254,1,218,218,218,2,220,220,220,1,215,215,215,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,222, + 222,222,1,218,218,218,1,251,251,251,1,255,255,255,1,216,216,216,1,218, + 218,218,1,217,217,217,2,216,216,216,2,255,255,255,1,222,222,222,1,215, + 215,215,1,219,219,219,1,215,215,215,1,255,255,255,1,218,218,218,1,170, + 170,170,1,167,167,167,1,216,216,216,1,220,220,220,1,216,216,216,1,218, + 218,218,1,219,219,219,1,215,215,215,1,221,221,221,1,215,215,215,1,218, + 218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,221,221,221,1,164, + 164,164,1,218,218,218,1,217,217,217,1,218,218,218,1,255,255,255,1,216, + 216,216,1,220,220,220,1,218,218,218,1,212,212,212,1,223,223,223,1,217, + 217,217,2,218,218,218,1,217,217,217,1,254,254,254,1,220,220,220,1,255, + 255,255,2,217,217,217,1,165,165,165,1,219,219,219,1,217,217,217,2,220, + 220,220,2,218,218,218,1,219,219,219,1,215,215,215,1,222,222,222,1,218, + 218,218,1,217,217,217,1,218,218,218,1,217,217,217,1,216,216,216,1,222, + 222,222,1,218,218,218,2,253,253,253,1,255,255,255,1,217,217,217,1,218, + 218,218,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,219, + 219,219,1,218,218,218,1,219,219,219,1,166,166,166,1,164,164,164,1,221, + 221,221,1,220,220,220,1,219,219,219,1,221,221,221,1,218,218,218,1,216, + 216,216,1,255,255,255,1,219,219,219,1,216,216,216,1,219,219,219,1,165, + 165,165,1,222,222,222,1,221,221,221,1,165,165,165,1,169,169,169,1,170, + 170,170,1,217,217,217,1,218,218,218,1,217,217,217,1,220,220,220,1,218, + 218,218,8,219,219,219,1,221,221,221,1,217,217,217,2,219,219,219,1,216, + 216,216,1,220,220,220,1,219,219,219,1,254,254,254,1,255,255,255,1,215, + 215,215,1,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,221,221,221,1,216,216,216,1,172,172,172,1,217,217,217,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,220,220,220,1,216, + 216,216,1,214,214,214,1,255,255,255,1,222,222,222,1,254,254,254,1,165, + 165,165,1,220,220,220,1,217,217,217,1,216,216,216,1,221,221,221,1,218, + 218,218,1,215,215,215,1,220,220,220,2,217,217,217,1,216,216,216,2,220, + 220,220,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,220, + 220,220,1,218,218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,222, + 222,222,1,217,217,217,2,254,254,254,1,218,218,218,1,164,164,164,1,169, + 169,169,1,221,221,221,1,214,214,214,1,218,218,218,1,219,219,219,1,217, + 217,217,1,221,221,221,1,219,219,219,1,220,220,220,1,218,218,218,1,217, + 217,217,2,220,220,220,1,217,217,217,1,221,221,221,1,219,219,219,1,221, + 221,221,1,217,217,217,1,253,253,253,1,221,221,221,1,217,217,217,1,218, + 218,218,1,220,220,220,1,215,215,215,1,218,218,218,1,222,222,222,1,214, + 214,214,1,220,220,220,1,170,170,170,1,254,254,254,1,255,255,255,1,252, + 252,252,1,167,167,167,1,173,173,173,1,166,166,166,1,218,218,218,1,219, + 219,219,1,218,218,218,1,213,213,213,1,220,220,220,1,219,219,219,1,216, + 216,216,1,169,169,169,1,168,168,168,2,171,171,171,1,170,170,170,1,168, + 168,168,1,218,218,218,1,216,216,216,1,253,253,253,1,255,255,255,1,254, + 254,254,1,218,218,218,4,219,219,219,1,217,217,217,1,219,219,219,1,215, + 215,215,1,172,172,172,1,167,167,167,1,172,172,172,1,167,167,167,2,215, + 215,215,1,216,216,216,1,219,219,219,1,216,216,216,1,255,255,255,1,218, + 218,218,1,217,217,217,1,168,168,168,1,219,219,219,1,216,216,216,1,219, + 219,219,1,166,166,166,1,170,170,170,1,166,166,166,1,219,219,219,2,217, + 217,217,1,218,218,218,9,217,217,217,1,214,214,214,1,221,221,221,1,220, + 220,220,1,215,215,215,1,220,220,220,1,218,218,218,1,217,217,217,1,255, + 255,255,2,219,219,219,3,214,214,214,1,220,220,220,1,219,219,219,1,218, + 218,218,1,166,166,166,1,219,219,219,1,218,218,218,1,215,215,215,1,221, + 221,221,1,214,214,214,1,220,220,220,1,217,217,217,1,220,220,220,1,218, + 218,218,1,171,171,171,1,217,217,217,1,170,170,170,1,168,168,168,1,216, + 216,216,1,221,221,221,1,219,219,219,1,218,218,218,2,219,219,219,1,217, + 217,217,2,219,219,219,1,220,220,220,2,216,216,216,1,218,218,218,3,219, + 219,219,1,217,217,217,1,219,219,219,2,216,216,216,1,220,220,220,1,218, + 218,218,1,214,214,214,1,221,221,221,1,255,255,255,2,217,217,217,1,220, + 220,220,1,218,218,218,1,221,221,221,1,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,1,164,164,164,1,218,218,218,3,220,220,220,1,255, + 255,255,1,218,218,218,1,166,166,166,2,165,165,165,1,218,218,218,1,219, + 219,219,1,218,218,218,1,220,220,220,1,218,218,218,1,221,221,221,1,218, + 218,218,1,216,216,216,1,220,220,220,1,215,215,215,1,255,255,255,1,166, + 166,166,1,165,165,165,1,255,255,255,1,254,254,254,1,172,172,172,1,213, + 213,213,1,170,170,170,1,218,218,218,1,220,220,220,1,219,219,219,1,217, + 217,217,1,220,220,220,1,215,215,215,1,218,218,218,1,168,168,168,1,169, + 169,169,1,167,167,167,1,165,165,165,1,168,168,168,1,165,165,165,1,217, + 217,217,1,219,219,219,1,220,220,220,1,254,254,254,1,255,255,255,1,217, + 217,217,1,219,219,219,1,217,217,217,1,214,214,214,1,222,222,222,1,217, + 217,217,1,218,218,218,1,222,222,222,1,214,214,214,1,167,167,167,1,169, + 169,169,1,167,167,167,1,170,170,170,1,218,218,218,2,167,167,167,1,255, + 255,255,1,252,252,252,1,255,255,255,1,216,216,216,1,168,168,168,1,217, + 217,217,1,255,255,255,2,219,219,219,1,165,165,165,1,220,220,220,1,218, + 218,218,1,219,219,219,3,218,218,218,9,220,220,220,1,218,218,218,2,220, + 220,220,1,214,214,214,1,219,219,219,1,217,217,217,1,250,250,250,1,254, + 254,254,1,219,219,219,1,216,216,216,1,217,217,217,1,222,222,222,1,217, + 217,217,1,254,254,254,1,255,255,255,1,224,224,224,1,215,215,215,1,218, + 218,218,1,222,222,222,1,216,216,216,1,217,217,217,1,218,218,218,1,217, + 217,217,1,219,219,219,1,255,255,255,1,167,167,167,1,255,255,255,1,212, + 212,212,1,172,172,172,1,216,216,216,1,215,215,215,1,218,218,218,1,215, + 215,215,1,219,219,219,1,222,222,222,1,217,217,217,1,216,216,216,1,218, + 218,218,2,216,216,216,1,217,217,217,1,221,221,221,1,216,216,216,1,217, + 217,217,3,218,218,218,2,217,217,217,1,219,219,219,3,217,217,217,1,254, + 254,254,1,251,251,251,1,218,218,218,1,219,219,219,1,217,217,217,1,219, + 219,219,1,213,213,213,1,221,221,221,1,218,218,218,2,165,165,165,1,172, + 172,172,1,217,217,217,1,218,218,218,1,217,217,217,1,168,168,168,2,218, + 218,218,1,220,220,220,2,221,221,221,1,214,214,214,1,218,218,218,2,216, + 216,216,1,217,217,217,1,220,220,220,1,219,219,219,2,218,218,218,1,217, + 217,217,2,170,170,170,1,254,254,254,1,255,255,255,1,252,252,252,1,170, + 170,170,1,220,220,220,1,216,216,216,1,214,214,214,1,221,221,221,1,218, + 218,218,2,255,255,255,3,216,216,216,1,218,218,218,2,171,171,171,1,169, + 169,169,2,215,215,215,1,220,220,220,1,253,253,253,1,214,214,214,1,224, + 224,224,1,215,215,215,1,219,219,219,1,222,222,222,1,215,215,215,1,217, + 217,217,1,218,218,218,1,216,216,216,1,219,219,219,1,224,224,224,1,252, + 252,252,1,166,166,166,1,218,218,218,1,219,219,219,1,218,218,218,1,168, + 168,168,1,218,218,218,1,216,216,216,1,218,218,218,1,171,171,171,1,165, + 165,165,1,167,167,167,1,255,255,255,3,220,220,220,1,219,219,219,1,218, + 218,218,3,216,216,216,1,218,218,218,8,216,216,216,1,218,218,218,1,216, + 216,216,1,218,218,218,1,222,222,222,1,217,217,217,1,218,218,218,1,221, + 221,221,1,255,255,255,3,216,216,216,1,220,220,220,1,217,217,217,1,252, + 252,252,1,255,255,255,1,215,215,215,1,214,214,214,1,220,220,220,1,218, + 218,218,3,217,217,217,1,219,219,219,1,218,218,218,1,255,255,255,1,254, + 254,254,1,218,218,218,2,221,221,221,1,216,216,216,1,221,221,221,1,218, + 218,218,1,221,221,221,1,219,219,219,1,217,217,217,3,220,220,220,2,221, + 221,221,1,215,215,215,1,217,217,217,1,219,219,219,1,216,216,216,1,221, + 221,221,1,220,220,220,1,219,219,219,1,217,217,217,1,215,215,215,1,222, + 222,222,1,218,218,218,1,215,215,215,1,221,221,221,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,218, + 218,218,1,220,220,220,1,214,214,214,1,255,255,255,1,219,219,219,1,218, + 218,218,1,216,216,216,1,171,171,171,1,166,166,166,1,168,168,168,1,254, + 254,254,1,255,255,255,2,215,215,215,1,219,219,219,1,217,217,217,2,220, + 220,220,1,218,218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,217, + 217,217,1,168,168,168,1,255,255,255,2,220,220,220,1,218,218,218,1,255, + 255,255,1,218,218,218,1,255,255,255,1,219,219,219,1,165,165,165,1,219, + 219,219,3,218,218,218,1,217,217,217,1,255,255,255,2,254,254,254,1,255, + 255,255,1,218,218,218,2,168,168,168,1,167,167,167,1,166,166,166,1,171, + 171,171,1,215,215,215,1,255,255,255,1,220,220,220,1,217,217,217,1,218, + 218,218,2,214,214,214,1,221,221,221,1,219,219,219,1,218,218,218,1,221, + 221,221,1,253,253,253,1,214,214,214,1,255,255,255,1,216,216,216,1,220, + 220,220,1,255,255,255,1,217,217,217,1,167,167,167,2,220,220,220,1,219, + 219,219,1,165,165,165,1,170,170,170,1,167,167,167,1,217,217,217,1,254, + 254,254,1,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,222, + 222,222,1,215,215,215,1,220,220,220,1,218,218,218,8,220,220,220,1,216, + 216,216,1,219,219,219,1,218,218,218,1,215,215,215,1,169,169,169,1,218, + 218,218,1,216,216,216,1,254,254,254,1,255,255,255,3,218,218,218,1,166, + 166,166,1,220,220,220,1,218,218,218,2,221,221,221,1,218,218,218,2,217, + 217,217,1,219,219,219,1,168,168,168,1,217,217,217,1,219,219,219,1,252, + 252,252,1,221,221,221,1,217,217,217,1,254,254,254,1,218,218,218,2,217, + 217,217,1,219,219,219,1,216,216,216,1,218,218,218,1,219,219,219,1,217, + 217,217,1,218,218,218,2,217,217,217,2,219,219,219,2,218,218,218,3,216, + 216,216,1,217,217,217,1,219,219,219,1,220,220,220,1,217,217,217,1,215, + 215,215,1,221,221,221,1,166,166,166,1,165,165,165,1,169,169,169,1,168, + 168,168,1,215,215,215,1,219,219,219,1,217,217,217,1,218,218,218,1,217, + 217,217,1,220,220,220,1,254,254,254,1,255,255,255,1,217,217,217,1,218, + 218,218,1,215,215,215,1,171,171,171,1,167,167,167,1,220,220,220,1,217, + 217,217,2,219,219,219,1,166,166,166,1,168,168,168,1,170,170,170,1,167, + 167,167,1,168,168,168,1,167,167,167,1,222,222,222,1,212,212,212,1,255, + 255,255,1,220,220,220,1,217,217,217,1,254,254,254,1,219,219,219,1,216, + 216,216,1,220,220,220,1,255,255,255,1,217,217,217,1,215,215,215,1,221, + 221,221,1,217,217,217,1,219,219,219,1,217,217,217,1,218,218,218,1,217, + 217,217,1,219,219,219,1,255,255,255,3,219,219,219,1,216,216,216,1,220, + 220,220,1,168,168,168,1,166,166,166,1,173,173,173,1,250,250,250,1,255, + 255,255,2,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,219, + 219,219,2,218,218,218,1,217,217,217,1,168,168,168,1,219,219,219,1,217, + 217,217,1,216,216,216,1,222,222,222,1,255,255,255,1,216,216,216,1,218, + 218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,169, + 169,169,1,166,166,166,1,168,168,168,1,166,166,166,1,220,220,220,1,216, + 216,216,1,219,219,219,1,221,221,221,1,217,217,217,2,218,218,218,4,219, + 219,219,1,167,167,167,1,217,217,217,1,219,219,219,1,167,167,167,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,222, + 222,222,1,215,215,215,1,216,216,216,1,218,218,218,1,255,255,255,2,253, + 253,253,1,220,220,220,1,216,216,216,1,219,219,219,3,218,218,218,3,220, + 220,220,2,217,217,217,2,220,220,220,1,255,255,255,1,253,253,253,1,222, + 222,222,1,215,215,215,1,221,221,221,1,218,218,218,1,217,217,217,1,218, + 218,218,17,220,220,220,1,216,216,216,1,219,219,219,1,217,217,217,2,170, + 170,170,1,168,168,168,2,220,220,220,1,215,215,215,1,221,221,221,1,219, + 219,219,1,217,217,217,1,169,169,169,1,168,168,168,2,220,220,220,1,217, + 217,217,1,253,253,253,1,255,255,255,2,164,164,164,1,170,170,170,1,218, + 218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,163,163,163,1,170, + 170,170,1,167,167,167,1,170,170,170,1,215,215,215,1,255,255,255,1,218, + 218,218,1,217,217,217,1,215,215,215,1,222,222,222,1,221,221,221,1,215, + 215,215,1,167,167,167,1,170,170,170,1,217,217,217,1,221,221,221,1,219, + 219,219,1,216,216,216,1,217,217,217,1,220,220,220,1,217,217,217,1,218, + 218,218,2,217,217,217,1,255,255,255,1,216,216,216,2,220,220,220,2,218, + 218,218,1,167,167,167,1,216,216,216,1,255,255,255,1,252,252,252,1,254, + 254,254,1,215,215,215,1,220,220,220,1,222,222,222,1,217,217,217,1,220, + 220,220,1,216,216,216,1,169,169,169,1,218,218,218,1,220,220,220,1,217, + 217,217,1,219,219,219,1,220,220,220,1,215,215,215,1,219,219,219,1,222, + 222,222,1,255,255,255,2,217,217,217,1,216,216,216,1,217,217,217,1,220, + 220,220,1,168,168,168,1,169,169,169,1,170,170,170,1,221,221,221,1,219, + 219,219,1,216,216,216,2,217,217,217,1,220,220,220,3,214,214,214,1,220, + 220,220,1,216,216,216,1,170,170,170,1,218,218,218,2,169,169,169,1,166, + 166,166,1,218,218,218,1,217,217,217,1,255,255,255,1,219,219,219,1,215, + 215,215,1,219,219,219,1,223,223,223,1,219,219,219,1,216,216,216,1,255, + 255,255,2,214,214,214,1,222,222,222,1,219,219,219,1,217,217,217,1,216, + 216,216,1,218,218,218,1,221,221,221,1,215,215,215,1,254,254,254,1,217, + 217,217,2,221,221,221,1,216,216,216,1,220,220,220,1,219,219,219,1,218, + 218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,221,221,221,1,218, + 218,218,16,216,216,216,1,215,215,215,1,222,222,222,1,255,255,255,2,220, + 220,220,1,255,255,255,1,166,166,166,1,216,216,216,1,221,221,221,1,218, + 218,218,1,216,216,216,1,169,169,169,1,166,166,166,1,169,169,169,2,168, + 168,168,1,167,167,167,1,255,255,255,4,220,220,220,1,218,218,218,1,255, + 255,255,1,254,254,254,1,255,255,255,4,220,220,220,1,217,217,217,1,220, + 220,220,1,217,217,217,1,218,218,218,1,217,217,217,1,222,222,222,1,214, + 214,214,1,215,215,215,1,221,221,221,1,169,169,169,1,166,166,166,1,217, + 217,217,1,219,219,219,1,217,217,217,1,167,167,167,1,218,218,218,1,217, + 217,217,1,216,216,216,1,221,221,221,1,218,218,218,1,217,217,217,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,215,215,215,1,218, + 218,218,1,171,171,171,1,168,168,168,1,216,216,216,1,255,255,255,3,217, + 217,217,1,218,218,218,1,215,215,215,1,214,214,214,1,255,255,255,3,215, + 215,215,1,218,218,218,2,217,217,217,1,216,216,216,1,254,254,254,2,255, + 255,255,2,221,221,221,1,218,218,218,1,255,255,255,1,252,252,252,1,220, + 220,220,1,167,167,167,1,170,170,170,1,211,211,211,1,217,217,217,1,219, + 219,219,2,221,221,221,1,218,218,218,1,215,215,215,1,216,216,216,1,220, + 220,220,1,255,255,255,1,218,218,218,1,216,216,216,1,254,254,254,1,217, + 217,217,1,219,219,219,1,218,218,218,2,219,219,219,1,216,216,216,1,220, + 220,220,1,217,217,217,2,213,213,213,1,218,218,218,1,220,220,220,1,215, + 215,215,1,218,218,218,1,220,220,220,1,214,214,214,1,216,216,216,1,220, + 220,220,1,219,219,219,1,220,220,220,1,214,214,214,1,222,222,222,1,221, + 221,221,1,218,218,218,1,217,217,217,1,220,220,220,1,218,218,218,1,217, + 217,217,1,218,218,218,1,217,217,217,1,216,216,216,1,220,220,220,2,215, + 215,215,1,218,218,218,16,219,219,219,1,221,221,221,1,211,211,211,1,219, + 219,219,1,255,255,255,1,252,252,252,1,254,254,254,1,220,220,220,1,217, + 217,217,1,218,218,218,1,221,221,221,1,213,213,213,1,255,255,255,2,215, + 215,215,1,255,255,255,1,253,253,253,1,172,172,172,1,214,214,214,1,217, + 217,217,1,254,254,254,1,255,255,255,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,252,252,252,1,255,255,255,3,218,218,218,1,216, + 216,216,1,218,218,218,1,222,222,222,1,218,218,218,1,217,217,217,1,218, + 218,218,2,255,255,255,1,252,252,252,1,255,255,255,1,217,217,217,1,219, + 219,219,1,218,218,218,1,167,167,167,1,169,169,169,2,219,219,219,1,170, + 170,170,1,167,167,167,1,170,170,170,1,218,218,218,1,217,217,217,1,218, + 218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,169,169,169,1,165, + 165,165,1,169,169,169,1,217,217,217,1,254,254,254,1,253,253,253,1,254, + 254,254,1,255,255,255,1,254,254,254,1,255,255,255,3,216,216,216,1,218, + 218,218,2,219,219,219,1,216,216,216,1,254,254,254,1,221,221,221,1,168, + 168,168,1,169,169,169,1,254,254,254,1,253,253,253,1,255,255,255,4,254, + 254,254,1,218,218,218,1,215,215,215,1,225,225,225,1,220,220,220,1,218, + 218,218,1,216,216,216,1,218,218,218,1,217,217,217,1,220,220,220,1,218, + 218,218,2,253,253,253,1,215,215,215,1,222,222,222,1,255,255,255,1,254, + 254,254,1,218,218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,217, + 217,217,1,216,216,216,1,221,221,221,1,217,217,217,1,220,220,220,1,217, + 217,217,1,220,220,220,1,215,215,215,1,220,220,220,1,223,223,223,1,217, + 217,217,1,222,222,222,1,216,216,216,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,2,215,215,215,1,220,220,220,1,216,216,216,1,220, + 220,220,1,218,218,218,1,220,220,220,1,221,221,221,1,217,217,217,2,220, + 220,220,1,217,217,217,1,218,218,218,16,220,220,220,1,216,216,216,1,219, + 219,219,1,255,255,255,1,214,214,214,1,255,255,255,1,218,218,218,1,215, + 215,215,1,219,219,219,2,252,252,252,1,223,223,223,1,218,218,218,1,255, + 255,255,1,219,219,219,1,254,254,254,1,169,169,169,1,166,166,166,1,171, + 171,171,1,221,221,221,1,219,219,219,2,218,218,218,1,217,217,217,2,222, + 222,222,1,218,218,218,1,221,221,221,1,219,219,219,1,216,216,216,1,217, + 217,217,1,220,220,220,1,217,217,217,1,215,215,215,1,218,218,218,1,216, + 216,216,1,220,220,220,2,251,251,251,1,255,255,255,1,220,220,220,1,217, + 217,217,1,218,218,218,1,255,255,255,1,167,167,167,1,168,168,168,1,167, + 167,167,3,168,168,168,1,215,215,215,1,216,216,216,1,223,223,223,1,219, + 219,219,1,216,216,216,1,219,219,219,1,220,220,220,1,217,217,217,1,169, + 169,169,1,167,167,167,1,219,219,219,1,218,218,218,1,255,255,255,2,251, + 251,251,1,215,215,215,1,221,221,221,1,215,215,215,1,216,216,216,1,218, + 218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,255,255,255,1,223, + 223,223,1,215,215,215,1,167,167,167,2,220,220,220,1,255,255,255,1,169, + 169,169,1,165,165,165,1,217,217,217,3,220,220,220,1,218,218,218,1,216, + 216,216,1,215,215,215,1,219,219,219,1,220,220,220,2,216,216,216,1,219, + 219,219,2,217,217,217,2,222,222,222,1,215,215,215,1,216,216,216,1,218, + 218,218,1,217,217,217,1,218,218,218,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,213,213,213,1,221,221,221,1,217,217,217,2,219, + 219,219,1,220,220,220,1,215,215,215,2,217,217,217,1,215,215,215,1,221, + 221,221,1,220,220,220,1,214,214,214,1,218,218,218,1,220,220,220,1,216, + 216,216,1,221,221,221,1,220,220,220,1,218,218,218,2,216,216,216,2,218, + 218,218,1,219,219,219,1,217,217,217,2,220,220,220,1,218,218,218,16,217, + 217,217,1,215,215,215,1,221,221,221,1,216,216,216,1,220,220,220,1,215, + 215,215,1,217,217,217,1,222,222,222,1,218,218,218,1,217,217,217,2,167, + 167,167,1,214,214,214,1,166,166,166,1,219,219,219,1,220,220,220,1,169, + 169,169,1,167,167,167,2,216,216,216,2,217,217,217,1,167,167,167,1,173, + 173,173,1,215,215,215,1,166,166,166,1,169,169,169,1,164,164,164,1,170, + 170,170,1,219,219,219,1,218,218,218,1,219,219,219,4,221,221,221,1,215, + 215,215,1,167,167,167,1,169,169,169,1,220,220,220,1,219,219,219,1,218, + 218,218,1,251,251,251,1,255,255,255,2,169,169,169,1,221,221,221,1,215, + 215,215,1,223,223,223,1,217,217,217,1,220,220,220,1,219,219,219,2,214, + 214,214,1,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,169, + 169,169,1,170,170,170,1,216,216,216,1,217,217,217,1,218,218,218,1,214, + 214,214,1,224,224,224,1,222,222,222,1,216,216,216,2,221,221,221,1,219, + 219,219,1,169,169,169,1,216,216,216,2,255,255,255,1,250,250,250,1,255, + 255,255,1,222,222,222,1,168,168,168,1,169,169,169,1,165,165,165,1,166, + 166,166,1,175,175,175,1,166,166,166,1,170,170,170,1,172,172,172,1,165, + 165,165,1,219,219,219,1,218,218,218,2,219,219,219,1,218,218,218,2,217, + 217,217,1,218,218,218,1,215,215,215,1,217,217,217,1,223,223,223,1,216, + 216,216,1,219,219,219,1,221,221,221,1,219,219,219,2,217,217,217,2,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,2,223,223,223,1,219,219,219,1,220, + 220,220,2,217,217,217,2,225,225,225,1,165,165,165,1,168,168,168,1,167, + 167,167,1,219,219,219,1,216,216,216,1,218,218,218,1,216,216,216,1,222, + 222,222,1,220,220,220,1,216,216,216,1,218,218,218,1,220,220,220,1,218, + 218,218,1,217,217,217,1,218,218,218,16,219,219,219,1,220,220,220,1,216, + 216,216,1,219,219,219,3,218,218,218,1,215,215,215,1,218,218,218,1,255, + 255,255,2,214,214,214,1,255,255,255,1,168,168,168,1,218,218,218,1,215, + 215,215,1,218,218,218,1,170,170,170,1,167,167,167,1,220,220,220,1,219, + 219,219,1,218,218,218,1,219,219,219,1,214,214,214,1,170,170,170,2,167, + 167,167,1,171,171,171,1,218,218,218,1,217,217,217,1,218,218,218,1,214, + 214,214,1,219,219,219,1,216,216,216,1,214,214,214,1,221,221,221,1,216, + 216,216,1,168,168,168,1,169,169,169,1,216,216,216,1,214,214,214,1,222, + 222,222,1,255,255,255,1,254,254,254,1,220,220,220,1,215,215,215,1,218, + 218,218,1,220,220,220,1,213,213,213,1,218,218,218,1,219,219,219,1,218, + 218,218,1,215,215,215,1,220,220,220,2,218,218,218,1,223,223,223,1,218, + 218,218,1,166,166,166,1,167,167,167,1,220,220,220,1,219,219,219,1,218, + 218,218,1,253,253,253,1,216,216,216,1,214,214,214,1,221,221,221,1,218, + 218,218,1,216,216,216,1,167,167,167,2,220,220,220,1,218,218,218,1,220, + 220,220,1,255,255,255,1,250,250,250,1,219,219,219,1,166,166,166,1,217, + 217,217,2,223,223,223,1,215,215,215,1,218,218,218,1,165,165,165,1,168, + 168,168,1,171,171,171,1,217,217,217,1,218,218,218,1,220,220,220,1,219, + 219,219,1,218,218,218,3,217,217,217,1,221,221,221,1,220,220,220,1,217, + 217,217,1,216,216,216,2,217,217,217,1,168,168,168,1,218,218,218,2,219, + 219,219,1,218,218,218,1,219,219,219,2,215,215,215,1,219,219,219,1,217, + 217,217,1,218,218,218,1,214,214,214,1,220,220,220,2,215,215,215,1,218, + 218,218,1,217,217,217,1,220,220,220,1,217,217,217,1,214,214,214,1,218, + 218,218,1,172,172,172,1,167,167,167,1,219,219,219,1,216,216,216,1,219, + 219,219,1,216,216,216,1,218,218,218,4,217,217,217,2,220,220,220,1,218, + 218,218,16,216,216,216,1,220,220,220,1,218,218,218,1,219,219,219,1,217, + 217,217,1,214,214,214,1,222,222,222,1,218,218,218,1,217,217,217,1,252, + 252,252,1,255,255,255,2,214,214,214,1,254,254,254,1,218,218,218,1,221, + 221,221,1,219,219,219,1,165,165,165,1,168,168,168,1,220,220,220,1,254, + 254,254,1,253,253,253,1,217,217,217,1,255,255,255,1,254,254,254,2,255, + 255,255,1,218,218,218,1,217,217,217,1,218,218,218,2,219,219,219,1,217, + 217,217,1,218,218,218,1,219,219,219,1,253,253,253,1,218,218,218,1,169, + 169,169,1,167,167,167,1,220,220,220,1,218,218,218,1,167,167,167,1,168, + 168,168,1,219,219,219,1,216,216,216,1,220,220,220,1,217,217,217,1,255, + 255,255,2,254,254,254,1,255,255,255,1,218,218,218,1,219,219,219,1,218, + 218,218,1,216,216,216,1,219,219,219,1,215,215,215,1,221,221,221,1,167, + 167,167,1,171,171,171,1,166,166,166,1,218,218,218,1,215,215,215,1,223, + 223,223,1,217,217,217,2,218,218,218,1,216,216,216,1,255,255,255,1,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,217,217,217,2,255, + 255,255,1,254,254,254,1,219,219,219,1,218,218,218,1,255,255,255,1,254, + 254,254,1,255,255,255,3,219,219,219,1,216,216,216,1,218,218,218,4,219, + 219,219,1,217,217,217,1,219,219,219,1,218,218,218,2,215,215,215,1,218, + 218,218,1,220,220,220,1,219,219,219,2,218,218,218,1,168,168,168,1,219, + 219,219,1,215,215,215,1,221,221,221,1,216,216,216,1,218,218,218,2,216, + 216,216,1,219,219,219,1,218,218,218,1,220,220,220,1,217,217,217,2,218, + 218,218,2,220,220,220,1,215,215,215,1,255,255,255,2,254,254,254,1,218, + 218,218,1,217,217,217,1,218,218,218,1,221,221,221,1,216,216,216,1,219, + 219,219,1,218,218,218,1,219,219,219,2,217,217,217,1,219,219,219,1,220, + 220,220,1,216,216,216,1,218,218,218,19,216,216,216,1,220,220,220,1,219, + 219,219,1,214,214,214,1,220,220,220,2,218,218,218,2,254,254,254,1,255, + 255,255,2,219,219,219,1,216,216,216,1,217,217,217,1,171,171,171,1,167, + 167,167,1,217,217,217,1,255,255,255,3,253,253,253,1,255,255,255,1,254, + 254,254,1,217,217,217,1,221,221,221,1,214,214,214,1,220,220,220,1,219, + 219,219,1,216,216,216,1,220,220,220,1,217,217,217,2,220,220,220,1,216, + 216,216,1,170,170,170,1,172,172,172,1,166,166,166,1,167,167,167,1,169, + 169,169,1,215,215,215,1,218,218,218,1,219,219,219,1,218,218,218,2,219, + 219,219,1,255,255,255,1,253,253,253,1,254,254,254,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,219, + 219,219,1,170,170,170,1,167,167,167,1,168,168,168,2,217,217,217,1,218, + 218,218,1,221,221,221,1,215,215,215,1,222,222,222,1,253,253,253,1,255, + 255,255,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,2,255, + 255,255,1,216,216,216,1,220,220,220,1,217,217,217,1,216,216,216,1,221, + 221,221,1,217,217,217,2,255,255,255,2,215,215,215,1,218,218,218,2,217, + 217,217,1,219,219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,216, + 216,216,1,218,218,218,2,220,220,220,1,217,217,217,1,216,216,216,1,254, + 254,254,1,221,221,221,1,217,217,217,1,169,169,169,1,218,218,218,9,220, + 220,220,1,214,214,214,1,219,219,219,1,220,220,220,1,217,217,217,1,168, + 168,168,1,217,217,217,1,216,216,216,1,255,255,255,2,215,215,215,1,220, + 220,220,1,218,218,218,3,219,219,219,1,217,217,217,1,219,219,219,2,218, + 218,218,3,169,169,169,1,218,218,218,8,217,217,217,1,220,220,220,1,216, + 216,216,1,220,220,220,1,217,217,217,1,218,218,218,1,216,216,216,1,219, + 219,219,2,217,217,217,1,218,218,218,3,220,220,220,1,219,219,219,2,218, + 218,218,2,219,219,219,1,218,218,218,1,255,255,255,1,254,254,254,1,255, + 255,255,3,217,217,217,1,168,168,168,1,169,169,169,1,167,167,167,2,220, + 220,220,1,216,216,216,1,215,215,215,1,219,219,219,2,168,168,168,1,220, + 220,220,1,219,219,219,2,217,217,217,1,215,215,215,1,221,221,221,1,254, + 254,254,1,215,215,215,1,222,222,222,1,165,165,165,1,164,164,164,1,220, + 220,220,1,221,221,221,1,218,218,218,1,222,222,222,1,216,216,216,1,221, + 221,221,1,166,166,166,2,169,169,169,1,216,216,216,1,255,255,255,2,217, + 217,217,1,218,218,218,1,219,219,219,1,220,220,220,1,216,216,216,1,255, + 255,255,2,212,212,212,1,168,168,168,1,170,170,170,1,169,169,169,1,221, + 221,221,1,216,216,216,1,217,217,217,1,219,219,219,1,218,218,218,1,219, + 219,219,1,220,220,220,1,216,216,216,2,220,220,220,2,219,219,219,1,217, + 217,217,1,255,255,255,1,218,218,218,1,217,217,217,1,220,220,220,1,167, + 167,167,1,169,169,169,2,215,215,215,1,219,219,219,1,169,169,169,1,171, + 171,171,1,219,219,219,1,215,215,215,1,219,219,219,1,217,217,217,1,215, + 215,215,1,221,221,221,1,218,218,218,1,221,221,221,1,217,217,217,1,216, + 216,216,1,222,222,222,1,217,217,217,1,222,222,222,1,251,251,251,1,218, + 218,218,1,217,217,217,1,218,218,218,8,219,219,219,1,217,217,217,1,221, + 221,221,1,217,217,217,1,219,219,219,1,218,218,218,2,169,169,169,1,170, + 170,170,1,217,217,217,1,167,167,167,1,221,221,221,1,215,215,215,1,218, + 218,218,2,217,217,217,1,219,219,219,1,217,217,217,1,215,215,215,1,217, + 217,217,1,220,220,220,1,215,215,215,1,219,219,219,1,216,216,216,1,218, + 218,218,8,214,214,214,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,2,171,171,171,1,218,218,218,1,217,217,217,1,220,220,220,1,217, + 217,217,2,218,218,218,1,216,216,216,2,217,217,217,1,219,219,219,1,218, + 218,218,1,215,215,215,1,220,220,220,1,253,253,253,1,255,255,255,2,254, + 254,254,1,253,253,253,1,221,221,221,1,167,167,167,2,255,255,255,2,168, + 168,168,2,173,173,173,1,217,217,217,1,216,216,216,1,217,217,217,1,221, + 221,221,1,214,214,214,1,215,215,215,1,220,220,220,1,219,219,219,1,255, + 255,255,1,218,218,218,1,220,220,220,1,218,218,218,1,220,220,220,2,216, + 216,216,1,218,218,218,2,214,214,214,1,222,222,222,1,217,217,217,1,220, + 220,220,1,169,169,169,1,167,167,167,1,220,220,220,1,255,255,255,1,254, + 254,254,1,215,215,215,1,219,219,219,1,218,218,218,1,214,214,214,1,255, + 255,255,1,253,253,253,1,255,255,255,2,219,219,219,1,167,167,167,1,166, + 166,166,1,215,215,215,1,220,220,220,2,216,216,216,1,217,217,217,1,218, + 218,218,1,217,217,217,1,218,218,218,1,214,214,214,1,221,221,221,1,216, + 216,216,1,253,253,253,1,255,255,255,2,251,251,251,1,255,255,255,1,253, + 253,253,1,254,254,254,1,221,221,221,1,216,216,216,1,218,218,218,1,219, + 219,219,1,168,168,168,1,215,215,215,1,220,220,220,1,221,221,221,1,215, + 215,215,1,219,219,219,1,170,170,170,1,165,165,165,1,219,219,219,1,214, + 214,214,1,221,221,221,1,217,217,217,2,218,218,218,2,255,255,255,1,217, + 217,217,1,218,218,218,9,216,216,216,1,222,222,222,1,215,215,215,1,216, + 216,216,1,255,255,255,1,219,219,219,1,218,218,218,1,216,216,216,1,219, + 219,219,1,215,215,215,1,218,218,218,2,217,217,217,1,222,222,222,1,220, + 220,220,1,219,219,219,1,216,216,216,1,219,219,219,1,222,222,222,1,219, + 219,219,1,216,216,216,1,255,255,255,1,213,213,213,1,219,219,219,1,218, + 218,218,8,219,219,219,1,222,222,222,1,217,217,217,1,218,218,218,1,219, + 219,219,1,218,218,218,1,216,216,216,1,217,217,217,1,220,220,220,1,217, + 217,217,1,216,216,216,1,219,219,219,1,218,218,218,1,219,219,219,1,223, + 223,223,1,218,218,218,1,217,217,217,1,221,221,221,1,218,218,218,1,217, + 217,217,1,220,220,220,1,218,218,218,1,215,215,215,1,220,220,220,1,255, + 255,255,1,252,252,252,1,255,255,255,2,217,217,217,1,215,215,215,1,216, + 216,216,1,217,217,217,1,216,216,216,1,255,255,255,1,220,220,220,1,217, + 217,217,2,219,219,219,1,221,221,221,1,218,218,218,1,216,216,216,1,254, + 254,254,1,217,217,217,1,222,222,222,1,213,213,213,1,218,218,218,1,216, + 216,216,1,222,222,222,1,216,216,216,1,219,219,219,1,218,218,218,1,220, + 220,220,1,216,216,216,1,218,218,218,1,169,169,169,1,171,171,171,1,165, + 165,165,1,253,253,253,1,254,254,254,1,222,222,222,1,217,217,217,1,219, + 219,219,1,169,169,169,1,216,216,216,1,255,255,255,1,252,252,252,1,255, + 255,255,1,219,219,219,1,165,165,165,1,172,172,172,1,217,217,217,1,220, + 220,220,1,217,217,217,2,221,221,221,1,220,220,220,1,218,218,218,1,220, + 220,220,1,221,221,221,1,218,218,218,2,217,217,217,1,252,252,252,1,216, + 216,216,1,220,220,220,1,254,254,254,1,255,255,255,2,218,218,218,1,216, + 216,216,1,255,255,255,1,253,253,253,1,219,219,219,2,216,216,216,1,217, + 217,217,1,221,221,221,1,220,220,220,1,168,168,168,1,169,169,169,2,219, + 219,219,1,215,215,215,1,221,221,221,1,219,219,219,2,218,218,218,3,219, + 219,219,1,218,218,218,8,219,219,219,1,217,217,217,2,222,222,222,1,218, + 218,218,1,255,255,255,1,254,254,254,1,221,221,221,1,255,255,255,1,218, + 218,218,1,217,217,217,1,220,220,220,2,215,215,215,1,218,218,218,1,216, + 216,216,1,218,218,218,1,217,217,217,1,216,216,216,2,217,217,217,1,215, + 215,215,1,220,220,220,2,218,218,218,9,214,214,214,1,219,219,219,1,217, + 217,217,1,255,255,255,1,215,215,215,1,220,220,220,1,219,219,219,1,215, + 215,215,1,217,217,217,1,220,220,220,1,221,221,221,1,217,217,217,1,216, + 216,216,1,217,217,217,1,216,216,216,1,217,217,217,1,219,219,219,1,218, + 218,218,2,217,217,217,1,218,218,218,1,216,216,216,1,218,218,218,1,253, + 253,253,1,254,254,254,1,221,221,221,1,215,215,215,1,221,221,221,1,217, + 217,217,1,255,255,255,1,218,218,218,1,220,220,220,1,217,217,217,1,219, + 219,219,1,217,217,217,1,216,216,216,1,220,220,220,1,217,217,217,1,216, + 216,216,1,255,255,255,2,217,217,217,2,220,220,220,1,216,216,216,1,217, + 217,217,1,220,220,220,1,218,218,218,1,220,220,220,2,216,216,216,1,217, + 217,217,1,220,220,220,1,165,165,165,1,167,167,167,1,169,169,169,1,255, + 255,255,1,253,253,253,1,254,254,254,1,219,219,219,1,167,167,167,1,168, + 168,168,2,217,217,217,1,253,253,253,1,219,219,219,1,220,220,220,1,167, + 167,167,2,220,220,220,1,217,217,217,2,219,219,219,1,218,218,218,1,216, + 216,216,2,218,218,218,1,216,216,216,1,217,217,217,1,221,221,221,1,217, + 217,217,1,224,224,224,1,215,215,215,1,220,220,220,3,218,218,218,1,217, + 217,217,1,219,219,219,1,255,255,255,1,219,219,219,1,216,216,216,1,218, + 218,218,1,220,220,220,1,217,217,217,1,253,253,253,1,254,254,254,1,166, + 166,166,1,219,219,219,1,215,215,215,1,219,219,219,1,220,220,220,1,218, + 218,218,1,214,214,214,1,217,217,217,1,221,221,221,1,216,216,216,1,219, + 219,219,1,218,218,218,9,219,219,219,1,218,218,218,1,219,219,219,1,216, + 216,216,2,217,217,217,1,220,220,220,1,216,216,216,1,219,219,219,3,215, + 215,215,1,218,218,218,1,215,215,215,1,222,222,222,1,219,219,219,1,220, + 220,220,1,218,218,218,1,219,219,219,1,222,222,222,1,217,217,217,1,219, + 219,219,1,220,220,220,1,215,215,215,1,218,218,218,9,221,221,221,1,216, + 216,216,1,219,219,219,1,218,218,218,1,222,222,222,1,214,214,214,1,217, + 217,217,1,220,220,220,2,218,218,218,1,215,215,215,1,219,219,219,1,221, + 221,221,1,216,216,216,1,220,220,220,2,217,217,217,2,218,218,218,1,220, + 220,220,1,221,221,221,1,220,220,220,1,217,217,217,1,219,219,219,2,218, + 218,218,1,222,222,222,1,215,215,215,1,220,220,220,1,216,216,216,1,219, + 219,219,1,217,217,217,1,215,215,215,1,219,219,219,1,220,220,220,1,217, + 217,217,1,216,216,216,1,218,218,218,1,215,215,215,1,255,255,255,2,254, + 254,254,1,217,217,217,2,220,220,220,2,217,217,217,1,215,215,215,1,220, + 220,220,1,215,215,215,1,217,217,217,1,222,222,222,1,214,214,214,1,255, + 255,255,1,216,216,216,1,220,220,220,1,255,255,255,1,254,254,254,2,222, + 222,222,1,167,167,167,1,169,169,169,1,168,168,168,1,170,170,170,1,219, + 219,219,1,218,218,218,1,215,215,215,1,170,170,170,1,167,167,167,1,217, + 217,217,1,218,218,218,1,220,220,220,1,218,218,218,1,216,216,216,1,220, + 220,220,1,222,222,222,1,216,216,216,1,219,219,219,2,218,218,218,1,217, + 217,217,2,220,220,220,1,213,213,213,1,218,218,218,2,215,215,215,1,218, + 218,218,1,217,217,217,1,219,219,219,2,218,218,218,1,219,219,219,1,216, + 216,216,1,219,219,219,1,255,255,255,3,221,221,221,1,219,219,219,1,216, + 216,216,1,218,218,218,1,217,217,217,1,220,220,220,2,219,219,219,2,216, + 216,216,1,217,217,217,1,218,218,218,8,216,216,216,1,220,220,220,1,218, + 218,218,1,219,219,219,2,221,221,221,1,217,217,217,1,219,219,219,1,216, + 216,216,1,221,221,221,1,216,216,216,1,222,222,222,1,220,220,220,1,218, + 218,218,1,216,216,216,2,218,218,218,2,217,217,217,1,218,218,218,1,217, + 217,217,3,220,220,220,1,218,218,218,8,217,217,217,1,218,218,218,3,216, + 216,216,2,221,221,221,1,218,218,218,1,219,219,219,1,215,215,215,1,219, + 219,219,2,216,216,216,1,219,219,219,2,217,217,217,2,216,216,216,1,220, + 220,220,1,218,218,218,2,216,216,216,1,220,220,220,1,219,219,219,1,217, + 217,217,2,213,213,213,1,217,217,217,1,219,219,219,1,214,214,214,1,219, + 219,219,1,221,221,221,1,218,218,218,1,219,219,219,1,217,217,217,1,216, + 216,216,1,219,219,219,1,220,220,220,1,217,217,217,1,221,221,221,1,255, + 255,255,2,252,252,252,1,255,255,255,2,253,253,253,1,218,218,218,1,219, + 219,219,4,254,254,254,1,255,255,255,3,216,216,216,2,220,220,220,1,254, + 254,254,1,255,255,255,1,215,215,215,1,219,219,219,1,166,166,166,1,168, + 168,168,1,214,214,214,1,218,218,218,2,220,220,220,1,168,168,168,1,218, + 218,218,1,220,220,220,1,217,217,217,2,218,218,218,4,216,216,216,1,219, + 219,219,1,215,215,215,1,220,220,220,1,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,3,218,218,218,1,170,170,170,1,221,221,221,1,215, + 215,215,1,218,218,218,1,215,215,215,1,221,221,221,2,215,215,215,1,254, + 254,254,1,221,221,221,1,215,215,215,1,217,217,217,1,218,218,218,2,217, + 217,217,1,218,218,218,2,216,216,216,1,217,217,217,1,215,215,215,1,221, + 221,221,1,219,219,219,1,218,218,218,8,222,222,222,1,216,216,216,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,216,216,216,1,217, + 217,217,1,221,221,221,1,213,213,213,1,218,218,218,1,217,217,217,1,218, + 218,218,1,220,220,220,1,218,218,218,1,219,219,219,1,216,216,216,1,220, + 220,220,1,217,217,217,2,219,219,219,1,220,220,220,1,217,217,217,2,218, + 218,218,8,221,221,221,1,214,214,214,1,221,221,221,1,216,216,216,1,218, + 218,218,1,219,219,219,3,216,216,216,1,220,220,220,1,216,216,216,1,219, + 219,219,1,220,220,220,1,216,216,216,1,220,220,220,1,217,217,217,1,220, + 220,220,1,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,218, + 218,218,1,219,219,219,1,217,217,217,1,219,219,219,2,221,221,221,1,217, + 217,217,1,220,220,220,1,218,218,218,1,168,168,168,1,165,165,165,1,220, + 220,220,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,2,217, + 217,217,1,218,218,218,1,217,217,217,1,253,253,253,1,255,255,255,1,254, + 254,254,2,220,220,220,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,218,218,218,1,255,255,255,1,218,218,218,4,219,219,219,1,216, + 216,216,1,255,255,255,1,218,218,218,1,217,217,217,1,220,220,220,1,219, + 219,219,2,220,220,220,1,217,217,217,2,218,218,218,1,216,216,216,1,220, + 220,220,1,216,216,216,1,220,220,220,1,219,219,219,1,217,217,217,1,219, + 219,219,2,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,217, + 217,217,1,218,218,218,3,220,220,220,1,217,217,217,2,170,170,170,1,215, + 215,215,1,217,217,217,1,220,220,220,1,218,218,218,1,220,220,220,1,216, + 216,216,1,217,217,217,2,221,221,221,1,216,216,216,1,220,220,220,1,216, + 216,216,1,218,218,218,2,219,219,219,1,218,218,218,2,219,219,219,2,217, + 217,217,1,219,219,219,1,217,217,217,1,218,218,218,8,216,216,216,1,219, + 219,219,1,215,215,215,1,221,221,221,1,217,217,217,1,216,216,216,1,222, + 222,222,1,217,217,217,1,216,216,216,1,223,223,223,1,216,216,216,1,217, + 217,217,1,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,219, + 219,219,1,216,216,216,1,218,218,218,1,220,220,220,1,216,216,216,1,219, + 219,219,1,216,216,216,1,220,220,220,1,218,218,218,8,216,216,216,1,222, + 222,222,1,217,217,217,1,216,216,216,1,219,219,219,2,215,215,215,1,217, + 217,217,1,219,219,219,1,218,218,218,1,168,168,168,1,169,169,169,1,215, + 215,215,1,220,220,220,1,217,217,217,1,220,220,220,1,217,217,217,1,218, + 218,218,2,219,219,219,1,217,217,217,1,218,218,218,2,219,219,219,1,216, + 216,216,1,220,220,220,1,218,218,218,1,216,216,216,1,220,220,220,1,217, + 217,217,1,218,218,218,3,219,219,219,1,218,218,218,2,216,216,216,1,218, + 218,218,1,217,217,217,1,221,221,221,1,216,216,216,1,220,220,220,1,217, + 217,217,2,255,255,255,2,218,218,218,1,220,220,220,1,217,217,217,1,219, + 219,219,1,217,217,217,2,220,220,220,1,217,217,217,1,216,216,216,1,221, + 221,221,1,218,218,218,1,217,217,217,1,219,219,219,1,222,222,222,1,213, + 213,213,1,219,219,219,3,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,220,220,220,1,218,218,218,1,217,217,217,1,218,218,218,2,219, + 219,219,1,215,215,215,1,219,219,219,1,218,218,218,1,219,219,219,2,218, + 218,218,1,216,216,216,1,221,221,221,1,219,219,219,1,217,217,217,1,219, + 219,219,1,217,217,217,1,255,255,255,1,167,167,167,1,171,171,171,1,218, + 218,218,3,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,220, + 220,220,1,217,217,217,1,219,219,219,1,217,217,217,1,219,219,219,1,218, + 218,218,9,217,217,217,1,219,219,219,1,218,218,218,2,217,217,217,1,220, + 220,220,1,215,215,215,1,219,219,219,1,216,216,216,1,221,221,221,1,219, + 219,219,1,217,217,217,1,218,218,218,1,217,217,217,1,219,219,219,1,218, + 218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,220,220,220,2,217, + 217,217,1,218,218,218,1,219,219,219,1,218,218,218,2,216,216,216,1,219, + 219,219,1,217,217,217,1,220,220,220,1,218,218,218,1,219,219,219,1,218, + 218,218,16,215,215,215,1,222,222,222,1,216,216,216,1,217,217,217,1,220, + 220,220,1,216,216,216,1,219,219,219,1,220,220,220,1,218,218,218,15,217, + 217,217,1,170,170,170,1,214,214,214,1,219,219,219,1,220,220,220,1,219, + 219,219,1,218,218,218,1,219,219,219,1,215,215,215,1,219,219,219,1,216, + 216,216,1,218,218,218,1,255,255,255,1,252,252,252,1,255,255,255,1,254, + 254,254,1,255,255,255,2,214,214,214,1,220,220,220,2,217,217,217,1,218, + 218,218,1,222,222,222,1,214,214,214,1,218,218,218,1,222,222,222,1,214, + 214,214,1,218,218,218,2,221,221,221,1,219,219,219,1,218,218,218,1,214, + 214,214,1,220,220,220,1,217,217,217,1,220,220,220,1,215,215,215,1,218, + 218,218,1,221,221,221,1,217,217,217,1,216,216,216,1,217,217,217,1,221, + 221,221,1,218,218,218,1,215,215,215,1,168,168,168,1,217,217,217,2,218, + 218,218,1,215,215,215,1,216,216,216,1,218,218,218,1,220,220,220,1,253, + 253,253,1,218,218,218,1,165,165,165,1,164,164,164,1,217,217,217,1,221, + 221,221,1,218,218,218,1,215,215,215,1,219,219,219,1,221,221,221,2,218, + 218,218,1,215,215,215,1,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,9,219,219,219,1,215,215,215,1,217,217,217,1,218,218,218,1,216, + 216,216,1,217,217,217,1,223,223,223,1,216,216,216,1,218,218,218,1,215, + 215,215,1,221,221,221,1,217,217,217,1,220,220,220,1,218,218,218,1,220, + 220,220,1,217,217,217,2,220,220,220,2,215,215,215,1,218,218,218,1,220, + 220,220,1,216,216,216,1,217,217,217,2,219,219,219,1,220,220,220,1,218, + 218,218,2,216,216,216,1,219,219,219,1,216,216,216,1,218,218,218,16,255, + 255,255,1,248,248,248,1,224,224,224,1,215,215,215,1,219,219,219,1,218, + 218,218,2,216,216,216,1,218,218,218,14,219,219,219,1,216,216,216,1,219, + 219,219,2,217,217,217,1,219,219,219,2,217,217,217,1,215,215,215,1,223, + 223,223,1,216,216,216,2,222,222,222,1,221,221,221,1,253,253,253,1,255, + 255,255,2,215,215,215,1,218,218,218,1,222,222,222,1,217,217,217,1,166, + 166,166,1,170,170,170,1,217,217,217,1,216,216,216,1,219,219,219,1,218, + 218,218,4,217,217,217,1,255,255,255,1,254,254,254,1,255,255,255,2,217, + 217,217,1,218,218,218,1,219,219,219,1,222,222,222,1,219,219,219,1,215, + 215,215,1,219,219,219,1,220,220,220,1,218,218,218,1,214,214,214,1,170, + 170,170,1,167,167,167,1,169,169,169,1,166,166,166,1,220,220,220,1,218, + 218,218,1,220,220,220,1,219,219,219,1,216,216,216,1,217,217,217,1,255, + 255,255,2,173,173,173,1,169,169,169,1,217,217,217,1,219,219,219,1,218, + 218,218,1,220,220,220,1,166,166,166,1,165,165,165,1,217,217,217,1,216, + 216,216,1,221,221,221,1,216,216,216,1,217,217,217,2,219,219,219,1,218, + 218,218,9,219,219,219,1,218,218,218,1,220,220,220,1,221,221,221,1,216, + 216,216,2,219,219,219,1,221,221,221,1,218,218,218,1,217,217,217,3,218, + 218,218,1,216,216,216,1,219,219,219,1,217,217,217,1,219,219,219,2,218, + 218,218,3,219,219,219,1,220,220,220,1,221,221,221,1,216,216,216,3,217, + 217,217,1,224,224,224,1,214,214,214,1,222,222,222,1,218,218,218,16,217, + 217,217,1,222,222,222,1,217,217,217,1,218,218,218,1,221,221,221,1,217, + 217,217,1,219,219,219,2,218,218,218,14,254,254,254,1,220,220,220,1,219, + 219,219,1,218,218,218,1,220,220,220,1,215,215,215,1,214,214,214,1,218, + 218,218,1,219,219,219,1,217,217,217,1,222,222,222,1,217,217,217,1,216, + 216,216,1,214,214,214,1,219,219,219,1,217,217,217,1,220,220,220,1,219, + 219,219,1,217,217,217,1,215,215,215,1,170,170,170,1,168,168,168,1,165, + 165,165,1,219,219,219,3,218,218,218,1,217,217,217,1,218,218,218,1,219, + 219,219,1,253,253,253,1,254,254,254,1,255,255,255,1,251,251,251,1,215, + 215,215,1,222,222,222,1,217,217,217,1,218,218,218,1,215,215,215,1,217, + 217,217,1,221,221,221,1,219,219,219,1,217,217,217,1,218,218,218,1,221, + 221,221,1,215,215,215,1,171,171,171,1,167,167,167,1,219,219,219,1,215, + 215,215,1,218,218,218,1,215,215,215,1,221,221,221,1,218,218,218,1,216, + 216,216,1,255,255,255,1,254,254,254,1,166,166,166,1,215,215,215,1,218, + 218,218,1,168,168,168,1,215,215,215,1,220,220,220,1,219,219,219,1,170, + 170,170,1,218,218,218,1,219,219,219,1,221,221,221,1,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,218,218,218,8,220,220,220,1,215, + 215,215,1,217,217,217,1,219,219,219,1,215,215,215,1,221,221,221,1,217, + 217,217,1,218,218,218,1,216,216,216,1,217,217,217,1,170,170,170,1,218, + 218,218,2,217,217,217,1,218,218,218,1,220,220,220,1,219,219,219,1,217, + 217,217,1,215,215,215,1,221,221,221,1,218,218,218,1,216,216,216,1,221, + 221,221,1,214,214,214,1,215,215,215,1,171,171,171,1,219,219,219,1,168, + 168,168,2,218,218,218,1,214,214,214,1,218,218,218,17,217,217,217,1,221, + 221,221,1,218,218,218,3,216,216,216,1,218,218,218,1,219,219,219,1,218, + 218,218,14,217,217,217,1,219,219,219,1,215,215,215,1,217,217,217,1,218, + 218,218,1,220,220,220,1,219,219,219,1,220,220,220,2,216,216,216,1,215, + 215,215,1,219,219,219,1,220,220,220,1,219,219,219,1,165,165,165,1,220, + 220,220,1,216,216,216,1,220,220,220,1,170,170,170,1,218,218,218,1,221, + 221,221,1,165,165,165,1,171,171,171,1,167,167,167,1,215,215,215,1,217, + 217,217,1,220,220,220,1,217,217,217,1,220,220,220,2,218,218,218,1,219, + 219,219,1,217,217,217,1,221,221,221,1,219,219,219,1,215,215,215,1,218, + 218,218,1,220,220,220,1,218,218,218,1,222,222,222,1,215,215,215,1,217, + 217,217,3,220,220,220,1,215,215,215,1,220,220,220,1,167,167,167,1,218, + 218,218,1,220,220,220,1,218,218,218,1,167,167,167,1,169,169,169,1,215, + 215,215,1,220,220,220,1,255,255,255,1,254,254,254,1,219,219,219,1,173, + 173,173,1,165,165,165,1,171,171,171,1,220,220,220,1,253,253,253,1,216, + 216,216,1,218,218,218,1,215,215,215,1,220,220,220,1,217,217,217,1,218, + 218,218,3,219,219,219,1,218,218,218,8,217,217,217,1,219,219,219,1,217, + 217,217,1,218,218,218,1,219,219,219,1,220,220,220,1,217,217,217,1,218, + 218,218,2,219,219,219,1,217,217,217,1,219,219,219,1,221,221,221,1,215, + 215,215,1,221,221,221,1,215,215,215,1,218,218,218,3,217,217,217,1,219, + 219,219,1,218,218,218,1,217,217,217,1,221,221,221,1,219,219,219,1,166, + 166,166,1,219,219,219,1,216,216,216,1,217,217,217,1,220,220,220,1,217, + 217,217,1,219,219,219,1,218,218,218,18,216,216,216,1,218,218,218,1,220, + 220,220,1,219,219,219,1,218,218,218,1,216,216,216,1,218,218,218,15,217, + 217,217,1,222,222,222,1,218,218,218,1,217,217,217,2,216,216,216,1,217, + 217,217,1,219,219,219,2,217,217,217,1,216,216,216,1,219,219,219,3,167, + 167,167,1,169,169,169,1,165,165,165,1,215,215,215,1,217,217,217,1,219, + 219,219,1,167,167,167,1,171,171,171,1,215,215,215,1,220,220,220,1,222, + 222,222,1,216,216,216,1,215,215,215,1,216,216,216,2,220,220,220,1,215, + 215,215,1,214,214,214,1,218,218,218,1,221,221,221,1,217,217,217,1,222, + 222,222,1,217,217,217,2,216,216,216,1,219,219,219,1,222,222,222,1,169, + 169,169,1,217,217,217,1,218,218,218,1,222,222,222,1,162,162,162,1,169, + 169,169,1,216,216,216,1,219,219,219,1,217,217,217,1,167,167,167,1,217, + 217,217,1,174,174,174,1,164,164,164,1,218,218,218,1,168,168,168,2,212, + 212,212,1,173,173,173,1,164,164,164,1,166,166,166,1,255,255,255,1,219, + 219,219,1,218,218,218,1,222,222,222,1,217,217,217,1,219,219,219,1,217, + 217,217,1,218,218,218,1,217,217,217,1,219,219,219,1,218,218,218,9,217, + 217,217,1,221,221,221,1,220,220,220,1,216,216,216,1,220,220,220,1,216, + 216,216,1,168,168,168,1,253,253,253,1,218,218,218,1,217,217,217,1,218, + 218,218,1,216,216,216,1,220,220,220,2,219,219,219,2,217,217,217,1,221, + 221,221,1,215,215,215,1,220,220,220,1,219,219,219,1,215,215,215,1,254, + 254,254,1,219,219,219,1,254,254,254,2,220,220,220,1,217,217,217,1,168, + 168,168,1,221,221,221,1,217,217,217,1,218,218,218,19,217,217,217,3,220, + 220,220,1,221,221,221,1,218,218,218,16,213,213,213,1,222,222,222,1,218, + 218,218,1,220,220,220,1,222,222,222,1,215,215,215,1,217,217,217,1,219, + 219,219,1,216,216,216,1,221,221,221,1,255,255,255,1,219,219,219,1,216, + 216,216,1,168,168,168,1,219,219,219,1,217,217,217,1,221,221,221,1,254, + 254,254,1,255,255,255,1,217,217,217,1,219,219,219,1,217,217,217,1,216, + 216,216,1,219,219,219,1,217,217,217,1,174,174,174,1,168,168,168,1,169, + 169,169,1,217,217,217,1,219,219,219,1,222,222,222,1,215,215,215,1,220, + 220,220,1,214,214,214,1,217,217,217,1,221,221,221,1,215,215,215,1,219, + 219,219,1,215,215,215,1,254,254,254,2,255,255,255,2,254,254,254,1,220, + 220,220,1,218,218,218,1,220,220,220,1,253,253,253,1,255,255,255,1,220, + 220,220,1,214,214,214,1,168,168,168,2,169,169,169,1,220,220,220,1,216, + 216,216,1,219,219,219,1,218,218,218,1,220,220,220,1,219,219,219,1,216, + 216,216,1,217,217,217,2,218,218,218,1,216,216,216,1,220,220,220,1,217, + 217,217,1,221,221,221,1,220,220,220,1,215,215,215,1,218,218,218,8,221, + 221,221,1,216,216,216,1,215,215,215,1,218,218,218,1,215,215,215,1,219, + 219,219,2,220,220,220,1,171,171,171,1,167,167,167,1,218,218,218,1,219, + 219,219,1,218,218,218,1,220,220,220,1,212,212,212,1,219,219,219,2,216, + 216,216,1,220,220,220,1,217,217,217,1,220,220,220,1,217,217,217,1,219, + 219,219,1,255,255,255,1,218,218,218,1,219,219,219,1,218,218,218,1,220, + 220,220,1,168,168,168,1,165,165,165,1,218,218,218,1,219,219,219,1,218, + 218,218,16,219,219,219,1,217,217,217,1,218,218,218,1,219,219,219,2,220, + 220,220,1,217,217,217,1,214,214,214,1,218,218,218,14,216,216,216,1,221, + 221,221,1,220,220,220,1,215,215,215,1,218,218,218,2,215,215,215,1,220, + 220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,1,215, + 215,215,1,255,255,255,1,220,220,220,1,216,216,216,2,221,221,221,1,218, + 218,218,1,254,254,254,1,255,255,255,1,219,219,219,1,216,216,216,1,220, + 220,220,2,215,215,215,1,170,170,170,1,165,165,165,1,168,168,168,2,218, + 218,218,1,217,217,217,2,219,219,219,1,215,215,215,1,221,221,221,1,218, + 218,218,1,216,216,216,1,220,220,220,1,219,219,219,1,255,255,255,3,254, + 254,254,1,255,255,255,1,253,253,253,1,219,219,219,1,218,218,218,1,217, + 217,217,1,255,255,255,1,165,165,165,1,218,218,218,1,255,255,255,1,215, + 215,215,1,217,217,217,1,218,218,218,1,216,216,216,1,220,220,220,1,255, + 255,255,2,215,215,215,1,217,217,217,1,220,220,220,1,218,218,218,1,217, + 217,217,1,170,170,170,1,216,216,216,1,220,220,220,1,219,219,219,1,215, + 215,215,1,219,219,219,2,218,218,218,8,215,215,215,1,221,221,221,1,219, + 219,219,1,216,216,216,1,221,221,221,1,253,253,253,1,217,217,217,2,216, + 216,216,1,218,218,218,1,221,221,221,1,214,214,214,1,221,221,221,1,217, + 217,217,1,219,219,219,1,220,220,220,1,218,218,218,2,217,217,217,1,218, + 218,218,1,217,217,217,1,218,218,218,1,220,220,220,1,216,216,216,1,219, + 219,219,1,216,216,216,1,218,218,218,1,254,254,254,1,219,219,219,1,220, + 220,220,1,167,167,167,2,218,218,218,17,217,217,217,1,219,219,219,2,216, + 216,216,1,218,218,218,1,219,219,219,2,218,218,218,22,219,219,219,1,218, + 218,218,1,215,215,215,1,221,221,221,1,220,220,220,1,255,255,255,1,254, + 254,254,1,219,219,219,1,218,218,218,1,167,167,167,1,169,169,169,1,251, + 251,251,1,255,255,255,1,218,218,218,2,217,217,217,1,220,220,220,1,255, + 255,255,1,253,253,253,1,220,220,220,1,166,166,166,1,169,169,169,1,221, + 221,221,1,215,215,215,1,220,220,220,1,217,217,217,1,220,220,220,1,215, + 215,215,1,218,218,218,1,217,217,217,1,219,219,219,4,218,218,218,1,216, + 216,216,1,219,219,219,1,217,217,217,2,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,1,254,254,254,1,218,218,218,1,220,220,220,1,218, + 218,218,1,217,217,217,2,219,219,219,1,218,218,218,1,166,166,166,1,170, + 170,170,1,218,218,218,1,217,217,217,1,216,216,216,1,219,219,219,1,218, + 218,218,2,219,219,219,1,216,216,216,1,219,219,219,2,216,216,216,1,218, + 218,218,1,219,219,219,2,215,215,215,1,221,221,221,1,218,218,218,1,216, + 216,216,1,219,219,219,2,218,218,218,1,217,217,217,3,218,218,218,1,255, + 255,255,2,218,218,218,16,219,219,219,1,217,217,217,1,255,255,255,2,217, + 217,217,1,218,218,218,1,167,167,167,1,168,168,168,1,219,219,219,2,218, + 218,218,1,217,217,217,1,218,218,218,1,217,217,217,1,220,220,220,1,217, + 217,217,2,219,219,219,2,218,218,218,1,217,217,217,1,218,218,218,1,215, + 215,215,1,221,221,221,1,217,217,217,1,218,218,218,1,216,216,216,1,221, + 221,221,1,215,215,215,1,218,218,218,1,220,220,220,1,215,215,215,1,217, + 217,217,1,219,219,219,1,218,218,218,1,216,216,216,1,221,221,221,1,216, + 216,216,1,218,218,218,1,216,216,216,1,218,218,218,14,219,219,219,1,217, + 217,217,1,221,221,221,1,216,216,216,1,251,251,251,1,255,255,255,1,254, + 254,254,1,218,218,218,1,221,221,221,1,164,164,164,1,219,219,219,1,255, + 255,255,2,254,254,254,1,253,253,253,1,255,255,255,1,252,252,252,1,255, + 255,255,1,218,218,218,1,253,253,253,1,170,170,170,1,215,215,215,1,217, + 217,217,1,222,222,222,1,215,215,215,1,219,219,219,1,215,215,215,1,218, + 218,218,1,221,221,221,1,220,220,220,1,216,216,216,1,215,215,215,1,218, + 218,218,1,217,217,217,2,219,219,219,3,220,220,220,1,218,218,218,1,253, + 253,253,1,255,255,255,1,219,219,219,1,218,218,218,1,255,255,255,4,219, + 219,219,1,218,218,218,1,219,219,219,1,167,167,167,1,216,216,216,2,220, + 220,220,1,255,255,255,1,217,217,217,2,218,218,218,1,217,217,217,1,221, + 221,221,1,216,216,216,1,217,217,217,1,219,219,219,1,217,217,217,1,215, + 215,215,1,217,217,217,1,222,222,222,1,216,216,216,2,222,222,222,1,218, + 218,218,1,215,215,215,1,219,219,219,2,220,220,220,1,219,219,219,1,220, + 220,220,1,214,214,214,1,219,219,219,1,218,218,218,16,216,216,216,1,219, + 219,219,1,218,218,218,2,255,255,255,2,171,171,171,1,169,169,169,1,215, + 215,215,1,218,218,218,1,219,219,219,1,220,220,220,1,216,216,216,1,223, + 223,223,1,214,214,214,1,219,219,219,1,220,220,220,1,216,216,216,1,219, + 219,219,1,220,220,220,1,217,217,217,1,170,170,170,2,215,215,215,1,217, + 217,217,1,220,220,220,1,218,218,218,2,217,217,217,1,218,218,218,1,219, + 219,219,1,222,222,222,1,220,220,220,1,216,216,216,1,220,220,220,1,219, + 219,219,1,215,215,215,1,217,217,217,1,224,224,224,1,219,219,219,1,218, + 218,218,14,216,216,216,1,219,219,219,1,218,218,218,2,172,172,172,1,216, + 216,216,1,219,219,219,1,217,217,217,1,255,255,255,1,218,218,218,1,219, + 219,219,1,250,250,250,1,255,255,255,2,254,254,254,1,220,220,220,1,218, + 218,218,1,255,255,255,3,217,217,217,1,220,220,220,1,219,219,219,1,215, + 215,215,1,219,219,219,1,218,218,218,1,220,220,220,1,217,217,217,1,215, + 215,215,1,218,218,218,1,217,217,217,1,222,222,222,1,215,215,215,1,221, + 221,221,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,214, + 214,214,1,219,219,219,1,170,170,170,1,166,166,166,1,255,255,255,1,253, + 253,253,1,255,255,255,1,254,254,254,1,253,253,253,1,255,255,255,1,219, + 219,219,1,253,253,253,1,255,255,255,1,218,218,218,1,220,220,220,1,219, + 219,219,1,215,215,215,1,217,217,217,1,169,169,169,1,168,168,168,1,218, + 218,218,1,219,219,219,1,216,216,216,1,220,220,220,1,218,218,218,1,216, + 216,216,1,168,168,168,1,220,220,220,1,219,219,219,1,214,214,214,1,218, + 218,218,3,215,215,215,1,221,221,221,1,215,215,215,1,218,218,218,1,216, + 216,216,1,217,217,217,1,216,216,216,1,222,222,222,1,217,217,217,1,218, + 218,218,16,219,219,219,3,218,218,218,1,255,255,255,2,211,211,211,1,220, + 220,220,1,223,223,223,1,216,216,216,1,167,167,167,1,215,215,215,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,219, + 219,219,1,215,215,215,1,222,222,222,1,166,166,166,1,165,165,165,1,171, + 171,171,1,218,218,218,1,217,217,217,3,218,218,218,1,220,220,220,1,217, + 217,217,2,216,216,216,1,215,215,215,1,219,219,219,1,217,217,217,1,218, + 218,218,3,216,216,216,1,218,218,218,15,219,219,219,1,218,218,218,2,217, + 217,217,1,214,214,214,1,255,255,255,1,218,218,218,1,220,220,220,1,217, + 217,217,1,218,218,218,2,222,222,222,1,217,217,217,1,218,218,218,1,215, + 215,215,1,218,218,218,1,255,255,255,1,215,215,215,1,255,255,255,1,218, + 218,218,1,219,219,219,1,216,216,216,2,220,220,220,1,219,219,219,1,214, + 214,214,1,221,221,221,1,217,217,217,1,218,218,218,1,220,220,220,1,215, + 215,215,1,217,217,217,1,221,221,221,1,217,217,217,1,165,165,165,1,217, + 217,217,1,218,218,218,1,220,220,220,1,222,222,222,1,168,168,168,2,220, + 220,220,1,166,166,166,1,221,221,221,1,215,215,215,1,219,219,219,1,222, + 222,222,1,215,215,215,1,218,218,218,1,251,251,251,1,216,216,216,1,219, + 219,219,1,216,216,216,1,219,219,219,1,217,217,217,1,219,219,219,1,167, + 167,167,1,166,166,166,1,220,220,220,1,219,219,219,1,215,215,215,1,220, + 220,220,1,219,219,219,1,220,220,220,2,215,215,215,1,220,220,220,1,221, + 221,221,1,216,216,216,1,219,219,219,1,217,217,217,1,221,221,221,1,216, + 216,216,1,218,218,218,1,221,221,221,1,219,219,219,1,218,218,218,1,220, + 220,220,1,215,215,215,1,220,220,220,1,218,218,218,16,217,217,217,1,219, + 219,219,1,215,215,215,1,218,218,218,1,255,255,255,1,253,253,253,1,220, + 220,220,1,221,221,221,1,214,214,214,1,217,217,217,1,219,219,219,1,222, + 222,222,1,218,218,218,1,215,215,215,1,222,222,222,1,217,217,217,2,221, + 221,221,1,167,167,167,1,255,255,255,1,254,254,254,1,221,221,221,1,217, + 217,217,1,218,218,218,1,222,222,222,1,215,215,215,1,220,220,220,1,221, + 221,221,1,214,214,214,1,221,221,221,1,219,219,219,1,166,166,166,1,171, + 171,171,1,217,217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,220, + 220,220,1,217,217,217,1,218,218,218,17,253,253,253,1,255,255,255,1,254, + 254,254,1,255,255,255,1,216,216,216,1,217,217,217,1,220,220,220,2,215, + 215,215,2,222,222,222,1,216,216,216,1,220,220,220,1,217,217,217,1,220, + 220,220,1,214,214,214,1,223,223,223,1,214,214,214,1,221,221,221,1,219, + 219,219,4,220,220,220,1,215,215,215,1,219,219,219,1,218,218,218,1,219, + 219,219,1,220,220,220,1,217,217,217,1,218,218,218,1,216,216,216,1,221, + 221,221,1,219,219,219,1,217,217,217,1,220,220,220,1,251,251,251,1,255, + 255,255,1,220,220,220,1,213,213,213,1,220,220,220,1,216,216,216,1,217, + 217,217,1,215,215,215,1,218,218,218,1,220,220,220,1,215,215,215,1,225, + 225,225,1,217,217,217,1,221,221,221,1,217,217,217,1,215,215,215,1,255, + 255,255,1,254,254,254,1,220,220,220,1,219,219,219,1,217,217,217,1,215, + 215,215,1,218,218,218,1,170,170,170,1,253,253,253,1,219,219,219,1,217, + 217,217,1,221,221,221,1,216,216,216,2,221,221,221,1,218,218,218,2,215, + 215,215,1,219,219,219,1,218,218,218,1,216,216,216,1,218,218,218,2,214, + 214,214,1,221,221,221,1,215,215,215,1,218,218,218,16,217,217,217,1,216, + 216,216,1,222,222,222,1,218,218,218,1,217,217,217,1,218,218,218,1,220, + 220,220,1,214,214,214,1,255,255,255,1,216,216,216,1,218,218,218,1,217, + 217,217,1,218,218,218,1,216,216,216,1,167,167,167,1,216,216,216,1,221, + 221,221,1,216,216,216,1,255,255,255,1,253,253,253,1,255,255,255,1,218, + 218,218,1,216,216,216,1,220,220,220,1,215,215,215,1,219,219,219,1,216, + 216,216,1,219,219,219,1,218,218,218,1,217,217,217,2,169,169,169,1,165, + 165,165,1,218,218,218,2,220,220,220,1,217,217,217,2,221,221,221,1,219, + 219,219,1,218,218,218,16,220,220,220,1,219,219,219,1,255,255,255,1,251, + 251,251,1,218,218,218,1,220,220,220,1,216,216,216,1,219,219,219,2,217, + 217,217,1,218,218,218,1,217,217,217,2,218,218,218,2,220,220,220,1,217, + 217,217,1,218,218,218,1,217,217,217,1,216,216,216,1,218,218,218,1,217, + 217,217,1,215,215,215,1,220,220,220,1,219,219,219,1,214,214,214,1,221, + 221,221,1,218,218,218,1,164,164,164,1,170,170,170,1,255,255,255,1,218, + 218,218,1,219,219,219,1,218,218,218,1,216,216,216,1,252,252,252,1,255, + 255,255,2,253,253,253,1,222,222,222,1,218,218,218,2,221,221,221,1,219, + 219,219,1,217,217,217,2,220,220,220,1,213,213,213,1,219,219,219,1,215, + 215,215,1,221,221,221,1,217,217,217,1,253,253,253,1,254,254,254,1,217, + 217,217,1,219,219,219,1,216,216,216,1,225,225,225,1,218,218,218,1,217, + 217,217,2,218,218,218,1,219,219,219,1,218,218,218,1,169,169,169,1,166, + 166,166,1,217,217,217,1,219,219,219,1,216,216,216,1,222,222,222,1,167, + 167,167,1,168,168,168,1,218,218,218,1,220,220,220,1,219,219,219,1,217, + 217,217,1,222,222,222,1,218,218,218,17,220,220,220,1,219,219,219,1,215, + 215,215,1,216,216,216,1,219,219,219,1,216,216,216,1,220,220,220,1,219, + 219,219,1,215,215,215,1,222,222,222,1,216,216,216,1,218,218,218,1,220, + 220,220,1,218,218,218,1,172,172,172,1,168,168,168,1,254,254,254,1,218, + 218,218,1,217,217,217,1,223,223,223,1,214,214,214,1,219,219,219,1,218, + 218,218,1,216,216,216,1,219,219,219,1,220,220,220,1,218,218,218,1,217, + 217,217,1,219,219,219,1,254,254,254,1,255,255,255,1,166,166,166,1,170, + 170,170,1,221,221,221,1,216,216,216,1,218,218,218,1,220,220,220,1,216, + 216,216,1,217,217,217,1,218,218,218,15,219,219,219,1,216,216,216,1,219, + 219,219,1,220,220,220,1,214,214,214,1,221,221,221,1,219,219,219,1,215, + 215,215,2,221,221,221,1,216,216,216,1,219,219,219,1,218,218,218,1,222, + 222,222,1,216,216,216,1,219,219,219,2,215,215,215,1,222,222,222,1,219, + 219,219,1,217,217,217,1,223,223,223,1,219,219,219,1,215,215,215,1,218, + 218,218,2,216,216,216,1,220,220,220,1,216,216,216,1,217,217,217,1,220, + 220,220,1,217,217,217,1,219,219,219,1,216,216,216,1,218,218,218,1,220, + 220,220,1,217,217,217,1,221,221,221,1,218,218,218,1,217,217,217,1,218, + 218,218,1,216,216,216,1,220,220,220,1,219,219,219,1,216,216,216,1,217, + 217,217,1,219,219,219,1,218,218,218,1,217,217,217,1,219,219,219,1,221, + 221,221,1,216,216,216,1,217,217,217,1,220,220,220,1,219,219,219,1,218, + 218,218,1,219,219,219,2,216,216,216,1,250,250,250,1,217,217,217,1,221, + 221,221,1,216,216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,2,219,219,219,1,218,218,218,1,217,217,217,1,218,218,218,1,220, + 220,220,1,219,219,219,1,216,216,216,2,217,217,217,1,219,219,219,1,214, + 214,214,1,216,216,216,1,218,218,218,16,215,215,215,1,220,220,220,2,219, + 219,219,1,221,221,221,1,214,214,214,1,219,219,219,1,216,216,216,1,221, + 221,221,1,166,166,166,1,218,218,218,1,217,217,217,1,254,254,254,1,217, + 217,217,1,166,166,166,1,168,168,168,1,218,218,218,2,220,220,220,1,213, + 213,213,1,219,219,219,1,220,220,220,1,219,219,219,1,218,218,218,1,216, + 216,216,1,217,217,217,1,218,218,218,1,219,219,219,1,220,220,220,1,255, + 255,255,1,250,250,250,1,172,172,172,1,166,166,166,1,217,217,217,1,221, + 221,221,1,216,216,216,1,219,219,219,1,220,220,220,1,218,218,218,16,219, + 219,219,3,215,215,215,1,220,220,220,2,213,213,213,1,221,221,221,1,219, + 219,219,1,215,215,215,1,220,220,220,1,217,217,217,2,216,216,216,1,218, + 218,218,2,219,219,219,1,218,218,218,2,216,216,216,1,218,218,218,1,215, + 215,215,1,219,219,219,3,217,217,217,1,220,220,220,1,215,215,215,1,255, + 255,255,1,252,252,252,1,220,220,220,1,217,217,217,2,221,221,221,1,217, + 217,217,1,218,218,218,1,219,219,219,1,216,216,216,1,219,219,219,1,217, + 217,217,1,220,220,220,1,216,216,216,1,217,217,217,1,218,218,218,1,219, + 219,219,2,217,217,217,1,219,219,219,2,215,215,215,1,219,219,219,1,220, + 220,220,1,217,217,217,2,219,219,219,1,217,217,217,2,168,168,168,1,170, + 170,170,1,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,218, + 218,218,1,253,253,253,1,255,255,255,1,216,216,216,1,219,219,219,2,217, + 217,217,1,254,254,254,1,255,255,255,1,217,217,217,1,218,218,218,2,219, + 219,219,2,216,216,216,1,221,221,221,1,218,218,218,17,221,221,221,1,214, + 214,214,1,220,220,220,1,217,217,217,2,220,220,220,1,217,217,217,1,169, + 169,169,1,168,168,168,1,169,169,169,1,168,168,168,2,218,218,218,1,220, + 220,220,1,167,167,167,1,219,219,219,1,220,220,220,1,165,165,165,1,219, + 219,219,1,220,220,220,1,219,219,219,1,216,216,216,2,169,169,169,1,219, + 219,219,1,218,218,218,2,216,216,216,1,218,218,218,1,253,253,253,1,255, + 255,255,1,216,216,216,1,218,218,218,1,220,220,220,1,216,216,216,1,219, + 219,219,1,217,217,217,1,218,218,218,2,219,219,219,1,218,218,218,16,216, + 216,216,1,219,219,219,1,220,220,220,1,217,217,217,2,219,219,219,1,220, + 220,220,1,216,216,216,1,217,217,217,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,216,216,216,1,218,218,218,33,217,217,217,1,220, + 220,220,1,216,216,216,1,218,218,218,1,221,221,221,1,216,216,216,1,220, + 220,220,1,221,221,221,1,216,216,216,1,217,217,217,1,219,219,219,1,217, + 217,217,1,220,220,220,1,216,216,216,1,218,218,218,1,219,219,219,1,218, + 218,218,1,216,216,216,1,219,219,219,2,216,216,216,1,220,220,220,1,218, + 218,218,1,219,219,219,1,216,216,216,1,219,219,219,2,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,219,219,219,1,169,169,169,1,217, + 217,217,2,219,219,219,1,218,218,218,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,217,217,217,1,218,218,218,2,215,215,215,1,222, + 222,222,1,216,216,216,1,217,217,217,1,221,221,221,1,216,216,216,1,220, + 220,220,1,217,217,217,2,218,218,218,1,255,255,255,1,168,168,168,2,166, + 166,166,1,171,171,171,1,218,218,218,2,167,167,167,1,218,218,218,1,221, + 221,221,1,214,214,214,1,220,220,220,2,215,215,215,1,219,219,219,1,217, + 217,217,1,219,219,219,2,217,217,217,1,219,219,219,1,168,168,168,1,219, + 219,219,1,252,252,252,1,255,255,255,1,218,218,218,2,169,169,169,1,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,2,218,218,218,16,220, + 220,220,1,219,219,219,1,217,217,217,1,216,216,216,2,218,218,218,1,217, + 217,217,1,216,216,216,1,221,221,221,1,219,219,219,1,215,215,215,1,219, + 219,219,1,216,216,216,1,217,217,217,1,220,220,220,1,218,218,218,32,219, + 219,219,1,216,216,216,1,218,218,218,1,219,219,219,1,222,222,222,1,215, + 215,215,1,220,220,220,1,254,254,254,1,252,252,252,1,222,222,222,1,218, + 218,218,2,217,217,217,1,218,218,218,1,221,221,221,1,216,216,216,1,220, + 220,220,1,217,217,217,1,219,219,219,1,217,217,217,1,167,167,167,1,170, + 170,170,1,217,217,217,1,219,219,219,1,217,217,217,1,219,219,219,2,215, + 215,215,1,217,217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,215, + 215,215,1,218,218,218,1,219,219,219,1,221,221,221,1,218,218,218,1,216, + 216,216,1,217,217,217,3,220,220,220,1,218,218,218,2,216,216,216,1,220, + 220,220,1,215,215,215,1,169,169,169,1,218,218,218,2,217,217,217,1,214, + 214,214,1,223,223,223,1,254,254,254,1,255,255,255,1,217,217,217,1,219, + 219,219,1,220,220,220,2,215,215,215,1,217,217,217,1,170,170,170,1,168, + 168,168,1,255,255,255,1,168,168,168,1,217,217,217,1,216,216,216,1,217, + 217,217,1,219,219,219,1,254,254,254,1,221,221,221,1,216,216,216,1,219, + 219,219,2,215,215,215,1,218,218,218,1,219,219,219,1,218,218,218,3,217, + 217,217,1,167,167,167,1,217,217,217,1,216,216,216,1,219,219,219,1,216, + 216,216,1,219,219,219,1,218,218,218,15,217,217,217,2,218,218,218,1,219, + 219,219,2,221,221,221,2,218,218,218,2,216,216,216,2,217,217,217,1,222, + 222,222,1,218,218,218,1,216,216,216,1,219,219,219,1,218,218,218,34,220, + 220,220,1,215,215,215,1,216,216,216,1,218,218,218,1,215,215,215,1,220, + 220,220,2,215,215,215,1,220,220,220,1,218,218,218,1,219,219,219,1,214, + 214,214,1,221,221,221,1,169,169,169,1,165,165,165,1,218,218,218,1,170, + 170,170,1,168,168,168,1,220,220,220,1,167,167,167,1,216,216,216,1,217, + 217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,221,221,221,1,218, + 218,218,1,210,210,210,1,222,222,222,1,255,255,255,1,222,222,222,1,218, + 218,218,1,216,216,216,1,217,217,217,1,221,221,221,1,215,215,215,1,222, + 222,222,1,218,218,218,1,171,171,171,1,165,165,165,1,220,220,220,1,215, + 215,215,1,220,220,220,1,218,218,218,1,168,168,168,1,169,169,169,1,170, + 170,170,1,217,217,217,1,216,216,216,1,220,220,220,1,216,216,216,1,218, + 218,218,1,255,255,255,2,217,217,217,1,218,218,218,1,216,216,216,1,219, + 219,219,2,170,170,170,1,214,214,214,1,170,170,170,1,166,166,166,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,220,220,220,1,216, + 216,216,1,218,218,218,2,255,255,255,1,219,219,219,1,217,217,217,1,216, + 216,216,1,219,219,219,1,220,220,220,1,254,254,254,1,220,220,220,1,170, + 170,170,1,217,217,217,1,222,222,222,1,219,219,219,2,217,217,217,1,218, + 218,218,15,220,220,220,1,216,216,216,1,218,218,218,2,217,217,217,1,218, + 218,218,1,217,217,217,2,218,218,218,2,221,221,221,1,220,220,220,1,214, + 214,214,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,32,217, + 217,217,1,216,216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,222, + 222,222,1,220,220,220,1,216,216,216,1,217,217,217,1,220,220,220,1,216, + 216,216,2,221,221,221,1,217,217,217,1,218,218,218,1,216,216,216,1,171, + 171,171,1,219,219,219,1,252,252,252,1,222,222,222,1,215,215,215,1,218, + 218,218,1,219,219,219,1,220,220,220,1,216,216,216,1,221,221,221,1,220, + 220,220,1,215,215,215,1,219,219,219,1,222,222,222,1,216,216,216,1,215, + 215,215,1,216,216,216,2,222,222,222,1,217,217,217,1,216,216,216,1,169, + 169,169,1,167,167,167,1,168,168,168,1,165,165,165,1,169,169,169,1,167, + 167,167,1,219,219,219,1,218,218,218,1,255,255,255,1,165,165,165,1,168, + 168,168,1,164,164,164,1,168,168,168,1,171,171,171,1,221,221,221,1,215, + 215,215,1,255,255,255,2,254,254,254,1,253,253,253,1,255,255,255,1,220, + 220,220,1,214,214,214,1,221,221,221,1,167,167,167,1,220,220,220,1,165, + 165,165,1,170,170,170,1,218,218,218,1,215,215,215,1,217,217,217,1,218, + 218,218,1,165,165,165,1,219,219,219,1,220,220,220,1,167,167,167,1,168, + 168,168,1,218,218,218,1,219,219,219,2,221,221,221,1,215,215,215,1,254, + 254,254,1,214,214,214,1,219,219,219,1,218,218,218,1,215,215,215,1,217, + 217,217,1,219,219,219,1,221,221,221,1,217,217,217,1,218,218,218,14,219, + 219,219,1,217,217,217,1,220,220,220,1,217,217,217,1,215,215,215,1,218, + 218,218,2,220,220,220,1,219,219,219,1,216,216,216,1,215,215,215,1,219, + 219,219,1,216,216,216,1,221,221,221,1,217,217,217,1,222,222,222,1,218, + 218,218,33,220,220,220,1,218,218,218,1,216,216,216,1,219,219,219,1,216, + 216,216,1,212,212,212,1,218,218,218,1,216,216,216,1,219,219,219,2,217, + 217,217,1,218,218,218,1,254,254,254,1,255,255,255,1,221,221,221,1,253, + 253,253,1,255,255,255,1,217,217,217,1,252,252,252,1,219,219,219,1,221, + 221,221,1,217,217,217,1,216,216,216,1,219,219,219,1,216,216,216,1,218, + 218,218,1,219,219,219,1,217,217,217,2,218,218,218,1,222,222,222,1,219, + 219,219,1,218,218,218,1,220,220,220,1,215,215,215,1,220,220,220,1,168, + 168,168,1,217,217,217,2,167,167,167,1,169,169,169,1,170,170,170,1,216, + 216,216,1,254,254,254,1,255,255,255,1,219,219,219,1,167,167,167,1,171, + 171,171,1,170,170,170,1,216,216,216,1,165,165,165,1,223,223,223,1,217, + 217,217,1,254,254,254,1,255,255,255,2,253,253,253,1,218,218,218,1,221, + 221,221,1,166,166,166,1,215,215,215,1,225,225,225,1,168,168,168,2,166, + 166,166,1,169,169,169,1,171,171,171,1,169,169,169,3,217,217,217,1,170, + 170,170,1,166,166,166,1,168,168,168,1,220,220,220,1,218,218,218,1,216, + 216,216,1,218,218,218,1,255,255,255,1,220,220,220,1,217,217,217,1,218, + 218,218,1,221,221,221,1,215,215,215,1,217,217,217,1,216,216,216,1,221, + 221,221,1,218,218,218,14,216,216,216,1,218,218,218,1,220,220,220,1,217, + 217,217,1,219,219,219,1,223,223,223,1,216,216,216,2,217,217,217,1,165, + 165,165,1,173,173,173,1,217,217,217,1,218,218,218,1,219,219,219,1,217, + 217,217,1,214,214,214,1,218,218,218,32,217,217,217,1,218,218,218,1,217, + 217,217,2,220,220,220,1,222,222,222,1,220,220,220,1,217,217,217,1,220, + 220,220,1,218,218,218,2,217,217,217,1,216,216,216,1,218,218,218,1,255, + 255,255,1,215,215,215,1,220,220,220,1,255,255,255,1,218,218,218,1,220, + 220,220,1,218,218,218,2,216,216,216,1,221,221,221,1,220,220,220,1,215, + 215,215,1,218,218,218,1,219,219,219,1,216,216,216,1,217,217,217,3,219, + 219,219,1,216,216,216,1,219,219,219,1,255,255,255,1,254,254,254,1,253, + 253,253,1,218,218,218,1,219,219,219,1,221,221,221,1,166,166,166,1,167, + 167,167,1,220,220,220,1,254,254,254,1,252,252,252,1,219,219,219,1,218, + 218,218,1,217,217,217,1,164,164,164,1,170,170,170,1,169,169,169,1,216, + 216,216,1,219,219,219,1,217,217,217,1,219,219,219,1,255,255,255,2,216, + 216,216,1,217,217,217,1,218,218,218,1,221,221,221,1,213,213,213,1,167, + 167,167,1,168,168,168,1,169,169,169,1,164,164,164,1,219,219,219,1,167, + 167,167,1,165,165,165,1,253,253,253,1,255,255,255,1,167,167,167,1,171, + 171,171,1,217,217,217,1,215,215,215,1,219,219,219,1,169,169,169,1,167, + 167,167,1,215,215,215,1,218,218,218,1,222,222,222,1,215,215,215,2,222, + 222,222,1,219,219,219,1,218,218,218,1,216,216,216,1,218,218,218,16,219, + 219,219,1,216,216,216,1,219,219,219,1,218,218,218,1,212,212,212,1,221, + 221,221,1,220,220,220,1,215,215,215,1,220,220,220,1,217,217,217,2,221, + 221,221,1,218,218,218,34,221,221,221,1,216,216,216,1,218,218,218,1,221, + 221,221,1,213,213,213,2,219,219,219,2,215,215,215,1,167,167,167,1,222, + 222,222,1,217,217,217,1,220,220,220,1,217,217,217,2,219,219,219,1,215, + 215,215,1,218,218,218,2,216,216,216,2,220,220,220,1,216,216,216,1,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,1,219, + 219,219,1,216,216,216,1,255,255,255,1,250,250,250,1,255,255,255,1,253, + 253,253,1,255,255,255,2,215,215,215,1,218,218,218,1,217,217,217,1,255, + 255,255,2,220,220,220,1,216,216,216,1,170,170,170,1,219,219,219,1,168, + 168,168,1,165,165,165,1,169,169,169,1,218,218,218,1,216,216,216,1,218, + 218,218,1,252,252,252,1,255,255,255,2,220,220,220,1,218,218,218,1,214, + 214,214,1,221,221,221,2,216,216,216,1,220,220,220,2,216,216,216,1,219, + 219,219,1,220,220,220,1,255,255,255,1,253,253,253,1,217,217,217,1,215, + 215,215,1,220,220,220,1,218,218,218,1,219,219,219,1,216,216,216,1,222, + 222,222,1,219,219,219,1,218,218,218,1,217,217,217,1,220,220,220,1,218, + 218,218,2,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,14,219, + 219,219,1,217,217,217,1,219,219,219,1,218,218,218,2,215,215,215,1,222, + 222,222,1,254,254,254,1,255,255,255,1,219,219,219,1,217,217,217,1,218, + 218,218,1,220,220,220,1,216,216,216,1,219,219,219,2,218,218,218,32,216, + 216,216,1,219,219,219,1,218,218,218,2,219,219,219,3,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,218,218,218,1,220, + 220,220,1,217,217,217,1,219,219,219,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,218,218,218,2,217,217,217,1,219,219,219,1,215, + 215,215,1,220,220,220,1,219,219,219,1,215,215,215,1,219,219,219,2,214, + 214,214,1,218,218,218,1,216,216,216,1,220,220,220,1,218,218,218,1,216, + 216,216,1,255,255,255,2,254,254,254,1,255,255,255,1,254,254,254,1,220, + 220,220,1,219,219,219,1,168,168,168,1,219,219,219,1,215,215,215,1,219, + 219,219,2,215,215,215,1,221,221,221,1,168,168,168,1,169,169,169,1,168, + 168,168,1,217,217,217,1,220,220,220,1,219,219,219,1,255,255,255,1,254, + 254,254,1,255,255,255,2,218,218,218,3,216,216,216,1,218,218,218,3,217, + 217,217,1,169,169,169,1,217,217,217,1,255,255,255,2,218,218,218,1,171, + 171,171,1,217,217,217,1,253,253,253,1,255,255,255,1,219,219,219,1,216, + 216,216,1,168,168,168,2,218,218,218,1,220,220,220,1,219,219,219,1,217, + 217,217,1,218,218,218,1,219,219,219,1,218,218,218,63,219,219,219,1,217, + 217,217,1,219,219,219,1,218,218,218,2,215,215,215,1,222,222,222,1,254, + 254,254,1,218,218,218,8,219,219,219,1,214,214,214,1,220,220,220,1,217, + 217,217,1,218,218,218,1,215,215,215,1,221,221,221,1,218,218,218,1,168, + 168,168,2,216,216,216,1,218,218,218,1,217,217,217,1,221,221,221,1,217, + 217,217,1,166,166,166,1,220,220,220,1,217,217,217,1,219,219,219,1,215, + 215,215,1,221,221,221,1,217,217,217,1,215,215,215,1,220,220,220,2,218, + 218,218,2,166,166,166,1,219,219,219,1,218,218,218,2,219,219,219,1,218, + 218,218,2,219,219,219,1,170,170,170,1,165,165,165,1,218,218,218,4,253, + 253,253,1,255,255,255,3,218,218,218,1,219,219,219,1,217,217,217,1,219, + 219,219,1,218,218,218,2,167,167,167,1,218,218,218,1,216,216,216,1,255, + 255,255,1,218,218,218,1,167,167,167,1,169,169,169,1,170,170,170,1,166, + 166,166,1,168,168,168,1,170,170,170,1,165,165,165,1,169,169,169,1,167, + 167,167,1,169,169,169,1,217,217,217,1,216,216,216,1,217,217,217,1,219, + 219,219,2,217,217,217,1,218,218,218,64,219,219,219,1,216,216,216,1,219, + 219,219,1,218,218,218,1,212,212,212,1,221,221,221,1,218,218,218,8,216, + 216,216,1,221,221,221,1,217,217,217,1,220,220,220,1,217,217,217,1,221, + 221,221,1,216,216,216,1,217,217,217,1,169,169,169,2,219,219,219,1,216, + 216,216,1,167,167,167,1,166,166,166,2,172,172,172,1,214,214,214,1,219, + 219,219,1,221,221,221,1,216,216,216,1,215,215,215,1,222,222,222,1,219, + 219,219,1,217,217,217,2,254,254,254,1,255,255,255,1,254,254,254,1,217, + 217,217,1,218,218,218,1,217,217,217,1,216,216,216,1,255,255,255,1,253, + 253,253,1,217,217,217,1,167,167,167,1,169,169,169,1,173,173,173,1,164, + 164,164,1,217,217,217,1,219,219,219,1,217,217,217,1,255,255,255,3,218, + 218,218,1,214,214,214,1,219,219,219,1,218,218,218,3,165,165,165,1,224, + 224,224,1,216,216,216,1,215,215,215,1,219,219,219,1,169,169,169,1,166, + 166,166,1,170,170,170,1,168,168,168,1,166,166,166,1,219,219,219,2,170, + 170,170,1,171,171,171,1,161,161,161,1,169,169,169,1,223,223,223,1,217, + 217,217,2,219,219,219,1,218,218,218,63,216,216,216,1,218,218,218,1,220, + 220,220,1,217,217,217,1,219,219,219,1,223,223,223,1,216,216,216,2,218, + 218,218,8,219,219,219,1,216,216,216,1,218,218,218,1,216,216,216,1,215, + 215,215,1,219,219,219,1,255,255,255,2,217,217,217,1,219,219,219,1,216, + 216,216,1,219,219,219,1,168,168,168,1,219,219,219,1,166,166,166,2,221, + 221,221,1,219,219,219,1,218,218,218,1,221,221,221,1,220,220,220,1,214, + 214,214,1,220,220,220,1,217,217,217,1,166,166,166,1,255,255,255,1,254, + 254,254,1,255,255,255,1,220,220,220,1,218,218,218,1,254,254,254,1,255, + 255,255,1,254,254,254,1,255,255,255,2,165,165,165,1,168,168,168,1,169, + 169,169,2,221,221,221,1,218,218,218,2,219,219,219,1,254,254,254,1,253, + 253,253,1,255,255,255,1,221,221,221,1,217,217,217,1,215,215,215,1,220, + 220,220,1,168,168,168,1,170,170,170,1,165,165,165,1,219,219,219,1,218, + 218,218,1,216,216,216,1,218,218,218,1,217,217,217,3,220,220,220,1,217, + 217,217,1,221,221,221,1,214,214,214,1,165,165,165,1,222,222,222,1,167, + 167,167,1,218,218,218,1,217,217,217,1,215,215,215,1,221,221,221,1,216, + 216,216,1,218,218,218,62,219,219,219,1,217,217,217,1,220,220,220,1,217, + 217,217,1,215,215,215,1,218,218,218,2,220,220,220,1,218,218,218,8,216, + 216,216,1,219,219,219,1,218,218,218,1,222,222,222,1,219,219,219,1,218, + 218,218,1,255,255,255,2,217,217,217,2,255,255,255,2,218,218,218,1,220, + 220,220,1,168,168,168,2,214,214,214,1,220,220,220,1,216,216,216,1,215, + 215,215,1,217,217,217,1,221,221,221,1,217,217,217,1,220,220,220,1,168, + 168,168,1,220,220,220,1,254,254,254,2,217,217,217,2,219,219,219,1,218, + 218,218,1,255,255,255,1,252,252,252,2,222,222,222,1,220,220,220,1,167, + 167,167,1,168,168,168,1,215,215,215,1,216,216,216,1,220,220,220,1,216, + 216,216,1,255,255,255,3,211,211,211,1,222,222,222,1,221,221,221,1,215, + 215,215,1,169,169,169,1,165,165,165,1,168,168,168,1,220,220,220,1,217, + 217,217,1,220,220,220,1,218,218,218,2,223,223,223,1,217,217,217,1,215, + 215,215,1,218,218,218,1,217,217,217,1,221,221,221,1,217,217,217,1,220, + 220,220,1,214,214,214,1,170,170,170,1,220,220,220,1,219,219,219,2,217, + 217,217,1,218,218,218,62,220,220,220,1,216,216,216,1,218,218,218,2,217, + 217,217,1,218,218,218,1,217,217,217,2,218,218,218,8,222,222,222,1,215, + 215,215,1,216,216,216,1,219,219,219,1,215,215,215,1,220,220,220,1,215, + 215,215,1,170,170,170,1,169,169,169,1,168,168,168,1,254,254,254,1,255, + 255,255,2,216,216,216,1,168,168,168,1,169,169,169,1,219,219,219,1,217, + 217,217,1,222,222,222,1,220,220,220,2,217,217,217,1,255,255,255,1,217, + 217,217,1,220,220,220,1,216,216,216,1,255,255,255,2,169,169,169,1,172, + 172,172,1,166,166,166,1,217,217,217,2,255,255,255,1,219,219,219,1,218, + 218,218,1,213,213,213,1,171,171,171,1,169,169,169,1,220,220,220,1,221, + 221,221,1,219,219,219,1,217,217,217,1,168,168,168,1,219,219,219,1,255, + 255,255,1,220,220,220,1,216,216,216,2,217,217,217,1,224,224,224,1,167, + 167,167,1,219,219,219,1,217,217,217,1,220,220,220,1,214,214,214,1,217, + 217,217,1,218,218,218,1,215,215,215,1,218,218,218,1,221,221,221,2,214, + 214,214,1,171,171,171,1,255,255,255,1,218,218,218,1,220,220,220,1,164, + 164,164,1,217,217,217,1,219,219,219,1,216,216,216,1,218,218,218,63,217, + 217,217,2,218,218,218,1,219,219,219,2,221,221,221,2,218,218,218,9,217, + 217,217,2,222,222,222,1,216,216,216,1,217,217,217,1,220,220,220,1,217, + 217,217,1,219,219,219,1,169,169,169,1,166,166,166,1,255,255,255,2,251, + 251,251,1,219,219,219,1,170,170,170,1,164,164,164,1,219,219,219,1,217, + 217,217,1,216,216,216,1,219,219,219,1,215,215,215,1,169,169,169,1,220, + 220,220,1,218,218,218,1,216,216,216,1,222,222,222,1,254,254,254,1,255, + 255,255,1,163,163,163,1,168,168,168,1,169,169,169,1,218,218,218,2,255, + 255,255,1,217,217,217,2,220,220,220,1,168,168,168,1,166,166,166,1,168, + 168,168,1,165,165,165,1,215,215,215,1,220,220,220,1,218,218,218,1,252, + 252,252,1,253,253,253,1,220,220,220,1,217,217,217,1,219,219,219,2,213, + 213,213,1,219,219,219,2,217,217,217,1,218,218,218,1,220,220,220,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,1,220,220,220,1,165,165,165,1,216,216,216,1,255,255,255,1,218, + 218,218,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,64,220,220,220,1,219,219,219,1,217,217,217,1,216,216,216,2,218, + 218,218,1,217,217,217,1,218,218,218,8,217,217,217,1,219,219,219,1,215, + 215,215,1,219,219,219,1,222,222,222,1,254,254,254,1,253,253,253,1,217, + 217,217,1,166,166,166,1,172,172,172,1,164,164,164,1,218,218,218,1,255, + 255,255,1,253,253,253,1,171,171,171,1,217,217,217,1,215,215,215,1,218, + 218,218,1,217,217,217,1,223,223,223,1,217,217,217,1,216,216,216,1,219, + 219,219,1,218,218,218,3,255,255,255,1,214,214,214,1,220,220,220,1,170, + 170,170,1,164,164,164,1,170,170,170,1,219,219,219,1,213,213,213,1,221, + 221,221,1,218,218,218,1,219,219,219,1,170,170,170,1,167,167,167,1,168, + 168,168,1,169,169,169,1,255,255,255,2,169,169,169,1,214,214,214,1,223, + 223,223,1,215,215,215,1,220,220,220,2,217,217,217,1,218,218,218,1,221, + 221,221,1,218,218,218,1,217,217,217,1,219,219,219,1,216,216,216,1,218, + 218,218,2,219,219,219,1,217,217,217,1,216,216,216,1,220,220,220,1,166, + 166,166,1,171,171,171,1,169,169,169,1,253,253,253,1,219,219,219,1,216, + 216,216,1,167,167,167,1,220,220,220,1,218,218,218,1,216,216,216,1,218, + 218,218,64,216,216,216,1,219,219,219,1,220,220,220,1,217,217,217,2,219, + 219,219,1,218,218,218,8,219,219,219,2,218,218,218,1,219,219,219,1,216, + 216,216,1,218,218,218,1,255,255,255,1,217,217,217,1,220,220,220,1,166, + 166,166,1,169,169,169,1,255,255,255,3,214,214,214,1,170,170,170,1,220, + 220,220,1,218,218,218,1,217,217,217,1,251,251,251,1,255,255,255,1,217, + 217,217,1,219,219,219,1,218,218,218,3,253,253,253,1,255,255,255,1,254, + 254,254,1,166,166,166,1,172,172,172,1,167,167,167,1,217,217,217,1,222, + 222,222,1,216,216,216,1,217,217,217,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,216,216,216,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,216,216,216,1,219,219,219,1,217,217,217,1,216, + 216,216,1,219,219,219,1,217,217,217,1,215,215,215,1,219,219,219,1,216, + 216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,220,220,220,1,215, + 215,215,1,221,221,221,1,218,218,218,1,217,217,217,1,170,170,170,1,168, + 168,168,2,219,219,219,1,216,216,216,1,221,221,221,1,215,215,215,1,171, + 171,171,1,215,215,215,1,220,220,220,1,218,218,218,70,220,220,220,1,215, + 215,215,1,218,218,218,1,221,221,221,1,218,218,218,2,219,219,219,1,217, + 217,217,2,220,220,220,1,217,217,217,1,221,221,221,1,218,218,218,1,254, + 254,254,1,217,217,217,1,255,255,255,2,220,220,220,1,168,168,168,1,166, + 166,166,1,255,255,255,1,219,219,219,1,167,167,167,1,169,169,169,1,170, + 170,170,1,168,168,168,1,219,219,219,1,216,216,216,1,218,218,218,1,217, + 217,217,1,220,220,220,1,217,217,217,1,216,216,216,1,255,255,255,4,218, + 218,218,1,217,217,217,1,220,220,220,1,219,219,219,1,220,220,220,1,218, + 218,218,1,215,215,215,1,218,218,218,1,217,217,217,1,255,255,255,1,218, + 218,218,1,217,217,217,1,255,255,255,1,254,254,254,1,217,217,217,1,216, + 216,216,1,218,218,218,1,219,219,219,1,218,218,218,14,220,220,220,1,255, + 255,255,1,216,216,216,1,221,221,221,1,217,217,217,1,255,255,255,1,218, + 218,218,1,219,219,219,1,218,218,218,1,167,167,167,1,219,219,219,1,218, + 218,218,70,217,217,217,1,223,223,223,1,216,216,216,1,218,218,218,1,216, + 216,216,1,166,166,166,1,170,170,170,1,219,219,219,1,220,220,220,1,216, + 216,216,1,217,217,217,3,255,255,255,1,169,169,169,1,253,253,253,1,254, + 254,254,1,170,170,170,1,167,167,167,1,173,173,173,1,218,218,218,1,253, + 253,253,1,221,221,221,1,166,166,166,1,165,165,165,1,168,168,168,1,215, + 215,215,1,217,217,217,1,221,221,221,1,217,217,217,1,214,214,214,1,219, + 219,219,1,217,217,217,1,224,224,224,1,217,217,217,1,254,254,254,1,255, + 255,255,1,218,218,218,2,216,216,216,1,219,219,219,1,214,214,214,1,255, + 255,255,3,219,219,219,1,215,215,215,1,216,216,216,1,219,219,219,1,215, + 215,215,1,218,218,218,1,222,222,222,1,218,218,218,1,219,219,219,2,215, + 215,215,1,218,218,218,8,219,219,219,1,220,220,220,1,217,217,217,1,219, + 219,219,1,218,218,218,1,255,255,255,2,222,222,222,1,217,217,217,1,218, + 218,218,1,219,219,219,1,255,255,255,1,219,219,219,1,217,217,217,1,219, + 219,219,1,216,216,216,1,218,218,218,70,216,216,216,1,218,218,218,3,219, + 219,219,1,218,218,218,1,169,169,169,1,167,167,167,1,166,166,166,1,221, + 221,221,1,219,219,219,1,218,218,218,1,255,255,255,1,218,218,218,1,165, + 165,165,1,255,255,255,2,216,216,216,1,167,167,167,1,168,168,168,1,216, + 216,216,1,255,255,255,1,253,253,253,1,255,255,255,1,169,169,169,1,168, + 168,168,1,221,221,221,1,223,223,223,1,218,218,218,1,215,215,215,1,219, + 219,219,1,218,218,218,1,219,219,219,1,215,215,215,1,218,218,218,2,254, + 254,254,2,218,218,218,1,220,220,220,1,219,219,219,1,217,217,217,1,255, + 255,255,1,254,254,254,1,216,216,216,1,221,221,221,1,220,220,220,1,219, + 219,219,1,217,217,217,1,255,255,255,1,220,220,220,1,215,215,215,1,218, + 218,218,1,214,214,214,1,219,219,219,2,218,218,218,8,217,217,217,1,219, + 219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,217,217,217,1,220, + 220,220,1,215,215,215,1,217,217,217,1,220,220,220,1,217,217,217,1,216, + 216,216,1,254,254,254,1,218,218,218,1,221,221,221,1,218,218,218,71,220, + 220,220,1,216,216,216,1,217,217,217,1,254,254,254,1,255,255,255,1,220, + 220,220,1,216,216,216,1,217,217,217,1,220,220,220,1,216,216,216,1,217, + 217,217,1,218,218,218,1,254,254,254,1,220,220,220,1,218,218,218,1,254, + 254,254,1,252,252,252,1,218,218,218,1,170,170,170,1,165,165,165,1,170, + 170,170,1,255,255,255,1,254,254,254,2,167,167,167,1,220,220,220,1,214, + 214,214,1,215,215,215,1,217,217,217,1,219,219,219,1,169,169,169,1,218, + 218,218,1,217,217,217,1,219,219,219,2,255,255,255,1,253,253,253,1,221, + 221,221,1,218,218,218,1,216,216,216,1,166,166,166,1,170,170,170,1,216, + 216,216,1,218,218,218,1,219,219,219,1,215,215,215,1,217,217,217,2,255, + 255,255,2,217,217,217,1,220,220,220,1,218,218,218,1,219,219,219,1,220, + 220,220,1,216,216,216,1,218,218,218,9,220,220,220,1,218,218,218,1,221, + 221,221,1,218,218,218,1,221,221,221,1,215,215,215,1,221,221,221,1,219, + 219,219,2,216,216,216,1,221,221,221,2,218,218,218,2,215,215,215,1,218, + 218,218,70,217,217,217,1,218,218,218,1,220,220,220,1,169,169,169,1,255, + 255,255,1,252,252,252,1,255,255,255,1,220,220,220,1,217,217,217,2,218, + 218,218,1,222,222,222,1,254,254,254,1,166,166,166,1,172,172,172,1,255, + 255,255,2,219,219,219,1,218,218,218,1,169,169,169,1,167,167,167,2,255, + 255,255,1,217,217,217,1,166,166,166,1,171,171,171,1,218,218,218,1,220, + 220,220,1,221,221,221,1,217,217,217,1,218,218,218,1,217,217,217,1,218, + 218,218,1,255,255,255,1,218,218,218,1,216,216,216,1,255,255,255,1,215, + 215,215,1,214,214,214,1,223,223,223,1,168,168,168,1,169,169,169,1,216, + 216,216,1,169,169,169,1,218,218,218,1,217,217,217,1,218,218,218,1,219, + 219,219,1,254,254,254,1,255,255,255,1,221,221,221,1,216,216,216,2,219, + 219,219,2,217,217,217,1,218,218,218,8,221,221,221,1,215,215,215,1,168, + 168,168,1,215,215,215,1,169,169,169,1,220,220,220,1,215,215,215,1,218, + 218,218,1,216,216,216,1,220,220,220,1,219,219,219,1,217,217,217,1,213, + 213,213,1,217,217,217,1,219,219,219,2,218,218,218,70,217,217,217,1,221, + 221,221,1,216,216,216,1,167,167,167,1,218,218,218,1,220,220,220,1,214, + 214,214,1,217,217,217,1,221,221,221,1,219,219,219,1,217,217,217,1,216, + 216,216,1,217,217,217,1,169,169,169,1,163,163,163,1,255,255,255,1,252, + 252,252,1,219,219,219,1,214,214,214,1,170,170,170,1,168,168,168,1,165, + 165,165,1,254,254,254,1,173,173,173,1,169,169,169,2,220,220,220,1,215, + 215,215,1,252,252,252,1,219,219,219,1,218,218,218,2,219,219,219,1,218, + 218,218,1,216,216,216,1,255,255,255,2,218,218,218,1,223,223,223,1,215, + 215,215,1,168,168,168,1,166,166,166,1,219,219,219,1,170,170,170,1,218, + 218,218,1,219,219,219,2,216,216,216,1,254,254,254,1,255,255,255,1,217, + 217,217,1,219,219,219,1,222,222,222,1,215,215,215,1,219,219,219,1,217, + 217,217,1,218,218,218,8,217,217,217,1,169,169,169,2,216,216,216,1,168, + 168,168,1,216,216,216,1,219,219,219,1,220,220,220,1,219,219,219,1,215, + 215,215,1,220,220,220,1,214,214,214,1,220,220,220,1,222,222,222,1,216, + 216,216,1,219,219,219,1,218,218,218,6,29,99,111,110,116,97,105,110,101, + 114,46,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110, + 116,2,2,29,99,111,110,116,97,105,110,101,114,46,102,97,99,101,46,102, + 97,100,101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,31, + 99,111,110,116,97,105,110,101,114,46,102,97,99,101,46,102,97,100,101,95, + 99,111,108,111,114,46,99,111,117,110,116,2,2,31,99,111,110,116,97,105, + 110,101,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46, + 105,116,101,109,115,1,4,218,226,237,0,4,191,174,181,0,0,25,99,111, + 110,116,97,105,110,101,114,46,102,97,99,101,46,108,111,99,97,108,112,114, + 111,112,115,11,13,102,97,108,95,102,97,111,112,97,99,105,116,121,0,18, + 99,111,110,116,97,105,110,101,114,46,116,97,98,111,114,100,101,114,2,1, + 16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0, + 2,30,3,126,2,3,0,1,0,13,111,112,116,105,111,110,115,119,105,110, + 100,111,119,11,14,119,111,95,103,114,111,117,112,108,101,97,100,101,114,0, + 8,109,97,105,110,109,101,110,117,7,9,109,97,105,110,109,101,110,117,49, + 7,111,112,116,105,111,110,115,11,7,102,111,95,109,97,105,110,19,102,111, + 95,116,101,114,109,105,110,97,116,101,111,110,99,108,111,115,101,15,102,111, + 95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116, + 111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111, + 115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116, + 102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112, + 116,105,111,110,6,15,77,83,69,105,100,101,32,43,32,77,83,69,103,117, + 105,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116, + 109,115,101,102,111,114,109,0,11,116,115,116,114,105,110,103,101,100,105,116, + 12,116,115,116,114,105,110,103,101,100,105,116,49,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,105,2,1,16, + 102,114,97,109,101,46,102,114,97,109,101,119,105,100,116,104,2,2,16,102, + 114,97,109,101,46,99,111,108,111,114,102,114,97,109,101,4,3,0,0,128, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3, + 0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,16,67, + 97,112,116,105,111,110,32,38,116,111,112,108,101,102,116,16,102,114,97,109, + 101,46,102,111,110,116,46,99,111,108,111,114,3,99,115,15,102,114,97,109, + 101,46,102,111,110,116,46,110,97,109,101,6,11,115,116,102,95,100,101,102, + 97,117,108,116,17,102,114,97,109,101,46,102,111,110,116,46,120,115,99,97, + 108,101,2,1,21,102,114,97,109,101,46,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111,114,10,102,108, + 112,95,120,115,99,97,108,101,0,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,105,14,102, + 114,108,95,102,114,97,109,101,119,105,100,116,104,14,102,114,108,95,99,111, + 108,111,114,102,114,97,109,101,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110,100,115,95, + 120,2,107,8,98,111,117,110,100,115,95,121,2,39,9,98,111,117,110,100, + 115,95,99,121,2,43,8,115,116,97,116,102,105,108,101,7,10,116,115,116, + 97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,12,116,115, + 116,114,105,110,103,101,100,105,116,50,5,99,111,108,111,114,4,3,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,105,2,1,16,102,114,97, + 109,101,46,102,114,97,109,101,119,105,100,116,104,2,2,16,102,114,97,109, + 101,46,99,111,108,111,114,102,114,97,109,101,4,3,0,0,128,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,67,97,112,116, + 105,111,110,32,38,116,111,112,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46, + 102,111,110,116,46,99,111,108,111,114,4,121,145,0,0,16,102,114,97,109, + 101,46,102,111,110,116,46,115,116,121,108,101,11,7,102,115,95,98,111,108, + 100,0,15,102,114,97,109,101,46,102,111,110,116,46,110,97,109,101,6,11, + 115,116,102,95,100,101,102,97,117,108,116,17,102,114,97,109,101,46,102,111, + 110,116,46,120,115,99,97,108,101,2,1,21,102,114,97,109,101,46,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99, + 111,108,111,114,9,102,108,112,95,115,116,121,108,101,10,102,108,112,95,120, + 115,99,97,108,101,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,105,14,102,114,108,95, + 102,114,97,109,101,119,105,100,116,104,14,102,114,108,95,99,111,108,111,114, + 102,114,97,109,101,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,19,102,97,99,101,46,102,97,100,101,95, + 112,111,115,46,99,111,117,110,116,2,2,19,102,97,99,101,46,102,97,100, + 101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,21,102,97, + 99,101,46,102,97,100,101,95,99,111,108,111,114,46,99,111,117,110,116,2, + 2,21,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116, + 101,109,115,1,4,217,224,188,0,4,255,161,161,0,0,17,102,97,99,101, + 46,102,97,100,101,95,111,112,97,99,105,116,121,4,95,95,95,0,15,102, + 97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,13,102,97,108,95, + 102,97,111,112,97,99,105,116,121,0,8,116,97,98,111,114,100,101,114,2, + 1,8,98,111,117,110,100,115,95,120,3,6,1,8,98,111,117,110,100,115, + 95,121,2,39,9,98,111,117,110,100,115,95,99,121,2,43,8,115,116,97, + 116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,12,116,115,116,114,105,110,103,101,100,105,116,51, + 5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,3,12,102,114,97,109,101,46,108,101,118,101,108,105,2, + 255,16,102,114,97,109,101,46,102,114,97,109,101,119,105,100,116,104,2,2, + 16,102,114,97,109,101,46,99,111,108,111,114,102,114,97,109,101,4,3,0, + 0,128,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 13,67,97,112,116,105,111,110,32,38,108,101,102,116,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,7,99,112,95,108,101,102,116, + 16,102,114,97,109,101,46,102,111,110,116,46,99,111,108,111,114,4,6,0, + 0,160,16,102,114,97,109,101,46,102,111,110,116,46,115,116,121,108,101,11, + 7,102,115,95,98,111,108,100,9,102,115,95,105,116,97,108,105,99,0,15, + 102,114,97,109,101,46,102,111,110,116,46,110,97,109,101,6,11,115,116,102, + 95,100,101,102,97,117,108,116,17,102,114,97,109,101,46,102,111,110,116,46, + 120,115,99,97,108,101,2,1,21,102,114,97,109,101,46,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111, + 114,9,102,108,112,95,115,116,121,108,101,10,102,108,112,95,120,115,99,97, + 108,101,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118, + 101,108,105,14,102,114,108,95,102,114,97,109,101,119,105,100,116,104,14,102, + 114,108,95,99,111,108,111,114,102,114,97,109,101,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,81,2,0,2,0,2,0,0,19,102,97, + 99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,19, + 102,97,99,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1, + 2,0,2,1,0,21,102,97,99,101,46,102,97,100,101,95,99,111,108,111, + 114,46,99,111,117,110,116,2,2,21,102,97,99,101,46,102,97,100,101,95, + 99,111,108,111,114,46,105,116,101,109,115,1,4,6,0,0,160,4,5,0, + 0,160,0,19,102,97,99,101,46,102,97,100,101,95,100,105,114,101,99,116, + 105,111,110,7,5,103,100,95,117,112,17,102,97,99,101,46,102,97,100,101, + 95,111,112,97,99,105,116,121,4,127,127,127,0,15,102,97,99,101,46,108, + 111,99,97,108,112,114,111,112,115,11,15,102,97,108,95,102,97,100,105,114, + 101,99,116,105,111,110,13,102,97,108,95,102,97,111,112,97,99,105,116,121, + 0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95, + 120,2,23,8,98,111,117,110,100,115,95,121,2,112,9,98,111,117,110,100, + 115,95,99,120,3,181,0,9,98,111,117,110,100,115,95,99,121,2,32,8, + 115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116, + 115,116,114,105,110,103,101,100,105,116,12,116,115,116,114,105,110,103,101,100, + 105,116,52,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,21,102,114,97,109,101,46,102,114,97,109, + 101,105,109,97,103,101,95,108,105,115,116,7,4,105,109,108,105,23,102,114, + 97,109,101,46,102,114,97,109,101,105,109,97,103,101,95,111,102,102,115,101, + 116,2,24,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,15,67,97,112,116,105,111,110,32,38,98,111,116,116,111,109,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,9,99,112,95,98, + 111,116,116,111,109,16,102,114,97,109,101,46,102,111,110,116,46,99,111,108, + 111,114,4,87,131,189,0,15,102,114,97,109,101,46,102,111,110,116,46,110, + 97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,17,102,114,97, + 109,101,46,102,111,110,116,46,120,115,99,97,108,101,2,1,21,102,114,97, + 109,101,46,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,9, + 102,108,112,95,99,111,108,111,114,10,102,108,112,95,120,115,99,97,108,101, + 0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108, + 105,14,102,114,108,95,102,114,97,109,101,119,105,100,116,104,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,105,115,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,17,0, + 8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120, + 3,5,1,8,98,111,117,110,100,115,95,121,3,177,0,9,98,111,117,110, + 100,115,95,99,121,2,49,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,12,116, + 115,116,114,105,110,103,101,100,105,116,53,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,3,12,102,114, + 97,109,101,46,108,101,118,101,108,105,2,255,16,102,114,97,109,101,46,102, + 114,97,109,101,119,105,100,116,104,2,2,16,102,114,97,109,101,46,99,111, + 108,111,114,102,114,97,109,101,4,3,0,0,128,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,20,67,97,112,116,105,111,110,32, + 98,111,116,116,111,38,109,114,105,103,104,116,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,14,99,112,95,98,111,116,116,111,109, + 114,105,103,104,116,16,102,114,97,109,101,46,102,111,110,116,46,99,111,108, + 111,114,4,101,114,135,0,26,102,114,97,109,101,46,102,111,110,116,46,99, + 111,108,111,114,98,97,99,107,103,114,111,117,110,100,4,240,192,204,0,15, + 102,114,97,109,101,46,102,111,110,116,46,110,97,109,101,6,11,115,116,102, + 95,100,101,102,97,117,108,116,17,102,114,97,109,101,46,102,111,110,116,46, + 120,115,99,97,108,101,2,1,21,102,114,97,109,101,46,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111, + 114,19,102,108,112,95,99,111,108,111,114,98,97,99,107,103,114,111,117,110, + 100,10,102,108,112,95,120,115,99,97,108,101,0,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,10,102,114,108,95,108,101,118,101,108,105,14,102,114,108,95,102,114, + 97,109,101,119,105,100,116,104,14,102,114,108,95,99,111,108,111,114,102,114, + 97,109,101,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,28, + 2,0,2,0,2,17,0,8,116,97,98,111,114,100,101,114,2,5,8,98, + 111,117,110,100,115,95,120,2,76,8,98,111,117,110,100,115,95,121,3,176, + 0,9,98,111,117,110,100,115,95,99,120,3,128,0,9,98,111,117,110,100, + 115,95,99,121,2,49,8,115,116,97,116,102,105,108,101,7,10,116,115,116, + 97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,12,116,115, + 116,114,105,110,103,101,100,105,116,54,5,99,111,108,111,114,4,3,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,21,102,114,97, + 109,101,46,102,114,97,109,101,105,109,97,103,101,95,108,105,115,116,7,4, + 105,109,108,105,23,102,114,97,109,101,46,102,114,97,109,101,105,109,97,103, + 101,95,111,102,102,115,101,116,2,8,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,3,0,0,128,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,14,67,97,112,116,105,111,110,32,38,114,105, + 103,104,116,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,102,111,110, + 116,46,99,111,108,111,114,4,184,134,173,0,16,102,114,97,109,101,46,102, + 111,110,116,46,115,116,121,108,101,11,9,102,115,95,105,116,97,108,105,99, + 0,15,102,114,97,109,101,46,102,111,110,116,46,110,97,109,101,6,11,115, + 116,102,95,100,101,102,97,117,108,116,17,102,114,97,109,101,46,102,111,110, + 116,46,120,115,99,97,108,101,2,1,21,102,114,97,109,101,46,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111, + 108,111,114,9,102,108,112,95,115,116,121,108,101,10,102,108,112,95,120,115, + 99,97,108,101,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108, + 101,118,101,108,105,14,102,114,108,95,102,114,97,109,101,119,105,100,116,104, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,105,115,116,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 84,2,0,0,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99, + 111,117,110,116,2,2,19,102,97,99,101,46,102,97,100,101,95,112,111,115, + 46,105,116,101,109,115,1,2,0,2,1,0,21,102,97,99,101,46,102,97, + 100,101,95,99,111,108,111,114,46,99,111,117,110,116,2,2,21,102,97,99, + 101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1,4, + 6,0,0,160,4,5,0,0,160,0,19,102,97,99,101,46,102,97,100,101, + 95,100,105,114,101,99,116,105,111,110,7,5,103,100,95,117,112,17,102,97, + 99,101,46,102,97,100,101,95,111,112,97,99,105,116,121,4,127,127,127,0, + 15,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,97, + 108,95,102,97,100,105,114,101,99,116,105,111,110,13,102,97,108,95,102,97, + 111,112,97,99,105,116,121,0,8,116,97,98,111,114,100,101,114,2,4,8, + 98,111,117,110,100,115,95,120,3,5,1,8,98,111,117,110,100,115,95,121, + 2,113,9,98,111,117,110,100,115,95,99,120,3,184,0,9,98,111,117,110, + 100,115,95,99,121,2,32,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,12,116, + 115,116,114,105,110,103,101,100,105,116,55,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,12,102,114, + 97,109,101,46,108,101,118,101,108,105,2,1,16,102,114,97,109,101,46,102, + 114,97,109,101,119,105,100,116,104,2,2,16,102,114,97,109,101,46,99,111, + 108,111,114,102,114,97,109,101,4,3,0,0,128,17,102,114,97,109,101,46, + 102,114,97,109,101,105,95,108,101,102,116,2,4,18,102,114,97,109,101,46, + 102,114,97,109,101,105,95,114,105,103,104,116,2,4,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,14,102,114, + 108,95,102,114,97,109,101,119,105,100,116,104,14,102,114,108,95,99,111,108, + 111,114,102,114,97,109,101,10,102,114,108,95,102,105,108,101,102,116,11,102, + 114,108,95,102,105,114,105,103,104,116,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,12,102,97,99,101,46,111,112,116,105,111,110,115, + 11,18,102,97,111,95,97,108,112,104,97,102,97,100,101,105,109,97,103,101, + 0,27,102,97,99,101,46,105,109,97,103,101,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,18,102,97,99,101,46, + 105,109,97,103,101,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,0,20,102,97,99,101,46,105,109,97,103,101,46,97,108, + 105,103,110,109,101,110,116,11,12,97,108,95,120,99,101,110,116,101,114,101, + 100,12,97,108,95,121,99,101,110,116,101,114,101,100,8,97,108,95,116,105, + 108,101,100,0,16,102,97,99,101,46,105,109,97,103,101,46,105,109,97,103, + 101,10,16,95,0,0,0,0,0,0,2,0,0,0,100,0,0,0,100,0, + 0,0,156,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,170,213, + 186,1,207,237,201,1,212,237,217,1,219,251,232,1,243,254,244,31,99,173, + 140,1,99,127,96,1,207,237,201,1,63,106,73,1,54,147,99,1,8,116, + 66,1,87,160,116,1,190,225,195,1,230,237,219,1,188,183,164,1,156,146, + 116,1,131,118,84,1,122,109,68,2,114,102,60,3,122,109,68,2,114,102, + 60,1,122,109,68,1,114,102,60,3,122,109,68,1,114,102,60,1,124,114, + 76,2,136,125,88,1,148,139,109,1,161,152,125,1,164,158,132,1,131,118, + 84,1,64,96,66,1,243,254,244,7,190,225,195,1,169,195,161,1,124,114, + 76,1,41,57,22,1,62,76,54,1,81,88,63,1,88,88,52,1,68,77, + 40,1,45,62,27,1,142,147,115,1,180,218,196,1,243,254,244,11,210,250, + 218,1,207,237,201,1,56,84,51,2,21,58,27,1,68,136,108,1,122,198, + 164,1,190,246,220,1,243,254,244,2,182,245,228,1,243,254,244,26,190,246, + 220,1,64,96,66,1,120,168,132,1,149,209,171,1,51,128,85,1,37,124, + 76,1,91,164,127,1,193,220,204,1,225,228,214,1,183,176,156,1,144,134, + 100,1,122,109,68,1,114,102,60,13,122,109,68,1,124,114,76,1,136,125, + 88,1,148,139,109,1,164,158,132,1,183,176,156,1,169,167,132,1,80,102, + 76,1,126,170,142,1,243,254,244,5,182,245,228,1,99,173,140,1,21,58, + 27,1,95,117,76,1,131,177,148,1,179,236,213,1,219,251,232,1,188,234, + 204,1,190,246,220,1,220,254,244,1,191,216,185,1,120,149,116,1,48,75, + 52,1,100,150,112,1,182,245,228,1,243,254,244,4,182,245,228,1,243,254, + 244,1,179,236,213,1,146,194,165,1,99,127,96,1,31,64,36,1,21,58, + 27,1,190,246,220,1,186,254,239,1,176,226,194,1,120,176,139,1,86,108, + 84,1,41,57,22,1,120,168,132,1,188,234,204,1,243,254,244,28,176,226, + 194,1,21,58,27,1,169,195,161,1,170,213,186,1,120,168,132,1,150,185, + 158,1,199,228,209,1,220,226,195,1,172,174,138,1,136,130,100,1,122,109, + 68,1,107,96,52,6,114,102,60,6,122,109,68,1,124,114,76,1,136,125, + 88,1,148,139,109,1,169,167,132,1,188,183,164,2,142,147,115,1,45,62, + 27,1,179,236,213,1,243,254,244,4,176,226,194,1,64,96,66,1,86,108, + 84,1,154,213,186,1,148,230,196,1,30,143,118,1,15,130,100,1,30,172, + 142,1,39,186,167,1,30,172,142,1,8,140,93,1,24,129,86,1,149,209, + 171,1,188,234,204,1,99,127,96,1,86,108,84,1,190,246,220,1,243,254, + 244,4,166,203,172,1,46,73,42,1,80,97,65,1,120,149,116,1,169,195, + 161,1,176,226,194,1,38,162,142,1,36,151,114,1,28,122,100,1,68,136, + 108,1,157,204,180,1,188,234,204,1,68,136,108,1,31,64,36,1,123,183, + 147,1,182,245,228,1,243,254,244,25,182,245,228,1,243,254,244,1,154,213, + 186,1,46,73,42,1,150,185,158,1,240,251,235,1,199,228,209,1,240,251, + 235,1,204,203,188,1,161,152,125,1,131,118,84,1,107,96,52,1,101,87, + 41,5,107,96,52,4,114,102,60,2,122,109,68,1,124,114,76,1,136,125, + 88,1,144,134,100,1,169,167,132,1,183,176,156,1,201,197,180,1,183,176, + 156,1,114,102,60,1,124,160,128,1,243,254,244,3,182,245,228,1,170,213, + 186,1,21,58,27,1,121,151,126,1,210,250,218,1,34,129,116,1,88,188, + 156,1,82,225,224,1,44,202,180,1,10,202,202,1,13,215,208,1,40,226, + 207,1,64,238,200,1,43,202,153,1,37,124,76,1,126,170,142,1,240,251, + 235,1,99,127,96,2,190,246,220,2,243,254,244,1,150,185,158,1,45,62, + 27,1,142,147,115,1,207,237,201,1,170,213,186,1,124,160,128,1,51,128, + 85,1,43,238,223,1,18,226,208,1,44,212,209,1,76,214,220,2,34,129, + 116,1,88,188,156,1,179,236,213,1,68,115,88,1,80,102,76,1,176,226, + 194,1,243,254,244,27,154,213,186,1,41,57,22,1,142,147,115,1,198,204, + 170,1,213,211,195,1,175,166,143,1,144,134,100,1,114,102,60,1,87,78, + 36,2,88,75,26,2,101,87,41,4,107,96,52,2,114,102,60,1,122,109, + 68,1,124,114,76,1,131,118,84,1,148,139,109,1,164,158,132,1,188,183, + 164,1,201,197,180,1,196,191,171,1,144,134,100,1,21,58,27,1,188,250, + 211,1,243,254,244,3,154,213,186,1,41,57,22,1,131,177,148,1,124,214, + 180,1,20,136,116,1,76,214,220,1,12,177,207,1,4,159,196,1,4,168, + 195,1,7,191,203,1,10,202,202,1,29,237,208,1,40,236,193,1,18,195, + 149,1,8,140,93,1,72,138,92,1,180,218,196,1,168,197,172,1,68,77, + 40,1,133,183,157,1,210,250,218,1,166,203,172,1,41,57,22,1,120,139, + 109,1,232,248,219,1,146,192,155,1,51,128,85,1,11,150,100,1,43,202, + 153,1,41,247,222,1,13,215,208,1,7,191,203,1,9,176,194,1,4,168, + 195,1,12,177,207,1,82,225,224,1,34,129,116,1,140,202,184,1,133,183, + 157,1,46,73,42,1,133,183,157,1,243,254,244,27,176,226,194,1,80,102, + 76,1,62,86,60,1,136,125,88,2,114,102,60,1,88,75,26,1,69,65, + 21,1,65,60,12,1,69,65,21,3,88,75,26,2,101,87,41,2,107,96, + 52,1,114,102,60,2,136,125,88,1,144,134,100,1,164,158,132,1,183,176, + 156,1,198,204,170,1,196,191,171,1,142,147,115,1,46,73,42,1,154,213, + 186,1,243,254,244,2,182,245,228,1,188,234,204,1,46,73,42,1,120,168, + 132,1,152,201,171,1,38,162,142,1,44,212,209,1,4,168,195,1,4,159, + 196,1,12,177,207,2,28,216,220,1,43,238,223,1,36,225,183,1,16,181, + 140,1,8,140,93,1,24,129,86,1,99,173,140,1,199,228,209,1,198,204, + 170,1,122,109,68,1,56,84,51,1,124,160,128,1,95,117,76,1,88,88, + 52,1,171,176,148,1,240,251,235,1,123,183,147,1,24,129,86,1,6,151, + 109,1,43,202,153,1,26,216,182,1,41,247,222,1,13,215,208,1,12,177, + 207,1,4,159,196,1,4,141,191,2,44,170,204,1,76,214,220,1,34,129, + 116,1,186,254,239,1,80,102,76,1,104,150,124,1,190,246,220,1,243,254, + 244,27,152,201,171,1,68,115,88,1,31,64,36,1,41,57,22,1,68,77, + 40,1,84,84,41,1,80,97,65,1,101,87,41,1,65,60,12,2,69,65, + 21,1,88,75,26,2,101,87,41,1,107,96,52,1,114,102,60,1,124,114, + 76,1,144,134,100,1,161,152,125,1,183,176,156,1,196,191,171,1,188,183, + 164,1,161,152,125,1,68,77,40,1,150,185,158,1,243,254,244,4,124,160, + 128,1,87,116,86,1,188,250,211,1,20,136,116,1,76,214,220,1,4,168, + 195,2,12,177,207,1,17,203,215,1,36,228,222,1,18,226,208,1,22,199, + 164,1,9,160,109,1,8,116,66,1,54,147,99,1,120,176,139,1,193,220, + 204,1,232,248,219,1,171,176,148,1,122,109,68,1,69,65,21,1,88,75, + 26,1,69,65,21,1,107,96,52,1,175,166,143,1,240,251,235,1,149,209, + 171,1,70,152,110,1,8,116,66,1,34,164,113,1,9,160,109,1,20,203, + 154,1,43,238,223,1,28,216,220,1,19,189,215,1,7,151,199,1,4,141, + 191,1,4,130,188,1,4,154,180,1,56,206,220,1,34,129,116,1,179,236, + 213,1,68,136,108,1,99,127,96,1,182,245,228,1,243,254,244,27,188,250, + 211,1,188,234,204,1,149,209,171,1,166,203,172,1,146,192,155,1,120,168, + 132,1,120,149,116,1,106,138,100,1,107,96,52,1,69,65,21,1,65,60, + 12,1,69,65,21,1,101,87,41,2,122,109,68,1,136,125,88,1,156,146, + 116,1,172,174,138,1,188,183,164,1,171,176,148,1,148,139,109,1,46,73, + 42,1,123,183,147,1,243,254,244,4,179,236,213,1,21,58,27,1,191,216, + 185,1,15,130,100,1,72,237,212,1,7,191,203,1,9,176,194,1,19,189, + 215,1,28,216,220,1,43,238,223,1,21,213,172,1,11,177,130,1,8,140, + 93,1,11,125,74,1,73,159,115,1,146,194,165,1,188,234,204,1,240,251, + 235,1,201,197,180,1,148,139,109,1,114,102,60,1,88,75,26,1,65,60, + 12,1,88,75,26,1,114,102,60,1,161,152,125,1,213,211,195,1,219,251, + 232,1,146,194,165,1,73,159,115,1,8,116,66,1,11,125,74,1,8,140, + 93,1,18,189,146,1,43,227,196,1,36,228,222,1,17,203,215,1,12,177, + 207,1,7,151,199,1,4,141,191,2,52,194,212,1,38,162,142,1,148,214, + 196,1,72,138,92,1,102,139,110,1,243,254,244,1,182,245,228,1,243,254, + 244,30,188,250,211,1,148,230,196,1,152,201,171,1,126,170,142,1,99,127, + 96,1,107,96,52,1,65,60,12,1,69,65,21,1,101,87,41,1,122,109, + 68,1,136,130,100,1,156,146,116,1,169,167,132,1,156,146,116,1,124,114, + 76,1,41,57,22,1,152,201,171,1,243,254,244,5,123,183,147,1,87,116, + 86,1,176,226,194,1,30,172,142,1,40,226,207,1,10,202,202,1,13,215, + 208,1,43,238,223,1,18,226,208,1,18,189,146,1,6,151,109,1,8,116, + 66,1,54,147,99,1,99,173,140,1,149,209,171,1,212,237,217,1,225,239, + 228,1,204,203,188,1,175,166,143,1,136,125,88,1,114,102,60,1,87,78, + 36,1,88,75,26,1,101,87,41,1,122,109,68,1,148,139,109,1,188,183, + 164,1,230,237,219,1,212,237,217,1,146,194,165,1,100,150,112,1,95,171, + 130,1,12,136,83,1,11,125,74,1,11,177,130,1,21,213,172,1,43,238, + 223,1,28,216,220,1,19,189,215,1,4,168,195,1,4,154,180,1,4,168, + 195,1,36,203,201,1,38,162,142,1,156,237,201,1,95,117,76,1,123,183, + 147,1,243,254,244,34,156,237,201,1,152,201,171,1,120,168,132,1,95,117, + 76,1,41,57,22,1,68,77,40,1,107,96,52,1,124,114,76,1,87,116, + 86,1,86,108,72,1,46,73,42,1,99,127,96,1,188,234,204,1,243,254, + 244,4,190,246,220,1,243,254,244,1,68,115,88,1,126,170,142,1,99,173, + 140,1,43,204,168,1,29,237,208,1,18,226,208,1,43,238,223,1,21,213, + 172,1,10,166,125,1,12,136,83,2,73,159,115,1,128,191,155,1,170,213, + 186,1,225,239,228,1,237,240,229,1,204,203,188,1,171,176,148,1,148,139, + 109,1,131,118,84,1,107,96,52,2,87,78,36,1,107,96,52,1,114,102, + 60,1,144,134,100,1,169,167,132,1,213,211,195,1,240,251,235,1,199,228, + 209,1,146,194,165,1,152,201,171,1,95,171,130,1,34,137,95,1,8,116, + 66,1,9,160,109,1,18,189,146,1,16,214,196,1,41,247,222,1,28,216, + 220,1,17,203,215,1,7,191,203,2,72,237,212,1,18,115,76,1,186,254, + 239,1,31,64,36,1,179,236,213,1,243,254,244,36,176,226,194,1,126,170, + 142,1,95,117,76,1,46,73,42,1,31,64,36,1,56,84,51,1,104,150, + 124,1,154,213,186,1,243,254,244,7,190,246,220,1,31,64,36,1,166,203, + 172,1,60,141,100,1,43,204,168,1,43,249,210,1,36,225,183,1,18,195, + 149,1,6,151,109,1,11,125,74,1,54,147,99,1,95,171,130,1,157,204, + 180,1,199,228,209,1,219,251,232,1,237,240,229,1,204,203,188,1,183,176, + 156,1,140,152,126,1,136,130,100,1,122,109,68,1,114,102,60,1,107,96, + 52,3,122,109,68,1,136,125,88,1,164,158,132,1,188,183,164,1,219,218, + 206,1,243,254,244,1,225,228,214,1,199,228,209,1,157,204,180,1,99,173, + 140,1,70,152,110,1,11,125,74,1,17,121,86,1,9,160,109,1,18,189, + 146,1,26,216,182,1,43,238,223,1,36,228,222,1,18,226,208,1,46,237, + 209,1,40,196,164,1,99,173,140,1,126,170,142,1,104,150,124,1,243,254, + 244,1,182,245,228,1,243,254,244,37,188,250,211,2,210,250,218,1,243,254, + 244,9,190,246,220,1,21,58,27,1,191,216,185,1,60,141,100,1,36,181, + 146,1,18,189,146,1,16,169,116,1,11,125,74,1,24,129,86,1,91,164, + 127,1,133,183,157,1,180,218,196,1,212,237,217,1,243,254,244,1,219,218, + 206,1,201,197,180,1,183,176,156,1,161,152,125,1,144,134,100,1,131,118, + 84,1,122,109,68,1,114,102,60,4,124,114,76,1,136,125,88,1,148,139, + 109,1,175,166,143,1,201,197,180,1,225,228,214,1,243,254,244,2,212,237, + 217,1,177,204,185,1,146,194,165,1,91,164,127,1,54,147,99,1,11,125, + 74,1,8,116,66,1,9,160,109,1,11,177,130,1,20,203,154,1,36,225, + 183,1,43,227,196,1,46,211,164,1,18,115,76,1,210,250,218,1,31,64, + 36,1,188,250,211,1,243,254,244,50,188,250,211,1,46,73,42,1,168,197, + 172,1,91,164,127,1,37,124,76,1,12,136,83,1,11,125,74,1,70,152, + 110,1,123,183,147,1,170,213,186,1,212,237,217,1,243,254,244,1,230,237, + 219,1,213,211,195,1,194,186,172,1,175,166,143,1,161,152,125,1,144,134, + 100,1,136,125,88,1,131,118,84,1,122,109,68,2,114,102,60,1,122,109, + 68,2,131,118,84,1,136,125,88,1,144,134,100,1,164,158,132,1,171,176, + 148,1,204,203,188,1,225,228,214,1,219,218,206,1,240,251,235,2,193,220, + 204,1,170,213,186,1,128,191,155,1,95,171,130,1,70,152,110,1,24,129, + 86,1,11,125,74,1,17,121,86,1,11,150,100,1,9,160,109,1,36,151, + 114,1,18,115,76,1,207,237,201,1,64,96,66,1,176,226,194,1,243,254, + 244,51,99,127,96,1,120,149,116,1,191,216,185,1,70,152,110,2,120,176, + 139,1,170,213,186,1,199,228,209,1,243,254,244,1,225,239,228,1,213,211, + 195,1,201,197,180,1,183,176,156,1,164,158,132,1,156,146,116,1,144,134, + 100,1,136,125,88,2,124,114,76,1,122,109,68,6,136,125,88,1,144,134, + 100,1,156,146,116,1,164,158,132,1,183,176,156,1,201,197,180,1,204,203, + 188,1,219,218,206,1,237,240,229,1,243,254,244,1,230,237,219,1,193,220, + 204,1,170,213,186,1,152,201,171,1,133,183,157,1,99,173,140,1,70,152, + 110,1,66,145,110,1,34,137,95,1,51,128,85,1,104,150,124,1,210,250, + 218,1,87,116,86,1,166,203,172,1,243,254,244,51,140,202,184,1,80,97, + 65,1,199,228,209,1,190,225,195,1,192,216,196,1,210,250,218,1,240,251, + 235,1,212,237,217,1,213,211,195,1,196,191,171,1,183,176,156,1,175,166, + 143,1,161,152,125,1,144,134,100,2,136,125,88,1,131,118,84,2,124,114, + 76,1,122,109,68,1,124,114,76,1,122,109,68,1,124,114,76,2,131,118, + 84,2,136,125,88,1,148,139,109,1,156,146,116,1,169,167,132,1,183,176, + 156,2,194,186,172,1,204,203,188,1,225,228,214,1,237,240,229,1,243,254, + 244,2,212,237,217,2,190,225,195,1,170,213,186,1,166,203,172,1,152,201, + 171,2,191,216,185,1,212,237,217,1,63,106,73,1,170,213,186,1,243,254, + 244,51,190,246,220,1,63,106,73,1,136,130,100,1,198,204,170,1,191,216, + 185,1,204,203,188,1,188,183,164,1,183,176,156,1,164,158,132,1,161,152, + 125,1,156,146,116,1,148,139,109,1,144,134,100,1,136,130,100,1,136,125, + 88,2,124,114,76,9,136,125,88,2,136,130,100,1,148,139,109,1,156,146, + 116,1,164,158,132,2,175,166,143,1,183,176,156,1,196,191,171,1,204,203, + 188,1,213,211,195,1,225,228,214,1,230,237,219,2,240,251,235,1,243,254, + 244,1,240,251,235,1,243,254,244,1,240,251,235,1,220,226,195,1,164,158, + 132,1,46,73,42,1,188,234,204,1,243,254,244,52,176,226,194,1,45,62, + 27,1,80,102,76,1,136,125,88,1,136,130,100,1,144,134,100,2,136,130, + 100,2,136,125,88,2,131,118,84,1,124,114,76,1,131,118,84,1,124,114, + 76,5,122,109,68,1,124,114,76,1,131,118,84,1,136,125,88,1,122,109, + 68,1,136,125,88,1,124,114,76,1,136,125,88,1,144,134,100,1,148,139, + 109,1,156,146,116,3,164,158,132,1,175,166,143,2,188,183,164,2,194,186, + 172,1,201,197,180,4,188,183,164,1,183,176,156,1,148,139,109,1,80,102, + 76,1,86,108,72,1,243,254,244,54,176,226,194,1,87,116,86,1,65,60, + 12,1,84,84,41,1,107,96,52,1,114,102,60,2,122,109,68,1,124,114, + 76,5,122,109,68,1,124,114,76,2,122,109,68,1,136,125,88,1,131,118, + 84,1,124,114,76,1,131,118,84,1,124,114,76,1,131,118,84,1,136,125, + 88,4,144,134,100,1,148,139,109,1,144,134,100,1,148,139,109,2,156,146, + 116,1,161,152,125,1,164,158,132,2,175,166,143,2,164,158,132,2,161,152, + 125,1,148,139,109,1,136,125,88,1,107,96,52,1,69,65,21,1,120,176, + 139,1,190,246,220,1,243,254,244,54,176,226,194,1,102,139,110,1,69,65, + 21,1,65,60,12,1,101,87,41,1,107,96,52,1,114,102,60,2,122,109, + 68,3,124,114,76,2,131,118,84,1,124,114,76,1,136,125,88,1,122,109, + 68,1,131,118,84,1,124,114,76,2,136,125,88,1,131,118,84,3,136,125, + 88,3,136,130,100,1,136,125,88,1,136,130,100,2,148,139,109,4,144,134, + 100,1,148,139,109,2,144,134,100,1,136,125,88,1,124,114,76,1,107,96, + 52,1,88,75,26,1,84,84,41,1,146,192,155,1,243,254,244,54,182,245, + 228,1,243,254,244,1,152,201,171,1,95,117,76,1,65,60,12,1,88,75, + 26,1,101,87,41,1,107,96,52,1,114,102,60,1,122,109,68,2,124,114, + 76,1,122,109,68,1,124,114,76,2,136,125,88,1,131,118,84,2,122,109, + 68,1,136,125,88,2,124,114,76,1,136,125,88,1,131,118,84,2,124,114, + 76,1,136,125,88,1,131,118,84,1,136,125,88,1,131,118,84,1,136,125, + 88,6,136,130,100,1,136,125,88,1,124,114,76,2,114,102,60,1,107,96, + 52,1,101,87,41,1,69,65,21,1,107,96,52,1,123,183,147,1,243,254, + 244,56,156,237,201,1,142,147,115,1,88,75,26,1,69,65,21,1,101,87, + 41,2,107,96,52,1,114,102,60,1,122,109,68,2,124,114,76,3,131,118, + 84,1,124,114,76,1,131,118,84,1,136,125,88,1,131,118,84,3,136,125, + 88,1,122,109,68,1,136,125,88,1,131,118,84,2,136,125,88,2,131,118, + 84,2,136,125,88,1,124,114,76,1,136,125,88,1,124,114,76,1,136,125, + 88,1,131,118,84,1,124,114,76,1,122,109,68,3,101,87,41,2,65,60, + 12,1,84,84,41,1,124,160,128,1,188,234,204,1,243,254,244,27,182,245, + 228,1,243,254,244,27,190,246,220,1,120,176,139,1,84,84,41,1,69,65, + 21,1,87,78,36,1,101,87,41,1,107,96,52,1,114,102,60,1,122,109, + 68,2,124,114,76,2,131,118,84,1,124,114,76,1,131,118,84,1,136,125, + 88,1,124,114,76,1,136,125,88,1,131,118,84,1,136,125,88,1,124,114, + 76,1,136,125,88,2,131,118,84,6,124,114,76,1,131,118,84,1,124,114, + 76,4,122,109,68,1,124,114,76,1,122,109,68,1,107,96,52,1,101,87, + 41,1,87,78,36,1,65,60,12,1,69,65,21,1,106,138,100,1,152,201, + 171,1,243,254,244,56,131,177,148,1,86,108,72,1,65,60,12,1,88,75, + 26,1,101,87,41,1,114,102,60,2,122,109,68,2,124,114,76,2,131,118, + 84,2,136,125,88,1,124,114,76,1,131,118,84,4,136,125,88,1,131,118, + 84,1,124,114,76,1,131,118,84,2,136,125,88,1,124,114,76,1,131,118, + 84,1,124,114,76,1,131,118,84,1,124,114,76,1,136,125,88,1,124,114, + 76,3,122,109,68,2,114,102,60,1,107,96,52,2,87,78,36,1,88,75, + 26,1,65,60,12,1,95,117,76,1,120,176,139,1,182,245,228,1,243,254, + 244,55,146,192,155,1,86,108,72,1,65,60,12,1,88,75,26,1,101,87, + 41,1,107,96,52,1,114,102,60,1,122,109,68,1,124,114,76,1,136,125, + 88,1,131,118,84,1,136,125,88,1,131,118,84,2,136,125,88,3,136,130, + 100,1,131,118,84,1,136,125,88,1,131,118,84,1,136,125,88,2,131,118, + 84,4,124,114,76,1,131,118,84,1,124,114,76,5,122,109,68,2,114,102, + 60,1,107,96,52,1,101,87,41,1,87,78,36,1,88,75,26,1,65,60, + 12,1,84,84,41,1,124,160,128,1,173,226,206,1,164,234,212,1,243,254, + 244,54,152,201,171,1,95,117,76,1,65,60,12,1,88,75,26,1,101,87, + 41,1,114,102,60,1,122,109,68,1,124,114,76,1,136,125,88,1,131,118, + 84,1,136,125,88,2,136,130,100,2,136,125,88,6,131,118,84,1,136,125, + 88,1,124,114,76,1,136,125,88,1,124,114,76,1,136,125,88,1,124,114, + 76,1,136,125,88,1,124,114,76,4,122,109,68,1,124,114,76,1,122,109, + 68,2,114,102,60,2,101,87,41,2,88,75,26,1,65,60,12,1,84,84, + 41,1,106,138,100,1,154,213,186,1,243,254,244,13,190,246,220,1,182,245, + 228,1,190,246,220,1,243,254,244,39,149,209,171,1,95,117,76,1,65,60, + 12,1,101,87,41,1,114,102,60,1,124,114,76,1,131,118,84,1,136,125, + 88,1,136,130,100,1,148,139,109,1,144,134,100,1,136,130,100,1,148,139, + 109,1,136,130,100,1,148,139,109,2,136,125,88,1,144,134,100,1,136,130, + 100,1,136,125,88,2,131,118,84,2,136,125,88,1,131,118,84,1,124,114, + 76,1,131,118,84,1,124,114,76,2,131,118,84,1,124,114,76,1,122,109, + 68,1,124,114,76,1,122,109,68,1,114,102,60,3,107,96,52,1,101,87, + 41,2,88,75,26,1,65,60,12,1,71,73,27,1,100,150,112,1,152,201, + 171,1,243,254,244,9,182,245,228,1,190,246,220,1,170,213,186,1,120,168, + 132,1,95,117,76,1,88,88,52,1,56,84,51,1,86,108,72,1,124,160, + 128,1,170,213,186,1,190,246,220,1,243,254,244,35,169,195,161,1,71,73, + 27,1,87,78,36,1,114,102,60,1,124,114,76,1,136,130,100,1,148,139, + 109,1,156,146,116,2,161,152,125,1,164,158,132,1,161,152,125,1,164,158, + 132,1,161,152,125,2,156,146,116,1,148,139,109,2,136,130,100,2,136,125, + 88,3,131,118,84,1,136,125,88,1,124,114,76,4,122,109,68,1,124,114, + 76,1,122,109,68,4,114,102,60,2,107,96,52,1,101,87,41,1,88,75, + 26,2,65,60,12,1,84,84,41,1,120,149,116,1,154,213,186,1,243,254, + 244,8,182,245,228,1,152,201,171,1,56,84,51,2,106,138,100,1,120,176, + 139,1,169,195,161,1,146,192,155,1,169,167,132,1,106,138,100,1,56,84, + 51,1,68,115,88,1,176,226,194,1,182,245,228,1,243,254,244,31,182,245, + 228,1,243,254,244,1,131,177,148,1,45,62,27,1,80,102,76,1,144,134, + 100,1,161,152,125,1,175,166,143,2,188,183,164,2,183,176,156,1,188,183, + 164,1,183,176,156,2,175,166,143,2,164,158,132,1,161,152,125,2,148,139, + 109,3,136,125,88,1,131,118,84,2,124,114,76,3,122,109,68,1,124,114, + 76,3,122,109,68,3,114,102,60,2,107,96,52,2,101,87,41,1,88,75, + 26,1,69,65,21,1,65,60,12,1,122,109,68,1,120,168,132,1,164,234, + 212,1,243,254,244,6,182,245,228,1,188,234,204,1,99,127,96,1,64,96, + 66,1,131,177,148,1,219,251,232,1,143,224,183,1,120,176,139,1,87,160, + 116,1,95,171,130,1,146,192,155,1,176,226,194,1,232,248,219,1,120,139, + 109,1,31,64,36,1,166,203,172,1,243,254,244,33,131,177,148,1,84,84, + 41,1,148,139,109,1,196,191,171,1,213,211,195,1,220,226,195,1,225,228, + 214,1,219,218,206,1,220,226,195,1,225,228,214,1,219,218,206,2,204,203, + 188,2,201,197,180,1,188,183,164,1,183,176,156,1,157,165,141,1,164,158, + 132,1,156,146,116,1,136,130,100,1,144,134,100,1,136,125,88,2,124,114, + 76,1,131,118,84,1,124,114,76,1,122,109,68,1,124,114,76,1,122,109, + 68,5,114,102,60,1,107,96,52,2,101,87,41,1,88,75,26,2,65,60, + 12,1,84,84,41,1,102,139,110,1,152,201,171,1,243,254,244,6,182,245, + 228,1,164,234,212,1,64,96,66,1,99,127,96,1,207,237,201,1,146,192, + 155,1,37,124,76,1,30,136,84,1,34,164,113,2,22,148,91,1,15,109, + 66,1,68,136,108,1,169,195,161,1,240,251,235,1,164,158,132,1,21,58, + 27,1,176,226,194,1,243,254,244,32,146,192,155,1,56,84,51,1,188,183, + 164,1,240,251,235,1,230,237,219,1,199,228,209,2,212,237,217,2,219,251, + 232,1,243,254,244,2,240,251,235,1,225,239,228,1,219,218,206,2,204,203, + 188,1,194,186,172,1,175,166,143,1,164,158,132,1,161,152,125,1,144,134, + 100,1,136,130,100,1,136,125,88,1,124,114,76,3,122,109,68,1,124,114, + 76,1,122,109,68,3,114,102,60,3,107,96,52,2,101,87,41,1,88,75, + 26,1,65,60,12,2,95,117,76,1,120,176,139,1,164,234,212,1,182,245, + 228,1,243,254,244,5,190,246,220,1,99,127,96,2,219,251,232,1,87,160, + 116,1,12,136,83,1,35,176,126,1,32,188,146,1,32,183,128,1,35,176, + 126,1,22,148,91,1,15,109,66,1,72,138,92,1,123,183,147,1,212,237, + 217,1,201,197,180,1,80,102,76,1,120,149,116,1,182,245,228,1,243,254, + 244,31,176,226,194,1,46,73,42,1,188,183,164,1,212,237,217,1,123,183, + 147,1,120,168,132,1,95,171,130,1,97,184,143,1,123,183,147,1,122,198, + 164,1,149,209,171,1,170,213,186,1,199,228,209,1,212,237,217,1,243,254, + 244,1,240,251,235,1,225,228,214,1,213,211,195,1,201,197,180,1,183,176, + 156,1,175,166,143,1,156,146,116,1,144,134,100,1,136,125,88,1,131,118, + 84,1,124,114,76,1,122,109,68,5,124,114,76,1,114,102,60,1,122,109, + 68,1,114,102,60,1,107,96,52,2,87,78,36,1,88,75,26,1,65,60, + 12,1,84,84,41,1,120,149,116,1,154,213,186,1,243,254,244,7,146,194, + 165,1,62,86,60,1,207,237,201,1,120,176,139,1,11,125,74,1,35,176, + 126,1,32,183,128,1,16,169,116,1,11,150,100,1,11,125,74,2,70,152, + 110,1,123,183,147,1,170,213,186,1,243,254,244,1,196,191,171,1,124,114, + 76,1,64,96,66,1,190,246,220,1,243,254,244,32,68,115,88,1,120,139, + 109,1,232,248,219,1,87,160,116,1,15,109,66,1,8,116,66,2,24,129, + 86,1,34,137,95,1,73,159,115,1,91,164,127,1,123,183,147,1,152,201, + 171,1,180,218,196,1,199,228,209,1,240,251,235,1,243,254,244,1,225,228, + 214,1,204,203,188,1,188,183,164,1,175,166,143,1,156,146,116,1,144,134, + 100,1,136,125,88,1,131,118,84,1,124,114,76,3,122,109,68,1,124,114, + 76,2,122,109,68,1,124,114,76,1,114,102,60,2,107,96,52,1,101,87, + 41,1,71,73,27,1,65,60,12,1,95,117,76,1,146,194,165,1,190,246, + 220,1,243,254,244,6,190,246,220,1,86,108,84,1,142,147,115,1,176,226, + 194,1,51,128,85,1,30,136,84,1,12,136,83,2,8,116,66,1,30,136, + 84,1,73,159,115,1,120,176,139,1,152,201,171,1,199,228,209,1,243,254, + 244,1,213,211,195,1,164,158,132,1,107,96,52,1,84,84,41,1,154,213, + 186,1,243,254,244,32,154,213,186,1,46,73,42,1,198,204,170,1,128,191, + 155,1,18,115,76,1,34,164,113,1,35,176,126,1,16,169,116,1,11,150, + 100,1,11,125,74,2,30,136,84,1,73,159,115,1,95,171,130,1,128,191, + 155,1,170,213,186,1,188,234,204,1,243,254,244,1,230,237,219,1,213,211, + 195,1,188,183,164,1,175,166,143,1,156,146,116,1,136,125,88,1,131,118, + 84,1,136,125,88,1,131,118,84,1,124,114,76,1,131,118,84,6,124,114, + 76,1,122,109,68,1,107,96,52,1,88,75,26,1,65,60,12,1,100,150, + 112,1,156,237,201,1,243,254,244,7,179,236,213,1,45,62,27,1,198,204, + 170,1,169,195,161,1,51,136,90,1,37,124,76,1,30,136,84,1,54,147, + 99,1,91,164,127,1,128,191,155,1,166,203,172,1,199,228,209,1,219,251, + 232,1,237,240,229,1,204,203,188,1,175,166,143,1,144,134,100,1,101,87, + 41,1,68,77,40,1,146,194,165,1,243,254,244,33,126,170,142,1,63,106, + 73,1,210,250,218,1,70,152,110,1,32,169,128,1,46,211,164,1,36,225, + 183,1,21,213,172,1,18,195,149,1,11,177,130,1,11,150,100,1,11,125, + 74,2,73,159,115,1,95,171,130,1,146,192,155,1,191,216,185,1,219,251, + 232,1,240,251,235,1,219,218,206,1,188,183,164,1,164,158,132,1,148,139, + 109,1,136,130,100,1,144,134,100,5,148,139,109,2,156,146,116,1,148,139, + 109,1,144,134,100,1,131,118,84,1,114,102,60,1,87,78,36,1,71,73, + 27,1,146,194,165,1,243,254,244,8,154,213,186,1,62,76,54,1,220,226, + 195,1,177,204,185,1,124,160,128,1,131,177,148,1,123,183,147,1,152,201, + 171,1,193,220,204,1,225,239,228,1,240,251,235,1,219,251,232,1,219,218, + 206,1,194,186,172,1,157,165,141,1,148,139,109,1,122,109,68,1,87,78, + 36,1,65,60,12,1,106,138,100,1,176,226,194,1,243,254,244,33,120,149, + 116,1,86,108,84,1,219,251,232,1,54,147,99,1,35,176,126,1,64,238, + 200,1,43,249,210,2,40,236,193,1,21,213,172,1,11,177,130,1,9,160, + 109,1,11,125,74,2,70,152,110,1,97,184,143,1,166,203,172,1,199,228, + 209,1,243,254,244,1,219,218,206,1,194,186,172,1,164,158,132,1,156,146, + 116,1,164,158,132,4,183,176,156,1,175,166,143,1,183,176,156,2,172,174, + 138,1,169,167,132,1,161,152,125,1,136,125,88,1,68,77,40,1,99,127, + 96,1,188,250,211,1,243,254,244,8,170,213,186,1,68,77,40,1,198,204, + 170,1,232,248,219,1,190,225,195,1,212,237,217,1,232,248,219,1,243,254, + 244,1,237,240,229,1,220,226,195,1,213,211,195,1,196,191,171,1,183,176, + 156,1,164,158,132,1,156,146,116,1,136,125,88,1,114,102,60,1,101,87, + 41,1,69,65,21,1,84,84,41,1,124,160,128,1,170,213,186,1,243,254, + 244,1,182,245,228,1,243,254,244,31,126,170,142,1,64,96,66,1,176,226, + 194,1,99,173,140,1,6,151,109,1,43,227,196,1,64,238,200,1,29,237, + 208,1,43,249,210,1,40,236,193,1,28,213,162,1,32,183,128,1,11,150, + 100,1,8,116,66,1,51,136,90,1,87,160,116,1,146,194,165,1,193,220, + 204,1,243,254,244,1,219,218,206,1,196,191,171,1,175,166,143,1,194,186, + 172,1,196,191,171,1,194,186,172,1,201,197,180,1,204,203,188,1,213,211, + 195,1,219,218,206,1,213,211,195,2,201,197,180,1,169,167,132,1,124,114, + 76,1,41,57,22,1,154,213,186,1,243,254,244,9,164,234,212,1,46,73, + 42,1,161,152,125,1,191,216,185,1,225,228,214,1,219,218,206,1,213,211, + 195,1,201,197,180,1,196,191,171,1,188,183,164,1,175,166,143,1,164,158, + 132,1,156,146,116,1,148,139,109,1,136,125,88,1,124,114,76,1,114,102, + 60,1,101,87,41,1,87,78,36,1,69,65,21,1,71,73,27,1,99,127, + 96,1,146,192,155,1,243,254,244,32,190,246,220,1,131,177,148,1,71,73, + 27,1,120,176,139,1,188,234,204,1,34,137,95,1,30,172,142,1,64,238, + 200,1,63,249,210,1,43,249,210,1,40,236,193,1,36,225,183,1,18,195, + 149,1,16,169,116,1,12,136,83,1,37,124,76,1,87,160,116,1,150,185, + 158,1,193,220,204,1,243,254,244,1,219,218,206,1,196,191,171,1,220,226, + 195,1,213,211,195,1,225,228,214,2,237,240,229,2,240,251,235,1,237,240, + 229,1,219,218,206,1,188,183,164,1,99,127,96,1,41,57,22,1,152,201, + 171,1,243,254,244,10,190,246,220,1,68,77,40,1,122,109,68,1,142,147, + 115,1,164,158,132,3,161,152,125,2,148,139,109,2,144,134,100,1,136,130, + 100,1,131,118,84,1,124,114,76,1,122,109,68,1,114,102,60,1,107,96, + 52,1,101,87,41,1,87,78,36,2,69,65,21,1,68,77,40,1,123,183, + 147,1,243,254,244,1,182,245,228,1,243,254,244,25,182,245,228,1,243,254, + 244,1,182,245,228,1,176,226,194,1,146,194,165,1,124,160,128,1,80,97, + 65,1,87,78,36,1,120,139,109,1,173,226,206,1,124,214,180,1,20,136, + 116,1,6,151,109,1,16,181,140,1,22,199,164,1,43,204,168,1,18,195, + 149,1,35,176,126,1,51,136,90,1,18,115,76,1,72,138,92,1,131,177, + 148,1,220,226,195,1,243,254,244,1,219,218,206,1,204,203,188,1,183,176, + 156,1,188,183,164,1,204,203,188,1,220,226,195,1,225,228,214,2,219,218, + 206,1,196,191,171,1,161,152,125,1,80,97,65,1,62,86,60,1,176,226, + 194,1,243,254,244,12,120,149,116,1,71,73,27,1,107,96,52,1,122,109, + 68,1,136,125,88,4,136,130,100,1,136,125,88,1,131,118,84,1,136,125, + 88,1,124,114,76,2,122,109,68,3,114,102,60,2,122,109,68,1,114,102, + 60,1,81,88,63,1,41,57,22,1,199,228,209,1,243,254,244,25,188,250, + 211,1,166,203,172,1,106,138,100,1,41,57,22,1,62,76,54,1,86,108, + 72,1,99,127,96,1,142,147,115,1,121,151,126,1,124,160,128,1,171,176, + 148,1,168,197,172,1,199,228,209,1,220,254,244,1,176,226,194,1,133,183, + 157,1,91,164,127,1,70,152,110,1,100,150,112,1,91,164,127,1,146,192, + 155,1,190,225,195,1,240,251,235,1,219,218,206,1,171,176,148,1,161,152, + 125,1,156,146,116,1,45,62,27,1,62,76,54,1,81,88,63,1,86,108, + 84,2,80,102,76,1,81,88,63,1,45,62,27,1,86,108,72,1,149,209, + 171,1,210,250,218,1,243,254,244,13,146,192,155,1,71,73,27,1,69,65, + 21,1,101,87,41,1,107,96,52,1,114,102,60,1,122,109,68,1,124,114, + 76,6,122,109,68,1,124,114,76,1,122,109,68,1,131,118,84,2,136,125, + 88,1,148,139,109,1,156,146,116,1,142,147,115,1,80,97,65,1,123,183, + 147,1,243,254,244,20,182,245,228,1,243,254,244,2,179,236,213,1,120,176, + 139,1,31,64,36,1,64,96,66,1,120,149,116,1,170,213,186,1,219,251, + 232,1,176,226,194,1,122,198,164,1,123,183,147,2,146,194,165,1,176,226, + 194,1,219,251,232,1,199,228,209,1,183,176,156,1,142,147,115,1,106,138, + 100,1,142,147,115,1,124,160,128,2,126,170,142,1,102,139,110,1,87,116, + 86,1,81,88,63,1,45,61,37,1,68,77,40,1,86,108,72,1,80,102, + 76,1,190,246,220,1,164,234,212,1,154,213,186,1,140,202,184,1,157,204, + 180,1,152,201,171,1,173,226,206,1,182,245,228,1,243,254,244,16,149,209, + 171,1,95,117,76,1,65,60,12,1,88,75,26,1,101,87,41,2,114,102, + 60,1,122,109,68,1,124,114,76,1,122,109,68,1,124,114,76,1,122,109, + 68,1,124,114,76,1,122,109,68,1,124,114,76,1,131,118,84,1,136,125, + 88,1,136,130,100,1,161,152,125,1,183,176,156,1,201,197,180,1,196,191, + 171,1,144,134,100,1,99,127,96,1,243,254,244,21,190,246,220,1,131,177, + 148,1,41,57,22,1,87,116,86,1,146,194,165,1,186,254,239,1,88,188, + 156,1,17,121,86,1,6,151,109,1,30,172,142,1,22,199,164,1,43,204, + 168,1,18,189,146,1,34,164,113,1,11,125,74,1,51,136,90,1,146,192, + 155,1,240,251,235,1,171,176,148,1,88,88,52,1,86,108,72,1,120,168, + 132,1,120,176,139,1,131,177,148,1,140,202,184,1,154,213,186,1,164,234, + 212,1,182,245,228,1,243,254,244,27,152,201,171,1,99,127,96,1,65,60, + 12,1,88,75,26,2,107,96,52,2,114,102,60,1,122,109,68,3,124,114, + 76,1,122,109,68,1,124,114,76,1,131,118,84,1,136,125,88,1,136,130, + 100,1,164,158,132,1,183,176,156,1,213,211,195,1,237,240,229,1,230,237, + 219,1,140,152,126,1,80,102,76,1,243,254,244,19,190,246,220,1,157,204, + 180,1,56,84,51,1,68,115,88,1,146,192,155,1,164,234,212,1,68,136, + 108,1,30,143,118,1,48,214,186,1,72,237,212,1,43,227,196,1,29,237, + 208,2,43,249,210,1,40,236,193,1,20,203,154,1,34,164,113,1,8,116, + 66,1,66,145,110,1,168,197,172,1,232,248,219,1,148,139,109,1,41,57, + 22,1,190,225,195,1,243,254,244,33,152,201,171,1,95,117,76,1,65,60, + 12,2,101,87,41,2,107,96,52,1,114,102,60,3,122,109,68,2,124,114, + 76,2,131,118,84,1,148,139,109,1,156,146,116,1,183,176,156,1,213,211, + 195,1,240,251,235,1,237,240,229,1,243,254,244,1,169,167,132,1,87,116, + 86,1,190,246,220,1,243,254,244,17,188,234,204,1,124,160,128,1,46,73, + 42,1,131,177,148,1,188,250,211,1,36,158,132,2,71,239,220,1,44,212, + 209,1,10,202,202,2,13,215,208,1,18,226,208,1,43,249,210,1,43,227, + 196,1,20,203,154,1,16,169,116,1,11,125,74,1,24,129,86,1,120,168, + 132,1,170,213,186,1,240,251,235,1,169,167,132,1,84,84,41,1,100,150, + 112,1,219,251,232,1,243,254,244,9,182,245,228,1,243,254,244,22,128,191, + 155,1,95,117,76,1,65,60,12,1,88,75,26,2,101,87,41,1,107,96, + 52,2,114,102,60,1,122,109,68,1,114,102,60,1,122,109,68,2,131,118, + 84,1,136,125,88,1,156,146,116,1,175,166,143,1,204,203,188,1,225,239, + 228,2,213,211,195,1,219,251,232,1,120,139,109,1,124,160,128,1,243,254, + 244,14,190,246,220,1,243,254,244,1,182,245,228,1,152,201,171,1,31,64, + 36,1,87,116,86,1,188,234,204,1,128,191,155,1,15,130,100,1,80,220, + 208,1,44,212,209,1,10,202,202,1,7,191,203,1,17,203,215,1,28,216, + 220,1,43,238,223,1,29,237,208,1,21,213,172,1,11,177,130,1,8,140, + 93,1,8,116,66,1,70,152,110,1,123,183,147,1,170,213,186,1,240,251, + 235,1,204,203,188,1,142,147,115,1,107,96,52,1,80,97,65,1,166,203, + 172,1,243,254,244,1,182,245,228,1,243,254,244,4,190,246,220,1,243,254, + 244,1,123,183,147,1,188,234,204,1,243,254,244,22,146,192,155,1,95,117, + 76,1,65,60,12,1,88,75,26,1,101,87,41,2,107,96,52,2,114,102, + 60,2,122,109,68,3,131,118,84,1,144,134,100,1,161,152,125,1,188,183, + 164,1,219,218,206,1,240,251,235,1,192,216,196,1,175,198,183,1,240,251, + 235,1,80,102,76,1,170,213,186,1,243,254,244,15,188,234,204,1,121,151, + 126,1,46,73,42,1,131,177,148,1,190,246,220,1,20,136,116,1,36,181, + 146,1,82,225,224,1,10,202,202,1,7,191,203,1,10,202,202,1,13,215, + 208,1,36,228,222,1,43,249,210,1,21,213,172,1,11,177,130,1,11,150, + 100,1,8,116,66,1,34,137,95,1,95,171,130,1,152,201,171,1,188,234, + 204,1,240,251,235,1,213,211,195,1,175,166,143,1,136,130,100,1,84,84, + 41,1,65,60,12,1,106,138,100,1,146,192,155,1,149,209,171,1,190,225, + 195,1,166,203,172,1,124,160,128,1,99,127,96,1,87,116,86,1,140,152, + 126,1,95,117,76,1,21,58,27,1,150,185,158,1,243,254,244,20,190,246, + 220,1,154,213,186,1,99,127,96,1,65,60,12,2,87,78,36,1,101,87, + 41,2,107,96,52,2,114,102,60,2,122,109,68,1,124,114,76,1,136,125, + 88,1,144,134,100,1,175,166,143,1,201,197,180,1,240,251,235,1,199,228, + 209,1,175,198,183,1,213,211,195,1,175,198,183,1,41,57,22,1,243,254, + 244,14,179,236,213,1,131,177,148,1,21,58,27,1,87,116,86,1,176,226, + 194,1,122,198,164,1,17,121,86,1,68,218,191,1,18,226,208,1,10,202, + 202,1,17,203,215,2,36,228,222,1,43,238,223,1,26,216,182,1,16,181, + 140,1,6,151,109,1,8,116,66,1,34,137,95,1,87,160,116,1,128,191, + 155,1,191,216,185,1,219,251,232,1,237,240,229,1,204,203,188,1,171,176, + 148,1,148,139,109,1,122,109,68,1,101,87,41,1,65,60,12,1,88,75, + 26,1,95,117,76,1,106,138,100,1,86,108,72,1,41,57,22,1,56,84, + 51,1,131,118,84,1,144,134,100,1,99,127,96,1,240,251,235,1,166,203, + 172,1,64,96,66,1,124,160,128,1,243,254,244,20,154,213,186,1,100,150, + 112,1,84,84,41,1,69,65,21,1,88,75,26,2,101,87,41,1,107,96, + 52,3,114,102,60,2,124,114,76,1,131,118,84,1,156,146,116,1,183,176, + 156,1,219,218,206,1,240,251,235,1,204,203,188,1,177,204,185,1,243,254, + 244,1,99,127,96,1,133,183,157,1,182,245,228,1,243,254,244,11,190,225, + 195,1,150,185,158,1,45,62,27,1,80,102,76,1,123,183,147,1,188,250, + 211,1,36,151,114,1,30,172,142,1,43,238,223,1,13,215,208,1,10,202, + 202,1,13,215,208,1,18,226,208,1,41,247,222,1,26,216,182,1,18,195, + 149,1,9,160,109,1,11,125,74,1,12,136,83,1,73,159,115,1,120,176, + 139,1,157,204,180,1,212,237,217,1,243,254,244,1,225,228,214,1,201,197, + 180,1,175,166,143,1,156,146,116,1,124,114,76,1,114,102,60,1,101,87, + 41,1,88,75,26,1,65,60,12,3,69,65,21,1,107,96,52,1,148,139, + 109,1,168,197,172,1,240,251,235,1,243,254,244,1,70,152,110,1,123,183, + 147,1,232,248,219,1,63,106,73,1,124,160,128,1,243,254,244,19,164,234, + 212,1,123,183,147,1,95,117,76,1,69,65,21,1,65,60,12,1,88,75, + 26,2,101,87,41,2,107,96,52,2,114,102,60,1,122,109,68,1,136,125, + 88,1,164,158,132,1,188,183,164,1,230,237,219,1,237,240,229,1,193,220, + 204,1,212,237,217,1,171,176,148,1,46,73,42,1,243,254,244,10,190,246, + 220,1,170,213,186,1,120,149,116,1,21,58,27,1,86,108,72,1,120,176, + 139,1,219,251,232,1,97,184,143,1,17,121,86,1,43,204,168,1,29,237, + 208,1,18,226,208,1,13,215,208,1,18,226,208,1,41,247,222,1,43,227, + 196,1,20,203,154,1,16,169,116,1,12,136,83,1,11,125,74,1,70,152, + 110,1,95,171,130,1,146,194,165,1,193,220,204,1,240,251,235,2,213,211, + 195,1,194,186,172,1,169,167,132,1,148,139,109,1,136,125,88,1,122,109, + 68,1,114,102,60,1,101,87,41,1,87,78,36,1,88,75,26,2,87,78, + 36,1,101,87,41,1,124,114,76,1,164,158,132,1,219,218,206,1,199,228, + 209,1,150,185,158,1,8,116,66,1,37,124,76,1,54,147,99,1,219,251, + 232,1,80,102,76,1,150,185,158,1,243,254,244,19,154,213,186,1,124,160, + 128,1,86,108,72,1,65,60,12,1,69,65,21,1,71,73,27,1,88,75, + 26,1,101,87,41,1,88,75,26,1,101,87,41,1,107,96,52,1,114,102, + 60,1,136,125,88,1,161,152,125,1,201,197,180,1,237,240,229,1,240,251, + 235,2,196,191,171,1,46,73,42,1,176,226,194,1,243,254,244,6,190,246, + 220,2,170,213,186,1,124,160,128,1,46,73,42,1,56,84,51,1,106,138, + 100,1,166,203,172,1,186,254,239,1,128,191,155,1,11,125,74,1,16,181, + 140,1,29,237,208,4,41,247,222,1,29,237,208,1,18,195,149,1,11,177, + 130,1,8,140,93,1,11,125,74,1,34,137,95,1,95,171,130,1,133,183, + 157,1,180,218,196,1,225,239,228,1,243,254,244,1,225,228,214,1,204,203, + 188,1,188,183,164,1,164,158,132,1,156,146,116,1,136,130,100,1,131,118, + 84,1,122,109,68,1,114,102,60,1,107,96,52,1,101,87,41,4,114,102, + 60,1,136,125,88,1,183,176,156,1,230,237,219,1,191,216,185,1,91,164, + 127,1,8,116,66,1,35,176,126,1,32,169,128,1,34,137,95,1,188,250, + 211,1,46,73,42,1,148,230,196,1,182,245,228,1,243,254,244,18,154,213, + 186,1,124,160,128,1,95,117,76,1,71,73,27,1,65,60,12,1,69,65, + 21,1,65,60,12,1,88,75,26,1,87,78,36,1,101,87,41,1,107,96, + 52,1,136,125,88,1,161,152,125,1,196,191,171,1,219,218,206,1,225,228, + 214,1,171,176,148,1,48,75,52,1,152,201,171,1,243,254,244,1,182,245, + 228,1,243,254,244,1,190,246,220,1,243,254,244,1,190,246,220,1,154,213, + 186,1,124,160,128,1,46,73,42,1,56,84,51,1,99,127,96,1,146,192, + 155,1,210,250,218,1,154,213,186,1,73,159,115,1,15,109,66,1,32,169, + 128,1,36,225,183,1,43,249,210,3,41,247,222,1,40,236,193,1,20,203, + 154,1,11,177,130,1,8,140,93,1,8,116,66,1,34,137,95,1,73,159, + 115,1,133,183,157,1,157,204,180,1,212,237,217,1,240,251,235,1,237,240, + 229,1,219,218,206,1,196,191,171,1,171,176,148,1,161,152,125,1,148,139, + 109,1,136,130,100,1,131,118,84,1,124,114,76,1,122,109,68,1,114,102, + 60,2,107,96,52,3,114,102,60,1,122,109,68,1,144,134,100,1,175,166, + 143,1,225,228,214,1,199,228,209,1,124,160,128,1,11,125,74,1,32,183, + 128,1,41,220,172,1,32,188,146,1,73,159,115,1,152,201,171,1,46,73, + 42,1,190,246,220,1,243,254,244,19,154,213,186,1,126,170,142,1,120,139, + 109,1,114,102,60,1,84,84,41,1,69,65,21,1,65,60,12,2,71,73, + 27,1,101,87,41,1,122,109,68,1,148,139,109,1,169,167,132,1,172,174, + 138,1,136,130,100,1,45,62,27,1,152,201,171,1,243,254,244,4,188,234, + 204,1,150,185,158,1,80,97,65,1,46,73,42,1,99,127,96,1,150,185, + 158,1,219,251,232,1,148,230,196,1,95,171,130,1,17,121,86,1,11,150, + 100,1,18,189,146,1,36,225,183,1,40,236,193,1,43,249,210,1,40,236, + 193,2,26,216,182,1,18,195,149,1,10,166,125,1,8,140,93,1,8,116, + 66,1,34,137,95,1,73,159,115,1,131,177,148,1,157,204,180,1,199,228, + 209,1,240,251,235,1,243,254,244,1,225,228,214,1,204,203,188,1,188,183, + 164,1,175,166,143,1,164,158,132,1,148,139,109,1,136,125,88,1,136,130, + 100,1,124,114,76,2,122,109,68,2,114,102,60,5,131,118,84,1,148,139, + 109,1,175,166,143,1,225,228,214,1,212,237,217,1,126,170,142,1,12,136, + 83,1,9,160,109,1,36,225,183,1,63,249,210,1,36,181,146,1,122,198, + 164,1,102,139,110,1,120,176,139,1,243,254,244,20,156,237,201,1,152,201, + 171,1,123,183,147,1,124,160,128,1,106,138,100,1,95,117,76,1,80,97, + 65,1,69,65,21,2,84,84,41,1,80,97,65,2,46,73,42,1,99,127, + 96,1,188,234,204,1,219,251,232,1,243,254,244,1,182,245,228,1,164,234, + 212,1,123,183,147,1,31,64,36,1,86,108,72,1,169,167,132,1,188,250, + 211,1,176,226,194,1,95,171,130,1,37,124,76,1,8,140,93,1,35,176, + 126,1,46,211,164,1,41,220,172,1,36,225,183,3,21,213,172,1,18,195, + 149,1,11,177,130,1,6,151,109,1,12,136,83,1,8,116,66,1,34,137, + 95,1,73,159,115,1,123,183,147,1,152,201,171,1,173,226,206,1,237,240, + 229,1,243,254,244,1,225,228,214,1,213,211,195,1,194,186,172,1,171,176, + 148,1,164,158,132,1,156,146,116,1,144,134,100,1,136,130,100,1,136,125, + 88,1,124,114,76,3,122,109,68,6,124,114,76,1,131,118,84,1,148,139, + 109,1,175,166,143,1,213,211,195,1,219,251,232,1,168,197,172,1,34,164, + 113,1,11,125,74,1,22,199,164,1,43,249,210,1,63,249,210,1,8,140, + 93,1,219,251,232,1,48,75,52,1,173,226,206,1,243,254,244,21,182,245, + 228,1,148,230,196,1,154,213,186,1,152,201,171,1,123,183,147,1,124,160, + 128,1,106,138,100,1,95,117,76,1,99,127,96,1,126,170,142,1,176,226, + 194,1,243,254,244,3,190,246,220,1,169,195,161,1,68,77,40,1,80,102, + 76,1,150,185,158,1,219,251,232,1,122,198,164,1,51,136,90,1,8,140, + 93,1,35,176,126,1,20,203,154,1,46,211,164,1,28,213,162,1,41,220, + 172,1,28,213,162,1,20,203,154,1,32,183,128,1,16,169,116,1,9,160, + 109,1,12,136,83,1,8,116,66,1,12,136,83,1,54,147,99,1,91,164, + 127,1,123,183,147,1,157,204,180,1,193,220,204,1,225,239,228,1,243,254, + 244,1,237,240,229,1,213,211,195,1,201,197,180,1,188,183,164,1,175,166, + 143,1,161,152,125,1,148,139,109,1,144,134,100,2,131,118,84,3,124,114, + 76,3,122,109,68,1,124,114,76,1,122,109,68,1,124,114,76,1,122,109, + 68,1,124,114,76,1,136,125,88,1,148,139,109,1,164,158,132,1,204,203, + 188,1,243,254,244,1,177,204,185,1,97,184,143,1,8,116,66,1,11,177, + 130,1,40,236,193,1,29,237,208,1,43,227,196,1,66,145,110,1,128,191, + 155,1,68,115,88,1,243,254,244,34,179,236,213,1,106,138,100,1,56,84, + 51,1,120,168,132,1,240,251,235,1,128,191,155,1,37,124,76,1,11,150, + 100,1,32,183,128,1,43,202,153,1,28,213,162,1,20,203,154,1,18,195, + 149,1,16,181,140,1,11,177,130,1,11,150,100,1,8,140,93,1,11,125, + 74,1,8,116,66,1,12,136,83,1,54,147,99,1,73,159,115,1,120,176, + 139,1,146,194,165,1,157,204,180,1,199,228,209,1,225,239,228,1,243,254, + 244,1,237,240,229,1,219,218,206,1,201,197,180,1,194,186,172,1,175,166, + 143,1,164,158,132,1,156,146,116,1,148,139,109,1,144,134,100,1,136,125, + 88,2,124,114,76,3,131,118,84,1,124,114,76,5,122,109,68,1,124,114, + 76,1,131,118,84,1,136,125,88,1,148,139,109,1,164,158,132,1,196,191, + 171,1,225,239,228,1,225,228,214,1,149,209,171,1,36,151,114,1,8,140, + 93,1,28,213,162,1,43,249,210,1,29,237,208,1,36,181,146,1,148,230, + 196,1,63,106,73,1,154,213,186,1,182,245,228,1,243,254,244,31,146,194, + 165,1,45,62,27,1,99,127,96,1,190,225,195,1,149,209,171,1,51,136, + 90,1,12,136,83,1,35,176,126,1,43,202,153,1,18,195,149,1,32,183, + 128,2,11,150,100,1,22,148,91,1,11,125,74,1,8,116,66,1,12,136, + 83,1,60,141,100,1,73,159,115,1,91,164,127,1,123,183,147,1,146,194, + 165,1,157,204,180,1,193,220,204,1,199,228,209,1,243,254,244,1,240,251, + 235,1,225,239,228,1,213,211,195,1,196,191,171,1,188,183,164,1,175,166, + 143,1,164,158,132,1,156,146,116,1,148,139,109,1,144,134,100,1,136,125, + 88,1,136,130,100,1,136,125,88,1,124,114,76,1,136,125,88,2,122,109, + 68,1,131,118,84,1,124,114,76,1,131,118,84,1,136,125,88,1,122,109, + 68,1,131,118,84,1,136,125,88,1,124,114,76,1,136,125,88,2,148,139, + 109,1,164,158,132,1,188,183,164,1,219,218,206,1,237,240,229,1,176,226, + 194,1,99,173,140,1,8,116,66,1,11,177,130,1,29,237,208,2,43,249, + 210,1,17,121,86,1,154,213,186,1,56,84,51,1,243,254,244,30,190,246, + 220,1,126,170,142,1,71,73,27,1,124,160,128,1,219,251,232,1,120,168, + 132,1,15,109,66,1,34,164,113,1,32,183,128,2,9,160,109,1,11,150, + 100,1,11,125,74,1,8,116,66,1,24,129,86,1,70,152,110,1,73,159, + 115,1,95,171,130,1,123,183,147,1,146,194,165,1,157,204,180,1,180,218, + 196,1,199,228,209,1,212,237,217,1,243,254,244,2,225,239,228,1,219,218, + 206,1,213,211,195,1,196,191,171,1,188,183,164,1,183,176,156,1,164,158, + 132,1,161,152,125,1,156,146,116,1,148,139,109,1,144,134,100,1,136,130, + 100,1,136,125,88,1,131,118,84,3,136,125,88,1,124,114,76,1,136,125, + 88,2,131,118,84,2,122,109,68,1,136,125,88,1,124,114,76,3,131,118, + 84,1,136,125,88,1,136,130,100,1,156,146,116,1,183,176,156,1,213,211, + 195,1,243,254,244,1,212,237,217,1,146,194,165,1,54,147,99,1,12,136, + 83,1,18,195,149,1,41,247,222,1,29,237,208,1,32,188,146,1,143,224, + 183,1,95,117,76,1,152,201,171,1,243,254,244,28,188,234,204,1,99,127, + 96,1,64,96,66,1,146,192,155,1,207,237,201,1,70,152,110,1,11,125, + 74,1,34,164,113,2,11,150,100,1,12,136,83,1,8,116,66,1,34,137, + 95,1,70,152,110,1,95,171,130,1,133,183,157,1,152,201,171,1,157,204, + 180,1,193,220,204,1,199,228,209,1,219,251,232,1,243,254,244,2,225,239, + 228,1,237,240,229,1,219,218,206,1,213,211,195,1,204,203,188,1,194,186, + 172,1,188,183,164,1,175,166,143,1,164,158,132,1,156,146,116,2,148,139, + 109,2,136,125,88,5,131,118,84,2,124,114,76,1,136,125,88,1,131,118, + 84,2,136,125,88,1,124,114,76,1,136,125,88,1,131,118,84,1,136,125, + 88,1,131,118,84,1,136,125,88,3,144,134,100,1,156,146,116,1,175,166, + 143,1,196,191,171,1,237,240,229,1,243,254,244,1,180,218,196,1,97,184, + 143,1,11,125,74,1,16,169,116,1,36,225,183,1,43,249,210,1,40,236, + 193,1,18,115,76,1,176,226,194,1,31,64,36,1,190,246,220,1,243,254, + 244,25,190,246,220,1,166,203,172,1,31,64,36,1,95,117,76,1,207,237, + 201,1,149,209,171,1,51,128,85,1,30,136,84,1,22,148,91,2,11,125, + 74,2,54,147,99,1,95,171,130,1,128,191,155,1,154,213,186,1,180,218, + 196,1,212,237,217,1,240,251,235,1,243,254,244,1,240,251,235,1,225,239, + 228,1,219,218,206,2,213,211,195,1,201,197,180,1,194,186,172,2,183,176, + 156,1,175,166,143,2,164,158,132,1,156,146,116,3,144,134,100,2,136,125, + 88,2,131,118,84,1,136,125,88,1,131,118,84,2,136,125,88,1,131,118, + 84,2,136,125,88,1,124,114,76,1,131,118,84,2,136,125,88,1,124,114, + 76,1,131,118,84,4,136,125,88,2,148,139,109,2,169,167,132,1,188,183, + 164,1,219,218,206,1,225,239,228,2,152,201,171,1,70,152,110,1,8,116, + 66,1,11,177,130,1,40,236,193,1,64,238,200,1,35,176,126,1,124,214, + 180,1,87,116,86,1,146,194,165,1,182,245,228,1,243,254,244,23,190,246, + 220,1,124,160,128,1,46,73,42,1,124,160,128,1,240,251,235,1,120,176, + 139,1,8,116,66,1,30,136,84,1,22,148,91,1,8,116,66,1,11,125, + 74,1,54,147,99,1,131,177,148,1,149,209,171,1,193,220,204,1,212,237, + 217,1,243,254,244,1,240,251,235,1,225,228,214,1,219,218,206,1,204,203, + 188,2,196,191,171,2,183,176,156,3,157,165,141,1,175,166,143,1,164,158, + 132,1,161,152,125,2,156,146,116,1,148,139,109,2,136,130,100,1,144,134, + 100,1,136,130,100,1,136,125,88,1,136,130,100,1,136,125,88,4,131,118, + 84,3,136,125,88,3,131,118,84,2,136,125,88,2,131,118,84,1,136,125, + 88,1,131,118,84,1,136,125,88,3,148,139,109,1,161,152,125,1,175,166, + 143,1,204,203,188,1,225,228,214,1,243,254,244,1,193,220,204,1,131,177, + 148,1,54,147,99,1,12,136,83,1,18,195,149,1,40,236,193,1,46,211, + 164,1,34,137,95,1,176,226,194,1,21,58,27,1,190,246,220,1,243,254, + 244,20,190,246,220,1,243,254,244,1,173,226,206,1,64,96,66,1,63,106, + 73,1,166,203,172,1,190,225,195,1,70,152,110,1,37,124,76,1,22,148, + 91,2,8,116,66,1,54,147,99,1,120,168,132,1,149,209,171,1,188,234, + 204,1,240,251,235,1,237,240,229,1,225,228,214,1,213,211,195,1,196,191, + 171,1,188,183,164,2,175,166,143,2,164,158,132,2,161,152,125,1,164,158, + 132,1,161,152,125,2,156,146,116,3,148,139,109,4,136,130,100,1,136,125, + 88,1,136,130,100,1,136,125,88,2,131,118,84,2,136,125,88,2,131,118, + 84,2,136,125,88,2,131,118,84,2,136,125,88,3,131,118,84,1,136,125, + 88,3,131,118,84,1,136,125,88,1,136,130,100,1,144,134,100,1,156,146, + 116,1,175,166,143,1,188,183,164,1,201,197,180,1,225,228,214,1,219,251, + 232,1,170,213,186,1,99,173,140,1,24,129,86,1,8,140,93,1,18,195, + 149,1,46,211,164,1,22,148,91,1,149,209,171,1,106,138,100,1,100,150, + 112,1,243,254,244,21,146,194,165,1,41,57,22,1,106,138,100,1,210,250, + 218,1,128,191,155,1,8,116,66,1,11,150,100,1,16,169,116,1,12,136, + 83,1,8,116,66,1,54,147,99,1,123,183,147,1,190,225,195,1,219,251, + 232,1,237,240,229,1,219,218,206,1,201,197,180,1,188,183,164,1,175,166, + 143,1,169,167,132,1,161,152,125,1,156,146,116,3,148,139,109,1,156,146, + 116,1,148,139,109,4,156,146,116,2,148,139,109,4,136,130,100,1,148,139, + 109,1,144,134,100,1,136,130,100,1,136,125,88,1,136,130,100,1,131,118, + 84,1,136,125,88,2,131,118,84,1,136,130,100,1,136,125,88,5,131,118, + 84,1,136,125,88,1,131,118,84,1,136,125,88,2,131,118,84,2,136,130, + 100,1,136,125,88,2,148,139,109,2,161,152,125,1,183,176,156,1,188,183, + 164,1,204,203,188,1,240,251,235,1,212,237,217,1,154,213,186,1,91,164, + 127,1,24,129,86,1,22,148,91,1,32,183,128,1,34,164,113,1,54,147, + 99,1,210,250,218,1,64,96,66,1,150,185,158,1,243,254,244,18,182,245, + 228,1,131,177,148,1,46,73,42,1,126,170,142,1,190,246,220,1,66,145, + 110,1,11,150,100,1,32,183,128,2,22,148,91,1,11,125,74,1,73,159, + 115,1,146,192,155,1,179,236,213,1,240,251,235,1,219,218,206,1,194,186, + 172,1,175,166,143,1,169,167,132,1,156,146,116,2,144,134,100,1,148,139, + 109,1,144,134,100,6,148,139,109,1,144,134,100,1,156,146,116,1,148,139, + 109,2,156,146,116,1,148,139,109,1,156,146,116,2,144,134,100,1,148,139, + 109,1,144,134,100,1,136,130,100,1,136,125,88,1,136,130,100,1,136,125, + 88,1,131,118,84,1,136,125,88,2,131,118,84,1,136,125,88,1,131,118, + 84,1,136,125,88,1,131,118,84,1,136,125,88,5,131,118,84,1,136,130, + 100,1,131,118,84,1,136,125,88,2,136,130,100,1,144,134,100,1,148,139, + 109,1,156,146,116,1,164,158,132,1,175,166,143,1,194,186,172,1,219,218, + 206,1,237,240,229,1,225,239,228,1,149,209,171,1,91,164,127,1,37,124, + 76,1,12,136,83,1,22,148,91,1,15,109,66,1,146,192,155,1,198,204, + 170,1,46,73,42,1,124,160,128,1,188,234,204,1,182,245,228,1,243,254, + 244,14,190,246,220,1,124,160,128,1,62,86,60,1,166,203,172,1,149,209, + 171,1,11,125,74,1,11,177,130,1,43,202,153,1,18,195,149,1,9,160, + 109,1,8,116,66,1,54,147,99,1,122,198,164,1,212,237,217,1,225,239, + 228,1,213,211,195,1,183,176,156,1,175,166,143,1,156,146,116,1,148,139, + 109,1,144,134,100,1,136,130,100,1,136,125,88,4,136,130,100,1,136,125, + 88,1,136,130,100,1,144,134,100,2,148,139,109,1,156,146,116,3,161,152, + 125,3,156,146,116,1,161,152,125,1,156,146,116,1,144,134,100,1,148,139, + 109,1,144,134,100,1,136,125,88,2,136,130,100,1,131,118,84,1,136,125, + 88,2,131,118,84,1,136,125,88,4,131,118,84,1,136,125,88,2,131,118, + 84,1,136,125,88,4,136,130,100,1,136,125,88,2,144,134,100,1,148,139, + 109,1,161,152,125,1,164,158,132,1,175,166,143,1,196,191,171,1,219,218, + 206,1,225,239,228,2,157,204,180,1,95,171,130,1,54,147,99,1,8,116, + 66,1,18,115,76,1,60,141,100,1,190,225,195,1,198,204,170,1,86,108, + 84,1,41,57,22,1,120,149,116,1,157,204,180,1,173,226,206,1,190,246, + 220,1,243,254,244,1,190,246,220,1,243,254,244,1,182,245,228,1,243,254, + 244,1,182,245,228,1,243,254,244,1,182,245,228,1,243,254,244,1,182,245, + 228,1,164,234,212,1,99,127,96,1,64,96,66,1,176,226,194,1,97,184, + 143,1,15,130,100,1,28,213,162,1,36,225,183,1,41,220,172,1,11,177, + 130,1,11,125,74,1,54,147,99,1,128,191,155,1,212,237,217,1,237,240, + 229,1,204,203,188,1,183,176,156,1,156,146,116,1,148,139,109,1,144,134, + 100,1,136,125,88,1,131,118,84,2,136,125,88,1,124,114,76,1,131,118, + 84,1,136,125,88,2,136,130,100,1,144,134,100,2,148,139,109,2,156,146, + 116,1,164,158,132,2,175,166,143,4,164,158,132,2,156,146,116,1,148,139, + 109,2,144,134,100,1,136,130,100,1,136,125,88,1,131,118,84,1,136,125, + 88,5,131,118,84,1,136,125,88,3,131,118,84,1,136,125,88,1,136,130, + 100,1,136,125,88,1,136,130,100,1,136,125,88,3,144,134,100,2,148,139, + 109,2,156,146,116,1,161,152,125,1,175,166,143,1,194,186,172,1,219,218, + 206,1,230,237,219,1,219,251,232,1,180,218,196,1,133,183,157,1,73,159, + 115,1,60,141,100,1,54,147,99,1,120,168,132,1,180,218,196,1,212,237, + 217,1,150,185,158,1,120,139,109,1,80,102,76,1,46,73,42,1,41,57, + 22,1,80,102,76,1,124,160,128,1,146,192,155,1,176,226,194,1,188,250, + 211,1,243,254,244,3,188,250,211,1,170,213,186,1,64,96,66,1,87,116, + 86,1,210,250,218,1,95,171,130,1,10,166,125,1,43,227,196,1,43,249, + 210,1,40,236,193,1,18,195,149,1,8,140,93,1,12,136,83,1,120,176, + 139,1,173,226,206,1,240,251,235,1,204,203,188,1,183,176,156,1,161,152, + 125,1,148,139,109,1,136,125,88,1,131,118,84,3,124,114,76,1,131,118, + 84,1,136,125,88,2,131,118,84,1,136,125,88,2,144,134,100,1,148,139, + 109,1,156,146,116,1,161,152,125,1,164,158,132,1,175,166,143,1,183,176, + 156,1,188,183,164,1,194,186,172,2,188,183,164,2,183,176,156,1,175,166, + 143,1,164,158,132,1,156,146,116,1,148,139,109,2,136,125,88,3,131,118, + 84,2,124,114,76,1,131,118,84,2,136,130,100,1,131,118,84,1,136,125, + 88,5,131,118,84,1,136,130,100,1,131,118,84,1,136,130,100,2,136,125, + 88,1,144,134,100,1,148,139,109,2,156,146,116,1,164,158,132,1,175,166, + 143,1,188,183,164,1,204,203,188,1,225,228,214,1,243,254,244,1,225,239, + 228,1,170,213,186,1,133,183,157,1,131,177,148,1,120,168,132,1,126,170, + 142,1,168,197,172,1,192,216,196,1,230,237,219,1,240,251,235,1,220,226, + 195,1,198,204,170,1,172,174,138,1,106,138,100,1,68,115,88,1,68,77, + 40,1,21,58,27,1,63,106,73,1,104,150,124,1,124,160,128,1,87,116, + 86,1,46,73,42,1,100,150,112,1,219,251,232,1,30,143,118,1,36,181, + 146,1,41,247,222,1,43,249,210,2,21,213,172,1,9,160,109,1,11,125, + 74,1,95,171,130,1,154,213,186,1,243,254,244,1,219,218,206,1,183,176, + 156,1,161,152,125,1,148,139,109,1,136,125,88,2,124,114,76,1,131,118, + 84,1,124,114,76,1,131,118,84,2,124,114,76,1,136,125,88,2,136,130, + 100,1,144,134,100,1,136,130,100,1,156,146,116,1,161,152,125,1,175,166, + 143,1,188,183,164,1,194,186,172,1,204,203,188,1,213,211,195,1,219,218, + 206,3,213,211,195,1,204,203,188,1,194,186,172,1,183,176,156,1,175,166, + 143,1,161,152,125,1,148,139,109,2,136,130,100,1,136,125,88,2,131,118, + 84,2,136,125,88,1,131,118,84,3,136,125,88,3,136,130,100,1,131,118, + 84,1,136,130,100,1,136,125,88,1,136,130,100,1,136,125,88,2,144,134, + 100,4,148,139,109,2,161,152,125,1,164,158,132,1,183,176,156,1,194,186, + 172,1,213,211,195,1,212,237,217,1,243,254,244,1,225,239,228,1,180,218, + 196,1,175,198,183,1,146,194,165,1,131,177,148,1,133,183,157,1,131,177, + 148,1,120,176,139,1,123,183,147,2,149,209,171,1,191,216,185,1,210,250, + 218,2,191,216,185,1,120,168,132,1,120,149,116,1,102,139,110,1,120,168, + 132,1,176,226,194,1,143,224,183,1,17,121,86,1,44,202,180,1,29,237, + 208,1,18,226,208,1,29,237,208,1,36,225,183,1,11,177,130,1,8,116, + 66,1,70,152,110,1,146,194,165,1,225,239,228,1,225,228,214,1,201,197, + 180,1,175,166,143,1,156,146,116,1,136,130,100,1,136,125,88,1,124,114, + 76,2,131,118,84,1,124,114,76,1,131,118,84,2,136,125,88,1,131,118, + 84,1,136,125,88,1,136,130,100,1,144,134,100,1,156,146,116,1,161,152, + 125,1,175,166,143,1,188,183,164,1,201,197,180,1,213,211,195,1,225,228, + 214,1,237,240,229,1,243,254,244,3,240,251,235,1,225,239,228,1,219,218, + 206,1,204,203,188,1,194,186,172,1,175,166,143,1,161,152,125,1,156,146, + 116,1,144,134,100,1,136,130,100,1,136,125,88,2,131,118,84,4,136,125, + 88,1,136,130,100,1,131,118,84,2,136,125,88,2,136,130,100,1,136,125, + 88,3,136,130,100,1,136,125,88,2,144,134,100,1,136,130,100,2,148,139, + 109,2,156,146,116,1,164,158,132,2,183,176,156,1,194,186,172,1,204,203, + 188,1,225,228,214,1,240,251,235,2,212,237,217,1,180,218,196,1,146,194, + 165,1,131,177,148,1,120,168,132,1,100,150,112,1,72,138,92,2,51,128, + 85,2,72,138,92,1,87,160,116,1,120,176,139,1,128,191,155,1,122,198, + 164,1,123,183,147,1,15,130,100,1,36,158,132,1,64,238,200,1,18,226, + 208,1,13,215,208,1,29,237,208,2,18,195,149,1,12,136,83,1,34,137, + 95,1,123,183,147,1,193,220,204,1,243,254,244,1,213,211,195,1,183,176, + 156,1,161,152,125,1,144,134,100,1,136,125,88,1,131,118,84,1,124,114, + 76,1,131,118,84,1,124,114,76,1,136,125,88,2,131,118,84,2,136,125, + 88,1,136,130,100,1,144,134,100,1,148,139,109,1,161,152,125,1,164,158, + 132,1,183,176,156,1,204,203,188,1,225,228,214,1,240,251,235,2,212,237, + 217,1,193,220,204,1,180,218,196,2,188,234,204,1,225,239,228,1,243,254, + 244,1,225,239,228,1,219,218,206,1,201,197,180,1,183,176,156,1,164,158, + 132,1,156,146,116,1,148,139,109,1,136,125,88,3,131,118,84,5,136,125, + 88,1,131,118,84,1,136,125,88,2,131,118,84,1,136,125,88,1,136,130, + 100,1,136,125,88,1,136,130,100,3,136,125,88,1,144,134,100,1,148,139, + 109,1,136,130,100,1,148,139,109,3,161,152,125,2,175,166,143,1,183,176, + 156,1,188,183,164,1,175,198,183,1,213,211,195,1,237,240,229,1,243,254, + 244,1,225,239,228,1,180,218,196,1,157,204,180,1,120,176,139,1,87,160, + 116,1,60,141,100,1,37,124,76,1,8,116,66,1,11,125,74,1,30,136, + 84,1,9,160,109,1,34,164,113,1,11,177,130,1,22,199,164,1,40,226, + 207,2,13,215,208,2,18,226,208,1,43,249,210,1,22,199,164,1,11,150, + 100,1,11,125,74,1,95,171,130,1,157,204,180,1,219,251,232,1,219,218, + 206,1,196,191,171,1,175,166,143,1,148,139,109,1,144,134,100,1,136,125, + 88,1,131,118,84,1,136,125,88,1,131,118,84,1,136,125,88,1,131,118, + 84,1,136,125,88,1,131,118,84,1,136,130,100,1,136,125,88,1,144,134, + 100,1,148,139,109,1,156,146,116,1,164,158,132,1,183,176,156,1,204,203, + 188,1,219,218,206,1,243,254,244,1,212,237,217,1,170,213,186,1,146,194, + 165,1,97,184,143,1,95,171,130,1,120,176,139,1,128,191,155,1,146,192, + 155,1,170,213,186,1,225,239,228,1,243,254,244,1,225,228,214,1,204,203, + 188,1,188,183,164,1,164,158,132,1,142,147,115,1,148,139,109,1,136,125, + 88,1,136,130,100,1,131,118,84,5,136,125,88,2,136,130,100,1,136,125, + 88,5,136,130,100,1,136,125,88,1,136,130,100,1,144,134,100,2,136,130, + 100,1,144,134,100,1,148,139,109,1,136,130,100,1,148,139,109,2,156,146, + 116,2,161,152,125,1,164,158,132,1,175,166,143,1,188,183,164,1,194,186, + 172,1,213,211,195,1,225,228,214,1,243,254,244,1,237,240,229,1,173,226, + 206,1,152,201,171,1,123,183,147,1,87,160,116,1,51,136,90,1,8,116, + 66,1,12,136,83,1,9,160,109,1,32,183,128,1,41,220,172,1,43,249, + 210,1,29,237,208,1,18,226,208,2,29,237,208,1,43,238,223,1,18,195, + 149,1,9,160,109,1,11,125,74,1,70,152,110,1,146,194,165,1,212,237, + 217,1,240,251,235,1,213,211,195,1,183,176,156,1,161,152,125,1,148,139, + 109,1,136,125,88,2,131,118,84,3,136,125,88,5,136,130,100,2,148,139, + 109,1,161,152,125,1,175,166,143,1,194,186,172,1,219,218,206,1,240,251, + 235,1,212,237,217,1,157,204,180,1,95,171,130,1,30,143,118,1,17,121, + 86,1,8,116,66,1,15,109,66,1,11,125,74,1,36,151,114,1,91,164, + 127,1,122,198,164,1,180,218,196,1,219,251,232,1,225,239,228,1,213,211, + 195,1,188,183,164,1,157,165,141,1,156,146,116,1,148,139,109,1,136,130, + 100,2,131,118,84,1,136,125,88,3,131,118,84,1,136,125,88,3,136,130, + 100,2,148,139,109,1,136,130,100,1,148,139,109,1,136,130,100,1,144,134, + 100,1,148,139,109,6,156,146,116,1,148,139,109,2,156,146,116,1,144,134, + 100,1,156,146,116,2,161,152,125,1,164,158,132,1,183,176,156,1,194,186, + 172,1,204,203,188,1,225,228,214,1,237,240,229,1,240,251,235,1,199,228, + 209,1,157,204,180,1,133,183,157,1,87,160,116,1,54,147,99,1,8,116, + 66,1,8,140,93,1,32,183,128,1,28,213,162,1,40,236,193,1,29,237, + 208,2,36,225,183,1,18,195,149,1,11,150,100,1,8,116,66,1,54,147, + 99,1,128,191,155,1,180,218,196,1,243,254,244,1,219,218,206,1,194,186, + 172,1,175,166,143,1,156,146,116,1,144,134,100,2,131,118,84,1,136,125, + 88,2,131,118,84,1,136,125,88,1,131,118,84,1,136,125,88,3,144,134, + 100,1,148,139,109,1,156,146,116,1,164,158,132,1,183,176,156,1,201,197, + 180,1,237,240,229,1,225,239,228,1,157,204,180,1,95,171,130,1,11,125, + 74,1,8,140,93,1,16,181,140,1,40,196,164,1,39,186,167,1,30,172, + 142,1,11,150,100,1,18,115,76,1,54,147,99,1,99,173,140,1,157,204, + 180,1,212,237,217,1,240,251,235,1,219,218,206,1,196,191,171,1,183,176, + 156,1,161,152,125,1,148,139,109,2,136,130,100,3,136,125,88,1,136,130, + 100,3,144,134,100,1,148,139,109,1,136,130,100,1,148,139,109,1,136,130, + 100,1,148,139,109,4,164,158,132,3,161,152,125,4,142,147,115,1,148,139, + 109,3,136,130,100,1,148,139,109,1,156,146,116,1,161,152,125,1,164,158, + 132,1,175,166,143,1,188,183,164,1,201,197,180,1,225,228,214,1,225,239, + 228,1,243,254,244,1,212,237,217,1,170,213,186,1,128,191,155,1,95,171, + 130,1,34,137,95,1,15,109,66,1,8,140,93,1,10,166,125,1,11,177, + 130,2,9,160,109,1,8,140,93,1,11,125,74,1,70,152,110,1,131,177, + 148,1,170,213,186,1,237,240,229,1,230,237,219,1,204,203,188,1,183,176, + 156,1,161,152,125,1,156,146,116,1,144,134,100,1,136,125,88,7,136,130, + 100,1,136,125,88,1,136,130,100,1,144,134,100,2,161,152,125,1,164,158, + 132,1,194,186,172,1,213,211,195,1,240,251,235,1,199,228,209,1,133,183, + 157,1,34,137,95,1,6,151,109,1,48,214,186,1,56,226,220,1,17,203, + 215,1,56,206,220,1,43,238,223,1,36,225,183,1,11,177,130,1,12,136, + 83,1,37,124,76,1,87,160,116,1,146,192,155,1,199,228,209,1,240,251, + 235,1,225,228,214,1,204,203,188,1,188,183,164,1,157,165,141,1,161,152, + 125,1,156,146,116,1,148,139,109,7,156,146,116,3,161,152,125,1,140,152, + 126,1,161,152,125,1,140,152,126,1,161,152,125,1,183,176,156,5,175,166, + 143,1,157,165,141,1,175,166,143,1,161,152,125,2,148,139,109,3,136,130, + 100,2,148,139,109,1,156,146,116,1,164,158,132,1,175,166,143,1,188,183, + 164,1,196,191,171,1,213,211,195,1,230,237,219,1,243,254,244,1,225,239, + 228,1,180,218,196,1,146,194,165,1,99,173,140,1,66,145,110,1,24,129, + 86,1,11,125,74,3,34,137,95,1,91,164,127,1,123,183,147,1,148,214, + 196,1,225,239,228,1,237,240,229,1,219,218,206,1,194,186,172,1,175,166, + 143,1,161,152,125,1,136,130,100,1,144,134,100,1,136,125,88,5,136,130, + 100,1,136,125,88,3,144,134,100,1,136,130,100,1,148,139,109,1,161,152, + 125,1,171,176,148,1,196,191,171,1,225,228,214,1,243,254,244,1,170,213, + 186,1,91,164,127,1,8,116,66,1,36,181,146,1,60,218,228,1,7,151, + 199,1,5,116,187,2,4,159,196,1,28,216,220,1,46,237,209,1,18,195, + 149,1,11,150,100,1,8,116,66,1,54,147,99,1,123,183,147,1,170,213, + 186,1,219,251,232,1,237,240,229,1,219,218,206,1,201,197,180,1,183,176, + 156,1,175,166,143,2,164,158,132,4,157,165,141,1,164,158,132,1,157,165, + 141,1,175,166,143,2,183,176,156,1,175,166,143,1,183,176,156,3,219,218, + 206,1,213,211,195,1,219,218,206,1,213,211,195,2,204,203,188,1,201,197, + 180,1,196,191,171,1,183,176,156,1,175,166,143,1,164,158,132,1,156,146, + 116,1,148,139,109,1,136,130,100,1,148,139,109,1,136,130,100,1,144,134, + 100,1,136,130,100,1,156,146,116,1,161,152,125,1,175,166,143,1,183,176, + 156,1,194,186,172,1,213,211,195,1,225,228,214,1,240,251,235,1,219,251, + 232,1,188,234,204,1,166,203,172,1,128,191,155,1,97,184,143,1,99,173, + 140,1,123,183,147,1,133,183,157,1,152,201,171,1,193,220,204,1,237,240, + 229,1,240,251,235,1,225,228,214,1,196,191,171,1,183,176,156,1,164,158, + 132,1,156,146,116,1,148,139,109,1,144,134,100,1,136,125,88,1,144,134, + 100,1,136,125,88,5,144,134,100,1,136,125,88,1,144,134,100,1,148,139, + 109,1,156,146,116,1,164,158,132,1,175,166,143,1,201,197,180,1,237,240, + 229,1,225,239,228,1,149,209,171,1,70,152,110,1,12,136,83,1,48,214, + 186,1,19,189,215,1,5,116,187,1,4,66,167,2,4,154,180,1,60,218, + 228,1,80,220,208,1,46,211,164,1,35,176,126,1,22,148,91,1,8,116, + 66,1,51,136,90,1,120,168,132,1,168,197,172,1,199,228,209,1,240,251, + 235,1,237,240,229,1,225,228,214,1,204,203,188,1,201,197,180,2,194,186, + 172,2,196,191,171,4,201,197,180,1,204,203,188,3,213,211,195,3,240,251, + 235,1,243,254,244,1,219,251,232,1,243,254,244,3,225,239,228,1,225,228, + 214,1,213,211,195,1,196,191,171,1,183,176,156,1,164,158,132,1,161,152, + 125,1,144,134,100,1,148,139,109,1,136,125,88,1,136,130,100,2,144,134, + 100,2,156,146,116,2,164,158,132,1,171,176,148,1,188,183,164,1,204,203, + 188,1,220,226,195,1,237,240,229,1,243,254,244,1,225,239,228,1,199,228, + 209,1,193,220,204,2,199,228,209,1,225,239,228,1,243,254,244,1,237,240, + 229,1,219,218,206,1,201,197,180,1,183,176,156,1,175,166,143,1,161,152, + 125,1,148,139,109,1,136,130,100,1,148,139,109,1,144,134,100,1,136,130, + 100,1,144,134,100,1,136,125,88,1,136,130,100,2,136,125,88,1,136,130, + 100,1,136,125,88,1,144,134,100,1,148,139,109,2,164,158,132,1,183,176, + 156,1,204,203,188,1,225,228,214,1,237,240,229,1,140,202,184,1,70,152, + 110,1,8,140,93,1,48,214,186,1,19,189,215,1,5,116,187,1,4,66, + 167,1,5,116,187,1,68,188,196,1,17,121,86,1,34,137,95,1,17,121, + 86,1,15,109,66,2,63,106,73,1,51,128,85,1,66,145,110,1,120,176, + 139,1,146,194,165,1,180,218,196,1,212,237,217,1,220,254,244,1,243,254, + 244,1,237,240,229,2,225,239,228,2,225,228,214,1,225,239,228,1,237,240, + 229,1,240,251,235,3,243,254,244,5,152,201,171,1,168,197,172,1,146,194, + 165,1,152,201,171,1,177,204,185,1,191,216,185,1,199,228,209,1,212,237, + 217,1,243,254,244,1,230,237,219,1,213,211,195,1,196,191,171,1,175,166, + 143,1,164,158,132,1,148,139,109,1,144,134,100,1,136,125,88,1,136,130, + 100,1,131,118,84,1,136,125,88,1,136,130,100,1,144,134,100,1,148,139, + 109,1,156,146,116,1,164,158,132,1,171,176,148,1,183,176,156,1,201,197, + 180,1,219,218,206,1,225,228,214,1,237,240,229,1,240,251,235,3,237,240, + 229,1,225,228,214,1,219,218,206,1,201,197,180,1,188,183,164,1,175,166, + 143,1,161,152,125,1,156,146,116,1,148,139,109,2,144,134,100,3,136,125, + 88,1,136,130,100,1,136,125,88,1,144,134,100,1,136,125,88,1,144,134, + 100,1,136,125,88,1,144,134,100,2,156,146,116,1,164,158,132,1,175,166, + 143,1,204,203,188,1,225,239,228,2,157,204,180,1,70,152,110,1,12,136, + 83,1,44,202,180,1,56,206,220,1,4,154,180,1,5,116,187,1,92,210, + 252,1,124,202,196,1,128,191,155,1,120,176,139,1,149,209,171,1,210,250, + 218,1,188,250,211,1,143,224,183,1,122,198,164,1,128,191,155,1,146,192, + 155,2,175,198,183,1,177,204,185,1,213,211,195,1,199,228,209,1,193,220, + 204,1,225,239,228,1,225,228,214,1,199,228,209,1,225,239,228,1,219,218, + 206,1,199,228,209,2,193,220,204,1,192,216,196,3,170,213,186,1,177,204, + 185,2,87,160,116,2,70,152,110,1,100,150,112,1,70,152,110,1,87,160, + 116,1,120,176,139,1,146,192,155,1,170,213,186,1,230,237,219,1,240,251, + 235,1,219,218,206,1,196,191,171,1,175,166,143,1,156,146,116,1,148,139, + 109,1,136,125,88,1,131,118,84,1,136,125,88,1,131,118,84,2,136,125, + 88,2,144,134,100,2,156,146,116,1,161,152,125,1,169,167,132,1,171,176, + 148,1,188,183,164,1,201,197,180,1,213,211,195,3,204,203,188,2,194,186, + 172,1,183,176,156,1,175,166,143,1,164,158,132,1,161,152,125,1,156,146, + 116,1,148,139,109,2,144,134,100,1,136,125,88,1,144,134,100,3,136,125, + 88,1,136,130,100,1,136,125,88,1,136,130,100,1,144,134,100,2,148,139, + 109,1,156,146,116,1,161,152,125,1,183,176,156,1,201,197,180,1,225,228, + 214,1,240,251,235,1,170,213,186,1,73,159,115,1,8,116,66,1,16,181, + 140,1,43,238,223,1,7,191,203,1,9,176,194,1,68,188,196,1,186,254, + 239,1,21,58,27,1,124,160,128,1,51,128,85,1,21,58,27,1,56,84, + 51,1,87,116,86,1,124,160,128,1,169,195,161,1,220,226,195,1,240,251, + 235,2,230,237,219,1,219,218,206,1,193,220,204,1,204,203,188,1,177,204, + 185,2,168,197,172,2,146,194,165,1,150,185,158,1,131,177,148,1,123,183, + 147,1,120,176,139,2,120,168,132,1,95,171,130,1,120,168,132,1,91,164, + 127,1,72,138,92,1,51,128,85,1,72,138,92,1,51,128,85,1,37,124, + 76,2,51,136,90,1,72,138,92,1,91,164,127,1,146,192,155,1,193,220, + 204,1,243,254,244,1,225,228,214,1,194,186,172,1,175,166,143,1,156,146, + 116,1,144,134,100,1,136,125,88,1,131,118,84,1,124,114,76,3,136,125, + 88,1,131,118,84,1,136,125,88,2,148,139,109,1,156,146,116,1,161,152, + 125,1,164,158,132,1,175,166,143,1,183,176,156,1,188,183,164,3,183,176, + 156,3,175,166,143,1,161,152,125,2,156,146,116,1,148,139,109,2,136,130, + 100,1,148,139,109,2,136,125,88,1,136,130,100,1,148,139,109,1,136,125, + 88,1,144,134,100,1,136,125,88,1,144,134,100,1,136,130,100,1,148,139, + 109,2,164,158,132,1,175,166,143,1,196,191,171,1,225,228,214,1,243,254, + 244,1,180,218,196,1,120,176,139,1,12,136,83,1,6,151,109,1,43,227, + 196,1,18,226,208,1,13,215,208,1,39,186,167,1,220,254,244,1,41,57, + 22,1,219,251,232,1,243,254,244,1,210,250,218,1,188,234,204,1,170,213, + 186,1,124,160,128,1,80,102,76,1,45,61,37,1,62,76,54,1,99,127, + 96,1,140,152,126,1,169,195,161,1,190,225,195,1,219,251,232,2,199,228, + 209,1,192,216,196,1,166,203,172,1,146,192,155,2,150,185,158,1,131,177, + 148,1,120,168,132,3,124,160,128,1,120,168,132,1,87,160,116,1,207,237, + 201,1,176,226,194,1,170,213,186,1,146,192,155,1,120,176,139,1,102,139, + 110,1,37,124,76,2,51,128,85,1,87,160,116,1,123,183,147,1,190,225, + 195,1,243,254,244,1,225,228,214,1,194,186,172,1,164,158,132,1,148,139, + 109,1,136,125,88,1,131,118,84,1,124,114,76,1,122,109,68,1,124,114, + 76,1,122,109,68,1,124,114,76,2,136,125,88,1,131,118,84,1,136,125, + 88,1,156,146,116,1,148,139,109,1,161,152,125,1,164,158,132,2,183,176, + 156,1,175,166,143,1,183,176,156,2,164,158,132,3,161,152,125,1,156,146, + 116,1,148,139,109,3,136,130,100,1,144,134,100,4,136,125,88,1,136,130, + 100,1,136,125,88,1,144,134,100,3,148,139,109,1,161,152,125,1,169,167, + 132,1,188,183,164,1,219,218,206,1,240,251,235,1,212,237,217,1,146,194, + 165,1,70,152,110,1,11,125,74,1,18,195,149,1,43,249,210,1,29,237, + 208,1,40,196,164,1,188,234,204,1,31,64,36,1,190,246,220,1,243,254, + 244,6,188,250,211,1,173,226,206,1,146,194,165,1,68,136,108,1,31,64, + 36,1,46,73,42,1,86,108,72,1,136,130,100,1,140,152,126,1,169,195, + 161,1,198,204,170,1,225,228,214,1,232,248,219,2,240,251,235,7,80,102, + 76,1,86,108,84,1,99,127,96,1,124,160,128,1,152,201,171,1,219,251, + 232,1,149,209,171,1,87,160,116,1,51,128,85,2,100,150,112,1,133,183, + 157,1,192,216,196,1,243,254,244,1,213,211,195,1,188,183,164,1,161,152, + 125,1,136,130,100,1,131,118,84,1,122,109,68,3,114,102,60,1,122,109, + 68,2,124,114,76,2,131,118,84,2,144,134,100,2,156,146,116,1,164,158, + 132,2,183,176,156,1,175,166,143,2,183,176,156,1,175,166,143,1,164,158, + 132,2,161,152,125,1,156,146,116,2,148,139,109,2,144,134,100,2,136,130, + 100,1,148,139,109,1,144,134,100,1,136,125,88,1,144,134,100,1,136,125, + 88,1,144,134,100,2,148,139,109,1,156,146,116,1,164,158,132,1,188,183, + 164,1,204,203,188,1,225,228,214,1,240,251,235,1,170,213,186,1,99,173, + 140,1,24,129,86,1,9,160,109,1,41,220,172,1,43,249,210,1,43,202, + 153,1,176,226,194,1,46,73,42,1,190,246,220,1,243,254,244,9,210,250, + 218,1,243,254,244,1,188,234,204,1,166,203,172,1,150,185,158,1,102,139, + 110,1,80,97,65,1,41,57,22,1,31,64,36,1,45,61,37,1,62,76, + 54,3,62,86,60,1,62,76,54,3,46,73,42,1,173,226,206,2,122,198, + 164,1,126,170,142,1,56,84,51,1,64,96,66,1,126,170,142,1,240,251, + 235,1,146,192,155,1,66,145,110,1,60,141,100,1,91,164,127,1,146,194, + 165,1,199,228,209,1,240,251,235,1,201,197,180,1,164,158,132,1,148,139, + 109,1,131,118,84,1,122,109,68,1,114,102,60,7,124,114,76,2,136,130, + 100,1,148,139,109,1,161,152,125,1,164,158,132,1,183,176,156,1,188,183, + 164,2,194,186,172,1,188,183,164,1,183,176,156,2,175,166,143,1,164,158, + 132,1,161,152,125,1,156,146,116,1,148,139,109,2,136,130,100,1,144,134, + 100,2,136,125,88,1,144,134,100,1,136,125,88,1,144,134,100,1,136,125, + 88,1,144,134,100,2,148,139,109,1,156,146,116,1,161,152,125,1,175,166, + 143,1,196,191,171,1,219,218,206,1,240,251,235,1,212,237,217,1,146,194, + 165,1,70,152,110,1,8,116,66,1,11,177,130,1,41,220,172,1,36,181, + 146,1,143,224,183,1,56,84,51,1,190,246,220,1,243,254,244,17,190,246, + 220,3,164,234,212,4,190,246,220,1,182,245,228,2,243,254,244,4,219,251, + 232,1,170,213,186,1,64,96,66,1,86,108,72,1,166,203,172,1,188,234, + 204,1,120,176,139,1,124,160,128,1,131,177,148,1,177,204,185,1,237,240, + 229,1,225,228,214,1,183,176,156,1,148,139,109,1,136,125,88,1,122,109, + 68,1,107,96,52,1,101,87,41,4,107,96,52,1,114,102,60,2,124,114, + 76,1,131,118,84,1,156,146,116,1,164,158,132,1,183,176,156,1,196,191, + 171,1,201,197,180,1,213,211,195,1,204,203,188,2,201,197,180,1,194,186, + 172,1,188,183,164,1,175,166,143,1,164,158,132,1,161,152,125,1,156,146, + 116,1,148,139,109,2,144,134,100,3,136,125,88,1,144,134,100,1,136,125, + 88,1,136,130,100,1,136,125,88,1,144,134,100,3,156,146,116,1,164,158, + 132,1,171,176,148,1,201,197,180,1,219,218,206,1,243,254,244,1,180,218, + 196,1,123,183,147,1,60,141,100,1,12,136,83,1,32,183,128,1,22,148, + 91,1,188,234,204,1,46,73,42,1,190,246,220,1,243,254,244,33,179,236, + 213,1,133,183,157,1,46,73,42,1,140,152,126,1,210,250,218,1,192,216, + 196,1,168,197,172,1,175,198,183,1,230,237,219,1,237,240,229,1,196,191, + 171,1,161,152,125,1,131,118,84,1,114,102,60,1,101,87,41,2,88,75, + 26,1,101,87,41,4,114,102,60,1,124,114,76,1,144,134,100,1,140,152, + 126,1,183,176,156,1,201,197,180,1,219,218,206,1,237,240,229,2,240,251, + 235,1,225,239,228,1,219,218,206,1,213,211,195,1,201,197,180,1,183,176, + 156,1,175,166,143,1,164,158,132,1,156,146,116,2,148,139,109,1,136,130, + 100,1,144,134,100,2,136,125,88,1,144,134,100,1,136,125,88,1,144,134, + 100,2,136,125,88,1,148,139,109,1,144,134,100,1,148,139,109,1,161,152, + 125,1,164,158,132,1,188,183,164,1,201,197,180,1,230,237,219,1,240,251, + 235,1,180,218,196,1,95,171,130,1,24,129,86,1,37,124,76,2,232,248, + 219,1,21,58,27,1,243,254,244,36,188,234,204,1,68,115,88,1,81,88, + 63,1,126,170,142,1,212,237,217,1,243,254,244,1,240,251,235,1,230,237, + 219,1,196,191,171,1,156,146,116,1,122,109,68,1,107,96,52,1,88,75, + 26,1,71,73,27,2,69,65,21,2,88,75,26,1,101,87,41,1,107,96, + 52,1,124,114,76,1,148,139,109,1,183,176,156,1,213,211,195,1,240,251, + 235,1,219,251,232,1,225,239,228,1,199,228,209,1,225,239,228,1,237,240, + 229,1,243,254,244,1,225,239,228,1,219,218,206,1,201,197,180,1,188,183, + 164,1,175,166,143,1,164,158,132,1,156,146,116,1,148,139,109,1,144,134, + 100,2,136,125,88,1,144,134,100,1,136,130,100,1,136,125,88,1,136,130, + 100,1,136,125,88,3,144,134,100,2,148,139,109,1,156,146,116,1,164,158, + 132,1,188,183,164,1,204,203,188,1,225,239,228,1,219,251,232,1,170,213, + 186,1,120,168,132,1,54,147,99,1,123,183,147,1,169,195,161,1,87,116, + 86,1,243,254,244,38,157,204,180,1,64,96,66,1,62,86,60,1,120,139, + 109,1,164,158,132,1,169,167,132,1,156,146,116,1,136,125,88,1,114,102, + 60,1,88,75,26,1,65,60,12,2,69,65,21,2,65,60,12,2,71,73, + 27,1,101,87,41,1,124,114,76,1,164,158,132,1,213,211,195,1,240,251, + 235,1,176,226,194,1,152,201,171,1,123,183,147,1,128,191,155,1,146,194, + 165,1,170,213,186,1,199,228,209,1,240,251,235,1,237,240,229,1,219,218, + 206,1,194,186,172,1,183,176,156,1,164,158,132,1,156,146,116,1,148,139, + 109,1,136,130,100,1,144,134,100,2,136,125,88,1,136,130,100,1,136,125, + 88,7,144,134,100,1,148,139,109,1,156,146,116,1,164,158,132,1,175,166, + 143,1,201,197,180,1,220,226,195,1,243,254,244,1,192,216,196,1,175,198, + 183,1,232,248,219,1,99,127,96,1,168,197,172,1,243,254,244,39,219,251, + 232,1,180,218,196,1,124,160,128,1,56,84,51,1,41,57,22,1,45,62, + 27,1,41,57,22,1,45,62,27,1,114,102,60,1,99,127,96,1,142,147, + 115,1,124,160,128,1,100,150,112,1,106,138,100,1,107,96,52,1,41,57, + 22,1,88,75,26,1,131,118,84,1,171,176,148,1,240,251,235,1,157,204, + 180,1,104,150,124,1,51,136,90,1,11,125,74,1,30,136,84,1,70,152, + 110,1,99,173,140,1,152,201,171,1,193,220,204,1,243,254,244,1,230,237, + 219,1,213,211,195,1,194,186,172,1,175,166,143,1,161,152,125,1,156,146, + 116,1,148,139,109,1,144,134,100,1,136,125,88,1,144,134,100,1,136,125, + 88,4,131,118,84,1,136,125,88,5,144,134,100,2,156,146,116,1,164,158, + 132,1,188,183,164,1,213,211,195,1,230,237,219,1,232,248,219,1,150,185, + 158,1,21,58,27,1,188,250,211,1,243,254,244,38,164,234,212,1,243,254, + 244,4,188,250,211,1,190,246,220,4,243,254,244,3,190,246,220,1,173,226, + 206,1,146,194,165,1,120,149,116,1,41,57,22,1,107,96,52,1,171,176, + 148,1,240,251,235,1,120,168,132,1,8,116,66,1,9,160,109,1,34,164, + 113,1,11,150,100,1,8,116,66,1,30,136,84,1,95,171,130,1,149,209, + 171,1,225,228,214,1,243,254,244,1,225,228,214,1,194,186,172,1,175,166, + 143,1,164,158,132,1,156,146,116,1,144,134,100,2,136,130,100,1,136,125, + 88,6,124,114,76,1,131,118,84,3,136,125,88,1,131,118,84,1,136,125, + 88,1,136,130,100,1,144,134,100,1,148,139,109,1,161,152,125,1,157,165, + 141,1,164,158,132,1,64,96,66,1,131,177,148,1,243,254,244,54,188,250, + 211,1,243,254,244,1,170,213,186,1,80,97,65,1,80,102,76,1,192,216, + 196,1,123,183,147,1,34,137,95,1,46,211,164,1,40,236,193,1,28,213, + 162,1,11,177,130,1,11,125,74,1,34,137,95,1,120,176,139,1,148,214, + 196,1,237,240,229,1,225,239,228,1,204,203,188,1,183,176,156,1,164,158, + 132,1,156,146,116,1,148,139,109,1,144,134,100,1,136,125,88,1,136,130, + 100,1,136,125,88,1,131,118,84,1,136,125,88,2,131,118,84,1,136,125, + 88,2,124,114,76,4,122,109,68,5,114,102,60,1,84,84,41,1,95,117, + 76,1,243,254,244,58,188,250,211,1,102,139,110,1,87,116,86,1,219,251, + 232,1,34,137,95,1,41,220,172,1,46,237,209,1,41,247,222,1,21,213, + 172,1,16,169,116,1,8,116,66,1,73,159,115,1,146,194,165,1,212,237, + 217,1,243,254,244,1,213,211,195,1,188,183,164,1,164,158,132,1,156,146, + 116,1,144,134,100,2,136,125,88,2,131,118,84,1,136,125,88,2,124,114, + 76,1,136,125,88,1,124,114,76,1,131,118,84,1,136,125,88,1,124,114, + 76,1,122,109,68,3,114,102,60,1,107,96,52,1,101,87,41,2,65,60, + 12,1,86,108,72,1,180,218,196,1,243,254,244,59,190,246,220,1,99,127, + 96,1,106,138,100,1,124,214,180,1,30,172,142,1,29,237,208,1,18,226, + 208,1,43,249,210,1,18,195,149,1,12,136,83,1,34,137,95,1,123,183, + 147,1,193,220,204,1,243,254,244,1,219,218,206,1,196,191,171,1,175,166, + 143,1,156,146,116,1,144,134,100,2,136,125,88,4,131,118,84,1,136,125, + 88,1,131,118,84,1,136,125,88,1,124,114,76,3,122,109,68,2,114,102, + 60,1,107,96,52,1,101,87,41,1,88,75,26,1,65,60,12,1,101,87, + 41,1,120,168,132,1,243,254,244,1,182,245,228,1,243,254,244,59,176,226, + 194,1,21,58,27,1,170,213,186,1,24,129,86,1,71,239,220,1,18,226, + 208,1,29,237,208,1,26,216,182,1,16,169,116,1,11,125,74,1,95,171, + 130,1,170,213,186,1,243,254,244,1,219,218,206,1,196,191,171,1,164,158, + 132,1,156,146,116,1,148,139,109,1,136,125,88,4,131,118,84,3,136,125, + 88,1,122,109,68,1,131,118,84,1,124,114,76,1,122,109,68,2,114,102, + 60,1,107,96,52,1,101,87,41,2,65,60,12,2,95,117,76,1,149,209, + 171,1,243,254,244,60,182,245,228,1,243,254,244,1,133,183,157,1,87,116, + 86,1,143,224,183,1,39,186,167,1,16,214,196,1,18,226,208,1,41,247, + 222,1,11,177,130,1,8,116,66,1,73,159,115,1,157,204,180,1,219,251, + 232,1,225,228,214,1,194,186,172,1,175,166,143,1,156,146,116,1,136,130, + 100,2,131,118,84,4,136,125,88,1,131,118,84,2,136,125,88,1,124,114, + 76,3,122,109,68,1,114,102,60,1,107,96,52,1,101,87,41,1,88,75, + 26,1,69,65,21,1,65,60,12,1,99,127,96,1,154,213,186,1,243,254, + 244,62,173,226,206,1,21,58,27,1,188,234,204,1,16,110,76,1,46,237, + 209,1,13,215,208,1,43,238,223,1,20,203,154,1,12,136,83,1,54,147, + 99,1,146,194,165,1,225,239,228,1,225,228,214,1,196,191,171,1,175,166, + 143,1,148,139,109,1,144,134,100,1,136,125,88,1,136,130,100,1,124,114, + 76,1,136,125,88,1,131,118,84,3,122,109,68,1,124,114,76,2,122,109, + 68,2,114,102,60,2,107,96,52,1,101,87,41,1,87,78,36,1,88,75, + 26,1,65,60,12,1,95,117,76,1,152,201,171,1,243,254,244,63,124,160, + 128,1,100,150,112,1,97,184,143,1,68,218,191,1,13,215,208,1,29,237, + 208,1,36,225,183,1,11,150,100,1,34,137,95,1,128,191,155,1,212,237, + 217,1,225,239,228,1,196,191,171,1,175,166,143,1,148,139,109,1,136,130, + 100,1,136,125,88,1,124,114,76,1,136,125,88,1,124,114,76,1,131,118, + 84,1,124,114,76,1,131,118,84,1,136,125,88,1,124,114,76,3,122,109, + 68,2,114,102,60,1,107,96,52,2,88,75,26,2,65,60,12,1,107,96, + 52,1,123,183,147,1,243,254,244,63,190,225,195,1,56,84,51,1,186,254, + 239,1,36,151,114,1,40,226,207,1,29,237,208,1,43,227,196,1,16,169, + 116,1,11,125,74,1,123,183,147,1,212,237,217,1,230,237,219,1,196,191, + 171,1,157,165,141,1,148,139,109,1,144,134,100,1,131,118,84,2,124,114, + 76,1,131,118,84,1,124,114,76,1,131,118,84,1,124,114,76,4,122,109, + 68,2,114,102,60,2,101,87,41,2,87,78,36,1,88,75,26,1,69,65, + 21,2,124,160,128,1,190,246,220,1,243,254,244,63,80,102,76,1,123,183, + 147,1,104,150,124,1,43,227,196,1,29,237,208,1,40,236,193,1,11,177, + 130,1,11,125,74,1,97,184,143,1,199,228,209,1,225,239,228,1,196,191, + 171,1,164,158,132,1,148,139,109,1,136,125,88,1,131,118,84,1,124,114, + 76,1,131,118,84,1,124,114,76,1,131,118,84,1,124,114,76,4,122,109, + 68,3,114,102,60,2,107,96,52,2,101,87,41,2,88,75,26,1,65,60, + 12,1,87,116,86,1,188,250,211,1,243,254,244,63,140,202,184,1,80,102, + 76,1,188,234,204,1,10,166,125,1,63,249,210,1,43,249,210,1,11,177, + 130,1,11,125,74,1,95,171,130,1,199,228,209,1,230,237,219,1,196,191, + 171,1,164,158,132,1,144,134,100,1,131,118,84,2,124,114,76,7,122,109, + 68,1,124,114,76,1,122,109,68,2,114,102,60,3,107,96,52,1,101,87, + 41,3,84,84,41,1,46,73,42,1,188,234,204,1,243,254,244,63,182,245, + 228,1,56,84,51,1,146,192,155,1,36,151,114,1,46,211,164,1,36,225, + 183,1,18,195,149,1,8,116,66,1,95,171,130,1,199,228,209,1,230,237, + 219,1,188,183,164,1,161,152,125,1,144,134,100,1,131,118,84,1,124,114, + 76,5,136,125,88,1,122,109,68,1,124,114,76,3,114,102,60,1,122,109, + 68,1,114,102,60,2,107,96,52,2,114,102,60,2,107,96,52,2,41,57, + 22,1,188,234,204,1,243,254,244,64,146,194,165,1,63,106,73,1,188,250, + 211,1,24,129,86,1,43,202,153,1,32,183,128,1,11,125,74,1,87,160, + 116,1,173,226,206,1,230,237,219,1,194,186,172,1,156,146,116,1,136,130, + 100,1,131,118,84,1,122,109,68,1,124,114,76,1,122,109,68,1,124,114, + 76,1,122,109,68,2,124,114,76,1,122,109,68,4,114,102,60,6,124,114, + 76,1,136,125,88,1,114,102,60,1,41,57,22,1,188,234,204,1,182,245, + 228,1,243,254,244,63,210,250,218,1,64,96,66,1,120,176,139,1,97,184, + 143,1,11,150,100,1,11,177,130,1,8,116,66,1,91,164,127,1,199,228, + 209,1,230,237,219,1,183,176,156,1,156,146,116,1,131,118,84,1,124,114, + 76,1,122,109,68,10,114,102,60,4,122,109,68,2,131,118,84,1,136,125, + 88,1,144,134,100,1,124,114,76,1,46,73,42,1,210,250,218,1,243,254, + 244,30,15,0,0,0,248,255,255,255,31,240,127,0,12,0,0,0,63,1, + 0,0,248,255,255,255,31,252,255,161,15,0,0,0,255,0,0,0,240,255, + 255,255,31,254,255,195,15,0,0,0,255,3,0,0,232,255,255,255,143,255, + 255,239,15,0,0,0,255,7,0,0,192,255,255,255,143,255,255,255,15,0, + 0,0,255,15,0,0,128,255,255,255,231,255,255,255,15,0,0,0,255,63, + 0,0,0,254,255,255,195,255,255,255,15,0,0,0,255,127,0,0,0,252, + 255,255,225,255,255,255,15,0,0,0,255,127,1,0,0,128,255,255,224,255, + 255,255,15,0,0,0,255,255,0,0,0,0,252,127,232,255,255,255,15,0, + 0,0,255,255,1,0,0,0,224,31,240,255,255,255,11,0,0,0,255,255, + 5,0,0,0,0,7,240,255,253,255,7,0,0,0,254,255,3,0,0,0, + 0,0,240,127,255,255,15,0,0,0,255,255,3,0,0,0,0,0,224,223, + 255,255,15,0,0,0,247,255,3,0,0,0,0,0,224,255,255,255,15,0, + 0,0,159,255,3,0,0,0,0,0,224,255,255,255,15,0,0,0,255,235, + 3,0,0,0,0,0,192,255,255,255,15,0,0,0,255,255,1,0,0,0, + 0,0,128,255,255,255,15,0,0,0,255,255,3,0,0,0,0,0,0,255, + 255,255,15,0,0,0,255,255,1,0,0,0,0,0,128,254,255,255,15,0, + 0,0,255,255,1,0,0,0,0,0,0,254,255,255,15,0,0,0,255,255, + 3,0,0,32,0,0,0,254,255,255,15,0,0,0,255,255,3,0,0,0, + 0,0,0,252,255,255,15,0,0,0,255,255,7,0,0,0,0,0,0,252, + 255,255,15,0,0,0,255,255,15,0,0,0,0,0,0,252,255,255,15,0, + 0,0,255,255,7,0,7,0,0,0,0,252,255,255,15,0,0,0,255,255, + 7,240,127,0,0,0,0,252,255,255,15,0,0,0,255,255,7,248,255,1, + 0,0,0,253,255,255,15,0,0,0,255,255,7,254,255,1,0,0,0,252, + 255,255,15,0,0,0,255,255,3,255,255,3,0,0,0,252,207,255,15,0, + 0,0,255,255,7,255,255,7,0,0,0,252,255,254,15,0,0,0,255,255, + 1,255,191,7,0,0,0,248,255,247,15,0,0,0,255,255,129,255,223,7, + 0,0,0,248,255,239,15,0,0,0,255,255,128,255,255,7,0,0,0,240, + 255,255,15,0,0,0,255,127,128,255,255,15,0,0,0,224,255,127,15,0, + 0,0,255,127,128,191,255,95,0,0,0,192,255,255,14,0,0,0,255,63, + 128,255,255,63,0,0,0,192,255,255,13,0,0,0,255,31,128,255,255,127, + 1,0,0,244,255,255,13,0,0,0,255,15,0,255,255,255,0,0,0,254, + 255,255,15,0,0,0,255,7,0,255,255,255,0,0,144,255,255,255,15,0, + 0,0,255,0,0,255,255,255,0,0,224,255,255,255,1,0,0,0,0,0, + 0,255,255,255,0,0,248,255,255,7,0,0,0,0,0,0,0,255,255,223, + 1,0,252,255,255,15,0,0,0,0,2,0,0,255,255,255,0,64,255,255, + 255,47,4,0,0,0,3,0,0,255,255,255,0,128,255,255,255,255,15,0, + 0,0,7,0,128,255,255,127,0,224,255,255,255,255,15,0,0,0,15,0, + 0,255,255,239,0,248,255,255,251,255,7,0,0,0,31,0,0,255,255,63, + 0,255,255,255,255,255,15,0,0,0,63,0,0,254,255,63,240,255,255,127, + 255,255,15,0,0,0,255,0,0,252,255,95,253,255,255,255,255,255,15,0, + 0,0,255,0,0,248,255,15,255,255,255,239,255,255,15,0,0,0,255,0, + 0,240,255,239,255,255,255,251,255,255,15,0,0,0,255,1,0,192,255,241, + 255,255,255,254,255,255,11,0,0,0,255,1,0,0,0,248,255,255,191,255, + 255,255,15,0,0,0,255,7,0,0,0,252,255,255,247,255,255,255,15,0, + 0,0,255,3,0,0,0,255,255,255,252,255,255,255,7,0,0,0,255,7, + 0,0,128,255,255,207,255,255,255,255,15,0,0,0,254,15,0,0,224,255, + 255,254,255,255,255,255,15,0,0,0,255,31,0,0,240,255,239,255,255,255, + 255,255,15,0,0,0,253,31,0,0,250,255,255,255,255,255,255,255,15,0, + 0,0,255,31,0,0,252,255,255,255,255,255,255,255,15,0,0,0,255,63, + 0,0,255,255,255,255,255,255,255,255,15,0,0,0,255,255,1,128,255,255, + 255,255,255,255,255,255,15,0,0,0,255,255,175,234,255,255,255,255,255,255, + 255,255,15,0,0,0,255,255,255,241,255,255,255,255,255,255,255,255,15,0, + 0,0,127,255,255,255,255,251,255,255,255,255,255,255,15,0,0,0,255,253, + 255,255,255,255,255,255,199,255,255,255,15,0,0,0,255,255,255,255,255,253, + 255,255,255,254,255,255,15,0,0,0,255,191,255,255,255,255,255,127,255,251, + 255,255,15,0,0,0,255,255,254,255,255,255,255,255,255,255,255,255,15,0, + 0,0,255,255,255,255,127,255,255,255,255,255,255,255,15,0,0,0,255,255, + 223,255,255,255,255,255,255,255,255,255,15,0,0,0,255,255,127,255,255,255, + 255,223,255,255,255,255,15,0,0,0,255,255,255,255,255,255,255,255,255,255, + 255,255,15,0,0,0,197,255,255,239,247,255,255,255,255,255,239,127,0,0, + 0,0,255,254,255,255,255,255,255,255,255,255,255,255,15,0,0,0,255,255, + 255,255,255,255,255,255,255,255,255,255,15,0,0,0,255,247,255,255,255,255, + 255,223,255,253,255,255,15,0,0,0,255,239,255,255,255,255,255,255,255,129, + 255,255,15,0,0,0,255,223,255,255,255,255,255,255,255,1,244,255,15,0, + 0,0,255,255,255,255,255,255,255,255,255,1,0,252,15,0,0,0,240,255, + 255,255,255,255,255,127,255,1,0,0,0,0,0,0,192,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,223,255,255,191,255,255,255,255,0, + 0,0,0,0,0,0,0,252,255,255,255,255,255,255,251,0,0,0,0,0, + 0,0,0,248,255,255,255,254,255,255,255,0,0,0,0,0,0,0,0,132, + 143,255,255,253,255,255,127,0,0,0,0,0,0,0,0,0,0,250,255,255, + 255,255,63,0,0,0,0,0,0,0,0,0,0,240,255,251,255,255,63,0, + 0,0,0,0,0,0,0,0,0,224,255,251,255,255,95,0,0,0,0,0, + 0,0,0,0,0,192,255,251,255,255,31,0,0,0,0,0,0,0,0,0, + 0,160,255,255,255,255,31,0,0,0,0,0,0,0,0,0,0,128,255,255, + 255,255,31,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,31,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,255,63,0,0,0,0,0, + 0,0,0,0,0,0,254,255,255,255,63,0,0,0,0,0,0,0,0,0, + 0,0,254,255,255,255,63,0,0,0,0,0,0,0,0,0,0,0,254,255, + 255,255,63,0,0,0,0,0,0,0,0,0,0,0,252,255,255,255,127,0, + 0,0,0,0,0,0,0,0,0,0,252,255,255,255,63,0,0,0,0,0, + 0,0,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117, + 110,116,2,5,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46,105, + 116,101,109,115,1,2,0,5,205,204,204,204,204,204,204,204,252,63,5,0, + 0,0,0,0,0,0,128,254,63,5,205,204,204,204,204,204,204,204,254,63, + 2,1,0,21,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46, + 99,111,117,110,116,2,5,21,102,97,99,101,46,102,97,100,101,95,99,111, + 108,111,114,46,105,116,101,109,115,1,4,255,255,255,0,4,128,128,128,0, + 4,64,64,64,0,4,128,128,128,0,4,255,255,255,0,0,19,102,97,99, + 101,46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,5,103,100, + 95,117,112,15,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11, + 11,102,97,108,95,111,112,116,105,111,110,115,15,102,97,108,95,102,97,100, + 105,114,101,99,116,105,111,110,13,102,97,108,95,102,97,111,112,97,99,105, + 116,121,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,3,144,1,8,98,111,117,110,100,115,95,121,2,40,9,98,111, + 117,110,100,115,95,99,120,3,132,0,9,98,111,117,110,100,115,95,99,121, + 2,52,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105, + 108,101,49,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,11,116,115,116,114,105,110,103,101,100,105,116,12,116,115,116,114,105,110, + 103,101,100,105,116,56,5,99,111,108,111,114,4,3,0,0,128,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,102, + 114,97,109,101,105,95,108,101,102,116,2,4,18,102,114,97,109,101,46,102, + 114,97,109,101,105,95,114,105,103,104,116,2,4,21,102,114,97,109,101,46, + 102,114,97,109,101,105,109,97,103,101,95,108,105,115,116,7,4,105,109,108, + 105,28,102,114,97,109,101,46,102,114,97,109,101,105,109,97,103,101,95,111, + 102,102,115,101,116,109,111,117,115,101,2,8,30,102,114,97,109,101,46,102, + 114,97,109,101,105,109,97,103,101,95,111,102,102,115,101,116,99,108,105,99, + 107,101,100,2,8,29,102,114,97,109,101,46,102,114,97,109,101,105,109,97, + 103,101,95,111,102,102,115,101,116,97,99,116,105,118,101,2,24,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105, + 14,102,114,108,95,102,114,97,109,101,119,105,100,116,104,10,102,114,108,95, + 102,105,108,101,102,116,11,102,114,108,95,102,105,114,105,103,104,116,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,105,115,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,12,102,97,99,101, + 46,111,112,116,105,111,110,115,11,18,102,97,111,95,97,108,112,104,97,102, + 97,100,101,105,109,97,103,101,0,20,102,97,99,101,46,105,109,97,103,101, + 46,97,108,105,103,110,109,101,110,116,11,12,97,108,95,120,99,101,110,116, + 101,114,101,100,12,97,108,95,121,99,101,110,116,101,114,101,100,8,97,108, + 95,116,105,108,101,100,0,16,102,97,99,101,46,105,109,97,103,101,46,105, + 109,97,103,101,10,160,11,0,0,0,0,0,0,0,0,0,0,32,0,0, + 0,32,0,0,0,108,11,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,189,189,189,1,181,181,181,1,189,189,189,4,198,198,198,1,206,206,206, + 1,222,222,222,3,214,214,214,1,156,156,156,1,148,148,148,1,206,206,206, + 1,222,222,222,2,181,181,181,2,189,189,189,1,222,222,222,3,214,214,214, + 1,198,198,198,2,189,189,189,1,181,181,181,2,189,189,189,1,148,148,148, + 1,156,156,156,1,189,189,189,1,173,173,173,2,156,156,156,1,148,148,148, + 1,156,156,156,1,165,165,165,1,189,189,189,1,165,165,165,1,156,156,156, + 1,148,148,148,2,214,214,214,1,148,148,148,2,222,222,222,1,189,189,189, + 2,181,181,181,1,189,189,189,1,156,156,156,2,165,165,165,1,173,173,173, + 1,165,165,165,2,156,156,156,1,148,148,148,1,156,156,156,1,181,181,181, + 1,156,156,156,1,206,206,206,2,198,198,198,1,173,173,173,1,181,181,181, + 1,214,214,214,1,222,222,222,2,206,206,206,1,198,198,198,1,189,189,189, + 3,222,222,222,1,206,206,206,1,173,173,173,1,189,189,189,1,156,156,156, + 1,173,173,173,1,222,222,222,1,206,206,206,1,181,181,181,1,198,198,198, + 3,214,214,214,1,222,222,222,2,206,206,206,1,148,148,148,1,181,181,181, + 1,214,214,214,1,189,189,189,1,198,198,198,1,222,222,222,1,148,148,148, + 1,181,181,181,2,222,222,222,4,189,189,189,1,206,206,206,1,222,222,222, + 3,181,181,181,2,156,156,156,1,214,214,214,1,222,222,222,3,189,189,189, + 1,206,206,206,1,222,222,222,3,206,206,206,1,156,156,156,1,189,189,189, + 1,181,181,181,1,222,222,222,1,165,165,165,1,222,222,222,2,156,156,156, + 1,189,189,189,2,181,181,181,3,189,189,189,1,181,181,181,2,189,189,189, + 1,181,181,181,1,206,206,206,1,214,214,214,1,156,156,156,1,181,181,181, + 1,222,222,222,1,189,189,189,1,181,181,181,1,189,189,189,1,181,181,181, + 2,189,189,189,1,181,181,181,2,156,156,156,1,148,148,148,1,156,156,156, + 1,181,181,181,1,222,222,222,3,198,198,198,1,165,165,165,1,222,222,222, + 1,181,181,181,1,189,189,189,1,165,165,165,1,156,156,156,6,189,189,189, + 2,173,173,173,1,148,148,148,1,222,222,222,1,156,156,156,1,148,148,148, + 1,156,156,156,5,173,173,173,1,156,156,156,1,206,206,206,1,181,181,181, + 1,148,148,148,1,222,222,222,3,181,181,181,1,148,148,148,1,222,222,222, + 1,206,206,206,1,148,148,148,2,214,214,214,1,222,222,222,6,165,165,165, + 2,189,189,189,1,198,198,198,1,222,222,222,6,189,189,189,3,222,222,222, + 1,189,189,189,1,148,148,148,1,222,222,222,3,173,173,173,1,148,148,148, + 1,222,222,222,2,189,189,189,1,181,181,181,2,214,214,214,1,222,222,222, + 3,165,165,165,1,214,214,214,1,156,156,156,1,189,189,189,1,156,156,156, + 1,181,181,181,2,189,189,189,1,222,222,222,3,198,198,198,1,156,156,156, + 1,165,165,165,1,222,222,222,2,198,198,198,1,173,173,173,1,206,206,206, + 1,222,222,222,2,148,148,148,1,181,181,181,1,222,222,222,2,189,189,189, + 1,165,165,165,1,156,156,156,1,181,181,181,1,222,222,222,3,198,198,198, + 2,165,165,165,1,214,214,214,1,181,181,181,1,148,148,148,1,206,206,206, + 2,222,222,222,2,206,206,206,1,165,165,165,1,181,181,181,1,148,148,148, + 1,222,222,222,3,156,156,156,1,189,189,189,1,222,222,222,1,198,198,198, + 1,181,181,181,1,198,198,198,1,222,222,222,2,181,181,181,1,148,148,148, + 1,198,198,198,1,165,165,165,1,173,173,173,1,189,189,189,3,181,181,181, + 1,156,156,156,1,222,222,222,1,181,181,181,1,165,165,165,1,181,181,181, + 3,189,189,189,1,165,165,165,2,189,189,189,1,156,156,156,1,222,222,222, + 3,165,165,165,1,148,148,148,1,222,222,222,1,181,181,181,1,156,156,156, + 1,222,222,222,3,173,173,173,2,222,222,222,1,198,198,198,1,156,156,156, + 1,173,173,173,1,148,148,148,2,156,156,156,2,222,222,222,1,181,181,181, + 1,173,173,173,1,156,156,156,3,181,181,181,1,165,165,165,1,222,222,222, + 1,206,206,206,1,189,189,189,1,206,206,206,1,222,222,222,2,189,189,189, + 1,165,165,165,1,214,214,214,1,173,173,173,1,189,189,189,1,222,222,222, + 3,156,156,156,1,181,181,181,1,222,222,222,2,198,198,198,1,173,173,173, + 1,156,156,156,1,206,206,206,1,189,189,189,1,156,156,156,1,222,222,222, + 1,181,181,181,1,156,156,156,1,222,222,222,1,189,189,189,1,165,165,165, + 1,173,173,173,1,214,214,214,1,222,222,222,2,156,156,156,1,189,189,189, + 1,222,222,222,2,214,214,214,1,165,165,165,1,214,214,214,1,222,222,222, + 5,156,156,156,1,181,181,181,1,189,189,189,1,148,148,148,2,206,206,206, + 1,165,165,165,2,214,214,214,1,165,165,165,1,198,198,198,1,148,148,148, + 1,181,181,181,1,189,189,189,1,165,165,165,1,198,198,198,1,173,173,173, + 1,156,156,156,1,165,165,165,1,181,181,181,1,156,156,156,1,181,181,181, + 1,222,222,222,6,206,206,206,1,214,214,214,1,189,189,189,1,156,156,156, + 1,181,181,181,1,156,156,156,2,214,214,214,1,198,198,198,1,148,148,148, + 1,181,181,181,1,189,189,189,1,156,156,156,1,165,165,165,1,181,181,181, + 1,156,156,156,1,189,189,189,1,173,173,173,1,189,189,189,1,156,156,156, + 1,165,165,165,1,206,206,206,1,173,173,173,1,156,156,156,1,173,173,173, + 1,156,156,156,1,173,173,173,1,206,206,206,2,222,222,222,2,206,206,206, + 1,156,156,156,2,165,165,165,1,181,181,181,1,156,156,156,1,214,214,214, + 1,222,222,222,1,181,181,181,1,206,206,206,2,181,181,181,2,148,148,148, + 1,189,189,189,1,181,181,181,2,173,173,173,1,181,181,181,1,165,165,165, + 1,181,181,181,1,222,222,222,1,173,173,173,1,198,198,198,1,222,222,222, + 1,189,189,189,1,181,181,181,1,148,148,148,1,173,173,173,1,165,165,165, + 1,181,181,181,1,222,222,222,1,156,156,156,1,173,173,173,1,189,189,189, + 1,214,214,214,1,222,222,222,6,189,189,189,1,156,156,156,1,222,222,222, + 1,206,206,206,1,156,156,156,1,189,189,189,2,181,181,181,1,222,222,222, + 1,181,181,181,1,156,156,156,1,222,222,222,7,198,198,198,1,173,173,173, + 2,148,148,148,1,181,181,181,2,156,156,156,1,181,181,181,1,206,206,206, + 2,222,222,222,2,206,206,206,1,214,214,214,1,198,198,198,1,165,165,165, + 1,214,214,214,1,181,181,181,1,173,173,173,1,189,189,189,2,148,148,148, + 1,206,206,206,1,181,181,181,1,148,148,148,1,222,222,222,1,214,214,214, + 1,222,222,222,2,206,206,206,2,189,189,189,1,156,156,156,1,165,165,165, + 1,148,148,148,1,189,189,189,1,222,222,222,1,173,173,173,1,189,189,189, + 1,148,148,148,1,173,173,173,1,165,165,165,1,181,181,181,1,189,189,189, + 1,173,173,173,1,206,206,206,1,189,189,189,1,165,165,165,1,148,148,148, + 1,181,181,181,1,173,173,173,2,165,165,165,3,173,173,173,1,181,181,181, + 1,206,206,206,1,165,165,165,1,198,198,198,1,181,181,181,1,165,165,165, + 1,156,156,156,1,173,173,173,2,165,165,165,1,206,206,206,1,222,222,222, + 5,198,198,198,1,156,156,156,2,165,165,165,4,173,173,173,1,165,165,165, + 1,189,189,189,1,148,148,148,1,189,189,189,1,148,148,148,1,189,189,189, + 1,148,148,148,1,181,181,181,1,156,156,156,1,181,181,181,1,156,156,156, + 1,189,189,189,1,156,156,156,1,181,181,181,2,206,206,206,1,222,222,222, + 4,198,198,198,1,206,206,206,1,222,222,222,3,156,156,156,1,189,189,189, + 1,214,214,214,1,189,189,189,1,198,198,198,1,173,173,173,1,181,181,181, + 1,189,189,189,1,198,198,198,1,173,173,173,1,206,206,206,1,181,181,181, + 1,165,165,165,1,214,214,214,1,148,148,148,1,156,156,156,1,214,214,214, + 1,189,189,189,1,206,206,206,1,222,222,222,1,148,148,148,1,181,181,181, + 1,222,222,222,3,198,198,198,1,214,214,214,1,165,165,165,1,173,173,173, + 1,222,222,222,3,156,156,156,1,181,181,181,1,222,222,222,1,214,214,214, + 1,173,173,173,2,206,206,206,1,181,181,181,2,156,156,156,1,222,222,222, + 1,181,181,181,1,156,156,156,1,189,189,189,2,198,198,198,1,156,156,156, + 1,198,198,198,1,222,222,222,2,165,165,165,1,189,189,189,1,222,222,222, + 2,206,206,206,1,181,181,181,1,206,206,206,1,181,181,181,1,156,156,156, + 1,214,214,214,1,222,222,222,2,181,181,181,1,156,156,156,1,214,214,214, + 1,181,181,181,1,173,173,173,1,156,156,156,2,148,148,148,1,156,156,156, + 1,148,148,148,1,222,222,222,1,181,181,181,1,173,173,173,1,148,148,148, + 3,156,156,156,1,165,165,165,1,198,198,198,2,165,165,165,1,222,222,222, + 3,189,189,189,1,148,148,148,1,222,222,222,1,206,206,206,1,165,165,165, + 1,189,189,189,1,222,222,222,2,181,181,181,1,156,156,156,1,181,181,181, + 1,156,156,156,1,206,206,206,1,222,222,222,3,189,189,189,1,156,156,156, + 1,222,222,222,1,181,181,181,1,148,148,148,1,222,222,222,4,181,181,181, + 1,165,165,165,1,189,189,189,1,148,148,148,1,222,222,222,3,148,148,148, + 1,181,181,181,1,222,222,222,2,156,156,156,1,181,181,181,1,222,222,222, + 2,189,189,189,2,165,165,165,1,198,198,198,1,222,222,222,3,165,165,165, + 1,214,214,214,1,173,173,173,1,198,198,198,1,156,156,156,1,181,181,181, + 1,173,173,173,1,189,189,189,1,222,222,222,3,156,156,156,1,181,181,181, + 1,156,156,156,1,222,222,222,2,206,206,206,1,173,173,173,1,198,198,198, + 1,222,222,222,2,181,181,181,1,148,148,148,1,222,222,222,2,181,181,181, + 1,173,173,173,1,198,198,198,1,222,222,222,4,198,198,198,1,214,214,214, + 1,148,148,148,1,189,189,189,1,156,156,156,1,189,189,189,1,206,206,206, + 2,222,222,222,4,156,156,156,2,206,206,206,1,222,222,222,1,181,181,181, + 1,156,156,156,1,222,222,222,3,189,189,189,1,156,156,156,1,222,222,222, + 1,198,198,198,1,173,173,173,1,198,198,198,1,181,181,181,2,189,189,189, + 1,181,181,181,3,206,206,206,1,181,181,181,2,165,165,165,1,214,214,214, + 1,189,189,189,1,181,181,181,2,189,189,189,1,181,181,181,2,189,189,189, + 1,173,173,173,1,156,156,156,1,222,222,222,1,181,181,181,1,148,148,148, + 1,222,222,222,3,214,214,214,1,181,181,181,1,198,198,198,1,148,148,148, + 1,156,156,156,1,148,148,148,2,156,156,156,1,148,148,148,4,198,198,198, + 1,206,206,206,1,165,165,165,1,181,181,181,1,222,222,222,1,148,148,148, + 1,156,156,156,4,148,148,148,3,189,189,189,1,181,181,181,1,165,165,165, + 1,181,181,181,1,222,222,222,2,214,214,214,1,222,222,222,1,156,156,156, + 1,173,173,173,1,148,148,148,1,206,206,206,1,222,222,222,8,198,198,198, + 1,173,173,173,1,156,156,156,1,222,222,222,9,181,181,181,1,189,189,189, + 1,173,173,173,1,189,189,189,1,222,222,222,1,198,198,198,2,222,222,222, + 1,148,148,148,1,156,156,156,1,206,206,206,1,222,222,222,4,165,165,165, + 1,198,198,198,1,222,222,222,3,165,165,165,2,189,189,189,1,198,198,198, + 1,222,222,222,3,165,165,165,1,198,198,198,1,222,222,222,4,165,165,165, + 1,173,173,173,1,181,181,181,1,222,222,222,1,156,156,156,1,214,214,214, + 1,148,148,148,1,173,173,173,1,189,189,189,2,181,181,181,2,173,173,173, + 1,165,165,165,2,156,156,156,2,222,222,222,1,181,181,181,1,165,165,165, + 1,206,206,206,1,181,181,181,1,156,156,156,1,206,206,206,1,198,198,198, + 1,156,156,156,1,165,165,165,3,189,189,189,1,181,181,181,3,198,198,198, + 1,156,156,156,1,189,189,189,1,222,222,222,1,148,148,148,1,165,165,165, + 1,156,156,156,1,148,148,148,1,156,156,156,2,165,165,165,2,189,189,189, + 1,181,181,181,2,198,198,198,1,189,189,189,2,181,181,181,1,222,222,222, + 1,206,206,206,1,156,156,156,1,148,148,148,1,214,214,214,1,181,181,181, + 4,165,165,165,2,148,148,148,1,156,156,156,2,148,148,148,1,181,181,181, + 2,156,156,156,1,206,206,206,1,222,222,222,9,206,206,206,1,165,165,165, + 1,181,181,181,1,222,222,222,3,206,206,206,1,165,165,165,2,222,222,222, + 10,181,181,181,2,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46, + 99,111,117,110,116,2,3,19,102,97,99,101,46,102,97,100,101,95,112,111, + 115,46,105,116,101,109,115,1,2,0,5,0,0,0,0,0,0,0,128,254, + 63,2,1,0,21,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114, + 46,99,111,117,110,116,2,3,21,102,97,99,101,46,102,97,100,101,95,99, + 111,108,111,114,46,105,116,101,109,115,1,4,255,255,255,0,2,0,4,255, + 255,255,0,0,15,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115, + 11,11,102,97,108,95,111,112,116,105,111,110,115,13,102,97,108,95,102,97, + 111,112,97,99,105,116,121,0,8,116,97,98,111,114,100,101,114,2,7,8, + 98,111,117,110,100,115,95,120,3,144,1,8,98,111,117,110,100,115,95,121, + 3,168,0,9,98,111,117,110,100,115,95,99,120,3,132,0,9,98,111,117, + 110,100,115,95,99,121,2,52,8,115,116,97,116,102,105,108,101,7,10,116, + 115,116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,9,116,102,97,99,101,99,111,109,112,11,98,117, + 116,116,111,110,102,97,99,101,49,23,116,101,109,112,108,97,116,101,46,102, + 97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101,109,112, + 108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1, + 2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100,101,95, + 99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112,108,97, + 116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1, + 4,5,0,0,160,4,4,0,0,160,0,23,116,101,109,112,108,97,116,101, + 46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,7,103,100,95, + 100,111,119,110,4,108,101,102,116,2,16,3,116,111,112,2,72,0,0,9, + 116,109,97,105,110,109,101,110,117,9,109,97,105,110,109,101,110,117,49,18, + 112,111,112,117,112,102,114,97,109,101,116,101,109,112,108,97,116,101,7,10, + 112,111,112,117,112,102,114,97,109,101,22,112,111,112,117,112,105,116,101,109, + 102,114,97,109,101,116,101,109,112,108,97,116,101,7,14,112,111,112,117,112, + 105,116,101,109,102,114,97,109,101,21,112,111,112,117,112,105,116,101,109,102, + 97,99,101,116,101,109,112,108,97,116,101,7,11,98,117,116,116,111,110,102, + 97,99,101,50,28,112,111,112,117,112,105,116,101,109,102,114,97,109,101,116, + 101,109,112,108,97,116,101,97,99,116,105,118,101,7,14,112,111,112,117,112, + 105,116,101,109,102,114,97,109,101,27,112,111,112,117,112,105,116,101,109,102, + 97,99,101,116,101,109,112,108,97,116,101,97,99,116,105,118,101,7,11,98, + 117,116,116,111,110,102,97,99,101,50,13,102,114,97,109,101,116,101,109,112, + 108,97,116,101,7,13,109,97,105,110,109,101,110,117,102,114,97,109,101,12, + 102,97,99,101,116,101,109,112,108,97,116,101,7,11,98,117,116,116,111,110, + 102,97,99,101,49,17,105,116,101,109,102,114,97,109,101,116,101,109,112,108, + 97,116,101,7,17,109,97,105,110,109,101,110,117,105,116,101,109,102,114,97, + 109,101,16,105,116,101,109,102,97,99,101,116,101,109,112,108,97,116,101,7, + 11,98,117,116,116,111,110,102,97,99,101,50,23,105,116,101,109,102,114,97, + 109,101,116,101,109,112,108,97,116,101,97,99,116,105,118,101,7,17,109,97, + 105,110,109,101,110,117,105,116,101,109,102,114,97,109,101,22,105,116,101,109, + 102,97,99,101,116,101,109,112,108,97,116,101,97,99,116,105,118,101,7,11, + 98,117,116,116,111,110,102,97,99,101,50,18,109,101,110,117,46,115,117,98, + 109,101,110,117,46,99,111,117,110,116,2,4,18,109,101,110,117,46,115,117, + 98,109,101,110,117,46,105,116,101,109,115,14,1,13,115,117,98,109,101,110, + 117,46,99,111,117,110,116,2,4,13,115,117,98,109,101,110,117,46,105,116, + 101,109,115,14,1,13,115,117,98,109,101,110,117,46,99,111,117,110,116,2, + 6,13,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97, + 112,116,105,111,110,6,13,101,119,114,103,113,101,103,32,113,101,119,114,32, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,9,113,101,114,32, + 113,119,101,116,114,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6, + 10,117,122,107,109,101,53,54,97,114,101,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,7,99,97, + 112,116,105,111,110,6,12,119,52,51,53,32,101,114,116,114,104,52,54,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,0,1,7,99,97,112,116,105,111,110,6,12,52,119,53,103,98, + 115,103,102,100,98,115,119,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111, + 110,6,14,97,101,114,103,97,32,97,101,114,103,51,52,53,32,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,0,0,7,99,97,112,116,105,111,110,6,11,38,49,49,49,49,49,49, + 49,49,49,49,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,9, + 38,50,50,50,50,50,50,50,50,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116, + 105,111,110,6,10,38,51,51,51,51,51,51,51,51,51,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0, + 1,7,99,97,112,116,105,111,110,6,11,38,52,52,52,52,52,52,52,52, + 52,52,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,0,0,0,7,99,97,112,116,105,111,110,6,8,38,65, + 97,97,97,97,97,97,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110, + 6,7,38,66,98,98,98,98,98,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116, + 105,111,110,6,9,38,67,99,99,99,99,99,99,99,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1, + 7,99,97,112,116,105,111,110,6,6,38,68,100,100,100,100,5,115,116,97, + 116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0, + 0,0,4,108,101,102,116,2,24,3,116,111,112,2,40,0,0,10,116,102, + 114,97,109,101,99,111,109,112,13,109,97,105,110,109,101,110,117,102,114,97, + 109,101,15,116,101,109,112,108,97,116,101,46,108,101,118,101,108,105,2,1, + 4,108,101,102,116,3,144,0,3,116,111,112,2,36,0,0,10,116,102,114, + 97,109,101,99,111,109,112,17,109,97,105,110,109,101,110,117,105,116,101,109, + 102,114,97,109,101,15,116,101,109,112,108,97,116,101,46,108,101,118,101,108, + 111,2,255,15,116,101,109,112,108,97,116,101,46,108,101,118,101,108,105,2, + 1,19,116,101,109,112,108,97,116,101,46,102,114,97,109,101,119,105,100,116, + 104,2,2,19,116,101,109,112,108,97,116,101,46,99,111,108,111,114,102,114, + 97,109,101,4,3,0,0,128,20,116,101,109,112,108,97,116,101,46,102,114, + 97,109,101,105,95,108,101,102,116,2,2,19,116,101,109,112,108,97,116,101, + 46,102,114,97,109,101,105,95,116,111,112,2,2,21,116,101,109,112,108,97, + 116,101,46,102,114,97,109,101,105,95,114,105,103,104,116,2,2,22,116,101, + 109,112,108,97,116,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109, + 2,2,4,108,101,102,116,3,32,1,3,116,111,112,2,36,0,0,9,116, + 102,97,99,101,99,111,109,112,11,98,117,116,116,111,110,102,97,99,101,50, + 23,116,101,109,112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,99, + 111,117,110,116,2,2,23,116,101,109,112,108,97,116,101,46,102,97,100,101, + 95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,25,116,101,109, + 112,108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,99,111,117, + 110,116,2,2,25,116,101,109,112,108,97,116,101,46,102,97,100,101,95,99, + 111,108,111,114,46,105,116,101,109,115,1,4,5,0,0,160,4,4,0,0, + 160,0,23,116,101,109,112,108,97,116,101,46,102,97,100,101,95,100,105,114, + 101,99,116,105,111,110,7,5,103,100,95,117,112,4,108,101,102,116,2,16, + 3,116,111,112,2,104,0,0,10,116,102,114,97,109,101,99,111,109,112,14, + 112,111,112,117,112,105,116,101,109,102,114,97,109,101,15,116,101,109,112,108, + 97,116,101,46,108,101,118,101,108,111,2,255,15,116,101,109,112,108,97,116, + 101,46,108,101,118,101,108,105,2,1,19,116,101,109,112,108,97,116,101,46, + 102,114,97,109,101,105,95,116,111,112,2,1,22,116,101,109,112,108,97,116, + 101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,1,4,108,101, + 102,116,3,186,1,3,116,111,112,2,63,0,0,10,116,102,114,97,109,101, + 99,111,109,112,10,112,111,112,117,112,102,114,97,109,101,15,116,101,109,112, + 108,97,116,101,46,108,101,118,101,108,111,2,2,19,116,101,109,112,108,97, + 116,101,46,102,114,97,109,101,119,105,100,116,104,2,1,4,108,101,102,116, + 3,187,1,3,116,111,112,2,35,0,0,9,116,115,116,97,116,102,105,108, + 101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109, + 101,6,10,115,116,97,116,117,115,46,115,116,97,4,108,101,102,116,2,19, + 3,116,111,112,3,195,0,0,0,10,116,105,109,97,103,101,108,105,115,116, + 4,105,109,108,105,5,119,105,100,116,104,2,4,6,104,101,105,103,104,116, + 2,4,7,111,112,116,105,111,110,115,11,0,5,99,111,117,110,116,2,51, + 4,108,101,102,116,3,192,1,3,116,111,112,2,112,5,105,109,97,103,101, + 10,84,11,0,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0,0, + 0,32,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,231,233, + 1,206,223,228,1,202,221,225,1,201,220,224,1,202,221,225,1,116,60,0, + 1,252,253,253,2,204,222,227,1,126,77,22,1,202,199,191,1,214,223,226, + 1,213,222,225,4,205,215,219,1,189,189,182,1,126,77,22,1,230,241,243, + 1,218,226,228,1,212,221,224,1,116,60,0,1,226,238,241,1,202,221,225, + 1,203,222,226,1,206,223,228,1,213,231,233,1,201,220,224,4,206,223,228, + 1,208,225,230,1,168,149,122,1,131,87,37,1,202,221,225,1,116,60,0, + 1,252,253,253,2,207,225,229,1,160,135,102,1,147,113,74,1,180,174,163, + 1,197,208,214,4,182,183,177,1,144,110,72,1,162,139,106,1,235,244,245, + 1,218,226,228,1,212,221,224,1,116,60,0,1,226,238,241,1,126,77,22, + 1,160,136,103,1,210,228,232,2,116,60,0,4,203,222,226,1,168,149,122, + 1,162,125,85,1,221,207,192,1,202,221,225,1,116,60,0,1,252,253,253, + 2,212,230,233,1,216,233,236,1,170,153,125,1,131,87,37,1,116,60,0, + 4,126,77,22,1,164,140,108,1,234,244,244,1,238,246,247,1,218,226,228, + 1,212,221,224,1,116,60,0,1,226,238,241,1,232,223,213,1,162,125,85, + 1,169,149,123,1,213,231,233,1,255,255,255,4,203,222,226,1,131,87,37, + 1,220,206,191,1,254,254,254,1,202,221,225,1,116,60,0,1,252,253,253, + 2,218,234,237,1,223,237,239,1,231,241,243,1,237,245,246,1,240,246,248, + 4,242,247,248,1,242,248,249,1,241,247,248,1,222,237,239,1,218,226,228, + 1,212,221,224,1,116,60,0,1,226,238,241,1,253,254,254,1,219,206,191, + 1,131,87,37,1,218,234,237,1,254,254,254,4,213,231,233,1,206,223,228, + 1,202,221,225,1,201,220,224,1,202,221,225,1,116,60,0,1,245,211,186, + 1,246,211,186,1,204,222,227,1,126,77,22,1,228,173,137,8,126,77,22, + 1,230,241,243,1,228,173,137,2,116,60,0,1,226,238,241,1,202,221,225, + 1,203,222,226,1,206,223,228,1,213,231,233,1,201,220,224,4,206,223,228, + 1,208,225,230,1,168,149,122,1,131,87,37,1,202,221,225,1,116,60,0, + 1,245,211,186,1,246,211,186,1,207,225,229,1,160,135,102,1,133,77,39, + 1,193,125,77,1,238,130,105,5,133,77,39,1,162,139,106,1,235,244,245, + 1,228,173,137,2,116,60,0,1,226,238,241,1,126,77,22,1,160,136,103, + 1,210,228,232,2,116,60,0,4,203,222,226,1,168,149,122,1,133,77,39, + 1,255,231,206,1,202,221,225,1,116,60,0,1,245,211,186,1,246,211,186, + 1,212,230,233,1,216,233,236,1,170,153,125,1,131,87,37,1,116,60,0, + 4,126,77,22,1,164,140,108,1,234,244,244,1,238,246,247,1,228,173,137, + 2,116,60,0,1,226,238,241,1,255,231,206,1,133,77,39,1,169,149,123, + 1,213,231,233,1,255,231,206,4,203,222,226,1,131,87,37,1,246,212,188, + 2,202,221,225,1,116,60,0,1,245,211,186,1,246,211,186,1,218,234,237, + 1,223,237,239,1,231,241,243,1,237,245,246,1,239,246,247,4,242,247,248, + 1,242,248,249,1,241,247,248,1,222,237,239,1,228,173,137,2,116,60,0, + 1,226,238,241,1,246,212,188,2,131,87,37,1,218,234,237,1,246,212,188, + 4,213,231,233,1,206,223,228,1,202,221,225,1,201,220,224,1,203,222,226, + 1,116,60,0,1,207,216,218,1,215,222,224,1,204,222,227,1,126,77,22, + 1,199,197,188,1,222,230,230,1,227,233,234,4,218,211,202,1,210,206,196, + 1,126,77,22,1,230,241,243,1,223,229,230,2,116,60,0,1,226,238,241, + 1,202,221,225,1,203,222,226,1,206,223,228,1,213,231,233,1,201,220,224, + 4,206,223,228,1,208,225,230,1,168,149,122,1,131,87,37,1,203,222,226, + 1,116,60,0,1,207,216,218,1,215,222,224,1,207,225,229,1,160,135,102, + 1,152,117,77,1,203,193,178,1,238,241,242,4,218,211,202,1,155,119,79, + 1,162,139,106,1,235,244,245,1,223,229,230,2,116,60,0,1,226,238,241, + 1,126,77,22,1,160,136,103,1,210,228,232,2,116,60,0,4,203,222,226, + 1,168,149,122,1,142,109,70,1,172,168,157,1,203,222,226,1,116,60,0, + 1,207,216,218,1,215,222,224,1,212,230,233,1,216,233,236,1,170,153,125, + 1,131,87,37,1,116,60,0,4,126,77,22,1,164,140,108,1,234,244,244, + 1,238,246,247,1,223,229,230,2,116,60,0,1,226,238,241,1,183,183,177, + 1,146,112,73,1,169,149,123,1,213,231,233,1,193,204,209,4,203,222,226, + 1,131,87,37,1,177,171,160,1,198,208,214,1,203,222,226,1,116,60,0, + 1,207,216,218,1,215,222,224,1,218,234,237,1,223,237,239,1,231,241,243, + 1,237,245,246,1,240,247,248,4,242,247,248,1,242,248,249,1,241,247,248, + 1,222,237,239,1,223,229,230,2,116,60,0,1,226,238,241,1,206,215,219, + 1,189,181,169,1,131,87,37,1,218,234,237,1,207,216,220,4,207,227,229, + 1,187,206,213,1,178,200,208,1,177,199,205,1,178,200,208,1,116,60,0, + 1,154,223,254,1,121,210,252,1,184,204,212,1,125,76,20,1,73,181,239, + 1,48,178,248,1,48,179,248,4,48,178,248,1,71,181,237,1,125,76,20, + 1,245,249,250,1,51,180,248,1,53,180,248,1,116,60,0,1,238,245,247, + 1,178,200,208,1,182,203,209,1,187,206,213,1,207,227,229,1,162,187,196, + 4,187,206,213,1,200,217,225,1,159,134,101,1,130,84,34,1,178,200,208, + 1,116,60,0,1,154,223,254,1,121,210,252,1,191,210,218,1,153,123,86, + 1,113,134,132,1,0,151,229,6,111,132,131,1,157,130,94,1,250,252,252, + 1,51,180,248,1,53,180,248,1,116,60,0,1,238,245,247,1,125,76,20, + 1,153,124,87,1,204,223,227,1,198,219,224,1,116,60,0,4,182,203,209, + 1,159,134,101,1,161,158,141,1,210,232,239,1,178,200,208,1,116,60,0, + 1,154,223,254,1,121,210,252,1,204,224,227,1,216,233,236,1,162,139,106, + 1,130,84,34,1,116,60,0,4,125,76,20,1,159,132,97,1,240,248,248, + 1,252,253,254,1,51,180,248,1,53,180,248,1,116,60,0,1,238,245,247, + 1,211,237,248,1,161,158,141,1,160,133,101,1,207,227,229,1,207,240,255, + 4,182,203,209,1,130,84,34,1,173,220,238,1,121,210,252,1,178,200,208, + 1,116,60,0,1,154,223,254,1,121,210,252,1,220,236,239,1,234,243,244, + 1,246,249,251,1,251,253,253,1,255,255,255,4,254,254,254,2,253,254,254, + 1,232,242,244,1,51,180,248,1,53,180,248,1,116,60,0,1,238,245,247, + 1,121,210,252,1,173,220,238,1,130,84,34,1,222,236,239,1,137,216,253, + 4,207,227,229,1,187,206,213,1,178,200,208,1,177,199,205,1,178,200,208, + 1,116,60,0,1,154,223,254,1,121,210,252,1,184,204,212,1,125,76,20, + 1,73,181,239,1,48,178,248,1,48,179,248,4,48,178,248,1,71,181,237, + 1,125,76,20,1,245,249,250,1,51,180,248,1,53,180,248,1,116,60,0, + 1,238,245,247,1,178,200,208,1,182,203,209,1,187,206,213,1,207,227,229, + 1,162,187,196,4,187,206,213,1,200,217,225,1,159,134,101,1,130,84,34, + 1,178,200,208,1,116,60,0,1,154,223,254,1,121,210,252,1,191,210,218, + 1,153,123,86,1,113,134,132,1,0,151,229,6,111,132,131,1,157,130,94, + 1,250,252,252,1,51,180,248,1,53,180,248,1,116,60,0,1,238,245,247, + 1,125,76,20,1,153,124,87,1,204,223,227,1,198,219,224,1,116,60,0, + 4,182,203,209,1,159,134,101,1,161,158,141,1,210,232,239,1,178,200,208, + 1,116,60,0,1,154,223,254,1,121,210,252,1,204,224,227,1,216,233,236, + 1,162,139,106,1,130,84,34,1,116,60,0,4,125,76,20,1,159,132,97, + 1,240,248,248,1,252,253,254,1,51,180,248,1,53,180,248,1,116,60,0, + 1,238,245,247,1,211,237,248,1,161,158,141,1,160,133,101,1,207,227,229, + 1,207,240,255,4,182,203,209,1,130,84,34,1,173,220,238,1,121,210,252, + 1,178,200,208,1,116,60,0,1,154,223,254,1,121,210,252,1,220,236,239, + 1,234,243,244,1,246,249,251,1,251,253,253,1,255,255,255,4,254,254,254, + 2,253,254,254,1,232,242,244,1,51,180,248,1,53,180,248,1,116,60,0, + 1,238,245,247,1,121,210,252,1,173,220,238,1,130,84,34,1,222,236,239, + 1,137,216,253,4,213,231,233,1,206,223,228,1,202,221,225,1,201,220,224, + 1,203,222,226,1,116,60,0,1,207,216,218,1,215,222,224,1,204,222,227, + 1,126,77,22,1,199,197,188,1,222,230,230,1,227,233,234,4,218,211,202, + 1,210,206,196,1,126,77,22,1,230,241,243,1,223,229,230,2,116,60,0, + 1,226,238,241,1,202,221,225,1,203,222,226,1,206,223,228,1,213,231,233, + 1,201,220,224,4,206,223,228,1,208,225,230,1,168,149,122,1,131,87,37, + 1,203,222,226,1,116,60,0,1,207,216,218,1,215,222,224,1,207,225,229, + 1,160,135,102,1,152,117,77,1,203,193,178,1,238,241,242,4,218,211,202, + 1,155,119,79,1,162,139,106,1,235,244,245,1,223,229,230,2,116,60,0, + 1,226,238,241,1,126,77,22,1,160,136,103,1,210,228,232,2,116,60,0, + 4,203,222,226,1,168,149,122,1,142,109,70,1,172,168,157,1,203,222,226, + 1,116,60,0,1,207,216,218,1,215,222,224,1,212,230,233,1,216,233,236, + 1,170,153,125,1,131,87,37,1,116,60,0,4,126,77,22,1,164,140,108, + 1,234,244,244,1,238,246,247,1,223,229,230,2,116,60,0,1,226,238,241, + 1,183,183,177,1,146,112,73,1,169,149,123,1,213,231,233,1,193,204,209, + 4,203,222,226,1,131,87,37,1,177,171,160,1,198,208,214,1,203,222,226, + 1,116,60,0,1,207,216,218,1,215,222,224,1,218,234,237,1,223,237,239, + 1,231,241,243,1,237,245,246,1,240,247,248,4,242,247,248,1,242,248,249, + 1,241,247,248,1,222,237,239,1,223,229,230,2,116,60,0,1,226,238,241, + 1,206,215,219,1,189,181,169,1,131,87,37,1,218,234,237,1,207,216,220, + 4,201,220,224,4,255,255,255,8,201,220,224,4,202,221,225,1,203,222,226, + 1,206,223,228,1,213,231,233,1,228,173,137,2,116,60,0,1,226,238,241, + 1,228,173,137,2,126,77,22,1,230,241,243,1,228,173,137,4,116,60,0, + 4,255,255,255,8,116,60,0,4,126,77,22,1,160,136,103,1,210,228,232, + 2,228,173,137,2,116,60,0,1,226,238,241,1,238,130,105,1,133,77,39, + 1,162,139,106,1,235,244,245,1,238,130,105,4,255,231,206,4,255,255,255, + 8,255,231,206,5,133,77,39,1,169,149,123,1,213,231,233,1,228,173,137, + 2,116,60,0,1,226,238,241,1,126,77,22,1,164,140,108,1,234,244,244, + 1,238,246,247,1,116,60,0,4,246,212,188,4,255,255,255,8,246,212,188, + 6,131,87,37,1,218,234,237,1,228,173,137,2,116,60,0,1,226,238,241, + 1,242,247,248,1,242,248,249,1,241,247,248,1,222,237,239,1,239,246,247, + 4,204,222,227,1,126,77,22,1,228,173,137,2,202,221,225,1,116,60,0, + 1,245,211,186,1,246,211,186,1,213,231,233,1,206,223,228,1,202,221,225, + 1,201,220,224,1,208,208,208,2,206,206,206,1,119,119,119,1,33,33,33, + 1,6,6,6,1,37,37,37,1,144,144,144,1,208,208,208,2,0,0,0, + 1,208,208,208,3,0,0,0,1,208,208,208,3,0,0,0,1,208,208,208, + 1,207,225,229,1,160,135,102,1,133,77,39,1,193,125,77,1,202,221,225, + 1,116,60,0,1,245,211,186,1,246,211,186,1,206,223,228,1,208,225,230, + 1,168,149,122,1,131,87,37,1,208,208,208,20,212,230,233,1,216,233,236, + 1,170,153,125,1,131,87,37,1,202,221,225,1,116,60,0,1,245,211,186, + 1,246,211,186,1,203,222,226,1,168,149,122,1,133,77,39,1,255,231,206, + 1,208,208,208,20,218,234,237,1,223,237,239,1,231,241,243,1,237,245,246, + 1,202,221,225,1,116,60,0,1,245,211,186,1,246,211,186,1,203,222,226, + 1,131,87,37,1,246,212,188,2,208,208,208,9,255,255,255,1,128,128,128, + 1,208,208,208,9,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/apps/i18ndemo/de/dummy.txt b/mseide-msegui/apps/i18ndemo/de/dummy.txt new file mode 100644 index 0000000..53e3a6e --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/de/dummy.txt @@ -0,0 +1 @@ +Placeholder for git. diff --git a/mseide-msegui/apps/i18ndemo/fr/dummy.txt b/mseide-msegui/apps/i18ndemo/fr/dummy.txt new file mode 100644 index 0000000..53e3a6e --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/fr/dummy.txt @@ -0,0 +1 @@ +Placeholder for git. diff --git a/mseide-msegui/apps/i18ndemo/i18ndemo.pas b/mseide-msegui/apps/i18ndemo/i18ndemo.pas new file mode 100644 index 0000000..debd6ed --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/i18ndemo.pas @@ -0,0 +1,27 @@ +{ MSEide Copyright (c) 1999-2011 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program i18ndemo; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef FPC} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui,mseforms,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/apps/i18ndemo/i18ndemo.prj b/mseide-msegui/apps/i18ndemo/i18ndemo.prj new file mode 100644 index 0000000..6ae5d32 --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/i18ndemo.prj @@ -0,0 +1,1200 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +[projectoptions] +projectdir=/D:/mse/packs/standard/git/mseide-msegui/apps/i18ndemo +projectfilename=/D:/mse/packs/standard/git/mseide-msegui/apps/i18ndemo/i18ndemo.prj +finddialog=8 + [finddialogfo.selectedonly] + value=0 + [finddialogfo] + stackedunder= + x=319 + y=205 + cx=371 + cy=93 +options=128 + [projectoptionsfo.toolshortcuts] + dropdowncolwidths=3 + 70 + 70 + 70 + [projectoptionsfo.twidgetgrid3] + propcolwidthref=723 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + width4=97 + sortdescend4=0 + width5=78 + sortdescend5=0 + width6=50 + sortdescend6=0 + width7=50 + sortdescend7=0 + width8=99 + sortdescend8=0 + width9=295 + sortdescend9=0 + [projectoptionsfo.twidgetgrid4] + propcolwidthref=549 + width0=96 + sortdescend0=0 + sortdescend1=0 + width2=73 + sortdescend2=0 + width3=263 + sortdescend3=0 + width4=276 + sortdescend4=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=15 + [projectoptionsfo.newfile] + firsttab=0 + index=0 + [projectoptionsfo.fontaliasgrid] + propcolwidthref=386 + width0=98 + sortdescend0=0 + width1=375 + sortdescend1=0 + width2=50 + sortdescend2=0 + width3=50 + sortdescend3=0 + width4=50 + sortdescend4=0 + width5=50 + sortdescend5=0 + width6=70 + sortdescend6=0 + [projectoptionsfo.macrosplitter] + x=0 + y=122 + xprop=1 + yprop=0.24084778420039 + [projectoptionsfo.macrogrid] + propcolwidthref=530 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + width6=146 + sortdescend6=0 + width7=518 + sortdescend7=0 + [projectoptionsfo.makeoptionsgrid] + propcolwidthref=619 + values0=4 + + + + + width0=57 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + sortdescend6=0 + values7=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX + sortdescend7=0 + [projectoptionsfo.makegroupbox] + firsttab=0 + index=1 + [projectoptionsfo.exceptionsgrid] + propcolwidthref=707 + width0=47 + sortdescend0=0 + width1=701 + sortdescend1=0 + [projectoptionsfo.ttabwidget1] + firsttab=0 + index=0 + [projectoptionsfo.filefiltergrid] + propcolwidthref=615 + width0=112 + sortdescend0=0 + width1=608 + sortdescend1=0 + [projectoptionsfo.ttabwidget2] + firsttab=0 + index=0 + [projectoptionsfo.ttabwidget3] + firsttab=0 + index=0 + [projectoptionsfo.tabwidget] + firsttab=0 + index=2 + [projectoptionsfo] + stackedunder= + x=28 + y=159 + cx=756 + cy=568 +settings=14 + [settingsfo.macrogrid] + propcolwidthref=524 + width0=149 + sortdescend0=0 + width1=368 + sortdescend1=0 + [settingsfo] + x=100 + y=106 + cx=570 + cy=570 + wsize=0 + active=1 + visible=1 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +codetemplatedirs=1 + ${TEMPLATEDIR} +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +componenthints=1 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +pairmarkcolor=-2147483642 +pairmaxrowcount=100 +editfontantialiased=1 +editmarkbrackets=1 +editmarkpairwords=0 +backupfilecount=2 +encoding=1 +eolstyle=1 +trimtrailingwhitespace=0 +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +fpcgdbworkaround=1 +mainfile=i18ndemo.pas +targetfile=i18ndemo${EXEEXT} +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +reversepathorder=0 +makeoptpurpose=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 65599 + 196671 + 65599 +uid=0 +macroon=0 +macronames=0 +macrovalues=0 +groupcomments=6 + + + + + + +fontalias=0 +fontnames=0 +fontancestors=0 +fontoptions=0 +fontheights=0 +fontwidths=0 +fontxscales=0 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +toolmenus=0 +toolfiles=0 +toolparams=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +settingsfile= +settingsautoload=0 +settingsautosave=0 +settingseditor=0 +settingsdebugger=0 +settingsmake=1 +settingsmacros=0 +settingsfontalias=0 +settingsusercolors=0 +settingsformatmacros=0 +settingstemplates=0 +settingstools=0 +settingsstorage=0 +settingscomponentstore=0 +settingsprojecttree=0 +settingslayout=0 +messageoutputfile= +modulenames=1 + MAINFO +moduletypes=1 + TMAINFO +modulefiles=1 + /D:/mse/packs/standard/git/mseide-msegui/apps/i18ndemo/main.mfm +macrogroup=0 +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +units= + ( + a=0,8228,6,Pascal Units + ) +cmodules= + ( + a=0,8228,6,C Modules + ) +files= + ( + a=0,8228,6,Text Files + ) +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +[componentstore] +storedir=/D:/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext=fdir +findhistory=1 + fdir +findoptions=1 +editpos=2 + 55,1 + 0,-1073741823 +bookmarks0=0 +bookmarks1=0 +sourcefiles=2 + /D:/mse/packs/standard/git/mseide-msegui/apps/i18ndemo/main.pas + /D:/mse/packs/standard/git/mseide-msegui/lib/common/i18n/msei18nutils.pas +relpaths=2 + main.pas + ../../lib/common/i18n/msei18nutils.pas +ismoduletexts=2 + 0 + 0 +modules=1 + /D:/mse/packs/standard/git/mseide-msegui/apps/i18ndemo/main.mfm +moduleoptions=1 + 0 +visiblemodules=1 + -1 +nomenumodules=1 + 0 +[sourcefo.tabwidget] +tabsize=117 +firsttab=0 +index=0 +[layout] +windowlayout=568 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/apps/i18ndemo/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=268582016 + [mainfo] + splitdir=0 + useroptions=838860923 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=8 + y=30 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=0 + cy=0 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=805322875 + stackedunder=cpuc86_64fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=805322859 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=268451947 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=805322859 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=332 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=149 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=172 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=268451947 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=805322859 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=805322875 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=18 + + + + + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=116 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=805355627 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=680 + cx=983 + cy=200 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=805331067 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=805331051 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=30 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=268460139 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=30 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=805322857 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=983 + cy=677 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpuc86_64fo] + irqoff=0 + splitdir=0 + useroptions=268451947 + stackedunder=watchpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=183 + y=113 + cx=352 + cy=277 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=838893035 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=8 + y=118 + cx=993 + cy=880 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=838893035 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=805322875 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=291 + y=247 + cx=413 + cy=196 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/i18ndemo/i18ndemo.trd b/mseide-msegui/apps/i18ndemo/i18ndemo.trd new file mode 100644 index 0000000..6d5babe --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/i18ndemo.trd @@ -0,0 +1,86 @@ +name,type,notranslate,comment,value,de,fr +main.rsj,vaNull,F,,,, +"main.rsj,main",vaNull,F,,,, +"main.rsj,main,rs1",vaWString,F,,This is the first resource text.,Das ist der erste Text,C'est le premier texte +"main.rsj,main,rs2",vaWString,F,,This is the second resource text.,This ist der zweite Text,C'est le deuxième texte +mainfo,vaNull,F,,,, +"mainfo,bounds_x",vaInt16,F,,291,, +"mainfo,bounds_y",vaInt16,F,,247,, +"mainfo,bounds_cx",vaInt16,F,,403,, +"mainfo,bounds_cy",vaInt16,F,,196,, +"mainfo,container.bounds",vaList,F,,,, +"mainfo,container.bounds,0:",vaInt8,F,,0,, +"mainfo,container.bounds,1:",vaInt8,F,,0,, +"mainfo,container.bounds,2:",vaInt16,F,,403,, +"mainfo,container.bounds,3:",vaInt16,F,,196,, +"mainfo,optionswindow",vaSet,F,,[wo_groupleader],, +"mainfo,options",vaSet,F,,"[fo_main,fo_terminateonclose,fo_autoreadstat,fo_autowritestat,fo_savepos,fo_savestate]",, +"mainfo,caption",vaString,F,,MSEi18n Demo,MSEi18n Demo,MSEi18n Demo +"mainfo,oneventloopstart",vaIdent,F,,formonloaded,, +"mainfo,moduleclassname",vaString,T,,tmseform,tmseform,tmseform +"mainfo,disp1",vaNull,F,,,, +"mainfo,disp1,frame.caption",vaString,F,,Text of resource string 1,Text von resourcestring 1,Texte du resourcestring 1 +"mainfo,disp1,frame.dummy",vaInt8,F,,0,, +"mainfo,disp1,frame.outerframe",vaList,F,,,, +"mainfo,disp1,frame.outerframe,0:",vaInt8,F,,0,, +"mainfo,disp1,frame.outerframe,1:",vaInt8,F,,17,, +"mainfo,disp1,frame.outerframe,2:",vaInt8,F,,0,, +"mainfo,disp1,frame.outerframe,3:",vaInt8,F,,0,, +"mainfo,disp1,taborder",vaInt8,F,,4,, +"mainfo,disp1,bounds_x",vaInt8,F,,16,, +"mainfo,disp1,bounds_y",vaInt8,F,,71,, +"mainfo,disp1,bounds_cx",vaInt16,F,,372,, +"mainfo,disp1,bounds_cy",vaInt8,F,,37,, +"mainfo,disp1,reffontheight",vaInt8,F,,14,, +"mainfo,disp2",vaNull,F,,,, +"mainfo,disp2,frame.caption",vaString,F,,Text of resource string 2,Text von resourcestring 2,Texte du resourcestring 2 +"mainfo,disp2,frame.dummy",vaInt8,F,,0,, +"mainfo,disp2,frame.outerframe",vaList,F,,,, +"mainfo,disp2,frame.outerframe,0:",vaInt8,F,,0,, +"mainfo,disp2,frame.outerframe,1:",vaInt8,F,,17,, +"mainfo,disp2,frame.outerframe,2:",vaInt8,F,,0,, +"mainfo,disp2,frame.outerframe,3:",vaInt8,F,,0,, +"mainfo,disp2,taborder",vaInt8,F,,3,, +"mainfo,disp2,bounds_x",vaInt8,F,,16,, +"mainfo,disp2,bounds_y",vaInt8,F,,127,, +"mainfo,disp2,bounds_cx",vaInt16,F,,372,, +"mainfo,disp2,bounds_cy",vaInt8,F,,37,, +"mainfo,disp2,reffontheight",vaInt8,F,,14,, +"mainfo,default",vaNull,F,,,, +"mainfo,default,bounds_x",vaInt8,F,,16,, +"mainfo,default,bounds_y",vaInt8,F,,24,, +"mainfo,default,bounds_cx",vaInt8,F,,114,, +"mainfo,default,bounds_cy",vaInt8,F,,30,, +"mainfo,default,state",vaSet,F,,"[as_localcaption,as_localonexecute]",, +"mainfo,default,caption",vaString,T,,Default,Default,Default +"mainfo,default,font.height",vaInt8,F,,18,14, +"mainfo,default,font.name",vaString,T,,stf_default,stf_default,stf_default +"mainfo,default,font.xscale",vaInt8,F,,1,, +"mainfo,default,font.dummy",vaInt8,F,,0,, +"mainfo,default,onexecute",vaIdent,F,,defaultexe,, +"mainfo,deutsch",vaNull,F,,,, +"mainfo,deutsch,taborder",vaInt8,F,,1,, +"mainfo,deutsch,bounds_x",vaInt16,F,,144,, +"mainfo,deutsch,bounds_y",vaInt8,F,,24,, +"mainfo,deutsch,bounds_cx",vaInt8,F,,114,, +"mainfo,deutsch,bounds_cy",vaInt8,F,,30,, +"mainfo,deutsch,state",vaSet,F,,"[as_localcaption,as_localonexecute]",, +"mainfo,deutsch,caption",vaString,T,,Deutsch,Deutsch,Deutsch +"mainfo,deutsch,font.height",vaInt8,F,,14,18,14 +"mainfo,deutsch,font.name",vaString,T,,stf_default,stf_default,stf_default +"mainfo,deutsch,font.xscale",vaInt8,F,,1,, +"mainfo,deutsch,font.dummy",vaInt8,F,,0,, +"mainfo,deutsch,onexecute",vaIdent,F,,deutschexe,, +"mainfo,francais",vaNull,F,,,, +"mainfo,francais,taborder",vaInt8,F,,2,, +"mainfo,francais,bounds_x",vaInt16,F,,272,, +"mainfo,francais,bounds_y",vaInt8,F,,24,, +"mainfo,francais,bounds_cx",vaInt8,F,,114,, +"mainfo,francais,bounds_cy",vaInt8,F,,30,, +"mainfo,francais,state",vaSet,F,,"[as_localcaption,as_localonexecute]",, +"mainfo,francais,caption",vaWString,T,,Français,Français,Français +"mainfo,francais,font.height",vaInt8,F,,14,14,18 +"mainfo,francais,font.name",vaString,T,,stf_default,stf_default,stf_default +"mainfo,francais,font.xscale",vaInt8,F,,1,, +"mainfo,francais,font.dummy",vaInt8,F,,0,, +"mainfo,francais,onexecute",vaIdent,F,,francaisexe,, diff --git a/mseide-msegui/apps/i18ndemo/i18ndemo.trp b/mseide-msegui/apps/i18ndemo/i18ndemo.trp new file mode 100644 index 0000000..1bc579b --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/i18ndemo.trp @@ -0,0 +1,133 @@ +[projectfo.projectstat] +colcount=7 +[projectfo.impexpfiledialog] +filenames=1 + /home/mse/proj/msegui/trunk/apps/i18ndemo/test.csv +filecolwidth=174 +x=0 +y=0 +cx=0 +cy=0 +lastdir=/home/mse/proj/msegui/trunk/apps/i18ndemo/ +filefilterindex=0 +filefilter=*.csv +[projectfo.aftermake] +value= +[projectfo.beforemake] +value= +[projectfo.destname] +value= +[projectfo.makeon] +value=1 +[projectfo.makecommand] +value=${COMPILER} -B -Cg -Fu${MSELIBDIR}i18n ${LIBFILE} +[projectfo.grid2] +propcolwidthref=581 +values0=2 + de + fr +width0=102 +sortdescend0=0 +values1=2 + ./de/ + ./fr/ +[projectfo.datafilename] +filenames=1 + i18ndemo.trd +filecolwidth=174 +x=0 +y=0 +cx=0 +cy=0 +lastdir= +filefilterindex=3 +filefilter= +[projectfo.grid] +propcolwidthref=428 +values0=2 + main.rsj + mainfo +width0=72 +sortdescend0=0 +values1=2 + main.rsj + main.mfm +values2=2 + 3 + 0 +values2_ci=-1 +width2=183 +sortdescend2=0 +[projectfo.impexpencoding] +value=1 +[projectfo] +x=149 +y=167 +cx=683 +cy=698 +wsize=0 +active=0 +visible=0 +[mainfo] +stackedunder= +x=518 +y=230 +cx=724 +cy=264 +wsize=0 +active=1 +visible=1 +[mainfo.grid] +propcolwidthref=613 +width0=167 +sortdescend0=0 +width1=50 +sortdescend1=0 +width2=20 +sortdescend2=0 +width3=100 +sortdescend3=0 +width4=101 +sortdescend4=0 +values5=5 + Das ist der erste Text + This ist der zweite Text + MSEi18n Demo + Text von resourcestring 1 + Text von resourcestring 2 +width5=117 +sortdescend5=0 +values6=5 + C'est le premier texte + C'est le deuxième texte + MSEi18n Demo + Texte du resourcestring 1 + Texte du resourcestring 2 +width6=109 +sortdescend6=0 +width7=50 +sortdescend7=0 +width8=50 +sortdescend8=0 +width9=50 +sortdescend9=0 +width10=50 +sortdescend10=0 +width11=50 +sortdescend11=0 +rowstate=5 + 0 0 + 0 0 + 0 0 + 0 0 + 0 0 +[mainfo.flat] +value=1 +[mainfo.stringonly] +value=1 +[mainfo.nont] +value=1 +[mainfo.ntonly] +value=0 +[mainfo.coloron] +value=1 diff --git a/mseide-msegui/apps/i18ndemo/main.mfm b/mseide-msegui/apps/i18ndemo/main.mfm new file mode 100644 index 0000000..2b8fa16 --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/main.mfm @@ -0,0 +1,90 @@ +object mainfo: tmainfo + bounds_x = 291 + bounds_y = 247 + bounds_cx = 403 + bounds_cy = 196 + container.bounds = ( + 0 + 0 + 403 + 196 + ) + optionswindow = [wo_groupleader] + options = [fo_main, fo_terminateonclose, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + caption = 'MSEi18n Demo' + oneventloopstart = formonloaded + moduleclassname = 'tmseform' + object disp1: tstringdisp + frame.caption = 'Text of resource string 1' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 16 + bounds_y = 71 + bounds_cx = 372 + bounds_cy = 37 + reffontheight = 14 + end + object disp2: tstringdisp + frame.caption = 'Text of resource string 2' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 16 + bounds_y = 127 + bounds_cx = 372 + bounds_cy = 37 + reffontheight = 14 + end + object default: tbutton + bounds_x = 16 + bounds_y = 24 + bounds_cx = 114 + bounds_cy = 30 + state = [as_localcaption, as_localonexecute] + caption = 'Default' + font.height = 18 + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + onexecute = defaultexe + end + object deutsch: tbutton + taborder = 1 + bounds_x = 144 + bounds_y = 24 + bounds_cx = 114 + bounds_cy = 30 + state = [as_localcaption, as_localonexecute] + caption = 'Deutsch' + font.height = 14 + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + onexecute = deutschexe + end + object francais: tbutton + taborder = 2 + bounds_x = 272 + bounds_y = 24 + bounds_cx = 114 + bounds_cy = 30 + state = [as_localcaption, as_localonexecute] + caption = 'Fran'#231'ais' + font.height = 14 + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + onexecute = francaisexe + end +end diff --git a/mseide-msegui/apps/i18ndemo/main.pas b/mseide-msegui/apps/i18ndemo/main.pas new file mode 100644 index 0000000..2e0d973 --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/main.pas @@ -0,0 +1,57 @@ +unit main; +{$ifdef FPC}{$mode objfpc}{$h+}{$codepage utf8}{$endif} +interface +uses + msegui,mseclasses,mseforms,msedispwidgets,msegraphedits,msesimplewidgets; + +type + tmainfo = class(tmseform) + disp1: tstringdisp; + disp2: tstringdisp; + default: tbutton; + deutsch: tbutton; + francais: tbutton; + procedure formonloaded(const sender: TObject); + procedure defaultexe(const sender: TObject); + procedure deutschexe(const sender: TObject); + procedure francaisexe(const sender: TObject); + protected + procedure updatedisp; + end; +var + mainfo: tmainfo; +implementation +uses + main_mfm,msei18nutils,msestrings; + +resourcestring + rs1 = 'This is the first resource text.'; + rs2 = 'This is the second resource text.'; + +procedure tmainfo.formonloaded(const sender: TObject); +begin + updatedisp; +end; + +procedure tmainfo.updatedisp; +begin + disp1.value:= utf8tostring(rs1); + disp2.value:= utf8tostring(rs2); +end; + +procedure tmainfo.defaultexe(const sender: TObject); +begin + loadlangunit(''); +end; + +procedure tmainfo.deutschexe(const sender: TObject); +begin + loadlangunit('i18ndemo_de'); +end; + +procedure tmainfo.francaisexe(const sender: TObject); +begin + loadlangunit('i18ndemo_fr'); +end; + +end. diff --git a/mseide-msegui/apps/i18ndemo/main_mfm.pas b/mseide-msegui/apps/i18ndemo/main_mfm.pas new file mode 100644 index 0000000..00b84aa --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/main_mfm.pas @@ -0,0 +1,84 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..1321] of byte end = + (size: 1322; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,8, + 98,111,117,110,100,115,95,120,3,35,1,8,98,111,117,110,100,115,95,121, + 3,247,0,9,98,111,117,110,100,115,95,99,120,3,147,1,9,98,111,117, + 110,100,115,95,99,121,3,196,0,16,99,111,110,116,97,105,110,101,114,46, + 98,111,117,110,100,115,1,2,0,2,0,3,147,1,3,196,0,0,13,111, + 112,116,105,111,110,115,119,105,110,100,111,119,11,14,119,111,95,103,114,111, + 117,112,108,101,97,100,101,114,0,7,111,112,116,105,111,110,115,11,7,102, + 111,95,109,97,105,110,19,102,111,95,116,101,114,109,105,110,97,116,101,111, + 110,99,108,111,115,101,15,102,111,95,97,117,116,111,114,101,97,100,115,116, + 97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10, + 102,111,95,115,97,118,101,112,111,115,12,102,111,95,115,97,118,101,115,116, + 97,116,101,0,7,99,97,112,116,105,111,110,6,12,77,83,69,105,49,56, + 110,32,68,101,109,111,16,111,110,101,118,101,110,116,108,111,111,112,115,116, + 97,114,116,7,12,102,111,114,109,111,110,108,111,97,100,101,100,15,109,111, + 100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102, + 111,114,109,0,11,116,115,116,114,105,110,103,100,105,115,112,5,100,105,115, + 112,49,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,25,84,101, + 120,116,32,111,102,32,114,101,115,111,117,114,99,101,32,115,116,114,105,110, + 103,32,49,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110, + 100,115,95,120,2,16,8,98,111,117,110,100,115,95,121,2,71,9,98,111, + 117,110,100,115,95,99,120,3,116,1,9,98,111,117,110,100,115,95,99,121, + 2,37,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 11,116,115,116,114,105,110,103,100,105,115,112,5,100,105,115,112,50,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,25,84,101,120,116,32,111, + 102,32,114,101,115,111,117,114,99,101,32,115,116,114,105,110,103,32,50,11, + 102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120, + 2,16,8,98,111,117,110,100,115,95,121,2,127,9,98,111,117,110,100,115, + 95,99,120,3,116,1,9,98,111,117,110,100,115,95,99,121,2,37,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117, + 116,116,111,110,7,100,101,102,97,117,108,116,8,98,111,117,110,100,115,95, + 120,2,16,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110,100, + 115,95,99,120,2,114,9,98,111,117,110,100,115,95,99,121,2,30,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,99,97,112,116,105,111,110,6,7,68,101,102,97,117,108,116,11,102,111, + 110,116,46,104,101,105,103,104,116,2,18,9,102,111,110,116,46,110,97,109, + 101,6,11,115,116,102,95,100,101,102,97,117,108,116,11,102,111,110,116,46, + 120,115,99,97,108,101,2,1,10,102,111,110,116,46,100,117,109,109,121,2, + 0,9,111,110,101,120,101,99,117,116,101,7,10,100,101,102,97,117,108,116, + 101,120,101,0,0,7,116,98,117,116,116,111,110,7,100,101,117,116,115,99, + 104,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,3,144,0,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110, + 100,115,95,99,120,2,114,9,98,111,117,110,100,115,95,99,121,2,30,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,7,99,97,112,116,105,111,110,6,7,68,101,117,116,115,99,104,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,10,102,111,110,116,46,100,117,109,109,121, + 2,0,9,111,110,101,120,101,99,117,116,101,7,10,100,101,117,116,115,99, + 104,101,120,101,0,0,7,116,98,117,116,116,111,110,8,102,114,97,110,99, + 97,105,115,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,3,16,1,8,98,111,117,110,100,115,95,121,2,24,9,98,111, + 117,110,100,115,95,99,120,2,114,9,98,111,117,110,100,115,95,99,121,2, + 30,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117, + 116,101,0,7,99,97,112,116,105,111,110,18,8,0,0,0,70,0,114,0, + 97,0,110,0,231,0,97,0,105,0,115,0,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,11,115,116, + 102,95,100,101,102,97,117,108,116,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,10,102,111,110,116,46,100,117,109,109,121,2,0,9,111,110,101, + 120,101,99,117,116,101,7,11,102,114,97,110,99,97,105,115,101,120,101,0, + 0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/apps/ide/COPYING.GPL b/mseide-msegui/apps/ide/COPYING.GPL new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/mseide-msegui/apps/ide/COPYING.GPL @@ -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/mseide-msegui/apps/ide/COPYING.IDE b/mseide-msegui/apps/ide/COPYING.IDE new file mode 100644 index 0000000..098aa98 --- /dev/null +++ b/mseide-msegui/apps/ide/COPYING.IDE @@ -0,0 +1,17 @@ +This is the file COPYING.IDE, it applies to MSEide. + +The source code of the MSEide is +distributed under the GNU General Public License (GPL) +(see the file COPYING.GPL) with the following modification: + +As a special exception, the copyright holders of MSEide give you +permission to link MSEide with non GPL runtime component unit modules by the +-dmorecomponents mechanism described in README.TXT. +Design time parts of the components and its unit modules must be GPL. + +If you didn't receive a copy of the file COPYING.GPL, contact: + Free Software Foundation + 675 Mass Ave + Cambridge, MA 02139 + USA + diff --git a/mseide-msegui/apps/ide/actionsmodule.mfm b/mseide-msegui/apps/ide/actionsmodule.mfm new file mode 100644 index 0000000..eb8d49e --- /dev/null +++ b/mseide-msegui/apps/ide/actionsmodule.mfm @@ -0,0 +1,2605 @@ +object actionsmo: tactionsmo + bounds_cx = 543 + bounds_cy = 435 + left = 7 + top = 198 + moduleclassname = 'tmsedatamodule' + object makeact: taction + Tag = 1 + caption = '&Make' + onexecute = makeactonexecute + left = 8 + top = 294 + end + object run: taction + caption = '&Run' + imagenr = 0 + hint = 'Run' + left = 80 + top = 191 + end + object step: taction + imagelist = buttonicons + caption = '&Step' + imagenr = 1 + imagenrdisabled = 18 + hint = 'Step' + onexecute = stepactonexecute + left = 8 + top = 222 + sc = ( + 1 + 310 + ) + end + object next: taction + imagelist = buttonicons + caption = '&Next' + imagenr = 2 + imagenrdisabled = 22 + hint = 'Next' + onexecute = nextactonexecute + left = 8 + top = 206 + sc = ( + 1 + 311 + ) + end + object continue: taction + imagelist = buttonicons + caption = '&Continue' + imagenr = 4 + imagenrdisabled = 17 + hint = 'Continue' + onexecute = continueactonexecute + left = 8 + top = 254 + sc = ( + 1 + 312 + ) + end + object interrupt: taction + imagelist = buttonicons + caption = '&Interrupt' + imagenr = 5 + imagenrdisabled = 16 + hint = 'Interrupt' + onexecute = interruptactonexecute + left = 9 + top = 269 + end + object reset: taction + imagelist = buttonicons + caption = '&Reset' + imagenr = 6 + imagenrdisabled = 15 + hint = 'Reset' + onexecute = resetactonexecute + left = 7 + top = 191 + end + object opensource: taction + caption = '&Open' + onexecute = opensourceactonexecute + left = 8 + top = 4 + sc = ( + 1 + 16463 + ) + end + object finish: taction + imagelist = buttonicons + caption = '&Finish' + imagenr = 3 + imagenrdisabled = 20 + hint = 'Finish' + onexecute = finishactonexecute + left = 8 + top = 238 + sc = ( + 1 + 8502 + ) + end + object save: taction + caption = '&Save' + onexecute = saveactonexecute + left = 8 + top = 20 + sc = ( + 1 + 16467 + ) + end + object close: taction + caption = '&Close' + onexecute = closeactonexecute + left = 8 + top = 68 + sc = ( + 1 + 16691 + ) + end + object abortmakeact: taction + caption = '&Abort Make' + onexecute = abortmakeactonexecute + left = 8 + top = 402 + end + object undo: taction + caption = '&Undo' + onexecute = undoactonexecute + left = 280 + top = 4 + sc = ( + 1 + 16474 + ) + end + object redo: taction + caption = '&Redo' + onexecute = redoactonexecute + left = 280 + top = 20 + sc = ( + 1 + 24666 + ) + end + object cut: taction + caption = 'Cu&t' + onexecute = cutactonexecute + left = 280 + top = 36 + sc = ( + 1 + 16472 + ) + sc1 = ( + 1 + 8455 + ) + end + object copy: taction + caption = '&Copy' + onexecute = copyactonexecute + left = 280 + top = 52 + sc = ( + 1 + 16451 + ) + end + object paste: taction + caption = '&Paste' + onexecute = pasteactonexecute + left = 280 + top = 68 + sc = ( + 1 + 16470 + ) + sc1 = ( + 1 + 8454 + ) + end + object delete: taction + caption = '&Delete' + onexecute = deleteactonexecute + left = 280 + top = 84 + end + object saveall: taction + caption = 'Sa&ve all' + onexecute = saveallactonexecute + left = 8 + top = 36 + end + object find: taction + caption = '&Find' + onexecute = findactonexecute + onupdate = findupdateexe + left = 152 + top = 28 + sc = ( + 1 + 16454 + ) + end + object repeatfind: taction + caption = '&Search again' + onexecute = repeatfindactonexecute + left = 152 + top = 44 + sc = ( + 1 + 306 + ) + end + object findinfile: taction + caption = 'Find in F&iles' + onexecute = findinfileonexecute + left = 152 + top = 76 + sc = ( + 1 + 24646 + ) + end + object closeall: taction + caption = 'C&lose all' + onexecute = closeallactonexecute + left = 8 + top = 84 + end + object saveas: taction + caption = 'Save &as' + onexecute = saveasactonexecute + left = 8 + top = 52 + end + object bkptsonact: taction + imagelist = buttonicons + caption = '&Breakpoints on' + state = [as_checked] + imagenr = 7 + hint = 'Breakpoints on/off' + onexecute = bkptsononexecute + left = 152 + top = 236 + sc = ( + 1 + 16450 + ) + end + object watchesonact: taction + imagelist = buttonicons + caption = '&Watches on' + state = [as_checked] + imagenr = 9 + hint = 'Watches on/off' + statfile = mainfo.projectstatfile + onexecute = watchesononexecute + left = 152 + top = 252 + sc = ( + 1 + 16471 + ) + end + object line: taction + caption = '&Line' + onexecute = lineactonexecute + left = 152 + top = 12 + sc = ( + 1 + 16460 + ) + end + object togglebkpt: taction + caption = '&Toggle Breakpoint' + onexecute = togglebreakpointexe + left = 152 + top = 204 + sc = ( + 1 + 308 + ) + end + object togglebkptenable: taction + caption = 'Toggle Bkpt. &enabled' + onexecute = togglebkptenableactonexecute + left = 152 + top = 220 + sc = ( + 1 + 8500 + ) + end + object buttonicons: timagelist + width = 24 + height = 24 + options = [bmo_masked, bmo_colormask] + count = 24 + left = 352 + top = 32 + image = { + 00000000060000007800000078000000583A0000000000000000000000000000 + 0000000000000000000000000000000000000000C0C0C018D0D0D00600A50903 + D0D0D01A00000001D0D0D00200000001D0D0D00B00000001D0D0D00200000001 + D0D0D02AC0C0C018D0D0D00600A5090110A8100100A50902D0D0D01900000005 + D0D0D00A00000005D0D0D029C0C0C018D0D0D00600A5090126BB20011EB41A01 + 00A50902D0D0D01A00000002D0D0D00D00000009D0D0D00500A30803D0D0D01B + C0C0C00D80000002C0C0C009D0D0D00600A5090132CE2E013CD3330122BD2001 + 00A50902D0D0D00100000001D0D0D00200000001D0D0D02500000007D0D0D005 + 0AB7070118D002010AB707010015000100000001D0D0D00700A9090104B40A01 + 00000001D0D0D00FC0C0C00D80000002C0C0C009D0D0D00600A509013BDF3801 + 4CED440143E23D0127C6260100A5090200000005D0D0D0240000000B00BF0001 + 0FBD050120DF00010DB304010004000100000001D0D0D00700A708010DC50A01 + 089A0B01002B0001D0D0D00EC0C0C005808080068000000380808001C0C0C009 + D0D0D00302A8090107B207010BB7060107B107013CE1390152FA4D0154FD4F01 + 4CF247012CD02C0100A50902D0D0D00100000009D0D0D00300AA000108B20801 + 0AB706010CBB06010EBE06010EBD06040AB7070100920701D0D0D0100000000B + 00AA000110C0040120DF00010EB204010008000100000001D0D0D00700A70801 + 15D50B0124DD19010CA1100100590001D0D0D00DC0C0C0088080800180000005 + C0C0C00AD0D0D00206AF07010EBD05011FDD000120DF000112C5040134D32F01 + 49E840014BED43014EF2470146ED42011FC5230100A50901D0D0D00300000007 + D0D0D00200A70A0109B507011BD7010120DF000718D00201003E030100000001 + D0D0D00B00000004D0D0D00B00A30C0112C3040120DF00010CAB050100020001 + 00000001D0D0D00700A7080115D50B012CE71D0137E52B0113A8150100680601 + 00000001D0D0D00BC0C0C0048080800480000006C0C0C00AD0D0D00102A80901 + 10C1050120DF00021CD7010109AF06012DC526013FD5330142DA370140DB3701 + 28C827010061050100120101D0D0D00300000007D0D0D00100AA000109B50601 + 1FDE000120DF00011DD8010113C403010FB604010FB504010EB404010EB20401 + 0EB1040109AE0601003E030100000001D0D0D00100000003D0D0D00200000001 + D0D0D00400000004D0D0D00A00A8070107B107011CD7010120DF0001099C0601 + 00000002D0D0D00700A7080115D50B012CE71D013CEA2E014AEB3D011FB32101 + 0A7C0D0100000001D0D0D00AC0C0C008800000018080800180000005C0C0C009 + D0D0D00108B307011FDD000120DF00010BA90501036C0501004B040126B71C01 + 35C2270134C5280121BB1E010061050100120101D0D0D00400000007D0D0D001 + 06AF08011AD6010120DF000112BA0301047B0501002C020100100001000F0001 + 000B000100080001000600010002000100000002D0D0D00100000007D0D0D004 + 04B2080108B507010BB806010EBC06010EBD060914C903011EDB010120DF0001 + 1DDA01010584050100000002D0D0D00700A7080115D50B012CE71D013CEA2E01 + 4CEC3F015CEF500131C13101108A170100000001D0D0D009C0C0C00580808005 + 80000006C0C0C008D0D0D0010DBB050120DF00011CD70101036C050100000001 + 006A06011FA9130129AF19011AAE14010061050100120101D0D0D00100000004 + D0D0D0080BB9050120DF00011FDE0001068A0601000000010027040100910701 + 00970F0100000005D0D0D00400000001D0D0D00300000001D0D0D00308AF0801 + 12C3040120DF000E1CD80101089E0601000D000100000002D0D0D00700A70801 + 15D50B012CE71D013CEA2E014CEC3F015CEF50016BF260014BCF480117961C01 + 00000001D0D0D008C0C0C0098000000480808001C0C0C00180000002C0C0C007 + 00A509010FBF050120DF000111BB04010022020100000001009A0801159C0A01 + 13A10B010061050100120101D0D0D00200000004D0D0D0080DBC050120DF0001 + 17CC0201014B03010000000100A3080110A9110100A40901009F1001D0D0D00F + 06AA060112C5040120DF000216CC02010EB204010DB104010DB204010EB20402 + 0EB304010FB504020FB6040110B704010CAD0401089A0601047B0501000B0001 + 00000002D0D0D00800A7080115D50B012CE71D013CEA2E014CEC3F015CEF5001 + 6BF260017BF5710168E064011D9D220100550001D0D0D007C0C0C00580000002 + C0C0C0028000000580808001C0C0C00180808001C0C0C007D0D0D0010DBB0501 + 20DF00011CD70101036E05010000000100A30901099B06010061050100120101 + 00000001D0D0D00E0CBA060120DF000117CC0201014B03010000000100A30801 + 26BB21011EB31A01009D0901009F1001D0D0D00E09B307011FDF000120DF0001 + 09A3050102450301001B010100430401001701010006000100080001000A0001 + 000C0001000D0001000F0001001302010002000100000005D0D0D00800A70801 + 15D50B012CE71D013CEA2E014CEC3F015CEF50016BF260017BF571018BF78201 + 86EE800126A7290100620A01D0D0D006C0C0C004808080018000000380808001 + 800000028080800180000003C0C0C009D0D0D00108B107011FDE000120DF0001 + 0AA60501015D0501007A070100A3090100120101D0D0D0100AB6070120DF0001 + 1FDE0001068A06010000000100A3080132CE2D013CD3340122BD2001009D0901 + 009F1001D0D0D00D0AB9060120DF00011AD40201015B040100000001006C0601 + 11A91001009C0801006105010000000BD0D0D00900A7080115D50B012CE71D01 + 3CEA2E014CEC3F015CEF50016BF260017BF571018BF7820186EE800124A02701 + 0018020100000001D0D0D005C0C0C004800000018080800180000005C0C0C001 + 8080800180000002C0C0C009D0D0D001018F070110BA040120DF00011FDE0001 + 14C403010EB905010DBB05010DBC05080CB9060109B3060106AB070100290201 + 00000001D0D0D00405AE080117CA030120DF000112BA03010491060100A40801 + 3BDF38014CED440143E23D0127C62601009D0901009F1001D0D0D00C0CBA0601 + 20DF000113C003010029020100000001009A080126BC21011EB41A0100A50902 + D0D0D01300A7080115D50B012CE71D013CEA2E014CEC3F015CEF50016BF26001 + 7BF5710168E064011A901F010007000100000001D0D0D006C0C0C00780808001 + 80000002C0C0C0028080800180000002C0C0C009D0D0D0010000000105930601 + 0DB105011FDE000120DF000D1BD40201069E060100000002D0D0D00406A60601 + 1DDB010120DF00011DD801010EBD04013CE1390152FA4D0154FD4F014CF24701 + 2CCF2C01009D0901009F1001D0D0D00200000008D0D0D0010AB7060120DF0001 + 1DDA0101057D05010000000100A3090133CF2E013DD3330123BD200100A50902 + 00000006D0D0D00C00A7080115D50B012CE71D013CEA2E014CEC3F015CEF5001 + 6BF260014BCF4801137B170100000002D0D0D007C0C0C00C8000000280808001 + C0C0C009D0D0D00200000001014504010692060109A105010CAE05010DB00509 + 13C103011EDB010120DF000117CA0201036C050100000002D0D0D00300930001 + 0699060119D0020120DF000118D0020134D22F0149E840014BED43014EF24701 + 46ED42011FC6230100940701D0D0D00200000008D0D0D00107AF07011FDC0001 + 20DF00010EB3040104850601009B08013BE039014CED450144E33D0127C72601 + 00A509010040030100000005D0D0D00C00A7080115D50B012CE71D013CEA2E01 + 4CEC3F015CEF500130C030010B5F100100000002D0D0D008C0C0C00B80808001 + 8000000180808001C0C0C00AD0D0D0030000000D002C0201069206011CD70101 + 20DF00010896050100000002D0D0D004000E0001047A04010898060108AA0601 + 2DC526013FD5330142DA370140DB370128C827010060050100120201D0D0D00B + 008607010EB8040120DF000218D1020108B106013CE23A0153FB4D0154FE4F01 + 4CF347012CD02C0100A50902D0D0D00200000007D0D0D00700A7080115D50B01 + 2CE71D013CEA2E014AEB3D011FB22001053F060100000002D0D0D009C0C0C00B + 8000000280808002C0C0C009D0D0D0030000000E004A040110BE040120DF0001 + 0BA7050100000002D0D0D00500000002004F040126B71C0135C2270134C52801 + 21BA1E010060050100120201D0D0D00C00000001059307010EB104011FDF0001 + 20DF000112C5040135D3300149E841014CED44014EF2470147ED43011FC52301 + 00A50901D0D0D00200000007D0D0D00700A7080115D50B012CE71D0137E52B01 + 13A415010021020100000002D0D0D00AC0C0C00B80000004C0C0C009D0D0D005 + 00000009D0D0D003008507010FBE050120DF00010EB205010008000100000001 + D0D0D00700A108011FA8120129AF19011AAE14010060050100120201D0D0D00E + 00000001004D0301079205010BA3040107AC06012EC526013FD5340142DB3701 + 41DC380128C927010061050100120101D0D0D00200000008D0D0D00600A70801 + 15D50B0124DD19010B980F01000F000100000002D0D0D00BC0C0C018D0D0D007 + 00000007D0D0D00300A509010EBD050120DF00010DB205010005000100000001 + D0D0D00700A30801149D0A0113A00B010060050100120201D0D0D01000000003 + 004C040126B81D0136C3270134C6290121BB1E01006105010012010100000004 + D0D0D00100000002D0D0D00A00A708010DC50A0107890A010003000100000001 + D0D0D00DC0C0C018D0D0D0070000000B0AB6060118D0020109AE060100010001 + 00000001D0D0D00700A308010A9905010166050100120201D0D0D01200000002 + 009408011FA9130129AF19011AAE1501006105010012010100000005D0D0D00D + 00A9090104B30A0100000002D0D0D00EC0C0C018D0D0D00500000009D0D0D001 + 0000000300910801004604010042040100000002D0D0D007009F100100A10801 + 00120201D0D0D00200000004D0D0D00F00A50901169C0A0113A10C0100610501 + 00120101D0D0D01500000001D0D0D00FC0C0C018D0D0D00300000004D0D0D00B + 00000005D0D0D00C00000004D0D0D00F00A50901099B06010061050100120101 + D0D0D026C0C0C018D0D0D00600000001D0D0D02F00A50901009E090100120101 + D0D0D06FF8FCF818D0D0D060F8FCF818D0D0D038000094010000A3010000AC01 + 0000B6020000AA0100009F010000850100000002D0D0D01EF8FCF80200000002 + F8FCF81000000002F8FCF802D0D0D036000095010000A9010000D9010000F501 + 0000FF040000F5010000D7010000A0010000540100000001D0D0D01DF8FCF802 + 00000003F8FCF80E00000003F8FCF802D0D0D01EF2301401F5563102F02D1201 + D0D0D004F0301401F5583202F22E1201D0D0D00B0000A2010000BE010000FB01 + 0000FF030909FF010E0EFF011111FF020E0EFF010909FB010101B40100008501 + 00000002D0D0D01BF8FCF80300000003F8FCF80C00000003F8FCF803D0D0D01E + F4502D01FDA36E02E44A290102000001D0D0D003F4502D01FDA36E02E44A2901 + 02000001D0D0D0090000A2010000DC010000FF020101FF010E0EFF011A1AFF01 + 2323FF012929FF012D2DFF022929FF012323FF011A1AFF010A0AD60100007601 + 00000002D0D0D01AF8FCF80400000003F8FCF80A00000003F8FCF804D0D0D01E + F44D2901FC996602E447270104000001D0D0D003F44D2901FC996602E4472701 + 04000001D0D0D008000095010000BE010000FF010000F50104049C011515EB01 + 2626FF013333FF013E3EFF014545FF014848FF023F3FE90126269C013232F501 + 2727FF010909B00100002B0100000001D0D0D01AF8FCF80500000003F8FCF803 + 0000F802F8FCF80300000003F8FCF805D0D0D01EF3482601FB8F5E02E5442401 + 05000001D0D0D003F3482601FB8F5F02E544250105000001D0D0D0080000A901 + 0000FB010000FF0104049C0100000001070728013737E7014C4CFF015757FF01 + 5F5FFF016464FF015B5BE7010F0F2801000000012E2E9C013E3EFF012B2BFB01 + 05058F0100000002D0D0D00A06069F010C0CAF011313B9011919BA011515AE01 + 0C0C9C01D0D0D009F8FCF806000000030000F80600000003F8FCF806D0D0D005 + 00000002D0D0D00400000002D0D0D00400000003D0D0D00AF3442301FA855702 + E341220107000001D0D0D003F3442301FA855702E341220107000001D0D0D007 + 000094010000D9010000FF021515E90107072801000000010D0D28015A5AE701 + 7171FF017A7AFF017373E7011414280100000001121228015C5CEB015353FF01 + 4141FF011D1DD2010000360100000002D0D0D0080404AB010E0ECC012828FE01 + 3434FF014040FF014B4BFE012E2EC30114149101D0D0D008F8FCF80700000003 + 0000F80400000003F8FCF807D0D0D0030000000CD0D0D00100000006D0D0D008 + F3402001F97B4F02E33D1F0109000001D0D0D003F3402001F97B4F02E33D1F01 + 09000001D0D0D0070000A3010000F5010000FF010E0EFF012525FF013636E701 + 0D0D280100000001131328017878E7017C7CE701161628010000000115152801 + 7878E7017A7AFF016767FF015353FF013838F5010404690100000002D0D0D007 + 00009F010909CC011C1CFF012828FF013434FF014040FF014C4CFF015858FF01 + 3232BE0105053E01D0D0D007F8FCF8070000F801000000030000F80200000003 + 0000F801F8FCF807D0D0D00300000014D0D0D007F23C1C01F8714702E3391C01 + 0B020001D0D0D003F23C1C01F8714702E3391C010B020001D0D0D0070000AC01 + 0000FF021919FF013232FF014A4AFF015858E701131328010000000114142401 + 1515240100000001181828018585E7018D8DFF018686FF017878FF016262FF01 + 4A4AFF010B0B8A0100000002D0D0D0070101AF011111FE011C1CFF012828FF01 + 3434FF014040FF014C4CFF015858FF016363FE011818870100000001D0D0D006 + F8FCF8070000F802000000060000F802F8FCF807D0D0D00300000014D0D0D007 + F2371901F7673F02E13619010C020001D0D0D003F2371901F7673F02E1361901 + 0C020001D0D0D0070000B6010000FF010707FF012121FF013A3AFF015454FF01 + 6D6DFF017777E7011414240100000002171724019292E7019D9DFF019595FF01 + 8C8CFF018383FF016D6DFF015454FF011313A10100000002D0D0D0070303B901 + 1111FF011C1CFF012828FF013434FF014040FF014C4CFF015858FF016464FF01 + 25259F0100000001D0D0D006F8FCF8060000F804000000040000F804F8FCF806 + D0D0D00300000014D0D0D007F2341601F65D3702E23216010C020001D0D0D003 + F2341601F65D3702E23217010C020001D0D0D0070000B6010000FF010B0BFF01 + 2626FF014040FF015A5AFF017575FF017979E701151524010000000218182401 + 9C9CE701A5A5FF019B9BFF019191FF018686FF017575FF015B5BFF011515A001 + 00000002D0D0D0070303BA011111FF011C1CFF012828FF013434FF014040FF01 + 4C4CFF015858FF016464FF0125259F0100000001D0D0D006F8FCF8060000F804 + 000000040000F804F8FCF806D0D0D00400000013D0D0D007F12F1301F5533002 + E12D14010E020001D0D0D003F12F1301F5533001F5543001E12F14010E020001 + D0D0D0070000AA010000FF010D0DFF012727FF014242FF015D5DFF016C6CE701 + 15152801000000011717240118182401000000011C1C28019898E7019D9DFF01 + 9393FF018888FF017777FF015D5DFF010E0E890100000002D0D0D0070101AE01 + 1111FE011C1CFF012828FF013434FF014040FF014C4CFF015858FF016363FE01 + 1818870100000001D0D0D006F8FCF8070000F802000000060000F802F8FCF807 + D0D0D00500000004D0D0D00200000004D0D0D00200000005D0D0D008F12C1101 + F4492802E02A110110020001D0D0D003F12C1101F44A2802E02A110110020001 + D0D0D00700009F010000F5010B0BFF012626FF014040FF015252E70112122801 + 00000001171728018C8CE7019595E7011B1B2801000000011A1A28018C8CE701 + 9191FF018686FF017575FF015252F5010808650100000002D0D0D00700009C01 + 0909C3011C1CFF012828FF013434FF014040FF014C4CFF015858FF013333BE01 + 0303250100000001D0D0D006F8FCF8070000F801000000030000F80200000003 + 0000F801F8FCF807D0D0D00500000004D0D0D00200000004D0D0D00200000004 + D0D0D009F1280D01F3402002E0260E0112020001D0D0D003F1280D01F3402002 + E0260E0112020001D0D0D007000085010000D7010707FF012121FF013636EB01 + 0D0D280100000001151528017F7FE7019595FF019D9DFF019292E70119192801 + 00000001171728018080E9018383FF016D6DFF013636D30100002B0100000002 + D0D0D008020291010F0FBE012828FE013434FF014040FF014B4BFE012C2CBE01 + 0C0C5C0100000002D0D0D006F8FCF807000000030000F80400000003F8FCF807 + D0D0D00500000003D0D0D00300000003D0D0D00300000004D0D0D009F0230901 + F2361802DF230B0113020001D0D0D003F0230901F2361802DF230B0113020001 + D0D0D007000000010000A0010000FB011919FF011F1F9C01000000010F0F2801 + 6D6DE7018686FF018D8DFF019393FF019696FF018888E7011717280100000001 + 52529C017878FF015E5EFB010F0F8B0100000003D0D0D00900003E0108088701 + 12129F0115159F01111187010202250100000002D0D0D007F8FCF80600000003 + 0000F80600000003F8FCF806D0D0D00500000004D0D0D00200000004D0D0D002 + 00000004D0D0D009F0200601F12C1002E01F060115020001D0D0D003F0200601 + F12C1002E01F070115020001D0D0D00700000001000054010000B4010E0EFF01 + 2525F50125259C014C4CE9016767FF017A7AFF018484FF018989FF018B8BFF02 + 7E7EEB0151519C017474F5016767FF012020AE010000150100000003D0D0D00A + 00000006D0D0D008F8FCF80500000003F8FCF8030000F802F8FCF80300000003 + F8FCF805D0D0D00600000002D0D0D00400000002D0D0D00400000002D0D0D00A + F01B0401F0220802DE1A030117020001D0D0D003F01B0401F0220902DE1A0401 + 17020001D0D0D00800000001000085010101D6011717FF012D2DFF014141FF01 + 5353FF016464FF017171FF017B7BFF017F7FFF027A7AFF017171FF016363FF01 + 3939D6010606580100000003D0D0D019F8FCF80400000003F8FCF80A00000003 + F8FCF804D0D0D01EEE180001DF160001DE160001E016000118020001D0D0D003 + EF170001DE150001DB150001DE15000118020001D0D0D0090000000100007601 + 0303B0011919FB012D2DFF013E3EFF014C4CFF015858FF016060FF016464FF02 + 5F5FFF015454FB011E1EAE010606580100000003D0D0D01AF8FCF80300000003 + F8FCF80C00000003F8FCF803D0D0D01EFF2B0001090000010400000100000002 + D0D0D00400000004D0D0D0090000000200002C0101018F010E0ED2012424F501 + 3434FF013E3EFF014545FF014848FF014242F5012C2CD3010D0D8B0100001501 + 00000004D0D0D01AF8FCF80200000003F8FCF80E00000003F8FCF802D0D0D035 + 000000030000360101016901060689010B0BA1010D0DA0010A0A890105056501 + 00002B0100000005D0D0D01BF8FCF80200000002F8FCF81000000002F8FCF802 + D0D0D0370000000CD0D0D01DF8FCF818D0D0D0380000000AD0D0D01EF8FCF818 + D0D0D018C0C0C030D0D0D0060000BC03D0D0D01A00000001D0D0D00200000001 + D0D0D021C0C0C030D0D0D0060000BC011A1AD5010000BC02D0D0D01900000005 + D0D0D020C0C0C030D0D0D0060000BC014949EA013636E2010000BC02D0D0D01A + 00000002D0D0D021C0C0C030D0D0D0060000BC016B6BEE017D7DFB014545E201 + 0000BC02D0D0D00100000001D0D0D00200000001D0D0D037C0C0C030D0D0D006 + 0000BC018686EE01A9A9FF019595FB015454E2010000BC0200000005D0D0D036 + C0C0C030D0D0D0030606CF011A1AD7012626DC011818D2018888EA01BDBDFC01 + C3C3FF01ADADFB016262E2010000BC02D0D0D00100000009D0D0D0030000AA01 + 1717D7012323DC012B2BDF013030E1013030E0042222DB010000B601D0D0D022 + C0C0C030D0D0D0021414D5012F2FE1016C6CFD016F6FFF013E3EE4017070E301 + 9E9EF201A7A7F501AFAFF801A1A1F2014848D4010000BC01D0D0D00300000007 + D0D0D0020000CE011F1FDB015F5FF8016F6FFF075353F20100004E0100000001 + D0D0D021C0C0C00B0000F802C0C0C0170000F801C0C0C00BD0D0D0010505CE01 + 3636E5016F6FFF026060F7011E1ECF015858DB017F7FE8018888EB018787EB01 + 5656D90100006F0100001401D0D0D00300000007D0D0D0010000AA012121DB01 + 6C6CFE016F6FFF016363FA014545E5013535D7013434D7013232D5013030D401 + 2E2ED3012121D00100004D0100000001D0D0D00100000003D0D0D00200000001 + D0D0D00BFF041F01FF0F2701FF0E2701FF031D01FF001A02D0D0D009C0C0C00B + 0000F802C0C0C0170000F801C0C0C00BD0D0D0011B1BD8016C6CFE016F6FFF01 + 2727CA010C0C8301000057014141D4016060DE016161DF013F3FD20100006F01 + 00001401D0D0D00400000007D0D0D0011414D6015C5CF7016F6FFF013C3CDB01 + 0E0E9601000037010000130200000D0100000A01000006010000020100000002 + D0D0D00100000007D0D0D009FF0F2601FF2A3F01FF394D02FF2A3F01FF0F2701 + FE001A01DF001601D0D0D008C0C0C00B0000F802C0C0C0170000F801C0C0C00B + D0D0D0012B2BDE016F6FFF016060F7010C0C840100000001000079012A2ACC01 + 3D3DD2012929CB0100006F0100001401D0D0D00100000004D0D0D0082424DD01 + 6F6FFF016C6CFE011313A8010000000100002F010000A6010000B50100000005 + D0D0D00400000001D0D0D00300000001D0D0D008FF041F01FF2B3F01FF4C5E01 + FF627202FF4C5E01FF2B4001FF041E01FE001A0188000E01D0D0D007C0C0C00B + 0000F802C0C0C0170000F801C0C0C00B0000CC013333E2016F6FFF013A3ADC01 + 00002A01000000010000B0011111C4011313C40100006F0100001401D0D0D002 + 00000004D0D0D0082C2CE0016F6FFF014F4FED0104045C01000000010000BB01 + 1A1AD5010000BD010000BF01D0D0D015FF112A01FF3D5101FF677601FF9FA902 + FF677601FF3D5101FF122A01FF001A01CC00150100000001D0D0D006C0C0C00B + 0000F802C0C0C0170000F801C0C0C00BD0D0D0012D2DDF016F6FFF016060F701 + 0C0C8601000000010000BA010000BD0100006F010000140100000001D0D0D00E + 2B2BDF016F6FFF014F4FED0104045C01000000010000BB014949EA013636E201 + 0000B5010000BF01D0D0D014FF152D01FF425501FF6E7C01FFBBC302FF6E7C01 + FF425501FF152D01FF001A01F000180100000001D0D0D006C0C0C00B0000F802 + C0C0C0170000F801C0C0C00BD0D0D0011D1DD6016C6CFE016F6FFF012323C701 + 0303730100008B010000BA0100001401D0D0D0102121DB016F6FFF016C6CFE01 + 1313A801000000010000BB016B6BEE017D7DFB014545E2010000B5010000BF01 + D0D0D013FF0D2601FF374B01FF5D6D01FF828E02FF5D6D01FF374B01FF0D2601 + FF001A01F000180100000001D0D0D006C0C0C00B0000F802C0C0C0170000F801 + C0C0C00BD0D0D0010505B0013535DD016F6FFF016D6DFE014444E6012F2FDC01 + 2E2EDF092929DD012020D7011515CF010000330100000001D0D0D0041212D301 + 4D4DEC016F6FFF013C3CDB011010B0010000BE018686EE01A9A9FF019595FB01 + 5454E2010000B5010000BF01D0D0D012FF001A01FF203601FF3E5101FF516202 + FF3E5101FF203601FF001A02CC00150100000001D0D0D006C0C0C0240000F801 + C0C0C00BD0D0D001000000011111B3012D2DD3016C6CFE016F6FFF0D5C5CF501 + 1616BF0100000002D0D0D0041818C8016666FB016F6FFF016363FA013333DC01 + 8888EA01BDBDFC01C3C3FF01ADADFB016262E2010000B5010000BF01D0D0D002 + 00000008D0D0D007FF001A01FE011B01FF193101FF273D02FF193101FF011B01 + FF001A01FE001A015900090100000001D0D0D006C0C0C030D0D0D00200000001 + 020256011616B0012121C0012A2AD0012C2CD2094242E3016868FC016F6FFF01 + 4F4FEB010A0A830100000002D0D0D0030000B7011515B9015959F2016F6FFF01 + 5353EE017070E3019E9EF201A7A7F501AFAFF801A1A1F3014848D4010000A901 + D0D0D00200000008D0D0D008DF001601FE001A01FF001A04FE001A019E001001 + 00000002D0D0D006C0C0C00B0000F802C0C0C0170000F801C0C0C00BD0D0D003 + 0000000D010136011313B1016060F7016F6FFF011A1AB50100000002D0D0D004 + 00000E010E0E93011C1CB7011D1DC8015858DB017F7FE8018888EB018787EB01 + 5656DA0100006F0100001601D0D0D01388000E01CC001501F0001802CC001501 + 5900090100000002D0D0D007C0C0C00B0000F802C0C0C023D0D0D0030000000E + 00005C013939E0016F6FFF012525C80100000002D0D0D0050000000200005A01 + 4141D4016060DE016161DF013F3FD30100006F0100001601D0D0D01500000006 + D0D0D008C0C0C030D0D0D00500000009D0D0D0030000A5013636E1016F6FFF01 + 2F2FD40100000A0100000001D0D0D0070000B9012A2ACC013D3DD3012929CC01 + 00006F0100001601D0D0D024C0C0C030D0D0D00700000007D0D0D0030000CC01 + 3131E1016F6FFF012F2FD3010000060100000001D0D0D0070000BB011111C401 + 1313C40100006F0100001601D0D0D025C0C0C030D0D0D0070000000B2222DA01 + 5353F2012121D1010000020100000001D0D0D0070000BB010000BE0100006F01 + 00001601D0D0D026C0C0C030D0D0D00500000009D0D0D001000000030000B301 + 000057010000520100000002D0D0D0070000BF010000B90100001501D0D0D002 + 00000004D0D0D021C0C0C030D0D0D00300000004D0D0D00B00000005D0D0D00C + 00000004D0D0D021C0C0C030D0D0D00600000001D0D0D0AC00000001D0D0D002 + 00000001D0D0D0579F9F9F01A0A0A001D0D0D01B00000005D0D0D00FBFBFBF01 + A1A1A1019F9F9F01A0A0A0049F9F9F01A1A1A101BFBFBF01D0D0D03D9F9F9F01 + A0A0A001A3A3A301D0D0D01C00000002D0D0D00FA2A2A201A0A0A009A6A6A601 + A8A8A801D0D0D0259F9F9F01D0D0D0169F9F9F01A0A0A002A3A3A301D0D0D003 + 00000001D0D0D00200000001D0D0D023FFFFFF01A1A1A101A0A0A00BA2A2A201 + B1B1B101FFFFFF01D0D0D00AA0A0A004D0D0D004A0A0A004D0D0D00DA0A0A001 + BFBFBF01D0D0D0159F9F9F01A0A0A003A3A3A301D0D0D00200000005D0D0D022 + A1A1A101A0A0A00EC2C2C201FFFFFF01D0D0D009A0A0A004FFFFFF01D0D0D003 + A0A0A004FFFFFF01D0D0D00CA0A0A001A2A2A201BBBBBB01D0D0D011A0A0A008 + A3A3A301D0D0D00300000009D0D0D003929292019F9F9F01A0A0A008FFFFFF01 + D0D0D00DA2A2A201A0A0A0029F9F9F01959595019E9E9E01A0A0A0069D9D9D01 + 949494019F9F9F01A0A0A001A3A3A301E3E3E301D0D0D009A0A0A004FFFFFF01 + D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A003B8B8B801FFFFFF01D0D0D00E + A0A0A00AA3A3A301D0D0D00400000007D0D0D0029F9F9F01A0A0A00AFFFFFF01 + D0D0D00CBFBFBF01A0A0A00392929201808080018D8D8D01A5A5A501A0A0A004 + 9D9D9D018585850180808001ACACAC01A5A5A501A0A0A001B2B2B201F9F9F901 + D0D0D008A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A004 + B3B3B302D0D0D00CA0A0A00AA3A3A301FFFFFF02D0D0D00300000007D0D0D001 + 99999901A0A0A00BFFFFFF01D0D0D00200000003D0D0D00200000001D0D0D004 + A1A1A101A0A0A0039D9D9D018A8A8A018080800194949401A5A5A501A0A0A002 + 9D9D9D01858585018080800192929201F5F5F501C7C7C701A0A0A002DEDEDE01 + FFFFFF01D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00C + A0A0A005AEAEAE01B7B7B701D0D0D00BA0A0A003ACACAC01E5E5E501F8F8F801 + A0A0A003A3A3A301FFFFFF02D0D0D00400000007D0D0D001A0A0A003A3A3A301 + D5D5D501F3F3F301FFFFFF07D0D0D00200000007D0D0D003A1A1A101A0A0A004 + A3A3A301909090018080800193939301A6A6A6019D9D9D018585850180808001 + 92929201F3F3F301F0F0F001A8A8A801A0A0A002D0D0D001FFFFFF01D0D0D007 + A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A006A9A9A901 + BCBCBC01D0D0D00AA0A0A003E5E5E501FFFFFF01F5F5F501A0A0A002A3A3A301 + FFFFFF02D0D0D00100000004D0D0D008A0A0A003D4D4D401FFFFFF03D0D0D00A + 00000001D0D0D00300000001D0D0D003A0A0A006A4A4A4019090900180808001 + 92929201868686018080800192929201F3F3F301F0F0F001A9A9A901A0A0A003 + BCBCBC01FFFFFF01D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01 + D0D0D00CA0A0A007A4A4A401BDBDBD01D0D0D008A0A0A004FBFBFB01FFFFFF01 + 9F9F9F01A0A0A001A1A1A101FFFFFF02D0D0D00200000004D0D0D008A0A0A003 + F3F3F301FFFFFF01D0D0D001A0A0A001D0D0D012A0A0A007A3A3A3018F8F8F01 + 8080800291919101F3F3F301F0F0F001A9A9A901A0A0A004A9A9A901FFFFFF01 + D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A008 + A1A1A101BBBBBB01D0D0D008A0A0A003EAEAEA01FFFFFF019F9F9F01A0A0A001 + FFFFFF02D0D0D00FA0A0A003F3F3F301FFFFFF01D0D0D001A0A0A002FFFFFF01 + D0D0D010A0A0A0079D9D9D01868686018080800292929201E7E7E701A9A9A901 + A0A0A005A9A9A901FFFFFF01D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004 + FFFFFF01D0D0D00CA0A0A008A1A1A101D7D7D701FFFFFF01D0D0D007A0A0A003 + AFAFAF01C6C6C601A0A0A001FFFFFF02D0D0D010A0A0A003D2D2D201FFFFFF01 + D0D0D001A0A0A003FFFFFF01D0D0D00FA0A0A0069D9D9D018585850180808001 + 90909001949494018080800191919101A7A7A701A0A0A005BCBCBC01FFFFFF01 + D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A007 + A5A5A501E4E4E401FFFFFF02D0D0D007A0A0A001A1A1A101A0A0A011D0D0D005 + A0A0A003A3A3A301C5C5C5019C9C9C01A0A0A004FFFFFF01D0D0D00EA1A1A101 + A0A0A0049D9D9D01858585018080800192929201F3F3F301E8E8E80193939301 + 8080800191919101A7A7A701A0A0A004D0D0D001FFFFFF01D0D0D007A0A0A004 + FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A006ABABAB01EEEEEE01 + FFFFFF02D0D0D009B2B2B201A3A3A301A0A0A00FB3B3B301ECECEC01D0D0D004 + AAAAAA01A8A8A801A0A0A009FFFFFF01D0D0D00300000008D0D0D002A1A1A101 + A0A0A0039D9D9D01858585018080800192929201F3F3F301F0F0F001A9A9A901 + A3A3A301939393018080800190909001A9A9A901A0A0A003E3E3E301FFFFFF01 + D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A005 + B4B4B401F6F6F601FFFFFF02D0D0D00BDFDFDF01C2C2C201B0B0B001A1A1A101 + A0A0A00DCCCCCC01FFFFFF01D0D0D004A1A1A101AFAFAF01A0A0A009FFFFFF01 + D0D0D00200000008D0D0D002BFBFBF01A6A6A601A0A0A0029494940180808001 + 92929201F3F3F301F0F0F001A9A9A901A0A0A002A3A3A3019494940180808001 + C4C4C401ACACAC01A0A0A001B3B3B301FEFEFE01FFFFFF01D0D0D007A0A0A004 + FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A004BFBFBF01FCFCFC01 + FFFFFF02D0D0D00C00000001FFFFFF02F1F1F101FFFFFF09F4F4F401C5C5C501 + A0A0A002C0C0C001FFFFFF01D0D0D005F0F0F001CACACA01B9B9B901A7A7A701 + A0A0A005FFFFFF02D0D0D00DA8A8A801A2A2A201A0A0A0019F9F9F01A9A9A901 + F4F4F401F0F0F001A9A9A901A0A0A004A3A3A301C4C4C401FBFBFB01CACACA01 + A3A3A301F0F0F001FFFFFF02D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004 + FFFFFF01D0D0D00CA0A0A003CDCDCD01FFFFFF03D0D0D00D00000005D0D0D009 + BFBFBF01A0A0A002AEAEAE01FFFFFF01D0D0D006FFFFFF03A0A0A004FFFFFF02 + D0D0D00FB1B1B101A0A0A002A2A2A201C2C2C201A8A8A801A0A0A006A4A4A401 + BFBFBF01A3A3A301D5D5D501FFFFFF02D0D0D008A0A0A004FFFFFF01D0D0D003 + A0A0A004FFFFFF01D0D0D00CA0A0A001A2A2A201DBDBDB01FFFFFF03D0D0D010 + 00000009D0D0D003A0A0A003A5A5A501FFFFFF01D0D0D009A0A0A003FFFFFF02 + D0D0D010FFFFFF01C2C2C201A3A3A301A0A0A00AA3A3A301D5D5D501FFFFFF02 + D0D0D009A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A001 + E8E8E801FFFFFF02D0D0D01400000007D0D0D003A0A0A003A3A3A301FFFFFF01 + D0D0D009A0A0A002FFFFFF02D0D0D012FFFFFF01E3E3E301B2B2B201A0A0A008 + B3B3B301F0F0F001FFFFFF03D0D0D00AFFFFFF04D0D0D004FFFFFF04D0D0D00C + 9F9F9F01FFFFFF02D0D0D0150000000A1D1D1D01A0A0A002A3A3A301FFFFFF01 + D0D0D009A0A0A001FCFCFC01FFFFFF01D0D0D015F9F9F901DEDEDE01CFCFCF01 + BCBCBC01A9A9A902BCBCBC01CFCFCF01E3E3E301FEFEFE01FFFFFF02D0D0D025 + FFFFFF01D0D0D01400000009D0D0D00100000003C3C3C301FFFFFF03D0D0D009 + FFFFFF02D0D0D00200000004D0D0D011FFFFFF0AD0D0D03900000004D0D0D00C + FFFFFF01D0D0D00F00000004D0D0D05700000001D0D0D02B00000001D0D0D002 + 00000001D0D0D03500000001D0D0D00200000001D0D0D00B00000001D0D0D002 + 00000001D0D0D02C00000005D0D0D0179F9F9F01A0A0A001D0D0D01B00000005 + D0D0D00A00000005D0D0D02D00000009D0D0D005A0A0A001D0D0D00B9F9F9F01 + A0A0A001A3A3A301D0D0D01C00000002D0D0D00D00000009D0D0D0050000CD01 + 0000CB02D0D0D02100000007D0D0D004A0A0A004D0D0D0099F9F9F01A0A0A002 + A3A3A301D0D0D00300000001D0D0D00200000001D0D0D02500000007D0D0D005 + 2222DB015353F2012323DB010000150100000001D0D0D01F0000000BA0A0A003 + A3A3A301FFFFFF01D0D0D0089F9F9F01A0A0A003A3A3A301D0D0D00200000005 + D0D0D0240000000B0000BF013030E1016F6FFF012F2FD4010000040100000001 + D0D0D01F0000000BA0A0A003A5A5A501FFFFFF01D0D0D005A0A0A008A3A3A301 + D0D0D00300000009D0D0D003929292019F9F9F01A0A0A008FFFFFF01D0D0D010 + 0000000B0000D5013737E4016F6FFF013030D40100000A0100000001D0D0D01B + 00000004D0D0D00BA0A0A003AEAEAE01FFFFFF01D0D0D004A0A0A00AA3A3A301 + D0D0D00400000007D0D0D0029F9F9F01A0A0A00AFFFFFF01D0D0D00C00000004 + D0D0D00B0000C6013A3AE5016F6FFF012929CC010000020100000001D0D0D01B + 00000004D0D0D00AA0A0A004C0C0C001FFFFFF01D0D0D003A0A0A00AA3A3A301 + FFFFFF02D0D0D00300000007D0D0D00199999901A0A0A00BFFFFFF01D0D0D002 + 00000003D0D0D00200000001D0D0D00400000004D0D0D00A0000D0011919D501 + 6161F8016F6FFF012020BB0100000002D0D0D00A00009F010000AF010000BA02 + 0000AE0100009C01D0D0D00CA0A0A011D6D6D601FFFFFF01D0D0D003A0A0A003 + ACACAC01E5E5E501F8F8F801A0A0A003A3A3A301FFFFFF02D0D0D00400000007 + D0D0D001A0A0A003A3A3A301D5D5D501F3F3F301FFFFFF07D0D0D00200000007 + D0D0D0040F0FD1011D1DD9012828DD012F2FE0013030E0094545EB016767FB01 + 6F6FFF016565FA0111119F0100000002D0D0D0090000AB010000CB010000FE01 + 0000FF020000FE010000C40100009101D0D0D00AA0A0A011BFBFBF01FEFEFE01 + FFFFFF01D0D0D003A0A0A003E5E5E501FFFFFF01F5F5F501A0A0A002A3A3A301 + FFFFFF02D0D0D00100000004D0D0D008A0A0A003D4D4D401FFFFFF03D0D0D00A + 00000001D0D0D00300000001D0D0D0031717D6013C3CE7016F6FFF0E6363F801 + 1B1BBF010000110100000002D0D0D00800009F010000CB010000FF060000BE01 + 00003E01D0D0D008A0A0A00FA7A7A701B8B8B801CCCCCC01FCFCFC01FFFFFF02 + D0D0D002A0A0A004FBFBFB01FFFFFF019F9F9F01A0A0A001A1A1A101FFFFFF02 + D0D0D00200000004D0D0D008A0A0A003F3F3F301FFFFFF01D0D0D001A0A0A001 + D0D0D0110C0CCE013E3EE7016F6FFF024F4FED013131D5012C2CD3012F2FD301 + 3030D4023030D5013333D6013333D7013434D7013535D8012B2BCD011E1EB801 + 0F0F960100000D0100000002D0D0D0090000AF010000FE010000FF060000FE01 + 0000870100000001D0D0D007A0A0A003AFAFAF01E8E8E801FCFCFC01FFFFFF0E + D0D0D004A0A0A003EAEAEA01FFFFFF019F9F9F01A0A0A001FFFFFF02D0D0D00F + A0A0A003F3F3F301FFFFFF01D0D0D001A0A0A002FFFFFF01D0D0D00F1D1DD801 + 6D6DFE016F6FFF011F1FC40103035401000021010000520100001B0100000601 + 00000A0100000C0100000F010000110100001301000017010000020100000005 + D0D0D0090000BA010000FF080000A00100000001D0D0D007A0A0A003EAEAEA01 + FFFFFF01F4F4F401A0A0A001D0D0D011A0A0A003AFAFAF01C6C6C601A0A0A001 + FFFFFF02D0D0D010A0A0A003D2D2D201FFFFFF01D0D0D001A0A0A003FFFFFF01 + D0D0D00E2626DB016F6FFF015B5BF5010707700100000001000086011A1ADF01 + 0000C001000078010000000BD0D0D00A0000BA010000FF0800009F0100000001 + D0D0D006A0A0A004FBFBFB01FFFFFF019F9F9F01A0A0A001A1A1A101D0D0D010 + A0A0A001A1A1A101A0A0A011D0D0D005A0A0A003A3A3A301C5C5C5019C9C9C01 + A0A0A004FFFFFF01D0D0D00D2B2BDD016F6FFF013F3FE2010000330100000001 + 0000BF014949EF013636E9010000CC02D0D0D0140000AE010000FE010000FF06 + 0000FE010000870100000001D0D0D007A0A0A003E5E5E501FFFFFF019F9F9F01 + A0A0A002A3A3A301D0D0D00200000006D0D0D008B2B2B201A3A3A301A0A0A00F + B3B3B301ECECEC01D0D0D004AAAAAA01A8A8A801A0A0A009FFFFFF01D0D0D003 + 00000008D0D0D0012525DA016F6FFF016565FB0111119801000000010000CA01 + 6B6BF2017D7DFC014545E9010000CC0200000006D0D0D00D00009C010000C401 + 0000FF060000BE010000240100000001D0D0D007A0A0A003ACACAC01C8C8C801 + A0A0A004A3A3A301D0D0D00100000006D0D0D009DFDFDF01C2C2C201B0B0B001 + A1A1A101A0A0A00DCCCCCC01FFFFFF01D0D0D004A1A1A101AFAFAF01A0A0A009 + FFFFFF01D0D0D00200000008D0D0D0011A1AD4016B6BFD016F6FFF013232D401 + 0C0CA3010000BF018686F201A9A9FF019595FC015454E9010000CC0100004F01 + 00000005D0D0D00E000091010000BE010000FE010000FF020000FE010000BE01 + 00005C0100000002D0D0D007A0A0A001A3A3A301A0A0A008A3A3A301D0D0D004 + 00000007D0D0D00400000001FFFFFF02F1F1F101FFFFFF09F4F4F401C5C5C501 + A0A0A002C0C0C001FFFFFF01D0D0D005F0F0F001CACACA01B9B9B901A7A7A701 + A0A0A005FFFFFF02D0D0D00B0000A4013131DB016F6FFF025757F3011D1DD601 + 8888EE01BDBDFC01C3C3FF01ADADFC016262E9010000CC02D0D0D00200000007 + D0D0D00A00003E01000087010000A00100009F01000087010000240100000002 + D0D0D009B3B3B301A5A5A501A0A0A008A3A3A301D0D0D00300000007D0D0D004 + 00000005D0D0D009BFBFBF01A0A0A002AEAEAE01FFFFFF01D0D0D006FFFFFF03 + A0A0A004FFFFFF02D0D0D00C000000011010B2012E2ED3016D6DFE016F6FFF01 + 3E3EE8017070E7019E9EF201A7A7F501AFAFF801A1A1F4014848DE010000CC01 + D0D0D00200000007D0D0D00B00000006D0D0D00BE0E0E001C3C3C301B0B0B001 + A1A1A101A0A0A004A3A3A301FFFFFF02D0D0D00200000008D0D0D00500000009 + D0D0D003A0A0A003A5A5A501FFFFFF01D0D0D009A0A0A003FFFFFF02D0D0D00E + 0000000103035D011717B0012525C3011A1AD0015858DF017F7FE8018888EB01 + 8787EC015656E0010000780100001701D0D0D00200000008D0D0D01CFFFFFF02 + FBFBFB01A0A0A003A3A3A301FFFFFF01FCFCFC0100000004D0D0D00100000002 + D0D0D00B00000007D0D0D003A0A0A003A3A3A301FFFFFF01D0D0D009A0A0A002 + FFFFFF02D0D0D0100000000300005E014141D8016060DE016161E0013F3FD901 + 000078010000170100000004D0D0D00100000002D0D0D0229F9F9F01A0A0A002 + A3A3A301FFFFFF0200000005D0D0D00E0000000A1D1D1D01A0A0A002A3A3A301 + FFFFFF01D0D0D009A0A0A001FCFCFC01FFFFFF01D0D0D012000000020000B701 + 2A2AD0013D3DD3012929D201000078010000170100000005D0D0D0259F9F9F01 + A0A0A001A3A3A301FFFFFF02D0D0D01200000009D0D0D00100000003C3C3C301 + FFFFFF03D0D0D009FFFFFF02D0D0D00200000004D0D0D00F0000CC011111C901 + 1313CB010000780100001701D0D0D02B9F9F9F01A0A0A001FFFFFF02D0D0D011 + 00000004D0D0D00CFFFFFF01D0D0D00F00000004D0D0D00F0000CC010000C801 + 0000780100001701D0D0D02DFFFFFF02D0D0D01500000001D0D0D02F0000CC01 + 0000C30100001701D0D0D027543A00000000001E101010014040400110101001 + 0000001A0C0C0C01000000020C0C0C010000000B0C0C0C01000000020C0C0C01 + 0000004840404001FFFFFF017070700110101001000000194646460169696901 + 6464640168686801707070010000000A46464601696969016464640168686801 + 707070010000004740404001FFFFFF0270707001101010010000001A13131301 + 171717010000000D13131301171717021A1A1A013B3B3B010B0B0B0117171701 + 2828280111111101000000053D3D3D014040400200000028FFFFFF020000000F + 40404001FFFFFF037070700110101001000000010C0C0C01000000020C0C0C01 + 00000025414141014D4D4D01494949011A1A1A01353535014747470124242401 + 00000005E6E6E601FFFFFF01E9E9E9010C0C0C0101010101000000073B3B3B01 + 7B7B7B01010101010000001CFFFFFF020000000F40404001FFFFFF0470707001 + 1010100160606001727272016262620164646401545454010000002426262601 + 2F2F2F01353535014747470136363601303030011E1E1E012A2A2A011F1F1F01 + 4D4D4D012828280104040401E3E3E301FFFFFF01F0F0F001747474010B0B0B01 + 0000000740404001F6F6F601BABABA010606060100000013FFFFFF0A0000000C + 20202001ACACAC01C8C8C801ECECEC01FFFFFF05707070011010100100000001 + 212121010A0A0A011A1A1A01282828012C2C2C01121212011010100132323201 + 08080801000000030303030185858501B8B8B801D3D3D301E0E0E001E1E1E104 + E9E9E90147474701000000102F2F2F014C4C4C0157575701393939013D3D3D01 + 2E2E2E012323230124242401181818013D3D3D01161616010C0C0C01E5E5E501 + FFFFFF01F1F1F101808080010C0C0C010000000740404001FFFFFF01FCFCFC01 + D3D3D3011414140100000015FFFFFF060000000C5B5B5B01DEDEDE01FFFFFF09 + 404040010000000350505001595959012D2D2D012A2A2A012424240152525201 + 1B1B1B01000000021A1A1A01C4C4C401FDFDFD01FFFFFF08A7A7A70101010101 + 0000000B2D2D2D01464646014A4A4A01505050010000000B16161601E8E8E801 + FFFFFF01EDEDED017A7A7A010B0B0B010000000740404001FFFFFF03E2E2E201 + 2C2C2C01010101010000000FFFFFFF0A0000000B25252501E3E3E301FFFFFF03 + F8F8F801FFFFFF05BFBFBF0193939301000000032B2B2B012F2F2F0138383801 + 4D4D4D0133333301373737011F1F1F010000000103030301CCCCCC01FFFFFF03 + F9F9F901F3F3F301F2F2F202F1F1F102F5F5F501A8A8A8010101010100000001 + 0C0C0C010404040111111101000000021919190100000004111111011D1D1D01 + 1F1F1F012A2A2A010000000A26262601B8B8B801FCFCFC01FFFFFF01E2E2E201 + 6E6E6E010A0A0A010000000740404001FFFFFF04EBEBEB015050500101010101 + 00000012FFFFFF070000000AB7B7B701FFFFFF02EBEBEB01C0C0C001AAAAAA01 + FFFFFF04BFBFBF019393930100000004353535014E4E4E015A5A5A013E3E3E01 + 41414101383838011C1C1C01000000017D7D7D01FBFBFB01FFFFFF01F3F3F301 + CCCCCC019E9E9E01919191018989890187878701868686018585850183838301 + 8282820101010101000000015656560163636301606060012B2B2B0146464601 + 62626201222222010000000442424201B8B8B801CECECE01DFDFDF01E1E1E109 + EFEFEF01FFFFFF03CFCFCF0159595901080808010000000740404001FFFFFF05 + F1F1F1017C7C7C01010101010000000EFFFFFF0B00000009D3D3D301FFFFFF02 + C0C0C0017070700163636301FFFFFF03BFBFBF01939393010000000144444401 + 494949014E4E4E013939390100000008BDBDBD01FFFFFF02D8D8D80184848401 + 4242420148484801111111010101010500000004010101010000000308080801 + 0000000383838301E9E9E901FFFFFF0FE7E7E701878787013D3D3D0105050501 + 0000000740404001FFFFFF06F6F6F601A3A3A3010202020100000011FFFFFF05 + 00000001FFFFFF020000000706060601E1E1E101FFFFFF01F4F4F40192929201 + 3131310144444401FFFFFF02BFBFBF0193939301000000021E1E1E0117171701 + 222222012020200100000008D1D1D101FFFFFF01FCFCFC01AEAEAE013B3B3B01 + 40404001FFFFFF0170707001101010010000000F2A2A2A01E8E8E801FFFFFF02 + FCFCFC01F2F2F201F1F1F104F2F2F204F3F3F301EDEDED01E1E1E101CBCBCB01 + 87878701585858010D0D0D010000000840404001FFFFFF07FAFAFA01C4C4C401 + 090909010000000CFFFFFF0200000002FFFFFF0600000001FFFFFF0100000008 + D2D2D201FFFFFF02BBBBBB011818180141414101FFFFFF01BFBFBF0193939301 + 020202010000000ED0D0D001FFFFFF01FCFCFC01AEAEAE011111110140404001 + FFFFFF0275757501101010010000000EB0B0B001FFFFFF02EAEAEA01AAAAAA01 + 8E8E8E01A1A1A101898989018282820183838301848484018585850286868601 + 8787870180808001777777016262620147474701101010010101010100000008 + 40404001FFFFFF08FEFEFE01D9D9D9011A1A1A010000000AFFFFFF0B0000000A + B5B5B501FFFFFF02E9E9E9015757570116161601414141019393930100000010 + B9B9B901FFFFFF02D7D7D7011414140140404001FFFFFF037575750110101001 + 0000000DC7C7C701FFFFFF02B7B7B7016C6C6C0162626201FFFFFF0177777701 + 1B1B1B010C0C0C070B0B0B010909090106060601010101010000000940404001 + FFFFFF08FEFEFE01E2E2E201696969010101010100000009FFFFFF0700000001 + FFFFFF030000000A29292901EBEBEB01FFFFFF02F7F7F701E4E4E401DEDEDE02 + DDDDDD07D2D2D201BDBDBD018C8C8C0108080801010101010000000461616101 + F8F8F801FFFFFF01F3F3F301AEAEAE0161616101FFFFFF047575750110101001 + 0000000CD2D2D201FFFFFF01F7F7F701959595012B2B2B0144444401FFFFFF02 + 70707001101010010000001340404001FFFFFF07FAFAFA01D6D6D6016A6A6A01 + 0C0C0C010000000DFFFFFF0300000002FFFFFF030000000A010101016D6D6D01 + EDEDED01FFFFFF0EFCFCFC01C6C6C601121212010202020100000004C7C7C701 + FFFFFF03F8F8F801FFFFFF057575750110101001000000021010100113131302 + 2E2E2E0112121201131313010D0D0D011616160100000001C8C8C801FFFFFF02 + C6C6C6011515150141414101FFFFFF037070700110101001282828012E2E2E02 + 3F3F3F0135353501020202010000000C40404001FFFFFF06F6F6F601C7C7C701 + 565656010505050100000013FFFFFF030000000B050505014D4D4D01D2D2D201 + E4E4E401EFEFEF01F1F1F109F8F8F801FFFFFF02FAFAFA01989898010E0E0E01 + 01010101000000030E0E0E01D6D6D601FCFCFC01FFFFFF084747470100000002 + 4C4C4C016C6C6C0176767601585858015D5D5D014F4F4F012D2D2D0131313101 + 00000001ADADAD01FFFFFF02EFEFEF017F7F7F014A4A4A01FFFFFF0470707001 + 292929013D3D3D014B4B4B015F5F5F0133333301040404010000000C40404001 + FFFFFF05F2F2F201B4B4B401424242010202020100000013FFFFFF030000000D + 121212011F1F1F0150505001717171017D7D7D018080800893939301DADADA01 + FEFEFE01FFFFFF01DCDCDC013F3F3F01060606010000000412121201B2B2B201 + E0E0E001F2F2F201FFFFFF05BFBFBF018C8C8C010000000B22222201EBEBEB01 + FFFFFF02FDFDFD01F2F2F201FFFFFF057070700110101001000000022F2F2F01 + 545454015E5E5E012C2C2C015757570132323201303030010000000740404001 + FFFFFF04EDEDED019F9F9F012F2F2F010101010100000014FFFFFF040000000C + 77777701767676017575750168686801464646010C0C0C080D0D0D012F2F2F01 + EEEEEE01FFFFFF01E9E9E9015C5C5C010808080100000005030303013D3D3D01 + 88888801FFFFFF04BFBFBF018C8C8C010000000C010101016D6D6D01ECECEC01 + FFFFFF0940404001000000020E0E0E011B1B1B021D1D1D010C0C0C011D1D1D01 + 242424010000000740404001FFFFFF03E7E7E7018B8B8B011F1F1F0101010101 + 00000015FFFFFF040000000E29292901010101013D3D3D01464646013A3A3A01 + 2626260115151501444444010E0E0E01000000030F0F0F01E7E7E701FFFFFF01 + F1F1F101757575010B0B0B010000000741414101FFFFFF03BFBFBF018C8C8C01 + 0000000E0505050150505001D0D0D001E5E5E501F7F7F701FFFFFF05BFBFBF01 + 8F8F8F01000000024141410168686801717171016B6B6B016D6D6D015B5B5B01 + 4A4A4A01575757010000000640404001FFFFFF01FCFCFC01DFDFDF0177777701 + 13131301010101010000002A353535013E3E3E011C1C1C012222220112121201 + 3F3F3F01161616010000000304040401E2E2E201FFFFFF01F1F1F1017F7F7F01 + 0C0C0C010000000740404001FFFFFF02BFBFBF018C8C8C010000001006060601 + 1E1E1E015252520192929201FFFFFF04BFBFBF01909090011212120110101001 + 2A2A2A01020202010000000114141401010101010000000A40404001F6F6F601 + D1D1D10164646401090909010000002C414141015A5A5A01515151015D5D5D01 + 4C4C4C015454540139393901292929015C5C5C01515151010E0E0E01E7E7E701 + FFFFFF01F4F4F401808080010C0C0C010000000740404001FFFFFF01C3C3C301 + 8C8C8C0100000012020202010707070147474701FFFFFF03BFBFBF018F8F8F01 + 282828015C5C5C014F4F4F0154545401060606010000000D3B3B3B017C7C7C01 + 4F4F4F01040404010000002B0A0A0A0103030301222222013030300131313101 + 21212101222222011C1C1C010E0E0E0100000001101010011111110116161601 + 4545450197979701A0A0A001737373010D0D0D01000000071010100141414101 + 919191010000000218181801303030023F3F3F010000000F40404001FFFFFF02 + BFBFBF018F8F8F0100000015010101010000002A707070027878780129292901 + 0000000B010101010C0C0C020B0B0B01010101010000000C2626260136363601 + 393939013A3A3A010000000F40404001FFFFFF01BFBFBF018F8F8F0100000044 + 080808010000002F10101001434343018F8F8F01000000FF0000003832323201 + 7F7F7F01AEAEAE01C8C8C801C9C9C901AFAFAF01828282013737370104040401 + 0101010100000020FFFFFF0200000010FFFFFF020000003818181801BBBBBB01 + F4F4F401FFFFFF06F6F6F601C3C3C30125252501030303010000001FFFFFFF03 + 0000000EFFFFFF0300000020D9D9D901DCDCDC02E2E2E20100000004DDDDDD01 + E0E0E002E5E5E5010000000B68686801DADADA01FFFFFF0AE7E7E7017C7C7C01 + 09090901010101010000001EFFFFFF030000000CFFFFFF0300000021D8D8D801 + FFFFFF02F2F2F2018C8C8C0100000003D8D8D801FFFFFF02F2F2F2018C8C8C01 + 0000000968686801F0F0F001FFFFFF0CF6F6F6018C8C8C010D0D0D0101010101 + 0000001EFFFFFF030000000AFFFFFF0300000022D8D8D801FFFFFF02F2F2F201 + 8D8D8D0100000003D8D8D801FFFFFF02F2F2F2018D8D8D010000000818181801 + DADADA01FFFFFF0EEBEBEB0153535301090909010000001FFFFFFF0300000003 + FFFFFF0200000003FFFFFF0300000023D8D8D801FFFFFF02F1F1F1018D8D8D01 + 00000003D8D8D801FFFFFF02F1F1F1018D8D8D0100000008BBBBBB01FFFFFF10 + D9D9D90125252501030303010000000A2D2D2D01ACACAC01C5C5C501C4C4C401 + ABABAB012C2C2C010000000FFFFFFF0C0000000B212121010303030100000004 + 171717010D0D0D0100000004090909011A1A1A01010101010000000AD8D8D801 + FFFFFF02F1F1F1018E8E8E0100000003D8D8D801FFFFFF02F1F1F1018E8E8E01 + 0000000732323201F4F4F401FFFFFF10F8F8F8017F7F7F011010100101010101 + 0000000873737301E5E5E501FFFFFF04EEEEEE017D7D7D010000000FFFFFFF0A + 0000000A36363601D0D0D001B3B3B301D4D4D40168686801020202010A0A0A01 + BEBEBE01BFBFBF01CCCCCC01A2A2A20103030301000000018A8A8A01D0D0D001 + BABABA01C4C4C401202020010101010100000008D8D8D801FFFFFF02F1F1F101 + 8E8E8E0100000003D8D8D801FFFFFF02F1F1F1018E8E8E01000000077F7F7F01 + FFFFFF12BBBBBB012F2F2F0104040401000000072D2D2D01E5E5E501FFFFFF06 + F1F1F1015F5F5F010000000EFFFFFF0A0000000AB5B5B5016D6D6D0169696901 + 6A6A6A01F1F1F101414141016F6F6F01A4A4A4016161610162626201DCDCDC01 + 8181810129292901E2E2E2014D4D4D0169696901ADADAD01B9B9B90113131301 + 0101010100000007D8D8D801FFFFFF02F2F2F2018F8F8F0100000003D8D8D801 + FFFFFF02F2F2F2018F8F8F0100000007AEAEAE01FFFFFF12D5D5D50146464601 + 0808080100000007ACACAC01FFFFFF08D5D5D501202020010000000DFFFFFF0A + 0000000A2D2D2D015C5C5C013131310110101001ECECEC018181810127272701 + 464646015252520107070701B1B1B1019E9E9E0133333301353535016F6F6F01 + 0A0A0A0169696901BFBFBF01494949010303030100000007D8D8D801FFFFFF02 + F2F2F2018F8F8F0100000003D8D8D801FFFFFF02F2F2F2018F8F8F0100000007 + C8C8C801FFFFFF12E3E3E3015C5C5C010A0A0A0100000007C5C5C501FFFFFF08 + E4E4E401606060010000000CFFFFFF0C0000000901010101171717010D0D0D01 + BABABA018686860177777701101010020D0D0D017C7C7C01C1C1C10160606001 + 323232010A0A0A01131313013E3E3E01E0E0E001575757015555550103030301 + 00000007D8D8D801FFFFFF02F1F1F1019090900100000003D8D8D801FFFFFF02 + F1F1F1019090900100000007C9C9C901FFFFFF12E3E3E301707070010D0D0D01 + 00000007C4C4C401FFFFFF08E4E4E4017E7E7E010000000CFFFFFF0C0000000A + 0101010198989801959595015E5E5E0144444401030303010101010150505001 + CCCCCC014B4B4B0161616101080808010101010116161601E3E3E3014E4E4E01 + 6F6F6F01191919010101010100000007D8D8D801FFFFFF02F1F1F10190909001 + 00000003D8D8D801FFFFFF02F1F1F1019090900100000007AFAFAF01FFFFFF12 + D7D7D701707070010D0D0D0100000007ABABAB01FFFFFF08D6D6D6017E7E7E01 + 0000000DFFFFFF0A0000000CDDDDDD01616161014C4C4C010505050100000002 + 969696017E7E7E01666666010E0E0E01000000024D4D4D01B1B1B10172727201 + 1F1F1F010202020100000008D8D8D801FFFFFF02F2F2F2019191910100000003 + D8D8D801FFFFFF02F2F2F201919191010000000782828201FFFFFF12C0C0C001 + 5C5C5C010A0A0A01000000072C2C2C01EEEEEE01FFFFFF06F1F1F1019D9D9D01 + 606060010000000DFFFFFF0A0000000C23232301707070011313130101010101 + 0000000218181801555555013535350102020201000000020E0E0E013B3B3B01 + 585858010404040100000009D8D8D801FFFFFF02F2F2F2019191910100000003 + D8D8D801FFFFFF02F2F2F201919191010000000737373701F6F6F601FFFFFF10 + F8F8F8019A9A9A014646460108080801000000087D7D7D01F1F1F101FFFFFF04 + F1F1F101B9B9B9018B8B8B01202020010000000DFFFFFF0A0000000CF8F8F801 + 3B3B3B010404040100000003AFAFAF01797979010B0B0B010000000366666601 + BBBBBB01121212010101010100000009D8D8D801FFFFFF02F2F2F20191919101 + 00000003D8D8D801FFFFFF02F2F2F201919191010000000704040401C3C3C301 + FFFFFF10DCDCDC017F7F7F012F2F2F0104040401000000095F5F5F01D5D5D501 + E4E4E402D6D6D6019D9D9D018B8B8B01424242010000000DFFFFFF0C0000000B + 0404040177777701181818010101010100000002030303015656560139393901 + 020202010000000202020201343434015B5B5B010303030100000009D8D8D801 + FFFFFF02F1F1F1019292920100000003D8D8D801FFFFFF02F1F1F10192929201 + 000000070101010125252501E7E7E701FFFFFF0EEDEDED019292920162626201 + 10101001010101010000000A20202001606060017E7E7E026060600120202001 + 0000000DFFFFFF0300000003FFFFFF0200000003FFFFFF030000000B04040401 + 010101010000000403030301020202010000000402020201030303010000000A + D8D8D801FFFFFF02F2F2F2019292920100000003D8D8D801FFFFFF02F2F2F201 + 9292920100000008030303017C7C7C01F6F6F601FFFFFF0CF8F8F801B9B9B901 + 7777770125252501030303010000001DFFFFFF030000000AFFFFFF0300000022 + DEDEDE01F1F1F102F2F2F2019393930100000003DEDEDE01F0F0F002F1F1F101 + 9393930100000009090909018D8D8D01EBEBEB01FFFFFF0AEDEDED01B9B9B901 + 7D7D7D0141414101090909010000001DFFFFFF030000000CFFFFFF0300000021 + 060606018E8E8E018D8D8D018C8C8C02000000048C8C8C040000000901010101 + 0D0D0D0152525201D9D9D901F8F8F801FFFFFF06F8F8F801DCDCDC0192929201 + 77777701404040010D0D0D01010101010000001CFFFFFF030000000EFFFFFF03 + 000000370101010109090901252525017F7F7F01BBBBBB01D4D4D401E3E3E302 + D7D7D701C0C0C0019A9A9A017F7F7F0162626201252525010909090101010101 + 0000001DFFFFFF0200000010FFFFFF020000003903030301101010012F2F2F01 + 464646015C5C5C01707070025C5C5C01464646012F2F2F011010100103030301 + 0000006D0101010104040401080808010A0A0A010D0D0D020A0A0A0108080801 + 0404040101010101000000841010100140404001101010010000001A0C0C0C01 + 000000020C0C0C010000005740404001FFFFFF01707070011010100100000019 + 46464601696969016464640168686801707070010000005640404001FFFFFF02 + 70707001101010010000001A13131301171717010000005740404001FFFFFF03 + 7070700110101001000000010C0C0C01000000020C0C0C010000006D40404001 + FFFFFF0470707001101010016060600172727201626262016464640154545401 + 0000006920202001ACACAC01C8C8C801ECECEC01FFFFFF057070700110101001 + 00000001212121010A0A0A011A1A1A01282828012C2C2C011212120110101001 + 3232320108080801000000030303030185858501B8B8B801D3D3D301E0E0E001 + E1E1E104E9E9E90147474701000000545B5B5B01DEDEDE01FFFFFF0940404001 + 0000000350505001595959012D2D2D012A2A2A0124242401525252011B1B1B01 + 000000021A1A1A01C4C4C401FDFDFD01FFFFFF08A7A7A701010101010000002C + FFFFFF0200000017FFFFFF010000000C25252501E3E3E301FFFFFF03F8F8F801 + FFFFFF05BFBFBF0193939301000000032B2B2B012F2F2F01383838014D4D4D01 + 33333301373737011F1F1F010000000103030301CCCCCC01FFFFFF03F9F9F901 + F3F3F301F2F2F202F1F1F102F5F5F501A8A8A80101010101000000010C0C0C01 + 040404011111110100000002191919010000000B3A3A3A01AFAFAF01E5E5E502 + AFAFAF013A3A3A0100000014FFFFFF0200000017FFFFFF010000000CB7B7B701 + FFFFFF02EBEBEB01C0C0C001AAAAAA01FFFFFF04BFBFBF019393930100000004 + 353535014E4E4E015A5A5A013E3E3E0141414101383838011C1C1C0100000001 + 7D7D7D01FBFBFB01FFFFFF01F3F3F301CCCCCC019E9E9E019191910189898901 + 8787870186868601858585018383830182828201010101010000000156565601 + 63636301606060012B2B2B014646460162626201222222010000000978787801 + FDFDFD01FFFFFF04FEFEFE018989890100000013FFFFFF0200000017FFFFFF01 + 0000000CD3D3D301FFFFFF02C0C0C0017070700163636301FFFFFF03BFBFBF01 + 939393010000000144444401494949014E4E4E013939390100000008BDBDBD01 + FFFFFF02D8D8D801848484014242420148484801111111010101010500000004 + 010101010000000308080801000000083A3A3A01FDFDFD01FFFFFF06FEFEFE01 + 6D6D6D0100000012FFFFFF0200000017FFFFFF010000000B06060601E1E1E101 + FFFFFF01F4F4F401929292013131310144444401FFFFFF02BFBFBF0193939301 + 000000021E1E1E0117171701222222012020200100000008D1D1D101FFFFFF01 + FCFCFC01AEAEAE013B3B3B0140404001FFFFFF01707070011010100100000015 + AFAFAF01FFFFFF08DBDBDB012020200100000011FFFFFF0200000017FFFFFF01 + 0000000CD2D2D201FFFFFF02BBBBBB011818180141414101FFFFFF01BFBFBF01 + 93939301020202010000000ED0D0D001FFFFFF01FCFCFC01AEAEAE0111111101 + 40404001FFFFFF02757575011010100100000014E5E5E501FFFFFF08F3F3F301 + 6060600100000011FFFFFF0200000017FFFFFF010000000CB5B5B501FFFFFF02 + E9E9E9015757570116161601414141019393930100000010B9B9B901FFFFFF02 + D7D7D7011414140140404001FFFFFF03757575011010100100000013E5E5E501 + FFFFFF08F3F3F3017E7E7E0100000011FFFFFF0200000017FFFFFF010000000C + 29292901EBEBEB01FFFFFF02F7F7F701E4E4E401DEDEDE02DDDDDD07D2D2D201 + BDBDBD018C8C8C0108080801010101010000000461616101F8F8F801FFFFFF01 + F3F3F301AEAEAE0161616101FFFFFF04757575011010100100000012AFAFAF01 + FFFFFF08DBDBDB017E7E7E010000002AFFFFFF010000000C010101016D6D6D01 + EDEDED01FFFFFF0EFCFCFC01C6C6C601121212010202020100000004C7C7C701 + FFFFFF03F8F8F801FFFFFF057575750110101001000000021010100113131302 + 2E2E2E0112121201131313010D0D0D0116161601000000073A3A3A01FEFEFE01 + FFFFFF06FEFEFE01A6A6A6016060600100000038050505014D4D4D01D2D2D201 + E4E4E401EFEFEF01F1F1F109F8F8F801FFFFFF02FAFAFA01989898010E0E0E01 + 01010101000000030E0E0E01D6D6D601FCFCFC01FFFFFF084747470100000002 + 4C4C4C016C6C6C0176767601585858015D5D5D014F4F4F012D2D2D0131313101 + 0000000889898901FEFEFE01FFFFFF04FEFEFE01C2C2C2018B8B8B0120202001 + 00000011FFFFFF0200000017FFFFFF010000000E121212011F1F1F0150505001 + 717171017D7D7D018080800893939301DADADA01FEFEFE01FFFFFF01DCDCDC01 + 3F3F3F01060606010000000412121201B2B2B201E0E0E001F2F2F201FFFFFF05 + BFBFBF018C8C8C01000000136D6D6D01DBDBDB01F3F3F302DBDBDB01A6A6A601 + 8B8B8B014242420100000012FFFFFF0200000026777777017676760175757501 + 68686801464646010C0C0C080D0D0D012F2F2F01EEEEEE01FFFFFF01E9E9E901 + 5C5C5C010808080100000005030303013D3D3D0188888801FFFFFF04BFBFBF01 + 8C8C8C010000001520202001606060017E7E7E0260606001202020010000003D + 29292901010101013D3D3D01464646013A3A3A01262626011515150144444401 + 0E0E0E01000000030F0F0F01E7E7E701FFFFFF01F1F1F101757575010B0B0B01 + 0000000741414101FFFFFF03BFBFBF018C8C8C010000005B353535013E3E3E01 + 1C1C1C0122222201121212013F3F3F01161616010000000304040401E2E2E201 + FFFFFF01F1F1F1017F7F7F010C0C0C010000000740404001FFFFFF02BFBFBF01 + 8C8C8C010000005C414141015A5A5A01515151015D5D5D014C4C4C0154545401 + 39393901292929015C5C5C01515151010E0E0E01E7E7E701FFFFFF01F4F4F401 + 808080010C0C0C010000000740404001FFFFFF01BFBFBF018C8C8C010000005B + 0A0A0A010303030122222201303030013131310121212101222222011C1C1C01 + 0E0E0E01000000011010100111111101161616014545450197979701A0A0A001 + 737373010D0D0D01000000071010100141414101919191010000000218181801 + 303030023F3F3F01000000547070700278787801292929010000000B01010101 + 0C0C0C020B0B0B01010101010000000C2626260136363601393939013A3A3A01 + 0000005708080801000000AC0C0C0C01000000020C0C0C010000005708080801 + F8F8F8010000001B46464601696969016464640168686801707070010000000F + 040404014C4C4C0180808001B3B3B301E6E6E602B3B3B301808080014C4C4C01 + 040404010000003D08080801FFFFFF020000001C13131301171717010000000F + 29292901CBCBCB01FFFFFF08DADADA012C2C2C01000000252525250100000016 + 08080801FFFFFF03000000030C0C0C01000000020C0C0C010000002301010101 + 72727201F7F7F701FFFFFF0AFDFDFD0189898901010101010000000AFFFFFF04 + 00000004FFFFFF040000000DEDEDED015B5B5B010000001508080801FFFFFF04 + 0000000260606001727272016262620164646401545454010000002272727201 + FFFFFF0EB1B1B1010101010100000009FFFFFF0500000003FFFFFF050000000C + FFFFFF028787870100000011222222019F9F9F01D3D3D301FCFCFC01FFFFFF05 + 00000003212121010A0A0A011A1A1A01282828012C2C2C011212120110101001 + 323232010808080100000003070707017D7D7D01BCBCBC01EDEDED01FFFFFF06 + 101010010000000D29292901F7F7F701FFFFFF0F8989890100000009FFFFFF05 + 00000003FFFFFF050000000CFFFFFF03B4B4B401010101010000000E52525201 + F1F1F101FFFFFF090000000450505001595959012D2D2D012A2A2A0124242401 + 525252011B1B1B010000000228282801D1D1D101FFFFFF0A0000000C04040401 + CBCBCB01FFFFFF10FDFDFD012C2C2C0100000008FFFFFF0500000003FFFFFF05 + 0000000CFFFFFF04D7D7D7010A0A0A010000000C1E1E1E01F4F4F401FFFFFF0A + F8F8F801000000032B2B2B012F2F2F01383838014D4D4D013333330137373701 + 1F1F1F010000000105050501D6D6D601FFFFFF0B000000020C0C0C0104040401 + 111111010000000219191901000000044C4C4C01FFFFFF12DADADA0104040401 + 00000007FFFFFF0500000003FFFFFF050000000CFFFFFF05EDEDED0120202001 + 0000000B9E9E9E01FFFFFF0AF8F8F80100000004353535014E4E4E015A5A5A01 + 3E3E3E0141414101383838011C1C1C01000000016E6E6E01FFFFFF06F0F0F006 + 000000025656560163636301606060012B2B2B01464646016262620122222201 + 000000037F7F7F01FFFFFF134C4C4C0100000007FFFFFF0500000003FFFFFF05 + 0000000CFFFFFF06F9F9F901414141010000000AD8D8D801FFFFFF03DEDEDE01 + 4B4B4B01FFFFFF04F8F8F8010000000144444401494949014E4E4E0139393901 + 00000008B9B9B901FFFFFF03F3F3F30161616101121212010000000A01010101 + 000000030808080100000003B3B3B301FFFFFF137F7F7F0100000007FFFFFF05 + 00000003FFFFFF050000000CFFFFFF07FDFDFD01696969010000000801010101 + FAFAFA01FFFFFF034545450108080801FFFFFF03F8F8F801000000021E1E1E01 + 17171701222222012020200100000008E5E5E501FFFFFF036B6B6B0100000001 + FFFFFF0100000012E6E6E601FFFFFF13B3B3B30100000007FFFFFF0500000003 + FFFFFF050000000CFFFFFF099696960100000008DDDDDD01FFFFFF030B0B0B01 + 08080801F8F8F801FFFFFF01FCFCFC010000000FE5E5E501FFFFFF031D1D1D01 + 00000001FFFFFF021010100100000010E6E6E601FFFFFF13E6E6E60100000007 + FFFFFF0500000003FFFFFF050000000CFFFFFF09FDFDFD016C6C6C0100000007 + A5A5A501FFFFFF03696969010909090108080801F8F8F80100000010B9B9B901 + FFFFFF032323230100000001FFFFFF03101010010000000FB3B3B301FFFFFF13 + E6E6E60100000007FFFFFF0500000003FFFFFF050000000CFFFFFF09FCFCFC01 + 6C6C6C010000000725252501FDFDFD01FFFFFF0DEDEDED01BEBEBE018A8A8A01 + 080808010000000569696901FFFFFF03B9B9B9011F1F1F01FFFFFF0410101001 + 0000000E7F7F7F01FFFFFF13B3B3B30100000007FFFFFF0500000003FFFFFF05 + 0000000CFFFFFF08F2F2F201494949010000000977777701FFFFFF10D9D9D901 + 0A0A0A010000000403030301E2E2E201FFFFFF09101010010000000310101001 + 131313022E2E2E0112121201131313010D0D0D0116161601000000024C4C4C01 + FFFFFF137F7F7F0100000007FFFFFF0500000003FFFFFF050000000CFFFFFF07 + E1E1E1012D2D2D010000000B7A7A7A01FCFCFC01FFFFFF0FD1D1D10102020201 + 0000000426262601F4F4F401FFFFFF0910101001000000024C4C4C016C6C6C01 + 76767601585858015D5D5D014F4F4F012D2D2D01313131010000000204040401 + DADADA01FFFFFF124C4C4C0100000007FFFFFF0500000003FFFFFF050000000C + FFFFFF06C9C9C901181818010000000C0C0C0C0129292901A1A1A101D6D6D601 + FCFCFC01FFFFFF0D6F6F6F010000000521212101E1E1E101FFFFFF08F0F0F001 + 0000000D2C2C2C01FDFDFD01FFFFFF10CBCBCB010404040100000007FFFFFF05 + 00000003FFFFFF050000000CFFFFFF05ABABAB01090909010000000D77777701 + 7575750171717101626262013D3D3D010000000948484801FFFFFF03A9A9A901 + 00000006040404016F6F6F01ACACAC01FFFFFF05F0F0F0010000000F89898901 + FFFFFF0FF7F7F7012929290100000008FFFFFF0500000003FFFFFF050000000C + FFFFFF0486868601010101010000001029292901010101013D3D3D0146464601 + 3A3A3A012626260115151501444444010E0E0E01000000030E0E0E01FFFFFF03 + D9D9D90100000009FFFFFF04F0F0F0010000001001010101B1B1B101FFFFFF0E + 7272720100000009FFFFFF0500000003FFFFFF050000000CEDEDED01FFFFFF01 + F9F9F9016060600100000014353535013E3E3E011C1C1C012222220112121201 + 3F3F3F01161616010000000308080801FFFFFF03F2F2F20100000009FFFFFF03 + F0F0F001000000120101010189898901FDFDFD01FFFFFF0AF7F7F70172727201 + 010101010000000AFFFFFF0400000004FFFFFF040000000C25252501EDEDED01 + 3F3F3F0100000015414141015A5A5A01515151015D5D5D014C4C4C0154545401 + 39393901292929015C5C5C015151510111111101FFFFFF03F7F7F70100000009 + FFFFFF02F0F0F001000000152C2C2C01DADADA01FFFFFF08CBCBCB0129292901 + 0000002525252501000000140A0A0A0103030301222222013030300131313101 + 21212101222222011C1C1C010E0E0E0100000001101010011111110116161601 + 08080801FFFFFF02F8F8F8010000000902020201FBFBFB010000000218181801 + 303030023F3F3F0100000011040404014C4C4C0180808001B3B3B301E6E6E602 + B3B3B301808080014C4C4C010404040100000039707070027878780129292901 + 0000000C050505010000000F2626260136363601393939013A3A3A0100000057 + 080808010000002B0C0C0C01000000020C0C0C01000000350C0C0C0100000002 + 0C0C0C010000000B0C0C0C01000000020C0C0C010000002C4646460169696901 + 6464640168686801707070010000001708080801F8F8F8010000001B46464601 + 696969016464640168686801707070010000000A464646016969690164646401 + 68686801707070010000002D13131301171717021A1A1A013B3B3B010B0B0B01 + 17171701282828011111110100000005050505010000000B08080801FFFFFF02 + 0000001C13131301171717010000000D13131301171717021A1A1A013B3B3B01 + 0B0B0B01171717012828280111111101000000053D3D3D014040400200000021 + 414141014D4D4D01494949011A1A1A0135353501474747012424240100000004 + 03030301FFFFFF02F8F8F8010000000908080801FFFFFF03000000030C0C0C01 + 000000020C0C0C0100000025414141014D4D4D01494949011A1A1A0135353501 + 474747012424240100000005E6E6E601FFFFFF01E9E9E9010C0C0C0101010101 + 0000001F262626012F2F2F01353535014747470136363601303030011E1E1E01 + 2A2A2A011F1F1F014D4D4D012828280108080801FFFFFF03F8F8F80100000008 + 08080801FFFFFF04000000026060600172727201626262016464640154545401 + 00000024262626012F2F2F01353535014747470136363601303030011E1E1E01 + 2A2A2A011F1F1F014D4D4D012828280104040401E3E3E301FFFFFF01F0F0F001 + 747474010B0B0B010000001F2F2F2F014C4C4C0157575701393939013D3D3D01 + 2E2E2E012323230124242401181818013D3D3D01161616010E0E0E01FFFFFF03 + F7F7F70100000005222222019F9F9F01D3D3D301FCFCFC01FFFFFF0500000003 + 212121010A0A0A011A1A1A01282828012C2C2C01121212011010100132323201 + 0808080100000003070707017D7D7D01BCBCBC01EDEDED01FFFFFF0610101001 + 000000102F2F2F014C4C4C0157575701393939013D3D3D012E2E2E0123232301 + 24242401181818013D3D3D01161616010C0C0C01E5E5E501FFFFFF01F1F1F101 + 808080010C0C0C010000001B2D2D2D01464646014A4A4A01505050010000000B + 30303001FFFFFF03F2F2F2010000000452525201F1F1F101FFFFFF0900000004 + 50505001595959012D2D2D012A2A2A0124242401525252011B1B1B0100000002 + 28282801D1D1D101FFFFFF0A0000000C2D2D2D01464646014A4A4A0150505001 + 0000000B16161601E8E8E801FFFFFF01EDEDED017A7A7A010B0B0B010000001B + 111111011D1D1D011F1F1F012A2A2A010000000A1D1D1D019B9B9B01FFFFFF03 + D9D9D901000000031E1E1E01F4F4F401FFFFFF0AF8F8F801000000032B2B2B01 + 2F2F2F01383838014D4D4D0133333301373737011F1F1F010000000105050501 + D6D6D601FFFFFF0B000000020C0C0C0104040401111111010000000219191901 + 00000004111111011D1D1D011F1F1F012A2A2A010000000A26262601B8B8B801 + FCFCFC01FFFFFF01E2E2E2016E6E6E010A0A0A010000000A2D2D2D01ACACAC01 + C5C5C501C4C4C401ABABAB012C2C2C010000000C29292901A1A1A101D4D4D401 + FCFCFC01FFFFFF0EA9A9A901000000039E9E9E01FFFFFF0AF8F8F80100000004 + 353535014E4E4E015A5A5A013E3E3E0141414101383838011C1C1C0100000001 + 6E6E6E01FFFFFF06F0F0F006000000025656560163636301606060012B2B2B01 + 4646460162626201222222010000000442424201B8B8B801CECECE01DFDFDF01 + E1E1E109EFEFEF01FFFFFF03CFCFCF0159595901080808010000000973737301 + E5E5E501FFFFFF04EEEEEE017D7D7D010000000A60606001F6F6F601FFFFFF11 + 6F6F6F0100000003D8D8D801FFFFFF03DEDEDE014B4B4B01FFFFFF04F8F8F801 + 0000000144444401494949014E4E4E013939390100000008B9B9B901FFFFFF03 + F3F3F30161616101121212010000000A01010101000000030808080100000003 + 83838301E9E9E901FFFFFF0FE7E7E701878787013D3D3D010505050100000008 + 2D2D2D01E5E5E501FFFFFF06F1F1F1015F5F5F010000000825252501FAFAFA01 + FFFFFF11ADADAD01020202010000000201010101FAFAFA01FFFFFF0345454501 + 08080801FFFFFF03F8F8F801000000021E1E1E01171717012222220120202001 + 00000008E5E5E501FFFFFF036B6B6B0100000001FFFFFF01000000112A2A2A01 + E8E8E801FFFFFF02FCFCFC01F2F2F201F1F1F104F2F2F204F3F3F301EDEDED01 + E1E1E101CBCBCB0187878701585858010D0D0D0100000009ACACAC01FFFFFF08 + D5D5D5012020200100000007A5A5A501FFFFFF0FEDEDED01BEBEBE018A8A8A01 + 0808080100000004DDDDDD01FFFFFF030B0B0B0108080801F8F8F801FFFFFF01 + FCFCFC010000000FE5E5E501FFFFFF031D1D1D0100000001FFFFFF0210101001 + 0000000FB0B0B001FFFFFF02EAEAEA01AAAAAA018E8E8E01A1A1A10189898901 + 8282820183838301848484018585850286868601878787018080800177777701 + 6262620147474701101010010101010100000009C5C5C501FFFFFF08E4E4E401 + 6060600100000007DDDDDD01FFFFFF03D6D6D60145454501F8F8F80100000011 + A5A5A501FFFFFF03696969010909090108080801F8F8F80100000010B9B9B901 + FFFFFF032323230100000001FFFFFF03101010010000000EC7C7C701FFFFFF02 + B7B7B7016C6C6C0162626201FFFFFF01777777011B1B1B010C0C0C070B0B0B01 + 0909090106060601010101010000000AC4C4C401FFFFFF08E4E4E4017E7E7E01 + 0000000601010101FAFAFA01FFFFFF033838380108080801FFFFFF0200000010 + 25252501FDFDFD01FFFFFF0DEDEDED01BEBEBE018A8A8A010808080100000005 + 69696901FFFFFF03B9B9B9011F1F1F01FFFFFF04101010010000000DD2D2D201 + FFFFFF01F7F7F701959595012B2B2B0144444401FFFFFF027070700110101001 + 00000014ABABAB01FFFFFF08D6D6D6017E7E7E0100000007D8D8D801FFFFFF03 + 0B0B0B0108080801FFFFFF0300000002282828012E2E2E023F3F3F0135353501 + 020202010000000877777701FFFFFF10D9D9D9010A0A0A010000000403030301 + E2E2E201FFFFFF09101010010000000310101001131313022E2E2E0112121201 + 131313010D0D0D011616160100000001C8C8C801FFFFFF02C6C6C60115151501 + 41414101FFFFFF037070700110101001282828012E2E2E023F3F3F0135353501 + 020202010000000D2C2C2C01EEEEEE01FFFFFF06F1F1F1019D9D9D0160606001 + 000000079E9E9E01FFFFFF037777770112121201FFFFFF04000000011B1B1B01 + 3D3D3D014B4B4B015F5F5F013333330104040401000000097A7A7A01FCFCFC01 + FFFFFF0FD1D1D101020202010000000426262601F4F4F401FFFFFF0910101001 + 000000024C4C4C016C6C6C0176767601585858015D5D5D014F4F4F012D2D2D01 + 3131310100000001ADADAD01FFFFFF02EFEFEF017F7F7F014A4A4A01FFFFFF04 + 70707001292929013D3D3D014B4B4B015F5F5F0133333301040404010000000E + 7D7D7D01F1F1F101FFFFFF04F1F1F101B9B9B9018B8B8B012020200100000007 + 1E1E1E01FBFBFB01FFFFFF09000000042F2F2F01545454015E5E5E012C2C2C01 + 575757013232320130303001000000040C0C0C0129292901A1A1A101D6D6D601 + FCFCFC01FFFFFF0D6F6F6F010000000521212101E1E1E101FFFFFF08F0F0F001 + 0000000B22222201EBEBEB01FFFFFF02FDFDFD01F2F2F201FFFFFF0570707001 + 10101001000000022F2F2F01545454015E5E5E012C2C2C015757570132323201 + 303030010000000A5F5F5F01D5D5D501E4E4E402D6D6D6019D9D9D018B8B8B01 + 424242010000000966666601FEFEFE01FFFFFF09000000030E0E0E011B1B1B02 + 1D1D1D010C0C0C011D1D1D012424240100000004777777017575750171717101 + 626262013D3D3D010000000948484801FFFFFF03A9A9A9010000000604040401 + 6F6F6F01ACACAC01FFFFFF05F0F0F0010000000C010101016D6D6D01ECECEC01 + FFFFFF0940404001000000020E0E0E011B1B1B021D1D1D010C0C0C011D1D1D01 + 242424010000000B20202001606060017E7E7E0260606001202020010000000B + 69696901FAFAFA01FFFFFF08F8F8F80100000002414141016868680171717101 + 6B6B6B016D6D6D015B5B5B014A4A4A0157575701000000052929290101010101 + 3D3D3D01464646013A3A3A012626260115151501444444010E0E0E0100000003 + 0E0E0E01FFFFFF03D9D9D90100000009FFFFFF04F0F0F0010000000E05050501 + 50505001D0D0D001E5E5E501F7F7F701FFFFFF05BFBFBF018F8F8F0100000002 + 4141410168686801717171016B6B6B016D6D6D015B5B5B014A4A4A0157575701 + 0000001C222222019F9F9F01D4D4D401FFFFFF05F8F8F8011212120110101001 + 2A2A2A01020202010000000114141401010101010000000B353535013E3E3E01 + 1C1C1C0122222201121212013F3F3F01161616010000000308080801FFFFFF03 + F2F2F20100000009FFFFFF03F0F0F00100000010060606011E1E1E0152525201 + 92929201FFFFFF04BFBFBF019090900112121201101010012A2A2A0102020201 + 0000000114141401010101010000002208080801FFFFFF04F8F8F80128282801 + 5C5C5C014F4F4F0154545401060606010000000E414141015A5A5A0151515101 + 5D5D5D014C4C4C015454540139393901292929015C5C5C015151510111111101 + FFFFFF03F7F7F70100000009FFFFFF02F0F0F001000000120202020107070701 + 47474701FFFFFF03BFBFBF018F8F8F01282828015C5C5C014F4F4F0154545401 + 060606010000002508080801FFFFFF03F8F8F801000000120A0A0A0103030301 + 22222201303030013131310121212101222222011C1C1C010E0E0E0100000001 + 10101001111111011616160108080801FFFFFF02F8F8F8010000000902020201 + FBFBFB010000000218181801303030023F3F3F010000000F40404001FFFFFF02 + BFBFBF018F8F8F010000002B08080801F8F8F801FFFFFF01F8F8F80100000011 + 7070700278787801292929010000000C050505010000000F2626260136363601 + 393939013A3A3A010000000F40404001FFFFFF01BFBFBF018F8F8F010000002D + 08080801F8F8F80100000015080808010000002F10101001434343018F8F8F01 + 00000027 + } + end + object selecteditpage: taction + caption = 'Select &Edit Page' + options = [ao_globalshortcut] + onexecute = selecteditpageonexecute + left = 280 + top = 120 + sc = ( + 1 + 16453 + ) + end + object indent: taction + caption = '&Indent' + onexecute = indentonexecute + left = 280 + top = 136 + sc = ( + 1 + 16457 + ) + end + object unindent: taction + caption = 'U&nindent' + onexecute = unidentonexecute + left = 280 + top = 152 + sc = ( + 1 + 16469 + ) + end + object toggleformunit: taction + caption = 'Toggle Form/&Unit' + onexecute = toggleformunitonexecute + left = 152 + top = 104 + sc = ( + 1 + 315 + ) + end + object nexti: taction + imagelist = buttonicons + caption = 'Next Instruction' + imagenr = 13 + imagenrdisabled = 19 + onexecute = nextiactonexecute + left = 80 + top = 208 + sc = ( + 1 + 24887 + ) + end + object stepi: taction + imagelist = buttonicons + caption = 'Step Instruction' + imagenr = 12 + imagenrdisabled = 21 + onexecute = stepiactonexecute + left = 80 + top = 224 + sc = ( + 1 + 24886 + ) + end + object bluedotsonact: taction + imagelist = buttonicons + caption = 'Exec Line Hint on' + state = [as_checked] + imagenr = 14 + hint = 'Executable lines hint on/off' + statfile = mainfo.projectstatfile + onchange = bluedotsononchange + left = 152 + top = 269 + end + object replace: taction + caption = 'Find && &Replace' + onexecute = replaceactonexecute + left = 208 + top = 16 + sc = ( + 1 + 16466 + ) + end + object print: taction + caption = '&Print' + onexecute = printactonexecute + left = 8 + top = 100 + end + object detachtarget: taction + caption = 'Detach' + onexecute = ondetachtarget + left = 8 + top = 136 + end + object attachprocess: taction + caption = 'Attach Process' + onexecute = onattachprocess + left = 8 + top = 152 + end + object lowercase: taction + caption = '&Lowercase' + onexecute = lowercaseexecute + onupdate = enableonselect + left = 360 + top = 136 + end + object uppercase: taction + caption = '&Uppercase' + onexecute = uppercaseexecute + onupdate = enableonselect + left = 360 + top = 152 + end + object shortcuts: tshortcutcontroller + actions.count = 98 + actions.items = < + item + dispname = 'File' + end + item + action = opensource + dispname = 'Open' + sc = ( + 1 + 16463 + ) + end + item + action = save + dispname = 'Save' + sc = ( + 1 + 16467 + ) + end + item + action = saveall + dispname = 'Save all' + end + item + action = saveas + dispname = 'Save as' + end + item + action = close + dispname = 'Close' + sc = ( + 1 + 16691 + ) + end + item + action = closeall + dispname = 'Close all' + end + item + action = print + dispname = 'Print' + end + item + dispname = 'Search' + end + item + action = line + dispname = 'Line' + sc = ( + 1 + 16460 + ) + end + item + action = find + dispname = 'Find' + sc = ( + 1 + 16454 + ) + end + item + action = repeatfind + dispname = 'Search again' + sc = ( + 1 + 306 + ) + end + item + action = findback + dispname = 'Search back' + sc = ( + 1 + 8498 + ) + end + item + action = replace + dispname = 'Find and replace' + sc = ( + 1 + 16466 + ) + end + item + action = findinfile + dispname = 'Find in File' + sc = ( + 1 + 24646 + ) + end + item + dispname = 'Edit' + end + item + action = selecteditpage + dispname = 'Select Editpage' + sc = ( + 1 + 16453 + ) + end + item + action = copyword + dispname = 'Copy Word at Cursor' + sc = ( + 1 + 24663 + ) + end + item + action = indent + dispname = 'Indent' + sc = ( + 1 + 16457 + ) + end + item + action = unindent + dispname = 'Unindent' + sc = ( + 1 + 16469 + ) + end + item + action = comment + dispname = 'Comment Selection' + sc = ( + 2 + 16459 + 67 + ) + end + item + action = uncomment + dispname = 'Uncomment Selection' + sc = ( + 2 + 16459 + 85 + ) + end + item + action = lowercase + dispname = 'Lowercase' + end + item + action = uppercase + dispname = 'Uppercase' + end + item + action = copylatexact + dispname = 'Copy LaTeX' + sc = ( + 2 + 16459 + 76 + ) + end + item + action = sourcefo.completeclassact + dispname = 'Complete Class' + sc = ( + 1 + 24641 + ) + end + item + action = instemplate + dispname = 'Insert Template' + sc = ( + 1 + 16468 + ) + end + item + action = sourcefo.navigbackact + dispname = 'Navigate Back' + sc = ( + 1 + 16456 + ) + end + item + action = sourcefo.navigforwardact + dispname = 'Navigate Forward' + sc = ( + 1 + 24648 + ) + end + item + dispname = 'Set Bookmark' + end + item + action = setbm0 + dispname = 'Set Bookmark 0' + sc = ( + 1 + 24624 + ) + end + item + action = setbm1 + dispname = 'Set Bookmark 1' + sc = ( + 1 + 24625 + ) + end + item + action = setbm2 + dispname = 'Set Bookmark 2' + sc = ( + 1 + 24626 + ) + end + item + action = setbm3 + dispname = 'Set Bookmark 3' + sc = ( + 1 + 24627 + ) + end + item + action = setbm4 + dispname = 'Set Bookmark 4' + sc = ( + 1 + 24628 + ) + end + item + action = setbm5 + dispname = 'Set Bookmark 5' + sc = ( + 1 + 24629 + ) + end + item + action = setbm6 + dispname = 'Set Bookmark 6' + sc = ( + 1 + 24630 + ) + end + item + action = setbm7 + dispname = 'Set Bookmark 7' + sc = ( + 1 + 24631 + ) + end + item + action = setbm8 + dispname = 'Set Bookmark 8' + sc = ( + 1 + 24632 + ) + end + item + action = setbm9 + dispname = 'Set Bookmark 9' + sc = ( + 1 + 24633 + ) + end + item + action = setbmnone + dispname = 'Clear Bookmark' + end + item + dispname = 'Find Bookmark' + end + item + action = findbm0 + dispname = 'Find Bookmark 0' + sc = ( + 1 + 16432 + ) + end + item + action = findbm1 + dispname = 'Find Bookmark 1' + sc = ( + 1 + 16433 + ) + end + item + action = findbm2 + dispname = 'Find Bookmark 2' + sc = ( + 1 + 16434 + ) + end + item + action = findbm3 + dispname = 'Find Bookmark 3' + sc = ( + 1 + 16435 + ) + end + item + action = findbm4 + dispname = 'Find Bookmark 4' + sc = ( + 1 + 16436 + ) + end + item + action = findbm5 + dispname = 'Find Bookmark 5' + sc = ( + 1 + 16437 + ) + end + item + action = findbm6 + dispname = 'Find Bookmark 6' + sc = ( + 1 + 16438 + ) + end + item + action = findbm7 + dispname = 'Find Bookmark 7' + sc = ( + 1 + 16439 + ) + end + item + action = findbm8 + dispname = 'Find Bookmark 8' + sc = ( + 1 + 16440 + ) + end + item + action = findbm9 + dispname = 'Find Bookmark 9' + sc = ( + 1 + 16441 + ) + end + item + dispname = 'Target' + end + item + action = attachprocess + dispname = 'Attach Process' + end + item + action = detachtarget + dispname = 'Detach Target' + end + item + action = continue + dispname = 'Continue' + sc = ( + 1 + 312 + ) + end + item + action = reset + dispname = 'Reset' + end + item + action = interrupt + dispname = 'Interrupt' + end + item + action = next + dispname = 'Next' + sc = ( + 1 + 311 + ) + end + item + action = nexti + dispname = 'Next Instruction' + sc = ( + 1 + 24887 + ) + end + item + action = step + dispname = 'Step' + sc = ( + 1 + 310 + ) + end + item + action = stepi + dispname = 'Step Instruction' + sc = ( + 1 + 24886 + ) + end + item + action = finish + dispname = 'Finish' + sc = ( + 1 + 8502 + ) + end + item + action = bkptsonact + dispname = 'Breakpoints on/off' + sc = ( + 1 + 16450 + ) + end + item + action = togglebkpt + dispname = 'Toggle Breakpoint' + sc = ( + 1 + 308 + ) + end + item + action = togglebkptenable + dispname = 'Toggle Breakpoint enabled' + sc = ( + 1 + 8500 + ) + end + item + action = watchesonact + dispname = 'Watches on/off' + sc = ( + 1 + 16471 + ) + end + item + action = bluedotsonact + dispname = 'Exec Line Hints on/off' + end + item + dispname = 'View' + end + item + action = toggleinspector + dispname = 'Toggle Form/Object Inspector' + sc = ( + 1 + 314 + ) + end + item + action = toggleformunit + dispname = 'Toggle Form/Unit' + sc = ( + 1 + 315 + ) + end + item + dispname = 'Project' + end + item + action = makeact + dispname = 'Make' + end + item + action = buildact + dispname = 'Build' + end + item + action = make1act + dispname = 'Make 1' + end + item + action = make2act + dispname = 'Make 2' + end + item + action = make3act + dispname = 'Make 3' + end + item + action = make4act + dispname = 'Make 4' + end + item + action = abortmakeact + dispname = 'Abort Make' + end + item + action = projectoptionsact + dispname = 'Options' + end + item + action = projectopenact + dispname = 'Open' + end + item + action = projectsaveact + dispname = 'Save' + end + item + action = projecttreeact + dispname = 'Tree' + end + item + action = projectsourceact + dispname = 'Source' + end + item + action = projectcloseact + dispname = 'Close' + end + item + dispname = 'Help' + end + item + action = helpact + dispname = 'Help' + sc = ( + 1 + 304 + ) + end + item + dispname = 'Tools' + end + item + action = tool0 + dispname = 'Tool 1' + end + item + action = tool1 + dispname = 'Tool 2' + end + item + action = tool2 + dispname = 'Tool 3' + end + item + action = tool3 + dispname = 'Tool 4' + end + item + action = tool4 + dispname = 'Tool 5' + end + item + action = tool5 + dispname = 'Tool 6' + end + item + action = tool6 + dispname = 'Tool 7' + end + item + action = tool7 + dispname = 'Tool 8' + end + item + action = tool8 + dispname = 'Tool 9' + end + item + action = tool9 + dispname = 'Tool 10' + end> + sysshortcuts.count = 11 + sysshortcuts.items = ( + 16451 + 16470 + 16472 + 16449 + 16646 + 24838 + 16647 + 24643 + 24662 + 16474 + 24666 + ) + sysshortcuts1.count = 11 + sysshortcuts1.items = ( + 0 + 8454 + 8455 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ) + assistiveshortcuts.count = 9 + assistiveshortcuts.items = ( + ( + 16416 + ) + ( + 24608 + ) + ( + 16473 + 70 + ) + ( + 16473 + 76 + ) + ( + 16473 + 67 + ) + ( + 18477 + ) + ( + 18475 + ) + ( + 26669 + ) + ( + 26667 + ) + ) + assistiveshortcuts1.count = 9 + assistiveshortcuts1.items = ( + ( + 18692 + ) + ( + 26884 + ) + ( ) + ( ) + ( ) + ( ) + ( ) + ( ) + ( ) + ) + statfile = mainfo.mainstatfile + onafterupdate = updateshortcuts + left = 352 + top = 8 + end + object toggleinspector: taction + caption = 'Toggle Form/Inspector' + left = 152 + top = 120 + sc = ( + 1 + 314 + ) + end + object buildact: taction + onexecute = makeactonexecute + left = 8 + top = 312 + end + object make1act: taction + onexecute = makeactonexecute + left = 8 + top = 330 + end + object make2act: taction + onexecute = makeactonexecute + left = 8 + top = 348 + end + object make3act: taction + onexecute = makeactonexecute + left = 8 + top = 366 + end + object make4act: taction + onexecute = makeactonexecute + left = 8 + top = 384 + end + object download: taction + caption = 'Download' + onexecute = downloadexe + left = 8 + top = 168 + end + object helpact: taction + options = [ao_globalshortcut] + onexecute = helpex + left = 280 + top = 400 + sc = ( + 1 + 304 + ) + end + object attachtarget: taction + caption = 'Attach Target' + onexecute = onattachtarget + left = 8 + top = 120 + end + object setbm0: taction + caption = 'Bookmark &0' + onexecute = setbmexec + left = 280 + top = 208 + sc = ( + 1 + 24624 + ) + end + object findbm0: taction + caption = 'Bookmark &0' + onexecute = findbmexec + left = 360 + top = 208 + sc = ( + 1 + 16432 + ) + end + object findbm1: taction + caption = 'Bookmark &1' + tagaction = 1 + onexecute = findbmexec + left = 360 + top = 224 + sc = ( + 1 + 16433 + ) + end + object setbm1: taction + caption = 'Bookmark &1' + tagaction = 1 + onexecute = setbmexec + left = 280 + top = 224 + sc = ( + 1 + 24625 + ) + end + object findbm2: taction + caption = 'Bookmark &2' + tagaction = 2 + onexecute = findbmexec + left = 360 + top = 240 + sc = ( + 1 + 16434 + ) + end + object setbm2: taction + caption = 'Bookmark &2' + tagaction = 2 + onexecute = setbmexec + left = 280 + top = 240 + sc = ( + 1 + 24626 + ) + end + object findbm3: taction + caption = 'Bookmark &3' + tagaction = 3 + onexecute = findbmexec + left = 360 + top = 256 + sc = ( + 1 + 16435 + ) + end + object setbm3: taction + caption = 'Bookmark &3' + tagaction = 3 + onexecute = setbmexec + left = 280 + top = 256 + sc = ( + 1 + 24627 + ) + end + object findbm4: taction + caption = 'Bookmark &4' + tagaction = 4 + onexecute = findbmexec + left = 360 + top = 272 + sc = ( + 1 + 16436 + ) + end + object setbm4: taction + caption = 'Bookmark &4' + tagaction = 4 + onexecute = setbmexec + left = 280 + top = 272 + sc = ( + 1 + 24628 + ) + end + object findbm5: taction + caption = 'Bookmark &5' + tagaction = 5 + onexecute = findbmexec + left = 360 + top = 288 + sc = ( + 1 + 16437 + ) + end + object setbm5: taction + caption = 'Bookmark &5' + tagaction = 5 + onexecute = setbmexec + left = 280 + top = 288 + sc = ( + 1 + 24629 + ) + end + object findbm6: taction + caption = 'Bookmark &6' + tagaction = 6 + onexecute = findbmexec + left = 360 + top = 304 + sc = ( + 1 + 16438 + ) + end + object setbm6: taction + Tag = 6 + caption = 'Bookmark &6' + tagaction = 6 + onexecute = setbmexec + left = 280 + top = 304 + sc = ( + 1 + 24630 + ) + end + object findbm7: taction + caption = 'Bookmark &7' + tagaction = 7 + onexecute = findbmexec + left = 360 + top = 320 + sc = ( + 1 + 16439 + ) + end + object setbm7: taction + caption = 'Bookmark &7' + tagaction = 7 + onexecute = setbmexec + left = 280 + top = 320 + sc = ( + 1 + 24631 + ) + end + object findbm8: taction + caption = 'Bookmark &8' + tagaction = 8 + onexecute = findbmexec + left = 360 + top = 336 + sc = ( + 1 + 16440 + ) + end + object setbm8: taction + caption = 'Bookmark &8' + tagaction = 8 + onexecute = setbmexec + left = 280 + top = 336 + sc = ( + 1 + 24632 + ) + end + object findbm9: taction + caption = 'Bookmark &9' + tagaction = 9 + onexecute = findbmexec + left = 360 + top = 352 + sc = ( + 1 + 16441 + ) + end + object setbm9: taction + caption = 'Bookmark &9' + tagaction = 9 + onexecute = setbmexec + left = 280 + top = 352 + sc = ( + 1 + 24633 + ) + end + object setbmnone: taction + caption = 'none' + tagaction = -1 + onexecute = setbmexec + left = 280 + top = 368 + end + object instemplate: taction + onexecute = instemplateactonexecute + left = 368 + top = 96 + sc = ( + 1 + 16468 + ) + end + object projectopenact: taction + caption = 'O&pen' + onexecute = projectopenexe + left = 112 + top = 296 + end + object projectoptionsact: taction + caption = '&Options' + onexecute = projectoptionsexe + left = 112 + top = 312 + end + object projecttreeact: taction + caption = '&Tree' + onexecute = projecttreeexe + left = 112 + top = 328 + end + object projectsourceact: taction + caption = 'So&urce' + onexecute = projectsourceexe + left = 112 + top = 344 + end + object projectsaveact: taction + caption = '&Save' + onexecute = projectsaveexe + left = 112 + top = 360 + end + object projectcloseact: taction + caption = '&Close' + onexecute = projectcloeseexe + left = 112 + top = 376 + end + object c: tstringcontainer + onreadstate = creadstateexe + strings.data = ( + 'Configure MSEide' + 'Process ID' + 'Attach to process' + 'Unknown moduleclass for "' + 'Inherited component "' + '" can not be deleted.' + 'ERROR' + 'Make aborted.' + 'Download aborted.' + 'Runerror with "' + 'Error: Timeout.' + 'Making.' + 'Make not running.' + 'Downloading.' + 'Download not running.' + '" running.' + 'Script' + 'Recursive form inheritance of "' + 'Component "' + '" exists.' + 'Ancestor for "' + '" not found.' + 'Module "' + 'Invalid name "' + 'Invalid methodname' + 'Module not found' + 'Method not found' + 'Published (managed) method' + 'does not exist.' + 'Do you wish to delete the event?' + 'WARNING' + 'Method' + 'has different parameters.' + 'A module "' + '" is already open.' + 'Unresolved reference(s) to' + 'Module(s):' + 'Can not read formfile "' + 'Invalid component name.' + 'Invalid exception' + 'T&ools' + 'Forms' + 'Source' + 'All Files' + 'Program' + 'Unit' + 'Textfile' + 'Mainform' + 'Simple Form' + 'Docking Form' + 'Datamodule' + 'Subform' + 'Scrollboxform' + 'Tabform' + 'Dockpanel' + 'Report' + 'Scriptform' + 'Inherited Form' + 'Do you want to replace the settings by' + 'File "' + 'Do you want to overwrite?' + 'Unknown' + 'Error' + 'Startup' + 'Exception' + 'GDB died' + 'Breakpoint hit' + 'Watchpoint triggered' + 'Read Watchpoint triggered' + 'Access Watchpoint triggered' + 'End stepping range' + 'Function finished' + 'Exited normally' + 'Exited' + 'Detached' + 'Signal received' + 'Stop error' + 'Can not read project' + 'About' + 'Object Inspector' + 'Store Component' + 'Attaching Process' + 'Loading' + 'Sizing Form' + ) + left = 392 + top = 400 + end + object copylatexact: taction + caption = 'Copy &LaTeX' + onexecute = copylatexactonexecute + left = 368 + top = 80 + sc = ( + 2 + 16459 + 76 + ) + end + object findcompact: taction + onexecute = findcompexe + left = 152 + top = 152 + sc = ( + 1 + 16454 + ) + end + object findcompallact: taction + caption = '&Find Component' + onexecute = findcompallexe + left = 152 + top = 168 + end + object forcezorderact: taction + caption = 'Force &Z-Order' + onchange = forcezorderexe + left = 136 + top = 400 + end + object tool0: taction + left = 472 + top = 8 + end + object tool1: taction + left = 472 + top = 24 + end + object tool2: taction + left = 472 + top = 40 + end + object tool3: taction + left = 472 + top = 56 + end + object tool4: taction + left = 472 + top = 72 + end + object tool5: taction + left = 472 + top = 88 + end + object tool6: taction + left = 472 + top = 104 + end + object tool7: taction + left = 472 + top = 120 + end + object tool8: taction + left = 472 + top = 136 + end + object tool9: taction + left = 472 + top = 152 + end + object comment: taction + caption = '&Comment' + onexecute = commentonexecute + onupdate = enablecomment + left = 280 + top = 168 + sc = ( + 2 + 16459 + 67 + ) + end + object uncomment: taction + caption = 'Unc&omment' + onexecute = uncommentonexecute + onupdate = enableuncomment + left = 280 + top = 184 + sc = ( + 2 + 16459 + 85 + ) + end + object copyword: taction + caption = 'Copy &Word at Cursor' + options = [ao_globalshortcut] + onexecute = selectwordactiononexecute + left = 280 + top = 100 + sc = ( + 1 + 24663 + ) + end + object selectall: taction + caption = 'Select &all' + onexecute = seleclallactonexecute + left = 344 + top = 56 + sc = ( + 1 + 16449 + ) + end + object tabtospace: taction + caption = '&Tabs to space' + onexecute = tabtospaceexecute + onupdate = enableonselect + left = 360 + top = 168 + end + object findback: taction + caption = 'Search &back' + onexecute = findbackonexecute + left = 152 + top = 60 + sc = ( + 1 + 8498 + ) + end +end diff --git a/mseide-msegui/apps/ide/actionsmodule.pas b/mseide-msegui/apps/ide/actionsmodule.pas new file mode 100644 index 0000000..3d6ea73 --- /dev/null +++ b/mseide-msegui/apps/ide/actionsmodule.pas @@ -0,0 +1,918 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit actionsmodule; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mseclasses,mseact,mseactions,msebitmap,msestrings,msegui, + msedatamodules,mseglob,msestat,mseifiglob,msegraphics,msegraphutils,mseguiglob, + msemenus,msesimplewidgets,msewidgets,projecttreeform,msestringcontainer, + targetconsole,mseificomp,mseificompglob,mclasses; + +type + stringconsts = ( + ac_configuremseide, //0 Configure MSEide + ac_processid, //1 Process ID + ac_attachtoprocess, //2 Attach to process + ac_unknownmodclass, //3 Unknown moduleclass for " + ac_inheritedcomp, //4 Inherited component " + ac_cannotdel, //5 " can not be deleted. + ac_error, //6 ERROR + ac_makeaborted, //7 Make aborted. + ac_downloadaborted, //8 Download aborted. + ac_runerrorwith, //9 Runerror with " + ac_errortimeout, //10 Error: Timeout. + ac_making, //11 Making. + ac_makenotrunning, //12 Make not running. + ac_downloading, //13 Downloading. + ac_downloadnotrunning, //14 Download not running. + ac_running, //15 " running. + ac_script, //16 Script + ac_recursiveforminheritance, //17 Recursive form inheritance of " + ac_component, //18 Component " + ac_exists, //19 " exists. + ac_ancestorfor, //20 Ancestor for " + ac_notfound, //21 " not found. + ac_module, //22 Module " + ac_invalidname, //23 Invalid name " + ac_invalidmethodname, //24 Invalid methodname + ac_modulenotfound, //25 Module not found + ac_methodnotfound, //26 Method not found + ac_publishedmeth, //27 Published (managed) method + ac_doesnotexist, //28 does not exist. + ac_wishdelete, //29 Do you wish to delete the event? + ac_warning, //30 WARNING + ac_method, //31 Method + ac_differentparams, //32 has different parameters. + ac_amodule, //33 A module " + ac_isopen, //34 " is already open. + ac_unresolvedref, //35 Unresolved reference(s) to + ac_modules, //36 Module(s): + ac_cannotreadform, //37 Can not read formfile " + ac_invalidcompname,//38 Invalid component name. + ac_invalidexception, //39 Invalid exception + ac_tools, //40 T&ools + ac_forms, //41 Forms + ac_source, //42 Source + ac_allfiles, //43 All Files + ac_program, //44 Program + ac_unit, //45 Unit + ac_textfile, //46 Textfile + ac_mainform, //47 Mainform + ac_simpleform, //48 Simple Form + ac_dockingform, //49 Docking Form + ac_datamodule, //50 Datamodule + ac_subform, //51 Subform + ac_scrollboxform, //52 Scrollboxform + ac_tabform, //53 Tabform + ac_dockpanel, //54 Dockpanel + ac_report, //55 Report + ac_scriptform, //56 Scriptform + ac_inheritedform, //57 Inherited Form + ac_replacesettings, //58 Do you want to replace the settings by + ac_file, //59 File " + ac_wantoverwrite, //60 Do you want to overwrite? + ac_sr_unknown, //61 Unknown + ac_sr_error, //62 Error + ac_sr_startup, //63 Startup + ac_sr_exception, //64 Exception + ac_sr_gdbdied, //65 GDB died + ac_sr_breakpoint_hit, //66 Breakpoint hit + ac_sr_watchpointtrigger, //67 Watchpoint triggered + ac_sr_readwatchpointtrigger, //68 Read Watchpoint triggered + ac_sr_accesswatchpointtrigger, //69 Access Watchpoint triggered + ac_sr_end_stepping_range, //70 End stepping range + ac_sr_function_finished, //71 Function finished + ac_sr_exited_normally, //72 Exited normally + ac_sr_exited, //73 Exited + ac_sr_detached, //74 Detached + ac_sr_signal_received, //75 Signal received + ac_stoperror, //76 Stop error + ac_cannotreadproject, //77 Can not read project + ac_about, //78 About + ac_objectinspector, //79 Object Inspector + ac_storecomponent, //80 Store Component + ac_attachingprocess, //81 Attaching Process + ac_loading, //82 Loading + ac_sizingform //83 Sizing Form + ); + +type + tactionsmo = class(tmsedatamodule) + buttonicons: timagelist; + + opensource: taction; + saveall: taction; + saveas: taction; + save: taction; + close: taction; + closeall: taction; + + reset: taction; + interrupt: taction; + next: taction; + step: taction; + finish: taction; + continue: taction; +// run: taction; + + line: taction; + find: taction; + repeatfind: taction; + findinfile: taction; + + indent: taction; + nexti: taction; + stepi: taction; + bluedotsonact: taction; + replace: taction; + print: taction; + detachtarget: taction; + attachprocess: taction; + lowercase: taction; + uppercase: taction; + toggleformunit: taction; + unindent: taction; + undo: taction; + redo: taction; + cut: taction; + copy: taction; + paste: taction; + delete: taction; + + togglebkpt: taction; + togglebkptenable: taction; + bkptsonact: taction; + watchesonact: taction; + + abortmakeact: taction; + makeact: taction; + selecteditpage: taction; + + run: taction; + //common + shortcuts: tshortcutcontroller; + toggleinspector: taction; + buildact: taction; + make1act: taction; + make2act: taction; + make3act: taction; + make4act: taction; + download: taction; + helpact: taction; + attachtarget: taction; + setbm0: taction; + findbm0: taction; + findbm1: taction; + setbm1: taction; + findbm2: taction; + setbm2: taction; + findbm3: taction; + setbm3: taction; + findbm4: taction; + setbm4: taction; + findbm5: taction; + setbm5: taction; + findbm6: taction; + setbm6: taction; + findbm7: taction; + setbm7: taction; + findbm8: taction; + setbm8: taction; + findbm9: taction; + setbm9: taction; + setbmnone: taction; + instemplate: taction; + projectopenact: taction; + projectoptionsact: taction; + projecttreeact: taction; + projectsourceact: taction; + projectsaveact: taction; + projectcloseact: taction; + c: tstringcontainer; + copylatexact: taction; + findcompact: taction; + findcompallact: taction; + forcezorderact: taction; + tool0: taction; + tool1: taction; + tool2: taction; + tool3: taction; + tool4: taction; + tool5: taction; + tool6: taction; + tool7: taction; + tool8: taction; + tool9: taction; + comment: taction; + uncomment: taction; + copyword: taction; + selectall: taction; + tabtospace: taction; + findback: taction; + procedure findinfileonexecute(const sender: tobject); + + //file + procedure opensourceactonexecute(const sender: tobject); + procedure saveactonexecute(const sender: tobject); + procedure saveasactonexecute(const sender: TObject); + procedure saveallactonexecute(const sender: tobject); + procedure closeactonexecute(const sender: tobject); + procedure closeallactonexecute(const sender: tobject); + + //editor + procedure seleclallactonexecute(const sender: TObject); + procedure pasteactonexecute(const sender: tobject); + procedure deleteactonexecute(const sender: tobject); + procedure selecteditpageonexecute(const sender: TObject); + procedure undoactonexecute(const sender: tobject); + procedure redoactonexecute(const sender: tobject); + procedure copyactonexecute(const sender: tobject); + procedure cutactonexecute(const sender: tobject); + + procedure indentonexecute(const sender: TObject); + procedure unidentonexecute(const sender: TObject); + procedure lowercaseexecute(const sender: TObject); + procedure uppercaseexecute(const sender: TObject); + procedure enableonselect(const sender: tcustomaction); + + procedure lineactonexecute(const sender: TObject); + procedure findactonexecute(const sender: tobject); + procedure repeatfindactonexecute(const sender: tobject); + procedure replaceactonexecute(const sender: TObject); + + procedure togglebreakpointexe(const sender: TObject); + procedure togglebkptenableactonexecute(const sender: TObject); + procedure toggleformunitonexecute(const sender: TObject); + + //make + procedure makeactonexecute(const sender: tobject); + procedure abortmakeactonexecute(const sender: tobject); + + //debugger + procedure resetactonexecute(const sender: tobject); + procedure interruptactonexecute(const sender: tobject); + procedure continueactonexecute(const sender: tobject); + procedure nextactonexecute(const sender: tobject); + procedure finishactonexecute(const sender: tobject); + procedure stepactonexecute(const sender: tobject); + procedure stepiactonexecute(const sender: TObject); + procedure nextiactonexecute(const sender: TObject); + procedure bkptsononexecute(const sender: TObject); + procedure watchesononexecute(const sender: TObject); + procedure bluedotsononchange(const sender: TObject); + procedure printactonexecute(const sender: TObject); + procedure ondetachtarget(const sender: TObject); + procedure onattachprocess(const sender: TObject); + procedure updateshortcuts(const sender: tshortcutcontroller); + procedure downloadexe(const sender: TObject); + procedure helpex(const sender: TObject); + procedure onattachtarget(const sender: TObject); + procedure setbmexec(const sender: TObject); + procedure findbmexec(const sender: TObject); + procedure instemplateactonexecute(const sender: TObject); + procedure projectopenexe(const sender: TObject); + procedure projectoptionsexe(const sender: TObject); + procedure projecttreeexe(const sender: TObject); + procedure projectsourceexe(const sender: TObject); + procedure projectsaveexe(const sender: TObject); + procedure projectcloeseexe(const sender: TObject); + procedure creadstateexe(const sender: TObject); + procedure findupdateexe(const sender: tcustomaction); + procedure copylatexactonexecute(const sender: TObject); + procedure findcompexe(const sender: TObject); + procedure findcompallexe(const sender: TObject); + procedure forcezorderexe(const sender: TObject); + procedure commentonexecute(const sender: TObject); + procedure uncommentonexecute(const sender: TObject); + procedure enablecomment(const sender: tcustomaction); + procedure enableuncomment(const sender: tcustomaction); + procedure selectwordactiononexecute(const sender: TObject); + procedure tabtospaceexecute(const sender: TObject); + procedure findbackonexecute(const sender: TObject); + private + function filterfindcomp(const acomponent: tcomponent): boolean; + public + function gettoolshortcutaction(const index: int32; + out act: taction): boolean; + end; + +var + actionsmo: tactionsmo; + +procedure configureide; + +implementation +uses + main,make,actionsmodule_mfm,sourceform,msedesigner,msetypes,msefiledialog, + projectoptionsform,findinfileform,breakpointsform,watchform,selecteditpageform, + disassform,printform,msegdbutils,mseintegerenter,msesettings, + componentstore,cpuform,sysutils,msecomptree,mseformatstr; + +procedure configureide; +begin + disassfo.resetshortcuts(); + if editsettings(actionsmo.c[ord(ac_configuremseide)], + actionsmo.shortcuts) then begin + mainfo.mainstatfile.writestat(); + expandprojectmacros(); + end; +end; + +{ tactionsmo } + +function tactionsmo.gettoolshortcutaction(const index: int32; + out act: taction): boolean; +begin + case index of + 0: act:= tool0; + 1: act:= tool1; + 2: act:= tool2; + 3: act:= tool3; + 4: act:= tool4; + 5: act:= tool5; + 6: act:= tool6; + 7: act:= tool7; + 8: act:= tool8; + 9:act:= tool9; + else act:= nil; + end; + result:= act <> nil; +end; + +procedure tactionsmo.updateshortcuts(const sender: tshortcutcontroller); +begin + undo.shortcut:= sysshortcuts[sho_groupundo]; + undo.shortcut1:= sysshortcuts1[sho_groupundo]; + redo.shortcut:= sysshortcuts[sho_groupredo]; + redo.shortcut1:= sysshortcuts1[sho_groupredo]; + copy.shortcut:= sysshortcuts[sho_copy]; + copy.shortcut1:= sysshortcuts1[sho_copy]; + cut.shortcut:= sysshortcuts[sho_cut]; + cut.shortcut1:= sysshortcuts1[sho_cut]; + paste.shortcut:= sysshortcuts[sho_paste]; + paste.shortcut1:= sysshortcuts1[sho_paste]; + selectall.shortcut:= sysshortcuts[sho_selectall]; + selectall.shortcut1:= sysshortcuts1[sho_selectall]; + findcompact.shortcut:= find.shortcut; + findcompact.shortcut1:= find.shortcut1; + findcompallact.shortcut:= find.shortcut; + findcompallact.shortcut1:= find.shortcut1; +end; + +//common +procedure tactionsmo.findinfileonexecute(const sender: tobject); +begin + dofindinfile; +end; + +//file + +procedure tactionsmo.opensourceactonexecute(const sender: tobject); +begin + with mainfo do begin + opensource(fk_source,false); + end; +end; + +procedure tactionsmo.saveactonexecute(const sender: tobject); +begin + with mainfo do begin + if factivedesignmodule <> nil then begin + designer.saveformfile(factivedesignmodule,factivedesignmodule^.filename,true); + updatemodifiedforms; + end + else begin + sourcefo.saveactivepage; + end; + end; +end; + +procedure tactionsmo.saveasactonexecute(const sender: TObject); +var + namebefore,str1: filenamety; + po1: pmoduleinfoty; +begin + with mainfo do begin + if factivedesignmodule <> nil then begin + str1:= factivedesignmodule^.filename; + if openfile.controller.execute(str1,fdk_save) then begin + designer.saveformfile(factivedesignmodule,str1,true); + end; + end + else begin + str1:= sourcefo.activepage.filepath; + namebefore:= str1; + if openfile.controller.execute(str1,fdk_save) then begin + sourcefo.saveactivepage(str1); + po1:= designer.modules.findmodule(designer.sourcenametoformname(namebefore)); + if po1 <> nil then begin + str1:= designer.sourcenametoformname(str1); + designer.saveformfile(po1,str1,true); + po1^.filename:= str1; + updatemodifiedforms; + end; + end; + end; + end; +end; + +procedure tactionsmo.saveallactonexecute(const sender: tobject); +begin + with mainfo do begin + sourcefo.saveall(true); + designer.saveall(true,true); + componentstorefo.saveall(true); + saveprojectoptions; + updatemodifiedforms; + end; +end; + +procedure tactionsmo.closeactonexecute(const sender: tobject); +begin + with mainfo do begin + if factivedesignmodule <> nil then begin + if closemodule(factivedesignmodule,true) then begin + factivedesignmodule:= nil; + end; + end + else begin + sourcefo.closeactivepage; + end; + end; +end; + +procedure tactionsmo.closeallactonexecute(const sender: tobject); +begin + with mainfo do begin + closeall(false); + end; +end; + +//editor + +procedure tactionsmo.seleclallactonexecute(const sender: TObject); +begin + sourcefo.activepage.edit.selectall(); +end; + +procedure tactionsmo.pasteactonexecute(const sender: tobject); +begin + sourcefo.activepage.edit.paste; +end; + +procedure tactionsmo.deleteactonexecute(const sender: tobject); +begin + sourcefo.activepage.edit.deleteselection; +end; + +procedure tactionsmo.selectwordactiononexecute(const sender: TObject); +begin + sourcefo.activepage.copywordatcursor(); +end; + +procedure tactionsmo.selecteditpageonexecute(const sender: TObject); +begin + selecteditpageform.selecteditpage; +end; + +procedure tactionsmo.toggleformunitonexecute(const sender: TObject); +begin + mainfo.toggleformunit; +end; + +procedure tactionsmo.undoactonexecute(const sender: tobject); +begin + sourcefo.activepage.doundo; +end; + +procedure tactionsmo.redoactonexecute(const sender: tobject); +begin + sourcefo.activepage.doredo; +end; + +procedure tactionsmo.copyactonexecute(const sender: tobject); +begin + sourcefo.activepage.edit.copyselection; +end; + +procedure tactionsmo.copylatexactonexecute(const sender: TObject); +begin + sourcefo.activepage.copylatex; +end; + +procedure tactionsmo.cutactonexecute(const sender: tobject); +begin + sourcefo.activepage.edit.cutselection; +end; + +procedure tactionsmo.indentonexecute(const sender: TObject); +begin + sourcefo.activepage.edit.indent(projectoptions.e.blockindent, + projectoptions.e.tabindent); +end; + +procedure tactionsmo.unidentonexecute(const sender: TObject); +begin + sourcefo.activepage.edit.unindent(projectoptions.e.blockindent); +end; + +procedure tactionsmo.lowercaseexecute(const sender: TObject); +begin + sourcefo.activepage.edit.lowercase; +end; + +procedure tactionsmo.uppercaseexecute(const sender: TObject); +begin + sourcefo.activepage.edit.uppercase; +end; + +procedure tactionsmo.tabtospaceexecute(const sender: TObject); +begin + sourcefo.activepage.edit.tabtospace; +end; + +procedure tactionsmo.enableonselect(const sender: tcustomaction); +begin + sender.enabled:= (sourcefo.activepage <> nil) and + sourcefo.activepage.edit.hasselection; +end; + +procedure tactionsmo.enablecomment(const sender: tcustomaction); +begin + enableonselect(sender); + sender.enabled:= sender.enabled and sourcefo.activepage.cancomment(); +end; + +procedure tactionsmo.enableuncomment(const sender: tcustomaction); +begin + enableonselect(sender); + sender.enabled:= sender.enabled and sourcefo.activepage.canuncomment(); +end; + +procedure tactionsmo.commentonexecute(const sender: TObject); +begin + sourcefo.activepage.commentselection(); +end; + +procedure tactionsmo.uncommentonexecute(const sender: TObject); +begin + sourcefo.activepage.uncommentselection(); +end; + +procedure tactionsmo.lineactonexecute(const sender: TObject); +begin + sourcefo.activepage.doline; +end; + +procedure tactionsmo.findactonexecute(const sender: tobject); +begin + if targetconsolefo.activeentered then begin + targetconsolefo.dofind; + end + else begin + sourcefo.activepage.dofind; + end; +end; + +procedure tactionsmo.repeatfindactonexecute(const sender: tobject); +begin + if targetconsolefo.activeentered then begin + targetconsolefo.repeatfind; + end + else begin + sourcefo.activepage.repeatfind; + end; +end; + +procedure tactionsmo.findbackonexecute(const sender: TObject); +begin + if targetconsolefo.activeentered then begin + targetconsolefo.findback; + end + else begin + sourcefo.activepage.findback; + end; +end; + +procedure tactionsmo.replaceactonexecute(const sender: tobject); +begin + sourcefo.activepage.doreplace; +end; + +procedure tactionsmo.togglebreakpointexe(const sender: TObject); +begin + sourcefo.activepage.togglebreakpoint; +end; + +procedure tactionsmo.togglebkptenableactonexecute(const sender: TObject); +begin + sourcefo.activepage.togglebreakpointenabled; +end; + +procedure tactionsmo.instemplateactonexecute(const sender: TObject); +begin + sourcefo.activepage.inserttemplate; +end; + + +//make + +procedure tactionsmo.abortmakeactonexecute(const sender: tobject); +begin + make.abortmake; +end; + +procedure tactionsmo.makeactonexecute(const sender: tobject); +begin + with mainfo do begin + if sender is tmenuitem then begin + domake(tmenuitem(sender).tag); + end + else begin + domake(0); + end; + resetstartcommand; + end; +end; + +//debugger + +procedure tactionsmo.resetactonexecute(const sender: tobject); +begin + with mainfo do begin + gdb.abort; + killtarget; //if running + programfinished; + setstattext(''); + startgdb(false); + end; +end; + +procedure tactionsmo.interruptactonexecute(const sender: tobject); +begin + with mainfo do begin + gdb.interrupt; + end; +end; + +procedure tactionsmo.continueactonexecute(const sender: tobject); +begin + with mainfo do begin + if checkremake(sc_continue) then begin + cpufo.beforecontinue; + gdb.continue; + end; + end; +end; + +procedure tactionsmo.stepactonexecute(const sender: tobject); +begin + with mainfo do begin + if checkremake(sc_step) then begin + gdb.step; + end; + end; +end; + +procedure tactionsmo.stepiactonexecute(const sender: TObject); +begin + with mainfo do begin + if checkremake(sc_step) then begin + gdb.stepi; + end; + end; +end; + +procedure tactionsmo.nextactonexecute(const sender: tobject); +begin + with mainfo do begin + if checkremake(sc_step) then begin + gdb.next; + end; + end; +end; + +procedure tactionsmo.nextiactonexecute(const sender: TObject); +begin + with mainfo do begin + if checkremake(sc_step) then begin + gdb.nexti; + end; + end; +end; + +procedure tactionsmo.finishactonexecute(const sender: tobject); +begin + with mainfo do begin + if checkremake(sc_continue) then begin + gdb.finish; + end; + end; +end; + +procedure tactionsmo.bkptsononexecute(const sender: TObject); +begin + breakpointsfo.bkptson.value:= bkptsonact.checked; +end; + +procedure tactionsmo.watchesononexecute(const sender: TObject); +begin + watchfo.watcheson.value:= watchesonact.checked; +end; + +procedure tactionsmo.bluedotsononchange(const sender: TObject); +begin + mainfo.checkbluedots; +end; + +procedure tactionsmo.printactonexecute(const sender: TObject); +begin + printform.print; +end; + +procedure tactionsmo.ondetachtarget(const sender: TObject); +begin + if mainfo.checkgdberror(mainfo.gdb.detach) then begin + mainfo.startgdb(false); + end; +end; + +procedure tactionsmo.onattachprocess(const sender: TObject); +var + int1: integer; + info: stopinfoty; +begin + with mainfo do begin + int1:= 0; + if integerenter(int1,minint,maxint,self.c[ord(ac_processid)], + self.c[ord(ac_attachtoprocess)]) = mr_ok then begin + setstattext(self.c[ord(ac_attachingprocess)]+' '+ + inttostrmse(int1),mtk_running); + application.processmessages; + startgdb(false); + gdb.attach(int1,info); + loadexec(true,false); + refreshstopinfo(info); + breakpointsfo.updatebreakpoints(); + end; + end; +end; + +procedure tactionsmo.onattachtarget(const sender: TObject); +var + info: stopinfoty; +begin + with mainfo do begin + startgdb(false); + if checkgdberror(gdb.filesymbol(gettargetfile)) and + startgdbconnection(true) then begin + gdb.attachtarget(info); + loadexec(true,false); + refreshstopinfo(info); + breakpointsfo.updatebreakpoints(); + end; + end; +end; + +procedure tactionsmo.downloadexe(const sender: TObject); +begin + mainfo.loadexec(false,true); +end; + +procedure tactionsmo.helpex(const sender: TObject); +begin + application.help(application.activewidget); +end; + +procedure tactionsmo.setbmexec(const sender: TObject); +begin + sourcefo.setbmexec(sender); +end; + +procedure tactionsmo.findbmexec(const sender: TObject); +begin + sourcefo.findbmexec(sender); +end; + +procedure tactionsmo.projectopenexe(const sender: TObject); +var + fna1: filenamety; +begin + if projectfiledialog(fna1,false) = mr_ok then begin + mainfo.openproject(fna1); + end; +end; + +procedure tactionsmo.projectoptionsexe(const sender: TObject); +begin + editprojectoptions; +end; + +procedure tactionsmo.projecttreeexe(const sender: TObject); +begin + projecttreefo.activate; +end; + +procedure tactionsmo.projectsourceexe(const sender: TObject); +begin + sourcefo.openfile(projectoptions.k.texp.mainfile,true); +end; + +procedure tactionsmo.projectsaveexe(const sender: TObject); +begin + if projectoptions.projectfilename = '' then begin + mainfo.saveprojectasonexecute(sender); + end + else begin + mainfo.saveproject(projectoptions.projectfilename); + end; +end; + +procedure tactionsmo.projectcloeseexe(const sender: TObject); +begin + mainfo.closeprojectactonexecute (sender); +end; + +procedure tactionsmo.creadstateexe(const sender: TObject); +begin + msegdbutils.localizetext; +end; + +procedure tactionsmo.findupdateexe(const sender: tcustomaction); +begin + if targetconsolefo.activeentered then begin + find.enabled:= true; + repeatfind.enabled:= projectoptions.targetconsolefindinfo.text <> '' + end + else begin + find.enabled:= (sourcefo.activepage <> nil) and + sourcefo.activepage.activeentered; + repeatfind.enabled:= find.enabled and + (projectoptions.findreplaceinfo.find.text <> ''); + end; + findback.enabled:= repeatfind.enabled; + findcompallact.enabled:= not find.enabled; +end; + +procedure tactionsmo.findcompexe(const sender: TObject); +begin + if mainfo.factivedesignmodule <> nil then begin + mainfo.factivedesignmodule^.designformintf.findcompdialog(); + end; +end; + +function tactionsmo.filterfindcomp( + const acomponent: tcomponent): boolean; +begin + result:= not (cssubcomponent in acomponent.componentstyle) and + (not (acomponent is twidget) or + (ws_iswidget in twidget(acomponent).widgetstate)); +end; + +procedure tactionsmo.findcompallexe(const sender: TObject); +var + name1: msestring; + comp1: tcomponent; + po1: pmoduleinfoty; +begin + name1:= ''; + with designer do begin + if selections.count > 0 then begin + name1:= msestring(ownernamepath(selections[0])); + end; + if compnamedialog(designer.getcomponentnametree(nil,true,true,nil, + @filterfindcomp,nil),name1,true) = mr_ok then begin + replacechar1(name1,':','.'); + comp1:= designer.getcomponent(ansistring(name1),po1); + designer.showformdesigner(po1); + designer.selectcomponent(comp1); + end; + end; +end; + +procedure tactionsmo.forcezorderexe(const sender: TObject); +begin + if projectoptions.s <> nil then begin + projectoptions.s.forcezorder:= taction(sender).checked; + projectoptionsmodified(); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/actionsmodule_mfm.pas b/mseide-msegui/apps/ide/actionsmodule_mfm.pas new file mode 100644 index 0000000..06dd7ef --- /dev/null +++ b/mseide-msegui/apps/ide/actionsmodule_mfm.pas @@ -0,0 +1,2295 @@ +unit actionsmodule_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,actionsmodule; + +const + objdata: record size: integer; data: array[0..45557] of byte end = + (size: 45558; data: ( + 84,80,70,48,10,116,97,99,116,105,111,110,115,109,111,9,97,99,116,105, + 111,110,115,109,111,9,98,111,117,110,100,115,95,99,120,3,31,2,9,98, + 111,117,110,100,115,95,99,121,3,179,1,4,108,101,102,116,2,7,3,116, + 111,112,3,198,0,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,14,116,109,115,101,100,97,116,97,109,111,100,117,108,101,0,7,116, + 97,99,116,105,111,110,7,109,97,107,101,97,99,116,3,84,97,103,2,1, + 7,99,97,112,116,105,111,110,6,5,38,77,97,107,101,9,111,110,101,120, + 101,99,117,116,101,7,16,109,97,107,101,97,99,116,111,110,101,120,101,99, + 117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,38,1,0,0,7, + 116,97,99,116,105,111,110,3,114,117,110,7,99,97,112,116,105,111,110,6, + 4,38,82,117,110,7,105,109,97,103,101,110,114,2,0,4,104,105,110,116, + 6,3,82,117,110,4,108,101,102,116,2,80,3,116,111,112,3,191,0,0, + 0,7,116,97,99,116,105,111,110,4,115,116,101,112,9,105,109,97,103,101, + 108,105,115,116,7,11,98,117,116,116,111,110,105,99,111,110,115,7,99,97, + 112,116,105,111,110,6,5,38,83,116,101,112,7,105,109,97,103,101,110,114, + 2,1,15,105,109,97,103,101,110,114,100,105,115,97,98,108,101,100,2,18, + 4,104,105,110,116,6,4,83,116,101,112,9,111,110,101,120,101,99,117,116, + 101,7,16,115,116,101,112,97,99,116,111,110,101,120,101,99,117,116,101,4, + 108,101,102,116,2,8,3,116,111,112,3,222,0,2,115,99,1,2,1,3, + 54,1,0,0,0,7,116,97,99,116,105,111,110,4,110,101,120,116,9,105, + 109,97,103,101,108,105,115,116,7,11,98,117,116,116,111,110,105,99,111,110, + 115,7,99,97,112,116,105,111,110,6,5,38,78,101,120,116,7,105,109,97, + 103,101,110,114,2,2,15,105,109,97,103,101,110,114,100,105,115,97,98,108, + 101,100,2,22,4,104,105,110,116,6,4,78,101,120,116,9,111,110,101,120, + 101,99,117,116,101,7,16,110,101,120,116,97,99,116,111,110,101,120,101,99, + 117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,206,0,2,115,99, + 1,2,1,3,55,1,0,0,0,7,116,97,99,116,105,111,110,8,99,111, + 110,116,105,110,117,101,9,105,109,97,103,101,108,105,115,116,7,11,98,117, + 116,116,111,110,105,99,111,110,115,7,99,97,112,116,105,111,110,6,9,38, + 67,111,110,116,105,110,117,101,7,105,109,97,103,101,110,114,2,4,15,105, + 109,97,103,101,110,114,100,105,115,97,98,108,101,100,2,17,4,104,105,110, + 116,6,8,67,111,110,116,105,110,117,101,9,111,110,101,120,101,99,117,116, + 101,7,20,99,111,110,116,105,110,117,101,97,99,116,111,110,101,120,101,99, + 117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,254,0,2,115,99, + 1,2,1,3,56,1,0,0,0,7,116,97,99,116,105,111,110,9,105,110, + 116,101,114,114,117,112,116,9,105,109,97,103,101,108,105,115,116,7,11,98, + 117,116,116,111,110,105,99,111,110,115,7,99,97,112,116,105,111,110,6,10, + 38,73,110,116,101,114,114,117,112,116,7,105,109,97,103,101,110,114,2,5, + 15,105,109,97,103,101,110,114,100,105,115,97,98,108,101,100,2,16,4,104, + 105,110,116,6,9,73,110,116,101,114,114,117,112,116,9,111,110,101,120,101, + 99,117,116,101,7,21,105,110,116,101,114,114,117,112,116,97,99,116,111,110, + 101,120,101,99,117,116,101,4,108,101,102,116,2,9,3,116,111,112,3,13, + 1,0,0,7,116,97,99,116,105,111,110,5,114,101,115,101,116,9,105,109, + 97,103,101,108,105,115,116,7,11,98,117,116,116,111,110,105,99,111,110,115, + 7,99,97,112,116,105,111,110,6,6,38,82,101,115,101,116,7,105,109,97, + 103,101,110,114,2,6,15,105,109,97,103,101,110,114,100,105,115,97,98,108, + 101,100,2,15,4,104,105,110,116,6,5,82,101,115,101,116,9,111,110,101, + 120,101,99,117,116,101,7,17,114,101,115,101,116,97,99,116,111,110,101,120, + 101,99,117,116,101,4,108,101,102,116,2,7,3,116,111,112,3,191,0,0, + 0,7,116,97,99,116,105,111,110,10,111,112,101,110,115,111,117,114,99,101, + 7,99,97,112,116,105,111,110,6,5,38,79,112,101,110,9,111,110,101,120, + 101,99,117,116,101,7,22,111,112,101,110,115,111,117,114,99,101,97,99,116, + 111,110,101,120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112, + 2,4,2,115,99,1,2,1,3,79,64,0,0,0,7,116,97,99,116,105, + 111,110,6,102,105,110,105,115,104,9,105,109,97,103,101,108,105,115,116,7, + 11,98,117,116,116,111,110,105,99,111,110,115,7,99,97,112,116,105,111,110, + 6,7,38,70,105,110,105,115,104,7,105,109,97,103,101,110,114,2,3,15, + 105,109,97,103,101,110,114,100,105,115,97,98,108,101,100,2,20,4,104,105, + 110,116,6,6,70,105,110,105,115,104,9,111,110,101,120,101,99,117,116,101, + 7,18,102,105,110,105,115,104,97,99,116,111,110,101,120,101,99,117,116,101, + 4,108,101,102,116,2,8,3,116,111,112,3,238,0,2,115,99,1,2,1, + 3,54,33,0,0,0,7,116,97,99,116,105,111,110,4,115,97,118,101,7, + 99,97,112,116,105,111,110,6,5,38,83,97,118,101,9,111,110,101,120,101, + 99,117,116,101,7,16,115,97,118,101,97,99,116,111,110,101,120,101,99,117, + 116,101,4,108,101,102,116,2,8,3,116,111,112,2,20,2,115,99,1,2, + 1,3,83,64,0,0,0,7,116,97,99,116,105,111,110,5,99,108,111,115, + 101,7,99,97,112,116,105,111,110,6,6,38,67,108,111,115,101,9,111,110, + 101,120,101,99,117,116,101,7,17,99,108,111,115,101,97,99,116,111,110,101, + 120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,2,68,2, + 115,99,1,2,1,3,51,65,0,0,0,7,116,97,99,116,105,111,110,12, + 97,98,111,114,116,109,97,107,101,97,99,116,7,99,97,112,116,105,111,110, + 6,11,38,65,98,111,114,116,32,77,97,107,101,9,111,110,101,120,101,99, + 117,116,101,7,21,97,98,111,114,116,109,97,107,101,97,99,116,111,110,101, + 120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,146,1, + 0,0,7,116,97,99,116,105,111,110,4,117,110,100,111,7,99,97,112,116, + 105,111,110,6,5,38,85,110,100,111,9,111,110,101,120,101,99,117,116,101, + 7,16,117,110,100,111,97,99,116,111,110,101,120,101,99,117,116,101,4,108, + 101,102,116,3,24,1,3,116,111,112,2,4,2,115,99,1,2,1,3,90, + 64,0,0,0,7,116,97,99,116,105,111,110,4,114,101,100,111,7,99,97, + 112,116,105,111,110,6,5,38,82,101,100,111,9,111,110,101,120,101,99,117, + 116,101,7,16,114,101,100,111,97,99,116,111,110,101,120,101,99,117,116,101, + 4,108,101,102,116,3,24,1,3,116,111,112,2,20,2,115,99,1,2,1, + 3,90,96,0,0,0,7,116,97,99,116,105,111,110,3,99,117,116,7,99, + 97,112,116,105,111,110,6,4,67,117,38,116,9,111,110,101,120,101,99,117, + 116,101,7,15,99,117,116,97,99,116,111,110,101,120,101,99,117,116,101,4, + 108,101,102,116,3,24,1,3,116,111,112,2,36,2,115,99,1,2,1,3, + 88,64,0,3,115,99,49,1,2,1,3,7,33,0,0,0,7,116,97,99, + 116,105,111,110,4,99,111,112,121,7,99,97,112,116,105,111,110,6,5,38, + 67,111,112,121,9,111,110,101,120,101,99,117,116,101,7,16,99,111,112,121, + 97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116,3,24,1, + 3,116,111,112,2,52,2,115,99,1,2,1,3,67,64,0,0,0,7,116, + 97,99,116,105,111,110,5,112,97,115,116,101,7,99,97,112,116,105,111,110, + 6,6,38,80,97,115,116,101,9,111,110,101,120,101,99,117,116,101,7,17, + 112,97,115,116,101,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101, + 102,116,3,24,1,3,116,111,112,2,68,2,115,99,1,2,1,3,86,64, + 0,3,115,99,49,1,2,1,3,6,33,0,0,0,7,116,97,99,116,105, + 111,110,6,100,101,108,101,116,101,7,99,97,112,116,105,111,110,6,7,38, + 68,101,108,101,116,101,9,111,110,101,120,101,99,117,116,101,7,18,100,101, + 108,101,116,101,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102, + 116,3,24,1,3,116,111,112,2,84,0,0,7,116,97,99,116,105,111,110, + 7,115,97,118,101,97,108,108,7,99,97,112,116,105,111,110,6,9,83,97, + 38,118,101,32,97,108,108,9,111,110,101,120,101,99,117,116,101,7,19,115, + 97,118,101,97,108,108,97,99,116,111,110,101,120,101,99,117,116,101,4,108, + 101,102,116,2,8,3,116,111,112,2,36,0,0,7,116,97,99,116,105,111, + 110,4,102,105,110,100,7,99,97,112,116,105,111,110,6,5,38,70,105,110, + 100,9,111,110,101,120,101,99,117,116,101,7,16,102,105,110,100,97,99,116, + 111,110,101,120,101,99,117,116,101,8,111,110,117,112,100,97,116,101,7,13, + 102,105,110,100,117,112,100,97,116,101,101,120,101,4,108,101,102,116,3,152, + 0,3,116,111,112,2,28,2,115,99,1,2,1,3,70,64,0,0,0,7, + 116,97,99,116,105,111,110,10,114,101,112,101,97,116,102,105,110,100,7,99, + 97,112,116,105,111,110,6,13,38,83,101,97,114,99,104,32,97,103,97,105, + 110,9,111,110,101,120,101,99,117,116,101,7,22,114,101,112,101,97,116,102, + 105,110,100,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116, + 3,152,0,3,116,111,112,2,44,2,115,99,1,2,1,3,50,1,0,0, + 0,7,116,97,99,116,105,111,110,10,102,105,110,100,105,110,102,105,108,101, + 7,99,97,112,116,105,111,110,6,14,70,105,110,100,32,105,110,32,70,38, + 105,108,101,115,9,111,110,101,120,101,99,117,116,101,7,19,102,105,110,100, + 105,110,102,105,108,101,111,110,101,120,101,99,117,116,101,4,108,101,102,116, + 3,152,0,3,116,111,112,2,76,2,115,99,1,2,1,3,70,96,0,0, + 0,7,116,97,99,116,105,111,110,8,99,108,111,115,101,97,108,108,7,99, + 97,112,116,105,111,110,6,10,67,38,108,111,115,101,32,97,108,108,9,111, + 110,101,120,101,99,117,116,101,7,20,99,108,111,115,101,97,108,108,97,99, + 116,111,110,101,120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111, + 112,2,84,0,0,7,116,97,99,116,105,111,110,6,115,97,118,101,97,115, + 7,99,97,112,116,105,111,110,6,8,83,97,118,101,32,38,97,115,9,111, + 110,101,120,101,99,117,116,101,7,18,115,97,118,101,97,115,97,99,116,111, + 110,101,120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,2, + 52,0,0,7,116,97,99,116,105,111,110,10,98,107,112,116,115,111,110,97, + 99,116,9,105,109,97,103,101,108,105,115,116,7,11,98,117,116,116,111,110, + 105,99,111,110,115,7,99,97,112,116,105,111,110,6,15,38,66,114,101,97, + 107,112,111,105,110,116,115,32,111,110,5,115,116,97,116,101,11,10,97,115, + 95,99,104,101,99,107,101,100,0,7,105,109,97,103,101,110,114,2,7,4, + 104,105,110,116,6,18,66,114,101,97,107,112,111,105,110,116,115,32,111,110, + 47,111,102,102,9,111,110,101,120,101,99,117,116,101,7,16,98,107,112,116, + 115,111,110,111,110,101,120,101,99,117,116,101,4,108,101,102,116,3,152,0, + 3,116,111,112,3,236,0,2,115,99,1,2,1,3,66,64,0,0,0,7, + 116,97,99,116,105,111,110,12,119,97,116,99,104,101,115,111,110,97,99,116, + 9,105,109,97,103,101,108,105,115,116,7,11,98,117,116,116,111,110,105,99, + 111,110,115,7,99,97,112,116,105,111,110,6,11,38,87,97,116,99,104,101, + 115,32,111,110,5,115,116,97,116,101,11,10,97,115,95,99,104,101,99,107, + 101,100,0,7,105,109,97,103,101,110,114,2,9,4,104,105,110,116,6,14, + 87,97,116,99,104,101,115,32,111,110,47,111,102,102,8,115,116,97,116,102, + 105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115, + 116,97,116,102,105,108,101,9,111,110,101,120,101,99,117,116,101,7,18,119, + 97,116,99,104,101,115,111,110,111,110,101,120,101,99,117,116,101,4,108,101, + 102,116,3,152,0,3,116,111,112,3,252,0,2,115,99,1,2,1,3,87, + 64,0,0,0,7,116,97,99,116,105,111,110,4,108,105,110,101,7,99,97, + 112,116,105,111,110,6,5,38,76,105,110,101,9,111,110,101,120,101,99,117, + 116,101,7,16,108,105,110,101,97,99,116,111,110,101,120,101,99,117,116,101, + 4,108,101,102,116,3,152,0,3,116,111,112,2,12,2,115,99,1,2,1, + 3,76,64,0,0,0,7,116,97,99,116,105,111,110,10,116,111,103,103,108, + 101,98,107,112,116,7,99,97,112,116,105,111,110,6,18,38,84,111,103,103, + 108,101,32,66,114,101,97,107,112,111,105,110,116,9,111,110,101,120,101,99, + 117,116,101,7,19,116,111,103,103,108,101,98,114,101,97,107,112,111,105,110, + 116,101,120,101,4,108,101,102,116,3,152,0,3,116,111,112,3,204,0,2, + 115,99,1,2,1,3,52,1,0,0,0,7,116,97,99,116,105,111,110,16, + 116,111,103,103,108,101,98,107,112,116,101,110,97,98,108,101,7,99,97,112, + 116,105,111,110,6,21,84,111,103,103,108,101,32,66,107,112,116,46,32,38, + 101,110,97,98,108,101,100,9,111,110,101,120,101,99,117,116,101,7,28,116, + 111,103,103,108,101,98,107,112,116,101,110,97,98,108,101,97,99,116,111,110, + 101,120,101,99,117,116,101,4,108,101,102,116,3,152,0,3,116,111,112,3, + 220,0,2,115,99,1,2,1,3,52,33,0,0,0,10,116,105,109,97,103, + 101,108,105,115,116,11,98,117,116,116,111,110,105,99,111,110,115,5,119,105, + 100,116,104,2,24,6,104,101,105,103,104,116,2,24,7,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,5,99,111,117,110,116,2,24,4,108,101, + 102,116,3,96,1,3,116,111,112,2,32,5,105,109,97,103,101,10,228,116, + 0,0,0,0,0,0,6,0,0,0,120,0,0,0,120,0,0,0,88,58, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,192,192,24,208,208, + 208,6,0,165,9,3,208,208,208,26,0,0,0,1,208,208,208,2,0,0, + 0,1,208,208,208,11,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,42,192,192,192,24,208,208,208,6,0,165,9,1,16,168,16,1,0,165, + 9,2,208,208,208,25,0,0,0,5,208,208,208,10,0,0,0,5,208,208, + 208,41,192,192,192,24,208,208,208,6,0,165,9,1,38,187,32,1,30,180, + 26,1,0,165,9,2,208,208,208,26,0,0,0,2,208,208,208,13,0,0, + 0,9,208,208,208,5,0,163,8,3,208,208,208,27,192,192,192,13,128,0, + 0,2,192,192,192,9,208,208,208,6,0,165,9,1,50,206,46,1,60,211, + 51,1,34,189,32,1,0,165,9,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,37,0,0,0,7,208,208,208,5,10,183, + 7,1,24,208,2,1,10,183,7,1,0,21,0,1,0,0,0,1,208,208, + 208,7,0,169,9,1,4,180,10,1,0,0,0,1,208,208,208,15,192,192, + 192,13,128,0,0,2,192,192,192,9,208,208,208,6,0,165,9,1,59,223, + 56,1,76,237,68,1,67,226,61,1,39,198,38,1,0,165,9,2,0,0, + 0,5,208,208,208,36,0,0,0,11,0,191,0,1,15,189,5,1,32,223, + 0,1,13,179,4,1,0,4,0,1,0,0,0,1,208,208,208,7,0,167, + 8,1,13,197,10,1,8,154,11,1,0,43,0,1,208,208,208,14,192,192, + 192,5,128,128,128,6,128,0,0,3,128,128,128,1,192,192,192,9,208,208, + 208,3,2,168,9,1,7,178,7,1,11,183,6,1,7,177,7,1,60,225, + 57,1,82,250,77,1,84,253,79,1,76,242,71,1,44,208,44,1,0,165, + 9,2,208,208,208,1,0,0,0,9,208,208,208,3,0,170,0,1,8,178, + 8,1,10,183,6,1,12,187,6,1,14,190,6,1,14,189,6,4,10,183, + 7,1,0,146,7,1,208,208,208,16,0,0,0,11,0,170,0,1,16,192, + 4,1,32,223,0,1,14,178,4,1,0,8,0,1,0,0,0,1,208,208, + 208,7,0,167,8,1,21,213,11,1,36,221,25,1,12,161,16,1,0,89, + 0,1,208,208,208,13,192,192,192,8,128,128,128,1,128,0,0,5,192,192, + 192,10,208,208,208,2,6,175,7,1,14,189,5,1,31,221,0,1,32,223, + 0,1,18,197,4,1,52,211,47,1,73,232,64,1,75,237,67,1,78,242, + 71,1,70,237,66,1,31,197,35,1,0,165,9,1,208,208,208,3,0,0, + 0,7,208,208,208,2,0,167,10,1,9,181,7,1,27,215,1,1,32,223, + 0,7,24,208,2,1,0,62,3,1,0,0,0,1,208,208,208,11,0,0, + 0,4,208,208,208,11,0,163,12,1,18,195,4,1,32,223,0,1,12,171, + 5,1,0,2,0,1,0,0,0,1,208,208,208,7,0,167,8,1,21,213, + 11,1,44,231,29,1,55,229,43,1,19,168,21,1,0,104,6,1,0,0, + 0,1,208,208,208,11,192,192,192,4,128,128,128,4,128,0,0,6,192,192, + 192,10,208,208,208,1,2,168,9,1,16,193,5,1,32,223,0,2,28,215, + 1,1,9,175,6,1,45,197,38,1,63,213,51,1,66,218,55,1,64,219, + 55,1,40,200,39,1,0,97,5,1,0,18,1,1,208,208,208,3,0,0, + 0,7,208,208,208,1,0,170,0,1,9,181,6,1,31,222,0,1,32,223, + 0,1,29,216,1,1,19,196,3,1,15,182,4,1,15,181,4,1,14,180, + 4,1,14,178,4,1,14,177,4,1,9,174,6,1,0,62,3,1,0,0, + 0,1,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,1,208,208, + 208,4,0,0,0,4,208,208,208,10,0,168,7,1,7,177,7,1,28,215, + 1,1,32,223,0,1,9,156,6,1,0,0,0,2,208,208,208,7,0,167, + 8,1,21,213,11,1,44,231,29,1,60,234,46,1,74,235,61,1,31,179, + 33,1,10,124,13,1,0,0,0,1,208,208,208,10,192,192,192,8,128,0, + 0,1,128,128,128,1,128,0,0,5,192,192,192,9,208,208,208,1,8,179, + 7,1,31,221,0,1,32,223,0,1,11,169,5,1,3,108,5,1,0,75, + 4,1,38,183,28,1,53,194,39,1,52,197,40,1,33,187,30,1,0,97, + 5,1,0,18,1,1,208,208,208,4,0,0,0,7,208,208,208,1,6,175, + 8,1,26,214,1,1,32,223,0,1,18,186,3,1,4,123,5,1,0,44, + 2,1,0,16,0,1,0,15,0,1,0,11,0,1,0,8,0,1,0,6, + 0,1,0,2,0,1,0,0,0,2,208,208,208,1,0,0,0,7,208,208, + 208,4,4,178,8,1,8,181,7,1,11,184,6,1,14,188,6,1,14,189, + 6,9,20,201,3,1,30,219,1,1,32,223,0,1,29,218,1,1,5,132, + 5,1,0,0,0,2,208,208,208,7,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,76,236,63,1,92,239,80,1,49,193,49,1,16,138, + 23,1,0,0,0,1,208,208,208,9,192,192,192,5,128,128,128,5,128,0, + 0,6,192,192,192,8,208,208,208,1,13,187,5,1,32,223,0,1,28,215, + 1,1,3,108,5,1,0,0,0,1,0,106,6,1,31,169,19,1,41,175, + 25,1,26,174,20,1,0,97,5,1,0,18,1,1,208,208,208,1,0,0, + 0,4,208,208,208,8,11,185,5,1,32,223,0,1,31,222,0,1,6,138, + 6,1,0,0,0,1,0,39,4,1,0,145,7,1,0,151,15,1,0,0, + 0,5,208,208,208,4,0,0,0,1,208,208,208,3,0,0,0,1,208,208, + 208,3,8,175,8,1,18,195,4,1,32,223,0,14,28,216,1,1,8,158, + 6,1,0,13,0,1,0,0,0,2,208,208,208,7,0,167,8,1,21,213, + 11,1,44,231,29,1,60,234,46,1,76,236,63,1,92,239,80,1,107,242, + 96,1,75,207,72,1,23,150,28,1,0,0,0,1,208,208,208,8,192,192, + 192,9,128,0,0,4,128,128,128,1,192,192,192,1,128,0,0,2,192,192, + 192,7,0,165,9,1,15,191,5,1,32,223,0,1,17,187,4,1,0,34, + 2,1,0,0,0,1,0,154,8,1,21,156,10,1,19,161,11,1,0,97, + 5,1,0,18,1,1,208,208,208,2,0,0,0,4,208,208,208,8,13,188, + 5,1,32,223,0,1,23,204,2,1,1,75,3,1,0,0,0,1,0,163, + 8,1,16,169,17,1,0,164,9,1,0,159,16,1,208,208,208,15,6,170, + 6,1,18,197,4,1,32,223,0,2,22,204,2,1,14,178,4,1,13,177, + 4,1,13,178,4,1,14,178,4,2,14,179,4,1,15,181,4,2,15,182, + 4,1,16,183,4,1,12,173,4,1,8,154,6,1,4,123,5,1,0,11, + 0,1,0,0,0,2,208,208,208,8,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,76,236,63,1,92,239,80,1,107,242,96,1,123,245, + 113,1,104,224,100,1,29,157,34,1,0,85,0,1,208,208,208,7,192,192, + 192,5,128,0,0,2,192,192,192,2,128,0,0,5,128,128,128,1,192,192, + 192,1,128,128,128,1,192,192,192,7,208,208,208,1,13,187,5,1,32,223, + 0,1,28,215,1,1,3,110,5,1,0,0,0,1,0,163,9,1,9,155, + 6,1,0,97,5,1,0,18,1,1,0,0,0,1,208,208,208,14,12,186, + 6,1,32,223,0,1,23,204,2,1,1,75,3,1,0,0,0,1,0,163, + 8,1,38,187,33,1,30,179,26,1,0,157,9,1,0,159,16,1,208,208, + 208,14,9,179,7,1,31,223,0,1,32,223,0,1,9,163,5,1,2,69, + 3,1,0,27,1,1,0,67,4,1,0,23,1,1,0,6,0,1,0,8, + 0,1,0,10,0,1,0,12,0,1,0,13,0,1,0,15,0,1,0,19, + 2,1,0,2,0,1,0,0,0,5,208,208,208,8,0,167,8,1,21,213, + 11,1,44,231,29,1,60,234,46,1,76,236,63,1,92,239,80,1,107,242, + 96,1,123,245,113,1,139,247,130,1,134,238,128,1,38,167,41,1,0,98, + 10,1,208,208,208,6,192,192,192,4,128,128,128,1,128,0,0,3,128,128, + 128,1,128,0,0,2,128,128,128,1,128,0,0,3,192,192,192,9,208,208, + 208,1,8,177,7,1,31,222,0,1,32,223,0,1,10,166,5,1,1,93, + 5,1,0,122,7,1,0,163,9,1,0,18,1,1,208,208,208,16,10,182, + 7,1,32,223,0,1,31,222,0,1,6,138,6,1,0,0,0,1,0,163, + 8,1,50,206,45,1,60,211,52,1,34,189,32,1,0,157,9,1,0,159, + 16,1,208,208,208,13,10,185,6,1,32,223,0,1,26,212,2,1,1,91, + 4,1,0,0,0,1,0,108,6,1,17,169,16,1,0,156,8,1,0,97, + 5,1,0,0,0,11,208,208,208,9,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,76,236,63,1,92,239,80,1,107,242,96,1,123,245, + 113,1,139,247,130,1,134,238,128,1,36,160,39,1,0,24,2,1,0,0, + 0,1,208,208,208,5,192,192,192,4,128,0,0,1,128,128,128,1,128,0, + 0,5,192,192,192,1,128,128,128,1,128,0,0,2,192,192,192,9,208,208, + 208,1,1,143,7,1,16,186,4,1,32,223,0,1,31,222,0,1,20,196, + 3,1,14,185,5,1,13,187,5,1,13,188,5,8,12,185,6,1,9,179, + 6,1,6,171,7,1,0,41,2,1,0,0,0,1,208,208,208,4,5,174, + 8,1,23,202,3,1,32,223,0,1,18,186,3,1,4,145,6,1,0,164, + 8,1,59,223,56,1,76,237,68,1,67,226,61,1,39,198,38,1,0,157, + 9,1,0,159,16,1,208,208,208,12,12,186,6,1,32,223,0,1,19,192, + 3,1,0,41,2,1,0,0,0,1,0,154,8,1,38,188,33,1,30,180, + 26,1,0,165,9,2,208,208,208,19,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,76,236,63,1,92,239,80,1,107,242,96,1,123,245, + 113,1,104,224,100,1,26,144,31,1,0,7,0,1,0,0,0,1,208,208, + 208,6,192,192,192,7,128,128,128,1,128,0,0,2,192,192,192,2,128,128, + 128,1,128,0,0,2,192,192,192,9,208,208,208,1,0,0,0,1,5,147, + 6,1,13,177,5,1,31,222,0,1,32,223,0,13,27,212,2,1,6,158, + 6,1,0,0,0,2,208,208,208,4,6,166,6,1,29,219,1,1,32,223, + 0,1,29,216,1,1,14,189,4,1,60,225,57,1,82,250,77,1,84,253, + 79,1,76,242,71,1,44,207,44,1,0,157,9,1,0,159,16,1,208,208, + 208,2,0,0,0,8,208,208,208,1,10,183,6,1,32,223,0,1,29,218, + 1,1,5,125,5,1,0,0,0,1,0,163,9,1,51,207,46,1,61,211, + 51,1,35,189,32,1,0,165,9,2,0,0,0,6,208,208,208,12,0,167, + 8,1,21,213,11,1,44,231,29,1,60,234,46,1,76,236,63,1,92,239, + 80,1,107,242,96,1,75,207,72,1,19,123,23,1,0,0,0,2,208,208, + 208,7,192,192,192,12,128,0,0,2,128,128,128,1,192,192,192,9,208,208, + 208,2,0,0,0,1,1,69,4,1,6,146,6,1,9,161,5,1,12,174, + 5,1,13,176,5,9,19,193,3,1,30,219,1,1,32,223,0,1,23,202, + 2,1,3,108,5,1,0,0,0,2,208,208,208,3,0,147,0,1,6,153, + 6,1,25,208,2,1,32,223,0,1,24,208,2,1,52,210,47,1,73,232, + 64,1,75,237,67,1,78,242,71,1,70,237,66,1,31,198,35,1,0,148, + 7,1,208,208,208,2,0,0,0,8,208,208,208,1,7,175,7,1,31,220, + 0,1,32,223,0,1,14,179,4,1,4,133,6,1,0,155,8,1,59,224, + 57,1,76,237,69,1,68,227,61,1,39,199,38,1,0,165,9,1,0,64, + 3,1,0,0,0,5,208,208,208,12,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,76,236,63,1,92,239,80,1,48,192,48,1,11,95, + 16,1,0,0,0,2,208,208,208,8,192,192,192,11,128,128,128,1,128,0, + 0,1,128,128,128,1,192,192,192,10,208,208,208,3,0,0,0,13,0,44, + 2,1,6,146,6,1,28,215,1,1,32,223,0,1,8,150,5,1,0,0, + 0,2,208,208,208,4,0,14,0,1,4,122,4,1,8,152,6,1,8,170, + 6,1,45,197,38,1,63,213,51,1,66,218,55,1,64,219,55,1,40,200, + 39,1,0,96,5,1,0,18,2,1,208,208,208,11,0,134,7,1,14,184, + 4,1,32,223,0,2,24,209,2,1,8,177,6,1,60,226,58,1,83,251, + 77,1,84,254,79,1,76,243,71,1,44,208,44,1,0,165,9,2,208,208, + 208,2,0,0,0,7,208,208,208,7,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,74,235,61,1,31,178,32,1,5,63,6,1,0,0, + 0,2,208,208,208,9,192,192,192,11,128,0,0,2,128,128,128,2,192,192, + 192,9,208,208,208,3,0,0,0,14,0,74,4,1,16,190,4,1,32,223, + 0,1,11,167,5,1,0,0,0,2,208,208,208,5,0,0,0,2,0,79, + 4,1,38,183,28,1,53,194,39,1,52,197,40,1,33,186,30,1,0,96, + 5,1,0,18,2,1,208,208,208,12,0,0,0,1,5,147,7,1,14,177, + 4,1,31,223,0,1,32,223,0,1,18,197,4,1,53,211,48,1,73,232, + 65,1,76,237,68,1,78,242,71,1,71,237,67,1,31,197,35,1,0,165, + 9,1,208,208,208,2,0,0,0,7,208,208,208,7,0,167,8,1,21,213, + 11,1,44,231,29,1,55,229,43,1,19,164,21,1,0,33,2,1,0,0, + 0,2,208,208,208,10,192,192,192,11,128,0,0,4,192,192,192,9,208,208, + 208,5,0,0,0,9,208,208,208,3,0,133,7,1,15,190,5,1,32,223, + 0,1,14,178,5,1,0,8,0,1,0,0,0,1,208,208,208,7,0,161, + 8,1,31,168,18,1,41,175,25,1,26,174,20,1,0,96,5,1,0,18, + 2,1,208,208,208,14,0,0,0,1,0,77,3,1,7,146,5,1,11,163, + 4,1,7,172,6,1,46,197,38,1,63,213,52,1,66,219,55,1,65,220, + 56,1,40,201,39,1,0,97,5,1,0,18,1,1,208,208,208,2,0,0, + 0,8,208,208,208,6,0,167,8,1,21,213,11,1,36,221,25,1,11,152, + 15,1,0,15,0,1,0,0,0,2,208,208,208,11,192,192,192,24,208,208, + 208,7,0,0,0,7,208,208,208,3,0,165,9,1,14,189,5,1,32,223, + 0,1,13,178,5,1,0,5,0,1,0,0,0,1,208,208,208,7,0,163, + 8,1,20,157,10,1,19,160,11,1,0,96,5,1,0,18,2,1,208,208, + 208,16,0,0,0,3,0,76,4,1,38,184,29,1,54,195,39,1,52,198, + 41,1,33,187,30,1,0,97,5,1,0,18,1,1,0,0,0,4,208,208, + 208,1,0,0,0,2,208,208,208,10,0,167,8,1,13,197,10,1,7,137, + 10,1,0,3,0,1,0,0,0,1,208,208,208,13,192,192,192,24,208,208, + 208,7,0,0,0,11,10,182,6,1,24,208,2,1,9,174,6,1,0,1, + 0,1,0,0,0,1,208,208,208,7,0,163,8,1,10,153,5,1,1,102, + 5,1,0,18,2,1,208,208,208,18,0,0,0,2,0,148,8,1,31,169, + 19,1,41,175,25,1,26,174,21,1,0,97,5,1,0,18,1,1,0,0, + 0,5,208,208,208,13,0,169,9,1,4,179,10,1,0,0,0,2,208,208, + 208,14,192,192,192,24,208,208,208,5,0,0,0,9,208,208,208,1,0,0, + 0,3,0,145,8,1,0,70,4,1,0,66,4,1,0,0,0,2,208,208, + 208,7,0,159,16,1,0,161,8,1,0,18,2,1,208,208,208,2,0,0, + 0,4,208,208,208,15,0,165,9,1,22,156,10,1,19,161,12,1,0,97, + 5,1,0,18,1,1,208,208,208,21,0,0,0,1,208,208,208,15,192,192, + 192,24,208,208,208,3,0,0,0,4,208,208,208,11,0,0,0,5,208,208, + 208,12,0,0,0,4,208,208,208,15,0,165,9,1,9,155,6,1,0,97, + 5,1,0,18,1,1,208,208,208,38,192,192,192,24,208,208,208,6,0,0, + 0,1,208,208,208,47,0,165,9,1,0,158,9,1,0,18,1,1,208,208, + 208,111,248,252,248,24,208,208,208,96,248,252,248,24,208,208,208,56,0,0, + 148,1,0,0,163,1,0,0,172,1,0,0,182,2,0,0,170,1,0,0, + 159,1,0,0,133,1,0,0,0,2,208,208,208,30,248,252,248,2,0,0, + 0,2,248,252,248,16,0,0,0,2,248,252,248,2,208,208,208,54,0,0, + 149,1,0,0,169,1,0,0,217,1,0,0,245,1,0,0,255,4,0,0, + 245,1,0,0,215,1,0,0,160,1,0,0,84,1,0,0,0,1,208,208, + 208,29,248,252,248,2,0,0,0,3,248,252,248,14,0,0,0,3,248,252, + 248,2,208,208,208,30,242,48,20,1,245,86,49,2,240,45,18,1,208,208, + 208,4,240,48,20,1,245,88,50,2,242,46,18,1,208,208,208,11,0,0, + 162,1,0,0,190,1,0,0,251,1,0,0,255,3,9,9,255,1,14,14, + 255,1,17,17,255,2,14,14,255,1,9,9,251,1,1,1,180,1,0,0, + 133,1,0,0,0,2,208,208,208,27,248,252,248,3,0,0,0,3,248,252, + 248,12,0,0,0,3,248,252,248,3,208,208,208,30,244,80,45,1,253,163, + 110,2,228,74,41,1,2,0,0,1,208,208,208,3,244,80,45,1,253,163, + 110,2,228,74,41,1,2,0,0,1,208,208,208,9,0,0,162,1,0,0, + 220,1,0,0,255,2,1,1,255,1,14,14,255,1,26,26,255,1,35,35, + 255,1,41,41,255,1,45,45,255,2,41,41,255,1,35,35,255,1,26,26, + 255,1,10,10,214,1,0,0,118,1,0,0,0,2,208,208,208,26,248,252, + 248,4,0,0,0,3,248,252,248,10,0,0,0,3,248,252,248,4,208,208, + 208,30,244,77,41,1,252,153,102,2,228,71,39,1,4,0,0,1,208,208, + 208,3,244,77,41,1,252,153,102,2,228,71,39,1,4,0,0,1,208,208, + 208,8,0,0,149,1,0,0,190,1,0,0,255,1,0,0,245,1,4,4, + 156,1,21,21,235,1,38,38,255,1,51,51,255,1,62,62,255,1,69,69, + 255,1,72,72,255,2,63,63,233,1,38,38,156,1,50,50,245,1,39,39, + 255,1,9,9,176,1,0,0,43,1,0,0,0,1,208,208,208,26,248,252, + 248,5,0,0,0,3,248,252,248,3,0,0,248,2,248,252,248,3,0,0, + 0,3,248,252,248,5,208,208,208,30,243,72,38,1,251,143,94,2,229,68, + 36,1,5,0,0,1,208,208,208,3,243,72,38,1,251,143,95,2,229,68, + 37,1,5,0,0,1,208,208,208,8,0,0,169,1,0,0,251,1,0,0, + 255,1,4,4,156,1,0,0,0,1,7,7,40,1,55,55,231,1,76,76, + 255,1,87,87,255,1,95,95,255,1,100,100,255,1,91,91,231,1,15,15, + 40,1,0,0,0,1,46,46,156,1,62,62,255,1,43,43,251,1,5,5, + 143,1,0,0,0,2,208,208,208,10,6,6,159,1,12,12,175,1,19,19, + 185,1,25,25,186,1,21,21,174,1,12,12,156,1,208,208,208,9,248,252, + 248,6,0,0,0,3,0,0,248,6,0,0,0,3,248,252,248,6,208,208, + 208,5,0,0,0,2,208,208,208,4,0,0,0,2,208,208,208,4,0,0, + 0,3,208,208,208,10,243,68,35,1,250,133,87,2,227,65,34,1,7,0, + 0,1,208,208,208,3,243,68,35,1,250,133,87,2,227,65,34,1,7,0, + 0,1,208,208,208,7,0,0,148,1,0,0,217,1,0,0,255,2,21,21, + 233,1,7,7,40,1,0,0,0,1,13,13,40,1,90,90,231,1,113,113, + 255,1,122,122,255,1,115,115,231,1,20,20,40,1,0,0,0,1,18,18, + 40,1,92,92,235,1,83,83,255,1,65,65,255,1,29,29,210,1,0,0, + 54,1,0,0,0,2,208,208,208,8,4,4,171,1,14,14,204,1,40,40, + 254,1,52,52,255,1,64,64,255,1,75,75,254,1,46,46,195,1,20,20, + 145,1,208,208,208,8,248,252,248,7,0,0,0,3,0,0,248,4,0,0, + 0,3,248,252,248,7,208,208,208,3,0,0,0,12,208,208,208,1,0,0, + 0,6,208,208,208,8,243,64,32,1,249,123,79,2,227,61,31,1,9,0, + 0,1,208,208,208,3,243,64,32,1,249,123,79,2,227,61,31,1,9,0, + 0,1,208,208,208,7,0,0,163,1,0,0,245,1,0,0,255,1,14,14, + 255,1,37,37,255,1,54,54,231,1,13,13,40,1,0,0,0,1,19,19, + 40,1,120,120,231,1,124,124,231,1,22,22,40,1,0,0,0,1,21,21, + 40,1,120,120,231,1,122,122,255,1,103,103,255,1,83,83,255,1,56,56, + 245,1,4,4,105,1,0,0,0,2,208,208,208,7,0,0,159,1,9,9, + 204,1,28,28,255,1,40,40,255,1,52,52,255,1,64,64,255,1,76,76, + 255,1,88,88,255,1,50,50,190,1,5,5,62,1,208,208,208,7,248,252, + 248,7,0,0,248,1,0,0,0,3,0,0,248,2,0,0,0,3,0,0, + 248,1,248,252,248,7,208,208,208,3,0,0,0,20,208,208,208,7,242,60, + 28,1,248,113,71,2,227,57,28,1,11,2,0,1,208,208,208,3,242,60, + 28,1,248,113,71,2,227,57,28,1,11,2,0,1,208,208,208,7,0,0, + 172,1,0,0,255,2,25,25,255,1,50,50,255,1,74,74,255,1,88,88, + 231,1,19,19,40,1,0,0,0,1,20,20,36,1,21,21,36,1,0,0, + 0,1,24,24,40,1,133,133,231,1,141,141,255,1,134,134,255,1,120,120, + 255,1,98,98,255,1,74,74,255,1,11,11,138,1,0,0,0,2,208,208, + 208,7,1,1,175,1,17,17,254,1,28,28,255,1,40,40,255,1,52,52, + 255,1,64,64,255,1,76,76,255,1,88,88,255,1,99,99,254,1,24,24, + 135,1,0,0,0,1,208,208,208,6,248,252,248,7,0,0,248,2,0,0, + 0,6,0,0,248,2,248,252,248,7,208,208,208,3,0,0,0,20,208,208, + 208,7,242,55,25,1,247,103,63,2,225,54,25,1,12,2,0,1,208,208, + 208,3,242,55,25,1,247,103,63,2,225,54,25,1,12,2,0,1,208,208, + 208,7,0,0,182,1,0,0,255,1,7,7,255,1,33,33,255,1,58,58, + 255,1,84,84,255,1,109,109,255,1,119,119,231,1,20,20,36,1,0,0, + 0,2,23,23,36,1,146,146,231,1,157,157,255,1,149,149,255,1,140,140, + 255,1,131,131,255,1,109,109,255,1,84,84,255,1,19,19,161,1,0,0, + 0,2,208,208,208,7,3,3,185,1,17,17,255,1,28,28,255,1,40,40, + 255,1,52,52,255,1,64,64,255,1,76,76,255,1,88,88,255,1,100,100, + 255,1,37,37,159,1,0,0,0,1,208,208,208,6,248,252,248,6,0,0, + 248,4,0,0,0,4,0,0,248,4,248,252,248,6,208,208,208,3,0,0, + 0,20,208,208,208,7,242,52,22,1,246,93,55,2,226,50,22,1,12,2, + 0,1,208,208,208,3,242,52,22,1,246,93,55,2,226,50,23,1,12,2, + 0,1,208,208,208,7,0,0,182,1,0,0,255,1,11,11,255,1,38,38, + 255,1,64,64,255,1,90,90,255,1,117,117,255,1,121,121,231,1,21,21, + 36,1,0,0,0,2,24,24,36,1,156,156,231,1,165,165,255,1,155,155, + 255,1,145,145,255,1,134,134,255,1,117,117,255,1,91,91,255,1,21,21, + 160,1,0,0,0,2,208,208,208,7,3,3,186,1,17,17,255,1,28,28, + 255,1,40,40,255,1,52,52,255,1,64,64,255,1,76,76,255,1,88,88, + 255,1,100,100,255,1,37,37,159,1,0,0,0,1,208,208,208,6,248,252, + 248,6,0,0,248,4,0,0,0,4,0,0,248,4,248,252,248,6,208,208, + 208,4,0,0,0,19,208,208,208,7,241,47,19,1,245,83,48,2,225,45, + 20,1,14,2,0,1,208,208,208,3,241,47,19,1,245,83,48,1,245,84, + 48,1,225,47,20,1,14,2,0,1,208,208,208,7,0,0,170,1,0,0, + 255,1,13,13,255,1,39,39,255,1,66,66,255,1,93,93,255,1,108,108, + 231,1,21,21,40,1,0,0,0,1,23,23,36,1,24,24,36,1,0,0, + 0,1,28,28,40,1,152,152,231,1,157,157,255,1,147,147,255,1,136,136, + 255,1,119,119,255,1,93,93,255,1,14,14,137,1,0,0,0,2,208,208, + 208,7,1,1,174,1,17,17,254,1,28,28,255,1,40,40,255,1,52,52, + 255,1,64,64,255,1,76,76,255,1,88,88,255,1,99,99,254,1,24,24, + 135,1,0,0,0,1,208,208,208,6,248,252,248,7,0,0,248,2,0,0, + 0,6,0,0,248,2,248,252,248,7,208,208,208,5,0,0,0,4,208,208, + 208,2,0,0,0,4,208,208,208,2,0,0,0,5,208,208,208,8,241,44, + 17,1,244,73,40,2,224,42,17,1,16,2,0,1,208,208,208,3,241,44, + 17,1,244,74,40,2,224,42,17,1,16,2,0,1,208,208,208,7,0,0, + 159,1,0,0,245,1,11,11,255,1,38,38,255,1,64,64,255,1,82,82, + 231,1,18,18,40,1,0,0,0,1,23,23,40,1,140,140,231,1,149,149, + 231,1,27,27,40,1,0,0,0,1,26,26,40,1,140,140,231,1,145,145, + 255,1,134,134,255,1,117,117,255,1,82,82,245,1,8,8,101,1,0,0, + 0,2,208,208,208,7,0,0,156,1,9,9,195,1,28,28,255,1,40,40, + 255,1,52,52,255,1,64,64,255,1,76,76,255,1,88,88,255,1,51,51, + 190,1,3,3,37,1,0,0,0,1,208,208,208,6,248,252,248,7,0,0, + 248,1,0,0,0,3,0,0,248,2,0,0,0,3,0,0,248,1,248,252, + 248,7,208,208,208,5,0,0,0,4,208,208,208,2,0,0,0,4,208,208, + 208,2,0,0,0,4,208,208,208,9,241,40,13,1,243,64,32,2,224,38, + 14,1,18,2,0,1,208,208,208,3,241,40,13,1,243,64,32,2,224,38, + 14,1,18,2,0,1,208,208,208,7,0,0,133,1,0,0,215,1,7,7, + 255,1,33,33,255,1,54,54,235,1,13,13,40,1,0,0,0,1,21,21, + 40,1,127,127,231,1,149,149,255,1,157,157,255,1,146,146,231,1,25,25, + 40,1,0,0,0,1,23,23,40,1,128,128,233,1,131,131,255,1,109,109, + 255,1,54,54,211,1,0,0,43,1,0,0,0,2,208,208,208,8,2,2, + 145,1,15,15,190,1,40,40,254,1,52,52,255,1,64,64,255,1,75,75, + 254,1,44,44,190,1,12,12,92,1,0,0,0,2,208,208,208,6,248,252, + 248,7,0,0,0,3,0,0,248,4,0,0,0,3,248,252,248,7,208,208, + 208,5,0,0,0,3,208,208,208,3,0,0,0,3,208,208,208,3,0,0, + 0,4,208,208,208,9,240,35,9,1,242,54,24,2,223,35,11,1,19,2, + 0,1,208,208,208,3,240,35,9,1,242,54,24,2,223,35,11,1,19,2, + 0,1,208,208,208,7,0,0,0,1,0,0,160,1,0,0,251,1,25,25, + 255,1,31,31,156,1,0,0,0,1,15,15,40,1,109,109,231,1,134,134, + 255,1,141,141,255,1,147,147,255,1,150,150,255,1,136,136,231,1,23,23, + 40,1,0,0,0,1,82,82,156,1,120,120,255,1,94,94,251,1,15,15, + 139,1,0,0,0,3,208,208,208,9,0,0,62,1,8,8,135,1,18,18, + 159,1,21,21,159,1,17,17,135,1,2,2,37,1,0,0,0,2,208,208, + 208,7,248,252,248,6,0,0,0,3,0,0,248,6,0,0,0,3,248,252, + 248,6,208,208,208,5,0,0,0,4,208,208,208,2,0,0,0,4,208,208, + 208,2,0,0,0,4,208,208,208,9,240,32,6,1,241,44,16,2,224,31, + 6,1,21,2,0,1,208,208,208,3,240,32,6,1,241,44,16,2,224,31, + 7,1,21,2,0,1,208,208,208,7,0,0,0,1,0,0,84,1,0,0, + 180,1,14,14,255,1,37,37,245,1,37,37,156,1,76,76,233,1,103,103, + 255,1,122,122,255,1,132,132,255,1,137,137,255,1,139,139,255,2,126,126, + 235,1,81,81,156,1,116,116,245,1,103,103,255,1,32,32,174,1,0,0, + 21,1,0,0,0,3,208,208,208,10,0,0,0,6,208,208,208,8,248,252, + 248,5,0,0,0,3,248,252,248,3,0,0,248,2,248,252,248,3,0,0, + 0,3,248,252,248,5,208,208,208,6,0,0,0,2,208,208,208,4,0,0, + 0,2,208,208,208,4,0,0,0,2,208,208,208,10,240,27,4,1,240,34, + 8,2,222,26,3,1,23,2,0,1,208,208,208,3,240,27,4,1,240,34, + 9,2,222,26,4,1,23,2,0,1,208,208,208,8,0,0,0,1,0,0, + 133,1,1,1,214,1,23,23,255,1,45,45,255,1,65,65,255,1,83,83, + 255,1,100,100,255,1,113,113,255,1,123,123,255,1,127,127,255,2,122,122, + 255,1,113,113,255,1,99,99,255,1,57,57,214,1,6,6,88,1,0,0, + 0,3,208,208,208,25,248,252,248,4,0,0,0,3,248,252,248,10,0,0, + 0,3,248,252,248,4,208,208,208,30,238,24,0,1,223,22,0,1,222,22, + 0,1,224,22,0,1,24,2,0,1,208,208,208,3,239,23,0,1,222,21, + 0,1,219,21,0,1,222,21,0,1,24,2,0,1,208,208,208,9,0,0, + 0,1,0,0,118,1,3,3,176,1,25,25,251,1,45,45,255,1,62,62, + 255,1,76,76,255,1,88,88,255,1,96,96,255,1,100,100,255,2,95,95, + 255,1,84,84,251,1,30,30,174,1,6,6,88,1,0,0,0,3,208,208, + 208,26,248,252,248,3,0,0,0,3,248,252,248,12,0,0,0,3,248,252, + 248,3,208,208,208,30,255,43,0,1,9,0,0,1,4,0,0,1,0,0, + 0,2,208,208,208,4,0,0,0,4,208,208,208,9,0,0,0,2,0,0, + 44,1,1,1,143,1,14,14,210,1,36,36,245,1,52,52,255,1,62,62, + 255,1,69,69,255,1,72,72,255,1,66,66,245,1,44,44,211,1,13,13, + 139,1,0,0,21,1,0,0,0,4,208,208,208,26,248,252,248,2,0,0, + 0,3,248,252,248,14,0,0,0,3,248,252,248,2,208,208,208,53,0,0, + 0,3,0,0,54,1,1,1,105,1,6,6,137,1,11,11,161,1,13,13, + 160,1,10,10,137,1,5,5,101,1,0,0,43,1,0,0,0,5,208,208, + 208,27,248,252,248,2,0,0,0,2,248,252,248,16,0,0,0,2,248,252, + 248,2,208,208,208,55,0,0,0,12,208,208,208,29,248,252,248,24,208,208, + 208,56,0,0,0,10,208,208,208,30,248,252,248,24,208,208,208,24,192,192, + 192,48,208,208,208,6,0,0,188,3,208,208,208,26,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,33,192,192,192,48,208,208,208,6,0,0, + 188,1,26,26,213,1,0,0,188,2,208,208,208,25,0,0,0,5,208,208, + 208,32,192,192,192,48,208,208,208,6,0,0,188,1,73,73,234,1,54,54, + 226,1,0,0,188,2,208,208,208,26,0,0,0,2,208,208,208,33,192,192, + 192,48,208,208,208,6,0,0,188,1,107,107,238,1,125,125,251,1,69,69, + 226,1,0,0,188,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,1,208,208,208,55,192,192,192,48,208,208,208,6,0,0,188,1,134,134, + 238,1,169,169,255,1,149,149,251,1,84,84,226,1,0,0,188,2,0,0, + 0,5,208,208,208,54,192,192,192,48,208,208,208,3,6,6,207,1,26,26, + 215,1,38,38,220,1,24,24,210,1,136,136,234,1,189,189,252,1,195,195, + 255,1,173,173,251,1,98,98,226,1,0,0,188,2,208,208,208,1,0,0, + 0,9,208,208,208,3,0,0,170,1,23,23,215,1,35,35,220,1,43,43, + 223,1,48,48,225,1,48,48,224,4,34,34,219,1,0,0,182,1,208,208, + 208,34,192,192,192,48,208,208,208,2,20,20,213,1,47,47,225,1,108,108, + 253,1,111,111,255,1,62,62,228,1,112,112,227,1,158,158,242,1,167,167, + 245,1,175,175,248,1,161,161,242,1,72,72,212,1,0,0,188,1,208,208, + 208,3,0,0,0,7,208,208,208,2,0,0,206,1,31,31,219,1,95,95, + 248,1,111,111,255,7,83,83,242,1,0,0,78,1,0,0,0,1,208,208, + 208,33,192,192,192,11,0,0,248,2,192,192,192,23,0,0,248,1,192,192, + 192,11,208,208,208,1,5,5,206,1,54,54,229,1,111,111,255,2,96,96, + 247,1,30,30,207,1,88,88,219,1,127,127,232,1,136,136,235,1,135,135, + 235,1,86,86,217,1,0,0,111,1,0,0,20,1,208,208,208,3,0,0, + 0,7,208,208,208,1,0,0,170,1,33,33,219,1,108,108,254,1,111,111, + 255,1,99,99,250,1,69,69,229,1,53,53,215,1,52,52,215,1,50,50, + 213,1,48,48,212,1,46,46,211,1,33,33,208,1,0,0,77,1,0,0, + 0,1,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,1,208,208, + 208,11,255,4,31,1,255,15,39,1,255,14,39,1,255,3,29,1,255,0, + 26,2,208,208,208,9,192,192,192,11,0,0,248,2,192,192,192,23,0,0, + 248,1,192,192,192,11,208,208,208,1,27,27,216,1,108,108,254,1,111,111, + 255,1,39,39,202,1,12,12,131,1,0,0,87,1,65,65,212,1,96,96, + 222,1,97,97,223,1,63,63,210,1,0,0,111,1,0,0,20,1,208,208, + 208,4,0,0,0,7,208,208,208,1,20,20,214,1,92,92,247,1,111,111, + 255,1,60,60,219,1,14,14,150,1,0,0,55,1,0,0,19,2,0,0, + 13,1,0,0,10,1,0,0,6,1,0,0,2,1,0,0,0,2,208,208, + 208,1,0,0,0,7,208,208,208,9,255,15,38,1,255,42,63,1,255,57, + 77,2,255,42,63,1,255,15,39,1,254,0,26,1,223,0,22,1,208,208, + 208,8,192,192,192,11,0,0,248,2,192,192,192,23,0,0,248,1,192,192, + 192,11,208,208,208,1,43,43,222,1,111,111,255,1,96,96,247,1,12,12, + 132,1,0,0,0,1,0,0,121,1,42,42,204,1,61,61,210,1,41,41, + 203,1,0,0,111,1,0,0,20,1,208,208,208,1,0,0,0,4,208,208, + 208,8,36,36,221,1,111,111,255,1,108,108,254,1,19,19,168,1,0,0, + 0,1,0,0,47,1,0,0,166,1,0,0,181,1,0,0,0,5,208,208, + 208,4,0,0,0,1,208,208,208,3,0,0,0,1,208,208,208,8,255,4, + 31,1,255,43,63,1,255,76,94,1,255,98,114,2,255,76,94,1,255,43, + 64,1,255,4,30,1,254,0,26,1,136,0,14,1,208,208,208,7,192,192, + 192,11,0,0,248,2,192,192,192,23,0,0,248,1,192,192,192,11,0,0, + 204,1,51,51,226,1,111,111,255,1,58,58,220,1,0,0,42,1,0,0, + 0,1,0,0,176,1,17,17,196,1,19,19,196,1,0,0,111,1,0,0, + 20,1,208,208,208,2,0,0,0,4,208,208,208,8,44,44,224,1,111,111, + 255,1,79,79,237,1,4,4,92,1,0,0,0,1,0,0,187,1,26,26, + 213,1,0,0,189,1,0,0,191,1,208,208,208,21,255,17,42,1,255,61, + 81,1,255,103,118,1,255,159,169,2,255,103,118,1,255,61,81,1,255,18, + 42,1,255,0,26,1,204,0,21,1,0,0,0,1,208,208,208,6,192,192, + 192,11,0,0,248,2,192,192,192,23,0,0,248,1,192,192,192,11,208,208, + 208,1,45,45,223,1,111,111,255,1,96,96,247,1,12,12,134,1,0,0, + 0,1,0,0,186,1,0,0,189,1,0,0,111,1,0,0,20,1,0,0, + 0,1,208,208,208,14,43,43,223,1,111,111,255,1,79,79,237,1,4,4, + 92,1,0,0,0,1,0,0,187,1,73,73,234,1,54,54,226,1,0,0, + 181,1,0,0,191,1,208,208,208,20,255,21,45,1,255,66,85,1,255,110, + 124,1,255,187,195,2,255,110,124,1,255,66,85,1,255,21,45,1,255,0, + 26,1,240,0,24,1,0,0,0,1,208,208,208,6,192,192,192,11,0,0, + 248,2,192,192,192,23,0,0,248,1,192,192,192,11,208,208,208,1,29,29, + 214,1,108,108,254,1,111,111,255,1,35,35,199,1,3,3,115,1,0,0, + 139,1,0,0,186,1,0,0,20,1,208,208,208,16,33,33,219,1,111,111, + 255,1,108,108,254,1,19,19,168,1,0,0,0,1,0,0,187,1,107,107, + 238,1,125,125,251,1,69,69,226,1,0,0,181,1,0,0,191,1,208,208, + 208,19,255,13,38,1,255,55,75,1,255,93,109,1,255,130,142,2,255,93, + 109,1,255,55,75,1,255,13,38,1,255,0,26,1,240,0,24,1,0,0, + 0,1,208,208,208,6,192,192,192,11,0,0,248,2,192,192,192,23,0,0, + 248,1,192,192,192,11,208,208,208,1,5,5,176,1,53,53,221,1,111,111, + 255,1,109,109,254,1,68,68,230,1,47,47,220,1,46,46,223,9,41,41, + 221,1,32,32,215,1,21,21,207,1,0,0,51,1,0,0,0,1,208,208, + 208,4,18,18,211,1,77,77,236,1,111,111,255,1,60,60,219,1,16,16, + 176,1,0,0,190,1,134,134,238,1,169,169,255,1,149,149,251,1,84,84, + 226,1,0,0,181,1,0,0,191,1,208,208,208,18,255,0,26,1,255,32, + 54,1,255,62,81,1,255,81,98,2,255,62,81,1,255,32,54,1,255,0, + 26,2,204,0,21,1,0,0,0,1,208,208,208,6,192,192,192,36,0,0, + 248,1,192,192,192,11,208,208,208,1,0,0,0,1,17,17,179,1,45,45, + 211,1,108,108,254,1,111,111,255,13,92,92,245,1,22,22,191,1,0,0, + 0,2,208,208,208,4,24,24,200,1,102,102,251,1,111,111,255,1,99,99, + 250,1,51,51,220,1,136,136,234,1,189,189,252,1,195,195,255,1,173,173, + 251,1,98,98,226,1,0,0,181,1,0,0,191,1,208,208,208,2,0,0, + 0,8,208,208,208,7,255,0,26,1,254,1,27,1,255,25,49,1,255,39, + 61,2,255,25,49,1,255,1,27,1,255,0,26,1,254,0,26,1,89,0, + 9,1,0,0,0,1,208,208,208,6,192,192,192,48,208,208,208,2,0,0, + 0,1,2,2,86,1,22,22,176,1,33,33,192,1,42,42,208,1,44,44, + 210,9,66,66,227,1,104,104,252,1,111,111,255,1,79,79,235,1,10,10, + 131,1,0,0,0,2,208,208,208,3,0,0,183,1,21,21,185,1,89,89, + 242,1,111,111,255,1,83,83,238,1,112,112,227,1,158,158,242,1,167,167, + 245,1,175,175,248,1,161,161,243,1,72,72,212,1,0,0,169,1,208,208, + 208,2,0,0,0,8,208,208,208,8,223,0,22,1,254,0,26,1,255,0, + 26,4,254,0,26,1,158,0,16,1,0,0,0,2,208,208,208,6,192,192, + 192,11,0,0,248,2,192,192,192,23,0,0,248,1,192,192,192,11,208,208, + 208,3,0,0,0,13,1,1,54,1,19,19,177,1,96,96,247,1,111,111, + 255,1,26,26,181,1,0,0,0,2,208,208,208,4,0,0,14,1,14,14, + 147,1,28,28,183,1,29,29,200,1,88,88,219,1,127,127,232,1,136,136, + 235,1,135,135,235,1,86,86,218,1,0,0,111,1,0,0,22,1,208,208, + 208,19,136,0,14,1,204,0,21,1,240,0,24,2,204,0,21,1,89,0, + 9,1,0,0,0,2,208,208,208,7,192,192,192,11,0,0,248,2,192,192, + 192,35,208,208,208,3,0,0,0,14,0,0,92,1,57,57,224,1,111,111, + 255,1,37,37,200,1,0,0,0,2,208,208,208,5,0,0,0,2,0,0, + 90,1,65,65,212,1,96,96,222,1,97,97,223,1,63,63,211,1,0,0, + 111,1,0,0,22,1,208,208,208,21,0,0,0,6,208,208,208,8,192,192, + 192,48,208,208,208,5,0,0,0,9,208,208,208,3,0,0,165,1,54,54, + 225,1,111,111,255,1,47,47,212,1,0,0,10,1,0,0,0,1,208,208, + 208,7,0,0,185,1,42,42,204,1,61,61,211,1,41,41,204,1,0,0, + 111,1,0,0,22,1,208,208,208,36,192,192,192,48,208,208,208,7,0,0, + 0,7,208,208,208,3,0,0,204,1,49,49,225,1,111,111,255,1,47,47, + 211,1,0,0,6,1,0,0,0,1,208,208,208,7,0,0,187,1,17,17, + 196,1,19,19,196,1,0,0,111,1,0,0,22,1,208,208,208,37,192,192, + 192,48,208,208,208,7,0,0,0,11,34,34,218,1,83,83,242,1,33,33, + 209,1,0,0,2,1,0,0,0,1,208,208,208,7,0,0,187,1,0,0, + 190,1,0,0,111,1,0,0,22,1,208,208,208,38,192,192,192,48,208,208, + 208,5,0,0,0,9,208,208,208,1,0,0,0,3,0,0,179,1,0,0, + 87,1,0,0,82,1,0,0,0,2,208,208,208,7,0,0,191,1,0,0, + 185,1,0,0,21,1,208,208,208,2,0,0,0,4,208,208,208,33,192,192, + 192,48,208,208,208,3,0,0,0,4,208,208,208,11,0,0,0,5,208,208, + 208,12,0,0,0,4,208,208,208,33,192,192,192,48,208,208,208,6,0,0, + 0,1,208,208,208,172,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,87,159,159,159,1,160,160,160,1,208,208,208,27,0,0,0,5,208,208, + 208,15,191,191,191,1,161,161,161,1,159,159,159,1,160,160,160,4,159,159, + 159,1,161,161,161,1,191,191,191,1,208,208,208,61,159,159,159,1,160,160, + 160,1,163,163,163,1,208,208,208,28,0,0,0,2,208,208,208,15,162,162, + 162,1,160,160,160,9,166,166,166,1,168,168,168,1,208,208,208,37,159,159, + 159,1,208,208,208,22,159,159,159,1,160,160,160,2,163,163,163,1,208,208, + 208,3,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,35,255,255, + 255,1,161,161,161,1,160,160,160,11,162,162,162,1,177,177,177,1,255,255, + 255,1,208,208,208,10,160,160,160,4,208,208,208,4,160,160,160,4,208,208, + 208,13,160,160,160,1,191,191,191,1,208,208,208,21,159,159,159,1,160,160, + 160,3,163,163,163,1,208,208,208,2,0,0,0,5,208,208,208,34,161,161, + 161,1,160,160,160,14,194,194,194,1,255,255,255,1,208,208,208,9,160,160, + 160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208, + 208,12,160,160,160,1,162,162,162,1,187,187,187,1,208,208,208,17,160,160, + 160,8,163,163,163,1,208,208,208,3,0,0,0,9,208,208,208,3,146,146, + 146,1,159,159,159,1,160,160,160,8,255,255,255,1,208,208,208,13,162,162, + 162,1,160,160,160,2,159,159,159,1,149,149,149,1,158,158,158,1,160,160, + 160,6,157,157,157,1,148,148,148,1,159,159,159,1,160,160,160,1,163,163, + 163,1,227,227,227,1,208,208,208,9,160,160,160,4,255,255,255,1,208,208, + 208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160,160,3,184,184, + 184,1,255,255,255,1,208,208,208,14,160,160,160,10,163,163,163,1,208,208, + 208,4,0,0,0,7,208,208,208,2,159,159,159,1,160,160,160,10,255,255, + 255,1,208,208,208,12,191,191,191,1,160,160,160,3,146,146,146,1,128,128, + 128,1,141,141,141,1,165,165,165,1,160,160,160,4,157,157,157,1,133,133, + 133,1,128,128,128,1,172,172,172,1,165,165,165,1,160,160,160,1,178,178, + 178,1,249,249,249,1,208,208,208,8,160,160,160,4,255,255,255,1,208,208, + 208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160,160,4,179,179, + 179,2,208,208,208,12,160,160,160,10,163,163,163,1,255,255,255,2,208,208, + 208,3,0,0,0,7,208,208,208,1,153,153,153,1,160,160,160,11,255,255, + 255,1,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,1,208,208, + 208,4,161,161,161,1,160,160,160,3,157,157,157,1,138,138,138,1,128,128, + 128,1,148,148,148,1,165,165,165,1,160,160,160,2,157,157,157,1,133,133, + 133,1,128,128,128,1,146,146,146,1,245,245,245,1,199,199,199,1,160,160, + 160,2,222,222,222,1,255,255,255,1,208,208,208,7,160,160,160,4,255,255, + 255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160, + 160,5,174,174,174,1,183,183,183,1,208,208,208,11,160,160,160,3,172,172, + 172,1,229,229,229,1,248,248,248,1,160,160,160,3,163,163,163,1,255,255, + 255,2,208,208,208,4,0,0,0,7,208,208,208,1,160,160,160,3,163,163, + 163,1,213,213,213,1,243,243,243,1,255,255,255,7,208,208,208,2,0,0, + 0,7,208,208,208,3,161,161,161,1,160,160,160,4,163,163,163,1,144,144, + 144,1,128,128,128,1,147,147,147,1,166,166,166,1,157,157,157,1,133,133, + 133,1,128,128,128,1,146,146,146,1,243,243,243,1,240,240,240,1,168,168, + 168,1,160,160,160,2,208,208,208,1,255,255,255,1,208,208,208,7,160,160, + 160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208, + 208,12,160,160,160,6,169,169,169,1,188,188,188,1,208,208,208,10,160,160, + 160,3,229,229,229,1,255,255,255,1,245,245,245,1,160,160,160,2,163,163, + 163,1,255,255,255,2,208,208,208,1,0,0,0,4,208,208,208,8,160,160, + 160,3,212,212,212,1,255,255,255,3,208,208,208,10,0,0,0,1,208,208, + 208,3,0,0,0,1,208,208,208,3,160,160,160,6,164,164,164,1,144,144, + 144,1,128,128,128,1,146,146,146,1,134,134,134,1,128,128,128,1,146,146, + 146,1,243,243,243,1,240,240,240,1,169,169,169,1,160,160,160,3,188,188, + 188,1,255,255,255,1,208,208,208,7,160,160,160,4,255,255,255,1,208,208, + 208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160,160,7,164,164, + 164,1,189,189,189,1,208,208,208,8,160,160,160,4,251,251,251,1,255,255, + 255,1,159,159,159,1,160,160,160,1,161,161,161,1,255,255,255,2,208,208, + 208,2,0,0,0,4,208,208,208,8,160,160,160,3,243,243,243,1,255,255, + 255,1,208,208,208,1,160,160,160,1,208,208,208,18,160,160,160,7,163,163, + 163,1,143,143,143,1,128,128,128,2,145,145,145,1,243,243,243,1,240,240, + 240,1,169,169,169,1,160,160,160,4,169,169,169,1,255,255,255,1,208,208, + 208,7,160,160,160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255, + 255,1,208,208,208,12,160,160,160,8,161,161,161,1,187,187,187,1,208,208, + 208,8,160,160,160,3,234,234,234,1,255,255,255,1,159,159,159,1,160,160, + 160,1,255,255,255,2,208,208,208,15,160,160,160,3,243,243,243,1,255,255, + 255,1,208,208,208,1,160,160,160,2,255,255,255,1,208,208,208,16,160,160, + 160,7,157,157,157,1,134,134,134,1,128,128,128,2,146,146,146,1,231,231, + 231,1,169,169,169,1,160,160,160,5,169,169,169,1,255,255,255,1,208,208, + 208,7,160,160,160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255, + 255,1,208,208,208,12,160,160,160,8,161,161,161,1,215,215,215,1,255,255, + 255,1,208,208,208,7,160,160,160,3,175,175,175,1,198,198,198,1,160,160, + 160,1,255,255,255,2,208,208,208,16,160,160,160,3,210,210,210,1,255,255, + 255,1,208,208,208,1,160,160,160,3,255,255,255,1,208,208,208,15,160,160, + 160,6,157,157,157,1,133,133,133,1,128,128,128,1,144,144,144,1,148,148, + 148,1,128,128,128,1,145,145,145,1,167,167,167,1,160,160,160,5,188,188, + 188,1,255,255,255,1,208,208,208,7,160,160,160,4,255,255,255,1,208,208, + 208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160,160,7,165,165, + 165,1,228,228,228,1,255,255,255,2,208,208,208,7,160,160,160,1,161,161, + 161,1,160,160,160,17,208,208,208,5,160,160,160,3,163,163,163,1,197,197, + 197,1,156,156,156,1,160,160,160,4,255,255,255,1,208,208,208,14,161,161, + 161,1,160,160,160,4,157,157,157,1,133,133,133,1,128,128,128,1,146,146, + 146,1,243,243,243,1,232,232,232,1,147,147,147,1,128,128,128,1,145,145, + 145,1,167,167,167,1,160,160,160,4,208,208,208,1,255,255,255,1,208,208, + 208,7,160,160,160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255, + 255,1,208,208,208,12,160,160,160,6,171,171,171,1,238,238,238,1,255,255, + 255,2,208,208,208,9,178,178,178,1,163,163,163,1,160,160,160,15,179,179, + 179,1,236,236,236,1,208,208,208,4,170,170,170,1,168,168,168,1,160,160, + 160,9,255,255,255,1,208,208,208,3,0,0,0,8,208,208,208,2,161,161, + 161,1,160,160,160,3,157,157,157,1,133,133,133,1,128,128,128,1,146,146, + 146,1,243,243,243,1,240,240,240,1,169,169,169,1,163,163,163,1,147,147, + 147,1,128,128,128,1,144,144,144,1,169,169,169,1,160,160,160,3,227,227, + 227,1,255,255,255,1,208,208,208,7,160,160,160,4,255,255,255,1,208,208, + 208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160,160,5,180,180, + 180,1,246,246,246,1,255,255,255,2,208,208,208,11,223,223,223,1,194,194, + 194,1,176,176,176,1,161,161,161,1,160,160,160,13,204,204,204,1,255,255, + 255,1,208,208,208,4,161,161,161,1,175,175,175,1,160,160,160,9,255,255, + 255,1,208,208,208,2,0,0,0,8,208,208,208,2,191,191,191,1,166,166, + 166,1,160,160,160,2,148,148,148,1,128,128,128,1,146,146,146,1,243,243, + 243,1,240,240,240,1,169,169,169,1,160,160,160,2,163,163,163,1,148,148, + 148,1,128,128,128,1,196,196,196,1,172,172,172,1,160,160,160,1,179,179, + 179,1,254,254,254,1,255,255,255,1,208,208,208,7,160,160,160,4,255,255, + 255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160, + 160,4,191,191,191,1,252,252,252,1,255,255,255,2,208,208,208,12,0,0, + 0,1,255,255,255,2,241,241,241,1,255,255,255,9,244,244,244,1,197,197, + 197,1,160,160,160,2,192,192,192,1,255,255,255,1,208,208,208,5,240,240, + 240,1,202,202,202,1,185,185,185,1,167,167,167,1,160,160,160,5,255,255, + 255,2,208,208,208,13,168,168,168,1,162,162,162,1,160,160,160,1,159,159, + 159,1,169,169,169,1,244,244,244,1,240,240,240,1,169,169,169,1,160,160, + 160,4,163,163,163,1,196,196,196,1,251,251,251,1,202,202,202,1,163,163, + 163,1,240,240,240,1,255,255,255,2,208,208,208,7,160,160,160,4,255,255, + 255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160, + 160,3,205,205,205,1,255,255,255,3,208,208,208,13,0,0,0,5,208,208, + 208,9,191,191,191,1,160,160,160,2,174,174,174,1,255,255,255,1,208,208, + 208,6,255,255,255,3,160,160,160,4,255,255,255,2,208,208,208,15,177,177, + 177,1,160,160,160,2,162,162,162,1,194,194,194,1,168,168,168,1,160,160, + 160,6,164,164,164,1,191,191,191,1,163,163,163,1,213,213,213,1,255,255, + 255,2,208,208,208,8,160,160,160,4,255,255,255,1,208,208,208,3,160,160, + 160,4,255,255,255,1,208,208,208,12,160,160,160,1,162,162,162,1,219,219, + 219,1,255,255,255,3,208,208,208,16,0,0,0,9,208,208,208,3,160,160, + 160,3,165,165,165,1,255,255,255,1,208,208,208,9,160,160,160,3,255,255, + 255,2,208,208,208,16,255,255,255,1,194,194,194,1,163,163,163,1,160,160, + 160,10,163,163,163,1,213,213,213,1,255,255,255,2,208,208,208,9,160,160, + 160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208, + 208,12,160,160,160,1,232,232,232,1,255,255,255,2,208,208,208,20,0,0, + 0,7,208,208,208,3,160,160,160,3,163,163,163,1,255,255,255,1,208,208, + 208,9,160,160,160,2,255,255,255,2,208,208,208,18,255,255,255,1,227,227, + 227,1,178,178,178,1,160,160,160,8,179,179,179,1,240,240,240,1,255,255, + 255,3,208,208,208,10,255,255,255,4,208,208,208,4,255,255,255,4,208,208, + 208,12,159,159,159,1,255,255,255,2,208,208,208,21,0,0,0,10,29,29, + 29,1,160,160,160,2,163,163,163,1,255,255,255,1,208,208,208,9,160,160, + 160,1,252,252,252,1,255,255,255,1,208,208,208,21,249,249,249,1,222,222, + 222,1,207,207,207,1,188,188,188,1,169,169,169,2,188,188,188,1,207,207, + 207,1,227,227,227,1,254,254,254,1,255,255,255,2,208,208,208,37,255,255, + 255,1,208,208,208,20,0,0,0,9,208,208,208,1,0,0,0,3,195,195, + 195,1,255,255,255,3,208,208,208,9,255,255,255,2,208,208,208,2,0,0, + 0,4,208,208,208,17,255,255,255,10,208,208,208,57,0,0,0,4,208,208, + 208,12,255,255,255,1,208,208,208,15,0,0,0,4,208,208,208,87,0,0, + 0,1,208,208,208,43,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,53,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,11,0,0, + 0,1,208,208,208,2,0,0,0,1,208,208,208,44,0,0,0,5,208,208, + 208,23,159,159,159,1,160,160,160,1,208,208,208,27,0,0,0,5,208,208, + 208,10,0,0,0,5,208,208,208,45,0,0,0,9,208,208,208,5,160,160, + 160,1,208,208,208,11,159,159,159,1,160,160,160,1,163,163,163,1,208,208, + 208,28,0,0,0,2,208,208,208,13,0,0,0,9,208,208,208,5,0,0, + 205,1,0,0,203,2,208,208,208,33,0,0,0,7,208,208,208,4,160,160, + 160,4,208,208,208,9,159,159,159,1,160,160,160,2,163,163,163,1,208,208, + 208,3,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,37,0,0, + 0,7,208,208,208,5,34,34,219,1,83,83,242,1,35,35,219,1,0,0, + 21,1,0,0,0,1,208,208,208,31,0,0,0,11,160,160,160,3,163,163, + 163,1,255,255,255,1,208,208,208,8,159,159,159,1,160,160,160,3,163,163, + 163,1,208,208,208,2,0,0,0,5,208,208,208,36,0,0,0,11,0,0, + 191,1,48,48,225,1,111,111,255,1,47,47,212,1,0,0,4,1,0,0, + 0,1,208,208,208,31,0,0,0,11,160,160,160,3,165,165,165,1,255,255, + 255,1,208,208,208,5,160,160,160,8,163,163,163,1,208,208,208,3,0,0, + 0,9,208,208,208,3,146,146,146,1,159,159,159,1,160,160,160,8,255,255, + 255,1,208,208,208,16,0,0,0,11,0,0,213,1,55,55,228,1,111,111, + 255,1,48,48,212,1,0,0,10,1,0,0,0,1,208,208,208,27,0,0, + 0,4,208,208,208,11,160,160,160,3,174,174,174,1,255,255,255,1,208,208, + 208,4,160,160,160,10,163,163,163,1,208,208,208,4,0,0,0,7,208,208, + 208,2,159,159,159,1,160,160,160,10,255,255,255,1,208,208,208,12,0,0, + 0,4,208,208,208,11,0,0,198,1,58,58,229,1,111,111,255,1,41,41, + 204,1,0,0,2,1,0,0,0,1,208,208,208,27,0,0,0,4,208,208, + 208,10,160,160,160,4,192,192,192,1,255,255,255,1,208,208,208,3,160,160, + 160,10,163,163,163,1,255,255,255,2,208,208,208,3,0,0,0,7,208,208, + 208,1,153,153,153,1,160,160,160,11,255,255,255,1,208,208,208,2,0,0, + 0,3,208,208,208,2,0,0,0,1,208,208,208,4,0,0,0,4,208,208, + 208,10,0,0,208,1,25,25,213,1,97,97,248,1,111,111,255,1,32,32, + 187,1,0,0,0,2,208,208,208,10,0,0,159,1,0,0,175,1,0,0, + 186,2,0,0,174,1,0,0,156,1,208,208,208,12,160,160,160,17,214,214, + 214,1,255,255,255,1,208,208,208,3,160,160,160,3,172,172,172,1,229,229, + 229,1,248,248,248,1,160,160,160,3,163,163,163,1,255,255,255,2,208,208, + 208,4,0,0,0,7,208,208,208,1,160,160,160,3,163,163,163,1,213,213, + 213,1,243,243,243,1,255,255,255,7,208,208,208,2,0,0,0,7,208,208, + 208,4,15,15,209,1,29,29,217,1,40,40,221,1,47,47,224,1,48,48, + 224,9,69,69,235,1,103,103,251,1,111,111,255,1,101,101,250,1,17,17, + 159,1,0,0,0,2,208,208,208,9,0,0,171,1,0,0,203,1,0,0, + 254,1,0,0,255,2,0,0,254,1,0,0,196,1,0,0,145,1,208,208, + 208,10,160,160,160,17,191,191,191,1,254,254,254,1,255,255,255,1,208,208, + 208,3,160,160,160,3,229,229,229,1,255,255,255,1,245,245,245,1,160,160, + 160,2,163,163,163,1,255,255,255,2,208,208,208,1,0,0,0,4,208,208, + 208,8,160,160,160,3,212,212,212,1,255,255,255,3,208,208,208,10,0,0, + 0,1,208,208,208,3,0,0,0,1,208,208,208,3,23,23,214,1,60,60, + 231,1,111,111,255,14,99,99,248,1,27,27,191,1,0,0,17,1,0,0, + 0,2,208,208,208,8,0,0,159,1,0,0,203,1,0,0,255,6,0,0, + 190,1,0,0,62,1,208,208,208,8,160,160,160,15,167,167,167,1,184,184, + 184,1,204,204,204,1,252,252,252,1,255,255,255,2,208,208,208,2,160,160, + 160,4,251,251,251,1,255,255,255,1,159,159,159,1,160,160,160,1,161,161, + 161,1,255,255,255,2,208,208,208,2,0,0,0,4,208,208,208,8,160,160, + 160,3,243,243,243,1,255,255,255,1,208,208,208,1,160,160,160,1,208,208, + 208,17,12,12,206,1,62,62,231,1,111,111,255,2,79,79,237,1,49,49, + 213,1,44,44,211,1,47,47,211,1,48,48,212,2,48,48,213,1,51,51, + 214,1,51,51,215,1,52,52,215,1,53,53,216,1,43,43,205,1,30,30, + 184,1,15,15,150,1,0,0,13,1,0,0,0,2,208,208,208,9,0,0, + 175,1,0,0,254,1,0,0,255,6,0,0,254,1,0,0,135,1,0,0, + 0,1,208,208,208,7,160,160,160,3,175,175,175,1,232,232,232,1,252,252, + 252,1,255,255,255,14,208,208,208,4,160,160,160,3,234,234,234,1,255,255, + 255,1,159,159,159,1,160,160,160,1,255,255,255,2,208,208,208,15,160,160, + 160,3,243,243,243,1,255,255,255,1,208,208,208,1,160,160,160,2,255,255, + 255,1,208,208,208,15,29,29,216,1,109,109,254,1,111,111,255,1,31,31, + 196,1,3,3,84,1,0,0,33,1,0,0,82,1,0,0,27,1,0,0, + 6,1,0,0,10,1,0,0,12,1,0,0,15,1,0,0,17,1,0,0, + 19,1,0,0,23,1,0,0,2,1,0,0,0,5,208,208,208,9,0,0, + 186,1,0,0,255,8,0,0,160,1,0,0,0,1,208,208,208,7,160,160, + 160,3,234,234,234,1,255,255,255,1,244,244,244,1,160,160,160,1,208,208, + 208,17,160,160,160,3,175,175,175,1,198,198,198,1,160,160,160,1,255,255, + 255,2,208,208,208,16,160,160,160,3,210,210,210,1,255,255,255,1,208,208, + 208,1,160,160,160,3,255,255,255,1,208,208,208,14,38,38,219,1,111,111, + 255,1,91,91,245,1,7,7,112,1,0,0,0,1,0,0,134,1,26,26, + 223,1,0,0,192,1,0,0,120,1,0,0,0,11,208,208,208,10,0,0, + 186,1,0,0,255,8,0,0,159,1,0,0,0,1,208,208,208,6,160,160, + 160,4,251,251,251,1,255,255,255,1,159,159,159,1,160,160,160,1,161,161, + 161,1,208,208,208,16,160,160,160,1,161,161,161,1,160,160,160,17,208,208, + 208,5,160,160,160,3,163,163,163,1,197,197,197,1,156,156,156,1,160,160, + 160,4,255,255,255,1,208,208,208,13,43,43,221,1,111,111,255,1,63,63, + 226,1,0,0,51,1,0,0,0,1,0,0,191,1,73,73,239,1,54,54, + 233,1,0,0,204,2,208,208,208,20,0,0,174,1,0,0,254,1,0,0, + 255,6,0,0,254,1,0,0,135,1,0,0,0,1,208,208,208,7,160,160, + 160,3,229,229,229,1,255,255,255,1,159,159,159,1,160,160,160,2,163,163, + 163,1,208,208,208,2,0,0,0,6,208,208,208,8,178,178,178,1,163,163, + 163,1,160,160,160,15,179,179,179,1,236,236,236,1,208,208,208,4,170,170, + 170,1,168,168,168,1,160,160,160,9,255,255,255,1,208,208,208,3,0,0, + 0,8,208,208,208,1,37,37,218,1,111,111,255,1,101,101,251,1,17,17, + 152,1,0,0,0,1,0,0,202,1,107,107,242,1,125,125,252,1,69,69, + 233,1,0,0,204,2,0,0,0,6,208,208,208,13,0,0,156,1,0,0, + 196,1,0,0,255,6,0,0,190,1,0,0,36,1,0,0,0,1,208,208, + 208,7,160,160,160,3,172,172,172,1,200,200,200,1,160,160,160,4,163,163, + 163,1,208,208,208,1,0,0,0,6,208,208,208,9,223,223,223,1,194,194, + 194,1,176,176,176,1,161,161,161,1,160,160,160,13,204,204,204,1,255,255, + 255,1,208,208,208,4,161,161,161,1,175,175,175,1,160,160,160,9,255,255, + 255,1,208,208,208,2,0,0,0,8,208,208,208,1,26,26,212,1,107,107, + 253,1,111,111,255,1,50,50,212,1,12,12,163,1,0,0,191,1,134,134, + 242,1,169,169,255,1,149,149,252,1,84,84,233,1,0,0,204,1,0,0, + 79,1,0,0,0,5,208,208,208,14,0,0,145,1,0,0,190,1,0,0, + 254,1,0,0,255,2,0,0,254,1,0,0,190,1,0,0,92,1,0,0, + 0,2,208,208,208,7,160,160,160,1,163,163,163,1,160,160,160,8,163,163, + 163,1,208,208,208,4,0,0,0,7,208,208,208,4,0,0,0,1,255,255, + 255,2,241,241,241,1,255,255,255,9,244,244,244,1,197,197,197,1,160,160, + 160,2,192,192,192,1,255,255,255,1,208,208,208,5,240,240,240,1,202,202, + 202,1,185,185,185,1,167,167,167,1,160,160,160,5,255,255,255,2,208,208, + 208,11,0,0,164,1,49,49,219,1,111,111,255,2,87,87,243,1,29,29, + 214,1,136,136,238,1,189,189,252,1,195,195,255,1,173,173,252,1,98,98, + 233,1,0,0,204,2,208,208,208,2,0,0,0,7,208,208,208,10,0,0, + 62,1,0,0,135,1,0,0,160,1,0,0,159,1,0,0,135,1,0,0, + 36,1,0,0,0,2,208,208,208,9,179,179,179,1,165,165,165,1,160,160, + 160,8,163,163,163,1,208,208,208,3,0,0,0,7,208,208,208,4,0,0, + 0,5,208,208,208,9,191,191,191,1,160,160,160,2,174,174,174,1,255,255, + 255,1,208,208,208,6,255,255,255,3,160,160,160,4,255,255,255,2,208,208, + 208,12,0,0,0,1,16,16,178,1,46,46,211,1,109,109,254,1,111,111, + 255,1,62,62,232,1,112,112,231,1,158,158,242,1,167,167,245,1,175,175, + 248,1,161,161,244,1,72,72,222,1,0,0,204,1,208,208,208,2,0,0, + 0,7,208,208,208,11,0,0,0,6,208,208,208,11,224,224,224,1,195,195, + 195,1,176,176,176,1,161,161,161,1,160,160,160,4,163,163,163,1,255,255, + 255,2,208,208,208,2,0,0,0,8,208,208,208,5,0,0,0,9,208,208, + 208,3,160,160,160,3,165,165,165,1,255,255,255,1,208,208,208,9,160,160, + 160,3,255,255,255,2,208,208,208,14,0,0,0,1,3,3,93,1,23,23, + 176,1,37,37,195,1,26,26,208,1,88,88,223,1,127,127,232,1,136,136, + 235,1,135,135,236,1,86,86,224,1,0,0,120,1,0,0,23,1,208,208, + 208,2,0,0,0,8,208,208,208,28,255,255,255,2,251,251,251,1,160,160, + 160,3,163,163,163,1,255,255,255,1,252,252,252,1,0,0,0,4,208,208, + 208,1,0,0,0,2,208,208,208,11,0,0,0,7,208,208,208,3,160,160, + 160,3,163,163,163,1,255,255,255,1,208,208,208,9,160,160,160,2,255,255, + 255,2,208,208,208,16,0,0,0,3,0,0,94,1,65,65,216,1,96,96, + 222,1,97,97,224,1,63,63,217,1,0,0,120,1,0,0,23,1,0,0, + 0,4,208,208,208,1,0,0,0,2,208,208,208,34,159,159,159,1,160,160, + 160,2,163,163,163,1,255,255,255,2,0,0,0,5,208,208,208,14,0,0, + 0,10,29,29,29,1,160,160,160,2,163,163,163,1,255,255,255,1,208,208, + 208,9,160,160,160,1,252,252,252,1,255,255,255,1,208,208,208,18,0,0, + 0,2,0,0,183,1,42,42,208,1,61,61,211,1,41,41,210,1,0,0, + 120,1,0,0,23,1,0,0,0,5,208,208,208,37,159,159,159,1,160,160, + 160,1,163,163,163,1,255,255,255,2,208,208,208,18,0,0,0,9,208,208, + 208,1,0,0,0,3,195,195,195,1,255,255,255,3,208,208,208,9,255,255, + 255,2,208,208,208,2,0,0,0,4,208,208,208,15,0,0,204,1,17,17, + 201,1,19,19,203,1,0,0,120,1,0,0,23,1,208,208,208,43,159,159, + 159,1,160,160,160,1,255,255,255,2,208,208,208,17,0,0,0,4,208,208, + 208,12,255,255,255,1,208,208,208,15,0,0,0,4,208,208,208,15,0,0, + 204,1,0,0,200,1,0,0,120,1,0,0,23,1,208,208,208,45,255,255, + 255,2,208,208,208,21,0,0,0,1,208,208,208,47,0,0,204,1,0,0, + 195,1,0,0,23,1,208,208,208,39,84,58,0,0,0,0,0,30,16,16, + 16,1,64,64,64,1,16,16,16,1,0,0,0,26,12,12,12,1,0,0, + 0,2,12,12,12,1,0,0,0,11,12,12,12,1,0,0,0,2,12,12, + 12,1,0,0,0,72,64,64,64,1,255,255,255,1,112,112,112,1,16,16, + 16,1,0,0,0,25,70,70,70,1,105,105,105,1,100,100,100,1,104,104, + 104,1,112,112,112,1,0,0,0,10,70,70,70,1,105,105,105,1,100,100, + 100,1,104,104,104,1,112,112,112,1,0,0,0,71,64,64,64,1,255,255, + 255,2,112,112,112,1,16,16,16,1,0,0,0,26,19,19,19,1,23,23, + 23,1,0,0,0,13,19,19,19,1,23,23,23,2,26,26,26,1,59,59, + 59,1,11,11,11,1,23,23,23,1,40,40,40,1,17,17,17,1,0,0, + 0,5,61,61,61,1,64,64,64,2,0,0,0,40,255,255,255,2,0,0, + 0,15,64,64,64,1,255,255,255,3,112,112,112,1,16,16,16,1,0,0, + 0,1,12,12,12,1,0,0,0,2,12,12,12,1,0,0,0,37,65,65, + 65,1,77,77,77,1,73,73,73,1,26,26,26,1,53,53,53,1,71,71, + 71,1,36,36,36,1,0,0,0,5,230,230,230,1,255,255,255,1,233,233, + 233,1,12,12,12,1,1,1,1,1,0,0,0,7,59,59,59,1,123,123, + 123,1,1,1,1,1,0,0,0,28,255,255,255,2,0,0,0,15,64,64, + 64,1,255,255,255,4,112,112,112,1,16,16,16,1,96,96,96,1,114,114, + 114,1,98,98,98,1,100,100,100,1,84,84,84,1,0,0,0,36,38,38, + 38,1,47,47,47,1,53,53,53,1,71,71,71,1,54,54,54,1,48,48, + 48,1,30,30,30,1,42,42,42,1,31,31,31,1,77,77,77,1,40,40, + 40,1,4,4,4,1,227,227,227,1,255,255,255,1,240,240,240,1,116,116, + 116,1,11,11,11,1,0,0,0,7,64,64,64,1,246,246,246,1,186,186, + 186,1,6,6,6,1,0,0,0,19,255,255,255,10,0,0,0,12,32,32, + 32,1,172,172,172,1,200,200,200,1,236,236,236,1,255,255,255,5,112,112, + 112,1,16,16,16,1,0,0,0,1,33,33,33,1,10,10,10,1,26,26, + 26,1,40,40,40,1,44,44,44,1,18,18,18,1,16,16,16,1,50,50, + 50,1,8,8,8,1,0,0,0,3,3,3,3,1,133,133,133,1,184,184, + 184,1,211,211,211,1,224,224,224,1,225,225,225,4,233,233,233,1,71,71, + 71,1,0,0,0,16,47,47,47,1,76,76,76,1,87,87,87,1,57,57, + 57,1,61,61,61,1,46,46,46,1,35,35,35,1,36,36,36,1,24,24, + 24,1,61,61,61,1,22,22,22,1,12,12,12,1,229,229,229,1,255,255, + 255,1,241,241,241,1,128,128,128,1,12,12,12,1,0,0,0,7,64,64, + 64,1,255,255,255,1,252,252,252,1,211,211,211,1,20,20,20,1,0,0, + 0,21,255,255,255,6,0,0,0,12,91,91,91,1,222,222,222,1,255,255, + 255,9,64,64,64,1,0,0,0,3,80,80,80,1,89,89,89,1,45,45, + 45,1,42,42,42,1,36,36,36,1,82,82,82,1,27,27,27,1,0,0, + 0,2,26,26,26,1,196,196,196,1,253,253,253,1,255,255,255,8,167,167, + 167,1,1,1,1,1,0,0,0,11,45,45,45,1,70,70,70,1,74,74, + 74,1,80,80,80,1,0,0,0,11,22,22,22,1,232,232,232,1,255,255, + 255,1,237,237,237,1,122,122,122,1,11,11,11,1,0,0,0,7,64,64, + 64,1,255,255,255,3,226,226,226,1,44,44,44,1,1,1,1,1,0,0, + 0,15,255,255,255,10,0,0,0,11,37,37,37,1,227,227,227,1,255,255, + 255,3,248,248,248,1,255,255,255,5,191,191,191,1,147,147,147,1,0,0, + 0,3,43,43,43,1,47,47,47,1,56,56,56,1,77,77,77,1,51,51, + 51,1,55,55,55,1,31,31,31,1,0,0,0,1,3,3,3,1,204,204, + 204,1,255,255,255,3,249,249,249,1,243,243,243,1,242,242,242,2,241,241, + 241,2,245,245,245,1,168,168,168,1,1,1,1,1,0,0,0,1,12,12, + 12,1,4,4,4,1,17,17,17,1,0,0,0,2,25,25,25,1,0,0, + 0,4,17,17,17,1,29,29,29,1,31,31,31,1,42,42,42,1,0,0, + 0,10,38,38,38,1,184,184,184,1,252,252,252,1,255,255,255,1,226,226, + 226,1,110,110,110,1,10,10,10,1,0,0,0,7,64,64,64,1,255,255, + 255,4,235,235,235,1,80,80,80,1,1,1,1,1,0,0,0,18,255,255, + 255,7,0,0,0,10,183,183,183,1,255,255,255,2,235,235,235,1,192,192, + 192,1,170,170,170,1,255,255,255,4,191,191,191,1,147,147,147,1,0,0, + 0,4,53,53,53,1,78,78,78,1,90,90,90,1,62,62,62,1,65,65, + 65,1,56,56,56,1,28,28,28,1,0,0,0,1,125,125,125,1,251,251, + 251,1,255,255,255,1,243,243,243,1,204,204,204,1,158,158,158,1,145,145, + 145,1,137,137,137,1,135,135,135,1,134,134,134,1,133,133,133,1,131,131, + 131,1,130,130,130,1,1,1,1,1,0,0,0,1,86,86,86,1,99,99, + 99,1,96,96,96,1,43,43,43,1,70,70,70,1,98,98,98,1,34,34, + 34,1,0,0,0,4,66,66,66,1,184,184,184,1,206,206,206,1,223,223, + 223,1,225,225,225,9,239,239,239,1,255,255,255,3,207,207,207,1,89,89, + 89,1,8,8,8,1,0,0,0,7,64,64,64,1,255,255,255,5,241,241, + 241,1,124,124,124,1,1,1,1,1,0,0,0,14,255,255,255,11,0,0, + 0,9,211,211,211,1,255,255,255,2,192,192,192,1,112,112,112,1,99,99, + 99,1,255,255,255,3,191,191,191,1,147,147,147,1,0,0,0,1,68,68, + 68,1,73,73,73,1,78,78,78,1,57,57,57,1,0,0,0,8,189,189, + 189,1,255,255,255,2,216,216,216,1,132,132,132,1,66,66,66,1,72,72, + 72,1,17,17,17,1,1,1,1,5,0,0,0,4,1,1,1,1,0,0, + 0,3,8,8,8,1,0,0,0,3,131,131,131,1,233,233,233,1,255,255, + 255,15,231,231,231,1,135,135,135,1,61,61,61,1,5,5,5,1,0,0, + 0,7,64,64,64,1,255,255,255,6,246,246,246,1,163,163,163,1,2,2, + 2,1,0,0,0,17,255,255,255,5,0,0,0,1,255,255,255,2,0,0, + 0,7,6,6,6,1,225,225,225,1,255,255,255,1,244,244,244,1,146,146, + 146,1,49,49,49,1,68,68,68,1,255,255,255,2,191,191,191,1,147,147, + 147,1,0,0,0,2,30,30,30,1,23,23,23,1,34,34,34,1,32,32, + 32,1,0,0,0,8,209,209,209,1,255,255,255,1,252,252,252,1,174,174, + 174,1,59,59,59,1,64,64,64,1,255,255,255,1,112,112,112,1,16,16, + 16,1,0,0,0,15,42,42,42,1,232,232,232,1,255,255,255,2,252,252, + 252,1,242,242,242,1,241,241,241,4,242,242,242,4,243,243,243,1,237,237, + 237,1,225,225,225,1,203,203,203,1,135,135,135,1,88,88,88,1,13,13, + 13,1,0,0,0,8,64,64,64,1,255,255,255,7,250,250,250,1,196,196, + 196,1,9,9,9,1,0,0,0,12,255,255,255,2,0,0,0,2,255,255, + 255,6,0,0,0,1,255,255,255,1,0,0,0,8,210,210,210,1,255,255, + 255,2,187,187,187,1,24,24,24,1,65,65,65,1,255,255,255,1,191,191, + 191,1,147,147,147,1,2,2,2,1,0,0,0,14,208,208,208,1,255,255, + 255,1,252,252,252,1,174,174,174,1,17,17,17,1,64,64,64,1,255,255, + 255,2,117,117,117,1,16,16,16,1,0,0,0,14,176,176,176,1,255,255, + 255,2,234,234,234,1,170,170,170,1,142,142,142,1,161,161,161,1,137,137, + 137,1,130,130,130,1,131,131,131,1,132,132,132,1,133,133,133,2,134,134, + 134,1,135,135,135,1,128,128,128,1,119,119,119,1,98,98,98,1,71,71, + 71,1,16,16,16,1,1,1,1,1,0,0,0,8,64,64,64,1,255,255, + 255,8,254,254,254,1,217,217,217,1,26,26,26,1,0,0,0,10,255,255, + 255,11,0,0,0,10,181,181,181,1,255,255,255,2,233,233,233,1,87,87, + 87,1,22,22,22,1,65,65,65,1,147,147,147,1,0,0,0,16,185,185, + 185,1,255,255,255,2,215,215,215,1,20,20,20,1,64,64,64,1,255,255, + 255,3,117,117,117,1,16,16,16,1,0,0,0,13,199,199,199,1,255,255, + 255,2,183,183,183,1,108,108,108,1,98,98,98,1,255,255,255,1,119,119, + 119,1,27,27,27,1,12,12,12,7,11,11,11,1,9,9,9,1,6,6, + 6,1,1,1,1,1,0,0,0,9,64,64,64,1,255,255,255,8,254,254, + 254,1,226,226,226,1,105,105,105,1,1,1,1,1,0,0,0,9,255,255, + 255,7,0,0,0,1,255,255,255,3,0,0,0,10,41,41,41,1,235,235, + 235,1,255,255,255,2,247,247,247,1,228,228,228,1,222,222,222,2,221,221, + 221,7,210,210,210,1,189,189,189,1,140,140,140,1,8,8,8,1,1,1, + 1,1,0,0,0,4,97,97,97,1,248,248,248,1,255,255,255,1,243,243, + 243,1,174,174,174,1,97,97,97,1,255,255,255,4,117,117,117,1,16,16, + 16,1,0,0,0,12,210,210,210,1,255,255,255,1,247,247,247,1,149,149, + 149,1,43,43,43,1,68,68,68,1,255,255,255,2,112,112,112,1,16,16, + 16,1,0,0,0,19,64,64,64,1,255,255,255,7,250,250,250,1,214,214, + 214,1,106,106,106,1,12,12,12,1,0,0,0,13,255,255,255,3,0,0, + 0,2,255,255,255,3,0,0,0,10,1,1,1,1,109,109,109,1,237,237, + 237,1,255,255,255,14,252,252,252,1,198,198,198,1,18,18,18,1,2,2, + 2,1,0,0,0,4,199,199,199,1,255,255,255,3,248,248,248,1,255,255, + 255,5,117,117,117,1,16,16,16,1,0,0,0,2,16,16,16,1,19,19, + 19,2,46,46,46,1,18,18,18,1,19,19,19,1,13,13,13,1,22,22, + 22,1,0,0,0,1,200,200,200,1,255,255,255,2,198,198,198,1,21,21, + 21,1,65,65,65,1,255,255,255,3,112,112,112,1,16,16,16,1,40,40, + 40,1,46,46,46,2,63,63,63,1,53,53,53,1,2,2,2,1,0,0, + 0,12,64,64,64,1,255,255,255,6,246,246,246,1,199,199,199,1,86,86, + 86,1,5,5,5,1,0,0,0,19,255,255,255,3,0,0,0,11,5,5, + 5,1,77,77,77,1,210,210,210,1,228,228,228,1,239,239,239,1,241,241, + 241,9,248,248,248,1,255,255,255,2,250,250,250,1,152,152,152,1,14,14, + 14,1,1,1,1,1,0,0,0,3,14,14,14,1,214,214,214,1,252,252, + 252,1,255,255,255,8,71,71,71,1,0,0,0,2,76,76,76,1,108,108, + 108,1,118,118,118,1,88,88,88,1,93,93,93,1,79,79,79,1,45,45, + 45,1,49,49,49,1,0,0,0,1,173,173,173,1,255,255,255,2,239,239, + 239,1,127,127,127,1,74,74,74,1,255,255,255,4,112,112,112,1,41,41, + 41,1,61,61,61,1,75,75,75,1,95,95,95,1,51,51,51,1,4,4, + 4,1,0,0,0,12,64,64,64,1,255,255,255,5,242,242,242,1,180,180, + 180,1,66,66,66,1,2,2,2,1,0,0,0,19,255,255,255,3,0,0, + 0,13,18,18,18,1,31,31,31,1,80,80,80,1,113,113,113,1,125,125, + 125,1,128,128,128,8,147,147,147,1,218,218,218,1,254,254,254,1,255,255, + 255,1,220,220,220,1,63,63,63,1,6,6,6,1,0,0,0,4,18,18, + 18,1,178,178,178,1,224,224,224,1,242,242,242,1,255,255,255,5,191,191, + 191,1,140,140,140,1,0,0,0,11,34,34,34,1,235,235,235,1,255,255, + 255,2,253,253,253,1,242,242,242,1,255,255,255,5,112,112,112,1,16,16, + 16,1,0,0,0,2,47,47,47,1,84,84,84,1,94,94,94,1,44,44, + 44,1,87,87,87,1,50,50,50,1,48,48,48,1,0,0,0,7,64,64, + 64,1,255,255,255,4,237,237,237,1,159,159,159,1,47,47,47,1,1,1, + 1,1,0,0,0,20,255,255,255,4,0,0,0,12,119,119,119,1,118,118, + 118,1,117,117,117,1,104,104,104,1,70,70,70,1,12,12,12,8,13,13, + 13,1,47,47,47,1,238,238,238,1,255,255,255,1,233,233,233,1,92,92, + 92,1,8,8,8,1,0,0,0,5,3,3,3,1,61,61,61,1,136,136, + 136,1,255,255,255,4,191,191,191,1,140,140,140,1,0,0,0,12,1,1, + 1,1,109,109,109,1,236,236,236,1,255,255,255,9,64,64,64,1,0,0, + 0,2,14,14,14,1,27,27,27,2,29,29,29,1,12,12,12,1,29,29, + 29,1,36,36,36,1,0,0,0,7,64,64,64,1,255,255,255,3,231,231, + 231,1,139,139,139,1,31,31,31,1,1,1,1,1,0,0,0,21,255,255, + 255,4,0,0,0,14,41,41,41,1,1,1,1,1,61,61,61,1,70,70, + 70,1,58,58,58,1,38,38,38,1,21,21,21,1,68,68,68,1,14,14, + 14,1,0,0,0,3,15,15,15,1,231,231,231,1,255,255,255,1,241,241, + 241,1,117,117,117,1,11,11,11,1,0,0,0,7,65,65,65,1,255,255, + 255,3,191,191,191,1,140,140,140,1,0,0,0,14,5,5,5,1,80,80, + 80,1,208,208,208,1,229,229,229,1,247,247,247,1,255,255,255,5,191,191, + 191,1,143,143,143,1,0,0,0,2,65,65,65,1,104,104,104,1,113,113, + 113,1,107,107,107,1,109,109,109,1,91,91,91,1,74,74,74,1,87,87, + 87,1,0,0,0,6,64,64,64,1,255,255,255,1,252,252,252,1,223,223, + 223,1,119,119,119,1,19,19,19,1,1,1,1,1,0,0,0,42,53,53, + 53,1,62,62,62,1,28,28,28,1,34,34,34,1,18,18,18,1,63,63, + 63,1,22,22,22,1,0,0,0,3,4,4,4,1,226,226,226,1,255,255, + 255,1,241,241,241,1,127,127,127,1,12,12,12,1,0,0,0,7,64,64, + 64,1,255,255,255,2,191,191,191,1,140,140,140,1,0,0,0,16,6,6, + 6,1,30,30,30,1,82,82,82,1,146,146,146,1,255,255,255,4,191,191, + 191,1,144,144,144,1,18,18,18,1,16,16,16,1,42,42,42,1,2,2, + 2,1,0,0,0,1,20,20,20,1,1,1,1,1,0,0,0,10,64,64, + 64,1,246,246,246,1,209,209,209,1,100,100,100,1,9,9,9,1,0,0, + 0,44,65,65,65,1,90,90,90,1,81,81,81,1,93,93,93,1,76,76, + 76,1,84,84,84,1,57,57,57,1,41,41,41,1,92,92,92,1,81,81, + 81,1,14,14,14,1,231,231,231,1,255,255,255,1,244,244,244,1,128,128, + 128,1,12,12,12,1,0,0,0,7,64,64,64,1,255,255,255,1,195,195, + 195,1,140,140,140,1,0,0,0,18,2,2,2,1,7,7,7,1,71,71, + 71,1,255,255,255,3,191,191,191,1,143,143,143,1,40,40,40,1,92,92, + 92,1,79,79,79,1,84,84,84,1,6,6,6,1,0,0,0,13,59,59, + 59,1,124,124,124,1,79,79,79,1,4,4,4,1,0,0,0,43,10,10, + 10,1,3,3,3,1,34,34,34,1,48,48,48,1,49,49,49,1,33,33, + 33,1,34,34,34,1,28,28,28,1,14,14,14,1,0,0,0,1,16,16, + 16,1,17,17,17,1,22,22,22,1,69,69,69,1,151,151,151,1,160,160, + 160,1,115,115,115,1,13,13,13,1,0,0,0,7,16,16,16,1,65,65, + 65,1,145,145,145,1,0,0,0,2,24,24,24,1,48,48,48,2,63,63, + 63,1,0,0,0,15,64,64,64,1,255,255,255,2,191,191,191,1,143,143, + 143,1,0,0,0,21,1,1,1,1,0,0,0,42,112,112,112,2,120,120, + 120,1,41,41,41,1,0,0,0,11,1,1,1,1,12,12,12,2,11,11, + 11,1,1,1,1,1,0,0,0,12,38,38,38,1,54,54,54,1,57,57, + 57,1,58,58,58,1,0,0,0,15,64,64,64,1,255,255,255,1,191,191, + 191,1,143,143,143,1,0,0,0,68,8,8,8,1,0,0,0,47,16,16, + 16,1,67,67,67,1,143,143,143,1,0,0,0,255,0,0,0,56,50,50, + 50,1,127,127,127,1,174,174,174,1,200,200,200,1,201,201,201,1,175,175, + 175,1,130,130,130,1,55,55,55,1,4,4,4,1,1,1,1,1,0,0, + 0,32,255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,56,24,24, + 24,1,187,187,187,1,244,244,244,1,255,255,255,6,246,246,246,1,195,195, + 195,1,37,37,37,1,3,3,3,1,0,0,0,31,255,255,255,3,0,0, + 0,14,255,255,255,3,0,0,0,32,217,217,217,1,220,220,220,2,226,226, + 226,1,0,0,0,4,221,221,221,1,224,224,224,2,229,229,229,1,0,0, + 0,11,104,104,104,1,218,218,218,1,255,255,255,10,231,231,231,1,124,124, + 124,1,9,9,9,1,1,1,1,1,0,0,0,30,255,255,255,3,0,0, + 0,12,255,255,255,3,0,0,0,33,216,216,216,1,255,255,255,2,242,242, + 242,1,140,140,140,1,0,0,0,3,216,216,216,1,255,255,255,2,242,242, + 242,1,140,140,140,1,0,0,0,9,104,104,104,1,240,240,240,1,255,255, + 255,12,246,246,246,1,140,140,140,1,13,13,13,1,1,1,1,1,0,0, + 0,30,255,255,255,3,0,0,0,10,255,255,255,3,0,0,0,34,216,216, + 216,1,255,255,255,2,242,242,242,1,141,141,141,1,0,0,0,3,216,216, + 216,1,255,255,255,2,242,242,242,1,141,141,141,1,0,0,0,8,24,24, + 24,1,218,218,218,1,255,255,255,14,235,235,235,1,83,83,83,1,9,9, + 9,1,0,0,0,31,255,255,255,3,0,0,0,3,255,255,255,2,0,0, + 0,3,255,255,255,3,0,0,0,35,216,216,216,1,255,255,255,2,241,241, + 241,1,141,141,141,1,0,0,0,3,216,216,216,1,255,255,255,2,241,241, + 241,1,141,141,141,1,0,0,0,8,187,187,187,1,255,255,255,16,217,217, + 217,1,37,37,37,1,3,3,3,1,0,0,0,10,45,45,45,1,172,172, + 172,1,197,197,197,1,196,196,196,1,171,171,171,1,44,44,44,1,0,0, + 0,15,255,255,255,12,0,0,0,11,33,33,33,1,3,3,3,1,0,0, + 0,4,23,23,23,1,13,13,13,1,0,0,0,4,9,9,9,1,26,26, + 26,1,1,1,1,1,0,0,0,10,216,216,216,1,255,255,255,2,241,241, + 241,1,142,142,142,1,0,0,0,3,216,216,216,1,255,255,255,2,241,241, + 241,1,142,142,142,1,0,0,0,7,50,50,50,1,244,244,244,1,255,255, + 255,16,248,248,248,1,127,127,127,1,16,16,16,1,1,1,1,1,0,0, + 0,8,115,115,115,1,229,229,229,1,255,255,255,4,238,238,238,1,125,125, + 125,1,0,0,0,15,255,255,255,10,0,0,0,10,54,54,54,1,208,208, + 208,1,179,179,179,1,212,212,212,1,104,104,104,1,2,2,2,1,10,10, + 10,1,190,190,190,1,191,191,191,1,204,204,204,1,162,162,162,1,3,3, + 3,1,0,0,0,1,138,138,138,1,208,208,208,1,186,186,186,1,196,196, + 196,1,32,32,32,1,1,1,1,1,0,0,0,8,216,216,216,1,255,255, + 255,2,241,241,241,1,142,142,142,1,0,0,0,3,216,216,216,1,255,255, + 255,2,241,241,241,1,142,142,142,1,0,0,0,7,127,127,127,1,255,255, + 255,18,187,187,187,1,47,47,47,1,4,4,4,1,0,0,0,7,45,45, + 45,1,229,229,229,1,255,255,255,6,241,241,241,1,95,95,95,1,0,0, + 0,14,255,255,255,10,0,0,0,10,181,181,181,1,109,109,109,1,105,105, + 105,1,106,106,106,1,241,241,241,1,65,65,65,1,111,111,111,1,164,164, + 164,1,97,97,97,1,98,98,98,1,220,220,220,1,129,129,129,1,41,41, + 41,1,226,226,226,1,77,77,77,1,105,105,105,1,173,173,173,1,185,185, + 185,1,19,19,19,1,1,1,1,1,0,0,0,7,216,216,216,1,255,255, + 255,2,242,242,242,1,143,143,143,1,0,0,0,3,216,216,216,1,255,255, + 255,2,242,242,242,1,143,143,143,1,0,0,0,7,174,174,174,1,255,255, + 255,18,213,213,213,1,70,70,70,1,8,8,8,1,0,0,0,7,172,172, + 172,1,255,255,255,8,213,213,213,1,32,32,32,1,0,0,0,13,255,255, + 255,10,0,0,0,10,45,45,45,1,92,92,92,1,49,49,49,1,16,16, + 16,1,236,236,236,1,129,129,129,1,39,39,39,1,70,70,70,1,82,82, + 82,1,7,7,7,1,177,177,177,1,158,158,158,1,51,51,51,1,53,53, + 53,1,111,111,111,1,10,10,10,1,105,105,105,1,191,191,191,1,73,73, + 73,1,3,3,3,1,0,0,0,7,216,216,216,1,255,255,255,2,242,242, + 242,1,143,143,143,1,0,0,0,3,216,216,216,1,255,255,255,2,242,242, + 242,1,143,143,143,1,0,0,0,7,200,200,200,1,255,255,255,18,227,227, + 227,1,92,92,92,1,10,10,10,1,0,0,0,7,197,197,197,1,255,255, + 255,8,228,228,228,1,96,96,96,1,0,0,0,12,255,255,255,12,0,0, + 0,9,1,1,1,1,23,23,23,1,13,13,13,1,186,186,186,1,134,134, + 134,1,119,119,119,1,16,16,16,2,13,13,13,1,124,124,124,1,193,193, + 193,1,96,96,96,1,50,50,50,1,10,10,10,1,19,19,19,1,62,62, + 62,1,224,224,224,1,87,87,87,1,85,85,85,1,3,3,3,1,0,0, + 0,7,216,216,216,1,255,255,255,2,241,241,241,1,144,144,144,1,0,0, + 0,3,216,216,216,1,255,255,255,2,241,241,241,1,144,144,144,1,0,0, + 0,7,201,201,201,1,255,255,255,18,227,227,227,1,112,112,112,1,13,13, + 13,1,0,0,0,7,196,196,196,1,255,255,255,8,228,228,228,1,126,126, + 126,1,0,0,0,12,255,255,255,12,0,0,0,10,1,1,1,1,152,152, + 152,1,149,149,149,1,94,94,94,1,68,68,68,1,3,3,3,1,1,1, + 1,1,80,80,80,1,204,204,204,1,75,75,75,1,97,97,97,1,8,8, + 8,1,1,1,1,1,22,22,22,1,227,227,227,1,78,78,78,1,111,111, + 111,1,25,25,25,1,1,1,1,1,0,0,0,7,216,216,216,1,255,255, + 255,2,241,241,241,1,144,144,144,1,0,0,0,3,216,216,216,1,255,255, + 255,2,241,241,241,1,144,144,144,1,0,0,0,7,175,175,175,1,255,255, + 255,18,215,215,215,1,112,112,112,1,13,13,13,1,0,0,0,7,171,171, + 171,1,255,255,255,8,214,214,214,1,126,126,126,1,0,0,0,13,255,255, + 255,10,0,0,0,12,221,221,221,1,97,97,97,1,76,76,76,1,5,5, + 5,1,0,0,0,2,150,150,150,1,126,126,126,1,102,102,102,1,14,14, + 14,1,0,0,0,2,77,77,77,1,177,177,177,1,114,114,114,1,31,31, + 31,1,2,2,2,1,0,0,0,8,216,216,216,1,255,255,255,2,242,242, + 242,1,145,145,145,1,0,0,0,3,216,216,216,1,255,255,255,2,242,242, + 242,1,145,145,145,1,0,0,0,7,130,130,130,1,255,255,255,18,192,192, + 192,1,92,92,92,1,10,10,10,1,0,0,0,7,44,44,44,1,238,238, + 238,1,255,255,255,6,241,241,241,1,157,157,157,1,96,96,96,1,0,0, + 0,13,255,255,255,10,0,0,0,12,35,35,35,1,112,112,112,1,19,19, + 19,1,1,1,1,1,0,0,0,2,24,24,24,1,85,85,85,1,53,53, + 53,1,2,2,2,1,0,0,0,2,14,14,14,1,59,59,59,1,88,88, + 88,1,4,4,4,1,0,0,0,9,216,216,216,1,255,255,255,2,242,242, + 242,1,145,145,145,1,0,0,0,3,216,216,216,1,255,255,255,2,242,242, + 242,1,145,145,145,1,0,0,0,7,55,55,55,1,246,246,246,1,255,255, + 255,16,248,248,248,1,154,154,154,1,70,70,70,1,8,8,8,1,0,0, + 0,8,125,125,125,1,241,241,241,1,255,255,255,4,241,241,241,1,185,185, + 185,1,139,139,139,1,32,32,32,1,0,0,0,13,255,255,255,10,0,0, + 0,12,248,248,248,1,59,59,59,1,4,4,4,1,0,0,0,3,175,175, + 175,1,121,121,121,1,11,11,11,1,0,0,0,3,102,102,102,1,187,187, + 187,1,18,18,18,1,1,1,1,1,0,0,0,9,216,216,216,1,255,255, + 255,2,242,242,242,1,145,145,145,1,0,0,0,3,216,216,216,1,255,255, + 255,2,242,242,242,1,145,145,145,1,0,0,0,7,4,4,4,1,195,195, + 195,1,255,255,255,16,220,220,220,1,127,127,127,1,47,47,47,1,4,4, + 4,1,0,0,0,9,95,95,95,1,213,213,213,1,228,228,228,2,214,214, + 214,1,157,157,157,1,139,139,139,1,66,66,66,1,0,0,0,13,255,255, + 255,12,0,0,0,11,4,4,4,1,119,119,119,1,24,24,24,1,1,1, + 1,1,0,0,0,2,3,3,3,1,86,86,86,1,57,57,57,1,2,2, + 2,1,0,0,0,2,2,2,2,1,52,52,52,1,91,91,91,1,3,3, + 3,1,0,0,0,9,216,216,216,1,255,255,255,2,241,241,241,1,146,146, + 146,1,0,0,0,3,216,216,216,1,255,255,255,2,241,241,241,1,146,146, + 146,1,0,0,0,7,1,1,1,1,37,37,37,1,231,231,231,1,255,255, + 255,14,237,237,237,1,146,146,146,1,98,98,98,1,16,16,16,1,1,1, + 1,1,0,0,0,10,32,32,32,1,96,96,96,1,126,126,126,2,96,96, + 96,1,32,32,32,1,0,0,0,13,255,255,255,3,0,0,0,3,255,255, + 255,2,0,0,0,3,255,255,255,3,0,0,0,11,4,4,4,1,1,1, + 1,1,0,0,0,4,3,3,3,1,2,2,2,1,0,0,0,4,2,2, + 2,1,3,3,3,1,0,0,0,10,216,216,216,1,255,255,255,2,242,242, + 242,1,146,146,146,1,0,0,0,3,216,216,216,1,255,255,255,2,242,242, + 242,1,146,146,146,1,0,0,0,8,3,3,3,1,124,124,124,1,246,246, + 246,1,255,255,255,12,248,248,248,1,185,185,185,1,119,119,119,1,37,37, + 37,1,3,3,3,1,0,0,0,29,255,255,255,3,0,0,0,10,255,255, + 255,3,0,0,0,34,222,222,222,1,241,241,241,2,242,242,242,1,147,147, + 147,1,0,0,0,3,222,222,222,1,240,240,240,2,241,241,241,1,147,147, + 147,1,0,0,0,9,9,9,9,1,141,141,141,1,235,235,235,1,255,255, + 255,10,237,237,237,1,185,185,185,1,125,125,125,1,65,65,65,1,9,9, + 9,1,0,0,0,29,255,255,255,3,0,0,0,12,255,255,255,3,0,0, + 0,33,6,6,6,1,142,142,142,1,141,141,141,1,140,140,140,2,0,0, + 0,4,140,140,140,4,0,0,0,9,1,1,1,1,13,13,13,1,82,82, + 82,1,217,217,217,1,248,248,248,1,255,255,255,6,248,248,248,1,220,220, + 220,1,146,146,146,1,119,119,119,1,64,64,64,1,13,13,13,1,1,1, + 1,1,0,0,0,28,255,255,255,3,0,0,0,14,255,255,255,3,0,0, + 0,55,1,1,1,1,9,9,9,1,37,37,37,1,127,127,127,1,187,187, + 187,1,212,212,212,1,227,227,227,2,215,215,215,1,192,192,192,1,154,154, + 154,1,127,127,127,1,98,98,98,1,37,37,37,1,9,9,9,1,1,1, + 1,1,0,0,0,29,255,255,255,2,0,0,0,16,255,255,255,2,0,0, + 0,57,3,3,3,1,16,16,16,1,47,47,47,1,70,70,70,1,92,92, + 92,1,112,112,112,2,92,92,92,1,70,70,70,1,47,47,47,1,16,16, + 16,1,3,3,3,1,0,0,0,109,1,1,1,1,4,4,4,1,8,8, + 8,1,10,10,10,1,13,13,13,2,10,10,10,1,8,8,8,1,4,4, + 4,1,1,1,1,1,0,0,0,132,16,16,16,1,64,64,64,1,16,16, + 16,1,0,0,0,26,12,12,12,1,0,0,0,2,12,12,12,1,0,0, + 0,87,64,64,64,1,255,255,255,1,112,112,112,1,16,16,16,1,0,0, + 0,25,70,70,70,1,105,105,105,1,100,100,100,1,104,104,104,1,112,112, + 112,1,0,0,0,86,64,64,64,1,255,255,255,2,112,112,112,1,16,16, + 16,1,0,0,0,26,19,19,19,1,23,23,23,1,0,0,0,87,64,64, + 64,1,255,255,255,3,112,112,112,1,16,16,16,1,0,0,0,1,12,12, + 12,1,0,0,0,2,12,12,12,1,0,0,0,109,64,64,64,1,255,255, + 255,4,112,112,112,1,16,16,16,1,96,96,96,1,114,114,114,1,98,98, + 98,1,100,100,100,1,84,84,84,1,0,0,0,105,32,32,32,1,172,172, + 172,1,200,200,200,1,236,236,236,1,255,255,255,5,112,112,112,1,16,16, + 16,1,0,0,0,1,33,33,33,1,10,10,10,1,26,26,26,1,40,40, + 40,1,44,44,44,1,18,18,18,1,16,16,16,1,50,50,50,1,8,8, + 8,1,0,0,0,3,3,3,3,1,133,133,133,1,184,184,184,1,211,211, + 211,1,224,224,224,1,225,225,225,4,233,233,233,1,71,71,71,1,0,0, + 0,84,91,91,91,1,222,222,222,1,255,255,255,9,64,64,64,1,0,0, + 0,3,80,80,80,1,89,89,89,1,45,45,45,1,42,42,42,1,36,36, + 36,1,82,82,82,1,27,27,27,1,0,0,0,2,26,26,26,1,196,196, + 196,1,253,253,253,1,255,255,255,8,167,167,167,1,1,1,1,1,0,0, + 0,44,255,255,255,2,0,0,0,23,255,255,255,1,0,0,0,12,37,37, + 37,1,227,227,227,1,255,255,255,3,248,248,248,1,255,255,255,5,191,191, + 191,1,147,147,147,1,0,0,0,3,43,43,43,1,47,47,47,1,56,56, + 56,1,77,77,77,1,51,51,51,1,55,55,55,1,31,31,31,1,0,0, + 0,1,3,3,3,1,204,204,204,1,255,255,255,3,249,249,249,1,243,243, + 243,1,242,242,242,2,241,241,241,2,245,245,245,1,168,168,168,1,1,1, + 1,1,0,0,0,1,12,12,12,1,4,4,4,1,17,17,17,1,0,0, + 0,2,25,25,25,1,0,0,0,11,58,58,58,1,175,175,175,1,229,229, + 229,2,175,175,175,1,58,58,58,1,0,0,0,20,255,255,255,2,0,0, + 0,23,255,255,255,1,0,0,0,12,183,183,183,1,255,255,255,2,235,235, + 235,1,192,192,192,1,170,170,170,1,255,255,255,4,191,191,191,1,147,147, + 147,1,0,0,0,4,53,53,53,1,78,78,78,1,90,90,90,1,62,62, + 62,1,65,65,65,1,56,56,56,1,28,28,28,1,0,0,0,1,125,125, + 125,1,251,251,251,1,255,255,255,1,243,243,243,1,204,204,204,1,158,158, + 158,1,145,145,145,1,137,137,137,1,135,135,135,1,134,134,134,1,133,133, + 133,1,131,131,131,1,130,130,130,1,1,1,1,1,0,0,0,1,86,86, + 86,1,99,99,99,1,96,96,96,1,43,43,43,1,70,70,70,1,98,98, + 98,1,34,34,34,1,0,0,0,9,120,120,120,1,253,253,253,1,255,255, + 255,4,254,254,254,1,137,137,137,1,0,0,0,19,255,255,255,2,0,0, + 0,23,255,255,255,1,0,0,0,12,211,211,211,1,255,255,255,2,192,192, + 192,1,112,112,112,1,99,99,99,1,255,255,255,3,191,191,191,1,147,147, + 147,1,0,0,0,1,68,68,68,1,73,73,73,1,78,78,78,1,57,57, + 57,1,0,0,0,8,189,189,189,1,255,255,255,2,216,216,216,1,132,132, + 132,1,66,66,66,1,72,72,72,1,17,17,17,1,1,1,1,5,0,0, + 0,4,1,1,1,1,0,0,0,3,8,8,8,1,0,0,0,8,58,58, + 58,1,253,253,253,1,255,255,255,6,254,254,254,1,109,109,109,1,0,0, + 0,18,255,255,255,2,0,0,0,23,255,255,255,1,0,0,0,11,6,6, + 6,1,225,225,225,1,255,255,255,1,244,244,244,1,146,146,146,1,49,49, + 49,1,68,68,68,1,255,255,255,2,191,191,191,1,147,147,147,1,0,0, + 0,2,30,30,30,1,23,23,23,1,34,34,34,1,32,32,32,1,0,0, + 0,8,209,209,209,1,255,255,255,1,252,252,252,1,174,174,174,1,59,59, + 59,1,64,64,64,1,255,255,255,1,112,112,112,1,16,16,16,1,0,0, + 0,21,175,175,175,1,255,255,255,8,219,219,219,1,32,32,32,1,0,0, + 0,17,255,255,255,2,0,0,0,23,255,255,255,1,0,0,0,12,210,210, + 210,1,255,255,255,2,187,187,187,1,24,24,24,1,65,65,65,1,255,255, + 255,1,191,191,191,1,147,147,147,1,2,2,2,1,0,0,0,14,208,208, + 208,1,255,255,255,1,252,252,252,1,174,174,174,1,17,17,17,1,64,64, + 64,1,255,255,255,2,117,117,117,1,16,16,16,1,0,0,0,20,229,229, + 229,1,255,255,255,8,243,243,243,1,96,96,96,1,0,0,0,17,255,255, + 255,2,0,0,0,23,255,255,255,1,0,0,0,12,181,181,181,1,255,255, + 255,2,233,233,233,1,87,87,87,1,22,22,22,1,65,65,65,1,147,147, + 147,1,0,0,0,16,185,185,185,1,255,255,255,2,215,215,215,1,20,20, + 20,1,64,64,64,1,255,255,255,3,117,117,117,1,16,16,16,1,0,0, + 0,19,229,229,229,1,255,255,255,8,243,243,243,1,126,126,126,1,0,0, + 0,17,255,255,255,2,0,0,0,23,255,255,255,1,0,0,0,12,41,41, + 41,1,235,235,235,1,255,255,255,2,247,247,247,1,228,228,228,1,222,222, + 222,2,221,221,221,7,210,210,210,1,189,189,189,1,140,140,140,1,8,8, + 8,1,1,1,1,1,0,0,0,4,97,97,97,1,248,248,248,1,255,255, + 255,1,243,243,243,1,174,174,174,1,97,97,97,1,255,255,255,4,117,117, + 117,1,16,16,16,1,0,0,0,18,175,175,175,1,255,255,255,8,219,219, + 219,1,126,126,126,1,0,0,0,42,255,255,255,1,0,0,0,12,1,1, + 1,1,109,109,109,1,237,237,237,1,255,255,255,14,252,252,252,1,198,198, + 198,1,18,18,18,1,2,2,2,1,0,0,0,4,199,199,199,1,255,255, + 255,3,248,248,248,1,255,255,255,5,117,117,117,1,16,16,16,1,0,0, + 0,2,16,16,16,1,19,19,19,2,46,46,46,1,18,18,18,1,19,19, + 19,1,13,13,13,1,22,22,22,1,0,0,0,7,58,58,58,1,254,254, + 254,1,255,255,255,6,254,254,254,1,166,166,166,1,96,96,96,1,0,0, + 0,56,5,5,5,1,77,77,77,1,210,210,210,1,228,228,228,1,239,239, + 239,1,241,241,241,9,248,248,248,1,255,255,255,2,250,250,250,1,152,152, + 152,1,14,14,14,1,1,1,1,1,0,0,0,3,14,14,14,1,214,214, + 214,1,252,252,252,1,255,255,255,8,71,71,71,1,0,0,0,2,76,76, + 76,1,108,108,108,1,118,118,118,1,88,88,88,1,93,93,93,1,79,79, + 79,1,45,45,45,1,49,49,49,1,0,0,0,8,137,137,137,1,254,254, + 254,1,255,255,255,4,254,254,254,1,194,194,194,1,139,139,139,1,32,32, + 32,1,0,0,0,17,255,255,255,2,0,0,0,23,255,255,255,1,0,0, + 0,14,18,18,18,1,31,31,31,1,80,80,80,1,113,113,113,1,125,125, + 125,1,128,128,128,8,147,147,147,1,218,218,218,1,254,254,254,1,255,255, + 255,1,220,220,220,1,63,63,63,1,6,6,6,1,0,0,0,4,18,18, + 18,1,178,178,178,1,224,224,224,1,242,242,242,1,255,255,255,5,191,191, + 191,1,140,140,140,1,0,0,0,19,109,109,109,1,219,219,219,1,243,243, + 243,2,219,219,219,1,166,166,166,1,139,139,139,1,66,66,66,1,0,0, + 0,18,255,255,255,2,0,0,0,38,119,119,119,1,118,118,118,1,117,117, + 117,1,104,104,104,1,70,70,70,1,12,12,12,8,13,13,13,1,47,47, + 47,1,238,238,238,1,255,255,255,1,233,233,233,1,92,92,92,1,8,8, + 8,1,0,0,0,5,3,3,3,1,61,61,61,1,136,136,136,1,255,255, + 255,4,191,191,191,1,140,140,140,1,0,0,0,21,32,32,32,1,96,96, + 96,1,126,126,126,2,96,96,96,1,32,32,32,1,0,0,0,61,41,41, + 41,1,1,1,1,1,61,61,61,1,70,70,70,1,58,58,58,1,38,38, + 38,1,21,21,21,1,68,68,68,1,14,14,14,1,0,0,0,3,15,15, + 15,1,231,231,231,1,255,255,255,1,241,241,241,1,117,117,117,1,11,11, + 11,1,0,0,0,7,65,65,65,1,255,255,255,3,191,191,191,1,140,140, + 140,1,0,0,0,91,53,53,53,1,62,62,62,1,28,28,28,1,34,34, + 34,1,18,18,18,1,63,63,63,1,22,22,22,1,0,0,0,3,4,4, + 4,1,226,226,226,1,255,255,255,1,241,241,241,1,127,127,127,1,12,12, + 12,1,0,0,0,7,64,64,64,1,255,255,255,2,191,191,191,1,140,140, + 140,1,0,0,0,92,65,65,65,1,90,90,90,1,81,81,81,1,93,93, + 93,1,76,76,76,1,84,84,84,1,57,57,57,1,41,41,41,1,92,92, + 92,1,81,81,81,1,14,14,14,1,231,231,231,1,255,255,255,1,244,244, + 244,1,128,128,128,1,12,12,12,1,0,0,0,7,64,64,64,1,255,255, + 255,1,191,191,191,1,140,140,140,1,0,0,0,91,10,10,10,1,3,3, + 3,1,34,34,34,1,48,48,48,1,49,49,49,1,33,33,33,1,34,34, + 34,1,28,28,28,1,14,14,14,1,0,0,0,1,16,16,16,1,17,17, + 17,1,22,22,22,1,69,69,69,1,151,151,151,1,160,160,160,1,115,115, + 115,1,13,13,13,1,0,0,0,7,16,16,16,1,65,65,65,1,145,145, + 145,1,0,0,0,2,24,24,24,1,48,48,48,2,63,63,63,1,0,0, + 0,84,112,112,112,2,120,120,120,1,41,41,41,1,0,0,0,11,1,1, + 1,1,12,12,12,2,11,11,11,1,1,1,1,1,0,0,0,12,38,38, + 38,1,54,54,54,1,57,57,57,1,58,58,58,1,0,0,0,87,8,8, + 8,1,0,0,0,172,12,12,12,1,0,0,0,2,12,12,12,1,0,0, + 0,87,8,8,8,1,248,248,248,1,0,0,0,27,70,70,70,1,105,105, + 105,1,100,100,100,1,104,104,104,1,112,112,112,1,0,0,0,15,4,4, + 4,1,76,76,76,1,128,128,128,1,179,179,179,1,230,230,230,2,179,179, + 179,1,128,128,128,1,76,76,76,1,4,4,4,1,0,0,0,61,8,8, + 8,1,255,255,255,2,0,0,0,28,19,19,19,1,23,23,23,1,0,0, + 0,15,41,41,41,1,203,203,203,1,255,255,255,8,218,218,218,1,44,44, + 44,1,0,0,0,37,37,37,37,1,0,0,0,22,8,8,8,1,255,255, + 255,3,0,0,0,3,12,12,12,1,0,0,0,2,12,12,12,1,0,0, + 0,35,1,1,1,1,114,114,114,1,247,247,247,1,255,255,255,10,253,253, + 253,1,137,137,137,1,1,1,1,1,0,0,0,10,255,255,255,4,0,0, + 0,4,255,255,255,4,0,0,0,13,237,237,237,1,91,91,91,1,0,0, + 0,21,8,8,8,1,255,255,255,4,0,0,0,2,96,96,96,1,114,114, + 114,1,98,98,98,1,100,100,100,1,84,84,84,1,0,0,0,34,114,114, + 114,1,255,255,255,14,177,177,177,1,1,1,1,1,0,0,0,9,255,255, + 255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255,255,2,135,135, + 135,1,0,0,0,17,34,34,34,1,159,159,159,1,211,211,211,1,252,252, + 252,1,255,255,255,5,0,0,0,3,33,33,33,1,10,10,10,1,26,26, + 26,1,40,40,40,1,44,44,44,1,18,18,18,1,16,16,16,1,50,50, + 50,1,8,8,8,1,0,0,0,3,7,7,7,1,125,125,125,1,188,188, + 188,1,237,237,237,1,255,255,255,6,16,16,16,1,0,0,0,13,41,41, + 41,1,247,247,247,1,255,255,255,15,137,137,137,1,0,0,0,9,255,255, + 255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255,255,3,180,180, + 180,1,1,1,1,1,0,0,0,14,82,82,82,1,241,241,241,1,255,255, + 255,9,0,0,0,4,80,80,80,1,89,89,89,1,45,45,45,1,42,42, + 42,1,36,36,36,1,82,82,82,1,27,27,27,1,0,0,0,2,40,40, + 40,1,209,209,209,1,255,255,255,10,0,0,0,12,4,4,4,1,203,203, + 203,1,255,255,255,16,253,253,253,1,44,44,44,1,0,0,0,8,255,255, + 255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255,255,4,215,215, + 215,1,10,10,10,1,0,0,0,12,30,30,30,1,244,244,244,1,255,255, + 255,10,248,248,248,1,0,0,0,3,43,43,43,1,47,47,47,1,56,56, + 56,1,77,77,77,1,51,51,51,1,55,55,55,1,31,31,31,1,0,0, + 0,1,5,5,5,1,214,214,214,1,255,255,255,11,0,0,0,2,12,12, + 12,1,4,4,4,1,17,17,17,1,0,0,0,2,25,25,25,1,0,0, + 0,4,76,76,76,1,255,255,255,18,218,218,218,1,4,4,4,1,0,0, + 0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255, + 255,5,237,237,237,1,32,32,32,1,0,0,0,11,158,158,158,1,255,255, + 255,10,248,248,248,1,0,0,0,4,53,53,53,1,78,78,78,1,90,90, + 90,1,62,62,62,1,65,65,65,1,56,56,56,1,28,28,28,1,0,0, + 0,1,110,110,110,1,255,255,255,6,240,240,240,6,0,0,0,2,86,86, + 86,1,99,99,99,1,96,96,96,1,43,43,43,1,70,70,70,1,98,98, + 98,1,34,34,34,1,0,0,0,3,127,127,127,1,255,255,255,19,76,76, + 76,1,0,0,0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0, + 0,12,255,255,255,6,249,249,249,1,65,65,65,1,0,0,0,10,216,216, + 216,1,255,255,255,3,222,222,222,1,75,75,75,1,255,255,255,4,248,248, + 248,1,0,0,0,1,68,68,68,1,73,73,73,1,78,78,78,1,57,57, + 57,1,0,0,0,8,185,185,185,1,255,255,255,3,243,243,243,1,97,97, + 97,1,18,18,18,1,0,0,0,10,1,1,1,1,0,0,0,3,8,8, + 8,1,0,0,0,3,179,179,179,1,255,255,255,19,127,127,127,1,0,0, + 0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255, + 255,7,253,253,253,1,105,105,105,1,0,0,0,8,1,1,1,1,250,250, + 250,1,255,255,255,3,69,69,69,1,8,8,8,1,255,255,255,3,248,248, + 248,1,0,0,0,2,30,30,30,1,23,23,23,1,34,34,34,1,32,32, + 32,1,0,0,0,8,229,229,229,1,255,255,255,3,107,107,107,1,0,0, + 0,1,255,255,255,1,0,0,0,18,230,230,230,1,255,255,255,19,179,179, + 179,1,0,0,0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0, + 0,12,255,255,255,9,150,150,150,1,0,0,0,8,221,221,221,1,255,255, + 255,3,11,11,11,1,8,8,8,1,248,248,248,1,255,255,255,1,252,252, + 252,1,0,0,0,15,229,229,229,1,255,255,255,3,29,29,29,1,0,0, + 0,1,255,255,255,2,16,16,16,1,0,0,0,16,230,230,230,1,255,255, + 255,19,230,230,230,1,0,0,0,7,255,255,255,5,0,0,0,3,255,255, + 255,5,0,0,0,12,255,255,255,9,253,253,253,1,108,108,108,1,0,0, + 0,7,165,165,165,1,255,255,255,3,105,105,105,1,9,9,9,1,8,8, + 8,1,248,248,248,1,0,0,0,16,185,185,185,1,255,255,255,3,35,35, + 35,1,0,0,0,1,255,255,255,3,16,16,16,1,0,0,0,15,179,179, + 179,1,255,255,255,19,230,230,230,1,0,0,0,7,255,255,255,5,0,0, + 0,3,255,255,255,5,0,0,0,12,255,255,255,9,252,252,252,1,108,108, + 108,1,0,0,0,7,37,37,37,1,253,253,253,1,255,255,255,13,237,237, + 237,1,190,190,190,1,138,138,138,1,8,8,8,1,0,0,0,5,105,105, + 105,1,255,255,255,3,185,185,185,1,31,31,31,1,255,255,255,4,16,16, + 16,1,0,0,0,14,127,127,127,1,255,255,255,19,179,179,179,1,0,0, + 0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255, + 255,8,242,242,242,1,73,73,73,1,0,0,0,9,119,119,119,1,255,255, + 255,16,217,217,217,1,10,10,10,1,0,0,0,4,3,3,3,1,226,226, + 226,1,255,255,255,9,16,16,16,1,0,0,0,3,16,16,16,1,19,19, + 19,2,46,46,46,1,18,18,18,1,19,19,19,1,13,13,13,1,22,22, + 22,1,0,0,0,2,76,76,76,1,255,255,255,19,127,127,127,1,0,0, + 0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255, + 255,7,225,225,225,1,45,45,45,1,0,0,0,11,122,122,122,1,252,252, + 252,1,255,255,255,15,209,209,209,1,2,2,2,1,0,0,0,4,38,38, + 38,1,244,244,244,1,255,255,255,9,16,16,16,1,0,0,0,2,76,76, + 76,1,108,108,108,1,118,118,118,1,88,88,88,1,93,93,93,1,79,79, + 79,1,45,45,45,1,49,49,49,1,0,0,0,2,4,4,4,1,218,218, + 218,1,255,255,255,18,76,76,76,1,0,0,0,7,255,255,255,5,0,0, + 0,3,255,255,255,5,0,0,0,12,255,255,255,6,201,201,201,1,24,24, + 24,1,0,0,0,12,12,12,12,1,41,41,41,1,161,161,161,1,214,214, + 214,1,252,252,252,1,255,255,255,13,111,111,111,1,0,0,0,5,33,33, + 33,1,225,225,225,1,255,255,255,8,240,240,240,1,0,0,0,13,44,44, + 44,1,253,253,253,1,255,255,255,16,203,203,203,1,4,4,4,1,0,0, + 0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255, + 255,5,171,171,171,1,9,9,9,1,0,0,0,13,119,119,119,1,117,117, + 117,1,113,113,113,1,98,98,98,1,61,61,61,1,0,0,0,9,72,72, + 72,1,255,255,255,3,169,169,169,1,0,0,0,6,4,4,4,1,111,111, + 111,1,172,172,172,1,255,255,255,5,240,240,240,1,0,0,0,15,137,137, + 137,1,255,255,255,15,247,247,247,1,41,41,41,1,0,0,0,8,255,255, + 255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255,255,4,134,134, + 134,1,1,1,1,1,0,0,0,16,41,41,41,1,1,1,1,1,61,61, + 61,1,70,70,70,1,58,58,58,1,38,38,38,1,21,21,21,1,68,68, + 68,1,14,14,14,1,0,0,0,3,14,14,14,1,255,255,255,3,217,217, + 217,1,0,0,0,9,255,255,255,4,240,240,240,1,0,0,0,16,1,1, + 1,1,177,177,177,1,255,255,255,14,114,114,114,1,0,0,0,9,255,255, + 255,5,0,0,0,3,255,255,255,5,0,0,0,12,237,237,237,1,255,255, + 255,1,249,249,249,1,96,96,96,1,0,0,0,20,53,53,53,1,62,62, + 62,1,28,28,28,1,34,34,34,1,18,18,18,1,63,63,63,1,22,22, + 22,1,0,0,0,3,8,8,8,1,255,255,255,3,242,242,242,1,0,0, + 0,9,255,255,255,3,240,240,240,1,0,0,0,18,1,1,1,1,137,137, + 137,1,253,253,253,1,255,255,255,10,247,247,247,1,114,114,114,1,1,1, + 1,1,0,0,0,10,255,255,255,4,0,0,0,4,255,255,255,4,0,0, + 0,12,37,37,37,1,237,237,237,1,63,63,63,1,0,0,0,21,65,65, + 65,1,90,90,90,1,81,81,81,1,93,93,93,1,76,76,76,1,84,84, + 84,1,57,57,57,1,41,41,41,1,92,92,92,1,81,81,81,1,17,17, + 17,1,255,255,255,3,247,247,247,1,0,0,0,9,255,255,255,2,240,240, + 240,1,0,0,0,21,44,44,44,1,218,218,218,1,255,255,255,8,203,203, + 203,1,41,41,41,1,0,0,0,37,37,37,37,1,0,0,0,20,10,10, + 10,1,3,3,3,1,34,34,34,1,48,48,48,1,49,49,49,1,33,33, + 33,1,34,34,34,1,28,28,28,1,14,14,14,1,0,0,0,1,16,16, + 16,1,17,17,17,1,22,22,22,1,8,8,8,1,255,255,255,2,248,248, + 248,1,0,0,0,9,2,2,2,1,251,251,251,1,0,0,0,2,24,24, + 24,1,48,48,48,2,63,63,63,1,0,0,0,17,4,4,4,1,76,76, + 76,1,128,128,128,1,179,179,179,1,230,230,230,2,179,179,179,1,128,128, + 128,1,76,76,76,1,4,4,4,1,0,0,0,57,112,112,112,2,120,120, + 120,1,41,41,41,1,0,0,0,12,5,5,5,1,0,0,0,15,38,38, + 38,1,54,54,54,1,57,57,57,1,58,58,58,1,0,0,0,87,8,8, + 8,1,0,0,0,43,12,12,12,1,0,0,0,2,12,12,12,1,0,0, + 0,53,12,12,12,1,0,0,0,2,12,12,12,1,0,0,0,11,12,12, + 12,1,0,0,0,2,12,12,12,1,0,0,0,44,70,70,70,1,105,105, + 105,1,100,100,100,1,104,104,104,1,112,112,112,1,0,0,0,23,8,8, + 8,1,248,248,248,1,0,0,0,27,70,70,70,1,105,105,105,1,100,100, + 100,1,104,104,104,1,112,112,112,1,0,0,0,10,70,70,70,1,105,105, + 105,1,100,100,100,1,104,104,104,1,112,112,112,1,0,0,0,45,19,19, + 19,1,23,23,23,2,26,26,26,1,59,59,59,1,11,11,11,1,23,23, + 23,1,40,40,40,1,17,17,17,1,0,0,0,5,5,5,5,1,0,0, + 0,11,8,8,8,1,255,255,255,2,0,0,0,28,19,19,19,1,23,23, + 23,1,0,0,0,13,19,19,19,1,23,23,23,2,26,26,26,1,59,59, + 59,1,11,11,11,1,23,23,23,1,40,40,40,1,17,17,17,1,0,0, + 0,5,61,61,61,1,64,64,64,2,0,0,0,33,65,65,65,1,77,77, + 77,1,73,73,73,1,26,26,26,1,53,53,53,1,71,71,71,1,36,36, + 36,1,0,0,0,4,3,3,3,1,255,255,255,2,248,248,248,1,0,0, + 0,9,8,8,8,1,255,255,255,3,0,0,0,3,12,12,12,1,0,0, + 0,2,12,12,12,1,0,0,0,37,65,65,65,1,77,77,77,1,73,73, + 73,1,26,26,26,1,53,53,53,1,71,71,71,1,36,36,36,1,0,0, + 0,5,230,230,230,1,255,255,255,1,233,233,233,1,12,12,12,1,1,1, + 1,1,0,0,0,31,38,38,38,1,47,47,47,1,53,53,53,1,71,71, + 71,1,54,54,54,1,48,48,48,1,30,30,30,1,42,42,42,1,31,31, + 31,1,77,77,77,1,40,40,40,1,8,8,8,1,255,255,255,3,248,248, + 248,1,0,0,0,8,8,8,8,1,255,255,255,4,0,0,0,2,96,96, + 96,1,114,114,114,1,98,98,98,1,100,100,100,1,84,84,84,1,0,0, + 0,36,38,38,38,1,47,47,47,1,53,53,53,1,71,71,71,1,54,54, + 54,1,48,48,48,1,30,30,30,1,42,42,42,1,31,31,31,1,77,77, + 77,1,40,40,40,1,4,4,4,1,227,227,227,1,255,255,255,1,240,240, + 240,1,116,116,116,1,11,11,11,1,0,0,0,31,47,47,47,1,76,76, + 76,1,87,87,87,1,57,57,57,1,61,61,61,1,46,46,46,1,35,35, + 35,1,36,36,36,1,24,24,24,1,61,61,61,1,22,22,22,1,14,14, + 14,1,255,255,255,3,247,247,247,1,0,0,0,5,34,34,34,1,159,159, + 159,1,211,211,211,1,252,252,252,1,255,255,255,5,0,0,0,3,33,33, + 33,1,10,10,10,1,26,26,26,1,40,40,40,1,44,44,44,1,18,18, + 18,1,16,16,16,1,50,50,50,1,8,8,8,1,0,0,0,3,7,7, + 7,1,125,125,125,1,188,188,188,1,237,237,237,1,255,255,255,6,16,16, + 16,1,0,0,0,16,47,47,47,1,76,76,76,1,87,87,87,1,57,57, + 57,1,61,61,61,1,46,46,46,1,35,35,35,1,36,36,36,1,24,24, + 24,1,61,61,61,1,22,22,22,1,12,12,12,1,229,229,229,1,255,255, + 255,1,241,241,241,1,128,128,128,1,12,12,12,1,0,0,0,27,45,45, + 45,1,70,70,70,1,74,74,74,1,80,80,80,1,0,0,0,11,48,48, + 48,1,255,255,255,3,242,242,242,1,0,0,0,4,82,82,82,1,241,241, + 241,1,255,255,255,9,0,0,0,4,80,80,80,1,89,89,89,1,45,45, + 45,1,42,42,42,1,36,36,36,1,82,82,82,1,27,27,27,1,0,0, + 0,2,40,40,40,1,209,209,209,1,255,255,255,10,0,0,0,12,45,45, + 45,1,70,70,70,1,74,74,74,1,80,80,80,1,0,0,0,11,22,22, + 22,1,232,232,232,1,255,255,255,1,237,237,237,1,122,122,122,1,11,11, + 11,1,0,0,0,27,17,17,17,1,29,29,29,1,31,31,31,1,42,42, + 42,1,0,0,0,10,29,29,29,1,155,155,155,1,255,255,255,3,217,217, + 217,1,0,0,0,3,30,30,30,1,244,244,244,1,255,255,255,10,248,248, + 248,1,0,0,0,3,43,43,43,1,47,47,47,1,56,56,56,1,77,77, + 77,1,51,51,51,1,55,55,55,1,31,31,31,1,0,0,0,1,5,5, + 5,1,214,214,214,1,255,255,255,11,0,0,0,2,12,12,12,1,4,4, + 4,1,17,17,17,1,0,0,0,2,25,25,25,1,0,0,0,4,17,17, + 17,1,29,29,29,1,31,31,31,1,42,42,42,1,0,0,0,10,38,38, + 38,1,184,184,184,1,252,252,252,1,255,255,255,1,226,226,226,1,110,110, + 110,1,10,10,10,1,0,0,0,10,45,45,45,1,172,172,172,1,197,197, + 197,1,196,196,196,1,171,171,171,1,44,44,44,1,0,0,0,12,41,41, + 41,1,161,161,161,1,212,212,212,1,252,252,252,1,255,255,255,14,169,169, + 169,1,0,0,0,3,158,158,158,1,255,255,255,10,248,248,248,1,0,0, + 0,4,53,53,53,1,78,78,78,1,90,90,90,1,62,62,62,1,65,65, + 65,1,56,56,56,1,28,28,28,1,0,0,0,1,110,110,110,1,255,255, + 255,6,240,240,240,6,0,0,0,2,86,86,86,1,99,99,99,1,96,96, + 96,1,43,43,43,1,70,70,70,1,98,98,98,1,34,34,34,1,0,0, + 0,4,66,66,66,1,184,184,184,1,206,206,206,1,223,223,223,1,225,225, + 225,9,239,239,239,1,255,255,255,3,207,207,207,1,89,89,89,1,8,8, + 8,1,0,0,0,9,115,115,115,1,229,229,229,1,255,255,255,4,238,238, + 238,1,125,125,125,1,0,0,0,10,96,96,96,1,246,246,246,1,255,255, + 255,17,111,111,111,1,0,0,0,3,216,216,216,1,255,255,255,3,222,222, + 222,1,75,75,75,1,255,255,255,4,248,248,248,1,0,0,0,1,68,68, + 68,1,73,73,73,1,78,78,78,1,57,57,57,1,0,0,0,8,185,185, + 185,1,255,255,255,3,243,243,243,1,97,97,97,1,18,18,18,1,0,0, + 0,10,1,1,1,1,0,0,0,3,8,8,8,1,0,0,0,3,131,131, + 131,1,233,233,233,1,255,255,255,15,231,231,231,1,135,135,135,1,61,61, + 61,1,5,5,5,1,0,0,0,8,45,45,45,1,229,229,229,1,255,255, + 255,6,241,241,241,1,95,95,95,1,0,0,0,8,37,37,37,1,250,250, + 250,1,255,255,255,17,173,173,173,1,2,2,2,1,0,0,0,2,1,1, + 1,1,250,250,250,1,255,255,255,3,69,69,69,1,8,8,8,1,255,255, + 255,3,248,248,248,1,0,0,0,2,30,30,30,1,23,23,23,1,34,34, + 34,1,32,32,32,1,0,0,0,8,229,229,229,1,255,255,255,3,107,107, + 107,1,0,0,0,1,255,255,255,1,0,0,0,17,42,42,42,1,232,232, + 232,1,255,255,255,2,252,252,252,1,242,242,242,1,241,241,241,4,242,242, + 242,4,243,243,243,1,237,237,237,1,225,225,225,1,203,203,203,1,135,135, + 135,1,88,88,88,1,13,13,13,1,0,0,0,9,172,172,172,1,255,255, + 255,8,213,213,213,1,32,32,32,1,0,0,0,7,165,165,165,1,255,255, + 255,15,237,237,237,1,190,190,190,1,138,138,138,1,8,8,8,1,0,0, + 0,4,221,221,221,1,255,255,255,3,11,11,11,1,8,8,8,1,248,248, + 248,1,255,255,255,1,252,252,252,1,0,0,0,15,229,229,229,1,255,255, + 255,3,29,29,29,1,0,0,0,1,255,255,255,2,16,16,16,1,0,0, + 0,15,176,176,176,1,255,255,255,2,234,234,234,1,170,170,170,1,142,142, + 142,1,161,161,161,1,137,137,137,1,130,130,130,1,131,131,131,1,132,132, + 132,1,133,133,133,2,134,134,134,1,135,135,135,1,128,128,128,1,119,119, + 119,1,98,98,98,1,71,71,71,1,16,16,16,1,1,1,1,1,0,0, + 0,9,197,197,197,1,255,255,255,8,228,228,228,1,96,96,96,1,0,0, + 0,7,221,221,221,1,255,255,255,3,214,214,214,1,69,69,69,1,248,248, + 248,1,0,0,0,17,165,165,165,1,255,255,255,3,105,105,105,1,9,9, + 9,1,8,8,8,1,248,248,248,1,0,0,0,16,185,185,185,1,255,255, + 255,3,35,35,35,1,0,0,0,1,255,255,255,3,16,16,16,1,0,0, + 0,14,199,199,199,1,255,255,255,2,183,183,183,1,108,108,108,1,98,98, + 98,1,255,255,255,1,119,119,119,1,27,27,27,1,12,12,12,7,11,11, + 11,1,9,9,9,1,6,6,6,1,1,1,1,1,0,0,0,10,196,196, + 196,1,255,255,255,8,228,228,228,1,126,126,126,1,0,0,0,6,1,1, + 1,1,250,250,250,1,255,255,255,3,56,56,56,1,8,8,8,1,255,255, + 255,2,0,0,0,16,37,37,37,1,253,253,253,1,255,255,255,13,237,237, + 237,1,190,190,190,1,138,138,138,1,8,8,8,1,0,0,0,5,105,105, + 105,1,255,255,255,3,185,185,185,1,31,31,31,1,255,255,255,4,16,16, + 16,1,0,0,0,13,210,210,210,1,255,255,255,1,247,247,247,1,149,149, + 149,1,43,43,43,1,68,68,68,1,255,255,255,2,112,112,112,1,16,16, + 16,1,0,0,0,20,171,171,171,1,255,255,255,8,214,214,214,1,126,126, + 126,1,0,0,0,7,216,216,216,1,255,255,255,3,11,11,11,1,8,8, + 8,1,255,255,255,3,0,0,0,2,40,40,40,1,46,46,46,2,63,63, + 63,1,53,53,53,1,2,2,2,1,0,0,0,8,119,119,119,1,255,255, + 255,16,217,217,217,1,10,10,10,1,0,0,0,4,3,3,3,1,226,226, + 226,1,255,255,255,9,16,16,16,1,0,0,0,3,16,16,16,1,19,19, + 19,2,46,46,46,1,18,18,18,1,19,19,19,1,13,13,13,1,22,22, + 22,1,0,0,0,1,200,200,200,1,255,255,255,2,198,198,198,1,21,21, + 21,1,65,65,65,1,255,255,255,3,112,112,112,1,16,16,16,1,40,40, + 40,1,46,46,46,2,63,63,63,1,53,53,53,1,2,2,2,1,0,0, + 0,13,44,44,44,1,238,238,238,1,255,255,255,6,241,241,241,1,157,157, + 157,1,96,96,96,1,0,0,0,7,158,158,158,1,255,255,255,3,119,119, + 119,1,18,18,18,1,255,255,255,4,0,0,0,1,27,27,27,1,61,61, + 61,1,75,75,75,1,95,95,95,1,51,51,51,1,4,4,4,1,0,0, + 0,9,122,122,122,1,252,252,252,1,255,255,255,15,209,209,209,1,2,2, + 2,1,0,0,0,4,38,38,38,1,244,244,244,1,255,255,255,9,16,16, + 16,1,0,0,0,2,76,76,76,1,108,108,108,1,118,118,118,1,88,88, + 88,1,93,93,93,1,79,79,79,1,45,45,45,1,49,49,49,1,0,0, + 0,1,173,173,173,1,255,255,255,2,239,239,239,1,127,127,127,1,74,74, + 74,1,255,255,255,4,112,112,112,1,41,41,41,1,61,61,61,1,75,75, + 75,1,95,95,95,1,51,51,51,1,4,4,4,1,0,0,0,14,125,125, + 125,1,241,241,241,1,255,255,255,4,241,241,241,1,185,185,185,1,139,139, + 139,1,32,32,32,1,0,0,0,7,30,30,30,1,251,251,251,1,255,255, + 255,9,0,0,0,4,47,47,47,1,84,84,84,1,94,94,94,1,44,44, + 44,1,87,87,87,1,50,50,50,1,48,48,48,1,0,0,0,4,12,12, + 12,1,41,41,41,1,161,161,161,1,214,214,214,1,252,252,252,1,255,255, + 255,13,111,111,111,1,0,0,0,5,33,33,33,1,225,225,225,1,255,255, + 255,8,240,240,240,1,0,0,0,11,34,34,34,1,235,235,235,1,255,255, + 255,2,253,253,253,1,242,242,242,1,255,255,255,5,112,112,112,1,16,16, + 16,1,0,0,0,2,47,47,47,1,84,84,84,1,94,94,94,1,44,44, + 44,1,87,87,87,1,50,50,50,1,48,48,48,1,0,0,0,10,95,95, + 95,1,213,213,213,1,228,228,228,2,214,214,214,1,157,157,157,1,139,139, + 139,1,66,66,66,1,0,0,0,9,102,102,102,1,254,254,254,1,255,255, + 255,9,0,0,0,3,14,14,14,1,27,27,27,2,29,29,29,1,12,12, + 12,1,29,29,29,1,36,36,36,1,0,0,0,4,119,119,119,1,117,117, + 117,1,113,113,113,1,98,98,98,1,61,61,61,1,0,0,0,9,72,72, + 72,1,255,255,255,3,169,169,169,1,0,0,0,6,4,4,4,1,111,111, + 111,1,172,172,172,1,255,255,255,5,240,240,240,1,0,0,0,12,1,1, + 1,1,109,109,109,1,236,236,236,1,255,255,255,9,64,64,64,1,0,0, + 0,2,14,14,14,1,27,27,27,2,29,29,29,1,12,12,12,1,29,29, + 29,1,36,36,36,1,0,0,0,11,32,32,32,1,96,96,96,1,126,126, + 126,2,96,96,96,1,32,32,32,1,0,0,0,11,105,105,105,1,250,250, + 250,1,255,255,255,8,248,248,248,1,0,0,0,2,65,65,65,1,104,104, + 104,1,113,113,113,1,107,107,107,1,109,109,109,1,91,91,91,1,74,74, + 74,1,87,87,87,1,0,0,0,5,41,41,41,1,1,1,1,1,61,61, + 61,1,70,70,70,1,58,58,58,1,38,38,38,1,21,21,21,1,68,68, + 68,1,14,14,14,1,0,0,0,3,14,14,14,1,255,255,255,3,217,217, + 217,1,0,0,0,9,255,255,255,4,240,240,240,1,0,0,0,14,5,5, + 5,1,80,80,80,1,208,208,208,1,229,229,229,1,247,247,247,1,255,255, + 255,5,191,191,191,1,143,143,143,1,0,0,0,2,65,65,65,1,104,104, + 104,1,113,113,113,1,107,107,107,1,109,109,109,1,91,91,91,1,74,74, + 74,1,87,87,87,1,0,0,0,28,34,34,34,1,159,159,159,1,212,212, + 212,1,255,255,255,5,248,248,248,1,18,18,18,1,16,16,16,1,42,42, + 42,1,2,2,2,1,0,0,0,1,20,20,20,1,1,1,1,1,0,0, + 0,11,53,53,53,1,62,62,62,1,28,28,28,1,34,34,34,1,18,18, + 18,1,63,63,63,1,22,22,22,1,0,0,0,3,8,8,8,1,255,255, + 255,3,242,242,242,1,0,0,0,9,255,255,255,3,240,240,240,1,0,0, + 0,16,6,6,6,1,30,30,30,1,82,82,82,1,146,146,146,1,255,255, + 255,4,191,191,191,1,144,144,144,1,18,18,18,1,16,16,16,1,42,42, + 42,1,2,2,2,1,0,0,0,1,20,20,20,1,1,1,1,1,0,0, + 0,34,8,8,8,1,255,255,255,4,248,248,248,1,40,40,40,1,92,92, + 92,1,79,79,79,1,84,84,84,1,6,6,6,1,0,0,0,14,65,65, + 65,1,90,90,90,1,81,81,81,1,93,93,93,1,76,76,76,1,84,84, + 84,1,57,57,57,1,41,41,41,1,92,92,92,1,81,81,81,1,17,17, + 17,1,255,255,255,3,247,247,247,1,0,0,0,9,255,255,255,2,240,240, + 240,1,0,0,0,18,2,2,2,1,7,7,7,1,71,71,71,1,255,255, + 255,3,191,191,191,1,143,143,143,1,40,40,40,1,92,92,92,1,79,79, + 79,1,84,84,84,1,6,6,6,1,0,0,0,37,8,8,8,1,255,255, + 255,3,248,248,248,1,0,0,0,18,10,10,10,1,3,3,3,1,34,34, + 34,1,48,48,48,1,49,49,49,1,33,33,33,1,34,34,34,1,28,28, + 28,1,14,14,14,1,0,0,0,1,16,16,16,1,17,17,17,1,22,22, + 22,1,8,8,8,1,255,255,255,2,248,248,248,1,0,0,0,9,2,2, + 2,1,251,251,251,1,0,0,0,2,24,24,24,1,48,48,48,2,63,63, + 63,1,0,0,0,15,64,64,64,1,255,255,255,2,191,191,191,1,143,143, + 143,1,0,0,0,43,8,8,8,1,248,248,248,1,255,255,255,1,248,248, + 248,1,0,0,0,17,112,112,112,2,120,120,120,1,41,41,41,1,0,0, + 0,12,5,5,5,1,0,0,0,15,38,38,38,1,54,54,54,1,57,57, + 57,1,58,58,58,1,0,0,0,15,64,64,64,1,255,255,255,1,191,191, + 191,1,143,143,143,1,0,0,0,45,8,8,8,1,248,248,248,1,0,0, + 0,21,8,8,8,1,0,0,0,47,16,16,16,1,67,67,67,1,143,143, + 143,1,0,0,0,39,0,0,7,116,97,99,116,105,111,110,14,115,101,108, + 101,99,116,101,100,105,116,112,97,103,101,7,99,97,112,116,105,111,110,6, + 17,83,101,108,101,99,116,32,38,69,100,105,116,32,80,97,103,101,7,111, + 112,116,105,111,110,115,11,17,97,111,95,103,108,111,98,97,108,115,104,111, + 114,116,99,117,116,0,9,111,110,101,120,101,99,117,116,101,7,23,115,101, + 108,101,99,116,101,100,105,116,112,97,103,101,111,110,101,120,101,99,117,116, + 101,4,108,101,102,116,3,24,1,3,116,111,112,2,120,2,115,99,1,2, + 1,3,69,64,0,0,0,7,116,97,99,116,105,111,110,6,105,110,100,101, + 110,116,7,99,97,112,116,105,111,110,6,7,38,73,110,100,101,110,116,9, + 111,110,101,120,101,99,117,116,101,7,15,105,110,100,101,110,116,111,110,101, + 120,101,99,117,116,101,4,108,101,102,116,3,24,1,3,116,111,112,3,136, + 0,2,115,99,1,2,1,3,73,64,0,0,0,7,116,97,99,116,105,111, + 110,8,117,110,105,110,100,101,110,116,7,99,97,112,116,105,111,110,6,9, + 85,38,110,105,110,100,101,110,116,9,111,110,101,120,101,99,117,116,101,7, + 16,117,110,105,100,101,110,116,111,110,101,120,101,99,117,116,101,4,108,101, + 102,116,3,24,1,3,116,111,112,3,152,0,2,115,99,1,2,1,3,85, + 64,0,0,0,7,116,97,99,116,105,111,110,14,116,111,103,103,108,101,102, + 111,114,109,117,110,105,116,7,99,97,112,116,105,111,110,6,17,84,111,103, + 103,108,101,32,70,111,114,109,47,38,85,110,105,116,9,111,110,101,120,101, + 99,117,116,101,7,23,116,111,103,103,108,101,102,111,114,109,117,110,105,116, + 111,110,101,120,101,99,117,116,101,4,108,101,102,116,3,152,0,3,116,111, + 112,2,104,2,115,99,1,2,1,3,59,1,0,0,0,7,116,97,99,116, + 105,111,110,5,110,101,120,116,105,9,105,109,97,103,101,108,105,115,116,7, + 11,98,117,116,116,111,110,105,99,111,110,115,7,99,97,112,116,105,111,110, + 6,16,78,101,120,116,32,73,110,115,116,114,117,99,116,105,111,110,7,105, + 109,97,103,101,110,114,2,13,15,105,109,97,103,101,110,114,100,105,115,97, + 98,108,101,100,2,19,9,111,110,101,120,101,99,117,116,101,7,17,110,101, + 120,116,105,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116, + 2,80,3,116,111,112,3,208,0,2,115,99,1,2,1,3,55,97,0,0, + 0,7,116,97,99,116,105,111,110,5,115,116,101,112,105,9,105,109,97,103, + 101,108,105,115,116,7,11,98,117,116,116,111,110,105,99,111,110,115,7,99, + 97,112,116,105,111,110,6,16,83,116,101,112,32,73,110,115,116,114,117,99, + 116,105,111,110,7,105,109,97,103,101,110,114,2,12,15,105,109,97,103,101, + 110,114,100,105,115,97,98,108,101,100,2,21,9,111,110,101,120,101,99,117, + 116,101,7,17,115,116,101,112,105,97,99,116,111,110,101,120,101,99,117,116, + 101,4,108,101,102,116,2,80,3,116,111,112,3,224,0,2,115,99,1,2, + 1,3,54,97,0,0,0,7,116,97,99,116,105,111,110,13,98,108,117,101, + 100,111,116,115,111,110,97,99,116,9,105,109,97,103,101,108,105,115,116,7, + 11,98,117,116,116,111,110,105,99,111,110,115,7,99,97,112,116,105,111,110, + 6,17,69,120,101,99,32,76,105,110,101,32,72,105,110,116,32,111,110,5, + 115,116,97,116,101,11,10,97,115,95,99,104,101,99,107,101,100,0,7,105, + 109,97,103,101,110,114,2,14,4,104,105,110,116,6,28,69,120,101,99,117, + 116,97,98,108,101,32,108,105,110,101,115,32,104,105,110,116,32,111,110,47, + 111,102,102,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,8,111,110,99, + 104,97,110,103,101,7,18,98,108,117,101,100,111,116,115,111,110,111,110,99, + 104,97,110,103,101,4,108,101,102,116,3,152,0,3,116,111,112,3,13,1, + 0,0,7,116,97,99,116,105,111,110,7,114,101,112,108,97,99,101,7,99, + 97,112,116,105,111,110,6,16,70,105,110,100,32,38,38,32,38,82,101,112, + 108,97,99,101,9,111,110,101,120,101,99,117,116,101,7,19,114,101,112,108, + 97,99,101,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116, + 3,208,0,3,116,111,112,2,16,2,115,99,1,2,1,3,82,64,0,0, + 0,7,116,97,99,116,105,111,110,5,112,114,105,110,116,7,99,97,112,116, + 105,111,110,6,6,38,80,114,105,110,116,9,111,110,101,120,101,99,117,116, + 101,7,17,112,114,105,110,116,97,99,116,111,110,101,120,101,99,117,116,101, + 4,108,101,102,116,2,8,3,116,111,112,2,100,0,0,7,116,97,99,116, + 105,111,110,12,100,101,116,97,99,104,116,97,114,103,101,116,7,99,97,112, + 116,105,111,110,6,6,68,101,116,97,99,104,9,111,110,101,120,101,99,117, + 116,101,7,14,111,110,100,101,116,97,99,104,116,97,114,103,101,116,4,108, + 101,102,116,2,8,3,116,111,112,3,136,0,0,0,7,116,97,99,116,105, + 111,110,13,97,116,116,97,99,104,112,114,111,99,101,115,115,7,99,97,112, + 116,105,111,110,6,14,65,116,116,97,99,104,32,80,114,111,99,101,115,115, + 9,111,110,101,120,101,99,117,116,101,7,15,111,110,97,116,116,97,99,104, + 112,114,111,99,101,115,115,4,108,101,102,116,2,8,3,116,111,112,3,152, + 0,0,0,7,116,97,99,116,105,111,110,9,108,111,119,101,114,99,97,115, + 101,7,99,97,112,116,105,111,110,6,10,38,76,111,119,101,114,99,97,115, + 101,9,111,110,101,120,101,99,117,116,101,7,16,108,111,119,101,114,99,97, + 115,101,101,120,101,99,117,116,101,8,111,110,117,112,100,97,116,101,7,14, + 101,110,97,98,108,101,111,110,115,101,108,101,99,116,4,108,101,102,116,3, + 104,1,3,116,111,112,3,136,0,0,0,7,116,97,99,116,105,111,110,9, + 117,112,112,101,114,99,97,115,101,7,99,97,112,116,105,111,110,6,10,38, + 85,112,112,101,114,99,97,115,101,9,111,110,101,120,101,99,117,116,101,7, + 16,117,112,112,101,114,99,97,115,101,101,120,101,99,117,116,101,8,111,110, + 117,112,100,97,116,101,7,14,101,110,97,98,108,101,111,110,115,101,108,101, + 99,116,4,108,101,102,116,3,104,1,3,116,111,112,3,152,0,0,0,19, + 116,115,104,111,114,116,99,117,116,99,111,110,116,114,111,108,108,101,114,9, + 115,104,111,114,116,99,117,116,115,13,97,99,116,105,111,110,115,46,99,111, + 117,110,116,2,98,13,97,99,116,105,111,110,115,46,105,116,101,109,115,14, + 1,8,100,105,115,112,110,97,109,101,6,4,70,105,108,101,0,1,6,97, + 99,116,105,111,110,7,10,111,112,101,110,115,111,117,114,99,101,8,100,105, + 115,112,110,97,109,101,6,4,79,112,101,110,2,115,99,1,2,1,3,79, + 64,0,0,1,6,97,99,116,105,111,110,7,4,115,97,118,101,8,100,105, + 115,112,110,97,109,101,6,4,83,97,118,101,2,115,99,1,2,1,3,83, + 64,0,0,1,6,97,99,116,105,111,110,7,7,115,97,118,101,97,108,108, + 8,100,105,115,112,110,97,109,101,6,8,83,97,118,101,32,97,108,108,0, + 1,6,97,99,116,105,111,110,7,6,115,97,118,101,97,115,8,100,105,115, + 112,110,97,109,101,6,7,83,97,118,101,32,97,115,0,1,6,97,99,116, + 105,111,110,7,5,99,108,111,115,101,8,100,105,115,112,110,97,109,101,6, + 5,67,108,111,115,101,2,115,99,1,2,1,3,51,65,0,0,1,6,97, + 99,116,105,111,110,7,8,99,108,111,115,101,97,108,108,8,100,105,115,112, + 110,97,109,101,6,9,67,108,111,115,101,32,97,108,108,0,1,6,97,99, + 116,105,111,110,7,5,112,114,105,110,116,8,100,105,115,112,110,97,109,101, + 6,5,80,114,105,110,116,0,1,8,100,105,115,112,110,97,109,101,6,6, + 83,101,97,114,99,104,0,1,6,97,99,116,105,111,110,7,4,108,105,110, + 101,8,100,105,115,112,110,97,109,101,6,4,76,105,110,101,2,115,99,1, + 2,1,3,76,64,0,0,1,6,97,99,116,105,111,110,7,4,102,105,110, + 100,8,100,105,115,112,110,97,109,101,6,4,70,105,110,100,2,115,99,1, + 2,1,3,70,64,0,0,1,6,97,99,116,105,111,110,7,10,114,101,112, + 101,97,116,102,105,110,100,8,100,105,115,112,110,97,109,101,6,12,83,101, + 97,114,99,104,32,97,103,97,105,110,2,115,99,1,2,1,3,50,1,0, + 0,1,6,97,99,116,105,111,110,7,8,102,105,110,100,98,97,99,107,8, + 100,105,115,112,110,97,109,101,6,11,83,101,97,114,99,104,32,98,97,99, + 107,2,115,99,1,2,1,3,50,33,0,0,1,6,97,99,116,105,111,110, + 7,7,114,101,112,108,97,99,101,8,100,105,115,112,110,97,109,101,6,16, + 70,105,110,100,32,97,110,100,32,114,101,112,108,97,99,101,2,115,99,1, + 2,1,3,82,64,0,0,1,6,97,99,116,105,111,110,7,10,102,105,110, + 100,105,110,102,105,108,101,8,100,105,115,112,110,97,109,101,6,12,70,105, + 110,100,32,105,110,32,70,105,108,101,2,115,99,1,2,1,3,70,96,0, + 0,1,8,100,105,115,112,110,97,109,101,6,4,69,100,105,116,0,1,6, + 97,99,116,105,111,110,7,14,115,101,108,101,99,116,101,100,105,116,112,97, + 103,101,8,100,105,115,112,110,97,109,101,6,15,83,101,108,101,99,116,32, + 69,100,105,116,112,97,103,101,2,115,99,1,2,1,3,69,64,0,0,1, + 6,97,99,116,105,111,110,7,8,99,111,112,121,119,111,114,100,8,100,105, + 115,112,110,97,109,101,6,19,67,111,112,121,32,87,111,114,100,32,97,116, + 32,67,117,114,115,111,114,2,115,99,1,2,1,3,87,96,0,0,1,6, + 97,99,116,105,111,110,7,6,105,110,100,101,110,116,8,100,105,115,112,110, + 97,109,101,6,6,73,110,100,101,110,116,2,115,99,1,2,1,3,73,64, + 0,0,1,6,97,99,116,105,111,110,7,8,117,110,105,110,100,101,110,116, + 8,100,105,115,112,110,97,109,101,6,8,85,110,105,110,100,101,110,116,2, + 115,99,1,2,1,3,85,64,0,0,1,6,97,99,116,105,111,110,7,7, + 99,111,109,109,101,110,116,8,100,105,115,112,110,97,109,101,6,17,67,111, + 109,109,101,110,116,32,83,101,108,101,99,116,105,111,110,2,115,99,1,2, + 2,3,75,64,2,67,0,0,1,6,97,99,116,105,111,110,7,9,117,110, + 99,111,109,109,101,110,116,8,100,105,115,112,110,97,109,101,6,19,85,110, + 99,111,109,109,101,110,116,32,83,101,108,101,99,116,105,111,110,2,115,99, + 1,2,2,3,75,64,2,85,0,0,1,6,97,99,116,105,111,110,7,9, + 108,111,119,101,114,99,97,115,101,8,100,105,115,112,110,97,109,101,6,9, + 76,111,119,101,114,99,97,115,101,0,1,6,97,99,116,105,111,110,7,9, + 117,112,112,101,114,99,97,115,101,8,100,105,115,112,110,97,109,101,6,9, + 85,112,112,101,114,99,97,115,101,0,1,6,97,99,116,105,111,110,7,12, + 99,111,112,121,108,97,116,101,120,97,99,116,8,100,105,115,112,110,97,109, + 101,6,10,67,111,112,121,32,76,97,84,101,88,2,115,99,1,2,2,3, + 75,64,2,76,0,0,1,6,97,99,116,105,111,110,7,25,115,111,117,114, + 99,101,102,111,46,99,111,109,112,108,101,116,101,99,108,97,115,115,97,99, + 116,8,100,105,115,112,110,97,109,101,6,14,67,111,109,112,108,101,116,101, + 32,67,108,97,115,115,2,115,99,1,2,1,3,65,96,0,0,1,6,97, + 99,116,105,111,110,7,11,105,110,115,116,101,109,112,108,97,116,101,8,100, + 105,115,112,110,97,109,101,6,15,73,110,115,101,114,116,32,84,101,109,112, + 108,97,116,101,2,115,99,1,2,1,3,84,64,0,0,1,6,97,99,116, + 105,111,110,7,21,115,111,117,114,99,101,102,111,46,110,97,118,105,103,98, + 97,99,107,97,99,116,8,100,105,115,112,110,97,109,101,6,13,78,97,118, + 105,103,97,116,101,32,66,97,99,107,2,115,99,1,2,1,3,72,64,0, + 0,1,6,97,99,116,105,111,110,7,24,115,111,117,114,99,101,102,111,46, + 110,97,118,105,103,102,111,114,119,97,114,100,97,99,116,8,100,105,115,112, + 110,97,109,101,6,16,78,97,118,105,103,97,116,101,32,70,111,114,119,97, + 114,100,2,115,99,1,2,1,3,72,96,0,0,1,8,100,105,115,112,110, + 97,109,101,6,12,83,101,116,32,66,111,111,107,109,97,114,107,0,1,6, + 97,99,116,105,111,110,7,6,115,101,116,98,109,48,8,100,105,115,112,110, + 97,109,101,6,14,83,101,116,32,66,111,111,107,109,97,114,107,32,48,2, + 115,99,1,2,1,3,48,96,0,0,1,6,97,99,116,105,111,110,7,6, + 115,101,116,98,109,49,8,100,105,115,112,110,97,109,101,6,14,83,101,116, + 32,66,111,111,107,109,97,114,107,32,49,2,115,99,1,2,1,3,49,96, + 0,0,1,6,97,99,116,105,111,110,7,6,115,101,116,98,109,50,8,100, + 105,115,112,110,97,109,101,6,14,83,101,116,32,66,111,111,107,109,97,114, + 107,32,50,2,115,99,1,2,1,3,50,96,0,0,1,6,97,99,116,105, + 111,110,7,6,115,101,116,98,109,51,8,100,105,115,112,110,97,109,101,6, + 14,83,101,116,32,66,111,111,107,109,97,114,107,32,51,2,115,99,1,2, + 1,3,51,96,0,0,1,6,97,99,116,105,111,110,7,6,115,101,116,98, + 109,52,8,100,105,115,112,110,97,109,101,6,14,83,101,116,32,66,111,111, + 107,109,97,114,107,32,52,2,115,99,1,2,1,3,52,96,0,0,1,6, + 97,99,116,105,111,110,7,6,115,101,116,98,109,53,8,100,105,115,112,110, + 97,109,101,6,14,83,101,116,32,66,111,111,107,109,97,114,107,32,53,2, + 115,99,1,2,1,3,53,96,0,0,1,6,97,99,116,105,111,110,7,6, + 115,101,116,98,109,54,8,100,105,115,112,110,97,109,101,6,14,83,101,116, + 32,66,111,111,107,109,97,114,107,32,54,2,115,99,1,2,1,3,54,96, + 0,0,1,6,97,99,116,105,111,110,7,6,115,101,116,98,109,55,8,100, + 105,115,112,110,97,109,101,6,14,83,101,116,32,66,111,111,107,109,97,114, + 107,32,55,2,115,99,1,2,1,3,55,96,0,0,1,6,97,99,116,105, + 111,110,7,6,115,101,116,98,109,56,8,100,105,115,112,110,97,109,101,6, + 14,83,101,116,32,66,111,111,107,109,97,114,107,32,56,2,115,99,1,2, + 1,3,56,96,0,0,1,6,97,99,116,105,111,110,7,6,115,101,116,98, + 109,57,8,100,105,115,112,110,97,109,101,6,14,83,101,116,32,66,111,111, + 107,109,97,114,107,32,57,2,115,99,1,2,1,3,57,96,0,0,1,6, + 97,99,116,105,111,110,7,9,115,101,116,98,109,110,111,110,101,8,100,105, + 115,112,110,97,109,101,6,14,67,108,101,97,114,32,66,111,111,107,109,97, + 114,107,0,1,8,100,105,115,112,110,97,109,101,6,13,70,105,110,100,32, + 66,111,111,107,109,97,114,107,0,1,6,97,99,116,105,111,110,7,7,102, + 105,110,100,98,109,48,8,100,105,115,112,110,97,109,101,6,15,70,105,110, + 100,32,66,111,111,107,109,97,114,107,32,48,2,115,99,1,2,1,3,48, + 64,0,0,1,6,97,99,116,105,111,110,7,7,102,105,110,100,98,109,49, + 8,100,105,115,112,110,97,109,101,6,15,70,105,110,100,32,66,111,111,107, + 109,97,114,107,32,49,2,115,99,1,2,1,3,49,64,0,0,1,6,97, + 99,116,105,111,110,7,7,102,105,110,100,98,109,50,8,100,105,115,112,110, + 97,109,101,6,15,70,105,110,100,32,66,111,111,107,109,97,114,107,32,50, + 2,115,99,1,2,1,3,50,64,0,0,1,6,97,99,116,105,111,110,7, + 7,102,105,110,100,98,109,51,8,100,105,115,112,110,97,109,101,6,15,70, + 105,110,100,32,66,111,111,107,109,97,114,107,32,51,2,115,99,1,2,1, + 3,51,64,0,0,1,6,97,99,116,105,111,110,7,7,102,105,110,100,98, + 109,52,8,100,105,115,112,110,97,109,101,6,15,70,105,110,100,32,66,111, + 111,107,109,97,114,107,32,52,2,115,99,1,2,1,3,52,64,0,0,1, + 6,97,99,116,105,111,110,7,7,102,105,110,100,98,109,53,8,100,105,115, + 112,110,97,109,101,6,15,70,105,110,100,32,66,111,111,107,109,97,114,107, + 32,53,2,115,99,1,2,1,3,53,64,0,0,1,6,97,99,116,105,111, + 110,7,7,102,105,110,100,98,109,54,8,100,105,115,112,110,97,109,101,6, + 15,70,105,110,100,32,66,111,111,107,109,97,114,107,32,54,2,115,99,1, + 2,1,3,54,64,0,0,1,6,97,99,116,105,111,110,7,7,102,105,110, + 100,98,109,55,8,100,105,115,112,110,97,109,101,6,15,70,105,110,100,32, + 66,111,111,107,109,97,114,107,32,55,2,115,99,1,2,1,3,55,64,0, + 0,1,6,97,99,116,105,111,110,7,7,102,105,110,100,98,109,56,8,100, + 105,115,112,110,97,109,101,6,15,70,105,110,100,32,66,111,111,107,109,97, + 114,107,32,56,2,115,99,1,2,1,3,56,64,0,0,1,6,97,99,116, + 105,111,110,7,7,102,105,110,100,98,109,57,8,100,105,115,112,110,97,109, + 101,6,15,70,105,110,100,32,66,111,111,107,109,97,114,107,32,57,2,115, + 99,1,2,1,3,57,64,0,0,1,8,100,105,115,112,110,97,109,101,6, + 6,84,97,114,103,101,116,0,1,6,97,99,116,105,111,110,7,13,97,116, + 116,97,99,104,112,114,111,99,101,115,115,8,100,105,115,112,110,97,109,101, + 6,14,65,116,116,97,99,104,32,80,114,111,99,101,115,115,0,1,6,97, + 99,116,105,111,110,7,12,100,101,116,97,99,104,116,97,114,103,101,116,8, + 100,105,115,112,110,97,109,101,6,13,68,101,116,97,99,104,32,84,97,114, + 103,101,116,0,1,6,97,99,116,105,111,110,7,8,99,111,110,116,105,110, + 117,101,8,100,105,115,112,110,97,109,101,6,8,67,111,110,116,105,110,117, + 101,2,115,99,1,2,1,3,56,1,0,0,1,6,97,99,116,105,111,110, + 7,5,114,101,115,101,116,8,100,105,115,112,110,97,109,101,6,5,82,101, + 115,101,116,0,1,6,97,99,116,105,111,110,7,9,105,110,116,101,114,114, + 117,112,116,8,100,105,115,112,110,97,109,101,6,9,73,110,116,101,114,114, + 117,112,116,0,1,6,97,99,116,105,111,110,7,4,110,101,120,116,8,100, + 105,115,112,110,97,109,101,6,4,78,101,120,116,2,115,99,1,2,1,3, + 55,1,0,0,1,6,97,99,116,105,111,110,7,5,110,101,120,116,105,8, + 100,105,115,112,110,97,109,101,6,16,78,101,120,116,32,73,110,115,116,114, + 117,99,116,105,111,110,2,115,99,1,2,1,3,55,97,0,0,1,6,97, + 99,116,105,111,110,7,4,115,116,101,112,8,100,105,115,112,110,97,109,101, + 6,4,83,116,101,112,2,115,99,1,2,1,3,54,1,0,0,1,6,97, + 99,116,105,111,110,7,5,115,116,101,112,105,8,100,105,115,112,110,97,109, + 101,6,16,83,116,101,112,32,73,110,115,116,114,117,99,116,105,111,110,2, + 115,99,1,2,1,3,54,97,0,0,1,6,97,99,116,105,111,110,7,6, + 102,105,110,105,115,104,8,100,105,115,112,110,97,109,101,6,6,70,105,110, + 105,115,104,2,115,99,1,2,1,3,54,33,0,0,1,6,97,99,116,105, + 111,110,7,10,98,107,112,116,115,111,110,97,99,116,8,100,105,115,112,110, + 97,109,101,6,18,66,114,101,97,107,112,111,105,110,116,115,32,111,110,47, + 111,102,102,2,115,99,1,2,1,3,66,64,0,0,1,6,97,99,116,105, + 111,110,7,10,116,111,103,103,108,101,98,107,112,116,8,100,105,115,112,110, + 97,109,101,6,17,84,111,103,103,108,101,32,66,114,101,97,107,112,111,105, + 110,116,2,115,99,1,2,1,3,52,1,0,0,1,6,97,99,116,105,111, + 110,7,16,116,111,103,103,108,101,98,107,112,116,101,110,97,98,108,101,8, + 100,105,115,112,110,97,109,101,6,25,84,111,103,103,108,101,32,66,114,101, + 97,107,112,111,105,110,116,32,101,110,97,98,108,101,100,2,115,99,1,2, + 1,3,52,33,0,0,1,6,97,99,116,105,111,110,7,12,119,97,116,99, + 104,101,115,111,110,97,99,116,8,100,105,115,112,110,97,109,101,6,14,87, + 97,116,99,104,101,115,32,111,110,47,111,102,102,2,115,99,1,2,1,3, + 87,64,0,0,1,6,97,99,116,105,111,110,7,13,98,108,117,101,100,111, + 116,115,111,110,97,99,116,8,100,105,115,112,110,97,109,101,6,22,69,120, + 101,99,32,76,105,110,101,32,72,105,110,116,115,32,111,110,47,111,102,102, + 0,1,8,100,105,115,112,110,97,109,101,6,4,86,105,101,119,0,1,6, + 97,99,116,105,111,110,7,15,116,111,103,103,108,101,105,110,115,112,101,99, + 116,111,114,8,100,105,115,112,110,97,109,101,6,28,84,111,103,103,108,101, + 32,70,111,114,109,47,79,98,106,101,99,116,32,73,110,115,112,101,99,116, + 111,114,2,115,99,1,2,1,3,58,1,0,0,1,6,97,99,116,105,111, + 110,7,14,116,111,103,103,108,101,102,111,114,109,117,110,105,116,8,100,105, + 115,112,110,97,109,101,6,16,84,111,103,103,108,101,32,70,111,114,109,47, + 85,110,105,116,2,115,99,1,2,1,3,59,1,0,0,1,8,100,105,115, + 112,110,97,109,101,6,7,80,114,111,106,101,99,116,0,1,6,97,99,116, + 105,111,110,7,7,109,97,107,101,97,99,116,8,100,105,115,112,110,97,109, + 101,6,4,77,97,107,101,0,1,6,97,99,116,105,111,110,7,8,98,117, + 105,108,100,97,99,116,8,100,105,115,112,110,97,109,101,6,5,66,117,105, + 108,100,0,1,6,97,99,116,105,111,110,7,8,109,97,107,101,49,97,99, + 116,8,100,105,115,112,110,97,109,101,6,6,77,97,107,101,32,49,0,1, + 6,97,99,116,105,111,110,7,8,109,97,107,101,50,97,99,116,8,100,105, + 115,112,110,97,109,101,6,6,77,97,107,101,32,50,0,1,6,97,99,116, + 105,111,110,7,8,109,97,107,101,51,97,99,116,8,100,105,115,112,110,97, + 109,101,6,6,77,97,107,101,32,51,0,1,6,97,99,116,105,111,110,7, + 8,109,97,107,101,52,97,99,116,8,100,105,115,112,110,97,109,101,6,6, + 77,97,107,101,32,52,0,1,6,97,99,116,105,111,110,7,12,97,98,111, + 114,116,109,97,107,101,97,99,116,8,100,105,115,112,110,97,109,101,6,10, + 65,98,111,114,116,32,77,97,107,101,0,1,6,97,99,116,105,111,110,7, + 17,112,114,111,106,101,99,116,111,112,116,105,111,110,115,97,99,116,8,100, + 105,115,112,110,97,109,101,6,7,79,112,116,105,111,110,115,0,1,6,97, + 99,116,105,111,110,7,14,112,114,111,106,101,99,116,111,112,101,110,97,99, + 116,8,100,105,115,112,110,97,109,101,6,4,79,112,101,110,0,1,6,97, + 99,116,105,111,110,7,14,112,114,111,106,101,99,116,115,97,118,101,97,99, + 116,8,100,105,115,112,110,97,109,101,6,4,83,97,118,101,0,1,6,97, + 99,116,105,111,110,7,14,112,114,111,106,101,99,116,116,114,101,101,97,99, + 116,8,100,105,115,112,110,97,109,101,6,4,84,114,101,101,0,1,6,97, + 99,116,105,111,110,7,16,112,114,111,106,101,99,116,115,111,117,114,99,101, + 97,99,116,8,100,105,115,112,110,97,109,101,6,6,83,111,117,114,99,101, + 0,1,6,97,99,116,105,111,110,7,15,112,114,111,106,101,99,116,99,108, + 111,115,101,97,99,116,8,100,105,115,112,110,97,109,101,6,5,67,108,111, + 115,101,0,1,8,100,105,115,112,110,97,109,101,6,4,72,101,108,112,0, + 1,6,97,99,116,105,111,110,7,7,104,101,108,112,97,99,116,8,100,105, + 115,112,110,97,109,101,6,4,72,101,108,112,2,115,99,1,2,1,3,48, + 1,0,0,1,8,100,105,115,112,110,97,109,101,6,5,84,111,111,108,115, + 0,1,6,97,99,116,105,111,110,7,5,116,111,111,108,48,8,100,105,115, + 112,110,97,109,101,6,6,84,111,111,108,32,49,0,1,6,97,99,116,105, + 111,110,7,5,116,111,111,108,49,8,100,105,115,112,110,97,109,101,6,6, + 84,111,111,108,32,50,0,1,6,97,99,116,105,111,110,7,5,116,111,111, + 108,50,8,100,105,115,112,110,97,109,101,6,6,84,111,111,108,32,51,0, + 1,6,97,99,116,105,111,110,7,5,116,111,111,108,51,8,100,105,115,112, + 110,97,109,101,6,6,84,111,111,108,32,52,0,1,6,97,99,116,105,111, + 110,7,5,116,111,111,108,52,8,100,105,115,112,110,97,109,101,6,6,84, + 111,111,108,32,53,0,1,6,97,99,116,105,111,110,7,5,116,111,111,108, + 53,8,100,105,115,112,110,97,109,101,6,6,84,111,111,108,32,54,0,1, + 6,97,99,116,105,111,110,7,5,116,111,111,108,54,8,100,105,115,112,110, + 97,109,101,6,6,84,111,111,108,32,55,0,1,6,97,99,116,105,111,110, + 7,5,116,111,111,108,55,8,100,105,115,112,110,97,109,101,6,6,84,111, + 111,108,32,56,0,1,6,97,99,116,105,111,110,7,5,116,111,111,108,56, + 8,100,105,115,112,110,97,109,101,6,6,84,111,111,108,32,57,0,1,6, + 97,99,116,105,111,110,7,5,116,111,111,108,57,8,100,105,115,112,110,97, + 109,101,6,7,84,111,111,108,32,49,48,0,0,18,115,121,115,115,104,111, + 114,116,99,117,116,115,46,99,111,117,110,116,2,11,18,115,121,115,115,104, + 111,114,116,99,117,116,115,46,105,116,101,109,115,1,3,67,64,3,86,64, + 3,88,64,3,65,64,3,6,65,3,6,97,3,7,65,3,67,96,3,86, + 96,3,90,64,3,90,96,0,19,115,121,115,115,104,111,114,116,99,117,116, + 115,49,46,99,111,117,110,116,2,11,19,115,121,115,115,104,111,114,116,99, + 117,116,115,49,46,105,116,101,109,115,1,2,0,3,6,33,3,7,33,2, + 0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,0,24,97,115,115, + 105,115,116,105,118,101,115,104,111,114,116,99,117,116,115,46,99,111,117,110, + 116,2,9,24,97,115,115,105,115,116,105,118,101,115,104,111,114,116,99,117, + 116,115,46,105,116,101,109,115,1,1,3,32,64,0,1,3,32,96,0,1, + 3,89,64,2,70,0,1,3,89,64,2,76,0,1,3,89,64,2,67,0, + 1,3,45,72,0,1,3,43,72,0,1,3,45,104,0,1,3,43,104,0, + 0,25,97,115,115,105,115,116,105,118,101,115,104,111,114,116,99,117,116,115, + 49,46,99,111,117,110,116,2,9,25,97,115,115,105,115,116,105,118,101,115, + 104,111,114,116,99,117,116,115,49,46,105,116,101,109,115,1,1,3,4,73, + 0,1,3,4,105,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 0,8,115,116,97,116,102,105,108,101,7,19,109,97,105,110,102,111,46,109, + 97,105,110,115,116,97,116,102,105,108,101,13,111,110,97,102,116,101,114,117, + 112,100,97,116,101,7,15,117,112,100,97,116,101,115,104,111,114,116,99,117, + 116,115,4,108,101,102,116,3,96,1,3,116,111,112,2,8,0,0,7,116, + 97,99,116,105,111,110,15,116,111,103,103,108,101,105,110,115,112,101,99,116, + 111,114,7,99,97,112,116,105,111,110,6,21,84,111,103,103,108,101,32,70, + 111,114,109,47,73,110,115,112,101,99,116,111,114,4,108,101,102,116,3,152, + 0,3,116,111,112,2,120,2,115,99,1,2,1,3,58,1,0,0,0,7, + 116,97,99,116,105,111,110,8,98,117,105,108,100,97,99,116,9,111,110,101, + 120,101,99,117,116,101,7,16,109,97,107,101,97,99,116,111,110,101,120,101, + 99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,56,1,0,0, + 7,116,97,99,116,105,111,110,8,109,97,107,101,49,97,99,116,9,111,110, + 101,120,101,99,117,116,101,7,16,109,97,107,101,97,99,116,111,110,101,120, + 101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,74,1,0, + 0,7,116,97,99,116,105,111,110,8,109,97,107,101,50,97,99,116,9,111, + 110,101,120,101,99,117,116,101,7,16,109,97,107,101,97,99,116,111,110,101, + 120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,92,1, + 0,0,7,116,97,99,116,105,111,110,8,109,97,107,101,51,97,99,116,9, + 111,110,101,120,101,99,117,116,101,7,16,109,97,107,101,97,99,116,111,110, + 101,120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,110, + 1,0,0,7,116,97,99,116,105,111,110,8,109,97,107,101,52,97,99,116, + 9,111,110,101,120,101,99,117,116,101,7,16,109,97,107,101,97,99,116,111, + 110,101,120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3, + 128,1,0,0,7,116,97,99,116,105,111,110,8,100,111,119,110,108,111,97, + 100,7,99,97,112,116,105,111,110,6,8,68,111,119,110,108,111,97,100,9, + 111,110,101,120,101,99,117,116,101,7,11,100,111,119,110,108,111,97,100,101, + 120,101,4,108,101,102,116,2,8,3,116,111,112,3,168,0,0,0,7,116, + 97,99,116,105,111,110,7,104,101,108,112,97,99,116,7,111,112,116,105,111, + 110,115,11,17,97,111,95,103,108,111,98,97,108,115,104,111,114,116,99,117, + 116,0,9,111,110,101,120,101,99,117,116,101,7,6,104,101,108,112,101,120, + 4,108,101,102,116,3,24,1,3,116,111,112,3,144,1,2,115,99,1,2, + 1,3,48,1,0,0,0,7,116,97,99,116,105,111,110,12,97,116,116,97, + 99,104,116,97,114,103,101,116,7,99,97,112,116,105,111,110,6,13,65,116, + 116,97,99,104,32,84,97,114,103,101,116,9,111,110,101,120,101,99,117,116, + 101,7,14,111,110,97,116,116,97,99,104,116,97,114,103,101,116,4,108,101, + 102,116,2,8,3,116,111,112,2,120,0,0,7,116,97,99,116,105,111,110, + 6,115,101,116,98,109,48,7,99,97,112,116,105,111,110,6,11,66,111,111, + 107,109,97,114,107,32,38,48,9,111,110,101,120,101,99,117,116,101,7,9, + 115,101,116,98,109,101,120,101,99,4,108,101,102,116,3,24,1,3,116,111, + 112,3,208,0,2,115,99,1,2,1,3,48,96,0,0,0,7,116,97,99, + 116,105,111,110,7,102,105,110,100,98,109,48,7,99,97,112,116,105,111,110, + 6,11,66,111,111,107,109,97,114,107,32,38,48,9,111,110,101,120,101,99, + 117,116,101,7,10,102,105,110,100,98,109,101,120,101,99,4,108,101,102,116, + 3,104,1,3,116,111,112,3,208,0,2,115,99,1,2,1,3,48,64,0, + 0,0,7,116,97,99,116,105,111,110,7,102,105,110,100,98,109,49,7,99, + 97,112,116,105,111,110,6,11,66,111,111,107,109,97,114,107,32,38,49,9, + 116,97,103,97,99,116,105,111,110,2,1,9,111,110,101,120,101,99,117,116, + 101,7,10,102,105,110,100,98,109,101,120,101,99,4,108,101,102,116,3,104, + 1,3,116,111,112,3,224,0,2,115,99,1,2,1,3,49,64,0,0,0, + 7,116,97,99,116,105,111,110,6,115,101,116,98,109,49,7,99,97,112,116, + 105,111,110,6,11,66,111,111,107,109,97,114,107,32,38,49,9,116,97,103, + 97,99,116,105,111,110,2,1,9,111,110,101,120,101,99,117,116,101,7,9, + 115,101,116,98,109,101,120,101,99,4,108,101,102,116,3,24,1,3,116,111, + 112,3,224,0,2,115,99,1,2,1,3,49,96,0,0,0,7,116,97,99, + 116,105,111,110,7,102,105,110,100,98,109,50,7,99,97,112,116,105,111,110, + 6,11,66,111,111,107,109,97,114,107,32,38,50,9,116,97,103,97,99,116, + 105,111,110,2,2,9,111,110,101,120,101,99,117,116,101,7,10,102,105,110, + 100,98,109,101,120,101,99,4,108,101,102,116,3,104,1,3,116,111,112,3, + 240,0,2,115,99,1,2,1,3,50,64,0,0,0,7,116,97,99,116,105, + 111,110,6,115,101,116,98,109,50,7,99,97,112,116,105,111,110,6,11,66, + 111,111,107,109,97,114,107,32,38,50,9,116,97,103,97,99,116,105,111,110, + 2,2,9,111,110,101,120,101,99,117,116,101,7,9,115,101,116,98,109,101, + 120,101,99,4,108,101,102,116,3,24,1,3,116,111,112,3,240,0,2,115, + 99,1,2,1,3,50,96,0,0,0,7,116,97,99,116,105,111,110,7,102, + 105,110,100,98,109,51,7,99,97,112,116,105,111,110,6,11,66,111,111,107, + 109,97,114,107,32,38,51,9,116,97,103,97,99,116,105,111,110,2,3,9, + 111,110,101,120,101,99,117,116,101,7,10,102,105,110,100,98,109,101,120,101, + 99,4,108,101,102,116,3,104,1,3,116,111,112,3,0,1,2,115,99,1, + 2,1,3,51,64,0,0,0,7,116,97,99,116,105,111,110,6,115,101,116, + 98,109,51,7,99,97,112,116,105,111,110,6,11,66,111,111,107,109,97,114, + 107,32,38,51,9,116,97,103,97,99,116,105,111,110,2,3,9,111,110,101, + 120,101,99,117,116,101,7,9,115,101,116,98,109,101,120,101,99,4,108,101, + 102,116,3,24,1,3,116,111,112,3,0,1,2,115,99,1,2,1,3,51, + 96,0,0,0,7,116,97,99,116,105,111,110,7,102,105,110,100,98,109,52, + 7,99,97,112,116,105,111,110,6,11,66,111,111,107,109,97,114,107,32,38, + 52,9,116,97,103,97,99,116,105,111,110,2,4,9,111,110,101,120,101,99, + 117,116,101,7,10,102,105,110,100,98,109,101,120,101,99,4,108,101,102,116, + 3,104,1,3,116,111,112,3,16,1,2,115,99,1,2,1,3,52,64,0, + 0,0,7,116,97,99,116,105,111,110,6,115,101,116,98,109,52,7,99,97, + 112,116,105,111,110,6,11,66,111,111,107,109,97,114,107,32,38,52,9,116, + 97,103,97,99,116,105,111,110,2,4,9,111,110,101,120,101,99,117,116,101, + 7,9,115,101,116,98,109,101,120,101,99,4,108,101,102,116,3,24,1,3, + 116,111,112,3,16,1,2,115,99,1,2,1,3,52,96,0,0,0,7,116, + 97,99,116,105,111,110,7,102,105,110,100,98,109,53,7,99,97,112,116,105, + 111,110,6,11,66,111,111,107,109,97,114,107,32,38,53,9,116,97,103,97, + 99,116,105,111,110,2,5,9,111,110,101,120,101,99,117,116,101,7,10,102, + 105,110,100,98,109,101,120,101,99,4,108,101,102,116,3,104,1,3,116,111, + 112,3,32,1,2,115,99,1,2,1,3,53,64,0,0,0,7,116,97,99, + 116,105,111,110,6,115,101,116,98,109,53,7,99,97,112,116,105,111,110,6, + 11,66,111,111,107,109,97,114,107,32,38,53,9,116,97,103,97,99,116,105, + 111,110,2,5,9,111,110,101,120,101,99,117,116,101,7,9,115,101,116,98, + 109,101,120,101,99,4,108,101,102,116,3,24,1,3,116,111,112,3,32,1, + 2,115,99,1,2,1,3,53,96,0,0,0,7,116,97,99,116,105,111,110, + 7,102,105,110,100,98,109,54,7,99,97,112,116,105,111,110,6,11,66,111, + 111,107,109,97,114,107,32,38,54,9,116,97,103,97,99,116,105,111,110,2, + 6,9,111,110,101,120,101,99,117,116,101,7,10,102,105,110,100,98,109,101, + 120,101,99,4,108,101,102,116,3,104,1,3,116,111,112,3,48,1,2,115, + 99,1,2,1,3,54,64,0,0,0,7,116,97,99,116,105,111,110,6,115, + 101,116,98,109,54,3,84,97,103,2,6,7,99,97,112,116,105,111,110,6, + 11,66,111,111,107,109,97,114,107,32,38,54,9,116,97,103,97,99,116,105, + 111,110,2,6,9,111,110,101,120,101,99,117,116,101,7,9,115,101,116,98, + 109,101,120,101,99,4,108,101,102,116,3,24,1,3,116,111,112,3,48,1, + 2,115,99,1,2,1,3,54,96,0,0,0,7,116,97,99,116,105,111,110, + 7,102,105,110,100,98,109,55,7,99,97,112,116,105,111,110,6,11,66,111, + 111,107,109,97,114,107,32,38,55,9,116,97,103,97,99,116,105,111,110,2, + 7,9,111,110,101,120,101,99,117,116,101,7,10,102,105,110,100,98,109,101, + 120,101,99,4,108,101,102,116,3,104,1,3,116,111,112,3,64,1,2,115, + 99,1,2,1,3,55,64,0,0,0,7,116,97,99,116,105,111,110,6,115, + 101,116,98,109,55,7,99,97,112,116,105,111,110,6,11,66,111,111,107,109, + 97,114,107,32,38,55,9,116,97,103,97,99,116,105,111,110,2,7,9,111, + 110,101,120,101,99,117,116,101,7,9,115,101,116,98,109,101,120,101,99,4, + 108,101,102,116,3,24,1,3,116,111,112,3,64,1,2,115,99,1,2,1, + 3,55,96,0,0,0,7,116,97,99,116,105,111,110,7,102,105,110,100,98, + 109,56,7,99,97,112,116,105,111,110,6,11,66,111,111,107,109,97,114,107, + 32,38,56,9,116,97,103,97,99,116,105,111,110,2,8,9,111,110,101,120, + 101,99,117,116,101,7,10,102,105,110,100,98,109,101,120,101,99,4,108,101, + 102,116,3,104,1,3,116,111,112,3,80,1,2,115,99,1,2,1,3,56, + 64,0,0,0,7,116,97,99,116,105,111,110,6,115,101,116,98,109,56,7, + 99,97,112,116,105,111,110,6,11,66,111,111,107,109,97,114,107,32,38,56, + 9,116,97,103,97,99,116,105,111,110,2,8,9,111,110,101,120,101,99,117, + 116,101,7,9,115,101,116,98,109,101,120,101,99,4,108,101,102,116,3,24, + 1,3,116,111,112,3,80,1,2,115,99,1,2,1,3,56,96,0,0,0, + 7,116,97,99,116,105,111,110,7,102,105,110,100,98,109,57,7,99,97,112, + 116,105,111,110,6,11,66,111,111,107,109,97,114,107,32,38,57,9,116,97, + 103,97,99,116,105,111,110,2,9,9,111,110,101,120,101,99,117,116,101,7, + 10,102,105,110,100,98,109,101,120,101,99,4,108,101,102,116,3,104,1,3, + 116,111,112,3,96,1,2,115,99,1,2,1,3,57,64,0,0,0,7,116, + 97,99,116,105,111,110,6,115,101,116,98,109,57,7,99,97,112,116,105,111, + 110,6,11,66,111,111,107,109,97,114,107,32,38,57,9,116,97,103,97,99, + 116,105,111,110,2,9,9,111,110,101,120,101,99,117,116,101,7,9,115,101, + 116,98,109,101,120,101,99,4,108,101,102,116,3,24,1,3,116,111,112,3, + 96,1,2,115,99,1,2,1,3,57,96,0,0,0,7,116,97,99,116,105, + 111,110,9,115,101,116,98,109,110,111,110,101,7,99,97,112,116,105,111,110, + 6,4,110,111,110,101,9,116,97,103,97,99,116,105,111,110,2,255,9,111, + 110,101,120,101,99,117,116,101,7,9,115,101,116,98,109,101,120,101,99,4, + 108,101,102,116,3,24,1,3,116,111,112,3,112,1,0,0,7,116,97,99, + 116,105,111,110,11,105,110,115,116,101,109,112,108,97,116,101,9,111,110,101, + 120,101,99,117,116,101,7,23,105,110,115,116,101,109,112,108,97,116,101,97, + 99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116,3,112,1,3, + 116,111,112,2,96,2,115,99,1,2,1,3,84,64,0,0,0,7,116,97, + 99,116,105,111,110,14,112,114,111,106,101,99,116,111,112,101,110,97,99,116, + 7,99,97,112,116,105,111,110,6,5,79,38,112,101,110,9,111,110,101,120, + 101,99,117,116,101,7,14,112,114,111,106,101,99,116,111,112,101,110,101,120, + 101,4,108,101,102,116,2,112,3,116,111,112,3,40,1,0,0,7,116,97, + 99,116,105,111,110,17,112,114,111,106,101,99,116,111,112,116,105,111,110,115, + 97,99,116,7,99,97,112,116,105,111,110,6,8,38,79,112,116,105,111,110, + 115,9,111,110,101,120,101,99,117,116,101,7,17,112,114,111,106,101,99,116, + 111,112,116,105,111,110,115,101,120,101,4,108,101,102,116,2,112,3,116,111, + 112,3,56,1,0,0,7,116,97,99,116,105,111,110,14,112,114,111,106,101, + 99,116,116,114,101,101,97,99,116,7,99,97,112,116,105,111,110,6,5,38, + 84,114,101,101,9,111,110,101,120,101,99,117,116,101,7,14,112,114,111,106, + 101,99,116,116,114,101,101,101,120,101,4,108,101,102,116,2,112,3,116,111, + 112,3,72,1,0,0,7,116,97,99,116,105,111,110,16,112,114,111,106,101, + 99,116,115,111,117,114,99,101,97,99,116,7,99,97,112,116,105,111,110,6, + 7,83,111,38,117,114,99,101,9,111,110,101,120,101,99,117,116,101,7,16, + 112,114,111,106,101,99,116,115,111,117,114,99,101,101,120,101,4,108,101,102, + 116,2,112,3,116,111,112,3,88,1,0,0,7,116,97,99,116,105,111,110, + 14,112,114,111,106,101,99,116,115,97,118,101,97,99,116,7,99,97,112,116, + 105,111,110,6,5,38,83,97,118,101,9,111,110,101,120,101,99,117,116,101, + 7,14,112,114,111,106,101,99,116,115,97,118,101,101,120,101,4,108,101,102, + 116,2,112,3,116,111,112,3,104,1,0,0,7,116,97,99,116,105,111,110, + 15,112,114,111,106,101,99,116,99,108,111,115,101,97,99,116,7,99,97,112, + 116,105,111,110,6,6,38,67,108,111,115,101,9,111,110,101,120,101,99,117, + 116,101,7,16,112,114,111,106,101,99,116,99,108,111,101,115,101,101,120,101, + 4,108,101,102,116,2,112,3,116,111,112,3,120,1,0,0,16,116,115,116, + 114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,11,111,110,114,101, + 97,100,115,116,97,116,101,7,13,99,114,101,97,100,115,116,97,116,101,101, + 120,101,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,16,67,111, + 110,102,105,103,117,114,101,32,77,83,69,105,100,101,6,10,80,114,111,99, + 101,115,115,32,73,68,6,17,65,116,116,97,99,104,32,116,111,32,112,114, + 111,99,101,115,115,6,25,85,110,107,110,111,119,110,32,109,111,100,117,108, + 101,99,108,97,115,115,32,102,111,114,32,34,6,21,73,110,104,101,114,105, + 116,101,100,32,99,111,109,112,111,110,101,110,116,32,34,6,21,34,32,99, + 97,110,32,110,111,116,32,98,101,32,100,101,108,101,116,101,100,46,6,5, + 69,82,82,79,82,6,13,77,97,107,101,32,97,98,111,114,116,101,100,46, + 6,17,68,111,119,110,108,111,97,100,32,97,98,111,114,116,101,100,46,6, + 15,82,117,110,101,114,114,111,114,32,119,105,116,104,32,34,6,15,69,114, + 114,111,114,58,32,84,105,109,101,111,117,116,46,6,7,77,97,107,105,110, + 103,46,6,17,77,97,107,101,32,110,111,116,32,114,117,110,110,105,110,103, + 46,6,12,68,111,119,110,108,111,97,100,105,110,103,46,6,21,68,111,119, + 110,108,111,97,100,32,110,111,116,32,114,117,110,110,105,110,103,46,6,10, + 34,32,114,117,110,110,105,110,103,46,6,6,83,99,114,105,112,116,6,31, + 82,101,99,117,114,115,105,118,101,32,102,111,114,109,32,105,110,104,101,114, + 105,116,97,110,99,101,32,111,102,32,34,6,11,67,111,109,112,111,110,101, + 110,116,32,34,6,9,34,32,101,120,105,115,116,115,46,6,14,65,110,99, + 101,115,116,111,114,32,102,111,114,32,34,6,12,34,32,110,111,116,32,102, + 111,117,110,100,46,6,8,77,111,100,117,108,101,32,34,6,14,73,110,118, + 97,108,105,100,32,110,97,109,101,32,34,6,18,73,110,118,97,108,105,100, + 32,109,101,116,104,111,100,110,97,109,101,6,16,77,111,100,117,108,101,32, + 110,111,116,32,102,111,117,110,100,6,16,77,101,116,104,111,100,32,110,111, + 116,32,102,111,117,110,100,6,26,80,117,98,108,105,115,104,101,100,32,40, + 109,97,110,97,103,101,100,41,32,109,101,116,104,111,100,6,15,100,111,101, + 115,32,110,111,116,32,101,120,105,115,116,46,6,32,68,111,32,121,111,117, + 32,119,105,115,104,32,116,111,32,100,101,108,101,116,101,32,116,104,101,32, + 101,118,101,110,116,63,6,7,87,65,82,78,73,78,71,6,6,77,101,116, + 104,111,100,6,25,104,97,115,32,100,105,102,102,101,114,101,110,116,32,112, + 97,114,97,109,101,116,101,114,115,46,6,10,65,32,109,111,100,117,108,101, + 32,34,6,18,34,32,105,115,32,97,108,114,101,97,100,121,32,111,112,101, + 110,46,6,26,85,110,114,101,115,111,108,118,101,100,32,114,101,102,101,114, + 101,110,99,101,40,115,41,32,116,111,6,10,77,111,100,117,108,101,40,115, + 41,58,6,23,67,97,110,32,110,111,116,32,114,101,97,100,32,102,111,114, + 109,102,105,108,101,32,34,6,23,73,110,118,97,108,105,100,32,99,111,109, + 112,111,110,101,110,116,32,110,97,109,101,46,6,17,73,110,118,97,108,105, + 100,32,101,120,99,101,112,116,105,111,110,6,6,84,38,111,111,108,115,6, + 5,70,111,114,109,115,6,6,83,111,117,114,99,101,6,9,65,108,108,32, + 70,105,108,101,115,6,7,80,114,111,103,114,97,109,6,4,85,110,105,116, + 6,8,84,101,120,116,102,105,108,101,6,8,77,97,105,110,102,111,114,109, + 6,11,83,105,109,112,108,101,32,70,111,114,109,6,12,68,111,99,107,105, + 110,103,32,70,111,114,109,6,10,68,97,116,97,109,111,100,117,108,101,6, + 7,83,117,98,102,111,114,109,6,13,83,99,114,111,108,108,98,111,120,102, + 111,114,109,6,7,84,97,98,102,111,114,109,6,9,68,111,99,107,112,97, + 110,101,108,6,6,82,101,112,111,114,116,6,10,83,99,114,105,112,116,102, + 111,114,109,6,14,73,110,104,101,114,105,116,101,100,32,70,111,114,109,6, + 38,68,111,32,121,111,117,32,119,97,110,116,32,116,111,32,114,101,112,108, + 97,99,101,32,116,104,101,32,115,101,116,116,105,110,103,115,32,98,121,6, + 6,70,105,108,101,32,34,6,25,68,111,32,121,111,117,32,119,97,110,116, + 32,116,111,32,111,118,101,114,119,114,105,116,101,63,6,7,85,110,107,110, + 111,119,110,6,5,69,114,114,111,114,6,7,83,116,97,114,116,117,112,6, + 9,69,120,99,101,112,116,105,111,110,6,8,71,68,66,32,100,105,101,100, + 6,14,66,114,101,97,107,112,111,105,110,116,32,104,105,116,6,20,87,97, + 116,99,104,112,111,105,110,116,32,116,114,105,103,103,101,114,101,100,6,25, + 82,101,97,100,32,87,97,116,99,104,112,111,105,110,116,32,116,114,105,103, + 103,101,114,101,100,6,27,65,99,99,101,115,115,32,87,97,116,99,104,112, + 111,105,110,116,32,116,114,105,103,103,101,114,101,100,6,18,69,110,100,32, + 115,116,101,112,112,105,110,103,32,114,97,110,103,101,6,17,70,117,110,99, + 116,105,111,110,32,102,105,110,105,115,104,101,100,6,15,69,120,105,116,101, + 100,32,110,111,114,109,97,108,108,121,6,6,69,120,105,116,101,100,6,8, + 68,101,116,97,99,104,101,100,6,15,83,105,103,110,97,108,32,114,101,99, + 101,105,118,101,100,6,10,83,116,111,112,32,101,114,114,111,114,6,20,67, + 97,110,32,110,111,116,32,114,101,97,100,32,112,114,111,106,101,99,116,6, + 5,65,98,111,117,116,6,16,79,98,106,101,99,116,32,73,110,115,112,101, + 99,116,111,114,6,15,83,116,111,114,101,32,67,111,109,112,111,110,101,110, + 116,6,17,65,116,116,97,99,104,105,110,103,32,80,114,111,99,101,115,115, + 6,7,76,111,97,100,105,110,103,6,11,83,105,122,105,110,103,32,70,111, + 114,109,0,4,108,101,102,116,3,136,1,3,116,111,112,3,144,1,0,0, + 7,116,97,99,116,105,111,110,12,99,111,112,121,108,97,116,101,120,97,99, + 116,7,99,97,112,116,105,111,110,6,11,67,111,112,121,32,38,76,97,84, + 101,88,9,111,110,101,120,101,99,117,116,101,7,21,99,111,112,121,108,97, + 116,101,120,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116, + 3,112,1,3,116,111,112,2,80,2,115,99,1,2,2,3,75,64,2,76, + 0,0,0,7,116,97,99,116,105,111,110,11,102,105,110,100,99,111,109,112, + 97,99,116,9,111,110,101,120,101,99,117,116,101,7,11,102,105,110,100,99, + 111,109,112,101,120,101,4,108,101,102,116,3,152,0,3,116,111,112,3,152, + 0,2,115,99,1,2,1,3,70,64,0,0,0,7,116,97,99,116,105,111, + 110,14,102,105,110,100,99,111,109,112,97,108,108,97,99,116,7,99,97,112, + 116,105,111,110,6,15,38,70,105,110,100,32,67,111,109,112,111,110,101,110, + 116,9,111,110,101,120,101,99,117,116,101,7,14,102,105,110,100,99,111,109, + 112,97,108,108,101,120,101,4,108,101,102,116,3,152,0,3,116,111,112,3, + 168,0,0,0,7,116,97,99,116,105,111,110,14,102,111,114,99,101,122,111, + 114,100,101,114,97,99,116,7,99,97,112,116,105,111,110,6,14,70,111,114, + 99,101,32,38,90,45,79,114,100,101,114,8,111,110,99,104,97,110,103,101, + 7,14,102,111,114,99,101,122,111,114,100,101,114,101,120,101,4,108,101,102, + 116,3,136,0,3,116,111,112,3,144,1,0,0,7,116,97,99,116,105,111, + 110,5,116,111,111,108,48,4,108,101,102,116,3,216,1,3,116,111,112,2, + 8,0,0,7,116,97,99,116,105,111,110,5,116,111,111,108,49,4,108,101, + 102,116,3,216,1,3,116,111,112,2,24,0,0,7,116,97,99,116,105,111, + 110,5,116,111,111,108,50,4,108,101,102,116,3,216,1,3,116,111,112,2, + 40,0,0,7,116,97,99,116,105,111,110,5,116,111,111,108,51,4,108,101, + 102,116,3,216,1,3,116,111,112,2,56,0,0,7,116,97,99,116,105,111, + 110,5,116,111,111,108,52,4,108,101,102,116,3,216,1,3,116,111,112,2, + 72,0,0,7,116,97,99,116,105,111,110,5,116,111,111,108,53,4,108,101, + 102,116,3,216,1,3,116,111,112,2,88,0,0,7,116,97,99,116,105,111, + 110,5,116,111,111,108,54,4,108,101,102,116,3,216,1,3,116,111,112,2, + 104,0,0,7,116,97,99,116,105,111,110,5,116,111,111,108,55,4,108,101, + 102,116,3,216,1,3,116,111,112,2,120,0,0,7,116,97,99,116,105,111, + 110,5,116,111,111,108,56,4,108,101,102,116,3,216,1,3,116,111,112,3, + 136,0,0,0,7,116,97,99,116,105,111,110,5,116,111,111,108,57,4,108, + 101,102,116,3,216,1,3,116,111,112,3,152,0,0,0,7,116,97,99,116, + 105,111,110,7,99,111,109,109,101,110,116,7,99,97,112,116,105,111,110,6, + 8,38,67,111,109,109,101,110,116,9,111,110,101,120,101,99,117,116,101,7, + 16,99,111,109,109,101,110,116,111,110,101,120,101,99,117,116,101,8,111,110, + 117,112,100,97,116,101,7,13,101,110,97,98,108,101,99,111,109,109,101,110, + 116,4,108,101,102,116,3,24,1,3,116,111,112,3,168,0,2,115,99,1, + 2,2,3,75,64,2,67,0,0,0,7,116,97,99,116,105,111,110,9,117, + 110,99,111,109,109,101,110,116,7,99,97,112,116,105,111,110,6,10,85,110, + 99,38,111,109,109,101,110,116,9,111,110,101,120,101,99,117,116,101,7,18, + 117,110,99,111,109,109,101,110,116,111,110,101,120,101,99,117,116,101,8,111, + 110,117,112,100,97,116,101,7,15,101,110,97,98,108,101,117,110,99,111,109, + 109,101,110,116,4,108,101,102,116,3,24,1,3,116,111,112,3,184,0,2, + 115,99,1,2,2,3,75,64,2,85,0,0,0,7,116,97,99,116,105,111, + 110,8,99,111,112,121,119,111,114,100,7,99,97,112,116,105,111,110,6,20, + 67,111,112,121,32,38,87,111,114,100,32,97,116,32,67,117,114,115,111,114, + 7,111,112,116,105,111,110,115,11,17,97,111,95,103,108,111,98,97,108,115, + 104,111,114,116,99,117,116,0,9,111,110,101,120,101,99,117,116,101,7,25, + 115,101,108,101,99,116,119,111,114,100,97,99,116,105,111,110,111,110,101,120, + 101,99,117,116,101,4,108,101,102,116,3,24,1,3,116,111,112,2,100,2, + 115,99,1,2,1,3,87,96,0,0,0,7,116,97,99,116,105,111,110,9, + 115,101,108,101,99,116,97,108,108,7,99,97,112,116,105,111,110,6,11,83, + 101,108,101,99,116,32,38,97,108,108,9,111,110,101,120,101,99,117,116,101, + 7,21,115,101,108,101,99,108,97,108,108,97,99,116,111,110,101,120,101,99, + 117,116,101,4,108,101,102,116,3,88,1,3,116,111,112,2,56,2,115,99, + 1,2,1,3,65,64,0,0,0,7,116,97,99,116,105,111,110,10,116,97, + 98,116,111,115,112,97,99,101,7,99,97,112,116,105,111,110,6,14,38,84, + 97,98,115,32,116,111,32,115,112,97,99,101,9,111,110,101,120,101,99,117, + 116,101,7,17,116,97,98,116,111,115,112,97,99,101,101,120,101,99,117,116, + 101,8,111,110,117,112,100,97,116,101,7,14,101,110,97,98,108,101,111,110, + 115,101,108,101,99,116,4,108,101,102,116,3,104,1,3,116,111,112,3,168, + 0,0,0,7,116,97,99,116,105,111,110,8,102,105,110,100,98,97,99,107, + 7,99,97,112,116,105,111,110,6,12,83,101,97,114,99,104,32,38,98,97, + 99,107,9,111,110,101,120,101,99,117,116,101,7,17,102,105,110,100,98,97, + 99,107,111,110,101,120,101,99,117,116,101,4,108,101,102,116,3,152,0,3, + 116,111,112,2,60,2,115,99,1,2,1,3,50,33,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tactionsmo,''); +end. diff --git a/mseide-msegui/apps/ide/breakpointsform.mfm b/mseide-msegui/apps/ide/breakpointsform.mfm new file mode 100644 index 0000000..2f4f27a --- /dev/null +++ b/mseide-msegui/apps/ide/breakpointsform.mfm @@ -0,0 +1,471 @@ +object breakpointsfo: tbreakpointsfo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton] + visible = False + bounds_x = 107 + bounds_y = 404 + bounds_cx = 636 + bounds_cy = 128 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 626 + 128 + ) + dragdock.splitter_size = 0 + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Breakpoints' + icon.transparentcolor = -2147483642 + icon.image = { + 00000000000000001800000018000000CC060000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E1E1E601B9B9EA01 + 8989EE018888ED01B5B5E601DBDBE001DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01E4E4EA017171F4010707FE010000FF04 + 0707FE016A6AED01D5D5DB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01 + C5C5EE012828FB010000FF081F1FF201B4B4DD01D7D7D702D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01E7E7ED01 + 2929FC010000FF0A1818EB01C5C5CB01D6D6D601D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE017373F6010000FF0C + 3636B901C9C9C901D4D4D401D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001E9E9EE010707FE010000FF0C0303FA0186868B01D2D2D201 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001C0C0F101 + 0000FF0E51518201B0B0B001D2D2D202D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F0019090F5010000FF0E3C3CA10191919101D1D1D101D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F0019090F5010000FF0E3B3BA0017A7A7A01 + D1D1D101D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001C0C0F101 + 0000FF0E4E4E7F016A6A6A01D0D0D001D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001E9E9EE010707FE010000FF0C0303FA01606065017A7A7A01 + D1D1D101D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + 7272F5010000FF0C2F2FB2016363630191919101D1D1D101D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01E6E6EC012121F4010000FF0A + 1111E4015F5F650164646401B0B0B001D2D2D202D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001EEEEEE01EDEDED01C2C2EB011A1AED010000FF081111E401 + 52527B016363630189898901D2D2D201D3D3D301D2D2D201D0D0D001F5F5F501 + F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EAEAEA01D5D5DB013A3ABD01 + 0303FA010000FF040303FA013131B401616167016464640170707001C9C9C901 + D4D4D401D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001 + EEEEEE01EDEDED01EBEBEB01E9E9E901D9D9D9018F8F9401565687013F3FA401 + 3E3EA3015252830163636801656565028A8A8A01CACACA01D6D6D601D5D5D501 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EBEBEB01EAEAEA01E7E7E701E3E3E301BDBDBD019A9A9A0181818101 + 707070018080800196969601B5B5B501D7D7D703D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01 + EAEAEA01E8E8E801E6E6E601E4E4E401E1E1E101DFDFDF01DDDDDD01DCDCDC01 + DBDBDB01DADADA02D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + } + onshow = breakpointsonshow + moduleclassname = 'tdockform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + popupmenu = gripopup + bounds_x = 0 + bounds_y = 24 + bounds_cx = 626 + bounds_cy = 104 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 20 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 11 + captions.items = < + item + caption = 'on' + end + item + caption = 'File' + end + item + end + item + caption = 'Line Nr.' + end + item + caption = 'Address' + end + item + end + item + end + item + caption = 'Count' + end + item + caption = 'Ignore' + end + item + end + item + caption = 'Condition' + end> + end> + datacols.count = 13 + datacols.items = < + item[bkpton] + linecolorfix = -1610612733 + width = 16 + options = [co_drawfocus, co_fixwidth, co_savestate] + widgetname = 'bkpton' + dataclass = tgridintegerdatalist + end + item[filename] + linecolorfix = -1610612733 + width = 158 + options = [co_savevalue, co_savestate] + widgetname = 'filename' + dataclass = tgridmsestringdatalist + end + item[path] + linecolorfix = -1610612733 + options = [co_invisible, co_savevalue] + widgetname = 'path' + dataclass = tgridmsestringdatalist + end + item[line] + linecolorfix = -1610612733 + options = [co_savevalue, co_savestate] + widgetname = 'line' + dataclass = tgridintegerdatalist + end + item[address] + width = 61 + onbeforedrawcell = adbefdrawcell + widgetname = 'address' + dataclass = tgridint64datalist + end + item[addressbkpt] + width = 6 + options = [co_invisible, co_drawfocus, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'addressbkpt' + dataclass = tgridintegerdatalist + end + item[bkptno] + linecolorfix = -1610612733 + width = 19 + options = [co_invisible, co_savevalue] + widgetname = 'bkptno' + dataclass = tgridintegerdatalist + end + item[count] + color = -1879048185 + linecolorfix = -1610612733 + width = 31 + options = [co_readonly, co_nofocus, co_savevalue, co_savestate] + widgetname = 'count' + dataclass = tgridintegerdatalist + end + item[ignore] + linecolorfix = -1610612733 + width = 30 + options = [co_savevalue, co_savestate] + widgetname = 'ignore' + dataclass = tgridintegerdatalist + end + item[conderr] + linecolorfix = -1610612733 + width = 7 + options = [co_readonly, co_nofocus, co_fixwidth, co_savestate] + onshowhint = errhint + widgetname = 'conderr' + dataclass = tgridintegerdatalist + end + item[condition] + linecolorfix = -1610612733 + width = 124 + options = [co_fill, co_savevalue, co_savestate] + widthmin = 0 + widgetname = 'condition' + dataclass = tgridmsestringdatalist + end + item[errormessage] + width = 19 + options = [co_invisible, co_mousescrollrow] + widgetname = 'errormessage' + dataclass = tgridmsestringdatalist + end + item[flags] + width = 17 + options = [co_invisible, co_savevalue, co_savestate] + widgetname = 'flags' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + onrowsdeleting = gridonrowsdeleting + onrowsdeleted = gridonrowsdeleted + oncellevent = gridoncellevent + reffontheight = 14 + object bkpton: tbooleanedit + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 16 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + ondataentered = ondataentered + visible = False + onsetvalue = ononsetvalue + valuedefault = True + end + object filename: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 17 + bounds_y = 0 + bounds_cx = 158 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = ondataenterednewbkpt + onsetvalue = filenameonsetvalue + reffontheight = 14 + end + object path: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 176 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + object line: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 227 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = ondataenterednewbkpt + onsetvalue = lineonsetvalue + min = 1 + reffontheight = 14 + end + object address: tint64edit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 5 + visible = False + bounds_x = 278 + bounds_y = 0 + bounds_cx = 61 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + ondataentered = addressentered + base = nb_hex + max = -1 + reffontheight = 14 + end + object addressbkpt: tbooleanedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 6 + bounds_x = 340 + bounds_y = 0 + bounds_cx = 6 + bounds_cy = 16 + visible = False + reffontheight = 14 + end + object bkptno: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 7 + visible = False + bounds_x = 347 + bounds_y = 0 + bounds_cx = 19 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + object count: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 8 + visible = False + bounds_x = 367 + bounds_y = 0 + bounds_cx = 31 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object ignore: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 9 + visible = False + bounds_x = 399 + bounds_y = 0 + bounds_cx = 30 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + ondataentered = ondataentered + onsetvalue = ignoreonsetvalue + reffontheight = 14 + end + object conderr: tdataicon + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 10 + bounds_x = 430 + bounds_y = 0 + bounds_cx = 7 + bounds_cy = 16 + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + imagelist = actionsmo.buttonicons + imageoffset = 10 + reffontheight = 14 + end + object condition: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 11 + visible = False + bounds_x = 438 + bounds_y = 0 + bounds_cx = 124 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick, oe_trimright, oe_trimleft] + ondataentered = ondataentered + onsetvalue = conditiononsetvalue + reffontheight = 14 + end + object errormessage: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 12 + visible = False + bounds_x = 563 + bounds_y = 0 + bounds_cx = 19 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object flags: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 13 + visible = False + bounds_x = 583 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + end + object bkptson: tbooleanedit + frame.caption = 'Breakpoints &on' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 98 + 2 + ) + bounds_x = 8 + bounds_y = 4 + bounds_cx = 111 + bounds_cy = 16 + statfile = mainfo.projectstatfile + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + onchange = bkptsononchange + onsetvalue = bkptsononsetvalue + value = True + end + object gripopup: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Delete all' + state = [as_localcaption, as_localonexecute] + onexecute = deleteallexecute + end> + menu.name = 'gridpopup' + left = 168 + end + object c: tstringcontainer + strings.data = ( + 'Breakpoint error.' + 'BREAKPOINT ERROR' + 'Do you wish to delete all breakpoints?' + 'Confirmation' + ) + left = 344 + top = 80 + end +end diff --git a/mseide-msegui/apps/ide/breakpointsform.pas b/mseide-msegui/apps/ide/breakpointsform.pas new file mode 100644 index 0000000..0405a4d --- /dev/null +++ b/mseide-msegui/apps/ide/breakpointsform.pas @@ -0,0 +1,822 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit breakpointsform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseforms,msewidgetgrid,msedataedits,msegdbutils,msetypes,msegrids, + msegraphedits,msestat,msemenuwidgets,msemenus,msestrings,mseedit,mseevent, + msegui,msegraphics,mseguiglob,msestringcontainer; + +type + bkptstatety = (bkpts_none,bkpts_normal,bkpts_disabled,bkpts_error); + + bkptlineinfoty = record + line: integer; + state: bkptstatety; + end; + bkptlineinfoarty = array of bkptlineinfoty; + + tbreakpointsfo = class(tdockform) + grid: twidgetgrid; + filename: tstringedit; + path: tstringedit; + line: tintegeredit; + bkptno: tintegeredit; + bkpton: tbooleanedit; + bkptson: tbooleanedit; + condition: tstringedit; + conderr: tdataicon; + ignore: tintegeredit; + count: tintegeredit; + gridpopup: tpopupmenu; + flags: tintegeredit; + address: tint64edit; + addressbkpt: tbooleanedit; + errormessage: tstringedit; + c: tstringcontainer; + procedure bkptsononchange(const sender: TObject); + procedure bkptsononsetvalue(const sender: TObject; var avalue: boolean; + var accept: Boolean); + + procedure breakpointsonshow(const sender: TObject); + procedure gridoncellevent(const sender: TObject; var info: celleventinfoty); + procedure gridonrowsdeleted(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); + procedure gridonrowsdeleting(const sender: tcustomgrid; var aindex,acount: integer); + + procedure ononsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure ignoreonsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); + procedure conditiononsetvalue(const sender: TObject; var avalue: mseString; var accept: Boolean); + procedure ondataentered(const sender: tobject); + + procedure lineonsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); + procedure filenameonsetvalue(const sender: tobject; var avalue: msestring; var accept: boolean); + procedure ondataenterednewbkpt(const sender: tobject); + + procedure deleteallexecute(const sender: TObject); + procedure addressentered(const sender: TObject); + procedure adbefdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure errhint(const sender: tdatacol; const arow: Integer; + var info: hintinfoty); + private + fbreakpointsvalid: boolean; + function infotolineinfo(const info: breakpointinfoty): bkptlineinfoty; + function breakpointerror(const error: gdbresultty; + out errme: msestring): boolean; + procedure removeactbreakpoint; + function findbreakpointrow(const anum: integer): integer; + procedure newbkpt(const addressbp: boolean); + procedure updaterow(const arow: integer); + protected + procedure infotolist(const index: integer; var info: breakpointinfoty; + const nobkpton: boolean); + procedure listtoinfo(const index: integer; var info: breakpointinfoty); + procedure changed; + procedure insertbkpt(index: integer; + withcondition,witherrormessage: boolean); + public + gdb: tgdbmi; + + breakpointpaths: msestringarty; + breakpointlines: integerarty; + breakpointaddress: int64arty; + addressbreakpoints: longboolarty; + breakpointons: longboolarty; + breakpointignore: integerarty; + breakpointconditions: msestringarty; + + procedure clear; + procedure refresh; + procedure updatestat(const statfiler: tstatfiler); + function addbreakpoint(var info: breakpointinfoty): boolean; + //true if gdb ok + procedure deletebreakpoint(var info: breakpointinfoty); + function updatebreakpointon(var info: breakpointinfoty): boolean; + //true if gdb ok + function getbreakpointlines(const filepath: filenamety): bkptlineinfoarty; + procedure sourcelinesinserted(const filepath: filenamety; + const aindex,acount: integer); + procedure sourcelinesdeleted(const filepath: filenamety; + const aindex,acount: integer); + + procedure updatebreakpoints; //transfer breakpoints to gdb + procedure showbreakpoint(const filepath: filenamety; + const aline: integer; const focus: boolean); + procedure showbreakpoint(const aaddress: int64; focus: boolean); + function checkbreakpointcontinue(const stopinfo: stopinfoty): boolean; + //set condition + function isactivebreakpoint(const addr: qword): boolean; + procedure toggleaddrbreakpoint(const addr: qword); + end; + +var + breakpointsfo: tbreakpointsfo; + +implementation +uses + breakpointsform_mfm,msefileutils,sourceform,projectoptionsform,msedatalist, + main,msewidgets,actionsmodule,watchpointsform,mseformatstr,msegraphutils, + disassform; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + stringconsts = ( + breakpointerror0, //0 Breakpoint error. + breakpointerror1, //1 BREAKPOINT ERROR + delbr, //2 Do you wish to delete all breakpoints? + confirmation //3 Confirmation + ); + +{ tbreakpointsfo } + +procedure tbreakpointsfo.updatestat(const statfiler: tstatfiler); +var + int1: integer; +begin + with statfiler,projectoptions do begin + setsection('breakpoints'); + updatevalue('on',breakpointons); + updatevalue('path',breakpointpaths); + updatevalue('line',breakpointlines); + updatevalue('address',breakpointaddress); + updatevalue('addbkpt',addressbreakpoints); + updatevalue('ignore',breakpointignore); + updatevalue('condition',breakpointconditions); + if not iswriter then begin + ignore.gridvalues:= breakpointignore; + condition.gridvalues:= breakpointconditions; + bkpton.gridvalues:= breakpointons; + path.gridvalues:= breakpointpaths; + line.gridvalues:= breakpointlines; + address.gridvalues:= breakpointaddress; + addressbkpt.gridvalues:= addressbreakpoints; +// updatebreakpoints(true); + end; +// updatestat(istatfile(bkptson)); +// updatestat(istatfile(grid)); + end; + for int1:= 0 to grid.rowhigh do begin + filename[int1]:= msefileutils.filename(path[int1]); + end; +end; + +procedure tbreakpointsfo.infotolist(const index: integer; + var info: breakpointinfoty; const nobkpton: boolean); +var + int1: integer; + lineinfo: bkptlineinfoty; + info1: breakpointinfoty; +// bo1: boolean; +begin + if gdb.execloaded and not gdb.running then begin + gdb.infobreakpoint(info,info.addressbreakpoint); + //update adress or fileinfo + end; + addressbkpt[index]:= info.addressbreakpoint; + path[index]:= info.path; + filename[index]:= msefileutils.filename(info.path); + line[index]:= info.line; + address[index]:= info.address; + bkptno[index]:= info.bkptno; + if not nobkpton then begin + bkpton[index]:= info.bkpton; + end; + ignore[index]:= info.ignore; + if info.conditionmessage <> '' then begin + int1:= 0; + end + else begin + int1:= -1; + end; + conderr[index]:= int1; + condition[index]:= msestring(info.condition); + info1:= info; + info1.bkpton:= bkpton[index]; + lineinfo:= infotolineinfo(info1); + sourcefo.updatebreakpointicon(info.path,lineinfo); +end; + +procedure tbreakpointsfo.listtoinfo(const index: integer; + var info: breakpointinfoty); +begin + info.addressbreakpoint:= addressbkpt[index]; + info.path:= path[index]; + info.line:= line[index]; + info.address:= address[index]; + info.bkptno:= bkptno[index]; + info.bkpton:= bkpton[index] and bkptson.value; + info.ignore:= ignore[index]; + info.condition:= ansistring(condition[index]); + if (info.conditionmessage = '') and (conderr[index] = 0) then begin + info.conditionmessage:= ' '; //old error + end; +end; + +procedure tbreakpointsfo.bkptsononchange(const sender: TObject); +var + int1: integer; + bo1: boolean; +begin + projectoptions.modified:= true; + if gdb.execloaded then begin + bo1:= bkptson.value; + gdb.interrupttarget; + for int1:= 0 to grid.rowhigh do begin + if bkpton[int1] then begin + gdb.breakenable(bkptno[int1],bo1); + end; + end; + gdb.restarttarget; + end; +end; + +procedure tbreakpointsfo.bkptsononsetvalue( + const sender: TObject; var avalue: boolean; var accept: Boolean); +begin + actionsmo.bkptsonact.checked:= avalue; +end; + +procedure tbreakpointsfo.breakpointsonshow(const sender: TObject); +begin + refresh; +end; + +procedure tbreakpointsfo.gridoncellevent(const sender: TObject; + var info: celleventinfoty); +begin + if iscellclick(info,[ccr_dblclick]) then begin + sourcefo.showsourceline(path[info.cell.row],line[info.cell.row]-1,0,true); + end; +end; + +procedure tbreakpointsfo.gridonrowsdeleted(const sender: tcustomgrid; + const aindex: Integer; const acount: Integer); +begin + changed; +end; + +procedure tbreakpointsfo.gridonrowsdeleting(const sender: tcustomgrid; + var aindex, acount: integer); +var + int1,int2: integer; + info: bkptlineinfoty; +begin + if gdb.execloaded then begin + for int1:= aindex to aindex + acount - 1 do begin + int2:= bkptno[int1]; + if int2 > 0 then begin + gdb.breakdelete(int2); + end; + end; + end; + for int1:= aindex to aindex + acount - 1 do begin + info.line:= line[int1]; + if info.line > 0 then begin + info.state:= bkpts_none; + sourcefo.updatebreakpointicon(path[int1],info); + end; + end; +end; + +procedure tbreakpointsfo.deletebreakpoint(var info: breakpointinfoty); +var + int1: integer; + wstr1: msestring; +begin + wstr1:= msefileutils.filename(info.path); + for int1:= grid.rowcount - 1 downto 0 do begin + if (line[int1] = info.line) and (filename[int1] = wstr1) then begin + grid.deleterow(int1); + end; + end; +end; + +function tbreakpointsfo.infotolineinfo( + const info: breakpointinfoty): bkptlineinfoty; +begin + result.line:= info.line; + if info.bkpton then begin + if info.conditionmessage <> '' then begin + result.state:= bkpts_error; + end + else begin + result.state:= bkpts_normal; + end; + end + else begin + result.state:= bkpts_disabled; + end; +end; + +function tbreakpointsfo.getbreakpointlines( + const filepath: filenamety): bkptlineinfoarty; +var + int1,int2: integer; + wstr1: filenamety; +begin + int2:= 0; + wstr1:= msefileutils.filename(filepath); + setlength(result,grid.rowcount); + for int1:= 0 to grid.rowcount - 1 do begin + if issamefilename(filename[int1],wstr1) then begin + with result[int2] do begin + line:= self.line[int1]; + if bkpton[int1] then begin + state:= bkpts_normal; + end + else begin + state:= bkpts_disabled; + end; + end; + inc(int2); + end; + end; + setlength(result,int2); +end; + +function tbreakpointsfo.breakpointerror(const error: gdbresultty; + out errme: msestring): boolean; +var + str1: msestring; +begin + result:= error <> gdb_ok; + errme:= ''; + if result then begin + if error = gdb_message then begin + str1:= msestring(gdb.errormessage); + end + else begin + str1:= c[ord(breakpointerror0)]; + end; + errme:= str1; + showmessage(str1,c[ord(breakpointerror1)]); + end; +end; + +procedure tbreakpointsfo.insertbkpt(index: integer; + withcondition,witherrormessage: boolean); +var + info: breakpointinfoty; + str1: string; + mstr1: msestring; +begin + fillchar(info,sizeof(info),0); + listtoinfo(index,info); + str1:= info.condition; + if not withcondition then begin + info.condition:= ''; + end; + if gdb.execloaded then begin + if witherrormessage then begin + if breakpointerror(gdb.breakinsert(info),mstr1) then begin + errormessage[index]:= mstr1; + end; + end + else begin + gdb.breakinsert(info); + end; + end; + info.condition:= str1; + infotolist(index,info,true); +end; + +function tbreakpointsfo.addbreakpoint(var info: breakpointinfoty): boolean; +var + int1: integer; + info1: breakpointinfoty; +begin + info1:= info; + info1.bkpton:= info1.bkpton and bkptson.value; + if gdb.execloaded then begin + result:= gdb.breakinsert(info1) = gdb_ok; + end + else begin + result:= true; + end; + if result then begin + if (grid.rowcount = 0) or + not grid.datacols.rowempty(grid.rowcount - 1) then begin + int1:= grid.appendrow; + end + else begin + int1:= grid.rowcount - 1; + end; + info1.bkpton:= info.bkpton; + infotolist(int1,info1,false); + changed; + end; +end; + +procedure tbreakpointsfo.updatebreakpoints; +var + int1: integer; +begin + if gdb.active then begin + gdb.breakdelete(0); + flags.fillcol(0); +// gdb.breakinsert('main'); + for int1:= 0 to grid.rowhigh do begin + insertbkpt(int1,false,false); + end; + fbreakpointsvalid:= true; + end + else begin + fbreakpointsvalid:= false; + end; +end; + +function tbreakpointsfo.findbreakpointrow(const anum: integer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to grid.rowhigh do begin + if bkptno[int1] = anum then begin + result:= int1; + break; + end; + end; +end; + +function tbreakpointsfo.checkbreakpointcontinue( + const stopinfo: stopinfoty): boolean; + //set condition +var + int1: integer; + str1,str2: string; + ptrint1: ptruint; + inf1: breakpointinfoty; + mstr1: msestring; +begin + result:= false; + if (stopinfo.reason = sr_breakpoint_hit) then begin + int1:= findbreakpointrow(stopinfo.bkptno); + if int1 >= 0 then begin + if (condition[int1] <> '') and (flags[int1] = 0) then begin + flags[int1]:= 1; + str1:= ansistring(condition[int1]); + if breakpointerror(gdb.breakcondition(stopinfo.bkptno,str1), + mstr1) then begin + conderr[int1]:= 0; + errormessage[int1]:= mstr1; + end + else begin + conderr[int1]:= -1; + gdb.evaluateexpression(str1,str2); + if not (str2 = 'true') or trystrtoptruint(str2,ptrint1) and + (ptrint1 <> 0) then begin + flags[int1]:= 2; //count has to be decremented + result:= true; + end; + end; + listtoinfo(int1,inf1); + infotolist(int1,inf1,true); + end; + end; + end; +end; + +function tbreakpointsfo.isactivebreakpoint(const addr: qword): boolean; +var + int1: integer; + po1: pqwordaty; + po2: plongboolaty; +begin + result:= false; + po1:= address.griddata.datapo; + po2:= bkpton.griddata.datapo; + for int1:= 0 to grid.rowhigh do begin + if po2^[int1] and (po1^[int1] = addr) then begin + result:= true; + break; + end; + end; +end; + +procedure tbreakpointsfo.toggleaddrbreakpoint(const addr: qword); +var + int1: integer; + po1: pqwordaty; + info1: breakpointinfoty; +begin + po1:= address.griddata.datapo; + for int1:= 0 to grid.rowhigh do begin + if po1^[int1] = addr then begin + if addressbkpt[int1] then begin + grid.deleterow(int1); + end + else begin + bkpton[int1]:= not bkpton[int1]; + updaterow(int1); + end; + exit; + end; + end; + fillchar(info1,sizeof(info1),0); + info1.address:= addr; + info1.addressbreakpoint:= true; + info1.bkpton:= true; + addbreakpoint(info1); +end; + +function tbreakpointsfo.updatebreakpointon(var info: breakpointinfoty): boolean; +var + int1: integer; + wstr1: filenamety; +begin + result:= true; + wstr1:= msefileutils.filename(info.path); + for int1:= grid.rowcount - 1 downto 0 do begin + if (line[int1] = info.line) and (filename[int1] = wstr1) then begin + bkpton[int1]:= info.bkpton; + if gdb.execloaded then begin + result:= gdb.breakenable(bkptno[int1],info.bkpton and + bkptson.value) = gdb_ok; + end; + if conderr[int1] >= 0 then begin + info.conditionmessage:= ' '; + end + else begin + info.conditionmessage:= ''; + end; + sourcefo.updatebreakpointicon(path[int1],infotolineinfo(info)); + if not result then begin + break; + end; + end; + end; + changed; +end; + +procedure tbreakpointsfo.ononsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + if gdb.execloaded then begin + gdb.breakenable(bkptno.value,avalue and bkptson.value) + end; +end; + +procedure tbreakpointsfo.ignoreonsetvalue(const sender: TObject; + var avalue: Integer; var accept: Boolean); +begin + if gdb.execloaded then begin + gdb.breakafter(bkptno.value,avalue) + end; +end; + +procedure tbreakpointsfo.conditiononsetvalue(const sender: TObject; + var avalue: mseString; var accept: Boolean); +var + mstr1: msestring; +begin + if gdb.execloaded then begin + if breakpointerror(gdb.breakcondition(bkptno.value,ansistring(avalue)), + mstr1) then begin + conderr.value:= 0; + errormessage.value:= mstr1; + end + else begin + conderr.value:= -1; + end; + end; +end; + +procedure tbreakpointsfo.updaterow(const arow: integer); +var + info: breakpointinfoty; +begin + fillchar(info,sizeof(info),0); + listtoinfo(arow,info); + infotolist(arow,info,true); + changed; +end; + +procedure tbreakpointsfo.ondataentered(const sender: tobject); +begin + updaterow(grid.row); +end; + +procedure tbreakpointsfo.newbkpt(const addressbp: boolean); +begin + addressbkpt.value:= addressbp; + insertbkpt(grid.row,true,true); + changed; +end; + +procedure tbreakpointsfo.ondataenterednewbkpt(const sender: tobject); +begin + newbkpt(false); +end; + +procedure tbreakpointsfo.addressentered(const sender: TObject); +begin + filename.value:= ''; + newbkpt(true); +end; + +procedure tbreakpointsfo.removeactbreakpoint; +var + int1,int2: integer; +begin + int1:= grid.row; + int2:= 1; + gridonrowsdeleting(nil,int1,int2); +end; + +procedure tbreakpointsfo.lineonsetvalue(const sender: TObject; + var avalue: Integer; var accept: Boolean); +begin + removeactbreakpoint; +end; + +procedure tbreakpointsfo.filenameonsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + removeactbreakpoint; + path.value:= filepath(avalue); +end; + +procedure tbreakpointsfo.sourcelinesdeleted(const filepath: msestring; + const aindex, acount: integer); +var + int1: integer; +begin + for int1:= grid.rowcount - 1 downto 0 do begin + if (line[int1] >= aindex) and (path[int1] = filepath) then begin + if line[int1] < aindex + acount then begin + grid.deleterow(int1); + end + else begin + line[int1]:= line[int1] - acount; + end; + end; + end; + changed; +end; + +procedure tbreakpointsfo.sourcelinesinserted(const filepath: msestring; + const aindex, acount: integer); +var + int1: integer; +begin + for int1:= 0 to grid.rowcount - 1 do begin + if (line[int1] >= aindex) and (path[int1] = filepath) then begin + line[int1]:= line[int1] + acount; + end; + end; + changed; +end; + +procedure tbreakpointsfo.changed; +begin + fbreakpointsvalid:= false; + with projectoptions do begin + modified:= true; + addressbreakpoints:= addressbkpt.gridvalues; + breakpointons:= bkpton.gridvalues; + breakpointpaths:= path.gridvalues; + breakpointlines:= line.gridvalues; + breakpointaddress:= address.gridvalues; + breakpointignore:= ignore.gridvalues; + breakpointconditions:= condition.gridvalues; + end; + disassfo.invalidate; +end; + +procedure tbreakpointsfo.refresh; +var + breakpoints: breakpointinfoarty; + int1,int2: integer; +// po1: pintegeraty; +begin + if gdb.active and (visible or watchpointsfo.visible) then begin + gdb.breaklist(breakpoints,false); + if visible then begin + for int1:= 0 to grid.rowhigh do begin + count[int1]:= 0; + for int2:= 0 to high(breakpoints) do begin + with breakpoints[int2] do begin + if bkptno = self.bkptno[int1] then begin + count[int1]:= passcount; + end; + end; + end; + end; +{ + po1:= bkptno.griddata.datapo; + for int1:= 0 to high(breakpoints) do begin + with breakpoints[int1] do begin + for int2:= 0 to grid.rowhigh do begin + if po1^[int2] = bkptno then begin + count[int2]:= passcount; + end; + end; + end; + end; +} + end; + if watchpointsfo.visible then begin + watchpointsfo.refresh(breakpoints); + end; + end; +end; + +procedure tbreakpointsfo.showbreakpoint(const filepath: filenamety; + const aline: integer; const focus: boolean); +var + int1: integer; +begin + for int1:= 0 to grid.rowhigh do begin + if (line[int1] = aline) and issamefilename(filepath,path[int1]) then begin + grid.row:= int1; + show; + if focus then begin + grid.setfocus; + window.bringtofront; + end; + end; + end; +end; + +procedure tbreakpointsfo.showbreakpoint(const aaddress: int64; focus: boolean); +var + int1: integer; +begin + for int1:= 0 to grid.rowhigh do begin + if address[int1] = aaddress then begin + grid.row:= int1; + show(); + if focus then begin + grid.setfocus(); + window.bringtofront(); + end; + end; + end; +end; + +procedure tbreakpointsfo.deleteallexecute(const sender: TObject); +begin + if askok(c[ord(delbr)],c[ord(confirmation)]) then begin + grid.deleterow(0,grid.rowcount); + end; +end; + +procedure tbreakpointsfo.clear; +begin + grid.clear; +end; + +procedure tbreakpointsfo.adbefdrawcell(const sender: tcol; + const canvas: tcanvas; var cellinfo: cellinfoty; + var processed: Boolean); +begin + with cellinfo do begin + if not addressbkpt[cell.row] then begin + color:= cl_active; + end; + end; +end; + +procedure tbreakpointsfo.errhint(const sender: tdatacol; const arow: Integer; + var info: hintinfoty); +begin + if conderr[arow] >= 0 then begin + info.caption:= errormessage[arow]; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/breakpointsform_mfm.pas b/mseide-msegui/apps/ide/breakpointsform_mfm.pas new file mode 100644 index 0000000..d65f13f --- /dev/null +++ b/mseide-msegui/apps/ide/breakpointsform_mfm.pas @@ -0,0 +1,569 @@ +unit breakpointsform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,breakpointsform; + +const + objdata: record size: integer; data: array[0..11030] of byte end = + (size: 11031; data: ( + 84,80,70,48,14,116,98,114,101,97,107,112,111,105,110,116,115,102,111,13, + 98,114,101,97,107,112,111,105,110,116,115,102,111,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103, + 114,105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105, + 112,95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98, + 117,116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116, + 111,110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111, + 95,116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114, + 111,117,110,100,98,117,116,116,111,110,15,103,111,95,110,111,108,111,99,107, + 98,117,116,116,111,110,0,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,2,107,8,98,111,117,110,100,115,95,121,3,148,1,9, + 98,111,117,110,100,115,95,99,120,3,124,2,9,98,111,117,110,100,115,95, + 99,121,3,128,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97, + 105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100, + 115,1,2,0,2,0,3,114,2,3,128,0,0,22,100,114,97,103,100,111, + 99,107,46,115,112,108,105,116,116,101,114,95,115,105,122,101,2,0,20,100, + 114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111,99,107,11, + 10,111,100,95,115,97,118,101,112,111,115,13,111,100,95,115,97,118,101,122, + 111,114,100,101,114,10,111,100,95,99,97,110,109,111,118,101,11,111,100,95, + 99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107,11, + 111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116,105, + 111,110,104,105,110,116,0,7,111,112,116,105,111,110,115,11,10,102,111,95, + 115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101, + 114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116, + 102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116, + 115,116,97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,11,66,114, + 101,97,107,112,111,105,110,116,115,21,105,99,111,110,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,10,105,99,111, + 110,46,105,109,97,103,101,10,0,7,0,0,0,0,0,0,0,0,0,0, + 24,0,0,0,24,0,0,0,204,6,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1, + 223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1, + 229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1, + 221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1, + 232,232,232,1,225,225,230,1,185,185,234,1,137,137,238,1,136,136,237,1, + 181,181,230,1,219,219,224,1,221,221,221,1,219,219,219,1,218,218,218,1, + 216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,228,228,234,1,113,113,244,1, + 7,7,254,1,0,0,255,4,7,7,254,1,106,106,237,1,213,213,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,197,197,238,1,40,40,251,1, + 0,0,255,8,31,31,242,1,180,180,221,1,215,215,215,2,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,231,231,237,1,41,41,252,1, + 0,0,255,10,24,24,235,1,197,197,203,1,214,214,214,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,115,115,246,1,0,0,255,12, + 54,54,185,1,201,201,201,1,212,212,212,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 233,233,238,1,7,7,254,1,0,0,255,12,3,3,250,1,134,134,139,1, + 210,210,210,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,192,192,241,1,0,0,255,14, + 81,81,130,1,176,176,176,1,210,210,210,2,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,144,144,245,1,0,0,255,14, + 60,60,161,1,145,145,145,1,209,209,209,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,144,144,245,1, + 0,0,255,14,59,59,160,1,122,122,122,1,209,209,209,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 192,192,241,1,0,0,255,14,78,78,127,1,106,106,106,1,208,208,208,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,233,233,238,1,7,7,254,1,0,0,255,12,3,3,250,1, + 96,96,101,1,122,122,122,1,209,209,209,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 114,114,245,1,0,0,255,12,47,47,178,1,99,99,99,1,145,145,145,1, + 209,209,209,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,230,230,236,1,33,33,244,1, + 0,0,255,10,17,17,228,1,95,95,101,1,100,100,100,1,176,176,176,1, + 210,210,210,2,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,194,194,235,1,26,26,237,1, + 0,0,255,8,17,17,228,1,82,82,123,1,99,99,99,1,137,137,137,1, + 210,210,210,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 234,234,234,1,213,213,219,1,58,58,189,1,3,3,250,1,0,0,255,4, + 3,3,250,1,49,49,180,1,97,97,103,1,100,100,100,1,112,112,112,1, + 201,201,201,1,212,212,212,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,233,233,233,1,217,217,217,1,143,143,148,1, + 86,86,135,1,63,63,164,1,62,62,163,1,82,82,131,1,99,99,104,1, + 101,101,101,2,138,138,138,1,202,202,202,1,214,214,214,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,231,231,231,1,227,227,227,1,189,189,189,1,154,154,154,1, + 129,129,129,1,112,112,112,1,128,128,128,1,150,150,150,1,181,181,181,1, + 215,215,215,3,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1, + 228,228,228,1,225,225,225,1,223,223,223,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,2,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1, + 224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1, + 216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,6,111,110,115,104,111,119,7,17,98,114,101,97,107,112,111, + 105,110,116,115,111,110,115,104,111,119,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115, + 99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100, + 101,114,2,1,9,112,111,112,117,112,109,101,110,117,7,8,103,114,105,112, + 111,112,117,112,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,24,9,98,111,117,110,100,115,95,99,120,3,114,2,9, + 98,111,117,110,100,115,95,99,121,2,104,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111, + 112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105, + 122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103, + 95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119, + 105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101, + 116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101, + 110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119, + 13,111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111, + 108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119, + 114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0, + 13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120, + 99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,20, + 8,110,117,109,115,116,97,114,116,2,1,7,110,117,109,115,116,101,112,2, + 1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13, + 102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103, + 104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2, + 11,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99, + 97,112,116,105,111,110,6,2,111,110,0,1,7,99,97,112,116,105,111,110, + 6,4,70,105,108,101,0,1,0,1,7,99,97,112,116,105,111,110,6,8, + 76,105,110,101,32,78,114,46,0,1,7,99,97,112,116,105,111,110,6,7, + 65,100,100,114,101,115,115,0,1,0,1,0,1,7,99,97,112,116,105,111, + 110,6,5,67,111,117,110,116,0,1,7,99,97,112,116,105,111,110,6,6, + 73,103,110,111,114,101,0,1,0,1,7,99,97,112,116,105,111,110,6,9, + 67,111,110,100,105,116,105,111,110,0,0,0,0,14,100,97,116,97,99,111, + 108,115,46,99,111,117,110,116,2,13,14,100,97,116,97,99,111,108,115,46, + 105,116,101,109,115,14,7,6,98,107,112,116,111,110,1,12,108,105,110,101, + 99,111,108,111,114,102,105,120,4,3,0,0,160,5,119,105,100,116,104,2, + 16,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95,115, + 97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110,97,109,101, + 6,6,98,107,112,116,111,110,9,100,97,116,97,99,108,97,115,115,7,20, + 116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116, + 0,7,8,102,105,108,101,110,97,109,101,1,12,108,105,110,101,99,111,108, + 111,114,102,105,120,4,3,0,0,160,5,119,105,100,116,104,3,158,0,7, + 111,112,116,105,111,110,115,11,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103, + 101,116,110,97,109,101,6,8,102,105,108,101,110,97,109,101,9,100,97,116, + 97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105, + 110,103,100,97,116,97,108,105,115,116,0,7,4,112,97,116,104,1,12,108, + 105,110,101,99,111,108,111,114,102,105,120,4,3,0,0,160,7,111,112,116, + 105,111,110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,12,99, + 111,95,115,97,118,101,118,97,108,117,101,0,10,119,105,100,103,101,116,110, + 97,109,101,6,4,112,97,116,104,9,100,97,116,97,99,108,97,115,115,7, + 22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108, + 105,115,116,0,7,4,108,105,110,101,1,12,108,105,110,101,99,111,108,111, + 114,102,105,120,4,3,0,0,160,7,111,112,116,105,111,110,115,11,12,99, + 111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115, + 116,97,116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,4,108,105, + 110,101,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105, + 110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,97,100,100, + 114,101,115,115,1,5,119,105,100,116,104,2,61,16,111,110,98,101,102,111, + 114,101,100,114,97,119,99,101,108,108,7,13,97,100,98,101,102,100,114,97, + 119,99,101,108,108,10,119,105,100,103,101,116,110,97,109,101,6,7,97,100, + 100,114,101,115,115,9,100,97,116,97,99,108,97,115,115,7,18,116,103,114, + 105,100,105,110,116,54,52,100,97,116,97,108,105,115,116,0,7,11,97,100, + 100,114,101,115,115,98,107,112,116,1,5,119,105,100,116,104,2,6,7,111, + 112,116,105,111,110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101, + 12,99,111,95,100,114,97,119,102,111,99,117,115,12,99,111,95,115,97,118, + 101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,11,97,100,100,114,101,115,115,98,107, + 112,116,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105, + 110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,6,98,107,112, + 116,110,111,1,12,108,105,110,101,99,111,108,111,114,102,105,120,4,3,0, + 0,160,5,119,105,100,116,104,2,19,7,111,112,116,105,111,110,115,11,12, + 99,111,95,105,110,118,105,115,105,98,108,101,12,99,111,95,115,97,118,101, + 118,97,108,117,101,0,10,119,105,100,103,101,116,110,97,109,101,6,6,98, + 107,112,116,110,111,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,5, + 99,111,117,110,116,1,5,99,111,108,111,114,4,7,0,0,144,12,108,105, + 110,101,99,111,108,111,114,102,105,120,4,3,0,0,160,5,119,105,100,116, + 104,2,31,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100, + 111,110,108,121,10,99,111,95,110,111,102,111,99,117,115,12,99,111,95,115, + 97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116, + 101,0,10,119,105,100,103,101,116,110,97,109,101,6,5,99,111,117,110,116, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,6,105,103,110,111,114, + 101,1,12,108,105,110,101,99,111,108,111,114,102,105,120,4,3,0,0,160, + 5,119,105,100,116,104,2,30,7,111,112,116,105,111,110,115,11,12,99,111, + 95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116, + 97,116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,6,105,103,110, + 111,114,101,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,99,111, + 110,100,101,114,114,1,12,108,105,110,101,99,111,108,111,114,102,105,120,4, + 3,0,0,160,5,119,105,100,116,104,2,7,7,111,112,116,105,111,110,115, + 11,11,99,111,95,114,101,97,100,111,110,108,121,10,99,111,95,110,111,102, + 111,99,117,115,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95, + 115,97,118,101,115,116,97,116,101,0,10,111,110,115,104,111,119,104,105,110, + 116,7,7,101,114,114,104,105,110,116,10,119,105,100,103,101,116,110,97,109, + 101,6,7,99,111,110,100,101,114,114,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,7,9,99,111,110,100,105,116,105,111,110,1,12,108,105,110,101, + 99,111,108,111,114,102,105,120,4,3,0,0,160,5,119,105,100,116,104,2, + 124,7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99, + 111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115, + 116,97,116,101,0,8,119,105,100,116,104,109,105,110,2,0,10,119,105,100, + 103,101,116,110,97,109,101,6,9,99,111,110,100,105,116,105,111,110,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,7,12,101,114,114,111,114, + 109,101,115,115,97,103,101,1,5,119,105,100,116,104,2,19,7,111,112,116, + 105,111,110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,12,101,114,114,111,114,109,101,115,115,97, + 103,101,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,5,102, + 108,97,103,115,1,5,119,105,100,116,104,2,17,7,111,112,116,105,111,110, + 115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,12,99,111,95,115, + 97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116, + 101,0,10,119,105,100,103,101,116,110,97,109,101,6,5,102,108,97,103,115, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,14,111,110,114,111,119,115,100,101,108, + 101,116,105,110,103,7,18,103,114,105,100,111,110,114,111,119,115,100,101,108, + 101,116,105,110,103,13,111,110,114,111,119,115,100,101,108,101,116,101,100,7, + 17,103,114,105,100,111,110,114,111,119,115,100,101,108,101,116,101,100,11,111, + 110,99,101,108,108,101,118,101,110,116,7,15,103,114,105,100,111,110,99,101, + 108,108,101,118,101,110,116,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,98,107, + 112,116,111,110,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,16,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7, + 13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,118,105,115,105,98, + 108,101,8,10,111,110,115,101,116,118,97,108,117,101,7,12,111,110,111,110, + 115,101,116,118,97,108,117,101,12,118,97,108,117,101,100,101,102,97,117,108, + 116,9,0,0,11,116,115,116,114,105,110,103,101,100,105,116,8,102,105,108, + 101,110,97,109,101,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,17,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,158,0,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,13, + 111,110,100,97,116,97,101,110,116,101,114,101,100,7,20,111,110,100,97,116, + 97,101,110,116,101,114,101,100,110,101,119,98,107,112,116,10,111,110,115,101, + 116,118,97,108,117,101,7,18,102,105,108,101,110,97,109,101,111,110,115,101, + 116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,4,112,97,116, + 104,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,3,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110, + 116,101,103,101,114,101,100,105,116,4,108,105,110,101,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,4,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,3,227,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97, + 118,101,118,97,108,117,101,0,13,111,110,100,97,116,97,101,110,116,101,114, + 101,100,7,20,111,110,100,97,116,97,101,110,116,101,114,101,100,110,101,119, + 98,107,112,116,10,111,110,115,101,116,118,97,108,117,101,7,14,108,105,110, + 101,111,110,115,101,116,118,97,108,117,101,3,109,105,110,2,1,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,10,116,105,110,116, + 54,52,101,100,105,116,7,97,100,100,114,101,115,115,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3, + 0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118, + 101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,5,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,3,22,1,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,61,9,98,111,117,110, + 100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,14,97,100,100,114, + 101,115,115,101,110,116,101,114,101,100,4,98,97,115,101,7,6,110,98,95, + 104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 11,97,100,100,114,101,115,115,98,107,112,116,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0, + 128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108, + 105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116, + 97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,84, + 1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,6,9,98,111,117,110,100,115,95,99,121,2,16,7,118,105,115, + 105,98,108,101,8,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,6,98,107,112, + 116,110,111,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,8,116,97,98,111,114,100,101,114,2,7,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,91,1,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,19,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,5,99,111,117,110,116,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,8,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,3,111,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,31,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97, + 118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,6, + 105,103,110,111,114,101,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,9,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,143,1,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,30,9, + 98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,24,111,101,95,102,111,114,99, + 101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,13,111,110, + 100,97,116,97,101,110,116,101,114,101,100,10,111,110,115,101,116,118,97,108, + 117,101,7,16,105,103,110,111,114,101,111,110,115,101,116,118,97,108,117,101, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116, + 100,97,116,97,105,99,111,110,7,99,111,110,100,101,114,114,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,10,8,98, + 111,117,110,100,115,95,120,3,174,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,7,9,98,111,117,110,100,115, + 95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111, + 101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,9,105,109,97, + 103,101,108,105,115,116,7,21,97,99,116,105,111,110,115,109,111,46,98,117, + 116,116,111,110,105,99,111,110,115,11,105,109,97,103,101,111,102,102,115,101, + 116,2,10,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,11,116,115,116,114,105,110,103,101,100,105,116,9,99,111,110,100,105,116, + 105,111,110,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,8,116,97,98,111,114,100,101,114,2,11,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,182,1,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,124,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,12,111,101,95,116,114,105,109,114,105,103,104,116,11,111,101, + 95,116,114,105,109,108,101,102,116,0,13,111,110,100,97,116,97,101,110,116, + 101,114,101,100,7,13,111,110,100,97,116,97,101,110,116,101,114,101,100,10, + 111,110,115,101,116,118,97,108,117,101,7,19,99,111,110,100,105,116,105,111, + 110,111,110,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105, + 116,12,101,114,114,111,114,109,101,115,115,97,103,101,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,12,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,51,2,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,19, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,5,102,108,97,103, + 115,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,13,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,3,71,2,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,17,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,7,98,107,112,116,115,111,110,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,15,66,114,101,97,107,112,111,105,110, + 116,115,32,38,111,110,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,98,2,2,0,8,98,111,117,110,100,115,95, + 120,2,8,8,98,111,117,110,100,115,95,121,2,4,9,98,111,117,110,100, + 115,95,99,120,2,111,9,98,111,117,110,100,115,95,99,121,2,16,8,115, + 116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106, + 101,99,116,115,116,97,116,102,105,108,101,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,8, + 111,110,99,104,97,110,103,101,7,15,98,107,112,116,115,111,110,111,110,99, + 104,97,110,103,101,10,111,110,115,101,116,118,97,108,117,101,7,17,98,107, + 112,116,115,111,110,111,110,115,101,116,118,97,108,117,101,5,118,97,108,117, + 101,9,0,0,10,116,112,111,112,117,112,109,101,110,117,8,103,114,105,112, + 111,112,117,112,18,109,101,110,117,46,115,117,98,109,101,110,117,46,99,111, + 117,110,116,2,1,18,109,101,110,117,46,115,117,98,109,101,110,117,46,105, + 116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,10,68,101,108,101, + 116,101,32,97,108,108,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,16, + 100,101,108,101,116,101,97,108,108,101,120,101,99,117,116,101,0,0,9,109, + 101,110,117,46,110,97,109,101,6,9,103,114,105,100,112,111,112,117,112,4, + 108,101,102,116,3,168,0,0,0,16,116,115,116,114,105,110,103,99,111,110, + 116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116, + 97,1,6,17,66,114,101,97,107,112,111,105,110,116,32,101,114,114,111,114, + 46,6,16,66,82,69,65,75,80,79,73,78,84,32,69,82,82,79,82,6, + 38,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,100,101,108,101, + 116,101,32,97,108,108,32,98,114,101,97,107,112,111,105,110,116,115,63,6, + 12,67,111,110,102,105,114,109,97,116,105,111,110,0,4,108,101,102,116,3, + 88,1,3,116,111,112,2,80,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tbreakpointsfo,''); +end. diff --git a/mseide-msegui/apps/ide/cdesignparser.pas b/mseide-msegui/apps/ide/cdesignparser.pas new file mode 100644 index 0000000..7833144 --- /dev/null +++ b/mseide-msegui/apps/ide/cdesignparser.pas @@ -0,0 +1,637 @@ +{ MSEide Copyright (c) 2012 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cdesignparser; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseparser,msedesignparser,mselist,msestrings,msehash; + +type + + tcdesignparser = class(tcparser,idesignparser) + private + funitinfopo: punitinfoty; +// fimplementation: boolean; +// finterface: boolean; + finterfaceonly: boolean; + fnoautoparse: boolean; + ffunctionlevel: integer; + protected + function parsefunction: boolean; + function parsefunctionparams: boolean; + function parseblock: boolean; + function parsetypedef: boolean; + function parsevardef: boolean; + function parsestatement: boolean; + public + constructor create(unitinfopo: punitinfoty; + const afilelist: tmseindexednamelist; + const getincludefile: getincludefileeventty; + const ainterfaceonly: boolean); overload; + constructor create(const afilelist: tmseindexednamelist; + const atext: string); overload; + procedure initidents; override; + function dogetincludefile(const afilename: filenamety; + const astatementstart,astatementend: sourceposty): tscanner; override; + procedure parse; override; + procedure clear; override; + end; + + tcfunctions = class(tfunctions) + end; + + tcunitinfo = class(tunitinfo) + public + constructor create; + destructor destroy; override; + end; + + tcrootdeflist = class(trootdeflist) + protected + procedure finalizerecord(var item); override; + end; + + cglobfuncinfoty = record + list: tcrootdeflist; + id: integer; + end; + pcglobfuncinfoty = ^cglobfuncinfoty; + cglobfunchashdataty = record + header: hashheaderty; + data: cglobfuncinfoty; + end; + pcglobfunchashdataty = ^cglobfunchashdataty; + + tcglobals = class(thashdatalist) + private + fclosing: boolean; + flistparam: tcrootdeflist; + fidparam: integer; + fansistringparam: ansistring; + procedure checkfunctioninfo(const aitem: phashdataty; var accept: boolean); + procedure checkfindname(var stop: boolean); + protected + procedure add(const alist: tcrootdeflist; const aid: integer); +// procedure checkexact(const aitemdata; var accept: boolean); override; + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + procedure delete(const alist: tcrootdeflist; const aid: integer); + function checkfind(const aname: ansistring): pcglobfuncinfoty; + function getrecordsize(): int32 override; + public + property closing: boolean read fclosing; +// constructor create; + function finddef(const aname: ansistring): pdefinfoty; + function findfunction(const aname: ansistring): pfunctioninfoty; + end; + + tcprocdeflist = class(tdeflist) + end; + +procedure parsecdef(const adef: pdefinfoty; out atext: string; out scope: tdeflist); +function cglobals: tcglobals; +procedure beginfinalizecglobals; +procedure finalizecglobals; + +implementation +uses + sourceupdate,msedesigner,sysutils,projecttreeform; +var + fcglobals: tcglobals; + +function cglobals: tcglobals; +begin + if fcglobals = nil then begin + fcglobals:= tcglobals.create; + end; + result:= fcglobals; +end; + +procedure finalizecglobals; +begin + freeandnil(fcglobals); +end; + +procedure beginfinalizecglobals; +begin + if fcglobals <> nil then begin + fcglobals.fclosing:= true; + end; +end; + +procedure parsecdef(const adef: pdefinfoty; out atext: string; out scope: tdeflist); + //add used identifiers +var + parser: tcparser; + + procedure doaddidents; + begin + with parser do begin + while checkoperator('*') do begin + end; + scope.addidentpath(parser,'.'); + if checkoperator('[') then begin + findoperator(']'); + end; + while checkoperator('*') do begin + end; + scope.addidentpath(parser,'.'); + end; + end; + + procedure dofunctionparameters; + begin + with parser do begin + while not eof do begin + doaddidents; //type, parameter + if checkoperator(')') then begin + break; + end; + if not checkoperator(';') then begin + nexttoken; + end; + end; + end; + end; + +begin + scope:= tdeflist.create(adef^.kind,true); + atext:= sourceupdater.getdefinfotext(adef); + if atext <> '' then begin + parser:= tcparser.create(designer.designfiles,atext); + try + with parser do begin + doaddidents; //type, function name + if checkoperator('(') then begin + dofunctionparameters; + end; + if checkoperator('{') then begin + repeat + doaddidents; + if checkoperator('=') then begin //assignment + doaddidents; + checkoperator(';'); + end + else begin + if checkoperator('(') then begin + dofunctionparameters; + end + else begin + nexttoken; + end; + end; + until eof or checkoperator('}'); + end; + end; + finally + parser.free; + end; + end; +end; + +{ tcdesignparser } + +constructor tcdesignparser.create(unitinfopo: punitinfoty; + const afilelist: tmseindexednamelist; + const getincludefile: getincludefileeventty; + const ainterfaceonly: boolean); +begin + finterfaceonly:= ainterfaceonly; + inherited create(afilelist); + funitinfopo:= unitinfopo; + funitinfopo^.interfacecompiled:= false; + funitinfopo^.implementationcompiled:= false; + ongetincludefile:= getincludefile; +end; + +constructor tcdesignparser.create(const afilelist: tmseindexednamelist; + const atext: string); +begin + fnoautoparse:= true; + inherited create(afilelist,atext); +end; + +{ +constructor tcdesignparser.create(unitinfopo: punitinfoty; + const afilelist: tmseindexednamelist; + const getincludefile: getincludefileeventty; + const ainterfaceonly: boolean; const atext: ansistring); +begin + create(unitinfopo,afilelist,getincludefile,ainterfaceonly); + create(afilelist,atext); +end; +} +function tcdesignparser.parsetypedef: boolean; +begin + result:= false; +end; + +function tcdesignparser.parsevardef: boolean; +begin + result:= false; +end; + +function tcdesignparser.parsefunctionparams: boolean; +begin + result:= false; + mark; + if checkoperator('(') then begin + result:= findoperator(')'); + end; + if result then begin + pop; + end + else begin + back; + end; +end; + +function tcdesignparser.parseblock: boolean; +var + ch1: char; +begin + result:= true; + skipwhitespace; + mark; + if checkoperator('{') then begin + while not eof do begin + ch1:= getoperator; + case ch1 of + '}': begin + break; + end; + '{': begin + parseblock(); + end; + else begin + parsestatement; + end; + end; + end; + end; + if result then begin + pop; + end + else begin + back; + end; +end; + +function tcdesignparser.parsefunction: boolean; //todo: optimize +var + {lstr1,}lstr2: lstringty; + str1: string; +// ch1: char; + pos1: sourceposty; +// po1: pfunctioninfoty; + po2: pfunctionheaderinfoty; + static: boolean; + bo1: boolean; +begin + inc(ffunctionlevel); + result:= false; + skipwhitespace; + mark; + pos1:= sourcepos; + with funitinfopo^ do begin + static:= false; + bo1:= false; + while not eof do begin + case fto^.kind of + tk_name: begin + if checkident(ord(cid_static)) then begin + static:= true; + end + else begin + nexttoken; + end; + end; + tk_operator: begin + if fto^.op = '(' then begin + bo1:= true; + break; + end + else begin + if fto^.op = ';' then begin + break; + end; + nexttoken; + end; + end; + else begin + nexttoken; + end; + end; + end; + if bo1 then begin + lastnonwhitetoken; + if getorigname(lstr2) then begin //function name + if parsefunctionparams then begin + if (ffunctionlevel = 1) and testoperator(';') then begin + po2:= c.functionheaders.newitem; + po2^.name:= lstringtostring(lstr2); + deflist.add(pos1,sourcepos,po2); + nexttoken; + result:= true; //header + end + else begin + if testoperator('{') then begin + result:= true; + str1:= lstringtostring(lstr2); + with deflist.beginnode(str1,syk_procimp,pos1,sourcepos)^ do begin + //new scope + if ffunctionlevel = 1 then begin + include(symbolflags,syf_global); + c.functions.add(str1,pos1,sourcepos); + end; + end; + parseblock; + deflist.endnode(sourcepos); + if not static and (ffunctionlevel = 1) then begin + cglobals.add(tcrootdeflist(deflist),deflist.infocount-1); + end; + end; + end; + end; + end; + end; + end; + if result then begin + pop; + end + else begin + back; + end; + dec(ffunctionlevel); +end; + +function tcdesignparser.parsestatement: boolean; +var + lstr1{,lstr2}: lstringty; + ch1: char; + bo1: boolean; + pos1: sourceposty; +begin + result:= true; + bo1:= ffunctionlevel = 0; + skipwhitespace; + mark; + if not bo1 then begin //in function body + skipidents; //remove keywords + pos1:= sourcepos; + if getnamenoident(lstr1) then begin + repeat + ch1:= getoperator; + case ch1 of + '(': begin + funitinfopo^.deflist.actnode.startident(pos1,lstr1.len); +// funitinfopo^.deflist.actnode.addident(pos1,lstr1.len); + findclosingbracket; //function call + funitinfopo^.deflist.actnode.endident(self); + end; + '=': begin + skipstatement; //assignment + break; + end; + ';': begin + break; + end; + else begin + bo1:= true; + break; + end; + end; + until ch1 = #0; + end + else begin + if checkoperator('{') then begin + parseblock; + end + else begin + bo1:= true; + end; + end; + end; + if bo1 then begin + back; + if not parsefunction then begin + if not parsetypedef then begin + if not parsevardef then begin + skipstatement; + end; + end; + end; + end + else begin + pop; + end; +end; + +procedure tcdesignparser.parse; +//var +// po1: pfunctioninfoty; +// int1: integer; +begin + inherited; + if fnoautoparse then begin + exit; + end; + initcompinfo(funitinfopo^); + while not eof do begin + parsestatement; + end; + afterparse(self,funitinfopo^,true); + projecttree.cmodules.modulecompiled(funitinfopo^.sourcefilename); +end; + +procedure tcdesignparser.clear; +begin + inherited; + ffunctionlevel:= 0; +end; + +function tcdesignparser.dogetincludefile(const afilename: filenamety; + const astatementstart: sourceposty; + const astatementend: sourceposty): tscanner; +begin + result:= inherited dogetincludefile(afilename,astatementstart,astatementend); + if result <> nil then begin + addincludefile(funitinfopo^,afilename,astatementstart,astatementend); + end; +end; + +procedure tcdesignparser.initidents; +begin + setidents(cidents); +end; + +{ tcunitinfo } + +constructor tcunitinfo.create; +begin + with info do begin + proglang:= pl_c; + c.functionheaders:= tfunctionheaders.create; + c.functions:= tcfunctions.create; + if deflist = nil then begin + deflist:= tcrootdeflist.create(@info); + end; + end; + inherited; +end; + +destructor tcunitinfo.destroy; +//var +// int1: integer; +// po1: pfunctioninfoty; +begin + with info do begin + c.functionheaders.free; + c.functions.free; + end; + inherited; +end; + +{ tcglobals } +{ +constructor tcglobals.create; +begin + inherited create(sizeof(cglobfuncinfoty)); +end; +} +procedure tcglobals.add(const alist: tcrootdeflist; const aid: integer); +var + po1: pcglobfunchashdataty; +begin + with alist.finfos[aid] do begin + po1:= pcglobfunchashdataty(internaladd(name)); + end; + with po1^.data do begin + list:= alist; + id:= aid; + end; +end; + +function tcglobals.hashkey(const akey): hashvaluety; +begin + result:= stringhash(ansistring(akey)); +end; + +procedure tcglobals.checkfunctioninfo(const aitem: phashdataty; + var accept: boolean); +begin + with pcglobfunchashdataty(aitem)^.data do begin + accept:= (list = flistparam) and (id = fidparam); + end; +end; + +procedure tcglobals.delete(const alist: tcrootdeflist; const aid: integer); +var + po1: phashdataty; +begin + flistparam:= alist; + fidparam:= aid; + with alist.finfos[aid] do begin + po1:= internalfind(name,{$ifdef FPC}@{$endif}checkfunctioninfo); + end; + if po1 <> nil then begin + internaldeleteitem(po1); + end; +end; + +function tcglobals.checkkey(const akey; const aitem: phashdataty): boolean; +begin + with pcglobfunchashdataty(aitem)^.data do begin + with list.finfos[id] do begin + result:= ansistring(akey) = name; + end; + end; +end; + +procedure tcglobals.checkfindname(var stop: boolean); +begin + stop:= internalfind(fansistringparam) <> nil; +end; + +function tcglobals.checkfind(const aname: ansistring): pcglobfuncinfoty; +var + po1: pcglobfunchashdataty; +begin + result:= nil; + po1:= pcglobfunchashdataty(internalfind(aname)); + if po1 = nil then begin + fansistringparam:= aname; + projecttree.cmodules.parse({$ifdef FPC}@{$endif}checkfindname); + po1:= pcglobfunchashdataty(internalfind(aname)); + end; + if po1 <> nil then begin + result:= @po1^.data; + end; +end; + +function tcglobals.getrecordsize(): int32; +begin + result:= sizeof(cglobfunchashdataty); +end; + +function tcglobals.finddef(const aname: ansistring): pdefinfoty; +var + po1: pcglobfuncinfoty; +begin + result:= nil; + po1:= checkfind(aname); + if po1 <> nil then begin + with po1^ do begin + result:= @list.finfos[id]; + end; + end; +end; + +function tcglobals.findfunction(const aname: ansistring): pfunctioninfoty; +var + po1: pcglobfunchashdataty; +begin + result:= nil; + po1:= pcglobfunchashdataty(internalfind(aname)); + if po1 <> nil then begin + with po1^.data do begin + with list.unitinfopo^ do begin + if proglang = pl_c then begin + result:= c.functions.find(aname); + end; + end; + end; + end; +end; + +{ tcrootdeflist } + +procedure tcrootdeflist.finalizerecord(var item); +begin + if (fcglobals <> nil) and not fcglobals.closing then begin + with finfos[defnamety(item).id] do begin + if (kind = syk_procimp) and (syf_global in symbolflags) then begin + fcglobals.delete(self,defnamety(item).id); + end; + end; + end; + inherited; +end; +initialization +finalization + finalizecglobals; +end. diff --git a/mseide-msegui/apps/ide/commandlineform.mfm b/mseide-msegui/apps/ide/commandlineform.mfm new file mode 100644 index 0000000..9dd3098 --- /dev/null +++ b/mseide-msegui/apps/ide/commandlineform.mfm @@ -0,0 +1,41 @@ +object commandlinefo: tcommandlinefo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + bounds_x = 241 + bounds_y = 310 + bounds_cx = 542 + bounds_cy = 100 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.bounds = ( + 0 + 0 + 542 + 100 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + caption = 'Command Line' + moduleclassname = 'tmseform' + object disp: tmemoedit + frame.framei_left = 3 + frame.framei_top = 3 + frame.framei_right = 3 + frame.framei_bottom = 3 + frame.sbhorz.pagesize = 1 + frame.sbvert.pagesize = 1 + frame.localprops = [frl_colorclient] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 542 + bounds_cy = 100 + anchors = [] + optionsedit1 = [oe1_multiline, oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_linebreak, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object c: tstringcontainer + strings.data = ( + 'Make disabled by Default make col!' + ) + left = 184 + top = 32 + end +end diff --git a/mseide-msegui/apps/ide/commandlineform.pas b/mseide-msegui/apps/ide/commandlineform.pas new file mode 100644 index 0000000..61ff50b --- /dev/null +++ b/mseide-msegui/apps/ide/commandlineform.pas @@ -0,0 +1,59 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit commandlineform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,msedataedits,msestringcontainer,msestrings; + +type + stringconsts = ( + makedisabled //0 Make disabled by Default make col! + ); + + tcommandlinefo = class(tmseform) + disp: tmemoedit; + c: tstringcontainer; + end; + +procedure showcommandline; + +implementation +uses + commandlineform_mfm,make,projectoptionsform; + +procedure showcommandline; +var + fo: tcommandlinefo; +begin + fo:= tcommandlinefo.create(nil); + try + if projectoptions.defaultmake >= maxdefaultmake then begin + fo.disp.value:= fo.c[ord(makedisabled)]; + end + else begin + fo.disp.value:= buildmakecommandline(projectoptions.defaultmake); + end; + fo.show(true); + finally + fo.Free; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/commandlineform_mfm.pas b/mseide-msegui/apps/ide/commandlineform_mfm.pas new file mode 100644 index 0000000..a5664f1 --- /dev/null +++ b/mseide-msegui/apps/ide/commandlineform_mfm.pas @@ -0,0 +1,72 @@ +unit commandlineform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,commandlineform; + +const + objdata: record size: integer; data: array[0..1091] of byte end = + (size: 1092; data: ( + 84,80,70,48,14,116,99,111,109,109,97,110,100,108,105,110,101,102,111,13, + 99,111,109,109,97,110,100,108,105,110,101,102,111,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116, + 111,110,0,8,98,111,117,110,100,115,95,120,3,241,0,8,98,111,117,110, + 100,115,95,121,3,54,1,9,98,111,117,110,100,115,95,99,120,3,30,2, + 9,98,111,117,110,100,115,95,99,121,2,100,23,99,111,110,116,97,105,110, + 101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119, + 95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114, + 97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,30,2,2,100,0,7,111,112,116, + 105,111,110,115,11,17,102,111,95,115,99,114,101,101,110,99,101,110,116,101, + 114,101,100,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102,111, + 95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116, + 111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111, + 115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95,115, + 97,118,101,115,116,97,116,101,0,7,99,97,112,116,105,111,110,6,12,67, + 111,109,109,97,110,100,32,76,105,110,101,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,9,116, + 109,101,109,111,101,100,105,116,4,100,105,115,112,17,102,114,97,109,101,46, + 102,114,97,109,101,105,95,108,101,102,116,2,3,16,102,114,97,109,101,46, + 102,114,97,109,101,105,95,116,111,112,2,3,18,102,114,97,109,101,46,102, + 114,97,109,101,105,95,114,105,103,104,116,2,3,19,102,114,97,109,101,46, + 102,114,97,109,101,105,95,98,111,116,116,111,109,2,3,21,102,114,97,109, + 101,46,115,98,104,111,114,122,46,112,97,103,101,115,105,122,101,2,1,21, + 102,114,97,109,101,46,115,98,118,101,114,116,46,112,97,103,101,115,105,122, + 101,2,1,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,30,2,9,98,111,117,110,100,115, + 95,99,121,2,100,7,97,110,99,104,111,114,115,11,0,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,13,111,101,49,95,109,117,108,116,105,108, + 105,110,101,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111, + 101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,108,105, + 110,101,98,114,101,97,107,14,111,101,95,115,104,105,102,116,114,101,116,117, + 114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114, + 101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95, + 101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111, + 110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97,105,110, + 101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,34, + 77,97,107,101,32,100,105,115,97,98,108,101,100,32,98,121,32,68,101,102, + 97,117,108,116,32,109,97,107,101,32,99,111,108,33,0,4,108,101,102,116, + 3,184,0,3,116,111,112,2,32,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcommandlinefo,''); +end. diff --git a/mseide-msegui/apps/ide/componentpaletteform.mfm b/mseide-msegui/apps/ide/componentpaletteform.mfm new file mode 100644 index 0000000..6e30f4f --- /dev/null +++ b/mseide-msegui/apps/ide/componentpaletteform.mfm @@ -0,0 +1,134 @@ +object componentpalettefo: tcomponentpalettefo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 131 + bounds_y = 289 + bounds_cx = 738 + bounds_cy = 69 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = componentgrouponchildscaled + container.bounds = ( + 0 + 0 + 728 + 69 + ) + dragdock.caption = 'Component Palette' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_proportional, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 0000000002000000180000001800000064070000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D00AFFFFFF0AD0D0D004 + FFFFFF0BD0D0D001B7B7B701C6C6C601CACACA01C8C8C801D0D0D00385858501 + D0D0D004FFFFFF01BABABA01AFAFAF01C1C1C101D0D0D00585858501FFFFFF01 + ACACAC01878787018D8D8D019494940181818101D0D0D00385858501D0D0D004 + FFFFFF019D9D9D018D8D8D018A8A8A019494940189898901D0D0D00385858501 + FFFFFF01C5C5C501C4C4C401BDBDBD01B9B9B901B5B5B501D0D0D00385858501 + D0D0D004FFFFFF01C0C0C001B3B3B301BDBDBD01BCBCBC01B3B3B301D0D0D003 + 8585850FF5F5F501F3F3F301F2F2F201E8EEEE01EEEEEE01EDEDED01EBEBEB01 + EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01 + DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501C7E8E80147CBCD011EC4C7013AC8CA01B8E1E101EBEBEB01 + EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201CEDCDC0164CBCC01 + 1DBFC1015AC8C901C5D7D701D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D001F1F4F40123C3C50162E8F4017AF1FF0145E9F60117C3C501DBE7E701 + EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E1E2E20121C0C1014ADDE801 + 6EF1FF0133DFEB0117BEC001D3D7D701D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D001A9E2E2013ED4DB01B4F3FF01C1F3FF017BF1FF011FD9E30185D5D601 + EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301A8D6D60138D0D601ACF2FF01 + B6F3FF0175F1FF011CD3DB0192CECE01D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D00160D2D30152E2ED01C0F3FF01D0F4FF0181F1FF0126E6F40141C9CB01 + DADAE8018383E101E6E6E601E5E5E501E3E3E30158CBCC0154E2ED01C5F3FF01 + D0F5FF0183F1FF0125E5F20141C4C601D0D0D7019595D601D3D3D301D2D2D201 + D0D0D001BFE7E7012ECFD50186F1FF018EF1FF015DF0FF0115D4DD019CDADA01 + 6A6AE3010E0EDC01DDDDE501E5E5E501E3E3E301A0D6D60131D1D80191F2FF01 + 99F2FF0164F0FF0115D5DE0188CDCD017373D9011515DB01D1D1D301D2D2D201 + D0D0D001F5F5F50129C4C6012DDAE40141EDFD011BDCE7011BC1C201DBE0E901 + 1919DF010808F0017777E101E5E5E501E3E3E301DFE1E1011CC1C2013BE3F001 + 4FF0FF0124E4F20116C1C201CDD3D6011C1CDD010C0CEB018787D601D2D2D201 + D0D0D001F5F5F501E9F1F10183D8D90125C4C50173D4D501DFEAEA017A7AE401 + 0808EF010404FF011D1DDF01E1E1E501E3E3E301E2E2E201BFD9D9014AC7C801 + 18C1C30142C4C601B5D4D4018383D9010B0BED010404FD012020DC01D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01E8E8EC011A1ADF01 + 0404FE010404FF010A0AEE018686E101E3E3E301E2E2E201E0E0E001DFDFDF01 + DBDCDC01DBDBDB01D9D9DA011F1FDD010404FE010404FF010E0EE9019191D401 + D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE018A8AE6010A0AED01 + 0404FF020404FE012020DF01E1E1E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB019393DA010E0EEA010404FF020404FC012323DB01D0D0D001F5F5F501 + C2211F01C91D1F01C81C1E01C71C1F012605B6011905C8012020E1031515DD01 + A4A4E001E2E2E201C4333101C52525032106BC011206D3011717E2030A0ADA01 + 9D9DD201F5F5F501CB262801FF002004CA272901EAEAEA01E8E8E801E6E6E601 + E5E5E501E3E3E301E2E2E201C9242601FF002003EF002C01BB223101CACAD701 + C8C8D501C6C6D301C5C5D201CACAD001F5F5F501CB262801FF002004CA272901 + EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201C9242601FF002004 + C7242601D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501CB262801 + FF002004CA272901EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201 + C9242601FF002004C7242601D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501CB262801FF002004CA272901EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201C9242601FF002004C7242601D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501C8373601CB282A02CA272902C8393801EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201BF1E1C01CA1B1F01C91A1E03 + C0222001D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601 + E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01 + D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601 + E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01 + D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601 + E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01 + D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001FFFFFF08FFFFFF08 + FFFFFFBFFFFFFF08FFFFFF00FFFFFF08FFFFFF03FFFFFFC0FFFFFF00FFFFFF0A + FFFFFF00FFFFFF08FFFFFF08FFFFFF08FFFFFFBFFFFFFF08FFFFFF00FFFFFF03 + FFFFFF08FFFFFF00FFFFFF00FFFFFFBFFFFFFF00FFFFFF08 + } + onstatread = foonreadstat + onlayout = componentgrouponchildscaled + moduleclassname = 'tdockform' + object componentpalette: ttoolbar + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_destroywidgets, ow_hinton] + optionsskin = [osk_container] + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 26 + bounds_cx = 728 + bounds_cy = 30 + anchors = [an_top, an_bottom] + buttons.width = 26 + buttons.height = 26 + options = [tbo_dragsource, tbo_dragdest] + onbuttonchanged = componentpalettebuttonchanged + drag.onafterdragdrop = componentpalettedragdrop + left = 128 + top = 8 + end + object componentpages: ttabbar + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autoheight] + optionswidget = [ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 728 + bounds_cy = 18 + bounds_cymin = 15 + anchors = [an_top] + statfile = mainfo.projectstatfile + onactivetabchange = componentpagesactivetabchange + options = [tabo_dragsource, tabo_dragdest] + left = 128 + top = 72 + reffontheight = 14 + end +end diff --git a/mseide-msegui/apps/ide/componentpaletteform.pas b/mseide-msegui/apps/ide/componentpaletteform.pas new file mode 100644 index 0000000..544aaa9 --- /dev/null +++ b/mseide-msegui/apps/ide/componentpaletteform.pas @@ -0,0 +1,155 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit componentpaletteform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,msetabs,msetoolbar,msegraphutils,msestat,mseguiglob, + msedragglob,msetypes{msestrings}; + +type + tcomponentpalettefo = class(tdockform) + componentpages: ttabbar; + componentpalette: ttoolbar; + procedure componentgrouponchildscaled(const sender: TObject); + procedure componentpalettedragdrop(const sender: TObject; + const apos: pointty; var dragobject: tdragobject; var processed: boolean); + procedure componentpagesactivetabchange(const sender: TObject); + procedure componentpalettebuttonchanged(const sender: tobject; + const button: tcustomtoolbutton); + procedure foonreadstat(const sender: TObject; const reader: tstatreader); + public + procedure updatecomponentpalette(init: boolean); + procedure resetselected; + end; + +var + componentpalettefo: tcomponentpalettefo; + +implementation +uses + componentpaletteform_mfm,main,projectoptionsform,msedesignintf,mseshapes, + mseactions,classes,mclasses,mseact,componentstore; + +procedure tcomponentpalettefo.componentpalettedragdrop(const sender: TObject; + const apos: pointty; var dragobject: tdragobject; var processed: boolean); +begin + registeredcomponents.pagecomporders[componentpages.activetag - 1]:= + ttoolbar(sender).buttons.idents; + projectoptionsmodified; +end; + +procedure tcomponentpalettefo.componentpagesactivetabchange(const sender: TObject); +begin + updatecomponentpalette(false); + componentpalette.firstbutton:= 0; +end; + +procedure tcomponentpalettefo.componentpalettebuttonchanged(const sender: TObject; + const button: tcustomtoolbutton); +begin + if not application.terminated then begin + with registeredcomponents do begin + if tclass(button.tagpo) = selectedclass then begin + selectedclass:= nil; + end; + if as_checked in button.state then begin + componentstorefo.resetselected; + selectedclass:= mclasses.tcomponentclass(button.tagpo); + end; + end; + end; +end; + +procedure tcomponentpalettefo.componentgrouponchildscaled(const sender: TObject); +begin + placeyorder(0,[0],[componentpages,componentpalette],0); +end; + +procedure tcomponentpalettefo.updatecomponentpalette(init: boolean); +var + int1,int2: integer; + ar1: comppagearty; +begin + resetselected; + if init then begin + with componentpages do begin + beginupdate; + try + tabs.count:= 0; + ar1:= registeredcomponents.pagenames; + tabs.count:= length(ar1); +// tabs.additems(registeredcomponents.pagenames); + if tabs.count > 0 then begin + activetab:= 0; + end; + for int1:= 0 to tabs.count - 1 do begin + with tabs[int1] do begin + tag:= int1 + 1; + caption:= ar1[int1].caption; + hint:= ar1[int1].hint; + end; + end; + finally + componentpages.endupdate; + end; + end; + end; + + componentpalette.beginupdate; + registeredcomponents.defaultorder:= true; + try + int2:= componentpages.activetag - 1; + componentpalette.buttons.count:= 0; + if int2 >= 0 then begin + for int1:= 0 to registeredcomponents.count - 1 do begin + with registeredcomponents.itempo(int1)^ do begin + if page = int2 then begin + with componentpalette.buttons.add do begin + options:= [mao_checkbox,mao_radiobutton]; + imagelist:= registeredcomponents.imagelist; + imagenr:= icon; + hint:= msestring(classtyp.classname); + tagpo:= classtyp; + end; + end; + end; + end; + if int2 <= registeredcomponents.pagehigh then begin + componentpalette.buttons.order(registeredcomponents.pagecomporders[int2]); + end; + end; + finally + registeredcomponents.defaultorder:= false; + componentpalette.endupdate; + end; +end; + +procedure tcomponentpalettefo.foonreadstat(const sender: TObject; + const reader: tstatreader); +begin + updatecomponentpalette(true); +end; + +procedure tcomponentpalettefo.resetselected; +begin + componentpalette.buttons.resetradioitems(0); +end; + +end. diff --git a/mseide-msegui/apps/ide/componentpaletteform_mfm.pas b/mseide-msegui/apps/ide/componentpaletteform_mfm.pas new file mode 100644 index 0000000..81508cc --- /dev/null +++ b/mseide-msegui/apps/ide/componentpaletteform_mfm.pas @@ -0,0 +1,214 @@ +unit componentpaletteform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,componentpaletteform; + +const + objdata: record size: integer; data: array[0..3938] of byte end = + (size: 3939; data: ( + 84,80,70,48,19,116,99,111,109,112,111,110,101,110,116,112,97,108,101,116, + 116,101,102,111,18,99,111,109,112,111,110,101,110,116,112,97,108,101,116,116, + 101,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102, + 111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,9,111,119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103, + 114,105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105, + 112,95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98, + 117,116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116, + 111,110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111, + 95,116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114, + 111,117,110,100,98,117,116,116,111,110,15,103,111,95,110,111,108,111,99,107, + 98,117,116,116,111,110,14,103,111,95,98,117,116,116,111,110,104,105,110,116, + 115,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,131,0,8,98,111,117,110,100,115,95,121,3,33,1,9,98,111,117,110, + 100,115,95,99,120,3,226,2,9,98,111,117,110,100,115,95,99,121,2,69, + 23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119, + 95,109,111,117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,26,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,99,111,110,116, + 97,105,110,101,114,46,111,110,108,97,121,111,117,116,7,27,99,111,109,112, + 111,110,101,110,116,103,114,111,117,112,111,110,99,104,105,108,100,115,99,97, + 108,101,100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115, + 1,2,0,2,0,3,216,2,2,69,0,16,100,114,97,103,100,111,99,107, + 46,99,97,112,116,105,111,110,6,17,67,111,109,112,111,110,101,110,116,32, + 80,97,108,101,116,116,101,20,100,114,97,103,100,111,99,107,46,111,112,116, + 105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112,111,115, + 13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95,99,97, + 110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100, + 95,99,97,110,100,111,99,107,15,111,100,95,112,114,111,112,111,114,116,105, + 111,110,97,108,11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95, + 99,97,112,116,105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100, + 105,99,111,110,115,0,7,111,112,116,105,111,110,115,11,10,102,111,95,115, + 97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114, + 12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102, + 105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115, + 116,97,116,102,105,108,101,21,105,99,111,110,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,12,105,99,111,110,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,0, + 10,105,99,111,110,46,105,109,97,103,101,10,248,7,0,0,0,0,0,0, + 2,0,0,0,24,0,0,0,24,0,0,0,100,7,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,208,208,208,10,255,255,255,10,208,208,208,4, + 255,255,255,11,208,208,208,1,183,183,183,1,198,198,198,1,202,202,202,1, + 200,200,200,1,208,208,208,3,133,133,133,1,208,208,208,4,255,255,255,1, + 186,186,186,1,175,175,175,1,193,193,193,1,208,208,208,5,133,133,133,1, + 255,255,255,1,172,172,172,1,135,135,135,1,141,141,141,1,148,148,148,1, + 129,129,129,1,208,208,208,3,133,133,133,1,208,208,208,4,255,255,255,1, + 157,157,157,1,141,141,141,1,138,138,138,1,148,148,148,1,137,137,137,1, + 208,208,208,3,133,133,133,1,255,255,255,1,197,197,197,1,196,196,196,1, + 189,189,189,1,185,185,185,1,181,181,181,1,208,208,208,3,133,133,133,1, + 208,208,208,4,255,255,255,1,192,192,192,1,179,179,179,1,189,189,189,1, + 188,188,188,1,179,179,179,1,208,208,208,3,133,133,133,15,245,245,245,1, + 243,243,243,1,242,242,242,1,232,238,238,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,199,232,232,1, + 71,203,205,1,30,196,199,1,58,200,202,1,184,225,225,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,206,220,220,1,100,203,204,1,29,191,193,1,90,200,201,1, + 197,215,215,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,241,244,244,1,35,195,197,1,98,232,244,1, + 122,241,255,1,69,233,246,1,23,195,197,1,219,231,231,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,225,226,226,1, + 33,192,193,1,74,221,232,1,110,241,255,1,51,223,235,1,23,190,192,1, + 211,215,215,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,169,226,226,1,62,212,219,1,180,243,255,1,193,243,255,1, + 123,241,255,1,31,217,227,1,133,213,214,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,168,214,214,1,56,208,214,1, + 172,242,255,1,182,243,255,1,117,241,255,1,28,211,219,1,146,206,206,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 96,210,211,1,82,226,237,1,192,243,255,1,208,244,255,1,129,241,255,1, + 38,230,244,1,65,201,203,1,218,218,232,1,131,131,225,1,230,230,230,1, + 229,229,229,1,227,227,227,1,88,203,204,1,84,226,237,1,197,243,255,1, + 208,245,255,1,131,241,255,1,37,229,242,1,65,196,198,1,208,208,215,1, + 149,149,214,1,211,211,211,1,210,210,210,1,208,208,208,1,191,231,231,1, + 46,207,213,1,134,241,255,1,142,241,255,1,93,240,255,1,21,212,221,1, + 156,218,218,1,106,106,227,1,14,14,220,1,221,221,229,1,229,229,229,1, + 227,227,227,1,160,214,214,1,49,209,216,1,145,242,255,1,153,242,255,1, + 100,240,255,1,21,213,222,1,136,205,205,1,115,115,217,1,21,21,219,1, + 209,209,211,1,210,210,210,1,208,208,208,1,245,245,245,1,41,196,198,1, + 45,218,228,1,65,237,253,1,27,220,231,1,27,193,194,1,219,224,233,1, + 25,25,223,1,8,8,240,1,119,119,225,1,229,229,229,1,227,227,227,1, + 223,225,225,1,28,193,194,1,59,227,240,1,79,240,255,1,36,228,242,1, + 22,193,194,1,205,211,214,1,28,28,221,1,12,12,235,1,135,135,214,1, + 210,210,210,1,208,208,208,1,245,245,245,1,233,241,241,1,131,216,217,1, + 37,196,197,1,115,212,213,1,223,234,234,1,122,122,228,1,8,8,239,1, + 4,4,255,1,29,29,223,1,225,225,229,1,227,227,227,1,226,226,226,1, + 191,217,217,1,74,199,200,1,24,193,195,1,66,196,198,1,181,212,212,1, + 131,131,217,1,11,11,237,1,4,4,253,1,32,32,220,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,232,232,236,1,26,26,223,1,4,4,254,1,4,4,255,1, + 10,10,238,1,134,134,225,1,227,227,227,1,226,226,226,1,224,224,224,1, + 223,223,223,1,219,220,220,1,219,219,219,1,217,217,218,1,31,31,221,1, + 4,4,254,1,4,4,255,1,14,14,233,1,145,145,212,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 138,138,230,1,10,10,237,1,4,4,255,2,4,4,254,1,32,32,223,1, + 225,225,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,147,147,218,1,14,14,234,1,4,4,255,2,4,4,252,1, + 35,35,219,1,208,208,208,1,245,245,245,1,194,33,31,1,201,29,31,1, + 200,28,30,1,199,28,31,1,38,5,182,1,25,5,200,1,32,32,225,3, + 21,21,221,1,164,164,224,1,226,226,226,1,196,51,49,1,197,37,37,3, + 33,6,188,1,18,6,211,1,23,23,226,3,10,10,218,1,157,157,210,1, + 245,245,245,1,203,38,40,1,255,0,32,4,202,39,41,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1, + 201,36,38,1,255,0,32,3,239,0,44,1,187,34,49,1,202,202,215,1, + 200,200,213,1,198,198,211,1,197,197,210,1,202,202,208,1,245,245,245,1, + 203,38,40,1,255,0,32,4,202,39,41,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,201,36,38,1, + 255,0,32,4,199,36,38,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,203,38,40,1,255,0,32,4, + 202,39,41,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,201,36,38,1,255,0,32,4,199,36,38,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,203,38,40,1,255,0,32,4,202,39,41,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1, + 201,36,38,1,255,0,32,4,199,36,38,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,200,55,54,1, + 203,40,42,2,202,39,41,2,200,57,56,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,191,30,28,1, + 202,27,31,1,201,26,30,3,192,34,32,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1, + 224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1, + 216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1, + 223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 255,255,255,8,255,255,255,8,255,255,255,191,255,255,255,8,255,255,255,0, + 255,255,255,8,255,255,255,3,255,255,255,192,255,255,255,0,255,255,255,10, + 255,255,255,0,255,255,255,8,255,255,255,8,255,255,255,8,255,255,255,191, + 255,255,255,8,255,255,255,0,255,255,255,3,255,255,255,8,255,255,255,0, + 255,255,255,0,255,255,255,191,255,255,255,0,255,255,255,8,10,111,110,115, + 116,97,116,114,101,97,100,7,12,102,111,111,110,114,101,97,100,115,116,97, + 116,8,111,110,108,97,121,111,117,116,7,27,99,111,109,112,111,110,101,110, + 116,103,114,111,117,112,111,110,99,104,105,108,100,115,99,97,108,101,100,15, + 109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9,116,100,111, + 99,107,102,111,114,109,0,8,116,116,111,111,108,98,97,114,16,99,111,109, + 112,111,110,101,110,116,112,97,108,101,116,116,101,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,13,111,115,107,95,99,111,110,116,97, + 105,110,101,114,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,26,9,98,111, + 117,110,100,115,95,99,120,3,216,2,9,98,111,117,110,100,115,95,99,121, + 2,30,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97, + 110,95,98,111,116,116,111,109,0,13,98,117,116,116,111,110,115,46,119,105, + 100,116,104,2,26,14,98,117,116,116,111,110,115,46,104,101,105,103,104,116, + 2,26,7,111,112,116,105,111,110,115,11,14,116,98,111,95,100,114,97,103, + 115,111,117,114,99,101,12,116,98,111,95,100,114,97,103,100,101,115,116,0, + 15,111,110,98,117,116,116,111,110,99,104,97,110,103,101,100,7,29,99,111, + 109,112,111,110,101,110,116,112,97,108,101,116,116,101,98,117,116,116,111,110, + 99,104,97,110,103,101,100,20,100,114,97,103,46,111,110,97,102,116,101,114, + 100,114,97,103,100,114,111,112,7,24,99,111,109,112,111,110,101,110,116,112, + 97,108,101,116,116,101,100,114,97,103,100,114,111,112,4,108,101,102,116,3, + 128,0,3,116,111,112,2,8,0,0,7,116,116,97,98,98,97,114,14,99, + 111,109,112,111,110,101,110,116,112,97,103,101,115,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,14,111,119,49,95,97,117,116,111,104,101,105,103,104,116,0,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,216,2, + 9,98,111,117,110,100,115,95,99,121,2,18,12,98,111,117,110,100,115,95, + 99,121,109,105,110,2,15,7,97,110,99,104,111,114,115,11,6,97,110,95, + 116,111,112,0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102, + 111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,17,111,110, + 97,99,116,105,118,101,116,97,98,99,104,97,110,103,101,7,29,99,111,109, + 112,111,110,101,110,116,112,97,103,101,115,97,99,116,105,118,101,116,97,98, + 99,104,97,110,103,101,7,111,112,116,105,111,110,115,11,15,116,97,98,111, + 95,100,114,97,103,115,111,117,114,99,101,13,116,97,98,111,95,100,114,97, + 103,100,101,115,116,0,4,108,101,102,116,3,128,0,3,116,111,112,2,72, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcomponentpalettefo,''); +end. diff --git a/mseide-msegui/apps/ide/componentstore.mfm b/mseide-msegui/apps/ide/componentstore.mfm new file mode 100644 index 0000000..7bd41b0 --- /dev/null +++ b/mseide-msegui/apps/ide/componentstore.mfm @@ -0,0 +1,469 @@ +object componentstorefo: tcomponentstorefo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 305 + bounds_y = 101 + bounds_cx = 445 + bounds_cy = 354 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 435 + 354 + ) + dragdock.caption = 'Component Store' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_cansize, od_canfloat, od_candock, od_proportional, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + icon.transparentcolor = -2147483642 + icon.image = { + 00000000000000001800000018000000A0070000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001E9E9E901B2B2B2019A9A9A029B9B9B029C9C9C019B9B9B019D9D9D01 + 9C9C9C019D9D9D019C9C9C029E9E9E019D9D9D019E9E9E01A4A4A401D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201E2E2E201A5A5A501BCBCBC01 + DEDEDE01DFDFDF01DEDEDE04DDDDDD02DCDCDC04CBCBCB019C9C9C019B9B9B01 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F2018D8D8D018686860E + 8D8D8D01BBBBBB019B9B9B01D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F20186868601AAAAFF01AEAEFF01B2B2FF01B6B6FF01BBBBFF01BFBFFF01 + C3C3FF01C8C8FF01CCCCFF01D0D0FF01D4D4FF01D6D6FF0387878701D6D6D601 + 9A9A9A01D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F20186868601 + AAAAFF01AEAEFF01B2B2FF01B6B6FF01BBBBFF01BFBFFF01C3C3FF0100000001 + CCCCFF01D0D0FF01D4D4FF01D6D6FF0387878701D7D7D7019A9A9A01D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F20186868601AAAAFF01AEAEFF01 + B2B2FF01B6B6FF01BBBBFF01BFBFFF01C3C3FF01C8C8FF01CCCCFF01D0D0FF01 + D4D4FF01D6D6FF0387878701D7D7D7019B9B9B01D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F20186868601AAAAFF01AEAEFF01B2B2FF01B6B6FF01 + BBBBFF01BFBFFF01C3C3FF01C8C8FF01CCCCFF01D0D0FF01D4D4FF01D6D6FF03 + 87878701D7D7D7019C9C9C01D2D2D202D0D0D001F5F5F501F3F3F301F2F2F201 + 868686018A8A8A038B8B8B058C8C8C0687878701D7D7D7019C9C9C01D1D1D101 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F20186868601AAFFF601AEFFF701 + B2FFF701B6FFF801BBFFF901BFFFF901C3FFFA01C8FFFB01CCFFFC01D0FFFC01 + D4FFFD01D6FFFD02D8FCFB0187878701D7D7D7019C9C9C01D1D1D101D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F20186868601AAFFF601AEFFF701B2FFF701 + B6FFF801BBFFF901BFFFF901C3FFFA0100000001CCFFFC01D0FFFC01D4FFFD01 + D6FFFD02D9FDFB0187878701D7D7D7019D9D9D01D0D0D001D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F20186868601AAFFF601AEFFF701B2FFF701B6FFF801 + BBFFF901BFFFF901C3FFFA01C8FFFB01CCFFFC01D0FFFC01D4FFFD01D6FFFD02 + D9FDFB0187878701D7D7D7019E9E9E01D0D0D001D2D2D201D0D0D001F5F5F501 + F3F3F301F2F2F20186868601AAFFF601AEFFF701B2FFF701B6FFF801BBFFF901 + BFFFF901C3FFFA01C8FFFB01CCFFFC01D0FFFC01D4FFFD01D6FFFD02D9FDFB01 + 87878701D6D6D6019E9E9E01CFCFCF01D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201868686018A8A8A038B8B8B058C8C8C0687878701D6D6D6019F9F9F01 + CECECE01D2D2D201D0D0D001F5F5F501F3F3F301F2F2F2019D8C8F01FFAAB901 + FFAFBB01FFB3BE01FFB7C101FFBBC401FFBFC701FFC4CA01FFC8CD01FFCCD001 + FFD0D301FFD5D601FFD6D70387878701D6D6D6019F9F9F01CECECE01D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F2019D8C8F01FFAAB901FFAFBB01FFB3BE01 + FFB7C101FFBBC401FFBFC701FFC4CA0100000001FFCCD001FFD0D301FFD5D601 + FFD6D70387878701C4C4C401A3A3A301D2D2D202D0D0D001F5F5F501F3F3F301 + F2F2F2019D8C8F01FFAAB901FFAFBB01FFB3BE01FFB7C101FFBBC401FFBFC701 + FFC4CA01FFC8CD01FFCCD001FFD0D301FFD5D601FFD6D70387878701A2A2A201 + C4C4C401D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F2019D8C8F01 + FFAAB901FFAFBB01FFB3BE01FFB7C101FFBBC401FFBFC701FFC4CA01FFC8CD01 + FFCCD001FFD0D301FFD5D601FFD6D70387878701ACACAC01D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201919191018888880B89898901 + 888888028E8E8E01CACACA01D3D3D302D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201E9E9E901C6C6C601818181017272720271717101707070026F6F6F02 + 6E6E6E016D6D6D016C6C6C016B6B6B037C7C7C01BFBFBF01D1D1D101D2D2D201 + D0D0D001F5F5F501F3F3F301F0F0F001D8D8D8018C8C8C017575750172727202 + 71717101707070016F6F6F016E6E6E026D6D6D016C6C6C016B6B6B016A6A6A02 + 71717101A9A9A901CFCFCF01D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201EEEEEE01E7E7E701E6E6E601E3E3E301E2E2E201E0E0E001DEDEDE01 + DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201 + D1D1D101D4D4D402D3D3D301D2D2D201D0D0D001 + } + oncreate = createexe + moduleclassname = 'tdockform' + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 435 + bounds_cy = 354 + anchors = [] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 4 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Sel' + hint = 'Select item for inserting' + end + item + caption = 'Description' + end + item + caption = 'File' + end> + end> + datacols.count = 4 + datacols.options = [co_proportional, co_savestate, co_mousescrollrow] + datacols.items = < + item[node] + width = 110 + options = [co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + widgetname = 'node' + dataclass = ttreeitemeditlist + datalist.imnr_expanded = 1 + datalist.imagelist = filedialogres.images + datalist.imagewidth = 16 + datalist.imageheight = 16 + datalist.onstatreaditem = dostatreaditem + datalist.ondragover = drago + datalist.ondragdrop = dragdro + end + item[sel] + color = -2147483646 + width = 28 + options = [co_fixwidth, co_proportional, co_savestate, co_mousescrollrow] + widthmin = 0 + widgetname = 'sel' + dataclass = tgridintegerdatalist + end + item[compdesc] + width = 103 + options = [co_fill, co_savestate, co_mousescrollrow] + widgetname = 'compdesc' + dataclass = tgridmsestringdatalist + end + item[filepath] + width = 186 + options = [co_proportional, co_savestate, co_mousescrollrow] + widgetname = 'filepath' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = mainfo.projectstatfile + oncellevent = docellevent + drag.onbeforedragbegin = beforedrag + reffontheight = 14 + object node: ttreeitemedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + onenter = nodeenter + onexit = nodeexit + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 110 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_hintclippedtext, oe_locate] + ondataentered = datent + onsetvalue = compnamesetva + onupdaterowvalues = doupdaterowvalues + options = [teo_treecolnavig, teo_keyrowmoving] + reffontheight = 14 + end + object sel: tdatabutton + taborder = 2 + bounds_x = 111 + bounds_y = 0 + bounds_cx = 28 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_radioitemcol, bo_cantoggle, bo_resetcheckedonrowexit] + state = [as_invisible, as_localinvisible] + valuefaces.count = 1 + valuefaces.items = < + item + fade_pos.count = 2 + fade_pos.items = ( + 0 + 1 + ) + fade_color.count = 2 + fade_color.items = ( + -1610612729 + 16768903 + ) + fade_direction = gd_down + localprops = [fal_fadirection] + end> + onsetvalue = setval + end + object compdesc: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 3 + visible = False + bounds_x = 140 + bounds_y = 0 + bounds_cx = 103 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = datent + onsetvalue = compdescsetva + reffontheight = 14 + end + object filepath: tfilenameedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 4 + visible = False + bounds_x = 244 + bounds_y = 0 + bounds_cx = 186 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + ondataentered = datent + onsetvalue = filenamesetva + controller.filterlist.data = ( + ( + 'Component File' + '*.cmp' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'cmp' + reffontheight = 14 + end + end + object copycompact: taction + caption = '&Copy Component' + options = [ao_localshortcut] + onexecute = docopycomponent + onupdate = copyupda + left = 176 + top = 64 + end + object pastecompact: taction + caption = '&Paste Component(s)' + options = [ao_localshortcut] + onexecute = dopastecomponent + onupdate = pasteupda + left = 176 + top = 88 + end + object tpopupmenu1: tpopupmenu + onupdate = popupupdate + menu.submenu.count = 18 + menu.submenu.items = < + item + action = copycompact + caption = '&Copy Component(s)' + state = [as_localcaption] + end + item + action = pastecompact + end + item + action = addfileact + end + item + caption = 'Update Component(s)' + name = 'updatenode' + state = [as_localcaption, as_localonexecute] + onexecute = doupdatecomponent + end + item + caption = 'Remove Component(s)' + name = 'removecomp' + state = [as_localcaption, as_localonexecute] + onexecute = removecomp + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'New Node' + name = 'addnode' + state = [as_localcaption, as_localonexecute] + onexecute = donewnode + end + item + caption = 'Remove Node' + name = 'removenode' + state = [as_localcaption, as_localonexecute] + onexecute = delnode + end + item + caption = 'Copy Node' + name = 'copynode' + state = [as_localcaption, as_localonexecute] + onexecute = copynodeex + end + item + caption = 'Paste Node' + name = 'pastenode' + state = [as_localcaption, as_localonexecute] + onexecute = pastenodeex + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'New Store' + state = [as_localcaption, as_localonexecute] + onexecute = newstoreex + end + item + caption = 'Add Store' + state = [as_localcaption, as_localonexecute] + onexecute = addstoreex + end + item + caption = 'Remove Store' + name = 'removestore' + state = [as_localcaption, as_localonexecute] + onexecute = removestoreex + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Open Store Group' + state = [as_localcaption, as_localonexecute] + onexecute = opengroup + end + item + caption = 'Save Store Group' + state = [as_localcaption, as_localonexecute] + onexecute = savegroup + end + item + caption = 'Save Store Group as' + state = [as_localcaption, as_localonexecute] + onexecute = savegroupas + end> + left = 40 + top = 88 + end + object storefile: tstatfile + filename = 'store.sta' + onstatread = statreadexe + onstatwrite = statwriteexe + left = 296 + top = 88 + end + object storefiledialog: tfiledialog + statfile = mainfo.projectstatfile + controller.filterlist.data = ( + ( + 'Component Stores' + '*.sto' + ) + ) + controller.defaultext = 'sto' + controller.options = [fdo_checkexist, fdo_savelastdir] + controller.captionopen = 'Load Component Store' + controller.captionsave = 'New Component Store' + left = 40 + top = 136 + end + object groupfiledialog: tfiledialog + statfile = mainfo.projectstatfile + controller.filterlist.data = ( + ( + 'Store Groups' + '*.stg' + ) + ) + controller.defaultext = 'stg' + controller.captionopen = 'Open Store Group' + controller.captionsave = 'Save Store Group' + left = 40 + top = 168 + end + object addfileact: taction + caption = 'Add Componentfile' + onexecute = doaddfile + onupdate = pasteupda + left = 176 + top = 112 + end + object compfiledialog: tfiledialog + statfile = mainfo.projectstatfile + controller.filterlist.data = ( + ( + 'Component File' + '*.cmp' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'cmp' + controller.options = [fdo_checkexist, fdo_savelastdir] + controller.captionopen = 'Select Component File' + left = 40 + top = 200 + end + object c: tstringcontainer + strings.data = ( + 'Component Store' + 'Component read error.' + 'Do you want to overwrite "' + '" with current clipboard content?' + 'WARNING' + 'No component(s) in clipboard.' + 'Error while writing the storegroup.' + 'ERROR' + 'Do you want to remove "' + '"?' + '" branch?' + 'File "' + '" does not exist, do you want to create it?' + 'Save Component Store Group' + ) + left = 296 + top = 144 + end +end diff --git a/mseide-msegui/apps/ide/componentstore.pas b/mseide-msegui/apps/ide/componentstore.pas new file mode 100644 index 0000000..3d5538d --- /dev/null +++ b/mseide-msegui/apps/ide/componentstore.pas @@ -0,0 +1,1071 @@ +{ MSEide Copyright (c) 2008-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit componentstore; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics,msedragglob,msegraphutils,mseevent,mseclasses,mseforms,msedock, + mseact,mseactions,msestrings,msedataedits,mseedit,msegrids,msetypes, + msewidgetgrid,msedatanodes,mselistbrowser,msewidgets,msestatfile,msebitmap, + msefiledialog,msesys,msedialog,msememodialog,msesimplewidgets,msegridsglob, + msegraphedits,msestringcontainer,msesplitter; + +type + storedcomponentinfoty = record + compclass: ansistring; + componentname: ansistring; + compname: msestring; + compdesc: msestring; + filepath: filenamety; + storedir: filenamety; + end; + pstoredcomponentinfoty = ^storedcomponentinfoty; + + tstoredcomponent = class(ttreelistedititem) + private + finfo: storedcomponentinfoty; + fisnode: boolean; + fpasting: boolean; + procedure setinfo(const avalue: storedcomponentinfoty); + procedure setcompname(const avalue: msestring); + procedure checkisnode; + procedure setfilepath(const avalue: filenamety); + function getfilepath: msestring; + procedure setcompdesc(const avalue: msestring); + protected + procedure setcaption(const avalue: msestring); override; + public + constructor create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); overload; override; + constructor create(const isnode: boolean); overload; + property info: storedcomponentinfoty read finfo write setinfo; + property compclass: ansistring read finfo.compclass write finfo.compclass; + property componentname: ansistring read finfo.componentname write + finfo.componentname; + property compname: msestring read finfo.compname write setcompname; + property compdesc: msestring read finfo.compdesc write setcompdesc; + property filepath: msestring read getfilepath write setfilepath; + property storedir: msestring read finfo.storedir write finfo.storedir; + property isnode: boolean read fisnode; + + procedure updatestoredir; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + end; + + storedcomponentarty = array of tstoredcomponent; + + tcomponentstorefo = class(tdockform) + grid: twidgetgrid; + node: ttreeitemedit; + copycompact: taction; + pastecompact: taction; + tpopupmenu1: tpopupmenu; + storefile: tstatfile; + filepath: tfilenameedit; + compdesc: tmemodialogedit; + storefiledialog: tfiledialog; + groupfiledialog: tfiledialog; + addfileact: taction; + compfiledialog: tfiledialog; + sel: tdatabutton; + c: tstringcontainer; + procedure createexe(const sender: TObject); + procedure dopastecomponent(const sender: TObject); + procedure statreadexe(const sender: TObject; const reader: tstatreader); + procedure statwriteexe(const sender: TObject; const writer: tstatwriter); + procedure dostatreaditem(const sender: TObject; const reader: tstatreader; + var aitem: ttreelistitem); + procedure doupdaterowvalues(const sender: TObject; const aindex: Integer; + const aitem: tlistitem); + procedure filenamesetva(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure docopycomponent(const sender: TObject); + procedure donewnode(const sender: TObject); + procedure popupupdate(const sender: tcustommenu); + procedure copyupda(const sender: tcustomaction); + procedure pasteupda(const sender: tcustomaction); + procedure docellevent(const sender: TObject; var info: celleventinfoty); + procedure newstoreex(const sender: TObject); + procedure addstoreex(const sender: TObject); + procedure removestoreex(const sender: TObject); + procedure compdescsetva(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure compnamesetva(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure delnode(const sender: TObject); + procedure copynodeex(const sender: TObject); + procedure pastenodeex(const sender: TObject); + procedure beforedrag(const sender: TObject; const apos: pointty; + var dragobject: tdragobject; var processed: Boolean); + procedure drago(const sender: ttreeitemedit; const source: ttreelistitem; + const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var accept: Boolean; + var processed: Boolean); + procedure dragdro(const sender: ttreeitemedit; const source: ttreelistitem; + const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var processed: Boolean); + procedure removecomp(const sender: TObject); + procedure datent(const sender: TObject); + procedure opengroup(const sender: TObject); + procedure savegroupas(const sender: TObject); + procedure savegroup(const sender: TObject); + procedure nodeenter(const sender: TObject); + procedure nodeexit(const sender: TObject); + procedure doupdatecomponent(const sender: TObject); + procedure doaddfile(const sender: TObject); + procedure setval(const sender: TObject; var avalue: Integer; + var accept: Boolean); + private + far1: storedcomponentarty; + fstoredir: msestring; + fchanged: boolean; + fgroupfilename: filenamety; + function dosavegroupas: modalresultty; + procedure initcomponentinfo(out ainfo: storedcomponentinfoty); + function isnode: boolean; + function iscomp: boolean; + function dogetstorerec(const index: integer): msestring; + procedure dosetstorescount(const count: integer); + procedure dosetstorerec(const index: integer; const avalue: msestring); + procedure readstore(const aitem: tstoredcomponent); + procedure checkchanged; + procedure storechanged; + function writestoregroup(const afilename: filenamety): modalresultty; + function readstoregroup(const afilename: filenamety): boolean; + //false if file not found + procedure pasteoradd(const apaste: boolean); + function copycomponent: string; + public + procedure updatestat(afiler: tstatfiler); + function saveall(const quiet: boolean): modalresultty; + procedure resetselected; + function hasselection: boolean; + function copyselected: string; + end; + +var + componentstorefo: tcomponentstorefo; + +implementation +uses + componentstore_mfm,msestream,storedcomponentinfodialog,msedatalist,msefileutils, + sysutils,projectoptionsform,componentpaletteform,mseobjecttext,msearrayutils; +type + treader1 = class(treader); + strconsts = ( + storecaption, //0 Component Store + compreaderror, //1 Component read error. + wantoverwrite, //2 Do you want to overwrite " + withcurrent, //3 " with current clipboard content? + warning, //4 WARNING + nocomps, //5 No component(s) in clipboard. + errorwriting, //6 Error while writing the storegroup. + error, //7 ERROR + wantremove, //8 Do you want to remove " + qm, //9 "? + branch, //10 " branch? + str_file, //11 File " + doesnotexist, //12 " does not exist, do you want to create it? + savecompstore //13 Save Component Store Group + ); + +function getstoredir: filenamety; +begin + result:= filepath(expandprmacros('${COMPSTOREDIR}'),fk_dir); +end; + +{ tstoredcomponent } + +constructor tstoredcomponent.create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); +begin + inherited; + include(fstate1,ns1_candrag); +end; + +constructor tstoredcomponent.create(const isnode: boolean); +begin + include(fstate1,ns1_rootchange); + fisnode:= isnode; + create(nil,nil); + checkisnode; +end; + +procedure tstoredcomponent.setinfo(const avalue: storedcomponentinfoty); +begin + finfo:= avalue; + caption:= finfo.compname; +end; + +procedure tstoredcomponent.dostatread(const reader: tstatreader); +begin + inherited; + + if not fpasting and isroot then begin + caption:= compname; //restore + end + else begin + with reader do begin + fisnode:= readboolean('isnode',fisnode); + compname:= readmsestring('compname',compname); + compclass:= readstring('compclass',compclass); + compdesc:= readmsestring('compdesc',compdesc); + finfo.filepath:= readmsestring('filepath',filepath); + finfo.storedir:= readmsestring('storedir',storedir); + end; + end; + checkisnode; +end; + +procedure tstoredcomponent.dostatwrite(const writer: tstatwriter); +begin + inherited; + with writer do begin + writeboolean('isnode',fisnode); + writemsestring('compname',compname); + writestring('compclass',compclass); + writemsestring('compdesc',compdesc); + writemsestring('filepath',finfo.filepath); + writemsestring('storedir',storedir); + end; +end; + +procedure tstoredcomponent.setcompname(const avalue: msestring); +begin + finfo.compname:= avalue; + caption:= avalue; +end; + +procedure tstoredcomponent.setcaption(const avalue: msestring); +begin + finfo.compname:= avalue; + inherited; +end; + +procedure tstoredcomponent.checkisnode; +begin + if not fisnode then begin + fimagenr:= 2; + end + else begin + if not isroot then begin + finfo.filepath:= ''; + end; + fimagenr:= 0; + end; +end; + +procedure tstoredcomponent.updatestoredir; +begin + finfo.storedir:= getstoredir; +end; + +procedure tstoredcomponent.setfilepath(const avalue: filenamety); +begin + finfo.filepath:= avalue; + statechanged; + updatestoredir; +end; + +function tstoredcomponent.getfilepath: msestring; +begin + relocatepath(finfo.storedir,getstoredir,finfo.filepath); + result:= finfo.filepath; +end; + +procedure tstoredcomponent.setcompdesc(const avalue: msestring); +begin + finfo.compdesc:= avalue; + statechanged; +end; + +{ tcomponentstorefo } + +procedure tcomponentstorefo.createexe(const sender: TObject); +begin +{ + frootnode:= tstoredcomponent.create(true); + frootnode.caption:= 'Root'; + node.itemlist.add(frootnode); + } +end; + +procedure tcomponentstorefo.initcomponentinfo(out ainfo: storedcomponentinfoty); +begin + fillchar(ainfo,sizeof(ainfo),0); + ainfo.filepath:= storefiledialog.controller.lastdir; +end; + +procedure tcomponentstorefo.pasteoradd(const apaste: boolean); +var + str1: ansistring; + str2: msestring; + stream1: tstringcopystream; + stream2: ttextstream; + stream3: ttextstream; + reader1: treader; + info: storedcomponentinfoty; + flags: tfilerflags; + int1: integer; +// compname1: string; + node1: tstoredcomponent; + statwriter1: tstatwriter; + dialogfo: tstoredcomponentinfodialogfo; +begin + statwriter1:= nil; + stream1:= nil; + stream2:= nil; + stream3:= nil; + reader1:= nil; + initcomponentinfo(info); + try + if apaste then begin + if not pastefromclipboard(str2) then begin + exit; + end; + str1:= ansistring(str2); + end + else begin + if compfiledialog.execute <> mr_ok then begin + exit; + end; + stream2:= ttextstream.create(compfiledialog.controller.filename,fm_read); + try + str1:= stream2.readdatastring; + finally + stream2.free; + end; + end; + + stream1:= tstringcopystream.create(str1); + stream2:= ttextstream.create; + try + objecttexttobinarymse(stream1,stream2); + stream2.position:= 0; + reader1:= treader.create(stream2,4096); + with info,treader1(reader1) do begin + driver.beginrootcomponent; + driver.begincomponent(flags,int1,compclass,componentname); + end; + except + if not apaste then begin + showerror(c[ord(compreaderror)]); + end; + exit; //invalid + end; + info.compname:= msestring(info.compclass); + dialogfo:= tstoredcomponentinfodialogfo.create(info); + if apaste then begin + dialogfo.checkfilename; + end + else begin + dialogfo.filepath.value:= compfiledialog.controller.filename; + end; + if dialogfo.show(true) = mr_ok then begin + stream3:= ttextstream.create(info.filepath,fm_create); + node1:= tstoredcomponent.create(false); + node1.info:= info; + node.item.add(node1); + node1.statechanged; + stream3.writedatastring(str1); + storechanged; + end; + finally + statwriter1.free; + reader1.free; + stream1.free; + stream2.free; + stream3.free; + end; +end; + +procedure tcomponentstorefo.dopastecomponent(const sender: TObject); +begin + pasteoradd(true); +end; + +procedure tcomponentstorefo.doaddfile(const sender: TObject); +begin + pasteoradd(false); +end; + +procedure tcomponentstorefo.doupdatecomponent(const sender: TObject); +var + mstr1: msestring; + str1: ansistring; + bo1: boolean; + stream1,stream2: tstream; + stream3: ttextstream; +begin + if askyesno(c[ord(wantoverwrite)]+filepath.value+c[ord(withcurrent)], + c[ord(warning)]) then begin + bo1:= false; + if pastefromclipboard(mstr1) then begin + str1:= ansistring(mstr1); + stream1:= tstringcopystream.create(str1); + stream2:= ttextstream.create; + try + objecttexttobinarymse(stream1,stream2); + bo1:= true; //no error + except + end; + stream1.free; + stream2.free; + if bo1 then begin + stream3:= ttextstream.create(filepath.value,fm_create); + try + stream3.writedatastring(str1); + finally + stream3.free; + end; + end; + end; + if not bo1 then begin + showerror(c[ord(nocomps)]); + end; + end; +end; + +function tcomponentstorefo.copycomponent: string; +var + stream1: ttextstream; +begin + with tstoredcomponent(node.item) do begin + stream1:= ttextstream.create(filepath); + try + result:= stream1.readdatastring; + finally + stream1.free; + end; + end; +end; + +procedure tcomponentstorefo.docopycomponent(const sender: TObject); +begin + copytoclipboard(msestring(copycomponent)); +end; + +procedure tcomponentstorefo.statreadexe(const sender: TObject; + const reader: tstatreader); +begin +// frootnode.dostatread(reader); +end; + +procedure tcomponentstorefo.statwriteexe(const sender: TObject; + const writer: tstatwriter); +begin +// frootnode.dostatwrite(writer); +end; + +procedure tcomponentstorefo.dostatreaditem(const sender: TObject; + const reader: tstatreader; var aitem: ttreelistitem); +begin + aitem:= tstoredcomponent.create(true); +end; + +function tcomponentstorefo.dogetstorerec(const index: integer): msestring; +begin + with far1[index].finfo do begin + result:= encoderecord([compname,filepath,compdesc]); + end; +end; + +procedure tcomponentstorefo.dosetstorescount(const count: integer); +var + int1: integer; +begin + setlength(far1,count); + for int1:= 0 to high(far1) do begin + far1[int1]:= tstoredcomponent.create(true); + end; +end; + +procedure tcomponentstorefo.dosetstorerec(const index: integer; + const avalue: msestring); +var + mstr1,mstr2,mstr3: msestring; +begin + if not decoderecord(avalue,[@mstr1,@mstr2,@mstr3],'SSS') then begin + freeandnil(far1[index]); + end + else begin + with far1[index] do begin + compname:= mstr1; + finfo.filepath:= mstr2; + compdesc:= mstr3; + end; + end; +end; + +procedure tcomponentstorefo.readstore(const aitem: tstoredcomponent); +var + reader1: tstatreader; +begin + with aitem do begin + reader1:= tstatreader.create(finfo.filepath,ce_utf8); + try + reader1.setsection('store'); + aitem.dostatread(reader1); + finally + reader1.free; + end; + end; +end; + +function tcomponentstorefo.writestoregroup( + const afilename: filenamety): modalresultty; +var + item1: tstoredcomponent; + int1: integer; + writer1,writer2: tstatwriter; +begin + result:= mr_ok; + fchanged:= false; + fgroupfilename:= msefileutils.filepath(afilename); + writer2:= nil; + try + writer2:= tstatwriter.create(fgroupfilename,ce_utf8,true); + with writer2,node do begin + for int1:= 0 to itemlist.count - 1 do begin + item1:= tstoredcomponent(items[int1]); + if item1.isroot then begin + additem(pointerarty(far1),item1); + end; + end; + writesection('componentstore'); + writerecordarray('stores',length(far1),{$ifdef FPC}@{$endif}dogetstorerec); +// try + for int1:= 0 to high(far1) do begin + with far1[int1] do begin + if isstatechanged then begin + writer1:= tstatwriter.create(finfo.filepath,ce_utf8,true); + try + writer1.writesection('store'); + far1[int1].dostatwrite(writer1); + finally + writer1.free; + end; + end; + end; + end; +// except +// application.handleexception(self); +// end; + end; + except + on e: exception do begin + fchanged:= true; + result:= showmessage(c[ord(errorwriting)]+lineend+ + msestring(e.message),c[ord(error)],[mr_cancel,mr_ignore]); + if result = mr_ignore then begin + result:= mr_ok; + end; + end; + end; + far1:= nil; + writer2.free; + checkchanged; +end; + +function tcomponentstorefo.readstoregroup(const afilename: filenamety): boolean; +var + int1: integer; + {reader1,}reader2: tstatreader; + item1: tstoredcomponent; + storedir1: filenamety; +begin + grid.clear; + reader2:= nil; + result:= afilename <> ''; + if result then begin + try + fgroupfilename:= msefileutils.filepath(afilename); + storedir1:= getstoredir; + reader2:= tstatreader.create(fgroupfilename,ce_utf8); + with reader2,node do begin + setsection('componentstore'); + readrecordarray('stores',{$ifdef FPC}@{$endif}dosetstorescount, + {$ifdef FPC}@{$endif}dosetstorerec); + try + for int1:= 0 to high(far1) do begin + item1:= far1[int1]; + if item1 <> nil then begin + with item1 do begin + if relocatepath(fstoredir,storedir1,finfo.filepath) then begin + readstore(item1); + end; + end; + end; + end; + except + application.handleexception(self); + end; + for int1:= 0 to high(far1) do begin + if far1[int1] <> nil then begin + node.itemlist.add(far1[int1]); + end; + end; + end; + except + result:= false; + end; + far1:= nil; + reader2.free; + end + else begin + fgroupfilename:= ''; + end; + fchanged:= false; + checkchanged; +end; + +procedure tcomponentstorefo.updatestat(afiler: tstatfiler); +begin + if afiler.iswriter then begin + with tstatwriter(afiler) do begin + writesection('componentstore'); + writemsestring('storedir',getstoredir); + writemsestring('filename',fgroupfilename); + end; + end + else begin + with tstatreader(afiler) do begin + setsection('componentstore'); + fstoredir:= readmsestring('storedir',getstoredir); + storefiledialog.controller.filename:= fstoredir; + groupfiledialog.controller.filename:= fstoredir; + fgroupfilename:= readmsestring('filename',fstoredir+'default.stg'); + if not readstoregroup(fgroupfilename) then begin + fgroupfilename:= ''; + end; + end; + end; +end; + +procedure tcomponentstorefo.doupdaterowvalues(const sender: TObject; + const aindex: Integer; const aitem: tlistitem); +begin + with tstoredcomponent(aitem).info do begin + self.filepath[aindex]:= filepath; + self.compdesc[aindex]:= compdesc; + end; +end; + +procedure tcomponentstorefo.filenamesetva(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + tstoredcomponent(node.item).filepath:= avalue; +end; + +procedure tcomponentstorefo.compdescsetva(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + tstoredcomponent(node.item).compdesc:= avalue; +end; + +procedure tcomponentstorefo.compnamesetva(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + tstoredcomponent(node.item).compname:= avalue; +end; + +procedure tcomponentstorefo.donewnode(const sender: TObject); +var + int1: integer; +begin + with node.item do begin + int1:= add(tstoredcomponent.create(true)); + expanded:= true; + end; + grid.row:= grid.row + int1 + 1; + node.beginedit; +end; + +function tcomponentstorefo.isnode: boolean; +begin + result:= (node.item <> nil) and (tstoredcomponent(node.item).fisnode); +end; + +function tcomponentstorefo.iscomp: boolean; +begin + result:= (node.item <> nil) and not(tstoredcomponent(node.item).fisnode); +end; + +procedure tcomponentstorefo.popupupdate(const sender: tcustommenu); +var + bo1,bo2: boolean; +begin + bo1:= isnode; + bo2:= iscomp; + sender.menu.submenu.itembyname('addnode').enabled:= bo1; + sender.menu.submenu.itembyname('pastenode').enabled:= bo1; + sender.menu.submenu.itembyname('updatenode').enabled:= bo2; + sender.menu.submenu.itembyname('removestore').enabled:= bo1 and + node.item.isroot; + sender.menu.submenu.itembyname('removecomp').enabled:= bo2; + bo1:= isnode and not node.item.isroot; + sender.menu.submenu.itembyname('removenode').enabled:= bo1; + sender.menu.submenu.itembyname('copynode').enabled:= bo1; +end; + +procedure tcomponentstorefo.copyupda(const sender: tcustomaction); +begin + sender.enabled:= iscomp; +end; + +procedure tcomponentstorefo.pasteupda(const sender: tcustomaction); +begin + sender.enabled:= isnode; +end; + +procedure tcomponentstorefo.docellevent(const sender: TObject; + var info: celleventinfoty); +var + bo1: boolean; +begin +// if isrowexit(info) then begin +// resetselected; +// end; + case info.eventkind of + cek_enter: begin + with tstoredcomponent(node.item) do begin + bo1:= fisnode; + self.filepath.readonly:= bo1;; + if bo1 and (treelevel > 0) then begin + self.filepath.value:= ''; + end; + end; + end; + end; +end; + +//todo: check duplicates +procedure tcomponentstorefo.newstoreex(const sender: TObject); +var + stream1: ttextstream; + node1: tstoredcomponent; +begin + with storefiledialog do begin + if execute(fdk_save) = mr_ok then begin + stream1:= ttextstream.create(controller.filename,fm_create); + stream1.free; + node1:= tstoredcomponent.create(true); + with node1.finfo do begin + filepath:= controller.filename; + compname:= removefileext(filename(filepath)); + node1.caption:= compname; + end; + node.itemlist.add(node1); + storechanged; + end; + end; +end; + +//todo: check duplicates +procedure tcomponentstorefo.addstoreex(const sender: TObject); +var +// stream1: ttextstream; + node1: tstoredcomponent; +begin + with storefiledialog do begin + if execute(fdk_open) = mr_ok then begin + node1:= tstoredcomponent.create(true); + with node1.finfo do begin + storedir:= getstoredir; + filepath:= controller.filename; + compname:= removefileext(filename(filepath)); + node1.caption:= compname; + end; + readstore(node1); + node.itemlist.add(node1); + storechanged; + end; + end; +end; + +procedure tcomponentstorefo.removestoreex(const sender: TObject); +begin + with tstoredcomponent(node.item).finfo do begin + if askyesno(c[ord(wantremove)]+compname+c[ord(qm)]) then begin + tstoredcomponent(node.item).free; + storechanged; + end; + end; +end; + +procedure tcomponentstorefo.delnode(const sender: TObject); +begin + with tstoredcomponent(node.item).finfo do begin + if askyesno(c[ord(wantremove)]+compname+c[ord(branch)]) then begin + tstoredcomponent(node.item).free; + storechanged; + end; + end; +end; + +procedure tcomponentstorefo.removecomp(const sender: TObject); +begin + with tstoredcomponent(node.item).finfo do begin + if askyesno(c[ord(wantremove)]+compname+c[ord(qm)]) then begin + tstoredcomponent(node.item).free; + storechanged; + end; + end; +end; + +const + nodecopysig = '{DEA80549-4F45-4117-B182-A0EF49C4A097}'; + +procedure tcomponentstorefo.copynodeex(const sender: TObject); +var + stream1: ttextstream; + writer1: tstatwriter; +begin + stream1:= ttextstream.create; //memory stream + writer1:= tstatwriter.create(stream1,ce_utf8); +// stream1.encoding:= ce_utf8n; + try + writer1.writesection('nodecopy'); + writer1.writemsestring('signature',nodecopysig); + node.item.dostatwrite(writer1); + stream1.position:= 0; + copytoclipboard(utf8tostringansi(stream1.readdatastring)); + finally + writer1.free; + stream1.free; + end; +end; + +procedure tcomponentstorefo.pastenodeex(const sender: TObject); +var + reader1: tstatreader; + stream1: ttextstream; + node1: tstoredcomponent; + mstr1: msestring; +begin + if pastefromclipboard(mstr1) then begin + reader1:= nil; + stream1:= nil; + try + stream1:= ttextstream.createdata(stringtoutf8ansi(mstr1)); +// stream1.encoding:= ce_utf8n; + reader1:= tstatreader.create(stream1,ce_utf8); + if reader1.findsection('nodecopy') and + (reader1.readmsestring('signature','') = nodecopysig) then begin + node1:= tstoredcomponent.create(true); + node1.fpasting:= true; + node1.dostatread(reader1); + node1.fpasting:= false; + with node.item do begin + expanded:= true; + add(node1); + grid.row:= grid.row + count; + end; + storechanged; + end; + finally + reader1.free; + stream1.free; + end; + end; +end; + +procedure tcomponentstorefo.beforedrag(const sender: TObject; + const apos: pointty; var dragobject: tdragobject; + var processed: Boolean); +//var +// widget1: twidget; +begin +end; + +procedure tcomponentstorefo.drago(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var accept: Boolean; + var processed: Boolean); +begin + accept:= not dest.checkancestor(source) and + not ((source.parent = nil) and (dest.parent <> nil)) and + not (tstoredcomponent(source).isnode and + not tstoredcomponent(dest).isnode); +end; + +procedure tcomponentstorefo.dragdro(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var processed: Boolean); +begin + if tstoredcomponent(dest).isnode then begin + dest.add(source); + end + else begin + sender.itemlist.moverow(dest.index,source.index); + end; + storechanged; +end; + +procedure tcomponentstorefo.datent(const sender: TObject); +begin + storechanged; +end; + +procedure tcomponentstorefo.checkchanged; +var + mstr1,mstr2: msestring; +begin + if fchanged then begin + mstr1:= '*'; + end + else begin + mstr1:= ''; + end; + if fgroupfilename = '' then begin + mstr2:= ''; + end + else begin + mstr2:= filename(fgroupfilename); + end; + dragdock.caption:= mstr1+c[ord(storecaption)]+' ('+mstr2+')'; +end; + +procedure tcomponentstorefo.storechanged; +begin + fchanged:= true; + checkchanged; +end; + +function tcomponentstorefo.saveall(const quiet: boolean): modalresultty; +begin + result:= mr_none; + if fchanged then begin + if fgroupfilename = '' then begin + result:= dosavegroupas(); + end + else begin + if quiet or confirmsavechangedfile(fgroupfilename,result) then begin + result:= writestoregroup(fgroupfilename); + end; + end; + end; +end; + +procedure tcomponentstorefo.opengroup(const sender: TObject); +begin + if canclose(nil) and (saveall(false) <> mr_cancel) then begin + with groupfiledialog,controller do begin + filename:= fgroupfilename; + if execute(fdk_open) = mr_ok then begin + if not findfile(filename) then begin + if askyesno(c[ord(str_file)]+filename+c[ord(doesnotexist)]) then begin + writestoregroup(filename); + end; + end + else begin + readstoregroup(filename); + end; + end; + end; + end; +end; + +procedure tcomponentstorefo.savegroup(const sender: TObject); +begin + if canclose(nil) then begin + if fgroupfilename = '' then begin + savegroupas(sender); + end + else begin + writestoregroup(fgroupfilename); + end; + end; +end; + +function tcomponentstorefo.dosavegroupas: modalresultty; +begin + with groupfiledialog,controller do begin + filename:= fgroupfilename; + result:= execute(fdk_save,c[ord(savecompstore)],[fdo_checkexist]); + if result = mr_ok then begin + result:= writestoregroup(filename); + end; + end; +end; + +procedure tcomponentstorefo.savegroupas(const sender: TObject); +begin + if canclose(nil) then begin + dosavegroupas; + end; +end; + +procedure tcomponentstorefo.nodeenter(const sender: TObject); +begin + copycompact.shortcut:= sysshortcuts[sho_copy]; + pastecompact.shortcut:= sysshortcuts[sho_paste]; +end; + +procedure tcomponentstorefo.nodeexit(const sender: TObject); +begin + copycompact.shortcut:= 0; + pastecompact.shortcut:= 0; +end; + +procedure tcomponentstorefo.setval(const sender: TObject; var avalue: Integer; + var accept: Boolean); +begin + if not iscomp and (avalue <> -1) then begin + accept:= false; + end + else begin + if avalue >= 0 then begin + componentpalettefo.resetselected; + end; + end; +end; + +procedure tcomponentstorefo.resetselected; +begin + sel.value:= -1; +end; + +function tcomponentstorefo.copyselected: string; +begin + result:= ''; + if sel.checkedrow >= 0 then begin + result:= copycomponent; + resetselected; + end; +end; + +function tcomponentstorefo.hasselection: boolean; +begin + result:= sel.checkedrow >= 0; +end; +{ +procedure tcomponentstorefo.selcha(const sender: tdatacol; + const aindex: Integer); +begin + if aindex >= 0 then begin + if tstoredcomponent(node[aindex]).fisnode then begin + if sel[aindex] <> -1 then begin //no recursion + sel[aindex]:= -1; + end; + end; + end; +end; +} +end. diff --git a/mseide-msegui/apps/ide/componentstore_mfm.pas b/mseide-msegui/apps/ide/componentstore_mfm.pas new file mode 100644 index 0000000..4708019 --- /dev/null +++ b/mseide-msegui/apps/ide/componentstore_mfm.pas @@ -0,0 +1,524 @@ +unit componentstore_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,componentstore; + +const + objdata: record size: integer; data: array[0..10139] of byte end = + (size: 10140; data: ( + 84,80,70,48,17,116,99,111,109,112,111,110,101,110,116,115,116,111,114,101, + 102,111,16,99,111,109,112,111,110,101,110,116,115,116,111,114,101,102,111,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117,115, + 13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116, + 111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101,2,10, + 18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110,115,11, + 14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111,95,102, + 105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108,111,97, + 116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110, + 19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110, + 15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95, + 98,117,116,116,111,110,104,105,110,116,115,0,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,49,1,8,98,111,117,110,100,115, + 95,121,2,101,9,98,111,117,110,100,115,95,99,120,3,189,1,9,98,111, + 117,110,100,115,95,99,121,3,98,1,26,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46, + 98,111,117,110,100,115,1,2,0,2,0,3,179,1,3,98,1,0,16,100, + 114,97,103,100,111,99,107,46,99,97,112,116,105,111,110,6,15,67,111,109, + 112,111,110,101,110,116,32,83,116,111,114,101,20,100,114,97,103,100,111,99, + 107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97, + 118,101,112,111,115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10, + 111,100,95,99,97,110,109,111,118,101,10,111,100,95,99,97,110,115,105,122, + 101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110, + 100,111,99,107,15,111,100,95,112,114,111,112,111,114,116,105,111,110,97,108, + 11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116, + 105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110, + 115,0,7,111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112, + 111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95, + 115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7, + 22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102, + 105,108,101,21,105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103, + 101,10,212,7,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,160,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237, + 237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229, + 229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235, + 235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234, + 234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,233,233,233,1,178,178,178,1,154,154,154,2,155,155,155,2,156,156, + 156,1,155,155,155,1,157,157,157,1,156,156,156,1,157,157,157,1,156,156, + 156,2,158,158,158,1,157,157,157,1,158,158,158,1,164,164,164,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,226,226,226,1,165,165,165,1,188,188,188,1,222,222,222,1,223,223, + 223,1,222,222,222,4,221,221,221,2,220,220,220,4,203,203,203,1,156,156, + 156,1,155,155,155,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,141,141,141,1,134,134,134,14,141,141, + 141,1,187,187,187,1,155,155,155,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,134,134,134,1,170,170, + 255,1,174,174,255,1,178,178,255,1,182,182,255,1,187,187,255,1,191,191, + 255,1,195,195,255,1,200,200,255,1,204,204,255,1,208,208,255,1,212,212, + 255,1,214,214,255,3,135,135,135,1,214,214,214,1,154,154,154,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,134,134,134,1,170,170,255,1,174,174,255,1,178,178,255,1,182,182, + 255,1,187,187,255,1,191,191,255,1,195,195,255,1,0,0,0,1,204,204, + 255,1,208,208,255,1,212,212,255,1,214,214,255,3,135,135,135,1,215,215, + 215,1,154,154,154,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,134,134,134,1,170,170,255,1,174,174, + 255,1,178,178,255,1,182,182,255,1,187,187,255,1,191,191,255,1,195,195, + 255,1,200,200,255,1,204,204,255,1,208,208,255,1,212,212,255,1,214,214, + 255,3,135,135,135,1,215,215,215,1,155,155,155,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,134,134, + 134,1,170,170,255,1,174,174,255,1,178,178,255,1,182,182,255,1,187,187, + 255,1,191,191,255,1,195,195,255,1,200,200,255,1,204,204,255,1,208,208, + 255,1,212,212,255,1,214,214,255,3,135,135,135,1,215,215,215,1,156,156, + 156,1,210,210,210,2,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,134,134,134,1,138,138,138,3,139,139,139,5,140,140,140,6,135,135, + 135,1,215,215,215,1,156,156,156,1,209,209,209,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,134,134,134,1,170,255, + 246,1,174,255,247,1,178,255,247,1,182,255,248,1,187,255,249,1,191,255, + 249,1,195,255,250,1,200,255,251,1,204,255,252,1,208,255,252,1,212,255, + 253,1,214,255,253,2,216,252,251,1,135,135,135,1,215,215,215,1,156,156, + 156,1,209,209,209,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,134,134,134,1,170,255,246,1,174,255,247,1,178,255, + 247,1,182,255,248,1,187,255,249,1,191,255,249,1,195,255,250,1,0,0, + 0,1,204,255,252,1,208,255,252,1,212,255,253,1,214,255,253,2,217,253, + 251,1,135,135,135,1,215,215,215,1,157,157,157,1,208,208,208,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,134,134, + 134,1,170,255,246,1,174,255,247,1,178,255,247,1,182,255,248,1,187,255, + 249,1,191,255,249,1,195,255,250,1,200,255,251,1,204,255,252,1,208,255, + 252,1,212,255,253,1,214,255,253,2,217,253,251,1,135,135,135,1,215,215, + 215,1,158,158,158,1,208,208,208,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,134,134,134,1,170,255,246,1,174,255, + 247,1,178,255,247,1,182,255,248,1,187,255,249,1,191,255,249,1,195,255, + 250,1,200,255,251,1,204,255,252,1,208,255,252,1,212,255,253,1,214,255, + 253,2,217,253,251,1,135,135,135,1,214,214,214,1,158,158,158,1,207,207, + 207,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,134,134,134,1,138,138,138,3,139,139,139,5,140,140,140,6,135,135, + 135,1,214,214,214,1,159,159,159,1,206,206,206,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,157,140,143,1,255,170, + 185,1,255,175,187,1,255,179,190,1,255,183,193,1,255,187,196,1,255,191, + 199,1,255,196,202,1,255,200,205,1,255,204,208,1,255,208,211,1,255,213, + 214,1,255,214,215,3,135,135,135,1,214,214,214,1,159,159,159,1,206,206, + 206,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,157,140,143,1,255,170,185,1,255,175,187,1,255,179,190,1,255,183, + 193,1,255,187,196,1,255,191,199,1,255,196,202,1,0,0,0,1,255,204, + 208,1,255,208,211,1,255,213,214,1,255,214,215,3,135,135,135,1,196,196, + 196,1,163,163,163,1,210,210,210,2,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,157,140,143,1,255,170,185,1,255,175,187,1,255,179, + 190,1,255,183,193,1,255,187,196,1,255,191,199,1,255,196,202,1,255,200, + 205,1,255,204,208,1,255,208,211,1,255,213,214,1,255,214,215,3,135,135, + 135,1,162,162,162,1,196,196,196,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,157,140,143,1,255,170, + 185,1,255,175,187,1,255,179,190,1,255,183,193,1,255,187,196,1,255,191, + 199,1,255,196,202,1,255,200,205,1,255,204,208,1,255,208,211,1,255,213, + 214,1,255,214,215,3,135,135,135,1,172,172,172,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,145,145,145,1,136,136,136,11,137,137,137,1,136,136,136,2,142,142, + 142,1,202,202,202,1,211,211,211,2,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,233,233,233,1,198,198,198,1,129,129, + 129,1,114,114,114,2,113,113,113,1,112,112,112,2,111,111,111,2,110,110, + 110,1,109,109,109,1,108,108,108,1,107,107,107,3,124,124,124,1,191,191, + 191,1,209,209,209,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,240,240,240,1,216,216,216,1,140,140,140,1,117,117,117,1,114,114, + 114,2,113,113,113,1,112,112,112,1,111,111,111,1,110,110,110,2,109,109, + 109,1,108,108,108,1,107,107,107,1,106,106,106,2,113,113,113,1,169,169, + 169,1,207,207,207,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,238,238,238,1,231,231,231,1,230,230, + 230,1,227,227,227,1,226,226,226,1,224,224,224,1,222,222,222,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,209,209,209,1,212,212,212,2,211,211, + 211,1,210,210,210,1,208,208,208,1,8,111,110,99,114,101,97,116,101,7, + 9,99,114,101,97,116,101,101,120,101,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,9,112,111,112,117,112, + 109,101,110,117,7,11,116,112,111,112,117,112,109,101,110,117,49,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,179,1,9,98,111,117,110,100,115,95, + 99,121,3,98,1,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105, + 111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110, + 103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101, + 114,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107, + 101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108, + 108,99,111,108,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,4,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,4,78,97,109,101,0,1,7,99,97,112, + 116,105,111,110,6,3,83,101,108,4,104,105,110,116,6,25,83,101,108,101, + 99,116,32,105,116,101,109,32,102,111,114,32,105,110,115,101,114,116,105,110, + 103,0,1,7,99,97,112,116,105,111,110,6,11,68,101,115,99,114,105,112, + 116,105,111,110,0,1,7,99,97,112,116,105,111,110,6,4,70,105,108,101, + 0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2, + 4,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,15, + 99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115, + 97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101, + 109,115,14,7,4,110,111,100,101,1,5,119,105,100,116,104,2,110,7,111, + 112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115, + 15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95, + 115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6, + 4,110,111,100,101,9,100,97,116,97,99,108,97,115,115,7,17,116,116,114, + 101,101,105,116,101,109,101,100,105,116,108,105,115,116,22,100,97,116,97,108, + 105,115,116,46,105,109,110,114,95,101,120,112,97,110,100,101,100,2,1,18, + 100,97,116,97,108,105,115,116,46,105,109,97,103,101,108,105,115,116,7,20, + 102,105,108,101,100,105,97,108,111,103,114,101,115,46,105,109,97,103,101,115, + 19,100,97,116,97,108,105,115,116,46,105,109,97,103,101,119,105,100,116,104, + 2,16,20,100,97,116,97,108,105,115,116,46,105,109,97,103,101,104,101,105, + 103,104,116,2,16,23,100,97,116,97,108,105,115,116,46,111,110,115,116,97, + 116,114,101,97,100,105,116,101,109,7,14,100,111,115,116,97,116,114,101,97, + 100,105,116,101,109,19,100,97,116,97,108,105,115,116,46,111,110,100,114,97, + 103,111,118,101,114,7,5,100,114,97,103,111,19,100,97,116,97,108,105,115, + 116,46,111,110,100,114,97,103,100,114,111,112,7,7,100,114,97,103,100,114, + 111,0,7,3,115,101,108,1,5,99,111,108,111,114,4,2,0,0,128,5, + 119,105,100,116,104,2,28,7,111,112,116,105,111,110,115,11,11,99,111,95, + 102,105,120,119,105,100,116,104,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,8,119,105,100, + 116,104,109,105,110,2,0,10,119,105,100,103,101,116,110,97,109,101,6,3, + 115,101,108,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,8,99,111, + 109,112,100,101,115,99,1,5,119,105,100,116,104,2,103,7,111,112,116,105, + 111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101, + 115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,8,99,111,109, + 112,100,101,115,99,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114, + 105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0, + 7,8,102,105,108,101,112,97,116,104,1,5,119,105,100,116,104,3,186,0, + 7,111,112,116,105,111,110,115,11,15,99,111,95,112,114,111,112,111,114,116, + 105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,8,102,105,108,101,112,97,116,104,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105,108,101,7, + 22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102, + 105,108,101,11,111,110,99,101,108,108,101,118,101,110,116,7,11,100,111,99, + 101,108,108,101,118,101,110,116,22,100,114,97,103,46,111,110,98,101,102,111, + 114,101,100,114,97,103,98,101,103,105,110,7,10,98,101,102,111,114,101,100, + 114,97,103,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 13,116,116,114,101,101,105,116,101,109,101,100,105,116,4,110,111,100,101,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,1,7,111,110,101,110,116,101,114,7,9,110,111,100,101,101,110,116,101, + 114,6,111,110,101,120,105,116,7,8,110,111,100,101,101,120,105,116,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 110,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,9,111,101,95,108,111,99,97,116,101,0,13,111,110,100,97,116, + 97,101,110,116,101,114,101,100,7,6,100,97,116,101,110,116,10,111,110,115, + 101,116,118,97,108,117,101,7,13,99,111,109,112,110,97,109,101,115,101,116, + 118,97,17,111,110,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115, + 7,17,100,111,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115,7, + 111,112,116,105,111,110,115,11,16,116,101,111,95,116,114,101,101,99,111,108, + 110,97,118,105,103,16,116,101,111,95,107,101,121,114,111,119,109,111,118,105, + 110,103,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,11,116,100,97,116,97,98,117,116,116,111,110,3,115,101,108,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,111,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,28,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109, + 101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111, + 101,49,95,115,97,118,101,115,116,97,116,101,0,7,111,112,116,105,111,110, + 115,11,17,98,111,95,101,120,101,99,117,116,101,111,110,99,108,105,99,107, + 15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98,111,95, + 101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27,98,111, + 95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101,110,116, + 101,114,107,101,121,15,98,111,95,114,97,100,105,111,105,116,101,109,99,111, + 108,12,98,111,95,99,97,110,116,111,103,103,108,101,24,98,111,95,114,101, + 115,101,116,99,104,101,99,107,101,100,111,110,114,111,119,101,120,105,116,0, + 5,115,116,97,116,101,11,12,97,115,95,105,110,118,105,115,105,98,108,101, + 17,97,115,95,108,111,99,97,108,105,110,118,105,115,105,98,108,101,0,16, + 118,97,108,117,101,102,97,99,101,115,46,99,111,117,110,116,2,1,16,118, + 97,108,117,101,102,97,99,101,115,46,105,116,101,109,115,14,1,14,102,97, + 100,101,95,112,111,115,46,99,111,117,110,116,2,2,14,102,97,100,101,95, + 112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,16,102,97,100,101, + 95,99,111,108,111,114,46,99,111,117,110,116,2,2,16,102,97,100,101,95, + 99,111,108,111,114,46,105,116,101,109,115,1,4,7,0,0,160,4,135,223, + 255,0,0,14,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,7, + 103,100,95,100,111,119,110,10,108,111,99,97,108,112,114,111,112,115,11,15, + 102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,0,0,0,10,111, + 110,115,101,116,118,97,108,117,101,7,6,115,101,116,118,97,108,0,0,15, + 116,109,101,109,111,100,105,97,108,111,103,101,100,105,116,8,99,111,109,112, + 100,101,115,99,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1, + 5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2, + 17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108, + 111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110, + 46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2, + 3,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3, + 140,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,103,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101, + 116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,18,111,101,95,104,105,110,116,99,108,105,112, + 112,101,100,116,101,120,116,0,13,111,110,100,97,116,97,101,110,116,101,114, + 101,100,7,6,100,97,116,101,110,116,10,111,110,115,101,116,118,97,108,117, + 101,7,13,99,111,109,112,100,101,115,99,115,101,116,118,97,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101, + 110,97,109,101,101,100,105,116,8,102,105,108,101,112,97,116,104,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111, + 110,116,103,108,121,112,104,104,101,105,103,104,116,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4, + 5,0,0,144,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97, + 109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144, + 20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110, + 114,2,17,8,116,97,98,111,114,100,101,114,2,4,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,244,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,186,0,9, + 98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116, + 102,95,101,108,108,105,112,115,101,108,101,102,116,0,13,111,110,100,97,116, + 97,101,110,116,101,114,101,100,7,6,100,97,116,101,110,116,10,111,110,115, + 101,116,118,97,108,117,101,7,13,102,105,108,101,110,97,109,101,115,101,116, + 118,97,26,99,111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114, + 108,105,115,116,46,100,97,116,97,1,1,6,14,67,111,109,112,111,110,101, + 110,116,32,70,105,108,101,6,5,42,46,99,109,112,0,1,6,9,65,108, + 108,32,70,105,108,101,115,6,1,42,0,0,21,99,111,110,116,114,111,108, + 108,101,114,46,100,101,102,97,117,108,116,101,120,116,6,3,99,109,112,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,7,116, + 97,99,116,105,111,110,11,99,111,112,121,99,111,109,112,97,99,116,7,99, + 97,112,116,105,111,110,6,15,38,67,111,112,121,32,67,111,109,112,111,110, + 101,110,116,7,111,112,116,105,111,110,115,11,16,97,111,95,108,111,99,97, + 108,115,104,111,114,116,99,117,116,0,9,111,110,101,120,101,99,117,116,101, + 7,15,100,111,99,111,112,121,99,111,109,112,111,110,101,110,116,8,111,110, + 117,112,100,97,116,101,7,8,99,111,112,121,117,112,100,97,4,108,101,102, + 116,3,176,0,3,116,111,112,2,64,0,0,7,116,97,99,116,105,111,110, + 12,112,97,115,116,101,99,111,109,112,97,99,116,7,99,97,112,116,105,111, + 110,6,19,38,80,97,115,116,101,32,67,111,109,112,111,110,101,110,116,40, + 115,41,7,111,112,116,105,111,110,115,11,16,97,111,95,108,111,99,97,108, + 115,104,111,114,116,99,117,116,0,9,111,110,101,120,101,99,117,116,101,7, + 16,100,111,112,97,115,116,101,99,111,109,112,111,110,101,110,116,8,111,110, + 117,112,100,97,116,101,7,9,112,97,115,116,101,117,112,100,97,4,108,101, + 102,116,3,176,0,3,116,111,112,2,88,0,0,10,116,112,111,112,117,112, + 109,101,110,117,11,116,112,111,112,117,112,109,101,110,117,49,8,111,110,117, + 112,100,97,116,101,7,11,112,111,112,117,112,117,112,100,97,116,101,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,18,18, + 109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1, + 6,97,99,116,105,111,110,7,11,99,111,112,121,99,111,109,112,97,99,116, + 7,99,97,112,116,105,111,110,6,18,38,67,111,112,121,32,67,111,109,112, + 111,110,101,110,116,40,115,41,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111, + 110,7,12,112,97,115,116,101,99,111,109,112,97,99,116,0,1,6,97,99, + 116,105,111,110,7,10,97,100,100,102,105,108,101,97,99,116,0,1,7,99, + 97,112,116,105,111,110,6,19,85,112,100,97,116,101,32,67,111,109,112,111, + 110,101,110,116,40,115,41,4,110,97,109,101,6,10,117,112,100,97,116,101, + 110,111,100,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,17,100,111, + 117,112,100,97,116,101,99,111,109,112,111,110,101,110,116,0,1,7,99,97, + 112,116,105,111,110,6,19,82,101,109,111,118,101,32,67,111,109,112,111,110, + 101,110,116,40,115,41,4,110,97,109,101,6,10,114,101,109,111,118,101,99, + 111,109,112,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,10,114,101,109, + 111,118,101,99,111,109,112,0,1,7,111,112,116,105,111,110,115,11,13,109, + 97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111, + 114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116, + 105,111,110,6,9,78,101,119,32,32,78,111,100,101,4,110,97,109,101,6, + 7,97,100,100,110,111,100,101,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,9,100,111,110,101,119,110,111,100,101,0,1,7,99,97,112,116,105,111, + 110,6,11,82,101,109,111,118,101,32,78,111,100,101,4,110,97,109,101,6, + 10,114,101,109,111,118,101,110,111,100,101,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,7,100,101,108,110,111,100,101,0,1,7,99,97,112,116,105, + 111,110,6,9,67,111,112,121,32,78,111,100,101,4,110,97,109,101,6,8, + 99,111,112,121,110,111,100,101,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,10,99,111,112,121,110,111,100,101,101,120,0,1,7,99,97,112,116,105, + 111,110,6,10,80,97,115,116,101,32,78,111,100,101,4,110,97,109,101,6, + 9,112,97,115,116,101,110,111,100,101,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117, + 116,101,7,11,112,97,115,116,101,110,111,100,101,101,120,0,1,7,111,112, + 116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 0,0,1,7,99,97,112,116,105,111,110,6,9,78,101,119,32,83,116,111, + 114,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,10,110,101,119,115, + 116,111,114,101,101,120,0,1,7,99,97,112,116,105,111,110,6,9,65,100, + 100,32,83,116,111,114,101,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 10,97,100,100,115,116,111,114,101,101,120,0,1,7,99,97,112,116,105,111, + 110,6,12,82,101,109,111,118,101,32,83,116,111,114,101,4,110,97,109,101, + 6,11,114,101,109,111,118,101,115,116,111,114,101,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120, + 101,99,117,116,101,7,13,114,101,109,111,118,101,115,116,111,114,101,101,120, + 0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97, + 114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,16,79,112, + 101,110,32,83,116,111,114,101,32,71,114,111,117,112,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,9,111,112,101,110,103,114,111,117,112,0,1,7, + 99,97,112,116,105,111,110,6,16,83,97,118,101,32,83,116,111,114,101,32, + 71,114,111,117,112,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,9,115, + 97,118,101,103,114,111,117,112,0,1,7,99,97,112,116,105,111,110,6,19, + 83,97,118,101,32,83,116,111,114,101,32,71,114,111,117,112,32,97,115,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,111,110,101,120,101,99,117,116,101,7,11,115,97,118,101,103,114,111, + 117,112,97,115,0,0,4,108,101,102,116,2,40,3,116,111,112,2,88,0, + 0,9,116,115,116,97,116,102,105,108,101,9,115,116,111,114,101,102,105,108, + 101,8,102,105,108,101,110,97,109,101,6,9,115,116,111,114,101,46,115,116, + 97,10,111,110,115,116,97,116,114,101,97,100,7,11,115,116,97,116,114,101, + 97,100,101,120,101,11,111,110,115,116,97,116,119,114,105,116,101,7,12,115, + 116,97,116,119,114,105,116,101,101,120,101,4,108,101,102,116,3,40,1,3, + 116,111,112,2,88,0,0,11,116,102,105,108,101,100,105,97,108,111,103,15, + 115,116,111,114,101,102,105,108,101,100,105,97,108,111,103,8,115,116,97,116, + 102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116, + 115,116,97,116,102,105,108,101,26,99,111,110,116,114,111,108,108,101,114,46, + 102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,16,67, + 111,109,112,111,110,101,110,116,32,83,116,111,114,101,115,6,5,42,46,115, + 116,111,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102,97, + 117,108,116,101,120,116,6,3,115,116,111,18,99,111,110,116,114,111,108,108, + 101,114,46,111,112,116,105,111,110,115,11,14,102,100,111,95,99,104,101,99, + 107,101,120,105,115,116,15,102,100,111,95,115,97,118,101,108,97,115,116,100, + 105,114,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116,105, + 111,110,111,112,101,110,6,20,76,111,97,100,32,67,111,109,112,111,110,101, + 110,116,32,83,116,111,114,101,22,99,111,110,116,114,111,108,108,101,114,46, + 99,97,112,116,105,111,110,115,97,118,101,6,19,78,101,119,32,67,111,109, + 112,111,110,101,110,116,32,83,116,111,114,101,4,108,101,102,116,2,40,3, + 116,111,112,3,136,0,0,0,11,116,102,105,108,101,100,105,97,108,111,103, + 15,103,114,111,117,112,102,105,108,101,100,105,97,108,111,103,8,115,116,97, + 116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,102,105,108,101,26,99,111,110,116,114,111,108,108,101,114, + 46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,12, + 83,116,111,114,101,32,71,114,111,117,112,115,6,5,42,46,115,116,103,0, + 0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102,97,117,108,116, + 101,120,116,6,3,115,116,103,22,99,111,110,116,114,111,108,108,101,114,46, + 99,97,112,116,105,111,110,111,112,101,110,6,16,79,112,101,110,32,83,116, + 111,114,101,32,71,114,111,117,112,22,99,111,110,116,114,111,108,108,101,114, + 46,99,97,112,116,105,111,110,115,97,118,101,6,16,83,97,118,101,32,83, + 116,111,114,101,32,71,114,111,117,112,4,108,101,102,116,2,40,3,116,111, + 112,3,168,0,0,0,7,116,97,99,116,105,111,110,10,97,100,100,102,105, + 108,101,97,99,116,7,99,97,112,116,105,111,110,6,17,65,100,100,32,67, + 111,109,112,111,110,101,110,116,102,105,108,101,9,111,110,101,120,101,99,117, + 116,101,7,9,100,111,97,100,100,102,105,108,101,8,111,110,117,112,100,97, + 116,101,7,9,112,97,115,116,101,117,112,100,97,4,108,101,102,116,3,176, + 0,3,116,111,112,2,112,0,0,11,116,102,105,108,101,100,105,97,108,111, + 103,14,99,111,109,112,102,105,108,101,100,105,97,108,111,103,8,115,116,97, + 116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,102,105,108,101,26,99,111,110,116,114,111,108,108,101,114, + 46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,14, + 67,111,109,112,111,110,101,110,116,32,70,105,108,101,6,5,42,46,99,109, + 112,0,1,6,9,65,108,108,32,70,105,108,101,115,6,1,42,0,0,21, + 99,111,110,116,114,111,108,108,101,114,46,100,101,102,97,117,108,116,101,120, + 116,6,3,99,109,112,18,99,111,110,116,114,111,108,108,101,114,46,111,112, + 116,105,111,110,115,11,14,102,100,111,95,99,104,101,99,107,101,120,105,115, + 116,15,102,100,111,95,115,97,118,101,108,97,115,116,100,105,114,0,22,99, + 111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101, + 110,6,21,83,101,108,101,99,116,32,67,111,109,112,111,110,101,110,116,32, + 70,105,108,101,4,108,101,102,116,2,40,3,116,111,112,3,200,0,0,0, + 16,116,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12, + 115,116,114,105,110,103,115,46,100,97,116,97,1,6,15,67,111,109,112,111, + 110,101,110,116,32,83,116,111,114,101,6,21,67,111,109,112,111,110,101,110, + 116,32,114,101,97,100,32,101,114,114,111,114,46,6,26,68,111,32,121,111, + 117,32,119,97,110,116,32,116,111,32,111,118,101,114,119,114,105,116,101,32, + 34,6,33,34,32,119,105,116,104,32,99,117,114,114,101,110,116,32,99,108, + 105,112,98,111,97,114,100,32,99,111,110,116,101,110,116,63,6,7,87,65, + 82,78,73,78,71,6,29,78,111,32,99,111,109,112,111,110,101,110,116,40, + 115,41,32,105,110,32,99,108,105,112,98,111,97,114,100,46,6,35,69,114, + 114,111,114,32,119,104,105,108,101,32,119,114,105,116,105,110,103,32,116,104, + 101,32,115,116,111,114,101,103,114,111,117,112,46,6,5,69,82,82,79,82, + 6,23,68,111,32,121,111,117,32,119,97,110,116,32,116,111,32,114,101,109, + 111,118,101,32,34,6,2,34,63,6,9,34,32,98,114,97,110,99,104,63, + 6,6,70,105,108,101,32,34,6,43,34,32,100,111,101,115,32,110,111,116, + 32,101,120,105,115,116,44,32,100,111,32,121,111,117,32,119,97,110,116,32, + 116,111,32,99,114,101,97,116,101,32,105,116,63,6,26,83,97,118,101,32, + 67,111,109,112,111,110,101,110,116,32,83,116,111,114,101,32,71,114,111,117, + 112,0,4,108,101,102,116,3,40,1,3,116,111,112,3,144,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcomponentstorefo,''); +end. diff --git a/mseide-msegui/apps/ide/compstore/dummy b/mseide-msegui/apps/ide/compstore/dummy new file mode 100644 index 0000000..b3eff39 --- /dev/null +++ b/mseide-msegui/apps/ide/compstore/dummy @@ -0,0 +1 @@ +git dummy file for empty directory. diff --git a/mseide-msegui/apps/ide/cpuarmform.mfm b/mseide-msegui/apps/ide/cpuarmform.mfm new file mode 100644 index 0000000..901b7d8 --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmform.mfm @@ -0,0 +1,997 @@ +inherited cpuarmfo: tcpuarmfo + bounds_x = 174 + bounds_y = 158 + bounds_cx = 264 + bounds_cy = 276 + container.bounds = ( + 0 + 0 + 254 + 276 + ) + caption = 'CPU ARM' + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + bounds_x = 152 + bounds_y = 4 + end + inherited stoptime: tdatetimedisp + bounds_x = 0 + bounds_y = 0 + end + object tspacer1: tspacer[2] + taborder = 2 + visible = True + bounds_x = 0 + bounds_y = 20 + bounds_cx = 248 + bounds_cy = 238 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = stoptime + object tlayouter1: tlayouter + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 40 + bounds_cx = 107 + bounds_cy = 198 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placey] + place_maxdist = 0 + linkright = tlayouter2 + dist_right = 3 + object r1: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r1' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 13 + 0 + ) + bounds_x = 0 + bounds_y = 22 + bounds_cx = 106 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r0: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r0' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r4: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r4' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 88 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r3: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r3' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 66 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r2: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r2' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 44 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r5: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r5' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 110 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r6: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r6' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 132 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r7: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r7' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 154 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r8: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r8' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 8 + bounds_x = 0 + bounds_y = 176 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + end + object tbooleanedit16: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 237 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tbooleanedit17: tbooleanedit + Tag = 1 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'e' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 2 + bounds_x = 226 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit18: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 3 + bounds_x = 215 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit19: tbooleanedit + Tag = 3 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'o' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 4 + bounds_x = 204 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit20: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'M' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 1 + 0 + ) + taborder = 5 + bounds_x = 193 + bounds_y = 6 + bounds_cx = 12 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit15: tbooleanedit + Tag = 9 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'E' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 6 + bounds_x = 134 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit14: tbooleanedit + Tag = 6 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'F' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 7 + bounds_x = 167 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit13: tbooleanedit + Tag = 8 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'A' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 8 + bounds_x = 145 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit12: tbooleanedit + Tag = 5 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'T' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 9 + bounds_x = 178 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit11: tbooleanedit + Tag = 7 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'I' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 10 + bounds_x = 156 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit10: tbooleanedit + Tag = 19 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 11 + bounds_x = 86 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tbooleanedit9: tbooleanedit + Tag = 18 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'G' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 12 + bounds_x = 97 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit8: tbooleanedit + Tag = 17 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'E' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 13 + bounds_x = 108 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit7: tbooleanedit + Tag = 16 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 14 + bounds_x = 119 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tbooleanedit6: tbooleanedit + Tag = 24 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'J' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 15 + bounds_x = 68 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit5: tbooleanedit + Tag = 27 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Q' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 16 + bounds_x = 50 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit4: tbooleanedit + Tag = 28 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'V' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 17 + bounds_x = 39 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit3: tbooleanedit + Tag = 29 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 18 + bounds_x = 28 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit2: tbooleanedit + Tag = 30 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 19 + bounds_x = 17 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object c: tbooleanedit + Tag = 31 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'N' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 20 + bounds_x = 6 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tlayouter2: tlayouter + frame.localprops = [] + frame.localprops1 = [] + taborder = 21 + bounds_x = 110 + bounds_y = 40 + bounds_cx = 121 + bounds_cy = 198 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placey] + place_maxdist = 0 + dist_bottom = 3 + object r11: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r11' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + bounds_x = 0 + bounds_y = 44 + bounds_cx = 112 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r10: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r10' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 20 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 22 + bounds_cx = 113 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r9: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r9' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object fps: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'fps' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 21 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 154 + bounds_cx = 114 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object cpsr: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'cpsr' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 28 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 176 + bounds_cx = 121 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r12: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r12' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 20 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 66 + bounds_cx = 113 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object sp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'sp' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 132 + bounds_cx = 110 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object lr: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'lr' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 10 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 110 + bounds_cx = 103 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object pc: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'pc' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 8 + bounds_x = 0 + bounds_y = 88 + bounds_cx = 110 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + end + end +end diff --git a/mseide-msegui/apps/ide/cpuarmform.pas b/mseide-msegui/apps/ide/cpuarmform.pas new file mode 100644 index 0000000..e56e22d --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmform.pas @@ -0,0 +1,133 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpuarmform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,cpuform,msesplitter,msedataedits, + mseedit,msestrings,msetypes,msegraphedits,mseifiglob; + +type + tcpuarmfo = class(tcpufo) + tspacer1: tspacer; + tspacer2: tspacer; + tlayouter1: tlayouter; + r1: tintegeredit; + r0: tintegeredit; + r4: tintegeredit; + r3: tintegeredit; + r2: tintegeredit; + r5: tintegeredit; + tbooleanedit16: tbooleanedit; + tbooleanedit17: tbooleanedit; + tbooleanedit18: tbooleanedit; + tbooleanedit19: tbooleanedit; + tbooleanedit20: tbooleanedit; + tbooleanedit15: tbooleanedit; + tbooleanedit14: tbooleanedit; + tbooleanedit13: tbooleanedit; + tbooleanedit12: tbooleanedit; + tbooleanedit11: tbooleanedit; + tbooleanedit10: tbooleanedit; + tbooleanedit9: tbooleanedit; + tbooleanedit8: tbooleanedit; + tbooleanedit7: tbooleanedit; + tbooleanedit6: tbooleanedit; + tbooleanedit5: tbooleanedit; + tbooleanedit4: tbooleanedit; + tbooleanedit3: tbooleanedit; + tbooleanedit2: tbooleanedit; + c: tbooleanedit; + tlayouter2: tlayouter; + r11: tintegeredit; + r10: tintegeredit; + r9: tintegeredit; + fps: tintegeredit; + cpsr: tintegeredit; + r12: tintegeredit; + sp: tintegeredit; + r6: tintegeredit; + lr: tintegeredit; + pc: tintegeredit; + r7: tintegeredit; + r8: tintegeredit; + procedure regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure flagonchange(const sender: TObject); + protected + procedure updateregisternames() override; + public + constructor create(aowner: tcomponent); override; + function flagedit(const aindex: integer): tcustombooleanedit; override; + end; + +implementation +uses + cpuarmform_mfm; + +{ tcpuarmfo } + +constructor tcpuarmfo.create(aowner: tcomponent); +begin + inherited create(aowner); + fflagswidget:= cpsr; +end; + +procedure tcpuarmfo.updateregisternames(); +var + comp1: tintegeredit; + i1: int32; +begin + comp1:= cpsr; + cpsr.name:= 'cpsr'; + for i1 := high(fregisternames) downto 0 do begin + if fregisternames[i1] = 'xpsr' then begin //for segger j-link + cpsr.name:= 'xpsr'; + break; + end; + end; + cpsr:= comp1; + cpsr.frame.caption:= msestring(cpsr.name); +end; + +procedure tcpuarmfo.regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); +begin + doregsetvalue(sender,avalue,accept); +end; + +procedure tcpuarmfo.flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; + +procedure tcpuarmfo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +function tcpuarmfo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= c.tagitem(aindex); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpuarmform_mfm.pas b/mseide-msegui/apps/ide/cpuarmform_mfm.pas new file mode 100644 index 0000000..0bf840e --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmform_mfm.pas @@ -0,0 +1,843 @@ +unit cpuarmform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpuarmform; + +const + objdata: record size: integer; data: array[0..16510] of byte end = + (size: 16511; data: ( + 84,80,70,48,241,9,116,99,112,117,97,114,109,102,111,8,99,112,117,97, + 114,109,102,111,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111,117, + 110,100,115,95,121,3,158,0,9,98,111,117,110,100,115,95,99,120,3,8, + 1,9,98,111,117,110,100,115,95,99,121,3,20,1,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,254,0,3, + 20,1,0,7,99,97,112,116,105,111,110,6,7,67,80,85,32,65,82,77, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,6,116,99, + 112,117,102,111,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,2, + 111,110,8,98,111,117,110,100,115,95,120,3,152,0,8,98,111,117,110,100, + 115,95,121,2,4,0,0,241,13,116,100,97,116,101,116,105,109,101,100,105, + 115,112,8,115,116,111,112,116,105,109,101,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,0,0,242,2,2,7,116, + 115,112,97,99,101,114,8,116,115,112,97,99,101,114,49,8,116,97,98,111, + 114,100,101,114,2,2,7,118,105,115,105,98,108,101,9,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,20,9,98,111, + 117,110,100,115,95,99,120,3,248,0,9,98,111,117,110,100,115,95,99,121, + 3,238,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107, + 120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104, + 114,105,110,107,121,0,7,108,105,110,107,116,111,112,7,8,115,116,111,112, + 116,105,109,101,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121, + 111,117,116,101,114,49,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,40,9,98,111,117,110,100,115,95,99,120,2,107,9, + 98,111,117,110,100,115,95,99,121,3,198,0,12,111,112,116,105,111,110,115, + 115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111, + 115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110, + 100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105, + 111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101, + 121,0,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,0,9,108, + 105,110,107,114,105,103,104,116,7,10,116,108,97,121,111,117,116,101,114,50, + 10,100,105,115,116,95,114,105,103,104,116,2,3,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,2,114,49,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,2,114,49,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102, + 95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,13,2,0,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,22,9,98,111,117,110,100,115, + 95,99,120,2,106,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,114,48,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,48, + 22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,2,114,52,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,52,22,102, + 114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98, + 111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,88,9,98,111,117,110,100,115,95,99,120,2, + 107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,2,114,51,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,51,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114, + 100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,66,9,98,111,117,110,100,115,95,99,120,2,107,9, + 98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,2,114,50,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,2,114,50,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116, + 102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114,100,101, + 114,2,4,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,44,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111, + 117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,2,114,53,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,2,114,53,22,102,114,97,109,101,46,99, + 97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2, + 5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,110,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111,117,110, + 100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,2,114,54,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,2,114,54,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99, + 101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,0,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,6,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3, + 132,0,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100, + 115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,114,55,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,2,114,55,22,102,114,97,109,101,46,99,97,112,116, + 105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,7,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,154, + 0,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100,115, + 95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100, + 105,116,2,114,56,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,2,114,56,22,102,114,97,109,101,46,99,97,112,116,105, + 111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110, + 116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,176,0, + 9,98,111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100,115,95, + 99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,18,0,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,54,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,237,0, + 8,98,111,117,110,100,115,95,121,2,25,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,11,10,111,110,115,101, + 116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117, + 101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111, + 111,108,101,97,110,101,100,105,116,49,55,3,84,97,103,2,1,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,1,101,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,3,226,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110, + 100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10, + 111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116, + 118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 14,116,98,111,111,108,101,97,110,101,100,105,116,49,56,3,84,97,103,2, + 2,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,100,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,3,215,0,8,98,111,117,110,100,115,95,121,2,6,9, + 98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99, + 121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103, + 115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,57,3, + 84,97,103,2,3,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,111,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,4, + 8,98,111,117,110,100,115,95,120,3,204,0,8,98,111,117,110,100,115,95, + 121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13, + 102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105, + 116,50,48,3,84,97,103,2,4,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,1,77,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,19,2,1,2,0,0,8,116,97,98,111,114,100, + 101,114,2,5,8,98,111,117,110,100,115,95,120,3,193,0,8,98,111,117, + 110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,12,9, + 98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108, + 117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97, + 110,101,100,105,116,49,53,3,84,97,103,2,9,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,69,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,134,0, + 8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101, + 116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117, + 101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111, + 111,108,101,97,110,101,100,105,116,49,52,3,84,97,103,2,6,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,1,70,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95, + 120,3,167,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110, + 100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10, + 111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116, + 118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 14,116,98,111,111,108,101,97,110,101,100,105,116,49,51,3,84,97,103,2, + 8,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,65,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111,117, + 110,100,115,95,120,3,145,0,8,98,111,117,110,100,115,95,121,2,6,9, + 98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99, + 121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103, + 115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,50,3, + 84,97,103,2,5,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,84,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,9, + 8,98,111,117,110,100,115,95,120,3,178,0,8,98,111,117,110,100,115,95, + 121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13, + 102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105, + 116,49,49,3,84,97,103,2,7,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,1,73,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,10,8,98,111,117,110,100,115,95,120,3,156,0,8,98,111,117, + 110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9, + 98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108, + 117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97, + 110,101,100,105,116,49,48,3,84,97,103,2,19,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100, + 101,114,2,11,8,98,111,117,110,100,115,95,120,2,86,8,98,111,117,110, + 100,115,95,121,2,25,9,98,111,117,110,100,115,95,99,120,2,11,9,98, + 111,117,110,100,115,95,99,121,2,11,10,111,110,115,101,116,118,97,108,117, + 101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110, + 101,100,105,116,57,3,84,97,103,2,18,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,71,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,12,8,98,111,117,110,100,115,95,120,2,97,8,98,111, + 117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97, + 108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101, + 97,110,101,100,105,116,56,3,84,97,103,2,17,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,69,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,13,8,98,111,117,110,100,115,95,120,2,108,8, + 98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120, + 2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116, + 118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111, + 108,101,97,110,101,100,105,116,55,3,84,97,103,2,16,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,14,8,98,111,117,110,100,115,95,120,2,119,8,98,111, + 117,110,100,115,95,121,2,25,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,11,10,111,110,115,101,116,118,97, + 108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101, + 97,110,101,100,105,116,54,3,84,97,103,2,24,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,74,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,15,8,98,111,117,110,100,115,95,120,2,68,8, + 98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120, + 2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116, + 118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111, + 108,101,97,110,101,100,105,116,53,3,84,97,103,2,27,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 81,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,16,8,98,111,117,110,100,115,95,120,2, + 50,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95, + 99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115, + 101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108, + 117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,52,3,84,97,103,2,28,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,1,86,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,17,8,98,111,117,110,100,115,95, + 120,2,39,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100, + 115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111, + 110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118, + 97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13, + 116,98,111,111,108,101,97,110,101,100,105,116,51,3,84,97,103,2,29,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,67,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,18,8,98,111,117,110,100, + 115,95,120,2,28,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117, + 110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30, + 10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101, + 116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,13,116,98,111,111,108,101,97,110,101,100,105,116,50,3,84,97,103,2, + 30,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,90,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,19,8,98,111,117, + 110,100,115,95,120,2,17,8,98,111,117,110,100,115,95,121,2,6,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115, + 115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,1,99,3,84,97,103,2,31,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,78,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,20,8,98,111,117,110,100,115,95,120,2,6,8,98,111, + 117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97, + 108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0, + 9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114, + 50,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,21,8,98,111,117,110,100,115,95,120, + 2,110,8,98,111,117,110,100,115,95,121,2,40,9,98,111,117,110,100,115, + 95,99,120,2,121,9,98,111,117,110,100,115,95,99,121,3,198,0,12,111, + 112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112, + 97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99, + 95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121, + 0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111, + 95,112,108,97,99,101,121,0,13,112,108,97,99,101,95,109,97,120,100,105, + 115,116,2,0,11,100,105,115,116,95,98,111,116,116,111,109,2,3,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,3,114,49,49,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,114,49,49, + 22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,19,2,0,0,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,44, + 9,98,111,117,110,100,115,95,99,120,2,112,9,98,111,117,110,100,115,95, + 99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,3,114,49,48,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,3,114,49,48,22,102,114,97,109,101,46,99,97,112,116, + 105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,20,2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,22, + 9,98,111,117,110,100,115,95,99,120,2,113,9,98,111,117,110,100,115,95, + 99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,2,114,57,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,2,114,57,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116, + 101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0, + 2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100,115,95,99,121, + 2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,118,97, + 108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,3, + 102,112,115,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,3,102,112,115,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116, + 101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0, + 2,21,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,154,0,9, + 98,111,117,110,100,115,95,99,120,2,114,9,98,111,117,110,100,115,95,99, + 121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,118, + 97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116, + 4,99,112,115,114,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,4,99,112,115,114,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99, + 101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,0,2,28,2,0,0,8,116,97,98,111,114,100,101,114,2,4,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3, + 176,0,9,98,111,117,110,100,115,95,99,120,2,121,9,98,111,117,110,100, + 115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,8,111,110,99,104,97,110,103,101,7,12,102,108,97,103,111, + 110,99,104,97,110,103,101,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,3,114,49,50,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,3,114,49,50,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116, + 102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,20,2,0,0,8,116,97,98,111,114,100,101, + 114,2,5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,66,9,98,111,117,110,100,115,95,99,120,2,113,9,98,111, + 117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,2,115,112,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,2,115,112,22,102,114,97,109,101,46,99, + 97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,0,2,17,2,0,0,8,116,97,98,111,114,100,101,114,2, + 6,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,3,132,0,9,98,111,117,110,100,115,95,99,120,2,110,9,98,111,117, + 110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,2,108,114,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,2,108,114,22,102,114,97,109,101,46,99,97, + 112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121, + 99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,10,2,0,0,8,116,97,98,111,114,100,101,114,2,7, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,110,9,98,111,117,110,100,115,95,99,120,2,103,9,98,111,117,110,100, + 115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,112,99,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,2,112,99,22,102,114,97,109,101,46,99,97,112,116, + 105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,17,2,0,0,8,116,97,98,111,114,100,101,114,2,8,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,88, + 9,98,111,117,110,100,115,95,99,120,2,110,9,98,111,117,110,100,115,95, + 99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,18,0,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpuarmfo,''); +end. diff --git a/mseide-msegui/apps/ide/cpuarmm3form.mfm b/mseide-msegui/apps/ide/cpuarmm3form.mfm new file mode 100644 index 0000000..bd23253 --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmm3form.mfm @@ -0,0 +1,285 @@ +inherited cpuarmm3fo: tcpuarmm3fo + bounds_x = 57 + bounds_y = 234 + bounds_cx = 272 + bounds_cy = 266 + container.bounds = ( + 0 + 0 + 262 + 266 + ) + caption = 'CPU ARM M3' + moduleclassname = 'tcpuarmfo' + inherited on: tbooleanedit + end + inherited stoptime: tdatetimedisp + end + inherited tspacer1: tspacer + bounds_cx = 251 + inherited tlayouter1: tlayouter + inherited r1: tintegeredit + end + inherited r0: tintegeredit + end + inherited r4: tintegeredit + end + inherited r3: tintegeredit + end + inherited r2: tintegeredit + end + inherited r5: tintegeredit + end + inherited r6: tintegeredit + end + inherited r7: tintegeredit + end + inherited r8: tintegeredit + end + end + inherited tbooleanedit16: tbooleanedit + frame.caption = 'ISR_NUMBER' + frame.captionpos = cp_topright + frame.outerframe = ( + 63 + 19 + 0 + 0 + ) + bounds_x = 177 + bounds_y = 6 + bounds_cx = 74 + bounds_cy = 30 + end + inherited tbooleanedit17: tbooleanedit + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 229 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit18: tbooleanedit + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 218 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit19: tbooleanedit + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 207 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit20: tbooleanedit + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 195 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit15: tbooleanedit + Tag = 13 + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 104 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit14: tbooleanedit + Tag = 10 + frame.caption = 'ICI/IT' + frame.captionpos = cp_topright + frame.outerframe = ( + 22 + 19 + 0 + 0 + ) + bounds_x = 115 + bounds_cx = 33 + end + inherited tbooleanedit13: tbooleanedit + Tag = 12 + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 115 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit12: tbooleanedit + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 184 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit11: tbooleanedit + Tag = 11 + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 126 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit10: tbooleanedit + Tag = 26 + frame.captionpos = cp_topleft + bounds_x = 60 + end + inherited tbooleanedit9: tbooleanedit + Tag = 25 + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 71 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit8: tbooleanedit + Tag = 15 + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 82 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit7: tbooleanedit + Tag = 14 + bounds_x = 93 + end + inherited tbooleanedit6: tbooleanedit + frame.caption = 'T' + bounds_x = 77 + bounds_y = 0 + visible = False + end + inherited tbooleanedit5: tbooleanedit + bounds_x = 46 + end + inherited tbooleanedit4: tbooleanedit + bounds_x = 35 + end + inherited tbooleanedit3: tbooleanedit + bounds_x = 24 + end + inherited tbooleanedit2: tbooleanedit + bounds_x = 13 + end + inherited c: tbooleanedit + bounds_x = 2 + end + inherited tlayouter2: tlayouter + inherited r11: tintegeredit + end + inherited r10: tintegeredit + end + inherited r9: tintegeredit + end + inherited fps: tintegeredit + end + inherited cpsr: tintegeredit + end + inherited r12: tintegeredit + end + inherited sp: tintegeredit + end + inherited lr: tintegeredit + end + inherited pc: tintegeredit + end + end + object tbooleanedit21: tbooleanedit[22] + Tag = 6 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 22 + bounds_x = 173 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + end + object tbooleanedit22: tbooleanedit[23] + Tag = 7 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 23 + bounds_x = 162 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + end + object tbooleanedit23: tbooleanedit[24] + Tag = 8 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 24 + bounds_x = 151 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + end + end +end diff --git a/mseide-msegui/apps/ide/cpuarmm3form.pas b/mseide-msegui/apps/ide/cpuarmm3form.pas new file mode 100644 index 0000000..db3e9cd --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmm3form.pas @@ -0,0 +1,22 @@ +unit cpuarmm3form; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,cpuarmform, + msegraphedits,mseifiglob,msetypes; + +type + tcpuarmm3fo = class(tcpuarmfo) + tbooleanedit21: tbooleanedit; + tbooleanedit22: tbooleanedit; + tbooleanedit23: tbooleanedit; + protected + end; +var + cpuarmm3fo: tcpuarmm3fo; +implementation +uses + cpuarmm3form_mfm,msedataedits; + +end. diff --git a/mseide-msegui/apps/ide/cpuarmm3form_mfm.pas b/mseide-msegui/apps/ide/cpuarmm3form_mfm.pas new file mode 100644 index 0000000..9aedc05 --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmm3form_mfm.pas @@ -0,0 +1,175 @@ +unit cpuarmm3form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpuarmm3form; + +const + objdata: record size: integer; data: array[0..3147] of byte end = + (size: 3148; data: ( + 84,80,70,48,241,11,116,99,112,117,97,114,109,109,51,102,111,10,99,112, + 117,97,114,109,109,51,102,111,8,98,111,117,110,100,115,95,120,2,57,8, + 98,111,117,110,100,115,95,121,3,234,0,9,98,111,117,110,100,115,95,99, + 120,3,16,1,9,98,111,117,110,100,115,95,99,121,3,10,1,16,99,111, + 110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3, + 6,1,3,10,1,0,7,99,97,112,116,105,111,110,6,10,67,80,85,32, + 65,82,77,32,77,51,15,109,111,100,117,108,101,99,108,97,115,115,110,97, + 109,101,6,9,116,99,112,117,97,114,109,102,111,0,241,12,116,98,111,111, + 108,101,97,110,101,100,105,116,2,111,110,0,0,241,13,116,100,97,116,101, + 116,105,109,101,100,105,115,112,8,115,116,111,112,116,105,109,101,0,0,241, + 7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,49,9,98,111, + 117,110,100,115,95,99,120,3,251,0,0,241,9,116,108,97,121,111,117,116, + 101,114,10,116,108,97,121,111,117,116,101,114,49,0,241,12,116,105,110,116, + 101,103,101,114,101,100,105,116,2,114,49,0,0,241,12,116,105,110,116,101, + 103,101,114,101,100,105,116,2,114,48,0,0,241,12,116,105,110,116,101,103, + 101,114,101,100,105,116,2,114,52,0,0,241,12,116,105,110,116,101,103,101, + 114,101,100,105,116,2,114,51,0,0,241,12,116,105,110,116,101,103,101,114, + 101,100,105,116,2,114,50,0,0,241,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,114,53,0,0,241,12,116,105,110,116,101,103,101,114,101,100, + 105,116,2,114,54,0,0,241,12,116,105,110,116,101,103,101,114,101,100,105, + 116,2,114,55,0,0,241,12,116,105,110,116,101,103,101,114,101,100,105,116, + 2,114,56,0,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116, + 14,116,98,111,111,108,101,97,110,101,100,105,116,49,54,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,10,73,83,82,95,78,85,77,66,69, + 82,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,11, + 99,112,95,116,111,112,114,105,103,104,116,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,63,2,19,2,0,2,0,0,8,98, + 111,117,110,100,115,95,120,3,177,0,8,98,111,117,110,100,115,95,121,2, + 6,9,98,111,117,110,100,115,95,99,120,2,74,9,98,111,117,110,100,115, + 95,99,121,2,30,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105, + 116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,55,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,0,0,8, + 98,111,117,110,100,115,95,120,3,229,0,8,98,111,117,110,100,115,95,121, + 2,25,9,98,111,117,110,100,115,95,99,121,2,11,0,0,241,12,116,98, + 111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101, + 100,105,116,49,56,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,0,2,0,2,0,0,8,98,111,117,110,100,115,95,120,3,218,0, + 8,98,111,117,110,100,115,95,121,2,25,9,98,111,117,110,100,115,95,99, + 121,2,11,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,14, + 116,98,111,111,108,101,97,110,101,100,105,116,49,57,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,0,0,8,98,111, + 117,110,100,115,95,120,3,207,0,8,98,111,117,110,100,115,95,121,2,25, + 9,98,111,117,110,100,115,95,99,121,2,11,0,0,241,12,116,98,111,111, + 108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105, + 116,50,48,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,0,2,0,0,8,98,111,117,110,100,115,95,120,3,195,0,8,98, + 111,117,110,100,115,95,121,2,25,9,98,111,117,110,100,115,95,99,121,2, + 11,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116,98, + 111,111,108,101,97,110,101,100,105,116,49,53,3,84,97,103,2,13,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,0, + 0,8,98,111,117,110,100,115,95,120,2,104,8,98,111,117,110,100,115,95, + 121,2,25,9,98,111,117,110,100,115,95,99,121,2,11,0,0,241,12,116, + 98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110, + 101,100,105,116,49,52,3,84,97,103,2,10,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,6,73,67,73,47,73,84,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,11,99,112,95,116,111,112,114, + 105,103,104,116,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,22,2,19,2,0,2,0,0,8,98,111,117,110,100,115,95,120, + 2,115,9,98,111,117,110,100,115,95,99,120,2,33,0,0,241,12,116,98, + 111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101, + 100,105,116,49,51,3,84,97,103,2,12,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,0,2,0,0,8,98,111,117,110,100, + 115,95,120,2,115,8,98,111,117,110,100,115,95,121,2,25,9,98,111,117, + 110,100,115,95,99,121,2,11,0,0,241,12,116,98,111,111,108,101,97,110, + 101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,50,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0,2, + 0,0,8,98,111,117,110,100,115,95,120,3,184,0,8,98,111,117,110,100, + 115,95,121,2,25,9,98,111,117,110,100,115,95,99,121,2,11,0,0,241, + 12,116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101, + 97,110,101,100,105,116,49,49,3,84,97,103,2,11,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,0,0,8,98,111, + 117,110,100,115,95,120,2,126,8,98,111,117,110,100,115,95,121,2,25,9, + 98,111,117,110,100,115,95,99,121,2,11,0,0,241,12,116,98,111,111,108, + 101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116, + 49,48,3,84,97,103,2,26,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,10,99,112,95,116,111,112,108,101,102,116,8,98,111, + 117,110,100,115,95,120,2,60,0,0,241,12,116,98,111,111,108,101,97,110, + 101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,57,3,84, + 97,103,2,25,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,0,2,0,0,8,98,111,117,110,100,115,95,120,2,71,8,98, + 111,117,110,100,115,95,121,2,25,9,98,111,117,110,100,115,95,99,121,2, + 11,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,56,3,84,97,103,2,15,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,0,0, + 8,98,111,117,110,100,115,95,120,2,82,8,98,111,117,110,100,115,95,121, + 2,25,9,98,111,117,110,100,115,95,99,121,2,11,0,0,241,12,116,98, + 111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101, + 100,105,116,55,3,84,97,103,2,14,8,98,111,117,110,100,115,95,120,2, + 93,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,54,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,1,84,8,98,111,117,110,100,115,95,120,2,77,8, + 98,111,117,110,100,115,95,121,2,0,7,118,105,115,105,98,108,101,8,0, + 0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111, + 108,101,97,110,101,100,105,116,53,8,98,111,117,110,100,115,95,120,2,46, + 0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111, + 111,108,101,97,110,101,100,105,116,52,8,98,111,117,110,100,115,95,120,2, + 35,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,51,8,98,111,117,110,100,115,95,120, + 2,24,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116, + 98,111,111,108,101,97,110,101,100,105,116,50,8,98,111,117,110,100,115,95, + 120,2,13,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,1, + 99,8,98,111,117,110,100,115,95,120,2,2,0,0,241,9,116,108,97,121, + 111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,50,0,241,12,116, + 105,110,116,101,103,101,114,101,100,105,116,3,114,49,49,0,0,241,12,116, + 105,110,116,101,103,101,114,101,100,105,116,3,114,49,48,0,0,241,12,116, + 105,110,116,101,103,101,114,101,100,105,116,2,114,57,0,0,241,12,116,105, + 110,116,101,103,101,114,101,100,105,116,3,102,112,115,0,0,241,12,116,105, + 110,116,101,103,101,114,101,100,105,116,4,99,112,115,114,0,0,241,12,116, + 105,110,116,101,103,101,114,101,100,105,116,3,114,49,50,0,0,241,12,116, + 105,110,116,101,103,101,114,101,100,105,116,2,115,112,0,0,241,12,116,105, + 110,116,101,103,101,114,101,100,105,116,2,108,114,0,0,241,12,116,105,110, + 116,101,103,101,114,101,100,105,116,2,112,99,0,0,0,242,2,22,12,116, + 98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110, + 101,100,105,116,50,49,3,84,97,103,2,6,5,99,111,108,111,114,4,3, + 0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,22,8,98,111,117,110,100,115,95,120,3,173,0,8,98,111,117,110, + 100,115,95,121,2,25,9,98,111,117,110,100,115,95,99,120,2,11,9,98, + 111,117,110,100,115,95,99,121,2,11,0,0,242,2,23,12,116,98,111,111, + 108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105, + 116,50,50,3,84,97,103,2,7,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,23, + 8,98,111,117,110,100,115,95,120,3,162,0,8,98,111,117,110,100,115,95, + 121,2,25,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,11,0,0,242,2,24,12,116,98,111,111,108,101,97, + 110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,50,51, + 3,84,97,103,2,8,5,99,111,108,111,114,4,3,0,0,128,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,24,8,98,111, + 117,110,100,115,95,120,3,151,0,8,98,111,117,110,100,115,95,121,2,25, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,11,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpuarmm3fo,''); +end. diff --git a/mseide-msegui/apps/ide/cpuavr32form.mfm b/mseide-msegui/apps/ide/cpuavr32form.mfm new file mode 100644 index 0000000..d96edfc --- /dev/null +++ b/mseide-msegui/apps/ide/cpuavr32form.mfm @@ -0,0 +1,1058 @@ +inherited cpuavr32fo: tcpuavr32fo + bounds_x = 174 + bounds_y = 158 + bounds_cx = 261 + bounds_cy = 280 + container.bounds = ( + 0 + 0 + 251 + 280 + ) + caption = 'CPU AVR32' + left = 2 + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + bounds_x = 152 + bounds_y = 1 + end + inherited stoptime: tdatetimedisp + bounds_x = 0 + bounds_y = 0 + end + object tspacer1: tspacer[2] + taborder = 2 + visible = True + bounds_x = 0 + bounds_y = 20 + bounds_cx = 243 + bounds_cy = 265 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = stoptime + object tbooleanedit16: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + bounds_x = 232 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit17: tbooleanedit + Tag = 1 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 1 + bounds_x = 221 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit18: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'N' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 2 + bounds_x = 210 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit19: tbooleanedit + Tag = 3 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'V' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 3 + bounds_x = 199 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit20: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Q' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 4 + bounds_x = 188 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit12: tbooleanedit + Tag = 5 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'L' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 5 + bounds_x = 177 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit14: tbooleanedit + Tag = 14 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'T' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 6 + bounds_x = 164 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit11: tbooleanedit + Tag = 15 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'R' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 7 + bounds_x = 153 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object gm: tbooleanedit + Tag = 16 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'G' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 8 + bounds_x = 137 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit15: tbooleanedit + Tag = 17 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '0' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 9 + bounds_x = 126 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit7: tbooleanedit + Tag = 18 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '1' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 10 + bounds_x = 115 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit8: tbooleanedit + Tag = 19 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '2' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 11 + bounds_x = 104 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit21: tbooleanedit + Tag = 20 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'I' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 12 + bounds_x = 93 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit9: tbooleanedit + Tag = 21 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'E' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 13 + bounds_x = 80 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit10: tbooleanedit + Tag = 22 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '0' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 14 + bounds_x = 69 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit6: tbooleanedit + Tag = 23 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '1' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 15 + bounds_x = 58 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit5: tbooleanedit + Tag = 24 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'M' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 1 + 0 + ) + taborder = 16 + bounds_x = 47 + bounds_y = 6 + bounds_cx = 12 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit4: tbooleanedit + Tag = 25 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'D' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 17 + bounds_x = 34 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit3: tbooleanedit + Tag = 26 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'M' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 1 + 0 + ) + taborder = 18 + bounds_x = 23 + bounds_y = 6 + bounds_cx = 12 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit2: tbooleanedit + Tag = 27 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'J' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 19 + bounds_x = 12 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object c: tbooleanedit + Tag = 28 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'H' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 20 + bounds_x = 1 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object irqoff: tbooleanedit + frame.caption = 'IRQoff' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 38 + 3 + ) + taborder = 21 + hint = 'Set global interrupt mask while stepping' + bounds_x = 17 + bounds_y = 235 + bounds_cx = 51 + bounds_cy = 18 + onsetvalue = irqoffset + end + object exceptstack: tbutton + optionswidget1 = [ow1_autowidth, ow1_autoheight] + taborder = 22 + bounds_x = 112 + bounds_y = 243 + bounds_cx = 115 + bounds_cy = 22 + state = [as_disabled, as_localdisabled, as_localcaption, as_localonexecute] + caption = 'Check Exceptstack' + onexecute = checkexcept + end + object tlayouter2: tlayouter + frame.localprops = [] + frame.localprops1 = [] + taborder = 23 + bounds_x = 113 + bounds_y = 40 + bounds_cx = 113 + bounds_cy = 176 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_xscale] + optionslayout = [lao_placey] + place_maxdist = 0 + onafterlayout = afterla + dist_bottom = 3 + object r6: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r6' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r7: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r7' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 22 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r8: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r8' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 44 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r11: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r11' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 110 + bounds_cx = 112 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r10: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r10' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 20 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 88 + bounds_cx = 113 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r9: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r9' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 66 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r12: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r12' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 20 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 132 + bounds_cx = 113 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object sr: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'sr' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 154 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + end + object tlayouter1: tlayouter + frame.localprops = [] + frame.localprops1 = [] + taborder = 24 + bounds_x = 0 + bounds_y = 40 + bounds_cx = 110 + bounds_cy = 198 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_xscale] + optionslayout = [lao_placey] + place_maxdist = 0 + linkright = tlayouter2 + linkbottom = exceptstack + dist_right = 3 + dist_bottom = 5 + object r1: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r1' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 13 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 22 + bounds_cx = 106 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r0: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r0' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r4: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r4' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 88 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r3: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r3' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 66 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r2: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r2' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 44 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r5: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r5' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 110 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object sp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'sp' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 132 + bounds_cx = 110 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object lr: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'lr' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 10 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 154 + bounds_cx = 103 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object pc: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'pc' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 8 + bounds_x = 0 + bounds_y = 176 + bounds_cx = 110 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + end + end + object cs: tstringcontainer[3] + strings.data = ( + 'Return address:' + 'Exception return' + ) + left = 128 + top = 224 + end +end diff --git a/mseide-msegui/apps/ide/cpuavr32form.pas b/mseide-msegui/apps/ide/cpuavr32form.pas new file mode 100644 index 0000000..5f040b8 --- /dev/null +++ b/mseide-msegui/apps/ide/cpuavr32form.pas @@ -0,0 +1,305 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpuavr32form; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,cpuform,msesplitter,msedataedits, + mseedit,msestrings,msetypes,msegraphedits,msesimplewidgets,msewidgets, + msestringcontainer; + +type + tcpuavr32fo = class(tcpufo) + fps: tintegeredit; + tspacer1: tspacer; + tbooleanedit16: tbooleanedit; + tbooleanedit17: tbooleanedit; + tbooleanedit18: tbooleanedit; + tbooleanedit19: tbooleanedit; + tbooleanedit20: tbooleanedit; + tbooleanedit12: tbooleanedit; + tbooleanedit14: tbooleanedit; + tbooleanedit11: tbooleanedit; + gm: tbooleanedit; + tbooleanedit15: tbooleanedit; + tbooleanedit7: tbooleanedit; + tbooleanedit8: tbooleanedit; + tbooleanedit21: tbooleanedit; + tbooleanedit9: tbooleanedit; + tbooleanedit10: tbooleanedit; + tbooleanedit6: tbooleanedit; + tbooleanedit5: tbooleanedit; + tbooleanedit4: tbooleanedit; + tbooleanedit3: tbooleanedit; + tbooleanedit2: tbooleanedit; + c: tbooleanedit; + irqoff: tbooleanedit; + exceptstack: tbutton; + tlayouter2: tlayouter; + r6: tintegeredit; + r7: tintegeredit; + r8: tintegeredit; + r11: tintegeredit; + r10: tintegeredit; + r9: tintegeredit; + r12: tintegeredit; + sr: tintegeredit; + tlayouter1: tlayouter; + r1: tintegeredit; + r0: tintegeredit; + r4: tintegeredit; + r3: tintegeredit; + r2: tintegeredit; + r5: tintegeredit; + sp: tintegeredit; + lr: tintegeredit; + pc: tintegeredit; + cs: tstringcontainer; + procedure regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure flagonchange(const sender: TObject); + function internalrefresh: boolean; override; + procedure checkexcept(const sender: TObject); + procedure irqoffset(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure afterla(const sender: tcustomlayouter); + private + fgmbefore: boolean; + protected + procedure updatereadstatvalues; override; + procedure updatewritestatvalues; override; + procedure doirqoff; + procedure irqrestore; + public + constructor create(aowner: tcomponent); override; + function flagedit(const aindex: integer): tcustombooleanedit; override; + procedure refresh; override; + procedure beforecontinue; override; + end; + +implementation +uses + cpuavr32form_mfm,main,msegdbutils,sourceform,mseformatstr,sysutils, + disassform; +type + stringconsts = ( + retad, //0 Return address: + exceptreturn //1 Exception return + ); + +const + modebits = $01c00000; + gmmask = $00010000; + exceptmode = $00800000; //irq level 0 +{ tcpuavr32fo } + +constructor tcpuavr32fo.create(aowner: tcomponent); +begin + inherited create(aowner); + fflagswidget:= sr; +end; + +procedure tcpuavr32fo.regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); +//var +// str1: string; +begin + if mainfo.gdb.cancommand then begin + with tintegeredit(sender) do begin + if mainfo.gdb.setsystemregister(0,value) <> gdb_ok then begin + accept:= false; + end; + end; + end + else begin + accept:= false; + end; +end; + +procedure tcpuavr32fo.flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; + +procedure tcpuavr32fo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +function tcpuavr32fo.internalrefresh: boolean; +var + int1: qword; +begin + result:= inherited internalrefresh; + if result then begin + if mainfo.gdb.getsystemregister(0,int1) = gdb_ok then begin + if sr.value <> int1 then begin + sr.font.color:= cl_red; + end + else begin + sr.font.color:= cl_black; + end; + sr.value:= int1; + result:= true; + exceptstack.enabled:= int1 and modebits >= exceptmode; + end + else begin + result:= false; + end; + end; + if not result then begin + exceptstack.enabled:= false; + end; +end; +//todo: fix 32/64 +procedure tcpuavr32fo.checkexcept(const sender: TObject); + + procedure locateframe(const address: qword); + var + bo1: boolean; + filename: filenamety; + line: integer; + start,stop: qword; + mstr1,mstr2: msestring; + begin + disassfo.refresh(address); + mstr1:= ''; + with mainfo.gdb do begin + bo1:= infoline(address,filename,line,start,stop) = gdb_ok; + if bo1 then begin + if sourcefo.showsourceline(filename,line-1,0,true) <> nil then begin + exit; + end; + mstr1:= filename+':'+inttostrmse(line); + end; + mstr2:= hextostrmse(address,8); + if infosymbol('*0x'+mstr2,mstr1) = gdb_ok then begin + mstr1:= mstr1+lineend+mstr1; + end + else begin + mstr1:= mstr1+lineend+cs[ord(retad)]+' '+mstr2; + end; + end; + showmessage(mstr1,cs[ord(exceptreturn)]); + end; + +var + lwo1,lwo2,{lwo3,}lwo4: longword; + lwo3,framead: qword; +begin + with mainfo.gdb do begin + if (getframeaddress(framead) = gdb_ok) then begin + if readmemorylongword(framead+4,lwo1) = gdb_ok then begin + //pc +// setregistervalue('pc',lwo1); + if readmemorylongword(framead,lwo2) = gdb_ok then begin + //sr + lwo4:= sr.value; //backup + if setsystemregister(0,lwo2) = gdb_ok then begin + //for sp_app access + // if getregistervalue('sp',longint(lwo3)) = gdb_ok then begin + if (getregistervalue('sp',lwo3) = gdb_ok) then begin + if selectstackpointer(lwo3) = gdb_ok then begin + mainfo.refreshframe; + end; + end; + end; + setsystemregister(0,lwo4); //restore + end; + end; + locateframe(lwo1); + end; + end; +end; + +procedure tcpuavr32fo.doirqoff; +begin + fgmbefore:= gm.value; + if not gm.value then begin + gm.value:= true; + gm.checkvalue; + end; +end; + +procedure tcpuavr32fo.irqrestore; +begin + if gm.value <> fgmbefore then begin + gm.value:= fgmbefore; + gm.checkvalue; + end; +end; + +procedure tcpuavr32fo.refresh; +begin + if irqoff.value and mainfo.gdb.cancommand then begin + inherited; + doirqoff; + end + else begin + inherited; + end; +end; + +procedure tcpuavr32fo.beforecontinue; +begin + if irqoff.value and mainfo.gdb.cancommand then begin + irqrestore; + end; + inherited; +end; + +procedure tcpuavr32fo.irqoffset(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + if mainfo.gdb.cancommand then begin + if avalue then begin + doirqoff; + end + else begin + irqrestore; + end; + end; +end; + +procedure tcpuavr32fo.afterla(const sender: tcustomlayouter); +begin + aligny(wam_center,[exceptstack,irqoff]); +end; + +procedure tcpuavr32fo.updatereadstatvalues; +begin + irqoff.value:= irqoffvalue; + inherited; +end; + +procedure tcpuavr32fo.updatewritestatvalues; +begin + irqoffvalue:= irqoff.value; + inherited; +end; + +function tcpuavr32fo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= c.tagitem(aindex); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpuavr32form_mfm.pas b/mseide-msegui/apps/ide/cpuavr32form_mfm.pas new file mode 100644 index 0000000..0f938cd --- /dev/null +++ b/mseide-msegui/apps/ide/cpuavr32form_mfm.pas @@ -0,0 +1,876 @@ +unit cpuavr32form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpuavr32form; + +const + objdata: record size: integer; data: array[0..17167] of byte end = + (size: 17168; data: ( + 84,80,70,48,241,11,116,99,112,117,97,118,114,51,50,102,111,10,99,112, + 117,97,118,114,51,50,102,111,8,98,111,117,110,100,115,95,120,3,174,0, + 8,98,111,117,110,100,115,95,121,3,158,0,9,98,111,117,110,100,115,95, + 99,120,3,5,1,9,98,111,117,110,100,115,95,99,121,3,24,1,16,99, + 111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0, + 3,251,0,3,24,1,0,7,99,97,112,116,105,111,110,6,9,67,80,85, + 32,65,86,82,51,50,4,108,101,102,116,2,2,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,6,116,99,112,117,102,111,0,241,12, + 116,98,111,111,108,101,97,110,101,100,105,116,2,111,110,8,98,111,117,110, + 100,115,95,120,3,152,0,8,98,111,117,110,100,115,95,121,2,1,0,0, + 241,13,116,100,97,116,101,116,105,109,101,100,105,115,112,8,115,116,111,112, + 116,105,109,101,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,0,0,242,2,2,7,116,115,112,97,99,101,114,8, + 116,115,112,97,99,101,114,49,8,116,97,98,111,114,100,101,114,2,2,7, + 118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120, + 3,243,0,9,98,111,117,110,100,115,95,99,121,3,9,1,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101, + 120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,7, + 108,105,110,107,116,111,112,7,8,115,116,111,112,116,105,109,101,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110, + 101,100,105,116,49,54,5,99,111,108,111,114,4,3,0,0,128,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,1,67,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,19,2,0,2,0,0,8,98,111,117,110,100,115,95,120,3, + 232,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115, + 95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110, + 115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97, + 108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116, + 98,111,111,108,101,97,110,101,100,105,116,49,55,3,84,97,103,2,1,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,90,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,3,221,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111, + 117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2, + 30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115, + 101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,56,3,84,97, + 103,2,2,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,78,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98, + 111,117,110,100,115,95,120,3,210,0,8,98,111,117,110,100,115,95,121,2, + 6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115, + 95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108, + 97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49, + 57,3,84,97,103,2,3,5,99,111,108,111,114,4,3,0,0,128,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,1,86,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,3,8,98,111,117,110,100,115,95,120,3,199,0,8,98,111,117,110,100, + 115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111, + 117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101, + 7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101, + 100,105,116,50,48,3,84,97,103,2,4,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,81,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,188,0,8,98, + 111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2, + 11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118, + 97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108, + 101,97,110,101,100,105,116,49,50,3,84,97,103,2,5,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 76,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3, + 177,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115, + 95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110, + 115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97, + 108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116, + 98,111,111,108,101,97,110,101,100,105,116,49,52,3,84,97,103,2,14,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,84,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100, + 115,95,120,3,164,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111, + 117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2, + 30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115, + 101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,49,3,84,97, + 103,2,15,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,82,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,7,8,98, + 111,117,110,100,115,95,120,3,153,0,8,98,111,117,110,100,115,95,121,2, + 6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115, + 95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108, + 97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,2,103,109,3,84,97,103,2,16,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 71,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,8,8,98,111,117,110,100,115,95,120,3, + 137,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115, + 95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110, + 115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97, + 108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116, + 98,111,111,108,101,97,110,101,100,105,116,49,53,3,84,97,103,2,17,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,48,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100, + 115,95,120,2,126,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117, + 110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30, + 10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101, + 116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,13,116,98,111,111,108,101,97,110,101,100,105,116,55,3,84,97,103,2, + 18,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,49,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,10,8,98,111,117, + 110,100,115,95,120,2,115,8,98,111,117,110,100,115,95,121,2,6,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115, + 115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,56,3,84,97, + 103,2,19,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,50,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,11,8,98, + 111,117,110,100,115,95,120,2,104,8,98,111,117,110,100,115,95,121,2,6, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97, + 103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,50,49, + 3,84,97,103,2,20,5,99,111,108,111,114,4,3,0,0,128,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,1,73,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2, + 12,8,98,111,117,110,100,115,95,120,2,93,8,98,111,117,110,100,115,95, + 121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13, + 102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105, + 116,57,3,84,97,103,2,21,5,99,111,108,111,114,4,3,0,0,128,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,1,69,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,13,8,98,111,117,110,100,115,95,120,2,80,8,98,111,117,110,100, + 115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111, + 117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101, + 7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101, + 100,105,116,49,48,3,84,97,103,2,22,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,48,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,14,8,98,111,117,110,100,115,95,120,2,69,8,98,111, + 117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97, + 108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101, + 97,110,101,100,105,116,54,3,84,97,103,2,23,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,49,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,15,8,98,111,117,110,100,115,95,120,2,58,8, + 98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120, + 2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116, + 118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111, + 108,101,97,110,101,100,105,116,53,3,84,97,103,2,24,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 77,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,1,2,0,0,8, + 116,97,98,111,114,100,101,114,2,16,8,98,111,117,110,100,115,95,120,2, + 47,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95, + 99,120,2,12,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115, + 101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108, + 117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,52,3,84,97,103,2,25,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,1,68,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,17,8,98,111,117,110,100,115,95, + 120,2,34,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100, + 115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111, + 110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118, + 97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13, + 116,98,111,111,108,101,97,110,101,100,105,116,51,3,84,97,103,2,26,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,77,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,1, + 2,0,0,8,116,97,98,111,114,100,101,114,2,18,8,98,111,117,110,100, + 115,95,120,2,23,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117, + 110,100,115,95,99,120,2,12,9,98,111,117,110,100,115,95,99,121,2,30, + 10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101, + 116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,13,116,98,111,111,108,101,97,110,101,100,105,116,50,3,84,97,103,2, + 27,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,74,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,19,8,98,111,117, + 110,100,115,95,120,2,12,8,98,111,117,110,100,115,95,121,2,6,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115, + 115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,1,99,3,84,97,103,2,28,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,72,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,20,8,98,111,117,110,100,115,95,120,2,1,8,98,111, + 117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97, + 108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,6,105,114,113,111,102,102, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,6,73,82,81,111, + 102,102,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,2,2,38,2,3,0,8,116,97,98,111,114,100,101,114,2,21,4, + 104,105,110,116,6,40,83,101,116,32,103,108,111,98,97,108,32,105,110,116, + 101,114,114,117,112,116,32,109,97,115,107,32,119,104,105,108,101,32,115,116, + 101,112,112,105,110,103,8,98,111,117,110,100,115,95,120,2,17,8,98,111, + 117,110,100,115,95,121,3,235,0,9,98,111,117,110,100,115,95,99,120,2, + 51,9,98,111,117,110,100,115,95,99,121,2,18,10,111,110,115,101,116,118, + 97,108,117,101,7,9,105,114,113,111,102,102,115,101,116,0,0,7,116,98, + 117,116,116,111,110,11,101,120,99,101,112,116,115,116,97,99,107,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117, + 116,111,119,105,100,116,104,14,111,119,49,95,97,117,116,111,104,101,105,103, + 104,116,0,8,116,97,98,111,114,100,101,114,2,22,8,98,111,117,110,100, + 115,95,120,2,112,8,98,111,117,110,100,115,95,121,3,243,0,9,98,111, + 117,110,100,115,95,99,120,2,115,9,98,111,117,110,100,115,95,99,121,2, + 22,5,115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100, + 16,97,115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110, + 6,17,67,104,101,99,107,32,69,120,99,101,112,116,115,116,97,99,107,9, + 111,110,101,120,101,99,117,116,101,7,11,99,104,101,99,107,101,120,99,101, + 112,116,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111, + 117,116,101,114,50,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,23,8,98,111,117,110, + 100,115,95,120,2,113,8,98,111,117,110,100,115,95,121,2,40,9,98,111, + 117,110,100,115,95,99,120,2,113,9,98,111,117,110,100,115,95,99,121,3, + 176,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99, + 95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120, + 11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114, + 105,110,107,121,0,9,102,111,110,116,46,110,97,109,101,6,11,115,116,102, + 95,100,101,102,97,117,108,116,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,13,111,112,116,105,111,110,115,108, + 97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,121,0,13,112, + 108,97,99,101,95,109,97,120,100,105,115,116,2,0,13,111,110,97,102,116, + 101,114,108,97,121,111,117,116,7,7,97,102,116,101,114,108,97,11,100,105, + 115,116,95,98,111,116,116,111,109,2,3,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,2,114,54,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,2,114,54,22,102,114,97,109,101,46,99,97, + 112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121, + 99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,14,2,0,0,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,2,114,55,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,55,22,102, + 114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98, + 111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,22,9,98,111,117,110,100,115,95,99,120,2, + 107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,2,114,56,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,56,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114, + 100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,44,9,98,111,117,110,100,115,95,99,120,2,107,9, + 98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,3,114,49,49,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,3,114,49,49,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114, + 100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,110,9,98,111,117,110,100,115,95,99,120,2,112,9, + 98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,3,114,49,48,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,3,114,49,48,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,20,2,0,0,8,116,97,98,111,114, + 100,101,114,2,4,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,88,9,98,111,117,110,100,115,95,99,120,2,113,9, + 98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,2,114,57,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,2,114,57,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116, + 102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,66,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111, + 117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,3,114,49,50,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,3,114,49,50,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116, + 102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,20,2,0,0,8,116,97,98,111,114,100,101, + 114,2,6,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,3,132,0,9,98,111,117,110,100,115,95,99,120,2,113,9,98, + 111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103, + 104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95, + 102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7, + 11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110, + 98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,2,115,114,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,2,115,114,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102, + 95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114,100,101,114, + 2,7,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,3,154,0,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111, + 117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,8,111,110,99,104,97,110,103,101,7,12,102,108, + 97,103,111,110,99,104,97,110,103,101,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,0,9,116,108, + 97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,49,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,24,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,40,9,98,111,117,110,100,115,95,99,120, + 2,110,9,98,111,117,110,100,115,95,99,121,3,198,0,12,111,112,116,105, + 111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100, + 120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120, + 112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,9,102, + 111,110,116,46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108, + 116,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10, + 108,97,111,95,112,108,97,99,101,121,0,13,112,108,97,99,101,95,109,97, + 120,100,105,115,116,2,0,9,108,105,110,107,114,105,103,104,116,7,10,116, + 108,97,121,111,117,116,101,114,50,10,108,105,110,107,98,111,116,116,111,109, + 7,11,101,120,99,101,112,116,115,116,97,99,107,10,100,105,115,116,95,114, + 105,103,104,116,2,3,11,100,105,115,116,95,98,111,116,116,111,109,2,5, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,114,49,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,49, + 22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,13,2,0,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,22,9,98,111,117,110,100,115,95,99, + 120,2,106,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,2,114,48,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,48,22,102, + 114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100,115,95,99,121, + 2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,118,97, + 108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2, + 114,52,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,2,114,52,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116, + 101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114, + 101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,14, + 2,0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,88,9,98,111,117, + 110,100,115,95,99,120,2,107,9,98,111,117,110,100,115,95,99,121,2,22, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,118,97,108,117, + 101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,114,51, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 2,114,51,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100, + 0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8, + 99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,14,2,0, + 0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,2,66,9,98,111,117,110,100, + 115,95,99,120,2,107,9,98,111,117,110,100,115,95,99,121,2,22,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,114,50,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114, + 50,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8, + 116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,44,9,98,111,117,110,100,115,95, + 99,120,2,107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0, + 12,116,105,110,116,101,103,101,114,101,100,105,116,2,114,53,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,53,22, + 102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97, + 103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114, + 105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116,97, + 98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,110,9,98,111,117,110,100,115,95,99,120, + 2,107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46, + 104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9, + 115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,2,115,112,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,115,112,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,17,2,0,0,8,116,97,98,111, + 114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,3,132,0,9,98,111,117,110,100,115,95,99,120,2, + 110,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,2,108,114,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,2,108,114,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,10,2,0,0,8,116,97,98,111,114, + 100,101,114,2,7,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,3,154,0,9,98,111,117,110,100,115,95,99,120,2,103, + 9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110, + 116,101,103,101,114,101,100,105,116,2,112,99,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,2,112,99,22,102,114,97,109, + 101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12, + 116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,0,2,17,2,0,0,8,116,97,98,111,114,100, + 101,114,2,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,3,176,0,9,98,111,117,110,100,115,95,99,120,2,110,9, + 98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,0,0,242,2,3, + 16,116,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,2,99,115, + 12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,15,82,101,116,117, + 114,110,32,97,100,100,114,101,115,115,58,6,16,69,120,99,101,112,116,105, + 111,110,32,114,101,116,117,114,110,0,4,108,101,102,116,3,128,0,3,116, + 111,112,3,224,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpuavr32fo,''); +end. diff --git a/mseide-msegui/apps/ide/cpucpu32form.mfm b/mseide-msegui/apps/ide/cpucpu32form.mfm new file mode 100644 index 0000000..d47ee7f --- /dev/null +++ b/mseide-msegui/apps/ide/cpucpu32form.mfm @@ -0,0 +1,897 @@ +inherited cpucpu32fo: tcpucpu32fo + bounds_x = 245 + bounds_y = 202 + bounds_cx = 252 + bounds_cy = 291 + container.bounds = ( + 0 + 0 + 242 + 291 + ) + caption = 'CPU CPU32' + icon.image = { + 00000000020000001800000018000000C0020000000000000000000000000000 + 0000000000000000000000000000000000000000804CF09180808016804CF002 + 80808001E0E0E004D8DCD801A8A8A801888C8801B0B0B001E0E0E006C8C8C801 + B0B0B001D0D0D001E0E0E003F8FCF801804CF00280808001E0E0E003D8DCD801 + 40404001080C0801383838010808080150505001D8DCD801E0E0E00290909001 + 1014100100000002888C8801E0E0E003F8FCF801804CF00280808001E0E0E003 + 787C7801080C0801C8C8C801E0E0E001B8BCB8010004000190909001E0E0E002 + A8A8A80190909001B8BCB80100000001888C8801E0E0E003F8FCF801804CF002 + 80808001E0E0E003282C2801585C5801E0E0E0034848480140404001E0E0E005 + 00000001888C8801E0E0E003F8FCF801804CF00280808001E0E0E002D8DCD801 + 0004000188888801E0E0E0037070700118181801E0E0E00500000001888C8801 + E0E0E003F8FCF801804CF00280808001E0E0E002D0D0D0010000000190949001 + E0E0E0038080800108080801E0E0E00500000001888C8801E0E0E003F8FCF801 + 804CF00280808001E0E0E002D0D4D0010000000190949001E0E0E00380808001 + 08080801E0E0E00500000001888C8801E0E0E003F8FCF801804CF00280808001 + E0E0E002D8DCD8010808080180808001E0E0E003686C6801181C1801E0E0E005 + 00000001888C8801E0E0E003F8FCF801804CF00280808001E0E0E00330343001 + 50505001E0E0E00338383801484C4801E0E0E00500000001888C8801E0E0E003 + F8FCF801804CF00280808001E0E0E0039090900100040001A8ACA801E0E0E001 + 989C980100000001A0A4A001E0E0E002D0D4D001B8BCB8020000000178787801 + B8BCB801C8C8C801E0E0E001F8FCF801804CF00280808001E0E0E00468686801 + 00040001101010010004000178787801E0E0E003A0A4A0010000000550545001 + E0E0E001F8FCF801804CF00280808001E0E0E005D0D0D001B8B8B801D0D4D001 + E0E0E00CF8FCF801804CF002F8FCF816804CF061000000000000000000000000 + 000000000000000000000000FEFF7F00FEFF7F00FEFF7F00FEFF7F00FEFF7F00 + FEFF7F00FEFF7F00FEFF7F00FEFF7F00FEFF7F00FEFF7F00FEFF7F00FEFF7F00 + FEFF7F0000000000000000000000000000000000 + } + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + bounds_x = 151 + bounds_y = 1 + end + inherited stoptime: tdatetimedisp + bounds_x = 0 + bounds_y = 0 + end + object tspacer1: tspacer[2] + taborder = 2 + visible = True + bounds_x = 0 + bounds_y = 18 + bounds_cx = 237 + bounds_cy = 254 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = stoptime + object c: tbooleanedit + Tag = 15 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'T' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 9 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object S: tbooleanedit + Tag = 13 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'S' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 34 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit6: tbooleanedit + Tag = 9 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'I' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 59 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit4: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'X' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 84 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit7: tbooleanedit + Tag = 3 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'N' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 95 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit8: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 106 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit9: tbooleanedit + Tag = 1 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'V' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + bounds_x = 117 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit10: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + bounds_x = 128 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit5: tbooleanedit + Tag = 8 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 8 + bounds_x = 70 + bounds_y = 20 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tbooleanedit3: tbooleanedit + Tag = 10 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 9 + bounds_x = 48 + bounds_y = 20 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tbooleanedit2: tbooleanedit + Tag = 14 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 10 + bounds_x = 20 + bounds_y = 20 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tlayouter2: tlayouter + taborder = 11 + bounds_x = 118 + bounds_y = 34 + bounds_cx = 119 + bounds_cy = 220 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + dist_right = 3 + optionslayout = [lao_placey] + place_maxdist = 0 + object a1: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a1' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + bounds_x = 0 + bounds_y = 20 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object a0: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a0' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object a4: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a4' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 80 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object a3: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a3' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 60 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object a2: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a2' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 40 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object a5: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a5' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 100 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object fp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'fp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 15 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 120 + bounds_cx = 108 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object usp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'usp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 26 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 140 + bounds_cx = 119 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object pc: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'pc' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 8 + bounds_x = 0 + bounds_y = 160 + bounds_cx = 111 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object ssp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ssp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 25 + 0 + ) + taborder = 9 + bounds_x = 0 + bounds_y = 180 + bounds_cx = 118 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object vbr: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'vbr' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 10 + bounds_x = 0 + bounds_y = 200 + bounds_cx = 115 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + end + object tlayouter1: tlayouter + taborder = 12 + bounds_x = 0 + bounds_y = 34 + bounds_cx = 115 + bounds_cy = 220 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linkright = tlayouter2 + dist_right = 3 + optionslayout = [lao_placey] + place_maxdist = 0 + object d1: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd1' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + bounds_x = 0 + bounds_y = 20 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d0: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd0' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d4: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd4' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 80 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d3: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd3' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 60 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d2: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd2' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 40 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d5: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd5' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 100 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d6: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd6' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 120 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d7: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd7' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 140 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object ps: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ps' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 8 + bounds_x = 0 + bounds_y = 160 + bounds_cx = 111 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object sfc: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'sfc' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 21 + 0 + ) + taborder = 9 + bounds_x = 0 + bounds_y = 180 + bounds_cx = 114 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object dfc: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'dfc' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 10 + bounds_x = 0 + bounds_y = 200 + bounds_cx = 115 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + end + end +end diff --git a/mseide-msegui/apps/ide/cpucpu32form.pas b/mseide-msegui/apps/ide/cpucpu32form.pas new file mode 100644 index 0000000..fd676fa --- /dev/null +++ b/mseide-msegui/apps/ide/cpucpu32form.pas @@ -0,0 +1,109 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpucpu32form; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,cpuform,msesplitter,msedataedits, + mseedit,msestrings,msetypes,msegraphedits; + +type + tcpucpu32fo = class(tcpufo) + tspacer1: tspacer; + c: tbooleanedit; + S: tbooleanedit; + tbooleanedit6: tbooleanedit; + tbooleanedit4: tbooleanedit; + tbooleanedit7: tbooleanedit; + tbooleanedit8: tbooleanedit; + tbooleanedit9: tbooleanedit; + tbooleanedit10: tbooleanedit; + tbooleanedit5: tbooleanedit; + tbooleanedit3: tbooleanedit; + tbooleanedit2: tbooleanedit; + tlayouter2: tlayouter; + a1: tintegeredit; + a0: tintegeredit; + a4: tintegeredit; + a3: tintegeredit; + a2: tintegeredit; + a5: tintegeredit; + fp: tintegeredit; + usp: tintegeredit; + pc: tintegeredit; + ssp: tintegeredit; + vbr: tintegeredit; + tlayouter1: tlayouter; + d1: tintegeredit; + d0: tintegeredit; + d4: tintegeredit; + d3: tintegeredit; + d2: tintegeredit; + d5: tintegeredit; + d6: tintegeredit; + d7: tintegeredit; + ps: tintegeredit; + sfc: tintegeredit; + dfc: tintegeredit; + procedure flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure flagonchange(const sender: TObject); + public + constructor create(aowner: tcomponent); override; + function flagedit(const aindex: integer): tcustombooleanedit; override; + end; + +var + cpucpu32fo: tcpucpu32fo; + +implementation +uses + cpucpu32form_mfm; + +constructor tcpucpu32fo.create(aowner: tcomponent); +begin + inherited create(aowner); + fflagswidget:= ps; +end; + +procedure tcpucpu32fo.flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; + +procedure tcpucpu32fo.regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); +begin + doregsetvalue(sender,avalue,accept); +end; + +procedure tcpucpu32fo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +function tcpucpu32fo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= c.tagitem(aindex); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpucpu32form_mfm.pas b/mseide-msegui/apps/ide/cpucpu32form_mfm.pas new file mode 100644 index 0000000..be302a0 --- /dev/null +++ b/mseide-msegui/apps/ide/cpucpu32form_mfm.pas @@ -0,0 +1,793 @@ +unit cpucpu32form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpucpu32form; + +const + objdata: record size: integer; data: array[0..15509] of byte end = + (size: 15510; data: ( + 84,80,70,48,241,11,116,99,112,117,99,112,117,51,50,102,111,10,99,112, + 117,99,112,117,51,50,102,111,8,98,111,117,110,100,115,95,120,3,245,0, + 8,98,111,117,110,100,115,95,121,3,202,0,9,98,111,117,110,100,115,95, + 99,120,3,252,0,9,98,111,117,110,100,115,95,99,121,3,35,1,16,99, + 111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0, + 3,242,0,3,35,1,0,7,99,97,112,116,105,111,110,6,9,67,80,85, + 32,67,80,85,51,50,10,105,99,111,110,46,105,109,97,103,101,10,84,3, + 0,0,0,0,0,0,2,0,0,0,24,0,0,0,24,0,0,0,192,2, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,76,240,145,128,128, + 128,22,128,76,240,2,128,128,128,1,224,224,224,4,216,220,216,1,168,168, + 168,1,136,140,136,1,176,176,176,1,224,224,224,6,200,200,200,1,176,176, + 176,1,208,208,208,1,224,224,224,3,248,252,248,1,128,76,240,2,128,128, + 128,1,224,224,224,3,216,220,216,1,64,64,64,1,8,12,8,1,56,56, + 56,1,8,8,8,1,80,80,80,1,216,220,216,1,224,224,224,2,144,144, + 144,1,16,20,16,1,0,0,0,2,136,140,136,1,224,224,224,3,248,252, + 248,1,128,76,240,2,128,128,128,1,224,224,224,3,120,124,120,1,8,12, + 8,1,200,200,200,1,224,224,224,1,184,188,184,1,0,4,0,1,144,144, + 144,1,224,224,224,2,168,168,168,1,144,144,144,1,184,188,184,1,0,0, + 0,1,136,140,136,1,224,224,224,3,248,252,248,1,128,76,240,2,128,128, + 128,1,224,224,224,3,40,44,40,1,88,92,88,1,224,224,224,3,72,72, + 72,1,64,64,64,1,224,224,224,5,0,0,0,1,136,140,136,1,224,224, + 224,3,248,252,248,1,128,76,240,2,128,128,128,1,224,224,224,2,216,220, + 216,1,0,4,0,1,136,136,136,1,224,224,224,3,112,112,112,1,24,24, + 24,1,224,224,224,5,0,0,0,1,136,140,136,1,224,224,224,3,248,252, + 248,1,128,76,240,2,128,128,128,1,224,224,224,2,208,208,208,1,0,0, + 0,1,144,148,144,1,224,224,224,3,128,128,128,1,8,8,8,1,224,224, + 224,5,0,0,0,1,136,140,136,1,224,224,224,3,248,252,248,1,128,76, + 240,2,128,128,128,1,224,224,224,2,208,212,208,1,0,0,0,1,144,148, + 144,1,224,224,224,3,128,128,128,1,8,8,8,1,224,224,224,5,0,0, + 0,1,136,140,136,1,224,224,224,3,248,252,248,1,128,76,240,2,128,128, + 128,1,224,224,224,2,216,220,216,1,8,8,8,1,128,128,128,1,224,224, + 224,3,104,108,104,1,24,28,24,1,224,224,224,5,0,0,0,1,136,140, + 136,1,224,224,224,3,248,252,248,1,128,76,240,2,128,128,128,1,224,224, + 224,3,48,52,48,1,80,80,80,1,224,224,224,3,56,56,56,1,72,76, + 72,1,224,224,224,5,0,0,0,1,136,140,136,1,224,224,224,3,248,252, + 248,1,128,76,240,2,128,128,128,1,224,224,224,3,144,144,144,1,0,4, + 0,1,168,172,168,1,224,224,224,1,152,156,152,1,0,0,0,1,160,164, + 160,1,224,224,224,2,208,212,208,1,184,188,184,2,0,0,0,1,120,120, + 120,1,184,188,184,1,200,200,200,1,224,224,224,1,248,252,248,1,128,76, + 240,2,128,128,128,1,224,224,224,4,104,104,104,1,0,4,0,1,16,16, + 16,1,0,4,0,1,120,120,120,1,224,224,224,3,160,164,160,1,0,0, + 0,5,80,84,80,1,224,224,224,1,248,252,248,1,128,76,240,2,128,128, + 128,1,224,224,224,5,208,208,208,1,184,184,184,1,208,212,208,1,224,224, + 224,12,248,252,248,1,128,76,240,2,248,252,248,22,128,76,240,97,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,254,255,127,0,254,255,127,0,254,255,127,0,254,255,127,0,254,255, + 127,0,254,255,127,0,254,255,127,0,254,255,127,0,254,255,127,0,254,255, + 127,0,254,255,127,0,254,255,127,0,254,255,127,0,254,255,127,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,6,116,99,112,117,102,111,0,241, + 12,116,98,111,111,108,101,97,110,101,100,105,116,2,111,110,8,98,111,117, + 110,100,115,95,120,3,151,0,8,98,111,117,110,100,115,95,121,2,1,0, + 0,241,13,116,100,97,116,101,116,105,109,101,100,105,115,112,8,115,116,111, + 112,116,105,109,101,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,0,0,242,2,2,7,116,115,112,97,99,101,114, + 8,116,115,112,97,99,101,114,49,8,116,97,98,111,114,100,101,114,2,2, + 7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,18,9,98,111,117,110,100,115,95,99, + 120,3,237,0,9,98,111,117,110,100,115,95,99,121,3,254,0,12,111,112, + 116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97, + 110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95, + 101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0, + 7,108,105,110,107,116,111,112,7,8,115,116,111,112,116,105,109,101,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,1,99,3,84,97,103,2,15, + 5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,1,84,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,8,98,111,117,110,100,115,95,120,2,9,8,98,111,117,110, + 100,115,95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,11,9,98, + 111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117, + 101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,1,83,3,84,97,103,2,13,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,83,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,34,8,98,111,117,110,100,115,95,121,2,3,9,98,111,117, + 110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,28, + 10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101, + 116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,13,116,98,111,111,108,101,97,110,101,100,105,116,54,3,84,97,103,2, + 9,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,73,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117, + 110,100,115,95,120,2,59,8,98,111,117,110,100,115,95,121,2,3,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,28,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115, + 115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,52,3,84,97, + 103,2,4,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,88,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,2,84,8,98,111,117,110,100,115,95,121,2,3, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97, + 103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,55,3, + 84,97,103,2,3,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,78,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,4, + 8,98,111,117,110,100,115,95,120,2,95,8,98,111,117,110,100,115,95,121, + 2,3,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100, + 115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,13,102, + 108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116, + 56,3,84,97,103,2,2,5,99,111,108,111,114,4,3,0,0,128,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,1,90,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,5,8,98,111,117,110,100,115,95,120,2,106,8,98,111,117,110,100,115, + 95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117, + 110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7, + 13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100, + 105,116,57,3,84,97,103,2,1,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,1,86,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,6,8,98,111,117,110,100,115,95,120,2,117,8,98,111,117,110, + 100,115,95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,11,9,98, + 111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117, + 101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110, + 101,100,105,116,49,48,5,99,111,108,111,114,4,3,0,0,128,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,1,67,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2, + 7,8,98,111,117,110,100,115,95,120,3,128,0,8,98,111,117,110,100,115, + 95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117, + 110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7, + 13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100, + 105,116,53,3,84,97,103,2,8,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,8, + 8,98,111,117,110,100,115,95,120,2,70,8,98,111,117,110,100,115,95,121, + 2,20,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100, + 115,95,99,121,2,11,10,111,110,115,101,116,118,97,108,117,101,7,13,102, + 108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116, + 51,3,84,97,103,2,10,5,99,111,108,111,114,4,3,0,0,128,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,9,8,98, + 111,117,110,100,115,95,120,2,48,8,98,111,117,110,100,115,95,121,2,20, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,11,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97, + 103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,50,3, + 84,97,103,2,14,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,10,8,98,111,117, + 110,100,115,95,120,2,20,8,98,111,117,110,100,115,95,121,2,20,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,11,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115, + 115,101,116,118,97,108,117,101,0,0,9,116,108,97,121,111,117,116,101,114, + 10,116,108,97,121,111,117,116,101,114,50,8,116,97,98,111,114,100,101,114, + 2,11,8,98,111,117,110,100,115,95,120,2,118,8,98,111,117,110,100,115, + 95,121,2,34,9,98,111,117,110,100,115,95,99,120,2,119,9,98,111,117, + 110,100,115,95,99,121,3,220,0,12,111,112,116,105,111,110,115,115,99,97, + 108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95, + 115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,0,10,100,105,115,116,95,114,105, + 103,104,116,2,3,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,112,108,97,99,101,121,0,13,112,108,97,99,101,95,109, + 97,120,100,105,115,116,2,0,0,12,116,105,110,116,101,103,101,114,101,100, + 105,116,2,97,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,2,97,49,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,0,2,19,2,0,0,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120, + 2,112,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,97,48,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,97,48, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99, + 112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,112,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,97,52, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 2,97,52,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19, + 2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,80,9,98,111,117, + 110,100,115,95,99,120,2,112,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116, + 2,97,51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,2,97,51,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,60,9, + 98,111,117,110,100,115,95,99,120,2,112,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,97,50,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,2,97,50,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,4, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,40,9,98,111,117,110,100,115,95,99,120,2,112,11,102,111,110,116,46, + 104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9, + 115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,2,97,53,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,2,97,53,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101, + 114,2,5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,100,9,98,111,117,110,100,115,95,99,120,2,112,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110, + 116,101,103,101,114,101,100,105,116,2,102,112,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,2,102,112,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,15,2,0,0,8,116,97,98,111, + 114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,120,9,98,111,117,110,100,115,95,99,120,2,108, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,3,117,115,112,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,117,115,112, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99, + 112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,26,2,0,0, + 8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,3,140,0,9,98,111,117,110,100, + 115,95,99,120,2,119,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,112, + 99,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,2,112,99,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 18,2,0,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,160,0,9,98, + 111,117,110,100,115,95,99,120,2,111,11,102,111,110,116,46,104,101,105,103, + 104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95, + 102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7, + 11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110, + 98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100, + 105,116,3,115,115,112,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,3,115,115,112,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,0,2,25,2,0,0,8,116,97,98,111,114,100,101,114,2, + 9,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,3,180,0,9,98,111,117,110,100,115,95,99,120,2,118,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,3,118,98,114,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,3,118,98,114,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,2,22,2,0,0,8,116,97,98, + 111,114,100,101,114,2,10,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,3,200,0,9,98,111,117,110,100,115,95,99,120, + 2,115,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116, + 101,114,49,8,116,97,98,111,114,100,101,114,2,12,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,34,9,98,111,117, + 110,100,115,95,99,120,2,115,9,98,111,117,110,100,115,95,99,121,3,220, + 0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95, + 101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11, + 111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105, + 110,107,121,0,9,108,105,110,107,114,105,103,104,116,7,10,116,108,97,121, + 111,117,116,101,114,50,10,100,105,115,116,95,114,105,103,104,116,2,3,13, + 111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112, + 108,97,99,101,121,0,13,112,108,97,99,101,95,109,97,120,100,105,115,116, + 2,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,100,49,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2, + 100,49,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19,2, + 0,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,20,9,98,111,117,110,100,115,95,99,120,2,112,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,2,100,48,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,2,100,48,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,112,11, + 102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110, + 97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46, + 120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110, + 115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117, + 101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,2,100,52,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,100,52,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114, + 105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,19,2,0,0,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,80,9,98,111,117,110,100,115,95,99,120, + 2,112,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,100,51,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,100,51, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99, + 112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19,2,0,0, + 8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,60,9,98,111,117,110,100,115, + 95,99,120,2,112,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,100,50, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 2,100,50,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19, + 2,0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,40,9,98,111,117, + 110,100,115,95,99,120,2,112,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116, + 2,100,53,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,2,100,53,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,100,9, + 98,111,117,110,100,115,95,99,120,2,112,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,100,54,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,2,100,54,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,6, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,120,9,98,111,117,110,100,115,95,99,120,2,112,11,102,111,110,116,46, + 104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9, + 115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,2,100,55,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,2,100,55,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101, + 114,2,7,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,3,140,0,9,98,111,117,110,100,115,95,99,120,2,112,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,2,112,115,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,2,112,115,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,2,18,2,0,0,8,116,97,98, + 111,114,100,101,114,2,8,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,3,160,0,9,98,111,117,110,100,115,95,99,120, + 2,111,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105, + 116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,3,115,102,99,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,3,115,102,99,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,0,2,21,2,0,0,8,116,97,98,111,114,100, + 101,114,2,9,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,3,180,0,9,98,111,117,110,100,115,95,99,120,2,114,11, + 102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110, + 97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46, + 120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,8,111,110, + 99,104,97,110,103,101,7,12,102,108,97,103,111,110,99,104,97,110,103,101, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,3,100,102,99,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,100, + 102,99,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,22,2, + 0,0,8,116,97,98,111,114,100,101,114,2,10,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,3,200,0,9,98,111,117, + 110,100,115,95,99,120,2,115,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpucpu32fo,''); +end. diff --git a/mseide-msegui/apps/ide/cpuform.mfm b/mseide-msegui/apps/ide/cpuform.mfm new file mode 100644 index 0000000..29475fe --- /dev/null +++ b/mseide-msegui/apps/ide/cpuform.mfm @@ -0,0 +1,99 @@ +object cpufo: tcpufo + optionswidget = [ow_mousefocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 192 + bounds_y = 451 + bounds_cx = 387 + bounds_cy = 207 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 377 + 207 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'CPU' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'CPU' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 000000000200000018000000180000003C030000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D0607C7C7C19D9D9D916 + FFFFFF017C7C7C01D9D9D904BFBFBF01D9D9D906B1B1B101D9D9D905BCBCBC01 + D9D9D904FFFFFF017C7C7C01D9D9D9027D7D7D01101010010707070128282801 + CCCCCC01D9D9D9039797970105050501D9D9D9039C9C9C011717170107070701 + 18181801B8B8B801D9D9D902FFFFFF017C7C7C01D9D9D901CCCCCC0110101001 + 89898901C2C2C2012626260156565601D9D9D902808080010D0D0D0101010101 + D9D9D9032222220161616101CFCFCF013C3C3C0136363601D9D9D902FFFFFF01 + 7C7C7C01D9D9D901868686011F1F1F01D9D9D902828282011C1C1C01D9D9D901 + AEAEAE010B0B0B016F6F6F0101010101D9D9D902BBBBBB0109090901D5D5D501 + D9D9D901B4B4B40106060601D9D9D902FFFFFF017C7C7C01D9D9D90169696901 + 35353501D9D9D902A8A8A8010D0D0D01D9D9D901CCCCCC01C5C5C501C8C8C801 + 01010101D9D9D902959595011A1A1A01D9D9D90303030301BFBFBF01D9D9D901 + FFFFFF017C7C7C01D9D9D901525252013E3E3E01D9D9D902BBBBBB0103030301 + D9D9D903C8C8C80101010101D9D9D9027979790122222201D9D9D9030A0A0A01 + A7A7A701D9D9D901FFFFFF017C7C7C01D9D9D9015B5B5B0138383801D9D9D902 + AEAEAE010B0B0B01D9D9D903C8C8C80101010101D9D9D902848484011D1D1D01 + D9D9D90305050501BFBFBF01D9D9D901FFFFFF017C7C7C01D9D9D9016F6F6F01 + 28282801D9D9D902929292011A1A1A01D9D9D903C8C8C80101010101D9D9D902 + 9C9C9C0110101001D9D9D902C8C8C80104040401D9D9D902FFFFFF017C7C7C01 + D9D9D901B9B9B9010A0A0A01BFBFBF01D9D9D901414141013F3F3F01D9D9D903 + C8C8C80101010101D9D9D902D5D5D5010F0F0F019A9A9A01D9D9D90163636301 + 23232301D9D9D902FFFFFF017C7C7C01D9D9D902494949010909090123232301 + 0B0B0B01BFBFBF01D9D9D903C8C8C80101010101D9D9D9036B6B6B0105050501 + 2A2A2A01040404019B9B9B01D9D9D902FFFFFF017C7C7C01D9D9D9038D8D8D01 + 79797901CFCFCF01D9D9D904D5D5D50189898901D9D9D9049C9C9C0173737301 + C2C2C201D9D9D903FFFFFF017C7C7C01D9D9D916FFFFFF017C7C7C01D9D9D916 + FFFFFF017C7C7C01FFFFFF17D0D0D06000000000000000000000000000000000 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + 00000000000000000000000000000000 + } + onshow = cpuonshow + onasyncevent = asynceventexe + onstatupdate = updastat + onstatafterread = aftread + onstatbeforewrite = befwrite + moduleclassname = 'tdockform' + object on: tbooleanedit + Tag = -1 + frame.caption = 'CPU &on' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 48 + 2 + ) + bounds_x = 7 + bounds_y = 9 + bounds_cx = 61 + bounds_cy = 16 + onchange = ononchange + value = True + end + object stoptime: tdatetimedisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 80 + bounds_y = 8 + bounds_cx = 124 + bounds_cy = 18 + textflags = [tf_xcentered, tf_right, tf_ycentered] + format = 'yy-mm-dd hh:mm:ss' + kind = dtk_datetime + value = -Inf + reffontheight = 14 + end +end diff --git a/mseide-msegui/apps/ide/cpuform.pas b/mseide-msegui/apps/ide/cpuform.pas new file mode 100644 index 0000000..d4e5b4d --- /dev/null +++ b/mseide-msegui/apps/ide/cpuform.pas @@ -0,0 +1,372 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpuform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + classes,mclasses,msegui,mseclasses,mseforms,msegdbutils,msetypes,msedataedits, + msegraphics,msegraphedits,mseevent,msemenus,msestat,msedispwidgets; + +type + + tcpufo = class(tdockform) + on: tbooleanedit; + stoptime: tdatetimedisp; + procedure cpuonshow(const sender: TObject); + procedure ononchange(const sender: TObject); + procedure updastat(const sender: TObject; const filer: tstatfiler); virtual; + procedure aftread(const sender: TObject); + procedure befwrite(const sender: TObject); + procedure asynceventexe(const sender: TObject; var atag: Integer); + protected + fflagswidget: tintegeredit; + fflagswidget64: tint64edit; + fregisternames: stringarty; + fedits: array of tdataedit; + irqoffvalue: boolean; + fneedsrefresh: boolean; + procedure doregsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); + procedure doregset64value(const sender: TObject; var avalue: Int64; var accept: Boolean); + procedure doflagsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); + procedure doflagonchange(const sender: TObject); + function internalrefresh: boolean; virtual; + procedure updatereadstatvalues; virtual; + procedure updatewritestatvalues; virtual; + procedure updatelayout(const dsender: twidget); override; + procedure updateregisternames() virtual; + public + constructor create(aowner: tcomponent); override; + procedure refresh; virtual; + procedure beforecontinue; virtual; + function flagedit(const aindex: integer): tcustombooleanedit; virtual; + end; + +var + cpufo: tcpufo; + +procedure createcpufo; + +implementation +uses + cpuform_mfm,main,sysutils,mseformatstr,msebits,msestrings,msegraphutils, + cpui386form,cpux86_64form,cpuarmform,cpuarmm3form, + cpucpu32form,cpuavr32form,cpurl78form, + projectoptionsform; +const + refreshtag = 738952; +var + currentproc: processorty; + +procedure createcpufo; +begin + mainfo.gdb.processorname:= ansistring(projectoptions.d.texp.gdbprocessor); + if (cpufo = nil) or (currentproc <> mainfo.gdb.processor) then begin + freeandnil(cpufo); + currentproc:= mainfo.gdb.processor; + case mainfo.gdb.processor of + pro_i386: begin + application.createform(tcpui386fo,cpufo); + end; + pro_x86_64: begin + application.createform(tcpux86_64fo,cpufo); + end; + pro_arm: begin + application.createform(tcpuarmfo,cpufo); + end; + pro_armm3: begin + application.createform(tcpuarmm3fo,cpufo); + end; + pro_cpu32: begin + application.createform(tcpucpu32fo,cpufo); + end; + pro_avr32: begin + application.createform(tcpuavr32fo,cpufo); + end; + pro_rl78: begin + application.createform(tcpurl78fo,cpufo); + end; + else begin + application.createform(tcpufo,cpufo); + end; + end; + end; + cpufo.fregisternames:= nil; +end; + +{ tcpufo } + +function tcpufo.internalrefresh: boolean; +var + ar1: registerinfoarty; + int1,int2: integer; + comp1: tcomponent; + ed1: tdataedit; + str1: msestring; +begin + result:= false; + if fregisternames = nil then begin + if mainfo.gdb.listregisternames(fregisternames) <> gdb_ok then begin + exit; + end; + updateregisternames(); + fedits:= nil; + setlength(fedits,length(fregisternames)); + for int1:= 0 to high(fregisternames) do begin + if fregisternames[int1] <> '' then begin + for int2:= 0 to componentcount - 1 do begin + comp1:= components[int2]; + if (comp1.Name = fregisternames[int1]) then begin + if (comp1 is tdataedit) then begin + fedits[int1]:= tdataedit(comp1); + comp1.Tag:= int1; + end; + break; + end; + end; + end; + end; + end; + if mainfo.gdb.listregistervalues(ar1) = gdb_ok then begin + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if (num >= 0) and (num <= high(fedits)) then begin + ed1:= fedits[num]; + if ed1 <> nil then begin + str1:= ed1.text; + ed1.text:= msestring(ar1[int1].bits); + ed1.checkvalue(true); + if ed1.text <> str1 then begin + ed1.font.color:= cl_red; + end + else begin + ed1.font.color:= cl_black; + end; + end; + end; + end; + end; + result:= true; + end; +end; + +procedure tcpufo.refresh; +begin + if visible and mainfo.gdb.cancommand and on.value then begin + internalrefresh; + end; +end; + +procedure tcpufo.cpuonshow(const sender: TObject); +begin + refresh; +end; + +procedure tcpufo.ononchange(const sender: TObject); +var + int1: integer; +begin + if on.value then begin + for int1:= 0 to childrencount - 1 do begin + children[int1].enabled:= true; + end; + refresh; + end + else begin + for int1:= 0 to childrencount - 1 do begin + if children[int1] <> sender then begin + children[int1].enabled:= false; + end; + end; + end; +end; + +procedure tcpufo.doregsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); +begin + if mainfo.gdb.cancommand then begin + with tintegeredit(sender) do begin + if (mainfo.gdb.setregistervalue( + fregisternames[tag],avalue) <> gdb_ok) then begin + accept:= false; + end + else begin + if fneedsrefresh then begin + self.asyncevent(refreshtag); + end; + end; + end; + end + else begin + accept:= false; + end; +end; + +procedure tcpufo.doregset64value(const sender: TObject; var avalue: Int64; + var accept: Boolean); +begin + if mainfo.gdb.cancommand then begin + with tintegeredit(sender) do begin + if mainfo.gdb.setregistervalue(fregisternames[tag],avalue) <> gdb_ok then begin + accept:= false; + end + else begin + if fneedsrefresh then begin + self.asyncevent(refreshtag); + end; + end; + end; + end + else begin + accept:= false; + end; +end; + +procedure tcpufo.doflagsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + if fflagswidget <> nil then begin + with tbooleanedit(sender) do begin + if avalue then begin + fflagswidget.value:= longword(fflagswidget.value) or bits[tag]; + end + else begin + fflagswidget.value:= longword(fflagswidget.value) and not bits[tag]; + end; + fflagswidget.checkvalue; + end; + end + else begin + if fflagswidget64 <> nil then begin + with tbooleanedit(sender) do begin + if avalue then begin + fflagswidget64.value:= longword(fflagswidget64.value) or bits[tag]; + end + else begin + fflagswidget64.value:= longword(fflagswidget64.value) and not bits[tag]; + end; + fflagswidget64.checkvalue; + end; + end; + end; +end; + +function tcpufo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= nil; +end; + +procedure tcpufo.doflagonchange(const sender: TObject); +var + int1: integer; + ed1: tcustombooleanedit; + bo1: boolean; + ca1: longword; +begin + if fflagswidget <> nil then begin + ca1:= fflagswidget.value; + for int1:= 0 to 31 do begin + ed1:= flagedit(int1); + if (ed1 <> nil) then begin + bo1:= bits[int1] and ca1 <> 0; + if ed1.value <> bo1 then begin + ed1.frame.colorclient:= cl_ltred; + end + else begin + ed1.frame.colorclient:= cl_active; + end; + ed1.value:= bo1; + end; + end; + end + else begin + if fflagswidget64 <> nil then begin + ca1:= fflagswidget64.value; + for int1:= 0 to 31 do begin + ed1:= flagedit(int1); + if (ed1 <> nil) then begin + bo1:= bits[int1] and ca1 <> 0; + if ed1.value <> bo1 then begin + ed1.frame.colorclient:= cl_ltred; + end + else begin + ed1.frame.colorclient:= cl_active; + end; + ed1.value:= bo1; + end; + end; + end; + end; +end; + +procedure tcpufo.beforecontinue; +begin + //dummy +end; + +procedure tcpufo.updastat(const sender: TObject; const filer: tstatfiler); +begin + filer.updatevalue('irqoff',irqoffvalue); +end; + +procedure tcpufo.updatereadstatvalues; +begin + //dummy +end; + +procedure tcpufo.updatewritestatvalues; +begin + //dummy +end; + +procedure tcpufo.aftread(const sender: TObject); +begin + updatereadstatvalues; +end; + +procedure tcpufo.befwrite(const sender: TObject); +begin + updatewritestatvalues; +end; + +constructor tcpufo.create(aowner: tcomponent); +begin + inherited create(aowner); +end; + +procedure tcpufo.updatelayout(const dsender: twidget); +begin + aligny(wam_center,[stoptime,on]); + inherited; +end; + +procedure tcpufo.updateregisternames(); +begin + //dummy +end; + +procedure tcpufo.asynceventexe(const sender: TObject; var atag: Integer); +begin + if atag = refreshtag then begin + refresh; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/cpuform_mfm.pas b/mseide-msegui/apps/ide/cpuform_mfm.pas new file mode 100644 index 0000000..095327a --- /dev/null +++ b/mseide-msegui/apps/ide/cpuform_mfm.pas @@ -0,0 +1,133 @@ +unit cpuform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpuform; + +const + objdata: record size: integer; data: array[0..2317] of byte end = + (size: 2318; data: ( + 84,80,70,48,6,116,99,112,117,102,111,5,99,112,117,102,111,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116, + 111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101,2,10, + 18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110,115,11, + 14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111,95,102, + 105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108,111,97, + 116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110, + 19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110, + 15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95, + 98,117,116,116,111,110,104,105,110,116,115,0,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,192,0,8,98,111,117,110,100,115, + 95,121,3,195,1,9,98,111,117,110,100,115,95,99,120,3,131,1,9,98, + 111,117,110,100,115,95,99,121,3,207,0,26,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114, + 46,98,111,117,110,100,115,1,2,0,2,0,3,121,1,3,207,0,0,22, + 100,114,97,103,100,111,99,107,46,115,112,108,105,116,116,101,114,95,115,105, + 122,101,2,0,16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111, + 110,6,3,67,80,85,20,100,114,97,103,100,111,99,107,46,111,112,116,105, + 111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112,111,115,13, + 111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95,99,97,110, + 109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100,95, + 99,97,110,100,111,99,107,11,111,100,95,112,114,111,112,115,105,122,101,14, + 111,100,95,99,97,112,116,105,111,110,104,105,110,116,0,7,111,112,116,105, + 111,110,115,11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115, + 97,118,101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97, + 116,101,0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112, + 116,105,111,110,6,3,67,80,85,21,105,99,111,110,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,12,105,99,111, + 110,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,0,10,105,99,111,110,46,105,109,97,103,101,10,208,3,0,0,0,0, + 0,0,2,0,0,0,24,0,0,0,24,0,0,0,60,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,208,208,208,96,124,124,124,25,217,217, + 217,22,255,255,255,1,124,124,124,1,217,217,217,4,191,191,191,1,217,217, + 217,6,177,177,177,1,217,217,217,5,188,188,188,1,217,217,217,4,255,255, + 255,1,124,124,124,1,217,217,217,2,125,125,125,1,16,16,16,1,7,7, + 7,1,40,40,40,1,204,204,204,1,217,217,217,3,151,151,151,1,5,5, + 5,1,217,217,217,3,156,156,156,1,23,23,23,1,7,7,7,1,24,24, + 24,1,184,184,184,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217, + 217,1,204,204,204,1,16,16,16,1,137,137,137,1,194,194,194,1,38,38, + 38,1,86,86,86,1,217,217,217,2,128,128,128,1,13,13,13,1,1,1, + 1,1,217,217,217,3,34,34,34,1,97,97,97,1,207,207,207,1,60,60, + 60,1,54,54,54,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217, + 217,1,134,134,134,1,31,31,31,1,217,217,217,2,130,130,130,1,28,28, + 28,1,217,217,217,1,174,174,174,1,11,11,11,1,111,111,111,1,1,1, + 1,1,217,217,217,2,187,187,187,1,9,9,9,1,213,213,213,1,217,217, + 217,1,180,180,180,1,6,6,6,1,217,217,217,2,255,255,255,1,124,124, + 124,1,217,217,217,1,105,105,105,1,53,53,53,1,217,217,217,2,168,168, + 168,1,13,13,13,1,217,217,217,1,204,204,204,1,197,197,197,1,200,200, + 200,1,1,1,1,1,217,217,217,2,149,149,149,1,26,26,26,1,217,217, + 217,3,3,3,3,1,191,191,191,1,217,217,217,1,255,255,255,1,124,124, + 124,1,217,217,217,1,82,82,82,1,62,62,62,1,217,217,217,2,187,187, + 187,1,3,3,3,1,217,217,217,3,200,200,200,1,1,1,1,1,217,217, + 217,2,121,121,121,1,34,34,34,1,217,217,217,3,10,10,10,1,167,167, + 167,1,217,217,217,1,255,255,255,1,124,124,124,1,217,217,217,1,91,91, + 91,1,56,56,56,1,217,217,217,2,174,174,174,1,11,11,11,1,217,217, + 217,3,200,200,200,1,1,1,1,1,217,217,217,2,132,132,132,1,29,29, + 29,1,217,217,217,3,5,5,5,1,191,191,191,1,217,217,217,1,255,255, + 255,1,124,124,124,1,217,217,217,1,111,111,111,1,40,40,40,1,217,217, + 217,2,146,146,146,1,26,26,26,1,217,217,217,3,200,200,200,1,1,1, + 1,1,217,217,217,2,156,156,156,1,16,16,16,1,217,217,217,2,200,200, + 200,1,4,4,4,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217, + 217,1,185,185,185,1,10,10,10,1,191,191,191,1,217,217,217,1,65,65, + 65,1,63,63,63,1,217,217,217,3,200,200,200,1,1,1,1,1,217,217, + 217,2,213,213,213,1,15,15,15,1,154,154,154,1,217,217,217,1,99,99, + 99,1,35,35,35,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217, + 217,2,73,73,73,1,9,9,9,1,35,35,35,1,11,11,11,1,191,191, + 191,1,217,217,217,3,200,200,200,1,1,1,1,1,217,217,217,3,107,107, + 107,1,5,5,5,1,42,42,42,1,4,4,4,1,155,155,155,1,217,217, + 217,2,255,255,255,1,124,124,124,1,217,217,217,3,141,141,141,1,121,121, + 121,1,207,207,207,1,217,217,217,4,213,213,213,1,137,137,137,1,217,217, + 217,4,156,156,156,1,115,115,115,1,194,194,194,1,217,217,217,3,255,255, + 255,1,124,124,124,1,217,217,217,22,255,255,255,1,124,124,124,1,217,217, + 217,22,255,255,255,1,124,124,124,1,255,255,255,23,208,208,208,96,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,255,255, + 255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255, + 255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255, + 255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,111,110,115,104,111, + 119,7,9,99,112,117,111,110,115,104,111,119,12,111,110,97,115,121,110,99, + 101,118,101,110,116,7,13,97,115,121,110,99,101,118,101,110,116,101,120,101, + 12,111,110,115,116,97,116,117,112,100,97,116,101,7,8,117,112,100,97,115, + 116,97,116,15,111,110,115,116,97,116,97,102,116,101,114,114,101,97,100,7, + 7,97,102,116,114,101,97,100,17,111,110,115,116,97,116,98,101,102,111,114, + 101,119,114,105,116,101,7,8,98,101,102,119,114,105,116,101,15,109,111,100, + 117,108,101,99,108,97,115,115,110,97,109,101,6,9,116,100,111,99,107,102, + 111,114,109,0,12,116,98,111,111,108,101,97,110,101,100,105,116,2,111,110, + 3,84,97,103,2,255,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,7,67,80,85,32,38,111,110,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,48,2,2,0,8,98,111,117,110, + 100,115,95,120,2,7,8,98,111,117,110,100,115,95,121,2,9,9,98,111, + 117,110,100,115,95,99,120,2,61,9,98,111,117,110,100,115,95,99,121,2, + 16,8,111,110,99,104,97,110,103,101,7,10,111,110,111,110,99,104,97,110, + 103,101,5,118,97,108,117,101,9,0,0,13,116,100,97,116,101,116,105,109, + 101,100,105,115,112,8,115,116,111,112,116,105,109,101,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100, + 101,114,2,1,8,98,111,117,110,100,115,95,120,2,80,8,98,111,117,110, + 100,115,95,121,2,8,9,98,111,117,110,100,115,95,99,120,2,124,9,98, + 111,117,110,100,115,95,99,121,2,18,9,116,101,120,116,102,108,97,103,115, + 11,12,116,102,95,120,99,101,110,116,101,114,101,100,8,116,102,95,114,105, + 103,104,116,12,116,102,95,121,99,101,110,116,101,114,101,100,0,6,102,111, + 114,109,97,116,6,17,121,121,45,109,109,45,100,100,32,104,104,58,109,109, + 58,115,115,4,107,105,110,100,7,12,100,116,107,95,100,97,116,101,116,105, + 109,101,5,118,97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpufo,''); +end. diff --git a/mseide-msegui/apps/ide/cpui386form.mfm b/mseide-msegui/apps/ide/cpui386form.mfm new file mode 100644 index 0000000..4129d16 --- /dev/null +++ b/mseide-msegui/apps/ide/cpui386form.mfm @@ -0,0 +1,757 @@ +inherited cpui386fo: tcpui386fo + bounds_x = 337 + bounds_y = 295 + bounds_cx = 273 + container.onlayout = cpufoonchildscaled + container.bounds = ( + 0 + 0 + 263 + 207 + ) + caption = 'CPU I386' + onlayout = cpufoonchildscaled + top = 4 + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + bounds_x = 167 + bounds_y = 1 + end + inherited stoptime: tdatetimedisp + bounds_x = 0 + bounds_y = 0 + end + object tspacer1: tspacer[2] + taborder = 2 + visible = True + bounds_x = 0 + bounds_y = 18 + bounds_cx = 254 + bounds_cy = 182 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = stoptime + object c: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 158 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object p: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'P' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 147 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object a: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'A' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 136 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object z: tbooleanedit + Tag = 6 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 125 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object s: tbooleanedit + Tag = 7 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'S' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 114 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object t: tbooleanedit + Tag = 8 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'T' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 103 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object i: tbooleanedit + Tag = 9 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'I' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + bounds_x = 92 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object d: tbooleanedit + Tag = 10 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'D' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + bounds_x = 81 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object o: tbooleanedit + Tag = 11 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'O' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 8 + bounds_x = 70 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object io: tbooleanedit + Tag = 12 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'IO' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 1 + 17 + 2 + 0 + ) + taborder = 9 + bounds_x = 54 + bounds_y = 5 + bounds_cx = 14 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object nt: tbooleanedit + Tag = 15 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'NT' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 3 + 17 + 4 + 0 + ) + taborder = 10 + bounds_x = 34 + bounds_y = 5 + bounds_cx = 18 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object r: tbooleanedit + Tag = 16 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'R' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 11 + bounds_x = 20 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object v: tbooleanedit + Tag = 17 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'V' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 12 + bounds_x = 4 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object ss: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ss' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 13 + bounds_x = 187 + bounds_y = 162 + bounds_cx = 58 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object gs: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'gs' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 14 + bounds_x = 187 + bounds_y = 141 + bounds_cx = 59 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object fs: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'fs' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 15 + bounds_x = 187 + bounds_y = 120 + bounds_cx = 55 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object es: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'es' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 16 + bounds_x = 128 + bounds_y = 162 + bounds_cx = 59 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object ds: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ds' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 17 + bounds_x = 128 + bounds_y = 141 + bounds_cx = 59 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object cs: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'cs' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 18 + bounds_x = 128 + bounds_y = 120 + bounds_cx = 58 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object eflags: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'efl' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 19 + bounds_x = 128 + bounds_y = 36 + bounds_cx = 118 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object eip: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'eip' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 20 + bounds_x = 128 + bounds_y = 78 + bounds_cx = 122 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object esp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'esp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 26 + 0 + ) + taborder = 21 + bounds_x = 128 + bounds_y = 57 + bounds_cx = 126 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object ebp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ebp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 27 + 0 + ) + taborder = 22 + bounds_x = 0 + bounds_y = 162 + bounds_cx = 120 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object edi: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'edi' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 23 + bounds_x = 0 + bounds_y = 141 + bounds_cx = 115 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object esi: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'esi' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 21 + 0 + ) + taborder = 24 + bounds_x = 0 + bounds_y = 120 + bounds_cx = 114 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object edx: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'edx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 25 + 0 + ) + taborder = 25 + bounds_x = 0 + bounds_y = 99 + bounds_cx = 118 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object ecx: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ecx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 26 + bounds_x = 0 + bounds_y = 78 + bounds_cx = 117 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object ebx: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ebx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 25 + 0 + ) + taborder = 27 + bounds_x = 0 + bounds_y = 57 + bounds_cx = 118 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object eax: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'eax' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 25 + 0 + ) + taborder = 28 + bounds_x = 0 + bounds_y = 36 + bounds_cx = 118 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + end +end diff --git a/mseide-msegui/apps/ide/cpui386form.pas b/mseide-msegui/apps/ide/cpui386form.pas new file mode 100644 index 0000000..68e225e --- /dev/null +++ b/mseide-msegui/apps/ide/cpui386form.pas @@ -0,0 +1,131 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpui386form; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + classes,mclasses,msegui,mseclasses,mseforms,msegdbutils,msetypes,msedataedits, + msegraphics,msegraphedits,cpuform,mseguiglob,msemenus,msesplitter,mseedit, + msestrings; + +type + + tcpui386fo = class(tcpufo) + tspacer1: tspacer; + c: tbooleanedit; + p: tbooleanedit; + a: tbooleanedit; + z: tbooleanedit; + s: tbooleanedit; + t: tbooleanedit; + i: tbooleanedit; + d: tbooleanedit; + o: tbooleanedit; + io: tbooleanedit; + nt: tbooleanedit; + r: tbooleanedit; + v: tbooleanedit; + ss: tintegeredit; + gs: tintegeredit; + fs: tintegeredit; + es: tintegeredit; + ds: tintegeredit; + cs: tintegeredit; + eflags: tintegeredit; + eip: tintegeredit; + esp: tintegeredit; + ebp: tintegeredit; + edi: tintegeredit; + esi: tintegeredit; + edx: tintegeredit; + ecx: tintegeredit; + ebx: tintegeredit; + eax: tintegeredit; + procedure flagonchange(const sender: TObject); + procedure flagsetvalue(const sender: TObject; var avalue: Boolean; var accept: Boolean); +// procedure ononchange(const sender: TObject); + procedure regsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); + procedure cpufoonchildscaled(const sender: TObject); + public + constructor create(aowner: tcomponent); override; + function flagedit(const aindex: integer): tcustombooleanedit; override; + end; + +implementation +uses + cpui386form_mfm,main,sysutils,mseformatstr,msebits,msegraphutils; + +{ tcpui386fo } + +constructor tcpui386fo.create(aowner: tcomponent); +begin + inherited create(aowner); + fflagswidget:= eflags; +end; + +function tcpui386fo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= c.tagitem(aindex); +end; + +procedure tcpui386fo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +procedure tcpui386fo.flagsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; +{ +procedure tcpui386fo.ononchange(const sender: TObject); +var + int1: integer; +begin + if on.value then begin + for int1:= 0 to childrencount - 1 do begin + children[int1].enabled:= true; + end; + refresh; + end + else begin + for int1:= 0 to childrencount - 1 do begin + if children[int1] <> sender then begin + children[int1].enabled:= false; + end; + end; + end; +end; +} +procedure tcpui386fo.regsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); +begin + doregsetvalue(sender,avalue,accept); +end; + +procedure tcpui386fo.cpufoonchildscaled(const sender: TObject); +begin + placeyorder(eax.bounds_y,[0],[eax,ebx,ecx,edx,esi,edi,ebp]); + placeyorder(eflags.bounds_y,[0],[eflags,esp,eip]); + placeyorder(esi.bounds_y,[0],[cs,ds,es]); + placeyorder(esi.bounds_y,[0],[fs,gs,ss]); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpui386form_mfm.pas b/mseide-msegui/apps/ide/cpui386form_mfm.pas new file mode 100644 index 0000000..8eb2063 --- /dev/null +++ b/mseide-msegui/apps/ide/cpui386form_mfm.pas @@ -0,0 +1,621 @@ +unit cpui386form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpui386form; + +const + objdata: record size: integer; data: array[0..12072] of byte end = + (size: 12073; data: ( + 84,80,70,48,241,10,116,99,112,117,105,51,56,54,102,111,9,99,112,117, + 105,51,56,54,102,111,8,98,111,117,110,100,115,95,120,3,81,1,8,98, + 111,117,110,100,115,95,121,3,39,1,9,98,111,117,110,100,115,95,99,120, + 3,17,1,18,99,111,110,116,97,105,110,101,114,46,111,110,108,97,121,111, + 117,116,7,18,99,112,117,102,111,111,110,99,104,105,108,100,115,99,97,108, + 101,100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1, + 2,0,2,0,3,7,1,3,207,0,0,7,99,97,112,116,105,111,110,6, + 8,67,80,85,32,73,51,56,54,8,111,110,108,97,121,111,117,116,7,18, + 99,112,117,102,111,111,110,99,104,105,108,100,115,99,97,108,101,100,3,116, + 111,112,2,4,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,6,116,99,112,117,102,111,0,241,12,116,98,111,111,108,101,97,110,101, + 100,105,116,2,111,110,8,98,111,117,110,100,115,95,120,3,167,0,8,98, + 111,117,110,100,115,95,121,2,1,0,0,241,13,116,100,97,116,101,116,105, + 109,101,100,105,115,112,8,115,116,111,112,116,105,109,101,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,0,0,242, + 2,2,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,49,8, + 116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,9,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 18,9,98,111,117,110,100,115,95,99,120,3,254,0,9,98,111,117,110,100, + 115,95,99,121,3,182,0,12,111,112,116,105,111,110,115,115,99,97,108,101, + 11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104, + 114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115, + 99,95,115,104,114,105,110,107,121,0,7,108,105,110,107,116,111,112,7,8, + 115,116,111,112,116,105,109,101,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,1,99,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,1,67,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,17,2,0,2,0,0,8,98,111,117,110,100,115,95,120,3,158,0, + 8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101, + 116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,1,112,3,84,97, + 103,2,2,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,80,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,3,147,0,8,98,111,117,110,100,115,95,121,2, + 5,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115, + 95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108, + 97,103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,1,97,3,84,97,103,2,4,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,65,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,136,0, + 8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101, + 116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,1,122,3,84,97, + 103,2,6,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,90,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,2,125,8,98,111,117,110,100,115,95,121,2,5, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97, + 103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,1,115,3,84,97,103,2,7,5,99,111,108,111,114,4,3, + 0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,83,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98, + 111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2,114,8,98, + 111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2, + 11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118, + 97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,1,116,3,84,97,103,2, + 8,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,84,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117, + 110,100,115,95,120,2,103,8,98,111,117,110,100,115,95,121,2,5,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115, + 101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,1,105,3,84,97,103,2,9,5,99,111,108,111,114,4,3,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,73,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,92,8,98,111,117, + 110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2,11,9, + 98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108, + 117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,1,100,3,84,97,103,2,10,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,68,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100, + 115,95,120,2,81,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117, + 110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,28, + 10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116, + 118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 1,111,3,84,97,103,2,11,5,99,111,108,111,114,4,3,0,0,128,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,1,79,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,8,8,98,111,117,110,100,115,95,120,2,70,8,98,111,117,110,100, + 115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111, + 117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101, + 7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,2,105,111,3,84,97,103,2,12,5,99, + 111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,2,73,79,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,1,2,17,2,2, + 2,0,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100, + 115,95,120,2,54,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117, + 110,100,115,95,99,120,2,14,9,98,111,117,110,100,115,95,99,121,2,28, + 10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116, + 118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 2,110,116,3,84,97,103,2,15,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,2,78,84,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,3,2,17,2,4,2,0,0,8,116,97,98,111,114, + 100,101,114,2,10,8,98,111,117,110,100,115,95,120,2,34,8,98,111,117, + 110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2,18,9, + 98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108, + 117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,1,114,3,84,97,103,2,16,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,82,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,11,8,98,111,117,110,100, + 115,95,120,2,20,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117, + 110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,28, + 10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116, + 118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 1,118,3,84,97,103,2,17,5,99,111,108,111,114,4,3,0,0,128,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,1,86,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,12,8,98,111,117,110,100,115,95,120,2,4,8,98,111,117,110,100, + 115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111, + 117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101, + 7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116,105,110, + 116,101,103,101,114,101,100,105,116,2,115,115,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,2,115,115,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,17,2,0,0,8,116,97,98,111, + 114,100,101,114,2,13,8,98,111,117,110,100,115,95,120,3,187,0,8,98, + 111,117,110,100,115,95,121,3,162,0,9,98,111,117,110,100,115,95,99,120, + 2,58,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105, + 116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,2,103,115,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,2,103,115,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,18,2,0,0,8,116,97,98,111,114,100,101,114, + 2,14,8,98,111,117,110,100,115,95,120,3,187,0,8,98,111,117,110,100, + 115,95,121,3,141,0,9,98,111,117,110,100,115,95,99,120,2,59,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117, + 110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,2,102,115,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,2,102,115,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,15,8,98, + 111,117,110,100,115,95,120,3,187,0,8,98,111,117,110,100,115,95,121,2, + 120,9,98,111,117,110,100,115,95,99,120,2,55,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3, + 109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,101,115,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2, + 101,115,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,18,2, + 0,0,8,116,97,98,111,114,100,101,114,2,16,8,98,111,117,110,100,115, + 95,120,3,128,0,8,98,111,117,110,100,115,95,121,3,162,0,9,98,111, + 117,110,100,115,95,99,120,2,59,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,2,100,115,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,100,115,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,18,2,0,0,8,116, + 97,98,111,114,100,101,114,2,17,8,98,111,117,110,100,115,95,120,3,128, + 0,8,98,111,117,110,100,115,95,121,3,141,0,9,98,111,117,110,100,115, + 95,99,120,2,59,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,2,99,115,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,2,99,115,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,17,2,0,0,8,116,97,98,111,114, + 100,101,114,2,18,8,98,111,117,110,100,115,95,120,3,128,0,8,98,111, + 117,110,100,115,95,121,2,120,9,98,111,117,110,100,115,95,99,120,2,58, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,6,101,102,108,97,103,115,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,3,101,102,108,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,18,2,0,0,8,116,97,98,111,114, + 100,101,114,2,19,8,98,111,117,110,100,115,95,120,3,128,0,8,98,111, + 117,110,100,115,95,121,2,36,9,98,111,117,110,100,115,95,99,120,2,118, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,8,111, + 110,99,104,97,110,103,101,7,12,102,108,97,103,111,110,99,104,97,110,103, + 101,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,3,101,105,112,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3, + 101,105,112,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,22, + 2,0,0,8,116,97,98,111,114,100,101,114,2,20,8,98,111,117,110,100, + 115,95,120,3,128,0,8,98,111,117,110,100,115,95,121,2,78,9,98,111, + 117,110,100,115,95,99,120,2,122,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,3,101,115,112,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,3,101,115,112,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,26,2,0,0,8,116,97,98,111,114,100,101,114,2,21, + 8,98,111,117,110,100,115,95,120,3,128,0,8,98,111,117,110,100,115,95, + 121,2,57,9,98,111,117,110,100,115,95,99,120,2,126,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,3,101,98,112,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,101,98,112,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,27,2,0,0,8,116,97,98,111, + 114,100,101,114,2,22,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,3,162,0,9,98,111,117,110,100,115,95,99,120,2, + 120,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116, + 46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110, + 116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10, + 111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97, + 108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 12,116,105,110,116,101,103,101,114,101,100,105,116,3,101,100,105,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,101,100, + 105,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8, + 99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,22,2,0, + 0,8,116,97,98,111,114,100,101,114,2,23,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,3,141,0,9,98,111,117,110, + 100,115,95,99,120,2,115,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,3, + 101,115,105,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,3,101,115,105,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,21,2,0,0,8,116,97,98,111,114,100,101,114,2,24,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,120, + 9,98,111,117,110,100,115,95,99,120,2,114,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,3,101,100,120,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,3,101,100,120,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,25,2,0,0,8,116,97,98,111,114,100,101, + 114,2,25,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,99,9,98,111,117,110,100,115,95,99,120,2,118,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110, + 116,101,103,101,114,101,100,105,116,3,101,99,120,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,3,101,99,120,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114, + 105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,24,2,0,0,8,116,97, + 98,111,114,100,101,114,2,26,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,78,9,98,111,117,110,100,115,95,99,120, + 2,117,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,3,101,98,120,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,101, + 98,120,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,25,2, + 0,0,8,116,97,98,111,114,100,101,114,2,27,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,57,9,98,111,117,110, + 100,115,95,99,120,2,118,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,3, + 101,97,120,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,3,101,97,120,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,25,2,0,0,8,116,97,98,111,114,100,101,114,2,28,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,36, + 9,98,111,117,110,100,115,95,99,120,2,118,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpui386fo,''); +end. diff --git a/mseide-msegui/apps/ide/cpurl78form.mfm b/mseide-msegui/apps/ide/cpurl78form.mfm new file mode 100644 index 0000000..85a515d --- /dev/null +++ b/mseide-msegui/apps/ide/cpurl78form.mfm @@ -0,0 +1,1743 @@ +inherited cpurl78fo: tcpurl78fo + bounds_x = 24 + bounds_y = 391 + bounds_cx = 377 + bounds_cy = 271 + container.bounds = ( + 0 + 0 + 367 + 271 + ) + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + end + inherited stoptime: tdatetimedisp + taborder = 69 + bounds_x = 72 + end + object a: tintegeredit[2] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'A' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 72 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object x: tintegeredit[3] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'X' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 97 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object ax: tintegeredit[4] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 9 + bounds_x = 72 + bounds_y = 69 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bc: tintegeredit[5] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 10 + bounds_x = 123 + bounds_y = 69 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object b: tintegeredit[6] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'B' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 123 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object c: tintegeredit[7] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 148 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object de: tintegeredit[8] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 11 + bounds_x = 174 + bounds_y = 69 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object d: tintegeredit[9] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'D' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 174 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object e: tintegeredit[10] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'E' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + bounds_x = 199 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object hl: tintegeredit[11] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 12 + bounds_x = 225 + bounds_y = 69 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object h: tintegeredit[12] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'H' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + bounds_x = 225 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object l: tintegeredit[13] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'L' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 8 + bounds_x = 250 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object psw: tintegeredit[14] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'PSW' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 2 + 17 + 2 + 0 + ) + taborder = 68 + bounds_x = 6 + bounds_y = 175 + bounds_cx = 29 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object tgroupbox1: tgroupbox[15] + taborder = 67 + bounds_x = 0 + bounds_y = 32 + bounds_cx = 54 + bounds_cy = 138 + optionsscale = [osc_expandx] + object tbooleanedit9: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'CY' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 18 + 3 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 24 + bounds_cx = 29 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit8: tbooleanedit + Tag = 1 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ISP0' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 30 + 3 + ) + taborder = 5 + bounds_x = 8 + bounds_y = 88 + bounds_cx = 41 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit7: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ISP1' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 30 + 3 + ) + taborder = 4 + bounds_x = 8 + bounds_y = 72 + bounds_cx = 41 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit6: tbooleanedit + Tag = 3 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'RBS0' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 35 + 3 + ) + taborder = 7 + bounds_x = 8 + bounds_y = 120 + bounds_cx = 46 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit5: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'AC' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 19 + 3 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 40 + bounds_cx = 30 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit4: tbooleanedit + Tag = 5 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'RBS1' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 35 + 3 + ) + taborder = 6 + bounds_x = 8 + bounds_y = 104 + bounds_cx = 46 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object z: tbooleanedit + Tag = 6 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 12 + 3 + ) + bounds_x = 8 + bounds_y = 8 + bounds_cx = 23 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit2: tbooleanedit + Tag = 7 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'IE' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 14 + 3 + ) + taborder = 3 + bounds_x = 8 + bounds_y = 56 + bounds_cx = 25 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + end + object sp: tintegeredit[16] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'SP' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 61 + bounds_x = 281 + bounds_y = 48 + bounds_cx = 69 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object pc: tintegeredit[17] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'PC' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 62 + bounds_x = 281 + bounds_y = 69 + bounds_cx = 69 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object es: tintegeredit[18] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ES' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 63 + bounds_x = 281 + bounds_y = 93 + bounds_cx = 69 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object cs: tintegeredit[19] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'CS' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 64 + bounds_x = 281 + bounds_y = 114 + bounds_cx = 69 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object pmc: tintegeredit[20] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'PMC' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 29 + 0 + ) + taborder = 65 + bounds_x = 281 + bounds_y = 136 + bounds_cx = 79 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_r6: tintegeredit[21] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 20 + bounds_x = 250 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_r7: tintegeredit[22] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 19 + bounds_x = 225 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_rp3: tintegeredit[23] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 24 + bounds_x = 225 + bounds_y = 114 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank0_r4: tintegeredit[24] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 18 + bounds_x = 199 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_r5: tintegeredit[25] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 17 + bounds_x = 174 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_rp2: tintegeredit[26] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 23 + bounds_x = 174 + bounds_y = 114 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank0_r2: tintegeredit[27] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 16 + bounds_x = 148 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_r3: tintegeredit[28] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 15 + bounds_x = 123 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_rp1: tintegeredit[29] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 22 + bounds_x = 123 + bounds_y = 114 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank0_rp0: tintegeredit[30] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 21 + bounds_x = 72 + bounds_y = 114 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank0_r0: tintegeredit[31] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 14 + bounds_x = 97 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_r1: tintegeredit[32] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '0' + frame.captionpos = cp_left + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 11 + 0 + 0 + 0 + ) + taborder = 13 + bounds_x = 61 + bounds_y = 93 + bounds_cx = 36 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_r1: tintegeredit[33] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '1' + frame.captionpos = cp_left + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 11 + 0 + 0 + 0 + ) + taborder = 25 + bounds_x = 61 + bounds_y = 136 + bounds_cx = 36 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_r0: tintegeredit[34] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 26 + bounds_x = 97 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_rp0: tintegeredit[35] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 33 + bounds_x = 72 + bounds_y = 157 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank1_rp1: tintegeredit[36] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 34 + bounds_x = 123 + bounds_y = 157 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank1_r3: tintegeredit[37] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 27 + bounds_x = 123 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_r2: tintegeredit[38] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 28 + bounds_x = 148 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_rp2: tintegeredit[39] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 35 + bounds_x = 174 + bounds_y = 157 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank1_r5: tintegeredit[40] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 29 + bounds_x = 174 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_r4: tintegeredit[41] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 30 + bounds_x = 199 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_rp3: tintegeredit[42] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 36 + bounds_x = 225 + bounds_y = 157 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank1_r7: tintegeredit[43] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 31 + bounds_x = 225 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_r6: tintegeredit[44] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 32 + bounds_x = 250 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_r1: tintegeredit[45] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '2' + frame.captionpos = cp_left + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 11 + 0 + 0 + 0 + ) + taborder = 37 + bounds_x = 61 + bounds_y = 179 + bounds_cx = 36 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_r0: tintegeredit[46] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 38 + bounds_x = 97 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_rp0: tintegeredit[47] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 45 + bounds_x = 72 + bounds_y = 200 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank2_rp1: tintegeredit[48] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 46 + bounds_x = 123 + bounds_y = 200 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank2_r3: tintegeredit[49] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 39 + bounds_x = 123 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_r2: tintegeredit[50] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 40 + bounds_x = 148 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_rp2: tintegeredit[51] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 47 + bounds_x = 174 + bounds_y = 200 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank2_r5: tintegeredit[52] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 41 + bounds_x = 174 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_r4: tintegeredit[53] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 42 + bounds_x = 199 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_rp3: tintegeredit[54] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 48 + bounds_x = 225 + bounds_y = 200 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank2_r7: tintegeredit[55] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 43 + bounds_x = 225 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_r6: tintegeredit[56] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 44 + bounds_x = 250 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_r1: tintegeredit[57] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '3' + frame.captionpos = cp_left + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 11 + 0 + 0 + 0 + ) + taborder = 49 + bounds_x = 61 + bounds_y = 222 + bounds_cx = 36 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_r0: tintegeredit[58] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 50 + bounds_x = 97 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_rp0: tintegeredit[59] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 57 + bounds_x = 72 + bounds_y = 243 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank3_rp1: tintegeredit[60] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 58 + bounds_x = 123 + bounds_y = 243 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank3_r3: tintegeredit[61] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 51 + bounds_x = 123 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_r2: tintegeredit[62] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 52 + bounds_x = 148 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_rp2: tintegeredit[63] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 59 + bounds_x = 174 + bounds_y = 243 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank3_r5: tintegeredit[64] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 53 + bounds_x = 174 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_r4: tintegeredit[65] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 54 + bounds_x = 199 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_rp3: tintegeredit[66] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 60 + bounds_x = 225 + bounds_y = 243 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank3_r7: tintegeredit[67] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 55 + bounds_x = 225 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_r6: tintegeredit[68] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 56 + bounds_x = 250 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object mem: tintegeredit[69] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'MEM' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 31 + 0 + ) + taborder = 66 + bounds_x = 281 + bounds_y = 157 + bounds_cx = 81 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end +end diff --git a/mseide-msegui/apps/ide/cpurl78form.pas b/mseide-msegui/apps/ide/cpurl78form.pas new file mode 100644 index 0000000..f3842bd --- /dev/null +++ b/mseide-msegui/apps/ide/cpurl78form.pas @@ -0,0 +1,149 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpurl78form; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,cpuform,msedataedits, + mseedit,mseifiglob,msestrings,msetypes,classes,mclasses,msegraphedits, + msesimplewidgets,msewidgets; + +type + tcpurl78fo = class(tcpufo) + a: tintegeredit; + x: tintegeredit; + ax: tintegeredit; + bc: tintegeredit; + b: tintegeredit; + c: tintegeredit; + de: tintegeredit; + d: tintegeredit; + e: tintegeredit; + hl: tintegeredit; + h: tintegeredit; + l: tintegeredit; + psw: tintegeredit; + tgroupbox1: tgroupbox; + tbooleanedit9: tbooleanedit; + tbooleanedit8: tbooleanedit; + tbooleanedit7: tbooleanedit; + tbooleanedit6: tbooleanedit; + tbooleanedit5: tbooleanedit; + tbooleanedit4: tbooleanedit; + z: tbooleanedit; + tbooleanedit2: tbooleanedit; + sp: tintegeredit; + pc: tintegeredit; + es: tintegeredit; + cs: tintegeredit; + pmc: tintegeredit; + bank0_r6: tintegeredit; + bank0_r7: tintegeredit; + bank0_rp3: tintegeredit; + bank0_r4: tintegeredit; + bank0_r5: tintegeredit; + bank0_rp2: tintegeredit; + bank0_r2: tintegeredit; + bank0_r3: tintegeredit; + bank0_rp1: tintegeredit; + bank0_rp0: tintegeredit; + bank0_r0: tintegeredit; + bank0_r1: tintegeredit; + bank1_r1: tintegeredit; + bank1_r0: tintegeredit; + bank1_rp0: tintegeredit; + bank1_rp1: tintegeredit; + bank1_r3: tintegeredit; + bank1_r2: tintegeredit; + bank1_rp2: tintegeredit; + bank1_r5: tintegeredit; + bank1_r4: tintegeredit; + bank1_rp3: tintegeredit; + bank1_r7: tintegeredit; + bank1_r6: tintegeredit; + bank2_r1: tintegeredit; + bank2_r0: tintegeredit; + bank2_rp0: tintegeredit; + bank2_rp1: tintegeredit; + bank2_r3: tintegeredit; + bank2_r2: tintegeredit; + bank2_rp2: tintegeredit; + bank2_r5: tintegeredit; + bank2_r4: tintegeredit; + bank2_rp3: tintegeredit; + bank2_r7: tintegeredit; + bank2_r6: tintegeredit; + bank3_r1: tintegeredit; + bank3_r0: tintegeredit; + bank3_rp0: tintegeredit; + bank3_rp1: tintegeredit; + bank3_r3: tintegeredit; + bank3_r2: tintegeredit; + bank3_rp2: tintegeredit; + bank3_r5: tintegeredit; + bank3_r4: tintegeredit; + bank3_rp3: tintegeredit; + bank3_r7: tintegeredit; + bank3_r6: tintegeredit; + mem: tintegeredit; + procedure regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure flagsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure flagonchange(const sender: TObject); + function flagedit(const aindex: integer): tcustombooleanedit; override; + public + constructor create(aowner: tcomponent); override; + end; + +var + cpurl78fo: tcpurl78fo; +implementation +uses + cpurl78form_mfm; + +constructor tcpurl78fo.create(aowner: tcomponent); +begin + fneedsrefresh:= true; + inherited; + fflagswidget:= psw; +end; + +procedure tcpurl78fo.regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); +begin + doregsetvalue(sender,avalue,accept); +end; + +procedure tcpurl78fo.flagsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; + +procedure tcpurl78fo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +function tcpurl78fo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= z.tagitem(aindex); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpurl78form_mfm.pas b/mseide-msegui/apps/ide/cpurl78form_mfm.pas new file mode 100644 index 0000000..f7f23ba --- /dev/null +++ b/mseide-msegui/apps/ide/cpurl78form_mfm.pas @@ -0,0 +1,1721 @@ +unit cpurl78form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpurl78form; + +const + objdata: record size: integer; data: array[0..34063] of byte end = + (size: 34064; data: ( + 84,80,70,48,241,10,116,99,112,117,114,108,55,56,102,111,9,99,112,117, + 114,108,55,56,102,111,8,98,111,117,110,100,115,95,120,2,24,8,98,111, + 117,110,100,115,95,121,3,135,1,9,98,111,117,110,100,115,95,99,120,3, + 121,1,9,98,111,117,110,100,115,95,99,121,3,15,1,16,99,111,110,116, + 97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,111,1, + 3,15,1,0,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,6,116,99,112,117,102,111,0,241,12,116,98,111,111,108,101,97,110,101, + 100,105,116,2,111,110,0,0,241,13,116,100,97,116,101,116,105,109,101,100, + 105,115,112,8,115,116,111,112,116,105,109,101,8,116,97,98,111,114,100,101, + 114,2,69,8,98,111,117,110,100,115,95,120,2,72,0,0,242,2,2,12, + 116,105,110,116,101,103,101,114,101,100,105,116,1,97,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,65,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,72,8,98,111,117, + 110,100,115,95,121,2,31,9,98,111,117,110,100,115,95,99,120,2,25,9, + 98,111,117,110,100,115,95,99,121,2,37,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,242,2,3,12,116,105,110,116,101,103,101,114,101,100,105,116,1,120,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 88,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2, + 97,8,98,111,117,110,100,115,95,121,2,31,9,98,111,117,110,100,115,95, + 99,120,2,25,9,98,111,117,110,100,115,95,99,121,2,37,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116, + 2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,242,2,4,12,116,105,110,116,101,103,101,114,101,100, + 105,116,2,97,120,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100, + 115,95,120,2,72,8,98,111,117,110,100,115,95,121,2,69,9,98,111,117, + 110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2, + 5,12,116,105,110,116,101,103,101,114,101,100,105,116,2,98,99,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,10,8,98,111,117,110,100,115,95,120,2,123,8,98,111, + 117,110,100,115,95,121,2,69,9,98,111,117,110,100,115,95,99,120,2,50, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,242,2,6,12,116,105,110,116,101,103, + 101,114,101,100,105,116,1,98,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,1,66,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,2,123,8,98,111,117,110,100,115,95,121,2, + 31,9,98,111,117,110,100,115,95,99,120,2,25,9,98,111,117,110,100,115, + 95,99,121,2,37,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,7,12,116, + 105,110,116,101,103,101,114,101,100,105,116,1,99,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,1,67,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,4,8,98,111,117,110,100,115,95,120,3,148,0,8,98,111,117, + 110,100,115,95,121,2,31,9,98,111,117,110,100,115,95,99,120,2,25,9, + 98,111,117,110,100,115,95,99,121,2,37,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,242,2,8,12,116,105,110,116,101,103,101,114,101,100,105,116,2,100,101, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116, + 97,98,111,114,100,101,114,2,11,8,98,111,117,110,100,115,95,120,3,174, + 0,8,98,111,117,110,100,115,95,121,2,69,9,98,111,117,110,100,115,95, + 99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,9,12,116,105, + 110,116,101,103,101,114,101,100,105,116,1,100,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,1,68,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,5,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111,117,110, + 100,115,95,121,2,31,9,98,111,117,110,100,115,95,99,120,2,25,9,98, + 111,117,110,100,115,95,99,121,2,37,11,102,111,110,116,46,104,101,105,103, + 104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95, + 102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7, + 11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110, + 98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 242,2,10,12,116,105,110,116,101,103,101,114,101,100,105,116,1,101,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,69, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99, + 112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116, + 97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,199, + 0,8,98,111,117,110,100,115,95,121,2,31,9,98,111,117,110,100,115,95, + 99,120,2,25,9,98,111,117,110,100,115,95,99,121,2,37,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116, + 2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,242,2,11,12,116,105,110,116,101,103,101,114,101,100, + 105,116,2,104,108,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,12,8,98,111,117,110,100, + 115,95,120,3,225,0,8,98,111,117,110,100,115,95,121,2,69,9,98,111, + 117,110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242, + 2,12,12,116,105,110,116,101,103,101,114,101,100,105,116,1,104,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,72,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120,3,225,0, + 8,98,111,117,110,100,115,95,121,2,31,9,98,111,117,110,100,115,95,99, + 120,2,25,9,98,111,117,110,100,115,95,99,121,2,37,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,13,12,116,105,110,116,101,103,101,114,101,100,105, + 116,1,108,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,76,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111,117,110,100, + 115,95,120,3,250,0,8,98,111,117,110,100,115,95,121,2,31,9,98,111, + 117,110,100,115,95,99,120,2,25,9,98,111,117,110,100,115,95,99,121,2, + 37,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116, + 46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110, + 116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10, + 111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97, + 108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116, + 99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,242,2,14,12,116,105,110,116,101, + 103,101,114,101,100,105,116,3,112,115,119,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,80,83,87,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,2,2,17,2,2,2,0,0,8,116,97,98,111,114,100, + 101,114,2,68,8,98,111,117,110,100,115,95,120,2,6,8,98,111,117,110, + 100,115,95,121,3,175,0,9,98,111,117,110,100,115,95,99,120,2,29,9, + 98,111,117,110,100,115,95,99,121,2,37,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,8,111,110,99,104,97,110,103,101,7,12, + 102,108,97,103,111,110,99,104,97,110,103,101,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8, + 3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,16,0,0,242,2,15,9,116,103,114,111,117,112,98,111,120,10,116,103, + 114,111,117,112,98,111,120,49,8,116,97,98,111,114,100,101,114,2,67,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 32,9,98,111,117,110,100,115,95,99,120,2,54,9,98,111,117,110,100,115, + 95,99,121,3,138,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,120,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116, + 57,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,2,67,89,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,2,2,18,2,3, + 0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,2,8,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110,100, + 115,95,99,120,2,29,9,98,111,117,110,100,115,95,99,121,2,16,10,111, + 110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97, + 108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116, + 98,111,111,108,101,97,110,101,100,105,116,56,3,84,97,103,2,1,5,99, + 111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,4,73,83,80,48,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,2,2,30,2,3,0, + 8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,88,9,98,111,117,110,100,115, + 95,99,120,2,41,9,98,111,117,110,100,115,95,99,121,2,16,10,111,110, + 115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108, + 117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,55,3,84,97,103,2,2,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,4,73,83,80,49,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,2,2,30,2,3,0,8, + 116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,2,72,9,98,111,117,110,100,115,95, + 99,120,2,41,9,98,111,117,110,100,115,95,99,121,2,16,10,111,110,115, + 101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117, + 101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111, + 111,108,101,97,110,101,100,105,116,54,3,84,97,103,2,3,5,99,111,108, + 111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 4,82,66,83,48,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,2,2,35,2,3,0,8,116, + 97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120,2,8, + 8,98,111,117,110,100,115,95,121,2,120,9,98,111,117,110,100,115,95,99, + 120,2,46,9,98,111,117,110,100,115,95,99,121,2,16,10,111,110,115,101, + 116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111, + 108,101,97,110,101,100,105,116,53,3,84,97,103,2,4,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2, + 65,67,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,2,2,19,2,3,0,8,116,97,98,111, + 114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,8,8,98,111, + 117,110,100,115,95,121,2,40,9,98,111,117,110,100,115,95,99,120,2,30, + 9,98,111,117,110,100,115,95,99,121,2,16,10,111,110,115,101,116,118,97, + 108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97, + 110,101,100,105,116,52,3,84,97,103,2,5,5,99,111,108,111,114,4,3, + 0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,4,82,66,83, + 49,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,2,2,35,2,3,0,8,116,97,98,111,114, + 100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117, + 110,100,115,95,121,2,104,9,98,111,117,110,100,115,95,99,120,2,46,9, + 98,111,117,110,100,115,95,99,121,2,16,10,111,110,115,101,116,118,97,108, + 117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,1,122,3,84,97,103,2,6,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,90,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,2,2,12,2,3,0,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,8, + 9,98,111,117,110,100,115,95,99,120,2,23,9,98,111,117,110,100,115,95, + 99,121,2,16,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97, + 103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,50,3,84, + 97,103,2,7,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,2,73,69,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,2,2, + 14,2,3,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110, + 100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,56,9,98,111, + 117,110,100,115,95,99,120,2,25,9,98,111,117,110,100,115,95,99,121,2, + 16,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101, + 116,118,97,108,117,101,0,0,0,242,2,16,12,116,105,110,116,101,103,101, + 114,101,100,105,116,2,115,112,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,2,83,80,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101,114, + 2,61,8,98,111,117,110,100,115,95,120,3,25,1,8,98,111,117,110,100, + 115,95,121,2,48,9,98,111,117,110,100,115,95,99,120,2,69,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110, + 116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,242,2,17,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,112,99,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,2,80,67,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,62, + 8,98,111,117,110,100,115,95,120,3,25,1,8,98,111,117,110,100,115,95, + 121,2,69,9,98,111,117,110,100,115,95,99,120,2,69,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,18,12,116,105,110,116,101,103,101,114,101,100,105, + 116,2,101,115,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,2,69,83,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,63,8,98, + 111,117,110,100,115,95,120,3,25,1,8,98,111,117,110,100,115,95,121,2, + 93,9,98,111,117,110,100,115,95,99,120,2,69,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3, + 109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 16,0,0,242,2,19,12,116,105,110,116,101,103,101,114,101,100,105,116,2, + 99,115,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,2,67,83,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0, + 2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,64,8,98,111,117, + 110,100,115,95,120,3,25,1,8,98,111,117,110,100,115,95,121,2,114,9, + 98,111,117,110,100,115,95,99,120,2,69,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,242,2,20,12,116,105,110,116,101,103,101,114,101,100,105,116,3,112,109, + 99,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,3,80,77,67,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0, + 2,29,2,0,0,8,116,97,98,111,114,100,101,114,2,65,8,98,111,117, + 110,100,115,95,120,3,25,1,8,98,111,117,110,100,115,95,121,3,136,0, + 9,98,111,117,110,100,115,95,99,120,2,79,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,242,2,21,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98, + 97,110,107,48,95,114,54,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,20,8,98,111,117,110,100, + 115,95,120,3,250,0,8,98,111,117,110,100,115,95,121,2,93,9,98,111, + 117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242, + 2,22,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107, + 48,95,114,55,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,19,8,98,111,117,110,100,115,95,120, + 3,225,0,8,98,111,117,110,100,115,95,121,2,93,9,98,111,117,110,100, + 115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,23,12, + 116,105,110,116,101,103,101,114,101,100,105,116,9,98,97,110,107,48,95,114, + 112,51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,24,8,98,111,117,110,100,115,95,120, + 3,225,0,8,98,111,117,110,100,115,95,121,2,114,9,98,111,117,110,100, + 115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,24,12, + 116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,48,95,114, + 52,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,18,8,98,111,117,110,100,115,95,120,3,199,0, + 8,98,111,117,110,100,115,95,121,2,93,9,98,111,117,110,100,115,95,99, + 120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98, + 105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,25,12,116,105,110, + 116,101,103,101,114,101,100,105,116,8,98,97,110,107,48,95,114,53,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,17,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111, + 117,110,100,115,95,121,2,93,9,98,111,117,110,100,115,95,99,120,2,25, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,242,2,26,12,116,105,110,116,101,103, + 101,114,101,100,105,116,9,98,97,110,107,48,95,114,112,50,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8, + 99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,23,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111, + 117,110,100,115,95,121,2,114,9,98,111,117,110,100,115,95,99,120,2,50, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,242,2,27,12,116,105,110,116,101,103, + 101,114,101,100,105,116,8,98,97,110,107,48,95,114,50,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99, + 112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,16,8,98,111,117,110,100,115,95,120,3,148,0,8,98,111,117,110,100, + 115,95,121,2,93,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110, + 116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,242,2,28,12,116,105,110,116,101,103,101,114,101, + 100,105,116,8,98,97,110,107,48,95,114,51,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,15,8, + 98,111,117,110,100,115,95,120,2,123,8,98,111,117,110,100,115,95,121,2, + 93,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3, + 109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 16,0,0,242,2,29,12,116,105,110,116,101,103,101,114,101,100,105,116,9, + 98,97,110,107,48,95,114,112,49,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,22,8,98, + 111,117,110,100,115,95,120,2,123,8,98,111,117,110,100,115,95,121,2,114, + 9,98,111,117,110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,242,2,30,12,116,105,110,116,101,103,101,114,101,100,105,116,9,98, + 97,110,107,48,95,114,112,48,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,21,8,98,111, + 117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,2,114,9, + 98,111,117,110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,242,2,31,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97, + 110,107,48,95,114,48,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,116,97,98,111,114,100,101,114,2,14,8,98,111,117,110,100,115, + 95,120,2,97,8,98,111,117,110,100,115,95,121,2,93,9,98,111,117,110, + 100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,32, + 12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,48,95, + 114,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,1,48,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,7,99,112,95,108,101,102,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,11,2,0,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,13,8,98,111,117,110,100, + 115,95,120,2,61,8,98,111,117,110,100,115,95,121,2,93,9,98,111,117, + 110,100,115,95,99,120,2,36,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2, + 33,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,49, + 95,114,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,49,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,7,99,112,95,108,101,102,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,11,2,0,2, + 0,2,0,0,8,116,97,98,111,114,100,101,114,2,25,8,98,111,117,110, + 100,115,95,120,2,61,8,98,111,117,110,100,115,95,121,3,136,0,9,98, + 111,117,110,100,115,95,99,120,2,36,11,102,111,110,116,46,104,101,105,103, + 104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95, + 102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7, + 11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110, + 98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 242,2,34,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110, + 107,49,95,114,48,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,26,8,98,111,117,110,100,115,95, + 120,2,97,8,98,111,117,110,100,115,95,121,3,136,0,9,98,111,117,110, + 100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,35, + 12,116,105,110,116,101,103,101,114,101,100,105,116,9,98,97,110,107,49,95, + 114,112,48,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,33,8,98,111,117,110,100,115,95, + 120,2,72,8,98,111,117,110,100,115,95,121,3,157,0,9,98,111,117,110, + 100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,36, + 12,116,105,110,116,101,103,101,114,101,100,105,116,9,98,97,110,107,49,95, + 114,112,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,34,8,98,111,117,110,100,115,95, + 120,2,123,8,98,111,117,110,100,115,95,121,3,157,0,9,98,111,117,110, + 100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,37, + 12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,49,95, + 114,51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116, + 97,98,111,114,100,101,114,2,27,8,98,111,117,110,100,115,95,120,2,123, + 8,98,111,117,110,100,115,95,121,3,136,0,9,98,111,117,110,100,115,95, + 99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,38,12,116,105, + 110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,49,95,114,50,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,28,8,98,111,117,110,100,115,95,120,3,148,0,8,98, + 111,117,110,100,115,95,121,3,136,0,9,98,111,117,110,100,115,95,99,120, + 2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105, + 116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,16,0,0,242,2,39,12,116,105,110,116, + 101,103,101,114,101,100,105,116,9,98,97,110,107,49,95,114,112,50,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98, + 111,114,100,101,114,2,35,8,98,111,117,110,100,115,95,120,3,174,0,8, + 98,111,117,110,100,115,95,121,3,157,0,9,98,111,117,110,100,115,95,99, + 120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98, + 105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,40,12,116,105,110, + 116,101,103,101,114,101,100,105,116,8,98,97,110,107,49,95,114,53,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,29,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111, + 117,110,100,115,95,121,3,136,0,9,98,111,117,110,100,115,95,99,120,2, + 25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116, + 46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110, + 116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10, + 111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97, + 108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116, + 99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,242,2,41,12,116,105,110,116,101, + 103,101,114,101,100,105,116,8,98,97,110,107,49,95,114,52,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,30,8,98,111,117,110,100,115,95,120,3,199,0,8,98,111,117,110, + 100,115,95,121,3,136,0,9,98,111,117,110,100,115,95,99,120,2,25,11, + 102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110, + 97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46, + 120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110, + 115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117, + 101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111, + 117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,16,0,0,242,2,42,12,116,105,110,116,101,103,101, + 114,101,100,105,116,9,98,97,110,107,49,95,114,112,51,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99, + 112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100, + 101,114,2,36,8,98,111,117,110,100,115,95,120,3,225,0,8,98,111,117, + 110,100,115,95,121,3,157,0,9,98,111,117,110,100,115,95,99,120,2,50, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,242,2,43,12,116,105,110,116,101,103, + 101,114,101,100,105,116,8,98,97,110,107,49,95,114,55,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99, + 112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,31,8,98,111,117,110,100,115,95,120,3,225,0,8,98,111,117,110,100, + 115,95,121,3,136,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117, + 110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,242,2,44,12,116,105,110,116,101,103,101,114, + 101,100,105,116,8,98,97,110,107,49,95,114,54,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,32, + 8,98,111,117,110,100,115,95,120,3,250,0,8,98,111,117,110,100,115,95, + 121,3,136,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116, + 2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,242,2,45,12,116,105,110,116,101,103,101,114,101,100, + 105,116,8,98,97,110,107,50,95,114,49,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,1,50,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,7,99,112,95,108,101,102,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,11,2,0,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,37,8,98,111,117,110,100,115,95,120,2,61,8,98,111,117,110,100, + 115,95,121,3,179,0,9,98,111,117,110,100,115,95,99,120,2,36,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117, + 110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,242,2,46,12,116,105,110,116,101,103,101,114, + 101,100,105,116,8,98,97,110,107,50,95,114,48,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,38, + 8,98,111,117,110,100,115,95,120,2,97,8,98,111,117,110,100,115,95,121, + 3,179,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,47,12,116,105,110,116,101,103,101,114,101,100,105, + 116,9,98,97,110,107,50,95,114,112,48,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,45, + 8,98,111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121, + 3,200,0,9,98,111,117,110,100,115,95,99,120,2,50,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,48,12,116,105,110,116,101,103,101,114,101,100,105, + 116,9,98,97,110,107,50,95,114,112,49,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,46, + 8,98,111,117,110,100,115,95,120,2,123,8,98,111,117,110,100,115,95,121, + 3,200,0,9,98,111,117,110,100,115,95,99,120,2,50,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,49,12,116,105,110,116,101,103,101,114,101,100,105, + 116,8,98,97,110,107,50,95,114,51,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,39,8,98,111, + 117,110,100,115,95,120,2,123,8,98,111,117,110,100,115,95,121,3,179,0, + 9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,242,2,50,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98, + 97,110,107,50,95,114,50,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,40,8,98,111,117,110,100, + 115,95,120,3,148,0,8,98,111,117,110,100,115,95,121,3,179,0,9,98, + 111,117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103, + 104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95, + 102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7, + 11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110, + 98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 242,2,51,12,116,105,110,116,101,103,101,114,101,100,105,116,9,98,97,110, + 107,50,95,114,112,50,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,47,8,98,111,117,110, + 100,115,95,120,3,174,0,8,98,111,117,110,100,115,95,121,3,200,0,9, + 98,111,117,110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,242,2,52,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97, + 110,107,50,95,114,53,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,116,97,98,111,114,100,101,114,2,41,8,98,111,117,110,100,115, + 95,120,3,174,0,8,98,111,117,110,100,115,95,121,3,179,0,9,98,111, + 117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242, + 2,53,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107, + 50,95,114,52,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,42,8,98,111,117,110,100,115,95,120, + 3,199,0,8,98,111,117,110,100,115,95,121,3,179,0,9,98,111,117,110, + 100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,54, + 12,116,105,110,116,101,103,101,114,101,100,105,116,9,98,97,110,107,50,95, + 114,112,51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,48,8,98,111,117,110,100,115,95, + 120,3,225,0,8,98,111,117,110,100,115,95,121,3,200,0,9,98,111,117, + 110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2, + 55,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,50, + 95,114,55,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,43,8,98,111,117,110,100,115,95,120,3, + 225,0,8,98,111,117,110,100,115,95,121,3,179,0,9,98,111,117,110,100, + 115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,56,12, + 116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,50,95,114, + 54,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,44,8,98,111,117,110,100,115,95,120,3,250,0, + 8,98,111,117,110,100,115,95,121,3,179,0,9,98,111,117,110,100,115,95, + 99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,57,12,116,105, + 110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,51,95,114,49,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 51,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,7, + 99,112,95,108,101,102,116,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,11,2,0,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,49,8,98,111,117,110,100,115,95,120, + 2,61,8,98,111,117,110,100,115,95,121,3,222,0,9,98,111,117,110,100, + 115,95,99,120,2,36,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,58,12, + 116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,51,95,114, + 48,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,50,8,98,111,117,110,100,115,95,120,2,97,8, + 98,111,117,110,100,115,95,121,3,222,0,9,98,111,117,110,100,115,95,99, + 120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98, + 105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,59,12,116,105,110, + 116,101,103,101,114,101,100,105,116,9,98,97,110,107,51,95,114,112,48,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,57,8,98,111,117,110,100,115,95,120,2,72,8, + 98,111,117,110,100,115,95,121,3,243,0,9,98,111,117,110,100,115,95,99, + 120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98, + 105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,60,12,116,105,110, + 116,101,103,101,114,101,100,105,116,9,98,97,110,107,51,95,114,112,49,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,58,8,98,111,117,110,100,115,95,120,2,123,8, + 98,111,117,110,100,115,95,121,3,243,0,9,98,111,117,110,100,115,95,99, + 120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98, + 105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,61,12,116,105,110, + 116,101,103,101,114,101,100,105,116,8,98,97,110,107,51,95,114,51,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,51,8,98,111,117,110,100,115,95,120,2,123,8,98,111,117, + 110,100,115,95,121,3,222,0,9,98,111,117,110,100,115,95,99,120,2,25, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,242,2,62,12,116,105,110,116,101,103, + 101,114,101,100,105,116,8,98,97,110,107,51,95,114,50,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99, + 112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,52,8,98,111,117,110,100,115,95,120,3,148,0,8,98,111,117,110,100, + 115,95,121,3,222,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117, + 110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,242,2,63,12,116,105,110,116,101,103,101,114, + 101,100,105,116,9,98,97,110,107,51,95,114,112,50,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,59,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111,117,110, + 100,115,95,121,3,243,0,9,98,111,117,110,100,115,95,99,120,2,50,11, + 102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110, + 97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46, + 120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110, + 115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117, + 101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111, + 117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,16,0,0,242,2,64,12,116,105,110,116,101,103,101, + 114,101,100,105,116,8,98,97,110,107,51,95,114,53,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 53,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111,117,110,100,115, + 95,121,3,222,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110, + 116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,242,2,65,12,116,105,110,116,101,103,101,114,101, + 100,105,116,8,98,97,110,107,51,95,114,52,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,54,8, + 98,111,117,110,100,115,95,120,3,199,0,8,98,111,117,110,100,115,95,121, + 3,222,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,66,12,116,105,110,116,101,103,101,114,101,100,105, + 116,9,98,97,110,107,51,95,114,112,51,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,60, + 8,98,111,117,110,100,115,95,120,3,225,0,8,98,111,117,110,100,115,95, + 121,3,243,0,9,98,111,117,110,100,115,95,99,120,2,50,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116, + 2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,242,2,67,12,116,105,110,116,101,103,101,114,101,100, + 105,116,8,98,97,110,107,51,95,114,55,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,55,8,98, + 111,117,110,100,115,95,120,3,225,0,8,98,111,117,110,100,115,95,121,3, + 222,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116,46, + 104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9, + 115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8, + 3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,16,0,0,242,2,68,12,116,105,110,116,101,103,101,114,101,100,105,116, + 8,98,97,110,107,51,95,114,54,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,56,8,98,111,117, + 110,100,115,95,120,3,250,0,8,98,111,117,110,100,115,95,121,3,222,0, + 9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,242,2,69,12,116,105,110,116,101,103,101,114,101,100,105,116,3,109, + 101,109,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,3,77,69,77,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,31,2,0,0,8,116,97,98,111,114,100,101,114,2,66,8,98,111, + 117,110,100,115,95,120,3,25,1,8,98,111,117,110,100,115,95,121,3,157, + 0,9,98,111,117,110,100,115,95,99,120,2,81,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3, + 109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 16,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpurl78fo,''); +end. diff --git a/mseide-msegui/apps/ide/cpux86_64form.mfm b/mseide-msegui/apps/ide/cpux86_64form.mfm new file mode 100644 index 0000000..790b363 --- /dev/null +++ b/mseide-msegui/apps/ide/cpux86_64form.mfm @@ -0,0 +1,807 @@ +inherited cpuc86_64fo: tcpux86_64fo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + bounds_x = 183 + bounds_y = 113 + bounds_cx = 352 + bounds_cy = 277 + container.onlayout = cpufoonchildscaled + container.bounds = ( + 0 + 0 + 342 + 277 + ) + caption = 'CPU X68_64' + onlayout = cpufoonchildscaled + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + bounds_x = 215 + bounds_y = 1 + end + inherited stoptime: tdatetimedisp + bounds_x = -8 + bounds_y = 0 + bounds_cx = 141 + end + object tspacer1: tspacer[2] + taborder = 2 + visible = True + bounds_x = 0 + bounds_y = 18 + bounds_cx = 341 + bounds_cy = 249 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = stoptime + object r14: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r14' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + bounds_x = 176 + bounds_y = 208 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r13: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r13' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 1 + bounds_x = 176 + bounds_y = 187 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r12: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r12' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 2 + bounds_x = 176 + bounds_y = 166 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r11: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r11' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 3 + bounds_x = 176 + bounds_y = 145 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r10: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r10' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 4 + bounds_x = 176 + bounds_y = 124 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r15: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r15' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 5 + bounds_x = 176 + bounds_y = 229 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r9: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r9' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 16 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 229 + bounds_cx = 157 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r8: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r8' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 16 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 208 + bounds_cx = 157 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object io: tbooleanedit + Tag = 12 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'IO' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 1 + 17 + 2 + 0 + ) + taborder = 8 + bounds_x = 57 + bounds_y = 9 + bounds_cx = 14 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object nt: tbooleanedit + Tag = 15 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'NT' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 3 + 17 + 4 + 0 + ) + taborder = 9 + bounds_x = 37 + bounds_y = 9 + bounds_cx = 18 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object c: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 10 + bounds_x = 161 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object p: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'P' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 11 + bounds_x = 150 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object a: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'A' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 12 + bounds_x = 139 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object z: tbooleanedit + Tag = 6 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 13 + bounds_x = 128 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object s: tbooleanedit + Tag = 7 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'S' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 14 + bounds_x = 117 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object t: tbooleanedit + Tag = 8 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'T' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 15 + bounds_x = 106 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object i: tbooleanedit + Tag = 9 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'I' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 16 + bounds_x = 95 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object d: tbooleanedit + Tag = 10 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'D' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 17 + bounds_x = 84 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object o: tbooleanedit + Tag = 11 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'O' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 18 + bounds_x = 73 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object eflags: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rfl' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 15 + 0 + ) + taborder = 19 + bounds_x = 176 + bounds_y = 40 + bounds_cx = 155 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rip: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rip' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 20 + bounds_x = 176 + bounds_y = 82 + bounds_cx = 159 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rsp: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rsp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 23 + 0 + ) + taborder = 21 + bounds_x = 176 + bounds_y = 61 + bounds_cx = 163 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rbp: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rbp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 22 + bounds_x = 0 + bounds_y = 124 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rdi: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rdi' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 23 + bounds_x = 0 + bounds_y = 166 + bounds_cx = 160 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rsi: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rsi' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 24 + bounds_x = 0 + bounds_y = 145 + bounds_cx = 159 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rdx: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rdx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 25 + bounds_x = 0 + bounds_y = 103 + bounds_cx = 163 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rcx: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rcx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 21 + 0 + ) + taborder = 26 + bounds_x = 0 + bounds_y = 82 + bounds_cx = 162 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rbx: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rbx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 27 + bounds_x = 0 + bounds_y = 61 + bounds_cx = 163 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rax: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rax' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 28 + bounds_x = 0 + bounds_y = 40 + bounds_cx = 163 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r: tbooleanedit + Tag = 16 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'R' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 29 + bounds_x = 23 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object v: tbooleanedit + Tag = 17 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'V' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 30 + bounds_x = 7 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + end +end diff --git a/mseide-msegui/apps/ide/cpux86_64form.pas b/mseide-msegui/apps/ide/cpux86_64form.pas new file mode 100644 index 0000000..65dc549 --- /dev/null +++ b/mseide-msegui/apps/ide/cpux86_64form.pas @@ -0,0 +1,133 @@ +{ MSEide Copyright (c) 2009-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpux86_64form; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + classes,mclasses,msegui,mseclasses,mseforms,msegdbutils,msetypes,msedataedits, + msegraphics,msegraphedits,cpuform,msegraphutils,mseguiglob,msemenus, + msesimplewidgets,msewidgets,mseedit,msestrings,msesplitter; + +type + + tcpux86_64fo = class(tcpufo) + tspacer1: tspacer; + r14: tint64edit; + r13: tint64edit; + r12: tint64edit; + r11: tint64edit; + r10: tint64edit; + r15: tint64edit; + r9: tint64edit; + r8: tint64edit; + io: tbooleanedit; + nt: tbooleanedit; + c: tbooleanedit; + p: tbooleanedit; + a: tbooleanedit; + z: tbooleanedit; + s: tbooleanedit; + t: tbooleanedit; + i: tbooleanedit; + d: tbooleanedit; + o: tbooleanedit; + eflags: tint64edit; + rip: tint64edit; + rsp: tint64edit; + rbp: tint64edit; + rdi: tint64edit; + rsi: tint64edit; + rdx: tint64edit; + rcx: tint64edit; + rbx: tint64edit; + rax: tint64edit; + r: tbooleanedit; + v: tbooleanedit; + procedure flagonchange(const sender: TObject); + procedure flagsetvalue(const sender: TObject; var avalue: Boolean; var accept: Boolean); +// procedure ononchange(const sender: TObject); + procedure regsetvalue(const sender: TObject; var avalue: Int64; var accept: Boolean); + procedure cpufoonchildscaled(const sender: TObject); + public + constructor create(aowner: tcomponent); override; + function flagedit(const aindex: integer): tcustombooleanedit; override; + end; + +implementation +uses + cpux86_64form_mfm,main,sysutils,mseformatstr,msebits; + +{ tcpux86_64fo } + +constructor tcpux86_64fo.create(aowner: tcomponent); +begin + inherited create(aowner); + fflagswidget64:= eflags; +end; + +procedure tcpux86_64fo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +procedure tcpux86_64fo.flagsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; +{ +procedure tcpux86_64fo.ononchange(const sender: TObject); +var + int1: integer; +begin + if on.value then begin + for int1:= 0 to childrencount - 1 do begin + children[int1].enabled:= true; + end; + refresh; + end + else begin + for int1:= 0 to childrencount - 1 do begin + if children[int1] <> sender then begin + children[int1].enabled:= false; + end; + end; + end; +end; +} +procedure tcpux86_64fo.regsetvalue(const sender: TObject; var avalue: Int64; var accept: Boolean); +begin + doregset64value(sender,avalue,accept); +end; + +procedure tcpux86_64fo.cpufoonchildscaled(const sender: TObject); +begin + placeyorder(rax.bounds_y,[0],[rax,rbx,rcx,rdx,rbp,rsi,rdi]); + placeyorder(rdi.bounds_y+2*rdi.bounds_cy,[0],[r8,r9]); + placeyorder(eflags.bounds_y,[0],[eflags,rsp,rip]); + placeyorder(rbp.bounds_y,[0],[r10,r11,r12,r13,r14,r15]); +end; + +function tcpux86_64fo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= c.tagitem(aindex); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpux86_64form_mfm.pas b/mseide-msegui/apps/ide/cpux86_64form_mfm.pas new file mode 100644 index 0000000..2a88609 --- /dev/null +++ b/mseide-msegui/apps/ide/cpux86_64form_mfm.pas @@ -0,0 +1,671 @@ +unit cpux86_64form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpux86_64form; + +const + objdata: record size: integer; data: array[0..13079] of byte end = + (size: 13080; data: ( + 84,80,70,48,241,12,116,99,112,117,120,56,54,95,54,52,102,111,11,99, + 112,117,99,56,54,95,54,52,102,111,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11, + 111,119,95,115,117,98,102,111,99,117,115,13,111,119,95,109,111,117,115,101, + 119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,9,111,119,95,104,105,110,116,111,110,0,8,98,111,117,110,100, + 115,95,120,3,183,0,8,98,111,117,110,100,115,95,121,2,113,9,98,111, + 117,110,100,115,95,99,120,3,96,1,9,98,111,117,110,100,115,95,99,121, + 3,21,1,18,99,111,110,116,97,105,110,101,114,46,111,110,108,97,121,111, + 117,116,7,18,99,112,117,102,111,111,110,99,104,105,108,100,115,99,97,108, + 101,100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1, + 2,0,2,0,3,86,1,3,21,1,0,7,99,97,112,116,105,111,110,6, + 10,67,80,85,32,88,54,56,95,54,52,8,111,110,108,97,121,111,117,116, + 7,18,99,112,117,102,111,111,110,99,104,105,108,100,115,99,97,108,101,100, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,6,116,99, + 112,117,102,111,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,2, + 111,110,8,98,111,117,110,100,115,95,120,3,215,0,8,98,111,117,110,100, + 115,95,121,2,1,0,0,241,13,116,100,97,116,101,116,105,109,101,100,105, + 115,112,8,115,116,111,112,116,105,109,101,8,98,111,117,110,100,115,95,120, + 2,248,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,141,0,0,0,242,2,2,7,116,115,112,97,99,101,114,8, + 116,115,112,97,99,101,114,49,8,116,97,98,111,114,100,101,114,2,2,7, + 118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,18,9,98,111,117,110,100,115,95,99,120, + 3,85,1,9,98,111,117,110,100,115,95,99,121,3,249,0,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101, + 120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,7, + 108,105,110,107,116,111,112,7,8,115,116,111,112,116,105,109,101,0,10,116, + 105,110,116,54,52,101,100,105,116,3,114,49,52,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,3,114,49,52,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114, + 105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,24,2,0,0,8,98,111, + 117,110,100,115,95,120,3,176,0,8,98,111,117,110,100,115,95,121,3,208, + 0,9,98,111,117,110,100,115,95,99,120,3,165,0,11,102,111,110,116,46, + 104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9, + 115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,10,116,105,110,116,54,52, + 101,100,105,116,3,114,49,51,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,3,114,49,51,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,24,2,0,0,8,116,97,98,111,114,100,101, + 114,2,1,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110, + 100,115,95,121,3,187,0,9,98,111,117,110,100,115,95,99,120,3,165,0, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,10, + 116,105,110,116,54,52,101,100,105,116,3,114,49,50,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,114,49,50,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,24,2,0,0,8,116, + 97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,176, + 0,8,98,111,117,110,100,115,95,121,3,166,0,9,98,111,117,110,100,115, + 95,99,120,3,165,0,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,10,116,105,110,116,54,52,101,100,105,116,3,114,49,49, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 3,114,49,49,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 24,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110, + 100,115,95,120,3,176,0,8,98,111,117,110,100,115,95,121,3,145,0,9, + 98,111,117,110,100,115,95,99,120,3,165,0,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,10,116,105,110,116,54,52,101,100, + 105,116,3,114,49,48,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,3,114,49,48,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,0,2,24,2,0,0,8,116,97,98,111,114,100,101,114,2, + 4,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110,100,115, + 95,121,2,124,9,98,111,117,110,100,115,95,99,120,3,165,0,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,10,116,105,110, + 116,54,52,101,100,105,116,3,114,49,53,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,114,49,53,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,24,2,0,0,8,116,97,98,111, + 114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,176,0,8,98, + 111,117,110,100,115,95,121,3,229,0,9,98,111,117,110,100,115,95,99,120, + 3,165,0,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,10,116,105,110,116,54,52,101,100,105,116,2,114,57,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,57,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,16,2,0,0,8, + 116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,3,229,0,9,98,111,117,110,100,115, + 95,99,120,3,157,0,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,10,116,105,110,116,54,52,101,100,105,116,2,114,56,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2, + 114,56,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,16,2, + 0,0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,3,208,0,9,98,111,117, + 110,100,115,95,99,120,3,157,0,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,2,105,111,3,84,97,103,2,12,5,99,111,108,111,114,4,3,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,73,79,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,1,2,17,2,2,2,0,0,8,116,97,98,111, + 114,100,101,114,2,8,8,98,111,117,110,100,115,95,120,2,57,8,98,111, + 117,110,100,115,95,121,2,9,9,98,111,117,110,100,115,95,99,120,2,14, + 9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97, + 108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,2,110,116,3,84,97,103,2, + 15,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,2,78,84,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,3,2, + 17,2,4,2,0,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111, + 117,110,100,115,95,120,2,37,8,98,111,117,110,100,115,95,121,2,9,9, + 98,111,117,110,100,115,95,99,120,2,18,9,98,111,117,110,100,115,95,99, + 121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103, + 115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,1,99,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,67,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,10, + 8,98,111,117,110,100,115,95,120,3,161,0,8,98,111,117,110,100,115,95, + 121,2,9,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12, + 102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,1,112,3,84,97,103,2,2,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 80,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,11,8,98,111,117,110,100,115,95,120,3, + 150,0,8,98,111,117,110,100,115,95,121,2,9,9,98,111,117,110,100,115, + 95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110, + 115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108, + 117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,1,97,3, + 84,97,103,2,4,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,65,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,12, + 8,98,111,117,110,100,115,95,120,3,139,0,8,98,111,117,110,100,115,95, + 121,2,9,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12, + 102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,1,122,3,84,97,103,2,6,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 90,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,13,8,98,111,117,110,100,115,95,120,3, + 128,0,8,98,111,117,110,100,115,95,121,2,9,9,98,111,117,110,100,115, + 95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110, + 115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108, + 117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,1,115,3, + 84,97,103,2,7,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,83,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,14, + 8,98,111,117,110,100,115,95,120,2,117,8,98,111,117,110,100,115,95,121, + 2,9,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100, + 115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102, + 108,97,103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,1,116,3,84,97,103,2,8,5,99,111,108,111,114, + 4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,84, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99, + 112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116, + 97,98,111,114,100,101,114,2,15,8,98,111,117,110,100,115,95,120,2,106, + 8,98,111,117,110,100,115,95,121,2,9,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101, + 116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,1,105,3,84,97, + 103,2,9,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,73,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,16,8,98, + 111,117,110,100,115,95,120,2,95,8,98,111,117,110,100,115,95,121,2,9, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97, + 103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,1,100,3,84,97,103,2,10,5,99,111,108,111,114,4,3, + 0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,68,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98, + 111,114,100,101,114,2,17,8,98,111,117,110,100,115,95,120,2,84,8,98, + 111,117,110,100,115,95,121,2,9,9,98,111,117,110,100,115,95,99,120,2, + 11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118, + 97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,1,111,3,84,97,103,2, + 11,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,79,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,18,8,98,111,117, + 110,100,115,95,120,2,73,8,98,111,117,110,100,115,95,121,2,9,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115, + 101,116,118,97,108,117,101,0,0,10,116,105,110,116,54,52,101,100,105,116, + 6,101,102,108,97,103,115,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,3,114,102,108,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,15,2,0,0,8,116,97,98,111,114,100,101,114, + 2,19,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110,100, + 115,95,121,2,40,9,98,111,117,110,100,115,95,99,120,3,155,0,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,8,111,110,99, + 104,97,110,103,101,7,12,102,108,97,103,111,110,99,104,97,110,103,101,10, + 111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97, + 108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 10,116,105,110,116,54,52,101,100,105,116,3,114,105,112,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,114,105,112,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19,2,0,0,8, + 116,97,98,111,114,100,101,114,2,20,8,98,111,117,110,100,115,95,120,3, + 176,0,8,98,111,117,110,100,115,95,121,2,82,9,98,111,117,110,100,115, + 95,99,120,3,159,0,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,10,116,105,110,116,54,52,101,100,105,116,3,114,115,112, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 3,114,115,112,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 23,2,0,0,8,116,97,98,111,114,100,101,114,2,21,8,98,111,117,110, + 100,115,95,120,3,176,0,8,98,111,117,110,100,115,95,121,2,61,9,98, + 111,117,110,100,115,95,99,120,3,163,0,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,10,116,105,110,116,54,52,101,100,105, + 116,3,114,98,112,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,3,114,98,112,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,24,2,0,0,8,116,97,98,111,114,100,101,114,2,22, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,124,9,98,111,117,110,100,115,95,99,120,3,165,0,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,10,116,105,110,116,54, + 52,101,100,105,116,3,114,100,105,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,3,114,100,105,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100, + 101,114,2,23,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,3,166,0,9,98,111,117,110,100,115,95,99,120,3,160,0, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,10, + 116,105,110,116,54,52,101,100,105,116,3,114,115,105,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,114,115,105,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,18,2,0,0,8,116, + 97,98,111,114,100,101,114,2,24,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,3,145,0,9,98,111,117,110,100,115,95, + 99,120,3,159,0,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,16,0,0,10,116,105,110,116,54,52,101,100,105,116,3,114,100,120,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3, + 114,100,120,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,22, + 2,0,0,8,116,97,98,111,114,100,101,114,2,25,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,103,9,98,111,117, + 110,100,115,95,99,120,3,163,0,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,10,116,105,110,116,54,52,101,100,105,116,3, + 114,99,120,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,3,114,99,120,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,21,2,0,0,8,116,97,98,111,114,100,101,114,2,26,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,82, + 9,98,111,117,110,100,115,95,99,120,3,162,0,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,16,0,0,10,116,105,110,116,54,52,101, + 100,105,116,3,114,98,120,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,3,114,98,120,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,22,2,0,0,8,116,97,98,111,114,100,101,114, + 2,27,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,61,9,98,111,117,110,100,115,95,99,120,3,163,0,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,10,116,105,110, + 116,54,52,101,100,105,116,3,114,97,120,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,114,97,120,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,22,2,0,0,8,116,97,98,111, + 114,100,101,114,2,28,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,40,9,98,111,117,110,100,115,95,99,120,3,163, + 0,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116, + 46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110, + 116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10, + 111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97, + 108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,1,114,3,84,97,103,2, + 16,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,82,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,29,8,98,111,117, + 110,100,115,95,120,2,23,8,98,111,117,110,100,115,95,121,2,9,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115, + 101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,1,118,3,84,97,103,2,17,5,99,111,108,111,114,4,3,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,86,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,30,8,98,111,117,110,100,115,95,120,2,7,8,98,111,117, + 110,100,115,95,121,2,9,9,98,111,117,110,100,115,95,99,120,2,11,9, + 98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108, + 117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpux86_64fo,''); +end. diff --git a/mseide-msegui/apps/ide/debuggerform.mfm b/mseide-msegui/apps/ide/debuggerform.mfm new file mode 100644 index 0000000..08dcc10 --- /dev/null +++ b/mseide-msegui/apps/ide/debuggerform.mfm @@ -0,0 +1,164 @@ +object debuggerfo: tdebuggerfo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 116 + bounds_y = 131 + bounds_cx = 441 + bounds_cy = 100 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 431 + 100 + ) + dragdock.caption = 'Debugger' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_proportional, od_propsize, od_captionhint] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + icon.image = { + 00000000000000001800000018000000D4080000000000000000000000000000 + 0000000000000000000000000000000000000000E6E6E601E5E5E501E4E4E401 + E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01DDDDDD01DCDCDC01 + DBDBDB02DADADA01D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401 + D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301 + E2E2E201D7DED701E0E0E001DFDFDF01DEDEDE01DDDDDD01DCDCDC01DBDBDB02 + DADADA01D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301 + D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301E2E2E201 + 22B52701C1D9C201DFDFDF01DEDEDE01DDDDDD01DCDCDC01DBDBDB02DADADA01 + D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201 + D1D1D101D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301E2E2E20122C42101 + 2BC62A019CD09D01DEDEDE01DDDDDD01DCDCDC01DBDBDB02DADADA01D9D9D901 + D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101 + D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E61501 + 27C9220171C67401DDDDDD01DCDCDC01DBDBDB02DADADA01D9D9D901D8D8D801 + D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001 + E6E6E601E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E82301 + 34D72B014EBD5201D6DAD601DBDBDB02DADADA01D9D9D901D8D8D801D7D7D701 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 45E53B013DBD3F01C4D4C501DBDBDB01DADADA01D9D9D901D8D8D801D7D7D701 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED410158ED4D013BC03C01A7CFA901DADADA01D9D9D901D8D8D801D7D7D701 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0148CA470183C78501D9D9D901D8D8D801D7D7D701 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C0161DB5B0161C06401D4D6D401D7D7D701 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C0184F67A017CEB76014EBD5101C7D2C801 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C0184F67A0191F8890197F68F014FC15201 + AECCAF01D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C0184F67A0191F8890197F68F0142B44501 + 809E8101D0D0D001D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C0184F67A017CEB760137A63A015B665C01 + 67676701A4A4A401D2D2D201D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C015FD9590139983C016163610166666601 + 99999901D0D0D001D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0142C4410143874501626262016C6C6C01ADADAD01 + D2D2D201D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED410158ED4D0130B531014F7751016464640176767601BDBDBD01D5D5D501 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 45E53B0129A92B015A6A5B016666660184848401CACACA01D7D7D702D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501 + E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230133D62A012C9B3001 + 616561016767670197979701D3D3D301D9D9D901D8D8D801D7D7D701D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501 + E4E4E401E3E3E301E2E2E20123C6220125E6150123C51E01388D3B0164646401 + 6B6B6B01AAAAAA01D7D7D701DADADA01D9D9D901D8D8D801D7D7D701D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501 + E4E4E401E3E3E301E2E2E20122C4210127C226014B7F4C016666660174747401 + BDBDBD01D8D8D801DBDBDB01DADADA01D9D9D901D8D8D801D7D7D701D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501 + E4E4E401E3E3E301E2E2E20122B52701A5BDA6016A6A6A0182828201CACACA01 + DBDBDB03DADADA01D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401 + D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301 + E2E2E201D6DDD601C2C2C20196969601D5D5D501DDDDDD01DCDCDC01DBDBDB02 + DADADA01D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301 + D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301E2E2E201 + E1E1E101DBDBDB01DCDCDC01DEDEDE01DDDDDD01DCDCDC01DBDBDB02DADADA01 + D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201 + D1D1D101D0D0D001 + } + moduleclassname = 'tdockform' + object gdbtoolbar: ttoolbar + optionswidget = [ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets, ow_timedhint] + color = -2147483645 + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 431 + bounds_cy = 100 + anchors = [] + buttons.count = 13 + buttons.width = 24 + buttons.height = 24 + buttons.items = < + item + action = actionsmo.reset + end + item + action = actionsmo.interrupt + end + item + action = actionsmo.continue + end + item + action = actionsmo.next + end + item + action = actionsmo.step + end + item + action = actionsmo.finish + end + item + options = [mao_separator] + end + item + hint = 'Next instruction' + action = actionsmo.nexti + state = [as_localhint] + end + item + hint = 'Step instruction' + action = actionsmo.stepi + state = [as_localhint] + end + item + options = [mao_separator] + end + item + action = actionsmo.bkptsonact + state = [as_checked] + options = [mao_checkbox] + end + item + action = actionsmo.watchesonact + state = [as_checked] + options = [mao_checkbox] + end + item + action = actionsmo.bluedotsonact + state = [as_checked] + options = [mao_checkbox] + end> + options = [tbo_dragsourceenabledonly, tbo_dragdestenabledonly] + end +end diff --git a/mseide-msegui/apps/ide/debuggerform.pas b/mseide-msegui/apps/ide/debuggerform.pas new file mode 100644 index 0000000..7b57cf3 --- /dev/null +++ b/mseide-msegui/apps/ide/debuggerform.pas @@ -0,0 +1,33 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit debuggerform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms; + +type + tdebuggerfo = class(tdockform) + end; +var + debuggerfo: tdebuggerfo; +implementation +uses + debuggerform_mfm; +end. diff --git a/mseide-msegui/apps/ide/debuggerform_mfm.pas b/mseide-msegui/apps/ide/debuggerform_mfm.pas new file mode 100644 index 0000000..2a366b7 --- /dev/null +++ b/mseide-msegui/apps/ide/debuggerform_mfm.pas @@ -0,0 +1,211 @@ +unit debuggerform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,debuggerform; + +const + objdata: record size: integer; data: array[0..3861] of byte end = + (size: 3862; data: ( + 84,80,70,48,11,116,100,101,98,117,103,103,101,114,102,111,10,100,101,98, + 117,103,103,101,114,102,111,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105, + 122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105, + 111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16, + 103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95, + 102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117, + 116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117, + 116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110, + 14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,116,8,98,111,117, + 110,100,115,95,121,3,131,0,9,98,111,117,110,100,115,95,99,120,3,185, + 1,9,98,111,117,110,100,115,95,99,121,2,100,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110, + 101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,175,1,2,100,0, + 16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111,110,6,8,68, + 101,98,117,103,103,101,114,20,100,114,97,103,100,111,99,107,46,111,112,116, + 105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112,111,115, + 13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95,99,97, + 110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100, + 95,99,97,110,100,111,99,107,15,111,100,95,112,114,111,112,111,114,116,105, + 111,110,97,108,11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95, + 99,97,112,116,105,111,110,104,105,110,116,0,7,111,112,116,105,111,110,115, + 11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101, + 122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0, + 8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114, + 111,106,101,99,116,115,116,97,116,102,105,108,101,10,105,99,111,110,46,105, + 109,97,103,101,10,8,9,0,0,0,0,0,0,0,0,0,0,24,0,0, + 0,24,0,0,0,212,8,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,2,218,218,218,1,217,217,217,1,216,216,216, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,215,222,215,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 2,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214, + 1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209, + 1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,34,181,39,1,193,217,194,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,2,218,218,218,1,217,217,217, + 1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,34,196,33, + 1,43,198,42,1,156,208,157,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,2,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21,1,39,201,34, + 1,113,198,116,1,221,221,221,1,220,220,220,1,219,219,219,2,218,218,218, + 1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,35,198,34,1,37,230,21,1,50,232,35,1,52,215,43,1,78,189,82, + 1,214,218,214,1,219,219,219,2,218,218,218,1,217,217,217,1,216,216,216, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21, + 1,50,232,35,1,64,234,50,1,69,229,59,1,61,189,63,1,196,212,197, + 1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21,1,50,232,35, + 1,64,234,50,1,78,237,65,1,88,237,77,1,59,192,60,1,167,207,169, + 1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214, + 1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209, + 1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,35,198,34,1,37,230,21,1,50,232,35,1,64,234,50, + 1,78,237,65,1,91,239,79,1,105,241,93,1,72,202,71,1,131,199,133, + 1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,35,198,34,1,37,230,21,1,50,232,35,1,64,234,50,1,78,237,65, + 1,91,239,79,1,105,241,93,1,118,244,108,1,97,219,91,1,97,192,100, + 1,212,214,212,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34, + 1,37,230,21,1,50,232,35,1,64,234,50,1,78,237,65,1,91,239,79, + 1,105,241,93,1,118,244,108,1,132,246,122,1,124,235,118,1,78,189,81, + 1,199,210,200,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21, + 1,50,232,35,1,64,234,50,1,78,237,65,1,91,239,79,1,105,241,93, + 1,118,244,108,1,132,246,122,1,145,248,137,1,151,246,143,1,79,193,82, + 1,174,204,175,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21,1,50,232,35, + 1,64,234,50,1,78,237,65,1,91,239,79,1,105,241,93,1,118,244,108, + 1,132,246,122,1,145,248,137,1,151,246,143,1,66,180,69,1,128,158,129, + 1,208,208,208,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209, + 1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,35,198,34,1,37,230,21,1,50,232,35,1,64,234,50, + 1,78,237,65,1,91,239,79,1,105,241,93,1,118,244,108,1,132,246,122, + 1,124,235,118,1,55,166,58,1,91,102,92,1,103,103,103,1,164,164,164, + 1,210,210,210,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,35,198,34,1,37,230,21,1,50,232,35,1,64,234,50,1,78,237,65, + 1,91,239,79,1,105,241,93,1,118,244,108,1,95,217,89,1,57,152,60, + 1,97,99,97,1,102,102,102,1,153,153,153,1,208,208,208,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34, + 1,37,230,21,1,50,232,35,1,64,234,50,1,78,237,65,1,91,239,79, + 1,105,241,93,1,66,196,65,1,67,135,69,1,98,98,98,1,108,108,108, + 1,173,173,173,1,210,210,210,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21, + 1,50,232,35,1,64,234,50,1,78,237,65,1,88,237,77,1,48,181,49, + 1,79,119,81,1,100,100,100,1,118,118,118,1,189,189,189,1,213,213,213, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21,1,50,232,35, + 1,64,234,50,1,69,229,59,1,41,169,43,1,90,106,91,1,102,102,102, + 1,132,132,132,1,202,202,202,1,215,215,215,2,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,35,198,34,1,37,230,21,1,50,232,35,1,51,214,42,1,44,155,48, + 1,97,101,97,1,103,103,103,1,151,151,151,1,211,211,211,1,217,217,217, + 1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34, + 1,37,230,21,1,35,197,30,1,56,141,59,1,100,100,100,1,107,107,107, + 1,170,170,170,1,215,215,215,1,218,218,218,1,217,217,217,1,216,216,216, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,34,196,33,1,39,194,38, + 1,75,127,76,1,102,102,102,1,116,116,116,1,189,189,189,1,216,216,216, + 1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,34,181,39,1,165,189,166,1,106,106,106, + 1,130,130,130,1,202,202,202,1,219,219,219,3,218,218,218,1,217,217,217, + 1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,214,221,214, + 1,194,194,194,1,150,150,150,1,213,213,213,1,221,221,221,1,220,220,220, + 1,219,219,219,2,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,219,219,219,1,220,220,220, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,2,218,218,218, + 1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9,116, + 100,111,99,107,102,111,114,109,0,8,116,116,111,111,108,98,97,114,10,103, + 100,98,116,111,111,108,98,97,114,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,12,111,119,95,116, + 105,109,101,100,104,105,110,116,0,5,99,111,108,111,114,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,175,1,9,98,111,117,110,100, + 115,95,99,121,2,100,7,97,110,99,104,111,114,115,11,0,13,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,13,13,98,117,116,116,111,110,115, + 46,119,105,100,116,104,2,24,14,98,117,116,116,111,110,115,46,104,101,105, + 103,104,116,2,24,13,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,6,97,99,116,105,111,110,7,15,97,99,116,105,111,110,115,109,111,46, + 114,101,115,101,116,0,1,6,97,99,116,105,111,110,7,19,97,99,116,105, + 111,110,115,109,111,46,105,110,116,101,114,114,117,112,116,0,1,6,97,99, + 116,105,111,110,7,18,97,99,116,105,111,110,115,109,111,46,99,111,110,116, + 105,110,117,101,0,1,6,97,99,116,105,111,110,7,14,97,99,116,105,111, + 110,115,109,111,46,110,101,120,116,0,1,6,97,99,116,105,111,110,7,14, + 97,99,116,105,111,110,115,109,111,46,115,116,101,112,0,1,6,97,99,116, + 105,111,110,7,16,97,99,116,105,111,110,115,109,111,46,102,105,110,105,115, + 104,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112, + 97,114,97,116,111,114,0,0,1,4,104,105,110,116,6,16,78,101,120,116, + 32,105,110,115,116,114,117,99,116,105,111,110,6,97,99,116,105,111,110,7, + 15,97,99,116,105,111,110,115,109,111,46,110,101,120,116,105,5,115,116,97, + 116,101,11,12,97,115,95,108,111,99,97,108,104,105,110,116,0,0,1,4, + 104,105,110,116,6,16,83,116,101,112,32,105,110,115,116,114,117,99,116,105, + 111,110,6,97,99,116,105,111,110,7,15,97,99,116,105,111,110,115,109,111, + 46,115,116,101,112,105,5,115,116,97,116,101,11,12,97,115,95,108,111,99, + 97,108,104,105,110,116,0,0,1,7,111,112,116,105,111,110,115,11,13,109, + 97,111,95,115,101,112,97,114,97,116,111,114,0,0,1,6,97,99,116,105, + 111,110,7,20,97,99,116,105,111,110,115,109,111,46,98,107,112,116,115,111, + 110,97,99,116,5,115,116,97,116,101,11,10,97,115,95,99,104,101,99,107, + 101,100,0,7,111,112,116,105,111,110,115,11,12,109,97,111,95,99,104,101, + 99,107,98,111,120,0,0,1,6,97,99,116,105,111,110,7,22,97,99,116, + 105,111,110,115,109,111,46,119,97,116,99,104,101,115,111,110,97,99,116,5, + 115,116,97,116,101,11,10,97,115,95,99,104,101,99,107,101,100,0,7,111, + 112,116,105,111,110,115,11,12,109,97,111,95,99,104,101,99,107,98,111,120, + 0,0,1,6,97,99,116,105,111,110,7,23,97,99,116,105,111,110,115,109, + 111,46,98,108,117,101,100,111,116,115,111,110,97,99,116,5,115,116,97,116, + 101,11,10,97,115,95,99,104,101,99,107,101,100,0,7,111,112,116,105,111, + 110,115,11,12,109,97,111,95,99,104,101,99,107,98,111,120,0,0,0,7, + 111,112,116,105,111,110,115,11,25,116,98,111,95,100,114,97,103,115,111,117, + 114,99,101,101,110,97,98,108,101,100,111,110,108,121,23,116,98,111,95,100, + 114,97,103,100,101,115,116,101,110,97,98,108,101,100,111,110,108,121,0,0, + 0,0) + ); + +initialization + registerobjectdata(@objdata,tdebuggerfo,''); +end. diff --git a/mseide-msegui/apps/ide/disassform.mfm b/mseide-msegui/apps/ide/disassform.mfm new file mode 100644 index 0000000..5b7df81 --- /dev/null +++ b/mseide-msegui/apps/ide/disassform.mfm @@ -0,0 +1,166 @@ +object disassfo: tdisassfo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + onactivate = act + ondeactivate = deact + visible = False + bounds_x = 162 + bounds_y = 502 + bounds_cx = 564 + bounds_cy = 210 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 554 + 210 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Assembler' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Assembler' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 00000000020000001800000018000000F4060000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D0198888880D82888801 + 88888801D0D0D00988888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01 + C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE017F878701 + 9FC5C80188888801D0D0D00888888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01 + BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01 + 83898A01C6F9FF019EC5C80188888801D0D0D00788888801B3F8FE01B6F8FE01 + B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01 + D2FEFE01D5FEFE01858A8A01E2FCFF01C5F9FF019EC5C80188888801D0D0D006 + 88888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01 + C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE0182898A01FEFEFF01E1FCFF01 + C3F9FF019EC5C80188888801D0D0D00588888801B3F8FE01B6F8FE01B9F9FE01 + BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01 + D5FEFE017F898A01DFFCFF01FCFEFF01DFFCFF01C2F9FF019DC4C80188888801 + D0D0D00488888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01 + C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE017C898A01BEF9FF01 + E1FCFF01FAFEFF01DDFCFF01C0F9FF019DC4C80188888801D0D0D00388888801 + B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01 + CCFDFE01CFFDFE01D2FEFE01D5FEFE0179898A019EF6FF01C0F9FF01E3FCFF01 + F9FEFF01DCFBFF01BEF9FF019DC4C80188888801D0D0D00288888801B3F8FE01 + B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01 + CFFDFE01D2FEFE01D5FEFE018296970178898A017A898A017C898A017E898A02 + 7A898A017786870181888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01 + BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01 + D5FEFE01CEFDFE01BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE01 + 66F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01 + BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01 + CEFDFE01BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE01 + 88888801D0D0D00288888801B3F8FE01B6F8FE01AFEBF0015774760137494A01 + 7DA1A301C6FBFE01C9FCFE01CCFDFE01C6F2F30149595901D5FEFE01CEFDFE01 + BFFCFE016D9B9D01314B4D01426F730180EDF70175F3FE0166F1FE0188888801 + D0D0D00288888801B3F8FE01B6F8FE014D686A0162828401AADFE2012A363701 + 9DC7C901C9FCFE01ADD6D701323D3D010D101001D5FEFE01CEFDFE018EBCBD01 + 2C3F400194E3E801447276013D71760175F3FE0166F1FE0188888801D0D0D002 + 88888801B3F8FE01B6F8FE01141A1B01A7DEE101BFFAFE01638081015E777901 + C9FCFE015E7576019DC0C1011A1F1F01D5FEFE01CEFDFE01546F7001618A8C01 + A2F8FE017CCFD6011322240175F3FE0166F1FE0188888801D0D0D00288888801 + B3F8FE01B2F3F90110151601BCFAFE01BFFAFE0184AAAC01475A5B01C9FCFE01 + CCFDFE01CFFDFE011A1F1F01D5FEFE01CEFDFE013D50510183BABD01A2F8FE01 + 91F2FA01070D0E0175F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01 + B3F4FA010C101001BCFAFE01BFFAFE017EA2A4014E626401C9FCFE01CCFDFE01 + CFFDFE011A1F1F01D5FEFE01CEFDFE013D51520180B5B801A2F8FE018EEEF601 + 0911120175F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01 + 11171801A7DFE201BFFAFE015D787A0168848501C9FCFE01CCFDFE01CFFDFE01 + 1A1F1F01D5FEFE01CEFDFE01526C6D01628B8D01A2F8FE0177C8CE01192F3101 + 75F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE015B7A7D01 + 4B6466018DB8BB01242E2F01ADDCDE01C9FCFE01CCFDFE01CFFDFE011A1F1F01 + D5FEFE01CEFDFE019ACCCD01243334017ABBBF01315255014E90960175F3FE01 + 66F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE018CBABD01 + 5B7779019DCBCD01C6FBFE01C9FCFE01CCFDFE01CFFDFE01768E8E01D5FEFE01 + CEFDFE01BFFCFE019BDCDF014F7A7D0161A3A80183F3FD0175F3FE0166F1FE01 + 88888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01 + C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01CEFDFE01 + BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE0188888801 + D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01 + C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01CEFDFE01BFFCFE01 + B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE0188888801D0D0D002 + 88888816D0D0D01900000008FEFF0008FEFF01BFFEFF0308FEFF0700FEFF0F08 + FEFF1F02FEFF3FC0FEFF7F00FEFF7F08FEFF7F00FEFF7F08FEFF7F08FEFF7F08 + FEFF7FBFFEFF7F08FEFF7F00FEFF7F02FEFF7F08FEFF7F00FEFF7F00FEFF7FBF + FEFF7F0000000008 + } + onshow = disassfoonshow + moduleclassname = 'tdockform' + object grid: tstringgrid + color = -1879048187 + frame.sbvert.options = [sbo_thumbtrack, sbo_show] + frame.localprops = [] + frame.localprops1 = [] + popupmenu = popupmen + bounds_x = 0 + bounds_y = 0 + bounds_cx = 554 + bounds_cy = 210 + anchors = [] + onkeydown = keydo + optionsgrid = [og_colsizing, og_colchangeontabkey, og_wrapcol, og_autopopup] + datacols.count = 4 + datacols.options = [co_readonly, co_drawfocus, co_savestate] + datacols.items = < + item + width = 76 + onbeforedrawcell = befdrawcell + options = [co_readonly, co_drawfocus, co_savestate] + oncellevent = addrcellevent + textflags = [tf_right, tf_ycentered, tf_noselect] + textflagsactive = [tf_right, tf_ycentered] + optionsedit = [scoe_eatreturn, scoe_hintclippedtext] + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + valuefalse = '0' + valuetrue = '1' + end + item + width = 355 + options = [co_readonly, co_drawfocus, co_fill, co_savestate] + textflags = [tf_ycentered, tf_noselect, tf_tabtospace] + textflagsactive = [tf_ycentered, tf_tabtospace] + optionsedit = [scoe_eatreturn, scoe_hintclippedtext] + valuefalse = '0' + valuetrue = '1' + end + item + options = [co_readonly, co_invisible, co_drawfocus, co_savestate] + valuefalse = '0' + valuetrue = '1' + end + item + options = [co_readonly, co_invisible, co_drawfocus, co_savestate] + valuefalse = '0' + valuetrue = '1' + end> + rowcolors.count = 2 + rowcolors.items = ( + 14745599 + 16777184 + ) + datarowheight = 16 + onscrollrows = scrollrows + oncellevent = celleventexe + reffontheight = 13 + end + object popupmen: tpopupmenu + onupdate = popupupdate + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Show &Breakpoint' + name = 'showbreak' + state = [as_localcaption, as_localonexecute] + onexecute = showbreakexe + end> + left = 120 + top = 24 + end +end diff --git a/mseide-msegui/apps/ide/disassform.pas b/mseide-msegui/apps/ide/disassform.pas new file mode 100644 index 0000000..1c65cf9 --- /dev/null +++ b/mseide-msegui/apps/ide/disassform.pas @@ -0,0 +1,339 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit disassform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,msegdbutils,msegrids,msetypes,msestrings,mseevent, + msegraphics,mseguiglob,msemenus; + +type + tdisassfo = class(tdockform) + grid: tstringgrid; + popupmen: tpopupmenu; + procedure disassfoonshow(const sender: TObject); + procedure keydo(const sender: twidget; var info: keyeventinfoty); + procedure deact(const sender: TObject); + procedure act(const sender: TObject); + procedure befdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure addrcellevent(const sender: TObject; var info: celleventinfoty); + procedure scrollrows(const sender: tcustomgrid; var step: Integer); + procedure celleventexe(const sender: TObject; var info: celleventinfoty); + procedure popupupdate(const sender: tcustommenu); + procedure showbreakexe(const sender: TObject); + private + faddress: qword; + ffirstaddress: qword; + flastaddress: qword; + factiverow: integer; + fshortcutsswapped: boolean; + procedure swapshortcuts; + procedure internalrefresh; + procedure addlines(const aaddress: qword; const alinecount: integer); + procedure addpreviouslines(const asetrow: boolean); + public + gdb: tgdbmi; + procedure refresh(const addr: qword); + procedure clear; + procedure resetactiverow; + procedure resetshortcuts; + end; + +var + disassfo: tdisassfo; + +implementation + +uses + disassform_mfm,sourceform,sourcepage,mseformatstr,sysutils,msekeyboard,mseglob, + actionsmodule,breakpointsform,msegraphutils,mseeditglob,msegridsglob; + +{ tdisassfo } + +procedure tdisassfo.disassfoonshow(const sender: TObject); +begin + internalrefresh; +end; + +procedure tdisassfo.clear; +begin + grid.clear; +end; + +procedure tdisassfo.addlines(const aaddress: qword; const alinecount: integer); +var + ar1: asmlinearty; + int1,int2: integer; + apage: tsourcepage; + aline: integer; + start,stop: qword; + fname1: filenamety; + ca1,ca2: qword; + endrow: integer; + digits: integer; + +begin + int2:= grid.rowcount; + endrow:= int2 + alinecount; + digits:= gdb.pointerhexdigits; + if gdb.infoline(aaddress,fname1,aline,start,stop) <> gdb_ok then begin + start:= aaddress; + stop:= aaddress + $100; + aline:= 0; + end; + if start < ffirstaddress then begin + ffirstaddress:= start; + end; + grid.beginupdate; + try + while int2 < endrow do begin + flastaddress:= stop; + if gdb.disassemble(ar1,start,stop) = gdb_ok then begin + if aline > 0 then begin + apage:= sourcefo.openfile(fname1); + grid.rowcount:= int2 + 1 + length(ar1); + grid[3][int2]:= inttostrmse(aline-1); + if (apage <> nil) and (aline > 0) and + (aline <= apage.grid.rowcount) then begin + grid[1][int2]:= apage.edit[aline-1]; + grid[2][int2]:= fname1; + end + else begin + grid[1][int2]:= ''; + end; + grid.rowcolorstate[int2]:= 1; + inc(int2); + end + else begin + grid.rowcount:= int2 + length(ar1); + end; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + grid[0][int2]:= hextostrmse(address,digits); + grid[1][int2]:= msestring(instruction); + if address = faddress then begin + factiverow:= int2; + grid.rowcolorstate[int2]:= 0; + end; + end; + inc(int2); + end; + if gdb.infoline(stop,fname1,aline,ca1,ca2) = gdb_ok then begin + start:= ca1; + stop:= ca2; + end + else begin + break; + end; + end + else begin + break; + end; + end; + if (factiverow >= 0) and (factiverow <= grid.rowcount) then begin + grid.showcell(makegridcoord(invalidaxis,factiverow)); + end; + finally + grid.endupdate; + end; +end; + +procedure tdisassfo.internalrefresh; +begin + if showing and gdb.cancommand then begin + grid.beginupdate; + try + grid.rowcount:= 0; + addlines(faddress,grid.rowsperpage); + finally + grid.endupdate; + end; + end; +end; + +procedure tdisassfo.refresh(const addr: qword); +begin + ffirstaddress:= not qword(0); + faddress:= addr; + internalrefresh; +end; + +procedure tdisassfo.resetactiverow; +begin + if (factiverow < grid.rowcount) then begin + grid.rowcolorstate[factiverow]:= -1; + end; +end; + +procedure tdisassfo.addpreviouslines(const asetrow: boolean); +var + rowcountbefore,rowbefore,activerowbefore{,firstvisiblerowbefore}: integer; +// int1: integer; +begin + with grid do begin + rowcountbefore:= rowcount; +// firstvisiblerowbefore:= firstvisiblerow; + rowbefore:= row; + activerowbefore:= factiverow; + clear; + addlines((ffirstaddress and not qword($7))-$40,rowcountbefore+$48); + if asetrow then begin + row:= rowbefore + factiverow - activerowbefore; + end + else begin + showcell(makegridcoord(col,factiverow-activerowbefore),cep_top,true); + end; + end; +end; + +procedure tdisassfo.scrollrows(const sender: tcustomgrid; var step: Integer); +begin + if (step > 0) then begin + if sender.firstvisiblerow = 0 then begin + addpreviouslines(false); + end; + end + else begin + if sender.lastvisiblerow = sender.rowhigh then begin + addlines(flastaddress,grid.rowsperpage); + end; + end; +end; + +procedure tdisassfo.keydo(const sender: twidget; var info: keyeventinfoty); +begin + if visible and gdb.cancommand then begin + with grid,info do begin + if (shiftstate = []) then begin + if ((key = key_down) or (key = key_pagedown)) and (row = rowhigh) then begin + addlines(flastaddress,grid.rowsperpage); + end + else begin + if ((key = key_up) or (key = key_pageup)) and (row = 0) then begin + addpreviouslines(true); + showcell(focusedcell,cep_top); + end; + end; + end; + end; + end; +end; + +procedure tdisassfo.swapshortcuts; +var + sho1: shortcutty; +begin + with actionsmo do begin + sho1:= step.shortcut; + step.shortcut:= stepi.shortcut; + stepi.shortcut:= sho1; + sho1:= next.shortcut; + next.shortcut:= nexti.shortcut; + nexti.shortcut:= sho1; + end; +end; + +procedure tdisassfo.resetshortcuts; +begin + if fshortcutsswapped then begin + swapshortcuts; + fshortcutsswapped:= false; + end; +end; + +procedure tdisassfo.deact(const sender: TObject); +begin + if (application.inactivewindow <> window) then begin + resetshortcuts; + end; +end; + +procedure tdisassfo.act(const sender: TObject); +begin + if not fshortcutsswapped then begin + swapshortcuts; + fshortcutsswapped:= true; + end; +end; + +procedure tdisassfo.befdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); +begin + with cellinfo do begin + if pmsestring(datapo)^ <> '' then begin + if breakpointsfo.isactivebreakpoint( + strtohex64(ansistring(pmsestring(datapo)^))) then begin + color:= cl_ltred; + end; + end; + end; +end; + +procedure tdisassfo.addrcellevent(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if iscellclick(info,[ccr_buttonpress,ccr_data]) then begin + breakpointsfo.toggleaddrbreakpoint( + strtohex64(ansistring(self.grid[cell.col][cell.row]))); + grid.invalidatecell(cell); + end; + end; +end; + +procedure tdisassfo.celleventexe(const sender: TObject; + var info: celleventinfoty); +var + int1: integer; +begin + if (info.cell.col = 1) and iscellclick(info,[ccr_dblclick]) then begin + int1:= info.cell.row; + if int1 >= 0 then begin + while (int1 >= 0) and (grid[2][int1] = '') do begin + dec(int1); + end; + if int1 < 0 then begin + int1:= info.cell.row; + while (int1 < grid.rowcount) and (grid[2][int1] = '') do begin + inc(int1); + end; + end; + if (int1 >= 0) and (int1 < grid.rowcount) then begin + sourcefo.showsourceline(grid[2][int1],strtoint64( + ansistring(grid[3][int1])),0,true); + end; + end; + end; +end; + +procedure tdisassfo.popupupdate(const sender: tcustommenu); +begin + popupmen.menu.itembyname('showbreak').enabled:= grid.focusedcellvalid and + (grid[0][grid.row] <> '') and + breakpointsfo.isactivebreakpoint(strtohex64(ansistring(grid[0][grid.row]))); +end; + +procedure tdisassfo.showbreakexe(const sender: TObject); +begin + breakpointsfo.showbreakpoint( + strtohex64(ansistring(self.grid[0][grid.row])),true); +end; + +end. diff --git a/mseide-msegui/apps/ide/disassform_mfm.pas b/mseide-msegui/apps/ide/disassform_mfm.pas new file mode 100644 index 0000000..adc185f --- /dev/null +++ b/mseide-msegui/apps/ide/disassform_mfm.pas @@ -0,0 +1,227 @@ +unit disassform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,disassform; + +const + objdata: record size: integer; data: array[0..4193] of byte end = + (size: 4194; data: ( + 84,80,70,48,9,116,100,105,115,97,115,115,102,111,8,100,105,115,97,115, + 115,102,111,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101,2,10, + 18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110,115,11, + 14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111,95,102, + 105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108,111,97, + 116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110, + 19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110, + 15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95, + 98,117,116,116,111,110,104,105,110,116,115,0,10,111,110,97,99,116,105,118, + 97,116,101,7,3,97,99,116,12,111,110,100,101,97,99,116,105,118,97,116, + 101,7,5,100,101,97,99,116,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,3,162,0,8,98,111,117,110,100,115,95,121,3,246, + 1,9,98,111,117,110,100,115,95,99,120,3,52,2,9,98,111,117,110,100, + 115,95,99,121,3,210,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,42,2,3,210,0,0,22,100,114,97,103, + 100,111,99,107,46,115,112,108,105,116,116,101,114,95,115,105,122,101,2,0, + 16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111,110,6,9,65, + 115,115,101,109,98,108,101,114,20,100,114,97,103,100,111,99,107,46,111,112, + 116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112,111, + 115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95,99, + 97,110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111, + 100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111,112,115,105,122, + 101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,13,111,100,95, + 99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105,111,110,115,11, + 10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122, + 111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8, + 115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111, + 106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112,116,105,111,110, + 6,9,65,115,115,101,109,98,108,101,114,21,105,99,111,110,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,12,105, + 99,111,110,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,0,10,105,99,111,110,46,105,109,97,103,101,10,136,7,0,0, + 0,0,0,0,2,0,0,0,24,0,0,0,24,0,0,0,244,6,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,25,136,136,136,13, + 130,136,136,1,136,136,136,1,208,208,208,9,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,127,135,135,1,159,197,200,1,136,136,136,1,208,208,208,8, + 136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1, + 191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253,254,1, + 207,253,254,1,210,254,254,1,213,254,254,1,131,137,138,1,198,249,255,1, + 158,197,200,1,136,136,136,1,208,208,208,7,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,133,138,138,1,226,252,255,1,197,249,255,1,158,197,200,1, + 136,136,136,1,208,208,208,6,136,136,136,1,179,248,254,1,182,248,254,1, + 185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1, + 201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1, + 130,137,138,1,254,254,255,1,225,252,255,1,195,249,255,1,158,197,200,1, + 136,136,136,1,208,208,208,5,136,136,136,1,179,248,254,1,182,248,254,1, + 185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1, + 201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1, + 127,137,138,1,223,252,255,1,252,254,255,1,223,252,255,1,194,249,255,1, + 157,196,200,1,136,136,136,1,208,208,208,4,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,124,137,138,1,190,249,255,1,225,252,255,1,250,254,255,1, + 221,252,255,1,192,249,255,1,157,196,200,1,136,136,136,1,208,208,208,3, + 136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1, + 191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253,254,1, + 207,253,254,1,210,254,254,1,213,254,254,1,121,137,138,1,158,246,255,1, + 192,249,255,1,227,252,255,1,249,254,255,1,220,251,255,1,190,249,255,1, + 157,196,200,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,130,150,151,1,120,137,138,1,122,137,138,1,124,137,138,1, + 126,137,138,2,122,137,138,1,119,134,135,1,129,136,136,1,208,208,208,2, + 136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1, + 191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253,254,1, + 207,253,254,1,210,254,254,1,213,254,254,1,206,253,254,1,191,252,254,1, + 176,250,254,1,162,248,254,1,147,246,254,1,132,244,254,1,117,243,254,1, + 102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,206,253,254,1,191,252,254,1,176,250,254,1,162,248,254,1, + 147,246,254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136,136,1, + 208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,175,235,240,1, + 87,116,118,1,55,73,74,1,125,161,163,1,198,251,254,1,201,252,254,1, + 204,253,254,1,198,242,243,1,73,89,89,1,213,254,254,1,206,253,254,1, + 191,252,254,1,109,155,157,1,49,75,77,1,66,111,115,1,128,237,247,1, + 117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1, + 179,248,254,1,182,248,254,1,77,104,106,1,98,130,132,1,170,223,226,1, + 42,54,55,1,157,199,201,1,201,252,254,1,173,214,215,1,50,61,61,1, + 13,16,16,1,213,254,254,1,206,253,254,1,142,188,189,1,44,63,64,1, + 148,227,232,1,68,114,118,1,61,113,118,1,117,243,254,1,102,241,254,1, + 136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1, + 20,26,27,1,167,222,225,1,191,250,254,1,99,128,129,1,94,119,121,1, + 201,252,254,1,94,117,118,1,157,192,193,1,26,31,31,1,213,254,254,1, + 206,253,254,1,84,111,112,1,97,138,140,1,162,248,254,1,124,207,214,1, + 19,34,36,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2, + 136,136,136,1,179,248,254,1,178,243,249,1,16,21,22,1,188,250,254,1, + 191,250,254,1,132,170,172,1,71,90,91,1,201,252,254,1,204,253,254,1, + 207,253,254,1,26,31,31,1,213,254,254,1,206,253,254,1,61,80,81,1, + 131,186,189,1,162,248,254,1,145,242,250,1,7,13,14,1,117,243,254,1, + 102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1, + 179,244,250,1,12,16,16,1,188,250,254,1,191,250,254,1,126,162,164,1, + 78,98,100,1,201,252,254,1,204,253,254,1,207,253,254,1,26,31,31,1, + 213,254,254,1,206,253,254,1,61,81,82,1,128,181,184,1,162,248,254,1, + 142,238,246,1,9,17,18,1,117,243,254,1,102,241,254,1,136,136,136,1, + 208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,17,23,24,1, + 167,223,226,1,191,250,254,1,93,120,122,1,104,132,133,1,201,252,254,1, + 204,253,254,1,207,253,254,1,26,31,31,1,213,254,254,1,206,253,254,1, + 82,108,109,1,98,139,141,1,162,248,254,1,119,200,206,1,25,47,49,1, + 117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1, + 179,248,254,1,182,248,254,1,91,122,125,1,75,100,102,1,141,184,187,1, + 36,46,47,1,173,220,222,1,201,252,254,1,204,253,254,1,207,253,254,1, + 26,31,31,1,213,254,254,1,206,253,254,1,154,204,205,1,36,51,52,1, + 122,187,191,1,49,82,85,1,78,144,150,1,117,243,254,1,102,241,254,1, + 136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1, + 185,249,254,1,140,186,189,1,91,119,121,1,157,203,205,1,198,251,254,1, + 201,252,254,1,204,253,254,1,207,253,254,1,118,142,142,1,213,254,254,1, + 206,253,254,1,191,252,254,1,155,220,223,1,79,122,125,1,97,163,168,1, + 131,243,253,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2, + 136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1, + 191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253,254,1, + 207,253,254,1,210,254,254,1,213,254,254,1,206,253,254,1,191,252,254,1, + 176,250,254,1,162,248,254,1,147,246,254,1,132,244,254,1,117,243,254,1, + 102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,206,253,254,1,191,252,254,1,176,250,254,1,162,248,254,1, + 147,246,254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136,136,1, + 208,208,208,2,136,136,136,22,208,208,208,25,0,0,0,8,254,255,0,8, + 254,255,1,191,254,255,3,8,254,255,7,0,254,255,15,8,254,255,31,2, + 254,255,63,192,254,255,127,0,254,255,127,8,254,255,127,0,254,255,127,8, + 254,255,127,8,254,255,127,8,254,255,127,191,254,255,127,8,254,255,127,0, + 254,255,127,2,254,255,127,8,254,255,127,0,254,255,127,0,254,255,127,191, + 254,255,127,0,0,0,0,8,6,111,110,115,104,111,119,7,14,100,105,115, + 97,115,115,102,111,111,110,115,104,111,119,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,11, + 116,115,116,114,105,110,103,103,114,105,100,4,103,114,105,100,5,99,111,108, + 111,114,4,5,0,0,144,20,102,114,97,109,101,46,115,98,118,101,114,116, + 46,111,112,116,105,111,110,115,11,14,115,98,111,95,116,104,117,109,98,116, + 114,97,99,107,8,115,98,111,95,115,104,111,119,0,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,9,112,111,112,117,112,109, + 101,110,117,7,8,112,111,112,117,112,109,101,110,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,42,2,9,98,111,117,110,100,115,95,99,121,3,210, + 0,7,97,110,99,104,111,114,115,11,0,9,111,110,107,101,121,100,111,119, + 110,7,5,107,101,121,100,111,11,111,112,116,105,111,110,115,103,114,105,100, + 11,12,111,103,95,99,111,108,115,105,122,105,110,103,20,111,103,95,99,111, + 108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119, + 114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,4,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99,111,95,114, + 101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99,117,115, + 12,99,111,95,115,97,118,101,115,116,97,116,101,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,76,16, + 111,110,98,101,102,111,114,101,100,114,97,119,99,101,108,108,7,11,98,101, + 102,100,114,97,119,99,101,108,108,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111, + 99,117,115,12,99,111,95,115,97,118,101,115,116,97,116,101,0,11,111,110, + 99,101,108,108,101,118,101,110,116,7,13,97,100,100,114,99,101,108,108,101, + 118,101,110,116,9,116,101,120,116,102,108,97,103,115,11,8,116,102,95,114, + 105,103,104,116,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102, + 95,110,111,115,101,108,101,99,116,0,15,116,101,120,116,102,108,97,103,115, + 97,99,116,105,118,101,11,8,116,102,95,114,105,103,104,116,12,116,102,95, + 121,99,101,110,116,101,114,101,100,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,20,115, + 99,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,3, + 99,1,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111, + 110,108,121,12,99,111,95,100,114,97,119,102,111,99,117,115,7,99,111,95, + 102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,0,9,116, + 101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114, + 101,100,11,116,102,95,110,111,115,101,108,101,99,116,13,116,102,95,116,97, + 98,116,111,115,112,97,99,101,0,15,116,101,120,116,102,108,97,103,115,97, + 99,116,105,118,101,11,12,116,102,95,121,99,101,110,116,101,114,101,100,13, + 116,102,95,116,97,98,116,111,115,112,97,99,101,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,14,115,99,111,101,95,101,97,116,114,101,116,117, + 114,110,20,115,99,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,1,7,111,112,116,105,111,110, + 115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,105,110, + 118,105,115,105,98,108,101,12,99,111,95,100,114,97,119,102,111,99,117,115, + 12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,118,97,108,117,101, + 102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1, + 49,0,1,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100, + 111,110,108,121,12,99,111,95,105,110,118,105,115,105,98,108,101,12,99,111, + 95,100,114,97,119,102,111,99,117,115,12,99,111,95,115,97,118,101,115,116, + 97,116,101,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,0,15,114,111,119,99,111,108, + 111,114,115,46,99,111,117,110,116,2,2,15,114,111,119,99,111,108,111,114, + 115,46,105,116,101,109,115,1,4,255,255,224,0,4,224,255,255,0,0,13, + 100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,12,111,110,115,99, + 114,111,108,108,114,111,119,115,7,10,115,99,114,111,108,108,114,111,119,115, + 11,111,110,99,101,108,108,101,118,101,110,116,7,12,99,101,108,108,101,118, + 101,110,116,101,120,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,13,0,0,10,116,112,111,112,117,112,109,101,110,117,8,112,111,112,117, + 112,109,101,110,8,111,110,117,112,100,97,116,101,7,11,112,111,112,117,112, + 117,112,100,97,116,101,18,109,101,110,117,46,115,117,98,109,101,110,117,46, + 99,111,117,110,116,2,1,18,109,101,110,117,46,115,117,98,109,101,110,117, + 46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,16,83,104, + 111,119,32,38,66,114,101,97,107,112,111,105,110,116,4,110,97,109,101,6, + 9,115,104,111,119,98,114,101,97,107,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117, + 116,101,7,12,115,104,111,119,98,114,101,97,107,101,120,101,0,0,4,108, + 101,102,116,2,120,3,116,111,112,2,24,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tdisassfo,''); +end. diff --git a/mseide-msegui/apps/ide/dumpunitgroups.pas b/mseide-msegui/apps/ide/dumpunitgroups.pas new file mode 100644 index 0000000..55f9951 --- /dev/null +++ b/mseide-msegui/apps/ide/dumpunitgroups.pas @@ -0,0 +1,236 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit dumpunitgroups; +{$ifdef FPC}{$mode objfpc}{$h+}{$INTERFACES CORBA}{$endif} +interface +procedure dumpunitgr; +implementation +uses + msedesigner,msedesignintf,typinfo,mseclasses,pascaldesignparser,msearrayutils, + sourceupdate,msestrings,msearrayprops,msetypes,msedatalist,msedesignparser; + +procedure dumpunitgr; +const + systypes: array[0..9] of string = ('Boolean','Integer','AnsiString', + 'Pointer','LongInt','LongWord','Variant','Int64','QWord','Currency'); +type + unitnamety = record + name: string; + uppername: string; + end; + unitnamearty = array of unitnamety; + unitgroupty = record + group: unitnamety; + units: unitnamearty; + end; + punitgroupty = ^unitgroupty; + unitgrouparty = array of unitgroupty; +var + groupar: unitgrouparty; + + function findgroup(const unitname: string): punitgroupty; + var + str1: string; + int1,int2: integer; + begin + str1:= struppercase(unitname); + int2:= length(groupar); + for int1:= 0 to int2 - 1 do begin + if str1 = groupar[int1].group.uppername then begin + int2:= int1; + break; + end; + end; + if int2 > high(groupar) then begin + setlength(groupar,int2+1); + with groupar[int2] do begin + group.name:= unitname; + group.uppername:= struppercase(unitname); + end; + end; + result:= @groupar[int2]; + end; + + procedure adddependency(const agroup: punitgroupty; const unitname: string); + var + str1: string; + int1,int2: integer; + begin + str1:= struppercase(unitname); + if str1 <> 'SYSTEM' then begin + with agroup^do begin + if str1 <> group.uppername then begin + int2:= length(units); + for int1:= 0 to int2 - 1 do begin + if units[int1].uppername = str1 then begin + int2:= int1; + break; + end; + end; + if int2> high(units) then begin + setlength(units,int2+1); + with units[int2] do begin + name:= unitname; + uppername:= str1; + end; + end; + end; + end; + end; + end; + +var + classn: string; + parsedclasses: classarty; + po6: punitgroupty; + + function isnotparsed(const aclass: tclass): boolean; + var + int1: integer; + begin + for int1:= 0 to high(parsedclasses) do begin + if parsedclasses[int1] = aclass then begin + result:= false; + exit; + end; + end; + additem(pointerarty(parsedclasses),aclass); + result:= true; + end; + + procedure dumpclass(po2: ptypeinfo); + var + po4: punitinfoty; + ar1: propinfopoarty; + int2,int3,int4: integer; + bo1: boolean; + defunitna,propna,typena,unitn: string; + po5: pdefinfoty; + methinfo: methodparaminfoty; + po3: ptypeinfo; + class1: tclass; + begin + if po2 = nil then begin + exit; + end; + unitn:= gettypedata(po2)^.unitname; + po4:= sourceupdater.updateunitinterface(unitn); + if po4 <> nil then begin + ar1:= getpropinfoar(po2); + for int2:= 0 to high(ar1) do begin + po2:= ar1[int2]^.proptype; + if po2^.kind = tkmethod then begin + getmethodparaminfo(po2,methinfo); + propna:= ar1[int2]^.name; + // writeln(' ',propna); + for int3:= 0 to high(methinfo.params) do begin + typena:= methinfo.params[int3].typename; + bo1:= false; + for int4:= 0 to high(systypes) do begin + bo1:= typena = systypes[int4]; + if bo1 then begin + break; + end; + end; + if not bo1 then begin + po5:= sourceupdater.finddef(po4,typena); + if po5 <> nil then begin + defunitna:= po5^.owner.rootlist.unitinfopo^.origunitname; + adddependency(po6,defunitna); + // writeln(' ',typena,' ',defunitna); + end + else begin + if typena = 'Exception' then begin + adddependency(po6,'sysutils'); + end + else begin + writeln(unitn,'.',classn,'.',propna,' "',typena+'" def unit not found.'); + end; + end; + end; + end; + end + else begin + if po2^.kind = tkclass then begin + class1:= gettypedata(po2)^.classtype; + if class1 = nil then begin + writeln(unitn,'.',classn,'.',propna, + ' "',typena+' '+po2^.name+'" typedata nil.'); + end + else begin + if isnotparsed(class1) then begin + po3:= class1.classinfo; + dumpclass(po3); + if class1.inheritsfrom(tpersistentarrayprop) then begin + class1:= persistentarraypropclassty(class1).getitemclasstype; + if class1 = nil then begin + writeln(unitn,'.',classn,'.',propna, + ' "',typena+' '+po3^.name+'" itemclasstype nil.'); + end + else begin + po3:= class1.classinfo; + dumpclass(po3); + end; + end; + end; + end; + end; + end; + end; + end + else begin + writeln('"'+unitn+'"'+'for '+'"'+classn+'" not found.'); + end; + end; //dumpclass + +var + int1,int2: integer; + po1: pcomponentclassinfoty; + po2: ptypeinfo; +// po3: ptypedata; + +begin + parsedclasses:= nil; + with registeredcomponents do begin + if count > 0 then begin + po1:= itempo(0); + for int1:= 0 to count - 1 do begin + classn:= po1^.classtyp.classname; +// writeln(classn); + po2:= po1^.classtyp.classinfo; + if isnotparsed(po1^.classtyp) then begin + po6:= findgroup(gettypedata(po2)^.unitname); + dumpclass(po2); + end; + inc(po1); + end; + end; + end; + writeln; + for int1:= 0 to high(groupar) do begin + with groupar[int1] do begin + if high(units) >= 0 then begin + write(' registerunitgroup(['''+group.name+'''],['); + for int2:= 0 to high(units) do begin + write(''''+units[int2].name+''''); + if int2 = high(units) then begin + write(']);'); + end + else begin + write(','); + end; + end; + writeln; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/finddialogform.mfm b/mseide-msegui/apps/ide/finddialogform.mfm new file mode 100644 index 0000000..671c690 --- /dev/null +++ b/mseide-msegui/apps/ide/finddialogform.mfm @@ -0,0 +1,213 @@ +object finddialogfo: tfinddialogfo + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 319 + bounds_y = 205 + bounds_cx = 371 + bounds_cy = 93 + anchors = [an_left, an_top, an_right] + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 371 + 93 + ) + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = statfile1 + caption = 'Find Text' + moduleclassname = 'tmseform' + object findtext: thistoryedit + frame.caption = '&Text to find' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 8 + bounds_y = 6 + bounds_cx = 356 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object tlayouter4: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 8 + bounds_y = 47 + bounds_cx = 358 + bounds_cy = 36 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + place_options = [plo_endmargin] + linktop = findtext + dist_top = 4 + object tlayouter3: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 105 + bounds_y = 0 + bounds_cx = 86 + bounds_cy = 36 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_alignx, lao_placey] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + object wholeword: tbooleanedit + frame.caption = '&whole word' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 73 + 2 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 86 + bounds_cy = 16 + end + object backward: tbooleanedit + frame.caption = '&backward' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 63 + 2 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 20 + bounds_cx = 76 + bounds_cy = 16 + end + end + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 101 + bounds_cy = 36 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_alignx, lao_placey] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + dist_top = 4 + dist_bottom = 4 + object casesensitive: tbooleanedit + frame.caption = 'c&asesensitive' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 88 + 2 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 101 + bounds_cy = 16 + end + object selectedonly: tbooleanedit + frame.caption = '&selected only' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 86 + 2 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 20 + bounds_cx = 99 + bounds_cy = 16 + statfile = statfile1 + end + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 2 + bounds_x = 195 + bounds_y = 8 + bounds_cx = 163 + bounds_cy = 20 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + place_options = [plo_endmargin] + object tlayouter5: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 51 + bounds_y = 0 + bounds_cx = 109 + bounds_cy = 20 + anchors = [an_top, an_right] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny, lao_syncmaxautosize] + align_glue = wam_start + place_mindist = 5 + place_maxdist = 5 + place_mode = wam_end + object cancel: tbutton + taborder = 1 + bounds_x = 57 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object tbutton2: tbutton + bounds_x = 0 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + end + end + end + object statfile1: tstatfile + filename = 'finddialogfo.sta' + options = [sfo_memory] + left = 112 + end +end diff --git a/mseide-msegui/apps/ide/finddialogform.pas b/mseide-msegui/apps/ide/finddialogform.pas new file mode 100644 index 0000000..f882a8e --- /dev/null +++ b/mseide-msegui/apps/ide/finddialogform.pas @@ -0,0 +1,113 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit finddialogform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msesimplewidgets,msedataedits,msegraphedits,msetextedit,msestrings, + msetypes,msestat,msestatfile,projectoptionsform,mseglob,mseevent,msegui, + msemenus,msesplitter,msegraphics,msegraphutils,msewidgets,mseguiglob, + mseificomp,mseificompglob,mseifiglob,msescrollbar; + +type + + tfinddialogfo = class(tmseform) + findtext: thistoryedit; + statfile1: tstatfile; + ok: tbutton; + tlayouter4: tlayouter; + tlayouter3: tlayouter; + wholeword: tbooleanedit; + backward: tbooleanedit; + tlayouter2: tlayouter; + casesensitive: tbooleanedit; + selectedonly: tbooleanedit; + tlayouter1: tlayouter; + tlayouter5: tlayouter; + cancel: tbutton; + tbutton2: tbutton; + private + procedure valuestoinfo(out info: findinfoty); + procedure infotovalues(const info: findinfoty); + end; + +procedure updatefindvalues(const astatfiler: tstatfiler; + var aoptions: findinfoty); +function finddialogexecute(var info: findinfoty): boolean; + +implementation +uses + finddialogform_mfm; + +procedure updatefindvalues(const astatfiler: tstatfiler; + var aoptions: findinfoty); +var + int1: integer; +begin + with astatfiler,aoptions do begin + updatevalue('finddtext',text); + updatevalue('findhistory',history); + int1:= {$ifdef FPC}longword{$else}byte{$endif}(options); + updatevalue('findoptions',int1); + options:= searchoptionsty({$ifdef FPC}longword{$else}byte{$endif}(int1)); + end; +end; + +function finddialogexecute(var info: findinfoty): boolean; +var + fo: tfinddialogfo; +begin + fo:= tfinddialogfo.create(nil); + try + fo.infotovalues(info); + result:= fo.show(true,nil) = mr_ok; + if result then begin + fo.valuestoinfo(info); + end; + finally + fo.Free; + end; +end; + +{ tfinddialogfo } + +procedure tfinddialogfo.valuestoinfo(out info: findinfoty); +begin + with info do begin + text:= findtext.value; + history:= findtext.dropdown.valuelist.asarray; + options:= encodesearchoptions(not casesensitive.value,wholeword.value, + false,backward.value); + selectedonly:= self.selectedonly.value; + end; +end; + +procedure tfinddialogfo.infotovalues(const info: findinfoty); +begin + with info do begin + findtext.value:= text; + findtext.dropdown.valuelist.asarray:= history; + casesensitive.value:= not (so_caseinsensitive in options); + wholeword.value:= so_wholeword in options; + backward.value:= so_backward in options; +// self.selectedonly.value:= selectedonly; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/finddialogform_mfm.pas b/mseide-msegui/apps/ide/finddialogform_mfm.pas new file mode 100644 index 0000000..d9634e1 --- /dev/null +++ b/mseide-msegui/apps/ide/finddialogform_mfm.pas @@ -0,0 +1,238 @@ +unit finddialogform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,finddialogform; + +const + objdata: record size: integer; data: array[0..4417] of byte end = + (size: 4418; data: ( + 84,80,70,48,13,116,102,105,110,100,100,105,97,108,111,103,102,111,12,102, + 105,110,100,100,105,97,108,111,103,102,111,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104, + 105,110,116,111,110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,3,63,1,8,98,111,117,110,100,115,95,121,3,205,0,9, + 98,111,117,110,100,115,95,99,120,3,115,1,9,98,111,117,110,100,115,95, + 99,121,2,93,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,23,99, + 111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95, + 115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97, + 110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,115,1,2,93,0,7,111,112,116,105,111, + 110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,17,102,111, + 95,108,111,99,97,108,115,104,111,114,116,99,117,116,115,15,102,111,95,97, + 117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119, + 114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,13, + 102,111,95,115,97,118,101,122,111,114,100,101,114,0,8,115,116,97,116,102, + 105,108,101,7,9,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105, + 111,110,6,9,70,105,110,100,32,84,101,120,116,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0, + 12,116,104,105,115,116,111,114,121,101,100,105,116,8,102,105,110,100,116,101, + 120,116,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,13,38,84, + 101,120,116,32,116,111,32,102,105,110,100,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,0,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100, + 115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,3,100,1,9,98, + 111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111, + 101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,13,111,101,49, + 95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116, + 2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101, + 109,115,14,1,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111, + 117,116,101,114,52,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101, + 110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119, + 95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2, + 47,9,98,111,117,110,100,115,95,99,120,3,102,1,9,98,111,117,110,100, + 115,95,99,121,2,36,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101, + 120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,17,111, + 115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99, + 95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111,112,116,105, + 111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101, + 120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95, + 103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112,108,97,99, + 101,95,109,105,110,100,105,115,116,2,4,13,112,108,97,99,101,95,109,97, + 120,100,105,115,116,2,4,13,112,108,97,99,101,95,111,112,116,105,111,110, + 115,11,13,112,108,111,95,101,110,100,109,97,114,103,105,110,0,7,108,105, + 110,107,116,111,112,7,8,102,105,110,100,116,101,120,116,8,100,105,115,116, + 95,116,111,112,2,4,0,9,116,108,97,121,111,117,116,101,114,10,116,108, + 97,121,111,117,116,101,114,51,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112, + 97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,2,105,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,86,9,98,111,117, + 110,100,115,95,99,121,2,36,12,111,112,116,105,111,110,115,115,99,97,108, + 101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115, + 104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111, + 115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110, + 100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115, + 104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117, + 116,11,10,108,97,111,95,97,108,105,103,110,120,10,108,97,111,95,112,108, + 97,99,101,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97, + 109,95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115, + 116,2,4,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,4,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,9,119,104,111,108,101,119, + 111,114,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11,38, + 119,104,111,108,101,32,119,111,114,100,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,1,2,73,2,2,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,86,9,98,111,117,110,100,115,95,99,121, + 2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,8,98,97, + 99,107,119,97,114,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,9,38,98,97,99,107,119,97,114,100,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,1,2,63,2,2,0,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120, + 2,76,9,98,111,117,110,100,115,95,99,121,2,16,0,0,0,9,116,108, + 97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,50,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98, + 102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,101,9,98,111,117,110,100, + 115,95,99,121,2,36,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114, + 105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99, + 95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100,115, + 104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114, + 105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,97,108,105,103,110,120,10,108,97,111,95,112,108,97,99, + 101,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95, + 115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116,2, + 4,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,4,8,100,105, + 115,116,95,116,111,112,2,4,11,100,105,115,116,95,98,111,116,116,111,109, + 2,4,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,99,97,115, + 101,115,101,110,115,105,116,105,118,101,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,14,99,38,97,115,101,115,101,110,115,105,116,105,118,101, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,88,2,2,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,101, + 9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,12,115,101,108,101,99,116,101,100,111,110,108,121, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,14,38,115,101,108, + 101,99,116,101,100,32,111,110,108,121,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,1,2,86,2,2,0,8,116,97,98, + 111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120,2, + 99,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105, + 108,101,7,9,115,116,97,116,102,105,108,101,49,0,0,0,9,116,108,97, + 121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,49,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102, + 111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120, + 3,195,0,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100, + 115,95,99,120,3,163,0,9,98,111,117,110,100,115,95,99,121,2,20,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95, + 116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105,111,110, + 115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111, + 117,116,11,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103, + 110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112,108, + 97,99,101,95,111,112,116,105,111,110,115,11,13,112,108,111,95,101,110,100, + 109,97,114,103,105,110,0,0,9,116,108,97,121,111,117,116,101,114,10,116, + 108,97,121,111,117,116,101,114,53,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95, + 112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100,115,95,120, + 2,51,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,109,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107, + 120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104, + 114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116, + 11,10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105, + 103,110,121,19,108,97,111,95,115,121,110,99,109,97,120,97,117,116,111,115, + 105,122,101,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109, + 95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116, + 2,5,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,5,10,112, + 108,97,99,101,95,109,111,100,101,7,7,119,97,109,95,101,110,100,0,7, + 116,98,117,116,116,111,110,6,99,97,110,99,101,108,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,57,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,52,9, + 98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109, + 111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101, + 108,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100, + 115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,10, + 97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100, + 101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100, + 97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,0,0,0, + 9,116,115,116,97,116,102,105,108,101,9,115,116,97,116,102,105,108,101,49, + 8,102,105,108,101,110,97,109,101,6,16,102,105,110,100,100,105,97,108,111, + 103,102,111,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111, + 95,109,101,109,111,114,121,0,4,108,101,102,116,2,112,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfinddialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/findinfiledialogform.mfm b/mseide-msegui/apps/ide/findinfiledialogform.mfm new file mode 100644 index 0000000..45895af --- /dev/null +++ b/mseide-msegui/apps/ide/findinfiledialogform.mfm @@ -0,0 +1,308 @@ +object findinfileadialogfo: tfindinfiledialogfo + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 268 + bounds_y = 415 + bounds_cx = 339 + bounds_cy = 275 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 339 + 275 + ) + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = statfile1 + caption = 'Find Text in Files' + oncreate = cereateev + moduleclassname = 'tmseform' + object findtext: thistoryedit + frame.caption = '&Text to find' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 8 + bounds_y = 9 + bounds_cx = 321 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = statfile1 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object dir: tfilenameedit + frame.caption = '&Directory' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + onshowhint = dirshowhint + bounds_x = 8 + bounds_y = 137 + bounds_cx = 321 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = statfile1 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + onsetvalue = dirsetvalue + controller.options = [fdo_directory] + controller.ongetfilename = dirgetfilenameexe + controller.onbeforeexecute = dironbeforeexecute + reffontheight = 14 + end + object mask: thistoryedit + frame.caption = '&File Mask' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 8 + bounds_y = 185 + bounds_cx = 321 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = statfile1 + value = '"*.pas" "*.pp" "*.inc"' + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 0 + bounds_y = 48 + bounds_cx = 154 + bounds_cy = 80 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linkright = tlayouter2 + object indirectories: tbooleaneditradio + frame.caption = 'Search in &directories' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 133 + 2 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 64 + bounds_cx = 146 + bounds_cy = 16 + statfile = statfile1 + ondataentered = sourcechangeexe + onsetvalue = dirsetval + end + object casesensitive: tbooleanedit + frame.caption = 'C&asesensitive' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 89 + 2 + ) + bounds_x = 8 + bounds_y = 16 + bounds_cx = 102 + bounds_cy = 16 + statfile = statfile1 + end + object inprojectdir: tbooleaneditradio + frame.caption = 'Search in &project dir' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 130 + 2 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 40 + bounds_cx = 143 + bounds_cy = 16 + statfile = statfile1 + ondataentered = sourcechangeexe + onsetvalue = dirsetval + value = True + end + end + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 2 + bounds_x = 154 + bounds_y = 48 + bounds_cx = 155 + bounds_cy = 82 + optionsscale = [osc_expandx, osc_shrinkx] + object wholeword: tbooleanedit + frame.caption = '&Whole word' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 75 + 2 + ) + bounds_x = 8 + bounds_y = 16 + bounds_cx = 88 + bounds_cy = 16 + statfile = statfile1 + end + object inopenfiles: tbooleaneditradio + Tag = 1 + frame.caption = 'Search in &open files' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 127 + 2 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 40 + bounds_cx = 140 + bounds_cy = 16 + statfile = statfile1 + ondataentered = sourcechangeexe + onsetvalue = opensetval + end + object incurrentfile: tbooleaneditradio + Tag = 1 + frame.caption = 'Search in ¤t file' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 134 + 2 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 64 + bounds_cx = 147 + bounds_cy = 16 + statfile = statfile1 + ondataentered = sourcechangeexe + onsetvalue = currentsetval + end + end + object tlayouter4: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 5 + bounds_x = 0 + bounds_y = 232 + bounds_cx = 339 + bounds_cy = 30 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object tlayouter3: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.framei_top = 5 + frame.framei_bottom = 5 + frame.localprops = [frl_fitop, frl_fibottom] + frame.localprops1 = [] + bounds_x = 218 + bounds_y = 0 + bounds_cx = 119 + bounds_cy = 30 + anchors = [an_top, an_right] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 5 + place_maxdist = 5 + place_mode = wam_end + place_options = [plo_propmargin, plo_syncmaxautosize] + object ok: tbutton + bounds_x = 5 + bounds_y = 5 + bounds_cx = 52 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 1 + bounds_x = 62 + bounds_y = 5 + bounds_cx = 52 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + end + object subdirs: tbooleanedit + frame.caption = '&Include subdirectories' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 142 + 2 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 8 + bounds_cx = 155 + bounds_cy = 16 + statfile = statfile1 + end + end + object statfile1: tstatfile + filename = 'findinfiledialogfo.sta' + options = [sfo_memory] + left = 248 + top = 72 + end +end diff --git a/mseide-msegui/apps/ide/findinfiledialogform.pas b/mseide-msegui/apps/ide/findinfiledialogform.pas new file mode 100644 index 0000000..3af960f --- /dev/null +++ b/mseide-msegui/apps/ide/findinfiledialogform.pas @@ -0,0 +1,244 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit findinfiledialogform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + finddialogform,findinfileform,mseforms,msedataedits,msesimplewidgets, + msegraphedits,msefiledialog,msetypes,mseglob,mseguiglob,msegui,msestat, + msestatfile,mseevent,msemenus,msesplitter,msegraphics,msegraphutils,msewidgets, + msestrings,mseificomp,mseificompglob,mseifiglob,msescrollbar; + +type + + tfindinfiledialogfo = class(tmseform) + findtext: thistoryedit; + statfile1: tstatfile; + dir: tfilenameedit; + mask: thistoryedit; + tlayouter1: tlayouter; + indirectories: tbooleaneditradio; + casesensitive: tbooleanedit; + tlayouter2: tlayouter; + wholeword: tbooleanedit; + inopenfiles: tbooleaneditradio; + tlayouter4: tlayouter; + tlayouter3: tlayouter; + ok: tbutton; + cancel: tbutton; + subdirs: tbooleanedit; + inprojectdir: tbooleaneditradio; + incurrentfile: tbooleaneditradio; + procedure dironbeforeexecute(const sender: tfiledialogcontroller; + var dialogkind: filedialogkindty; var aresult: modalresultty); + procedure dirshowhint(const sender: TObject; var info: hintinfoty); + procedure sourcechangeexe(const sender: TObject); +// procedure chainopenfiles(const sender: TObject); + procedure dirgetfilenameexe(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure dirsetval(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure opensetval(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure dirsetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure cereateev(const sender: TObject); + procedure currentsetval(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + private + procedure valuestoinfo(out info: findinfileinfoty); + procedure infotovalues(const info: findinfileinfoty); + end; + +function findinfiledialogexecute(var info: findinfileinfoty; + const useinfo: boolean): boolean; + +implementation +uses + msebits,findinfiledialogform_mfm,projectoptionsform,main,msefileutils, + sourceform; + +function findinfiledialogexecute(var info: findinfileinfoty; + const useinfo: boolean): boolean; +var + fo: tfindinfiledialogfo; +begin + fo:= tfindinfiledialogfo.create(nil); + try + if useinfo then begin + fo.infotovalues(info); + end; + result:= fo.show(true,nil) = mr_ok; + if result then begin + fo.valuestoinfo(info); + end; + finally + fo.Free; + end; +end; + +{ tfindinfiledialogfo } + +procedure tfindinfiledialogfo.dironbeforeexecute( + const sender: tfiledialogcontroller; var dialogkind: filedialogkindty; + var aresult: modalresultty); +begin + sender.filterlist.asarrayb:= mask.dropdown.valuelist.asarray; + sender.filter:= mask.value; +end; + +procedure tfindinfiledialogfo.valuestoinfo(out info: findinfileinfoty); +begin +{$warnings off} + with info.findinfo do begin + text:= findtext.value; + history:= findtext.dropdown.valuelist.asarray; + options:= encodesearchoptions(not casesensitive.value,wholeword.value); + end; + with info do begin + directory:= dir.value; + filemask:= mask.value; + updatebit({$ifdef FPC}longword{$else}byte{$endif}(options),ord(fifo_subdirs),subdirs.value); + if inopenfiles.value then begin + source:= fs_inopenfiles; + end + else begin + if indirectories.value then begin + source:= fs_indirectories; + end + else begin + if incurrentfile.value then begin + source:= fs_incurrentfile; + end + else begin + source:= fs_inprojectdir; + end; + end; + end; + end; +end; +{$warnings on} +procedure tfindinfiledialogfo.infotovalues(const info: findinfileinfoty); +begin + with info.findinfo do begin + findtext.value:= text; + findtext.dropdown.valuelist.asarray:= history; + casesensitive.value:= not (so_caseinsensitive in options); + wholeword.value:= so_wholeword in options; + end; + with info do begin + dir.value:= directory; + mask.value:= filemask; + subdirs.value:= fifo_subdirs in options; + case source of + fs_inopenfiles: begin + inopenfiles.value:= true; + end; + fs_indirectories: begin + indirectories.value:= true; + end; + fs_inprojectdir: begin + inprojectdir.value:= true; + end; + fs_incurrentfile: begin + incurrentfile.value:= true; + end; + end; + end; +end; + +procedure tfindinfiledialogfo.dirshowhint(const sender: TObject; + var info: hintinfoty); +begin + hintmacros(tcustomstringedit(sender),info); + info.caption:= info.caption+lineend+'Empty -> project directory'; +end; + +procedure tfindinfiledialogfo.dirgetfilenameexe(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + expandprmacros1(avalue); +end; + +procedure tfindinfiledialogfo.sourcechangeexe(const sender: TObject); +begin + if indirectories.value then begin +// inopenfiles.value:= false; + dir.enabled:= true; + mask.enabled:= true; + subdirs.enabled:= true; + end + else begin + if inopenfiles.value or incurrentfile.value then begin + dir.enabled:= false; + mask.enabled:= false; + subdirs.enabled:= false; + end + else begin // + dir.enabled:= false; + mask.enabled:= true; + subdirs.enabled:= true; + end; + end; +end; + +procedure tfindinfiledialogfo.dirsetval(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + if avalue then begin + inopenfiles.value:= false; + incurrentfile.value:= false; + end; +end; + +procedure tfindinfiledialogfo.opensetval(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + if avalue then begin + inprojectdir.value:= false; + indirectories.value:= false; + end; +end; + +procedure tfindinfiledialogfo.currentsetval(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + if avalue then begin + inprojectdir.value:= false; + indirectories.value:= false; + end; +end; + + +procedure tfindinfiledialogfo.dirsetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + if avalue = '' then begin + avalue:= filedir(mainfo.projectname); + end; +end; + +procedure tfindinfiledialogfo.cereateev(const sender: TObject); +begin + if sourcefo.activepage = nil then begin + incurrentfile.enabled:= false; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/findinfiledialogform_mfm.pas b/mseide-msegui/apps/ide/findinfiledialogform_mfm.pas new file mode 100644 index 0000000..fdd9fb4 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfiledialogform_mfm.pas @@ -0,0 +1,286 @@ +unit findinfiledialogform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,findinfiledialogform; + +const + objdata: record size: integer; data: array[0..5371] of byte end = + (size: 5372; data: ( + 84,80,70,48,19,116,102,105,110,100,105,110,102,105,108,101,100,105,97,108, + 111,103,102,111,19,102,105,110,100,105,110,102,105,108,101,97,100,105,97,108, + 111,103,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111, + 119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,12,1, + 8,98,111,117,110,100,115,95,121,3,159,1,9,98,111,117,110,100,115,95, + 99,120,3,83,1,9,98,111,117,110,100,115,95,99,121,3,19,1,23,99, + 111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95, + 115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97, + 110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,83,1,3,19,1,0,7,111,112,116,105, + 111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,17,102, + 111,95,108,111,99,97,108,115,104,111,114,116,99,117,116,115,15,102,111,95, + 97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111, + 119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115, + 13,102,111,95,115,97,118,101,122,111,114,100,101,114,0,8,115,116,97,116, + 102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,7,99,97,112,116, + 105,111,110,6,18,70,105,110,100,32,84,101,120,116,32,105,110,32,70,105, + 108,101,115,8,111,110,99,114,101,97,116,101,7,9,99,101,114,101,97,116, + 101,101,118,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6, + 8,116,109,115,101,102,111,114,109,0,12,116,104,105,115,116,111,114,121,101, + 100,105,116,8,102,105,110,100,116,101,120,116,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,13,38,84,101,120,116,32,116,111,32,102,105,110, + 100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4, + 2,0,0,128,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,9,9,98,111,117,110,100,115, + 95,99,120,3,65,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,8,115,116,97,116,102,105,108, + 101,7,9,115,116,97,116,102,105,108,101,49,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105, + 108,101,110,97,109,101,101,100,105,116,3,100,105,114,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,10,38,68,105,114,101,99,116,111,114,121, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101, + 110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116, + 116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,3,10,111,110,115,104,111,119,104,105, + 110,116,7,11,100,105,114,115,104,111,119,104,105,110,116,8,98,111,117,110, + 100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,3,137,0,9,98, + 111,117,110,100,115,95,99,120,3,65,1,9,98,111,117,110,100,115,95,99, + 121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,8,115,116, + 97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101, + 100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101,108,108, + 105,112,115,101,108,101,102,116,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,100,105,114,115,101,116,118,97,108,117,101,18,99,111,110,116,114,111, + 108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111,95,100,105, + 114,101,99,116,111,114,121,0,24,99,111,110,116,114,111,108,108,101,114,46, + 111,110,103,101,116,102,105,108,101,110,97,109,101,7,17,100,105,114,103,101, + 116,102,105,108,101,110,97,109,101,101,120,101,26,99,111,110,116,114,111,108, + 108,101,114,46,111,110,98,101,102,111,114,101,101,120,101,99,117,116,101,7, + 18,100,105,114,111,110,98,101,102,111,114,101,101,120,101,99,117,116,101,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,104, + 105,115,116,111,114,121,101,100,105,116,4,109,97,115,107,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,10,38,70,105,108,101,32,77,97,115, + 107,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4, + 2,0,0,128,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,4,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115, + 95,121,3,185,0,9,98,111,117,110,100,115,95,99,120,3,65,1,9,98, + 111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,0,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102, + 105,108,101,49,5,118,97,108,117,101,6,22,34,42,46,112,97,115,34,32, + 34,42,46,112,112,34,32,34,42,46,105,110,99,34,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111, + 112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116, + 108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,49,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97, + 98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111, + 99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,48,9,98,111,117,110, + 100,115,95,99,120,3,154,0,9,98,111,117,110,100,115,95,99,121,2,80, + 12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101, + 120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111, + 115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110, + 107,121,0,9,108,105,110,107,114,105,103,104,116,7,10,116,108,97,121,111, + 117,116,101,114,50,0,17,116,98,111,111,108,101,97,110,101,100,105,116,114, + 97,100,105,111,13,105,110,100,105,114,101,99,116,111,114,105,101,115,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,22,83,101,97,114,99,104, + 32,105,110,32,38,100,105,114,101,99,116,111,114,105,101,115,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,133,0, + 2,2,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,64,9,98,111,117, + 110,100,115,95,99,120,3,146,0,9,98,111,117,110,100,115,95,99,121,2, + 16,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101, + 49,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,15,115,111,117, + 114,99,101,99,104,97,110,103,101,101,120,101,10,111,110,115,101,116,118,97, + 108,117,101,7,9,100,105,114,115,101,116,118,97,108,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,13,99,97,115,101,115,101,110,115,105,116, + 105,118,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,14,67, + 38,97,115,101,115,101,110,115,105,116,105,118,101,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,89,2,2,0,8, + 98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2, + 16,9,98,111,117,110,100,115,95,99,120,2,102,9,98,111,117,110,100,115, + 95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116, + 102,105,108,101,49,0,0,17,116,98,111,111,108,101,97,110,101,100,105,116, + 114,97,100,105,111,12,105,110,112,114,111,106,101,99,116,100,105,114,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,22,83,101,97,114,99,104, + 32,105,110,32,38,112,114,111,106,101,99,116,32,100,105,114,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,130,0, + 2,2,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,40,9,98,111,117, + 110,100,115,95,99,120,3,143,0,9,98,111,117,110,100,115,95,99,121,2, + 16,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101, + 49,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,15,115,111,117, + 114,99,101,99,104,97,110,103,101,101,120,101,10,111,110,115,101,116,118,97, + 108,117,101,7,9,100,105,114,115,101,116,118,97,108,5,118,97,108,117,101, + 9,0,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111, + 117,116,101,114,50,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101, + 110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119, + 95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,2,8, + 98,111,117,110,100,115,95,120,3,154,0,8,98,111,117,110,100,115,95,121, + 2,48,9,98,111,117,110,100,115,95,99,120,3,155,0,9,98,111,117,110, + 100,115,95,99,121,2,82,12,111,112,116,105,111,110,115,115,99,97,108,101, + 11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104, + 114,105,110,107,120,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 9,119,104,111,108,101,119,111,114,100,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,11,38,87,104,111,108,101,32,119,111,114,100,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,75, + 2,2,0,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100, + 115,95,121,2,16,9,98,111,117,110,100,115,95,99,120,2,88,9,98,111, + 117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,9, + 115,116,97,116,102,105,108,101,49,0,0,17,116,98,111,111,108,101,97,110, + 101,100,105,116,114,97,100,105,111,11,105,110,111,112,101,110,102,105,108,101, + 115,3,84,97,103,2,1,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,21,83,101,97,114,99,104,32,105,110,32,38,111,112,101,110,32,102, + 105,108,101,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,1,2,127,2,2,0,8,116,97,98,111,114,100,101,114,2, + 1,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95, + 121,2,40,9,98,111,117,110,100,115,95,99,120,3,140,0,9,98,111,117, + 110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,9,115, + 116,97,116,102,105,108,101,49,13,111,110,100,97,116,97,101,110,116,101,114, + 101,100,7,15,115,111,117,114,99,101,99,104,97,110,103,101,101,120,101,10, + 111,110,115,101,116,118,97,108,117,101,7,10,111,112,101,110,115,101,116,118, + 97,108,0,0,17,116,98,111,111,108,101,97,110,101,100,105,116,114,97,100, + 105,111,13,105,110,99,117,114,114,101,110,116,102,105,108,101,3,84,97,103, + 2,1,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,23,83,101, + 97,114,99,104,32,105,110,32,38,99,117,114,114,101,110,116,32,102,105,108, + 101,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,1,3,134,0,2,2,0,8,116,97,98,111,114,100,101,114,2,2,8, + 98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2, + 64,9,98,111,117,110,100,115,95,99,120,3,147,0,9,98,111,117,110,100, + 115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,9,115,116,97, + 116,102,105,108,101,49,13,111,110,100,97,116,97,101,110,116,101,114,101,100, + 7,15,115,111,117,114,99,101,99,104,97,110,103,101,101,120,101,10,111,110, + 115,101,116,118,97,108,117,101,7,13,99,117,114,114,101,110,116,115,101,116, + 118,97,108,0,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97, + 121,111,117,116,101,114,52,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97, + 114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11, + 111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2, + 5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,3,232,0,9,98,111,117,110,100,115,95,99,120,3,83,1,9,98,111, + 117,110,100,115,95,99,121,2,30,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114, + 105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95,103, + 108,117,101,7,9,119,97,109,95,115,116,97,114,116,0,9,116,108,97,121, + 111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,51,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111, + 99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,16, + 102,114,97,109,101,46,102,114,97,109,101,105,95,116,111,112,2,5,19,102, + 114,97,109,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,5, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,9,102, + 114,108,95,102,105,116,111,112,12,102,114,108,95,102,105,98,111,116,116,111, + 109,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,98,111,117,110,100,115,95,120,3,218,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,119,9,98,111, + 117,110,100,115,95,99,121,2,30,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105, + 111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100, + 120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120, + 112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111, + 112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108, + 97,99,101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105, + 103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112, + 108,97,99,101,95,109,105,110,100,105,115,116,2,5,13,112,108,97,99,101, + 95,109,97,120,100,105,115,116,2,5,10,112,108,97,99,101,95,109,111,100, + 101,7,7,119,97,109,95,101,110,100,13,112,108,97,99,101,95,111,112,116, + 105,111,110,115,11,14,112,108,111,95,112,114,111,112,109,97,114,103,105,110, + 19,112,108,111,95,115,121,110,99,109,97,120,97,117,116,111,115,105,122,101, + 0,0,7,116,98,117,116,116,111,110,2,111,107,8,98,111,117,110,100,115, + 95,120,2,5,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110, + 100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99,121,2,20,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97, + 117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112, + 116,105,111,110,6,2,79,75,11,109,111,100,97,108,114,101,115,117,108,116, + 7,5,109,114,95,111,107,0,0,7,116,98,117,116,116,111,110,6,99,97, + 110,99,101,108,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,62,8,98,111,117,110,100,115,95,121,2,5,9,98,111, + 117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99,121,2, + 20,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 6,67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7, + 9,109,114,95,99,97,110,99,101,108,0,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,7,115,117,98,100,105,114,115,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,23,38,73,110,99,108,117,100,101,32,115, + 117,98,100,105,114,101,99,116,111,114,105,101,115,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,142,0,2,2,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100,115, + 95,99,120,3,155,0,9,98,111,117,110,100,115,95,99,121,2,16,8,115, + 116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,0,0, + 0,9,116,115,116,97,116,102,105,108,101,9,115,116,97,116,102,105,108,101, + 49,8,102,105,108,101,110,97,109,101,6,22,102,105,110,100,105,110,102,105, + 108,101,100,105,97,108,111,103,102,111,46,115,116,97,7,111,112,116,105,111, + 110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116, + 3,248,0,3,116,111,112,2,72,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfindinfiledialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/findinfileform.mfm b/mseide-msegui/apps/ide/findinfileform.mfm new file mode 100644 index 0000000..9255ee0 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfileform.mfm @@ -0,0 +1,111 @@ +object findinfilefo: tfindinfilefo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_topbutton, go_nolockbutton] + visible = False + bounds_x = 548 + bounds_y = 115 + bounds_cx = 369 + bounds_cy = 198 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 359 + 198 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Findresults' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint] + options = [fo_savepos, fo_savezorder] + statfile = mainfo.projectstatfile + caption = 'Find in file results' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000078080000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E0E0E001D3D3D301 + DDDDDD01E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01D9D9D901B4B4B401A3A3A30199999903A2A2A201 + AFAFAF01CCCCCC01DBDBDB02DADADA01D8D8D801D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EBEBEB01BFBFBF01 + 9A9A9A01A2A0A001BBB4B401D0C7C801E1D2D401D1C4C501BCB3B401A29F9F01 + 9A9A9A01A9A9A901D2D2D201D9D9D901D8D8D801D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201EAEAEA01A7A7A70199999901 + C1B7B701F6E2E401FDEBED01FFEBED01FFE8EB01FFE6E901FFE3E601FBDEE101 + C4B6B80199999902C6C6C601D5D5D501D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F201B9B9B9019A9A9A01DBCACB01FAE4E601 + FDE9EB01FFEBEE01FFE9EB01FFE6E901FFE4E701FFE1E501FFDFE201FFDCE001 + E1C6CA01999999018D8D8D01B6B6B601D4D4D401D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501F3F3F301D7D7D70199999901C6BABB01F9E3E401FCE8EA01 + FFECEE01CFBEC00174696A012F2A2B0149414201BEA6A901FFDDE101FFDADE01 + FFD8DC01CAB6B8019999990181818101C6C6C601D4D4D401D3D3D301D2D2D201 + D0D0D001F5F5F501F3F3F301A7A6A601A9A5A601F6E1E201FBE7E801FEECEE01 + F1DDDF010F0E0E017A6E6F01CFB7BB017C6D6E010A090901EECCD001FFD8DD01 + FFD6DA01FDD3D801AAA3A4019392920191919101CDCDCD01D3D3D301D2D2D201 + D0D0D001F5F5F501EDEDED0199999901CBBFC001FAE6E701FDEBED01FFEBED01 + 928587012E292A01FFE3E601FFE1E401FFDEE201372F30018C777901FFD6DB01 + FFD4D902CFB8BB01999999016D6D6D01B4B4B401D1D1D101D2D2D201D0D0D001 + F5F5F501DADADA0199999901DFCFD101FDE9EB01FFEBEE01FFE9EB01FFE6E901 + FBE0E301FFE1E501FFDFE201F9D7DB012A242501957E8101FFD4D903E3C4C701 + 99999901737373019A9A9A01CFCFCF01D2D2D201D0D0D001F5F5F501CACACA01 + 99999901F3E1E301FFECEE01FFE9EC01FFE7EA01FFE4E701FFE2E501FFDFE301 + FAD9DD0152464701382F3001F6CDD201FFD4D903F6CFD301999999017D7D7D01 + 84848401CDCDCD01D2D2D201D0D0D001F5F5F501D1D1D10199999901ECDDDF01 + FFEAEC01FFE8EA01FFE5E801FFE2E601FFE0E301FFDDE101655758012F282901 + EBC5C901FFD4D904EDCACE01999999017777770170707001CCCCCC01D2D2D201 + D0D0D001F5F5F501E3E3E30199999901D9CCCE01FFE8EB01FFE6E801FFE3E601 + FFE0E401FFDEE201F9D6DA0103030301D0AFB301FFD4D905D9BEC10199999901 + 6B6B6B0170707001CCCCCC01D2D2D201D0D0D001F5F5F501F2F2F2019C9C9C01 + C3BABB01FFE6E901FFE4E701FFE1E401FFDFE201FFDCE001EECBCF0167575801 + F7CDD201FFD4D905C3B1B401989898016565650183838301CCCCCC01D2D2D201 + D0D0D001F5F5F501F3F3F301B7B7B7019B9A9A01ECD6D801FFE2E501FFDFE301 + FFDDE101FFDADE01EFCACE01A78B8F01F2C9CE01FFD4D904ECC9CD019A999901 + 858585016565650198989801CFCFCF01D2D2D201D0D0D001F5F5F501F3F3F301 + E8E8E8019E9E9E01ABA6A701FDDFE201FFDDE101FFDBDF01FFD8DD01D0AEB201 + 00000001D7B3B701FFD4D903FDD3D801ABA3A4019697980158809301696B6C01 + B2B2B201D1D1D101D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201CECECE01 + 99999901B2AAAB01F3D3D701FFD9DD01FFD6DB01FFD4D905F3CDD201B2A7A901 + 999999018CADBE0166A4C3015488A201B7B9BA01D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201EFEFEF01C0C0C001999898019D9B9B01D3BCBF01 + F1CCD001FFD4D903F1CCD001D3BBBD019D9B9B019898990196B0BD01A7CADD01 + 86B7D00167A4C3015489A301BEC0C101D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001EAEAEA01BFBFBF0193929201999999029D9B9C01ACA3A401 + 9D9B9C01999999028C8B8B01618BA00174ACC90194BFD501A7CADD0187B7D001 + 67A4C301578BA501B9BBBC01D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001 + EEEEEE01E9E9E901D5D5D5019797970181818101878787018E8E8E0185858501 + 7B7B7B01727272016A6A6A01696F72015A93B00174ACC80194BFD501A7CADD01 + 87B7D00167A4C3015489A301B7B9BA01F5F5F501F3F3F301F2F2F201F0F0F001 + EEEEEE01EDEDED01EAEAEA01E2E2E201C0C0C001A2A2A2018989890175757501 + 74747401868686019D9D9D01B7B7B701C0C6C9015D96B30174ACC80194BFD501 + A7CADD0187B7D00167A4C3015F879B01F5F5F501F3F3F301F2F2F201F0F0F001 + EEEEEE01EDEDED01EBEBEB01EAEAEA01E5E5E501E1E1E101DEDEDE01DADADA01 + D9D9D902DBDBDB01DADADA01DBDBDB01C7CDD0015E97B40174ACC80194BFD501 + A7CBDD0186B6CD0162737C01F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201 + E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01C5CBCE015E97B30174ACC801 + 93BDD201758086015E5E5E01F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201 + E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801C4CACD016995AB01 + 6C7C85015F5F5F017D7D7D01 + } + moduleclassname = 'tdockform' + object tabs: ttabwidget + bounds_x = 0 + bounds_y = 0 + bounds_cx = 359 + bounds_cy = 198 + anchors = [] + tab_options = [tabo_dragsource, tabo_dragdest, tabo_opposite, tabo_dblclickedtabfirst, tabo_hintclippedtext] + tab_frame.buttonslast = True + tab_frame.localprops = [] + tab_frame.localprops1 = [] + tab_size = 18 + end +end diff --git a/mseide-msegui/apps/ide/findinfileform.pas b/mseide-msegui/apps/ide/findinfileform.pas new file mode 100644 index 0000000..a9600e6 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfileform.pas @@ -0,0 +1,77 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit findinfileform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + finddialogform,mseforms,msegrids,msethreadcomp,msesimplewidgets, + msesysutils,msedispwidgets,msetypes,msestrings,msewidgetgrid,msetextedit, + msestat,msetabs,projectoptionsform; + +type + + filesourcety = (fs_indirectories,fs_inopenfiles,fs_inprojectdir, + fs_incurrentfile); + findinfileoptionty = (fifo_subdirs); + findinfileoptionsty = set of findinfileoptionty; + + findinfileinfoty = record + findinfo: findinfoty; + options: findinfileoptionsty; + directory: filenamety; + filemask: msestring; + resultlist: ttextedit; + source: filesourcety; + end; + + tfindinfilefo = class(tdockform) + tabs: ttabwidget; + private + public + procedure newsearch(const info: findinfileinfoty); + end; + +procedure dofindinfile; + +var + findinfilefo: tfindinfilefo; + findinfileinfo: findinfileinfoty; + +implementation +uses + findinfiledialogform,main,findinfileform_mfm,msefileutils,msestream, + msesys,msegui,sysutils,mserichstring,msegraphics,sourceform,sourcepage, + findinfilepage,mseeditglob; + +procedure dofindinfile; +begin + if findinfiledialogexecute(findinfileinfo,false) then begin + findinfilefo.newsearch(findinfileinfo); + findinfilefo.activate; + end; +end; + +{ tfindinfilefo } + +procedure tfindinfilefo.newsearch(const info: findinfileinfoty); +begin + tabs.add(itabpage(tfindinfilepagefo.create(self,info))); +end; + +end. diff --git a/mseide-msegui/apps/ide/findinfileform_mfm.pas b/mseide-msegui/apps/ide/findinfileform_mfm.pas new file mode 100644 index 0000000..058f214 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfileform_mfm.pas @@ -0,0 +1,174 @@ +unit findinfileform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,findinfileform; + +const + objdata: record size: integer; data: array[0..3129] of byte end = + (size: 3130; data: ( + 84,80,70,48,13,116,102,105,110,100,105,110,102,105,108,101,102,111,12,102, + 105,110,100,105,110,102,105,108,101,102,111,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105, + 112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95, + 111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116, + 116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110, + 12,103,111,95,116,111,112,98,117,116,116,111,110,15,103,111,95,110,111,108, + 111,99,107,98,117,116,116,111,110,0,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,3,36,2,8,98,111,117,110,100,115,95,121, + 2,115,9,98,111,117,110,100,115,95,99,120,3,113,1,9,98,111,117,110, + 100,115,95,99,121,3,198,0,26,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111, + 117,110,100,115,1,2,0,2,0,3,103,1,3,198,0,0,22,100,114,97, + 103,100,111,99,107,46,115,112,108,105,116,116,101,114,95,115,105,122,101,2, + 0,16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111,110,6,11, + 70,105,110,100,114,101,115,117,108,116,115,20,100,114,97,103,100,111,99,107, + 46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118, + 101,112,111,115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111, + 100,95,99,97,110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97, + 116,10,111,100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111,112, + 115,105,122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,0, + 7,111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112,111,115, + 13,102,111,95,115,97,118,101,122,111,114,100,101,114,0,8,115,116,97,116, + 102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116, + 115,116,97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,20,70,105, + 110,100,32,105,110,32,102,105,108,101,32,114,101,115,117,108,116,115,21,105, + 99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,10,105,99,111,110,46,105,109,97,103,101,10,172,8,0, + 0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,120,8,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,245,245,245,1,243,243,243, + 1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235, + 1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227, + 1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219, + 1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211, + 1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242, + 1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234, + 1,232,232,232,1,224,224,224,1,211,211,211,1,221,221,221,1,226,226,226, + 1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218, + 1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210, + 1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240, + 1,238,238,238,1,237,237,237,1,217,217,217,1,180,180,180,1,163,163,163, + 1,153,153,153,3,162,162,162,1,175,175,175,1,204,204,204,1,219,219,219, + 2,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211, + 1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242, + 1,240,240,240,1,235,235,235,1,191,191,191,1,154,154,154,1,162,160,160, + 1,187,180,180,1,208,199,200,1,225,210,212,1,209,196,197,1,188,179,180, + 1,162,159,159,1,154,154,154,1,169,169,169,1,210,210,210,1,217,217,217, + 1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210, + 1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,234,234,234, + 1,167,167,167,1,153,153,153,1,193,183,183,1,246,226,228,1,253,235,237, + 1,255,235,237,1,255,232,235,1,255,230,233,1,255,227,230,1,251,222,225, + 1,196,182,184,1,153,153,153,2,198,198,198,1,213,213,213,1,215,215,215, + 1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245, + 1,243,243,243,1,242,242,242,1,185,185,185,1,154,154,154,1,219,202,203, + 1,250,228,230,1,253,233,235,1,255,235,238,1,255,233,235,1,255,230,233, + 1,255,228,231,1,255,225,229,1,255,223,226,1,255,220,224,1,225,198,202, + 1,153,153,153,1,141,141,141,1,182,182,182,1,212,212,212,1,213,213,213, + 1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243, + 1,215,215,215,1,153,153,153,1,198,186,187,1,249,227,228,1,252,232,234, + 1,255,236,238,1,207,190,192,1,116,105,106,1,47,42,43,1,73,65,66, + 1,190,166,169,1,255,221,225,1,255,218,222,1,255,216,220,1,202,182,184, + 1,153,153,153,1,129,129,129,1,198,198,198,1,212,212,212,1,211,211,211, + 1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,167,166,166, + 1,169,165,166,1,246,225,226,1,251,231,232,1,254,236,238,1,241,221,223, + 1,15,14,14,1,122,110,111,1,207,183,187,1,124,109,110,1,10,9,9, + 1,238,204,208,1,255,216,221,1,255,214,218,1,253,211,216,1,170,163,164, + 1,147,146,146,1,145,145,145,1,205,205,205,1,211,211,211,1,210,210,210, + 1,208,208,208,1,245,245,245,1,237,237,237,1,153,153,153,1,203,191,192, + 1,250,230,231,1,253,235,237,1,255,235,237,1,146,133,135,1,46,41,42, + 1,255,227,230,1,255,225,228,1,255,222,226,1,55,47,48,1,140,119,121, + 1,255,214,219,1,255,212,217,2,207,184,187,1,153,153,153,1,109,109,109, + 1,180,180,180,1,209,209,209,1,210,210,210,1,208,208,208,1,245,245,245, + 1,218,218,218,1,153,153,153,1,223,207,209,1,253,233,235,1,255,235,238, + 1,255,233,235,1,255,230,233,1,251,224,227,1,255,225,229,1,255,223,226, + 1,249,215,219,1,42,36,37,1,149,126,129,1,255,212,217,3,227,196,199, + 1,153,153,153,1,115,115,115,1,154,154,154,1,207,207,207,1,210,210,210, + 1,208,208,208,1,245,245,245,1,202,202,202,1,153,153,153,1,243,225,227, + 1,255,236,238,1,255,233,236,1,255,231,234,1,255,228,231,1,255,226,229, + 1,255,223,227,1,250,217,221,1,82,70,71,1,56,47,48,1,246,205,210, + 1,255,212,217,3,246,207,211,1,153,153,153,1,125,125,125,1,132,132,132, + 1,205,205,205,1,210,210,210,1,208,208,208,1,245,245,245,1,209,209,209, + 1,153,153,153,1,236,221,223,1,255,234,236,1,255,232,234,1,255,229,232, + 1,255,226,230,1,255,224,227,1,255,221,225,1,101,87,88,1,47,40,41, + 1,235,197,201,1,255,212,217,4,237,202,206,1,153,153,153,1,119,119,119, + 1,112,112,112,1,204,204,204,1,210,210,210,1,208,208,208,1,245,245,245, + 1,227,227,227,1,153,153,153,1,217,204,206,1,255,232,235,1,255,230,232, + 1,255,227,230,1,255,224,228,1,255,222,226,1,249,214,218,1,3,3,3, + 1,208,175,179,1,255,212,217,5,217,190,193,1,153,153,153,1,107,107,107, + 1,112,112,112,1,204,204,204,1,210,210,210,1,208,208,208,1,245,245,245, + 1,242,242,242,1,156,156,156,1,195,186,187,1,255,230,233,1,255,228,231, + 1,255,225,228,1,255,223,226,1,255,220,224,1,238,203,207,1,103,87,88, + 1,247,205,210,1,255,212,217,5,195,177,180,1,152,152,152,1,101,101,101, + 1,131,131,131,1,204,204,204,1,210,210,210,1,208,208,208,1,245,245,245, + 1,243,243,243,1,183,183,183,1,155,154,154,1,236,214,216,1,255,226,229, + 1,255,223,227,1,255,221,225,1,255,218,222,1,239,202,206,1,167,139,143, + 1,242,201,206,1,255,212,217,4,236,201,205,1,154,153,153,1,133,133,133, + 1,101,101,101,1,152,152,152,1,207,207,207,1,210,210,210,1,208,208,208, + 1,245,245,245,1,243,243,243,1,232,232,232,1,158,158,158,1,171,166,167, + 1,253,223,226,1,255,221,225,1,255,219,223,1,255,216,221,1,208,174,178, + 1,0,0,0,1,215,179,183,1,255,212,217,3,253,211,216,1,171,163,164, + 1,150,151,152,1,88,128,147,1,105,107,108,1,178,178,178,1,209,209,209, + 1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242, + 1,206,206,206,1,153,153,153,1,178,170,171,1,243,211,215,1,255,217,221, + 1,255,214,219,1,255,212,217,5,243,205,210,1,178,167,169,1,153,153,153, + 1,140,173,190,1,102,164,195,1,84,136,162,1,183,185,186,1,211,211,211, + 1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242, + 1,239,239,239,1,192,192,192,1,153,152,152,1,157,155,155,1,211,188,191, + 1,241,204,208,1,255,212,217,3,241,204,208,1,211,187,189,1,157,155,155, + 1,152,152,153,1,150,176,189,1,167,202,221,1,134,183,208,1,103,164,195, + 1,84,137,163,1,190,192,193,1,210,210,210,1,208,208,208,1,245,245,245, + 1,243,243,243,1,242,242,242,1,240,240,240,1,234,234,234,1,191,191,191, + 1,147,146,146,1,153,153,153,2,157,155,156,1,172,163,164,1,157,155,156, + 1,153,153,153,2,140,139,139,1,97,139,160,1,116,172,201,1,148,191,213, + 1,167,202,221,1,135,183,208,1,103,164,195,1,87,139,165,1,185,187,188, + 1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240, + 1,238,238,238,1,233,233,233,1,213,213,213,1,151,151,151,1,129,129,129, + 1,135,135,135,1,142,142,142,1,133,133,133,1,123,123,123,1,114,114,114, + 1,106,106,106,1,105,111,114,1,90,147,176,1,116,172,200,1,148,191,213, + 1,167,202,221,1,135,183,208,1,103,164,195,1,84,137,163,1,183,185,186, + 1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238, + 1,237,237,237,1,234,234,234,1,226,226,226,1,192,192,192,1,162,162,162, + 1,137,137,137,1,117,117,117,1,116,116,116,1,134,134,134,1,157,157,157, + 1,183,183,183,1,192,198,201,1,93,150,179,1,116,172,200,1,148,191,213, + 1,167,202,221,1,135,183,208,1,103,164,195,1,95,135,155,1,245,245,245, + 1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237, + 1,235,235,235,1,234,234,234,1,229,229,229,1,225,225,225,1,222,222,222, + 1,218,218,218,1,217,217,217,2,219,219,219,1,218,218,218,1,219,219,219, + 1,199,205,208,1,94,151,180,1,116,172,200,1,148,191,213,1,167,203,221, + 1,134,182,205,1,98,115,124,1,245,245,245,1,243,243,243,1,242,242,242, + 1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234, + 1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226, + 1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218, + 1,197,203,206,1,94,151,179,1,116,172,200,1,147,189,210,1,117,128,134, + 1,94,94,94,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240, + 1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232, + 1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224,224, + 1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216, + 1,196,202,205,1,105,149,171,1,108,124,133,1,95,95,95,1,125,125,125, + 1,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9,116, + 100,111,99,107,102,111,114,109,0,10,116,116,97,98,119,105,100,103,101,116, + 4,116,97,98,115,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,103,1, + 9,98,111,117,110,100,115,95,99,121,3,198,0,7,97,110,99,104,111,114, + 115,11,0,11,116,97,98,95,111,112,116,105,111,110,115,11,15,116,97,98, + 111,95,100,114,97,103,115,111,117,114,99,101,13,116,97,98,111,95,100,114, + 97,103,100,101,115,116,13,116,97,98,111,95,111,112,112,111,115,105,116,101, + 23,116,97,98,111,95,100,98,108,99,108,105,99,107,101,100,116,97,98,102, + 105,114,115,116,20,116,97,98,111,95,104,105,110,116,99,108,105,112,112,101, + 100,116,101,120,116,0,21,116,97,98,95,102,114,97,109,101,46,98,117,116, + 116,111,110,115,108,97,115,116,9,20,116,97,98,95,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,21,116,97,98,95,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98, + 95,115,105,122,101,2,18,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfindinfilefo,''); +end. diff --git a/mseide-msegui/apps/ide/findinfilepage.mfm b/mseide-msegui/apps/ide/findinfilepage.mfm new file mode 100644 index 0000000..2688793 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfilepage.mfm @@ -0,0 +1,158 @@ +object findinfilepagefo: tfindinfilepagefo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 382 + bounds_y = 163 + bounds_cx = 573 + bounds_cy = 310 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = childscaled + container.bounds = ( + 0 + 0 + 573 + 310 + ) + icon.options = [bmo_masked] + ondestroy = formdestroy + onlayout = childscaled + moduleclassname = 'tmseform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -1879048187 + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 24 + bounds_cx = 571 + bounds_cy = 284 + anchors = [an_left, an_top, an_right, an_bottom] + fixcols.count = 1 + fixcols.items = < + item + width = 38 + textflags = [tf_right, tf_ycentered] + numstart = 1 + numstep = 1 + end> + rowcount = 1 + datacols.count = 1 + datacols.items = < + item[foundlist] + width = 1500 + options = [co_readonly, co_fill] + widthmin = 1500 + widgetname = 'foundlist' + dataclass = tgridrichstringdatalist + data = ( + ( + '' + ) + ) + end> + datarowheight = 16 + oncellevent = foundlistoncellevent + reffontheight = 14 + object foundlist: ttextedit + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048185 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 1500 + bounds_cy = 16 + optionsedit1 = [oe1_keyexecute, oe1_savestate] + optionsedit = [oe_readonly, oe_closequery, oe_checkmrcancel, oe_linebreak, oe_eatreturn, oe_exitoncursor] + oncellevent = foundlistoncellevent + reffontheight = 14 + end + end + object filename: tstringdisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 3 + bounds_x = 1 + bounds_y = 0 + bounds_cx = 406 + bounds_cy = 18 + bounds_cxmin = 140 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_ellipseleft] + reffontheight = 14 + end + object foundcount: tintegerdisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 407 + bounds_y = 0 + bounds_cx = 44 + bounds_cy = 18 + anchors = [an_top, an_right] + reffontheight = 14 + end + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + taborder = 5 + bounds_x = 453 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localcaption, as_localonexecute] + caption = '&Cancel' + onexecute = cancelonexecute + reffontheight = 14 + end + object again: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + taborder = 4 + bounds_x = 503 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption, as_localonexecute] + caption = '&again' + onexecute = againonexecute + reffontheight = 14 + end + object closepage: tstockglyphbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + bounds_x = 553 + bounds_y = 1 + bounds_cx = 18 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_checked + onexecute = closebuonexecute + reffontheight = 14 + end + object thread: tthreadcomp + onstart = threadonstart + onexecute = threadonexecute + onterminate = threadonterminate + left = 16 + top = 72 + end + object c: tstringcontainer + strings.data = ( + '*** CANCELED ***' + 'FINISHED' + ) + left = 136 + top = 64 + end +end diff --git a/mseide-msegui/apps/ide/findinfilepage.pas b/mseide-msegui/apps/ide/findinfilepage.pas new file mode 100644 index 0000000..4b1b659 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfilepage.pas @@ -0,0 +1,368 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit findinfilepage; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msegui,mseclasses,mseforms,msetabs,msetextedit,msewidgetgrid,msegrids, + msethreadcomp,findinfileform,msesimplewidgets,msedispwidgets,msestrings, + classes,mclasses,msestringcontainer; + +type + + tfindinfilepagefo = class(ttabform) + cancel: tbutton; + filename: tstringdisp; + foundcount: tintegerdisp; + foundlist: ttextedit; + grid: twidgetgrid; + again: tbutton; + thread: tthreadcomp; + closepage: tstockglyphbutton; + c: tstringcontainer; + procedure foundlistoncellevent(const sender: tobject; var info: celleventinfoty); + procedure threadonexecute(const sender: tthreadcomp); + procedure threadonstart(const sender: tthreadcomp); + procedure threadonterminate(const sender: tthreadcomp); + procedure cancelonexecute(const sender: tobject); + procedure closebuonexecute(const sender: TObject); + procedure againonexecute(const sender: TObject); + procedure childscaled(const sender: TObject); + procedure formdestroy(const sender: TObject); + private + finfo: findinfileinfoty; + procedure dorun; + protected + procedure addfoundline(const text: string; const linenr: integer; col: integer); + procedure startfile(const afilename: filenamety); + public + constructor create(const aowner: tcomponent; + const findinfo: findinfileinfoty); reintroduce; + procedure cancelsearch; + end; + +implementation +uses + findinfilepage_mfm,sourcepage,sourceform,mseeditglob,sysutils,mserichstring, + msegraphics,msestream,msefileutils,msesys,findinfiledialogform,msegraphutils, + projectoptionsform,msesystypes,mseformatstr,main; + +type + stringconsts = ( + canceled, //0 *** CANCELED *** + finished //1 FINISHED + ); + +{ tfindinfilepagefo} + +constructor tfindinfilepagefo.create(const aowner: tcomponent; + const findinfo: findinfileinfoty); +begin + finfo:= findinfo; + inherited create(aowner); + name:= ''; + dorun; +end; + +procedure tfindinfilepagefo.foundlistoncellevent(const sender: tobject; + var info: celleventinfoty); +var + page: tsourcepage; +begin + if iscellclick(info,[ccr_dblclick]) then begin + locateerrormessage(foundlist[info.cell.row],page); + if page <> nil then begin + with page.edit do begin + setselection(editpos,makegridcoord(editpos.col + length(finfo.findinfo.text), + editpos.row),true); + end; + end; + end; +end; + +procedure tfindinfilepagefo.cancelsearch; +begin + thread.terminate; + thread.waitfor; + filename.value:= c[ord(canceled)]; +end; + +procedure tfindinfilepagefo.startfile(const afilename: filenamety); +begin + application.lock; + try + filename.value:= afilename; + finally + application.unlock; + end; +end; + +procedure tfindinfilepagefo.addfoundline(const text: string; + const linenr: integer; col: integer); +const + maxfoundpos = 80; + maxcenteredpos = maxfoundpos div 2; + maxfoundlength = maxfoundpos + maxcenteredpos; +var + int1: integer; + str1,str2: msestring; +begin + if foundlist <> nil then begin + application.lock; + try + str1:= filename.value+'('+inttostrmse(linenr+1)+','+inttostrmse(col+1)+'): '; + if col > maxfoundpos then begin + int1:= col - maxcenteredpos; + str2:= '...'+msestring(copy(text,int1,maxfoundlength)); + col:= maxcenteredpos + 4; + if length(text) > length(str2) + int1 - 4 then begin + str2:= str2 + '...'; + end; + end + else begin + str2:= msestring(copy(text,1,maxfoundlength)); + if length(text) > length(str2) then begin + str2:= str2 + '...'; + end; + end; + int1:= foundlist.appendrow(str1+str2); + foundcount.value:= foundcount.value + 1; + updatefontstyle1(foundlist.datalist.richitemspo[int1]^.format,length(str1)+col, + length(finfo.findinfo.text),fs_bold,true); + finally + application.unlock; + end; + end; +end; + +procedure tfindinfilepagefo.threadonexecute(const sender: tthreadcomp); + + procedure searchstream(const stream: ttextstream; const afilename: filenamety); + var + str1: string; + begin + case projectoptions.e.encoding of + 1: begin + stream.encoding:= ce_utf8; + end; + 2: begin + stream.encoding:= ce_iso8859_1; + end; + end; + with sender,tfindinfilepagefo(datapo),finfo do begin + stream.buflen:= 4096; + with stream do begin + msesearchtext:= findinfo.text; + searchoptions:= findinfo.options; + startfile(afilename); + while searchnext and not terminated do begin + Position:= searchlinestartpos; + readln(str1); + addfoundline(str1,searchlinenumber,searchfoundpos-searchlinestartpos); + end; + end; + end; + end; + + procedure searchdirectory(const adir: filenamety); + var + stream1: ttextstream; + filelist: tfiledatalist; + int1,int2: integer; + ar1: filenamearty; + begin + with sender,tfindinfilepagefo(datapo),finfo do begin + filelist:= tfiledatalist.create; + filelist.options:= [flo_sortname]; + try + unquotefilename(adir,ar1); + for int2:= 0 to high(ar1) do begin + ar1[int2]:= filepath(ar1[int2],fk_file); + if fifo_subdirs in options then begin + {$ifndef FPC} + if filelist.adddirectory2(ar1[int2],fil_ext1,'', + [fa_dir],[],[],nil,true) then begin + {$else} + if filelist.adddirectory(ar1[int2],fil_ext1,'', + [fa_dir],[],[],nil,true) then begin + {$endif} + for int1:= 0 to filelist.count - 1 do begin + if terminated then begin + break; + end; + with filelist[int1] do begin + searchdirectory(ar1[int2]+'/'+ name); + end; + end; + end; + end; + filelist.clear; + {$ifndef FPC} + if filelist.adddirectory2(ar1[int2],fil_ext1,filemask, + [fa_all],[fa_dir],[],nil,true) then begin + {$else} + if filelist.adddirectory(ar1[int2],fil_ext1,filemask, + [fa_all],[fa_dir],[],nil,true) then begin + {$endif} + for int1:= 0 to filelist.count - 1 do begin + if terminated then begin + break; + end; + with filelist[int1] do begin + try + if ttextstream.trycreate( + stream1,ar1[int2]+'/'+name,fm_read) = sye_ok then begin + try + searchstream(stream1,stream1.filename); + finally + stream1.free; + end; + end; + except + end; + end; + end; + end; + end; + finally + filelist.Free; + end; + end; + end; //searchdirectory + +var + int1: integer; + stream1: ttextstream; + bo1: boolean; + mstr1: filenamety; + +begin + if finfo.source in [fs_inopenfiles,fs_incurrentfile] then begin + int1:= 0; + if finfo.source = fs_incurrentfile then begin + int1:= sourcefo.activepage.tabindex; + end; + with sender,tfindinfilepagefo(datapo),finfo do begin + while not terminated do begin + bo1:= false; + application.lock; + try + if int1 < sourcefo.count then begin + with sourcefo.items[int1] do begin + if fileloaded then begin + stream1:= ttextstream.create; //memorystream + edit.savetostream(stream1,false); + end + else begin + stream1:= ttextstream.create(filepath); + end; + application.unlock; + bo1:= true; + try + searchstream(stream1,filepath); + finally + stream1.free; + end; + end; + end + else begin + break; + end; + finally + if not bo1 then begin + application.unlock; + end; + end; + if finfo.source = fs_incurrentfile then begin + break; + end; + inc(int1); + end; + end; + end + else begin + if finfo.source = fs_inprojectdir then begin + application.lock(); + mstr1:= filedir(mainfo.projectname); + application.unlock(); + end + else begin + mstr1:= tfindinfilepagefo(sender.datapo).finfo.directory; + application.lock; + expandprmacros1(mstr1); + application.unlock; + end; + searchdirectory(mstr1); + end; +end; + +procedure tfindinfilepagefo.threadonstart(const sender: tthreadcomp); +begin + cancel.enabled:= true; + again.enabled:= false; +end; + +procedure tfindinfilepagefo.threadonterminate(const sender: tthreadcomp); +begin + if not application.terminated then begin + cancel.enabled:= false; + again.enabled:= true; + filename.value:= c[ord(finished)]; + end; +end; + +procedure tfindinfilepagefo.childscaled(const sender: TObject); +begin + placeyorder(0,[1],[cancel,grid],0); + aligny(wam_center,[cancel,filename,foundcount,again,closepage]); +end; + +procedure tfindinfilepagefo.closebuonexecute(const sender: TObject); +begin + release; +end; + +procedure tfindinfilepagefo.cancelonexecute(const sender: tobject); +begin + cancelsearch; +end; + +procedure tfindinfilepagefo.dorun; +begin + caption:= finfo.findinfo.text; + foundlist.clear; + foundcount.value:= 0; + thread.run(self); +end; + +procedure tfindinfilepagefo.againonexecute(const sender: TObject); +begin + findinfilefo.show; + if findinfiledialogexecute(finfo,true) then begin + dorun; + end; +end; + +procedure tfindinfilepagefo.formdestroy(const sender: TObject); +begin + thread.terminate; + thread.waitfor; +end; + +end. diff --git a/mseide-msegui/apps/ide/findinfilepage_mfm.pas b/mseide-msegui/apps/ide/findinfilepage_mfm.pas new file mode 100644 index 0000000..c4284ad --- /dev/null +++ b/mseide-msegui/apps/ide/findinfilepage_mfm.pas @@ -0,0 +1,184 @@ +unit findinfilepage_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,findinfilepage; + +const + objdata: record size: integer; data: array[0..3320] of byte end = + (size: 3321; data: ( + 84,80,70,48,17,116,102,105,110,100,105,110,102,105,108,101,112,97,103,101, + 102,111,16,102,105,110,100,105,110,102,105,108,101,112,97,103,101,102,111,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111, + 110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,126,1,8,98,111,117,110,100,115,95,121,3,163,0,9,98,111,117,110, + 100,115,95,99,120,3,61,2,9,98,111,117,110,100,115,95,99,121,3,54, + 1,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11, + 111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101, + 116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,18,99,111,110,116,97,105,110,101,114,46, + 111,110,108,97,121,111,117,116,7,11,99,104,105,108,100,115,99,97,108,101, + 100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,61,2,3,54,1,0,12,105,99,111,110,46,111,112,116,105, + 111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,0,9,111,110,100, + 101,115,116,114,111,121,7,11,102,111,114,109,100,101,115,116,114,111,121,8, + 111,110,108,97,121,111,117,116,7,11,99,104,105,108,100,115,99,97,108,101, + 100,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116, + 109,115,101,102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105,100, + 4,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111,99, + 117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115,101, + 119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,5,0,0,144,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,24,9,98,111,117,110,100,115,95,99,120,3,59,2, + 9,98,111,117,110,100,115,95,99,121,3,28,1,7,97,110,99,104,111,114, + 115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,13,102,105, + 120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108, + 115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,38,9,116,101, + 120,116,102,108,97,103,115,11,8,116,102,95,114,105,103,104,116,12,116,102, + 95,121,99,101,110,116,101,114,101,100,0,8,110,117,109,115,116,97,114,116, + 2,1,7,110,117,109,115,116,101,112,2,1,0,0,8,114,111,119,99,111, + 117,110,116,2,1,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116, + 2,1,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,9, + 102,111,117,110,100,108,105,115,116,1,5,119,105,100,116,104,3,220,5,7, + 111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121, + 7,99,111,95,102,105,108,108,0,8,119,105,100,116,104,109,105,110,3,220, + 5,10,119,105,100,103,101,116,110,97,109,101,6,9,102,111,117,110,100,108, + 105,115,116,9,100,97,116,97,99,108,97,115,115,7,23,116,103,114,105,100, + 114,105,99,104,115,116,114,105,110,103,100,97,116,97,108,105,115,116,4,100, + 97,116,97,1,1,6,0,0,0,0,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,16,11,111,110,99,101,108,108,101,118,101,110,116,7, + 20,102,111,117,110,100,108,105,115,116,111,110,99,101,108,108,101,118,101,110, + 116,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,9,116, + 116,101,120,116,101,100,105,116,9,102,111,117,110,100,108,105,115,116,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102, + 111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97, + 117,116,111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108, + 111,114,4,7,0,0,144,8,116,97,98,111,114,100,101,114,2,1,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 220,5,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111, + 110,108,121,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,108,105, + 110,101,98,114,101,97,107,12,111,101,95,101,97,116,114,101,116,117,114,110, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,0,11,111,110, + 99,101,108,108,101,118,101,110,116,7,20,102,111,117,110,100,108,105,115,116, + 111,110,99,101,108,108,101,118,101,110,116,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,11,116,115,116,114,105,110,103,100,105, + 115,112,8,102,105,108,101,110,97,109,101,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 3,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,150,1,9,98,111,117, + 110,100,115,95,99,121,2,18,12,98,111,117,110,100,115,95,99,120,109,105, + 110,3,140,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,9,116, + 101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114, + 101,100,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110, + 116,101,103,101,114,100,105,115,112,10,102,111,117,110,100,99,111,117,110,116, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3, + 151,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,44,9,98,111,117,110,100,115,95,99,121,2,18,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116, + 111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101, + 101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,5,99,111,108,111,114,4,3,0,0,128,8,116,97,98,111,114,100,101, + 114,2,5,8,98,111,117,110,100,115,95,120,3,197,1,8,98,111,117,110, + 100,115,95,121,2,1,9,98,111,117,110,100,115,95,99,120,2,50,9,98, + 111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97, + 116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16,97,115,95,108, + 111,99,97,108,100,105,115,97,98,108,101,100,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,7,38,67,97, + 110,99,101,108,9,111,110,101,120,101,99,117,116,101,7,15,99,97,110,99, + 101,108,111,110,101,120,101,99,117,116,101,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,5,97,103, + 97,105,110,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13, + 111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,13,111,119,95,109, + 111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,8, + 116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3, + 247,1,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100,115, + 95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,7,99,97,112,116,105,111,110,6,6,38,97,103,97,105, + 110,9,111,110,101,120,101,99,117,116,101,7,14,97,103,97,105,110,111,110, + 101,120,101,99,117,116,101,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,17,116,115,116,111,99,107,103,108,121,112,104,98,117,116, + 116,111,110,9,99,108,111,115,101,112,97,103,101,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99, + 111,108,111,114,4,3,0,0,128,8,98,111,117,110,100,115,95,120,3,41, + 2,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100,115,95, + 99,120,2,18,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,5,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103, + 101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,5,103,108,121,112,104,7,11,115,116,103,95,99,104,101,99,107,101, + 100,9,111,110,101,120,101,99,117,116,101,7,16,99,108,111,115,101,98,117, + 111,110,101,120,101,99,117,116,101,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,11,116,116,104,114,101,97,100,99,111,109,112,6, + 116,104,114,101,97,100,7,111,110,115,116,97,114,116,7,13,116,104,114,101, + 97,100,111,110,115,116,97,114,116,9,111,110,101,120,101,99,117,116,101,7, + 15,116,104,114,101,97,100,111,110,101,120,101,99,117,116,101,11,111,110,116, + 101,114,109,105,110,97,116,101,7,17,116,104,114,101,97,100,111,110,116,101, + 114,109,105,110,97,116,101,4,108,101,102,116,2,16,3,116,111,112,2,72, + 0,0,16,116,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,1, + 99,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,16,42,42,42, + 32,67,65,78,67,69,76,69,68,32,42,42,42,6,8,70,73,78,73,83, + 72,69,68,0,4,108,101,102,116,3,136,0,3,116,111,112,2,64,0,0, + 0) + ); + +initialization + registerobjectdata(@objdata,tfindinfilepagefo,''); +end. diff --git a/mseide-msegui/apps/ide/formdesigner.mfm b/mseide-msegui/apps/ide/formdesigner.mfm new file mode 100644 index 0000000..80eacdd --- /dev/null +++ b/mseide-msegui/apps/ide/formdesigner.mfm @@ -0,0 +1,338 @@ +object formdesignerfo: tformdesignerfo + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_hinton] + optionsskin = [osk_framebuttononly] + color = -1879048187 + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 0 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_buttonhints] + frame.grip_face.fade_pos.count = 1 + frame.grip_face.fade_pos.items = ( + 0 + ) + frame.grip_face.fade_color.count = 1 + frame.grip_face.fade_color.items = ( + -1610612717 + ) + frame.grip_face.localprops = [] + popupmenu = popupme + onenter = enterexe + onactivate = enterexe + visible = False + bounds_x = 68 + bounds_y = 277 + bounds_cx = 287 + bounds_cy = 300 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_mousewheel] + container.color = -1879048187 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.oncalcminscrollsize = calcscrollsize + container.bounds = ( + 0 + 0 + 287 + 300 + ) + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_cansize, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + dragdock.onbeforefloat = beffloatexe + dragdock.onfloat = floatexe + optionswindow = [wo_notaskbar] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + icon.transparentcolor = -2147483642 + icon.image = { + 00000000000000001800000018000000A4070000000000000000000000000000 + 0000000000000000000000000000000000000000FFFFFF19F2A69501DDD8D301 + F2A69501FF866D02794034019D534301BB625001D06D5902F7826A01D46F5B01 + FF866D04A0A0A00680808001FFFFFF01DDD8D30107EFFF01DDD8D301FF866D02 + 783F3301C96A5601B55F4D0187473A01D6705B018B493B01A3564601F27F6701 + FF866D03A0A0A001D4D4D40180808001A0A0A001D1D1D10180808002FFFFFF01 + F2A69501DDD8D301F2A69501FF866D02D46F5B01FF866D01DA735D01CC6B5701 + B45F4D01DE755F01B8614F01FD856C01FF866D03A0A0A001D4D4D40180808001 + A0A0A001D1D1D10180808002FFFFFF019718001080808007FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808019 + } + onclose = formdeonclose + left = 239 + top = 180 + moduleclassname = 'tdockform' + object popupme: tpopupmenu + menu.submenu.count = 33 + menu.submenu.items = < + item + caption = 'Show objectinspector' + state = [as_localcaption, as_localonexecute] + onexecute = doshowobjectinspector + end + item + caption = 'Show componentpalette' + state = [as_localcaption, as_localonexecute] + onexecute = doshowcomponentpalette + end + item + caption = 'Show as Text' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = doshowastext + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = hidecompact + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = hidewidgetact + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = togglehideact + end + item + action = showallact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Copy Component(s)' + name = 'copy' + state = [as_localcaption, as_localshortcut, as_localonexecute] + onexecute = copyexe + sc = ( + 1 + 16451 + ) + end + item + caption = 'Cut Component(s)' + name = 'cut' + state = [as_localcaption, as_localshortcut, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = cutexe + sc = ( + 1 + 16472 + ) + end + item + caption = 'Paste Component(s)' + name = 'paste' + state = [as_localcaption, as_localshortcut, as_localonexecute] + onexecute = pasteexe + sc = ( + 1 + 16470 + ) + end + item + caption = 'Delete Component(s)' + name = 'delete' + state = [as_localcaption, as_localshortcut, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = deleteexe + sc = ( + 1 + 263 + ) + end + item + caption = 'Undelete Component(s)' + name = 'undelete' + state = [as_localcaption, as_localonexecute] + onexecute = undeleteexe + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.findcompallact + caption = 'Find Component' + state = [as_localcaption] + end + item + caption = 'Select Childwidget' + name = 'selectchild' + state = [as_localcaption] + end + item + caption = '&Iconify' + name = 'iconify' + state = [as_localcaption, as_localonexecute] + onexecute = doiconify + end + item + caption = '&Deiconify' + name = 'deiconify' + state = [as_localcaption, as_localonexecute] + onexecute = dodeiconify + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Edit Component' + name = 'editcomp' + state = [as_localcaption, as_localonexecute] + onexecute = doeditcomponent + end + item + caption = 'Sync. to Font Height' + name = 'synctofo' + state = [as_localcaption, as_localonexecute] + onexecute = dosyncfontheight + end + item + caption = 'Bring to Front' + name = 'bringtofro' + state = [as_localcaption, as_localonexecute] + onexecute = dobringtofront + end + item + caption = 'Send to Back' + name = 'sendtoba' + state = [as_localcaption, as_localonexecute] + onexecute = dosendtoback + end + item + caption = 'Set Widget Order' + name = 'setwidgetord' + state = [as_localcaption, as_localonexecute] + onexecute = dosetwidgetorder + end + item + caption = 'Set Tab Order' + name = 'settabord' + state = [as_localcaption, as_localonexecute] + onexecute = dosettaborder + end + item + caption = 'Set Creation Order' + state = [as_localcaption, as_localonexecute] + onexecute = dosetcreationorder + end + item + caption = 'Revert to inherited' + name = 'revert' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = revertexe + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Touch Form' + state = [as_localcaption, as_localonexecute] + onexecute = dotouch + end + item + caption = 'Touch all Forms' + state = [as_localcaption, as_localonexecute] + onexecute = touchallexe + end + item + caption = 'Insert Submodule' + name = 'insertsub' + state = [as_localcaption, as_localonexecute] + onexecute = doinsertsubmodule + end + item + caption = 'Insert Component' + name = 'insertcomp' + state = [as_localcaption, as_localonexecute] + onexecute = doinsertcomponent + end> + left = 48 + top = 40 + end + object hidecompact: taction + caption = 'Hide &Components' + onchange = hidecompexe + left = 144 + top = 40 + end + object hidewidgetact: taction + caption = 'Hide &Widgets' + onupdate = updatewidgethideexe + onchange = hidewidgetexe + left = 144 + top = 56 + end + object togglehideact: taction + caption = '&Hide Widgets<>Components' + onexecute = togglehideexe + left = 144 + top = 72 + end + object showallact: taction + caption = '&Show all' + onexecute = showallexe + left = 144 + top = 88 + end + object c: tstringcontainer + strings.data = ( + 'Do you wish to revert to inherited' + 'the selected component?' + 'Do you want to touch all loaded forms?' + ) + left = 48 + top = 72 + end +end diff --git a/mseide-msegui/apps/ide/formdesigner.pas b/mseide-msegui/apps/ide/formdesigner.pas new file mode 100644 index 0000000..cf26f2d --- /dev/null +++ b/mseide-msegui/apps/ide/formdesigner.pas @@ -0,0 +1,4178 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit formdesigner; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msetypes,classes,mclasses,mseforms,mseguiglob,msegui,mseevent,msegraphutils, + msegraphics, + msedesignintf,mseclasses,msemenuwidgets,msemenus,msefiledialog,msedesigner, + typinfo,componentpaletteform,msestrings,msewidgets,msepointer, + mseglob{$ifndef mse_no_db}{$ifdef FPC},msereport{$endif}{$endif},msetimer, + mseact,mseactions,mseifiglob,msestringcontainer,mseificomp,mseificompglob, + msesimplewidgets,msestat,msedock; + +type + areaty = (ar_none,ar_component,ar_componentmove,ar_selectrect,ht_topleft, + ht_top,ht_topright,ht_right, + ht_bottomright,ht_bottom,ht_bottomleft,ht_left); + areasty = set of areaty; + markerty = (mt_topleft,mt_topright,mt_bottomright,mt_bottomleft); + +const + firsthandle = ht_topleft; + lasthandle = ht_left; + defaultgridsizex = 8; + defaultgridsizey = 8; + handlesize = 5; + componentsize = 24; + complabelleftmargin = 2; + complabelrightmargin = 2 + handlesize div 2; + movethreshold = 3; + +type + formselectedinfoty = record + selectedinfo: selectedinfoty; + rect: rectty; + nohandles: boolean; + handles: array[firsthandle..lasthandle] of rectty; + markers: array[markerty] of rectty; + end; + + pformselectedinfoty = ^formselectedinfoty; + + tformdesignerfo = class; + + markerkindty = (mak_none,mak_module,mak_all); + + tformdesignerselections = class(tdesignerselections) + private + fowner: tformdesignerfo; + finfovalid: boolean; + fmovingchecked: boolean; + fcandelete: boolean; + procedure paint(const canvas: tcanvas); + procedure beforepaintmoving; + procedure paintmoving(const canvas: tcanvas; const pos: pointty); + function move(const dist: pointty): boolean; + //false if nothing is moved + procedure resize(const dist: pointty); + procedure deletecomponents; + function getareainfo(const pos: pointty; out index: integer): areaty; + function getcandelete: boolean; + procedure updateinfos; + protected + function checkmarker(const ainfo: formselectedinfoty): markerkindty; + function getrecordsize: integer; override; + procedure externalcomponentchanged(const acomponent: tobject); + procedure removeforeign(const checkmove: boolean); + //removes form and components in other modules + property candelete: boolean read getcandelete; + public + constructor create(const owner: tformdesignerfo); + function assign(const source: idesignerselections): boolean; + //true if owned components involved + function remove(const ainstance: tcomponent): integer; override; + procedure change; override; + procedure dochanged; override; + procedure componentschanged; + function itempo(const index: integer): pformselectedinfoty; + end; + + selectmodety = (sm_select,sm_add,sm_flip,sm_remove); + + tformcontainer = class(tformscrollbox) + private + fdesignfo: tformdesignerfo; + protected + function isdesignwidget(): boolean; override; + procedure widgetregionchanged(const sender: twidget); override; + public + constructor create(const aowner: tformdesignerfo); + end; + + formdesignerstatety = (fds_loaded,fds_sizesyncing); + formdesignerstatesty = set of formdesignerstatety; + + tformdesignerdockcontroller = class(tformdockcontroller) + protected + procedure dostatplace(const aparent: twidget; + const avisible: boolean; arect: rectty); override; + end; + + tformdesignerfo = class(tdockform,iformdesigner,idesignnotification) + popupme: tpopupmenu; + hidecompact: taction; + hidewidgetact: taction; + togglehideact: taction; + showallact: taction; + c: tstringcontainer; + procedure doshowobjectinspector(const sender: tobject); + procedure doshowcomponentpalette(const sender: tobject); + procedure doshowastext(const sender: tobject); + procedure doeditcomponent(const sender: tobject); + procedure doinsertsubmodule(const sender: tobject); + procedure dobringtofront(const sender: tobject); + procedure dosendtoback(const sender: tobject); + procedure dosettaborder(const sender: tobject); + procedure dosyncfontheight(const sender: tobject); + procedure copyexe(const sender: TObject); + procedure pasteexe(const sender: TObject); + procedure deleteexe(const sender: TObject); + procedure undeleteexe(const sender: TObject); + procedure cutexe(const sender: TObject); + procedure calcscrollsize(const sender: tscrollingwidgetnwr; + var asize: sizety); + procedure formdeonclose(const sender: TObject); + procedure revertexe(const sender: TObject); + procedure doinsertcomponent(const sender: TObject); + procedure dotouch(const sender: TObject); + procedure dosetcreationorder(const sender: TObject); + procedure doiconify(const sender: TObject); + procedure dodeiconify(const sender: TObject); + procedure hidecompexe(const sender: TObject); + procedure updatewidgethideexe(const sender: tcustomaction); virtual; + procedure hidewidgetexe(const sender: TObject); + procedure togglehideexe(const sender: TObject); + procedure showallexe(const sender: TObject); + procedure touchallexe(const sender: TObject); + procedure beffloatexe(const sender: twidget; var arect: rectty); + procedure floatexe(const sender: TObject); + procedure enterexe(const sender: TObject); + procedure dosetwidgetorder(const sender: TObject); + private + fdesigner: tdesigner; + fform: twidget; + fmodule: tmsecomponent; + fmoduleintf: pdesignmoduleintfty; + fmodulesetting: integer; + fmoduleoptions: moduleoptionsty; + fsizeerrorcount: integer; + fupdatecaptionpending: boolean; + + fpickpos: pointty; + fmousepos: pointty; + fpickwidget: twidget; + fsizerect,factsizerect: rectty; + fxorpicoffset: pointty; + fxorpicactive: boolean; + fxorpicshowed: boolean; + factarea: areaty; + fmovearea: areaty; + factcompindex: integer; + fselecting: integer; + fgridsizex: integer; + fgridsizey: integer; + fsnaptogrid: boolean; + fshowgrid: boolean; + fdelobjs: objinfoarty; + fclipinitcomps: boolean; + finitcompsoffset: pointty; + fuseinitcompsoffset: boolean; + fcompsoffsetused: boolean; + fclickedcompbefore: tcomponent; + fselectwidget: twidget; + fselectcomp: tcomponent; + fclientsizevalid: boolean; + fcompoffsbefore: pointty; + fsizebefore: sizety; + fshift: pointty; + fshiftroot: tcomponent; + fhintedcomp: tcomponent; + procedure drawgrid(const canvas: tcanvas); + procedure hidexorpic(const canvas: tcanvas); + procedure showxorpic(const canvas: tcanvas); + procedure paintxorpic(const canvas: tcanvas); + procedure checkdelobjs(const aitem: tcomponent); + + procedure doaddcomponent(acomponent: tcomponent); + procedure doinitcomponent(const acomponent: tcomponent; + const parent: tcomponent); + procedure shiftcomp(child: tcomponent); + + procedure setshowgrid(const avalue: boolean); + procedure setgridsizex(const avalue: integer); + procedure setgridsizey(const avalue: integer); + procedure doundelete; + procedure dopaste(const usemousepos: boolean; const adata: string); + procedure docopy(const noclear: boolean); + procedure docut; + procedure clientsizechanged; + procedure adjustchildcomponentpos(var apos: pointty); + procedure readjustchildcomponentpos(var apos: pointty); + procedure widgetscrolled(const sender: tobject); + + + procedure setmodule(const value: tmsecomponent); + function getselections: tformdesignerselections; + function filterfindcomp(const acomponent: tcomponent): boolean; + function getmodulerect: rectty; + procedure setactarea(const avalue: areaty); + property actarea: areaty read factarea write setactarea; + protected + fselections: tformdesignerselections; + fformcont: tformcontainer; + ffostate: formdesignerstatesty; + fmoduleinfo: pmoduleinfoty; + fmodulepos: pointty; + fmodulesize: sizety; + //iformdesigner + function getmodulepos_x(): integer; + function getmodulepos_y(): integer; + procedure setmodulepos_x(const avalue: integer); + procedure setmodulepos_y(const avalue: integer); + function getdockcontroller(): tdockcontroller; + function isdesignwidget(): boolean; override; + + function getsnaptogrid: boolean; virtual; + function getshowgrid: boolean; virtual; + function getgridsizex: integer; virtual; + function getgridsizey: integer; virtual; + + procedure designmouseevent(var info: moeventinfoty; + capture: twidget); override; + procedure designkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); override; + + function getcomponentrect(const component: tcomponent; + const shiftoffset: boolean): rectty; + //embedded + + function dosnaptogrid(const apos: pointty): pointty; + function snaptogriddelta(const apos: pointty): pointty; + + function iswidgetcomp(const acomp: tcomponent): boolean; + function getcomponentrect1(const component: tcomponent): rectty; + //top level + function componentscrollsize: sizety; + function componentoffset(): pointty; + function componentatpos(const apos: pointty): tcomponent; + function widgetatpos(const apos: pointty; const onlywidgets: boolean; + const everywhere: boolean = false): twidget; + procedure updateselections; + + procedure setrootpos(const component: tcomponent; const apos: pointty); + procedure beginselect; + procedure endselect; + procedure updatecursorshape(const ashiftstate: shiftstatesty; + const area: areaty); + procedure updateclickedcomponent; + procedure deletecomponent(const component: tcomponent); + procedure selectparentwidget(const awidget: twidget); + procedure domodified; + + procedure selectchildexec(const sender: tobject); + procedure dopopup(var info: mouseeventinfoty); reintroduce; + + property selections: tformdesignerselections read getselections; + procedure formcontainerscrolled(); + procedure updatemodulename(); + procedure doupdatecaption(); + procedure updatedockinfo(); + procedure updateformcont(); + procedure checksynctoformsize(); + procedure checksynctomodulepos(); + procedure formcontainerwidgetregionchanged(const sender: twidget); + procedure rootchanged(const aflags: rootchangeflagsty); override; + procedure parentchanged(); override; + procedure poschanged; override; + procedure sizechanged; override; + procedure clientrectchanged(); override; + procedure doasyncevent(var atag: integer); override; + procedure dobeforepaint(const canvas: tcanvas); override; + procedure doafterpaint(const canvas: tcanvas); override; + procedure doactivate; override; + procedure validaterename(acomponent: tcomponent; + const curname, newname: string); override; + procedure notification(acomponent: tcomponent; + operation: toperation); override; + procedure doshow; override; + + procedure componentselected( + const aselections: tformdesignerselections); virtual; + function getmoduleparent: twidget; virtual; + function getmodulesize: sizety; virtual; + function insertoffset: pointty; virtual; + function gridoffset: pointty; virtual; + function gridrect: rectty; virtual; + function markerrect: rectty; virtual; + function widgetrefpoint: pointty; virtual; + function compplacementrect: rectty; virtual; + procedure recalcclientsize; + procedure setcomponentscrollsize(const avalue: sizety); virtual; + function fixformsize: boolean; virtual; + function getdesignrect: rectty; virtual; + procedure setdesignrect(const arect: rectty); virtual; + function checkdelete(): boolean; virtual; + function dodelete: boolean; //true if ok + procedure componentmoving(const apos: pointty); virtual; + procedure placecomponent(const component: tcomponent; const apos: pointty; + aparent: tcomponent = nil); virtual; + function getmoduleoptions: moduleoptionsty; + procedure setmoduleoptions(const aoptions: moduleoptionsty); virtual; + + //idesignnotification + procedure itemdeleted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure iteminserted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure itemsmodified(const adesigner: idesigner; const aitem: tobject); + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure selectionchanged(const adesigner: idesigner; + const aselection: idesignerselections); + procedure moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; + const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + + public + constructor create(const aowner: tcomponent; const adesigner: tdesigner; + const aintf: pdesignmoduleintfty; + const amoduleinfo: pmoduleinfoty); reintroduce; virtual; + + destructor destroy(); override; + procedure updateprojectoptions(); + + function designnotification: idesignnotification; + //idesignform + property moduleoptions: moduleoptionsty read getmoduleoptions + write setmoduleoptions; + function clickedcomponent: tcomponent; + property modulerect: rectty read getmodulerect; + procedure updatecaption(); + procedure placemodule(); virtual; + procedure beginplacement(); + procedure endplacement(); + procedure beginstreaming(); virtual; + procedure endstreaming(); virtual; + procedure findcompdialog(); + procedure clearselection; + procedure selectcomponent(const component: tcomponent; + mode: selectmodety = sm_select); + //component can be nil + + property module: tmsecomponent read fmodule write setmodule; + property form: twidget read fform; + + property snaptogrid: boolean read getsnaptogrid write + fsnaptogrid default true; + property showgrid: boolean read getshowgrid write setshowgrid default true; + property gridsizex: integer read getgridsizex write setgridsizex + default defaultgridsizex; + property gridsizey: integer read getgridsizey write setgridsizey + default defaultgridsizey; + end; + + designformclassty = class of tformdesignerfo; +{ + tdesignwindow = class(twindow) + private + protected + procedure movewindowrect(const dist: pointty; const rect: rectty); override; + public + constructor create(const aowner: tformdesignerfo); +// destructor destroy; override; + end; +} +procedure registerdesignmoduleclass(const aclass: tcomponentclass; + const aintf: pdesignmoduleintfty; + const adesignformclass: designformclassty = nil); +function createdesignmodule(const amodule: pmoduleinfoty; designmoduleclassname: string; + const aclassname: pshortstring): tmsecomponent; +function createdesignform(const aowner: tdesigner; + const amodule: pmoduleinfoty): tformdesignerfo; +function selectinheritedmodule(const amodule: pmoduleinfoty; + const caption: msestring = ''): pmoduleinfoty; +function getdesignform(const acomp: tcomponent): tformdesignerfo; + +implementation +uses + formdesigner_mfm,mselist,msekeyboard,msebits,sysutils, + msestockobjects,msedrawtext,selectsubmoduledialogform,mseshapes,settaborderform, + msedatalist,objectinspector,projectoptionsform,main,msedatamodules, + setcreateorderform,componentstore,msearrayutils,actionsmodule,msecomptree + {$ifndef FPC},classes_del{$endif}; + +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + stringconsts = ( + sc_wishrevert, //0 Do you wish to revert to inherited + sc_selectedcomp, //1 the selected component? + sc_touchall //2 Do you want to touch all loaded forms? + ); + + tcomponent1 = class(tcomponent); + tmsecomponent1 = class(tmsecomponent); + twidget1 = class(twidget); + tmseform1 = class(tmseform); + tframe1 = class(tframe); + tscrollingwidget1 = class(tscrollingwidget); + twindow1 = class(twindow); + tcustomframe1 = class(tcustomframe); + + designerfoeventty = (fde_none,fde_syncsize,fde_updatecaption,fde_scrolled, + fde_showastext); + + designmoduleinfoty = record + classtype: tcomponentclass; + intf: pdesignmoduleintfty; + formclass: designformclassty; + end; + designmoduleinfoarty = array of designmoduleinfoty; + + tdesignmoduleinfoar = class + private + flist: designmoduleinfoarty; + end; + +var + fregistereddesignmoduleclasses: tdesignmoduleinfoar; + +function registereddesignmoduleclasses: tdesignmoduleinfoar; +begin + if fregistereddesignmoduleclasses = nil then begin + fregistereddesignmoduleclasses:= tdesignmoduleinfoar.create; + end; + result:= fregistereddesignmoduleclasses; +end; + +procedure registerdesignmoduleclass(const aclass: tcomponentclass; + const aintf: pdesignmoduleintfty; + const adesignformclass: designformclassty = nil); +var + int1: integer; +begin + with registereddesignmoduleclasses do begin + for int1:= 0 to high(flist) do begin + with flist[int1] do begin + if classtype = aclass then begin + intf:= aintf; + formclass:= adesignformclass; + exit; + end; + end; + end; + registerclass(aclass); + setlength(flist,high(flist)+2); + with flist[high(flist)] do begin + classtype:= aclass; + intf:= aintf; + formclass:= adesignformclass; + end; + end; +end; + +function createdesignmodule(const amodule: pmoduleinfoty; designmoduleclassname: string; + const aclassname: pshortstring): tmsecomponent; +var + int1: integer; +begin + with amodule^ do begin + if designmoduleclassname = '' then begin + designmoduleclassname:= defaultmoduleclassname; + end; + designmoduleclassname:= uppercase(designmoduleclassname); + with registereddesignmoduleclasses do begin + for int1:= 0 to high(flist) do begin + with flist[int1] do begin + if uppercase(classtype.classname) = designmoduleclassname then begin + designformclass:= formclass; + moduleintf:= intf; + result:= intf^.createfunc(classtype,aclassname); + exit; + end; + end; + end; + end; + end; + raise exception.Create(ansistring(actionsmo.c[ord(ac_unknownmodclass)]+ + msestring(aclassname^) +'": "'+ msestring(designmoduleclassname)+'".')); +end; + +function createdesignform(const aowner: tdesigner; + const amodule: pmoduleinfoty): tformdesignerfo; +begin + with amodule^ do begin + if designformclass = nil then begin + designformclass:= tformdesignerfo; + end; + result:= designformclassty(designformclass).create(nil,aowner, + moduleintf,amodule); + result.module:= instance; + end; +end; +{ +function getcomponentrect(const sender: twidget; + const component: tcomponent): rectty; +begin + result.pos:= getcomponentpos(component); + addpoint1(result.pos,tdesignwindow(sender.window).componentoffset); + result.cx:= componentsize + complabelleftmargin + + sender.getcanvas.getstringwidth(component.name) + + complabelrightmargin; + result.cy:= componentsize; +end; + +function getcomponentrect1(const sender: twidget; const component: tcomponent; + const module: tcomponent): rectty; +var + comp1: tcomponent; + bo1: boolean; +begin + result:= getcomponentrect(sender,component); + if module is twidget then begin + comp1:= component; + bo1:= false; + while (comp1 <> module) and (comp1 <> nil) do begin + if comp1 is twidget then begin + if not bo1 then begin + tdesignwindow(sender.window).adjustchildcomponentpos(result.pos); + bo1:= true; + end; + addpoint1(result.pos,twidget(comp1).pos); + end; + comp1:= comp1.owner; + end; + end; +end; +} + +{ tformdesignerselections } + +constructor tformdesignerselections.create(const owner: tformdesignerfo); +begin + fowner:= owner; + inherited create; +end; + +function tformdesignerselections.assign( + const source: idesignerselections): boolean; + //true if owned components involved +var + amodule: tmsecomponent; + ar1: booleanarty; + + procedure checkowned; + var + int1: integer; + comp1: tcomponent; + po1: pformselectedinfoty; + begin + result:= false; + setlength(ar1,count); + po1:= datapo; + for int1:= 0 to count - 1 do begin + result:= po1^.selectedinfo.instance = amodule; + comp1:= po1^.selectedinfo.instance; + while comp1 <> nil do begin + if comp1 = amodule then begin + result:= true; + ar1[int1]:= true; + break; + end; + comp1:= comp1.owner; + end; + inc(po1); + end; + end; + +var + int1: integer; + po1: pformselectedinfoty; + comp1: tcomponent; + bo1,bo2: boolean; +begin + result:= false; + ar1:= nil; + amodule:= fowner.fmodule; + checkowned; + inherited assign(source); + if not result then begin + checkowned; + end; + if result then begin + bo1:= false; + bo2:= false; + po1:= datapo; + for int1:= 0 to count - 1 do begin + comp1:= po1^.selectedinfo.instance; + while (comp1 <> nil) and (comp1 <> amodule) do begin + if ar1[int1] then begin + if (comp1 is tmsedatamodule) and (comp1 <> + po1^.selectedinfo.instance) then begin + with tmsedatamodule(comp1) do begin + options:= options - [dmo_iconic]; + end; + end; + + if fowner.iswidgetcomp(comp1) then begin + bo1:= true; + end + else begin + bo2:= true; + end; + end; + comp1:= comp1.owner; + end; + inc(po1); + end; + with fowner do begin + if bo1 then begin + hidewidgetact.checked:= false; + end; + if bo2 then begin + hidecompact.checked:= false; + end; + end; + end; +end; + +procedure tformdesignerselections.updateinfos; +var + marker: markerty; + int1: integer; +begin + if not finfovalid then begin + fcandelete:= count > 0; + for int1:= 0 to count - 1 do begin + with itempo(int1)^,selectedinfo do begin + if fowner.iswidgetcomp(instance) then begin + with twidget1(instance) do begin + nohandles:= ws1_nodesignhandles in fwidgetstate1; + fcandelete:= fcandelete and not (ws1_nodesigndelete in fwidgetstate1); + rect:= makerect(translatewidgetpoint(pos,parentwidget,fowner),size); + end; + end + else begin + nohandles:= false; + if instance is tcomponent then begin + rect:= fowner.getcomponentrect1(tcomponent(instance)); + end + else begin + rect:= nullrect; + end; + end; + with rect do begin + centerrect(pos,handlesize,handles[ht_topleft]); + centerrect(makepoint(x+cx div 2,y),handlesize,handles[ht_top]); + centerrect(makepoint(x+cx-1,y),handlesize,handles[ht_topright]); + centerrect(makepoint(x+cx-1,y+cy div 2),handlesize,handles[ht_right]); + centerrect(makepoint(x+cx-1,y+cy-1),handlesize,handles[ht_bottomright]); + centerrect(makepoint(x+cx div 2,y+cy-1),handlesize,handles[ht_bottom]); + centerrect(makepoint(x,y+cy-1),handlesize,handles[ht_bottomleft]); + centerrect(makepoint(x,y+cy div 2),handlesize,handles[ht_left]); + + for marker:= low(marker) to high(marker) do begin + markers[marker].cx:= handlesize; + markers[marker].cy:= handlesize; + end; + markers[mt_topleft].pos:= pos; + markers[mt_topright].x:= x + cx - handlesize; + markers[mt_topright].y:= y; + markers[mt_bottomright].x:= x + cx - handlesize; + markers[mt_bottomright].y:= y + cy - handlesize; + markers[mt_bottomleft].x:= x; + markers[mt_bottomleft].y:= y + cy - handlesize; + + end; + end; + end; + end; + finfovalid:= true; +end; + +procedure tformdesignerselections.beforepaintmoving; +begin + if not fmovingchecked then begin + removeforeign(true); + fmovingchecked:= true; + end; + updateinfos; +end; + +procedure tformdesignerselections.paintmoving(const canvas: tcanvas; + const pos: pointty); +var + int1: integer; + po1: pformselectedinfoty; +begin +// beforepaintmoving; + with canvas do begin + save; + move(pos); + rasterop:= rop_xor; + for int1:= 0 to count-1 do begin + po1:= itempo(int1); + if po1^.selectedinfo.instance <> fowner.module then begin + drawframe(itempo(int1)^.rect,-2,cl_white); + end; + end; + restore; + end; +end; + +function tformdesignerselections.checkmarker( + const ainfo: formselectedinfoty): markerkindty; +begin + result:= mak_none; + with ainfo do begin + if not nohandles then begin + if fowner.module.checkowned(selectedinfo.instance) then begin + if (selectedinfo.instance <> fowner.module) then begin + if (selectedinfo.instance is twidget) and + (ws1_nodesignmove in + twidget1(selectedinfo.instance).fwidgetstate1) then begin + result:= mak_module; + end + else begin + result:= mak_all; + end; + end + else begin + if (fowner.parentwidget <> nil) and (fowner.fform <> nil) and + (fowner.fformcont.visible) then begin //docked + result:= mak_module; + end; + end; + end; + end; + end; +end; + +procedure tformdesignerselections.paint(const canvas: tcanvas); + +var + int1: integer; + handle: areaty; + marker: markerty; + po1: pformselectedinfoty; +begin + updateinfos(); + po1:= datapo; + with canvas do begin + if count > 1 then begin + for int1:= 0 to count - 1 do begin + case checkmarker(po1^) of + mak_all: begin + for marker:= low(markerty) to high(markerty) do begin + fillrect(po1^.markers[marker],cl_dkgray); + end; + end; + mak_module: begin + canvas.save(); + canvas.addcliprect(fowner.markerrect); + fillrect(po1^.markers[mt_bottomright],cl_dkgray); + canvas.restore; + end; + end; + inc(po1); + end; + end + else begin + for int1:= 0 to count - 1 do begin + case checkmarker(po1^) of + mak_all: begin + for handle:= firsthandle to lasthandle do begin + fillrect(po1^.handles[handle],cl_black); + end; + end; + mak_module: begin + canvas.save(); + canvas.addcliprect(fowner.markerrect); + fillrect(po1^.handles[ht_right],cl_black); + fillrect(po1^.handles[ht_bottomright],cl_black); + fillrect(po1^.handles[ht_bottom],cl_black); + canvas.restore(); + end; + end; + inc(po1); + end; + end; + end; +end; + +function tformdesignerselections.move(const dist: pointty): boolean; +var + int1,int2: integer; + widget1: twidget; + comp1,comp2: tcomponent; + rect1,rect2: rectty; + pt1: pointty; + ar1: componentarty; +begin + result:= false; + if (dist.x <> 0) or (dist.y <> 0) then begin + setlength(ar1,count); + for int1:= 0 to high(ar1) do begin + comp1:= items[int1]; + while fowner.iswidgetcomp(comp1) and + (cs_parentwidgetrect in twidget1(comp1).fmsecomponentstate) do begin + comp1:= twidget(comp1).parentwidget; + end; + ar1[int1]:= comp1; + end; + for int1:= 0 to high(ar1) do begin + comp1:= ar1[int1]; + for int2:= int1 + 1 to high(ar1) do begin + if ar1[int2] = comp1 then begin + ar1[int2]:= nil; //remove duplicates + end; + end; + end; + for int1:= 0 to count - 1 do begin + comp1:= ar1[int1]; + if comp1 <> nil then begin + with itempo(int1)^,selectedinfo do begin + if fowner.iswidgetcomp(comp1) and (comp1 <> fowner.module) then begin + if not nohandles then begin + widget1:= twidget(comp1).parentwidget; + while widget1 <> nil do begin + if (widget1 <> fowner.form) and (indexof(widget1) >= 0) then begin + break; //moved by parent + end; + widget1:= widget1.parentwidget; + end; + if widget1 = nil then begin + with twidget(comp1) do begin + pos:= addpoint(pos,dist); + result:= true; + end; + end; + end; + end + else begin + comp2:= tcomponent(comp1).owner; + while comp2 <> nil do begin + if (comp2 <> fowner.module) and + (fowner.iswidgetcomp(comp2) or isdatasubmodule(comp2)) and + (indexof(comp2) >= 0) then begin + break; //moved by owner + end; + comp2:= comp2.owner; + end; + if comp2 = nil then begin + rect1:= fowner.getcomponentrect1(tcomponent(comp1)); + fowner.invalidaterect(rect1); + pt1:= rect1.pos; + addpoint1(rect1.pos,dist); + with fowner do begin + rect2:= compplacementrect; + if form <> nil then begin + shiftinrect(rect1,rect2); + end + else begin + if rect1.x < rect2.x then begin + rect1.x:= rect2.x; + end; + if rect1.y < rect2.y then begin + rect1.y:= rect2.y; + end; + end; + end; + setcomponentpos(comp1,addpoint(getcomponentpos(comp1), + subpoint(rect1.pos,pt1))); + fowner.invalidaterect(rect1); + result:= true; + end; + end; + end; + end; + end; + componentschanged; + end; +end; + +procedure tformdesignerselections.resize(const dist: pointty); +var + int1: integer; +begin + if (dist.x <> 0) or (dist.y <> 0) then begin + for int1:= 0 to count - 1 do begin + with itempo(int1)^,selectedinfo do begin + if not nohandles then begin + if fowner.iswidgetcomp(instance) then begin + with twidget(instance) do begin + size:= sizety(addpoint(pointty(size),dist)); + end; + end + else begin + if isdatasubmodule(instance) then begin + with tmsedatamodule(instance) do begin + size:= sizety(addpoint(pointty(size),dist)); + end; + end; + end; + end; + end; + end; + componentschanged; + end; +end; + +procedure tformdesignerselections.change; +begin + finfovalid:= false; + fmovingchecked:= false; + inherited; +end; + +procedure tformdesignerselections.dochanged; +begin + inherited; + fowner.invalidate; +end; + +procedure tformdesignerselections.componentschanged; +var + int1: integer; +begin + change; + for int1:= 0 to count - 1 do begin + fowner.fdesigner.componentmodified(items[int1]); + end; +end; + +procedure tformdesignerselections.externalcomponentchanged( + const acomponent: tobject); +begin + finfovalid:= false; + if count > 0 then begin + fowner.invalidate; + end; +end; + +const + validhandles: array[markerkindty] of areasty = ( + [], //mak_none + [ht_right,ht_bottomright,ht_bottom], //mak_module + [ht_topleft,ht_top,ht_topright,ht_right, + ht_bottomright,ht_bottom,ht_bottomleft,ht_left] //mak_all + ); + +function tformdesignerselections.getareainfo(const pos: pointty; + out index: integer): areaty; +var + handle: areaty; + int1: integer; + po1: pformselectedinfoty; + markerkind1: markerkindty; + bo1: boolean; +begin + updateinfos; + result:= ar_none; + index:= -1; + if pointinrect(pos,fowner.markerrect) then begin + bo1:= pointinrect(pos,fowner.gridrect); + po1:= datapo; + if count = 1 then begin + markerkind1:= checkmarker(po1^); + if (markerkind1 = mak_module) or bo1 then begin + with po1^,selectedinfo do begin + if not nohandles then begin + if instance is tcomponent then begin + if isdatasubmodule(instance) or fowner.iswidgetcomp(instance) and + not (cs_parentwidgetrect in + twidget1(instance).fmsecomponentstate) then begin + for handle:= firsthandle to lasthandle do begin + if pointinrect(pos,handles[handle]) then begin + if handle in validhandles[markerkind1] then begin + result:= handle; + index:= 0; + exit; + end; + end; + end; + end; + if pointinrect(pos,rect) then begin + result:= ar_component; + index:= 0; + exit; + end; + end; + end; + end; + end; + end + else begin + for int1:= 0 to count - 1 do begin + with po1^,selectedinfo do begin + if not nohandles then begin + if pointinrect(pos,rect) and (instance is tcomponent) and + (bo1 or (checkmarker(po1^) = mak_module)) then begin + result:= ar_component; + index:= int1; + break; + end; + end; + end; + inc(po1); + end; + end; + end; +end; + +procedure tformdesignerselections.deletecomponents; +begin + fowner.fDesigner.DeleteSelection; +end; + +function tformdesignerselections.getrecordsize: integer; +begin + result:= sizeof(formselectedinfoty); +end; + +function tformdesignerselections.itempo( + const index: integer): pformselectedinfoty; +begin + result:= pformselectedinfoty(getitempo(index)); +end; + +function tformdesignerselections.remove( + const ainstance: tcomponent): integer; +begin + if ainstance = fowner.fpickwidget then begin + fowner.fpickwidget:= nil; + end; + result:= inherited remove(ainstance); +end; + +procedure tformdesignerselections.removeforeign(const checkmove: boolean); + //removes form and components in other modules +var + int1: integer; + co1: tcomponent; +begin + beginupdate; + for int1:= count - 1 downto 0 do begin + co1:= items[int1]; + if (co1 = fowner.module) or not fowner.module.checkowned(co1) or + (checkmove and (co1 is twidget) and + (ws1_nodesignmove in twidget1(co1).fwidgetstate1)) then begin + delete(int1); + end; + end; + endupdate; + fowner.updateselections; +end; + +function tformdesignerselections.getcandelete: boolean; +begin + updateinfos; + result:= fcandelete; +end; + +{ tformcontainer } + +constructor tformcontainer.create(const aowner: tformdesignerfo); +begin + fdesignfo:= aowner; + inherited create(nil,aowner,false); + with tcustomframe1(fframe),fi.innerframe do begin + left:= 0; + top:= 0; + right:= 0; + bottom:= 0; + internalupdatestate(); + end; + createface(); + face.image.source:= mainfo.formbg; + face.image.alignment:= [al_tiled]; + color:= cl_background; + optionsskin:= [osk_framebuttononly]; + updateskin(); +end; + +procedure tformcontainer.widgetregionchanged(const sender: twidget); +begin + inherited; + fdesignfo.formcontainerwidgetregionchanged(sender); +end; + +function tformcontainer.isdesignwidget: boolean; +begin + result:= true; +end; + +{ tformdesignerfo } + +constructor tformdesignerfo.create(const aowner: tcomponent; + const adesigner: tdesigner; + const aintf: pdesignmoduleintfty; + const amoduleinfo: pmoduleinfoty); +begin + fdesigner:= adesigner; + fmoduleintf:= aintf; + fmoduleinfo:= amoduleinfo; + + fshowgrid:= true; + fsnaptogrid:= true; + fgridsizex:= defaultgridsizex; + fgridsizey:= defaultgridsizey; + fselections:= tformdesignerselections.create(self); + fformcont:= tformcontainer.create(self); + fdragdock:= tformdesignerdockcontroller.create(self); + + createwindow(); + inherited create(aowner); + updateprojectoptions(); + designnotifications.registernotification(idesignnotification(self)); + include(ffostate,fds_loaded); +end; + +destructor tformdesignerfo.destroy; +begin + if fwindow <> nil then begin + fwindow.unregisteronscroll(@widgetscrolled); + end; + designer.modules.designformdestroyed(self); + fmodule.free(); + designnotifications.unregisternotification(idesignnotification(self)); + inherited; + fformcont.free(); + fselections.free(); +end; + +procedure tformdesignerfo.rootchanged(const aflags: rootchangeflagsty); +begin + if (rcf_windowremove in aflags) and (fwindow <> nil) then begin + fwindow.unregisteronscroll(@widgetscrolled); + end; + inherited; + if (rcf_windowset in aflags) then begin + window.registeronscroll(@widgetscrolled); + end; +end; + +procedure tformdesignerfo.parentchanged(); +begin + inherited; +// checksynctoformsize(); + updateformcont(); + updatedockinfo(); +end; + +procedure tformdesignerfo.ValidateRename(AComponent: TComponent; + const CurName, NewName: string); +begin + inherited; + if (fdesigner <> nil) and (acomponent <> nil) and + not (csdestroying in acomponent.componentstate) then begin + fdesigner.validaterename(acomponent,curname,newname); + end; +end; + +procedure tformdesignerfo.notification(acomponent: tcomponent; + operation: toperation); +begin + if (operation = opremove) then begin + if (acomponent = fmodule) then begin + fmodule:= nil; + end; + if (acomponent = fhintedcomp) then begin + fhintedcomp:= nil; + end; + end; + inherited; +end; +{ +procedure tformdesignerfo.createwindow; +begin + tdesignwindow.create(self); +end; +} +function tformdesignerfo.designnotification: idesignnotification; +begin + result:= idesignnotification(self); +end; + +function tformdesignerfo.getcomponentrect1(const component: tcomponent): rectty; +var + comp1: tcomponent; + bo1: boolean; +begin + result:= getcomponentrect(component,true); + comp1:= component.owner; + while comp1 <> nil do begin + if isdatasubmodule(comp1) then begin //adjust submodulepos + addpoint1(result.pos,getcomponentpos(comp1)); + end; + comp1:= comp1.owner; + end; + if fform <> nil then begin + comp1:= component.owner; + bo1:= false; + while (comp1 <> module) and (comp1 <> nil) do begin + if iswidgetcomp(comp1) then begin + if not bo1 then begin + adjustchildcomponentpos(result.pos); + bo1:= true; + end; + addpoint1(result.pos,twidget(comp1).pos); + end; + comp1:= comp1.owner; + end; + end; +end; + +function tformdesignerfo.iswidgetcomp(const acomp: tcomponent): boolean; +begin + result:= (acomp is twidget) and (form <> nil) and + (twidget(acomp).parentwidget <> nil); +end; + +procedure tformdesignerfo.paintxorpic(const canvas: tcanvas); +begin + if fxorpicactive then begin + canvas.save; + canvas.setcliprect(markerrect); + case actarea of + firsthandle..lasthandle: begin + with canvas do begin + save; + rasterop:= rop_xor; + drawframe(factsizerect,-2,cl_white); + restore; + end; + end; + ar_componentmove: begin + fselections.paintmoving(canvas,fxorpicoffset); + end; + ar_selectrect: begin + with canvas do begin + drawxorframe(fpickpos,fxorpicoffset,1,stockobjects.bitmaps[stb_block3]); + end; + end; + end; + canvas.restore; + end; +end; + +procedure tformdesignerfo.hidexorpic(const canvas: tcanvas); +begin + if fxorpicshowed then begin + paintxorpic(canvas); + fxorpicshowed:= false; + end; +end; + +procedure tformdesignerfo.showxorpic(const canvas: tcanvas); +begin + if not fxorpicshowed then begin + paintxorpic(canvas); + fxorpicshowed:= true; + end; +end; + +procedure tformdesignerfo.adjustchildcomponentpos(var apos: pointty); +begin + subpoint1(apos,componentoffset); + addpoint1(apos,widgetrefpoint); +end; + +procedure tformdesignerfo.readjustchildcomponentpos(var apos: pointty); +begin + addpoint1(apos,componentoffset); + subpoint1(apos,widgetrefpoint); +end; + +procedure tformdesignerfo.widgetscrolled(const sender: tobject); +begin + fselections.change(); +end; + +function tformdesignerfo.getcomponentrect(const component: tcomponent; + const shiftoffset: boolean): rectty; +var + bo1: boolean; +begin + result.pos:= getcomponentpos(component); + if shiftoffset then begin + addpoint1(result.pos,componentoffset); + end; + bo1:= (component is tmsedatamodule) and + (csinline in tmsedatamodule(component).componentstate); + if bo1 and not (dmo_iconic in tmsedatamodule(component).options) then begin + result.size:= tmsedatamodule(component).size; + end + else begin + result.cx:= complabelleftmargin + + getcanvas.getstringwidth(msestring(component.name)) + + complabelrightmargin; + if not bo1 then begin + result.cx:= result.cx + componentsize; + end; + result.cy:= componentsize; + end; +end; + +function tformdesignerfo.componentscrollsize: sizety; + + procedure check(const acomponent: tcomponent; const shift: pointty); + var + int1,int2: integer; + component: tcomponent; + rect1: rectty; + begin + if acomponent <> nil then begin + with acomponent do begin + for int1:= 0 to componentcount - 1 do begin + component:= components[int1]; + if not iswidgetcomp(component) then begin + rect1:= getcomponentrect(component,false); + addpoint1(rect1.pos,shift); + int2:= rect1.x + rect1.cx; + if int2 > result.cx then begin + result.cx:= int2; + end; + int2:= rect1.y + rect1.cy; + if int2 > result.cy then begin + result.cy:= int2; + end; + if isdatasubmodule(component) then begin + check(component,rect1.pos); + end; + end; + end; + end; + end; + end; //check + +begin + result:= nullsize; + check(fmodule,nullpoint); + inc(result.cx,handlesize); + inc(result.cy,handlesize); +end; + +procedure tformdesignerfo.doaddcomponent(acomponent: tcomponent); +var + comp1: tcomponent; + comps: tfplist; +begin + comp1:= acomponent.owner; + if (comp1 <> nil) and not issubcomponent(fmodule,comp1) then begin + {$ifdef FPC}{$warnings off}{$endif} + with tcomponent1(comp1) do begin + {$ifdef FPC}{$warnings on}{$endif} + comps:= fcomponents; + fcomponents:= nil; //do not propagate freenotifiaction to children + comp1.removecomponent(acomponent); + if comps <> nil then begin + comps.remove(acomponent); + if comps.count = 0 then begin + comps.free; + end + else begin + fcomponents:= comps; + end; + end; + end; + end; + fdesigner.addcomponent(module,acomponent); +// if csinline in component.ComponentState then begin + if acomponent.ComponentState * [csancestor,csinline] <> [] then begin + tcomponent1(acomponent).getchildren( + {$ifdef FPC}@{$endif}doaddcomponent,acomponent); + if comp1 <> nil then begin + tcomponent1(acomponent).getchildren( + {$ifdef FPC}@{$endif}doaddcomponent,comp1); + end; + end + else begin +// if comp1 <> nil then begin //else submodule + tcomponent1(acomponent).getchildren( + {$ifdef FPC}@{$endif}doaddcomponent,comp1); + end; +end; + +procedure tformdesignerfo.shiftcomp(child: tcomponent); +begin + setcomponentpos(child,addpoint(getcomponentpos(child),fshift)); + tcomponent1(child).getchildren(@shiftcomp,fshiftroot); +end; + +procedure tformdesignerfo.doinitcomponent(const acomponent: tcomponent; + const parent: tcomponent); +var + rect1: rectty; + pt1,pt2: pointty; +begin + doaddcomponent(acomponent); + if (acomponent is twidget) and (parent is twidget) then begin + with twidget(acomponent) do begin + if fuseinitcompsoffset then begin + pt1:= finitcompsoffset; + subpoint1(finitcompsoffset,pos); + fcompsoffsetused:= true; + fuseinitcompsoffset:= false; + end + else begin + if fcompsoffsetused then begin + pt1:= addpoint(pos,finitcompsoffset); + end + else begin + pt1:= addpoint(pos,twidget(parent).containeroffset); + end; + end; + end; + twidget(parent).insertwidget(twidget(acomponent),pt1); + if fclipinitcomps then begin + rect1:= twidget(acomponent).widgetrect; + shiftinrect(rect1,twidget(acomponent).parentwidget.clientwidgetrect); + twidget(acomponent).widgetrect:= rect1; + end; + end + else begin + pt2:= getcomponentpos(acomponent); + if fuseinitcompsoffset then begin + pt1:= finitcompsoffset; + subpoint1(finitcompsoffset,pt2); + fcompsoffsetused:= true; + fuseinitcompsoffset:= false; + end + else begin + pt1:= pt2; + if fcompsoffsetused then begin + addpoint1(pt1,finitcompsoffset); + end; + end; + setcomponentpos(acomponent,pt1); + fshiftroot:= acomponent.owner; + fshift:= subpoint(pt1,pt2); + tcomponent1(acomponent).getchildren(@shiftcomp,fshiftroot); + end; +end; + +procedure tformdesignerfo.docopy(const noclear: boolean); +var + int1: integer; + widget1: twidget; +begin + fselections.remove(module); + fselections.copytoclipboard; + if not noclear then begin + if form = nil then begin + selectcomponent(fmodule); + end + else begin + widget1:= nil; + if (fselections.count > 0) and iswidgetcomp(fselections[0]) then begin + widget1:= twidget(fselections[0]).parentofcontainer; + for int1:= 1 to fselections.count - 1 do begin + if not iswidgetcomp(fselections[int1]) or + (twidget(fselections[int1]).parentofcontainer <> widget1) then begin + widget1:= nil; //no common parent + break; + end; + end; + end; + if widget1 = nil then begin + selectcomponent(module); + end + else begin + selectcomponent(widget1); + end; + end; + end; +end; + +procedure tformdesignerfo.docut(); +begin + docopy(true); + dodelete(); +end; + +procedure tformdesignerfo.dopaste(const usemousepos: boolean; + const adata: string); +var + comp1: tcomponent; + bo1: boolean; +begin + try +// if form <> nil then begin + fclipinitcomps:= not usemousepos; + comp1:= module; + bo1:= true; + fuseinitcompsoffset:= usemousepos; + fcompsoffsetused:= false; + finitcompsoffset:= dosnaptogrid(fmousepos); + with fselections do begin + if count = 1 then begin + comp1:= items[0]; + if iswidgetcomp(comp1) then begin + bo1:= form.checkdescendent(twidget(comp1)); + if usemousepos then begin + finitcompsoffset:= + translatewidgetpoint(finitcompsoffset,self,twidget(comp1)); + end; + end; + end; + if bo1 then begin + clear; + if adata <> '' then begin + pastefromobjecttext(adata,module,comp1, + {$ifdef FPC}@{$endif}doinitcomponent); + end + else begin + pastefromclipboard(module,comp1,{$ifdef FPC}@{$endif}doinitcomponent); + end; + updateselections; + designer.componentmodified(module); + end; + end; + finally + fclipinitcomps:= false; + end; + clientsizechanged; +end; + +procedure tformdesignerfo.doundelete(); +var + int1: integer; + ar1: componentarty; +begin + if fdelobjs <> nil then begin + with fselections do begin + clear; + for int1:= 0 to high(fdelobjs) do begin + with fdelobjs[int1] do begin + ar1:= pastefromobjecttext(objtext,owner,parent, + {$ifdef FPC}@{$endif}doinitcomponent); + if ar1 <> nil then begin + if (owner <> nil) and (ownerindex >= 0) then begin + ar1[0].componentindex:= ownerindex; + end; + if (parent <> nil) and (parentindex >= 0) then begin + {$warnings off} + tcomponent1(parent).setchildorder(ar1[0],parentindex); + {$warnings on} + end; + end; + if parent <> nil then begin + + designer.componentmodified(parent); + end + else begin + designer.componentmodified(owner); + end; + end; + end; + for int1:= count-1 downto 0 do begin + if isembedded(items[int1]) then begin + delete(int1); + end; + end; + end; + updateselections; + fdelobjs:= nil; + clientsizechanged; + end; +end; + +function tformdesignerfo.dodelete(): boolean; +var + int1: integer; +begin + result:= false; + if checkdelete() then begin + with fselections do begin + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if componentstate * [csancestor,csinline] = [csancestor] then begin + showmessage(actionsmo.c[ord(ac_inheritedcomp)]+msestring(name)+ + actionsmo.c[ord(ac_cannotdel)],actionsmo.c[ord(ac_error)]); + exit; + end; + end; + end; + removeforeign(false); + fdelobjs:= fselections.getobjinfoar; + deletecomponents; + end; + // domodified; + clientsizechanged; + result:= true; + end; +end; + + +procedure tformdesignerfo.selectchildexec(const sender: tobject); +var + ar1: msestringarty; + comp1: tcomponent; +begin + with tmenuitem(sender) do begin + ar1:= splitstring(caption,widechar(' ')); + if fselectwidget <> nil then begin + comp1:= fselectwidget.findlogicalchild(ansistring(ar1[0])); + end + else begin + comp1:= fselectcomp.findcomponent(ansistring(ar1[0])); + end; + if comp1 <> nil then begin + selectcomponent(comp1,sm_select); + end; + end; +end; + +procedure tformdesignerfo.dopopup(var info: mouseeventinfoty); + +var + bo1,bo2,bo3,bo4: boolean; + item1: tmenuitem; + ar1: msestringarty; + ar2: componentarty; + int1: integer; + selectcomp: tcomponent; + comp1: tcomponent; +begin + with popupme,menu do begin + selectcomp:= nil; + if fselections.count = 1 then begin + selectcomp:= fselections[0]; + end; + bo1:= (fselections.count > 0) and (fselections[0] <> module); + bo2:= bo1 and fselections.candelete; + itembyname('copy').enabled:= bo1; + itembyname('cut').enabled:= bo2; + itembyname('delete').enabled:= bo2; + itembyname('undelete').enabled:= fdelobjs <> nil; + itembyname('paste').enabled:= iswidgetcomp(selectcomp) or (fform = nil); + itembyname('editcomp').enabled:= designer.componentcanedit; + { + bo1:= not( + (fselections.count <> 1) or + not(fselections.items[0] is twidget) or + not fowner.checkdescendent(twidget(fselections.items[0])) + ); + } + bo1:= iswidgetcomp(selectcomp) and + checkdescendent(twidget(selectcomp)); + itembyname('insertsub').enabled:= bo1 or (selectcomp = module) or + isdatasubmodule(selectcomp); + + itembyname('revert').enabled:= (fselections.count = 1) and + (fselections[0].componentstate * [csinline,csancestor] <> []); + itembyname('insertcomp').enabled:= designer.hascurrentcomponent and + (fselections.count = 1); + itembyname('bringtofro').enabled:= bo1; + itembyname('sendtoba').enabled:= bo1; + + bo3:= false; + bo4:= false; + for int1:= 0 to fselections.count - 1 do begin + comp1:= fselections[int1]; + if not (comp1 is tmsedatamodule) or + not (csinline in comp1.componentstate) then begin + bo3:= false; + bo4:= false; + break; + end; + if dmo_iconic in tmsedatamodule(comp1).options then begin + bo4:= true; + end + else begin + bo3:= true; + end; + end; + itembyname('iconify').enabled:= bo3; + itembyname('deiconify').enabled:= bo4; + + itembyname('setwidgetord').enabled:= bo1; + itembyname('settabord').enabled:= bo1 and + (twidget(fselections.items[0]).parentwidget.childrencount >= 2); + itembyname('synctofo').enabled:= fselections.count > 0; + item1:= itembyname('selectchild'); + item1.enabled:= iswidgetcomp(selectcomp) and + (twidget(selectcomp).container.widgetcount > 0) or + isdatasubmodule(selectcomp) and + (selectcomp.componentcount > 0); + if item1.enabled then begin + if iswidgetcomp(selectcomp) then begin + fselectwidget:= twidget(selectcomp); + ar2:= componentarty(fselectwidget.getlogicalchildren); + end + else begin + fselectwidget:= nil; + fselectcomp:= selectcomp; + setlength(ar2,fselectcomp.componentcount); + for int1:= 0 to high(ar2) do begin + ar2[int1]:= fselectcomp.components[int1]; + end; + end; + setlength(ar1,length(ar2)); + for int1:= 0 to high(ar1) do begin + with ar2[int1] do begin + ar1[int1]:= msestring(name + ' (' + classname+')'); + end; + end; + sortarray(ar1); + item1.submenu.count:= length(ar1); + for int1:= 0 to high(ar1) do begin + with item1.submenu[int1] do begin + caption:= ar1[int1]; + onexecute:= {$ifdef FPC}@{$endif}selectchildexec; + end; + end; + end; + show(self,info); + item1.submenu.clear; + end; +end; + +function tformdesignerfo.widgetatpos(const apos: pointty; + const onlywidgets: boolean; const everywhere: boolean = false): twidget; +var + widgetinfo: widgetatposinfoty; +begin + result:= nil; + if everywhere or pointinrect(apos,gridrect) then begin + fillchar(widgetinfo,sizeof(widgetinfo),0); + with widgetinfo do begin + pos:= translatewidgetpoint(apos,self,form); +// pos:= subpoint(apos,form.rootpos); + if onlywidgets then begin + childstate:= [ws_designing,ws_iswidget,ws_isvisible]; + end + else begin + childstate:= [ws_isvisible]; + end; + parentstate:= [ws_isvisible]; + end; + result:= form.widgetatpos(widgetinfo); + end; +end; + +procedure tformdesignerfo.clientsizechanged(); +begin + fclientsizevalid:= false; +end; + +procedure tformdesignerfo.poschanged(); +begin + inherited; + if not (fos_statreading in fformstate) and (fmodulesetting = 0) and + (fparentwidget = nil) then begin //not docked + fmodulepos:= translatewidgetpoint(paintpos,self,nil); + doModified; + end; + updatedockinfo(); +end; + +procedure tformdesignerfo.sizechanged(); +begin + inherited; + updatedockinfo(); +end; + +procedure tformdesignerfo.drawgrid(const canvas: tcanvas); +var + po1: pointty; + rect1,rect2: rectty; + endy: integer; + offset: pointty; + points1: pointarty; + int1,gridcx,gridcy: integer; +begin + if showgrid then begin + rect2:= gridrect; + msegraphutils.intersectrect(canvas.clipbox,rect2,rect1); + offset:= gridoffset; + gridcx:= gridsizex; + gridcy:= gridsizey; + with rect1 do begin + po1.x:= ((x - offset.x) div gridcx) * gridcx + offset.x; + po1.y:= ((y - offset.y) div gridcy) * gridcy + offset.y; + endy:= y + cy; + end; + setlength(points1, rect1.cx div gridcx + 2); + for int1:= 0 to high(points1) do begin + points1[int1].x:= po1.x; + inc(po1.x,gridcx); + end; + while po1.y < endy do begin + for int1:= 0 to high(points1) do begin + points1[int1].y:= po1.y; + end; + canvas.drawpoints(points1,cl_black); + inc(po1.y,gridcy); + end; + end; +end; + +procedure tformdesignerfo.clearselection(); +begin + fdesigner.noselection; +end; + +procedure tformdesignerfo.deletecomponent(const component: tcomponent); +begin + fdesigner.selectcomponent(component); + fdesigner.deleteselection(true); + domodified; + clientsizechanged; +end; + +procedure tformdesignerfo.selectcomponent(const component: tcomponent; +// const bymouse: boolean; + mode: selectmodety = sm_select); +begin + if component <> nil then begin + if mode = sm_remove then begin + fselections.remove(component); + factcompindex:= -1; + end + else begin + if mode = sm_select then begin + fselections.clear; + end; + factcompindex:= fselections.indexof(component); + if factcompindex < 0 then begin + factcompindex:= fselections.add(component); + end + else begin + if mode = sm_flip then begin + fselections.remove(component); + factcompindex:= -1; + end; + end; + end; + if factcompindex < 0 then begin + actarea:= ar_none; + end; + updateselections; + end; +end; + +procedure tformdesignerfo.selectparentwidget(const awidget: twidget); +var + int1: integer; +begin + with fselections do begin + beginupdate; + try + for int1:= count-1 downto 0 do begin + with itempo(int1)^ do begin + if (selectedinfo.instance is twidget) and + awidget.checkdescendent(twidget(selectedinfo.instance)) then begin + delete(int1); + end; + end; + end; + add(awidget); + factcompindex:= indexof(awidget); + finally + endupdate; + end; + end; + updateselections; +end; + +procedure tformdesignerfo.setrootpos(const component: tcomponent; + const apos: pointty); +begin + setcomponentpos(component,apos); +end; + +procedure tformdesignerfo.updateselections; +begin + if fselecting = 0 then begin + case fselections.count of + 0: begin + fdesigner.SelectComponent(nil); + end; + 1: begin + designer.SelectComponent(fselections[0]); + end + else begin + fdesigner.SetSelections(idesignerselections(fselections)); + end; + end; + end; +end; + +procedure tformdesignerfo.updateclickedcomponent; +begin + objectinspectorfo.clickedcomponentchanged(clickedcomponent); +end; + +procedure tformdesignerfo.beginselect; +begin + inc(fselecting); + fselections.beginupdate; +end; + +procedure tformdesignerfo.endselect; +begin + dec(fselecting); + fselections.endupdate; + if fselecting = 0 then begin + updateselections; + end; +end; + +procedure tformdesignerfo.domodified; +begin + invalidate; + if fds_loaded in ffostate then begin + fdesigner.componentmodified(fmodule); + end; +end; + +procedure tformdesignerfo.methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; const aname: string; + const atype: ptypeinfo); +begin + //dummy +end; + +procedure tformdesignerfo.methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; const newname, oldname: string; + const atypeinfo: ptypeinfo); +begin + //dummy +end; + +procedure tformdesignerfo.showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); +begin + //dummy +end; + +procedure tformdesignerfo.closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); +begin + //dummy +end; + +procedure tformdesignerfo.moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + //dummy +end; + +procedure tformdesignerfo.moduledeactivated(const adesigner: idesigner; const amodule: tmsecomponent); +begin + //dummy +end; + +procedure tformdesignerfo.checkdelobjs(const aitem: tcomponent); +var + int1: integer; +begin + for int1:= 0 to high(fdelobjs) do begin + with fdelobjs[int1] do begin + if (owner = aitem) or (parent = aitem) then begin + owner:= nil; + parent:= nil; + objtext:= ''; + end; + end; + end; +end; + +procedure tformdesignerfo.moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + checkdelobjs(amodule); +end; + +procedure tformdesignerfo.ItemDeleted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + fselections.remove(aitem); + checkdelobjs(aitem); +end; + +procedure tformdesignerfo.ItemInserted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + //dummy +end; + +procedure tformdesignerfo.ItemsModified(const ADesigner: IDesigner; + const AItem: tobject); +begin + fselections.externalcomponentchanged(aitem); + if isdatasubmodule(aitem,false,true) then begin //iconic state could be changed + clientsizechanged; + end; +end; + +procedure tformdesignerfo.componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); +begin + if (amodule = fmodule) then begin + if not (aitem is twidget) then begin + fclientsizevalid:= false; + end; + updatemodulename(); + end; +end; + +procedure tformdesignerfo.moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin + //dummy +end; + +procedure tformdesignerfo.instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin + //dummy +end; + +procedure tformdesignerfo.setshowgrid(const avalue: boolean); +begin + if fshowgrid <> avalue then begin + fshowgrid:= avalue; + invalidate(); + end; +end; + +procedure tformdesignerfo.setgridsizex(const avalue: integer); +begin + if fgridsizex <> avalue then begin + fgridsizex:= avalue; + invalidate(); + end; +end; + +procedure tformdesignerfo.setgridsizey(const avalue: integer); +begin + if fgridsizey <> avalue then begin + fgridsizey:= avalue; + invalidate(); + end; +end; + +procedure tformdesignerfo.updateprojectoptions(); +begin + with projectoptions do begin + showgrid:= e.showgrid; + snaptogrid:= e.snaptogrid; + gridsizex:= e.gridsizex; + gridsizey:= e.gridsizey; + if not e.noformdesignerdocking xor (frame.grip_size <> 0) then begin + beginplacement(); + if not e.noformdesignerdocking then begin + frame.grip_size:= 10; + end + else begin + frame.grip_size:= 0; + dragdock.optionsdock:= dragdock.optionsdock - [od_top,od_background]; + dragdock.float(); + end; + if not fixformsize then begin + checksynctoformsize(); + end; + endplacement(); + end; + end; + invalidate(); +end; + +procedure tformdesignerfo.beforemake(const adesigner: idesigner; + const maketag: integer; var abort: boolean); +begin + //dummy +end; + +procedure tformdesignerfo.aftermake(const adesigner: idesigner; + const exitcode: integer); +begin + //dummy +end; + +procedure tformdesignerfo.beforefilesave(const adesigner: idesigner; + const afilename: filenamety); +begin + //dummy +end; + +function tformdesignerfo.componentoffset: pointty; +begin +// result:= tformdesignerfo(fowner).gridrect.pos; + result:= gridoffset; +end; + +function tformdesignerfo.snaptogriddelta(const apos: pointty): pointty; +begin + if snaptogrid then begin + result.x:= roundint(apos.x,gridsizex); + result.y:= roundint(apos.y,gridsizey); + end + else begin + result:= apos; + end; +end; + +function tformdesignerfo.dosnaptogrid(const apos: pointty): pointty; +begin + if snaptogrid then begin + result:= snaptogriddelta(subpoint(apos,gridoffset)); + addpoint1(result,gridoffset); + end + else begin + result:= apos; + end; +end; + + +procedure tformdesignerfo.selectionchanged(const adesigner: idesigner; + const aselection: idesignerselections); +begin + try + fselections.beginupdate; + if fselections.assign(aselection) then begin + componentselected(fselections); + invalidate(); + end; + finally + fselections.decupdate; + end; +end; + +function tformdesignerfo.componentatpos(const apos: pointty): tcomponent; + +var + isdatamodule: boolean; + toplevel: boolean; + compoff,widoff: boolean; + + function checkcomponent(const component: tcomponent; + const pos: pointty; const shiftoffset: boolean): tcomponent; + var + int1: integer; + pt1: pointty; + bo1,bo2: boolean; + shift1: boolean; + rect1: rectty; + comp1: tcomponent; + begin + result:= nil; + bo2:= iswidgetcomp(component); + if ((bo2 and widoff) or (not bo2 and compoff)) and + (component.owner <> nil) then begin + exit; + end; + bo1:= not isdatamodule and bo2 and + (twidget(component).parentwidget <> nil); + bo2:= false; + shift1:= shiftoffset; //for chidren + pt1:= pos; + rect1:= getcomponentrect(component,shiftoffset); + if bo1 and not toplevel then begin + subpoint1(pt1,twidget(component).pos); + if (component.owner = module) and (module is twidget) then begin +// tdesignwindow(twidget(component).window).readjustchildcomponentpos(pt1); + readjustchildcomponentpos(pt1); + end; + end + else begin + if isdatasubmodule(component) then begin + bo2:= pointinrect(pt1,rect1); + subpoint1(pt1,rect1.pos); + shift1:= false; + end; + end; + if toplevel or + (not isdatamodule and bo1 or bo2) and + not (cssubcomponent in component.componentstyle) and + (component.componentstate * [csinline,csancestor] <> []) then begin + toplevel:= false; + for int1:= component.componentcount - 1 downto 0 do begin + comp1:= component.components[int1]; + if isdatasubmodule(comp1) then begin + result:= checkcomponent(comp1,pt1,shift1); + if result <> nil then begin + exit; + end; + end; + end; + for int1:= component.componentcount - 1 downto 0 do begin + comp1:= component.components[int1]; + if not isdatasubmodule(comp1) then begin + result:= checkcomponent(comp1,pt1,shift1); + if result <> nil then begin + exit; + end; + end; + end; + end; + if not bo1 {or isdatamodule} then begin + if pointinrect(pos,rect1) then begin + result:= component; + end; + end; + end; + +begin + isdatamodule:= fform = nil; + widoff:= hidewidgetact.checked; + compoff:= hidecompact.checked; + toplevel:= true; + result:= checkcomponent(fmodule,apos,true); + if result = fmodule then begin + result:= nil; + end; +end; + + +procedure tformdesignerfo.doafterpaint(const canvas: tcanvas); +var + offs: pointty; + gridrect1: rectty; + + procedure clipchildren(const acomp: tcomponent; const aindex: integer; + const shiftoffset: boolean); + var + int1: integer; + comp1: tcomponent; + rect1: rectty; + begin + for int1:= aindex to acomp.componentcount - 1 do begin + comp1:= acomp.components[int1]; + if isdatasubmodule(comp1) then begin + rect1:= mr(getcomponentpos(comp1),tmsedatamodule(comp1).size); + if shiftoffset then begin + addpoint1(rect1.pos,offs); + end; + canvas.subcliprect(rect1); + end; + end; + end; + +var + level: integer; + + procedure drawcomponent(const component: tcomponent); + var + rect1: rectty; + int1: integer; + isroot,iswidget,issub: boolean; + comp1: tcomponent; +// bo1: boolean; + label + endlab; + begin + isroot:= level = 0; + inc(level); + if not (cssubcomponent in component.componentstyle) then begin + iswidget:= false; + issub:= false; + if isroot then begin + iswidget:= true; + end + else begin + iswidget:= iswidgetcomp(component); + if not iswidget then begin + issub:= isdatasubmodule(component); + end; + end; + if iswidget then begin + if isroot then begin + rect1:= gridrect1; + end + else begin + if hidewidgetact.checked then begin + goto endlab; + end; + rect1:= twidget(component).widgetrect; + if level = 2 then begin + addpoint1(rect1.pos,gridrect1.pos); + end; + end + end + else begin + rect1:= getcomponentrect(component,level <= 2); + end; + if not (iswidget or issub) then begin + if isdatasubmodule(component,true) then begin + canvas.fillrect(rect1,cl_ltgray); + drawtext(canvas,msestring(component.name),rect1,[tf_ycentered,tf_xcentered], + stockobjects.fonts[stf_default]); + end + else begin + rect1.cx:= rect1.cx - complabelrightmargin; + drawtext(canvas,msestring(component.name),rect1,[tf_ycentered,tf_right], + stockobjects.fonts[stf_default]); + rect1.cx:= rect1.cy; + registeredcomponents.drawcomponenticon(component,canvas,rect1); + end; + end + else begin + if component.componentcount > 0 then begin + canvas.save; + if not issub then begin + canvas.intersectcliprect(rect1); + end; + if not isroot then begin + canvas.move(rect1.pos); + end; + clipchildren(component,0,isroot); + + for int1:= 0 to component.componentcount - 1 do begin + comp1:= component.components[int1]; + if not isdatasubmodule(comp1) then begin + drawcomponent(comp1); + end; + end; + canvas.restore; + if not isroot then begin + canvas.move(rect1.pos); + end; + for int1:= 0 to component.componentcount - 1 do begin + comp1:= component.components[int1]; + if isdatasubmodule(comp1) then begin + canvas.save; + clipchildren(component,int1+1,isroot); + drawcomponent(comp1); + canvas.restore; + end; + end; + if not isroot then begin + canvas.remove(rect1.pos); + end; + end; + if issub then begin + canvas.dashes:= #3#3; + dec(rect1.cx); + dec(rect1.cy); + canvas.drawrect(rect1); + canvas.dashes:= ''; + end; + end; + end; + endlab: + dec(level); + end; + +begin + inherited; + offs:= componentoffset; + if not pointisequal(offs,fcompoffsbefore) then begin + fcompoffsbefore:= offs; + fselections.finfovalid:= false; + end; + gridrect1:= gridrect(); + if fmodule <> nil then begin +// canvas.save(); + canvas.intersectcliprect(gridrect1); + if not hidecompact.checked then begin + level:= 0; + drawcomponent(fmodule); + end; + if form <> nil then begin + drawgrid(canvas); + end; +// canvas.restore(); +// canvas.intersectcliprect(markerrect); + fselections.paint(canvas); + showxorpic(canvas); + end; +end; + +procedure tformdesignerfo.dobeforepaint(const canvas: tcanvas); +begin + hidexorpic(canvas); + inherited; + if not fclientsizevalid then begin + recalcclientsize(); + fclientsizevalid:= true; + fselections.finfovalid:= false; + end; +end; + +procedure tformdesignerfo.doactivate; +begin + fdesigner.setactivemodule(self); + inherited; +end; + +function tformdesignerfo.fixformsize: boolean; +begin + result:= parentwidget <> nil; //docked +end; + +procedure tformdesignerfo.doupdatecaption(); +var + mstr1: msestring; +begin + if fmodule <> nil then begin + mstr1:= msestring(fmodule.name); + if fmoduleoptions <> [] then begin + mstr1:= '-'+mstr1; + end; + if fdesigner.modules.findmodule(fmodule)^.modified then begin + mstr1:= '*'+mstr1; + end; + caption:= mstr1; + dragdock.caption:= mstr1; + end; +end; + +procedure tformdesignerfo.doasyncevent(var atag: integer); +var + rect1: rectty; +begin + case designerfoeventty(atag) of + fde_updatecaption: begin + fupdatecaptionpending:= false; + doupdatecaption(); + end; + fde_syncsize: begin + if not fixformsize then begin + rect1:= paintrect; + if form <> nil then begin + form.widgetrect:= rect1; + if sizeisequal(form.size,rect1.size) or + not sizeisequal(rect1.size,fsizebefore) then begin + fsizeerrorcount:= 0; + end; + fsizebefore:= rect1.size; + if fsizeerrorcount < 4 then begin + inc(fsizeerrorcount); + include(ffostate,fds_sizesyncing); + try + paintsize:= form.size; + finally + exclude(ffostate,fds_sizesyncing); + end; + end; + end + else begin + if module is tmsedatamodule then begin + tmsedatamodule(module).size:= rect1.size; + end; + end; + if parentwidget = nil then begin //not docked + fmodulepos:= translatewidgetpoint(rect1.pos,self,nil); + end; + domodified(); + end + else begin + if parentwidget = nil then begin //not docked + fmodulesize:= paintsize; + domodified(); + end; + end; + end; + fde_scrolled: begin + fselections.change(); + end; + fde_showastext: begin + fdesigner.showastext(fdesigner.modules.findmodule(fmodule)); + end; + end; +end; + +procedure tformdesignerfo.updatecaption; +begin + if not fupdatecaptionpending then begin + fupdatecaptionpending:= true; + asyncevent(integer(fde_updatecaption)); + end; +end; + +procedure tformdesignerfo.formcontainerscrolled; +begin + asyncevent(ord(fde_scrolled)); +end; + +procedure tformdesignerfo.checksynctoformsize(); +begin + if (fparentwidget = nil) and (fds_loaded in ffostate) then begin + if (fform <> nil) and not fixformsize then begin + fformcont.size:= fform.size; //not docked + paintsize:= fformcont.size; + end + else begin + paintsize:= getmodulesize(); + end; + end; +end; + +procedure tformdesignerfo.checksynctomodulepos(); +begin + if (fparentwidget = nil) and (fds_loaded in ffostate) then begin + if fform <> nil then begin + pos:= translatewidgetpoint(fmodulepos,fform.parentwidget,self); + end + else begin + pos:= translatewidgetpoint(fmodulepos,fscrollbox,self); + end; + end; +end; + +procedure tformdesignerfo.updateformcont(); +var + si1: sizety; + + function updatesi(const source: sizety): sizety; + begin + result:= source; + if result.cx <> 0 then begin + inc(result.cx,si1.cx); + end; + if result.cy <> 0 then begin + inc(result.cy,si1.cy); + end; + end; //updatesi + +begin + if (fparentwidget = nil) and (form <> nil) then begin + si1:= framedim; + minsize:= updatesi(form.minsize); + maxsize:= updatesi(form.maxsize); + end + else begin + minsize:= nullsize; + maxsize:= nullsize; + end; + fformcont.widgetrect:= paintrect; +end; + +procedure tformdesignerfo.formcontainerwidgetregionchanged( + const sender: twidget); +begin + if (fform <> nil) and (sender = fform) and + not(ws1_anchorsizing in fform.widgetstate1) and + not (csdestroying in fform.componentstate) and + not (csdestroying in componentstate) then begin + checksynctoformsize(); + end; +end; + +procedure tformdesignerfo.beffloatexe(const sender: twidget; + var arect: rectty); +begin + inc(fmodulesetting); + visible:= false; +end; + +procedure tformdesignerfo.floatexe(const sender: TObject); +begin + checksynctoformsize(); + if fform <> nil then begin + pos:= translatewidgetpoint(fmodulepos,fform.parentwidget,self); + end + else begin + pos:= translatewidgetpoint(fmodulepos,fscrollbox,self); + end; + visible:= true; + dec(fmodulesetting); +end; + +procedure tformdesignerfo.clientrectchanged(); + +begin + inherited; + updateformcont(); + if not (ws_loadedproc in widgetstate) and (fmodulesetting = 0) and + (ffostate * [fds_sizesyncing,fds_loaded] = [fds_loaded]) then begin + asyncevent(ord(fde_syncsize)); + end; +end; + +procedure tformdesignerfo.doshow; +begin + inherited; + updatecaption; +end; + +procedure tformdesignerfo.beginplacement; +begin + inc(fmodulesetting); +end; + +procedure tformdesignerfo.endplacement; +begin + dec(fmodulesetting); +end; + +function tformdesignerfo.getdesignrect: rectty; +begin + result:= twidget(fmodule).widgetrect; +end; + +procedure tformdesignerfo.setdesignrect(const arect: rectty); +begin +end; +procedure tformdesignerfo.updatemodulename; +begin + name:= '_mse_'+fmodule.name+'_mse_'; + updatecaption(); +end; + +procedure tformdesignerfo.placemodule; +var +// asize: sizety; +// po1: pointty; +// int1: integer; + rect1: rectty; +begin + beginplacement; + try + updatemodulename(); + if fmodule is twidget then begin + fmodulepos:= twidget(fmodule).pos; + fmodulesize:= twidget(fmodule).size; + setlinkedvar(fmodule,tmsecomponent(fform)); + rect1:= getdesignrect; + widgetrect:= inflaterect(rect1,frame.paintframe); + twidget(fmodule).parentwidget:= getmoduleparent; + twidget(fmodule).pos:= nullpoint; + twidget(fmodule).taborder:= 0; + end + else begin + fform:= nil; + fmodulepos:= getcomponentpos(fmodule); + fmodulesize:= getmodulesize(); + widgetrect:= inflaterect(mr(fmodulepos,fmodulesize),frame.paintframe); + end; + doupdatecaption(); + finally + endplacement; + end; +end; + +procedure tformdesignerfo.setmodule(const Value: tmsecomponent); +begin + if fmodule <> value then begin + fmodule.free; + fmodule:= Value; + if fmodule <> nil then begin + fmodule.freenotification(self); +// insertcomponent(value); + placemodule; + end; + end; +end; + +procedure tformdesignerfo.doshowobjectinspector(const sender: tobject); +begin + designer.showobjectinspector; +// objectinspectorfo.activate; +end; + +procedure tformdesignerfo.doshowcomponentpalette(const sender: tobject); +begin + componentpalettefo.window.bringtofront; + componentpalettefo.show; +end; + +procedure tformdesignerfo.doshowastext(const sender: tobject); +begin + asyncevent(ord(fde_showastext)); +end; + +procedure tformdesignerfo.doeditcomponent(const sender: tobject); +begin + designer.getcomponenteditor.edit; +end; + +function selectinheritedmodule(const amodule: pmoduleinfoty; + const caption: msestring = ''): pmoduleinfoty; +var + fo: tselectsubmoduledialogfo; + ar1: msestringarty; + int1: integer; + ar2: componentarty; +begin + result:= nil; + fo:= tselectsubmoduledialogfo.create(nil); + try + if caption <> '' then begin + fo.caption:= caption; + end; + if amodule <> nil then begin + ar2:= designer.descendentinstancelist.getancestorsandchildren(amodule^.instance); + additem(pointerarty(ar2),amodule^.instance); + end + else begin + ar2:= nil; + end; + ar1:= nil; + with designer.modules do begin + for int1:= 0 to count - 1 do begin + with itempo[int1]^ do begin + if finditem(pointerarty(ar2),instance) < 0 then begin + additem(ar1,filename); + end; + end; + end; + end; + fo.submodule.dropdown.cols[0].asarray:= ar1; + if fo.show(true) = mr_ok then begin + result:= designer.modules.findmodule(fo.submodule.value); + end; + finally + fo.Free; + end; +end; + +function getdesignform(const acomp: tcomponent): tformdesignerfo; +var + comp1: tcomponent; + p1: pmoduleinfoty; +begin + result:= nil; + comp1:= rootcomponent(acomp); + if comp1 <> nil then begin + p1:= designer.modules.findmodulebyinstance(comp1); + if p1 <> nil then begin + pointer(result):= p1^.designform; + if not (result is tformdesignerfo) then begin + result:= nil; + end; + end; + end; +end; + +procedure tformdesignerfo.placecomponent(const component: tcomponent; + const apos: pointty; aparent: tcomponent = nil); +var +// widget1: twidget; + po1: pointty; + rea1: real; + str1,str2: string; + int1,int2: integer; + ar1: componentarty; + bo1: boolean; + comp1: tcomponent; +begin +// with tdesignwindow(window) do begin + try + rea1:= 1.0; + if component is tmsecomponent then begin + with fmoduleintf^ do begin + if assigned(getscale) then begin + rea1:= getscale(module); + end; + end; + tmsecomponent(component).initnewcomponent(rea1); + end; + if (component is twidget) and (form <> nil) then begin + if (aparent = nil) or not (aparent is twidget) then begin + aparent:= widgetatpos(apos,true); + end; + if aparent <> nil then begin + comp1:= aparent.findcomponent(component.name); + if (comp1 <> nil) and (comp1 <> component) then begin + str1:= component.name; + int1:= length(str1); + while (int1 > 1) and (str1[int1] >= '0') and (str1[int1] <= '9') do begin + dec(int1); + end; + setlength(str1,int1); //remove trailing nums + int1:= 1; + ar1:= designer.descendentinstancelist.getdescendents(fmodule); + additem(pointerarty(ar1),module); + additem(pointerarty(ar1),aparent); + str2:= str1+'1'; + repeat + bo1:= true; + for int2:= 0 to high(ar1) do begin + if ar1[int2].findcomponent(str2) <> nil then begin + inc(int1); + str2:= str1 + inttostr(int1); + bo1:= false; + break; + end; + end; + until bo1; + component.name:= str2; + end; +// po1:= subpoint(dosnaptogrid(apos),form.rootpos); + po1:= dosnaptogrid(apos); + twidget(aparent).insertwidget(twidget(component), + translatewidgetpoint(po1,self,twidget(aparent))); + twidget(component).initnewwidget(rea1); + end; + end + else begin + setrootpos(component,subpoint(dosnaptogrid(apos),insertoffset)); + end; + tcomponent1(component).loaded; + domodified; + except + deletecomponent(component); + raise; + end; + selectcomponent(component); + recalcclientsize; +// end; +end; + +procedure tformdesignerfo.doinsertsubmodule(const sender: tobject); +var + comp: tmsecomponent; + po1: pmoduleinfoty; +begin + po1:= selectinheritedmodule(fdesigner.modules.findmodulebyinstance(module)); + if po1 <> nil then begin + comp:= fdesigner.copycomponent(po1^.instance,po1^.instance,false,false); + initinline(comp); + comp.name:= po1^.instance.name; + fdesigner.addancestorinfo(comp,po1^.instance); +// with tdesignwindow(window) do begin + doaddcomponent(comp); + placecomponent(comp,fmousepos,fselections[0]); +// end; + end; +end; + +procedure tformdesignerfo.doinsertcomponent(const sender: TObject); +var + comp1: tcomponent; +begin + comp1:= fdesigner.createcurrentcomponent(module); +// with tdesignwindow(window) do begin + placecomponent(comp1,fmousepos,fselections[0]); +// end; +end; + +procedure tformdesignerfo.dotouch(const sender: TObject); +begin + fdesigner.touch(fmodule); +// tdesignwindow(window).domodified; +end; + +procedure tformdesignerfo.touchallexe(const sender: TObject); +begin + if askconfirmation(c[ord(sc_touchall)]) then begin + fdesigner.touchall; + end; +end; + +procedure tformdesignerfo.dobringtofront(const sender: tobject); +begin +// with tdesignwindow(window) do begin + twidget(fselections[0]).bringtofront; + domodified; +// end; +end; + +procedure tformdesignerfo.dosendtoback(const sender: tobject); +begin +// with tdesignwindow(window) do begin + twidget(fselections[0]).sendtoback; + domodified; +// end; +end; + +procedure tformdesignerfo.doiconify(const sender: TObject); +var + int1: integer; +begin +// with tdesignwindow(window) do begin + for int1:= 0 to fselections.count - 1 do begin + with tmsedatamodule(fselections[int1]) do begin + options:= options + [dmo_iconic]; + end; + end; +// end; +end; + +procedure tformdesignerfo.dodeiconify(const sender: TObject); +var + int1: integer; +begin +// with tdesignwindow(window) do begin + for int1:= 0 to fselections.count - 1 do begin + with tmsedatamodule(fselections[int1]) do begin + options:= options - [dmo_iconic]; + end; + end; +// end; +end; + +procedure tformdesignerfo.dosettaborder(const sender: tobject); +begin + settaborderdialog(twidget(fselections.items[0]),false); +end; + +procedure tformdesignerfo.dosetwidgetorder(const sender: TObject); +begin + settaborderdialog(twidget(fselections.items[0]),true); +end; + +procedure tformdesignerfo.dosetcreationorder(const sender: TObject); +var + fo: tsetcreateorderfo; + str1: string; + comp1: tcomponent; +begin +// with tdesignwindow(window) do begin + comp1:= nil; + str1:= ''; + if (fselections.count = 1) then begin + comp1:= selections[0].owner; + end; + if comp1 = nil then begin + comp1:= module; + end + else begin + str1:= fselections[0].name; + end; +// end; + fo:= tsetcreateorderfo.create(comp1,str1); + try + fo.show(true,window); + finally + fo.free; + end; +end; + +procedure tformdesignerfo.dosyncfontheight(const sender: tobject); +var + int1: integer; + comp1: tcomponent; +begin +// with tdesignwindow(window) do begin + for int1:= 0 to fselections.count - 1 do begin + comp1:= fselections[int1]; + if comp1 is twidget then begin + twidget(comp1).synctofontheight; + fdesigner.componentmodified(comp1); + end; + end; +// end; +end; + +procedure tformdesignerfo.copyexe(const sender: TObject); +begin +// tdesignwindow(twidget(tmenuitem(sender).owner.owner).window).docopy(false); + docopy(false); +end; + +procedure tformdesignerfo.pasteexe(const sender: TObject); +begin +// tdesignwindow(twidget(tmenuitem(sender).owner.owner).window).dopaste(true,''); + dopaste(true,''); +end; + +procedure tformdesignerfo.deleteexe(const sender: TObject); +begin +// tdesignwindow(twidget(tmenuitem(sender).owner.owner).window).dodelete; + dodelete(); +end; + +procedure tformdesignerfo.undeleteexe(const sender: TObject); +begin +// tdesignwindow(twidget(tmenuitem(sender).owner.owner).window).doundelete; + doundelete(); +end; + +procedure tformdesignerfo.cutexe(const sender: TObject); +begin +// tdesignwindow(twidget(tmenuitem(sender).owner.owner).window).docut; + docut(); +end; + +procedure tformdesignerfo.setcomponentscrollsize(const avalue: sizety); +begin + if fform is tcustommseform then begin +{$warnings off} + with tscrollingwidget1(tcustommseform(fform).container) do begin +{$warnings on} + fminminclientsize:= avalue; + clientsize:= clientsize; + end; + end; +end; + +procedure tformdesignerfo.calcscrollsize(const sender: tscrollingwidgetnwr; + var asize: sizety); +var + size1: sizety; +begin + size1:= componentscrollsize(); + setcomponentscrollsize(size1); + if asize.cx < size1.cx then begin + asize.cx:= size1.cx; + end; + if asize.cy < size1.cy then begin + asize.cy:= size1.cy; + end; +end; + +procedure tformdesignerfo.recalcclientsize; +begin + if (fform = nil) or not fformcont.visible then begin +{$warnings off} + with twidget1(container) do begin +{$warnings on} + exclude(fwidgetstate,ws_minclientsizevalid); + tframe1(frame).updatestate; + end; + end + else begin + setcomponentscrollsize(componentscrollsize); + end; +end; + +procedure tformdesignerfo.formdeonclose(const sender: TObject); +var + int1: integer; + bo1: boolean; +begin + with {tdesignwindow(window),}fselections do begin + bo1:= false; + for int1:= count - 1 downto 0 do begin + if (items[int1] = fmodule) or (items[int1].owner = fmodule) then begin + delete(int1); + bo1:= true; + end; + end; + if bo1 then begin + updateselections; + end; + end; +end; + +procedure tformdesignerfo.revertexe(const sender: TObject); +begin + if askok(c[ord(sc_wishrevert)]+lineend+c[ord(sc_selectedcomp)]) then begin + fdesigner.revert(fselections[0]); + objectinspectorfo.refresh; + end; +end; + +function tformdesignerfo.insertoffset: pointty; +var + widget1: twidget; +begin + if (form = nil) or not fformcont.visible then begin + widget1:= container; + end + else begin + if form <> nil then begin + widget1:= form.container; + end + else begin + widget1:= fformcont; + end; + end; + result:= translatewidgetpoint(widget1.clientwidgetpos,widget1,self); +end; + +function tformdesignerfo.gridoffset: pointty; +begin + result:= insertoffset; +end; + +function tformdesignerfo.gridrect: rectty; +begin + if (form = nil) or hidewidgetact.checked then begin + result:= mr(translatewidgetpoint(container.paintpos,container,self), + container.paintsize); + end + else begin + result:= mr(translatewidgetpoint(form.container.paintpos,form.container,self), + form.container.paintsize); + intersectrect1(result, + mr(translatewidgetpoint(fformcont.paintpos,fformcont,self), + fformcont.paintsize)); + end; +end; + +function tformdesignerfo.markerrect: rectty; +var + widget1: twidget; +begin + if (form = nil) or hidewidgetact.checked then begin + widget1:= container; + end + else begin + widget1:= fformcont; + end; + result:= mr(translatewidgetpoint(widget1.paintpos,widget1,self), + widget1.paintsize); +end; + +function tformdesignerfo.widgetrefpoint: pointty; +begin + if form = nil then begin + result:= paintpos; + end + else begin + result:= translatewidgetpoint(form.container.pos,form.container,self); +// result:= form.container.rootpos; + end; +end; + +function tformdesignerfo.compplacementrect: rectty; +begin + if form = nil then begin + result:= container.clientrect; + end + else begin + result:= form.container.clientwidgetrect; + translatewidgetpoint1(result.pos,form.container,self); +// addpoint1(result.pos,form.container.rootpos); + end; +end; + +function tformdesignerfo.getmoduleparent: twidget; +begin +// result:= self; + result:= fformcont; + fscrollbox.visible:= false; +end; + +procedure tformdesignerfo.componentselected(const aselections: tformdesignerselections); +begin + //dummy +end; + +procedure tformdesignerfo.beginstreaming; +var + pt1: pointty; +begin + pt1:= modulerect.pos; //screen pos + if fmodule is twidget then begin + twidget1(fmodule).fwidgetrect.pos:= pt1; + end + else begin + setcomponentpos(fmodule,pt1); + end; + if fform is tcustommseform then begin + tcustommseform(fform).container.frame.scrollpos:= nullpoint; + end; + fformcont.frame.scrollpos:= nullpoint; +end; + +procedure tformdesignerfo.endstreaming; +begin + if fmodule is twidget then begin + with twidget1(fmodule) do begin + fwidgetrect.pos:= self.paintpos; + rootchanged([rcf_widgetregioninvalid]); + end; + end; +end; +{ +function tformdesignerfo.candelete(const acomponent: tcomponent): boolean; +begin + result:= true; +end; +} +{ +function tformdesignerfo.gridsizex: integer; +begin + result:= tdesignwindow(window).fgridsizex; +end; + +function tformdesignerfo.gridsizey: integer; +begin + result:= tdesignwindow(window).fgridsizey; +end; + +function tformdesignerfo.showgrid: boolean; +begin + result:= tdesignwindow(window).fshowgrid; +end; + +function tformdesignerfo.snaptogrid: boolean; +begin + result:= tdesignwindow(window).fsnaptogrid; +end; +} +procedure tformdesignerfo.componentmoving(const apos: pointty); +begin + //dummy +end; + +function tformdesignerfo.getselections: tformdesignerselections; +begin + result:= fselections; +end; +{ +procedure tformdesignerfo.deletecomponent(const comp: tcomponent); +begin + with tdesignwindow(fwindow) do begin + fselections.clear; + fselections.add(comp); + dodelete; + end; +end; +} +function tformdesignerfo.clickedcomponent: tcomponent; +begin + result:= nil; +// with tdesignwindow(fwindow) do begin + if (factcompindex >= 0) and (factcompindex < fselections.count) then begin + result:= fselections[factcompindex]; + end; +// end; +end; + +procedure tformdesignerfo.setmoduleoptions(const aoptions: moduleoptionsty); +var + changes: moduleoptionsty; +begin + if fform <> nil then begin + {$ifdef FPC} + changes:= aoptions> [] then begin + fmoduleoptions:= aoptions; + hidewidgetact.checked:= mo_hidewidgets in aoptions; + hidecompact.checked:= mo_hidecomp in aoptions; + updatecaption; + if mo_hidecomp in changes then begin + clientrectchanged; + if mo_hidecomp in fmoduleoptions then begin + designer.noselection; + end; + end; + if mo_hidewidgets in changes then begin + if mo_hidewidgets in fmoduleoptions then begin + designer.noselection; + fscrollbox.visible:= true; + end + else begin + fscrollbox.visible:= false; + end; + fformcont.visible:= not fscrollbox.visible; + end; + end; + end; +end; + +procedure tformdesignerfo.hidecompexe(const sender: TObject); +begin + clientrectchanged; + if hidecompact.checked then begin + moduleoptions:= moduleoptions + [mo_hidecomp]; + end + else begin + moduleoptions:= moduleoptions - [mo_hidecomp]; + end; +end; + +procedure tformdesignerfo.hidewidgetexe(const sender: TObject); +begin + if hidewidgetact.checked then begin + moduleoptions:= moduleoptions + [mo_hidewidgets]; + end + else begin + moduleoptions:= moduleoptions - [mo_hidewidgets]; + end; +end; + +procedure tformdesignerfo.updatewidgethideexe(const sender: tcustomaction); +begin + hidecompact.enabled:= fform <> nil; + hidewidgetact.enabled:= fform <> nil; + togglehideact.enabled:= fform <> nil; + showallact.enabled:= fform <> nil; +end; + +function tformdesignerfo.getmoduleoptions: moduleoptionsty; +begin + result:= fmoduleoptions; +end; + +procedure tformdesignerfo.togglehideexe(const sender: TObject); +begin + if hidewidgetact.checked then begin + if hidecompact.enabled then begin + hidecompact.checked:= true; + end; + hidewidgetact.checked:= false; + end + else begin + if hidecompact.checked then begin + if hidewidgetact.enabled then begin + hidewidgetact.checked:= true; + end; + hidecompact.checked:= false; + end + else begin + if hidecompact.enabled then begin + hidecompact.checked:= true; + end; + end; + end; +end; + +procedure tformdesignerfo.showallexe(const sender: TObject); +begin + moduleoptions:= moduleoptions - [mo_hidewidgets,mo_hidecomp]; +end; + +function tformdesignerfo.filterfindcomp( + const acomponent: tcomponent): boolean; +begin + result:= not (cssubcomponent in acomponent.componentstyle) and + (not (acomponent is twidget) or + (ws_iswidget in twidget(acomponent).widgetstate)); +end; + +procedure tformdesignerfo.findcompdialog; +var + name1: msestring; +begin + name1:= ''; +// with tdesignwindow(fwindow) do begin + if fselections.count > 0 then begin + name1:= msestring(ownernamepath(fselections[0])); + end; + if compnamedialog(designer.getcomponentnametree(nil,true,true,nil, + @filterfindcomp,fmodule),name1,true) = mr_ok then begin + if name1 = msestring(fmodule.name) then begin + designer.selectcomponent(fmodule); + end + else begin + replacechar1(name1,':','.'); + designer.selectcomponent( + designer.modules.findmodule(fmodule)^. + components.getcomponent(ansistring(name1),true)); + end; + end; +// end; +end; + +function tformdesignerfo.getsnaptogrid: boolean; +begin + result:= fsnaptogrid; +end; + +function tformdesignerfo.getshowgrid: boolean; +begin + result:= fshowgrid; +end; + +function tformdesignerfo.getgridsizex: integer; +begin + result:= fgridsizex; +end; + +function tformdesignerfo.getgridsizey: integer; +begin + result:= fgridsizey; +end; + +procedure tformdesignerfo.updatecursorshape(const ashiftstate: shiftstatesty; + const area: areaty); +var + shape: cursorshapety; +begin + shape:= cr_arrow; + if ashiftstate = [] then begin + case area of + ht_topleft: shape:= cr_topleftcorner; + ht_bottomright: shape:= cr_bottomrightcorner; + ht_topright: shape:= cr_toprightcorner; + ht_bottomleft: shape:= cr_bottomleftcorner; + ht_top,ht_bottom: shape:= cr_sizever; + ht_left,ht_right: shape:= cr_sizehor; + end; + end; + application.widgetcursorshape:= shape; +end; + +procedure tformdesignerfo.designmouseevent(var info: moeventinfoty; + capture: twidget); +var + mousepos1: pointty; + ss1: shiftstatesty; + + function griddelta: pointty; + begin + result:= snaptogriddelta(subpoint(mousepos1,fpickpos)); + end; + + procedure updatesizerect; + var + pos1,posbefore: pointty; + begin + pos1:= griddelta; + posbefore:= pos1; + with fsizerect,pos1 do begin + case actarea of + ht_topleft,ht_left,ht_bottomleft: begin + if x > size.cx then begin + x:= size.cx + end; + factsizerect.pos.x:= pos.x + x; + factsizerect.size.cx:= size.cx - x; + end; + ht_topright,ht_right,ht_bottomright: begin + if x < -size.cx then begin + x:= -size.cx; + end; + factsizerect.size.cx:= size.cx + x; + end; + end; + case actarea of + ht_topleft,ht_top,ht_topright: begin + if y > size.cy then begin + y:= size.cy + end; + factsizerect.pos.y:= pos.y + y; + factsizerect.size.cy:= size.cy - y; + end; + ht_bottomleft,ht_bottom,ht_bottomright: begin + if y < -size.cy then begin + y:= -size.cy; + end; + factsizerect.size.cy:= size.cy + y; + end; + end; + end; + case actarea of + ht_top,ht_bottom: begin + mousepos1.x:= fpickpos.x; + end; + ht_left,ht_right: begin + mousepos1.y:= fpickpos.y; + end; + end; + application.mouse.move(subpoint(pos1,posbefore)); + end; + + function getcompatpos(const mousepos: pointty; out dest: tcomponent): boolean; + //true if widget + begin + result:= false; + dest:= componentatpos(mousepos); + if (dest = nil) then begin + if (form <> nil) and + not hidewidgetact.checked then begin + dest:= widgetatpos(mousepos,true,true); + result:= true; + end + else begin + dest:= module; + end; + end; + end; //getcompatpos + + function getcompatpos(const mousepos: pointty): tcomponent; + begin + getcompatpos(mousepos,result); + end; + + procedure removehint(); + begin + if fhintedcomp <> nil then begin + application.hidehint(); + fhintedcomp:= nil; + end; + end; //removehint + +var + component: tcomponent; + int1: integer; + bo1,bo2: boolean; + widget1: twidget; + rect1: rectty; + selectmode: selectmodety; + area1: areaty; + isinpaintrect: boolean; + designactive: boolean; + po1: pformselectedinfoty; + pt1: pointty; + hintinfo1: hintinfoty; +label + 1; +begin + if (module = nil) or (info.mouse.eventkind = ek_mousewheel) then begin + exit; //continue normal handling + end; + if info.mouse.eventkind in [ek_mouseleave,ek_mouseenter] then begin + removehint(); + fclickedcompbefore:= nil; + include(info.mouse.eventstate,es_processed); + exit; + end; +// twindow1(window).checkmousewidget(info.mouse,capture); + with info.mouse do begin + designactive:= (capture <> nil) and + (ws1_designactive in twidget1(capture).fwidgetstate1); + mousepos1:= translatewidgetpoint(pos,window.owner,self); + ss1:= shiftstate * (shiftstatesmask); + isinpaintrect:= pointinrect(mousepos1,gridrect); + if eventkind in [ek_buttonpress,ek_buttonrelease] then begin + fmousepos:= mousepos1; + end; + if (fhintedcomp <> nil) and + (info.mouse.eventkind in mouseposevents) then begin + if getcompatpos(mousepos1) <> fhintedcomp then begin + removehint(); + end; + end; + if (info.mouse.eventkind = ek_mousepark) and application.active and + projectoptions.e.componenthints and (fhintedcomp = nil) then begin + bo1:= getcompatpos(mousepos1,fhintedcomp); + if (fhintedcomp <> nil) then begin + if bo1 then begin + widget1:= twidget(fhintedcomp); + end + else begin + if fform <> nil then begin + widget1:= fform; + end + else begin + widget1:= fformcont; + end; + end; + application.inithintinfo(hintinfo1,widget1); + hintinfo1.caption:= msestring( + fhintedcomp.name+' ('+fhintedcomp.classname+')'); + application.showhint(widget1,hintinfo1); + end; + end; + component:= nil; + if not (es_processed in eventstate) then begin + bo1:= false; + if (eventkind = ek_buttonpress) and (button = mb_left) then begin + fpickpos:= mousepos1; + if (ss1 = [ss_left]) or (ss1 = [ss_left,ss_ctrl]){ or + (ss1 = [ss_left,ss_ctrl,ss_shift])} then begin + actarea:= fselections.getareainfo(mousepos1,factcompindex); + if factcompindex >= 0 then begin + fsizerect:= fselections.itempo(factcompindex)^.rect; + factsizerect:= fsizerect; + end; + if (actarea in [ar_component,ar_none]) and + not (ss_shift in ss1) then begin + if isinpaintrect then begin + component:= getcompatpos(mousepos1); + end; + if component <> nil then begin + if (factcompindex < 0) or + (component <> fselections[factcompindex]) then begin + actarea:= ar_none; + end; + bo1:= true; + end + else begin + actarea:= ar_none; + end; + fclickedcompbefore:= component; + end + else begin + capturemouse; + include(eventstate,es_processed); + end; + end + end; + if (eventkind = ek_buttonrelease) and (button = mb_right) and + not (es_processed in eventstate) then begin + pt1:= info.mouse.pos; + try + translatewidgetpoint1(info.mouse.pos,window.owner,self); + dopopup(info.mouse); + finally + info.mouse.pos:= pt1; + end; + end; + if not (es_processed in eventstate) and + (ss1 <> [ss_left,ss_shift,ss_ctrl]) then begin + area1:= fselections.getareainfo(mousepos1,int1); + bo2:= not ((eventkind = ek_buttonpress) and (button = mb_left) and + (ss1 = [ss_left])); + if not ((ss_double in shiftstate) and (eventkind = ek_buttonpress) + or (ss1 = [ss_left,ss_shift])) and + (bo2 or + ((area1 < firsthandle) or (area1 > lasthandle)) and + (not (fdesigner.hascurrentcomponent or + componentstorefo.hasselection)) + ) and + ((actarea < firsthandle) or (actarea > lasthandle)) and + (actarea <> ar_componentmove) then begin + twindow1(window).dispatchmouseevent(info,capture); //"inherited" + if not designactive then begin + exclude(eventstate,es_processed); + end; + if es_processed in eventstate then begin + releasemouse(); + end; + end; + if bo1 then begin + if ss_ctrl in ss1 then begin + selectcomponent(component,sm_flip); + end + else begin + bo2:= fselections.indexof(component) < 0; + if (component = form) and (fselections.count > 1) or bo2 then begin + selectcomponent(component,sm_select); + if projectoptions.e.moveonfirstclick then begin + actarea:= ar_component; + end; + end + else begin + if not bo2 then begin + updateclickedcomponent; + end; + end; + end; + if not (es_processed in eventstate) then begin + if not designactive then begin + capturemouse; //capture mouse + end; + updatecursorshape(ss1,actarea); + end + else begin + actarea:= ar_none; + end; + end; + end; + if not (es_processed in eventstate) then begin + if (eventkind = ek_buttonpress) and (button = mb_left) then begin + if (ss1 = [ss_left]) or (ss1 = [ss_left,ss_shift,ss_ctrl]) then begin + if isinpaintrect then begin + component:= fdesigner.createcurrentcomponent(module); + if (component = nil) and componentstorefo.hasselection then begin + dopaste(true,componentstorefo.copyselected); + end; + end; + if component <> nil then begin + if (ss1 = [ss_left,ss_shift,ss_ctrl]) and + (fselections.count = 1) then begin + //insert in current selected widget + placecomponent(component,mousepos1,fselections[0]); + end + else begin + placecomponent(component,mousepos1); + end; + end; + end + else begin + if (ss1 = [ss_left,ss_shift]) and isinpaintrect then begin + actarea:= ar_selectrect; + capturemouse(); + fxorpicoffset:= mousepos1; + if form <> nil then begin + fpickwidget:= widgetatpos(mousepos1,false); + end + else begin + fpickwidget:= self; + end; + end; + end; + end; + if (eventkind = ek_buttonrelease) and (button = mb_left) then begin + hidexorpic(getcanvas(org_widget)); + fxorpicactive:= false; + case actarea of + firsthandle..lasthandle: begin + if (factcompindex >= 0) and + (factcompindex < fselections.count) then begin + component:= tcomponent( + fselections.itempo(factcompindex)^.selectedinfo.instance); + if (component is twidget) and (form <> nil) then begin + with twidget(component) do begin + translatewidgetpoint1(factsizerect.pos,self,parentwidget); + widgetrect:= factsizerect; + end; + fselections.componentschanged; + end + else begin + if component is tmsedatamodule then begin + rect1:= getcomponentrect1(component); + with tmsedatamodule(component) do begin + subpoint1(factsizerect.pos,rect1.pos); + setcomponentpos(component, + addpoint(getcomponentpos(component),factsizerect.pos)); + size:= factsizerect.size; + end; + fselections.componentschanged; + end; + end; + end; + invalidate(); + end; + ar_componentmove: begin + if fselections.move(griddelta) then begin + invalidate(); //redraw handles + clientsizechanged; + end; + end; + ar_component: begin + if ss_double in shiftstate then begin + designer.showobjectinspector; + end; + end; + ar_selectrect: begin + if fpickwidget <> nil then begin + rect1.pos:= fpickpos; + rect1.cx:= mousepos1.x - fpickpos.x; + rect1.cy:= mousepos1.y - fpickpos.y; + if (rect1.cx < 0) or (rect1.cy < 0) then begin + selectmode:= sm_remove; + end + else begin + selectmode:= sm_add; + end; + beginselect; + try + if (selectmode = sm_add) and (fselections.count = 1) and + (fselections[0] = module) then begin + fselections.clear; //remove underlaying form + end; + for int1:= 0 to module.componentcount - 1 do begin + component:= module.Components[int1]; + if (form = nil) or (not (component is twidget)) then begin + if rectinrect(getcomponentrect1(component),rect1) then begin + selectcomponent(component,selectmode); + end; + end; + end; + if fpickwidget <> self then begin + rect1.pos:= translatewidgetpoint(fpickpos,self,fpickwidget); + for int1:= 0 to fpickwidget.widgetcount -1 do begin + widget1:= fpickwidget.widgets[int1]; + if rectinrect(widget1.widgetrect,rect1) and + (ws_iswidget in widget1.widgetstate) then begin + selectcomponent(widget1,selectmode); + end; + end; + end; + finally + endselect; + end; + end; + end; + end; + fpickwidget:= nil; + actarea:= ar_none; + if factcompindex >= 0 then begin + factcompindex:= -1; + updateclickedcomponent; //update objectionspector componentname + end; + releasemouse(); + end; + + if not (es_processed in eventstate) then begin + if (eventkind = ek_mousemove) or (eventkind = ek_mousepark) then begin + hidexorpic(getcanvas(org_widget)); + bo1:= true; + case actarea of + firsthandle..lasthandle: begin + updatesizerect; + end; + ar_component: begin + if (distance(fpickpos,mousepos1) > movethreshold) then begin + fxorpicoffset:= griddelta; + actarea:= ar_componentmove; + capturemouse(); + end + else begin + bo1:= false; + end; + end; + ar_componentmove: begin + fxorpicoffset:= griddelta; + end; + ar_selectrect: begin + fxorpicoffset:= mousepos1; + end; + else begin + bo1:= false; + fmovearea:= fselections.getareainfo(mousepos1,int1); + updatecursorshape(ss1,fmovearea); + end; + end; + if bo1 then begin + fxorpicactive:= true; + if not (actarea in [ar_component,firsthandle..lasthandle]) then begin + fselections.beforepaintmoving; //resets canvas + end; + showxorpic(getcanvas(org_widget)); + end; + end; + end; + end; + end; +1: + if (eventkind in mouseposevents) and (fselections.count = 1) then begin + fselections.updateinfos; + po1:= fselections.itempo(0); + if po1^.selectedinfo.instance <> fmodule then begin + bo1:= true; + case actarea of + ar_component: begin + if (eventkind = ek_buttonpress) and (button = mb_left) then begin + pt1:= rectcenter(po1^.handles[ht_topleft]); + end + else begin + bo1:= false; + end; + end; + ht_topleft: begin + pt1:= factsizerect.pos; + end; + ht_left: begin + with factsizerect do begin + pt1.x:= x; + pt1.y:= y + cy div 2; + end; + end; + ht_bottomleft: begin + with factsizerect do begin + pt1.x:= x; + pt1.y:= y + cy; + end; + end; + ht_bottom: begin + with factsizerect do begin + pt1.x:= x + cx div 2; + pt1.y:= y + cy ; + end; + end; + ht_bottomright: begin + with factsizerect do begin + pt1.x:= x + cx; + pt1.y:= y + cy; + end; + end; + ht_right: begin + with factsizerect do begin + pt1.x:= x + cx; + pt1.y:= y + cy div 2; + end; + end; + ht_topright: begin + with factsizerect do begin + pt1.x:= x + cx; + pt1.y:= y; + end; + end; + ht_top: begin + with factsizerect do begin + pt1.x:= x + cx div 2; + pt1.y:= y; + end; + end; + ar_componentmove: begin + pt1:= addpoint(rectcenter(po1^.handles[ht_topleft]),fxorpicoffset); + end; + else begin + bo1:= false; + end; + end; + if bo1 then begin + componentmoving(pt1); + end; + end; + end; + end; + include(info.mouse.eventstate,es_processed); +end; + +procedure tformdesignerfo.designkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); +var + po1: pointty; + comp1: tcomponent; + shiftstate1: shiftstatesty; + actareabefore: areaty; +begin + if module = nil then begin + exit; + end; + shiftstate1:= info.shiftstate * keyshiftstatesmask; + if actarea = ar_none then begin + updatecursorshape(shiftstate1,fmovearea); + end; + if eventkind = ek_keypress then begin + with info do begin + if shiftstate1 = [] then begin + include(eventstate,es_processed); + case key of + key_return: begin + if not designer.editcomponent(module) then begin + exclude(eventstate,es_processed); + end; + end; + key_escape: begin + if not (actarea in [ar_none,ar_component]) then begin + hidexorpic(getcanvas(org_widget)); + fxorpicactive:= false; + actarea:= ar_none; + end + else begin + if (fselections.count > 1) and (actarea <> ar_component) then begin + selectcomponent(module); + end + else begin + if fselections.count > 0 then begin + if actarea = ar_component then begin + comp1:= fselections[factcompindex]; + end + else begin + comp1:= fselections[0]; + end; + if iswidgetcomp(comp1) then begin + repeat + comp1:= twidget(comp1).parentwidget; + until (comp1 = nil) or (ws_iswidget in twidget(comp1).widgetstate); + actareabefore:= actarea; + if (comp1 <> nil) and (comp1 <> self) then begin + if fselections.count > 1 then begin + selectparentwidget(twidget(comp1)); + end + else begin + selectcomponent(comp1); + end; + end + else begin + selectcomponent(module); + end; + actarea:= actareabefore; + end + else begin +// if isdatasubmodule(comp1.owner) then begin + selectcomponent(comp1.owner); +// end +// else begin +// selectcomponent(module); +// end; + end; + end; + end; + end; + end; + key_delete: begin + if fselections.candelete then begin + dodelete; + end; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end + else begin + if (shiftstate1 = [ss_ctrl]) or (shiftstate1 = [ss_shift]) then begin + include(eventstate,es_processed); + po1:= nullpoint; + case key of + key_right: po1.x:= 1; + key_up: po1.y:= -1; + key_left: po1.x:= -1; + key_down: po1.y:= 1; + else exclude(eventstate,es_processed); + end; + if (es_processed in eventstate) then begin + if shiftstate1 = [ss_ctrl] then begin + fselections.move(po1); + if fselections.count > 0 then begin + fselections.updateinfos; + componentmoving(rectcenter(fselections.itempo(0)^.handles[ht_topleft])); + end; + end + else begin + fselections.resize(po1); + if fselections.count > 0 then begin + fselections.updateinfos; + with fselections.itempo(0)^.handles[ht_bottomright] do begin + componentmoving(makepoint(x+cx div 2 + 1,y+cy div 2 +1)); + end; + end; + end; + invalidate(); + clientsizechanged(); + end; + end; + end; + if not (es_processed in eventstate) then begin + if issysshortcut(sho_copy,info) then begin + docopy(false); + include(eventstate,es_processed); + end + else begin + if issysshortcut(sho_cut,info) then begin + docut; + include(eventstate,es_processed); + end + else begin + if issysshortcut(sho_paste,info) then begin + dopaste(false,''); + include(eventstate,es_processed); + end; + end; + end; + end; + end; + end; +end; + +function tformdesignerfo.isdesignwidget(): boolean; +begin + result:= true; +end; + +function tformdesignerfo.getmodulesize: sizety; +var + asize: sizety; + int1: integer; + pt1: pointty; +begin + if fform <> nil then begin + result:= fform.size; + end + else begin + if fmodule is tmsedatamodule then begin + result:= tmsedatamodule(fmodule).size; + end + else begin + asize:= nullsize; + for int1:= 0 to fmodule.ComponentCount - 1 do begin + pt1:= getcomponentpos(fmodule.Components[int1]); + if pt1.x > asize.cx then begin + asize.cx:= pt1.x; + end; + if pt1.y > asize.cy then begin + asize.cy:= pt1.y; + end; + end; + inc(asize.cx,80); + inc(asize.cy,30); //todo: correct size, scrollbox + result:= asize; + end; + end; +end; + +function tformdesignerfo.getmodulerect: rectty; +begin + result.pos:= fmodulepos; + result.size:= getmodulesize(); +end; + +function tformdesignerfo.getmodulepos_x: integer; +begin + result:= fmodulepos.x; +end; + +function tformdesignerfo.getmodulepos_y: integer; +begin + result:= fmodulepos.y; +end; + +procedure tformdesignerfo.setmodulepos_x(const avalue: integer); +begin + if fmodulepos.x <> avalue then begin + fmodulepos.x:= avalue; + checksynctomodulepos(); + end; +end; + +procedure tformdesignerfo.setmodulepos_y(const avalue: integer); +begin + if fmodulepos.y <> avalue then begin + fmodulepos.y:= avalue; + checksynctomodulepos(); + end; +end; + +function tformdesignerfo.getdockcontroller(): tdockcontroller; +begin + result:= dragdock; +end; + +procedure tformdesignerfo.updatedockinfo(); +begin +{ + with fmoduleinfo^.dockinfo do begin + panelname:= dragdock.dockparentname(); + rect:= widgetrect; + end; +} +end; + +function tformdesignerfo.checkdelete: boolean; +begin + result:= true; +end; + +procedure tformdesignerfo.enterexe(const sender: TObject); +begin + mainfo.designformactivated(self); +end; + +procedure tformdesignerfo.setactarea(const avalue: areaty); +begin + factarea:= avalue; + fmovearea:= factarea; +end; + + +{ tformdesignerdockcontroller } + +procedure tformdesignerdockcontroller.dostatplace(const aparent: twidget; + const avisible: boolean; arect: rectty); +begin + if (aparent <> nil) then begin //do not change undocked position + inherited; + end; +end; + +initialization +finalization + freeandnil(fregistereddesignmoduleclasses); +end. diff --git a/mseide-msegui/apps/ide/formdesigner_mfm.pas b/mseide-msegui/apps/ide/formdesigner_mfm.pas new file mode 100644 index 0000000..941f026 --- /dev/null +++ b/mseide-msegui/apps/ide/formdesigner_mfm.pas @@ -0,0 +1,375 @@ +unit formdesigner_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,formdesigner; + +const + objdata: record size: integer; data: array[0..7146] of byte end = + (size: 7147; data: ( + 84,80,70,48,15,116,102,111,114,109,100,101,115,105,103,110,101,114,102,111, + 14,102,111,114,109,100,101,115,105,103,110,101,114,102,111,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,9,111,119,95,104, + 105,110,116,111,110,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 5,99,111,108,111,114,4,5,0,0,144,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105, + 112,95,115,105,122,101,2,0,18,102,114,97,109,101,46,103,114,105,112,95, + 111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116, + 116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110, + 14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116, + 111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117, + 110,100,98,117,116,116,111,110,14,103,111,95,98,117,116,116,111,110,104,105, + 110,116,115,0,30,102,114,97,109,101,46,103,114,105,112,95,102,97,99,101, + 46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,1,30,102,114, + 97,109,101,46,103,114,105,112,95,102,97,99,101,46,102,97,100,101,95,112, + 111,115,46,105,116,101,109,115,1,2,0,0,32,102,114,97,109,101,46,103, + 114,105,112,95,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46, + 99,111,117,110,116,2,1,32,102,114,97,109,101,46,103,114,105,112,95,102, + 97,99,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115, + 1,4,19,0,0,160,0,26,102,114,97,109,101,46,103,114,105,112,95,102, + 97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,0,9,112,111,112, + 117,112,109,101,110,117,7,7,112,111,112,117,112,109,101,7,111,110,101,110, + 116,101,114,7,8,101,110,116,101,114,101,120,101,10,111,110,97,99,116,105, + 118,97,116,101,7,8,101,110,116,101,114,101,120,101,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,68,8,98,111,117,110,100, + 115,95,121,3,21,1,9,98,111,117,110,100,115,95,99,120,3,31,1,9, + 98,111,117,110,100,115,95,99,121,3,44,1,23,99,111,110,116,97,105,110, + 101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,13,111,119,95,109,111,117,115,101,119,104,101,101,108,0,15,99,111, + 110,116,97,105,110,101,114,46,99,111,108,111,114,4,5,0,0,144,26,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,29,99,111, + 110,116,97,105,110,101,114,46,111,110,99,97,108,99,109,105,110,115,99,114, + 111,108,108,115,105,122,101,7,14,99,97,108,99,115,99,114,111,108,108,115, + 105,122,101,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115, + 1,2,0,2,0,3,31,1,3,44,1,0,20,100,114,97,103,100,111,99, + 107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97, + 118,101,112,111,115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10, + 111,100,95,99,97,110,109,111,118,101,10,111,100,95,99,97,110,115,105,122, + 101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110, + 100,111,99,107,11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95, + 99,97,112,116,105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100, + 105,99,111,110,115,0,22,100,114,97,103,100,111,99,107,46,111,110,98,101, + 102,111,114,101,102,108,111,97,116,7,11,98,101,102,102,108,111,97,116,101, + 120,101,16,100,114,97,103,100,111,99,107,46,111,110,102,108,111,97,116,7, + 8,102,108,111,97,116,101,120,101,13,111,112,116,105,111,110,115,119,105,110, + 100,111,119,11,12,119,111,95,110,111,116,97,115,107,98,97,114,0,7,111, + 112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112,111,115,13,102, + 111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95,115,97,118,101, + 115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,22,109,97,105, + 110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,21, + 105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103,101,10,216,7, + 0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,164,7, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,25,242,166, + 149,1,221,216,211,1,242,166,149,1,255,134,109,2,121,64,52,1,157,83, + 67,1,187,98,80,1,208,109,89,2,247,130,106,1,212,111,91,1,255,134, + 109,4,160,160,160,6,128,128,128,1,255,255,255,1,221,216,211,1,7,239, + 255,1,221,216,211,1,255,134,109,2,120,63,51,1,201,106,86,1,181,95, + 77,1,135,71,58,1,214,112,91,1,139,73,59,1,163,86,70,1,242,127, + 103,1,255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160, + 160,1,209,209,209,1,128,128,128,2,255,255,255,1,242,166,149,1,221,216, + 211,1,242,166,149,1,255,134,109,2,212,111,91,1,255,134,109,1,218,115, + 93,1,204,107,87,1,180,95,77,1,222,117,95,1,184,97,79,1,253,133, + 108,1,255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160, + 160,1,209,209,209,1,128,128,128,2,255,255,255,1,151,24,0,16,128,128, + 128,7,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255, + 255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128, + 128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255, + 255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128, + 128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255, + 255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128, + 128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255, + 255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,128,128,128,25,7,111,110,99,108,111,115,101,7,13, + 102,111,114,109,100,101,111,110,99,108,111,115,101,4,108,101,102,116,3,239, + 0,3,116,111,112,3,180,0,15,109,111,100,117,108,101,99,108,97,115,115, + 110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,10,116,112,111, + 112,117,112,109,101,110,117,7,112,111,112,117,112,109,101,18,109,101,110,117, + 46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,33,18,109,101,110, + 117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97, + 112,116,105,111,110,6,20,83,104,111,119,32,111,98,106,101,99,116,105,110, + 115,112,101,99,116,111,114,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 21,100,111,115,104,111,119,111,98,106,101,99,116,105,110,115,112,101,99,116, + 111,114,0,1,7,99,97,112,116,105,111,110,6,21,83,104,111,119,32,99, + 111,109,112,111,110,101,110,116,112,97,108,101,116,116,101,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110, + 101,120,101,99,117,116,101,7,22,100,111,115,104,111,119,99,111,109,112,111, + 110,101,110,116,112,97,108,101,116,116,101,0,1,7,99,97,112,116,105,111, + 110,6,12,83,104,111,119,32,97,115,32,84,101,120,116,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112, + 116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99,117,116,99, + 97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101,120,101,99, + 117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,12,100,111,115,104, + 111,119,97,115,116,101,120,116,0,1,7,111,112,116,105,111,110,115,11,13, + 109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116, + 105,111,110,7,11,104,105,100,101,99,111,109,112,97,99,116,7,111,112,116, + 105,111,110,115,11,12,109,97,111,95,99,104,101,99,107,98,111,120,19,109, + 97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0, + 1,6,97,99,116,105,111,110,7,13,104,105,100,101,119,105,100,103,101,116, + 97,99,116,7,111,112,116,105,111,110,115,11,12,109,97,111,95,99,104,101, + 99,107,98,111,120,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,13,116,111,103, + 103,108,101,104,105,100,101,97,99,116,0,1,6,97,99,116,105,111,110,7, + 10,115,104,111,119,97,108,108,97,99,116,0,1,7,111,112,116,105,111,110, + 115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111, + 95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,7, + 99,97,112,116,105,111,110,6,17,67,111,112,121,32,67,111,109,112,111,110, + 101,110,116,40,115,41,4,110,97,109,101,6,4,99,111,112,121,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 16,97,115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,7,99,111,112,121,101,120,101,2,115,99,1,2, + 1,3,67,64,0,0,1,7,99,97,112,116,105,111,110,6,16,67,117,116, + 32,67,111,109,112,111,110,101,110,116,40,115,41,4,110,97,109,101,6,3, + 99,117,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,16,97,115,95,108,111,99,97,108,115,104,111,114,116, + 99,117,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114, + 116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110, + 99,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 6,99,117,116,101,120,101,2,115,99,1,2,1,3,88,64,0,0,1,7, + 99,97,112,116,105,111,110,6,18,80,97,115,116,101,32,67,111,109,112,111, + 110,101,110,116,40,115,41,4,110,97,109,101,6,5,112,97,115,116,101,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,16,97,115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111, + 110,101,120,101,99,117,116,101,7,8,112,97,115,116,101,101,120,101,2,115, + 99,1,2,1,3,86,64,0,0,1,7,99,97,112,116,105,111,110,6,19, + 68,101,108,101,116,101,32,67,111,109,112,111,110,101,110,116,40,115,41,4, + 110,97,109,101,6,6,100,101,108,101,116,101,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,16,97,115,95,108, + 111,99,97,108,115,104,111,114,116,99,117,116,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 16,109,97,111,95,97,115,121,110,99,101,120,101,99,117,116,101,0,9,111, + 110,101,120,101,99,117,116,101,7,9,100,101,108,101,116,101,101,120,101,2, + 115,99,1,2,1,3,7,1,0,0,1,7,99,97,112,116,105,111,110,6, + 21,85,110,100,101,108,101,116,101,32,67,111,109,112,111,110,101,110,116,40, + 115,41,4,110,97,109,101,6,8,117,110,100,101,108,101,116,101,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9, + 111,110,101,120,101,99,117,116,101,7,11,117,110,100,101,108,101,116,101,101, + 120,101,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101, + 112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116, + 99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,24,97, + 99,116,105,111,110,115,109,111,46,102,105,110,100,99,111,109,112,97,108,108, + 97,99,116,7,99,97,112,116,105,111,110,6,14,70,105,110,100,32,67,111, + 109,112,111,110,101,110,116,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111, + 110,6,18,83,101,108,101,99,116,32,67,104,105,108,100,119,105,100,103,101, + 116,4,110,97,109,101,6,11,115,101,108,101,99,116,99,104,105,108,100,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,0,1,7,99,97,112,116,105,111,110,6,8,38,73,99,111,110, + 105,102,121,4,110,97,109,101,6,7,105,99,111,110,105,102,121,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9, + 111,110,101,120,101,99,117,116,101,7,9,100,111,105,99,111,110,105,102,121, + 0,1,7,99,97,112,116,105,111,110,6,10,38,68,101,105,99,111,110,105, + 102,121,4,110,97,109,101,6,9,100,101,105,99,111,110,105,102,121,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 9,111,110,101,120,101,99,117,116,101,7,11,100,111,100,101,105,99,111,110, + 105,102,121,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115, + 101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117, + 116,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6, + 15,38,69,100,105,116,32,67,111,109,112,111,110,101,110,116,4,110,97,109, + 101,6,8,101,100,105,116,99,111,109,112,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,15,100,111,101,100,105,116,99,111,109,112,111,110,101,110,116, + 0,1,7,99,97,112,116,105,111,110,6,20,83,121,110,99,46,32,116,111, + 32,70,111,110,116,32,72,101,105,103,104,116,4,110,97,109,101,6,8,115, + 121,110,99,116,111,102,111,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 16,100,111,115,121,110,99,102,111,110,116,104,101,105,103,104,116,0,1,7, + 99,97,112,116,105,111,110,6,14,66,114,105,110,103,32,116,111,32,70,114, + 111,110,116,4,110,97,109,101,6,10,98,114,105,110,103,116,111,102,114,111, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,111,110,101,120,101,99,117,116,101,7,14,100,111,98,114,105,110, + 103,116,111,102,114,111,110,116,0,1,7,99,97,112,116,105,111,110,6,12, + 83,101,110,100,32,116,111,32,66,97,99,107,4,110,97,109,101,6,8,115, + 101,110,100,116,111,98,97,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 12,100,111,115,101,110,100,116,111,98,97,99,107,0,1,7,99,97,112,116, + 105,111,110,6,16,83,101,116,32,87,105,100,103,101,116,32,79,114,100,101, + 114,4,110,97,109,101,6,12,115,101,116,119,105,100,103,101,116,111,114,100, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,111,110,101,120,101,99,117,116,101,7,16,100,111,115,101,116,119, + 105,100,103,101,116,111,114,100,101,114,0,1,7,99,97,112,116,105,111,110, + 6,13,83,101,116,32,84,97,98,32,79,114,100,101,114,4,110,97,109,101, + 6,9,115,101,116,116,97,98,111,114,100,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,13,100,111,115,101,116,116,97,98,111,114,100,101,114,0,1, + 7,99,97,112,116,105,111,110,6,18,83,101,116,32,67,114,101,97,116,105, + 111,110,32,79,114,100,101,114,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,18,100,111,115,101,116,99,114,101,97,116,105,111,110,111,114,100,101,114, + 0,1,7,99,97,112,116,105,111,110,6,19,82,101,118,101,114,116,32,116, + 111,32,105,110,104,101,114,105,116,101,100,4,110,97,109,101,6,6,114,101, + 118,101,114,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95, + 115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95, + 97,115,121,110,99,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,9,114,101,118,101,114,116,101,120,101,0,1,7,111,112,116, + 105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19, + 109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0, + 0,1,7,99,97,112,116,105,111,110,6,10,84,111,117,99,104,32,70,111, + 114,109,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,7,100,111,116,111, + 117,99,104,0,1,7,99,97,112,116,105,111,110,6,15,84,111,117,99,104, + 32,97,108,108,32,70,111,114,109,115,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117, + 116,101,7,11,116,111,117,99,104,97,108,108,101,120,101,0,1,7,99,97, + 112,116,105,111,110,6,16,73,110,115,101,114,116,32,83,117,98,109,111,100, + 117,108,101,4,110,97,109,101,6,9,105,110,115,101,114,116,115,117,98,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,111,110,101,120,101,99,117,116,101,7,17,100,111,105,110,115,101,114, + 116,115,117,98,109,111,100,117,108,101,0,1,7,99,97,112,116,105,111,110, + 6,16,73,110,115,101,114,116,32,67,111,109,112,111,110,101,110,116,4,110, + 97,109,101,6,10,105,110,115,101,114,116,99,111,109,112,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110, + 101,120,101,99,117,116,101,7,17,100,111,105,110,115,101,114,116,99,111,109, + 112,111,110,101,110,116,0,0,4,108,101,102,116,2,48,3,116,111,112,2, + 40,0,0,7,116,97,99,116,105,111,110,11,104,105,100,101,99,111,109,112, + 97,99,116,7,99,97,112,116,105,111,110,6,16,72,105,100,101,32,38,67, + 111,109,112,111,110,101,110,116,115,8,111,110,99,104,97,110,103,101,7,11, + 104,105,100,101,99,111,109,112,101,120,101,4,108,101,102,116,3,144,0,3, + 116,111,112,2,40,0,0,7,116,97,99,116,105,111,110,13,104,105,100,101, + 119,105,100,103,101,116,97,99,116,7,99,97,112,116,105,111,110,6,13,72, + 105,100,101,32,38,87,105,100,103,101,116,115,8,111,110,117,112,100,97,116, + 101,7,19,117,112,100,97,116,101,119,105,100,103,101,116,104,105,100,101,101, + 120,101,8,111,110,99,104,97,110,103,101,7,13,104,105,100,101,119,105,100, + 103,101,116,101,120,101,4,108,101,102,116,3,144,0,3,116,111,112,2,56, + 0,0,7,116,97,99,116,105,111,110,13,116,111,103,103,108,101,104,105,100, + 101,97,99,116,7,99,97,112,116,105,111,110,6,25,38,72,105,100,101,32, + 87,105,100,103,101,116,115,60,62,67,111,109,112,111,110,101,110,116,115,9, + 111,110,101,120,101,99,117,116,101,7,13,116,111,103,103,108,101,104,105,100, + 101,101,120,101,4,108,101,102,116,3,144,0,3,116,111,112,2,72,0,0, + 7,116,97,99,116,105,111,110,10,115,104,111,119,97,108,108,97,99,116,7, + 99,97,112,116,105,111,110,6,9,38,83,104,111,119,32,97,108,108,9,111, + 110,101,120,101,99,117,116,101,7,10,115,104,111,119,97,108,108,101,120,101, + 4,108,101,102,116,3,144,0,3,116,111,112,2,88,0,0,16,116,115,116, + 114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116,114,105, + 110,103,115,46,100,97,116,97,1,6,34,68,111,32,121,111,117,32,119,105, + 115,104,32,116,111,32,114,101,118,101,114,116,32,116,111,32,105,110,104,101, + 114,105,116,101,100,6,23,116,104,101,32,115,101,108,101,99,116,101,100,32, + 99,111,109,112,111,110,101,110,116,63,6,38,68,111,32,121,111,117,32,119, + 97,110,116,32,116,111,32,116,111,117,99,104,32,97,108,108,32,108,111,97, + 100,101,100,32,102,111,114,109,115,63,0,4,108,101,102,116,2,48,3,116, + 111,112,2,72,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tformdesignerfo,''); +end. diff --git a/mseide-msegui/apps/ide/guitemplates.mfm b/mseide-msegui/apps/ide/guitemplates.mfm new file mode 100644 index 0000000..5cd4dfe --- /dev/null +++ b/mseide-msegui/apps/ide/guitemplates.mfm @@ -0,0 +1,426 @@ +object guitemplatesmo: tguitemplatesmo + bounds_cx = 483 + bounds_cy = 132 + onloaded = loadedexe + left = 99 + top = 135 + moduleclassname = 'tmsedatamodule' + object fadevertkonvex: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + 14408667 + 13158600 + ) + template.fade_direction = gd_down + left = 24 + top = 16 + end + object fadehorzconvex: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + 14408667 + 13158600 + ) + left = 24 + top = 40 + end + object fadehorzconcave: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + 14408667 + 13158600 + ) + template.fade_direction = gd_left + left = 144 + top = 40 + end + object fadevertconcave: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + 14408667 + 13158600 + ) + template.fade_direction = gd_up + left = 144 + top = 16 + end + object skin: tskincontroller + extenders = 0 + sb_horz_facebutton = fadevertkonvex + sb_horz_faceendbutton = fadevertkonvex + sb_vert_facebutton = fadehorzconvex + sb_vert_faceendbutton = fadehorzconvex + stepbutton_face = fadehorzconvex + widget_color = -2147483645 + container_face = fadehorzconvex + grid_fixrows_face = fadevertkonvex + button_face = fadevertkonvex + databutton_face = fadevertkonvex + framebutton_face = fadehorzconvex + tabbar_horz_face = fadevertconcave + tabbar_horz_tab_face = fadevertkonvex + tabbar_horzopo_face = fadevertconcave + tabbar_horzopo_tab_face = fadevertkonvex + tabbar_vert_face = fadehorzconcave + tabbar_vert_tab_face = fadevertkonvex + tabbar_vertopo_face = fadehorzconcave + tabbar_vertopo_tab_face = fadevertkonvex + mainmenu_face = fadevertconcave + left = 24 + top = 72 + end + object fadecontainer: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612731 + 13421772 + ) + left = 144 + top = 72 + end + object nullface: tfacecomp + left = 272 + top = 16 + end + object sysenv: tsysenvmanager + helpheader = 'MSEide Copyright 1999-2015 by Martin Schreiber'#10'Usage: mseide [OPTION]... [PROJECTFILE]'#10#10'Options:' + helpfooter = #10'Environment variables'#10'FPCDIR, FPCLIBDIR, MSEDIR, MSELIBDIR'#10'SYNTAXDEFDIR, TEMPLATEDIR, COMPSTOREDIR'#10'COMPILER, DEBUGGER, EXEEXT,TARGET,TARGETOSDIR'#10'can be used to override the settings macros.'#10#10'Have a lot of fun!'#10#10'Martin' + left = 24 + top = 96 + defs = ( + ( + ak_pararg + '-globstatfile' + ( ) + [] + '' + '' + 'Set path to global status file.' + '' + '' + ) + ( + ak_pararg + '-macrodef' + ( ) + [] + '' + ',{,,}' + 'Macro definition, will be overridden by ''Project''-''Options''-''Macros''.'#10' Example:'#10' --macrodef=MAC1,abc,MAC2,def' + '' + '' + ) + ( + ak_par + '-storeglobalmacros' + ( ) + [] + '' + '' + 'Store --macrodef values as global macros and terminate MSEide. ' + '' + '' + ) + ( + ak_pararg + '-macrogroup' + ( ) + [] + '' + '' + 'Use ''Project''-''Options''-''Macros''-''Active group'' number ,'#10' = 1..6.' + '' + '' + ) + ( + ak_par + 'np' + ( ) + [] + '' + '' + 'Do not load a project.' + '' + '' + ) + ( + ak_par + 'ns' + ( ) + [] + '' + '' + 'Do not use a skin, no fades.' + '' + '' + ) + ( + ak_par + '-help' + ( ) + [arf_help] + '' + '' + 'Display this help and exit.' + '' + ' ' + ) + ( + ak_envvar + 'FPCDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'FPCLIBDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'MSEDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'MSELIBDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'SYNTAXDEFDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'TEMPLATEDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'COMPSTOREDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'COMPILER' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'DEBUGGER' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'EXEEXT' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'TARGET' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'TARGETOSDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_arg + '' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_par + '-NOZORDERHANDLING' + ( ) + [] + '' + '' + 'Do not touch Z-order of the windows.' + '' + '' + ) + ( + ak_par + '-NORESTACKWINDOW' + ( ) + [] + '' + '' + 'Do not use the NET_RESTACK_WINDOW protocol.' + '' + '' + ) + ( + ak_par + '-RESTACKWINDOW' + ( ) + [] + '' + '' + 'Use the NET_RESTACK_WINDOW protocol.' + '' + '' + ) + ( + ak_par + '-NORECONFIGUREWMWINDOW' + ( ) + [] + '' + '' + 'Do not use xreconfigurewmwindow() for window stacking operation.' + '' + '' + ) + ( + ak_par + '-RECONFIGUREWMWINDOW' + ( ) + [] + '' + '' + 'Use xreconfigurewmwindow() for window stacking operation.' + '' + '' + ) + ( + ak_par + '-STACKMODEBELOWWORKAROUND' + ( ) + [] + '' + '' + 'Necessarry for windowmanagers with buggy xreconfigurewmwindow() handling.' + '' + '' + ) + ( + ak_par + '-NOSTACKMODEBELOWWORKAROUND' + ( ) + [] + '' + '' + 'No workaround.' + '' + '' + ) + ( + ak_par + '-TOPLEVELRAISE' + ( ) + [] + '' + '' + 'Use the top level frame window id instead of the application client window id'#10'for window raise operation. Implies --NORESTACKWINDOW and'#10' --NORECONFIGUREWMWINDOW.' + '' + '' + ) + ) + end +end diff --git a/mseide-msegui/apps/ide/guitemplates.pas b/mseide-msegui/apps/ide/guitemplates.pas new file mode 100644 index 0000000..ccb92b6 --- /dev/null +++ b/mseide-msegui/apps/ide/guitemplates.pas @@ -0,0 +1,113 @@ +unit guitemplates; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseapplication,mseclasses,msedatamodules,msegui,mseskin,msestrings, + msesysenv,msemacros; + +type + envvarty = (env_globstatfile,env_macrodef,env_storeglobalmacros,env_vargroup, + env_np,env_ns,env_help, + env_fpcdir,env_fpclibdir,env_msedir,env_mselibdir,env_syntaxdefdir, + env_templatedir,env_compstoredir,env_compiler,env_debugger, + env_exeext,env_target,env_targetosdir, + env_filename); +const +{ + sysenvvalues: array[envvarty] of argumentdefty = + ((kind: ak_pararg; name: '-macrodef'; anames: nil; flags: []; initvalue: ''), + (kind: ak_pararg; name: '-macrogroup'; anames: nil; flags: []; initvalue: ''), + (kind: ak_par; name: 'np'; anames: nil; flags: []; initvalue: ''), //no project + (kind: ak_par; name: 'ns'; anames: nil; flags: []; initvalue: ''), //no skin + (kind: ak_envvar; name: 'FPCDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'FPCLIBDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'MSEDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'MSELIBDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'SYNTAXDEFDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'TEMPLATEDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'COMPSTOREDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'COMPILER'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'DEBUGGER'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'EXEEXT'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'TARGET'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'TARGETOSDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_arg; name: ''; anames: nil; flags: []; initvalue: '')); +} + firstenvvarmacro = env_fpcdir; + lastenvvarmacro = env_target; + +type + tguitemplatesmo = class(tmsedatamodule) + fadevertkonvex: tfacecomp; + fadehorzconvex: tfacecomp; + fadehorzconcave: tfacecomp; + fadevertconcave: tfacecomp; + skin: tskincontroller; + fadecontainer: tfacecomp; + nullface: tfacecomp; + sysenv: tsysenvmanager; + procedure loadedexe(const sender: TObject); + end; + +function getcommandlinemacros: macroinfoarty; + +var + guitemplatesmo: tguitemplatesmo; +implementation +uses + guitemplates_mfm; + +function getcommandlinemacros: macroinfoarty; +begin + result:= guitemplatesmo.sysenv.getcommandlinemacros( + ord(env_macrodef),ord(firstenvvarmacro),ord(lastenvvarmacro)); +end; + +(* +function getcommandlinemacros: macroinfoarty; +var + ar1,ar2: msestringarty; + int1,int2,int3,int4: integer; +begin + result:= nil; + with guitemplatesmo.sysenv do begin + for int1:= ord(firstenvvarmacro) to ord(lastenvvarmacro) do begin + //envvar macros can be overridden by --macrodef + if defined[int1] then begin + setlength(result,high(result) + 2); + with result[high(result)] do begin + name:= sysenvvalues[envvarty(int1)].name; + value:= guitemplatesmo.sysenv.value[int1]; + end; + end; + end; + ar1:= values[ord(env_macrodef)]; + for int1:= 0 to high(ar1) do begin + ar2:= nil; + splitstringquoted(ar1[int1],ar2,msechar('"'),msechar(',')); + if ar2 <> nil then begin + int3:= length(result); + int4:= (high(ar2)+2) div 2; //pair count + setlength(result,int3+int4); + for int2:= 0 to int4-1 do begin + with result[int2+int3] do begin + int4:= int2 * 2; + name:= ar2[int4]; + if int4 < high(ar2) then begin + value:= ar2[int4+1] + end; + end; + end; + end; + end; + end; +end; +*) + +procedure tguitemplatesmo.loadedexe(const sender: TObject); +begin +// sysenv.init(sysenvvalues); + skin.active:= not sysenv.defined[ord(env_ns)]; +end; + +end. diff --git a/mseide-msegui/apps/ide/guitemplates_mfm.pas b/mseide-msegui/apps/ide/guitemplates_mfm.pas new file mode 100644 index 0000000..df58ae3 --- /dev/null +++ b/mseide-msegui/apps/ide/guitemplates_mfm.pas @@ -0,0 +1,226 @@ +unit guitemplates_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,guitemplates; + +const + objdata: record size: integer; data: array[0..4168] of byte end = + (size: 4169; data: ( + 84,80,70,48,15,116,103,117,105,116,101,109,112,108,97,116,101,115,109,111, + 14,103,117,105,116,101,109,112,108,97,116,101,115,109,111,9,98,111,117,110, + 100,115,95,99,120,3,227,1,9,98,111,117,110,100,115,95,99,121,3,132, + 0,8,111,110,108,111,97,100,101,100,7,9,108,111,97,100,101,100,101,120, + 101,4,108,101,102,116,2,99,3,116,111,112,3,135,0,15,109,111,100,117, + 108,101,99,108,97,115,115,110,97,109,101,6,14,116,109,115,101,100,97,116, + 97,109,111,100,117,108,101,0,9,116,102,97,99,101,99,111,109,112,14,102, + 97,100,101,118,101,114,116,107,111,110,118,101,120,23,116,101,109,112,108,97, + 116,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23, + 116,101,109,112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116, + 101,109,115,1,2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102, + 97,100,101,95,99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101, + 109,112,108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116, + 101,109,115,1,4,219,219,219,0,4,200,200,200,0,0,23,116,101,109,112, + 108,97,116,101,46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7, + 7,103,100,95,100,111,119,110,4,108,101,102,116,2,24,3,116,111,112,2, + 16,0,0,9,116,102,97,99,101,99,111,109,112,14,102,97,100,101,104,111, + 114,122,99,111,110,118,101,120,23,116,101,109,112,108,97,116,101,46,102,97, + 100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101,109,112,108, + 97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1,2, + 0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100,101,95,99, + 111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112,108,97,116, + 101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1,4, + 219,219,219,0,4,200,200,200,0,0,4,108,101,102,116,2,24,3,116,111, + 112,2,40,0,0,9,116,102,97,99,101,99,111,109,112,15,102,97,100,101, + 104,111,114,122,99,111,110,99,97,118,101,23,116,101,109,112,108,97,116,101, + 46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101, + 109,112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109, + 115,1,2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100, + 101,95,99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112, + 108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109, + 115,1,4,219,219,219,0,4,200,200,200,0,0,23,116,101,109,112,108,97, + 116,101,46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,7,103, + 100,95,108,101,102,116,4,108,101,102,116,3,144,0,3,116,111,112,2,40, + 0,0,9,116,102,97,99,101,99,111,109,112,15,102,97,100,101,118,101,114, + 116,99,111,110,99,97,118,101,23,116,101,109,112,108,97,116,101,46,102,97, + 100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101,109,112,108, + 97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1,2, + 0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100,101,95,99, + 111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112,108,97,116, + 101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1,4, + 219,219,219,0,4,200,200,200,0,0,23,116,101,109,112,108,97,116,101,46, + 102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,5,103,100,95,117, + 112,4,108,101,102,116,3,144,0,3,116,111,112,2,16,0,0,15,116,115, + 107,105,110,99,111,110,116,114,111,108,108,101,114,4,115,107,105,110,9,101, + 120,116,101,110,100,101,114,115,2,0,18,115,98,95,104,111,114,122,95,102, + 97,99,101,98,117,116,116,111,110,7,14,102,97,100,101,118,101,114,116,107, + 111,110,118,101,120,21,115,98,95,104,111,114,122,95,102,97,99,101,101,110, + 100,98,117,116,116,111,110,7,14,102,97,100,101,118,101,114,116,107,111,110, + 118,101,120,18,115,98,95,118,101,114,116,95,102,97,99,101,98,117,116,116, + 111,110,7,14,102,97,100,101,104,111,114,122,99,111,110,118,101,120,21,115, + 98,95,118,101,114,116,95,102,97,99,101,101,110,100,98,117,116,116,111,110, + 7,14,102,97,100,101,104,111,114,122,99,111,110,118,101,120,15,115,116,101, + 112,98,117,116,116,111,110,95,102,97,99,101,7,14,102,97,100,101,104,111, + 114,122,99,111,110,118,101,120,12,119,105,100,103,101,116,95,99,111,108,111, + 114,4,3,0,0,128,14,99,111,110,116,97,105,110,101,114,95,102,97,99, + 101,7,14,102,97,100,101,104,111,114,122,99,111,110,118,101,120,17,103,114, + 105,100,95,102,105,120,114,111,119,115,95,102,97,99,101,7,14,102,97,100, + 101,118,101,114,116,107,111,110,118,101,120,11,98,117,116,116,111,110,95,102, + 97,99,101,7,14,102,97,100,101,118,101,114,116,107,111,110,118,101,120,15, + 100,97,116,97,98,117,116,116,111,110,95,102,97,99,101,7,14,102,97,100, + 101,118,101,114,116,107,111,110,118,101,120,16,102,114,97,109,101,98,117,116, + 116,111,110,95,102,97,99,101,7,14,102,97,100,101,104,111,114,122,99,111, + 110,118,101,120,16,116,97,98,98,97,114,95,104,111,114,122,95,102,97,99, + 101,7,15,102,97,100,101,118,101,114,116,99,111,110,99,97,118,101,20,116, + 97,98,98,97,114,95,104,111,114,122,95,116,97,98,95,102,97,99,101,7, + 14,102,97,100,101,118,101,114,116,107,111,110,118,101,120,19,116,97,98,98, + 97,114,95,104,111,114,122,111,112,111,95,102,97,99,101,7,15,102,97,100, + 101,118,101,114,116,99,111,110,99,97,118,101,23,116,97,98,98,97,114,95, + 104,111,114,122,111,112,111,95,116,97,98,95,102,97,99,101,7,14,102,97, + 100,101,118,101,114,116,107,111,110,118,101,120,16,116,97,98,98,97,114,95, + 118,101,114,116,95,102,97,99,101,7,15,102,97,100,101,104,111,114,122,99, + 111,110,99,97,118,101,20,116,97,98,98,97,114,95,118,101,114,116,95,116, + 97,98,95,102,97,99,101,7,14,102,97,100,101,118,101,114,116,107,111,110, + 118,101,120,19,116,97,98,98,97,114,95,118,101,114,116,111,112,111,95,102, + 97,99,101,7,15,102,97,100,101,104,111,114,122,99,111,110,99,97,118,101, + 23,116,97,98,98,97,114,95,118,101,114,116,111,112,111,95,116,97,98,95, + 102,97,99,101,7,14,102,97,100,101,118,101,114,116,107,111,110,118,101,120, + 13,109,97,105,110,109,101,110,117,95,102,97,99,101,7,15,102,97,100,101, + 118,101,114,116,99,111,110,99,97,118,101,4,108,101,102,116,2,24,3,116, + 111,112,2,72,0,0,9,116,102,97,99,101,99,111,109,112,13,102,97,100, + 101,99,111,110,116,97,105,110,101,114,23,116,101,109,112,108,97,116,101,46, + 102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101,109, + 112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115, + 1,2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100,101, + 95,99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112,108, + 97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115, + 1,4,5,0,0,160,4,204,204,204,0,0,4,108,101,102,116,3,144,0, + 3,116,111,112,2,72,0,0,9,116,102,97,99,101,99,111,109,112,8,110, + 117,108,108,102,97,99,101,4,108,101,102,116,3,16,1,3,116,111,112,2, + 16,0,0,14,116,115,121,115,101,110,118,109,97,110,97,103,101,114,6,115, + 121,115,101,110,118,10,104,101,108,112,104,101,97,100,101,114,6,96,77,83, + 69,105,100,101,32,67,111,112,121,114,105,103,104,116,32,49,57,57,57,45, + 50,48,49,53,32,98,121,32,77,97,114,116,105,110,32,83,99,104,114,101, + 105,98,101,114,10,85,115,97,103,101,58,32,109,115,101,105,100,101,32,91, + 79,80,84,73,79,78,93,46,46,46,32,91,80,82,79,74,69,67,84,70, + 73,76,69,93,10,10,79,112,116,105,111,110,115,58,10,104,101,108,112,102, + 111,111,116,101,114,6,218,10,69,110,118,105,114,111,110,109,101,110,116,32, + 118,97,114,105,97,98,108,101,115,10,70,80,67,68,73,82,44,32,70,80, + 67,76,73,66,68,73,82,44,32,77,83,69,68,73,82,44,32,77,83,69, + 76,73,66,68,73,82,10,83,89,78,84,65,88,68,69,70,68,73,82,44, + 32,84,69,77,80,76,65,84,69,68,73,82,44,32,67,79,77,80,83,84, + 79,82,69,68,73,82,10,67,79,77,80,73,76,69,82,44,32,68,69,66, + 85,71,71,69,82,44,32,69,88,69,69,88,84,44,84,65,82,71,69,84, + 44,84,65,82,71,69,84,79,83,68,73,82,10,99,97,110,32,98,101,32, + 117,115,101,100,32,116,111,32,111,118,101,114,114,105,100,101,32,116,104,101, + 32,115,101,116,116,105,110,103,115,32,109,97,99,114,111,115,46,10,10,72, + 97,118,101,32,97,32,108,111,116,32,111,102,32,102,117,110,33,10,10,77, + 97,114,116,105,110,4,108,101,102,116,2,24,3,116,111,112,2,96,4,100, + 101,102,115,1,1,7,9,97,107,95,112,97,114,97,114,103,6,13,45,103, + 108,111,98,115,116,97,116,102,105,108,101,1,0,11,0,6,0,6,10,60, + 102,105,108,101,112,97,116,104,62,6,31,83,101,116,32,112,97,116,104,32, + 116,111,32,103,108,111,98,97,108,32,115,116,97,116,117,115,32,102,105,108, + 101,46,6,0,6,0,0,1,7,9,97,107,95,112,97,114,97,114,103,6, + 9,45,109,97,99,114,111,100,101,102,1,0,11,0,6,0,6,31,60,110, + 97,109,101,62,44,60,118,97,108,117,101,62,123,44,60,110,97,109,101,62, + 44,60,118,97,108,117,101,62,125,6,109,77,97,99,114,111,32,100,101,102, + 105,110,105,116,105,111,110,44,32,119,105,108,108,32,98,101,32,111,118,101, + 114,114,105,100,100,101,110,32,98,121,32,39,80,114,111,106,101,99,116,39, + 45,39,79,112,116,105,111,110,115,39,45,39,77,97,99,114,111,115,39,46, + 10,32,69,120,97,109,112,108,101,58,10,32,45,45,109,97,99,114,111,100, + 101,102,61,77,65,67,49,44,97,98,99,44,77,65,67,50,44,100,101,102, + 6,0,6,0,0,1,7,6,97,107,95,112,97,114,6,18,45,115,116,111, + 114,101,103,108,111,98,97,108,109,97,99,114,111,115,1,0,11,0,6,0, + 6,0,6,63,83,116,111,114,101,32,45,45,109,97,99,114,111,100,101,102, + 32,118,97,108,117,101,115,32,97,115,32,103,108,111,98,97,108,32,109,97, + 99,114,111,115,32,97,110,100,32,116,101,114,109,105,110,97,116,101,32,77, + 83,69,105,100,101,46,32,6,0,6,0,0,1,7,9,97,107,95,112,97, + 114,97,114,103,6,11,45,109,97,99,114,111,103,114,111,117,112,1,0,11, + 0,6,0,6,3,60,110,62,6,71,85,115,101,32,39,80,114,111,106,101, + 99,116,39,45,39,79,112,116,105,111,110,115,39,45,39,77,97,99,114,111, + 115,39,45,39,65,99,116,105,118,101,32,103,114,111,117,112,39,32,110,117, + 109,98,101,114,32,60,110,62,44,10,60,110,62,32,61,32,49,46,46,54, + 46,6,0,6,0,0,1,7,6,97,107,95,112,97,114,6,2,110,112,1, + 0,11,0,6,0,6,0,6,22,68,111,32,110,111,116,32,108,111,97,100, + 32,97,32,112,114,111,106,101,99,116,46,6,0,6,0,0,1,7,6,97, + 107,95,112,97,114,6,2,110,115,1,0,11,0,6,0,6,0,6,28,68, + 111,32,110,111,116,32,117,115,101,32,97,32,115,107,105,110,44,32,110,111, + 32,102,97,100,101,115,46,6,0,6,0,0,1,7,6,97,107,95,112,97, + 114,6,5,45,104,101,108,112,1,0,11,8,97,114,102,95,104,101,108,112, + 0,6,0,6,0,6,27,68,105,115,112,108,97,121,32,116,104,105,115,32, + 104,101,108,112,32,97,110,100,32,101,120,105,116,46,6,0,6,1,32,0, + 1,7,9,97,107,95,101,110,118,118,97,114,6,6,70,80,67,68,73,82, + 1,0,11,0,6,0,6,0,6,0,6,0,6,0,0,1,7,9,97,107, + 95,101,110,118,118,97,114,6,9,70,80,67,76,73,66,68,73,82,1,0, + 11,0,6,0,6,0,6,0,6,0,6,0,0,1,7,9,97,107,95,101, + 110,118,118,97,114,6,6,77,83,69,68,73,82,1,0,11,0,6,0,6, + 0,6,0,6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114, + 6,9,77,83,69,76,73,66,68,73,82,1,0,11,0,6,0,6,0,6, + 0,6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114,6,12, + 83,89,78,84,65,88,68,69,70,68,73,82,1,0,11,0,6,0,6,0, + 6,0,6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114,6, + 11,84,69,77,80,76,65,84,69,68,73,82,1,0,11,0,6,0,6,0, + 6,0,6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114,6, + 12,67,79,77,80,83,84,79,82,69,68,73,82,1,0,11,0,6,0,6, + 0,6,0,6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114, + 6,8,67,79,77,80,73,76,69,82,1,0,11,0,6,0,6,0,6,0, + 6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114,6,8,68, + 69,66,85,71,71,69,82,1,0,11,0,6,0,6,0,6,0,6,0,6, + 0,0,1,7,9,97,107,95,101,110,118,118,97,114,6,6,69,88,69,69, + 88,84,1,0,11,0,6,0,6,0,6,0,6,0,6,0,0,1,7,9, + 97,107,95,101,110,118,118,97,114,6,6,84,65,82,71,69,84,1,0,11, + 0,6,0,6,0,6,0,6,0,6,0,0,1,7,9,97,107,95,101,110, + 118,118,97,114,6,11,84,65,82,71,69,84,79,83,68,73,82,1,0,11, + 0,6,0,6,0,6,0,6,0,6,0,0,1,7,6,97,107,95,97,114, + 103,6,0,1,0,11,0,6,0,6,0,6,0,6,0,6,0,0,1,7, + 6,97,107,95,112,97,114,6,17,45,78,79,90,79,82,68,69,82,72,65, + 78,68,76,73,78,71,1,0,11,0,6,0,6,0,6,36,68,111,32,110, + 111,116,32,116,111,117,99,104,32,90,45,111,114,100,101,114,32,111,102,32, + 116,104,101,32,119,105,110,100,111,119,115,46,6,0,6,0,0,1,7,6, + 97,107,95,112,97,114,6,16,45,78,79,82,69,83,84,65,67,75,87,73, + 78,68,79,87,1,0,11,0,6,0,6,0,6,43,68,111,32,110,111,116, + 32,117,115,101,32,116,104,101,32,78,69,84,95,82,69,83,84,65,67,75, + 95,87,73,78,68,79,87,32,112,114,111,116,111,99,111,108,46,6,0,6, + 0,0,1,7,6,97,107,95,112,97,114,6,14,45,82,69,83,84,65,67, + 75,87,73,78,68,79,87,1,0,11,0,6,0,6,0,6,36,85,115,101, + 32,116,104,101,32,78,69,84,95,82,69,83,84,65,67,75,95,87,73,78, + 68,79,87,32,112,114,111,116,111,99,111,108,46,6,0,6,0,0,1,7, + 6,97,107,95,112,97,114,6,22,45,78,79,82,69,67,79,78,70,73,71, + 85,82,69,87,77,87,73,78,68,79,87,1,0,11,0,6,0,6,0,6, + 64,68,111,32,110,111,116,32,117,115,101,32,120,114,101,99,111,110,102,105, + 103,117,114,101,119,109,119,105,110,100,111,119,40,41,32,102,111,114,32,119, + 105,110,100,111,119,32,115,116,97,99,107,105,110,103,32,111,112,101,114,97, + 116,105,111,110,46,6,0,6,0,0,1,7,6,97,107,95,112,97,114,6, + 20,45,82,69,67,79,78,70,73,71,85,82,69,87,77,87,73,78,68,79, + 87,1,0,11,0,6,0,6,0,6,57,85,115,101,32,120,114,101,99,111, + 110,102,105,103,117,114,101,119,109,119,105,110,100,111,119,40,41,32,102,111, + 114,32,119,105,110,100,111,119,32,115,116,97,99,107,105,110,103,32,111,112, + 101,114,97,116,105,111,110,46,6,0,6,0,0,1,7,6,97,107,95,112, + 97,114,6,25,45,83,84,65,67,75,77,79,68,69,66,69,76,79,87,87, + 79,82,75,65,82,79,85,78,68,1,0,11,0,6,0,6,0,6,73,78, + 101,99,101,115,115,97,114,114,121,32,102,111,114,32,119,105,110,100,111,119, + 109,97,110,97,103,101,114,115,32,119,105,116,104,32,98,117,103,103,121,32, + 120,114,101,99,111,110,102,105,103,117,114,101,119,109,119,105,110,100,111,119, + 40,41,32,104,97,110,100,108,105,110,103,46,6,0,6,0,0,1,7,6, + 97,107,95,112,97,114,6,27,45,78,79,83,84,65,67,75,77,79,68,69, + 66,69,76,79,87,87,79,82,75,65,82,79,85,78,68,1,0,11,0,6, + 0,6,0,6,14,78,111,32,119,111,114,107,97,114,111,117,110,100,46,6, + 0,6,0,0,1,7,6,97,107,95,112,97,114,6,14,45,84,79,80,76, + 69,86,69,76,82,65,73,83,69,1,0,11,0,6,0,6,0,6,161,85, + 115,101,32,116,104,101,32,116,111,112,32,108,101,118,101,108,32,102,114,97, + 109,101,32,119,105,110,100,111,119,32,105,100,32,105,110,115,116,101,97,100, + 32,111,102,32,116,104,101,32,97,112,112,108,105,99,97,116,105,111,110,32, + 99,108,105,101,110,116,32,119,105,110,100,111,119,32,105,100,10,102,111,114, + 32,119,105,110,100,111,119,32,114,97,105,115,101,32,111,112,101,114,97,116, + 105,111,110,46,32,73,109,112,108,105,101,115,32,45,45,78,79,82,69,83, + 84,65,67,75,87,73,78,68,79,87,32,97,110,100,10,32,45,45,78,79, + 82,69,67,79,78,70,73,71,85,82,69,87,77,87,73,78,68,79,87,46, + 6,0,6,0,0,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tguitemplatesmo,''); +end. diff --git a/mseide-msegui/apps/ide/main.mfm b/mseide-msegui/apps/ide/main.mfm new file mode 100644 index 0000000..b5b778b --- /dev/null +++ b/mseide-msegui/apps/ide/main.mfm @@ -0,0 +1,1572 @@ +object mainfo: tmainfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_lockbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 740 + bounds_y = 149 + bounds_cx = 459 + bounds_cy = 149 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.framei_left = 0 + container.frame.framei_top = 0 + container.frame.framei_right = 0 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + container.frame.localprops1 = [] + container.frame.sbhorz.options = [sbo_moveauto, sbo_showauto] + container.frame.sbvert.options = [sbo_moveauto, sbo_showauto] + container.onlayout = onscale + container.bounds = ( + 0 + 16 + 449 + 133 + ) + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_cansize, od_canfloat, od_candock, od_captionhint] + dragdock.optionsdockform = [odf_main, odf_childicons] + optionswindow = [wo_taskbar] + mainmenu = mainmenu1 + options = [fo_main, fo_terminateonclose, fo_globalshortcuts, fo_savepos, fo_savezorder, fo_savestate] + statfile = projectstatfile + caption = 'MSEide' + oncreate = mainfooncreate + oneventloopstart = mainonloaded + ondestroy = mainfoondestroy + onterminatequery = mainfoonterminate + onlayout = onscale + left = 8 + top = 80 + moduleclassname = 'tdockform' + object basedock: tdockpanel + optionswidget1 = [ow1_autoscale, ow1_noparentheightextend] + optionswidget = [ow_background, ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_destroywidgets] + onpaint = basedockpaintexe + bounds_x = 0 + bounds_y = 19 + bounds_cx = 449 + bounds_cy = 114 + anchors = [an_top, an_bottom] + dragdock.optionsdock = [od_acceptsdock, od_splitvert, od_splithorz, od_tabed, od_proportional, od_background, od_captionhint] + statfile = projectstatfile + end + object statdisp: tstringdisp + optionswidget = [ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.colorclient = -2147483645 + frame.localprops = [frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 1 + bounds_cx = 449 + bounds_cy = 18 + anchors = [an_top] + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_xscale] + options = [dwo_hintclippedtext] + reffontheight = 14 + end + object gdb: tgdbmi + guiintf = True + gdbdownload = False + simulator = False + startupbkpt = 0 + startupbkpton = False + onevent = gdbonevent + overloadsleepus = 10000 + left = 120 + top = 32 + end + object mainstatfile: tstatfile + filename = 'mseide.sta' + filedir = '"^/.mseide"' + options = [sfo_createpath, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + onstatupdate = mainstatfileonupdatestat + onstatbeforewrite = mainstatbeforewriteexe + top = 32 + end + object mainmenu1: tmainmenu + options = [mo_shortcutright, mo_activate, mo_updateonidle] + onupdate = mainmenuonupdate + menu.submenu.count = 7 + menu.submenu.items = < + item + submenu.count = 10 + submenu.items = < + item + submenu.count = 1 + submenu.items = < + item + submenu.count = 9 + submenu.items = < + item + caption = '&Mainform' + state = [as_localcaption, as_localonexecute] + onexecute = newformonexecute + end + item + caption = '&Simple Form' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + tag = 1 + onexecute = newformonexecute + end + item + caption = '&Docking Form' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + tag = 2 + onexecute = newformonexecute + end + item + caption = 'D&atamodule' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + tag = 3 + onexecute = newformonexecute + end + item + caption = 'S&ubform' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 4 + onexecute = newformonexecute + end + item + caption = '&Report' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 5 + onexecute = newformonexecute + end + item + caption = 'S&criptform' + name = 'pascform' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 6 + onexecute = newformonexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Inherited' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 7 + onexecute = newformonexecute + end> + caption = '&Form' + name = 'form' + state = [as_localcaption] + end> + caption = '&New' + name = 'new' + state = [as_localcaption] + end + item + action = actionsmo.opensource + end + item + action = actionsmo.save + end + item + action = actionsmo.saveas + end + item + action = actionsmo.saveall + end + item + action = actionsmo.close + end + item + action = actionsmo.closeall + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.print + end + item + caption = 'E&xit' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = exitonexecute + end> + caption = '&File' + name = 'file' + state = [as_localcaption] + end + item + submenu.count = 7 + submenu.items = < + item + action = actionsmo.line + end + item + action = actionsmo.find + end + item + action = actionsmo.repeatfind + end + item + action = actionsmo.findback + end + item + action = actionsmo.replace + end + item + action = actionsmo.findinfile + end + item + action = actionsmo.findcompallact + caption = 'Find &Component' + state = [as_localcaption, as_localshortcut, as_localshortcut1] + end> + caption = '&Search' + name = 'search' + state = [as_localcaption] + end + item + submenu.count = 15 + submenu.items = < + item + action = actionsmo.selecteditpage + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.undo + end + item + action = actionsmo.redo + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.copy + end + item + action = actionsmo.copylatexact + end + item + action = actionsmo.copyword + end + item + action = actionsmo.cut + end + item + action = actionsmo.paste + end + item + action = actionsmo.delete + end + item + action = actionsmo.selectall + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.indent + end + item + action = actionsmo.unindent + end> + caption = '&Edit' + name = 'edit' + state = [as_localcaption] + end + item + submenu.count = 22 + submenu.items = < + item + caption = 'En&vironment' + state = [as_localcaption, as_localimagelist, as_localonexecute] + imagelist = dummyimagelist + onexecute = parametersonexecute + end + item + caption = 'Restart Debugger' + state = [as_localcaption, as_localimagelist, as_localonexecute] + imagelist = dummyimagelist + onexecute = restartgdbonexecute + end + item + action = actionsmo.attachprocess + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + action = actionsmo.attachtarget + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + action = actionsmo.detachtarget + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + action = actionsmo.download + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.continue + end + item + action = actionsmo.reset + end + item + action = actionsmo.interrupt + end + item + action = actionsmo.step + end + item + action = actionsmo.stepi + end + item + action = actionsmo.next + end + item + action = actionsmo.nexti + end + item + action = actionsmo.finish + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.bkptsonact + state = [as_checked] + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = actionsmo.togglebkpt + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + action = actionsmo.togglebkptenable + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.watchesonact + state = [as_checked] + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = actionsmo.bluedotsonact + state = [as_checked] + options = [mao_checkbox, mao_shortcutcaption] + end> + caption = '&Target' + name = 'target' + state = [as_localcaption] + end + item + submenu.count = 28 + submenu.items = < + item + submenu.count = 2 + submenu.items = < + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&New Panel' + state = [as_localcaption, as_localonexecute] + onexecute = newpanelonexecute + end> + caption = 'Pan&els' + name = 'panels' + state = [as_localcaption, as_localimagelist, as_localimagenr] + imagelist = vievmenuicons + imagenr = 0 + end + item + action = actionsmo.forcezorderact + state = [as_localimagelist] + options = [mao_checkbox, mao_shortcutcaption] + imagelist = vievmenuicons + end + item + caption = 'Load Wi&ndow Layout' + state = [as_localcaption, as_localimagelist, as_localonexecute] + imagelist = vievmenuicons + onexecute = loadwindowlayoutexe + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Component &Palette' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 1 + onexecute = viewcomponentpaletteonexecute + end + item + caption = 'Component Sto&re' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 16 + onexecute = viewcomponentstoreonexecute + end + item + caption = 'Object &Inspector' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 14 + onexecute = viewobjectinspectoronexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'So&urce' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + imagenr = 5 + onexecute = viewsourceonexecute + end + item + caption = '&Messages' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + imagenr = 4 + onexecute = viewmessagesonexecute + end + item + caption = '&Find Results' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 15 + onexecute = viewfindresults + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Debugger' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 2 + onexecute = viewdebuggertoolbaronexecute + end + item + caption = 'Symbo&ls' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 18 + onexecute = viewsymbolsonexecute + end + item + caption = '&Watches' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + imagenr = 8 + onexecute = viewwatchesonexecute + end + item + caption = '&Stack' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + imagenr = 9 + onexecute = viewstackonexecute + end + item + caption = 'T&hreads' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 10 + onexecute = viewthreadsonexecute + end + item + caption = '&CPU' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 11 + onexecute = viewcpuonexecute + end + item + caption = '&Assembler' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 12 + onexecute = viewassembleronexecute + end + item + caption = 'Memor&y' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 17 + onexecute = viewmemoryonexecute + end + item + caption = '&Target Console' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 13 + onexecute = viewconsoleonexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Breakpoints' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + imagenr = 6 + onexecute = viewbreakpointsonexecute + end + item + caption = 'Watchp&oints' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 7 + onexecute = viewwatchpointsonexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.toggleinspector + state = [as_localimagelist, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + onexecute = toggleobjectinspectoronexecute + end + item + action = actionsmo.toggleformunit + caption = 'Toggle Form/Unit' + state = [as_localcaption, as_localimagelist] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + end + item + name = 'formmenuitemstart' + options = [mao_separator, mao_shortcutcaption] + end> + caption = '&View' + name = 'view' + state = [as_localcaption] + end + item + submenu.count = 19 + submenu.items = < + item + action = actionsmo.makeact + caption = '&Make' + state = [as_localcaption, as_localtag] + tag = 1 + end + item + action = actionsmo.buildact + caption = '&Build' + state = [as_localcaption, as_localtag] + tag = 2 + end + item + action = actionsmo.make1act + caption = 'Make &1' + state = [as_localcaption, as_localtag] + tag = 4 + end + item + action = actionsmo.make2act + caption = 'Make &2' + state = [as_localcaption, as_localtag] + tag = 8 + end + item + action = actionsmo.make3act + caption = 'Make &3' + state = [as_localcaption, as_localtag] + tag = 16 + end + item + action = actionsmo.make4act + caption = 'Make &4' + state = [as_localcaption, as_localtag] + tag = 32 + end + item + action = actionsmo.abortmakeact + caption = '&Abort Make' + state = [as_localcaption, as_localtag] + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.projectoptionsact + end + item + action = actionsmo.projecttreeact + end + item + action = actionsmo.projectsourceact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + submenu.count = 3 + submenu.items = < + item + caption = 'From &Template' + state = [as_localcaption, as_localonexecute] + onexecute = newprojectonexecute + end + item + caption = 'From &Program' + state = [as_localcaption, as_localonexecute] + onexecute = newprojectfromprogramexe + end + item + caption = '&Empty' + state = [as_localcaption, as_localonexecute] + onexecute = newemptyprojectexe + end> + caption = '&New' + state = [as_localcaption] + end + item + action = actionsmo.projectopenact + end + item + caption = 'Open copy' + state = [as_localcaption, as_localonexecute] + onexecute = openprojectcopyexecute + end + item + action = actionsmo.projectsaveact + end + item + caption = 'Save &as' + state = [as_localcaption, as_localonexecute] + onexecute = saveprojectasonexecute + end + item + caption = 'Save as copy' + state = [as_localcaption, as_localonexecute] + onexecute = saveprojectcopyexecute + end + item + action = actionsmo.projectcloseact + caption = '&Close' + name = 'close' + state = [as_localcaption, as_localonexecute] + onexecute = closeprojectactonexecute + end> + caption = '&Project' + name = 'project' + state = [as_localcaption, as_localonexecute] + onexecute = aboutonexecute + end + item + submenu.count = 2 + submenu.items = < + item + caption = '&About' + state = [as_localcaption, as_localonexecute] + onexecute = aboutonexecute + end + item + caption = '&Configure MSEide' + state = [as_localcaption, as_localonexecute] + onexecute = configureexecute + end> + caption = 'Sett&ings' + name = 'settings' + state = [as_localcaption, as_localonexecute] + onexecute = aboutonexecute + end> + left = 103 + top = 96 + end + object openfile: tfiledialog + statfile = projectstatfile + controller.options = [fdo_checkexist] + controller.captionopen = 'Open file' + controller.captionsave = 'Save file as' + top = 1 + end + object projectstatfile: tstatfile + filename = 'status.sta' + onstatbeforeread = statbefread + onstatafterread = statafterread + top = 64 + end + object vievmenuicons: timagelist + width = 18 + height = 18 + options = [bmo_masked, bmo_colormask] + count = 19 + left = 313 + top = 96 + image = { + 00000000060000005A0000005A000000883D0000000000000000000000000000 + 0000000000000000000000000000000000000000FFFFFF06CB582601C5440B01 + FFFFFF03C23B0001FFFFFF06A8A8A801B8B8B807D4D4D401E9E9E908E5E5E501 + ADADAD01BEBEBE11D0D0D001FFFFFF11E0E0E001FFFFFF10D0D0D001FFFFFF02 + C6390001FF000001FFFFFF01FD430901DF8C6A01DF886401EA370501EA360501 + DD522201DA815C01DE3E0601FD430901FFFFFF04DCDCDC01CACACA07FFFFFF08 + CACACA01A7A7A701BEBEBE01D0D0D0113C3C3C01D0D0D0108DB4B701D0D0D001 + 7C7C7C0FFFFFFF010000FF01FFFFFF02CD623201DD937201D9603201EB370501 + DF7F5D01FCF7F401D75A3101D43F1501EDC0AF01EEC3B101DD330201EB370501 + F63E0801FFFFFF03E9E9E901FFFFFF08CACACA01C4C4C401C5C5C501C8C8C802 + CACACA0185858501CACACA018A8A8A01BEBEBE01D0D0D00302AC080101AA0901 + D0D0D00CB5F8FE01D0D0D010FFFFFF017C7C7C02E8E8E80EFFFFFF01D0D0D001 + FFFFFF02C5491601EEC5B401F7E2DA01DB755101D24B2101FBF2EE01F1CDBF01 + D6664101FFFFFF01E2957A01D3270001D92C0101E5330401DA673B01D4744A01 + FFFFFF01E9E9E901FFFFFF01B5B5B501B7B7B701BEBEBE01D8D8D801E0E0E001 + 85858501FFFFFF01B1B1B1017D7D7D01979797019A9A9A0187878701CACACA01 + 85858501CACACA018A8A8A01BEBEBE01D0D0D00304B206010DB40D0108AD0E01 + D0D0D00B6FC7CE01D0D0D0102F2F2F01D0D0D0017C7C7C01E8E8E80EFFFFFF01 + 74959601FFFFFF02F63E0801DC785201FEFDFC01FFFFFF01E8AE9901D8734F01 + FCF6F301D4684201F6DFD601DA725201D36A4001D0421901DD836201F7E6DE01 + D9744B01FFFFFF01E5E5E501FFFFFF0195959501919191018F8F8F01ACACAC01 + E0E0E00185858501FFFFFF01B5B5B501B1B1B101A5A5A501A6A6A601A0A0A001 + CACACA0185858501CACACA01A7A7A701BEBEBE01D0D0D00305B3060122CD1501 + 1DB81B010EAD1301D0D0D00A181818017C7C7C0FFFFFFF0100000001D0D0D001 + 7C7C7C01E8E8E80EFFFFFF0100000001FFFFFF01FD430901EB370501D43E1101 + DB7B5901FFFFFF01FCF4F101C8523201CC715501A65642016A9A8C01D13E1D01 + D66A4801F5DED401FFFEFE01DA744F01E8380501FD430901DBDBDB01F0F0F001 + E0E0E005FFFFFF0AFCFCFC01BEBEBE01D0D0D00305B3060122CD150138D42C01 + 35C8310114AD190100A90901D0D0D0097C7C7C01E8E8E80EFFFFFF017A7AFF01 + 9BBABA017C7C7C01E8E8E80EFFFFFF010000FF01FFFFFF01F53D0701E2310301 + DC815F01D97A5601D86F4E01D97253011EECE5014EB3AE017A7E7B0128E0DB01 + D5412901FCF7F401FFFFFF01E3957B01D22B0401E2310301F53D0701DFDFDF01 + F5F5F501D3EBEB01E5EFEF01F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801CAE0E001E0E4E401E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + E1E1E101BEBEBE01D0D0D00305B3060122CD150138D42C014DDB420154D94C01 + 1DB1210100A90901D0D0D0070404FF017C7C7C01E8E8E8017B7B7B014F4F4F01 + 74747401E8E8E802BABABA0160606001E8E8E801E6E6E6015F5F5F014A4A4A01 + 98989801E8E8E801FFFFFF01FF002601D0D0D0017C7C7C01E8E8E80192929201 + 31313101E8E8E802C1C1C10115151501E8E8E801454545014F4F4F03BABABA01 + E8E8E801FFFFFF01E0E0E001FFFFFF01EB390501D6401301D3593101D5664201 + DC765901D654370181777501BA6F7301D6CDCE01B74E52015CA49F01CF775B01 + DA7B5B01D34E2901D6583201D64C2001E93905017ACACC0160D6D90137D7DE01 + 32D2D80198DEDF01EEEEEE01EDEDED01EBEBEB01EAEAEA0157D0D30135D5DC01 + 31CDD201ACDADB01E2E2E201E0E0E001DFDFDF01DDDDDD01DEDEDE01BEBEBE01 + D0D0D00305B3060122CD150138D42C014DDB420162E2580171E669012EB83101 + 13B21A01D0D0D0067272FF017C7C7C01C6C6C60155555501E8E8E80153535301 + CBCBCB01ACACAC015353530150505001E8E8E8019999990182828201E8E8E801 + 37373701E7E7E701FFFFFF02000068017C7C7C01E8E8E801898989012C2C2C01 + BCBCBC01E8E8E8017474740124242401E8E8E80139393901E8E8E805FFFFFF01 + E0E0E001C23B0001D6744B01F8E8E101FFFFFF03D16D55014AB8B601C1737B01 + D6B2B601A7636B0123E6E201BB533C01EAB4A101FEFBFA01FCF4F101E39F8401 + D857270145C3C7013DD5DB01B2F3FF0184F1FF013ED1D501EEEEEE01E0E0EC01 + EBEBEB01CEE4E40140D7DF01B0F3FF0176F1FF0147CFD101E2E2E201D3D3E001 + DFDFDF01DDDDDD01DEDEDE01BEBEBE01D0D0D00305B3060122CD150138D42C01 + 4DDB420162E2580177E96E018BF084014CC64D0121B42701D0D0D0059797FF01 + 7C7C7C01A1A1A10182828201E8E8E8017E7E7E01A4A4A401E3E3E301E1E1E101 + 50505001E8E8E80172727201B1B1B101E8E8E8014F4F4F01D3D3D301FFFFFF01 + D0D0D0010000FF017C7C7C01E8E8E801898989017B7B7B016E6E6E01E8E8E801 + 6060600139393901E8E8E8013636360174747403DEDEDE01E8E8E801FFFFFF01 + 67676701FFFFFF01DE441301D8674101E8AC9601FCF6F301DE856A01BC453201 + 25E3DF019D4E5A0158A3A9019C515C01D75B4401DD745B01D55E3B01D9624501 + D2431D01D42A0001EA36050138C3CA013FD8E001C7F3FF0190F2FF0134D1D501 + EEEEEE013434DF01E5E5EA01ACDEDE014CDFE901D0F4FF0186F1FF0138CED101 + E2E2E2013434DD01D0D0DF01DDDDDD01D9D9DE01BEBEBE01D0D0D00305B30601 + 22CD150138D42C014DDB420162E2580177E96E018BF084014AC14B01146D1701 + 00000001D0D0D0057C7C7C01B1B1B10180808001E8E8E8017B7B7B01A8A8A801 + E8E8E801E1E1E10150505001E8E8E80181818101B0B0B001E8E8E8014C4C4C01 + D8D8D801FFFFFF01888888017C7C7C02E8E8E801898989019F9F9F0149494901 + BBBBBB018C8C8C0139393901E8E8E80138383801C4C4C403E5E5E501E8E8E801 + FFFFFF010000FF01FFFFFF01EB370501D72A0001D3260401D2502A01E1927A01 + D7694901DB655101D35C470140C2C20195686301F6E1D901FFFFFF01F6E0D701 + D8674601D3290701D72A0001EB37050138C3C9013CCED20151E6F30138DEE901 + 6BD6D701ACACE9010C0CEC018383E601E8E9E90130CACE015FEBF90136DEE801 + 74D2D301B8B8E0010F0FEA016666DF01DDDDDD01B9B9DE01BEBEBE01D0D0D003 + 05B3060122CD150138D42C014DDB420162E2580171E669012BAE2E0106370801 + 00000002D0D0D004000000017C7C7C01E3E3E30156565601E8E8E8014E4E4E01 + CFCFCF01E8E8E801E1E1E10150505001E8E8E801BBBBBB017E7E7E01E4E4E401 + 39393901E8E8E801FFFFFF037C7C7C01E8E8E801898989019F9F9F0177777701 + 46464601D8D8D80139393901E8E8E80139393901E8E8E805FFFFFF01D0D0D001 + FFFFFF01EF390601DB2C0101D33F1901EEBFAF01F0C7BA01DA7B5E01FFFFFF01 + EFC7BA01D2321F01DC765D01D66A4A01FCF5F201FFFFFF01FFFEFE01DF886901 + D9320601EF39060143BDC101EAE4E40182CDCE01A6D3D401ECE1E1014141E501 + 0404FF013333E601E9E6E601D3D6D60165C3C5019ACBCB01E0D5D5014646E101 + 0404FE012929E501DADADD016B6BDF01BEBEBE01D0D0D00305B3060122CD1501 + 38D42C014DDB420154D94C011A9D1D010015010100000002D0D0D005FFFFFF01 + 7C7C7C01E8E8E801959595015A5A5A0190909001E8E8E802E3E3E30176767601 + E8E8E801E6E6E6017B7B7B0159595901AEAEAE01E8E8E801FFFFFF0200000001 + 7C7C7C01E8E8E801A1A1A101B1B1B101C7C7C70165656501E8E8E80165656501 + E8E8E801606060014F4F4F03A6A6A601E8E8E801FFFFFF0188888801FFFFFF01 + F53D0701DB481B01EAB39E01FFFFFF01D8704E01F9E7E101FFFFFF01E2937C01 + D2402201FCF4F101E9AB9901D55F3C01DD7C6101E18E7301E49F8601D4613501 + F53D0701C8CECE01D4161E01DE1B2802AD1A3A011818ED010404FF010E0EF301 + AC7FAC01D3151D01DC192602B71B2E011B1BE9010404FF010707F6018888DD01 + 3C3CE301BEBEBE01D0D0D00305B3060122CD150138D42C0136C7300110891401 + 0004000100000001D0D0D007FFFFFF017C7C7C01E8E8E80EFFFFFF02D0D0D001 + 7C7C7C01E8E8E80EFFFFFF0100000001FFFFFF01FD430901D56A3E01E08C6D01 + DA6C4B01D86D4A01FFFFFF01E9AE9C01D45D3B01D8664901E9AE9A01FFFFFF01 + DC735601D5200501D4240201DA2B0101E6380501FD430901C6434901ED011801 + FF002002791278013838E6013C3CE7013B3BE6017D50AA01ED011801FF002002 + 8B1467013333E3013939E4013838E3015757DE011B1BEF01BEBEBE01D0D0D003 + 05B3060122CD15011CB51A01096B0C0100000002D0D0D008FFFFFF017C7C7C01 + FFFFFF0FD0D0D001FFFFFF017C7C7C01E8E8E80EFFFFFF04E83C0601E6330401 + D62B0001E0937601DB795901D32F1201E0896F01DD7D6101D9684A01FFFFFF01 + DF886B01D4240201D72A0001E6330401F63E0801FFFFFF01CF081801ED011801 + FF002002D8202901EEEEEE01EDEDED01EBEBEB01DDB0AF01ED011801FF002002 + D71F2801E2E2E201E0E0E001DFDFDF01DDDDDD012929E901BEBEBE01D0D0D003 + 04B206010CAE0D010343060100000002D0D0D009FFFFFF01D0D0D0108A8A8A01 + FFFFFF017C7C7C01E8E8E80EFFFFFF05F43D0701E2340401D5502501D4260001 + D4240201D9755201D3462201D3320E01EFC7B801E1947801DA2B0101E6330401 + F43D0701FFFFFF02D8001501D01A2001D9202A02C61D1E01EEEEEE01EDEDED01 + EBEBEB01DDB0AF01CF181E01D71F2802C51C1C01E2E2E201E0E0E001DFDFDF01 + DDDDDD017E7EE101BEBEBE01D0D0D00302AC08010033030100000002D0D0D00A + F5E1E201D0D0D0100000FF01D0D0D0017C7C7C01E8E8E80EFFFFFF01D0D0D001 + FFFFFF04F63E0801EB370501E2310301DB2C0101D62B0001D5290001D72A0001 + D96B4401DE846201EB370501F63E0801FFFFFF03D2061701F5F5F501F3F3F301 + F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601 + E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DEDEDE01BEBEBE01 + D0D0D00400000002D0D0D01CFF00FF01888888017C7C7C01FFFFFF15FD430901 + F53D0701EF390601EB370501EA360501EB370501E5400D01E04E1A01FD430901 + FFFFFF04C0282D01D92F3801DB313A01D3303501D25D5E01EDEDED02EBEBEB01 + E3CBCA01D87A7C01D22A3001D82F3702CB2D2F01D6969601E1E1E101DFDFDF01 + DEDEDE01BEBEBE01D0D0D00281C283010E8F1301002A0201000400010C0C0C01 + 80808001D0D0D00979797901FFFFFF10C9C9C9017C7C7C01FFFFFF103BEFFF01 + D0D0D001FFFFFF10E0E0E001D0D0D012FFFFFF09C0C0C001FFFFFF08D0D0D012 + 00000001FFFFFF0F00000001D0D0D012E0E0E001D0D0D0390000FF01D0D0D00D + 010101011C1C1C01D0D0D00188888808878E8E018686860100000001D0D0D004 + 7C7C7C01D0D0D011D9D9D901D0D0D00600000006D0D0D005FFFFFF01D0D0D011 + 80808001E0E0E001D0D0D0020000FF02D0D0D00100000008D0D0D003D9D9D902 + D0D0D00188888801B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01 + D3FEFE01A0AFB0019EC1C5016363630100000001D0D0D0030000FF01D0D0D008 + 0000B602D0D0D008FFFFFF01D0D0D00400000008D0D0D004E9A49101D0D0D012 + 000000010000FF0500000008D0D0D003353535013E3E3E01D0D0D00188888801 + B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE01A7B6B701 + E0FCFF019CC1C5016565650100000001D0D0D0090505C6010B0BCE011515D501 + 1A1AD5011616CE010D0DC601D0D0D006FFFFFF01D0D0D0040000000218189B01 + 3434FF013F3FFE012D2D9B0100000002D0D0D004FCF3F001D0D0D0017C7C7C0F + FFFFFF01D0D0D0014E4E4E010000FF01D0D0D0010000FF02D0D0D00400000003 + D0D0D00100000001D0D0D00300000002D0D0D00188888801B5F8FE018BBABD01 + 97C6C90197C2C401ACD7D901B2DADB019DBDBD019AB5B701F0FDFF01DDFCFF01 + 9BC2C5016767670100000001D0D0D001A7CDCE01D0D0D0050303C8011515E901 + 2929FF013434FF014040FF014B4BFF013A3AE4011313BB01D0D0D005F3C3B601 + D0D0D0030000000100000101060638012929FF013434FF014040FF014B4BFF01 + 191948010000010100000001D0D0D003E0E0E001D0D0D0017C7C7C01E8E8E80E + FFFFFF01D0D0D001D9D9D9010000FF01D0D0D0010000FF02D0D0D00400000005 + D0D0D0030000FF01D0D0D00288888801B5F8FE017CA6A90175999B0174959601 + 8DB1B2018BABAB0195B3B3018DB4B701BCF8FF01F3FDFF01DBFBFF019BC4C701 + 686A6A0100000001D0D0D0050303C6010D0DE9011E1EFF012929FF013434FF01 + 4040FF014B4BFF015656FF014242E2010D0D8E01D0D0D003DADADA01804CF001 + D0D0D0030404EA010E0ED3011919DE012929FF013434FF014040FF014B4BFF01 + 1F1F5C0104040B0139398301D0D0D0057C7C7C01E8E8E8016161610162626201 + 61616101E7E7E7019C9C9C015D5D5D0158585801BABABA01D9D9D90156565601 + 616161017C7C7C01E8E8E801FFFFFF0180808001D0D0D0010000FF01D0D0D007 + 00000005D0D0D003C9F6F601B2F3F601D0D0D00188888801B5F8FE01BAF9FE01 + BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE0193B9BB0188B3B70190B4B701 + 98B5B7018BAFB301858C8C01000000010000FD01D0D0D0040303CE011212FF01 + 1E1EFF012929FF013434FF014040FF014B4BFF015656FF016262FF011B1BB401 + 00000001D0D0D0029523410100FCF801D0D0D0030606FF011111FF011D1DFF01 + 2929FF013434FF014040FF013636B6010202050124245E015757CC0100000001 + D0D0D00209A40001D0D0D0017C7C7C01CACACA0192929201E8E8E80174747401 + B4B4B40175757501E6E6E601D1D1D10157575701AAAAAA01B1B1B101E8E8E801 + 4A4A4A01E0E0E001FFFFFF01D0D0D001B5F8FE010000FF01D0D0D00400000006 + D0D0D0020000FF03D0D0D0010606FC01D0D0D00188888801B5F8FE01BAF9FE01 + BFFAFE01C4FBFE01B5E2E401A7CDCE019BBABA01A9CFCF0194CACC017FC3C801 + 89F5FE0172F2FE018888880100000001E0E0E001EEEEEE01D0D0D0020000B601 + 0202D5011212FF011E1EFF012929FF013434FF014040FF014B4BFF015656FF01 + 6262FF012929C40100000D01D0D0D002000000010DB60001D0D0D0030606FF01 + 1111FF011D1DFF012929FF013434FF012E2EB8010303090114143B016060F701 + 6868F00100000001D0D0D00280808001E07000017C7C7C01E8E8E802CFCFCF01 + 48484801DEDEDE01E8E8E80267676701A6A6A601E8E8E802B4B4B40158585801 + E8E8E801FFFFFF010000010176D3DB010000FF01D0D0D00400000006D0D0D004 + 0000FF01BDBDBD01D0D0D00288888801B5F8FE01BAF9FE01BFFAFE01C4FBFE01 + A8D2D40191B3B30197B5B5019FC3C30183B2B4016BA5A90189F5FE0172F2FE01 + 8888880100000001E0E0E001FFFFFF01D0D0D0020000B6010202D5011212FF01 + 1E1EFF012929FF013434FF014040FF014B4BFF015656FF016262FF012929C401 + 00000A01D0D0D00200000001D0D0D0040606FF011111FF011D1DFF012929FF01 + 2B2BD301020206010E0E31015151EE016363FF016868F00100000001D0D0D002 + FFFFFF01000000017C7C7C01E8E8E80251515101D1D1D101E8E8E8029F9F9F01 + 83838301E8E8E802E7E7E70142424201E2E2E201E8E8E801FFFFFF0100000001 + 0F0F56010000FF01D0D0D00E0000FF01A3A3A30103030301D0D0D00188888801 + B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01B0D8D901CEF8F801C9F6F601 + B2F3F6019FF5FB0186F0F90172F2FE018888880100000001FFFFFF0100000001 + D0D0D0030303CE011212FF011E1EFF012929FF013434FF014040FF014B4BFF01 + 5656FF016262FF011A1AB30100000001D0D0D002FFFFFF014F4F4F01D0D0D003 + 0606FF011111FF011D1DFF012929FF0113135F0103030C014545E9015757FF01 + 6363FF015757CC0100000001D0D0D00247474701FFFFFF017C7C7C01E8E8E802 + ABABAB01E8E8E803C0C0C001D4D4D401E8E8E802E3E3E301B1B1B101E8E8E802 + FFFFFF0100000001E0E0E0010000FF01D0D0D00E0000FF01D0D0D00388888801 + B5F8FE01BAF9FE01BFFAFE01C4FBFE019AC2C3018DADAD01839D9D017A959501 + 83B3B5015B8C8F0154979C0172F2FE018888880100000002FFFFFF01D0D0D003 + 0303C6010C0CE4011E1EFF012929FF013434FF014040FF014B4BFF015656FF01 + 4242E2010A0A6C0100000001D0D0D00200000001FFFFFF01D0D0D0030404FF01 + 1111FE011D1DFF012929FF010B0B36010F0F3D014B4BFF015757FF016262FE01 + 2626590100000001D0D0D002CE331101FFFFFF017C7C7C01E8E8E80260606001 + E8E8E80391919101B8B8B801E8E8E802D7D7D70172727201E8E8E802FFFFFF02 + E0E0E0010000FF01D0D0D00200000008D0D0D0040000FF01D0D0D00388888801 + B5F8FE01BAF9FE01BCF6FA01C4FBFE01BCECEE01AFD7D8018DA9A901B3DBDB01 + 8FC3C50180C4C90176D3DB0172F2FE0188888801000000010000FF0100000001 + D0D0D0040303BB011414E2012929FF013434FF014040FF014B4BFF013939E201 + 0F0F9A0100000002D0D0D002FFFFFF02D0D0D0040F0FDF011D1DFE012929FF01 + 2626BC013232C7014B4BFF015656FE013E3E9E0100000002D0D0D002CF350B01 + 000000017C7C7C01E8E8E80EFFFFFF0100000001D0D0D0010000FF02D0D0D001 + 00000008D0D0D0010000FF02D0D0D0010000FF01D0D0D00388888801B5F8FE01 + 92C3C70190BCBF0193BCBE017592930192B4B401CCF5F501CFFEFE01B8FBFE01 + A1F8FE0189F5FE0172F2FE018888880100000001FFFFFF0100000001D0D0D005 + 04048E010A0AB4011313C4011717C4011313B30107076C0100000002D0D0D003 + 8C8C8C01D5503001D0D0D005101088012121CC012222A7012B2BAC013B3BCC01 + 1F1F590100000002D0D0D00380808001FFFFFF017C7C7C01FFFFFF0F00000001 + FFFFFF01D0D0D00A00000001D0D0D0010000FF02D0D0D0010000FF01FFFFFF02 + D0D0D00188888801B5F8FE017AA3A60189B3B6018FB7B90188AAAB0191B3B301 + CDF7F701CFFEFE01B8FBFE01A1F8FE0189F5FE0172F2FE018888880100000001 + FFFFFF018C8C8C01D0D0D0060000000100000D0100000A0100000003D0D0D004 + F5F5F501804CF001D0D0D00600000006D0D0D005FFFFFF01D0D0D0108C8C8C01 + FFFFFF01D0D0D003000000080000FF05D0D0D0038888880E00000001D0D0D001 + FFFFFF01D0D0D010FFFFFF02D0D0D00700000002D0D0D007FFFFFF0100000001 + D0D0D010FFFFFF01FF1E4001D0D0D00300000008D0D0D0010000FF02D0D0D005 + 0000000F88888801C6C6C601D0D0D010FFFFFF02D0D0D010FFFFFF01D7D7D701 + D0D0D010E4E4E401D0D0D00E0000FF01D0D0D004FFFFFF0C00000003FFFFFF01 + D0D0D001FFFFFF0C00000001FFFFFF05E0E0E001FFFFFF10D0D0D001BBBBBB01 + B0B0B001DBDBDB01A2A2A201BABABA01E3E3E3018C8C8C01E3E3E3019E9E9E03 + 8D8D8D018C8C8C01FFFFFF057C7C7C01FFFFFF10CEFDFE01ADADAD01DE445B01 + E91B3A02DE435A01BEBEBE0DFFFFFF0AC2C2C2013A3A3A013B3B3B01C6C6C601 + FFFFFF03E07C6101D0D0D001FFFFFF10D0D0D002FFFFFF1000000001D0D0D001 + FFFFFF11BEBEBE01D0D0D001FF1E4003D0D0D00D00000001D0D0D010804CF001 + D0D0D011959595010000FF017C7C7C0FFFFFFF01BAF9FE01BCF8FF01D0D0D004 + 0DEEFF01D0D0D00BFFFFFF01BEBEBE01D0D0D001FF1E4004D0D0D00CCD2D0401 + D0D0D010F8FCF8017C7C7C01D0D0D00188888808878E8E018686860100000001 + D0D0D00488888801000000017C7C7C01E8E8E80EFFFFFF0167676701FFFFFF01 + D0D0D00233EFFF0147EFFF0142EFFF0127EEFF010DEEFF01D0D0D00927EEFF01 + BEBEBE01D0D0D003FF1E4004D0D0D00AF8FCF801D0D0D0114A4A4A01D0D0D001 + 88888801B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE01 + A0AFB0019EC1C5016363630100000001D0D0D0037ABCC0018DB1B2017C7C7C01 + E8E8E80EFFFFFF010000FF01F3F3F301D0D0D0013BEFFF016FF1FF018EF1FF01 + 87F1FF015FF0FF0128EEFF010AB2BF01D0D0D009BEBEBE01D0D0D004FF1E4005 + D0D0D0097C7C7C0FFFFFFF01D9D9D9018AB4B701D0D0D00188888801B5F8FE01 + BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE01A7B6B701E0FCFF01 + 9CC1C5016565650100000001D0D0D0021C1C1C01D0D0D0017C7C7C01E8E8E80E + FFFFFF01E0E0E001D0D0D00258F0FF019AF2FF01D0F4FF01C1F3FF0184F1FF01 + 42EFFF010CD6E50100000001D0D0D007FF002601B8BFC101D0D0D006FF1E4004 + D0D0D006C8D0D301D0D0D0017C7C7C01E8E8E80EFFFFFF013C3C3C0188888801 + D0D0D00188888801B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01 + D3FEFE019AB5B701F0FDFF01DDFCFF019BC2C5016767670100000001D0D0D001 + FFFFFF010000FF017C7C7C01E8E8E80EFFFFFF016262F1018080FF01D0D0D001 + 58F0FF019AF2FF01D0F4FF01C1F3FF0184F1FF0142EFFF010DE6F70100000001 + D0D0D0020808FF01D0D0D0043838380183C8E5018ADCFF018EDEFF01D0D0D006 + FF1E4004D0D0D00276D7FF018ADCFF017FD6FA01323232017C7C7C01E8E8E801 + 7B7B7B014F4F4F0174747401E8E8E802BABABA0160606001E8E8E801E6E6E601 + 5F5F5F014A4A4A0198989801E8E8E801FFFFFF02B2B2B201D0D0D00188888801 + B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE018DB4B701 + BCF8FF01F3FDFF01DBFBFF019BC4C701686A6A01000000010404FF01E0E0E001 + 7C7C7C01E8E8E807BDBDBD018E8E8E01E0E0E001E8E8E804FFFFFF01D9D9D901 + A1A1FF01D0D0D0013BEFFF016FF1FF018EF1FF0187F1FF015FF0FF0128EEFF01 + 0BC0CE0100000001D0D0D0010000FF010404FF0100008F01D0D0D003D9D9D901 + 9AD1E901B4E9FF0190DEFF018FDEFF01D0D0D006FF1E4003D0D0D0018BDDFF01 + 9BE1FF01B4E9FF0193DFFF01B8B8B8017C7C7C01C6C6C60155555501E8E8E801 + 53535301CBCBCB01ACACAC015353530150505001E8E8E8019999990182828201 + E8E8E80137373701E7E7E701FFFFFF02FF002001D0D0D00188888801B5F8FE01 + BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE0193B9BB0188B3B701 + 90B4B70198B5B7018BAFB301858C8C0100000001FF002601E0E0E0017C7C7C01 + E8E8E807D2D2D2015D5D5D011A1A1A0169696901C9C9C901E8E8E802FFFFFF03 + D0D0D0010DEEFF0131E5F50147EFFF0142EFFF0127EEFF010CE1F10103333601 + 00000001D0D0D0010303FF010404FF010303BB0100000001D0D0D002CEFDFE01 + BADBE901DDF5FF0192DFFF0191DEFF01FF002601D0D0D001FF002601D0D0D001 + FF002601D0D0D001FF002601D0D0D001FF002601D0D0D001B6E9FF01C6EEFF01 + DDF5FF01B5E9FF01FFFFFF017C7C7C01A1A1A10182828201E8E8E8017E7E7E01 + A4A4A401E3E3E301E1E1E10150505001E8E8E80172727201B1B1B101E8E8E801 + 4F4F4F01D3D3D301FFFFFF01AE755801D0D0D00288888801B5F8FE01A8E2E601 + 85AEB001BEF3F601C9FCFE01CEFDFE01A8CACA01CFFEFE01B8FBFE017ABCC001 + 6FC7CE0172F2FE0188888801000000019F9FFF01929292017C7C7C01E7E7E701 + 858585012E2E2E0153535301A4A4A401B4B4B4018C8C8C01E8E8E802DBDBDB01 + 888888012B2B2B0144444401E2E2E201FFFFFF0100000001D0D0D00306747C01 + 08949E010AAFBB01088E9801011A1C01000000020707FF010404FF020404FC01 + 02025501D0D0D002FFFFFF01D4E2E801F8FBFD0195DFFF0194DFFF01FF002601 + A3E4FF01FF002601A3E4FF01FF002601A3E4FF01FF002601A3E4FF01FF002601 + A3E4FF01E1F6FF01F1FAFF01F8FBFD01D9F3FE01CB2203017C7C7C01B1B1B101 + 80808001E8E8E8017B7B7B01A8A8A801E8E8E801E1E1E10150505001E8E8E801 + 81818101B0B0B001E8E8E8014C4C4C01D8D8D801FFFFFF01E0E0E001D0D0D002 + 88888801B3F5FB0142585A018AB4B701556C6E01C9FCFE01708A8A01343F3F01 + CFFEFE017AA6A8015E9194013A686C015EC7D1018888880100000001D0D0D002 + 7C7C7C01E2E2E20169696901AEAEAE01777777012B2B2B0124242401A0A0A001 + E8E8E802DFDFDF018D8D8D012D2D2D0143434301E2E2E201FFFFFF0192C3C701 + 88888801D0D0D00300000005D0D0D0010505FF010404FF030404C70100000001 + D0D0D001FFFFFF01DBE1E501D7EAF30188D6F7018FDBFB01FF002601FFFFFF01 + FF002601FFFFFF01FF002601FFFFFF01FF002601FFFFFF01FF002601FFFFFF01 + F4F9FB01E7F3F801D7EAF301EEF8FD01DA644B017C7C7C01E3E3E30156565601 + E8E8E8014E4E4E01CFCFCF01E8E8E801E1E1E10150505001E8E8E801BBBBBB01 + 7E7E7E01E4E4E40139393901E8E8E801FFFFFF0160E84801D0D0D00288888801 + 9CD6DB015B7A7D01BFFAFE0144585901C9FCFE01A8CECF0155676701CFFEFE01 + 4B66680199EBF1016BBFC601418B910188888801000000020000FF017C7C7C01 + E8E8E807D6D6D601696969011D1D1D0166666601C7C7C701E8E8E802FFFFFF01 + 72F2FE01FFFFFF01D0D0D001FF002006D0D0D0010505FF010404FF040404FE01 + 02026701D0D0D00100000001C2D4DD01B6D9E90173C7EB017BCDEF01FF002601 + B6D9E901FF002601B6D9E901FF002601B6D9E901FF002601B6D9E901FF002601 + B6D9E901D2E8F101C5E1EE01B6D9E901E2F0F601E0E0E0017C7C7C01E8E8E801 + 959595015A5A5A0190909001E8E8E802E3E3E30176767601E8E8E801E6E6E601 + 7B7B7B0159595901AEAEAE01E8E8E801FFFFFF0100000001FFFFFF01D0D0D001 + 888888019FDADF0162848601BFFAFE014B5F6101C9FCFE01CEFDFE0155676701 + CFFEFE014F6C6E019DF2F8016FC7CE01418A90018888880100000001FFFFFF01 + 888888017C7C7C01E8E8E807BBBBBB0188888801DDDDDD01E8E8E804FFFFFF01 + D0D0D001FFFFFF01D0D0D001FF002006000000010404FF060303D50100000001 + FFFFFF01A8C7D50194C8DF015EB9DF0166BEE301FF0026016DB4D401FF002601 + 6DB4D401FF0026016DB4D401FF0026016DB4D401FF0026016DB4D401AFD6E701 + A3D0E30194C8DF01C6E1EE01D0D0D0017C7C7C01E8E8E80EFFFFFF01D0D0D001 + FFFFFF01D0D0D00188888801B5F8FE014D686A01B1E7EB01495E5F01C9FCFE01 + CEFDFE0155676701CFFEFE0178A3A50179BBBF014D898E0155B4BD0188888801 + 00000001FFFFFF01D0D0D0017C7C7C01E8E8E80EFFFFFF01E0E0E001FFFFFF01 + D0D0D001FF00200600000001D0D0D00100000007D0D0D0018FBACE0173B8D601 + 4AABD30151B0D701FF002601248FBE01FF002601248FBE01FF002601248FBE01 + FF002601248FBE01FF002601248FBE018DC5DD0180BED90173B8D601AAD3E501 + D0D0D0017C7C7C01FFFFFF0FD0D0D001EC25EC01D0D0D00188888801B5F8FE01 + 96C8CC0162808201ADDDE001C9FCFE01CEFDFE0194B2B201CFFEFE01B3F4F701 + 62979A0155999E0172F2FE018888880100000001FFFFFF027C7C7C01E8E8E80E + FFFFFF02D0D0D002FF00200600000001D0D0D008FF00FF0175AEC70152A7CC01 + 359CC7013DA1CC01FF002601D0D0D001FF002601D0D0D001FF002601D0D0D001 + FF002601D0D0D001FF002601D0D0D0016BB3D3015EADCF0152A7CC018DC4DC01 + D0D0D011FFFFFF02D0D0D00188888801B5F8FE01BAF9FE01BFFAFE01C4FBFE01 + C9FCFE01CEFDFE01D3FEFE01CFFEFE01B8FBFE01A1F8FE0189F5FE0172F2FE01 + 8888880100000001FFFFFF027C7C7C01E8E8E80EFFFFFF02D0D0D002FF002006 + 00000001D0D0D008FF00FF015CA1BF013196C201218EBB012893C001D0D0D00A + 49A2C9013C9BC5013196C20170B6D401FFFFFF01D0D0D010FFFFFF01D5D5D501 + D0D0D0018888880E00000001B6AFAF01D0D0D0017C7C7C01E8E8E80EFFFFFF02 + 0000FF01D0D0D001FF00200600000001D0D0D008FFFFFF014394B8011085B801 + 0C7FB001D0D0D00C198ABB011085B80154A8CC01FFFFFF01D0D0D011D5D5D501 + D0D0D00100000010FFFFFF017C7C7C01FFFFFF0FD0D0D001E21BE201D0D0D002 + 00000006D0D0D008D4D4D4012A87B001238EBB012C93BE0175AFC701D0D0D00B + 9CBECD014DA2C8013899C30188888801FFFFFF10D0D0D001FCE0E301FFFFFF10 + 797979016FF1FF01FFFFFF10D0D0D001C1C1C101FFFFFF10D0D0D001DADADA01 + FFFFFF10D9D9D901ADADAD01999999018E8E8E028C8C8C0C8D8D8D0194949401 + FFFFFF12D0D0D012D4D4D413D0D0D0103931320199999901D0D0D0019A9A9A01 + 9E9E9E019A9A9A0B9E9E9E01D0D0D0019F9F9F01804CF0017C7C7C0FFFFFFF01 + D0D0D013D4D4D401D0D0D010D4D4D401D0D0D0059B9B9B019C9A9A019E9D9D01 + A09D9E019C9A9A0199999901D0D0D00679797901848484019A9A9A019D9D9D01 + BABABA01DEDEDE01DFDFDF08CFCFCF019D9D9D019A9A9A01D0D0D0019E9E9E01 + D0D0D0017C7C7C01C0C0C002A9A9A901BABABA01AAAAAA01A6A6A601A9A9A901 + AEAEAE01A5A5A5018E8E8E01A9A9A901BCBCBC01ACACAC01A0A0A001FFFFFF01 + D0D0D013D4D4D401D0D0D00500000006D0D0D005FFD4D902D0D0D00295959501 + 9E9E9E01A29F9F01CBC0C101E1D4D501E1D1D201CCBEC0019F9C9C018B8B8B01 + 8A8A8A01D0D0D004FF0000017C7C7C018A8A8A018686860B8B8B8B01BEBEBE01 + 9A9A9A01D0D0D0019E9E9E01D0D0D0017C7C7C018B8B8B0198989801A9A9A901 + B7B7B70194949402A9A9A901989898018181810170707001A9A9A901B8B8B801 + 8E8E8E018D8D8D01FFFFFF027E7E7E018B8B8B108F8F8F0199989801D0D0D004 + 00000008D0D0D00479797902D0D0D0029C9B9B01B6AFAF01F5E1E201FEECEE01 + FEE8EA01FEE4E701FFE1E401FADADD01B6ABAC018381810100000001D0D0D003 + 9C9C9C017A7A7A0186868601AAAAFF01AEAEFF01B2B2FF01B6B6FF01BBBBFF01 + BFBFFF01C3C3FF01C8C8FF01CCCCFF01D0D0FF01D4D4FF0186868601D7D7D701 + 9A9A9A01D0D0D0019E9E9E017C7C7C02ABABAB01B4B4B401A9A9A901C0C0C001 + ACACAC01A4A4A401A9A9A901C0C0C003A9A9A901C0C0C001B5B5B501A9A9A901 + FFFFFF028B8B8B01D9D9D902C5C5C501C8C8C801D9D9D901CDCDCD01D2D2D201 + D9D9D901D8D8D801CDCDCD02C9C9C901D9D9D902D0D0D001CECECE01F9F9F901 + 78AECA01D0D0D0040000000200009B010000FF010000FE0100009B0100000002 + D0D0D004FF00FF0179797901D0D0D00198989801A3A1A101F5E0E101FDEBEC01 + 9F929301554D4E01564C4D019B878901FFDADF01FBD3D801A09C9C014D4D4D01 + 00000001D0D0D002F1F1F1017A7A7A0186868601AAAAFF01AEAEFF01B2B2FF01 + B6B6FF01BBBBFF0100000001C3C3FF01C8C8FF01CCCCFF01D0D0FF01D4D4FF01 + 86868601D7D7D7019A9A9A01D0D0D0019E9E9E01FFFFFF017C7C7C01A9A9A90E + FFFFFF028B8B8B01D9D9D9017E7E7E01212121012C2C2C01ABABAB0188888801 + 80808001D9D9D901C3C3C30161616101666666013C3C3C01D4D4D401D9D9D901 + 6868680179797901F9F9F90100FFFF01D0D0D003000000010000010100003801 + 0000FF04000048010000010100000001D0D0D003E1E1E10180808001D0D0D001 + 9E9D9D01D3C5C601FCE9EA01FDE9EB01524A4B01FCE0E301FEDEE201322B2C01 + FCD4D901FFD4D901D8BDC0018683840100000001D0D0D002D4D4D4017A7A7A01 + 86868601AAAAFF01AEAEFF01B2B2FF01B6B6FF01BBBBFF01BFBFFF01C3C3FF01 + C8C8FF01CCCCFF01D0D0FF01D4D4FF0186868601D7D7D7019A9A9A01D0D0D001 + 9E9E9E01FFFFFF017C7C7C01C2C2C201C0C0C001A9A9A901D3D3D301BABABA01 + ADADAD01A9A9A901E7E7E701CDCDCD01BDBDBD01A9A9A901E2E2E201B6B6B601 + BDBDBD01FFFFFF01D75835018B8B8B01CECECE012D2D2D01BFBFBF0193939301 + 50505001BFBFBF014A4A4A01C5C5C5018989890176767601666666011F1F1F01 + ABABAB01D9D9D9012B2B2B016D6D6D01F9F9F901C902C901D0D0D0030000EA01 + 0000D3010000DE010000FF0400005C0100000B0100008301D0D0D003D4D4D402 + D0D0D0019D9C9C01EBDADB01FFECEE01FFE8EA01FFE4E701FFE0E401CCB0B301 + 443A3B01FFD4D902EECACE019896960100000002D0D0D001D4D4D4017A7A7A01 + 8686860DD7D7D7019A9A9A01D0D0D0019E9E9E01BC8C75017C7C7C01A0A0A001 + A6A6A601A9A9A901C7C7C70187878701B3B3B301A9A9A901ADADAD01A6A6A601 + 9D9D9D01A9A9A901FFFFFF01B3B3B302FFFFFF01E0E0E0018B8B8B01CBCBCB01 + 353535018D8D8D01BCBCBC01A5A5A501D3D3D301696969018E8E8E013C3C3C01 + B9B9B901676767013F3F3F0188888801C4C4C4012D2D2D0171717101F9F9F901 + 42424201D0D0D0030000FF060000B6010000050100005E010000CC0100000001 + D0D0D002FFFFFF01D0D0D0029C9B9B01F4E3E501FFE9EB01FFE5E801FFE1E401 + E5C6CA0139313201E9C3C701FFD4D902F4CED2019998980100000002D0D0D001 + DADADA017A7A7A0186868601ADF9F101ADFFF701B2FFF701B6FFF801BAFFF901 + BFFFF901C3FFFA01C7FFFB01CBFFFC01D0FFFC01D4FFFD0190959501D7D7D701 + 9A9A9A01D0D0D0019E9E9E0100FCF8017C7C7C01B9B9B901B0B0B001A9A9A901 + FFFFFF03A9A9A901EFEFEF01CCCCCC01BABABA01A9A9A901FFFFFF040EB50001 + 8B8B8B01D9D9D9019A9A9A012A2A2A012B2B2B01A7A7A701D9D9D901A6A6A601 + 262626016A6A6A01D8D8D801676767015C5C5C0176767601828282015C5C5C01 + 71717101F9F9F901D2D2D201D0D0D0030000FF050000B8010000090100003B01 + 0000F7010000F00100000001D0D0D002D2D2D202D0D0D001A19EA001E0D1D301 + FFE6E901FFE2E501FFDEE201A68E9101A48A8D01FFD4D903E0C2C5018E8B8B01 + 00000002D0D0D001D2D2D2017A7A7A0186868601ADF9F101ADFFF701B2FFF701 + B6FFF801BAFFF90100000001C3FFFA01C7FFFB01CBFFFC01D0FFFC01D4FFFD01 + 90959501D7D7D7019A9A9A01D0D0D0019E9E9E01E0E0E0017C7C7C01A9A9A90E + FFFFFF01D0D0D0018B8B8B01D2D2D201C7C7C701D4D4D401888888012F2F2F01 + D9D9D9022E2E2E01D1D1D101D9D9D901676767016565650241414101A5A5A501 + 71717101F9F9F901D2D2D201D0D0D0030000FF040000D3010000060100003101 + 0000EE010000FF010000F00100000001D0D0D002D2D2D202D0D0D0019B9B9B01 + B6AFAF01FFE3E601FFDFE301FFDBDF01CFAFB301D2AFB301FFD4D903B5A8A901 + 6464640100000002D0D0D001D2D2D2017A7A7A0186868601ADF9F101ADFFF701 + B2FFF701B6FFF801BAFFF901BFFFF901C3FFFA01C7FFFB01CBFFFC01D0FFFC01 + D4FFFD0190959501D7D7D7019A9A9A01D0D0D0019E9E9E010DB600017C7C7C01 + BABABA01C0C0C001A9A9A901E2E2E201CFCFCF01BABABA01A9A9A901E2E2E201 + CFCFCF01BABABA01A9A9A901DDDDDD01CFCFCF01BEBEBE01FFFFFF01CFCFCF01 + 8B8B8B01B2B2B20149494901D1D1D101C6C6C60133333301D9D9D90230303001 + D6D6D601D9D9D90167676701717171016565650134343401BABABA0171717101 + F9F9F901D2D2D201D0D0D0030000FF0400005F0100000C010000E9010000FF02 + 0000CC0100000001D0D0D002D2D2D202D0D0D0019292920199989801D8C5C701 + FFDCE001FFD8DD01C3A2A601C7A5A901FFD4D902D8BDC1019596990135678101 + 05090C0100000001D0D0D001D2D2D2017A7A7A018686860DD7D7D7019A9A9A01 + D0D0D0019E9E9E017C7C7C02A1A1A101C0C0C001A9A9A901AEAEAE018A8A8A01 + 88888801A9A9A901AEAEAE018A8A8A0188888801A9A9A901AEAEAE0180808001 + 96969601FFFFFF028B8B8B01D4D4D401505050012D2D2D013131310169696901 + D9D9D90230303001D6D6D601D9D9D901676767017C7C7C01757575015B5B5B01 + BABABA0171717101F9F9F901D2D2D201D0D0D0030000FF010000FE010000FF02 + 0000360100003D010000FF020000FE010000590100000001D0D0D002D2D2D202 + D0D0D0029696960197959601BAADAE01F1CDD101FFD4D902F1CCD001BAABAD01 + 98989901A5C2D10178AECA013D7C9B010C181E01D0D0D001808080017A7A7A01 + 86868601FFAAB801FFAEBB01FFB2BE01FFB6C101FFBBC401FFBFC701FFC3CA01 + FFC8CD01FFCCD001FFD0D301FFD4D60186868601D7D7D7019A9A9A01D0D0D001 + 9E9E9E01FFFFFF017C7C7C01A4A4A401C0C0C001A9A9A901ECECEC01DBDBDB01 + C9C9C901A9A9A901ECECEC01DBDBDB01C9C9C901A9A9A901E7E7E701DBDBDB01 + CCCCCC01FFFFFF028B8B8B01D9D9D9029F9F9F019D9D9D01D4D4D401D9D9D902 + A4A4A401D9D9D902BBBBBB01C2C2C201C0C0C001C4C4C401CFCFCF01B9B9B901 + F9F9F901D2D2D201D0D0D0040000DF010000FE010000FF010000BC010000C701 + 0000FF010000FE0100009E0100000002D0D0D002D2D2D202D0D0D0033F3F3F01 + 78777701969495019998980296949501706F6F01406F870183B5CE01A8CBDD01 + 78AFCA013D7C9B0112252E01D2D2D2017A7A7A0186868601FFAAB801FFAEBB01 + FFB2BE01FFB6C101FFBBC40100000001FFC3CA01FFC8CD01FFCCD001FFD0D301 + FFD4D60186868601B6B6B6019E9E9E01D0D0D0019E9E9E01FFFFFF017C7C7C01 + A9A9A90EFFFFFF01CE3006018B8B8B01D9D9D910F9F9F901D2D2D201D0D0D005 + 000088010000CC010000A7010000AC010000CC010000590100000002D0D0D003 + D2D2D202D0D0D00400000002181818011414140100000002070E12014A88A801 + 83B5CE01A8CBDD0178AFCA01346A8501D2D2D2017A7A7A0186868601FFAAB801 + FFAEBB01FFB2BE01FFB6C101FFBBC401FFBFC701FFC3CA01FFC8CD01FFCCD001 + FFD0D301FFD4D60186868601969696011818180100000001A0A0A001FFFFFF01 + 7C7C7C01C5C5C501C0C0C001A9A9A901E0E0E001D8D8D801CFCFCF01A9A9A901 + EAEAEA01D8D8D802A9A9A901FDFDFD01D0D0D001D2D2D201FFFFFF0100000001 + 8F8F8F01F8F8F810FEFEFE01D2D2D201D0D0D00600000006D0D0D004D2D2D202 + D0D0D00600000004D0D0D0011B3846014987A60182B5CE01A8CADC01364E5A01 + D2D2D2017A7A7A01888888018686860B898989012B2B2B0100000001D0D0D001 + 68686801FFFFFF017C7C7C01A1A1A10191919101A9A9A901A6A6A601ADADAD01 + AAAAAA01A9A9A901EAEAEA01A9A9A901B3B3B301A9A9A901F3F3F301A6A6A601 + 60606001FFFFFF02D0D0D012D2D2D201D0D0D00700000002D0D0D007D2D2D202 + D0D0D00C28506501417893013C53600100000001DADADA017A7A7A010000000E + D0D0D00214141401FFFFFF017C7C7C01F6F6F601FFFFFF0FD0D0D025D2D2D210 + D0D0D001727272017B7B7B0D7C7C7C015A5A5A012121210120202001D0D0D001 + FFFFFF10E0E0E001D0D0D024C8CAC001CBCCC701C8CBC802D1D1D102D0D0D00B + D1D1D10100000001FFFFFF1063636301D0D0D047D1CDCC01BFFAFE01D0D0D047 + D0CDCB01D0D0D010D1D1D10100000001D0D0D011D9D9D904FFFFFF0180808001 + D9D9D904D0D0D02CD1CFCF01D0D0D0070000B602D0D0D007CFCFCF010000FF01 + D0D0D0070000B602D0D0D0076262F101D0D0D036D1D1D101D0D0D0050000C301 + 0000CE010000D6020000CE010000C301D0D0D005D0CAC901E0E0E001D0D0D005 + 0000C3010000CE010000D6020000CE010000C301D0D0D005D9D9D901D0D0D036 + D0CCCA01D0D0D0040000C8010000E9010000FF040000E4010000BB01D0D0D004 + D1CDCC01E0E0E001D0D0D0040000C8010000E9010000FF040000E4010000BB01 + D0D0D00436363601D0D0D036CFC7C501D0D0D0030000C3010000E9010000FF06 + 0000E20100008C01D0D0D003D2D2D201D9D9D901D0D0D0030000C3010000E901 + 0000FF060000E20100008C01D0D0D004DADADA01D9D9D907FFFFFF0180808001 + D9D9D904D0D0D028D2D2D201D0D0D0030000CE010000FF080000B40100000001 + D0D0D002CFCFCF010000FF01D0D0D0030000CE010000FF080000B40100000001 + D0D0D002888888010000000162021101E8A52301221041010000000188090001 + 401D2801141D280100000002241D28010000000200000101D0D0D00400000002 + ECECEC22D1D1D101D0D0D0020000B6010000D6010000FF080000C50100000D01 + D0D0D002CFC8C60100000001D0D0D0020000B6010000D6010000FF080000C501 + 00000D01D0D0D00280C4C90100000036D0CBC901D0D0D0020000B6010000D601 + 0000FF080000C50100000A01D0D0D002CFC9C70190BCBF01D0D0D0020000B601 + 0000D6010000FF080000C50100000A01D0D0D002A3A3A6010000002AFFFFFF0C + CDC7C601D0D0D0030000CE010000FF080000B30100000001D0D0D002D1CFCE01 + 88888801D0D0D0030000CE010000FF080000B30100000001D0D0D00300000003 + 26262601010101010000001BFFFFFF018C8C8C0EFFFFFF0100000002FFFFFF04 + CFC8C601D0D0D0030000C3010000E4010000FF060000E20100006B0100000001 + D0D0D002D0CFCE01D0D0D0040000C3010000E4010000FF060000E20100006B01 + 00000001D0D0D002E0E0E00100000016FFFFFF018C8C8C0EFFFFFF0100000001 + FFFFFF0E00000001D1D1D101D0D0D0040000BB010000E2010000FF040000E201 + 00009A0100000002D0D0D002D2D2D201E0E0E001D0D0D0040000BB010000E201 + 0000FF040000E20100009A0100000002D0D0D003FFFFFF0D8C8C8C0EFFFFFF11 + 00000001FFFFFF09D1CDCC01D0D0D00500008C010000B4010000C5020000B301 + 00006B0100000002D0D0D003D0CECE01FFFFFF01D0D0D00500008C010000B401 + 0000C5020000B30100006B0100000002D0D0D003FFFFFF018C8C8C01FFFFFF02 + 8C8C8C0EFFFFFF1100000001FFFFFF0F0000000380808001D0D2D201D0D0D006 + 0000000100000D0100000A0100000003D0D0D004D2D2D201FFFFFF01D0D0D006 + 0000000100000D0100000A0100000003D0D0D004FFFFFF018C8C8C01DDDDDD01 + D8D8D803A3A3A3018C8C8C01FFFFFF1100000001FFFFFF0F0000000380808001 + FFFFFF05B6B6B6010707070100000003D2D2D201D0D0D010D0CCCA01D0D0D011 + FF1E4001FFFFFF0E00000001FFFFFF0F0000000380808001FFFFFF06DBDBDB01 + 1E1E1E0100000004FFFFFF01AFAFAF01BFBFBF018C8C8C01C0C0C001AEAEAE01 + 8F8F8F0190909001D1D1D101D0D0D010CFC9C701D0D0D012FFFFFF0400000001 + FFFFFF0F0000000380808001FFFFFF06E6E6E6017D7D7D010E0E0E0100000003 + FFFFFF01A8A8A801BFBFBF018C8C8C01C2C2C201ACACAC018C8C8C0190909001 + D7D7D7018C8C8C01BFBFBF01A8A8A8018C8C8C01DADADA0194949401FFFFFF02 + 8C8C8C01D1C4C001D0CAC801CFC8C601CFC7C401D0C9C701D0CCCB01D1D1D101 + D1CECD01D0CAC801D0C6C401CFC7C501D0C9C703CFC9C601CFC6C601CEC8C801 + CDC0C001FF1E4001FFFFFF107C7C7C01FFFFFF0A0000000380808001FFFFFF05 + D4D4D4018F8F8F016E6E6E010E0E0E0100000003FFFFFF018F8F8F01D4D4D401 + 8C8C8C01D8D8D801989898018C8C8C0190909001D7D7D7018C8C8C01A2A2A201 + C1C1C1018E8E8E01E3E3E3018C8C8C01FFFFFF028C8C8C01BBBBBB01B0B0B001 + C4C4C401DCDCDC0194949401E3E3E3018C8C8C01E3E3E3018C8C8C02501B0000 + 000000062E2E2E01151515010000000305050501000000500909090102020201 + 0000000106060601CFCFCF01D4D4D401747474017A7A7A01A1A1A101E8E8E801 + 575757010606060100000005FFFFFF1000000026FFFFFF0F8080800100000003 + 66666601CDCDCD018080800172727201E7E7E701FFFFFF01F7F7F701F8F8F801 + FDFDFD02B3B3B301727272013030300100000004FFFFFF10000000059B9B9B01 + 1B1B1B010000001FFFFFFF100000000323232301F1F1F101FDFDFD01F5F5F501 + FFFFFF07DBDBDB01939393019F9F9F01ACACAC0100000002FFFFFF1000000005 + C4C4C401DDDDDD01414141010000001EFFFFFF100000000330303001DEDEDE01 + FFFFFF0AFBFBFB01FFFFFF01ADADAD0100000002FFFFFF1000000005C0C0C001 + FFFFFF01EFEFEF01767676010000000BFFFFFF1000000002FFFFFF1000000002 + 0606060172727201E7E7E701FFFFFF0BF6F6F601767676010606060100000001 + FFFFFF1000000005C0C0C001FFFFFF02F8F8F801A7A7A7010303030100000009 + FFFFFF1000000002FFFFFF100000000237373701A9A9A901FFFFFF0DA9A9A901 + 3737370100000002FFFFFF0F00000005C0C0C001FFFFFF03FEFEFE01CACACA01 + 1212120100000008FFFFFF1000000002FFFFFF100000000261616101E2E2E201 + FFFFFF0DE6E6E6016363630100000001FFFFFF1000000005C0C0C001FFFFFF05 + DEDEDE013232320100000007FFFFFF1000000002FFFFFF100000000118181801 + EFEFEF01FFFFFF0EFDFDFD01B9B9B90100000001FFFFFF1000000005C0C0C001 + FFFFFF06EBEBEB016565650100000006FFFFFF1000000002FFFFFF1000000002 + 99999901FBFBFB01FFFFFF0DF6F6F6017A7A7A0100000001FFFFFF1000000005 + C0C0C001FFFFFF06F1F1F101A6A6A6010E0E0E0100000005FFFFFF1000000002 + FFFFFF100000000272727201ECECEC01FFFFFF0DECECEC017272720100000001 + FFFFFF1000000005C0C0C001FFFFFF05EBEBEB01A2A2A2016E6E6E010E0E0E01 + 00000005FFFFFF1000000002FFFFFF10000000025B5B5B01D2D2D201FFFFFF0D + D7D7D7015B5B5B0100000001FFFFFF1000000005C0C0C001FFFFFF03FEFEFE01 + E3E3E30194949401575757010404040100000006FFFFFF1000000002FFFFFF10 + 0000000237373701C3C3C301FFFFFF0DEBEBEB013737370100000001FFFFFF10 + 00000005C0C0C001FFFFFF02F9F9F901D4D4D4018B8B8B013D3D3D0100000008 + FFFFFF1000000002FFFFFF100000000206060601E7E7E701F8F8F801FFFFFF0B + DCDCDC01787878010606060100000001FFFFFF1000000005C0C0C001FFFFFF01 + F3F3F301BFBFBF01828282012525250100000009FFFFFF1000000002FFFFFF10 + 000000033F3F3F0191919101EDEDED01FFFFFF09ECECEC019191910130303001 + 00000002FFFFFF1000000005C4C4C401E4E4E401A9A9A9017474740113131301 + 0000001CFFFFFF10000000043E3E3E0199999901EEEEEE01FFFFFF07DBDBDB01 + 919191013E3E3E0100000003FFFFFF10000000059B9B9B015A5A5A0160606001 + 070707010000001DFFFFFF10000000053030300172727201A9A9A901D2D2D201 + EDEDED01F5F5F501ECECEC01F1F1F101EEEEEE01727272013030300100000005 + FFFFFF0F0000000615151501010101010000001EFFFFFF0180808001FFFFFF0E + 0000000606060601373737015B5B5B01727272017A7A7A01727272016F6F6F01 + 5D5D5D0106060601000000F1FFFFFF0100000010FFFFFF08FBFBFB0146464601 + 010101010000001D08080801656565019595950194949401696969010A0A0A01 + 0000001BFFFFFF020000000109090901151515011B1B1B021616160133333301 + 202020013939390100000006FFFFFF09FDFDFD0167676701010101010000000C + 070707020000000D1D1D1D01E0E0E001FFFFFF01D7D7D701DADADA01FFFFFF01 + E1E1E1012424240100000018FFFFFF0534343401626262015B5B5B0152525201 + 4A4A4A01383838016B6B6B013A3A3A0100000006FFFFFF0AFDFDFD016F6F6F01 + 010101010000000966666601C9C9C901DCDCDC02C9C9C901666666010000000B + B9B9B901FFFFFF01C7C7C701E5E5E502C7C7C701FEFEFE01C3C3C30100000006 + FFFFFF1000000002FFFFFF0100000001FFFFFF02000000040E0E0E0106060601 + 0E0E0E01000000010E0E0E0100000006FFFFFF0BFDFDFD017777770101010101 + 00000007A6A6A601F2F2F201FFFFFF04F7F7F701B1B1B1010000000911111101 + FDFDFD01FFFFFF06FEFEFE010D0D0D0100000005FFFFFF1000000002FFFFFF01 + 00000001FFFFFF0108080801000000045E5E5E014E4E4E015D5D5D0150505001 + 4C4C4C0100000006FFFFFF0CFDFDFD0180808001020202010000000566666601 + F2F2F201FFFFFF06F9F9F9018E8E8E01000000083E3E3E01FDFDFD01FFFFFF07 + 6F6F6F0100000005FFFFFF1000000002FFFFFF01000000072D2D2D0131313101 + 2F2F2F013D3D3D011C1C1C0100000006FFFFFF0E3636360100000005C9C9C901 + FFFFFF08E6E6E6012020200100000007AFAFAF01FFFFFF08DBDBDB0120202001 + 00000004FFFFFF1000000002FFFFFF0100000004141414012B2B2B0128282801 + 57575701232323011212120100000002FFFFFF0300000003FFFFFF0E88888801 + 0000000407070701DCDCDC01FFFFFF08EFEFEF016464640100000007E5E5E501 + FFFFFF08F3F3F3016060600100000004FFFFFF1000000002FFFFFF0100000004 + 2A2A2A014F4F4F01505050015E5E5E014A4A4A012929290100000004FFFFFF01 + 00000003FFFFFF0E8A8A8A010000000407070701DCDCDC01FFFFFF08EFEFEF01 + 8282820100000007E5E5E501FFFFFF08F3F3F3017E7E7E0100000004FFFFFF10 + 00000002FFFFFF010000000EFFFFFF0100000003FFFFFF0E8A8A8A0100000005 + C9C9C901FFFFFF08E7E7E7017E7E7E0100000007AFAFAF01FFFFFF08DBDBDB01 + 7E7E7E0100000004FFFFFF1000000002FFFFFF010000000EFFFFFF0100000003 + FFFFFF0E8A8A8A010000000566666601F7F7F701FFFFFF06F9F9F901BABABA01 + 60606001000000073A3A3A01FEFEFE01FFFFFF06FEFEFE01A6A6A60160606001 + 00000004FFFFFF1000000002FFFFFF01000000023B3B3B012D2D2D0114141401 + 1A1A1A011C1C1C01030303011A1A1A011313130100000004FFFFFF0100000003 + FFFFFF0E8A8A8A0100000006B1B1B101F9F9F901FFFFFF04F9F9F901D7D7D701 + 8B8B8B01202020010000000889898901FEFEFE01FFFFFF04FEFEFE01C2C2C201 + 8B8B8B012020200100000004FFFFFF1000000002FFFFFF02000000014E4E4E01 + 3D3D3D015B5B5B01646464016D6D6D0124242401656565013030300100000001 + 08080801FFFFFF0100000001FFFFFF0100000003FFFFFF0E8A8A8A0100000007 + 8E8E8E01E6E6E601EFEFEF02E7E7E701BABABA018B8B8B01424242010000000A + 6D6D6D01DBDBDB01F7F7F701F6F6F601DBDBDB01A6A6A6018B8B8B0142424201 + 00000005FFFFFF100000000C1212120100000001FFFFFF0200000001FFFFFF01 + 00000003FFFFFF0E8A8A8A01000000082020200164646401828282017E7E7E01 + 60606001202020010000000C20202001F6F6F601EFEFEF017E7E7E0160606001 + 202020010000001B6969690153535301525252015B5B5B015D5D5D017C7C7C01 + 4545450139393901FFFFFF0500000003FFFFFF0E8A8A8A010000001B78787801 + 707070010000001E262626011F1F1F011D1D1D0121212101222222012C2C2C01 + 1A1A1A010D0D0D0100000001FFFFFF020000000502020201888888018A8A8A0C + 8888880100000045FFFFFF01000000B9767676017C7C7C010707070100000032 + FFFFFF1000000006010101010000000E20202001B0B0B001DBDBDB0149494901 + 00000020FFFFFF08FBFBFB01464646010101010100000006FFFFFF1000000004 + 56565601D2D2D201F9F9F901D2D2D201565656010000000E49494901DBDBDB01 + AFAFAF01202020010000001EFFFFFF09FDFDFD01676767010101010100000005 + FFFFFF10000000035A5A5A01FFFFFF05787878010000000E070707017C7C7C01 + ECECEC017C7C7C010707070100000009FFFFFF1000000003FFFFFF0AFDFDFD01 + 6F6F6F010101010100000004FFFFFF1000000003D3D3D301FFFFFF05EBEBEB01 + 313131010000000F20202001B0B0B001DBDBDB014949490100000008FFFFFF10 + 00000003FFFFFF0BFDFDFD01777777010101010100000003FFFFFF1000000003 + F0F0F001FFFFFF05F8F8F80174747401000000022222220100000006FFFFFF01 + 555555010000000649494901DBDBDB01B0B0B001202020010000000255555501 + FFFFFF0100000002FFFFFF1000000003FFFFFF0CFDFDFD018080800102020201 + 00000002FFFFFF1000000003B2B2B201FFFFFF05DCDCDC018484840100000001 + 16161601E6E6E6012727270100000005FFFFFF01EAEAEA011515150100000006 + 070707017C7C7C01767676010000000115151501EAEAEA01FFFFFF0100000002 + FFFFFF1000000003FFFFFF0E3636360100000002FFFFFF100000000321212101 + F0F0F001FFFFFF03F4F4F4019B9B9B01626262010000000193939301FFFFFF01 + C8C8C8010C0C0C0100000004FFFFFF02AAAAAA01FFFFFF0100000001FFFFFF01 + 00000001FFFFFF0100000001FFFFFF0100000001FFFFFF0100000001AAAAAA01 + FFFFFF0200000002FFFFFF1000000003FFFFFF0E8888880100000002FFFFFF10 + 0000000421212101B8B8B801D1D1D101BFBFBF01939393017E7E7E0112121201 + 23232301FAFAFA01FFFFFF01FDFDFD016969690100000004FFFFFF1000000002 + FFFFFF1000000003FFFFFF0E8A8A8A0100000002FFFFFF100000000509090901 + 3F3F3F01555555013F3F3F010909090100000001A7A7A701FFFFFF03D6D6D601 + 1313130100000003FFFFFF1000000002FFFFFF1000000003FFFFFF0E8A8A8A01 + 00000002FFFFFF1000000003FFFFFF060000000132323201FEFEFE01FFFFFF04 + 7C7C7C0100000003FFFFFF1000000002FFFFFF1000000003FFFFFF0E8A8A8A01 + 00000002FFFFFF1000000003FFFFFF068C8C8C01BBBBBB01FFFFFF05E0E0E001 + 1B1B1B0100000002FFFFFF1000000002FFFFFF1000000003FFFFFF0E8A8A8A01 + 00000002FFFFFF1000000003FFFFFF068C8C8C0100000001676767018C8C8C05 + 6767670100000002FFFFFF1000000002FFFFFF1000000003FFFFFF0E8A8A8A01 + 00000002FFFFFF1000000003FFFFFF068C8C8C010000000AFFFFFF02AAAAAA01 + FFFFFF0100000001FFFFFF0100000001FFFFFF0100000001FFFFFF0100000001 + FFFFFF0100000001AAAAAA01FFFFFF0200000015FFFFFF0E8A8A8A0100000002 + FFFFFF1000000003FFFFFF068C8C8C010000000AFFFFFF01EAEAEA0115151501 + 0000000A15151501EAEAEA01FFFFFF0100000015FFFFFF0E8A8A8A0100000002 + FFFFFF1000000003FFFFFF068C8C8C010000000AFFFFFF01555555010000000C + 55555501FFFFFF010000001502020201888888018A8A8A0C8888880100000002 + FFFFFF0180808001FFFFFF0E000000048C8C8C06000000D110101001C0C0C001 + FFFFFF0BECECEC0100000003FFFFFF100000002A3D3D3D0193939301D1D1D102 + 939393013E3E3E01000000082C2C2C01E6E6E601F8F8F801FFFFFF0AFEFEFE01 + FFFFFF0100000003FFFFFF100000001908080801656565019595950194949401 + 696969010A0A0A01000000090C0C0C019E9E9E01F3F3F301FEFEFE01FFFFFF03 + F8F8F801B3B3B3010D0D0D0100000006F8F8F801FFFFFF0E00000003FFFFFF10 + 00000001FCFCFC01EDEDED10FCFCFC01000000051D1D1D01E0E0E001FFFFFF01 + D7D7D701DADADA01FFFFFF01E1E1E1012424240100000008ADADAD01F7F7F701 + FFFFFF06FBFBFB01D0D0D0010F0F0F0100000005FFFFFF0F00000003FFFFFF10 + 00000001EDEDED018C8C8C02929292028C8C8C01909090018E8E8E018C8C8C01 + 8D8D8D0190909002919191018C8C8C028F8F8F0190909001EBEBEB0100000005 + B9B9B901FFFFFF01C7C7C701E5E5E502C7C7C701FEFEFE01C3C3C30100000007 + 4D4D4D01F4F4F401FFFFFF08FAFAFA01999999010101010100000004FFFFFF0F + 00000003FFFFFF1000000001EDEDED018C8C8C01B0B0B001EBEBEB01E2E2E201 + 9F9F9F01ACACAC01B7B7B7018C8C8C0196969601BEBEBE01BABABA01DCDCDC01 + 8E8E8E018C8C8C01BBBBBB01BEBEBE01EBEBEB010000000411111101FDFDFD01 + FFFFFF06FEFEFE010D0D0D0100000006BBBBBB01FFFFFF0ADEDEDE0138383801 + 00000004FFFFFF0F00000003FFFFFF01FAFAFA01FFFFFF02989898019F9F9F01 + A4A4A401FFFFFF01929292019A9A9A019E9E9E01FFFFFF0194949401A1A1A101 + 9E9E9E01FFFFFF0100000001EDEDED018F8F8F01E2E2E20194949401A9A9A901 + C4C4C40198989801CACACA0194949401ADADAD01BBBBBB02E8E8E8019D9D9D01 + 8C8C8C01DDDDDD01C3C3C301EBEBEB01000000043E3E3E01FDFDFD01FFFFFF07 + 6F6F6F0100000006EDEDED01FFFFFF0AF7F7F7016B6B6B010101010100000003 + FFFFFF0F00000003FFFFFF01FAFAFA01FFFFFF029B9B9B01B2B2B201A2A2A201 + FFFFFF01A4A4A401A6A6A601A9A9A901FFFFFF018C8C8C01A2A2A202FFFFFF01 + 00000001EDEDED0190909001DBDBDB01AEAEAE0196969601A0A0A0018E8E8E01 + BFBFBF01ACACAC01D4D4D40198989801BBBBBB01CFCFCF01B0B0B00193939301 + DBDBDB01C0C0C001EBEBEB0100000004AFAFAF01FFFFFF08DBDBDB0120202001 + 00000005F7F7F701FFFFFF0AFBFBFB01848484010101010100000003FFFFFF0F + 00000003FFFFFF01F7F7F701FFFFFF028C8C8C03FFFFFF01909090019A9A9A01 + 9F9F9F01FFFFFF018C8C8C03FFFFFF0100000001EDEDED018C8C8C01A6A6A601 + DDDDDD01E3E3E301A0A0A0018C8C8C01A0A0A001E5E5E501BABABA018C8C8C01 + BBBBBB01BEBEBE01BBBBBB01ADADAD01C0C0C002EBEBEB0100000004E5E5E501 + FFFFFF08F3F3F3016060600100000005CECECE01FFFFFF0AE9E9E90184848401 + 0101010100000003FFFFFF0F00000003FFFFFF1000000001EDEDED018F8F8F01 + 939393018E8E8E01ADADAD01DADADA018C8C8C02E4E4E4018E8E8E018C8C8C01 + BBBBBB01B9B9B901BABABA01CECECE01A2A2A201C0C0C001EBEBEB0100000004 + E5E5E501FFFFFF08F3F3F3017E7E7E01000000057F7F7F01F9F9F901FFFFFF08 + FAFAFA01C5C5C5016B6B6B010101010100000003FFFFFF0F00000003FFFFFF01 + F5F5F501FFFFFF0294949401999999019F9F9F01FFFFFF019494940199999901 + 9F9F9F01FFFFFF0195959501999999019E9E9E01FFFFFF0100000001EDEDED01 + 9A9A9A01CCCCCC018E8E8E0192929201DBDBDB018C8C8C02E2E2E2018D8D8D01 + 8C8C8C01BBBBBB01B3B3B301BCBCBC01D6D6D6019C9C9C01C0C0C001EBEBEB01 + 00000004AFAFAF01FFFFFF08DBDBDB017E7E7E010000000507070701E6E6E601 + FFFFFF08F7F7F701CDCDCD013F3F3F010202020100000003FFFFFF0F00000003 + FFFFFF01F5F5F501FFFFFF02A3A3A301B1B1B102FFFFFF01A3A3A301B1B1B102 + FFFFFF01A3A3A301B5B5B501ACACAC01FFFFFF0100000001EDEDED018E8E8E01 + C9C9C901E2E2E201DDDDDD01BBBBBB018C8C8C02E2E2E2018D8D8D018C8C8C01 + BBBBBB01AFAFAF01BDBDBD01BFBFBF019C9C9C01C0C0C001EBEBEB0100000004 + 3A3A3A01FEFEFE01FFFFFF06FEFEFE01A6A6A60160606001000000062E2E2E01 + F1F1F101FAFAFA01FFFFFF04FAFAFA01F9F9F901FFFFFF02C9C9C90119191901 + 00000003FFFFFF0F00000003FFFFFF01F4F4F401FFFFFF029191910195959501 + 9B9B9B01FFFFFF0191919101959595019B9B9B01FFFFFF019292920195959501 + 9A9A9A01FFFFFF0100000001EDEDED018C8C8C02A0A0A001A2A2A2018E8E8E01 + 8C8C8C029E9E9E018C8C8C02969696019393930194949401929292018F8F8F01 + 97979701EBEBEB010000000589898901FEFEFE01FFFFFF04FEFEFE01C2C2C201 + 8B8B8B01202020010000000718181801C1C1C101F4F4F401FDFDFD02F5F5F501 + CECECE01CFCFCF01FFFFFF03CACACA011010100100000002FFFFFF0DF8F8F801 + BFBFBF0100000003FFFFFF1000000001EDEDED018C8C8C10EBEBEB0100000006 + 6D6D6D01DBDBDB01F7F7F701F6F6F601DBDBDB01A6A6A6018B8B8B0142424201 + 000000090101010138383801767676018D8D8D01848484016B6B6B013E3E3E01 + C5C5C501FFFFFF03B3B3B30100000002FFFFFF0DEFEFEF016868680107070701 + 00000002FFFFFF01EFEFEF01FFFFFF02949494019696960199999901FFFFFF01 + 9191910196969602FFFFFF018C8C8C019999990198989801FFFFFF0100000001 + FCFCFC01EBEBEB10FCFCFC010000000720202001F6F6F601EFEFEF017E7E7E01 + 60606001202020010000000C010101040000000110101001C8C8C801FFFFFF01 + FDFDFD01AFAFAF0100000002E8E8E801FFFFFF0BFCFCFC019F9F9F012A2A2A01 + 00000003FFFFFF01F1F1F101FFFFFF02A6A6A601A4A4A401A5A5A501FFFFFF01 + 91919101A5A5A501A2A2A201FFFFFF018F8F8F01A6A6A601C3C3C301FFFFFF01 + 0000001B7878780170707001000000150B0B0B01AAAAAA01A8A8A80179797901 + 00000002161616014646460C3131310100000004FFFFFF0184848401FFFFFF0E + 000000A3FFFFFF3600000024FFFFFF3600000024FFFFFF360000000807070702 + 000000100707070200000008FFFFFF360000000666666601C9C9C901DCDCDC02 + C9C9C901666666010000000C66666601C9C9C901DCDCDC02C9C9C90166666601 + 00000006FFFFFF3600000005A6A6A601F2F2F201FFFFFF04F7F7F701B1B1B101 + 0000000AA6A6A601F2F2F201FFFFFF04F7F7F701B1B1B10100000005FFFFFF36 + 0000000466666601F2F2F201FFFFFF06F9F9F9018E8E8E010000000866666601 + F2F2F201FFFFFF06F9F9F9018E8E8E0100000004FFFFFF3600000004C9C9C901 + FFFFFF08E6E6E6012020200100000007C9C9C901FFFFFF08E6E6E60120202001 + 00000003FFFFFF360000000307070701DCDCDC01FFFFFF08EFEFEF0164646401 + 0000000607070701DCDCDC01FFFFFF08EFEFEF016464640100000003FFFFFF36 + 0000000307070701DCDCDC01FFFFFF08EFEFEF01828282010000000607070701 + DCDCDC01FFFFFF08EFEFEF018282820100000003FFFFFF3600000004C9C9C901 + FFFFFF08E7E7E7017E7E7E0100000007C9C9C901FFFFFF08E7E7E7017E7E7E01 + 00000003FFFFFF360000000466666601F7F7F701FFFFFF06F9F9F901BABABA01 + 606060010000000766666601F7F7F701FFFFFF06F9F9F901BABABA0160606001 + 00000003FFFFFF3600000005B1B1B101F9F9F901FFFFFF04F9F9F901D7D7D701 + 8B8B8B012020200100000008B1B1B101F9F9F901FFFFFF04F9F9F901D7D7D701 + 8B8B8B012020200100000003FFFFFF36000000068E8E8E01E6E6E601EFEFEF02 + E7E7E701BABABA018B8B8B01424242010000000A8E8E8E01E6E6E601EFEFEF02 + E7E7E701BABABA018B8B8B014242420100000004FFFFFF360000000720202001 + 64646401828282017E7E7E0160606001202020010000000C2020200164646401 + 828282017E7E7E01606060012020200100000005FFFFFF3600000024FFFFFF36 + 00000024FFFFFF3600000024FFFFFF36 + } + end + object dummyimagelist: timagelist + width = 24 + left = 120 + top = 64 + end + object viewmenu: tframecomp + left = 208 + top = 96 + end + object runprocmon: tprocessmonitor + onchilddied = runprocdied + left = 192 + top = 32 + end + object statoptions: trttistat + ongetobjects = getstatobjs + top = 96 + end + object projectfiledia: tfiledialog + statfile = projectstatfile + controller.filterlist.data = ( + ( + 'Project files' + '*.prj' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'prj' + controller.captionopen = 'Open Project' + controller.captionsave = 'Save Project' + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + left = 256 + top = 1 + end + object targetpipe: tpipereadercomp + oninputavailable = targetpipeinput + left = 312 + top = 32 + end + object c: tstringcontainer + strings.data = ( + 'Unresolved references in' + 'to' + 'Do you wish to search the formfile?' + 'WARNING' + 'Formfile for' + 'Formfiles' + 'Recursive form hierarchy for "' + 'ERROR' + 'Classtype' + 'not found.' + 'Project' + 'is modified. Save?' + 'Confirmation' + 'Unable to open file "' + '*** Running ***' + 'Downloading' + 'Downloaded' + 'Start gdb server command "' + '" running.' + 'Start gdb Server' + 'gdb server start error' + 'gdb server start canceled.' + 'Can not run start gdb command.' + 'Uploadcommand "' + 'Download ***ERROR***' + 'Download finished.' + 'Download canceled.' + 'File "' + '" not found.' + '" exists.' + 'New' + 'Select ancestor' + 'New form' + 'Pascal Files' + 'new' + 'Can not load Project "' + 'Select project template' + 'Project files' + 'All files' + 'Select program file' + 'Pascal program files' + 'C program files' + 'New Project' + 'Can not start process' + 'Process' + 'running' + 'Process terminated. Exitcode: ' + 'Process terminated normally.' + 'Make ***ERROR***' + 'Make OK.' + 'Source has changed, do you wish to remake project?' + 'Load Window Layout' + 'Docking Area' + ) + left = 256 + top = 64 + end + object openform: tfiledialog + statfile = projectstatfile + controller.filterlist.data = ( + ( + 'Form Files' + '*.mfm' + ) + ) + controller.defaultext = 'mfm' + controller.options = [fdo_checkexist] + controller.captionopen = 'Open Form File' + left = 120 + top = 1 + end + object formbg: tbitmapcomp + bitmap.origformat = 'png' + bitmap.alignment = [al_tiled] + bitmap.image = { + 000000000000000010000000100000007C000000000000000000000000000000 + 0000000000000000000000000000000000000000B8B8B808C7C7C708B8B8B808 + C7C7C708B8B8B808C7C7C708B8B8B808C7C7C708B8B8B808C7C7C708B8B8B808 + C7C7C708B8B8B808C7C7C708B8B8B808C7C7C710B8B8B808C7C7C708B8B8B808 + C7C7C708B8B8B808C7C7C708B8B8B808C7C7C708B8B8B808C7C7C708B8B8B808 + C7C7C708B8B8B808C7C7C708B8B8B808 + } + left = 312 + top = 64 + end +end diff --git a/mseide-msegui/apps/ide/main.pas b/mseide-msegui/apps/ide/main.pas new file mode 100644 index 0000000..ddcc8f9 --- /dev/null +++ b/mseide-msegui/apps/ide/main.pas @@ -0,0 +1,3125 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit main; +{$ifdef linux}{$define unix}{$endif} +{$ifdef FPC} + {$mode objfpc}{$h+}{$goto on} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +{$ifdef mse_no_ifi} + {$define mse_no_db} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseforms,msesimplewidgets,mseguiglob,msegui,msegdbutils,mseactions, + msedispwidgets,msedataedits,msestat,msestatfile,msemenus,msebitmap,msetoolbar, + msegrids,msefiledialog,msetypes,sourcepage,msetabs,msedesignintf,msedesigner, + classes,mclasses,mseclasses,msegraphutils,typinfo,msedock,sysutils,msesysenv, + msemacros,msestrings,msepostscriptprinter,msegraphics,mseglob,msestream, + mseprocmonitorcomp,msesystypes,mserttistat,msedatanodes,mseedit,mseifiglob, + mselistbrowser,projecttreeform,msepipestream,msestringcontainer,msesys, + msewidgets; +const + versiontext = '4.6.3'; + idecaption = 'MSEide'; + statname = 'mseide'; + +type + stringconsts = ( + unresreferences, //0 Unresolved references in + str_to, //1 to + wishsearch, //2 Do you wish to search the formfile? + warning, //3 WARNING + formfile, //4 Formfile for + formfiles, //5 Formfiles + recursive, //6 Recursive form hierarchy for " + error, //7 ERROR + str_classtype, //8 Classtype + notfound, //9 not found. + project, //10 Project + ismodified, //11 is modified. Save? + confirmation, //12 Confirmation + unableopen, //13 Unable to open file " + running, //14 *** Running *** + str_downloading, //15 Downloading + str_downloaded, //16 Downloaded + startgdbservercommand, //17 Start gdb server command " + running2, //18 " running. + startgdbserver, //19 Start gdb Server + gdbserverstarterror,//20 gdb server start error + gdbservercanceled, //21 gdb server start canceled. + cannotrunstartgdb, //22 Can not run start gdb command. + str_uploadcommand, //23 Uploadcommand " + downloaderror, //24 Download ***ERROR*** + downloadfinished, //25 Download finished. + downloadcanceled, //26 Download canceled. + str_file, //27 File " + notfound2, //28 " not found. + exists, //29 " exists. + str_new, //30 New + selectancestor, //31 Select ancestor + newform, //32 New form + pascalfiles, //33 Pascal Files + new2, //34 new + cannotloadproj, //35 Can not load Project " + selecttemplate, //36 Select project template + projectfiles, //37 Project files + str_allfiles, //38 All files + selectprogramfile, //39 Select program file + pascalprogfiles, //40 Pascal program files + cfiles, //41 C program files + str_newproject, //42 New Project + cannotstartprocess, //43 Can not start process + process, //44 Process + running3, //45 running. + processterminated, //46 Process terminated + proctermnormally, //47 Process terminated normally. + makeerror, //48 Make ***ERROR*** + makeok, //49 Make OK. + str_sourcechanged, //50 Source has changed, do you wish to remake project? + str_loadwindowlayout, //51 Load Window Layout + dockingarea //52 Docking Area + ); + + filekindty = (fk_none,fk_source,fk_unit); + messagetextkindty = (mtk_info,mtk_running,mtk_finished,mtk_error,mtk_signal); + + startcommandty = (sc_none,sc_step,sc_continue); +// formkindty = (fok_main,fok_simple,fok_dock,fok_data,fok_subform, +// fok_report,fok_script,fok_inherited); + + tmainfo = class(tdockform,idesignnotification) + gdb: tgdbmi; + filedisp: tstringdisp; + linedisp: tintegerdisp; + projectstatfile: tstatfile; + reasondisp: tintegerdisp; + expr: tstringedit; + exprdisp: tstringdisp; + symboltype: tstringedit; + symboltypedisp: tstringdisp; + mainstatfile: tstatfile; + mainmenu1: tmainmenu; + statdisp: tstringdisp; + errordisp: tstringdisp; + basedock: tdockpanel; + + openfile: tfiledialog; + + dummyimagelist: timagelist; + vievmenuicons: timagelist; + + viewmenu: tframecomp; + runprocmon: tprocessmonitor; + statoptions: trttistat; + projectfiledia: tfiledialog; + targetpipe: tpipereadercomp; + c: tstringcontainer; + openform: tfiledialog; + formbg: tbitmapcomp; + procedure newfileonexecute(const sender: tobject); + procedure newformonexecute(const sender: TObject); + + procedure mainfooncreate(const sender: tobject); + procedure mainfoondestroy(const sender: tobject); + procedure mainstatfileonupdatestat(const sender: tobject; const filer: tstatfiler); + procedure mainfoonterminate(var terminate: Boolean); + procedure mainonloaded(const sender: TObject); + + procedure mainmenuonupdate(const sender: tcustommenu); + procedure onscale(const sender: TObject); + procedure parametersonexecute(const sender: TObject); + procedure buildactonexecute(const sender: TObject); + procedure saveprojectasonexecute(const sender: tobject); + procedure newprojectonexecute(const sender: TObject); + procedure closeprojectactonexecute(const sender: TObject); + procedure exitonexecute(const sender: tobject); + procedure newpanelonexecute(const sender: TObject); + + procedure viewassembleronexecute(const sender: TObject); + procedure viewcpuonexecute(const sender: TObject); + procedure viewmessagesonexecute(const sender: TObject); + procedure viewsourceonexecute(const sender: tobject); + procedure viewbreakpointsonexecute(const sender: tobject); + procedure viewwatchesonexecute(const sender: tobject); + procedure viewstackonexecute(const sender: tobject); + procedure viewobjectinspectoronexecute(const sender: TObject); + procedure toggleobjectinspectoronexecute(const sender: tobject); + procedure viewcomponentpaletteonexecute(const sender: TObject); + procedure viewcomponentstoreonexecute(const sender: TObject); + procedure viewdebuggertoolbaronexecute(const sender: TObject); + procedure viewwatchpointsonexecute(const sender: TObject); + procedure viewthreadsonexecute(const sender: TObject); + procedure viewconsoleonexecute(const sender: TObject); + procedure viewfindresults(const sender: TObject); + procedure aboutonexecute(const sender: TObject); + procedure configureexecute(const sender: TObject); + + //debugger + procedure restartgdbonexecute(const sender: tobject); + procedure runexec(const sender: tobject); + procedure gdbonevent(const sender: tgdbmi; var eventkind: gdbeventkindty; + const values: resultinfoarty; const stopinfo: stopinfoty); + procedure expronsetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); + procedure symboltypeonsetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); + procedure openprojectcopyexecute(const sender: TObject); + procedure saveprojectcopyexecute(const sender: TObject); + procedure newprojectfromprogramexe(const sender: TObject); + procedure newemptyprojectexe(const sender: TObject); + procedure viewmemoryonexecute(const sender: TObject); + procedure runprocdied(const sender: TObject; const prochandle: prochandlety; + const execresult: Integer; const data: Pointer); + procedure statbefread(const sender: TObject); + procedure viewsymbolsonexecute(const sender: TObject); + procedure loadwindowlayoutexe(const sender: TObject); + procedure getstatobjs(const sender: TObject; var aobjects: objectinfoarty); + procedure targetpipeinput(const sender: tpipereader); + procedure mainstatbeforewriteexe(const sender: TObject); + procedure statafterread(const sender: TObject); + procedure basedockpaintexe(const sender: twidget; const acanvas: tcanvas); + private + fstartcommand: startcommandty; + fnoremakecheck: boolean; + fcurrent: boolean; + flastform: tcustommseform; + flastdesignform: tcustommseform; + fexecstamp: integer; + fprojectname: filenamety; + fcheckmodulelevel: integer; + fgdbserverprocid: integer; + fgdbserverexitcode: integer; + fgdbservertimeout: longword; + ftargetfilemodified: boolean; + frunningprocess: prochandlety; + flayoutloading: boolean; + fstopinfo: stopinfoty; + fgdbdownloaded: boolean; + procedure dorun; + function runtarget: boolean; //true if run possible + procedure newproject(const fromprogram,empty: boolean); + procedure doshowform(const sender: tobject); + procedure setprojectname(aname: filenamety); + //not const because of not refcounted widestrings + procedure dofindmodulebyname(const amodule: pmoduleinfoty; const aname: string; + var action: modalresultty); + procedure dofindmodulebytype(const atypename: string); + + //idesignnotification + procedure ItemDeleted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); + procedure ItemInserted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); + procedure ItemsModified(const ADesigner: IDesigner; const AItem: tobject); + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure SelectionChanged(const ADesigner: IDesigner; + const ASelection: IDesignerSelections); + procedure moduleactivated(const adesigner: idesigner; const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; const amodule: tmsecomponent); + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + + function checksave: modalresultty; + procedure unloadexec; + procedure cleardebugdisp; + procedure resetdebugdisp; //called before running debuggee + procedure createprogramfile(const aname: filenamety); + function copynewfile(const aname,newname: filenamety; + const autoincrement: boolean; + const canoverwrite: boolean; + const macronames: array of msestring; + const macrovalues: array of msestring): boolean; + //true if ok + procedure createform(const aname: filenamety; const namebase: string; + const formsuffix: string; + const ancestor: string); + procedure removemodulemenuitem(const amodule: pmoduleinfoty); + procedure uploadexe(const sender: tguiapplication; var again: boolean); + procedure uploadcancel(const sender: tobject); + procedure gdbserverexe(const sender: tguiapplication; var again: boolean); + function terminategdbserver(const force: boolean): boolean; + procedure gdbservercancel(const sender: tobject); + procedure updatetargetenvironment; + function needsdownload: boolean; + function candebug: boolean; //run command empty or process attached + procedure startconsole(); + public + factivedesignmodule: pmoduleinfoty; + fprojectloaded: boolean; + errorformfilename: filenamety; + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure designformactivated(const sender: tcustommseform); + procedure startgdb(const killserver: boolean); + function checkgdberror(aresult: gdbresultty): boolean; + function startgdbconnection(const attach: boolean): boolean; + function loadexec(isattach: boolean; + const forcedownload: boolean): boolean; //true if ok + procedure setstattext(const atext: msestring; const akind: messagetextkindty = mtk_info); + procedure refreshstopinfo(const astopinfo: stopinfoty); + procedure updatemodifiedforms; + function checkremake(startcommand: startcommandty): boolean; + //true if running possible + procedure resetstartcommand; + procedure killtarget; + procedure domake(atag: integer); + procedure targetfilemodified; + function checksavecancel(const aresult: modalresultty): modalresultty; + function closeall(const nosave: boolean): boolean; //false in cancel + function closemodule(const amodule: pmoduleinfoty; + const achecksave: boolean; + nocheckclose: boolean = false): boolean; + function openproject(const aname: filenamety; + const ascopy: boolean = false): boolean; + procedure saveproject(aname: filenamety; const ascopy: boolean = false); + procedure savewindowlayout(const astream: ttextstream); + procedure savewindowlayout(const awriter: tstatwriter); + procedure loadwindowlayout(const astream: ttextstream); + procedure loadwindowlayout(const areader: tstatreader); + + procedure sourcechanged(const sender: tsourcepage); + function opensource(const filekind: filekindty; const addtoproject: boolean; + const aactivate: boolean = true; + const currentnode: tprojectnode = nil): boolean; + //true if filedialog not canceled + function openformfile(const filename: filenamety; + const ashow,aactivate,showsource,createmenu, + skipexisting: boolean): pmoduleinfoty; + procedure createmodulemenuitem(const amodule: pmoduleinfoty); + function formmenuitemstart: integer; + procedure loadformbysource(const sourcefilename: filenamety); + procedure loadsourcebyform(const formfilename: filenamety; + const aactivate: boolean = false); + procedure checkbluedots; + procedure updatesigsettings; + procedure runtool(const sender: tobject); + + procedure downloaded; + procedure programfinished; + procedure showfirsterror; + procedure stackframechanged(const frameno: integer); + procedure refreshframe; + procedure toggleformunit; + property projectname: filenamety read fprojectname; + property lastform: tcustommseform read flastform; + property execstamp: integer read fexecstamp; + property stopinfo: stopinfoty read fstopinfo; + end; + +var + mainfo: tmainfo; + +procedure handleerror(const e: exception; const text: string); +implementation +uses + regwidgets,regeditwidgets,regdialogs,regkernel,regprinter,msearrayutils, + toolhandlermodule, +{$ifndef mse_no_math} + regmath,regmm, +{$endif} +{$ifndef mse_no_db} + regdb,regreport, +{$endif} +{$ifdef mse_with_ifi} + regifi,{$ifndef mse_no_ifirem}regifirem,{$endif} +{$endif} +{$ifdef mse_with_pascalscript} + regpascalscript, +{$endif} +{$ifdef mse_with_zeoslib} + regzeoslib, +{$endif} + regdesignutils,regsysutils,regcrypto,regserialcomm,regexperimental, +{$ifndef mse_no_deprecated} + regdeprecated, +{$endif} + {$ifdef morecomponents} + {$include regcomponents.inc} + {$endif} + + mseparser,msesysintf,memoryform,msedrawtext,mseformatstr, + main_mfm,sourceform,watchform,breakpointsform,stackform, + guitemplates,projectoptionsform,make,msepropertyeditors, + skeletons,msedatamodules,mseact, + mseformdatatools,mseshapes,msefileutils,mseeditglob, + findinfileform,formdesigner,sourceupdate,actionsmodule,programparametersform, + objectinspector,msesysutils,cpuform,disassform, + panelform,watchpointsform,threadsform,targetconsole, + debuggerform,componentpaletteform,componentstore, + messageform,msesettings,mseintegerenter,symbolform + {$ifdef unix},mselibc {$endif}, //SIGRT* + mseprocutils + {$ifdef mse_dumpunitgroups},dumpunitgroups{$endif}; + +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure handleerror(const e: exception; const text: string); +begin + if text <> '' then begin + writestderr(text+' '+e.message,true); + end + else begin + writestderr(e.message,true); + end; +end; + +{ tmainfo } + +constructor tmainfo.create(aowner: tcomponent); +begin + frunningprocess:= invalidprochandle; + fgdbserverprocid:= invalidprochandle; + inherited create(aowner); +end; + +destructor tmainfo.destroy; +begin + terminategdbserver(true); + inherited; +end; + +//common + +procedure tmainfo.mainfooncreate(const sender: tobject); +begin + designer.ongetmodulenamefile:= {$ifdef FPC}@{$endif}dofindmodulebyname; + designer.ongetmoduletypefile:= {$ifdef FPC}@{$endif}dofindmodulebytype; + + designer.objformat:= of_fp; + componentpalettefo.updatecomponentpalette(true); + designnotifications.Registernotification(idesignnotification(self)); + watchfo.gdb:= gdb; + breakpointsfo.gdb:= gdb; + watchpointsfo.gdb:= gdb; + stackfo.gdb:= gdb; + threadsfo.gdb:= gdb; + disassfo.gdb:= gdb; + initprojectoptions; + sourceupdate.init(designer); +{$ifndef mse_with_pascalscript} + mainmenu1.menu.deleteitembynames(['file','new','form','pascform']); +{$endif} +end; + +procedure tmainfo.mainfoondestroy(const sender: tobject); +begin + designnotifications.unRegisternotification(idesignnotification(self)); + abortmake; + abortdownload; + sourceupdate.deinit(designer); +end; + +procedure tmainfo.dofindmodulebyname(const amodule: pmoduleinfoty; + const aname: string; var action: modalresultty); +var + wstr2: msestring; + + function dofind(const modulenames: array of msestring; + const modulefilenames: array of filenamety): boolean; + var + int1: integer; + wstr1: msestring; + po1: pmoduleinfoty; + begin + result:= false; + for int1:= 0 to high(modulenames) do begin + if modulenames[int1] = wstr2 then begin + if int1 <= high(modulefilenames) then begin + wstr1:= modulefilenames[int1]; + if relocatepath(projectoptions.projectdir,'',wstr1,[pro_preferenew]) or + findfile(modulefilenames[int1], + projectoptions.d.texp.sourcedirs,wstr1) or + findfile(filename(modulefilenames[int1]), + projectoptions.d.texp.sourcedirs,wstr1) then begin + try + po1:= openformfile(wstr1,false,false,false,false,false); + result:= (po1 <> nil) and + (msestring(struppercase(po1^.instancevarname)) = wstr2); + except + application.handleexception; + result:= false; + end; + end; + end; + break; + end; + end; + end; + +var + bo1: boolean; + int1: integer; + mstr1: filenamety; + +begin + wstr2:= msestring(struppercase(aname)); + int1:= findchar(wstr2,'.'); + if int1 > 0 then begin + setlength(wstr2,int1-1); //main name only + end; + with projectoptions do begin + bo1:= dofind(s.modulenames,s.modulefiles); + end; + if not bo1 and + projecttree.units.findformbyname(ansistring(wstr2),mstr1) then begin + bo1:= dofind([wstr2],[mstr1]); + end; + if bo1 then begin + action:= mr_ok; + end + else begin + action:= showmessage(c[ord(unresreferences)]+' '+ + msestring(amodule^.moduleclassname)+' '+ + c[ord(str_to)]+' ' + + msestring(aname) + '.'+lineend+ + ' '+c[ord(wishsearch)],c[ord(warning)], + [mr_ok,mr_cancel],mr_ok); + case action of + mr_ok: begin + wstr2:= ''; +// openform.controller.filename:= ''; +// openform.controller.captionopen:= c[ord(formfile)]+' '+ aname; + if openform.controller.execute(wstr2,fdk_open, + c[ord(formfile)]+' '+ msestring(aname)) then begin +// action:= filedialog(wstr2,[fdo_checkexist],c[ord(formfile)]+' '+ aname, +// [c[ord(formfiles)]],['*.mfm'],'',nil,nil,nil,[fa_all],[fa_hidden]); +// //defaultvalues don't work on kylix +// if action = mr_ok then begin +// openformfile(openform.controller.filename,false,false,true,true,false); + openformfile(wstr2,false,false,true,true,false); + end; + end; + end; + end; +end; + +procedure tmainfo.dofindmodulebytype(const atypename: string); +var + wstr2: msestring; + int1: integer; + po1: pmoduleinfoty; + + procedure checkmodule(fname: filenamety); + var + wstr1: filenamety; + begin + with projectoptions do begin + if findfile(fname,d.texp.sourcedirs,wstr1) or + findfile(fname,d.texp.sourcedirs,wstr1) then begin + try + po1:= openformfile(wstr1,false,false,false,false,false); + except + on e: eabort do begin + raise; + end + else begin + po1:= nil; + application.handleexception; + end; + end; + end; + end; + end; + +var +// ar1: msestringarty; + mstr1: filenamety; + +begin +// ar1:= nil; //compilerwarning + if fcheckmodulelevel >= 16 then begin + showmessage(c[ord(recursive)]+msestring(atypename)+'"',c[ord(error)]); + sysutils.abort; + end; + inc(fcheckmodulelevel); + try + with projectoptions do begin + po1:= nil; + wstr2:= msestring(struppercase(atypename)); + for int1:= 0 to high(s.moduletypes) do begin + if s.moduletypes[int1] = wstr2 then begin + if int1 <= high(s.modulefiles) then begin + checkmodule(s.modulefiles[int1]); + end; + break; + end; + end; + end; + if po1 = nil then begin + if projecttree.units.findformbyclass(ansistring(wstr2),mstr1) then begin + checkmodule(mstr1); + end; + { + ar1:= projecttree.units.moduleclassnames; + for int1:= 0 to high(ar1) do begin + if ar1[int1] = wstr2 then begin + checkmodule(projecttree.units.modulefilenames[int1]); + break; + end; + end; + } + end; + if (po1 = nil) or + (stringicomp(po1^.moduleclassname,atypename) <> 0) then begin + if showmessage(c[ord(str_classtype)]+' '+msestring(atypename)+ + ' '+c[ord(notfound)]+lineend+ + ' '+c[ord(wishsearch)],c[ord(warning)], + [mr_yes,mr_cancel]) = mr_yes then begin + wstr2:= ''; +// if filedialog(wstr2,[fdo_checkexist],c[ord(formfile)]+' '+ +// msestring(atypename), +// [c[ord(formfiles)]],['*.mfm']) = mr_ok then begin + if openform.controller.execute(wstr2,fdk_open,c[ord(formfile)]+' '+ + msestring(atypename),[fdo_checkexist]) then begin + openformfile(wstr2,false,false,false,false,false); + end; + end; + end; + finally + dec(fcheckmodulelevel); + end; +end; + +//editor +//formdesigner + + +procedure Tmainfo.doshowform(const sender: tobject); +begin + with tmenuitem(sender) do begin + designer.showformdesigner(pmoduleinfoty(tagpo)); + end; +end; + +procedure tmainfo.toggleobjectinspectoronexecute(const sender: tobject); +begin + if (flastform = objectinspectorfo) then begin + if flastdesignform <> nil then begin + flastdesignform.activate(true); + end; + end + else begin + objectinspectorfo.activate(true); + end; +end; + +procedure tmainfo.viewobjectinspectoronexecute(const sender: TObject); +begin + objectinspectorfo.activate(true); +end; + + //idesignnotification + +procedure Tmainfo.ItemDeleted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + +end; + +procedure Tmainfo.ItemInserted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + componentpalettefo.resetselected; +end; + +procedure tmainfo.moduleactivated(const adesigner: idesigner; const amodule: tmsecomponent); +begin + factivedesignmodule:= designer.actmodulepo; + setlinkedvar(factivedesignmodule^.designform,tmsecomponent(flastdesignform)); +end; + +procedure tmainfo.moduledeactivated(const adesigner: idesigner; const amodule: tmsecomponent); +begin +// factivedesignmodule:= nil; +end; +{ +procedure tmainfo.sourceformactivated; +begin + factivedesignmodule:= nil; +end; +} +function tmainfo.checksave: modalresultty; +var + str1: filenamety; +begin + result:= sourcefo.saveall(false); + if result <> mr_cancel then begin + result:= designer.saveall(result = mr_all,true); + if result <> mr_cancel then begin + result:= componentstorefo.saveall(false); + if result <> mr_cancel then begin + with projectoptions,s,texp do begin + if modified and not savechecked then begin + result:= showmessage(c[ord(project)]+' '+fprojectname+' '+ + c[ord(ismodified)],c[ord(confirmation)], + [mr_yes,mr_no,mr_cancel],mr_yes); + if result = mr_yes then begin + if projectfilename = '' then begin + result:= projectfiledialog(str1,true); + if result <> mr_ok then begin + result:= mr_cancel; + end; + end + else begin + str1:= projectfilename; + end; + if result <> mr_cancel then begin + saveproject(str1); + end; + end + else begin + if result <> mr_no then begin + result:= mr_cancel; + end; + end; + savechecked:= true; + end + else begin + saveproject(projectfilename); + end; + end; + end; + end; + end; + + checksavecancel(result); +end; + +procedure tmainfo.updatemodifiedforms(); +var + int1: integer; +begin + with mainmenu1.menu.itembyname('view') do begin + for int1:= itembyname('formmenuitemstart').index+1 to count - 1 do begin + with items[int1] do begin + with pmoduleinfoty(tagpo)^ do begin + if modified then begin + caption:= '*'+msefileutils.filename(filename); + end + else begin + caption:= msefileutils.filename(filename); + end; + if (designform is tformdesignerfo) and designform.visible then begin + tformdesignerfo(designform).updatecaption; + end; + end; + end; + end; + end; +end; + +procedure Tmainfo.ItemsModified(const ADesigner: IDesigner; const AItem: tobject); +begin + updatemodifiedforms; + sourcechanged(nil); +end; + +procedure tmainfo.componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); +begin + //dummy +end; + +procedure tmainfo.moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin + //dummy +end; + +procedure tmainfo.instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin +end; + +procedure Tmainfo.SelectionChanged(const ADesigner: IDesigner; + const ASelection: IDesignerSelections); +begin + if (aselection.Count > 0) and (factivedesignmodule <> nil) then begin +// objectinspectorfo.bringtofront; + objectinspectorfo.show; + if not objectinspectorfo.active then begin + objectinspectorfo.window.stackunder(factivedesignmodule^.designform.window); + end; + end; +end; + +//debugger + +procedure tmainfo.expronsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +var + expres: string; +begin + gdb.evaluateexpression(ansistring(avalue),expres); + exprdisp.value:= msestring(expres); +end; + +procedure tmainfo.refreshframe; +var + pc: qword; +begin + cpufo.refresh; + if gdb.getpc(pc) = gdb_ok then begin + disassfo.refresh(pc); + end + else begin + disassfo.clear; + end; + watchfo.refresh; +end; + +procedure tmainfo.stackframechanged(const frameno: integer); +begin + if gdb.cancommand then begin + gdb.selectstackframe(frameno); + refreshframe; + end; +end; + +procedure tmainfo.toggleformunit; +var + po1: pmoduleinfoty; + page1: tsourcepage; + str1,str2: filenamety; +begin + if sourcefo.checkancestor(flastform) then begin + page1:= sourcefo.activepage; + if (page1 <> nil) then begin + str2:= fileext(page1.filepath); + if str2 = pasfileext then begin + str1:= replacefileext(page1.filepath,formfileext); + po1:= designer.modules.findmodule(str1); + if po1 <> nil then begin + createmodulemenuitem(po1); + po1^.designform.activate(true); + page1:= nil; + end + else begin + page1:= sourcefo.findsourcepage(str1); + if page1 = nil then begin //mfm not loaded in editor + po1:= designer.loadformfile(str1,false); + if po1 <> nil then begin + createmodulemenuitem(po1); + po1^.designform.activate(true); + end; + end; + end; + end + else begin + if str2 = formfileext then begin + page1:= sourcefo.findsourcepage( + replacefileext(page1.filepath,pasfileext)); + end; + end; + if page1 <> nil then begin + page1.activate; + end; + end; + end + else begin + po1:= designer.actmodulepo; + if po1 <> nil then begin + str1:= replacefileext(po1^.filename,pasfileext); + if sourcefo.openfile(str1,true) = nil then begin + raise exception.create(ansistring(c[ord(unableopen)]+str1+'".')); + end; + end + else begin + if designer.modules.count > 0 then begin + designer.modules[0]^.designform.activate(true); + end; + end; + end; +end; + +procedure tmainfo.setstattext(const atext: msestring; + const akind: messagetextkindty = mtk_info); +begin + with statdisp do begin + value:= removelinebreaks(atext); + case akind of + mtk_finished: color:= cl_ltgreen; + mtk_error: color:= cl_ltyellow; + mtk_signal: color:= cl_ltred; + else color:= cl_parent; + end; + case akind of + mtk_running: font.color:= cl_red; + else font.color:= cl_black; + end; + end; +end; + +procedure tmainfo.cleardebugdisp; +begin + resetdebugdisp; + stackfo.clear; + threadsfo.clear; + disassfo.clear; +end; + +procedure tmainfo.resetdebugdisp; +begin + setstattext('',mtk_info); + if sourcefo.gdbpage <> nil then begin + sourcefo.gdbpage.hidehint; + end; + sourcefo.resetactiverow; + disassfo.resetactiverow; +end; + +procedure tmainfo.programfinished; +begin + sourcefo.resetactiverow; + watchpointsfo.clear; + disassfo.clear; + watchfo.clear; + stackfo.clear; + threadsfo.clear; +end; + +procedure tmainfo.refreshstopinfo(const astopinfo: stopinfoty); +begin + fstopinfo:= astopinfo; + with astopinfo do begin + case reason of + sr_signal_received: begin + setstattext(msestring(messagetext),mtk_signal); + end; + sr_error: begin + setstattext(msestring(messagetext),mtk_error); + end; + sr_exception: begin + end; + else begin + setstattext(msestring(messagetext),mtk_finished); + end; + end; + watchfo.refresh; + breakpointsfo.refresh; + stackfo.refresh; + threadsfo.refresh; + threadsfo.stopinfo:= astopinfo; + cpufo.refresh; + disassfo.refresh(addr); + if (reason = sr_exception) then begin + setstattext(msestring(messagetext)+' '+stackfo.infotext(1),mtk_signal); + if not stackfo.showsource(1) then begin + sourcefo.locate(stopinfo); + end; + end + else begin + sourcefo.locate(stopinfo); + end; + if reason in [sr_exited,sr_exited_normally,sr_detached] then begin + programfinished; + end; + if projectoptions.d.activateonbreak then begin + application.activate(); + { + if application.activewindow <> nil then begin + application.activewindow.activate; + end + else begin + if flastform <> nil then begin + flastform.activate(); + end + else begin + sourcefo.activate(); + end; + end; + } + end; + if projectoptions.d.raiseonbreak then begin + application.packwindowzorder(); + end; + end; +end; + +procedure tmainfo.gdbonevent(const sender: tgdbmi; + var eventkind: gdbeventkindty; const values: resultinfoarty; + const stopinfo: stopinfoty); +begin + cpufo.stoptime.value:= gdb.stoptime; + case eventkind of + gek_stopped: begin + with stopinfo do begin + if (reason = sr_startup) and + (fstartcommand = sc_continue) then begin + gdb.continue; + end + else begin + if breakpointsfo.checkbreakpointcontinue(stopinfo) then begin + gdb.continue; + end + else begin + if reason = sr_detached then begin + cleardebugdisp; + setstattext(msestring(stopinfo.messagetext),mtk_finished); + programfinished; + end + else begin + gdb.debugbegin; + refreshstopinfo(stopinfo); + end; + end; + end; + end; + fstartcommand:= sc_none; + end; + gek_running: begin + resetdebugdisp; + setstattext(c[ord(running)],mtk_running); + end; + gek_error,gek_writeerror,gek_gdbdied: begin + setstattext('GDB: '+msestring(stopinfo.messagetext),mtk_error); + end; + gek_targetoutput: begin + targetconsolefo.addtext(values[0].value); + end; + gek_download: begin + with stopinfo do begin + if sectionsize > 0 then begin + setstattext(c[ord(str_downloading)]+' '+msestring(section)+' '+ + inttostrmse(round(sectionsent/sectionsize*100))+'%',mtk_running); + end; + end; + end; + gek_done: begin + if sender.downloaded then begin + downloaded; + setstattext(c[ord(str_downloaded)]+' '+formatfloatmse( + stopinfo.totalsent/1024,'0.00,')+'kB',mtk_finished); +// sender.abort; + end; + end; + gek_loaded: begin + symbolfo.updatesymbols; + end; + end; +end; + +procedure tmainfo.gdbserverexe(const sender: tguiapplication; + var again: boolean); +begin + sys_schedyield; + if timeout(fgdbservertimeout) and + ((getprocessexitcode(fgdbserverprocid,fgdbserverexitcode,100000) = pee_ok) or + projectoptions.d.nogdbserverexit) then begin + sender.terminatewait; + end + else begin + sender.idlesleep(100000); + again:= true; + end; +end; + +function tmainfo.terminategdbserver(const force: boolean): boolean; +var + int1: integer; +begin + result:= false; + if (fgdbserverprocid <> invalidprochandle) and + (not projectoptions.d.gdbserverstartonce or force) then begin + result:= true; + try + if (getprocessexitcode(fgdbserverprocid,int1) <> pee_ok) then begin + killprocesstree(fgdbserverprocid); + end; + except + end; + fgdbserverprocid:= invalidprochandle; + end; +end; + +procedure tmainfo.gdbservercancel(const sender: tobject); +begin + terminategdbserver(true); +end; + +procedure tmainfo.targetpipeinput(const sender: tpipereader); +begin + messagefo.messages[0].readpipe(sender); +end; + +function tmainfo.startgdbconnection(const attach: boolean): boolean; +var + mstr1: msestring; +begin + result:= false; + with projectoptions,d.texp do begin + if attach then begin + mstr1:= gdbservercommandattach; + end + else begin + mstr1:= gdbservercommand; + end; + if mstr1 <> '' then begin + if terminategdbserver(false) then begin +// sleep(1000); + end; + if d.gdbserverstartonce and gdb.tryconnect then begin + result:= true; + exit; + end; + if d.gdbservertty then begin + fgdbserverprocid:= execmse2(syscommandline(mstr1),nil, + targetpipe.pipereader,targetpipe.pipereader,-1,[exo_tty]); + end + else begin + fgdbserverprocid:= execmse2(syscommandline(mstr1),nil, + nil,nil,-1,[]); + end; + if fgdbserverprocid <> invalidprochandle then begin + fgdbservertimeout:= timestep(round(1000000*d.gdbserverwait)); + if application.waitdialog(nil,c[ord(startgdbservercommand)]+ + mstr1+c[ord(running2)],c[ord(startgdbserver)], + {$ifdef FPC}@{$endif}gdbservercancel,nil, + {$ifdef FPC}@{$endif}gdbserverexe) then begin + if (fgdbserverexitcode <> 0) and + not (projectoptions.d.nogdbserverexit and + (fgdbserverexitcode = -1)) then begin + setstattext(c[ord(gdbserverstarterror)]+' '+ + inttostrmse(fgdbserverexitcode)+'.',mtk_error); + exit; + end; + end + else begin + setstattext(c[ord(gdbservercanceled)],mtk_error); + exit; + end; + end + else begin + setstattext(c[ord(cannotrunstartgdb)],mtk_error); + exit; + end; + end; + end; + result:= true; +end; + +function tmainfo.checkgdberror(aresult: gdbresultty): boolean; +begin + result:= aresult = gdb_ok; + if not result then begin + setstattext(msestring('GDB: ' + gdb.geterrormessage(aresult)),mtk_error); + end; +end; + +procedure tmainfo.checkbluedots; +begin + if (sourcefo <> nil) and (sourcefo.activepage <> nil) then begin + if (gdb.execloaded or gdb.attached) and actionsmo.bluedotsonact.checked then begin + sourcefo.activepage.updatedebuglines; + end + else begin + sourcefo.activepage.cleardebuglines; + end; + end; +end; + +procedure tmainfo.updatesigsettings; +var + int1,int2: integer; + str1: string; + bo1: boolean; +begin + if gdb.active then begin + bo1:= gdb.running; + if bo1 then begin + gdb.interrupttarget; + end; + gdb.ignoreexceptionclasses:= projectoptions.ignoreexceptionclasses; + gdb.stoponexception:= projectoptions.d.stoponexception; + str1:= ''; + {$ifndef mswindows} + for int1:= sigrtmin to sigrtmax do begin + str1:= str1 + 'SIG' + inttostr(int1) + ' '; + end; + {$endif} + if (gdb.handle(str1,[]) = gdb_ok) then begin + for int1:= 0 to high(projectoptions.sigsettings) do begin + with projectoptions.sigsettings[int1] do begin + if num > 0 then begin + for int2:= num to numto do begin + gdb.handle(getsigname(int2),flags); + end; + end; + end; + end; + end; + if bo1 then begin + gdb.restarttarget; + end; + end; + gdb.newconsole:= projectoptions.d.externalconsole; + {$ifdef mswindows} +// gdb.newconsole:= projectoptions.d.externalconsole; + {$else} + gdb.settty:= projectoptions.d.settty; + gdb.xtermcommand:= projectoptions.d.texp.xtermcommand; + {$endif} +end; + +procedure tmainfo.uploadexe(const sender: tguiapplication; var again: boolean); +begin + if not downloading then begin + sender.terminatewait; + end + else begin + sender.idlesleep(100000); + again:= true; + end; +end; + +procedure tmainfo.uploadcancel(const sender: tobject); +begin + abortdownload; +// killprocess(fuploadprocid); +end; + +function tmainfo.needsdownload: boolean; +begin + result:= ftargetfilemodified or projectoptions.d.downloadalways; +end; + +function tmainfo.candebug: boolean; //run command empty or process attached +begin + result:= (projectoptions.d.texp.runcommand = '') or gdb.started; +end; + +procedure tmainfo.downloaded; +begin + ftargetfilemodified:= false; + if fgdbdownloaded then begin + fgdbdownloaded:= false; + if projectoptions.d.restartgdbbeforeload then begin + mainfo.startgdb(false); + end; + end; +end; + +procedure tmainfo.updatetargetenvironment; + //todo: implement for run without gdb +var + int1: integer; +begin + with projectoptions,d.texp do begin + gdb.progparameters:= ansistring(progparameters); + gdb.workingdirectory:= progworkingdirectory; + gdb.clearenvvars; + for int1:= 0 to high(envvarons) do begin + if (int1 > high(envvarnames)) or + (int1 > high(envvarnames)) then begin + break; + end; + if envvarons[int1] then begin + gdb.setenvvar(ansistring(envvarnames[int1]),ansistring(envvarvalues[int1])); + end + else begin + gdb.unsetenvvar(ansistring(envvarnames[int1])); + end; + end; + end; +end; + +procedure tmainfo.startconsole(); +begin + targetconsolefo.clear; + if projectoptions.d.showconsole then begin + targetconsolefo.activate; + end; +end; + +function tmainfo.loadexec(isattach: boolean; + const forcedownload: boolean): boolean; +var + str1: filenamety; +begin + setstattext(''); + result:= false; + if isattach then begin + inc(fexecstamp); + breakpointsfo.updatebreakpoints; + checkbluedots; + end + else begin + if not gdb.execloaded or forcedownload then begin + with projectoptions,d.texp do begin + if d.restartgdbbeforeload or not gdb.active then begin + startgdb(false); + end; + str1:= gettargetfile; + if not d.gdbdownload and not d.gdbsimulator and (uploadcommand <> '') and + (needsdownload or forcedownload) then begin + dodownload; + if application.waitdialog(nil,c[ord(str_uploadcommand)]+uploadcommand+ + c[ord(running2)], + c[ord(str_downloading)],{$ifdef FPC}@{$endif}uploadcancel,nil, + {$ifdef FPC}@{$endif}uploadexe) then begin + if downloadresult <> 0 then begin + setstattext(c[ord(downloaderror)]+' '+ + inttostrmse(downloadresult)+'.',mtk_error); + exit; + end + else begin + setstattext(c[ord(downloadfinished)],mtk_finished); + downloaded; + if projectoptions.s.closemessages then begin + messagefo.hide; + end; + end; + end + else begin + setstattext(c[ord(downloadcanceled)],mtk_error); + exit; + end; + end + end; + mainfo.setstattext(actionsmo.c[ord(ac_loading)]+'.',mtk_running); + application.processmessages(); + application.beginwait(); + if checkgdberror(gdb.fileexec(str1,forcedownload)) then begin + inc(fexecstamp); + breakpointsfo.updatebreakpoints; + mainfo.setstattext('',mtk_info); + end; + application.endwait(); + checkbluedots; + end; + end; + result:= gdb.execloaded or gdb.attached; + if result then begin + updatetargetenvironment; + watchpointsfo.clear; + startconsole(); + if forcedownload and projectoptions.d.gdbdownload then begin + if startgdbconnection(false) then begin + if checkgdberror(gdb.download(false)) then begin + fgdbdownloaded:= true; + end; + end; + end; + end; +end; + +procedure tmainfo.unloadexec; +begin + if gdb.active then begin + gdb.fileexec(''); //unload exec + end; + resetdebugdisp; + checkbluedots; +end; + +procedure tmainfo.startgdb(const killserver: boolean); +begin + terminategdbserver(killserver); + with projectoptions,d.texp do begin + if d.gdbloadtimeout = emptyreal then begin + gdb.loadtimeoutus:= 0; + end + else begin + gdb.loadtimeoutus:= round(d.gdbloadtimeout*1000000); + end; + gdb.remoteconnection:= remoteconnection; + gdb.gdbdownload:= d.gdbdownload; + gdb.simulator:= d.gdbsimulator; + gdb.processorname:= ansistring(gdbprocessor); + gdb.guiintf:= not d.nodebugbeginend; + gdb.beforeconnect:= beforeconnect; + gdb.afterconnect:= afterconnect; + gdb.beforeload:= beforeload; + gdb.afterload:= afterload; + gdb.beforerun:= beforerun; + gdb.startupbkpt:= d.startupbkpt; + gdb.startupbkpton:= d.startupbkpton; + gdb.startgdb(quotefilename(debugcommand)+ ' ' + debugoptions); + end; + updatesigsettings; + cleardebugdisp; + checkbluedots; +end; + +procedure tmainfo.restartgdbonexecute(const sender: tobject); +begin + startgdb(true); +end; + +procedure tmainfo.symboltypeonsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +var + expres: string; +begin + gdb.symboltype(ansistring(avalue),expres); + symboltypedisp.value:= msestring(expres); +end; + +procedure tmainfo.viewbreakpointsonexecute(const sender: tobject); +begin + breakpointsfo.activate; +end; + +procedure tmainfo.viewwatchesonexecute(const sender: tobject); +begin + watchfo.activate; +end; + +procedure tmainfo.viewstackonexecute(const sender: tobject); +begin + stackfo.activate; +end; + +procedure tmainfo.onscale(const sender: TObject); +begin + basedock.bounds_y:= statdisp.bottom + 1; + basedock.bounds_cy:= container.paintrect.cy - basedock.bounds_y; +end; + +procedure tmainfo.parametersonexecute(const sender: TObject); +begin + editprogramparameters; +end; + +procedure tmainfo.viewassembleronexecute(const sender: TObject); +begin + disassfo.activate; +end; + +procedure tmainfo.viewmemoryonexecute(const sender: TObject); +begin + memoryfo.activate; +end; + +procedure tmainfo.viewcpuonexecute(const sender: TObject); +begin + cpufo.activate; +end; + +procedure tmainfo.viewmessagesonexecute(const sender: TObject); +begin + messagefo.activate; +end; + +procedure tmainfo.viewsourceonexecute(const sender: tobject); +begin + sourcefo.activate; +end; + +procedure tmainfo.mainmenuonupdate(const sender: tcustommenu); +var + bo1: boolean; +begin + with projectoptions,d.texp,actionsmo do begin + detachtarget.enabled:= gdb.execloaded or gdb.attached; + download.enabled:= not gdb.started and not gdb.downloading and + ((uploadcommand <> '') or d.gdbdownload); + attachprocess.enabled:= not (gdb.execloaded or gdb.attached); + attachtarget.enabled:= attachprocess.enabled; + run.enabled:= not gdb.running and not gdb.downloading; + bo1:= candebug; + step.enabled:= not gdb.running and not gdb.downloading and bo1; + stepi.enabled:= not gdb.running and not gdb.downloading and bo1; + next.enabled:= not gdb.running and not gdb.downloading and bo1; + nexti.enabled:= not gdb.running and not gdb.downloading and bo1; + finish.enabled:= not gdb.running and gdb.started and bo1; + continue.enabled:= not gdb.running and not gdb.downloading and + (bo1 or (frunningprocess = invalidprochandle)); + interrupt.enabled:= gdb.running and not gdb.downloading and bo1; + reset.enabled:= (gdb.started or gdb.attached or gdb.downloading) or + not bo1 and (frunningprocess <> invalidprochandle); + makeact.enabled:= not making; + buildact.enabled:= not making; + make1act.enabled:= not making; + make2act.enabled:= not making; + make3act.enabled:= not making; + make4act.enabled:= not making; + abortmakeact.enabled:= making; + saveall.enabled:= sourcefo.modified or designer.modified or + projectoptions.modified; + actionsmo.toggleformunit.enabled:= (flastform <> nil) or + (designer.modules.count > 0); + if (sourcefo.activepage <> nil) and + sourcefo.activepage.activeentered then begin + setbm0.enabled:= true; + setbm1.enabled:= true; + setbm2.enabled:= true; + setbm3.enabled:= true; + setbm4.enabled:= true; + setbm5.enabled:= true; + setbm6.enabled:= true; + setbm7.enabled:= true; + setbm8.enabled:= true; + setbm8.enabled:= true; + setbm9.enabled:= true; + setbmnone.enabled:= true; + findbm0.enabled:= true; + findbm1.enabled:= true; + findbm2.enabled:= true; + findbm3.enabled:= true; + findbm4.enabled:= true; + findbm5.enabled:= true; + findbm6.enabled:= true; + findbm7.enabled:= true; + findbm8.enabled:= true; + findbm9.enabled:= true; + print.enabled:= true; + with sourcefo.activepage do begin + actionsmo.save.enabled:= modified; + undo.enabled:= edit.canundo; + redo.enabled:= edit.canredo; + copy.enabled:= edit.hasselection; + copylatexact.enabled:= edit.hasselection; + cut.enabled:= edit.hasselection; + paste.enabled:= edit.canpaste; + delete.enabled:= edit.hasselection; + indent.enabled:= true; + unindent.enabled:= true; + line.enabled:= grid.rowcount > 0; + togglebkpt.enabled:= line.enabled; + togglebkptenable.enabled:= togglebkpt.enabled; +// find.enabled:= true; + replace.enabled:= true; + copyword.enabled:= true; +// actionsmo.repeatfind.enabled:= find.enabled and +// (projectoptions.findreplaceinfo.find.text <> ''); + end; + end + else begin + setbm0.enabled:= false; + setbm1.enabled:= false; + setbm2.enabled:= false; + setbm3.enabled:= false; + setbm4.enabled:= false; + setbm5.enabled:= false; + setbm6.enabled:= false; + setbm7.enabled:= false; + setbm8.enabled:= false; + setbm8.enabled:= false; + setbm9.enabled:= false; + setbmnone.enabled:= false; + findbm0.enabled:= false; + findbm1.enabled:= false; + findbm2.enabled:= false; + findbm3.enabled:= false; + findbm4.enabled:= false; + findbm5.enabled:= false; + findbm6.enabled:= false; + findbm7.enabled:= false; + findbm8.enabled:= false; + findbm9.enabled:= false; + + print.enabled:= false; + save.enabled:= false; + undo.enabled:= false; + redo.enabled:= false; + copy.enabled:= false; + copylatexact.enabled:= false; + cut.enabled:= false; + paste.enabled:= false; + delete.enabled:= false; + indent.enabled:= false; + unindent.enabled:= false; + line.enabled:= false; + togglebkpt.enabled:= false; + togglebkptenable.enabled:= false; +// find.enabled:= false; +// actionsmo.repeatfind.enabled:= false; + replace.enabled:= false; + copyword.enabled:= false; + end; + if (factivedesignmodule <> nil) then begin + save.enabled:= factivedesignmodule^.modified; + close.enabled:= true; + end + else begin + close.enabled:= sourcefo.count > 0; + end; + closeall.enabled:= (sourcefo.count > 0) or (designer.modules.count > 0); + saveas.enabled:= (factivedesignmodule <> nil) or (sourcefo.activepage <> nil); + mainmenu1.menu.itembyname('project').itembyname('close').enabled:= + fprojectloaded; + end; +end; + +function tmainfo.formmenuitemstart: integer; +begin + result:= mainmenu1.menu.itembyname('view').itembyname( + 'formmenuitemstart').index + 1; +end; + +procedure tmainfo.createmodulemenuitem(const amodule: pmoduleinfoty); +var + int1: integer; + item1: tmenuitem; +begin + with mainmenu1.menu.itembyname('view') do begin + for int1:= formmenuitemstart to submenu.count-1 do begin + if submenu[int1].tagpo = amodule then begin + exit; + end; + end; + amodule^.hasmenuitem:= true; + item1:= tmenuitem.create; + with item1 do begin + if amodule^.modified then begin + caption:= '*'+msefileutils.filename(amodule^.filename); + end + else begin + caption:= msefileutils.filename(amodule^.filename); + end; + onexecute:= {$ifdef FPC}@{$endif}doshowform; + tagpo:= amodule; + options:= options + [mao_asyncexecute]; + end; + for int1:= formmenuitemstart to submenu.count-1 do begin + if submenu[int1].caption > item1.caption then begin + submenu.insert(int1,item1); + exit; + end; + end; + submenu.insert(bigint,item1); + end; +end; + +function tmainfo.openformfile(const filename: filenamety; + const ashow,aactivate,showsource,createmenu, + skipexisting: boolean): pmoduleinfoty; +var +// item1: tmenuitem; + wstr1,wstr2: filenamety; +// bo1: boolean; +// int1: integer; +begin + result:= designer.modules.findmodule(filename); + if result = nil then begin + wstr2:= msefileutils.filename(filename); + if findfile(filename) then begin + wstr1:= filename; + end + else begin + wstr1:= searchfile(wstr2,projectoptions.d.texp.sourcedirs); + if wstr1 = '' then begin + wstr1:= filename; //to raise exception + end + else begin + wstr1:= wstr1 + wstr2; + end; + end; + try + result:= designer.loadformfile(wstr1,skipexisting); + if result <> nil then begin + result^.filetag:= sourcefo.newfiletag; + sourcefo.filechangenotifyer.addnotification(wstr1,result^.filetag); + end; + except + showobjecttext(nil,wstr1,false); + errorformfilename:= wstr1; + raise; + end; + if result <> nil then begin + if showsource then begin + loadsourcebyform(wstr1); + end; + end; + end; + if result <> nil then begin + if createmenu then begin + createmodulemenuitem(result); + end; + if ashow then begin + result^.designform.show; + if aactivate then begin + result^.designform.activate; + end; + end; + if result^.modified then begin + sourcechanged(nil); + end; + end; +end; + +procedure tmainfo.loadformbysource(const sourcefilename: filenamety); +var + str1: filenamety; + activebefore: pmoduleinfoty; +begin + if fileext(sourcefilename) = pasfileext then begin + str1:= replacefileext(sourcefilename,formfileext); + if findfile(str1) then begin + activebefore:= factivedesignmodule; + try + openformfile(str1,true,false,false,true,true); + finally + factivedesignmodule:= activebefore; + end; + end; + end; +end; + +procedure tmainfo.loadsourcebyform(const formfilename: filenamety; + const aactivate: boolean = false); +begin + sourcefo.openfile(replacefileext(formfilename,pasfileext),aactivate); +end; + +function tmainfo.opensource(const filekind: filekindty; + const addtoproject: boolean; const aactivate: boolean = true; + const currentnode: tprojectnode = nil): boolean; + +var + unitnode: tunitnode; + +var + int1: integer; + page: tsourcepage; + str1: filenamety; + po1: pmoduleinfoty; + +begin //opensourceactonexecute + result:= openfile.execute = mr_ok; + if result then begin + page:= nil; + po1:= nil; + unitnode:= nil; //compilerwarning + designer.beginskipall; + try + with openfile.controller do begin + for int1:= 0 to high(filenames) do begin + if checkfileext(filenames[int1],[formfileext]) then begin + page:= sourcefo.findsourcepage(filenames[int1]); + if page = nil then begin + po1:= openformfile(filenames[int1],true,false,false,true,false); + end; + end + else begin + page:= sourcefo.openfile(filenames[int1]); + if addtoproject then begin + unitnode:= projecttree.units.addfile(currentnode,filenames[int1]); + end; + str1:= designer.sourcenametoformname(filenames[int1]); + if findfile(str1) then begin + po1:= openformfile(str1,true,false,false,true,false); + if addtoproject then begin + unitnode.setformfile(str1); + end; + end; + end; + end; + end; + finally + designer.endskipall; + end; + if aactivate then begin + if page <> nil then begin + page.activate(true,true); + end + else begin + if po1 <> nil then begin + po1^.designform.activate(true,true); + end; + end; + end; + end; +end; + +procedure tmainfo.designformactivated(const sender: tcustommseform); +begin + setlinkedvar(sender,tmsecomponent(flastform)); + if sourcefo = flastform then begin + factivedesignmodule:= nil; + setlinkedvar(sender,tmsecomponent(flastdesignform)); + end + else begin + if (designer.actmodulepo <> nil) and + (designer.actmodulepo^.designform = flastform) then begin + factivedesignmodule:= designer.actmodulepo; + setlinkedvar(sender,tmsecomponent(flastdesignform)); + end; + end; +end; + +procedure tmainfo.viewcomponentpaletteonexecute(const sender: TObject); +begin + componentpalettefo.show; + componentpalettefo.window.bringtofront; +end; + +procedure tmainfo.viewcomponentstoreonexecute(const sender: TObject); +begin + componentstorefo.activate; +end; + +procedure tmainfo.viewdebuggertoolbaronexecute(const sender: TObject); +begin + debuggerfo.show; + debuggerfo.window.bringtofront; +end; + +procedure tmainfo.mainonloaded(const sender: tobject); +var + wstr1: msestring; +label + endlab; +begin + try + if guitemplatesmo.sysenv.defined[ord(env_globstatfile)] then begin + wstr1:= guitemplatesmo.sysenv.value[ord(env_globstatfile)]; + if wstr1 <> '' then begin + mainstatfile.filename:= wstr1; + goto endlab; + end; + end; + wstr1:= filepath(statdirname); + if not finddir(wstr1) then begin + createdir(wstr1); + end; + {$ifdef mswindows} + mainstatfile.filename:= statname+'wi.sta'; + {$endif} + {$ifdef linux} + mainstatfile.filename:= statname+'li.sta'; + {$endif} + {$ifdef openbsd} + mainstatfile.filename:= statname+'obsd.sta'; + {$endif} + {$ifdef bsd} + mainstatfile.filename:= statname+'bsd.sta'; + {$endif} +endlab: + mainstatfile.readstat; + expandprojectmacros; + onscale(nil); + finally + if not application.terminated then begin + mainfo.activate; + end; + end; + {$ifdef mse_dumpunitgroups} + dumpunitgr; + {$endif} +end; + +function getmodulename(const aname,suffix,formsuffix: msestring): msestring; +var + int1: integer; +begin + int1:= length(aname) - length(suffix); + if (int1 >= 0) and + (msestringcomp(copy(aname,int1+1,bigint),suffix) = 0) then begin + result:= copy(aname,1,int1) + formsuffix; + end + else begin + result:= aname + formsuffix; + end; +end; + +procedure tmainfo.createform(const aname: filenamety; const namebase: string; + const formsuffix: string; const ancestor: string); +var + stream1: ttextstream; + str1,str2,str3: msestring; + po1: pmoduleinfoty; +begin + str3:= removefileext(filename(aname)); + str2:= msestring(getmodulename(str3,msestring(namebase), + msestring(formsuffix))); + stream1:= ttextstream.create(aname,fm_create); + try + formskeleton(stream1,ansistring(filename(str3)),ansistring(str2),ancestor); + finally + stream1.Free; + end; + sourcefo.showsourceline(aname,0,0,true); + str1:= replacefileext(aname,formfileext); + closemodule(designer.modules.findmodule(str1),false); + stream1:= ttextstream.create(str1,fm_create); + try + with stream1 do begin + writeln('object '+str2+': t'+str2); + writeln(' moduleclassname = '''+ancestor+''''); + writeln('end'); + end; + finally + stream1.Free; + end; + po1:= openformfile(str1,true,false,true,true,false); +{ + if kind = fok_main then begin + with tmseform(po1^.instance) do begin + options:= options + [fo_main,fo_terminateonclose]; + optionswindow:= optionswindow + [wo_groupleader]; + end; + end; +} + po1^.modified:= true; //initial create of ..._mfm.pas +end; + +procedure tmainfo.createprogramfile(const aname: filenamety); +var + stream1: ttextstream; +begin + stream1:= ttextstream.create(aname,fm_create); + try + programskeleton(stream1,ansistring(removefileext(filename(aname)))); + finally + stream1.Free; + end; + sourcefo.showsourceline(aname,0,0,true); +end; + +function tmainfo.copynewfile(const aname,newname: filenamety; + const autoincrement: boolean; + const canoverwrite: boolean; + const macronames: array of msestring; + const macrovalues: array of msestring): boolean; + //true if ok +var + int1: integer; + dir,base,ext: filenamety; + path1,path2: filenamety; + macrolist: tmacrolist; + instream,outstream: ttextstream; + text: msestringarty; + +begin + result:= false; + path1:= searchfile(aname); + if path1 = '' then begin + showmessage(c[ord(str_file)]+aname+c[ord(notfound2)],c[ord(warning)]); + end + else begin + path2:= filepath(newname); + if not canoverwrite and findfile(path2) then begin + if not autoincrement then begin + showerror(c[ord(str_file)]+newname+c[ord(exists)]); + exit; + end + else begin + splitfilepath(filepath(aname),dir,base,ext); + base:= base + dir; + int1:= 1; + repeat + path2:= base+inttostrmse(int1)+ext; + inc(int1); + until not findfile(path2); + end; + end; + splitfilepath(path2,dir,base,ext); + macrolist:= tmacrolist.create([mao_curlybraceonly]); + try + macrolist.add(['%FILEPATH%','%FILENAME%','%FILENAMEBASE%'], + [path2,base+ext,base],[]); + macrolist.add(macronames,macrovalues,[]); + instream:= ttextstream.create(path1); + try + text:= instream.readmsestrings; + macrolist.expandmacros1(text); + outstream:= ttextstream.create(path2,fm_create); + try + outstream.writemsestrings(text); + finally + outstream.free; + end; + finally + instream.free; + end; + finally + macrolist.free; + end; + result:= true; + end; +end; + +procedure tmainfo.newfileonexecute(const sender: TObject); +var + str1: filenamety; + int1: integer; +begin + str1:= ''; + int1:= tmenuitem(sender).tag; + with projectoptions.p.texp do begin + if newfisources[int1] = '' then begin + sourcefo.newpage; + end + else begin + if filedialog(str1,[fdo_save,fdo_checkexist],c[ord(str_new)]+' '+ + newfinames[int1],[newfinames[int1]], + [newfifilters[int1]],newfiexts[int1]) = mr_ok then begin + copynewfile(newfisources[int1],str1,false,true, + ['%PROGRAMNAME%','%UNITNAME%'],['${%FILENAMEBASE%}', + '${%FILENAMEBASE%}']); + sourcefo.openfile(str1,true); + end; + end; + end; +end; + +procedure tmainfo.newformonexecute(const sender: TObject); +var + str1,str2,str3,str4,str5,str6: filenamety; + dir,base,ext: filenamety; + po1: pmoduleinfoty; + ancestorclass,ancestorunit: msestring; + +begin +// if formkindty(tmenuitem(sender).tag) = fok_inherited then begin + if projectoptions.p.newinheritedforms[tmenuitem(sender).tag] then begin + po1:= selectinheritedmodule(nil,c[ord(selectancestor)]); + if po1 = nil then begin + exit; + end; + ancestorclass:= msestring(po1^.moduleclassname); + ancestorunit:= filenamebase(po1^.filename); + end + else begin + ancestorclass:= ''; + ancestorunit:= ''; + po1:= nil; + end; + str1:= ''; + if filedialog(str1,[fdo_save,fdo_checkexist],c[ord(newform)], + [c[ord(pascalfiles)]], + ['"*.pas" "*.pp" "*.mla"'],'pas') = mr_ok then begin + with projectoptions.p.texp do begin + str4:= newfonamebases[tmenuitem(sender).tag]; + str6:= newfoformsuffixes[tmenuitem(sender).tag]; + str2:= newfosources[tmenuitem(sender).tag]; + str3:= newfoforms[tmenuitem(sender).tag]; + end; + if (str2 <> '') or (str3 <> '') then begin + if str2 <> '' then begin + str2:= filepath(str2); //sourcesource + end; + if str3 <> '' then begin + str3:= filepath(str3); //formsource + end; + splitfilepath(str1,dir,base,ext); + str4:= getmodulename(base,str4,str6); + str5:= replacefileext(str1,'mfm'); + if str2 <> '' then begin + copynewfile(str2,str1,false,true, + ['%UNITNAME%','%FORMNAME%','%ANCESTORUNIT%','%ANCESTORCLASS%'], + ['${%FILENAMEBASE%}',str4,ancestorunit,ancestorclass]); //source + end; + if str3 <> '' then begin + copynewfile(str3,str5,false,true, + ['%UNITNAME%','%FORMNAME%','%ANCESTORUNIT%','%ANCESTORCLASS%'], + ['${%FILENAMEBASE%}',str4,ancestorunit,ancestorclass]); //form + end; + if str2 <> '' then begin + sourcefo.openfile(str1,true); + end; + if (str3 <> '') then begin + openformfile(str5,true,false,false,true,false); + po1:= designer.modules.findmodule(str5); + if po1 <> nil then begin + po1^.modified:= true; //initial create of ..._mfm.pas + end; + end; + end + else begin +// createform(str1,formkindty(tmenuitem(sender).tag)); + createform(str1,'form','tmseform','fo'); //default + end; + end; +end; + +procedure tmainfo.removemodulemenuitem(const amodule: pmoduleinfoty); +var + int1: integer; +begin + with mainmenu1.menu.itembyname('view') do begin + for int1:= itembyname('formmenuitemstart').index+1 to count - 1 do begin + if items[int1].tagpo = amodule then begin + submenu.delete(int1); + break; + end; + end; + end; +end; + +function tmainfo.closemodule(const amodule: pmoduleinfoty; + const achecksave: boolean; + nocheckclose: boolean = false): boolean; +var + str1: string; + mstr1: filenamety; +begin + if amodule <> nil then begin + mstr1:= amodule^.filename; + if nocheckclose or designer.checkcanclose(amodule,str1) then begin + result:= designer.closemodule(amodule,achecksave); + end + else begin + amodule^.designform.hide; + result:= true; + removemodulemenuitem(amodule); + amodule^.hasmenuitem:= false; + end; + if result then begin + sourcefo.filechangenotifyer.removenotification(mstr1); + if factivedesignmodule = amodule then begin + factivedesignmodule:= nil; + end; + end; + end + else begin + result:= true; + end; +end; + +function tmainfo.checksavecancel(const aresult: modalresultty): modalresultty; +begin + if aresult = mr_cancel then begin + projectoptions.savechecked:= false; + sourcefo.savecanceled; + designer.savecanceled; + end; + result:= aresult; +end; + +function tmainfo.closeall(const nosave: boolean): boolean; +begin + result:= nosave or (checksavecancel(sourcefo.saveall(false)) <> mr_cancel); + if result then begin + result:= nosave or + (checksavecancel(designer.saveall(false,true)) <> mr_cancel); + if result then begin + sourcefo.closeall(true); + while designer.modules.count > 0 do begin + closemodule(designer.modules.itempo[designer.modules.count-1],not nosave,true); + end; + end; + end; +end; + +procedure tmainfo.buildactonexecute(const sender: TObject); +begin + domake(2); +end; + +procedure tmainfo.showfirsterror; +var + int1: integer; + apage: tsourcepage; +begin + with messagefo do begin + for int1:= 0 to messages.rowcount - 1 do begin + if locateerrormessage(messages[0][int1],apage,el_error) then begin + messages.focuscell(makegridcoord(0,int1)); + setstattext(messages[0][int1],mtk_error); + break; + end; + end; + end; +end; +{ +procedure tmainfo.mainfoonclosequery(const sender: tcustommseform; + var modalresult: modalresultty); +begin + if checksave = mr_cancel then begin + modalresult:= mr_none; + end + else begin + sourcefo.filechangenotifyer.clear; + mainstatfile.writestat; + end; +end; +} +procedure tmainfo.mainfoonterminate(var terminate: Boolean); +//var +// modres: modalresultty; +begin + if checksave = mr_cancel then begin + terminate:= false; + end + else begin + sourcefo.filechangenotifyer.clear; + mainstatfile.writestat; + end; + { + modres:= mr_windowclosed; + mainfoonclosequery(nil,modres); + if modres <> mr_windowclosed then begin + terminate:= false; + end; + end; + } +end; + +procedure tmainfo.setprojectname(aname: filenamety); +begin + fprojectname:= aname; + if aname = '' then begin + caption:= idecaption+' (<'+c[ord(new2)]+'>)'; + end + else begin + caption:= idecaption+' ('+filename(aname)+')'; + setcurrentdirmse(filedir(aname)); + openfile.controller.filename:= ''; + end; + dragdock.layoutchanged; //refresh possible dockpanel caption +end; + +function tmainfo.openproject(const aname: filenamety; + const ascopy: boolean = false): boolean; + + procedure closepro; + begin + gdb.abort; + sourceupdater.clear; + initprojectoptions; + projectoptions.projectfilename:= ''; + setprojectname(''); + projecttreefo.clear; + watchfo.clear(true); + breakpointsfo.clear; + watchpointsfo.clear(true); + cleardebugdisp; + designer.savecanceled(); //reset saveall flag + end; + +var + namebefore: msestring; + projectfilebefore: msestring; + projectdirbefore: msestring; + +begin + gdb.abort; + terminategdbserver(true); + result:= false; + projectfilebefore:= projectoptions.projectfilename; + projectdirbefore:= projectoptions.projectdir; + namebefore:= fprojectname; + if (checksave <> mr_cancel) and closeall(true) then begin + closepro; + if aname <> '' then begin + try + setcurrentdirmse(removelastpathsection(aname)); + except + application.handleexception(nil,c[ord(cannotloadproj)]+aname+'": '); + exit; + end; + if not readprojectoptions(aname) then begin + closepro; + end + else begin + fcurrent:= false; + gdb.closegdb; + cleardebugdisp; + if not ascopy then begin + setprojectname(aname); + end + else begin + projectoptions.projectfilename:= projectfilebefore; + projectoptions.projectdir:= projectdirbefore; + expandprojectmacros; + setprojectname(namebefore); + end; + end; + end; + result:= true; + fprojectloaded:= true; + end; +end; + +procedure tmainfo.saveproject(aname: filenamety; + const ascopy: boolean = false); +begin + if aname <> '' then begin + try + saveprojectoptions(aname); + if not ascopy then begin + setprojectname(aname); + expandprojectmacros; + end; + except + application.handleexception(nil); + end; + end; +end; + +procedure tmainfo.newproject(const fromprogram,empty: boolean); +var + aname: filenamety; + mstr1,mstr2: msestring; + i1: integer; + curdir,source,dest: filenamety; + macrolist: tmacrolist; + copiedfiles: filenamearty; + bo1: boolean; +label + endlab; +begin + mstr2:= projecttemplatedir; //use macros of current project + if fromprogram then begin + if (checksave() = mr_cancel) or not closeall(false) then begin + exit; + end; + setprojectname(''); + end; + if fromprogram or openproject('') then begin + gdb.closegdb; + cleardebugdisp; + sourcechanged(nil); + mstr1:= ''; + if not fromprogram then begin + if not empty then begin + aname:= mstr2 + 'default.prj'; + if filedialog(aname,[fdo_checkexist],c[ord(selecttemplate)], + [c[ord(projectfiles)],c[ord(str_allfiles)]], + ['*.prj','*'],'prj') = mr_ok then begin + readprojectoptions(aname); + end; + end; + aname:= ''; + end + else begin + aname:= ''; + if filedialog(aname,[fdo_checkexist],c[ord(selectprogramfile)], + [c[ord(pascalprogfiles)],c[ord(cfiles)],c[ord(str_allfiles)]], + ['"*.pas" "*.pp" "*.mla" "*.dpr" "*.lpr"','"*.c" "*.cc" "*.cpp"','*'], + 'pas') = mr_ok then begin + setcurrentdirmse(filedir(aname)); + with projectoptions do begin + with k.t do begin + mainfile:= filename(aname); + aname:= removefileext(mainfile); + targetfile:= aname+'${EXEEXT}' + end; + expandprojectmacros; + end; + aname:= aname + '.prj'; + end + else begin + goto endlab; + end; + end; + if filedialog(aname,[fdo_save,fdo_checkexist],c[ord(str_newproject)], + [c[ord(projectfiles)],c[ord(str_allfiles)]], + ['*.prj','*'],'prj') = mr_ok then begin + curdir:= filedir(aname); + setcurrentdirmse(curdir); + insertitem(projecthistory,0,aname); + i1:= 1; + while i1 <= high(projecthistory) do begin + if projecthistory[i1] = aname then begin + deleteitem(projecthistory,i1); + end; + inc(i1); + end; + if high(projecthistory) >= + projectfiledia.controller.historymaxcount then begin + setlength(projecthistory,projectfiledia.controller.historymaxcount); + end; + if not fromprogram then begin + mstr1:= removefileext(filename(aname)); + with projectoptions,s do begin + projectfilename:= aname; + projectdir:= curdir; + expandprojectmacros; + with p.texp do begin + setlength(copiedfiles,length(newprojectfiles)); + macrolist:= tmacrolist.create([mao_curlybraceonly]); + try + macrolist.add(['%PROJECTNAME%','%PROJECTDIR%'],[mstr1,curdir],[]); + if runscript(scriptbeforecopy,true,false) then begin + for i1:= 0 to high(newprojectfiles) do begin + source:= filepath(newprojectfiles[i1]); + if i1 <= high(newprojectfilesdest) then begin + dest:= newprojectfilesdest[i1]; + end + else begin + dest:= ''; + end; + if dest <> '' then begin + macrolist.expandmacros1(dest); + if source = '' then begin + createdirpath(dest); + end + else begin + createdirpath(filedir(dest)); + end; + end + else begin + dest:= filename(source); + end; + copiedfiles[i1]:= dest; + if newprojectfiles[i1] <> '' then begin + if (i1 <= high(p.expandprojectfilemacros)) and + p.expandprojectfilemacros[i1] then begin + copynewfile(source,dest,false,false,['%PROJECTNAME%','%PROJECTDIR%'], + [mstr1,curdir]); + end + else begin + try + if not copyfile(source,dest,false) then begin + showerror(c[ord(str_file)]+dest+c[ord(exists)]); + end; + except + application.handleexception(nil); + end; + end; + end; + end; + runscript(scriptaftercopy,false,false); + end; + finally + macrolist.free; + end; + end; + saveproject(aname); + bo1:= true; + for i1:= 0 to high(copiedfiles) do begin + if i1 > high(p.loadprojectfile) then begin + break; + end; + if p.loadprojectfile[i1] then begin + if checkfileext(copiedfiles[i1],[formfileext])then begin + openformfile(copiedfiles[i1],true,false,false,true,false); + end + else begin + sourcefo.openfile(copiedfiles[i1],bo1); + bo1:= false; + end; + end; + end; + end; + end + else begin + saveproject(aname); + sourcefo.openfile(projectoptions.k.texp.mainfile,true); + end; + end + else begin +endlab: + projectoptions.projectfilename:= ''; + projectoptions.modified:= true; + end; + end; +end; + +procedure tmainfo.newprojectonexecute(const sender: tobject); +begin + newproject(false,false); +end; + +procedure tmainfo.newprojectfromprogramexe(const sender: TObject); +begin + newproject(true,false); +end; + +procedure tmainfo.newemptyprojectexe(const sender: TObject); +begin + newproject(false,true); +end; + +procedure tmainfo.openprojectcopyexecute(const sender: TObject); +var + str1: filenamety; +begin + if projectfiledialog(str1,false) = mr_ok then begin + openproject(str1,true); + end; +end; + +procedure tmainfo.saveprojectasonexecute(const sender: tobject); +var + str1: filenamety; +begin + if projectfiledialog(str1,true) = mr_ok then begin + saveproject(str1); + end; +end; + +procedure tmainfo.saveprojectcopyexecute(const sender: TObject); +var + str1: filenamety; +begin + if projectfiledialog(str1,true) = mr_ok then begin + saveproject(str1,true); + end; +end; + +procedure tmainfo.mainstatfileonupdatestat(const sender: tobject; + const filer: tstatfiler); +var + mstr1: filenamety; + mstr2: msestring; + ar1: msestringarty; + int1,i2: integer; + ar2: macroinfoarty; + ma1: settingsmacroty; + bo1: boolean; +begin + ar1:= nil; //compiler warning + updatesettings(filer); + + mstr1:= projectoptions.projectfilename; + filer.updatevalue('projectname',mstr1); + filer.updatevalue('projecthistory',projecthistory); + filer.updatevalue('windowlayoutfile',windowlayoutfile); + filer.updatevalue('windowlayouthistory',windowlayouthistory); + + if not filer.iswriter then begin + if guitemplatesmo.sysenv.defined[ord(env_storeglobalmacros)] then begin + ar2:= guitemplatesmo.sysenv.getcommandlinemacros(ord(env_macrodef)); + with settings.macros do begin + for int1:= 0 to high(ar2) do begin + mstr2:= ar2[int1].name; + bo1:= false; + for ma1:= low(settingsmacroty) to high(settingsmacroty) do begin + if msecomparetext(mstr2,settingsmacronames[ma1]) = 0 then begin + macros[ma1]:= ar2[int1].value; + bo1:= true; + break; + end; + end; + if not bo1 then begin + bo1:= false; + for i2:= 0 to high(globmacronames) do begin + if msecomparetext(mstr2,globmacronames[i2]) = 0 then begin + bo1:= true; + if high(globmacrovalues) < i2 then begin + setlength(globmacrovalues,i2+1); + end; + globmacronames[i2]:= ar2[int1].name; + globmacrovalues[i2]:= ar2[int1].value; + end; + end; + if not bo1 then begin + additem(globmacronames,ar2[int1].name); + if high(globmacrovalues) < high(globmacronames) then begin + setlength(globmacrovalues,high(globmacronames)+1); + end; + globmacrovalues[high(globmacronames)]:= ar2[int1].value; + end; + end; + end; + end; + application.terminated:= true; + projectoptions.projectfilename:= mstr1; + mainstatfile.writestat(); + exit(); + end; + if guitemplatesmo.sysenv.defined[ord(env_filename)] then begin + ar1:= guitemplatesmo.sysenv.values[ord(env_filename)]; + if (high(ar1) = 0) and (fileext(ar1[0]) = 'prj') then begin + mstr1:= filepath(ar1[0]); + end + else begin + if high(ar1) >= 0 then begin + for int1:= 0 to high(ar1) do begin + sourcefo.openfile(ar1[int1],int1 = 0); + end; + end; + exit; + end; + end; + end; + if not filer.iswriter and (mstr1 <> '') and + not guitemplatesmo.sysenv.defined[ord(env_np)] then begin + openproject(mstr1); + end; +end; + +procedure tmainfo.targetfilemodified; +begin + ftargetfilemodified:= true; +end; + +procedure tmainfo.domake(atag: integer); +begin + unloadexec; + if designer.beforemake and + (checksavecancel(sourcefo.saveall(true)) <> mr_cancel) and + (checksavecancel(designer.saveall(true,true)) <> mr_cancel) then begin + updatemodifiedforms; + ftargetfilemodified:= false; + make.domake(atag); + end; +end; + +procedure tmainfo.dorun; +var + mstr1: msestring; + pwdbefore: msestring; +begin + if projectoptions.d.texp.runcommand = '' then begin + if not projectoptions.d.gdbsimulator then begin + if startgdbconnection(false) then begin + gdb.gdbdownload:= projectoptions.d.gdbdownload and needsdownload; + checkgdberror(gdb.run); + end; + end + else begin + checkgdberror(gdb.run); + end; + end + else begin + with projectoptions,d.texp do begin + mstr1:= runcommand; + if progparameters <> '' then begin + mstr1:= mstr1 + ' ' + progparameters; + end; + if progworkingdirectory <> '' then begin + pwdbefore:= setcurrentdirmse(progworkingdirectory); + end; + try + if projectoptions.d.externalconsole then begin + frunningprocess:= execmse4(mstr1,[exo_newconsole]); + end + else begin + startconsole(); + frunningprocess:= targetconsolefo.terminal.execprog(mstr1); + end; + if frunningprocess = invalidprochandle then begin + setstattext(c[ord(cannotstartprocess)],mtk_error); + exit; + end; + runprocmon.listentoprocess(frunningprocess); + finally + if progworkingdirectory <> '' then begin + setcurrentdirmse(pwdbefore); + end; + end; + end; + setstattext('*** '+c[ord(process)]+' '+inttostrmse(frunningprocess)+' '+ + c[ord(running3)]+' ***',mtk_running); + end; +end; + +procedure tmainfo.runprocdied(const sender: TObject; + const prochandle: prochandlety; + const execresult: Integer; const data: Pointer); +begin + if prochandle = frunningprocess then begin + frunningprocess:= invalidprochandle; + if execresult <> 0 then begin + setstattext(c[ord(processterminated)]+' '+inttostrmse(execresult){+'.'}, + mtk_finished); + end + else begin + setstattext(c[ord(proctermnormally)],mtk_finished); + end; + end; +end; + +function tmainfo.runtarget: boolean; + //true if run possible +begin + result:= true; + if not gdb.attached then begin + if (projectoptions.d.texp.runcommand = '') and + (projectoptions.d.t.debugcommand <> '') then begin + if not gdb.started then begin + if loadexec(false,false) then begin + result:= false; + dorun; + end; + end; + end + else begin + result:= false; + if (projectoptions.d.texp.runcommand <> '') then begin + dorun; + end; + end; + end; +end; + +function tmainfo.checkremake(startcommand: startcommandty): boolean; + //true if running possible +begin + if not objectinspectorfo.canclose(nil) then begin + result:= false; + exit; + end; + result:= true; + fstartcommand:= startcommand; + if not gdb.active then begin + startgdb(false); + end; + if not gdb.attached then begin + if (not gdb.started or not fnoremakecheck) and not fcurrent then begin + if (projectoptions.defaultmake <= maxdefaultmake) and + (not gdb.started or askconfirmation(c[ord(str_sourcechanged)])) then begin + result:= false; + watchpointsfo.clear; + domake(projectoptions.defaultmake); + end; + fnoremakecheck:= true; + end; + if result then begin + result:= runtarget; + end; + end + else begin + if not gdb.started then begin + result:= false; + dorun; + end; + end; +end; + +procedure tmainfo.runexec(const sender: tobject); +begin + if checkremake(sc_continue) then begin + dorun; + end; +end; + +procedure tmainfo.aftermake(const adesigner: idesigner; + const exitcode: integer); +begin + if exitcode <> 0 then begin + setstattext(c[ord(makeerror)]+' '+inttostrmse(exitcode)+'.',mtk_error); + showfirsterror; + end + else begin + setstattext(c[ord(makeok)],mtk_finished); + fcurrent:= true; + fnoremakecheck:= false; + messagefo.messages.lastrow; + if projectoptions.s.closemessages then begin + messagefo.hide; + end; + if fstartcommand <> sc_none then begin + runtarget; + end; + end; +end; + +procedure Tmainfo.resetstartcommand; +begin + fstartcommand:= sc_none; +end; + +procedure tmainfo.killtarget; +begin + if frunningprocess <> invalidprochandle then begin + killprocess(frunningprocess); + frunningprocess:= invalidprochandle; + end; +end; + +procedure tmainfo.sourcechanged(const sender: tsourcepage); +begin + fnoremakecheck:= false; + fcurrent:= false; + if sender = nil then begin + updatemodifiedforms; + end; +end; + +procedure tmainfo.exitonexecute(const sender: tobject); +begin + window.close; +end; + +procedure tmainfo.moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); +var + po1: pmoduleinfoty; +begin + po1:= designer.modules.findmodulebyinstance(amodule); + removemodulemenuitem(po1); + if po1 = factivedesignmodule then begin + factivedesignmodule:= nil; + end; +end; + +procedure tmainfo.methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; const aname: string; + const atype: ptypeinfo); +begin + //dummy +end; + +procedure tmainfo.methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; const newname, oldname: string; const atypeinfo: ptypeinfo); +begin + //dummy +end; + +procedure tmainfo.showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); +var + page: tsourcepage; +begin + page:= sourcefo.openfile(afilename,true); + if page <> nil then begin + page.ismoduletext:= true; + if backupcreated then begin + page.setbackupcreated; + end; + end; +end; + +procedure tmainfo.closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); +begin + cancel:= not sourcefo.closepage(afilename); +end; + +procedure tmainfo.newpanelonexecute(const sender: TObject); +begin + newpanel.activate; +end; + +procedure tmainfo.viewwatchpointsonexecute(const sender: TObject); +begin + watchpointsfo.activate; +end; + +procedure tmainfo.viewsymbolsonexecute(const sender: TObject); +begin + symbolfo.activate; +end; + +procedure tmainfo.viewthreadsonexecute(const sender: TObject); +begin + threadsfo.activate; +end; + +procedure tmainfo.viewconsoleonexecute(const sender: TObject); +begin + targetconsolefo.activate; +end; + +procedure tmainfo.viewfindresults(const sender: TObject); +begin + findinfilefo.activate; +end; + +procedure tmainfo.aboutonexecute(const sender: TObject); +begin + showmessage('MSEide version: '+versiontext+c_linefeed+ + 'MSEgui version: '+mseguiversiontext+c_linefeed+ + 'Host: '+ platformtext+ c_linefeed+ + c_linefeed+ + copyrighttext+c_linefeed+ + 'by Martin Schreiber' + ,actionsmo.c[ord(ac_about)]+' MSEide'); +end; + +procedure tmainfo.configureexecute(const sender: TObject); +begin + configureide; +end; + +procedure tmainfo.beforemake(const adesigner: idesigner; + const maketag: integer; var abort: boolean); +begin + //dummy +end; + + +procedure tmainfo.beforefilesave(const adesigner: idesigner; + const afilename: filenamety); +begin + //dummy +end; + +procedure tmainfo.runtool(const sender: tobject); +var + str1: msestring; + mstr1: msestring; + macrolist: tmacrolist; +// gridcoord1: gridcoordty; + cursourcefile,curmodulefile, + cursselection,cursword,cursdefinition: msestring; + curcomponentclass,curproperty: msestring; + spos1: sourceposty; + ar1: componentarty; + propit: tpropertyitem; + opt1: execoptionsty; +begin + with tmenuitem(sender),projectoptions,t,texp do begin + str1:= tosysfilepath(toolfiles[index]); + if str1 <> '' then begin + if (index <= high(toolfiles)) and (toolparams[index] <> '') then begin + if (index <= high(toolsave)) and toolsave[index] then begin + actionsmo.saveallactonexecute(nil); + end; + if sourcefo.activepage <> nil then begin + with sourcefo.activepage do begin + cursourcefile:= tosysfilepath(sourcefo.currentfilename); + cursselection:= sourcefo.currentselection;//edit.selectedtext; + cursword:= sourcefo.currentwordatcursor;//getpascalvarname(edit,edit.editpos,gridcoord1); + if (index <= high(toolparse)) and toolparse[index] then begin + spos1.pos:= edit.editpos; + spos1.filename:= designer.designfiles.find(edit.filename); + application.beginwait; + try + findlinkdest(edit,spos1,cursdefinition); + finally + application.endwait; + end; + end; + end + end + else begin + cursourcefile:= ''; + cursselection:= ''; + cursword:= ''; + cursdefinition:= ''; + end; + curcomponentclass:= ''; + curproperty:= ''; + if factivedesignmodule <> nil then begin + curmodulefile:= tosysfilepath(factivedesignmodule^.filename); + ar1:= designer.selectedcomponents; + if high(ar1) = 0 then begin + with gettypedata(ar1[0].classinfo)^ do begin + curcomponentclass:= msestring(uppercase(unitname+'.'+ar1[0].classname)); + end; + propit:= tpropertyitem(objectinspectorfo.props.item); + if propit <> nil then begin + curproperty:= curcomponentclass+'.' + uppercase(propit.rootpath); + end; + end; + end + else begin + curmodulefile:= ''; + end; + mstr1:= toolparams[index]; + if mstr1 <> '' then begin + macrolist:= tmacrolist.create([mao_caseinsensitive]); + macrolist.add(getprojectmacros); + macrolist.add(['CURSOURCEFILE','CURMODULEFILE', + 'CURSSELECTION','CURSWORD','CURSDEFINITION', + 'CURCOMPONENTCLASS','CURPROPERTY'], + [cursourcefile,curmodulefile, + cursselection,cursword,cursdefinition, + curcomponentclass,curproperty],[]); + macrolist.expandmacros1(mstr1); + macrolist.free; + str1:= str1 + ' ' + mstr1; + end; + end; + opt1:= [exo_nostdhandle]; + if not((index > high(toolhide)) or toolhide[index]) then begin + include(opt1,exo_inactive); + end; + if (index <= high(toolmessages)) and toolmessages[index] then begin + ttoolhandlermo.create(self,str1,opt1); + end + else begin + execmse(str1,opt1{not((index > high(toolhide)) or toolhide[index]),true}); + end; + end; + end; +end; + +procedure tmainfo.statbefread(const sender: TObject); +begin + createcpufo; +end; + +procedure tmainfo.getstatobjs(const sender: TObject; + var aobjects: objectinfoarty); +begin + with projectoptions do begin +{ + if not (sg_options in disabled) then begin + addobjectinfoitem(aobjects,o); + end; +} + if not (sg_editor in disabled) then begin + addobjectinfoitem(aobjects,e); + end; + if not (sg_debugger in disabled) then begin + addobjectinfoitem(aobjects,d); + end; + if not (sg_make in disabled) then begin + addobjectinfoitem(aobjects,k); + end; + if not (sg_macros in disabled) then begin + addobjectinfoitem(aobjects,m); + end; + if not (sg_fontalias in disabled) then begin + addobjectinfoitem(aobjects,a); + end; + if not (sg_usercolors in disabled) then begin + addobjectinfoitem(aobjects,u); + end; + if not (sg_formatmacros in disabled) then begin + addobjectinfoitem(aobjects,f); + end; + if not (sg_templates in disabled) then begin + addobjectinfoitem(aobjects,p); + end; + if not (sg_tools in disabled) then begin + addobjectinfoitem(aobjects,t); + end; + if not (sg_storage in disabled) then begin + addobjectinfoitem(aobjects,r); + end; + if not (sg_state in disabled) then begin + addobjectinfoitem(aobjects,s); + end; + end; +end; + +procedure tmainfo.savewindowlayout(const awriter: tstatwriter); +var + opt1: statfileoptionsty; +begin + opt1:= projectstatfile.options; + projectstatfile.options:= mainfo.projectstatfile.options + + [sfo_nodata,sfo_nooptions]; + awriter.setsection('breakpoints'); + beginpanelplacement(); + try + panelform.updatestat(awriter); + awriter.setsection('layout'); + projectstatfile.updatestat('windowlayout',awriter); + finally + endpanelplacement(); + mainfo.projectstatfile.options:= opt1; + end; +end; + +procedure tmainfo.savewindowlayout(const astream: ttextstream); +var + statwriter: tstatwriter; +begin + statwriter:= tstatwriter.create(astream,ce_utf8); + try + savewindowlayout(statwriter); + finally + statwriter.free; + end; +end; + +procedure tmainfo.loadwindowlayout(const areader: tstatreader); +begin + beginpanelplacement(); + try + areader.setsection('breakpoints'); + panelform.updatestat(areader); + areader.setsection('layout'); + projectstatfile.options:= projectstatfile.options + + [sfo_nodata,sfo_nooptions]; + flayoutloading:= true; + projectstatfile.readstat('windowlayout',areader); + finally + flayoutloading:= false; + projectstatfile.options:= projectstatfile.options - + [sfo_nodata,sfo_nooptions]; + endpanelplacement(); + end; +end; + +procedure tmainfo.loadwindowlayout(const astream: ttextstream); +var + statreader: tstatreader; +begin + statreader:= tstatreader.create(astream,ce_utf8); + try + loadwindowlayout(statreader); + finally + statreader.free; + end; +end; + +procedure tmainfo.loadwindowlayoutexe(const sender: TObject); +var + str1: ttextstream; +begin + if filedialog(windowlayoutfile,[fdo_checkexist],c[ord(str_loadwindowlayout)], + [c[ord(projectfiles)],c[ord(str_allfiles)]],['*.prj','*'],'prj', + nil,nil,nil,[fa_all],[fa_hidden], + @windowlayouthistory) = mr_ok then begin + str1:= ttextstream.create(windowlayoutfile); + try + loadwindowlayout(str1); + finally + str1.destroy(); + end; + end; +end; + +procedure tmainfo.closeprojectactonexecute(const sender: TObject); +begin + if mainfo.openproject('') then begin + caption:= idecaption; + fprojectloaded:= false; + end; +end; + +procedure tmainfo.mainstatbeforewriteexe(const sender: TObject); +begin + disassfo.resetshortcuts(); +end; + +procedure tmainfo.statafterread(const sender: TObject); +begin + actionsmo.forcezorderact.checked:= projectoptions.s.forcezorder; +end; + +procedure tmainfo.basedockpaintexe(const sender: twidget; + const acanvas: tcanvas); +begin + paintdockingareacaption(acanvas,sender,mainfo.c[ord(dockingarea)]); +end; + +end. diff --git a/mseide-msegui/apps/ide/main_mfm.pas b/mseide-msegui/apps/ide/main_mfm.pas new file mode 100644 index 0000000..d29c2be --- /dev/null +++ b/mseide-msegui/apps/ide/main_mfm.pas @@ -0,0 +1,1950 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..38640] of byte end = + (size: 38641; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117,115, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111, + 119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95, + 115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112, + 116,105,111,110,115,11,16,103,111,95,102,105,120,115,105,122,101,98,117,116, + 116,111,110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103, + 111,95,116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103, + 114,111,117,110,100,98,117,116,116,111,110,13,103,111,95,108,111,99,107,98, + 117,116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111, + 110,14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,228,2,8,98, + 111,117,110,100,115,95,121,3,149,0,9,98,111,117,110,100,115,95,99,120, + 3,203,1,9,98,111,117,110,100,115,95,99,121,3,149,0,23,99,111,110, + 116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117, + 115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,27,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,108,101,102,116, + 2,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102, + 114,97,109,101,105,95,116,111,112,2,0,28,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,114,105,103,104,116, + 2,0,29,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102, + 114,97,109,101,105,95,98,111,116,116,111,109,2,0,26,99,111,110,116,97, + 105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,102,105,108,101,102,116,9,102,114,108,95,102,105, + 116,111,112,11,102,114,108,95,102,105,114,105,103,104,116,12,102,114,108,95, + 102,105,98,111,116,116,111,109,0,27,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,30, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,115,98,104,111, + 114,122,46,111,112,116,105,111,110,115,11,12,115,98,111,95,109,111,118,101, + 97,117,116,111,12,115,98,111,95,115,104,111,119,97,117,116,111,0,30,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,115,98,118,101,114, + 116,46,111,112,116,105,111,110,115,11,12,115,98,111,95,109,111,118,101,97, + 117,116,111,12,115,98,111,95,115,104,111,119,97,117,116,111,0,18,99,111, + 110,116,97,105,110,101,114,46,111,110,108,97,121,111,117,116,7,7,111,110, + 115,99,97,108,101,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110, + 100,115,1,2,0,2,16,3,193,1,3,133,0,0,20,100,114,97,103,100, + 111,99,107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95, + 115,97,118,101,112,111,115,13,111,100,95,115,97,118,101,122,111,114,100,101, + 114,10,111,100,95,99,97,110,109,111,118,101,10,111,100,95,99,97,110,115, + 105,122,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100,95,99, + 97,110,100,111,99,107,14,111,100,95,99,97,112,116,105,111,110,104,105,110, + 116,0,24,100,114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100, + 111,99,107,102,111,114,109,11,8,111,100,102,95,109,97,105,110,14,111,100, + 102,95,99,104,105,108,100,105,99,111,110,115,0,13,111,112,116,105,111,110, + 115,119,105,110,100,111,119,11,10,119,111,95,116,97,115,107,98,97,114,0, + 8,109,97,105,110,109,101,110,117,7,9,109,97,105,110,109,101,110,117,49, + 7,111,112,116,105,111,110,115,11,7,102,111,95,109,97,105,110,19,102,111, + 95,116,101,114,109,105,110,97,116,101,111,110,99,108,111,115,101,18,102,111, + 95,103,108,111,98,97,108,115,104,111,114,116,99,117,116,115,10,102,111,95, + 115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101, + 114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116, + 102,105,108,101,7,15,112,114,111,106,101,99,116,115,116,97,116,102,105,108, + 101,7,99,97,112,116,105,111,110,6,6,77,83,69,105,100,101,8,111,110, + 99,114,101,97,116,101,7,14,109,97,105,110,102,111,111,110,99,114,101,97, + 116,101,16,111,110,101,118,101,110,116,108,111,111,112,115,116,97,114,116,7, + 12,109,97,105,110,111,110,108,111,97,100,101,100,9,111,110,100,101,115,116, + 114,111,121,7,15,109,97,105,110,102,111,111,110,100,101,115,116,114,111,121, + 16,111,110,116,101,114,109,105,110,97,116,101,113,117,101,114,121,7,17,109, + 97,105,110,102,111,111,110,116,101,114,109,105,110,97,116,101,8,111,110,108, + 97,121,111,117,116,7,7,111,110,115,99,97,108,101,4,108,101,102,116,2, + 8,3,116,111,112,2,80,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,10,116,100,111,99, + 107,112,97,110,101,108,8,98,97,115,101,100,111,99,107,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,24,111,119,49,95,110,111,112,97,114,101,110,116,104,101, + 105,103,104,116,101,120,116,101,110,100,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,98,97,99,107,103,114,111,117,110,100, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,7,111,110,112,97,105,110,116,7, + 16,98,97,115,101,100,111,99,107,112,97,105,110,116,101,120,101,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9, + 98,111,117,110,100,115,95,99,120,3,193,1,9,98,111,117,110,100,115,95, + 99,121,2,114,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 9,97,110,95,98,111,116,116,111,109,0,20,100,114,97,103,100,111,99,107, + 46,111,112,116,105,111,110,115,100,111,99,107,11,14,111,100,95,97,99,99, + 101,112,116,115,100,111,99,107,12,111,100,95,115,112,108,105,116,118,101,114, + 116,12,111,100,95,115,112,108,105,116,104,111,114,122,8,111,100,95,116,97, + 98,101,100,15,111,100,95,112,114,111,112,111,114,116,105,111,110,97,108,13, + 111,100,95,98,97,99,107,103,114,111,117,110,100,14,111,100,95,99,97,112, + 116,105,111,110,104,105,110,116,0,8,115,116,97,116,102,105,108,101,7,15, + 112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,0,0,11,116,115, + 116,114,105,110,103,100,105,115,112,8,115,116,97,116,100,105,115,112,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117, + 110,100,115,95,99,120,3,193,1,9,98,111,117,110,100,115,95,99,121,2, + 18,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,9,102, + 111,110,116,46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108, + 116,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,7,111,112,116,105,111,110,115,11,19,100,119,111,95,104,105, + 110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,6,116,103,100,98,109,105,3, + 103,100,98,7,103,117,105,105,110,116,102,9,11,103,100,98,100,111,119,110, + 108,111,97,100,8,9,115,105,109,117,108,97,116,111,114,8,11,115,116,97, + 114,116,117,112,98,107,112,116,2,0,13,115,116,97,114,116,117,112,98,107, + 112,116,111,110,8,7,111,110,101,118,101,110,116,7,10,103,100,98,111,110, + 101,118,101,110,116,15,111,118,101,114,108,111,97,100,115,108,101,101,112,117, + 115,3,16,39,4,108,101,102,116,2,120,3,116,111,112,2,32,0,0,9, + 116,115,116,97,116,102,105,108,101,12,109,97,105,110,115,116,97,116,102,105, + 108,101,8,102,105,108,101,110,97,109,101,6,10,109,115,101,105,100,101,46, + 115,116,97,7,102,105,108,101,100,105,114,6,11,34,94,47,46,109,115,101, + 105,100,101,34,7,111,112,116,105,111,110,115,11,14,115,102,111,95,99,114, + 101,97,116,101,112,97,116,104,15,115,102,111,95,116,114,97,110,115,97,99, + 116,105,111,110,17,115,102,111,95,97,99,116,105,118,97,116,111,114,114,101, + 97,100,18,115,102,111,95,97,99,116,105,118,97,116,111,114,119,114,105,116, + 101,0,12,111,110,115,116,97,116,117,112,100,97,116,101,7,24,109,97,105, + 110,115,116,97,116,102,105,108,101,111,110,117,112,100,97,116,101,115,116,97, + 116,17,111,110,115,116,97,116,98,101,102,111,114,101,119,114,105,116,101,7, + 22,109,97,105,110,115,116,97,116,98,101,102,111,114,101,119,114,105,116,101, + 101,120,101,3,116,111,112,2,32,0,0,9,116,109,97,105,110,109,101,110, + 117,9,109,97,105,110,109,101,110,117,49,7,111,112,116,105,111,110,115,11, + 16,109,111,95,115,104,111,114,116,99,117,116,114,105,103,104,116,11,109,111, + 95,97,99,116,105,118,97,116,101,15,109,111,95,117,112,100,97,116,101,111, + 110,105,100,108,101,0,8,111,110,117,112,100,97,116,101,7,16,109,97,105, + 110,109,101,110,117,111,110,117,112,100,97,116,101,18,109,101,110,117,46,115, + 117,98,109,101,110,117,46,99,111,117,110,116,2,7,18,109,101,110,117,46, + 115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,13,115,117,98,109, + 101,110,117,46,99,111,117,110,116,2,10,13,115,117,98,109,101,110,117,46, + 105,116,101,109,115,14,1,13,115,117,98,109,101,110,117,46,99,111,117,110, + 116,2,1,13,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,13, + 115,117,98,109,101,110,117,46,99,111,117,110,116,2,9,13,115,117,98,109, + 101,110,117,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6, + 9,38,77,97,105,110,102,111,114,109,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117, + 116,101,7,16,110,101,119,102,111,114,109,111,110,101,120,101,99,117,116,101, + 0,1,7,99,97,112,116,105,111,110,6,12,38,83,105,109,112,108,101,32, + 70,111,114,109,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111, + 112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99,117,116, + 99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101,120,101, + 99,117,116,101,0,3,116,97,103,2,1,9,111,110,101,120,101,99,117,116, + 101,7,16,110,101,119,102,111,114,109,111,110,101,120,101,99,117,116,101,0, + 1,7,99,97,112,116,105,111,110,6,13,38,68,111,99,107,105,110,103,32, + 70,111,114,109,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111, + 112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99,117,116, + 99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101,120,101, + 99,117,116,101,0,3,116,97,103,2,2,9,111,110,101,120,101,99,117,116, + 101,7,16,110,101,119,102,111,114,109,111,110,101,120,101,99,117,116,101,0, + 1,7,99,97,112,116,105,111,110,6,11,68,38,97,116,97,109,111,100,117, + 108,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112,116, + 105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101,120,101,99,117, + 116,101,0,3,116,97,103,2,3,9,111,110,101,120,101,99,117,116,101,7, + 16,110,101,119,102,111,114,109,111,110,101,120,101,99,117,116,101,0,1,7, + 99,97,112,116,105,111,110,6,8,83,38,117,98,102,111,114,109,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 11,97,115,95,108,111,99,97,108,116,97,103,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,3,116,97,103,2,4,9,111,110, + 101,120,101,99,117,116,101,7,16,110,101,119,102,111,114,109,111,110,101,120, + 101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,7,38,82,101, + 112,111,114,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,3,116, + 97,103,2,5,9,111,110,101,120,101,99,117,116,101,7,16,110,101,119,102, + 111,114,109,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105, + 111,110,6,11,83,38,99,114,105,112,116,102,111,114,109,4,110,97,109,101, + 6,8,112,97,115,99,102,111,114,109,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99, + 97,108,116,97,103,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,3,116,97,103,2,6,9,111,110,101,120,101,99,117,116,101, + 7,16,110,101,119,102,111,114,109,111,110,101,120,101,99,117,116,101,0,1, + 7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97, + 116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116, + 105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,10,38,73,110,104, + 101,114,105,116,101,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97, + 103,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 3,116,97,103,2,7,9,111,110,101,120,101,99,117,116,101,7,16,110,101, + 119,102,111,114,109,111,110,101,120,101,99,117,116,101,0,0,7,99,97,112, + 116,105,111,110,6,5,38,70,111,114,109,4,110,97,109,101,6,4,102,111, + 114,109,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,0,0,0,7,99,97,112,116,105,111,110,6,4,38,78, + 101,119,4,110,97,109,101,6,3,110,101,119,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,6,97, + 99,116,105,111,110,7,20,97,99,116,105,111,110,115,109,111,46,111,112,101, + 110,115,111,117,114,99,101,0,1,6,97,99,116,105,111,110,7,14,97,99, + 116,105,111,110,115,109,111,46,115,97,118,101,0,1,6,97,99,116,105,111, + 110,7,16,97,99,116,105,111,110,115,109,111,46,115,97,118,101,97,115,0, + 1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46, + 115,97,118,101,97,108,108,0,1,6,97,99,116,105,111,110,7,15,97,99, + 116,105,111,110,115,109,111,46,99,108,111,115,101,0,1,6,97,99,116,105, + 111,110,7,18,97,99,116,105,111,110,115,109,111,46,99,108,111,115,101,97, + 108,108,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101, + 112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116, + 99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,15,97, + 99,116,105,111,110,115,109,111,46,112,114,105,110,116,0,1,7,99,97,112, + 116,105,111,110,6,5,69,38,120,105,116,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110, + 115,11,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105, + 111,110,16,109,97,111,95,97,115,121,110,99,101,120,101,99,117,116,101,0, + 9,111,110,101,120,101,99,117,116,101,7,13,101,120,105,116,111,110,101,120, + 101,99,117,116,101,0,0,7,99,97,112,116,105,111,110,6,5,38,70,105, + 108,101,4,110,97,109,101,6,4,102,105,108,101,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,13, + 115,117,98,109,101,110,117,46,99,111,117,110,116,2,7,13,115,117,98,109, + 101,110,117,46,105,116,101,109,115,14,1,6,97,99,116,105,111,110,7,14, + 97,99,116,105,111,110,115,109,111,46,108,105,110,101,0,1,6,97,99,116, + 105,111,110,7,14,97,99,116,105,111,110,115,109,111,46,102,105,110,100,0, + 1,6,97,99,116,105,111,110,7,20,97,99,116,105,111,110,115,109,111,46, + 114,101,112,101,97,116,102,105,110,100,0,1,6,97,99,116,105,111,110,7, + 18,97,99,116,105,111,110,115,109,111,46,102,105,110,100,98,97,99,107,0, + 1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46, + 114,101,112,108,97,99,101,0,1,6,97,99,116,105,111,110,7,20,97,99, + 116,105,111,110,115,109,111,46,102,105,110,100,105,110,102,105,108,101,0,1, + 6,97,99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,102, + 105,110,100,99,111,109,112,97,108,108,97,99,116,7,99,97,112,116,105,111, + 110,6,15,70,105,110,100,32,38,67,111,109,112,111,110,101,110,116,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,16,97,115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17,97, + 115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,49,0,0,0,7, + 99,97,112,116,105,111,110,6,7,38,83,101,97,114,99,104,4,110,97,109, + 101,6,6,115,101,97,114,99,104,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109, + 101,110,117,46,99,111,117,110,116,2,15,13,115,117,98,109,101,110,117,46, + 105,116,101,109,115,14,1,6,97,99,116,105,111,110,7,24,97,99,116,105, + 111,110,115,109,111,46,115,101,108,101,99,116,101,100,105,116,112,97,103,101, + 0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97, + 114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,14,97,99,116, + 105,111,110,115,109,111,46,117,110,100,111,0,1,6,97,99,116,105,111,110, + 7,14,97,99,116,105,111,110,115,109,111,46,114,101,100,111,0,1,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,14,97,99,116,105,111,110,115, + 109,111,46,99,111,112,121,0,1,6,97,99,116,105,111,110,7,22,97,99, + 116,105,111,110,115,109,111,46,99,111,112,121,108,97,116,101,120,97,99,116, + 0,1,6,97,99,116,105,111,110,7,18,97,99,116,105,111,110,115,109,111, + 46,99,111,112,121,119,111,114,100,0,1,6,97,99,116,105,111,110,7,13, + 97,99,116,105,111,110,115,109,111,46,99,117,116,0,1,6,97,99,116,105, + 111,110,7,15,97,99,116,105,111,110,115,109,111,46,112,97,115,116,101,0, + 1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115,109,111,46, + 100,101,108,101,116,101,0,1,6,97,99,116,105,111,110,7,19,97,99,116, + 105,111,110,115,109,111,46,115,101,108,101,99,116,97,108,108,0,1,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115, + 109,111,46,105,110,100,101,110,116,0,1,6,97,99,116,105,111,110,7,18, + 97,99,116,105,111,110,115,109,111,46,117,110,105,110,100,101,110,116,0,0, + 7,99,97,112,116,105,111,110,6,5,38,69,100,105,116,4,110,97,109,101, + 6,4,101,100,105,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109,101,110,117, + 46,99,111,117,110,116,2,22,13,115,117,98,109,101,110,117,46,105,116,101, + 109,115,14,1,7,99,97,112,116,105,111,110,6,12,69,110,38,118,105,114, + 111,110,109,101,110,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,14,100,117, + 109,109,121,105,109,97,103,101,108,105,115,116,9,111,110,101,120,101,99,117, + 116,101,7,19,112,97,114,97,109,101,116,101,114,115,111,110,101,120,101,99, + 117,116,101,0,1,7,99,97,112,116,105,111,110,6,16,82,101,115,116,97, + 114,116,32,68,101,98,117,103,103,101,114,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,105,109,97,103,101,108,105,115,116,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,9,105,109,97,103,101,108,105,115, + 116,7,14,100,117,109,109,121,105,109,97,103,101,108,105,115,116,9,111,110, + 101,120,101,99,117,116,101,7,19,114,101,115,116,97,114,116,103,100,98,111, + 110,101,120,101,99,117,116,101,0,1,6,97,99,116,105,111,110,7,23,97, + 99,116,105,111,110,115,109,111,46,97,116,116,97,99,104,112,114,111,99,101, + 115,115,5,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,0,9,105,109,97,103,101,108,105,115,116,7,14, + 100,117,109,109,121,105,109,97,103,101,108,105,115,116,0,1,6,97,99,116, + 105,111,110,7,22,97,99,116,105,111,110,115,109,111,46,97,116,116,97,99, + 104,116,97,114,103,101,116,5,115,116,97,116,101,11,17,97,115,95,108,111, + 99,97,108,105,109,97,103,101,108,105,115,116,0,9,105,109,97,103,101,108, + 105,115,116,7,14,100,117,109,109,121,105,109,97,103,101,108,105,115,116,0, + 1,6,97,99,116,105,111,110,7,22,97,99,116,105,111,110,115,109,111,46, + 100,101,116,97,99,104,116,97,114,103,101,116,5,115,116,97,116,101,11,17, + 97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,0,9,105, + 109,97,103,101,108,105,115,116,7,14,100,117,109,109,121,105,109,97,103,101, + 108,105,115,116,0,1,6,97,99,116,105,111,110,7,18,97,99,116,105,111, + 110,115,109,111,46,100,111,119,110,108,111,97,100,5,115,116,97,116,101,11, + 17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,0,9, + 105,109,97,103,101,108,105,115,116,7,14,100,117,109,109,121,105,109,97,103, + 101,108,105,115,116,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111, + 95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116, + 99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111,110, + 7,18,97,99,116,105,111,110,115,109,111,46,99,111,110,116,105,110,117,101, + 0,1,6,97,99,116,105,111,110,7,15,97,99,116,105,111,110,115,109,111, + 46,114,101,115,101,116,0,1,6,97,99,116,105,111,110,7,19,97,99,116, + 105,111,110,115,109,111,46,105,110,116,101,114,114,117,112,116,0,1,6,97, + 99,116,105,111,110,7,14,97,99,116,105,111,110,115,109,111,46,115,116,101, + 112,0,1,6,97,99,116,105,111,110,7,15,97,99,116,105,111,110,115,109, + 111,46,115,116,101,112,105,0,1,6,97,99,116,105,111,110,7,14,97,99, + 116,105,111,110,115,109,111,46,110,101,120,116,0,1,6,97,99,116,105,111, + 110,7,15,97,99,116,105,111,110,115,109,111,46,110,101,120,116,105,0,1, + 6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115,109,111,46,102, + 105,110,105,115,104,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111, + 95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116, + 99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111,110, + 7,20,97,99,116,105,111,110,115,109,111,46,98,107,112,116,115,111,110,97, + 99,116,5,115,116,97,116,101,11,10,97,115,95,99,104,101,99,107,101,100, + 0,7,111,112,116,105,111,110,115,11,12,109,97,111,95,99,104,101,99,107, + 98,111,120,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116, + 105,111,110,0,0,1,6,97,99,116,105,111,110,7,20,97,99,116,105,111, + 110,115,109,111,46,116,111,103,103,108,101,98,107,112,116,5,115,116,97,116, + 101,11,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116, + 0,9,105,109,97,103,101,108,105,115,116,7,14,100,117,109,109,121,105,109, + 97,103,101,108,105,115,116,0,1,6,97,99,116,105,111,110,7,26,97,99, + 116,105,111,110,115,109,111,46,116,111,103,103,108,101,98,107,112,116,101,110, + 97,98,108,101,5,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108, + 105,109,97,103,101,108,105,115,116,0,9,105,109,97,103,101,108,105,115,116, + 7,14,100,117,109,109,121,105,109,97,103,101,108,105,115,116,0,1,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,22,97,99,116,105,111,110,115, + 109,111,46,119,97,116,99,104,101,115,111,110,97,99,116,5,115,116,97,116, + 101,11,10,97,115,95,99,104,101,99,107,101,100,0,7,111,112,116,105,111, + 110,115,11,12,109,97,111,95,99,104,101,99,107,98,111,120,19,109,97,111, + 95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,6, + 97,99,116,105,111,110,7,23,97,99,116,105,111,110,115,109,111,46,98,108, + 117,101,100,111,116,115,111,110,97,99,116,5,115,116,97,116,101,11,10,97, + 115,95,99,104,101,99,107,101,100,0,7,111,112,116,105,111,110,115,11,12, + 109,97,111,95,99,104,101,99,107,98,111,120,19,109,97,111,95,115,104,111, + 114,116,99,117,116,99,97,112,116,105,111,110,0,0,0,7,99,97,112,116, + 105,111,110,6,7,38,84,97,114,103,101,116,4,110,97,109,101,6,6,116, + 97,114,103,101,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109,101,110,117,46, + 99,111,117,110,116,2,28,13,115,117,98,109,101,110,117,46,105,116,101,109, + 115,14,1,13,115,117,98,109,101,110,117,46,99,111,117,110,116,2,2,13, + 115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,111,112,116,105, + 111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109, + 97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0, + 1,7,99,97,112,116,105,111,110,6,10,38,78,101,119,32,80,97,110,101, + 108,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117, + 116,101,0,9,111,110,101,120,101,99,117,116,101,7,17,110,101,119,112,97, + 110,101,108,111,110,101,120,101,99,117,116,101,0,0,7,99,97,112,116,105, + 111,110,6,7,80,97,110,38,101,108,115,4,110,97,109,101,6,6,112,97, + 110,101,108,115,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97,103, + 101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101,110, + 114,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101, + 110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,0,0,1,6, + 97,99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,102,111, + 114,99,101,122,111,114,100,101,114,97,99,116,5,115,116,97,116,101,11,17, + 97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,0,7,111, + 112,116,105,111,110,115,11,12,109,97,111,95,99,104,101,99,107,98,111,120, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110, + 117,105,99,111,110,115,0,1,7,99,97,112,116,105,111,110,6,19,76,111, + 97,100,32,87,105,38,110,100,111,119,32,76,97,121,111,117,116,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,105,109, + 97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110,117,105,99,111, + 110,115,9,111,110,101,120,101,99,117,116,101,7,19,108,111,97,100,119,105, + 110,100,111,119,108,97,121,111,117,116,101,120,101,0,1,7,111,112,116,105, + 111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109, + 97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0, + 1,7,99,97,112,116,105,111,110,6,18,67,111,109,112,111,110,101,110,116, + 32,38,80,97,108,101,116,116,101,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101, + 118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,1, + 9,111,110,101,120,101,99,117,116,101,7,29,118,105,101,119,99,111,109,112, + 111,110,101,110,116,112,97,108,101,116,116,101,111,110,101,120,101,99,117,116, + 101,0,1,7,99,97,112,116,105,111,110,6,16,67,111,109,112,111,110,101, + 110,116,32,83,116,111,38,114,101,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101, + 118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,16, + 9,111,110,101,120,101,99,117,116,101,7,27,118,105,101,119,99,111,109,112, + 111,110,101,110,116,115,116,111,114,101,111,110,101,120,101,99,117,116,101,0, + 1,7,99,97,112,116,105,111,110,6,17,79,98,106,101,99,116,32,38,73, + 110,115,112,101,99,116,111,114,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109, + 97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118, + 109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,14,9, + 111,110,101,120,101,99,117,116,101,7,28,118,105,101,119,111,98,106,101,99, + 116,105,110,115,112,101,99,116,111,114,111,110,101,120,101,99,117,116,101,0, + 1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114, + 97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112, + 116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,7,83,111,38, + 117,114,99,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97,103, + 101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101,110, + 114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99, + 117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101, + 120,101,99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118, + 105,101,118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114, + 2,5,9,111,110,101,120,101,99,117,116,101,7,19,118,105,101,119,115,111, + 117,114,99,101,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116, + 105,111,110,6,9,38,77,101,115,115,97,103,101,115,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108, + 111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,19, + 109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,16, + 109,97,111,95,97,115,121,110,99,101,120,101,99,117,116,101,0,9,105,109, + 97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110,117,105,99,111, + 110,115,7,105,109,97,103,101,110,114,2,4,9,111,110,101,120,101,99,117, + 116,101,7,21,118,105,101,119,109,101,115,115,97,103,101,115,111,110,101,120, + 101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,13,38,70,105, + 110,100,32,82,101,115,117,108,116,115,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108, + 105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105, + 101,118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2, + 15,9,111,110,101,120,101,99,117,116,101,7,15,118,105,101,119,102,105,110, + 100,114,101,115,117,108,116,115,0,1,7,111,112,116,105,111,110,115,11,13, + 109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,7,99,97,112, + 116,105,111,110,6,9,38,68,101,98,117,103,103,101,114,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95, + 108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,9,105,109,97,103,101,108,105,115, + 116,7,13,118,105,101,118,109,101,110,117,105,99,111,110,115,7,105,109,97, + 103,101,110,114,2,2,9,111,110,101,120,101,99,117,116,101,7,28,118,105, + 101,119,100,101,98,117,103,103,101,114,116,111,111,108,98,97,114,111,110,101, + 120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,8,83,121, + 109,98,111,38,108,115,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103, + 101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101, + 110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,18,9,111,110, + 101,120,101,99,117,116,101,7,20,118,105,101,119,115,121,109,98,111,108,115, + 111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6, + 8,38,87,97,116,99,104,101,115,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115, + 104,111,114,116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97, + 115,121,110,99,101,120,101,99,117,116,101,0,9,105,109,97,103,101,108,105, + 115,116,7,13,118,105,101,118,109,101,110,117,105,99,111,110,115,7,105,109, + 97,103,101,110,114,2,8,9,111,110,101,120,101,99,117,116,101,7,20,118, + 105,101,119,119,97,116,99,104,101,115,111,110,101,120,101,99,117,116,101,0, + 1,7,99,97,112,116,105,111,110,6,6,38,83,116,97,99,107,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97, + 115,95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110, + 115,11,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105, + 111,110,16,109,97,111,95,97,115,121,110,99,101,120,101,99,117,116,101,0, + 9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110,117, + 105,99,111,110,115,7,105,109,97,103,101,110,114,2,9,9,111,110,101,120, + 101,99,117,116,101,7,18,118,105,101,119,115,116,97,99,107,111,110,101,120, + 101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,8,84,38,104, + 114,101,97,100,115,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97, + 103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101, + 110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110, + 117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,10,9,111,110,101, + 120,101,99,117,116,101,7,20,118,105,101,119,116,104,114,101,97,100,115,111, + 110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,4, + 38,67,80,85,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97,103, + 101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101,110, + 114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110,117, + 105,99,111,110,115,7,105,109,97,103,101,110,114,2,11,9,111,110,101,120, + 101,99,117,116,101,7,16,118,105,101,119,99,112,117,111,110,101,120,101,99, + 117,116,101,0,1,7,99,97,112,116,105,111,110,6,10,38,65,115,115,101, + 109,98,108,101,114,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97, + 103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101, + 110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110, + 117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,12,9,111,110,101, + 120,101,99,117,116,101,7,22,118,105,101,119,97,115,115,101,109,98,108,101, + 114,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110, + 6,7,77,101,109,111,114,38,121,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101, + 118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,17, + 9,111,110,101,120,101,99,117,116,101,7,19,118,105,101,119,109,101,109,111, + 114,121,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111, + 110,6,15,38,84,97,114,103,101,116,32,67,111,110,115,111,108,101,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15, + 97,115,95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,105,109,97,103,101, + 108,105,115,116,7,13,118,105,101,118,109,101,110,117,105,99,111,110,115,7, + 105,109,97,103,101,110,114,2,13,9,111,110,101,120,101,99,117,116,101,7, + 20,118,105,101,119,99,111,110,115,111,108,101,111,110,101,120,101,99,117,116, + 101,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112, + 97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99, + 97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,12,38, + 66,114,101,97,107,112,111,105,110,116,115,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97, + 108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,19,109,97,111, + 95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,16,109,97,111, + 95,97,115,121,110,99,101,120,101,99,117,116,101,0,9,105,109,97,103,101, + 108,105,115,116,7,13,118,105,101,118,109,101,110,117,105,99,111,110,115,7, + 105,109,97,103,101,110,114,2,6,9,111,110,101,120,101,99,117,116,101,7, + 24,118,105,101,119,98,114,101,97,107,112,111,105,110,116,115,111,110,101,120, + 101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,12,87,97,116, + 99,104,112,38,111,105,110,116,115,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101, + 118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,7, + 9,111,110,101,120,101,99,117,116,101,7,24,118,105,101,119,119,97,116,99, + 104,112,111,105,110,116,115,111,110,101,120,101,99,117,116,101,0,1,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,25,97,99,116,105,111,110,115, + 109,111,46,116,111,103,103,108,101,105,110,115,112,101,99,116,111,114,5,115, + 116,97,116,101,11,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108, + 105,115,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114, + 116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110, + 99,101,120,101,99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7, + 13,118,105,101,118,109,101,110,117,105,99,111,110,115,9,111,110,101,120,101, + 99,117,116,101,7,30,116,111,103,103,108,101,111,98,106,101,99,116,105,110, + 115,112,101,99,116,111,114,111,110,101,120,101,99,117,116,101,0,1,6,97, + 99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,116,111,103, + 103,108,101,102,111,114,109,117,110,105,116,7,99,97,112,116,105,111,110,6, + 16,84,111,103,103,108,101,32,70,111,114,109,47,85,110,105,116,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,0,7, + 111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99,117, + 116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101,120, + 101,99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105, + 101,118,109,101,110,117,105,99,111,110,115,0,1,4,110,97,109,101,6,17, + 102,111,114,109,109,101,110,117,105,116,101,109,115,116,97,114,116,7,111,112, + 116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 0,0,0,7,99,97,112,116,105,111,110,6,5,38,86,105,101,119,4,110, + 97,109,101,6,4,118,105,101,119,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109, + 101,110,117,46,99,111,117,110,116,2,19,13,115,117,98,109,101,110,117,46, + 105,116,101,109,115,14,1,6,97,99,116,105,111,110,7,17,97,99,116,105, + 111,110,115,109,111,46,109,97,107,101,97,99,116,7,99,97,112,116,105,111, + 110,6,5,38,77,97,107,101,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108, + 116,97,103,0,3,116,97,103,2,1,0,1,6,97,99,116,105,111,110,7, + 18,97,99,116,105,111,110,115,109,111,46,98,117,105,108,100,97,99,116,7, + 99,97,112,116,105,111,110,6,6,38,66,117,105,108,100,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97, + 115,95,108,111,99,97,108,116,97,103,0,3,116,97,103,2,2,0,1,6, + 97,99,116,105,111,110,7,18,97,99,116,105,111,110,115,109,111,46,109,97, + 107,101,49,97,99,116,7,99,97,112,116,105,111,110,6,7,77,97,107,101, + 32,38,49,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,0,3, + 116,97,103,2,4,0,1,6,97,99,116,105,111,110,7,18,97,99,116,105, + 111,110,115,109,111,46,109,97,107,101,50,97,99,116,7,99,97,112,116,105, + 111,110,6,7,77,97,107,101,32,38,50,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111, + 99,97,108,116,97,103,0,3,116,97,103,2,8,0,1,6,97,99,116,105, + 111,110,7,18,97,99,116,105,111,110,115,109,111,46,109,97,107,101,51,97, + 99,116,7,99,97,112,116,105,111,110,6,7,77,97,107,101,32,38,51,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,11,97,115,95,108,111,99,97,108,116,97,103,0,3,116,97,103,2, + 16,0,1,6,97,99,116,105,111,110,7,18,97,99,116,105,111,110,115,109, + 111,46,109,97,107,101,52,97,99,116,7,99,97,112,116,105,111,110,6,7, + 77,97,107,101,32,38,52,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116, + 97,103,0,3,116,97,103,2,32,0,1,6,97,99,116,105,111,110,7,22, + 97,99,116,105,111,110,115,109,111,46,97,98,111,114,116,109,97,107,101,97, + 99,116,7,99,97,112,116,105,111,110,6,11,38,65,98,111,114,116,32,77, + 97,107,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,0,0, + 1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114, + 97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112, + 116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,27,97,99,116,105, + 111,110,115,109,111,46,112,114,111,106,101,99,116,111,112,116,105,111,110,115, + 97,99,116,0,1,6,97,99,116,105,111,110,7,24,97,99,116,105,111,110, + 115,109,111,46,112,114,111,106,101,99,116,116,114,101,101,97,99,116,0,1, + 6,97,99,116,105,111,110,7,26,97,99,116,105,111,110,115,109,111,46,112, + 114,111,106,101,99,116,115,111,117,114,99,101,97,99,116,0,1,7,111,112, + 116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 0,0,1,13,115,117,98,109,101,110,117,46,99,111,117,110,116,2,3,13, + 115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97,112,116, + 105,111,110,6,14,70,114,111,109,32,38,84,101,109,112,108,97,116,101,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,111,110,101,120,101,99,117,116,101,7,19,110,101,119,112,114,111,106, + 101,99,116,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105, + 111,110,6,13,70,114,111,109,32,38,80,114,111,103,114,97,109,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9, + 111,110,101,120,101,99,117,116,101,7,24,110,101,119,112,114,111,106,101,99, + 116,102,114,111,109,112,114,111,103,114,97,109,101,120,101,0,1,7,99,97, + 112,116,105,111,110,6,6,38,69,109,112,116,121,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120, + 101,99,117,116,101,7,18,110,101,119,101,109,112,116,121,112,114,111,106,101, + 99,116,101,120,101,0,0,7,99,97,112,116,105,111,110,6,4,38,78,101, + 119,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,24,97,99,116,105, + 111,110,115,109,111,46,112,114,111,106,101,99,116,111,112,101,110,97,99,116, + 0,1,7,99,97,112,116,105,111,110,6,9,79,112,101,110,32,99,111,112, + 121,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117, + 116,101,0,9,111,110,101,120,101,99,117,116,101,7,22,111,112,101,110,112, + 114,111,106,101,99,116,99,111,112,121,101,120,101,99,117,116,101,0,1,6, + 97,99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,112,114, + 111,106,101,99,116,115,97,118,101,97,99,116,0,1,7,99,97,112,116,105, + 111,110,6,8,83,97,118,101,32,38,97,115,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101, + 99,117,116,101,7,22,115,97,118,101,112,114,111,106,101,99,116,97,115,111, + 110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,12, + 83,97,118,101,32,97,115,32,99,111,112,121,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101, + 99,117,116,101,7,22,115,97,118,101,112,114,111,106,101,99,116,99,111,112, + 121,101,120,101,99,117,116,101,0,1,6,97,99,116,105,111,110,7,25,97, + 99,116,105,111,110,115,109,111,46,112,114,111,106,101,99,116,99,108,111,115, + 101,97,99,116,7,99,97,112,116,105,111,110,6,6,38,67,108,111,115,101, + 4,110,97,109,101,6,5,99,108,111,115,101,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101, + 99,117,116,101,7,24,99,108,111,115,101,112,114,111,106,101,99,116,97,99, + 116,111,110,101,120,101,99,117,116,101,0,0,7,99,97,112,116,105,111,110, + 6,8,38,80,114,111,106,101,99,116,4,110,97,109,101,6,7,112,114,111, + 106,101,99,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,14,97,98, + 111,117,116,111,110,101,120,101,99,117,116,101,0,1,13,115,117,98,109,101, + 110,117,46,99,111,117,110,116,2,2,13,115,117,98,109,101,110,117,46,105, + 116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,6,38,65,98,111, + 117,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,14,97,98,111,117, + 116,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110, + 6,17,38,67,111,110,102,105,103,117,114,101,32,77,83,69,105,100,101,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,111,110,101,120,101,99,117,116,101,7,16,99,111,110,102,105,103,117, + 114,101,101,120,101,99,117,116,101,0,0,7,99,97,112,116,105,111,110,6, + 9,83,101,116,116,38,105,110,103,115,4,110,97,109,101,6,8,115,101,116, + 116,105,110,103,115,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,14,97, + 98,111,117,116,111,110,101,120,101,99,117,116,101,0,0,4,108,101,102,116, + 2,103,3,116,111,112,2,96,0,0,11,116,102,105,108,101,100,105,97,108, + 111,103,8,111,112,101,110,102,105,108,101,8,115,116,97,116,102,105,108,101, + 7,15,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,18,99,111, + 110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,14,102,100, + 111,95,99,104,101,99,107,101,120,105,115,116,0,22,99,111,110,116,114,111, + 108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,9,79,112, + 101,110,32,102,105,108,101,22,99,111,110,116,114,111,108,108,101,114,46,99, + 97,112,116,105,111,110,115,97,118,101,6,12,83,97,118,101,32,102,105,108, + 101,32,97,115,3,116,111,112,2,1,0,0,9,116,115,116,97,116,102,105, + 108,101,15,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,8,102, + 105,108,101,110,97,109,101,6,10,115,116,97,116,117,115,46,115,116,97,16, + 111,110,115,116,97,116,98,101,102,111,114,101,114,101,97,100,7,11,115,116, + 97,116,98,101,102,114,101,97,100,15,111,110,115,116,97,116,97,102,116,101, + 114,114,101,97,100,7,13,115,116,97,116,97,102,116,101,114,114,101,97,100, + 3,116,111,112,2,64,0,0,10,116,105,109,97,103,101,108,105,115,116,13, + 118,105,101,118,109,101,110,117,105,99,111,110,115,5,119,105,100,116,104,2, + 18,6,104,101,105,103,104,116,2,18,7,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,5,99,111,117,110,116,2,19,4,108,101,102,116,3,57, + 1,3,116,111,112,2,96,5,105,109,97,103,101,10,16,89,0,0,0,0, + 0,0,6,0,0,0,90,0,0,0,90,0,0,0,136,61,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,6,203,88,38,1,197,68, + 11,1,255,255,255,3,194,59,0,1,255,255,255,6,168,168,168,1,184,184, + 184,7,212,212,212,1,233,233,233,8,229,229,229,1,173,173,173,1,190,190, + 190,17,208,208,208,1,255,255,255,17,224,224,224,1,255,255,255,16,208,208, + 208,1,255,255,255,2,198,57,0,1,255,0,0,1,255,255,255,1,253,67, + 9,1,223,140,106,1,223,136,100,1,234,55,5,1,234,54,5,1,221,82, + 34,1,218,129,92,1,222,62,6,1,253,67,9,1,255,255,255,4,220,220, + 220,1,202,202,202,7,255,255,255,8,202,202,202,1,167,167,167,1,190,190, + 190,1,208,208,208,17,60,60,60,1,208,208,208,16,141,180,183,1,208,208, + 208,1,124,124,124,15,255,255,255,1,0,0,255,1,255,255,255,2,205,98, + 50,1,221,147,114,1,217,96,50,1,235,55,5,1,223,127,93,1,252,247, + 244,1,215,90,49,1,212,63,21,1,237,192,175,1,238,195,177,1,221,51, + 2,1,235,55,5,1,246,62,8,1,255,255,255,3,233,233,233,1,255,255, + 255,8,202,202,202,1,196,196,196,1,197,197,197,1,200,200,200,2,202,202, + 202,1,133,133,133,1,202,202,202,1,138,138,138,1,190,190,190,1,208,208, + 208,3,2,172,8,1,1,170,9,1,208,208,208,12,181,248,254,1,208,208, + 208,16,255,255,255,1,124,124,124,2,232,232,232,14,255,255,255,1,208,208, + 208,1,255,255,255,2,197,73,22,1,238,197,180,1,247,226,218,1,219,117, + 81,1,210,75,33,1,251,242,238,1,241,205,191,1,214,102,65,1,255,255, + 255,1,226,149,122,1,211,39,0,1,217,44,1,1,229,51,4,1,218,103, + 59,1,212,116,74,1,255,255,255,1,233,233,233,1,255,255,255,1,181,181, + 181,1,183,183,183,1,190,190,190,1,216,216,216,1,224,224,224,1,133,133, + 133,1,255,255,255,1,177,177,177,1,125,125,125,1,151,151,151,1,154,154, + 154,1,135,135,135,1,202,202,202,1,133,133,133,1,202,202,202,1,138,138, + 138,1,190,190,190,1,208,208,208,3,4,178,6,1,13,180,13,1,8,173, + 14,1,208,208,208,11,111,199,206,1,208,208,208,16,47,47,47,1,208,208, + 208,1,124,124,124,1,232,232,232,14,255,255,255,1,116,149,150,1,255,255, + 255,2,246,62,8,1,220,120,82,1,254,253,252,1,255,255,255,1,232,174, + 153,1,216,115,79,1,252,246,243,1,212,104,66,1,246,223,214,1,218,114, + 82,1,211,106,64,1,208,66,25,1,221,131,98,1,247,230,222,1,217,116, + 75,1,255,255,255,1,229,229,229,1,255,255,255,1,149,149,149,1,145,145, + 145,1,143,143,143,1,172,172,172,1,224,224,224,1,133,133,133,1,255,255, + 255,1,181,181,181,1,177,177,177,1,165,165,165,1,166,166,166,1,160,160, + 160,1,202,202,202,1,133,133,133,1,202,202,202,1,167,167,167,1,190,190, + 190,1,208,208,208,3,5,179,6,1,34,205,21,1,29,184,27,1,14,173, + 19,1,208,208,208,10,24,24,24,1,124,124,124,15,255,255,255,1,0,0, + 0,1,208,208,208,1,124,124,124,1,232,232,232,14,255,255,255,1,0,0, + 0,1,255,255,255,1,253,67,9,1,235,55,5,1,212,62,17,1,219,123, + 89,1,255,255,255,1,252,244,241,1,200,82,50,1,204,113,85,1,166,86, + 66,1,106,154,140,1,209,62,29,1,214,106,72,1,245,222,212,1,255,254, + 254,1,218,116,79,1,232,56,5,1,253,67,9,1,219,219,219,1,240,240, + 240,1,224,224,224,5,255,255,255,10,252,252,252,1,190,190,190,1,208,208, + 208,3,5,179,6,1,34,205,21,1,56,212,44,1,53,200,49,1,20,173, + 25,1,0,169,9,1,208,208,208,9,124,124,124,1,232,232,232,14,255,255, + 255,1,122,122,255,1,155,186,186,1,124,124,124,1,232,232,232,14,255,255, + 255,1,0,0,255,1,255,255,255,1,245,61,7,1,226,49,3,1,220,129, + 95,1,217,122,86,1,216,111,78,1,217,114,83,1,30,236,229,1,78,179, + 174,1,122,126,123,1,40,224,219,1,213,65,41,1,252,247,244,1,255,255, + 255,1,227,149,123,1,210,43,4,1,226,49,3,1,245,61,7,1,223,223, + 223,1,245,245,245,1,211,235,235,1,229,239,239,1,240,240,240,1,238,238, + 238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,202,224, + 224,1,224,228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,225,225,225,1,190,190,190,1,208,208,208,3,5,179, + 6,1,34,205,21,1,56,212,44,1,77,219,66,1,84,217,76,1,29,177, + 33,1,0,169,9,1,208,208,208,7,4,4,255,1,124,124,124,1,232,232, + 232,1,123,123,123,1,79,79,79,1,116,116,116,1,232,232,232,2,186,186, + 186,1,96,96,96,1,232,232,232,1,230,230,230,1,95,95,95,1,74,74, + 74,1,152,152,152,1,232,232,232,1,255,255,255,1,255,0,38,1,208,208, + 208,1,124,124,124,1,232,232,232,1,146,146,146,1,49,49,49,1,232,232, + 232,2,193,193,193,1,21,21,21,1,232,232,232,1,69,69,69,1,79,79, + 79,3,186,186,186,1,232,232,232,1,255,255,255,1,224,224,224,1,255,255, + 255,1,235,57,5,1,214,64,19,1,211,89,49,1,213,102,66,1,220,118, + 89,1,214,84,55,1,129,119,117,1,186,111,115,1,214,205,206,1,183,78, + 82,1,92,164,159,1,207,119,91,1,218,123,91,1,211,78,41,1,214,88, + 50,1,214,76,32,1,233,57,5,1,122,202,204,1,96,214,217,1,55,215, + 222,1,50,210,216,1,152,222,223,1,238,238,238,1,237,237,237,1,235,235, + 235,1,234,234,234,1,87,208,211,1,53,213,220,1,49,205,210,1,172,218, + 219,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,222,222, + 222,1,190,190,190,1,208,208,208,3,5,179,6,1,34,205,21,1,56,212, + 44,1,77,219,66,1,98,226,88,1,113,230,105,1,46,184,49,1,19,178, + 26,1,208,208,208,6,114,114,255,1,124,124,124,1,198,198,198,1,85,85, + 85,1,232,232,232,1,83,83,83,1,203,203,203,1,172,172,172,1,83,83, + 83,1,80,80,80,1,232,232,232,1,153,153,153,1,130,130,130,1,232,232, + 232,1,55,55,55,1,231,231,231,1,255,255,255,2,0,0,104,1,124,124, + 124,1,232,232,232,1,137,137,137,1,44,44,44,1,188,188,188,1,232,232, + 232,1,116,116,116,1,36,36,36,1,232,232,232,1,57,57,57,1,232,232, + 232,5,255,255,255,1,224,224,224,1,194,59,0,1,214,116,75,1,248,232, + 225,1,255,255,255,3,209,109,85,1,74,184,182,1,193,115,123,1,214,178, + 182,1,167,99,107,1,35,230,226,1,187,83,60,1,234,180,161,1,254,251, + 250,1,252,244,241,1,227,159,132,1,216,87,39,1,69,195,199,1,61,213, + 219,1,178,243,255,1,132,241,255,1,62,209,213,1,238,238,238,1,224,224, + 236,1,235,235,235,1,206,228,228,1,64,215,223,1,176,243,255,1,118,241, + 255,1,71,207,209,1,226,226,226,1,211,211,224,1,223,223,223,1,221,221, + 221,1,222,222,222,1,190,190,190,1,208,208,208,3,5,179,6,1,34,205, + 21,1,56,212,44,1,77,219,66,1,98,226,88,1,119,233,110,1,139,240, + 132,1,76,198,77,1,33,180,39,1,208,208,208,5,151,151,255,1,124,124, + 124,1,161,161,161,1,130,130,130,1,232,232,232,1,126,126,126,1,164,164, + 164,1,227,227,227,1,225,225,225,1,80,80,80,1,232,232,232,1,114,114, + 114,1,177,177,177,1,232,232,232,1,79,79,79,1,211,211,211,1,255,255, + 255,1,208,208,208,1,0,0,255,1,124,124,124,1,232,232,232,1,137,137, + 137,1,123,123,123,1,110,110,110,1,232,232,232,1,96,96,96,1,57,57, + 57,1,232,232,232,1,54,54,54,1,116,116,116,3,222,222,222,1,232,232, + 232,1,255,255,255,1,103,103,103,1,255,255,255,1,222,68,19,1,216,103, + 65,1,232,172,150,1,252,246,243,1,222,133,106,1,188,69,50,1,37,227, + 223,1,157,78,90,1,88,163,169,1,156,81,92,1,215,91,68,1,221,116, + 91,1,213,94,59,1,217,98,69,1,210,67,29,1,212,42,0,1,234,54, + 5,1,56,195,202,1,63,216,224,1,199,243,255,1,144,242,255,1,52,209, + 213,1,238,238,238,1,52,52,223,1,229,229,234,1,172,222,222,1,76,223, + 233,1,208,244,255,1,134,241,255,1,56,206,209,1,226,226,226,1,52,52, + 221,1,208,208,223,1,221,221,221,1,217,217,222,1,190,190,190,1,208,208, + 208,3,5,179,6,1,34,205,21,1,56,212,44,1,77,219,66,1,98,226, + 88,1,119,233,110,1,139,240,132,1,74,193,75,1,20,109,23,1,0,0, + 0,1,208,208,208,5,124,124,124,1,177,177,177,1,128,128,128,1,232,232, + 232,1,123,123,123,1,168,168,168,1,232,232,232,1,225,225,225,1,80,80, + 80,1,232,232,232,1,129,129,129,1,176,176,176,1,232,232,232,1,76,76, + 76,1,216,216,216,1,255,255,255,1,136,136,136,1,124,124,124,2,232,232, + 232,1,137,137,137,1,159,159,159,1,73,73,73,1,187,187,187,1,140,140, + 140,1,57,57,57,1,232,232,232,1,56,56,56,1,196,196,196,3,229,229, + 229,1,232,232,232,1,255,255,255,1,0,0,255,1,255,255,255,1,235,55, + 5,1,215,42,0,1,211,38,4,1,210,80,42,1,225,146,122,1,215,105, + 73,1,219,101,81,1,211,92,71,1,64,194,194,1,149,104,99,1,246,225, + 217,1,255,255,255,1,246,224,215,1,216,103,70,1,211,41,7,1,215,42, + 0,1,235,55,5,1,56,195,201,1,60,206,210,1,81,230,243,1,56,222, + 233,1,107,214,215,1,172,172,233,1,12,12,236,1,131,131,230,1,232,233, + 233,1,48,202,206,1,95,235,249,1,54,222,232,1,116,210,211,1,184,184, + 224,1,15,15,234,1,102,102,223,1,221,221,221,1,185,185,222,1,190,190, + 190,1,208,208,208,3,5,179,6,1,34,205,21,1,56,212,44,1,77,219, + 66,1,98,226,88,1,113,230,105,1,43,174,46,1,6,55,8,1,0,0, + 0,2,208,208,208,4,0,0,0,1,124,124,124,1,227,227,227,1,86,86, + 86,1,232,232,232,1,78,78,78,1,207,207,207,1,232,232,232,1,225,225, + 225,1,80,80,80,1,232,232,232,1,187,187,187,1,126,126,126,1,228,228, + 228,1,57,57,57,1,232,232,232,1,255,255,255,3,124,124,124,1,232,232, + 232,1,137,137,137,1,159,159,159,1,119,119,119,1,70,70,70,1,216,216, + 216,1,57,57,57,1,232,232,232,1,57,57,57,1,232,232,232,5,255,255, + 255,1,208,208,208,1,255,255,255,1,239,57,6,1,219,44,1,1,211,63, + 25,1,238,191,175,1,240,199,186,1,218,123,94,1,255,255,255,1,239,199, + 186,1,210,50,31,1,220,118,93,1,214,106,74,1,252,245,242,1,255,255, + 255,1,255,254,254,1,223,136,105,1,217,50,6,1,239,57,6,1,67,189, + 193,1,234,228,228,1,130,205,206,1,166,211,212,1,236,225,225,1,65,65, + 229,1,4,4,255,1,51,51,230,1,233,230,230,1,211,214,214,1,101,195, + 197,1,154,203,203,1,224,213,213,1,70,70,225,1,4,4,254,1,41,41, + 229,1,218,218,221,1,107,107,223,1,190,190,190,1,208,208,208,3,5,179, + 6,1,34,205,21,1,56,212,44,1,77,219,66,1,84,217,76,1,26,157, + 29,1,0,21,1,1,0,0,0,2,208,208,208,5,255,255,255,1,124,124, + 124,1,232,232,232,1,149,149,149,1,90,90,90,1,144,144,144,1,232,232, + 232,2,227,227,227,1,118,118,118,1,232,232,232,1,230,230,230,1,123,123, + 123,1,89,89,89,1,174,174,174,1,232,232,232,1,255,255,255,2,0,0, + 0,1,124,124,124,1,232,232,232,1,161,161,161,1,177,177,177,1,199,199, + 199,1,101,101,101,1,232,232,232,1,101,101,101,1,232,232,232,1,96,96, + 96,1,79,79,79,3,166,166,166,1,232,232,232,1,255,255,255,1,136,136, + 136,1,255,255,255,1,245,61,7,1,219,72,27,1,234,179,158,1,255,255, + 255,1,216,112,78,1,249,231,225,1,255,255,255,1,226,147,124,1,210,64, + 34,1,252,244,241,1,233,171,153,1,213,95,60,1,221,124,97,1,225,142, + 115,1,228,159,134,1,212,97,53,1,245,61,7,1,200,206,206,1,212,22, + 30,1,222,27,40,2,173,26,58,1,24,24,237,1,4,4,255,1,14,14, + 243,1,172,127,172,1,211,21,29,1,220,25,38,2,183,27,46,1,27,27, + 233,1,4,4,255,1,7,7,246,1,136,136,221,1,60,60,227,1,190,190, + 190,1,208,208,208,3,5,179,6,1,34,205,21,1,56,212,44,1,54,199, + 48,1,16,137,20,1,0,4,0,1,0,0,0,1,208,208,208,7,255,255, + 255,1,124,124,124,1,232,232,232,14,255,255,255,2,208,208,208,1,124,124, + 124,1,232,232,232,14,255,255,255,1,0,0,0,1,255,255,255,1,253,67, + 9,1,213,106,62,1,224,140,109,1,218,108,75,1,216,109,74,1,255,255, + 255,1,233,174,156,1,212,93,59,1,216,102,73,1,233,174,154,1,255,255, + 255,1,220,115,86,1,213,32,5,1,212,36,2,1,218,43,1,1,230,56, + 5,1,253,67,9,1,198,67,73,1,237,1,24,1,255,0,32,2,121,18, + 120,1,56,56,230,1,60,60,231,1,59,59,230,1,125,80,170,1,237,1, + 24,1,255,0,32,2,139,20,103,1,51,51,227,1,57,57,228,1,56,56, + 227,1,87,87,222,1,27,27,239,1,190,190,190,1,208,208,208,3,5,179, + 6,1,34,205,21,1,28,181,26,1,9,107,12,1,0,0,0,2,208,208, + 208,8,255,255,255,1,124,124,124,1,255,255,255,15,208,208,208,1,255,255, + 255,1,124,124,124,1,232,232,232,14,255,255,255,4,232,60,6,1,230,51, + 4,1,214,43,0,1,224,147,118,1,219,121,89,1,211,47,18,1,224,137, + 111,1,221,125,97,1,217,104,74,1,255,255,255,1,223,136,107,1,212,36, + 2,1,215,42,0,1,230,51,4,1,246,62,8,1,255,255,255,1,207,8, + 24,1,237,1,24,1,255,0,32,2,216,32,41,1,238,238,238,1,237,237, + 237,1,235,235,235,1,221,176,175,1,237,1,24,1,255,0,32,2,215,31, + 40,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,41,41, + 233,1,190,190,190,1,208,208,208,3,4,178,6,1,12,174,13,1,3,67, + 6,1,0,0,0,2,208,208,208,9,255,255,255,1,208,208,208,16,138,138, + 138,1,255,255,255,1,124,124,124,1,232,232,232,14,255,255,255,5,244,61, + 7,1,226,52,4,1,213,80,37,1,212,38,0,1,212,36,2,1,217,117, + 82,1,211,70,34,1,211,50,14,1,239,199,184,1,225,148,120,1,218,43, + 1,1,230,51,4,1,244,61,7,1,255,255,255,2,216,0,21,1,208,26, + 32,1,217,32,42,2,198,29,30,1,238,238,238,1,237,237,237,1,235,235, + 235,1,221,176,175,1,207,24,30,1,215,31,40,2,197,28,28,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,126,126,225,1,190,190, + 190,1,208,208,208,3,2,172,8,1,0,51,3,1,0,0,0,2,208,208, + 208,10,245,225,226,1,208,208,208,16,0,0,255,1,208,208,208,1,124,124, + 124,1,232,232,232,14,255,255,255,1,208,208,208,1,255,255,255,4,246,62, + 8,1,235,55,5,1,226,49,3,1,219,44,1,1,214,43,0,1,213,41, + 0,1,215,42,0,1,217,107,68,1,222,132,98,1,235,55,5,1,246,62, + 8,1,255,255,255,3,210,6,23,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234, + 234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,222,222,222,1,190,190, + 190,1,208,208,208,4,0,0,0,2,208,208,208,28,255,0,255,1,136,136, + 136,1,124,124,124,1,255,255,255,21,253,67,9,1,245,61,7,1,239,57, + 6,1,235,55,5,1,234,54,5,1,235,55,5,1,229,64,13,1,224,78, + 26,1,253,67,9,1,255,255,255,4,192,40,45,1,217,47,56,1,219,49, + 58,1,211,48,53,1,210,93,94,1,237,237,237,2,235,235,235,1,227,203, + 202,1,216,122,124,1,210,42,48,1,216,47,55,2,203,45,47,1,214,150, + 150,1,225,225,225,1,223,223,223,1,222,222,222,1,190,190,190,1,208,208, + 208,2,129,194,131,1,14,143,19,1,0,42,2,1,0,4,0,1,12,12, + 12,1,128,128,128,1,208,208,208,9,121,121,121,1,255,255,255,16,201,201, + 201,1,124,124,124,1,255,255,255,16,59,239,255,1,208,208,208,1,255,255, + 255,16,224,224,224,1,208,208,208,18,255,255,255,9,192,192,192,1,255,255, + 255,8,208,208,208,18,0,0,0,1,255,255,255,15,0,0,0,1,208,208, + 208,18,224,224,224,1,208,208,208,57,0,0,255,1,208,208,208,13,1,1, + 1,1,28,28,28,1,208,208,208,1,136,136,136,8,135,142,142,1,134,134, + 134,1,0,0,0,1,208,208,208,4,124,124,124,1,208,208,208,17,217,217, + 217,1,208,208,208,6,0,0,0,6,208,208,208,5,255,255,255,1,208,208, + 208,17,128,128,128,1,224,224,224,1,208,208,208,2,0,0,255,2,208,208, + 208,1,0,0,0,8,208,208,208,3,217,217,217,2,208,208,208,1,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,201,252, + 254,1,206,253,254,1,211,254,254,1,160,175,176,1,158,193,197,1,99,99, + 99,1,0,0,0,1,208,208,208,3,0,0,255,1,208,208,208,8,0,0, + 182,2,208,208,208,8,255,255,255,1,208,208,208,4,0,0,0,8,208,208, + 208,4,233,164,145,1,208,208,208,18,0,0,0,1,0,0,255,5,0,0, + 0,8,208,208,208,3,53,53,53,1,62,62,62,1,208,208,208,1,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,201,252, + 254,1,206,253,254,1,211,254,254,1,167,182,183,1,224,252,255,1,156,193, + 197,1,101,101,101,1,0,0,0,1,208,208,208,9,5,5,198,1,11,11, + 206,1,21,21,213,1,26,26,213,1,22,22,206,1,13,13,198,1,208,208, + 208,6,255,255,255,1,208,208,208,4,0,0,0,2,24,24,155,1,52,52, + 255,1,63,63,254,1,45,45,155,1,0,0,0,2,208,208,208,4,252,243, + 240,1,208,208,208,1,124,124,124,15,255,255,255,1,208,208,208,1,78,78, + 78,1,0,0,255,1,208,208,208,1,0,0,255,2,208,208,208,4,0,0, + 0,3,208,208,208,1,0,0,0,1,208,208,208,3,0,0,0,2,208,208, + 208,1,136,136,136,1,181,248,254,1,139,186,189,1,151,198,201,1,151,194, + 196,1,172,215,217,1,178,218,219,1,157,189,189,1,154,181,183,1,240,253, + 255,1,221,252,255,1,155,194,197,1,103,103,103,1,0,0,0,1,208,208, + 208,1,167,205,206,1,208,208,208,5,3,3,200,1,21,21,233,1,41,41, + 255,1,52,52,255,1,64,64,255,1,75,75,255,1,58,58,228,1,19,19, + 187,1,208,208,208,5,243,195,182,1,208,208,208,3,0,0,0,1,0,0, + 1,1,6,6,56,1,41,41,255,1,52,52,255,1,64,64,255,1,75,75, + 255,1,25,25,72,1,0,0,1,1,0,0,0,1,208,208,208,3,224,224, + 224,1,208,208,208,1,124,124,124,1,232,232,232,14,255,255,255,1,208,208, + 208,1,217,217,217,1,0,0,255,1,208,208,208,1,0,0,255,2,208,208, + 208,4,0,0,0,5,208,208,208,3,0,0,255,1,208,208,208,2,136,136, + 136,1,181,248,254,1,124,166,169,1,117,153,155,1,116,149,150,1,141,177, + 178,1,139,171,171,1,149,179,179,1,141,180,183,1,188,248,255,1,243,253, + 255,1,219,251,255,1,155,196,199,1,104,106,106,1,0,0,0,1,208,208, + 208,5,3,3,198,1,13,13,233,1,30,30,255,1,41,41,255,1,52,52, + 255,1,64,64,255,1,75,75,255,1,86,86,255,1,66,66,226,1,13,13, + 142,1,208,208,208,3,218,218,218,1,128,76,240,1,208,208,208,3,4,4, + 234,1,14,14,211,1,25,25,222,1,41,41,255,1,52,52,255,1,64,64, + 255,1,75,75,255,1,31,31,92,1,4,4,11,1,57,57,131,1,208,208, + 208,5,124,124,124,1,232,232,232,1,97,97,97,1,98,98,98,1,97,97, + 97,1,231,231,231,1,156,156,156,1,93,93,93,1,88,88,88,1,186,186, + 186,1,217,217,217,1,86,86,86,1,97,97,97,1,124,124,124,1,232,232, + 232,1,255,255,255,1,128,128,128,1,208,208,208,1,0,0,255,1,208,208, + 208,7,0,0,0,5,208,208,208,3,201,246,246,1,178,243,246,1,208,208, + 208,1,136,136,136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251, + 254,1,201,252,254,1,206,253,254,1,211,254,254,1,147,185,187,1,136,179, + 183,1,144,180,183,1,152,181,183,1,139,175,179,1,133,140,140,1,0,0, + 0,1,0,0,253,1,208,208,208,4,3,3,206,1,18,18,255,1,30,30, + 255,1,41,41,255,1,52,52,255,1,64,64,255,1,75,75,255,1,86,86, + 255,1,98,98,255,1,27,27,180,1,0,0,0,1,208,208,208,2,149,35, + 65,1,0,252,248,1,208,208,208,3,6,6,255,1,17,17,255,1,29,29, + 255,1,41,41,255,1,52,52,255,1,64,64,255,1,54,54,182,1,2,2, + 5,1,36,36,94,1,87,87,204,1,0,0,0,1,208,208,208,2,9,164, + 0,1,208,208,208,1,124,124,124,1,202,202,202,1,146,146,146,1,232,232, + 232,1,116,116,116,1,180,180,180,1,117,117,117,1,230,230,230,1,209,209, + 209,1,87,87,87,1,170,170,170,1,177,177,177,1,232,232,232,1,74,74, + 74,1,224,224,224,1,255,255,255,1,208,208,208,1,181,248,254,1,0,0, + 255,1,208,208,208,4,0,0,0,6,208,208,208,2,0,0,255,3,208,208, + 208,1,6,6,252,1,208,208,208,1,136,136,136,1,181,248,254,1,186,249, + 254,1,191,250,254,1,196,251,254,1,181,226,228,1,167,205,206,1,155,186, + 186,1,169,207,207,1,148,202,204,1,127,195,200,1,137,245,254,1,114,242, + 254,1,136,136,136,1,0,0,0,1,224,224,224,1,238,238,238,1,208,208, + 208,2,0,0,182,1,2,2,213,1,18,18,255,1,30,30,255,1,41,41, + 255,1,52,52,255,1,64,64,255,1,75,75,255,1,86,86,255,1,98,98, + 255,1,41,41,196,1,0,0,13,1,208,208,208,2,0,0,0,1,13,182, + 0,1,208,208,208,3,6,6,255,1,17,17,255,1,29,29,255,1,41,41, + 255,1,52,52,255,1,46,46,184,1,3,3,9,1,20,20,59,1,96,96, + 247,1,104,104,240,1,0,0,0,1,208,208,208,2,128,128,128,1,224,112, + 0,1,124,124,124,1,232,232,232,2,207,207,207,1,72,72,72,1,222,222, + 222,1,232,232,232,2,103,103,103,1,166,166,166,1,232,232,232,2,180,180, + 180,1,88,88,88,1,232,232,232,1,255,255,255,1,0,0,1,1,118,211, + 219,1,0,0,255,1,208,208,208,4,0,0,0,6,208,208,208,4,0,0, + 255,1,189,189,189,1,208,208,208,2,136,136,136,1,181,248,254,1,186,249, + 254,1,191,250,254,1,196,251,254,1,168,210,212,1,145,179,179,1,151,181, + 181,1,159,195,195,1,131,178,180,1,107,165,169,1,137,245,254,1,114,242, + 254,1,136,136,136,1,0,0,0,1,224,224,224,1,255,255,255,1,208,208, + 208,2,0,0,182,1,2,2,213,1,18,18,255,1,30,30,255,1,41,41, + 255,1,52,52,255,1,64,64,255,1,75,75,255,1,86,86,255,1,98,98, + 255,1,41,41,196,1,0,0,10,1,208,208,208,2,0,0,0,1,208,208, + 208,4,6,6,255,1,17,17,255,1,29,29,255,1,41,41,255,1,43,43, + 211,1,2,2,6,1,14,14,49,1,81,81,238,1,99,99,255,1,104,104, + 240,1,0,0,0,1,208,208,208,2,255,255,255,1,0,0,0,1,124,124, + 124,1,232,232,232,2,81,81,81,1,209,209,209,1,232,232,232,2,159,159, + 159,1,131,131,131,1,232,232,232,2,231,231,231,1,66,66,66,1,226,226, + 226,1,232,232,232,1,255,255,255,1,0,0,0,1,15,15,86,1,0,0, + 255,1,208,208,208,14,0,0,255,1,163,163,163,1,3,3,3,1,208,208, + 208,1,136,136,136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251, + 254,1,201,252,254,1,176,216,217,1,206,248,248,1,201,246,246,1,178,243, + 246,1,159,245,251,1,134,240,249,1,114,242,254,1,136,136,136,1,0,0, + 0,1,255,255,255,1,0,0,0,1,208,208,208,3,3,3,206,1,18,18, + 255,1,30,30,255,1,41,41,255,1,52,52,255,1,64,64,255,1,75,75, + 255,1,86,86,255,1,98,98,255,1,26,26,179,1,0,0,0,1,208,208, + 208,2,255,255,255,1,79,79,79,1,208,208,208,3,6,6,255,1,17,17, + 255,1,29,29,255,1,41,41,255,1,19,19,95,1,3,3,12,1,69,69, + 233,1,87,87,255,1,99,99,255,1,87,87,204,1,0,0,0,1,208,208, + 208,2,71,71,71,1,255,255,255,1,124,124,124,1,232,232,232,2,171,171, + 171,1,232,232,232,3,192,192,192,1,212,212,212,1,232,232,232,2,227,227, + 227,1,177,177,177,1,232,232,232,2,255,255,255,1,0,0,0,1,224,224, + 224,1,0,0,255,1,208,208,208,14,0,0,255,1,208,208,208,3,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,154,194, + 195,1,141,173,173,1,131,157,157,1,122,149,149,1,131,179,181,1,91,140, + 143,1,84,151,156,1,114,242,254,1,136,136,136,1,0,0,0,2,255,255, + 255,1,208,208,208,3,3,3,198,1,12,12,228,1,30,30,255,1,41,41, + 255,1,52,52,255,1,64,64,255,1,75,75,255,1,86,86,255,1,66,66, + 226,1,10,10,108,1,0,0,0,1,208,208,208,2,0,0,0,1,255,255, + 255,1,208,208,208,3,4,4,255,1,17,17,254,1,29,29,255,1,41,41, + 255,1,11,11,54,1,15,15,61,1,75,75,255,1,87,87,255,1,98,98, + 254,1,38,38,89,1,0,0,0,1,208,208,208,2,206,51,17,1,255,255, + 255,1,124,124,124,1,232,232,232,2,96,96,96,1,232,232,232,3,145,145, + 145,1,184,184,184,1,232,232,232,2,215,215,215,1,114,114,114,1,232,232, + 232,2,255,255,255,2,224,224,224,1,0,0,255,1,208,208,208,2,0,0, + 0,8,208,208,208,4,0,0,255,1,208,208,208,3,136,136,136,1,181,248, + 254,1,186,249,254,1,188,246,250,1,196,251,254,1,188,236,238,1,175,215, + 216,1,141,169,169,1,179,219,219,1,143,195,197,1,128,196,201,1,118,211, + 219,1,114,242,254,1,136,136,136,1,0,0,0,1,0,0,255,1,0,0, + 0,1,208,208,208,4,3,3,187,1,20,20,226,1,41,41,255,1,52,52, + 255,1,64,64,255,1,75,75,255,1,57,57,226,1,15,15,154,1,0,0, + 0,2,208,208,208,2,255,255,255,2,208,208,208,4,15,15,223,1,29,29, + 254,1,41,41,255,1,38,38,188,1,50,50,199,1,75,75,255,1,86,86, + 254,1,62,62,158,1,0,0,0,2,208,208,208,2,207,53,11,1,0,0, + 0,1,124,124,124,1,232,232,232,14,255,255,255,1,0,0,0,1,208,208, + 208,1,0,0,255,2,208,208,208,1,0,0,0,8,208,208,208,1,0,0, + 255,2,208,208,208,1,0,0,255,1,208,208,208,3,136,136,136,1,181,248, + 254,1,146,195,199,1,144,188,191,1,147,188,190,1,117,146,147,1,146,180, + 180,1,204,245,245,1,207,254,254,1,184,251,254,1,161,248,254,1,137,245, + 254,1,114,242,254,1,136,136,136,1,0,0,0,1,255,255,255,1,0,0, + 0,1,208,208,208,5,4,4,142,1,10,10,180,1,19,19,196,1,23,23, + 196,1,19,19,179,1,7,7,108,1,0,0,0,2,208,208,208,3,140,140, + 140,1,213,80,48,1,208,208,208,5,16,16,136,1,33,33,204,1,34,34, + 167,1,43,43,172,1,59,59,204,1,31,31,89,1,0,0,0,2,208,208, + 208,3,128,128,128,1,255,255,255,1,124,124,124,1,255,255,255,15,0,0, + 0,1,255,255,255,1,208,208,208,10,0,0,0,1,208,208,208,1,0,0, + 255,2,208,208,208,1,0,0,255,1,255,255,255,2,208,208,208,1,136,136, + 136,1,181,248,254,1,122,163,166,1,137,179,182,1,143,183,185,1,136,170, + 171,1,145,179,179,1,205,247,247,1,207,254,254,1,184,251,254,1,161,248, + 254,1,137,245,254,1,114,242,254,1,136,136,136,1,0,0,0,1,255,255, + 255,1,140,140,140,1,208,208,208,6,0,0,0,1,0,0,13,1,0,0, + 10,1,0,0,0,3,208,208,208,4,245,245,245,1,128,76,240,1,208,208, + 208,6,0,0,0,6,208,208,208,5,255,255,255,1,208,208,208,16,140,140, + 140,1,255,255,255,1,208,208,208,3,0,0,0,8,0,0,255,5,208,208, + 208,3,136,136,136,14,0,0,0,1,208,208,208,1,255,255,255,1,208,208, + 208,16,255,255,255,2,208,208,208,7,0,0,0,2,208,208,208,7,255,255, + 255,1,0,0,0,1,208,208,208,16,255,255,255,1,255,30,64,1,208,208, + 208,3,0,0,0,8,208,208,208,1,0,0,255,2,208,208,208,5,0,0, + 0,15,136,136,136,1,198,198,198,1,208,208,208,16,255,255,255,2,208,208, + 208,16,255,255,255,1,215,215,215,1,208,208,208,16,228,228,228,1,208,208, + 208,14,0,0,255,1,208,208,208,4,255,255,255,12,0,0,0,3,255,255, + 255,1,208,208,208,1,255,255,255,12,0,0,0,1,255,255,255,5,224,224, + 224,1,255,255,255,16,208,208,208,1,187,187,187,1,176,176,176,1,219,219, + 219,1,162,162,162,1,186,186,186,1,227,227,227,1,140,140,140,1,227,227, + 227,1,158,158,158,3,141,141,141,1,140,140,140,1,255,255,255,5,124,124, + 124,1,255,255,255,16,206,253,254,1,173,173,173,1,222,68,91,1,233,27, + 58,2,222,67,90,1,190,190,190,13,255,255,255,10,194,194,194,1,58,58, + 58,1,59,59,59,1,198,198,198,1,255,255,255,3,224,124,97,1,208,208, + 208,1,255,255,255,16,208,208,208,2,255,255,255,16,0,0,0,1,208,208, + 208,1,255,255,255,17,190,190,190,1,208,208,208,1,255,30,64,3,208,208, + 208,13,0,0,0,1,208,208,208,16,128,76,240,1,208,208,208,17,149,149, + 149,1,0,0,255,1,124,124,124,15,255,255,255,1,186,249,254,1,188,248, + 255,1,208,208,208,4,13,238,255,1,208,208,208,11,255,255,255,1,190,190, + 190,1,208,208,208,1,255,30,64,4,208,208,208,12,205,45,4,1,208,208, + 208,16,248,252,248,1,124,124,124,1,208,208,208,1,136,136,136,8,135,142, + 142,1,134,134,134,1,0,0,0,1,208,208,208,4,136,136,136,1,0,0, + 0,1,124,124,124,1,232,232,232,14,255,255,255,1,103,103,103,1,255,255, + 255,1,208,208,208,2,51,239,255,1,71,239,255,1,66,239,255,1,39,238, + 255,1,13,238,255,1,208,208,208,9,39,238,255,1,190,190,190,1,208,208, + 208,3,255,30,64,4,208,208,208,10,248,252,248,1,208,208,208,17,74,74, + 74,1,208,208,208,1,136,136,136,1,181,248,254,1,186,249,254,1,191,250, + 254,1,196,251,254,1,201,252,254,1,206,253,254,1,211,254,254,1,160,175, + 176,1,158,193,197,1,99,99,99,1,0,0,0,1,208,208,208,3,122,188, + 192,1,141,177,178,1,124,124,124,1,232,232,232,14,255,255,255,1,0,0, + 255,1,243,243,243,1,208,208,208,1,59,239,255,1,111,241,255,1,142,241, + 255,1,135,241,255,1,95,240,255,1,40,238,255,1,10,178,191,1,208,208, + 208,9,190,190,190,1,208,208,208,4,255,30,64,5,208,208,208,9,124,124, + 124,15,255,255,255,1,217,217,217,1,138,180,183,1,208,208,208,1,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,201,252, + 254,1,206,253,254,1,211,254,254,1,167,182,183,1,224,252,255,1,156,193, + 197,1,101,101,101,1,0,0,0,1,208,208,208,2,28,28,28,1,208,208, + 208,1,124,124,124,1,232,232,232,14,255,255,255,1,224,224,224,1,208,208, + 208,2,88,240,255,1,154,242,255,1,208,244,255,1,193,243,255,1,132,241, + 255,1,66,239,255,1,12,214,229,1,0,0,0,1,208,208,208,7,255,0, + 38,1,184,191,193,1,208,208,208,6,255,30,64,4,208,208,208,6,200,208, + 211,1,208,208,208,1,124,124,124,1,232,232,232,14,255,255,255,1,60,60, + 60,1,136,136,136,1,208,208,208,1,136,136,136,1,181,248,254,1,186,249, + 254,1,191,250,254,1,196,251,254,1,201,252,254,1,206,253,254,1,211,254, + 254,1,154,181,183,1,240,253,255,1,221,252,255,1,155,194,197,1,103,103, + 103,1,0,0,0,1,208,208,208,1,255,255,255,1,0,0,255,1,124,124, + 124,1,232,232,232,14,255,255,255,1,98,98,241,1,128,128,255,1,208,208, + 208,1,88,240,255,1,154,242,255,1,208,244,255,1,193,243,255,1,132,241, + 255,1,66,239,255,1,13,230,247,1,0,0,0,1,208,208,208,2,8,8, + 255,1,208,208,208,4,56,56,56,1,131,200,229,1,138,220,255,1,142,222, + 255,1,208,208,208,6,255,30,64,4,208,208,208,2,118,215,255,1,138,220, + 255,1,127,214,250,1,50,50,50,1,124,124,124,1,232,232,232,1,123,123, + 123,1,79,79,79,1,116,116,116,1,232,232,232,2,186,186,186,1,96,96, + 96,1,232,232,232,1,230,230,230,1,95,95,95,1,74,74,74,1,152,152, + 152,1,232,232,232,1,255,255,255,2,178,178,178,1,208,208,208,1,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,201,252, + 254,1,206,253,254,1,211,254,254,1,141,180,183,1,188,248,255,1,243,253, + 255,1,219,251,255,1,155,196,199,1,104,106,106,1,0,0,0,1,4,4, + 255,1,224,224,224,1,124,124,124,1,232,232,232,7,189,189,189,1,142,142, + 142,1,224,224,224,1,232,232,232,4,255,255,255,1,217,217,217,1,161,161, + 255,1,208,208,208,1,59,239,255,1,111,241,255,1,142,241,255,1,135,241, + 255,1,95,240,255,1,40,238,255,1,11,192,206,1,0,0,0,1,208,208, + 208,1,0,0,255,1,4,4,255,1,0,0,143,1,208,208,208,3,217,217, + 217,1,154,209,233,1,180,233,255,1,144,222,255,1,143,222,255,1,208,208, + 208,6,255,30,64,3,208,208,208,1,139,221,255,1,155,225,255,1,180,233, + 255,1,147,223,255,1,184,184,184,1,124,124,124,1,198,198,198,1,85,85, + 85,1,232,232,232,1,83,83,83,1,203,203,203,1,172,172,172,1,83,83, + 83,1,80,80,80,1,232,232,232,1,153,153,153,1,130,130,130,1,232,232, + 232,1,55,55,55,1,231,231,231,1,255,255,255,2,255,0,32,1,208,208, + 208,1,136,136,136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251, + 254,1,201,252,254,1,206,253,254,1,211,254,254,1,147,185,187,1,136,179, + 183,1,144,180,183,1,152,181,183,1,139,175,179,1,133,140,140,1,0,0, + 0,1,255,0,38,1,224,224,224,1,124,124,124,1,232,232,232,7,210,210, + 210,1,93,93,93,1,26,26,26,1,105,105,105,1,201,201,201,1,232,232, + 232,2,255,255,255,3,208,208,208,1,13,238,255,1,49,229,245,1,71,239, + 255,1,66,239,255,1,39,238,255,1,12,225,241,1,3,51,54,1,0,0, + 0,1,208,208,208,1,3,3,255,1,4,4,255,1,3,3,187,1,0,0, + 0,1,208,208,208,2,206,253,254,1,186,219,233,1,221,245,255,1,146,223, + 255,1,145,222,255,1,255,0,38,1,208,208,208,1,255,0,38,1,208,208, + 208,1,255,0,38,1,208,208,208,1,255,0,38,1,208,208,208,1,255,0, + 38,1,208,208,208,1,182,233,255,1,198,238,255,1,221,245,255,1,181,233, + 255,1,255,255,255,1,124,124,124,1,161,161,161,1,130,130,130,1,232,232, + 232,1,126,126,126,1,164,164,164,1,227,227,227,1,225,225,225,1,80,80, + 80,1,232,232,232,1,114,114,114,1,177,177,177,1,232,232,232,1,79,79, + 79,1,211,211,211,1,255,255,255,1,174,117,88,1,208,208,208,2,136,136, + 136,1,181,248,254,1,168,226,230,1,133,174,176,1,190,243,246,1,201,252, + 254,1,206,253,254,1,168,202,202,1,207,254,254,1,184,251,254,1,122,188, + 192,1,111,199,206,1,114,242,254,1,136,136,136,1,0,0,0,1,159,159, + 255,1,146,146,146,1,124,124,124,1,231,231,231,1,133,133,133,1,46,46, + 46,1,83,83,83,1,164,164,164,1,180,180,180,1,140,140,140,1,232,232, + 232,2,219,219,219,1,136,136,136,1,43,43,43,1,68,68,68,1,226,226, + 226,1,255,255,255,1,0,0,0,1,208,208,208,3,6,116,124,1,8,148, + 158,1,10,175,187,1,8,142,152,1,1,26,28,1,0,0,0,2,7,7, + 255,1,4,4,255,2,4,4,252,1,2,2,85,1,208,208,208,2,255,255, + 255,1,212,226,232,1,248,251,253,1,149,223,255,1,148,223,255,1,255,0, + 38,1,163,228,255,1,255,0,38,1,163,228,255,1,255,0,38,1,163,228, + 255,1,255,0,38,1,163,228,255,1,255,0,38,1,163,228,255,1,225,246, + 255,1,241,250,255,1,248,251,253,1,217,243,254,1,203,34,3,1,124,124, + 124,1,177,177,177,1,128,128,128,1,232,232,232,1,123,123,123,1,168,168, + 168,1,232,232,232,1,225,225,225,1,80,80,80,1,232,232,232,1,129,129, + 129,1,176,176,176,1,232,232,232,1,76,76,76,1,216,216,216,1,255,255, + 255,1,224,224,224,1,208,208,208,2,136,136,136,1,179,245,251,1,66,88, + 90,1,138,180,183,1,85,108,110,1,201,252,254,1,112,138,138,1,52,63, + 63,1,207,254,254,1,122,166,168,1,94,145,148,1,58,104,108,1,94,199, + 209,1,136,136,136,1,0,0,0,1,208,208,208,2,124,124,124,1,226,226, + 226,1,105,105,105,1,174,174,174,1,119,119,119,1,43,43,43,1,36,36, + 36,1,160,160,160,1,232,232,232,2,223,223,223,1,141,141,141,1,45,45, + 45,1,67,67,67,1,226,226,226,1,255,255,255,1,146,195,199,1,136,136, + 136,1,208,208,208,3,0,0,0,5,208,208,208,1,5,5,255,1,4,4, + 255,3,4,4,199,1,0,0,0,1,208,208,208,1,255,255,255,1,219,225, + 229,1,215,234,243,1,136,214,247,1,143,219,251,1,255,0,38,1,255,255, + 255,1,255,0,38,1,255,255,255,1,255,0,38,1,255,255,255,1,255,0, + 38,1,255,255,255,1,255,0,38,1,255,255,255,1,244,249,251,1,231,243, + 248,1,215,234,243,1,238,248,253,1,218,100,75,1,124,124,124,1,227,227, + 227,1,86,86,86,1,232,232,232,1,78,78,78,1,207,207,207,1,232,232, + 232,1,225,225,225,1,80,80,80,1,232,232,232,1,187,187,187,1,126,126, + 126,1,228,228,228,1,57,57,57,1,232,232,232,1,255,255,255,1,96,232, + 72,1,208,208,208,2,136,136,136,1,156,214,219,1,91,122,125,1,191,250, + 254,1,68,88,89,1,201,252,254,1,168,206,207,1,85,103,103,1,207,254, + 254,1,75,102,104,1,153,235,241,1,107,191,198,1,65,139,145,1,136,136, + 136,1,0,0,0,2,0,0,255,1,124,124,124,1,232,232,232,7,214,214, + 214,1,105,105,105,1,29,29,29,1,102,102,102,1,199,199,199,1,232,232, + 232,2,255,255,255,1,114,242,254,1,255,255,255,1,208,208,208,1,255,0, + 32,6,208,208,208,1,5,5,255,1,4,4,255,4,4,4,254,1,2,2, + 103,1,208,208,208,1,0,0,0,1,194,212,221,1,182,217,233,1,115,199, + 235,1,123,205,239,1,255,0,38,1,182,217,233,1,255,0,38,1,182,217, + 233,1,255,0,38,1,182,217,233,1,255,0,38,1,182,217,233,1,255,0, + 38,1,182,217,233,1,210,232,241,1,197,225,238,1,182,217,233,1,226,240, + 246,1,224,224,224,1,124,124,124,1,232,232,232,1,149,149,149,1,90,90, + 90,1,144,144,144,1,232,232,232,2,227,227,227,1,118,118,118,1,232,232, + 232,1,230,230,230,1,123,123,123,1,89,89,89,1,174,174,174,1,232,232, + 232,1,255,255,255,1,0,0,0,1,255,255,255,1,208,208,208,1,136,136, + 136,1,159,218,223,1,98,132,134,1,191,250,254,1,75,95,97,1,201,252, + 254,1,206,253,254,1,85,103,103,1,207,254,254,1,79,108,110,1,157,242, + 248,1,111,199,206,1,65,138,144,1,136,136,136,1,0,0,0,1,255,255, + 255,1,136,136,136,1,124,124,124,1,232,232,232,7,187,187,187,1,136,136, + 136,1,221,221,221,1,232,232,232,4,255,255,255,1,208,208,208,1,255,255, + 255,1,208,208,208,1,255,0,32,6,0,0,0,1,4,4,255,6,3,3, + 213,1,0,0,0,1,255,255,255,1,168,199,213,1,148,200,223,1,94,185, + 223,1,102,190,227,1,255,0,38,1,109,180,212,1,255,0,38,1,109,180, + 212,1,255,0,38,1,109,180,212,1,255,0,38,1,109,180,212,1,255,0, + 38,1,109,180,212,1,175,214,231,1,163,208,227,1,148,200,223,1,198,225, + 238,1,208,208,208,1,124,124,124,1,232,232,232,14,255,255,255,1,208,208, + 208,1,255,255,255,1,208,208,208,1,136,136,136,1,181,248,254,1,77,104, + 106,1,177,231,235,1,73,94,95,1,201,252,254,1,206,253,254,1,85,103, + 103,1,207,254,254,1,120,163,165,1,121,187,191,1,77,137,142,1,85,180, + 189,1,136,136,136,1,0,0,0,1,255,255,255,1,208,208,208,1,124,124, + 124,1,232,232,232,14,255,255,255,1,224,224,224,1,255,255,255,1,208,208, + 208,1,255,0,32,6,0,0,0,1,208,208,208,1,0,0,0,7,208,208, + 208,1,143,186,206,1,115,184,214,1,74,171,211,1,81,176,215,1,255,0, + 38,1,36,143,190,1,255,0,38,1,36,143,190,1,255,0,38,1,36,143, + 190,1,255,0,38,1,36,143,190,1,255,0,38,1,36,143,190,1,141,197, + 221,1,128,190,217,1,115,184,214,1,170,211,229,1,208,208,208,1,124,124, + 124,1,255,255,255,15,208,208,208,1,236,37,236,1,208,208,208,1,136,136, + 136,1,181,248,254,1,150,200,204,1,98,128,130,1,173,221,224,1,201,252, + 254,1,206,253,254,1,148,178,178,1,207,254,254,1,179,244,247,1,98,151, + 154,1,85,153,158,1,114,242,254,1,136,136,136,1,0,0,0,1,255,255, + 255,2,124,124,124,1,232,232,232,14,255,255,255,2,208,208,208,2,255,0, + 32,6,0,0,0,1,208,208,208,8,255,0,255,1,117,174,199,1,82,167, + 204,1,53,156,199,1,61,161,204,1,255,0,38,1,208,208,208,1,255,0, + 38,1,208,208,208,1,255,0,38,1,208,208,208,1,255,0,38,1,208,208, + 208,1,255,0,38,1,208,208,208,1,107,179,211,1,94,173,207,1,82,167, + 204,1,141,196,220,1,208,208,208,17,255,255,255,2,208,208,208,1,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,201,252, + 254,1,206,253,254,1,211,254,254,1,207,254,254,1,184,251,254,1,161,248, + 254,1,137,245,254,1,114,242,254,1,136,136,136,1,0,0,0,1,255,255, + 255,2,124,124,124,1,232,232,232,14,255,255,255,2,208,208,208,2,255,0, + 32,6,0,0,0,1,208,208,208,8,255,0,255,1,92,161,191,1,49,150, + 194,1,33,142,187,1,40,147,192,1,208,208,208,10,73,162,201,1,60,155, + 197,1,49,150,194,1,112,182,212,1,255,255,255,1,208,208,208,16,255,255, + 255,1,213,213,213,1,208,208,208,1,136,136,136,14,0,0,0,1,182,175, + 175,1,208,208,208,1,124,124,124,1,232,232,232,14,255,255,255,2,0,0, + 255,1,208,208,208,1,255,0,32,6,0,0,0,1,208,208,208,8,255,255, + 255,1,67,148,184,1,16,133,184,1,12,127,176,1,208,208,208,12,25,138, + 187,1,16,133,184,1,84,168,204,1,255,255,255,1,208,208,208,17,213,213, + 213,1,208,208,208,1,0,0,0,16,255,255,255,1,124,124,124,1,255,255, + 255,15,208,208,208,1,226,27,226,1,208,208,208,2,0,0,0,6,208,208, + 208,8,212,212,212,1,42,135,176,1,35,142,187,1,44,147,190,1,117,175, + 199,1,208,208,208,11,156,190,205,1,77,162,200,1,56,153,195,1,136,136, + 136,1,255,255,255,16,208,208,208,1,252,224,227,1,255,255,255,16,121,121, + 121,1,111,241,255,1,255,255,255,16,208,208,208,1,193,193,193,1,255,255, + 255,16,208,208,208,1,218,218,218,1,255,255,255,16,217,217,217,1,173,173, + 173,1,153,153,153,1,142,142,142,2,140,140,140,12,141,141,141,1,148,148, + 148,1,255,255,255,18,208,208,208,18,212,212,212,19,208,208,208,16,57,49, + 50,1,153,153,153,1,208,208,208,1,154,154,154,1,158,158,158,1,154,154, + 154,11,158,158,158,1,208,208,208,1,159,159,159,1,128,76,240,1,124,124, + 124,15,255,255,255,1,208,208,208,19,212,212,212,1,208,208,208,16,212,212, + 212,1,208,208,208,5,155,155,155,1,156,154,154,1,158,157,157,1,160,157, + 158,1,156,154,154,1,153,153,153,1,208,208,208,6,121,121,121,1,132,132, + 132,1,154,154,154,1,157,157,157,1,186,186,186,1,222,222,222,1,223,223, + 223,8,207,207,207,1,157,157,157,1,154,154,154,1,208,208,208,1,158,158, + 158,1,208,208,208,1,124,124,124,1,192,192,192,2,169,169,169,1,186,186, + 186,1,170,170,170,1,166,166,166,1,169,169,169,1,174,174,174,1,165,165, + 165,1,142,142,142,1,169,169,169,1,188,188,188,1,172,172,172,1,160,160, + 160,1,255,255,255,1,208,208,208,19,212,212,212,1,208,208,208,5,0,0, + 0,6,208,208,208,5,255,212,217,2,208,208,208,2,149,149,149,1,158,158, + 158,1,162,159,159,1,203,192,193,1,225,212,213,1,225,209,210,1,204,190, + 192,1,159,156,156,1,139,139,139,1,138,138,138,1,208,208,208,4,255,0, + 0,1,124,124,124,1,138,138,138,1,134,134,134,11,139,139,139,1,190,190, + 190,1,154,154,154,1,208,208,208,1,158,158,158,1,208,208,208,1,124,124, + 124,1,139,139,139,1,152,152,152,1,169,169,169,1,183,183,183,1,148,148, + 148,2,169,169,169,1,152,152,152,1,129,129,129,1,112,112,112,1,169,169, + 169,1,184,184,184,1,142,142,142,1,141,141,141,1,255,255,255,2,126,126, + 126,1,139,139,139,16,143,143,143,1,153,152,152,1,208,208,208,4,0,0, + 0,8,208,208,208,4,121,121,121,2,208,208,208,2,156,155,155,1,182,175, + 175,1,245,225,226,1,254,236,238,1,254,232,234,1,254,228,231,1,255,225, + 228,1,250,218,221,1,182,171,172,1,131,129,129,1,0,0,0,1,208,208, + 208,3,156,156,156,1,122,122,122,1,134,134,134,1,170,170,255,1,174,174, + 255,1,178,178,255,1,182,182,255,1,187,187,255,1,191,191,255,1,195,195, + 255,1,200,200,255,1,204,204,255,1,208,208,255,1,212,212,255,1,134,134, + 134,1,215,215,215,1,154,154,154,1,208,208,208,1,158,158,158,1,124,124, + 124,2,171,171,171,1,180,180,180,1,169,169,169,1,192,192,192,1,172,172, + 172,1,164,164,164,1,169,169,169,1,192,192,192,3,169,169,169,1,192,192, + 192,1,181,181,181,1,169,169,169,1,255,255,255,2,139,139,139,1,217,217, + 217,2,197,197,197,1,200,200,200,1,217,217,217,1,205,205,205,1,210,210, + 210,1,217,217,217,1,216,216,216,1,205,205,205,2,201,201,201,1,217,217, + 217,2,208,208,208,1,206,206,206,1,249,249,249,1,120,174,202,1,208,208, + 208,4,0,0,0,2,0,0,155,1,0,0,255,1,0,0,254,1,0,0, + 155,1,0,0,0,2,208,208,208,4,255,0,255,1,121,121,121,1,208,208, + 208,1,152,152,152,1,163,161,161,1,245,224,225,1,253,235,236,1,159,146, + 147,1,85,77,78,1,86,76,77,1,155,135,137,1,255,218,223,1,251,211, + 216,1,160,156,156,1,77,77,77,1,0,0,0,1,208,208,208,2,241,241, + 241,1,122,122,122,1,134,134,134,1,170,170,255,1,174,174,255,1,178,178, + 255,1,182,182,255,1,187,187,255,1,0,0,0,1,195,195,255,1,200,200, + 255,1,204,204,255,1,208,208,255,1,212,212,255,1,134,134,134,1,215,215, + 215,1,154,154,154,1,208,208,208,1,158,158,158,1,255,255,255,1,124,124, + 124,1,169,169,169,14,255,255,255,2,139,139,139,1,217,217,217,1,126,126, + 126,1,33,33,33,1,44,44,44,1,171,171,171,1,136,136,136,1,128,128, + 128,1,217,217,217,1,195,195,195,1,97,97,97,1,102,102,102,1,60,60, + 60,1,212,212,212,1,217,217,217,1,104,104,104,1,121,121,121,1,249,249, + 249,1,0,255,255,1,208,208,208,3,0,0,0,1,0,0,1,1,0,0, + 56,1,0,0,255,4,0,0,72,1,0,0,1,1,0,0,0,1,208,208, + 208,3,225,225,225,1,128,128,128,1,208,208,208,1,158,157,157,1,211,197, + 198,1,252,233,234,1,253,233,235,1,82,74,75,1,252,224,227,1,254,222, + 226,1,50,43,44,1,252,212,217,1,255,212,217,1,216,189,192,1,134,131, + 132,1,0,0,0,1,208,208,208,2,212,212,212,1,122,122,122,1,134,134, + 134,1,170,170,255,1,174,174,255,1,178,178,255,1,182,182,255,1,187,187, + 255,1,191,191,255,1,195,195,255,1,200,200,255,1,204,204,255,1,208,208, + 255,1,212,212,255,1,134,134,134,1,215,215,215,1,154,154,154,1,208,208, + 208,1,158,158,158,1,255,255,255,1,124,124,124,1,194,194,194,1,192,192, + 192,1,169,169,169,1,211,211,211,1,186,186,186,1,173,173,173,1,169,169, + 169,1,231,231,231,1,205,205,205,1,189,189,189,1,169,169,169,1,226,226, + 226,1,182,182,182,1,189,189,189,1,255,255,255,1,215,88,53,1,139,139, + 139,1,206,206,206,1,45,45,45,1,191,191,191,1,147,147,147,1,80,80, + 80,1,191,191,191,1,74,74,74,1,197,197,197,1,137,137,137,1,118,118, + 118,1,102,102,102,1,31,31,31,1,171,171,171,1,217,217,217,1,43,43, + 43,1,109,109,109,1,249,249,249,1,201,2,201,1,208,208,208,3,0,0, + 234,1,0,0,211,1,0,0,222,1,0,0,255,4,0,0,92,1,0,0, + 11,1,0,0,131,1,208,208,208,3,212,212,212,2,208,208,208,1,157,156, + 156,1,235,218,219,1,255,236,238,1,255,232,234,1,255,228,231,1,255,224, + 228,1,204,176,179,1,68,58,59,1,255,212,217,2,238,202,206,1,152,150, + 150,1,0,0,0,2,208,208,208,1,212,212,212,1,122,122,122,1,134,134, + 134,13,215,215,215,1,154,154,154,1,208,208,208,1,158,158,158,1,188,140, + 117,1,124,124,124,1,160,160,160,1,166,166,166,1,169,169,169,1,199,199, + 199,1,135,135,135,1,179,179,179,1,169,169,169,1,173,173,173,1,166,166, + 166,1,157,157,157,1,169,169,169,1,255,255,255,1,179,179,179,2,255,255, + 255,1,224,224,224,1,139,139,139,1,203,203,203,1,53,53,53,1,141,141, + 141,1,188,188,188,1,165,165,165,1,211,211,211,1,105,105,105,1,142,142, + 142,1,60,60,60,1,185,185,185,1,103,103,103,1,63,63,63,1,136,136, + 136,1,196,196,196,1,45,45,45,1,113,113,113,1,249,249,249,1,66,66, + 66,1,208,208,208,3,0,0,255,6,0,0,182,1,0,0,5,1,0,0, + 94,1,0,0,204,1,0,0,0,1,208,208,208,2,255,255,255,1,208,208, + 208,2,156,155,155,1,244,227,229,1,255,233,235,1,255,229,232,1,255,225, + 228,1,229,198,202,1,57,49,50,1,233,195,199,1,255,212,217,2,244,206, + 210,1,153,152,152,1,0,0,0,2,208,208,208,1,218,218,218,1,122,122, + 122,1,134,134,134,1,173,249,241,1,173,255,247,1,178,255,247,1,182,255, + 248,1,186,255,249,1,191,255,249,1,195,255,250,1,199,255,251,1,203,255, + 252,1,208,255,252,1,212,255,253,1,144,149,149,1,215,215,215,1,154,154, + 154,1,208,208,208,1,158,158,158,1,0,252,248,1,124,124,124,1,185,185, + 185,1,176,176,176,1,169,169,169,1,255,255,255,3,169,169,169,1,239,239, + 239,1,204,204,204,1,186,186,186,1,169,169,169,1,255,255,255,4,14,181, + 0,1,139,139,139,1,217,217,217,1,154,154,154,1,42,42,42,1,43,43, + 43,1,167,167,167,1,217,217,217,1,166,166,166,1,38,38,38,1,106,106, + 106,1,216,216,216,1,103,103,103,1,92,92,92,1,118,118,118,1,130,130, + 130,1,92,92,92,1,113,113,113,1,249,249,249,1,210,210,210,1,208,208, + 208,3,0,0,255,5,0,0,184,1,0,0,9,1,0,0,59,1,0,0, + 247,1,0,0,240,1,0,0,0,1,208,208,208,2,210,210,210,2,208,208, + 208,1,161,158,160,1,224,209,211,1,255,230,233,1,255,226,229,1,255,222, + 226,1,166,142,145,1,164,138,141,1,255,212,217,3,224,194,197,1,142,139, + 139,1,0,0,0,2,208,208,208,1,210,210,210,1,122,122,122,1,134,134, + 134,1,173,249,241,1,173,255,247,1,178,255,247,1,182,255,248,1,186,255, + 249,1,0,0,0,1,195,255,250,1,199,255,251,1,203,255,252,1,208,255, + 252,1,212,255,253,1,144,149,149,1,215,215,215,1,154,154,154,1,208,208, + 208,1,158,158,158,1,224,224,224,1,124,124,124,1,169,169,169,14,255,255, + 255,1,208,208,208,1,139,139,139,1,210,210,210,1,199,199,199,1,212,212, + 212,1,136,136,136,1,47,47,47,1,217,217,217,2,46,46,46,1,209,209, + 209,1,217,217,217,1,103,103,103,1,101,101,101,2,65,65,65,1,165,165, + 165,1,113,113,113,1,249,249,249,1,210,210,210,1,208,208,208,3,0,0, + 255,4,0,0,211,1,0,0,6,1,0,0,49,1,0,0,238,1,0,0, + 255,1,0,0,240,1,0,0,0,1,208,208,208,2,210,210,210,2,208,208, + 208,1,155,155,155,1,182,175,175,1,255,227,230,1,255,223,227,1,255,219, + 223,1,207,175,179,1,210,175,179,1,255,212,217,3,181,168,169,1,100,100, + 100,1,0,0,0,2,208,208,208,1,210,210,210,1,122,122,122,1,134,134, + 134,1,173,249,241,1,173,255,247,1,178,255,247,1,182,255,248,1,186,255, + 249,1,191,255,249,1,195,255,250,1,199,255,251,1,203,255,252,1,208,255, + 252,1,212,255,253,1,144,149,149,1,215,215,215,1,154,154,154,1,208,208, + 208,1,158,158,158,1,13,182,0,1,124,124,124,1,186,186,186,1,192,192, + 192,1,169,169,169,1,226,226,226,1,207,207,207,1,186,186,186,1,169,169, + 169,1,226,226,226,1,207,207,207,1,186,186,186,1,169,169,169,1,221,221, + 221,1,207,207,207,1,190,190,190,1,255,255,255,1,207,207,207,1,139,139, + 139,1,178,178,178,1,73,73,73,1,209,209,209,1,198,198,198,1,51,51, + 51,1,217,217,217,2,48,48,48,1,214,214,214,1,217,217,217,1,103,103, + 103,1,113,113,113,1,101,101,101,1,52,52,52,1,186,186,186,1,113,113, + 113,1,249,249,249,1,210,210,210,1,208,208,208,3,0,0,255,4,0,0, + 95,1,0,0,12,1,0,0,233,1,0,0,255,2,0,0,204,1,0,0, + 0,1,208,208,208,2,210,210,210,2,208,208,208,1,146,146,146,1,153,152, + 152,1,216,197,199,1,255,220,224,1,255,216,221,1,195,162,166,1,199,165, + 169,1,255,212,217,2,216,189,193,1,149,150,153,1,53,103,129,1,5,9, + 12,1,0,0,0,1,208,208,208,1,210,210,210,1,122,122,122,1,134,134, + 134,13,215,215,215,1,154,154,154,1,208,208,208,1,158,158,158,1,124,124, + 124,2,161,161,161,1,192,192,192,1,169,169,169,1,174,174,174,1,138,138, + 138,1,136,136,136,1,169,169,169,1,174,174,174,1,138,138,138,1,136,136, + 136,1,169,169,169,1,174,174,174,1,128,128,128,1,150,150,150,1,255,255, + 255,2,139,139,139,1,212,212,212,1,80,80,80,1,45,45,45,1,49,49, + 49,1,105,105,105,1,217,217,217,2,48,48,48,1,214,214,214,1,217,217, + 217,1,103,103,103,1,124,124,124,1,117,117,117,1,91,91,91,1,186,186, + 186,1,113,113,113,1,249,249,249,1,210,210,210,1,208,208,208,3,0,0, + 255,1,0,0,254,1,0,0,255,2,0,0,54,1,0,0,61,1,0,0, + 255,2,0,0,254,1,0,0,89,1,0,0,0,1,208,208,208,2,210,210, + 210,2,208,208,208,2,150,150,150,1,151,149,150,1,186,173,174,1,241,205, + 209,1,255,212,217,2,241,204,208,1,186,171,173,1,152,152,153,1,165,194, + 209,1,120,174,202,1,61,124,155,1,12,24,30,1,208,208,208,1,128,128, + 128,1,122,122,122,1,134,134,134,1,255,170,184,1,255,174,187,1,255,178, + 190,1,255,182,193,1,255,187,196,1,255,191,199,1,255,195,202,1,255,200, + 205,1,255,204,208,1,255,208,211,1,255,212,214,1,134,134,134,1,215,215, + 215,1,154,154,154,1,208,208,208,1,158,158,158,1,255,255,255,1,124,124, + 124,1,164,164,164,1,192,192,192,1,169,169,169,1,236,236,236,1,219,219, + 219,1,201,201,201,1,169,169,169,1,236,236,236,1,219,219,219,1,201,201, + 201,1,169,169,169,1,231,231,231,1,219,219,219,1,204,204,204,1,255,255, + 255,2,139,139,139,1,217,217,217,2,159,159,159,1,157,157,157,1,212,212, + 212,1,217,217,217,2,164,164,164,1,217,217,217,2,187,187,187,1,194,194, + 194,1,192,192,192,1,196,196,196,1,207,207,207,1,185,185,185,1,249,249, + 249,1,210,210,210,1,208,208,208,4,0,0,223,1,0,0,254,1,0,0, + 255,1,0,0,188,1,0,0,199,1,0,0,255,1,0,0,254,1,0,0, + 158,1,0,0,0,2,208,208,208,2,210,210,210,2,208,208,208,3,63,63, + 63,1,120,119,119,1,150,148,149,1,153,152,152,2,150,148,149,1,112,111, + 111,1,64,111,135,1,131,181,206,1,168,203,221,1,120,175,202,1,61,124, + 155,1,18,37,46,1,210,210,210,1,122,122,122,1,134,134,134,1,255,170, + 184,1,255,174,187,1,255,178,190,1,255,182,193,1,255,187,196,1,0,0, + 0,1,255,195,202,1,255,200,205,1,255,204,208,1,255,208,211,1,255,212, + 214,1,134,134,134,1,182,182,182,1,158,158,158,1,208,208,208,1,158,158, + 158,1,255,255,255,1,124,124,124,1,169,169,169,14,255,255,255,1,206,48, + 6,1,139,139,139,1,217,217,217,16,249,249,249,1,210,210,210,1,208,208, + 208,5,0,0,136,1,0,0,204,1,0,0,167,1,0,0,172,1,0,0, + 204,1,0,0,89,1,0,0,0,2,208,208,208,3,210,210,210,2,208,208, + 208,4,0,0,0,2,24,24,24,1,20,20,20,1,0,0,0,2,7,14, + 18,1,74,136,168,1,131,181,206,1,168,203,221,1,120,175,202,1,52,106, + 133,1,210,210,210,1,122,122,122,1,134,134,134,1,255,170,184,1,255,174, + 187,1,255,178,190,1,255,182,193,1,255,187,196,1,255,191,199,1,255,195, + 202,1,255,200,205,1,255,204,208,1,255,208,211,1,255,212,214,1,134,134, + 134,1,150,150,150,1,24,24,24,1,0,0,0,1,160,160,160,1,255,255, + 255,1,124,124,124,1,197,197,197,1,192,192,192,1,169,169,169,1,224,224, + 224,1,216,216,216,1,207,207,207,1,169,169,169,1,234,234,234,1,216,216, + 216,2,169,169,169,1,253,253,253,1,208,208,208,1,210,210,210,1,255,255, + 255,1,0,0,0,1,143,143,143,1,248,248,248,16,254,254,254,1,210,210, + 210,1,208,208,208,6,0,0,0,6,208,208,208,4,210,210,210,2,208,208, + 208,6,0,0,0,4,208,208,208,1,27,56,70,1,73,135,166,1,130,181, + 206,1,168,202,220,1,54,78,90,1,210,210,210,1,122,122,122,1,136,136, + 136,1,134,134,134,11,137,137,137,1,43,43,43,1,0,0,0,1,208,208, + 208,1,104,104,104,1,255,255,255,1,124,124,124,1,161,161,161,1,145,145, + 145,1,169,169,169,1,166,166,166,1,173,173,173,1,170,170,170,1,169,169, + 169,1,234,234,234,1,169,169,169,1,179,179,179,1,169,169,169,1,243,243, + 243,1,166,166,166,1,96,96,96,1,255,255,255,2,208,208,208,18,210,210, + 210,1,208,208,208,7,0,0,0,2,208,208,208,7,210,210,210,2,208,208, + 208,12,40,80,101,1,65,120,147,1,60,83,96,1,0,0,0,1,218,218, + 218,1,122,122,122,1,0,0,0,14,208,208,208,2,20,20,20,1,255,255, + 255,1,124,124,124,1,246,246,246,1,255,255,255,15,208,208,208,37,210,210, + 210,16,208,208,208,1,114,114,114,1,123,123,123,13,124,124,124,1,90,90, + 90,1,33,33,33,1,32,32,32,1,208,208,208,1,255,255,255,16,224,224, + 224,1,208,208,208,36,200,202,192,1,203,204,199,1,200,203,200,2,209,209, + 209,2,208,208,208,11,209,209,209,1,0,0,0,1,255,255,255,16,99,99, + 99,1,208,208,208,71,209,205,204,1,191,250,254,1,208,208,208,71,208,205, + 203,1,208,208,208,16,209,209,209,1,0,0,0,1,208,208,208,17,217,217, + 217,4,255,255,255,1,128,128,128,1,217,217,217,4,208,208,208,44,209,207, + 207,1,208,208,208,7,0,0,182,2,208,208,208,7,207,207,207,1,0,0, + 255,1,208,208,208,7,0,0,182,2,208,208,208,7,98,98,241,1,208,208, + 208,54,209,209,209,1,208,208,208,5,0,0,195,1,0,0,206,1,0,0, + 214,2,0,0,206,1,0,0,195,1,208,208,208,5,208,202,201,1,224,224, + 224,1,208,208,208,5,0,0,195,1,0,0,206,1,0,0,214,2,0,0, + 206,1,0,0,195,1,208,208,208,5,217,217,217,1,208,208,208,54,208,204, + 202,1,208,208,208,4,0,0,200,1,0,0,233,1,0,0,255,4,0,0, + 228,1,0,0,187,1,208,208,208,4,209,205,204,1,224,224,224,1,208,208, + 208,4,0,0,200,1,0,0,233,1,0,0,255,4,0,0,228,1,0,0, + 187,1,208,208,208,4,54,54,54,1,208,208,208,54,207,199,197,1,208,208, + 208,3,0,0,195,1,0,0,233,1,0,0,255,6,0,0,226,1,0,0, + 140,1,208,208,208,3,210,210,210,1,217,217,217,1,208,208,208,3,0,0, + 195,1,0,0,233,1,0,0,255,6,0,0,226,1,0,0,140,1,208,208, + 208,4,218,218,218,1,217,217,217,7,255,255,255,1,128,128,128,1,217,217, + 217,4,208,208,208,40,210,210,210,1,208,208,208,3,0,0,206,1,0,0, + 255,8,0,0,180,1,0,0,0,1,208,208,208,2,207,207,207,1,0,0, + 255,1,208,208,208,3,0,0,206,1,0,0,255,8,0,0,180,1,0,0, + 0,1,208,208,208,2,136,136,136,1,0,0,0,1,98,2,17,1,232,165, + 35,1,34,16,65,1,0,0,0,1,136,9,0,1,64,29,40,1,20,29, + 40,1,0,0,0,2,36,29,40,1,0,0,0,2,0,0,1,1,208,208, + 208,4,0,0,0,2,236,236,236,34,209,209,209,1,208,208,208,2,0,0, + 182,1,0,0,214,1,0,0,255,8,0,0,197,1,0,0,13,1,208,208, + 208,2,207,200,198,1,0,0,0,1,208,208,208,2,0,0,182,1,0,0, + 214,1,0,0,255,8,0,0,197,1,0,0,13,1,208,208,208,2,128,196, + 201,1,0,0,0,54,208,203,201,1,208,208,208,2,0,0,182,1,0,0, + 214,1,0,0,255,8,0,0,197,1,0,0,10,1,208,208,208,2,207,201, + 199,1,144,188,191,1,208,208,208,2,0,0,182,1,0,0,214,1,0,0, + 255,8,0,0,197,1,0,0,10,1,208,208,208,2,163,163,166,1,0,0, + 0,42,255,255,255,12,205,199,198,1,208,208,208,3,0,0,206,1,0,0, + 255,8,0,0,179,1,0,0,0,1,208,208,208,2,209,207,206,1,136,136, + 136,1,208,208,208,3,0,0,206,1,0,0,255,8,0,0,179,1,0,0, + 0,1,208,208,208,3,0,0,0,3,38,38,38,1,1,1,1,1,0,0, + 0,27,255,255,255,1,140,140,140,14,255,255,255,1,0,0,0,2,255,255, + 255,4,207,200,198,1,208,208,208,3,0,0,195,1,0,0,228,1,0,0, + 255,6,0,0,226,1,0,0,107,1,0,0,0,1,208,208,208,2,208,207, + 206,1,208,208,208,4,0,0,195,1,0,0,228,1,0,0,255,6,0,0, + 226,1,0,0,107,1,0,0,0,1,208,208,208,2,224,224,224,1,0,0, + 0,22,255,255,255,1,140,140,140,14,255,255,255,1,0,0,0,1,255,255, + 255,14,0,0,0,1,209,209,209,1,208,208,208,4,0,0,187,1,0,0, + 226,1,0,0,255,4,0,0,226,1,0,0,154,1,0,0,0,2,208,208, + 208,2,210,210,210,1,224,224,224,1,208,208,208,4,0,0,187,1,0,0, + 226,1,0,0,255,4,0,0,226,1,0,0,154,1,0,0,0,2,208,208, + 208,3,255,255,255,13,140,140,140,14,255,255,255,17,0,0,0,1,255,255, + 255,9,209,205,204,1,208,208,208,5,0,0,140,1,0,0,180,1,0,0, + 197,2,0,0,179,1,0,0,107,1,0,0,0,2,208,208,208,3,208,206, + 206,1,255,255,255,1,208,208,208,5,0,0,140,1,0,0,180,1,0,0, + 197,2,0,0,179,1,0,0,107,1,0,0,0,2,208,208,208,3,255,255, + 255,1,140,140,140,1,255,255,255,2,140,140,140,14,255,255,255,17,0,0, + 0,1,255,255,255,15,0,0,0,3,128,128,128,1,208,210,210,1,208,208, + 208,6,0,0,0,1,0,0,13,1,0,0,10,1,0,0,0,3,208,208, + 208,4,210,210,210,1,255,255,255,1,208,208,208,6,0,0,0,1,0,0, + 13,1,0,0,10,1,0,0,0,3,208,208,208,4,255,255,255,1,140,140, + 140,1,221,221,221,1,216,216,216,3,163,163,163,1,140,140,140,1,255,255, + 255,17,0,0,0,1,255,255,255,15,0,0,0,3,128,128,128,1,255,255, + 255,5,182,182,182,1,7,7,7,1,0,0,0,3,210,210,210,1,208,208, + 208,16,208,204,202,1,208,208,208,17,255,30,64,1,255,255,255,14,0,0, + 0,1,255,255,255,15,0,0,0,3,128,128,128,1,255,255,255,6,219,219, + 219,1,30,30,30,1,0,0,0,4,255,255,255,1,175,175,175,1,191,191, + 191,1,140,140,140,1,192,192,192,1,174,174,174,1,143,143,143,1,144,144, + 144,1,209,209,209,1,208,208,208,16,207,201,199,1,208,208,208,18,255,255, + 255,4,0,0,0,1,255,255,255,15,0,0,0,3,128,128,128,1,255,255, + 255,6,230,230,230,1,125,125,125,1,14,14,14,1,0,0,0,3,255,255, + 255,1,168,168,168,1,191,191,191,1,140,140,140,1,194,194,194,1,172,172, + 172,1,140,140,140,1,144,144,144,1,215,215,215,1,140,140,140,1,191,191, + 191,1,168,168,168,1,140,140,140,1,218,218,218,1,148,148,148,1,255,255, + 255,2,140,140,140,1,209,196,192,1,208,202,200,1,207,200,198,1,207,199, + 196,1,208,201,199,1,208,204,203,1,209,209,209,1,209,206,205,1,208,202, + 200,1,208,198,196,1,207,199,197,1,208,201,199,3,207,201,198,1,207,198, + 198,1,206,200,200,1,205,192,192,1,255,30,64,1,255,255,255,16,124,124, + 124,1,255,255,255,10,0,0,0,3,128,128,128,1,255,255,255,5,212,212, + 212,1,143,143,143,1,110,110,110,1,14,14,14,1,0,0,0,3,255,255, + 255,1,143,143,143,1,212,212,212,1,140,140,140,1,216,216,216,1,152,152, + 152,1,140,140,140,1,144,144,144,1,215,215,215,1,140,140,140,1,162,162, + 162,1,193,193,193,1,142,142,142,1,227,227,227,1,140,140,140,1,255,255, + 255,2,140,140,140,1,187,187,187,1,176,176,176,1,196,196,196,1,220,220, + 220,1,148,148,148,1,227,227,227,1,140,140,140,1,227,227,227,1,140,140, + 140,2,80,27,0,0,0,0,0,6,46,46,46,1,21,21,21,1,0,0, + 0,3,5,5,5,1,0,0,0,80,9,9,9,1,2,2,2,1,0,0, + 0,1,6,6,6,1,207,207,207,1,212,212,212,1,116,116,116,1,122,122, + 122,1,161,161,161,1,232,232,232,1,87,87,87,1,6,6,6,1,0,0, + 0,5,255,255,255,16,0,0,0,38,255,255,255,15,128,128,128,1,0,0, + 0,3,102,102,102,1,205,205,205,1,128,128,128,1,114,114,114,1,231,231, + 231,1,255,255,255,1,247,247,247,1,248,248,248,1,253,253,253,2,179,179, + 179,1,114,114,114,1,48,48,48,1,0,0,0,4,255,255,255,16,0,0, + 0,5,155,155,155,1,27,27,27,1,0,0,0,31,255,255,255,16,0,0, + 0,3,35,35,35,1,241,241,241,1,253,253,253,1,245,245,245,1,255,255, + 255,7,219,219,219,1,147,147,147,1,159,159,159,1,172,172,172,1,0,0, + 0,2,255,255,255,16,0,0,0,5,196,196,196,1,221,221,221,1,65,65, + 65,1,0,0,0,30,255,255,255,16,0,0,0,3,48,48,48,1,222,222, + 222,1,255,255,255,10,251,251,251,1,255,255,255,1,173,173,173,1,0,0, + 0,2,255,255,255,16,0,0,0,5,192,192,192,1,255,255,255,1,239,239, + 239,1,118,118,118,1,0,0,0,11,255,255,255,16,0,0,0,2,255,255, + 255,16,0,0,0,2,6,6,6,1,114,114,114,1,231,231,231,1,255,255, + 255,11,246,246,246,1,118,118,118,1,6,6,6,1,0,0,0,1,255,255, + 255,16,0,0,0,5,192,192,192,1,255,255,255,2,248,248,248,1,167,167, + 167,1,3,3,3,1,0,0,0,9,255,255,255,16,0,0,0,2,255,255, + 255,16,0,0,0,2,55,55,55,1,169,169,169,1,255,255,255,13,169,169, + 169,1,55,55,55,1,0,0,0,2,255,255,255,15,0,0,0,5,192,192, + 192,1,255,255,255,3,254,254,254,1,202,202,202,1,18,18,18,1,0,0, + 0,8,255,255,255,16,0,0,0,2,255,255,255,16,0,0,0,2,97,97, + 97,1,226,226,226,1,255,255,255,13,230,230,230,1,99,99,99,1,0,0, + 0,1,255,255,255,16,0,0,0,5,192,192,192,1,255,255,255,5,222,222, + 222,1,50,50,50,1,0,0,0,7,255,255,255,16,0,0,0,2,255,255, + 255,16,0,0,0,1,24,24,24,1,239,239,239,1,255,255,255,14,253,253, + 253,1,185,185,185,1,0,0,0,1,255,255,255,16,0,0,0,5,192,192, + 192,1,255,255,255,6,235,235,235,1,101,101,101,1,0,0,0,6,255,255, + 255,16,0,0,0,2,255,255,255,16,0,0,0,2,153,153,153,1,251,251, + 251,1,255,255,255,13,246,246,246,1,122,122,122,1,0,0,0,1,255,255, + 255,16,0,0,0,5,192,192,192,1,255,255,255,6,241,241,241,1,166,166, + 166,1,14,14,14,1,0,0,0,5,255,255,255,16,0,0,0,2,255,255, + 255,16,0,0,0,2,114,114,114,1,236,236,236,1,255,255,255,13,236,236, + 236,1,114,114,114,1,0,0,0,1,255,255,255,16,0,0,0,5,192,192, + 192,1,255,255,255,5,235,235,235,1,162,162,162,1,110,110,110,1,14,14, + 14,1,0,0,0,5,255,255,255,16,0,0,0,2,255,255,255,16,0,0, + 0,2,91,91,91,1,210,210,210,1,255,255,255,13,215,215,215,1,91,91, + 91,1,0,0,0,1,255,255,255,16,0,0,0,5,192,192,192,1,255,255, + 255,3,254,254,254,1,227,227,227,1,148,148,148,1,87,87,87,1,4,4, + 4,1,0,0,0,6,255,255,255,16,0,0,0,2,255,255,255,16,0,0, + 0,2,55,55,55,1,195,195,195,1,255,255,255,13,235,235,235,1,55,55, + 55,1,0,0,0,1,255,255,255,16,0,0,0,5,192,192,192,1,255,255, + 255,2,249,249,249,1,212,212,212,1,139,139,139,1,61,61,61,1,0,0, + 0,8,255,255,255,16,0,0,0,2,255,255,255,16,0,0,0,2,6,6, + 6,1,231,231,231,1,248,248,248,1,255,255,255,11,220,220,220,1,120,120, + 120,1,6,6,6,1,0,0,0,1,255,255,255,16,0,0,0,5,192,192, + 192,1,255,255,255,1,243,243,243,1,191,191,191,1,130,130,130,1,37,37, + 37,1,0,0,0,9,255,255,255,16,0,0,0,2,255,255,255,16,0,0, + 0,3,63,63,63,1,145,145,145,1,237,237,237,1,255,255,255,9,236,236, + 236,1,145,145,145,1,48,48,48,1,0,0,0,2,255,255,255,16,0,0, + 0,5,196,196,196,1,228,228,228,1,169,169,169,1,116,116,116,1,19,19, + 19,1,0,0,0,28,255,255,255,16,0,0,0,4,62,62,62,1,153,153, + 153,1,238,238,238,1,255,255,255,7,219,219,219,1,145,145,145,1,62,62, + 62,1,0,0,0,3,255,255,255,16,0,0,0,5,155,155,155,1,90,90, + 90,1,96,96,96,1,7,7,7,1,0,0,0,29,255,255,255,16,0,0, + 0,5,48,48,48,1,114,114,114,1,169,169,169,1,210,210,210,1,237,237, + 237,1,245,245,245,1,236,236,236,1,241,241,241,1,238,238,238,1,114,114, + 114,1,48,48,48,1,0,0,0,5,255,255,255,15,0,0,0,6,21,21, + 21,1,1,1,1,1,0,0,0,30,255,255,255,1,128,128,128,1,255,255, + 255,14,0,0,0,6,6,6,6,1,55,55,55,1,91,91,91,1,114,114, + 114,1,122,122,122,1,114,114,114,1,111,111,111,1,93,93,93,1,6,6, + 6,1,0,0,0,241,255,255,255,1,0,0,0,16,255,255,255,8,251,251, + 251,1,70,70,70,1,1,1,1,1,0,0,0,29,8,8,8,1,101,101, + 101,1,149,149,149,1,148,148,148,1,105,105,105,1,10,10,10,1,0,0, + 0,27,255,255,255,2,0,0,0,1,9,9,9,1,21,21,21,1,27,27, + 27,2,22,22,22,1,51,51,51,1,32,32,32,1,57,57,57,1,0,0, + 0,6,255,255,255,9,253,253,253,1,103,103,103,1,1,1,1,1,0,0, + 0,12,7,7,7,2,0,0,0,13,29,29,29,1,224,224,224,1,255,255, + 255,1,215,215,215,1,218,218,218,1,255,255,255,1,225,225,225,1,36,36, + 36,1,0,0,0,24,255,255,255,5,52,52,52,1,98,98,98,1,91,91, + 91,1,82,82,82,1,74,74,74,1,56,56,56,1,107,107,107,1,58,58, + 58,1,0,0,0,6,255,255,255,10,253,253,253,1,111,111,111,1,1,1, + 1,1,0,0,0,9,102,102,102,1,201,201,201,1,220,220,220,2,201,201, + 201,1,102,102,102,1,0,0,0,11,185,185,185,1,255,255,255,1,199,199, + 199,1,229,229,229,2,199,199,199,1,254,254,254,1,195,195,195,1,0,0, + 0,6,255,255,255,16,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,4,14,14,14,1,6,6,6,1,14,14,14,1,0,0, + 0,1,14,14,14,1,0,0,0,6,255,255,255,11,253,253,253,1,119,119, + 119,1,1,1,1,1,0,0,0,7,166,166,166,1,242,242,242,1,255,255, + 255,4,247,247,247,1,177,177,177,1,0,0,0,9,17,17,17,1,253,253, + 253,1,255,255,255,6,254,254,254,1,13,13,13,1,0,0,0,5,255,255, + 255,16,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,1,8,8, + 8,1,0,0,0,4,94,94,94,1,78,78,78,1,93,93,93,1,80,80, + 80,1,76,76,76,1,0,0,0,6,255,255,255,12,253,253,253,1,128,128, + 128,1,2,2,2,1,0,0,0,5,102,102,102,1,242,242,242,1,255,255, + 255,6,249,249,249,1,142,142,142,1,0,0,0,8,62,62,62,1,253,253, + 253,1,255,255,255,7,111,111,111,1,0,0,0,5,255,255,255,16,0,0, + 0,2,255,255,255,1,0,0,0,7,45,45,45,1,49,49,49,1,47,47, + 47,1,61,61,61,1,28,28,28,1,0,0,0,6,255,255,255,14,54,54, + 54,1,0,0,0,5,201,201,201,1,255,255,255,8,230,230,230,1,32,32, + 32,1,0,0,0,7,175,175,175,1,255,255,255,8,219,219,219,1,32,32, + 32,1,0,0,0,4,255,255,255,16,0,0,0,2,255,255,255,1,0,0, + 0,4,20,20,20,1,43,43,43,1,40,40,40,1,87,87,87,1,35,35, + 35,1,18,18,18,1,0,0,0,2,255,255,255,3,0,0,0,3,255,255, + 255,14,136,136,136,1,0,0,0,4,7,7,7,1,220,220,220,1,255,255, + 255,8,239,239,239,1,100,100,100,1,0,0,0,7,229,229,229,1,255,255, + 255,8,243,243,243,1,96,96,96,1,0,0,0,4,255,255,255,16,0,0, + 0,2,255,255,255,1,0,0,0,4,42,42,42,1,79,79,79,1,80,80, + 80,1,94,94,94,1,74,74,74,1,41,41,41,1,0,0,0,4,255,255, + 255,1,0,0,0,3,255,255,255,14,138,138,138,1,0,0,0,4,7,7, + 7,1,220,220,220,1,255,255,255,8,239,239,239,1,130,130,130,1,0,0, + 0,7,229,229,229,1,255,255,255,8,243,243,243,1,126,126,126,1,0,0, + 0,4,255,255,255,16,0,0,0,2,255,255,255,1,0,0,0,14,255,255, + 255,1,0,0,0,3,255,255,255,14,138,138,138,1,0,0,0,5,201,201, + 201,1,255,255,255,8,231,231,231,1,126,126,126,1,0,0,0,7,175,175, + 175,1,255,255,255,8,219,219,219,1,126,126,126,1,0,0,0,4,255,255, + 255,16,0,0,0,2,255,255,255,1,0,0,0,14,255,255,255,1,0,0, + 0,3,255,255,255,14,138,138,138,1,0,0,0,5,102,102,102,1,247,247, + 247,1,255,255,255,6,249,249,249,1,186,186,186,1,96,96,96,1,0,0, + 0,7,58,58,58,1,254,254,254,1,255,255,255,6,254,254,254,1,166,166, + 166,1,96,96,96,1,0,0,0,4,255,255,255,16,0,0,0,2,255,255, + 255,1,0,0,0,2,59,59,59,1,45,45,45,1,20,20,20,1,26,26, + 26,1,28,28,28,1,3,3,3,1,26,26,26,1,19,19,19,1,0,0, + 0,4,255,255,255,1,0,0,0,3,255,255,255,14,138,138,138,1,0,0, + 0,6,177,177,177,1,249,249,249,1,255,255,255,4,249,249,249,1,215,215, + 215,1,139,139,139,1,32,32,32,1,0,0,0,8,137,137,137,1,254,254, + 254,1,255,255,255,4,254,254,254,1,194,194,194,1,139,139,139,1,32,32, + 32,1,0,0,0,4,255,255,255,16,0,0,0,2,255,255,255,2,0,0, + 0,1,78,78,78,1,61,61,61,1,91,91,91,1,100,100,100,1,109,109, + 109,1,36,36,36,1,101,101,101,1,48,48,48,1,0,0,0,1,8,8, + 8,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,3,255,255, + 255,14,138,138,138,1,0,0,0,7,142,142,142,1,230,230,230,1,239,239, + 239,2,231,231,231,1,186,186,186,1,139,139,139,1,66,66,66,1,0,0, + 0,10,109,109,109,1,219,219,219,1,247,247,247,1,246,246,246,1,219,219, + 219,1,166,166,166,1,139,139,139,1,66,66,66,1,0,0,0,5,255,255, + 255,16,0,0,0,12,18,18,18,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,3,255,255,255,14,138,138,138,1,0,0, + 0,8,32,32,32,1,100,100,100,1,130,130,130,1,126,126,126,1,96,96, + 96,1,32,32,32,1,0,0,0,12,32,32,32,1,246,246,246,1,239,239, + 239,1,126,126,126,1,96,96,96,1,32,32,32,1,0,0,0,27,105,105, + 105,1,83,83,83,1,82,82,82,1,91,91,91,1,93,93,93,1,124,124, + 124,1,69,69,69,1,57,57,57,1,255,255,255,5,0,0,0,3,255,255, + 255,14,138,138,138,1,0,0,0,27,120,120,120,1,112,112,112,1,0,0, + 0,30,38,38,38,1,31,31,31,1,29,29,29,1,33,33,33,1,34,34, + 34,1,44,44,44,1,26,26,26,1,13,13,13,1,0,0,0,1,255,255, + 255,2,0,0,0,5,2,2,2,1,136,136,136,1,138,138,138,12,136,136, + 136,1,0,0,0,69,255,255,255,1,0,0,0,185,118,118,118,1,124,124, + 124,1,7,7,7,1,0,0,0,50,255,255,255,16,0,0,0,6,1,1, + 1,1,0,0,0,14,32,32,32,1,176,176,176,1,219,219,219,1,73,73, + 73,1,0,0,0,32,255,255,255,8,251,251,251,1,70,70,70,1,1,1, + 1,1,0,0,0,6,255,255,255,16,0,0,0,4,86,86,86,1,210,210, + 210,1,249,249,249,1,210,210,210,1,86,86,86,1,0,0,0,14,73,73, + 73,1,219,219,219,1,175,175,175,1,32,32,32,1,0,0,0,30,255,255, + 255,9,253,253,253,1,103,103,103,1,1,1,1,1,0,0,0,5,255,255, + 255,16,0,0,0,3,90,90,90,1,255,255,255,5,120,120,120,1,0,0, + 0,14,7,7,7,1,124,124,124,1,236,236,236,1,124,124,124,1,7,7, + 7,1,0,0,0,9,255,255,255,16,0,0,0,3,255,255,255,10,253,253, + 253,1,111,111,111,1,1,1,1,1,0,0,0,4,255,255,255,16,0,0, + 0,3,211,211,211,1,255,255,255,5,235,235,235,1,49,49,49,1,0,0, + 0,15,32,32,32,1,176,176,176,1,219,219,219,1,73,73,73,1,0,0, + 0,8,255,255,255,16,0,0,0,3,255,255,255,11,253,253,253,1,119,119, + 119,1,1,1,1,1,0,0,0,3,255,255,255,16,0,0,0,3,240,240, + 240,1,255,255,255,5,248,248,248,1,116,116,116,1,0,0,0,2,34,34, + 34,1,0,0,0,6,255,255,255,1,85,85,85,1,0,0,0,6,73,73, + 73,1,219,219,219,1,176,176,176,1,32,32,32,1,0,0,0,2,85,85, + 85,1,255,255,255,1,0,0,0,2,255,255,255,16,0,0,0,3,255,255, + 255,12,253,253,253,1,128,128,128,1,2,2,2,1,0,0,0,2,255,255, + 255,16,0,0,0,3,178,178,178,1,255,255,255,5,220,220,220,1,132,132, + 132,1,0,0,0,1,22,22,22,1,230,230,230,1,39,39,39,1,0,0, + 0,5,255,255,255,1,234,234,234,1,21,21,21,1,0,0,0,6,7,7, + 7,1,124,124,124,1,118,118,118,1,0,0,0,1,21,21,21,1,234,234, + 234,1,255,255,255,1,0,0,0,2,255,255,255,16,0,0,0,3,255,255, + 255,14,54,54,54,1,0,0,0,2,255,255,255,16,0,0,0,3,33,33, + 33,1,240,240,240,1,255,255,255,3,244,244,244,1,155,155,155,1,98,98, + 98,1,0,0,0,1,147,147,147,1,255,255,255,1,200,200,200,1,12,12, + 12,1,0,0,0,4,255,255,255,2,170,170,170,1,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,1,0,0,0,1,170,170,170,1,255,255, + 255,2,0,0,0,2,255,255,255,16,0,0,0,3,255,255,255,14,136,136, + 136,1,0,0,0,2,255,255,255,16,0,0,0,4,33,33,33,1,184,184, + 184,1,209,209,209,1,191,191,191,1,147,147,147,1,126,126,126,1,18,18, + 18,1,35,35,35,1,250,250,250,1,255,255,255,1,253,253,253,1,105,105, + 105,1,0,0,0,4,255,255,255,16,0,0,0,2,255,255,255,16,0,0, + 0,3,255,255,255,14,138,138,138,1,0,0,0,2,255,255,255,16,0,0, + 0,5,9,9,9,1,63,63,63,1,85,85,85,1,63,63,63,1,9,9, + 9,1,0,0,0,1,167,167,167,1,255,255,255,3,214,214,214,1,19,19, + 19,1,0,0,0,3,255,255,255,16,0,0,0,2,255,255,255,16,0,0, + 0,3,255,255,255,14,138,138,138,1,0,0,0,2,255,255,255,16,0,0, + 0,3,255,255,255,6,0,0,0,1,50,50,50,1,254,254,254,1,255,255, + 255,4,124,124,124,1,0,0,0,3,255,255,255,16,0,0,0,2,255,255, + 255,16,0,0,0,3,255,255,255,14,138,138,138,1,0,0,0,2,255,255, + 255,16,0,0,0,3,255,255,255,6,140,140,140,1,187,187,187,1,255,255, + 255,5,224,224,224,1,27,27,27,1,0,0,0,2,255,255,255,16,0,0, + 0,2,255,255,255,16,0,0,0,3,255,255,255,14,138,138,138,1,0,0, + 0,2,255,255,255,16,0,0,0,3,255,255,255,6,140,140,140,1,0,0, + 0,1,103,103,103,1,140,140,140,5,103,103,103,1,0,0,0,2,255,255, + 255,16,0,0,0,2,255,255,255,16,0,0,0,3,255,255,255,14,138,138, + 138,1,0,0,0,2,255,255,255,16,0,0,0,3,255,255,255,6,140,140, + 140,1,0,0,0,10,255,255,255,2,170,170,170,1,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,1,0,0,0,1,170,170,170,1,255,255, + 255,2,0,0,0,21,255,255,255,14,138,138,138,1,0,0,0,2,255,255, + 255,16,0,0,0,3,255,255,255,6,140,140,140,1,0,0,0,10,255,255, + 255,1,234,234,234,1,21,21,21,1,0,0,0,10,21,21,21,1,234,234, + 234,1,255,255,255,1,0,0,0,21,255,255,255,14,138,138,138,1,0,0, + 0,2,255,255,255,16,0,0,0,3,255,255,255,6,140,140,140,1,0,0, + 0,10,255,255,255,1,85,85,85,1,0,0,0,12,85,85,85,1,255,255, + 255,1,0,0,0,21,2,2,2,1,136,136,136,1,138,138,138,12,136,136, + 136,1,0,0,0,2,255,255,255,1,128,128,128,1,255,255,255,14,0,0, + 0,4,140,140,140,6,0,0,0,209,16,16,16,1,192,192,192,1,255,255, + 255,11,236,236,236,1,0,0,0,3,255,255,255,16,0,0,0,42,61,61, + 61,1,147,147,147,1,209,209,209,2,147,147,147,1,62,62,62,1,0,0, + 0,8,44,44,44,1,230,230,230,1,248,248,248,1,255,255,255,10,254,254, + 254,1,255,255,255,1,0,0,0,3,255,255,255,16,0,0,0,25,8,8, + 8,1,101,101,101,1,149,149,149,1,148,148,148,1,105,105,105,1,10,10, + 10,1,0,0,0,9,12,12,12,1,158,158,158,1,243,243,243,1,254,254, + 254,1,255,255,255,3,248,248,248,1,179,179,179,1,13,13,13,1,0,0, + 0,6,248,248,248,1,255,255,255,14,0,0,0,3,255,255,255,16,0,0, + 0,1,252,252,252,1,237,237,237,16,252,252,252,1,0,0,0,5,29,29, + 29,1,224,224,224,1,255,255,255,1,215,215,215,1,218,218,218,1,255,255, + 255,1,225,225,225,1,36,36,36,1,0,0,0,8,173,173,173,1,247,247, + 247,1,255,255,255,6,251,251,251,1,208,208,208,1,15,15,15,1,0,0, + 0,5,255,255,255,15,0,0,0,3,255,255,255,16,0,0,0,1,237,237, + 237,1,140,140,140,2,146,146,146,2,140,140,140,1,144,144,144,1,142,142, + 142,1,140,140,140,1,141,141,141,1,144,144,144,2,145,145,145,1,140,140, + 140,2,143,143,143,1,144,144,144,1,235,235,235,1,0,0,0,5,185,185, + 185,1,255,255,255,1,199,199,199,1,229,229,229,2,199,199,199,1,254,254, + 254,1,195,195,195,1,0,0,0,7,77,77,77,1,244,244,244,1,255,255, + 255,8,250,250,250,1,153,153,153,1,1,1,1,1,0,0,0,4,255,255, + 255,15,0,0,0,3,255,255,255,16,0,0,0,1,237,237,237,1,140,140, + 140,1,176,176,176,1,235,235,235,1,226,226,226,1,159,159,159,1,172,172, + 172,1,183,183,183,1,140,140,140,1,150,150,150,1,190,190,190,1,186,186, + 186,1,220,220,220,1,142,142,142,1,140,140,140,1,187,187,187,1,190,190, + 190,1,235,235,235,1,0,0,0,4,17,17,17,1,253,253,253,1,255,255, + 255,6,254,254,254,1,13,13,13,1,0,0,0,6,187,187,187,1,255,255, + 255,10,222,222,222,1,56,56,56,1,0,0,0,4,255,255,255,15,0,0, + 0,3,255,255,255,1,250,250,250,1,255,255,255,2,152,152,152,1,159,159, + 159,1,164,164,164,1,255,255,255,1,146,146,146,1,154,154,154,1,158,158, + 158,1,255,255,255,1,148,148,148,1,161,161,161,1,158,158,158,1,255,255, + 255,1,0,0,0,1,237,237,237,1,143,143,143,1,226,226,226,1,148,148, + 148,1,169,169,169,1,196,196,196,1,152,152,152,1,202,202,202,1,148,148, + 148,1,173,173,173,1,187,187,187,2,232,232,232,1,157,157,157,1,140,140, + 140,1,221,221,221,1,195,195,195,1,235,235,235,1,0,0,0,4,62,62, + 62,1,253,253,253,1,255,255,255,7,111,111,111,1,0,0,0,6,237,237, + 237,1,255,255,255,10,247,247,247,1,107,107,107,1,1,1,1,1,0,0, + 0,3,255,255,255,15,0,0,0,3,255,255,255,1,250,250,250,1,255,255, + 255,2,155,155,155,1,178,178,178,1,162,162,162,1,255,255,255,1,164,164, + 164,1,166,166,166,1,169,169,169,1,255,255,255,1,140,140,140,1,162,162, + 162,2,255,255,255,1,0,0,0,1,237,237,237,1,144,144,144,1,219,219, + 219,1,174,174,174,1,150,150,150,1,160,160,160,1,142,142,142,1,191,191, + 191,1,172,172,172,1,212,212,212,1,152,152,152,1,187,187,187,1,207,207, + 207,1,176,176,176,1,147,147,147,1,219,219,219,1,192,192,192,1,235,235, + 235,1,0,0,0,4,175,175,175,1,255,255,255,8,219,219,219,1,32,32, + 32,1,0,0,0,5,247,247,247,1,255,255,255,10,251,251,251,1,132,132, + 132,1,1,1,1,1,0,0,0,3,255,255,255,15,0,0,0,3,255,255, + 255,1,247,247,247,1,255,255,255,2,140,140,140,3,255,255,255,1,144,144, + 144,1,154,154,154,1,159,159,159,1,255,255,255,1,140,140,140,3,255,255, + 255,1,0,0,0,1,237,237,237,1,140,140,140,1,166,166,166,1,221,221, + 221,1,227,227,227,1,160,160,160,1,140,140,140,1,160,160,160,1,229,229, + 229,1,186,186,186,1,140,140,140,1,187,187,187,1,190,190,190,1,187,187, + 187,1,173,173,173,1,192,192,192,2,235,235,235,1,0,0,0,4,229,229, + 229,1,255,255,255,8,243,243,243,1,96,96,96,1,0,0,0,5,206,206, + 206,1,255,255,255,10,233,233,233,1,132,132,132,1,1,1,1,1,0,0, + 0,3,255,255,255,15,0,0,0,3,255,255,255,16,0,0,0,1,237,237, + 237,1,143,143,143,1,147,147,147,1,142,142,142,1,173,173,173,1,218,218, + 218,1,140,140,140,2,228,228,228,1,142,142,142,1,140,140,140,1,187,187, + 187,1,185,185,185,1,186,186,186,1,206,206,206,1,162,162,162,1,192,192, + 192,1,235,235,235,1,0,0,0,4,229,229,229,1,255,255,255,8,243,243, + 243,1,126,126,126,1,0,0,0,5,127,127,127,1,249,249,249,1,255,255, + 255,8,250,250,250,1,197,197,197,1,107,107,107,1,1,1,1,1,0,0, + 0,3,255,255,255,15,0,0,0,3,255,255,255,1,245,245,245,1,255,255, + 255,2,148,148,148,1,153,153,153,1,159,159,159,1,255,255,255,1,148,148, + 148,1,153,153,153,1,159,159,159,1,255,255,255,1,149,149,149,1,153,153, + 153,1,158,158,158,1,255,255,255,1,0,0,0,1,237,237,237,1,154,154, + 154,1,204,204,204,1,142,142,142,1,146,146,146,1,219,219,219,1,140,140, + 140,2,226,226,226,1,141,141,141,1,140,140,140,1,187,187,187,1,179,179, + 179,1,188,188,188,1,214,214,214,1,156,156,156,1,192,192,192,1,235,235, + 235,1,0,0,0,4,175,175,175,1,255,255,255,8,219,219,219,1,126,126, + 126,1,0,0,0,5,7,7,7,1,230,230,230,1,255,255,255,8,247,247, + 247,1,205,205,205,1,63,63,63,1,2,2,2,1,0,0,0,3,255,255, + 255,15,0,0,0,3,255,255,255,1,245,245,245,1,255,255,255,2,163,163, + 163,1,177,177,177,2,255,255,255,1,163,163,163,1,177,177,177,2,255,255, + 255,1,163,163,163,1,181,181,181,1,172,172,172,1,255,255,255,1,0,0, + 0,1,237,237,237,1,142,142,142,1,201,201,201,1,226,226,226,1,221,221, + 221,1,187,187,187,1,140,140,140,2,226,226,226,1,141,141,141,1,140,140, + 140,1,187,187,187,1,175,175,175,1,189,189,189,1,191,191,191,1,156,156, + 156,1,192,192,192,1,235,235,235,1,0,0,0,4,58,58,58,1,254,254, + 254,1,255,255,255,6,254,254,254,1,166,166,166,1,96,96,96,1,0,0, + 0,6,46,46,46,1,241,241,241,1,250,250,250,1,255,255,255,4,250,250, + 250,1,249,249,249,1,255,255,255,2,201,201,201,1,25,25,25,1,0,0, + 0,3,255,255,255,15,0,0,0,3,255,255,255,1,244,244,244,1,255,255, + 255,2,145,145,145,1,149,149,149,1,155,155,155,1,255,255,255,1,145,145, + 145,1,149,149,149,1,155,155,155,1,255,255,255,1,146,146,146,1,149,149, + 149,1,154,154,154,1,255,255,255,1,0,0,0,1,237,237,237,1,140,140, + 140,2,160,160,160,1,162,162,162,1,142,142,142,1,140,140,140,2,158,158, + 158,1,140,140,140,2,150,150,150,1,147,147,147,1,148,148,148,1,146,146, + 146,1,143,143,143,1,151,151,151,1,235,235,235,1,0,0,0,5,137,137, + 137,1,254,254,254,1,255,255,255,4,254,254,254,1,194,194,194,1,139,139, + 139,1,32,32,32,1,0,0,0,7,24,24,24,1,193,193,193,1,244,244, + 244,1,253,253,253,2,245,245,245,1,206,206,206,1,207,207,207,1,255,255, + 255,3,202,202,202,1,16,16,16,1,0,0,0,2,255,255,255,13,248,248, + 248,1,191,191,191,1,0,0,0,3,255,255,255,16,0,0,0,1,237,237, + 237,1,140,140,140,16,235,235,235,1,0,0,0,6,109,109,109,1,219,219, + 219,1,247,247,247,1,246,246,246,1,219,219,219,1,166,166,166,1,139,139, + 139,1,66,66,66,1,0,0,0,9,1,1,1,1,56,56,56,1,118,118, + 118,1,141,141,141,1,132,132,132,1,107,107,107,1,62,62,62,1,197,197, + 197,1,255,255,255,3,179,179,179,1,0,0,0,2,255,255,255,13,239,239, + 239,1,104,104,104,1,7,7,7,1,0,0,0,2,255,255,255,1,239,239, + 239,1,255,255,255,2,148,148,148,1,150,150,150,1,153,153,153,1,255,255, + 255,1,145,145,145,1,150,150,150,2,255,255,255,1,140,140,140,1,153,153, + 153,1,152,152,152,1,255,255,255,1,0,0,0,1,252,252,252,1,235,235, + 235,16,252,252,252,1,0,0,0,7,32,32,32,1,246,246,246,1,239,239, + 239,1,126,126,126,1,96,96,96,1,32,32,32,1,0,0,0,12,1,1, + 1,4,0,0,0,1,16,16,16,1,200,200,200,1,255,255,255,1,253,253, + 253,1,175,175,175,1,0,0,0,2,232,232,232,1,255,255,255,11,252,252, + 252,1,159,159,159,1,42,42,42,1,0,0,0,3,255,255,255,1,241,241, + 241,1,255,255,255,2,166,166,166,1,164,164,164,1,165,165,165,1,255,255, + 255,1,145,145,145,1,165,165,165,1,162,162,162,1,255,255,255,1,143,143, + 143,1,166,166,166,1,195,195,195,1,255,255,255,1,0,0,0,27,120,120, + 120,1,112,112,112,1,0,0,0,21,11,11,11,1,170,170,170,1,168,168, + 168,1,121,121,121,1,0,0,0,2,22,22,22,1,70,70,70,12,49,49, + 49,1,0,0,0,4,255,255,255,1,132,132,132,1,255,255,255,14,0,0, + 0,163,255,255,255,54,0,0,0,36,255,255,255,54,0,0,0,36,255,255, + 255,54,0,0,0,8,7,7,7,2,0,0,0,16,7,7,7,2,0,0, + 0,8,255,255,255,54,0,0,0,6,102,102,102,1,201,201,201,1,220,220, + 220,2,201,201,201,1,102,102,102,1,0,0,0,12,102,102,102,1,201,201, + 201,1,220,220,220,2,201,201,201,1,102,102,102,1,0,0,0,6,255,255, + 255,54,0,0,0,5,166,166,166,1,242,242,242,1,255,255,255,4,247,247, + 247,1,177,177,177,1,0,0,0,10,166,166,166,1,242,242,242,1,255,255, + 255,4,247,247,247,1,177,177,177,1,0,0,0,5,255,255,255,54,0,0, + 0,4,102,102,102,1,242,242,242,1,255,255,255,6,249,249,249,1,142,142, + 142,1,0,0,0,8,102,102,102,1,242,242,242,1,255,255,255,6,249,249, + 249,1,142,142,142,1,0,0,0,4,255,255,255,54,0,0,0,4,201,201, + 201,1,255,255,255,8,230,230,230,1,32,32,32,1,0,0,0,7,201,201, + 201,1,255,255,255,8,230,230,230,1,32,32,32,1,0,0,0,3,255,255, + 255,54,0,0,0,3,7,7,7,1,220,220,220,1,255,255,255,8,239,239, + 239,1,100,100,100,1,0,0,0,6,7,7,7,1,220,220,220,1,255,255, + 255,8,239,239,239,1,100,100,100,1,0,0,0,3,255,255,255,54,0,0, + 0,3,7,7,7,1,220,220,220,1,255,255,255,8,239,239,239,1,130,130, + 130,1,0,0,0,6,7,7,7,1,220,220,220,1,255,255,255,8,239,239, + 239,1,130,130,130,1,0,0,0,3,255,255,255,54,0,0,0,4,201,201, + 201,1,255,255,255,8,231,231,231,1,126,126,126,1,0,0,0,7,201,201, + 201,1,255,255,255,8,231,231,231,1,126,126,126,1,0,0,0,3,255,255, + 255,54,0,0,0,4,102,102,102,1,247,247,247,1,255,255,255,6,249,249, + 249,1,186,186,186,1,96,96,96,1,0,0,0,7,102,102,102,1,247,247, + 247,1,255,255,255,6,249,249,249,1,186,186,186,1,96,96,96,1,0,0, + 0,3,255,255,255,54,0,0,0,5,177,177,177,1,249,249,249,1,255,255, + 255,4,249,249,249,1,215,215,215,1,139,139,139,1,32,32,32,1,0,0, + 0,8,177,177,177,1,249,249,249,1,255,255,255,4,249,249,249,1,215,215, + 215,1,139,139,139,1,32,32,32,1,0,0,0,3,255,255,255,54,0,0, + 0,6,142,142,142,1,230,230,230,1,239,239,239,2,231,231,231,1,186,186, + 186,1,139,139,139,1,66,66,66,1,0,0,0,10,142,142,142,1,230,230, + 230,1,239,239,239,2,231,231,231,1,186,186,186,1,139,139,139,1,66,66, + 66,1,0,0,0,4,255,255,255,54,0,0,0,7,32,32,32,1,100,100, + 100,1,130,130,130,1,126,126,126,1,96,96,96,1,32,32,32,1,0,0, + 0,12,32,32,32,1,100,100,100,1,130,130,130,1,126,126,126,1,96,96, + 96,1,32,32,32,1,0,0,0,5,255,255,255,54,0,0,0,36,255,255, + 255,54,0,0,0,36,255,255,255,54,0,0,0,36,255,255,255,54,0,0, + 10,116,105,109,97,103,101,108,105,115,116,14,100,117,109,109,121,105,109,97, + 103,101,108,105,115,116,5,119,105,100,116,104,2,24,4,108,101,102,116,2, + 120,3,116,111,112,2,64,0,0,10,116,102,114,97,109,101,99,111,109,112, + 8,118,105,101,119,109,101,110,117,4,108,101,102,116,3,208,0,3,116,111, + 112,2,96,0,0,15,116,112,114,111,99,101,115,115,109,111,110,105,116,111, + 114,10,114,117,110,112,114,111,99,109,111,110,11,111,110,99,104,105,108,100, + 100,105,101,100,7,11,114,117,110,112,114,111,99,100,105,101,100,4,108,101, + 102,116,3,192,0,3,116,111,112,2,32,0,0,9,116,114,116,116,105,115, + 116,97,116,11,115,116,97,116,111,112,116,105,111,110,115,12,111,110,103,101, + 116,111,98,106,101,99,116,115,7,11,103,101,116,115,116,97,116,111,98,106, + 115,3,116,111,112,2,96,0,0,11,116,102,105,108,101,100,105,97,108,111, + 103,14,112,114,111,106,101,99,116,102,105,108,101,100,105,97,8,115,116,97, + 116,102,105,108,101,7,15,112,114,111,106,101,99,116,115,116,97,116,102,105, + 108,101,26,99,111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114, + 108,105,115,116,46,100,97,116,97,1,1,6,13,80,114,111,106,101,99,116, + 32,102,105,108,101,115,6,5,42,46,112,114,106,0,1,6,9,65,108,108, + 32,70,105,108,101,115,6,1,42,0,0,21,99,111,110,116,114,111,108,108, + 101,114,46,100,101,102,97,117,108,116,101,120,116,6,3,112,114,106,22,99, + 111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101, + 110,6,12,79,112,101,110,32,80,114,111,106,101,99,116,22,99,111,110,116, + 114,111,108,108,101,114,46,99,97,112,116,105,111,110,115,97,118,101,6,12, + 83,97,118,101,32,80,114,111,106,101,99,116,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112, + 109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13, + 111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104, + 101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97, + 100,0,4,108,101,102,116,3,0,1,3,116,111,112,2,1,0,0,15,116, + 112,105,112,101,114,101,97,100,101,114,99,111,109,112,10,116,97,114,103,101, + 116,112,105,112,101,16,111,110,105,110,112,117,116,97,118,97,105,108,97,98, + 108,101,7,15,116,97,114,103,101,116,112,105,112,101,105,110,112,117,116,4, + 108,101,102,116,3,56,1,3,116,111,112,2,32,0,0,16,116,115,116,114, + 105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110, + 103,115,46,100,97,116,97,1,6,24,85,110,114,101,115,111,108,118,101,100, + 32,114,101,102,101,114,101,110,99,101,115,32,105,110,6,2,116,111,6,35, + 68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,115,101,97,114,99, + 104,32,116,104,101,32,102,111,114,109,102,105,108,101,63,6,7,87,65,82, + 78,73,78,71,6,12,70,111,114,109,102,105,108,101,32,102,111,114,6,9, + 70,111,114,109,102,105,108,101,115,6,30,82,101,99,117,114,115,105,118,101, + 32,102,111,114,109,32,104,105,101,114,97,114,99,104,121,32,102,111,114,32, + 34,6,5,69,82,82,79,82,6,9,67,108,97,115,115,116,121,112,101,6, + 10,110,111,116,32,102,111,117,110,100,46,6,7,80,114,111,106,101,99,116, + 6,18,105,115,32,109,111,100,105,102,105,101,100,46,32,83,97,118,101,63, + 6,12,67,111,110,102,105,114,109,97,116,105,111,110,6,21,85,110,97,98, + 108,101,32,116,111,32,111,112,101,110,32,102,105,108,101,32,34,6,15,42, + 42,42,32,82,117,110,110,105,110,103,32,42,42,42,6,11,68,111,119,110, + 108,111,97,100,105,110,103,6,10,68,111,119,110,108,111,97,100,101,100,6, + 26,83,116,97,114,116,32,103,100,98,32,115,101,114,118,101,114,32,99,111, + 109,109,97,110,100,32,34,6,10,34,32,114,117,110,110,105,110,103,46,6, + 16,83,116,97,114,116,32,103,100,98,32,83,101,114,118,101,114,6,22,103, + 100,98,32,115,101,114,118,101,114,32,115,116,97,114,116,32,101,114,114,111, + 114,6,26,103,100,98,32,115,101,114,118,101,114,32,115,116,97,114,116,32, + 99,97,110,99,101,108,101,100,46,6,30,67,97,110,32,110,111,116,32,114, + 117,110,32,115,116,97,114,116,32,103,100,98,32,99,111,109,109,97,110,100, + 46,6,15,85,112,108,111,97,100,99,111,109,109,97,110,100,32,34,6,20, + 68,111,119,110,108,111,97,100,32,42,42,42,69,82,82,79,82,42,42,42, + 6,18,68,111,119,110,108,111,97,100,32,102,105,110,105,115,104,101,100,46, + 6,18,68,111,119,110,108,111,97,100,32,99,97,110,99,101,108,101,100,46, + 6,6,70,105,108,101,32,34,6,12,34,32,110,111,116,32,102,111,117,110, + 100,46,6,9,34,32,101,120,105,115,116,115,46,6,3,78,101,119,6,15, + 83,101,108,101,99,116,32,97,110,99,101,115,116,111,114,6,8,78,101,119, + 32,102,111,114,109,6,12,80,97,115,99,97,108,32,70,105,108,101,115,6, + 3,110,101,119,6,22,67,97,110,32,110,111,116,32,108,111,97,100,32,80, + 114,111,106,101,99,116,32,34,6,23,83,101,108,101,99,116,32,112,114,111, + 106,101,99,116,32,116,101,109,112,108,97,116,101,6,13,80,114,111,106,101, + 99,116,32,102,105,108,101,115,6,9,65,108,108,32,102,105,108,101,115,6, + 19,83,101,108,101,99,116,32,112,114,111,103,114,97,109,32,102,105,108,101, + 6,20,80,97,115,99,97,108,32,112,114,111,103,114,97,109,32,102,105,108, + 101,115,6,15,67,32,112,114,111,103,114,97,109,32,102,105,108,101,115,6, + 11,78,101,119,32,80,114,111,106,101,99,116,6,21,67,97,110,32,110,111, + 116,32,115,116,97,114,116,32,112,114,111,99,101,115,115,6,7,80,114,111, + 99,101,115,115,6,7,114,117,110,110,105,110,103,6,30,80,114,111,99,101, + 115,115,32,116,101,114,109,105,110,97,116,101,100,46,32,69,120,105,116,99, + 111,100,101,58,32,6,28,80,114,111,99,101,115,115,32,116,101,114,109,105, + 110,97,116,101,100,32,110,111,114,109,97,108,108,121,46,6,16,77,97,107, + 101,32,42,42,42,69,82,82,79,82,42,42,42,6,8,77,97,107,101,32, + 79,75,46,6,50,83,111,117,114,99,101,32,104,97,115,32,99,104,97,110, + 103,101,100,44,32,100,111,32,121,111,117,32,119,105,115,104,32,116,111,32, + 114,101,109,97,107,101,32,112,114,111,106,101,99,116,63,6,18,76,111,97, + 100,32,87,105,110,100,111,119,32,76,97,121,111,117,116,6,12,68,111,99, + 107,105,110,103,32,65,114,101,97,0,4,108,101,102,116,3,0,1,3,116, + 111,112,2,64,0,0,11,116,102,105,108,101,100,105,97,108,111,103,8,111, + 112,101,110,102,111,114,109,8,115,116,97,116,102,105,108,101,7,15,112,114, + 111,106,101,99,116,115,116,97,116,102,105,108,101,26,99,111,110,116,114,111, + 108,108,101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97, + 1,1,6,10,70,111,114,109,32,70,105,108,101,115,6,5,42,46,109,102, + 109,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102,97,117, + 108,116,101,120,116,6,3,109,102,109,18,99,111,110,116,114,111,108,108,101, + 114,46,111,112,116,105,111,110,115,11,14,102,100,111,95,99,104,101,99,107, + 101,120,105,115,116,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97, + 112,116,105,111,110,111,112,101,110,6,14,79,112,101,110,32,70,111,114,109, + 32,70,105,108,101,4,108,101,102,116,2,120,3,116,111,112,2,1,0,0, + 11,116,98,105,116,109,97,112,99,111,109,112,6,102,111,114,109,98,103,17, + 98,105,116,109,97,112,46,111,114,105,103,102,111,114,109,97,116,6,3,112, + 110,103,16,98,105,116,109,97,112,46,97,108,105,103,110,109,101,110,116,11, + 8,97,108,95,116,105,108,101,100,0,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,176,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0, + 16,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8,184,184,184,8, + 199,199,199,8,184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8, + 184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8,184,184,184,8, + 199,199,199,16,184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8, + 184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8,184,184,184,8, + 199,199,199,8,184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8, + 184,184,184,8,4,108,101,102,116,3,56,1,3,116,111,112,2,64,0,0, + 0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/apps/ide/make.pas b/mseide-msegui/apps/ide/make.pas new file mode 100644 index 0000000..a23661b --- /dev/null +++ b/mseide-msegui/apps/ide/make.pas @@ -0,0 +1,566 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit make; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msestrings,msepipestream,msesystypes; + +procedure domake(atag: integer); +procedure abortmake; +function making: boolean; +function buildmakecommandline(const atag: integer): msestring; +function addmessagetext(const sender: tpipereader; + const procid: pprocidty): string; + +procedure dodownload; +procedure abortdownload; +function downloading: boolean; +function downloadresult: integer; +function runscript(const script: filenamety; + const clearscreen,setmakedir: boolean): boolean; + +implementation +uses + mseprocutils,main,projectoptionsform,sysutils,msegrids, + sourceform,mseeditglob,msefileutils,msesys, + msesysutils,msegraphics,messageform,msedesignintf,msedesigner, + mseprocmonitor,mseevent, + classes,mclasses,mseclasses,mseapplication,msestream, + msegui,actionsmodule; + +type + tprogrunner = class(tactcomponent) + private + fexitcode: integer; + fmessagefile: ttextstream; + fnofilecopy: boolean; + ffinished: boolean; + fmessagefinished: boolean; + fsetmakedir: boolean; + messagepipe: tpipereader; + protected + fcanceled: boolean; + procid: integer; + procedure doasyncevent(var atag: integer); override; + procedure inputavailable(const sender: tpipereader); + procedure messagefinished(const sender: tpipereader); + procedure dofinished; virtual; + function getcommandline: msestring; virtual; + procedure runprog(const acommandline: msestring); + public + constructor create(const aowner: tcomponent; + const clearscreen,setmakedir: boolean); reintroduce; + destructor destroy; override; + end; + + tscriptrunner = class(tprogrunner) + private + fscriptpath: filenamety; + protected + function getcommandline: msestring; override; + procedure dofinished; override; + public + constructor create(const aowner: tcomponent; const ascriptpath: filenamety; + const clearscreen,setmakedir: boolean); + property exitcode: integer read fexitcode; + property canceled: boolean read fcanceled; + end; + + makestepty = (maks_before,maks_make,maks_after,maks_finished); + tmaker = class(tprogrunner) + private + ftargettimestamp: tdatetime; + fmaketag: integer; + fstep: makestepty; + fscriptnum: integer; + fcurrentdir: filenamety; + protected + procedure doasyncevent(var atag: integer); override; + procedure dofinished; override; + function getcommandline: msestring; override; + public + constructor create(atag: integer); reintroduce; + end; + + tloader = class(tprogrunner) + protected + procedure dofinished; override; + function getcommandline: msestring; override; + public + constructor create(aowner: tcomponent); + end; + +var + maker: tmaker; + loader: tloader; + +function making: boolean; +begin + result:= (maker <> nil) and (maker.procid <> invalidprochandle); +end; + +function downloading: boolean; +begin + result:= (loader <> nil) and (loader.procid <> invalidprochandle); +end; + +function downloadresult: integer; +begin + result:= -1; + if loader <> nil then begin + result:= loader.fexitcode; + end; +end; + +procedure killmake; +begin + freeandnil(maker); +end; + +procedure killload; +begin + freeandnil(loader); +end; + +procedure domake(atag: integer); +var + bo1: boolean; +begin + killmake; + bo1:= false; + designnotifications.beforemake(idesigner(designer),atag,bo1); + if not bo1 then begin + maker:= tmaker.Create(atag); + if projectoptions.s.closemessages then begin + messagefo.messages.show; + end; + end; +end; + +procedure abortmake; +begin + if maker <> nil then begin + killmake; + mainfo.setstattext(actionsmo.c[ord(ac_makeaborted)],mtk_error); + end; +end; + +procedure abortdownload; +begin + if loader <> nil then begin + killload; + mainfo.setstattext(actionsmo.c[ord(ac_downloadaborted)],mtk_error); + end; +end; + +function buildmakecommandline(const atag: integer): msestring; + + function normalizename(const aname: filenamety): filenamety; + begin + result:= tosysfilepath(filepath(trim(aname),fk_file,true)); + end; + +var + int1,int2,step: integer; + str1,str2,str3: msestring; + ar1: filenamearty; +// wstr1: filenamety; +begin + with projectoptions,k,texp do begin + if makecommand = '' then begin + result:= ''; + exit; + end; + unquotefilename(makecommand,ar1); + if ar1 <> nil then begin + tosysfilepath1(ar1[0]); + end; + str3:= quotefilename(ar1); + str1:= str3; + if (targetfile <> '') and (targpref <> '') then begin + str1:= str1 + ' '+quotefilename(targpref+normalizename(targetfile)); + end; + int2:= high(unitdirs); + int1:= high(unitdirson); + if int1 < int2 then begin + int2:= int1; + end; + if not projectoptions.k.reversepathorder then begin + int1:= int2; + int2:= -1; + step:= -1; + end + else begin + int1:= 0; + int2:= int2+1; + step:= 1; + end; + while int1 <> int2 do begin +// for int1:= int1 to int2 do begin + if (atag and unitdirson[int1] <> 0) and + (unitdirs[int1] <> '') then begin + str2:= normalizename(unitdirs[int1]); + if unitdirson[int1] and $10000 <> 0 then begin + str1:= str1 + ' ' + quotefilename(unitpref+str2); + end; + if unitdirson[int1] and $20000 <> 0 then begin + str1:= str1 + ' ' + quotefilename(incpref+str2); + end; + if unitdirson[int1] and $40000 <> 0 then begin + str1:= str1 + ' ' + quotefilename(libpref+str2); + end; + if unitdirson[int1] and $80000 <> 0 then begin + str1:= str1 + ' ' + quotefilename(objpref+str2); + end; + end; + inc(int1,step); + end; + for int1:= 0 to high(makeoptions) do begin + if makeoptionson[int1] and optaftermainfilemask = 0 then begin + if (atag and makeoptionson[int1] <> 0) and + (makeoptions[int1] <> '') then begin + str1:= str1 + ' ' + makeoptions[int1]; + end; + end; + end; + str1:= str1 + ' ' + quotefilename(normalizename(mainfile)); + for int1:= 0 to high(makeoptions) do begin + if makeoptionson[int1] and optaftermainfilemask <> 0 then begin + if (atag and makeoptionson[int1] <> 0) and + (makeoptions[int1] <> '') then begin + str1:= str1 + ' ' + makeoptions[int1]; + end; + end; + end; + end; + result:= str1; +end; + +procedure dodownload; +begin + killload; + if projectoptions.s.closemessages then begin + messagefo.messages.show; + end; + loader:= tloader.create(nil); +end; + +function runscript(const script: filenamety; + const clearscreen,setmakedir: boolean): boolean; +var + runner: tscriptrunner; +begin + result:= script = ''; + if not result then begin + runner:= tscriptrunner.create(nil,script,clearscreen,setmakedir); + try + result:= not runner.canceled and (runner.fexitcode = 0); + finally + runner.release; + end; + end; +end; + +{ tprogrunner } + +constructor tprogrunner.create(const aowner: tcomponent; + const clearscreen,setmakedir: boolean); +begin + inherited create(aowner); + with projectoptions,s.texp do begin + if s.copymessages and (messageoutputfile <> '') and not fnofilecopy then begin + fmessagefile:= ttextstream.create(messageoutputfile,fm_create); + end; + messagepipe:= tpipereader.create; + messagepipe.oninputavailable:= {$ifdef FPC}@{$endif}inputavailable; + messagepipe.onpipebroken:= {$ifdef FPC}@{$endif}messagefinished; + if clearscreen then begin + messagefo.messages.rowcount:= 0; + end; + procid:= invalidprochandle; + fsetmakedir:= setmakedir; + runprog(getcommandline); + end; +end; + +destructor tprogrunner.destroy; +begin + if (procid <> invalidprochandle) then begin + try + killprocess(procid); + except + end; + procid:= invalidprochandle; + end; + messagepipe.Free; + fmessagefile.free; + inherited; +end; + +procedure tprogrunner.runprog(const acommandline: msestring); +var + wdbefore: filenamety; +begin + if acommandline = '' then begin + fexitcode:= 0; + fmessagefinished:= true; + ffinished:= true; + exit; + end; + fexitcode:= 1; //defaulterror + fmessagefinished:= false; + ffinished:= false; + procid:= invalidprochandle; + with projectoptions,k.texp do begin + if fsetmakedir and (makedir <> '') then begin + wdbefore:= setcurrentdirmse(makedir); + end; + try + procid:= execmse2(msestring(acommandline),nil,messagepipe,messagepipe,-1, + [exo_inactive,exo_tty]); + except + on e1: exception do begin + fcanceled:= true; + if e1 is eoserror then begin +{$warnings off} + fexitcode:= eoserror(e).error; +{$warnings on} + end; + application.handleexception(nil,actionsmo.c[ord(ac_runerrorwith)]+ + msestring(acommandline)+'": '); + end; + end; + if fsetmakedir and (makedir <> '') then begin + setcurrentdirmse(wdbefore); + end; + end; +end; + +procedure tprogrunner.doasyncevent(var atag: integer); +begin + if getprocessexitcode(procid,fexitcode,5000000) <> pee_ok then begin + messagefo.messages.appendrow([actionsmo.c[ord(ac_errortimeout)]]); + messagefo.messages.appendrow(['']); + killprocess(procid); + end; + procid:= invalidprochandle; +end; + +procedure tprogrunner.dofinished; +begin + ffinished:= true; + asyncevent(0); +end; + +procedure tprogrunner.messagefinished(const sender: tpipereader); +begin + fmessagefinished:= true; + dofinished; +end; + +function addmessagetext(const sender: tpipereader; + const procid: pprocidty): string; +var + str1: string; +begin + result:= ''; + str1:= sender.readdatastring; + while application.checkoverload(-1) do begin + if (procid <> nil) and (procid^ = invalidprochandle) then begin + exit; + end; + application.unlock; + sleepus(100000); + application.lock; + end; + messagefo.addtext(str1); + result:= str1; +end; + +procedure tprogrunner.inputavailable(const sender: tpipereader); +var + str1: string; +begin + str1:= addmessagetext(sender,@procid); + if fmessagefile <> nil then begin + fmessagefile.writestr(str1); + end; +end; + +function tprogrunner.getcommandline: msestring; +begin + result:= ''; //dummy +end; + +{ tmaker } + +constructor tmaker.create(atag: integer); +begin + fstep:= maks_before; + fmaketag:= atag; + ftargettimestamp:= getfilemodtime(gettargetfile); + fcurrentdir:= getcurrentdirmse; + inherited create(nil,true,true); + if procid <> invalidprochandle then begin + mainfo.setstattext(actionsmo.c[ord(ac_making)],mtk_running); + messagefo.messages.font.options:= messagefo.messages.font.options + + [foo_nonantialiased]; + end + else begin + mainfo.setstattext(actionsmo.c[ord(ac_makenotrunning)],mtk_error); + designnotifications.aftermake(idesigner(designer),fexitcode); + end; +end; + +procedure tmaker.dofinished; +begin + if ftargettimestamp <> getfilemodtime(gettargetfile) then begin + mainfo.targetfilemodified; + end; + inherited; +end; + +function tmaker.getcommandline: msestring; +begin + result:= ''; + with projectoptions,k do begin + if fstep = maks_before then begin + while fscriptnum <= high(befcommandon) do begin + if (befcommandon[fscriptnum] and fmaketag <> 0) and + (fscriptnum <= high(texp.befcommand)) then begin + result:= k.texp.befcommand[fscriptnum]; + break; + end; + inc(fscriptnum); + end; + if fscriptnum <= high(befcommandon) then begin + inc(fscriptnum); + exit; + end + else begin + fstep:= maks_make; + end; + end; + if fstep = maks_make then begin + result:= buildmakecommandline(fmaketag); + fscriptnum:= 0; + fstep:= maks_after; + exit; + end; + if fstep = maks_after then begin + while fscriptnum <= high(aftcommandon) do begin + if (aftcommandon[fscriptnum] and fmaketag <> 0) and + (fscriptnum <= high(k.texp.aftcommand)) then begin + result:= k.texp.aftcommand[fscriptnum]; + break; + end; + inc(fscriptnum); + end; + if fscriptnum <= high(aftcommandon) then begin + inc(fscriptnum); + exit; + end + else begin + fstep:= maks_finished; + end; + end; + end; +end; + +procedure tmaker.doasyncevent(var atag: integer); + procedure finished; + begin + setcurrentdirmse(fcurrentdir); + designnotifications.aftermake(idesigner(designer),fexitcode); + messagefo.messages.font.options:= messagefo.messages.font.options + + [foo_antialiased2]; + end; +var + str1: msestring; +begin + inherited; + str1:= getcommandline; + if (fstep = maks_finished) or (fexitcode <> 0) then begin + finished; + end + else begin + runprog(str1); + if procid = invalidprochandle then begin + finished; + end; + end; +end; + +{ tloader } + +constructor tloader.create(aowner: tcomponent); +begin + inherited create(aowner,false,true); + if procid <> invalidprochandle then begin + mainfo.setstattext(actionsmo.c[ord(ac_downloading)],mtk_running); + end + else begin + mainfo.setstattext(actionsmo.c[ord(ac_downloadnotrunning)],mtk_error); + end; +end; + +procedure tloader.dofinished; +begin + inherited; +end; + +function tloader.getcommandline: msestring; +begin + result:= projectoptions.d.texp.uploadcommand; +end; + +{ tscriptrunner } + +constructor tscriptrunner.create(const aowner: tcomponent; + const ascriptpath: filenamety; const clearscreen: boolean; + const setmakedir: boolean); +begin + fscriptpath:= tosysfilepath(ascriptpath); + fnofilecopy:= true; + if clearscreen then begin + messagefo.messages.rowcount:= 0; + end; + messagefo.messages.appendrow(ascriptpath); + messagefo.messages.appendrow(''); + inherited create(aowner,false,setmakedir); + if not fcanceled then begin + fcanceled:= not application.waitdialog(nil,'"'+ascriptpath+ + actionsmo.c[ord(ac_running)], + actionsmo.c[ord(ac_script)],nil,nil,nil); + end; +end; + +function tscriptrunner.getcommandline: msestring; +begin + result:= fscriptpath; +end; + +procedure tscriptrunner.dofinished; +begin + inherited; + application.terminatewait; +end; + +end. diff --git a/mseide-msegui/apps/ide/memoryform.mfm b/mseide-msegui/apps/ide/memoryform.mfm new file mode 100644 index 0000000..72f4f96 --- /dev/null +++ b/mseide-msegui/apps/ide/memoryform.mfm @@ -0,0 +1,501 @@ +object memoryfo: tmemoryfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 100 + bounds_y = 100 + bounds_cx = 465 + bounds_cy = 354 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 455 + 354 + ) + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_cansize, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Memory' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 0000000002000000180000001800000068050000000000000000000000000000 + 00000000000000000000000000000000000000007C7C7C17FFFFFF017C7C7C01 + C0C0C004A9A9A901C0C0C005A9A9A901C0C0C005A9A9A901C0C0C005FFFFFF01 + 7C7C7C01C0C0C004A9A9A901C0C0C00182828201ACACAC0186868601B8B8B801 + A9A9A901C0C0C0018E8E8E01A3A3A30185858501B0B0B001A9A9A901C0C0C001 + A4A4A401BEBEBE0186868601B5B5B501FFFFFF017C7C7C01C0C0C0018A8A8A01 + 90909001C0C0C001A9A9A901BFBFBF0182828201BEBEBE0181818101B5B5B501 + A9A9A901B5B5B5016B6B6B018F8F8F01606060019B9B9B01A9A9A901C0C0C001 + 6C6C6C01A7A7A70178787801B2B2B201FFFFFF017C7C7C01BFBFBF0158585801 + 76767601C0C0C001A9A9A901C0C0C001979797019C9C9C0175757501B5B5B501 + A9A9A901C0C0C001888888018E8E8E0188888801A0A0A001A9A9A901C0C0C001 + 8A8A8A01B2B2B201888888019B9B9B01FFFFFF017C7C7C01C0C0C004A9A9A901 + C0C0C005A9A9A901C0C0C005A9A9A901C0C0C005FFFFFF017C7C7C01A9A9A916 + FFFFFF017C7C7C01C0C0C004A9A9A901FFFFFF05A9A9A901FFFFFF05A9A9A901 + FFFFFF067C7C7C01C0C0C004A9A9A901FFFFFF0197979701BABABA018D8D8D01 + F8F8F801A9A9A901FFFFFF01B1B1B101DEDEDE019E9E9E01ECECEC01A9A9A901 + FFFFFF0188888801ECECEC0196969601FFFFFF027C7C7C01C0C0C00182828201 + 91919101C0C0C001A9A9A901FFFFFF017E7E7E01777777018F8F8F01F4F4F401 + A9A9A901EDEDED0168686801ABABAB01B2B2B201A7A7A701A9A9A901FFFFFF01 + 87878701EDEDED0193939301FFFFFF027C7C7C01C0C0C0019898980190909001 + C0C0C001A9A9A901FFFFFF01A1A1A101B2B2B201B3B3B301F6F6F601A9A9A901 + FAFAFA017F7F7F018484840150505001D3D3D301A9A9A901FFFFFF01ABABAB01 + FFFFFF01ABABAB01FFFFFF027C7C7C01C0C0C004A9A9A901FFFFFF05A9A9A901 + FFFFFF05A9A9A901FFFFFF067C7C7C01A9A9A916FFFFFF017C7C7C01C0C0C004 + A9A9A901FFFFFF05A9A9A901FFFFFF05A9A9A901FFFFFF067C7C7C01C0C0C001 + ACACAC01C0C0C002A9A9A901FFFFFF01A0A0A001E3E3E30196969601F3F3F301 + A9A9A901FFFFFF01A1A1A101E2E2E20196969601F1F1F101A9A9A901F8F8F801 + 85858501BABABA0180808001E3E3E301FFFFFF017C7C7C01C0C0C00193939301 + C0C0C002A9A9A901E3E3E301A1A1A10169696901BDBDBD0191919101A9A9A901 + E8E8E8019D9D9D016B6B6B01BABABA0190909001A9A9A901CFCFCF01B7B7B701 + 60606001CCCCCC0199999901FFFFFF017C7C7C01C0C0C00184848401C0C0C002 + A9A9A901FBFBFB01787878018D8D8D0177777701B1B1B101A9A9A901FDFDFD01 + 797979018F8F8F0178787801ADADAD01A9A9A901FDFDFD0185858501AEAEAE01 + 80808001D8D8D801FFFFFF017C7C7C01C0C0C0018F8F8F01C0C0C002A9A9A901 + FFFFFF05A9A9A901FFFFFF05A9A9A901FFFFFF067C7C7C01A9A9A916FFFFFF01 + 7C7C7C01C0C0C004A9A9A901FFFFFF05A9A9A901FFFFFF05A9A9A901FFFFFF06 + 7C7C7C01C0C0C004A9A9A901F3F3F30193939301D8D8D8018C8C8C01FFFFFF01 + A9A9A901FBFBFB018A8A8A01D6D6D601A5A5A501FFFFFF01A9A9A901FFFFFF01 + AAAAAA01D2D2D201BABABA01C7C7C701FFFFFF017C7C7C01C0C0C00190909001 + 7A7A7A01BBBBBB01A9A9A901ABABAB0180808001C0C0C0018F8F8F01FFFFFF01 + A9A9A901F8F8F8018C8C8C01EAEAEA0195959501FFFFFF01A9A9A901FFFFFF01 + BCBCBC01B2B2B20169696901A3A3A301FFFFFF017C7C7C01C0C0C0019D9D9D01 + 7F7F7F01BEBEBE01A9A9A901E7E7E7018D8D8D01C7C7C701ABABAB01FFFFFF01 + A9A9A901FFFFFF01ABABAB01FFFFFF01ABABAB01FFFFFF01A9A9A901FFFFFF01 + DADADA01C1C1C101A0A0A001ABABAB01FFFFFF017C7C7C01FFFFFF17FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + onshow = formshow + moduleclassname = 'tdockform' + object grid: tstringgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 38 + bounds_cx = 455 + bounds_cy = 316 + anchors = [an_top, an_bottom] + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + datacols.count = 16 + datacols.width = 20 + datacols.textflags = [tf_xcentered, tf_ycentered, tf_noselect] + datacols.optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datacols.items = < + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + onsetvalue = cellsetvalue + ondataentered = adent + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end> + fixcols.count = 1 + fixcols.items = < + item + width = 71 + onafterdrawcell = drawfixcol + end> + fixrows.count = 1 + fixrows.items = < + item + height = 18 + captions.count = 16 + captions.items = < + item + caption = '0' + end + item + caption = '1' + end + item + caption = '2' + end + item + caption = '3' + end + item + caption = '4' + end + item + caption = '5' + end + item + caption = '6' + end + item + caption = '7' + end + item + caption = '8' + end + item + caption = '9' + end + item + caption = 'A' + end + item + caption = 'B' + end + item + caption = 'C' + end + item + caption = 'D' + end + item + caption = 'E' + end + item + caption = 'F' + end> + end> + rowcount = 5 + datarowheight = 18 + reffontheight = 16 + end + object tlayouter1: tlayouter + frame.framei_left = 5 + frame.localprops = [frl_fileft] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 433 + bounds_cy = 31 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + place_mindist = 5 + place_maxdist = 5 + linkbottom = grid + dist_bottom = 7 + object add: tint64edit + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + frame.caption = 'Add' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 25 + 0 + ) + taborder = 3 + bounds_x = 5 + bounds_y = 9 + bounds_cx = 143 + bounds_cy = 22 + statfile = mainfo.projectstatfile + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + ondataentered = adent + base = nb_hex + valuemax = -1 + reffontheight = 16 + end + object memon: tbooleanedit + frame.caption = 'Memory &on' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 64 + 3 + ) + bounds_x = 356 + bounds_y = 12 + bounds_cx = 77 + bounds_cy = 18 + statfile = mainfo.projectstatfile + ondataentered = adent + end + object bitwidth: tenumedit + frame.caption = 'Width' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 0 + 35 + 0 + ) + taborder = 1 + bounds_x = 264 + bounds_y = 9 + bounds_cx = 87 + bounds_cy = 22 + statfile = mainfo.projectstatfile + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + ondataentered = updatelayoutexe + dropdown.cols.count = 1 + dropdown.cols.items = < + item + data = ( + '8' + '16' + '32' + '64' + ) + end> + value = 0 + reffontheight = 16 + end + object cnt: tintegeredit + frame.caption = 'Cnt' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 2 + bounds_x = 153 + bounds_y = 9 + bounds_cx = 106 + bounds_cy = 22 + statfile = mainfo.projectstatfile + ondataentered = adent + base = nb_hex + reffontheight = 16 + end + end +end diff --git a/mseide-msegui/apps/ide/memoryform.pas b/mseide-msegui/apps/ide/memoryform.pas new file mode 100644 index 0000000..1b44485 --- /dev/null +++ b/mseide-msegui/apps/ide/memoryform.pas @@ -0,0 +1,254 @@ +unit memoryform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msedock,msegrids,msestrings, + msetypes,msedataedits,mseedit,msegraphedits,msesplitter; + +type + tmemoryfo = class(tdockform) + grid: tstringgrid; + tlayouter1: tlayouter; + memon: tbooleanedit; + bitwidth: tenumedit; + cnt: tintegeredit; + add: tint64edit; + procedure adent(const sender: TObject); + procedure drawfixcol(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty); + procedure updatelayoutexe(const sender: TObject); + procedure formshow(const sender: TObject); + procedure cellsetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + private + firstadd: card64; + fhexwidth: int32; + procedure updatecolwidth(); + public + procedure refresh; + end; +var + memoryfo: tmemoryfo; +implementation +uses + memoryform_mfm,mseformatstr,msedrawtext,main,msegdbutils,msewidgets; + +type + bitwidthty = (bw_8,bw_16,bw_32,bw_64); + +procedure tmemoryfo.adent(const sender: TObject); +begin + updatelayoutexe(nil); +end; + +procedure tmemoryfo.refresh; +var + linecount: integer; + int1,int2,int3: integer; + bytes: bytearty; + words: wordarty; + longwords: longwordarty; + qwords: card64arty; +begin + add.bitcount:= mainfo.gdb.pointersize*8; + updatecolwidth(); + if memon.value and isvisible then begin + firstadd:= add.value and $fffffffffffffff0; + linecount:= ((add.value + cnt.value + $f)-firstadd) div $10; + if linecount < 0 then begin + linecount:= 0; + cnt.value:= 0; + end; + if (linecount > 1000) then begin + linecount:= 1000; + cnt.value:= linecount * $10; + end; + grid.rowcount:= linecount; + if mainfo.gdb.cancommand then begin + case bitwidthty(bitwidth.value) of + bw_8: begin + bytes:= nil; + mainfo.gdb.readmemorybytes(add.value,cnt.value,bytes); + int3:= -(add.value and $f); + for int1:= 0 to linecount-1 do begin //todo: optimize + for int2:= 0 to 15 do begin + if (int3 < 0) or (int3 > high(bytes)) then begin + grid[int2][int1]:= ''; + end + else begin + grid[int2][int1]:= hextostrmse(bytes[int3],2); + end; + inc(int3); + end; + end; + end; + bw_16: begin + words:= nil; + mainfo.gdb.readmemorywords(add.value,cnt.value div 2,words); + int3:= -(add.value and $f) div 2; + for int1:= 0 to linecount-1 do begin //todo: optimize + for int2:= 0 to 7 do begin + if (int3 < 0) or (int3 > high(words)) then begin + grid[int2][int1]:= ''; + end + else begin + grid[int2][int1]:= hextostrmse(words[int3],4); + end; + inc(int3); + end; + end; + end; + bw_32: begin + longwords:= nil; + mainfo.gdb.readmemorylongwords(add.value,cnt.value div 4,longwords); + int3:= -(add.value and $f) div 4; + for int1:= 0 to linecount-1 do begin //todo: optimize + for int2:= 0 to 3 do begin + if (int3 < 0) or (int3 > high(longwords)) then begin + grid[int2][int1]:= ''; + end + else begin + grid[int2][int1]:= hextostrmse(longwords[int3],8); + end; + inc(int3); + end; + end; + end; + bw_64: begin + qwords:= nil; + mainfo.gdb.readmemoryqwords(add.value,cnt.value div 8,qwords); + int3:= -(add.value and $f) div 8; + for int1:= 0 to linecount-1 do begin //todo: optimize + for int2:= 0 to 1 do begin + if (int3 < 0) or (int3 > high(qwords)) then begin + grid[int2][int1]:= ''; + end + else begin + grid[int2][int1]:= hextostrmse(qwords[int3],16); + end; + inc(int3); + end; + end; + end; + end; + end; + grid.invalidate; + end + else begin + grid.rowcount:= 0; + end; +end; + +procedure tmemoryfo.drawfixcol(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty); +begin + drawtext(canvas,hextostrmse(card64(firstadd+cellinfo.cell.row*16),fhexwidth), + cellinfo.innerrect); +end; + +procedure tmemoryfo.updatecolwidth(); +var + mstr1: msestring; +begin + if mainfo.gdb.pointersize = 8 then begin + mstr1:= 'WWWWWWWWWWWWWWWW'; + fhexwidth:= 16; + end + else begin + mstr1:= 'WWWWWWWW'; + fhexwidth:= 8; + end; + grid.fixcols[-1].width:= getcanvas.getstringwidth(mstr1,grid.font)+4; +end; + +procedure tmemoryfo.updatelayoutexe(const sender: TObject); +var + int1: integer; + mstr1: msestring; +begin + mstr1:= ''; + case bitwidthty(bitwidth.value) of + bw_8: begin + mstr1:= 'WW'; + grid.datacols.count:= 16; + for int1:= 0 to 15 do begin + grid.fixrows[-1].captions[int1].caption:= msechar(charhex[int1]); +// grid.datacols[int1].ondataentered:= {$ifdef FPC}@{$endif}celldataentered; + grid.datacols[int1].onsetvalue:= {$ifdef FPC}@{$endif}cellsetvalue; + end; + end; + bw_16: begin + mstr1:= 'WWWW'; + grid.datacols.count:= 8; + for int1:= 0 to 7 do begin + grid.fixrows[-1].captions[int1].caption:= msechar(charhex[int1*2]); +// grid.datacols[int1].ondataentered:= {$ifdef FPC}@{$endif}celldataentered; + grid.datacols[int1].onsetvalue:= {$ifdef FPC}@{$endif}cellsetvalue; + end; + add.value:= add.value and not 3; + end; + bw_32: begin + mstr1:= 'WWWWWWWW'; + grid.datacols.count:= 4; + for int1:= 0 to 3 do begin + grid.fixrows[-1].captions[int1].caption:= msechar(charhex[int1*4]); +// grid.datacols[int1].ondataentered:= {$ifdef FPC}@{$endif}celldataentered; + grid.datacols[int1].onsetvalue:= {$ifdef FPC}@{$endif}cellsetvalue; + end; + add.value:= add.value and not 7; + end; + bw_64: begin + mstr1:= 'WWWWWWWWWWWWWWWW'; + grid.datacols.count:= 2; + for int1:= 0 to 1 do begin + grid.fixrows[-1].captions[int1].caption:= msechar(charhex[int1*8]); +// grid.datacols[int1].ondataentered:= {$ifdef FPC}@{$endif}celldataentered; + grid.datacols[int1].onsetvalue:= {$ifdef FPC}@{$endif}cellsetvalue; + end; + add.value:= add.value and not 15; + end; + end; + int1:= getcanvas.getstringwidth(mstr1,grid.font); + grid.datacols.width:= int1+4; + updatecolwidth(); + refresh; +end; + +procedure tmemoryfo.formshow(const sender: TObject); +begin + refresh; +end; + +procedure tmemoryfo.cellsetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); +var + val: card64; + res: gdbresultty; +begin + if mainfo.gdb.cancommand then begin + accept:= false; + val:= strtohex64(ansistring(avalue)); + res:= gdb_error; + case bitwidthty(bitwidth.value) of + bw_8: begin + res:= mainfo.gdb.writememory8(firstadd+grid.row*16+grid.col*8,val); + end; + bw_16: begin + res:= mainfo.gdb.writememory16(firstadd+grid.row*16+grid.col*2,val); + end; + bw_32: begin + res:= mainfo.gdb.writememory32(firstadd+grid.row*16+grid.col*4,val); + end; + bw_64: begin + res:= mainfo.gdb.writememory64(firstadd+grid.row*16+grid.col*8,val); + end; + end; + if res <> gdb_ok then begin + showerror(msestring(mainfo.gdb.errormessage)); + end; + refresh; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/memoryform_mfm.pas b/mseide-msegui/apps/ide/memoryform_mfm.pas new file mode 100644 index 0000000..23461d4 --- /dev/null +++ b/mseide-msegui/apps/ide/memoryform_mfm.pas @@ -0,0 +1,453 @@ +unit memoryform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,memoryform; + +const + objdata: record size: integer; data: array[0..8712] of byte end = + (size: 8713; data: ( + 84,80,70,48,9,116,109,101,109,111,114,121,102,111,8,109,101,109,111,114, + 121,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102, + 111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95, + 104,105,110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105, + 122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105, + 111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16, + 103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95, + 102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117, + 116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117, + 116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110, + 14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,100,8,98,111,117, + 110,100,115,95,121,2,100,9,98,111,117,110,100,115,95,99,120,3,209,1, + 9,98,111,117,110,100,115,95,99,121,3,98,1,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110, + 101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,199,1,3,98,1, + 0,20,100,114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111, + 99,107,11,10,111,100,95,115,97,118,101,112,111,115,13,111,100,95,115,97, + 118,101,122,111,114,100,101,114,10,111,100,95,99,97,110,109,111,118,101,10, + 111,100,95,99,97,110,115,105,122,101,11,111,100,95,99,97,110,102,108,111, + 97,116,10,111,100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111, + 112,115,105,122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116, + 13,111,100,95,99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105, + 111,110,115,11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115, + 97,118,101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97, + 116,101,0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112, + 116,105,111,110,6,6,77,101,109,111,114,121,21,105,99,111,110,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,12, + 105,99,111,110,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,0,10,105,99,111,110,46,105,109,97,103,101,10,252,5,0, + 0,0,0,0,0,2,0,0,0,24,0,0,0,24,0,0,0,104,5,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,124,124,124,23,255,255,255, + 1,124,124,124,1,192,192,192,4,169,169,169,1,192,192,192,5,169,169,169, + 1,192,192,192,5,169,169,169,1,192,192,192,5,255,255,255,1,124,124,124, + 1,192,192,192,4,169,169,169,1,192,192,192,1,130,130,130,1,172,172,172, + 1,134,134,134,1,184,184,184,1,169,169,169,1,192,192,192,1,142,142,142, + 1,163,163,163,1,133,133,133,1,176,176,176,1,169,169,169,1,192,192,192, + 1,164,164,164,1,190,190,190,1,134,134,134,1,181,181,181,1,255,255,255, + 1,124,124,124,1,192,192,192,1,138,138,138,1,144,144,144,1,192,192,192, + 1,169,169,169,1,191,191,191,1,130,130,130,1,190,190,190,1,129,129,129, + 1,181,181,181,1,169,169,169,1,181,181,181,1,107,107,107,1,143,143,143, + 1,96,96,96,1,155,155,155,1,169,169,169,1,192,192,192,1,108,108,108, + 1,167,167,167,1,120,120,120,1,178,178,178,1,255,255,255,1,124,124,124, + 1,191,191,191,1,88,88,88,1,118,118,118,1,192,192,192,1,169,169,169, + 1,192,192,192,1,151,151,151,1,156,156,156,1,117,117,117,1,181,181,181, + 1,169,169,169,1,192,192,192,1,136,136,136,1,142,142,142,1,136,136,136, + 1,160,160,160,1,169,169,169,1,192,192,192,1,138,138,138,1,178,178,178, + 1,136,136,136,1,155,155,155,1,255,255,255,1,124,124,124,1,192,192,192, + 4,169,169,169,1,192,192,192,5,169,169,169,1,192,192,192,5,169,169,169, + 1,192,192,192,5,255,255,255,1,124,124,124,1,169,169,169,22,255,255,255, + 1,124,124,124,1,192,192,192,4,169,169,169,1,255,255,255,5,169,169,169, + 1,255,255,255,5,169,169,169,1,255,255,255,6,124,124,124,1,192,192,192, + 4,169,169,169,1,255,255,255,1,151,151,151,1,186,186,186,1,141,141,141, + 1,248,248,248,1,169,169,169,1,255,255,255,1,177,177,177,1,222,222,222, + 1,158,158,158,1,236,236,236,1,169,169,169,1,255,255,255,1,136,136,136, + 1,236,236,236,1,150,150,150,1,255,255,255,2,124,124,124,1,192,192,192, + 1,130,130,130,1,145,145,145,1,192,192,192,1,169,169,169,1,255,255,255, + 1,126,126,126,1,119,119,119,1,143,143,143,1,244,244,244,1,169,169,169, + 1,237,237,237,1,104,104,104,1,171,171,171,1,178,178,178,1,167,167,167, + 1,169,169,169,1,255,255,255,1,135,135,135,1,237,237,237,1,147,147,147, + 1,255,255,255,2,124,124,124,1,192,192,192,1,152,152,152,1,144,144,144, + 1,192,192,192,1,169,169,169,1,255,255,255,1,161,161,161,1,178,178,178, + 1,179,179,179,1,246,246,246,1,169,169,169,1,250,250,250,1,127,127,127, + 1,132,132,132,1,80,80,80,1,211,211,211,1,169,169,169,1,255,255,255, + 1,171,171,171,1,255,255,255,1,171,171,171,1,255,255,255,2,124,124,124, + 1,192,192,192,4,169,169,169,1,255,255,255,5,169,169,169,1,255,255,255, + 5,169,169,169,1,255,255,255,6,124,124,124,1,169,169,169,22,255,255,255, + 1,124,124,124,1,192,192,192,4,169,169,169,1,255,255,255,5,169,169,169, + 1,255,255,255,5,169,169,169,1,255,255,255,6,124,124,124,1,192,192,192, + 1,172,172,172,1,192,192,192,2,169,169,169,1,255,255,255,1,160,160,160, + 1,227,227,227,1,150,150,150,1,243,243,243,1,169,169,169,1,255,255,255, + 1,161,161,161,1,226,226,226,1,150,150,150,1,241,241,241,1,169,169,169, + 1,248,248,248,1,133,133,133,1,186,186,186,1,128,128,128,1,227,227,227, + 1,255,255,255,1,124,124,124,1,192,192,192,1,147,147,147,1,192,192,192, + 2,169,169,169,1,227,227,227,1,161,161,161,1,105,105,105,1,189,189,189, + 1,145,145,145,1,169,169,169,1,232,232,232,1,157,157,157,1,107,107,107, + 1,186,186,186,1,144,144,144,1,169,169,169,1,207,207,207,1,183,183,183, + 1,96,96,96,1,204,204,204,1,153,153,153,1,255,255,255,1,124,124,124, + 1,192,192,192,1,132,132,132,1,192,192,192,2,169,169,169,1,251,251,251, + 1,120,120,120,1,141,141,141,1,119,119,119,1,177,177,177,1,169,169,169, + 1,253,253,253,1,121,121,121,1,143,143,143,1,120,120,120,1,173,173,173, + 1,169,169,169,1,253,253,253,1,133,133,133,1,174,174,174,1,128,128,128, + 1,216,216,216,1,255,255,255,1,124,124,124,1,192,192,192,1,143,143,143, + 1,192,192,192,2,169,169,169,1,255,255,255,5,169,169,169,1,255,255,255, + 5,169,169,169,1,255,255,255,6,124,124,124,1,169,169,169,22,255,255,255, + 1,124,124,124,1,192,192,192,4,169,169,169,1,255,255,255,5,169,169,169, + 1,255,255,255,5,169,169,169,1,255,255,255,6,124,124,124,1,192,192,192, + 4,169,169,169,1,243,243,243,1,147,147,147,1,216,216,216,1,140,140,140, + 1,255,255,255,1,169,169,169,1,251,251,251,1,138,138,138,1,214,214,214, + 1,165,165,165,1,255,255,255,1,169,169,169,1,255,255,255,1,170,170,170, + 1,210,210,210,1,186,186,186,1,199,199,199,1,255,255,255,1,124,124,124, + 1,192,192,192,1,144,144,144,1,122,122,122,1,187,187,187,1,169,169,169, + 1,171,171,171,1,128,128,128,1,192,192,192,1,143,143,143,1,255,255,255, + 1,169,169,169,1,248,248,248,1,140,140,140,1,234,234,234,1,149,149,149, + 1,255,255,255,1,169,169,169,1,255,255,255,1,188,188,188,1,178,178,178, + 1,105,105,105,1,163,163,163,1,255,255,255,1,124,124,124,1,192,192,192, + 1,157,157,157,1,127,127,127,1,190,190,190,1,169,169,169,1,231,231,231, + 1,141,141,141,1,199,199,199,1,171,171,171,1,255,255,255,1,169,169,169, + 1,255,255,255,1,171,171,171,1,255,255,255,1,171,171,171,1,255,255,255, + 1,169,169,169,1,255,255,255,1,218,218,218,1,193,193,193,1,160,160,160, + 1,171,171,171,1,255,255,255,1,124,124,124,1,255,255,255,23,255,255,255, + 0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255, + 0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255, + 0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255, + 0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255, + 0,255,255,255,0,255,255,255,0,255,255,255,0,6,111,110,115,104,111,119, + 7,8,102,111,114,109,115,104,111,119,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,11,116, + 115,116,114,105,110,103,103,114,105,100,4,103,114,105,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,38,9,98,111,117, + 110,100,115,95,99,120,3,199,1,9,98,111,117,110,100,115,95,99,121,3, + 60,1,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97, + 110,95,98,111,116,116,111,109,0,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,14,100,97,116,97,99,111, + 108,115,46,99,111,117,110,116,2,16,14,100,97,116,97,99,111,108,115,46, + 119,105,100,116,104,2,20,18,100,97,116,97,99,111,108,115,46,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100, + 12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115, + 101,108,101,99,116,0,20,100,97,116,97,99,111,108,115,46,111,112,116,105, + 111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110, + 101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110, + 99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114, + 101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,14,100,97,116,97,99,111,108,115,46, + 105,116,101,109,115,14,1,5,119,105,100,116,104,2,20,9,116,101,120,116, + 102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12, + 116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101, + 108,101,99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115, + 99,111,101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101,95,102, + 111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101, + 14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99,111,101, + 95,97,117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 13,100,97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6,0,6, + 0,6,0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48, + 9,118,97,108,117,101,116,114,117,101,6,1,49,10,111,110,115,101,116,118, + 97,108,117,101,7,12,99,101,108,108,115,101,116,118,97,108,117,101,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,5,97,100,101,110,116,0, + 1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110, + 100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101, + 116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95, + 101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108, + 105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0, + 10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101, + 116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101, + 100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111, + 115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101, + 95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108, + 117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6, + 0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6, + 1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105, + 100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114, + 101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110, + 101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110, + 99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114, + 101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46, + 100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108, + 117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101, + 6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102, + 95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101, + 99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111, + 101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114, + 99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115, + 99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100, + 97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6, + 0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2, + 20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110, + 116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116, + 102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26, + 115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99, + 107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114, + 110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97, + 1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97, + 108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0, + 1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110, + 100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101, + 116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95, + 101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108, + 105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0, + 10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101, + 116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101, + 100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111, + 115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101, + 95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108, + 117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6, + 0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6, + 1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105, + 100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114, + 101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110, + 101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110, + 99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114, + 101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46, + 100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108, + 117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101, + 6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102, + 95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101, + 99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111, + 101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114, + 99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115, + 99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100, + 97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6, + 0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2, + 20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110, + 116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116, + 102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26, + 115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99, + 107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114, + 110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97, + 1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97, + 108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0, + 1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110, + 100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101, + 116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95, + 101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108, + 105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0, + 10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101, + 116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101, + 100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111, + 115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101, + 95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108, + 117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6, + 0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6, + 1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105, + 100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114, + 101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110, + 101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110, + 99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114, + 101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46, + 100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108, + 117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101, + 6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102, + 95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101, + 99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111, + 101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114, + 99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115, + 99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100, + 97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6, + 0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2, + 20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110, + 116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116, + 102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26, + 115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99, + 107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114, + 110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97, + 1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97, + 108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0, + 0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105, + 120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2, + 71,15,111,110,97,102,116,101,114,100,114,97,119,99,101,108,108,7,10,100, + 114,97,119,102,105,120,99,111,108,0,0,13,102,105,120,114,111,119,115,46, + 99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109, + 115,14,1,6,104,101,105,103,104,116,2,18,14,99,97,112,116,105,111,110, + 115,46,99,111,117,110,116,2,16,14,99,97,112,116,105,111,110,115,46,105, + 116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,1,48,0,1,7, + 99,97,112,116,105,111,110,6,1,49,0,1,7,99,97,112,116,105,111,110, + 6,1,50,0,1,7,99,97,112,116,105,111,110,6,1,51,0,1,7,99, + 97,112,116,105,111,110,6,1,52,0,1,7,99,97,112,116,105,111,110,6, + 1,53,0,1,7,99,97,112,116,105,111,110,6,1,54,0,1,7,99,97, + 112,116,105,111,110,6,1,55,0,1,7,99,97,112,116,105,111,110,6,1, + 56,0,1,7,99,97,112,116,105,111,110,6,1,57,0,1,7,99,97,112, + 116,105,111,110,6,1,65,0,1,7,99,97,112,116,105,111,110,6,1,66, + 0,1,7,99,97,112,116,105,111,110,6,1,67,0,1,7,99,97,112,116, + 105,111,110,6,1,68,0,1,7,99,97,112,116,105,111,110,6,1,69,0, + 1,7,99,97,112,116,105,111,110,6,1,70,0,0,0,0,8,114,111,119, + 99,111,117,110,116,2,5,13,100,97,116,97,114,111,119,104,101,105,103,104, + 116,2,18,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101, + 114,49,17,102,114,97,109,101,46,102,114,97,109,101,105,95,108,101,102,116, + 2,5,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,102,105,108,101,102,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,177,1,9,98, + 111,117,110,100,115,95,99,121,2,31,12,111,112,116,105,111,110,115,115,99, + 97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99, + 95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121, + 11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110, + 115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,120,10, + 108,97,111,95,97,108,105,103,110,121,0,13,112,108,97,99,101,95,109,105, + 110,100,105,115,116,2,5,13,112,108,97,99,101,95,109,97,120,100,105,115, + 116,2,5,10,108,105,110,107,98,111,116,116,111,109,7,4,103,114,105,100, + 11,100,105,115,116,95,98,111,116,116,111,109,2,7,0,10,116,105,110,116, + 54,52,101,100,105,116,3,97,100,100,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101, + 13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,3,65,100,100,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,25,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,2,5,8,98,111,117,110,100,115,95,121,2,9, + 9,98,111,117,110,100,115,95,99,120,3,143,0,9,98,111,117,110,100,115, + 95,99,121,2,22,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110, + 102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,24,111,101,95,102,111,114,99,101,114, + 101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22, + 111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110, + 108,121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,5,97,100, + 101,110,116,4,98,97,115,101,7,6,110,98,95,104,101,120,8,118,97,108, + 117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,5,109, + 101,109,111,110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10, + 77,101,109,111,114,121,32,38,111,110,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,2,2,64,2,3,0,8,98,111,117, + 110,100,115,95,120,3,100,1,8,98,111,117,110,100,115,95,121,2,12,9, + 98,111,117,110,100,115,95,99,120,2,77,9,98,111,117,110,100,115,95,99, + 121,2,18,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,13,111,110,100, + 97,116,97,101,110,116,101,114,101,100,7,5,97,100,101,110,116,0,0,9, + 116,101,110,117,109,101,100,105,116,8,98,105,116,119,105,100,116,104,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,5,87,105,100,116,104,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4, + 2,0,0,128,0,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,0,2,35,2,0,0,8,116,97,98,111,114,100, + 101,114,2,1,8,98,111,117,110,100,115,95,120,3,8,1,8,98,111,117, + 110,100,115,95,121,2,9,9,98,111,117,110,100,115,95,99,120,2,87,9, + 98,111,117,110,100,115,95,99,121,2,22,8,115,116,97,116,102,105,108,101, + 7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116, + 102,105,108,101,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120, + 99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101, + 100,11,116,102,95,110,111,115,101,108,101,99,116,0,13,111,110,100,97,116, + 97,101,110,116,101,114,101,100,7,15,117,112,100,97,116,101,108,97,121,111, + 117,116,101,120,101,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46, + 99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,105,116,101,109,115,14,1,4,100,97,116,97,1,6,1,56,6,2, + 49,54,6,2,51,50,6,2,54,52,0,0,0,5,118,97,108,117,101,2, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,3,99,110,116,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,67,110,116,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,0,2,22,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8, + 98,111,117,110,100,115,95,120,3,153,0,8,98,111,117,110,100,115,95,121, + 2,9,9,98,111,117,110,100,115,95,99,120,2,106,9,98,111,117,110,100, + 115,95,99,121,2,22,8,115,116,97,116,102,105,108,101,7,22,109,97,105, + 110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,13, + 111,110,100,97,116,97,101,110,116,101,114,101,100,7,5,97,100,101,110,116, + 4,98,97,115,101,7,6,110,98,95,104,101,120,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmemoryfo,''); +end. diff --git a/mseide-msegui/apps/ide/menusdesign.pas b/mseide-msegui/apps/ide/menusdesign.pas new file mode 100644 index 0000000..ef72cbc --- /dev/null +++ b/mseide-msegui/apps/ide/menusdesign.pas @@ -0,0 +1,51 @@ +{ MSEide Copyright (c) 2017 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit menusdesign; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + msemenus,msemenuwidgets,msegui,mclasses,mseclasses,formdesigner, + objectinspector,msearrayutils,msetypes,mseformatstr; + +procedure domenuexe(const sender: tmenuitem); +var + f1: tformdesignerfo; + ar1: msestringarty; + item1: tmenuitem; +begin + f1:= getdesignform(sender.owner); + if f1 <> nil then begin + f1.clearselection(); + f1.selectcomponent(sender.owner); + item1:= sender; + ar1:= nil; //compiler warning + insertitem(ar1,0,'menu'); + while item1.parentmenu <> nil do begin + insertitem(ar1,1,'submenu.count'); + insertitem(ar1,2,'Item '+inttostrmse(item1.index)); + item1:= item1.parentmenu; + end; + if objectinspectorfo.selectprop(ar1,0,true) then begin + objectinspectorfo.asyncactivate(); + end; + end; +end; + +initialization + menuexehandlerdesign:= @domenuexe; +end. diff --git a/mseide-msegui/apps/ide/messageform.mfm b/mseide-msegui/apps/ide/messageform.mfm new file mode 100644 index 0000000..363b6ea --- /dev/null +++ b/mseide-msegui/apps/ide/messageform.mfm @@ -0,0 +1,102 @@ +object messagefo: tmessagefo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 100 + bounds_y = 100 + bounds_cx = 491 + bounds_cy = 317 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 481 + 317 + ) + dragdock.caption = 'Messages' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + icon.image = { + 000000000000000018000000180000001C030000000000000000000000000000 + 00000000000000000000000000000000000000007C7C7C17FFFFFF017C7C7C01 + EAEAEA16FFFFFF017C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16FFFFFF01 + 7C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16 + FFFFFF017C7C7C01EAEAEA02E3E3E301AFAFAF01C7C7C701EAEAEA04C9C9C901 + B1B1B101EAEAEA01E0E0E001AFAFAF05B3B3B301EAEAEA03FFFFFF017C7C7C01 + EAEAEA02CCCCCC01000000012C2C2C01EAEAEA043131310106060601EAEAEA01 + C0C0C00102020201323232043C3C3C01EAEAEA03FFFFFF017C7C7C01EAEAEA02 + CCCCCC01060606011E1E1E01C9C9C901EAEAEA02CBCBCB011D1D1D0106060601 + EAEAEA01C0C0C0010C0C0C01EAEAEA08FFFFFF017C7C7C01EAEAEA02CCCCCC01 + 060606016C6C6C017B7B7B01EAEAEA027A7A7A016D6D6D0106060601EAEAEA01 + C0C0C0010C0C0C01EAEAEA08FFFFFF017C7C7C01EAEAEA02CCCCCC0106060601 + BCBCBC012D2D2D01EAEAEA022C2C2C01BDBDBD0106060601EAEAEA01C0C0C001 + 04040401575757048D8D8D01EAEAEA03FFFFFF017C7C7C01EAEAEA02CCCCCC01 + 06060601EAEAEA0121212101CACACA01C3C3C3013C3C3C01D4D4D40106060601 + EAEAEA01C0C0C0010707070192929204B2B2B201EAEAEA03FFFFFF017C7C7C01 + EAEAEA02CCCCCC0106060601EAEAEA01707070017C7C7C01737373018D8D8D01 + D4D4D40106060601EAEAEA01C0C0C0010C0C0C01EAEAEA08FFFFFF017C7C7C01 + EAEAEA02CCCCCC0106060601EAEAEA01BFBFBF013030300128282801DADADA01 + D4D4D40106060601EAEAEA01C0C0C0010C0C0C01EAEAEA08FFFFFF017C7C7C01 + EAEAEA02CCCCCC0106060601EAEAEA022424240147474701EAEAEA01D4D4D401 + 06060601EAEAEA01C0C0C001030303013A3A3A05CCCCCC01EAEAEA02FFFFFF01 + 7C7C7C01EAEAEA02E3E3E301B1B1B101EAEAEA02C5C5C501CECECE01EAEAEA01 + E4E4E401B1B1B101EAEAEA01E0E0E001AFAFAF06E1E1E101EAEAEA02FFFFFF01 + 7C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16 + FFFFFF017C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16FFFFFF017C7C7C01 + EAEAEA16FFFFFF017C7C7C01FFFFFF17 + } + moduleclassname = 'tdockform' + object messages: tstringgrid + frame.localprops = [] + frame.localprops1 = [] + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 481 + bounds_cy = 317 + anchors = [] + font.name = 'stf_default' + font.options = [foo_antialiased] + font.xscale = 1 + font.localprops = [flp_xscale] + datacols.count = 1 + datacols.linewidth = 0 + datacols.items = < + item + linecolorfix = -1610612733 + width = 3000 + options = [co_readonly, co_drawfocus, co_leftbuttonfocusonly, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_cancopy, co_mousescrollrow] + optionsedit = [] + valuefalse = '0' + valuetrue = '1' + end> + rowcountmax = 5000 + rowcolors.count = 3 + rowcolors.items = ( + -1610612712 + -1610612717 + -1610612716 + ) + datarowlinewidth = 0 + datarowheight = 16 + oncellevent = messagesoncellevent + reffontheight = 14 + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Copy to clipboard' + state = [as_localcaption, as_localonexecute] + onexecute = copyexe + end> + left = 88 + top = 72 + end +end diff --git a/mseide-msegui/apps/ide/messageform.pas b/mseide-msegui/apps/ide/messageform.pas new file mode 100644 index 0000000..ea38362 --- /dev/null +++ b/mseide-msegui/apps/ide/messageform.pas @@ -0,0 +1,143 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit messageform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msegui,mseclasses,mseforms,msegrids,msemenus,msedataedits, + msesimplewidgets,classes,mclasses,projectoptionsform; + +type + tmessagefo = class(tdockform) + messages: tstringgrid; + tpopupmenu1: tpopupmenu; + procedure messagesoncellevent(const sender: tobject; + var info: celleventinfoty); + procedure copyexe(const sender: TObject); + private + fcolorrow: integer; + public + constructor create(aowner: tcomponent); override; + procedure addtext(const atext: string); + procedure updateprojectoptions; + end; + +var + messagefo: tmessagefo; + +implementation +uses + messageform_mfm,sourcepage,sourceform,msewidgets,msestrings,msedatalist; + +constructor tmessagefo.create(aowner: tcomponent); +begin + fcolorrow:= -1; + inherited create(aowner); +end; + +procedure tmessagefo.messagesoncellevent(const sender: tobject; + var info: celleventinfoty); +var + page: tsourcepage; +begin + if (info.cell.row >= 0) and iscellclick(info,[ccr_dblclick]) then begin + locateerrormessage( + messagefo.messages[0].datalist.getparagraph(info.cell.row),page); + end; +end; + +procedure tmessagefo.copyexe(const sender: TObject); +begin + copytoclipboard(messages.datacols[0].datalist.concatstring('',lineend)); +end; + +procedure tmessagefo.addtext(const atext: string); +var + int1,int2: integer; + lev1: errorlevelty; + col1,row1: integer; + fn1: filenamety; + strcol1: tstringcol; + rowhigh1: integer; + + procedure setrowcolor(const arowcolor: rowstatenumty); + var + int2: integer; + begin + messages.rowcolorstate[int1]:= arowcolor; + for int2:= int1 + 1 to rowhigh1 do begin + if strcol1.noparagraph[int2] then begin + messages.rowcolorstate[int2]:= arowcolor; + end + else begin + break; + end; + end; + end; //setrowcolor + +var + opt1: addcharoptionsty; + +begin + with messages do begin + opt1:= [aco_processeditchars]; + if projectoptions.s.stripmessageesc then begin + include(opt1,aco_stripescsequence); + end; + int1:= datacols[0].readpipe(atext,opt1,120); + rowhigh1:= rowhigh; + int2:= rowhigh1-int1; + if int2 < 0 then begin + int2:= 0; + end; + strcol1:= messages[0]; + with strcol1 do begin + for int1:= rowhigh downto int2 do begin + if not noparagraph[int1] and + checkerrormessage(datalist.getparagraph(int1), + lev1,fn1,col1,row1) then begin + case lev1 of + el_error: begin + setrowcolor(0); + end; + el_warning: begin + setrowcolor(1); + end; + el_note: begin + setrowcolor(2); + end; + end; + end; + end; + end; + showlastrow; + end; +end; + +procedure tmessagefo.updateprojectoptions; +begin + with messages,projectoptions.s do begin + rowcolors[0]:= colorerror; + rowcolors[1]:= colorwarning; + rowcolors[2]:= colornote; + invalidate; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/messageform_mfm.pas b/mseide-msegui/apps/ide/messageform_mfm.pas new file mode 100644 index 0000000..2ed15d6 --- /dev/null +++ b/mseide-msegui/apps/ide/messageform_mfm.pas @@ -0,0 +1,146 @@ +unit messageform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,messageform; + +const + objdata: record size: integer; data: array[0..2562] of byte end = + (size: 2563; data: ( + 84,80,70,48,10,116,109,101,115,115,97,103,101,102,111,9,109,101,115,115, + 97,103,101,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119, + 95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95,115, + 105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112,116, + 105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111,110, + 16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103,111, + 95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112,98, + 117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100,98, + 117,116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111, + 110,14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,100,8,98,111, + 117,110,100,115,95,121,2,100,9,98,111,117,110,100,115,95,99,120,3,235, + 1,9,98,111,117,110,100,115,95,99,121,3,61,1,23,99,111,110,116,97, + 105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102, + 111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97, + 114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1, + 2,0,2,0,3,225,1,3,61,1,0,16,100,114,97,103,100,111,99,107, + 46,99,97,112,116,105,111,110,6,8,77,101,115,115,97,103,101,115,20,100, + 114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111,99,107,11, + 10,111,100,95,115,97,118,101,112,111,115,13,111,100,95,115,97,118,101,122, + 111,114,100,101,114,10,111,100,95,99,97,110,109,111,118,101,11,111,100,95, + 99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107,11, + 111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116,105, + 111,110,104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110,115, + 0,7,111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112,111, + 115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95,115, + 97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,22, + 109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105, + 108,101,10,105,99,111,110,46,105,109,97,103,101,10,80,3,0,0,0,0, + 0,0,0,0,0,0,24,0,0,0,24,0,0,0,28,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,124,124,124,23,255,255,255,1,124,124, + 124,1,234,234,234,22,255,255,255,1,124,124,124,1,234,234,234,22,255,255, + 255,1,124,124,124,1,234,234,234,22,255,255,255,1,124,124,124,1,234,234, + 234,22,255,255,255,1,124,124,124,1,234,234,234,22,255,255,255,1,124,124, + 124,1,234,234,234,22,255,255,255,1,124,124,124,1,234,234,234,2,227,227, + 227,1,175,175,175,1,199,199,199,1,234,234,234,4,201,201,201,1,177,177, + 177,1,234,234,234,1,224,224,224,1,175,175,175,5,179,179,179,1,234,234, + 234,3,255,255,255,1,124,124,124,1,234,234,234,2,204,204,204,1,0,0, + 0,1,44,44,44,1,234,234,234,4,49,49,49,1,6,6,6,1,234,234, + 234,1,192,192,192,1,2,2,2,1,50,50,50,4,60,60,60,1,234,234, + 234,3,255,255,255,1,124,124,124,1,234,234,234,2,204,204,204,1,6,6, + 6,1,30,30,30,1,201,201,201,1,234,234,234,2,203,203,203,1,29,29, + 29,1,6,6,6,1,234,234,234,1,192,192,192,1,12,12,12,1,234,234, + 234,8,255,255,255,1,124,124,124,1,234,234,234,2,204,204,204,1,6,6, + 6,1,108,108,108,1,123,123,123,1,234,234,234,2,122,122,122,1,109,109, + 109,1,6,6,6,1,234,234,234,1,192,192,192,1,12,12,12,1,234,234, + 234,8,255,255,255,1,124,124,124,1,234,234,234,2,204,204,204,1,6,6, + 6,1,188,188,188,1,45,45,45,1,234,234,234,2,44,44,44,1,189,189, + 189,1,6,6,6,1,234,234,234,1,192,192,192,1,4,4,4,1,87,87, + 87,4,141,141,141,1,234,234,234,3,255,255,255,1,124,124,124,1,234,234, + 234,2,204,204,204,1,6,6,6,1,234,234,234,1,33,33,33,1,202,202, + 202,1,195,195,195,1,60,60,60,1,212,212,212,1,6,6,6,1,234,234, + 234,1,192,192,192,1,7,7,7,1,146,146,146,4,178,178,178,1,234,234, + 234,3,255,255,255,1,124,124,124,1,234,234,234,2,204,204,204,1,6,6, + 6,1,234,234,234,1,112,112,112,1,124,124,124,1,115,115,115,1,141,141, + 141,1,212,212,212,1,6,6,6,1,234,234,234,1,192,192,192,1,12,12, + 12,1,234,234,234,8,255,255,255,1,124,124,124,1,234,234,234,2,204,204, + 204,1,6,6,6,1,234,234,234,1,191,191,191,1,48,48,48,1,40,40, + 40,1,218,218,218,1,212,212,212,1,6,6,6,1,234,234,234,1,192,192, + 192,1,12,12,12,1,234,234,234,8,255,255,255,1,124,124,124,1,234,234, + 234,2,204,204,204,1,6,6,6,1,234,234,234,2,36,36,36,1,71,71, + 71,1,234,234,234,1,212,212,212,1,6,6,6,1,234,234,234,1,192,192, + 192,1,3,3,3,1,58,58,58,5,204,204,204,1,234,234,234,2,255,255, + 255,1,124,124,124,1,234,234,234,2,227,227,227,1,177,177,177,1,234,234, + 234,2,197,197,197,1,206,206,206,1,234,234,234,1,228,228,228,1,177,177, + 177,1,234,234,234,1,224,224,224,1,175,175,175,6,225,225,225,1,234,234, + 234,2,255,255,255,1,124,124,124,1,234,234,234,22,255,255,255,1,124,124, + 124,1,234,234,234,22,255,255,255,1,124,124,124,1,234,234,234,22,255,255, + 255,1,124,124,124,1,234,234,234,22,255,255,255,1,124,124,124,1,234,234, + 234,22,255,255,255,1,124,124,124,1,234,234,234,22,255,255,255,1,124,124, + 124,1,255,255,255,23,15,109,111,100,117,108,101,99,108,97,115,115,110,97, + 109,101,6,9,116,100,111,99,107,102,111,114,109,0,11,116,115,116,114,105, + 110,103,103,114,105,100,8,109,101,115,115,97,103,101,115,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,9,112,111,112,117,112, + 109,101,110,117,7,11,116,112,111,112,117,112,109,101,110,117,49,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,225,1,9,98,111,117,110,100,115,95, + 99,121,3,61,1,7,97,110,99,104,111,114,115,11,0,9,102,111,110,116, + 46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,12,102, + 111,110,116,46,111,112,116,105,111,110,115,11,15,102,111,111,95,97,110,116, + 105,97,108,105,97,115,101,100,0,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,14,100,97,116,97,99,111,108, + 115,46,99,111,117,110,116,2,1,18,100,97,116,97,99,111,108,115,46,108, + 105,110,101,119,105,100,116,104,2,0,14,100,97,116,97,99,111,108,115,46, + 105,116,101,109,115,14,1,12,108,105,110,101,99,111,108,111,114,102,105,120, + 4,3,0,0,160,5,119,105,100,116,104,3,184,11,7,111,112,116,105,111, + 110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,100, + 114,97,119,102,111,99,117,115,22,99,111,95,108,101,102,116,98,117,116,116, + 111,110,102,111,99,117,115,111,110,108,121,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,10,99,111,95,99,97,110,99,111,112,121,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,11,111,112, + 116,105,111,110,115,101,100,105,116,11,0,10,118,97,108,117,101,102,97,108, + 115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,0, + 11,114,111,119,99,111,117,110,116,109,97,120,3,136,19,15,114,111,119,99, + 111,108,111,114,115,46,99,111,117,110,116,2,3,15,114,111,119,99,111,108, + 111,114,115,46,105,116,101,109,115,1,4,24,0,0,160,4,19,0,0,160, + 4,20,0,0,160,0,16,100,97,116,97,114,111,119,108,105,110,101,119,105, + 100,116,104,2,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2, + 16,11,111,110,99,101,108,108,101,118,101,110,116,7,19,109,101,115,115,97, + 103,101,115,111,110,99,101,108,108,101,118,101,110,116,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,10,116,112,111,112,117,112,109, + 101,110,117,11,116,112,111,112,117,112,109,101,110,117,49,18,109,101,110,117, + 46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,1,18,109,101,110, + 117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97, + 112,116,105,111,110,6,17,67,111,112,121,32,116,111,32,99,108,105,112,98, + 111,97,114,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,7,99,111, + 112,121,101,120,101,0,0,4,108,101,102,116,2,88,3,116,111,112,2,72, + 0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmessagefo,''); +end. diff --git a/mseide-msegui/apps/ide/msecodetemplates.pas b/mseide-msegui/apps/ide/msecodetemplates.pas new file mode 100644 index 0000000..1cbd811 --- /dev/null +++ b/mseide-msegui/apps/ide/msecodetemplates.pas @@ -0,0 +1,374 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msecodetemplates; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +(* +Extension for template files is *.mct +Example of a template file: +" +[header] +name=thename +comment=Comment abcdefg HIKLMNO +params=3 + param1 + param2 + param3 +noselect=1 +cursorcol=12 +cursorrow=1 +[] +The Template Text with macros ${param1} +more text +${param2} ${param3} more params +" +If noselect=0 or not defined the templateblock will be selected in editor. +If noselect=1 the cursor will be placed at the offset by cursorcol, cursorrow. +If indent=1 the inserted block will be indented at cursor column +Minimal template file: +" +[header] +name=thename +[] +" +Parameters can be entered in editor: +" +thename,valueforparam1,valueforparam2 +" +A dialog window will be displayed if there are more params defined than supplied +for param entry or if the template name can not be found. +*) + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msestrings,msehash,msemacros,msetypes,mseforms; + +type + templateinfoty = record + name: msestring; + path: filenamety; + comment: msestring; + select: boolean; + indent: boolean; + cursorcol: integer; + cursorrow: integer; + params: msestringarty; + paramdefaults: msestringarty; + template: msestring; + cursorpos: gridcoordty; //variable + end; + ptemplateinfoty = ^templateinfoty; + templateinfoarty = array of templateinfoty; + + tcodetemplates = class(tobject) + private + finfos: templateinfoarty; + fmask: filenamety; + flist: tpointermsestringhashdatalist; + protected + function loadfile(const afilename: filenamety; + out ainfo: templateinfoty): boolean; + //true if ok + procedure reload(const selectform: tmseform); //tmsetemplateselectfo + public + constructor create; + destructor destroy; override; + procedure initinfo(out ainfo: templateinfoty); + procedure savefile(const ainfo: templateinfoty); + procedure clear; + procedure scan(const adirectories: filenamearty); + function hastemplate(const aname: msestring): boolean; + function gettemplate(const aname: msestring; out templatetext: msestring; + const amacrolist: tmacrolist = nil): ptemplateinfoty; + property templates: templateinfoarty read finfos; + end; + +implementation +uses + msefileutils,msesys,msestat,msestream,mseparamentryform,mseglob,msearrayutils, + msetemplateselectform,msedataedits; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tcodetemplates } + +constructor tcodetemplates.create; +begin + fmask:= '*.mct'; + flist:= tpointermsestringhashdatalist.create; + inherited; +end; + +destructor tcodetemplates.destroy; +begin + clear; + flist.free; + inherited; +end; + +procedure tcodetemplates.clear; +begin + finfos:= nil; + flist.clear; +end; + +function compitems(const l,r): integer; +begin + result:= msecomparetext(templateinfoty(l).name,templateinfoty(r).name); +end; + +procedure tcodetemplates.scan(const adirectories: filenamearty); +var + int1,int2: integer; + ar1: filenamearty; +begin + clear; + ar1:= searchfiles(fmask,adirectories); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if high(finfos) < int2 then begin + setlength(finfos,int2*2+16); + end; + if loadfile(ar1[int1],finfos[int2]) then begin + inc(int2); + end; + end; + setlength(finfos,int2); + sortarray(finfos,sizeof(templateinfoty),@compitems); + for int1:= 0 to high(finfos) do begin + flist.add(finfos[int1].name,pointer(ptruint(int1))); + end; +end; + +procedure tcodetemplates.initinfo(out ainfo: templateinfoty); +begin + finalize(ainfo); + fillchar(ainfo,sizeof(ainfo),0); +end; + +function tcodetemplates.loadfile(const afilename: filenamety; + out ainfo: templateinfoty): boolean; +var + stat: tstatreader; +begin + result:= false; + initinfo(ainfo); + stat:= tstatreader.create(afilename,ce_utf8); + with stat,ainfo do begin + if findsection('header') then begin + name:= readmsestring('name',''); + if name <> '' then begin + path:= afilename; + comment:= readmsestring('comment',''); + select:= readboolean('select',false); + indent:= readboolean('indent',false); + cursorcol:= readinteger('cursorcol',0,0,1000); + cursorrow:= readinteger('cursorrow',0,0,1000000); + params:= readarray('params',msestringarty(nil)); + paramdefaults:= readarray('paramdefaults',msestringarty(nil)); + setlength(paramdefaults,length(params)); + template:= streamtext; + result:= true; + end; + end; + end; + stat.free; +end; + +procedure tcodetemplates.savefile(const ainfo: templateinfoty); +var + stat: tstatwriter; +begin + stat:= tstatwriter.create(ainfo.path,ce_utf8,true); + with stat,ainfo do begin + writesection('header'); + writemsestring('name',name); + writemsestring('comment',comment); + writeboolean('select',select); + writeboolean('indent',indent); + writeinteger('cursorcol',cursorcol); + writeinteger('cursorrow',cursorrow); + writearray('params',params); + writearray('paramdefaults',paramdefaults); + streamtext(template); + end; + stat.free; +end; + +function tcodetemplates.hastemplate(const aname: msestring): boolean; +var + po1: pointer; + ar1: msestringarty; +begin + result:= false; + if aname <> '' then begin + result:= flist.find(aname,po1); + if not result then begin + splitstringquoted(aname,ar1,msechar('"'),msechar(',')); + result:= flist.find(ar1[0],po1); + end; + end; +end; + +function tcodetemplates.gettemplate(const aname: msestring; + out templatetext: msestring; + const amacrolist: tmacrolist = nil): ptemplateinfoty; +var + ar1: msestringarty; + ar2: integerarty; + puint1: ptruint; + mac1: tmacrolist; + fo: tmseparamentryfo; + se: tmsetemplateselectfo; + int1,int2: integer; + bo1: boolean; +begin + result:= nil; + templatetext:= ''; + if aname <> '' then begin + splitstringquoted(aname,ar1,msechar('"'),msechar(',')); + end + else begin + setlength(ar1,1); + end; + if (ar1[0] = '') or not flist.find(ar1[0],pointer(puint1),int1) or + (int1 > 1) then begin + se:= tmsetemplateselectfo.create(self); + try + reload(se); + se.show; + se.grid.setfocus; + se.templatename.editor.filtertext:= ar1[0]; + if (se.show(true) <> mr_ok) or (se.grid.row < 0) or + (se.grid.row > high(finfos)) then begin + exit; + end; + puint1:= se.grid.row; + finally + se.free; + end; + end; + bo1:= true; + mac1:= amacrolist; + if mac1 = nil then begin + mac1:= tmacrolist.create([mao_caseinsensitive,mao_curlybraceonly]); + end; + try + with finfos[puint1] do begin + fo:= tmseparamentryfo.create(nil); + try + fo.caption:= fo.c[ord(codetemplate)]+name+'"'; + fo.comment.caption:= comment; + fo.macroname.gridvalues:= params; + fo.macrovalue.gridvalues:= paramdefaults; + for int1:= 0 to high(params) do begin + if int1 >= high(ar1) then begin + break; + end; + fo.macrovalue[int1]:= ar1[int1+1]; + end; + if high(ar1) <= high(params) then begin + fo.grid.row:= high(ar1); + bo1:= fo.show(true) = mr_ok; + end; + mac1.add(params,fo.macrovalue.gridvalues,[]); + finally + fo.free; + end; + if bo1 then begin + result:= @finfos[puint1]; + cursorpos.col:= cursorcol; + cursorpos.row:= cursorrow; + if (cursorcol > 0) or (cursorrow > 0) then begin + ar1:= breaklines(template); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if int1 >= cursorrow then begin + break; + end; + int2:= int2 + length(ar1[int1]) + length(lineend); + end; + int2:= int2 + cursorcol; + setlength(ar2,1); + ar2[0]:= int2; + templatetext:= concatstrings(ar1,lineend); + mac1.expandmacros1(templatetext,ar2); + ar1:= breaklines(templatetext); + int2:= ar2[0]; + for int1:= 0 to high(ar1) do begin + int2:= int2 - (length(ar1[int1]) + length(lineend)); + if int2 < 0 then begin + cursorpos.row:= int1; + cursorpos.col:= int2 + (length(ar1[int1]) + length(lineend)); + break; + end; + end; + end + else begin + templatetext:= template; + mac1.expandmacros1(templatetext); + end; + end; + end; + finally + if mac1 <> amacrolist then begin + mac1.free; + end; + end; +end; + +procedure tcodetemplates.reload(const selectform: tmseform); +var + se: tmsetemplateselectfo; + int1,int2: integer; + edit1: tstringedit; +begin + se:= selectform as tmsetemplateselectfo; + se.finfos:= finfos; + se.grid.beginupdate; + se.grid.clear; + se.grid.rowcount:= length(finfos)+1; + for int1:= 0 to high(finfos) do begin + with finfos[int1] do begin + se.templatename[int1]:= name; + se.comment[int1]:= comment; + for int2:= 0 to high(params) do begin + edit1:= tstringedit(se.grid.findtagchild(int2+1,tstringedit)); + if edit1 <> nil then begin + edit1[int1]:= params[int2]; + end; + end; + end; + end; + se.grid.endupdate; +end; + +end. diff --git a/mseide-msegui/apps/ide/msecomptree.mfm b/mseide-msegui/apps/ide/msecomptree.mfm new file mode 100644 index 0000000..f2f48e8 --- /dev/null +++ b/mseide-msegui/apps/ide/msecomptree.mfm @@ -0,0 +1,73 @@ +object compnametreefo: tcompnametreefo + visible = False + bounds_x = 80 + bounds_y = 374 + bounds_cx = 300 + bounds_cy = 203 + bounds_cxmin = 200 + container.bounds = ( + 0 + 0 + 300 + 203 + ) + optionswindow = [wo_notaskbar] + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = tstatfile1 + caption = 'Select Component' + moduleclassname = 'tmseform' + object grid: twidgetgrid + frame.levelo = 0 + frame.colorframe = -1610612734 + frame.localprops = [frl_levelo, frl_framewidth, frl_colorframe] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 300 + bounds_cy = 203 + anchors = [] + datacols.count = 1 + datacols.items = < + item[treeitem] + width = 299 + options = [co_readonly, co_fill, co_savevalue] + widgetname = 'treeitem' + dataclass = ttreeitemeditlist + datalist.imnr_base = 2 + datalist.imnr_expanded = 1 + datalist.imnr_subitems = -2 + datalist.imagelist = filedialogres.images + datalist.imagewidth = 16 + datalist.imageheight = 16 + datalist.onitemnotification = treeitemonitemnotification + datalist.oncreateitem = treeitemoncreateitem + end> + datarowlinewidth = 0 + datarowheight = 16 + reffontheight = 14 + object treeitem: ttreeitemedit + color = -1879048185 + cursor = cr_arrow + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 299 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_forcereturncheckvalue, oe_locate] + ondataentered = treeitemondataentered + oncellevent = treeitemoncellevent + options = [teo_treecolnavig, teo_enteronimageclick] + reffontheight = 14 + end + end + object tstatfile1: tstatfile + filename = 'compnamedialog.sta' + options = [sfo_memory] + left = 48 + top = 48 + end +end diff --git a/mseide-msegui/apps/ide/msecomptree.pas b/mseide-msegui/apps/ide/msecomptree.pas new file mode 100644 index 0000000..8717662 --- /dev/null +++ b/mseide-msegui/apps/ide/msecomptree.pas @@ -0,0 +1,173 @@ +{ MSEide Copyright (c) 2011 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msecomptree; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msewidgetgrid,mselistbrowser,msedatanodes,msetypes,msestrings,msegui, + mseglob,mseclasses,msegrids,msesys,msegridsglob,msestat,msestatfile; + +const + compnamedialogstatname = 'compnamedialog.sta'; + +type + tcompnameitem = class(ttreelistedititem) + public + isvalue: boolean; + end; + + tcompnametreefo = class(tmseform) + grid: twidgetgrid; + treeitem: ttreeitemedit; + tstatfile1: tstatfile; + procedure treeitemoncreateitem(const sender: tcustomitemlist; + var item: ttreelistedititem); virtual; + procedure treeitemonitemnotification(const sender: tlistitem; + var action: nodeactionty); virtual; + procedure treeitemondataentered(const sender: tobject); virtual; + procedure treeitemoncellevent(const sender: tobject; + var info: celleventinfoty); virtual; + private + fselectparent: boolean; + public + end; +{ + tdiredit = class(tstringedit) + private + end; +} +//var +// dirtreefo: tdirtreefo; + +function compnamedialog(const avalues: tcompnameitem; //will be freed + var avalue: msestring; + const selectparent: boolean): modalresultty; + +implementation +uses + msecomptree_mfm,msesysintf,mseeditglob,msefiledialog,msebitmap,mseevent, + mseguiglob; + +function compnamedialog(const avalues: tcompnameitem; var avalue: msestring; + const selectparent: boolean): modalresultty; +var + fo1: tcompnametreefo; + ar1: msestringarty; + item1: ttreelistitem; +begin + fo1:= tcompnametreefo.create(nil); + try + fo1.fselectparent:= selectparent; + ar1:= splitstring(avalue,msechar('.')); + item1:= avalues.finditembycaption(ar1,false,false,true); + if item1 <> nil then begin + item1.expandtoroot(); + item1.expanded:= true; + end; + fo1.treeitem.itemlist.assign(avalues); + if item1 <> nil then begin + fo1.grid.row:= item1.index; + end; + result:= fo1.show(true); + if result = mr_ok then begin + ar1:= tcompnameitem(fo1.treeitem.item).rootcaptions; + avalue:= ar1[0]; + if high(ar1) > 0 then begin + avalue:= ar1[0]+'.'+ar1[1]; + if high(ar1) > 1 then begin + if high(ar1) = 2 then begin + avalue:= avalue+':'+ar1[2]; + end + else begin + avalue:= avalue+':'+concatstrings(copy(ar1,2,bigint),':'); + end; + end; + end; + end; + finally + fo1.free; + end; +end; + +{ tcompnametreefo } + +procedure tcompnametreefo.treeitemoncellevent(const sender: tobject; + var info: celleventinfoty); +begin + case info.eventkind of + cek_enter: begin +// if assigned(fonpathchanged) then begin +// fonpathchanged(self); +// end; + end; + end; + if iscellclick(info) and (info.zone = cz_caption) then begin + treeitem.checkvalue; + end; +end; + +procedure tcompnametreefo.treeitemoncreateitem(const sender: tcustomitemlist; + var item: ttreelistedititem); +begin + item:= tcompnameitem.create(sender); +end; + +procedure tcompnametreefo.treeitemondataentered(const sender: tobject); +begin + if fselectparent or tcompnameitem(treeitem.item).isvalue then begin + window.modalresult:= mr_ok; + end; +end; + +procedure tcompnametreefo.treeitemonitemnotification(const sender: tlistitem; + var action: nodeactionty); +//var +// bo1: boolean; +begin +{ + with tdirlistitem(sender) do begin + case action of + na_expand: begin + include(finfo.state,fis_diropen); + updateinfo; + if (count = 0) or not(dto_checkbox in foptions) then begin + adddir(tdirlistitem(sender)); + end; + if count = 0 then begin + state:= state - [ns_subitems,ns_expanded]; + action:= na_none; + end; + end; + na_collapse: begin + bo1:= count > 0; + if not (dto_checkbox in foptions) then begin + clear; + end; + if bo1 then begin + state:= state + [ns_subitems]; + end; + exclude(finfo.state,fis_diropen); + updateinfo; + end; + end; + end; + } +end; + +end. diff --git a/mseide-msegui/apps/ide/msecomptree_mfm.pas b/mseide-msegui/apps/ide/msecomptree_mfm.pas new file mode 100644 index 0000000..1669ba1 --- /dev/null +++ b/mseide-msegui/apps/ide/msecomptree_mfm.pas @@ -0,0 +1,94 @@ +unit msecomptree_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msecomptree; + +const + objdata: record size: integer; data: array[0..1520] of byte end = + (size: 1521; data: ( + 84,80,70,48,15,116,99,111,109,112,110,97,109,101,116,114,101,101,102,111, + 14,99,111,109,112,110,97,109,101,116,114,101,101,102,111,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,80,8,98,111,117,110, + 100,115,95,121,3,118,1,9,98,111,117,110,100,115,95,99,120,3,44,1, + 9,98,111,117,110,100,115,95,99,121,3,203,0,12,98,111,117,110,100,115, + 95,99,120,109,105,110,3,200,0,16,99,111,110,116,97,105,110,101,114,46, + 98,111,117,110,100,115,1,2,0,2,0,3,44,1,3,203,0,0,13,111, + 112,116,105,111,110,115,119,105,110,100,111,119,11,12,119,111,95,110,111,116, + 97,115,107,98,97,114,0,7,111,112,116,105,111,110,115,11,17,102,111,95, + 115,99,114,101,101,110,99,101,110,116,101,114,101,100,13,102,111,95,99,108, + 111,115,101,111,110,101,115,99,17,102,111,95,108,111,99,97,108,115,104,111, + 114,116,99,117,116,115,15,102,111,95,97,117,116,111,114,101,97,100,115,116, + 97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10, + 102,111,95,115,97,118,101,112,111,115,0,8,115,116,97,116,102,105,108,101, + 7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110, + 6,16,83,101,108,101,99,116,32,67,111,109,112,111,110,101,110,116,15,109, + 111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101, + 102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114, + 105,100,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,16,102,114, + 97,109,101,46,99,111,108,111,114,102,114,97,109,101,4,2,0,0,160,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,14,102,114,108,95,102,114,97,109,101,119,105, + 100,116,104,14,102,114,108,95,99,111,108,111,114,102,114,97,109,101,0,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,44,1,9,98,111,117,110,100, + 115,95,99,121,3,203,0,7,97,110,99,104,111,114,115,11,0,14,100,97, + 116,97,99,111,108,115,46,99,111,117,110,116,2,1,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,8,116,114,101,101,105,116,101,109, + 1,5,119,105,100,116,104,3,43,1,7,111,112,116,105,111,110,115,11,11, + 99,111,95,114,101,97,100,111,110,108,121,7,99,111,95,102,105,108,108,12, + 99,111,95,115,97,118,101,118,97,108,117,101,0,10,119,105,100,103,101,116, + 110,97,109,101,6,8,116,114,101,101,105,116,101,109,9,100,97,116,97,99, + 108,97,115,115,7,17,116,116,114,101,101,105,116,101,109,101,100,105,116,108, + 105,115,116,18,100,97,116,97,108,105,115,116,46,105,109,110,114,95,98,97, + 115,101,2,2,22,100,97,116,97,108,105,115,116,46,105,109,110,114,95,101, + 120,112,97,110,100,101,100,2,1,22,100,97,116,97,108,105,115,116,46,105, + 109,110,114,95,115,117,98,105,116,101,109,115,2,254,18,100,97,116,97,108, + 105,115,116,46,105,109,97,103,101,108,105,115,116,7,20,102,105,108,101,100, + 105,97,108,111,103,114,101,115,46,105,109,97,103,101,115,19,100,97,116,97, + 108,105,115,116,46,105,109,97,103,101,119,105,100,116,104,2,16,20,100,97, + 116,97,108,105,115,116,46,105,109,97,103,101,104,101,105,103,104,116,2,16, + 27,100,97,116,97,108,105,115,116,46,111,110,105,116,101,109,110,111,116,105, + 102,105,99,97,116,105,111,110,7,26,116,114,101,101,105,116,101,109,111,110, + 105,116,101,109,110,111,116,105,102,105,99,97,116,105,111,110,21,100,97,116, + 97,108,105,115,116,46,111,110,99,114,101,97,116,101,105,116,101,109,7,20, + 116,114,101,101,105,116,101,109,111,110,99,114,101,97,116,101,105,116,101,109, + 0,0,16,100,97,116,97,114,111,119,108,105,110,101,119,105,100,116,104,2, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,13,116,116,114,101,101, + 105,116,101,109,101,100,105,116,8,116,114,101,101,105,116,101,109,5,99,111, + 108,111,114,4,7,0,0,144,6,99,117,114,115,111,114,7,8,99,114,95, + 97,114,114,111,119,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,2, + 0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,8,116,97,98,111,114,100,101,114,2,1, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,43,1,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111, + 101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110, + 101,115,99,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 24,111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107, + 118,97,108,117,101,9,111,101,95,108,111,99,97,116,101,0,13,111,110,100, + 97,116,97,101,110,116,101,114,101,100,7,21,116,114,101,101,105,116,101,109, + 111,110,100,97,116,97,101,110,116,101,114,101,100,11,111,110,99,101,108,108, + 101,118,101,110,116,7,19,116,114,101,101,105,116,101,109,111,110,99,101,108, + 108,101,118,101,110,116,7,111,112,116,105,111,110,115,11,16,116,101,111,95, + 116,114,101,101,99,111,108,110,97,118,105,103,21,116,101,111,95,101,110,116, + 101,114,111,110,105,109,97,103,101,99,108,105,99,107,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,116,97,116, + 102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101, + 110,97,109,101,6,18,99,111,109,112,110,97,109,101,100,105,97,108,111,103, + 46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101, + 109,111,114,121,0,4,108,101,102,116,2,48,3,116,111,112,2,48,0,0, + 0) + ); + +initialization + registerobjectdata(@objdata,tcompnametreefo,''); +end. diff --git a/mseide-msegui/apps/ide/msedesigner.pas b/mseide-msegui/apps/ide/msedesigner.pas new file mode 100644 index 0000000..602d360 --- /dev/null +++ b/mseide-msegui/apps/ide/msedesigner.pas @@ -0,0 +1,6037 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msedesigner; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegraphutils,mseglob,mseguiglob,msedesignintf, + mseforms,mselist,msearrayutils,msebitmap,msetypes,sysutils,msehash,mseclasses, + mseformdatatools,typinfo,msepropertyeditors,msecomponenteditors,msegraphics, + mseapplication,msegui,msestrings,msedesignparser,msecomptree,mseevent, + mseinterfaces,msedock; + +{$ifndef mse_methodswap} + {$define mse_nomethodswap} +{$endif} + +const + formfileext = 'mfm'; + pasfileext = 'pas'; + backupext = '.bak'; + subcomponentsplitchar = ':'; + +type + tdesigner = class; + + moduleoptionty = (mo_hidewidgets,mo_hidecomp); + moduleoptionsty = set of moduleoptionty; + + iformdesigner = interface(inullinterface)[miid_iformdesigner] + function clickedcomponent: tcomponent; + function getmoduleoptions: moduleoptionsty; + procedure setmoduleoptions(const aoptions: moduleoptionsty); + property moduleoptions: moduleoptionsty read getmoduleoptions + write setmoduleoptions; + procedure updatecaption(); + procedure findcompdialog(); + function getmodulepos_x(): integer; + function getmodulepos_y(): integer; + procedure setmodulepos_x(const avalue: integer); + procedure setmodulepos_y(const avalue: integer); + function getdockcontroller(): tdockcontroller; + end; + + methodinfoty = record + name: string; + address: pointer; + typeinfo: ptypeinfo; + end; + pmethodinfoty = ^methodinfoty; + tmethods = class; + methodsarty = array of tmethods; + + methodsdataty = record + key: ptruint; + data: methodinfoty; + end; + pmethodsdataty = ^methodsdataty; + methodshashdataty = record + header: hashheaderty; + data: methodsdataty; + end; + pmethodshashdataty = ^methodshashdataty; + + tmethods = class(tptruinthashdatalist) + private + fdesigner: tdesigner; + {fapropname,fapropvalue: string;} +{$ifndef mse_nomethodswap} + fmethodtable: pointer; +{$endif} + protected + procedure finalizeitem(const aitem: phashdataty); override; + procedure deletemethod(const aadress: pointer); + procedure addmethod(const aname: string; const aaddress: pointer; + const atypeinfo: ptypeinfo); + function getrecordsize(): int32 override; + public + constructor create(adesigner: tdesigner); + destructor destroy; override; + function findmethod(const aadress: pointer): pmethodinfoty; + function findmethodbyname(const aname: string; const atype: ptypeinfo; + out namefound: boolean): pmethodinfoty; overload; + function findmethodbyname(const aname: string): pmethodinfoty; overload; +{$ifndef mse_nomethodswap} + function createmethodtable(const ancestors: methodsarty): pointer; + procedure releasemethodtable; +{$endif} + end; + + tmethodnames = class(tansistringptruinthashdatalist) + public + end; + + tcomponents = class; + + tcomponentslink = class(tcomponent) + private + fownercomps: tcomponents; + protected + procedure notification(acomponent: tcomponent; operation: toperation); override; + end; + + componentnamety = record + instance: tcomponent; + dispname: string; + end; + componentnamearty = array of componentnamety; + + moduleinfoty = record + filename: msestring; + filetag: longword; + filechanged: boolean; + savetime: tdatetime; + moduleclassname: string[80]; //can not be ansistring! + instancevarname: string; + instance: tmsecomponent; + moduleintf: pdesignmoduleintfty; + designformclass: pointer; + methods: tmethods; + {$ifndef mse_nomethodswap} + methodtableswapped: integer; + methodtablebefore: pointer; + {$endif} + backupcreated: boolean; + modified: boolean; + readermodified: boolean; + resolved: boolean; + hasmenuitem: boolean; + components: tcomponents; + designform: tcustommseform; + designformintf: iformdesigner; + referencedmodules: stringarty; + loadingstream: tstream; + end; + pmoduleinfoty = ^moduleinfoty; + moduleinfopoarty = array of pmoduleinfoty; + + componentsdataty = record + key: ptruint; + data: componentinfoty; + end; + pcomponentsdataty = ^componentsdataty; + componentshashdataty = record + header: hashheaderty; + data: componentsdataty; + end; + pcomponentshashdataty = ^componentshashdataty; + + tcomponents = class(tptruinthashdatalist) + private + fdesigner: tdesigner; + fcomponent: tcomponentslink; // to receive componentnotifications + fowner: pmoduleinfoty; + protected + procedure finalizeitem(const aitem: phashdataty); override; + function find(const value: tobject): pcomponentshashdataty; + procedure destroynotification(const acomponent: tcomponent); + procedure swapcomponent(const old,new: tcomponent); + function getrecordsize(): int32 override; + public + constructor create(const aowner: pmoduleinfoty; const adesigner: tdesigner); + destructor destroy; override; + procedure assigncomps(const module: tmsecomponent); + procedure add(comp: tcomponent); + function next: pcomponentshashdataty; + function getcomponents: componentarty; + function getdispnames: componentnamearty; + function getcomponent(const aname: string; + const children: boolean = false): tcomponent; + procedure namechanged(const acomponent: tcomponent; const newname: string); + end; + + tmoduleinfo = class(tlinkedobject) + protected + fdesigner: tdesigner; + public + info: moduleinfoty; + constructor create(adesigner: tdesigner); + destructor destroy; override; + end; + + pmoduleinfo = ^tmoduleinfo; + + tmodulelist = class(tlinkedobjectqueue) + private + fdesigner: tdesigner; + fmethodnames: tmethodnames; + function getitempo1(const index: integer): pmoduleinfoty; + protected + function newmodule(const ainherited: boolean; const afilename: msestring; + const amoduleclassname,ainstancevarname, + designmoduleclassname: string): tmoduleinfo; + function findmethodbyname(const name: string; const atype: ptypeinfo; + const amodule: tmsecomponent): tmethod; + function findmethodname(const method: tmethod; const comp: tcomponent): string; + function findform(aform: tcustommseform): pmoduleinfoty; + function removemoduleinfo(po: pmoduleinfoty): integer; + procedure componentmodified(const acomponent: tobject); + procedure freeloadingstreams; + + public + constructor create(adesigner: tdesigner); reintroduce; + destructor destroy; override; + procedure designformdestroyed(const sender: tcustommseform); + function delete(index: integer): pointer; override; + function findmodule(const filename: msestring): pmoduleinfoty; overload; + function findmodule(const amodule: tmsecomponent): pmoduleinfoty; overload; + function findmodule(const po: pmoduleinfoty): integer; overload; + function findmodulebyname(const name: string): pmoduleinfoty; + function findmoduleinstancebyname(const name: string): tcomponent; + function findmoduleinstancebyclass(const aclass: tclass): tcomponent; + function findmodulebyclassname(aclassname: string): pmoduleinfoty; + function findmodulebycomponent(const acomponent: tcomponent): pmoduleinfoty; + function findmodulebyinstance(const ainstance: tcomponent): pmoduleinfoty; + function findownermodule(const acomponent: tcomponent): pmoduleinfoty; + function filenames: filenamearty; + + property itempo[const index: integer]: pmoduleinfoty read getitempo1; default; + end; + + tdesignformlist = class(tcomponentqueue) + private + function getitems(const index: integer): tmseform;//tformdesignerfo; + public + property items[const index: integer]: tmseform read getitems; default; + end; + + ancestorinfoty = record + descendent,ancestor: tmsecomponent + end; + pancestorinfoty = ^ancestorinfoty; + ancestorinfoarty = array of ancestorinfoty; + ancestorinfoaty = array[0..0] of ancestorinfoty; + pancestorinfoaty = ^ancestorinfoaty; + + ancestornameinfoty = record + desc,anc: string; + end; + ancestornameinfoarty = array of ancestornameinfoty; + + tancestorlist = class(tobjectlinkrecordlist) + private + fstreaming: integer; +{$ifndef mse_nomethodswap} + fswappedancestors: componentarty; +{$endif} + protected + procedure dounlink(var item); override; + procedure doitemdestroyed(const sender: tmsecomponent); virtual; + procedure itemdestroyed(const sender: iobjectlink); override; + function getdescendentar(const aancestor: tmsecomponent): msecomponentarty; +{$ifndef mse_nomethodswap} + procedure streamingswapmethodpointer(const acomp: tcomponent); +{$endif} + public + constructor create; + function findancestor(const adescendent: tcomponent): tmsecomponent; + function finddescendent(const aancestor: tcomponent): tmsecomponent; + function finddescendentinfo(const adescendent: tcomponent): pancestorinfoty; + function findancestorinfo(const aancestor: tcomponent): pancestorinfoty; + function findinfo(const ainfo: ancestornameinfoty): pancestorinfoty; + procedure getinfo(const apo: pancestorinfoty; out info: ancestornameinfoty); + procedure add(const adescendent,aancestor: tmsecomponent); + procedure beginstreaming; + procedure endstreaming; + end; + + tdesignerancestorlist = class(tancestorlist) + private + fdesigner: tdesigner; + public + constructor create(aowner: tdesigner); + end; + + tsubmodulelist = class(tdesignerancestorlist,ievent) + //ancestor is copy of old state of descendent, + //descendent is real submodule + protected + frenewbackuplist: msecomponentarty; + procedure finalizerecord(var item); override; + procedure dorenewbackup; + procedure receiveevent(const event: tobjectevent); + procedure doitemdestroyed(const sender: tmsecomponent); override; + public + procedure add(const amodule: tmsecomponent); overload; + procedure renewbackup(const amodule: tmsecomponent); + function findoldancestor(const adescendent: tmsecomponent): tmsecomponent; + end; + + treaderrorhandler = class(tcomponent) + private + fcomponentar: componentarty; + fnewcomponents: componentarty; + froot: tcomponent; + procedure doraise(const acomponent: tcomponent); + procedure ancestornotfound(Reader: TReader; const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent); + procedure onsetname(reader: treader; component: tcomponent; var aname: string); + procedure onerror(reader: treader; const message: string; var handled: boolean); + protected + procedure notification(acomponent: tcomponent; operation: toperation); + override; + public + destructor destroy; override; + end; + + tdescendentinstancelist = class(tdesignerancestorlist) + private + fdelcomps:componentarty; + froot: tcomponent; + fmodule: pmoduleinfoty; + fmodulemodifying: boolean; + fmodifiedmodules: moduleinfopoarty; + frefreshmethods: methodsarty; + fcomponentnamechanging: boolean; + fdeletedcomps: componentarty; + procedure delcomp(child: tcomponent); + procedure addcomp(child: tcomponent); + procedure domodulemodified(const amodule: pmoduleinfoty; + modifylevel: integer; destcompnames,ancestorcompnames: stringarty; + newancestorcomps,oldancestorcomps: msecomponentarty); + {$ifdef mse_nomethodswap} + procedure setrefreshmethod(reader: treader; instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); + {$else} + procedure findrefreshmethod(reader: treader; const amethodname: string; + var address: pointer; var error: boolean); + {$endif} + procedure modulemodified(const amodule: pmoduleinfoty); + procedure componentnamechanged(const amodule: pmoduleinfoty; + const acomponent: tcomponent; const newname: string); + procedure setnodefaultpos(const aroot: twidget); + procedure restorepos(const aroot: twidget); + public + procedure beginstreaming(const amodule: pmoduleinfoty); + procedure add(const instance,ancestor: tmsecomponent; + const submodulelist: tsubmodulelist); overload; + function getclassname(const comp: tcomponent): string; + //returns submodule or root classname if appropriate + function getancestors(const adescendent: tcomponent): componentarty; + function getancestorsandchildren(const adescendent: tcomponent): componentarty; + function getdescendents(const aancestor: tcomponent): componentarty; + end; + + getmoduleeventty = procedure(const amodule: pmoduleinfoty; + const aname: string; var action: modalresultty) of object; + //mr_ignore,mr_ok, cancel otherwise + getmoduletypeeventty = procedure(const atypename: string) of object; + propprocty = procedure(const ainstance: tobject; const data: pointer; + const apropinfo: ppropinfo); + + forallmethpropinfoty = record + root: tcomponent; + dat: pointer; + proc: propprocty; + dochi: boolean; + end; + + designerstatety = (des_pasting,des_inheritednewmodule,des_skipall); + designerstatesty = set of designerstatety; + + tdesigner = class(tactcomponent,idesigner) + private + fselections: tdesignerselections; + factmodulepo: pmoduleinfoty; + floadingmodulepo: pmoduleinfoty; + flastmethodmodulepo: pmoduleinfoty; + fmodules: tmodulelist; + fcomponenteditor: tcomponenteditor; + fobjformat: objformatty; + fsubmoduleinfopo: pmoduleinfoty; + fsubmodulelist: tsubmodulelist; + fdescendentinstancelist: tdescendentinstancelist; + fdesignfiles: tindexedfilenamelist; + fongetmodulenamefile: getmoduleeventty; + fongetmoduletypefile: getmoduletypeeventty; + fnotifymodule: tmsecomponent; + fcomponentmodifying: integer; + floadedsubmodules: componentarty; + fformloadlevel: integer; + fformloadlocklevel: integer; + fnotifydeletedlock: integer; + fallsaved: boolean; + fcreatecomponenttag: integer; //incremented by createcoponent + ffindcompclasstag: integer; //stamp of createcomponenttag + fcheckfixups: moduleinfopoarty; + fskipall: integer; + fstreaming: integer; + function formfiletoname(const filename: msestring): msestring; + {$ifdef mse_nomethodswap} + procedure setmethodproperty(reader: treader; + instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); + {$else} + procedure findmethod(Reader: TReader; const aMethodName: string; + var Address: Pointer; var Error: Boolean); + {$endif} + function getinheritedmodule(const aclassname: string): pmoduleinfoty; + function findcomponentmodule(const acomponent: tcomponent): pmoduleinfoty; + procedure selectionchanged; +{$ifndef mse_nomethodswap} + procedure docopymethods(const source, dest: tcomponent; const force: boolean); +{$endif} + procedure writemodule(const amodule: pmoduleinfoty; const astream: tstream); + procedure notifydeleted(comp: tcomponent); + procedure componentdestroyed(const acomponent: tcomponent; const module: pmoduleinfoty); + procedure dofixup; + {$ifndef mse_nomethodswap} + procedure buildmethodtable(const amodule: pmoduleinfoty); + procedure releasemethodtable(const amodule: pmoduleinfoty); + {$endif} + protected + fstate: designerstatesty; +// procedure doasyncevent(var atag: integer); override; + procedure readererror(reader: treader; const message: string; + var handled: boolean); + procedure readerenumerror(const reader: treader; const atype: ptypeinfo; + const aitemname: string; var avalue: longword); + procedure readerseterror(const reader: treader; const atype: ptypeinfo; + const aitemname: string; var avalue: integer); + procedure forallmethodproperties(const aroot: tcomponent; + const ainstance: tobject; const data: pointer; + const aproc: propprocty; + const dochildren: boolean); + procedure componentevent(const event: tcomponentevent); override; + function checkmodule(const filename: msestring): pmoduleinfoty; + procedure checkident(const aname: string); + procedure beginstreaming({const amodule: pmoduleinfoty}); + procedure endstreaming({const amodule: pmoduleinfoty}); + {$ifndef mse_nomethodswap} + procedure internaldoswapmethodpointers(const aroot: tcomponent; + const ainstance: tobject; const ainit: boolean); + {$endif} + procedure dotouch(const amodule: pmoduleinfoty); + procedure handledesignexception(const sender: tobject); + public + constructor create; reintroduce; + destructor destroy; override; + + procedure begincomponentmodify; + procedure endcomponentmodify; + procedure beginpasting; + procedure endpasting; + + function beforemake: boolean; //true if ok + procedure modulechanged(const amodule: pmoduleinfoty); + procedure touch(const amodule: tmsecomponent); + procedure touchall; + function changemodulename(const filename: msestring; const avalue: string): string; + function changemoduleclassname(const filename: msestring; const avalue: string): string; + function changeinstancevarname(const filename: msestring; const avalue: string): string; + function checksubmodule(const ainstance: tcomponent; + out aancestormodule: pmoduleinfoty): boolean; + function getreferencingmodulenames(const amodule: pmoduleinfoty): stringarty; + function checkmethodtypes(const amodule: pmoduleinfoty; + const init: boolean): boolean; + //false on cancel +{$ifndef mse_nomethodswap} + procedure doswapmethodpointers(const ainstance: tobject; const ainit: boolean); +{$endif} +{$ifdef mse_nomethodswap} + procedure writedesignmethod(writer: twriter; instance: tpersistent; + propinfo: ppropinfo; + const methodvalue, defmethodvalue: tmethod; + var handled: boolean); +{$endif} + procedure ancestornotfound(Reader: TReader; const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent); + procedure findcomponentclass(Reader: TReader; const aClassName: string; + var ComponentClass: TComponentClass); + procedure findancestor(Writer: TWriter; Component: TComponent; + const aName: string; var Ancestor, RootAncestor: TComponent); + function findancestorcomponent(const acomponent: tcomponent): tcomponent; + function getancestormethods(const amodule: pmoduleinfoty): methodsarty; + procedure createcomponent1(reader: treader; componentclass: tcomponentclass; + var component: tcomponent); + function createcomponent: tcreatecomponentevent; + function selectedcomponents: componentarty; + + //idesigner + procedure componentmodified(const component: tobject; + const apropname: string = ''; const apropindex: int32 = -1); + procedure selectcomponent(instance: tcomponent); + procedure setselections(const list: idesignerselections); + function createnewcomponent(const module: tmsecomponent; + const aclass: tcomponentclass): tcomponent; + function createcurrentcomponent(const module: tmsecomponent): tcomponent; + function hascurrentcomponent: boolean; + procedure addcomponent(const module: tmsecomponent; + const acomponent: tcomponent); + procedure deleteselection(adoall: boolean = false); + procedure deletecomponent(const acomponent: tcomponent); + procedure clearselection; + procedure noselection; + + function getmethod(const aname: string; const methodowner: tmsecomponent; + const atype: ptypeinfo; const searchancestors: boolean): tmethod; + function getmethodname(const method: tmethod; const comp: tcomponent): string; + procedure changemethodname(const method: tmethod; newname: string; + const atypeinfo: ptypeinfo); + function createmethod(const aname: string; const module: tmsecomponent; + const atype: ptypeinfo): tmethod; + procedure checkmethod(const method: tmethod; const aname: string; + const module: tmsecomponent; const atype: ptypeinfo); + + function getcomponentname(const comp: tcomponent): string; + //returns qualified name for foreign modules + function getcomponentdispname(const comp: tcomponent): string; + //returns qualified name into root + procedure validaterename(const acomponent: tcomponent; + const curname, newname: string); reintroduce; + function getclassname(const comp: tcomponent): string; + //returns submoduleclassname if appropriate + function getcomponent(const aname: string; + const aroot: tcomponent): tcomponent; + //handles qualified names for foreign forms + function getcomponent(const apath: string; + out amodule: pmoduleinfoty): tcomponent; + function componentcanedit: boolean; + function getcomponenteditor: icomponenteditor; + function editcomponent(const aowner: tcomponent = nil): boolean; //false if no editor available + function getcomponentlist(const acomponentclass: tcomponentclass; + const filter: compfilterfuncty = nil; + const allmodules: boolean = false): componentarty; + function getcomponentnamelist(const acomponents: componentarty; + const amodule: tmsecomponent): msestringarty; overload; + //nil values ignored + function getcomponentnamelist(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil): msestringarty; overload; + function getcomponentnamelist(const acomponentclass: tcomponentclass; + const arootcomp: tcomponent; + const filter: compfilterfuncty = nil): msestringarty; overload; + function getcomponentnametree(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const findmode: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil; + const amodule: tcomponent = nil): tcompnameitem; + function getwidgetnamelist(const awidgetclass: widgetclassty; + const arootwidget: twidget; + const filter: compfilterfuncty = nil): msestringarty; + function getwidgetnametree(const rootwidget: twidget): tcompnameitem; + + function getancestorclassinfo(const ainstance: tcomponent; + const interfaceonly: boolean): classinfopoarty; + overload; + function getancestorclassinfo(const ainstance: tcomponent; + const interfaceonly: boolean; + out aunits: unitinfopoarty): classinfopoarty; + overload; + + function getmodulex(const amodule: tmsecomponent): integer; + procedure setmodulex(const amodule: tmsecomponent; avalue: integer); + function getmoduley(const amodule: tmsecomponent): integer; + procedure setmoduley(const amodule: tmsecomponent; avalue: integer); + procedure modulesizechanged(const amodule: tmsecomponent); + + function isownedmethod(const root: tcomponent; + const method: tmethod): boolean; + procedure getmethodinfo(const method: tmethod; out moduleinfo: pmoduleinfoty; + out methodinfo: pmethodinfoty); + function getmodules: tmodulelist; + + procedure beginskipall; + procedure endskipall; + function loadformfile(filename: msestring; + const skipexisting: boolean): pmoduleinfoty; + function saveformfile(const modulepo: pmoduleinfoty; + const afilename: msestring; createdatafile: boolean): boolean; + //false if canceled + procedure refreshdatafile(const amodule: pmoduleinfoty); + function saveall(noconfirm,createdatafile: boolean): modalresultty; + procedure savecanceled; //resets fallsaved + procedure setactivemodule(const adesignform: tcustommseform); + function sourcenametoformname(const aname: filenamety): filenamety; + + function closemodule(const amodule: pmoduleinfoty; + const checksave: boolean): boolean; //true if closed + procedure showformdesigner(const amodule: pmoduleinfoty); + procedure showastext(const amodule: pmoduleinfoty); + procedure showobjectinspector; + function actmodulepo: pmoduleinfoty; + function modified: boolean; + function clickedcomp: tcomponent; + procedure moduledestroyed(const amodule: pmoduleinfoty); + procedure addancestorinfo(const ainstance,aancestor: tmsecomponent); + function copycomponent(const source: tmsecomponent; + const root: tmsecomponent; const asinherited: boolean; + const noloading: boolean):tmsecomponent; + procedure revert(const acomponent: tcomponent); + function checkcanclose(const amodule: pmoduleinfoty; out references: string): boolean; + + property modules: tmodulelist read getmodules; + property descendentinstancelist: tdescendentinstancelist read + fdescendentinstancelist; + property selections: tdesignerselections read fselections; + //do not modify! + + property objformat: objformatty read fobjformat write fobjformat default of_default; + property designfiles: tindexedfilenamelist read fdesignfiles; + + property ongetmodulenamefile: getmoduleeventty read fongetmodulenamefile + write fongetmodulenamefile; + property ongetmoduletypefile: getmoduletypeeventty read fongetmoduletypefile + write fongetmoduletypefile; + end; + +procedure createbackupfile(const newname,origname: filenamety; + var backupcreated: boolean; const backupcount: integer); + +function designer: tdesigner; +function isdatasubmodule(const acomponent: tobject; + const iconified: boolean = false; + const both: boolean = false): boolean; + +implementation +uses + msestream,msefileutils, +// {$ifdef mswindows}windows{$else}mselibc{$endif}, + designer_bmp,msesys,msewidgets,formdesigner,objectinspector,mseformatstr, + msefiledialog,projectoptionsform,sourceupdate,sourceform,sourcepage, + pascaldesignparser,msearrayprops,rtlconsts,msedatamodules, + msesimplewidgets,msesysutils,mseobjecttext,msestreaming,msedatanodes,main, + actionsmodule,mseeditglob; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + renewbackuptag = 0; + +type + tcomponent1 = class(tcomponent); + tmsecomponent1 = class(tmsecomponent); + twidget1 = class(twidget); + twriter1 = class(twriter); + treader1 = class(treader); +{$ifdef mse_nomethodswap} + tbinaryobjectwriter1 = class(tbinaryobjectwriter); +{$endif} + moduleeventty = (me_none,me_componentmodified); + +var + fdesigner: tdesigner; + loadingdesigner: tdesigner; + methodaddressdummy: ptruint; + submodulecopy: integer; + +function designer: tdesigner; +begin + result:= fdesigner; +end; + +function isnosubcomp(const acomp: tcomponent): boolean; +begin + result:= (cssubcomponent in acomp.componentstyle) and + (acomp is tmsecomponent) and + not(cs_subcompref in tmsecomponent1(acomp).fmsecomponentstate); +end; + +function isdatasubmodule(const acomponent: tobject; + const iconified: boolean = false; + const both: boolean = false): boolean; +begin + result:= (acomponent <> nil) and (acomponent is tmsedatamodule) and + (csinline in tmsedatamodule(acomponent).componentstate) and + (both or + (iconified = (dmo_iconic in tmsedatamodule(acomponent).options))); +end; + +function issubprop(const obj1: tobject): boolean; +begin + result:= (obj1 <> nil) and (not (obj1 is tcomponent) or + (cssubcomponent in tcomponent(obj1).componentstyle) and + ((tcomponent(obj1).owner = nil) or + (obj1 is tmsecomponent) and + not(cs_subcompref in tmsecomponent1(obj1).fmsecomponentstate))); +end; + +function ismodule(const acomponent: tcomponent): boolean; +begin + result:= (acomponent = nil) or (acomponent.owner = nil); +// result:= (acomponent.owner = nil) or (acomponent.owner.owner = nil); +end; + +function getglobalcomponent(const Name: string): TComponent; +begin + if (loadingdesigner <> nil) or (submodulecopy > 0) then begin + result:= fdesigner.fmodules.findmoduleinstancebyname(name); + end + else begin + result:= nil; + end; +end; + +procedure beginsubmodulecopy; +begin + inc(submodulecopy); + if submodulecopy = 1 then begin + lockfindglobalcomponent; + RegisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + end; +end; + +procedure endsubmodulecopy; +begin + dec(submodulecopy); + if submodulecopy = 0 then begin + unlockfindglobalcomponent; + unregisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + end; +end; + +{ tancestorlist } + +constructor tancestorlist.create; +begin + inherited create(sizeof(ancestorinfoty)); +end; + +procedure tancestorlist.doitemdestroyed(const sender: tmsecomponent); +var + int1: integer; + bo1: boolean; +begin + for int1:= count - 1 downto 0 do begin + with pancestorinfoty(getitempo(int1))^ do begin + bo1:= false; + if descendent = sender then begin + descendent:= nil; + bo1:= true; + end; + if ancestor = sender then begin + ancestor:= nil; + bo1:= true; + end; + if bo1 then begin + delete(int1); + end; + end; + end; +end; + +procedure tancestorlist.itemdestroyed(const sender: iobjectlink); +begin + doitemdestroyed(tmsecomponent(sender.getinstance)); +end; + +function tancestorlist.getdescendentar( + const aancestor: tmsecomponent): msecomponentarty; +var + int1,int2: integer; + po1: pancestorinfoty; +begin + setlength(result,count); + int2:= 0; + po1:= datapo; + for int1:= 0 to high(result) do begin + if po1^.ancestor = aancestor then begin + result[int2]:= po1^.descendent; + inc(int2); + end; + inc(po1); + end; + setlength(result,int2); +end; + +procedure tancestorlist.add(const adescendent, aancestor: tmsecomponent); +var + info: ancestorinfoty; +begin + fillchar(info,sizeof(info),0); + fobjectlinker.link(adescendent); + fobjectlinker.link(aancestor); + info.descendent:= adescendent; + info.ancestor:= aancestor; + inherited add(info); +end; + +procedure tancestorlist.dounlink(var item); +begin + with ancestorinfoty(item) do begin + fobjectlinker.unlink(descendent); + fobjectlinker.unlink(ancestor); + end; +end; + +{$ifndef mse_nomethodswap} +procedure tancestorlist.streamingswapmethodpointer(const acomp: tcomponent); +begin + if (fstreaming > 0) then begin + if finditem(pointerarty(fswappedancestors),acomp) < 0 then begin + designer.doswapmethodpointers(acomp,false); + additem(pointerarty(fswappedancestors),acomp); + end; + end; +end; +{$endif} + +function tancestorlist.findancestor( + const adescendent: tcomponent): tmsecomponent; +var + po1: pancestorinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if po1^.descendent = adescendent then begin + result:= po1^.ancestor; + break; + end; + inc(po1); + end; +{$ifndef mse_nomethodswap} + if result <> nil then begin + streamingswapmethodpointer(result); + end; +{$endif} +end; + +procedure tancestorlist.beginstreaming; +begin + inc(fstreaming); +end; + +procedure tancestorlist.endstreaming; +{$ifndef mse_nomethodswap} +var + int1: integer; + ar1: componentarty; +{$endif} +begin + dec(fstreaming); +{$ifndef mse_nomethodswap} + ar1:= nil; //compiler warning + if fstreaming = 0 then begin + ar1:= copy(fswappedancestors); + fswappedancestors:= nil; + for int1:= 0 to high(ar1) do begin + designer.doswapmethodpointers(ar1[int1],true); + end; + end; +{$endif} +end; + +function tancestorlist.finddescendent(const aancestor: tcomponent): tmsecomponent; +var + po1: pancestorinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if po1^.ancestor = aancestor then begin + result:= po1^.descendent; + break; + end; + inc(po1); + end; +end; + +function tancestorlist.finddescendentinfo(const adescendent: tcomponent): pancestorinfoty; +var + po1: pancestorinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if po1^.descendent = adescendent then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +function tancestorlist.findancestorinfo(const aancestor: tcomponent): pancestorinfoty; +var + po1: pancestorinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if po1^.ancestor = aancestor then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +function tancestorlist.findinfo(const ainfo: ancestornameinfoty): pancestorinfoty; +var + po1: pancestorinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to count - 1 do begin + if (namepathowner(po1^.descendent) = ainfo.desc) and + (namepathowner(po1^.ancestor) = ainfo.anc) then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +procedure tancestorlist.getinfo(const apo: pancestorinfoty; + out info: ancestornameinfoty); +begin + info.desc:= namepathowner(apo^.descendent); + info.anc:= namepathowner(apo^.ancestor); +end; + +{ tdesignerancestorlist } + +constructor tdesignerancestorlist.create(aowner: tdesigner); +begin + fdesigner:= aowner; + inherited create; +end; + +{ tsubmodulelist } + +procedure tsubmodulelist.finalizerecord(var item); +var + comp: tmsecomponent; +begin + with ancestorinfoty(item) do begin + comp:= ancestor; + ancestor:= nil; + end; + inherited; + if comp <> nil then begin + removefixupreferences(comp,''); + end; + comp.Free; +end; + +procedure tsubmodulelist.add(const amodule: tmsecomponent); +var + comp1: tmsecomponent; +begin + if findancestor(amodule) = nil then begin + comp1:= fdesigner.copycomponent(amodule,amodule,false,false); + if comp1 is twidget then begin + with twidget1(comp1) do begin + if ownswindow1() then begin + freeandnil(fwindow); //never mapped + rootchanged([]); + end; + end; + end; + inherited add(amodule,comp1); +// inherited add(amodule,fdesigner.copycomponent(amodule,nil)); + end; +end; + +procedure tsubmodulelist.dorenewbackup; +var + po1: pancestorinfoty; + comp: tmsecomponent; + amodule: tmsecomponent; + int1: integer; +begin + try + for int1:= 0 to high(frenewbackuplist) do begin + amodule:= frenewbackuplist[int1]; + if amodule <> nil then begin + po1:= finddescendentinfo(amodule); + if po1 <> nil then begin + comp:= po1^.ancestor; + po1^.ancestor:= nil; + if comp <> nil then begin + removefixupreferences(comp,''); + end; + comp.Free; + {$ifdef mse_debugcopycomponent} + debugwriteln('***renewbackup before copy '+amodule.name); + dumpcomponent(amodule,'source:'); + {$endif} +// fdesigner.fsubmoduleinfopo:= nil; + po1^.ancestor:= fdesigner.copycomponent(amodule,amodule,false,false); + {$ifdef mse_debugcopycomponent} + debugwriteln('***renewbackup after copy '+amodule.name); + dumpcomponent(amodule,'source:'); + dumpcomponent(po1^.ancestor,'backup:'); + {$endif} + // po1^.ancestor:= fdesigner.copycomponent(amodule,nil); + fobjectlinker.link(po1^.ancestor); + end; + end; + end; + finally + frenewbackuplist:= nil; + end; +end; + +procedure tsubmodulelist.receiveevent(const event: tobjectevent); +begin + if (event is tasyncevent) and + (tasyncevent(event).tag = renewbackuptag) then begin + dorenewbackup; + end; +end; + +procedure tsubmodulelist.renewbackup(const amodule: tmsecomponent); +begin + if frenewbackuplist = nil then begin + application.postevent(tasyncevent.create(ievent(self),renewbackuptag), + [peo_local]); + end; + additem(pointerarty(frenewbackuplist),amodule); +end; + +function tsubmodulelist.findoldancestor( + const adescendent: tmsecomponent): tmsecomponent; +var + po1: pancestorinfoty; +begin + result:= nil; + po1:= finddescendentinfo(adescendent); + if po1 <> nil then begin + result:= po1^.ancestor; + end; +end; + +procedure tsubmodulelist.doitemdestroyed(const sender: tmsecomponent); +var + int1: integer; +begin + for int1:= 0 to high(frenewbackuplist) do begin + if frenewbackuplist[int1] = sender then begin + frenewbackuplist[int1]:= nil; + end; + end; + inherited; +end; + +const + skipmark = '1w%f62*7/*+z'; + +type + trefreshexception = class(exception) + end; + +{ treaderrorhandler } + +destructor treaderrorhandler.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fcomponentar) do begin + fcomponentar[int1].free; //FPC does not free the component + end; + inherited; +end; + +procedure treaderrorhandler.onerror(reader: treader; const message: string; + var handled: boolean); +begin + if message = skipmark then begin + handled:= true; + end; +end; + +procedure treaderrorhandler.notification(acomponent: tcomponent; operation: toperation); +begin + if (operation = opremove) then begin + removeitem(pointerarty(fcomponentar),acomponent); + removeitem(pointerarty(fnewcomponents),acomponent); + end; + inherited; +end; + +procedure treaderrorhandler.doraise(const acomponent: tcomponent); +begin + if acomponent <> nil then begin + additem(pointerarty(fcomponentar),acomponent); + acomponent.freenotification(self); + end; + raise trefreshexception.create(skipmark); +end; + +procedure treaderrorhandler.ancestornotfound(Reader: TReader; + const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent); +begin + designer.fsubmoduleinfopo:= nil; //reset for createcomponent + component:= findancestorcomponent(reader,componentname); + if component = nil then begin + doraise(nil); //changed name + end; +end; + +procedure treaderrorhandler.onsetname(reader: treader; + component: tcomponent; var aname: string); +begin +// if (component.owner <> nil) and (csinline in component.owner.componentstate) and +// not (csancestor in component.componentstate) then begin + if component.owner = froot then begin + additem(pointerarty(fnewcomponents),component); + component.freenotification(self); +// doraise(component); //new component placed into submodule + end; +end; + +{ tdescendentinstancelist } + +procedure tdescendentinstancelist.delcomp(child: tcomponent); +begin + tcomponent1(child).getchildren({$ifdef FPC}@{$endif}delcomp,froot); + additem(pointerarty(fdelcomps),child); +end; + +procedure tdescendentinstancelist.addcomp(child: tcomponent); +begin + fmodule^.components.add(child); + tcomponent1(child).getchildren({$ifdef FPC}@{$endif}addcomp,child); +end; + +type + tdelcomp = class(tcomponent) + private + fdelcomps: componentarty; + protected + procedure notification(acomponent: tcomponent; operation: toperation); override; + end; + +procedure tdelcomp.notification(acomponent: tcomponent; operation: toperation); +var + int1: integer; +begin + inherited; + if operation = opremove then begin + for int1:= high(fdelcomps) downto 0 do begin + if fdelcomps[int1] = acomponent then begin + fdelcomps[int1]:= nil; + end; + end; + end; +end; + +(* +procedure tdescendentinstancelist.revert(const info: pancestorinfoty; + const module: pmoduleinfoty; out anewinstance: tmsecomponent; + const norootposition: boolean = false; + const initflags: boolean = true); +var + comp1,comp2: tmsecomponent; + decomp: tdelcomp; + parent1: twidget; + str1: string; + int1: integer; + isroot: boolean; + ancestorclassname1: string; + actualclassname1: pshortstring; + pt1: pointty; + ar1: msecomponentarty; + ancestorbefore: tmsecomponent; + infoancestor: tmsecomponent; + po1: pancestorinfoty; +begin +{$ifdef mse_debugsubmodule} + debugwriteln('***revert module'+ module^.instance.name+ + ' dest '+info^.descendent.name+' anch '+info^.ancestor.name); + po1:= datapo; + for int1:= 0 to count-1 do begin + debugwriteln('*'+inttostr(int1)+' '+po1^.ancestor.name+' '+ + po1^.descendent.name); + inc(po1); + end; +{$endif} + comp1:= info^.descendent; + infoancestor:= info^.ancestor; + isroot:= comp1 = module^.instance; + delete((pchar(info)-pchar(datapo)) div recordsize); //remove item + ancestorbefore:= nil; //compiler warning + ar1:= nil; //compiler warning + if isroot then begin + ar1:= getdescendentar(comp1); //restore after revert + po1:= fdesigner.fsubmodulelist.finddescendentinfo(comp1); + if po1 <> nil then begin + ancestorbefore:= po1^.ancestor; + po1^.ancestor:= nil; //don't free + end; + end; + with tmsecomponent1(comp1) do begin + ancestorclassname1:= fancestorclassname; + actualclassname1:= factualclassname; + end; + +// info^.descendent:= nil; //no recursion + if comp1 is twidget then begin + with twidget1(comp1) do begin + parent1:= parentwidget; + pt1:= tformdesignerfo(module^.designform).modulerect.pos; + end; + end + else begin + parent1:= nil; + pt1:= getcomponentpos(comp1); + end; + str1:= comp1.name; +// fobjectlinker.unlink(comp1); + fdelcomps:= nil; + froot:= comp1.owner; + if ismodule(comp1) then begin + froot:= comp1; + end; + delcomp(comp1); + decomp:= tdelcomp.create(nil); + try + decomp.fdelcomps:= fdelcomps; + for int1:= high(fdelcomps) downto 0 do begin + fdelcomps[int1].freenotification(decomp); + end; + for int1:= high(fdelcomps) downto 0 do begin + fdelcomps[int1].free; + end; + finally + decomp.free; + end; + fdelcomps:= nil; + comp2:= fdesigner.copycomponent(infoancestor,infoancestor); + if isroot and initflags then begin + initrootdescendent(comp2); + end; + + { + if not isroot then begin +// comp2:= fdesigner.copycomponent(info^.ancestor,nil); + comp2:= fdesigner.copycomponent(info^.ancestor,info^.ancestor); + end + else begin + comp2:= fdesigner.copycomponent(info^.ancestor,info^.ancestor); + initrootdescendent(comp2); + end; + } +// info^.descendent:= comp2; + comp2.name:= str1; + with tmsecomponent1(comp2) do begin + fancestorclassname:= ancestorclassname1; + factualclassname:= actualclassname1; + end; + if not isroot then begin + initinline(comp2); + end + else begin + tcomponent1(comp2).setancestor(true); + end; + { + if isroot then begin + tcomponent1(comp2).setancestor(true); + end + else begin + tmsecomponent1(comp2).setinline(true); + end; + } +// checkinline(comp2); +// fobjectlinker.link(comp2); + if isroot then begin + module^.instance:= comp2; + if norootposition then begin + if (comp2 is twidget) then begin + with twidget1(comp2) do begin + fwidgetrect.pos:= pt1; //do not restore position + end; + end + else begin + setcomponentpos(comp2,pt1); + end; + end; + tformdesignerfo(module^.designform).module:= comp2; + end + else begin + tmsecomponent1(comp2).setinline(true); + module^.instance.insertcomponent(comp2); + end; + if parent1 <> nil then begin + twidget(comp2).parentwidget:= parent1; + end; + fmodule:= module; + addcomp(comp2); + removefixupreferences(module^.instance,''); + anewinstance:= comp2; + add(comp2,infoancestor); //restore entry +// add(comp2,info^.ancestor); //restore entry + if isroot then begin + for int1:= 0 to high(ar1) do begin + add(ar1[int1],comp2); + //restore entry; + end; + if ancestorbefore = nil then begin +// fdesigner.fsubmodulelist.add(comp2); //should not happen + end + else begin + fdesigner.fsubmodulelist.add(comp2,ancestorbefore); + end; + end; +{$ifdef mse_debugsubmodule} + debugwriteln('***end revert' ); + po1:= datapo; + for int1:= 0 to count-1 do begin + debugwriteln('*'+inttostr(int1)+' '+po1^.ancestor.name+' '+ + po1^.descendent.name); + inc(po1); + end; +{$endif} +end; +*) + +function tdescendentinstancelist.getancestors( + const adescendent: tcomponent): componentarty; + + procedure addancestors(const adescendent: tcomponent); + var + po1: pointer; + int1: integer; + begin + po1:= datapo; + for int1:= 0 to count - 1 do begin + with(pancestorinfoaty(po1)^[int1]) do begin + if descendent = adescendent then begin + if finditem(pointerarty(result),ancestor) < 0 then begin + additem(pointerarty(result),ancestor); + end; + addancestors(ancestor); + end + end; + end; + end; + +begin + result:= nil; + addancestors(adescendent); +end; + +function tdescendentinstancelist.getancestorsandchildren( + const adescendent: tcomponent): componentarty; +var + po1: pointer; + int1: integer; + po2: pmoduleinfoty; +begin + result:= getancestors(adescendent); + po1:= datapo; + for int1:= 0 to count - 1 do begin + with(pancestorinfoaty(po1)^[int1]) do begin + if ancestor = adescendent then begin + po2:= fdesigner.modules.findmodulebycomponent(descendent); + if (po2 <> nil) and (finditem(pointerarty(result),po2^.instance) < 0) then begin + additem(pointerarty(result),po2^.instance); + end; + end; + end; + end; +end; + +function tdescendentinstancelist.getdescendents( + const aancestor: tcomponent): componentarty; +var + recursionlevel: integer; + + procedure adddescendent(const aancestor: tcomponent); + var + int1: integer; + po1: pancestorinfoaty; + begin + dec(recursionlevel); + if recursionlevel > 0 then begin + po1:= datapo; + for int1:= count - 1 downto 0 do begin + with po1^[int1] do begin + if ancestor = aancestor then begin + additem(pointerarty(result),descendent); + adddescendent(descendent); + end; + end; + end; + end; + inc(recursionlevel); + end; + +begin + result:= nil; + recursionlevel:= 32; //max + adddescendent(aancestor); +end; + +{$ifdef mse_nomethodswap} +procedure tdescendentinstancelist.setrefreshmethod(reader: treader; + instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); +var + m1: tmethod; + po1: pmethodinfoty; + int1: integer; +begin + m1.code:= nil; + m1.data:= nil; + for int1:= high(frefreshmethods) downto 0 do begin + if frefreshmethods[int1] <> nil then begin + po1:= frefreshmethods[int1].findmethodbyname(themethodname); + if po1 <> nil then begin + m1.data:= po1^.address; + break; + end; + end; + end; + setmethodprop(instance,propinfo,m1); + handled:= true; +end; +{$else} +procedure tdescendentinstancelist.findrefreshmethod(reader: treader; + const amethodname: string; var address: pointer; var error: boolean); +var +// method: tmethod; + po1: pmethodinfoty; + int1: integer; +begin + if error then begin + for int1:= high(frefreshmethods) downto 0 do begin + po1:= frefreshmethods[int1].findmethodbyname(amethodname); +// po1:= fdesigner.floadingmodulepo^.methods.findmethodbyname(amethodname); + if po1 <> nil then begin + address:= po1^.address; + break; + end; + end; + error:= false; + end; +end; +{$endif} + +procedure tdescendentinstancelist.domodulemodified(const amodule: pmoduleinfoty; + modifylevel: integer; + destcompnames,ancestorcompnames: stringarty; + newancestorcomps,oldancestorcomps: msecomponentarty); + //todo: simplify, optimize +var + dependentmodules: moduleinfopoarty; + dependentmod: moduleinfopoarty; + comp1: tmsecomponent; + newancestor0: tmsecomponent; + oldancestor0: tmsecomponent; + descendent1,newancestor1,oldancestor1: tmsecomponent; + int1,int2,int3,int4: integer; +// str1: string; + destname: string; + po1: pancestorinfoty; + po2: pmoduleinfoty; + bo1,bo2,bo3,newcomponent: boolean; + pt1: pointty; + taborderbefore: integer; + depmodcomps: array of stringarty; + dependentcomponents: array of msecomponentarty; + newancestorcomponents: array of msecomponentarty; + oldancestorcomponents: array of msecomponentarty; +// sourcemethodtab: pointer; + +begin + if modifylevel >= 16 then begin + showmessage(actionsmo.c[ord(ac_recursiveforminheritance)]+ + amodule^.filename+'".',actionsmo.c[ord(ac_error)]); + sysutils.abort; + end; + if modifylevel = 0 then begin + fdeletedcomps:= nil; + begingloballoading; + end; + inc(modifylevel); + try + dependentmodules:= nil; //compilerwarning + {$ifdef mse_debugsubmodule} + debugwriteln('***modulemodified '+inttostr(modifylevel)+' '+ + amodule^.instance.name); + debugwriteln(' destcompnames: '+debugstringarty(destcompnames)); + debugwriteln(' ancestorcompnames: '+debugstringarty(ancestorcompnames)); + debugwriteln(' newancestorcomps: '+ + debugcomprootnames(componentarty(newancestorcomps))); + debugwriteln(' oldancestorcomps: '+ + debugcomprootnames(componentarty(oldancestorcomps))); + // po1:= datapo; + // for int1:= 0 to count-1 do begin + // debugwriteln('*'+inttostr(int1)+' '+po1^.ancestor.name+' '+ + // po1^.descendent.name); + // inc(po1); + // end; + {$endif} + + newancestor0:= amodule^.instance; + oldancestor0:= fdesigner.fsubmodulelist.findoldancestor(amodule^.instance); + po1:= datapo; + int2:= 0; + setlength(dependentmod,fcount); //max + for int1:= 0 to fcount - 1 do begin + if po1^.ancestor = amodule^.instance then begin + // dependentcomponents[int2]:= po1^.descendent; + if ismodule(po1^.descendent) then begin //inherited form + comp1:= po1^.descendent; + destname:= 'OWNER'; + end + else begin + comp1:= tmsecomponent(po1^.descendent.owner); + destname:= po1^.descendent.name; + end; + po2:= fdesigner.modules.findmodule(comp1); + dependentmod[int2]:= po2; + inc(int2); + {$ifdef mse_debugsubmodule} + debugwriteln(' item ancestor: '+po1^.ancestor.name+ ' descendent: '+ + po1^.descendent.name + ' module: '+po2^.instance.name); + {$endif} + int3:= finditem(pointerarty(dependentmodules),po2); + if int3 < 0 then begin + int3:= high(dependentmodules)+2; + setlength(dependentmodules,int3); + setlength(depmodcomps,int3); + setlength(dependentcomponents,int3); + setlength(newancestorcomponents,int3); + setlength(oldancestorcomponents,int3); + dec(int3); + dependentmodules[int3]:= po2; + end; + if (destcompnames = nil) then begin + additem(depmodcomps[int3],destname); + additem(pointerarty(dependentcomponents[int3]),po1^.descendent); + additem(pointerarty(newancestorcomponents[int3]),newancestor0); + additem(pointerarty(oldancestorcomponents[int3]),oldancestor0); + end + else begin + for int4:= 0 to high(destcompnames) do begin + additem(depmodcomps[int3],destname+'.'+destcompnames[int4]); + additem(pointerarty(newancestorcomponents[int3]),newancestorcomps[int4]); + additem(pointerarty(oldancestorcomponents[int3]),oldancestorcomps[int4]); + additem(pointerarty(dependentcomponents[int3]),po1^.descendent); + end; + end; + // adduniqueitem(pointerarty(dependentmodules),po2); + end; + inc(po1); + end; + setlength(dependentmod,int2); + + if int2 > 0 then begin + {$ifdef mse_debugsubmodule} + debugwriteln('*descendents:'); + for int1:= 0 to high(dependentmodules) do begin + debugwriteln('module: '+dependentmodules[int1]^.instance.name); + for int2:= 0 to high(depmodcomps[int1]) do begin + debugwriteln(' '+depmodcomps[int1][int2]); + end; + end; + {$endif} + beginsubmodulecopy; + beginstreaming(amodule); + if modifylevel = 1 then begin + {$ifndef mse_nomethodswap} + streamingswapmethodpointer(amodule^.instance); + {$endif} +// frefreshmethods:= fdesigner.getancestormethods(amodule); + {$ifndef mse_nomethodswap} + amodule^.methods.createmethodtable(frefreshmethods); + {$endif} + end; + insertitem(pointerarty(frefreshmethods),0,nil); +// setlength(frefreshmethods,high(frefreshmethods)+3); +// frefreshmethods[high(frefreshmethods)-1]:= amodule^.methods; + {$ifndef mse_nomethodswap} + for int1:= 0 to high(dependentmodules) do begin + dependentmodules[int1]^.methods.createmethodtable(frefreshmethods); + // fdesigner.getancestormethods(dependentmodules[int1])); + end; + {$endif} + stackarray(pointerarty(dependentmodules),pointerarty(fmodifiedmodules)); + try +// oldancestor0:= fdesigner.fsubmodulelist.findoldancestor(amodule^.instance); + for int1:= 0 to high(dependentmodules) do begin + {$ifndef mse_nomethodswap} + streamingswapmethodpointer(dependentmodules[int1]^.instance); + {$endif} + frefreshmethods[0]:= dependentmodules[int1]^.methods; + newcomponent:= false; + for int2:= 0 to high(depmodcomps[int1]) do begin + descendent1:= dependentcomponents[int1][int2]; + newancestor1:= amodule^.instance; + oldancestor1:= oldancestor0; + descendent1:= tmsecomponent( + findnestedcomponent(dependentmodules[int1]^.instance, + depmodcomps[int1][int2])); + if ancestorcompnames <> nil then begin + int3:= int2 mod length(ancestorcompnames); + newancestor1:= newancestorcomps[int3]; + oldancestor1:= oldancestorcomps[int3]; + {$ifdef mse_debugsubmodule} + debugwriteln('*refreshmain descendent: '+debugcomprootname(descendent1)+ + ' newancestor: '+debugcomprootname(newancestor1)+ + ' oldancestor: '+debugcomprootname(oldancestor1)); + {$endif} + refreshancestor(fdeletedcomps,descendent1,newancestor1, + oldancestor1,false, + {$ifdef FPC}@{$endif}fdesigner.findancestor, + {$ifdef FPC}@{$endif}fdesigner.findcomponentclass, + fdesigner.createcomponent(), + {$ifdef mse_nomethodswap} + {$ifdef FPC}@{$endif}setrefreshmethod, + {$ifdef FPC}@{$endif}fdesigner.writedesignmethod, + @newcomponent + {$else} + {$ifdef FPC}@{$endif}findrefreshmethod, + dependentmod[int1]^.methods.fmethodtable + {amodule^.methods.fmethodtable}, + dependentmod[int1]^.methods.fmethodtable + {$endif}); + end + else begin + if destcompnames <> nil then begin + int3:= int2 mod length(destcompnames); + newancestor1:= newancestorcomps[int3]; + oldancestor1:= oldancestorcomps[int3]; + end; + bo3:= (csinline in descendent1.componentstate) and + (descendent1.owner <> nil); + //whole submodule + bo1:= false; + bo2:= false; + if bo3 then begin //submodule + bo1:= descendent1 is twidget; + if bo1 then begin + pt1:= twidget(descendent1).pos; + taborderbefore:= twidget(descendent1).taborder; + end + else begin + bo2:= isdatasubmodule(descendent1); + if bo2 then begin + pt1:= getcomponentpos(descendent1); + end; + end; + end; + {$ifdef mse_debugsubmodule} + debugwriteln('*refreshcomps descendent: '+debugcomprootname(descendent1)+ + ' newancestor: '+debugcomprootname(newancestor1)+ + ' oldancestor: '+debugcomprootname(oldancestor1)); + {$endif} + refreshancestor(fdeletedcomps,descendent1,newancestor1, + oldancestor1,false, + {$ifdef FPC}@{$endif}fdesigner.findancestor, + {$ifdef FPC}@{$endif}fdesigner.findcomponentclass, + fdesigner.createcomponent(), + {$ifdef mse_nomethodswap} + {$ifdef FPC}@{$endif}setrefreshmethod, + {$ifdef FPC}@{$endif}fdesigner.writedesignmethod, + @newcomponent + {$else} + {$ifdef FPC}@{$endif}findrefreshmethod, + amodule^.methods.fmethodtable, + dependentmod[int1]^.methods.fmethodtable + {$endif}); + if bo2 then begin + end; + if bo1 then begin + twidget(descendent1).pos:= pt1; //restore insert position + twidget(descendent1).taborder:= taborderbefore; + end + else begin + if bo2 then begin + setcomponentpos(descendent1,pt1); //restore insert position + end; + end; + end; + end; + if newcomponent then begin + with dependentmodules[int1]^ do begin + components.assigncomps(instance) + end; + end; + end; + for int1:= 0 to high(dependentmodules) do begin + domodulemodified(dependentmodules[int1],modifylevel, + depmodcomps[int1],destcompnames, + newancestorcomponents[int1],oldancestorcomponents[int1]); + end; + finally + if frefreshmethods <> nil then begin + setlength(frefreshmethods,high(frefreshmethods)); + end; + fdesigner.fsubmodulelist.renewbackup(amodule^.instance); + {$ifndef mse_nomethodswap} + amodule^.methods.releasemethodtable; + {$endif} + endsubmodulecopy; + endstreaming; + end; + end + else begin + fdesigner.fsubmodulelist.renewbackup(amodule^.instance); + end; + {$ifdef mse_debugsubmodule} + debugwriteln('***end modulemodified '+inttostr(modifylevel)+' '+ + amodule^.instance.name); + {$endif} + if modifylevel = 1 then begin + notifygloballoading; + if fdeletedcomps <> nil then begin + freecomponents(fdeletedcomps); + fdeletedcomps:= nil; + modulemodified(amodule); //refresh again + end; + end; + finally + if modifylevel = 1 then begin + endgloballoading; + end; + end; +end; + +procedure tdescendentinstancelist.modulemodified(const amodule: pmoduleinfoty); +var + int1: integer; +begin + if not fmodulemodifying then begin + fmodulemodifying:= true; + fmodifiedmodules:= nil; + try + domodulemodified(amodule,0,nil,nil,nil,nil); + finally + try + {$ifndef mse_nomethodswap} + for int1:= 0 to high(fmodifiedmodules) do begin + fmodifiedmodules[int1]^.methods.releasemethodtable; + end; + {$endif} + for int1:= 0 to high(fmodifiedmodules) do begin + fdesigner.modulechanged(fmodifiedmodules[int1]); + end; + finally + fmodulemodifying:= false; + end; + end; + end; +end; + +procedure tdescendentinstancelist.componentnamechanged( + const amodule: pmoduleinfoty; + const acomponent: tcomponent; const newname: string); +var + reclevel: integer; + namepath: string; + newpath: string; + + procedure donamechange(aancestor: pmoduleinfoty); + var + int1: integer; + po1: pancestorinfoty; + comp1: tcomponent; + begin + if aancestor <> nil then begin + if reclevel >= 16 then begin + showmessage(actionsmo.c[ord(ac_recursiveforminheritance)]+ + amodule^.filename+'".',actionsmo.c[ord(ac_error)]); + sysutils.abort; + end; + inc(reclevel); + po1:= datapo; + for int1:= 0 to count-1 do begin + if po1^.ancestor = aancestor^.instance then begin + comp1:= findnestedcomponent(po1^.descendent,namepath); + if comp1 <> nil then begin + comp1.name:= newname; + end; + donamechange(fdesigner.modules.findmodule(po1^.descendent)); + end; + inc(po1); + end; + dec(reclevel); + end; + end; + + procedure docheckname(aancestor: pmoduleinfoty); + var + int1: integer; + po1: pancestorinfoty; + comp1: tcomponent; + begin + if aancestor <> nil then begin + if reclevel >= 16 then begin + showmessage(actionsmo.c[ord(ac_recursiveforminheritance)]+ + amodule^.filename+'".',actionsmo.c[ord(ac_error)]); + sysutils.abort; + end; + inc(reclevel); + po1:= datapo; + for int1:= 0 to count-1 do begin + if po1^.ancestor = aancestor^.instance then begin + comp1:= findnestedcomponent(po1^.descendent,newpath); + if comp1 <> nil then begin + raise exception.create(po1^.descendent.name+': '+ + ansistring(actionsmo.c[ord(ac_component)])+ + newpath+ansistring(actionsmo.c[ord(ac_exists)])); + end; + donamechange(fdesigner.modules.findmodule(po1^.descendent)); + end; + inc(po1); + end; + dec(reclevel); + end; + end; + +var + ar1: componentarty; + int1: integer; +begin + if not fcomponentnamechanging then begin + fcomponentnamechanging:= true; + try + ar1:= ownercomponentpath(acomponent); + if high(ar1) > 0 then begin + namepath:= ar1[1].name; + for int1:= 2 to high(ar1) do begin + namepath:= namepath+'.'+ar1[int1].name; + end; + if high(ar1) > 1 then begin + newpath:= ar1[1].name; + for int1:= 2 to high(ar1)-1 do begin + namepath:= namepath+'.'+ar1[int1].name; + end; + newpath:= newpath+'.'+newname; + end + else begin + newpath:= newname; + end; + reclevel:= 0; + docheckname(amodule); + reclevel:= 0; + donamechange(amodule); + end; + finally + fcomponentnamechanging:= false; + end; + end; +end; + +procedure tdescendentinstancelist.add(const instance,ancestor: tmsecomponent; + const submodulelist: tsubmodulelist); +begin + submodulelist.add(ancestor); + inherited add(instance,ancestor); +end; + +function tdescendentinstancelist.getclassname(const comp: tcomponent): string; + //returns submoduleclassname if appropriate +var + comp1: tmsecomponent; +begin + if ismodule(comp) then begin + //module, must be tmsecomponent; + result:= tmsecomponent(comp).actualclassname; + end + else begin + if csinline in comp.ComponentState then begin + comp1:= findancestor(comp); + if comp1 <> nil then begin + result:= comp1.actualclassname; + exit; + end; + end; + result:= comp.classname; + end; +end; + +procedure tdescendentinstancelist.setnodefaultpos(const aroot: twidget); +var + po1: pancestorinfoty; + int1: integer; +begin + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if (po1^.descendent is twidget) and (po1^.descendent <> nil) and //else inherited form + twidget(po1^.descendent).checkancestor(aroot) then begin + twidget1(po1^.ancestor).fwidgetrect.pos:= makepoint(-bigint,-bigint); + end; + inc(po1); + end; +end; + +procedure tdescendentinstancelist.restorepos(const aroot: twidget); +var + po1: pancestorinfoty; + int1: integer; +begin + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if (po1^.descendent is twidget) and + twidget(po1^.descendent).checkancestor(aroot) then begin + twidget1(po1^.ancestor).fwidgetrect.pos:= nullpoint; + end; + inc(po1); + end; +end; + +procedure tdescendentinstancelist.beginstreaming(const amodule: pmoduleinfoty); +begin + inherited beginstreaming; + if amodule <> nil then begin + frefreshmethods:= fdesigner.getancestormethods(amodule); + end; +end; + +{ tmethods } + +constructor tmethods.create(adesigner: tdesigner); +begin + fdesigner:= adesigner; + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +destructor tmethods.destroy; +begin +{$ifndef mse_nomethodswap} + releasemethodtable; +{$endif} + inherited; +end; + +function tmethods.getrecordsize(): int32; +begin + result:= sizeof(methodshashdataty); +end; + +procedure tmethods.addmethod(const aname: string; const aaddress: pointer; + const atypeinfo: ptypeinfo); +var + po1: pmethodshashdataty; +begin + {$ifdef FPC} {$checkpointer off} {$endif} + po1:= pmethodshashdataty(add(ptruint(aaddress))); + {$ifdef FPC} {$checkpointer default} {$endif} + with po1^.data.data do begin + name:= aname; + address:= aaddress; + typeinfo:= atypeinfo; + end; + fdesigner.fmodules.fmethodnames.add(ptruint(aaddress),aname); +end; + +procedure tmethods.deletemethod(const aadress: pointer); +begin +// inherited delete(aadress); do nothing +end; + +{$ifndef mse_nomethodswap} +type +{$ifdef FPC} + tmethodnamerec = packed record + name : pshortstring; + addr : pointer; + end; + pmethodtableentryty = ^tmethodnamerec; + + tmethodnametable = packed record + count : dword; + entries : packed array[0..0] of tmethodnamerec; + end; + +function tmethods.createmethodtable(const ancestors: methodsarty): pointer; +var + int1,int2,int3: integer; + po1: pmethodinfoty; + po2: pmethodtableentryty; + po3: pchar; + count1: integer; + ar1: methodsarty; +begin + releasemethodtable; + ar1:= copy(ancestors); + additem(pointerarty(ar1),self); + count1:= 0; + for int1:= 0 to high(ar1) do begin + inc(count1,ar1[int1].count); + end; + if count1 > 0 then begin + int2:= count1; //lenbyte + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + for int1:= 0 to count -1 do begin + int2:= int2 + length(pmethodsdataty(next)^.data.name); //stringsize + end; + end; + end; + int1:= sizeof(dword) + count1 * sizeof(tmethodnamerec); //tablesize + getmem(fmethodtable,int1+int2); + pdword(fmethodtable)^:= count1; + po2:= pmethodtableentryty(pchar(fmethodtable) + sizeof(dword)); + po3:= pchar(fmethodtable) + int1; //stringtable + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + for int1:= 0 to count - 1 do begin + po1:= @pmethodsdataty(next)^.data; + int2:= length(po1^.name); + po2^.name:= pshortstring(po3); + po3^:= char(int2); //namelen + inc(po3); + move(pointer(po1^.name)^,po3^,int2); + inc(po3,int2); + po2^.addr:= po1^.address; + inc(po2); + end; + end; + end; + end; + result:= fmethodtable; +end; + +{$else} + + methodtableentryfixty = packed record + len: word; + addr: pointer; + namlen: byte; +end; + + methodtableentryty = packed record + len: word; + adr: pointer; + name: shortstring; //variable length + end; + pmethodtableentryty = ^methodtableentryty; + +function tmethods.createmethodtable(const ancestors: methodsarty): pointer; +var + int1,int2,int3: integer; + po1: pmethodinfoty; + po2: pmethodtableentryty; + count1: integer; + ar1: methodsarty; + +begin + releasemethodtable; + ar1:= copy(ancestors); + additem(pointerarty(ar1),self); + count1:= 0; + for int1:= 0 to high(ar1) do begin + inc(count1,ar1[int1].count); + end; + if count1 > 0 then begin + int2:= sizeof(word); //numentries + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + for int1:= 0 to count -1 do begin + int2:= int2 + length(pmethodsdataty(next)^.data.name); + end; + end; + end; + getmem(fmethodtable,int2 + count1 * sizeof(methodtableentryfixty)); + pword(fmethodtable)^:= count1; + po2:= pmethodtableentryty(pchar(fmethodtable) + sizeof(word)); + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + for int1:= 0 to count - 1 do begin + po1:= pmethodinfoty(next); +// po1:= @pmethodstataty(next).data; ???? + int2:= length(po1^.name); + po2^.len:= sizeof(methodtableentryfixty) + int2; + po2^.adr:= po1^.address; + po2^.name[0]:= char(int2); + move(po1^.name[1],po2^.name[1],int2); + inc(pchar(po2),po2^.len); + end; + end; + end; + end; + result:= fmethodtable; +end; + +{$endif} + +procedure tmethods.releasemethodtable; +begin + if fmethodtable <> nil then begin + freemem(fmethodtable); + fmethodtable:= nil; + end; +end; +{$endif mse_nomethodswap} + +function tmethods.findmethod(const aadress: pointer): pmethodinfoty; +begin + result:= pointer(find(ptruint(aadress))); + if result <> nil then begin + result:= @pmethodshashdataty(result)^.data.data; + end; +end; + +function tmethods.findmethodbyname(const aname: string; + const atype: ptypeinfo; out namefound: boolean): pmethodinfoty; +var + int1: integer; + po1: pmethodshashdataty; + str1: string; +begin + str1:= uppercase(aname); + result:= nil; + namefound:= false; + for int1:= 0 to count - 1 do begin + po1:= pmethodshashdataty(next); + if uppercase(po1^.data.data.name) = str1 then begin + namefound:= true; + if (po1^.data.data.typeinfo = atype) then begin + result:= @po1^.data.data; + break; + end; + end; + end; +end; + +function tmethods.findmethodbyname(const aname: string): pmethodinfoty; +var + int1: integer; + po1: pmethodshashdataty; + str1: string; +begin + str1:= uppercase(aname); + result:= nil; + for int1:= 0 to count - 1 do begin + po1:= pmethodshashdataty(next); + if uppercase(po1^.data.data.name) = str1 then begin + result:= @po1^.data.data; + break; + end; + end; +end; + +procedure tmethods.finalizeitem(const aitem: phashdataty); +begin + if fdesigner.fmodules.fmethodnames <> nil then begin + fdesigner.fmodules.fmethodnames.delete( + ptruint(pmethodshashdataty(aitem)^.data.data.address)); + end; + finalize(pmethodshashdataty(aitem)^.data.data); +end; + +{ tcomponents } + +constructor tcomponents.create(const aowner: pmoduleinfoty; + const adesigner: tdesigner); +begin + fowner:= aowner; + fdesigner:= adesigner; + fcomponent:= tcomponentslink.Create(nil); + fcomponent.fownercomps:= self; + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +destructor tcomponents.destroy; +begin + fcomponent.Free; + inherited; +end; + +function tcomponents.getrecordsize(): int32; +begin + result:= sizeof(componentshashdataty); +end; + +procedure tcomponents.destroynotification(const acomponent: tcomponent); +begin + fdesigner.componentdestroyed(acomponent,fowner); + delete(ptruint(acomponent),true); +end; + +procedure tcomponents.finalizeitem(const aitem: phashdataty); +begin + finalize(pcomponentshashdataty(aitem)^.data.data); +end; + +(* +procedure tcomponents.doadd(component: tcomponent); +var + root: tcomponent; +begin + if not(component is twidget) or + (ws_iswidget in twidget1(component).fwidgetstate) then begin + add(component); + end; + root:= famodule; + if csinline in component.componentstate then begin + famodule:= component; + end; + tcomponent1(component).GetChildren({$ifdef FPC}@{$endif}doadd,famodule); + famodule:= root; +end; +*) +procedure tcomponents.assigncomps(const module: tmsecomponent); + procedure addcomp(acomp: tcomponent); + var + ar1: componentarty; + int1: integer; + begin + if not(acomp is twidget) or + (ws_iswidget in twidget1(acomp).fwidgetstate) then begin + add(acomp); + end; + ar1:= getcomponentchildren(acomp,module,true); + for int1:= 0 to high(ar1) do begin + addcomp(ar1[int1]); + end; + end; + +begin + clear; + if module <> nil then begin + addcomp(module); +// famodule:= module; +// doadd(module); + end; +end; + +procedure tcomponents.add(comp: tcomponent); +var + po1: pcomponentshashdataty; +begin + {$ifdef FPC} {$checkpointer off} {$endif} + po1:= pcomponentshashdataty(inherited add(ptruint(comp))); + {$ifdef FPC} {$checkpointer default} {$endif} + with po1^.data.data do begin + instance:= comp; + name:= comp.Name; + end; + comp.freenotification(fcomponent); +end; + +function tcomponents.find(const value: tobject): pcomponentshashdataty; +begin + result:= pcomponentshashdataty(inherited find(ptruint(value))); +end; + +procedure tcomponents.swapcomponent(const old,new: tcomponent); +var + po1: pcomponentshashdataty; +begin + po1:= find(old); + if po1 <> nil then begin + po1^.data.data.instance:= new; + old.removefreenotification(fcomponent); + new.freenotification(fcomponent); + end; +end; + +function tcomponents.getcomponents: componentarty; +var + int1: integer; +begin + setlength(result,count); + for int1:= 0 to count - 1 do begin + result[int1]:= pcomponentsdataty(next)^.data.instance; + end; +end; + +function tcomponents.next: pcomponentshashdataty; +begin + result:= pcomponentshashdataty(inherited next); +end; + +function tcomponents.getcomponent(const aname: string; + const children: boolean = false): tcomponent; +var + int1,int2: integer; + po1: pcomponentshashdataty; + str1: string; + ar1: stringarty; +begin + result:= nil; + str1:= uppercase(aname); + if aname <> '' then begin + if children then begin + ar1:= splitstring(str1,'.'); + deleteitem(ar1,0); + if ar1 = nil then begin + exit; + end; + end + else begin + ar1:= splitstring(str1,subcomponentsplitchar); + end; + for int1:= 0 to count - 1 do begin + po1:= next; + if uppercase(po1^.data.data.name) = ar1[0] then begin + result:= po1^.data.data.instance; + for int2:= 1 to high(ar1) do begin + result:= result.findcomponent(ar1[int2]); + if (result = nil) then begin + break; + end; + if isnosubcomp(result) then begin +// if not(cssubcomponent in result.componentstyle) then begin + result:= nil; + break; + end; + end; + break; + end; + end; + end; +end; + +procedure tcomponents.namechanged(const acomponent: tcomponent; + const newname: string); +var + po1: pcomponentshashdataty; +begin + po1:= find(acomponent); + if po1 <> nil then begin + po1^.data.data.name:= newname; + end; +end; + +function comparecomponentname(const l,r): integer; +begin + result:= comparetext(componentnamety(l).dispname,componentnamety(r).dispname); +end; + +function tcomponents.getdispnames: componentnamearty; +var + int1: integer; +begin + setlength(result,count); + for int1:= 0 to count - 1 do begin + with result[int1] do begin + instance:= next^.data.data.instance; + dispname:= fdesigner.getcomponentdispname(instance); + end; + end; + sortarray(result,sizeof(componentnamety), + {$ifdef FPC}@{$endif}comparecomponentname); +end; + +{ tmoduleinfo } + +constructor tmoduleinfo.create(adesigner: tdesigner); +begin + fdesigner:= adesigner; + with info do begin + methods:= tmethods.create(fdesigner); + components:= tcomponents.create(@info,fdesigner); + end; +end; + +destructor tmoduleinfo.destroy; +begin + inherited; + removeitem(pointerarty(fdesigner.fcheckfixups),@info); + with info do begin + if filetag <> 0 then begin + sourcefo.filechangenotifyer.removenotification(filename,filetag); + end; + freeandnil(loadingstream); + freeandnil(methods); + freeandnil(components); + freeandnil(designform); + end; +end; + +{ tmodulelist } + +constructor tmodulelist.create(adesigner: tdesigner); +begin + fdesigner:= adesigner; + inherited create(true); + fmethodnames:= tmethodnames.create; +end; + +procedure tmodulelist.designformdestroyed(const sender: tcustommseform); +var + po1: pmoduleinfoty; +begin + if not destroying then begin + po1:= findform(sender); + if po1 <> nil then begin + po1^.designform:= nil; + removemoduleinfo(po1); + // fdesigner.moduledestroyed(po1); + end; + end; +end; + +function tmodulelist.getitempo1(const index: integer): pmoduleinfoty; +begin + result:= @(tmoduleinfo(items[index]).info); +end; + +function tmodulelist.findmodule(const filename: msestring): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; + po2: pmoduleinfoty; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount-1 do begin + po2:= @tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info; + if po2^.filename = filename then begin + result:= po2; + break; + end; + end; +end; + +function tmodulelist.findmodule(const amodule: tmsecomponent): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; + po2: pmoduleinfoty; +begin + result:= nil; + if amodule <> nil then begin + po1:= datapo; + for int1:= 0 to fcount-1 do begin + po2:= @tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info; + if po2^.instance = amodule then begin + result:= po2; + break; + end; + end; + end; +end; + +function tmodulelist.findownermodule(const acomponent: tcomponent): pmoduleinfoty; +begin + result:= findmodulebyinstance(rootcomponent(acomponent)); +end; + +function tmodulelist.findmodulebyinstance(const ainstance: tcomponent): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; + po2: pmoduleinfoty; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount-1 do begin + po2:= @tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info; + if po2^.instance = ainstance then begin + result:= po2; + break; + end; + end; +end; + +function tmodulelist.findmodule(const po: pmoduleinfoty): integer; +var + int1: integer; + po1: ppointeraty; +begin + result:= -1; + po1:= datapo; + for int1:= 0 to fcount-1 do begin + if @tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info = po then begin + result:= int1; + break; + end; + end; +end; + +function tmodulelist.findmodulebyname(const name: string): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount-1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + if info.instancevarname = name then begin + result:= @info; + break; + end; + end; + end; +end; + +function tmodulelist.findmoduleinstancebyname(const name: string): tcomponent; +var + po1: pmoduleinfoty; +begin + po1:= findmodulebyname(name); + if po1 <> nil then begin + result:= po1^.instance; + end + else begin + result:= nil; + end; +end; + +function tmodulelist.findmoduleinstancebyclass(const aclass: tclass): tcomponent; +var + int1: integer; + po1: ppointeraty; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount-1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + if info.instance.classtype = aclass then begin + if not info.resolved then begin + exit; + end; + result:= info.instance; + break; + end; + end; + end; +end; + +function tmodulelist.findmodulebyclassname(aclassname: string): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; +begin + result:= nil; + po1:= datapo; + aclassname:= uppercase(aclassname); + for int1:= 0 to fcount-1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + if uppercase(info.moduleclassname) = aclassname then begin + result:= @info; + break; + end; + end; + end; +end; + +function tmodulelist.newmodule(const ainherited: boolean; + const afilename: msestring; const amoduleclassname,ainstancevarname, + designmoduleclassname: string): tmoduleinfo; +var + po1: pmoduleinfoty; + inheritedbefore: boolean; +begin + po1:= findmodule(afilename); + if po1 <> nil then begin + delete(findmodule(po1)); + end; + result:= tmoduleinfo.create(fdesigner); + with result.info do begin + filename:= afilename; + instancevarname:= ainstancevarname; + moduleclassname:= amoduleclassname; + try + if ainherited then begin + po1:= fdesigner.getinheritedmodule(designmoduleclassname); + if po1 = nil then begin + raise exception.create(ansistring(actionsmo.c[ord(ac_ancestorfor)])+ + designmoduleclassname+ansistring(actionsmo.c[ord(ac_notfound)])); + end; + fdesigner.beginstreaming({po1}); + try + inheritedbefore:= des_inheritednewmodule in fdesigner.fstate; + include(fdesigner.fstate,des_inheritednewmodule); + instance:= fdesigner.copycomponent(po1^.instance,po1^.instance,false,true); + finally + if not inheritedbefore then begin + exclude(fdesigner.fstate,des_inheritednewmodule); + end; + fdesigner.endstreaming({po1}); + end; + moduleintf:= po1^.moduleintf; + designformclass:= po1^.designformclass; +{$warnings off} + tcomponent1(instance).setancestor(true); +{$warnings on} + additem(pointerarty(fdesigner.floadedsubmodules),instance); + fdesigner.fdescendentinstancelist.add(tmsecomponent(instance),po1^.instance, + fdesigner.fsubmodulelist); + tmsecomponent1(instance).factualclassname:= @moduleclassname; + tmsecomponent1(instance).fancestorclassname:= designmoduleclassname; +// initrootdescendent(instance); + tmsecomponent1(instance).setancestor(true); + end + else begin + instance:= createdesignmodule(@result.info,designmoduleclassname,@moduleclassname); + end; +{$warnings off} + tcomponent1(instance).setdesigning(true{$ifndef FPC},true{$endif}); +{$warnings on} + except + result.Free; + raise; + end; + end; +end; + +function tmodulelist.findmethodbyname(const name: string; + const atype: ptypeinfo; + const amodule: tmsecomponent): tmethod; + + procedure getmethod(ainfo: pmoduleinfoty; aname: string); + var + po1: pmethodinfoty; + bo1: boolean; + begin + if ainfo <> nil then begin + po1:= ainfo^.methods.findmethodbyname(aname,atype,bo1); + if po1 <> nil then begin + result.data:= po1^.address; + // result.code:= po1^.address; + // result.Data:= ainfo^.instance; + end +// else begin +// if bo1 then begin +// result.data:= pointer(1); //name found +// end; +// end; + end; + end; + +var + ar1: stringarty; +begin + result:= nullmethod; + if amodule <> nil then begin + getmethod(findmodule(amodule),name); + end + else begin + ar1:= nil; + splitstring(name,ar1,'.'); + if length(ar1) = 2 then begin + getmethod(findmodulebyname(ar1[0]),ar1[1]); + end; + end; +end; + +function tmodulelist.findmethodname(const method: tmethod; const comp: tcomponent): string; +var + int1: integer; + po1: ppointeraty; + po2: pmethodinfoty; +begin + result:= ''; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + po2:= info.methods.findmethod(method.data); + if po2 <> nil then begin + if info.components.find(comp) = nil then begin + result:= info.instance.actualclassname + '.' + po2^.name //foreign module + end + else begin + result:= po2^.name; + end; + break; + end; + end; + end; +end; + +function tmodulelist.delete(index: integer): pointer; +begin + fdesigner.moduledestroyed(itempo[index]); + result:= inherited delete(index); +end; + +function tmodulelist.removemoduleinfo(po: pmoduleinfoty): integer; +begin + result:= findmodule(po); + delete(result); +end; + +function tmodulelist.findform(aform: tcustommseform): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to count - 1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + if info.designform = aform then begin + result:= @info; + break; + end; + end; + end; +end; + +procedure tmodulelist.freeloadingstreams; +var + int1: integer; + po1: ppointeraty; +begin + po1:= datapo; + for int1:= 0 to count - 1 do begin + freeandnil(tmoduleinfo( + iobjectlink(po1^[int1]).getinstance).info.loadingstream); + end; +end; + +procedure tmodulelist.componentmodified(const acomponent: tobject); +var + int1: integer; + po1: ppointeraty; + comp: tcomponent; + +begin + if acomponent is tcomponent then begin + comp:= rootcomponent(tcomponent(acomponent)); + po1:= datapo; + for int1:= 0 to count - 1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + if info.components.find(comp) <> nil then begin + if not info.modified then begin + info.modified:= true; + if info.designform <> nil then begin + tformdesignerfo(info.designform).updatecaption; + end; + end; + if (info.designform <> nil) and (fdesigner.fcomponentmodifying > 0) then begin + idesignnotification( + tformdesignerfo(info.designform)).itemsmodified(nil,comp); + end; + fdesigner.fdescendentinstancelist.modulemodified(@info); + break; + end; + end; + end; + end; +end; + +function tmodulelist.findmodulebycomponent(const acomponent: tcomponent): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; + po2: pmoduleinfoty; +// comp1: tcomponent; +begin + result:= nil; + po1:= datapo; +// comp1:= acomponent; +// while comp1 <> nil do begin + for int1:= 0 to fcount-1 do begin + po2:= @tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info; + if po2^.components.find(acomponent) <> nil then begin + result:= po2; + break; + end; + end; +// if result <> nil then begin +// break; +// end; +// if cssubcomponent in comp1.componentstyle then begin +// comp1:= comp1.owner; +// end +// else begin +// comp1:= nil; +// end; +// end; +end; + +function tmodulelist.filenames: filenamearty; +var + int1: integer; + po1: ppointeraty; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info.filename; + end; +end; + +destructor tmodulelist.destroy; +begin + freeandnil(fmethodnames); + inherited; +end; + +{ tdesignformlist } + +function tdesignformlist.getitems(const index: integer): tmseform;//tformdesignerfo; +begin + result:= tmseform(inherited getitems(index)); +end; + +type + tselectiondestroytracker = class(tcomponent) + private + fselections: tdesignerselections; + protected + procedure notification(acomponent: tcomponent; + operation: toperation); override; + public + constructor create(const aselections: tdesignerselections); reintroduce; + end; + +{ tselectiondestroytracker } + +constructor tselectiondestroytracker.create( + const aselections: tdesignerselections); +var + int1: integer; +begin + fselections:= aselections; + with fselections do begin + for int1:= 0 to count - 1 do begin + items[int1].freenotification(self); + end; + end; + inherited create(nil); +end; + +procedure tselectiondestroytracker.notification(acomponent: tcomponent; + operation: toperation); +var + po1: pcomponentaty; + int1: integer; +begin + if operation = opremove then begin + po1:= fselections.datapo; + for int1:= 0 to fselections.count-1 do begin + if po1^[int1] = acomponent then begin + po1^[int1]:= nil; + end; + end; + end; + inherited; +end; + +{ tdesigner } + +constructor tdesigner.create; +begin + fobjformat:= of_default; + fselections:= tdesignerselections.create; + fmodules:= tmodulelist.create(self); + fsubmodulelist:= tsubmodulelist.create(self); + fdescendentinstancelist:= tdescendentinstancelist.create(self); + fdesignfiles:= tindexedfilenamelist.create; + ondesignchanged:= @componentmodified; + onfreedesigncomponent:= {$ifdef FPC}@{$endif}deletecomponent; + ondesignvalidaterename:= {$ifdef FPC}@{$endif}validaterename; + ondesignexception:= @handledesignexception; +end; + +destructor tdesigner.destroy; +begin + ondesignchanged:= nil; + fdescendentinstancelist.Free; + fsubmodulelist.Free; + inherited; + fcomponenteditor.Free; + fmodules.free; + fselections.Free; + fdesignfiles.Free; +end; + +procedure tdesigner.ClearSelection; +begin + //dummy +end; + +procedure tdesigner.addcomponent(const module: tmsecomponent; + const acomponent: tcomponent); +var + int1,int2: integer; + str1: string; + bo1: boolean; + classna: string; + ar1: componentarty; + +begin + if (des_pasting in fstate) and (acomponent.name <> '') then begin + addpastedcomponentname(acomponent); + end; + with registeredcomponents do begin + if (acomponent.ComponentState * [csancestor] = []) or + (acomponent.Owner = nil) or (acomponent.Owner = module) then begin //probaly inline + classna:= ''; + str1:= acomponent.Name; + acomponent.name:= ''; + if csinline in acomponent.componentstate then begin + if str1 <> '' then begin + classna:= str1; + str1:= str1 + '1'; + end; + end + else begin + classna:= acomponent.ClassName; + end; + if acomponent.Owner <> nil then begin + acomponent.owner.removecomponent(acomponent); + end; + module.InsertComponent(acomponent); + if str1 = '' then begin + str1:= classna + '1'; + end; + int1:= 1; + ar1:= fdescendentinstancelist.getdescendents(module); + additem(pointerarty(ar1),module); + repeat + bo1:= true; + for int2:= 0 to high(ar1) do begin + if ar1[int2].findcomponent(str1) <> nil then begin + inc(int1); + str1:= classna + inttostr(int1); + bo1:= false; + break; + end; + end; + until bo1; + acomponent.Name:= str1; + fmodules.findmodulebyinstance(module)^.components.add(acomponent); + designnotifications.ItemInserted(self,module,acomponent); + end + else begin + fmodules.findmodulebyinstance(module)^.components.add(acomponent); + end; +/////////// componentmodified(acomponent); + end; +end; + +function tdesigner.createnewcomponent(const module: tmsecomponent; + const aclass: tcomponentclass): tcomponent; +begin + result:= tcomponent(aclass.newinstance); + try + tcomponent1(result).setdesigning(true); + result.create(nil); + except + result.Free; + raise; + end; + with modules.findmodule(module)^.moduleintf^ do begin + if assigned(initnewcomponent) then begin + initnewcomponent(module,result); + end; + end; + addcomponent(module,result); +end; + +function tdesigner.createcurrentcomponent(const module: tmsecomponent): tcomponent; +begin + with registeredcomponents do begin + if selectedclass <> nil then begin + result:= createnewcomponent(module,selectedclass); + end + else begin + result:= nil; + end; + end; +end; + +function tdesigner.hascurrentcomponent: boolean; +begin + result:= registeredcomponents.selectedclass <> nil; +end; + +procedure tdesigner.notifydeleted(comp: tcomponent); +begin + if fnotifydeletedlock = 0 then begin + if comp is twidget then begin + tcomponent1(comp).getchildren({$ifdef FPC}@{$endif}notifydeleted,fnotifymodule); + end; + designnotifications.itemdeleted(idesigner(self),fnotifymodule,comp); + end; +end; + +procedure tdesigner.deleteselection(adoall: boolean); +var + int1: integer; + comp1,comp2: tcomponent; + po1: pmoduleinfoty; + destroytracker: tselectiondestroytracker; + +begin + destroytracker:= tselectiondestroytracker.create(self.fselections); + try + for int1:= 0 to fselections.count - 1 do begin + comp1:= fselections[int1]; + if comp1 <> nil then begin + comp2:= comp1.owner; + po1:= fmodules.findmodulebycomponent(comp1); + if po1 <> nil then begin + fnotifymodule:= po1^.instance; + notifydeleted(comp1); + end; + inc(fnotifydeletedlock); + try + comp1.free; + finally + dec(fnotifydeletedlock); + end; + fmodules.componentmodified(comp2); + end; + end; + fselections.clear; + selectionchanged; + finally + destroytracker.free; + end; +end; + +procedure tdesigner.componentdestroyed(const acomponent: tcomponent; + const module: pmoduleinfoty); +begin + if fnotifydeletedlock = 0 then begin +// designnotifications.itemdeleted(idesigner(self),module^.instance,acomponent); + if fselections.remove(acomponent) >= 0 then begin + selectionchanged; + end; + end; +end; + +procedure tdesigner.deletecomponent(const acomponent: tcomponent); +var + po1: pmoduleinfoty; + notifymodulebefore: tmsecomponent; +begin + if acomponent <> nil then begin + fmodules.componentmodified(acomponent); + po1:= fmodules.findmodulebycomponent(acomponent); + if po1 <> nil then begin + notifymodulebefore:= fnotifymodule; + fnotifymodule:= po1^.instance; + try + notifydeleted(acomponent); +// designnotifications.ItemDeleted(idesigner(self), +// fmodules.findmodulebycomponent(acomponent)^.instance,acomponent); + finally + fnotifymodule:= notifymodulebefore; + end; + end; + acomponent.free; + end; +end; + +{$ifdef mse_nomethodswap} +procedure tdesigner.setmethodproperty(reader: treader; + instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); +var + m1: tmethod; + po1: pmethodinfoty; +begin + po1:= floadingmodulepo^.methods.findmethodbyname(themethodname); + if po1 = nil then begin + m1:= createmethod(themethodname,nil,nil); + end + else begin + m1.data:= po1^.address; + m1.code:= nil; + end; + setmethodprop(instance,propinfo,m1); + handled:= true; +end; +{$else} +procedure tdesigner.findmethod(reader: treader; const amethodname: string; + var address: pointer; var error: boolean); +var + method: tmethod; + po1: pmethodinfoty; +begin + if error then begin + po1:= floadingmodulepo^.methods.findmethodbyname(amethodname); + if po1 = nil then begin + method:= createmethod(amethodname,nil,nil); + address:= method.data; + end + else begin + address:= po1^.address; + end; + error:= false; + end; +end; +{$endif} +{ +procedure tdesigner.findmethod2(Reader: TReader; const aMethodName: string; + var Address: Pointer; var Error: Boolean); +var + po2: pmethodinfoty; +begin + if error then begin + error:= false; //ignore new method error + po2:= flookupmodule^.methods.findmethodbyname(amethodname); + if po2 <> nil then begin + address:= po2^.address; + end; + end; +end; +} +function tdesigner.getinheritedmodule(const aclassname: string): pmoduleinfoty; +begin + result:= fmodules.findmodulebyclassname(aclassname); + if result = nil then begin + if assigned(fongetmoduletypefile) then begin + fongetmoduletypefile(aclassname); + end; + result:= fmodules.findmodulebyclassname(aclassname); + end; +end; + +procedure tdesigner.findcomponentclass(Reader: TReader; const aClassName: string; + var ComponentClass: TComponentClass); + +var + po1: pmoduleinfoty; +begin + fsubmoduleinfopo:= nil; + ffindcompclasstag:= fcreatecomponenttag+1; + if componentclass = nil then begin + po1:= getinheritedmodule(aclassname); + if po1 <> nil then begin + fsubmoduleinfopo:= po1; //used in createcomponent + ffindcompclasstag:= fcreatecomponenttag+1; + componentclass:= tcomponentclass(po1^.instance.classtype); + end; + end; +end; + +procedure tdesigner.ancestornotfound(Reader: TReader; const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent); +begin + fsubmoduleinfopo:= nil; //reset for createcomponent + component:= fmodules.findmoduleinstancebyclass(componentclass); + if component = nil then begin + component:= mseclasses.findancestorcomponent(reader,componentname); + end; +end; + +function tdesigner.findancestorcomponent(const acomponent: tcomponent): tcomponent; +var +// ancestormodule: tmsecomponent; + comp1: tcomponent; + ar1: stringarty; + int1: integer; +begin + result:= nil; + if acomponent.owner = nil then begin //module + result:= descendentinstancelist.findancestor(acomponent); + end + else begin //embedded component + ar1:= nil; + result:= nil; + comp1:= acomponent; + while (comp1.owner <> nil) and + (comp1.componentstate * [csinline,csancestor] <> [csinline]) do begin + if comp1.name = '' then begin + exit; + end; + additem(ar1,comp1.name); + comp1:= comp1.owner; + end; + if (comp1.owner <> nil) and + (csancestor in comp1.owner.componentstate) then begin + //inherited submodule + additem(ar1,comp1.name); + comp1:= comp1.owner; + end; + result:= descendentinstancelist.findancestor(comp1); + for int1:= high(ar1) downto 0 do begin + if result = nil then begin + exit; + end; + result:= result.findcomponent(ar1[int1]); + end; + end; +end; + +procedure tdesigner.createcomponent1(Reader: TReader; + ComponentClass: TComponentClass; var Component: TComponent); +var + asubmoduleinfopo: pmoduleinfoty; + int1: integer; +begin + inc(fcreatecomponenttag); + if fcreatecomponenttag <> ffindcompclasstag then begin + fsubmoduleinfopo:= nil; //invalid + end; + asubmoduleinfopo:= fsubmoduleinfopo; //can be recursive + if asubmoduleinfopo <> nil then begin + fsubmoduleinfopo:= nil; +// component:= copycomponent(asubmoduleinfopo^.instance, +// asubmoduleinfopo^.instance,false,false); + component:= copycomponent(asubmoduleinfopo^.instance, + asubmoduleinfopo^.instance,false,true); + reader.root.insertcomponent(component); + initinline(component); + if (des_inheritednewmodule in fstate) then begin + tcomponent1(component).setancestor(true); + end + else begin + for int1:= 0 to component.componentcount - 1 do begin + tcomponent1(component.components[int1]).setancestor(true); + end; + end; + if (submodulecopy = 0) and + (reader.root.componentstate * [csinline{,csancestor}] = []) then begin + additem(pointerarty(floadedsubmodules),component); + fdescendentinstancelist.add(tmsecomponent(component), + asubmoduleinfopo^.instance,fsubmodulelist); + end; + end; + if reader is tasinheritedreader then begin + tasinheritedreader(reader).newcomp:= true; + end; +end; + +function tdesigner.createcomponent: tcreatecomponentevent; +begin + fsubmoduleinfopo:= nil; //reset + result:= {$ifdef FPC}@{$endif}createcomponent1; +end; + +{$ifndef mse_nomethodswap} +procedure tdesigner.docopymethods(const source,dest: tcomponent; + const force: boolean); + procedure doprops(const source,desc: tobject); + var + ar1: propinfopoarty; + int1: integer; + method1: tmethod; + begin + ar1:= getpropinfoar(desc); + for int1:= 0 to high(ar1) do begin + case ar1[int1]^.proptype^.kind of + tkmethod: begin + method1:= getmethodprop(source,ar1[int1]); + if {force or }(method1.code <> nil) or (method1.data <> nil) then begin + setmethodprop(dest,ar1[int1],method1); + end; + end; + { + tkclass: begin + obj1:= getobjectprop(source,ar1[int1]); + if (obj1 <> nil) and (not (obj1 is tcomponent) or + (cssubcomponent in tcomponent(obj1).componentstyle)) then begin + obj2:= getobjectprop(dest,ar1[int1]); + if obj2 <> nil then begin + doprops(obj1,obj2); + if obj1 is tpersistentarrayprop then begin + int3:= tpersistentarrayprop(obj1).count; + if int3 > tpersistentarrayprop(obj2).count then begin + int3:= tpersistentarrayprop(obj2).count; + end; + for int2:= 0 to int3 - 1 do begin + doprops(tpersistentarrayprop(obj1).items[int2], + tpersistentarrayprop(obj2).items[int2]); + end; + end; + end; //collections? + end; + end; + } + end; + end; + end; + +var + comp1,comp2: tcomponent; + int1: integer; + bo1: boolean; +begin + bo1:= setloading(dest,true); + try + doprops(source,dest); + finally + setloading(dest,bo1); + end; + for int1:= 0 to source.componentcount - 1 do begin + comp1:= source.components[int1]; + comp2:= dest.findcomponent(comp1.name); + if (comp2 <> nil) and + (comp1.classtype = comp2.classtype) then begin + docopymethods(comp1,comp2,force); + end; + end; +end; +{$endif} +{ +procedure tdesigner.docopymethods(const source, dest: tcomponent; + const force: boolean); +var + propar: propinfopoarty; + po1: ^ppropinfo; + int1: integer; + method,method1: tmethod; + comp1,comp2: tcomponent; +begin + propar:= getpropinfoar(source); + po1:= pointer(propar); + for int1:= 0 to high(propar) do begin + if po1^^.proptype^.kind = tkmethod then begin + method:= getmethodprop(source,po1^); + method1:= getmethodprop(dest,po1^); + if (method1.code <> method.code) or (method1.data <> method.data) then begin + setmethodprop(dest,po1^,method); + end; + end; + inc(po1); + end; + for int1:= 0 to source.ComponentCount - 1 do begin + comp1:= source.Components[int1]; + comp2:= dest.FindComponent(comp1.name); + if (comp2 <> nil) and (comp1.ClassType = comp2.ClassType) then begin + docopymethods(comp1,comp2,force); + end; + end; +end; +} +{ +procedure tdesigner.dorefreshmethods(const descendent,newancestor, + oldancestor: tcomponent); + procedure doprops(const desc,newan,oldan: tobject); + var + ar1: propinfopoarty; + int1,int2,int3: integer; + method1,method2,method3: tmethod; + obj1,obj2,obj3: tobject; + begin + ar1:= getpropinfoar(desc); + for int1:= 0 to high(ar1) do begin + case ar1[int1]^.proptype^.kind of + tkmethod: begin + method2:= getmethodprop(newan,ar1[int1]); + if (method2.code <> nil) or (method2.data <> nil) then begin + setmethodprop(desc,ar1[int1],method2); + //refresh ancestor value, it is not possible to override methods + end; + end; + tkclass: begin + obj1:= getobjectprop(desc,ar1[int1]); + obj2:= getobjectprop(newan,ar1[int1]); + obj3:= getobjectprop(oldan,ar1[int1]); + if (obj1 <> nil) and (not (obj1 is tcomponent) or + (cssubcomponent in tcomponent(obj1).componentstyle)) then begin + doprops(obj1,obj2,obj3); + if obj1 is tpersistentarrayprop then begin + int3:= tpersistentarrayprop(obj1).count; + if int3 > tpersistentarrayprop(obj2).count then begin + int3:= tpersistentarrayprop(obj2).count; + end; + if int3 > tpersistentarrayprop(obj3).count then begin + int3:= tpersistentarrayprop(obj3).count; + end; + for int2:= 0 to int3 - 1 do begin + doprops(tpersistentarrayprop(obj1).items[int2], + tpersistentarrayprop(obj2).items[int2], + tpersistentarrayprop(obj3).items[int2]); + end; + end; + end; + end; + end; + end; + end; + +var + comp1,comp2,comp3: tcomponent; + int1: integer; +begin + doprops(descendent,newancestor,oldancestor); + for int1:= 0 to descendent.componentcount - 1 do begin + comp1:= descendent.components[int1]; + comp2:= newancestor.findcomponent(comp1.name); + comp3:= oldancestor.findcomponent(comp1.name); + if (comp2 <> nil) and (comp3 <> nil) and + (comp1.classtype = comp2.classtype) and + (comp1.classtype = comp3.classtype) then begin + dorefreshmethods(comp1,comp2,comp3); + end; + end; +end; +} +{ +procedure tdesigner.forallmethprop(child: tcomponent); +begin + with fforallmethpropsinfo do begin + forallmethodproperties(child,dat,proc,dochi); + end; +end; +} + +procedure tdesigner.forallmethodproperties(const aroot: tcomponent; + const ainstance: tobject; + const data: pointer; const aproc: propprocty; + const dochildren: boolean); +var + ar1: propinfopoarty; + ar2: componentarty; + int1,int2: integer; + obj1: tobject; + bo1{,bo2}: boolean; +// rootbefore: tcomponent; +begin + if ainstance is tcomponent then begin + bo1:= not (csloading in tcomponent(ainstance).componentstate); + if bo1 then begin + setloading(tcomponent(ainstance),true); + end; + end + else begin + bo1:= false; + end; + ar1:= getpropinfoar(ainstance); + for int1:= 0 to high(ar1) do begin + case ar1[int1]^.proptype^.kind of + tkmethod: begin + aproc(ainstance,data,ar1[int1]); + end; + tkclass: begin + obj1:= getobjectprop(ainstance,ar1[int1]); + if issubprop(obj1) then begin + forallmethodproperties(aroot,obj1,data,aproc,dochildren); + if obj1 is tpersistentarrayprop then begin + with tpersistentarrayprop(obj1) do begin + for int2:= 0 to count - 1 do begin + forallmethodproperties(aroot,items[int2],data,aproc,dochildren); + end; + end; + end + else begin + if obj1 is tcollection then begin + with tcollection(obj1) do begin + for int2:= 0 to count - 1 do begin + forallmethodproperties(aroot,items[int2],data,aproc,dochildren); + end; + end; + end; + end; + end; + end; + end; + end; + if (ainstance is tcomponent) then begin + ar2:= getcomponentchildren(tcomponent(ainstance),aroot,true); + for int1:= 0 to high(ar2) do begin + forallmethodproperties(aroot,ar2[int1],data,aproc,dochildren); + end; + end; + if bo1 then begin + setloading(tcomponent(ainstance),false); + end; +end; + +procedure tdesigner.componentevent(const event: tcomponentevent); +begin + with event do begin + if tag = ord(me_componentmodified) then begin + designnotifications.ItemsModified(idesigner(self),sender); + end; + end; + inherited; +end; + +function tdesigner.getmodulex(const amodule: tmsecomponent): integer; +var + po1: pmoduleinfoty; +begin + po1:= fmodules.findmodule(tmsecomponent(amodule)); + if po1 <> nil then begin + result:= po1^.designformintf.getmodulepos_x(); + end + else begin + result:= 0; + end; +end; + +function tdesigner.getmoduley(const amodule: tmsecomponent): integer; +var + po1: pmoduleinfoty; +begin + po1:= fmodules.findmodule(tmsecomponent(amodule)); + if po1 <> nil then begin + result:= po1^.designformintf.getmodulepos_y(); + end + else begin + result:= 0; + end; +end; + +procedure tdesigner.setmodulex(const amodule: tmsecomponent; avalue: integer); +var + po1: pmoduleinfoty; +begin + po1:= fmodules.findmodule(tmsecomponent(amodule)); + if po1 <> nil then begin + po1^.designformintf.setmodulepos_x(avalue); +// po1^.designform.bounds_x:= avalue; + end; +end; + +procedure tdesigner.setmoduley(const amodule: tmsecomponent; avalue: integer); +var + po1: pmoduleinfoty; +begin + po1:= fmodules.findmodule(tmsecomponent(amodule)); + if po1 <> nil then begin + po1^.designformintf.setmodulepos_y(avalue); + end; +end; + +procedure tdesigner.modulesizechanged(const amodule: tmsecomponent); +var + po1: pmoduleinfoty; +begin + po1:= fmodules.findmodule(tmsecomponent(amodule)); + if po1 <> nil then begin +{$warnings off} + twidget1(po1^.designform).sizechanged; +{$warnings on} + end; +end; + +function tdesigner.checkmodule(const filename: msestring): pmoduleinfoty; +begin + result:= fmodules.findmodule(filename); + if result = nil then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_module)]+ + filename+actionsmo.c[ord(ac_notfound)])); + end; +end; + +procedure tdesigner.beginstreaming({const amodule: pmoduleinfoty}); +var + i1: int32; +begin + if fstreaming = 0 then begin + for i1:= 0 to fmodules.count - 1 do begin + with fmodules[i1]^ do begin + if designform <> nil then begin + tformdesignerfo(designform).beginstreaming; + end; + end; + end; + end; + inc(fstreaming); +{ + with amodule^ do begin + if designform <> nil then begin + tformdesignerfo(designform).beginstreaming; + end; + end; +} +end; + +procedure tdesigner.endstreaming({const amodule: pmoduleinfoty}); +var + i1: int32; +begin + dec(fstreaming); + if fstreaming = 0 then begin + for i1:= 0 to fmodules.count - 1 do begin + with fmodules[i1]^ do begin + if designform <> nil then begin + tformdesignerfo(designform).endstreaming; + end; + end; + end; + end; +{ + with amodule^ do begin + if designform <> nil then begin + tformdesignerfo(designform).endstreaming; + end; + end; +} +end; + +procedure tdesigner.modulechanged(const amodule: pmoduleinfoty); +begin + componentmodified(amodule^.instance); +end; + +procedure tdesigner.dotouch(const amodule: pmoduleinfoty); +begin + fallsaved:= false; + with amodule^ do begin + modified:= true; + designformintf.updatecaption + end; +end; + +procedure tdesigner.touch(const amodule: tmsecomponent); +begin + dotouch(modules.findmodule(amodule)); +end; + +procedure tdesigner.touchall; +var + int1: integer; +begin + for int1:= 0 to modules.count - 1 do begin + dotouch(modules.itempo[int1]); + end; +end; + +procedure tdesigner.beginskipall; +begin + if fskipall = 0 then begin + exclude(fstate,des_skipall); + end; + inc(fskipall); +end; + +procedure tdesigner.endskipall; +begin + dec(fskipall); + if fskipall = 0 then begin + exclude(fstate,des_skipall); + end; +end; + +procedure tdesigner.handledesignexception(const sender: tobject); +var + exceptobj: tobject; + mstr1: msestring; + res1: modalresultsty; +begin + exceptobj:= exceptobject; + if exceptobj is exception then begin + if not (exceptobj is eabort) then begin + if not application.ismainthread then begin + application.showasyncexception(exception(exceptobj)); + end + else begin + if not (des_skipall in fstate) then begin + mstr1:= msestring(exception(exceptobj).message); + res1:= [mr_skip,mr_cancel]; + if fskipall > 0 then begin + include(res1,mr_skipall); + end; + case showmessage(mstr1,'Exception'{$ifdef FPC}, + [mr_skip,mr_skipall,mr_cancel],mr_skip,[],0,lineend+ + getexceptiontext(exceptobj, + exceptaddr,exceptframecount,exceptframes){$endif}) of + mr_skipall: begin + include(fstate,des_skipall); + end; + mr_cancel: begin + abort; + end; + end; + end; + end; + end; + end; +end; + +function tdesigner.changemodulename(const filename: msestring; + const avalue: string): string; +var + po1: pmoduleinfoty; + str1: string; +begin + po1:= checkmodule(filename); + str1:= po1^.instance.name; + po1^.instance.Name:= avalue; + result:= po1^.instance.name; + if result <> str1 then begin + modulechanged(po1); + end; +end; + +function tdesigner.componentcanedit: boolean; +begin + result:= (fcomponenteditor <> nil) and (cs_canedit in fcomponenteditor.state); +end; + +procedure tdesigner.checkident(const aname: string); +begin + if not isvalidident(aname) or (aname = '') then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_invalidname)])+ + aname+'".'); + end; +end; + +function tdesigner.changemoduleclassname(const filename: msestring; + const avalue: string): string; +var + po1: pmoduleinfoty; +begin + po1:= checkmodule(filename); + checkident(avalue); + designnotifications.moduleclassnamechanging(idesigner(self), + po1^.instance,avalue); + po1^.moduleclassname:= avalue; + result:= po1^.moduleclassname; + modulechanged(po1); +end; + +function tdesigner.changeinstancevarname(const filename: msestring; const avalue: string): string; +var + po1: pmoduleinfoty; +begin + po1:= checkmodule(filename); + checkident(avalue); + designnotifications.instancevarnamechanging(idesigner(self),po1^.instance,avalue); + po1^.instancevarname:= avalue; + result:= po1^.instancevarname; + modulechanged(po1); +end; + +function tdesigner.checksubmodule(const ainstance: tcomponent; + out aancestormodule: pmoduleinfoty): boolean; +begin + aancestormodule:= modules.findmodule( + fdescendentinstancelist.findancestor(ainstance)); + result:= aancestormodule <> nil; +end; + +procedure tdesigner.componentmodified(const component: tobject; + const apropname: string = ''; const apropindex: int32 = -1); +begin + if fformloadlocklevel = 0 then begin + if apropname <> '' then begin + objectinspectorfo.selectprop(component,apropname,apropindex); + end; + fallsaved:= false; + if component <> nil then begin + fmodules.componentmodified(component); + end; + if fcomponentmodifying = 0 then begin + postcomponentevent( + tcomponentevent.create(component,ord(me_componentmodified),false)); + end + end; +end; + +procedure tdesigner.begincomponentmodify; +begin + inc(fcomponentmodifying); +end; + +procedure tdesigner.endcomponentmodify; +begin + dec(fcomponentmodifying); +end; + +procedure tdesigner.beginpasting; +begin + include(fstate,des_pasting); +end; + +procedure tdesigner.endpasting; +begin + exclude(fstate,des_pasting); +end; + +function tdesigner.copycomponent(const source: tmsecomponent; + const root: tmsecomponent; const asinherited: boolean; + const noloading: boolean): tmsecomponent; +var + po1,po2: pmoduleinfoty; + ar1: msecomponentarty; + comp1: tmsecomponent; + int1: integer; + stream1: tmemorystream; + stream2: tstream; + reader: treader; + writer: twritermse; + posbefore: integer; +begin + {$ifdef mse_debugcopycomponent} + dumpcomponent(source,'***designer copycomponent source: '+source.name+' root: '+ + debugcompname(root)); + {$endif} + comp1:= source; + setlength(ar1,1); + ar1[0]:= source; + while true do begin + comp1:= fdescendentinstancelist.findancestor(comp1); + if comp1 = nil then begin + break; + end; + additem(pointerarty(ar1),comp1); + end; + setlength(ar1,high(ar1)+2); //dummy ancestor + beginsubmodulecopy; + if root <> nil then begin + po1:= fmodules.findmodule(root); + if po1 <> nil then begin + beginstreaming({po1}); + {$ifndef mse_nomethodswap} + buildmethodtable(po1); + {$endif} + end; + end + else begin + po1:= nil; + end; + fdescendentinstancelist.beginstreaming(po1); +// doswapmethodpointers(source,false); +{$ifndef mse_nomethodswap} + for int1:= 0 to high(ar1)-1 do begin + doswapmethodpointers(ar1[int1],false); + end; +{$endif} + try + if not noloading then begin + begingloballoading; + end; + result:= tmsecomponent(source.newinstance); +{$warnings off} + tcomponent1(result).setdesigning(true); +{$warnings on} + result.create(nil); + stream1:= tmemorystream.create; + try + for int1:= high(ar1)-1 downto 0 do begin + stream2:= nil; + if high(ar1) < 2 then begin //has no ancestors, loading stream can be used ???? + po2:= fmodules.findmodule(root); + if po2 <> nil then begin + stream2:= po2^.loadingstream; //needs possibly fixup + end; + end; + if stream2 = nil then begin + stream2:= stream1; + stream1.clear; + writer:= twritermse.create(stream1,4096,false); + try + {$ifdef mse_nomethodswap} + writer.onwritemethodproperty:= {$ifdef FPC}@{$endif}writedesignmethod; + {$endif} + writer.onfindancestor:= {$ifdef FPC}@{$endif}findancestor; + writer.writedescendent(ar1[int1],ar1[int1+1]); + result.name:= ar1[int1].name; + finally + writer.free; + end; + end; + {$ifdef mse_debugcopycomponent} + debugstreamout(stream1,'*source '+inttostr(int1)+ ': '+ + debugcompname(ar1[int1])+ + ' ancestor: '+debugcompname(ar1[int1+1])); + {$endif} + posbefore:= stream2.position; + stream2.position:= 0; + if asinherited then begin + reader:= tasinheritedreader.create(stream2,4096,true); + end + else begin + reader:= treader.create(stream2,4096); + end; + try + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= + {$ifdef FPC}@{$endif}fdescendentinstancelist.setrefreshmethod; + {$endif} + reader.onfindcomponentclass:= {$ifdef FPC}@{$endif}findcomponentclass; + reader.oncreatecomponent:= createcomponent(); + reader.onancestornotfound:= {$ifdef FPC}@{$endif}ancestornotfound; + {$ifdef mse_debugcopycomponent} + debugwriteln('*read '+inttostr(int1)+' '+ + debugcompname(ar1[int1])+' ancestor: '+debugcompname(ar1[int1+1])); + {$endif} + reader.readrootcomponent(result); + finally + reader.free; + stream2.position:= posbefore; + end; + end; + finally + stream1.free; + end; + tmsecomponent1(result).factualclassname:= + tmsecomponent1(source).factualclassname; + (* + result:= tmsecomponent(mseclasses.copycomponent(source,nil, + {$ifdef FPC}@{$endif}findancestor, + {$ifdef FPC}@{$endif}findcomponentclass, + {$ifdef FPC}@{$endif}createcomponent, + {$ifdef FPC}@{$endif}ancestornotfound)); + *) +{$ifndef mse_nomethodswap} + if po1 = nil then begin + docopymethods(source,result,false); + end; + doswapmethodpointers(result,true); +{$endif} + if not noloading then begin + notifygloballoading; + end; + finally + if not noloading then begin + endgloballoading; + end; +// doswapmethodpointers(source,true); +{$ifndef mse_nomethodswap} + for int1:= 0 to high(ar1)-1 do begin + doswapmethodpointers(ar1[int1],true); + end; +{$endif} + fdescendentinstancelist.endstreaming; + endsubmodulecopy; + if po1 <> nil then begin + endstreaming({po1}); + {$ifndef mse_nomethodswap} + releasemethodtable(po1); + {$endif} + end; + end; + {$ifdef mse_debugcopycomponent} + dumpcomponent(result,'*endcopycomp source: '+source.name+' result:'); + {$endif} +end; + +procedure tdesigner.revert(const acomponent: tcomponent); +var + comp1: tcomponent; +// msecomp1: tmsecomponent; +// po1: pancestorinfoty; + po2: pmoduleinfoty; + po4: pmoduleinfoty; +{$ifndef mse_nomethodswap} + po3: pointer; +{$endif} + bo1,bo2,bo3: boolean; + pt1: pointty; + delcomps: componentarty; +begin + po2:= fmodules.findmodule(tmsecomponent(rootcomponent(acomponent))); + bo3:= (csinline in acomponent.componentstate) and + (acomponent.owner <> nil) and + not (csancestor in acomponent.owner.componentstate); //submodule + if bo3 or (csancestor in acomponent.componentstate) then begin + comp1:= findancestorcomponent(acomponent); + if comp1 <> nil then begin + beginsubmodulecopy; + begingloballoading; + po4:= fmodules.findownermodule(comp1); +{$ifndef mse_nomethodswap} + po3:= po4^.methods.createmethodtable(getancestormethods(po4)); +{$endif} + fdescendentinstancelist.beginstreaming(po4); +{$ifndef mse_nomethodswap} + doswapmethodpointers(acomponent,false); + doswapmethodpointers(comp1,false); +{$endif} + try + bo1:= false; + bo2:= false; + if bo3 then begin //submodule + bo1:= acomponent is twidget; + if bo1 then begin + pt1:= twidget(acomponent).pos; + end + else begin + bo2:= isdatasubmodule(acomponent); + if bo2 then begin + pt1:= getcomponentpos(acomponent); + end; + end; + end; + refreshancestor(delcomps,acomponent,comp1,comp1,true, + {$ifdef FPC}@{$endif}findancestor, + {$ifdef FPC}@{$endif}findcomponentclass, + createcomponent(), + {$ifdef mse_nomethodswap} + {$ifdef FPC}@{$endif}fdescendentinstancelist.setrefreshmethod, + {$ifdef FPC}@{$endif}writedesignmethod + {$else} + nil,po3,po3 + {$endif} + ); +// docopymethods(comp1,acomponent,true); + if bo1 then begin + twidget(acomponent).pos:= pt1; //restore insert position + end + else begin + if bo2 then begin + setcomponentpos(acomponent,pt1); //restore insert position + end; + end; + notifygloballoading; + finally + endsubmodulecopy; + endgloballoading; + {$ifndef mse_nomethodswap} + po4^.methods.releasemethodtable; + doswapmethodpointers(acomponent,true); + doswapmethodpointers(comp1,true); + {$endif} + fdescendentinstancelist.endstreaming; + end; + end; + end; + freecomponents(delcomps); + componentmodified(po2^.instance); +end; + +function tdesigner.getreferencingmodulenames(const amodule: pmoduleinfoty): stringarty; +var + int1,int2: integer; + po1: pancestorinfoaty; + str1: string; + po2: pmoduleinfoty; + bo1: boolean; +begin + result:= nil; + for int1:= 0 to fmodules.count - 1 do begin + with fmodules[int1]^ do begin + for int2:= 0 to high(referencedmodules) do begin + if referencedmodules[int2] = amodule^.instance.Name then begin + additem(result,instance.name); + end; + end; + end; + end; + po1:= fdescendentinstancelist.datapo; + for int1:= 0 to fdescendentinstancelist.count - 1 do begin + with po1^[int1] do begin + if ancestor = amodule^.instance then begin + po2:= fmodules.findmodulebycomponent(descendent); + if po2 <> nil then begin + str1:= po2^.instance.name; + bo1:= false; + for int2:= high(result) downto 0 do begin + if result[int2] = str1 then begin + bo1:= true; + break; + end; + end; + if not bo1 then begin + additem(result,str1); + end; + end; + end; + end; + end; +end; + +function tdesigner.checkcanclose(const amodule: pmoduleinfoty; + out references: string): boolean; +begin + references:= concatstrings(getreferencingmodulenames(amodule),','); + result:= references = ''; +end; + +procedure tdesigner.findancestor(Writer: TWriter; Component: TComponent; + const aName: string; var Ancestor, RootAncestor: TComponent); +var + str1: string; + comp1: tcomponent; +begin + if (csinline in component.ComponentState) then begin + if (ancestor = nil) then begin + ancestor:= fdescendentinstancelist.findancestor(component); + rootancestor:= ancestor; + end; + end; + if csancestor in component.componentstate then begin + if ancestor = nil then begin + str1:= aname; + comp1:= component.owner; + while comp1 <> nil do begin + if csinline in comp1.componentstate then begin + break; + end; + str1:= comp1.name+'.'+str1; + comp1:= comp1.owner; + end; + if comp1 <> nil then begin + comp1:= fdescendentinstancelist.findancestor(comp1); + if comp1 <> nil then begin + ancestor:= findnestedcomponent(comp1,str1); + end; + end; + end; + end + else begin + if not (csinline in component.componentstate) and + (component.owner <> nil) and (csancestor in component.owner.componentstate) then begin + ancestor:= nil; //has name duplicate + end; + end; +end; + +procedure tdesigner.getmethodinfo(const method: tmethod; out moduleinfo: pmoduleinfoty; + out methodinfo: pmethodinfoty); +var + int1: integer; +begin +// moduleinfo:= fmodules.findmodulebyinstance(tcomponent(method.data)); +// if moduleinfo <> nil then begin +// with moduleinfo^.methods do begin +// methodinfo:= findmethod(method.data); +// end; +// end +// else begin + methodinfo:= nil; + for int1:= 0 to fmodules.count - 1 do begin + methodinfo:= fmodules[int1]^.methods.findmethod(method.data); + if methodinfo <> nil then begin + moduleinfo:= fmodules[int1]; + break; + end; + end; +// end; +end; + +function tdesigner.isownedmethod(const root: tcomponent; + const method: tmethod): boolean; +var + po1: pmoduleinfoty; +begin + result:= false; + po1:= fmodules.findmodulebyinstance(root); + if po1 <> nil then begin + result:= po1^.methods.findmethod(method.data) <> nil; + end; +end; + +procedure tdesigner.changemethodname(const method: tmethod; newname: string; + const atypeinfo: ptypeinfo); +var + po1: pmethodinfoty; + po2: pmoduleinfoty; + oldname: string; +begin + if not isvalidident(newname) then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_invalidmethodname)])+ + ' '''+newname+'''.'); + end; + getmethodinfo(method,po2,po1); + if po2 = nil then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_modulenotfound)])); + end; + if po1 = nil then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_methodnotfound)])); + end; + oldname:= po1^.name; + po1^.name:= newname; + fmodules.fmethodnames.setdata(ptruint(po1^.address),newname); + po2^.modified:= true; + designnotifications.methodnamechanged(fdesigner,po2^.instance,newname,oldname,atypeinfo); +end; + +function tdesigner.createmethod(const aname: string; const module: tmsecomponent; + const atype: ptypeinfo): tmethod; +var + po1: pmoduleinfoty; +begin + if module = nil then begin + po1:= floadingmodulepo; + end + else begin + po1:= fmodules.findmodulebyinstance(module); + end; + if po1 <> nil then begin + with po1^.methods do begin + inc(methodaddressdummy); + if methodaddressdummy < 256 then begin + methodaddressdummy:= 256; //0..255 -> special purpose + end; +// result.code:= pointer(methodaddressdummy); +// result.Data:= po1^.instance; + result.data:= pointer(methodaddressdummy); + result.code:= nil; + addmethod(aname,result.data,atype); + end; + if atype <> nil then begin + designnotifications.methodcreated(idesigner(self),module,aname,atype); + end; + end + else begin + result:= nullmethod; + end; +end; + +procedure tdesigner.checkmethod(const method: tmethod; const aname: string; + const module: tmsecomponent; const atype: ptypeinfo); +var + po1: pmethodinfoty; + po2: pmoduleinfoty; +begin + getmethodinfo(method,po2,po1); + if (po1 <> nil) and (po2 <> nil) and (atype <> nil) then begin + designnotifications.methodcreated(idesigner(self),module,aname,atype); + end; +end; + +procedure tdesigner.setactivemodule(const adesignform: tcustommseform); +var + po1: pmoduleinfoty; +begin + if adesignform <> nil then begin + po1:= fmodules.findform(adesignform); + end + else begin + po1:= nil; + end; + floadingmodulepo:= po1; + if po1 <> factmodulepo then begin + if factmodulepo <> nil then begin + designnotifications.moduledeactivated(idesigner(self),factmodulepo^.instance); + end; + if po1 <> nil then begin + factmodulepo:= po1; +// checkobjectinspector; //ev. create + designnotifications.moduleactivated(idesigner(self),factmodulepo^.instance); + end + else begin + factmodulepo:= nil; + end; + end; +end; + +function tdesigner.sourcenametoformname(const aname: filenamety): filenamety; +begin + result:= replacefileext(aname,formfileext); +end; + +procedure tdesigner.moduledestroyed(const amodule: pmoduleinfoty); +var + int1: integer; +begin + removefixupreferences(amodule^.instance,''); + if amodule = flastmethodmodulepo then begin + flastmethodmodulepo:= nil; + end; + if amodule = factmodulepo then begin + setactivemodule(nil); + end; + for int1:= 0 to amodule^.components.count - 1 do begin + fselections.remove(amodule^.components.next^.data.data.instance); + end; + designnotifications.moduledestroyed(idesigner(self),amodule^.instance); + designnotifications.selectionchanged(idesigner(self), + idesignerselections(fselections)); +// designnotifications.moduledestroyed(idesigner(self),amodule^.instance); +end; + +procedure tdesigner.addancestorinfo(const ainstance,aancestor: tmsecomponent); +begin + fdescendentinstancelist.add(ainstance,aancestor,fsubmodulelist); +end; + +procedure tdesigner.showformdesigner(const amodule: pmoduleinfoty); +begin + if amodule <> nil then begin + amodule^.designform.activate; + mainfo.createmodulemenuitem(amodule); + end; +end; + +procedure tdesigner.showastext(const amodule: pmoduleinfoty); +var + mstr1: filenamety; + bo1: boolean; +begin + if (amodule <> nil) then begin + mstr1:= amodule^.filename; + bo1:= amodule^.backupcreated; + if closemodule(amodule,true) then begin + designnotifications.showobjecttext(idesigner(self),mstr1,bo1); + end; + end; +end; + +procedure swapmethodpointer(const ainstance: tobject; const data: pointer; + const apropinfo: ppropinfo); +var + method1: tmethod; +begin + method1:= getmethodprop(ainstance,apropinfo); + if method1.data <> nil then begin + method1.code:= method1.data; + method1.data:= nil; + setmethodprop(ainstance,apropinfo,method1); + end; +end; + +procedure swapinitmethodpointer(const ainstance: tobject; const data: pointer; + const apropinfo: ppropinfo); +var + method1: tmethod; +begin + method1:= getmethodprop(ainstance,apropinfo); + if method1.code <> nil then begin + method1.data:= method1.code; + method1.code:= nil; + setmethodprop(ainstance,apropinfo,method1); + end; +end; + +{$ifndef mse_nomethodswap} +procedure tdesigner.internaldoswapmethodpointers(const aroot: tcomponent; + const ainstance: tobject; + const ainit: boolean); +begin + if finditem(pointerarty(fdescendentinstancelist.fswappedancestors), + ainstance) < 0 then begin + if ainit then begin + forallmethodproperties(aroot,ainstance,nil, + {$ifdef FPC}@{$endif}swapinitmethodpointer,true); + end + else begin + forallmethodproperties(aroot,ainstance,nil, + {$ifdef FPC}@{$endif}swapmethodpointer,true); + end; + end; +end; + +procedure tdesigner.doswapmethodpointers(const ainstance: tobject; + const ainit: boolean); +begin + if ainstance is tcomponent then begin + internaldoswapmethodpointers(rootcomponent(tcomponent(ainstance)), + ainstance,ainit); + end + else begin + internaldoswapmethodpointers(nil,ainstance,ainit); + end; +end; +{$endif} + +{$ifdef mse_nomethodswap} +procedure tdesigner.writedesignmethod(writer: twriter; instance: tpersistent; + propinfo: ppropinfo; const methodvalue: tmethod; + const defmethodvalue: tmethod; var handled: boolean); +var + str1: string; +// po1: pmethodinfoty; +begin + handled:= true; + if (methodvalue.data <> defmethodvalue.data) then begin + with tbinaryobjectwriter1(writer.driver) do begin + beginproperty(writer.propertypath + ppropinfo(propinfo)^.name); + if methodvalue.data = nil then begin + writevalue(vanil); + end + else begin + str1:= fmodules.fmethodnames.find(ptruint(methodvalue.data)); + if str1 = '' then begin + writevalue(vanil); + end + else begin + writevalue(vaident); + writestr(str1); + endproperty; + end; + end; + end; + end; +end; +{$endif} + +{ +procedure tdesigner.doswapmethodpointers(const ainstance: tobject; + const ainit: boolean); +var + propar: propinfopoarty; + int1: integer; + method1: tmethod; + po1: ^ppropinfo; + po2: pointer; +begin + propar:= getpropinfoar(ainstance); + po1:= pointer(propar); + for int1:= high(propar) downto 0 do begin + case po1^^.proptype^.kind of + tkmethod: begin + method1:= getmethodprop(ainstance,po1^); + if ainit then begin + if method1.code <> nil then begin + method1.data:= method1.code; + method1.code:= nil; + setmethodprop(ainstance,po1^,method1); + end; + end + else begin + if method1.data <> nil then begin + method1.code:= method1.data; + method1.data:= nil; + setmethodprop(ainstance,po1^,method1); + end; + end; + end; + end; + inc(po1); + end; +end; +} +function tdesigner.getancestorclassinfo(const ainstance: tcomponent; + const interfaceonly: boolean): classinfopoarty; +var + ar1: componentarty; + ar2: classinfopoarty; + int1{,int2}: integer; + po1: punitinfoty; + po2: pmoduleinfoty; +begin + ar1:= fdescendentinstancelist.getancestors(ainstance); + additem(pointerarty(ar1),ainstance); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + po2:= modules.findmodule(tmsecomponent(ar1[int1])); + if po2 <> nil then begin + po1:= sourceupdater.updateformunit(po2^.filename,interfaceonly); + if po1 <> nil then begin + ar2[int1]:= findclassinfobyinstance(tmsecomponent(ar1[int1]),po1); + end; + end; + end; + result:= classinfopoarty(packarray(pointerarty(ar2))); +end; + +function tdesigner.getancestorclassinfo(const ainstance: tcomponent; + const interfaceonly: boolean; + out aunits: unitinfopoarty): classinfopoarty; + +var + ar1: componentarty; + ar2: classinfopoarty; + int1{,int2}: integer; + po1: punitinfoty; + po2: pmoduleinfoty; +begin + ar1:= fdescendentinstancelist.getancestors(ainstance); + additem(pointerarty(ar1),ainstance); + setlength(ar2,length(ar1)); + setlength(aunits,length(ar1)); + for int1:= 0 to high(ar1) do begin + po2:= modules.findmodule(tmsecomponent(ar1[int1])); + if po2 <> nil then begin + po1:= sourceupdater.updateformunit(po2^.filename,interfaceonly); + aunits[int1]:= po1; + if po1 <> nil then begin + ar2[int1]:= findclassinfobyinstance(tmsecomponent(ar1[int1]),po1); + end; + end; + end; + result:= ar2; +end; + +function tdesigner.checkmethodtypes(const amodule: pmoduleinfoty; + const init: boolean): boolean; + //false on cancel +var + classinfar: classinfopoarty; + comp1: tcomponent; + + procedure doinit(const instance: tobject); + var + ar1: propinfopoarty; + int1,int2: integer; + method1: tmethod; + po1: pmethodinfoty; + obj1: tobject; + po2: pprocedureinfoty; + mr1: modalresultty; + begin + ar1:= getpropinfoar(instance); + for int1:= 0 to high(ar1) do begin + case ar1[int1]^.proptype^.kind of + tkmethod: begin + method1:= getmethodprop(instance,ar1[int1]); + if (method1.data <> nil) then begin + po1:= amodule^.methods.findmethod(method1.data); + if po1 <> nil then begin + if init then begin + po1^.typeinfo:= ar1[int1]^.proptype{$ifndef FPC}^{$endif}; + end + else begin + po2:= nil; + for int2:= 0 to high(classinfar) do begin + po2:= classinfar[int2]^.procedurelist.finditembyname(po1^.name); + if po2 <> nil then begin + break; + end; + end; + mr1:= mr_none; + if (po2 = nil) or not po2^.managed then begin + mr1:= askyesnocancel(actionsmo.c[ord(ac_publishedmeth)]+ ' '+ + msestring(amodule^.instance.name)+'.'+ + msestring(po1^.name)+' ('+ + msestring(comp1.name)+'.'+msestring(ar1[int1]^.name)+') '+ + actionsmo.c[ord(ac_doesnotexist)]+lineend+ + actionsmo.c[ord(ac_wishdelete)],actionsmo.c[ord(ac_warning)]); + end + else begin + if not parametersmatch(po1^.typeinfo,po2^.params) then begin + mr1:= askyesnocancel( + actionsmo.c[ord(ac_method)]+ + ' '+msestring(amodule^.instance.name)+'.'+ + msestring(po1^.name)+' ('+ + msestring(comp1.name)+'.'+msestring(ar1[int1]^.name)+') '+ + actionsmo.c[ord(ac_differentparams)]+lineend+ + actionsmo.c[ord(ac_wishdelete)],actionsmo.c[ord(ac_warning)]); + end; + end; + if mr1 = mr_yes then begin + setmethodprop(instance,ar1[int1],nullmethod); + modulechanged(amodule); + end + else begin + end; + result:= mr1 in [mr_yes,mr_no,mr_none]; + end; + end; + end; + end; + tkclass: begin + obj1:= getobjectprop(instance,ar1[int1]); + if issubprop(obj1) then begin + doinit(obj1); + if obj1 is tpersistentarrayprop then begin + with tpersistentarrayprop(obj1) do begin + for int2:= 0 to count - 1 do begin + doinit(items[int2]); + if not result then begin + break; + end; + end; + end; + end + else begin + if obj1 is tcollection then begin + with tcollection(obj1) do begin + for int2:= 0 to count - 1 do begin + doinit(items[int2]); + if not result then begin + break; + end; + end; + end; + end; + end; + end; + end; + end; + if not result then begin + break; + end; + end; + end; + +var + int1: integer; + mstr1: msestring; +// po3: punitinfoty; +begin + result:= true; + if not init then begin + mstr1:= replacefileext(amodule^.filename,pasfileext); + if sourcefo.findsourcepage(mstr1) = nil then begin + exit; + end; +// po3:= sourceupdater.updateformunit(amodule^.filename,true); +// if po3= nil then begin +// exit; +// end; + classinfar:= getancestorclassinfo(amodule^.instance,true); +// classinf:= findclassinfobyinstance(amodule^.instance,po3); +// if classinf = nil then begin +// exit; +// end; + end; + with amodule^ do begin + for int1:= 0 to components.count - 1 do begin + comp1:= components.next^.data.data.instance; + doinit(comp1); + if not result then begin + break; + end; + end; + end; +end; + +procedure tdesigner.dofixup; +begin + RegisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + try + globalfixupreferences; + finally + unregisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + end; +end; + +procedure tdesigner.readererror(reader: treader; const message: string; + var handled: boolean); +var + comp1: tcomponent; +begin + comp1:= reader.lookuproot; + if comp1 = nil then begin + comp1:= reader.root; + end; + with exception(ExceptObject) do begin + message:= ansistring(actionsmo.c[ord(ac_component)])+ + ownernamepath(comp1)+'":'+lineend+message; + end; +end; + +procedure tdesigner.readerenumerror(const reader: treader; + const atype: ptypeinfo; const aitemname: string; var avalue: longword); +begin + if atype = typeinfo(charencodingty) then begin + if (aitemname = 'ce_utf8n') then begin + avalue:= ord(ce_utf8); + floadingmodulepo^.readermodified:= true; + end; + end; +end; + +procedure tdesigner.readerseterror(const reader: treader; + const atype: ptypeinfo; const aitemname: string; var avalue: integer); +begin + if atype = typeinfo(optioneditty) then begin + if (aitemname = 'oe_autopopupmenu') or + (aitemname = 'oe_keyexecute') then begin + avalue:= -2; //skip + floadingmodulepo^.readermodified:= true; + end; + end; + if atype = typeinfo(framelocalpropty) then begin + if (aitemname = 'frl_frameimageoffsetactivemouse') or + (aitemname = 'frl_frameimageoffsetactiveclicked') then begin + avalue:= -2; //skip + floadingmodulepo^.readermodified:= true; + end; + end; + if atype = typeinfo(framelocalprop1ty) then begin + if (aitemname = 'frl1_framefaceoffsetactivemouse') or + (aitemname = 'frl1_framefaceoffsetactiveclicked') then begin + avalue:= -2; //skip + floadingmodulepo^.readermodified:= true; + end; + end; +end; + +function tdesigner.loadformfile(filename: msestring; + const skipexisting: boolean): pmoduleinfoty; +var + module: tmsecomponent; + loadedsubmodulesindex: integer; + moduleinfo: tmoduleinfo; + + procedure dodelete; + var + int1: integer; + desfo: tcustommseform; + begin + removefixupreferences(module,''); + for int1:= high(floadedsubmodules) downto loadedsubmodulesindex+1 do begin + removefixupreferences(floadedsubmodules[int1],''); + end; + desfo:= result^.designform; + moduleinfo.free; //frees module by designform + if desfo = nil then begin + module.Free; + end; + module:= nil; + result:= nil; + end; + +var + moduleclassname1,modulename, + designmoduleclassname: string; + stream1: ttextstream; + stream2: tmemorystream; + reader: treader; + flags: tfilerflags; + pos: integer; + rootnames,rootinstancenames: tstringlist; + int1: integer; + wstr1: msestring; + res1: modalresultty; + bo1: boolean; + loadingdesignerbefore: tdesigner; + loadingmodulepobefore: pmoduleinfoty; + isinherited: boolean; + str1: string; + fixupmodule: string; + lastmissed: string; + comp1: tcomponent; + deletefixups: boolean; + exp1: exception; + +begin //loadformfile + filename:= filepath(filename); + result:= fmodules.findmodule(filename); + if result = nil then begin + designnotifications.closeobjecttext(idesigner(self),filename,bo1); + if bo1 then begin + exit; //canceled + end; + exp1:= nil; + stream1:= ttextstream.Create(filename,fm_read); + designmoduleclassname:= ''; + rootnames:= tstringlist.create; + rootinstancenames:= tstringlist.create; + beginskipall; + try + stream2:= tmemorystream.Create; + try + try + objecttexttobinarymse(stream1,stream2); + stream2.position:= 0; + reader:= treader.create(stream2,4096); + try + with treader1(reader) do begin + driver.beginrootcomponent; + driver.begincomponent(flags,pos,moduleclassname1,modulename); + isinherited:= ffinherited in flags; + while not endoflist do begin + str1:= driver.beginproperty; + if str1 = moduleclassnamename then begin + designmoduleclassname:= readstring; + end + else begin + driver.skipvalue; + end; + end; + end; + finally + reader.free; + end; + result:= modules.findmodulebyname(modulename); + if result <> nil then begin + stream2.free; //not listed in loadingstreams + if skipexisting and issamefilepath(result^.filename,filename) then begin + exit; + end; + raise exception.create(ansistring(actionsmo.c[ord(ac_amodule)])+ + modulename+ansistring(actionsmo.c[ord(ac_isopen)])); + end; + stream2.Position:= 0; + loadingdesignerbefore:= loadingdesigner; + loadingdesigner:= self; + inc(fformloadlocklevel); + begingloballoading; + try + try + moduleinfo:= fmodules.newmodule(isinherited,filename,moduleclassname1, + modulename,designmoduleclassname); + fmodules.add(moduleinfo); + result:= @moduleinfo.info; + result^.loadingstream:= stream2; + module:= result^.instance; + stream2.Position:= 0; + reader:= treader.Create(stream2,4096); + loadedsubmodulesindex:= high(floadedsubmodules); + inc(fformloadlevel); + loadingmodulepobefore:= floadingmodulepo; + try + floadingmodulepo:= result; + lockfindglobalcomponent; + try + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= {$ifdef FPC}@{$endif}setmethodproperty; + {$else} + reader.onfindmethod:= {$ifdef FPC}@{$endif}findmethod; + {$endif} + reader.onfindcomponentclass:= {$ifdef FPC}@{$endif}findcomponentclass; + reader.onancestornotfound:= {$ifdef FPC}@{$endif}ancestornotfound; + reader.oncreatecomponent:= createcomponent(); + reader.onerror:= {$ifdef FPC}@{$endif}readererror; + reader.onseterror:= @readerseterror; + reader.onenumerror:= @readerenumerror; + module.Name:= modulename; + reader.ReadrootComponent(module); + {$ifndef mse_nomethodswap} + doswapmethodpointers(module,true); + {$endif} + result^.components.assigncomps(module); + getfixupreferencenames(module,rootnames); + setlength(result^.referencedmodules,rootnames.Count); + for int1:= 0 to high(result^.referencedmodules) do begin + result^.referencedmodules[int1]:= rootnames[int1]; + end; + dofixup; + fixupmodule:= ''; + lastmissed:= ''; + deletefixups:= true; + while true do begin + rootnames.clear; + rootinstancenames.clear; + getfixupreferencenames(module,rootnames); + for int1:= rootnames.count - 1 downto 0 do begin + comp1:= fmodules.findmoduleinstancebyname(rootnames[int1]); + if (comp1 <> nil) and (comp1 <> module) and + (csloading in comp1.componentstate) then begin + deletefixups:= false; + additem(pointerarty(fcheckfixups),result); + rootnames.delete(int1); //there is hope + end; + end; + if rootnames.Count > 0 then begin + if assigned(fongetmodulenamefile) then begin + try + res1:= mr_cancel; + if fixupmodule = rootnames[0] then begin + break; + end; + fixupmodule:= rootnames[0]; + getfixupinstancenames(module,fixupmodule,rootinstancenames); + if rootinstancenames.count > 0 then begin + str1:= '.'+rootinstancenames[0]; + end + else begin + str1:= ''; + end; + lastmissed:= fixupmodule + str1; + fongetmodulenamefile(result,lastmissed,res1); + dofixup; + case res1 of + mr_ok: begin + end; + mr_ignore: begin + rootnames.Clear; + break; + end; + else begin + break; + end; + end; + except + application.handleexception(self); + break; + end; + end + else begin + break; + end; + end + else begin + break; + end; + end; + if (module <> nil) and deletefixups then begin + removefixupreferences(module,''); + end; + if rootnames.Count > 0 then begin + wstr1:= msestring(rootnames[0]); + for int1:= 1 to rootnames.Count - 1 do begin + wstr1:= wstr1 + ','+msestring(rootnames[int1]); + end; + raise exception.Create(ansistring( + actionsmo.c[ord(ac_unresolvedref)]+' '+ + msestring(lastmissed)+lineend+ + actionsmo.c[ord(ac_modules)]+' '+wstr1+'.')); + end; + result^.resolved:= true; + except + freeandnil(reader); //used stream will be freed + dodelete; + raise; + end; + finally + reader.free; + floadingmodulepo:= loadingmodulepobefore; + setlength(floadedsubmodules,loadedsubmodulesindex+1); + //remove info + dec(fformloadlevel); + unlockfindglobalcomponent; + end; + if result <> nil then begin + result^.designform:= createdesignform(self,result); + result^.designform.getcorbainterface(typeinfo(iformdesigner), + result^.designformintf); + checkmethodtypes(result,true); + result^.modified:= result^.readermodified; +// if result^.modified then begin +// mainfo.sourcechanged(nil); +// end; + end; + finally + loadingdesigner:= nil; + end; + notifygloballoading; + finally + loadingdesigner:= loadingdesignerbefore; + endgloballoading; + dec(fformloadlocklevel); + end; + except + on e: exception do begin + e.Message:= ansistring(actionsmo.c[ord(ac_cannotreadform)]+filename)+ + '".'+lineend+e.Message; + raise; + end; + end; + finally + if fformloadlevel = 0 then begin + fmodules.freeloadingstreams; + while high(fcheckfixups) >= 0 do begin + rootnames.clear; + with fcheckfixups[high(fcheckfixups)]^ do begin + getfixupreferencenames(instance,rootnames); + if rootnames.count > 0 then begin + designnotifications.showobjecttext( + idesigner(self),filename,backupcreated); + if exp1 = nil then begin + rootinstancenames.clear; + getfixupinstancenames(instance,rootnames[0],rootinstancenames); + if rootinstancenames.count > 0 then begin + str1:= '.'+rootinstancenames[0]; + end + else begin + str1:= ''; + end; + exp1:= exception.create(ansistring( + actionsmo.c[ord(ac_cannotreadform)]+filename+'".'+lineend+ + actionsmo.c[ord(ac_unresolvedref)]+ + msestring(rootnames[0]+str1+'.'))); + end; + instance.free; + fmodules.removemoduleinfo(fcheckfixups[high(fcheckfixups)]); + end + else begin + setlength(fcheckfixups,high(fcheckfixups)); + end; + end; + end; + removefixupreferences(nil,''); + if exp1 <> nil then begin + if result <> nil then begin + dodelete; + end; + raise exp1; + end; + end; + end; + finally + rootnames.free; + rootinstancenames.free; + stream1.Free; + endskipall; + end; + end; + (* + {$ifdef mse_debugsubmodule} + {$ifdef mse_debugmoduleload} + dumpcomponent(result^.instance,filename); + {$endif} + debugbinstreamout(result^.instance,nil, + {$ifdef FPC}@{$endif}fdesigner.findancestor, + '*****loadformfile '+filename); + {$endif} + *) +end; //loadformfile + +procedure createbackupfile(const newname,origname: filenamety; + var backupcreated: boolean; const backupcount: integer); +var + int1: integer; + mstr1: filenamety; + mstr2: filenamety; +begin + if (backupcount > 0) and not backupcreated and + issamefilename(newname,origname) and findfile(origname) then begin + backupcreated:= true; + mstr1:= origname + backupext; + for int1:= backupcount-1 downto 2 do begin + mstr2:= mstr1+inttostrmse(int1-1); + if findfile(mstr2) then begin + msefileutils.renamefile(mstr2,mstr1+inttostrmse(int1)); + end; + end; + if backupcount > 1 then begin + if findfile(mstr1) then begin + msefileutils.renamefile(mstr1,mstr1+'1'); + end; + end; + msefileutils.copyfile(origname,mstr1); + end; +end; + +function tdesigner.getancestormethods(const amodule: pmoduleinfoty): methodsarty; +var + comp1: tcomponent; +begin +{$ifdef mse_nomethodswap} + setlength(result,1); + result[0]:= amodule^.methods; +{$else} + result:= nil; +{$endif} + comp1:= amodule^.instance; + while true do begin + comp1:= fdescendentinstancelist.findancestor(comp1); + if comp1 = nil then begin + break; + end; + additem(pointerarty(result),fmodules.findmodulebyinstance(comp1)^.methods); + end; +end; + +{$ifndef mse_nomethodswap} +procedure tdesigner.buildmethodtable(const amodule: pmoduleinfoty); +begin + if amodule <> nil then begin + with amodule^ do begin + if methodtableswapped = 0 then begin +// flookupmodule:= amodule; + methodtablebefore:= swapmethodtable(instance, + methods.createmethodtable(getancestormethods(amodule))); + end; + inc(methodtableswapped); + end; + end; +end; + +procedure tdesigner.releasemethodtable(const amodule: pmoduleinfoty); +begin + if amodule <> nil then begin + with amodule^ do begin + dec(methodtableswapped); + if methodtableswapped = 0 then begin + swapmethodtable(instance,methodtablebefore); + methods.releasemethodtable; +// flookupmodule:= nil; + end; + end; + end; +end; +{$endif} +procedure tdesigner.writemodule(const amodule: pmoduleinfoty; + const astream: tstream); +var + writer1: twritermse; + ancestor: tcomponent; +begin +{$ifndef mse_nomethodswap} + buildmethodtable(amodule); +{$endif} + with amodule^ do begin + fdescendentinstancelist.beginstreaming(nil); + {$ifndef mse_nomethodswap} + doswapmethodpointers(instance,false); + {$endif} + writer1:= twritermse.create(astream,4096,false); + if instance is twidget then begin + fdescendentinstancelist.setnodefaultpos(twidget(instance)); + end; + beginstreaming({amodule}); + try + if csancestor in instance.componentstate then begin + ancestor:= fdescendentinstancelist.findancestor(instance); + end + else begin + ancestor:= nil; + end; + writer1.onfindancestor:= {$ifdef FPC}@{$endif}findancestor; + {$ifdef mse_nomethodswap} + writer1.onwritemethodproperty:= {$ifdef FPC}@{$endif}writedesignmethod; + {$endif} + writer1.writedescendent(instance,ancestor); + finally + fdescendentinstancelist.endstreaming; + endstreaming({amodule}); + writer1.free; + {$ifndef mse_nomethodswap} + doswapmethodpointers(instance,true); + releasemethodtable(amodule); + {$endif} + if instance is twidget then begin + fdescendentinstancelist.restorepos(twidget(instance)); + end; + end; + end; +end; + +function tdesigner.saveformfile(const modulepo: pmoduleinfoty; + const afilename: msestring; createdatafile: boolean): boolean; + //false if aborted +var + stream1: tmemorystream; + stream2: tbufstream; + info: fileinfoty; +begin + if createdatafile and projectoptions.s.checkmethods + and not checkmethodtypes(modulepo,false{,nil}) then begin + result:= false; + exit; + end; + result:= true; + with modulepo^ do begin + createbackupfile(afilename,filename, + backupcreated,projectoptions.e.backupfilecount); + if createdatafile and (filetag <> 0) then begin + sourcefo.filechangenotifyer.removenotification(filename,filetag); + end; + stream1:= tmemorystream.Create; + application.beginwait(); + try + writemodule(modulepo,stream1); + stream2:= tbufstream.createtransaction(afilename); + stream2.usewritebuffer:= true; + try + stream1.position:= 0; + try + objectbinarytotextmse(stream1,stream2); + except + stream2.cancel; + raise; + end; + finally + stream2.Free; + end; + if issamefilename(afilename,filename) then begin + modified:= false; + if getfileinfo(afilename,info) then begin + savetime:= info.extinfo1.modtime; + end; + end; + if createdatafile then begin + if filetag = 0 then begin + filetag:= sourcefo.newfiletag; + end; + sourcefo.filechangenotifyer.addnotification(filename,filetag,false); + formtexttoobjsource(afilename,moduleclassname,'',fobjformat); + end; + finally + application.endwait(); + stream1.free; + end; + end; +end; + +procedure tdesigner.refreshdatafile(const amodule: pmoduleinfoty); +begin + with amodule^ do begin + formtexttoobjsource(filename,moduleclassname,'',fobjformat); + end; +end; + +function tdesigner.saveall(noconfirm,createdatafile: boolean): modalresultty; +var + int1: integer; + po1: pmoduleinfoty; +begin + result:= mr_none; + for int1:= 0 to modules.count - 1 do begin + po1:= modules[int1]; + with po1^ do begin + if not modified and projectoptions.s.checkmethods then begin + if not checkmethodtypes(po1,false{,nil}) then begin + result:= mr_cancel; + exit; + end; + end; + if modified and (result <> mr_noall) and + (noconfirm or + (result = mr_all) or + not fallsaved and confirmsavechangedfile(filename,result,true)) then begin + if not saveformfile(po1,filename,createdatafile) then begin + result:= mr_cancel; + end; + end; + case result of + mr_cancel: begin + exit; + end; + mr_noall: begin + break; + end; + end; + end; + end; + fallsaved:= fallsaved or not noconfirm; +end; + +function tdesigner.closemodule(const amodule: pmoduleinfoty; + const checksave: boolean): boolean; //true if closed +var + closingmodules: moduleinfopoarty; + + procedure dochecksave(const amodule: pmoduleinfoty); + var + modalresult: modalresultty; + int1: integer; + ar1: stringarty; + ar2: moduleinfopoarty; + begin + ar1:= nil; //compiler warning + if amodule <> nil then begin + modalresult:= mr_none; + for int1:= 0 to high(closingmodules) do begin + if closingmodules[int1] = amodule then begin + exit; //already checked; + end; + end; + with amodule^ do begin + if modified and checksave and + confirmsavechangedfile(filename,modalresult,false) then begin + saveformfile(amodule,filename,true); + end; + end; + result:= modalresult <> mr_cancel; + if result then begin + additem(pointerarty(closingmodules),amodule); + ar1:= getreferencingmodulenames(amodule); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar2[int1]:= modules.findmodulebyname(ar1[int1]); + dochecksave(ar2[int1]); + if not result then begin + break; + end; + end; + end; + end; + end; + +var + int1: integer; + +begin //closemodule + result:= false; + closingmodules:= nil; + dochecksave(amodule); + if result then begin + for int1:= 0 to high(closingmodules) do begin + if closingmodules[int1] <> nil then begin + modules.removemoduleinfo(closingmodules[int1]); + end; + end; + end; +end; //closemodule + +function tdesigner.modified: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to fmodules.count - 1 do begin + if modules[int1]^.modified then begin + result:= true; + break; + end; + end; +end; + +procedure tdesigner.NoSelection; +begin + selectcomponent(nil); +end; + +procedure tdesigner.SelectComponent(Instance: Tcomponent); +var + list: tdesignerselections; +begin + freeandnil(fcomponenteditor); + list:= tdesignerselections.create; + try + if instance <> nil then begin + list.Add(instance); + fcomponenteditor:= componenteditors.geteditorclass( + componentclassty(instance.classtype)).create(idesigner(self),instance); + end; + setselections(idesignerselections(list)); + finally + list.Free; + end; +end; + +procedure tdesigner.selectionchanged; +begin + designnotifications.SelectionChanged( + idesigner(self),idesignerselections(fselections)); +end; + +procedure tdesigner.SetSelections(const List: IDesignerSelections); +var + int1: integer; + component1: tcomponent; +begin + for int1:= 0 to fselections.count - 1 do begin + component1:= fselections[int1]; + if component1 is tmsecomponent then begin + tmsecomponent1(component1).designselected(false); + end; + end; + fselections.assign(list); + for int1:= 0 to fselections.count - 1 do begin + component1:= fselections[int1]; + if component1 is tmsecomponent then begin + tmsecomponent1(component1).designselected(true); + end; + end; + selectionchanged; +end; +{ +procedure tdesigner.checkobjectinspector; +begin + if objectinspectorfo = nil then begin + objectinspectorfo:= tobjectinspectorfo.create(nil,self); + end; +end; +} +procedure tdesigner.showobjectinspector; +begin +// asyncevent(showobjectinspectortag); + //use async because of window stacking problems + objectinspectorfo.activate; +end; + +function tdesigner.formfiletoname(const filename: msestring): msestring; +begin + result:= removefileext(msefileutils.filename(filename)); +end; + +function tdesigner.getmethod(const aname: string; + const methodowner: tmsecomponent; const atype: ptypeinfo; + const searchancestors: boolean): tmethod; +var + ar1: componentarty; + int1: integer; +begin + result:= fmodules.findmethodbyname(aname,atype,methodowner); + if searchancestors and (result.data = nil) then begin + ar1:= fdescendentinstancelist.getancestors(methodowner); + for int1:= high(ar1) downto 0 do begin + result:= fmodules.findmethodbyname(aname,atype,tmsecomponent(ar1[int1])); + if result.data <> nil then begin + break; + end; + end; + end; +end; + +function tdesigner.getmethodname(const Method: TMethod; const comp: tcomponent): string; +begin + result:= fmodules.findmethodname(method,comp); +end; + +function tdesigner.actmodulepo: pmoduleinfoty; +begin + result:= factmodulepo; +end; + +function tdesigner.getcomponentname(const comp: tcomponent): string; +var + int1: integer; + po1: pmoduleinfoty; +begin + result:= ''; + if comp <> nil then begin + if (floadingmodulepo <> nil) and + (comp.Owner = floadingmodulepo^.instance) then begin //??? + result:= comp.name; + end + else begin + for int1:= 0 to fmodules.count - 1 do begin + po1:= fmodules[int1]; + if issubcomponent(po1^.instance,comp) then begin + if po1 = floadingmodulepo then begin + result:= getcomponentdispname(comp); + end + else begin + result:= po1^.instancevarname + '.' + getcomponentdispname(comp); + end; + break; + end; + end; + end; + end; +end; + +function tdesigner.getcomponentdispname(const comp: tcomponent): string; + //returns qualified name +var + comp1: tcomponent; + bo1: boolean; + ch1: char; +begin + result:= comp.Name; + ch1:= subcomponentsplitchar; +// if not (cssubcomponent in comp.componentstyle) then begin +// ch1:= '.'; +// end; + comp1:= comp.owner; + while not ismodule(comp1) do begin + result:= comp1.Name + ch1 + result; + comp1:= comp1.Owner; +// if not (cssubcomponent in comp1.componentstyle) then begin +// ch1:= '.'; +// end; + end; + bo1:= ismodule(comp); + if bo1 or ismodule(comp.owner) then begin + if csancestor in comp.componentstate then begin + if bo1 then begin + comp1:= comp; + end + else begin + comp1:= comp.owner; + end; + comp1:= fdescendentinstancelist.findancestor(comp1); + if comp1 <> nil then begin + result:= result+'<'+comp1.name+'>'; + end; + end; + end; +end; + +function tdesigner.getcomponent(const aname: string; + const aroot: tcomponent): tcomponent; +var + ar1,ar2: stringarty; + po1,po2: pmoduleinfoty; + int1,int2: integer; + bo1: boolean; +// str1: string; +begin + result:= nil; + if (aname <> '') and (floadingmodulepo <> nil) then begin + splitstring(aname,ar2,':'); + result:= floadingmodulepo^.components.getcomponent(ar2[0]); + if result = nil then begin + splitstring(ar2[0],ar1,'.'); + if high(ar1) = 1 then begin + ar1[0]:= uppercase(ar1[0]); + for int1:= 0 to fmodules.count - 1 do begin + po1:= fmodules[int1]; + if stricomp(pchar(po1^.instancevarname),pchar(ar1[0])) = 0 then begin + result:= po1^.components.getcomponent(ar1[1]); + if result <> nil then begin + if (aroot <> nil) and (aroot <> po1^.instance) then begin + po2:= fmodules.findmodulebyinstance(aroot); + if po2 <> nil then begin + bo1:= false; + for int2:= 0 to high(po2^.referencedmodules) do begin + if po2^.referencedmodules[int2] = aroot.name then begin + bo1:= true; + break; + end; + end; + if not bo1 then begin + additem(po2^.referencedmodules,po1^.instance.name); + end; + end; + end; + break; + end; + end; + end; + end; + end; + if (result <> nil) and (high(ar2) > 0) then begin + for int1:= 1 to high(ar2) do begin + result:= result.findcomponent(ar2[int1]); + if result = nil then begin + break; + end; + end; + end; + end; +end; + +function tdesigner.getcomponent(const apath: string; + out amodule: pmoduleinfoty): tcomponent; +var + ar1: stringarty; +begin + result:= nil; + amodule:= nil; + ar1:= splitstring(apath,'.'); + if ar1 <> nil then begin + amodule:= fmodules.findmodulebyname(ar1[0]); + if amodule <> nil then begin + result:= findcomponentbynamepath(apath,amodule^.instance); + end; + end; +end; + +function tdesigner.getcomponentlist( + const acomponentclass: tcomponentclass; + const filter: compfilterfuncty = nil; + const allmodules: boolean = false): componentarty; +var + acount: integer; + + procedure check(const acomp: tcomponent); + begin + if acomp.InheritsFrom(acomponentclass) and + (({$ifndef FPC}@{$endif}filter = nil) or filter(acomp)) and + not isnosubcomp(acomp) then begin + additem(pointerarty(result),acomp,acount); + end; + end; //check + + procedure scanmodule(amodule: pmoduleinfoty); + var + int1,int3: integer; + comp1,comp2: tcomponent; + begin + with amodule^.components do begin +// for int1:= 0 to high(result) do begin +// check(next^.instance); +// end; + for int1:= 0 to count - 1 do begin + comp1:= next^.data.data.instance; + check(comp1); + for int3:= 0 to comp1.componentcount - 1 do begin + comp2:= comp1.components[int3]; + if cssubcomponent in comp2.componentstyle then begin + check(comp2); + end; + end; + end; + end; + end; + +var + int1: integer; + +begin + acount:= 0; + if allmodules then begin + for int1:= 0 to modules.count-1 do begin + scanmodule(modules[int1]); + end; + end + else begin + if floadingmodulepo <> nil then begin + scanmodule(floadingmodulepo); + end; + end; + setlength(result,acount); +end; + +function compcompname(const l,r): integer; +begin + result:= ord(msestring(l)[1])-ord(msestring(r)[1]); + if result = 0 then begin + result:= countchars(msestring(l),msechar('.')) - + countchars(msestring(r),msechar('.')); + if result = 0 then begin + result:= msestringicomp(msestring(l),msestring(r)); + end; + end; +end; + +procedure sortcompnamelist(var avalue: msestringarty); +var + int1: integer; +begin + sortarray(avalue,{$ifdef FPC}@{$endif}compcompname); + for int1:= 0 to high(avalue) do begin + avalue[int1]:= copy(avalue[int1],2,bigint); + end; +end; + +function tdesigner.getcomponentnamelist(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil): msestringarty; +var + str1: msestring; + acount: integer; + + procedure check(const comp1: tcomponent); + var + int3: integer; + comp2: tcomponent; + begin + if comp1.InheritsFrom(acomponentclass) and + (({$ifndef FPC}@{$endif}filter = nil) or filter(comp1)) then begin + if ((aowner = nil) or (aowner = comp1.owner)) and + (includeinherited or + (comp1.componentstate * [csinline,csancestor] = [])) then begin + additem(result,str1+msestring(getcomponentdispname(comp1)),acount); + end; + end; + for int3:= 0 to comp1.componentcount - 1 do begin + comp2:= comp1.components[int3]; + if (cssubcomponent in comp2.componentstyle){ and + not isnosubcomp(comp2)} then begin + check(comp2); + end; + end; + end; + +var + int1,int2{,int3}: integer; + comp1{,comp2}: tcomponent; + po1: pmoduleinfoty; +begin + result:= nil; + acount:= 0; + for int1:= 0 to fmodules.count - 1 do begin + po1:= fmodules[int1]; + if po1 = floadingmodulepo then begin + str1:= ' '; + end + else begin + str1:= msestring('z'+po1^.instancevarname + '.'); + end; + with po1^.components do begin + for int2:= 0 to count - 1 do begin + comp1:= next^.data.data.instance; + check(comp1); + end; + end; + end; + setlength(result,acount); + sortcompnamelist(result); +end; + +function tdesigner.getcomponentnamelist(const acomponentclass: tcomponentclass; + const arootcomp: tcomponent; + const filter: compfilterfuncty = nil): msestringarty; +var + acount: integer; + + procedure check(const acomp: tcomponent; prefix: msestring); + var + i1: int32; + comp1: tcomponent; + begin + if (prefix <> '') then begin + if (acomp is acomponentclass) and filter(acomp) then begin + additem(result,prefix,acount); + end; + prefix:= prefix+'.'; + end; + for i1:= 0 to acomp.componentcount-1 do begin + comp1:= acomp.components[i1]; + check(comp1,prefix+msestring(comp1.name)); + end; + end; + +begin + result:= nil; + acount:= 0; + check(arootcomp,''); + setlength(result,acount); + sortarray(result); +end; + +function tdesigner.getwidgetnamelist(const awidgetclass: widgetclassty; + const arootwidget: twidget; + const filter: compfilterfuncty = nil): msestringarty; +var + acount: integer; + + procedure check(const awidget: twidget; prefix: msestring); + var + i1: int32; + begin + if prefix = '!' then begin //first + prefix:= ''; + end + else begin + if ((awidgetclass = nil) or (awidget is awidgetclass)) and + filter(awidget) then begin + additem(result,prefix+msestring(awidget.name),acount); + end; + if csinline in awidget.componentstate then begin + prefix:= prefix + msestring(awidget.name)+'.'; + end; + end; + for i1:= 0 to awidget.widgetcount-1 do begin + check(awidget.widgets[i1],prefix); + end; + end; + +begin + result:= nil; + acount:= 0; + check(arootwidget,'!'); + setlength(result,acount); + sortarray(result); +end; + +function tdesigner.getcomponentnamelist(const acomponents: componentarty; + const amodule: tmsecomponent): msestringarty; +var + int1,int2: integer; + co1: tcomponent; +begin + setlength(result,length(acomponents)); + int2:= 0; + for int1:= 0 to high(acomponents) do begin + if acomponents[int1] <> nil then begin + co1:= rootcomponent(acomponents[int1]); + if co1 = amodule then begin + result[int2]:= ' '; + end + else begin + result[int2]:= msestring('z'+co1.name + '.'); + end; + result[int2]:= result[int2] + + msestring(getcomponentdispname(acomponents[int1])); + inc(int2); + end; + end; + setlength(result,int2); + sortcompnamelist(result); +end; + +type + tdesigncompnameitem = class(tcompnameitem) + private + fcomp: tcomponent; + public + constructor create(const acomp: tcomponent; + const aisvalue: boolean); reintroduce; + function findcomp(const acomp: tcomponent): tdesigncompnameitem; + end; + +{ tdesigncompnameitem } + +constructor tdesigncompnameitem.create(const acomp: tcomponent; + const aisvalue: boolean); +begin + fcomp:= acomp; + inherited create; + isvalue:= aisvalue; + if acomp <> nil then begin + caption:= msestring(acomp.name); + end; +end; + +function tdesigncompnameitem.findcomp(const acomp: tcomponent): tdesigncompnameitem; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to fcount -1 do begin + if tdesigncompnameitem(fitems[int1]).fcomp = acomp then begin + result:= tdesigncompnameitem(fitems[int1]); + break; + end; + end; +end; + + +function tdesigner.getcomponentnametree(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const findmode: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil; + const amodule: tcomponent = nil): tcompnameitem; + + procedure check(const acomp: tcomponent); + var + int1,int3: integer; + comp1,comp2: tcomponent; + node1,node2,node3: tdesigncompnameitem; + ar1: componentarty; + begin + if ((acomponentclass = nil) or acomp.InheritsFrom(acomponentclass)) and + ((@filter = nil) or filter(acomp)) then begin + if ((aowner = nil) or (aowner = acomp.owner)) and + (includeinherited or + (acomp.componentstate * [csinline,csancestor] = [])) then begin + node1:= tdesigncompnameitem.create(acomp,true); + node1.imagenr:= 4; + node1.state:= node1.state + [ns_imagenrfix]; + comp1:= acomp.owner; + while comp1 <> nil do begin + additem(pointerarty(ar1),comp1); + comp1:= comp1.owner; + end; + node2:= tdesigncompnameitem(result); + for int1:= high(ar1) downto 0 do begin + node3:= node2.findcomp(ar1[int1]); + if node3 = nil then begin + node3:= tdesigncompnameitem.create(ar1[int1],false); + node2.add(node3); + end; + node3.state:= node3.state - [ns_imagenrfix]; + node2:= node3; + end; + node2.add(node1); + end; + end; + for int3:= 0 to acomp.componentcount - 1 do begin + comp2:= acomp.components[int3]; + if (cssubcomponent in comp2.componentstyle) xor findmode{ and + not isnosubcomp(comp2)} then begin +// node1:= anode.findcomp(comp2); +// if node1 = nil then begin +// node1:= tdesigncompnameitem.create(comp2,false); +// end; + check(comp2); + end; + end; + end; + +var + int1,int2{,int3}: integer; + comp1{,comp2}: tcomponent; + po1: pmoduleinfoty; +begin + result:= tdesigncompnameitem.create(nil,false); + if amodule <> nil then begin + check(amodule); + end + else begin + for int1:= 0 to fmodules.count - 1 do begin + po1:= fmodules[int1]; + if findmode then begin + check(po1^.instance); + end + else begin + with po1^.components do begin + for int2:= 0 to count - 1 do begin + comp1:= next^.data.data.instance; + check(comp1); + end; + end; + end; + end; + end; + result.sort(false,true); +end; + +function tdesigner.getwidgetnametree(const rootwidget: twidget): tcompnameitem; + + procedure check(const aitem: tcompnameitem; awidget: twidget); + var + node1: tdesigncompnameitem; + i1: int32; + begin + if (awidget <> nil) and (ws_iswidget in awidget.widgetstate) then begin + node1:= tdesigncompnameitem.create(awidget,true); + node1.imagenr:= 4; + node1.state:= node1.state + [ns_imagenrfix]; + aitem.add(node1); + for i1:= 0 to high(twidget1(awidget).fwidgets) do begin + check(node1,twidget1(awidget).fwidgets[i1]); + end; + end + else begin + if awidget = nil then begin + awidget:= rootwidget; + end; + for i1:= 0 to high(twidget1(awidget).fwidgets) do begin + check(aitem,twidget1(awidget).fwidgets[i1]); + end; + end; + end; + +begin + result:= tdesigncompnameitem.create(nil,false); + check(result,nil); + result.sort(false,true); +end; + +function tdesigner.getmodules: tmodulelist; +begin + result:= fmodules; +end; + +function tdesigner.findcomponentmodule(const acomponent: tcomponent): pmoduleinfoty; +var + int1: integer; + po1: pmoduleinfoty; +begin + result:= nil; + for int1:= 0 to fmodules.count-1 do begin + po1:= fmodules[int1]; + if po1^.components.find(acomponent) <> nil then begin + result:= po1; + break; + end; + end; +end; + +procedure tdesigner.validaterename(const acomponent: tcomponent; + const curname,NewName: string); +var + po1: pmoduleinfoty; + ar1: objectarty; + int1: integer; + comp1: tcomponent; +begin + ar1:= nil; //compiler warning + if loadingdesigner = nil then begin + po1:= findcomponentmodule(acomponent); + if po1 <> nil then begin + if newname = '' then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_invalidcompname)])); + end; + if acomponent.name <> newname then begin + if stringicomp(acomponent.name,newname) <> 0 then begin + comp1:= acomponent.getparentcomponent; + if (comp1 <> nil) and (comp1.findcomponent(newname) <> nil) then begin + raise EComponentError.Createfmt(SDuplicateName,[newname]); + end; + end; + po1^.components.namechanged(acomponent,newname); + fdescendentinstancelist.componentnamechanged(po1,acomponent,newname); + + designnotifications.componentnamechanging(idesigner(self),po1^.instance, + acomponent,newname); + if acomponent is tmsecomponent then begin + ar1:= tmsecomponent(acomponent).linkedobjects; + end + else begin + ar1:= objectarty(getlinkedcomponents(acomponent)); + end; + end; + for int1:= 0 to high(ar1) do begin + if ar1[int1] is tcomponent then begin + componentmodified(tcomponent(ar1[int1])); + end; + end; + end; + end; +end; + +function tdesigner.getclassname(const comp: tcomponent): string; + //returns submoduleclass if appropriate +begin + result:= fdescendentinstancelist.getclassname(comp); +end; + +function tdesigner.getcomponenteditor: icomponenteditor; +begin + if fcomponenteditor = nil then begin + result:= nil; + end + else begin + result:= icomponenteditor(fcomponenteditor); + end; +end; + +function tdesigner.editcomponent(const aowner: tcomponent = nil): boolean; + //false if no editor available +begin + result:= componentcanedit and ((aowner = nil) or + (fcomponenteditor.component.owner = aowner)); + if result then begin + fcomponenteditor.edit; + end; +end; + +procedure tdesigner.savecanceled; +begin + fallsaved:= false; +end; + +function tdesigner.beforemake: boolean; +var + int1: integer; + page1: tsourcepage; +begin + result:= true; + for int1:= 0 to fmodules.count - 1 do begin + with fmodules.itempo[int1]^ do begin + if assigned(moduleintf^.sourcetoform) then begin + page1:= sourcefo.findsourcepage(replacefileext(filename,pasfileext),true,true); + if (page1 <> nil) then begin + moduleintf^.sourcetoform(instance,page1.source); + end; + end; + end; + end; +end; + +function tdesigner.selectedcomponents: componentarty; +begin + setlength(result,fselections.count); + move(fselections.datapo^,result[0],length(result)*sizeof(pointer)); +end; + +function tdesigner.clickedcomp: tcomponent; +begin + result:= nil; + if (factmodulepo <> nil) and (factmodulepo^.designformintf <> nil) then begin + result:= factmodulepo^.designformintf.clickedcomponent; + end; +end; + +{ +procedure tdesigner.doasyncevent(var atag: integer); +begin + if atag = showobjectinspectortag then begin + objectinspectorfo.activate; + end; +end; +} +{ tcomponentslink } + +procedure tcomponentslink.notification(acomponent: tcomponent; + operation: toperation); +begin + if operation = opremove then begin + fownercomps.destroynotification(acomponent); + end; + inherited; +end; + +{ tmethodnames } + +initialization + fdesigner:= tdesigner.create; +finalization + fdesigner.Free; +end. diff --git a/mseide-msegui/apps/ide/msedesignparser.pas b/mseide-msegui/apps/ide/msedesignparser.pas new file mode 100644 index 0000000..cec6261 --- /dev/null +++ b/mseide-msegui/apps/ide/msedesignparser.pas @@ -0,0 +1,2210 @@ +{ MSEide Copyright (c) 1999-2018 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msedesignparser; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$if FPC_FULLVERSION >= 030100} {$define mse_fpc_3_2} {$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseglob,msedatalist,mselist,mseparser,msetypes,typinfo,msestrings, + msearrayutils; + +type + idesignparser = interface(inullinterface) + end; +type + + sourceitemkindty = (sik_uses,sik_include{,sik_identuse}); + identuseflagty = (idu_first,idu_last); + identuseflagsty = set of identuseflagty; + + sourceitemty = record + filename: nameidty; + startoffset,endoffset: integer; + startpos,endpos: gridcoordty; + case kind: sourceitemkindty of + sik_uses: + (imp: boolean); + sik_include: + (index: integer); + { + sik_identuse: + (identuseflags: identuseflagsty); + } + end; + psourceitemty = ^sourceitemty; + sourceiteminfoaty = array[0..0] of sourceitemty; + psourceiteminfoaty = ^sourceiteminfoaty; + + browserlistitemty = record + index: integer; + end; + pbrowserlistitemty = ^browserlistitemty; + + tsourceitemlist = class(torderedrecordlist) + protected + function getcomparefunc: sortcomparemethodty; override; + function compare(const l,r): integer; + public + constructor create; + function newitem(const astart,aend: sourceposty; + akind: sourceitemkindty): psourceitemty; reintroduce; + procedure updateitem(var aitem: sourceitemty; const astart,aend: sourceposty; + akind: sourceitemkindty); + function find(const apos: sourceposty): psourceitemty; overload; + function find(const apos: sourceposty; + out aindex: integer): psourceitemty; overload; + end; + + tbrowserlist = class(trecordlist) + public + function newitem: pointer; override; + end; + + sourceiteminfoty = record + end; + + compinfoty = record + b: browserlistitemty; + name,uppername: string; + typename,uppertypename: string; + insertpos,namepos,nameend,typepos,typeend,endpos: sourceposty; + end; + pcompinfoty = ^compinfoty; + + tcomponentinfolist = class(tbrowserlist) + protected + function getitempo(const index: integer): pcompinfoty; + procedure finalizerecord(var item); override; + public + constructor create; + function finditembyname(const aname: string): pcompinfoty; + property items[const index: integer]: pcompinfoty read getitempo; default; + end; + + paraminfoty = record + flags: tparamflags; + name: string; + typename: string; + defaultvalue: string; + start,stop: sourceposty; + end; + paraminfoarty = array of paraminfoty; + + methodflagty = (mef_virtual,mef_abstract,mef_inherited,mef_override, + mef_reintroduce,mef_overload{,mef_inline}, + mef_brackets,mef_forward); + methodflagsty = set of methodflagty; + + methodkindty = (mk_none,mk_procedure,mk_procedurefunc,mk_function, + mk_method,mk_methodfunc, + mk_constructor,mk_destructor, + mk_classprocedure,mk_classfunction); + + methodparaminfoty = record + kind: methodkindty; + flags: methodflagsty; + params: paraminfoarty; //last is functionresult + end; + + tdeflist = class; + + procedureinfoty = record + b: browserlistitemty; + params: methodparaminfoty; + name,uppername: string; + intinsertpos,intstartpos,intendpos: sourceposty; + impheaderstartpos: sourceposty; + impheaderendpos: sourceposty; + impendpos: sourceposty; + managed: boolean; + classproc: boolean; + end; + pprocedureinfoty = ^procedureinfoty; + procedureinfoarty = array of procedureinfoty; + procedureinfopoarty = array of pprocedureinfoty; + + tprocedureinfolist = class(tbrowserlist) + private + protected + procedure finalizerecord(var item); override; + function getitempo(const index: integer): pprocedureinfoty; + public + constructor create; + function finditembyname(const aname: string): pprocedureinfoty; + function finditembyuppername(const aname: lstringty; + var info: methodparaminfoty; + const anyparam: boolean = false): pprocedureinfoty; + function matchmethod(const atype: ptypeinfo; + const amanaged: boolean): integerarty; + function matchedmethodnames(const atype: ptypeinfo; + const managed: boolean): msestringarty; + property items[const index: integer]: pprocedureinfoty read getitempo; default; + end; + + interfaceinfoty = record + b: browserlistitemty; + name,uppername: string; + end; + pinterfaceinfoty = ^interfaceinfoty; + + tinterfaceinfolist = class(tbrowserlist) + private + protected + procedure finalizerecord(var item); override; + function getitempo(const index: integer): pinterfaceinfoty; + public + constructor create; + function finditembyname(const aname: string): pinterfaceinfoty; + function finditembyuppername(const aname: lstringty): pinterfaceinfoty; + property items[const index: integer]: pinterfaceinfoty read getitempo; default; + end; + + classinfoty = record + b: browserlistitemty; + deflist: tdeflist; + name,uppername: string; + parentname: string; + componentlist: tcomponentinfolist; + procedurelist: tprocedureinfolist; + headerstop: sourceposty; + managedstart: sourceposty; + procedurestart: sourceposty; + //fileoffset of first line with methods, fileoffset of end of managed + //section if none + managedend: sourceposty; + privatestart: sourceposty; //start of first private segment + privatefieldend: sourceposty; + //before start of first procdef in first private segment + privateend: sourceposty; //end of first private segment + procimpstart,procimpend: sourceposty; + inimplementation: boolean; + end; + pclassinfoty = ^classinfoty; + classinfopoarty = array of pclassinfoty; + + tclassinfolist = class(tbrowserlist) + protected + procedure finalizerecord(var item); override; + procedure initializerecord(var item); override; + function getitempo(const index: integer): pclassinfoty; + public + constructor create; + property items[const index: integer]: pclassinfoty read getitempo; default; + function finditembyname(const aname: lstringty; const interfaceonly: boolean): pclassinfoty; overload; + function finditembyname(const aname: string; const interfaceonly: boolean): pclassinfoty; overload; + end; + + usesinfoty = record + b: browserlistitemty; + name,uppername: string; + end; + pusesinfoty = ^usesinfoty; + usesinfoaty = array[0..0] of usesinfoty; + pusesinfoaty = ^usesinfoaty; + + trootdeflist = class; + + tusesinfolist = class(tbrowserlist) + private + fimplementation: boolean; + function getunitnames(const index: integer): string; + protected + fstartpos,fendpos: sourceposty; + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + public + constructor create(aimplementation: boolean); + procedure clear; override; + property startpos: sourceposty read fstartpos; + property endpos: sourceposty read fendpos; + procedure add(const units: lstringarty); + procedure getsourceitems(const alist: tsourceitemlist); + function find(const aname: string): pusesinfoty; + function getunitdeflist(const index: integer): trootdeflist; overload; + function getunitdeflist(const aunitname: string): trootdeflist; overload; + property unitnames[const index: integer]: string read getunitnames; + end; + +// c parser + + functionheaderinfoty = record + b: browserlistitemty; + name: ansistring; + end; + pfunctionheaderinfoty = ^functionheaderinfoty; + + functioninfoty = record +// b: browserlistitemty; + name: ansistring; + start,stop: sourceposty; + end; + pfunctioninfoty = ^functioninfoty; + + identuseinfoty = record + b: browserlistitemty; + startpos: sourceposty; + length: integer; + flags: identuseflagsty; + scope: tdeflist; + end; + pidentuseinfoty = ^identuseinfoty; + identuseinfoaty = array[0..0] of identuseinfoty; + pidentuseinfoaty = ^identuseinfoaty; + + sourcefileinfoty = record + filename: filenamety; + startline,count,includecount: integer; + end; + sourcefileinfoarty = array of sourcefileinfoty; + + includestatementty = record + startpos,endpos: sourceposty; + filename: filenamety; + end; + symbolkindty = (syk_none,syk_nopars,syk_substr,syk_deleted,syk_root,syk_classdef, + syk_procdef,syk_procimp,syk_classprocimp, + syk_vardef,syk_pardef, + syk_constdef,syk_typedef,syk_interfacedef,syk_identuse); + defnamety = record + name: string; + id: nameidty; + end; + pdefnamety = ^defnamety; + defnameaty = array[0..0] of defnamety; + pdefnameaty = ^defnameaty; + + identflagty = (if_first,if_last); + identflagsty = set of identflagty; + varflagty = (vf_property); + varflagsty = set of varflagty; + + symbolflagty = (syf_global); + symbolflagsty = set of symbolflagty; + + definfoty = record + name: string; //'' -> statment + pos,stop1: sourceposty; + owner: tdeflist; + deflist: tdeflist; //can be nil + symbolflags: symbolflagsty; + case kind: symbolkindty of + syk_classdef: (classindex: integer); + syk_procdef,syk_classprocimp,syk_procimp: (procindex: integer); + syk_identuse: (identlen: integer; identflags: identflagsty); + syk_vardef: (varflags: varflagsty); + end; + pdefinfoty = ^definfoty; + definfoarty = array of definfoty; + definfopoarty = array of pdefinfoty; + + defsearchlevelty = (dsl_normal,dsl_qualified,dsl_child,dsl_parent, + dsl_parentclass,dsl_inclass,dsl_unitsearch); + deflistarty = array of tdeflist; + + tdeflist = class(torderedrecordlist) + private + fparent: tdeflist; + fparentid: nameidty; + fparentident: string; + fparentunitindex: integer; + finfocount: integer; + fstart,fstop: sourceposty; + fkind: symbolkindty; + fcasesensitive: boolean; + function comp(const l,r): integer; + function compnopars(const l,r): integer; + function compsubstr(const l,r): integer; + function getname: string; virtual; + function getdefinfopo: pdefinfoty; + function getrootlist: trootdeflist; + function incinfocount: integer; + function internalfinditem(const apos: sourceposty; const firstidentuse,last: boolean; + out scope: tdeflist): pdefinfoty; + protected + finfos: definfoarty; + fparentscope: tdeflist; //class definition + procedure finalizerecord(var item); override; + function getcomparefunc: sortcomparemethodty; override; + function add(const aname: string; const akind: symbolkindty; + const apos,astop: sourceposty): pdefinfoty; overload; + function add(const akind: symbolkindty; const apos,astop: sourceposty): pdefinfoty; overload; + //statment + public + constructor create(const akind: symbolkindty; const acasesensitive: boolean); + procedure clear; override; + procedure startident(const aparser: tparser); overload; + procedure startident(const apos: sourceposty; const alen: integer); overload; + procedure addident(const aparser: tparser); overload; + procedure addident(const apos: sourceposty; const alen: integer); overload; + procedure addemptyident(const aparser: tparser); + procedure endident(const aparser: tparser); overload; + procedure endident(const aparser: tparser; const endpos: sourceposty); overload; + function addidentpath(const aparser: tparser; + const aseparator: char): boolean; + function addidents(const aparser: tparser; + const aseparator: char; const apathseparator: char): boolean; + + function find(const aname: string; + const akind: symbolkindty = syk_none): pdefinfoty; + function getmatchingitems(const aname: string; + const akind: symbolkindty = syk_none): definfopoarty; + function finddef(const anamepath: stringarty; var scopes: deflistarty; + var defs: definfopoarty; + const first: boolean; // break if first found + const level: defsearchlevelty; + const afindkind: symbolkindty = syk_none; + const maxcount: integer = bigint): boolean; overload; virtual; + //true if found + function finddef(const aname: string; const afindkind: symbolkindty; + out ascope: tdeflist): pdefinfoty; overload; + function finditem(const apos: sourceposty; const firstidentuse: boolean; + out scope: tdeflist): pdefinfoty; + function rootnamepath: string; + property parent: tdeflist read fparent; + property parentid: nameidty read fparentid; + property parentscope: tdeflist read fparent; + property kind: symbolkindty read fkind; + property name: string read getname; + property definfopo: pdefinfoty read getdefinfopo; + property rootlist: trootdeflist read getrootlist; + property infos: definfoarty read finfos; + property infocount: integer read finfocount; + end; + + includestatementarty = array of includestatementty; + + proglangty = (pl_pascal,pl_c); + + tfunctionheaders = class; + tfunctions = class; + + cunitinfoty = record + functionheaders: tfunctionheaders; + functions: tfunctions; + end; + + pascalunitinfoty = record + procedurelist: tprocedureinfolist; + interfacelist: tinterfaceinfolist; + classinfolist: tclassinfolist; + interfaceuses,implementationuses: tusesinfolist; + implementationstart: sourceposty; + implementationbodystart: sourceposty; + implementationend: sourceposty; + initializationstart: sourceposty; + finalizationstart: sourceposty; + end; + + unitinfoty = record + interfacecompiled: boolean; + implementationcompiled: boolean; + isprogram: boolean; + itemlist: tsourceitemlist; + deflist: trootdeflist; + sourcefilename: filenamety; + unitname: string; //uppercase + origunitname: string; + formfilename: filenamety; + unitend: sourceposty; + sourceend: sourceposty; + sourcefiles: sourcefileinfoarty; + includestatements: includestatementarty; + case proglang: proglangty of + pl_pascal: + (p: pascalunitinfoty); + pl_c: + (c: cunitinfoty); + end; + punitinfoty = ^unitinfoty; + unitinfopoarty = array of punitinfoty; + + trootdeflist = class(tdeflist) + private + factnode: tdeflist; + funitinfopo: punitinfoty; + flastunitindex: integer; + protected + function getname: string; override; + public + allreadysearched: boolean; + constructor create(const aunitinfopo: punitinfoty); + procedure clear; override; + procedure endnode(const apos: sourceposty); + function beginnode(const aname: string; const akind: symbolkindty; + const apos,astop: sourceposty): pdefinfoty; overload; + function beginnode(const apos: sourceposty; + const aclassinfo: pclassinfoty): tdeflist; overload; + function add(const aname: string; const akind: symbolkindty; + const astart,astop: sourceposty): pdefinfoty; overload; + function add(const apos,astop: sourceposty; + const aprocinfo: pprocedureinfoty): pdefinfoty; overload; + function add(const apos,astop: sourceposty; + const afunctioninfo: pfunctioninfoty): pdefinfoty; overload; + function add(const apos,astop: sourceposty; + const afunctionheaderinfo: pfunctionheaderinfoty): pdefinfoty; overload; + procedure deletenode; + function finddef(const anamepath: stringarty; var scopes: deflistarty; + var defs: definfopoarty; + const first: boolean; // break on first found + const level: defsearchlevelty; + const afindkind: symbolkindty = syk_none; + const maxcount: integer = bigint): boolean; override; + //true if found + function findparentclass(const adescendent: tdeflist; + var defs: definfopoarty): boolean; + + property unitinfopo: punitinfoty read funitinfopo; + property actnode: tdeflist read factnode; + end; + + tfunctionheaders = class(tbrowserlist) + private + function getitempo(const index: integer): pfunctionheaderinfoty; + protected + procedure finalizerecord(var item); override; + public + constructor create; + property items[const index: integer]: pfunctionheaderinfoty + read getitempo; default; + end; + + tfunctions = class(torderedrecordlist) + private + function getitempo(const index: integer): pfunctioninfoty; + function comp(const left,right): integer; + protected + procedure finalizerecord(var item); override; + function getcomparefunc: sortcomparemethodty; override; + public + constructor create; + procedure add(const aname: ansistring; const astart,astop: sourceposty); + function find(const name: ansistring): pfunctioninfoty; + property items[const index: integer]: pfunctioninfoty + read getitempo; default; + end; + + tunitinfo = class + public + info: unitinfoty; + constructor create; + destructor destroy; override; + function infopo: punitinfoty; + end; + + tpascalunitinfo = class(tunitinfo) + public + constructor create; + destructor destroy; override; + end; + +function parametersmatch(const a: ptypeinfo; const b: methodparaminfoty): boolean; +procedure getmethodparaminfo(const atype: ptypeinfo; var info: methodparaminfoty); +function splitidentpath(const atext: string): stringarty; +function mangleprocparams(const aparams: methodparaminfoty): string; +procedure initcompinfo(var info: unitinfoty); +procedure afterparse(const sender: tparser; var unitinfo: unitinfoty; + const aimplementationcompiled: boolean); +function addincludefile(var info: unitinfoty; const afilename: filenamety; + const astatementstart, astatementend: sourceposty): integer; + //returns index + +var + updateunitinterface: function(const unitname: string): punitinfoty of object; + gettype: function (const adef: pdefinfoty): stringarty of object; + resetunitsearched: procedure of object; + +implementation +uses + {sourceupdate,}sysutils,cdesignparser; + //todo: remove cdesignparser, extract c+pascaldesignparser code +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +{$ifdef FPC}{$goto on}{$endif} +type + tparser1 = class(tparser); + +function addincludefile(var info: unitinfoty; const afilename: filenamety; + const astatementstart, astatementend: sourceposty): integer; +begin + with info do begin + result:= length(includestatements); + setlength(includestatements,result+1); + with includestatements[high(includestatements)] do begin + filename:= afilename; + startpos:= astatementstart; + endpos:= astatementend; + end; + end; +end; + +procedure initcompinfo(var info: unitinfoty); +begin + with info do begin + case proglang of + pl_pascal: begin + p.procedurelist.clear; + p.interfacelist.clear; + p.classinfolist.clear; + p.interfaceuses.clear; + p.implementationuses.clear; + p.implementationstart.filenum:= 0; + p.implementationend.filenum:= 0; + p.initializationstart.filenum:= 0; + p.finalizationstart.filenum:= 0; + end; + pl_c: begin + c.functionheaders.clear; + c.functions.clear; + end; + end; + interfacecompiled:= false; + implementationcompiled:= false; + isprogram:= false; + freeandnil(itemlist); + deflist.clear; + unitname:= ''; + origunitname:= ''; + unitend.filenum:= 0; + sourceend.filenum:= 0; + sourcefiles:= nil; + includestatements:= nil; + end; +end; + +procedure afterparse(const sender: tparser; var unitinfo: unitinfoty; + const aimplementationcompiled: boolean); +var + int1: integer; +begin + with tparser1(sender),unitinfo do begin + interfacecompiled:= true; + implementationcompiled:= aimplementationcompiled; + sourceend:= sourcepos; + setlength(sourcefiles,length(fscanners)); + for int1:= 0 to high(fscanners) do begin + sourcefiles[int1].filename:= fscanners[int1].filename; + sourcefiles[int1].startline:= fscanners[int1].startline; + sourcefiles[int1].count:= fscanners[int1].count; + sourcefiles[int1].includecount:= fscanners[int1].includecount; + end; + end; +end; + +function parametersmatch1(const a,b: methodparaminfoty): boolean; +var + int1: integer; +begin + result:= (a.kind = b.kind) and (high(a.params) = high(b.params)); + if result then begin + for int1:= 0 to high(a.params) do begin + with a.params[int1] do begin + if (flags*[pfvar,pfconst,pfout,pfarray] <> + b.params[int1].flags*[pfvar,pfconst,pfout,pfarray]) or + (stringicomp(typename,b.params[int1].typename) <> 0) then begin + result:= false; + break; + end; + end; + end; + end; +end; + +const + tmethodkindtomethodkind: array[tmethodkind] of methodkindty = ( + //mkProcedure, mkFunction, mkConstructor, mkDestructor, + mk_procedure,mk_function,mk_constructor,mk_destructor, + //mkClassProcedure, mkClassFunction, mkClassConstructor, + mk_classprocedure,mk_classfunction,mk_none, + //mkClassDestructor,mkOperatorOverload + mk_none, mk_none + ); + +procedure getmethodparaminfo(const atype: ptypeinfo; + var info: methodparaminfoty); + + function getshortstring(var po: pchar): string; + begin + setlength(result,byte(po^)); + inc(po); + move(po^,pointer(result)^,length(result)); + inc(po,length(result)); + end; + +type + pparamflags = ^tparamflags; + paramrecty = record + Flags : TParamFlags; +// ParamName : ShortString; + end; +var + isfunction: boolean; + int1: integer; + po1: pchar; +begin + with info do begin + kind:= methodkindty(-1); + params:= nil; + if atype^.Kind = tkmethod then begin + with gettypedata(atype)^ do begin + kind:= tmethodkindtomethodkind[methodkind]; + int1:= paramcount; + isfunction:= methodkind = mkfunction; + if isfunction then begin + inc(int1); + end; + if isfunction or (methodkind = mkprocedure) then begin + setlength(params,int1); + po1:= @paramlist; + for int1:= 0 to paramcount - 1 do begin + with params[int1] do begin + flags:= tparamflags( + {$ifdef mse_fpc_3_2}wordset{$else}byteset{$endif}(pbyte(po1)^)); + inc(po1,{$ifdef mse_fpc_3_2}2{$else}1{$endif}); +// inc(po1,sizeof(paramrecty)); +// inc(po1,sizeof(tparamflags)); +// inc(po1,sizeof(byteset)); + name:= getshortstring(po1); + typename:= getshortstring(po1); + if (typename = 'WideString') or (typename = 'UnicodeString') then begin + typename:= 'msestring'; + end + else begin + if typename = 'LongInt' then begin + typename:= 'Integer'; + end + else begin + if typename = 'Double' then begin + typename:= 'Real'; + end; + end; + end; + end; + end; + if isfunction then begin + params[high(params)].typename:= getshortstring(po1); + end; + end; + end; + end; + end; +end; + +function parametersmatch(const a: ptypeinfo; const b: methodparaminfoty): boolean; +var + a1: methodparaminfoty; +begin + getmethodparaminfo(a,a1); + result:= parametersmatch1(a1,b); +end; + +function splitidentpath(const atext: string): stringarty; +begin + result:= nil; + splitstring(atext,result,'.',true); +end; + +function mangleprocparams(const aparams: methodparaminfoty): string; +var + int1: integer; +begin + with aparams do begin + result:= ''; + for int1:= 0 to high(params) do begin + result:= result + '$' + params[int1].typename; + end; + if kind in [mk_function,mk_classfunction, + mk_procedurefunc,mk_methodfunc] then begin + result:= result+'$'; + end; + end; +end; + +{ tsourceitemlist } + +constructor tsourceitemlist.create; +begin + inherited create(sizeof(sourceitemty)); +end; + +function tsourceitemlist.compare(const l,r): integer; +begin + result:= sourceitemty(l).startpos.row - sourceitemty(r).startpos.row; + if result = 0 then begin + result:= sourceitemty(l).startpos.col - sourceitemty(r).startpos.col; + end; +end; + +function tsourceitemlist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}compare; +end; + +function tsourceitemlist.find(const apos: sourceposty; out aindex: integer): psourceitemty; +var + aitem: sourceitemty; +begin + aitem.startpos.col:= apos.pos.col; + aitem.startpos.row:= apos.line; + if not internalfind(aitem,aindex) then begin + dec(aindex); + end; + if aindex >= 0 then begin + result:= @psourceiteminfoaty(datapo)^[aindex]; + with result^ do begin + if (endpos.row < apos.line) or + (endpos.row = apos.line) and (endpos.col <= apos.pos.col) then begin + result:= nil; + aindex:= -1; + end; + end; + end + else begin + result:= nil; + end; +end; + +function tsourceitemlist.find(const apos: sourceposty): psourceitemty; +var + int1: integer; +begin + result:= find(apos,int1); +end; + +{ +function tsourceitemlist.newitem(const afilename: nameidty; + const startcol,startrow,endcol,endrow: integer; + akind: sourceitemkindty): psourceitemty; +begin + result:= inherited newitem; + with result^ do begin + filename:= afilename; + startpos.col:= startcol; + startpos.row:= startrow; + endpos.row:= endrow; + endpos.col:= endcol; + kind:= akind; + end; +end; +} + +procedure tsourceitemlist.updateitem(var aitem: sourceitemty; + const astart,aend: sourceposty; akind: sourceitemkindty); +begin + with aitem do begin + filename:= astart.filename; + startpos.col:= astart.pos.col; + startpos.row:= astart.line; + startoffset:= astart.offset; + endpos.col:= aend.pos.col; + endpos.row:= aend.line; + endoffset:= aend.offset; + kind:= akind; + end; +end; + +function tsourceitemlist.newitem(const astart,aend: sourceposty; + akind: sourceitemkindty): psourceitemty; +begin + result:= inherited newitem; + updateitem(result^,astart,aend,akind); +end; + +{ tbrowserlist } + +function tbrowserlist.newitem: pointer; +begin + result:= inherited newitem; + pbrowserlistitemty(result)^.index:= count - 1; +end; + +{ tusesinfolist } + +constructor tusesinfolist.create(aimplementation: boolean); +begin + fimplementation:= aimplementation; + inherited create(sizeof(usesinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +procedure tusesinfolist.clear; +begin + inherited; + if not fimplementation then begin + count:= 1; + with pusesinfoty(fdata)^ do begin + name:= 'system'; + uppername:= 'SYSTEM'; + end; + end; +end; + +procedure tusesinfolist.add(const units: lstringarty); +var + int1: integer; + po1: pusesinfoty; +begin + if high(units) >= 0 then begin + int1:= count; + count:= count + length(units); + po1:= getitempo(int1); + for int1:= 0 to high(units) do begin + with po1^ do begin + name:= lstringtostring(units[int1]); + uppername:= struppercase(name); + end; + inc(po1); + end; + end; +end; + +procedure tusesinfolist.getsourceitems(const alist: tsourceitemlist); +var + po1: psourceitemty; +begin + po1:= alist.newitem(fstartpos,fendpos,sik_uses); + with po1^ do begin + imp:= fimplementation; + end; +end; + +procedure tusesinfolist.finalizerecord(var item); +begin + finalize(usesinfoty(item)); +end; + +procedure tusesinfolist.copyrecord(var item); +begin + with usesinfoty(item) do begin + stringaddref(name); + stringaddref(uppername); + end; +end; + +function tusesinfolist.find(const aname: string): pusesinfoty; +var + po1: pusesinfoty; + int1: integer; + str1: string; +begin + result:= nil; + po1:= datapo; + str1:= struppercase(aname); + for int1:= 0 to count - 1 do begin + if str1 = po1^.uppername then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +function tusesinfolist.getunitdeflist(const index: integer): trootdeflist; +var + po2: punitinfoty; +begin + po2:= {sourceupdater.}updateunitinterface(unitnames[index]); + if po2 <> nil then begin + result:= po2^.deflist; + end + else begin + result:= nil; + end; +end; + +function tusesinfolist.getunitdeflist(const aunitname: string): trootdeflist; +var + po1: pusesinfoty; + po2: punitinfoty; +begin + result:= nil; + po1:= find(aunitname); + if po1 <> nil then begin + po2:= {sourceupdater.}updateunitinterface(aunitname); + if po2 <> nil then begin + result:= po2^.deflist; + end; + end; +end; + +function tusesinfolist.getunitnames(const index: integer): string; +begin + result:= pusesinfoty(getitempo(index))^.name; +end; + +{ tcomponentinfolist } + +constructor tcomponentinfolist.create; +begin + inherited create(sizeof(compinfoty),[rels_needsfinalize]); +end; + +procedure tcomponentinfolist.finalizerecord(var item); +begin + finalize(compinfoty(item)); +end; + +function tcomponentinfolist.getitempo(const index: integer): pcompinfoty; +begin + result:= pcompinfoty(inherited getitempo(index)); +end; + +function tcomponentinfolist.finditembyname(const aname: string): pcompinfoty; +var + po1: pcompinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if stringicompupper(aname,po1^.uppername) = 0 then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +{ tprocedureinfolist } + +constructor tprocedureinfolist.create; +begin + inherited create(sizeof(procedureinfoty),[rels_needsfinalize]); +end; + +procedure tprocedureinfolist.finalizerecord(var item); +begin + finalize(procedureinfoty(item)); +end; + +function tprocedureinfolist.getitempo( + const index: integer): pprocedureinfoty; +begin + result:= pprocedureinfoty(inherited getitempo(index)); +end; + +function tprocedureinfolist.finditembyname(const aname: string): pprocedureinfoty; +var + po1: pprocedureinfoty; + int1: integer; + str1: string; +begin + result:= nil; + po1:= datapo; + str1:= struppercase(aname); + for int1:= 0 to fcount - 1 do begin + if str1 = po1^.uppername then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +function tprocedureinfolist.finditembyuppername(const aname: lstringty; + var info: methodparaminfoty; + const anyparam: boolean): pprocedureinfoty; +var + po1: pprocedureinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if (po1^.params.kind = info.kind) and + (lstringcomp(aname,po1^.uppername) = 0) and + parametersmatch1(info,po1^.params) then begin + result:= po1; + break; + end; + inc(po1); + end; + if (result = nil) and anyparam then begin + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if (po1^.params.kind = info.kind) and + (lstringcomp(aname,po1^.uppername) = 0) then begin + result:= po1; + info:= po1^.params; + break; + end; + inc(po1); + end; + end; +end; + +function tprocedureinfolist.matchmethod(const atype: ptypeinfo; + const amanaged: boolean): integerarty; +var + info: methodparaminfoty; + int1: integer; + po1: pprocedureinfoty; +begin + result:= nil; + getmethodparaminfo(atype,info); + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + with po1^ do begin + if parametersmatch1(params,info) and (not amanaged or managed) then begin + additem(result,int1); + end; + end; + inc(po1); + end; +end; + +function tprocedureinfolist.matchedmethodnames(const atype: ptypeinfo; + const managed: boolean): msestringarty; +var + ar1: integerarty; + int1: integer; +begin + ar1:= matchmethod(atype,managed); + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= msestring(getitempo(ar1[int1])^.name); + end; +end; + +{ tinterfaceinfolist } + +constructor tinterfaceinfolist.create; +begin + inherited create(sizeof(interfaceinfoty),[rels_needsfinalize]); +end; + +procedure tinterfaceinfolist.finalizerecord(var item); +begin + finalize(interfaceinfoty(item)); +end; + +function tinterfaceinfolist.getitempo( + const index: integer): pinterfaceinfoty; +begin + result:= pinterfaceinfoty(inherited getitempo(index)); +end; + +function tinterfaceinfolist.finditembyname(const aname: string): pinterfaceinfoty; +var + po1: pinterfaceinfoty; + int1: integer; + str1: string; +begin + result:= nil; + po1:= datapo; + str1:= struppercase(aname); + for int1:= 0 to fcount - 1 do begin + if str1 = po1^.uppername then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +function tinterfaceinfolist.finditembyuppername( + const aname: lstringty): pinterfaceinfoty; +var + po1: pinterfaceinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if lstringcomp(aname,po1^.uppername) = 0 then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +{ tclassinfolist } + +constructor tclassinfolist.create; +begin + inherited create(sizeof(classinfoty),[rels_needsfinalize,rels_needsinitialize]); +end; + +procedure tclassinfolist.initializerecord(var item); +begin + with classinfoty(item) do begin + componentlist:= tcomponentinfolist.create; + procedurelist:= tprocedureinfolist.create; + end; +end; + +procedure tclassinfolist.finalizerecord(var item); +begin + with classinfoty(item) do begin + componentlist.free; + procedurelist.free; + end; + finalize(classinfoty(item)); +end; + +function tclassinfolist.getitempo(const index: integer): pclassinfoty; +begin + result:= pclassinfoty(inherited getitempo(index)); +end; + +function tclassinfolist.finditembyname(const aname: lstringty; const interfaceonly: boolean): pclassinfoty; +var + po1: pclassinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if lstringicompupper(aname,po1^.uppername) = 0 then begin + if not interfaceonly or not po1^.inimplementation then begin + result:= po1; + end; + break; + end; + inc(po1); + end; +end; + +function tclassinfolist.finditembyname(const aname: string; const interfaceonly: boolean): pclassinfoty; +begin + result:= finditembyname(stringtolstring(aname),interfaceonly); +end; + +{ tidentuselist} +{ +constructor tidentuselist.create; +begin + inherited create(sizeof(identuseinfoty)); +end; + +function tidentuselist.add(const info: identuseinfoty): integer; +begin + result:= inherited add(info); +end; + +procedure tidentuselist.getsourceitems(const alist: tsourceitemlist); +var + po1: psourceitemty; + po2: pidentuseinfoty; + int1: integer; + pos1: sourceposty; +begin + po1:= alist.newitems(count); + po2:= datapo; + for int1:= 0 to count - 1 do begin + pos1:= po2^.startpos; + inc(pos1.offset,po2^.length); + inc(pos1.pos.col,po2^.length); + alist.updateitem(po1^,po2^.startpos,pos1,sik_identuse); + po1^.identuseflags:= po2^.flags; + inc(po1); + inc(po2); + end; +end; +} +{ tdeflist } + +constructor tdeflist.create(const akind: symbolkindty; + const acasesensitive: boolean); +begin + fcasesensitive:= acasesensitive; + fkind:= akind; + inherited create(sizeof(defnamety),[rels_needsfinalize]); +end; + +procedure tdeflist.clear; +begin + inherited; + finfocount:= 0; + finfos:= nil; +end; + +function tdeflist.incinfocount: integer; +begin + result:= finfocount; + inc(finfocount); + if length(finfos) < finfocount then begin + setlength(finfos,finfocount + 4 + finfocount div 4); + end; +end; + +function tdeflist.add(const aname: string; const akind: symbolkindty; + const apos,astop: sourceposty): pdefinfoty; +var + po1: pdefnamety; +begin + po1:= newitem; + if fcasesensitive then begin + po1^.name:= aname; + end + else begin + po1^.name:= struppercase(aname); + end; + po1^.id:= incinfocount; + result:= @finfos[po1^.id]; + with result^ do begin + owner:= self; + name:= aname; + kind:= akind; + pos:= apos; + stop1:= astop; + end; +end; + +function tdeflist.add(const akind: symbolkindty; const apos,astop: sourceposty): pdefinfoty; + //statment +var + int1: integer; +begin + int1:= incinfocount; + result:= @finfos[int1]; + with result^ do begin + owner:= self; + kind:= akind; + pos:= apos; + stop1:= astop; + end; +end; + +procedure tdeflist.startident(const aparser: tparser); +begin + with add(syk_identuse,aparser.sourcepos,emptysourcepos)^ do begin + identflags:= [if_first]; + identlen:= aparser.token^.value.len; + stop1:= pos; + inc(stop1.pos.col,identlen); + end; + aparser.nexttoken; +end; + +procedure tdeflist.startident(const apos: sourceposty; const alen: integer); +begin + with add(syk_identuse,apos,emptysourcepos)^ do begin + identflags:= [if_first]; + identlen:= alen; + stop1:= pos; + inc(stop1.pos.col,alen); + end; +end; + +procedure tdeflist.addident(const aparser: tparser); +begin + with add(syk_identuse,aparser.sourcepos,emptysourcepos)^ do begin + identlen:= aparser.token^.value.len; + stop1:= pos; + inc(stop1.pos.col,identlen); + end; + aparser.nexttoken +end; + +procedure tdeflist.addident(const apos: sourceposty; const alen: integer); +begin + with add(syk_identuse,apos,emptysourcepos)^ do begin + identlen:= alen; + stop1:= pos; + inc(stop1.pos.col,identlen); + end; +end; + +procedure tdeflist.addemptyident(const aparser: tparser); +begin + aparser.lasttoken; + with add(syk_identuse,aparser.sourcepos,emptysourcepos)^ do begin + aparser.nexttoken; + stop1:= aparser.sourcepos; + end; +end; + +procedure tdeflist.endident(const aparser: tparser); +begin + with finfos[finfocount-1] do begin + include(finfos[finfocount-1].identflags,if_last); + stop1:= aparser.sourcepos; + end; +end; + +procedure tdeflist.endident(const aparser: tparser; const endpos: sourceposty); +begin + with finfos[finfocount-1] do begin + include(identflags,if_last); + stop1:= endpos; + end; +end; + +function tdeflist.addidentpath(const aparser: tparser; + const aseparator: char): boolean; +var + ident1: integer; +begin + with aparser do begin + ident1:= getident; + if (token^.kind = tk_name) and (ident1 < 0) then begin + startident(aparser); + while checkoperator(aseparator) do begin + ident1:= getident; + if (token^.kind = tk_name) and (ident1 < 0) then begin + addident(aparser); + end + else begin + break; + end; + end; + endident(aparser); + result:= true; + end + else begin + result:= false; + end; + end; +end; + +function tdeflist.addidents(const aparser: tparser; + const aseparator: char; const apathseparator: char): boolean; +//var +// ident1: integer; +begin + repeat + result:= addidentpath(aparser,apathseparator); + until not result or not aparser.checkoperator(aseparator); +{ + result:= true; + with aparser do begin + repeat + ident1:= getident; + if (token^.kind = tk_name) and (ident1 < 0) then begin + startident(aparser); + endident(aparser); + end + else begin + result:= false; + break; + end; + until not checkoperator(aseparator); + end; +} +end; + +function tdeflist.finddef(const anamepath: stringarty; var scopes: deflistarty; + var defs: definfopoarty; + const first: boolean; // break on first found + const level: defsearchlevelty; + const afindkind: symbolkindty = syk_none; + const maxcount: integer = bigint): boolean; + //true if found +var + ar1: stringarty; + ar3: definfopoarty; + findkind1: symbolkindty; +// po1: pdefinfoty; + ar4: definfopoarty; + int1: integer; + +begin + result:= false; + if first then begin + scopes:= nil; + defs:= nil; + end; + if high(anamepath) >= 0 then begin + setlength(ar4,1); + if high(anamepath) > 0 then begin + findkind1:= syk_none; + ar4[0]:= find(anamepath[0],findkind1); + if ar4[0] = nil then begin + ar4[0]:= find(anamepath[0],syk_nopars); + end; + end + else begin + findkind1:= afindkind; + if first then begin + ar4[0]:= find(anamepath[0],findkind1); + end + else begin + ar4:= getmatchingitems(anamepath[0],findkind1); + additem(pointerarty(ar4),nil); + end; + end; + for int1:= 0 to high(ar4) do begin + if (ar4[int1] = nil) and (fkind = syk_classdef) and + (name <> 'TOBJECT') then begin + //search parent class +// setlength(ar1,1); +// ar1[0]:= fparentident; +// if rootlist.finddef(ar1,ar2,ar3,true,dsl_parentclass,syk_classdef) and +// (ar3[0]^.kind = syk_classdef) then begin + if rootlist.findparentclass(self,ar3) and (ar3[0]^.kind = syk_classdef) then begin + if ar3[0]^.deflist.finddef(anamepath,scopes,defs,first,dsl_inclass, + afindkind,maxcount) then begin + result:= true; + if first then begin + continue; + end; + end; + end; + end; + if ar4[int1] = nil then begin + if (level in [dsl_normal,dsl_parent]) and (fparentscope <> nil) then begin + result:= fparentscope.finddef(anamepath,scopes,defs,first,dsl_parent, + afindkind,maxcount) or result; + end; +// if (not result or not first) and (level = dsl_normal) and +// (fkind in [syk_procimp1,syk_classprocimp]) then begin +// result:= rootlist.finddef(anamepath,scopes,defs,first,level,afindkind) or result; +// end; + if first then begin + continue; + end; + end + else begin + if (ar4[int1]^.kind in [syk_vardef,syk_procdef,syk_procimp]) and (high(anamepath) > 0) then begin + ar1:= {sourceupdater.}gettype(ar4[int1]); + stackarray(copy(anamepath,1,bigint),ar1); + {sourceupdater.}resetunitsearched; + result:= finddef(ar1,scopes,defs,first,dsl_normal,afindkind,maxcount) or result; + continue; + end + else begin + if high(anamepath) > 0 then begin + if ar4[int1]^.deflist <> nil then begin + result:= ar4[int1]^.deflist.finddef(copy(anamepath,1,bigint), + scopes,defs,first,dsl_child,afindkind,maxcount) or result; + end; + end + else begin + result:= true; + if high(defs) <= maxcount then begin + additem(pointerarty(scopes),self); + additem(pointerarty(defs),ar4[int1]); + end + else begin + break; + end; + end; + end; + end; + end; + end; +end; + +function tdeflist.finddef(const aname: string; const afindkind: symbolkindty; + out ascope: tdeflist): pdefinfoty; +var + scopes: deflistarty; + defs: definfopoarty; +begin + if finddef(splitidentpath(aname),scopes,defs,true, + dsl_normal,afindkind) then begin + ascope:= scopes[0]; + result:= defs[0]; + end + else begin + result:= nil; + end; +end; + +function isinrange(const apos: sourceposty; const start: sourceposty; + const stop: sourceposty): boolean; +begin + result:= not((apos.pos.row < start.pos.row) or + (apos.pos.row > stop.pos.row) or + (apos.pos.row = start.pos.row) and + (apos.pos.col < start.pos.col) or + (apos.pos.row = stop.pos.row) and + (apos.pos.col > stop.pos.col) + ); +end; + +function tdeflist.internalfinditem(const apos: sourceposty; + const firstidentuse,last: boolean; out scope: tdeflist): pdefinfoty; +var + int1,int2,lastmatching: integer; +begin + lastmatching:= -1; + if firstidentuse and last then begin + int2:= -1; + for int1:= 0 to finfocount - 1 do begin + with finfos[int1] do begin + if (kind = syk_identuse) and ((stop1.line > apos.line) or + (stop1.line = apos.line) and (stop1.pos.col > apos.pos.col)) then begin + int2:= int1; + break; + end; + end; + end; + end + else begin + int2:= finfocount; + for int1:= 0 to finfocount - 1 do begin + with finfos[int1] do begin + if (kind > syk_deleted) then begin + if isinrange(apos,pos,stop1) then begin + lastmatching:= int1; + end; + if (pos.line > apos.line) or + ((pos.line = apos.line) and (pos.pos.col > apos.pos.col)) then begin + int2:= int1; + if (kind = syk_identuse) and not (if_first in identflags) then begin + with finfos[int1-1] do begin + if (apos.line > pos.line) or (apos.pos.col > pos.pos.col + identlen) then begin + inc(int2); //before next word + end; + end; + end; + break; + end; + end; + end; + end; + dec(int2); + while (int2 >= 0) and (finfos[int2].kind <= syk_deleted) do begin + dec(int2); + end; + end; + if int2 >= 0 then begin + with finfos[int2] do begin + case kind of + syk_vardef,syk_constdef: begin + if (stop1.line < apos.line) or (stop1.line = apos.line) and + (stop1.pos.col <= apos.pos.col) then begin + int2:= lastmatching; + end; + end; + syk_identuse: begin + if (if_last in identflags) and + ((stop1.line < apos.line) or + (stop1.line = apos.line) and + (stop1.pos.col <= apos.pos.col)) then begin + int2:= lastmatching; + end; + end; + else begin + if (deflist <> nil) and + ((deflist.fstop.line < apos.line) or (deflist.fstop.line = apos.line) and + (deflist.fstop.pos.col <= apos.pos.col)) then begin + int2:= lastmatching; + end; + end; + end; + end; + end; + if int2 >= 0 then begin + if finfos[int2].deflist <> nil then begin + result:= finfos[int2].deflist.internalfinditem(apos,firstidentuse,false,scope); + end + else begin + if firstidentuse and not last then begin + result:= internalfinditem(apos,firstidentuse,true,scope); + end + else begin + scope:= self; + result:= @finfos[int2]; + end; + end; + end + else begin + if fparent <> nil then begin + scope:= fparentscope; + result:= @fparent.finfos[fparentid]; + end + else begin + scope:= self; + result:= nil; + end; + end; +end; + +function tdeflist.finditem(const apos: sourceposty; + const firstidentuse: boolean; out scope: tdeflist): pdefinfoty; +begin + result:= internalfinditem(apos,firstidentuse,false,scope); +end; + +procedure tdeflist.finalizerecord(var item); +begin + freeandnil(finfos[defnamety(item).id].deflist); + finalize(defnamety(item)); +end; +{ +procedure tdeflist.comp(const l,r; out result: integer); +var + int1: integer; +begin + result:= (length(defnamety(l).name) - + length(defnamety(r).name)) shl 16; + if result = 0 then begin + for int1:= length(defnamety(l).name) - 1 downto 0 do begin + result:= integer(pcharaty(defnamety(l).name)^[int1]) - + integer(pcharaty(defnamety(r).name)^[int1]); + if result <> 0 then begin + break; + end; + end; + end; +end; +} +function tdeflist.comp(const l,r): integer; +var + po1,po2: pchar; + ch1: shortint; +begin + po1:= pchar(defnamety(l).name); //searchvalue + po2:= pchar(defnamety(r).name); //tableitems + repeat + ch1:= shortint(po1^) - shortint(po2^); + if (ch1 <> 0) or (po1^ = #0) then begin + break; + end; + inc(po2); + inc(po1); + until false; + result:= ch1; +end; + +function tdeflist.compnopars(const l,r): integer; +var + po1,po2: pchar; + ch1: shortint; +begin + po1:= pchar(defnamety(l).name); //searchvalue + po2:= pchar(defnamety(r).name); //tableitems + repeat + ch1:= shortint(po1^) - shortint(po2^); + if (ch1 <> 0) or (po1^ = #0) then begin + break; + end; + inc(po2); + inc(po1); + if po2^ = '$' then begin + if (po1^ = #0) or (po1^ = '$') then begin + break; + end; + end; + until false; + result:= ch1; +end; + +function tdeflist.compsubstr(const l,r): integer; +var + po1,po2: pchar; + ch1: shortint; +begin + po1:= pchar(defnamety(l).name); //searchvalue + po2:= pchar(defnamety(r).name); //tableitems + ch1:= 0; + repeat + if (po1^ = #0) then begin + break; + end; + ch1:= shortint(po1^) - shortint(po2^); + if (ch1 <> 0) then begin + break; + end; + inc(po2); + inc(po1); + until false; + result:= ch1; +end; + +function tdeflist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}comp; +end; + +function tdeflist.getname: string; +begin + if fparent = nil then begin + result:= ''; + end + else begin + result:= fparent.finfos[fparentid].name; + end; +end; + +function tdeflist.getdefinfopo: pdefinfoty; +begin + if fparent = nil then begin + result:= nil; + end + else begin + result:= @fparent.finfos[fparentid]; + end; +end; + +function tdeflist.getrootlist: trootdeflist; +begin + result:= trootdeflist(self); + while result.fparent <> nil do begin + result:= trootdeflist(result.fparent); + end; +end; + +function tdeflist.find(const aname: string; + const akind: symbolkindty = syk_none): pdefinfoty; +var + int1,int2: integer; + str1: string; +label + exit1; +begin + result:= nil; + if fcasesensitive then begin + str1:= aname; + end + else begin + str1:= struppercase(aname); + end; + sorted:= true; + if akind = syk_nopars then begin + fcomparefunc:= {$ifdef FPC}@{$endif}compnopars; + end + else begin + if akind = syk_substr then begin + fcomparefunc:= {$ifdef FPC}@{$endif}compsubstr; + end + end; + if internalfind(str1,int1) then begin + if akind > syk_deleted then begin + while finfos[pdefnameaty(fdata)^[int1].id].kind <> akind do begin + dec(int1); + if (int1 < 0) then begin + goto exit1; + end; + int2:= comp(str1,pdefnameaty(fdata)^[int1].name); + if (int2 <> 0) then begin + goto exit1; + end; + end; + end; + result:= @finfos[pdefnameaty(fdata)^[int1].id]; + end; +exit1: + fcomparefunc:= {$ifdef FPC}@{$endif}comp; +end; + +function tdeflist.getmatchingitems(const aname: string; + const akind: symbolkindty = syk_none): definfopoarty; +var + int1,int2: integer; + str1: string; + po1: pdefinfoty; +begin + result:= nil; + if fcasesensitive then begin + str1:= aname; + end + else begin + str1:= struppercase(aname); + end; + sorted:= true; + if akind = syk_nopars then begin + fcomparefunc:= {$ifdef FPC}@{$endif}compnopars; + end + else begin + if akind = syk_substr then begin + fcomparefunc:= {$ifdef FPC}@{$endif}compsubstr; + end + end; + if internalfind(str1,int1) then begin + while (int1 >= 0) do begin + int2:= fcomparefunc(str1,pdefnameaty(fdata)^[int1]); + if int2 <> 0 then begin + break; + end; + po1:= @finfos[pdefnameaty(fdata)^[int1].id]; + if po1^.kind <> syk_deleted then begin + additem(pointerarty(result),po1); + end; + dec(int1); + end; + end; + fcomparefunc:= {$ifdef FPC}@{$endif}comp; +end; + +function tdeflist.rootnamepath: string; +var + pa: tdeflist; +begin + result:= name; + pa:= parentscope; + while pa <> nil do begin + result:= pa.name + '.' + result; + pa:= pa.parentscope; + end; +end; + +{ trootdeflist} + +constructor trootdeflist.create(const aunitinfopo: punitinfoty); +begin + funitinfopo:= aunitinfopo; + factnode:= self; + inherited create(syk_root,funitinfopo^.proglang = pl_c); +end; + +procedure trootdeflist.clear; +begin + inherited; + factnode:= self; +end; + +function trootdeflist.beginnode(const aname: string; const akind: symbolkindty; + const apos,astop: sourceposty): pdefinfoty; +begin + result:= factnode.add(aname,akind,apos,astop); + with result^ do begin + deflist:= tdeflist.create(akind,fcasesensitive); + deflist.fparent:= factnode; + deflist.fparentid:= factnode.count - 1; + deflist.fparentscope:= factnode; + deflist.fstart:= apos; + factnode:= deflist; + end; +end; + +procedure trootdeflist.endnode(const apos: sourceposty); +begin + factnode.fstop:= apos; + factnode:= factnode.fparent; +end; + +procedure trootdeflist.deletenode; +begin + with finfos[high(finfos)] do begin + freeandnil(deflist); + kind:= syk_deleted; + end; +end; + +function trootdeflist.beginnode(const apos: sourceposty; + const aclassinfo: pclassinfoty): tdeflist; +begin + with beginnode(aclassinfo^.uppername,syk_classdef,apos,aclassinfo^.headerstop)^ do begin + classindex:= aclassinfo^.b.index; + deflist.fparentident:= aclassinfo^.parentname; + result:= deflist; + end; +end; +{ +procedure trootdeflist.selectnode(const anode: tdeflist); +begin + factnode:= anode; +end; + +procedure trootdeflist.popnode; +begin + factnode:= factnode.fparent; + if factnode = nil then begin + factnode:= self; + end; +end; +} +function trootdeflist.add(const aname: string; const akind: symbolkindty; + const astart,astop: sourceposty): pdefinfoty; +begin + result:= factnode.add(aname,akind,astart,astop); +end; + +function trootdeflist.add(const apos,astop: sourceposty; + const aprocinfo: pprocedureinfoty): pdefinfoty; +begin + result:= factnode.add(aprocinfo^.name+mangleprocparams(aprocinfo^.params), + syk_procdef,apos,astop); + result^.procindex:= aprocinfo^.b.index; +end; + +function trootdeflist.add(const apos,astop: sourceposty; + const afunctioninfo: pfunctioninfoty): pdefinfoty; +begin + result:= factnode.add(afunctioninfo^.name,syk_procimp,apos,astop); + result^.procindex:= -1; //functioninfoty is no browseritem +// result^.procindex:= afunctioninfo^.b.index; +end; + +function trootdeflist.add(const apos,astop: sourceposty; + const afunctionheaderinfo: pfunctionheaderinfoty): pdefinfoty; +begin + result:= factnode.add(afunctionheaderinfo^.name,syk_procdef,apos,astop); + result^.procindex:= afunctionheaderinfo^.b.index; +end; + +function trootdeflist.finddef(const anamepath: stringarty; var scopes: deflistarty; + var defs: definfopoarty; + const first: boolean; // break if first found + const level: defsearchlevelty; + const afindkind: symbolkindty = syk_none; + const maxcount: integer = bigint): boolean; + //true if found + + function unitsearch(alist: trootdeflist): boolean; + begin + if (alist <> nil) and not (alist.allreadysearched and + (level in [dsl_normal,dsl_parent])) then begin + if level in [dsl_normal,dsl_parent] then begin + trootdeflist(alist).allreadysearched:= true; + end; + result:= alist.finddef(anamepath,scopes,defs,first,dsl_unitsearch,afindkind,maxcount); + end + else begin + result:= false; + end; + end; + +var + int1: integer; + alist: trootdeflist; + po1: punitinfoty; + po2: pdefinfoty; +begin + result:= false; + if high(anamepath) >= 0 then begin + alist:= nil; + if (level in [dsl_normal,dsl_parent]) and (high(anamepath) > 0) then begin + //check qualified + if stringicomp(anamepath[0],funitinfopo^.unitname) = 0 then begin + alist:= self; + end + else begin + if funitinfopo^.proglang = pl_pascal then begin + alist:= funitinfopo^.p.interfaceuses.getunitdeflist(anamepath[0]); + if alist = nil then begin + alist:= funitinfopo^.p.implementationuses.getunitdeflist(anamepath[0]); + end; + end; + end; + end; + if alist <> nil then begin + result:= alist.finddef(copy(anamepath,1,bigint),scopes,defs,first, + dsl_qualified,afindkind,maxcount); + end + else begin + flastunitindex:= 0; + if level in [dsl_normal,dsl_parent] then begin + allreadysearched:= true; + end; + result:= inherited finddef(anamepath,scopes,defs,first,level,afindkind,maxcount); + case funitinfopo^.proglang of + pl_pascal: begin + if (not result or not first) and (level in [dsl_normal,dsl_parent,dsl_parentclass]) then begin + for int1:= funitinfopo^.p.implementationuses.count - 1 downto 0 do begin + result:= unitsearch(funitinfopo^.p.implementationuses.getunitdeflist(int1)) or result; + if result and first then begin + flastunitindex:= -int1; + exit; + end; + end; + for int1:= funitinfopo^.p.interfaceuses.count - 1 downto 0 do begin + result:= unitsearch(funitinfopo^.p.interfaceuses.getunitdeflist(int1)) or result; + if result and first then begin + flastunitindex:= int1+1; + exit; + end; + end; + po1:= {sourceupdater.}updateunitinterface('system'); + if po1 <> nil then begin + result:= po1^.deflist.finddef(anamepath,scopes,defs,first, + dsl_unitsearch,afindkind,maxcount) or result; + end; + end; + end; + pl_c: begin + if result and first and (defs[0]^.kind = syk_procdef) then begin + result:= false; + scopes:= nil; + defs:= nil; + end; + if (not result {or not first}) and (level in + [dsl_normal,dsl_parent]) then begin + po2:= cglobals.finddef(anamepath[high(anamepath)]); + if po2 <> nil then begin + result:= true; + additem(pointerarty(defs),pointer(po2)); + end; + end; + end; + end; + end; + end; +end; + +function trootdeflist.findparentclass(const adescendent: tdeflist; + var defs: definfopoarty): boolean; +var + ar1: stringarty; + ar2: deflistarty; +begin + with adescendent do begin + setlength(ar1,1); + ar1[0]:= fparentident; + result:= false; + if adescendent.fparentunitindex > 0 then begin + result:= funitinfopo^.p.interfaceuses. + getunitdeflist(adescendent.fparentunitindex-1). + finddef(ar1,ar2,defs,true,dsl_unitsearch,syk_classdef); + end + else begin + if adescendent.fparentunitindex < 0 then begin + result:= funitinfopo^.p.implementationuses. + getunitdeflist(-adescendent.fparentunitindex). + finddef(ar1,ar2,defs,true,dsl_unitsearch,syk_classdef); + end; + end; + if not result then begin + result:= self.finddef(ar1,ar2,defs,true,dsl_parentclass,syk_classdef); + if result then begin + adescendent.fparentunitindex:= flastunitindex; + end; + end; + end; +end; + +function trootdeflist.getname: string; +begin + result:= funitinfopo^.unitname; +end; + +{ tfunctionheaders } + +constructor tfunctionheaders.create; +begin + inherited create(sizeof(functionheaderinfoty),[rels_needsfinalize]); +end; + +function tfunctionheaders.getitempo(const index: integer): pfunctionheaderinfoty; +begin + result:= pfunctionheaderinfoty(inherited getitempo(index)); +end; + +procedure tfunctionheaders.finalizerecord(var item); +begin + finalize(functionheaderinfoty(item)); +end; + +{ tfunctions } + +constructor tfunctions.create; +begin + inherited create(sizeof(functioninfoty),[rels_needsfinalize]); +end; + +function tfunctions.getitempo(const index: integer): pfunctioninfoty; +begin + result:= pfunctioninfoty(inherited getitempo(index)); +end; + +procedure tfunctions.finalizerecord(var item); +begin + finalize(functioninfoty(item)); +end; + +procedure tfunctions.add(const aname: ansistring; const astart,astop: sourceposty); +begin + with pfunctioninfoty(newitem)^ do begin + name:= aname; + start:= astart; + stop:= astop; + end; +end; + +function tfunctions.comp(const left,right): integer; +begin + result:= stringcomp(ansistring(left),ansistring(right)); +end; + +function tfunctions.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}comp; +end; + +function tfunctions.find(const name: ansistring): pfunctioninfoty; +var + info: functioninfoty; + int1: integer; +begin + result:= nil; + info.name:= name; + if internalfind(info,int1) then begin + result:= items[int1]; + end; +end; + +{ tunitinfo } + +function tunitinfo.infopo: punitinfoty; +begin + result:= @info; +end; + +constructor tunitinfo.create; +begin + with info do begin + if deflist = nil then begin + deflist:= trootdeflist.create(@info); + end; + end; +end; + +destructor tunitinfo.destroy; +begin + with info do begin + itemlist.free; + deflist.Free; + end; + inherited; +end; + +{ tpascalunitinfo } + +constructor tpascalunitinfo.create; +begin + inherited; + with info do begin + proglang:= pl_pascal; + p.procedurelist:= tprocedureinfolist.create; + p.interfacelist:= tinterfaceinfolist.create; + p.classinfolist:= tclassinfolist.create; + p.interfaceuses:= tusesinfolist.create(false); + p.implementationuses:= tusesinfolist.create(true); + end; +end; + +destructor tpascalunitinfo.destroy; +begin + with info do begin + p.procedurelist.Free; + p.interfacelist.Free; + p.classinfolist.Free; + p.interfaceuses.Free; + p.implementationuses.Free; + end; + inherited; +end; + +end. diff --git a/mseide-msegui/apps/ide/mseide.ico b/mseide-msegui/apps/ide/mseide.ico new file mode 100644 index 0000000..6a22884 Binary files /dev/null and b/mseide-msegui/apps/ide/mseide.ico differ diff --git a/mseide-msegui/apps/ide/mseide.pas b/mseide-msegui/apps/ide/mseide.pas new file mode 100644 index 0000000..89bddda --- /dev/null +++ b/mseide-msegui/apps/ide/mseide.pas @@ -0,0 +1,76 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program mseide; +{$ifdef FPC} + {$mode objfpc}{$h+} + {$ifdef mswindows} + {$ifdef mse_debug}{$apptype console}{$else}{$apptype gui}{$endif} + {$endif} +{$endif} +{$ifdef mswindows} + {$R mseide.res} +{$endif} +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses +{$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} +// mseopenglgdiinit, + mseskindesign,menusdesign, + msegui,msegraphics,actionsmodule,sourceform,debuggerform, + componentpaletteform,componentstore, + messageform,watchform,objectinspector,breakpointsform,watchpointsform, + stackform,projecttreeform,findinfileform,cpuform,disassform,memoryform, + threadsform,mseguiglob,symbolform, + targetconsole,main,mseguiintf,{msestockobjects,}regunitgroups,guitemplates, + msegraphutils,msefont,stringconsts; +begin + registerfontalias('mseide_source',gui_getdefaultfontnames[stf_courier], + fam_fixnooverwrite,16); + application.createdatamodule(tguitemplatesmo,guitemplatesmo); + if application.terminated then begin + exit; + end; + application.createdatamodule(tstringconstsmo,s); + application.createdatamodule(tactionsmo,actionsmo); + application.createform(tsourcefo, sourcefo); + application.createform(tdebuggerfo,debuggerfo); + application.createform(tcomponentpalettefo,componentpalettefo); + application.createform(tcomponentstorefo,componentstorefo); + application.createform(tmessagefo,messagefo); + application.createform(twatchfo, watchfo); + application.createform(tsymbolfo, symbolfo); + application.createform(tobjectinspectorfo, objectinspectorfo); + application.createform(tbreakpointsfo, breakpointsfo); + application.createform(twatchpointsfo, watchpointsfo); + application.createform(tstackfo, stackfo); + application.createform(tprojecttreefo, projecttreefo); + application.createform(tfindinfilefo, findinfilefo); +// application.createform(tcpufo, cpufo); + application.createform(tdisassfo, disassfo); + application.createform(tmemoryfo, memoryfo); + application.createform(tthreadsfo, threadsfo); + application.createform(ttargetconsolefo,targetconsolefo); + application.createform(tmainfo, mainfo); + createcpufo; + application.run; +end. diff --git a/mseide-msegui/apps/ide/mseide.prj b/mseide-msegui/apps/ide/mseide.prj new file mode 100644 index 0000000..31b76a4 --- /dev/null +++ b/mseide-msegui/apps/ide/mseide.prj @@ -0,0 +1,1047 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/mseide.prj +mainfile=mseide.pas +targetfile=mseide${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=4 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=10 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Report + Scriptform + Inherited Form +newfonamebases=10 + form + form + form + module + form + form + form + report + script + form +newfosources=10 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=10 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=3 + ACTIONSMO + MAINFO + SOURCEFO +moduletypes=3 + TACTIONSMO + TMAINFO + TSOURCEFO +modulefiles=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=4 + 196671 + 65599 + 196671 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=10 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=3 + 0,0 + 0,0 + 0,0 +bookmarks0=0 +bookmarks1=0 +bookmarks2=0 +sourcefiles=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.pas + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.pas + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.pas +relpaths=3 + main.pas + sourceform.pas + actionsmodule.pas +ismoduletexts=3 + 0 + 0 + 0 +modules=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm +moduleoptions=3 + 0 + 0 + 0 +visiblemodules=3 + -1 + -1 + -1 +nomenumodules=3 + 0 + 0 + 0 +[sourcefo.tabwidget] +tabsize=140 +firsttab=0 +index=0 +[layout] +windowlayout=567 + [mainfo.openform] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=2 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + filefilterindex=0 + filefilter=*.mfm + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=14 + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=_mse_actionsmo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=16507 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=45 + y=165 + cx=469 + cy=149 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/mseide.rc b/mseide-msegui/apps/ide/mseide.rc new file mode 100644 index 0000000..8dda4b4 --- /dev/null +++ b/mseide-msegui/apps/ide/mseide.rc @@ -0,0 +1,24 @@ +MAINICON ICON "mseide.ico" +1 VERSIONINFO +FILEVERSION 3,0,0,0 +PRODUCTVERSION 3,0,0,0 +FILEFLAGSMASK 0 +FILEOS 0x40000 +FILETYPE 1 +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "CompanyName","" + VALUE "FileDescription","MSEide Free Pascal RAD suite" + VALUE "FileVersion","3.3.0.0" + VALUE "InternalName","" + VALUE "LegalCopyright","2013 (c) Martin Schreiber" + VALUE "OriginalFilename","mseide.pas" + VALUE "ProductName","MSEide" + VALUE "ProductVersion","3.0.0" + } + } +} + diff --git a/mseide-msegui/apps/ide/mseide.res b/mseide-msegui/apps/ide/mseide.res new file mode 100644 index 0000000..a1069c1 Binary files /dev/null and b/mseide-msegui/apps/ide/mseide.res differ diff --git a/mseide-msegui/apps/ide/mseide_zeos.prj b/mseide-msegui/apps/ide/mseide_zeos.prj new file mode 100644 index 0000000..c9e49cb --- /dev/null +++ b/mseide-msegui/apps/ide/mseide_zeos.prj @@ -0,0 +1,1163 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/mseide_zeos.prj +options=99 + [projectoptionsfo.twidgetgrid3] + propcolwidthref=788 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + width4=364 + sortdescend4=0 + width5=51 + sortdescend5=0 + width6=322 + sortdescend6=0 + [projectoptionsfo.twidgetgrid4] + propcolwidthref=612 + width0=96 + sortdescend0=0 + sortdescend1=0 + width2=73 + sortdescend2=0 + width3=293 + sortdescend3=0 + width4=309 + sortdescend4=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [projectoptionsfo.newfile] + firsttab=0 + index=0 + [projectoptionsfo.fontaliasgrid] + propcolwidthref=471 + width0=98 + sortdescend0=0 + width1=460 + sortdescend1=0 + width2=30 + sortdescend2=0 + width3=50 + sortdescend3=0 + width4=50 + sortdescend4=0 + width5=50 + sortdescend5=0 + width6=70 + sortdescend6=0 + [projectoptionsfo.macrosplitter] + x=0 + y=179 + xprop=1 + yprop=0.34942084942085 + [projectoptionsfo.macrogrid] + propcolwidthref=595 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + width6=146 + sortdescend6=0 + width7=583 + sortdescend7=0 + [projectoptionsfo.makegroupbox] + firsttab=0 + index=2 + [projectoptionsfo.exceptionsgrid] + propcolwidthref=772 + width0=47 + sortdescend0=0 + width1=766 + sortdescend1=0 + [projectoptionsfo.ttabwidget1] + firsttab=0 + index=0 + [projectoptionsfo.grid] + propcolwidthref=573 + width0=219 + sortdescend0=0 + width1=566 + sortdescend1=0 + [projectoptionsfo.filefiltergrid] + propcolwidthref=680 + width0=112 + sortdescend0=0 + width1=673 + sortdescend1=0 + [projectoptionsfo.ttabwidget2] + firsttab=0 + index=1 + [projectoptionsfo.tabwidget] + firsttab=0 + index=3 + [projectoptionsfo] + stackedunder= + x=151 + y=68 + cx=821 + cy=572 +mainfile=mseide.pas +targetfile=mseide_zeos${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=5 + ${zeosdir}/src/*/ + ${zeosdir}/src/ + ${MSELIBDIR}kernel/$TARGETOSDIR + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -Fcutf8 -dmse_with_zeoslib -dMSEgui + -gl + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=3 + ACTIONSMO + MAINFO + SOURCEFO +moduletypes=3 + TACTIONSMO + TMAINFO + TSOURCEFO +modulefiles=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=5 + 983103 + 131135 + 65599 + 196671 + 65599 +macroon=1 + 63 +macronames=1 + zeosdir +macrovalues=1 + +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=-1 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=14 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=5 + ${zeosdir}/src/*/ + ${zeosdir}/src/ + ${MSELIBDIR}kernel/$TARGET/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=3 + 0,0 + 0,0 + 0,0 +bookmarks0=0 +bookmarks1=0 +bookmarks2=0 +sourcefiles=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.pas + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.pas + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.pas +relpaths=3 + main.pas + sourceform.pas + actionsmodule.pas +ismoduletexts=3 + 0 + 0 + 0 +modules=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm +moduleoptions=3 + 0 + 0 + 0 +visiblemodules=3 + -1 + -1 + -1 +nomenumodules=3 + 0 + 0 + 0 +[sourcefo.tabwidget] +tabsize=134 +firsttab=0 +index=0 +[layout] +windowlayout=571 + [mainfo.openform] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=2 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + filefilterindex=0 + filefilter=*.mfm + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=_mse_actionsmo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=1 + 0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=1 + pinteger(0x126c6b4)^ + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=1 + 0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=1 + + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=14 + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=16507 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=45 + y=165 + cx=469 + cy=149 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/mseparamentryform.mfm b/mseide-msegui/apps/ide/mseparamentryform.mfm new file mode 100644 index 0000000..5f7dc6f --- /dev/null +++ b/mseide-msegui/apps/ide/mseparamentryform.mfm @@ -0,0 +1,140 @@ +object mseparamentryfo: tmseparamentryfo + visible = False + bounds_x = 222 + bounds_y = 262 + bounds_cx = 371 + bounds_cy = 260 + container.bounds = ( + 0 + 0 + 371 + 260 + ) + options = [fo_screencentered, fo_cancelonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = tstatfile1 + moduleclassname = 'tmseform' + object grid: twidgetgrid + bounds_x = 0 + bounds_y = 0 + bounds_cx = 371 + bounds_cy = 231 + anchors = [an_top] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Macro' + end + item + caption = 'Value' + end> + end> + datacols.count = 2 + datacols.options = [co_proportional, co_savestate, co_mousescrollrow] + datacols.items = < + item[macroname] + width = 89 + options = [co_readonly, co_nofocus, co_proportional, co_savestate, co_mousescrollrow] + widgetname = 'macroname' + dataclass = tgridmsestringdatalist + end + item[macrovalue] + width = 276 + options = [co_fill, co_savestate, co_mousescrollrow] + widgetname = 'macrovalue' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = tstatfile1 + reffontheight = 14 + object macroname: tstringedit + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 89 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object macrovalue: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.localprops = [frl_levelo] + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 90 + bounds_y = 0 + bounds_cx = 276 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + object tsplitter1: tsplitter + color = -1879048189 + taborder = 1 + bounds_x = 0 + bounds_y = 231 + bounds_cx = 371 + bounds_cy = 25 + anchors = [an_bottom] + optionsscale = [osc_expandy, osc_shrinky] + linktop = grid + grip = stb_none + object tbutton2: tbutton + bounds_x = 312 + bounds_y = 5 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object tbutton1: tbutton + taborder = 1 + bounds_x = 256 + bounds_y = 5 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object comment: tlabel + optionswidget1 = [ow1_autoheight] + taborder = 2 + bounds_x = 2 + bounds_y = 2 + bounds_cx = 252 + bounds_cy = 14 + anchors = [an_left, an_top, an_right] + caption = 'comment' + textflags = [tf_ycentered, tf_wordbreak] + end + end + object tstatfile1: tstatfile + filename = 'templparam.sta' + options = [sfo_memory, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + left = 40 + top = 80 + end + object c: tstringcontainer + strings.data = ( + 'Code Template "' + ) + left = 40 + top = 120 + end +end diff --git a/mseide-msegui/apps/ide/mseparamentryform.pas b/mseide-msegui/apps/ide/mseparamentryform.pas new file mode 100644 index 0000000..3ff7315 --- /dev/null +++ b/mseide-msegui/apps/ide/mseparamentryform.pas @@ -0,0 +1,46 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit mseparamentryform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msesimplewidgets, + msewidgets,msedataedits,mseedit,msegrids,msestrings,msetypes,msewidgetgrid, + msememodialog,msesplitter,msestatfile,msestringcontainer; +type + strinconsts = ( + codetemplate //0 Code Template " + ); + + tmseparamentryfo = class(tmseform) + grid: twidgetgrid; + macroname: tstringedit; + macrovalue: tmemodialogedit; + tsplitter1: tsplitter; + tbutton2: tbutton; + tbutton1: tbutton; + comment: tlabel; + tstatfile1: tstatfile; + c: tstringcontainer; + end; +var + mseparamentryfo: tmseparamentryfo; +implementation +uses + mseparamentryform_mfm; +end. diff --git a/mseide-msegui/apps/ide/mseparamentryform_mfm.pas b/mseide-msegui/apps/ide/mseparamentryform_mfm.pas new file mode 100644 index 0000000..bfdab66 --- /dev/null +++ b/mseide-msegui/apps/ide/mseparamentryform_mfm.pas @@ -0,0 +1,153 @@ +unit mseparamentryform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseparamentryform; + +const + objdata: record size: integer; data: array[0..2713] of byte end = + (size: 2714; data: ( + 84,80,70,48,16,116,109,115,101,112,97,114,97,109,101,110,116,114,121,102, + 111,15,109,115,101,112,97,114,97,109,101,110,116,114,121,102,111,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,222,0,8,98, + 111,117,110,100,115,95,121,3,6,1,9,98,111,117,110,100,115,95,99,120, + 3,115,1,9,98,111,117,110,100,115,95,99,121,3,4,1,16,99,111,110, + 116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,115, + 1,3,4,1,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99, + 114,101,101,110,99,101,110,116,101,114,101,100,14,102,111,95,99,97,110,99, + 101,108,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115, + 116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116, + 10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122, + 111,114,100,101,114,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116, + 97,116,102,105,108,101,49,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,8,116,109,115,101,102,111,114,109,0,11,116,119,105,100,103, + 101,116,103,114,105,100,4,103,114,105,100,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,115,1,9,98,111,117,110,100,115,95,99,121,3,231,0,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,11,111,112,116, + 105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105, + 110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116, + 101,114,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98, + 107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117, + 116,111,112,111,112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111, + 108,108,99,111,108,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116, + 2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104, + 101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117, + 110,116,2,2,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14, + 1,7,99,97,112,116,105,111,110,6,5,77,97,99,114,111,0,1,7,99, + 97,112,116,105,111,110,6,5,86,97,108,117,101,0,0,0,0,14,100,97, + 116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97,116,97,99, + 111,108,115,46,111,112,116,105,111,110,115,11,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116, + 101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0, + 14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,9,109,97, + 99,114,111,110,97,109,101,1,5,119,105,100,116,104,2,89,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,10,99,111, + 95,110,111,102,111,99,117,115,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,9,109,97,99,114,111,110,97,109,101,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,109,97,99,114,111, + 118,97,108,117,101,1,5,119,105,100,116,104,3,20,1,7,111,112,116,105, + 111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101, + 115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,109,97,99, + 114,111,118,97,108,117,101,9,100,97,116,97,99,108,97,115,115,7,22,116, + 103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115, + 116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8, + 115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,115, + 116,114,105,110,103,101,100,105,116,9,109,97,99,114,111,110,97,109,101,8, + 116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,89,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97, + 100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101, + 116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101, + 100,105,116,10,109,97,99,114,111,118,97,108,117,101,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,0,18,102,114,97,109,101,46,98,117,116, + 116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101, + 46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97, + 98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,2,90,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,20,1,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,112,108, + 105,116,116,101,114,10,116,115,112,108,105,116,116,101,114,49,5,99,111,108, + 111,114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,231, + 0,9,98,111,117,110,100,115,95,99,120,3,115,1,9,98,111,117,110,100, + 115,95,99,121,2,25,7,97,110,99,104,111,114,115,11,9,97,110,95,98, + 111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114, + 105,110,107,121,0,7,108,105,110,107,116,111,112,7,4,103,114,105,100,4, + 103,114,105,112,7,8,115,116,98,95,110,111,110,101,0,7,116,98,117,116, + 116,111,110,8,116,98,117,116,116,111,110,50,8,98,111,117,110,100,115,95, + 120,3,56,1,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,6,67, + 97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109, + 114,95,99,97,110,99,101,108,0,0,7,116,98,117,116,116,111,110,8,116, + 98,117,116,116,111,110,49,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,3,0,1,8,98,111,117,110,100,115,95,121,2, + 5,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,10,97, + 115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101, + 102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,2,79,75,11,109,111,100,97,108, + 114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,6,116,108,97,98, + 101,108,7,99,111,109,109,101,110,116,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,14,111,119,49,95,97,117,116,111,104,101,105,103,104, + 116,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,2,8,98,111,117,110,100,115,95,121,2,2,9,98,111,117,110, + 100,115,95,99,120,3,252,0,9,98,111,117,110,100,115,95,99,121,2,14, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,7,99,97,112,116,105, + 111,110,6,7,99,111,109,109,101,110,116,9,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,12,116,102,95,119, + 111,114,100,98,114,101,97,107,0,0,0,0,9,116,115,116,97,116,102,105, + 108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97, + 109,101,6,14,116,101,109,112,108,112,97,114,97,109,46,115,116,97,7,111, + 112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,15,115, + 102,111,95,116,114,97,110,115,97,99,116,105,111,110,17,115,102,111,95,97, + 99,116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95,97,99,116, + 105,118,97,116,111,114,119,114,105,116,101,0,4,108,101,102,116,2,40,3, + 116,111,112,2,80,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97, + 105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1, + 6,15,67,111,100,101,32,84,101,109,112,108,97,116,101,32,34,0,4,108, + 101,102,116,2,40,3,116,111,112,2,120,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmseparamentryfo,''); +end. diff --git a/mseide-msegui/apps/ide/msetemplateselectform.mfm b/mseide-msegui/apps/ide/msetemplateselectform.mfm new file mode 100644 index 0000000..2e29f90 --- /dev/null +++ b/mseide-msegui/apps/ide/msetemplateselectform.mfm @@ -0,0 +1,261 @@ +object msetemplateselectfo: tmsetemplateselectfo + visible = False + bounds_x = 152 + bounds_y = 247 + bounds_cx = 569 + bounds_cy = 277 + container.bounds = ( + 0 + 0 + 569 + 277 + ) + options = [fo_screencentered, fo_cancelonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = tstatfile1 + caption = 'Select Code Template' + moduleclassname = 'tmseform' + object tbutton1: tbutton + taborder = 2 + bounds_x = 512 + bounds_y = 251 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object tbutton2: tbutton + taborder = 1 + bounds_x = 456 + bounds_y = 251 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object grid: twidgetgrid + bounds_x = 0 + bounds_y = 0 + bounds_cx = 569 + bounds_cy = 245 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 25 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 7 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Comment' + end + item + caption = 'Par1' + end + item + caption = 'Par2' + end + item + caption = 'Par3' + end + item + caption = 'Par4' + end + item + caption = 'ed' + end> + end> + datacols.count = 7 + datacols.colorfocused = -1879048185 + datacols.options = [co_nofocus, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + datacols.options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + datacols.items = < + item[templatename] + colorfocused = -1879048185 + width = 60 + options = [co_readonly, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'templatename' + dataclass = tgridmsestringdatalist + end + item[comment] + colorfocused = -1879048185 + width = 252 + options = [co_readonly, co_nofocus, co_drawfocus, co_fill, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'comment' + dataclass = tgridmsestringdatalist + end + item[par1] + colorfocused = -1879048185 + width = 51 + options = [co_readonly, co_nofocus, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'par1' + dataclass = tgridmsestringdatalist + end + item[par2] + colorfocused = -1879048185 + width = 51 + options = [co_readonly, co_nofocus, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'par2' + dataclass = tgridmsestringdatalist + end + item[par3] + colorfocused = -1879048185 + width = 51 + options = [co_readonly, co_nofocus, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'par3' + dataclass = tgridmsestringdatalist + end + item[par4] + colorfocused = -1879048185 + width = 51 + options = [co_readonly, co_nofocus, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'par4' + dataclass = tgridmsestringdatalist + end + item[tstockglyphdatabutton1] + color = -2147483646 + colorfocused = -1879048185 + width = 16 + options = [co_readonly, co_fixwidth, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'tstockglyphdatabutton1' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + statfile = tstatfile1 + oncellevent = celle + reffontheight = 14 + object templatename: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 60 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext, oe_locate] + reffontheight = 14 + end + object comment: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 61 + bounds_y = 0 + bounds_cx = 252 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object par1: tstringedit + Tag = 1 + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 314 + bounds_y = 0 + bounds_cx = 51 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object par2: tstringedit + Tag = 2 + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 366 + bounds_y = 0 + bounds_cx = 51 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object par3: tstringedit + Tag = 3 + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 5 + visible = False + bounds_x = 418 + bounds_y = 0 + bounds_cx = 51 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object par4: tstringedit + Tag = 4 + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 6 + visible = False + bounds_x = 470 + bounds_y = 0 + bounds_cx = 51 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object tstockglyphdatabutton1: tstockglyphdatabutton + optionsskin = [osk_framebuttononly] + taborder = 7 + bounds_x = 522 + bounds_y = 0 + bounds_cx = 16 + bounds_cy = 16 + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_asyncexecute] + state = [as_invisible, as_localinvisible, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_ellipsesmall + onexecute = edtemplateactonexecute + end + end + object filename: tstringdisp + frame.dummy = 0 + taborder = 3 + bounds_x = 5 + bounds_y = 252 + bounds_cx = 446 + bounds_cy = 18 + anchors = [an_left, an_right, an_bottom] + textflags = [tf_ycentered, tf_ellipseleft] + options = [dwo_hintclippedtext] + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'templselect.sta' + options = [sfo_memory, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + left = 40 + top = 80 + end +end diff --git a/mseide-msegui/apps/ide/msetemplateselectform.pas b/mseide-msegui/apps/ide/msetemplateselectform.pas new file mode 100644 index 0000000..0826bcf --- /dev/null +++ b/mseide-msegui/apps/ide/msetemplateselectform.pas @@ -0,0 +1,85 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msetemplateselectform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msesimplewidgets, + msewidgets,msedataedits,mseedit,msegrids,msestrings,msetypes,msewidgetgrid, + msedispwidgets,msecodetemplates,msestatfile,msegraphedits; +type + tmsetemplateselectfo = class(tmseform) + tbutton1: tbutton; + tbutton2: tbutton; + grid: twidgetgrid; + templatename: tstringedit; + comment: tstringedit; + par1: tstringedit; + par2: tstringedit; + par3: tstringedit; + par4: tstringedit; + filename: tstringdisp; + tstatfile1: tstatfile; + tstockglyphdatabutton1: tstockglyphdatabutton; + procedure celle(const sender: TObject; var info: celleventinfoty); + procedure edtemplateactonexecute(const sender: TObject); + private + ftemplates: tcodetemplates; + public + finfos: templateinfoarty; + constructor create(const atemplates: tcodetemplates); reintroduce; + end; + +implementation +uses + msetemplateselectform_mfm,templateeditor,projectoptionsform; + +type + tcodetemplates1 = class(tcodetemplates); + +constructor tmsetemplateselectfo.create(const atemplates: tcodetemplates); +begin + ftemplates:= atemplates; + inherited create(nil); +end; + +procedure tmsetemplateselectfo.edtemplateactonexecute(const sender: TObject); +var + mstr1: msestring; +begin + if ttemplateeditorfo.create(grid.row).show(mstr1) = mr_ok then begin + ftemplates.scan(projectoptions.e.texp.codetemplatedirs); + tcodetemplates1(ftemplates).reload(self); + templatename.editor.filtertext:= mstr1; + end; +end; + +procedure tmsetemplateselectfo.celle(const sender: TObject; + var info: celleventinfoty); +begin + if isrowenter(info) then begin + if info.newcell.row > high(finfos) then begin + filename.value:= ''; + end + else begin + filename.value:= finfos[info.newcell.row].path; + end; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/msetemplateselectform_mfm.pas b/mseide-msegui/apps/ide/msetemplateselectform_mfm.pas new file mode 100644 index 0000000..f047444 --- /dev/null +++ b/mseide-msegui/apps/ide/msetemplateselectform_mfm.pas @@ -0,0 +1,348 @@ +unit msetemplateselectform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msetemplateselectform; + +const + objdata: record size: integer; data: array[0..6609] of byte end = + (size: 6610; data: ( + 84,80,70,48,20,116,109,115,101,116,101,109,112,108,97,116,101,115,101,108, + 101,99,116,102,111,19,109,115,101,116,101,109,112,108,97,116,101,115,101,108, + 101,99,116,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,152,0,8,98,111,117,110,100,115,95,121,3,247,0,9,98, + 111,117,110,100,115,95,99,120,3,57,2,9,98,111,117,110,100,115,95,99, + 121,3,21,1,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100, + 115,1,2,0,2,0,3,57,2,3,21,1,0,7,111,112,116,105,111,110, + 115,11,17,102,111,95,115,99,114,101,101,110,99,101,110,116,101,114,101,100, + 14,102,111,95,99,97,110,99,101,108,111,110,101,115,99,15,102,111,95,97, + 117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119, + 114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,13, + 102,111,95,115,97,118,101,122,111,114,100,101,114,0,8,115,116,97,116,102, + 105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116, + 105,111,110,6,20,83,101,108,101,99,116,32,67,111,100,101,32,84,101,109, + 112,108,97,116,101,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110, + 8,116,98,117,116,116,111,110,49,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,3,0,2,8,98,111,117,110,100,115,95, + 121,3,251,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117, + 110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,6,67,97,110,99,101,108,11,109,111, + 100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108, + 0,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3, + 200,1,8,98,111,117,110,100,115,95,121,3,251,0,9,98,111,117,110,100, + 115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97, + 110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97,115,95,100,101, + 102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108, + 116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99, + 97,112,116,105,111,110,6,2,79,75,11,109,111,100,97,108,114,101,115,117, + 108,116,7,5,109,114,95,111,107,0,0,11,116,119,105,100,103,101,116,103, + 114,105,100,4,103,114,105,100,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 3,57,2,9,98,111,117,110,100,115,95,99,121,3,245,0,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116, + 111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95, + 99,111,108,115,105,122,105,110,103,19,111,103,95,102,111,99,117,115,99,101, + 108,108,111,110,101,110,116,101,114,20,111,103,95,99,111,108,99,104,97,110, + 103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111, + 108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109,111, + 117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111,108, + 115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116, + 101,109,115,14,1,5,119,105,100,116,104,2,25,8,110,117,109,115,116,97, + 114,116,2,1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120, + 114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115, + 46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97, + 112,116,105,111,110,115,46,99,111,117,110,116,2,7,14,99,97,112,116,105, + 111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6, + 4,78,97,109,101,0,1,7,99,97,112,116,105,111,110,6,7,67,111,109, + 109,101,110,116,0,1,7,99,97,112,116,105,111,110,6,4,80,97,114,49, + 0,1,7,99,97,112,116,105,111,110,6,4,80,97,114,50,0,1,7,99, + 97,112,116,105,111,110,6,4,80,97,114,51,0,1,7,99,97,112,116,105, + 111,110,6,4,80,97,114,52,0,1,7,99,97,112,116,105,111,110,6,2, + 101,100,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110, + 116,2,7,21,100,97,116,97,99,111,108,115,46,99,111,108,111,114,102,111, + 99,117,115,101,100,4,7,0,0,144,16,100,97,116,97,99,111,108,115,46, + 111,112,116,105,111,110,115,11,10,99,111,95,110,111,102,111,99,117,115,12, + 99,111,95,100,114,97,119,102,111,99,117,115,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116, + 101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0, + 17,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,49,11,11, + 99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99, + 111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,19, + 99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,0, + 14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,12,116,101, + 109,112,108,97,116,101,110,97,109,101,1,12,99,111,108,111,114,102,111,99, + 117,115,101,100,4,7,0,0,144,5,119,105,100,116,104,2,60,7,111,112, + 116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99, + 111,95,100,114,97,119,102,111,99,117,115,15,99,111,95,112,114,111,112,111, + 114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,8, + 111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111,110, + 116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49,95,122, + 101,98,114,97,99,111,108,111,114,19,99,111,49,95,114,111,119,99,111,108, + 111,114,102,111,99,117,115,101,100,0,10,119,105,100,103,101,116,110,97,109, + 101,6,12,116,101,109,112,108,97,116,101,110,97,109,101,9,100,97,116,97, + 99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,7,7,99,111,109,109,101,110,116,1, + 12,99,111,108,111,114,102,111,99,117,115,101,100,4,7,0,0,144,5,119, + 105,100,116,104,3,252,0,7,111,112,116,105,111,110,115,11,11,99,111,95, + 114,101,97,100,111,110,108,121,10,99,111,95,110,111,102,111,99,117,115,12, + 99,111,95,100,114,97,119,102,111,99,117,115,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,8,111,112,116,105,111,110,115, + 49,11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114, + 111,119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108, + 111,114,19,99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115, + 101,100,0,10,119,105,100,103,101,116,110,97,109,101,6,7,99,111,109,109, + 101,110,116,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100, + 109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,4, + 112,97,114,49,1,12,99,111,108,111,114,102,111,99,117,115,101,100,4,7, + 0,0,144,5,119,105,100,116,104,2,51,7,111,112,116,105,111,110,115,11, + 11,99,111,95,114,101,97,100,111,110,108,121,10,99,111,95,110,111,102,111, + 99,117,115,12,99,111,95,100,114,97,119,102,111,99,117,115,15,99,111,95, + 112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101, + 115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114, + 111,119,102,111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14, + 99,111,49,95,122,101,98,114,97,99,111,108,111,114,19,99,111,49,95,114, + 111,119,99,111,108,111,114,102,111,99,117,115,101,100,0,10,119,105,100,103, + 101,116,110,97,109,101,6,4,112,97,114,49,9,100,97,116,97,99,108,97, + 115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97, + 116,97,108,105,115,116,0,7,4,112,97,114,50,1,12,99,111,108,111,114, + 102,111,99,117,115,101,100,4,7,0,0,144,5,119,105,100,116,104,2,51, + 7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108, + 121,10,99,111,95,110,111,102,111,99,117,115,12,99,111,95,100,114,97,119, + 102,111,99,117,115,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,8,111,112,116,105,111,110, + 115,49,11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95, + 114,111,119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111, + 108,111,114,19,99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117, + 115,101,100,0,10,119,105,100,103,101,116,110,97,109,101,6,4,112,97,114, + 50,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,4,112,97, + 114,51,1,12,99,111,108,111,114,102,111,99,117,115,101,100,4,7,0,0, + 144,5,119,105,100,116,104,2,51,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,10,99,111,95,110,111,102,111,99,117, + 115,12,99,111,95,100,114,97,119,102,111,99,117,115,15,99,111,95,112,114, + 111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116, + 97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119, + 102,111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111, + 49,95,122,101,98,114,97,99,111,108,111,114,19,99,111,49,95,114,111,119, + 99,111,108,111,114,102,111,99,117,115,101,100,0,10,119,105,100,103,101,116, + 110,97,109,101,6,4,112,97,114,51,9,100,97,116,97,99,108,97,115,115, + 7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97, + 108,105,115,116,0,7,4,112,97,114,52,1,12,99,111,108,111,114,102,111, + 99,117,115,101,100,4,7,0,0,144,5,119,105,100,116,104,2,51,7,111, + 112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,10, + 99,111,95,110,111,102,111,99,117,115,12,99,111,95,100,114,97,119,102,111, + 99,117,115,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12, + 99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,8,111,112,116,105,111,110,115,49, + 11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111, + 119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111, + 114,19,99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115,101, + 100,0,10,119,105,100,103,101,116,110,97,109,101,6,4,112,97,114,52,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,22,116,115,116,111, + 99,107,103,108,121,112,104,100,97,116,97,98,117,116,116,111,110,49,1,5, + 99,111,108,111,114,4,2,0,0,128,12,99,111,108,111,114,102,111,99,117, + 115,101,100,4,7,0,0,144,5,119,105,100,116,104,2,16,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,11,99,111, + 95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102, + 111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49, + 95,122,101,98,114,97,99,111,108,111,114,19,99,111,49,95,114,111,119,99, + 111,108,111,114,102,111,99,117,115,101,100,0,10,119,105,100,103,101,116,110, + 97,109,101,6,22,116,115,116,111,99,107,103,108,121,112,104,100,97,116,97, + 98,117,116,116,111,110,49,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,11,111, + 110,99,101,108,108,101,118,101,110,116,7,5,99,101,108,108,101,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,115,116,114,105, + 110,103,101,100,105,116,12,116,101,109,112,108,97,116,101,110,97,109,101,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,60,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,9,111,101,95,108,111,99,97,116,101,0,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100, + 105,116,7,99,111,109,109,101,110,116,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,2,61,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,252,0,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95, + 114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102, + 116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104,105,110,116,99, + 108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105, + 116,4,112,97,114,49,3,84,97,103,2,1,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,8,116,97,98,111,114,100,101,114,2,3,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,58,1,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,51,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111, + 101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104, + 105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104,105,110, + 116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101, + 100,105,116,4,112,97,114,50,3,84,97,103,2,2,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,4,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,110,1,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,51, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110, + 103,101,100,105,116,4,112,97,114,51,3,84,97,103,2,3,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,5,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,162,1,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,51,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,4,112,97,114,52,3,84,97,103,2,4,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102, + 111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,6, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,214, + 1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,51,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18, + 111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,21,116,115, + 116,111,99,107,103,108,121,112,104,100,97,116,97,98,117,116,116,111,110,22, + 116,115,116,111,99,107,103,108,121,112,104,100,97,116,97,98,117,116,116,111, + 110,49,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98, + 111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120,3,10,2,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,16,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111, + 110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,27,111,101,49,95,99,104,101,99,107,118,97,108,117,101,97, + 102,116,101,114,115,116,97,116,114,101,97,100,0,7,111,112,116,105,111,110, + 115,11,17,98,111,95,101,120,101,99,117,116,101,111,110,99,108,105,99,107, + 15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98,111,95, + 101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27,98,111, + 95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101,110,116, + 101,114,107,101,121,15,98,111,95,97,115,121,110,99,101,120,101,99,117,116, + 101,0,5,115,116,97,116,101,11,12,97,115,95,105,110,118,105,115,105,98, + 108,101,17,97,115,95,108,111,99,97,108,105,110,118,105,115,105,98,108,101, + 17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97, + 115,95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121,112,104,7, + 16,115,116,103,95,101,108,108,105,112,115,101,115,109,97,108,108,9,111,110, + 101,120,101,99,117,116,101,7,22,101,100,116,101,109,112,108,97,116,101,97, + 99,116,111,110,101,120,101,99,117,116,101,0,0,0,11,116,115,116,114,105, + 110,103,100,105,115,112,8,102,105,108,101,110,97,109,101,11,102,114,97,109, + 101,46,100,117,109,109,121,2,0,8,116,97,98,111,114,100,101,114,2,3, + 8,98,111,117,110,100,115,95,120,2,5,8,98,111,117,110,100,115,95,121, + 3,252,0,9,98,111,117,110,100,115,95,99,120,3,190,1,9,98,111,117, + 110,100,115,95,99,121,2,18,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 121,99,101,110,116,101,114,101,100,14,116,102,95,101,108,108,105,112,115,101, + 108,101,102,116,0,7,111,112,116,105,111,110,115,11,19,100,119,111,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,116,97,116,102, + 105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110, + 97,109,101,6,15,116,101,109,112,108,115,101,108,101,99,116,46,115,116,97, + 7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121, + 15,115,102,111,95,116,114,97,110,115,97,99,116,105,111,110,17,115,102,111, + 95,97,99,116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95,97, + 99,116,105,118,97,116,111,114,119,114,105,116,101,0,4,108,101,102,116,2, + 40,3,116,111,112,2,80,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsetemplateselectfo,''); +end. diff --git a/mseide-msegui/apps/ide/objectinspector.mfm b/mseide-msegui/apps/ide/objectinspector.mfm new file mode 100644 index 0000000..07d0282 --- /dev/null +++ b/mseide-msegui/apps/ide/objectinspector.mfm @@ -0,0 +1,366 @@ +object objectinspectorfo: tobjectinspectorfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + popupmenu = mainpopup + onenter = enterexe + onactivate = enterexe + visible = False + bounds_x = 185 + bounds_y = 360 + bounds_cx = 254 + bounds_cy = 248 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = objectinspectoronchildscaled + container.bounds = ( + 0 + 0 + 244 + 248 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Objectinspector' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Object Inspector' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000078070000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001D9EEF001AEEEF3018EEDF5019EECF201C5E9EC01E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301EFF2F201 + A0EFF70160F0FF0257F0FF0144EFFF0128EEFF0161EBF501D9E6E701E3E3E301 + E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F3019BF1F90174F1FF01 + 8AF1FF0190F2FF0183F1FF016AF0FF0148EFFF0122EEFF0138DDEA01E1E2E201 + E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501CFF3F60170F1FF0196F2FF01 + B5F3FF01BFF3FF01ACF2FF0188F1FF0160F0FF0136EFFF010DEEFF0155ADB401 + DDDDDD01E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501A1F1F9017CF1FF01A9F2FF01 + D0F4FF01D0F8FF01C5F3FF0198F2FF016BF0FF013EEFFF0111EEFF012AC2CD01 + 96969601E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F50184F0FB0177F1FF01A2F2FF01 + C8F3FF01D0F5FF01BBF3FF0193F2FF0168F0FF013BEFFF010FEEFF011DD6E401 + 66666601D4D4D401DFDFDF01DDDDDD01DBDBDB01D3D3DB01D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F5019AF1F90163F0FF0186F1FF01 + A0F2FF01A8F2FF0198F2FF017AF1FF0155F0FF012DEFFF010DEEFF012CC0CB01 + 66666601BABABA01DFDFDF01DDDDDD01ABABE3015B5BF001D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501CCF2F50147EFFF0161F0FF01 + 73F1FF0178F1FF016EF0FF0157F0FF0139EFFF0116EEFF010DEEFF0146979D01 + 66666601BCBCBC01DFDFDF01DDDDDD013737F7010707FE019A9AC101D6D6D601 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F30187F0F90136EFFF01 + 45EFFF0148EFFF0141EFFF012FEFFF0116EEFF010DEEFF0129C5D10166666602 + D5D5D501DFDFDF019A9AE8010404FF022424D001ABABAB01D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F1F2F20176D3DA011AE6F60118EEFF01 + 12EEFF010DEEFF010FECFD0138B0B901636B6C01666666019B9B9B01E0E0E001 + DCDCDF012626FA010404FF0356569001D1D1D101D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F0019FAAAB01548D910143A1A8014F909501 + 6175760168686801676767018B8B8B01DEDEDE01E0E0E0018888EC010404FF04 + 1919DC019F9F9F01D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01CFCFCF01969696017C7C7C01767676018F8F8F01BABABA01 + E3E3E301E2E2E201D6D6E1011A1AFC010404FF0548489901CBCBCB01D2D2D201 + D0D0D001F5F5F501F79BA701F9798901F8788801F7778701F6768601F5758502 + F4748401F3738301EABAC001E3E3E301E2E2E2017474EF010404FF061111E701 + 91919501D2D2D201D0D0D001F5F5F501FC445B01FF002008EF8F9B01E3E3E301 + CFCFE5010F0FFD010404FF073C3CA301C4C4C401D0D0D001F5F5F501FC445B01 + FF002008A0404C01767676016161F3010404FF080D0DF10182828E01D0D0D001 + F5F5F501FC445B01FF002008A0404C01757578017878F0017272F0014141BF01 + 3434B2013333B1023232B0033131AF014F4F7C01BBBBBB01F5F5F501FC445B01 + FF002008A0404C0176767601E2E2E201B8B8B801656565016464640163636301 + 6262620161616102606060015F5F5F027D7D7D01F5F5F501FC445B01FF002008 + A0404C0176767601E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01 + D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501FC445B01 + FF002008A0404C0176767601E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01 + DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501 + FC445B01FF002008A0404C0176767601E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501FC445B01FF002008A0404C0176767601E2E2E201E0E0E001DFDFDF01 + DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501F79BA701EC6C7C01B6364601B5354504B434440284545A01 + 76767601E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301D9D9D901 + 6C6C6C016B6B6B026A6A6A0269696901686868016767670176767601E2E2E201 + E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501 + D3D3D301D2D2D201D0D0D001 + } + oncreate = createexe + oneventloopstart = objectinspectorfoonloaded + onasyncevent = asyncexe + onlayout = objectinspectoronchildscaled + left = 239 + top = 180 + moduleclassname = 'tdockform' + object compselector: tdropdownlistedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + taborder = 2 + bounds_x = 0 + bounds_y = 1 + bounds_cx = 171 + bounds_cy = 22 + anchors = [an_left, an_top, an_right] + onsetvalue = compselectoronsetvalue + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + onbeforedropdown = compselectorbeforedropdown + reffontheight = 16 + end + object grid: twidgetgrid + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + popupmenu = gridpopup + bounds_x = 0 + bounds_y = 24 + bounds_cx = 244 + bounds_cy = 224 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_colmoving, og_colchangeontabkey, og_wrapcol] + optionsgrid1 = [og1_noresetselect] + rowcolors.count = 1 + rowcolors.items = ( + 16777202 + ) + rowfonts.count = 6 + rowfonts.items = < + item + name = 'stf_default' + xscale = 1 + localprops = [flp_xscale] + end + item + color = 32768 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end + item + color = 32768 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end + item + color = -1610612723 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end + item + style = [fs_bold] + name = 'stf_default' + xscale = 1 + localprops = [flp_style, flp_xscale] + end + item + style = [fs_bold] + name = 'stf_default' + xscale = 1 + localprops = [flp_style, flp_xscale] + end> + datacols.count = 2 + datacols.items = < + item[props] + linecolor = -1610612731 + linecolorfix = -1610612733 + colorselect = -1610612717 + coloractive = -1879048185 + width = 90 + onbeforedrawcell = befdrawcell + options = [co_readonly, co_drawfocus, co_mouseselect, co_keyselect, co_multiselect, co_proportional, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor] + widthmin = 10 + onshowhint = col0onshowhint + onselectionchanged = selchanged + widgetname = 'props' + dataclass = ttreeitemeditlist + end + item[values] + linecolorfix = -1610612733 + width = 148 + rowfontoffset = 4 + options = [co_fill, co_savestate] + options1 = [co1_rowfont, co1_zebracolor] + widthmin = 10 + oncellevent = valuescellevent + onshowhint = col1onshowhint + widgetname = 'values' + dataclass = titemeditlist + end> + datarowlinecolor = -1610612731 + datarowheight = 18 + statfile = mainfo.projectstatfile + onrowsdatachanged = gridrowsdatachanged + oncellevent = gridcellevent + drag.onbeforedragbegin = gridondragbegin + drag.onbeforedragover = gridondragover + drag.onbeforedragdrop = gridondragdrop + reffontheight = 16 + object props: ttreeitemedit + optionswidget1 = [ow1_autoheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_noskin] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + onpopup = propsonpopup + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 90 + bounds_cy = 18 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_resetselectonexit, oe_exitoncursor, oe_hintclippedtext, oe_locate] + onkeydown = propskeydownexe + onupdaterowvalues = propupdaterowvalue + options = [teo_treecolnavig, teo_keyrowmoving] + oncheckrowmove = propsoncheckrowmove + end + object values: tdropdownitemedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.button.width = 15 + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + width = 15 + color = -1879048187 + end + item + width = 15 + color = -1879048187 + imagenr = 17 + end> + taborder = 2 + onenter = valuesenterexe + visible = False + bounds_x = 91 + bounds_y = 0 + bounds_cx = 148 + bounds_cy = 18 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_forcereturncheckvalue, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_xscale] + onkeydown = valueskeydown + onclientmouseevent = valuesonmouseevent + onsetvalue = valuessetvalue + onpaintimage = paintimageexe + onextendimage = extendimageexe + onbuttonaction = valuesbuttonaction + onupdaterowvalues = valueupdaterowvalue + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + dropdown.dropdownrowcount = 16 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + onbeforedropdown = valuesbeforedropdown + reffontheight = 16 + end + end + object compedit: trichbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets, ow_disabledhint, ow_timedhint] + optionsskin = [osk_noface] + face.fade_pos.count = 2 + face.fade_pos.items = ( + 0 + 1 + ) + face.fade_color.count = 2 + face.fade_color.items = ( + 16760767 + 15571610 + ) + face.fade_direction = gd_down + face.localprops = [fal_fadirection] + hint = 'Show component editor.' + bounds_x = 217 + bounds_y = 2 + bounds_cx = 25 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localcaption, as_localhint, as_localonexecute] + facedisabled.localprops = [] + facedisabled.template = guitemplatesmo.fadevertkonvex + caption = '&ED' + onexecute = compeditonexecute + reffontheight = 16 + end + object findbu: tstockglyphbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 3 + bounds_x = 197 + bounds_y = 2 + bounds_cx = 18 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption, as_localimagelist, as_localimagenr] + glyph = stg_ellipsesmall + action = actionsmo.findcompallact + reffontheight = 16 + end + object gridpopup: tpopupmenu + onupdate = popupupdate + menu.submenu.count = 3 + menu.submenu.items = < + item + caption = 'Collapse tree' + state = [as_localcaption, as_localonexecute] + onexecute = collapseexe + end + item + caption = 'Revert to inherited' + name = 'revert' + state = [as_localcaption, as_localonexecute] + onexecute = revertexe + end + item + caption = 'Clear Selection' + name = 'clearselect' + state = [as_localcaption, as_localonexecute] + onexecute = clearselect + end> + left = 112 + top = 80 + end + object mainpopup: tpopupmenu + options = [mo_insertfirst, mo_shortcutright] + menu.submenu.count = 1 + menu.submenu.items = < + item + action = actionsmo.findcompallact + end> + left = 56 + top = 56 + end +end diff --git a/mseide-msegui/apps/ide/objectinspector.pas b/mseide-msegui/apps/ide/objectinspector.pas new file mode 100644 index 0000000..8071207 --- /dev/null +++ b/mseide-msegui/apps/ide/objectinspector.pas @@ -0,0 +1,2039 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit objectinspector; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseforms,msewidgets,msegrids,msewidgetgrid,classes,mclasses,mseclasses, + msepropertyeditors,mseglob,mseguiglob,msearrayutils,msedragglob,msegui,mseedit, + msedataedits,mselistbrowser,msedatanodes,msedesignintf,typinfo, + msecomponenteditors,msesimplewidgets,msegraphutils,msemenus,mseevent, + msedesigner,msetypes,msestrings,mselist,msegraphics; + +type + tobjectinspectorfo = class; + + tobjectinspectorselections = class(tdesignerselections) + private + fowner: tobjectinspectorfo; + protected + procedure compselectoronsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure dochanged; override; + public + constructor create(owner: tobjectinspectorfo); + end; + + tpropertyitem = class; + + tproppathinfo = class(ttreelistedititem) + private + fname: msestring; + procedure doexpand(const aitem: tpropertyitem); + public + constructor create(const aprop: tpropertyitem); reintroduce; + procedure save(const aprops: ttreeitemeditlist); + procedure restore(const aprops: ttreeitemeditlist); + end; + + compinfoty = record + instance: tcomponent; + proppathinfo: tproppathinfo; + actprop: msestringarty; + end; + pcompinfoty = ^compinfoty; + + tcomponentinfos = class(torderedrecordlist) + protected + function compare(const l,r): integer; + function getcomparefunc: sortcomparemethodty; override; + procedure finalizerecord(var item); override; + public + constructor create; + function find(const ainstance: tcomponent): integer; + function deleteitem(const ainstance: tcomponent): integer; + function getitem(ainstance: tcomponent): pcompinfoty; + function add(const aitem: compinfoty): integer; + end; + + tobjectinspectorfo = class(tdockform,iobjectinspector,idesignnotification) + compselector: tdropdownlistedit; + grid: twidgetgrid; + props: ttreeitemedit; + gridpopup: tpopupmenu; + values: tdropdownitemedit; + compedit: trichbutton; + findbu: tstockglyphbutton; + mainpopup: tpopupmenu; + procedure propsoncheckrowmove(const curindex: Integer; + const newindex: Integer; var accept: Boolean); + procedure createexe(const sender: TObject); + procedure gridrowsdatachanged(const sender: tcustomgrid; + const acell: gridcoordty; const count: integer); + procedure compselectorbeforedropdown(const sender: TObject); + procedure compselectoronsetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); + procedure valuesonmouseevent(const sender: twidget; var info: mouseeventinfoty); + procedure valuessetvalue(const sender: TObject; var avalue: mseString; + var accept: Boolean); + procedure gridcellevent(const sender: tobject; var info: celleventinfoty); + procedure valueupdaterowvalue(const sender: tobject; const aindex: integer; + const aitem: tlistitem); + procedure valuesbuttonaction(const sender: tobject; var action: buttonactionty; + const buttonindex: Integer); + procedure valuesbeforedropdown(const sender: TObject); + procedure compeditonexecute(const sender: tobject); + procedure gridondragbegin(const sender: tobject; const apos: pointty; + var dragobject: tdragobject; var processed: boolean); + procedure gridondragover(const sender: tobject; const apos: pointty; + var dragobject: tdragobject; var accept: boolean; var processed: boolean); + procedure gridondragdrop(const sender: tobject; const apos: pointty; + var dragobject: tdragobject; var processed: boolean); + procedure propsonpopup(const sender: tobject; var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); + procedure objectinspectorfoonloaded(const sender: tobject); + procedure objectinspectoronchildscaled(const sender: TObject); + procedure col0onshowhint(const sender: tdatacol; const arow: Integer; var info: hintinfoty); + procedure col1onshowhint(const sender: tdatacol; const arow: Integer; + var info: hintinfoty); + procedure valueskeydown(const sender: twidget; var info: keyeventinfoty); + procedure propupdaterowvalue(const sender: TObject; const aindex: integer; + const aitem: tlistitem); + procedure collapseexe(const sender: TObject); + procedure popupupdate(const sender: tcustommenu); + procedure revertexe(const sender: TObject); + procedure befdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure selchanged(const sender: tdatacol); + procedure clearselect(const sender: TObject); + procedure valuescellevent(const sender: TObject; var info: celleventinfoty); + procedure valuesenterexe(const sender: TObject); + procedure asyncexe(const sender: TObject; var atag: Integer); + procedure paintimageexe(const sender: twidget; const acanvas: tcanvas); + procedure extendimageexe(const sender: twidget; + const cellinfopo: pcellinfoty; var info: extrainfoty); + + procedure propskeydownexe(const sender: twidget; var ainfo: keyeventinfoty); + procedure enterexe(const sender: TObject); + private + factmodule: tmsecomponent; + factcomp: tcomponent; + flastcomp: tcomponent; + factcomps: componentarty; + fcomponentnames: componentnamearty; + fcomponentinfos: tcomponentinfos; + fchanging: integer; + frereadprops: boolean; + fsinglecomp: boolean; + function componentdispname(const instance: tcomponent): msestring; + procedure updatecomponentname; + procedure selectedcompchanged; + procedure propscreatenode(const sender: tcustomitemlist; + var node: ttreelistedititem); + procedure valuescreatenode(const sender: tcustomitemlist; + var node: tlistedititem); + procedure propnotification(const sender: tlistitem; var action: nodeactionty); + + procedure readprops(const module: tmsecomponent; const comp: componentarty); + procedure readprops(const module: tmsecomponent; const comp: tcomponent); + function editorstoprops(const editors: propertyeditorarty): treelistitemarty; + function candragsource(const apos: pointty; var row: integer): boolean; + function candragdest(const apos: pointty; var row: integer): boolean; + procedure rereadprops; + protected + procedure updatecompselection; + procedure updatedefaultstate(const aindex: integer); + procedure doasyncevent(var atag: integer); override; + function findvalueeditor(const editor: tpropertyeditor): integer; + function restoreactprop(const acomponent: tcomponent; + acol: integer; exact: boolean = false): boolean; + procedure saveproppath; + procedure clear; + function reviseproperties(const aprops: propertyeditorarty): propertyeditorarty; + procedure loaded; override; + procedure clearselectedprops(const aprop: tpropertyitem); + //clears editor selction of all nodes which are no siblings + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure refresh; + procedure clickedcomponentchanged(const aclickedcomp: tcomponent); + procedure showmethodsource(const aeditor: tmethodpropertyeditor); + function selectprop(const anamepath: msestringarty; + const acol: int32; const exact: boolean): boolean; + function selectprop(const acomponent: tobject; const apropname: string; + const aitemindex: int32): boolean; + procedure asyncactivate(); + + //idesignnotification + procedure itemdeleted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure iteminserted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure itemsmodified(const adesigner: idesigner; const aitem: tobject); + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure selectionchanged(const adesigner: idesigner; + const aselection: idesignerselections); + procedure moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + + //iobjectinspector + function getproperties(const objects: objectarty; const amodule: tmsecomponent; + const acomponent: tcomponent): propertyeditorarty; + procedure propertymodified(const sender: tpropertyeditor); + function getmatchingmethods(const sender: tpropertyeditor; + atype: ptypeinfo): msestringarty; + end; + + tpropertyitem = class(ttreelistedititem) + private + function getexpanded: boolean; + protected + feditor: tpropertyeditor; + procedure setexpanded(const Value: boolean) override; + procedure updatestate; + procedure updatesubpropertypath; + function finditembyname(const aname: msestring): tpropertyitem; + public + destructor destroy; override; + property expanded: boolean read getexpanded write setexpanded; + function rootpath: msestring; + end; + +var + objectinspectorfo: Tobjectinspectorfo; + +implementation +uses + objectinspector_mfm,sysutils,msearrayprops,actionsmodule,mseformatstr, + msebitmap,msedrag,mseeditglob,msestockobjects,msedropdownlist, + sourceupdate,sourceform,msekeyboard,main,msedatalist,msecolordialog; + +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + ado_rereadprops = 1; //asyncevent codes + ado_updatecomponentname = 2; + ado_compselection = 3; + ado_activate = 4; + selectcolor = cl_ltred; + +type + defaultmethodty = procedure of object; + + titemlist1 = class(tcustomitemlist); + tpropertyeditor1 = class(tpropertyeditor); + propertyitemarty = array of tpropertyitem; + + tpropertyvalue = class(tlistedititem) + protected + feditor: tpropertyeditor; + public + procedure updatestate(const exitrow: boolean = false); + end; + ppropertyvalue = ^tpropertyvalue; + +{ tproppathinfo } + +constructor tproppathinfo.create(const aprop: tpropertyitem); +var + int1: integer; +begin + inherited create; + if aprop <> nil then begin + fname:= aprop.feditor.name; + if aprop.expanded then begin + for int1:= 0 to aprop.fcount - 1 do begin + add(ttreelistedititem( + tproppathinfo.create(tpropertyitem(aprop[int1])))); + end; + end; + end; +end; + +procedure tproppathinfo.save(const aprops: ttreeitemeditlist); +var + int1: integer; +begin + clear; + for int1:= 0 to aprops.count - 1 do begin + self.add(ttreelistedititem( + tproppathinfo.create(tpropertyitem(aprops[int1])))); + end; +end; + +procedure tproppathinfo.doexpand(const aitem: tpropertyitem); +var + int1,int2: integer; + item1: tpropertyitem; +begin + if aitem.feditor <> nil then begin + try + aitem.expanded:= true; //else root item + except + aitem.expanded:= false; //probably multiselection with less items + exit; + end; + end; + for int1:= 0 to fcount - 1 do begin + with tproppathinfo(fitems[int1]) do begin + if fcount > 0 then begin + for int2:= 0 to aitem.count - 1 do begin + item1:= tpropertyitem(aitem[int2]); + if item1.feditor.name = fname then begin + doexpand(item1); + end; + end; + end; + end; + end; +end; + +procedure tproppathinfo.restore(const aprops: ttreeitemeditlist); +var + item1: tpropertyitem; +begin + item1:= tpropertyitem.create; + try + item1.assign(aprops); + doexpand(item1); + finally + item1.Free; + end; +end; + +{ tcomponentinfos } + +constructor tcomponentinfos.create; +begin + inherited create(sizeof(compinfoty),[rels_needsfinalize]); +end; + +function tcomponentinfos.compare(const l,r): integer; +begin + result:= pchar(compinfoty(l).instance) - pchar(compinfoty(r).instance); +end; + +function tcomponentinfos.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}compare; +end; + +procedure tcomponentinfos.finalizerecord(var item); +begin + finalize(compinfoty(item)); + with compinfoty(item) do begin + proppathinfo.free; + end; +end; + +function tcomponentinfos.find(const ainstance: tcomponent): integer; +var + info: compinfoty; +begin + info.instance:= ainstance; + result:= indexof(info); +end; + +function tcomponentinfos.deleteitem(const ainstance: tcomponent): integer; +begin + result:= find(ainstance); + delete(result); +end; + +function tcomponentinfos.add(const aitem: compinfoty): integer; +begin + result:= inherited add(aitem); +end; + +function tcomponentinfos.getitem(ainstance: tcomponent): pcompinfoty; +var + int1: integer; + info: compinfoty; +begin + int1:= find(ainstance); + if int1 < 0 then begin + fillchar(info,sizeof(info),0); + info.instance:= ainstance; + info.proppathinfo:= tproppathinfo.create(nil); + int1:= add(info); + end; + result:= getitempo(int1); +end; + +{ tobjectinspectorselections } + +constructor tobjectinspectorselections.create(owner: tobjectinspectorfo); +begin + fowner:= owner; + inherited create; +end; + +procedure tobjectinspectorselections.compselectoronsetvalue(const sender: TObject; + var avalue: Integer; var accept: Boolean); +begin +end; + +procedure tobjectinspectorselections.dochanged; +var + int1: integer; +begin + inherited; + with fowner.compselector.dropdown do begin + cols[0].clear; + for int1:= 0 to count-1 do begin + with itempo(int1)^ do begin + cols[0].add(msestring(designer.getcomponentdispname(instance))+ + ' ('+msestring(designer.getclassname(instance))+')'); + end; + end; + end; +end; + +{ tpropertyitem } + +destructor tpropertyitem.destroy; +begin + inherited; + if (feditor <> nil) and not (ps_owned in feditor.state) then begin + feditor.free; + end; +end; + +function tpropertyitem.getexpanded: boolean; +begin + result:= ps_expanded in feditor.state; +end; + +procedure tpropertyitem.setexpanded(const Value: boolean); +begin + inherited; +// inherited expanded:= value; + if value <> getexpanded then begin + feditor.expanded:= value; + updatestate; + end; +end; + +procedure tpropertyitem.updatestate; +var + stat1: propertystatesty; +begin + with feditor do begin + caption:= Name; + stat1:= state; + if ps_subproperties in stat1 then begin + if ps_expanded in stat1 then begin + fimagenr:= 1; + end + else begin + fimagenr:= 2; + end; + end + else begin + fimagenr:= -1; + end; + end; +end; + +procedure tpropertyitem.updatesubpropertypath; +begin + //dummy +end; + +function tpropertyitem.finditembyname(const aname: msestring): tpropertyitem; +var + int1: integer; + item1: tpropertyitem; +begin + result:= nil; + for int1:= 0 to fcount-1 do begin + item1:= tpropertyitem(fitems[int1]); + if item1.feditor.name = aname then begin + result:= item1; + break; + end; + end; +end; + +function tpropertyitem.rootpath: msestring; + +var + prop1: tpropertyitem; +begin + prop1:= self; + result:= ''; + while prop1 <> nil do begin + if (prop1.feditor is tarrayelementeditor) or + (prop1.feditor is tcollectionitemeditor) then begin + result:= '[]'+result; + end + else begin + if prop1.feditor is trecordpropertyeditor then begin + result:= '.'+prop1.feditor.propertyname+'_'+copy(result,2,bigint); + end + else begin + result:= '.'+prop1.feditor.propertyname+result; + end; + end; + prop1:= tpropertyitem(prop1.parent); + end; + result:= copy(result,2,bigint); +end; + +{ tpropertyvalue } + +procedure tpropertyvalue.updatestate(const exitrow: boolean = false); +begin + with feditor do begin + if allequal or + (not exitrow and (objectinspectorfo.values.item = self) and + (objectinspectorfo.grid.col = 1)) then begin + caption:= removelinebreaks(getvalue); + end + else begin + caption:= ''; + end; + end; +end; + +{ tobjectinspectorfo} + +constructor tobjectinspectorfo.create(aowner: tcomponent); +begin + fcomponentinfos:= tcomponentinfos.create; + inherited create(aowner); + designnotifications.Registernotification(idesignnotification(self)); +end; + +destructor tobjectinspectorfo.destroy; +begin + designnotifications.unRegisternotification(idesignnotification(self)); + inherited; + fcomponentinfos.Free; +end; + +procedure Tobjectinspectorfo.propscreatenode(const sender: tcustomitemlist; + var node: ttreelistedititem); +begin + node:= tpropertyitem.create(sender); +end; + +function tobjectinspectorfo.findvalueeditor(const editor: tpropertyeditor): integer; +var + int1: integer; + po1: ppropertyvalue; +begin + result:= -1; +{$warnings off} + po1:= ppropertyvalue(titemlist1(values.itemlist).fdatapo); +{$warnings on} + for int1:= 0 to values.itemlist.count - 1 do begin + if po1^.feditor = editor then begin + result:= int1; + break; + end; + inc(po1); + end; +end; + +procedure Tobjectinspectorfo.valuescreatenode( + const sender: tcustomitemlist; var node: tlistedititem); +begin + node:= tpropertyvalue.create(sender); +end; + +procedure tobjectinspectorfo.showmethodsource( + const aeditor: tmethodpropertyeditor); +begin + if aeditor.method.data <> nil then begin + sourcefo.showsourcepos(sourceupdater.findmethodpos(aeditor.method,true),true); + end; +end; + +procedure tobjectinspectorfo.valuesonmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + if sender.isdblclick(info) then begin + with tpropertyitem(props.item) do begin +// if feditor is tmethodpropertyeditor then begin + if not values.edited or values.checkvalue then begin + feditor.valueeditor.navigevent(); +// showmethodsource(tmethodpropertyeditor(feditor)); +// end; + end; + end; + end; +end; + +procedure tobjectinspectorfo.valuessetvalue(const sender: TObject; + var avalue: mseString; var accept: Boolean); +begin + try + tpropertyvalue(titemedit(sender).item).feditor.setvalue(avalue); + except + values.editor.undo; + raise; + end; + avalue:= tpropertyvalue(titemedit(sender).item).feditor.getvalue; +// mainfo.sourcechanged(nil); +end; + +procedure tobjectinspectorfo.propsoncheckrowmove(const curindex: Integer; + const newindex: Integer; var accept: Boolean); +var + editor1: tpropertyeditor; + bo1: boolean; +begin + //simulate dragevent + editor1:= tpropertyitem(props[curindex]).feditor; + editor1.dragbegin(bo1); + if bo1 then begin + with tpropertyitem(props[newindex]).feditor do begin + bo1:= false; + dragover(editor1,bo1); + if bo1 then begin + dragdrop(editor1); + grid.row:= newindex; + end; + end; + end; +end; + +procedure tobjectinspectorfo.createexe(const sender: TObject); +begin + props.itemlist.oncreateitem:= {$ifdef FPC}@{$endif}propscreatenode; + props.itemlist.onitemnotification:= {$ifdef FPC}@{$endif}propnotification; + values.itemlist.oncreateitem:= {$ifdef FPC}@{$endif}valuescreatenode; +end; + +procedure tobjectinspectorfo.gridrowsdatachanged(const sender: tcustomgrid; + const acell: gridcoordty; const count: integer); +var + int1: integer; +begin + props.itemlist.beginupdate; + values.itemlist.beginupdate; + try + for int1:= acell.row to acell.row + count - 1 do begin + tpropertyitem(props.itemlist[int1]).updatestate; + tpropertyvalue(values.itemlist[int1]).feditor:= + tpropertyitem(props.itemlist[int1]).feditor; + if not grid.cellexiting then begin + tpropertyvalue(values.itemlist[int1]).updatestate; + end; + end; + finally + props.itemlist.endupdate; + values.itemlist.endupdate; + end; +end; + +procedure tobjectinspectorfo.valuesenterexe(const sender: TObject); +begin + tpropertyvalue(values.item).updatestate; +end; + +procedure tobjectinspectorfo.moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + factmodule:= amodule; + caption:= actionsmo.c[ord(ac_objectinspector)] + ' (' + + msestring(amodule.Name)+')'; + updatecomponentname; +// clear; +end; + +procedure tobjectinspectorfo.moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + caption:= actionsmo.c[ord(ac_objectinspector)]; +// clear; + factmodule:= nil; +end; + +procedure tobjectinspectorfo.moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + //dummy +end; + +procedure tobjectinspectorfo.ItemDeleted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + if factcomp = aitem then begin + clear; + end; + if flastcomp = aitem then begin + flastcomp:= nil; + end; + fcomponentinfos.deleteitem(aitem); +end; + +procedure tobjectinspectorfo.ItemInserted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + //dummy; +end; + +function tobjectinspectorfo.reviseproperties( + const aprops: propertyeditorarty): propertyeditorarty; +var + int1,int2,int3,int4: integer; + str1: msestring; + edar1: propertyeditorarty; + amodule: tmsecomponent; + acomponent: tcomponent; +begin + result:= aprops; + if length(result) > 0 then begin + int2:= 0; + int3:= 1; + for int1:= 1 to high(result) do begin + if result[int1].name = result[int2].name then begin + result[int1].free; //remove duplicates + end + else begin + result[int3]:= result[int1]; + inc(int3); + int2:= int1; + end; + end; + setlength(result,int3); + with tpropertyeditor1(result[0]) do begin + amodule:= fmodule; + acomponent:= fcomponent; + end; + int1:= 0; + while int1 <= high(result) do begin + str1:= result[int1].name; +// int2:= msestrscan(str1,msechar('_')); + int2:= findchar(str1,msechar('_')); + if int2 > 0 then begin + int3:= int1+1; + while (int3 <= high(result)) and + (msestrlcomp(pmsechar(str1),pmsechar(result[int3].name),int2) = 0) do begin + inc(int3); + end; + setlength(edar1,int3-int1); + move(result[int1],edar1[0],length(edar1) * sizeof(edar1[0])); + inc(int2); + for int4:= 0 to high(edar1) do begin + tpropertyeditor1(edar1[int4]).fname:= + copy(tpropertyeditor1(edar1[int4]).fname,int2,bigint); + end; + fillchar(result[int1],length(edar1)*sizeof(result[0]),0); + result[int1]:= trecordpropertyeditor.create(designer,amodule,acomponent, + iobjectinspector(self),ansistring(copy(str1,1,int2-2)), + reviseproperties(edar1)); + int1:= int3; + end + else begin + inc(int1); + end; + end; + int2:= 0; + for int1:= 0 to high(result) do begin + if result[int1] <> nil then begin + result[int2]:= result[int1]; + inc(int2); + end; + end; + setlength(result,int2); + end; +end; + +function comparepropertyeditor(const l,r): integer; +begin + result:= tpropertyeditor(l).sortlevel - tpropertyeditor(r).sortlevel; + if result = 0 then begin +// result:= msecomparetext(tpropertyeditor(l).name,tpropertyeditor(r).name); + //has problems with underscores + result:= msestringicomp(tpropertyeditor(l).name,tpropertyeditor(r).name); + end; +end; + +function tobjectinspectorfo.getproperties(const objects: objectarty; + const amodule: tmsecomponent; + const acomponent: tcomponent): propertyeditorarty; +type + propinfopoararty = array of propinfopoarty; +var + ar1: propinfopoararty; + master: integer; + + function isok(const index: integer; var indexes: integerarty): boolean; + + function check(info: ppropinfo; ar: propinfopoarty; var foundindex: integer): boolean; + var + int1: integer; + kind: ttypekind; + typedata: ptypedata; + begin + result:= false; + kind:= info^.proptype^.Kind; + typedata:= gettypedata(info^.proptype{$ifndef FPC}^{$endif}); + for int1:= 0 to high(ar) do begin + if (ar[int1]^.proptype^.Kind = kind) and (info^.Name = ar[int1]^.Name) then begin + if not ((kind = tkset) and + (typedata^.comptype <> + gettypedata(ar[int1]^.proptype{$ifndef FPC}^{$endif})^.CompType) or + (kind = tkenumeration) and + (typedata^.basetype <> + gettypedata(ar[int1]^.proptype{$ifndef FPC}^{$endif})^.basetype)) then begin + foundindex:= int1; + result:= true; + break; + end; + end; + end; + end; + + var + int1: integer; + begin //isok + result:= true; + for int1:= 0 to high(ar1) do begin + if int1 <> master then begin + result:= check(ar1[master][index],ar1[int1],indexes[int1]); + if not result then begin + break; + end; + end + else begin + indexes[int1]:= index; + end; + end; + end; //isok + +var + ar2: propinfopoararty; + int1,int2,int3: integer; + propar: propinstancearty; + intar: integerarty; + +begin + result:= nil; + if (amodule <> nil) and (acomponent <> nil) and (high(objects) >= 0) then begin + setlength(ar1,length(objects)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= getpropinfoar(objects[int1]); + end; + if high(objects) > 0 then begin + master:= 0; + int2:= high(ar1[0]); + for int1:= 1 to high(ar1) do begin + if high(ar1[int1]) < int2 then begin + master:= int1; + int2:= high(ar1[int1]); + end; + end; + inc(int2); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + setlength(ar2[int1],int2); + end; + int2:= 0; + setlength(intar,length(ar1)); + for int1:= 0 to high(ar1[master]) do begin + if isok(int1,intar) then begin + for int3:= 0 to high(ar1) do begin + ar2[int3][int2]:= ar1[int3][intar[int3]]; + end; + inc(int2); + end; + end; + for int3:= 0 to high(ar1) do begin + setlength(ar2[int3],int2); + end; + end + else begin + ar2:= ar1; + int2:= length(ar2[0]); + end; + setlength(result,int2); + setlength(propar,length(objects)); + for int1:= 0 to high(propar) do begin + propar[int1].instance:= objects[int1]; + end; + for int1:= 0 to int2 - 1 do begin + for int3:= 0 to high(propar) do begin + propar[int3].propinfo:= ar2[int3][int1]; + end; + result[int1]:= propertyeditors.geteditorclass( + ar2[0][int1]^.proptype{$ifndef FPC}^{$endif}, + objects[0].ClassType,ar2[0][int1]^.Name).create( + designer,amodule,acomponent,iobjectinspector(self), + propar,ar2[0][int1]^.proptype{$ifndef FPC}^{$endif}); + end; + sortarray(pointerarty(result),{$ifdef FPC}@{$endif}comparepropertyeditor); + result:= reviseproperties(result); + end; +end; +{ +function tobjectinspectorfo.selectprop(const anamepath: msestringarty; + const acol: int32; const exact: boolean): boolean; +var + i1: integer; + item1,item2,item3: tpropertyitem; +begin + result:= false; + if anamepath <> nil then begin + item1:= tpropertyitem.create; + try + item1.assign(props.itemlist); + item2:= item1; + result:= true; + item3:= item2; //compiler warning + for i1:= 0 to high(anamepath) do begin + item3:= item2; + item2:= item2.finditembyname(anamepath[i1]); + if item2 = nil then begin + result:= not exact; + break; + end; + end; + if result then begin + if item2 = nil then begin + item2:= item3; + end; + grid.focuscell(makegridcoord(acol,item2.findex)); + end; + finally + item1.Free; + end; + end; +end; +} +function tobjectinspectorfo.selectprop(const anamepath: msestringarty; + const acol: int32; const exact: boolean): boolean; +var + i1: integer; + p1,pe,p2: ^tpropertyitem; + item1: tpropertyitem; +begin + result:= false; + if anamepath <> nil then begin + p1:= props.itemlist.datapo; + pe:= p1 + props.itemlist.count; + while p1 < pe do begin + if (p1^.treelevel = 0) and (p1^.caption = anamepath[0]) then begin + break; + end; + inc(p1); + end; + if p1 < pe then begin + result:= true; + item1:= p1^; + p1:= @item1; + for i1:= 1 to high(anamepath) do begin + p1^.expanded:= true; + p2:= p1; + p1:= pointer(p1^.fitems); + pe:= p1 + p2^.count; + while p1 < pe do begin + if p1^.fcaption = anamepath[i1] then begin + break; + end; + inc(p1); + end; + if p1 = pe then begin + result:= not exact; + if p1 <> nil then begin + dec(p1); + end; + break; + end; + end; + if p1 = nil then begin + result:= false; + end; + if result then begin + grid.focuscell(makegridcoord(acol,p1^.findex)); + end; + end; + end; +end; + +function tobjectinspectorfo.selectprop(const acomponent: tobject; + const apropname: string; const aitemindex: int32): boolean; +var + ar1: msestringarty; +begin + result:= false; + if (apropname <> '') and (factcomp = acomponent) then begin + setlength(ar1,1); + ar1[0]:= msestring(apropname); + if aitemindex >= 0 then begin + ar1[0]:= ar1[0]+'.count'; + setlength(ar1,2); + ar1[1]:= 'Item '+inttostrmse(aitemindex); //todo: use correct propertyname + end; + result:= selectprop(ar1,0,true); + end; +end; + +procedure tobjectinspectorfo.asyncactivate(); +begin + asyncevent(ado_activate,[peo_modaldefer]); +end; + +function tobjectinspectorfo.restoreactprop(const acomponent: tcomponent; + acol: integer; exact: boolean = false): boolean; +var + po1: pcompinfoty; +begin + result:= false; + if acomponent <> nil then begin + po1:= fcomponentinfos.getitempo(fcomponentinfos.find(acomponent)); + if po1 <> nil then begin + result:= selectprop(po1^.actprop,acol,exact); + end; + end; +end; + +procedure tobjectinspectorfo.readprops(const module: tmsecomponent; + const comp: componentarty); +var + po1: pcompinfoty; + acol: integer; + int1: integer; +begin + try + grid.canclose; //save pending edits + except + on e: exception do begin + grid.rowcount:= 0; + raise; + end; + end; + acol:= grid.col; + if acol < 0 then begin + acol:= 1; + end; + grid.rowcount:= 0; + if high(comp) >= 0 then begin + props.itemlist.Assign(listitemarty(editorstoprops( + getproperties(objectarty(comp),module,comp[0])))); + po1:= fcomponentinfos.getitempo(fcomponentinfos.find(comp[0])); + if (po1 = nil) and (flastcomp <> nil) then begin + po1:= fcomponentinfos.getitempo(fcomponentinfos.find(flastcomp)); + end; + if po1 <> nil then begin + po1^.proppathinfo.restore(props.itemlist); + end; + if not restoreactprop(flastcomp,acol,true) then begin + restoreactprop(comp[0],acol); + end; + for int1:= 0 to grid.rowhigh do begin + updatedefaultstate(int1); + end; + end; +end; + +procedure tobjectinspectorfo.readprops(const module: tmsecomponent; + const comp: tcomponent); +var + ar1: componentarty; +begin + setlength(ar1,1); + ar1[0]:= comp; + readprops(module,ar1); +end; + +function tobjectinspectorfo.editorstoprops( + const editors: propertyeditorarty): treelistitemarty; +var + int1: integer; +begin + setlength(result,length(editors)); + for int1:= 0 to high(result) do begin + result[int1]:= tpropertyitem.create; + with tpropertyitem(result[int1]) do begin + feditor:= editors[int1]; + feditor.expanded:= false; + fcaption:= feditor.name{.fprops[0].propinfo^.Name}; + if ps_subproperties in feditor.state then begin + state:= state + [ns_subitems]; + end; + end; + end; +end; + +procedure tobjectinspectorfo.rereadprops; +var + scrpos: integer; +begin + saveproppath; +// grid.beginupdate; + scrpos:= grid.frame.scrollpos_y; + try + grid.defocusrow; + readprops(factmodule,factcomps); + finally + frereadprops:= false; +// grid.endupdate; + end; + grid.frame.scrollpos_y:= scrpos; + grid.showcell(grid.focusedcell); +end; + +procedure tobjectinspectorfo.ItemsModified(const ADesigner: IDesigner; + const AItem: tobject); +begin + if (aitem = nil) or (aitem = factcomp) and (fchanging = 0) then begin + refresh; + end; +end; + +procedure tobjectinspectorfo.doasyncevent(var atag: integer); +begin + inherited; + case atag of + ado_rereadprops: begin + rereadprops; + end; + ado_updatecomponentname: begin + updatecomponentname; + end; + ado_activate: begin + activate(); + end; + end; +end; + +procedure tobjectinspectorfo.refresh; +begin + if not frereadprops and (fchanging = 0) then begin + asyncevent(ado_rereadprops,[peo_modaldefer]); + frereadprops:= true; + end; +end; + +procedure tobjectinspectorfo.propertymodified(const sender: tpropertyeditor); + + procedure compmodified; + var + int1: integer; + props1: propinstancearty; + comps: componentarty; + begin + props1:= nil; //compiler warning + inc(fchanging); + try + comps:= sender.propowner; + if length(comps) > 0 then begin + for int1:= 0 to high(comps) do begin + designer.componentmodified(comps[int1]); + end; + end + else begin + props1:= sender.rootprops; + for int1:= 0 to high(props1) do begin + designer.componentmodified(props1[int1].instance); + end; + end; + finally + dec(fchanging); + end; + end; + +var + po1,po2: tpropertyvalue; + int1,int2,int3: integer; + bo1: boolean; + +begin + designer.begincomponentmodify; + props.itemlist.beginupdate; + values.itemlist.beginupdate; + try + if ps_volatile in sender.state then begin + refresh; + compmodified; + end + else begin +// designer.begincomponentmodify; +// try + if (props.item <> nil) and + (tpropertyvalue(values.item).feditor = sender) then begin + po1:= tpropertyvalue(values.item); + end + else begin + int1:= findvalueeditor(sender); + if int1 >= 0 then begin + po1:= tpropertyvalue(values.itemlist[int1]); + end + else begin + po1:= nil; + end; + end; + if po1 <> nil then begin + po1.updatestate; + updatedefaultstate(po1.index); + bo1:= (ps_refreshall in sender.state); + for int1:= 0 to grid.rowcount - 1 do begin + po2:= tpropertyvalue(values[int1]); + if (po2 <> po1) and (bo1 or (ps_refresh in po2.feditor.state)) then begin + with tpropertyitem(props[int1]) do begin + if feditor <> nil then begin + feditor.updatedefaultvalue; + end; + end; + po2.updatestate; + updatedefaultstate(int1); + int3:= props[int1].treelevel; + for int2:= int1 + 1 to grid.rowcount - 1 do begin + if props[int2].treelevel <= int3 then begin + break; + end + else begin + tpropertyvalue(values[int2]).updatestate; + end; + end; + end; + end; + end; + compmodified; + end; + mainfo.sourcechanged(nil); + finally + props.itemlist.endupdate; + values.itemlist.endupdate; + designer.endcomponentmodify; + end; +end; + +procedure tobjectinspectorfo.clickedcomponentchanged( + const aclickedcomp: tcomponent); +begin + with compselector do begin + if fsinglecomp then begin + value:= componentdispname(factcomp); + end + else begin + if aclickedcomp <> nil then begin + value:= componentdispname(aclickedcomp); + end + else begin + value:= ''; + end; + end; + if focused then begin + initfocus; + end; + end; +end; + +procedure tobjectinspectorfo.updatecomponentname; +begin + clickedcomponentchanged(designer.clickedcomp); +end; + +function tobjectinspectorfo.componentdispname( + const instance: tcomponent): msestring; +begin + result:= ''; + if instance <> nil then begin + if (factmodule <> nil) and not factmodule.checkowned(instance) and + (factmodule <> instance) and (instance.owner <> nil) then begin + result:= msestring(instance.owner.name)+'.'; + end; + result:= result + msestring(designer.getcomponentdispname(instance)) + + ' (' + msestring(designer.getclassname(instance))+')'; + end; +end; + +procedure tobjectinspectorfo.compselectorbeforedropdown( + const sender: TObject); +var + po1: pmoduleinfoty; + int1,int2: integer; + str1: msestring; +begin + with compselector,dropdown do begin + str1:= text; + cols.clear; + if factmodule <> nil then begin + int2:= -1; + po1:= designer.modules.findmodulebyinstance(factmodule); + if po1 <> nil then begin + fcomponentnames:= po1^.components.getdispnames; + cols[0].count:= po1^.components.count; + for int1:= 0 to cols[0].count-1 do begin + with fcomponentnames[int1] do begin + cols[0][int1]:= msestring(dispname) + ' (' + + msestring(designer.getclassname(instance))+')'; + if cols[0][int1] = str1 then begin + int2:= int1; + end; + end; + end; + itemindex:= int2; + end; + end; + text:= str1; + if editor.sellength > 0 then begin + editor.selectall; + end + else begin + editor.curindex:= length(str1); + end; + end; +end; + +procedure tobjectinspectorfo.updatecompselection; +var + comp1: tcomponent; +begin + comp1:= factcomp; + with compselector.dropdown do begin + if itemindex < 0 then begin + clear; + factcomp:= nil; + end + else begin + factcomp:= fcomponentnames[itemindex].instance; + end; + end; + if comp1 <> factcomp then begin + selectedcompchanged; + end; +end; + +procedure tobjectinspectorfo.compselectoronsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + asyncevent(ado_compselection); +end; + +procedure tobjectinspectorfo.SelectionChanged(const ADesigner: IDesigner; + const ASelection: IDesignerSelections); +begin + saveproppath; + with aselection do begin + if count > 0 then begin + factcomp:= items[0]; + end + else begin + factcomp:= nil; + end; + factcomps:= getarray; + if count = 1 then begin + fsinglecomp:= true; + updatecomponentname; + readprops(factmodule,factcomp); + end + else begin + fsinglecomp:= false; + updatecomponentname; +// compselector.value:= ''; + readprops(factmodule,factcomps); + end; + inc(fchanging); + try + selectedcompchanged; + finally + dec(fchanging); + end; + end; +end; + +procedure tobjectinspectorfo.selectedcompchanged; +begin + if fchanging = 0 then begin + designer.selectcomponent(factcomp); + end; + compedit.enabled:= designer.componentcanedit; +end; + +procedure tobjectinspectorfo.saveproppath; +var + po1: pcompinfoty; +begin + if (factcomp <> nil) and (props.itemlist.count > 0) then begin + po1:= fcomponentinfos.getitem(factcomp); + po1^.proppathinfo.save(props.itemlist); + if props.item <> nil then begin + po1^.actprop:= props.item.rootcaptions; + end; + flastcomp:= factcomp; + end; +end; + +procedure tobjectinspectorfo.clear; +begin + saveproppath; + compselector.value:= ''; + grid.clear; +// values.itemlist.clear; + frereadprops:= false; +end; + +procedure tobjectinspectorfo.loaded; +begin + inherited; + clear; +end; + +procedure tobjectinspectorfo.propnotification(const sender: tlistitem; + var action: nodeactionty); +begin + with tpropertyitem(sender) do begin + case action of + na_expand: begin + feditor.expanded:= true; + if count = 0 then begin + add(editorstoprops(feditor.subproperties)); + end; + end; + na_collapse: begin + feditor.expanded:= false; + end; + end; + end; +end; + +procedure tobjectinspectorfo.gridcellevent(const sender: tobject; + var info: celleventinfoty); +begin + if isrowenter(info) then begin + values.itemlist.beginupdate; + try + with tpropertyvalue(values.item) do begin + if ps_valuelist in feditor.state then begin + values.dropdown.options:= values.dropdown.options - [deo_disabled]; + end + else begin + values.dropdown.options:= values.dropdown.options + [deo_disabled]; + end; + values.frame.buttons[1].visible:= ps_dialog in feditor.state; + end; + finally + values.itemlist.decupdate; + end; + tpropertyitem(props.item).feditor.focused(); +// tpropertyvalue(values[info.cellbefore.row]).updatestate(false); + end + else begin + if not frereadprops and isrowexit(info,true) and + (info.cellbefore.row < grid.rowcount) then begin + tpropertyvalue(values[info.cellbefore.row]).updatestate(true); + end; + end; +end; + +procedure tobjectinspectorfo.valuesbuttonaction(const sender: tobject; + var action: buttonactionty; const buttonindex: Integer); +begin + with titemedit(sender) do begin + if action = ba_click then begin + case buttonindex of + 1: begin + tpropertyvalue(item).feditor.edit; + end; + end; + end; + end; +end; + +procedure tobjectinspectorfo.valueskeydown(const sender: twidget; + var info: keyeventinfoty); +begin + if isenterkey(nil,info.key) and (info.shiftstate = []) and + not values.edited then begin + with tpropertyvalue(values.item),feditor do begin + if ps_dialog in state then begin + include(info.eventstate,es_processed); + edit; + end + else begin + feditor.valueeditor.navigevent(); + { + if (feditor is tmethodpropertyeditor) then begin + showmethodsource(tmethodpropertyeditor(feditor)); + end; + } + end; + end; + end; +end; + +procedure tobjectinspectorfo.valuesbeforedropdown(const sender: TObject); +begin + with tdropdownitemedit(sender) do begin + dropdown.cols.clear; + with tpropertyvalue(item).feditor do begin + if ps_sortlist in state then begin + dropdown.options:= dropdown.options + [deo_sorted]; + end + else begin + dropdown.options:= dropdown.options - [deo_sorted]; + end; + dropdown.cols[0].asarray:= getvalues; + end; + end; +end; + +procedure tobjectinspectorfo.propupdaterowvalue(const sender: TObject; + const aindex: Integer; const aitem: tlistitem); +begin + updatedefaultstate(aindex); +end; + +procedure tobjectinspectorfo.valueupdaterowvalue(const sender: tobject; + const aindex: integer; const aitem: tlistitem); +begin + if (aitem <> nil) and (tpropertyvalue(aitem).feditor <> nil) then begin + with tpropertyvalue(aitem).feditor do begin + if (aindex = values.activerow) or allequal then begin + aitem.caption:= removelinebreaks(getvalue); + end + else begin + aitem.caption:= ''; + end; + end; + end; +end; + +procedure tobjectinspectorfo.updatedefaultstate(const aindex: integer); +type + fontmarkty = (modified,iscomponent,issubproperty); + fontmarksty = set of fontmarkty; +var + mark: fontmarksty; +const + marktable: array[0..7] of integer = ( + //issubbroperty iscomponent modified + -1, // 0 0 0 + 0, // 0 0 1 + 3, // 0 1 0 + -1, // 0 1 1 invalid + 2, // 1 0 0 + 1, // 1 0 1 + 2, // 1 1 0 + -1 // 1 1 1 invalid + ); +begin + with tpropertyvalue(values[aindex]) do begin + if feditor <> nil then begin + mark:= []; + if ps_modified in feditor.state then begin + include(mark,modified); + end; + if ps_component in feditor.state then begin + include(mark,iscomponent); + end; + if ps_subprop in feditor.state then begin + include(mark,issubproperty); + end; + grid.rowfontstate[aindex]:= marktable[ + {$ifdef FPC}longword{$else}byte{$endif}(mark)]; + if feditor.sortlevel > 0 then begin + grid.rowcolorstate[aindex]:= 0; + end + else begin + grid.rowcolorstate[aindex]:= -1; + end; + end; + end; +end; + +procedure tobjectinspectorfo.componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); +begin + if factcomp = aitem then begin + asyncevent(ado_updatecomponentname); + end; +end; + +procedure tobjectinspectorfo.moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin + if factcomp = amodule then begin + asyncevent(ado_updatecomponentname); + end; +end; + +procedure tobjectinspectorfo.instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin + //dummy +end; + +procedure init; +begin + registerpropertyeditor(typeinfo(integer),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(longint),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(longword),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(word),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(byte),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(int64),nil,'',tint64propertyeditor); + registerpropertyeditor(typeinfo(uint64),nil,'',tint64propertyeditor); + registerpropertyeditor(typeinfo(currency),nil,'',tcurrencypropertyeditor); + registerpropertyeditor(typeinfo(real),nil,'',trealpropertyeditor); + registerpropertyeditor(typeinfo(double),nil,'',trealpropertyeditor); + registerpropertyeditor(typeinfo(realty),nil,'',trealtypropertyeditor); + registerpropertyeditor(typeinfo(tdatetime),nil,'',tdatetimepropertyeditor); + registerpropertyeditor(typeinfo(variant),nil,'',tvariantpropertyeditor); + registerpropertyeditor(typeinfo(char),nil,'',tcharpropertyeditor); + registerpropertyeditor(typeinfo(widechar),nil,'',twidecharpropertyeditor); + registerpropertyeditor(typeinfo(defaultenumerationty),nil,'',tenumpropertyeditor); + {$ifdef FPC} + registerpropertyeditor(typeinfo(boolean),nil,'',tbooleanpropertyeditor); //for fpc + {$endif} + registerpropertyeditor(typeinfo(string),nil,'',tstringpropertyeditor); + registerpropertyeditor(typeinfo(utf8string),nil,'',tutf8stringpropertyeditor); + registerpropertyeditor(typeinfo(string),tcomponent,'Name',tnamepropertyeditor); + registerpropertyeditor(typeinfo(msestring),nil,'',tmsestringpropertyeditor); + registerpropertyeditor(typeinfo(colorty),nil,'',tcolorpropertyeditor); +// registerpropertyeditor(typeinfo(msechar),nil,'',tmsestringpropertyeditor); + //??? + registerpropertyeditor({$ifdef FPC}tpersistent.classinfo{$else}typeinfo(tpersistent){$endif}, + nil,'',tclasspropertyeditor); + registerpropertyeditor(tparentfont.classinfo,nil,'',tparentfontpropertyeditor); + + registerpropertyeditor(tcomponent.classinfo,nil,'',tcomponentpropertyeditor); + registerpropertyeditor(typeinfo(defaultmethodty),nil,'',tmethodpropertyeditor); + registerpropertyeditor(typeinfo(defaultsetty),nil,'',tsetpropertyeditor); + registerpropertyeditor(tarrayprop.classinfo,nil,'',tarraypropertyeditor); + registerpropertyeditor(tpersistentarrayprop.classinfo,nil,'', + tpersistentarraypropertyeditor); + registerpropertyeditor(tintegerarrayprop.classinfo,nil,'', + tintegerarraypropertyeditor); + registerpropertyeditor(tsetarrayprop.classinfo,nil,'', + tsetarraypropertyeditor); + registerpropertyeditor(tcolorarrayprop.classinfo,nil,'', + tcolorarraypropertyeditor); + registerpropertyeditor(trealarrayprop.classinfo,nil,'', + trealarraypropertyeditor); + registerpropertyeditor(tstringarrayprop.classinfo,nil,'', + tstringarraypropertyeditor); + registerpropertyeditor(tmsestringarrayprop.classinfo,nil,'', + tmsestringarraypropertyeditor); + registerpropertyeditor(tmaskedbitmap.classinfo,nil,'',tbitmappropertyeditor); + registerpropertyeditor(tstrings.classinfo,nil,'',tstringspropertyeditor); + registerpropertyeditor(tmsestringdatalist.classinfo,nil,'', + tmsestringdatalistpropertyeditor); + registerpropertyeditor(tdoublemsestringdatalist.classinfo,nil,'', + tdoublemsestringdatalistpropertyeditor); + registerpropertyeditor(typeinfo(tmsestringintdatalist),nil,'', + tmsestringintdatalistpropertyeditor); + registerpropertyeditor(tdatalist.classinfo,nil,'',tdatalistpropertyeditor); +{ + info.editorclass:= timagelisteditor; + info.propertytype:= typeinfo(timagelist);//tobject.classinfo; + apropertyeditors.adddata(info); +} + registercomponenteditor(tcomponent,tcomponenteditor); + registercomponenteditor(timagelist,timagelisteditor); +end; + +procedure tobjectinspectorfo.compeditonexecute(const sender: tobject); +begin + designer.getcomponenteditor.edit; +end; + +function tobjectinspectorfo.candragsource(const apos: pointty; var row: integer): boolean; +var + widget1: twidget; + cell: gridcoordty; +begin + widget1:= grid.editwidgetatpos(apos,cell); + row:= cell.row; + if (widget1 = props) and (not values.edited or values.checkvalue) then begin + result:= props.candragsource(translateclientpoint(apos,grid,widget1)); + end + else begin + result:= false; + end; +end; + +function tobjectinspectorfo.candragdest(const apos: pointty; var row: integer): boolean; +var + widget1: twidget; + cell: gridcoordty; +begin + widget1:= grid.editwidgetatpos(apos,cell); + row:= cell.row; + result:= widget1 = props; +end; + +procedure tobjectinspectorfo.gridondragbegin(const sender: tobject; + const apos: pointty; var dragobject: tdragobject; var processed: boolean); +var + row: integer; + bo1: boolean; +begin + if candragsource(apos,row) then begin + bo1:= false; + tpropertyitem(props[row]).feditor.dragbegin(bo1); + if bo1 then begin + tobjectdragobject.create(sender,dragobject,nullpoint, + tpropertyitem(props[row]).feditor); + end; + end; +end; + +procedure tobjectinspectorfo.gridondragdrop(const sender: tobject; + const apos: pointty; var dragobject: tdragobject; var processed: boolean); +var + row: integer; +begin + if candragdest(apos,row) then begin + tpropertyitem(props[row]).feditor.dragdrop( + tpropertyeditor(tobjectdragobject(dragobject).data)); + grid.row:= row; + end; +end; + +procedure tobjectinspectorfo.gridondragover(const sender: tobject; + const apos: pointty; var dragobject: tdragobject; + var accept: boolean; var processed: boolean); +var + row: integer; +begin + if candragdest(apos,row) then begin + tpropertyitem(props[row]).feditor.dragover( + tpropertyeditor(tobjectdragobject(dragobject).data),accept); + end; +end; + +procedure tobjectinspectorfo.propsonpopup(const sender: tobject; + var amenu: tpopupmenu; var mouseinfo: mouseeventinfoty); +begin + tpropertyitem(props.item).feditor.dopopup(amenu,props,mouseinfo); +end; + +procedure tobjectinspectorfo.propskeydownexe(const sender: twidget; + var ainfo: keyeventinfoty); +begin + tpropertyitem(props.item).feditor.dokeydown(ainfo); +end; + +procedure tobjectinspectorfo.objectinspectorfoonloaded(const sender: tobject); +begin + grid.top:= compselector.bottom + 1; + grid.height:= height-grid.top; +// compedit.width:= compedit.height+6; +// compedit.left:= compedit.right - compedit.height-; + findbu.right:= compedit.left; + compselector.right:= findbu.left - 1; +// with values.frame.buttons[0] do begin +// imagelist:= stockobjects.glyphs; +// imagenr:= ord(stg_ellipsesmall); +// end; +end; + +procedure tobjectinspectorfo.methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; const aname: string; + const atype: ptypeinfo); +begin + //dummy +end; + +function tobjectinspectorfo.getmatchingmethods( + const sender: tpropertyeditor; atype: ptypeinfo): msestringarty; +var + ar1: componentarty; + int1,int2: integer; + mstr1: msestring; +begin + ar1:= designer.descendentinstancelist.getancestors(sender.module); + additem(pointerarty(ar1),sender.module); + result:= nil; + for int1:= 0 to high(ar1) do begin + stackarray(sourceupdater.getmatchingmethods(tmsecomponent(ar1[int1]),atype), + result); + end; + for int1:= 0 to high(result) do begin + mstr1:= struppercase(result[int1]); + for int2:= int1 + 1 to high(result) do begin + if msestringicompupper(result[int2],mstr1) = 0 then begin + result[int2]:= ''; + end; + end; + end; + result:= packarray(result); +end; + +procedure tobjectinspectorfo.methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; const newname, oldname: string; const atypeinfo: ptypeinfo); +begin + //dummy +end; + +procedure tobjectinspectorfo.showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); +begin + //dummy +end; + +procedure tobjectinspectorfo.closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); +begin + //dummy +end; + +procedure tobjectinspectorfo.objectinspectoronchildscaled(const sender: TObject); +begin + placeyorder(0,[2],[compselector,grid]); + aligny(wam_center,[compselector,findbu,compedit]); +end; + +procedure tobjectinspectorfo.col0onshowhint(const sender: tdatacol; + const arow: Integer; var info: hintinfoty); +begin + if (props[arow] <> nil) and props[arow].captionclipped then begin + info.caption:= props[arow].caption; + end; +end; + +procedure tobjectinspectorfo.col1onshowhint(const sender: tdatacol; + const arow: Integer; var info: hintinfoty); +begin + if (values[arow] <> nil) and values[arow].captionclipped then begin + info.caption:= values[arow].caption; + end; +end; + +procedure tobjectinspectorfo.collapseexe(const sender: TObject); +var + int1: integer; +begin + for int1:= grid.rowhigh downto 0 do begin + props[int1].expanded:= false; + end; +end; + +procedure tobjectinspectorfo.beforemake(const adesigner: idesigner; + const maketag: integer; var abort: boolean); +begin + //dummy +end; + +procedure tobjectinspectorfo.aftermake(const adesigner: idesigner; + const exitcode: integer); +begin + //dummy +end; + +procedure tobjectinspectorfo.beforefilesave(const adesigner: idesigner; + const afilename: filenamety); +begin + //dummy +end; + +procedure tobjectinspectorfo.popupupdate(const sender: tcustommenu); +begin + with sender.menu.itembyname('revert') do begin + enabled:= (props.item <> nil) and (tpropertyitem(props.item).feditor <> nil) and + tpropertyitem(props.item).feditor.canrevert; + end; + sender.menu.itembyname('clearselect').enabled:= + grid.datacols[0].selectedcellcount > 0; +end; + +procedure tobjectinspectorfo.revertexe(const sender: TObject); +var + comp1: tcomponent; +begin + with tpropertyitem(props.item).feditor do begin + comp1:= designer.findancestorcomponent(component); + if comp1 <> nil then begin + copyproperty(comp1); + end; + end; +end; + +procedure tobjectinspectorfo.befdrawcell(const sender: tcol; + const canvas: tcanvas; var cellinfo: cellinfoty; + var processed: Boolean); +var + editor1: tpropertyeditor; +begin +exit; + editor1:= tpropertyitem(cellinfo.datapo^).feditor; + if (editor1 <> nil) and editor1.selected then begin + cellinfo.color:= selectcolor; + end; +end; + +procedure tobjectinspectorfo.clearselectedprops(const aprop: tpropertyitem); + //clears editor selction of all nodes which are no siblings + procedure doclear(const prop: tpropertyitem); + var + int1: integer; + begin + if (aprop = nil) or (prop.parent <> aprop.parent) then begin + prop.feditor.selected:= false; + end; + for int1:= 0 to prop.count-1 do begin + doclear(tpropertyitem(prop[int1])); + end; + end; +var + int1: integer; +begin + for int1:= 0 to grid.rowhigh do begin + if props[int1].parent = nil then begin + doclear(tpropertyitem(props[int1])); + end; + end; + grid.datacols[0].invalidate; +end; + +procedure tobjectinspectorfo.selchanged(const sender: tdatacol); +var + ar1: integerarty; + int1: integer; +begin + sender.grid.beginupdate; + ar1:= sender.selectedcells; + clearselectedprops(nil); + if props.item <> nil then begin + for int1:= 0 to high(ar1) do begin + tpropertyitem(props[ar1[int1]]).feditor.selected:= true; + end; + clearselectedprops(tpropertyitem(props.item)); + for int1:= 0 to high(ar1) do begin + if not tpropertyitem(props[ar1[int1]]).feditor.selected then begin + sender.selected[ar1[int1]]:= false; + end; + end; + end; + sender.grid.endupdate; +end; + +procedure tobjectinspectorfo.clearselect(const sender: TObject); +begin + grid.datacols[0].clearselection; +end; + +procedure tobjectinspectorfo.valuescellevent(const sender: TObject; + var info: celleventinfoty); +var + comp1: tcomponent; +begin + if iscellclick(info,[ccr_dblclick,ccr_nokeyreturn]) then begin + comp1:= tpropertyitem(props.item).feditor.linkcomponent; + if comp1 <> nil then begin + designer.showformdesigner(designer.modules.findmodulebycomponent(comp1)); + designer.selectcomponent(comp1); + end; + end; +end; + +procedure tobjectinspectorfo.asyncexe(const sender: TObject; var atag: Integer); +begin + case atag of + ado_compselection: begin + updatecompselection; + end; + end; +end; + +var + wascolorprop: boolean; + propcolor: colorty; + +function iscolorprop(const sender: twidget; const cellinfopo: pcellinfoty; + out acolor: colorty): boolean; + +var + propval: tpropertyvalue; +begin + if cellinfopo = nil then begin + propval:= tpropertyvalue(titemedit(sender).item); + end + else begin + pointer(propval):= ppointer(cellinfopo^.datapo)^; + end; + result:= (propval.feditor.typinfo = typeinfo(colorty)) and + propval.feditor.allequal; + if result then begin + acolor:= tpropertyeditor1(propval.feditor).getordvalue; + end; +end; + +procedure tobjectinspectorfo.paintimageexe(const sender: twidget; + const acanvas: tcanvas); +begin + if wascolorprop then begin + paintcolorimage(sender,acanvas,propcolor); + end; +end; + +procedure tobjectinspectorfo.extendimageexe(const sender: twidget; + const cellinfopo: pcellinfoty; var info: extrainfoty); +begin + wascolorprop:= iscolorprop(sender,cellinfopo,propcolor); + if wascolorprop then begin + info.image.cx:= info.image.cx+sender.clientheight; + end; +end; + +procedure tobjectinspectorfo.enterexe(const sender: TObject); +begin + mainfo.designformactivated(self); +end; + +initialization + init; +end. diff --git a/mseide-msegui/apps/ide/objectinspector_mfm.pas b/mseide-msegui/apps/ide/objectinspector_mfm.pas new file mode 100644 index 0000000..ba2a433 --- /dev/null +++ b/mseide-msegui/apps/ide/objectinspector_mfm.pas @@ -0,0 +1,457 @@ +unit objectinspector_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,objectinspector; + +const + objdata: record size: integer; data: array[0..8790] of byte end = + (size: 8791; data: ( + 84,80,70,48,18,116,111,98,106,101,99,116,105,110,115,112,101,99,116,111, + 114,102,111,17,111,98,106,101,99,116,105,110,115,112,101,99,116,111,114,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99, + 117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105, + 110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101, + 2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110, + 115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111, + 95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108, + 111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116, + 111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116, + 111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103, + 111,95,98,117,116,116,111,110,104,105,110,116,115,0,9,112,111,112,117,112, + 109,101,110,117,7,9,109,97,105,110,112,111,112,117,112,7,111,110,101,110, + 116,101,114,7,8,101,110,116,101,114,101,120,101,10,111,110,97,99,116,105, + 118,97,116,101,7,8,101,110,116,101,114,101,120,101,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,185,0,8,98,111,117,110, + 100,115,95,121,3,104,1,9,98,111,117,110,100,115,95,99,120,3,254,0, + 9,98,111,117,110,100,115,95,99,121,3,248,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,18,99,111,110,116,97,105,110, + 101,114,46,111,110,108,97,121,111,117,116,7,28,111,98,106,101,99,116,105, + 110,115,112,101,99,116,111,114,111,110,99,104,105,108,100,115,99,97,108,101, + 100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,244,0,3,248,0,0,22,100,114,97,103,100,111,99,107,46, + 115,112,108,105,116,116,101,114,95,115,105,122,101,2,0,16,100,114,97,103, + 100,111,99,107,46,99,97,112,116,105,111,110,6,15,79,98,106,101,99,116, + 105,110,115,112,101,99,116,111,114,20,100,114,97,103,100,111,99,107,46,111, + 112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112, + 111,115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95, + 99,97,110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10, + 111,100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111,112,115,105, + 122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,13,111,100, + 95,99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105,111,110,115, + 11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101, + 122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0, + 8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114, + 111,106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112,116,105,111, + 110,6,16,79,98,106,101,99,116,32,73,110,115,112,101,99,116,111,114,21, + 105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103,101,10,172,7, + 0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,120,7, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235, + 235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,217,238,240,1,174,238,243,1,142,237,245,1,158,236, + 242,1,197,233,236,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,239,242,242,1,160,239, + 247,1,96,240,255,2,87,240,255,1,68,239,255,1,40,238,255,1,97,235, + 245,1,217,230,231,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215, + 215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,155,241,249,1,116,241,255,1,138,241,255,1,144,242, + 255,1,131,241,255,1,106,240,255,1,72,239,255,1,34,238,255,1,56,221, + 234,1,225,226,226,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,207,243, + 246,1,112,241,255,1,150,242,255,1,181,243,255,1,191,243,255,1,172,242, + 255,1,136,241,255,1,96,240,255,1,54,239,255,1,13,238,255,1,85,173, + 180,1,221,221,221,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,161,241,249,1,124,241, + 255,1,169,242,255,1,208,244,255,1,208,248,255,1,197,243,255,1,152,242, + 255,1,107,240,255,1,62,239,255,1,17,238,255,1,42,194,205,1,150,150, + 150,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,132,240,251,1,119,241,255,1,162,242, + 255,1,200,243,255,1,208,245,255,1,187,243,255,1,147,242,255,1,104,240, + 255,1,59,239,255,1,15,238,255,1,29,214,228,1,102,102,102,1,212,212, + 212,1,223,223,223,1,221,221,221,1,219,219,219,1,211,211,219,1,216,216, + 216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,154,241,249,1,99,240,255,1,134,241,255,1,160,242, + 255,1,168,242,255,1,152,242,255,1,122,241,255,1,85,240,255,1,45,239, + 255,1,13,238,255,1,44,192,203,1,102,102,102,1,186,186,186,1,223,223, + 223,1,221,221,221,1,171,171,227,1,91,91,240,1,216,216,216,1,215,215, + 215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,204,242,245,1,71,239,255,1,97,240,255,1,115,241,255,1,120,241, + 255,1,110,240,255,1,87,240,255,1,57,239,255,1,22,238,255,1,13,238, + 255,1,70,151,157,1,102,102,102,1,188,188,188,1,223,223,223,1,221,221, + 221,1,55,55,247,1,7,7,254,1,154,154,193,1,214,214,214,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,135,240,249,1,54,239,255,1,69,239,255,1,72,239,255,1,65,239, + 255,1,47,239,255,1,22,238,255,1,13,238,255,1,41,197,209,1,102,102, + 102,2,213,213,213,1,223,223,223,1,154,154,232,1,4,4,255,2,36,36, + 208,1,171,171,171,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,241,242,242,1,118,211,218,1,26,230, + 246,1,24,238,255,1,18,238,255,1,13,238,255,1,15,236,253,1,56,176, + 185,1,99,107,108,1,102,102,102,1,155,155,155,1,224,224,224,1,220,220, + 223,1,38,38,250,1,4,4,255,3,86,86,144,1,209,209,209,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,159,170,171,1,84,141,145,1,67,161,168,1,79,144, + 149,1,97,117,118,1,104,104,104,1,103,103,103,1,139,139,139,1,222,222, + 222,1,224,224,224,1,136,136,236,1,4,4,255,4,25,25,220,1,159,159, + 159,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,207,207,207,1,150,150, + 150,1,124,124,124,1,118,118,118,1,143,143,143,1,186,186,186,1,227,227, + 227,1,226,226,226,1,214,214,225,1,26,26,252,1,4,4,255,5,72,72, + 153,1,203,203,203,1,210,210,210,1,208,208,208,1,245,245,245,1,247,155, + 167,1,249,121,137,1,248,120,136,1,247,119,135,1,246,118,134,1,245,117, + 133,2,244,116,132,1,243,115,131,1,234,186,192,1,227,227,227,1,226,226, + 226,1,116,116,239,1,4,4,255,6,17,17,231,1,145,145,149,1,210,210, + 210,1,208,208,208,1,245,245,245,1,252,68,91,1,255,0,32,8,239,143, + 155,1,227,227,227,1,207,207,229,1,15,15,253,1,4,4,255,7,60,60, + 163,1,196,196,196,1,208,208,208,1,245,245,245,1,252,68,91,1,255,0, + 32,8,160,64,76,1,118,118,118,1,97,97,243,1,4,4,255,8,13,13, + 241,1,130,130,142,1,208,208,208,1,245,245,245,1,252,68,91,1,255,0, + 32,8,160,64,76,1,117,117,120,1,120,120,240,1,114,114,240,1,65,65, + 191,1,52,52,178,1,51,51,177,2,50,50,176,3,49,49,175,1,79,79, + 124,1,187,187,187,1,245,245,245,1,252,68,91,1,255,0,32,8,160,64, + 76,1,118,118,118,1,226,226,226,1,184,184,184,1,101,101,101,1,100,100, + 100,1,99,99,99,1,98,98,98,1,97,97,97,2,96,96,96,1,95,95, + 95,2,125,125,125,1,245,245,245,1,252,68,91,1,255,0,32,8,160,64, + 76,1,118,118,118,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,252,68, + 91,1,255,0,32,8,160,64,76,1,118,118,118,1,226,226,226,1,224,224, + 224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216, + 216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,252,68,91,1,255,0,32,8,160,64,76,1,118,118, + 118,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,252,68,91,1,255,0, + 32,8,160,64,76,1,118,118,118,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215, + 215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,247,155,167,1,236,108,124,1,182,54,70,1,181,53,69,4,180,52, + 68,2,132,84,90,1,118,118,118,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215, + 215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,217,217,217,1,108,108,108,1,107,107,107,2,106,106, + 106,2,105,105,105,1,104,104,104,1,103,103,103,1,118,118,118,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,8,111,110,99,114,101,97,116,101,7,9,99,114,101, + 97,116,101,101,120,101,16,111,110,101,118,101,110,116,108,111,111,112,115,116, + 97,114,116,7,25,111,98,106,101,99,116,105,110,115,112,101,99,116,111,114, + 102,111,111,110,108,111,97,100,101,100,12,111,110,97,115,121,110,99,101,118, + 101,110,116,7,8,97,115,121,110,99,101,120,101,8,111,110,108,97,121,111, + 117,116,7,28,111,98,106,101,99,116,105,110,115,112,101,99,116,111,114,111, + 110,99,104,105,108,100,115,99,97,108,101,100,4,108,101,102,116,3,239,0, + 3,116,111,112,3,180,0,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,17,116,100,114,111, + 112,100,111,119,110,108,105,115,116,101,100,105,116,12,99,111,109,112,115,101, + 108,101,99,116,111,114,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1, + 5,99,111,108,111,114,4,2,0,0,128,0,0,8,116,97,98,111,114,100, + 101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,1,9,98,111,117,110,100,115,95,99,120,3,171,0,9, + 98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104,111,114,115,11, + 7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,22,99,111, + 109,112,115,101,108,101,99,116,111,114,111,110,115,101,116,118,97,108,117,101, + 16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,14,100, + 101,111,95,115,101,108,101,99,116,111,110,108,121,16,100,101,111,95,97,117, + 116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121,100,114, + 111,112,100,111,119,110,0,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,105,116,101,109,115,14,1,0,0,16,111,110,98,101,102,111, + 114,101,100,114,111,112,100,111,119,110,7,26,99,111,109,112,115,101,108,101, + 99,116,111,114,98,101,102,111,114,101,100,114,111,112,100,111,119,110,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,11,116,119,105, + 100,103,101,116,103,114,105,100,4,103,114,105,100,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,1,9,112,111,112,117,112,109,101,110,117, + 7,9,103,114,105,100,112,111,112,117,112,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110,100,115, + 95,99,120,3,244,0,9,98,111,117,110,100,115,95,99,121,3,224,0,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98, + 111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12, + 111,103,95,99,111,108,115,105,122,105,110,103,12,111,103,95,99,111,108,109, + 111,118,105,110,103,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110, + 116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,0,12,111, + 112,116,105,111,110,115,103,114,105,100,49,11,17,111,103,49,95,110,111,114, + 101,115,101,116,115,101,108,101,99,116,0,15,114,111,119,99,111,108,111,114, + 115,46,99,111,117,110,116,2,1,15,114,111,119,99,111,108,111,114,115,46, + 105,116,101,109,115,1,4,242,255,255,0,0,14,114,111,119,102,111,110,116, + 115,46,99,111,117,110,116,2,6,14,114,111,119,102,111,110,116,115,46,105, + 116,101,109,115,14,1,4,110,97,109,101,6,11,115,116,102,95,100,101,102, + 97,117,108,116,6,120,115,99,97,108,101,2,1,10,108,111,99,97,108,112, + 114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,0,1,5, + 99,111,108,111,114,4,0,128,0,0,4,110,97,109,101,6,11,115,116,102, + 95,100,101,102,97,117,108,116,6,120,115,99,97,108,101,2,1,10,108,111, + 99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111,114,10, + 102,108,112,95,120,115,99,97,108,101,0,0,1,5,99,111,108,111,114,4, + 0,128,0,0,4,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117, + 108,116,6,120,115,99,97,108,101,2,1,10,108,111,99,97,108,112,114,111, + 112,115,11,9,102,108,112,95,99,111,108,111,114,10,102,108,112,95,120,115, + 99,97,108,101,0,0,1,5,99,111,108,111,114,4,13,0,0,160,4,110, + 97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99, + 97,108,101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108, + 112,95,99,111,108,111,114,10,102,108,112,95,120,115,99,97,108,101,0,0, + 1,5,115,116,121,108,101,11,7,102,115,95,98,111,108,100,0,4,110,97, + 109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99,97, + 108,101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112, + 95,115,116,121,108,101,10,102,108,112,95,120,115,99,97,108,101,0,0,1, + 5,115,116,121,108,101,11,7,102,115,95,98,111,108,100,0,4,110,97,109, + 101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99,97,108, + 101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95, + 115,116,121,108,101,10,102,108,112,95,120,115,99,97,108,101,0,0,0,14, + 100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,14,100,97,116, + 97,99,111,108,115,46,105,116,101,109,115,14,7,5,112,114,111,112,115,1, + 9,108,105,110,101,99,111,108,111,114,4,5,0,0,160,12,108,105,110,101, + 99,111,108,111,114,102,105,120,4,3,0,0,160,11,99,111,108,111,114,115, + 101,108,101,99,116,4,19,0,0,160,11,99,111,108,111,114,97,99,116,105, + 118,101,4,7,0,0,144,5,119,105,100,116,104,2,90,16,111,110,98,101, + 102,111,114,101,100,114,97,119,99,101,108,108,7,11,98,101,102,100,114,97, + 119,99,101,108,108,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101, + 97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99, + 111,95,115,97,118,101,115,116,97,116,101,0,8,111,112,116,105,111,110,115, + 49,11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114, + 111,119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108, + 111,114,0,8,119,105,100,116,104,109,105,110,2,10,10,111,110,115,104,111, + 119,104,105,110,116,7,14,99,111,108,48,111,110,115,104,111,119,104,105,110, + 116,18,111,110,115,101,108,101,99,116,105,111,110,99,104,97,110,103,101,100, + 7,10,115,101,108,99,104,97,110,103,101,100,10,119,105,100,103,101,116,110, + 97,109,101,6,5,112,114,111,112,115,9,100,97,116,97,99,108,97,115,115, + 7,17,116,116,114,101,101,105,116,101,109,101,100,105,116,108,105,115,116,0, + 7,6,118,97,108,117,101,115,1,12,108,105,110,101,99,111,108,111,114,102, + 105,120,4,3,0,0,160,5,119,105,100,116,104,3,148,0,13,114,111,119, + 102,111,110,116,111,102,102,115,101,116,2,4,7,111,112,116,105,111,110,115, + 11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97, + 116,101,0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111, + 119,102,111,110,116,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114, + 0,8,119,105,100,116,104,109,105,110,2,10,11,111,110,99,101,108,108,101, + 118,101,110,116,7,15,118,97,108,117,101,115,99,101,108,108,101,118,101,110, + 116,10,111,110,115,104,111,119,104,105,110,116,7,14,99,111,108,49,111,110, + 115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6, + 6,118,97,108,117,101,115,9,100,97,116,97,99,108,97,115,115,7,13,116, + 105,116,101,109,101,100,105,116,108,105,115,116,0,0,16,100,97,116,97,114, + 111,119,108,105,110,101,99,111,108,111,114,4,5,0,0,160,13,100,97,116, + 97,114,111,119,104,101,105,103,104,116,2,18,8,115,116,97,116,102,105,108, + 101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97, + 116,102,105,108,101,17,111,110,114,111,119,115,100,97,116,97,99,104,97,110, + 103,101,100,7,19,103,114,105,100,114,111,119,115,100,97,116,97,99,104,97, + 110,103,101,100,11,111,110,99,101,108,108,101,118,101,110,116,7,13,103,114, + 105,100,99,101,108,108,101,118,101,110,116,22,100,114,97,103,46,111,110,98, + 101,102,111,114,101,100,114,97,103,98,101,103,105,110,7,15,103,114,105,100, + 111,110,100,114,97,103,98,101,103,105,110,21,100,114,97,103,46,111,110,98, + 101,102,111,114,101,100,114,97,103,111,118,101,114,7,14,103,114,105,100,111, + 110,100,114,97,103,111,118,101,114,21,100,114,97,103,46,111,110,98,101,102, + 111,114,101,100,114,97,103,100,114,111,112,7,14,103,114,105,100,111,110,100, + 114,97,103,100,114,111,112,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,13,116,116,114,101,101,105,116,101,109,101,100,105,116,5,112, + 114,111,112,115,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 14,111,119,49,95,97,117,116,111,104,101,105,103,104,116,0,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,10,111,115,107, + 95,110,111,115,107,105,110,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,2,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,1,7,111,110,112,111,112,117,112,7,12,112,114,111,112,115,111,110, + 112,111,112,117,112,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,90,9,98,111,117,110,100,115,95,99,121,2,18, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 9,111,101,95,108,111,99,97,116,101,0,9,111,110,107,101,121,100,111,119, + 110,7,15,112,114,111,112,115,107,101,121,100,111,119,110,101,120,101,17,111, + 110,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115,7,18,112,114, + 111,112,117,112,100,97,116,101,114,111,119,118,97,108,117,101,7,111,112,116, + 105,111,110,115,11,16,116,101,111,95,116,114,101,101,99,111,108,110,97,118, + 105,103,16,116,101,111,95,107,101,121,114,111,119,109,111,118,105,110,103,0, + 14,111,110,99,104,101,99,107,114,111,119,109,111,118,101,7,19,112,114,111, + 112,115,111,110,99,104,101,99,107,114,111,119,109,111,118,101,0,0,17,116, + 100,114,111,112,100,111,119,110,105,116,101,109,101,100,105,116,6,118,97,108, + 117,101,115,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,5,99,111,108,111,114,4,7,0,0,144,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,119,105,100,116, + 104,2,15,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108, + 111,114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,15,5, + 99,111,108,111,114,4,5,0,0,144,0,1,5,119,105,100,116,104,2,15, + 5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2, + 17,0,0,8,116,97,98,111,114,100,101,114,2,2,7,111,110,101,110,116, + 101,114,7,14,118,97,108,117,101,115,101,110,116,101,114,101,120,101,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,91,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 148,0,9,98,111,117,110,100,115,95,99,121,2,18,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,24,111,101,95,102,111,114,99,101,114,101,116,117,114, + 110,99,104,101,99,107,118,97,108,117,101,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,18,111,101,95,104,105,110,116,99,108,105,112, + 112,101,100,116,101,120,116,0,9,102,111,110,116,46,110,97,109,101,6,11, + 115,116,102,95,100,101,102,97,117,108,116,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,9,111,110,107,101,121, + 100,111,119,110,7,13,118,97,108,117,101,115,107,101,121,100,111,119,110,18, + 111,110,99,108,105,101,110,116,109,111,117,115,101,101,118,101,110,116,7,18, + 118,97,108,117,101,115,111,110,109,111,117,115,101,101,118,101,110,116,10,111, + 110,115,101,116,118,97,108,117,101,7,14,118,97,108,117,101,115,115,101,116, + 118,97,108,117,101,12,111,110,112,97,105,110,116,105,109,97,103,101,7,13, + 112,97,105,110,116,105,109,97,103,101,101,120,101,13,111,110,101,120,116,101, + 110,100,105,109,97,103,101,7,14,101,120,116,101,110,100,105,109,97,103,101, + 101,120,101,14,111,110,98,117,116,116,111,110,97,99,116,105,111,110,7,18, + 118,97,108,117,101,115,98,117,116,116,111,110,97,99,116,105,111,110,17,111, + 110,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115,7,19,118,97, + 108,117,101,117,112,100,97,116,101,114,111,119,118,97,108,117,101,16,100,114, + 111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,16,100,101,111,95, + 97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121, + 100,114,111,112,100,111,119,110,12,100,101,111,95,99,108,105,112,104,105,110, + 116,0,25,100,114,111,112,100,111,119,110,46,100,114,111,112,100,111,119,110, + 114,111,119,99,111,117,110,116,2,16,19,100,114,111,112,100,111,119,110,46, + 99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,16,111,110,98, + 101,102,111,114,101,100,114,111,112,100,111,119,110,7,20,118,97,108,117,101, + 115,98,101,102,111,114,101,100,114,111,112,100,111,119,110,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,0,11,116,114,105,99,104, + 98,117,116,116,111,110,8,99,111,109,112,101,100,105,116,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,15,111,119,95,100,105,115,97,98,108,101,100,104,105, + 110,116,12,111,119,95,116,105,109,101,100,104,105,110,116,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,10,111,115,107,95,110,111,102,97,99,101, + 0,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110, + 116,2,2,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46,105,116, + 101,109,115,1,2,0,2,1,0,21,102,97,99,101,46,102,97,100,101,95, + 99,111,108,111,114,46,99,111,117,110,116,2,2,21,102,97,99,101,46,102, + 97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1,4,191,191,255, + 0,4,154,154,237,0,0,19,102,97,99,101,46,102,97,100,101,95,100,105, + 114,101,99,116,105,111,110,7,7,103,100,95,100,111,119,110,15,102,97,99, + 101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,97,108,95,102,97, + 100,105,114,101,99,116,105,111,110,0,4,104,105,110,116,6,22,83,104,111, + 119,32,99,111,109,112,111,110,101,110,116,32,101,100,105,116,111,114,46,8, + 98,111,117,110,100,115,95,120,3,217,0,8,98,111,117,110,100,115,95,121, + 2,2,9,98,111,117,110,100,115,95,99,120,2,25,9,98,111,117,110,100, + 115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,11, + 97,115,95,100,105,115,97,98,108,101,100,16,97,115,95,108,111,99,97,108, + 100,105,115,97,98,108,101,100,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,12,97,115,95,108,111,99,97,108,104,105,110,116,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,23,102,97,99, + 101,100,105,115,97,98,108,101,100,46,108,111,99,97,108,112,114,111,112,115, + 11,0,21,102,97,99,101,100,105,115,97,98,108,101,100,46,116,101,109,112, + 108,97,116,101,7,29,103,117,105,116,101,109,112,108,97,116,101,115,109,111, + 46,102,97,100,101,118,101,114,116,107,111,110,118,101,120,7,99,97,112,116, + 105,111,110,6,3,38,69,68,9,111,110,101,120,101,99,117,116,101,7,17, + 99,111,109,112,101,100,105,116,111,110,101,120,101,99,117,116,101,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,17,116,115,116,111, + 99,107,103,108,121,112,104,98,117,116,116,111,110,6,102,105,110,100,98,117, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49, + 95,97,117,116,111,115,99,97,108,101,0,8,116,97,98,111,114,100,101,114, + 2,3,8,98,111,117,110,100,115,95,120,3,197,0,8,98,111,117,110,100, + 115,95,121,2,2,9,98,111,117,110,100,115,95,99,120,2,18,9,98,111, + 117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95, + 108,111,99,97,108,105,109,97,103,101,110,114,0,5,103,108,121,112,104,7, + 16,115,116,103,95,101,108,108,105,112,115,101,115,109,97,108,108,6,97,99, + 116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,102,105,110,100, + 99,111,109,112,97,108,108,97,99,116,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,10,116,112,111,112,117,112,109,101,110,117,9, + 103,114,105,100,112,111,112,117,112,8,111,110,117,112,100,97,116,101,7,11, + 112,111,112,117,112,117,112,100,97,116,101,18,109,101,110,117,46,115,117,98, + 109,101,110,117,46,99,111,117,110,116,2,3,18,109,101,110,117,46,115,117, + 98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111, + 110,6,13,67,111,108,108,97,112,115,101,32,116,114,101,101,5,115,116,97, + 116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111, + 110,101,120,101,99,117,116,101,7,11,99,111,108,108,97,112,115,101,101,120, + 101,0,1,7,99,97,112,116,105,111,110,6,19,82,101,118,101,114,116,32, + 116,111,32,105,110,104,101,114,105,116,101,100,4,110,97,109,101,6,6,114, + 101,118,101,114,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,9,114, + 101,118,101,114,116,101,120,101,0,1,7,99,97,112,116,105,111,110,6,15, + 67,108,101,97,114,32,83,101,108,101,99,116,105,111,110,4,110,97,109,101, + 6,11,99,108,101,97,114,115,101,108,101,99,116,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120, + 101,99,117,116,101,7,11,99,108,101,97,114,115,101,108,101,99,116,0,0, + 4,108,101,102,116,2,112,3,116,111,112,2,80,0,0,10,116,112,111,112, + 117,112,109,101,110,117,9,109,97,105,110,112,111,112,117,112,7,111,112,116, + 105,111,110,115,11,14,109,111,95,105,110,115,101,114,116,102,105,114,115,116, + 16,109,111,95,115,104,111,114,116,99,117,116,114,105,103,104,116,0,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,1,18, + 109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1, + 6,97,99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,102, + 105,110,100,99,111,109,112,97,108,108,97,99,116,0,0,4,108,101,102,116, + 2,56,3,116,111,112,2,56,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tobjectinspectorfo,''); +end. diff --git a/mseide-msegui/apps/ide/panelform.mfm b/mseide-msegui/apps/ide/panelform.mfm new file mode 100644 index 0000000..87675c5 --- /dev/null +++ b/mseide-msegui/apps/ide/panelform.mfm @@ -0,0 +1,38 @@ +object panelfo: tpanelfo + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_lockbutton, go_nolockbutton, go_buttonhints] + onpaint = paintexe + visible = False + bounds_x = 157 + bounds_y = 493 + bounds_cx = 323 + bounds_cy = 195 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent] + container.frame.framei_left = 0 + container.frame.framei_top = 0 + container.frame.framei_right = 0 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + container.frame.localprops1 = [] + container.onpaint = paintexe + container.bounds = ( + 0 + 0 + 313 + 195 + ) + dragdock.tab_options = [tabo_dragsource, tabo_dragdest, tabo_hintclippedtext] + dragdock.tab_textflags = [tf_ycentered, tf_ellipseright] + dragdock.tab_widthmax = 100 + dragdock.caption = 'Mainwindow' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_acceptsdock, od_dockparent, od_splitvert, od_splithorz, od_tabed, od_proportional, od_propsize, od_captionhint] + dragdock.onlayoutchanged = panellayoutchanged + dragdock.oncaptionchanged = panellayoutchanged + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + onclose = onclo + moduleclassname = 'tdockform' +end diff --git a/mseide-msegui/apps/ide/panelform.pas b/mseide-msegui/apps/ide/panelform.pas new file mode 100644 index 0000000..ac3c908 --- /dev/null +++ b/mseide-msegui/apps/ide/panelform.pas @@ -0,0 +1,314 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit panelform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegui,mseclasses,mseforms,msemenus,msestat, + msetypes{msestrings}, + msedock,msegraphutils,msegraphics,mseguiglob,msesimplewidgets,msewidgets, + msestringcontainer; + +type + + tpanelfo = class(tdockform) + procedure onclo(const sender: TObject); + procedure panellayoutchanged(const sender: tdockcontroller); + procedure paintexe(const sender: twidget; const acanvas: tcanvas); + private + fmenuitem: tmenuitem; + fnameindex: integer; //0 for unnumbered + procedure showexecute(const sender: tobject); + protected + procedure updatecaption(acaption: msestring); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function canclose(const newfocus: twidget): boolean; override; + end; + +function newpanel(aname: string = ''): tpanelfo; +procedure updatestat(const filer: tstatfiler); +procedure docktopanel(const controller: tdockcontroller; + const panelname: string; const arect: rectty); +procedure beginpanelplacement(); +procedure endpanelplacement(); + +implementation + +uses + panelform_mfm,main,sysutils,msekeyboard,mselist,msedatalist, + msearrayutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +var + panellist: tpointerlist; + +procedure updatestat(const filer: tstatfiler); +var + ar1: msestringarty; + int1: integer; +begin + ar1:= nil; + if filer.iswriter then begin + setlength(ar1,panellist.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= msestring(tpanelfo(panellist[int1]).name); + end; + end; + filer.updatevalue('panels',ar1); + if not filer.iswriter then begin + for int1:= panellist.count - 1 downto 0 do begin + tpanelfo(panellist[int1]).free; + end; + for int1:= 0 to high(ar1) do begin + try + newpanel(ansistring(ar1[int1])); + except + end; + end; + end; +end; + +procedure docktopanel(const controller: tdockcontroller; + const panelname: string; const arect: rectty); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + if name = panelname then begin + dragdock.dock(controller,arect); + break; + end; + end; + end; +end; + +procedure beginpanelplacement(); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + dragdock.beginplacement(); + end; + end; +end; + +procedure endpanelplacement(); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + try + dragdock.endplacement(); + except + application.handleexception(); + end; + end; + end; +end; + +function newpanel(aname: string = ''): tpanelfo; +var + item1: tmenuitem; + int1,int2: integer; + ar1: integerarty; +begin + item1:= mainfo.mainmenu.menu.itembyname('view').itembyname('panels'); + if aname = '' then begin + setlength(ar1,panellist.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tpanelfo(panellist[int1]).fnameindex; + end; + sortarray(ar1); + int2:= length(ar1); + for int1:= 0 to high(ar1) do begin //find first gap + if ar1[int1] <> int1 then begin + int2:= int1; + break; + end; + end; + end + else begin + int2:= strtoint(copy(aname,6,bigint))-1; + end; + result:= tpanelfo.create(mainfo); + int1:= int2 + 1; + if aname = '' then begin + aname:= 'panel'+inttostr(int1); + end; + with result do begin + name:= aname; + fnameindex:= int2; + fmenuitem:= tmenuitem.create(nil,nil); + updatecaption(''); + end; + if int2 > item1.count - 2 then begin + int2:= item1.count - 2; + end; + item1.submenu.insert(int2,result.fmenuitem); +end; + +{ tpanelfo } + +constructor tpanelfo.create(aowner: tcomponent); +begin + inherited create(aowner); + panellist.add(self); +end; + +destructor tpanelfo.destroy; +begin + if panellist <> nil then begin + panellist.remove(self); + end; + if not (csdestroying in mainfo.componentstate) then begin + fmenuitem.parentmenu.submenu.delete(fmenuitem.index); + end; + inherited; +end; + +procedure tpanelfo.updatecaption(acaption: msestring); + +begin + if acaption = '' then begin + acaption:= 'Panel'; + end; + if length(acaption) > 40 then begin + setlength(acaption,40); + acaption:= acaption+'...'; + end; + with fmenuitem do begin + onexecute:= {$ifdef FPC}@{$endif}showexecute; + if fnameindex < 9 then begin + shortcut:= (ord(key_f1) or key_modctrl) + fnameindex; + caption:= '&' + inttostrmse(fnameindex+1)+' '+acaption; + end + else begin + shortcut:= 0; + caption:= acaption; + end; + if shortcut <> 0 then begin + acaption:= acaption + ' (Ctrl+F' + inttostrmse(fnameindex+1)+')'; + end; + self.caption:= acaption; + end; +end; + +procedure tpanelfo.showexecute(const sender: tobject); +begin + activate; +end; + +function tpanelfo.canclose(const newfocus: twidget): boolean; + + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; + +begin + result:= inherited canclose(newfocus); + { + if result and (newfocus = nil) and containerempty then begin + release; + end; + } +end; + +procedure tpanelfo.onclo(const sender: TObject); + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; +begin + if containerempty then begin + release; + end; +end; + +procedure tpanelfo.panellayoutchanged(const sender: tdockcontroller); +var + intf1: idocktarget; + mstr1: msestring; + int1: integer; + ar1: widgetarty; +begin + mstr1:= ''; + ar1:= sender.getitems; + for int1:= 0 to high(ar1) do begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + mstr1:= mstr1 + intf1.getdockcontroller.getdockcaption+','; + end; + end; + if mstr1 <> '' then begin + setlength(mstr1,length(mstr1)-1); + end; + fdragdock.caption:= mstr1; + updatecaption(mstr1); +end; + +procedure tpanelfo.paintexe(const sender: twidget; const acanvas: tcanvas); +begin + paintdockingareacaption(acanvas,sender,mainfo.c[ord(dockingarea)]); +end; + +initialization + panellist:= tpointerlist.Create; +finalization + freeandnil(panellist); +end. diff --git a/mseide-msegui/apps/ide/panelform_mfm.pas b/mseide-msegui/apps/ide/panelform_mfm.pas new file mode 100644 index 0000000..aba635e --- /dev/null +++ b/mseide-msegui/apps/ide/panelform_mfm.pas @@ -0,0 +1,88 @@ +unit panelform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,panelform; + +const + objdata: record size: integer; data: array[0..1412] of byte end = + (size: 1413; data: ( + 84,80,70,48,8,116,112,97,110,101,108,102,111,7,112,97,110,101,108,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,9,111,119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114, + 105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112, + 95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117, + 116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111, + 110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95, + 116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111, + 117,110,100,98,117,116,116,111,110,13,103,111,95,108,111,99,107,98,117,116, + 116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14, + 103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,111,110,112,97, + 105,110,116,7,8,112,97,105,110,116,101,120,101,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,157,0,8,98,111,117,110,100, + 115,95,121,3,237,1,9,98,111,117,110,100,115,95,99,120,3,67,1,9, + 98,111,117,110,100,115,95,99,121,3,195,0,23,99,111,110,116,97,105,110, + 101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46, + 102,114,97,109,101,105,95,108,101,102,116,2,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,116,111,112, + 2,0,28,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102, + 114,97,109,101,105,95,114,105,103,104,116,2,0,29,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,98,111,116, + 116,111,109,2,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,102,105, + 108,101,102,116,9,102,114,108,95,102,105,116,111,112,11,102,114,108,95,102, + 105,114,105,103,104,116,12,102,114,108,95,102,105,98,111,116,116,111,109,0, + 27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,17,99,111,110,116,97,105,110,101,114, + 46,111,110,112,97,105,110,116,7,8,112,97,105,110,116,101,120,101,16,99, + 111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0, + 3,57,1,3,195,0,0,20,100,114,97,103,100,111,99,107,46,116,97,98, + 95,111,112,116,105,111,110,115,11,15,116,97,98,111,95,100,114,97,103,115, + 111,117,114,99,101,13,116,97,98,111,95,100,114,97,103,100,101,115,116,20, + 116,97,98,111,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,22,100,114,97,103,100,111,99,107,46,116,97,98,95,116,101,120,116,102, + 108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,15,116, + 102,95,101,108,108,105,112,115,101,114,105,103,104,116,0,21,100,114,97,103, + 100,111,99,107,46,116,97,98,95,119,105,100,116,104,109,97,120,2,100,16, + 100,114,97,103,100,111,99,107,46,99,97,112,116,105,111,110,6,10,77,97, + 105,110,119,105,110,100,111,119,20,100,114,97,103,100,111,99,107,46,111,112, + 116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112,111, + 115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95,99, + 97,110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111, + 100,95,99,97,110,100,111,99,107,14,111,100,95,97,99,99,101,112,116,115, + 100,111,99,107,13,111,100,95,100,111,99,107,112,97,114,101,110,116,12,111, + 100,95,115,112,108,105,116,118,101,114,116,12,111,100,95,115,112,108,105,116, + 104,111,114,122,8,111,100,95,116,97,98,101,100,15,111,100,95,112,114,111, + 112,111,114,116,105,111,110,97,108,11,111,100,95,112,114,111,112,115,105,122, + 101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,0,24,100,114, + 97,103,100,111,99,107,46,111,110,108,97,121,111,117,116,99,104,97,110,103, + 101,100,7,18,112,97,110,101,108,108,97,121,111,117,116,99,104,97,110,103, + 101,100,25,100,114,97,103,100,111,99,107,46,111,110,99,97,112,116,105,111, + 110,99,104,97,110,103,101,100,7,18,112,97,110,101,108,108,97,121,111,117, + 116,99,104,97,110,103,101,100,7,111,112,116,105,111,110,115,11,10,102,111, + 95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100, + 101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97, + 116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,102,105,108,101,7,111,110,99,108,111,115,101,7,5,111, + 110,99,108,111,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,9,116,100,111,99,107,102,111,114,109,0,0) + ); + +initialization + registerobjectdata(@objdata,tpanelfo,''); +end. diff --git a/mseide-msegui/apps/ide/pascaldesignparser.pas b/mseide-msegui/apps/ide/pascaldesignparser.pas new file mode 100644 index 0000000..bbe55ea --- /dev/null +++ b/mseide-msegui/apps/ide/pascaldesignparser.pas @@ -0,0 +1,1504 @@ +{ MSEide Copyright (c) 1999-2018 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit pascaldesignparser; + +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} + +interface +uses + classes,mseparser,typinfo,msetypes,mselist,msestrings,mseclasses, + msedesignparser; + +type + + tpascaldesignparser = class(tpascalparser,idesignparser) + private + funitinfopo: punitinfoty; + fimplementation: boolean; + finterface: boolean; + finterfaceonly: boolean; + protected + function skipexpression: boolean; + procedure parsetype; + procedure parselabel; + procedure parseconst; + procedure parsevar; + function parseclasstype: boolean; + function parseinterfacetype: boolean; + function parserecord: boolean; + function parseobject: boolean; + function parseprocparams(var akind: methodkindty; + var aflags: methodflagsty; var params: paraminfoarty; + const acceptnameonly: boolean): boolean; + function parseclassprocedureheader(atoken: pascalidentty; + classinfopo: pclassinfoty; const managed: boolean): boolean; + function skipprocedureparams(atoken: pascalidentty): boolean; + function skipprocedureheader(atoken: pascalidentty): boolean; + procedure parseprocedurebody; + procedure parseimplementation; + public + constructor create(unitinfopo: punitinfoty; + const afilelist: tmseindexednamelist; + const getincludefile: getincludefileeventty; + const ainterfaceonly: boolean); overload; + constructor create(const afilelist: tmseindexednamelist; + const atext: string); overload; + procedure parse; override; + function dogetincludefile(const afilename: filenamety; + const astatementstart,astatementend: sourceposty): tscanner override; + function parseprocedureheader(atoken: pascalidentty; + procedureinfopo: pprocedureinfoty): boolean; + end; + +function findclassinfobyinstance(const ainstance: tmsecomponent; + const infopo: punitinfoty): pclassinfoty; +function isemptysourcepos(const apos: sourceposty): boolean; +function isinrowrange(const apos,startpos,endpos: sourceposty): boolean; +procedure parsepascaldef(const adef: pdefinfoty; out atext: string; + out scope: tdeflist); + +implementation +uses + sysutils,msedatalist,msefileutils,msedesigner,sourceupdate,msestream; +type + tdeflist1 = class(tdeflist); + tusesinfolist1 = class(tusesinfolist); + +procedure parsepascaldef(const adef: pdefinfoty; out atext: string; + out scope: tdeflist); +var + parser: tpascalparser; + + procedure doaddidents; + begin + with parser do begin + while checkoperator('^') do begin + end; + if checkident(ord(pid_array)) then begin + if checkoperator('[') then begin + findoperator(']'); + end; + checkident(ord(pid_of)); + while checkoperator('^') do begin + end; + end; + scope.addidentpath(parser,'.'); + end; + end; + + procedure parsecase; + var + ident1: pascalidentty; + int1: integer; + begin + with parser do begin + if not checkname then begin + exit; + end; + if checkoperator(':') then begin + if not checkname then begin + exit; + end; + end; + if pascalidentty(getident) <> pid_of then begin + exit; + end; + repeat + if not findoperator(':') then begin + exit; + end; + if not checkoperator('(') then begin + exit; + end; + while not checkoperator(')') and not eof do begin + if not getnameorident(int1) then begin + exit; + end; + ident1:= pascalidentty(int1); + if ident1 = pid_case then begin + parsecase; + end + else begin + skipnamelist; + if not checkoperator(':') then begin + exit; + end; + doaddidents; + end; + checkoperator(';'); + end; + checkoperator(';'); + until eof or testident(ord(pid_end)); + end; + end; + + procedure parsetypedef; + var + ident1: pascalidentty; + int1: integer; + begin + with parser do begin + while checkoperator('^') do begin + end; + ident1:= pascalidentty(getident); + case ident1 of + pid_case: begin + parsecase; + end; + pid_record: begin + repeat + if not getnameorident(int1) then begin + nexttoken; + break; + end; + ident1:= pascalidentty(int1); + if ident1 = pid_case then begin + parsecase; + end + else begin + skipnamelist; + if checkoperator(':') then begin + parsetypedef; + end + else begin + nexttoken; + break; + end; + end; + until eof or checkident(ord(pid_end)); + end; + else begin + lasttoken; + doaddidents; + end; + end; + checkoperator(';'); + end; + end; + +var + bo1: boolean; +begin + scope:= tdeflist.create(adef^.kind,false); + atext:= sourceupdater.getdefinfotext(adef); + if atext <> '' then begin + parser:= tpascalparser.create(designer.designfiles,atext); + try + with parser do begin + if adef^.kind in [syk_procdef,syk_classprocimp,syk_procimp] then begin + nextnonwhitetoken; //procedure or function + if adef^.kind = syk_classprocimp then begin + nextnonwhitetoken; //classname + nextnonwhitetoken; //dot + end; + nextnonwhitetoken; //procname + if checkoperator('(') then begin + repeat + while not eof and not checkoperator(':') do begin + nexttoken; + end; + doaddidents; + while not eof and not checkoperator(';') do begin + if checkoperator(')') then begin + break; + end; + nexttoken; + end; + until eof; + end; + if checkoperator(':') then begin + doaddidents; + end; + end + else begin +// ident1:= getident; + if skipnamenoident then begin + case adef^.kind of + syk_typedef: begin + if checkoperator('=') then begin + parsetypedef; + end; + end; + syk_vardef,syk_pardef: begin + bo1:= true; + while bo1 and checkoperator(',') do begin + bo1:= checknamenoident; + end; + if bo1 and checkoperator(':') then begin + doaddidents; + end; + end; + syk_classdef: begin + if checkoperator('=') and + (checkident([ord(pid_class),ord(pid_object)]) >= 0) and + checkoperator('(') then begin + scope.addidents(parser,',','.'); +// doaddidents; + end; + end; + syk_interfacedef: begin + if checkoperator('=') and checkident(ord(pid_interface)) + and checkoperator('(') then begin + scope.addidents(parser,#0,'.'); + end; + end; + end; + end; + end; + end; + finally + parser.Free; + end; + end; +end; + +function isemptysourcepos(const apos: sourceposty): boolean; +begin + with apos do begin + result:= (filenum = 0) {and (pos.col = 0) and (pos.row = 0)}; + end; +end; + +function isinrowrange(const apos,startpos,endpos: sourceposty): boolean; +begin +// result:= (apos.filenum = startpos.filenum) and (apos.filenum = endpos.filenum) and +// (apos.pos.row >= startpos.line) and (apos.pos.row <= endpos.line); + result:= (apos.line >= startpos.line) and (apos.line <= endpos.line); +end; + +function findclassinfobyinstance(const ainstance: tmsecomponent; const infopo: punitinfoty): pclassinfoty; +var + po1: pmoduleinfoty; +begin + result:= nil; + if infopo <> nil then begin + po1:= designer.modules.findmodule(ainstance); + if po1 <> nil then begin + result:= infopo^.p.classinfolist.finditembyname(po1^.moduleclassname,true); + end; + end; +end; + +{ tpascaldesignparser } + +constructor tpascaldesignparser.create(unitinfopo: punitinfoty; + const afilelist: tmseindexednamelist; + const getincludefile: getincludefileeventty; + const ainterfaceonly: boolean); +begin + finterfaceonly:= ainterfaceonly; + inherited create(afilelist); + funitinfopo:= unitinfopo; + funitinfopo^.interfacecompiled:= false; + funitinfopo^.implementationcompiled:= false; + ongetincludefile:= getincludefile; +end; + +constructor tpascaldesignparser.create(const afilelist: tmseindexednamelist; + const atext: string); +begin + fnoautoparse:= true; + inherited create(afilelist,atext); +end; + +function tpascaldesignparser.skipexpression: boolean; +var + bracketlevel: integer; + ch1: char; + str1: string; +begin + result:= true; + bracketlevel:= 0; + repeat + ch1:= getoperator; + case ch1 of + '(','[': inc(bracketlevel); + ')',']': dec(bracketlevel); + '*','/','+','-','^',',': begin + end; + else begin + if ch1 <> #0 then begin + lasttoken; //' for pascalstring + end; + if getvaluestring(str1) = vk_none then begin + if ch1 <> #0 then begin + break; //error + end + else begin + nexttoken; //was ident + end; + end; + end; + end; + until eof or (bracketlevel < 0); + if bracketlevel < 0 then begin + lasttoken; + end; +end; + +function tpascaldesignparser.parseprocparams(var akind: methodkindty; + var aflags: methodflagsty; + var params: paraminfoarty; + const acceptnameonly: boolean): boolean; +var + ar1: stringarty; + paraflags: tparamflags; + defaultstr: string; + apos,epos: sourceposty; + + procedure putparams(const atypename: string); + var + int1,int2: integer; + begin + int2:= length(params); + setlength(params,int2+length(ar1)); + for int1:= 0 to high(ar1) do begin + with params[int2] do begin + name:= ar1[int1]; + flags:= paraflags; + typename:= atypename; + defaultvalue:= defaultstr; + start:= apos; + stop:= epos; + end; + inc(int2); + end; + end; + +var + str1: string; + int1: integer; + po1: pchar; + +begin + ar1:= nil; //compiler warning + params:= nil; + result:= false; + if checkoperator(';') then begin + if not (akind in [mk_function,mk_classfunction]) or acceptnameonly then begin + result:= true; //no params + end; + end + else begin + if checkoperator('(') then begin + include(aflags,mef_brackets); + if checkoperator(')') then begin + apos:= sourcepos; + result:= true; //no params + end + else begin + while not eof do begin + defaultstr:= ''; + int1:= getident; + case pascalidentty(int1) of + pid_const: paraflags:= [pfconst]; + pid_var: paraflags:= [pfvar]; + pid_out: paraflags:= [pfout]; + else paraflags:= []; + end; + if (paraflags = []) and (int1 >= 0) then begin + break; + end; + apos:= sourcepos; + ar1:= lstringartostringar(getorignamelist); + if not checkoperator(':') then begin + epos:= sourcepos; + putparams(''); //untyped + end + else begin + if checkident(ord(pid_array)) then begin + include(paraflags,pfarray); + checkident(ord(pid_of)); + if checkident(ord(pid_const)) then begin + str1:= 'TVarRec'; + end + else begin + str1:= getorigname; + end; + end + else begin + str1:= getorigname; + end; + if str1 = '' then begin + break; + end; + if checkoperator('=') then begin + skipwhitespace; + po1:= fto^.value.po; + skipexpression; + defaultstr:= getorigtext(po1); + end; + epos:= sourcepos; + putparams(str1); + end; + if checkoperator(')') then begin + apos:= sourcepos; + result:= true; + break; + end; + if not checkoperator(';') then begin + break; + end; + end; + end; + end + else begin + apos:= sourcepos; + result:= true; + end; + if result then begin + if checkoperator(':') then begin + setlength(params,length(params)+1); + with params[high(params)] do begin + name:= 'result'; + flags:= [pfvar]; + typename:= getorigname; + start:= apos; + stop:= sourcepos; + end; + case akind of + mk_procedure: begin + akind:= mk_procedurefunc; + end; + mk_method: begin + akind:= mk_methodfunc; + end; + end; + end + else begin + if (akind in [mk_function,mk_classfunction]) then begin + result:= acceptnameonly; + end; + end; + end; + if result then begin + checkoperator(';'); + mark(); + if checkident(ord(pid_inline)) then begin + pop(); + checkoperator(';'); + end + else begin + back(); //after semicolon + end; + end; + end; +end; + +function tpascaldesignparser.parseprocedureheader(atoken: pascalidentty; + procedureinfopo: pprocedureinfoty): boolean; +begin +// result:= false; + with procedureinfopo^ do begin + intinsertpos:= lasttokenpos; + skipwhitespace; + intstartpos:= sourcepos; + case atoken of + pid_function: params.kind:= mk_function; + pid_method: params.kind:= mk_method; + pid_constructor: params.kind:= mk_constructor; + pid_destructor: params.kind:= mk_destructor; + else params.kind:= mk_procedure; + end; + name:= getorigname; + result:= not checkoperator('.'); //interface proc definition? + if result then begin + uppername:= uppercase(name); + result:= parseprocparams(params.kind,params.flags,params.params,false); + if result then begin + intendpos:= sourcepos; + end; + end; + end; +end; + +function tpascaldesignparser.parseclassprocedureheader(atoken: pascalidentty; + classinfopo: pclassinfoty; const managed: boolean): boolean; +var + po1: pprocedureinfoty; + token1: tokenidty; + pos1,pos2: sourceposty; + bo1: boolean; + int1: integer; +begin + result:= false; + bo1:= atoken = pid_class; + if bo1 then begin + if getident(int1) then begin + atoken:= pascalidentty(int1); + if not ((atoken = pid_function) or (atoken = pid_procedure) or + (atoken = pid_method)) then begin + lasttoken; + exit; + end; + end + else begin + exit; + end; + end; + with classinfopo^ do begin + po1:= procedurelist.newitem; + token1:= acttoken; + po1^.managed:= managed; + po1^.classproc:= bo1; + result:= parseprocedureheader(atoken,po1); + pos2:= sourcepos; + if result then begin + while true do begin + case pascalidentty(getclassident) of + pid_abstract: include(po1^.params.flags,mef_abstract); + pid_inherited: include(po1^.params.flags,mef_inherited); + pid_overload: include(po1^.params.flags,mef_overload); + pid_override: include(po1^.params.flags,mef_override); + pid_virtual: include(po1^.params.flags,mef_virtual); + pid_inline: begin end; //include(po1^.params.flags,mef_inline); + pid_invalid: break; + else + lasttoken; + break; + end; + if not checkoperator(';') then begin + break; + end; + end; + if isemptysourcepos(procedurestart) then begin + procedurestart:= po1^.intinsertpos; + end; + pos1:= getsourcepos(token1); + dec(pos1.offset,pos1.pos.col); + pos1.pos.col:= 0; + funitinfopo^.deflist.add(pos1,pos2,po1); + end + else begin + procedurelist.deletelast; + end; + end; +end; + +function tpascaldesignparser.skipprocedureparams(atoken: pascalidentty): boolean; +var + ar1: paraminfoarty; + flags1: methodflagsty; + kind1: methodkindty; +begin + case atoken of + pid_procedure,pid_method,pid_function: begin + kind1:= mk_procedure; + result:= parseprocparams(kind1,flags1,ar1,false); + end; + else begin + result:= false; + end; + end; +{ + case atoken of + pid_procedure,pid_method: begin + result:= parseprocparams(mk_procedure,flags1,ar1,false); + end; + pid_function: begin + result:= parseprocparams(mk_function,flags1,ar1,false); + end + else begin + result:= false; + end; + end; +} +end; + +function tpascaldesignparser.skipprocedureheader(atoken: pascalidentty): boolean; +var + lstr1: lstringty; +begin + if getnamenoident(lstr1) then begin + result:= skipprocedureparams(atoken); + end + else begin + result:= false; + end; +end; + +function tpascaldesignparser.parseinterfacetype: boolean; +var + value: lstringty; + ident1: pascalidentty; + intfinfopo: pinterfaceinfoty; +begin + result:= getorignamenoident(value) and checkoperator('=') and + checkident(integer(pid_interface)); + if result then begin + while not eof do begin + ident1:= pascalidentty(getident); + case ident1 of + pid_end: begin + intfinfopo:= funitinfopo^.p.interfacelist.newitem; + with intfinfopo^ do begin + name:= lstringtostring(value); + uppername:= uppercase(name); + end; + break; + end; + pid_implementation: begin + break; + end; + pid_procedure,pid_function,pid_method: begin + skipprocedureheader(ident1); + end; + else begin + nexttoken; + end; + end; + end; + end; +end; + +function tpascaldesignparser.parseclasstype: boolean; +var + value: lstringty; + ar1: lstringarty; + classinfopo: pclassinfoty; + pos1: sourceposty; + ident1: pascalidentty; + lstr2: lstringty; + pc,pc1: pcompinfoty; + pd: pdefinfoty; + bo1: boolean; + token1: tokenidty; + first: boolean; + int1: integer; + +begin + ar1:= nil; //compiler warning + token1:= acttoken; + result:= getorignamenoident(value) and checkoperator('=') and + (checkident([integer(pid_class),integer(pid_object)]) >= 0); + if result then begin + if checkoperator(';') then begin + lasttoken; //forward declaration + end + else begin + if checkident(integer(pid_of)) then begin + result:= checkname and checkoperator(';'); + if result then begin + funitinfopo^.deflist.add(lstringtostring(value),syk_typedef, + getsourcepos(token1),sourcepos); + end; + exit; + end; + classinfopo:= funitinfopo^.p.classinfolist.newitem; + with classinfopo^ do begin + inimplementation:= fimplementation; + managedstart:= lasttokenpos; + name:= lstringtostring(value); + uppername:= uppercase(name); + if checkoperator('(') then begin + ar1:= getnamelist; + result:= checkoperator(')'); + end + else begin + ar1:= nil; + end; + headerstop:= getsourcepos(acttoken); + if ar1 <> nil then begin + parentname:= lstringtostring(ar1[0]); + end + else begin + parentname:= 'TObject'; + end; + if result then begin + deflist:= funitinfopo^.deflist.beginnode(getsourcepos(token1),classinfopo); + first:= true; + while not eof do begin + ident1:= getclassident; + case ident1 of + pid_end,pid_private,pid_protected,pid_public,pid_published,pid_automated, + pid_implementation: begin + if isemptysourcepos(managedend) then begin + managedend:= lasttokenpos; + end; + if isemptysourcepos(procedurestart) then begin + procedurestart:= managedend; + end; + if (ident1 = pid_private) then begin + if isemptysourcepos(privatestart) then begin + privatestart:= sourcepos; + end; + end + else begin + if not isemptysourcepos(privatestart) and + isemptysourcepos(privateend) then begin + privateend:= lasttokenpos; + if isemptysourcepos(privatefieldend) then begin + privatefieldend:= privateend; + end; + end; + end; + if ident1 = pid_end then begin + break; + end; + end; + pid_class,pid_procedure,pid_method,pid_function, + pid_constructor,pid_destructor: begin + if isemptysourcepos(privatefieldend) and + not isemptysourcepos(privatestart) and + isemptysourcepos(privateend) then begin + privatefieldend:= lasttokenpos; + end; + parseclassprocedureheader(ident1,classinfopo, + isemptysourcepos(managedend)); + end; + else begin + pos1:= sourcepos; + ar1:= getorignamelist; + if high(ar1) >= 0 then begin + if isemptysourcepos(managedend) and (ident1 <> pid_property) then begin + pc:= componentlist.newitem; //managed component + bo1:= false; + with pc^ do begin + insertpos:= lasttokenpos; + namepos:= pos1; + nameend:= sourcepos; + if checkoperator(':') then begin + skipwhitespace; + typepos:= sourcepos; + if getorigname(lstr2) then begin + typeend:= sourcepos; + name:= lstringtostring(ar1[0]); + uppername:= uppercase(name); + typename:= lstringtostring(lstr2); + uppertypename:= uppercase(typename); + checkoperator(';'); + checknewline; + endpos:= sourcepos; + bo1:= true; + funitinfopo^.deflist.add(name,syk_vardef,namepos,endpos); + end; + end; + end; + if not bo1 then begin + componentlist.deletelast; + nexttoken; + end + else begin + for int1:= 1 to high(ar1) do begin + pc1:= componentlist.newitem; //managed component + pc1^:= pc^; + pc1^.name:= lstringtostring(ar1[int1]); + pc1^.uppername:= uppercase(pc1^.name); + end; + end; + end + else begin + if ident1 = pid_property then begin + if checkoperator('[') then begin + while not eof and not checkoperator(']') do begin + nexttoken; + end; + end; + end; + if checkoperator(':') then begin + while not eof and not checkoperator(';') do begin + nexttoken; + end; + pd:= funitinfopo^.deflist.add(lstringtostring(ar1[0]), + syk_vardef,pos1,sourcepos); + if ident1 = pid_property then begin + pd^.varflags:= [vf_property]; + end; + for int1:= 1 to high(ar1) do begin + funitinfopo^.deflist.add(lstringtostring(ar1[int1]), + syk_vardef,pos1,sourcepos) + end; + end; + end; + end + else begin + if first and (getoperator = ';') then begin + break; //xxx = class(tclassxx); + end; + nexttoken; + end; + end; + end; + first:= false; + end; + if result then begin + funitinfopo^.deflist.endnode(sourcepos); + end + else begin + funitinfopo^.deflist.deletenode; + end; + end; + end; + if not result then begin + funitinfopo^.p.classinfolist.deletelast; + end; + end; + end; +end; + +function tpascaldesignparser.parserecord: boolean; + //todo: parse subitems +var + ident1: pascalidentty; + blocklevel: integer; +begin + result:= true; + blocklevel:= 1; + while not eof and (blocklevel > 0) do begin + ident1:= pascalidentty(getident); + case ident1 of + pid_end: begin + dec(blocklevel) + end; + pid_begin,pid_record: begin + inc(blocklevel) + end; + end; + nexttoken; + end; +end; + +function tpascaldesignparser.parseobject: boolean; + //todo: parse subitems +var + ident1: pascalidentty; + blocklevel: integer; +begin + result:= true; + blocklevel:= 1; + while not eof and (blocklevel > 0) do begin + ident1:= pascalidentty(getident); + case ident1 of + pid_end: begin + dec(blocklevel); + nexttoken; + end; + pid_begin,pid_record: begin + inc(blocklevel); + nexttoken; + end; + pid_procedure,pid_method,pid_function: begin + skipprocedureheader(ident1); + end; + else begin + nexttoken; + end; + end; + end; +end; + +procedure tpascaldesignparser.parselabel; +var + ident1: pascalidentty; +begin + while not eof do begin + skipwhitespace; + ident1:= pascalidentty(getident); + case ident1 of + pid_type,pid_const,pid_var,pid_implementation,pid_function, + pid_procedure,pid_method, + pid_constructor,pid_destructor,pid_begin: begin + lasttoken; + break; + end; + pid_label: begin + end; + else begin + nexttoken; + end; + end; + end; +end; + +procedure tpascaldesignparser.parsetype; +var + statementstart: tokenidty; + ident1: pascalidentty; + lstr1: lstringty; +// bo1: boolean; +begin + while not eof do begin + skipwhitespace; + statementstart:= acttoken; + ident1:= pascalidentty(getident); + case ident1 of + pid_label,pid_const,pid_var,pid_implementation,pid_function, + pid_procedure,pid_method, + pid_constructor,pid_destructor,pid_begin: begin + lasttoken; + break; + end; + pid_type: begin + end; + else begin + if (ident1 = pid_invalid) and getorigname(lstr1) and + checkoperator('=') then begin + ident1:= pascalidentty(getident); + case ident1 of + pid_interface: begin + mark; + acttoken:= statementstart; + if parseinterfacetype then begin + pop; + funitinfopo^.deflist.add(lstringtostring(lstr1),syk_interfacedef, + getsourcepos(statementstart),sourcepos); + end + else begin + back; + end; + end; + pid_class,pid_object: begin + mark; + acttoken:= statementstart; + if parseclasstype then begin + pop; + end + else begin + back; + end; + end; + { + pid_object: begin + parseobject; + funitinfopo^.deflist.add(lstringtostring(lstr1),syk_typedef, + getsourcepos(statementstart),sourcepos); + end; + } + pid_record: begin + parserecord; + funitinfopo^.deflist.add(lstringtostring(lstr1),syk_typedef, + getsourcepos(statementstart),sourcepos); + end; + pid_procedure,pid_method,pid_function: begin + if skipprocedureparams(ident1) then begin + if checkident(ord(pid_of)) then begin + checkident(ord(pid_object)); + end; + checkoperator(';'); + funitinfopo^.deflist.add(lstringtostring(lstr1),syk_typedef, + getsourcepos(statementstart),sourcepos); + end; + end; + else begin + while not eof and not checkoperator(';') do begin + nexttoken; + end; + funitinfopo^.deflist.add(lstringtostring(lstr1),syk_typedef, + getsourcepos(statementstart),sourcepos); + end; + end; + end + else begin + nexttoken; //invalid + end; + end; + end; + end; +end; + +procedure tpascaldesignparser.parseconst; +var + ident1: integer; + apos: sourceposty; + str1: string; + +begin + while not eof do begin + ident1:= getident; + if ident1 >= 0 then begin + lasttoken; + break; + end; + if (fto^.kind = tk_name) then begin + apos:= sourcepos; + str1:= self.getorigtoken; + if checkoperator('=') then begin + //todo: parse typed constants + while not eof and not checkoperator(';') do begin + nexttoken; + end; + funitinfopo^.deflist.add(str1,syk_constdef,apos,sourcepos); + end + else begin + while not eof and not checkoperator(';') do begin + nexttoken; + end; + end; + end + else begin + nexttoken; + end; + end; +end; + +procedure tpascaldesignparser.parsevar; +var + ident1: integer; + apos: sourceposty; + ar1: lstringarty; + int1: integer; + +begin + ar1:= nil; //compiler warning + while not eof do begin + ident1:= getident; + if (ident1 >= 0) and (ident1 <> ord(pid_threadvar)) then begin + lasttoken; + break; + end; + if fto^.kind = tk_name then begin + apos:= sourcepos; + ar1:= getorignamelist; + if checkoperator(':') then begin + while not eof and not checkoperator(';') do begin + nexttoken; + end; + for int1:= 0 to high(ar1) do begin + funitinfopo^.deflist.add(lstringtostring(ar1[int1]),syk_vardef, + apos,sourcepos); + end; + end + else begin + while not eof and not checkoperator(';') do begin + nexttoken; + end; + end; + end + else begin + nexttoken; + end; + end; +end; + +procedure tpascaldesignparser.parseprocedurebody; + + procedure getidentinfo; + var + bracketlevel: integer; + pos1: sourceposty; + begin + funitinfopo^.deflist.actnode.startident(self); + while checkoperator('.') do begin + skipwhitespace; + if fto^.kind = tk_name then begin + funitinfopo^.deflist.actnode.addident(self); + end + else begin + funitinfopo^.deflist.actnode.addemptyident(self); + end; + end; + if checkoperator('(') then begin + mark; + bracketlevel:= 0; + while not eof and (bracketlevel >= 0) do begin + if checkoperator('(') then begin + inc(bracketlevel); + end + else begin + if checkoperator(')') then begin + dec(bracketlevel); + end + else begin + nexttoken; + end; + end; + end; + pos1:= sourcepos; + back; + funitinfopo^.deflist.actnode.endident(self,pos1); + end + else begin + skipwhitespace; + funitinfopo^.deflist.actnode.endident(self); + end; + end; + +var + blocklevel: integer; + aident: integer; + str1: string; + +begin + blocklevel:= 0; + while not eof and (blocklevel >= 0) do begin + if getident(aident) then begin + case pascalidentty(aident) of + pid_begin,pid_try,pid_case: begin + inc(blocklevel); + end; + pid_end: begin + dec(blocklevel); + end; + end; + end + else begin + if (fto^.kind = tk_name) then begin + getidentinfo; + end + else begin + if (fto^.kind = tk_operator) and (fto^.op = '''') and + getpascalstring(str1) then begin + + end + else begin + nexttoken; + end; + end; + end; + end; +end; + +procedure tpascaldesignparser.parseimplementation; + +var + procnestinglevel: integer; + + procedure parseprocedure(const akind: methodkindty); + var + classname,procname: lstringty; + po1: pclassinfoty; + po2: pprocedureinfoty; + po3: pdefinfoty; + methodinfo: methodparaminfoty; + aident: integer; + deflist1: tdeflist1; + + procedure setprocinfo(const ainfo: pprocedureinfoty); + var + lstr1: lstringty; + begin + with ainfo^ do begin + params:= methodinfo; + lstr1:= procname; + inc(lstr1.po,origoffset); + name:= lstringtostring(lstr1); + uppername:= lstringtostring(procname); + end; + end;//setprocinfo + var + pos1,pos2: sourceposty; + i1: int32; + isforward: boolean; + kind1: symbolkindty; + label + endlab; + begin + if procnestinglevel < 32 then begin + isforward:= false; + classname.po:= nil; + classname.len:= 0; + inc(procnestinglevel); + lasttoken; + pos1:= sourcepos; + nexttoken; + if getname(procname) then begin + if checkoperator('.') then begin + classname:= procname; + getname(procname); + po1:= funitinfopo^.p.classinfolist.finditembyname(classname,false); + if (po1 <> nil) and isemptysourcepos(po1^.procimpstart) then begin + po1^.procimpstart:= pos1; + end; + end + else begin + po1:= nil; + end; + methodinfo.kind:= akind; + methodinfo.flags:= []; + if parseprocparams(methodinfo.kind,methodinfo.flags, + methodinfo.params,classname.po <> nil) then begin + pos2:= sourcepos; + if po1 <> nil then begin //class or object + po2:= po1^.procedurelist.finditembyuppername(procname,methodinfo,true); + //can update methodinfo + if po2 = nil then begin + po2:= po1^.procedurelist.newitem; + setprocinfo(po2); + end; + po3:= funitinfopo^.deflist.beginnode( + lstringtostring(classname)+'.'+lstringtostring(procname)+ + mangleprocparams(methodinfo), + syk_classprocimp,pos1,sourcepos); + deflist1:= tdeflist1(po3^.deflist); +// if po2 <> nil then begin +// po2^.impheaderstartpos:= pos1; +// po2^.impheaderendpos:= sourcepos; +// end; + deflist1.fparentscope:= po1^.deflist; + end + else begin + if checkident(ord(pid_forward)) then begin + include(methodinfo.flags,mef_forward); + isforward:= true; + checkoperator(';'); + skipwhitespaceonly(); + pos2:= sourcepos; + end; + po2:= nil; + if not isforward then begin + po2:= funitinfopo^.p.procedurelist.finditembyuppername( + procname,methodinfo,false); + end; + if po2 = nil then begin + po2:= funitinfopo^.p.procedurelist.newitem; + setprocinfo(po2) + end; + kind1:= syk_procimp; + if isforward then begin + kind1:= syk_procdef; + end; + po3:= funitinfopo^.deflist.beginnode( + lstringtostring(procname)+mangleprocparams(methodinfo), + kind1,pos1,pos2); + deflist1:= tdeflist1(po3^.deflist); + po3^.procindex:= po2^.b.index; + po2:= nil; + end; + if po2 <> nil then begin + po3^.procindex:= po2^.b.index; + po2^.impheaderstartpos:= pos1; + po2^.impheaderendpos:= pos2; + end; + if not isforward then begin + for i1:= 0 to high(methodinfo.params) do begin + with methodinfo.params[i1] do begin + funitinfopo^.deflist.add(name,syk_pardef,start,stop); + end; + end; + end; + if isforward then begin + funitinfopo^.deflist.endnode(pos2); + goto endlab; + end; + while not eof do begin + if getident(aident) then begin + case pascalidentty(aident) of + pid_var: begin + parsevar; + end; + pid_const: begin + parseconst; + end; + pid_type: begin + parsetype; + end; + pid_label: begin + parselabel; + end; + pid_procedure,pid_method: begin + parseprocedure(mk_procedure); + end; + pid_function: begin + parseprocedure(mk_function); + end; + pid_begin: begin + parseprocedurebody; + break; + end; + else begin + break; + end; + end; + end + else begin + nexttoken; + end; + end; + checkoperator(';'); + checknewline; + pos1:= sourcepos; + funitinfopo^.deflist.endnode(pos1); + if po1 <> nil then begin + po1^.procimpend:= pos1; + if po2 <> nil then begin + po2^.impendpos:= po1^.procimpend; + end; + end; + end; + end; + endlab: + dec(procnestinglevel); + end; + end; + + procedure checkend; + begin + if isemptysourcepos(funitinfopo^.p.implementationend) then begin + lasttoken; + funitinfopo^.p.implementationend:= sourcepos; + nexttoken; + end; + end; + +var + aident: integer; + +begin + finterface:= false; + fimplementation:= true; + funitinfopo^.p.implementationstart:= sourcepos; + funitinfopo^.p.implementationbodystart:= funitinfopo^.p.implementationstart; + procnestinglevel:= 0; + while not eof do begin + if getident(aident) then begin; + case pascalidentty(aident) of + pid_procedure: begin + parseprocedure(mk_procedure); + end; + pid_method: begin + parseprocedure(mk_method); + end; + pid_function: begin + parseprocedure(mk_function); + end; + pid_constructor: begin + parseprocedure(mk_constructor); + end; + pid_destructor: begin + parseprocedure(mk_destructor); + end; + pid_type: begin + parsetype; + end; + pid_var: begin + parsevar; + end; + pid_uses: begin + with tusesinfolist1(funitinfopo^.p.implementationuses) do begin + fstartpos:= sourcepos; + add(getorignamelist); + fendpos:= sourcepos; + end; + checkoperator(';'); + checknewline; + funitinfopo^.p.implementationbodystart:= sourcepos; + end; + pid_begin: begin + if funitinfopo^.isprogram then begin + parseprocedurebody; + end; + end; + pid_initialization: begin + checkend; + funitinfopo^.p.initializationstart:= nexttokenornewlinepos; + end; + pid_finalization: begin + checkend; + funitinfopo^.p.finalizationstart:= nexttokenornewlinepos; + end; + pid_end: begin + if checkoperator('.') then begin + lasttoken; + checkend; + nexttoken; + break; + end; + end; + end; + end + else begin + nexttoken; + end; + end; + funitinfopo^.unitend:= sourcepos; + if isemptysourcepos(funitinfopo^.p.implementationend) then begin + lasttoken; + funitinfopo^.p.implementationend:= sourcepos; + end; +end; + +procedure tpascaldesignparser.parse; +var + int1: integer; + po1: pprocedureinfoty; + pos1: sourceposty; +begin + inherited parse; + if fnoautoparse then begin + exit; + end; + initcompinfo(funitinfopo^); + with funitinfopo^ do begin + int1:= getident; + isprogram:= pascalidentty(int1) = pid_program; + if isprogram or (pascalidentty(int1) = pid_unit) then begin + origunitname:= getorigname; + unitname:= uppercase(origunitname); + end; + if isprogram then begin + parseimplementation; + end + else begin + while not eof do begin + skipwhitespace; + pos1:= sourcepos; + int1:= getident; + case pascalidentty(int1) of + pid_type: begin + parsetype; + end; + pid_const: begin + parseconst; + end; + pid_var: begin + parsevar; + end; + pid_procedure,pid_method,pid_function: begin + po1:= p.procedurelist.newitem; + if parseprocedureheader(pascalidentty(int1),po1) then begin + deflist.add(pos1,sourcepos,po1); + end + else begin + p.procedurelist.deletelast; + end; + end; + pid_interface: begin + finterface:= true; + end; + pid_uses: begin + with tusesinfolist1(funitinfopo^.p.interfaceuses) do begin + fstartpos:= sourcepos; + add(getorignamelist); + fendpos:= sourcepos; + end; + end; + pid_implementation: begin + if not finterfaceonly then begin + parseimplementation; + end; + break; + end; + else begin + nexttoken; + end; + end; + end; + end; + afterparse(self,funitinfopo^,isprogram or not finterfaceonly); + end; +end; + +function tpascaldesignparser.dogetincludefile(const afilename: filenamety; + const astatementstart, astatementend: sourceposty): tscanner; +begin + result:= inherited dogetincludefile(afilename,astatementstart,astatementend); + if result <> nil then begin + addincludefile(funitinfopo^,afilename,astatementstart,astatementend); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/printform.mfm b/mseide-msegui/apps/ide/printform.mfm new file mode 100644 index 0000000..d10532c --- /dev/null +++ b/mseide-msegui/apps/ide/printform.mfm @@ -0,0 +1,252 @@ +object printfo: tprintfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 166 + bounds_y = 216 + bounds_cx = 392 + bounds_cy = 281 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.bounds = ( + 0 + 0 + 392 + 281 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Print File' + onidle = printidle + moduleclassname = 'tmseform' + object ok: tbutton + bounds_x = 264 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption, as_localonexecute] + caption = '&Ok' + onexecute = runonexecute + end + object cancel: tbutton + taborder = 1 + bounds_x = 328 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_top, an_right] + state = [as_localcaption, as_localonexecute] + caption = 'Cancel' + onexecute = cancelexec + end + object linenum: tbooleanedit + frame.caption = 'Print line'#10'&numbers' + frame.dummy = 0 + frame.outerframe = ( + 0 + 8 + 58 + 9 + ) + taborder = 6 + bounds_x = 112 + bounds_y = 68 + bounds_cx = 71 + bounds_cy = 30 + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + end + object fontsize: trealedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_destroywidgets] + frame.caption = 'Font &size (Pt)' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 16 + 0 + ) + taborder = 5 + bounds_x = 16 + bounds_y = 55 + bounds_cx = 84 + bounds_cy = 37 + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 35.2778 + valuedefault = -Inf + formatedit = '0.0' + formatdisp = '0.0' + valuerange = 0.28346438836889 + valuestart = 0 + min = 21.1667 + max = 49.3889 + reffontheight = 14 + end + object titlefont: tstringedit + frame.caption = '&Title font' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 9 + bounds_x = 16 + bounds_y = 119 + bounds_cx = 361 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 'Helvetica' + onsetvalue = titlefosetvalue + reffontheight = 14 + end + object sourcefont: tstringedit + frame.caption = 'So&urce font' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 10 + bounds_x = 16 + bounds_y = 167 + bounds_cx = 361 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 'Courier' + onsetvalue = sourcefosetvalue + reffontheight = 14 + end + object colorset: tbooleanedit + frame.caption = '&Color' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 35 + 2 + ) + taborder = 7 + bounds_x = 192 + bounds_y = 75 + bounds_cx = 48 + bounds_cy = 16 + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + end + object tpagesizeselector1: tpagesizeselector + frame.caption = 'Paper size' + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 184 + bounds_y = 7 + bounds_cx = 79 + bounds_cy = 37 + anchors = [an_top, an_right] + dropdown.width = 180 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + printer = printer + reffontheight = 14 + end + object tpageorientationselector1: tpageorientationselector + frame.caption = 'Paper orientation' + frame.outerframe = ( + 0 + 17 + 10 + 0 + ) + taborder = 4 + bounds_x = 275 + bounds_y = 7 + bounds_cx = 112 + bounds_cy = 37 + anchors = [an_top, an_right] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + printer = printer + reffontheight = 14 + end + object rotate: tbooleanedit + frame.caption = 'Rotate CCW' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 76 + 2 + ) + taborder = 8 + bounds_x = 283 + bounds_y = 75 + bounds_cx = 89 + bounds_cy = 16 + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + end + object pages: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + frame.caption = 'Pages' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 16 + bounds_y = 7 + bounds_cx = 156 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = pagessetvalue + reffontheight = 14 + end + object printer: tpostscriptprinter + canvas.font.color = -1610612734 + canvas.font.xscale = 1 + canvas.font.dummy = 0 + canvas.ppmm = 10 + onpagestart = pronpagestart + pa_width = 210 + pa_height = 297 + pa_size = sps_a4 + tabulators.defaultdist = 0 + statfile = tstatfile1 + printcommand = 'lp -' + left = 184 + top = 96 + end + object tstatfile1: tstatfile + filename = 'printer.sta' + options = [sfo_memory] + left = 80 + top = 112 + end + object c: tstringcontainer + strings.data = ( + 'Page' + 'Do you wish to cancel printing?' + ) + left = 80 + top = 216 + end +end diff --git a/mseide-msegui/apps/ide/printform.pas b/mseide-msegui/apps/ide/printform.pas new file mode 100644 index 0000000..e609296 --- /dev/null +++ b/mseide-msegui/apps/ide/printform.pas @@ -0,0 +1,178 @@ +unit printform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegui,mseclasses,mseforms,msesimplewidgets,msepostscriptprinter,mseprinter, + msedataedits,msethreadcomp,msegraphedits,msestrings,msegraphics,msestat, + msestatfile,msetypes,mseglob,msestringcontainer; + +type + tprintfo = class(tmseform) + ok: tbutton; + cancel: tbutton; + printer: tpostscriptprinter; + linenum: tbooleanedit; + fontsize: trealedit; + colorset: tbooleanedit; + rotate: tbooleanedit; + titlefont: tstringedit; + sourcefont: tstringedit; + tpageorientationselector1: tpageorientationselector; + tpagesizeselector1: tpagesizeselector; + tstatfile1: tstatfile; + pages: tstringedit; + c: tstringcontainer; + procedure pronpagestart(const sender: tcustomprinter); + procedure printidle(var again: Boolean); + procedure runonexecute(const sender: TObject); + procedure cancelexec(const sender: TObject); + procedure sourcefosetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure titlefosetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure pagessetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + protected + run,started: boolean; + rowindex: integer; + font1: tfont; + end; + +procedure print; + +implementation +uses + printform_mfm,main,sourceform,msestream,msesys,msegraphutils,msedrawtext, + msesettings,msereal,msewidgets,sysutils,projectoptionsform,mserichstring, + mseguiglob,mseformatstr; +type + stringconsts = ( + page, //0 Page + wishcancel //1 Do you wish to cancel printing? + ); + +procedure tprintfo.printidle(var again: Boolean); +begin + try + with printer,canvas do begin + if run then begin + if not started then begin + pagesstring:= self.pages.value; + started:= true; + beginprint(getprintcommand); + if colorset.value then begin + colorspace:= cos_rgb; + end + else begin + colorspace:= cos_gray; + end; + if rotate.value then begin + printorientation:= pao_landscape; + end + else begin + printorientation:= pao_portrait; + end; + font.name:= ansistring(sourcefont.value); + font.height:= round(fontsize.value); + headerheight:= round(fontsize.value*5/3); + if linenum.value then begin + indentx:= round(4*fontsize.value); + end; + font1.assign(font); + font1.name:= ansistring(titlefont.value); + end; + with sourcefo.activepage.edit do begin + if rowindex >= datalist.count then begin + run:= false; + self.window.modalresult:= mr_ok; + end + else begin + if linenum.value then begin + drawtext(inttostrmse(linenumber+1), + makerect(0,liney,round(3*fontsize.value),0),[tf_right],font1); + end; + writeln(expandtabs(richlines[rowindex],projectoptions.e.tabstops)); + inc(rowindex); + again:= true; + end; + end; + end; + end; + except + run:= false; + window.modalresult:= mr_exception; + raise; + end; +end; + +procedure print; +var + fo1: tprintfo; +begin + fo1:= tprintfo.create(nil); + fo1.font1:= tfont.create; + try + fo1.show(true); + finally + fo1.font1.free; + fo1.free; + end; +end; + +procedure tprintfo.pronpagestart(const sender: tcustomprinter); +begin + with sender.canvas do begin + save; + font.name:= ansistring(titlefont.value); + drawtext(sourcefo.activepage.filepath,makerect(0,0,clientsize.cx- + round(10*fontsize.value),0),[tf_ellipseleft]); + drawtext(c[ord(page)]+' '+inttostrmse(pagenumber+1), + makerect(clientsize.cx,0,0,0),[tf_right]); + restore; + end; +end; + +procedure tprintfo.runonexecute(const sender: TObject); +begin + if window.candefocus then begin + run:= true; + ok.enabled:= false; + end; +end; + +procedure tprintfo.cancelexec(const sender: TObject); +begin + if run then begin + if askyesno(c[ord(wishcancel)]) then begin + run:= false; + window.modalresult:= mr_cancel; + end; + end + else begin + window.modalresult:= mr_cancel; + end; +end; + +procedure tprintfo.sourcefosetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); +begin + if avalue = '' then begin + avalue:= defaultsourceprintfont; + end; +end; + +procedure tprintfo.titlefosetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); +begin + if avalue = '' then begin + avalue:= defaulttitleprintfont; + end; +end; + +procedure tprintfo.pagessetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); +begin + stringtopages(avalue); +end; + +end. diff --git a/mseide-msegui/apps/ide/printform_mfm.pas b/mseide-msegui/apps/ide/printform_mfm.pas new file mode 100644 index 0000000..7486b92 --- /dev/null +++ b/mseide-msegui/apps/ide/printform_mfm.pas @@ -0,0 +1,246 @@ +unit printform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,printform; + +const + objdata: record size: integer; data: array[0..4560] of byte end = + (size: 4561; data: ( + 84,80,70,48,8,116,112,114,105,110,116,102,111,7,112,114,105,110,116,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,3,166,0,8,98,111,117,110,100,115,95, + 121,3,216,0,9,98,111,117,110,100,115,95,99,120,3,136,1,9,98,111, + 117,110,100,115,95,99,121,3,25,1,23,99,111,110,116,97,105,110,101,114, + 46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115, + 117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97,110, + 115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,136,1,3,25,1,0,7,111,112,116,105, + 111,110,115,11,17,102,111,95,115,99,114,101,101,110,99,101,110,116,101,114, + 101,100,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95, + 97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111, + 119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115, + 13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95,115,97, + 118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,10,116, + 115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6,10,80, + 114,105,110,116,32,70,105,108,101,6,111,110,105,100,108,101,7,9,112,114, + 105,110,116,105,100,108,101,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,8,116,109,115,101,102,111,114,109,0,7,116,98,117,116,116, + 111,110,2,111,107,8,98,111,117,110,100,115,95,120,3,8,1,8,98,111, + 117,110,100,115,95,121,3,232,0,9,98,111,117,110,100,115,95,99,120,2, + 50,9,98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104,111,114, + 115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5, + 115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115, + 95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,3,38,79, + 107,9,111,110,101,120,101,99,117,116,101,7,12,114,117,110,111,110,101,120, + 101,99,117,116,101,0,0,7,116,98,117,116,116,111,110,6,99,97,110,99, + 101,108,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,3,72,1,8,98,111,117,110,100,115,95,121,3,232,0,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 22,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,6,67, + 97,110,99,101,108,9,111,110,101,120,101,99,117,116,101,7,10,99,97,110, + 99,101,108,101,120,101,99,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,7,108,105,110,101,110,117,109,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,19,80,114,105,110,116,32,108,105,110,101,10,38,110,117, + 109,98,101,114,115,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 8,2,58,2,9,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111, + 117,110,100,115,95,120,2,112,8,98,111,117,110,100,115,95,121,2,68,9, + 98,111,117,110,100,115,95,99,120,2,71,9,98,111,117,110,100,115,95,99, + 121,2,30,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102, + 105,108,101,49,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,0,0,9,116,114,101,97,108,101,100,105,116,8,102, + 111,110,116,115,105,122,101,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,15,70,111,110, + 116,32,38,115,105,122,101,32,40,80,116,41,11,102,114,97,109,101,46,100, + 117,109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,16,2,0,0,8,116,97,98,111,114,100, + 101,114,2,5,8,98,111,117,110,100,115,95,120,2,16,8,98,111,117,110, + 100,115,95,121,2,55,9,98,111,117,110,100,115,95,99,120,2,84,9,98, + 111,117,110,100,115,95,99,121,2,37,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,0,5,118,97,108,117,101,5, + 242,176,80,107,154,119,28,141,4,64,12,118,97,108,117,101,100,101,102,97, + 117,108,116,5,0,0,0,0,0,0,0,128,255,255,10,102,111,114,109,97, + 116,101,100,105,116,6,3,48,46,48,10,102,111,114,109,97,116,100,105,115, + 112,6,3,48,46,48,10,118,97,108,117,101,114,97,110,103,101,5,16,82, + 3,64,139,62,34,145,253,63,10,118,97,108,117,101,115,116,97,114,116,2, + 0,3,109,105,110,5,215,18,242,65,207,102,85,169,3,64,3,109,97,120, + 5,121,88,168,53,205,59,142,197,4,64,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105, + 116,9,116,105,116,108,101,102,111,110,116,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,11,38,84,105,116,108,101,32,102,111,110,116,11,102, + 114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100,115,95,120,2, + 16,8,98,111,117,110,100,115,95,121,2,119,9,98,111,117,110,100,115,95, + 99,120,3,105,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,0,8,115,116,97,116,102,105,108,101, + 7,10,116,115,116,97,116,102,105,108,101,49,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,5,118,97,108,117,101, + 6,9,72,101,108,118,101,116,105,99,97,10,111,110,115,101,116,118,97,108, + 117,101,7,15,116,105,116,108,101,102,111,115,101,116,118,97,108,117,101,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115, + 116,114,105,110,103,101,100,105,116,10,115,111,117,114,99,101,102,111,110,116, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,83,111,38,117, + 114,99,101,32,102,111,110,116,11,102,114,97,109,101,46,100,117,109,109,121, + 2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,10, + 8,98,111,117,110,100,115,95,120,2,16,8,98,111,117,110,100,115,95,121, + 3,167,0,9,98,111,117,110,100,115,95,99,120,3,105,1,9,98,111,117, + 110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105, + 108,101,49,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,5,118,97,108,117,101,6,7,67,111,117,114,105,101,114, + 10,111,110,115,101,116,118,97,108,117,101,7,16,115,111,117,114,99,101,102, + 111,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 8,99,111,108,111,114,115,101,116,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,6,38,67,111,108,111,114,11,102,114,97,109,101,46,100,117, + 109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,35,2,2,0,8,116,97,98,111,114,100,101, + 114,2,7,8,98,111,117,110,100,115,95,120,3,192,0,8,98,111,117,110, + 100,115,95,121,2,75,9,98,111,117,110,100,115,95,99,120,2,48,9,98, + 111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,0,0,0,17,116,112,97,103, + 101,115,105,122,101,115,101,108,101,99,116,111,114,18,116,112,97,103,101,115, + 105,122,101,115,101,108,101,99,116,111,114,49,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,10,80,97,112,101,114,32,115,105,122,101,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,3,184,0,8,98,111,117,110,100,115,95,121,2,7,9, + 98,111,117,110,100,115,95,99,120,2,79,9,98,111,117,110,100,115,95,99, + 121,2,37,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8, + 97,110,95,114,105,103,104,116,0,14,100,114,111,112,100,111,119,110,46,119, + 105,100,116,104,3,180,0,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,105,116,101,109,115,14,1,0,0,7,112,114,105,110,116,101, + 114,7,7,112,114,105,110,116,101,114,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,24,116,112,97,103,101,111,114,105,101,110,116, + 97,116,105,111,110,115,101,108,101,99,116,111,114,25,116,112,97,103,101,111, + 114,105,101,110,116,97,116,105,111,110,115,101,108,101,99,116,111,114,49,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,17,80,97,112,101,114, + 32,111,114,105,101,110,116,97,116,105,111,110,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,10,2,0,0,8, + 116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3, + 19,1,8,98,111,117,110,100,115,95,121,2,7,9,98,111,117,110,100,115, + 95,99,120,2,112,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111, + 117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46, + 105,116,101,109,115,14,1,0,0,7,112,114,105,110,116,101,114,7,7,112, + 114,105,110,116,101,114,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,114,111, + 116,97,116,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10, + 82,111,116,97,116,101,32,67,67,87,11,102,114,97,109,101,46,100,117,109, + 109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,1,2,76,2,2,0,8,116,97,98,111,114,100,101,114, + 2,8,8,98,111,117,110,100,115,95,120,3,27,1,8,98,111,117,110,100, + 115,95,121,2,75,9,98,111,117,110,100,115,95,99,120,2,89,9,98,111, + 117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,10, + 116,115,116,97,116,102,105,108,101,49,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,0,0,0,11,116,115,116,114,105, + 110,103,101,100,105,116,5,112,97,103,101,115,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101, + 108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5,80,97,103,101, + 115,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2, + 0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,16,8,98,111,117,110,100,115,95,121,2,7,9,98,111,117,110, + 100,115,95,99,120,3,156,0,9,98,111,117,110,100,115,95,99,121,2,37, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,10,111,110,115,101,116, + 118,97,108,117,101,7,13,112,97,103,101,115,115,101,116,118,97,108,117,101, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,18,116, + 112,111,115,116,115,99,114,105,112,116,112,114,105,110,116,101,114,7,112,114, + 105,110,116,101,114,17,99,97,110,118,97,115,46,102,111,110,116,46,99,111, + 108,111,114,4,2,0,0,160,18,99,97,110,118,97,115,46,102,111,110,116, + 46,120,115,99,97,108,101,2,1,17,99,97,110,118,97,115,46,102,111,110, + 116,46,100,117,109,109,121,2,0,11,99,97,110,118,97,115,46,112,112,109, + 109,2,10,11,111,110,112,97,103,101,115,116,97,114,116,7,13,112,114,111, + 110,112,97,103,101,115,116,97,114,116,8,112,97,95,119,105,100,116,104,3, + 210,0,9,112,97,95,104,101,105,103,104,116,3,41,1,7,112,97,95,115, + 105,122,101,7,6,115,112,115,95,97,52,22,116,97,98,117,108,97,116,111, + 114,115,46,100,101,102,97,117,108,116,100,105,115,116,2,0,8,115,116,97, + 116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,12,112,114, + 105,110,116,99,111,109,109,97,110,100,6,4,108,112,32,45,4,108,101,102, + 116,3,184,0,3,116,111,112,2,96,0,0,9,116,115,116,97,116,102,105, + 108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97, + 109,101,6,11,112,114,105,110,116,101,114,46,115,116,97,7,111,112,116,105, + 111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102, + 116,2,80,3,116,111,112,2,112,0,0,16,116,115,116,114,105,110,103,99, + 111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100, + 97,116,97,1,6,4,80,97,103,101,6,31,68,111,32,121,111,117,32,119, + 105,115,104,32,116,111,32,99,97,110,99,101,108,32,112,114,105,110,116,105, + 110,103,63,0,4,108,101,102,116,2,80,3,116,111,112,3,216,0,0,0, + 0) + ); + +initialization + registerobjectdata(@objdata,tprintfo,''); +end. diff --git a/mseide-msegui/apps/ide/programparametersform.mfm b/mseide-msegui/apps/ide/programparametersform.mfm new file mode 100644 index 0000000..8d146bf --- /dev/null +++ b/mseide-msegui/apps/ide/programparametersform.mfm @@ -0,0 +1,230 @@ +object programparametersfo: tprogramparametersfo + visible = False + bounds_x = 272 + bounds_y = 243 + bounds_cx = 328 + bounds_cy = 348 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 328 + 348 + ) + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = statfile1 + caption = 'Target Environment' + windowopacity = -Inf + moduleclassname = 'tmseform' + object workingdirectory: tfilenameedit + frame.caption = '&Working directory' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 2 + bounds_y = 9 + bounds_cx = 324 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + controller.options = [fdo_directory] + controller.captionopen = 'Select program working directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object ok: tbutton + taborder = 4 + bounds_x = 216 + bounds_y = 320 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object tbutton2: tbutton + bounds_x = 272 + bounds_y = 320 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object parameters: tmemodialoghistoryedit + frame.caption = '&Parameters' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + end + item + color = -2147483646 + imagenr = 17 + end> + frame.buttondialog.color = -2147483646 + frame.buttondialog.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 2 + bounds_y = 57 + bounds_cx = 324 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + dropdown.options = [deo_keydropdown, deo_autosavehistory, deo_cliphint] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object grid: twidgetgrid + frame.caption = 'Environment variables' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 2 + bounds_y = 111 + bounds_cx = 324 + bounds_cy = 195 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_savestate, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 3 + captions.items = < + item + caption = 'on' + end + item + caption = 'Name' + end + item + caption = 'Value' + end> + end> + datacols.count = 3 + datacols.options = [co_savestate] + datacols.items = < + item[envvaron] + width = 20 + options = [co_drawfocus, co_savestate] + widgetname = 'envvaron' + dataclass = tgridintegerdatalist + end + item[envvarname] + width = 103 + options = [co_proportional, co_savestate] + widgetname = 'envvarname' + dataclass = tgridmsestringdatalist + end + item[envvarvalue] + width = 194 + options = [co_fill, co_savestate] + widgetname = 'envvarvalue' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object envvaron: tbooleanedit + optionswidget1 = [] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 20 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object envvarname: tstringedit + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 2 + visible = False + bounds_x = 21 + bounds_y = 0 + bounds_cx = 103 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object envvarvalue: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 3 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 125 + bounds_y = 0 + bounds_cx = 194 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + end + object statfile1: tstatfile + filename = 'programparametersfo.sta' + options = [sfo_memory] + left = 176 + top = 96 + end +end diff --git a/mseide-msegui/apps/ide/programparametersform.pas b/mseide-msegui/apps/ide/programparametersform.pas new file mode 100644 index 0000000..d88305d --- /dev/null +++ b/mseide-msegui/apps/ide/programparametersform.pas @@ -0,0 +1,123 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit programparametersform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msestat,mseglob,msestatfile,msesimplewidgets,msedataedits,msefiledialog, + msewidgetgrid,msegraphedits,msememodialog,msegui,msetypes{msestrings}; + +type + tprogramparametersfo = class(tmseform) + + ok: tbutton; + envvaron: tbooleanedit; + tbutton2: tbutton; + parameters: tmemodialoghistoryedit; + statfile1: tstatfile; + envvarname: tstringedit; + envvarvalue: tmemodialogedit; + grid: twidgetgrid; + workingdirectory: tfilenameedit; + procedure hintexpandedmacros(const sender: TObject; var info: hintinfoty); + procedure expandfilename(const sender: TObject; var avalue: msestring; + var accept: Boolean); + end; + +procedure editprogramparameters; +procedure updatestat(const filer: tstatfiler); + +implementation +uses + programparametersform_mfm,projectoptionsform,mseguiglob,mseedit; + +procedure editprogramparameters; +var + fo: tprogramparametersfo; +begin + fo:= tprogramparametersfo.create(nil); + try + with projectoptions,d.t do begin + fo.parameters.value:= progparameters; + fo.parameters.dropdown.valuelist.asarray:= progparamhistory; + fo.workingdirectory.value:= progworkingdirectory; + fo.workingdirectory.controller.history:= workdirparamhistory; + fo.envvaron.gridvalues:= envvarons; + fo.envvarname.gridvalues:= envvarnames; + fo.envvarvalue.gridvalues:= envvarvalues; + end; + if fo.show(true,nil) = mr_ok then begin + fo.grid.removeappendedrow; + with projectoptions,d.t do begin + progparameters:= fo.parameters.value; + progparamhistory:= fo.parameters.dropdown.valuelist.asarray; + progworkingdirectory:= fo.workingdirectory.value; + workdirparamhistory:= fo.workingdirectory.controller.history; + envvarons:= fo.envvaron.gridvalues; + envvarnames:= fo.envvarname.gridvalues; + envvarvalues:= fo.envvarvalue.gridvalues; + end; + expandprojectmacros; + end; + finally + fo.Free; + end; +end; + +procedure updatestat(const filer: tstatfiler); +begin + filer.setsection('progparams'); //backward compatibility + with projectoptions,d,tstatreader(filer) do begin + if not filer.iswriter then begin + with t do begin + progparameters:= readmsestring('parameters',progparameters); +// progparamhistory:= readarray('progparamhistory',propgparamhistory); + progworkingdirectory:= + readmsestring('workingdirectory',progworkingdirectory); +// envvarons:= readarray('envvarons',envvarons); + envvarnames:= readarray('envvarnames',envvarnames); + envvarvalues:= readarray('envvarvalues',envvarvalues); + end; + end; + +// filer.updatevalue('parameters',progparameters); + filer.updatevalue('progparamhistory',progparamhistory); + filer.updatevalue('workdirparamhistory',workdirparamhistory); +// filer.updatevalue('workingdirectory',progworkingdirectory); + filer.updatevalue('envvarons',envvarons); + // filer.updatevalue('envvarnames',envvarnames); +// filer.updatevalue('envvarvalues',envvarvalues); + end; +end; + +procedure tprogramparametersfo.hintexpandedmacros(const sender: TObject; + var info: hintinfoty); +begin + info.caption:= tcustomedit(sender).text; + expandprmacros1(info.caption); + include(info.flags,hfl_show); //show empty caption +end; + +procedure tprogramparametersfo.expandfilename(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + expandprmacros1(avalue); +end; + +end. diff --git a/mseide-msegui/apps/ide/programparametersform_mfm.pas b/mseide-msegui/apps/ide/programparametersform_mfm.pas new file mode 100644 index 0000000..320de8d --- /dev/null +++ b/mseide-msegui/apps/ide/programparametersform_mfm.pas @@ -0,0 +1,241 @@ +unit programparametersform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,programparametersform; + +const + objdata: record size: integer; data: array[0..4464] of byte end = + (size: 4465; data: ( + 84,80,70,48,20,116,112,114,111,103,114,97,109,112,97,114,97,109,101,116, + 101,114,115,102,111,19,112,114,111,103,114,97,109,112,97,114,97,109,101,116, + 101,114,115,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,16,1,8,98,111,117,110,100,115,95,121,3,243,0,9,98, + 111,117,110,100,115,95,99,120,3,72,1,9,98,111,117,110,100,115,95,99, + 121,3,92,1,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115, + 1,2,0,2,0,3,72,1,3,92,1,0,7,111,112,116,105,111,110,115, + 11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,17,102,111,95,108, + 111,99,97,108,115,104,111,114,116,99,117,116,115,15,102,111,95,97,117,116, + 111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105, + 116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,13,102,111, + 95,115,97,118,101,122,111,114,100,101,114,0,8,115,116,97,116,102,105,108, + 101,7,9,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110, + 6,18,84,97,114,103,101,116,32,69,110,118,105,114,111,110,109,101,110,116, + 13,119,105,110,100,111,119,111,112,97,99,105,116,121,5,0,0,0,0,0, + 0,0,128,255,255,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,13,116,102,105,108,101,110,97, + 109,101,101,100,105,116,16,119,111,114,107,105,110,103,100,105,114,101,99,116, + 111,114,121,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,18,38, + 87,111,114,107,105,110,103,32,100,105,114,101,99,116,111,114,121,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111, + 114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102, + 114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0, + 0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103, + 101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,1,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116, + 101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100, + 115,95,120,2,2,8,98,111,117,110,100,115,95,121,2,9,9,98,111,117, + 110,100,115,95,99,120,3,68,1,9,98,111,117,110,100,115,95,99,121,2, + 37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,18,99,111,110,116, + 114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111,95, + 100,105,114,101,99,116,111,114,121,0,22,99,111,110,116,114,111,108,108,101, + 114,46,99,97,112,116,105,111,110,111,112,101,110,6,32,83,101,108,101,99, + 116,32,112,114,111,103,114,97,109,32,119,111,114,107,105,110,103,32,100,105, + 114,101,99,116,111,114,121,24,99,111,110,116,114,111,108,108,101,114,46,111, + 110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112,97,110,100, + 102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,7,116,98,117,116,116,111,110,2,111,107,8,116,97, + 98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,216,0, + 8,98,111,117,110,100,115,95,121,3,64,1,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99, + 104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97, + 117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112, + 116,105,111,110,6,2,79,75,11,109,111,100,97,108,114,101,115,117,108,116, + 7,5,109,114,95,111,107,0,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,50,8,98,111,117,110,100,115,95,120,3,16,1,8,98, + 111,117,110,100,115,95,121,3,64,1,9,98,111,117,110,100,115,95,99,120, + 2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,6,67,97,110, + 99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95, + 99,97,110,99,101,108,0,0,22,116,109,101,109,111,100,105,97,108,111,103, + 104,105,115,116,111,114,121,101,100,105,116,10,112,97,114,97,109,101,116,101, + 114,115,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11,38,80, + 97,114,97,109,101,116,101,114,115,22,102,114,97,109,101,46,99,97,112,116, + 105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116, + 116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108, + 111,114,4,2,0,0,128,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0, + 0,128,0,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103, + 101,110,114,2,17,0,0,24,102,114,97,109,101,46,98,117,116,116,111,110, + 100,105,97,108,111,103,46,99,111,108,111,114,4,2,0,0,128,26,102,114, + 97,109,101,46,98,117,116,116,111,110,100,105,97,108,111,103,46,105,109,97, + 103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,2,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110, + 116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110, + 100,115,95,120,2,2,8,98,111,117,110,100,115,95,121,2,57,9,98,111, + 117,110,100,115,95,99,120,3,68,1,9,98,111,117,110,100,115,95,99,121, + 2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,16,100,114,111, + 112,100,111,119,110,46,111,112,116,105,111,110,115,11,15,100,101,111,95,107, + 101,121,100,114,111,112,100,111,119,110,19,100,101,111,95,97,117,116,111,115, + 97,118,101,104,105,115,116,111,114,121,12,100,101,111,95,99,108,105,112,104, + 105,110,116,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99, + 111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115, + 46,105,116,101,109,115,14,1,0,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,11,116,119,105,100,103,101,116,103,114,105,100, + 4,103,114,105,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 21,69,110,118,105,114,111,110,109,101,110,116,32,118,97,114,105,97,98,108, + 101,115,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116, + 102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,2,2,8,98,111,117,110,100,115,95,121,2,111,9,98,111,117, + 110,100,115,95,99,120,3,68,1,9,98,111,117,110,100,115,95,99,121,3, + 195,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12, + 111,103,95,99,111,108,115,105,122,105,110,103,15,111,103,95,107,101,121,114, + 111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114, + 116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15, + 111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97, + 117,116,111,97,112,112,101,110,100,12,111,103,95,115,97,118,101,115,116,97, + 116,101,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98, + 107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117, + 116,111,112,111,112,117,112,0,13,102,105,120,114,111,119,115,46,99,111,117, + 110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1, + 6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99, + 111,117,110,116,2,3,14,99,97,112,116,105,111,110,115,46,105,116,101,109, + 115,14,1,7,99,97,112,116,105,111,110,6,2,111,110,0,1,7,99,97, + 112,116,105,111,110,6,4,78,97,109,101,0,1,7,99,97,112,116,105,111, + 110,6,5,86,97,108,117,101,0,0,0,0,14,100,97,116,97,99,111,108, + 115,46,99,111,117,110,116,2,3,16,100,97,116,97,99,111,108,115,46,111, + 112,116,105,111,110,115,11,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,101, + 110,118,118,97,114,111,110,1,5,119,105,100,116,104,2,20,7,111,112,116, + 105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,12,99, + 111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110, + 97,109,101,6,8,101,110,118,118,97,114,111,110,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,10,101,110,118,118,97,114,110,97,109,101,1,5, + 119,105,100,116,104,2,103,7,111,112,116,105,111,110,115,11,15,99,111,95, + 112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101, + 115,116,97,116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,10,101, + 110,118,118,97,114,110,97,109,101,9,100,97,116,97,99,108,97,115,115,7, + 22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108, + 105,115,116,0,7,11,101,110,118,118,97,114,118,97,108,117,101,1,5,119, + 105,100,116,104,3,194,0,7,111,112,116,105,111,110,115,11,7,99,111,95, + 102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119, + 105,100,103,101,116,110,97,109,101,6,11,101,110,118,118,97,114,118,97,108, + 117,101,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100, + 97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102, + 105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,8,101,110,118,118,97,114,111,110,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,20,9, + 98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117, + 112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101, + 13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105, + 98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0, + 11,116,115,116,114,105,110,103,101,100,105,116,10,101,110,118,118,97,114,110, + 97,109,101,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0, + 128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,21,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 103,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100,105,116,11,101, + 110,118,118,97,114,118,97,108,117,101,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111, + 114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102, + 114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0, + 0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103, + 101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,3,10,111,110,115, + 104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101, + 100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,2,125,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,3,194,0,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104,105, + 110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,116,97,116,102, + 105,108,101,9,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97, + 109,101,6,23,112,114,111,103,114,97,109,112,97,114,97,109,101,116,101,114, + 115,102,111,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111, + 95,109,101,109,111,114,121,0,4,108,101,102,116,3,176,0,3,116,111,112, + 2,96,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tprogramparametersfo,''); +end. diff --git a/mseide-msegui/apps/ide/projectoptionsform.mfm b/mseide-msegui/apps/ide/projectoptionsform.mfm new file mode 100644 index 0000000..9b730d7 --- /dev/null +++ b/mseide-msegui/apps/ide/projectoptionsform.mfm @@ -0,0 +1,6790 @@ +object projectoptionsfo: tprojectoptionsfo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 205 + bounds_y = 177 + bounds_cx = 832 + bounds_cy = 581 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.color = -2147483645 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fibottom, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + container.frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + container.frame.sbhorz.options = [sbo_moveauto, sbo_showauto] + container.face.localprops = [] + container.bounds = ( + 0 + 0 + 832 + 581 + ) + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = statfile1 + caption = 'Project Options' + windowopacity = -Inf + oncreate = createexe + moduleclassname = 'tmseform' + object tlayouter9: tlayouter + bounds_x = 0 + bounds_y = 0 + bounds_cx = 832 + bounds_cy = 581 + anchors = [] + optionslayout = [lao_placey] + place_maxdist = 0 + place_options = [plo_endmargin] + object tlayouter8: tlayouter + color = -2147483645 + frame.framei_top = 5 + frame.framei_bottom = 5 + frame.localprops = [frl_fitop, frl_fibottom] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 551 + bounds_cx = 832 + bounds_cy = 30 + anchors = [an_bottom] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny, lao_syncmaxautosize] + align_glue = wam_center + place_mindist = 5 + place_maxdist = 5 + place_mode = wam_end + place_options = [plo_propmargin] + linktop = tabwidget + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -2147483645 + bounds_x = 775 + bounds_y = 5 + bounds_cx = 52 + bounds_cy = 20 + state = [as_localcaption, as_localcolor] + caption = 'Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -2147483645 + taborder = 1 + bounds_x = 718 + bounds_y = 5 + bounds_cx = 52 + bounds_cy = 20 + state = [as_default, as_localdefault, as_localcaption, as_localcolor] + caption = 'Ok' + modalresult = mr_ok + reffontheight = 14 + end + end + object tabwidget: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + optionswidget1 = [ow1_fontglyphheight] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 832 + bounds_cy = 551 + color = -1879048187 + frame.levelo = -1 + frame.captionoffset = 3 + frame.localprops = [frl_levelo] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + anchors = [an_top, an_bottom] + taborder = 1 + activepageindex = 2 + tab_frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + tab_frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + tab_color = -2147483645 + tab_size = 19 + statfile = statfile1 + reffontheight = 14 + object editorpage: ttabpage + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.framei_bottom = 0 + frame.localprops = [frl_fibottom, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 5 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_top] + caption = '&Editor' + reffontheight = 14 + object ttabwidget3: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_destroywidgets] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + activepageindex = 0 + tab_frame.localprops = [] + tab_frame.localprops1 = [] + tab_size = 19 + statfile = statfile1 + object ttabpage23: ttabpage + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 511 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Source' + object ttabwidget2: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + bounds_x = 0 + bounds_y = 295 + bounds_cx = 830 + bounds_cy = 216 + bounds_cymin = 84 + anchors = [an_top, an_bottom] + taborder = 1 + activepageindex = 0 + tab_frame.localprops = [] + tab_frame.localprops1 = [] + tab_color = -2147483645 + tab_size = 19 + statfile = statfile1 + reffontheight = 14 + object ttabpage13: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.framei_bottom = 0 + frame.localprops = [frl_fibottom, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 197 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'File filter' + reffontheight = 14 + object filefiltergrid: tstringgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 197 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + datacols.count = 2 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item + width = 112 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + valuefalse = '0' + valuetrue = '1' + end + item + width = 684 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + valuefalse = '0' + valuetrue = '1' + end> + fixcols.count = 1 + fixcols.items = < + item + width = 27 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'File mask' + end> + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + end + end + object ttabpage14: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 197 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Syntax definition files' + reffontheight = 14 + object twidgetgrid6: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 197 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 26 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Syntax definition file' + end + item + caption = 'File mask' + end> + end> + datacols.count = 2 + datacols.options = [co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[syntaxdeffile] + width = 251 + options = [co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'syntaxdeffile' + dataclass = tgridmsestringdatalist + end + item[syntaxdeffilemask] + width = 546 + options = [co_fill, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'syntaxdeffilemask' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object syntaxdeffile: tfilenameedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 251 + bounds_cy = 16 + textflags = [tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'Syntaxdef files' + '*.sdef' + ) + ) + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object syntaxdeffilemask: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.localprops = [frl_levelo] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 252 + bounds_y = 0 + bounds_cx = 546 + bounds_cy = 16 + reffontheight = 14 + end + end + end + object ttabpage19: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 3 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 197 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Code templates' + object twidgetgrid5: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.options = [cfo_fixtop, cfo_fixbottom] + frame.caption = 'Code template directories, file extension = .mct' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 197 + bounds_cymin = 40 + anchors = [an_top, an_bottom] + optionsgrid = [og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 28 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 11 + captions.items = < + item + caption = 'Directory' + end + item + caption = 'O' + hint = 'Add to object file search path' + end + item + caption = 'L' + hint = 'Add to library search path' + end + item + caption = 'I' + hint = 'Add to include file search path' + end + item + caption = 'U' + hint = 'Add to unit file search path' + end + item + caption = '4' + hint = 'Use in Make 4' + end + item + caption = '3' + hint = 'Use in Make 3' + end + item + caption = '2' + hint = 'Use in Make 2' + end + item + caption = '1' + hint = 'Use in Make 1' + end + item + caption = 'B' + hint = 'Use in Build' + end + item + caption = 'M' + hint = 'Use in Make' + end> + end> + datacols.count = 1 + datacols.width = 13 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[codetemplatedirs] + linecolorfix = -1610612733 + width = 796 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'codetemplatedirs' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object codetemplatedirs: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 796 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + controller.options = [fdo_directory] + controller.historymaxcount = 0 + controller.captionopen = 'Select unit directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + end + end + object tlayouter13: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 293 + anchors = [an_top] + optionsscale = [osc_expandx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placey] + place_mindist = 2 + place_maxdist = 2 + place_options = [plo_endmargin] + linkbottom = ttabwidget2 + dist_bottom = 2 + object dispgrid: twidgetgrid + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.caption = 'Test' + frame.captiontextflags = [tf_bottom] + frame.captionpos = cp_topright + frame.font.xscale = 1 + frame.font.localprops = [flp_xscale] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 6 + bounds_y = 202 + bounds_cx = 817 + bounds_cy = 91 + anchors = [an_left, an_top, an_right] + font.xscale = 1 + font.localprops = [flp_xscale] + optionsgrid = [og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + rowcount = 2 + rowcolors.count = 1 + rowcolors.items = ( + 14745599 + ) + datacols.count = 1 + datacols.linewidth = 0 + datacols.options = [co_fill, co_savestate] + datacols.items = < + item[fontdisp] + width = 812 + options = [co_fill, co_savestate] + widgetname = 'fontdisp' + dataclass = tgridrichstringdatalist + data = ( + ( + '' + '' + ) + ) + end> + datarowlinewidth = 0 + datarowheight = 14 + reffontheight = 14 + object fontdisp: ttextedit + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 812 + bounds_cy = 14 + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_xscale] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_eatreturn, oe_exitoncursor, oe_nofirstarrownavig] + reffontheight = 14 + end + end + object tlayouter12: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 0 + bounds_y = 163 + bounds_cx = 600 + bounds_cy = 37 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object editfontextraspace: tintegeredit + color = -2147483645 + frame.caption = 'ExtSp' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 1 + 0 + ) + taborder = 3 + hint = 'Extra space between lines' + bounds_x = 247 + bounds_y = 0 + bounds_cx = 37 + bounds_cy = 37 + ondataentered = fontondataentered + valuemin = -1000 + valuemax = 1000 + reffontheight = 14 + end + object editfontwidth: tintegeredit + frame.caption = 'Width' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 1 + 0 + ) + taborder = 2 + bounds_x = 199 + bounds_y = 0 + bounds_cx = 37 + bounds_cy = 37 + ondataentered = fontondataentered + reffontheight = 14 + end + object editfontheight: tintegeredit + frame.caption = 'Height' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 7 + 0 + ) + taborder = 1 + bounds_x = 151 + bounds_y = 0 + bounds_cx = 43 + bounds_cy = 37 + ondataentered = fontondataentered + reffontheight = 14 + end + object editfontname: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Font' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 7 + bounds_y = 0 + bounds_cx = 124 + bounds_cy = 37 + ondataentered = fontondataentered + value = 'mseide_source' + reffontheight = 14 + end + object editfontcolor: tcoloredit + frame.caption = 'Color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + options = [fbo_inactiveinvisible] + end + item + color = -2147483646 + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.color = -2147483646 + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 303 + bounds_y = 0 + bounds_cy = 37 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = fontondataentered + value = -1879048183 + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + reffontheight = 14 + end + object editbkcolor: tcoloredit + frame.caption = 'Bk. Color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + options = [fbo_inactiveinvisible] + end + item + color = -2147483646 + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.color = -2147483646 + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 407 + bounds_y = 0 + bounds_cy = 37 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = fontondataentered + value = -1879048186 + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + reffontheight = 14 + end + object editfontantialiased: tbooleanedit + frame.caption = 'Anti aliased' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 76 + 2 + ) + taborder = 6 + bounds_x = 511 + bounds_y = 20 + bounds_cx = 89 + bounds_cy = 16 + ondataentered = fontondataentered + value = True + end + end + object tlayouter11: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 0 + bounds_y = 91 + bounds_cx = 572 + bounds_cy = 70 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object tlayouter14: tlayouter + bounds_x = 7 + bounds_y = 0 + bounds_cx = 121 + bounds_cy = 70 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placey] + place_mindist = 2 + place_maxdist = 2 + object rightmarginon: tbooleanedit + frame.caption = 'Right margin line' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 108 + 2 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 54 + bounds_cx = 121 + bounds_cy = 16 + value = True + end + object linenumberson: tbooleanedit + frame.caption = 'Line numbers' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 87 + 2 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 100 + bounds_cy = 16 + end + object editmarkbrackets: tbooleanedit + frame.caption = 'Mark brackets' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 92 + 2 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 18 + bounds_cx = 105 + bounds_cy = 16 + value = True + end + object editmarkpairwords: tbooleanedit + frame.caption = 'Mark pairwords' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 98 + 2 + ) + taborder = 2 + hint = 'Mark in syntax definition file defined word pairs.' + bounds_x = 0 + bounds_y = 36 + bounds_cx = 111 + bounds_cy = 16 + value = True + end + end + object tlayouter15: tlayouter + taborder = 1 + bounds_x = 143 + bounds_y = 10 + bounds_cx = 429 + bounds_cy = 51 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object pairmarkcolor: tcoloredit + frame.caption = 'Mark'#10'color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + options = [fbo_inactiveinvisible] + end + item + color = -2147483646 + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.color = -2147483646 + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 31 + 0 + 0 + ) + taborder = 3 + hint = 'Background color of marked brackets and word pairs.'#10'Will be overridden by setting in syntax definition file.'#10'cl_none -> force none.' + onshowhint = colorhint + bounds_x = 264 + bounds_y = 0 + bounds_cy = 51 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + reffontheight = 14 + end + object statementcolor: tcoloredit + frame.caption = 'Statement'#10'color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + options = [fbo_inactiveinvisible] + end + item + color = -2147483646 + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.color = -2147483646 + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 31 + 0 + 0 + ) + taborder = 2 + hint = 'Background color of the active row while debugging.'#10'Will be overridden by setting in syntax definition file.'#10'cl_none -> force none.' + onshowhint = colorhint + bounds_x = 160 + bounds_y = 0 + bounds_cy = 51 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = fontondataentered + value = 14745599 + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + reffontheight = 14 + end + object scrollheight: tintegeredit + frame.caption = 'Scroll'#10'height' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 31 + 6 + 0 + ) + taborder = 1 + hint = '0 -> accelerated,'#10'-1 -> paged' + bounds_x = 104 + bounds_y = 0 + bounds_cx = 42 + bounds_cy = 51 + valuemin = -1 + valuemax = 1000 + reffontheight = 14 + end + object rightmarginchars: tintegeredit + frame.caption = 'Characters' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 35 + 0 + ) + bounds_x = 8 + bounds_y = 14 + bounds_cx = 71 + bounds_cy = 37 + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 80 + valuemin = 1 + valuemax = 100 + reffontheight = 14 + end + object pairmaxrowcount: tintegeredit + frame.caption = 'Mark max'#10'rowcount' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 31 + 1 + 0 + ) + taborder = 4 + bounds_x = 368 + bounds_y = 0 + bounds_cx = 61 + bounds_cy = 51 + value = 100 + valuemin = 1 + reffontheight = 14 + end + end + end + object tlayouter10: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 52 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object spacetabs: tbooleanedit + frame.caption = 'Space' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 42 + 2 + ) + taborder = 4 + bounds_x = 303 + bounds_y = 20 + bounds_cx = 55 + bounds_cy = 16 + end + object blockindent: tintegeredit + frame.caption = 'Block Indent' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 43 + 0 + ) + taborder = 1 + bounds_x = 151 + bounds_y = 0 + bounds_cx = 79 + bounds_cy = 37 + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 1 + valuemin = 1 + valuemax = 100 + reffontheight = 14 + end + object autoindent: tbooleanedit + frame.caption = 'Auto indent' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 76 + 2 + ) + bounds_x = 7 + bounds_y = 20 + bounds_cx = 89 + bounds_cy = 16 + value = True + end + object tabindent: tbooleanedit + frame.caption = 'Tab' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 26 + 2 + ) + taborder = 2 + bounds_x = 191 + bounds_y = 20 + bounds_cx = 39 + bounds_cy = 16 + end + object tabstops: tintegeredit + frame.caption = 'Tabstops' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 24 + 0 + ) + taborder = 3 + bounds_x = 247 + bounds_y = 0 + bounds_cx = 60 + bounds_cy = 37 + value = 4 + valuemin = 1 + valuemax = 50 + reffontheight = 14 + end + object showtabs: tbooleanedit + frame.caption = 'Show tabs' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 68 + 2 + ) + taborder = 5 + bounds_x = 407 + bounds_y = 20 + bounds_cx = 81 + bounds_cy = 16 + end + end + object tlayouter16: tlayouter + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 50 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object eolstyle: tenumtypeedit + frame.caption = 'Eolstyle' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + hint = 'End of line style for writing. eol_default -> use original style.' + bounds_x = 247 + bounds_y = 0 + bounds_cx = 116 + bounds_cy = 37 + value = 1 + valuemin = 0 + valuemax = 3 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = initeolstyleexe + reffontheight = 14 + end + object trimtrailingwhitespace: tbooleanedit + frame.caption = 'Trim trailing'#10'whitespace'#10'on save' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 15 + 76 + 16 + ) + bounds_x = 7 + bounds_y = 6 + bounds_cx = 89 + bounds_cy = 44 + end + object encoding: tenumedit + frame.caption = 'Encoding' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 151 + bounds_y = 0 + bounds_cx = 92 + bounds_cy = 37 + dropdown.options = [deo_selectonly, deo_forceselect, deo_autodropdown, deo_keydropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + data = ( + 'Locale' + 'utf8' + 'iso8859-1' + ) + end> + value = 0 + onsetvalue = encodingsetvalue + reffontheight = 14 + end + object backupfilecount: tintegeredit + frame.caption = 'Backup file count' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 74 + 0 + ) + taborder = 3 + bounds_x = 407 + bounds_y = 0 + bounds_cx = 110 + bounds_cy = 37 + value = 2 + valuemax = 10 + reffontheight = 14 + end + end + end + end + object ttabpage22: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 511 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Form' + object componenthints: tbooleanedit + frame.caption = 'Component hints' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 110 + 2 + ) + taborder = 6 + bounds_x = 511 + bounds_y = 18 + bounds_cx = 123 + bounds_cy = 16 + end + object noformdesignerdocking: tbooleanedit + frame.caption = 'Docking' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 53 + 2 + ) + taborder = 4 + bounds_x = 359 + bounds_y = 18 + bounds_cx = 66 + bounds_cy = 16 + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_reversed] + end + object moveonfirstclick: tbooleanedit + frame.caption = 'Move on first click' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 114 + 2 + ) + taborder = 5 + bounds_x = 359 + bounds_y = 42 + bounds_cx = 127 + bounds_cy = 16 + value = True + end + object gridsizey: tintegeredit + frame.caption = 'Grid size Y' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 29 + 0 + ) + taborder = 3 + bounds_x = 247 + bounds_y = 18 + bounds_cx = 65 + bounds_cy = 37 + value = 8 + valuemin = 1 + valuemax = 1000 + reffontheight = 14 + end + object gridsizex: tintegeredit + frame.caption = 'Grid size X' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 29 + 0 + ) + taborder = 2 + bounds_x = 151 + bounds_y = 18 + bounds_cx = 65 + bounds_cy = 37 + value = 8 + valuemin = 1 + valuemax = 1000 + reffontheight = 14 + object tintegeredit2: tintegeredit + frame.caption = 'Grid size X' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 29 + 0 + ) + bounds_x = 136 + bounds_y = 29 + bounds_cx = 65 + bounds_cy = 37 + reffontheight = 14 + end + end + object snaptogrid: tbooleanedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_destroywidgets, ow_hinton] + frame.caption = 'Snap to Grid' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 81 + 2 + ) + taborder = 1 + hint = 'Hint:'#10'Use Ctrl + arrow keys to move selected components without grid snap,'#10'use Shift + arrow keys to resize selected components without grid snap.' + bounds_x = 7 + bounds_y = 42 + bounds_cx = 94 + bounds_cy = 16 + value = True + end + object showgrid: tbooleanedit + frame.caption = 'Show Grid' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 65 + 2 + ) + bounds_x = 7 + bounds_y = 18 + bounds_cx = 78 + bounds_cy = 16 + value = True + end + end + end + end + object debuggerpage: ttabpage + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 4 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Debugger' + onlayout = debuggerlayoutexe + object debugcommand: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.options = [cfo_fixtop] + frame.caption = '&Debug command' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 57 + bounds_cx = 302 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + controller.options = [fdo_quotesingle] + controller.historymaxcount = 0 + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object debugoptions: tmemodialogedit + frame.options = [cfo_fixtop] + frame.caption = 'Debug &options' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + hint = '"--tty DEVICE" to set target terminal' + onshowhint = hintexpandedmacros + bounds_x = 306 + bounds_y = 57 + bounds_cx = 523 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + reffontheight = 14 + end + object ttabwidget1: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + optionswidget1 = [ow1_fontglyphheight] + bounds_x = 0 + bounds_y = 204 + bounds_cx = 830 + bounds_cy = 326 + anchors = [an_left, an_top, an_right, an_bottom] + taborder = 6 + activepageindex = 0 + tab_frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + tab_frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + tab_face.localprops = [fal_frameimageoffset] + tab_color = -2147483645 + tab_size = 19 + statfile = statfile1 + reffontheight = 14 + object ttabpage6: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 4 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 307 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Source &directories' + reffontheight = 14 + object sourcedirgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 24 + bounds_cx = 830 + bounds_cy = 283 + bounds_cymin = 40 + anchors = [an_top, an_bottom] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + datacols.count = 1 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[sourcedirs] + linecolorfix = -1610612733 + width = 825 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'sourcedirs' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object sourcedirs: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 825 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + controller.include = [fa_dir, fa_all] + controller.options = [fdo_directory] + controller.historymaxcount = 0 + controller.captionopen = 'Select source directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + object sourcebase: tfilenameedit + frame.caption = 'Object &Base Directory (empty = Make Directory)' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 0 + 301 + 0 + ) + taborder = 1 + onshowhint = sourcedirhint + bounds_x = 1 + bounds_y = 2 + bounds_cx = 827 + anchors = [an_left, an_top, an_right] + textflags = [tf_noselect, tf_ellipseleft] + controller.options = [fdo_directory] + controller.captionopen = 'Select source base directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object tspacer7: tspacer + taborder = 2 + bounds_x = 527 + bounds_y = 22 + bounds_cx = 50 + bounds_cy = 2 + linktop = sourcebase + linkbottom = sourcedirgrid + end + end + object ttabpage9: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 307 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Defi&nes' + reffontheight = 14 + object twidgetgrid2: twidgetgrid + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 307 + anchors = [] + optionsgrid = [og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'on' + end + item + caption = 'Space separated defines for {$ifdef}' + end> + end> + datacols.count = 2 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[defineson] + width = 22 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'defineson' + dataclass = tgridintegerdatalist + end + item[defines] + width = 802 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'defines' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object defineson: tbooleanedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 22 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + valuedefault = True + end + object defines: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + visible = False + bounds_x = 23 + bounds_y = 0 + bounds_cx = 802 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + end + object ttabpage7: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 307 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Signals' + reffontheight = 14 + object signalgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 307 + bounds_cymin = 40 + anchors = [] + optionsgrid = [og_colsizing, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_sorted, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 5 + captions.items = < + item + caption = 'Stop' + end + item + caption = 'Handle' + end + item + caption = 'Signum' + end + item + caption = '.. to' + end + item + caption = 'Name' + textflags = [tf_ycentered] + end> + end> + datacols.count = 5 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[sigstop] + width = 32 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'sigstop' + dataclass = tgridintegerdatalist + end + item[sighandle] + width = 43 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'sighandle' + dataclass = tgridintegerdatalist + end + item[signum] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'signum' + dataclass = tgridintegerdatalist + end + item[signumto] + width = 39 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'signumto' + dataclass = tgridintegerdatalist + end + item[signame] + width = 657 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'signame' + dataclass = tgridenumdatalist + end> + datarowheight = 16 + reffontheight = 14 + object sigstop: tbooleanedit + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 32 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object sighandle: tbooleanedit + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 33 + bounds_y = 0 + bounds_cx = 43 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object signum: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 77 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + onsetvalue = signumonsetvalue + valuemax = 255 + reffontheight = 14 + end + object signumto: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 128 + bounds_y = 0 + bounds_cx = 39 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + onsetvalue = signumtoonsetvalue + valuemax = 255 + reffontheight = 14 + end + object signame: tselector + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -1879048187 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + end> + taborder = 5 + visible = False + bounds_x = 168 + bounds_y = 0 + bounds_cx = 657 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + dropdownitems.count = 2 + dropdownitems.items = < + item + end + item + end> + onsetvalue = signameonsetvalue + dropdown.cols.count = 1 + dropdown.cols.items = < + item + width = 100 + end> + reffontheight = 14 + end + end + end + object ttabpage8: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 307 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Exceptions' + reffontheight = 14 + object exceptionsgrid: twidgetgrid + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 307 + anchors = [] + optionsgrid = [og_colsizing, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'ignore' + end + item + caption = 'Exception class' + end> + end> + datacols.count = 2 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[exceptignore] + width = 47 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste] + widgetname = 'exceptignore' + dataclass = tgridintegerdatalist + end + item[exceptclassnames] + width = 777 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste] + widgetname = 'exceptclassnames' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object exceptignore: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 47 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object exceptclassnames: tstringedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + visible = False + bounds_x = 48 + bounds_y = 0 + bounds_cx = 777 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_trimright, oe_trimleft] + reffontheight = 14 + end + end + end + object ttabpage16: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 5 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 307 + anchors = [an_left, an_top, an_right, an_bottom] + taborderoverride.items = ( + 'uploadcommand' + 'gdbloadtimeout' + 'gdbloadtimeout' + 'gdbservercommand' + 'gdbservercommand' + 'gdbserverwait' + 'gdbserverstartonce' + 'gdbservercommandattach' + 'gdbservercommandattach' + 'nogdbserverexit' + ) + caption = '&Target' + onlayout = debugtargetlayoutev + reffontheight = 14 + object remoteconnection: tstringedit + frame.caption = 'Target connection' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + hint = '"--tty DEVICE" to set target terminal' + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 112 + bounds_cx = 828 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + reffontheight = 14 + end + object tlayouter4: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 0 + bounds_y = 192 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + linkbottom = tlayouter5 + object beforeconnect: tfilenameedit + frame.caption = 'Before connect gdb script' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 0 + bounds_cx = 214 + bounds_cy = 37 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'gdb Scripts' + '*.gdb' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + object tsplitter7: tsplitter + color = -1879048189 + taborder = 1 + visible = False + bounds_x = 215 + bounds_y = 17 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = beforeconnect + linkright = beforeload + end + object beforeload: tfilenameedit + frame.caption = 'Before load gdb script' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 218 + bounds_y = 0 + bounds_cx = 221 + bounds_cy = 37 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'gdb Scripts' + '*.gdb' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + object tsplitter9: tsplitter + color = -1879048189 + taborder = 3 + visible = False + bounds_x = 439 + bounds_y = 17 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = beforeload + linkright = beforerun + end + object beforerun: tfilenameedit + frame.caption = 'Before run gdb script' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + onshowhint = hintexpandedmacros + bounds_x = 442 + bounds_y = 0 + bounds_cx = 387 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'gdb Scripts' + '*.gdb' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + end + object tlayouter5: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 0 + bounds_y = 243 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object afterconnect: tfilenameedit + frame.caption = 'After connect gdb script' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 0 + bounds_cx = 214 + bounds_cy = 37 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'gdb Scripts' + '*.gdb' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + object tsplitter8: tsplitter + color = -1879048189 + taborder = 1 + visible = False + bounds_x = 215 + bounds_y = 17 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = afterconnect + linkright = afterload + end + object afterload: tfilenameedit + frame.caption = 'After load gdb script' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 218 + bounds_y = 0 + bounds_cx = 221 + bounds_cy = 37 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'gdb Scripts' + '*.gdb' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + object tsplitter10: tsplitter + color = -1879048189 + taborder = 3 + visible = False + bounds_x = 439 + bounds_y = 17 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = afterload + end + end + object tlayouter3: tlayouter + color = -2147483645 + frame.framei_left = 1 + frame.localprops = [frl_fileft, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 149 + bounds_cx = 618 + bounds_cy = 43 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 5 + place_maxdist = 5 + linktop = remoteconnection + linkbottom = tlayouter4 + object gdbprocessor: tdropdownlistedit + frame.options = [cfo_fixtop] + frame.caption = 'Processor' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 0 + bounds_cx = 84 + bounds_cy = 37 + onchange = processorchange + value = 'i386' + dropdown.options = [deo_autodropdown, deo_keydropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + data = ( + 'auto' + 'i386' + 'x86_64' + 'arm' + 'armm3' + 'cpu32' + 'avr32' + 'rl78' + ) + end> + reffontheight = 14 + end + object gdbsimulator: tbooleanedit + frame.caption = 'Simulator' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 62 + 2 + ) + taborder = 1 + bounds_x = 90 + bounds_y = 20 + bounds_cx = 75 + bounds_cy = 16 + onchange = downloadchange + end + object gdbdownload: tbooleanedit + frame.caption = 'gdb download' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 91 + 2 + ) + taborder = 2 + bounds_x = 170 + bounds_y = 20 + bounds_cx = 104 + bounds_cy = 16 + onchange = downloadchange + end + object downloadalways: tbooleanedit + frame.caption = 'Always download'#10'before run' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 108 + 9 + ) + taborder = 3 + bounds_x = 279 + bounds_y = 13 + bounds_cx = 121 + bounds_cy = 30 + end + object startupbkpt: tintegeredit + frame.options = [cfo_fixtop] + frame.caption = 'Startup BKPT' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 500 + bounds_y = 0 + bounds_cy = 37 + base = nb_hex + valuemax = -1 + reffontheight = 14 + end + object startupbkpton: tbooleanedit + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 6 + bounds_x = 605 + bounds_y = 21 + onchange = downloadchange + end + object restartgdbbeforeload: tbooleanedit + frame.caption = 'Restart gdb'#10'before load' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 8 + 77 + 9 + ) + taborder = 4 + bounds_x = 405 + bounds_y = 13 + bounds_cx = 90 + bounds_cy = 30 + end + end + object downloadlayouter: tlayouter + taborder = 4 + bounds_x = 1 + bounds_y = 1 + bounds_cx = 609 + bounds_cy = 111 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placey] + place_maxdist = 0 + linkright = texpandingwidget1 + linkbottom = remoteconnection + dist_right = 2 + options = [spao_glueright] + object gdbservercommandattach: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.options = [cfo_fixtop] + frame.caption = 'Start gdb server command attach target' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 74 + bounds_cx = 609 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_params] + controller.historymaxcount = 0 + reffontheight = 14 + end + object gdbservercommand: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.options = [cfo_fixtop] + frame.caption = 'Start gdb server command run target' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 37 + bounds_cx = 609 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_params] + controller.historymaxcount = 0 + reffontheight = 14 + end + object uploadcommand: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.options = [cfo_fixtop] + frame.caption = 'Download command' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_xscale] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 0 + bounds_cx = 609 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_params] + controller.historymaxcount = 0 + reffontheight = 14 + end + end + object texpandingwidget1: texpandingwidget + taborder = 5 + bounds_x = 612 + bounds_y = 1 + bounds_cx = 214 + bounds_cy = 111 + anchors = [an_top, an_right] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + object gdbloadtimeout: trealedit + frame.options = [cfo_fixtop] + frame.caption = 'Load Timeout' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 14 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 86 + bounds_cy = 37 + value = -Inf + valuedefault = -Inf + formatedit = '0.#' + formatdisp = '0.#sec' + valuerange = 1 + valuestart = 0 + valuemin = -Inf + valuemax = 200 + reffontheight = 14 + end + object serverla: tlayouter + color = -2147483645 + frame.framei_left = 1 + frame.localprops = [frl_fileft, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 37 + bounds_cx = 214 + bounds_cy = 37 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 2 + place_maxdist = 2 + place_options = [plo_endmargin] + linktop = gdbloadtimeout + object gdbserverwait: trealedit + frame.caption = 'Wait before connect' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 58 + 0 + ) + bounds_x = 1 + bounds_y = 0 + bounds_cx = 129 + bounds_cy = 37 + anchors = [an_top, an_right] + value = 0 + valuedefault = -Inf + formatedit = '0.#' + formatdisp = '0.#sec' + valuerange = 1 + valuestart = 0 + valuemin = 0 + valuemax = 200 + reffontheight = 14 + end + object gdbserverstartonce: tbooleanedit + frame.caption = 'Start once' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 69 + 2 + ) + taborder = 1 + bounds_x = 132 + bounds_y = 20 + bounds_cx = 82 + bounds_cy = 16 + end + end + object tlayouter2: tlayouter + color = -2147483645 + frame.framei_left = 1 + frame.framei_right = 2 + frame.localprops = [frl_fileft, frl_firight] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 74 + bounds_cx = 164 + bounds_cy = 37 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 2 + place_maxdist = 2 + place_options = [plo_noinvisible] + linktop = serverla + object nogdbserverexit: tbooleanedit + frame.caption = 'no wait for exit' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 95 + 2 + ) + bounds_x = 1 + bounds_y = 20 + bounds_cx = 108 + bounds_cy = 16 + anchors = [an_top, an_right] + end + object gdbservertty: tbooleanedit + frame.caption = 'TTY' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 24 + 2 + ) + taborder = 1 + bounds_x = 111 + bounds_y = 20 + bounds_cx = 37 + bounds_cy = 16 + end + object tstringedit1: tstringedit + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_invisibleparentsizeextend] + frame.caption = 'a' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + visible = False + bounds_x = 150 + bounds_y = 0 + bounds_cx = 12 + bounds_cy = 37 + reffontheight = 14 + end + end + end + end + end + object tlayouter1: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 5 + bounds_x = 7 + bounds_y = 164 + bounds_cx = 744 + bounds_cy = 30 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 10 + place_maxdist = 10 + place_options = [plo_noinvisible] + linkbottom = ttabwidget1 + dist_bottom = 10 + object externalconsole: tbooleanedit + frame.caption = '&External'#10'Console' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 54 + 9 + ) + taborder = 7 + bounds_x = 620 + bounds_y = 0 + bounds_cx = 67 + bounds_cy = 30 + onchange = updatedebugenabled + end + object showconsole: tbooleanedit + frame.caption = 'Show &Cons.'#10'on Run' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 75 + 9 + ) + taborder = 5 + hint = 'Show console on run' + bounds_x = 475 + bounds_y = 0 + bounds_cx = 88 + bounds_cy = 30 + end + object stoponexception: tbooleanedit + frame.caption = '&Stop'#10'on Excep.' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 64 + 9 + ) + taborder = 4 + hint = 'Stop on exceptions' + bounds_x = 388 + bounds_y = 0 + bounds_cx = 77 + bounds_cy = 30 + end + object activateonbreak: tbooleanedit + frame.caption = '&Activate'#10'on Break' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 59 + 9 + ) + taborder = 1 + bounds_x = 61 + bounds_y = 0 + bounds_cx = 72 + bounds_cy = 30 + onsetvalue = activateonbreakset + end + object valuehints: tbooleanedit + frame.caption = '&Value'#10'Hints' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 38 + 9 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 51 + bounds_cy = 30 + end + object nodebugbeginend: tbooleanedit + frame.caption = 'Call GUI_DEBUGBEGIN/'#10'GUI_DEBUGEND' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 8 + 140 + 9 + ) + taborder = 3 + hint = 'Release mouse grab by target stop. gdb sometimes crashes with this option.' + bounds_x = 225 + bounds_y = 0 + bounds_cx = 153 + bounds_cy = 30 + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_reversed] + end + object settty: tbooleanedit + frame.caption = 'Set'#10'TT&Y' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 8 + 24 + 9 + ) + taborder = 6 + bounds_x = 573 + bounds_y = 0 + bounds_cx = 37 + bounds_cy = 30 + visible = False + end + object raiseonbreak: tbooleanedit + frame.caption = '&Raise'#10'on Break' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 59 + 9 + ) + taborder = 2 + bounds_x = 143 + bounds_y = 0 + bounds_cx = 72 + bounds_cy = 30 + end + object fpcgdbworkaround: tbooleanedit + frame.caption = '&FPC'#10'bugs' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 8 + 34 + 9 + ) + taborder = 8 + hint = 'Use workarounds for FPC/gdb bugs' + bounds_x = 697 + bounds_y = 0 + bounds_cx = 47 + bounds_cy = 30 + end + end + object debugtarget: tfilenameedit + frame.options = [cfo_fixtop, cfo_autowidth] + frame.caption = 'Debug &target (empty = make targetfile)' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 104 + bounds_cx = 302 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + controller.options = [] + controller.historymaxcount = 0 + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object debugtargetsplitter: tsplitter + color = -1879048189 + taborder = 7 + visible = False + bounds_x = 303 + bounds_y = 109 + bounds_cx = 3 + bounds_cy = 34 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = debugtarget + linkright = xtermcommand + end + object xtermcommand: tmemodialogedit + frame.caption = 'xterm command' + frame.captiontextflags = [tf_bottom, tf_grayed] + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + onshowhint = hintexpandedmacros + enabled = False + bounds_x = 306 + bounds_y = 104 + bounds_cx = 523 + bounds_cy = 37 + anchors = [an_top, an_right] + onsetvalue = setxtermcommandexe + reffontheight = 14 + end + object debugsplitter: tsplitter + color = -1879048189 + taborder = 8 + visible = False + bounds_x = 303 + bounds_y = 69 + bounds_cx = 3 + bounds_cy = 26 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = debugcommand + linkright = debugoptions + end + object runcommand: tfilenameedit + frame.options = [cfo_fixtop, cfo_autowidth] + frame.caption = '&Run command (empty = start debugger)' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 21 + bounds_cx = 828 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onchange = updatedebugenabled + controller.options = [fdo_params] + controller.historymaxcount = 0 + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + object makepage: ttabpage + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 6 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_top, an_bottom] + caption = '&Make' + onlayout = makepageonchildscaled + object tspacer2: tspacer + color = -2147483645 + taborder = 18 + bounds_x = 341 + bounds_y = 108 + bounds_cx = 10 + bounds_cy = 26 + linkleft = colornote + linkright = copymessages + end + object defaultmake: tenumedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Default make col' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 17 + 14 + 0 + ) + taborder = 11 + bounds_x = 1 + bounds_y = 123 + bounds_cx = 110 + bounds_cy = 37 + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + dropdown.options = [deo_selectonly, deo_forceselect, deo_autodropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + data = ( + 'M (Make)' + 'B (Build)' + '1 (Make 1)' + '2 (Make 2)' + '3 (Make 3)' + '4 (Make 4)' + 'None' + ) + end> + value = 0 + reffontheight = 14 + end + object mainfile: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = '&Mainfile' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 2 + bounds_cx = 246 + bounds_cy = 37 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_link] + controller.historymaxcount = 0 + controller.captionopen = 'Select mainfile' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object targetfile: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = '&Targetfile' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 250 + bounds_y = 2 + bounds_cx = 205 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_link] + controller.historymaxcount = 0 + controller.captionopen = 'Select target file' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object makecommand: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Make &Program' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 43 + bounds_cx = 246 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [] + controller.historymaxcount = 0 + controller.captionopen = 'Select make command' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object showcommandline: tbutton + optionswidget1 = [ow1_autowidth, ow1_autoheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -2147483645 + taborder = 12 + bounds_x = 109 + bounds_y = 140 + bounds_cx = 134 + bounds_cy = 20 + state = [as_localcaption, as_localcolor, as_localonexecute] + caption = 'Show command line' + onexecute = showcommandlineonexecute + end + object messageoutputfile: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Message &output file' + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + onshowhint = hintexpandedmacros + enabled = False + bounds_x = 458 + bounds_y = 43 + bounds_cx = 371 + bounds_cy = 37 + anchors = [an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object copymessages: tbooleanedit + frame.caption = 'Copy messages to &file' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 140 + 2 + ) + taborder = 9 + bounds_x = 351 + bounds_y = 99 + bounds_cx = 153 + bounds_cy = 16 + onchange = copymessagechanged + end + object closemessages: tbooleanedit + frame.caption = 'Close messages window after compile' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 240 + 2 + ) + taborder = 14 + bounds_x = 257 + bounds_y = 151 + bounds_cx = 253 + bounds_cy = 16 + value = True + end + object checkmethods: tbooleanedit + frame.caption = 'Check method headers' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 149 + 2 + ) + taborder = 13 + bounds_x = 257 + bounds_y = 135 + bounds_cx = 162 + bounds_cy = 16 + value = True + end + object makegroupbox: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + bounds_x = 0 + bounds_y = 187 + bounds_cx = 830 + bounds_cy = 345 + anchors = [an_top, an_bottom] + taborder = 15 + activepageindex = 1 + tab_frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + tab_frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + tab_face.localprops = [fal_frameimageoffset] + tab_color = -2147483645 + tab_size = 19 + statfile = statfile1 + reffontheight = 14 + object ttabpage17: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 3 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 326 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Command before' + object befcommandgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 326 + bounds_cymin = 40 + anchors = [] + optionsgrid = [og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 7 + captions.items = < + item + caption = 'M' + hint = 'Use in Make' + end + item + caption = 'B' + hint = 'Use in Build' + end + item + caption = '1' + hint = 'Use in Make 1' + end + item + caption = '2' + hint = 'Use in Make 2' + end + item + caption = '3' + hint = 'Use in Make 3' + end + item + caption = '4' + hint = 'Use in Make 4' + end + item + caption = 'Command' + end> + end> + datacols.count = 7 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[befmakeon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befmakeon' + dataclass = tgridintegerdatalist + end + item[befbuildon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befbuildon' + dataclass = tgridintegerdatalist + end + item[befmake1on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befmake1on' + dataclass = tgridintegerdatalist + end + item[befmake2on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befmake2on' + dataclass = tgridintegerdatalist + end + item[befmake3on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befmake3on' + dataclass = tgridintegerdatalist + end + item[befmake4on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befmake4on' + dataclass = tgridintegerdatalist + end + item[befcommand] + width = 741 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befcommand' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object befmakeon: tbooleanedit + Tag = 1 + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befbuildon: tbooleanedit + Tag = 2 + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befmake1on: tbooleanedit + Tag = 4 + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 28 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befmake2on: tbooleanedit + Tag = 8 + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 42 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befmake3on: tbooleanedit + Tag = 16 + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 56 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befmake4on: tbooleanedit + Tag = 32 + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 70 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befcommand: tmemodialogedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 7 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 84 + bounds_y = 0 + bounds_cx = 741 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + end + object ttabpage12: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + face.localprops = [fal_frameimageoffset] + taborder = 2 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 326 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Make options' + reffontheight = 14 + object makeoptionsgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 326 + bounds_cymin = 40 + anchors = [] + optionsgrid = [og_colsizing, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 10 + captions.items = < + item + caption = 'Purpose' + end + item + caption = 'M' + hint = 'Use in Make' + end + item + caption = 'B' + hint = 'Use in Build' + end + item + caption = '1' + hint = 'Use in Make 1' + end + item + caption = '2' + hint = 'Use in Make 2' + end + item + caption = '3' + hint = 'Use in Make 3' + end + item + caption = '4' + hint = 'Use in Make 4' + end + item + caption = 'A' + hint = 'After mainfile' + end + item + caption = 'Command line options' + end + item + end> + end> + datacols.count = 9 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[makeoptpurpose] + width = 57 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'makeoptpurpose' + dataclass = tgridmsestringdatalist + datalist.facultative = True + end + item[makeon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'makeon' + dataclass = tgridintegerdatalist + end + item[buildon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'buildon' + dataclass = tgridintegerdatalist + end + item[make1on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'make1on' + dataclass = tgridintegerdatalist + end + item[make2on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'make2on' + dataclass = tgridintegerdatalist + end + item[make3on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'make3on' + dataclass = tgridintegerdatalist + end + item[make4on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'make4on' + dataclass = tgridintegerdatalist + end + item[optafter] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'optafter' + dataclass = tgridintegerdatalist + end + item[makeoptions] + width = 669 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'makeoptions' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object makeoptpurpose: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 57 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object makeon: tbooleanedit + Tag = 1 + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 58 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object buildon: tbooleanedit + Tag = 2 + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 72 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object make1on: tbooleanedit + Tag = 4 + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 86 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object make2on: tbooleanedit + Tag = 8 + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 100 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object make3on: tbooleanedit + Tag = 16 + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 114 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object make4on: tbooleanedit + Tag = 32 + optionsskin = [osk_framebuttononly] + taborder = 7 + bounds_x = 128 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object optafter: tbooleanedit + Tag = 1073741824 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 8 + bounds_x = 142 + bounds_y = 0 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + end + object makeoptions: tmemodialogedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 9 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 156 + bounds_y = 0 + bounds_cx = 669 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + end + object ttabpage11: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 326 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Directories' + reffontheight = 14 + object unitdirgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.caption = 'Unit, include and library &directories' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 46 + bounds_cx = 830 + bounds_cy = 280 + bounds_cymin = 40 + anchors = [an_top, an_bottom] + optionsgrid = [og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 11 + captions.items = < + item + caption = 'M' + hint = 'Use in Make' + end + item + caption = 'B' + hint = 'Use in Build' + end + item + caption = '1' + hint = 'Use in Make 1' + end + item + caption = '2' + hint = 'Use in Make 2' + end + item + caption = '3' + hint = 'Use in Make 3' + end + item + caption = '4' + hint = 'Use in Make 4' + end + item + caption = 'U' + hint = 'Add to unit file search path' + end + item + caption = 'I' + hint = 'Add to include file search path' + end + item + caption = 'L' + hint = 'Add to library search path' + end + item + caption = 'O' + hint = 'Add to object file search path' + end + item + caption = 'Directory' + end> + end> + datacols.count = 11 + datacols.width = 13 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[dmakeon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dmakeon' + dataclass = tgridintegerdatalist + end + item[dbuildon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dbuildon' + dataclass = tgridintegerdatalist + end + item[dmake1on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dmake1on' + dataclass = tgridintegerdatalist + end + item[dmake2on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dmake2on' + dataclass = tgridintegerdatalist + end + item[dmake3on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dmake3on' + dataclass = tgridintegerdatalist + end + item[dmake4on] + linewidth = 2 + linecolorfix = -1610612733 + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dmake4on' + dataclass = tgridintegerdatalist + end + item[duniton] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'duniton' + dataclass = tgridintegerdatalist + end + item[dincludeon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dincludeon' + dataclass = tgridintegerdatalist + end + item[dlibon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dlibon' + dataclass = tgridintegerdatalist + end + item[dobjon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dobjon' + dataclass = tgridintegerdatalist + end + item[unitdirs] + linecolorfix = -1610612733 + width = 684 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'unitdirs' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object dmakeon: tbooleanedit + Tag = 1 + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dbuildon: tbooleanedit + Tag = 2 + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dmake1on: tbooleanedit + Tag = 4 + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 28 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dmake2on: tbooleanedit + Tag = 8 + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 42 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dmake3on: tbooleanedit + Tag = 16 + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 56 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dmake4on: tbooleanedit + Tag = 32 + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 70 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object duniton: tbooleanedit + Tag = 65536 + optionsskin = [osk_framebuttononly] + taborder = 7 + bounds_x = 85 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dincludeon: tbooleanedit + Tag = 131072 + optionsskin = [osk_framebuttononly] + taborder = 8 + bounds_x = 99 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dlibon: tbooleanedit + Tag = 262144 + optionsskin = [osk_framebuttononly] + taborder = 9 + bounds_x = 113 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dobjon: tbooleanedit + Tag = 524288 + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 10 + bounds_x = 127 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object unitdirs: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 11 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 141 + bounds_y = 0 + bounds_cx = 684 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + controller.options = [fdo_directory, fdo_file] + controller.historymaxcount = 0 + controller.captionopen = 'Select unit directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + object tspacer1: tspacer + color = -2147483645 + taborder = 1 + bounds_x = 287 + bounds_y = 41 + bounds_cx = 50 + bounds_cy = 5 + linktop = tlayouter17 + linkbottom = unitdirgrid + end + object tlayouter17: tlayouter + taborder = 2 + bounds_x = 0 + bounds_y = 4 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + object objpref: tstringedit + frame.caption = 'Obj pref. (-Fo)' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 4 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 269 + bounds_y = 0 + bounds_cx = 88 + bounds_cy = 37 + reffontheight = 14 + end + object libpref: tstringedit + frame.caption = 'Lib pref.(-Fl)' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 181 + bounds_y = 0 + bounds_cx = 84 + bounds_cy = 37 + reffontheight = 14 + end + object incpref: tstringedit + frame.caption = 'Inc pref.(-Fi)' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 93 + bounds_y = 0 + bounds_cx = 84 + bounds_cy = 37 + reffontheight = 14 + end + object unitpref: tstringedit + frame.caption = 'Unit pref.(-Fu)' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 5 + 0 + ) + taborder = 3 + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 0 + bounds_cx = 89 + bounds_cy = 37 + reffontheight = 14 + end + object reversepathorder: tbooleanedit + frame.caption = 'Reverse directory order' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 150 + 2 + ) + taborder = 4 + bounds_x = 391 + bounds_y = 20 + bounds_cx = 163 + bounds_cy = 16 + end + object tsimplewidget1: tsimplewidget + taborder = 5 + bounds_x = 361 + bounds_y = 22 + bounds_cx = 26 + bounds_cy = 10 + end + end + end + object ttabpage18: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 4 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 326 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Command after' + object aftcommandgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 326 + bounds_cymin = 40 + anchors = [] + optionsgrid = [og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 7 + captions.items = < + item + caption = 'M' + hint = 'Use in Make' + end + item + caption = 'B' + hint = 'Use in Build' + end + item + caption = '1' + hint = 'Use in Make 1' + end + item + caption = '2' + hint = 'Use in Make 2' + end + item + caption = '3' + hint = 'Use in Make 3' + end + item + caption = '4' + hint = 'Use in Make 4' + end + item + caption = 'Command' + end> + end> + datacols.count = 7 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[aftmakeon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftmakeon' + dataclass = tgridintegerdatalist + end + item[aftbuildon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftbuildon' + dataclass = tgridintegerdatalist + end + item[aftmake1on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftmake1on' + dataclass = tgridintegerdatalist + end + item[aftmake2on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftmake2on' + dataclass = tgridintegerdatalist + end + item[aftmake3on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftmake3on' + dataclass = tgridintegerdatalist + end + item[aftmake4on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftmake4on' + dataclass = tgridintegerdatalist + end + item[aftcommand] + width = 741 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftcommand' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object aftmakeon: tbooleanedit + Tag = 1 + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftbuildon: tbooleanedit + Tag = 2 + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftmake1on: tbooleanedit + Tag = 4 + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 28 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftmake2on: tbooleanedit + Tag = 8 + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 42 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftmake3on: tbooleanedit + Tag = 16 + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 56 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftmake4on: tbooleanedit + Tag = 32 + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 70 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftcommand: tmemodialogedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 7 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 84 + bounds_y = 0 + bounds_cx = 741 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + end + end + object targpref: tstringedit + frame.caption = 'Targ. pref. (-o)' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 458 + bounds_y = 2 + bounds_cx = 371 + bounds_cy = 37 + anchors = [an_top, an_right] + reffontheight = 14 + end + object makedir: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Make &Directory' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + onshowhint = hintexpandedmacros + bounds_x = 250 + bounds_y = 43 + bounds_cx = 205 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_directory] + controller.historymaxcount = 0 + controller.captionopen = 'Select make directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object tsplitter1: tsplitter + color = -1879048189 + taborder = 16 + visible = False + bounds_x = 247 + bounds_y = 61 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = makecommand + linkright = makedir + end + object tsplitter2: tsplitter + color = -1879048189 + taborder = 17 + visible = False + bounds_x = 247 + bounds_y = 20 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = mainfile + linkright = targetfile + end + object tsplitter4: tsplitter + color = -1879048189 + taborder = 19 + visible = False + bounds_x = 455 + bounds_y = 20 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = targetfile + linkright = targpref + end + object tsplitter5: tsplitter + color = -1879048189 + taborder = 20 + visible = False + bounds_x = 455 + bounds_y = 60 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = makedir + linkright = messageoutputfile + end + object colorerror: tcoloredit + frame.caption = 'Error Color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + options = [fbo_inactiveinvisible] + end + item + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + bounds_x = 1 + bounds_y = 87 + bounds_cx = 108 + bounds_cy = 37 + value = -1610612712 + reffontheight = 14 + end + object tspacer5: tspacer + taborder = 21 + bounds_x = 109 + bounds_y = 109 + bounds_cx = 8 + bounds_cy = 18 + linkleft = colorerror + linkright = colorwarning + end + object colorwarning: tcoloredit + frame.caption = 'Warning Color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + options = [fbo_inactiveinvisible] + end + item + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + bounds_x = 117 + bounds_y = 87 + bounds_cx = 108 + bounds_cy = 37 + value = -1610612717 + reffontheight = 14 + end + object tspacer6: tspacer + taborder = 22 + bounds_x = 225 + bounds_y = 109 + bounds_cx = 8 + bounds_cy = 18 + linkleft = colorwarning + linkright = colornote + end + object colornote: tcoloredit + frame.caption = 'Note Color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + options = [fbo_inactiveinvisible] + end + item + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 8 + bounds_x = 233 + bounds_y = 87 + bounds_cx = 108 + bounds_cy = 37 + value = -1610612716 + reffontheight = 14 + end + object tspacer4: tspacer + color = -2147483645 + taborder = 23 + bounds_x = 341 + bounds_y = 92 + bounds_cx = 10 + bounds_cy = 26 + linkleft = colornote + linkright = stripmessageesc + end + object stripmessageesc: tbooleanedit + frame.caption = 'Strip ESC sequences' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 133 + 2 + ) + taborder = 10 + bounds_x = 351 + bounds_y = 115 + bounds_cx = 146 + bounds_cy = 16 + end + end + object ttabpage1: ttabpage + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'M&acros' + onlayout = macronchildscaled + object macrogrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 124 + bounds_cx = 830 + bounds_cy = 405 + bounds_cymin = 40 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 8 + captions.items = < + item + caption = '1' + end + item + caption = '2' + end + item + caption = '3' + end + item + caption = '4' + end + item + caption = '5' + end + item + caption = '6' + end + item + caption = 'Name' + end + item + caption = 'Value' + end> + end> + datacols.count = 8 + datacols.width = 13 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[e0] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e0' + dataclass = tgridintegerdatalist + end + item[e1] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e1' + dataclass = tgridintegerdatalist + end + item[e2] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e2' + dataclass = tgridintegerdatalist + end + item[e3] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e3' + dataclass = tgridintegerdatalist + end + item[e4] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e4' + dataclass = tgridintegerdatalist + end + item[e5] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e5' + dataclass = tgridintegerdatalist + end + item[macronames] + width = 146 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'macronames' + dataclass = tgridmsestringdatalist + end + item[macrovalues] + width = 594 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'macrovalues' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object e0: tbooleanedit + Tag = 1 + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object e1: tbooleanedit + Tag = 2 + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object e2: tbooleanedit + Tag = 4 + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 28 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object e3: tbooleanedit + Tag = 8 + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 42 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object e4: tbooleanedit + Tag = 16 + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 56 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object e5: tbooleanedit + Tag = 32 + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 70 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object macronames: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 7 + visible = False + bounds_x = 84 + bounds_y = 0 + bounds_cx = 146 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object macrovalues: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 8 + visible = False + bounds_x = 231 + bounds_y = 0 + bounds_cx = 594 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + object selectactivegroupgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.caption = 'Active group' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 121 + bounds_cymin = 40 + anchors = [an_top] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_focuscellonenter, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 13 + numstart = 1 + numstep = 1 + end> + rowcount = 6 + datacols.count = 2 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[activemacroselect] + width = 14 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste] + widgetname = 'activemacroselect' + dataclass = tgridintegerdatalist + data = ( + ( + 0 + 0 + 0 + 0 + 0 + 0 + ) + ) + end + item[groupcomment] + width = 781 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste] + widgetname = 'groupcomment' + dataclass = tgridmsestringdatalist + data = ( + ( + '' + '' + '' + '' + '' + '' + ) + ) + end> + datarowheight = 16 + onrowsmoved = selectactiveonrowsmoved + reffontheight = 14 + object activemacroselect: tbooleaneditradio + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 14 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + ondataentered = acttiveselectondataentered + visible = False + end + object groupcomment: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 15 + bounds_y = 0 + bounds_cx = 781 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + object macrosplitter: tsplitter + color = -1879048189 + taborder = 2 + bounds_x = 0 + bounds_y = 121 + bounds_cx = 830 + bounds_cy = 3 + anchors = [an_top] + options = [spo_vmove, spo_vprop, spo_docktop, spo_dockbottom] + linktop = selectactivegroupgrid + linkbottom = macrogrid + statfile = statfile1 + end + end + object fontaliaspage: ttabpage + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Font Alias' + object fontaliasgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + optionsgrid = [og_colsizing, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 15 + captions.count = 7 + captions.items = < + item + caption = 'Alias' + end + item + caption = 'Font name' + end + item + caption = 'Height' + end + item + caption = 'Width' + end + item + caption = 'Options' + end + item + caption = 'Xscale' + end + item + caption = 'Ancestor' + end> + end> + datacols.count = 7 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[fontalias] + width = 98 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'fontalias' + dataclass = tgridmsestringdatalist + end + item[fontname] + width = 451 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste] + onshowhint = colonshowhint + widgetname = 'fontname' + dataclass = tgridmsestringdatalist + end + item[fontheight] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'fontheight' + dataclass = tgridintegerdatalist + end + item[fontwidth] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'fontwidth' + dataclass = tgridintegerdatalist + end + item[fontoptions] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'fontoptions' + dataclass = tgridmsestringdatalist + end + item[fontxscale] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'fontxscale' + dataclass = tgridrealdatalist + end + item[fontancestors] + width = 70 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'fontancestors' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object fontalias: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 98 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object fontname: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 2 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 99 + bounds_y = 0 + bounds_cx = 451 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object fontheight: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 551 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object fontwidth: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 602 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object fontoptions: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 5 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 653 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object fontxscale: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 6 + visible = False + bounds_x = 704 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 1 + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + valuemin = 0 + valuemax = 1E+038 + reffontheight = 14 + end + object fontancestors: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 7 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 755 + bounds_y = 0 + bounds_cx = 70 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + valuedefault = 'stf_default' + reffontheight = 14 + end + end + end + object ttabpage10: ttabpage + frame.framei_bottom = 0 + frame.localprops = [frl_fibottom, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 7 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'User &Colors' + object tlayouter7: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 1013 + bounds_cx = 830 + bounds_cy = 42 + anchors = [an_bottom] + optionslayout = [lao_aligny] + align_glue = wam_center + object tbutton1: tbutton + optionswidget1 = [ow1_autowidth, ow1_autoheight] + color = -2147483645 + bounds_x = 15 + bounds_y = 11 + bounds_cx = 279 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption, as_localcolor, as_localonexecute] + caption = 'Copy "setcolormapvalue" code to clipboard' + onexecute = copycolorcode + end + end + object colgrid: twidgetgrid + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_focuscellonenter, og_colchangeontabkey, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + color = -1879048185 + width = 80 + textflags = [tf_ycentered] + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 3 + captions.items = < + item + end + item + caption = 'Color' + end + item + caption = 'Comment' + end> + captionsfix.count = 1 + captionsfix.items = < + item + caption = 'Name' + end> + end> + datacols.count = 3 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[coldi] + width = 22 + options = [co_readonly, co_nofocus, co_invisible, co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_mousescrollrow] + widgetname = 'coldi' + dataclass = tgridpointerdatalist + end + item[usercolors] + width = 97 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'usercolors' + dataclass = tgridenumdatalist + end + item[usercolorcomment] + width = 623 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 100 + widgetname = 'usercolorcomment' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object coldi: tpointeredit + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 22 + bounds_cy = 16 + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + onpaintglyph = drawcol + end + object usercolors: tcoloredit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + color = -1879048187 + imagenr = 17 + end> + frame.buttonellipse.color = -1879048187 + frame.buttonellipse.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 23 + bounds_y = 0 + bounds_cx = 97 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 0 + valuedefault = 0 + onsetvalue = colsetvalue + reffontheight = 14 + end + object usercolorcomment: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + visible = False + bounds_x = 121 + bounds_y = 0 + bounds_cx = 623 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + end + object ttabpage21: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 10 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'F&ormat Macros' + tabhint = 'Used by formatfloatmse() and formatdatetimemse()' + object formatmacrogrid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + optionsgrid = [og_focuscellonenter, og_autofirstrow, og_autoappend, og_savestate, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Value' + end> + end> + datacols.count = 2 + datacols.options = [co_savestate, co_mousescrollrow] + datacols.items = < + item[formatmacronames] + width = 157 + options = [co_proportional, co_savestate, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'formatmacronames' + dataclass = tgridmsestringdatalist + end + item[formatmacrovalues] + width = 667 + options = [co_fill, co_savestate, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'formatmacrovalues' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object formatmacronames: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 157 + bounds_cy = 16 + optionsedit1 = [] + reffontheight = 14 + end + object formatmacrovalues: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 158 + bounds_y = 0 + bounds_cx = 667 + bounds_cy = 16 + optionsedit1 = [] + reffontheight = 14 + end + end + end + object ttabpage2: ttabpage + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Templates' + object newfile: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + activepageindex = 0 + tab_frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + tab_frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + tab_color = -2147483645 + tab_size = 19 + statfile = statfile1 + reffontheight = 14 + object ttabpage3: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 511 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'New Project' + onlayout = newprojectchildscaled + reffontheight = 14 + object copygrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 86 + bounds_cx = 830 + bounds_cy = 423 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_keycolmoving, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + height = 16 + captions.count = 4 + captions.items = < + item + caption = 'L' + hint = 'Load file in editor' + end + item + caption = 'M' + hint = 'Expand macros' + end + item + caption = 'Copied Files' + end + item + caption = 'Destination' + end> + end> + datacols.count = 4 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[loadprojectfile] + width = 18 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste] + widgetname = 'loadprojectfile' + dataclass = tgridintegerdatalist + end + item[expandprojectfilemacros] + width = 18 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste] + widgetname = 'expandprojectfilemacros' + dataclass = tgridintegerdatalist + end + item[newprojectfiles] + width = 417 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste] + onshowhint = colonshowhint + widgetname = 'newprojectfiles' + dataclass = tgridmsestringdatalist + end + item[newprojectfilesdest] + width = 369 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste] + onshowhint = colonshowhint + widgetname = 'newprojectfilesdest' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object loadprojectfile: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 18 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object expandprojectfilemacros: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 19 + bounds_y = 0 + bounds_cx = 18 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object newprojectfiles: tfilenameedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 3 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 38 + bounds_y = 0 + bounds_cx = 417 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object newprojectfilesdest: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 4 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 456 + bounds_y = 0 + bounds_cx = 369 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_trimright, oe_trimleft] + reffontheight = 14 + end + end + object scriptbeforecopy: tfilenameedit + optionsskin = [osk_framebuttononly] + frame.caption = 'Script before copy' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 3 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object scriptaftercopy: tfilenameedit + optionsskin = [osk_framebuttononly] + frame.caption = 'Script after copy' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 40 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + object ttabpage4: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 511 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'New File' + reffontheight = 14 + object twidgetgrid1: twidgetgrid + color = -2147483645 + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 511 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 27 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 5 + captions.items = < + item + caption = 'Kind' + end + item + caption = 'Filter' + end + item + caption = 'Ext' + end + item + caption = 'Source' + end + item + end> + end> + datacols.count = 4 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[newfinames] + width = 124 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'newfinames' + dataclass = tgridmsestringdatalist + end + item[newfifilters] + width = 110 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'newfifilters' + dataclass = tgridmsestringdatalist + end + item[newfiexts] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'newfiexts' + dataclass = tgridmsestringdatalist + end + item[newfisources] + width = 510 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'newfisources' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object newfinames: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 124 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + object newfifilters: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 125 + bounds_y = 0 + bounds_cx = 110 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + object newfiexts: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 3 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 236 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + object newfisources: tfilenameedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 4 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 287 + bounds_y = 0 + bounds_cx = 510 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + end + end + object ttabpage5: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 511 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'New Form' + onlayout = formtemplateonchildscaled + reffontheight = 14 + object twidgetgrid4: twidgetgrid + color = -2147483645 + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 511 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_savestate, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 23 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 6 + captions.items = < + item + caption = 'Kind' + end + item + caption = 'I' + hint = 'Inherited' + end + item + caption = 'Namebase' + end + item + caption = 'Formsuffix' + end + item + caption = 'Source File' + end + item + caption = 'Form File' + end> + end> + datacols.count = 6 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[newfonames] + width = 96 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'newfonames' + onshowhint = colonshowhint + widgetname = 'newfonames' + dataclass = tgridmsestringdatalist + end + item[newinheritedforms] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'newinheritedforms' + widgetname = 'newinheritedforms' + dataclass = tgridintegerdatalist + end + item[newfonamebases] + width = 73 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'newfonamebases' + onshowhint = colonshowhint + widgetname = 'newfonamebases' + dataclass = tgridmsestringdatalist + end + item[newfoformsuffixes] + width = 69 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'newfoformsuffix' + widgetname = 'newfoformsuffixes' + dataclass = tgridmsestringdatalist + end + item[newfosources] + width = 293 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'newfosources' + onshowhint = colonshowhint + widgetname = 'newfosources' + dataclass = tgridmsestringdatalist + end + item[newfoforms] + width = 252 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'mewfoforms' + onshowhint = colonshowhint + widgetname = 'newfoforms' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object newfonames: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 96 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object newinheritedforms: tbooleanedit + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 97 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object newfonamebases: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 3 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 111 + bounds_y = 0 + bounds_cx = 73 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object newfoformsuffixes: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 4 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 185 + bounds_y = 0 + bounds_cx = 69 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object newfosources: tfilenameedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 5 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 255 + bounds_y = 0 + bounds_cx = 293 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + controller.filterlist.data = ( + ( + 'Source' + '"*.pas" "*.pp"' + ) + ( + 'All Files' + '*' + ) + ) + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object newfoforms: tfilenameedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 6 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 549 + bounds_y = 0 + bounds_cx = 252 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + controller.filterlist.data = ( + ( + 'Form Files' + '*.mfm' + ) + ( + 'All Files' + '*' + ) + ) + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + end + end + end + object ttabpage15: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 8 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Too&ls' + reffontheight = 14 + object twidgetgrid3: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 18 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 10 + captions.items = < + item + caption = 'S' + hint = 'Save files' + end + item + caption = 'P' + hint = 'Parse source' + end + item + caption = 'H' + hint = 'Hide console (win32 only)' + end + item + caption = 'M' + hint = 'Show output in messages window' + end + item + caption = 'Menu' + end + item + caption = 'Shortcut' + hint = 'Select item from ''Settings''-''Configure MSEide''-''Shortcuts'''#10'''Tool 1''..''Tool 10''.' + end + item + caption = 'Sc.Key' + hint = 'Shortcut key' + end + item + caption = 'Alt.Sc.' + hint = 'Alternate shortcut key' + end + item + caption = 'File' + end + item + caption = 'Parameters' + end> + end> + datacols.count = 10 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[toolsave] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 13 + widthmax = 13 + widgetname = 'toolsave' + dataclass = tgridintegerdatalist + end + item[toolparse] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 13 + widthmax = 13 + widgetname = 'toolparse' + dataclass = tgridintegerdatalist + end + item[toolhide] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 13 + widthmax = 13 + widgetname = 'toolhide' + dataclass = tgridintegerdatalist + end + item[toolmessages] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'toolmessages' + dataclass = tgridintegerdatalist + end + item[toolmenus] + width = 107 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'toolmenus' + dataclass = tgridmsestringdatalist + end + item[toolshortcuts] + width = 86 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow, co_rowdatachange] + widgetname = 'toolshortcuts' + dataclass = tgridenumdatalist + end + item[toolsc] + color = -1879048185 + coloractive = -2147483647 + width = 55 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'toolsc' + dataclass = tgridmsestringdatalist + end + item[toolscalt] + color = -1879048185 + width = 55 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'toolscalt' + dataclass = tgridmsestringdatalist + end + item[toolfiles] + width = 116 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'toolfiles' + dataclass = tgridmsestringdatalist + end + item[toolparams] + width = 326 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'toolparams' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + onrowdatachanged = toolsrowdatachanged + reffontheight = 14 + object toolsave: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object toolparse: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object toolhide: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 28 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object toolmessages: tbooleanedit + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 42 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object toolmenus: tstringedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 5 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 56 + bounds_y = 0 + bounds_cx = 107 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + object toolshortcuts: tenumedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + end> + taborder = 6 + visible = False + bounds_x = 164 + bounds_y = 0 + bounds_cx = 86 + bounds_cy = 16 + statfile = statfile1 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_cliphint, deo_colsizing, deo_savestate] + dropdown.width = -1 + dropdown.cols.count = 3 + dropdown.cols.width = 70 + dropdown.cols.options = [co_readonly, co_mousemovefocus, co_focusselect, co_rowselect] + dropdown.cols.linewidth = 1 + dropdown.cols.items = < + item + options = [co_readonly, co_mousemovefocus, co_focusselect, co_rowselect] + width = 70 + linewidth = 1 + caption = 'Item' + data = ( + 'Tool 1' + 'Tool 2' + 'Tool 3' + 'Tool 4' + 'Tool 5' + 'Tool 6' + 'Tool 7' + 'Tool 8' + 'Tool 9' + 'Tool 10' + ) + end + item + options = [co_readonly, co_mousemovefocus, co_focusselect, co_rowselect] + width = 70 + linewidth = 1 + caption = 'Shortcut' + data = ( + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + ) + end + item + options = [co_readonly, co_mousemovefocus, co_focusselect, co_rowselect] + width = 70 + linewidth = 1 + caption = 'Alternate' + data = ( + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + ) + end> + valuemax = 9 + onbeforedropdown = toolshortcutdropdown + reffontheight = 14 + end + object toolsc: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 7 + visible = False + bounds_x = 251 + bounds_y = 0 + bounds_cx = 55 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object toolscalt: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 8 + visible = False + bounds_x = 307 + bounds_y = 0 + bounds_cx = 55 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object toolfiles: tfilenameedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 9 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 363 + bounds_y = 0 + bounds_cx = 116 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + controller.include = [fa_xusr, fa_xgrp, fa_xoth] + reffontheight = 14 + end + object toolparams: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 10 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 480 + bounds_y = 0 + bounds_cx = 326 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + end + end + object ttabpage20: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 9 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Storage' + object settingseditor: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Editor' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 40 + 2 + ) + taborder = 3 + bounds_x = 15 + bounds_y = 108 + bounds_cx = 54 + bounds_cy = 16 + end + object settingsautoload: tbooleanedit + frame.caption = 'Auto load' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 63 + 2 + ) + taborder = 1 + bounds_x = 15 + bounds_y = 52 + bounds_cx = 76 + bounds_cy = 16 + end + object settingsautosave: tbooleanedit + frame.caption = 'Auto save' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 65 + 2 + ) + taborder = 2 + bounds_x = 183 + bounds_y = 52 + bounds_cx = 78 + bounds_cy = 16 + end + object tlayouter6: tlayouter + frame.framei_left = 5 + frame.framei_top = 5 + frame.framei_right = 5 + frame.framei_bottom = 5 + frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 13 + bounds_cx = 830 + bounds_cy = 31 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 5 + place_maxdist = 5 + place_options = [plo_endmargin] + object savebu: tbutton + optionswidget1 = [ow1_fontlineheight, ow1_autoscale] + taborder = 2 + bounds_x = 776 + bounds_y = 5 + bounds_cx = 49 + bounds_cy = 21 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localcaption, as_localonexecute] + caption = 'Save' + onexecute = saveexe + reffontheight = 14 + end + object loadbu: tbutton + optionswidget1 = [ow1_fontlineheight, ow1_autoscale] + taborder = 1 + bounds_x = 722 + bounds_y = 5 + bounds_cx = 49 + bounds_cy = 21 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localcaption, as_localonexecute] + caption = 'Load' + onexecute = loadexe + reffontheight = 14 + end + object settingsfile: tfilenameedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Settings File' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 0 + 80 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 5 + bounds_y = 5 + bounds_cx = 712 + anchors = [an_left, an_top, an_right] + ondataentered = settingsdataent + controller.filterlist.data = ( + ( + 'Project Files' + '*.prj' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'prj' + controller.captionopen = 'Enter Settings File' + reffontheight = 14 + end + end + object settingsdebugger: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Debugger' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 65 + 2 + ) + taborder = 4 + bounds_x = 15 + bounds_y = 132 + bounds_cx = 79 + bounds_cy = 16 + end + object settingsstorage: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Storage' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 53 + 2 + ) + taborder = 12 + bounds_x = 15 + bounds_y = 324 + bounds_cx = 67 + bounds_cy = 16 + end + object settingsprojecttree: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Project Tree' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 79 + 2 + ) + taborder = 14 + bounds_x = 183 + bounds_y = 132 + bounds_cx = 93 + bounds_cy = 16 + end + object settingsmacros: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Macros' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 48 + 2 + ) + taborder = 6 + bounds_x = 15 + bounds_y = 180 + bounds_cx = 62 + bounds_cy = 16 + end + object settingstools: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Tools' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 36 + 2 + ) + taborder = 11 + bounds_x = 15 + bounds_y = 300 + bounds_cx = 50 + bounds_cy = 16 + end + object settingstemplates: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Templates' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 68 + 2 + ) + taborder = 10 + bounds_x = 15 + bounds_y = 276 + bounds_cx = 82 + bounds_cy = 16 + end + object settingscomponentstore: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Component Store' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 113 + 2 + ) + taborder = 13 + bounds_x = 183 + bounds_y = 108 + bounds_cx = 127 + bounds_cy = 16 + end + object settingslayout: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Window Layout' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 95 + 2 + ) + taborder = 15 + bounds_x = 183 + bounds_y = 156 + bounds_cx = 109 + bounds_cy = 16 + end + object tlabel1: tlabel + taborder = 16 + bounds_x = 15 + bounds_y = 84 + bounds_cx = 118 + bounds_cy = 14 + caption = 'Load/save settings' + reffontheight = 14 + end + object settingsmake: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Make' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 36 + 2 + ) + taborder = 5 + bounds_x = 15 + bounds_y = 156 + bounds_cx = 50 + bounds_cy = 16 + value = True + end + object settingsusercolors: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'User Colors' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 75 + 2 + ) + taborder = 8 + bounds_x = 15 + bounds_y = 228 + bounds_cx = 89 + bounds_cy = 16 + end + object settingsformatmacros: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Format Macros' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 96 + 2 + ) + taborder = 9 + bounds_x = 15 + bounds_y = 252 + bounds_cx = 110 + bounds_cy = 16 + end + object settingsfontalias: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Font Alias' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 64 + 2 + ) + taborder = 7 + bounds_x = 15 + bounds_y = 204 + bounds_cx = 78 + bounds_cy = 16 + end + end + end + end + object statfile1: tstatfile + filename = 'optionsfo.sta' + options = [sfo_memory] + left = 144 + top = 536 + end + object c: tstringcontainer + strings.data = ( + 'Wrong encoding can damage your source files.' + 'Do you wish to set encoding to' + '*** WARNING ***' + 'Hangup' + 'Interrupt' + 'Quit' + 'Illegal instruction' + 'Trace trap' + 'Abort' + 'BUS error' + 'Floating-point exception' + 'Kill' + 'User-defined signal 1' + 'Segmentation violation' + 'User-defined signal 2' + 'Broken pipe' + 'Alarm clock' + 'Termination' + 'Stack fault' + 'Child status has changed' + 'Continue' + 'Stop, unblockable' + 'Keyboard stop' + 'Background read from tty' + 'Background write to tty' + 'Urgent condition on socket' + 'CPU limit exceeded' + 'File size limit exceeded' + 'Virtual alarm clock' + 'Profiling alarm clock' + 'Window size change' + 'I/O now possible' + 'Power failure restart' + ) + left = 216 + top = 536 + end +end diff --git a/mseide-msegui/apps/ide/projectoptionsform.pas b/mseide-msegui/apps/ide/projectoptionsform.pas new file mode 100644 index 0000000..1ed0718 --- /dev/null +++ b/mseide-msegui/apps/ide/projectoptionsform.pas @@ -0,0 +1,3602 @@ +{ MSEide Copyright (c) 1999-2018 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit projectoptionsform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +{$ifndef mse_no_ifi} + {$define mse_with_ifi} + //MSEide needs mse_with_ifi, switch for compiling test only +{$endif} +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +interface +uses + mseforms,msefiledialog,mseapplication,msegui,msestat,msestatfile,msetabs, + msesimplewidgets,msetypes,msestrings,msedataedits,msetextedit,msegraphedits, + msewidgetgrid,msegrids,msesplitter,msemacros,msegdbutils,msedispwidgets,msesys, + mseclasses,msegraphutils,mseevent,msetabsglob,msearrayutils,msegraphics, + msedropdownlist,mseformatstr,mseinplaceedit,msedatanodes,mselistbrowser, + msebitmap,msecolordialog,msedrawtext,msewidgets,msepointer,mseguiglob, + msepipestream,msemenus,sysutils,mseglob,mseedit,msedialog,msescrollbar, + msememodialog,msecodetemplates,mseifiglob,msestream,msestringcontainer, + mserttistat,mseificomp,mseificompglob,msedragglob,mseeditglob,mseact; + +const + defaultsourceprintfont = 'Courier'; + defaulttitleprintfont = 'Helvetica'; + defaultprintfontsize = 35.2778; //10 point + maxdefaultmake = $40-1; + defaultxtermcommand = 'xterm -S${PTSN}/${PTSH}'; + optaftermainfilemask = $40000000; + +type + settinggroupty = (sg_editor,sg_debugger,sg_make,sg_templates, + sg_macros,sg_fontalias,sg_usercolors, + sg_formatmacros,sg_tools,sg_storage, + sg_state); + settinggroupsty = set of settinggroupty; + + findinfoty = record + text: msestring; + options: searchoptionsty; + selectedonly: boolean; + history: msestringarty; + end; + + replaceinfoty = record + find: findinfoty; + replacetext: msestring; + prompt: boolean; + end; + + sigsetinfoty = record + num: integer; + numto: integer; + flags: sigflagsty; + end; + sigsetinfoarty = array of sigsetinfoty; + + ttexttoolsoptions = class(toptions) + private + ftoolmenus: msestringarty; + ftoolfiles: msestringarty; + ftoolparams: msestringarty; + published + property toolmenus: msestringarty read ftoolmenus write ftoolmenus; + property toolfiles: msestringarty read ftoolfiles write ftoolfiles; + property toolparams: msestringarty read ftoolparams write ftoolparams; + end; + + ttoolsoptions = class(toptions) + private + ft: ttexttoolsoptions; + ftexp: ttexttoolsoptions; + ftoolsave: longboolarty; + ftoolhide: longboolarty; + ftoolparse: longboolarty; + ftoolmessages: longboolarty; + ftoolshortcuts: integerarty; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create; + property texp: ttexttoolsoptions read ftexp; + published + property t: ttexttoolsoptions read ft; + property toolsave: longboolarty read ftoolsave write ftoolsave; + property toolhide: longboolarty read ftoolhide write ftoolhide; + property toolparse: longboolarty read ftoolparse write ftoolparse; + property toolmessages: longboolarty read ftoolmessages write ftoolmessages; + property toolshortcuts: integerarty read ftoolshortcuts write ftoolshortcuts; + end; + + ttexttemplatesoptions = class(toptions) + private + fscriptbeforecopy: msestring; + fscriptaftercopy: msestring; + fnewprojectfiles: filenamearty; + fnewprojectfilesdest: filenamearty; + fnewfinames: msestringarty; + fnewfifilters: msestringarty; + fnewfiexts: msestringarty; + fnewfisources: filenamearty; + fnewfonames: msestringarty; + fnewfonamebases: msestringarty; + fnewfoformsuffixes: msestringarty; + fnewfosources: msestringarty; + fnewfoforms: msestringarty; + published + property scriptbeforecopy: msestring read fscriptbeforecopy + write fscriptbeforecopy; + property scriptaftercopy: msestring read fscriptaftercopy + write fscriptaftercopy; + property newprojectfiles: filenamearty read fnewprojectfiles + write fnewprojectfiles; + property newprojectfilesdest: filenamearty read fnewprojectfilesdest + write fnewprojectfilesdest; + property newfinames: msestringarty read fnewfinames write fnewfinames; + property newfifilters: msestringarty read fnewfifilters + write fnewfifilters; + property newfiexts: msestringarty read fnewfiexts write fnewfiexts; + property newfisources: filenamearty read fnewfisources write fnewfisources; + + property newfonames: msestringarty read fnewfonames write fnewfonames; + property newfonamebases: msestringarty read fnewfonamebases + write fnewfonamebases; + property newfoformsuffixes: msestringarty read fnewfoformsuffixes + write fnewfoformsuffixes; + property newfosources: msestringarty read fnewfosources + write fnewfosources; + property newfoforms: msestringarty read fnewfoforms write fnewfoforms; + end; + + ttemplatesoptions = class(toptions) + private + ft: ttexttemplatesoptions; + ftexp: ttexttemplatesoptions; + fexpandprojectfilemacros: longboolarty; + floadprojectfile: longboolarty; + fnewinheritedforms: longboolarty; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create; + property texp: ttexttemplatesoptions read ftexp; + published + property t: ttexttemplatesoptions read ft; + property expandprojectfilemacros: longboolarty read fexpandprojectfilemacros + write fexpandprojectfilemacros; + property loadprojectfile: longboolarty read floadprojectfile + write floadprojectfile; + property newinheritedforms: longboolarty read fnewinheritedforms + write fnewinheritedforms; + end; + + ttexteditoptions = class(toptions) + private + fsourcefilemasks: msestringarty; + fsyntaxdeffiles: msestringarty; + ffilemasknames: msestringarty; + ffilemasks: msestringarty; + public + fcodetemplatedirs: msestringarty; + published + property sourcefilemasks: msestringarty read fsourcefilemasks + write fsourcefilemasks; + property syntaxdeffiles: msestringarty read fsyntaxdeffiles + write fsyntaxdeffiles; + property filemasknames: msestringarty read ffilemasknames + write ffilemasknames; + property filemasks: msestringarty read ffilemasks write ffilemasks; + property codetemplatedirs: msestringarty read fcodetemplatedirs write + fcodetemplatedirs; + end; + + teditoptions = class(toptions) + private + ft: ttexteditoptions; + ftexp: ttexteditoptions; + + fshowgrid: boolean; + fsnaptogrid: boolean; + fmoveonfirstclick: boolean; + fgridsizex: integer; + fgridsizey: integer; + fautoindent: boolean; + fblockindent: integer; + flinenumberson: boolean; + frightmarginon: boolean; + frightmarginchars: integer; + fscrollheight: integer; + ftabstops: integer; + fspacetabs: boolean; + fshowtabs: boolean; + ftabindent: boolean; + feditfontname: msestring; + feditfontheight: integer; + feditfontwidth: integer; + feditfontextraspace: integer; + feditfontcolor: integer; + feditbkcolor: integer; + fstatementcolor: integer; + feditfontantialiased: boolean; + feditmarkbrackets: boolean; + feditmarkpairwords: boolean; + fbackupfilecount: integer; + fencoding: integer; + feolstyle: integer; + fnoformdesignerdocking: boolean; + ftrimtrailingwhitespace: boolean; + fpairmarkcolor: integer; + fpairmaxrowcount: integer; + fcomponenthints: boolean; + function limitgridsize(const avalue: integer): integer; + procedure setgridsizex(const avalue: integer); + procedure setgridsizey(const avalue: integer); +// function getcodetemplatedirs: msestringarty; +// procedure setcodetemplatedirs(const avalue: msestringarty); + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create; + property texp: ttexteditoptions read ftexp; + published + property t: ttexteditoptions read ft; + + property showgrid: boolean read fshowgrid write fshowgrid; + property snaptogrid: boolean read fsnaptogrid write fsnaptogrid; + property moveonfirstclick: boolean read fmoveonfirstclick + write fmoveonfirstclick; + property noformdesignerdocking: boolean read fnoformdesignerdocking + write fnoformdesignerdocking; + property componenthints: boolean read fcomponenthints + write fcomponenthints; + property gridsizex: integer read fgridsizex write setgridsizex; + property gridsizey: integer read fgridsizey write setgridsizey; + property autoindent: boolean read fautoindent write fautoindent; + property blockindent: integer read fblockindent write fblockindent; + property linenumberson: boolean read flinenumberson write flinenumberson; + property rightmarginon: boolean read frightmarginon write frightmarginon; + property rightmarginchars: integer read frightmarginchars + write frightmarginchars; + property scrollheight: integer read fscrollheight write fscrollheight; + property tabstops: integer read ftabstops write ftabstops; + property spacetabs: boolean read fspacetabs write fspacetabs; + property showtabs: boolean read fshowtabs write fshowtabs; + property tabindent: boolean read ftabindent write ftabindent; + property editfontname: msestring read feditfontname write feditfontname; + property editfontheight: integer read feditfontheight write feditfontheight; + property editfontwidth: integer read feditfontwidth write feditfontwidth; + property editfontextraspace: integer read feditfontextraspace + write feditfontextraspace; + property editfontcolor: integer read feditfontcolor write feditfontcolor; + property editbkcolor: integer read feditbkcolor write feditbkcolor; + property statementcolor: integer read fstatementcolor write fstatementcolor; + property pairmarkcolor: integer read fpairmarkcolor + write fpairmarkcolor; + property pairmaxrowcount: integer read fpairmaxrowcount + write fpairmaxrowcount; + + property editfontantialiased: boolean read feditfontantialiased + write feditfontantialiased; + property editmarkbrackets: boolean read feditmarkbrackets + write feditmarkbrackets; + property editmarkpairwords: boolean read feditmarkpairwords + write feditmarkpairwords; + property backupfilecount: integer read fbackupfilecount + write fbackupfilecount; + property encoding: integer read fencoding write fencoding; + property eolstyle: integer read feolstyle write feolstyle; + property trimtrailingwhitespace: boolean read ftrimtrailingwhitespace + write ftrimtrailingwhitespace; +// property codetemplatedirs: msestringarty read getcodetemplatedirs write +// setcodetemplatedirs; + end; + + ttextdebugoptions = class(toptions) + private + fdebugcommand: filenamety; + fdebugoptions: msestring; + fdebugtarget: filenamety; + fruncommand: filenamety; + fremoteconnection: msestring; + fuploadcommand: filenamety; + fgdbprocessor: msestring; + fgdbservercommand: filenamety; + fgdbservercommandattach: filenamety; + fbeforeload: filenamety; + fafterload: filenamety; + fbeforerun: filenamety; + fsourcedirs: msestringarty; + fdefines: msestringarty; + + fprogparameters: msestring; + fprogworkingdirectory: filenamety; + fenvvarnames: msestringarty; + fenvvarvalues: msestringarty; + fbeforeconnect: filenamety; + fafterconnect: filenamety; + fxtermcommand: msestring; + fsourcebase: msestring; + protected + public + constructor create; + published + property debugcommand: filenamety read fdebugcommand write fdebugcommand; + property debugoptions: msestring read fdebugoptions write fdebugoptions; + property debugtarget: filenamety read fdebugtarget write fdebugtarget; + property runcommand: filenamety read fruncommand write fruncommand; + property xtermcommand: msestring read fxtermcommand write fxtermcommand; + property remoteconnection: msestring read fremoteconnection + write fremoteconnection; + property uploadcommand: filenamety read fuploadcommand + write fuploadcommand; + property gdbprocessor: msestring read fgdbprocessor write fgdbprocessor; + property gdbservercommand: filenamety read fgdbservercommand + write fgdbservercommand; + property gdbservercommandattach: filenamety read fgdbservercommandattach + write fgdbservercommandattach; + property beforeconnect: filenamety read fbeforeconnect write fbeforeconnect; + property afterconnect: filenamety read fafterconnect write fafterconnect; + property beforeload: filenamety read fbeforeload write fbeforeload; + property afterload: filenamety read fafterload write fafterload; + property beforerun: filenamety read fbeforerun write fbeforerun; + property sourcebase: msestring read fsourcebase write fsourcebase; + property sourcedirs: msestringarty read fsourcedirs write fsourcedirs; + property defines: msestringarty read fdefines write fdefines; + + property progparameters: msestring read fprogparameters + write fprogparameters; + property progworkingdirectory: filenamety read fprogworkingdirectory + write fprogworkingdirectory; + property envvarnames: msestringarty read fenvvarnames write fenvvarnames; + property envvarvalues: msestringarty read fenvvarvalues write fenvvarvalues; + end; + + tdebugoptions = class(toptions) + private + ft: ttextdebugoptions; + ftexp: ttextdebugoptions; + fdefineson: longboolarty; + fstoponexception: boolean; + fvaluehints: boolean; + factivateonbreak: boolean; + fshowconsole: boolean; + fexternalconsole: boolean; + fgdbdownload: boolean; + fdownloadalways: boolean; + frestartgdbbeforeload: boolean; + fstartupbkpt: integer; + fstartupbkpton: boolean; + fgdbsimulator: boolean; + fgdbserverwait: real; + fexceptclassnames: msestringarty; + fexceptignore: booleanarty; + fnogdbserverexit: boolean; + fgdbservertty: boolean; + fnodebugbeginend: boolean; + fsettty: boolean; + fgdbserverstartonce: boolean; + fraiseonbreak: boolean; + fgdbloadtimeout: realty; + ffpcgdbworkaround: boolean; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create; + property texp: ttextdebugoptions read ftexp; + published + property t: ttextdebugoptions read ft; + property defineson: longboolarty read fdefineson write fdefineson; + property stoponexception: boolean read fstoponexception write fstoponexception; + property valuehints: boolean read fvaluehints write fvaluehints; + property activateonbreak: boolean read factivateonbreak write factivateonbreak; + property raiseonbreak: boolean read fraiseonbreak write fraiseonbreak; + property showconsole: boolean read fshowconsole write fshowconsole; + property externalconsole: boolean read fexternalconsole write fexternalconsole; + property settty: boolean read fsettty write fsettty; + property gdbdownload: boolean read fgdbdownload write fgdbdownload; + property downloadalways: boolean read fdownloadalways write fdownloadalways; + property restartgdbbeforeload: boolean read frestartgdbbeforeload + write frestartgdbbeforeload; + property startupbkpt: integer read fstartupbkpt write fstartupbkpt; + property startupbkpton: boolean read fstartupbkpton write fstartupbkpton; + property gdbsimulator: boolean read fgdbsimulator write fgdbsimulator; + property gdbserverstartonce: boolean read fgdbserverstartonce + write fgdbserverstartonce; + property gdbloadtimeout: real read fgdbloadtimeout write fgdbloadtimeout; + property gdbserverwait: real read fgdbserverwait write fgdbserverwait; + property nogdbserverexit: boolean read fnogdbserverexit + write fnogdbserverexit; + property gdbservertty: boolean read fgdbservertty + write fgdbservertty; + property exceptclassnames: msestringarty read fexceptclassnames + write fexceptclassnames; + property exceptignore: booleanarty read fexceptignore + write fexceptignore; + property nodebugbeginend: boolean read fnodebugbeginend + write fnodebugbeginend; + property fpcgdbworkaround: boolean read ffpcgdbworkaround + write ffpcgdbworkaround; + end; + + tmacrooptions = class(toptions) + private + fmacroon: integerarty; + fmacronames: msestringarty; + fmacrovalues: msestringarty; + fgroupcomments: msestringarty; + published + property macroon: integerarty read fmacroon write fmacroon; + property macronames: msestringarty read fmacronames write fmacronames; + property macrovalues: msestringarty read fmacrovalues write fmacrovalues; + property groupcomments: msestringarty read fgroupcomments + write fgroupcomments; + end; + + ttextprojectstate = class(toptions) + private + fmessageoutputfile: filenamety; + published + property messageoutputfile: filenamety read fmessageoutputfile + write fmessageoutputfile; + end; + + tprojectstate = class(toptions) + private + ft: ttextprojectstate; + ftexp: ttextprojectstate; + + fmodulenames: msestringarty; + fmoduletypes: msestringarty; + fmodulefiles: filenamearty; + fmacrogroup: integer; + + fforcezorder: longbool; + fstripmessageesc: boolean; + fcopymessages: boolean; + fcheckmethods: boolean; + fclosemessages: boolean; + fcolorerror: colorty; + fcolorwarning: colorty; + fcolornote: colorty; +// fsettingsautoload: boolean; +// fsettingsautosave: boolean; + procedure setforcezorder(const avalue: longbool); + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create(); + property texp: ttextprojectstate read ftexp; + published + property t: ttextprojectstate read ft; + property modulenames: msestringarty read fmodulenames write fmodulenames; + property moduletypes: msestringarty read fmoduletypes write fmoduletypes; + property modulefiles: filenamearty read fmodulefiles write fmodulefiles; + property macrogroup: integer read fmacrogroup write fmacrogroup; + + property forcezorder: longbool read fforcezorder write setforcezorder; + property stripmessageesc: boolean read fstripmessageesc + write fstripmessageesc; + property copymessages: boolean read fcopymessages write fcopymessages; + property closemessages: boolean read fclosemessages write fclosemessages; + property checkmethods: boolean read fcheckmethods write fcheckmethods; + property colorerror: colorty read fcolorerror write fcolorerror; + property colorwarning: colorty read fcolorwarning write fcolorwarning; + property colornote: colorty read fcolornote write fcolornote; +{ + property settingsautoload: boolean read fsettingsautoload + write fsettingsautoload; + property settingsautosave: boolean read fsettingsautosave + write fsettingsautosave; +} + end; + + ttextfontaliasoptions = class(toptions) + private + ffontalias: msestringarty; + ffontnames: msestringarty; + ffontancestors: msestringarty; + ffontoptions: msestringarty; + published + property fontalias: msestringarty read ffontalias write ffontalias; + property fontnames: msestringarty read ffontnames write ffontnames; + property fontancestors: msestringarty read ffontancestors + write ffontancestors; + property fontoptions: msestringarty read ffontoptions write ffontoptions; + end; + + tfontaliasoptions = class(toptions) + private + ft: ttextfontaliasoptions; + ftexp: ttextfontaliasoptions; + ffontheights: integerarty; + ffontwidths: integerarty; + ffontxscales: realarty; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create(); + property texp: ttextfontaliasoptions read ftexp; + published + property t: ttextfontaliasoptions read ft; + property fontheights: integerarty read ffontheights write ffontheights; + property fontwidths: integerarty read ffontwidths write ffontwidths; + property fontxscales: realarty read ffontxscales write ffontxscales; + + end; + + ttextusercoloroptions = class(toptions) + end; + + tusercoloroptions = class(toptions) + private + ft: ttextusercoloroptions; + ftexp: ttextusercoloroptions; + fusercolors: colorarty; + fusercolorcomment: msestringarty; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create(); + property texp: ttextusercoloroptions read ftexp; + published + property t: ttextusercoloroptions read ft; + property usercolors: colorarty read fusercolors write fusercolors; + property usercolorcomment: msestringarty read fusercolorcomment + write fusercolorcomment; + end; + + ttextformatmacrooptions = class(toptions) + private + fformatmacronames: msestringarty; + fformatmacrovalues: msestringarty; + published + property formatmacronames: msestringarty read fformatmacronames + write fformatmacronames; + property formatmacrovalues: msestringarty read fformatmacrovalues + write fformatmacrovalues; + end; + + tformatmacrooptions = class(toptions) + private + ft: ttextformatmacrooptions; + ftexp: ttextformatmacrooptions; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create(); + property texp: ttextformatmacrooptions read ftexp; + published + property t: ttextformatmacrooptions read ft; + end; + + tstorageoptions = class(toptions) + private + fsettingsfile: filenamety; + fsettingseditor: boolean; + fsettingsdebugger: boolean; + fsettingsmake: boolean; + fsettingsmacros: boolean; + fsettingsfontalias: boolean; + fsettingsusercolors: boolean; + fsettingsformatmacros: boolean; + fsettingstemplates: boolean; + fsettingstools: boolean; + fsettingsstorage: boolean; + fsettingscomponentstore: boolean; + fsettingsprojecttree: boolean; + fsettingslayout: boolean; + fsettingsautoload: boolean; + fsettingsautosave: boolean; + public + constructor create(); + published + property settingsfile: filenamety read fsettingsfile write fsettingsfile; + property settingsautoload: boolean read fsettingsautoload + write fsettingsautoload; + property settingsautosave: boolean read fsettingsautosave + write fsettingsautosave; + property settingseditor: boolean read fsettingseditor write fsettingseditor; + property settingsdebugger: boolean read fsettingsdebugger + write fsettingsdebugger; + property settingsmake: boolean read fsettingsmake + write fsettingsmake; + property settingsmacros: boolean read fsettingsmacros + write fsettingsmacros; + property settingsfontalias: boolean read fsettingsfontalias + write fsettingsfontalias; + property settingsusercolors: boolean read fsettingsusercolors + write fsettingsusercolors; + property settingsformatmacros: boolean read fsettingsformatmacros + write fsettingsformatmacros; + property settingstemplates: boolean read fsettingstemplates + write fsettingstemplates; + property settingstools: boolean read fsettingstools + write fsettingstools; + property settingsstorage: boolean read fsettingsstorage + write fsettingsstorage; + property settingscomponentstore: boolean read fsettingscomponentstore + write fsettingscomponentstore; + property settingsprojecttree: boolean read fsettingsprojecttree + write fsettingsprojecttree; + property settingslayout: boolean read fsettingslayout + write fsettingslayout; + end; + + ttextmakeoptions = class(toptions) + private + fmainfile: filenamety; + ftargetfile: filenamety; + fmakecommand: filenamety; + fmakedir: filenamety; + funitdirs: msestringarty; + funitpref: msestring; + fincpref: msestring; + flibpref: msestring; + fobjpref: msestring; + ftargpref: msestring; + fbefcommand: msestringarty; + faftcommand: msestringarty; + fmakeoptions: msestringarty; +// ffontnames: msestringarty; + public +// fcodetemplatedirs: msestringarty; + published + property mainfile: filenamety read fmainfile write fmainfile; + property targetfile: filenamety read ftargetfile write ftargetfile; + property makecommand: filenamety read fmakecommand write fmakecommand; + property makedir: filenamety read fmakedir write fmakedir; + property unitdirs: msestringarty read funitdirs write funitdirs; + property unitpref: msestring read funitpref write funitpref; + property incpref: msestring read fincpref write fincpref; + property libpref: msestring read flibpref write flibpref; + property objpref: msestring read fobjpref write fobjpref; + property targpref: msestring read ftargpref write ftargpref; + + property befcommand: msestringarty read fbefcommand write fbefcommand; + property aftcommand: msestringarty read faftcommand write faftcommand; + property makeoptions: msestringarty read fmakeoptions write fmakeoptions; + +// property codetemplatedirs: msestringarty read fcodetemplatedirs +// write fcodetemplatedirs; + end; + + tmakeoptions = class(toptions) + private + ft: ttextmakeoptions; + ftexp: ttextmakeoptions; + +// fusercolors: colorarty; +// fusercolorcomment: msestringarty; + +// fformatmacronames: msestringarty; +// fformatmacrovalues: msestringarty; +{ + fsettingsfile: filenamety; + fsettingseditor: boolean; + fsettingsdebugger: boolean; + fsettingsmake: boolean; + fsettingsmacros: boolean; + fsettingsfontalias: boolean; + fsettingsusercolors: boolean; + fsettingsformatmacros: boolean; + fsettingstemplates: boolean; + fsettingstools: boolean; + fsettingsstorage: boolean; + fsettingscomponentstore: boolean; + fsettingsprojecttree: boolean; + fsettingslayout: boolean; + fsettingsautoload: boolean; + fsettingsautosave: boolean; +} +// fmoduleoptions: integerarty; + fmakeoptpurpose: msestringarty; + fbefcommandon: integerarty; + fmakeoptionson: integerarty; + faftcommandon: integerarty; + funitdirson: integerarty; +{ + ffontalias: msestringarty; + ffontancestors: msestringarty; + ffontheights: integerarty; + ffontwidths: integerarty; + ffontoptions: msestringarty; + ffontxscales: realarty; + } + fuid: integer; + freversepathorder: boolean; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create; + property texp: ttextmakeoptions read ftexp; + published + property t: ttextmakeoptions read ft; + + property reversepathorder: boolean read freversepathorder + write freversepathorder; + + property makeoptpurpose: msestringarty read fmakeoptpurpose + write fmakeoptpurpose; + property befcommandon: integerarty read fbefcommandon write fbefcommandon; + property makeoptionson: integerarty read fmakeoptionson write fmakeoptionson; + property aftcommandon: integerarty read faftcommandon write faftcommandon; + property unitdirson: integerarty read funitdirson write funitdirson; + + property uid: integer read fuid write fuid; //for insert UID + end; +{ + ttextprojectoptions = class(toptions) + end; + + tprojectoptions = class(toptions) + private + ft: ttextprojectoptions; + ftexp: ttextprojectoptions; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create(); + property texp: ttextprojectoptions read ftexp; + published + property t: ttextprojectoptions read ft; + end; +} +{$M-} + + projectoptionsty = record + disabled: settinggroupsty; +// o: tprojectoptions; + e: teditoptions; + d: tdebugoptions; + k: tmakeoptions; + m: tmacrooptions; + a: tfontaliasoptions; + u: tusercoloroptions; + f: tformatmacrooptions; + p: ttemplatesoptions; + t: ttoolsoptions; + r: tstorageoptions; + s: tprojectstate; + modified: boolean; + savechecked: boolean; + ignoreexceptionclasses: stringarty; + projectfilename: filenamety; + projectdir: filenamety; + defaultmake: integer; + sigsettings: sigsetinfoarty; + progparamhistory: msestringarty; + workdirparamhistory: msestringarty; + envvarons: longboolarty; + findreplaceinfo: replaceinfoty; + targetconsolefindinfo: findinfoty; + end; + + tprojectoptionsfo = class(tmseform) + statfile1: tstatfile; + tlayouter9: tlayouter; + tlayouter8: tlayouter; + cancel: tbutton; + ok: tbutton; + tabwidget: ttabwidget; + editorpage: ttabpage; + debuggerpage: ttabpage; + debugcommand: tfilenameedit; + debugoptions: tmemodialogedit; + ttabwidget1: ttabwidget; + ttabpage6: ttabpage; + sourcedirgrid: twidgetgrid; + sourcedirs: tfilenameedit; + ttabpage9: ttabpage; + twidgetgrid2: twidgetgrid; + defineson: tbooleanedit; + defines: tstringedit; + ttabpage7: ttabpage; + signalgrid: twidgetgrid; + sigstop: tbooleanedit; + sighandle: tbooleanedit; + signum: tintegeredit; + signumto: tintegeredit; + signame: tselector; + ttabpage8: ttabpage; + exceptionsgrid: twidgetgrid; + exceptignore: tbooleanedit; + exceptclassnames: tstringedit; + ttabpage16: ttabpage; + remoteconnection: tstringedit; + tlayouter3: tlayouter; + gdbprocessor: tdropdownlistedit; + gdbsimulator: tbooleanedit; + gdbdownload: tbooleanedit; + tlayouter4: tlayouter; + beforeconnect: tfilenameedit; + tsplitter7: tsplitter; + beforeload: tfilenameedit; + tlayouter5: tlayouter; + afterconnect: tfilenameedit; + tsplitter8: tsplitter; + tlayouter1: tlayouter; + externalconsole: tbooleanedit; + showconsole: tbooleanedit; + stoponexception: tbooleanedit; + activateonbreak: tbooleanedit; + makepage: ttabpage; + tspacer2: tspacer; + defaultmake: tenumedit; + mainfile: tfilenameedit; + targetfile: tfilenameedit; + makecommand: tfilenameedit; + showcommandline: tbutton; + messageoutputfile: tfilenameedit; + copymessages: tbooleanedit; + closemessages: tbooleanedit; + checkmethods: tbooleanedit; + makegroupbox: ttabwidget; + ttabpage12: ttabpage; + makeoptionsgrid: twidgetgrid; + makeon: tbooleanedit; + buildon: tbooleanedit; + make1on: tbooleanedit; + make2on: tbooleanedit; + make3on: tbooleanedit; + make4on: tbooleanedit; + makeoptions: tmemodialogedit; + ttabpage11: ttabpage; + unitdirgrid: twidgetgrid; + dmakeon: tbooleanedit; + dbuildon: tbooleanedit; + dmake1on: tbooleanedit; + dmake2on: tbooleanedit; + dmake3on: tbooleanedit; + dmake4on: tbooleanedit; + duniton: tbooleanedit; + dincludeon: tbooleanedit; + dlibon: tbooleanedit; + dobjon: tbooleanedit; + unitdirs: tfilenameedit; + tspacer1: tspacer; + targpref: tstringedit; + makedir: tfilenameedit; + tsplitter1: tsplitter; + tsplitter2: tsplitter; + tsplitter4: tsplitter; + tsplitter5: tsplitter; + ttabpage1: ttabpage; + macrogrid: twidgetgrid; + e0: tbooleanedit; + e1: tbooleanedit; + e2: tbooleanedit; + e3: tbooleanedit; + e4: tbooleanedit; + e5: tbooleanedit; + macronames: tstringedit; + macrovalues: tmemodialogedit; + selectactivegroupgrid: twidgetgrid; + activemacroselect: tbooleaneditradio; + groupcomment: tstringedit; + macrosplitter: tsplitter; + fontaliaspage: ttabpage; + fontaliasgrid: twidgetgrid; + fontalias: tstringedit; + fontname: tstringedit; + fontheight: tintegeredit; + ttabpage10: ttabpage; + tlayouter7: tlayouter; + tbutton1: tbutton; + colgrid: twidgetgrid; + coldi: tpointeredit; + usercolors: tcoloredit; + usercolorcomment: tstringedit; + ttabpage2: ttabpage; + newfile: ttabwidget; + ttabpage3: ttabpage; + copygrid: twidgetgrid; + loadprojectfile: tbooleanedit; + expandprojectfilemacros: tbooleanedit; + newprojectfiles: tfilenameedit; + newprojectfilesdest: tstringedit; + ttabpage4: ttabpage; + ttabpage5: ttabpage; + ttabpage15: ttabpage; + twidgetgrid3: twidgetgrid; + toolsave: tbooleanedit; + toolparse: tbooleanedit; + toolhide: tbooleanedit; + toolmenus: tstringedit; + toolfiles: tfilenameedit; + toolparams: tstringedit; + downloadalways: tbooleanedit; + startupbkpt: tintegeredit; + startupbkpton: tbooleanedit; + valuehints: tbooleanedit; + debugtarget: tfilenameedit; + debugtargetsplitter: tsplitter; + fontwidth: tintegeredit; + fontoptions: tstringedit; + fontxscale: trealedit; + twidgetgrid4: twidgetgrid; + newfonames: tstringedit; + newfosources: tfilenameedit; + newfoforms: tfilenameedit; + scriptbeforecopy: tfilenameedit; + scriptaftercopy: tfilenameedit; + newinheritedforms: tbooleanedit; + newfonamebases: tstringedit; + twidgetgrid1: twidgetgrid; + newfinames: tstringedit; + newfisources: tfilenameedit; + newfifilters: tstringedit; + newfiexts: tstringedit; + fontancestors: tstringedit; + ttabpage17: ttabpage; + ttabpage18: ttabpage; + befcommandgrid: twidgetgrid; + befmakeon: tbooleanedit; + befbuildon: tbooleanedit; + befmake1on: tbooleanedit; + befmake2on: tbooleanedit; + befmake3on: tbooleanedit; + befmake4on: tbooleanedit; + befcommand: tmemodialogedit; + aftcommandgrid: twidgetgrid; + aftmakeon: tbooleanedit; + aftbuildon: tbooleanedit; + aftmake1on: tbooleanedit; + aftmake2on: tbooleanedit; + aftmake3on: tbooleanedit; + aftmake4on: tbooleanedit; + aftcommand: tmemodialogedit; + ttabpage20: ttabpage; + settingseditor: tbooleanedit; + settingsautoload: tbooleanedit; + settingsautosave: tbooleanedit; + tlayouter6: tlayouter; + savebu: tbutton; + loadbu: tbutton; + settingsfile: tfilenameedit; + settingsdebugger: tbooleanedit; + settingsstorage: tbooleanedit; + settingsprojecttree: tbooleanedit; + nodebugbeginend: tbooleanedit; + toolmessages: tbooleanedit; + settty: tbooleanedit; + tsplitter9: tsplitter; + beforerun: tfilenameedit; + afterload: tfilenameedit; + tsplitter10: tsplitter; + ttabpage21: ttabpage; + formatmacrogrid: twidgetgrid; + formatmacronames: tstringedit; + formatmacrovalues: tstringedit; + colorerror: tcoloredit; + tspacer5: tspacer; + colorwarning: tcoloredit; + tspacer6: tspacer; + colornote: tcoloredit; + c: tstringcontainer; + xtermcommand: tmemodialogedit; + debugsplitter: tsplitter; + tspacer4: tspacer; + stripmessageesc: tbooleanedit; + raiseonbreak: tbooleanedit; + runcommand: tfilenameedit; + sourcebase: tfilenameedit; + tspacer7: tspacer; + toolshortcuts: tenumedit; + toolsc: tstringedit; + toolscalt: tstringedit; + fpcgdbworkaround: tbooleanedit; + ttabwidget3: ttabwidget; + ttabpage22: ttabpage; + componenthints: tbooleanedit; + noformdesignerdocking: tbooleanedit; + moveonfirstclick: tbooleanedit; + gridsizey: tintegeredit; + gridsizex: tintegeredit; + tintegeredit2: tintegeredit; + snaptogrid: tbooleanedit; + showgrid: tbooleanedit; + ttabpage23: ttabpage; + ttabwidget2: ttabwidget; + ttabpage13: ttabpage; + filefiltergrid: tstringgrid; + ttabpage14: ttabpage; + twidgetgrid6: twidgetgrid; + syntaxdeffile: tfilenameedit; + syntaxdeffilemask: tmemodialogedit; + ttabpage19: ttabpage; + twidgetgrid5: twidgetgrid; + codetemplatedirs: tfilenameedit; + tlayouter13: tlayouter; + dispgrid: twidgetgrid; + fontdisp: ttextedit; + tlayouter12: tlayouter; + editfontextraspace: tintegeredit; + editfontwidth: tintegeredit; + editfontheight: tintegeredit; + editfontname: tstringedit; + editfontcolor: tcoloredit; + editbkcolor: tcoloredit; + editfontantialiased: tbooleanedit; + tlayouter11: tlayouter; + tlayouter14: tlayouter; + rightmarginon: tbooleanedit; + linenumberson: tbooleanedit; + editmarkbrackets: tbooleanedit; + editmarkpairwords: tbooleanedit; + tlayouter15: tlayouter; + pairmarkcolor: tcoloredit; + statementcolor: tcoloredit; + scrollheight: tintegeredit; + rightmarginchars: tintegeredit; + tlayouter10: tlayouter; + spacetabs: tbooleanedit; + blockindent: tintegeredit; + autoindent: tbooleanedit; + tabindent: tbooleanedit; + tabstops: tintegeredit; + showtabs: tbooleanedit; + tlayouter16: tlayouter; + eolstyle: tenumtypeedit; + trimtrailingwhitespace: tbooleanedit; + encoding: tenumedit; + backupfilecount: tintegeredit; + tlayouter17: tlayouter; + objpref: tstringedit; + libpref: tstringedit; + incpref: tstringedit; + unitpref: tstringedit; + reversepathorder: tbooleanedit; + settingsmacros: tbooleanedit; + settingstools: tbooleanedit; + settingstemplates: tbooleanedit; + tsimplewidget1: tsimplewidget; + settingscomponentstore: tbooleanedit; + settingslayout: tbooleanedit; + tlabel1: tlabel; + settingsmake: tbooleanedit; + settingsusercolors: tbooleanedit; + settingsformatmacros: tbooleanedit; + settingsfontalias: tbooleanedit; + makeoptpurpose: tstringedit; + pairmaxrowcount: tintegeredit; + newfoformsuffixes: tstringedit; + downloadlayouter: tlayouter; + gdbservercommand: tfilenameedit; + gdbservercommandattach: tfilenameedit; + uploadcommand: tfilenameedit; + texpandingwidget1: texpandingwidget; + gdbloadtimeout: trealedit; + serverla: tlayouter; + gdbserverwait: trealedit; + gdbserverstartonce: tbooleanedit; + tlayouter2: tlayouter; + nogdbserverexit: tbooleanedit; + gdbservertty: tbooleanedit; + tstringedit1: tstringedit; + optafter: tbooleanedit; + restartgdbbeforeload: tbooleanedit; + procedure acttiveselectondataentered(const sender: TObject); + procedure colonshowhint(const sender: tdatacol; const arow: Integer; + var info: hintinfoty); + procedure hintexpandedmacros(const sender: TObject; var info: hintinfoty); + procedure selectactiveonrowsmoved(const sender: tcustomgrid; + const fromindex: Integer; const toindex: Integer; + const acount: Integer); + procedure expandfilename(const sender: TObject; var avalue: mseString; + var accept: Boolean); + procedure showcommandlineonexecute(const sender: TObject); + procedure signameonsetvalue(const sender: TObject; var avalue: integer; + var accept: Boolean); + procedure signumonsetvalue(const sender: TObject; var avalue: integer; + var accept: Boolean); + procedure signumtoonsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure fontondataentered(const sender: TObject); + procedure makepageonchildscaled(const sender: TObject); + procedure debuggerlayoutexe(const sender: TObject); + procedure macronchildscaled(const sender: TObject); + procedure formtemplateonchildscaled(const sender: TObject); + procedure encodingsetvalue(const sender: TObject; var avalue: integer; + var accept: Boolean); + procedure createexe(const sender: TObject); + procedure drawcol(const sender: tpointeredit; const acanvas: tcanvas; + const avalue: Pointer; const arow: Integer); + procedure colsetvalue(const sender: TObject; var avalue: colorty; + var accept: Boolean); + procedure copycolorcode(const sender: TObject); + procedure downloadchange(const sender: TObject); + procedure processorchange(const sender: TObject); + procedure copymessagechanged(const sender: TObject); + procedure updatedebugenabled(const sender: TObject); + procedure newprojectchildscaled(const sender: TObject); + procedure saveexe(const sender: TObject); + procedure settingsdataent(const sender: TObject); + procedure loadexe(const sender: TObject); +// procedure extconschangeexe(const sender: TObject); + procedure setxtermcommandexe(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure activateonbreakset(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure sourcedirhint(const sender: TObject; var info: hintinfoty); + procedure toolshortcutdropdown(const sender: TObject); + procedure toolsrowdatachanged(const sender: tcustomgrid; + const acell: gridcoordty); + procedure colorhint(const sender: TObject; var info: hintinfoty); + procedure initeolstyleexe(const sender: tenumtypeedit); + procedure debugtargetlayoutev(const sender: TObject); + private + procedure activegroupchanged; + end; + +function readprojectoptions(const filename: filenamety): boolean; + //true if ok +procedure saveprojectoptions(filename: filenamety = ''); +procedure initprojectoptions; +function editprojectoptions: boolean; + //true if not aborted +function getprojectmacros: macroinfoarty; +procedure expandprojectmacros; +function expandprmacros(const atext: msestring): msestring; +procedure expandprmacros1(var atext: msestring); +function projecttemplatedir: filenamety; +function projectfiledialog(var aname: filenamety; save: boolean): modalresultty; +procedure projectoptionsmodified; +function checkprojectloadabort: boolean; //true on load abort + +function getsigname(const anum: integer): string; +procedure projectoptionstofont(const afont: tfont); +function objpath(const aname: filenamety): filenamety; +function sourcepath(const aname: filenamety): filenamety; +function gettargetfile: filenamety; +function getmacros: tmacrolist; +procedure hintmacros(const sender: tcustomedit; var info: hintinfoty); + +var + projectoptions: projectoptionsty; + projecthistory: filenamearty; + windowlayoutfile: filenamety; + windowlayouthistory: filenamearty; + codetemplates: tcodetemplates; + +implementation +uses + projectoptionsform_mfm,breakpointsform,sourceform,msereal, + objectinspector,msebits,msefileutils,msedesignintf,guitemplates, + watchform,stackform,main,projecttreeform,findinfileform, + selecteditpageform,programparametersform,sourceupdate,mseimagelisteditor, + msesysenvmanagereditor,targetconsole,actionsmodule,mseactions, + msefilemacros,mseenvmacros,msemacmacros,mseexecmacros,msestrmacros, + msedesigner,panelform,watchpointsform,commandlineform,messageform, + componentpaletteform,mserichstring,msesettings,formdesigner, + msestringlisteditor,msetexteditor,msepropertyeditors,mseshapes, + componentstore,cpuform,msesysutils,msecomptree,msefont,typinfo + {$ifndef mse_no_db}{$ifdef FPC},msedbfieldeditor{$endif}{$endif} + {$ifndef mse_no_ifi}{$ifdef FPC},mseificomponenteditors, + mseififieldeditor{$endif}{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +var + projectoptionsfo: tprojectoptionsfo; +type + + stringconststy = ( + wrongencoding, //0 Wrong encoding can damage your source files. + wishsetencoding, //1 Do you wish to set encoding to + warning, //2 *** WARNING *** + c_SIGHUP, //3 Hangup + c_SIGINT, //4 Interrupt + c_SIGQUIT, //5 Quit + c_SIGILL, //6 Illegal instruction + c_SIGTRAP, //7 Trace trap + c_SIGABRT, //8 Abort + c_SIGBUS, //9 BUS error + c_SIGFPE, //10 Floating-point exception + c_SIGKILL, //11 Kill + c_SIGUSR1, //12 User-defined signal 1 + c_SIGSEGV, //13 Segmentation violation + c_SIGUSR2, //14 User-defined signal 2 + c_SIGPIPE, //15 Broken pipe + c_SIGALRM, //16 Alarm clock + c_SIGTERM, //17 Termination + c_SIGSTKFLT, //18 Stack fault + c_SIGCHLD, //19 Child status has changed + c_SIGCONT, //20 Continue + c_SIGSTOP, //21 Stop, unblockable + c_SIGTSTP, //22 Keyboard stop + c_SIGTTIN, //23 Background read from tty + c_SIGTTOU, //24 Background write to tty + c_SIGURG, //25 Urgent condition on socket + c_SIGXCPU, //26 CPU limit exceeded + c_SIGXFSZ, //27 File size limit exceeded + c_SIGTALRM, //28 Virtual alarm clock + c_SIGPROF, //29 Profiling alarm clock + c_SIGWINCH, //30 Window size change + c_SIGIO, //31 I/O now possible + c_SIGPWR //32 Power failure restart + ); +const + firstsiginfocomment = c_sighup; + lastsiginfocomment = c_sigpwr; + +type + signalinfoty = record + num: integer; + flags: sigflagsty; + name: string; + comment: string; + end; + +const + findinfiledialogstatname = 'findinfiledialogfo.sta'; + finddialogstatname = 'finddialogfo.sta'; + replacedialogstatname = 'replacedialogfo.sta'; + optionsstatname = 'optionsfo.sta'; + settaborderstatname = 'settaborderfo.sta'; + setcreateorderstatname = 'setcreateorderfo.sta'; + programparametersstatname = 'programparametersfo.sta'; + settingsstatname = 'settingsfo.sta'; + printerstatname = 'printer.sta'; + imageselectorstatname = 'imageselector.sta'; + fadeeditorstatname = 'fadeeditor.sta'; + codetemplateselectstatname ='templselect.sta'; + codetemplateparamstatname = 'templparam.sta'; + codetemplateeditstatname = 'templedit.sta'; + cornermaskeditstatname = 'cornermask.sta'; + memodialogstatname = 'memodialog.sta'; + richmemodialogstatname = 'richmemodialog.sta'; + fontformatdialogstatname = 'fontformatdialog.sta'; + taborderoverridedialogstatname = 'taborderoverrideeditor.sta'; + + siginfocount = 30; +var + siginfos: array[0..siginfocount-1] of signalinfoty = ( + (num: 1; flags: [sfl_stop]; name: 'SIGHUP'; comment: 'Hangup'), + (num: 2; flags: [sfl_stop,sfl_internal,sfl_handle]; name: 'SIGINT'; comment: 'Interrupt'), + (num: 3; flags: [sfl_stop]; name: 'SIGQUIT'; comment: 'Quit'), + (num: 4; flags: [sfl_stop]; name: 'SIGILL'; comment: 'Illegal instruction'), + (num: 5; flags: [sfl_stop,sfl_internal,sfl_handle]; name: 'SIGTRAP'; comment: 'Trace trap'), + (num: 6; flags: [sfl_stop]; name: 'SIGABRT'; comment: 'Abort'), + (num: 7; flags: [sfl_stop]; name: 'SIGBUS'; comment: 'BUS error'), + (num: 8; flags: [sfl_stop]; name: 'SIGFPE'; comment: 'Floating-point exception'), + (num: 9; flags: [sfl_stop]; name: 'SIGKILL'; comment: 'Kill, unblockable'), + (num: 10; flags: [sfl_stop]; name: 'SIGUSR1'; comment: 'User-defined signal 1'), + (num: 11; flags: [sfl_stop]; name: 'SIGSEGV'; comment: 'Segmentation violation'), + (num: 12; flags: [sfl_stop]; name: 'SIGUSR2'; comment: 'User-defined signal 2'), + (num: 13; flags: [sfl_stop]; name: 'SIGPIPE'; comment: 'Broken pipe'), + (num: 14; flags: [sfl_internal]; name: 'SIGALRM'; comment: 'Alarm clock'), + (num: 15; flags: [sfl_stop]; name: 'SIGTERM'; comment: 'Termination'), + (num: 16; flags: [sfl_stop]; name: 'SIGSTKFLT'; comment: 'Stack fault'), + (num: 17; flags: [{sfl_stop}]; name: 'SIGCHLD'; comment: 'Child status has changed'), + (num: 18; flags: [sfl_stop]; name: 'SIGCONT'; comment: 'Continue'), + (num: 19; flags: [sfl_stop]; name: 'SIGSTOP'; comment: 'Stop, unblockable'), + (num: 20; flags: [sfl_stop]; name: 'SIGTSTP'; comment: 'Keyboard stop'), + (num: 21; flags: [sfl_stop]; name: 'SIGTTIN'; comment: 'Background read from tty'), + (num: 22; flags: [sfl_stop]; name: 'SIGTTOU'; comment: 'Background write to tty'), + (num: 23; flags: [sfl_stop]; name: 'SIGURG'; comment: 'Urgent condition on socket'), + (num: 24; flags: [sfl_stop]; name: 'SIGXCPU'; comment: 'CPU limit exceeded'), + (num: 25; flags: [sfl_stop]; name: 'SIGXFSZ'; comment: 'File size limit exceeded'), + (num: 26; flags: [sfl_stop]; name: 'SIGTALRM'; comment: 'Virtual alarm clock'), + (num: 27; flags: [sfl_stop]; name: 'SIGPROF'; comment: 'Profiling alarm clock'), + (num: 28; flags: [sfl_stop]; name: 'SIGWINCH'; comment: 'Window size change'), + (num: 29; flags: [sfl_stop]; name: 'SIGIO'; comment: 'I/O now possible'), + (num: 30; flags: [sfl_stop]; name: 'SIGPWR'; comment: 'Power failure restart') + ); + +function getsigname(const anum: integer): string; +var + int1: integer; +begin + result:= ''; + for int1:= 0 to high(siginfos) do begin + if siginfos[int1].num = anum then begin + result:= siginfos[int1].name; + break; + end; + end; + if result = '' then begin + result:= 'SIG'+inttostr(anum); + end; +end; + +function objpath(const aname: filenamety): filenamety; +begin + result:= ''; + if aname <> '' then begin + result:= filepath(projectoptions.k.texp.makedir,aname); + end; +end; + +function sourcepath(const aname: filenamety): filenamety; +begin + result:= ''; + if aname <> '' then begin + if projectoptions.d.t.sourcebase <> '' then begin + result:= filepath(projectoptions.d.texp.sourcebase,aname); + end + else begin + result:= objpath(aname); + end; + end; +end; + +function getprojectmacros: macroinfoarty; +var + int1,int2: integer; +begin + setlength(result,6); + with projectoptions,k do begin + with result[0] do begin + name:= 'PROJECTNAME'; + value:= removefileext(filename(projectfilename)) + end; + with result[1] do begin + name:= 'PROJECTDIR'; + value:= tosysfilepath(getcurrentdirmse)+pathdelim; + end; + with result[2] do begin + name:= 'MAINFILE'; + if projectoptionsfo = nil then begin + value:= t.mainfile; + end + else begin + value:= projectoptionsfo.mainfile.value; + end; + end; + with result[3] do begin + name:= 'TARGETFILE'; + if projectoptionsfo = nil then begin + value:= t.targetfile; + end + else begin + value:= projectoptionsfo.targetfile.value; + end; + end; + with result[4] do begin + name:= 'TARGETENV'; + int2:= high(envvarons); + if int2 > high(d.t.envvarnames) then begin + int2:= high(d.t.envvarnames); + end; + if int2 > high(d.t.envvarvalues) then begin + int2:= high(d.t.envvarvalues); + end; + for int1:= 0 to int2 do begin + if envvarons[int1] then begin + value:= value+d.t.envvarnames[int1]+'='+d.t.envvarvalues[int1]+' '; + end + else begin + value:= value+'--unset='+d.t.envvarnames[int1]+' '; + end; + end; + end; + with result[5] do begin + name:= 'TARGETPARAMS'; + value:= d.t.progparameters; + end; + end; + result:= initmacros([result,macmacros,filemacros,envmacros,execmacros, + strmacros]); +end; + +procedure hintmacros(const sender: tcustomedit; var info: hintinfoty); +begin + info.caption:= tcustomedit(sender).text; + expandprmacros1(info.caption); + include(info.flags,hfl_show); //show empty caption +end; + +function gettargetfile: filenamety; +begin + with projectoptions,d.texp do begin + if trim(debugtarget) <> '' then begin + result:= objpath(debugtarget); + end + else begin + result:= objpath(k.texp.targetfile); + end; + end; +end; + +procedure projectoptionstofont(const afont: tfont); +begin + with projectoptions,afont do begin + name:= ansistring(e.editfontname); + height:= e.editfontheight; + width:= e.editfontwidth; + extraspace:= e.editfontextraspace; + if e.editfontantialiased then begin + options:= options + [foo_antialiased2]; + end + else begin + options:= options + [foo_nonantialiased]; + end; + color:= e.editfontcolor; + end; +end; + +function checkprojectloadabort: boolean; +begin + result:= false; + if exceptobject is exception then begin + if showmessage(msestring(exception(exceptobject).Message), + actionsmo.c[ord(ac_error)],[mr_skip,mr_cancel]) <> mr_skip then begin + result:= true; + end; + end + else begin + raise exception.create(ansistring(actionsmo.c[ord(ac_invalidexception)])); + end; +end; + +function projectfiledialog(var aname: filenamety; save: boolean): modalresultty; +begin + with mainfo.projectfiledia.controller do begin + filename:= projectoptions.projectfilename; + history:= projecthistory; + if save then begin + result:= execute(fdk_save,[fdo_save,fdo_checkexist]); + end + else begin + result:= execute(fdk_open,[fdo_checkexist]); + end; + aname:= filename; + projecthistory:= history; + end; +end; + +function getmacros: tmacrolist; +var + ar1: macroinfoarty; + int1,int2: integer; + mask: integer; + +begin + with projectoptions.m do begin + result:= tmacrolist.create([mao_caseinsensitive]); + result.add(getsettingsmacros); + result.add(getcommandlinemacros); + result.add(getprojectmacros); + mask:= bits[projectoptions.s.macrogroup]; + setlength(fmacrovalues,length(macronames)); + setlength(ar1,length(macronames)); //max + int2:= 0; + for int1:= 0 to high(ar1) do begin + if macroon[int1] and mask <> 0 then begin + ar1[int2].name:= macronames[int1]; + ar1[int2].value:= macrovalues[int1]; + inc(int2); + end; + end; + setlength(ar1,int2); + result.add(ar1); + end; +end; + +procedure expandprmacros1(var atext: msestring); +var + li: tmacrolist; +begin + li:= getmacros; + li.expandmacros1(atext); + li.Free; +end; + +function projecttemplatedir: filenamety; +begin + result:= expandprmacros('${TEMPLATEDIR}'); +end; + +function expandprmacros(const atext: msestring): msestring; +begin + result:= atext; + expandprmacros1(result); +end; + +var + initfontaliascount: integer; + +procedure expandprojectmacros; +var + li: tmacrolist; + int1,int2: integer; + bo1: boolean; + item1: tmenuitem; + act1: taction; +begin + li:= getmacros; + with projectoptions do begin +// o.expandmacros(li); + e.expandmacros(li); + d.expandmacros(li); + m.expandmacros(li); + k.expandmacros(li); + a.expandmacros(li); + u.expandmacros(li); + f.expandmacros(li); + p.expandmacros(li); + t.expandmacros(li); + r.expandmacros(li); + s.expandmacros(li); + with a,texp do begin + if initfontaliascount = 0 then begin + initfontaliascount:= fontaliascount; + end; + setfontaliascount(initfontaliascount); + int2:= high(fontalias); + int1:= high(fontancestors); + setlength(ffontancestors,int2+1); //additional field + for int1:= int1+1 to int2 do begin + fontancestors[int1]:= 'sft_default'; + end; + if int2 > high(fontnames) then begin + int2:= high(fontnames); + end; + if int2 > high(fontheights) then begin + int2:= high(fontheights); + end; + if int2 > high(fontwidths) then begin + int2:= high(fontwidths); + end; + if int2 > high(fontoptions) then begin + int2:= high(fontoptions); + end; + if int2 > high(fontxscales) then begin + int2:= high(fontxscales); + end; + for int1:= 0 to int2 do begin + try + registerfontalias(ansistring(fontalias[int1]), + ansistring(fontnames[int1]),fam_overwrite, + fontheights[int1],fontwidths[int1], + fontoptioncharstooptions(ansistring(fontoptions[int1])), + fontxscales[int1],ansistring(fontancestors[int1])); + except + application.handleexception; + end; + end; + if sourceupdater <> nil then begin + sourceupdater.maxlinelength:= e.rightmarginchars; + end; + fontaliasnames:= fontalias; + end; + with s,texp do begin + with sourcefo.syntaxpainter do begin + bo1:= not cmparray(defdefs.asarraya,e.texp.sourcefilemasks) or + not cmparray(defdefs.asarrayb,e.texp.syntaxdeffiles); + defdefs.asarraya:= e.texp.sourcefilemasks; + defdefs.asarrayb:= e.texp.syntaxdeffiles; + if bo1 then begin + sourcefo.syntaxpainter.clear; + try + for int1:= 0 to sourcefo.count - 1 do begin + sourcefo.items[int1].edit.setsyntaxdef(sourcefo.items[int1].edit.filename); + end; + except + application.handleexception; + end; + end; + end; + for int1:= 0 to sourcefo.count - 1 do begin + sourcefo.items[int1].updatestatvalues; + end; + with mainfo.openfile.controller.filterlist do begin + asarraya:= e.texp.filemasknames; + asarrayb:= e.texp.filemasks; + end; + item1:= mainfo.mainmenu1.menu.itembynames(['file','new']); + item1.submenu.count:= 1; + with p.texp do begin + item1.submenu.count:= length(newfinames)+1; + for int1:= 0 to high(newfinames) do begin + with item1.submenu[int1+1] do begin + caption:= newfinames[int1]; + tag:= int1; + onexecute:= {$ifdef FPC}@{$endif}mainfo.newfileonexecute; + end; + end; + + item1:= mainfo.mainmenu1.menu.itembynames(['file','new','form']); + item1.submenu.count:= 0; + item1.submenu.count:= length(newfonames)+1; + int2:= 0; + for int1:= 0 to high(newfonames) do begin + if not p.newinheritedforms[int1] then begin + with item1.submenu[int2] do begin + caption:= newfonames[int1]; + tag:= int1; + onexecute:= {$ifdef FPC}@{$endif}mainfo.newformonexecute; + end; + inc(int2); + end; + end; + item1.submenu[int2].options:= [mao_separator]; + inc(int2); + for int1:= 0 to high(newfonames) do begin + if p.newinheritedforms[int1] then begin + with item1.submenu[int2] do begin + caption:= newfonames[int1]; + tag:= int1; + onexecute:= {$ifdef FPC}@{$endif}mainfo.newformonexecute; + end; + inc(int2); + end; + end; + end; + with mainfo.mainmenu1.menu.submenu do begin + item1:= itembyname('tools'); + with projectoptions.t,texp do begin + if toolmenus <> nil then begin + if item1 = nil then begin + item1:= tmenuitem.create; + item1.name:= 'tools'; + item1.caption:= actionsmo.c[ord(ac_tools)]; + insert(itemindexbyname('settings'),item1); + end; + with item1.submenu do begin + clear; + for int1:= 0 to high(toolmenus) do begin + if (int1 > high(toolfiles)) or (int1 > high(toolparams)) then begin + break; + end; + int2:= insert(bigint,[toolmenus[int1]], + [[mao_asyncexecute,mao_shortcutcaption]], + [],[{$ifdef FPC}@{$endif}mainfo.runtool]); + if (int1 <= high(toolshortcuts)) and + actionsmo.gettoolshortcutaction(toolshortcuts[int1],act1) then begin + with items[int2] do begin + shortcuts:= act1.shortcuts; + shortcuts1:= act1.shortcuts1; + end; + end; + end; + end; + end + else begin + if item1 <> nil then begin + delete(item1.index); + end; + end; + end; + end; + end; + ignoreexceptionclasses:= nil; + for int1:= 0 to high(d.exceptignore) do begin + if int1 > high(d.exceptclassnames) then begin + break; + end; + if d.exceptignore[int1] then begin + additem(ignoreexceptionclasses,ansistring(d.exceptclassnames[int1])); + end; + end; + for int1:= 0 to usercolorcount - 1 do begin + if int1 > high(u.usercolors) then begin + break; + end; + setcolormapvalue(cl_user + longword(int1),u.usercolors[int1]); + end; + clearformatmacros; + for int1:= 0 to high(f.texp.formatmacronames) do begin + if int1 > high(f.texp.formatmacrovalues) then begin + break; + end; + formatmacros.add(f.texp.formatmacronames[int1],f.texp.formatmacrovalues[int1],[]); + end; + + codetemplates.scan(e.texp.codetemplatedirs); + end; + li.free; + mainfo.updatesigsettings; +end; + +function defaultsigsettings: sigsetinfoarty; +var + int1,int2: integer; +begin + setlength(result,siginfocount); + int2:= 0; + for int1:= 0 to siginfocount - 1 do begin + with result[int2] do begin + if not (sfl_internal in siginfos[int1].flags) then begin + num:= siginfos[int1].num; + numto:= num; + flags:= siginfos[int1].flags; + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +procedure freeoptions(); +begin +// projectoptions.o.free(); + projectoptions.e.free(); + projectoptions.d.free(); + projectoptions.k.free(); + projectoptions.m.free(); + projectoptions.a.free(); + projectoptions.u.free(); + projectoptions.f.free(); + projectoptions.t.free(); + projectoptions.r.free(); + projectoptions.p.free(); + projectoptions.s.free(); +end; + +procedure createoptions(); +begin +// projectoptions.o:= tprojectoptions.create(); + projectoptions.e:= teditoptions.create(); + projectoptions.d:= tdebugoptions.create(); + projectoptions.k:= tmakeoptions.create(); + projectoptions.m:= tmacrooptions.create(); + projectoptions.a:= tfontaliasoptions.create(); + projectoptions.u:= tusercoloroptions.create(); + projectoptions.f:= tformatmacrooptions.create(); + projectoptions.t:= ttoolsoptions.create(); + projectoptions.r:= tstorageoptions.create(); + projectoptions.p:= ttemplatesoptions.create(); + projectoptions.s:= tprojectstate.create(); +end; + +procedure initpr(const expand: boolean); +const + alloptionson = 1+2+4+8+16+32; + unitson = 1+2+4+8+16+32+$10000; + allon = unitson+$20000+$40000; +var + int1: integer; +begin + freeoptions(); + codetemplates.clear(); + finalize(projectoptions); + fillchar(projectoptions,sizeof(projectoptions),0); + createoptions(); + with projectoptions,k,t do begin + if expand then begin + deletememorystatstream(findinfiledialogstatname); + deletememorystatstream(finddialogstatname); + deletememorystatstream(replacedialogstatname); + deletememorystatstream(optionsstatname); + deletememorystatstream(settaborderstatname); + deletememorystatstream(setcreateorderstatname); + deletememorystatstream(programparametersstatname); + deletememorystatstream(printerstatname); + deletememorystatstream(imageselectorstatname); + deletememorystatstream(stringlisteditorstatname); + deletememorystatstream(texteditorstatname); + deletememorystatstream(colordialogstatname); + deletememorystatstream(compnamedialogstatname); + deletememorystatstream(bmpfiledialogstatname); + deletememorystatstream(fadeeditorstatname); + deletememorystatstream(codetemplateselectstatname); + deletememorystatstream(codetemplateparamstatname); + deletememorystatstream(codetemplateeditstatname); + deletememorystatstream(cornermaskeditstatname); + deletememorystatstream(memodialogstatname); + deletememorystatstream(richmemodialogstatname); + deletememorystatstream(fontformatdialogstatname); + deletememorystatstream(taborderoverridedialogstatname); + {$ifndef mse_no_db}{$ifdef FPC} + deletememorystatstream(dbfieldeditorstatname); + {$endif}{$endif} + {$ifndef mse_no_ifi}{$ifdef FPC} + deletememorystatstream(ificlienteditorstatname); + deletememorystatstream(ififieldeditorstatname); + {$endif}{$endif} + modified:= false; + savechecked:= false; + findreplaceinfo.find.options:= [so_caseinsensitive]; + targetconsolefindinfo.options:= [so_caseinsensitive]; + end; + sigsettings:= defaultsigsettings; + ignoreexceptionclasses:= nil; + + additem(fmakeoptions,'-l -Mobjfpc -Sh -Fcutf8'); + additem(fmakeoptions,'-gl -O-'); + additem(fmakeoptions,'-B'); + additem(fmakeoptions,'-O2 -XX -CX -Xs'); + setlength(fmakeoptionson,length(fmakeoptions)); + for int1:= 0 to high(fmakeoptionson) do begin + fmakeoptionson[int1]:= alloptionson; + end; + fmakeoptionson[1]:= alloptionson and not bits[5]; + //all but make 4 + fmakeoptionson[2]:= bits[1] or bits[5]; //build + make 4 + fmakeoptionson[3]:= bits[5]; //make 4 + defaultmake:= 1; //make + additem(funitdirs,'${MSELIBDIR}*/'); +// additem(funitdirs,'${MSELIBDIR}kernel/'); + additem(funitdirs,'${MSELIBDIR}kernel/$TARGETOSDIR/'); + setlength(funitdirson,length(unitdirs)); + for int1:= 0 to high(funitdirson) do begin + funitdirson[int1]:= unitson; + end; +// funitdirson[1]:= unitson + $20000; //kernel include + unitdirs:= reversearray(unitdirs); + unitdirson:= reversearray(unitdirson); + unitpref:= '-Fu'; + incpref:= '-Fi'; + libpref:= '-Fl'; + objpref:= '-Fo'; + targpref:= '-o'; + makecommand:= '${COMPILER}'; + with p,t do begin + setlength(fnewfinames,3); + setlength(fnewfifilters,3); + setlength(fnewfiexts,3); + setlength(fnewfisources,3); + + newfinames[0]:= actionsmo.c[ord(ac_program)]; + newfifilters[0]:= '"*.pas" "*.pp"'; + newfiexts[0]:= 'pas'; + newfisources[0]:= '${TEMPLATEDIR}default/program.pas'; + + newfinames[1]:= actionsmo.c[ord(ac_unit)]; + newfifilters[1]:= '"*.pas" "*.pp"'; + newfiexts[1]:= 'pas'; + newfisources[1]:= '${TEMPLATEDIR}default/unit.pas'; + + newfinames[2]:= actionsmo.c[ord(ac_textfile)]; + newfifilters[2]:= ''; + newfiexts[2]:= ''; + newfisources[2]:= ''; + + setlength(fnewfonames,12); + setlength(fnewfonamebases,12); + setlength(fnewfoformsuffixes,12); + setlength(p.fnewinheritedforms,12); + setlength(fnewfosources,12); + setlength(fnewfoforms,12); + + newfonames[0]:= actionsmo.c[ord(ac_mainform)]; + newfonamebases[0]:= 'form'; + newfoformsuffixes[0]:= 'fo'; + newinheritedforms[0]:= false; + newfosources[0]:= '${TEMPLATEDIR}default/mainform.pas'; + newfoforms[0]:= '${TEMPLATEDIR}default/mainform.mfm'; + + newfonames[1]:= actionsmo.c[ord(ac_simpleform)]; + newfonamebases[1]:= 'form'; + newfoformsuffixes[1]:= 'fo'; + newinheritedforms[1]:= false; + newfosources[1]:= '${TEMPLATEDIR}default/simpleform.pas'; + newfoforms[1]:= '${TEMPLATEDIR}default/simpleform.mfm'; + + newfonames[2]:= actionsmo.c[ord(ac_dockingform)]; + newfonamebases[2]:= 'form'; + newfoformsuffixes[2]:= 'fo'; + newinheritedforms[2]:= false; + newfosources[2]:= '${TEMPLATEDIR}default/dockingform.pas'; + newfoforms[2]:= '${TEMPLATEDIR}default/dockingform.mfm'; + + newfonames[3]:= actionsmo.c[ord(ac_sizingform)]; + newfonamebases[3]:= 'form'; + newfoformsuffixes[3]:= 'fo'; + newinheritedforms[3]:= false; + newfosources[3]:= '${TEMPLATEDIR}default/sizingform.pas'; + newfoforms[3]:= '${TEMPLATEDIR}default/sizingform.mfm'; + + newfonames[4]:= actionsmo.c[ord(ac_datamodule)]; + newfonamebases[4]:= 'module'; + newfoformsuffixes[4]:= 'mo'; + newinheritedforms[4]:= false; + newfosources[4]:= '${TEMPLATEDIR}default/datamodule.pas'; + newfoforms[4]:= '${TEMPLATEDIR}default/datamodule.mfm'; + + newfonames[5]:= actionsmo.c[ord(ac_subform)]; + newfonamebases[5]:= 'form'; + newfoformsuffixes[5]:= 'fo'; + newinheritedforms[5]:= false; + newfosources[5]:= '${TEMPLATEDIR}default/subform.pas'; + newfoforms[5]:= '${TEMPLATEDIR}default/subform.mfm'; + + newfonames[6]:= actionsmo.c[ord(ac_scrollboxform)]; + newfonamebases[6]:= 'form'; + newfoformsuffixes[6]:= 'fo'; + newinheritedforms[6]:= false; + newfosources[6]:= '${TEMPLATEDIR}default/scrollboxform.pas'; + newfoforms[6]:= '${TEMPLATEDIR}default/scrollboxform.mfm'; + + newfonames[7]:= actionsmo.c[ord(ac_tabform)]; + newfonamebases[7]:= 'form'; + newfoformsuffixes[7]:= 'fo'; + newinheritedforms[7]:= false; + newfosources[7]:= '${TEMPLATEDIR}default/tabform.pas'; + newfoforms[7]:= '${TEMPLATEDIR}default/tabform.mfm'; + + newfonames[8]:= actionsmo.c[ord(ac_dockpanel)]; + newfonamebases[8]:= 'form'; + newfoformsuffixes[8]:= 'fo'; + newinheritedforms[8]:= false; + newfosources[8]:= '${TEMPLATEDIR}default/dockpanelform.pas'; + newfoforms[8]:= '${TEMPLATEDIR}default/dockpanelform.mfm'; + + newfonames[9]:= actionsmo.c[ord(ac_report)]; + newfonamebases[9]:= 'report'; + newfoformsuffixes[9]:= 're'; + newinheritedforms[9]:= false; + newfosources[9]:= '${TEMPLATEDIR}default/report.pas'; + newfoforms[9]:= '${TEMPLATEDIR}default/report.mfm'; + + newfonames[10]:= actionsmo.c[ord(ac_scriptform)]; + newfonamebases[10]:= 'script'; + newfoformsuffixes[10]:= 'sc'; + newinheritedforms[10]:= false; + newfosources[10]:= '${TEMPLATEDIR}default/pascform.pas'; + newfoforms[10]:= '${TEMPLATEDIR}default/pascform.mfm'; + + newfonames[11]:= actionsmo.c[ord(ac_inheritedform)]; + newfonamebases[11]:= 'form'; + newfoformsuffixes[11]:= 'fo'; + newinheritedforms[11]:= true; + newfosources[11]:= '${TEMPLATEDIR}default/inheritedform.pas'; + newfoforms[11]:= '${TEMPLATEDIR}default/inheritedform.mfm'; + end; + + end; + with projectoptions,e,t do begin + + additem(fsourcefilemasks,'"*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc"'); + additem(fsyntaxdeffiles,'${SYNTAXDEFDIR}pascal.sdef'); + additem(fsourcefilemasks,'"*.c" "*.cc" "*.h"'); + additem(fsyntaxdeffiles,'${SYNTAXDEFDIR}cpp.sdef'); + additem(fsourcefilemasks,'"*.mfm"'); + additem(fsyntaxdeffiles,'${SYNTAXDEFDIR}objecttext.sdef'); + + additem(ffilemasknames,actionsmo.c[ord(ac_source)]); + additem(ffilemasks,'"*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr"'); + additem(ffilemasknames,actionsmo.c[ord(ac_forms)]); + additem(ffilemasks,'*.mfm'); + additem(ffilemasknames,actionsmo.c[ord(ac_allfiles)]); + additem(ffilemasks,'*'); + + end; + with projectoptions,d,t do begin + debugcommand:= '${DEBUGGER}'; + gdbprocessor:= 'auto'; + additem(fsourcedirs,'./'); + additem(fsourcedirs,'${MSELIBDIR}*/'); + additem(fsourcedirs,'${MSELIBDIR}kernel/$TARGETOSDIR/'); + sourcedirs:= reversearray(sourcedirs); + end; + if expand then begin + expandprojectmacros; + end; +end; + +procedure initprojectoptions; +begin + initpr(true); +end; + +procedure projectoptionsmodified; +begin + projectoptions.modified:= true; + projectoptions.savechecked:= false; +end; + +procedure setsignalinfocount(const count: integer); +begin + if count = 0 then begin + projectoptions.sigsettings:= defaultsigsettings; + end + else begin + setlength(projectoptions.sigsettings,count); + end; +end; + +procedure storesignalinforec(const index: integer; + const avalue: msestring); +var + stop,handle: boolean; +begin + with projectoptions.sigsettings[index] do begin + decoderecord(avalue,[@num,@numto,@stop,@handle],'iibb'); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(sfl_stop),stop); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(sfl_handle),handle); + end; +end; + +function getsignalinforec(const index: integer): msestring; +var + stop,handle: boolean; +begin + with projectoptions.sigsettings[index] do begin + stop:= sfl_stop in flags; + handle:= sfl_handle in flags; + result:= encoderecord([num,numto,stop,handle]); + end; +end; + +procedure updateprojectsettings(const statfiler: tstatfiler; + const disabledoptions: settinggroupsty); +var + int1: integer; + i2: int32; +begin + with statfiler,projectoptions,s,t do begin + + if iswriter then begin + mainfo.statoptions.writestat(tstatwriter(statfiler)); + end + else begin + mainfo.statoptions.readstat(tstatreader(statfiler)); + with projectoptions.t do begin + setlength(ftoolmessages,length(ftoolsave)); + end; + end; + if not (sg_debugger in disabledoptions) then begin + if iswriter then begin + with tstatwriter(statfiler) do begin + writerecordarray('sigsettings',length(sigsettings), + {$ifdef FPC}@{$endif}getsignalinforec); + end; + end + else begin + with tstatreader(statfiler) do begin + readrecordarray('sigsettings',{$ifdef FPC}@{$endif}setsignalinfocount, + {$ifdef FPC}@{$endif}storesignalinforec); + end; + end; + end; + if not (sg_state in disabledoptions) then begin + updatevalue('defaultmake',defaultmake,1,maxdefaultmake+1); + end; + with p,t do begin + if not iswriter then begin + int1:= length(newfinames); + if int1 > length(newfifilters) then begin + int1:= length(newfifilters); + end; + if int1 > length(newfiexts) then begin + int1:= length(newfiexts); + end; + if int1 > length(newfisources) then begin + int1:= length(newfisources); + end; + setlength(fnewfinames,int1); + setlength(fnewfifilters,int1); + setlength(fnewfiexts,int1); + setlength(fnewfisources,int1); + end; + + if not iswriter then begin + int1:= length(newfonames); + if int1 > length(newfonamebases) then begin + int1:= length(newfonamebases); + end; + if high(newfoformsuffixes) <> high(newfonamebases) then begin + //probably old statfile + setlength(fnewfoformsuffixes,length(newfonamebases)); + for i2:= 0 to high(fnewfoformsuffixes) do begin + fnewfoformsuffixes[i2]:= copy(fnewfonamebases[i2],1,2) + end; + end; + if int1 > length(newfoformsuffixes) then begin + int1:= length(newfoformsuffixes); + end; + if int1 > length(newinheritedforms) then begin + int1:= length(newinheritedforms); + end; + if int1 > length(newfosources) then begin + int1:= length(newfosources); + end; + if int1 > length(newfoforms) then begin + int1:= length(newfoforms); + end; + setlength(fnewfonames,int1); + setlength(fnewfonamebases,int1); + setlength(fnewfoformsuffixes,int1); + setlength(fnewinheritedforms,int1); + setlength(fnewfosources,int1); + setlength(fnewfoforms,int1); + end; + end; + end; +end; + +procedure doloadexe(const sender: tprojectoptionsfo); forward; +procedure dosaveexe(const sender: tprojectoptionsfo); forward; + +function getdisabledoptions: settinggroupsty; +begin + result:= [sg_state]; + with projectoptions do begin + if not r.settingseditor then begin + include(result,sg_editor); + end; + if not r.settingsdebugger then begin + include(result,sg_debugger); + end; + if not r.settingsmake then begin + include(result,sg_make); + end; + if not r.settingsmacros then begin + include(result,sg_macros); + end; + if not r.settingsfontalias then begin + include(result,sg_fontalias); + end; + if not r.settingsusercolors then begin + include(result,sg_usercolors); + end; + if not r.settingsformatmacros then begin + include(result,sg_formatmacros); + end; + if not r.settingstemplates then begin + include(result,sg_templates); + end; + if not r.settingstools then begin + include(result,sg_tools); + end; + if not r.settingsstorage then begin + include(result,sg_storage); + end; + end; +end; + +procedure updateprojectoptions(const statfiler: tstatfiler; + const afilename: filenamety); +var + int1,int2,int3: integer; + b1: boolean; + modulenames1: msestringarty; + moduletypes1: msestringarty; + + modulefiles1: filenamearty; +// moduledock1: msestringarty; +begin + with statfiler,projectoptions do begin + if iswriter then begin + projectdir:= getcurrentdirmse; + with mainfo,mainmenu1.menu.itembyname('view') do begin + int3:= formmenuitemstart; + int2:= count - int3; + setlength(modulenames1,int2); + setlength(moduletypes1,int2); + setlength(modulefiles1,int2); +// setlength(moduledock1,int2); + for int1:= 0 to high(modulenames1) do begin + with pmoduleinfoty(submenu[int1+int3].tagpo)^ do begin + modulenames1[int1]:= msestring(struppercase(instance.name)); + moduletypes1[int1]:= msestring(struppercase(string(moduleclassname))); + modulefiles1[int1]:= filename; + end; + end; + s.modulenames:= modulenames1; + s.moduletypes:= moduletypes1; + s.modulefiles:= modulefiles1; + end; + end; + registeredcomponents.updatestat(statfiler); + setsection('projectoptions'); + updatevalue('projectdir',projectdir); + updatevalue('projectfilename',projectfilename); + projectfilename:= afilename; + updatememorystatstream('findinfiledialog',findinfiledialogstatname); + updatememorystatstream('finddialog',finddialogstatname); + updatememorystatstream('replacedialog',replacedialogstatname); + updatememorystatstream('options',optionsstatname); + updatememorystatstream('settaborder',settaborderstatname); + updatememorystatstream('setcreateorder',setcreateorderstatname); + updatememorystatstream('programparameters',programparametersstatname); + updatememorystatstream('settings',settingsstatname); + updatememorystatstream('printer',printerstatname); + updatememorystatstream('imageselector',imageselectorstatname); + updatememorystatstream('fadeeditor',fadeeditorstatname); + updatememorystatstream('stringlisteditor',stringlisteditorstatname); + updatememorystatstream('imagelisteditor',imagelisteditorstatname); + updatememorystatstream('sysenvmanagereditor',sysenvmanagereditorstatname); + updatememorystatstream('texteditor',texteditorstatname); + updatememorystatstream('colordialog',colordialogstatname); + updatememorystatstream('compnamedialog',compnamedialogstatname); + updatememorystatstream('bmpfiledialog',bmpfiledialogstatname); + updatememorystatstream('codetemplateselect',codetemplateselectstatname); + updatememorystatstream('codetemplateparam',codetemplateparamstatname); + updatememorystatstream('codetemplateedit',codetemplateeditstatname); + updatememorystatstream('cornermaskedit',cornermaskeditstatname); + updatememorystatstream('memodialog',memodialogstatname); + updatememorystatstream('richmemodialog',richmemodialogstatname); + updatememorystatstream('fontformatdialog',fontformatdialogstatname); + updatememorystatstream('taborderoverridedialog', + taborderoverridedialogstatname); +{$ifndef mse_no_db}{$ifdef FPC} + updatememorystatstream('dbfieldeditor',dbfieldeditorstatname); +{$endif}{$endif} +{$ifndef mse_no_ifi}{$ifdef FPC} + updatememorystatstream('ificlienteditor',ificlienteditorstatname); + updatememorystatstream('ififieldeditor',ififieldeditorstatname); +{$endif}{$endif} + + updateprojectsettings(statfiler,[]); + b1:= projecttree.updatestat(statfiler) or statfiler.iswriter; + breakpointsfo.updatestat(statfiler); + panelform.updatestat(statfiler); //uses section breakpoints! + if not b1 then begin + projecttree.updatestat(statfiler); //backward compatibility with section + //breakpoints + end; + componentstorefo.updatestat(statfiler); + + setsection('components'); + selecteditpageform.updatestat(statfiler); + programparametersform.updatestat(statfiler); + projectoptionstofont(textpropertyfont); + + if not iswriter then begin + if guitemplatesmo.sysenv.getintegervalue(int1, + ord(env_vargroup),1,6) then begin + s.macrogroup:= int1-1; + end; + expandprojectmacros; + projecttree.updatelist; + end; + + beginpanelplacement(); + try + sourcefo.updatestat(statfiler); //needs actual fontalias + setsection('layout'); + mainfo.projectstatfile.updatestat('windowlayout',statfiler); + finally + endpanelplacement(); + end; + setsection('targetconsole'); + targetconsole.updatestat(statfiler); + + modified:= false; + savechecked:= false; + + if iswriter then begin + if r.settingsautosave then begin + dosaveexe(nil); + end; + end + else begin + if r.settingsautoload then begin + doloadexe(nil); + end; + end; + end; +end; + +procedure projectoptionstoform(fo: tprojectoptionsfo); +var + int1,int2: integer; +begin + fo.optafter.tag:= optaftermainfilemask; + with projectoptions do begin + int1:= length(t.toolshortcuts); + setlength(t.ftoolshortcuts,length(t.t.toolmenus)); + for int2:= int1 to high(t.toolshortcuts) do begin + t.toolshortcuts[int2]:= -1; //init for backward compatibility + end; + end; + {$ifdef mse_with_ifi} + mainfo.statoptions.objtovalues(fo); + {$endif} + fo.colgrid.rowcount:= usercolorcount; + fo.colgrid.fixcols[-1].captions.count:= usercolorcount; + with fo,projectoptions do begin + for int1:= 0 to colgrid.rowhigh do begin + colgrid.fixcols[-1].captions[int1]:= + msestring(colortostring(cl_user+longword(int1))); + end; + end; + with fo.signame do begin + setlength(enums,siginfocount); + int2:= 0; + for int1:= 0 to siginfocount - 1 do begin + with siginfos[int1] do begin + if not (sfl_internal in flags) then begin + enums[int2]:= num; + dropdownitems.addrow([msestring(name),msestring(comment)]); + dropdown.cols.addrow([msestring(comment)+ ' ('+msestring(name)+')']); + inc(int2); + end; + end; + end; + setlength(enums,int2); + end; + with projectoptions{,t} do begin + fo.signalgrid.rowcount:= length(sigsettings); + for int1:= 0 to high(sigsettings) do begin + with sigsettings[int1] do begin + fo.signum[int1]:= num; + fo.signumto[int1]:= numto; + if num = numto then begin + fo.signame[int1]:= num; + end + else begin + fo.signame[int1]:= -1; + end; + fo.sigstop[int1]:= sfl_stop in flags; + fo.sighandle[int1]:= sfl_handle in flags; + end; + end; + fo.fontondataentered(nil); + fo.defaultmake.value:= lowestbit(defaultmake); + for int1:= 0 to fo.makeoptionsgrid.rowhigh do begin + if int1 > high(k.makeoptionson) then begin + break; + end; + fo.makeon.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.buildon.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.make1on.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.make2on.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.make3on.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.make4on.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.optafter.gridupdatetagvalue(int1,k.makeoptionson[int1]); + end; + + for int1:= 0 to fo.befcommandgrid.rowhigh do begin + if int1 > high(k.befcommandon) then begin + break; + end; + fo.befmakeon.gridupdatetagvalue(int1,k.befcommandon[int1]); + fo.befbuildon.gridupdatetagvalue(int1,k.befcommandon[int1]); + fo.befmake1on.gridupdatetagvalue(int1,k.befcommandon[int1]); + fo.befmake2on.gridupdatetagvalue(int1,k.befcommandon[int1]); + fo.befmake3on.gridupdatetagvalue(int1,k.befcommandon[int1]); + fo.befmake4on.gridupdatetagvalue(int1,k.befcommandon[int1]); + end; + + for int1:= 0 to fo.aftcommandgrid.rowhigh do begin + if int1 > high(k.aftcommandon) then begin + break; + end; + fo.aftmakeon.gridupdatetagvalue(int1,k.aftcommandon[int1]); + fo.aftbuildon.gridupdatetagvalue(int1,k.aftcommandon[int1]); + fo.aftmake1on.gridupdatetagvalue(int1,k.aftcommandon[int1]); + fo.aftmake2on.gridupdatetagvalue(int1,k.aftcommandon[int1]); + fo.aftmake3on.gridupdatetagvalue(int1,k.aftcommandon[int1]); + fo.aftmake4on.gridupdatetagvalue(int1,k.aftcommandon[int1]); + end; + + fo.unitdirs.gridvalues:= reversearray(k.t.unitdirs); + int2:= high(k.t.unitdirs); + for int1:= 0 to int2 do begin + if int1 > high(k.unitdirson) then begin + break; + end; + fo.dmakeon.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dbuildon.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dmake1on.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dmake2on.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dmake3on.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dmake4on.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.duniton.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dincludeon.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dlibon.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dobjon.gridupdatetagvalue(int2,k.unitdirson[int1]); + dec(int2); + end; + fo.activemacroselect[s.macrogroup]:= true; + fo.activegroupchanged; + setlength(m.fgroupcomments,6); + fo.groupcomment.gridvalues:= m.groupcomments; + + for int1:= 0 to fo.macrogrid.rowhigh do begin + if int1 > high(m.macroon) then begin + break; + end; + fo.e0.gridupdatetagvalue(int1,m.macroon[int1]); + fo.e1.gridupdatetagvalue(int1,m.macroon[int1]); + fo.e2.gridupdatetagvalue(int1,m.macroon[int1]); + fo.e3.gridupdatetagvalue(int1,m.macroon[int1]); + fo.e4.gridupdatetagvalue(int1,m.macroon[int1]); + fo.e5.gridupdatetagvalue(int1,m.macroon[int1]); + end; + + fo.sourcedirs.gridvalues:= reversearray(d.t.sourcedirs); + fo.syntaxdeffile.gridvalues:= e.t.syntaxdeffiles; + fo.syntaxdeffilemask.gridvalues:= e.t.sourcefilemasks; +// fo.grid[0].datalist.asarray:= e.t.syntaxdeffiles; +// fo.grid[1].datalist.asarray:= e.t.sourcefilemasks; + fo.filefiltergrid[0].datalist.asarray:= e.t.filemasknames; + fo.filefiltergrid[1].datalist.asarray:= e.t.filemasks; + fo.settingsdataent(nil); + + end; +end; + +procedure storemacros(fo: tprojectoptionsfo); +var + int1: integer; +begin + with projectoptions,m do begin + macronames:= fo.macronames.gridvalues; + macrovalues:= fo.macrovalues.gridvalues; + setlength(fmacroon,fo.macrogrid.rowcount); + for int1:= 0 to high(macroon) do begin + macroon[int1]:= fo.e0.gridvaluetag(int1,0) or fo.e1.gridvaluetag(int1,0) or + fo.e2.gridvaluetag(int1,0) or fo.e3.gridvaluetag(int1,0) or + fo.e4.gridvaluetag(int1,0) or fo.e5.gridvaluetag(int1,0); + end; + groupcomments:= fo.groupcomment.gridvalues; + end; +end; + +procedure formtoprojectoptions(fo: tprojectoptionsfo); +var + int1: integer; +begin +{$ifdef mse_with_ifi} + mainfo.statoptions.valuestoobj(fo); +{$endif} + fo.optafter.tag:= optaftermainfilemask; + with projectoptions do begin + setlength(sigsettings,fo.signalgrid.rowcount); + for int1:= 0 to high(sigsettings) do begin + with sigsettings[int1] do begin + num:= fo.signum[int1]; + numto:= fo.signumto[int1]; + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(sfl_stop), + fo.sigstop[int1]); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(sfl_handle), + fo.sighandle[int1]); + end; + end; + + for int1:= high(a.fontxscales) downto 0 do begin + if a.fontxscales[int1] = emptyreal then begin + a.fontxscales[int1]:= 1.0; + end; + end; + + defaultmake:= 1 shl fo.defaultmake.value; + setlength(k.fmakeoptionson,fo.makeoptionsgrid.rowcount); + for int1:= 0 to high(k.fmakeoptionson) do begin + k.fmakeoptionson[int1]:= + fo.makeon.gridvaluetag(int1,0) or fo.buildon.gridvaluetag(int1,0) or + fo.make1on.gridvaluetag(int1,0) or fo.make2on.gridvaluetag(int1,0) or + fo.make3on.gridvaluetag(int1,0) or fo.make4on.gridvaluetag(int1,0) or + fo.optafter.gridvaluetag(int1,0); + end; + + setlength(k.fbefcommandon,fo.befcommandgrid.rowcount); + for int1:= 0 to high(k.fbefcommandon) do begin + k.fbefcommandon[int1]:= + fo.befmakeon.gridvaluetag(int1,0) or fo.befbuildon.gridvaluetag(int1,0) or + fo.befmake1on.gridvaluetag(int1,0) or fo.befmake2on.gridvaluetag(int1,0) or + fo.befmake3on.gridvaluetag(int1,0) or fo.befmake4on.gridvaluetag(int1,0); + end; + setlength(k.faftcommandon,fo.aftcommandgrid.rowcount); + for int1:= 0 to high(k.faftcommandon) do begin + k.faftcommandon[int1]:= + fo.aftmakeon.gridvaluetag(int1,0) or fo.aftbuildon.gridvaluetag(int1,0) or + fo.aftmake1on.gridvaluetag(int1,0) or fo.aftmake2on.gridvaluetag(int1,0) or + fo.aftmake3on.gridvaluetag(int1,0) or fo.aftmake4on.gridvaluetag(int1,0); + end; + + k.t.unitdirs:= reversearray(fo.unitdirs.gridvalues); + setlength(k.funitdirson,length(k.t.unitdirs)); + for int1:= 0 to high(k.funitdirson) do begin + k.funitdirson[high(k.funitdirson)-int1]:= + fo.dmakeon.gridvaluetag(int1,0) or fo.dbuildon.gridvaluetag(int1,0) or + fo.dmake1on.gridvaluetag(int1,0) or fo.dmake2on.gridvaluetag(int1,0) or + fo.dmake3on.gridvaluetag(int1,0) or fo.dmake4on.gridvaluetag(int1,0) or + fo.duniton.gridvaluetag(int1,0) or fo.dincludeon.gridvaluetag(int1,0) or + fo.dlibon.gridvaluetag(int1,0) or fo.dobjon.gridvaluetag(int1,0); + end; + storemacros(fo); + d.t.sourcedirs:= reversearray(fo.sourcedirs.gridvalues); + e.t.syntaxdeffiles:= fo.syntaxdeffile.gridvalues; + e.t.sourcefilemasks:= fo.syntaxdeffilemask.gridvalues; +// e.t.syntaxdeffiles:= fo.grid[0].datalist.asarray; +// e.t.sourcefilemasks:= fo.grid[1].datalist.asarray; + e.t.filemasknames:= fo.filefiltergrid[0].datalist.asarray; + e.t.filemasks:= fo.filefiltergrid[1].datalist.asarray; + end; + expandprojectmacros; +end; + +procedure projectoptionschanged; +var + int1: integer; +begin + projecttree.updatelist; + createcpufo; + mainfo.gdb.fpcworkaround:= projectoptions.d.fpcgdbworkaround; + sourceupdater.unitchanged; + for int1:= 0 to designer.modules.count - 1 do begin + tformdesignerfo(designer.modules[int1]^.designform).updateprojectoptions(); + end; + messagefo.updateprojectoptions; +end; + +function readprojectoptions(const filename: filenamety): boolean; +var + statreader: tstatreader; +begin + result:= false; + try + statreader:= tstatreader.create(filename,ce_utf8); + try + application.beginwait; + updateprojectoptions(statreader,filename); + finally + statreader.free; + application.endwait; + projectoptionschanged; + end; + result:= true; + except + on e: exception do begin + showerror(actionsmo.c[ord(ac_cannotreadproject)]+' "'+filename+'".'+ + lineend+msestring(e.message),actionsmo.c[ord(ac_error)]); + end; + end; +end; + +procedure saveprojectoptions(filename: filenamety = ''); +var + statwriter: tstatwriter; +begin + if filename = '' then begin + filename:= projectoptions.projectfilename; + end; + statwriter:= tstatwriter.create(filename,ce_utf8,true); + try + updateprojectoptions(statwriter,filename); + finally + statwriter.free; + end; +end; + +function editprojectoptions: boolean; +var + fo: tprojectoptionsfo; +begin + fo:= tprojectoptionsfo.create(nil); + projectoptionstoform(fo); + try + projectoptionsfo:= fo; + result:= fo.show(true,nil) = mr_ok; + projectoptionsfo:= nil; + if result then begin + with mainfo.gdb do begin + if not started then begin + closegdb; + end; + end; + fo.window.nofocus; //remove empty grid lines + formtoprojectoptions(fo); + projectoptionsmodified; + projectoptionschanged; + end; + finally + projectoptionsfo:= nil; + fo.Free; + end; +end; + +procedure tprojectoptionsfo.activegroupchanged; +var + int1,int2: integer; +begin + int2:= 0; + for int1:= 0 to selectactivegroupgrid.rowcount-1 do begin + if activemacroselect[int1] then begin + int2:= int1; + break; + end; + end; + for int1:= 0 to 5 do begin + if int1 = int2 then begin + macrogrid.datacols[int1].color:= cl_infobackground; + end + else begin + macrogrid.datacols[int1].color:= cl_default; + end; + end; + projectoptions.s.macrogroup:= int2; +end; + +procedure tprojectoptionsfo.acttiveselectondataentered(const sender: TObject); +var + int1: integer; +begin + for int1:= 0 to selectactivegroupgrid.rowcount-1 do begin + activemacroselect[int1]:= false; + end; + tbooleaneditradio(sender).value:= true; + activegroupchanged; + projectoptions.s.macrogroup:= selectactivegroupgrid.row; +end; + +procedure tprojectoptionsfo.colonshowhint(const sender: tdatacol; + const arow: Integer; var info: hintinfoty); +begin + storemacros(self); + if sender is twidgetcol then begin + info.caption:= tcustomstringedit(twidgetcol(sender).editwidget).gridvalue[arow]; + end + else begin + info.caption:= tstringcol(sender)[arow]; + end; + expandprmacros1(info.caption); + include(info.flags,hfl_show); //show empty caption +end; + +procedure tprojectoptionsfo.hintexpandedmacros(const sender: TObject; + var info: hintinfoty); +begin + storemacros(self); + hintmacros(tcustomedit(sender),info); +end; + +procedure tprojectoptionsfo.selectactiveonrowsmoved(const sender: tcustomgrid; + const fromindex: Integer; const toindex: Integer; const acount: Integer); +var + ar1: array of longboolarty; + int1: integer; +begin + setlength(ar1,selectactivegroupgrid.rowcount); + with macrogrid do begin + beginupdate; + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tbooleanedit(datacols[int1].editwidget).gridvalues; + end; + moveitem(pointerarty(ar1),fromindex,toindex); + for int1:= 0 to high(ar1) do begin + tbooleanedit(datacols[int1].editwidget).gridvalues:= ar1[int1]; + end; + endupdate; + end; + activegroupchanged; +end; + +procedure tprojectoptionsfo.expandfilename(const sender: TObject; + var avalue: mseString; var accept: Boolean); +begin + expandprmacros1(avalue); +end; + +procedure tprojectoptionsfo.showcommandlineonexecute(const sender: TObject); +var + info1: projectoptionsty; +begin + info1:= projectoptions; + formtoprojectoptions(self); + commandlineform.showcommandline; + projectoptions:= info1; +end; + +procedure tprojectoptionsfo.signameonsetvalue(const sender: TObject; var avalue: LongInt; var accept: Boolean); +begin + signum.value:= avalue; + signumto.value:= avalue; +end; + +procedure tprojectoptionsfo.signumonsetvalue(const sender: TObject; var avalue: LongInt; var accept: Boolean); +begin + signame.value:= avalue; + signumto.value:= avalue; +end; + +procedure tprojectoptionsfo.signumtoonsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); +begin + if avalue <= signum.value then begin + signum.value:= avalue; + signame.value:= avalue; + end + else begin + signame.value:= -1; + end; +end; + +procedure tprojectoptionsfo.fontondataentered(const sender: TObject); +const + teststring = 'ABCDEFGabcdefgy0123WWWiii '; +var + format1: formatinfoarty; +begin + with fontdisp.font do begin + name:= ansistring(editfontname.value); + height:= editfontheight.value; + width:= editfontwidth.value; + extraspace:= editfontextraspace.value; + color:= editfontcolor.value; + dispgrid.frame.colorclient:= editbkcolor.value; + if editfontantialiased.value then begin + options:= options + [foo_antialiased2]; + end + else begin + options:= options + [foo_nonantialiased]; + end; + dispgrid.datarowheight:= lineheight; + fontdisp[0]:= teststring+teststring+teststring+teststring; + format1:= nil; + updatefontstyle1(format1,length(teststring),length(teststring),fs_bold,true); + updatefontstyle1(format1,2*length(teststring),2*length(teststring),fs_italic,true); + updatefontstyle1(format1,3*length(teststring),length(teststring),fs_bold,true); + fontdisp.richformats[0]:= format1; + fontdisp[1]:= + 'Ascent: '+inttostrmse(ascent)+' Descent: '+inttostrmse(descent)+ + ' Linespacing: '+inttostrmse(lineheight); + end; + dispgrid.rowcolorstate[1]:= 0; + dispgrid.rowcolors[0]:= statementcolor.value; +end; + +procedure tprojectoptionsfo.makepageonchildscaled(const sender: TObject); +var + int1: integer; +begin + placeyorder(0,[0,0,0,15],[mainfile,makecommand,colorerror, + defaultmake,makegroupbox],0); + aligny(wam_center,[mainfile,targetfile,targpref]); + aligny(wam_center,[makecommand,makedir,messageoutputfile]); + int1:= aligny(wam_center,[colorerror,colorwarning,colornote,stripmessageesc]); + with copymessages do begin + bounds_y:= int1 - bounds_cy - 2; + end; + with stripmessageesc do begin + pos:= makepoint(copymessages.bounds_x,int1); + end; + + placexorder(defaultmake.bounds_x,[10-defaultmake.frame.outerframe.right,10], + [defaultmake,showcommandline,checkmethods]); + int1:= aligny(wam_center,[defaultmake,showcommandline]); + with checkmethods do begin + bounds_y:= int1 - bounds_cy - 2; + end; + with closemessages do begin + pos:= makepoint(checkmethods.bounds_x,int1); + end; +end; + +procedure tprojectoptionsfo.debuggerlayoutexe(const sender: TObject); +begin +//{$ifdef mswindows} + placeyorder(2,[0,0,10],[runcommand,debugcommand,debugtarget,tlayouter1]); +//{$else} +// placeyorder(0,[0,0,2],[debugcommand,debugoptions,debugtarget,tlayouter1]); +//{$endif} + aligny(wam_center,[debugcommand,debugoptions]); + aligny(wam_center,[debugtarget,xtermcommand]); +end; + +procedure tprojectoptionsfo.macronchildscaled(const sender: TObject); +var + int1: integer; +begin + int1:= macrosplitter.bounds_y; + placeyorder(0,[0],[selectactivegroupgrid,macrosplitter,macrogrid],0); + macrosplitter.move(makepoint(0,int1-macrosplitter.bounds_y)); +end; + + +procedure tprojectoptionsfo.formtemplateonchildscaled(const sender: TObject); +begin +{ + placeyorder(0,[0],[mainfosource,mainfoform,simplefosource,simplefoform, + dockingfosource,dockingfoform,datamodsource,datamodform, + subfosource,subfoform,reportsource,reportform, + inheritedsource,inheritedform]); +} +end; + +procedure tprojectoptionsfo.encodingsetvalue(const sender: TObject; + var avalue: LongInt; var accept: Boolean); +var + mstr1: msestring; +begin + mstr1:= encoding.dropdown.valuelist[avalue]; + accept:= askyesno(c[ord(wrongencoding)]+lineend+ + c[ord(wishsetencoding)]+' '+mstr1+'?',c[ord(warning)]); +end; + +procedure tprojectoptionsfo.createexe(const sender: TObject); +var + int1: integer; +begin + {$ifdef mswindows} +// externalconsole.visible:= true; + {$else} + settty.visible:= true; +// xtermoptions.visible:= true; + {$endif} + for int1:= ord(firstsiginfocomment) to ord(lastsiginfocomment) do begin + siginfos[int1-ord(firstsiginfocomment)].comment:= ansistring(c[int1]); + end; +end; + +procedure tprojectoptionsfo.drawcol(const sender: tpointeredit; + const acanvas: tcanvas; const avalue: Pointer; + const arow: Integer); +begin + with pcellinfoty(acanvas.drawinfopo)^ do begin + acanvas.fillrect(innerrect,usercolors[arow]); + end; +end; + +procedure tprojectoptionsfo.colsetvalue(const sender: TObject; + var avalue: colorty; var accept: Boolean); +begin + colgrid.invalidaterow(colgrid.row); +end; + +procedure tprojectoptionsfo.copycolorcode(const sender: TObject); +var + str1: msestring; + int1: integer; +begin + str1:= ''; + for int1:= 0 to colgrid.rowhigh do begin + if usercolors[int1] <> 0 then begin + str1:= str1 + ' setcolormapvalue('+ + msestring(colortostring(cl_user+longword(int1)))+','+ + msestring(colortostring(usercolors[int1]))+');'; + if usercolorcomment[int1] <> '' then begin + str1:= str1 + ' //'+usercolorcomment[int1]; + end; + str1:= str1+lineend; + end; + end; + copytoclipboard(str1); +end; + +procedure tprojectoptionsfo.downloadchange(const sender: TObject); +begin + uploadcommand.enabled:= not gdbdownload.value and not gdbsimulator.value; + beforeload.enabled:= gdbdownload.value and not gdbsimulator.value; + afterload.enabled:= gdbdownload.value and not gdbsimulator.value; + gdbservercommand.enabled:= not gdbsimulator.value; + gdbservercommandattach.enabled:= not gdbsimulator.value; + gdbserverwait.enabled:= not gdbsimulator.value; + nogdbserverexit.enabled:= gdbserverwait.enabled; + gdbservertty.enabled:= not gdbsimulator.value; + remoteconnection.enabled:= not gdbsimulator.value; + gdbdownload.enabled:= not gdbsimulator.value; + downloadalways.enabled:= not gdbsimulator.value; + startupbkpt.enabled:= startupbkpton.value; +end; + +procedure tprojectoptionsfo.processorchange(const sender: TObject); +begin + mainfo.gdb.processorname:= ansistring(gdbprocessor.value); + if not (mainfo.gdb.processor in simulatorprocessors) then begin + gdbsimulator.value:= false; + gdbsimulator.enabled:= false; + end + else begin + gdbsimulator.enabled:= true; + end; +end; + +procedure tprojectoptionsfo.copymessagechanged(const sender: TObject); +begin + messageoutputfile.enabled:= copymessages.value; +end; + +procedure tprojectoptionsfo.updatedebugenabled(const sender: TObject); +var + bo1: boolean; +begin + bo1:= runcommand.value = ''; + debugcommand.enabled:= bo1; + debugoptions.enabled:= bo1; + debugtarget.enabled:= bo1; +{$ifndef mswindows} + xtermcommand.enabled:= bo1 and externalconsole.value; +{$endif} + activateonbreak.enabled:= bo1; + raiseonbreak.enabled:= bo1; + nodebugbeginend.enabled:= bo1; + stoponexception.enabled:= bo1; + stoponexception.enabled:= bo1; + showconsole.enabled:= not externalconsole.value; + settty.enabled:= bo1; +end; + +procedure tprojectoptionsfo.newprojectchildscaled(const sender: TObject); +begin + placeyorder(4,[4,4],[scriptbeforecopy,scriptaftercopy,copygrid],0); +end; + +type + valuebufferty = record + settingsfile: filenamety; + settingseditor: boolean; + settingsdebugger: boolean; + settingsmake: boolean; + settingsmacros: boolean; + settingsfontalias: boolean; + settingsusercolors: boolean; + settingsformatmacros: boolean; + settingstemplates: boolean; + settingstools: boolean; + settingsstorage: boolean; + settingscomponentstore: boolean; + settingsprojecttree: boolean; + settingslayout: boolean; +// settingsautoload: boolean; +// settingsautosave: boolean; + projectfilename: filenamety; + projectdir: filenamety; + end; + +procedure savesettingsvalues(fo: tprojectoptionsfo; out buffer: valuebufferty); +begin + with buffer do begin + projectfilename:= projectoptions.projectfilename; + projectdir:= projectoptions.projectdir; + if fo <> nil then begin + settingsfile:= fo.settingsfile.value; + settingseditor:= fo.settingseditor.value; + settingsdebugger:= fo.settingsdebugger.value; + settingsmake:= fo.settingsmake.value; + settingsmacros:= fo.settingsmacros.value; + settingsfontalias:= fo.settingsfontalias.value; + settingsusercolors:= fo.settingsusercolors.value; + settingsformatmacros:= fo.settingsformatmacros.value; + settingstemplates:= fo.settingstemplates.value; + settingstools:= fo.settingstools.value; + settingsstorage:= fo.settingsstorage.value; + settingscomponentstore:= fo.settingscomponentstore.value; + settingsprojecttree:= fo.settingsprojecttree.value; + settingslayout:= fo.settingslayout.value; +// settingsautoload:= fo.settingsautoload.value; +// settingsautosave:= fo.settingsautosave.value; + end + else begin + settingsfile:= projectoptions.r.settingsfile; + settingseditor:= projectoptions.r.settingseditor; + settingsdebugger:= projectoptions.r.settingsdebugger; + settingsmake:= projectoptions.r.settingsmake; + settingsmacros:= projectoptions.r.settingsmacros; + settingsfontalias:= projectoptions.r.settingsfontalias; + settingsusercolors:= projectoptions.r.settingsusercolors; + settingsformatmacros:= projectoptions.r.settingsformatmacros; + settingstemplates:= projectoptions.r.settingstemplates; + settingstools:= projectoptions.r.settingstools; + settingsstorage:= projectoptions.r.settingsstorage; + settingscomponentstore:= projectoptions.r.settingscomponentstore; + settingsprojecttree:= projectoptions.r.settingsprojecttree; + settingslayout:= projectoptions.r.settingslayout; +// settingsautoload:= projectoptions.r.settingsautoload; +// settingsautosave:= projectoptions.r.settingsautosave; + end; + end; +end; + +procedure restoresettingsvalues(fo: tprojectoptionsfo; + const buffer: valuebufferty); +begin + with buffer do begin + projectoptions.projectfilename:= projectfilename; + projectoptions.projectdir:= projectdir; + if fo <> nil then begin + if not settingsstorage then begin + fo.settingsfile.value:= settingsfile; + fo.settingseditor.value:= settingseditor; + fo.settingsdebugger.value:= settingsdebugger; + fo.settingsmake.value:= settingsmake; + fo.settingsmacros.value:= settingsmacros; + fo.settingsfontalias.value:= settingsfontalias; + fo.settingsusercolors.value:= settingsusercolors; + fo.settingsformatmacros.value:= settingsformatmacros; + fo.settingstemplates.value:= settingstemplates; + fo.settingstools.value:= settingstools; + fo.settingsstorage.value:= settingsstorage; + fo.settingscomponentstore.value:= settingscomponentstore; + fo.settingsprojecttree.value:= settingsprojecttree; + fo.settingslayout.value:= settingslayout; +// fo.settingsautoload.value:= settingsautoload; +// fo.settingsautosave.value:= settingsautosave; + end; + fo.fontondataentered(nil); + fo.settingsdataent(nil); + end + else begin + if not settingsstorage then begin + projectoptions.r.settingsfile:= settingsfile; + projectoptions.r.settingseditor:= settingseditor; + projectoptions.r.settingsdebugger:= settingsdebugger; + projectoptions.r.settingsmake:= settingsmake; + projectoptions.r.settingsmacros:= settingsmacros; + projectoptions.r.settingsfontalias:= settingsfontalias; + projectoptions.r.settingsusercolors:= settingsusercolors; + projectoptions.r.settingsformatmacros:= settingsformatmacros; + projectoptions.r.settingstemplates:= settingstemplates; + projectoptions.r.settingstools:= settingstools; + projectoptions.r.settingsstorage:= settingsstorage; + projectoptions.r.settingscomponentstore:= settingscomponentstore; + projectoptions.r.settingsprojecttree:= settingsprojecttree; + projectoptions.r.settingslayout:= settingslayout; +// projectoptions.r.settingsautoload:= settingsautoload; +// projectoptions.r.settingsautosave:= settingsautosave; + end; + end; + end; +end; + +procedure savestat(out astream: ttextstream); +var + write1: tstatwriter; +begin + astream:= ttextstream.create; //memory stream + write1:= tstatwriter.create(astream,ce_utf8); + try + write1.setsection('projectoptions'); + updateprojectsettings(write1,[]); //save projectoptions state + finally + write1.free; + end; +end; + +procedure restorestat(var astream: ttextstream); +var + read1: tstatreader; +begin + astream.position:= 0; + read1:= tstatreader.create(astream,ce_utf8); + try + read1.setsection('projectoptions'); + updateprojectsettings(read1,[]); //restore projectoptions state + finally + read1.free; + astream.free; + end; +end; + +procedure doloadexe(const sender: tprojectoptionsfo); +var + read1: tstatreader; + buffer: valuebufferty; + stream1: ttextstream; + fname1: filenamety; +begin + if (sender <> nil) then begin + storemacros(sender); + fname1:= sender.settingsfile.value; + expandprmacros1(fname1); + if not askyesno(actionsmo.c[ord(ac_replacesettings)]+lineend+ + '"'+fname1+'"?', + actionsmo.c[ord(ac_warning)]) then begin + exit; + end; + end + else begin + fname1:= projectoptions.r.settingsfile; + expandprmacros1(fname1); + end; + if fname1 <> '' then begin + savesettingsvalues(sender,buffer); + savestat(stream1); + if sender <> nil then begin //manual + formtoprojectoptions(sender); + end; + projectoptions.disabled:= getdisabledoptions; + try + read1:= tstatreader.create(fname1,ce_utf8); + try + if projectoptions.r.settingscomponentstore then begin + componentstorefo.updatestat(read1); + end; + if projectoptions.r.settingslayout then begin + mainfo.loadwindowlayout(read1); + end; + read1.setsection('projectoptions'); + if projectoptions.r.settingsprojecttree then begin + projecttree.updatestat(read1); + projecttree.updatelist; + end; + updateprojectsettings(read1,[]); + finally + read1.free; + end; + if sender <> nil then begin + projectoptionstoform(sender); + end; + restoresettingsvalues(sender,buffer); + except + application.handleexception; + end; + projectoptions.disabled:= []; + if sender <> nil then begin //manual + restorestat(stream1); + end + else begin + stream1.free; + expandprojectmacros; + end; + end; +end; + +procedure tprojectoptionsfo.loadexe(const sender: TObject); +begin + doloadexe(self); +end; + +procedure dosaveexe(const sender: tprojectoptionsfo); +var + stat1: tstatwriter; + stream1: ttextstream; + fname1: filenamety; +begin + if sender <> nil then begin //manual save + storemacros(sender); + fname1:= sender.settingsfile.value; + expandprmacros1(fname1); + if findfile(fname1) and not askyesno(actionsmo.c[ord(ac_file)]+fname1+ + actionsmo.c[ord(ac_exists)]+lineend+ + actionsmo.c[ord(ac_wantoverwrite)],actionsmo.c[ord(ac_warning)]) then begin + exit; + end; + end + else begin + fname1:= projectoptions.r.settingsfile; + expandprmacros1(fname1); + end; + if fname1 <> '' then begin + stat1:= tstatwriter.create(fname1,ce_utf8,true); + with projectoptions do begin + try + savestat(stream1); + if sender <> nil then begin + formtoprojectoptions(sender); + end; + disabled:= getdisabledoptions; + if r.settingscomponentstore then begin + componentstorefo.updatestat(stat1); + end; + if r.settingslayout then begin + mainfo.savewindowlayout(stat1); + end; + stat1.setsection('projectoptions'); + if r.settingsprojecttree then begin + projecttree.updatestat(stat1); + end; + if not r.settingsstorage then begin + r.settingsfile:= ''; + r.settingseditor:= false; + r.settingsdebugger:= false; + r.settingsmake:= false; + r.settingsmacros:= false; + r.settingsfontalias:= false; + r.settingsusercolors:= false; + r.settingsformatmacros:= false; + r.settingstemplates:= false; + r.settingstools:= false; + r.settingsstorage:= false; + r.settingscomponentstore:= false; + r.settingsprojecttree:= false; + r.settingslayout:= false; +// r.settingsautoload:= false; +// r.settingsautosave:= false; + end; + updateprojectsettings(stat1,disabled); + finally + disabled:= []; + stat1.free; + restorestat(stream1); + end; + end; + end; +end; + +procedure tprojectoptionsfo.saveexe(const sender: TObject); +begin + dosaveexe(self); +end; + +procedure tprojectoptionsfo.settingsdataent(const sender: TObject); +var + bo1: boolean; +begin + bo1:= settingsfile.value <> ''; + savebu.enabled:= bo1; + loadbu.enabled:= bo1; +end; +(* +procedure tprojectoptionsfo.extconschangeexe(const sender: TObject); +begin +{$ifndef mswindows} + xtermcommand.enabled:= externalconsole.value; +{$endif} +end; +*) +procedure tprojectoptionsfo.setxtermcommandexe(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + if avalue = '' then begin + avalue:= defaultxtermcommand; + end; +end; + +procedure tprojectoptionsfo.activateonbreakset(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + raiseonbreak.enabled:= avalue; +end; + +procedure tprojectoptionsfo.sourcedirhint(const sender: TObject; + var info: hintinfoty); +begin + if tcustomedit(sender).text = '' then begin + hintexpandedmacros(makedir,info); + end + else begin + hintexpandedmacros(sender,info); + end; +end; + +procedure tprojectoptionsfo.toolshortcutdropdown(const sender: TObject); +var + i1: int32; + act1: taction; +begin + with toolshortcuts.dropdown do begin + for i1:= 0 to valuelist.count-1 do begin + if actionsmo.gettoolshortcutaction(i1,act1) then begin + with act1 do begin + cols[1][i1]:= encodeshortcutname(shortcuts); + cols[2][i1]:= encodeshortcutname(shortcuts1); + end; + end; + end; + end; +end; + +procedure tprojectoptionsfo.toolsrowdatachanged(const sender: tcustomgrid; + const acell: gridcoordty); +var + act1: taction; +begin + if actionsmo.gettoolshortcutaction(toolshortcuts[acell.row],act1) then begin + with act1 do begin + toolsc[acell.row]:= encodeshortcutname(shortcuts); + toolscalt[acell.row]:= encodeshortcutname(shortcuts1); + end; + end; +end; + +procedure tprojectoptionsfo.colorhint(const sender: TObject; + var info: hintinfoty); +begin + info.caption:= tcustomedit(sender).text + lineend + info.caption; +end; + +procedure tprojectoptionsfo.initeolstyleexe(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(eolstylety); +end; + +procedure tprojectoptionsfo.debugtargetlayoutev(const sender: TObject); +begin + serverla.width:= serverla.width + uploadcommand.width-gdbservercommand.width; +end; +(* +{ tprojectoptions } + +constructor tprojectoptions.create; +begin + ft:= ttextprojectoptions.create; + ftexp:= ttextprojectoptions.create; + inherited; +end; + +function tprojectoptions.gett: tobject; +begin + result:= ft; +end; + +function tprojectoptions.gettexp: tobject; +begin + result:= ftexp; +end; +*) +{ teditoptions } + +constructor teditoptions.create; +var + ar1: msestringarty; +begin + ft:= ttexteditoptions.create; + ftexp:= ttexteditoptions.create; + + showgrid:= true; + snaptogrid:= true; + moveonfirstclick:= true; + componenthints:= true; + gridsizex:= defaultgridsizex; + gridsizey:= defaultgridsizey; + encoding:= 1; //utf8n + eolstyle:= 1; //eol_system + autoindent:= true; + blockindent:= 1; + rightmarginon:= true; + rightmarginchars:= 80; + tabstops:= 4; + editfontname:= 'mseide_source'; + editfontcolor:= integer(cl_text); + editbkcolor:= integer(cl_foreground); + statementcolor:= $E0FFFF; +// pairmarkcolor:= int32(cl_ltyellow); + pairmarkcolor:= int32(cl_none); + pairmaxrowcount:= 100; + editfontantialiased:= true; + editmarkbrackets:= true; +// editmarkpairwords:= true; + backupfilecount:= 2; + setlength(ar1,1); + ar1[0]:= '${TEMPLATEDIR}'; + ft.codetemplatedirs:= ar1; + inherited; +end; + +function teditoptions.limitgridsize(const avalue: integer): integer; +begin + result:= avalue; + if result < 1 then begin + result:= 1; + end; + if result > 1000 then begin + result:= 1000; + end; +end; + +procedure teditoptions.setgridsizex(const avalue: integer); +begin + fgridsizex:= limitgridsize(avalue); +end; + +procedure teditoptions.setgridsizey(const avalue: integer); +begin + fgridsizey:= limitgridsize(avalue); +end; +{ +function teditoptions.getcodetemplatedirs: msestringarty; +begin + result:= projectoptions.k.t.codetemplatedirs; +end; + +procedure teditoptions.setcodetemplatedirs(const avalue: msestringarty); +begin + projectoptions.k.t.codetemplatedirs:= avalue; +end; +} +function teditoptions.gett: tobject; +begin + result:= ft; +end; + +function teditoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ tdebugoptions } + +constructor tdebugoptions.create; +begin + ft:= ttextdebugoptions.create; + ftexp:= ttextdebugoptions.create; + + valuehints:= true; + activateonbreak:= true; + raiseonbreak:= true; + settty:= true; + additem(fexceptclassnames,'EconvertError'); + additem(fexceptignore,false); + fgdbloadtimeout:= emptyreal; + fpcgdbworkaround:= true; + inherited; +end; + +function tdebugoptions.gett: tobject; +begin + result:= ft; +end; + +function tdebugoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ ttextdebugoptions } + +constructor ttextdebugoptions.create; +begin + fxtermcommand:= defaultxtermcommand; +end; + +{ tmakeoptions } + +constructor tmakeoptions.create; +begin + ft:= ttextmakeoptions.create; + ftexp:= ttextmakeoptions.create; + inherited; +end; + +function tmakeoptions.gett: tobject; +begin + result:= ft; +end; + +function tmakeoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ ttoolsoptions } + +constructor ttoolsoptions.create; +begin + ft:= ttexttoolsoptions.create(); + ftexp:= ttexttoolsoptions.create(); + inherited; +end; + +function ttoolsoptions.gett: tobject; +begin + result:= ft; +end; + +function ttoolsoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ ttemplatesoptions } + +constructor ttemplatesoptions.create; +begin + ft:= ttexttemplatesoptions.create(); + ftexp:= ttexttemplatesoptions.create(); + inherited; +end; + +function ttemplatesoptions.gett: tobject; +begin + result:= ft; +end; + +function ttemplatesoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ tprojectstate } + +constructor tprojectstate.create(); +begin + ft:= ttextprojectstate.create(); + ftexp:= ttextprojectstate.create(); + closemessages:= true; + checkmethods:= true; + fcolorerror:= cl_ltyellow; + fcolorwarning:= cl_ltred; + fcolornote:= cl_ltgreen; + inherited; +end; + +procedure tprojectstate.setforcezorder(const avalue: longbool); +begin + fforcezorder:= avalue; + application.forcezorder:= avalue; +end; + +function tprojectstate.gett: tobject; +begin + result:= ft; +end; + +function tprojectstate.gettexp: tobject; +begin + result:= ftexp; +end; + +{ tfontaliasoptions } + +constructor tfontaliasoptions.create(); +begin + ft:= ttextfontaliasoptions.create(); + ftexp:= ttextfontaliasoptions.create(); + inherited; +end; + +function tfontaliasoptions.gett: tobject; +begin + result:= ft; +end; + +function tfontaliasoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ tusercoloroptions } + +constructor tusercoloroptions.create(); +begin + ft:= ttextusercoloroptions.create(); + ftexp:= ttextusercoloroptions.create(); + inherited; +end; + +function tusercoloroptions.gett: tobject; +begin + result:= ft; +end; + +function tusercoloroptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ tformatmacrooptions } + +constructor tformatmacrooptions.create(); +begin + ft:= ttextformatmacrooptions.create(); + ftexp:= ttextformatmacrooptions.create(); + inherited; +end; + +function tformatmacrooptions.gett: tobject; +begin + result:= ft; +end; + +function tformatmacrooptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ ttextfontaliasoptions } + +{ tstorageoptions } + +constructor tstorageoptions.create(); +begin + fsettingsmake:= true; + inherited; +end; + +{ ttexttemplatesoptions } + +initialization + codetemplates:= tcodetemplates.create; +finalization + freeoptions(); +{ + projectoptions.o.free(); + projectoptions.e.free(); + projectoptions.d.free(); + projectoptions.m.free(); + projectoptions.a.free(); + projectoptions.u.free(); + projectoptions.f.free(); + projectoptions.p.free(); + projectoptions.t.free(); + projectoptions.r.free(); + projectoptions.s.free(); +} + freeandnil(codetemplates); +end. diff --git a/mseide-msegui/apps/ide/projectoptionsform_mfm.pas b/mseide-msegui/apps/ide/projectoptionsform_mfm.pas new file mode 100644 index 0000000..9eeb5d6 --- /dev/null +++ b/mseide-msegui/apps/ide/projectoptionsform_mfm.pas @@ -0,0 +1,9382 @@ +unit projectoptionsform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,projectoptionsform; + +const + objdata: record size: integer; data: array[0..187294] of byte end = + (size: 187295; data: ( + 84,80,70,48,17,116,112,114,111,106,101,99,116,111,112,116,105,111,110,115, + 102,111,16,112,114,111,106,101,99,116,111,112,116,105,111,110,115,102,111,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111, + 110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,205,0,8,98,111,117,110,100,115,95,121,3,177,0,9,98,111,117,110, + 100,115,95,99,120,3,64,3,9,98,111,117,110,100,115,95,99,121,3,69, + 2,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11, + 111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101, + 116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,15,99,111,110,116,97,105,110,101,114, + 46,99,111,108,111,114,4,3,0,0,128,29,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,98,111,116,116,111, + 109,2,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,12,102,114,108,95,102,105,98,111, + 116,116,111,109,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108, + 101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111, + 112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104, + 116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116, + 111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,30,99,111,110,116,97,105,110,101,114,46,102,114,97, + 109,101,46,115,98,104,111,114,122,46,111,112,116,105,111,110,115,11,12,115, + 98,111,95,109,111,118,101,97,117,116,111,12,115,98,111,95,115,104,111,119, + 97,117,116,111,0,25,99,111,110,116,97,105,110,101,114,46,102,97,99,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,16,99,111,110,116,97,105, + 110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,64,3,3,69, + 2,0,7,111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115,101, + 111,110,101,115,99,17,102,111,95,108,111,99,97,108,115,104,111,114,116,99, + 117,116,115,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16, + 102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95, + 115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101, + 114,0,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108, + 101,49,7,99,97,112,116,105,111,110,6,15,80,114,111,106,101,99,116,32, + 79,112,116,105,111,110,115,13,119,105,110,100,111,119,111,112,97,99,105,116, + 121,5,0,0,0,0,0,0,0,128,255,255,8,111,110,99,114,101,97,116, + 101,7,9,99,114,101,97,116,101,101,120,101,15,109,111,100,117,108,101,99, + 108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,9, + 116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,57, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,3,64,3,9,98,111,117,110, + 100,115,95,99,121,3,69,2,7,97,110,99,104,111,114,115,11,0,13,111, + 112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108, + 97,99,101,121,0,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2, + 0,13,112,108,97,99,101,95,111,112,116,105,111,110,115,11,13,112,108,111, + 95,101,110,100,109,97,114,103,105,110,0,0,9,116,108,97,121,111,117,116, + 101,114,10,116,108,97,121,111,117,116,101,114,56,5,99,111,108,111,114,4, + 3,0,0,128,16,102,114,97,109,101,46,102,114,97,109,101,105,95,116,111, + 112,2,5,19,102,114,97,109,101,46,102,114,97,109,101,105,95,98,111,116, + 116,111,109,2,5,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,9,102,114,108,95,102,105,116,111,112,12,102,114,108,95,102,105, + 98,111,116,116,111,109,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,39, + 2,9,98,111,117,110,100,115,95,99,120,3,64,3,9,98,111,117,110,100, + 115,95,99,121,2,30,7,97,110,99,104,111,114,115,11,9,97,110,95,98, + 111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114, + 105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105,103, + 110,121,19,108,97,111,95,115,121,110,99,109,97,120,97,117,116,111,115,105, + 122,101,0,10,97,108,105,103,110,95,103,108,117,101,7,10,119,97,109,95, + 99,101,110,116,101,114,13,112,108,97,99,101,95,109,105,110,100,105,115,116, + 2,5,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,5,10,112, + 108,97,99,101,95,109,111,100,101,7,7,119,97,109,95,101,110,100,13,112, + 108,97,99,101,95,111,112,116,105,111,110,115,11,14,112,108,111,95,112,114, + 111,112,109,97,114,103,105,110,0,7,108,105,110,107,116,111,112,7,9,116, + 97,98,119,105,100,103,101,116,0,7,116,98,117,116,116,111,110,6,99,97, + 110,99,101,108,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 13,111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,8, + 98,111,117,110,100,115,95,120,3,7,3,8,98,111,117,110,100,115,95,121, + 2,5,9,98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100, + 115,95,99,121,2,20,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,13,97,115,95,108,111,99,97,108,99,111, + 108,111,114,0,7,99,97,112,116,105,111,110,6,6,67,97,110,99,101,108, + 11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110, + 99,101,108,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,7,116,98,117,116,116,111,110,2,111,107,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108, + 111,114,4,3,0,0,128,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,3,206,2,8,98,111,117,110,100,115,95,121,2, + 5,9,98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115, + 95,99,121,2,20,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97, + 117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,13,97,115,95,108, + 111,99,97,108,99,111,108,111,114,0,7,99,97,112,116,105,111,110,6,2, + 79,107,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111, + 107,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0, + 10,116,116,97,98,119,105,100,103,101,116,9,116,97,98,119,105,100,103,101, + 116,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13, + 111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,64,3,9,98,111,117,110,100,115,95,99,121,3,39,2,5,99,111, + 108,111,114,4,5,0,0,144,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,19,102,114,97,109,101,46,99,97,112,116,105,111,110,111,102,102, + 115,101,116,2,3,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,9,97,110,95,98,111,116,116,111,109,0,8,116,97,98,111,114,100, + 101,114,2,1,15,97,99,116,105,118,101,112,97,103,101,105,110,100,101,120, + 2,2,20,116,97,98,95,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108, + 101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111, + 112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104, + 116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116, + 111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99, + 116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110, + 0,21,116,97,98,95,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,9,116,97,98, + 95,99,111,108,111,114,4,3,0,0,128,8,116,97,98,95,115,105,122,101, + 2,19,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108, + 101,49,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,8, + 116,116,97,98,112,97,103,101,10,101,100,105,116,111,114,112,97,103,101,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,19,102,114,97,109, + 101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,0,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,12,102,114,108,95, + 102,105,98,111,116,116,111,109,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120, + 2,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115, + 95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,18,2,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,7,99,97,112, + 116,105,111,110,6,7,38,69,100,105,116,111,114,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,10,116,116,97,98,119,105,100,103,101, + 116,11,116,116,97,98,119,105,100,103,101,116,51,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,13,111,119,95,109,111,117, + 115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,62, + 3,9,98,111,117,110,100,115,95,99,121,3,18,2,7,97,110,99,104,111, + 114,115,11,0,15,97,99,116,105,118,101,112,97,103,101,105,110,100,101,120, + 2,0,20,116,97,98,95,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,21,116,97,98,95,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,95,115,105,122,101,2,19, + 8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49, + 0,8,116,116,97,98,112,97,103,101,10,116,116,97,98,112,97,103,101,50, + 51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100, + 101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9, + 98,111,117,110,100,115,95,99,121,3,255,1,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112, + 116,105,111,110,6,6,83,111,117,114,99,101,0,10,116,116,97,98,119,105, + 100,103,101,116,11,116,116,97,98,119,105,100,103,101,116,50,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,3,39,1,9,98,111,117,110,100,115,95,99,120,3, + 62,3,9,98,111,117,110,100,115,95,99,121,3,216,0,12,98,111,117,110, + 100,115,95,99,121,109,105,110,2,84,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,8,116,97, + 98,111,114,100,101,114,2,1,15,97,99,116,105,118,101,112,97,103,101,105, + 110,100,101,120,2,0,20,116,97,98,95,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,21,116,97,98,95,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,9,116,97,98,95,99,111, + 108,111,114,4,3,0,0,128,8,116,97,98,95,115,105,122,101,2,19,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,8,116,116,97, + 98,112,97,103,101,10,116,116,97,98,112,97,103,101,49,51,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116, + 111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115, + 117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,19,102,114, + 97,109,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,0,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,12,102,114, + 108,95,102,105,98,111,116,116,111,109,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,197, + 0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,7,99,97,112,116,105,111,110,6,11,70,105,108,101,32, + 102,105,108,116,101,114,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,11,116,115,116,114,105,110,103,103,114,105,100,14,102,105,108,101, + 102,105,108,116,101,114,103,114,105,100,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99, + 13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4, + 3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102, + 116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3, + 197,0,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105,111,110,115, + 103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12,111, + 103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114,111, + 119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116, + 105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,23,111, + 103,95,115,101,108,101,99,116,101,100,114,111,119,115,100,101,108,101,116,105, + 110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116, + 101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111, + 103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99, + 104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97, + 112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103, + 95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,14,100,97,116, + 97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97,116,97,99,111, + 108,115,46,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97, + 116,97,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104, + 2,112,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,118,97, + 108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117, + 101,6,1,49,0,1,5,119,105,100,116,104,3,172,2,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,118, + 97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114, + 117,101,6,1,49,0,0,13,102,105,120,99,111,108,115,46,99,111,117,110, + 116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5, + 119,105,100,116,104,2,27,8,110,117,109,115,116,97,114,116,2,1,7,110, + 117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115,46,99, + 111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115, + 14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115, + 46,99,111,117,110,116,2,2,14,99,97,112,116,105,111,110,115,46,105,116, + 101,109,115,14,1,7,99,97,112,116,105,111,110,6,4,78,97,109,101,0, + 1,7,99,97,112,116,105,111,110,6,9,70,105,108,101,32,109,97,115,107, + 0,0,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16, + 8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,8, + 116,116,97,98,112,97,103,101,10,116,116,97,98,112,97,103,101,49,52,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95, + 97,117,116,111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111, + 119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,197,0,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111, + 110,6,23,83,121,110,116,97,120,32,100,101,102,105,110,105,116,105,111,110, + 32,102,105,108,101,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,11,116,119,105,100,103,101,116,103,114,105,100,12,116,119,105,100, + 103,101,116,103,114,105,100,54,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 62,3,9,98,111,117,110,100,115,95,99,121,3,197,0,7,97,110,99,104, + 111,114,115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111, + 103,95,99,111,108,115,105,122,105,110,103,12,111,103,95,114,111,119,109,111, + 118,105,110,103,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103, + 15,111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95, + 114,111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115, + 99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102, + 105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110, + 100,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107, + 101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108, + 108,99,111,108,0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2, + 1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105, + 100,116,104,2,26,8,110,117,109,115,116,97,114,116,2,1,7,110,117,109, + 115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117, + 110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1, + 6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99, + 111,117,110,116,2,2,14,99,97,112,116,105,111,110,115,46,105,116,101,109, + 115,14,1,7,99,97,112,116,105,111,110,6,22,83,121,110,116,97,120,32, + 100,101,102,105,110,105,116,105,111,110,32,102,105,108,101,0,1,7,99,97, + 112,116,105,111,110,6,9,70,105,108,101,32,109,97,115,107,0,0,0,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118, + 97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116, + 97,99,111,108,115,46,105,116,101,109,115,14,7,13,115,121,110,116,97,120, + 100,101,102,102,105,108,101,1,5,119,105,100,116,104,3,251,0,7,111,112, + 116,105,111,110,115,11,15,99,111,95,112,114,111,112,111,114,116,105,111,110, + 97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116,7,13, + 99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103,101,116, + 110,97,109,101,6,13,115,121,110,116,97,120,100,101,102,102,105,108,101,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,17,115,121,110,116, + 97,120,100,101,102,102,105,108,101,109,97,115,107,1,5,119,105,100,116,104, + 3,34,2,7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118, + 101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,17,115,121, + 110,116,97,120,100,101,102,102,105,108,101,109,97,115,107,9,100,97,116,97, + 99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,13,115, + 121,110,116,97,120,100,101,102,102,105,108,101,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101, + 118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110, + 116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116, + 101,109,115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97, + 103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111, + 110,46,99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98, + 117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111, + 114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116,7,18,104, + 105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,251, + 0,9,98,111,117,110,100,115,95,99,121,2,16,9,116,101,120,116,102,108, + 97,103,115,11,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95, + 101,108,108,105,112,115,101,108,101,102,116,0,26,99,111,110,116,114,111,108, + 108,101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1, + 1,6,15,83,121,110,116,97,120,100,101,102,32,102,105,108,101,115,6,6, + 42,46,115,100,101,102,0,0,24,99,111,110,116,114,111,108,108,101,114,46, + 111,110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112,97,110, + 100,102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101, + 100,105,116,17,115,121,110,116,97,120,100,101,102,102,105,108,101,109,97,115, + 107,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,0,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114, + 2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114, + 2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,252,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,34,2,9,98,111,117,110,100,115,95,99,121,2,16,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,8, + 116,116,97,98,112,97,103,101,10,116,116,97,98,112,97,103,101,49,57,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116, + 97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,19,9,98,111,117,110,100,115,95,99, + 120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,197,0,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109, + 0,7,99,97,112,116,105,111,110,6,14,67,111,100,101,32,116,101,109,112, + 108,97,116,101,115,0,11,116,119,105,100,103,101,116,103,114,105,100,12,116, + 119,105,100,103,101,116,103,114,105,100,53,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115, + 99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101, + 46,111,112,116,105,111,110,115,11,10,99,102,111,95,102,105,120,116,111,112, + 13,99,102,111,95,102,105,120,98,111,116,116,111,109,0,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,48,67,111,100,101,32,116,101,109,112, + 108,97,116,101,32,100,105,114,101,99,116,111,114,105,101,115,44,32,102,105, + 108,101,32,101,120,116,101,110,115,105,111,110,32,61,32,46,109,99,116,22, + 102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97, + 103,115,11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97,109,101, + 46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,197, + 0,12,98,111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116, + 111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,15,111,103,95, + 107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105, + 110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116, + 105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119,115,100, + 101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108, + 111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116, + 114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10,111,103, + 95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117, + 112,0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102, + 105,120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104, + 2,28,8,110,117,109,115,116,97,114,116,2,1,7,110,117,109,115,116,101, + 112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,11,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,9,68,105,114,101,99,116,111,114,121,0, + 1,7,99,97,112,116,105,111,110,6,1,79,4,104,105,110,116,6,30,65, + 100,100,32,116,111,32,111,98,106,101,99,116,32,102,105,108,101,32,115,101, + 97,114,99,104,32,112,97,116,104,0,1,7,99,97,112,116,105,111,110,6, + 1,76,4,104,105,110,116,6,26,65,100,100,32,116,111,32,108,105,98,114, + 97,114,121,32,115,101,97,114,99,104,32,112,97,116,104,0,1,7,99,97, + 112,116,105,111,110,6,1,73,4,104,105,110,116,6,31,65,100,100,32,116, + 111,32,105,110,99,108,117,100,101,32,102,105,108,101,32,115,101,97,114,99, + 104,32,112,97,116,104,0,1,7,99,97,112,116,105,111,110,6,1,85,4, + 104,105,110,116,6,28,65,100,100,32,116,111,32,117,110,105,116,32,102,105, + 108,101,32,115,101,97,114,99,104,32,112,97,116,104,0,1,7,99,97,112, + 116,105,111,110,6,1,52,4,104,105,110,116,6,13,85,115,101,32,105,110, + 32,77,97,107,101,32,52,0,1,7,99,97,112,116,105,111,110,6,1,51, + 4,104,105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,51, + 0,1,7,99,97,112,116,105,111,110,6,1,50,4,104,105,110,116,6,13, + 85,115,101,32,105,110,32,77,97,107,101,32,50,0,1,7,99,97,112,116, + 105,111,110,6,1,49,4,104,105,110,116,6,13,85,115,101,32,105,110,32, + 77,97,107,101,32,49,0,1,7,99,97,112,116,105,111,110,6,1,66,4, + 104,105,110,116,6,12,85,115,101,32,105,110,32,66,117,105,108,100,0,1, + 7,99,97,112,116,105,111,110,6,1,77,4,104,105,110,116,6,11,85,115, + 101,32,105,110,32,77,97,107,101,0,0,0,0,14,100,97,116,97,99,111, + 108,115,46,99,111,117,110,116,2,1,14,100,97,116,97,99,111,108,115,46, + 119,105,100,116,104,2,13,16,100,97,116,97,99,111,108,115,46,111,112,116, + 105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97, + 116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14, + 7,16,99,111,100,101,116,101,109,112,108,97,116,101,100,105,114,115,1,12, + 108,105,110,101,99,111,108,111,114,102,105,120,4,3,0,0,160,5,119,105, + 100,116,104,3,28,3,7,111,112,116,105,111,110,115,11,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97, + 118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110, + 115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6, + 16,99,111,100,101,116,101,109,112,108,97,116,101,100,105,114,115,9,100,97, + 116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114, + 105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111, + 119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116, + 16,99,111,100,101,116,101,109,112,108,97,116,101,100,105,114,115,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0, + 18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4, + 2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109, + 97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,1,10,111, + 110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110, + 100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,28,3,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,18,99,111,110,116,114,111,108,108, + 101,114,46,111,112,116,105,111,110,115,11,13,102,100,111,95,100,105,114,101, + 99,116,111,114,121,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105, + 115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116, + 114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,21, + 83,101,108,101,99,116,32,117,110,105,116,32,100,105,114,101,99,116,111,114, + 121,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105, + 108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110,97, + 109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,0,0,9,116,108,97,121,111,117,116,101,114,11,116,108,97,121,111,117, + 116,101,114,49,51,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97,98,108, + 101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,37,1,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115, + 104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100,115,104,114, + 105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110, + 107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108, + 97,111,95,112,108,97,99,101,121,0,13,112,108,97,99,101,95,109,105,110, + 100,105,115,116,2,2,13,112,108,97,99,101,95,109,97,120,100,105,115,116, + 2,2,13,112,108,97,99,101,95,111,112,116,105,111,110,115,11,13,112,108, + 111,95,101,110,100,109,97,114,103,105,110,0,10,108,105,110,107,98,111,116, + 116,111,109,7,11,116,116,97,98,119,105,100,103,101,116,50,11,100,105,115, + 116,95,98,111,116,116,111,109,2,2,0,11,116,119,105,100,103,101,116,103, + 114,105,100,8,100,105,115,112,103,114,105,100,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13, + 111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,4,84,101,115,116,22,102,114,97,109,101,46,99, + 97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95, + 98,111,116,116,111,109,0,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,11,99,112,95,116,111,112,114,105,103,104,116,17,102,114, + 97,109,101,46,102,111,110,116,46,120,115,99,97,108,101,2,1,21,102,114, + 97,109,101,46,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,4, + 8,98,111,117,110,100,115,95,120,2,6,8,98,111,117,110,100,115,95,121, + 3,202,0,9,98,111,117,110,100,115,95,99,120,3,49,3,9,98,111,117, + 110,100,115,95,99,121,2,91,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,11,111,112,116,105,111,110,115,103,114,105,100,11,15,111, + 103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111, + 119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101, + 108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114, + 115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10, + 111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111, + 112,117,112,0,8,114,111,119,99,111,117,110,116,2,2,15,114,111,119,99, + 111,108,111,114,115,46,99,111,117,110,116,2,1,15,114,111,119,99,111,108, + 111,114,115,46,105,116,101,109,115,1,4,255,255,224,0,0,14,100,97,116, + 97,99,111,108,115,46,99,111,117,110,116,2,1,18,100,97,116,97,99,111, + 108,115,46,108,105,110,101,119,105,100,116,104,2,0,16,100,97,116,97,99, + 111,108,115,46,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,8,102,111,110,116,100,105,115,112, + 1,5,119,105,100,116,104,3,44,3,7,111,112,116,105,111,110,115,11,7, + 99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,10,119,105,100,103,101,116,110,97,109,101,6,8,102,111,110,116,100,105, + 115,112,9,100,97,116,97,99,108,97,115,115,7,23,116,103,114,105,100,114, + 105,99,104,115,116,114,105,110,103,100,97,116,97,108,105,115,116,4,100,97, + 116,97,1,1,6,0,6,0,0,0,0,0,16,100,97,116,97,114,111,119, + 108,105,110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,14,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,9,116,116,101,120,116,101,100,105,116,8,102,111,110,116,100, + 105,115,112,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13, + 111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111, + 114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,44,3,9,98,111,117,110,100,115,95,99,121, + 2,14,9,102,111,110,116,46,110,97,109,101,6,11,115,116,102,95,100,101, + 102,97,117,108,116,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117, + 14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,108,105, + 110,101,98,114,101,97,107,12,111,101,95,101,97,116,114,101,116,117,114,110, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,20,111,101,95, + 110,111,102,105,114,115,116,97,114,114,111,119,110,97,118,105,103,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,108, + 97,121,111,117,116,101,114,11,116,108,97,121,111,117,116,101,114,49,50,5, + 99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114, + 108,95,111,112,116,105,111,110,115,115,107,105,110,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,163,0,9, + 98,111,117,110,100,115,95,99,120,3,88,2,9,98,111,117,110,100,115,95, + 99,121,2,37,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111, + 115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110, + 107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115, + 104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117, + 116,11,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110, + 95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,18,101,100,105,116,102,111,110,116,101, + 120,116,114,97,115,112,97,99,101,5,99,111,108,111,114,4,3,0,0,128, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5,69,120,116,83, + 112,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,1,2,0,0,8,116,97,98,111,114,100, + 101,114,2,3,4,104,105,110,116,6,25,69,120,116,114,97,32,115,112,97, + 99,101,32,98,101,116,119,101,101,110,32,108,105,110,101,115,8,98,111,117, + 110,100,115,95,120,3,247,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,37,9,98,111,117,110,100,115,95,99, + 121,2,37,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,17,102, + 111,110,116,111,110,100,97,116,97,101,110,116,101,114,101,100,8,118,97,108, + 117,101,109,105,110,3,24,252,8,118,97,108,117,101,109,97,120,3,232,3, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,13,101,100,105,116,102,111,110,116, + 119,105,100,116,104,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 5,87,105,100,116,104,22,102,114,97,109,101,46,99,97,112,116,105,111,110, + 116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109, + 0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,1,2,0,0,8,116, + 97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,199, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,37,9,98,111,117,110,100,115,95,99,121,2,37,13,111,110,100, + 97,116,97,101,110,116,101,114,101,100,7,17,102,111,110,116,111,110,100,97, + 116,97,101,110,116,101,114,101,100,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116, + 14,101,100,105,116,102,111,110,116,104,101,105,103,104,116,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,6,72,101,105,103,104,116,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,7,2,0,0,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,151,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,43,9,98,111,117,110, + 100,115,95,99,121,2,37,13,111,110,100,97,116,97,101,110,116,101,114,101, + 100,7,17,102,111,110,116,111,110,100,97,116,97,101,110,116,101,114,101,100, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116, + 115,116,114,105,110,103,101,100,105,116,12,101,100,105,116,102,111,110,116,110, + 97,109,101,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,4,70,111,110,116,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116, + 102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114, + 105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98, + 111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 17,2,0,2,0,0,8,98,111,117,110,100,115,95,120,2,7,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,124, + 9,98,111,117,110,100,115,95,99,121,2,37,13,111,110,100,97,116,97,101, + 110,116,101,114,101,100,7,17,102,111,110,116,111,110,100,97,116,97,101,110, + 116,101,114,101,100,5,118,97,108,117,101,6,13,109,115,101,105,100,101,95, + 115,111,117,114,99,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,10,116,99,111,108,111,114,101,100,105,116,13,101,100,105,116, + 102,111,110,116,99,111,108,111,114,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,5,67,111,108,111,114,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116, + 105,118,101,105,110,118,105,115,105,98,108,101,0,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,2,0,0,128,7,111,112,116,105,111,110,115,11,21,102,98, + 111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0, + 0,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,7,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97, + 99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,0,0,25,102,114, + 97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111, + 108,111,114,4,2,0,0,128,27,102,114,97,109,101,46,98,117,116,116,111, + 110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2,17,27,102, + 114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,111, + 112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101, + 105,110,118,105,115,105,98,108,101,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,47,1, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 121,2,37,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,111,110,100,97, + 116,97,101,110,116,101,114,101,100,7,17,102,111,110,116,111,110,100,97,116, + 97,101,110,116,101,114,101,100,5,118,97,108,117,101,4,9,0,0,144,16, + 100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,16,100,101, + 111,95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107, + 101,121,100,114,111,112,100,111,119,110,12,100,101,111,95,99,108,105,112,104, + 105,110,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,10,116,99,111,108,111,114,101,100,105,116,11,101,100,105,116,98,107, + 99,111,108,111,114,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 9,66,107,46,32,67,111,108,111,114,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116, + 105,118,101,105,110,118,105,115,105,98,108,101,0,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,2,0,0,128,7,111,112,116,105,111,110,115,11,21,102,98, + 111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0, + 0,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,7,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97, + 99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,0,0,25,102,114, + 97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111, + 108,111,114,4,2,0,0,128,27,102,114,97,109,101,46,98,117,116,116,111, + 110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2,17,27,102, + 114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,111, + 112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101, + 105,110,118,105,115,105,98,108,101,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,151,1, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 121,2,37,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,111,110,100,97, + 116,97,101,110,116,101,114,101,100,7,17,102,111,110,116,111,110,100,97,116, + 97,101,110,116,101,114,101,100,5,118,97,108,117,101,4,6,0,0,144,16, + 100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,16,100,101, + 111,95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107, + 101,121,100,114,111,112,100,111,119,110,12,100,101,111,95,99,108,105,112,104, + 105,110,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,19,101,100,105,116, + 102,111,110,116,97,110,116,105,97,108,105,97,115,101,100,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,12,65,110,116,105,32,97,108,105,97, + 115,101,100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116, + 17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,76,2,2,0, + 8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120, + 3,255,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100, + 115,95,99,120,2,89,9,98,111,117,110,100,115,95,99,121,2,16,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,17,102,111,110,116,111,110, + 100,97,116,97,101,110,116,101,114,101,100,5,118,97,108,117,101,9,0,0, + 0,9,116,108,97,121,111,117,116,101,114,11,116,108,97,121,111,117,116,101, + 114,49,49,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,91,9,98,111,117,110,100,115,95,99,120,3,60,2,9,98,111,117,110, + 100,115,95,99,121,2,70,12,111,112,116,105,111,110,115,115,99,97,108,101, + 11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104, + 114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115, + 99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97, + 121,111,117,116,11,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108, + 105,103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,0, + 9,116,108,97,121,111,117,116,101,114,11,116,108,97,121,111,117,116,101,114, + 49,52,8,98,111,117,110,100,115,95,120,2,7,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,121,9,98,111,117, + 110,100,115,95,99,121,2,70,12,111,112,116,105,111,110,115,115,99,97,108, + 101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115, + 104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111, + 115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108, + 97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,121,0,13,112, + 108,97,99,101,95,109,105,110,100,105,115,116,2,2,13,112,108,97,99,101, + 95,109,97,120,100,105,115,116,2,2,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,13,114,105,103,104,116,109,97,114,103,105,110,111,110,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,17,82,105,103,104,116,32, + 109,97,114,103,105,110,32,108,105,110,101,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,1,2,108,2,2,0,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 54,9,98,111,117,110,100,115,95,99,120,2,121,9,98,111,117,110,100,115, + 95,99,121,2,16,5,118,97,108,117,101,9,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,13,108,105,110,101,110,117,109,98,101,114,115,111, + 110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,76,105,110, + 101,32,110,117,109,98,101,114,115,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,87,2,2,0,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,100,9,98,111,117,110,100,115,95,99,121,2, + 16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,16,101,100,105, + 116,109,97,114,107,98,114,97,99,107,101,116,115,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,13,77,97,114,107,32,98,114,97,99,107,101, + 116,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,92,2,2,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,18,9,98,111,117,110,100,115,95, + 99,120,2,105,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108, + 117,101,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,17,101, + 100,105,116,109,97,114,107,112,97,105,114,119,111,114,100,115,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,14,77,97,114,107,32,112,97,105, + 114,119,111,114,100,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108, + 101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111, + 112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104, + 116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116, + 111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,98, + 2,2,0,8,116,97,98,111,114,100,101,114,2,2,4,104,105,110,116,6, + 50,77,97,114,107,32,105,110,32,115,121,110,116,97,120,32,100,101,102,105, + 110,105,116,105,111,110,32,102,105,108,101,32,100,101,102,105,110,101,100,32, + 119,111,114,100,32,112,97,105,114,115,46,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,36,9,98,111,117,110,100,115, + 95,99,120,2,111,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97, + 108,117,101,9,0,0,0,9,116,108,97,121,111,117,116,101,114,11,116,108, + 97,121,111,117,116,101,114,49,53,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,143,0,8,98,111,117,110,100,115,95, + 121,2,10,9,98,111,117,110,100,115,95,99,120,3,173,1,9,98,111,117, + 110,100,115,95,99,121,2,51,12,111,112,116,105,111,110,115,115,99,97,108, + 101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115, + 104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111, + 115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110, + 100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115, + 104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117, + 116,11,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110, + 95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,0,10,116,99, + 111,108,111,114,101,100,105,116,13,112,97,105,114,109,97,114,107,99,111,108, + 111,114,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10,77,97, + 114,107,10,99,111,108,111,114,22,102,114,97,109,101,46,99,97,112,116,105, + 111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116, + 111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118, + 101,105,110,118,105,115,105,98,108,101,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111, + 114,4,2,0,0,128,7,111,112,116,105,111,110,115,11,21,102,98,111,95, + 105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,0,1, + 5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2, + 17,7,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116, + 105,118,101,105,110,118,105,115,105,98,108,101,0,0,0,25,102,114,97,109, + 101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111,108,111, + 114,4,2,0,0,128,27,102,114,97,109,101,46,98,117,116,116,111,110,101, + 108,108,105,112,115,101,46,105,109,97,103,101,110,114,2,17,27,102,114,97, + 109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,111,112,116, + 105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101,105,110, + 118,105,115,105,98,108,101,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,31,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,3,4,104,105,110,116,6,131,66,97,99,107,103,114,111, + 117,110,100,32,99,111,108,111,114,32,111,102,32,109,97,114,107,101,100,32, + 98,114,97,99,107,101,116,115,32,97,110,100,32,119,111,114,100,32,112,97, + 105,114,115,46,10,87,105,108,108,32,98,101,32,111,118,101,114,114,105,100, + 100,101,110,32,98,121,32,115,101,116,116,105,110,103,32,105,110,32,115,121, + 110,116,97,120,32,100,101,102,105,110,105,116,105,111,110,32,102,105,108,101, + 46,10,99,108,95,110,111,110,101,32,45,62,32,102,111,114,99,101,32,110, + 111,110,101,46,10,111,110,115,104,111,119,104,105,110,116,7,9,99,111,108, + 111,114,104,105,110,116,8,98,111,117,110,100,115,95,120,3,8,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2, + 51,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95, + 97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101, + 121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118,97,108, + 117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104, + 105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104,105,110, + 116,99,108,105,112,112,101,100,116,101,120,116,0,16,100,114,111,112,100,111, + 119,110,46,111,112,116,105,111,110,115,11,16,100,101,111,95,97,117,116,111, + 100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121,100,114,111,112, + 100,111,119,110,12,100,101,111,95,99,108,105,112,104,105,110,116,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,10,116,99,111, + 108,111,114,101,100,105,116,14,115,116,97,116,101,109,101,110,116,99,111,108, + 111,114,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,15,83,116, + 97,116,101,109,101,110,116,10,99,111,108,111,114,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110, + 46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117, + 116,116,111,110,46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110, + 97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1, + 5,99,111,108,111,114,4,2,0,0,128,7,111,112,116,105,111,110,115,11, + 21,102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98, + 108,101,0,0,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97, + 103,101,110,114,2,17,7,111,112,116,105,111,110,115,11,21,102,98,111,95, + 105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,0,0, + 25,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101, + 46,99,111,108,111,114,4,2,0,0,128,27,102,114,97,109,101,46,98,117, + 116,116,111,110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2, + 17,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115, + 101,46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116, + 105,118,101,105,110,118,105,115,105,98,108,101,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,31,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,2,4,104,105,110,116,6,131,66,97, + 99,107,103,114,111,117,110,100,32,99,111,108,111,114,32,111,102,32,116,104, + 101,32,97,99,116,105,118,101,32,114,111,119,32,119,104,105,108,101,32,100, + 101,98,117,103,103,105,110,103,46,10,87,105,108,108,32,98,101,32,111,118, + 101,114,114,105,100,100,101,110,32,98,121,32,115,101,116,116,105,110,103,32, + 105,110,32,115,121,110,116,97,120,32,100,101,102,105,110,105,116,105,111,110, + 32,102,105,108,101,46,10,99,108,95,110,111,110,101,32,45,62,32,102,111, + 114,99,101,32,110,111,110,101,46,10,111,110,115,104,111,119,104,105,110,116, + 7,9,99,111,108,111,114,104,105,110,116,8,98,111,117,110,100,115,95,120, + 3,160,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,121,2,51,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116, + 101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14, + 111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111, + 101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,17,102,111,110,116,111,110, + 100,97,116,97,101,110,116,101,114,101,100,5,118,97,108,117,101,4,255,255, + 224,0,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11, + 16,100,101,111,95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101, + 111,95,107,101,121,100,114,111,112,100,111,119,110,12,100,101,111,95,99,108, + 105,112,104,105,110,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,12,115, + 99,114,111,108,108,104,101,105,103,104,116,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,13,83,99,114,111,108,108,10,104,101,105,103,104,116, + 22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108, + 97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,31,2,6,2,0,0,8,116,97,98,111,114,100,101, + 114,2,1,4,104,105,110,116,6,29,48,32,45,62,32,97,99,99,101,108, + 101,114,97,116,101,100,44,10,45,49,32,45,62,32,112,97,103,101,100,8, + 98,111,117,110,100,115,95,120,2,104,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,42,9,98,111,117,110,100,115, + 95,99,121,2,51,8,118,97,108,117,101,109,105,110,2,255,8,118,97,108, + 117,101,109,97,120,3,232,3,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,16, + 114,105,103,104,116,109,97,114,103,105,110,99,104,97,114,115,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,10,67,104,97,114,97,99,116,101, + 114,115,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116, + 102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,35,2,0,0,8,98,111,117,110,100, + 115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,14,9,98,111,117, + 110,100,115,95,99,120,2,71,9,98,111,117,110,100,115,95,99,121,2,37, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97, + 117,116,111,112,111,112,117,112,109,101,110,117,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,5,118,97,108,117,101,2,80,8,118,97,108,117,101,109,105,110, + 2,1,8,118,97,108,117,101,109,97,120,2,100,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,15,112,97,105,114,109,97,120,114,111,119,99,111,117,110,116, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,17,77,97,114,107, + 32,109,97,120,10,114,111,119,99,111,117,110,116,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,31,2,1,2,0,0,8,116,97,98,111,114, + 100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,112,1,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,61, + 9,98,111,117,110,100,115,95,99,121,2,51,5,118,97,108,117,101,2,100, + 8,118,97,108,117,101,109,105,110,2,1,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,0,9,116,108,97,121,111,117,116,101, + 114,11,116,108,97,121,111,117,116,101,114,49,48,5,99,111,108,111,114,4, + 3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102, + 116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,28,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112,116,105, + 111,110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,52,9,98,111,117,110,100,115,95, + 99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112,116,105,111, + 110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121, + 11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110, + 115,108,97,121,111,117,116,11,10,108,97,111,95,97,108,105,103,110,121,0, + 10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97, + 114,116,0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,115,112,97, + 99,101,116,97,98,115,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,5,83,112,97,99,101,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2, + 42,2,2,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110, + 100,115,95,120,3,47,1,8,98,111,117,110,100,115,95,121,2,20,9,98, + 111,117,110,100,115,95,99,120,2,55,9,98,111,117,110,100,115,95,99,121, + 2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,11,98,108, + 111,99,107,105,110,100,101,110,116,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,12,66,108,111,99,107,32,73,110,100,101,110,116,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,43,2,0,0,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,151,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,79,9,98,111,117,110, + 100,115,95,99,121,2,37,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111, + 101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15, + 111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101, + 110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,5,118,97,108,117,101,2,1,8,118, + 97,108,117,101,109,105,110,2,1,8,118,97,108,117,101,109,97,120,2,100, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,10,97,117,116,111,105,110,100,101, + 110,116,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11,65,117, + 116,111,32,105,110,100,101,110,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114, + 105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98, + 111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,76,2,2,0,8,98,111,117,110,100,115,95,120,2,7,8,98,111, + 117,110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120,2,89, + 9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101,9,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,116,97,98,105,110, + 100,101,110,116,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3, + 84,97,98,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,1,2,26,2,2,0,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,3,191,0,8,98,111,117,110,100,115,95, + 121,2,20,9,98,111,117,110,100,115,95,99,120,2,39,9,98,111,117,110, + 100,115,95,99,121,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100, + 105,116,8,116,97,98,115,116,111,112,115,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,8,84,97,98,115,116,111,112,115,22,102,114,97,109, + 101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9, + 116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,24,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,3,247,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,60,9,98,111,117,110,100,115, + 95,99,121,2,37,5,118,97,108,117,101,2,4,8,118,97,108,117,101,109, + 105,110,2,1,8,118,97,108,117,101,109,97,120,2,50,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,8,115,104,111,119,116,97,98,115,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,9,83,104,111,119,32,116,97,98,115, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,68,2,2,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111, + 117,110,100,115,95,120,3,151,1,8,98,111,117,110,100,115,95,121,2,20, + 9,98,111,117,110,100,115,95,99,120,2,81,9,98,111,117,110,100,115,95, + 99,121,2,16,0,0,0,9,116,108,97,121,111,117,116,101,114,11,116,108, + 97,121,111,117,116,101,114,49,54,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,62,3,9,98,111,117,110,100,115,95,99,121,2,50,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112,116,105,111,110, + 115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111, + 117,116,11,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103, + 110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,0,13,116, + 101,110,117,109,116,121,112,101,101,100,105,116,8,101,111,108,115,116,121,108, + 101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,8,69,111,108, + 115,116,121,108,101,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116, + 101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,0,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,2,4,104,105,110,116,6,65,69,110,100,32,111,102,32,108,105,110, + 101,32,115,116,121,108,101,32,102,111,114,32,119,114,105,116,105,110,103,46, + 32,101,111,108,95,100,101,102,97,117,108,116,32,45,62,32,117,115,101,32, + 111,114,105,103,105,110,97,108,32,115,116,121,108,101,46,8,98,111,117,110, + 100,115,95,120,3,247,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,116,9,98,111,117,110,100,115,95,99,121, + 2,37,5,118,97,108,117,101,2,1,8,118,97,108,117,101,109,105,110,2, + 0,8,118,97,108,117,101,109,97,120,2,3,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,6,111, + 110,105,110,105,116,7,15,105,110,105,116,101,111,108,115,116,121,108,101,101, + 120,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,22,116,114,105,109,116,114, + 97,105,108,105,110,103,119,104,105,116,101,115,112,97,99,101,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,32,84,114,105,109,32,116,114,97, + 105,108,105,110,103,10,119,104,105,116,101,115,112,97,99,101,10,111,110,32, + 115,97,118,101,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,15,2,76,2,16,0,8,98,111,117,110,100,115,95,120,2, + 7,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95, + 99,120,2,89,9,98,111,117,110,100,115,95,99,121,2,44,0,0,9,116, + 101,110,117,109,101,100,105,116,8,101,110,99,111,100,105,110,103,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,8,69,110,99,111,100,105,110, + 103,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,2,0,0,128,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114, + 4,2,0,0,128,0,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,151,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,92, + 9,98,111,117,110,100,115,95,99,121,2,37,16,100,114,111,112,100,111,119, + 110,46,111,112,116,105,111,110,115,11,14,100,101,111,95,115,101,108,101,99, + 116,111,110,108,121,15,100,101,111,95,102,111,114,99,101,115,101,108,101,99, + 116,16,100,101,111,95,97,117,116,111,100,114,111,112,100,111,119,110,15,100, + 101,111,95,107,101,121,100,114,111,112,100,111,119,110,0,19,100,114,111,112, + 100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114, + 111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,4, + 100,97,116,97,1,6,6,76,111,99,97,108,101,6,4,117,116,102,56,6, + 9,105,115,111,56,56,53,57,45,49,0,0,0,5,118,97,108,117,101,2, + 0,10,111,110,115,101,116,118,97,108,117,101,7,16,101,110,99,111,100,105, + 110,103,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,15,98,97,99,107,117,112,102,105,108,101,99,111,117,110,116,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,17,66,97,99,107,117,112,32, + 102,105,108,101,32,99,111,117,110,116,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,74,2, + 0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115, + 95,120,3,151,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,110,9,98,111,117,110,100,115,95,99,121,2,37, + 5,118,97,108,117,101,2,2,8,118,97,108,117,101,109,97,120,2,10,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,0, + 8,116,116,97,98,112,97,103,101,10,116,116,97,98,112,97,103,101,50,50, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,19,9,98,111,117,110,100,115,95, + 99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,255,1,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111, + 109,0,7,99,97,112,116,105,111,110,6,4,70,111,114,109,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,14,99,111,109,112,111,110,101,110,116, + 104,105,110,116,115,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 15,67,111,109,112,111,110,101,110,116,32,104,105,110,116,115,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,2,110,2,2,0,8,116,97,98,111,114,100, + 101,114,2,6,8,98,111,117,110,100,115,95,120,3,255,1,8,98,111,117, + 110,100,115,95,121,2,18,9,98,111,117,110,100,115,95,99,120,2,123,9, + 98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,21,110,111,102,111,114,109,100,101,115,105,103,110,101, + 114,100,111,99,107,105,110,103,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,7,68,111,99,107,105,110,103,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,1,2,53,2,2,0,8,116,97,98,111,114,100,101,114,2,4,8, + 98,111,117,110,100,115,95,120,3,103,1,8,98,111,117,110,100,115,95,121, + 2,18,9,98,111,117,110,100,115,95,99,120,2,66,9,98,111,117,110,100, + 115,95,99,121,2,16,7,111,112,116,105,111,110,115,11,17,98,111,95,101, + 120,101,99,117,116,101,111,110,99,108,105,99,107,15,98,111,95,101,120,101, + 99,117,116,101,111,110,107,101,121,20,98,111,95,101,120,101,99,117,116,101, + 111,110,115,104,111,114,116,99,117,116,27,98,111,95,101,120,101,99,117,116, + 101,100,101,102,97,117,108,116,111,110,101,110,116,101,114,107,101,121,11,98, + 111,95,114,101,118,101,114,115,101,100,0,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,16,109,111,118,101,111,110,102,105,114,115,116,99,108, + 105,99,107,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,19,77, + 111,118,101,32,111,110,32,102,105,114,115,116,32,99,108,105,99,107,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,114,2,2,0,8,116,97,98,111, + 114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,103,1,8,98, + 111,117,110,100,115,95,121,2,42,9,98,111,117,110,100,115,95,99,120,2, + 127,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101,9, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,9,103,114,105,100, + 115,105,122,101,121,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 11,71,114,105,100,32,115,105,122,101,32,89,22,102,114,97,109,101,46,99, + 97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95, + 98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 29,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110, + 100,115,95,120,3,247,0,8,98,111,117,110,100,115,95,121,2,18,9,98, + 111,117,110,100,115,95,99,120,2,65,9,98,111,117,110,100,115,95,99,121, + 2,37,5,118,97,108,117,101,2,8,8,118,97,108,117,101,109,105,110,2, + 1,8,118,97,108,117,101,109,97,120,3,232,3,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,9,103,114,105,100,115,105,122,101,120,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,11,71,114,105,100,32,115,105,122,101,32, + 88,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,29,2,0,0,8,116,97,98,111,114,100, + 101,114,2,2,8,98,111,117,110,100,115,95,120,3,151,0,8,98,111,117, + 110,100,115,95,121,2,18,9,98,111,117,110,100,115,95,99,120,2,65,9, + 98,111,117,110,100,115,95,99,121,2,37,5,118,97,108,117,101,2,8,8, + 118,97,108,117,101,109,105,110,2,1,8,118,97,108,117,101,109,97,120,3, + 232,3,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,13,116,105,110,116,101,103,101, + 114,101,100,105,116,50,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,11,71,114,105,100,32,115,105,122,101,32,88,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105, + 103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111, + 116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,29,2,0,0,8,98,111,117,110,100,115,95,120,3,136,0,8,98,111, + 117,110,100,115,95,121,2,29,9,98,111,117,110,100,115,95,99,120,2,65, + 9,98,111,117,110,100,115,95,99,121,2,37,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,10,115,110,97,112,116,111,103,114,105,100,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,83,110,97,112,32, + 116,111,32,71,114,105,100,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2, + 81,2,2,0,8,116,97,98,111,114,100,101,114,2,1,4,104,105,110,116, + 6,146,72,105,110,116,58,10,85,115,101,32,67,116,114,108,32,43,32,97, + 114,114,111,119,32,107,101,121,115,32,116,111,32,109,111,118,101,32,115,101, + 108,101,99,116,101,100,32,99,111,109,112,111,110,101,110,116,115,32,119,105, + 116,104,111,117,116,32,103,114,105,100,32,115,110,97,112,44,10,117,115,101, + 32,83,104,105,102,116,32,43,32,97,114,114,111,119,32,107,101,121,115,32, + 116,111,32,114,101,115,105,122,101,32,115,101,108,101,99,116,101,100,32,99, + 111,109,112,111,110,101,110,116,115,32,119,105,116,104,111,117,116,32,103,114, + 105,100,32,115,110,97,112,46,8,98,111,117,110,100,115,95,120,2,7,8, + 98,111,117,110,100,115,95,121,2,42,9,98,111,117,110,100,115,95,99,120, + 2,94,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101, + 9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,8,115,104,111, + 119,103,114,105,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 9,83,104,111,119,32,71,114,105,100,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,1,2,65,2,2,0,8,98,111,117,110,100,115,95,120,2,7,8,98, + 111,117,110,100,115,95,121,2,18,9,98,111,117,110,100,115,95,99,120,2, + 78,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101,9, + 0,0,0,0,0,8,116,116,97,98,112,97,103,101,12,100,101,98,117,103, + 103,101,114,112,97,103,101,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115, + 117,98,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101, + 108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 4,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,2,20,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111, + 110,6,9,38,68,101,98,117,103,103,101,114,8,111,110,108,97,121,111,117, + 116,7,17,100,101,98,117,103,103,101,114,108,97,121,111,117,116,101,120,101, + 0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,12,100,101,98,117, + 103,99,111,109,109,97,110,100,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109, + 101,46,111,112,116,105,111,110,115,11,10,99,102,111,95,102,105,120,116,111, + 112,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,14,38,68, + 101,98,117,103,32,99,111,109,109,97,110,100,22,102,114,97,109,101,46,99, + 97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95, + 98,111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116,105,111, + 110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114, + 105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98, + 111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101, + 110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116, + 116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105, + 110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114, + 111,115,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115, + 95,121,2,57,9,98,111,117,110,100,115,95,99,120,3,46,1,9,98,111, + 117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111, + 110,115,11,15,102,100,111,95,113,117,111,116,101,115,105,110,103,108,101,0, + 26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114,121,109, + 97,120,99,111,117,110,116,2,0,24,99,111,110,116,114,111,108,108,101,114, + 46,111,110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112,97, + 110,100,102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103, + 101,100,105,116,12,100,101,98,117,103,111,112,116,105,111,110,115,13,102,114, + 97,109,101,46,111,112,116,105,111,110,115,11,10,99,102,111,95,102,105,120, + 116,111,112,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,14, + 68,101,98,117,103,32,38,111,112,116,105,111,110,115,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116, + 102,95,98,111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116, + 105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110, + 116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116, + 101,109,115,14,1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114, + 97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,4,104, + 105,110,116,6,37,34,45,45,116,116,121,32,68,69,86,73,67,69,34,32, + 116,111,32,115,101,116,32,116,97,114,103,101,116,32,116,101,114,109,105,110, + 97,108,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101, + 120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115, + 95,120,3,50,1,8,98,111,117,110,100,115,95,121,2,57,9,98,111,117, + 110,100,115,95,99,120,3,11,2,9,98,111,117,110,100,115,95,99,121,2, + 37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,10,116,116,97,98,119,105, + 100,103,101,116,11,116,116,97,98,119,105,100,103,101,116,49,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,0,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,3,204,0,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,70, + 1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,8,116,97,98,111,114,100,101,114,2,6,15,97,99,116, + 105,118,101,112,97,103,101,105,110,100,101,120,2,0,20,116,97,98,95,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114,108, + 95,111,112,116,105,111,110,115,115,107,105,110,0,21,116,97,98,95,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,19,116,97,98,95,102,97,99,101,46,108,111, + 99,97,108,112,114,111,112,115,11,20,102,97,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,0,9,116,97,98,95,99,111,108,111, + 114,4,3,0,0,128,8,116,97,98,95,115,105,122,101,2,19,8,115,116, + 97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,8,116,116,97,98,112, + 97,103,101,9,116,116,97,98,112,97,103,101,54,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102, + 111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108, + 101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98,111, + 117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121, + 3,51,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,19,83,111,117, + 114,99,101,32,38,100,105,114,101,99,116,111,114,105,101,115,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,119,105,100,103,101, + 116,103,114,105,100,13,115,111,117,114,99,101,100,105,114,103,114,105,100,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107, + 111,110,101,115,99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99, + 111,108,111,114,4,3,0,0,128,19,102,114,97,109,101,46,99,97,112,116, + 105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,24,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,27,1,12,98,111,117,110,100,115,95,99,121,109, + 105,110,2,40,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103, + 114,105,100,11,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103, + 95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119, + 105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101, + 116,105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119,115, + 100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108, + 108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115, + 116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1, + 16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,12,99, + 111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97, + 116,97,99,111,108,115,46,105,116,101,109,115,14,7,10,115,111,117,114,99, + 101,100,105,114,115,1,12,108,105,110,101,99,111,108,111,114,102,105,120,4, + 3,0,0,160,5,119,105,100,116,104,3,57,3,7,111,112,116,105,111,110, + 115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97, + 118,101,118,97,108,117,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116, + 7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103, + 101,116,110,97,109,101,6,10,115,111,117,114,99,101,100,105,114,115,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,13,116,102,105,108,101,110,97,109,101,101,100,105, + 116,10,115,111,117,114,99,101,100,105,114,115,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5, + 0,0,144,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109, + 101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,20, + 102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114, + 2,17,8,116,97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119, + 104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97, + 99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,57,3,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115, + 97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,18,99,111,110,116,114,111,108,108, + 101,114,46,105,110,99,108,117,100,101,11,6,102,97,95,100,105,114,6,102, + 97,95,97,108,108,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112, + 116,105,111,110,115,11,13,102,100,111,95,100,105,114,101,99,116,111,114,121, + 0,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114,121, + 109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111,108,108,101, + 114,46,99,97,112,116,105,111,110,111,112,101,110,6,23,83,101,108,101,99, + 116,32,115,111,117,114,99,101,32,100,105,114,101,99,116,111,114,121,24,99, + 111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110, + 97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,13,116, + 102,105,108,101,110,97,109,101,101,100,105,116,10,115,111,117,114,99,101,98, + 97,115,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,47,79, + 98,106,101,99,116,32,38,66,97,115,101,32,68,105,114,101,99,116,111,114, + 121,32,40,101,109,112,116,121,32,61,32,77,97,107,101,32,68,105,114,101, + 99,116,111,114,121,41,22,102,114,97,109,101,46,99,97,112,116,105,111,110, + 116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101, + 114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103,101, + 110,114,2,17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,3,45,1,2,0,0,8,116,97, + 98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116,7, + 13,115,111,117,114,99,101,100,105,114,104,105,110,116,8,98,111,117,110,100, + 115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,2,9,98,111,117, + 110,100,115,95,99,120,3,59,3,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,9,116,101,120,116,102,108,97,103,115,11,11,116,102,95,110,111, + 115,101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102, + 116,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110, + 115,11,13,102,100,111,95,100,105,114,101,99,116,111,114,121,0,22,99,111, + 110,116,114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110, + 6,28,83,101,108,101,99,116,32,115,111,117,114,99,101,32,98,97,115,101, + 32,100,105,114,101,99,116,111,114,121,24,99,111,110,116,114,111,108,108,101, + 114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112, + 97,110,100,102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,7,116,115,112,97,99,101,114,8,116,115, + 112,97,99,101,114,55,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,3,15,2,8,98,111,117,110,100,115,95,121,2,22, + 9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95, + 99,121,2,2,7,108,105,110,107,116,111,112,7,10,115,111,117,114,99,101, + 98,97,115,101,10,108,105,110,107,98,111,116,116,111,109,7,13,115,111,117, + 114,99,101,100,105,114,103,114,105,100,0,0,0,8,116,116,97,98,112,97, + 103,101,9,116,116,97,98,112,97,103,101,57,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111, + 99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101, + 100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98,111,117, + 110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3, + 51,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,8,68,101,102,105, + 38,110,101,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,11,116,119,105,100,103,101,116,103,114,105,100,12,116,119,105,100,103,101, + 116,103,114,105,100,50,5,99,111,108,111,114,4,3,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 62,3,9,98,111,117,110,100,115,95,99,121,3,51,1,7,97,110,99,104, + 111,114,115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,15,111, + 103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111, + 119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108, + 101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110, + 101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111, + 119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99, + 111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95, + 119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112, + 0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105, + 120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116, + 2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,2,14, + 99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112, + 116,105,111,110,6,2,111,110,0,1,7,99,97,112,116,105,111,110,6,36, + 83,112,97,99,101,32,115,101,112,97,114,97,116,101,100,32,100,101,102,105, + 110,101,115,32,102,111,114,32,123,36,105,102,100,101,102,125,0,0,0,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,9,100,101,102,105,110,101,115,111, + 110,1,5,119,105,100,116,104,2,22,7,111,112,116,105,111,110,115,11,12, + 99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,9,100,101,102,105,110,101,115,111,110, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,100,101,102,105,110, + 101,115,1,5,119,105,100,116,104,3,34,3,7,111,112,116,105,111,110,115, + 11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,111,110,115,104, + 111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119,104,105,110, + 116,10,119,105,100,103,101,116,110,97,109,101,6,7,100,101,102,105,110,101, + 115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97, + 116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,9,100,101,102,105,110,101,115,111,110,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101, + 101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,22,9,98,111,117,110, + 100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111, + 101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49, + 95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101, + 115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118,97,108,117,101, + 97,102,116,101,114,115,116,97,116,114,101,97,100,0,7,118,105,115,105,98, + 108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,7,100,101,102,105,110,101,115,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,13,111,119,95,109,111, + 117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98, + 111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,2,23,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,3,34,3,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,8,116,116,97,98, + 112,97,103,101,9,116,116,97,98,112,97,103,101,55,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115, + 99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98, + 111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99, + 121,3,51,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110, + 95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,8,38,83, + 105,103,110,97,108,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,11,116,119,105,100,103,101,116,103,114,105,100,10,115,105,103,110, + 97,108,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111, + 99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115, + 101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,19,102,114,97, + 109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 3,62,3,9,98,111,117,110,100,115,95,99,121,3,51,1,12,98,111,117, + 110,100,115,95,99,121,109,105,110,2,40,7,97,110,99,104,111,114,115,11, + 0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111, + 108,115,105,122,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116, + 105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19,111, + 103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15,111, + 103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97,117, + 116,111,97,112,112,101,110,100,9,111,103,95,115,111,114,116,101,100,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13, + 102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103, + 104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2, + 5,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99, + 97,112,116,105,111,110,6,4,83,116,111,112,0,1,7,99,97,112,116,105, + 111,110,6,6,72,97,110,100,108,101,0,1,7,99,97,112,116,105,111,110, + 6,6,83,105,103,110,117,109,0,1,7,99,97,112,116,105,111,110,6,5, + 46,46,32,116,111,0,1,7,99,97,112,116,105,111,110,6,4,78,97,109, + 101,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110, + 116,101,114,101,100,0,0,0,0,0,14,100,97,116,97,99,111,108,115,46, + 99,111,117,110,116,2,5,16,100,97,116,97,99,111,108,115,46,111,112,116, + 105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95, + 115,97,118,101,115,116,97,116,101,9,99,111,95,110,111,115,111,114,116,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,7,115, + 105,103,115,116,111,112,1,5,119,105,100,116,104,2,32,7,111,112,116,105, + 111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116, + 101,9,99,111,95,110,111,115,111,114,116,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116, + 110,97,109,101,6,7,115,105,103,115,116,111,112,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,9,115,105,103,104,97,110,100,108,101,1,5,119, + 105,100,116,104,2,43,7,111,112,116,105,111,110,115,11,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,9,99,111,95,110,111,115,111, + 114,116,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,9,115,105,103, + 104,97,110,100,108,101,9,100,97,116,97,99,108,97,115,115,7,20,116,103, + 114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7, + 6,115,105,103,110,117,109,1,7,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,6,115,105,103,110,117,109,9,100,97,116,97, + 99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100, + 97,116,97,108,105,115,116,0,7,8,115,105,103,110,117,109,116,111,1,5, + 119,105,100,116,104,2,39,7,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101, + 12,99,111,95,115,97,118,101,115,116,97,116,101,9,99,111,95,110,111,115, + 111,114,116,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,8,115,105, + 103,110,117,109,116,111,9,100,97,116,97,99,108,97,115,115,7,20,116,103, + 114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7, + 7,115,105,103,110,97,109,101,1,5,119,105,100,116,104,3,145,2,7,111, + 112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99, + 111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,9,99,111,95,110,111,115,111, + 114,116,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,115,105,103, + 110,97,109,101,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114,105, + 100,101,110,117,109,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97, + 114,111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,7,115,105,103,115,116,111,112,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,32,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117, + 116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101, + 120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,7,118,105,115,105,98,108,101,8,5,118,97,108,117,101,9,12,118,97, + 108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,9,115,105,103,104,97,110,100,108,101,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,8,98, + 111,117,110,100,115,95,120,2,33,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,43,9,98,111,117,110,100,115,95, + 99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,6,115,105,103,110,117,109,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 8,116,97,98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,2,77,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,16,115,105,103,110,117,109,111,110,115,101,116,118, + 97,108,117,101,8,118,97,108,117,101,109,97,120,3,255,0,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,8,115,105,103,110,117,109,116,111,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114, + 100,101,114,2,4,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,128,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,39,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 115,97,118,101,118,97,108,117,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,18,115,105,103,110,117,109,116,111,111,110,115,101,116,118,97,108,117, + 101,8,118,97,108,117,101,109,97,120,3,255,0,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,9,116,115,101,108,101,99,116,111, + 114,7,115,105,103,110,97,109,101,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0, + 144,0,0,8,116,97,98,111,114,100,101,114,2,5,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,168,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,145,2,9, + 98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0, + 19,100,114,111,112,100,111,119,110,105,116,101,109,115,46,99,111,117,110,116, + 2,2,19,100,114,111,112,100,111,119,110,105,116,101,109,115,46,105,116,101, + 109,115,14,1,0,1,0,0,10,111,110,115,101,116,118,97,108,117,101,7, + 17,115,105,103,110,97,109,101,111,110,115,101,116,118,97,108,117,101,19,100, + 114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1, + 19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115, + 14,1,5,119,105,100,116,104,2,100,0,0,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,0,8,116,116,97,98,112,97,103, + 101,9,116,116,97,98,112,97,103,101,56,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112, + 104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108, + 101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,51, + 1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,7,99,97,112,116,105,111,110,6,11,38,69,120,99,101, + 112,116,105,111,110,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,11,116,119,105,100,103,101,116,103,114,105,100,14,101,120,99,101, + 112,116,105,111,110,115,103,114,105,100,5,99,111,108,111,114,4,3,0,0, + 128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,51,1,7, + 97,110,99,104,111,114,115,11,0,11,111,112,116,105,111,110,115,103,114,105, + 100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,15,111,103,95,107, + 101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110, + 115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105, + 110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116, + 101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111, + 103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99, + 104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97, + 112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102, + 105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111, + 119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14, + 99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,2,14,99,97,112, + 116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111, + 110,6,6,105,103,110,111,114,101,0,1,7,99,97,112,116,105,111,110,6, + 15,69,120,99,101,112,116,105,111,110,32,99,108,97,115,115,0,0,0,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,12,101,120,99,101,112,116,105,103, + 110,111,114,101,1,5,119,105,100,116,104,2,47,7,111,112,116,105,111,110, + 115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,12,101,120,99,101, + 112,116,105,103,110,111,114,101,9,100,97,116,97,99,108,97,115,115,7,20, + 116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116, + 0,7,16,101,120,99,101,112,116,99,108,97,115,115,110,97,109,101,115,1, + 5,119,105,100,116,104,3,9,3,7,111,112,116,105,111,110,115,11,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,0,10,119,105,100,103,101, + 116,110,97,109,101,6,16,101,120,99,101,112,116,99,108,97,115,115,110,97, + 109,101,115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100, + 109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13, + 100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116, + 102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,12,101,120,99,101,112,116,105,103,110,111,114,101,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,47,9,98,111,117,110,100,115,95, + 99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,16,101,120,99,101,112,116,99,108, + 97,115,115,110,97,109,101,115,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97, + 98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,2,48,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,9,3,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 12,111,101,95,116,114,105,109,114,105,103,104,116,11,111,101,95,116,114,105, + 109,108,101,102,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,0,0,8,116,116,97,98,112,97,103,101,10,116,116,97,98, + 112,97,103,101,49,54,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108, + 111,114,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105, + 110,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100, + 101,114,2,5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9, + 98,111,117,110,100,115,95,99,121,3,51,1,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,22,116,97,98, + 111,114,100,101,114,111,118,101,114,114,105,100,101,46,105,116,101,109,115,1, + 6,13,117,112,108,111,97,100,99,111,109,109,97,110,100,6,14,103,100,98, + 108,111,97,100,116,105,109,101,111,117,116,6,14,103,100,98,108,111,97,100, + 116,105,109,101,111,117,116,6,16,103,100,98,115,101,114,118,101,114,99,111, + 109,109,97,110,100,6,16,103,100,98,115,101,114,118,101,114,99,111,109,109, + 97,110,100,6,13,103,100,98,115,101,114,118,101,114,119,97,105,116,6,18, + 103,100,98,115,101,114,118,101,114,115,116,97,114,116,111,110,99,101,6,22, + 103,100,98,115,101,114,118,101,114,99,111,109,109,97,110,100,97,116,116,97, + 99,104,6,22,103,100,98,115,101,114,118,101,114,99,111,109,109,97,110,100, + 97,116,116,97,99,104,6,15,110,111,103,100,98,115,101,114,118,101,114,101, + 120,105,116,0,7,99,97,112,116,105,111,110,6,7,38,84,97,114,103,101, + 116,8,111,110,108,97,121,111,117,116,7,19,100,101,98,117,103,116,97,114, + 103,101,116,108,97,121,111,117,116,101,118,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,11,116,115,116,114,105,110,103,101,100,105,116, + 16,114,101,109,111,116,101,99,111,110,110,101,99,116,105,111,110,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,17,84,97,114,103,101,116,32, + 99,111,110,110,101,99,116,105,111,110,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116,105,111,110,111, + 102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,4,104,105,110,116,6,37,34,45,45,116,116,121,32,68,69, + 86,73,67,69,34,32,116,111,32,115,101,116,32,116,97,114,103,101,116,32, + 116,101,114,109,105,110,97,108,10,111,110,115,104,111,119,104,105,110,116,7, + 18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8, + 98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2, + 112,9,98,111,117,110,100,115,95,99,120,3,60,3,9,98,111,117,110,100, + 115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116, + 108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,52,5, + 99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114, + 108,95,111,112,116,105,111,110,115,115,107,105,110,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,192,0,9, + 98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95, + 99,121,2,37,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95, + 101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0, + 13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95, + 97,108,105,103,110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9, + 119,97,109,95,115,116,97,114,116,10,108,105,110,107,98,111,116,116,111,109, + 7,10,116,108,97,121,111,117,116,101,114,53,0,13,116,102,105,108,101,110, + 97,109,101,101,100,105,116,13,98,101,102,111,114,101,99,111,110,110,101,99, + 116,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,25,66,101,102, + 111,114,101,32,99,111,110,110,101,99,116,32,103,100,98,32,115,99,114,105, + 112,116,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116, + 102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0, + 0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101, + 46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102, + 114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2, + 17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,17,2,0,2,0,0,10,111,110,115,104,111,119,104,105,110,116,7, + 18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8, + 98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,214,0,9,98,111,117,110,100, + 115,95,99,121,2,37,9,116,101,120,116,102,108,97,103,115,11,12,116,102, + 95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101, + 99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,26,99, + 111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116, + 46,100,97,116,97,1,1,6,11,103,100,98,32,83,99,114,105,112,116,115, + 6,5,42,46,103,100,98,0,0,18,99,111,110,116,114,111,108,108,101,114, + 46,111,112,116,105,111,110,115,11,14,102,100,111,95,99,104,101,99,107,101, + 120,105,115,116,15,102,100,111,95,115,97,118,101,108,97,115,116,100,105,114, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9, + 116,115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116,101,114,55, + 5,99,111,108,111,114,4,3,0,0,144,8,116,97,98,111,114,100,101,114, + 2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,215,0,8,98,111,117,110,100,115,95,121,2,17,9,98,111,117,110,100, + 115,95,99,120,2,3,9,98,111,117,110,100,115,95,99,121,2,20,7,111, + 112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111,112,12,115,112, + 111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100,111,99,107,116, + 111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116,14,115,112,111, + 95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110,107,108,101,102, + 116,7,13,98,101,102,111,114,101,99,111,110,110,101,99,116,9,108,105,110, + 107,114,105,103,104,116,7,10,98,101,102,111,114,101,108,111,97,100,0,0, + 13,116,102,105,108,101,110,97,109,101,101,100,105,116,10,98,101,102,111,114, + 101,108,111,97,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 22,66,101,102,111,114,101,32,108,111,97,100,32,103,100,98,32,115,99,114, + 105,112,116,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120, + 116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2, + 0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109, + 101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20, + 102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114, + 2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2, + 10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112, + 97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120, + 3,218,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,221,0,9,98,111,117,110,100,115,95,99,121,2,37,9, + 116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101, + 114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101, + 108,108,105,112,115,101,108,101,102,116,0,26,99,111,110,116,114,111,108,108, + 101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1, + 6,11,103,100,98,32,83,99,114,105,112,116,115,6,5,42,46,103,100,98, + 0,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110, + 115,11,14,102,100,111,95,99,104,101,99,107,101,120,105,115,116,15,102,100, + 111,95,115,97,118,101,108,97,115,116,100,105,114,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,112,108,105,116,116, + 101,114,10,116,115,112,108,105,116,116,101,114,57,5,99,111,108,111,114,4, + 3,0,0,144,8,116,97,98,111,114,100,101,114,2,3,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,183,1,8,98,111,117, + 110,100,115,95,121,2,17,9,98,111,117,110,100,115,95,99,120,2,3,9, + 98,111,117,110,100,115,95,99,121,2,20,7,111,112,116,105,111,110,115,11, + 9,115,112,111,95,104,112,114,111,112,12,115,112,111,95,100,111,99,107,108, + 101,102,116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112,111,95, + 100,111,99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107,98,111, + 116,116,111,109,0,8,108,105,110,107,108,101,102,116,7,10,98,101,102,111, + 114,101,108,111,97,100,9,108,105,110,107,114,105,103,104,116,7,9,98,101, + 102,111,114,101,114,117,110,0,0,13,116,102,105,108,101,110,97,109,101,101, + 100,105,116,9,98,101,102,111,114,101,114,117,110,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,21,66,101,102,111,114,101,32,114,117,110,32, + 103,100,98,32,115,99,114,105,112,116,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5, + 99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17, + 0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98, + 111,114,100,101,114,2,4,10,111,110,115,104,111,119,104,105,110,116,7,18, + 104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98, + 111,117,110,100,115,95,120,3,186,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,131,1,9,98,111,117,110,100, + 115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116, + 101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95, + 101,108,108,105,112,115,101,108,101,102,116,0,26,99,111,110,116,114,111,108, + 108,101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1, + 1,6,11,103,100,98,32,83,99,114,105,112,116,115,6,5,42,46,103,100, + 98,0,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111, + 110,115,11,14,102,100,111,95,99,104,101,99,107,101,120,105,115,116,15,102, + 100,111,95,115,97,118,101,108,97,115,116,100,105,114,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,108,97,121,111, + 117,116,101,114,10,116,108,97,121,111,117,116,101,114,53,5,99,111,108,111, + 114,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108, + 101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111, + 112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104, + 116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116, + 111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,28,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112, + 116,105,111,110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,3,243,0,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,2,37, + 7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112, + 116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97, + 110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116, + 105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,97,108,105,103, + 110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95, + 115,116,97,114,116,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116, + 12,97,102,116,101,114,99,111,110,110,101,99,116,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,24,65,102,116,101,114,32,99,111,110,110,101, + 99,116,32,103,100,98,32,115,99,114,105,112,116,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105, + 103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111, + 116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,10, + 111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97, + 110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120,2, + 1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,214,0,9,98,111,117,110,100,115,95,99,121,2,37,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101, + 100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101,108,108, + 105,112,115,101,108,101,102,116,0,26,99,111,110,116,114,111,108,108,101,114, + 46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,11, + 103,100,98,32,83,99,114,105,112,116,115,6,5,42,46,103,100,98,0,0, + 18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11, + 14,102,100,111,95,99,104,101,99,107,101,120,105,115,116,15,102,100,111,95, + 115,97,118,101,108,97,115,116,100,105,114,0,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,9,116,115,112,108,105,116,116,101,114, + 10,116,115,112,108,105,116,116,101,114,56,5,99,111,108,111,114,4,3,0, + 0,144,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,215,0,8,98,111,117,110,100, + 115,95,121,2,17,9,98,111,117,110,100,115,95,99,120,2,3,9,98,111, + 117,110,100,115,95,99,121,2,20,7,111,112,116,105,111,110,115,11,9,115, + 112,111,95,104,112,114,111,112,12,115,112,111,95,100,111,99,107,108,101,102, + 116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112,111,95,100,111, + 99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107,98,111,116,116, + 111,109,0,8,108,105,110,107,108,101,102,116,7,12,97,102,116,101,114,99, + 111,110,110,101,99,116,9,108,105,110,107,114,105,103,104,116,7,9,97,102, + 116,101,114,108,111,97,100,0,0,13,116,102,105,108,101,110,97,109,101,101, + 100,105,116,9,97,102,116,101,114,108,111,97,100,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,21,65,102,116,101,114,32,108,111,97,100,32, + 103,100,98,32,115,99,114,105,112,116,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5, + 99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17, + 0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98, + 111,114,100,101,114,2,2,10,111,110,115,104,111,119,104,105,110,116,7,18, + 104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98, + 111,117,110,100,115,95,120,3,218,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,221,0,9,98,111,117,110,100, + 115,95,99,121,2,37,9,116,101,120,116,102,108,97,103,115,11,12,116,102, + 95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101, + 99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,26,99, + 111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116, + 46,100,97,116,97,1,1,6,11,103,100,98,32,83,99,114,105,112,116,115, + 6,5,42,46,103,100,98,0,0,18,99,111,110,116,114,111,108,108,101,114, + 46,111,112,116,105,111,110,115,11,14,102,100,111,95,99,104,101,99,107,101, + 120,105,115,116,15,102,100,111,95,115,97,118,101,108,97,115,116,100,105,114, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9, + 116,115,112,108,105,116,116,101,114,11,116,115,112,108,105,116,116,101,114,49, + 48,5,99,111,108,111,114,4,3,0,0,144,8,116,97,98,111,114,100,101, + 114,2,3,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,3,183,1,8,98,111,117,110,100,115,95,121,2,17,9,98,111,117,110, + 100,115,95,99,120,2,3,9,98,111,117,110,100,115,95,99,121,2,20,7, + 111,112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111,112,12,115, + 112,111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100,111,99,107, + 116,111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116,14,115,112, + 111,95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110,107,108,101, + 102,116,7,9,97,102,116,101,114,108,111,97,100,0,0,0,9,116,108,97, + 121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,51,5,99,111, + 108,111,114,4,3,0,0,128,17,102,114,97,109,101,46,102,114,97,109,101, + 105,95,108,101,102,116,2,1,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,102,105,108,101,102,116,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107, + 105,110,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,3,149,0,9,98,111,117,110,100,115,95,99,120,3,106, + 2,9,98,111,117,110,100,115,95,99,121,2,43,12,111,112,116,105,111,110, + 115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11, + 111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97, + 110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116, + 105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99, + 101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110, + 95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112,108,97, + 99,101,95,109,105,110,100,105,115,116,2,5,13,112,108,97,99,101,95,109, + 97,120,100,105,115,116,2,5,7,108,105,110,107,116,111,112,7,16,114,101, + 109,111,116,101,99,111,110,110,101,99,116,105,111,110,10,108,105,110,107,98, + 111,116,116,111,109,7,10,116,108,97,121,111,117,116,101,114,52,0,17,116, + 100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,12,103,100,98, + 112,114,111,99,101,115,115,111,114,13,102,114,97,109,101,46,111,112,116,105, + 111,110,115,11,10,99,102,111,95,102,105,120,116,111,112,0,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,9,80,114,111,99,101,115,115,111, + 114,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,2,0,0,128,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114, + 4,2,0,0,128,0,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,10,111,110,115,104,111, + 119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109, + 97,99,114,111,115,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,84,9, + 98,111,117,110,100,115,95,99,121,2,37,8,111,110,99,104,97,110,103,101, + 7,15,112,114,111,99,101,115,115,111,114,99,104,97,110,103,101,5,118,97, + 108,117,101,6,4,105,51,56,54,16,100,114,111,112,100,111,119,110,46,111, + 112,116,105,111,110,115,11,16,100,101,111,95,97,117,116,111,100,114,111,112, + 100,111,119,110,15,100,101,111,95,107,101,121,100,114,111,112,100,111,119,110, + 0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110, + 116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116, + 101,109,115,14,1,4,100,97,116,97,1,6,4,97,117,116,111,6,4,105, + 51,56,54,6,6,120,56,54,95,54,52,6,3,97,114,109,6,5,97,114, + 109,109,51,6,5,99,112,117,51,50,6,5,97,118,114,51,50,6,4,114, + 108,55,56,0,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,12,103,100, + 98,115,105,109,117,108,97,116,111,114,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,9,83,105,109,117,108,97,116,111,114,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,62,2,2,0,8,116,97,98,111,114,100,101, + 114,2,1,8,98,111,117,110,100,115,95,120,2,90,8,98,111,117,110,100, + 115,95,121,2,20,9,98,111,117,110,100,115,95,99,120,2,75,9,98,111, + 117,110,100,115,95,99,121,2,16,8,111,110,99,104,97,110,103,101,7,14, + 100,111,119,110,108,111,97,100,99,104,97,110,103,101,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,11,103,100,98,100,111,119,110,108,111,97, + 100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,103,100,98, + 32,100,111,119,110,108,111,97,100,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114, + 105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98, + 111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,91,2,2,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,3,170,0,8,98,111,117,110,100,115,95,121,2,20, + 9,98,111,117,110,100,115,95,99,120,2,104,9,98,111,117,110,100,115,95, + 99,121,2,16,8,111,110,99,104,97,110,103,101,7,14,100,111,119,110,108, + 111,97,100,99,104,97,110,103,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,14,100,111,119,110,108,111,97,100,97,108,119,97,121,115,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,26,65,108,119,97,121, + 115,32,100,111,119,110,108,111,97,100,10,98,101,102,111,114,101,32,114,117, + 110,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,8,2,108,2,9,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,3,23,1,8,98,111,117,110,100,115,95,121,2, + 13,9,98,111,117,110,100,115,95,99,120,2,121,9,98,111,117,110,100,115, + 95,99,121,2,30,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116, + 11,115,116,97,114,116,117,112,98,107,112,116,13,102,114,97,109,101,46,111, + 112,116,105,111,110,115,11,10,99,102,111,95,102,105,120,116,111,112,0,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,83,116,97,114,116, + 117,112,32,66,75,80,84,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111, + 109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,5,8, + 98,111,117,110,100,115,95,120,3,244,1,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,121,2,37,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,13,115,116,97,114,116,117,112,98,107,112, + 116,111,110,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100, + 101,114,2,6,8,98,111,117,110,100,115,95,120,3,93,2,8,98,111,117, + 110,100,115,95,121,2,21,8,111,110,99,104,97,110,103,101,7,14,100,111, + 119,110,108,111,97,100,99,104,97,110,103,101,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,20,114,101,115,116,97,114,116,103,100,98,98,101, + 102,111,114,101,108,111,97,100,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,23,82,101,115,116,97,114,116,32,103,100,98,10,98,101,102,111, + 114,101,32,108,111,97,100,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,8,2,77,2,9,0,8,116,97,98,111,114,100, + 101,114,2,4,8,98,111,117,110,100,115,95,120,3,149,1,8,98,111,117, + 110,100,115,95,121,2,13,9,98,111,117,110,100,115,95,99,120,2,90,9, + 98,111,117,110,100,115,95,99,121,2,30,0,0,0,9,116,108,97,121,111, + 117,116,101,114,16,100,111,119,110,108,111,97,100,108,97,121,111,117,116,101, + 114,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100, + 115,95,99,120,3,97,2,9,98,111,117,110,100,115,95,99,121,2,111,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95, + 116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105,111,110, + 115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111, + 117,116,11,10,108,97,111,95,112,108,97,99,101,121,0,13,112,108,97,99, + 101,95,109,97,120,100,105,115,116,2,0,9,108,105,110,107,114,105,103,104, + 116,7,17,116,101,120,112,97,110,100,105,110,103,119,105,100,103,101,116,49, + 10,108,105,110,107,98,111,116,116,111,109,7,16,114,101,109,111,116,101,99, + 111,110,110,101,99,116,105,111,110,10,100,105,115,116,95,114,105,103,104,116, + 2,2,7,111,112,116,105,111,110,115,11,14,115,112,97,111,95,103,108,117, + 101,114,105,103,104,116,0,0,13,116,102,105,108,101,110,97,109,101,101,100, + 105,116,22,103,100,98,115,101,114,118,101,114,99,111,109,109,97,110,100,97, + 116,116,97,99,104,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,111, + 112,116,105,111,110,115,11,10,99,102,111,95,102,105,120,116,111,112,0,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,38,83,116,97,114,116, + 32,103,100,98,32,115,101,114,118,101,114,32,99,111,109,109,97,110,100,32, + 97,116,116,97,99,104,32,116,97,114,103,101,116,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116,105, + 111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116, + 2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101, + 109,115,14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103, + 101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110, + 46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117, + 116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,2,10,111,110,115,104,111,119,104, + 105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99, + 114,111,115,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,74,9,98,111,117,110,100,115,95,99,120,3,97,2,9,98, + 111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121, + 99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116, + 14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,18,99,111,110, + 116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,10,102,100,111, + 95,112,97,114,97,109,115,0,26,99,111,110,116,114,111,108,108,101,114,46, + 104,105,115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108, + 101,110,97,109,101,101,100,105,116,16,103,100,98,115,101,114,118,101,114,99, + 111,109,109,97,110,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46, + 111,112,116,105,111,110,115,11,10,99,102,111,95,102,105,120,116,111,112,0, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,35,83,116,97,114, + 116,32,103,100,98,32,115,101,114,118,101,114,32,99,111,109,109,97,110,100, + 32,114,117,110,32,116,97,114,103,101,116,22,102,114,97,109,101,46,99,97, + 112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98, + 111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116,105,111,110, + 111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105, + 103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111, + 116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110, + 116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111, + 115,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,37,9,98,111,117,110,100,115,95,99,120,3,97,2,9,98,111,117, + 110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116, + 102,95,101,108,108,105,112,115,101,108,101,102,116,0,18,99,111,110,116,114, + 111,108,108,101,114,46,111,112,116,105,111,110,115,11,10,102,100,111,95,112, + 97,114,97,109,115,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105, + 115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101,110, + 97,109,101,101,100,105,116,13,117,112,108,111,97,100,99,111,109,109,97,110, + 100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,111,112,116,105,111, + 110,115,11,10,99,102,111,95,102,105,120,116,111,112,0,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,16,68,111,119,110,108,111,97,100,32, + 99,111,109,109,97,110,100,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111, + 109,0,19,102,114,97,109,101,46,99,97,112,116,105,111,110,111,102,102,115, + 101,116,2,3,15,102,114,97,109,101,46,102,111,110,116,46,110,97,109,101, + 6,11,115,116,102,95,100,101,102,97,117,108,116,17,102,114,97,109,101,46, + 102,111,110,116,46,120,115,99,97,108,101,2,1,21,102,114,97,109,101,46, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105, + 103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111, + 116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,10, + 111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97, + 110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,97,2,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,0,9,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110, + 111,115,101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101, + 102,116,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111, + 110,115,11,10,102,100,111,95,112,97,114,97,109,115,0,26,99,111,110,116, + 114,111,108,108,101,114,46,104,105,115,116,111,114,121,109,97,120,99,111,117, + 110,116,2,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,0,16,116,101,120,112,97,110,100,105,110,103,119,105,100,103,101,116, + 17,116,101,120,112,97,110,100,105,110,103,119,105,100,103,101,116,49,8,116, + 97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,100, + 2,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100,115,95, + 99,120,3,214,0,9,98,111,117,110,100,115,95,99,121,2,111,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107, + 120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104, + 114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105, + 110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107, + 121,0,0,9,116,114,101,97,108,101,100,105,116,14,103,100,98,108,111,97, + 100,116,105,109,101,111,117,116,13,102,114,97,109,101,46,111,112,116,105,111, + 110,115,11,10,99,102,111,95,102,105,120,116,111,112,0,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,12,76,111,97,100,32,84,105,109,101, + 111,117,116,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120, + 116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 14,2,0,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,86,9,98, + 111,117,110,100,115,95,99,121,2,37,5,118,97,108,117,101,5,0,0,0, + 0,0,0,0,128,255,255,12,118,97,108,117,101,100,101,102,97,117,108,116, + 5,0,0,0,0,0,0,0,128,255,255,10,102,111,114,109,97,116,101,100, + 105,116,6,3,48,46,35,10,102,111,114,109,97,116,100,105,115,112,6,6, + 48,46,35,115,101,99,10,118,97,108,117,101,114,97,110,103,101,2,1,10, + 118,97,108,117,101,115,116,97,114,116,2,0,8,118,97,108,117,101,109,105, + 110,5,0,0,0,0,0,0,0,128,255,255,8,118,97,108,117,101,109,97, + 120,3,200,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,9,116,108,97,121,111,117,116,101,114,8,115,101,114,118,101,114,108, + 97,5,99,111,108,111,114,4,3,0,0,128,17,102,114,97,109,101,46,102, + 114,97,109,101,105,95,108,101,102,116,2,1,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,102,105,108,101,102, + 116,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116, + 17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 28,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112,116,105,111, + 110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,37,9,98,111,117,110,100,115,95,99, + 120,3,214,0,9,98,111,117,110,100,115,95,99,121,2,37,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101, + 120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,17,111, + 115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99, + 95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111,112,116,105, + 111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101, + 120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95, + 103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112,108,97,99, + 101,95,109,105,110,100,105,115,116,2,2,13,112,108,97,99,101,95,109,97, + 120,100,105,115,116,2,2,13,112,108,97,99,101,95,111,112,116,105,111,110, + 115,11,13,112,108,111,95,101,110,100,109,97,114,103,105,110,0,7,108,105, + 110,107,116,111,112,7,14,103,100,98,108,111,97,100,116,105,109,101,111,117, + 116,0,9,116,114,101,97,108,101,100,105,116,13,103,100,98,115,101,114,118, + 101,114,119,97,105,116,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,19,87,97,105,116,32,98,101,102,111,114,101,32,99,111,110,110,101,99, + 116,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97,98,108, + 101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,58,2, + 0,0,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,129,0,9,98,111, + 117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,118,97,108,117, + 101,2,0,12,118,97,108,117,101,100,101,102,97,117,108,116,5,0,0,0, + 0,0,0,0,128,255,255,10,102,111,114,109,97,116,101,100,105,116,6,3, + 48,46,35,10,102,111,114,109,97,116,100,105,115,112,6,6,48,46,35,115, + 101,99,10,118,97,108,117,101,114,97,110,103,101,2,1,10,118,97,108,117, + 101,115,116,97,114,116,2,0,8,118,97,108,117,101,109,105,110,2,0,8, + 118,97,108,117,101,109,97,120,3,200,0,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,18,103,100,98,115,101,114,118,101,114,115,116,97,114,116,111,110,99, + 101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10,83,116,97, + 114,116,32,111,110,99,101,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,2,69,2,2,0,8,116,97,98,111,114,100, + 101,114,2,1,8,98,111,117,110,100,115,95,120,3,132,0,8,98,111,117, + 110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120,2,82,9, + 98,111,117,110,100,115,95,99,121,2,16,0,0,0,9,116,108,97,121,111, + 117,116,101,114,10,116,108,97,121,111,117,116,101,114,50,5,99,111,108,111, + 114,4,3,0,0,128,17,102,114,97,109,101,46,102,114,97,109,101,105,95, + 108,101,102,116,2,1,18,102,114,97,109,101,46,102,114,97,109,101,105,95, + 114,105,103,104,116,2,2,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,102,105,108,101,102,116,11,102,114,108, + 95,102,105,114,105,103,104,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,74,9,98,111,117,110,100,115,95,99,120,3,164,0,9,98,111,117,110, + 100,115,95,99,121,2,37,12,111,112,116,105,111,110,115,115,99,97,108,101, + 11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104, + 114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115, + 99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104, + 114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116, + 11,10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105, + 103,110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109, + 95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116, + 2,2,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,2,13,112, + 108,97,99,101,95,111,112,116,105,111,110,115,11,15,112,108,111,95,110,111, + 105,110,118,105,115,105,98,108,101,0,7,108,105,110,107,116,111,112,7,8, + 115,101,114,118,101,114,108,97,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,15,110,111,103,100,98,115,101,114,118,101,114,101,120,105,116,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,16,110,111,32,119,97,105, + 116,32,102,111,114,32,101,120,105,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,1,2,95,2,2,0,8,98,111,117, + 110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,20,9,98, + 111,117,110,100,115,95,99,120,2,108,9,98,111,117,110,100,115,95,99,121, + 2,16,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,0,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,12,103,100,98,115,101,114,118,101,114,116,116,121,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,84,84,89,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,24,2,2, + 0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,2,111,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100, + 115,95,99,120,2,37,9,98,111,117,110,100,115,95,99,121,2,16,0,0, + 11,116,115,116,114,105,110,103,101,100,105,116,12,116,115,116,114,105,110,103, + 101,100,105,116,49,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,29,111,119,49,95, + 105,110,118,105,115,105,98,108,101,112,97,114,101,110,116,115,105,122,101,101, + 120,116,101,110,100,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,1,97,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120, + 116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,150,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,12,9, + 98,111,117,110,100,115,95,99,121,2,37,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,0,0,0,9,116,108,97,121,111,117, + 116,101,114,10,116,108,97,121,111,117,116,101,114,49,5,99,111,108,111,114, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,28,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112,116, + 105,111,110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120, + 2,7,8,98,111,117,110,100,115,95,121,3,164,0,9,98,111,117,110,100, + 115,95,99,120,3,232,2,9,98,111,117,110,100,115,95,99,121,2,30,12, + 111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120, + 112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115, + 99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107, + 121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97, + 111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105,103,110,121,0, + 10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97, + 114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116,2,10,13,112, + 108,97,99,101,95,109,97,120,100,105,115,116,2,10,13,112,108,97,99,101, + 95,111,112,116,105,111,110,115,11,15,112,108,111,95,110,111,105,110,118,105, + 115,105,98,108,101,0,10,108,105,110,107,98,111,116,116,111,109,7,11,116, + 116,97,98,119,105,100,103,101,116,49,11,100,105,115,116,95,98,111,116,116, + 111,109,2,10,0,12,116,98,111,111,108,101,97,110,101,100,105,116,15,101, + 120,116,101,114,110,97,108,99,111,110,115,111,108,101,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,17,38,69,120,116,101,114,110,97,108,10, + 67,111,110,115,111,108,101,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,8,2, + 54,2,9,0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110, + 100,115,95,120,3,108,2,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,67,9,98,111,117,110,100,115,95,99,121, + 2,30,8,111,110,99,104,97,110,103,101,7,18,117,112,100,97,116,101,100, + 101,98,117,103,101,110,97,98,108,101,100,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,11,115,104,111,119,99,111,110,115,111,108,101,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,18,83,104,111,119,32,38, + 67,111,110,115,46,10,111,110,32,82,117,110,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,8,2,75,2,9,0,8,116,97,98,111,114,100,101,114,2,5, + 4,104,105,110,116,6,19,83,104,111,119,32,99,111,110,115,111,108,101,32, + 111,110,32,114,117,110,8,98,111,117,110,100,115,95,120,3,219,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 88,9,98,111,117,110,100,115,95,99,121,2,30,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,15,115,116,111,112,111,110,101,120,99,101,112, + 116,105,111,110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,15, + 38,83,116,111,112,10,111,110,32,69,120,99,101,112,46,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,8,2,64,2,9,0,8,116,97,98,111,114,100,101, + 114,2,4,4,104,105,110,116,6,18,83,116,111,112,32,111,110,32,101,120, + 99,101,112,116,105,111,110,115,8,98,111,117,110,100,115,95,120,3,132,1, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,77,9,98,111,117,110,100,115,95,99,121,2,30,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,15,97,99,116,105,118,97,116,101,111, + 110,98,114,101,97,107,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,18,38,65,99,116,105,118,97,116,101,10,111,110,32,66,114,101,97,107, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,8,2,59,2,9,0,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,61,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,72,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116, + 118,97,108,117,101,7,18,97,99,116,105,118,97,116,101,111,110,98,114,101, + 97,107,115,101,116,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 10,118,97,108,117,101,104,105,110,116,115,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,12,38,86,97,108,117,101,10,72,105,110,116,115,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,8, + 2,38,2,9,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,51,9, + 98,111,117,110,100,115,95,99,121,2,30,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,15,110,111,100,101,98,117,103,98,101,103,105,110,101, + 110,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,33,67,97, + 108,108,32,71,85,73,95,68,69,66,85,71,66,69,71,73,78,47,10,71, + 85,73,95,68,69,66,85,71,69,78,68,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,8,3,140,0,2,9,0,8,116, + 97,98,111,114,100,101,114,2,3,4,104,105,110,116,6,74,82,101,108,101, + 97,115,101,32,109,111,117,115,101,32,103,114,97,98,32,98,121,32,116,97, + 114,103,101,116,32,115,116,111,112,46,32,103,100,98,32,115,111,109,101,116, + 105,109,101,115,32,99,114,97,115,104,101,115,32,119,105,116,104,32,116,104, + 105,115,32,111,112,116,105,111,110,46,8,98,111,117,110,100,115,95,120,3, + 225,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,153,0,9,98,111,117,110,100,115,95,99,121,2,30,7,111, + 112,116,105,111,110,115,11,17,98,111,95,101,120,101,99,117,116,101,111,110, + 99,108,105,99,107,15,98,111,95,101,120,101,99,117,116,101,111,110,107,101, + 121,20,98,111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116,99, + 117,116,27,98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108,116, + 111,110,101,110,116,101,114,107,101,121,11,98,111,95,114,101,118,101,114,115, + 101,100,0,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,115, + 101,116,116,116,121,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 8,83,101,116,10,84,84,38,89,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,8,2,24,2,9,0,8,116,97,98,111, + 114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,61,2,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 37,9,98,111,117,110,100,115,95,99,121,2,30,7,118,105,115,105,98,108, + 101,8,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,12,114,97, + 105,115,101,111,110,98,114,101,97,107,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,15,38,82,97,105,115,101,10,111,110,32,66,114,101,97, + 107,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,8,2,59,2,9,0,8,116, + 97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,143, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,72,9,98,111,117,110,100,115,95,99,121,2,30,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,16,102,112,99,103,100,98,119,111, + 114,107,97,114,111,117,110,100,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,9,38,70,80,67,10,98,117,103,115,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,8,2,34,2,9,0,8, + 116,97,98,111,114,100,101,114,2,8,4,104,105,110,116,6,32,85,115,101, + 32,119,111,114,107,97,114,111,117,110,100,115,32,102,111,114,32,70,80,67, + 47,103,100,98,32,98,117,103,115,8,98,111,117,110,100,115,95,120,3,185, + 2,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,47,9,98,111,117,110,100,115,95,99,121,2,30,0,0,0,13, + 116,102,105,108,101,110,97,109,101,101,100,105,116,11,100,101,98,117,103,116, + 97,114,103,101,116,13,102,114,97,109,101,46,111,112,116,105,111,110,115,11, + 10,99,102,111,95,102,105,120,116,111,112,13,99,102,111,95,97,117,116,111, + 119,105,100,116,104,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,39,68,101,98,117,103,32,38,116,97,114,103,101,116,32,40,101,109,112, + 116,121,32,61,32,109,97,107,101,32,116,97,114,103,101,116,102,105,108,101, + 41,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97, + 109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2, + 0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109, + 101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20, + 102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114, + 2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3, + 10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112, + 97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120, + 2,1,8,98,111,117,110,100,115,95,121,2,104,9,98,111,117,110,100,115, + 95,99,120,3,46,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,18,99,111,110,116,114,111,108, + 108,101,114,46,111,112,116,105,111,110,115,11,0,26,99,111,110,116,114,111, + 108,108,101,114,46,104,105,115,116,111,114,121,109,97,120,99,111,117,110,116, + 2,0,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102, + 105,108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110, + 97,109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,9,116,115,112,108,105,116,116,101,114,19,100,101,98,117,103,116,97,114, + 103,101,116,115,112,108,105,116,116,101,114,5,99,111,108,111,114,4,3,0, + 0,144,8,116,97,98,111,114,100,101,114,2,7,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,47,1,8,98,111,117,110,100, + 115,95,121,2,109,9,98,111,117,110,100,115,95,99,120,2,3,9,98,111, + 117,110,100,115,95,99,121,2,34,7,111,112,116,105,111,110,115,11,9,115, + 112,111,95,104,112,114,111,112,12,115,112,111,95,100,111,99,107,108,101,102, + 116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112,111,95,100,111, + 99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107,98,111,116,116, + 111,109,0,8,108,105,110,107,108,101,102,116,7,11,100,101,98,117,103,116, + 97,114,103,101,116,9,108,105,110,107,114,105,103,104,116,7,12,120,116,101, + 114,109,99,111,109,109,97,110,100,0,0,15,116,109,101,109,111,100,105,97, + 108,111,103,101,100,105,116,12,120,116,101,114,109,99,111,109,109,97,110,100, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,13,120,116,101,114, + 109,32,99,111,109,109,97,110,100,22,102,114,97,109,101,46,99,97,112,116, + 105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116, + 116,111,109,9,116,102,95,103,114,97,121,101,100,0,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,7,105,109, + 97,103,101,110,114,2,17,0,0,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,4,10,111,110,115,104,111,119,104,105,110, + 116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111, + 115,7,101,110,97,98,108,101,100,8,8,98,111,117,110,100,115,95,120,3, + 50,1,8,98,111,117,110,100,115,95,121,2,104,9,98,111,117,110,100,115, + 95,99,120,3,11,2,9,98,111,117,110,100,115,95,99,121,2,37,7,97, + 110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,18,115,101,116, + 120,116,101,114,109,99,111,109,109,97,110,100,101,120,101,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,112,108,105,116, + 116,101,114,13,100,101,98,117,103,115,112,108,105,116,116,101,114,5,99,111, + 108,111,114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2,8,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,47,1, + 8,98,111,117,110,100,115,95,121,2,69,9,98,111,117,110,100,115,95,99, + 120,2,3,9,98,111,117,110,100,115,95,99,121,2,26,7,111,112,116,105, + 111,110,115,11,9,115,112,111,95,104,112,114,111,112,12,115,112,111,95,100, + 111,99,107,108,101,102,116,11,115,112,111,95,100,111,99,107,116,111,112,13, + 115,112,111,95,100,111,99,107,114,105,103,104,116,14,115,112,111,95,100,111, + 99,107,98,111,116,116,111,109,0,8,108,105,110,107,108,101,102,116,7,12, + 100,101,98,117,103,99,111,109,109,97,110,100,9,108,105,110,107,114,105,103, + 104,116,7,12,100,101,98,117,103,111,112,116,105,111,110,115,0,0,13,116, + 102,105,108,101,110,97,109,101,101,100,105,116,10,114,117,110,99,111,109,109, + 97,110,100,13,102,114,97,109,101,46,111,112,116,105,111,110,115,11,10,99, + 102,111,95,102,105,120,116,111,112,13,99,102,111,95,97,117,116,111,119,105, + 100,116,104,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,37, + 38,82,117,110,32,99,111,109,109,97,110,100,32,40,101,109,112,116,121,32, + 61,32,115,116,97,114,116,32,100,101,98,117,103,103,101,114,41,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97,109,101,46,99, + 97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108, + 101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99, + 111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128,7, + 105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117, + 116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109, + 101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105, + 110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117, + 110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,21,9,98, + 111,117,110,100,115,95,99,120,3,60,3,9,98,111,117,110,100,115,95,99, + 121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,8,111,110, + 99,104,97,110,103,101,7,18,117,112,100,97,116,101,100,101,98,117,103,101, + 110,97,98,108,101,100,18,99,111,110,116,114,111,108,108,101,114,46,111,112, + 116,105,111,110,115,11,10,102,100,111,95,112,97,114,97,109,115,0,26,99, + 111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114,121,109,97,120, + 99,111,117,110,116,2,0,24,99,111,110,116,114,111,108,108,101,114,46,111, + 110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112,97,110,100, + 102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,0,8,116,116,97,98,112,97,103,101,8,109,97,107, + 101,112,97,103,101,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,6,8, + 98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2, + 20,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100, + 115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,6,97,110,95, + 116,111,112,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105, + 111,110,6,5,38,77,97,107,101,8,111,110,108,97,121,111,117,116,7,21, + 109,97,107,101,112,97,103,101,111,110,99,104,105,108,100,115,99,97,108,101, + 100,0,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,50,5, + 99,111,108,111,114,4,3,0,0,128,8,116,97,98,111,114,100,101,114,2, + 18,8,98,111,117,110,100,115,95,120,3,85,1,8,98,111,117,110,100,115, + 95,121,2,108,9,98,111,117,110,100,115,95,99,120,2,10,9,98,111,117, + 110,100,115,95,99,121,2,26,8,108,105,110,107,108,101,102,116,7,9,99, + 111,108,111,114,110,111,116,101,9,108,105,110,107,114,105,103,104,116,7,12, + 99,111,112,121,109,101,115,115,97,103,101,115,0,0,9,116,101,110,117,109, + 101,100,105,116,11,100,101,102,97,117,108,116,109,97,107,101,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,16,68, + 101,102,97,117,108,116,32,109,97,107,101,32,99,111,108,22,102,114,97,109, + 101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9, + 116,102,95,98,111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112, + 116,105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,2,0,0,128,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0, + 128,0,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,17,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2, + 11,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,2,123,9,98,111,117,110,100,115,95,99,120,2,110,9,98,111,117,110, + 100,115,95,99,121,2,37,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111, + 101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15, + 111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101, + 110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,9,116,101,120,116,102,108,97,103,115, + 11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99, + 101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,0, + 16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,14,100, + 101,111,95,115,101,108,101,99,116,111,110,108,121,15,100,101,111,95,102,111, + 114,99,101,115,101,108,101,99,116,16,100,101,111,95,97,117,116,111,100,114, + 111,112,100,111,119,110,0,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,105,116,101,109,115,14,1,4,100,97,116,97,1,6,8,77, + 32,40,77,97,107,101,41,6,9,66,32,40,66,117,105,108,100,41,6,10, + 49,32,40,77,97,107,101,32,49,41,6,10,50,32,40,77,97,107,101,32, + 50,41,6,10,51,32,40,77,97,107,101,32,51,41,6,10,52,32,40,77, + 97,107,101,32,52,41,6,4,78,111,110,101,0,0,0,5,118,97,108,117, + 101,2,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,8,109,97,105,110, + 102,105,108,101,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,9,38,77,97,105,110,102,105,108,101,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 9,116,102,95,98,111,116,116,111,109,0,19,102,114,97,109,101,46,99,97, + 112,116,105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101, + 100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111, + 117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128,7,105, + 109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116, + 116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101, + 46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110, + 116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110, + 100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,2,9,98,111, + 117,110,100,115,95,99,120,3,246,0,9,98,111,117,110,100,115,95,99,121, + 2,37,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116, + 102,95,101,108,108,105,112,115,101,108,101,102,116,0,18,99,111,110,116,114, + 111,108,108,101,114,46,111,112,116,105,111,110,115,11,8,102,100,111,95,108, + 105,110,107,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116, + 111,114,121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111, + 108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,15,83,101, + 108,101,99,116,32,109,97,105,110,102,105,108,101,24,99,111,110,116,114,111, + 108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7,14, + 101,120,112,97,110,100,102,105,108,101,110,97,109,101,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101,110,97, + 109,101,101,100,105,116,10,116,97,114,103,101,116,102,105,108,101,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11, + 38,84,97,114,103,101,116,102,105,108,101,22,102,114,97,109,101,46,99,97, + 112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98, + 111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116,105,111,110, + 111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105, + 103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111, + 116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110, + 116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111, + 115,8,98,111,117,110,100,115,95,120,3,250,0,8,98,111,117,110,100,115, + 95,121,2,2,9,98,111,117,110,100,115,95,99,120,3,205,0,9,98,111, + 117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99, + 101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14, + 116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,18,99,111,110,116, + 114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,8,102,100,111,95, + 108,105,110,107,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115, + 116,111,114,121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114, + 111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,18,83, + 101,108,101,99,116,32,116,97,114,103,101,116,32,102,105,108,101,24,99,111, + 110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97, + 109,101,7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105, + 108,101,110,97,109,101,101,100,105,116,11,109,97,107,101,99,111,109,109,97, + 110,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,13,77,97,107,101,32,38,80,114,111,103,114,97,109,22,102, + 114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103, + 115,11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97,109,101,46, + 99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128, + 7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,10,111,110, + 115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100, + 101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120,2,1,8, + 98,111,117,110,100,115,95,121,2,43,9,98,111,117,110,100,115,95,99,120, + 3,246,0,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99,104, + 111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8, + 97,110,95,114,105,103,104,116,0,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115, + 101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116, + 0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115, + 11,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114, + 121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111,108,108, + 101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,19,83,101,108,101, + 99,116,32,109,97,107,101,32,99,111,109,109,97,110,100,24,99,111,110,116, + 114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101, + 7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116, + 111,110,15,115,104,111,119,99,111,109,109,97,110,100,108,105,110,101,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,13,111,119,49,95,97, + 117,116,111,119,105,100,116,104,14,111,119,49,95,97,117,116,111,104,101,105, + 103,104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0, + 0,128,8,116,97,98,111,114,100,101,114,2,12,8,98,111,117,110,100,115, + 95,120,2,109,8,98,111,117,110,100,115,95,121,3,140,0,9,98,111,117, + 110,100,115,95,99,120,3,134,0,9,98,111,117,110,100,115,95,99,121,2, + 20,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,13,97,115,95,108,111,99,97,108,99,111,108,111,114,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97, + 112,116,105,111,110,6,17,83,104,111,119,32,99,111,109,109,97,110,100,32, + 108,105,110,101,9,111,110,101,120,101,99,117,116,101,7,24,115,104,111,119, + 99,111,109,109,97,110,100,108,105,110,101,111,110,101,120,101,99,117,116,101, + 0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,17,109,101,115, + 115,97,103,101,111,117,116,112,117,116,102,105,108,101,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,20,77,101,115, + 115,97,103,101,32,38,111,117,116,112,117,116,32,102,105,108,101,19,102,114, + 97,109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4, + 2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97, + 109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128, + 20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110, + 114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2, + 5,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120, + 112,97,110,100,101,100,109,97,99,114,111,115,7,101,110,97,98,108,101,100, + 8,8,98,111,117,110,100,115,95,120,3,202,1,8,98,111,117,110,100,115, + 95,121,2,43,9,98,111,117,110,100,115,95,99,120,3,115,1,9,98,111, + 117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,9,116,101,120,116, + 102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,11, + 116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101,108,108,105,112, + 115,101,108,101,102,116,0,24,99,111,110,116,114,111,108,108,101,114,46,111, + 110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112,97,110,100, + 102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,12, + 99,111,112,121,109,101,115,115,97,103,101,115,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,22,67,111,112,121,32,109,101,115,115,97,103,101, + 115,32,116,111,32,38,102,105,108,101,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,1,3,140,0,2,2,0,8,116,97,98,111,114,100,101,114,2,9,8, + 98,111,117,110,100,115,95,120,3,95,1,8,98,111,117,110,100,115,95,121, + 2,99,9,98,111,117,110,100,115,95,99,120,3,153,0,9,98,111,117,110, + 100,115,95,99,121,2,16,8,111,110,99,104,97,110,103,101,7,18,99,111, + 112,121,109,101,115,115,97,103,101,99,104,97,110,103,101,100,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,13,99,108,111,115,101,109,101,115, + 115,97,103,101,115,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 35,67,108,111,115,101,32,109,101,115,115,97,103,101,115,32,119,105,110,100, + 111,119,32,97,102,116,101,114,32,99,111,109,112,105,108,101,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,3,240,0,2,2,0,8,116,97,98,111,114, + 100,101,114,2,14,8,98,111,117,110,100,115,95,120,3,1,1,8,98,111, + 117,110,100,115,95,121,3,151,0,9,98,111,117,110,100,115,95,99,120,3, + 253,0,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101, + 9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,12,99,104,101, + 99,107,109,101,116,104,111,100,115,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,20,67,104,101,99,107,32,109,101,116,104,111,100,32,104,101, + 97,100,101,114,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,149,0, + 2,2,0,8,116,97,98,111,114,100,101,114,2,13,8,98,111,117,110,100, + 115,95,120,3,1,1,8,98,111,117,110,100,115,95,121,3,135,0,9,98, + 111,117,110,100,115,95,99,120,3,162,0,9,98,111,117,110,100,115,95,99, + 121,2,16,5,118,97,108,117,101,9,0,0,10,116,116,97,98,119,105,100, + 103,101,116,12,109,97,107,101,103,114,111,117,112,98,111,120,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,3,187,0,9,98,111,117,110,100,115,95,99,120,3, + 62,3,9,98,111,117,110,100,115,95,99,121,3,89,1,7,97,110,99,104, + 111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111, + 109,0,8,116,97,98,111,114,100,101,114,2,15,15,97,99,116,105,118,101, + 112,97,103,101,105,110,100,101,120,2,1,20,116,97,98,95,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112, + 116,105,111,110,115,115,107,105,110,0,21,116,97,98,95,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,19,116,97,98,95,102,97,99,101,46,108,111,99,97,108, + 112,114,111,112,115,11,20,102,97,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,0,9,116,97,98,95,99,111,108,111,114,4,3, + 0,0,128,8,116,97,98,95,115,105,122,101,2,19,8,115,116,97,116,102, + 105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,8,116,116,97,98,112,97,103,101, + 10,116,116,97,98,112,97,103,101,49,55,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 3,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,70,1,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111, + 110,6,14,67,111,109,109,97,110,100,32,98,101,102,111,114,101,0,11,116, + 119,105,100,103,101,116,103,114,105,100,14,98,101,102,99,111,109,109,97,110, + 100,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109, + 111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,19, + 102,114,97,109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2, + 3,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,70,1,12, + 98,111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110,99,104,111, + 114,115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,15,111,103, + 95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119, + 105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101, + 116,105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119,115, + 100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108, + 108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115, + 116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13, + 102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103, + 104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2, + 7,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99, + 97,112,116,105,111,110,6,1,77,4,104,105,110,116,6,11,85,115,101,32, + 105,110,32,77,97,107,101,0,1,7,99,97,112,116,105,111,110,6,1,66, + 4,104,105,110,116,6,12,85,115,101,32,105,110,32,66,117,105,108,100,0, + 1,7,99,97,112,116,105,111,110,6,1,49,4,104,105,110,116,6,13,85, + 115,101,32,105,110,32,77,97,107,101,32,49,0,1,7,99,97,112,116,105, + 111,110,6,1,50,4,104,105,110,116,6,13,85,115,101,32,105,110,32,77, + 97,107,101,32,50,0,1,7,99,97,112,116,105,111,110,6,1,51,4,104, + 105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,51,0,1, + 7,99,97,112,116,105,111,110,6,1,52,4,104,105,110,116,6,13,85,115, + 101,32,105,110,32,77,97,107,101,32,52,0,1,7,99,97,112,116,105,111, + 110,6,7,67,111,109,109,97,110,100,0,0,0,0,14,100,97,116,97,99, + 111,108,115,46,99,111,117,110,116,2,7,16,100,97,116,97,99,111,108,115, + 46,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99, + 117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118, + 101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116, + 101,109,115,14,7,9,98,101,102,109,97,107,101,111,110,1,5,119,105,100, + 116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97, + 119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,9,98,101,102,109,97,107,101,111,110,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,10,98,101,102,98,117,105,108,100,111,110,1, + 5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111, + 95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116, + 12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108, + 116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99, + 116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,10,98,101,102,98,117,105,108,100,111,110,9, + 100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101, + 103,101,114,100,97,116,97,108,105,115,116,0,7,10,98,101,102,109,97,107, + 101,49,111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110, + 115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,10,119,105,100,103,101,116,110,97,109,101,6,10,98,101,102,109,97,107, + 101,49,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105, + 100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,10,98, + 101,102,109,97,107,101,50,111,110,1,5,119,105,100,116,104,2,13,7,111, + 112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99, + 97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,98, + 101,102,109,97,107,101,50,111,110,9,100,97,116,97,99,108,97,115,115,7, + 20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115, + 116,0,7,10,98,101,102,109,97,107,101,51,111,110,1,5,119,105,100,116, + 104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,10,98,101,102,109,97,107,101,51,111,110,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,10,98,101,102,109,97,107,101,52,111,110,1, + 5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111, + 95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116, + 12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108, + 116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99, + 116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,10,98,101,102,109,97,107,101,52,111,110,9, + 100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101, + 103,101,114,100,97,116,97,108,105,115,116,0,7,10,98,101,102,99,111,109, + 109,97,110,100,1,5,119,105,100,116,104,3,229,2,7,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105, + 108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11, + 99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,10,98,101,102,99,111,109,109,97,110,100,9,100,97,116,97,99,108, + 97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100, + 97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,98,101,102,109, + 97,107,101,111,110,3,84,97,103,2,1,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116, + 111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120, + 101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0, + 7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117, + 108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,10,98, + 101,102,98,117,105,108,100,111,110,3,84,97,103,2,2,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49, + 95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107, + 101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116, + 97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100, + 101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,10,98,101,102,109,97,107,101,49,111,110,3,84,97,103,2,4,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,3,8,98,111,117,110,100,115,95,120,2,28,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97, + 108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,10,98,101,102,109,97,107,101,50,111,110,3,84,97, + 103,2,8,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2,42,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121, + 2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101, + 110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101, + 8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,10,98,101,102,109,97,107,101,51,111, + 110,3,84,97,103,2,16,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95, + 120,2,56,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112, + 117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116, + 101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115, + 105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,10,98,101,102,109,97, + 107,101,52,111,110,3,84,97,103,2,32,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117, + 110,100,115,95,120,2,70,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116, + 111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120, + 101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0, + 7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117, + 108,116,9,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100,105, + 116,10,98,101,102,99,111,109,109,97,110,100,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114, + 2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114, + 2,7,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101, + 120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,2,84,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,229,2,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0, + 8,116,116,97,98,112,97,103,101,10,116,116,97,98,112,97,103,101,49,50, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49, + 95,97,117,116,111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,15,102,97,99,101, + 46,108,111,99,97,108,112,114,111,112,115,11,20,102,97,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,0,8,116,97,98,111,114, + 100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3, + 9,98,111,117,110,100,115,95,99,121,3,70,1,7,97,110,99,104,111,114, + 115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97, + 112,116,105,111,110,6,12,77,97,107,101,32,111,112,116,105,111,110,115,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,119,105, + 100,103,101,116,103,114,105,100,15,109,97,107,101,111,112,116,105,111,110,115, + 103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 102,111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111, + 117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,19,102, + 114,97,109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,70,1,12,98, + 111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110,99,104,111,114, + 115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95, + 99,111,108,115,105,122,105,110,103,15,111,103,95,107,101,121,114,111,119,109, + 111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116,105,110, + 103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,23,111,103,95, + 115,101,108,101,99,116,101,100,114,111,119,115,100,101,108,101,116,105,110,103, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95, + 97,117,116,111,97,112,112,101,110,100,10,111,103,95,119,114,97,112,99,111, + 108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,114, + 111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46, + 105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112, + 116,105,111,110,115,46,99,111,117,110,116,2,10,14,99,97,112,116,105,111, + 110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,7, + 80,117,114,112,111,115,101,0,1,7,99,97,112,116,105,111,110,6,1,77, + 4,104,105,110,116,6,11,85,115,101,32,105,110,32,77,97,107,101,0,1, + 7,99,97,112,116,105,111,110,6,1,66,4,104,105,110,116,6,12,85,115, + 101,32,105,110,32,66,117,105,108,100,0,1,7,99,97,112,116,105,111,110, + 6,1,49,4,104,105,110,116,6,13,85,115,101,32,105,110,32,77,97,107, + 101,32,49,0,1,7,99,97,112,116,105,111,110,6,1,50,4,104,105,110, + 116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,50,0,1,7,99, + 97,112,116,105,111,110,6,1,51,4,104,105,110,116,6,13,85,115,101,32, + 105,110,32,77,97,107,101,32,51,0,1,7,99,97,112,116,105,111,110,6, + 1,52,4,104,105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101, + 32,52,0,1,7,99,97,112,116,105,111,110,6,1,65,4,104,105,110,116, + 6,14,65,102,116,101,114,32,109,97,105,110,102,105,108,101,0,1,7,99, + 97,112,116,105,111,110,6,20,67,111,109,109,97,110,100,32,108,105,110,101, + 32,111,112,116,105,111,110,115,0,1,0,0,0,0,14,100,97,116,97,99, + 111,108,115,46,99,111,117,110,116,2,9,16,100,97,116,97,99,111,108,115, + 46,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99, + 117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118, + 101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116, + 101,109,115,14,7,14,109,97,107,101,111,112,116,112,117,114,112,111,115,101, + 1,5,119,105,100,116,104,2,57,7,111,112,116,105,111,110,115,11,12,99, + 111,95,105,110,118,105,115,105,98,108,101,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11, + 99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,14,109,97,107,101,111,112,116,112,117,114,112,111,115,101,9,100,97, + 116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114, + 105,110,103,100,97,116,97,108,105,115,116,20,100,97,116,97,108,105,115,116, + 46,102,97,99,117,108,116,97,116,105,118,101,9,0,7,6,109,97,107,101, + 111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11, + 12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,6,109,97,107,101,111,110,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,7,7,98,117,105,108,100,111,110,1,5,119,105,100,116,104,2, + 13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105, + 120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,10,119,105,100,103,101,116,110,97,109,101,6,7,98,117,105,108,100,111, + 110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110, + 116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,109,97,107,101, + 49,111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115, + 11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,7,109,97,107,101,49,111,110,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,7,109,97,107,101,50,111,110,1,5,119,105,100,116, + 104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95, + 102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,109,97,107,101, + 50,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,109,97, + 107,101,51,111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111, + 110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,7,109,97,107,101,51,111,110,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,7,109,97,107,101,52,111,110,1,5,119,105, + 100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114, + 97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99, + 111,95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,109,97, + 107,101,52,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,8, + 111,112,116,97,102,116,101,114,1,5,119,105,100,116,104,2,13,7,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100, + 116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,8,111,112,116,97,102,116,101,114,9,100, + 97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103, + 101,114,100,97,116,97,108,105,115,116,0,7,11,109,97,107,101,111,112,116, + 105,111,110,115,1,5,119,105,100,116,104,3,157,2,7,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105, + 120,119,105,100,116,104,7,99,111,95,102,105,108,108,12,99,111,95,115,97, + 118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110, + 115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6, + 11,109,97,107,101,111,112,116,105,111,110,115,9,100,97,116,97,99,108,97, + 115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97, + 116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103, + 104,116,2,16,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102, + 105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,11,116,115,116,114,105,110,103,101,100,105,116,14,109,97,107,101,111,112, + 116,112,117,114,112,111,115,101,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101, + 105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,57,9,98,111,117,110,100,115, + 95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100, + 111,110,108,121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,109,97,107,101, + 111,110,3,84,97,103,2,1,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,58,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105, + 115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7,98,117,105,108, + 100,111,110,3,84,97,103,2,2,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,2,72,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111, + 101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15, + 111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118, + 105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116, + 9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7,109,97,107, + 101,49,111,110,3,84,97,103,2,4,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110, + 100,115,95,120,2,86,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7, + 118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108, + 116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7,109,97, + 107,101,50,111,110,3,84,97,103,2,8,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117, + 110,100,115,95,120,2,100,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116, + 111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120, + 101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0, + 7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117, + 108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7,109, + 97,107,101,51,111,110,3,84,97,103,2,16,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111, + 117,110,100,115,95,120,2,114,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117, + 116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101, + 120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97, + 117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7, + 109,97,107,101,52,111,110,3,84,97,103,2,32,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,7,8,98, + 111,117,110,100,115,95,120,3,128,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110, + 115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13, + 111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101, + 99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95, + 97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101, + 121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97, + 116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101, + 102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,8,111,112,116,97,102,116,101,114,3,84,97,103,4,0,0,0,64,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 8,8,98,111,117,110,100,115,95,120,3,142,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101, + 49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97, + 116,114,101,97,100,0,7,118,105,115,105,98,108,101,8,0,0,15,116,109, + 101,109,111,100,105,97,108,111,103,101,100,105,116,11,109,97,107,101,111,112, + 116,105,111,110,115,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114, + 4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114, + 97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0, + 144,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101, + 110,114,2,17,8,116,97,98,111,114,100,101,114,2,9,10,111,110,115,104, + 111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100, + 109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,3,156,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,3,157,2,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101, + 49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,0,0,8,116,116,97,98,112, + 97,103,101,10,116,116,97,98,112,97,103,101,49,49,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115, + 99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98, + 111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99, + 121,3,70,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110, + 95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,11,68,105, + 114,101,99,116,111,114,105,101,115,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,11,116,119,105,100,103,101,116,103,114,105,100,11,117, + 110,105,116,100,105,114,103,114,105,100,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99, + 13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,38,85,110,105,116,44,32,105,110,99,108,117, + 100,101,32,97,110,100,32,108,105,98,114,97,114,121,32,38,100,105,114,101, + 99,116,111,114,105,101,115,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111, + 109,0,19,102,114,97,109,101,46,99,97,112,116,105,111,110,111,102,102,115, + 101,116,2,3,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102, + 116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0, + 0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,46,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,24,1,12,98,111,117,110,100,115,95,99,121,109, + 105,110,2,40,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103, + 114,105,100,11,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103, + 15,111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95, + 114,111,119,100,101,108,101,116,105,110,103,23,111,103,95,115,101,108,101,99, + 116,101,100,114,111,119,115,100,101,108,101,116,105,110,103,19,111,103,95,102, + 111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97, + 117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97, + 112,112,101,110,100,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95, + 97,117,116,111,112,111,112,117,112,0,13,102,105,120,114,111,119,115,46,99, + 111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115, + 14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115, + 46,99,111,117,110,116,2,11,14,99,97,112,116,105,111,110,115,46,105,116, + 101,109,115,14,1,7,99,97,112,116,105,111,110,6,1,77,4,104,105,110, + 116,6,11,85,115,101,32,105,110,32,77,97,107,101,0,1,7,99,97,112, + 116,105,111,110,6,1,66,4,104,105,110,116,6,12,85,115,101,32,105,110, + 32,66,117,105,108,100,0,1,7,99,97,112,116,105,111,110,6,1,49,4, + 104,105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,49,0, + 1,7,99,97,112,116,105,111,110,6,1,50,4,104,105,110,116,6,13,85, + 115,101,32,105,110,32,77,97,107,101,32,50,0,1,7,99,97,112,116,105, + 111,110,6,1,51,4,104,105,110,116,6,13,85,115,101,32,105,110,32,77, + 97,107,101,32,51,0,1,7,99,97,112,116,105,111,110,6,1,52,4,104, + 105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,52,0,1, + 7,99,97,112,116,105,111,110,6,1,85,4,104,105,110,116,6,28,65,100, + 100,32,116,111,32,117,110,105,116,32,102,105,108,101,32,115,101,97,114,99, + 104,32,112,97,116,104,0,1,7,99,97,112,116,105,111,110,6,1,73,4, + 104,105,110,116,6,31,65,100,100,32,116,111,32,105,110,99,108,117,100,101, + 32,102,105,108,101,32,115,101,97,114,99,104,32,112,97,116,104,0,1,7, + 99,97,112,116,105,111,110,6,1,76,4,104,105,110,116,6,26,65,100,100, + 32,116,111,32,108,105,98,114,97,114,121,32,115,101,97,114,99,104,32,112, + 97,116,104,0,1,7,99,97,112,116,105,111,110,6,1,79,4,104,105,110, + 116,6,30,65,100,100,32,116,111,32,111,98,106,101,99,116,32,102,105,108, + 101,32,115,101,97,114,99,104,32,112,97,116,104,0,1,7,99,97,112,116, + 105,111,110,6,9,68,105,114,101,99,116,111,114,121,0,0,0,0,14,100, + 97,116,97,99,111,108,115,46,99,111,117,110,116,2,11,14,100,97,116,97, + 99,111,108,115,46,119,105,100,116,104,2,13,16,100,97,116,97,99,111,108, + 115,46,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105, + 116,101,109,115,14,7,7,100,109,97,107,101,111,110,1,5,119,105,100,116, + 104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,7,100,109,97,107,101,111,110,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,8,100,98,117,105,108,100,111,110,1,5,119,105,100,116, + 104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,8,100,98,117,105,108,100,111,110,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,8,100,109,97,107,101,49,111,110,1,5,119,105,100, + 116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97, + 119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,8,100,109,97,107,101,49,111,110,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,8,100,109,97,107,101,50,111,110,1,5,119,105, + 100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114, + 97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116, + 110,97,109,101,6,8,100,109,97,107,101,50,111,110,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,8,100,109,97,107,101,51,111,110,1,5,119, + 105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,8,100,109,97,107,101,51,111,110,9,100,97,116,97, + 99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100, + 97,116,97,108,105,115,116,0,7,8,100,109,97,107,101,52,111,110,1,9, + 108,105,110,101,119,105,100,116,104,2,2,12,108,105,110,101,99,111,108,111, + 114,102,105,120,4,3,0,0,160,5,119,105,100,116,104,2,13,7,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,8,100,109, + 97,107,101,52,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103, + 114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7, + 7,100,117,110,105,116,111,110,1,5,119,105,100,116,104,2,13,7,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,100,117, + 110,105,116,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,10, + 100,105,110,99,108,117,100,101,111,110,1,5,119,105,100,116,104,2,13,7, + 111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117, + 115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101, + 115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95, + 99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,10, + 100,105,110,99,108,117,100,101,111,110,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,7,6,100,108,105,98,111,110,1,5,119,105,100,116,104,2,13, + 7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99, + 117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118, + 101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6, + 6,100,108,105,98,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 7,6,100,111,98,106,111,110,1,5,119,105,100,116,104,2,13,7,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,6,100,111, + 98,106,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105, + 100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,8,117, + 110,105,116,100,105,114,115,1,12,108,105,110,101,99,111,108,111,114,102,105, + 120,4,3,0,0,160,5,119,105,100,116,104,3,172,2,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105, + 110,116,7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105, + 100,103,101,116,110,97,109,101,6,8,117,110,105,116,100,105,114,115,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 7,100,109,97,107,101,111,110,3,84,97,103,2,1,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110, + 115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13, + 111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101, + 99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95, + 97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101, + 121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97, + 116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101, + 102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,8,100,98,117,105,108,100,111,110,3,84,97,103,2,2,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 2,8,98,111,117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101, + 100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,8,100,109,97,107,101,49,111,110,3,84,97,103,2,4,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,2,28,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108, + 117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,8,100,109,97,107,101,50,111,110,3,84,97,103,2,8, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114, + 100,101,114,2,4,8,98,111,117,110,100,115,95,120,2,42,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14, + 111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115, + 97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118, + 97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,8,100,109,97,107,101,51,111,110,3,84,97,103, + 2,16,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98, + 111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,56,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2, + 16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8, + 12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,8,100,109,97,107,101,52,111,110,3,84, + 97,103,2,32,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,70, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109, + 101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111, + 101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108, + 101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,7,100,117,110,105,116,111,110,3, + 84,97,103,4,0,0,1,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115, + 95,120,2,85,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105, + 115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,10,100,105,110,99, + 108,117,100,101,111,110,3,84,97,103,4,0,0,2,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,8, + 8,98,111,117,110,100,115,95,120,2,99,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49, + 95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107, + 101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116, + 97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100, + 101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,6,100,108,105,98,111,110,3,84,97,103,4,0,0,4,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,9,8,98,111,117,110,100,115,95,120,2,113,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108, + 117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,6,100,111,98,106,111,110,3,84,97,103,4,0,0,8, + 0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 10,8,98,111,117,110,100,115,95,120,2,127,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7, + 118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108, + 116,9,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,8,117, + 110,105,116,100,105,114,115,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,2,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101, + 100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111, + 117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105, + 109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116, + 116,111,110,46,99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101, + 46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97, + 98,111,114,100,101,114,2,11,10,111,110,115,104,111,119,104,105,110,116,7, + 18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,141,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,172,2,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110, + 115,11,13,102,100,111,95,100,105,114,101,99,116,111,114,121,8,102,100,111, + 95,102,105,108,101,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105, + 115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116, + 114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,21, + 83,101,108,101,99,116,32,117,110,105,116,32,100,105,114,101,99,116,111,114, + 121,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105, + 108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110,97, + 109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,49,5,99, + 111,108,111,114,4,3,0,0,128,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,31,1,8,98,111,117,110,100,115,95, + 121,2,41,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110, + 100,115,95,99,121,2,5,7,108,105,110,107,116,111,112,7,11,116,108,97, + 121,111,117,116,101,114,49,55,10,108,105,110,107,98,111,116,116,111,109,7, + 11,117,110,105,116,100,105,114,103,114,105,100,0,0,9,116,108,97,121,111, + 117,116,101,114,11,116,108,97,121,111,117,116,101,114,49,55,8,116,97,98, + 111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,4,9,98,111,117,110,100,115,95,99,120,3, + 62,3,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,0,12,111,112,116,105,111,110,115,115, + 99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115, + 99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104, + 114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116, + 11,10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105, + 103,110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109, + 95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116, + 2,4,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,4,0,11, + 116,115,116,114,105,110,103,101,100,105,116,7,111,98,106,112,114,101,102,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,15,79,98,106,32,112, + 114,101,102,46,32,40,45,70,111,41,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,4,2, + 0,0,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101, + 120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115, + 95,120,3,13,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,88,9,98,111,117,110,100,115,95,99,121,2,37, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116, + 115,116,114,105,110,103,101,100,105,116,7,108,105,98,112,114,101,102,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,14,76,105,98,32,112,114, + 101,102,46,40,45,70,108,41,22,102,114,97,109,101,46,99,97,112,116,105, + 111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116, + 111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116, + 17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105, + 110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114, + 111,115,8,98,111,117,110,100,115,95,120,3,181,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,84,9,98,111, + 117,110,100,115,95,99,121,2,37,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,7, + 105,110,99,112,114,101,102,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,14,73,110,99,32,112,114,101,102,46,40,45,70,105,41,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2, + 10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112, + 97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120, + 2,93,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,84,9,98,111,117,110,100,115,95,99,121,2,37,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,8,117,110,105,116,112,114,101,102,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,15,85,110,105,116,32,112,114,101, + 102,46,40,45,70,117,41,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111, + 109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,5,2,0,0,8, + 116,97,98,111,114,100,101,114,2,3,10,111,110,115,104,111,119,104,105,110, + 116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111, + 115,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,89,9,98,111,117,110, + 100,115,95,99,121,2,37,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,16,114, + 101,118,101,114,115,101,112,97,116,104,111,114,100,101,114,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,23,82,101,118,101,114,115,101,32,100, + 105,114,101,99,116,111,114,121,32,111,114,100,101,114,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,150,0,2,2, + 0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95, + 120,3,135,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110, + 100,115,95,99,120,3,163,0,9,98,111,117,110,100,115,95,99,121,2,16, + 0,0,13,116,115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105, + 109,112,108,101,119,105,100,103,101,116,49,8,116,97,98,111,114,100,101,114, + 2,5,8,98,111,117,110,100,115,95,120,3,105,1,8,98,111,117,110,100, + 115,95,121,2,22,9,98,111,117,110,100,115,95,99,120,2,26,9,98,111, + 117,110,100,115,95,99,121,2,10,0,0,0,0,8,116,116,97,98,112,97, + 103,101,10,116,116,97,98,112,97,103,101,49,56,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,4,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98, + 111,117,110,100,115,95,99,121,3,70,1,7,97,110,99,104,111,114,115,11, + 7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116, + 105,111,110,6,13,67,111,109,109,97,110,100,32,97,102,116,101,114,0,11, + 116,119,105,100,103,101,116,103,114,105,100,14,97,102,116,99,111,109,109,97, + 110,100,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95, + 109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128, + 19,102,114,97,109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116, + 2,3,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,70,1, + 12,98,111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110,99,104, + 111,114,115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,15,111, + 103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111, + 119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108, + 101,116,105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119, + 115,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101, + 108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114, + 115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10, + 111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111, + 112,117,112,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1, + 13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105, + 103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116, + 2,7,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7, + 99,97,112,116,105,111,110,6,1,77,4,104,105,110,116,6,11,85,115,101, + 32,105,110,32,77,97,107,101,0,1,7,99,97,112,116,105,111,110,6,1, + 66,4,104,105,110,116,6,12,85,115,101,32,105,110,32,66,117,105,108,100, + 0,1,7,99,97,112,116,105,111,110,6,1,49,4,104,105,110,116,6,13, + 85,115,101,32,105,110,32,77,97,107,101,32,49,0,1,7,99,97,112,116, + 105,111,110,6,1,50,4,104,105,110,116,6,13,85,115,101,32,105,110,32, + 77,97,107,101,32,50,0,1,7,99,97,112,116,105,111,110,6,1,51,4, + 104,105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,51,0, + 1,7,99,97,112,116,105,111,110,6,1,52,4,104,105,110,116,6,13,85, + 115,101,32,105,110,32,77,97,107,101,32,52,0,1,7,99,97,112,116,105, + 111,110,6,7,67,111,109,109,97,110,100,0,0,0,0,14,100,97,116,97, + 99,111,108,115,46,99,111,117,110,116,2,7,16,100,97,116,97,99,111,108, + 115,46,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105, + 116,101,109,115,14,7,9,97,102,116,109,97,107,101,111,110,1,5,119,105, + 100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114, + 97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116, + 110,97,109,101,6,9,97,102,116,109,97,107,101,111,110,9,100,97,116,97, + 99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100, + 97,116,97,108,105,115,116,0,7,10,97,102,116,98,117,105,108,100,111,110, + 1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99, + 111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,10,97,102,116,98,117,105,108,100,111,110, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,10,97,102,116,109,97, + 107,101,49,111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111, + 110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,97,102,116,109,97, + 107,101,49,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,10, + 97,102,116,109,97,107,101,50,111,110,1,5,119,105,100,116,104,2,13,7, + 111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117, + 115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101, + 115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95, + 99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,10, + 97,102,116,109,97,107,101,50,111,110,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,7,10,97,102,116,109,97,107,101,51,111,110,1,5,119,105,100, + 116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97, + 119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,10,97,102,116,109,97,107,101,51,111,110,9,100,97,116,97, + 99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100, + 97,116,97,108,105,115,116,0,7,10,97,102,116,109,97,107,101,52,111,110, + 1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99, + 111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,10,97,102,116,109,97,107,101,52,111,110, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,10,97,102,116,99,111, + 109,109,97,110,100,1,5,119,105,100,116,104,3,229,2,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,10,97,102,116,99,111,109,109,97,110,100,9,100,97,116,97,99, + 108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101, + 105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,97,102,116, + 109,97,107,101,111,110,3,84,97,103,2,1,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117, + 116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101, + 120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97, + 117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,10, + 97,102,116,98,117,105,108,100,111,110,3,84,97,103,2,2,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 2,8,98,111,117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101, + 100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,10,97,102,116,109,97,107,101,49,111,110,3,84,97,103,2,4, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114, + 100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,28,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14, + 111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115, + 97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118, + 97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,10,97,102,116,109,97,107,101,50,111,110,3,84, + 97,103,2,8,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2,42, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109, + 101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111, + 101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108, + 101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,10,97,102,116,109,97,107,101,51, + 111,110,3,84,97,103,2,16,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115, + 95,120,2,56,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105, + 115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,10,97,102,116,109, + 97,107,101,52,111,110,3,84,97,103,2,32,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111, + 117,110,100,115,95,120,2,70,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117, + 116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101, + 120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97, + 117,108,116,9,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100, + 105,116,10,97,102,116,99,111,109,109,97,110,100,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110, + 114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101, + 114,2,7,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116, + 101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,84,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,229,2,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0, + 0,0,11,116,115,116,114,105,110,103,101,100,105,116,8,116,97,114,103,112, + 114,101,102,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,16,84, + 97,114,103,46,32,112,114,101,102,46,32,40,45,111,41,22,102,114,97,109, + 101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9, + 116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,10,111, + 110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110, + 100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120,3,202, + 1,8,98,111,117,110,100,115,95,121,2,2,9,98,111,117,110,100,115,95, + 99,120,3,115,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,7,109,97,107,101, + 100,105,114,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,15,77,97,107,101,32,38,68,105,114,101,99,116,111,114, + 121,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97, + 109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2, + 0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109, + 101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20, + 102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114, + 2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,4, + 10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112, + 97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120, + 3,250,0,8,98,111,117,110,100,115,95,121,2,43,9,98,111,117,110,100, + 115,95,99,120,3,205,0,9,98,111,117,110,100,115,95,99,121,2,37,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95, + 116,111,112,8,97,110,95,114,105,103,104,116,0,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102, + 95,110,111,115,101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101, + 108,101,102,116,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116, + 105,111,110,115,11,13,102,100,111,95,100,105,114,101,99,116,111,114,121,0, + 26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114,121,109, + 97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111,108,108,101,114, + 46,99,97,112,116,105,111,110,111,112,101,110,6,21,83,101,108,101,99,116, + 32,109,97,107,101,32,100,105,114,101,99,116,111,114,121,24,99,111,110,116, + 114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101, + 7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,112,108,105, + 116,116,101,114,10,116,115,112,108,105,116,116,101,114,49,5,99,111,108,111, + 114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2,16,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,247,0,8,98, + 111,117,110,100,115,95,121,2,61,9,98,111,117,110,100,115,95,99,120,2, + 3,9,98,111,117,110,100,115,95,99,121,2,20,7,111,112,116,105,111,110, + 115,11,9,115,112,111,95,104,112,114,111,112,12,115,112,111,95,100,111,99, + 107,108,101,102,116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112, + 111,95,100,111,99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107, + 98,111,116,116,111,109,0,8,108,105,110,107,108,101,102,116,7,11,109,97, + 107,101,99,111,109,109,97,110,100,9,108,105,110,107,114,105,103,104,116,7, + 7,109,97,107,101,100,105,114,0,0,9,116,115,112,108,105,116,116,101,114, + 10,116,115,112,108,105,116,116,101,114,50,5,99,111,108,111,114,4,3,0, + 0,144,8,116,97,98,111,114,100,101,114,2,17,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,247,0,8,98,111,117,110,100, + 115,95,121,2,20,9,98,111,117,110,100,115,95,99,120,2,3,9,98,111, + 117,110,100,115,95,99,121,2,20,7,111,112,116,105,111,110,115,11,9,115, + 112,111,95,104,112,114,111,112,12,115,112,111,95,100,111,99,107,108,101,102, + 116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112,111,95,100,111, + 99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107,98,111,116,116, + 111,109,0,8,108,105,110,107,108,101,102,116,7,8,109,97,105,110,102,105, + 108,101,9,108,105,110,107,114,105,103,104,116,7,10,116,97,114,103,101,116, + 102,105,108,101,0,0,9,116,115,112,108,105,116,116,101,114,10,116,115,112, + 108,105,116,116,101,114,52,5,99,111,108,111,114,4,3,0,0,144,8,116, + 97,98,111,114,100,101,114,2,19,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,199,1,8,98,111,117,110,100,115,95,121,2, + 20,9,98,111,117,110,100,115,95,99,120,2,3,9,98,111,117,110,100,115, + 95,99,121,2,20,7,111,112,116,105,111,110,115,11,9,115,112,111,95,104, + 112,114,111,112,12,115,112,111,95,100,111,99,107,108,101,102,116,11,115,112, + 111,95,100,111,99,107,116,111,112,13,115,112,111,95,100,111,99,107,114,105, + 103,104,116,14,115,112,111,95,100,111,99,107,98,111,116,116,111,109,0,8, + 108,105,110,107,108,101,102,116,7,10,116,97,114,103,101,116,102,105,108,101, + 9,108,105,110,107,114,105,103,104,116,7,8,116,97,114,103,112,114,101,102, + 0,0,9,116,115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116, + 101,114,53,5,99,111,108,111,114,4,3,0,0,144,8,116,97,98,111,114, + 100,101,114,2,20,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,199,1,8,98,111,117,110,100,115,95,121,2,60,9,98,111, + 117,110,100,115,95,99,120,2,3,9,98,111,117,110,100,115,95,99,121,2, + 20,7,111,112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111,112, + 12,115,112,111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100,111, + 99,107,116,111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116,14, + 115,112,111,95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110,107, + 108,101,102,116,7,7,109,97,107,101,100,105,114,9,108,105,110,107,114,105, + 103,104,116,7,17,109,101,115,115,97,103,101,111,117,116,112,117,116,102,105, + 108,101,0,0,10,116,99,111,108,111,114,101,100,105,116,10,99,111,108,111, + 114,101,114,114,111,114,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,11,69,114,114,111,114,32,67,111,108,111,114,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,20,102,114,97,109,101,46,98,117,116,116,111,110, + 46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105, + 118,101,105,110,118,105,115,105,98,108,101,0,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,7,111,112,116, + 105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101,105,110, + 118,105,115,105,98,108,101,0,0,1,7,105,109,97,103,101,110,114,2,17, + 7,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105, + 118,101,105,110,118,105,115,105,98,108,101,0,0,0,27,102,114,97,109,101, + 46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,105,109,97,103,101, + 110,114,2,17,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108, + 105,112,115,101,46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110, + 97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100, + 115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,87,9,98,111,117, + 110,100,115,95,99,120,2,108,9,98,111,117,110,100,115,95,99,121,2,37, + 5,118,97,108,117,101,4,24,0,0,160,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,7,116,115,112,97,99,101,114,8,116,115, + 112,97,99,101,114,53,8,116,97,98,111,114,100,101,114,2,21,8,98,111, + 117,110,100,115,95,120,2,109,8,98,111,117,110,100,115,95,121,2,109,9, + 98,111,117,110,100,115,95,99,120,2,8,9,98,111,117,110,100,115,95,99, + 121,2,18,8,108,105,110,107,108,101,102,116,7,10,99,111,108,111,114,101, + 114,114,111,114,9,108,105,110,107,114,105,103,104,116,7,12,99,111,108,111, + 114,119,97,114,110,105,110,103,0,0,10,116,99,111,108,111,114,101,100,105, + 116,12,99,111,108,111,114,119,97,114,110,105,110,103,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,13,87,97,114,110,105,110,103,32,67,111, + 108,111,114,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120, + 116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,20,102,114, + 97,109,101,46,98,117,116,116,111,110,46,111,112,116,105,111,110,115,11,21, + 102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108, + 101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117, + 110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105, + 116,101,109,115,14,1,7,111,112,116,105,111,110,115,11,21,102,98,111,95, + 105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,0,1, + 7,105,109,97,103,101,110,114,2,17,7,111,112,116,105,111,110,115,11,21, + 102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108, + 101,0,0,0,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108, + 105,112,115,101,46,105,109,97,103,101,110,114,2,17,27,102,114,97,109,101, + 46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,111,112,116,105,111, + 110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105, + 115,105,98,108,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,7,8,98,111,117,110,100,115,95,120,2,117,8,98,111,117,110, + 100,115,95,121,2,87,9,98,111,117,110,100,115,95,99,120,2,108,9,98, + 111,117,110,100,115,95,99,121,2,37,5,118,97,108,117,101,4,19,0,0, + 160,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7, + 116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,54,8,116,97,98, + 111,114,100,101,114,2,22,8,98,111,117,110,100,115,95,120,3,225,0,8, + 98,111,117,110,100,115,95,121,2,109,9,98,111,117,110,100,115,95,99,120, + 2,8,9,98,111,117,110,100,115,95,99,121,2,18,8,108,105,110,107,108, + 101,102,116,7,12,99,111,108,111,114,119,97,114,110,105,110,103,9,108,105, + 110,107,114,105,103,104,116,7,9,99,111,108,111,114,110,111,116,101,0,0, + 10,116,99,111,108,111,114,101,100,105,116,9,99,111,108,111,114,110,111,116, + 101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10,78,111,116, + 101,32,67,111,108,111,114,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111, + 109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,111,112,116,105,111, + 110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105, + 115,105,98,108,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,7,111,112,116,105,111,110,115,11,21, + 102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108, + 101,0,0,1,7,105,109,97,103,101,110,114,2,17,7,111,112,116,105,111, + 110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105, + 115,105,98,108,101,0,0,0,27,102,114,97,109,101,46,98,117,116,116,111, + 110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2,17,27,102, + 114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,111, + 112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101, + 105,110,118,105,115,105,98,108,101,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,8,8,98,111,117,110,100,115,95,120,3,233,0, + 8,98,111,117,110,100,115,95,121,2,87,9,98,111,117,110,100,115,95,99, + 120,2,108,9,98,111,117,110,100,115,95,99,121,2,37,5,118,97,108,117, + 101,4,20,0,0,160,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114, + 52,5,99,111,108,111,114,4,3,0,0,128,8,116,97,98,111,114,100,101, + 114,2,23,8,98,111,117,110,100,115,95,120,3,85,1,8,98,111,117,110, + 100,115,95,121,2,92,9,98,111,117,110,100,115,95,99,120,2,10,9,98, + 111,117,110,100,115,95,99,121,2,26,8,108,105,110,107,108,101,102,116,7, + 9,99,111,108,111,114,110,111,116,101,9,108,105,110,107,114,105,103,104,116, + 7,15,115,116,114,105,112,109,101,115,115,97,103,101,101,115,99,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,15,115,116,114,105,112,109,101, + 115,115,97,103,101,101,115,99,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,19,83,116,114,105,112,32,69,83,67,32,115,101,113,117,101,110, + 99,101,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116, + 17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,133,0,2,2, + 0,8,116,97,98,111,114,100,101,114,2,10,8,98,111,117,110,100,115,95, + 120,3,95,1,8,98,111,117,110,100,115,95,121,2,115,9,98,111,117,110, + 100,115,95,99,120,3,146,0,9,98,111,117,110,100,115,95,99,121,2,16, + 0,0,0,8,116,116,97,98,112,97,103,101,9,116,116,97,98,112,97,103, + 101,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114, + 2,3,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115, + 95,121,2,20,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111, + 117,110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105, + 111,110,6,7,77,38,97,99,114,111,115,8,111,110,108,97,121,111,117,116, + 7,17,109,97,99,114,111,110,99,104,105,108,100,115,99,97,108,101,100,0, + 11,116,119,105,100,103,101,116,103,114,105,100,9,109,97,99,114,111,103,114, + 105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111,99,117,115,98, + 97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115,101,119,104,101, + 101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,124,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,149, + 1,12,98,111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116, + 111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95, + 99,111,108,115,105,122,105,110,103,15,111,103,95,107,101,121,114,111,119,109, + 111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116,105,110, + 103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,23,111,103,95, + 115,101,108,101,99,116,101,100,114,111,119,115,100,101,108,101,116,105,110,103, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95, + 97,117,116,111,97,112,112,101,110,100,10,111,103,95,119,114,97,112,99,111, + 108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,114, + 111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46, + 105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112, + 116,105,111,110,115,46,99,111,117,110,116,2,8,14,99,97,112,116,105,111, + 110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,1, + 49,0,1,7,99,97,112,116,105,111,110,6,1,50,0,1,7,99,97,112, + 116,105,111,110,6,1,51,0,1,7,99,97,112,116,105,111,110,6,1,52, + 0,1,7,99,97,112,116,105,111,110,6,1,53,0,1,7,99,97,112,116, + 105,111,110,6,1,54,0,1,7,99,97,112,116,105,111,110,6,4,78,97, + 109,101,0,1,7,99,97,112,116,105,111,110,6,5,86,97,108,117,101,0, + 0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,8, + 14,100,97,116,97,99,111,108,115,46,119,105,100,116,104,2,13,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11, + 99,111,95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99, + 97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109, + 115,14,7,2,101,48,1,5,119,105,100,116,104,2,13,7,111,112,116,105, + 111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103, + 101,116,110,97,109,101,6,2,101,48,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,7,2,101,49,1,5,119,105,100,116,104,2,13,7,111,112,116, + 105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116, + 104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,2,101,49,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,2,101,50,1,5,119,105,100,116,104,2,13,7,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100, + 116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,2,101,50,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,2,101,51,1,5,119,105,100,116,104,2,13,7,111, + 112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105, + 100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,2,101,51,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,2,101,52,1,5,119,105,100,116,104,2,13,7, + 111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117, + 115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119, + 105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111, + 95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10, + 119,105,100,103,101,116,110,97,109,101,6,2,101,52,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,2,101,53,1,5,119,105,100,116,104,2,13, + 7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99, + 117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120, + 119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99, + 111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116, + 101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0, + 10,119,105,100,103,101,116,110,97,109,101,6,2,101,53,9,100,97,116,97, + 99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100, + 97,116,97,108,105,115,116,0,7,10,109,97,99,114,111,110,97,109,101,115, + 1,5,119,105,100,116,104,3,146,0,7,111,112,116,105,111,110,115,11,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,109,97, + 99,114,111,110,97,109,101,115,9,100,97,116,97,99,108,97,115,115,7,22, + 116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105, + 115,116,0,7,11,109,97,99,114,111,118,97,108,117,101,115,1,5,119,105, + 100,116,104,3,82,2,7,111,112,116,105,111,110,115,11,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116, + 7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103, + 101,116,110,97,109,101,6,11,109,97,99,114,111,118,97,108,117,101,115,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97, + 114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105,108,101, + 7,9,115,116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,2,101,48,3,84,97,103,2,1,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7, + 118,105,115,105,98,108,101,8,5,118,97,108,117,101,9,12,118,97,108,117, + 101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,2,101,49,3,84,97,103,2,2,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,8,98, + 111,117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97, + 117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121, + 101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116, + 101,0,7,118,105,115,105,98,108,101,8,5,118,97,108,117,101,9,12,118, + 97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,2,101,50,3,84,97,103,2,4,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 3,8,98,111,117,110,100,115,95,120,2,28,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,7,118,105,115,105,98,108,101,8,5,118,97,108,117,101, + 9,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,2,101,51,3,84,97,103,2,8,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,4,8,98,111,117,110,100,115,95,120,2,42,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,5,118,97, + 108,117,101,9,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,2,101,52,3,84,97,103, + 2,16,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98, + 111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,56,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2, + 16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8, + 5,118,97,108,117,101,9,12,118,97,108,117,101,100,101,102,97,117,108,116, + 9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,2,101,53,3, + 84,97,103,2,32,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,2, + 70,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112, + 109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13, + 111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98, + 108,101,8,5,118,97,108,117,101,9,12,118,97,108,117,101,100,101,102,97, + 117,108,116,9,0,0,11,116,115,116,114,105,110,103,101,100,105,116,10,109, + 97,99,114,111,110,97,109,101,115,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 7,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 84,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,146,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,15,116,109,101,109,111,100,105, + 97,108,111,103,101,100,105,116,11,109,97,99,114,111,118,97,108,117,101,115, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117, + 110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105, + 116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109, + 97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116, + 111,110,46,99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46, + 98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98, + 111,114,100,101,114,2,8,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,3,231,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,82,2,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0, + 11,116,119,105,100,103,101,116,103,114,105,100,21,115,101,108,101,99,116,97, + 99,116,105,118,101,103,114,111,117,112,103,114,105,100,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99, + 13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,12,65,99,116,105,118,101,32,103,114,111,117, + 112,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97, + 109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121, + 2,121,12,98,111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,0,11,111,112,116,105,111, + 110,115,103,114,105,100,11,12,111,103,95,114,111,119,109,111,118,105,110,103, + 15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,19,111,103,95, + 102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,10,111,103,95, + 119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112, + 0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105, + 120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2, + 13,8,110,117,109,115,116,97,114,116,2,1,7,110,117,109,115,116,101,112, + 2,1,0,0,8,114,111,119,99,111,117,110,116,2,6,14,100,97,116,97, + 99,111,108,115,46,99,111,117,110,116,2,2,16,100,97,116,97,99,111,108, + 115,46,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105, + 116,101,109,115,14,7,17,97,99,116,105,118,101,109,97,99,114,111,115,101, + 108,101,99,116,1,5,119,105,100,116,104,2,14,7,111,112,116,105,111,110, + 115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,17,97,99,116,105, + 118,101,109,97,99,114,111,115,101,108,101,99,116,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,4,100,97,116,97,1,1,2,0,2,0,2,0,2,0, + 2,0,2,0,0,0,0,7,12,103,114,111,117,112,99,111,109,109,101,110, + 116,1,5,119,105,100,116,104,3,13,3,7,111,112,116,105,111,110,115,11, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,0,10,119,105,100, + 103,101,116,110,97,109,101,6,12,103,114,111,117,112,99,111,109,109,101,110, + 116,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,4,100,97,116,97, + 1,1,6,0,6,0,6,0,6,0,6,0,6,0,0,0,0,0,13,100, + 97,116,97,114,111,119,104,101,105,103,104,116,2,16,11,111,110,114,111,119, + 115,109,111,118,101,100,7,23,115,101,108,101,99,116,97,99,116,105,118,101, + 111,110,114,111,119,115,109,111,118,101,100,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,17,116,98,111,111,108,101,97,110,101,100,105, + 116,114,97,100,105,111,17,97,99,116,105,118,101,109,97,99,114,111,115,101, + 108,101,99,116,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,14,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7, + 26,97,99,116,116,105,118,101,115,101,108,101,99,116,111,110,100,97,116,97, + 101,110,116,101,114,101,100,7,118,105,115,105,98,108,101,8,0,0,11,116, + 115,116,114,105,110,103,101,100,105,116,12,103,114,111,117,112,99,111,109,109, + 101,110,116,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,15,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,13,3,9, + 98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100, + 111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,0,9,116,115,112,108,105,116,116,101,114,13,109,97, + 99,114,111,115,112,108,105,116,116,101,114,5,99,111,108,111,114,4,3,0, + 0,144,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,121,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,2,3, + 7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,7,111,112, + 116,105,111,110,115,11,9,115,112,111,95,118,109,111,118,101,9,115,112,111, + 95,118,112,114,111,112,11,115,112,111,95,100,111,99,107,116,111,112,14,115, + 112,111,95,100,111,99,107,98,111,116,116,111,109,0,7,108,105,110,107,116, + 111,112,7,21,115,101,108,101,99,116,97,99,116,105,118,101,103,114,111,117, + 112,103,114,105,100,10,108,105,110,107,98,111,116,116,111,109,7,9,109,97, + 99,114,111,103,114,105,100,8,115,116,97,116,102,105,108,101,7,9,115,116, + 97,116,102,105,108,101,49,0,0,0,8,116,116,97,98,112,97,103,101,13, + 102,111,110,116,97,108,105,97,115,112,97,103,101,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,18, + 2,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,7,99,97,112,116,105,111,110,6,11,38,70,111,110,116, + 32,65,108,105,97,115,0,11,116,119,105,100,103,101,116,103,114,105,100,13, + 102,111,110,116,97,108,105,97,115,103,114,105,100,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99, + 111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114, + 105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98, + 111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100, + 115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,0,11,111,112, + 116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122, + 105,110,103,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15, + 111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114, + 111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99, + 101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105, + 114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100, + 10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112, + 111,112,117,112,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,15,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,7,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,5,65,108,105,97,115,0,1,7,99,97, + 112,116,105,111,110,6,9,70,111,110,116,32,110,97,109,101,0,1,7,99, + 97,112,116,105,111,110,6,6,72,101,105,103,104,116,0,1,7,99,97,112, + 116,105,111,110,6,5,87,105,100,116,104,0,1,7,99,97,112,116,105,111, + 110,6,7,79,112,116,105,111,110,115,0,1,7,99,97,112,116,105,111,110, + 6,6,88,115,99,97,108,101,0,1,7,99,97,112,116,105,111,110,6,8, + 65,110,99,101,115,116,111,114,0,0,0,0,14,100,97,116,97,99,111,108, + 115,46,99,111,117,110,116,2,7,16,100,97,116,97,99,111,108,115,46,111, + 112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111, + 108,115,46,105,116,101,109,115,14,7,9,102,111,110,116,97,108,105,97,115, + 1,5,119,105,100,116,104,2,98,7,111,112,116,105,111,110,115,11,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97, + 116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108, + 111,110,115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109, + 101,6,9,102,111,110,116,97,108,105,97,115,9,100,97,116,97,99,108,97, + 115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97, + 116,97,108,105,115,116,0,7,8,102,111,110,116,110,97,109,101,1,5,119, + 105,100,116,104,3,195,1,7,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11, + 99,111,95,99,97,110,112,97,115,116,101,0,10,111,110,115,104,111,119,104, + 105,110,116,7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119, + 105,100,103,101,116,110,97,109,101,6,8,102,111,110,116,110,97,109,101,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,102,111,110,116, + 104,101,105,103,104,116,1,7,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,102,111,110,116,104, + 101,105,103,104,116,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,9, + 102,111,110,116,119,105,100,116,104,1,7,111,112,116,105,111,110,115,11,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,9,102,111, + 110,116,119,105,100,116,104,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 7,11,102,111,110,116,111,112,116,105,111,110,115,1,7,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116, + 7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103, + 101,116,110,97,109,101,6,11,102,111,110,116,111,112,116,105,111,110,115,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,102,111,110,116, + 120,115,99,97,108,101,1,7,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,102,111,110,116,120, + 115,99,97,108,101,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114, + 105,100,114,101,97,108,100,97,116,97,108,105,115,116,0,7,13,102,111,110, + 116,97,110,99,101,115,116,111,114,115,1,5,119,105,100,116,104,2,70,7, + 111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,111,110,115,104,111, + 119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119,104,105,110,116, + 10,119,105,100,103,101,116,110,97,109,101,6,13,102,111,110,116,97,110,99, + 101,115,116,111,114,115,9,100,97,116,97,99,108,97,115,115,7,22,116,103, + 114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116, + 0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115, + 116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,115,116,114, + 105,110,103,101,100,105,116,9,102,111,110,116,97,108,105,97,115,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116, + 7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,98,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117, + 114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114, + 101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95, + 101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111, + 110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,8,102,111, + 110,116,110,97,109,101,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,10,111,110,115,104, + 111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100, + 109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,99,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,195,1,9,98,111,117,110,100,115,95,99,121, + 2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104, + 105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,10,102,111,110,116,104,101,105,103,104,116,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114, + 100,101,114,2,3,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,39,2,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105, + 102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,9,102,111,110,116,119,105,100,116,104,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,4,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,90,2,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,50, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,11,116,115,116,114,105,110,103,101,100,105,116,11,102,111,110,116,111, + 112,116,105,111,110,115,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,5,10,111,110,115,104,111,119,104,105,110,116,7, + 18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,141,2, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117, + 114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114, + 101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95, + 101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111, + 110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,9,116,114,101,97,108,101,100,105,116,10,102,111,110,116, + 120,115,99,97,108,101,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,6,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,3,192,2,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,5,118,97,108, + 117,101,2,1,12,118,97,108,117,101,100,101,102,97,117,108,116,5,0,0, + 0,0,0,0,0,128,255,255,10,118,97,108,117,101,114,97,110,103,101,2, + 1,10,118,97,108,117,101,115,116,97,114,116,2,0,8,118,97,108,117,101, + 109,105,110,2,0,8,118,97,108,117,101,109,97,120,5,244,136,13,181,80, + 153,118,150,125,64,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,13,102,111,110,116, + 97,110,99,101,115,116,111,114,115,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 8,116,97,98,111,114,100,101,114,2,7,10,111,110,115,104,111,119,104,105, + 110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114, + 111,115,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,243,2,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,2,70,9,98,111,117,110,100,115,95,99,121,2,16,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110, + 115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13, + 111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101, + 99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114, + 101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111, + 101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15, + 111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101, + 110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,12,118,97,108,117,101,100,101,102,97, + 117,108,116,6,11,115,116,102,95,100,101,102,97,117,108,116,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,8,116,116,97, + 98,112,97,103,101,10,116,116,97,98,112,97,103,101,49,48,19,102,114,97, + 109,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,12,102,114,108, + 95,102,105,98,111,116,116,111,109,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100, + 115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,18,2, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116, + 116,111,109,0,7,99,97,112,116,105,111,110,6,12,85,115,101,114,32,38, + 67,111,108,111,114,115,0,9,116,108,97,121,111,117,116,101,114,10,116,108, + 97,121,111,117,116,101,114,55,5,99,111,108,111,114,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107, + 105,110,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,3,245,3,9,98,111,117,110,100,115,95,99,120,3,62, + 3,9,98,111,117,110,100,115,95,99,121,2,42,7,97,110,99,104,111,114, + 115,11,9,97,110,95,98,111,116,116,111,109,0,13,111,112,116,105,111,110, + 115,108,97,121,111,117,116,11,10,108,97,111,95,97,108,105,103,110,121,0, + 10,97,108,105,103,110,95,103,108,117,101,7,10,119,97,109,95,99,101,110, + 116,101,114,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110, + 49,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,13,111,119, + 49,95,97,117,116,111,119,105,100,116,104,14,111,119,49,95,97,117,116,111, + 104,101,105,103,104,116,0,5,99,111,108,111,114,4,3,0,0,128,8,98, + 111,117,110,100,115,95,120,2,15,8,98,111,117,110,100,115,95,121,2,11, + 9,98,111,117,110,100,115,95,99,120,3,23,1,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,13,97,115,95, + 108,111,99,97,108,99,111,108,111,114,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,41,67, + 111,112,121,32,34,115,101,116,99,111,108,111,114,109,97,112,118,97,108,117, + 101,34,32,99,111,100,101,32,116,111,32,99,108,105,112,98,111,97,114,100, + 9,111,110,101,120,101,99,117,116,101,7,13,99,111,112,121,99,111,108,111, + 114,99,111,100,101,0,0,0,11,116,119,105,100,103,101,116,103,114,105,100, + 7,99,111,108,103,114,105,100,5,99,111,108,111,114,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,18,2,7,97,110, + 99,104,111,114,115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11, + 12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121, + 114,111,119,109,111,118,105,110,103,19,111,103,95,102,111,99,117,115,99,101, + 108,108,111,110,101,110,116,101,114,20,111,103,95,99,111,108,99,104,97,110, + 103,101,111,110,116,97,98,107,101,121,12,111,103,95,97,117,116,111,112,111, + 112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111, + 108,0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102, + 105,120,99,111,108,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114, + 4,7,0,0,144,5,119,105,100,116,104,2,80,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,0,0, + 13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120, + 114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2, + 16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,3,14,99, + 97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,0,1,7,99,97, + 112,116,105,111,110,6,5,67,111,108,111,114,0,1,7,99,97,112,116,105, + 111,110,6,7,67,111,109,109,101,110,116,0,0,17,99,97,112,116,105,111, + 110,115,102,105,120,46,99,111,117,110,116,2,1,17,99,97,112,116,105,111, + 110,115,102,105,120,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111, + 110,6,4,78,97,109,101,0,0,0,0,14,100,97,116,97,99,111,108,115, + 46,99,111,117,110,116,2,3,16,100,97,116,97,99,111,108,115,46,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115, + 14,7,5,99,111,108,100,105,1,5,119,105,100,116,104,2,22,7,111,112, + 116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,10,99, + 111,95,110,111,102,111,99,117,115,12,99,111,95,105,110,118,105,115,105,98, + 108,101,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,5,99,111,108,100,105,9,100,97,116, + 97,99,108,97,115,115,7,20,116,103,114,105,100,112,111,105,110,116,101,114, + 100,97,116,97,108,105,115,116,0,7,10,117,115,101,114,99,111,108,111,114, + 115,1,5,119,105,100,116,104,2,97,7,111,112,116,105,111,110,115,11,12, + 99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,10,117,115,101,114,99,111,108,111,114, + 115,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114,105,100,101,110, + 117,109,100,97,116,97,108,105,115,116,0,7,16,117,115,101,114,99,111,108, + 111,114,99,111,109,109,101,110,116,1,5,119,105,100,116,104,3,111,2,7, + 111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117, + 115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,8,119,105,100,116, + 104,109,105,110,2,100,10,119,105,100,103,101,116,110,97,109,101,6,16,117, + 115,101,114,99,111,108,111,114,99,111,109,109,101,110,116,9,100,97,116,97, + 99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,12,116,112,111,105,110,116,101,114,101,100,105,116,5,99,111, + 108,100,105,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,22,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111, + 110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,111,110,112,97,105, + 110,116,103,108,121,112,104,7,7,100,114,97,119,99,111,108,0,0,10,116, + 99,111,108,111,114,101,100,105,116,10,117,115,101,114,99,111,108,111,114,115, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,18,102,114,97,109,101,46,98,117,116,116, + 111,110,46,99,111,108,111,114,4,5,0,0,144,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,5,0,0,144,0,1,5,99,111,108,111,114,4,5,0,0, + 144,7,105,109,97,103,101,110,114,2,17,0,0,25,102,114,97,109,101,46, + 98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111,108,111,114,4, + 5,0,0,144,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108, + 105,112,115,101,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114, + 100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,23,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,97,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102, + 116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,0,5,118,97,108,117,101,2,0, + 12,118,97,108,117,101,100,101,102,97,117,108,116,2,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,99,111,108,115,101,116,118,97,108,117,101,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115, + 116,114,105,110,103,101,100,105,116,16,117,115,101,114,99,111,108,111,114,99, + 111,109,109,101,110,116,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101, + 114,2,3,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,2,121,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,111,2,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,0,8,116,116,97,98,112,97,103,101, + 10,116,116,97,98,112,97,103,101,50,49,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 10,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,2,20,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111, + 110,6,14,70,38,111,114,109,97,116,32,77,97,99,114,111,115,7,116,97, + 98,104,105,110,116,6,48,85,115,101,100,32,98,121,32,102,111,114,109,97, + 116,102,108,111,97,116,109,115,101,40,41,32,97,110,100,32,102,111,114,109, + 97,116,100,97,116,101,116,105,109,101,109,115,101,40,41,0,11,116,119,105, + 100,103,101,116,103,114,105,100,15,102,111,114,109,97,116,109,97,99,114,111, + 103,114,105,100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98, + 111,117,110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11, + 0,11,111,112,116,105,111,110,115,103,114,105,100,11,19,111,103,95,102,111, + 99,117,115,99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117, + 116,111,102,105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112, + 112,101,110,100,12,111,103,95,115,97,118,101,115,116,97,116,101,20,111,103, + 95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108, + 0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105, + 120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116, + 2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,2,14, + 99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112, + 116,105,111,110,6,4,78,97,109,101,0,1,7,99,97,112,116,105,111,110, + 6,5,86,97,108,117,101,0,0,0,0,14,100,97,116,97,99,111,108,115, + 46,99,111,117,110,116,2,2,16,100,97,116,97,99,111,108,115,46,111,112, + 116,105,111,110,115,11,12,99,111,95,115,97,118,101,115,116,97,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100, + 97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,16,102,111,114,109, + 97,116,109,97,99,114,111,110,97,109,101,115,1,5,119,105,100,116,104,3, + 157,0,7,111,112,116,105,111,110,115,11,15,99,111,95,112,114,111,112,111, + 114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10, + 111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111, + 119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,16,102,111, + 114,109,97,116,109,97,99,114,111,110,97,109,101,115,9,100,97,116,97,99, + 108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,7,17,102,111,114,109,97,116,109,97,99, + 114,111,118,97,108,117,101,115,1,5,119,105,100,116,104,3,155,2,7,111, + 112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95,115, + 97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116,7,13, + 99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103,101,116, + 110,97,109,101,6,17,102,111,114,109,97,116,109,97,99,114,111,118,97,108, + 117,101,115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100, + 109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13, + 100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,11,116,115,116,114,105,110,103, + 101,100,105,116,16,102,111,114,109,97,116,109,97,99,114,111,110,97,109,101, + 115,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111, + 114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116,7,18,104, + 105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,157, + 0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,17,102, + 111,114,109,97,116,109,97,99,114,111,118,97,108,117,101,115,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,10,111, + 110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110, + 100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,158,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,155,2,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0, + 0,8,116,116,97,98,112,97,103,101,9,116,116,97,98,112,97,103,101,50, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 1,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,2,20,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111, + 110,6,10,38,84,101,109,112,108,97,116,101,115,0,10,116,116,97,98,119, + 105,100,103,101,116,7,110,101,119,102,105,108,101,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98, + 111,117,110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11, + 0,15,97,99,116,105,118,101,112,97,103,101,105,110,100,101,120,2,0,20, + 116,97,98,95,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116, + 17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0,21,116, + 97,98,95,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,9,116,97,98,95,99,111, + 108,111,114,4,3,0,0,128,8,116,97,98,95,115,105,122,101,2,19,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,8,116,116,97, + 98,112,97,103,101,9,116,116,97,98,112,97,103,101,51,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117, + 98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9, + 98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95, + 99,121,3,255,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97, + 110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,11,78, + 101,119,32,80,114,111,106,101,99,116,8,111,110,108,97,121,111,117,116,7, + 21,110,101,119,112,114,111,106,101,99,116,99,104,105,108,100,115,99,97,108, + 101,100,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,11, + 116,119,105,100,103,101,116,103,114,105,100,8,99,111,112,121,103,114,105,100, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,102,111,99,117,115,98,97,99, + 107,111,110,101,115,99,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,86,9,98,111,117,110,100,115,95,99,120,3,62, + 3,9,98,111,117,110,100,115,95,99,121,3,167,1,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111, + 108,115,105,122,105,110,103,15,111,103,95,107,101,121,99,111,108,109,111,118, + 105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95, + 107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105, + 110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116, + 105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110, + 116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13, + 111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108, + 99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114, + 97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46, + 99,111,117,110,116,2,4,14,99,97,112,116,105,111,110,115,46,105,116,101, + 109,115,14,1,7,99,97,112,116,105,111,110,6,1,76,4,104,105,110,116, + 6,19,76,111,97,100,32,102,105,108,101,32,105,110,32,101,100,105,116,111, + 114,0,1,7,99,97,112,116,105,111,110,6,1,77,4,104,105,110,116,6, + 13,69,120,112,97,110,100,32,109,97,99,114,111,115,0,1,7,99,97,112, + 116,105,111,110,6,12,67,111,112,105,101,100,32,70,105,108,101,115,0,1, + 7,99,97,112,116,105,111,110,6,11,68,101,115,116,105,110,97,116,105,111, + 110,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116, + 2,4,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,118, + 97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111, + 95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14, + 100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,15,108,111,97, + 100,112,114,111,106,101,99,116,102,105,108,101,1,5,119,105,100,116,104,2, + 18,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105, + 120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,15,108,111,97,100, + 112,114,111,106,101,99,116,102,105,108,101,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,23,101,120,112,97,110,100,112,114,111,106,101,99,116,102, + 105,108,101,109,97,99,114,111,115,1,5,119,105,100,116,104,2,18,7,111, + 112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105, + 100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,0, + 10,119,105,100,103,101,116,110,97,109,101,6,23,101,120,112,97,110,100,112, + 114,111,106,101,99,116,102,105,108,101,109,97,99,114,111,115,9,100,97,116, + 97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114, + 100,97,116,97,108,105,115,116,0,7,15,110,101,119,112,114,111,106,101,99, + 116,102,105,108,101,115,1,5,119,105,100,116,104,3,161,1,7,111,112,116, + 105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95, + 112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101, + 118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99, + 111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116, + 101,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110, + 115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6, + 15,110,101,119,112,114,111,106,101,99,116,102,105,108,101,115,9,100,97,116, + 97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105, + 110,103,100,97,116,97,108,105,115,116,0,7,19,110,101,119,112,114,111,106, + 101,99,116,102,105,108,101,115,100,101,115,116,1,5,119,105,100,116,104,3, + 113,1,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,0, + 10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104, + 111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,19,110, + 101,119,112,114,111,106,101,99,116,102,105,108,101,115,100,101,115,116,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 15,108,111,97,100,112,114,111,106,101,99,116,102,105,108,101,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,18,9,98,111,117,110,100,115,95,99,121, + 2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111, + 101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49, + 95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101, + 115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,23,101,120,112,97,110,100,112,114,111, + 106,101,99,116,102,105,108,101,109,97,99,114,111,115,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101, + 100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,19,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,18,9,98,111,117,110,100,115,95,99,121,2,16, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49, + 95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107, + 101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116, + 97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,13,116,102,105,108, + 101,110,97,109,101,101,100,105,116,15,110,101,119,112,114,111,106,101,99,116, + 102,105,108,101,115,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99, + 111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0, + 0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114, + 4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105, + 109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,3,10, + 111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97, + 110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,38,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,161,1,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,24,99,111,110,116, + 114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101, + 7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105, + 110,103,101,100,105,116,19,110,101,119,112,114,111,106,101,99,116,102,105,108, + 101,115,100,101,115,116,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101, + 114,2,4,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116, + 101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,200,1,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,113,1,9, + 98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,12,111,101,95,116,114,105,109,114,105,103,104,116,11,111,101,95,116,114, + 105,109,108,101,102,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116, + 16,115,99,114,105,112,116,98,101,102,111,114,101,99,111,112,121,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,18,83,99,114,105,112,116,32,98,101,102,111,114,101, + 32,99,111,112,121,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116, + 101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114, + 2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116, + 97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116, + 7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,3,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110, + 100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,6,97,110,95, + 116,111,112,0,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101, + 116,102,105,108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108, + 101,110,97,109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,15,115,99, + 114,105,112,116,97,102,116,101,114,99,111,112,121,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,17,83,99,114,105,112,116,32,97,102,116,101,114,32,99,111,112,121, + 22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108, + 97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108, + 111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18, + 102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2, + 0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97, + 103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,2,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110, + 116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,40,9,98,111, + 117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121, + 2,37,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,24, + 99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101, + 110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,8, + 116,116,97,98,112,97,103,101,9,116,116,97,98,112,97,103,101,52,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102, + 111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97, + 117,116,111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119, + 95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110, + 100,115,95,99,121,3,255,1,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110, + 6,8,78,101,119,32,70,105,108,101,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,11,116,119,105,100,103,101,116,103,114,105,100,12, + 116,119,105,100,103,101,116,103,114,105,100,49,5,99,111,108,111,114,4,3, + 0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111, + 117,110,100,115,95,99,121,3,255,1,7,97,110,99,104,111,114,115,11,0, + 11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108, + 115,105,122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15, + 111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114, + 111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101, + 108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111, + 110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114, + 111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95, + 99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103, + 95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117, + 112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0, + 13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120, + 99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,27, + 7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115, + 46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101, + 109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111, + 110,115,46,99,111,117,110,116,2,5,14,99,97,112,116,105,111,110,115,46, + 105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,4,75,105,110, + 100,0,1,7,99,97,112,116,105,111,110,6,6,70,105,108,116,101,114,0, + 1,7,99,97,112,116,105,111,110,6,3,69,120,116,0,1,7,99,97,112, + 116,105,111,110,6,6,83,111,117,114,99,101,0,1,0,0,0,0,14,100, + 97,116,97,99,111,108,115,46,99,111,117,110,116,2,4,16,100,97,116,97, + 99,111,108,115,46,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111, + 95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14, + 100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,10,110,101,119, + 102,105,110,97,109,101,115,1,5,119,105,100,116,104,2,124,7,111,112,116, + 105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95, + 112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101, + 115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95, + 99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116,7,13, + 99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103,101,116, + 110,97,109,101,6,10,110,101,119,102,105,110,97,109,101,115,9,100,97,116, + 97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105, + 110,103,100,97,116,97,108,105,115,116,0,7,12,110,101,119,102,105,102,105, + 108,116,101,114,115,1,5,119,105,100,116,104,2,110,7,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116, + 7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103, + 101,116,110,97,109,101,6,12,110,101,119,102,105,102,105,108,116,101,114,115, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,9,110,101,119, + 102,105,101,120,116,115,1,7,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110, + 115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6, + 9,110,101,119,102,105,101,120,116,115,9,100,97,116,97,99,108,97,115,115, + 7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97, + 108,105,115,116,0,7,12,110,101,119,102,105,115,111,117,114,99,101,115,1, + 5,119,105,100,116,104,3,254,1,7,111,112,116,105,111,110,115,11,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104, + 105,110,116,7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119, + 105,100,103,101,116,110,97,109,101,6,12,110,101,119,102,105,115,111,117,114, + 99,101,115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100, + 109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13, + 100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,11,116,115,116,114,105,110,103, + 101,100,105,116,10,110,101,119,102,105,110,97,109,101,115,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1, + 10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112, + 97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,124,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116, + 114,105,110,103,101,100,105,116,12,110,101,119,102,105,102,105,108,116,101,114, + 115,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,2,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116, + 101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,125,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,110,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,9,110,101,119,102,105,101,120,116, + 115,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,3,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116, + 101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,236,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 13,116,102,105,108,101,110,97,109,101,101,100,105,116,12,110,101,119,102,105, + 115,111,117,114,99,101,115,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0,0, + 18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4, + 5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109, + 97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,4,10,111, + 110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110, + 100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,31,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,254,1,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,8,116, + 116,97,98,112,97,103,101,9,116,116,97,98,112,97,103,101,53,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111, + 110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117, + 116,111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 19,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100, + 115,95,99,121,3,255,1,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116, + 9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6, + 8,78,101,119,32,70,111,114,109,8,111,110,108,97,121,111,117,116,7,25, + 102,111,114,109,116,101,109,112,108,97,116,101,111,110,99,104,105,108,100,115, + 99,97,108,101,100,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,11,116,119,105,100,103,101,116,103,114,105,100,12,116,119,105,100,103, + 101,116,103,114,105,100,52,5,99,111,108,111,114,4,3,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95, + 99,121,3,255,1,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105, + 111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110, + 103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101, + 121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115, + 101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110, + 103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101, + 114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103, + 95,97,117,116,111,97,112,112,101,110,100,12,111,103,95,115,97,118,101,115, + 116,97,116,101,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116, + 97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95, + 97,117,116,111,112,111,112,117,112,17,111,103,95,109,111,117,115,101,115,99, + 114,111,108,108,99,111,108,0,13,102,105,120,99,111,108,115,46,99,111,117, + 110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1, + 5,119,105,100,116,104,2,23,7,110,117,109,115,116,101,112,2,1,0,0, + 13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120, + 114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2, + 16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,6,14,99, + 97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116, + 105,111,110,6,4,75,105,110,100,0,1,7,99,97,112,116,105,111,110,6, + 1,73,4,104,105,110,116,6,9,73,110,104,101,114,105,116,101,100,0,1, + 7,99,97,112,116,105,111,110,6,8,78,97,109,101,98,97,115,101,0,1, + 7,99,97,112,116,105,111,110,6,10,70,111,114,109,115,117,102,102,105,120, + 0,1,7,99,97,112,116,105,111,110,6,11,83,111,117,114,99,101,32,70, + 105,108,101,0,1,7,99,97,112,116,105,111,110,6,9,70,111,114,109,32, + 70,105,108,101,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111, + 117,110,116,2,6,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105, + 116,101,109,115,14,7,10,110,101,119,102,111,110,97,109,101,115,1,5,119, + 105,100,116,104,2,96,7,111,112,116,105,111,110,115,11,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,4,110,97,109,101,6,10,110,101,119,102,111,110,97,109,101,115,10,111, + 110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119, + 104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,10,110,101,119, + 102,111,110,97,109,101,115,9,100,97,116,97,99,108,97,115,115,7,22,116, + 103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115, + 116,0,7,17,110,101,119,105,110,104,101,114,105,116,101,100,102,111,114,109, + 115,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12, + 99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11, + 99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,4,110,97,109,101,6,17,110,101,119, + 105,110,104,101,114,105,116,101,100,102,111,114,109,115,10,119,105,100,103,101, + 116,110,97,109,101,6,17,110,101,119,105,110,104,101,114,105,116,101,100,102, + 111,114,109,115,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105, + 100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,14,110, + 101,119,102,111,110,97,109,101,98,97,115,101,115,1,5,119,105,100,116,104, + 2,73,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,4,110,97, + 109,101,6,14,110,101,119,102,111,110,97,109,101,98,97,115,101,115,10,111, + 110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119, + 104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,14,110,101,119, + 102,111,110,97,109,101,98,97,115,101,115,9,100,97,116,97,99,108,97,115, + 115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116, + 97,108,105,115,116,0,7,17,110,101,119,102,111,102,111,114,109,115,117,102, + 102,105,120,101,115,1,5,119,105,100,116,104,2,69,7,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,4,110,97,109,101,6,15,110,101,119,102, + 111,102,111,114,109,115,117,102,102,105,120,10,119,105,100,103,101,116,110,97, + 109,101,6,17,110,101,119,102,111,102,111,114,109,115,117,102,102,105,120,101, + 115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,12,110,101, + 119,102,111,115,111,117,114,99,101,115,1,5,119,105,100,116,104,3,37,1, + 7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,4,110,97,109,101,6,12,110,101, + 119,102,111,115,111,117,114,99,101,115,10,111,110,115,104,111,119,104,105,110, + 116,7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100, + 103,101,116,110,97,109,101,6,12,110,101,119,102,111,115,111,117,114,99,101, + 115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,110,101, + 119,102,111,102,111,114,109,115,1,5,119,105,100,116,104,3,252,0,7,111, + 112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99, + 111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,4,110,97,109,101,6,10,109,101,119,102,111,102,111,114,109,115,10,111, + 110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119, + 104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,10,110,101,119, + 102,111,102,111,114,109,115,9,100,97,116,97,99,108,97,115,115,7,22,116, + 103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115, + 116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,115,116, + 114,105,110,103,101,100,105,116,10,110,101,119,102,111,110,97,109,101,115,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,1,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110, + 116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,96,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,17,110,101,119,105,110,104,101, + 114,105,116,101,100,102,111,114,109,115,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110, + 100,115,95,120,2,97,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,14,110,101,119,102,111,110,97,109, + 101,98,97,115,101,115,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,3,10,111,110,115,104,111,119,104,105,110,116,7, + 18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,111,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,73,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,17,110,101,119, + 102,111,102,111,114,109,115,117,102,102,105,120,101,115,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,4,10,111,110,115, + 104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101, + 100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,3,185,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,69,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101,110, + 97,109,101,101,100,105,116,12,110,101,119,102,111,115,111,117,114,99,101,115, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0, + 144,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46, + 98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,20,102,114, + 97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17, + 8,116,97,98,111,114,100,101,114,2,5,10,111,110,115,104,111,119,104,105, + 110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114, + 111,115,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,255,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,37,1,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,26,99,111,110,116,114,111,108,108, + 101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1, + 6,6,83,111,117,114,99,101,6,14,34,42,46,112,97,115,34,32,34,42, + 46,112,112,34,0,1,6,9,65,108,108,32,70,105,108,101,115,6,1,42, + 0,0,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102, + 105,108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110, + 97,109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,10,110,101,119,102, + 111,102,111,114,109,115,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108, + 111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0,0,18, + 102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,5, + 0,0,144,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97, + 103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,6,10,111,110, + 115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100, + 101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,3,37,2,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,252,0,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,26,99,111, + 110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116,46, + 100,97,116,97,1,1,6,10,70,111,114,109,32,70,105,108,101,115,6,5, + 42,46,109,102,109,0,1,6,9,65,108,108,32,70,105,108,101,115,6,1, + 42,0,0,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116, + 102,105,108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101, + 110,97,109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,0,0,0,0,8,116,116,97,98,112,97,103,101,10,116,116,97,98, + 112,97,103,101,49,53,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111, + 117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,20,9, + 98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95, + 99,121,3,18,2,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97, + 110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,6,84, + 111,111,38,108,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,11,116,119,105,100,103,101,116,103,114,105,100,12,116,119,105,100,103, + 101,116,103,114,105,100,51,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102, + 111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117, + 115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108, + 101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111, + 112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104, + 116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116, + 111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99, + 121,3,18,2,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105,111, + 110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103, + 12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121, + 114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101, + 114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95, + 97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104,97, + 110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99, + 111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109, + 111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111, + 108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105, + 116,101,109,115,14,1,5,119,105,100,116,104,2,18,8,110,117,109,115,116, + 97,114,116,2,1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105, + 120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119, + 115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99, + 97,112,116,105,111,110,115,46,99,111,117,110,116,2,10,14,99,97,112,116, + 105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110, + 6,1,83,4,104,105,110,116,6,10,83,97,118,101,32,102,105,108,101,115, + 0,1,7,99,97,112,116,105,111,110,6,1,80,4,104,105,110,116,6,12, + 80,97,114,115,101,32,115,111,117,114,99,101,0,1,7,99,97,112,116,105, + 111,110,6,1,72,4,104,105,110,116,6,25,72,105,100,101,32,99,111,110, + 115,111,108,101,32,40,119,105,110,51,50,32,111,110,108,121,41,0,1,7, + 99,97,112,116,105,111,110,6,1,77,4,104,105,110,116,6,30,83,104,111, + 119,32,111,117,116,112,117,116,32,105,110,32,109,101,115,115,97,103,101,115, + 32,119,105,110,100,111,119,0,1,7,99,97,112,116,105,111,110,6,4,77, + 101,110,117,0,1,7,99,97,112,116,105,111,110,6,8,83,104,111,114,116, + 99,117,116,4,104,105,110,116,6,79,83,101,108,101,99,116,32,105,116,101, + 109,32,102,114,111,109,32,39,83,101,116,116,105,110,103,115,39,45,39,67, + 111,110,102,105,103,117,114,101,32,77,83,69,105,100,101,39,45,39,83,104, + 111,114,116,99,117,116,115,39,10,39,84,111,111,108,32,49,39,46,46,39, + 84,111,111,108,32,49,48,39,46,0,1,7,99,97,112,116,105,111,110,6, + 6,83,99,46,75,101,121,4,104,105,110,116,6,12,83,104,111,114,116,99, + 117,116,32,107,101,121,0,1,7,99,97,112,116,105,111,110,6,7,65,108, + 116,46,83,99,46,4,104,105,110,116,6,22,65,108,116,101,114,110,97,116, + 101,32,115,104,111,114,116,99,117,116,32,107,101,121,0,1,7,99,97,112, + 116,105,111,110,6,4,70,105,108,101,0,1,7,99,97,112,116,105,111,110, + 6,10,80,97,114,97,109,101,116,101,114,115,0,0,0,0,14,100,97,116, + 97,99,111,108,115,46,99,111,117,110,116,2,10,16,100,97,116,97,99,111, + 108,115,46,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111, + 108,115,46,105,116,101,109,115,14,7,8,116,111,111,108,115,97,118,101,1, + 5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111, + 95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116, + 12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108, + 116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99, + 116,11,99,111,95,102,105,120,119,105,100,116,104,15,99,111,95,112,114,111, + 112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97, + 116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,8,119,105,100,116,104,109,105,110,2,13,8,119,105,100,116, + 104,109,97,120,2,13,10,119,105,100,103,101,116,110,97,109,101,6,8,116, + 111,111,108,115,97,118,101,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 7,9,116,111,111,108,112,97,114,115,101,1,5,119,105,100,116,104,2,13, + 7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99, + 117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120, + 119,105,100,116,104,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,8,119,105,100, + 116,104,109,105,110,2,13,8,119,105,100,116,104,109,97,120,2,13,10,119, + 105,100,103,101,116,110,97,109,101,6,9,116,111,111,108,112,97,114,115,101, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,8,116,111,111,108,104, + 105,100,101,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115, + 11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,15,99,111, + 95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118, + 101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,8,119,105,100,116,104,109,105,110,2,13,8, + 119,105,100,116,104,109,97,120,2,13,10,119,105,100,103,101,116,110,97,109, + 101,6,8,116,111,111,108,104,105,100,101,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,12,116,111,111,108,109,101,115,115,97,103,101,115,1,5, + 119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95, + 100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101, + 115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95, + 99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,12, + 116,111,111,108,109,101,115,115,97,103,101,115,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,9,116,111,111,108,109,101,110,117,115,1,5,119,105, + 100,116,104,2,107,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,111,110,115, + 104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119,104,105, + 110,116,10,119,105,100,103,101,116,110,97,109,101,6,9,116,111,111,108,109, + 101,110,117,115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105, + 100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7, + 13,116,111,111,108,115,104,111,114,116,99,117,116,115,1,5,119,105,100,116, + 104,2,86,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,16,99,111,95,114,111,119, + 100,97,116,97,99,104,97,110,103,101,0,10,119,105,100,103,101,116,110,97, + 109,101,6,13,116,111,111,108,115,104,111,114,116,99,117,116,115,9,100,97, + 116,97,99,108,97,115,115,7,17,116,103,114,105,100,101,110,117,109,100,97, + 116,97,108,105,115,116,0,7,6,116,111,111,108,115,99,1,5,99,111,108, + 111,114,4,7,0,0,144,11,99,111,108,111,114,97,99,116,105,118,101,4, + 1,0,0,128,5,119,105,100,116,104,2,55,7,111,112,116,105,111,110,115, + 11,11,99,111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103, + 101,116,110,97,109,101,6,6,116,111,111,108,115,99,9,100,97,116,97,99, + 108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,7,9,116,111,111,108,115,99,97,108,116, + 1,5,99,111,108,111,114,4,7,0,0,144,5,119,105,100,116,104,2,55, + 7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108, + 121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,9,116,111,111,108, + 115,99,97,108,116,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114, + 105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0, + 7,9,116,111,111,108,102,105,108,101,115,1,5,119,105,100,116,104,2,116, + 7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111, + 110,115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101, + 6,9,116,111,111,108,102,105,108,101,115,9,100,97,116,97,99,108,97,115, + 115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116, + 97,108,105,115,116,0,7,10,116,111,111,108,112,97,114,97,109,115,1,5, + 119,105,100,116,104,3,70,1,7,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111, + 95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10, + 111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111, + 119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,10,116,111, + 111,108,112,97,114,97,109,115,9,100,97,116,97,99,108,97,115,115,7,22, + 116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105, + 115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16, + 8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49, + 16,111,110,114,111,119,100,97,116,97,99,104,97,110,103,101,100,7,19,116, + 111,111,108,115,114,111,119,100,97,116,97,99,104,97,110,103,101,100,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,8,116,111,111,108,115,97,118,101,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,10,102,114,108,95,102,105,108,101,102,116, + 9,102,114,108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103, + 104,116,12,102,114,108,95,102,105,98,111,116,116,111,109,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101, + 100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,9,116,111,111,108,112,97,114,115, + 101,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,10,102,114,108,95,108,101,118,101,108,105,10,102,114,108,95,102,105, + 108,101,102,116,9,102,114,108,95,102,105,116,111,112,11,102,114,108,95,102, + 105,114,105,103,104,116,12,102,114,108,95,102,105,98,111,116,116,111,109,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,2,8,98, + 111,117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101, + 116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,8,116,111,111,108, + 104,105,100,101,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,10,102,114,108, + 95,102,105,108,101,102,116,9,102,114,108,95,102,105,116,111,112,11,102,114, + 108,95,102,105,114,105,103,104,116,12,102,114,108,95,102,105,98,111,116,116, + 111,109,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 3,8,98,111,117,110,100,115,95,120,2,28,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102, + 116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112, + 109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13, + 111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98, + 108,101,8,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,12,116, + 111,111,108,109,101,115,115,97,103,101,115,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115, + 95,120,2,42,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111, + 101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49, + 95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101, + 115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,11,116,115, + 116,114,105,110,103,101,100,105,116,9,116,111,111,108,109,101,110,117,115,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,5,10, + 111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97, + 110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,56,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,101,110,117, + 109,101,100,105,116,13,116,111,111,108,115,104,111,114,116,99,117,116,115,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114, + 108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4, + 5,0,0,144,0,0,8,116,97,98,111,114,100,101,114,2,6,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,164,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 86,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105, + 108,101,7,9,115,116,97,116,102,105,108,101,49,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117, + 112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101, + 13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99, + 104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101, + 97,100,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22, + 111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110, + 108,121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11, + 14,100,101,111,95,115,101,108,101,99,116,111,110,108,121,16,100,101,111,95, + 97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121, + 100,114,111,112,100,111,119,110,12,100,101,111,95,99,108,105,112,104,105,110, + 116,13,100,101,111,95,99,111,108,115,105,122,105,110,103,13,100,101,111,95, + 115,97,118,101,115,116,97,116,101,0,14,100,114,111,112,100,111,119,110,46, + 119,105,100,116,104,2,255,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,99,111,117,110,116,2,3,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,119,105,100,116,104,2,70,21,100,114,111,112,100,111,119,110, + 46,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99,111,95,114,101, + 97,100,111,110,108,121,17,99,111,95,109,111,117,115,101,109,111,118,101,102, + 111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,0,23,100,114,111,112,100,111, + 119,110,46,99,111,108,115,46,108,105,110,101,119,105,100,116,104,2,1,19, + 100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14, + 1,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110, + 108,121,17,99,111,95,109,111,117,115,101,109,111,118,101,102,111,99,117,115, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,0,5,119,105,100,116,104,2,70,9,108,105, + 110,101,119,105,100,116,104,2,1,7,99,97,112,116,105,111,110,6,4,73, + 116,101,109,4,100,97,116,97,1,6,6,84,111,111,108,32,49,6,6,84, + 111,111,108,32,50,6,6,84,111,111,108,32,51,6,6,84,111,111,108,32, + 52,6,6,84,111,111,108,32,53,6,6,84,111,111,108,32,54,6,6,84, + 111,111,108,32,55,6,6,84,111,111,108,32,56,6,6,84,111,111,108,32, + 57,6,7,84,111,111,108,32,49,48,0,0,1,7,111,112,116,105,111,110, + 115,11,11,99,111,95,114,101,97,100,111,110,108,121,17,99,111,95,109,111, + 117,115,101,109,111,118,101,102,111,99,117,115,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 0,5,119,105,100,116,104,2,70,9,108,105,110,101,119,105,100,116,104,2, + 1,7,99,97,112,116,105,111,110,6,8,83,104,111,114,116,99,117,116,4, + 100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6, + 0,6,0,6,0,0,0,1,7,111,112,116,105,111,110,115,11,11,99,111, + 95,114,101,97,100,111,110,108,121,17,99,111,95,109,111,117,115,101,109,111, + 118,101,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,0,5,119,105,100, + 116,104,2,70,9,108,105,110,101,119,105,100,116,104,2,1,7,99,97,112, + 116,105,111,110,6,9,65,108,116,101,114,110,97,116,101,4,100,97,116,97, + 1,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6, + 0,0,0,0,8,118,97,108,117,101,109,97,120,2,9,16,111,110,98,101, + 102,111,114,101,100,114,111,112,100,111,119,110,7,20,116,111,111,108,115,104, + 111,114,116,99,117,116,100,114,111,112,100,111,119,110,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103, + 101,100,105,116,6,116,111,111,108,115,99,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112, + 104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,7,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,251,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,55,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107, + 118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100, + 111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116, + 117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100, + 111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116, + 111,110,114,101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108, + 105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116, + 9,116,111,111,108,115,99,97,108,116,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,8,116,97,98,111,114,100,101,114,2,8,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,51,1,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,55,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117, + 14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118, + 97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111, + 110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117, + 114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114, + 101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95, + 101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111, + 110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111, + 110,114,101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108,105, + 112,112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105, + 116,9,116,111,111,108,102,105,108,101,115,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112, + 104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114, + 2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114, + 2,9,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101, + 120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,107,1,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,116,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 0,18,99,111,110,116,114,111,108,108,101,114,46,105,110,99,108,117,100,101, + 11,7,102,97,95,120,117,115,114,7,102,97,95,120,103,114,112,7,102,97, + 95,120,111,116,104,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,10,116,111,111, + 108,112,97,114,97,109,115,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100, + 101,114,2,10,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110, + 116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,224,1,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,70,1, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,0,0,8,116,116,97,98,112,97,103,101,10,116,116,97,98,112,97, + 103,101,50,48,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100, + 115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117, + 110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3, + 18,2,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,8,38,83,116,111, + 114,97,103,101,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,115, + 101,116,116,105,110,103,115,101,100,105,116,111,114,11,111,112,116,105,111,110, + 115,115,107,105,110,11,14,111,115,107,95,110,111,108,97,121,111,117,116,99, + 120,14,111,115,107,95,110,111,108,97,121,111,117,116,99,121,0,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,6,69,100,105,116,111,114,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1, + 2,40,2,2,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,2,15,8,98,111,117,110,100,115,95,121,2,108,9,98, + 111,117,110,100,115,95,99,120,2,54,9,98,111,117,110,100,115,95,99,121, + 2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,16,115,101, + 116,116,105,110,103,115,97,117,116,111,108,111,97,100,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,9,65,117,116,111,32,108,111,97,100,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1, + 2,63,2,2,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,15,8,98,111,117,110,100,115,95,121,2,52,9,98, + 111,117,110,100,115,95,99,120,2,76,9,98,111,117,110,100,115,95,99,121, + 2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,16,115,101, + 116,116,105,110,103,115,97,117,116,111,115,97,118,101,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,9,65,117,116,111,32,115,97,118,101,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1, + 2,65,2,2,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117, + 110,100,115,95,120,3,183,0,8,98,111,117,110,100,115,95,121,2,52,9, + 98,111,117,110,100,115,95,99,120,2,78,9,98,111,117,110,100,115,95,99, + 121,2,16,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121, + 111,117,116,101,114,54,17,102,114,97,109,101,46,102,114,97,109,101,105,95, + 108,101,102,116,2,5,16,102,114,97,109,101,46,102,114,97,109,101,105,95, + 116,111,112,2,5,18,102,114,97,109,101,46,102,114,97,109,101,105,95,114, + 105,103,104,116,2,5,19,102,114,97,109,101,46,102,114,97,109,101,105,95, + 98,111,116,116,111,109,2,5,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,102,105,108,101,102,116,9,102,114, + 108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103,104,116,12, + 102,114,108,95,102,105,98,111,116,116,111,109,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,13,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,2,31, + 7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112, + 116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97, + 110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116, + 105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99, + 101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110, + 95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112,108,97, + 99,101,95,109,105,110,100,105,115,116,2,5,13,112,108,97,99,101,95,109, + 97,120,100,105,115,116,2,5,13,112,108,97,99,101,95,111,112,116,105,111, + 110,115,11,13,112,108,111,95,101,110,100,109,97,114,103,105,110,0,0,7, + 116,98,117,116,116,111,110,6,115,97,118,101,98,117,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,18,111,119,49,95,102,111,110,116,108, + 105,110,101,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110, + 100,115,95,120,3,8,3,8,98,111,117,110,100,115,95,121,2,5,9,98, + 111,117,110,100,115,95,99,120,2,49,9,98,111,117,110,100,115,95,99,121, + 2,21,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,11,97,115,95,100, + 105,115,97,98,108,101,100,16,97,115,95,108,111,99,97,108,100,105,115,97, + 98,108,101,100,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7, + 99,97,112,116,105,111,110,6,4,83,97,118,101,9,111,110,101,120,101,99, + 117,116,101,7,7,115,97,118,101,101,120,101,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,6,108, + 111,97,100,98,117,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,18,111,119,49,95,102,111,110,116,108,105,110,101,104,101,105,103,104,116, + 13,111,119,49,95,97,117,116,111,115,99,97,108,101,0,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,210,2,8,98, + 111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2, + 49,9,98,111,117,110,100,115,95,99,121,2,21,7,97,110,99,104,111,114, + 115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5, + 115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16,97, + 115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,4, + 76,111,97,100,9,111,110,101,120,101,99,117,116,101,7,7,108,111,97,100, + 101,120,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,12,115,101,116,116, + 105,110,103,115,102,105,108,101,11,111,112,116,105,111,110,115,115,107,105,110, + 11,14,111,115,107,95,110,111,108,97,121,111,117,116,99,120,14,111,115,107, + 95,110,111,108,97,121,111,117,116,99,121,0,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,13,83,101,116,116,105,110,103,115,32,70,105,108, + 101,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128, + 7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,80,2,0,0,10,111,110,115,104,111,119,104,105,110,116,7,18,104, + 105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111, + 117,110,100,115,95,120,2,5,8,98,111,117,110,100,115,95,121,2,5,9, + 98,111,117,110,100,115,95,99,120,3,200,2,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95, + 114,105,103,104,116,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100, + 7,15,115,101,116,116,105,110,103,115,100,97,116,97,101,110,116,26,99,111, + 110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116,46, + 100,97,116,97,1,1,6,13,80,114,111,106,101,99,116,32,70,105,108,101, + 115,6,5,42,46,112,114,106,0,1,6,9,65,108,108,32,70,105,108,101, + 115,6,1,42,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101, + 102,97,117,108,116,101,120,116,6,3,112,114,106,22,99,111,110,116,114,111, + 108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,19,69,110, + 116,101,114,32,83,101,116,116,105,110,103,115,32,70,105,108,101,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,16,115,101,116,116,105,110,103,115,100,101, + 98,117,103,103,101,114,11,111,112,116,105,111,110,115,115,107,105,110,11,14, + 111,115,107,95,110,111,108,97,121,111,117,116,99,120,14,111,115,107,95,110, + 111,108,97,121,111,117,116,99,121,0,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,8,68,101,98,117,103,103,101,114,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,65,2,2,0, + 8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120, + 2,15,8,98,111,117,110,100,115,95,121,3,132,0,9,98,111,117,110,100, + 115,95,99,120,2,79,9,98,111,117,110,100,115,95,99,121,2,16,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,15,115,101,116,116,105,110, + 103,115,115,116,111,114,97,103,101,11,111,112,116,105,111,110,115,115,107,105, + 110,11,14,111,115,107,95,110,111,108,97,121,111,117,116,99,120,14,111,115, + 107,95,110,111,108,97,121,111,117,116,99,121,0,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,7,83,116,111,114,97,103,101,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,53,2, + 2,0,8,116,97,98,111,114,100,101,114,2,12,8,98,111,117,110,100,115, + 95,120,2,15,8,98,111,117,110,100,115,95,121,3,68,1,9,98,111,117, + 110,100,115,95,99,120,2,67,9,98,111,117,110,100,115,95,99,121,2,16, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,19,115,101,116,116, + 105,110,103,115,112,114,111,106,101,99,116,116,114,101,101,11,111,112,116,105, + 111,110,115,115,107,105,110,11,14,111,115,107,95,110,111,108,97,121,111,117, + 116,99,120,14,111,115,107,95,110,111,108,97,121,111,117,116,99,121,0,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,80,114,111,106,101, + 99,116,32,84,114,101,101,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,2,79,2,2,0,8,116,97,98,111,114,100, + 101,114,2,14,8,98,111,117,110,100,115,95,120,3,183,0,8,98,111,117, + 110,100,115,95,121,3,132,0,9,98,111,117,110,100,115,95,99,120,2,93, + 9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,14,115,101,116,116,105,110,103,115,109,97,99,114, + 111,115,11,111,112,116,105,111,110,115,115,107,105,110,11,14,111,115,107,95, + 110,111,108,97,121,111,117,116,99,120,14,111,115,107,95,110,111,108,97,121, + 111,117,116,99,121,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,6,77,97,99,114,111,115,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,1,2,48,2,2,0,8,116,97,98,111,114, + 100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,15,8,98,111,117, + 110,100,115,95,121,3,180,0,9,98,111,117,110,100,115,95,99,120,2,62, + 9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,13,115,101,116,116,105,110,103,115,116,111,111,108, + 115,11,111,112,116,105,111,110,115,115,107,105,110,11,14,111,115,107,95,110, + 111,108,97,121,111,117,116,99,120,14,111,115,107,95,110,111,108,97,121,111, + 117,116,99,121,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 5,84,111,111,108,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,36,2,2,0,8,116,97,98,111,114,100,101, + 114,2,11,8,98,111,117,110,100,115,95,120,2,15,8,98,111,117,110,100, + 115,95,121,3,44,1,9,98,111,117,110,100,115,95,99,120,2,50,9,98, + 111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,17,115,101,116,116,105,110,103,115,116,101,109,112,108,97, + 116,101,115,11,111,112,116,105,111,110,115,115,107,105,110,11,14,111,115,107, + 95,110,111,108,97,121,111,117,116,99,120,14,111,115,107,95,110,111,108,97, + 121,111,117,116,99,121,0,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,9,84,101,109,112,108,97,116,101,115,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,1,2,68,2,2,0,8,116, + 97,98,111,114,100,101,114,2,10,8,98,111,117,110,100,115,95,120,2,15, + 8,98,111,117,110,100,115,95,121,3,20,1,9,98,111,117,110,100,115,95, + 99,120,2,82,9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,22,115,101,116,116,105,110,103,115, + 99,111,109,112,111,110,101,110,116,115,116,111,114,101,11,111,112,116,105,111, + 110,115,115,107,105,110,11,14,111,115,107,95,110,111,108,97,121,111,117,116, + 99,120,14,111,115,107,95,110,111,108,97,121,111,117,116,99,121,0,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,15,67,111,109,112,111,110, + 101,110,116,32,83,116,111,114,101,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,113,2,2,0,8,116,97,98,111, + 114,100,101,114,2,13,8,98,111,117,110,100,115,95,120,3,183,0,8,98, + 111,117,110,100,115,95,121,2,108,9,98,111,117,110,100,115,95,99,120,2, + 127,9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,14,115,101,116,116,105,110,103,115,108,97,121, + 111,117,116,11,111,112,116,105,111,110,115,115,107,105,110,11,14,111,115,107, + 95,110,111,108,97,121,111,117,116,99,120,14,111,115,107,95,110,111,108,97, + 121,111,117,116,99,121,0,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,13,87,105,110,100,111,119,32,76,97,121,111,117,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,95,2, + 2,0,8,116,97,98,111,114,100,101,114,2,15,8,98,111,117,110,100,115, + 95,120,3,183,0,8,98,111,117,110,100,115,95,121,3,156,0,9,98,111, + 117,110,100,115,95,99,120,2,109,9,98,111,117,110,100,115,95,99,121,2, + 16,0,0,6,116,108,97,98,101,108,7,116,108,97,98,101,108,49,8,116, + 97,98,111,114,100,101,114,2,16,8,98,111,117,110,100,115,95,120,2,15, + 8,98,111,117,110,100,115,95,121,2,84,9,98,111,117,110,100,115,95,99, + 120,2,118,9,98,111,117,110,100,115,95,99,121,2,14,7,99,97,112,116, + 105,111,110,6,18,76,111,97,100,47,115,97,118,101,32,115,101,116,116,105, + 110,103,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,12,115,101,116,116,105, + 110,103,115,109,97,107,101,11,111,112,116,105,111,110,115,115,107,105,110,11, + 14,111,115,107,95,110,111,108,97,121,111,117,116,99,120,14,111,115,107,95, + 110,111,108,97,121,111,117,116,99,121,0,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,4,77,97,107,101,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,1,2,36,2,2,0,8,116,97, + 98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,15,8, + 98,111,117,110,100,115,95,121,3,156,0,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117, + 101,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,18,115,101, + 116,116,105,110,103,115,117,115,101,114,99,111,108,111,114,115,11,111,112,116, + 105,111,110,115,115,107,105,110,11,14,111,115,107,95,110,111,108,97,121,111, + 117,116,99,120,14,111,115,107,95,110,111,108,97,121,111,117,116,99,121,0, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11,85,115,101,114, + 32,67,111,108,111,114,115,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,2,75,2,2,0,8,116,97,98,111,114,100, + 101,114,2,8,8,98,111,117,110,100,115,95,120,2,15,8,98,111,117,110, + 100,115,95,121,3,228,0,9,98,111,117,110,100,115,95,99,120,2,89,9, + 98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,20,115,101,116,116,105,110,103,115,102,111,114,109,97, + 116,109,97,99,114,111,115,11,111,112,116,105,111,110,115,115,107,105,110,11, + 14,111,115,107,95,110,111,108,97,121,111,117,116,99,120,14,111,115,107,95, + 110,111,108,97,121,111,117,116,99,121,0,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,13,70,111,114,109,97,116,32,77,97,99,114,111,115, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,96,2,2,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111, + 117,110,100,115,95,120,2,15,8,98,111,117,110,100,115,95,121,3,252,0, + 9,98,111,117,110,100,115,95,99,120,2,110,9,98,111,117,110,100,115,95, + 99,121,2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,17, + 115,101,116,116,105,110,103,115,102,111,110,116,97,108,105,97,115,11,111,112, + 116,105,111,110,115,115,107,105,110,11,14,111,115,107,95,110,111,108,97,121, + 111,117,116,99,120,14,111,115,107,95,110,111,108,97,121,111,117,116,99,121, + 0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10,70,111,110, + 116,32,65,108,105,97,115,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,2,64,2,2,0,8,116,97,98,111,114,100, + 101,114,2,7,8,98,111,117,110,100,115,95,120,2,15,8,98,111,117,110, + 100,115,95,121,3,204,0,9,98,111,117,110,100,115,95,99,120,2,78,9, + 98,111,117,110,100,115,95,99,121,2,16,0,0,0,0,0,9,116,115,116, + 97,116,102,105,108,101,9,115,116,97,116,102,105,108,101,49,8,102,105,108, + 101,110,97,109,101,6,13,111,112,116,105,111,110,115,102,111,46,115,116,97, + 7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121, + 0,4,108,101,102,116,3,144,0,3,116,111,112,3,24,2,0,0,16,116, + 115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116, + 114,105,110,103,115,46,100,97,116,97,1,6,44,87,114,111,110,103,32,101, + 110,99,111,100,105,110,103,32,99,97,110,32,100,97,109,97,103,101,32,121, + 111,117,114,32,115,111,117,114,99,101,32,102,105,108,101,115,46,6,30,68, + 111,32,121,111,117,32,119,105,115,104,32,116,111,32,115,101,116,32,101,110, + 99,111,100,105,110,103,32,116,111,6,15,42,42,42,32,87,65,82,78,73, + 78,71,32,42,42,42,6,6,72,97,110,103,117,112,6,9,73,110,116,101, + 114,114,117,112,116,6,4,81,117,105,116,6,19,73,108,108,101,103,97,108, + 32,105,110,115,116,114,117,99,116,105,111,110,6,10,84,114,97,99,101,32, + 116,114,97,112,6,5,65,98,111,114,116,6,9,66,85,83,32,101,114,114, + 111,114,6,24,70,108,111,97,116,105,110,103,45,112,111,105,110,116,32,101, + 120,99,101,112,116,105,111,110,6,4,75,105,108,108,6,21,85,115,101,114, + 45,100,101,102,105,110,101,100,32,115,105,103,110,97,108,32,49,6,22,83, + 101,103,109,101,110,116,97,116,105,111,110,32,118,105,111,108,97,116,105,111, + 110,6,21,85,115,101,114,45,100,101,102,105,110,101,100,32,115,105,103,110, + 97,108,32,50,6,11,66,114,111,107,101,110,32,112,105,112,101,6,11,65, + 108,97,114,109,32,99,108,111,99,107,6,11,84,101,114,109,105,110,97,116, + 105,111,110,6,11,83,116,97,99,107,32,102,97,117,108,116,6,24,67,104, + 105,108,100,32,115,116,97,116,117,115,32,104,97,115,32,99,104,97,110,103, + 101,100,6,8,67,111,110,116,105,110,117,101,6,17,83,116,111,112,44,32, + 117,110,98,108,111,99,107,97,98,108,101,6,13,75,101,121,98,111,97,114, + 100,32,115,116,111,112,6,24,66,97,99,107,103,114,111,117,110,100,32,114, + 101,97,100,32,102,114,111,109,32,116,116,121,6,23,66,97,99,107,103,114, + 111,117,110,100,32,119,114,105,116,101,32,116,111,32,116,116,121,6,26,85, + 114,103,101,110,116,32,99,111,110,100,105,116,105,111,110,32,111,110,32,115, + 111,99,107,101,116,6,18,67,80,85,32,108,105,109,105,116,32,101,120,99, + 101,101,100,101,100,6,24,70,105,108,101,32,115,105,122,101,32,108,105,109, + 105,116,32,101,120,99,101,101,100,101,100,6,19,86,105,114,116,117,97,108, + 32,97,108,97,114,109,32,99,108,111,99,107,6,21,80,114,111,102,105,108, + 105,110,103,32,97,108,97,114,109,32,99,108,111,99,107,6,18,87,105,110, + 100,111,119,32,115,105,122,101,32,99,104,97,110,103,101,6,16,73,47,79, + 32,110,111,119,32,112,111,115,115,105,98,108,101,6,21,80,111,119,101,114, + 32,102,97,105,108,117,114,101,32,114,101,115,116,97,114,116,0,4,108,101, + 102,116,3,216,0,3,116,111,112,3,24,2,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tprojectoptionsfo,''); +end. diff --git a/mseide-msegui/apps/ide/projecttreeform.mfm b/mseide-msegui/apps/ide/projecttreeform.mfm new file mode 100644 index 0000000..c24da08 --- /dev/null +++ b/mseide-msegui/apps/ide/projecttreeform.mfm @@ -0,0 +1,407 @@ +object projecttreefo: tprojecttreefo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 263 + bounds_y = 431 + bounds_cx = 286 + bounds_cy = 201 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 276 + 201 + ) + dragdock.splitter_size = 0 + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Project Tree' + oncreate = projecttreefooncreate + oneventloopstart = projecttreefoonloaded + ondestroy = projecttreefoondestroy + onstatupdate = projecttreeonupdatestat + moduleclassname = 'tdockform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 276 + bounds_cy = 201 + anchors = [] + optionsgrid = [og_colsizing, og_focuscellonenter, og_savestate, og_colchangeontabkey, og_wrapcol, og_autopopup] + datacols.count = 2 + datacols.options = [co_savestate, co_mousescrollrow] + datacols.items = < + item[projectedit] + linecolorfix = -1610612733 + width = 141 + options = [co_readonly, co_savestate, co_mousescrollrow] + oncellevent = projecteditoncellevent + widgetname = 'projectedit' + dataclass = ttreeitemeditlist + datalist.imnr_expanded = 1 + datalist.imagelist = nodeicons + datalist.imagewidth = 16 + datalist.imageheight = 16 + datalist.onstatreaditem = projecteditonstatreaditem + datalist.ondragbegin = editdragbegin + datalist.ondragover = editdragover + datalist.ondragdrop = editdragrop + end + item[edit] + linecolorfix = -1610612733 + width = 129 + options = [co_fill, co_savestate, co_mousescrollrow] + onshowhint = colshowhintexe + widgetname = 'edit' + dataclass = titemeditlist + end> + datarowheight = 17 + statfile = mainfo.projectstatfile + oncellevent = gridcellevent + reffontheight = 16 + object projectedit: ttreeitemedit + optionswidget1 = [ow1_autoheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + onpopup = projecteditonpopup + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 141 + bounds_cy = 18 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_exitoncursor, oe_hintclippedtext, oe_locate] + onchange = projecteditonchange + onsetvalue = captionset + onupdaterowvalues = projecteditonupdaterowvalues + fieldedit = edit + options = [teo_treecolnavig, teo_keyrowmoving] + oncheckrowmove = itemoncheckrowmove + end + object edit: trecordfieldedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.button.options = [fbo_invisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + options = [fbo_invisible] + end + item + color = -2147483646 + imagenr = 17 + onexecute = receditdialogexe + end> + taborder = 2 + onshowhint = edithintexe + visible = False + bounds_x = 142 + bounds_y = 0 + bounds_cx = 129 + bounds_cy = 17 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + textflags = [tf_ycentered, tf_clipo, tf_noselect, tf_ellipseleft] + oncellevent = editoncellevent + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 16 + end + end + object unitpopup: tpopupmenu + menu.action = addunitfileact + menu.submenu.count = 6 + menu.submenu.items = < + item + action = addunitfileact + end + item + action = removeunitfileact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = adddiract + end + item + action = removediract + end + item + action = editdiract + end> + left = 8 + top = 8 + end + object addunitfileact: taction + caption = '&Add Unit' + onexecute = addunitfileonexecute + left = 112 + top = 8 + end + object filedialog: tfiledialog + controller.options = [fdo_checkexist, fdo_savelastdir] + controller.historymaxcount = 0 + left = 8 + top = 168 + end + object removeunitfileact: taction + caption = '&Remove Unit' + onexecute = removeunitfileonexecute + onupdate = remfileupdateexe + left = 112 + top = 24 + end + object filepopup: tpopupmenu + menu.submenu.count = 6 + menu.submenu.items = < + item + action = addfileact + end + item + action = removefileact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = adddiract + end + item + action = removediract + end + item + action = editdiract + end> + menu.state = [as_localhint] + left = 8 + top = 40 + end + object addfileact: taction + caption = 'Add Text File' + onexecute = addfileexe + left = 112 + top = 48 + end + object removefileact: taction + caption = 'Remove Text File' + onexecute = removefileonexecute + onupdate = remfileupdateexe + left = 112 + top = 64 + end + object cmodulepopup: tpopupmenu + menu.submenu.count = 6 + menu.submenu.items = < + item + action = addcmoduleact + end + item + action = removecmoduleact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = adddiract + end + item + action = removediract + end + item + action = editdiract + end> + menu.state = [as_localhint] + left = 8 + top = 72 + end + object removecmoduleact: taction + caption = 'Remove C-File' + onexecute = removecmoduleonexecute + onupdate = remfileupdateexe + left = 112 + top = 104 + end + object addcmoduleact: taction + caption = 'Add C-File' + onexecute = addcmoduleonexecute + left = 112 + top = 88 + end + object cmoduledialog: tfiledialog + controller.filterlist.data = ( + ( + 'C-Source (*.c)' + '"*.c"' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + controller.historymaxcount = 0 + left = 96 + top = 168 + end + object adddiract: taction + caption = 'Add Directory' + onexecute = adddirexe + onupdate = updateadddirexe + top = 104 + end + object removediract: taction + caption = 'Remove Directory' + onexecute = remdirexe + onupdate = updateremdirexe + top = 120 + end + object nodeicons: timagelist + count = 8 + left = 144 + top = 120 + image = { + 00000000020000003000000030000000380A0000000000000000000000000000 + 0000000000000000000000000000000000000000FF00FF6300000006FF00FF0A + 00000006FF00FF0900000006FF00FF0B00000001FFFFFF0400000002FF00FF09 + 00000001FFFFFF0400000002FF00FF0800000001FFFFFF0400000002FF00FF0A + 00000001FFFFFF0400000001FFFFFF0100000001FF00FF0800000001FFFFFF04 + 00000001FFFFFF0100000001FF00FF0700000001FFFFFF0400000001FFFFFF01 + 00000001FF00FF0900000001FFFFFF0400000001FFFFFF0200000001FF00FF07 + 00000001FFFFFF0400000001FFFFFF0200000001FF00FF0600000001FFFFFF02 + FF8E7801E0321005AEAEAE01E032100100000001FF00FF0500000001FFFFFF04 + 00000005FF00FF0600000001FFFFFF0400000005FF00FF0500000001FFFFFF02 + F2F2F201E0E0E00780808001FF00FF0500000001FFFFFF080000000180808001 + FF00FF0500000001FFFFFF080000000180808001FF00FF0400000001FFFFFF02 + F2F2F201E0E0E00780808001FF00FF0500000001FFFFFF080000000180808001 + FF00FF0500000001FFFFFF080000000180808001FF00FF0400000001FFFFFF02 + F2F2F201E0E0E00780808001FF00FF0500000001FFFFFF080000000180808001 + FF00FF0500000001FFFFFF080000000180808001FF00FF0400000001FFFFFF02 + F2F2F201E0E0E001F2F2F205E0E0E00180808001FF00FF0500000001FFFFFF08 + 0000000180808001FF00FF0500000001FFFFFF080000000180808001FF00FF04 + 00000001FFFFFF02F2F2F201E0E0E001F2F2F201E0E0E00380808001E0E0E001 + 80808001FF00FF0500000001FFFFFF080000000180808001FF00FF0500000001 + FFFFFF080000000180808001FF00FF0400000001FFFFFF02F2F2F201E0E0E001 + F2F2F201E0E0E00380808001E0E0E00180808001FF00FF0500000001FFFFFF08 + 0000000180808001FF00FF0500000001FFFFFF080000000180808001FF00FF04 + 00000001FFFFFF02F2F2F201E0E0E001F2F2F20180808004E0E0E00180808001 + FF00FF050000000A80808001FF00FF050000000A80808001FF00FF0400000003 + F2F2F201E0E0E00780808001FF00FF068080800AFF00FF068080800AFF00FF05 + 80808002F2F2F20180808008FF00FF9400000006FF00FF2A00000001FFFFFF04 + 00000002FF00FF0AFF8E7801E0321006AEAEAE01E032100100000001FF00FF06 + FF8E7801E0321006AEAEAE01E032100100000001FF00FF0500000001FFFFFF04 + 00000001FFFFFF0100000001FF00FF09F2F2F201E0E0E00880808001FF00FF06 + F2F2F201E0E0E00880808001FF00FF0500000001FFFFFF02FF8E7801E0321005 + AEAEAE01E032100100000001FF00FF05F2F2F201E0E0E00880808001FF00FF06 + F2F2F201E0E0E00880808001FF00FF0500000001FFFFFF02F2F2F201E0E0E007 + 80808001FF00FF05F2F2F201E0E0E00880808001FF00FF06F2F2F201E0E0E008 + 80808001FF00FF0500000001FFFFFF02F2F2F201E0E0E00780808001FF00FF05 + F2F2F201E0E0E001F2F2F206E0E0E00180808001FF00FF06F2F2F201E0E0E001 + F2F2F206E0E0E00180808001FF00FF0500000001FFFFFF02F2F2F201E0E0E007 + 80808001FF00FF05F2F2F201E0E0E001F2F2F201E0E0E00480808001E0E0E001 + 80808001FF00FF06F2F2F201E0E0E001F2F2F201E0E0E00480808001E0E0E001 + 80808001FF00FF0500000001FFFFFF02F2F2F201E0E0E001F2F2F205E0E0E001 + 80808001FF00FF05F2F2F201E0E0E001F2F2F201E0E0E00480808001E0E0E001 + 80808001FF00FF06F2F2F201E0E0E001F2F2F201E0E0E00480808001E0E0E001 + 80808001FF00FF0500000001FFFFFF02F2F2F201E0E0E001F2F2F201E0E0E003 + 80808001E0E0E00180808001FF00FF05F2F2F201E0E0E001F2F2F20180808005 + E0E0E00180808001FF00FF06F2F2F201E0E0E001F2F2F20180808005E0E0E001 + 80808001FF00FF0500000001FFFFFF02F2F2F201E0E0E001F2F2F201E0E0E003 + 80808001E0E0E00180808001FF00FF05F2F2F201E0E0E00880808001FF00FF06 + F2F2F201E0E0E00880808001FF00FF0500000001FFFFFF02F2F2F201E0E0E001 + F2F2F20180808004E0E0E00180808001FF00FF05F2F2F20180808009FF00FF06 + F2F2F20180808009FF00FF0500000003F2F2F201E0E0E00780808001FF00FF25 + 80808002F2F2F20180808008FF00FFD400000006FF00FF0B7F7F7F0100000004 + 7F7F7F01FF00FF097F7F7F01000000047F7F7F01FF00FF0A00000001FFFFFF04 + 00000002FF00FF0A00000001FFFFFF0100FFFF01FFFFFF0100FFFF0100000001 + FF00FF090000000100FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0A + 00000001FFFFFF0400000001FFFFFF0100000001FF00FF080000000AFF00FF05 + 0000000100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100000003 + FF00FF0700000001FFFFFF0400000001FFFFFF0200000001FF00FF0700000001 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100000001FF00FF0400000001FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0600000001 + FFFFFF0400000005FF00FF060000000100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0400000001 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF0100000001FF00FF0600000001FFFFFF02FF8E7801E0321005AEAEAE01 + E032100100000001FF00FF0400000001FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0400000001 + FFFFFF0100FFFF01FFFFFF010000000AFF00FF0300000001FFFFFF02EBEBEB01 + E0E0E00780808001FF00FF040000000100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0400000001 + 00FFFF01FFFFFF010000000100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01 + BFBFBF0100FFFF01BFBFBF0100FFFF0100000001FF00FF0300000001FFFFFF02 + EBEBEB01E0E0E001EBEBEB0480808001E0E0E00180808001FF00FF0400000001 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100000001FF00FF0400000001FFFFFF010000000100FFFF01BFBFBF01 + 00FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF0100000001 + FF00FF0400000001FFFFFF02EBEBEB01E0E0E001EBEBEB01E0E0E00380808001 + E0E0E00180808001FF00FF040000000100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0400000002 + 00FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF01 + 00FFFF0100000001FF00FF0500000001FFFFFF02EBEBEB01E0E0E001EBEBEB01 + E0E0E00380808001E0E0E00180808001FF00FF050000000AFF00FF050000000A + FF00FF0600000001FFFFFF02EBEBEB01E0E0E001EBEBEB0180808004E0E0E001 + 80808001FF00FF2400000003EBEBEB01E0E0E00780808001FF00FF2580808002 + EBEBEB0180808008FF00FF3200000000000000000000000000000000F801F801 + FC000000F803F803FC010000F807F807FC030000F80FF80FFC3F0000F81FF81F + FC3F0000F83FF83FFC3F0000F83FF83FFC3F0000F83FF83FFC3F0000F83FF83F + FC3F0000F83FF83FFC3F0000F83FF83FFC3F0000F83FF83FFC3F0000F03FF03F + F83F0000000000000000000000000000000000000000000000000000FC000000 + 00000000FC01F81FF81F0000FC03F81FF81F0000FC3FF81FF81F0000FC3FF81F + F81F0000FC3FF81FF81F0000FC3FF81FF81F0000FC3FF81FF81F0000FC3FF81F + F81F0000FC3FF81FF81F0000FC3FF81FF81F0000FC3F000000000000F83F0000 + 0000000000000000000000000000000000000000000000000000000000000000 + FC000000F801FC00FC010000F801FC00FC030000FC0FFE07FC070000FC1FFE0F + FC0F0000FC1FFE0FFC3F0000FC1FFE7FFC3F0000FC1FFE7FFC3F0000FC1FFE3F + FC3F0000FC1FFE1FFC3F0000F81FFC0FFC3F000000000000FC3F000000000000 + F83F00000000000000000000 + } + end + object dummyimage: timagelist + width = 0 + height = 0 + left = 144 + top = 144 + end + object editdiract: taction + caption = 'Edit Directory Caption' + onexecute = editdirexe + onupdate = udateeditdirexe + top = 136 + end + object c: tstringcontainer + strings.data = ( + 'Pascal Units' + 'C Modules' + 'Text Files' + 'Do you wish to remove "' + 'Select Directory' + 'Do you want to remove' + 'with the sub-items from project?' + ) + left = 208 + top = 168 + end +end diff --git a/mseide-msegui/apps/ide/projecttreeform.pas b/mseide-msegui/apps/ide/projecttreeform.pas new file mode 100644 index 0000000..b609f2d --- /dev/null +++ b/mseide-msegui/apps/ide/projecttreeform.pas @@ -0,0 +1,1565 @@ +{ MSEide Copyright (c) 1999-2012 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit projecttreeform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +//todo: relative path linking + +interface +uses + mseforms,msewidgetgrid,mselistbrowser,msedatanodes,msetypes,msemenus,mseevent, + mseactions,msefiledialog,msestat,msegrids,msedesigner,msedataedits, + msegraphutils,msegui,msestrings,mseact,mseguiglob,mseclasses,msebitmap,mseedit, + mseglob,msegraphics,msescrollbar,msesys,msehash,mseifiglob,msestringcontainer, + msevaluenodes; + +type + projectnodety = (pnk_none,pnk_source,pnk_form,pnk_files,pnk_dir); +const + filenodes = [pnk_source,pnk_dir,pnk_form]; +type + tdirnode = class; + tprojecttreefo = class(tdockform) + grid: twidgetgrid; + projectedit: ttreeitemedit; + edit: trecordfieldedit; + unitpopup: tpopupmenu; + addunitfileact: taction; + removeunitfileact: taction; + filedialog: tfiledialog; + filepopup: tpopupmenu; + addfileact: taction; + removefileact: taction; + cmodulepopup: tpopupmenu; + removecmoduleact: taction; + addcmoduleact: taction; + cmoduledialog: tfiledialog; + adddiract: taction; + removediract: taction; + nodeicons: timagelist; + dummyimage: timagelist; + editdiract: taction; + c: tstringcontainer; + procedure projecteditonchange(const sender: TObject); + procedure projecteditonstatreaditem(const sender: TObject; + const reader: tstatreader; var aitem: ttreelistitem); + procedure projecteditonupdaterowvalues(const sender: TObject; + const aindex: Integer; const aitem: tlistitem); + procedure projecttreefooncreate(const sender: tobject); + procedure projecttreefoonloaded(const sender: tobject); + procedure projecttreefoondestroy(const sender: tobject); + procedure projecteditonpopup(const sender: tobject; var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); + + procedure addunitfileonexecute(const sender: tobject); + procedure removeunitfileonexecute(const sender: tobject); + + procedure projecttreeonupdatestat(const sender: tobject; + const filer: tstatfiler); + procedure projecteditoncellevent(const sender: tobject; + var info: celleventinfoty); + + procedure itemoncheckrowmove(const curindex: Integer; const newindex: Integer; + var accept: Boolean); + + procedure addfileexe(const sender: TObject); + procedure editdragbegin(const sender: ttreeitemedit; + const aitem: ttreelistitem; var candrag: Boolean; + var dragobject: ttreeitemdragobject; var processed: Boolean); + procedure editdragover(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var accept: Boolean; + var processed: Boolean); + procedure editdragrop(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var processed: Boolean); + procedure editoncellevent(const sender: TObject; var info: celleventinfoty); + procedure removefileonexecute(const sender: TObject); + procedure addcmoduleonexecute(const sender: TObject); + procedure removecmoduleonexecute(const sender: TObject); + procedure adddirexe(const sender: TObject); + procedure receditdialogexe(const sender: TObject); + procedure gridcellevent(const sender: TObject; var info: celleventinfoty); + procedure edithintexe(const sender: TObject; var info: hintinfoty); + procedure colshowhintexe(const sender: tdatacol; const arow: Integer; + var info: hintinfoty); + procedure updateremdirexe(const sender: tcustomaction); + procedure updateadddirexe(const sender: tcustomaction); + procedure remdirexe(const sender: TObject); + procedure remfileupdateexe(const sender: tcustomaction); + procedure udateeditdirexe(const sender: tcustomaction); + procedure editdirexe(const sender: TObject); + procedure captionset(const sender: TObject; var avalue: msestring; + var accept: Boolean); + private + funitloading: boolean; + finited: boolean; + protected + function addirectory(const aname: filenamety): tdirnode; + function gettreedir: filenamety; + public + procedure clear; + end; + + tprojectnode = class(ttreelistedititem) + fkind: projectnodety; + ferror: boolean; + protected + function getcurrentimagenr: integer; virtual; + function compare(const r: tlistitem; + const acasesensitive: boolean): integer; override; + public + constructor create(const akind: projectnodety); reintroduce; + end; + + tfilenode = class(tprojectnode) + private + ffilename: filenamety; + fpath: filenamety; + fmodified: boolean; + protected + function getcurrentimagenr: integer; override; + procedure setfilename(const value: filenamety); virtual; + function parentpath: msestring; + procedure updatepath; + public + constructor create(const akind: projectnodety); + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + function getvaluetext: msestring; override; + + property filename: filenamety read ffilename write setfilename; + property path: filenamety read fpath; + end; + + tdirnode = class(tfilenode) + protected + fcustomcaption: msestring; + procedure setfilename(const value: filenamety); override; + function getcurrentimagenr: integer; override; + function calccaption: msestring; + public + constructor create; + procedure setvaluetext(var avalue: msestring); override; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + end; + + tcmodulenode = class(tfilenode) + end; + + tformnode = class(tfilenode,irecordfield) + private + fclasstype: msestring; + fformname: msestring; + finstancevarname: msestring; + protected + function getcurrentimagenr: integer; override; + procedure setfilename(const value: filenamety); override; + function getfieldtext(const fieldindex: integer): msestring; + procedure setfieldtext(const fieldindex: integer; var avalue: msestring); + public + constructor create; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + end; + + tunitnode = class(tfilenode) + private + fformfile: tformnode; + protected + function getcurrentimagenr: integer; override; + public + procedure dostatread(const reader: tstatreader); override; + function setformfile(afilename: filenamety): tformnode; + end; + + tprojectrootnode = class(tprojectnode) + public + function getvaluetext: msestring; override; + end; + + tfilenodehashlist = class(tpointermsestringhashdatalist) + end; + + tnamehashlist = class(tpointeransistringhashdatalist) + end; + + tfilesnode = class(tprojectrootnode) + private + fhashlist: tfilenodehashlist; + fchangedcount: integer; + protected + function getcurrentimagenr: integer; override; + function createsubnode: ttreelistitem; override; + function createnode: tfilenode; virtual; + procedure removefilehash(const anode: tfilenode); virtual; + procedure addfilehash(const anode: tfilenode); virtual; + public + constructor create; + destructor destroy; override; + procedure clear; override; + procedure loadlist; virtual; + function addfile(const currentnode: tprojectnode; + const afilename: filenamety): tfilenode; + procedure addfiles(const currentnode: tprojectnode; + const afilenames: filenamearty); + procedure removefile(const anode: tfilenode); + function findfile(const filename: filenamety): tfilenode; + end; + + tunitsnode = class(tfilesnode) + private +// fmoduleclassnames: filenamearty; +// fmodulenames: filenamearty; +// fmodulefilenames: filenamearty; +// fstatreading: boolean; + fnamelist: tnamehashlist; + fclasstypelist: tnamehashlist; + protected + function createsubnode: ttreelistitem; override; + function createnode: tfilenode; override; + procedure removefilehash(const anode: tfilenode); override; + procedure addfilehash(const anode: tfilenode); override; + public + constructor create; + destructor destroy; override; + procedure clear; override; + procedure loadlist; override; + function addfile(const currentnode: tprojectnode; + const afilename: filenamety): tunitnode; +// function moduleclassnames: msestringarty; +// function modulenames: msestringarty; +// function modulefilenames(const aname: string): filenamearty; + function findformbyname(const aname: string; + out afilename: filenamety): boolean; + function findformbyclass(const aclassname: string; + out afilename: filenamety): boolean; + end; + + stopcheckprocty = procedure (var astop: boolean) of object; + tcmodulesnode = class(tfilesnode) + protected + function createsubnode: ttreelistitem; override; + function createnode(const afilename: filenamety): tfilenode; + reintroduce; virtual; + public + constructor create; + procedure parse(const astopcheckproc: stopcheckprocty = nil); + procedure modulechanged(const aname: filenamety); + procedure modulecompiled(const aname: filenamety); + end; + + tprojecttree = class + private + funits: tunitsnode; + fcmodules: tcmodulesnode; + ffiles: tfilesnode; + procedure docellevent(const projectedit: ttreeitemedit; + var info: celleventinfoty); + protected + public + constructor create; + function units: tunitsnode; + function cmodules: tcmodulesnode; + function files: tfilesnode; + function updatestat(const filer: tstatfiler): boolean; + //true if read data found + procedure updatelist; + end; + +var + projecttreefo: tprojecttreefo; + projecttree: tprojecttree; + +function isformfile(const aname: filenamety): boolean; + +implementation +uses + sysutils,projecttreeform_mfm,msefileutils,main,sourceform,msewidgets, + msedatalist,msedrag,sourceupdate,msemacros,projectoptionsform; +type + stringconsts = ( + pascalunits, //0 Pascal Units + str_cmodules, //1 C Modules + textfiles, //2 Text Files + wishremove, //3 Do you wish to remove " + selectdirectory, //4 Select Directory + wantremove, //5 Do you want to remove + withsubitems //6 with the sub-items from project? + ); +const +// unitscaption = 'Pascal Units'; +// cmodulescaption = 'C Modules'; +// filescaption = 'Text Files'; + mainico = -1; + fileico = 0; + unitico = 2; + formico = 4; + dirico = 6; + +function isformfile(const aname: filenamety): boolean; +begin + result:= issamefilename(aname,replacefileext(aname,formfileext)); +end; + +{ tprojectnode } + +constructor tprojectnode.create(const akind: projectnodety); +begin + fkind:= akind; + inherited create; +// include(fstate1,ns1_customsort); + fstate:= fstate + [ns_sorted]; +end; + +function tprojectnode.compare(const r: tlistitem; + const acasesensitive: boolean): integer; +begin + result:= 0; + if fkind = pnk_dir then begin + dec(result); + end; + if tprojectnode(r).fkind = pnk_dir then begin + inc(result); + end; + if result = 0 then begin + result:= inherited compare(r,acasesensitive); +// result:= msestringicomp(l.caption,r.caption); + end; +end; + +function tprojectnode.getcurrentimagenr: integer; +begin + result:= -1; +end; + +{ tfilenode } + +constructor tfilenode.create(const akind: projectnodety); +begin + fkind:= akind; + inherited create(akind); +// filename:= afilename; + include(fstate,ns_readonly); +end; + +procedure tfilenode.dostatread(const reader: tstatreader); +begin + ffilename:= reader.readmsestring('file',ffilename); +// ffilenamerel:= reader.readmsestring('filerel',ffilename); +// tfilesnode(rootnode).fhashlist.add(ffilename,self); + inherited; +end; + +procedure tfilenode.dostatwrite(const writer: tstatwriter); +begin + writer.writemsestring('file',ffilename); + writer.writeinteger('kind',ord(fkind)); + inherited; +end; + +procedure tfilenode.setfilename(const value: filenamety); +begin + ffilename:= relativepath(value,parentpath); + if fkind <> pnk_dir then begin + caption:= msefileutils.filename(value); + end; + with tfilesnode(rootnode) do begin + removefilehash(self); + self.updatepath; + addfilehash(self); + end; +end; + +function tfilenode.getvaluetext: msestring; +begin + result:= ffilename; +end; +{ +function tfilenode.getpath: filenamety; +begin + result:= ffilename; +end; +} +function tfilenode.parentpath: msestring; +var + n1: tprojectnode; +begin + n1:= self; + repeat + n1:= tprojectnode(n1.fparent); + until (n1 = nil) or (n1.fkind = pnk_dir); + if n1 <> nil then begin + result:= tfilenode(n1).path; + end + else begin + result:= getcurrentdirmse; + end; +end; + +procedure tfilenode.updatepath; +var + mstr1,mstr2: msestring; +begin + mstr1:= filename; + if fkind = pnk_dir then begin + expandprmacros1(mstr1); + end; + mstr2:= parentpath; + fpath:= filepath(mstr2,mstr1); + case fkind of + pnk_dir: begin + with tdirnode(self) do begin + if fcustomcaption <> '' then begin + caption:= fcustomcaption; + end + else begin + if (mstr1 <> '') and (mstr1[1] = '/') then begin + caption:= fpath; + end + else begin + caption:= relativepath(fpath,mstr2); + end; + end; + end; + end; + pnk_source,pnk_form: begin + caption:= msefileutils.filename(fpath); + end; + end; +end; + +function tfilenode.getcurrentimagenr: integer; +begin + result:= fileico; +end; + +{ tformnode } + +constructor tformnode.create; +begin + inherited create(pnk_form); + include(fstate,ns_nosubnodestat); +// filename:= afilename; + add(trecordfielditem.create(irecordfield(self),0,'classtype',true,-1, + projecttreefo.dummyimage)); + add(trecordfielditem.create(irecordfield(self),1,'name',true,-1, + projecttreefo.dummyimage)); + add(trecordfielditem.create(irecordfield(self),2,'instancevarname',true,-1, + projecttreefo.dummyimage)); +end; + +procedure tformnode.dostatread(const reader: tstatreader); +begin + inherited; + fclasstype:= reader.readmsestring('classtype',fclasstype); + fformname:= reader.readmsestring('formname',fformname); + finstancevarname:= reader.readmsestring('instancevarname',finstancevarname); +end; + +procedure tformnode.dostatwrite(const writer: tstatwriter); +begin + inherited; + writer.writemsestring('classtype',fclasstype); + writer.writemsestring('formname',fformname); + writer.writemsestring('instancevarname',finstancevarname); +end; + +procedure tformnode.setfilename(const value: filenamety); +var + po1: pmoduleinfoty; +begin + if value <> '' then begin + po1:= nil; + try + po1:= mainfo.openformfile(value,false,false,false,true,false); + except + end; + if po1 <> nil then begin + fclasstype:= msestring(po1^.moduleclassname); + fformname:= msestring(po1^.instance.Name); + finstancevarname:= msestring(po1^.instancevarname); + end + else begin + fclasstype:= ''; + end; + end; + inherited; + caption:= removefileext(msefileutils.filename(value)); +end; + + +function tformnode.getfieldtext(const fieldindex: integer): msestring; +begin + case fieldindex of + 0: result:= fclasstype; + 1: result:= fformname; + 2: result:= finstancevarname; + else result:= ''; + end; +end; + +procedure tformnode.setfieldtext(const fieldindex: integer; + var avalue: msestring); +var + n1: tfilesnode; +begin + n1:= tfilesnode(rootnode); + n1.removefilehash(self); + case fieldindex of + 0: begin + fclasstype:= msestring(designer.changemoduleclassname(fpath, + ansistring(avalue))); + avalue:= fclasstype; + end; + 1: begin + fformname:= msestring(designer.changemodulename(fpath,ansistring(avalue))); + avalue:= fformname; + end; + 2: begin + finstancevarname:= msestring(designer.changeinstancevarname( + fpath,ansistring(avalue))); + avalue:= finstancevarname; + end; + end; + n1.addfilehash(self); +end; + +function tformnode.getcurrentimagenr: integer; +begin + result:= formico; +end; + +{ tunitnode } + +procedure tunitnode.dostatread(const reader: tstatreader); +begin + inherited;{ + if (ftreelevel = 2) and (fkind = pnk_form) or isformfile(ffilename) then begin + fkind:= pnk_form; + tunitnode(fparent).fformfile:= self; + end; + } +end; + +function tunitnode.getcurrentimagenr: integer; +begin + result:= fileico; + if fcount > 0 then begin + result:= unitico; + end; +end; + +function tunitnode.setformfile(afilename: filenamety): tformnode; +begin + if afilename = '' then begin + fformfile:= nil; + clear; + end + else begin + projecttreefo.projectedit.itemlist.beginupdate(); + try + if fformfile = nil then begin + fformfile:= tformnode.create; + add(ttreelistitem(fformfile)); + end; + fformfile.filename:= afilename; + finally + projecttreefo.projectedit.itemlist.endupdate(); + end; + end; + result:= fformfile; + imagenr:= getcurrentimagenr; +end; + +{ tprojectrootnode } + +function tprojectrootnode.getvaluetext: msestring; +begin + result:= ''; +end; + +{ tfilesnode } + +constructor tfilesnode.create; +begin + fhashlist:= tfilenodehashlist.create; + inherited create(pnk_files); + fstate:= fstate + [ns_readonly,ns_drawemptybox]; + caption:= projecttreefo.c[ord(textfiles)]; +end; + +destructor tfilesnode.destroy; +begin + inherited; + fhashlist.free; +end; + +function tfilesnode.addfile(const currentnode: tprojectnode; + const afilename: filenamety): tfilenode; +var + n1: tprojectnode; + ind1: integer; +begin + result:= findfile(afilename); + if result = nil then begin + projecttreefo.projectedit.itemlist.beginupdate(); + try + n1:= currentnode; + if n1 <> nil then begin + ind1:= n1.count; + end; + while (n1 <> nil) and (n1.fkind <> pnk_dir) do begin + ind1:= n1.parentindex; + n1:= tprojectnode(n1.parent); + end; + if (n1 = nil) then begin + n1:= self; + ind1:= count; + end; + result:= createnode; + n1.insert(ind1,result); + result.filename:= afilename; + fhashlist.add(result.fpath,result); + inc(fchangedcount); + finally + projecttreefo.projectedit.itemlist.endupdate(); + end; + end; +end; + +procedure tfilesnode.removefilehash(const anode: tfilenode); +begin + if anode.fkind <> pnk_dir then begin + fhashlist.delete(anode.fpath,anode); + end; +end; + +procedure tfilesnode.addfilehash(const anode: tfilenode); +begin + if anode.fkind <> pnk_dir then begin + fhashlist.add(anode.fpath,anode); + end; +end; + +procedure tfilesnode.addfiles(const currentnode: tprojectnode; + const afilenames: filenamearty); +var + int1: integer; +begin + beginupdate; + try + for int1:= 0 to high(afilenames) do begin + addfile(currentnode,afilenames[int1]); + end; + finally + endupdate; + end; +end; + +procedure tfilesnode.removefile(const anode: tfilenode); +var + int1: integer; +begin + with anode do begin + if fkind <> pnk_dir then begin + if fmodified then begin + dec(fchangedcount); + end; + removefilehash(anode); + end; + for int1:= 0 to count - 1 do begin + if tprojectnode(fitems[int1]).fkind in [pnk_source,pnk_dir] then begin + removefile(tfilenode(fitems[int1])); + end; + end; + end; +// fhashlist.delete(anode.fpath,anode); +end; + +function tfilesnode.findfile(const filename: filenamety): tfilenode; +//var +// int1: integer; +begin + result:= tfilenode(fhashlist.find(filename)); +end; + +function tfilesnode.createnode: tfilenode; +begin + result:= tfilenode.create(pnk_source); +end; + +function tfilesnode.createsubnode: ttreelistitem; +begin + result:= tfilenode.create(pnk_none); +end; + +procedure tfilesnode.clear; +begin + fhashlist.clear; + inherited; + fchangedcount:= 0; +end; + +procedure tfilesnode.loadlist; +var + li: tmacrolist; + + procedure scan(const anode: tprojectnode; const apath: filenamety); + var + int1: integer; + mstr1: filenamety; + begin + with tfilenode(anode) do begin + if fkind in filenodes then begin + mstr1:= filename; + if fkind = pnk_dir then begin + li.expandmacros1(mstr1); + end; + fpath:= filepath(apath,mstr1); + case fkind of + pnk_dir: begin + with tdirnode(anode) do begin + if fcustomcaption <> '' then begin + fcaption:= fcustomcaption; + end + else begin + if (mstr1 <> '') and (mstr1[1] = '/') then begin + fcaption:= fpath; + end + else begin + fcaption:= relativepath(fpath,apath); + end; + end; + end; + for int1:= 0 to fcount-1 do begin + scan(tprojectnode(fitems[int1]),fpath); + end; + end; + pnk_source,pnk_form: begin +// fhashlist.add(fpath,anode); + addfilehash(tfilenode(anode)); + if fkind = pnk_source then begin + for int1:= 0 to fcount-1 do begin + scan(tprojectnode(fitems[int1]),apath); + end; + end; + end; + end; + end; + end; + anode.imagenr:= anode.getcurrentimagenr; + end; //scan + +var + int1: integer; + mstr1: msestring; + +begin + li:= getmacros; + beginupdate; + try + fhashlist.clear; + mstr1:= getcurrentdirmse; + for int1:= 0 to fcount-1 do begin + scan(tprojectnode(fitems[int1]),mstr1); + end; + imagenr:= getcurrentimagenr; + finally + fchangedcount:= fhashlist.count; + li.Free; + endupdate; + end; +end; + +function tfilesnode.getcurrentimagenr: integer; +begin + result:= dirico; +end; + +{ tunitsnode } + +constructor tunitsnode.create; +begin + inherited create; + caption:= projecttreefo.c[ord(pascalunits)]; + fnamelist:= tnamehashlist.create; + fclasstypelist:= tnamehashlist.create; +end; + +destructor tunitsnode.destroy; +begin + inherited; + fnamelist.free; + fclasstypelist.free; +end; + +function tunitsnode.addfile(const currentnode: tprojectnode; + const afilename: filenamety): tunitnode; +begin + result:= tunitnode(inherited addfile(currentnode,afilename)); +end; + +function tunitsnode.createnode: tfilenode; +begin + result:= tunitnode.create(pnk_source); +end; + +function tunitsnode.createsubnode: ttreelistitem; +begin + result:= tunitnode.create(pnk_none); +end; + +function tunitsnode.findformbyclass(const aclassname: string; + out afilename: filenamety): boolean; +var + n1: tformnode; +begin + afilename:= ''; + result:= fclasstypelist.find(aclassname,pointer(n1)); + if result then begin + afilename:= n1.path; + end; +end; + +function tunitsnode.findformbyname(const aname: string; + out afilename: filenamety): boolean; +var + n1: tformnode; +begin + afilename:= ''; + result:= fnamelist.find(aname,pointer(n1)); + if result then begin + afilename:= n1.path; + end; +end; + +procedure tunitsnode.clear; +begin + fnamelist.clear; + fclasstypelist.clear; + inherited; +end; + +procedure tunitsnode.removefilehash(const anode: tfilenode); +begin + if anode.fkind = pnk_form then begin + with tformnode(anode) do begin + fnamelist.delete(struppercase(string(fformname)),anode); + fclasstypelist.delete(struppercase(string(fclasstype)),anode); + end; + end; + inherited; +end; + +procedure tunitsnode.addfilehash(const anode: tfilenode); +begin + if anode.fkind = pnk_form then begin + with tformnode(anode) do begin + fnamelist.add(struppercase(string(fformname)),anode); + fclasstypelist.add(struppercase(string(fclasstype)),anode); + end; + end; +end; + +procedure tunitsnode.loadlist; +begin + fnamelist.clear; + fclasstypelist.clear; + inherited; +end; + +{ +function tunitsnode.modulefilenames: filenamearty; +var + int1,int2,int3: integer; +begin + if fstatreading then begin + result:= fmodulefilenames; + end + else begin + int2:= 0; + for int1:= 0 to fcount - 1 do begin + with tfilenode(fitems[int1]) do begin + for int3:= 0 to count - 1 do begin + with tfilenode(items[int3]) do begin + if fkind = pnk_form then begin + additem(result,ffilename,int2); + end; + end; + end; + end; + end; + setlength(result,int2); + end; +end; + +function tunitsnode.modulenames: msestringarty; +var + int1,int2,int3: integer; +begin + if fstatreading then begin + result:= fmodulenames; + end + else begin + int2:= 0; + for int1:= 0 to fcount - 1 do begin + with tfilenode(fitems[int1]) do begin + for int3:= 0 to count - 1 do begin + with tformnode(items[int3]) do begin + if fkind = pnk_form then begin + additem(result,struppercase(fformname),int2); + end; + end; + end; + end; + end; + setlength(result,int2); + end; +end; + +function tunitsnode.moduleclassnames: msestringarty; +var + int1,int2,int3: integer; +begin + if fstatreading then begin + result:= fmoduleclassnames; + end + else begin + int2:= 0; + for int1:= 0 to fcount - 1 do begin + with tfilenode(fitems[int1]) do begin + for int3:= 0 to count - 1 do begin + with tformnode(items[int3]) do begin + if fkind = pnk_form then begin + additem(result,struppercase(fclasstype),int2); + end; + end; + end; + end; + end; + setlength(result,int2); + end; +end; +} +{ tcmodulesnode } + +constructor tcmodulesnode.create; +begin + inherited; + caption:= projecttreefo.c[ord(str_cmodules)]; +end; + +procedure tcmodulesnode.parse(const astopcheckproc: stopcheckprocty); +var + int1,int2: integer; + bo1: boolean; +begin + if fchangedcount > 0 then begin + application.beginwait; + try + bo1:= false; + for int1:= 0 to count - 1 do begin + with tcmodulenode(fitems[int1]) do begin + if fmodified then begin + if application.waitescaped then begin + break; + end; + sourceupdater.updatesourceunit(ffilename,int2,false); + end; + end; + if {$ifndef FPC}@{$endif}astopcheckproc <> nil then begin + astopcheckproc(bo1); + if bo1 then begin + break; + end; + end; + end; + finally + application.endwait; + end; + end; +end; + +function tcmodulesnode.createsubnode: ttreelistitem; +begin + result:= tcmodulenode.create(pnk_none); +end; + +function tcmodulesnode.createnode(const afilename: filenamety): tfilenode; +begin + result:= tcmodulenode.create(pnk_source); +end; + +procedure tcmodulesnode.modulechanged(const aname: filenamety); +var + node1: tcmodulenode; +begin + node1:= tcmodulenode(fhashlist.find(aname)); + if (node1 <> nil) and not node1.fmodified then begin + node1.fmodified:= true; + inc(fchangedcount); + end; +end; + +procedure tcmodulesnode.modulecompiled(const aname: filenamety); +var + node1: tcmodulenode; +begin + node1:= tcmodulenode(fhashlist.find(aname)); + if (node1 <> nil) and node1.fmodified then begin + node1.fmodified:= false; + dec(fchangedcount); + end; +end; + +{ tprojecttree } + +constructor tprojecttree.create; +begin + funits:= tunitsnode.create; + fcmodules:= tcmodulesnode.create; + ffiles:= tfilesnode.create; +end; + +function tprojecttree.files: tfilesnode; +begin + result:= ffiles; +end; + +function tprojecttree.units: tunitsnode; +begin + result:= funits; +end; + +function tprojecttree.cmodules: tcmodulesnode; +begin + result:= fcmodules; +end; + +procedure tprojecttree.updatelist; +begin + funits.loadlist; + fcmodules.loadlist; + ffiles.loadlist; + projecttreefo.grid.invalidate; +end; + +function tprojecttree.updatestat(const filer: tstatfiler): boolean; + + procedure scan(const anode: tprojectnode); + var + int1: integer; + begin + with anode do begin + if fkind = pnk_form then begin + with tformnode(anode) do begin + funits.fnamelist.add(struppercase(string(fformname)),anode); + funits.fclasstypelist.add(struppercase(string(fclasstype)),anode); + end; + end; + for int1:= 0 to count-1 do begin + scan(tprojectnode(fitems[int1])); + end; + end; + end; + +begin + result:= false; + if not filer.candata then begin + exit; + end; + if not filer.iswriter then begin + funits.clear; + fcmodules.clear; + ffiles.clear; + with tstatreader(filer) do begin + result:= checkvar('units') or checkvar('cmodules') or checkvar('files'); + end; + end; + projecttreefo.projectedit.itemlist.beginupdate; + try + projecttreefo.funitloading:= true; + projecttreefo.projectedit.itemlist.updatenode('units',filer,funits); + scan(funits); + projecttreefo.funitloading:= false; + projecttreefo.projectedit.itemlist.updatenode('cmodules',filer,fcmodules); + projecttreefo.projectedit.itemlist.updatenode('files',filer,ffiles); + funits.caption:= projecttreefo.c[ord(pascalunits)]; + fcmodules.caption:= projecttreefo.c[ord(str_cmodules)]; + ffiles.caption:= projecttreefo.c[ord(textfiles)]; + finally + projecttreefo.projectedit.itemlist.endupdate; + end; +end; + +procedure tprojecttree.docellevent(const projectedit: ttreeitemedit; + var info: celleventinfoty); +var + node1,node2: ttreelistitem; +begin + if iscellclick(info,[ccr_nodefaultzone,ccr_dblclick]) then begin + if projectedit.item.treelevel > 0 then begin + node1:= projectedit[info.cell.row]; + node2:= node1.rootnode; + if node2 = funits then begin + with tunitnode(node1) do begin + case fkind of + pnk_form: begin + mainfo.openformfile(fpath,true,true,true,true,false); + end; + pnk_source: begin + sourcefo.openfile(fpath,true); + end; + end; + end; + end + else begin + if (node2 = ffiles) or (node2 = fcmodules) then begin + with tfilenode(node1) do begin + if fkind <> pnk_dir then begin + sourcefo.openfile(fpath,true); + end; + end; + end; + end; + end; + end; +end; + +{ tprojecttreefo } + +procedure tprojecttreefo.projecteditonstatreaditem(const sender: TObject; + const reader: tstatreader; var aitem: ttreelistitem); +var + kind: projectnodety; +begin + kind:= projectnodety(reader.readinteger('kind',ord(pnk_none),ord(low(projectnodety)), + ord(high(projectnodety)))); + case kind of + pnk_form: begin + aitem:= tformnode.create; + end; + pnk_source: begin + if funitloading then begin + aitem:= tunitnode.create(kind); + end + else begin + aitem:= tfilenode.create(kind); + end; + end; + pnk_dir: begin + aitem:= tdirnode.create; + end; + end; +end; + +function tprojecttreefo.addirectory(const aname: filenamety): tdirnode; +var + n2: tprojectnode; +begin + result:= tdirnode.create; + result.filename:= relativepath(aname,gettreedir); + n2:= tprojectnode(projectedit.item); + if (n2.fkind = pnk_dir) or (n2.parent = nil) then begin + n2.insert(0,result); + end + else begin + while (n2.treelevel > 1) and + (tprojectnode(n2.parent).fkind <> pnk_dir) do begin + n2:= tprojectnode(n2.parent); + end; + n2.parent.insert(n2.parentindex,result); + end; + tfilesnode(n2.rootnode).loadlist; +end; + +procedure tprojecttreefo.projecteditonupdaterowvalues(const sender: TObject; + const aindex: Integer; const aitem: tlistitem); +begin +{ + if aitem is trecordfielditem then begin + edit[aindex]:= trecordfielditem(aitem).valuetext; + end + else begin + if aitem is tfilenode then begin + edit[aindex]:= tfilenode(aitem).ffilename; + end + else begin + edit[aindex]:= ''; + end; + end; + } +end; + +procedure tprojecttreefo.projecttreefooncreate(const sender: tobject); +begin + projecttree:= tprojecttree.create; +end; + +procedure tprojecttreefo.projecttreefoonloaded(const sender: tobject); +begin + if not finited then begin + finited:= true; + projecttree.units.caption:= projecttreefo.c[ord(pascalunits)]; + projecttree.files.caption:= projecttreefo.c[ord(textfiles)]; + projecttree.cmodules.caption:= projecttreefo.c[ord(str_cmodules)]; + projectedit.itemlist.add(ttreelistedititem(projecttree.units)); + projectedit.itemlist.add(ttreelistedititem(projecttree.cmodules)); + projectedit.itemlist.add(ttreelistedititem(projecttree.files)); + end; +end; + +procedure tprojecttreefo.clear; +begin + projecttree.units.clear; + projecttree.files.clear; + projecttree.cmodules.clear; +end; + +procedure tprojecttreefo.projecttreefoondestroy(const sender: tobject); +begin + projecttree.Free; +end; + +procedure tprojecttreefo.projecteditonpopup(const sender: tobject; + var amenu: tpopupmenu; var mouseinfo: mouseeventinfoty); +begin + if projectedit.item.rootnode = projecttree.units then begin + freeandnil(amenu); + tpopupmenu.additems(amenu,self,mouseinfo,unitpopup); + end + else begin + if projectedit.item.rootnode = projecttree.files then begin + freeandnil(amenu); + tpopupmenu.additems(amenu,self,mouseinfo,filepopup); + end + else begin + if projectedit.item.rootnode = projecttree.cmodules then begin + freeandnil(amenu); + tpopupmenu.additems(amenu,self,mouseinfo,cmodulepopup); + end; + end; + end; +end; + +procedure tprojecttreefo.addunitfileonexecute(const sender: tobject); +begin + mainfo.openfile.controller.filename:= gettreedir; + mainfo.opensource(fk_unit,true,false,tprojectnode(projectedit.item)); + activate; //windowmanager can activate new form window +end; + +procedure tprojecttreefo.removeunitfileonexecute(const sender: tobject); +var + rowbefore: integer; + rnode: ttreelistitem; +begin + with tfilenode(projectedit.item) do begin + if askok(c[ord(wishremove)]+ ffilename + + '"?','') then begin + if sourcefo.closepage(fpath) then begin + rowbefore:= grid.row; + rnode:= rootnode; + if rnode is tfilesnode then begin + tfilesnode(rnode).removefile(tfilenode(projectedit.item)); + end; + projectedit.item.Free; + grid.row:= rowbefore; + end; + end; + end; +end; + +procedure tprojecttreefo.addcmoduleonexecute(const sender: TObject); +begin + cmoduledialog.controller.filename:= gettreedir; + if cmoduledialog.execute = mr_ok then begin + projecttree.cmodules.addfiles(tprojectnode(projectedit.item), + cmoduledialog.controller.filenames); + end; +end; + +procedure tprojecttreefo.removecmoduleonexecute(const sender: TObject); +begin + removeunitfileonexecute(sender); +end; + +procedure tprojecttreefo.addfileexe(const sender: TObject); +begin + with mainfo.openfile do begin + controller.filename:= gettreedir; + if execute = mr_ok then begin + projecttree.files.addfiles(tprojectnode(projectedit.item), + controller.filenames); + end; + end; +end; + +procedure tprojecttreefo.adddirexe(const sender: TObject); +var + int1: integer; +begin + with mainfo.openfile.controller do begin + filename:= gettreedir; + if execute(fdk_open,c[ord(selectdirectory)], + [fdo_directory]) = mr_ok then begin + int1:= addirectory(filename).index; + if int1 >= 0 then begin + grid.row:= int1; + end; + end; + end; +end; + +procedure tprojecttreefo.remdirexe(const sender: TObject); + +begin + if askyesno(c[ord(wantremove)]+' '+lineend+ + tfilenode(projectedit.item).fpath+lineend+ + c[ord(withsubitems)]) then begin + tfilesnode(projectedit.item.rootnode).removefile(tdirnode(projectedit.item)); + projectedit.item.free; + end; +end; + +procedure tprojecttreefo.removefileonexecute(const sender: TObject); +begin + removeunitfileonexecute(sender); +end; + +procedure tprojecttreefo.projecttreeonupdatestat(const sender: tobject; + const filer: tstatfiler); +begin +// projecttree.updatestat(filer); +end; + +procedure tprojecttreefo.projecteditoncellevent(const sender: tobject; + var info: celleventinfoty); +begin + projecttree.docellevent(projectedit,info); +end; + +procedure tprojecttreefo.editoncellevent(const sender: TObject; + var info: celleventinfoty); +begin + projecttree.docellevent(projectedit,info); +end; + +procedure tprojecttreefo.itemoncheckrowmove(const curindex: Integer; const newindex: Integer; + var accept: Boolean); +var + source,dest: ttreelistitem; +begin + source:= projectedit[curindex]; + dest:= projectedit[newindex]; + if (source.treelevel = 1) and (dest.treelevel = 1) and + (source.parent = dest.parent) then begin + accept:= true; + end; +end; + +procedure tprojecttreefo.projecteditonchange(const sender: TObject); +begin +// updatesubmodules; +end; + +procedure tprojecttreefo.editdragbegin(const sender: ttreeitemedit; + const aitem: ttreelistitem; var candrag: Boolean; + var dragobject: ttreeitemdragobject; var processed: Boolean); +begin + candrag:= aitem.treelevel = 1; +end; + +procedure tprojecttreefo.editdragover(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var accept: Boolean; + var processed: Boolean); +begin + accept:= source.parent = dest.parent; +end; + +procedure tprojecttreefo.editdragrop(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var processed: Boolean); +begin + sender.dragdrop(dragobject); +end; + +procedure tprojecttreefo.receditdialogexe(const sender: TObject); +var + fn1: filenamety; + no1: tfilenode; +begin + no1:= tfilenode(projectedit.item); + fn1:= no1.path; + with mainfo.openfile.controller do begin + if execute(fn1,fdk_open,c[ord(selectdirectory)],[fdo_directory]) then begin + no1.filename:= relativepath(fn1,no1.parentpath); + end; + end; +end; + +procedure tprojecttreefo.gridcellevent(const sender: TObject; + var info: celleventinfoty); +begin + if isrowenter(info) then begin + edit.frame.buttons[1].visible:= + tprojectnode(projectedit.item).fkind = pnk_dir; + end; + if isrowexit(info) then begin + projectedit.readonly:= true; + end; +end; + +procedure tprojecttreefo.colshowhintexe(const sender: tdatacol; + const arow: Integer; var info: hintinfoty); +begin + if projectedit.items[arow] is tfilenode then begin + info.caption:= tfilenode(projectedit.items[arow]).path; + end; +end; + +procedure tprojecttreefo.edithintexe(const sender: TObject; + var info: hintinfoty); +begin + if projectedit.item is tfilenode then begin + info.caption:= tfilenode(projectedit.item).path; + end; +end; + +function tprojecttreefo.gettreedir: filenamety; +var + n1: tprojectnode; +begin + result:= ''; + n1:= tprojectnode(projectedit.item); + while (n1 <> nil) and not (n1.fkind in [pnk_dir,pnk_source]) do begin + n1:= tprojectnode(n1.parent); + end; + if n1 <> nil then begin + case n1.fkind of + pnk_dir: begin + result:= tfilenode(n1).path; + end; + pnk_source: begin + result:= tfilenode(n1).parentpath; + end; + end; + end; + if result = '' then begin + result:= getcurrentdirmse; + end; +end; + +procedure tprojecttreefo.updateremdirexe(const sender: tcustomaction); +begin + sender.enabled:= (projectedit.item <> nil) and + (tprojectnode(projectedit.item).fkind = pnk_dir); +end; + +procedure tprojecttreefo.updateadddirexe(const sender: tcustomaction); +begin + sender.enabled:= (projectedit.item <> nil) and + (tprojectnode(projectedit.item).fkind in [pnk_source,pnk_dir,pnk_files]); +end; + +procedure tprojecttreefo.remfileupdateexe(const sender: tcustomaction); +begin + sender.enabled:= tprojectnode(projectedit.item).fkind = pnk_source; +end; + +procedure tprojecttreefo.udateeditdirexe(const sender: tcustomaction); +begin + sender.enabled:= tprojectnode(projectedit.item).fkind = pnk_dir; +end; + +procedure tprojecttreefo.editdirexe(const sender: TObject); +begin + projectedit.readonly:= false; + projectedit.beginedit; +end; + +procedure tprojecttreefo.captionset(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + if projectedit.item is tdirnode then begin + with tdirnode(projectedit.item) do begin + fcustomcaption:= avalue; + if avalue = '' then begin + avalue:= calccaption; + end; + end; + end; +end; + +{ tdirnode } + +constructor tdirnode.create; +begin + inherited create(pnk_dir); + exclude(fstate,ns_readonly); +end; + +procedure tdirnode.setvaluetext(var avalue: msestring); +begin + setfilename(avalue); +end; + +procedure tdirnode.setfilename(const value: filenamety); +begin + ffilename:= value; + if fowner <> nil then begin + tfilesnode(rootnode).loadlist; + end; + if fparent <> nil then begin + fparent.sort(false); + end; +end; + +function tdirnode.getcurrentimagenr: integer; +begin + result:= dirico; +end; + +procedure tdirnode.dostatread(const reader: tstatreader); +begin + fcustomcaption:= reader.readmsestring('capt',''); + inherited; +end; + +procedure tdirnode.dostatwrite(const writer: tstatwriter); +begin + writer.writemsestring('capt',fcustomcaption); + inherited; +end; + +function tdirnode.calccaption: msestring; +begin + result:= filename; + expandprmacros(result); + if (result <> '') and (result[1] = '/') then begin + result:= fpath; + end + else begin + result:= relativepath(fpath,parentpath); + end; +end; + +end. \ No newline at end of file diff --git a/mseide-msegui/apps/ide/projecttreeform_mfm.pas b/mseide-msegui/apps/ide/projecttreeform_mfm.pas new file mode 100644 index 0000000..9f2d40e --- /dev/null +++ b/mseide-msegui/apps/ide/projecttreeform_mfm.pas @@ -0,0 +1,475 @@ +unit projecttreeform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,projecttreeform; + +const + objdata: record size: integer; data: array[0..9153] of byte end = + (size: 9154; data: ( + 84,80,70,48,14,116,112,114,111,106,101,99,116,116,114,101,101,102,111,13, + 112,114,111,106,101,99,116,116,114,101,101,102,111,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115, + 117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109, + 101,46,103,114,105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46, + 103,114,105,112,95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111, + 115,101,98,117,116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98, + 117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110,19,103, + 111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110,15,103, + 111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95,98,117, + 116,116,111,110,104,105,110,116,115,0,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,3,7,1,8,98,111,117,110,100,115,95,121, + 3,175,1,9,98,111,117,110,100,115,95,99,120,3,30,1,9,98,111,117, + 110,100,115,95,99,121,3,201,0,23,99,111,110,116,97,105,110,101,114,46, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,19, + 111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101,110,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,26,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99,111, + 110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3, + 20,1,3,201,0,0,22,100,114,97,103,100,111,99,107,46,115,112,108,105, + 116,116,101,114,95,115,105,122,101,2,0,20,100,114,97,103,100,111,99,107, + 46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118, + 101,112,111,115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111, + 100,95,99,97,110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97, + 116,10,111,100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111,112, + 115,105,122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,13, + 111,100,95,99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105,111, + 110,115,11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97, + 118,101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116, + 101,0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46, + 112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112,116, + 105,111,110,6,12,80,114,111,106,101,99,116,32,84,114,101,101,8,111,110, + 99,114,101,97,116,101,7,21,112,114,111,106,101,99,116,116,114,101,101,102, + 111,111,110,99,114,101,97,116,101,16,111,110,101,118,101,110,116,108,111,111, + 112,115,116,97,114,116,7,21,112,114,111,106,101,99,116,116,114,101,101,102, + 111,111,110,108,111,97,100,101,100,9,111,110,100,101,115,116,114,111,121,7, + 22,112,114,111,106,101,99,116,116,114,101,101,102,111,111,110,100,101,115,116, + 114,111,121,12,111,110,115,116,97,116,117,112,100,97,116,101,7,23,112,114, + 111,106,101,99,116,116,114,101,101,111,110,117,112,100,97,116,101,115,116,97, + 116,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9,116, + 100,111,99,107,102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105, + 100,4,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111, + 99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115, + 101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,20,1,9, + 98,111,117,110,100,115,95,99,121,3,201,0,7,97,110,99,104,111,114,115, + 11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99, + 111,108,115,105,122,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108, + 108,111,110,101,110,116,101,114,12,111,103,95,115,97,118,101,115,116,97,116, + 101,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107, + 101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,0,14,100,97,116,97,99,111,108,115,46,99,111,117, + 110,116,2,2,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110, + 115,11,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,11,112,114,111,106,101,99,116,101, + 100,105,116,1,12,108,105,110,101,99,111,108,111,114,102,105,120,4,3,0, + 0,160,5,119,105,100,116,104,3,141,0,7,111,112,116,105,111,110,115,11, + 11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,115,97,118,101, + 115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,11,111,110,99,101,108,108,101,118,101,110,116,7,22,112,114, + 111,106,101,99,116,101,100,105,116,111,110,99,101,108,108,101,118,101,110,116, + 10,119,105,100,103,101,116,110,97,109,101,6,11,112,114,111,106,101,99,116, + 101,100,105,116,9,100,97,116,97,99,108,97,115,115,7,17,116,116,114,101, + 101,105,116,101,109,101,100,105,116,108,105,115,116,22,100,97,116,97,108,105, + 115,116,46,105,109,110,114,95,101,120,112,97,110,100,101,100,2,1,18,100, + 97,116,97,108,105,115,116,46,105,109,97,103,101,108,105,115,116,7,9,110, + 111,100,101,105,99,111,110,115,19,100,97,116,97,108,105,115,116,46,105,109, + 97,103,101,119,105,100,116,104,2,16,20,100,97,116,97,108,105,115,116,46, + 105,109,97,103,101,104,101,105,103,104,116,2,16,23,100,97,116,97,108,105, + 115,116,46,111,110,115,116,97,116,114,101,97,100,105,116,101,109,7,25,112, + 114,111,106,101,99,116,101,100,105,116,111,110,115,116,97,116,114,101,97,100, + 105,116,101,109,20,100,97,116,97,108,105,115,116,46,111,110,100,114,97,103, + 98,101,103,105,110,7,13,101,100,105,116,100,114,97,103,98,101,103,105,110, + 19,100,97,116,97,108,105,115,116,46,111,110,100,114,97,103,111,118,101,114, + 7,12,101,100,105,116,100,114,97,103,111,118,101,114,19,100,97,116,97,108, + 105,115,116,46,111,110,100,114,97,103,100,114,111,112,7,11,101,100,105,116, + 100,114,97,103,114,111,112,0,7,4,101,100,105,116,1,12,108,105,110,101, + 99,111,108,111,114,102,105,120,4,3,0,0,160,5,119,105,100,116,104,3, + 129,0,7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12, + 99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105, + 110,116,7,14,99,111,108,115,104,111,119,104,105,110,116,101,120,101,10,119, + 105,100,103,101,116,110,97,109,101,6,4,101,100,105,116,9,100,97,116,97, + 99,108,97,115,115,7,13,116,105,116,101,109,101,100,105,116,108,105,115,116, + 0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,17,8,115, + 116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106, + 101,99,116,115,116,97,116,102,105,108,101,11,111,110,99,101,108,108,101,118, + 101,110,116,7,13,103,114,105,100,99,101,108,108,101,118,101,110,116,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,13,116,116,114,101, + 101,105,116,101,109,101,100,105,116,11,112,114,111,106,101,99,116,101,100,105, + 116,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,14,111,119, + 49,95,97,117,116,111,104,101,105,103,104,116,0,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 5,99,111,108,111,114,4,7,0,0,144,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,2,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,1,7,111,110,112,111,112,117,112,7,18,112,114,111,106, + 101,99,116,101,100,105,116,111,110,112,111,112,117,112,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,141,0,9,98, + 111,117,110,100,115,95,99,121,2,18,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111, + 101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110, + 101,115,99,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,18,111,101,95, + 104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,9,111,101,95,108, + 111,99,97,116,101,0,8,111,110,99,104,97,110,103,101,7,19,112,114,111, + 106,101,99,116,101,100,105,116,111,110,99,104,97,110,103,101,10,111,110,115, + 101,116,118,97,108,117,101,7,10,99,97,112,116,105,111,110,115,101,116,17, + 111,110,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115,7,28,112, + 114,111,106,101,99,116,101,100,105,116,111,110,117,112,100,97,116,101,114,111, + 119,118,97,108,117,101,115,9,102,105,101,108,100,101,100,105,116,7,4,101, + 100,105,116,7,111,112,116,105,111,110,115,11,16,116,101,111,95,116,114,101, + 101,99,111,108,110,97,118,105,103,16,116,101,111,95,107,101,121,114,111,119, + 109,111,118,105,110,103,0,14,111,110,99,104,101,99,107,114,111,119,109,111, + 118,101,7,18,105,116,101,109,111,110,99,104,101,99,107,114,111,119,109,111, + 118,101,0,0,16,116,114,101,99,111,114,100,102,105,101,108,100,101,100,105, + 116,4,101,100,105,116,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,7,0,0, + 144,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,111,112,116,105,111,110,115,11,13,102,98,111,95,105,110,118,105, + 115,105,98,108,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0, + 128,7,111,112,116,105,111,110,115,11,13,102,98,111,95,105,110,118,105,115, + 105,98,108,101,0,0,1,5,99,111,108,111,114,4,2,0,0,128,7,105, + 109,97,103,101,110,114,2,17,9,111,110,101,120,101,99,117,116,101,7,16, + 114,101,99,101,100,105,116,100,105,97,108,111,103,101,120,101,0,0,8,116, + 97,98,111,114,100,101,114,2,2,10,111,110,115,104,111,119,104,105,110,116, + 7,11,101,100,105,116,104,105,110,116,101,120,101,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,142,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,129,0,9,98, + 111,117,110,100,115,95,99,121,2,17,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110, + 116,101,114,101,100,8,116,102,95,99,108,105,112,111,11,116,102,95,110,111, + 115,101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102, + 116,0,11,111,110,99,101,108,108,101,118,101,110,116,7,15,101,100,105,116, + 111,110,99,101,108,108,101,118,101,110,116,19,100,114,111,112,100,111,119,110, + 46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111, + 119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,0,10,116,112,111, + 112,117,112,109,101,110,117,9,117,110,105,116,112,111,112,117,112,11,109,101, + 110,117,46,97,99,116,105,111,110,7,14,97,100,100,117,110,105,116,102,105, + 108,101,97,99,116,18,109,101,110,117,46,115,117,98,109,101,110,117,46,99, + 111,117,110,116,2,6,18,109,101,110,117,46,115,117,98,109,101,110,117,46, + 105,116,101,109,115,14,1,6,97,99,116,105,111,110,7,14,97,100,100,117, + 110,105,116,102,105,108,101,97,99,116,0,1,6,97,99,116,105,111,110,7, + 17,114,101,109,111,118,101,117,110,105,116,102,105,108,101,97,99,116,0,1, + 7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97, + 116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116, + 105,111,110,0,0,1,6,97,99,116,105,111,110,7,9,97,100,100,100,105, + 114,97,99,116,0,1,6,97,99,116,105,111,110,7,12,114,101,109,111,118, + 101,100,105,114,97,99,116,0,1,6,97,99,116,105,111,110,7,10,101,100, + 105,116,100,105,114,97,99,116,0,0,4,108,101,102,116,2,8,3,116,111, + 112,2,8,0,0,7,116,97,99,116,105,111,110,14,97,100,100,117,110,105, + 116,102,105,108,101,97,99,116,7,99,97,112,116,105,111,110,6,9,38,65, + 100,100,32,85,110,105,116,9,111,110,101,120,101,99,117,116,101,7,20,97, + 100,100,117,110,105,116,102,105,108,101,111,110,101,120,101,99,117,116,101,4, + 108,101,102,116,2,112,3,116,111,112,2,8,0,0,11,116,102,105,108,101, + 100,105,97,108,111,103,10,102,105,108,101,100,105,97,108,111,103,18,99,111, + 110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,14,102,100, + 111,95,99,104,101,99,107,101,120,105,115,116,15,102,100,111,95,115,97,118, + 101,108,97,115,116,100,105,114,0,26,99,111,110,116,114,111,108,108,101,114, + 46,104,105,115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,4,108, + 101,102,116,2,8,3,116,111,112,3,168,0,0,0,7,116,97,99,116,105, + 111,110,17,114,101,109,111,118,101,117,110,105,116,102,105,108,101,97,99,116, + 7,99,97,112,116,105,111,110,6,12,38,82,101,109,111,118,101,32,85,110, + 105,116,9,111,110,101,120,101,99,117,116,101,7,23,114,101,109,111,118,101, + 117,110,105,116,102,105,108,101,111,110,101,120,101,99,117,116,101,8,111,110, + 117,112,100,97,116,101,7,16,114,101,109,102,105,108,101,117,112,100,97,116, + 101,101,120,101,4,108,101,102,116,2,112,3,116,111,112,2,24,0,0,10, + 116,112,111,112,117,112,109,101,110,117,9,102,105,108,101,112,111,112,117,112, + 18,109,101,110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2, + 6,18,109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115, + 14,1,6,97,99,116,105,111,110,7,10,97,100,100,102,105,108,101,97,99, + 116,0,1,6,97,99,116,105,111,110,7,13,114,101,109,111,118,101,102,105, + 108,101,97,99,116,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111, + 95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116, + 99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111,110, + 7,9,97,100,100,100,105,114,97,99,116,0,1,6,97,99,116,105,111,110, + 7,12,114,101,109,111,118,101,100,105,114,97,99,116,0,1,6,97,99,116, + 105,111,110,7,10,101,100,105,116,100,105,114,97,99,116,0,0,10,109,101, + 110,117,46,115,116,97,116,101,11,12,97,115,95,108,111,99,97,108,104,105, + 110,116,0,4,108,101,102,116,2,8,3,116,111,112,2,40,0,0,7,116, + 97,99,116,105,111,110,10,97,100,100,102,105,108,101,97,99,116,7,99,97, + 112,116,105,111,110,6,13,65,100,100,32,84,101,120,116,32,70,105,108,101, + 9,111,110,101,120,101,99,117,116,101,7,10,97,100,100,102,105,108,101,101, + 120,101,4,108,101,102,116,2,112,3,116,111,112,2,48,0,0,7,116,97, + 99,116,105,111,110,13,114,101,109,111,118,101,102,105,108,101,97,99,116,7, + 99,97,112,116,105,111,110,6,16,82,101,109,111,118,101,32,84,101,120,116, + 32,70,105,108,101,9,111,110,101,120,101,99,117,116,101,7,19,114,101,109, + 111,118,101,102,105,108,101,111,110,101,120,101,99,117,116,101,8,111,110,117, + 112,100,97,116,101,7,16,114,101,109,102,105,108,101,117,112,100,97,116,101, + 101,120,101,4,108,101,102,116,2,112,3,116,111,112,2,64,0,0,10,116, + 112,111,112,117,112,109,101,110,117,12,99,109,111,100,117,108,101,112,111,112, + 117,112,18,109,101,110,117,46,115,117,98,109,101,110,117,46,99,111,117,110, + 116,2,6,18,109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101, + 109,115,14,1,6,97,99,116,105,111,110,7,13,97,100,100,99,109,111,100, + 117,108,101,97,99,116,0,1,6,97,99,116,105,111,110,7,16,114,101,109, + 111,118,101,99,109,111,100,117,108,101,97,99,116,0,1,7,111,112,116,105, + 111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109, + 97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0, + 1,6,97,99,116,105,111,110,7,9,97,100,100,100,105,114,97,99,116,0, + 1,6,97,99,116,105,111,110,7,12,114,101,109,111,118,101,100,105,114,97, + 99,116,0,1,6,97,99,116,105,111,110,7,10,101,100,105,116,100,105,114, + 97,99,116,0,0,10,109,101,110,117,46,115,116,97,116,101,11,12,97,115, + 95,108,111,99,97,108,104,105,110,116,0,4,108,101,102,116,2,8,3,116, + 111,112,2,72,0,0,7,116,97,99,116,105,111,110,16,114,101,109,111,118, + 101,99,109,111,100,117,108,101,97,99,116,7,99,97,112,116,105,111,110,6, + 13,82,101,109,111,118,101,32,67,45,70,105,108,101,9,111,110,101,120,101, + 99,117,116,101,7,22,114,101,109,111,118,101,99,109,111,100,117,108,101,111, + 110,101,120,101,99,117,116,101,8,111,110,117,112,100,97,116,101,7,16,114, + 101,109,102,105,108,101,117,112,100,97,116,101,101,120,101,4,108,101,102,116, + 2,112,3,116,111,112,2,104,0,0,7,116,97,99,116,105,111,110,13,97, + 100,100,99,109,111,100,117,108,101,97,99,116,7,99,97,112,116,105,111,110, + 6,10,65,100,100,32,67,45,70,105,108,101,9,111,110,101,120,101,99,117, + 116,101,7,19,97,100,100,99,109,111,100,117,108,101,111,110,101,120,101,99, + 117,116,101,4,108,101,102,116,2,112,3,116,111,112,2,88,0,0,11,116, + 102,105,108,101,100,105,97,108,111,103,13,99,109,111,100,117,108,101,100,105, + 97,108,111,103,26,99,111,110,116,114,111,108,108,101,114,46,102,105,108,116, + 101,114,108,105,115,116,46,100,97,116,97,1,1,6,14,67,45,83,111,117, + 114,99,101,32,40,42,46,99,41,6,5,34,42,46,99,34,0,0,18,99, + 111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,14,102, + 100,111,95,99,104,101,99,107,101,120,105,115,116,15,102,100,111,95,115,97, + 118,101,108,97,115,116,100,105,114,0,26,99,111,110,116,114,111,108,108,101, + 114,46,104,105,115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,4, + 108,101,102,116,2,96,3,116,111,112,3,168,0,0,0,7,116,97,99,116, + 105,111,110,9,97,100,100,100,105,114,97,99,116,7,99,97,112,116,105,111, + 110,6,13,65,100,100,32,68,105,114,101,99,116,111,114,121,9,111,110,101, + 120,101,99,117,116,101,7,9,97,100,100,100,105,114,101,120,101,8,111,110, + 117,112,100,97,116,101,7,15,117,112,100,97,116,101,97,100,100,100,105,114, + 101,120,101,3,116,111,112,2,104,0,0,7,116,97,99,116,105,111,110,12, + 114,101,109,111,118,101,100,105,114,97,99,116,7,99,97,112,116,105,111,110, + 6,16,82,101,109,111,118,101,32,68,105,114,101,99,116,111,114,121,9,111, + 110,101,120,101,99,117,116,101,7,9,114,101,109,100,105,114,101,120,101,8, + 111,110,117,112,100,97,116,101,7,15,117,112,100,97,116,101,114,101,109,100, + 105,114,101,120,101,3,116,111,112,2,120,0,0,10,116,105,109,97,103,101, + 108,105,115,116,9,110,111,100,101,105,99,111,110,115,5,99,111,117,110,116, + 2,8,4,108,101,102,116,3,144,0,3,116,111,112,2,120,5,105,109,97, + 103,101,10,236,11,0,0,0,0,0,0,2,0,0,0,48,0,0,0,48, + 0,0,0,56,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 0,255,99,0,0,0,6,255,0,255,10,0,0,0,6,255,0,255,9,0, + 0,0,6,255,0,255,11,0,0,0,1,255,255,255,4,0,0,0,2,255, + 0,255,9,0,0,0,1,255,255,255,4,0,0,0,2,255,0,255,8,0, + 0,0,1,255,255,255,4,0,0,0,2,255,0,255,10,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,1,0,0,0,1,255,0,255,8,0, + 0,0,1,255,255,255,4,0,0,0,1,255,255,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,1,0, + 0,0,1,255,0,255,9,0,0,0,1,255,255,255,4,0,0,0,1,255, + 255,255,2,0,0,0,1,255,0,255,7,0,0,0,1,255,255,255,4,0, + 0,0,1,255,255,255,2,0,0,0,1,255,0,255,6,0,0,0,1,255, + 255,255,2,255,142,120,1,224,50,16,5,174,174,174,1,224,50,16,1,0, + 0,0,1,255,0,255,5,0,0,0,1,255,255,255,4,0,0,0,5,255, + 0,255,6,0,0,0,1,255,255,255,4,0,0,0,5,255,0,255,5,0, + 0,0,1,255,255,255,2,242,242,242,1,224,224,224,7,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,7,128, + 128,128,1,255,0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128, + 128,128,1,255,0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128, + 128,128,1,255,0,255,4,0,0,0,1,255,255,255,2,242,242,242,1,224, + 224,224,7,128,128,128,1,255,0,255,5,0,0,0,1,255,255,255,8,0, + 0,0,1,128,128,128,1,255,0,255,5,0,0,0,1,255,255,255,8,0, + 0,0,1,128,128,128,1,255,0,255,4,0,0,0,1,255,255,255,2,242, + 242,242,1,224,224,224,1,242,242,242,5,224,224,224,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,1,242, + 242,242,1,224,224,224,3,128,128,128,1,224,224,224,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,1,242, + 242,242,1,224,224,224,3,128,128,128,1,224,224,224,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,1,242, + 242,242,1,128,128,128,4,224,224,224,1,128,128,128,1,255,0,255,5,0, + 0,0,10,128,128,128,1,255,0,255,5,0,0,0,10,128,128,128,1,255, + 0,255,4,0,0,0,3,242,242,242,1,224,224,224,7,128,128,128,1,255, + 0,255,6,128,128,128,10,255,0,255,6,128,128,128,10,255,0,255,5,128, + 128,128,2,242,242,242,1,128,128,128,8,255,0,255,148,0,0,0,6,255, + 0,255,42,0,0,0,1,255,255,255,4,0,0,0,2,255,0,255,10,255, + 142,120,1,224,50,16,6,174,174,174,1,224,50,16,1,0,0,0,1,255, + 0,255,6,255,142,120,1,224,50,16,6,174,174,174,1,224,50,16,1,0, + 0,0,1,255,0,255,5,0,0,0,1,255,255,255,4,0,0,0,1,255, + 255,255,1,0,0,0,1,255,0,255,9,242,242,242,1,224,224,224,8,128, + 128,128,1,255,0,255,6,242,242,242,1,224,224,224,8,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,2,255,142,120,1,224,50,16,5,174, + 174,174,1,224,50,16,1,0,0,0,1,255,0,255,5,242,242,242,1,224, + 224,224,8,128,128,128,1,255,0,255,6,242,242,242,1,224,224,224,8,128, + 128,128,1,255,0,255,5,0,0,0,1,255,255,255,2,242,242,242,1,224, + 224,224,7,128,128,128,1,255,0,255,5,242,242,242,1,224,224,224,8,128, + 128,128,1,255,0,255,6,242,242,242,1,224,224,224,8,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,7,128, + 128,128,1,255,0,255,5,242,242,242,1,224,224,224,1,242,242,242,6,224, + 224,224,1,128,128,128,1,255,0,255,6,242,242,242,1,224,224,224,1,242, + 242,242,6,224,224,224,1,128,128,128,1,255,0,255,5,0,0,0,1,255, + 255,255,2,242,242,242,1,224,224,224,7,128,128,128,1,255,0,255,5,242, + 242,242,1,224,224,224,1,242,242,242,1,224,224,224,4,128,128,128,1,224, + 224,224,1,128,128,128,1,255,0,255,6,242,242,242,1,224,224,224,1,242, + 242,242,1,224,224,224,4,128,128,128,1,224,224,224,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,1,242, + 242,242,5,224,224,224,1,128,128,128,1,255,0,255,5,242,242,242,1,224, + 224,224,1,242,242,242,1,224,224,224,4,128,128,128,1,224,224,224,1,128, + 128,128,1,255,0,255,6,242,242,242,1,224,224,224,1,242,242,242,1,224, + 224,224,4,128,128,128,1,224,224,224,1,128,128,128,1,255,0,255,5,0, + 0,0,1,255,255,255,2,242,242,242,1,224,224,224,1,242,242,242,1,224, + 224,224,3,128,128,128,1,224,224,224,1,128,128,128,1,255,0,255,5,242, + 242,242,1,224,224,224,1,242,242,242,1,128,128,128,5,224,224,224,1,128, + 128,128,1,255,0,255,6,242,242,242,1,224,224,224,1,242,242,242,1,128, + 128,128,5,224,224,224,1,128,128,128,1,255,0,255,5,0,0,0,1,255, + 255,255,2,242,242,242,1,224,224,224,1,242,242,242,1,224,224,224,3,128, + 128,128,1,224,224,224,1,128,128,128,1,255,0,255,5,242,242,242,1,224, + 224,224,8,128,128,128,1,255,0,255,6,242,242,242,1,224,224,224,8,128, + 128,128,1,255,0,255,5,0,0,0,1,255,255,255,2,242,242,242,1,224, + 224,224,1,242,242,242,1,128,128,128,4,224,224,224,1,128,128,128,1,255, + 0,255,5,242,242,242,1,128,128,128,9,255,0,255,6,242,242,242,1,128, + 128,128,9,255,0,255,5,0,0,0,3,242,242,242,1,224,224,224,7,128, + 128,128,1,255,0,255,37,128,128,128,2,242,242,242,1,128,128,128,8,255, + 0,255,212,0,0,0,6,255,0,255,11,127,127,127,1,0,0,0,4,127, + 127,127,1,255,0,255,9,127,127,127,1,0,0,0,4,127,127,127,1,255, + 0,255,10,0,0,0,1,255,255,255,4,0,0,0,2,255,0,255,10,0, + 0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,0, + 0,0,1,255,0,255,9,0,0,0,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,1,255,0,255,10,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,1,0,0,0,1,255,0,255,8,0, + 0,0,10,255,0,255,5,0,0,0,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,0,0,3,255, + 0,255,7,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,2,0, + 0,0,1,255,0,255,7,0,0,0,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255, + 0,255,6,0,0,0,1,255,255,255,4,0,0,0,5,255,0,255,6,0, + 0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,0, + 0,0,1,255,0,255,4,0,0,0,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,0,0,0,1,255,0,255,6,0,0,0,1,255, + 255,255,2,255,142,120,1,224,50,16,5,174,174,174,1,224,50,16,1,0, + 0,0,1,255,0,255,4,0,0,0,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,0,0,10,255,0,255,3,0, + 0,0,1,255,255,255,2,235,235,235,1,224,224,224,7,128,128,128,1,255, + 0,255,4,0,0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,0,255,255,1,255, + 255,255,1,0,0,0,1,0,255,255,1,191,191,191,1,0,255,255,1,191, + 191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0, + 255,255,1,0,0,0,1,255,0,255,3,0,0,0,1,255,255,255,2,235, + 235,235,1,224,224,224,1,235,235,235,4,128,128,128,1,224,224,224,1,128, + 128,128,1,255,0,255,4,0,0,0,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,0,0,1,0,255,255,1,191,191,191,1,0,255,255,1,191, + 191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0, + 255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,2,235, + 235,235,1,224,224,224,1,235,235,235,1,224,224,224,3,128,128,128,1,224, + 224,224,1,128,128,128,1,255,0,255,4,0,0,0,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,2,0,255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0, + 255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,0, + 0,0,1,255,0,255,5,0,0,0,1,255,255,255,2,235,235,235,1,224, + 224,224,1,235,235,235,1,224,224,224,3,128,128,128,1,224,224,224,1,128, + 128,128,1,255,0,255,5,0,0,0,10,255,0,255,5,0,0,0,10,255, + 0,255,6,0,0,0,1,255,255,255,2,235,235,235,1,224,224,224,1,235, + 235,235,1,128,128,128,4,224,224,224,1,128,128,128,1,255,0,255,36,0, + 0,0,3,235,235,235,1,224,224,224,7,128,128,128,1,255,0,255,37,128, + 128,128,2,235,235,235,1,128,128,128,8,255,0,255,50,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,248,1,248,1,252,0,0,0,248, + 3,248,3,252,1,0,0,248,7,248,7,252,3,0,0,248,15,248,15,252, + 63,0,0,248,31,248,31,252,63,0,0,248,63,248,63,252,63,0,0,248, + 63,248,63,252,63,0,0,248,63,248,63,252,63,0,0,248,63,248,63,252, + 63,0,0,248,63,248,63,252,63,0,0,248,63,248,63,252,63,0,0,248, + 63,248,63,252,63,0,0,240,63,240,63,248,63,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252, + 0,0,0,0,0,0,0,252,1,248,31,248,31,0,0,252,3,248,31,248, + 31,0,0,252,63,248,31,248,31,0,0,252,63,248,31,248,31,0,0,252, + 63,248,31,248,31,0,0,252,63,248,31,248,31,0,0,252,63,248,31,248, + 31,0,0,252,63,248,31,248,31,0,0,252,63,248,31,248,31,0,0,252, + 63,248,31,248,31,0,0,252,63,0,0,0,0,0,0,248,63,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,252,0,0,0,248,1,252,0,252, + 1,0,0,248,1,252,0,252,3,0,0,252,15,254,7,252,7,0,0,252, + 31,254,15,252,15,0,0,252,31,254,15,252,63,0,0,252,31,254,127,252, + 63,0,0,252,31,254,127,252,63,0,0,252,31,254,63,252,63,0,0,252, + 31,254,31,252,63,0,0,248,31,252,15,252,63,0,0,0,0,0,0,252, + 63,0,0,0,0,0,0,248,63,0,0,0,0,0,0,0,0,0,0,0, + 0,10,116,105,109,97,103,101,108,105,115,116,10,100,117,109,109,121,105,109, + 97,103,101,5,119,105,100,116,104,2,0,6,104,101,105,103,104,116,2,0, + 4,108,101,102,116,3,144,0,3,116,111,112,3,144,0,0,0,7,116,97, + 99,116,105,111,110,10,101,100,105,116,100,105,114,97,99,116,7,99,97,112, + 116,105,111,110,6,22,69,100,105,116,32,68,105,114,101,99,116,111,114,121, + 32,67,97,112,116,105,111,110,9,111,110,101,120,101,99,117,116,101,7,10, + 101,100,105,116,100,105,114,101,120,101,8,111,110,117,112,100,97,116,101,7, + 15,117,100,97,116,101,101,100,105,116,100,105,114,101,120,101,3,116,111,112, + 3,136,0,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97,105,110, + 101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,12, + 80,97,115,99,97,108,32,85,110,105,116,115,6,9,67,32,77,111,100,117, + 108,101,115,6,10,84,101,120,116,32,70,105,108,101,115,6,23,68,111,32, + 121,111,117,32,119,105,115,104,32,116,111,32,114,101,109,111,118,101,32,34, + 6,16,83,101,108,101,99,116,32,68,105,114,101,99,116,111,114,121,6,21, + 68,111,32,121,111,117,32,119,97,110,116,32,116,111,32,114,101,109,111,118, + 101,6,32,119,105,116,104,32,116,104,101,32,115,117,98,45,105,116,101,109, + 115,32,102,114,111,109,32,112,114,111,106,101,99,116,63,0,4,108,101,102, + 116,3,208,0,3,116,111,112,3,168,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tprojecttreefo,''); +end. diff --git a/mseide-msegui/apps/ide/replacedialogform.mfm b/mseide-msegui/apps/ide/replacedialogform.mfm new file mode 100644 index 0000000..42a9564 --- /dev/null +++ b/mseide-msegui/apps/ide/replacedialogform.mfm @@ -0,0 +1,167 @@ +object replacedialogfo: treplacedialogfo + visible = False + bounds_x = 142 + bounds_y = 302 + bounds_cx = 427 + bounds_cy = 163 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 427 + 163 + ) + options = [fo_freeonclose, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = statfile1 + caption = 'Find and Replace Text' + moduleclassname = 'tmseform' + object findtext: thistoryedit + frame.caption = 'Text to &find' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 8 + bounds_y = 7 + bounds_cx = 410 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object replacetext: thistoryedit + frame.caption = '&Replace with' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 47 + bounds_cx = 410 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = statfile1 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object casesensitive: tbooleanedit + frame.caption = '&casesensitive' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 88 + 2 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 96 + bounds_cx = 101 + bounds_cy = 16 + end + object wholeword: tbooleanedit + frame.caption = '&whole word' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 73 + 2 + ) + taborder = 3 + bounds_x = 112 + bounds_y = 96 + bounds_cx = 86 + bounds_cy = 16 + end + object tintegerbutton1: tbutton + taborder = 6 + bounds_x = 8 + bounds_y = 123 + bounds_cx = 74 + bounds_cy = 20 + state = [as_localcaption] + caption = '&Replace' + modalresult = mr_ok + end + object tintegerbutton2: tbutton + taborder = 7 + bounds_x = 88 + bounds_y = 123 + bounds_cx = 74 + bounds_cy = 20 + state = [as_localcaption] + caption = 'Replace &all' + modalresult = mr_all + end + object selectedonly: tbooleanedit + frame.caption = 'select&ed only' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 86 + 2 + ) + taborder = 4 + bounds_x = 208 + bounds_y = 96 + bounds_cx = 99 + bounds_cy = 16 + statfile = statfile1 + end + object tintegerbutton3: tbutton + taborder = 8 + bounds_x = 168 + bounds_y = 123 + bounds_cx = 74 + bounds_cy = 20 + state = [as_default, as_localdefault, as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object promptonreplace: tbooleanedit + frame.caption = '&prompt on rep.' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 97 + 2 + ) + taborder = 5 + bounds_x = 312 + bounds_y = 96 + bounds_cx = 110 + bounds_cy = 16 + statfile = statfile1 + value = True + end + object statfile1: tstatfile + filename = 'replacedialogfo.sta' + options = [sfo_memory] + left = 112 + end +end diff --git a/mseide-msegui/apps/ide/replacedialogform.pas b/mseide-msegui/apps/ide/replacedialogform.pas new file mode 100644 index 0000000..56dbb79 --- /dev/null +++ b/mseide-msegui/apps/ide/replacedialogform.pas @@ -0,0 +1,93 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit replacedialogform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseguiglob,msegui,mseclasses,mseforms,msegraphedits,msedataedits,msesimplewidgets, + msestat,msestatfile,mseglob, + projectoptionsform; + +type + treplacedialogfo = class(tmseform) + casesensitive: tbooleanedit; + findtext: thistoryedit; + replacetext: thistoryedit; + selectedonly: tbooleanedit; + statfile1: tstatfile; + promptonreplace: tbooleanedit; + tintegerbutton1: tbutton; + tintegerbutton2: tbutton; + tintegerbutton3: tbutton; + wholeword: tbooleanedit; + private + procedure valuestoinfo(out info: replaceinfoty); + procedure infotovalues(const info: replaceinfoty); + end; + +function replacedialogexecute(var info: replaceinfoty): modalresultty; + +implementation +uses + replacedialogform_mfm,msestrings; + +function replacedialogexecute(var info: replaceinfoty): modalresultty; +var + fo: treplacedialogfo; +begin + fo:= treplacedialogfo.create(nil); + try + fo.infotovalues(info); + result:= fo.show(true,nil); + if result in [mr_ok,mr_all] then begin + fo.valuestoinfo(info); + end; + finally + fo.Free; + end; +end; + +{ treplacedialogfo } + +procedure treplacedialogfo.valuestoinfo(out info: replaceinfoty); +begin +{$warnings off} + with info.find do begin + text:= findtext.value; + history:= findtext.dropdown.valuelist.asarray; + options:= encodesearchoptions(not casesensitive.value,wholeword.value); + selectedonly:= self.selectedonly.value; + end; + info.prompt:= promptonreplace.value; + info.replacetext:= replacetext.value; +end; +{$warnings on} + +procedure treplacedialogfo.infotovalues(const info: replaceinfoty); +begin + with info.find do begin + findtext.value:= text; + findtext.dropdown.valuelist.asarray:= history; + casesensitive.value:= not (so_caseinsensitive in options); + wholeword.value:= so_wholeword in options; +// self.selectedonly.value:= selectedonly; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/replacedialogform_mfm.pas b/mseide-msegui/apps/ide/replacedialogform_mfm.pas new file mode 100644 index 0000000..09f75bb --- /dev/null +++ b/mseide-msegui/apps/ide/replacedialogform_mfm.pas @@ -0,0 +1,133 @@ +unit replacedialogform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,replacedialogform; + +const + objdata: record size: integer; data: array[0..2303] of byte end = + (size: 2304; data: ( + 84,80,70,48,16,116,114,101,112,108,97,99,101,100,105,97,108,111,103,102, + 111,15,114,101,112,108,97,99,101,100,105,97,108,111,103,102,111,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,142,0,8,98, + 111,117,110,100,115,95,121,3,46,1,9,98,111,117,110,100,115,95,99,120, + 3,171,1,9,98,111,117,110,100,115,95,99,121,3,163,0,26,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116, + 97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,171,1, + 3,163,0,0,7,111,112,116,105,111,110,115,11,14,102,111,95,102,114,101, + 101,111,110,99,108,111,115,101,13,102,111,95,99,108,111,115,101,111,110,101, + 115,99,17,102,111,95,108,111,99,97,108,115,104,111,114,116,99,117,116,115, + 15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95, + 97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118, + 101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,0,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,7, + 99,97,112,116,105,111,110,6,21,70,105,110,100,32,97,110,100,32,82,101, + 112,108,97,99,101,32,84,101,120,116,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,12,116,104, + 105,115,116,111,114,121,101,100,105,116,8,102,105,110,100,116,101,120,116,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,13,84,101,120,116,32, + 116,111,32,38,102,105,110,100,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110, + 46,99,111,108,111,114,4,2,0,0,128,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,7, + 9,98,111,117,110,100,115,95,99,120,3,154,1,9,98,111,117,110,100,115, + 95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,19, + 100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2, + 1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109, + 115,14,1,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,12,116,104,105,115,116,111,114,121,101,100,105,116,11,114,101,112, + 108,97,99,101,116,101,120,116,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,13,38,82,101,112,108,97,99,101,32,119,105,116,104,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,102,114,97, + 109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,47, + 9,98,111,117,110,100,115,95,99,120,3,154,1,9,98,111,117,110,100,115, + 95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,19, + 100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2, + 1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109, + 115,14,1,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,99,97,115, + 101,115,101,110,115,105,116,105,118,101,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,14,38,99,97,115,101,115,101,110,115,105,116,105,118,101, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,88,2,2,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,96,9, + 98,111,117,110,100,115,95,99,120,2,101,9,98,111,117,110,100,115,95,99, + 121,2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,119, + 104,111,108,101,119,111,114,100,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,11,38,119,104,111,108,101,32,119,111,114,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,73,2,2, + 0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95, + 120,2,112,8,98,111,117,110,100,115,95,121,2,96,9,98,111,117,110,100, + 115,95,99,120,2,86,9,98,111,117,110,100,115,95,99,121,2,16,0,0, + 7,116,98,117,116,116,111,110,15,116,105,110,116,101,103,101,114,98,117,116, + 116,111,110,49,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110, + 100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,123,9,98,111, + 117,110,100,115,95,99,120,2,74,9,98,111,117,110,100,115,95,99,121,2, + 20,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,8,38,82,101,112,108, + 97,99,101,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95, + 111,107,0,0,7,116,98,117,116,116,111,110,15,116,105,110,116,101,103,101, + 114,98,117,116,116,111,110,50,8,116,97,98,111,114,100,101,114,2,7,8, + 98,111,117,110,100,115,95,120,2,88,8,98,111,117,110,100,115,95,121,2, + 123,9,98,111,117,110,100,115,95,99,120,2,74,9,98,111,117,110,100,115, + 95,99,121,2,20,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,12,82, + 101,112,108,97,99,101,32,38,97,108,108,11,109,111,100,97,108,114,101,115, + 117,108,116,7,6,109,114,95,97,108,108,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,12,115,101,108,101,99,116,101,100,111,110,108,121,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,14,115,101,108,101,99, + 116,38,101,100,32,111,110,108,121,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,86,2,2,0,8,116,97,98,111, + 114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,208,0,8,98, + 111,117,110,100,115,95,121,2,96,9,98,111,117,110,100,115,95,99,120,2, + 99,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105, + 108,101,7,9,115,116,97,116,102,105,108,101,49,0,0,7,116,98,117,116, + 116,111,110,15,116,105,110,116,101,103,101,114,98,117,116,116,111,110,51,8, + 116,97,98,111,114,100,101,114,2,8,8,98,111,117,110,100,115,95,120,3, + 168,0,8,98,111,117,110,100,115,95,121,2,123,9,98,111,117,110,100,115, + 95,99,120,2,74,9,98,111,117,110,100,115,95,99,121,2,20,5,115,116, + 97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108, + 111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67, + 97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109, + 114,95,99,97,110,99,101,108,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,15,112,114,111,109,112,116,111,110,114,101,112,108,97,99,101,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,15,38,112,114,111,109, + 112,116,32,111,110,32,114,101,112,46,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,1,2,97,2,2,0,8,116,97,98, + 111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,56,1,8, + 98,111,117,110,100,115,95,121,2,96,9,98,111,117,110,100,115,95,99,120, + 2,110,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102, + 105,108,101,7,9,115,116,97,116,102,105,108,101,49,5,118,97,108,117,101, + 9,0,0,9,116,115,116,97,116,102,105,108,101,9,115,116,97,116,102,105, + 108,101,49,8,102,105,108,101,110,97,109,101,6,19,114,101,112,108,97,99, + 101,100,105,97,108,111,103,102,111,46,115,116,97,7,111,112,116,105,111,110, + 115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116,2, + 112,0,0,0) + ); + +initialization + registerobjectdata(@objdata,treplacedialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/reportdesigner.mfm b/mseide-msegui/apps/ide/reportdesigner.mfm new file mode 100644 index 0000000..a18f1b4 --- /dev/null +++ b/mseide-msegui/apps/ide/reportdesigner.mfm @@ -0,0 +1,459 @@ +inherited reportdesignerfo: treportdesignerfo + bounds_x = 198 + bounds_y = 137 + bounds_cx = 343 + bounds_cy = 459 + container.color = -1879048185 + container.onlayout = repchildscaled + container.oncalcminscrollsize = nil + container.onchildmouseevent = reportchildmouseevent + container.bounds = ( + 0 + 0 + 343 + 459 + ) + onclose = nil + onresize = formresized + onlayout = repchildscaled + moduleclassname = 'Tformdesignerfo' + object dialh: tdial[0] + color = -1879048185 + frame.localprops = [frl_fileft] + frame.localprops1 = [] + taborder = 4 + bounds_x = 7 + bounds_y = 19 + bounds_cx = 336 + bounds_cy = 7 + anchors = [an_left, an_top, an_right] + dial.options = [] + dial.widthmm = 0.3 + dial.start = 0 + dial.range = 100 + dial.markers.count = 1 + dial.markers.items = < + item + color = -1610612729 + widthmm = 0 + escapement = 0 + value = -Inf + end> + dial.ticks.count = 3 + dial.ticks.items = < + item + widthmm = 0 + escapement = 0 + intervalcount = 10 + end + item + color = -1610612733 + widthmm = 0 + length = 6 + escapement = 0 + intervalcount = 20 + end + item + color = -1610612733 + widthmm = 0 + length = 3 + escapement = 0 + intervalcount = 100 + end> + dial.angle = 0 + end + object tabbar: ttabbar[1] + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autoheight] + optionswidget = [ow_mousewheel, ow_destroywidgets] + color = -1879048187 + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 120 + bounds_y = 0 + bounds_cx = 221 + bounds_cy = 19 + anchors = [an_left, an_top, an_right] + onactivetabchange = tabcha + ontabmoving = tabmo + onclientmouseevent = tabmouse + options = [tabo_dragsource, tabo_dragdest] + reffontheight = 14 + end + object reportcontainer: tscrollbox[2] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + color = -1879048187 + frame.optionsscroll = [oscr_drag, oscr_key, oscr_mousewheel] + frame.colorclient = -1610612730 + frame.localprops = [frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 7 + bounds_y = 26 + bounds_cx = 335 + bounds_cy = 433 + anchors = [an_left, an_top, an_right, an_bottom] + onlayout = repcomtainerchildscaled + onscrolled = reportcontainerscrolled + end + object tspacer1: tspacer[3] + taborder = 2 + bounds_x = 144 + bounds_y = 19 + bounds_cx = 50 + bounds_cy = 5 + linktop = tabbar + linkbottom = dialh + dist_bottom = -5 + end + object dialv: tdial[4] + color = -1879048185 + taborder = 3 + bounds_x = 0 + bounds_y = 26 + bounds_cx = 7 + bounds_cy = 433 + anchors = [an_left, an_top, an_bottom] + dial.widthmm = 0.3 + dial.direction = gd_down + dial.start = 0 + dial.range = 100 + dial.markers.count = 1 + dial.markers.items = < + item + color = -1610612729 + widthmm = 0 + escapement = 0 + value = -Inf + end> + dial.ticks.count = 3 + dial.ticks.items = < + item + widthmm = 0 + escapement = 0 + intervalcount = 10 + end + item + color = -1610612733 + widthmm = 0 + length = 6 + escapement = 0 + intervalcount = 20 + end + item + color = -1610612733 + widthmm = 0 + length = 4 + escapement = 0 + intervalcount = 100 + end> + dial.angle = 0 + end + object tspacer2: tspacer[5] + taborder = 5 + bounds_x = 144 + bounds_y = 26 + bounds_cx = 50 + bounds_cy = 5 + linktop = dialh + linkbottom = reportcontainer + dist_bottom = -5 + end + object tspacer3: tspacer[6] + taborder = 6 + bounds_x = 7 + bounds_y = 173 + bounds_cx = 5 + bounds_cy = 50 + linkleft = dialv + linkright = reportcontainer + dist_right = -5 + end + object xdisp: trealdisp[7] + color = -1879048187 + frame.localprops = [] + frame.localprops1 = [] + taborder = 7 + bounds_x = 52 + bounds_y = 0 + bounds_cx = 68 + bounds_cy = 18 + textflags = [tf_ycentered] + valuerange = 1 + valuestart = 0 + format = '0.0mm' + value = -Inf + reffontheight = 14 + end + object ydisp: trealdisp[8] + color = -1879048187 + frame.localprops = [] + frame.localprops1 = [] + taborder = 8 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 18 + valuerange = 1 + valuestart = 0 + format = '0.0' + value = -Inf + reffontheight = 14 + end + object tspacer4: tspacer[9] + taborder = 9 + bounds_x = 16 + bounds_y = 26 + bounds_cx = 50 + bounds_cy = 5 + linktop = dialh + linkbottom = dialv + dist_bottom = -5 + end + inherited popupme: tpopupmenu[10] + menu.submenu.items = < + item + end + item + end + item + end + item + end + item + state = [as_localonexecute] + end + item + state = [as_localdisabled, as_localinvisible, as_localonexecute] + end + item + state = [as_localinvisible, as_localonexecute] + end + item + state = [as_localinvisible, as_localonexecute] + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end> + end + inherited hidecompact: taction[11] + end + inherited hidewidgetact: taction[12] + state = [as_disabled, as_invisible] + end + inherited togglehideact: taction[13] + end + inherited showallact: taction[14] + end + object tpopupmenu3: tpopupmenu[15] + menu.submenu.count = 29 + menu.submenu.items = < + item + caption = 'Show objectinspector' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Show componentpalette' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Show as Text' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + end + item + action = formdesignerfo.hidecompact + options = [mao_separator, mao_shortcutcaption] + end + item + action = formdesignerfo.hidewidgetact + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = hidewidgetact + state = [as_disabled, as_invisible] + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = togglehideact + end + item + action = showallact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Copy Component(s)' + name = 'copy' + state = [as_localcaption, as_localshortcut, as_localonexecute] + sc = ( + 1 + 16451 + ) + end + item + caption = 'Cut Component(s)' + name = 'cut' + state = [as_localcaption, as_localshortcut, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + sc = ( + 1 + 16472 + ) + end + item + caption = 'Paste Component(s)' + name = 'paste' + state = [as_localcaption, as_localshortcut, as_localonexecute] + sc = ( + 1 + 16470 + ) + end + item + caption = 'Delete Component(s)' + name = 'delete' + state = [as_localcaption, as_localshortcut, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + sc = ( + 1 + 263 + ) + end + item + caption = 'Undelete Component(s)' + name = 'undelete' + state = [as_localcaption, as_localonexecute] + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Select Childwidget' + name = 'selectchild' + state = [as_localcaption] + end + item + caption = 'Edit Component' + name = 'editcomp' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Bring to Front' + name = 'bringtofro' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Send to Back' + name = 'sendtoba' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Iconify' + name = 'iconify' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Deiconify' + name = 'deiconify' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Set Tab Order' + name = 'settabord' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Set Creation Order' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Sync. to Font Height' + name = 'synctofo' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Revert to inherited' + name = 'revert' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Touch Form' + state = [as_localcaption, as_localonexecute] + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Add report page' + name = 'addpage' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Delete report page' + name = 'delpage' + state = [as_localcaption, as_localonexecute] + end> + left = 16 + top = 160 + end + inherited c: tstringcontainer[16] + end + object sc: tstringcontainer[17] + strings.data = ( + 'Do you wish to delete' + 'WARNING' + ) + left = 64 + top = 208 + end +end diff --git a/mseide-msegui/apps/ide/reportdesigner.pas b/mseide-msegui/apps/ide/reportdesigner.pas new file mode 100644 index 0000000..432c98c --- /dev/null +++ b/mseide-msegui/apps/ide/reportdesigner.pas @@ -0,0 +1,630 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit reportdesigner; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,msegui,mseclasses,mseforms,formdesigner,msesimplewidgets, + msetabs,msesplitter,msegraphutils,msedesigner,msedesignintf,msereport,msetypes, + mseevent,mseglob,mseguiglob,msemenus,msedial,msedispwidgets,mseact, + msestringcontainer,msestrings,mseactions,mseificomp,mseificompglob,mseifiglob; + +const + updatetabtag = 83684; + +type + treportdesignerfo = class; + { + treportcontainer = class(tscrollbox) + protected + function isdesignwidget(): boolean; override; + public + constructor create(aowner: tcomponent); override; + end; + } + reportdesignerstatety = (rds_tabupdating,rds_mouseinclient); + reportdesignerstatesty = set of reportdesignerstatety; + + treportdesignerfo = class(tformdesignerfo) + dialh: tdial; + dialv: tdial; + tabbar: ttabbar; + reportcontainer: tscrollbox; + tspacer4: tspacer; + xdisp: trealdisp; + ydisp: trealdisp; + tspacer1: tspacer; + tspacer2: tspacer; + tspacer3: tspacer; + sc: tstringcontainer; + tpopupmenu3: tpopupmenu; + procedure repchildscaled(const sender: TObject); + procedure tabcha(const sender: TObject); + procedure tabmo(const sender: TObject; var curindex: Integer; + var newindex: Integer); + procedure tabmouse(const sender: twidget; var info: mouseeventinfoty); + procedure deletepage(const sender: TObject); + procedure popupupda(const sender: tcustommenu); + procedure addpage(const sender: TObject); + procedure formresized(const sender: TObject); + procedure reportchildmouseevent(const sender: twidget; + var info: mouseeventinfoty); + procedure reportcontainerscrolled(const sender: twidget; + const point: pointty); + procedure repcomtainerchildscaled(const sender: TObject); +// procedure updatewidgethideexe(const sender: tcustomaction); override; +// procedure repshowallexe(const sender: TObject); +// procedure reptoglehideexe(const sender: TObject); +// procedure rephidewidgetexe(const sender: TObject); + private +// freportcontainer: treportcontainer; + fstate: reportdesignerstatesty; + function ppmm: real; + protected + fisreppage: boolean; + procedure setmoduleoptions(const aoptions: moduleoptionsty); override; + function report: tcustomreport; + function reppage: treppageform; + function getdesigninfo(): prepdesigninfoty; + function getmoduleparent: twidget; override; + function markerrect(): rectty; override; + function getdesignrect(): rectty; override; + function getmodulesize(): sizety; override; + function gridrect(): rectty; override; + function insertoffset(): pointty; override; + function widgetrefpoint(): pointty; override; + function getgridsizex(): integer; override; + function getgridsizey(): integer; override; + function getshowgrid(): boolean; override; + function getsnaptogrid(): boolean; override; +// procedure poschanged(); override; +// procedure sizechanged(); override; + procedure checktabs(); + procedure updatetabs(); + procedure validaterename(acomponent: tcomponent; + const curname, newname: string); override; + procedure doasyncevent(var atag: integer); override; + procedure componentselected(const aselections: tformdesignerselections); + override; + procedure placecomponent(const component: tcomponent; const apos: pointty; + aparent: tcomponent = nil); override; + function fixformsize: boolean; override; +// function candelete(const acomponent: tcomponent): boolean; override; + function checkdelete(): boolean; override; + procedure componentmoving(const apos: pointty); override; + procedure updatedials; + procedure setmousemarkers(const avalue: pointty; const source: twidget); + public + constructor create(const aowner: tcomponent; const adesigner: tdesigner; + const aintf: pdesignmoduleintfty; + const amoduleinfo: pmoduleinfoty); override; + procedure placemodule(); override; + procedure beginstreaming(); override; + procedure endstreaming(); override; + end; + +var + reportdesignerfo: treportdesignerfo; + +implementation + +uses + reportdesigner_mfm,msearrayutils,msegraphics,msewidgets,msereal,sysutils; +type + tcustomreport1 = class(tcustomreport); + treppageform1 = class(treppageform); + twidget1 = class(twidget); + + stringconsts = ( + sc_wishdelete, //0 Do you wish to delete + sc_warning //1 WARNING + ); + +{ treportcontainer } +{ +constructor treportcontainer.create(aowner: tcomponent); +begin + inherited; + createframe; + frame.colorclient:= cl_white; + anchors:= [an_top,an_bottom]; +end; + +function treportcontainer.isdesignwidget: boolean; +begin + result:= true; +end; +} +{ treportdesignerfo } + +constructor treportdesignerfo.create(const aowner: tcomponent; + const adesigner: tdesigner; const aintf: pdesignmoduleintfty; + const amoduleinfo: pmoduleinfoty); +begin + fisreppage:= amoduleinfo^.instance is treppageform; + inherited; + include(twidget1(pointer(reportcontainer)).fwidgetstate1,ws1_designwidget); +end; + +function treportdesignerfo.fixformsize: boolean; +begin + result:= true; +end; + +function treportdesignerfo.getmoduleparent: twidget; +begin + result:= reportcontainer; +end; + +function treportdesignerfo.gridrect: rectty; +begin + if reportcontainer.visible then begin + with reportcontainer do begin + result:= intersectrect(inherited gridrect, + makerect(translatewidgetpoint(paintpos,reportcontainer,self),paintsize)); + end; + end + else begin + with reportcontainer do begin + result:= intersectrect(inherited gridrect, + makerect(translatewidgetpoint(pos,reportcontainer.parentwidget,self), + size)); + end; + end; +end; + +function treportdesignerfo.insertoffset: pointty; +begin +// result:= translateclientpoint(nullpoint,reportcontainer,self); + if fformcont.visible then begin + result:= translatewidgetpoint(reportcontainer.clientwidgetpos, + reportcontainer,self); +// result:= translatewidgetpoint(nullpoint,reportcontainer,self); + end + else begin + result:= inherited insertoffset; + end; +end; + +function treportdesignerfo.widgetrefpoint: pointty; +begin + if fformcont.visible then begin + result:= translatewidgetpoint(reportcontainer.pos, + reportcontainer.parentwidget,self); + addpoint1(result,reportcontainer.clientpos); + end + else begin + result:= inherited widgetrefpoint(); + end; +end; + +procedure treportdesignerfo.repchildscaled(const sender: TObject); +begin + ydisp.bounds_cx:= getcanvas.getstringwidth('999.9') + 8; + xdisp.bounds_cx:= getcanvas.getstringwidth('999.9mm') + 8; + placexorder(0,[],[ydisp,xdisp,tabbar],0); +end; + +procedure treportdesignerfo.checktabs; +var + int1: integer; +begin + if not fisreppage and (report <> nil) then begin + if report.reppagecount = 0 then begin + addpage(nil); + exit; + end; + tabbar.tabs.count:= report.reppagecount; + for int1:= 0 to tabbar.tabs.count - 1 do begin + tabbar.tabs[int1].caption:= msestring(report[int1].name); + end; + if (report.reppagecount > 0) then begin + if tabbar.activetab < 0 then begin + tabbar.activetab:= 0; + end + else begin + tabcha(nil); //possibly deleted page + end; + end; + end; +end; + +function treportdesignerfo.report: tcustomreport; +begin + if fisreppage then begin + raise exception.create('No report'); + end; + result:= tcustomreport(module); +end; + +function treportdesignerfo.reppage: treppageform; +begin + if not fisreppage then begin + raise exception.create('No reppageform'); + end; + result:= treppageform(module); +end; + +function treportdesignerfo.getdesigninfo(): prepdesigninfoty; +begin + if fisreppage then begin + result:= @treppageform1(module).frepdesigninfo; + end + else begin + result:= @tcustomreport1(module).frepdesigninfo; + end; +end; + +procedure treportdesignerfo.validaterename(acomponent: tcomponent; + const curname: string; const newname: string); +begin + inherited; + updatetabs; +end; + +procedure treportdesignerfo.doasyncevent(var atag: integer); +begin + if atag = updatetabtag then begin + exclude(fstate,rds_tabupdating); + checktabs; + end + else begin + inherited; + end; +end; + +procedure treportdesignerfo.updatetabs; +begin + if not (rds_tabupdating in fstate) then begin + include(fstate,rds_tabupdating); + asyncevent(updatetabtag); + end; +end; + +procedure treportdesignerfo.tabcha(const sender: TObject); +var + reppage1: tcustomreportpage; + int1: integer; +begin + if tabbar.activetab >= 0 then begin + for int1:= 0 to report.reppagecount - 1 do begin + report[int1].visible:= int1 = tabbar.activetab; + end; + reppage1:= report[tabbar.activetab]; + report.size:= reppage1.size; + reppage1.bringtofront; +// designer.selectcomponent(report); + end; +end; + +procedure treportdesignerfo.componentselected( + const aselections: tformdesignerselections); +var + int1,int2: integer; + widget1: twidget; +begin + if not fisreppage then begin + with tcustomreport1(report) do begin + for int1:= 0 to aselections.count-1 do begin + widget1:= twidget(aselections[int1]); + if widget1 is twidget then begin + for int2:= high(freppages) downto 0 do begin + if widget1.checkancestor(freppages[int2]) then begin + checktabs; + tabbar.activetab:= int2; + exit; + end; + end; + end; + end; + end; + end; +end; + +procedure treportdesignerfo.tabmo(const sender: TObject; var curindex: Integer; + var newindex: Integer); +begin + moveitem(pointerarty(tcustomreport1(report).freppages),curindex,newindex); +end; + +procedure treportdesignerfo.tabmouse(const sender: twidget; + var info: mouseeventinfoty); +begin + with info do begin + if (eventkind = ek_buttonpress) and (button = mb_left) then begin + designer.selectcomponent(module); + end; + end; +end; + +procedure treportdesignerfo.placemodule(); +begin + inherited; + with getdesigninfo^.widgetrect do begin + fmodulepos:= pos; + fmodulesize:= size; + end; +end; + +procedure treportdesignerfo.beginstreaming; +begin +// tcustomreport1(form).frepdesigninfo.widgetrect:= widgetrect; + with getdesigninfo^.widgetrect do begin + pos:= fmodulepos; + size:= fmodulesize; + end; +end; + +procedure treportdesignerfo.endstreaming; +begin + //dummy +end; + +function treportdesignerfo.getdesignrect: rectty; +begin + result:= getdesigninfo^.widgetrect; +end; + +function treportdesignerfo.getmodulesize: sizety; +begin + result:= getdesigninfo^.widgetrect.size; +end; + +procedure treportdesignerfo.popupupda(const sender: tcustommenu); +begin + popupme.menu.itembyname('delpage').enabled:= tabbar.activetab >= 0; +end; +{ +function treportdesignerfo.candelete(const acomponent: tcomponent): boolean; +var + int1: integer; +begin + result:= true; + with report do begin + for int1:= 0 to reppagecount - 1 do begin + if acomponent = reppages[int1] then begin + result:= false; + break; + end; + end; + end; +end; +} + +function treportdesignerfo.checkdelete(): boolean; +var + int1,int2: integer; + comp1: tcomponent; + pages: reportpagearty; + bo1: boolean; +begin + result:= false; + if inherited checkdelete() then begin + if not fisreppage then begin + pages:= tcustomreport1(report).freppages; + bo1:= false; + with fselections do begin + for int1:= 0 to count - 1 do begin + comp1:= items[int1]; + for int2:= 0 to high(pages) do begin + if pages[int2] = comp1 then begin + bo1:= true; + if not askok(sc[ord(sc_wishdelete)]+' '''+ + msestring(comp1.name)+'''?',sc[ord(sc_warning)],mr_cancel) then begin + exit; + end; + end; + end; + end; + end; + if bo1 then begin + updatetabs; + end; + end; + result:= true; + end; +end; + +procedure treportdesignerfo.addpage(const sender: TObject); +var + comp1: tcomponent; +begin + comp1:= designer.createnewcomponent(report,treportpage); + placecomponent(comp1,translatewidgetpoint(reportcontainer.pos, + reportcontainer.parentwidget,self),report); + updatetabs; +end; + +procedure treportdesignerfo.placecomponent(const component: tcomponent; + const apos: pointty; aparent: tcomponent = nil); +begin + if not fisreppage and (component is tcustomreportpage) then begin + inherited placecomponent(component, + translatewidgetpoint(reportcontainer.pos, + reportcontainer.parentwidget,self),report); + end + else begin + inherited; + end; +end; + +procedure treportdesignerfo.deletepage(const sender: TObject); +var + comp1: tcomponent; +begin + comp1:= report[tabbar.activetab]; + if askok(sc[ord(sc_wishdelete)]+' '''+msestring(comp1.name)+'''?', + sc[ord(sc_warning)],mr_cancel) then begin +// designer.deletecomponent(comp1); + deletecomponent(comp1); + updatetabs; + end; +end; + +function treportdesignerfo.getgridsizex: integer; +begin + result:= round(getdesigninfo^.gridsize * ppmm); + if result < 2 then begin + result:= 2; + end; +end; + +function treportdesignerfo.getgridsizey: integer; +begin + result:= gridsizex; +end; + +function treportdesignerfo.getshowgrid: boolean; +begin + result:= getdesigninfo^.showgrid; +end; + +function treportdesignerfo.getsnaptogrid: boolean; +begin + result:= getdesigninfo^.snaptogrid; +end; + +function treportdesignerfo.ppmm: real; +begin + if fisreppage then begin + if reppage = nil then begin + result:= 3; + end + else begin + result:= reppage.ppmm; + end; + end + else begin + if report = nil then begin + result:= 3; + end + else begin + result:= report.ppmm; + end; + end; +end; + +procedure treportdesignerfo.setmousemarkers(const avalue: pointty; + const source: twidget); +var + pt1: pointty; +begin + pt1:= translatewidgetpoint(avalue,source,reportcontainer); + xdisp.value:= pt1.x/ppmm + dialh.dial.start; + dialh.dial.markers[0].value:= xdisp.value; + ydisp.value:= pt1.y/ppmm + dialv.dial.start; + dialv.dial.markers[0].value:= ydisp.value; +end; + +procedure treportdesignerfo.reportchildmouseevent(const sender: twidget; + var info: mouseeventinfoty); +//var +// pt1: pointty; +begin + with info do begin + case eventkind of + ek_mouseleave: begin + exclude(fstate,rds_mouseinclient); + xdisp.value:= emptyreal; + ydisp.value:= emptyreal; + dialh.dial.markers[0].value:= emptyreal; + dialv.dial.markers[0].value:= emptyreal; + end; + ek_mouseenter: begin + include(fstate,rds_mouseinclient); + end; + ek_buttonpress: begin + if (button = mb_left) and (ss_double in shiftstate) and + not reportcontainer.checkdescendent(sender) then begin + designer.showobjectinspector; + include(eventstate,es_processed); + end; + end; + end; + if (eventkind in mouseposevents) and (rds_mouseinclient in fstate) then begin + setmousemarkers(pos,sender); + end; + end; +end; + +procedure treportdesignerfo.updatedials; + procedure adjustticks(const adial: tcustomdialcontroller); + begin + with adial do begin + ticks[0].intervalcount:= range/10.0; + ticks[1].intervalcount:= range/5.0; + ticks[2].intervalcount:= range/1.0; + end; + end; +begin + if dialh.bounds_cx > 0 then begin + dialh.dial.range:= dialh.bounds_cx / ppmm; //mm + end; + if dialv.bounds_cy > 0 then begin + dialv.dial.range:= dialv.bounds_cy / ppmm; //mm + end; + dialh.dial.start:= -reportcontainer.clientpos.x / ppmm; + dialv.dial.start:= -reportcontainer.clientpos.y / ppmm; + adjustticks(dialh.dial); + adjustticks(dialv.dial); +end; + +procedure treportdesignerfo.formresized(const sender: TObject); +begin + updatedials; +end; + +procedure treportdesignerfo.reportcontainerscrolled(const sender: twidget; + const point: pointty); +begin + updatedials; + formcontainerscrolled; +end; + +procedure treportdesignerfo.repcomtainerchildscaled(const sender: TObject); +begin + updatedials; +end; + +procedure treportdesignerfo.componentmoving(const apos: pointty); +begin + setmousemarkers(apos,self); +end; + +procedure treportdesignerfo.setmoduleoptions(const aoptions: moduleoptionsty); +begin + inherited; + if mo_hidewidgets in aoptions then begin + reportcontainer.visible:= false; + end + else begin + reportcontainer.visible:= true; + fscrollbox.visible:= true; + fscrollbox.bringtofront(); + end; +end; + +function treportdesignerfo.markerrect(): rectty; +begin + result:= inherited markerrect(); + intersectrect1(result,mr( + translatewidgetpoint(reportcontainer.paintpos,reportcontainer,self), + reportcontainer.paintsize)); +end; + +end. + diff --git a/mseide-msegui/apps/ide/reportdesigner_mfm.pas b/mseide-msegui/apps/ide/reportdesigner_mfm.pas new file mode 100644 index 0000000..6da1476 --- /dev/null +++ b/mseide-msegui/apps/ide/reportdesigner_mfm.pas @@ -0,0 +1,330 @@ +unit reportdesigner_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,reportdesigner; + +const + objdata: record size: integer; data: array[0..6258] of byte end = + (size: 6259; data: ( + 84,80,70,48,241,17,116,114,101,112,111,114,116,100,101,115,105,103,110,101, + 114,102,111,16,114,101,112,111,114,116,100,101,115,105,103,110,101,114,102,111, + 8,98,111,117,110,100,115,95,120,3,198,0,8,98,111,117,110,100,115,95, + 121,3,137,0,9,98,111,117,110,100,115,95,99,120,3,87,1,9,98,111, + 117,110,100,115,95,99,121,3,203,1,15,99,111,110,116,97,105,110,101,114, + 46,99,111,108,111,114,4,7,0,0,144,18,99,111,110,116,97,105,110,101, + 114,46,111,110,108,97,121,111,117,116,7,14,114,101,112,99,104,105,108,100, + 115,99,97,108,101,100,29,99,111,110,116,97,105,110,101,114,46,111,110,99, + 97,108,99,109,105,110,115,99,114,111,108,108,115,105,122,101,13,27,99,111, + 110,116,97,105,110,101,114,46,111,110,99,104,105,108,100,109,111,117,115,101, + 101,118,101,110,116,7,21,114,101,112,111,114,116,99,104,105,108,100,109,111, + 117,115,101,101,118,101,110,116,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,87,1,3,203,1,0,7,111,110, + 99,108,111,115,101,13,8,111,110,114,101,115,105,122,101,7,11,102,111,114, + 109,114,101,115,105,122,101,100,8,111,110,108,97,121,111,117,116,7,14,114, + 101,112,99,104,105,108,100,115,99,97,108,101,100,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,15,84,102,111,114,109,100,101,115,105, + 103,110,101,114,102,111,0,242,2,0,5,116,100,105,97,108,5,100,105,97, + 108,104,5,99,111,108,111,114,4,7,0,0,144,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,102,105,108,101, + 102,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100, + 115,95,120,2,7,8,98,111,117,110,100,115,95,121,2,19,9,98,111,117, + 110,100,115,95,99,120,3,80,1,9,98,111,117,110,100,115,95,99,121,2, + 7,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,12,100,105,97,108, + 46,111,112,116,105,111,110,115,11,0,12,100,105,97,108,46,119,105,100,116, + 104,109,109,5,154,153,153,153,153,153,153,153,253,63,10,100,105,97,108,46, + 115,116,97,114,116,2,0,10,100,105,97,108,46,114,97,110,103,101,2,100, + 18,100,105,97,108,46,109,97,114,107,101,114,115,46,99,111,117,110,116,2, + 1,18,100,105,97,108,46,109,97,114,107,101,114,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,7,0,0,160,7,119,105,100,116,104,109, + 109,2,0,10,101,115,99,97,112,101,109,101,110,116,2,0,5,118,97,108, + 117,101,5,0,0,0,0,0,0,0,128,255,255,0,0,16,100,105,97,108, + 46,116,105,99,107,115,46,99,111,117,110,116,2,3,16,100,105,97,108,46, + 116,105,99,107,115,46,105,116,101,109,115,14,1,7,119,105,100,116,104,109, + 109,2,0,10,101,115,99,97,112,101,109,101,110,116,2,0,13,105,110,116, + 101,114,118,97,108,99,111,117,110,116,2,10,0,1,5,99,111,108,111,114, + 4,3,0,0,160,7,119,105,100,116,104,109,109,2,0,6,108,101,110,103, + 116,104,2,6,10,101,115,99,97,112,101,109,101,110,116,2,0,13,105,110, + 116,101,114,118,97,108,99,111,117,110,116,2,20,0,1,5,99,111,108,111, + 114,4,3,0,0,160,7,119,105,100,116,104,109,109,2,0,6,108,101,110, + 103,116,104,2,3,10,101,115,99,97,112,101,109,101,110,116,2,0,13,105, + 110,116,101,114,118,97,108,99,111,117,110,116,2,100,0,0,10,100,105,97, + 108,46,97,110,103,108,101,2,0,0,0,242,2,1,7,116,116,97,98,98, + 97,114,6,116,97,98,98,97,114,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,14, + 111,119,49,95,97,117,116,111,104,101,105,103,104,116,0,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,119, + 104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,5,99,111,108,111,114,4,5,0,0,144,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100,115, + 95,120,2,120,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,221,0,9,98,111,117,110,100,115,95,99,121,2,19, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,17,111,110,97,99,116, + 105,118,101,116,97,98,99,104,97,110,103,101,7,6,116,97,98,99,104,97, + 11,111,110,116,97,98,109,111,118,105,110,103,7,5,116,97,98,109,111,18, + 111,110,99,108,105,101,110,116,109,111,117,115,101,101,118,101,110,116,7,8, + 116,97,98,109,111,117,115,101,7,111,112,116,105,111,110,115,11,15,116,97, + 98,111,95,100,114,97,103,115,111,117,114,99,101,13,116,97,98,111,95,100, + 114,97,103,100,101,115,116,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,242,2,2,10,116,115,99,114,111,108,108,98,111,120, + 15,114,101,112,111,114,116,99,111,110,116,97,105,110,101,114,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,13,111,119,95,109,111,117,115,101, + 119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,5,0,0,144,19,102,114,97,109, + 101,46,111,112,116,105,111,110,115,115,99,114,111,108,108,11,9,111,115,99, + 114,95,100,114,97,103,8,111,115,99,114,95,107,101,121,15,111,115,99,114, + 95,109,111,117,115,101,119,104,101,101,108,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,6,0,0,160,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 1,8,98,111,117,110,100,115,95,120,2,7,8,98,111,117,110,100,115,95, + 121,2,26,9,98,111,117,110,100,115,95,99,120,3,79,1,9,98,111,117, + 110,100,115,95,99,121,3,177,1,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,8,111,110,108,97,121,111, + 117,116,7,23,114,101,112,99,111,109,116,97,105,110,101,114,99,104,105,108, + 100,115,99,97,108,101,100,10,111,110,115,99,114,111,108,108,101,100,7,23, + 114,101,112,111,114,116,99,111,110,116,97,105,110,101,114,115,99,114,111,108, + 108,101,100,0,0,242,2,3,7,116,115,112,97,99,101,114,8,116,115,112, + 97,99,101,114,49,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117, + 110,100,115,95,120,3,144,0,8,98,111,117,110,100,115,95,121,2,19,9, + 98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99, + 121,2,5,7,108,105,110,107,116,111,112,7,6,116,97,98,98,97,114,10, + 108,105,110,107,98,111,116,116,111,109,7,5,100,105,97,108,104,11,100,105, + 115,116,95,98,111,116,116,111,109,2,251,0,0,242,2,4,5,116,100,105, + 97,108,5,100,105,97,108,118,5,99,111,108,111,114,4,7,0,0,144,8, + 116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,26,9,98,111,117,110,100,115,95, + 99,120,2,7,9,98,111,117,110,100,115,95,99,121,3,177,1,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,9,97,110,95,98,111,116,116,111,109,0,12,100,105,97,108,46,119,105, + 100,116,104,109,109,5,154,153,153,153,153,153,153,153,253,63,14,100,105,97, + 108,46,100,105,114,101,99,116,105,111,110,7,7,103,100,95,100,111,119,110, + 10,100,105,97,108,46,115,116,97,114,116,2,0,10,100,105,97,108,46,114, + 97,110,103,101,2,100,18,100,105,97,108,46,109,97,114,107,101,114,115,46, + 99,111,117,110,116,2,1,18,100,105,97,108,46,109,97,114,107,101,114,115, + 46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,7,0,0,160,7, + 119,105,100,116,104,109,109,2,0,10,101,115,99,97,112,101,109,101,110,116, + 2,0,5,118,97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,0, + 0,16,100,105,97,108,46,116,105,99,107,115,46,99,111,117,110,116,2,3, + 16,100,105,97,108,46,116,105,99,107,115,46,105,116,101,109,115,14,1,7, + 119,105,100,116,104,109,109,2,0,10,101,115,99,97,112,101,109,101,110,116, + 2,0,13,105,110,116,101,114,118,97,108,99,111,117,110,116,2,10,0,1, + 5,99,111,108,111,114,4,3,0,0,160,7,119,105,100,116,104,109,109,2, + 0,6,108,101,110,103,116,104,2,6,10,101,115,99,97,112,101,109,101,110, + 116,2,0,13,105,110,116,101,114,118,97,108,99,111,117,110,116,2,20,0, + 1,5,99,111,108,111,114,4,3,0,0,160,7,119,105,100,116,104,109,109, + 2,0,6,108,101,110,103,116,104,2,4,10,101,115,99,97,112,101,109,101, + 110,116,2,0,13,105,110,116,101,114,118,97,108,99,111,117,110,116,2,100, + 0,0,10,100,105,97,108,46,97,110,103,108,101,2,0,0,0,242,2,5, + 7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,50,8,116,97, + 98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,144,0, + 8,98,111,117,110,100,115,95,121,2,26,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,5,7,108,105,110,107, + 116,111,112,7,5,100,105,97,108,104,10,108,105,110,107,98,111,116,116,111, + 109,7,15,114,101,112,111,114,116,99,111,110,116,97,105,110,101,114,11,100, + 105,115,116,95,98,111,116,116,111,109,2,251,0,0,242,2,6,7,116,115, + 112,97,99,101,114,8,116,115,112,97,99,101,114,51,8,116,97,98,111,114, + 100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,7,8,98,111,117, + 110,100,115,95,121,3,173,0,9,98,111,117,110,100,115,95,99,120,2,5, + 9,98,111,117,110,100,115,95,99,121,2,50,8,108,105,110,107,108,101,102, + 116,7,5,100,105,97,108,118,9,108,105,110,107,114,105,103,104,116,7,15, + 114,101,112,111,114,116,99,111,110,116,97,105,110,101,114,10,100,105,115,116, + 95,114,105,103,104,116,2,251,0,0,242,2,7,9,116,114,101,97,108,100, + 105,115,112,5,120,100,105,115,112,5,99,111,108,111,114,4,5,0,0,144, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120,2, + 52,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,68,9,98,111,117,110,100,115,95,99,121,2,18,9,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100, + 0,10,118,97,108,117,101,114,97,110,103,101,2,1,10,118,97,108,117,101, + 115,116,97,114,116,2,0,6,102,111,114,109,97,116,6,5,48,46,48,109, + 109,5,118,97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,242,2,8,9, + 116,114,101,97,108,100,105,115,112,5,121,100,105,115,112,5,99,111,108,111, + 114,4,5,0,0,144,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99,121, + 2,18,10,118,97,108,117,101,114,97,110,103,101,2,1,10,118,97,108,117, + 101,115,116,97,114,116,2,0,6,102,111,114,109,97,116,6,3,48,46,48, + 5,118,97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,242,2,9,7,116, + 115,112,97,99,101,114,8,116,115,112,97,99,101,114,52,8,116,97,98,111, + 114,100,101,114,2,9,8,98,111,117,110,100,115,95,120,2,16,8,98,111, + 117,110,100,115,95,121,2,26,9,98,111,117,110,100,115,95,99,120,2,50, + 9,98,111,117,110,100,115,95,99,121,2,5,7,108,105,110,107,116,111,112, + 7,5,100,105,97,108,104,10,108,105,110,107,98,111,116,116,111,109,7,5, + 100,105,97,108,118,11,100,105,115,116,95,98,111,116,116,111,109,2,251,0, + 0,243,2,10,10,116,112,111,112,117,112,109,101,110,117,7,112,111,112,117, + 112,109,101,18,109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101, + 109,115,14,1,0,1,0,1,0,1,0,1,5,115,116,97,116,101,11,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,0,1, + 5,115,116,97,116,101,11,16,97,115,95,108,111,99,97,108,100,105,115,97, + 98,108,101,100,17,97,115,95,108,111,99,97,108,105,110,118,105,115,105,98, + 108,101,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,0,1,5,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108,105, + 110,118,105,115,105,98,108,101,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,0,1,5,115,116,97,116,101,11,17,97,115,95, + 108,111,99,97,108,105,110,118,105,115,105,98,108,101,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,0,1,0,1,0,1,0, + 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 1,0,1,0,0,0,0,243,2,11,7,116,97,99,116,105,111,110,11,104, + 105,100,101,99,111,109,112,97,99,116,0,0,243,2,12,7,116,97,99,116, + 105,111,110,13,104,105,100,101,119,105,100,103,101,116,97,99,116,5,115,116, + 97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,12,97,115,95, + 105,110,118,105,115,105,98,108,101,0,0,0,243,2,13,7,116,97,99,116, + 105,111,110,13,116,111,103,103,108,101,104,105,100,101,97,99,116,0,0,243, + 2,14,7,116,97,99,116,105,111,110,10,115,104,111,119,97,108,108,97,99, + 116,0,0,242,2,15,10,116,112,111,112,117,112,109,101,110,117,11,116,112, + 111,112,117,112,109,101,110,117,51,18,109,101,110,117,46,115,117,98,109,101, + 110,117,46,99,111,117,110,116,2,29,18,109,101,110,117,46,115,117,98,109, + 101,110,117,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6, + 20,83,104,111,119,32,111,98,106,101,99,116,105,110,115,112,101,99,116,111, + 114,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117, + 116,101,0,0,1,7,99,97,112,116,105,111,110,6,21,83,104,111,119,32, + 99,111,109,112,111,110,101,110,116,112,97,108,101,116,116,101,5,115,116,97, + 116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,0,1, + 7,99,97,112,116,105,111,110,6,12,83,104,111,119,32,97,115,32,84,101, + 120,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115, + 121,110,99,101,120,101,99,117,116,101,0,0,1,6,97,99,116,105,111,110, + 7,26,102,111,114,109,100,101,115,105,103,110,101,114,102,111,46,104,105,100, + 101,99,111,109,112,97,99,116,7,111,112,116,105,111,110,115,11,13,109,97, + 111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114, + 116,99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111, + 110,7,28,102,111,114,109,100,101,115,105,103,110,101,114,102,111,46,104,105, + 100,101,119,105,100,103,101,116,97,99,116,7,111,112,116,105,111,110,115,11, + 12,109,97,111,95,99,104,101,99,107,98,111,120,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116, + 105,111,110,7,13,104,105,100,101,119,105,100,103,101,116,97,99,116,5,115, + 116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,12,97,115, + 95,105,110,118,105,115,105,98,108,101,0,7,111,112,116,105,111,110,115,11, + 12,109,97,111,95,99,104,101,99,107,98,111,120,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116, + 105,111,110,7,13,116,111,103,103,108,101,104,105,100,101,97,99,116,0,1, + 6,97,99,116,105,111,110,7,10,115,104,111,119,97,108,108,97,99,116,0, + 1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114, + 97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112, + 116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,17,67,111,112, + 121,32,67,111,109,112,111,110,101,110,116,40,115,41,4,110,97,109,101,6, + 4,99,111,112,121,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,16,97,115,95,108,111,99,97,108,115,104,111, + 114,116,99,117,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,2,115,99,1,2,1,3,67,64,0,0,1,7,99,97,112, + 116,105,111,110,6,16,67,117,116,32,67,111,109,112,111,110,101,110,116,40, + 115,41,4,110,97,109,101,6,3,99,117,116,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,16,97,115,95,108, + 111,99,97,108,115,104,111,114,116,99,117,116,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 16,109,97,111,95,97,115,121,110,99,101,120,101,99,117,116,101,0,2,115, + 99,1,2,1,3,88,64,0,0,1,7,99,97,112,116,105,111,110,6,18, + 80,97,115,116,101,32,67,111,109,112,111,110,101,110,116,40,115,41,4,110, + 97,109,101,6,5,112,97,115,116,101,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,16,97,115,95,108,111,99, + 97,108,115,104,111,114,116,99,117,116,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,2,115,99,1,2,1,3,86,64,0,0, + 1,7,99,97,112,116,105,111,110,6,19,68,101,108,101,116,101,32,67,111, + 109,112,111,110,101,110,116,40,115,41,4,110,97,109,101,6,6,100,101,108, + 101,116,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,16,97,115,95,108,111,99,97,108,115,104,111,114,116, + 99,117,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114, + 116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110, + 99,101,120,101,99,117,116,101,0,2,115,99,1,2,1,3,7,1,0,0, + 1,7,99,97,112,116,105,111,110,6,21,85,110,100,101,108,101,116,101,32, + 67,111,109,112,111,110,101,110,116,40,115,41,4,110,97,109,101,6,8,117, + 110,100,101,108,101,116,101,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,0,1,7,111,112,116,105,111,110,115,11, + 13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115, + 104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,7,99,97, + 112,116,105,111,110,6,18,83,101,108,101,99,116,32,67,104,105,108,100,119, + 105,100,103,101,116,4,110,97,109,101,6,11,115,101,108,101,99,116,99,104, + 105,108,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,14,69, + 100,105,116,32,67,111,109,112,111,110,101,110,116,4,110,97,109,101,6,8, + 101,100,105,116,99,111,109,112,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,0,1,7,99,97,112,116,105,111,110, + 6,14,66,114,105,110,103,32,116,111,32,70,114,111,110,116,4,110,97,109, + 101,6,10,98,114,105,110,103,116,111,102,114,111,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,0,1,7,99,97, + 112,116,105,111,110,6,12,83,101,110,100,32,116,111,32,66,97,99,107,4, + 110,97,109,101,6,8,115,101,110,100,116,111,98,97,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,0,1,7,99, + 97,112,116,105,111,110,6,7,73,99,111,110,105,102,121,4,110,97,109,101, + 6,7,105,99,111,110,105,102,121,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,0,1,7,99,97,112,116,105,111, + 110,6,9,68,101,105,99,111,110,105,102,121,4,110,97,109,101,6,9,100, + 101,105,99,111,110,105,102,121,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,0,1,7,99,97,112,116,105,111,110, + 6,13,83,101,116,32,84,97,98,32,79,114,100,101,114,4,110,97,109,101, + 6,9,115,101,116,116,97,98,111,114,100,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,0,1,7,99,97,112,116, + 105,111,110,6,18,83,101,116,32,67,114,101,97,116,105,111,110,32,79,114, + 100,101,114,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,0,1,7,99,97,112,116,105,111,110,6,20,83,121,110, + 99,46,32,116,111,32,70,111,110,116,32,72,101,105,103,104,116,4,110,97, + 109,101,6,8,115,121,110,99,116,111,102,111,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,0,1,7,99,97,112, + 116,105,111,110,6,19,82,101,118,101,114,116,32,116,111,32,105,110,104,101, + 114,105,116,101,100,4,110,97,109,101,6,6,114,101,118,101,114,116,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99, + 117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101, + 120,101,99,117,116,101,0,0,1,7,111,112,116,105,111,110,115,11,13,109, + 97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111, + 114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116, + 105,111,110,6,10,84,111,117,99,104,32,70,111,114,109,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112, + 116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 0,0,1,7,99,97,112,116,105,111,110,6,15,65,100,100,32,114,101,112, + 111,114,116,32,112,97,103,101,4,110,97,109,101,6,7,97,100,100,112,97, + 103,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,0,1,7,99,97,112,116,105,111,110,6,18,68,101,108,101, + 116,101,32,114,101,112,111,114,116,32,112,97,103,101,4,110,97,109,101,6, + 7,100,101,108,112,97,103,101,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,0,0,4,108,101,102,116,2,16,3, + 116,111,112,3,160,0,0,0,243,2,16,16,116,115,116,114,105,110,103,99, + 111,110,116,97,105,110,101,114,1,99,0,0,242,2,17,16,116,115,116,114, + 105,110,103,99,111,110,116,97,105,110,101,114,2,115,99,12,115,116,114,105, + 110,103,115,46,100,97,116,97,1,6,21,68,111,32,121,111,117,32,119,105, + 115,104,32,116,111,32,100,101,108,101,116,101,6,7,87,65,82,78,73,78, + 71,0,4,108,101,102,116,2,64,3,116,111,112,3,208,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,treportdesignerfo,''); +end. diff --git a/mseide-msegui/apps/ide/selecteditpageform.mfm b/mseide-msegui/apps/ide/selecteditpageform.mfm new file mode 100644 index 0000000..da922cc --- /dev/null +++ b/mseide-msegui/apps/ide/selecteditpageform.mfm @@ -0,0 +1,66 @@ +object selecteditpagefo: tselecteditpagefo + visible = False + bounds_x = 160 + bounds_y = 124 + bounds_cx = 704 + bounds_cy = 473 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = formonchildscaled + container.bounds = ( + 0 + 0 + 704 + 473 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + caption = 'Select edit page (Ctrl+E)' + icon.transparentcolor = -2147483648 + oneventloopstart = fooncreate + onlayout = formonchildscaled + moduleclassname = 'tmseform' + object list: tlistview + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets, ow_multiplehint] + frame.colorclient = -1879048187 + frame.localprops = [frl_colorclient] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 704 + bounds_cy = 451 + anchors = [an_top, an_bottom] + datarowlinewidth = 0 + datacollinewidth = 0 + cellwidth = 100 + cellheight = 20 + cellframe.leveli = 1 + cellframe.localprops = [frl_leveli] + cellframe.localprops1 = [] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wraprow, og_wrapcol, og_autopopup] + options = [lvo_readonly, lvo_drawfocus, lvo_mousemovefocus, lvo_focusselect, lvo_mouseselect, lvo_locate, lvo_hintclippedtext] + onitemevent = doonitemevent + reffontheight = 16 + end + object pathdisp: tstringdisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 452 + bounds_cx = 650 + anchors = [an_left, an_right, an_bottom] + textflags = [tf_ycentered, tf_ellipseleft] + reffontheight = 16 + end + object openfilebutton: tbutton + taborder = 1 + bounds_x = 652 + bounds_y = 452 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption, as_localonexecute] + caption = '&Open' + onexecute = openfileonexecute + end +end diff --git a/mseide-msegui/apps/ide/selecteditpageform.pas b/mseide-msegui/apps/ide/selecteditpageform.pas new file mode 100644 index 0000000..57a8c21 --- /dev/null +++ b/mseide-msegui/apps/ide/selecteditpageform.pas @@ -0,0 +1,163 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit selecteditpageform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,mselistbrowser,msetypes,msestrings,msegrids,msegui,msedispwidgets, + msestat,msesimplewidgets,mseglob,msegridsglob; + +type + tselecteditpagefo = class(tmseform) + list: tlistview; + pathdisp: tstringdisp; + openfilebutton: tbutton; + procedure doonitemevent(const sender: tcustomlistview; const index: Integer; + var info: celleventinfoty); +// procedure doonshowhint(const sender: TObject; var info: hintinfoty); + procedure fooncreate(const sender: TObject); + procedure openfileonexecute(const sender: TObject); + procedure formonchildscaled(const sender: TObject); + private + fpaths,frelpaths,fnames: filenamearty; + fsortlist: integerarty; + public + end; + +procedure selecteditpage; +procedure updatestat(const filer: tstatfiler); + +implementation + +uses + selecteditpageform_mfm,sourceform,msedatalist,msedatanodes,msegraphutils,main, + msefileutils,mseguiglob,msearrayutils; +var + colwidth: integer; + pos: rectty; + +procedure updatestat(const filer: tstatfiler); +begin + filer.setsection('selecteditpage'); + filer.updatevalue('colwidth',colwidth); + with pos do begin + filer.updatevalue('x',x); + filer.updatevalue('y',y); + filer.updatevalue('cx',cx); + filer.updatevalue('cy',cy); + end; +end; + +procedure selecteditpage; +var + fo: tselecteditpagefo; +begin + fo:= tselecteditpagefo.create(nil); + try + fo.list.cellwidth:= colwidth; + if (pos.cx > 0) and (pos.y > 0) then begin + fo.widgetrect:= pos; + end; + if fo.show(true,sourcefo.window) = mr_ok then begin + sourcefo.show; + sourcefo.setfocus; + end; + colwidth:= fo.list.cellwidth; + pos:= fo.window.normalwindowrect; + finally + fo.Free; + end; +end; + +{ tselecteditpagefo } + +procedure tselecteditpagefo.doonitemevent(const sender: tcustomlistview; + const index: Integer; var info: celleventinfoty); +begin + if iscellclick(info) then begin + sourcefo.tabwidget.activepageindex:= fsortlist[index]; + window.modalresult:= mr_ok; + end + else begin + if info.eventkind = cek_enter then begin + if findfile(frelpaths[fsortlist[index]]) then begin + pathdisp.value:= filepath(frelpaths[fsortlist[index]]); + end + else begin + pathdisp.value:= fpaths[fsortlist[index]]; + end; + end; + end; +end; +{ +procedure tselecteditpagefo.doonshowhint(const sender: TObject; var info: hintinfoty); +var + item1: tlistitem; +begin + item1:= list.itematpos(info.posrect.pos); + if item1 <> nil then begin + with info do begin + caption:= fpaths[fsortlist[item1.index]]; + include(flags,hfl_show); + showtime:= 0; + end; + end; +end; +} +procedure tselecteditpagefo.fooncreate(const sender: TObject); +var + int1,int2: integer; +begin + setlength(fpaths,sourcefo.count); + setlength(frelpaths,sourcefo.count); + setlength(fnames,sourcefo.count); + for int1:= 0 to high(fpaths) do begin + fpaths[int1]:= sourcefo.items[int1].filepath; + frelpaths[int1]:= sourcefo.items[int1].relpath; + fnames[int1]:= sourcefo.items[int1].filename; + end; + sortarray(fnames,sms_upi,fsortlist); + list.itemlist.add(fnames); + int2:= sourcefo.tabwidget.activepageindex; + for int1:= 0 to high(fsortlist) do begin + if fsortlist[int1] = int2 then begin + list.focusedindex:= int1; + break; + end; + end; +end; + +procedure tselecteditpagefo.openfileonexecute(const sender: TObject); +begin + if mainfo.opensource(fk_source,false) then begin + release; + end; +end; + +procedure tselecteditpagefo.formonchildscaled(const sender: TObject); +begin + placeyorder(0,[1],[list,pathdisp],1); + openfilebutton.height:= pathdisp.height; + aligny(wam_center,[pathdisp,openfilebutton]); + list.synctofontheight; +end; + +initialization + colwidth:= 100; +end. diff --git a/mseide-msegui/apps/ide/selecteditpageform_mfm.pas b/mseide-msegui/apps/ide/selecteditpageform_mfm.pas new file mode 100644 index 0000000..829a4b7 --- /dev/null +++ b/mseide-msegui/apps/ide/selecteditpageform_mfm.pas @@ -0,0 +1,98 @@ +unit selecteditpageform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,selecteditpageform; + +const + objdata: record size: integer; data: array[0..1613] of byte end = + (size: 1614; data: ( + 84,80,70,48,17,116,115,101,108,101,99,116,101,100,105,116,112,97,103,101, + 102,111,16,115,101,108,101,99,116,101,100,105,116,112,97,103,101,102,111,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,160,0, + 8,98,111,117,110,100,115,95,121,2,124,9,98,111,117,110,100,115,95,99, + 120,3,192,2,9,98,111,117,110,100,115,95,99,121,3,217,1,26,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,99,111,110, + 116,97,105,110,101,114,46,111,110,108,97,121,111,117,116,7,17,102,111,114, + 109,111,110,99,104,105,108,100,115,99,97,108,101,100,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,192,2,3, + 217,1,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101, + 101,110,99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111, + 110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116, + 16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111, + 95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100, + 101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,7,99,97,112, + 116,105,111,110,6,25,83,101,108,101,99,116,32,101,100,105,116,32,112,97, + 103,101,32,40,67,116,114,108,43,69,41,21,105,99,111,110,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,0,0,0,128,16,111, + 110,101,118,101,110,116,108,111,111,112,115,116,97,114,116,7,10,102,111,111, + 110,99,114,101,97,116,101,8,111,110,108,97,121,111,117,116,7,17,102,111, + 114,109,111,110,99,104,105,108,100,115,99,97,108,101,100,15,109,111,100,117, + 108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114, + 109,0,9,116,108,105,115,116,118,105,101,119,4,108,105,115,116,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110, + 101,115,99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,15,111,119,95,109, + 117,108,116,105,112,108,101,104,105,110,116,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,5,0,0,144,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,192,2,9,98,111,117,110,100,115,95,99,121,3,195,1,7,97, + 110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111, + 116,116,111,109,0,16,100,97,116,97,114,111,119,108,105,110,101,119,105,100, + 116,104,2,0,16,100,97,116,97,99,111,108,108,105,110,101,119,105,100,116, + 104,2,0,9,99,101,108,108,119,105,100,116,104,2,100,10,99,101,108,108, + 104,101,105,103,104,116,2,20,16,99,101,108,108,102,114,97,109,101,46,108, + 101,118,101,108,105,2,1,20,99,101,108,108,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,105, + 0,21,99,101,108,108,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111, + 103,95,99,111,108,115,105,122,105,110,103,19,111,103,95,102,111,99,117,115, + 99,101,108,108,111,110,101,110,116,101,114,20,111,103,95,99,111,108,99,104, + 97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112, + 114,111,119,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117, + 116,111,112,111,112,117,112,0,7,111,112,116,105,111,110,115,11,12,108,118, + 111,95,114,101,97,100,111,110,108,121,13,108,118,111,95,100,114,97,119,102, + 111,99,117,115,18,108,118,111,95,109,111,117,115,101,109,111,118,101,102,111, + 99,117,115,15,108,118,111,95,102,111,99,117,115,115,101,108,101,99,116,15, + 108,118,111,95,109,111,117,115,101,115,101,108,101,99,116,10,108,118,111,95, + 108,111,99,97,116,101,19,108,118,111,95,104,105,110,116,99,108,105,112,112, + 101,100,116,101,120,116,0,11,111,110,105,116,101,109,101,118,101,110,116,7, + 13,100,111,111,110,105,116,101,109,101,118,101,110,116,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,16,0,0,11,116,115,116,114,105,110,103, + 100,105,115,112,8,112,97,116,104,100,105,115,112,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,3,196,1,9,98,111,117,110,100,115,95,99,120,3,138,2,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,9,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100, + 14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,7,116,98,117,116,116, + 111,110,14,111,112,101,110,102,105,108,101,98,117,116,116,111,110,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,140,2, + 8,98,111,117,110,100,115,95,121,3,196,1,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99, + 104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,5,38,79,112, + 101,110,9,111,110,101,120,101,99,117,116,101,7,17,111,112,101,110,102,105, + 108,101,111,110,101,120,101,99,117,116,101,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tselecteditpagefo,''); +end. diff --git a/mseide-msegui/apps/ide/selectsubformdialogform.pas b/mseide-msegui/apps/ide/selectsubformdialogform.pas new file mode 100644 index 0000000..84d1e66 --- /dev/null +++ b/mseide-msegui/apps/ide/selectsubformdialogform.pas @@ -0,0 +1,36 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit selectsubformdialogform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets; + +type + tselectsubformdialogfo = class(tmseform) + subform: tdropdownlistedit; + ok: tbutton; + cancel: tbutton; + end; + +implementation +uses + selectsubformdialogform_mfm; + +end. diff --git a/mseide-msegui/apps/ide/selectsubformdialogform_mfm.pas b/mseide-msegui/apps/ide/selectsubformdialogform_mfm.pas new file mode 100644 index 0000000..7d28380 --- /dev/null +++ b/mseide-msegui/apps/ide/selectsubformdialogform_mfm.pas @@ -0,0 +1,47 @@ +unit selectsubformdialogform_mfm; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,selectsubformdialogform; + +const + objdata: record size: integer; data: array[0..571] of byte end = + (size: 572; data: ( + 84,80,70,48,22,116,115,101,108,101,99,116,115,117,98,102,111,114,109,100, + 105,97,108,111,103,102,111,21,115,101,108,101,99,116,115,117,98,102,111,114, + 109,100,105,97,108,111,103,102,111,4,98,111,95,120,3,248,0,4,98,111, + 95,121,3,158,1,5,98,111,95,99,120,3,241,0,5,98,111,95,99,121, + 2,81,7,118,105,115,105,98,108,101,8,8,116,97,98,111,114,100,101,114, + 2,0,7,99,97,112,116,105,111,110,6,14,83,101,108,101,99,116,32,115, + 117,98,102,111,114,109,15,109,111,100,117,108,101,99,108,97,115,115,110,97, + 109,101,6,8,116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111, + 110,2,111,107,4,98,111,95,120,2,120,4,98,111,95,121,2,48,5,98, + 111,95,99,121,2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,8,116,97,98,111,114,100,101, + 114,2,2,7,99,97,112,116,105,111,110,6,2,79,75,11,109,111,100,97, + 108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117, + 116,116,111,110,6,99,97,110,99,101,108,4,98,111,95,120,3,184,0,4, + 98,111,95,121,2,48,5,98,111,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 8,116,97,98,111,114,100,101,114,2,1,7,99,97,112,116,105,111,110,6, + 6,67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7, + 9,109,114,95,99,97,110,99,101,108,0,0,17,116,100,114,111,112,100,111, + 119,110,108,105,115,116,101,100,105,116,7,115,117,98,102,111,114,109,4,98, + 111,95,120,2,8,4,98,111,95,121,2,8,5,98,111,95,99,120,3,228, + 0,5,98,111,95,99,121,2,20,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,254,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,8,116, + 97,98,111,114,100,101,114,2,0,16,100,114,111,112,100,111,119,110,46,111, + 112,116,105,111,110,115,11,14,100,101,111,95,115,101,108,101,99,116,111,110, + 108,121,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111, + 117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46, + 105,116,101,109,115,14,1,0,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tselectsubformdialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/selectsubmoduledialogform.mfm b/mseide-msegui/apps/ide/selectsubmoduledialogform.mfm new file mode 100644 index 0000000..0933695 --- /dev/null +++ b/mseide-msegui/apps/ide/selectsubmoduledialogform.mfm @@ -0,0 +1,51 @@ +object selectsubmoduledialogfo: tselectsubmoduledialogfo + visible = False + bounds_x = 391 + bounds_y = 320 + bounds_cx = 241 + bounds_cy = 81 + container.bounds = ( + 0 + 0 + 241 + 81 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + caption = 'Select subform' + moduleclassname = 'tmseform' + object ok: tbutton + taborder = 1 + bounds_x = 120 + bounds_y = 48 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 2 + bounds_x = 184 + bounds_y = 48 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object submodule: tdropdownlistedit + bounds_x = 8 + bounds_y = 8 + bounds_cx = 228 + anchors = [an_left, an_top, an_right] + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_sorted] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + end> + reffontheight = 14 + end +end diff --git a/mseide-msegui/apps/ide/selectsubmoduledialogform.pas b/mseide-msegui/apps/ide/selectsubmoduledialogform.pas new file mode 100644 index 0000000..ed0580f --- /dev/null +++ b/mseide-msegui/apps/ide/selectsubmoduledialogform.pas @@ -0,0 +1,36 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit selectsubmoduledialogform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets; + +type + tselectsubmoduledialogfo = class(tmseform) + submodule: tdropdownlistedit; + ok: tbutton; + cancel: tbutton; + end; + +implementation +uses + selectsubmoduledialogform_mfm; + +end. diff --git a/mseide-msegui/apps/ide/selectsubmoduledialogform_mfm.pas b/mseide-msegui/apps/ide/selectsubmoduledialogform_mfm.pas new file mode 100644 index 0000000..5796772 --- /dev/null +++ b/mseide-msegui/apps/ide/selectsubmoduledialogform_mfm.pas @@ -0,0 +1,64 @@ +unit selectsubmoduledialogform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,selectsubmoduledialogform; + +const + objdata: record size: integer; data: array[0..936] of byte end = + (size: 937; data: ( + 84,80,70,48,24,116,115,101,108,101,99,116,115,117,98,109,111,100,117,108, + 101,100,105,97,108,111,103,102,111,23,115,101,108,101,99,116,115,117,98,109, + 111,100,117,108,101,100,105,97,108,111,103,102,111,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,135,1,8,98,111,117,110,100, + 115,95,121,3,64,1,9,98,111,117,110,100,115,95,99,120,3,241,0,9, + 98,111,117,110,100,115,95,99,121,2,81,16,99,111,110,116,97,105,110,101, + 114,46,98,111,117,110,100,115,1,2,0,2,0,3,241,0,2,81,0,7, + 111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101,101,110,99,101, + 110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111,110,101,115,99, + 15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95, + 97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118, + 101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102, + 111,95,115,97,118,101,115,116,97,116,101,0,7,99,97,112,116,105,111,110, + 6,14,83,101,108,101,99,116,32,115,117,98,102,111,114,109,15,109,111,100, + 117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111, + 114,109,0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,120,8,98,111,117, + 110,100,115,95,121,2,48,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116, + 97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108, + 111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,2,79,75, + 11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0, + 0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108,8,116,97,98, + 111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,184,0,8, + 98,111,117,110,100,115,95,121,2,48,9,98,111,117,110,100,115,95,99,120, + 2,50,9,98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,0,7,99,97,112,116,105,111,110,6,6,67,97,110,99,101,108, + 11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110, + 99,101,108,0,0,17,116,100,114,111,112,100,111,119,110,108,105,115,116,101, + 100,105,116,9,115,117,98,109,111,100,117,108,101,8,98,111,117,110,100,115, + 95,120,2,8,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110, + 100,115,95,99,120,3,228,0,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11, + 14,100,101,111,95,115,101,108,101,99,116,111,110,108,121,16,100,101,111,95, + 97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121, + 100,114,111,112,100,111,119,110,10,100,101,111,95,115,111,114,116,101,100,0, + 19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116, + 2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101, + 109,115,14,1,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121, + 99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116, + 14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,0,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tselectsubmoduledialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/setcreateorderform.mfm b/mseide-msegui/apps/ide/setcreateorderform.mfm new file mode 100644 index 0000000..1d61187 --- /dev/null +++ b/mseide-msegui/apps/ide/setcreateorderform.mfm @@ -0,0 +1,109 @@ +object setcreateorderfo: tsetcreateorderfo + bounds_x = 223 + bounds_y = 264 + bounds_cx = 381 + bounds_cy = 340 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 381 + 340 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = statfile1 + onclosequery = formonclosequery + moduleclassname = 'tmseform' + object grid: tstringgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 381 + bounds_cy = 306 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + datacols.count = 2 + datacols.options = [co_readonly, co_focusselect, co_rowselect, co_proportional, co_savestate, co_mousescrollrow] + datacols.items = < + item + width = 165 + options = [co_readonly, co_focusselect, co_rowselect, co_proportional, co_savestate, co_mousescrollrow] + valuefalse = '0' + valuetrue = '1' + end + item + width = 159 + options = [co_readonly, co_focusselect, co_rowselect, co_fill, co_savestate, co_mousescrollrow] + optionsedit = [scoe_undoonesc, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick, scoe_hintclippedtext] + valuefalse = '0' + valuetrue = '1' + end> + fixcols.count = 1 + fixcols.items = < + item + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Class' + end> + captionsfix.count = 1 + captionsfix.items = < + item + caption = 'Order' + end> + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 1 + bounds_x = 254 + bounds_y = 312 + bounds_cx = 58 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 2 + bounds_x = 318 + bounds_y = 312 + bounds_cx = 58 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localdefault, as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object statfile1: tstatfile + filename = 'settaborderfo.sta' + options = [sfo_memory] + left = 104 + top = 136 + end + object c: tstringcontainer + strings.data = ( + 'Set Component create Order of' + ) + left = 40 + top = 40 + end +end diff --git a/mseide-msegui/apps/ide/setcreateorderform.pas b/mseide-msegui/apps/ide/setcreateorderform.pas new file mode 100644 index 0000000..3eb4f41 --- /dev/null +++ b/mseide-msegui/apps/ide/setcreateorderform.pas @@ -0,0 +1,89 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit setcreateorderform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,msegui,mseclasses,mseforms,msestat,msestatfile,msestrings, + msedatalist, + msedrawtext,mseevent,msegraphics,msegraphutils,msegrids,mseguiglob,mseglob, + msepipestream,msetypes,msesimplewidgets,msewidgets,msestringcontainer; + +type + tsetcreateorderfo = class(tmseform) + statfile1: tstatfile; + grid: tstringgrid; + tbutton1: tbutton; + tbutton2: tbutton; + c: tstringcontainer; + procedure formonclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); + private + fmodule: tcomponent; + public + constructor create(const amodule: tcomponent; const acurrentcompname: string); + reintroduce; + end; +var + setcreateorderfo: tsetcreateorderfo; + +implementation +uses + setcreateorderform_mfm,msedesigner; +type + stringconsttsty = ( + setcomponentcreateorder //0 Set Component create Order of + ); + +{ tsetcreateorderfo } + +constructor tsetcreateorderfo.create(const amodule: tcomponent; + const acurrentcompname: string); +var + int1: integer; +// str1: string; +begin + inherited create(nil); + caption:= c[ord(setcomponentcreateorder)]+' '+msestring(amodule.name); + fmodule:= amodule; + with amodule do begin + for int1:= 0 to componentcount - 1 do begin + with components[int1] do begin + if not hasparent or (csinline in componentstate) then begin + grid.appendrow([msestring(name),msestring(classname)]); + if acurrentcompname = name then begin + grid.row:=int1; + end; + end; + end; + end; + end; +end; + +procedure tsetcreateorderfo.formonclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); +//var +// int1: integer; +// comp1: tcomponent; +begin + if amodalresult = mr_ok then begin + setcomponentorder(fmodule,grid[0].datalist.asarray); + designer.componentmodified(fmodule); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/setcreateorderform_mfm.pas b/mseide-msegui/apps/ide/setcreateorderform_mfm.pas new file mode 100644 index 0000000..bd712d5 --- /dev/null +++ b/mseide-msegui/apps/ide/setcreateorderform_mfm.pas @@ -0,0 +1,121 @@ +unit setcreateorderform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,setcreateorderform; + +const + objdata: record size: integer; data: array[0..2072] of byte end = + (size: 2073; data: ( + 84,80,70,48,17,116,115,101,116,99,114,101,97,116,101,111,114,100,101,114, + 102,111,16,115,101,116,99,114,101,97,116,101,111,114,100,101,114,102,111,8, + 98,111,117,110,100,115,95,120,3,223,0,8,98,111,117,110,100,115,95,121, + 3,8,1,9,98,111,117,110,100,115,95,99,120,3,125,1,9,98,111,117, + 110,100,115,95,99,121,3,84,1,26,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,125,1,3,84,1,0,7,111,112, + 116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99, + 15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95, + 97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118, + 101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102, + 111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108, + 101,7,9,115,116,97,116,102,105,108,101,49,12,111,110,99,108,111,115,101, + 113,117,101,114,121,7,16,102,111,114,109,111,110,99,108,111,115,101,113,117, + 101,114,121,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6, + 8,116,109,115,101,102,111,114,109,0,11,116,115,116,114,105,110,103,103,114, + 105,100,4,103,114,105,100,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,125, + 1,9,98,111,117,110,100,115,95,99,121,3,50,1,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111, + 108,115,105,122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103, + 15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,19,111,103,95, + 102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,20,111,103,95, + 99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103, + 95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117, + 112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99,111,95,114, + 101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115, + 116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,1, + 5,119,105,100,116,104,3,165,0,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99, + 111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97, + 118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48, + 9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116, + 104,3,159,0,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97, + 100,111,110,108,121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,11,111,112,116,105,111,110, + 115,101,100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115, + 99,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99,111, + 101,95,97,117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 20,115,99,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108, + 117,101,116,114,117,101,6,1,49,0,0,13,102,105,120,99,111,108,115,46, + 99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109, + 115,14,1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114, + 111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46, + 105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112, + 116,105,111,110,115,46,99,111,117,110,116,2,2,14,99,97,112,116,105,111, + 110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,4, + 78,97,109,101,0,1,7,99,97,112,116,105,111,110,6,5,67,108,97,115, + 115,0,0,17,99,97,112,116,105,111,110,115,102,105,120,46,99,111,117,110, + 116,2,1,17,99,97,112,116,105,111,110,115,102,105,120,46,105,116,101,109, + 115,14,1,7,99,97,112,116,105,111,110,6,5,79,114,100,101,114,0,0, + 0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115, + 116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117, + 116,116,111,110,8,116,98,117,116,116,111,110,49,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,3,254,0,8,98,111,117,110,100,115,95,121,3,56,1,9, + 98,111,117,110,100,115,95,99,120,2,58,9,98,111,117,110,100,115,95,99, + 121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104, + 116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10, + 97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100, + 101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100, + 97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111, + 110,8,116,98,117,116,116,111,110,50,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101, + 0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,3,62,1,8,98,111,117,110,100,115,95,121,3,56,1,9,98,111,117, + 110,100,115,95,99,120,2,58,9,98,111,117,110,100,115,95,99,121,2,20, + 7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97, + 110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38, + 67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9, + 109,114,95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,9,116,115,116,97,116,102,105,108,101,9,115,116, + 97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,17,115,101, + 116,116,97,98,111,114,100,101,114,102,111,46,115,116,97,7,111,112,116,105, + 111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102, + 116,2,104,3,116,111,112,3,136,0,0,0,16,116,115,116,114,105,110,103, + 99,111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46, + 100,97,116,97,1,6,29,83,101,116,32,67,111,109,112,111,110,101,110,116, + 32,99,114,101,97,116,101,32,79,114,100,101,114,32,111,102,0,4,108,101, + 102,116,2,40,3,116,111,112,2,40,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsetcreateorderfo,''); +end. diff --git a/mseide-msegui/apps/ide/settaborderform.mfm b/mseide-msegui/apps/ide/settaborderform.mfm new file mode 100644 index 0000000..e60fa5d --- /dev/null +++ b/mseide-msegui/apps/ide/settaborderform.mfm @@ -0,0 +1,162 @@ +object settaborderfo: tsettaborderfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + bounds_x = 471 + bounds_y = 402 + bounds_cx = 292 + bounds_cy = 205 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 292 + 205 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = statfile1 + caption = 'Set Tab Order' + oneventloopstart = formonloaded + onclosequery = formonclosequery + onmouseevent = formmouseevent + moduleclassname = 'tmseform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 29 + bounds_cx = 290 + bounds_cy = 150 + bounds_cymin = 100 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_focuscellonenter, og_colchangeontabkey, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 32 + numstep = 1 + options = [fco_mousefocus] + end> + datacols.count = 2 + datacols.items = < + item[wname] + colorselect = -1879048185 + width = 201 + options = [co_readonly, co_focusselect, co_fill, co_savevalue, co_savestate] + widgetname = 'wname' + dataclass = tgridmsestringdatalist + end + item[windex] + options = [co_invisible, co_savevalue, co_savestate] + widgetname = 'windex' + dataclass = tgridintegerdatalist + end> + datarowheight = 18 + onrowsmoved = gridonrowsmoved + oncellevent = gridoncellevent + reffontheight = 16 + object wname: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 201 + bounds_cy = 18 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 16 + end + object windex: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 2 + visible = False + bounds_x = 202 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 18 + optionsedit1 = [oe1_savevalue] + reffontheight = 16 + end + end + object ok: tbutton + taborder = 4 + bounds_x = 37 + bounds_y = 183 + bounds_cx = 47 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 5 + bounds_x = 92 + bounds_y = 183 + bounds_cx = 47 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object mousetaborder: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 3 + bounds_y = 4 + bounds_cx = 60 + onsetvalue = mousetaborderonsetvalue + reffontheight = 16 + end + object start: tbutton + taborder = 2 + bounds_x = 69 + bounds_y = 4 + bounds_cx = 50 + bounds_cy = 20 + state = [as_localcaption, as_localonexecute] + caption = '&Start' + onexecute = startexecute + end + object stop: tbutton + taborder = 3 + bounds_x = 125 + bounds_y = 4 + bounds_cx = 48 + bounds_cy = 20 + state = [as_disabled, as_localdisabled, as_localcaption, as_localonexecute] + caption = 'St&op' + onexecute = stopexecute + end + object tlabel1: tlabel + taborder = 6 + bounds_x = 176 + bounds_y = 5 + bounds_cx = 63 + bounds_cy = 16 + caption = 'Mouse click' + reffontheight = 16 + end + object statfile1: tstatfile + filename = 'settaborderfo.sta' + options = [sfo_memory] + left = 80 + top = 8 + end +end diff --git a/mseide-msegui/apps/ide/settaborderform.pas b/mseide-msegui/apps/ide/settaborderform.pas new file mode 100644 index 0000000..24698f4 --- /dev/null +++ b/mseide-msegui/apps/ide/settaborderform.pas @@ -0,0 +1,259 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit settaborderform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msetypes,mseforms,msegrids,msegui,msewidgetgrid,msedataedits,msesimplewidgets, + msedesigner, + mseevent,mseglob,mseguiglob,msestat,msestatfile,msegridsglob,msestrings; + +type + + tsettaborderfo = class(tmseform) + grid: twidgetgrid; + ok: tbutton; + cancel: tbutton; + start: tbutton; + stop: tbutton; + mousetaborder: tintegeredit; + statfile1: tstatfile; + tlabel1: tlabel; + windex: tintegeredit; + wname: tstringedit; + procedure formmouseevent(const sender: twidget; var info: mouseeventinfoty); + procedure formonclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure formonloaded(const sender: TObject); + procedure gridoncellevent(const sender: TObject; var info: celleventinfoty); + procedure mousetaborderonsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); + procedure startexecute(const sender: TObject); + procedure stopexecute(const sender: TObject); + procedure gridonrowsmoved(const sender: tcustomgrid; const fromindex: Integer; + const toindex: Integer; const acount: Integer); + private + fwidget: twidget; + fparent: twidget; + fchildren: widgetarty; + fdesigner: tdesigner; + fwidgetorder: boolean; //set Z-order instead of taborder + public + constructor create(awidget: twidget; adesigner: tdesigner; + const awidgetorder: boolean); + end; + +procedure settaborderdialog(const awidget: twidget; + const awidgetorder: boolean); + +implementation +uses + settaborderform_mfm,msegraphutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + +procedure settaborderdialog(const awidget: twidget; + const awidgetorder: boolean); +var + fo: tsettaborderfo; +begin + fo:= tsettaborderfo.create(awidget,designer,awidgetorder); + try + fo.show(true); + finally + fo.Free; + end; +end; + + {tsettaborderfo} + +constructor tsettaborderfo.create(awidget: twidget; adesigner: tdesigner; + const awidgetorder: boolean); +begin + fwidget:= awidget; + fparent:= awidget.parentwidget; + fdesigner:= adesigner; + fwidgetorder:= awidgetorder; + inherited create(nil); + if fwidgetorder then begin + caption:= 'Set Widget Order'; + end; +end; + +procedure tsettaborderfo.formmouseevent(const sender: twidget; var info: mouseeventinfoty); +var + widget1: twidget; + int1,int2: integer; +begin + with info do begin + if (eventkind = ek_buttonpress) then begin + if stop.enabled and pointinrect(pos,paintrect) then begin +// stopexecute(nil); + end + else begin + if stop.enabled and (button = mb_left) and + (shiftstate * keyshiftstatesmask = []) then begin + widget1:= fparent.childatpos(translatewidgetpoint(pos,self,fparent),false); + if widget1 <> nil then begin + int2:= -1; + for int1:= 0 to high(fchildren) do begin + if widget1 = fchildren[int1] then begin + int2:= int1; + break; + end; + end; + if int2 >= 0 then begin + for int1:= 0 to high(fchildren) do begin + if windex[int1] = int2 then begin + grid.moverow(int1,mousetaborder.value); + break; + end; + end; + if mousetaborder.value = high(fchildren) then begin + stopexecute(nil); + end + else begin + mousetaborder.value:= mousetaborder.value + 1; + end; + grid.row:= mousetaborder.value; + end; + end; + end; + end; + end; + end; +end; + +procedure tsettaborderfo.formonclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); +var + i1: integer; + ar1: widgetarty; +begin + if amodalresult = mr_ok then begin + if fwidgetorder then begin + setlength(ar1,grid.rowcount); + for i1:= 0 to grid.rowcount - 1 do begin + ar1[i1]:= fchildren[windex[i1]]; + end; + with twidget1(fparent.container) do begin + fwidgets:= ar1; + widgetregionchanged(nil); + end; + end + else begin + for i1:= 0 to grid.rowcount - 1 do begin + fchildren[windex[i1]].taborder:= i1; + end; + for i1:= 0 to high(fchildren) do begin + fdesigner.componentmodified(fchildren[i1]); + end; + end; + end; +end; + +procedure tsettaborderfo.formonloaded(const sender: TObject); +var + int1: integer; +begin + if fwidgetorder then begin + fchildren:= twidget1(fparent.container).fwidgets; + end + else begin + fchildren:= fparent.container.gettaborderedwidgets; + end; + grid.rowcount:= length(fchildren); + for int1:= 0 to high(fchildren) do begin + wname[int1]:= msestring(fchildren[int1].Name); + windex[int1]:= int1; + if wname[int1] = msestring(fwidget.name) then begin + grid.row:= int1; + end; + end; + mousetaborder.valuemax:= high(fchildren); +end; + + +procedure tsettaborderfo.stopexecute(const sender: TObject); +begin + start.enabled:= true; + if stop.focused then begin + start.setfocus; + end; + stop.enabled:= false; + window.releasemouse; +end; + +procedure tsettaborderfo.gridoncellevent(const sender: TObject; + var info: celleventinfoty); +var + w1: twidget; +begin + if info.eventkind = cek_enter then begin + mousetaborder.value:= info.newcell.row; + end + else begin + if start.enabled and iscellclick(info,[ccr_dblclick,ccr_nokeyreturn]) then begin + w1:= fchildren[windex[info.cell.row]]; + if w1.childrencount > 0 then begin + settaborderdialog(w1[0],fwidgetorder); + end; + end; + end; +end; + +procedure tsettaborderfo.gridonrowsmoved(const sender: tcustomgrid; + const fromindex: Integer; const toindex: Integer; const acount: Integer); +begin + mousetaborder.value:= toindex; +end; + +procedure tsettaborderfo.mousetaborderonsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); +begin + grid.row:= avalue; +end; + +procedure tsettaborderfo.startexecute(const sender: TObject); +begin + stop.enabled:= true; + if start.focused then begin + stop.setfocus; + end; + start.enabled:= false; + window.capturemouse; +// capturemouse(true); +end; + +end. diff --git a/mseide-msegui/apps/ide/settaborderform_mfm.pas b/mseide-msegui/apps/ide/settaborderform_mfm.pas new file mode 100644 index 0000000..64c63d8 --- /dev/null +++ b/mseide-msegui/apps/ide/settaborderform_mfm.pas @@ -0,0 +1,193 @@ +unit settaborderform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,settaborderform; + +const + objdata: record size: integer; data: array[0..3519] of byte end = + (size: 3520; data: ( + 84,80,70,48,14,116,115,101,116,116,97,98,111,114,100,101,114,102,111,13, + 115,101,116,116,97,98,111,114,100,101,114,102,111,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116, + 111,110,0,8,98,111,117,110,100,115,95,120,3,215,1,8,98,111,117,110, + 100,115,95,121,3,146,1,9,98,111,117,110,100,115,95,99,120,3,36,1, + 9,98,111,117,110,100,115,95,99,121,3,205,0,23,99,111,110,116,97,105, + 110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111, + 119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116, + 114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,36,1,3,205,0,0,7,111,112, + 116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99, + 15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95, + 97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118, + 101,112,111,115,0,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116, + 102,105,108,101,49,7,99,97,112,116,105,111,110,6,13,83,101,116,32,84, + 97,98,32,79,114,100,101,114,16,111,110,101,118,101,110,116,108,111,111,112, + 115,116,97,114,116,7,12,102,111,114,109,111,110,108,111,97,100,101,100,12, + 111,110,99,108,111,115,101,113,117,101,114,121,7,16,102,111,114,109,111,110, + 99,108,111,115,101,113,117,101,114,121,12,111,110,109,111,117,115,101,101,118, + 101,110,116,7,14,102,111,114,109,109,111,117,115,101,101,118,101,110,116,15, + 109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115, + 101,102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103, + 114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111,99,117,115, + 98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115,101,119,104, + 101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,29,9,98,111,117,110,100,115,95,99,120,3,34,1,9,98,111,117, + 110,100,115,95,99,121,3,150,0,12,98,111,117,110,100,115,95,99,121,109, + 105,110,2,100,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110, + 95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100, + 11,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101, + 121,114,111,119,109,111,118,105,110,103,19,111,103,95,102,111,99,117,115,99, + 101,108,108,111,110,101,110,116,101,114,20,111,103,95,99,111,108,99,104,97, + 110,103,101,111,110,116,97,98,107,101,121,12,111,103,95,97,117,116,111,112, + 111,112,117,112,0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2, + 1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105, + 100,116,104,2,32,7,110,117,109,115,116,101,112,2,1,7,111,112,116,105, + 111,110,115,11,14,102,99,111,95,109,111,117,115,101,102,111,99,117,115,0, + 0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,14, + 100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,5,119,110,97, + 109,101,1,11,99,111,108,111,114,115,101,108,101,99,116,4,7,0,0,144, + 5,119,105,100,116,104,3,201,0,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118, + 101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,0, + 10,119,105,100,103,101,116,110,97,109,101,6,5,119,110,97,109,101,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,7,6,119,105,110,100,101, + 120,1,7,111,112,116,105,111,110,115,11,12,99,111,95,105,110,118,105,115, + 105,98,108,101,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110,97, + 109,101,6,6,119,105,110,100,101,120,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,18, + 11,111,110,114,111,119,115,109,111,118,101,100,7,15,103,114,105,100,111,110, + 114,111,119,115,109,111,118,101,100,11,111,110,99,101,108,108,101,118,101,110, + 116,7,15,103,114,105,100,111,110,99,101,108,108,101,118,101,110,116,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,11,116,115,116,114, + 105,110,103,101,100,105,116,5,119,110,97,109,101,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 5,99,111,108,111,114,4,7,0,0,144,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,2,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,201,0,9,98,111,117,110,100,115,95,99,121, + 2,18,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49, + 95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,6,119,105,110,100,101,120,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102, + 111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,202,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 50,9,98,111,117,110,100,115,95,99,121,2,18,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98,111,114,100,101, + 114,2,4,8,98,111,117,110,100,115,95,120,2,37,8,98,111,117,110,100, + 115,95,121,3,183,0,9,98,111,117,110,100,115,95,99,120,2,47,9,98, + 111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,5,115, + 116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95, + 108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,2,79, + 75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107, + 0,0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108,8,116,97, + 98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,92,8, + 98,111,117,110,100,115,95,121,3,183,0,9,98,111,117,110,100,115,95,99, + 120,2,47,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104, + 111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116, + 111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,6,67,97,110, + 99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95, + 99,97,110,99,101,108,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,13,109,111,117,115,101,116,97,98,111,114,100,101,114,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,3,8,98,111,117,110,100,115,95,121,2, + 4,9,98,111,117,110,100,115,95,99,120,2,60,10,111,110,115,101,116,118, + 97,108,117,101,7,23,109,111,117,115,101,116,97,98,111,114,100,101,114,111, + 110,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,7,116,98,117,116,116,111,110,5,115,116,97,114, + 116,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,2,69,8,98,111,117,110,100,115,95,121,2,4,9,98,111,117,110,100, + 115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,99,97,112,116,105,111,110,6,6,38,83,116,97,114,116,9,111,110,101, + 120,101,99,117,116,101,7,12,115,116,97,114,116,101,120,101,99,117,116,101, + 0,0,7,116,98,117,116,116,111,110,4,115,116,111,112,8,116,97,98,111, + 114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,125,8,98,111, + 117,110,100,115,95,121,2,4,9,98,111,117,110,100,115,95,99,120,2,48, + 9,98,111,117,110,100,115,95,99,121,2,20,5,115,116,97,116,101,11,11, + 97,115,95,100,105,115,97,98,108,101,100,16,97,115,95,108,111,99,97,108, + 100,105,115,97,98,108,101,100,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117, + 116,101,0,7,99,97,112,116,105,111,110,6,5,83,116,38,111,112,9,111, + 110,101,120,101,99,117,116,101,7,11,115,116,111,112,101,120,101,99,117,116, + 101,0,0,6,116,108,97,98,101,108,7,116,108,97,98,101,108,49,8,116, + 97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,176, + 0,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95, + 99,120,2,63,9,98,111,117,110,100,115,95,99,121,2,16,7,99,97,112, + 116,105,111,110,6,11,77,111,117,115,101,32,99,108,105,99,107,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,9,116,115,116,97, + 116,102,105,108,101,9,115,116,97,116,102,105,108,101,49,8,102,105,108,101, + 110,97,109,101,6,17,115,101,116,116,97,98,111,114,100,101,114,102,111,46, + 115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109, + 111,114,121,0,4,108,101,102,116,2,80,3,116,111,112,2,8,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsettaborderfo,''); +end. diff --git a/mseide-msegui/apps/ide/skeletons.pas b/mseide-msegui/apps/ide/skeletons.pas new file mode 100644 index 0000000..5aae1f4 --- /dev/null +++ b/mseide-msegui/apps/ide/skeletons.pas @@ -0,0 +1,84 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit skeletons; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msestream,mseclasses; + +procedure programskeleton(const stream: ttextstream; const name: string); +procedure unitskeleton(const stream: ttextstream; const name: string); +procedure formskeleton(const stream: ttextstream; const unitname,formname,ancestor: string); + +implementation +const + defaults = compilerdefaults; + +procedure programskeleton(const stream: ttextstream; const name: string); +begin + with stream do begin + writeln('program '+name+';'); + writeln(defaults); + writeln('{$ifdef FPC}'); + writeln(' {$ifdef mswindows}{$apptype gui}{$endif}'); + writeln('{$endif}'); + + writeln('uses'); + writeln( +' {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui,mseforms,main;'); + writeln('begin'); + writeln(' application.createform(tmainfo,mainfo);'); + writeln(' application.run;'); + writeln('end.'); + end; +end; + +procedure unitskeleton(const stream: ttextstream; const name: string); +begin + with stream do begin + writeln('unit '+name+';'); + writeln(defaults); + writeln('interface'); + writeln('implementation'); + writeln('end.'); + end; +end; + +procedure formskeleton(const stream: ttextstream; const unitname,formname,ancestor: string); +begin + with stream do begin + writeln('unit '+unitname+';'); + writeln(defaults); + writeln('interface'); + writeln('uses'); + writeln(' msegui,mseclasses,mseforms,msedatamodules;'); + writeln(''); + writeln('type'); + writeln(' t'+formname+' = class('+ancestor+')'); + writeln(' end;'); + writeln('var'); + writeln(' '+formname+': '+'t'+formname+';'); + writeln('implementation'); + writeln('uses'); + writeln(' '+unitname+'_mfm;'); + writeln('end.'); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/sourceform.mfm b/mseide-msegui/apps/ide/sourceform.mfm new file mode 100644 index 0000000..ca3a70a --- /dev/null +++ b/mseide-msegui/apps/ide/sourceform.mfm @@ -0,0 +1,568 @@ +object sourcefo: tsourcefo + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + onenter = enterexe + onactivate = enterexe + visible = False + bounds_x = 98 + bounds_y = 158 + bounds_cx = 433 + bounds_cy = 327 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.frame.sbhorz.options = [sbo_moveauto, sbo_showauto] + container.frame.sbvert.options = [sbo_moveauto, sbo_showauto] + container.bounds = ( + 0 + 0 + 423 + 327 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Source' + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = '' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 00000000020000001800000018000000F4060000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D0198888880D82888801 + 88888801D0D0D00988888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01 + C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE017F878701 + 9FC5C80188888801D0D0D00888888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01 + BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01 + 83898A01C6F9FF019EC5C80188888801D0D0D00788888801B3F8FE01B6F8FE01 + B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01 + D2FEFE01D5FEFE01858A8A01E2FCFF01C5F9FF019EC5C80188888801D0D0D006 + 88888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01 + C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE0182898A01FEFEFF01E1FCFF01 + C3F9FF019EC5C80188888801D0D0D00588888801B3F8FE01B6F8FE01B8F7FC01 + 5B797B01BFFAFE0182A8AA01C1F4F701C7F9FB01C4F3F401CDFAFB018EABAB01 + D5FEFE017F898A01DFFCFF01FCFEFF01DFFCFF01C2F9FF019DC4C80188888801 + D0D0D00488888801B3F8FE01B6F8FE0188B7BA016687890197C5C80159737501 + 6F8D8E017592930190B3B3017A95950160747401D5FEFE017C898A01BEF9FF01 + E1FCFF01FAFEFF01DDFCFF01C0F9FF019DC4C80188888801D0D0D00388888801 + B3F8FE01B6F8FE016E949701A4DBDE016D8F91015B7678017C9D9F0180A0A101 + 86A6A6017D99990162777701D5FEFE0179898A019EF6FF01C0F9FF01E3FCFF01 + F9FEFF01DCFBFF01BEF9FF019DC4C80188888801D0D0D00288888801B3F8FE01 + B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01 + CFFDFE01D2FEFE01D5FEFE018296970178898A017A898A017C898A017E898A02 + 7A898A017786870181888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01 + BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01C6F5F601CEFCFD01CCF7F701 + D0F8F801CCFAFB01BBF6F801B0FAFE019CEFF50193F6FE0184F4FE0175F3FE01 + 66F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01 + BFFAFE01C2FBFE01C6FBFE01C3F4F601576C6D01728C8C01748C8C019DBBBB01 + 7E9B9B016A8C8D016A979901476C6F0185DFE60184F4FE0175F3FE0166F1FE01 + 88888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01 + C2FBFE01C6FBFE01C4F6F8016A84840192B3B3017E98980193AFAF017E9B9B01 + 6788890174A5A701619598018BE8F00184F4FE0175F3FE0166F1FE0188888801 + D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01 + C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01CEFDFE01BFFCFE01 + B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE0188888801D0D0D002 + 88888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01 + C9FCFE01C3F2F30193B4B401CDF8F801CEF6F601CAF8F901B8F3F501AAF1F501 + 9FF3F9018EEEF60183F3FD0175F3FE0166F1FE0188888801D0D0D00288888801 + B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01BCECEE01 + 759191016F888801778F8F0164787801748E8E0181AAAB0177A9AB015D8E9101 + 3F696D014783880175F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01 + B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01BEEEF001738F8F01 + 748E8E01839E9E0163777701809E9E01A0D2D40177AAAC015D8E91014D808401 + 5CA9B00175F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01 + B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01 + 96B5B50189A3A301CEFDFE01ADE4E60177A9AB017EC2C60193F6FE0184F4FE01 + 75F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01 + B5F1F501A3D6D901C2FBFE01A7D4D60188AAAB01B5E0E101A1C4C501C1E9E901 + D5FEFE01CEFDFE01BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE01 + 66F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE016E949701516C6E01 + 74989A017EA2A401789899017D9C9D015B71720194B5B501BDE5E501D5FEFE01 + CEFDFE01BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE01 + 88888801D0D0D00288888801B3F8FE01B6F8FE0178A2A50171969801799EA001 + 82A8AA0178999A017D9C9D017D9B9B017F9C9C01BDE5E501D5FEFE01CEFDFE01 + BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE0188888801 + D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01 + C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01CEFDFE01BFFCFE01 + B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE0188888801D0D0D002 + 88888816D0D0D01900000008FEFF0008FEFF01BFFEFF0308FEFF0700FEFF0F08 + FEFF1F02FEFF3FC0FEFF7F00FEFF7F08FEFF7F00FEFF7F08FEFF7F08FEFF7F08 + FEFF7FBFFEFF7F08FEFF7F00FEFF7F02FEFF7F08FEFF7F00FEFF7F00FEFF7FBF + FEFF7F0000000008 + } + onclosequery = sourcefoonclosequery + onidle = formonidle + moduleclassname = 'tdockform' + object tabwidget: ttabwidget + bounds_x = 0 + bounds_y = 0 + bounds_cx = 423 + bounds_cy = 327 + anchors = [] + popupmenu = formpopup + onactivepagechanged = tabwidgetonactivepagechanged + onpageremoved = tabwidgetpageremoved + tab_options = [tabo_dragsource, tabo_dragdest, tabo_vertical, tabo_opposite, tabo_tabsizing, tabo_dblclickedtabfirst, tabo_hintclippedtext] + tab_frame.buttonpos = sbp_top + tab_frame.buttonslast = True + tab_frame.buttonsvisible = [sk_right, sk_up, sk_left, sk_down, sk_first, sk_last] + tab_frame.localprops = [frl_optionsskin] + tab_frame.localprops1 = [] + tab_textflags = [tf_ycentered] + tab_sizemin = 60 + tab_size = 60 + tab_optionswidget1 = [] + object tstockglyphbutton1: tstockglyphbutton + optionswidget = [ow_destroywidgets, ow_disabledhint, ow_timedhint] + taborder = 2 + hint = 'Step back in code navigation' + onshowhint = stephintev + bounds_x = 383 + bounds_y = 0 + bounds_cx = 20 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localimagelist, as_localimagenr, as_localcolorglyph, as_localhint, as_localonexecute] + glyph = stg_arrowleft + action = navigbackact + colorglyph = -1610612727 + onexecute = navigback + end + object tstockglyphbutton2: tstockglyphbutton + optionswidget = [ow_destroywidgets, ow_disabledhint, ow_timedhint] + taborder = 1 + hint = 'Step forward in code navigation' + onshowhint = stephintev + bounds_x = 403 + bounds_y = 0 + bounds_cx = 20 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localimagelist, as_localimagenr, as_localcolorglyph, as_localhint] + glyph = stg_arrowright + action = navigforwardact + colorglyph = -1610612727 + end + end + object syntaxpainter: tsyntaxpainter + defdefs.data = ( + ( + '*.pas' + 'pas.sdef' + ) + ) + left = 32 + top = 64 + end + object imagelist: timagelist + count = 14 + left = 33 + top = 93 + image = { + 00000000020000004000000040000000B80B0000000000000000000000000000 + 0000000000000000000000000000000000000000FFFFFFAA00000001FFFFFF3E + 00000003FFFFFF1D0000FF03FFFFFF0D0000FF03FFFFFF0D00000003FFFFFF1C + 0000FF05FFFFFF0B0000FF01FFFFFF030000FF01FFFFFF0C00000003FFFFFF07 + FF000002FFFFFF120000FF07FFFFFF090000FF01FFFFFF050000FF01FFFFFF0B + 00000003FFFFFF06FF000001FFFF0001FF000002FFFFFF110000FF07FFFFFF09 + 0000FF01FFFFFF050000FF01FFFFFF0B00000003FFFFFF06FF000004FFFFFF11 + 0000FF07FFFFFF090000FF01FFFFFF050000FF01FFFFFF0B00000003FFFFFF07 + FF000002FFFFFF130000FF05FFFFFF0B0000FF01FFFFFF030000FF01FFFFFF0D + 00000001FFFFFF1E0000FF03FFFFFF0D0000FF03FFFFFF4E00000001FFFFFF3E + 00000003FFFFFF3E00000001FFFFFF9A00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00C50001003500010020000100350001 + 00C50001FFFFFF0B00C400010008000100D90003FFFFFF0B003E000100120001 + 001E00010031000100B00001FFFFFF0B009000010036000100220001001F0001 + 00970001FFFFFF0B005800010080000100D900010085000100590001FFFFFF0B + 001600010007000100D90003FFFFFF0B0036000100C1000100D9000100A20001 + 00260001FFFFFF0B00D9000300B6000100140001FFFFFF0B001F000100C80001 + 00D9000100CC000100200001FFFFFF0B00D90001000D000100D90003FFFFFF0B + 00D9000300D60001000E0001FFFFFF0B00D9000200D600010084000100440001 + FFFFFF0B000C000100D90003000F0001FFFFFF0B00D90001000D000100D90003 + FFFFFF0B00D9000300970001003B0001FFFFFF0B00D9000200180001003D0001 + 00C30001FFFFFF0B000C000100D90003000E0001FFFFFF0B00D90001000D0001 + 00D90003FFFFFF0B00D9000200B90001001B000100AE0001FFFFFF0B00D90002 + 00D700010084000100310001FFFFFF0B001F000100CB000100D9000100CC0001 + 001F0001FFFFFF0B00D90001000D000100D90003FFFFFF0B00D9000100A80001 + 0021000100A2000100D90001FFFFFF0B00D9000300D80001000E0001FFFFFF0B + 005800010084000100D900010086000100590001FFFFFF0B00D90001000D0001 + 00D90003FFFFFF0B00800001002C000100BB000100D90002FFFFFF0B00420001 + 00C1000100D900010091000100370001FFFFFF0B00C500010034000100200001 + 0035000100C50001FFFFFF0B002B000100030001002B000200D90001FFFFFF0B + 00000001001A000100210003FFFFFF0B0043000100120001001F000100380001 + 00BE0001FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90002009700010004000100D90001FFFFFF0B00070001 + 002100020027000100D90001FFFFFF0B00D90001007B00010021000200D30001 + FFFFFF0B0021000400030001FFFFFF0B00D9000100BF00010030000100080001 + 00D90001FFFFFF0B0009000100D90004FFFFFF0B009300010035000100CE0001 + 00D90002FFFFFF0B00D9000300B40001002B0001FFFFFF0B00D5000100360001 + 00B100010009000100D90001FFFFFF0B0009000100D90004FFFFFF0B00390001 + 00A9000100D90003FFFFFF0B00D900030049000100920001FFFFFF0B005F0001 + 0081000100D900010009000100D90001FFFFFF0B0009000100200001002C0001 + 00AA000100D90001FFFFFF0B0013000100470001002200010030000100B20001 + FFFFFF0B00D9000200B700010024000100D70001FFFFFF0AB8B8B801004C0001 + 00D900020009000100D90001FFFFFF0B00D5000100D9000100A9000100270001 + 00D90001FFFFFF0B000B000100BF000100D9000100990001002B0001FFFFFF0B + 00D90002004D00010089000100D90001FFFFFF0A95959501001E000100210002 + 0001000100210001F9F9F901FFFFFF0A00D9000200D80001000E000100D90001 + FFFFFF0B001A000100D1000100D9000100D80001000E0001FFFFFF0B00D90001 + 00BA0001001F000100D6000100D90001FFFFFF0B00D900030009000100D90001 + FFFFFF0B008D000100D90001009A00010034000100D90001FFFFFF0B00560001 + 007F000100D90001009D000100370001FFFFFF0B00D900010051000100810001 + 00D90002FFFFFF0B00D900030009000100D90001FFFFFF0B00360001001E0001 + 0024000100B4000100D90001FFFFFF0B00C9000100390001001F000100310001 + 00BC0001FFFFFF0B00BD0001001A000100D3000100D90002FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF1B00FF0005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF1B00FF0005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF1B00FF0005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF1B00FF0005FFFFFF0B00A80001 + 002A0001001F00010025000100A10001FFFFFF0B00BC000100320001001F0001 + 003C000100C80001FFFFFF0CE8F8E8013EC53E0126BD26013EC53E01E8F8E801 + FFFFFF0A00E80001003E000100260001003E000100E80001FFFFFF0B001E0001 + 00B4000100D9000100AE0001001A0001FFFFFF0B003600010097000100D90001 + 0082000100540001FFFFFF0C67D1670196DF9601FFFFFF019CE19C0169D26901 + FFFFFF0A006700010096000100FF0001009C000100690001FFFFFF0B001F0001 + 00AE000100D9000100CB000100210001FFFFFF0B000B000100D6000100D90001 + 00D20001001A0001FFFFFF0C25BD2501EBF9EB01FFFFFF01F0FAF00126BD2601 + FFFFFF0A0025000100EB000100FF000100F0000100260001FFFFFF0B009C0001 + 0005000100420001003A000100940001FFFFFF0B002A00010097000100D90001 + 00C30001000E0001FFFFFF0C0EB60E01FFFFFF0312B71201FFFFFF0A000E0001 + 00FF000300120001FFFFFF0B005600010093000100AD000100450001004D0001 + FFFFFF0B00B2000100310001002300010049000100150001FFFFFF0C0EB60E01 + FFFFFF0311B71101FFFFFF0A000E000100FF000300110001FFFFFF0B000E0001 + 00D6000100D9000100D30001000B0001FFFFFF0B00D9000300AD0001003D0001 + FFFFFF0C24BD2401EFFAEF01FFFFFF01F0FAF00125BD2501FFFFFF0A00240001 + 00EF000100FF000100F0000100250001FFFFFF0B002700010093000100D90001 + 00A6000100280001FFFFFF0B00D9000200D000010039000100940001FFFFFF0C + 67D167019BE19B01FFFFFF019EE29E0168D16801FFFFFF0A00670001009B0001 + 00FF0001009E000100680001FFFFFF0B00AE000100290001001C0001002E0001 + 00B30001FFFFFF0B00D6000100220002007D000100D90001FFFFFF0CE7F8E701 + 3DC43D0126BD26013EC53E01E8F8E801FFFFFF0A00E70001003D000100260001 + 003E000100E80001FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF1B00FF0005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF1B00FF0005FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF1B00FF0005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF1B00FF0005FFFFFF060000000000000000000000000000000000000000 + 0004000000000000000E0000000E000E000E0000001F0011000E1800803F8020 + 000E3C00803F8020000E3C00803F8020000E1800001F001100040000000E000E + 00000000000000000004000000000000000E0000000000000004000000000000 + 000000000000000000000000E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003F003E003E003E003F007E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E0030000E003E003E0030000E003E003E003 + 0000E003E003E0030000E003E003E003C007E003E003E003C006E003E003E003 + C006E003E003E0034004E003E003E0034004E003E003E003C006E003E003E003 + C006E003E003E003C007E003E003E0030000E003E003E0030000E003E003E003 + 0000E003E003E0030000E003 + } + end + object filechangenotifyer: tfilechangenotifyer + onfilechanged = onfilechanged + left = 32 + top = 168 + end + object navigforwardact: taction + state = [as_disabled] + onexecute = navigforward + left = 32 + top = 16 + sc = ( + 1 + 24648 + ) + end + object navigbackact: taction + state = [as_disabled] + onexecute = navigback + left = 32 + top = 40 + sc = ( + 1 + 16456 + ) + end + object formpopup: tpopupmenu + onupdate = popupmonupdate + menu.submenu.count = 30 + menu.submenu.items = < + item + action = actionsmo.selecteditpage + caption = 'Select Page' + state = [as_localcaption, as_localonexecute] + onexecute = doselectpage + end + item + action = actionsmo.opensource + caption = '&Open File' + state = [as_localcaption] + end + item + action = actionsmo.close + caption = '&Close File' + state = [as_localcaption] + options = [mao_shortcutcaption, mao_asyncexecute] + end + item + action = actionsmo.save + caption = '&Save File' + state = [as_localcaption] + end + item + action = actionsmo.saveas + end + item + caption = 'Show as Form' + name = 'showasform' + state = [as_localcaption, as_localonexecute] + onexecute = showasformexe + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.delete + end + item + action = actionsmo.cut + end + item + action = actionsmo.copy + end + item + action = actionsmo.copylatexact + end + item + action = actionsmo.paste + end + item + action = actionsmo.selectall + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.undo + end + item + action = actionsmo.redo + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + submenu.count = 8 + submenu.items = < + item + action = actionsmo.indent + end + item + action = actionsmo.unindent + end + item + action = actionsmo.comment + end + item + action = actionsmo.uncomment + end + item + action = actionsmo.lowercase + end + item + action = actionsmo.uppercase + end + item + action = actionsmo.tabtospace + end + item + caption = 'Convert to &Pascal string' + name = 'convpas' + state = [as_localcaption, as_localonexecute] + onexecute = convpasex + end> + caption = '&Modify Selection' + name = 'modifyselection' + state = [as_localcaption] + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.togglebkpt + end + item + action = actionsmo.togglebkptenable + end + item + caption = '&Edit breakpoint' + name = 'editbreakpoint' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = editbreakpointexec + end + item + caption = 'Add &Watch at Cursor' + name = 'addwatch' + state = [as_localcaption, as_localonexecute] + onexecute = addwatchactonexecute + end + item + submenu.count = 11 + submenu.items = < + item + action = actionsmo.setbm0 + end + item + action = actionsmo.setbm1 + end + item + action = actionsmo.setbm2 + end + item + action = actionsmo.setbm3 + end + item + action = actionsmo.setbm4 + end + item + action = actionsmo.setbm5 + end + item + action = actionsmo.setbm6 + end + item + action = actionsmo.setbm7 + end + item + action = actionsmo.setbm8 + end + item + action = actionsmo.setbm9 + end + item + action = actionsmo.setbmnone + end> + caption = 'Set Bookmark' + name = 'setbm' + state = [as_localcaption] + end + item + submenu.count = 10 + submenu.items = < + item + action = actionsmo.findbm0 + end + item + action = actionsmo.findbm1 + end + item + action = actionsmo.findbm2 + end + item + action = actionsmo.findbm3 + end + item + action = actionsmo.findbm4 + end + item + action = actionsmo.findbm5 + end + item + action = actionsmo.findbm6 + end + item + action = actionsmo.findbm7 + end + item + action = actionsmo.findbm8 + end + item + action = actionsmo.findbm9 + end> + caption = 'Find Bookmark' + state = [as_localcaption] + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Insert GUID' + name = 'insgui' + state = [as_localcaption, as_localonexecute] + onexecute = insguiexec + end + item + caption = 'Insert UID' + name = 'insuid' + state = [as_localcaption, as_localonexecute] + onexecute = insuidexec + end + item + action = actionsmo.instemplate + caption = 'Insert Template' + name = 'instempl' + state = [as_localcaption] + end + item + action = completeclassact + caption = 'Complete Class at Cursor' + state = [as_localcaption] + end> + left = 176 + top = 40 + end + object completeclassact: taction + caption = 'Complete class at cursor' + onexecute = completeclassexecute + left = 32 + top = 208 + sc = ( + 1 + 24641 + ) + end + object c: tstringcontainer + strings.data = ( + 'File "' + '" has changed.' + 'There are modifications in edit buffer also.' + 'Do you wish to reload from disk?' + 'Confirmation' + '' + 'Do you wish to replace:' + 'with:' + '' + 'Syntaxdeffile:' + 'Text' + 'not found.' + 'Restart from begin of file?' + 'Cancel?' + 'Do you wish to to replace this occurence?' + 'Go to line number:' + 'Find line' + 'There are modifications in edit buffer also.' + 'Restart from end of file?' + ) + left = 176 + top = 104 + end +end diff --git a/mseide-msegui/apps/ide/sourceform.pas b/mseide-msegui/apps/ide/sourceform.pas new file mode 100644 index 0000000..bc9cd19 --- /dev/null +++ b/mseide-msegui/apps/ide/sourceform.pas @@ -0,0 +1,1636 @@ +{ MSEide Copyright (c) 1999-2015 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit sourceform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msetextedit,msewidgetgrid,mseforms,classes,mclasses,msegdbutils, + msegraphedits,mseevent, + msehash,msebitmap,msetabs,sourcepage,mseglob,msetypes,msestrings,mseguiglob, + msegui,msesyntaxpainter,msemenus,mseactions,msesyntaxedit,msestat, + finddialogform,msestream,msefilechange,breakpointsform,mseparser, + msesimplewidgets,msegrids,msegraphutils,mseact,msegridsglob,msestringcontainer; + +type + stringconsts = ( + str_file, //0 File " + haschanged, //1 " has changed. + therearemody, //2 There are modifications in edit buffer also. + wishreload, //3 Do you wish to reload from disk? + confirmation, //4 Confirmation + none, //5 + wishreplace, //6 Do you wish to replace: + str_with, //7 with: + str_new, //8 + syntaxdeffile, //9 Syntaxdeffile: + str_text, //10 Text + str_notfound, //11 not found. + restartbegin, //12 Restart from begin of file? + cancel, //13 Cancel? + replaceoccu, //14 Do you wish to to replace this occurence? + gotoline, //15 Go to line number: + findline, //16 Find line + modieditalso, //17 There are modifications in edit buffer also. + restartend //18 Restart from end of file? + ); + + tsourcefo = class; + + tnaviglist = class(tsourceposlist) + private + fsourcefo: tsourcefo; + findex: integer; + procedure updateshowpos(const acellpos: cellpositionty = cep_rowcenteredif); + public + constructor create; + procedure showsource(const apos: sourceposty; + const asetfocus: boolean = false); + function back: boolean; + function forward: boolean; + end; + + tsourcefo = class(tdockform) + completeclassact: taction; + tpopupmenu1: tpopupmenu; + tabwidget: ttabwidget; + syntaxpainter: tsyntaxpainter; + imagelist: timagelist; + filechangenotifyer: tfilechangenotifyer; + navigforwardact: taction; + navigbackact: taction; + tstockglyphbutton1: tstockglyphbutton; + tstockglyphbutton2: tstockglyphbutton; + c: tstringcontainer; + procedure formonidle(var again: boolean); + procedure doselectpage(const sender: TObject); + + procedure navigback(const sender: TObject); + procedure navigforward(const sender: TObject); + procedure onfilechanged(const sender: tfilechangenotifyer; + const info: filechangeinfoty); + procedure sourcefoonclosequery(const sender: tcustommseform; + var modalresult: modalresultty); + procedure tabwidgetpageremoved(const sender: TObject; const awidget: twidget); + procedure tabwidgetonactivepagechanged(const sender: tobject); + procedure addwatchactonexecute(const sender: tobject); + procedure enterexe(const sender: tobject); + procedure editbreakpointexec(const sender: TObject); + procedure popupmonupdate(const sender: tcustommenu); + procedure completeclassexecute(const sender: TObject); + procedure showasformexe(const sender: TObject); + procedure setbmexec(const sender: TObject); + procedure findbmexec(const sender: TObject); + procedure insguiexec(const sender: TObject); + procedure convpasex(const sender: TObject); + procedure insuidexec(const sender: TObject); + procedure stephintev(const sender: TObject; var info: hintinfoty); + private + fasking: boolean; + fgdbpage: tsourcepage; + ffileloading: boolean; + ffiletag: longword; + fnaviglist: tnaviglist; + fsourcehintwidget: twidget; + feditposar: gridcoordarty; + factbookmark: integer; + fbookmarkar: array of bookmarkarty; + fpagedestroying: integer; + popuprow: integer; + fallsaved: boolean; + flayoutstream: ttextstream; + function geteditpositem(const index: integer): msestring; + procedure seteditposcount(const count: integer); + procedure seteditpositem(const index: integer; const avalue: msestring); + function getbookmarkitem(const index: integer): msestring; + procedure setbookmarkcount(const count: integer); + procedure setbookmarkitem(const index: integer; const avalue: msestring); + function getitems(const index: integer): tsourcepage; + function createnewpage(const afilename: filenamety): tsourcepage; + function getsourcepos: sourceposty; + procedure setsourcehintwidget(const avalue: twidget); + public + hintsize: sizety; + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure updatestat(const statfiler: tstatfiler); + + function hidesourcehint: boolean; //false if no action; + procedure updatebreakpointicon(const path: filenamety; + const info: bkptlineinfoty); + procedure textmodified(const sender: tsourcepage); + function openfile(const filename: filenamety; + aactivate: boolean = false): tsourcepage; //nil if not ok + function showsourceline(const filename: filenamety; + line: integer; col: integer = 0; asetfocus: boolean = false; + const aposition: cellpositionty = cep_rowcentered): tsourcepage; + function showsourcepos(const apos: sourceposty; + asetfocus: boolean = false; + const aposition: cellpositionty = cep_top): tsourcepage; + procedure resetactiverow; + function locate(const info: stopinfoty): tsourcepage; + function count: integer; + function activepage: tsourcepage; + function currentselection: msestring; + function currentfilename: filenamety; + function currentwordatcursor: msestring; + procedure updatecaption; + function newpage: tsourcepage; + function findsourcepage(afilename: filenamety; wholepath: boolean = true; + onlyifloaded: boolean = false): tsourcepage; + procedure saveactivepage(const newname: filenamety = ''); + function saveall(noconfirm: boolean): modalresultty; //false if canceled + procedure savecanceled; //resets fallsaved + property allsaved: boolean read fallsaved; + function closeactivepage: boolean; + function closepage(const apage: tsourcepage; + noclosecheck: boolean = false): boolean; overload; + function closepage(const aname: filenamety): boolean; overload; + function closeall(const nosave: boolean): boolean; //false on cancel + function gdbpage: tsourcepage; + function modified: boolean; + function newfiletag: longword; + property items[const index: integer]: tsourcepage read getitems; default; + property naviglist: tnaviglist read fnaviglist; + function findbookmark(const bookmarknum: integer): boolean; + //true if found + procedure setbookmark(const apage: tsourcepage; const arow: integer; + const bookmarknum: integer); + + function gettextstream(const filename: filenamety; + forwrite: boolean): ttextstream; + function getfiletext(const filename: filenamety; + const startpos,endpos: gridcoordty): msestring; + procedure replacefiletext(const filename: filenamety; + const startpos,endpos: gridcoordty; const newtext: msestring); + property sourcepos: sourceposty read getsourcepos; + property sourcehintwidget: twidget read fsourcehintwidget + write setsourcehintwidget; + end; + + errorlevelty = (el_none,el_all,el_hint,el_note,el_warning,el_error); + +var + sourcefo: tsourcefo; + +function checkerrormessage(const text: msestring; out alevel: errorlevelty; + out afilename: filenamety; out col,row: integer): boolean; +function locateerrormessage(const text: msestring; var apage: tsourcepage; + minlevel: errorlevelty = el_all): boolean; + //true if valid errormessage + +implementation +uses + sourceform_mfm,msefileutils,sysutils,mseformatstr, + projectoptionsform,main,mseeditglob,watchform,msesys,msewidgets,msedesigner, + selecteditpageform,sourceupdate,pascaldesignparser,mseclasses,msearrayutils, + msebits,msesysutils,mseintegerenter,panelform; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsourcepage1 = class(tsourcepage); + +function checkerrormessage(const text: msestring; out alevel: errorlevelty; + out afilename: filenamety; out col,row: integer): boolean; +var + ar1,ar2,ar3: msestringarty; + int1: integer; +begin + result:= false; + col:= 0; + row:= 0; + alevel:= el_none; + splitstring(text,ar1,msechar('(')); + if length(ar1) > 1 then begin //try FPC + splitstring(ar1[1],ar2,msechar(')')); + if length(ar2) > 1 then begin + splitstring(ar2[0],ar3,msechar(',')); + if (high(ar3) >= 0) then begin + if msestartsstr(' Error:',ar2[1]) or + msestartsstr(' Fatal:',ar2[1]) then begin + alevel:= el_error; + end + else begin + if msestartsstr(' Warning:',ar2[1]) then begin + alevel:= el_warning; + end + else begin + if msestartsstr(' Note:',ar2[1]) then begin + alevel:= el_note; + end + else begin + if msestartsstr(' Hint:',ar2[1]) then begin + alevel:= el_hint; + end; + end; + end; + end; + if trystrtoint(ar3[0],row) then begin + dec(row); + if high(ar3) >= 1 then begin + if trystrtoint(ar3[1],col) then begin + dec(col); + result:= true; + end; + end + else begin + result:= true; + end; + if result then begin + afilename:= ar1[0]; + end; + end; + if result and (alevel = el_none) then begin + alevel:= el_all; + end; + end; + end; + end; + if (alevel = el_none) and not result then begin + ar1:= nil; + ar2:= nil; + splitstring(text,ar1,msechar(':')); + if high(ar1) > 2 then begin + for int1:= 2 to 3 do begin + ar1[int1]:= struppercase(ar1[int1]); + end; + if (ar1[2] = ' ERROR') or (ar1[3] = ' ERROR') then begin + alevel:= el_error; + end + else begin + if (ar1[2] = ' WARNING') or (ar1[3] = ' WARNING') then begin + alevel:= el_warning; + end + else begin + if (ar1[2] = ' HINT') or (ar1[3] = ' HINT') then begin + alevel:= el_hint; + end + else begin + alevel:= el_all; + end; + end; + end; + if alevel <> el_none then begin + if trystrtoint(ar1[1],row) then begin + dec(row); + if trystrtoint(ar1[2],col) then begin + dec(col); + end + else begin + col:= 0; + end; + afilename:= ar1[0]; + result:= true; + end; + end; + end; + end; +end; + +function locateerrormessage(const text: msestring; var apage: tsourcepage; + minlevel: errorlevelty = el_all): boolean; +var + lev1: errorlevelty; + col1,row1: integer; + fna1: filenamety; +begin + apage:= nil; + result:= false; + if checkerrormessage(text,lev1,fna1,col1,row1) and (fna1 <> '') and + (lev1 >= minlevel) then begin + apage:= sourcefo.showsourceline(sourcepath(fna1),row1,col1,true); + result:= true; + end; +end; + +(* +function locateerrormessage(const text: msestring; var apage: tsourcepage; + minlevel: errorlevelty = el_all): boolean; +var + ar1,ar2,ar3: msestringarty; + col,row: integer; + alevel: errorlevelty; + int1: integer; +begin + apage:= nil; + result:= false; + col:= 0; + row:= 0; + alevel:= el_all; + splitstring(text,ar1,msechar('(')); + if length(ar1) > 1 then begin //try FPC + splitstring(ar1[1],ar2,msechar(')')); + if length(ar2) > 1 then begin + splitstring(ar2[0],ar3,msechar(',')); + if (high(ar3) >= 0) then begin + if startsstr(' Error:',ar2[1]) or startsstr(' Fatal:',ar2[1]) then begin + alevel:= el_error; + end + else begin + if startsstr(' Warning:',ar2[1]) then begin + alevel:= el_warning; + end + else begin + if startsstr(' Hint:',ar2[1]) then begin + alevel:= el_hint; + end + else begin + if startsstr(' Note:',ar2[1]) then begin + alevel:= el_hint; + end; + end; + end; + end; + if alevel >= minlevel then begin + if trystrtointmse(ar3[0],row) then begin + dec(row); + if high(ar3) >= 1 then begin + if trystrtointmse(ar3[1],col) then begin + dec(col); + result:= true; + end; + end + else begin + result:= true; + end; + if result then begin + apage:= sourcefo.showsourceline(objpath(ar1[0]),row,col,true); + end; + end; + end; + end; + end; + end; + if (alevel = el_all) and not result then begin + ar1:= nil; + ar2:= nil; + splitstring(text,ar1,msechar(':')); + if high(ar1) > 2 then begin + for int1:= 2 to 3 do begin + ar1[int1]:= struppercase(ar1[int1]); + end; + if (ar1[2] = ' ERROR') or (ar1[3] = ' ERROR') then begin + alevel:= el_error; + end + else begin + if (ar1[2] = ' WARNING') or (ar1[3] = ' WARNING') then begin + alevel:= el_warning; + end + else begin + if (ar1[2] = ' HINT') or (ar1[3] = ' HINT') then begin + alevel:= el_hint; + end + else begin + alevel:= el_all; + end; + end; + end; + if alevel >= minlevel then begin + if trystrtointmse(ar1[1],row) then begin + dec(row); + if trystrtointmse(ar1[2],col) then begin + dec(col); + end + else begin + col:= 0; + end; + apage:= sourcefo.showsourceline(objpath(ar1[0]),row,col,true); + result:= true; + end; + end; + end; + end; +end; +*) + +{ tnaviglist } + +constructor tnaviglist.create; +begin + findex:= -1; + inherited; +end; + +procedure tnaviglist.updateshowpos( + const acellpos: cellpositionty = cep_rowcenteredif); +begin + with fsourcefo do begin + showsourcepos(self.items[findex]^,true,acellpos); + navigforwardact.enabled:= findex < fcount - 1; + navigbackact.enabled:= findex > 0; + end; +end; + +function tnaviglist.back: boolean; +begin + if findex > 0 then begin + result:= true; + dec(findex); + updateshowpos(cep_rowcenteredif); + end + else begin + result:= false; + end; +end; + +function tnaviglist.forward: boolean; +begin + if (findex < count - 1) then begin + result:= true; + inc(findex); + updateshowpos(cep_rowcenteredif); + end + else begin + result:= false; + end; +end; + +procedure tnaviglist.showsource(const apos: sourceposty; + const asetfocus: boolean = false); +begin + count:= findex + 1; + if count = 0 then begin + add(fsourcefo.sourcepos); + end + else begin + items[findex]^:= fsourcefo.sourcepos; + end; + findex:= add(apos); + updateshowpos(cep_none{cep_top}); +end; + +{ tsourcefo } + +constructor tsourcefo.create(aowner: tcomponent); +begin + fnaviglist:= tnaviglist.create; + fnaviglist.fsourcefo:= self; + inherited create(aowner); +end; + +destructor tsourcefo.destroy; +begin + hidesourcehint; + inherited; + fnaviglist.Free; + flayoutstream.free; +end; + +function tsourcefo.hidesourcehint: boolean; +begin + if fsourcehintwidget <> nil then begin + result:= true; + freeandnil(fsourcehintwidget); + end + else begin + result:= false; + end; +end; + +procedure tsourcefo.tabwidgetpageremoved(const sender: TObject; const awidget: twidget); +begin + if awidget = fgdbpage then begin + fgdbpage:= nil; + end; +end; + +procedure tsourcefo.updatestat(const statfiler: tstatfiler); +var + int1: integer; + filenames,relpaths,modulenames: filenamearty; + moduleoptions: integerarty; +// moduledock: stringarty; + ismod: longboolarty; + ar1,ar2: longboolarty; + page1: tsourcepage1; + intar1,intar2: integerarty; + mstr1: filenamety; + bo1: boolean; + po1: pmoduleinfoty; +// ar3: msestringarty; +// pt1: pointty; + +begin + with statfiler do begin + setsection('edit'); + updatevalue('hintwidth',hintsize.cx); + updatevalue('hintheight',hintsize.cy); + updatefindvalues(statfiler,projectoptions.findreplaceinfo.find); + if iswriter then begin + intar1:= tabwidget.idents; + sortarray(intar1,intar2); + setlength(filenames,count); + setlength(relpaths,count); + setlength(feditposar,count); + setlength(fbookmarkar,count); + setlength(ismod,count); + for int1:= 0 to high(filenames) do begin + with items[intar2[int1]] do begin + filenames[int1]:= filepath; + relpaths[int1]:= relpath; + feditposar[int1]:= edit.editpos; + fbookmarkar[int1]:= getbookmarks; + ismod[int1]:= ismoduletext; + end; + end; + setlength(modulenames,designer.modules.count); + setlength(moduleoptions,length(modulenames)); +// setlength(moduledock,length(modulenames)); + setlength(ar1,length(modulenames)); + setlength(ar2,length(modulenames)); + for int1:= 0 to designer.modules.count - 1 do begin + with designer.modules[int1]^ do begin + modulenames[int1]:= filename; + moduleoptions[int1]:= + {$ifdef FPC}longword{$else}byte{$endif}(designformintf.moduleoptions); + ar1[int1]:= designform.visible; + ar2[int1]:= not hasmenuitem; +// moduledock[int1]:= encodemoduledock(dockinfo); + end; + end; + tstatwriter(statfiler).writerecordarray('editpos',length(feditposar), + {$ifdef FPC}@{$endif}geteditpositem); + for int1:= 0 to high(fbookmarkar) do begin + factbookmark:= int1; + tstatwriter(statfiler).writerecordarray('bookmarks'+inttostrmse(int1), + length(fbookmarkar[int1]), + {$ifdef FPC}@{$endif}getbookmarkitem); + end; + end + else begin + tstatreader(statfiler).readrecordarray('editpos', + {$ifdef FPC}@{$endif}seteditposcount, + {$ifdef FPC}@{$endif}seteditpositem); + setlength(fbookmarkar,length(feditposar)); + for int1:= 0 to high(fbookmarkar) do begin + factbookmark:= int1; + tstatreader(statfiler).readrecordarray('bookmarks'+inttostrmse(int1), + {$ifdef FPC}@{$endif}setbookmarkcount, + {$ifdef FPC}@{$endif}setbookmarkitem); + end; + end; + updatevalue('sourcefiles',filenames); + updatevalue('relpaths',relpaths); + updatevalue('ismoduletexts',ismod); + updatevalue('modules',modulenames); + updatevalue('moduleoptions',moduleoptions); +// updatevalue('moduledock',moduledock); + updatevalue('visiblemodules',ar1); + updatevalue('nomenumodules',ar2); + if not iswriter then begin + tabwidget.window.nofocus; + tabwidget.clear; + tabwidget.beginupdate; + try + for int1:= 0 to high(filenames) do begin + page1:= tsourcepage1(createnewpage('')); + if (page1 <> nil) then begin + page1.finitialfilepath:= filenames[int1]; + if int1 <= high(relpaths) then begin + page1.relpath:= relpaths[int1]; + end; + if int1 <= high(ismod) then begin + page1.ismoduletext:= ismod[int1]; + end; + if int1 <= high(feditposar) then begin + page1.finitialeditpos:= feditposar[int1]; + if page1.finitialeditpos.col < 0 then begin + page1.finitialeditpos.col:= 0; + end; + if page1.finitialeditpos.row < 0 then begin + page1.finitialeditpos.row:= 0; + end; + end; + if int1 <= high(fbookmarkar) then begin + page1.finitialbookmarks:= fbookmarkar[int1]; + end; + page1.updatecaption(false); + end; + end; + mainfo.errorformfilename:= ''; + setlength(ar2,length(modulenames)); + setlength(moduleoptions,length(modulenames)); +// setlength(moduledock,length(modulenames)); + designer.beginskipall; + for int1:= 0 to high(modulenames) do begin + try + if int1 > high(ar1) then begin + bo1:= true; + end + else begin + bo1:= ar1[int1]; + end; + mstr1:= modulenames[int1]; + relocatepath(projectoptions.projectdir,'',mstr1, + [pro_preferenew,pro_rootpath]); + po1:= mainfo.openformfile(filepath(mstr1),bo1,false,false, + not ar2[int1],true); +{ + mstr1:= relativepath(modulenames[int1],projectoptions.projectdir); + if findfile(mstr1) then begin + po1:= mainfo.openformfile(filepath(mstr1),bo1,false,false, + not ar2[int1],true); + end + else begin + po1:= mainfo.openformfile(modulenames[int1],bo1,false,false, + not ar2[int1],true); + end; +} + if (po1 <> nil) then begin + with po1^ do begin + designformintf.moduleoptions:= + moduleoptionsty({$ifdef FPC}longword{$else}byte{$endif} + (moduleoptions[int1])) * [mo_hidewidgets,mo_hidecomp]; +// if decodemoduledock(moduledock[int1],dockinfo) then begin +// docktopanel(designformintf.getdockcontroller(),dockinfo.panelname, +// dockinfo.rect); +// end; + end; + end; + except + if checkprojectloadabort then begin + break; //do not load more modules + end; + end; + end; + designer.endskipall; + tabwidget.activepageindex:= -1; //do not load source +// updatestat(istatfile(tabwidget)); + finally + tabwidget.endupdate; + end; + end; +// if visible and (activepage <> nil) then begin +// activepage.sourcefoonshow(nil); +// end; + feditposar:= nil; //no longer used + fbookmarkar:= nil; + updatestat(istatfile(tabwidget)); + if mainfo.errorformfilename <> '' then begin + showsourceline(mainfo.errorformfilename,0,0,true); + end; + if (tabwidget.activepageindex < 0) and (tabwidget.count > 0) then begin + tabwidget.activepageindex:= 0; //default + end; + end; +end; + +procedure tsourcefo.doselectpage(const sender: TObject); +begin + selecteditpage; +end; + +procedure tsourcefo.navigback(const sender: TObject); +begin + fnaviglist.back; +end; + +procedure tsourcefo.navigforward(const sender: TObject); +begin + fnaviglist.forward; +end; + +procedure tsourcefo.formonidle(var again: boolean); + +var + all: boolean; + noall: boolean; + + function ask(const filepath: filenamety; const modified: boolean): boolean; + var + mstr1: msestring; + begin + if noall then begin + result:= false; + end + else begin + if all and not modified then begin + result:= true; + end + else begin + mstr1:= c[ord(str_file)]+filepath+c[ord(haschanged)]; + if modified then begin + mstr1:= mstr1 + ' '+ c[ord(modieditalso)]; + mstr1:= mstr1 + ' '+c[ord(wishreload)]; + result:= askyesno(mstr1,c[ord(confirmation)]); + end + else begin + result:= false; + mstr1:= mstr1 + ' '+c[ord(wishreload)]; + case showmessage(mstr1,c[ord(confirmation)], + [mr_yes,mr_all,mr_no,mr_noall],mr_yes) of + mr_yes: begin + result:= true; + end; + mr_all: begin + result:= true; + all:= true; + end; + mr_noall: begin + noall:= true; + end; + end; + end; + end; + end; + end; + +var + int1: integer; + po1: pmoduleinfoty; + fna1: filenamety; + hasdesignfo1: boolean; + hasmenu1: boolean; + visible1: boolean; + active1: boolean; +begin + if (application.activewindow <> nil) and not fasking and + (application.modallevel = 0) and + (application.keyboardcapturewidget = nil) then begin + fasking:= true; + all:= false; + noall:= false; + try + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if filechanged then begin + filechanged:= false; + if ask(filepath,modified) then begin + filechanged:= false; + reload; + mainfo.sourcechanged(items[int1]); + end + else begin + edit.modified:= true; + end; + mainfo.sourcechanged(items[int1]); + end; + end; + end; + for int1:= 0 to designer.modules.count - 1 do begin + po1:= designer.modules.itempo[int1]; + with po1^ do begin + if filechanged then begin + if flayoutstream = nil then begin + flayoutstream:= ttextstream.create(); + mainfo.savewindowlayout(flayoutstream); + end; + if ask(filename,modified) then begin + fna1:= filename; + hasmenu1:= hasmenuitem; + hasdesignfo1:= designform <> nil; + if hasdesignfo1 then begin + visible1:= designform.visible; + active1:= designform.activeentered; + end; + designform.free(); + if hasdesignfo1 then begin + po1:= mainfo.openformfile(fna1,visible1,active1,false,hasmenu1,false); + end + else begin + po1:= designer.loadformfile(fna1,false); + end; + po1^.filechanged:= true; + end + else begin + designer.modulechanged(po1); + end; + end; + end; + end; + all:= false; + noall:= false; + for int1:= 0 to designer.modules.count - 1 do begin + po1:= designer.modules.itempo[int1]; + with po1^ do begin + if filechanged then begin + filechanged:= false; + designer.refreshdatafile(po1); + end; + end; + end; + if flayoutstream <> nil then begin + try + flayoutstream.position:= 0; + mainfo.loadwindowlayout(flayoutstream); + mainfo.sourcechanged(nil); + finally + freeandnil(flayoutstream); + end; + end; + finally + fasking:= false; + end; + end; +end; + +function modulecanchangenotify(const amodule: pmoduleinfoty; + const info: filechangeinfoty): boolean; +begin + result:= (info.changed - [fc_force,fc_accesstime] <> []); +end; + +procedure tsourcefo.onfilechanged(const sender: tfilechangenotifyer; + const info: filechangeinfoty); +var + int1: integer; + po1: pmoduleinfoty; +begin + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if (longword(info.tag) = filetag) and canchangenotify(info) then begin + filechanged:= true; + application.wakeupmainthread(); + end; + end; + end; + for int1:= 0 to designer.modules.count - 1 do begin + po1:= designer.modules.itempo[int1]; + with po1^ do begin + if (longword(info.tag) = filetag) and + modulecanchangenotify(po1,info) then begin + filechanged:= true; + application.wakeupmainthread(); + end; + end; + end; +end; + +function tsourcefo.count: integer; +begin + result:= tabwidget.count; +end; + +function tsourcefo.getitems(const index: integer): tsourcepage; +begin + result:= tsourcepage(tabwidget[index]); +end; + +function tsourcefo.findsourcepage(afilename: filenamety; + wholepath: boolean = true; + onlyifloaded: boolean = false): tsourcepage; +var + int1: integer; +begin + result:= nil; + if wholepath then begin + for int1:= 0 to count - 1 do begin + if issamefilename(items[int1].filepath,afilename) then begin + result:= items[int1]; + break; + end; + end; + end + else begin + for int1:= 0 to count - 1 do begin + if issamefilename(items[int1].filename,afilename) then begin + result:= items[int1]; + break; + end; + end + end; + if result <> nil then begin + if onlyifloaded then begin + if not result.fileloaded then begin + result:= nil; + end; + end + else begin + result.loadfile; + end; + end; +end; + +function tsourcefo.createnewpage(const afilename: filenamety): tsourcepage; +begin + result:= tsourcepage.create(nil); + try + result.edit.syntaxpainter:= syntaxpainter; + result.dataicon.imagelist:= imagelist; + result.filepath:= afilename; + tabwidget.add(result,tabwidget.activepageindex+1); + if afilename <> '' then begin + filechangenotifyer.addnotification(result.filepath,result.filetag); + designer.designfiles.add(afilename); + end; + except + result.Free; + result:= nil; + application.handleexception(self); + end; +end; + +function tsourcefo.newpage: tsourcepage; +begin + result:= createnewpage(''); + result.updatecaption(false); + result.show; + result.setfocus(true); +end; + +function tsourcefo.openfile(const filename: filenamety; + aactivate: boolean = false): tsourcepage; + //nil if not ok + + function loadfile(aname: filenamety): tsourcepage; + var + po1: pmoduleinfoty; + begin + po1:= designer.modules.findmodule(filepath(aname)); + if not mainfo.closemodule(po1,true) then begin + sysutils.abort; + end; + ffileloading:= true; + try + result:= createnewpage(aname); + if result <> nil then begin + result.ismoduletext:= (po1 <> nil); + mainfo.loadformbysource(aname); + end; + finally + ffileloading:= false; + end; + end; + +var + str1: filenamety; + bo1: boolean; +begin + result:= nil; + if filename = '' then begin + exit; + end; + application.beginwait; + try + bo1:= isrootpath(filename); + if bo1 then begin + result:= findsourcepage(filename); + if result = nil then begin + if findfile(filename) then begin + result:= loadfile(filename); + end; + end; + end; + if result = nil then begin + if bo1 and findfile(msefileutils.filename(filename), + projectoptions.d.texp.sourcedirs,str1) or + not bo1 and + findfile(filename,projectoptions.d.texp.sourcedirs,str1) then begin + result:= findsourcepage(str1); + if result = nil then begin + result:= loadfile(str1); + end; + end; + end; + if (result <> nil) and aactivate then begin + result.activate(true); + end; + finally + application.endwait; + end; +end; + +function tsourcefo.showsourceline(const filename: filenamety; + line: integer; col: integer = 0; asetfocus: boolean = false; + const aposition: cellpositionty = cep_rowcentered): tsourcepage; +var + rowpos1: int32; +begin + rowpos1:= 0; + if activepage <> nil then begin + rowpos1:= activepage.grid.rowwindowpos; //current window pos of focused row + end; + result:= openfile(filename); + if result <> nil then begin + result.show; + if line >= 0 then begin + result.grid.showcell(makegridcoord(0,line),aposition); + if asetfocus then begin + result.edit.editpos:= makegridcoord(col,line); + result.grid.setfocus; + result.window.bringtofront; + end; + if aposition = cep_none then begin + result.grid.rowwindowpos:= rowpos1; + end; + end; + end; +end; + +function tsourcefo.showsourcepos(const apos: sourceposty; + asetfocus: boolean = false; + const aposition: cellpositionty = cep_top): tsourcepage; +var + str1: filenamety; +begin + result:= nil; + str1:= designer.designfiles.getname(apos.filename); + if str1 <> '' then begin + result:= showsourceline(str1,apos.pos.row,apos.pos.col,asetfocus,aposition); + end; +end; + +procedure tsourcefo.resetactiverow; +begin + if fgdbpage <> nil then begin + fgdbpage.activerow:= -1; + end; +end; + +function tsourcefo.locate(const info: stopinfoty): tsourcepage; +begin + resetactiverow; + if info.filename <> '' then begin + result:= openfile(sourcepath(info.filename)); + if result <> nil then begin + result.activerow:= info.line-1; + result.show; + end; + end + else begin + result:= nil; + end; + fgdbpage:= result; +end; + +function tsourcefo.saveall(noconfirm: boolean): modalresultty; +var + int1,int2: integer; +begin + result:= mr_none; + for int1:= 0 to tabwidget.count - 1 do begin + result:= mainfo.checksavecancel( + tsourcepage(tabwidget[int1]).checksave(noconfirm,true)); + case result of + mr_cancel: begin + exit; + end; + mr_noall: begin + break; + end; + mr_all: begin + for int2:= int1 to tabwidget.count - 1 do begin + tsourcepage(tabwidget[int2]).checksave(true,true); + end; + break; + end; + end; + end; + fallsaved:= fallsaved or not noconfirm; +end; + +function tsourcefo.modified: boolean; +var + int1: integer; +begin + result:= false; + if fpagedestroying = 0 then begin + for int1:= 0 to count - 1 do begin + if items[int1].modified then begin + result:= true; + break; + end; + end; + end; +end; + +function tsourcefo.newfiletag: longword; +begin + inc(ffiletag); + if ffiletag = 0 then begin + ffiletag:= 1; + end; + result:= ffiletag; +end; + +procedure tsourcefo.sourcefoonclosequery(const sender: tcustommseform; + var modalresult: modalresultty); +begin +{ + if saveall(false) = mr_cancel then begin + modalresult:= mr_none; + end; +} +end; + +procedure tsourcefo.updatecaption; +var + page: tsourcepage; + +begin + page:= tsourcepage(tabwidget.activepage); + if page <> nil then begin + caption:= page.caption; + end + else begin + caption:= c[ord(none)]; + end; +end; + +procedure tsourcefo.tabwidgetonactivepagechanged(const sender: tobject); +begin + updatecaption; +end; + +procedure tsourcefo.saveactivepage(const newname: filenamety = ''); +begin + if activepage <> nil then begin + activepage.save(newname); + end; +end; + +function tsourcefo.closepage(const apage: tsourcepage; + noclosecheck: boolean = false): boolean; +var + str1: filenamety; + bo1: boolean; +begin + result:= apage = nil; + if not result then begin + if apage.checksave(false,false) <> mr_cancel then begin + str1:= apage.filepath; + if not noclosecheck and (fileext(str1) = pasfileext) then begin + if not mainfo.closemodule( + designer.modules.findmodule(replacefileext(str1,formfileext)),true, + noclosecheck) then begin + exit; + end; + end; + filechangenotifyer.removenotification(str1); + inc(fpagedestroying); + try + bo1:= tabwidget.entered; + apage.free; + if bo1 then begin + tabwidget.setfocus; + end; + finally + dec(fpagedestroying); + end; + result:= true; + end; + end; +end; + +function tsourcefo.closepage(const aname: filenamety): boolean; +begin + result:= closepage(findsourcepage(aname,true,true)); +end; + +function tsourcefo.closeactivepage: boolean; +begin + result:= closepage(activepage); +end; + +function tsourcefo.closeall(const nosave: boolean): boolean; //false on cancel +var + int1: integer; +begin + result:= nosave or (saveall(false) <> mr_cancel); + if result then begin + for int1:= count - 1 downto 0 do begin + items[int1].enabled:= false; //avoid showing + end; + for int1:= count - 1 downto 0 do begin + closepage(items[int1],true); + end; + end; +end; + +function tsourcefo.activepage: tsourcepage; +begin + if fpagedestroying > 0 then begin + result:= nil; + end + else begin + result:= tsourcepage(tabwidget.activepage); + end; +end; + +procedure tsourcefo.textmodified(const sender: tsourcepage); +begin + fallsaved:= false; + if not ffileloading then begin + mainfo.sourcechanged(sender); + end; +end; + +function tsourcefo.gdbpage: tsourcepage; +begin + result:= fgdbpage; +end; + +procedure tsourcefo.addwatchactonexecute(const sender: tobject); +begin + with sender as tmenuitem do begin + watchfo.addwatch(getpascalvarname(activepage.edit, + translateclientpoint(owner.mouseinfopo^.pos, + owner.transientfor,activepage.edit))); + end; +end; + +procedure tsourcefo.updatebreakpointicon(const path: filenamety; const info: bkptlineinfoty); +var + int1: integer; + wstr1: msestring; +begin + wstr1:= filename(path); + for int1:= 0 to count - 1 do begin + with tsourcepage(tabwidget[int1]) do begin + if issamefilename(filename,wstr1) then begin + try + updatebreakpointicon(info); + except + end; + end; + end; + end; +end; + +function tsourcefo.geteditpositem(const index: integer): msestring; +begin + result:= encoderecord([feditposar[index].col,feditposar[index].row]); +end; + +procedure tsourcefo.seteditposcount(const count: integer); +begin + setlength(feditposar,count); +end; + +procedure tsourcefo.seteditpositem(const index: integer; const avalue: msestring); +begin + decoderecord(avalue,[@feditposar[index].col,@feditposar[index].row],'ii'); +end; + +function tsourcefo.getbookmarkitem(const index: integer): msestring; +begin + result:= encoderecord([fbookmarkar[factbookmark][index].row, + fbookmarkar[factbookmark][index].bookmarknum]); +end; + +procedure tsourcefo.setbookmarkcount(const count: integer); +begin + setlength(fbookmarkar[factbookmark],count); +end; + +procedure tsourcefo.setbookmarkitem(const index: integer; const avalue: msestring); +begin + decoderecord(avalue,[@fbookmarkar[factbookmark][index].row, + @fbookmarkar[factbookmark][index].bookmarknum],'ii'); +end; + +procedure tsourcefo.enterexe(const sender: tobject); +begin + mainfo.designformactivated(self); +end; + +function tsourcefo.gettextstream(const filename: filenamety; + forwrite: boolean): ttextstream; +var + page1: tsourcepage; +begin + page1:= findsourcepage(filename,true,true); + if forwrite then begin + if page1 = nil then begin + page1:= openfile(filename); + end; + end; + if page1 <> nil then begin + result:= page1.edit.datalist.dataastextstream; + end + else begin + if not forwrite then begin + result:= ttextstream.create(filename,fm_read); + end + else begin + result:= nil; + end; + end; +end; + +function tsourcefo.getfiletext(const filename: filenamety; + const startpos,endpos: gridcoordty): msestring; +var + apage: tsourcepage; +begin + apage:= openfile(filename); + if apage <> nil then begin + result:= apage.edit.gettext(startpos,endpos); + end + else begin + result:= ''; + end; +end; + +procedure tsourcefo.replacefiletext(const filename: filenamety; + const startpos,endpos: gridcoordty; const newtext: msestring); +var + apage: tsourcepage; +begin + apage:= openfile(filename); + if apage <> nil then begin + apage.edit.deletetext(startpos,endpos); + apage.edit.inserttext(startpos,msestring(newtext)); + end; +end; + +function tsourcefo.getsourcepos: sourceposty; +begin + finalize(result); + fillchar(result,sizeof(result),0); + if activepage <> nil then begin + result.filename:= designer.designfiles.find(activepage.filepath); + result.pos:= activepage.edit.editpos; + end; +end; + +procedure tsourcefo.setsourcehintwidget(const avalue: twidget); +begin + fsourcehintwidget.free; + setlinkedvar(avalue,tmsecomponent(fsourcehintwidget)); +end; + +procedure tsourcefo.editbreakpointexec(const sender: TObject); +begin + breakpointsfo.showbreakpoint(activepage.filepath,popuprow+1,true); +end; +{ +procedure tsourcefo.togglebreakpointexe(const sender: TObject); +begin + activepage.togglebreakpoint(popuprow); +end; +} +procedure tsourcefo.popupmonupdate(const sender: tcustommenu); +//var +// gc1: gridcoordty; +begin + if (activepage <> nil) and (sender.mouseinfopo <> nil) then begin + popuprow:= activepage.grid.cellatpos(translateclientpoint( + sender.mouseinfopo^.pos,activepage,activepage.grid)).row; + end + else begin + popuprow:= invalidaxis; + end; + sender.menu.itembyname('editbreakpoint').enabled:= + (activepage <> nil) and (popuprow >= 0) and + (activepage.getbreakpointstate(popuprow) > bkpts_none); + sender.menu.itembyname('showasform').enabled:= + (activepage <> nil) and activepage.ismoduletext; + sender.menu.itembyname('setbm').enabled:= + (activepage <> nil) and (popuprow >= 0); + sender.menu.itembyname('insgui').enabled:= (activepage <> nil); + sender.menu.itembyname('insuid').enabled:= (activepage <> nil); + sender.menu.itembynames(['modifyselection','convpas']).enabled:= + (activepage <> nil) and activepage.edit.hasselection; + sender.menu.itembyname('addwatch').enabled:= (activepage <> nil) and + (sender.mouseinfopo <> nil) and + (getpascalvarname(activepage.edit, + translateclientpoint(sender.mouseinfopo^.pos, + activepage,activepage.edit)) <> ''); +{ + sender.menu.itembyname('instempl').enabled:= (activepage <> nil) and + codetemplates.hastemplate( + activepage.edit.wordatpos(activepage.edit.editpos,gc1,'',[],true)); +} +end; + +procedure tsourcefo.completeclassexecute(const sender: TObject); +var + pos1: sourceposty; +begin + if activepage <> nil then begin + activepage.edit.editor.begingroup; + try + pos1.pos:= activepage.edit.editpos; + completeclass(activepage.filepath,pos1); + finally + activepage.edit.editor.endgroup; + end; + end; +end; + +procedure tsourcefo.showasformexe(const sender: TObject); +begin + activepage.asyncevent(integer(spat_showasform)); +end; + +procedure tsourcefo.setbookmark(const apage: tsourcepage; const arow: integer; + const bookmarknum: integer); +var + int1: integer; + page1: tsourcepage; + bo1: boolean; +begin + if bookmarknum >= 0 then begin + bo1:= (arow >= 0) and (bookmarknum >= 0); + for int1:= 0 to self.count - 1 do begin + page1:= items[int1]; + if bo1 and (page1 = apage) and (page1.findbookmark(bookmarknum) = arow) then begin + page1.clearbookmark(bookmarknum); + exit; + end; + page1.clearbookmark(bookmarknum); + end; + end; + apage.setbookmark(arow,bookmarknum); +end; + +procedure tsourcefo.setbmexec(const sender: TObject); +begin + setbookmark(activepage,-1,tmenuitem(sender).tag); +end; + +function tsourcefo.findbookmark(const bookmarknum: integer): boolean; +var + int1,int2: integer; +begin + result:= false; + for int1:= 0 to count - 1 do begin + with items[int1] do begin + int2:= findbookmark(bookmarknum); + if int2 >= 0 then begin + grid.showcell(makegridcoord(invalidaxis,int2),cep_rowcenteredif); + edit.editpos:= makegridcoord(0,int2); + activate; + result:= true; + end; + end; + end; +end; + +procedure tsourcefo.findbmexec(const sender: TObject); +begin + findbookmark(tmenuitem(sender).tag); +end; + +procedure tsourcefo.insguiexec(const sender: TObject); +begin + with activepage.edit do begin + inserttext(editpos,'['''+msestring(createguidstring)+''']'); + end; +end; + +procedure tsourcefo.insuidexec(const sender: TObject); +var + id1,int1: integer; + str1: string[4]; + str2: string; +begin + id1:= projectoptions.k.uid; + if integerenter(id1,minint,maxint,'ID','Enter ID') = mr_ok then begin + for int1:= 0 to 3 do begin + str1[int1+1]:= char(bitreverse[byte( + (id1 and ($ff shl (int1*8))shr(int1*8)))]); + end; + str1[0]:= #1; + for int1:= 4 downto 1 do begin + if str1[int1] <> #0 then begin + str1[0]:= char(int1); + break; + end; + end; + str2:= encodebase64(str1); + for int1:= length(str2) downto 1 do begin + if str2[int1] <> '=' then begin + setlength(str2,int1); + break; + end; + end; + + with activepage.edit do begin + inserttext(editpos,'['''+msestring(str2)+''']{'+inttostrmse(id1)+'}'); + end; + projectoptions.k.uid:= id1+1; + end; +end; + +procedure tsourcefo.convpasex(const sender: TObject); + +var + ar1: msestringarty; + + function messagestr(const def: msestring): msestring; + begin + if high(ar1) > 4 then begin + result:= concatstrings(copy(ar1,0,5),lineend); + result:= result+lineend+'...'; + end + else begin + result:= def; + end; + if length(result) > 5*80 then begin + result:= copy(result,1,5*80)+'...'; + end; + end; //msessagestr + +var + mstr1,mstr2,mstr3,mstr4: msestring; + int1: integer; + maxlen: int32; +const + liend = '+lineend+'; + +begin + with activepage.edit do begin + maxlen:= projectoptions.e.rightmarginchars; + if maxlen > 0 then begin //else unlimited + maxlen:= maxlen-length(liend); + if maxlen < 20 then begin + maxlen:= 20; + end; + end; + mstr1:= selectedtext; + ar1:= breaklines(mstr1); + mstr3:= messagestr(mstr1); + for int1:= 0 to high(ar1)-1 do begin + ar1[int1]:= msestring(stringtopascalstring(ar1[int1],maxlen))+liend; + end; + ar1[high(ar1)]:= msestring(stringtopascalstring(ar1[high(ar1)],maxlen)); + mstr2:= concatstrings(ar1,lineend); + mstr4:= messagestr(mstr2); + if askyesno(c[ord(wishreplace)]+lineend+mstr3+lineend+c[ord(str_with)]+lineend+ + mstr4+lineend+'?',c[ord(confirmation)]) then begin + editor.begingroup; + deleteselection; + inserttext(mstr2,true); + editor.endgroup; + end; + end; +end; + +procedure tsourcefo.savecanceled; +begin + fallsaved:= false; +end; + +function tsourcefo.currentselection: msestring; +begin + result:= ''; + if activepage <> nil then begin + with activepage do begin + result:= edit.selectedtext; + end; + end; +end; + +function tsourcefo.currentfilename: filenamety; +begin + result:= ''; + if activepage <> nil then begin + with activepage do begin + result:= filepath; + end; + end; +end; + +function tsourcefo.currentwordatcursor: msestring; +var + gridcoord1: gridcoordty; +begin + result:= ''; + if activepage <> nil then begin + with activepage do begin + result:= getpascalvarname(edit,edit.editpos,gridcoord1); + end; + end; +end; + +procedure tsourcefo.stephintev(const sender: TObject; var info: hintinfoty); +begin + info.caption:= info.caption + '('+ + encodeshortcutname(tstockglyphbutton(sender).shortcut)+').'; +end; + +end. diff --git a/mseide-msegui/apps/ide/sourceform_mfm.pas b/mseide-msegui/apps/ide/sourceform_mfm.pas new file mode 100644 index 0000000..122df0f --- /dev/null +++ b/mseide-msegui/apps/ide/sourceform_mfm.pas @@ -0,0 +1,618 @@ +unit sourceform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,sourceform; + +const + objdata: record size: integer; data: array[0..12007] of byte end = + (size: 12008; data: ( + 84,80,70,48,9,116,115,111,117,114,99,101,102,111,8,115,111,117,114,99, + 101,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111, + 99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101,2,10,18, + 102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110,115,11,14, + 103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111,95,102,105, + 120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108,111,97,116, + 98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110,19, + 103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110,15, + 103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95,98, + 117,116,116,111,110,104,105,110,116,115,0,7,111,110,101,110,116,101,114,7, + 8,101,110,116,101,114,101,120,101,10,111,110,97,99,116,105,118,97,116,101, + 7,8,101,110,116,101,114,101,120,101,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,98,8,98,111,117,110,100,115,95,121,3, + 158,0,9,98,111,117,110,100,115,95,99,120,3,177,1,9,98,111,117,110, + 100,115,95,99,121,3,71,1,23,99,111,110,116,97,105,110,101,114,46,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,19,111, + 119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,26,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,30,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,115,98,104,111,114,122,46, + 111,112,116,105,111,110,115,11,12,115,98,111,95,109,111,118,101,97,117,116, + 111,12,115,98,111,95,115,104,111,119,97,117,116,111,0,30,99,111,110,116, + 97,105,110,101,114,46,102,114,97,109,101,46,115,98,118,101,114,116,46,111, + 112,116,105,111,110,115,11,12,115,98,111,95,109,111,118,101,97,117,116,111, + 12,115,98,111,95,115,104,111,119,97,117,116,111,0,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,167,1,3, + 71,1,0,22,100,114,97,103,100,111,99,107,46,115,112,108,105,116,116,101, + 114,95,115,105,122,101,2,0,16,100,114,97,103,100,111,99,107,46,99,97, + 112,116,105,111,110,6,6,83,111,117,114,99,101,20,100,114,97,103,100,111, + 99,107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115, + 97,118,101,112,111,115,10,111,100,95,99,97,110,109,111,118,101,11,111,100, + 95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107, + 11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116, + 105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110, + 115,0,7,111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112, + 111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97, + 116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,6,60, + 110,111,110,101,62,21,105,99,111,110,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,12,105,99,111,110,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,0,10,105, + 99,111,110,46,105,109,97,103,101,10,136,7,0,0,0,0,0,0,2,0, + 0,0,24,0,0,0,24,0,0,0,244,6,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,208,208,208,25,136,136,136,13,130,136,136,1,136,136, + 136,1,208,208,208,9,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252, + 254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1,127,135, + 135,1,159,197,200,1,136,136,136,1,208,208,208,8,136,136,136,1,179,248, + 254,1,182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251, + 254,1,198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254, + 254,1,213,254,254,1,131,137,138,1,198,249,255,1,158,197,200,1,136,136, + 136,1,208,208,208,7,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252, + 254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1,133,138, + 138,1,226,252,255,1,197,249,255,1,158,197,200,1,136,136,136,1,208,208, + 208,6,136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250, + 254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253, + 254,1,207,253,254,1,210,254,254,1,213,254,254,1,130,137,138,1,254,254, + 255,1,225,252,255,1,195,249,255,1,158,197,200,1,136,136,136,1,208,208, + 208,5,136,136,136,1,179,248,254,1,182,248,254,1,184,247,252,1,91,121, + 123,1,191,250,254,1,130,168,170,1,193,244,247,1,199,249,251,1,196,243, + 244,1,205,250,251,1,142,171,171,1,213,254,254,1,127,137,138,1,223,252, + 255,1,252,254,255,1,223,252,255,1,194,249,255,1,157,196,200,1,136,136, + 136,1,208,208,208,4,136,136,136,1,179,248,254,1,182,248,254,1,136,183, + 186,1,102,135,137,1,151,197,200,1,89,115,117,1,111,141,142,1,117,146, + 147,1,144,179,179,1,122,149,149,1,96,116,116,1,213,254,254,1,124,137, + 138,1,190,249,255,1,225,252,255,1,250,254,255,1,221,252,255,1,192,249, + 255,1,157,196,200,1,136,136,136,1,208,208,208,3,136,136,136,1,179,248, + 254,1,182,248,254,1,110,148,151,1,164,219,222,1,109,143,145,1,91,118, + 120,1,124,157,159,1,128,160,161,1,134,166,166,1,125,153,153,1,98,119, + 119,1,213,254,254,1,121,137,138,1,158,246,255,1,192,249,255,1,227,252, + 255,1,249,254,255,1,220,251,255,1,190,249,255,1,157,196,200,1,136,136, + 136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252, + 254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1,130,150, + 151,1,120,137,138,1,122,137,138,1,124,137,138,1,126,137,138,2,122,137, + 138,1,119,134,135,1,129,136,136,1,208,208,208,2,136,136,136,1,179,248, + 254,1,182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251, + 254,1,198,251,254,1,201,252,254,1,198,245,246,1,206,252,253,1,204,247, + 247,1,208,248,248,1,204,250,251,1,187,246,248,1,176,250,254,1,156,239, + 245,1,147,246,254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136, + 136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,195,244, + 246,1,87,108,109,1,114,140,140,1,116,140,140,1,157,187,187,1,126,155, + 155,1,106,140,141,1,106,151,153,1,71,108,111,1,133,223,230,1,132,244, + 254,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136, + 136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1,191,250, + 254,1,194,251,254,1,198,251,254,1,196,246,248,1,106,132,132,1,146,179, + 179,1,126,152,152,1,147,175,175,1,126,155,155,1,103,136,137,1,116,165, + 167,1,97,149,152,1,139,232,240,1,132,244,254,1,117,243,254,1,102,241, + 254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248, + 254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251, + 254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254, + 254,1,206,253,254,1,191,252,254,1,176,250,254,1,162,248,254,1,147,246, + 254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208, + 208,2,136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250, + 254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,195,242, + 243,1,147,180,180,1,205,248,248,1,206,246,246,1,202,248,249,1,184,243, + 245,1,170,241,245,1,159,243,249,1,142,238,246,1,131,243,253,1,117,243, + 254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248, + 254,1,182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251, + 254,1,198,251,254,1,188,236,238,1,117,145,145,1,111,136,136,1,119,143, + 143,1,100,120,120,1,116,142,142,1,129,170,171,1,119,169,171,1,93,142, + 145,1,63,105,109,1,71,131,136,1,117,243,254,1,102,241,254,1,136,136, + 136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,190,238, + 240,1,115,143,143,1,116,142,142,1,131,158,158,1,99,119,119,1,128,158, + 158,1,160,210,212,1,119,170,172,1,93,142,145,1,77,128,132,1,92,169, + 176,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136, + 136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1,191,250, + 254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253,254,1,207,253, + 254,1,150,181,181,1,137,163,163,1,206,253,254,1,173,228,230,1,119,169, + 171,1,126,194,198,1,147,246,254,1,132,244,254,1,117,243,254,1,102,241, + 254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248, + 254,1,185,249,254,1,181,241,245,1,163,214,217,1,194,251,254,1,167,212, + 214,1,136,170,171,1,181,224,225,1,161,196,197,1,193,233,233,1,213,254, + 254,1,206,253,254,1,191,252,254,1,176,250,254,1,162,248,254,1,147,246, + 254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208, + 208,2,136,136,136,1,179,248,254,1,182,248,254,1,110,148,151,1,81,108, + 110,1,116,152,154,1,126,162,164,1,120,152,153,1,125,156,157,1,91,113, + 114,1,148,181,181,1,189,229,229,1,213,254,254,1,206,253,254,1,191,252, + 254,1,176,250,254,1,162,248,254,1,147,246,254,1,132,244,254,1,117,243, + 254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248, + 254,1,182,248,254,1,120,162,165,1,113,150,152,1,121,158,160,1,130,168, + 170,1,120,153,154,1,125,156,157,1,125,155,155,1,127,156,156,1,189,229, + 229,1,213,254,254,1,206,253,254,1,191,252,254,1,176,250,254,1,162,248, + 254,1,147,246,254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136, + 136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252, + 254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1,206,253, + 254,1,191,252,254,1,176,250,254,1,162,248,254,1,147,246,254,1,132,244, + 254,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136, + 136,22,208,208,208,25,0,0,0,8,254,255,0,8,254,255,1,191,254,255, + 3,8,254,255,7,0,254,255,15,8,254,255,31,2,254,255,63,192,254,255, + 127,0,254,255,127,8,254,255,127,0,254,255,127,8,254,255,127,8,254,255, + 127,8,254,255,127,191,254,255,127,8,254,255,127,0,254,255,127,2,254,255, + 127,8,254,255,127,0,254,255,127,0,254,255,127,191,254,255,127,0,0,0, + 0,8,12,111,110,99,108,111,115,101,113,117,101,114,121,7,20,115,111,117, + 114,99,101,102,111,111,110,99,108,111,115,101,113,117,101,114,121,6,111,110, + 105,100,108,101,7,10,102,111,114,109,111,110,105,100,108,101,15,109,111,100, + 117,108,101,99,108,97,115,115,110,97,109,101,6,9,116,100,111,99,107,102, + 111,114,109,0,10,116,116,97,98,119,105,100,103,101,116,9,116,97,98,119, + 105,100,103,101,116,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,167,1, + 9,98,111,117,110,100,115,95,99,121,3,71,1,7,97,110,99,104,111,114, + 115,11,0,9,112,111,112,117,112,109,101,110,117,7,9,102,111,114,109,112, + 111,112,117,112,19,111,110,97,99,116,105,118,101,112,97,103,101,99,104,97, + 110,103,101,100,7,28,116,97,98,119,105,100,103,101,116,111,110,97,99,116, + 105,118,101,112,97,103,101,99,104,97,110,103,101,100,13,111,110,112,97,103, + 101,114,101,109,111,118,101,100,7,20,116,97,98,119,105,100,103,101,116,112, + 97,103,101,114,101,109,111,118,101,100,11,116,97,98,95,111,112,116,105,111, + 110,115,11,15,116,97,98,111,95,100,114,97,103,115,111,117,114,99,101,13, + 116,97,98,111,95,100,114,97,103,100,101,115,116,13,116,97,98,111,95,118, + 101,114,116,105,99,97,108,13,116,97,98,111,95,111,112,112,111,115,105,116, + 101,14,116,97,98,111,95,116,97,98,115,105,122,105,110,103,23,116,97,98, + 111,95,100,98,108,99,108,105,99,107,101,100,116,97,98,102,105,114,115,116, + 20,116,97,98,111,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,19,116,97,98,95,102,114,97,109,101,46,98,117,116,116,111,110,112, + 111,115,7,7,115,98,112,95,116,111,112,21,116,97,98,95,102,114,97,109, + 101,46,98,117,116,116,111,110,115,108,97,115,116,9,24,116,97,98,95,102, + 114,97,109,101,46,98,117,116,116,111,110,115,118,105,115,105,98,108,101,11, + 8,115,107,95,114,105,103,104,116,5,115,107,95,117,112,7,115,107,95,108, + 101,102,116,7,115,107,95,100,111,119,110,8,115,107,95,102,105,114,115,116, + 7,115,107,95,108,97,115,116,0,20,116,97,98,95,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,15,102,114,108,95,111,112,116,105, + 111,110,115,115,107,105,110,0,21,116,97,98,95,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,13,116,97,98,95,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100, + 0,11,116,97,98,95,115,105,122,101,109,105,110,2,60,8,116,97,98,95, + 115,105,122,101,2,60,18,116,97,98,95,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,0,0,17,116,115,116,111,99,107,103,108,121,112,104, + 98,117,116,116,111,110,18,116,115,116,111,99,107,103,108,121,112,104,98,117, + 116,116,111,110,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,15,111, + 119,95,100,105,115,97,98,108,101,100,104,105,110,116,12,111,119,95,116,105, + 109,101,100,104,105,110,116,0,8,116,97,98,111,114,100,101,114,2,2,4, + 104,105,110,116,6,28,83,116,101,112,32,98,97,99,107,32,105,110,32,99, + 111,100,101,32,110,97,118,105,103,97,116,105,111,110,10,111,110,115,104,111, + 119,104,105,110,116,7,10,115,116,101,112,104,105,110,116,101,118,8,98,111, + 117,110,100,115,95,120,3,127,1,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,20,9,98,111,117,110,100,115,95, + 99,121,2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,11,97,115, + 95,100,105,115,97,98,108,101,100,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103, + 101,110,114,18,97,115,95,108,111,99,97,108,99,111,108,111,114,103,108,121, + 112,104,12,97,115,95,108,111,99,97,108,104,105,110,116,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121,112,104, + 7,13,115,116,103,95,97,114,114,111,119,108,101,102,116,6,97,99,116,105, + 111,110,7,12,110,97,118,105,103,98,97,99,107,97,99,116,10,99,111,108, + 111,114,103,108,121,112,104,4,9,0,0,160,9,111,110,101,120,101,99,117, + 116,101,7,9,110,97,118,105,103,98,97,99,107,0,0,17,116,115,116,111, + 99,107,103,108,121,112,104,98,117,116,116,111,110,18,116,115,116,111,99,107, + 103,108,121,112,104,98,117,116,116,111,110,50,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,15,111,119,95,100,105,115,97,98,108,101,100,104,105,110, + 116,12,111,119,95,116,105,109,101,100,104,105,110,116,0,8,116,97,98,111, + 114,100,101,114,2,1,4,104,105,110,116,6,31,83,116,101,112,32,102,111, + 114,119,97,114,100,32,105,110,32,99,111,100,101,32,110,97,118,105,103,97, + 116,105,111,110,10,111,110,115,104,111,119,104,105,110,116,7,10,115,116,101, + 112,104,105,110,116,101,118,8,98,111,117,110,100,115,95,120,3,147,1,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,20,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 5,115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,17, + 97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115, + 95,108,111,99,97,108,105,109,97,103,101,110,114,18,97,115,95,108,111,99, + 97,108,99,111,108,111,114,103,108,121,112,104,12,97,115,95,108,111,99,97, + 108,104,105,110,116,0,5,103,108,121,112,104,7,14,115,116,103,95,97,114, + 114,111,119,114,105,103,104,116,6,97,99,116,105,111,110,7,15,110,97,118, + 105,103,102,111,114,119,97,114,100,97,99,116,10,99,111,108,111,114,103,108, + 121,112,104,4,9,0,0,160,0,0,0,14,116,115,121,110,116,97,120,112, + 97,105,110,116,101,114,13,115,121,110,116,97,120,112,97,105,110,116,101,114, + 12,100,101,102,100,101,102,115,46,100,97,116,97,1,1,6,5,42,46,112, + 97,115,6,8,112,97,115,46,115,100,101,102,0,0,4,108,101,102,116,2, + 32,3,116,111,112,2,64,0,0,10,116,105,109,97,103,101,108,105,115,116, + 9,105,109,97,103,101,108,105,115,116,5,99,111,117,110,116,2,14,4,108, + 101,102,116,2,33,3,116,111,112,2,93,5,105,109,97,103,101,10,236,13, + 0,0,0,0,0,0,2,0,0,0,64,0,0,0,64,0,0,0,184,11, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,170,0,0, + 0,1,255,255,255,62,0,0,0,3,255,255,255,29,0,0,255,3,255,255, + 255,13,0,0,255,3,255,255,255,13,0,0,0,3,255,255,255,28,0,0, + 255,5,255,255,255,11,0,0,255,1,255,255,255,3,0,0,255,1,255,255, + 255,12,0,0,0,3,255,255,255,7,255,0,0,2,255,255,255,18,0,0, + 255,7,255,255,255,9,0,0,255,1,255,255,255,5,0,0,255,1,255,255, + 255,11,0,0,0,3,255,255,255,6,255,0,0,1,255,255,0,1,255,0, + 0,2,255,255,255,17,0,0,255,7,255,255,255,9,0,0,255,1,255,255, + 255,5,0,0,255,1,255,255,255,11,0,0,0,3,255,255,255,6,255,0, + 0,4,255,255,255,17,0,0,255,7,255,255,255,9,0,0,255,1,255,255, + 255,5,0,0,255,1,255,255,255,11,0,0,0,3,255,255,255,7,255,0, + 0,2,255,255,255,19,0,0,255,5,255,255,255,11,0,0,255,1,255,255, + 255,3,0,0,255,1,255,255,255,13,0,0,0,1,255,255,255,30,0,0, + 255,3,255,255,255,13,0,0,255,3,255,255,255,78,0,0,0,1,255,255, + 255,62,0,0,0,3,255,255,255,62,0,0,0,1,255,255,255,154,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,197,0,1,0,53,0,1,0,32,0,1,0,53, + 0,1,0,197,0,1,255,255,255,11,0,196,0,1,0,8,0,1,0,217, + 0,3,255,255,255,11,0,62,0,1,0,18,0,1,0,30,0,1,0,49, + 0,1,0,176,0,1,255,255,255,11,0,144,0,1,0,54,0,1,0,34, + 0,1,0,31,0,1,0,151,0,1,255,255,255,11,0,88,0,1,0,128, + 0,1,0,217,0,1,0,133,0,1,0,89,0,1,255,255,255,11,0,22, + 0,1,0,7,0,1,0,217,0,3,255,255,255,11,0,54,0,1,0,193, + 0,1,0,217,0,1,0,162,0,1,0,38,0,1,255,255,255,11,0,217, + 0,3,0,182,0,1,0,20,0,1,255,255,255,11,0,31,0,1,0,200, + 0,1,0,217,0,1,0,204,0,1,0,32,0,1,255,255,255,11,0,217, + 0,1,0,13,0,1,0,217,0,3,255,255,255,11,0,217,0,3,0,214, + 0,1,0,14,0,1,255,255,255,11,0,217,0,2,0,214,0,1,0,132, + 0,1,0,68,0,1,255,255,255,11,0,12,0,1,0,217,0,3,0,15, + 0,1,255,255,255,11,0,217,0,1,0,13,0,1,0,217,0,3,255,255, + 255,11,0,217,0,3,0,151,0,1,0,59,0,1,255,255,255,11,0,217, + 0,2,0,24,0,1,0,61,0,1,0,195,0,1,255,255,255,11,0,12, + 0,1,0,217,0,3,0,14,0,1,255,255,255,11,0,217,0,1,0,13, + 0,1,0,217,0,3,255,255,255,11,0,217,0,2,0,185,0,1,0,27, + 0,1,0,174,0,1,255,255,255,11,0,217,0,2,0,215,0,1,0,132, + 0,1,0,49,0,1,255,255,255,11,0,31,0,1,0,203,0,1,0,217, + 0,1,0,204,0,1,0,31,0,1,255,255,255,11,0,217,0,1,0,13, + 0,1,0,217,0,3,255,255,255,11,0,217,0,1,0,168,0,1,0,33, + 0,1,0,162,0,1,0,217,0,1,255,255,255,11,0,217,0,3,0,216, + 0,1,0,14,0,1,255,255,255,11,0,88,0,1,0,132,0,1,0,217, + 0,1,0,134,0,1,0,89,0,1,255,255,255,11,0,217,0,1,0,13, + 0,1,0,217,0,3,255,255,255,11,0,128,0,1,0,44,0,1,0,187, + 0,1,0,217,0,2,255,255,255,11,0,66,0,1,0,193,0,1,0,217, + 0,1,0,145,0,1,0,55,0,1,255,255,255,11,0,197,0,1,0,52, + 0,1,0,32,0,1,0,53,0,1,0,197,0,1,255,255,255,11,0,43, + 0,1,0,3,0,1,0,43,0,2,0,217,0,1,255,255,255,11,0,0, + 0,1,0,26,0,1,0,33,0,3,255,255,255,11,0,67,0,1,0,18, + 0,1,0,31,0,1,0,56,0,1,0,190,0,1,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,2,0,151, + 0,1,0,4,0,1,0,217,0,1,255,255,255,11,0,7,0,1,0,33, + 0,2,0,39,0,1,0,217,0,1,255,255,255,11,0,217,0,1,0,123, + 0,1,0,33,0,2,0,211,0,1,255,255,255,11,0,33,0,4,0,3, + 0,1,255,255,255,11,0,217,0,1,0,191,0,1,0,48,0,1,0,8, + 0,1,0,217,0,1,255,255,255,11,0,9,0,1,0,217,0,4,255,255, + 255,11,0,147,0,1,0,53,0,1,0,206,0,1,0,217,0,2,255,255, + 255,11,0,217,0,3,0,180,0,1,0,43,0,1,255,255,255,11,0,213, + 0,1,0,54,0,1,0,177,0,1,0,9,0,1,0,217,0,1,255,255, + 255,11,0,9,0,1,0,217,0,4,255,255,255,11,0,57,0,1,0,169, + 0,1,0,217,0,3,255,255,255,11,0,217,0,3,0,73,0,1,0,146, + 0,1,255,255,255,11,0,95,0,1,0,129,0,1,0,217,0,1,0,9, + 0,1,0,217,0,1,255,255,255,11,0,9,0,1,0,32,0,1,0,44, + 0,1,0,170,0,1,0,217,0,1,255,255,255,11,0,19,0,1,0,71, + 0,1,0,34,0,1,0,48,0,1,0,178,0,1,255,255,255,11,0,217, + 0,2,0,183,0,1,0,36,0,1,0,215,0,1,255,255,255,10,184,184, + 184,1,0,76,0,1,0,217,0,2,0,9,0,1,0,217,0,1,255,255, + 255,11,0,213,0,1,0,217,0,1,0,169,0,1,0,39,0,1,0,217, + 0,1,255,255,255,11,0,11,0,1,0,191,0,1,0,217,0,1,0,153, + 0,1,0,43,0,1,255,255,255,11,0,217,0,2,0,77,0,1,0,137, + 0,1,0,217,0,1,255,255,255,10,149,149,149,1,0,30,0,1,0,33, + 0,2,0,1,0,1,0,33,0,1,249,249,249,1,255,255,255,10,0,217, + 0,2,0,216,0,1,0,14,0,1,0,217,0,1,255,255,255,11,0,26, + 0,1,0,209,0,1,0,217,0,1,0,216,0,1,0,14,0,1,255,255, + 255,11,0,217,0,1,0,186,0,1,0,31,0,1,0,214,0,1,0,217, + 0,1,255,255,255,11,0,217,0,3,0,9,0,1,0,217,0,1,255,255, + 255,11,0,141,0,1,0,217,0,1,0,154,0,1,0,52,0,1,0,217, + 0,1,255,255,255,11,0,86,0,1,0,127,0,1,0,217,0,1,0,157, + 0,1,0,55,0,1,255,255,255,11,0,217,0,1,0,81,0,1,0,129, + 0,1,0,217,0,2,255,255,255,11,0,217,0,3,0,9,0,1,0,217, + 0,1,255,255,255,11,0,54,0,1,0,30,0,1,0,36,0,1,0,180, + 0,1,0,217,0,1,255,255,255,11,0,201,0,1,0,57,0,1,0,31, + 0,1,0,49,0,1,0,188,0,1,255,255,255,11,0,189,0,1,0,26, + 0,1,0,211,0,1,0,217,0,2,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,27,0,255, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,27,0,255,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,27,0,255,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,27,0,255,0,5,255,255,255,11,0,168, + 0,1,0,42,0,1,0,31,0,1,0,37,0,1,0,161,0,1,255,255, + 255,11,0,188,0,1,0,50,0,1,0,31,0,1,0,60,0,1,0,200, + 0,1,255,255,255,12,232,248,232,1,62,197,62,1,38,189,38,1,62,197, + 62,1,232,248,232,1,255,255,255,10,0,232,0,1,0,62,0,1,0,38, + 0,1,0,62,0,1,0,232,0,1,255,255,255,11,0,30,0,1,0,180, + 0,1,0,217,0,1,0,174,0,1,0,26,0,1,255,255,255,11,0,54, + 0,1,0,151,0,1,0,217,0,1,0,130,0,1,0,84,0,1,255,255, + 255,12,103,209,103,1,150,223,150,1,255,255,255,1,156,225,156,1,105,210, + 105,1,255,255,255,10,0,103,0,1,0,150,0,1,0,255,0,1,0,156, + 0,1,0,105,0,1,255,255,255,11,0,31,0,1,0,174,0,1,0,217, + 0,1,0,203,0,1,0,33,0,1,255,255,255,11,0,11,0,1,0,214, + 0,1,0,217,0,1,0,210,0,1,0,26,0,1,255,255,255,12,37,189, + 37,1,235,249,235,1,255,255,255,1,240,250,240,1,38,189,38,1,255,255, + 255,10,0,37,0,1,0,235,0,1,0,255,0,1,0,240,0,1,0,38, + 0,1,255,255,255,11,0,156,0,1,0,5,0,1,0,66,0,1,0,58, + 0,1,0,148,0,1,255,255,255,11,0,42,0,1,0,151,0,1,0,217, + 0,1,0,195,0,1,0,14,0,1,255,255,255,12,14,182,14,1,255,255, + 255,3,18,183,18,1,255,255,255,10,0,14,0,1,0,255,0,3,0,18, + 0,1,255,255,255,11,0,86,0,1,0,147,0,1,0,173,0,1,0,69, + 0,1,0,77,0,1,255,255,255,11,0,178,0,1,0,49,0,1,0,35, + 0,1,0,73,0,1,0,21,0,1,255,255,255,12,14,182,14,1,255,255, + 255,3,17,183,17,1,255,255,255,10,0,14,0,1,0,255,0,3,0,17, + 0,1,255,255,255,11,0,14,0,1,0,214,0,1,0,217,0,1,0,211, + 0,1,0,11,0,1,255,255,255,11,0,217,0,3,0,173,0,1,0,61, + 0,1,255,255,255,12,36,189,36,1,239,250,239,1,255,255,255,1,240,250, + 240,1,37,189,37,1,255,255,255,10,0,36,0,1,0,239,0,1,0,255, + 0,1,0,240,0,1,0,37,0,1,255,255,255,11,0,39,0,1,0,147, + 0,1,0,217,0,1,0,166,0,1,0,40,0,1,255,255,255,11,0,217, + 0,2,0,208,0,1,0,57,0,1,0,148,0,1,255,255,255,12,103,209, + 103,1,155,225,155,1,255,255,255,1,158,226,158,1,104,209,104,1,255,255, + 255,10,0,103,0,1,0,155,0,1,0,255,0,1,0,158,0,1,0,104, + 0,1,255,255,255,11,0,174,0,1,0,41,0,1,0,28,0,1,0,46, + 0,1,0,179,0,1,255,255,255,11,0,214,0,1,0,34,0,2,0,125, + 0,1,0,217,0,1,255,255,255,12,231,248,231,1,61,196,61,1,38,189, + 38,1,62,197,62,1,232,248,232,1,255,255,255,10,0,231,0,1,0,61, + 0,1,0,38,0,1,0,62,0,1,0,232,0,1,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,27,0,255,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,27,0,255, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,27,0,255,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,27,0,255,0,5,255,255,255,6,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0, + 0,0,0,14,0,0,0,14,0,14,0,14,0,0,0,31,0,17,0,14, + 24,0,128,63,128,32,0,14,60,0,128,63,128,32,0,14,60,0,128,63, + 128,32,0,14,24,0,0,31,0,17,0,4,0,0,0,14,0,14,0,0, + 0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,14,0,0,0,0, + 0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,240,3,224,3,224,3, + 224,3,240,7,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,0,0,224,3,224,3,224,3,0,0,224,3,224,3,224,3,0,0, + 224,3,224,3,224,3,0,0,224,3,224,3,224,3,192,7,224,3,224,3, + 224,3,192,6,224,3,224,3,224,3,192,6,224,3,224,3,224,3,64,4, + 224,3,224,3,224,3,64,4,224,3,224,3,224,3,192,6,224,3,224,3, + 224,3,192,6,224,3,224,3,224,3,192,7,224,3,224,3,224,3,0,0, + 224,3,224,3,224,3,0,0,224,3,224,3,224,3,0,0,224,3,224,3, + 224,3,0,0,224,3,0,0,19,116,102,105,108,101,99,104,97,110,103,101, + 110,111,116,105,102,121,101,114,18,102,105,108,101,99,104,97,110,103,101,110, + 111,116,105,102,121,101,114,13,111,110,102,105,108,101,99,104,97,110,103,101, + 100,7,13,111,110,102,105,108,101,99,104,97,110,103,101,100,4,108,101,102, + 116,2,32,3,116,111,112,3,168,0,0,0,7,116,97,99,116,105,111,110, + 15,110,97,118,105,103,102,111,114,119,97,114,100,97,99,116,5,115,116,97, + 116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,0,9,111,110,101, + 120,101,99,117,116,101,7,12,110,97,118,105,103,102,111,114,119,97,114,100, + 4,108,101,102,116,2,32,3,116,111,112,2,16,2,115,99,1,2,1,3, + 72,96,0,0,0,7,116,97,99,116,105,111,110,12,110,97,118,105,103,98, + 97,99,107,97,99,116,5,115,116,97,116,101,11,11,97,115,95,100,105,115, + 97,98,108,101,100,0,9,111,110,101,120,101,99,117,116,101,7,9,110,97, + 118,105,103,98,97,99,107,4,108,101,102,116,2,32,3,116,111,112,2,40, + 2,115,99,1,2,1,3,72,64,0,0,0,10,116,112,111,112,117,112,109, + 101,110,117,9,102,111,114,109,112,111,112,117,112,8,111,110,117,112,100,97, + 116,101,7,14,112,111,112,117,112,109,111,110,117,112,100,97,116,101,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,30,18, + 109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1, + 6,97,99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,115, + 101,108,101,99,116,101,100,105,116,112,97,103,101,7,99,97,112,116,105,111, + 110,6,11,83,101,108,101,99,116,32,80,97,103,101,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,12,100,111,115,101,108,101,99,116,112,97,103,101, + 0,1,6,97,99,116,105,111,110,7,20,97,99,116,105,111,110,115,109,111, + 46,111,112,101,110,115,111,117,114,99,101,7,99,97,112,116,105,111,110,6, + 10,38,79,112,101,110,32,70,105,108,101,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,6,97,99, + 116,105,111,110,7,15,97,99,116,105,111,110,115,109,111,46,99,108,111,115, + 101,7,99,97,112,116,105,111,110,6,11,38,67,108,111,115,101,32,70,105, + 108,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95, + 115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95, + 97,115,121,110,99,101,120,101,99,117,116,101,0,0,1,6,97,99,116,105, + 111,110,7,14,97,99,116,105,111,110,115,109,111,46,115,97,118,101,7,99, + 97,112,116,105,111,110,6,10,38,83,97,118,101,32,70,105,108,101,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115, + 109,111,46,115,97,118,101,97,115,0,1,7,99,97,112,116,105,111,110,6, + 12,83,104,111,119,32,97,115,32,70,111,114,109,4,110,97,109,101,6,10, + 115,104,111,119,97,115,102,111,114,109,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117, + 116,101,7,13,115,104,111,119,97,115,102,111,114,109,101,120,101,0,1,7, + 111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116, + 111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105, + 111,110,0,0,1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110, + 115,109,111,46,100,101,108,101,116,101,0,1,6,97,99,116,105,111,110,7, + 13,97,99,116,105,111,110,115,109,111,46,99,117,116,0,1,6,97,99,116, + 105,111,110,7,14,97,99,116,105,111,110,115,109,111,46,99,111,112,121,0, + 1,6,97,99,116,105,111,110,7,22,97,99,116,105,111,110,115,109,111,46, + 99,111,112,121,108,97,116,101,120,97,99,116,0,1,6,97,99,116,105,111, + 110,7,15,97,99,116,105,111,110,115,109,111,46,112,97,115,116,101,0,1, + 6,97,99,116,105,111,110,7,19,97,99,116,105,111,110,115,109,111,46,115, + 101,108,101,99,116,97,108,108,0,1,7,111,112,116,105,111,110,115,11,13, + 109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116, + 105,111,110,7,14,97,99,116,105,111,110,115,109,111,46,117,110,100,111,0, + 1,6,97,99,116,105,111,110,7,14,97,99,116,105,111,110,115,109,111,46, + 114,101,100,111,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95, + 115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99, + 117,116,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109,101,110,117, + 46,99,111,117,110,116,2,8,13,115,117,98,109,101,110,117,46,105,116,101, + 109,115,14,1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115, + 109,111,46,105,110,100,101,110,116,0,1,6,97,99,116,105,111,110,7,18, + 97,99,116,105,111,110,115,109,111,46,117,110,105,110,100,101,110,116,0,1, + 6,97,99,116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46,99, + 111,109,109,101,110,116,0,1,6,97,99,116,105,111,110,7,19,97,99,116, + 105,111,110,115,109,111,46,117,110,99,111,109,109,101,110,116,0,1,6,97, + 99,116,105,111,110,7,19,97,99,116,105,111,110,115,109,111,46,108,111,119, + 101,114,99,97,115,101,0,1,6,97,99,116,105,111,110,7,19,97,99,116, + 105,111,110,115,109,111,46,117,112,112,101,114,99,97,115,101,0,1,6,97, + 99,116,105,111,110,7,20,97,99,116,105,111,110,115,109,111,46,116,97,98, + 116,111,115,112,97,99,101,0,1,7,99,97,112,116,105,111,110,6,25,67, + 111,110,118,101,114,116,32,116,111,32,38,80,97,115,99,97,108,32,115,116, + 114,105,110,103,4,110,97,109,101,6,7,99,111,110,118,112,97,115,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 9,111,110,101,120,101,99,117,116,101,7,9,99,111,110,118,112,97,115,101, + 120,0,0,7,99,97,112,116,105,111,110,6,17,38,77,111,100,105,102,121, + 32,83,101,108,101,99,116,105,111,110,4,110,97,109,101,6,15,109,111,100, + 105,102,121,115,101,108,101,99,116,105,111,110,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,20,97,99,116,105,111,110,115, + 109,111,46,116,111,103,103,108,101,98,107,112,116,0,1,6,97,99,116,105, + 111,110,7,26,97,99,116,105,111,110,115,109,111,46,116,111,103,103,108,101, + 98,107,112,116,101,110,97,98,108,101,0,1,7,99,97,112,116,105,111,110, + 6,16,38,69,100,105,116,32,98,114,101,97,107,112,111,105,110,116,4,110, + 97,109,101,6,14,101,100,105,116,98,114,101,97,107,112,111,105,110,116,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116, + 99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99, + 101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,18, + 101,100,105,116,98,114,101,97,107,112,111,105,110,116,101,120,101,99,0,1, + 7,99,97,112,116,105,111,110,6,20,65,100,100,32,38,87,97,116,99,104, + 32,97,116,32,67,117,114,115,111,114,4,110,97,109,101,6,8,97,100,100, + 119,97,116,99,104,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,20,97, + 100,100,119,97,116,99,104,97,99,116,111,110,101,120,101,99,117,116,101,0, + 1,13,115,117,98,109,101,110,117,46,99,111,117,110,116,2,11,13,115,117, + 98,109,101,110,117,46,105,116,101,109,115,14,1,6,97,99,116,105,111,110, + 7,16,97,99,116,105,111,110,115,109,111,46,115,101,116,98,109,48,0,1, + 6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115,109,111,46,115, + 101,116,98,109,49,0,1,6,97,99,116,105,111,110,7,16,97,99,116,105, + 111,110,115,109,111,46,115,101,116,98,109,50,0,1,6,97,99,116,105,111, + 110,7,16,97,99,116,105,111,110,115,109,111,46,115,101,116,98,109,51,0, + 1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115,109,111,46, + 115,101,116,98,109,52,0,1,6,97,99,116,105,111,110,7,16,97,99,116, + 105,111,110,115,109,111,46,115,101,116,98,109,53,0,1,6,97,99,116,105, + 111,110,7,16,97,99,116,105,111,110,115,109,111,46,115,101,116,98,109,54, + 0,1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115,109,111, + 46,115,101,116,98,109,55,0,1,6,97,99,116,105,111,110,7,16,97,99, + 116,105,111,110,115,109,111,46,115,101,116,98,109,56,0,1,6,97,99,116, + 105,111,110,7,16,97,99,116,105,111,110,115,109,111,46,115,101,116,98,109, + 57,0,1,6,97,99,116,105,111,110,7,19,97,99,116,105,111,110,115,109, + 111,46,115,101,116,98,109,110,111,110,101,0,0,7,99,97,112,116,105,111, + 110,6,12,83,101,116,32,66,111,111,107,109,97,114,107,4,110,97,109,101, + 6,5,115,101,116,98,109,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109,101,110, + 117,46,99,111,117,110,116,2,10,13,115,117,98,109,101,110,117,46,105,116, + 101,109,115,14,1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110, + 115,109,111,46,102,105,110,100,98,109,48,0,1,6,97,99,116,105,111,110, + 7,17,97,99,116,105,111,110,115,109,111,46,102,105,110,100,98,109,49,0, + 1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46, + 102,105,110,100,98,109,50,0,1,6,97,99,116,105,111,110,7,17,97,99, + 116,105,111,110,115,109,111,46,102,105,110,100,98,109,51,0,1,6,97,99, + 116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46,102,105,110,100, + 98,109,52,0,1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110, + 115,109,111,46,102,105,110,100,98,109,53,0,1,6,97,99,116,105,111,110, + 7,17,97,99,116,105,111,110,115,109,111,46,102,105,110,100,98,109,54,0, + 1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46, + 102,105,110,100,98,109,55,0,1,6,97,99,116,105,111,110,7,17,97,99, + 116,105,111,110,115,109,111,46,102,105,110,100,98,109,56,0,1,6,97,99, + 116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46,102,105,110,100, + 98,109,57,0,0,7,99,97,112,116,105,111,110,6,13,70,105,110,100,32, + 66,111,111,107,109,97,114,107,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,0,0,1,7,111,112,116,105,111, + 110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97, + 111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1, + 7,99,97,112,116,105,111,110,6,11,73,110,115,101,114,116,32,71,85,73, + 68,4,110,97,109,101,6,6,105,110,115,103,117,105,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,10,105,110,115,103,117,105,101,120,101,99,0,1, + 7,99,97,112,116,105,111,110,6,10,73,110,115,101,114,116,32,85,73,68, + 4,110,97,109,101,6,6,105,110,115,117,105,100,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120, + 101,99,117,116,101,7,10,105,110,115,117,105,100,101,120,101,99,0,1,6, + 97,99,116,105,111,110,7,21,97,99,116,105,111,110,115,109,111,46,105,110, + 115,116,101,109,112,108,97,116,101,7,99,97,112,116,105,111,110,6,15,73, + 110,115,101,114,116,32,84,101,109,112,108,97,116,101,4,110,97,109,101,6, + 8,105,110,115,116,101,109,112,108,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105, + 111,110,7,16,99,111,109,112,108,101,116,101,99,108,97,115,115,97,99,116, + 7,99,97,112,116,105,111,110,6,24,67,111,109,112,108,101,116,101,32,67, + 108,97,115,115,32,97,116,32,67,117,114,115,111,114,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,0, + 4,108,101,102,116,3,176,0,3,116,111,112,2,40,0,0,7,116,97,99, + 116,105,111,110,16,99,111,109,112,108,101,116,101,99,108,97,115,115,97,99, + 116,7,99,97,112,116,105,111,110,6,24,67,111,109,112,108,101,116,101,32, + 99,108,97,115,115,32,97,116,32,99,117,114,115,111,114,9,111,110,101,120, + 101,99,117,116,101,7,20,99,111,109,112,108,101,116,101,99,108,97,115,115, + 101,120,101,99,117,116,101,4,108,101,102,116,2,32,3,116,111,112,3,208, + 0,2,115,99,1,2,1,3,65,96,0,0,0,16,116,115,116,114,105,110, + 103,99,111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115, + 46,100,97,116,97,1,6,6,70,105,108,101,32,34,6,14,34,32,104,97, + 115,32,99,104,97,110,103,101,100,46,6,44,84,104,101,114,101,32,97,114, + 101,32,109,111,100,105,102,105,99,97,116,105,111,110,115,32,105,110,32,101, + 100,105,116,32,98,117,102,102,101,114,32,97,108,115,111,46,6,32,68,111, + 32,121,111,117,32,119,105,115,104,32,116,111,32,114,101,108,111,97,100,32, + 102,114,111,109,32,100,105,115,107,63,6,12,67,111,110,102,105,114,109,97, + 116,105,111,110,6,6,60,110,111,110,101,62,6,23,68,111,32,121,111,117, + 32,119,105,115,104,32,116,111,32,114,101,112,108,97,99,101,58,6,5,119, + 105,116,104,58,6,5,60,110,101,119,62,6,14,83,121,110,116,97,120,100, + 101,102,102,105,108,101,58,6,4,84,101,120,116,6,10,110,111,116,32,102, + 111,117,110,100,46,6,27,82,101,115,116,97,114,116,32,102,114,111,109,32, + 98,101,103,105,110,32,111,102,32,102,105,108,101,63,6,7,67,97,110,99, + 101,108,63,6,41,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32, + 116,111,32,114,101,112,108,97,99,101,32,116,104,105,115,32,111,99,99,117, + 114,101,110,99,101,63,6,18,71,111,32,116,111,32,108,105,110,101,32,110, + 117,109,98,101,114,58,6,9,70,105,110,100,32,108,105,110,101,6,44,84, + 104,101,114,101,32,97,114,101,32,109,111,100,105,102,105,99,97,116,105,111, + 110,115,32,105,110,32,101,100,105,116,32,98,117,102,102,101,114,32,97,108, + 115,111,46,6,25,82,101,115,116,97,114,116,32,102,114,111,109,32,101,110, + 100,32,111,102,32,102,105,108,101,63,0,4,108,101,102,116,3,176,0,3, + 116,111,112,2,104,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsourcefo,''); +end. diff --git a/mseide-msegui/apps/ide/sourcehintform.mfm b/mseide-msegui/apps/ide/sourcehintform.mfm new file mode 100644 index 0000000..3dbc793 --- /dev/null +++ b/mseide-msegui/apps/ide/sourcehintform.mfm @@ -0,0 +1,24 @@ +object sourcehintfo: tsourcehintfo + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 100 + bounds_y = 291 + bounds_cx = 314 + bounds_cy = 214 + container.frame.framei_left = 0 + container.frame.framei_top = 0 + container.frame.framei_right = 0 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + container.bounds = ( + 0 + 0 + 314 + 214 + ) + optionswindow = [wo_message] + options = [fo_freeonclose, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + onclose = sourcehintfoonclose + onresize = formonresize + moduleclassname = 'tmseform' +end diff --git a/mseide-msegui/apps/ide/sourcehintform.pas b/mseide-msegui/apps/ide/sourcehintform.pas new file mode 100644 index 0000000..dbfdf8b --- /dev/null +++ b/mseide-msegui/apps/ide/sourcehintform.pas @@ -0,0 +1,56 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit sourcehintform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,mseedit,msegraphutils; + +type + stringeditarty = array of tedit; + tsourcehintfo = class(tmseform) + procedure sourcehintfoonclose(const sender: TObject); + procedure formonresize(const sender: TObject); + public + dispar: stringeditarty; + end; + +implementation +uses + sourceform,sourcehintform_mfm; + +procedure tsourcehintfo.sourcehintfoonclose(const sender: TObject); +begin + sourcefo.hintsize:= size; +end; + +procedure tsourcehintfo.formonresize(const sender: TObject); +var + int1,int3: integer; +begin + int3:= 0; + for int1:= 0 to high(dispar) do begin + dispar[int1].clientheight:= dispar[int1].editor.textrect.cy + 2; + inc(int3,dispar[int1].bounds_cy); + end; + placeyorder(0,[0],widgetarty(dispar)); + bounds_cymax:= int3; +end; + +end. diff --git a/mseide-msegui/apps/ide/sourcehintform_mfm.pas b/mseide-msegui/apps/ide/sourcehintform_mfm.pas new file mode 100644 index 0000000..c690c79 --- /dev/null +++ b/mseide-msegui/apps/ide/sourcehintform_mfm.pas @@ -0,0 +1,49 @@ +unit sourcehintform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,sourcehintform; + +const + objdata: record size: integer; data: array[0..627] of byte end = + (size: 628; data: ( + 84,80,70,48,13,116,115,111,117,114,99,101,104,105,110,116,102,111,12,115, + 111,117,114,99,101,104,105,110,116,102,111,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117,115,13,111, + 119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110, + 0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 100,8,98,111,117,110,100,115,95,121,3,35,1,9,98,111,117,110,100,115, + 95,99,120,3,58,1,9,98,111,117,110,100,115,95,99,121,3,214,0,27, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102,114,97,109, + 101,105,95,108,101,102,116,2,0,26,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,102,114,97,109,101,105,95,116,111,112,2,0,28,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102,114,97,109,101, + 105,95,114,105,103,104,116,2,0,29,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2, + 0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,102,105,108,101,102,116, + 9,102,114,108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103, + 104,116,12,102,114,108,95,102,105,98,111,116,116,111,109,0,16,99,111,110, + 116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,58, + 1,3,214,0,0,13,111,112,116,105,111,110,115,119,105,110,100,111,119,11, + 10,119,111,95,109,101,115,115,97,103,101,0,7,111,112,116,105,111,110,115, + 11,14,102,111,95,102,114,101,101,111,110,99,108,111,115,101,13,102,111,95, + 99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101, + 97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115, + 116,97,116,10,102,111,95,115,97,118,101,112,111,115,12,102,111,95,115,97, + 118,101,115,116,97,116,101,0,7,111,110,99,108,111,115,101,7,19,115,111, + 117,114,99,101,104,105,110,116,102,111,111,110,99,108,111,115,101,8,111,110, + 114,101,115,105,122,101,7,12,102,111,114,109,111,110,114,101,115,105,122,101, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109, + 115,101,102,111,114,109,0,0) + ); + +initialization + registerobjectdata(@objdata,tsourcehintfo,''); +end. diff --git a/mseide-msegui/apps/ide/sourcepage.mfm b/mseide-msegui/apps/ide/sourcepage.mfm new file mode 100644 index 0000000..e1eebc6 --- /dev/null +++ b/mseide-msegui/apps/ide/sourcepage.mfm @@ -0,0 +1,169 @@ +object sourcepage: tsourcepage + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + optionsskin = [osk_framebuttononly] + color = -1879048187 + bounds_x = 192 + bounds_y = 245 + bounds_cx = 311 + bounds_cy = 228 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 311 + 228 + ) + icon.transparentcolor = -2147483648 + oncreate = sourcefooncreate + oneventloopstart = sourcefoonloaded + ondestroy = sourcefoondestroy + onshow = sourcefoonshow + onhide = sourcefoondeactivate + moduleclassname = 'ttabform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 311 + bounds_cy = 206 + anchors = [an_top, an_bottom] + optionsgrid = [og_focuscellonenter, og_autofirstrow, og_wrapcol, og_visiblerowpagestep] + fixcols.count = 1 + fixcols.items = < + item + color = -1610612731 + linewidth = 0 + textflags = [tf_right, tf_ycentered] + numstart = 1 + numstep = 1 + font.color = -1610612733 + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_color, flp_xscale] + end> + gridframecolor = -2147483645 + rowcolors.count = 4 + rowcolors.items = ( + 14745599 + 65535 + 16711680 + -2147483646 + ) + datacols.count = 2 + datacols.items = < + item[dataicon] + linecolor = -1610612732 + width = 15 + options = [co_nofocus, co_nohscroll] + oncellevent = icononcellevent + widgetname = 'dataicon' + dataclass = tgridintegerdatalist + end + item[edit] + width = 2000 + options = [co_leftbuttonfocusonly, co_middlebuttonfocus, co_savestate, co_mousescrollrow] + onchange = textchanged + widgetname = 'edit' + dataclass = tgridrichstringdatalist + end> + datarowlinewidth = 0 + datarowheight = 18 + onrowsinserted = gridonrowsinserted + onrowsdeleted = gridonrowsdeleted + oncellevent = gridoncellevent + reffontheight = 16 + object edit: tsyntaxedit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 2000 + bounds_cy = 18 + font.name = 'mseide_source' + font.xscale = 1 + font.localprops = [flp_xscale] + optionsedit1 = [oe1_noselectall, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_eatreturn, oe_exitoncursor, oe_nofirstarrownavig] + tabulators.ppmm = 3 + tabulators.defaultdist = 0 + onkeydown = editonkeydown + onfontchanged = editonfontchanged + onmodifiedchanged = editonmodifiedchanged + ontextmouseevent = editontextmouseevent + oneditnotifcation = editoneditnotification + oncellevent = editoncellevent + maxundocount = 10000 + reffontheight = 18 + end + object dataicon: tdataicon + optionsskin = [osk_framebuttononly] + bounds_x = 50 + bounds_y = 0 + bounds_cx = 15 + bounds_cy = 18 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + options = [bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey] + visible = False + valuedefault = -2147483648 + min = -1 + max = 2 + imagenums.count = 14 + imagenums.items = ( + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + ) + end + end + object linedisp: tstringedit + optionsskin = [osk_framebuttononly] + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -2147483645 + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 207 + bounds_cx = 68 + anchors = [an_left, an_bottom] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + textflags = [tf_xcentered, tf_ycentered] + textflagsactive = [tf_xcentered, tf_ycentered] + reffontheight = 16 + end + object pathdisp: tstringedit + optionsskin = [osk_framebuttononly] + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -2147483645 + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 68 + bounds_y = 207 + bounds_cx = 243 + anchors = [an_left, an_right, an_bottom] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_caretonreadonly, oe_focusrectonreadonly, oe_hintclippedtext] + textflags = [tf_ycentered, tf_ellipseleft] + reffontheight = 16 + end +end diff --git a/mseide-msegui/apps/ide/sourcepage.pas b/mseide-msegui/apps/ide/sourcepage.pas new file mode 100644 index 0000000..bd64b4a --- /dev/null +++ b/mseide-msegui/apps/ide/sourcepage.pas @@ -0,0 +1,1836 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit sourcepage; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msetextedit,msewidgetgrid,mseforms,classes,mclasses,msegdbutils, + msegraphedits,mseevent, + msehash,msebitmap,msetabs,msetypes,msedataedits, + mseglob,mseguiglob,msegui,msesyntaxedit,mseeditglob, + mseinplaceedit,msedispwidgets,msegraphutils,msegrids,breakpointsform, + pascaldesignparser,msefilechange,msestrings,mserichstring,mseparser, + msegridsglob,projectoptionsform; + + +type + sourcepageasynctagty = (spat_showasform,{spat_checkbracket,}spat_showsource); + + bookmarkty = record + row: integer; + bookmarknum: integer; + end; + bookmarkarty = array of bookmarkty; + + tsourcepage = class(ttabform) + grid: twidgetgrid; + edit: tsyntaxedit; + dataicon: tdataicon; + linedisp: tstringedit; + pathdisp: tstringedit; + procedure icononcellevent(const sender: tobject; var info: celleventinfoty); + procedure sourcefooncreate(const sender: tobject); + procedure sourcefoondestroy(const sender: tobject); + procedure editoncellevent(const sender: TObject; var info: celleventinfoty); + procedure editonmodifiedchanged(const sender: tobject; const value: boolean); + procedure editontextmouseevent(const sender: tobject; + var info: textmouseeventinfoty); + procedure editoneditnotification(const sender: tobject; + var info: editnotificationinfoty); + procedure gridonrowsdeleted(const sender: tcustomgrid; + const index,count: integer); + procedure gridonrowsinserted(const sender: tcustomgrid; + const index,count: integer); + procedure sourcefoonloaded(const sender: TObject); + procedure textchanged(const sender: tdatacol; const aindex: integer); + procedure sourcefoonshow(const sender: TObject); + procedure editonfontchanged(const sender: TObject); + procedure sourcefoondeactivate(const sender: TObject); + procedure gridoncellevent(const sender: TObject; var info: celleventinfoty); + procedure editonkeydown(const sender: twidget; var info: keyeventinfoty); + private + factiverow: integer; + flasthint: gridcoordty; + flasthintlength: integer; + fbackupcreated: boolean; + ffindpos: gridcoordty; + ffiletag: longword; + fsavetime: tdatetime; + fexecstamp: integer; + fgotoline: integer; + ffileloading: integer; + ffileloaderror: boolean; + frelpath: filenamety; + fshowsourcepos: sourceposty; + procedure setactiverow(const Value: integer); + procedure setgdb(agdb: tgdbmi); + procedure setfilepath(const value: filenamety); + function getfilename: filenamety; + function getfilepath: filenamety; + function getrelpath: filenamety; + procedure replace(all: boolean); + procedure showprocheaders(const apos: gridcoordty); + procedure showsourceitems(const apos: gridcoordty); + procedure showlink(const apos: gridcoordty); + procedure showsourcehint(const apos: gridcoordty; const values: stringarty); + procedure setsyntaxdef(const value: filenamety); + procedure updatelinedisp; + protected + finitialfilepath: filenamety; + finitialeditpos: gridcoordty; + finitialbookmarks: bookmarkarty; + fbracket1,fbracket2: gridcoordty; + procedure doasyncevent(var atag: integer); override; + procedure removebookmark(const bookmarknum: integer); + procedure beginupdate; + procedure endupdate; + function checkfilechanged: boolean; + public + filechanged: boolean; + ismoduletext: boolean; + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure loadfile(value: filenamety); overload; //no const! + procedure loadfile; overload; //loads if needed + function fileloaded: boolean; + procedure setbackupcreated; + procedure updatestatvalues; + procedure updatecaption(const modified: boolean); + procedure updatebreakpointicons; + procedure updatebreakpointicon(const info: bkptlineinfoty); + procedure togglebreakpoint(const arow: integer = -1); + procedure togglebreakpointenabled(const arow: integer = -1); + procedure cleardebuglines; + procedure updatedebuglines; + procedure hidehint; + procedure save(newname: filenamety); + function checksave(noconfirm,multiple: boolean): modalresultty; + function modified: boolean; + function source: trichstringdatalist; + procedure copywordatcursor(); + procedure doline; + procedure dofind; + procedure repeatfind; + procedure findback; + procedure doreplace; + procedure reload; + procedure doundo; + procedure doredo; + procedure inserttemplate; + procedure copylatex; + function cancomment(): boolean; + function canuncomment(): boolean; + procedure commentselection(); + procedure uncommentselection(); + function canchangenotify(const info: filechangeinfoty): boolean; + function getbreakpointstate(arow: integer = -1): bkptstatety; + //-1 -> current row + procedure setbreakpointstate(astate: bkptstatety; arow: integer = -1); + //-1 -> acurrent row + function findbookmark(const bookmarknum: integer): integer; + //returns row, -1 if not found + procedure setbookmark(arow: integer; const bookmarknum: integer); + //arow -1 -> current row, bookmarknum < 1 -> clear + procedure clearbookmark(const bookmarknum: integer); + function getbookmarks: bookmarkarty; + + property activerow: integer read factiverow write setactiverow; + property gdb: tgdbmi write setgdb; + property filename: filenamety read getfilename; + property relpath: filenamety read getrelpath write frelpath; + property filepath: filenamety read getfilepath write setfilepath; + property filetag: longword read ffiletag; + end; + +function getpascalvarname(const edit: tsyntaxedit; pos: gridcoordty; + out startpos: gridcoordty): msestring; overload; +function getpascalvarname(const edit: tsyntaxedit; + const pos: pointty): msestring; overload; +procedure findintextedit(const edit: tcustomtextedit; var info: findinfoty; + var findpos: gridcoordty; const backward: boolean = false); +implementation +uses + sourcepage_mfm,msefileutils,sourceform,main, + sysutils,msewidgets,finddialogform,replacedialogform,msekeyboard, + sourceupdate,msefiledialog,mseintegerenter,msedesigner,mseformatstr, + msesys,make,actionsmodule,msegraphics,sourcehintform, + mseedit,msedrawtext,msebits,msearrayutils,msestream,msedesignintf, + msesysutils,msedesignparser,msesyntaxpainter,msemacros,msecodetemplates, + mselatex,msesystypes; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + pascaldelims = msestring(' :;+-*/(){},=<>' + c_linefeed + c_return + c_tab); + selectdelims = pascaldelims+'.[]''"'; + nodelimstrings: array[0..0] of msestring = ('->'); //for c + bmbitshift = 4; + bmbitmask = integer($3ff0); + findshowpos = cep_rowcentered; + +function getpascalvarname(const edit: tsyntaxedit; pos: gridcoordty; + out startpos: gridcoordty): msestring; +var + int1: integer; +begin + startpos:= edit.wordatpos(pos,result,pascaldelims,nodelimstrings); + if (result = '') and (pos.col > 0) then begin + dec(pos.col); + startpos:= edit.wordatpos(pos,result,pascaldelims,nodelimstrings); + end; + if result <> '' then begin + for int1:= pos.col - startpos.col + 1 to length(result) do begin + if (result[int1] = '.') or (result[int1] = '-') and (result[int1+1] = '>') then begin + setlength(result,int1-1); + break; + end; + end; + end; +end; + +function getpascalvarname(const edit: tsyntaxedit; const pos: pointty): msestring; +var + po1,po2: gridcoordty; +begin + if edit.mousepostotextpos(pos,po1,true) then begin + result:= getpascalvarname(edit,po1,po2); + end + else begin + result:= ''; + end; +end; + +{ tsourcepage } + +constructor tsourcepage.create(aowner: tcomponent); +begin + factiverow:= -1; + fgotoline:= 1; + fbracket1:= invalidcell; + fbracket2:= invalidcell; + inherited create(aowner); + updatestatvalues; +end; + +destructor tsourcepage.destroy; +begin + inherited; +end; + +procedure tsourcepage.doasyncevent(var atag: integer); +var + mstr1: filenamety; + po1: pmoduleinfoty; +begin + case sourcepageasynctagty(atag) of + spat_showasform: begin + mstr1:= filepath; + if sourcefo.closepage(self) then begin + po1:= mainfo.openformfile(mstr1,true,true,false,true,false); + if po1 <> nil then begin + po1^.backupcreated:= fbackupcreated; + designer.modulechanged(po1); + end; + end; + end; +{ + spat_checkbracket: begin + dec(fbracketchecking); + checkbrackets; + end; +} + spat_showsource: begin + sourcefo.naviglist.showsource(fshowsourcepos,true); + end; + end; +end; + +procedure tsourcepage.sourcefoonloaded(const sender: TObject); +begin + updatestatvalues; + grid.bottom:= linedisp.top - 1; +end; + +procedure tsourcepage.textchanged(const sender: tdatacol; + const aindex: integer); +begin + sourcechanged(edit.filename); +end; + +procedure tsourcepage.updatecaption(const modified: boolean); +var + str1: filenamety; +begin + if ffileloading > 0 then begin + exit; + end; + pathdisp.value:= finitialfilepath; + str1:= filename; + if str1 = '' then begin + str1:= sourcefo.c[ord(str_new)]; + end; + if modified then begin + caption:= '*'+str1; + sourcefo.textmodified(self); + end + else begin + caption:= str1; + end; + if isactivepage then begin + tsourcefo(tabwidget.parentofcontainer).updatecaption; + end; +end; + +procedure tsourcepage.updatebreakpointicon(const info: bkptlineinfoty); +var + int1: integer; +begin + with info do begin + int1:= line-1; + if (int1 >= 0) and (int1 <= grid.rowhigh) then begin + setbreakpointstate(state,int1); + end; + end; +end; + +procedure tsourcepage.updatebreakpointicons; +var + int1: integer; + ar1: bkptlineinfoarty; +begin + ar1:= breakpointsfo.getbreakpointlines(edit.filename); + for int1:= 0 to high(ar1) do begin + updatebreakpointicon(ar1[int1]); + end; +end; + +procedure tsourcepage.setsyntaxdef(const value: filenamety); +begin + try + edit.setsyntaxdef(value); + updatestatvalues; + except + on e: exception do begin + handleerror(e,ansistring(sourcefo.c[ord(syntaxdeffile)])); + end; + end; +end; + +procedure tsourcepage.loadfile(value: filenamety); +begin + inc(ffileloading); + try + edit.loadfromfile(value); + ismoduletext:= ismoduletext or (fileext(value) = formfileext); + finitialfilepath:= edit.filename; + setsyntaxdef(value); + updatebreakpointicons; + if mainfo.gdb.execloaded and actionsmo.bluedotsonact.checked then begin + updatedebuglines; + end; + finally + dec(ffileloading); + end; + updatecaption(false); +end; + +function tsourcepage.fileloaded: boolean; +begin + result:= (edit.filename = finitialfilepath) or (finitialfilepath = ''); +end; + +function tsourcepage.getfilepath: filenamety; +begin + result:= finitialfilepath; +end; + +function tsourcepage.getrelpath: filenamety; +begin + if fileloaded or (frelpath = '') then begin + result:= relativepath(finitialfilepath,projectoptions.projectdir); + end + else begin + result:= frelpath; + end; +end; + +function tsourcepage.getfilename: filenamety; +begin + result:= msefileutils.filename(finitialfilepath); +end; + +procedure tsourcepage.loadfile; //loads if needed +var + mstr1: filenamety; + int1: integer; +begin + if not fileloaded then begin + mstr1:= relpath; + if findfile(mstr1) then begin + mstr1:= msefileutils.filepath(mstr1); + end + else begin + mstr1:= finitialfilepath; + end; + setfilepath(mstr1); + sourcefo.filechangenotifyer.addnotification(finitialfilepath,filetag); + edit.editpos:= finitialeditpos; + for int1:= 0 to high(finitialbookmarks) do begin + with finitialbookmarks[int1] do begin + if (row >= 0) and (bookmarknum >= 0) and (row < grid.rowcount) and + (bookmarknum < 10) then begin + setbookmark(row,bookmarknum); + end; + end; + end; + end; +end; + +procedure tsourcepage.setfilepath(const value: filenamety); +begin + if edit.filename <> value then begin + fbackupcreated:= false; + ffiletag:= sourcefo.newfiletag; + loadfile(value); + end; +end; + +procedure tsourcepage.reload; +begin + loadfile(edit.filename); +end; + +procedure tsourcepage.cleardebuglines; +var + po1: pintegeraty; + int1: integer; +begin + if fexecstamp <> 0 then begin + fexecstamp:= 0; + po1:= dataicon.datalist.datapo; + for int1:= 0 to dataicon.datalist.count - 1 do begin + po1^[int1]:= po1^[int1] and (bmbitmask or integer($80000000)); + end; + dataicon.datalist.change(-1); +// dataicon.fillcol(integer($80000000)); + updatebreakpointicons; + end; +end; + +procedure tsourcepage.updatedebuglines; +var + ar1: integerarty; + ar2: qwordarty; + po1: pintegeraty; + int1,int2: integer; +begin + if mainfo.gdb.cancommand then begin + if fexecstamp <> mainfo.execstamp then begin + fexecstamp:= mainfo.execstamp; + application.beginwait; + if mainfo.gdb.listlines(edit.filename,ar1,ar2) = gdb_ok then begin + po1:= pintegeraty(dataicon.datalist.datapo); + for int1:= 0 to dataicon.datalist.count - 1 do begin + po1^[int1]:= po1^[int1] and (bmbitmask or integer($80000000)); + end; + int2:= dataicon.datalist.count; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] > 0) and (ar1[int1] <= int2) then begin + po1^[ar1[int1]-1]:= po1^[ar1[int1]-1] or integer($80000008); + end; + end; + updatebreakpointicons; + dataicon.datalist.change(-1); + end + else begin + cleardebuglines; + end; + application.endwait; + end; + end; +end; + +function tsourcepage.checkfilechanged: boolean; +var + stream1: ttextstream; + int1,int2: integer; + po1: prichstringty; + mstr1: msestring; +begin + result:= modified; + if not result then begin + result:= true; + if ttextstream.trycreate(stream1,edit.filename,fm_read) = sye_ok then begin + //else locked or deleted + try + stream1.encoding:= edit.encoding; + int1:= 0; + int2:= edit.datalist.count - 1; + po1:= edit.datalist.datapo; + for int1:= 0 to int2 do begin + if not stream1.readln(mstr1) then begin + if int1 <> int2 then begin + exit; + end; + end; + if mstr1 <> po1^.text then begin + exit; + end; + inc(po1); + end; + if stream1.eof then begin + result:= false; + end; + finally + stream1.free; + end; + end; + end; +end; + +function tsourcepage.canchangenotify(const info: filechangeinfoty): boolean; +begin + result:= (info.changed - [fc_force,fc_accesstime] <> []) or checkfilechanged(); + with projectoptions,s.texp do begin + if result and making and s.copymessages and + (filepath = msefileutils.filepath(messageoutputfile)) then begin + result:= false; + end; + end; +end; + +procedure tsourcepage.showsourcehint(const apos: gridcoordty; + const values: stringarty); +var + rect1: rectty; + int1: integer; +begin + if high(values) >= 0 then begin + sourcefo.sourcehintwidget:= tsourcehintfo.create(nil); + with tsourcehintfo(sourcefo.sourcehintwidget) do begin + if (sourcefo.hintsize.cx <= 0) or (sourcefo.hintsize.cy <= 0) then begin + sourcefo.hintsize:= size; + end; + rect1:= edit.textpostomouserect(apos,true); + dec(rect1.y,10); + inc(rect1.cy,40); + setlength(dispar,length(values)); + for int1:= 0 to high(values) do begin + dispar[int1]:= tedit.create(sourcefo.sourcehintwidget); + with dispar[int1] do begin + initnewcomponent(1.0); + frame.levelo:= 0; + frame.framewidth:= 1; + frame.colorframe:= cl_dkgray; + + optionsedit:= optionsedit + [oe_readonly]; + textflags:= [tf_wordbreak,tf_noselect]; + textflagsactive:= [tf_wordbreak]; + anchors:= [an_top]; + text:= msestring(values[high(values)-int1]); + end; + end; + for int1:= high(values) downto 0 do begin + dispar[int1].parentwidget:= sourcefo.sourcehintwidget.container; + end; + size:= sourcefo.hintsize; + formonresize(nil); + widgetrect:= placepopuprect(self.window,rect1,cp_bottomleft,size); + show(false,self.window); + end; + end + else begin + sourcefo.hidesourcehint; + end; + activate(false,true); //get focus back +end; + +procedure tsourcepage.showprocheaders(const apos: gridcoordty); +var + ar1: procedureinfoarty; + ar2: stringarty; + int1: integer; + pos1: sourceposty; +begin + pos1.pos:= apos; + ar1:= listprocheaders(edit.filename,pos1); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar2[int1]:= sourceupdater.composeprocedureheader(@ar1[int1],true); + end; + showsourcehint(apos,ar2); +end; + +procedure tsourcepage.showsourceitems(const apos: gridcoordty); +var + scopes: deflistarty; + defs: definfopoarty; + pos1: sourceposty; + ar1: stringarty; + int1: integer; +begin + pos1.pos:= apos; + listsourceitems(edit.filename,pos1,scopes,defs,100); + setlength(ar1,length(defs)); + for int1:= 0 to high(defs) do begin + ar1[int1]:= defs[int1]^.name; + end; + if high(ar1) >= 99 then begin + ar1[high(ar1)]:= '...'; + end; + showsourcehint(apos,ar1); +end; + +procedure tsourcepage.editoncellevent(const sender: TObject; + var info: celleventinfoty); + + procedure checklink; + var + pos2: gridcoordty; + begin + if info.keyeventinfopo^.shiftstate * shiftstatesmask = [ss_ctrl] then begin + if edit.mousepostotextpos(translatewidgetpoint(application.mouse.pos,nil,edit), + pos2,true) then begin + showlink(pos2); + end; + end + else begin + edit.removelink; + end; + end; + +var + pos1,pos2: sourceposty; + page1: tsourcepage; + shiftstate1: shiftstatesty; + bo1: boolean; + cellpos1: cellpositionty; + +begin + if iscellclick(info,[ccr_nokeyreturn,ccr_dblclick]) and + (dataicon[info.cell.row] and integer($80000000) <> 0) and + (info.mouseeventinfopo^.shiftstate = [ss_double]) then begin + include(info.mouseeventinfopo^.eventstate,es_processed); + breakpointsfo.showbreakpoint(filepath,info.cell.row + 1,true); + end; + case info.eventkind of + cek_exit: begin + edit.removelink; + end; + cek_keyup: begin + checklink; + end; + cek_keydown: begin + checklink; + with info.keyeventinfopo^ do begin + shiftstate1:= shiftstate * shiftstatesmask; + if not (es_processed in eventstate) then begin + if ((shiftstate1 = [ss_shift,ss_ctrl]) or + (shiftstate1 = [ss_ctrl])) then begin + include(eventstate,es_processed); + pos1.pos:= edit.editpos; + if (shiftstate1 = [ss_shift,ss_ctrl]) then begin + case key of + key_up,key_down: begin + if switchheaderimplementation(edit.filename,pos1,pos2,bo1) then begin + cellpos1:= cep_none; + if bo1 then begin + cellpos1:= cep_top; + end; + page1:= sourcefo.showsourcepos(pos2,true,cellpos1); + if page1 <> nil then begin + page1.grid.showcell(makegridcoord(1,pos1.pos.row)); + end; + end; + end; + key_space: begin + showprocheaders(edit.editpos); + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end + else begin + case key of + key_space: begin +{$ifdef mse_with_showsourceitems} + showsourceitems(edit.editpos); +{$endif} + end + else begin + exclude(eventstate,es_processed); + end; + end; + end; + end + else begin + if shiftstate1 = [] then begin + include(eventstate,es_processed); + case key of + key_escape: begin + if not sourcefo.hidesourcehint then begin + exclude(eventstate,es_processed); + end; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end; + end; + end; + end; + end; + end; +end; + +const + convtab: array[0..7] of bkptstatety = + // 000 001 010 011 + (bkpts_none,bkpts_normal,bkpts_disabled,bkpts_none, + // 100 101 110 111 + bkpts_none,bkpts_error,bkpts_none,bkpts_none); + +procedure tsourcepage.icononcellevent(const sender: tobject; + var info: celleventinfoty); +var + bpinfo: breakpointinfoty; + astate: bkptstatety; +begin + with dataicon do begin + if iscellclick(info) then begin + astate:= convtab[gridvalue[info.cell.row] and 7]; + fillchar(bpinfo,sizeof(bpinfo),0); + bpinfo.line:= info.cell.row + 1; + bpinfo.path:= edit.filename; + bpinfo.bkpton:= astate in [bkpts_disabled,bkpts_none]; //for toggle + case astate of + bkpts_none: begin + breakpointsfo.addbreakpoint(bpinfo); + end; + bkpts_normal,bkpts_disabled,bkpts_error: begin + if iscellclick(info,[ccr_dblclick]) then begin + breakpointsfo.deletebreakpoint(bpinfo); + end + else begin + breakpointsfo.updatebreakpointon(bpinfo); + end; + end; + end; + end; + end; +end; + +function tsourcepage.getbreakpointstate(arow: integer = -1): bkptstatety; +begin + if arow = -1 then begin + arow:= grid.row; + end; + if (arow >= 0) and (arow < grid.rowcount) then begin + result:= convtab[dataicon[arow] and 7]; + end + else begin + result:= bkpts_none; + end; +end; + +procedure tsourcepage.setbreakpointstate(astate: bkptstatety; + arow: integer = -1); +begin + if arow = -1 then begin + arow:= grid.row; + end; + if (arow >= 0) and (arow < grid.rowcount) then begin + case astate of + bkpts_none: dataicon[arow]:= dataicon[arow] and not integer($00000007); + bkpts_normal: dataicon[arow]:= dataicon[arow] and not integer($00000007) or + integer($80000001); + bkpts_disabled: dataicon[arow]:= dataicon[arow] and not integer($00000007) or + integer($80000002); + bkpts_error: dataicon[arow]:= dataicon[arow] and not integer($00000007) or + integer($80000005); + end; + end; +end; + +procedure tsourcepage.togglebreakpoint(const arow: integer = -1); +var + bpinfo: breakpointinfoty; + astate: bkptstatety; +begin + astate:= getbreakpointstate(grid.row); + fillchar(bpinfo,sizeof(bpinfo),0); + if arow < 0 then begin + bpinfo.line:= grid.row + 1; + end + else begin + bpinfo.line:= arow + 1; + end; + bpinfo.path:= edit.filename; + case astate of + bkpts_none: begin + bpinfo.bkpton:= true; + breakpointsfo.addbreakpoint(bpinfo); + end + else begin + breakpointsfo.deletebreakpoint(bpinfo); + setbreakpointstate(bkpts_none,grid.row); + //if breakpointinfo is not synchronized + end; + end; +end; + +procedure tsourcepage.togglebreakpointenabled(const arow: integer = -1); +var + bpinfo: breakpointinfoty; + astate: bkptstatety; +begin + astate:= convtab[dataicon.value and 7]; + fillchar(bpinfo,sizeof(bpinfo),0); + if arow < 0 then begin + bpinfo.line:= grid.row + 1; + end + else begin + bpinfo.line:= arow + 1; + end; + bpinfo.path:= edit.filename; + bpinfo.bkpton:= astate in [bkpts_disabled{,bkpts_none}]; //for toggle + if astate = bkpts_none then begin + breakpointsfo.addbreakpoint(bpinfo); + end + else begin + breakpointsfo.updatebreakpointon(bpinfo); + end; +end; + +procedure tsourcepage.setactiverow(const Value: integer); +begin + if factiverow <> value then begin + if (factiverow >= 0) and (factiverow < grid.rowcount) then begin + grid.rowcolorstate[factiverow]:= -1; + end; + if (value >= 0) and (value < grid.rowcount) then begin + grid.rowcolorstate[value]:= 0; + grid.showcell(makegridcoord(0,value),cep_rowcenteredif); + edit.editpos:= makegridcoord(0,value) + end; + end; + factiverow := Value; +end; + +procedure tsourcepage.setgdb(agdb: tgdbmi); +begin +// breakpoints.fgdb:= agdb; +end; + +procedure tsourcepage.sourcefooncreate(const sender: tobject); +begin +// breakpoints:= tbreakpoints.create; +end; + +procedure tsourcepage.sourcefoondestroy(const sender: tobject); +begin +// breakpoints.Free; +end; + +procedure tsourcepage.editonmodifiedchanged(const sender: tobject; + const value: boolean); +begin + updatecaption(value); +end; + +function tsourcepage.checksave(noconfirm,multiple: boolean): modalresultty; +begin + result:= mr_none; + if not sourcefo.allsaved then begin + if edit.modified and (noconfirm or + confirmsavechangedfile(edit.filename,result,multiple)) then begin + save(''); + end; + end; +end; + +procedure tsourcepage.save(newname: filenamety); +var + info: fileinfoty; + po1: prichstringty; + i1: int32; +begin + if newname = '' then begin + if (edit.filename = '') then begin + if filedialog(newname,[fdo_save],'',[],[]) = mr_cancel then begin + exit; + end; + end + else begin + newname:= edit.filename; + end; + end; + createbackupfile(newname,edit.filename,fbackupcreated, + projectoptions.e.backupfilecount); + if newname <> '' then begin + sourcefo.filechangenotifyer.removenotification(filepath); + end; + finitialfilepath:= newname; + try + designnotifications.beforefilesave(idesigner(designer),newname); + except + application.handleexception(nil); + end; + if projectoptions.e.trimtrailingwhitespace then begin + edit.datalist.beginupdate(); + try + po1:= edit.datalist.datapo; + for i1:= 0 to edit.datalist.count - 1 do begin + trimright1(po1^.text); + inc(po1); + end; + finally + edit.datalist.endupdate(); + end; + end; + edit.savetofile(newname); + if newname <> '' then begin + if ffiletag = 0 then begin + ffiletag:= sourcefo.newfiletag; + end; + sourcefo.filechangenotifyer.addnotification(filepath,filetag,true); + end; + setsyntaxdef(newname); + if getfileinfo(newname,info) then begin + fsavetime:= info.extinfo1.modtime; + end; + updatecaption(false); +end; + +function tsourcepage.modified: boolean; +begin + result:= false; + if edit <> nil then begin + result:= edit.modified; + end; +end; + +procedure textnotfound(const ainfo: findinfoty); +begin + showmessage(sourcefo.c[ord(str_text)]+' '''+ + ainfo.text+''' '+ + sourcefo.c[ord(str_notfound)]); +end; + +procedure findintextedit(const edit: tcustomtextedit; var info: findinfoty; + var findpos: gridcoordty; + const backward: boolean = false); +var + pt1: gridcoordty; + isback: boolean; +begin + with info do begin + if text = '' then begin + exit; + end; + if backward then begin + info.options:= info.options >< [so_backward]; + end; + isback:= so_backward in info.options; + if selectedonly then begin + if edit.hasselection then begin + if isback then begin + normalizetextrect(edit.selectstart,edit.selectend,pt1,findpos); + end + else begin + normalizetextrect(edit.selectstart,edit.selectend,findpos,pt1); + end; + if not edit.find(text,options,findpos,pt1,true) then begin + textnotfound(info); + end + else begin + selectedonly:= false; + end; + end; + end + else begin + findpos:= edit.editpos; +// dec(ffindpos.col); + if isback then begin + pt1:= nullcoord; + end + else begin + pt1:= bigcoord; + end; + if not edit.find(text,options,findpos,pt1,true,findshowpos) then begin + if (edit.linecount = 0) or + isback and (findpos.row = edit.linecount-1) and + (findpos.col = length(edit.gridvalue[edit.linecount-1])) or + not isback and (findpos.row = 0) and (findpos.col = 0) then begin + textnotfound(info); + end + else begin + if isback then begin + if askok(sourcefo.c[ord(str_text)]+' '''+text+ + ''' '+sourcefo.c[ord(str_notfound)]+' '+ + sourcefo.c[ord(restartend)]) then begin + findpos:= bigcoord; + if not edit.find(text,options,findpos,edit.editpos,true, + findshowpos) then begin + textnotfound(info); + end; + end; + end + else begin + if askok(sourcefo.c[ord(str_text)]+' '''+text+ + ''' '+sourcefo.c[ord(str_notfound)]+' '+ + sourcefo.c[ord(restartbegin)]) then begin + findpos:= nullcoord; + if not edit.find(text,options,findpos,edit.editpos,true, + findshowpos) then begin + textnotfound(info); + end; + end; + end; + end; + end; + end; + if backward then begin + info.options:= info.options >< [so_backward]; + end; + end; +end; +{ +procedure tsourcepage.find; +begin + findintextedit(edit,projectoptions.findreplaceinfo.find,ffindpos); +end; +} +procedure tsourcepage.beginupdate; +begin + edit.beginupdate; + grid.focuslock; + application.beginwait; +end; + +procedure tsourcepage.endupdate; +begin + application.endwait; + grid.focusunlock; + edit.endupdate; + updatelinedisp; +end; + +procedure tsourcepage.replace(all: boolean); + + function checkescape: boolean; + begin + result:= application.waitescaped; + if result then begin + endupdate; + result:= askyesno(sourcefo.c[ord(cancel)]); + application.processmessages; + beginupdate; + end; + end; + +var + pos1: gridcoordty; + res1: modalresultty; + rect1: rectty; + updatedisabled: boolean; + +begin + with projectoptions.findreplaceinfo,find do begin + updatedisabled:= false; + edit.editor.begingroup; + try + if selectedonly then begin + if not edit.hasselection then begin + exit; + end + else begin + normalizetextrect(edit.selectstart,edit.selectend,ffindpos,pos1); + end; + end + else begin + ffindpos:= edit.editpos; + pos1:= bigcoord; + end; + if not edit.find(text,options,ffindpos,pos1,true,findshowpos) then begin + textnotfound(find); + end + else begin + res1:= mr_yes; + repeat + if prompt then begin + rect1:= edit.textpostomouserect(ffindpos); + res1:= showmessage(sourcefo.c[ord(replaceoccu)],'', + [mr_yes,mr_all,mr_no,mr_cancel],rect1,grid,cp_bottomleft,res1); + end + else begin + res1:= mr_yes; + end; + case res1 of + mr_no: begin + inc(ffindpos.col,length(text)); + end; + mr_yes,mr_all: begin + edit.deleteselection; + edit.inserttext(ffindpos,replacetext); + inc(ffindpos.col,length(replacetext)); + if (res1 = mr_all) or (all and not prompt) then begin + if not updatedisabled then begin + application.processmessages; //remove message window + updatedisabled:= true; + beginupdate; + end; + prompt:= false; + all:= true; + end; + end; + else begin + exit; + end; + end; + until not all or + not edit.find(text,options,ffindpos,pos1,true,findshowpos) or + updatedisabled and checkescape; + end; + finally + if updatedisabled then begin + endupdate; + end; + edit.editor.endgroup; + end; + end; +end; + +procedure tsourcepage.doline; +var + int1: int32; +begin + if integerenter(fgotoline,1,grid.rowcount, + sourcefo.c[ord(gotoline)],sourcefo.c[ord(findline)]) = mr_ok then begin + int1:= grid.rowwindowpos; + grid.row:= fgotoline-1; + grid.rowwindowpos:= int1; + end; +end; + +procedure tsourcepage.dofind; +var + ainfo: findinfoty; +begin + ainfo:= projectoptions.findreplaceinfo.find; + if not edit.hasselection then begin + ainfo.selectedonly:= false; + end; +// ainfo.text:= edit.selectedtext; + if finddialogexecute(ainfo) then begin + projectoptions.findreplaceinfo.find:= ainfo; + findintextedit(edit,projectoptions.findreplaceinfo.find,ffindpos); + end; +end; + +procedure tsourcepage.doreplace; +var + ainfo: replaceinfoty; + res1: modalresultty; +begin + ainfo:= projectoptions.findreplaceinfo; +// ainfo.find.text:= edit.selectedtext; + res1:= replacedialogexecute(ainfo); + if res1 in [mr_ok,mr_all] then begin + projectoptions.findreplaceinfo:= ainfo; + replace(res1 = mr_all); + end; +end; + +procedure tsourcepage.repeatfind; +begin + findintextedit(edit,projectoptions.findreplaceinfo.find,ffindpos); +end; + +procedure tsourcepage.findback; +begin + findintextedit(edit,projectoptions.findreplaceinfo.find,ffindpos,true); +end; + +procedure tsourcepage.hidehint; +begin + flasthint:= invalidcell; + flasthintlength:= 0; + application.hidehint; +end; + +procedure tsourcepage.showlink(const apos: gridcoordty); +begin + edit.showlink(apos,pascaldelims + '.[]'); +end; + +procedure tsourcepage.editontextmouseevent(const sender: tobject; + var info: textmouseeventinfoty); + +var + po1: gridcoordty; + str1,str2: msestring; + pos1: sourceposty; + shiftstate1: shiftstatesty; +begin + shiftstate1:= info.mouseeventinfopo^.shiftstate * shiftstatesmask; + if mainfo.gdb.started and projectoptions.d.valuehints then begin + if info.eventkind = cek_mousepark then begin + str1:= getpascalvarname(edit,info.pos,po1); + if (po1.row <> flasthint.row) or (po1.col <> flasthint.col) or + (length(str1) <> flasthintlength) then begin + if str1 <> '' then begin + if mainfo.gdb.readpascalvariable(ansistring(str1),str2) = gdb_ok then begin + application.showhint(nil,str1 + ' = ' + str2, + inflaterect(edit.textpostomouserect(po1,true),20),cp_bottomleft,0); + end + else begin + hidehint; + end; + flasthint:= po1; + flasthintlength:= length(str1); + end + else begin + hidehint; + flasthintlength:= -1; + end; + end; + end; + end; + with info do begin + case eventkind of + cek_mousemove: begin + if (shiftstate1 = [ss_ctrl]) and active then begin + showlink(info.pos); + end; + end; + cek_mouseleave: begin + edit.removelink; + end; + cek_buttonpress: begin + if (shiftstate1 = [ss_ctrl,ss_left]) {and active} then begin +// include(info.mouseeventinfopo^.eventstate,es_processed); + pos1.pos:= info.pos; + pos1.filename:= designer.designfiles.find(edit.filename); + if findlinkdest(edit,pos1,str1) then begin + fshowsourcepos:= pos1; + asyncevent(ord(spat_showsource)); +// sourcefo.naviglist.showsource(pos1,true); + end; + end + else begin + if edit.isdblclicked(info.mouseeventinfopo^) and + (info.mouseeventinfopo^.shiftstate*[ss_double,ss_shift,ss_left] = + [ss_double,ss_shift,ss_left]) then begin + if ss_triple in info.mouseeventinfopo^.shiftstate then begin + edit.setselection(makegridcoord(0,edit.row), + makegridcoord(bigint,edit.row),true); + end + else begin + edit.selectword(info.pos,selectdelims); + end; + copytoclipboard(edit.selectedtext,cbb_primary); + include(info.mouseeventinfopo^.eventstate,es_processed); + end; + end; + end; + end; + end; +end; + +procedure tsourcepage.updatelinedisp; +begin + linedisp.value:= inttostrmse(edit.editpos.row+1) + ':'+ + inttostrmse(edit.editpos.col+1); +end; + +procedure tsourcepage.editoneditnotification(const sender: tobject; + var info: editnotificationinfoty); +begin +// if (info.action = ea_beforechange) and not edit.syntaxchanging then begin +// clearbrackets; +// end +// else begin + if (info.action = ea_indexmoved) and not grid.updating then begin + updatelinedisp; + end; +// if info.action in [ea_indexmoved,ea_delchar,ea_deleteselection,ea_pasteselection, +// ea_textentered] then begin +// callcheckbrackets; +// end; +// end; +end; + +procedure tsourcepage.gridonrowsdeleted(const sender: tcustomgrid; + const index, count: integer); +begin + breakpointsfo.sourcelinesdeleted(filepath,index+1,count); + if (factiverow >= 0) and (index <= factiverow) then begin + factiverow:= factiverow - count; + if factiverow < index then begin + activerow:= -1; //removed + end; + end; +end; + +procedure tsourcepage.gridonrowsinserted(const sender: tcustomgrid; + const index, count: integer); +begin + breakpointsfo.sourcelinesinserted(filepath,index+1,count); + if (factiverow >= 0) and (index <= factiverow) then begin + factiverow:= factiverow + count; + end; +end; + +procedure tsourcepage.sourcefoonshow(const sender: TObject); +begin + if not ffileloaderror then begin + try + loadfile; + mainfo.checkbluedots; + except + on e: exception do begin + ffileloaderror:= true; + application.showasyncexception(e,''); + hide; + // parentwidget:= nil; + release; + end; + end; + end; +end; + +procedure tsourcepage.updatestatvalues; +var + int1: integer; + colors: syntaxcolorinfoty; +begin + if edit <> nil then begin + projectoptionstofont(edit.font); + with projectoptions do begin + grid.frame.colorclient:= e.editbkcolor; + grid.rowcolors[0]:= e.statementcolor; + grid.datarowheight:= edit.font.lineheight; + int1:= edit.getcanvas.getstringwidth('oo') div 2; + with grid.fixcols[-1] do begin + visible:= e.linenumberson; + font.height:= edit.font.height; + font.name:= edit.font.name; + end; + if e.rightmarginon then begin + edit.marginlinecolor:= cl_gray; + edit.marginlinepos:= int1 * e.rightmarginchars; + end + else begin + edit.marginlinecolor:= cl_none; + end; + if e.tabstops < 1 then begin + e.tabstops:= 1; + end; + if e.showtabs then begin + edit.textflags:= edit.textflags + [tf_showtabs]; + edit.textflagsactive:= edit.textflagsactive + [tf_showtabs]; + end + else begin + edit.textflags:= edit.textflags - [tf_showtabs]; + edit.textflagsactive:= edit.textflagsactive - [tf_showtabs]; + end; + edit.tabulators.clear; + edit.tabulators.defaultdist:= int1 * e.tabstops / edit.tabulators.ppmm; +// edit.tabulators.setdefaulttabs(int1 * tabstops / edit.tabulators.ppmm); + edit.autoindent:= e.autoindent; + edit.markbrackets:= e.editmarkbrackets; + edit.markpairwords:= e.editmarkpairwords; + case e.encoding of + 1: begin + edit.encoding:= ce_utf8; + end; + 2: begin + edit.encoding:= ce_iso8859_1; + end; + else begin + edit.encoding:= ce_locale; + end; + end; + case e.eolstyle of + 1: begin + edit.eolstyle:= eol_system; + end; + 2: begin + edit.eolstyle:= eol_unix; + end; + 3: begin + edit.eolstyle:= eol_windows; + end; + else begin + edit.eolstyle:= eol_default; + end; + end; + grid.wheelscrollheight:= e.scrollheight; + edit.pairmarkbkgcolor:= e.pairmarkcolor; + edit.pairmaxrowcount:= e.pairmaxrowcount; + if edit.syntaxpainterhandle >= 0 then begin + colors:= edit.syntaxpainter.colors[edit.syntaxpainterhandle]; + with colors do begin + if font <> cl_default then begin + edit.font.color:= font; + end; + if background <> cl_default then begin + grid.frame.colorclient:= background; + end; + if (statement <> cl_default) and (grid.rowcolors[0] <> cl_none) then begin + grid.rowcolors[0]:= statement; + end; + end; + end; + end; + end; +end; + +procedure tsourcepage.editonfontchanged(const sender: TObject); +begin +// updatestatvalues; +end; + +procedure tsourcepage.sourcefoondeactivate(const sender: TObject); +begin + sourcefo.hidesourcehint; +end; + +procedure tsourcepage.gridoncellevent(const sender: TObject; + var info: celleventinfoty); +//var +// shiftstate1: shiftstatesty; +begin +{ + if (info.eventkind = cek_keydown) then begin + with info.keyeventinfopo^ do begin + shiftstate1:= shiftstate * shiftstatesmask; + if (shiftstate1 = [ss_ctrl]) and + (key >= key_0) and (key <= key_9) then begin + if sourcefo.findbookmark(ord(key) - ord(key_0)) then begin + include(eventstate,es_processed); + end; + end + else begin + if (shiftstate1 = [ss_ctrl,ss_shift]) and + (keynomod >= key_0) and (keynomod <= key_9) then begin + sourcefo.setbookmark(self,info.cell.row,ord(keynomod) - ord(key_0)); + include(eventstate,es_processed); + end; + end; + end; + end; +} +end; + +function tsourcepage.findbookmark(const bookmarknum: integer): integer; +var + int1,int2,int3: integer; + po1: pintegeraty; +begin + result:= -1; + for int3:= 0 to high(finitialbookmarks) do begin + if finitialbookmarks[int3].bookmarknum = bookmarknum then begin + loadfile; + po1:= dataicon.griddata.datapo; + int2:= 1 shl (bookmarknum + bmbitshift); + for int1:= 0 to grid.rowcount - 1 do begin + if po1^[int1] and bmbitmask = int2 then begin + result:= int1; + break; + end; + end; + end; + end; +end; + +procedure tsourcepage.removebookmark(const bookmarknum: integer); +var + int1: integer; +begin + for int1:= high(finitialbookmarks) downto 0 do begin + if finitialbookmarks[int1].bookmarknum = bookmarknum then begin + deleteitem(finitialbookmarks,typeinfo(bookmarkarty),int1); + end; + end; +end; + +procedure tsourcepage.setbookmark(arow: integer; const bookmarknum: integer); + //arow -1 -> current row, bookmarknum < 1 -> clear +begin + if arow < 0 then begin + arow:= grid.row; + end; + if arow >= 0 then begin + if bookmarknum < 0 then begin + dataicon[arow]:= dataicon[arow] and not bmbitmask; + removebookmark(bookmarknum); + end + else begin + dataicon[arow]:= replacebits(longword(1 shl (bookmarknum + bmbitshift)), + longword(dataicon[arow]),longword(bmbitmask)); + setlength(finitialbookmarks,high(finitialbookmarks)+2); + finitialbookmarks[high(finitialbookmarks)].bookmarknum:= bookmarknum; + end; + end; +end; + +procedure tsourcepage.clearbookmark(const bookmarknum: integer); +var + int1,int2: integer; + po1: pintegeraty; +begin + removebookmark(bookmarknum); + po1:= dataicon.griddata.datapo; + int2:= 1 shl (bookmarknum + bmbitshift); + for int1:= 0 to grid.rowcount - 1 do begin + if po1^[int1] and bmbitmask = int2 then begin + dataicon[int1]:= po1^[int1] and not bmbitmask; + end; + end; +end; + +function tsourcepage.getbookmarks: bookmarkarty; +var + int1,int2: integer; + po1: pintegeraty; + lwo1: longword; +begin + if not fileloaded then begin + result:= copy(finitialbookmarks); + end + else begin + po1:= dataicon.griddata.datapo; + int2:= 0; + result:= nil; + for int1:= 0 to grid.rowcount - 1 do begin + lwo1:= po1^[int1] and bmbitmask; + if lwo1 <> 0 then begin + additem(result,typeinfo(bookmarkarty),int2); + with result[int2-1] do begin + row:= int1; + bookmarknum:= lowestbit(lwo1) - bmbitshift; + end; + end; + end; + setlength(result,int2); + end; +end; + +procedure tsourcepage.setbackupcreated; +begin + fbackupcreated:= true; +end; + +procedure tsourcepage.editonkeydown(const sender: twidget; + var info: keyeventinfoty); +begin + with info,tsyntaxedit(sender).editor,projectoptions do begin + if e.spacetabs and (e.tabstops > 0) and (shiftstate = []) and + (key = key_tab) then begin + chars:= charstring(msechar(' '), + (curindex div e.tabstops + 1) * e.tabstops - curindex); + end; + end; +end; +{ +procedure tsourcepage.clearbrackets; +begin + if (fbracket1.col >= 0) and (fbracketsetting = 0) then begin + inc(fbracketsetting); + try + with edit do begin + setfontstyle(fbracket1,makegridcoord(fbracket1.col+1,fbracket1.row), + fs_bold,false); + setfontstyle(fbracket2,makegridcoord(fbracket2.col+1,fbracket2.row), + fs_bold,false); + refreshsyntax(fbracket1.row,1); + refreshsyntax(fbracket2.row,1); + fbracket1:= invalidcell; + fbracket2:= invalidcell; + if syntaxpainterhandle >= 0 then begin + syntaxpainter.boldchars[syntaxpainterhandle]:= nil; + end; + end; + finally + dec(fbracketsetting); + end; + end; +end; + +procedure tsourcepage.checkbrackets; +var + mch1: msechar; + br1,br2: bracketkindty; + open,open2: boolean; + pt1,pt2: gridcoordty; + ar1: gridcoordarty; +begin + clearbrackets; + pt2:= invalidcell; + with edit do begin + pt1:= editpos; + mch1:= charatpos(pt1); + br1:= checkbracketkind(mch1,open); + if (br1 <> bki_none) and (pt1.col > 0) then begin + dec(pt1.col); + br2:= checkbracketkind(charatpos(pt1),open2); + if (br2 = bki_none) or (open <> open2) then begin + inc(pt1.col); + end + else begin + br1:= br2; + end; + pt2:= matchbracket(pt1,br1,open); + end + else begin + dec(pt1.col); + if pt1.col >= 0 then begin + mch1:= charatpos(pt1); + br1:= checkbracketkind(mch1,open); + if br1 <> bki_none then begin + pt2:= matchbracket(pt1,br1,open); + end; + end; + end; + if pt2.col >= 0 then begin + fbracket1:= pt1; + fbracket2:= pt2; + inc(fbracketsetting); + try + setfontstyle(pt1,makegridcoord(pt1.col+1,pt1.row),fs_bold,true); + setfontstyle(pt2,makegridcoord(pt2.col+1,pt2.row),fs_bold,true); + finally + dec(fbracketsetting); + end; + if syntaxpainterhandle >= 0 then begin + setlength(ar1,2); + ar1[0]:= fbracket1; + ar1[1]:= fbracket2; + syntaxpainter.boldchars[syntaxpainterhandle]:= ar1; + refreshsyntax(fbracket1.row,1); + refreshsyntax(fbracket2.row,1); + end; + end; + end; +end; + +procedure tsourcepage.callcheckbrackets; +begin + if (fbracketchecking = 0) and (projectoptions.e.editmarkbrackets) then begin + inc(fbracketchecking); + asyncevent(ord(spat_checkbracket)); + end; +end; +} +function tsourcepage.source: trichstringdatalist; +begin + result:= edit.datalist; +end; + +procedure tsourcepage.copywordatcursor(); +begin + edit.selectword(edit.editpos,selectdelims); + edit.copyselection(); +end; + +procedure tsourcepage.doundo; +begin + beginupdate; + edit.undo; + endupdate; +end; + +procedure tsourcepage.doredo; +begin + beginupdate; + edit.redo; + endupdate; +end; + +procedure tsourcepage.inserttemplate; +var + mstr1,mstr2: msestring; +// po1: pmsechar; + po2: ptemplateinfoty; + gc1,gc2: gridcoordty; + int1: integer; + mac1: tmacrolist; + ar1: msestringarty; +begin + gc1:= edit.editpos; + if gc1.row >= 0 then begin + mstr1:= edit.wordatpos(gc1,gc2,'',[],true); + if gc2.col < 0 then begin + gc2.col:= gc1.col; + end; + mac1:= getmacros; + try + po2:= codetemplates.gettemplate(mstr1,mstr2,mac1); + if po2 <> nil then begin + with edit,po2^ do begin + editor.begingroup; + gc1.col:= gc2.col+length(mstr1); + deletetext(gc2,gc1); + if indent then begin + ar1:= breaklines(mstr2); + for int1:= 1 to high(ar1) do begin + ar1[int1]:= charstring(msechar(' '),gc2.col)+ar1[int1]; + end; + mstr2:= concatstrings(ar1,lineend); + end; + inserttext(gc2,mstr2,select); + if not select then begin + if indent or (cursorpos.row = 0) then begin + gc2.col:= gc2.col + cursorpos.col; + end + else begin + gc2.col:= cursorpos.col; + end; + gc2.row:= gc2.row + cursorpos.row; + editpos:= gc2; + end; + end; + edit.editor.endgroup; + end; + finally + mac1.free; + end; + end; +end; + +procedure tsourcepage.copylatex; +begin + copytoclipboard(richstringtolatex(edit.selectedrichtext)); +end; + +function tsourcepage.cancomment(): boolean; +begin + result:= edit.hasselection and (edit.selectstart.col = 0) and + (edit.selectend.col = 0); +end; + +function tsourcepage.canuncomment(): boolean; +var + po1,pe: prichstringty; + start,stop: int32; +begin + result:= cancomment(); + if result then begin + edit.getselectedrows(start,stop); + po1:= edit.datalist.getitempo(start); + pe:= po1 + stop - start; + while po1 <= pe do begin + if (length(po1^.text) < 2) or (po1^.text[1] <> '/') or + (po1^.text[2] <> '/') then begin + result:= false; + break; + end; + inc(po1); + end; + end; +end; + +procedure tsourcepage.commentselection(); +var + mstr1: msestring; + i1: int32; + start,stop: int32; +begin + if cancomment() then begin + edit.getselectedrows(start,stop); + edit.editor.begingroup(); + mstr1:= edit.selectedtext; + insert('//',mstr1,1); + i1:= 3; + while mstr1[i1] <> #0 do begin + if mstr1[i1] = c_return then begin + inc(i1); + end; + if mstr1[i1] = c_linefeed then begin + inc(i1); + if mstr1[i1] = #0 then begin + break; + end; + insert('//',mstr1,i1); + end; + inc(i1); + end; + grid.beginupdate(); + edit.deleteselection(); + edit.inserttext(mstr1,true); + grid.endupdate(); + edit.editor.endgroup(); + edit.refreshsyntax(start,stop-start); + end; +end; + +procedure tsourcepage.uncommentselection(); +var + mstr1: msestring; + i1: int32; + start,stop: int32; +begin + if canuncomment() then begin + edit.getselectedrows(start,stop); + edit.editor.begingroup(); + mstr1:= edit.selectedtext; + delete(mstr1,1,2); + i1:= 1; + while mstr1[i1] <> #0 do begin + if mstr1[i1] = c_return then begin + inc(i1); + end; + if mstr1[i1] = c_linefeed then begin + inc(i1); + if mstr1[i1] = #0 then begin + break; + end; + delete(mstr1,i1,2); + dec(i1); + end; + inc(i1); + end; + grid.beginupdate(); + edit.deleteselection(); + edit.inserttext(mstr1,true); + grid.endupdate(); + edit.editor.endgroup(); + edit.refreshsyntax(start,stop-start); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/sourcepage_mfm.pas b/mseide-msegui/apps/ide/sourcepage_mfm.pas new file mode 100644 index 0000000..ec1b224 --- /dev/null +++ b/mseide-msegui/apps/ide/sourcepage_mfm.pas @@ -0,0 +1,213 @@ +unit sourcepage_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,sourcepage; + +const + objdata: record size: integer; data: array[0..3917] of byte end = + (size: 3918; data: ( + 84,80,70,48,11,116,115,111,117,114,99,101,112,97,103,101,10,115,111,117, + 114,99,101,112,97,103,101,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,5,99,111,108,111,114,4,5,0, + 0,144,8,98,111,117,110,100,115,95,120,3,192,0,8,98,111,117,110,100, + 115,95,121,3,245,0,9,98,111,117,110,100,115,95,99,120,3,55,1,9, + 98,111,117,110,100,115,95,99,121,3,228,0,23,99,111,110,116,97,105,110, + 101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119, + 95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114, + 97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111, + 117,110,100,115,1,2,0,2,0,3,55,1,3,228,0,0,21,105,99,111, + 110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,0, + 0,0,128,8,111,110,99,114,101,97,116,101,7,16,115,111,117,114,99,101, + 102,111,111,110,99,114,101,97,116,101,16,111,110,101,118,101,110,116,108,111, + 111,112,115,116,97,114,116,7,16,115,111,117,114,99,101,102,111,111,110,108, + 111,97,100,101,100,9,111,110,100,101,115,116,114,111,121,7,17,115,111,117, + 114,99,101,102,111,111,110,100,101,115,116,114,111,121,6,111,110,115,104,111, + 119,7,14,115,111,117,114,99,101,102,111,111,110,115,104,111,119,6,111,110, + 104,105,100,101,7,20,115,111,117,114,99,101,102,111,111,110,100,101,97,99, + 116,105,118,97,116,101,15,109,111,100,117,108,101,99,108,97,115,115,110,97, + 109,101,6,8,116,116,97,98,102,111,114,109,0,11,116,119,105,100,103,101, + 116,103,114,105,100,4,103,114,105,100,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,55,1,9,98,111,117,110,100,115,95,99,121,3,206,0,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98, + 111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15, + 111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,10,111,103,95,119, + 114,97,112,99,111,108,21,111,103,95,118,105,115,105,98,108,101,114,111,119, + 112,97,103,101,115,116,101,112,0,13,102,105,120,99,111,108,115,46,99,111, + 117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,5,0,0,160,9,108,105,110,101,119,105,100, + 116,104,2,0,9,116,101,120,116,102,108,97,103,115,11,8,116,102,95,114, + 105,103,104,116,12,116,102,95,121,99,101,110,116,101,114,101,100,0,8,110, + 117,109,115,116,97,114,116,2,1,7,110,117,109,115,116,101,112,2,1,10, + 102,111,110,116,46,99,111,108,111,114,4,3,0,0,160,9,102,111,110,116, + 46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111,114,10, + 102,108,112,95,120,115,99,97,108,101,0,0,0,14,103,114,105,100,102,114, + 97,109,101,99,111,108,111,114,4,3,0,0,128,15,114,111,119,99,111,108, + 111,114,115,46,99,111,117,110,116,2,4,15,114,111,119,99,111,108,111,114, + 115,46,105,116,101,109,115,1,4,255,255,224,0,4,255,255,0,0,4,0, + 0,255,0,4,2,0,0,128,0,14,100,97,116,97,99,111,108,115,46,99, + 111,117,110,116,2,2,14,100,97,116,97,99,111,108,115,46,105,116,101,109, + 115,14,7,8,100,97,116,97,105,99,111,110,1,9,108,105,110,101,99,111, + 108,111,114,4,4,0,0,160,5,119,105,100,116,104,2,15,7,111,112,116, + 105,111,110,115,11,10,99,111,95,110,111,102,111,99,117,115,12,99,111,95, + 110,111,104,115,99,114,111,108,108,0,11,111,110,99,101,108,108,101,118,101, + 110,116,7,15,105,99,111,110,111,110,99,101,108,108,101,118,101,110,116,10, + 119,105,100,103,101,116,110,97,109,101,6,8,100,97,116,97,105,99,111,110, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,4,101,100,105,116,1, + 5,119,105,100,116,104,3,208,7,7,111,112,116,105,111,110,115,11,22,99, + 111,95,108,101,102,116,98,117,116,116,111,110,102,111,99,117,115,111,110,108, + 121,20,99,111,95,109,105,100,100,108,101,98,117,116,116,111,110,102,111,99, + 117,115,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,8,111,110,99,104,97, + 110,103,101,7,11,116,101,120,116,99,104,97,110,103,101,100,10,119,105,100, + 103,101,116,110,97,109,101,6,4,101,100,105,116,9,100,97,116,97,99,108, + 97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,0,16,100,97,116,97,114,111,119,108,105, + 110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,18,14,111,110,114,111,119,115,105,110,115,101,114,116,101,100, + 7,18,103,114,105,100,111,110,114,111,119,115,105,110,115,101,114,116,101,100, + 13,111,110,114,111,119,115,100,101,108,101,116,101,100,7,17,103,114,105,100, + 111,110,114,111,119,115,100,101,108,101,116,101,100,11,111,110,99,101,108,108, + 101,118,101,110,116,7,15,103,114,105,100,111,110,99,101,108,108,101,118,101, + 110,116,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,11, + 116,115,121,110,116,97,120,101,100,105,116,4,101,100,105,116,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,208,7,9,98,111,117,110,100,115,95,99,121,2,18,9,102,111, + 110,116,46,110,97,109,101,6,13,109,115,101,105,100,101,95,115,111,117,114, + 99,101,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,15, + 111,101,49,95,110,111,115,101,108,101,99,116,97,108,108,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,108,105, + 110,101,98,114,101,97,107,12,111,101,95,101,97,116,114,101,116,117,114,110, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,20,111,101,95, + 110,111,102,105,114,115,116,97,114,114,111,119,110,97,118,105,103,0,15,116, + 97,98,117,108,97,116,111,114,115,46,112,112,109,109,2,3,22,116,97,98, + 117,108,97,116,111,114,115,46,100,101,102,97,117,108,116,100,105,115,116,2, + 0,9,111,110,107,101,121,100,111,119,110,7,13,101,100,105,116,111,110,107, + 101,121,100,111,119,110,13,111,110,102,111,110,116,99,104,97,110,103,101,100, + 7,17,101,100,105,116,111,110,102,111,110,116,99,104,97,110,103,101,100,17, + 111,110,109,111,100,105,102,105,101,100,99,104,97,110,103,101,100,7,21,101, + 100,105,116,111,110,109,111,100,105,102,105,101,100,99,104,97,110,103,101,100, + 16,111,110,116,101,120,116,109,111,117,115,101,101,118,101,110,116,7,20,101, + 100,105,116,111,110,116,101,120,116,109,111,117,115,101,101,118,101,110,116,17, + 111,110,101,100,105,116,110,111,116,105,102,99,97,116,105,111,110,7,22,101, + 100,105,116,111,110,101,100,105,116,110,111,116,105,102,105,99,97,116,105,111, + 110,11,111,110,99,101,108,108,101,118,101,110,116,7,15,101,100,105,116,111, + 110,99,101,108,108,101,118,101,110,116,12,109,97,120,117,110,100,111,99,111, + 117,110,116,3,16,39,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,18,0,0,9,116,100,97,116,97,105,99,111,110,8,100,97,116,97,105, + 99,111,110,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,98,111, + 117,110,100,115,95,120,2,50,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,15,9,98,111,117,110,100,115,95,99, + 121,2,18,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109, + 101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111, + 101,49,95,115,97,118,101,115,116,97,116,101,0,7,111,112,116,105,111,110, + 115,11,15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98, + 111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27, + 98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101, + 110,116,101,114,107,101,121,0,7,118,105,115,105,98,108,101,8,12,118,97, + 108,117,101,100,101,102,97,117,108,116,4,0,0,0,128,3,109,105,110,2, + 255,3,109,97,120,2,2,15,105,109,97,103,101,110,117,109,115,46,99,111, + 117,110,116,2,14,15,105,109,97,103,101,110,117,109,115,46,105,116,101,109, + 115,1,2,0,2,1,2,2,2,3,2,4,2,5,2,6,2,7,2,8, + 2,9,2,10,2,11,2,12,2,13,0,0,0,0,11,116,115,116,114,105, + 110,103,101,100,105,116,8,108,105,110,101,100,105,115,112,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,3,207,0,9,98,111,117,110,100,115,95,99, + 120,2,68,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22, + 111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110, + 108,121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120,99,101, + 110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101,100,0, + 15,116,101,120,116,102,108,97,103,115,97,99,116,105,118,101,11,12,116,102, + 95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101, + 114,101,100,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,11,116,115,116,114,105,110,103,101,100,105,116,8,112,97,116,104,100, + 105,115,112,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,68,8,98,111,117,110,100,115,95,121,3,207,0,9, + 98,111,117,110,100,115,95,99,120,3,243,0,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,8,97,110,95,114,105,103,104,116,9,97, + 110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101, + 95,99,97,114,101,116,111,110,114,101,97,100,111,110,108,121,22,111,101,95, + 102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18, + 111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,9, + 116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101, + 114,101,100,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsourcepage,''); +end. diff --git a/mseide-msegui/apps/ide/sourceupdate.pas b/mseide-msegui/apps/ide/sourceupdate.pas new file mode 100644 index 0000000..226e492 --- /dev/null +++ b/mseide-msegui/apps/ide/sourceupdate.pas @@ -0,0 +1,2350 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit sourceupdate; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msedesigner,mseclasses,msedesignintf,classes,mclasses,typinfo, + msetypes,msestrings,pascaldesignparser,cdesignparser,mseglob, + msestream,mseparser,msesyntaxedit,mselist,msehash,msedesignparser; + +const + procheaderbreakchars = '(;'; +type + unitinfoaty = array[0..0] of tunitinfo; + punitinfoaty = ^unitinfoaty; +// unitinfopoarty = array of punitinfoty; + + tfilenameinfo = class + private + funits: unitinfopoarty; + public + procedure addunitinfo(ainfo: punitinfoty); + end; + + tfilenamelist = class(tobjectmsestringhashdatalist) + public + procedure add(const key: filenamety; info: punitinfoty); + function find(const key: filenamety): tfilenameinfo; + procedure sourcefilemodified(key: filenamety); + end; + + tunitinfolist = class(tobjectqueue) + private +// fnamelist: thashedstrings; + fnamelist: tpointeransistringhashdatalist; + protected + function getitempo(const index: integer): punitinfoty; + public + constructor create; + destructor destroy; override; + procedure clear; override; + function datapo: punitinfoaty; reintroduce; + function newitem(const lang: proglangty): punitinfoty; + property itempo[const index: integer]: punitinfoty read getitempo; default; + function finditembyformfilename(const afilename: filenamety): punitinfoty; + function finditembysourcefilename(const afilename: filenamety; + var filenum: integer): punitinfoty; + function finditembyunitname(const aname: string): punitinfoty; + end; + + tsourceupdater = class(tnullinterfacedobject,idesignnotification) + private + fdesigner: tdesigner; + funitinfolist: tunitinfolist; + ffilenamelist: tfilenamelist; + falphabeticprocorder: boolean; + fmaxlinelength: integer; + protected + //idesignnotification + procedure itemdeleted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure iteminserted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure itemsmodified(const adesigner: idesigner; const aitem: tobject); + //nil for undefined aitem + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure selectionchanged(const adesigner: idesigner; + const aselection: idesignerSelections); + procedure moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; + const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + + procedure getincludefile(const sender: tparser; const scanner: tscanner); + procedure updatepascalunit(const infopo: punitinfoty; + const interfaceonly: boolean); overload; + procedure updatecunit(const infopo: punitinfoty; + const interfaceonly: boolean); overload; + procedure updateunit(const infopo: punitinfoty; + const interfaceonly: boolean); overload; + function composeproceduretext(const name: string; const info: methodparaminfoty; + const withdefault: boolean): string; overload; + function composeprocedureheader(const name: string; + const info: methodparaminfoty; const withdefault: boolean; + const classproc: boolean): string; overload; + function composeprocedureheader(const infopo: pprocedureinfoty; + const classinfopo: pclassinfoty; + const withdefault: boolean): string; overload; + function composeprocedureheader(const name: string; const typeinfo: ptypeinfo; + const withdefault: boolean; + const classproc: boolean): string; overload; + procedure createmethodbody(const unitinfopo: punitinfoty; + const classinfopo: pclassinfoty; const aname: string; + const atype: ptypeinfo; beforeitem: integer); + function createscratchfile(const origname: filenamety): ttextstream; + function updateline(module: punitinfoty; var apos: sourceposty): boolean; overload; + function updateline(module: punitinfoty; var apos: sourceposty; + const afilename: filenamety): boolean; overload; + //calculates absolute line number from includefiles, + //false if invalid + procedure updateincludefilenum(module: punitinfoty; + const filename: filenamety; var filenum: integer); + + function findsourceitem1(const infopo: punitinfoty; const apos: sourceposty; + out scope: tdeflist): pdefinfoty; + procedure checkitemlist(const infopo: punitinfoty); + function findsourceitem(const infopo: punitinfoty; + const apos: sourceposty): psourceitemty; overload; + function findsourceitem(const infopo: punitinfoty; const apos: sourceposty; + out aindex: integer): psourceitemty; overload; + function getidentpath(const infopo: punitinfoty; const apos: sourceposty; + const firstidentuse: boolean; + out scope: tdeflist): stringarty; overload; + function getidentpath(const parser: tpascalparser): stringarty; overload; + function switchheaderimplementation(const infopo: punitinfoty; + var headerstart,headerstop: sourceposty; + out isimplementation: boolean): boolean; + function completeclass(const infopo: punitinfoty; + const pos: sourceposty): boolean; //true if changed + procedure sourcechanged(const filename: filenamety); + function listprocheaders(const infopo: punitinfoty; + const apos: sourceposty): procedureinfopoarty; + function listsourceitems(const infopo: punitinfoty; + const apos: sourceposty; out scopes: deflistarty; + out defs: definfopoarty; + const maxcount: integer = 100): boolean; + public + constructor create(const adesigner: tdesigner); + destructor destroy; override; + procedure clear; + + procedure unitchanged(const aunit: punitinfoty = nil); overload; + procedure unitchanged(const asourcefilename: filenamety); overload; + procedure resetunitsearched; //resets all allreadysearchedflags of rootdeflists + + function updateunitinterface(const aunitname: string): punitinfoty; + function updatemodule(const amodule: tmsecomponent): punitinfoty; + function updateformunit(const aformfilename: filenamety; + const interfaceonly: boolean): punitinfoty; + function updatesourceunit(const asourcefilename: filenamety; + out filenum: integer; const interfaceonly: boolean): punitinfoty; + + function gettext(const infopo: punitinfoty; + const startpos,endpos: sourceposty): msestring; + procedure replacetext(const infopo: punitinfoty; + const startpos,endpos: sourceposty; const newtext: msestring); + + function getmatchingmethods(const amodule: tmsecomponent; + const atype: ptypeinfo): msestringarty; + function parsemodule(const amodule: tmsecomponent): pclassinfoty; + function findunitfile(const aunitname: msestring): msestring; + function findmethodpos(const amethod: tmethod; const imp: boolean = false): sourceposty; + function findcfunctionimplementation(const aname: ansistring; + out headerstart,headerstop: sourceposty): boolean; + //true if found + + function composeproceduretext(const infopo: pprocedureinfoty; + const withdefault: boolean): string; overload; + function composeprocedureheader(const infopo: pprocedureinfoty; + const withdefault: boolean): string; overload; + function gettype(const adef: pdefinfoty): stringarty; + function finddef(const infopo: punitinfoty; + const apos: sourceposty): pdefinfoty; overload; + function finddef(const infopo: punitinfoty; + const typename: string): pdefinfoty; overload; + function getitemtext(const aitem: sourceitemty): string; + function getdefinfotext(const adef: pdefinfoty): string; + property maxlinelength: integer read fmaxlinelength + write fmaxlinelength default 80; + end; + +var + sourceupdater: tsourceupdater; + +procedure init(const adesigner: tdesigner); +procedure deinit(const adesigner: tdesigner); + +procedure sourcechanged(const filename: filenamety); +function switchheaderimplementation(const filename: filenamety; + var astart,astop: sourceposty; + out isimplementation: boolean): boolean; +function findlinkdest(const edit: tsyntaxedit; var apos: sourceposty; + out definition: msestring): boolean; + //true if dest found +function listprocheaders(const filename: filenamety; + var apos: sourceposty): procedureinfoarty; +function listsourceitems(const filename: filenamety; + var apos: sourceposty; out scopes: deflistarty; + out defs: definfopoarty; + const maxcount: integer = 100): boolean; + //true if found +function completeclass(const filename: filenamety; var pos: sourceposty): boolean; + //true if source changed +function getimplementationtext(const amodule: tmsecomponent; out aunit: punitinfoty; + out start,stop: sourceposty; out adest: msestring): boolean; + //false if not found +implementation +uses + sysutils,msesys,msefileutils,sourceform,sourcepage,projectoptionsform, + msegui,msearrayutils,projecttreeform; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function findprogramlanguage(const afilename: filenamety): proglangty; +var + mstr1: msestring; +begin + mstr1:= mseuppercase(fileext(afilename)); + if (mstr1 = 'C') or (mstr1 = 'H') then begin + result:= pl_c; + end + else begin + result:= pl_pascal; + end; +end; + +function limitlinelength(const atext: msestring; const maxlength: integer; + const breakchars: msestring; const indent: integer; + const startoffset: integer = 0): msestring; +var + ar1: msestringarty; + mstr1: msestring; + int1: integer; + po1,po2: pmsechar; + linelength: integer; + bo1: boolean; +begin + result:= ''; + if atext <> '' then begin + ar1:= breaklines(atext); + mstr1:= concatstrings(ar1,' '); + ar1:= nil; + po1:= pmsechar(mstr1); + po2:= po1; + bo1:= false; + while po2^ <> #0 do begin + if bo1 and (findchar(breakchars,po2^) <> 0) then begin + inc(po2); + additem(ar1,stringsegment(po1,po2)); + po1:= po2; + end + else begin + bo1:= true; + inc(po2); + end; + end; + additem(ar1,stringsegment(po1,po2)); + result:= ar1[0]; + linelength:= length(result) + startoffset; + for int1:= 1 to high(ar1) do begin + if (ar1[int1] <> '') and + (length(ar1[int1]) + linelength > maxlength) then begin + result:= result + lineend + charstring(msechar(' '),indent) + ar1[int1]; + linelength:= indent + length(ar1[int1]); + end + else begin + result:= result + ar1[int1]; + linelength:= linelength + length(ar1[int1]); + end; + end; + end; +end; + +procedure init(const adesigner: tdesigner); +begin + sourceupdater:= tsourceupdater.Create(adesigner); + sourceupdater.maxlinelength:= projectoptions.e.rightmarginchars; +end; + +procedure deinit(const adesigner: tdesigner); +begin + freeandnil(sourceupdater); +end; + +procedure sourcechanged(const filename: filenamety); +begin + if sourceupdater <> nil then begin + sourceupdater.sourcechanged(filename); + end; +end; + +function switchheaderimplementation(const filename: filenamety; + var astart,astop: sourceposty; out isimplementation: boolean): boolean; +var + po1: punitinfoty; +begin + with sourceupdater do begin + po1:= updatesourceunit(filename,astart.filenum,false); + if updateline(po1,astart) then begin + result:= switchheaderimplementation(po1,astart,astop,isimplementation); + end + else begin + result:= false; + end; + end; +end; + +function completeclass(const filename: filenamety; var pos: sourceposty): boolean; +var + po1: punitinfoty; +begin + with sourceupdater do begin + po1:= updatesourceunit(filename,pos.filenum,false); + if updateline(po1,pos) then begin + result:= completeclass(po1,pos); + end + else begin + result:= false; + end; + end; +end; + +function getimplementationtext(const amodule: tmsecomponent; + out aunit: punitinfoty; + out start,stop: sourceposty; out adest: msestring): boolean; + //false if not found +begin + result:= false; + with sourceupdater do begin + aunit:= updatemodule(amodule); + if aunit <> nil then begin + with aunit^ do begin + start:= p.implementationbodystart; + if isemptysourcepos(start) then begin + start:= p.implementationstart; + end; + stop:= p.implementationend; + if not isemptysourcepos(start) then begin + adest:= msestring(gettext(aunit,start,stop)); + result:= true; + end; + end; + end; + end; +end; + +function findlinkdest(const edit: tsyntaxedit; var apos: sourceposty; + out definition: msestring): boolean; +var + po1: punitinfoty; + po2: psourceitemty; + str1: msestring; +// coord1: gridcoordty; + po3: pdefinfoty; + int1: integer; + +begin + result:= false; + definition:= ''; + with sourceupdater do begin + application.beginwait; + try + if not application.waitcanceled then begin + po1:= updatesourceunit(edit.filename,apos.filenum,false); + if updateline(po1,apos) then begin + po2:= findsourceitem(po1,apos); + if po2 <> nil then begin + case po2^.kind of + sik_uses: begin + {coord1:= } + edit.wordatpos(apos.pos,str1,defaultdelimchars + ',;{}/',[]); + if str1 <> '' then begin + definition:= str1; + str1:= findunitfile(str1); + if str1 <> '' then begin + result:= true; + apos.filename:= designer.designfiles.add(str1); + apos.pos.col:= 0; + apos.pos.row:= 0; + end; + end; + end; + sik_include: begin + apos.filename:= + designer.designfiles.find(po1^.includestatements[po2^.index].filename); + definition:= designer.designfiles.getname(apos.filename); + apos.pos.col:= 0; + apos.pos.row:= 0; + result:= true; + end; + end; + end + else begin + po3:= finddef(po1,apos); + if po3 <> nil then begin + if po3^.deflist <> nil then begin + definition:= msestring(po3^.deflist.rootnamepath); + end + else begin + definition:= msestring(po3^.owner.rootnamepath+'.'+ + uppercase(po3^.name)); + end; + if po3^.kind in [syk_procdef,syk_procimp] then begin + int1:= findchar(definition,'$'); + if int1> 0 then begin + setlength(definition,int1-1); + end; + end; + apos.filename:= po3^.pos.filename; + apos.pos:= po3^.pos.pos; + result:= true; + end; + end; + end; + end; + finally + application.endwait; + end; + end; +end; + +function listprocheaders(const filename: filenamety; + var apos: sourceposty): procedureinfoarty; +var + po1: punitinfoty; + ar1: procedureinfopoarty; + int1: integer; +begin + ar1:= nil; //compiler warning + with sourceupdater do begin + po1:= updatesourceunit(filename,apos.filenum,false); + if updateline(po1,apos,filename) then begin + ar1:= listprocheaders(po1,apos); + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= ar1[int1]^; + end; + end + else begin + result:= nil; + end; + end; +end; + +function listsourceitems(const filename: filenamety; + var apos: sourceposty; out scopes: deflistarty; + out defs: definfopoarty; const maxcount: integer = 100): boolean; +var + po1: punitinfoty; +begin + with sourceupdater do begin + po1:= updatesourceunit(filename,apos.filenum,false); + if updateline(po1,apos,filename) then begin + result:= listsourceitems(po1,apos,scopes,defs,maxcount); + end + else begin + result:= false; + scopes:= nil; + defs:= nil; + end; + end; +end; + +{ tfilenameinfo } + +procedure tfilenameinfo.addunitinfo(ainfo: punitinfoty); +var + int1: integer; +begin + for int1:= 0 to high(funits) do begin + if funits[int1] = ainfo then begin + exit; + end; + end; + setlength(funits,high(funits) + 2); + funits[high(funits)]:= ainfo; +end; + +{ tfilenamelist } + +procedure tfilenamelist.add(const key: filenamety; info: punitinfoty); +var + adata: tfilenameinfo; +begin + adata:= find(key); + if adata = nil then begin + adata:= tfilenameinfo.Create; + if filesystemiscaseinsensitive then begin + inherited add(mseuppercase(key),adata); + end + else begin + inherited add(key,adata); + end; + end; + adata.addunitinfo(info); +end; + +function tfilenamelist.find(const key: filenamety): tfilenameinfo; +begin + if filesystemiscaseinsensitive then begin + result:= tfilenameinfo(inherited find(mseuppercase(key))); + end + else begin + result:= tfilenameinfo(inherited find(key)); + end; +end; + +procedure tfilenamelist.sourcefilemodified(key: filenamety); +var + int1: integer; + ainfo: tfilenameinfo; +begin + ainfo:= find(key); + if ainfo <> nil then begin + for int1:= 0 to high(ainfo.funits) do begin + with ainfo.funits[int1]^ do begin + if interfacecompiled then begin + interfacecompiled:= false; + if (proglang = pl_c) and (deflist <> nil) then begin + deflist.clear; //remove entries in cglobals; + projecttree.cmodules.modulechanged(key); + end; + end; + end; + end; + end; +end; + +{ tunitinfolist } + +constructor tunitinfolist.create; +begin +// fnamelist:= thashedstrings.create; + fnamelist:= tpointeransistringhashdatalist.create; + inherited create(true); +end; + +destructor tunitinfolist.destroy; +begin + inherited; + fnamelist.Free; +end; + +procedure tunitinfolist.clear; +begin + beginfinalizecglobals; + try + inherited; + fnamelist.clear; + finally + finalizecglobals; + end; +end; + +function tunitinfolist.datapo: punitinfoaty; +begin + result:= punitinfoaty(inherited datapo); +end; + +function tunitinfolist.newitem(const lang: proglangty): punitinfoty; +var + aitem: tunitinfo; +begin + case lang of + pl_pascal: begin + aitem:= tpascalunitinfo.create; + end; + pl_c: begin + aitem:= tcunitinfo.create; + end; + else begin + aitem:= tunitinfo.create; + end; + end; + add(aitem); + result:= aitem.infopo; +end; + +function tunitinfolist.getitempo(const index: integer): punitinfoty; +begin + result:= @tunitinfo(items[index]).info; +end; + +function tunitinfolist.finditembyformfilename(const afilename: filenamety): punitinfoty; +var + po1: punitinfoaty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if issamefilename(afilename,po1^[int1].info.formfilename) then begin + result:= po1^[int1].infopo; + break; + end; + end; +end; + +function tunitinfolist.finditembysourcefilename(const afilename: filenamety; + var filenum: integer): punitinfoty; +var + po1: punitinfoaty; + int1,int2: integer; +begin + result:= nil; + po1:= datapo; + filenum:= 0; + for int1:= 0 to fcount - 1 do begin //check includefiles first + for int2:= 1 to high(po1^[int1].info.sourcefiles) do begin + if issamefilename(afilename,po1^[int1].info.sourcefiles[int2].filename) then begin + filenum:= int2 + 1; + result:= po1^[int1].infopo; + break; + end; + end; + if result <> nil then begin + exit; + end; + end; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if issamefilename(afilename,po1^[int1].info.sourcefilename) then begin + filenum:= 1; + result:= po1^[int1].infopo; + break; + end; + end; +end; + +function tunitinfolist.finditembyunitname(const aname: string): punitinfoty; +begin + result:= fnamelist.find(struppercase(aname)); +end; + +{ tsourceupdater } + +procedure tsourceupdater.sourcechanged(const filename: filenamety); +begin + ffilenamelist.sourcefilemodified(filename); +end; + +function tsourceupdater.createscratchfile(const origname: filenamety): ttextstream; +begin + result:= ttextstream.create(origname + '.$$$',fm_create); +end; + +function tsourceupdater.gettext(const infopo: punitinfoty; + const startpos,endpos: sourceposty): msestring; +begin + result:= sourcefo.getfiletext(infopo^.sourcefilename,startpos.pos,endpos.pos); +end; + +procedure tsourceupdater.replacetext(const infopo: punitinfoty; + const startpos, endpos: sourceposty; const newtext: msestring); +begin + sourcefo.replacefiletext(infopo^.sourcefilename,startpos.pos,endpos.pos,newtext); +end; + +function tsourceupdater.updateline(module: punitinfoty; + var apos: sourceposty): boolean; +var + int1,int2: integer; + aincludefiles: integer; +begin + if apos.filenum > 0 then begin + result:= true; + apos.line:= apos.pos.row; + int2:= apos.filenum - 1; + with module^.sourcefiles[int2] do begin + inc(apos.line,startline); + aincludefiles:= includecount; + end; + for int1:= int2 + 1 to high(module^.sourcefiles) do begin + with module^.sourcefiles[int1] do begin + dec(aincludefiles); + if aincludefiles < 0 then begin + break; + end; + if apos.line <= startline then begin + break; + end; + inc(aincludefiles,includecount); + inc(apos.line,count); + end; + end; + end + else begin + result:= false; + end; +end; + +function tsourceupdater.updateline(module: punitinfoty; var apos: sourceposty; + const afilename: filenamety): boolean; +begin + apos.filename:= designer.designfiles.find(afilename); + result:= (apos.filename >= 0) and updateline(module,apos); +end; + +procedure tsourceupdater.checkitemlist(const infopo: punitinfoty); +var + int1: integer; +begin + with infopo^ do begin + if itemlist = nil then begin + itemlist:= tsourceitemlist.create; + for int1:= 0 to high(includestatements) do begin + with includestatements[int1] do begin + with itemlist.newitem(startpos,endpos,sik_include)^ do begin + index:= int1; + end; + end; + end; + case proglang of + pl_c: begin + end; + else begin + p.interfaceuses.getsourceitems(itemlist); + p.implementationuses.getsourceitems(itemlist); + end; + end; + end; + end; +end; + +function tsourceupdater.findsourceitem(const infopo: punitinfoty; + const apos: sourceposty): psourceitemty; +begin + checkitemlist(infopo); + result:= infopo^.itemlist.find(apos); +end; + +function tsourceupdater.findsourceitem(const infopo: punitinfoty; const apos: sourceposty; + out aindex: integer): psourceitemty; +begin + checkitemlist(infopo); + result:= infopo^.itemlist.find(apos,aindex); +end; + +function tsourceupdater.findsourceitem1(const infopo: punitinfoty; const apos: sourceposty; + out scope: tdeflist): pdefinfoty; +begin + with infopo^.deflist do begin + result:= finditem(apos,false,scope); + end; +end; + +function tsourceupdater.getitemtext(const aitem: sourceitemty): string; +var + infile: ttextstream; + int1: integer; +begin + infile:= sourcefo.gettextstream(designer.designfiles.getname(aitem.filename),false); + if infile <> nil then begin + try + infile.position:= aitem.startoffset; + int1:= aitem.endoffset - aitem.startoffset; + setlength(result,int1); + infile.ReadBuffer(result[1],int1); + finally + infile.Free; + end; + end + else begin + result:= ''; + end; +end; + +function tsourceupdater.getdefinfotext(const adef: pdefinfoty): string; +var + item1: sourceitemty; +begin + if adef^.kind in [syk_typedef,syk_vardef,syk_pardef,syk_classdef, + syk_procdef,syk_procimp, + syk_classprocimp,syk_interfacedef] then begin + item1.filename:= adef^.pos.filename; + item1.startoffset:= adef^.pos.offset; + item1.endoffset:= adef^.stop1.offset; + result:= getitemtext(item1); + end + else begin + result:= ''; + end; +end; + +function tsourceupdater.getidentpath(const infopo: punitinfoty; + const apos: sourceposty; const firstidentuse: boolean; + out scope: tdeflist): stringarty; + + procedure getidents(apo: pdefinfoty; const infile: ttextstream); + var + int1,int2,int3: integer; + begin + if infile <> nil then begin + try + int2:= 0; + if (apo <> nil) and (apo^.kind = syk_identuse) then begin + while (apo^.kind = syk_identuse) and + not (if_first in apo^.identflags) do begin + inc(int2); + dec(apo); + end; + setlength(result,int2+1); + for int1:= 0 to int2 do begin + infile.position:= apo^.pos.offset; + int3:= apo^.identlen; + if not((int1 = int2) and (apos.pos.col <= apo^.pos.pos.col) or + (apos.pos.row < apo^.pos.pos.row)) then begin + setlength(result[int1],int3); + infile.ReadBuffer(result[int1][1],int3); + //else '' + end; + inc(apo); + end; + end; + finally + infile.destroy; + end; + end; + end; + +var + po1: pdefinfoty; + pos1: sourceposty; + str1: string; + list1,list2: tdeflist; + +begin + result:= nil; + po1:= infopo^.deflist.finditem(apos,firstidentuse,scope); + if (po1 <> nil) then begin + case po1^.kind of + syk_identuse: begin + getidents(po1,sourcefo.gettextstream(designer.designfiles.getname( + po1^.pos.filename),false)); + end; + syk_typedef,syk_vardef,syk_pardef,syk_classdef,syk_procdef,syk_classprocimp, + syk_procimp,syk_interfacedef: begin + list1:= nil; + try + case infopo^.proglang of + pl_c: begin + parsecdef(po1,str1,list1); + end + else begin + parsepascaldef(po1,str1,list1); + end; + end; + pos1.line:= apos.line - po1^.pos.line; + if pos1.line = 0 then begin + pos1.pos.col:= apos.pos.col - po1^.pos.pos.col; + end + else begin + pos1.pos.col:= apos.pos.col; + end; + getidents(list1.finditem(pos1,false,list2),ttextstream.createdata(str1)); + finally + list1.Free; + end; + end; + end; + end; +end; + +function tsourceupdater.finddef(const infopo: punitinfoty; + const apos: sourceposty): pdefinfoty; +var + ar1: stringarty; + scope: tdeflist; + scopes: deflistarty; + defs: definfopoarty; +begin + application.beginwait; + try + result:= nil; + resetunitsearched; + ar1:= getidentpath(infopo,apos,false,scope); + if scope.finddef(ar1,scopes,defs,true,dsl_normal,syk_nopars) then begin + result:= defs[0]; + end; + finally + application.endwait; + end; +end; + +function tsourceupdater.finddef(const infopo: punitinfoty; + const typename: string): pdefinfoty; +var + ar1: stringarty; + scope: tdeflist; + scopes: deflistarty; + defs: definfopoarty; +begin + result:= nil; + resetunitsearched; + ar1:= splitstring(typename,'.'); + scope:= infopo^.deflist; + if scope.finddef(ar1,scopes,defs,true,dsl_normal,syk_nopars) then begin + result:= defs[0]; + end; +end; + +function tsourceupdater.listprocheaders(const infopo: punitinfoty; + const apos: sourceposty): procedureinfopoarty; +var + ar1: stringarty; + int1: integer; + scopes: deflistarty; + defs: definfopoarty; + scope1: tdeflist; + +begin + application.beginwait; + try + result:= nil; + resetunitsearched; + ar1:= getidentpath(infopo,apos,true,scope1); + if scope1.finddef(ar1,scopes,defs,false,dsl_normal,syk_nopars) then begin + for int1:= 0 to high(defs) do begin + if defs[int1]^.kind in [syk_procdef,syk_procimp] then begin + case scopes[int1].kind of + syk_classdef: begin + setlength(result,high(result) + 2); + result[high(result)]:= scopes[int1].rootlist.unitinfopo^. + p.classinfolist[scopes[int1].definfopo^.classindex]^. + procedurelist[defs[int1]^.procindex]; + end; + syk_root: begin + setlength(result,high(result) + 2); + result[high(result)]:= trootdeflist(scopes[int1]).rootlist.unitinfopo^. + p.procedurelist[defs[int1]^.procindex]; + end; + end; + end; + end; + end; + removearrayduplicates(pointerarty(result)); + finally + application.endwait; + end; +end; + +function tsourceupdater.listsourceitems(const infopo: punitinfoty; + const apos: sourceposty; out scopes: deflistarty; + out defs: definfopoarty; const maxcount: integer = 100): boolean; +var + ar1: stringarty; + scope1: tdeflist; +// ar2,ar4: deflistarty; +// ar3,ar5: definfopoarty; + int1,int2: integer; + +begin + application.beginwait; + try + resetunitsearched; + ar1:= getidentpath(infopo,apos,false,scope1); + result:= scope1.finddef(ar1,scopes,defs,false,dsl_normal,syk_substr,maxcount); + for int1:= 0 to high(defs) do begin //remove duplicates + if defs[int1] <> nil then begin + for int2:= int1 + 1 to high(defs) do begin + if defs[int2] = defs[int1] then begin + defs[int2]:= nil + end; + end; + end; + end; + int2:= 0; + for int1:= 0 to high(defs) do begin + if defs[int1] <> nil then begin + defs[int2]:= defs[int1]; + scopes[int2]:= scopes[int1]; + inc(int2); + end; + end; + setlength(defs,int2); + setlength(scopes,int2); + finally + application.endwait; + end; +end; + +function tsourceupdater.findunitfile(const aunitname: msestring): msestring; + + function dofind(const aname: filenamety): filenamety; + var + apage: tsourcepage; + begin + apage:= sourcefo.findsourcepage(aname,false); + if apage <> nil then begin + result:= apage.filepath; + end + else begin + result:= ''; + findfile(aname,projectoptions.d.texp.sourcedirs,result); + end; + end; + + function dofind1(const aunitname: filenamety): filenamety; + var + str1: msestring; + begin + result:= dofind(aunitname); + if result = '' then begin + str1:= mselowercase(aunitname); + if str1 <> aunitname then begin + result:= dofind(str1); + end; + if result = '' then begin + str1:= mseuppercase(aunitname); + if str1 <> aunitname then begin + result:= dofind(str1); + end; + end; + end; + end; + +begin + result:= dofind1(aunitname+'.pas'); + if result <> '' then exit; + result:= dofind1(aunitname+'.pp'); + if result <> '' then exit; + result:= dofind1(aunitname+'.mla'); +end; + +function tsourceupdater.findmethodpos(const amethod: tmethod; + const imp: boolean = false): sourceposty; +var + moduleinfo: pmoduleinfoty; + methodinfo: pmethodinfoty; +// unitinfo: punitinfoty; +// classinfo1: pclassinfoty; + procedureinfo: pprocedureinfoty; + ar1: classinfopoarty; + int1: integer; +begin + result:= emptysourcepos; + if amethod.data <> nil then begin + designer.getmethodinfo(amethod,moduleinfo,methodinfo); + if moduleinfo <> nil then begin + ar1:= designer.getancestorclassinfo(moduleinfo^.instance,false); + procedureinfo:= nil; + for int1:= high(ar1) downto 0 do begin + procedureinfo:= ar1[int1]^.procedurelist.finditembyname(methodinfo^.name); + if procedureinfo <> nil then begin + break; + end; + end; +// unitinfo:= updateformunit(moduleinfo^.filename,false); +// if unitinfo <> nil then begin +// classinfo1:= unitinfo^.p.classinfolist.finditembyname( +// moduleinfo^.moduleclassname,true); +// if classinfo1 <> nil then begin +// procedureinfo:= classinfo1^.procedurelist.finditembyname(methodinfo^.name); + if procedureinfo <> nil then begin + with procedureinfo^do begin + if imp and (impheaderendpos.filenum > 0) then begin + result:= impheaderendpos; + end + else begin + if intendpos.filenum > 0 then begin + result:= intendpos; + end + else begin + result:= impheaderendpos; + end; + end; + end; + end; +// end; +// end; + end; + end; +end; + +function tsourceupdater.switchheaderimplementation(const infopo: punitinfoty; + var headerstart,headerstop: sourceposty; + out isimplementation: boolean): boolean; +var + po1,po2: pdefinfoty; + scope: tdeflist; + str1: string; + ar1: stringarty; + bo1: boolean; + scopes: deflistarty; + defs: definfopoarty; + +begin + result:= false; + ar1:= nil; //compiler warning + isimplementation:= false; + with infopo^ do begin + po1:= deflist.finditem(headerstart,false,scope); + if po1 <> nil then begin + po2:= nil; + if po1^.kind = syk_procdef then begin + isimplementation:= true; + if scope.kind = syk_classdef then begin + str1:= scope.name + '.'+ po1^.name; //as direct procparameter delphi bug + po2:= scope.parent.find(str1,syk_classprocimp); + end + else begin + po2:= scope.find(po1^.name,syk_procimp); + if (po2 = nil) and (infopo^.proglang = pl_c) then begin + result:= findcfunctionimplementation(po1^.name,headerstart, + headerstop); + end; + end; + end + else begin + while (scope <> nil) and + not (scope.kind in [syk_root,syk_classdef]) do begin + po1:= scope.definfopo; + scope:= scope.parentscope; + end; + if scope <> nil then begin + ar1:= splitstring(po1^.name,'.'); + if scope.kind = syk_classdef then begin + bo1:= scope.finddef(copy(ar1,high(ar1),1),scopes,defs,true,dsl_normal); + end + else begin + bo1:= scope.finddef(ar1,scopes,defs,true,dsl_normal,syk_procdef); + end; + if bo1 then begin + po2:= defs[0]; + end; + end; + end; + if po2 <> nil then begin + headerstart:= po2^.pos; + headerstop:= po2^.stop1; + result:= true; + end; + end; + end; + if (headerstart.filenum = 0) or (headerstop.filenum = 0) then begin + result:= false; + end; +end; + +type + propinfoty = record + indextext: string; + typetext: stringarty; + getter: string; + setter: string; + end; + propinfoarty = array of propinfoty; + +function tsourceupdater.composeproceduretext(const name: string; + const info: methodparaminfoty; const withdefault: boolean): string; + +var + int1,int2: integer; +begin + result:= name; + with info do begin + int2:= high(params); + if kind in [mk_function,mk_procedurefunc,mk_methodfunc] then begin + dec(int2); + end; + if int2 >= 0 then begin + result:= result + '('; + for int1:= 0 to int2 do begin + with params[int1] do begin //todo: merge equal types + if pfconst in flags then begin + result:= result + 'const '; + end + else begin + if pfvar in flags then begin + result:= result + 'var '; + end + else begin + if pfout in flags then begin + result:= result + 'out '; + end; + end; + end; + result:= result + name; + if typename <> '' then begin + result:= result + ': '; + if pfarray in flags then begin + result:= result + 'array of '; + if typename = 'TVarRec' then begin + result:= result + 'const'; + end + else begin + result:= result + typename; + end; + end + else begin + result:= result + typename; + end; + if withdefault and (defaultvalue <> '') then begin + result:= result + ' = '+defaultvalue; + end; + end; + result:= result + '; '; + end; + end; + setlength(result,length(result)-1); //remove last space + result[length(result)]:= ')'; + end + else begin + if mef_brackets in flags then begin + result:= result + '()'; + end; + end; + if kind in [mk_function,mk_procedurefunc,mk_methodfunc] then begin + result:= result + ': ' + params[high(params)].typename; + end; + result:= result + ';'; + end; +end; + +function tsourceupdater.composeproceduretext(const infopo: pprocedureinfoty; + const withdefault: boolean): string; +begin + with infopo^ do begin + result:= composeproceduretext(name,params,withdefault); + end; +end; + +function tsourceupdater.composeprocedureheader(const infopo: pprocedureinfoty; + const withdefault: boolean): string; +begin + with infopo^ do begin + result:= composeprocedureheader(name,params,withdefault,classproc); + end; +end; + +procedure tsourceupdater.createmethodbody(const unitinfopo: punitinfoty; + const classinfopo: pclassinfoty; const aname: string; + const atype: ptypeinfo; beforeitem: integer); +var + str1: msestring; + pos1: sourceposty; + int1: integer; + bo1: boolean; +begin + pos1:= emptysourcepos; + bo1:= false; + if falphabeticprocorder then begin + with classinfopo^.procedurelist do begin + for int1:= beforeitem to count - 1 do begin + with items[int1]^ do begin + if not isemptysourcepos(impheaderstartpos) then begin + bo1:= true; + pos1:= impheaderstartpos; + break; + end; + end; + end; + end; + end; + if isemptysourcepos(pos1) then begin + pos1:= classinfopo^.procimpend; + if isemptysourcepos(pos1) then begin + pos1:= unitinfopo^.p.implementationend; + bo1:= true; + end; + end; + if pos1.filenum <> unitinfopo^.unitend.filenum then begin + pos1:= unitinfopo^.p.implementationend; + if pos1.filenum <> unitinfopo^.unitend.filenum then begin + pos1:= unitinfopo^.unitend; + end; + end; + if issamesourcepos(unitinfopo^.unitend,pos1) then begin + dec(pos1.line); //no 'end.' + dec(pos1.pos.row); + if pos1.pos.row < 0 then begin + exit; //invalid + end; + end; + if bo1 then begin + str1:= ''; + end + else begin + str1:= lineend; + end; + str1:= str1 + limitlinelength(msestring( + composeprocedureheader(classinfopo^.name+'.'+aname,atype,false,false)), + fmaxlinelength,procheaderbreakchars,14) + lineend; + str1:= str1 + 'begin' + lineend + 'end;' + lineend; + if bo1 then begin + str1:= str1 + lineend; + end; + replacetext(unitinfopo,pos1,pos1,str1); +end; + +function tsourceupdater.completeclass(const infopo: punitinfoty; + const pos: sourceposty): boolean; +var + ppo: pprocedureinfoty; + cpo: pclassinfoty; + scope: tdeflist; + int1: integer; + str1: msestring; + parser: tpascalparser; + po1: pchar; + ar1: propinfoarty; + + procedure insertprivate(const isfield: boolean; const atext: string); + var + int1: integer; + begin + completeclass:= true; + infopo^.interfacecompiled:= false; + int1:= length(breaklines(atext)); + with cpo^ do begin + if isfield then begin + replacetext(infopo,privatefieldend,privatefieldend, + msestring(' '+atext+lineend)); + inc(privatefieldend.pos.row,int1); + end + else begin + replacetext(infopo,privateend,privateend,msestring(' '+atext+lineend)); + end; + inc(privateend.pos.row,int1); + privateend.pos.col:= 0; + end; + end; + + procedure checkfield(const name: string; const propinfo: propinfoty); + var + scope1: tdeflist; + begin + if scope.finddef(name,syk_vardef,scope1) = nil then begin + insertprivate(true,name+': '+concatstrings(propinfo.typetext,'.')+';'); + end; + end; + + procedure checkproc(const issetter: boolean; const propinfo: propinfoty); + + function breakline(const atext: msestring): msestring; + begin + result:= limitlinelength(atext,fmaxlinelength,procheaderbreakchars,18); + end; + + var + scope1: tdeflist; + begin //checkproc + with propinfo do begin + if issetter then begin + if scope.finddef(setter,syk_nopars,scope1) = nil then begin + if indextext <> '' then begin + insertprivate(false,ansistring( + breakline('procedure '+msestring(setter+'('+ + indextext+'; const avalue: ')+ + msestring(concatstrings(typetext,'.')+');')))); + end + else begin + insertprivate(false,ansistring( + breakline('procedure '+msestring(setter)+'(const avalue: '+ + msestring(concatstrings(typetext,'.'))+');'))); + end; + end; + end + else begin + if scope.finddef(getter,syk_nopars,scope1) = nil then begin + if indextext <> '' then begin + insertprivate(false,ansistring( + breakline('function '+msestring(getter)+'('+msestring(indextext)+'): '+ + msestring(concatstrings(typetext,'.'))+';'))); + end + else begin + insertprivate(false,ansistring(breakline('function '+ + msestring(getter)+': '+ + msestring(concatstrings(typetext,'.'))))+';'); + end; + end; + end; + end; + end; + + procedure checklineinsert(const info: classinfoty; const startindex: int32; + const startline: int32; const linecount: int32); + var + po1,pe: pprocedureinfoty; + begin + po1:= info.procedurelist.datapo; + pe:= po1 + info.procedurelist.count; + while po1 < pe do begin + if po1^.impendpos.pos.row >= startindex then begin + inc(po1^.impendpos.pos.row,linecount); + end; + inc(po1); + end; + end; //checklineinsert + +var + po2: pdefinfoty; + atstart: boolean; + classindex1: integer; + str2: string; + i2: int32; + insertpos: sourceposty; + +begin //completeclass + result:= false; + with infopo^ do begin + cpo:= nil; + po2:= deflist.finditem(pos,false,scope); + if po2 <> nil then begin + if po2^.kind = syk_classdef then begin + scope:= po2^.deflist; + end; + if (scope <> nil) and (scope.kind = syk_classdef) then begin + classindex1:= scope.definfopo^.classindex; + cpo:= infopo^.p.classinfolist[classindex1]; + end + end; + if cpo <> nil then begin + with cpo^ do begin + ar1:= nil; + for int1:= 0 to high(scope.infos) do begin + with scope.infos[int1] do begin + if (kind = syk_vardef) and (vf_property in varflags) then begin + str2:= getdefinfotext(@scope.infos[int1]); + if str2 <> '' then begin + parser:= tpascalparser.create(designer.designfiles,str2); + try + with parser do begin + setlength(ar1,high(ar1)+2); + with ar1[high(ar1)] do begin + skipwhitespace; + nexttoken; //skip name + if checkoperator('[') then begin + po1:= token^.value.po; + if findoperator(']') then begin + indextext:= getlastorigtext(po1); + end; + end + else begin + indextext:= ''; + end; + if checkoperator(':') then begin + typetext:= getidentpath(parser); + getter:= ''; + setter:= ''; + if checkpropertyident(pid_read) then begin + getter:= getorigname; + if checkpropertyident(pid_write) then begin + setter:= getorigname; + end; + end + else begin + if checkpropertyident(pid_write) then begin + setter:= getorigname; + if checkpropertyident(pid_read) then begin + getter:= getorigname; + end; + end; + end; + end; + end; + end; + finally + parser.free; + end; + end; + end; + end; + end; + if ar1 <> nil then begin + if isemptysourcepos(privatestart) then begin + result:= true; + replacetext(infopo,managedend,managedend,' private'+lineend); + privatestart:= managedend; + inc(privatestart.pos.row); + privateend:= privatestart; + privateend.pos.col:= 0; + privatefieldend:= privateend; + end; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if getter <> '' then begin + if stringicomp(getter,setter) = 0 then begin + checkfield(getter,ar1[int1]); //fieldref + continue; + end + else begin + if startsstr('GET',struppercase(getter)) then begin + checkproc(false,ar1[int1]); + end + else begin + checkfield(getter,ar1[int1]); //fieldref + end; + end; + end; + if setter <> '' then begin + if startsstr('SET',struppercase(setter)) then begin + checkproc(true,ar1[int1]); + end + else begin + checkfield(setter,ar1[int1]); //fieldref + end; + end; + end; + end; + end; + if result then begin + updateunit(infopo,false); + end; + end; + cpo:= infopo^.p.classinfolist[classindex1]; + //cpo is invalid after updateunit + with cpo^ do begin + if isemptysourcepos(procimpstart) then begin + procimpstart:= infopo^.p.implementationend; + replacetext(infopo,procimpstart,procimpstart, + msestring('{ '+name+' }'+lineend+lineend)); + result:= true; + checklineinsert(cpo^,0,procimpstart.pos.row,2); + inc(procimpstart.pos.row,2); + procimpstart.pos.col:= 0; + procimpend:= procimpstart; + end; + insertpos:= procimpstart; + insertpos.pos.col:= 0; + atstart:= true; + for int1:= 0 to procedurelist.count - 1 do begin + ppo:= procedurelist[int1]; + with ppo^ do begin + if not (mef_abstract in params.flags) then begin + if isemptysourcepos(impheaderstartpos) then begin + if atstart then begin + str1:= ''; + end + else begin + str1:= lineend; + end; + str1:= str1 + + limitlinelength(msestring(composeprocedureheader(ppo,cpo,true)), + fmaxlinelength,procheaderbreakchars,14) + lineend + + 'begin'+lineend+ + 'end;'+lineend; + if atstart then begin + str1:= str1 + lineend; + end; + replacetext(infopo,insertpos,insertpos,str1); + result:= true; + i2:= high(breaklines(str1)); + checklineinsert(cpo^,insertpos.pos.row,int1,i2); + inc(insertpos.pos.row,i2); + end + else begin + insertpos.pos.row:= impendpos.pos.row; + atstart:= false; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tsourceupdater.methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; const aname: string; + const atype: ptypeinfo); + +var + po1: punitinfoty; + po2: pclassinfoty; + str1: string; + int1: integer; + pos1: sourceposty; + posindex: integer; + ar1: classinfopoarty; +begin + if atype^.Kind = tkmethod then begin + ar1:= designer.getancestorclassinfo(amodule,true); + if ar1 = nil then begin + exit; + end; + for int1:= high(ar1) downto 0 do begin + if ar1[int1]^.procedurelist.finditembyname(aname{,atype}) <> nil then begin + exit; + end; + end; + po2:= ar1[high(ar1)]; + po1:= updatemodule(amodule); +// po2:= findclassinfobyinstance(amodule,po1); +// if (po2 <> nil) and (po2^.procedurelist.finditembyname(aname{,atype}) = nil) then begin + pos1:= emptysourcepos; + str1:= uppercase(aname); + with po2^.procedurelist do begin + posindex:= count; + if falphabeticprocorder then begin + for int1:= 0 to count - 1 do begin + with items[int1]^ do begin + if uppername > str1 then begin + posindex:= int1; + pos1:= intinsertpos; + end; + break; + end; + end; + end; + end; + if isemptysourcepos(pos1) then begin + pos1:= po2^.managedend; + end; + if not isemptysourcepos(pos1) then begin + createmethodbody(po1,po2,aname,atype,posindex); + str1:= composeprocedureheader(aname,atype,false,false); + replacetext(po1,pos1,pos1, + limitlinelength(' ' + msestring(str1), + fmaxlinelength,procheaderbreakchars,18)+lineend); + end; + end; +//end; +end; + +procedure tsourceupdater.methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; const newname, oldname: string; + const atypeinfo: ptypeinfo); +var + po1: punitinfoty; + po2: pclassinfoty; + po3: pprocedureinfoty; + ar1: classinfopoarty; + ar2: unitinfopoarty; + int1: integer; +begin + ar1:= designer.getancestorclassinfo(amodule,false,ar2); + po1:= nil; + po2:= nil; + po3:= nil; + for int1:= high(ar1) downto 0 do begin + po1:= ar2[int1]; + if (po1 <> nil) and (ar1[int1] <> nil) then begin + po3:= ar1[int1]^.procedurelist.finditembyname(oldname); + if po3 <> nil then begin + po2:= ar1[int1]; + break; + end; + end; + end; +// po1:= updatemodule(amodule); +// po2:= findclassinfobyinstance(amodule,po1); +// if po2 <> nil then begin +// po3:= po2^.procedurelist.finditembyname(oldname{,atypeinfo}); + if po3 <> nil then begin + with po3^ do begin + name:= newname; + if not isemptysourcepos(impheaderstartpos) then begin + replacetext(po1,impheaderstartpos,impheaderendpos, + limitlinelength(msestring(composeprocedureheader(po3,po2,false)), + fmaxlinelength,procheaderbreakchars,14,impheaderstartpos.pos.col)); + end; + if not isemptysourcepos(intstartpos) then begin + replacetext(po1,intstartpos,intendpos, + limitlinelength(msestring(composeproceduretext(po3,false)),fmaxlinelength, + procheaderbreakchars,18,intstartpos.pos.col)); + end; + end; + end; +end; + +function tsourceupdater.getidentpath(const parser: tpascalparser): stringarty; +var + ident1: integer; +begin + result:= nil; + with parser do begin + ident1:= getident; + if (token^.kind = tk_name) and (ident1 < 0) then begin + additem(result,getorigname); + while checkoperator('.') do begin + if (token^.kind = tk_name) and (ident1 < 0) then begin + additem(result,getorigname); + end; + end; + end; + end; +end; + +function tsourceupdater.gettype(const adef: pdefinfoty): stringarty; +var + str1: string; + parser: tpascaldesignparser; + ident1: integer; + procinfo: procedureinfoty; +begin + result:= nil; + if adef^.kind in [syk_vardef,syk_procdef,syk_procimp] then begin + str1:= getdefinfotext(adef); + if str1 <> '' then begin + parser:= tpascaldesignparser.create(designer.designfiles,str1); + try + with parser do begin + ident1:= getident; + if adef^.kind = syk_vardef then begin + if (token^.kind = tk_name) and (ident1 < 0) then begin + nexttoken; + if checkoperator(':') then begin + result:= getidentpath(parser); + end; + end; + end + else begin + if ident1 = integer(pid_function) then begin + if parser.parseprocedureheader(pascalidentty(ident1),@procinfo) then begin + result:= splitidentpath( + procinfo.params.params[high(procinfo.params.params)].typename); + end; + end; + end; + end; + finally + parser.Free; + end; + end; + end; +end; + +function tsourceupdater.composeprocedureheader(const name: string; + const info: methodparaminfoty; const withdefault: boolean; + const classproc: boolean): string; +begin + result:= ''; + if classproc then begin + result:= 'class '; + end; + case info.kind of + mk_function: begin + result:= result + 'function '; + end; + mk_method,mk_methodfunc: begin + result:= result + 'method '; + end; + mk_constructor: begin + result:= result + 'constructor '; + end; + mk_destructor: begin + result:= result + 'destructor '; + end; + else begin + result:= result + 'procedure '; + end; + end; + result:= result + composeproceduretext(name,info,withdefault); +end; + +function tsourceupdater.composeprocedureheader(const infopo: pprocedureinfoty; + const classinfopo: pclassinfoty; const withdefault: boolean): string; +var + str1: string; +begin + with infopo^ do begin + if classinfopo <> nil then begin + str1:= classinfopo^.name + '.' + name; + end + else begin + str1:= name; + end; + result:= composeprocedureheader(str1,params,withdefault,infopo^.classproc); + end; +end; + +function tsourceupdater.composeprocedureheader(const name: string; + const typeinfo: ptypeinfo; + const withdefault: boolean; + const classproc: boolean): string; +var + info: methodparaminfoty; +begin + getmethodparaminfo(typeinfo,info); + result:= composeprocedureheader(name,info,withdefault,classproc); +end; + +constructor tsourceupdater.create(const adesigner: tdesigner); +begin + fmaxlinelength:= 80; + fdesigner:= adesigner; + designnotifications.registernotification(idesignnotification(self)); + funitinfolist:= tunitinfolist.create; + ffilenamelist:= tfilenamelist.create; + msedesignparser.updateunitinterface:= {$ifdef FPC}@{$endif}updateunitinterface; + msedesignparser.gettype:= {$ifdef FPC}@{$endif}gettype; + msedesignparser.resetunitsearched:= {$ifdef FPC}@{$endif}resetunitsearched; +end; + +destructor tsourceupdater.destroy; +begin + designnotifications.unregisternotification(idesignnotification(self)); + funitinfolist.free; + ffilenamelist.Free; + inherited; +end; + +procedure tsourceupdater.clear; +begin + funitinfolist.clear; + ffilenamelist.clear; +end; + +procedure tsourceupdater.unitchanged(const aunit: punitinfoty = nil); +var + int1: integer; +begin + if aunit <> nil then begin + aunit^.interfacecompiled:= false; + end + else begin + for int1:= 0 to funitinfolist.count - 1 do begin + funitinfolist[int1]^.interfacecompiled:= false; + end; + end; +end; + +procedure tsourceupdater.unitchanged(const asourcefilename: filenamety); +var + po1: punitinfoty; + int1: integer; +begin + po1:= funitinfolist.finditembysourcefilename(asourcefilename,int1); + if po1 <> nil then begin + unitchanged(po1); + end; +end; + +procedure tsourceupdater.resetunitsearched; + //resets all allreadysearchedflags of rootdeflists +var + int1: integer; +begin + for int1:= 0 to funitinfolist.count - 1 do begin + funitinfolist[int1]^.deflist.allreadysearched:= false; + end; +end; + +function tsourceupdater.getmatchingmethods(const amodule: tmsecomponent; + const atype: ptypeinfo): msestringarty; +var + po1: pclassinfoty; +begin + result:= nil; + po1:= parsemodule(amodule); + if po1 <> nil then begin + result:= po1^.procedurelist.matchedmethodnames(atype,true); + end; +end; + +procedure tsourceupdater.itemsmodified(const adesigner: idesigner; + const aitem: tobject); +begin + //dummy +end; + +procedure tsourceupdater.componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); +var + po1: punitinfoty; + po2: pclassinfoty; + po3,po4: pcompinfoty; + str1: string; + int1: integer; +begin + try + po1:= updatemodule(amodule); + except + exit; //no source file, no sourcepdate + end; + po2:= findclassinfobyinstance(amodule,po1); + str1:= uppercase(aitem.Name); + if po2 <> nil then begin + with po2^.componentlist do begin + po3:= nil; + po4:= datapo; + for int1:= 0 to count - 1 do begin + if po4^.uppername = str1 then begin + po3:= po4; + break; + end; + inc(po4); + end; + if po3 <> nil then begin + replacetext(po1,po3^.namepos,po3^.nameend,msestring(newname)); + end; + end; + end; +end; + +procedure tsourceupdater.moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin +end; + +procedure tsourceupdater.instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin +end; + +procedure tsourceupdater.iteminserted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); +var + po1,po4: punitinfoty; + po2: pclassinfoty; + po3: pmoduleinfoty; + pos1: sourceposty; + str1,str2: msestring; + classna,unitna: string; + int1: integer; + ar1: msestringarty; + ar2: stringarty; + first: boolean; +begin + try + po1:= updatemodule(amodule); + except + exit; //no source file, no sourcepdate + end; + updateunit(po1,true); + po2:= findclassinfobyinstance(amodule,po1); + str1:= msestring(uppercase(aitem.Name)); + pos1:= emptysourcepos; + if po2 <> nil then begin + if (csinline in aitem.componentstate) and + designer.checksubmodule(aitem,po3) then begin + classna:= po3^.moduleclassname; + po4:= updatemodule(po3^.instance); + if po4 <> nil then begin + unitna:= po4^.origunitname; + end; + end + else begin + classna:= aitem.ClassName; + unitna:= gettypedata(ptypeinfo(aitem.classinfo))^.unitname; + end; + if isemptysourcepos(pos1) then begin + pos1:= po2^.procedurestart; + end; + if not isemptysourcepos(pos1) then begin + str1:= msestring(' ' + aitem.Name + ': ' + classna+';' + lineend); + replacetext(po1,pos1,pos1,str1); + end; + with po1^.p.interfaceuses do begin + if (unitna <> '') then begin + if (startpos.filenum = endpos.filenum) and + not isemptysourcepos(startpos) then begin + str2:= gettext(po1,startpos,endpos); + ar2:= unitgroups.getneededunits(unitna); + first:= count = 0; + for int1:= 0 to high(ar2) do begin + if (find(ar2[int1]) = nil) then begin + if not first then begin + str2:= str2 + ','; + end + else begin + first:= false; + end; + str2:= str2 + msestring(ar2[int1]); + end + end; + if str2 <> '' then begin + ar1:= breaklines(str2); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= trim(ar1[int1]); + end; + if ar1[0] = '' then begin + deleteitem(ar1,0); + end; + str2:= concatstrings(ar1,''); + str2:= lineend+' '+ + limitlinelength(str2,fmaxlinelength,',',1,1); + end; + replacetext(po1,startpos,endpos,str2); + end; + end; + end; + end; +end; + +procedure tsourceupdater.itemdeleted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); +var + po1: punitinfoty; + po2: pclassinfoty; + po3: pcompinfoty; +begin + try + po1:= updatemodule(amodule); + except + exit; //no source file, no sourcepdate + end; + po2:= findclassinfobyinstance(amodule,po1); + if po2 <> nil then begin + po3:= po2^.componentlist.finditembyname(aitem.name); + if po3 <> nil then begin + with po3^ do begin + replacetext(po1,insertpos,endpos,''); + end; + end; + end; +end; + + +procedure tsourceupdater.showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); +begin + //dummy +end; + +procedure tsourceupdater.closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); +begin + //dummy +end; + +procedure tsourceupdater.moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + //dummy +end; + +procedure tsourceupdater.moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + //dummy +end; + +procedure tsourceupdater.moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + //dummy +end; + +function tsourceupdater.parsemodule(const amodule: tmsecomponent): pclassinfoty; +begin + result:= findclassinfobyinstance(amodule,updatemodule(amodule)); +end; + +procedure tsourceupdater.selectionchanged(const adesigner: idesigner; + const aselection: idesignerSelections); +begin + //dummy +end; + +procedure tsourceupdater.getincludefile(const sender: tparser; const scanner: tscanner); +var + infile: ttextstream; +begin + infile:= sourcefo.gettextstream(scanner.filename,false); + try + scanner.source:= infile.readdatastring; + finally + infile.Free; + end; +end; + +procedure tsourceupdater.updatepascalunit(const infopo: punitinfoty; + const interfaceonly: boolean); +var + scanner: tpascalscanner; + parser: tpascaldesignparser; + infile: ttextstream; + int1,int2,int3: integer; + ar1: stringarty; + ar3: msestringarty; +begin + ar3:= nil; //compiler warning + { + if not infopo^.interfacecompiled or + not infopo^.implementationcompiled and not interfaceonly then begin + if infopo^.unitname <> '' then begin + funitinfolist.fnamelist.delete(infopo^.unitname); + end; + } + scanner:= tpascalscanner.Create; + application.beginwait; + try + infile:= sourcefo.gettextstream(infopo^.sourcefilename,false); + scanner.setfilename(infopo^.sourcefilename,designer.designfiles); + try + scanner.source:= infile.readdatastring; + finally + infile.Free; + end; + parser:= tpascaldesignparser.create(infopo,designer.designfiles, + {$ifdef FPC}@{$endif}getincludefile,interfaceonly); + try + parser.includefiledirs:= projectoptions.d.texp.sourcedirs; + ar1:= nil; + int3:= 0; + for int1:= 0 to high(projectoptions.d.texp.defines) do begin + if int1 > high(projectoptions.d.defineson) then begin + break; + end; + if projectoptions.d.defineson[int1] then begin + ar3:= splitstring(projectoptions.d.texp.defines[int1],msechar(' ')); + for int2:= 0 to high(ar3) do begin + additem(ar1,string(ar3[int2]),int3); + end; + end; + end; + setlength(ar1,int3); + parser.startdefines:= ar1; + parser.scanner:= scanner; + { + if infopo^.unitname <> '' then begin + funitinfolist.fnamelist.add(infopo^.unitname,infopo); + end; + } + finally + parser.Free; + end; + finally + scanner.Free; + application.endwait; + end; +// end; +end; + +procedure tsourceupdater.updatecunit(const infopo: punitinfoty; + const interfaceonly: boolean); +var + scanner: tcscanner; + parser: tcdesignparser; + infile: ttextstream; + int1,int2,int3: integer; + ar1: stringarty; + ar3: msestringarty; +begin + ar3:= nil; //compiler warning + scanner:= tcscanner.Create; + application.beginwait; + try + infile:= sourcefo.gettextstream(infopo^.sourcefilename,false); + scanner.setfilename(infopo^.sourcefilename,designer.designfiles); + try + scanner.source:= infile.readdatastring; + finally + infile.Free; + end; + parser:= tcdesignparser.create(infopo,designer.designfiles, + {$ifdef FPC}@{$endif}getincludefile,interfaceonly); + try + parser.includefiledirs:= projectoptions.d.texp.sourcedirs; + ar1:= nil; + int3:= 0; + for int1:= 0 to high(projectoptions.d.texp.defines) do begin + if int1 > high(projectoptions.d.defineson) then begin + break; + end; + if projectoptions.d.defineson[int1] then begin + ar3:= splitstring(projectoptions.d.texp.defines[int1],msechar(' ')); + for int2:= 0 to high(ar3) do begin + additem(ar1,string(ar3[int2]),int3); + end; + end; + end; + setlength(ar1,int3); + parser.startdefines:= ar1; + parser.scanner:= scanner; + finally + parser.Free; + end; + finally + scanner.Free; + application.endwait; + end; +// end; +end; + +procedure tsourceupdater.updateunit(const infopo: punitinfoty; + const interfaceonly: boolean); +begin + if not infopo^.interfacecompiled or + not infopo^.implementationcompiled and not interfaceonly then begin + if infopo^.unitname <> '' then begin + funitinfolist.fnamelist.delete(ansistring(infopo^.unitname),true); + end; + case infopo^.proglang of + pl_c: begin + updatecunit(infopo,interfaceonly); + end + else begin + updatepascalunit(infopo,interfaceonly); + end; + end; + if infopo^.unitname <> '' then begin + funitinfolist.fnamelist.add(infopo^.unitname,infopo); + end; + end; +end; + +function tsourceupdater.updatemodule(const amodule: tmsecomponent): punitinfoty; +var + po1: pmoduleinfoty; +begin + result:= nil; + po1:= fdesigner.modules.findmodulebyinstance(amodule); + if po1 <> nil then begin + result:= updateformunit(po1^.filename,false); + end; +end; + +function tsourceupdater.updateformunit(const aformfilename: filenamety; + const interfaceonly: boolean): punitinfoty; +begin + result:= funitinfolist.finditembyformfilename(aformfilename); + if result = nil then begin + result:= funitinfolist.newitem(pl_pascal); + with result^ do begin + formfilename:= aformfilename; + sourcefilename:= replacefileext(aformfilename,'pas'); + end; + end; + updateunit(result,interfaceonly); + ffilenamelist.add(result^.sourcefilename,result); +end; + +procedure tsourceupdater.updateincludefilenum(module: punitinfoty; + const filename: filenamety; var filenum: integer); +var + int1: integer; +begin + filenum:= 0; + with module^ do begin + for int1:= 0 to high(sourcefiles) do begin + if issamefilename(filename,sourcefiles[int1].filename) then begin + filenum:= int1 + 1; + break; + end; + end; + end; +end; + +function tsourceupdater.updatesourceunit(const asourcefilename: filenamety; + out filenum: integer; const interfaceonly: boolean): punitinfoty; +begin + result:= funitinfolist.finditembysourcefilename(asourcefilename,filenum); + if result = nil then begin + result:= funitinfolist.newitem(findprogramlanguage(asourcefilename)); + with result^ do begin + formfilename:= replacefileext(asourcefilename,'mfm'); + sourcefilename:= asourcefilename; + end; + filenum:= 1; + end; + updateunit(result,interfaceonly); + ffilenamelist.add(asourcefilename,result); +end; + +function tsourceupdater.updateunitinterface(const aunitname: string): punitinfoty; +var + str1: filenamety; + int1: integer; +begin + result:= funitinfolist.finditembyunitname(aunitname); + if result <> nil then begin + updateunit(result,true); + end + else begin + str1:= findunitfile(msestring(aunitname)); + if str1 <> '' then begin + result:= updatesourceunit(str1,int1,true); + end + else begin + result:= nil; + end; + end; +end; + +procedure tsourceupdater.beforemake(const adesigner: idesigner; + const maketag: integer; var abort: boolean); +begin + //dummy +end; + +procedure tsourceupdater.aftermake(const adesigner: idesigner; + const exitcode: integer); +begin + //dummy +end; + +procedure tsourceupdater.beforefilesave(const adesigner: idesigner; + const afilename: filenamety); +begin + //dummy +end; + +function tsourceupdater.findcfunctionimplementation(const aname: ansistring; + out headerstart: sourceposty; + out headerstop: sourceposty): boolean; +var +// int1: integer; + po3: pfunctioninfoty; +// int2: integer; +// mstr1: filenamety; +begin + result:= false; + po3:= cglobals.findfunction(aname); + if po3 <> nil then begin + headerstart:= po3^.start; + headerstop:= po3^.stop; + result:= true; + end; +end; + +end. + diff --git a/mseide-msegui/apps/ide/stackform.mfm b/mseide-msegui/apps/ide/stackform.mfm new file mode 100644 index 0000000..944ed6f --- /dev/null +++ b/mseide-msegui/apps/ide/stackform.mfm @@ -0,0 +1,199 @@ +object stackfo: tstackfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + popupmenu = tpopupmenu1 + visible = False + bounds_x = 407 + bounds_y = 349 + bounds_cx = 254 + bounds_cy = 180 + container.frame.framei_right = 0 + container.frame.localprops = [frl_firight] + container.frame.localprops1 = [] + container.onlayout = formonchildscaled + container.bounds = ( + 0 + 0 + 244 + 180 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Stack' + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_proportional, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Stack' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000094080000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + 0000FF01EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + 0000FF02EDEDED01EBEBEB01EAEAEA01D6D6D601BDBDBD01C6C6C601C9C9C901 + B3B3B301B8B8B801D0D0D001BDBDBD0183838301ADADAD017E7E7E01C1C1C101 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F2010000FF03 + EBEBEB01EAEAEA01ACACAC0179797901A0A0A0019E9E9E019191910190909001 + A8A8A801C1C1C101959595017F7F7F0192929201D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F5010000FF06EAEAEA01BDBDBD01A1A1A101B6B6B601 + B7B7B701BFBFBF01A9A9A901BEBEBE01CFCFCF01B3B3B3019B9B9B01B4B4B401 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F5010000FF01F2F2F201 + 0000FF03EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301AFAFAF01 + DEDEDE01C4C4C401A9A9A901DBDBDB01DADADA01B4B4B401C9C9C901D5D5D501 + D3D3D301D2D2D201D0D0D001F5F5F5010000FF01F2F2F2010000FF02EDEDED01 + EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E3017E7E7E019A9A9A01 + 8686860178787801959595019494940179797901CFCFCF01D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F5010000FF01F2F2F2010000FF01EEEEEE01EDEDED01 + EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E3019B9B9B018B8B8B01 + 8F8F8F0198989801727272017070700194949401D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01 + EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001 + DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01 + EBEBEB01EAEAEA01D6D6D601BDBDBD01C6C6C601C9C9C901BBBBBB01A0A0A001 + B0B0B001D3D3D301DBDBDB01DADADA01D8D8D8016B6BEB010000FF03D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + ACACAC0179797901A0A0A0019E9E9E019B9B9B018E8E8E019090900192929201 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + BDBDBD01A1A1A101B6B6B601B7B7B701A7A7A701B1B1B101A1A1A101B8B8B801 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001C5C5C5019C9C9C01B6B6B601E8E8E802 + E4E4E401E5E5E501E1E1E101E2E2E201DFDFDF01DEDEDE01C6C6C601DBDBDB01 + DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001F5F5F501 + 0000FF01F2F2F201F0F0F001B2B2B2019B9B9B01B2B2B2015F5F5F01B1B1B101 + 5F5F5F019393930185858501E2E2E2018C8C8C017E7E7E0198989801DBDBDB01 + DADADA01D8D8D801D7D7D7010000FF01D3D3D3010000FF01D0D0D001F5F5F501 + 0000FF02F0F0F001C1C1C101DDDDDD01E7E7E7019D9D9D019898980197979701 + ADADAD0195959501E2E2E2019595950196969601A9A9A901DBDBDB01DADADA01 + D8D8D8010000FF02D3D3D3010000FF01D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01D2D2D201DBDBDB01DADADA010000FF03 + D3D3D3010000FF01D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001D9D9D901 + A4A4A401C1C1C101B0B0B001BABABA01B1B1B102B5B5B501A8A8A801B8B8B801 + 9D9D9D0199999901DBDBDB010000FF06D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001C1C1C1018B8B8B019A9A9A018F8F8F01A4A4A4017C7C7C019B9B9B01 + 80808001929292017A7A7A01A5A5A50196969601DBDBDB01DADADA010000FF03 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001E4E4E401 + BFBFBF01D4D4D401C2C2C201C7C7C701C5C5C501BEBEBE01C8C8C801B7B7B701 + CBCBCB01B9B9B901CECECE01DBDBDB01DADADA01D8D8D8010000FF02D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01 + EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001 + DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D7010000FF01D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01 + EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001 + DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001 + } + onshow = stackfoonshow + onlayout = formonchildscaled + moduleclassname = 'tdockform' + object grid: tstringgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -1879048187 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 20 + bounds_cx = 244 + bounds_cy = 160 + anchors = [an_top, an_bottom] + datacols.count = 5 + datacols.colorfocused = -1879048185 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_mousescrollrow] + datacols.items = < + item + color = -2147483646 + colorfocused = -1879048185 + width = 31 + options = [co_readonly, co_nofocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + textflags = [tf_xcentered, tf_ycentered] + valuefalse = '0' + valuetrue = '1' + end + item + colorselect = -1879048185 + colorfocused = -1879048185 + width = 54 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_cancopy] + textflags = [tf_ycentered, tf_noselect, tf_ellipseright] + textflagsactive = [tf_ycentered, tf_ellipseright] + optionsedit = [scoe_eatreturn, scoe_homeonenter] + valuefalse = '0' + valuetrue = '1' + end + item + colorfocused = -1879048185 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + optionsedit = [scoe_eatreturn] + valuefalse = '0' + valuetrue = '1' + end + item + colorfocused = -1879048185 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + valuefalse = '0' + valuetrue = '1' + end + item + colorfocused = -1879048185 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + valuefalse = '0' + valuetrue = '1' + end> + datarowheight = 16 + oncellevent = gridoncellevent + reffontheight = 14 + end + object filedisp: tstringdisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 71 + bounds_y = 0 + bounds_cx = 172 + bounds_cy = 18 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_ellipseleft] + options = [dwo_hintclippedtext] + reffontheight = 14 + end + object address: tstringdisp + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 1 + bounds_y = 0 + bounds_cx = 70 + bounds_cy = 18 + textflags = [tf_xcentered, tf_ycentered] + reffontheight = 14 + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Copy to Clipboard' + state = [as_localcaption, as_localonexecute] + onexecute = copytoclipboard + end> + menu.state = [as_localonexecute] + left = 48 + top = 56 + end +end diff --git a/mseide-msegui/apps/ide/stackform.pas b/mseide-msegui/apps/ide/stackform.pas new file mode 100644 index 0000000..b5895e2 --- /dev/null +++ b/mseide-msegui/apps/ide/stackform.pas @@ -0,0 +1,198 @@ +{ MSEide Copyright (c) 1999-2012 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit stackform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msegrids,msetypes,msegdbutils,msegui,msedispwidgets,msemenus, + mseguiintf,msegridsglob,msestrings; + +type + tstackfo = class(tdockform) + grid: tstringgrid; + filedisp: tstringdisp; + address: tstringdisp; + tpopupmenu1: tpopupmenu; + procedure stackfoonshow(const sender: tobject); + procedure gridoncellevent(const sender: tobject; var info: celleventinfoty); + procedure formonchildscaled(const sender: TObject); + procedure copytoclipboard(const sender: TObject); + private + frameinfo: frameinfoarty; + protected + procedure dispdetails; + public + gdb: tgdbmi; + procedure refresh; + procedure clear; + function showsource(const aframenr: integer): boolean; + function infotext(const aframenr: integer): msestring; + end; + +var + stackfo: tstackfo; + +implementation + +uses + sysutils,stackform_mfm,sourceform,msefileutils,mseformatstr,main,mseguiglob, + msegraphutils,projectoptionsform,msewidgets; + +{ tstackfo } + +function tstackfo.showsource(const aframenr: integer): boolean; +begin + result:= false; + if (aframenr >= 0) and (aframenr <= high(frameinfo)) then begin + grid.row:= aframenr; + with frameinfo[aframenr] do begin + if filename <> '' then begin + result:= sourcefo.showsourceline(sourcepath(filename),line-1,0,true) <> nil; + end; + end; + end; +end; + +function tstackfo.infotext(const aframenr: integer): msestring; +begin + if (aframenr >= 0) and (aframenr <= high(frameinfo)) then begin + with frameinfo[aframenr] do begin + result:= 'File: '+filename+':'+inttostrmse(line)+' '+'Function: '+ + msestring(func); + end; + end + else begin + result:= ''; + end; +end; + +procedure tstackfo.dispdetails; +begin +// if (grid.row < 0) and (grid.rowcount > 0) then begin +// grid.row:= 0; +// exit; +// end; + if grid.row >= 0 then begin + filedisp.value:= grid[2][grid.row]+':'+grid[3][grid.row]; + address.value:= grid[4][grid.row]; + end + else begin + filedisp.value:= ''; + address.value:= ''; + end; +end; + +procedure tstackfo.gridoncellevent(const sender: tobject; + var info: celleventinfoty); +var + rect1: rectty; +begin + with info do begin + case eventkind of + cek_focusedcellchanged: begin + dispdetails; + end; + cek_enter: begin + if (cellbefore.row >= 0) and (cellbefore.row <> newcell.row) then begin + mainfo.stackframechanged(newcell.row); + end; + end; + cek_firstmousepark: begin + if cell.col = 1 then begin + with tstringgrid(sender) do begin + if textclipped(cell,rect1) then begin + inc(rect1.cy,12); + application.showhint(twidget(sender),items[cell],rect1,cp_bottomleft,-1); + end; + end; + end; + end; + end; + if iscellclick(info,[ccr_dblclick]) then begin + showsource(cell.row); + end; + end; +end; + +procedure tstackfo.clear; +begin + grid.rowcount:= 0; + dispdetails; +end; + +procedure tstackfo.refresh; +var + int1,int2: integer; + str1: msestring; +begin + if visible and gdb.cancommand then begin + gdb.stacklistframes(frameinfo); + grid.beginupdate; + grid.row:= -1; + grid.rowcount:= length(frameinfo); + for int1:= 0 to high(frameinfo) do begin + with frameinfo[int1] do begin + grid[0][int1]:= inttostrmse(level); + str1:= msestring(func) + '('; + if high(params) >= 0 then begin + for int2:= 0 to high(params) do begin + str1:= str1 + msestring(params[int2].name) + '=' + + removelinebreaks(msestring(params[int2].value)) + ', '; + end; + setlength(str1,length(str1)-2); + end; + grid[1][int1]:= str1 + ')'; + grid[2][int1]:= filename; + grid[3][int1]:= inttostrmse(line); + grid[4][int1]:= hextostrmse(addr,8); + end; + end; + if grid.rowcount > 0 then begin + grid.row:= 0; + end; + grid.endupdate; + end; +end; + +procedure tstackfo.stackfoonshow(const sender: tobject); +begin + refresh; +end; + +procedure tstackfo.formonchildscaled(const sender: TObject); +begin + placeyorder(0,[0],[address,grid],0); + aligny(wam_center,[address,filedisp]); +end; + +procedure tstackfo.copytoclipboard(const sender: TObject); +var + mstr1: msestring; + int1: integer; +begin + mstr1:= ''; + for int1:= 0 to grid.rowhigh do begin + mstr1:= mstr1 + '#'+inttostrmse(int1)+' '+grid[4][int1]+' '+ + filename(grid[2][int1])+':'+ + grid[3][int1]+' '+grid[1][int1]+lineend; + end; + msewidgets.copytoclipboard(mstr1); +end; + +end. diff --git a/mseide-msegui/apps/ide/stackform_mfm.pas b/mseide-msegui/apps/ide/stackform_mfm.pas new file mode 100644 index 0000000..fdf63d8 --- /dev/null +++ b/mseide-msegui/apps/ide/stackform_mfm.pas @@ -0,0 +1,290 @@ +unit stackform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,stackform; + +const + objdata: record size: integer; data: array[0..5454] of byte end = + (size: 5455; data: ( + 84,80,70,48,8,116,115,116,97,99,107,102,111,7,115,116,97,99,107,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99, + 117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105, + 110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101, + 2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110, + 115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111, + 95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108, + 111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116, + 111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116, + 111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103, + 111,95,98,117,116,116,111,110,104,105,110,116,115,0,9,112,111,112,117,112, + 109,101,110,117,7,11,116,112,111,112,117,112,109,101,110,117,49,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,151,1,8,98, + 111,117,110,100,115,95,121,3,93,1,9,98,111,117,110,100,115,95,99,120, + 3,254,0,9,98,111,117,110,100,115,95,99,121,3,180,0,28,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95, + 114,105,103,104,116,2,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,11,102,114,108,95, + 102,105,114,105,103,104,116,0,27,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,99, + 111,110,116,97,105,110,101,114,46,111,110,108,97,121,111,117,116,7,17,102, + 111,114,109,111,110,99,104,105,108,100,115,99,97,108,101,100,16,99,111,110, + 116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,244, + 0,3,180,0,0,22,100,114,97,103,100,111,99,107,46,115,112,108,105,116, + 116,101,114,95,115,105,122,101,2,0,16,100,114,97,103,100,111,99,107,46, + 99,97,112,116,105,111,110,6,5,83,116,97,99,107,20,100,114,97,103,100, + 111,99,107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95, + 115,97,118,101,112,111,115,10,111,100,95,99,97,110,109,111,118,101,11,111, + 100,95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99, + 107,15,111,100,95,112,114,111,112,111,114,116,105,111,110,97,108,11,111,100, + 95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116,105,111,110, + 104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110,115,0,7, + 111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112,111,115,12, + 102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105, + 108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116, + 97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,5,83,116,97,99, + 107,21,105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103,101,10, + 200,8,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 148,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,0,0,255,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 0,0,255,2,237,237,237,1,235,235,235,1,234,234,234,1,214,214,214,1, + 189,189,189,1,198,198,198,1,201,201,201,1,179,179,179,1,184,184,184,1, + 208,208,208,1,189,189,189,1,131,131,131,1,173,173,173,1,126,126,126,1, + 193,193,193,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,0,0,255,3,235,235,235,1, + 234,234,234,1,172,172,172,1,121,121,121,1,160,160,160,1,158,158,158,1, + 145,145,145,1,144,144,144,1,168,168,168,1,193,193,193,1,149,149,149,1, + 127,127,127,1,146,146,146,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,0,0,255,6,234,234,234,1, + 189,189,189,1,161,161,161,1,182,182,182,1,183,183,183,1,191,191,191,1, + 169,169,169,1,190,190,190,1,207,207,207,1,179,179,179,1,155,155,155,1, + 180,180,180,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,0,0,255,1,242,242,242,1,0,0,255,3, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,175,175,175,1,222,222,222,1,196,196,196,1,169,169,169,1, + 219,219,219,1,218,218,218,1,180,180,180,1,201,201,201,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,0,0,255,1, + 242,242,242,1,0,0,255,2,237,237,237,1,235,235,235,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,126,126,126,1, + 154,154,154,1,134,134,134,1,120,120,120,1,149,149,149,1,148,148,148,1, + 121,121,121,1,207,207,207,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,0,0,255,1,242,242,242,1,0,0,255,1, + 238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,155,155,155,1,139,139,139,1, + 143,143,143,1,152,152,152,1,114,114,114,1,112,112,112,1,148,148,148,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,0,0,255,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1, + 229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1, + 221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 0,0,255,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,214,214,214,1,189,189,189,1,198,198,198,1, + 201,201,201,1,187,187,187,1,160,160,160,1,176,176,176,1,211,211,211,1, + 219,219,219,1,218,218,218,1,216,216,216,1,107,107,235,1,0,0,255,3, + 208,208,208,1,245,245,245,1,0,0,255,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,172,172,172,1, + 121,121,121,1,160,160,160,1,158,158,158,1,155,155,155,1,142,142,142,1, + 144,144,144,1,146,146,146,1,219,219,219,1,218,218,218,1,216,216,216,1, + 215,215,215,1,213,213,213,1,211,211,211,1,0,0,255,1,208,208,208,1, + 245,245,245,1,0,0,255,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,189,189,189,1,161,161,161,1, + 182,182,182,1,183,183,183,1,167,167,167,1,177,177,177,1,161,161,161,1, + 184,184,184,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,0,0,255,1,208,208,208,1,245,245,245,1, + 0,0,255,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,0,0,255,1,208,208,208,1,245,245,245,1,0,0,255,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 0,0,255,1,208,208,208,1,245,245,245,1,0,0,255,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1, + 224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1, + 216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,0,0,255,1, + 208,208,208,1,245,245,245,1,0,0,255,1,242,242,242,1,240,240,240,1, + 197,197,197,1,156,156,156,1,182,182,182,1,232,232,232,2,228,228,228,1, + 229,229,229,1,225,225,225,1,226,226,226,1,223,223,223,1,222,222,222,1, + 198,198,198,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,0,0,255,1,208,208,208,1,245,245,245,1, + 0,0,255,1,242,242,242,1,240,240,240,1,178,178,178,1,155,155,155,1, + 178,178,178,1,95,95,95,1,177,177,177,1,95,95,95,1,147,147,147,1, + 133,133,133,1,226,226,226,1,140,140,140,1,126,126,126,1,152,152,152,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,0,0,255,1, + 211,211,211,1,0,0,255,1,208,208,208,1,245,245,245,1,0,0,255,2, + 240,240,240,1,193,193,193,1,221,221,221,1,231,231,231,1,157,157,157,1, + 152,152,152,1,151,151,151,1,173,173,173,1,149,149,149,1,226,226,226,1, + 149,149,149,1,150,150,150,1,169,169,169,1,219,219,219,1,218,218,218,1, + 216,216,216,1,0,0,255,2,211,211,211,1,0,0,255,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1, + 229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1, + 210,210,210,1,219,219,219,1,218,218,218,1,0,0,255,3,211,211,211,1, + 0,0,255,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,217,217,217,1,164,164,164,1,193,193,193,1,176,176,176,1, + 186,186,186,1,177,177,177,2,181,181,181,1,168,168,168,1,184,184,184,1, + 157,157,157,1,153,153,153,1,219,219,219,1,0,0,255,6,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,193,193,193,1, + 139,139,139,1,154,154,154,1,143,143,143,1,164,164,164,1,124,124,124,1, + 155,155,155,1,128,128,128,1,146,146,146,1,122,122,122,1,165,165,165,1, + 150,150,150,1,219,219,219,1,218,218,218,1,0,0,255,3,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,228,228,228,1,191,191,191,1,212,212,212,1,194,194,194,1, + 199,199,199,1,197,197,197,1,190,190,190,1,200,200,200,1,183,183,183,1, + 203,203,203,1,185,185,185,1,206,206,206,1,219,219,219,1,218,218,218,1, + 216,216,216,1,0,0,255,2,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1, + 229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1, + 221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1, + 0,0,255,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,6,111,110,115,104,111,119,7, + 13,115,116,97,99,107,102,111,111,110,115,104,111,119,8,111,110,108,97,121, + 111,117,116,7,17,102,111,114,109,111,110,99,104,105,108,100,115,99,97,108, + 101,100,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9, + 116,100,111,99,107,102,111,114,109,0,11,116,115,116,114,105,110,103,103,114, + 105,100,4,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102, + 111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117, + 115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,5,99,111,108,111,114,4,5,0,0,144,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117, + 110,100,115,95,99,120,3,244,0,9,98,111,117,110,100,115,95,99,121,3, + 160,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97, + 110,95,98,111,116,116,111,109,0,14,100,97,116,97,99,111,108,115,46,99, + 111,117,110,116,2,5,21,100,97,116,97,99,111,108,115,46,99,111,108,111, + 114,102,111,99,117,115,101,100,4,7,0,0,144,16,100,97,116,97,99,111, + 108,115,46,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100, + 97,116,97,99,111,108,115,46,105,116,101,109,115,14,1,5,99,111,108,111, + 114,4,2,0,0,128,12,99,111,108,111,114,102,111,99,117,115,101,100,4, + 7,0,0,144,5,119,105,100,116,104,2,31,7,111,112,116,105,111,110,115, + 11,11,99,111,95,114,101,97,100,111,110,108,121,10,99,111,95,110,111,102, + 111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,0, + 9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116, + 101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101,100,0,10,118, + 97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114, + 117,101,6,1,49,0,1,11,99,111,108,111,114,115,101,108,101,99,116,4, + 7,0,0,144,12,99,111,108,111,114,102,111,99,117,115,101,100,4,7,0, + 0,144,5,119,105,100,116,104,2,54,7,111,112,116,105,111,110,115,11,11, + 99,111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,7,99,111,95,102,105,108,108,10,99,111,95,99,97,110,99,111,112, + 121,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,15,116, + 102,95,101,108,108,105,112,115,101,114,105,103,104,116,0,15,116,101,120,116, + 102,108,97,103,115,97,99,116,105,118,101,11,12,116,102,95,121,99,101,110, + 116,101,114,101,100,15,116,102,95,101,108,108,105,112,115,101,114,105,103,104, + 116,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111,101, + 95,101,97,116,114,101,116,117,114,110,16,115,99,111,101,95,104,111,109,101, + 111,110,101,110,116,101,114,0,10,118,97,108,117,101,102,97,108,115,101,6, + 1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,12,99,111, + 108,111,114,102,111,99,117,115,101,100,4,7,0,0,144,7,111,112,116,105, + 111,110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,0,11,111,112,116,105,111,110, + 115,101,100,105,116,11,14,115,99,111,101,95,101,97,116,114,101,116,117,114, + 110,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108, + 117,101,116,114,117,101,6,1,49,0,1,12,99,111,108,111,114,102,111,99, + 117,115,101,100,4,7,0,0,144,7,111,112,116,105,111,110,115,11,12,99, + 111,95,105,110,118,105,115,105,98,108,101,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,0,10,118,97,108,117,101,102,97,108,115,101,6,1, + 48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,12,99,111,108, + 111,114,102,111,99,117,115,101,100,4,7,0,0,144,7,111,112,116,105,111, + 110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,0,10,118,97,108,117,101,102,97, + 108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,11,111,110, + 99,101,108,108,101,118,101,110,116,7,15,103,114,105,100,111,110,99,101,108, + 108,101,118,101,110,116,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,100,105,115,112,8,102,105,108, + 101,100,105,115,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,71,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,172,0,9,98,111,117,110,100,115,95,99,121, + 2,18,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,9,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100, + 14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,7,111,112,116, + 105,111,110,115,11,19,100,119,111,95,104,105,110,116,99,108,105,112,112,101, + 100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,100,105,115,112,7,97,100,100, + 114,101,115,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,70,9,98,111, + 117,110,100,115,95,99,121,2,18,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101, + 110,116,101,114,101,100,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,10,116,112,111,112,117,112,109,101,110,117,11,116,112,111, + 112,117,112,109,101,110,117,49,18,109,101,110,117,46,115,117,98,109,101,110, + 117,46,99,111,117,110,116,2,1,18,109,101,110,117,46,115,117,98,109,101, + 110,117,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,17, + 67,111,112,121,32,116,111,32,67,108,105,112,98,111,97,114,100,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9, + 111,110,101,120,101,99,117,116,101,7,15,99,111,112,121,116,111,99,108,105, + 112,98,111,97,114,100,0,0,10,109,101,110,117,46,115,116,97,116,101,11, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,4, + 108,101,102,116,2,48,3,116,111,112,2,56,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstackfo,''); +end. diff --git a/mseide-msegui/apps/ide/storedcomponentinfodialog.mfm b/mseide-msegui/apps/ide/storedcomponentinfodialog.mfm new file mode 100644 index 0000000..f591246 --- /dev/null +++ b/mseide-msegui/apps/ide/storedcomponentinfodialog.mfm @@ -0,0 +1,107 @@ +object storedcomponentinfodialogfo: tstoredcomponentinfodialogfo + bounds_x = 172 + bounds_y = 228 + bounds_cx = 362 + bounds_cy = 255 + container.bounds = ( + 0 + 0 + 362 + 255 + ) + options = [fo_freeonclose, fo_screencentered, fo_cancelonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + onclosequery = doclosequery + moduleclassname = 'tmseform' + object tbutton1: tbutton + bounds_x = 240 + bounds_y = 224 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object tbutton2: tbutton + taborder = 1 + bounds_x = 304 + bounds_y = 224 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object filepath: tfilenameedit + frame.caption = '&File' + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 175 + bounds_cx = 348 + bounds_cy = 37 + anchors = [an_left, an_right, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_notnull] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'Component File' + '*.cmp' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'cmp' + controller.options = [fdo_save, fdo_checkexist, fdo_savelastdir] + controller.captionsave = 'Component File' + reffontheight = 14 + end + object compname: tstringedit + frame.caption = '&Name' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 8 + bounds_y = 7 + bounds_cx = 348 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + ondataentered = namedataentered + reffontheight = 14 + end + object compdesc: tmemoedit + frame.sbhorz.pagesize = 1 + frame.sbvert.pagesize = 1 + frame.caption = '&Description' + frame.localprops = [frl_colorclient] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 8 + bounds_y = 47 + bounds_cx = 348 + bounds_cy = 125 + anchors = [an_left, an_top, an_right, an_bottom] + reffontheight = 14 + end +end diff --git a/mseide-msegui/apps/ide/storedcomponentinfodialog.pas b/mseide-msegui/apps/ide/storedcomponentinfodialog.pas new file mode 100644 index 0000000..704114e --- /dev/null +++ b/mseide-msegui/apps/ide/storedcomponentinfodialog.pas @@ -0,0 +1,88 @@ +{ MSEide Copyright (c) 2008 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit storedcomponentinfodialog; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,componentstore,msesimplewidgets, + msewidgets,msebitmap,msedataedits,msedatanodes,mseedit,msefiledialog,msegrids, + mselistbrowser,msestrings,msesys,msetypes; +type + tstoredcomponentinfodialogfo = class(tmseform) + tbutton1: tbutton; + tbutton2: tbutton; + filepath: tfilenameedit; + compname: tstringedit; + compdesc: tmemoedit; + procedure doclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure namedataentered(const sender: TObject); + private + infopo: pstoredcomponentinfoty; + public + constructor create(var ainfo: storedcomponentinfoty); reintroduce; + procedure checkfilename; + end; +var + storedcomponentinfodialogfo: tstoredcomponentinfodialogfo; + +implementation +uses + storedcomponentinfodialog_mfm,msefileutils,actionsmodule; + +{ tstoredcomponentinfodialogfo } + +constructor tstoredcomponentinfodialogfo.create(var ainfo: storedcomponentinfoty); +begin + infopo:= @ainfo; + inherited create(nil); + with ainfo do begin + self.caption:= actionsmo.c[ord(ac_storecomponent)]+' '+ + msestring(componentname)+': '+msestring(compclass); + self.compname.value:= compname; + self.compdesc.value:= compdesc; + self.filepath.value:= filepath; + end; +end; + +procedure tstoredcomponentinfodialogfo.doclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); +begin + if amodalresult = mr_ok then begin + with infopo^ do begin + compname:= self.compname.value; + compdesc:= self.compdesc.value; + filepath:= self.filepath.value; + end; + end; +end; + +procedure tstoredcomponentinfodialogfo.namedataentered(const sender: TObject); +begin + checkfilename; +end; + +procedure tstoredcomponentinfodialogfo.checkfilename; +begin + if compname.value <> '' then begin + filepath.value:= uniquefilename(filedir(filepath.value) + + replacechar(compname.value,' ','_') + '.cmp'); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/storedcomponentinfodialog_mfm.pas b/mseide-msegui/apps/ide/storedcomponentinfodialog_mfm.pas new file mode 100644 index 0000000..b7909db --- /dev/null +++ b/mseide-msegui/apps/ide/storedcomponentinfodialog_mfm.pas @@ -0,0 +1,113 @@ +unit storedcomponentinfodialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,storedcomponentinfodialog; + +const + objdata: record size: integer; data: array[0..1905] of byte end = + (size: 1906; data: ( + 84,80,70,48,28,116,115,116,111,114,101,100,99,111,109,112,111,110,101,110, + 116,105,110,102,111,100,105,97,108,111,103,102,111,27,115,116,111,114,101,100, + 99,111,109,112,111,110,101,110,116,105,110,102,111,100,105,97,108,111,103,102, + 111,8,98,111,117,110,100,115,95,120,3,172,0,8,98,111,117,110,100,115, + 95,121,3,228,0,9,98,111,117,110,100,115,95,99,120,3,106,1,9,98, + 111,117,110,100,115,95,99,121,3,255,0,16,99,111,110,116,97,105,110,101, + 114,46,98,111,117,110,100,115,1,2,0,2,0,3,106,1,3,255,0,0, + 7,111,112,116,105,111,110,115,11,14,102,111,95,102,114,101,101,111,110,99, + 108,111,115,101,17,102,111,95,115,99,114,101,101,110,99,101,110,116,101,114, + 101,100,14,102,111,95,99,97,110,99,101,108,111,110,101,115,99,15,102,111, + 95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116, + 111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111, + 115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,12,111,110,99,108, + 111,115,101,113,117,101,114,121,7,12,100,111,99,108,111,115,101,113,117,101, + 114,121,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8, + 116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,49,8,98,111,117,110,100,115,95,120,3,240,0,8,98, + 111,117,110,100,115,95,121,3,224,0,9,98,111,117,110,100,115,95,99,120, + 2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108, + 116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105, + 111,110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7, + 5,109,114,95,111,107,0,0,7,116,98,117,116,116,111,110,8,116,98,117, + 116,116,111,110,50,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,3,48,1,8,98,111,117,110,100,115,95,121,3,224,0, + 9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95, + 99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97, + 112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0,0,13, + 116,102,105,108,101,110,97,109,101,101,100,105,116,8,102,105,108,101,112,97, + 116,104,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5,38,70, + 105,108,101,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108, + 111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110, + 46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,8,8, + 98,111,117,110,100,115,95,121,3,175,0,9,98,111,117,110,100,115,95,99, + 120,3,92,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99, + 104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117, + 112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115, + 97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,10,111,101,95,110,111,116,110,117,108,108,0,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101, + 100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101,108,108, + 105,112,115,101,108,101,102,116,0,26,99,111,110,116,114,111,108,108,101,114, + 46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,14, + 67,111,109,112,111,110,101,110,116,32,70,105,108,101,6,5,42,46,99,109, + 112,0,1,6,9,65,108,108,32,70,105,108,101,115,6,1,42,0,0,21, + 99,111,110,116,114,111,108,108,101,114,46,100,101,102,97,117,108,116,101,120, + 116,6,3,99,109,112,18,99,111,110,116,114,111,108,108,101,114,46,111,112, + 116,105,111,110,115,11,8,102,100,111,95,115,97,118,101,14,102,100,111,95, + 99,104,101,99,107,101,120,105,115,116,15,102,100,111,95,115,97,118,101,108, + 97,115,116,100,105,114,0,22,99,111,110,116,114,111,108,108,101,114,46,99, + 97,112,116,105,111,110,115,97,118,101,6,14,67,111,109,112,111,110,101,110, + 116,32,70,105,108,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,8,99,111,109, + 112,110,97,109,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 5,38,78,97,109,101,11,102,114,97,109,101,46,100,117,109,109,121,2,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,7, + 9,98,111,117,110,100,115,95,99,120,3,92,1,9,98,111,117,110,100,115, + 95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,13, + 111,110,100,97,116,97,101,110,116,101,114,101,100,7,15,110,97,109,101,100, + 97,116,97,101,110,116,101,114,101,100,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,9,116,109,101,109,111,101,100,105,116,8,99, + 111,109,112,100,101,115,99,21,102,114,97,109,101,46,115,98,104,111,114,122, + 46,112,97,103,101,115,105,122,101,2,1,21,102,114,97,109,101,46,115,98, + 118,101,114,116,46,112,97,103,101,115,105,122,101,2,1,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,12,38,68,101,115,99,114,105,112,116, + 105,111,110,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117, + 110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,47,9,98, + 111,117,110,100,115,95,99,120,3,92,1,9,98,111,117,110,100,115,95,99, + 121,2,125,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstoredcomponentinfodialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/stringconsts.mfm b/mseide-msegui/apps/ide/stringconsts.mfm new file mode 100644 index 0000000..351cd46 --- /dev/null +++ b/mseide-msegui/apps/ide/stringconsts.mfm @@ -0,0 +1,11 @@ +object s: tstringconstsmo + bounds_cx = 287 + bounds_cy = 100 + left = 100 + top = 100 + moduleclassname = 'tmsedatamodule' + object c: tstringcontainer + left = 16 + top = 16 + end +end diff --git a/mseide-msegui/apps/ide/stringconsts.pas b/mseide-msegui/apps/ide/stringconsts.pas new file mode 100644 index 0000000..eb76a47 --- /dev/null +++ b/mseide-msegui/apps/ide/stringconsts.pas @@ -0,0 +1,17 @@ +unit stringconsts; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseapplication,mseclasses,msedatamodules,msestringcontainer,msestrings; + +type + tstringconstsmo = class(tmsedatamodule) + c: tstringcontainer; + end; +var + s: tstringconstsmo; + +implementation +uses + stringconsts_mfm; +end. diff --git a/mseide-msegui/apps/ide/stringconsts_mfm.pas b/mseide-msegui/apps/ide/stringconsts_mfm.pas new file mode 100644 index 0000000..8b58533 --- /dev/null +++ b/mseide-msegui/apps/ide/stringconsts_mfm.pas @@ -0,0 +1,24 @@ +unit stringconsts_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,stringconsts; + +const + objdata: record size: integer; data: array[0..127] of byte end = + (size: 128; data: ( + 84,80,70,48,15,116,115,116,114,105,110,103,99,111,110,115,116,115,109,111, + 1,115,9,98,111,117,110,100,115,95,99,120,3,31,1,9,98,111,117,110, + 100,115,95,99,121,2,100,4,108,101,102,116,2,100,3,116,111,112,2,100, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,14,116,109, + 115,101,100,97,116,97,109,111,100,117,108,101,0,16,116,115,116,114,105,110, + 103,99,111,110,116,97,105,110,101,114,1,99,4,108,101,102,116,2,16,3, + 116,111,112,2,16,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstringconstsmo,''); +end. diff --git a/mseide-msegui/apps/ide/symbolform.mfm b/mseide-msegui/apps/ide/symbolform.mfm new file mode 100644 index 0000000..9e6d693 --- /dev/null +++ b/mseide-msegui/apps/ide/symbolform.mfm @@ -0,0 +1,235 @@ +object symbolfo: tsymbolfo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 142 + bounds_y = 257 + bounds_cx = 506 + bounds_cy = 137 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 496 + 137 + ) + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_cansize, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Symbols' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 00000000020000001800000018000000A8030000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D0607C7C7C19D9D9D916 + FFFFFF017C7C7C01D9D9D903B6B6B60199999901D5D5D501D9D9D901C2C2C201 + BCBCBC01D9D9D903C8C8C801BBBBBB01C2C2C201B2B2B201D9D9D903CCCCCC01 + AEAEAE01D9D9D901FFFFFF017C7C7C01D9D9D902555555010202020109090901 + 16161601BFBFBF019090900112121201D5D5D501D9D9D9023535350165656501 + 4F4F4F0103030301CCCCCC01D9D9D9026363630102020201D9D9D901FFFFFF01 + 7C7C7C01D9D9D901C7C7C7010B0B0B01B6B6B601D2D2D2013E3E3E014C4C4C01 + D9D9D901242424016F6F6F01D9D9D901AEAEAE0113131301D2D2D2014F4F4F01 + 0707070189898901D9D9D9023333330107070701D9D9D901FFFFFF017C7C7C01 + D9D9D901A4A4A4011F1F1F01D9D9D902A8A8A80165656501D9D9D90189898901 + 18181801D9D9D9013F3F3F0163636301D9D9D9014F4F4F012A2A2A0151515101 + D9D9D902262626010F0F0F01D9D9D901FFFFFF017C7C7C01D9D9D901D5D5D501 + 121212013030300195959501D9D9D9041F1F1F017171710116161601D2D2D201 + D9D9D9014F4F4F015656560126262601D9D9D901A7A7A7013E3E3E010F0F0F01 + D9D9D901FFFFFF017C7C7C01D9D9D902A6A6A6012C2C2C01010101011C1C1C01 + B8B8B801D9D9D902808080010404040163636301D9D9D9024F4F4F016C6C6C01 + 1A1A1A01D5D5D50165656501737373010F0F0F01D9D9D901FFFFFF017C7C7C01 + D9D9D904B4B4B4013B3B3B012B2B2B01D9D9D9030A0A0A01CFCFCF01D9D9D902 + 4F4F4F016C6C6C01393939019595950133333301BCBCBC010F0F0F01D9D9D901 + FFFFFF017C7C7C01D9D9D9017B7B7B015F5F5F01D9D9D902D2D2D20110101001 + D9D9D9030D0D0D01D5D5D501D9D9D9024F4F4F016C6C6C025858580128282801 + D9D9D9010F0F0F01D9D9D901FFFFFF017C7C7C01D9D9D9019B9B9B0116161601 + C4C4C401D9D9D9019292920122222201D9D9D9030D0D0D01D5D5D501D9D9D902 + 4F4F4F016C6C6C01B2B2B201191919013E3E3E01D9D9D9010F0F0F01D9D9D901 + FFFFFF017C7C7C01D9D9D9023C3C3C010909090121212101090909018A8A8A01 + D9D9D9030D0D0D01D5D5D501D9D9D9024F4F4F016C6C6C01D9D9D90111111101 + 73737301D9D9D9010F0F0F01D9D9D901FFFFFF017C7C7C01D9D9D9039B9B9B01 + 71717101B5B5B501D9D9D9048D8D8D01D9D9D903AEAEAE01B9B9B901D9D9D901 + 9C9C9C01C8C8C801D9D9D90190909001D9D9D901FFFFFF017C7C7C01D9D9D916 + FFFFFF017C7C7C01D9D9D916FFFFFF017C7C7C01FFFFFF17D0D0D06000000000 + 000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF0000000000000000000000000000000000 + } + onshow = showex + moduleclassname = 'tdockform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 496 + bounds_cy = 137 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 18 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 15 + captions.count = 3 + captions.items = < + item + caption = 'Symbol' + end + item + caption = 'Address' + end + item + caption = 'Info' + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612729 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datacols.count = 5 + datacols.options = [co_savevalue, co_savestate, co_cancopy, co_mousescrollrow] + datacols.items = < + item[symbol] + width = 111 + options = [co_savevalue, co_savestate, co_cancopy, co_canpaste] + options1 = [co1_rowfont, co1_zebracolor] + onchange = symbolcha + widgetname = 'symbol' + dataclass = tgridmsestringdatalist + end + item[symaddr] + width = 200 + options = [co_readonly, co_drawfocus, co_fill, co_savestate, co_cancopy, co_mousescrollrow] + widgetname = 'symaddr' + dataclass = tgridmsestringdatalist + end + item[syminfo] + width = 131 + options = [co_readonly, co_drawfocus, co_proportional, co_cancopy] + widthmin = 0 + widgetname = 'syminfo' + dataclass = tgridmsestringdatalist + end + item[path] + width = 15 + options = [co_invisible, co_cancopy, co_mousescrollrow] + widgetname = 'path' + dataclass = tgridmsestringdatalist + end + item[line] + width = 11 + options = [co_invisible, co_cancopy, co_mousescrollrow] + widgetname = 'line' + dataclass = tgridintegerdatalist + end> + datarowheight = 15 + statfile = mainfo.projectstatfile + oncellevent = cellev + reffontheight = 13 + object symbol: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 111 + bounds_cy = 15 + statfile = mainfo.projectstatfile + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = symboldataent + reffontheight = 13 + end + object symaddr: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 112 + bounds_y = 0 + bounds_cx = 200 + bounds_cy = 15 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_hintclippedtext] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + reffontheight = 13 + end + object syminfo: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 313 + bounds_y = 0 + bounds_cx = 131 + bounds_cy = 15 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_hintclippedtext] + reffontheight = 13 + end + object path: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 445 + bounds_y = 0 + bounds_cx = 15 + bounds_cy = 15 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 13 + end + object line: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 5 + visible = False + bounds_x = 461 + bounds_y = 0 + bounds_cx = 11 + bounds_cy = 15 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 13 + end + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Delete all' + state = [as_localcaption, as_localonexecute] + onexecute = deleteallex + end> + left = 80 + top = 72 + end + object c: tstringcontainer + strings.data = ( + 'GDB not active.' + 'Do you wish to delete all symbols?' + ) + left = 192 + top = 56 + end +end diff --git a/mseide-msegui/apps/ide/symbolform.pas b/mseide-msegui/apps/ide/symbolform.pas new file mode 100644 index 0000000..aa9fc3a --- /dev/null +++ b/mseide-msegui/apps/ide/symbolform.pas @@ -0,0 +1,149 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit symbolform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msedock,msedataedits, + mseedit,msegrids,msestrings,msetypes,msewidgetgrid,msegraphedits, + msestringcontainer; + +type + tsymbolfo = class(tdockform) + grid: twidgetgrid; + symbol: tstringedit; + syminfo: tstringedit; + symaddr: tstringedit; + tpopupmenu1: tpopupmenu; + path: tstringedit; + line: tintegeredit; + c: tstringcontainer; + procedure symboldataent(const sender: TObject); + procedure symbolcha(const sender: tdatacol; const aindex: Integer); + procedure deleteallex(const sender: TObject); + procedure cellev(const sender: TObject; var info: celleventinfoty); + procedure showex(const sender: TObject); + protected + procedure checksymbol(const aindex: integer); + public + procedure updatesymbols; + end; +var + symbolfo: tsymbolfo; + +implementation +uses + symbolform_mfm,msegdbutils,main,sysutils,msewidgets,mseformatstr,sourceform; +type + stringconsts = ( + gdbnotactive, //0 GDB not active. + deleteall //1 Do you wish to delete all symbols? + ); + +procedure tsymbolfo.checksymbol(const aindex: integer); +var + str1,str2: msestring; + err: gdbresultty; + mstr1: msestring; + int1: integer; + ad1,ad2,ad3: qword; +begin + str2:= trim(symbol[aindex]); + if str2 = '' then begin + syminfo[aindex]:= ''; + symaddr[aindex]:= ''; + end + else begin + if (length(str2) > 0) and (str2[1] = '$') then begin + str2:= '0x'+copy(str2,2,bigint); + end; + err:= mainfo.gdb.infosymbol(str2,str1); + if err = gdb_notactive then begin + mstr1:= c[ord(gdbnotactive)]; + syminfo[aindex]:= mstr1; + symaddr[aindex]:= mstr1; + exit; + end; + syminfo[aindex]:= trim(removelinebreaks(str1)); + path[aindex]:= ''; + line[aindex]:= 0; + if not msestartsstr('0x',str2) then begin + mainfo.gdb.infoaddress(str2,str1); + end + else begin + str1:= ''; + if trystrtointvalue64(ansistring(str2),ad1) then begin + if mainfo.gdb.infoline(ad1,mstr1,int1,ad2,ad3) = gdb_ok then begin + path[aindex]:= mstr1; + line[aindex]:= int1; + str1:= mstr1+':'+inttostrmse(int1); + end; + end; + end; + symaddr[aindex]:= trim(removelinebreaks(str1)); + end; +end; + +procedure tsymbolfo.symboldataent(const sender: TObject); +begin + checksymbol(grid.row); +end; + +procedure tsymbolfo.symbolcha(const sender: tdatacol; const aindex: Integer); +var + int1: integer; +begin + if not grid.updating then begin + if aindex < 0 then begin + for int1:= 0 to grid.rowhigh do begin + checksymbol(int1); + end; + end + else begin + checksymbol(aindex); + end; + end; +end; + +procedure tsymbolfo.updatesymbols; +begin + if visible then begin + symbolcha(nil,-1); + end; +end; + +procedure tsymbolfo.deleteallex(const sender: TObject); +begin + if askyesno(c[ord(deleteall)]) then begin + grid.clear; + end; +end; + +procedure tsymbolfo.cellev(const sender: TObject; var info: celleventinfoty); +begin + if iscellclick(info,[ccr_dblclick]) then begin + sourcefo.showsourceline(path[info.cell.row],line[info.cell.row]-1,0,true); + end; +end; + +procedure tsymbolfo.showex(const sender: TObject); +begin + updatesymbols; +end; + +end. diff --git a/mseide-msegui/apps/ide/symbolform_mfm.pas b/mseide-msegui/apps/ide/symbolform_mfm.pas new file mode 100644 index 0000000..70f3f15 --- /dev/null +++ b/mseide-msegui/apps/ide/symbolform_mfm.pas @@ -0,0 +1,316 @@ +unit symbolform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,symbolform; + +const + objdata: record size: integer; data: array[0..5974] of byte end = + (size: 5975; data: ( + 84,80,70,48,9,116,115,121,109,98,111,108,102,111,8,115,121,109,98,111, + 108,102,111,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101,2,10, + 18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110,115,11, + 14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111,95,102, + 105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108,111,97, + 116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110, + 19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110, + 15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95, + 98,117,116,116,111,110,104,105,110,116,115,0,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,142,0,8,98,111,117,110,100,115, + 95,121,3,1,1,9,98,111,117,110,100,115,95,99,120,3,250,1,9,98, + 111,117,110,100,115,95,99,121,3,137,0,26,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114, + 46,98,111,117,110,100,115,1,2,0,2,0,3,240,1,3,137,0,0,20, + 100,114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111,99,107, + 11,10,111,100,95,115,97,118,101,112,111,115,13,111,100,95,115,97,118,101, + 122,111,114,100,101,114,10,111,100,95,99,97,110,109,111,118,101,10,111,100, + 95,99,97,110,115,105,122,101,11,111,100,95,99,97,110,102,108,111,97,116, + 10,111,100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111,112,115, + 105,122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,13,111, + 100,95,99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105,111,110, + 115,11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118, + 101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101, + 0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112, + 114,111,106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112,116,105, + 111,110,6,7,83,121,109,98,111,108,115,21,105,99,111,110,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,12,105, + 99,111,110,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,0,10,105,99,111,110,46,105,109,97,103,101,10,60,4,0,0, + 0,0,0,0,2,0,0,0,24,0,0,0,24,0,0,0,168,3,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,96,124,124,124,25, + 217,217,217,22,255,255,255,1,124,124,124,1,217,217,217,3,182,182,182,1, + 153,153,153,1,213,213,213,1,217,217,217,1,194,194,194,1,188,188,188,1, + 217,217,217,3,200,200,200,1,187,187,187,1,194,194,194,1,178,178,178,1, + 217,217,217,3,204,204,204,1,174,174,174,1,217,217,217,1,255,255,255,1, + 124,124,124,1,217,217,217,2,85,85,85,1,2,2,2,1,9,9,9,1, + 22,22,22,1,191,191,191,1,144,144,144,1,18,18,18,1,213,213,213,1, + 217,217,217,2,53,53,53,1,101,101,101,1,79,79,79,1,3,3,3,1, + 204,204,204,1,217,217,217,2,99,99,99,1,2,2,2,1,217,217,217,1, + 255,255,255,1,124,124,124,1,217,217,217,1,199,199,199,1,11,11,11,1, + 182,182,182,1,210,210,210,1,62,62,62,1,76,76,76,1,217,217,217,1, + 36,36,36,1,111,111,111,1,217,217,217,1,174,174,174,1,19,19,19,1, + 210,210,210,1,79,79,79,1,7,7,7,1,137,137,137,1,217,217,217,2, + 51,51,51,1,7,7,7,1,217,217,217,1,255,255,255,1,124,124,124,1, + 217,217,217,1,164,164,164,1,31,31,31,1,217,217,217,2,168,168,168,1, + 101,101,101,1,217,217,217,1,137,137,137,1,24,24,24,1,217,217,217,1, + 63,63,63,1,99,99,99,1,217,217,217,1,79,79,79,1,42,42,42,1, + 81,81,81,1,217,217,217,2,38,38,38,1,15,15,15,1,217,217,217,1, + 255,255,255,1,124,124,124,1,217,217,217,1,213,213,213,1,18,18,18,1, + 48,48,48,1,149,149,149,1,217,217,217,4,31,31,31,1,113,113,113,1, + 22,22,22,1,210,210,210,1,217,217,217,1,79,79,79,1,86,86,86,1, + 38,38,38,1,217,217,217,1,167,167,167,1,62,62,62,1,15,15,15,1, + 217,217,217,1,255,255,255,1,124,124,124,1,217,217,217,2,166,166,166,1, + 44,44,44,1,1,1,1,1,28,28,28,1,184,184,184,1,217,217,217,2, + 128,128,128,1,4,4,4,1,99,99,99,1,217,217,217,2,79,79,79,1, + 108,108,108,1,26,26,26,1,213,213,213,1,101,101,101,1,115,115,115,1, + 15,15,15,1,217,217,217,1,255,255,255,1,124,124,124,1,217,217,217,4, + 180,180,180,1,59,59,59,1,43,43,43,1,217,217,217,3,10,10,10,1, + 207,207,207,1,217,217,217,2,79,79,79,1,108,108,108,1,57,57,57,1, + 149,149,149,1,51,51,51,1,188,188,188,1,15,15,15,1,217,217,217,1, + 255,255,255,1,124,124,124,1,217,217,217,1,123,123,123,1,95,95,95,1, + 217,217,217,2,210,210,210,1,16,16,16,1,217,217,217,3,13,13,13,1, + 213,213,213,1,217,217,217,2,79,79,79,1,108,108,108,2,88,88,88,1, + 40,40,40,1,217,217,217,1,15,15,15,1,217,217,217,1,255,255,255,1, + 124,124,124,1,217,217,217,1,155,155,155,1,22,22,22,1,196,196,196,1, + 217,217,217,1,146,146,146,1,34,34,34,1,217,217,217,3,13,13,13,1, + 213,213,213,1,217,217,217,2,79,79,79,1,108,108,108,1,178,178,178,1, + 25,25,25,1,62,62,62,1,217,217,217,1,15,15,15,1,217,217,217,1, + 255,255,255,1,124,124,124,1,217,217,217,2,60,60,60,1,9,9,9,1, + 33,33,33,1,9,9,9,1,138,138,138,1,217,217,217,3,13,13,13,1, + 213,213,213,1,217,217,217,2,79,79,79,1,108,108,108,1,217,217,217,1, + 17,17,17,1,115,115,115,1,217,217,217,1,15,15,15,1,217,217,217,1, + 255,255,255,1,124,124,124,1,217,217,217,3,155,155,155,1,113,113,113,1, + 181,181,181,1,217,217,217,4,141,141,141,1,217,217,217,3,174,174,174,1, + 185,185,185,1,217,217,217,1,156,156,156,1,200,200,200,1,217,217,217,1, + 144,144,144,1,217,217,217,1,255,255,255,1,124,124,124,1,217,217,217,22, + 255,255,255,1,124,124,124,1,217,217,217,22,255,255,255,1,124,124,124,1, + 255,255,255,23,208,208,208,96,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0, + 255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0, + 255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0, + 255,255,255,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,6,111,110,115,104,111,119,7,6,115,104,111,119,101,120,15, + 109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9,116,100,111, + 99,107,102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105,100,4, + 103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111,99,117, + 115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115,101,119, + 104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,9,111,119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,9,112,111,112,117,112,109,101, + 110,117,7,11,116,112,111,112,117,112,109,101,110,117,49,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,240,1,9,98,111,117,110,100,115,95,99,121, + 3,137,0,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105,111,110, + 115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12, + 111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114, + 111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114, + 116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15, + 111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97, + 117,116,111,97,112,112,101,110,100,10,111,103,95,119,114,97,112,99,111,108, + 12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,99,111, + 108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105, + 116,101,109,115,14,1,5,119,105,100,116,104,2,18,8,110,117,109,115,116, + 97,114,116,2,1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105, + 120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119, + 115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,15,14,99, + 97,112,116,105,111,110,115,46,99,111,117,110,116,2,3,14,99,97,112,116, + 105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110, + 6,6,83,121,109,98,111,108,0,1,7,99,97,112,116,105,111,110,6,7, + 65,100,100,114,101,115,115,0,1,7,99,97,112,116,105,111,110,6,4,73, + 110,102,111,0,0,0,0,14,114,111,119,102,111,110,116,115,46,99,111,117, + 110,116,2,1,14,114,111,119,102,111,110,116,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,7,0,0,160,4,110,97,109,101,6,11,115, + 116,102,95,100,101,102,97,117,108,116,6,120,115,99,97,108,101,2,1,10, + 108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111, + 114,10,102,108,112,95,120,115,99,97,108,101,0,0,0,14,100,97,116,97, + 99,111,108,115,46,99,111,117,110,116,2,5,16,100,97,116,97,99,111,108, + 115,46,111,112,116,105,111,110,115,11,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109, + 115,14,7,6,115,121,109,98,111,108,1,5,119,105,100,116,104,2,111,7, + 111,112,116,105,111,110,115,11,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,0,8,111, + 112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111,110,116, + 14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,0,8,111,110,99, + 104,97,110,103,101,7,9,115,121,109,98,111,108,99,104,97,10,119,105,100, + 103,101,116,110,97,109,101,6,6,115,121,109,98,111,108,9,100,97,116,97, + 99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,7,7,115,121,109,97,100,100,114,1, + 5,119,105,100,116,104,3,200,0,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111, + 99,117,115,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,7,115,121,109,97,100,100,114,9,100,97,116,97,99, + 108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,7,7,115,121,109,105,110,102,111,1,5, + 119,105,100,116,104,3,131,0,7,111,112,116,105,111,110,115,11,11,99,111, + 95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99, + 117,115,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,10,99, + 111,95,99,97,110,99,111,112,121,0,8,119,105,100,116,104,109,105,110,2, + 0,10,119,105,100,103,101,116,110,97,109,101,6,7,115,121,109,105,110,102, + 111,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,4,112,97, + 116,104,1,5,119,105,100,116,104,2,15,7,111,112,116,105,111,110,115,11, + 12,99,111,95,105,110,118,105,115,105,98,108,101,10,99,111,95,99,97,110, + 99,111,112,121,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,4,112,97,116,104, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,4,108,105,110, + 101,1,5,119,105,100,116,104,2,11,7,111,112,116,105,111,110,115,11,12, + 99,111,95,105,110,118,105,115,105,98,108,101,10,99,111,95,99,97,110,99, + 111,112,121,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,4,108,105,110,101,9, + 100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101, + 103,101,114,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111, + 119,104,101,105,103,104,116,2,15,8,115,116,97,116,102,105,108,101,7,22, + 109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105, + 108,101,11,111,110,99,101,108,108,101,118,101,110,116,7,6,99,101,108,108, + 101,118,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,11, + 116,115,116,114,105,110,103,101,100,105,116,6,115,121,109,98,111,108,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,111,9,98,111,117,110,100,115, + 95,99,121,2,15,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110, + 102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,24, + 111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118, + 97,108,117,101,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,18,111,101,95,104,105,110,116,99,108,105,112, + 112,101,100,116,101,120,116,0,13,111,110,100,97,116,97,101,110,116,101,114, + 101,100,7,13,115,121,109,98,111,108,100,97,116,97,101,110,116,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,7,115,121,109,97,100,100,114,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,2,112,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,200,0,9,98,111,117,110,100,115,95,99,121,2,15, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,18,111,101,95,104,105,110,116,99,108,105, + 112,112,101,100,116,101,120,116,0,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115, + 101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,7,115,121,109,105,110,102,111,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,3,57,1,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,131,0,9,98,111,117,110,100,115, + 95,99,121,2,15,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97, + 100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101, + 116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,18,111,101,95,104,105, + 110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,13,0,0,11,116,115,116,114,105,110,103, + 101,100,105,116,4,112,97,116,104,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 8,116,97,98,111,114,100,101,114,2,4,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,3,189,1,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,15,9,98,111,117,110, + 100,115,95,99,121,2,15,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14, + 111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,4,108,105,110,101,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,5,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,205,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 11,9,98,111,117,110,100,115,95,99,121,2,15,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 13,0,0,0,10,116,112,111,112,117,112,109,101,110,117,11,116,112,111,112, + 117,112,109,101,110,117,49,18,109,101,110,117,46,115,117,98,109,101,110,117, + 46,99,111,117,110,116,2,1,18,109,101,110,117,46,115,117,98,109,101,110, + 117,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,10,68, + 101,108,101,116,101,32,97,108,108,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116, + 101,7,11,100,101,108,101,116,101,97,108,108,101,120,0,0,4,108,101,102, + 116,2,80,3,116,111,112,2,72,0,0,16,116,115,116,114,105,110,103,99, + 111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100, + 97,116,97,1,6,15,71,68,66,32,110,111,116,32,97,99,116,105,118,101, + 46,6,34,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,100,101, + 108,101,116,101,32,97,108,108,32,115,121,109,98,111,108,115,63,0,4,108, + 101,102,116,3,192,0,3,116,111,112,2,56,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsymbolfo,''); +end. diff --git a/mseide-msegui/apps/ide/syntaxdefs/cpp.sdef b/mseide-msegui/apps/ide/syntaxdefs/cpp.sdef new file mode 100644 index 0000000..51ee909 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/cpp.sdef @@ -0,0 +1,80 @@ +styles + default '' + words 'b' + comment 'i' cl_blue + macros 'b' cl_blue + string '' cl_blue + +keyworddefs cpp + '__asm' '_asm' 'asm' 'auto' 'break' 'case' 'catch' 'cdecl' 'char' 'class' 'const' words + 'continue' '__cs' '_cs' 'default' 'delete' 'do' 'double' '__ds' '_ds' 'else' words + 'enum' 'extern' '__far' '_far' 'far' '__fastcall' '_fastcall' 'fastcall' '__finally' words + 'float' 'for' 'friend' 'goto' 'huge' '__huge' '_huge' 'if' '__import' 'inline' words + 'int' 'interrupt' '__interrupt' '_interrupt' '__loaddds' '_loadds' 'long' 'near' words + '_near' '__near' 'new' 'operator' '__pascal' '_pascal' 'pascal' 'private' 'protected' words + 'public' 'register' 'return' '__rtti' '__saveregs' '_saveregs' '__seg' '_seg' 'short' words + 'signed' 'sizeof' '__ss' '_ss' 'static' '__stdcall' '_stdcall' 'struct' 'switch' words + 'template' 'this' '__thread' 'throw' '__try' 'try' 'typedef' 'union' 'unsigned' words + 'virtual' 'void' 'volatile' 'while' words + +scope escapechar string + endtokens +# return on any char + +scope string string + calltokens + '\' escapechar + endtokens + '"' + +scope string1 string + calltokens + '\' escapechar + endtokens + '''' + +scope comment1 comment + endtokens + '*/' + +scope comment2 comment + endtokens + '' + +scope macros macros + + jumptokens + '/*' comment1 + '//' comment2 + + endtokens + '' +scope block + keywords + cpp + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + '{' block default + + endtokens + '}' default + +scope main + + keywords words + cpp + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + '{' block default + + diff --git a/mseide-msegui/apps/ide/syntaxdefs/glsl.sdef b/mseide-msegui/apps/ide/syntaxdefs/glsl.sdef new file mode 100644 index 0000000..ad39fe5 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/glsl.sdef @@ -0,0 +1,88 @@ +styles + default '' + words 'b' + comment 'i' cl_blue + macros 'b' cl_blue + string '' cl_blue + +keyworddefs glsl + 'and' 'attribute' 'bool' 'break' 'bvec2' 'bvec3' 'bvec4' 'case' 'centroid' words + 'const' 'continue' 'default' 'discard' 'dmat2' 'dmat2x2' 'dmat2x3' 'dmat2x4' words + 'dmat3' 'dmat3x2' 'dmat3x3' 'dmat3x4' 'dmat4' 'dmat4x2' 'dmat4x3' 'dmat4x4' words + 'do' 'double' 'dvec2' 'dvec3' 'dvec4' 'else' 'flat' 'float' 'for' 'highp' words + 'if' 'in' 'inout' 'int' 'invariant' 'isampler1D' 'isampler1DArray' 'isampler2D' words + 'isampler2DArray' 'isampler2DMS' 'isampler2DMSArray' 'isampler2DRect' 'isampler3D' words + 'isamplerBuffer' 'isamplerCube' 'isamplerCubeArray' 'ivec2' 'ivec3' 'ivec4' words + 'layout' 'lowp' 'mat2' 'mat2x2' 'mat2x3' 'mat2x4' 'mat3' 'mat3x2' 'mat3x3' words + 'mat3x4' 'mat4' 'mat4x2' 'mat4x3' 'mat4x4' 'mediump' 'noperspective' 'out' words + 'patch' 'precision' 'return' 'sample' 'sampler1D' 'sampler1DArray' 'sampler1DArrayShadow' words + 'sampler1DShadow' 'sampler2D' 'sampler2DArray' 'sampler2DArrayShadow' 'sampler2DMS' words + 'sampler2DMSArray' 'sampler2DRect' 'sampler2DRectShadow' 'sampler2DShadow' 'sampler3D' words + 'samplerBuffer' 'samplerCube' 'samplerCubeArray' 'samplerCubeArrayShadow' words + 'samplerCubeShadow' 'smooth' 'struct' 'subroutine' 'switch' 'uint' 'uniform' words + 'usampler1D' 'usampler1DArray' 'usampler2D' 'usampler2DArray' 'usampler2DMS' words + 'usampler2DMSarray' 'usampler2DRect' 'usampler3D' 'usamplerBuffer' 'usamplerCube' words + 'usamplerCubeArray' 'uvec2' 'uvec3' 'uvec4' 'varying' 'vec2' 'vec3' words + 'vec4' 'void' 'while' 'true' 'false' words + +scope escapechar string + endtokens +# return on any char + +scope string string + calltokens + '\' escapechar + endtokens + '"' + +scope string1 string + calltokens + '\' escapechar + endtokens + '''' + +scope comment1 comment + endtokens + '*/' + +scope comment2 comment + endtokens + '' + +scope macros macros + + jumptokens + '/*' comment1 + '//' comment2 + + endtokens + '' + +scope block + keywords + glsl + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + '{' block default + + endtokens + '}' default + +scope main + + keywords words + glsl + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + '{' block default + diff --git a/mseide-msegui/apps/ide/syntaxdefs/grammar.sdef b/mseide-msegui/apps/ide/syntaxdefs/grammar.sdef new file mode 100644 index 0000000..1bde6cd --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/grammar.sdef @@ -0,0 +1,54 @@ +caseinsensitive +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + number '' cl_dkred + +keyworddefs grammar + +scope comment2 comment + endtokens + '' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' + 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word + return + +scope op number + return + +scope main + + keywords words + grammar + + calltokens + '//' comment2 + '''' string + '#' number string + '"' op + '{' op + '}' op + '@' op + '$' op diff --git a/mseide-msegui/apps/ide/syntaxdefs/ipf.sdef b/mseide-msegui/apps/ide/syntaxdefs/ipf.sdef new file mode 100644 index 0000000..fcd479b --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/ipf.sdef @@ -0,0 +1,96 @@ +# MSEide syntaxdefinition for IPF format + +STYLES + default '' + words 'b' + comment 'i' cl_dkcyan + tag 'b' cl_dkblue + string '' cl_dkblue + macro '' cl_dkmagenta + +ADDKEYWORDCHARS + '.' + +KEYWORDDEFS control + '.br' '.ce' '.nameit' + +SCOPE tag tag + ENDTOKENS + '.' + +SCOPE comment1 comment + endtokens + '' + +SCOPE macro macro + endtokens + '.' + +SCOPE main + + KEYWORDS tag + control + + CALLTOKENS + ':a' tag +# ':acviewport' tag +# ':artlink' tag +# ':artwork' tag + ':c' tag +# ':caution' tag +# ':cgraphic' tag +# ':color' tag +# ':ctrl' tag +# ':ctrldef' tag + ':d' tag +# ':ddf' tag +# ':dl' tag +# ':docprof' tag + ':e' tag + ':f' tag +# ':fig' tag +# ':figcap' tag +# ':font' tag +# ':fn' tag + ':h' tag +# ':h' tag +# ':hdref' tag +# ':hide' tag +# ':hp' tag + ':i' tag +# ':i' tag +# ':icmd' tag +# ':isyn' tag + ':l' tag +# ':li' tag +# ':lines' tag +# ':link' tag +# ':lm' tag +# ':lp' tag + ':n' tag +# ':note' tag +# ':nt' tag + ':o' tag +# ':ol' tag + ':p' tag +# ':p' tag +# ':parml' tag +# ':pbutton' tag +# ':pd' tag +# ':pt' tag +# ':rm' tag + ':s' tag +# ':sl' tag + ':t' tag +# ':table' tag +# ':title' tag + ':u' tag +# ':ul' tag +# ':userdoc' tag + ':w' tag +# ':warning' tag + ':x' tag +# ':xmp' tag + + '.*' comment1 + '&' macro diff --git a/mseide-msegui/apps/ide/syntaxdefs/ipf2.sdef b/mseide-msegui/apps/ide/syntaxdefs/ipf2.sdef new file mode 100644 index 0000000..3c1ccfc --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/ipf2.sdef @@ -0,0 +1,131 @@ +# MSEide syntaxdefinition for IPF format + +# Define the textstyles +STYLES + default '' + words 'b' + comment 'i' cl_dkcyan + tag 'b' cl_dkblue + tagparams '' cl_dkblue +# RGB value + string '' $600000 + macro '' cl_dkmagenta + +# Add '.' to the allowed characters in keywords. +# Default is ['A'..'Z','a'..'z','0'..'9','_'] +ADDKEYWORDCHARS + '.' + +# Define control keywords +KEYWORDDEFS control + '.br' '.ce' '.nameit' + +# Scopes must be defined before they can be referenced + +# Define scope string with text style string +scope string string + endtokens + '''' '' + +# Define the scope paramend with no text style +SCOPE paramend + RETURN +# No endtokens, scope terminates imediately + +# Define the scope tagparams with the text style tagparams +SCOPE tagparams tagparams + CALLTOKENS + '''' string + JUMPTOKENS +# Jump to scope paramend with text style tag + '.' paramend tag + +# Define the scope tag with text style tag +SCOPE tag tag + ENDTOKENS + '.' + JUMPTOKENS +# Space -> tagprams scope + ' ' tagparams +# End of line -> tagprams scope + '' tagparams + +SCOPE comment1 comment + endtokens + '' + +SCOPE macro macro + endtokens + '.' + +# Coloring starts with the last scope, the name is irrelevant +SCOPE main + +# Keywords used in ths scope with text style tag + KEYWORDS tag + control + + CALLTOKENS + ':a' tag +# ':acviewport' tag +# ':artlink' tag +# ':artwork' tag + ':c' tag +# ':caution' tag +# ':cgraphic' tag +# ':color' tag +# ':ctrl' tag +# ':ctrldef' tag + ':d' tag +# ':ddf' tag +# ':dl' tag +# ':docprof' tag + ':e' tag + ':f' tag +# ':fig' tag +# ':figcap' tag +# ':font' tag +# ':fn' tag + ':h' tag +# ':h' tag +# ':hdref' tag +# ':hide' tag +# ':hp' tag + ':i' tag +# ':i' tag +# ':icmd' tag +# ':isyn' tag + ':l' tag +# ':li' tag +# ':lines' tag +# ':link' tag +# ':lm' tag +# ':lp' tag + ':n' tag +# ':note' tag +# ':nt' tag + ':o' tag +# ':ol' tag + ':p' tag +# ':p' tag +# ':parml' tag +# ':pbutton' tag +# ':pd' tag +# ':pt' tag +# ':rm' tag + ':s' tag +# ':sl' tag + ':t' tag +# ':table' tag +# ':title' tag + ':u' tag +# ':ul' tag +# ':userdoc' tag + ':w' tag +# ':warning' tag + ':x' tag +# ':xmp' tag + + '.*' comment1 + '&' macro + diff --git a/mseide-msegui/apps/ide/syntaxdefs/java.sdef b/mseide-msegui/apps/ide/syntaxdefs/java.sdef new file mode 100644 index 0000000..0d585aa --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/java.sdef @@ -0,0 +1,85 @@ +styles + default '' + words 'b' + type 'b' + comment 'i' cl_dkblue + macros 'b' cl_dkred + string '' cl_dkblue + +keyworddefs java + 'abstract' 'assert' 'byte' 'break' 'case' 'catch' 'char' 'const' + 'continue' 'default' 'delete' 'do' 'double' 'else' + 'enum' 'extends' 'instanceof' 'fastcall' 'finally' + 'for' 'false' 'goto' 'if' 'import' 'inline' 'interface' + 'implements' 'interrupt' 'long' 'near' 'new' 'null' 'protected' + 'strictfp' 'return' 'synchronized' 'this' 'throw' 'throws' 'try' 'transient' 'volatile' 'while' + +keyworddefs javaplus + 'void' 'public' 'package' 'private' 'final' 'class' 'static' 'boolean' 'int' 'native' 'float' + +scope escapechar string + endtokens +# return on any char + +scope string string + calltokens + '\' escapechar + endtokens + '"' + +scope string1 string + calltokens + '\' escapechar + endtokens + '''' + +scope comment1 comment + endtokens + '*/' + +scope comment2 comment + endtokens + '' + +scope method1 type + return + +scope macros macros + + jumptokens + '/*' comment1 + '//' comment2 + + endtokens + '' +scope block + keywords + java + javaplus type + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + '{' block default + + endtokens + '}' default + +scope main + + keywords words + java + + javaplus type + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + + diff --git a/mseide-msegui/apps/ide/syntaxdefs/llvm.sdef b/mseide-msegui/apps/ide/syntaxdefs/llvm.sdef new file mode 100644 index 0000000..8e2a47e --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/llvm.sdef @@ -0,0 +1,45 @@ +caseinsensitive +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + +keyworddefs llvm + 'RET' 'BR' 'SWITCH' 'INDIRECTBR' 'INVOKE' 'RESUME' 'UNREACHABLE' + 'ADD' 'FADD' 'SUB' 'FSUB' 'MUL' 'FMUL' 'UDIV' 'SDIV' + 'FDIF' 'UREM' 'SREM' 'FREM' 'SHL' 'LSHR' 'ASHR' 'AND' 'OR' 'XOR' + 'EXTRACTELEMENT' 'INSERTELEMENT' 'SHUFFLEVECTOR' + 'EXTRACTVALUE' 'INSERTVALUE' + 'ALLOCA' 'LOAD' 'STORE' 'FENCE' 'CMPXCHG' 'ATOMICRMW' 'GETELEMENTPTR' + 'TRUNC' 'TO' 'ZEXZ' 'SEXT' 'FPTRUNC' 'FPEXT' 'FPTOUI' 'FPTOSI' + 'UITOFP' 'SITOFP' 'PTRTOINT' 'INTTOPTR' 'BITCAST' 'ADDRSPACECAST' + 'ICMP' 'FCMP' 'PHI' 'SELECT' 'CALL' 'VA_ARG' 'LANDINGPAD' + 'LLVM' 'VA_START' 'VA_END' 'VA_COPY' 'GCROOT' 'GCREAD' 'GCWRITE' + 'RETURNADDRESS' 'FRAMEADDRESS' 'READ_REGISTER' 'WRITE_REGISTER' + 'STACKSAVE' 'STACKRESTORE' 'PREFETCH' 'PCMARKER' 'READCYCLECOUNTER' + 'CLEAR_CACHE' 'INSTRPROF_INCREMENT' + 'MEMCPY' 'MEMMOVE' 'MEMSET' 'SQRT' 'POWI' 'SIN' 'COS' 'POW' 'EXP' 'EXP2' + 'LOG' 'LOG10' 'LOG2' 'FMA' 'FABS' 'MINNUM' 'MAXNUM' 'COPYSIGN' 'FLOOR' 'CEIL' + 'TRUNC' 'RINT' 'NEARBYINT' 'ROUND' + 'BSWAP' 'CTPOP' 'CTLZ' 'CTTZ' + 'WITH' 'OVERFLOW' 'SADD' 'UADD' 'SSUB' 'USUB' 'SMUL' 'UMUL' + 'FMULADD' + 'CONVERT' 'FROM' 'FP16' + 'INIT' 'TRAMPOLINE' 'ADJUST' + 'LIFETIME' 'START' 'END' 'INVARIANT' + 'VAR' 'ANNOTATION' 'PTR' 'TRAP' 'DEBUGTRAP' 'STACKPROTECTOR' + 'STACKPROTECTORCHECK' 'OBJECTSIZE' 'EXPECT' 'ASSUME' 'DONOTHING' + +scope comment1 comment + endtokens + '' + +scope main + + keywords words + llvm + calltokens + ';' comment1 + diff --git a/mseide-msegui/apps/ide/syntaxdefs/mselang.sdef b/mseide-msegui/apps/ide/syntaxdefs/mselang.sdef new file mode 100644 index 0000000..f4356c0 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/mselang.sdef @@ -0,0 +1,107 @@ +caseinsensitive +colors cl_default cl_default cl_default cl_default +pairwords + 'BEGIN' 'CASE' 'TRY' 'RECORD' 'CLASS' 'OBJECT' 'INTERFACE' 'END' + 'REPEAT' 'UNTIL' + +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + number '' cl_dkred + +keyworddefs pascal + 'ABSOLUTE' 'ABSTRACT' 'AND' 'ARRAY' 'AS' 'ASM' 'ASSEMBLER' 'BEGIN' + 'BREAK' 'CASE' 'CDECL' 'CLASS' 'CONST' 'CONSTREF' 'CONSTRUCTOR' + 'CONTINUE' 'DEFAULT' 'DEPRECATED' 'DESTRUCTOR' 'DISPOSE' 'DIV' 'DO' 'DOWNTO' + 'ELSE' 'END' 'EXCEPT' 'EXIT' 'EXPORT' 'EXPORTS' 'EXTERNAL' 'FAIL' + 'FALSE' 'FAR' 'FILE' 'FINALIZATION' 'FINALLY' 'FOR' 'FORWARD' 'FUNCTION' 'GOTO' + 'IF' 'IMPLEMENTATION' 'IMPLEMENTS' 'IN' 'INHERITED' + 'INITIALIZATION' 'INLINE' 'INTERFACE' 'INTERRUPT' 'IS' 'LABEL' 'LIBRARY' + 'METHOD' 'MOD' 'NEW' 'NIL' 'NODEFAULT' 'NOT' 'OBJECT' + 'OF' 'ON' 'OPERATOR' 'OR' 'OUT' 'OTHERWISE' 'OVERLOAD' 'OVERRIDE' + 'PACKED' 'POPSTACK' 'PRIVATE' + 'PROCEDURE' 'PROGRAM' 'PROTECTED' + 'PUBLIC' 'PUBLISHED' 'RAISE' 'RECORD' 'REINTRODUCE' 'REPEAT' + 'RESOURCESTRING' + 'SELF' 'SET' 'SHL' 'SHR' + 'STDCALL' 'THEN' 'THREADVAR' 'TO' 'TRUE' 'TRY' 'TYPE' 'UNIT' 'UNTIL' + 'USES' 'VAR' 'VIRTUAL' 'WHILE' 'WITH' 'XOR' + +keyworddefs property + 'DEFAULT' 'INDEX' 'READ' 'STORED' 'WRITE' + +scope option option + endtokens + '}' + +scope comment1 comment + endtokens + '}' + +scope comment2 comment + endtokens + '' + +scope comment3 comment + endtokens + '*)' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' + 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word + return + +scope property1 default + keywords words + property + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + endtokens + ';' + +scope property words + jumptokens + property1 + + +scope main + + keywords words + pascal + + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + .'property'. property + +# '$' hexnumber number +# '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number +# 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' +# 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word diff --git a/mseide-msegui/apps/ide/syntaxdefs/objecttext.sdef b/mseide-msegui/apps/ide/syntaxdefs/objecttext.sdef new file mode 100644 index 0000000..bf34ba6 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/objecttext.sdef @@ -0,0 +1,35 @@ +caseinsensitive +addkeywordchars + '()<>=' +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + +keyworddefs objecttext + 'END' 'END>' 'INHERITED' 'INLINE' 'ITEM' 'OBJECT' +keyworddefs operators + '(' ')' '<' '>' '=' + +scope string string + endtokens + '''' '' + +scope string1 string + calltokens + '''' string + endtokens + ' ' '' + +scope main + + keywords words + objecttext + operators + + calltokens + '''' string + '#' string1 + diff --git a/mseide-msegui/apps/ide/syntaxdefs/pascal.sdef b/mseide-msegui/apps/ide/syntaxdefs/pascal.sdef new file mode 100644 index 0000000..9b43d8f --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/pascal.sdef @@ -0,0 +1,107 @@ +caseinsensitive +colors cl_default cl_default cl_default cl_default +pairwords + 'BEGIN' 'CASE' 'TRY' 'RECORD' 'CLASS' 'OBJECT' 'INTERFACE' 'END' + 'REPEAT' 'UNTIL' + +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + number '' cl_dkred + +keyworddefs pascal + 'ABSOLUTE' 'ABSTRACT' 'AND' 'ARRAY' 'AS' 'ASM' 'ASSEMBLER' 'BEGIN' + 'BREAK' 'CASE' 'CDECL' 'CLASS' 'CONST' 'CONSTREF' 'CONSTRUCTOR' + 'CONTINUE' 'DEFAULT' 'DEPRECATED' 'DESTRUCTOR' 'DISPOSE' 'DIV' 'DO' 'DOWNTO' + 'ELSE' 'END' 'EXCEPT' 'EXIT' 'EXPORT' 'EXPORTS' 'EXTERNAL' 'FAIL' + 'FALSE' 'FAR' 'FILE' 'FINALIZATION' 'FINALLY' 'FOR' 'FORWARD' 'FUNCTION' 'GOTO' + 'IF' 'IMPLEMENTATION' 'IMPLEMENTS' 'IN' 'INHERITED' + 'INITIALIZATION' 'INLINE' 'INTERFACE' 'INTERRUPT' 'IS' 'LABEL' 'LIBRARY' + 'MOD' 'NEW' 'NIL' 'NODEFAULT' 'NOT' 'OBJECT' + 'OF' 'ON' 'OPERATOR' 'OR' 'OUT' 'OTHERWISE' 'OVERLOAD' 'OVERRIDE' + 'PACKED' 'POPSTACK' 'PRIVATE' + 'PROCEDURE' 'PROGRAM' 'PROTECTED' + 'PUBLIC' 'PUBLISHED' 'RAISE' 'RECORD' 'REINTRODUCE' 'REPEAT' + 'RESOURCESTRING' + 'SELF' 'SET' 'SHL' 'SHR' + 'STDCALL' 'THEN' 'THREADVAR' 'TO' 'TRUE' 'TRY' 'TYPE' 'UNIT' 'UNTIL' + 'USES' 'VAR' 'VIRTUAL' 'WHILE' 'WITH' 'XOR' + +keyworddefs property + 'DEFAULT' 'INDEX' 'READ' 'STORED' 'WRITE' + +scope option option + endtokens + '}' + +scope comment1 comment + endtokens + '}' + +scope comment2 comment + endtokens + '' + +scope comment3 comment + endtokens + '*)' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' + 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word + return + +scope property1 default + keywords words + property + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + endtokens + ';' + +scope property words + jumptokens + property1 + + +scope main + + keywords words + pascal + + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + .'property'. property + +# '$' hexnumber number +# '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number +# 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' +# 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word diff --git a/mseide-msegui/apps/ide/syntaxdefs/pascal2.sdef b/mseide-msegui/apps/ide/syntaxdefs/pascal2.sdef new file mode 100644 index 0000000..7047fb6 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/pascal2.sdef @@ -0,0 +1,109 @@ +caseinsensitive +colors cl_default cl_default cl_default cl_default +pairwords + 'BEGIN' 'CASE' 'TRY' 'RECORD' 'CLASS' 'OBJECT' 'INTERFACE' 'END' + 'REPEAT' 'UNTIL' + +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + number '' cl_dkred + +keyworddefs pascal + 'ABSOLUTE' 'ABSTRACT' 'AND' 'ARRAY' 'AS' 'ASM' 'ASSEMBLER' 'BEGIN' + 'BREAK' 'CASE' 'CDECL' 'CLASS' 'CONST' 'CONSTREF' 'CONSTRUCTOR' + 'CONTINUE' 'DEFAULT' 'DEPRECATED' 'DESTRUCTOR' 'DISPOSE' 'DIV' 'DO' 'DOWNTO' + 'ELSE' 'END' 'EXCEPT' 'EXIT' 'EXPORT' 'EXPORTS' 'EXTERNAL' 'FAIL' + 'FALSE' 'FAR' 'FILE' 'FINALIZATION' 'FINALLY' 'FOR' 'FORWARD' 'FUNCTION' 'GOTO' + 'IF' 'IMPLEMENTATION' 'IMPLEMENTS' 'IN' 'INDEX' 'INHERITED' + 'INITIALIZATION' 'INLINE' 'INTERFACE' 'INTERRUPT' 'IS' 'LABEL' 'LIBRARY' + 'MOD' 'NEW' 'NIL' 'NODEFAULT' 'NOT' 'OBJECT' + 'OF' 'ON' 'OPERATOR' 'OR' 'OUT' 'OTHERWISE' 'OVERLOAD' 'OVERRIDE' + 'PACKED' 'POPSTACK' 'PRIVATE' + 'PROCEDURE' 'PROGRAM' 'PROTECTED' + 'PUBLIC' 'PUBLISHED' 'RAISE' 'RECORD' 'REINTRODUCE' 'REPEAT' + 'RESOURCESTRING' + 'SELF' 'SET' 'SHL' 'SHR' + 'STDCALL' 'THEN' 'THREADVAR' 'TO' 'TRUE' 'TRY' 'TYPE' 'UNIT' 'UNTIL' + 'USES' 'VAR' 'VIRTUAL' 'WHILE' 'WITH' 'XOR' + +keyworddefs property + 'DEFAULT' 'READ' 'STORED' 'WRITE' + +scope option option + endtokens + '}' + +scope comment1 comment + calltokens + '{' comment1 + endtokens + '}' + +scope comment2 comment + endtokens + '' + +scope comment3 comment + endtokens + '*)' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' + 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word + return + +scope property1 default + keywords words + property + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + endtokens + ';' + +scope property words + jumptokens + property1 + + +scope main + + keywords words + pascal + + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + .'property'. property + +# '$' hexnumber number +# '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number +# 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' +# 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word diff --git a/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized.sdef b/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized.sdef new file mode 100644 index 0000000..82c4f0f --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized.sdef @@ -0,0 +1,170 @@ +#for nested {} comments +caseinsensitive +pairwords + 'BEGIN' 'CASE' 'TRY' 'RECORD' 'CLASS' 'OBJECT' 'INTERFACE' 'END' + 'REPEAT' 'UNTIL' + +# COLORS font/paper +COLORS $586e75 $fdf6e3 + +# base03 $002b36 +# base01 $586e75 +# base0 $839496 +# base1 $93a1a1 +# base2 $eee8d5 +# base3 $fdf6e3 +# red $dc322f +# green $859900 +# cyan $2aa198 +# blue $268bd2 + + +styles + default '' + words 'b' $859900 + comment 'i' $93a1a1 + option '' $268bd2 + string '' $2aa198 + symbol '' $dc322f + number '' $2aa198 + +keyworddefs pascal + 'ABSOLUTE' 'ABSTRACT' 'AND' 'ARRAY' 'AS' 'ASM' 'ASSEMBLER' 'BEGIN' + 'BREAK' 'CASE' 'CDECL' 'CLASS' 'CONST' 'CONSTREF' 'CONSTRUCTOR' + 'CONTINUE' 'DEFAULT' 'DEPRECATED' 'DESTRUCTOR' 'DISPOSE' 'DIV' 'DO' 'DOWNTO' + 'ELSE' 'END' 'EXCEPT' 'EXIT' 'EXPORT' 'EXPORTS' 'EXTERNAL' 'FAIL' + 'FALSE' 'FAR' 'FILE' 'FINALIZATION' 'FINALLY' 'FOR' 'FORWARD' 'FUNCTION' 'GOTO' + 'IF' 'IMPLEMENTATION' 'IMPLEMENTS' 'IN' 'INHERITED' + 'INITIALIZATION' 'INLINE' 'INTERFACE' 'INTERRUPT' 'IS' 'LABEL' 'LIBRARY' + 'MOD' 'NEW' 'NIL' 'NODEFAULT' 'NOT' 'OBJECT' + 'OF' 'ON' 'OPERATOR' 'OR' 'OUT' 'OTHERWISE' 'OVERLOAD' 'OVERRIDE' + 'PACKED' 'POPSTACK' 'PRIVATE' + 'PROCEDURE' 'PROGRAM' 'PROTECTED' + 'PUBLIC' 'PUBLISHED' 'RAISE' 'RECORD' 'REINTRODUCE' 'REPEAT' + 'RESOURCESTRING' + 'SELF' 'SET' 'SHL' 'SHR' + 'STDCALL' 'THEN' 'THREADVAR' 'TO' 'TRUE' 'TRY' 'TYPE' 'UNIT' 'UNTIL' + 'USES' 'VAR' 'VIRTUAL' 'WHILE' 'WITH' 'XOR' + +keyworddefs property + 'DEFAULT' 'INDEX' 'READ' 'STORED' 'WRITE' + +scope option option + endtokens + '}' + +scope comment1 comment + calltokens + '{' comment1 + endtokens + '}' + +scope comment2 comment + endtokens + '' + +scope comment3 comment + endtokens + '*)' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope symbol1 symbol + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' + 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word + return + +scope property2 symbol + return + +scope property1 default + keywords words + property + jumptokens + ';' property2 + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + ':' symbol1 + '.' symbol1 + ',' symbol1 + '=' symbol1 + '<>' symbol1 + '<' symbol1 + '>' symbol1 + '(' symbol1 + ')' symbol1 + '+' symbol1 + '-' symbol1 + '/' symbol1 + '*' symbol1 + '[' symbol1 + ']' symbol1 + + '$' hexnumber number + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number + 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' + 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word + +scope property words + jumptokens + property1 + + +scope main + + keywords words + pascal + + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + ':' symbol1 + '.' symbol1 + ';' symbol1 + ',' symbol1 + '=' symbol1 + '<>' symbol1 + '<' symbol1 + '>' symbol1 + '(' symbol1 + ')' symbol1 + '+' symbol1 + '-' symbol1 + '/' symbol1 + '*' symbol1 + '[' symbol1 + ']' symbol1 + .'property'. property + + '$' hexnumber number + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number + 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' + 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word + \ No newline at end of file diff --git a/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized_dark.sdef b/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized_dark.sdef new file mode 100644 index 0000000..4da6ad2 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized_dark.sdef @@ -0,0 +1,168 @@ +#for nested {} comments +caseinsensitive +pairwords + 'BEGIN' 'CASE' 'TRY' 'RECORD' 'CLASS' 'OBJECT' 'INTERFACE' 'END' + 'REPEAT' 'UNTIL' + +# COLORS font/paper +COLORS $93a1a1 $002b36 + +# base03 $002b36 +# base01 $586e75 +# base0 $839496 +# base1 $93a1a1 +# base2 $eee8d5 +# base3 $fdf6e3 +# red $dc322f +# green $859900 +# cyan $2aa198 +# blue $268bd2 + + +styles + default '' + words 'b' $859900 + comment 'i' $586e75 + option '' $268bd2 + string '' $2aa198 + symbol '' $dc322f + number '' $2aa198 + +keyworddefs pascal + 'ABSOLUTE' 'ABSTRACT' 'AND' 'ARRAY' 'AS' 'ASM' 'ASSEMBLER' 'BEGIN' + 'BREAK' 'CASE' 'CDECL' 'CLASS' 'CONST' 'CONSTREF' 'CONSTRUCTOR' + 'CONTINUE' 'DEFAULT' 'DEPRECATED' 'DESTRUCTOR' 'DISPOSE' 'DIV' 'DO' 'DOWNTO' + 'ELSE' 'END' 'EXCEPT' 'EXIT' 'EXPORT' 'EXPORTS' 'EXTERNAL' 'FAIL' + 'FALSE' 'FAR' 'FILE' 'FINALIZATION' 'FINALLY' 'FOR' 'FORWARD' 'FUNCTION' 'GOTO' + 'IF' 'IMPLEMENTATION' 'IMPLEMENTS' 'IN' 'INHERITED' + 'INITIALIZATION' 'INLINE' 'INTERFACE' 'INTERRUPT' 'IS' 'LABEL' 'LIBRARY' + 'MOD' 'NEW' 'NIL' 'NODEFAULT' 'NOT' 'OBJECT' + 'OF' 'ON' 'OPERATOR' 'OR' 'OUT' 'OTHERWISE' 'OVERLOAD' 'OVERRIDE' + 'PACKED' 'POPSTACK' 'PRIVATE' + 'PROCEDURE' 'PROGRAM' 'PROTECTED' + 'PUBLIC' 'PUBLISHED' 'RAISE' 'RECORD' 'REINTRODUCE' 'REPEAT' + 'RESOURCESTRING' + 'SELF' 'SET' 'SHL' 'SHR' + 'STDCALL' 'THEN' 'THREADVAR' 'TO' 'TRUE' 'TRY' 'TYPE' 'UNIT' 'UNTIL' + 'USES' 'VAR' 'VIRTUAL' 'WHILE' 'WITH' 'XOR' + +keyworddefs property + 'DEFAULT' 'INDEX' 'READ' 'STORED' 'WRITE' + +scope option option + endtokens + '}' + +scope comment1 comment + calltokens + '{' comment1 + endtokens + '}' + +scope comment2 comment + endtokens + '' + +scope comment3 comment + endtokens + '*)' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope symbol1 symbol + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' + 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word + return + +scope property2 symbol + return +scope property1 default + keywords words + pascal + jumptokens + ';' property2 + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + ':' symbol1 + '.' symbol1 + ',' symbol1 + '=' symbol1 + '<>' symbol1 + '<' symbol1 + '>' symbol1 + '(' symbol1 + ')' symbol1 + '+' symbol1 + '-' symbol1 + '/' symbol1 + '*' symbol1 + '[' symbol1 + ']' symbol1 + + '$' hexnumber number + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number + 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' + 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word + +scope property words + jumptokens + property1 + + +scope main + + keywords words + pascal + + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + ':' symbol1 + '.' symbol1 + ';' symbol1 + ',' symbol1 + '=' symbol1 + '<>' symbol1 + '<' symbol1 + '>' symbol1 + '(' symbol1 + ')' symbol1 + '+' symbol1 + '-' symbol1 + '/' symbol1 + '*' symbol1 + '[' symbol1 + ']' symbol1 + .'property'. property + + '$' hexnumber number + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number + 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' + 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '_' word diff --git a/mseide-msegui/apps/ide/syntaxdefs/python.sdef b/mseide-msegui/apps/ide/syntaxdefs/python.sdef new file mode 100644 index 0000000..9fe6e02 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/python.sdef @@ -0,0 +1,45 @@ +# Python syntax definition +# +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + +keyworddefs python + 'False' 'class' 'finally' 'is' 'return' + 'None' 'continue' 'for' 'lambda' 'try' + 'True' 'def' 'from' 'nonlocal' 'while' + 'and' 'del' 'global' 'not' 'with' + 'as' 'elif' 'if' 'or' 'yield' + 'assert' 'else' 'import' 'pass' + 'break' 'except' 'in' 'raise' + +scope comment1 comment + endtokens + '' +scope string1 string + endtokens + '''' '' +scope string2 string + endtokens + '"' '' +scope string3 string + endtokens + '''''''' +scope string4 string + endtokens + '"""' + +scope main + + keywords words + python + calltokens + '#' comment1 + '''''''' string3 + '''' string1 + '"""' string4 + '"' string2 + diff --git a/mseide-msegui/apps/ide/syntaxdefs/sql.sdef b/mseide-msegui/apps/ide/syntaxdefs/sql.sdef new file mode 100644 index 0000000..a953f53 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/sql.sdef @@ -0,0 +1,82 @@ +caseinsensitive +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + +keyworddefs sql + 'ACTION' 'ACTIVE' 'ADD' 'ADMIN' 'AFTER' 'ALL' 'ALTER' 'AND' 'ANY' 'AS' 'ASC' + 'ASCENDING' 'AT' 'AUTO' 'AUTODDL' + 'AVG' 'BASED' 'BASENAME' 'BASE_NAME' 'BEFORE' 'BEGIN' 'BETWEEN' 'BLOB' + 'BLOBEDIT' 'BUFFER' 'BY' 'CACHE' + 'CASCADE' 'CASE' 'CAST' 'CHAR' 'CHARACTER' 'CHARACTER_LENGTH' 'CHAR_LENGTH' 'CHECK' + 'CHECK_POINT_LEN' + 'CHECK_POINT_LENGTH' 'COLLATE' 'COLLATION' 'COLUMN' 'COMMIT' 'COMMITTED' + 'COMPILETIME' + 'COMPUTED' 'CLOSE' 'CONDITIONAL' 'CONNECT' 'CONSTRAINT' 'CONTAINING' 'CONTINUE' + 'COUNT' 'CREATE' + 'CSTRING' 'CURRENT' 'CURRENT_DATE' 'CURRENT_TIME' 'CURRENT_TIMESTAMP' 'CURSOR' + 'DATABASE' 'DATE' 'DAY' 'DB_KEY' 'DEBUG' 'DEC' 'DECIMAL' 'DECLARE' 'DEFAULT' + 'DELETE' 'DESC' 'DESCENDING' + 'DESCRIBE' 'DESCRIPTOR' 'DISCONNECT' 'DISPLAY' 'DISTINCT' 'DO' 'DOMAIN' + 'DOUBLE' 'DROP' + 'ECHO' 'EDIT' 'ELSE' 'END' 'ENTRY_POINT' 'ESCAPE' 'EVENT' 'EXCEPTION' 'EXECUTE' + 'EXISTS' 'EXIT' 'EXTERN' 'EXTERNAL' 'EXTRACT' 'FETCH' 'FILE' 'FILTER' 'FLOAT' + 'FOR' 'FOREIGN' 'FOUND' + 'FREE_IT' 'FROM' 'FULL' 'FUNCTION' 'GDSCODE' 'GENERATOR' 'GEN_ID' 'GLOBAL' + 'GOTO' + 'GRANT' 'GROUP' 'GROUP_COMMIT_WAIT' 'GROUP_COMMIT_' 'WAIT_TIME' 'HAVING' 'HELP' + 'HOUR' 'IF' + 'IMMEDIATE' 'IN' 'INACTIVE' 'INDEX' 'INDICATOR' 'INIT' 'INNER' 'INPUT' + 'INPUT_TYPE' + 'INSERT' 'INT' 'INTEGER' 'INTO' 'IS' 'ISOLATION' 'ISQL' 'JOIN' 'KEY' + 'LC_MESSAGES' 'LC_TYPE' 'LEFT' + 'LENGTH' 'LEV' 'LEVEL' 'LIKE' 'LIMIT' + 'LOGFILE' 'LOG_BUFFER_SIZE' 'LOG_BUF_SIZE' + 'LONG' 'MANUAL' + 'MAX' 'MAXIMUM' 'MAXIMUM_SEGMENT' 'MAX_SEGMENT' 'MERGE' 'MESSAGE' 'MIN' + 'MINIMUM' 'MINUTE' + 'MODULE_NAME' 'MONTH' 'NAMES' 'NATIONAL' 'NATURAL' 'NCHAR' 'NO' 'NOAUTO' + 'NOT' + 'NULL' 'NUMERIC' 'NUM_LOG_BUFS' 'NUM_LOG_BUFFERS' 'OCTET_LENGTH' 'OF' 'ON' + 'ONLY' 'OPEN' + 'OPTION' 'OR' 'ORDER' 'OUTER' 'OUTPUT' 'OUTPUT_TYPE' 'OVERFLOW' 'PAGE' + 'PAGELENGTH' + 'PAGES' 'PAGE_SIZE' 'PARAMETER' 'PASSWORD' 'PLAN' 'POSITION' 'POST_EVENT' + 'PRECISION' 'PREPARE' + 'PROCEDURE' 'PROTECTED' 'PRIMARY' 'PRIVILEGES' 'PUBLIC' 'QUIT' + 'RAW_PARTITIONS' 'RDB$DB_KEY' 'READ' 'REAL' 'RECORD_VERSION' 'REFERENCES' + 'RELEASE' 'RESERV' 'RESERVING' 'RESTRICT' 'RETAIN' 'RETURN' + 'RETURNING_VALUES' 'RETURNS' 'REVOKE' 'RIGHT' 'ROLE' 'ROLLBACK' 'RUNTIME' + 'SCHEMA' 'SECOND' + 'SEGMENT' 'SELECT' 'SET' 'SHADOW' 'SHARED' 'SHELL' 'SHOW' 'SINGULAR' 'SIZE' + 'SMALLINT' 'SNAPSHOT' 'SOME' 'SORT' 'SQLCODE' 'SQLERROR' 'SQLWARNING' + 'STABILITY' 'STARTING' + 'STARTS' 'STATEMENT' 'STATIC' 'STATISTICS' 'SUB_TYPE' 'SUM' 'SUSPEND' + 'TABLE' 'TERMINATOR' + 'THEN' 'TIME' 'TIMESTAMP' 'TO' 'TRANSACTION' 'TRANSLATE' 'TRANSLATION' + 'TRIGGER' 'TRIM' + 'TYPE' 'UNCOMMITTED' 'UNION' 'UNIQUE' 'UPDATE' 'UPPER' 'USER' 'USING' + 'VALUE + 'VALUES' 'VARCHAR' 'VARIABLE' 'VARYING' 'VERSION' 'VIEW' 'WAIT' 'WEEKDAY' + 'WHEN' + 'WHENEVER' 'WHERE' 'WHILE' 'WITH' 'WORK' 'WRITE' 'YEAR' 'YEARDAY' + +scope comment1 comment + endtokens + '*/' + +scope string string + endtokens + '''' '' + +scope main + + keywords words + sql + calltokens + '/*' comment1 + '''' string + diff --git a/mseide-msegui/apps/ide/targetconsole.mfm b/mseide-msegui/apps/ide/targetconsole.mfm new file mode 100644 index 0000000..229144a --- /dev/null +++ b/mseide-msegui/apps/ide/targetconsole.mfm @@ -0,0 +1,113 @@ +object targetconsolefo: ttargetconsolefo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + popupmenu = popupmen + visible = False + bounds_x = 209 + bounds_y = 385 + bounds_cx = 368 + bounds_cy = 137 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 358 + 137 + ) + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Target Console' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000074020000000000000000000000000000 + 00000000000000000000000000000000000000007C7C7C17FFFFFF017C7C7C01 + E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF01 + 7C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E816 + FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E80CDEDEDE0156565601 + B0B0B001E8E8E807FFFFFF017C7C7C01E8E8E80CE2E2E2012D2D2D0100000001 + 222222017B7B7B01D1D1D101E8E8E804FFFFFF017C7C7C01E8E8E804D6D6D601 + E4E4E401E8E8E805E4E4E401E8E8E802BEBEBE01676767011313130104040401 + 46464601A0A0A001E4E4E401E8E8E801FFFFFF017C7C7C01E8E8E80292929201 + 141414010000000105050501414141018C8C8C01D0D0D001BABABA014E4E4E01 + BBBBBB01E8E8E804E3E3E3019F9F9F014747470104040401161616019D9D9D01 + FFFFFF017C7C7C01E8E8E80227272701545454017D7D7D015151510114141401 + 0000000314141401CDCDCD01E8E8E805DDDDDD01909090012A2A2A0100000001 + 7C7C7C01FFFFFF017C7C7C01E8E8E802C0C0C001E8E8E803E4E4E401A6A6A601 + 8282820199999901DADADA01E8E8E803E7E7E701B0B0B001575757010A0A0A01 + 0B0B0B015C5C5C01B8B8B801E8E8E801FFFFFF017C7C7C01E8E8E80CE5E5E501 + 767676011F1F1F0100000001313131018D8D8D01DDDDDD01E8E8E803FFFFFF01 + 7C7C7C01E8E8E80CDCDCDC010F0F0F0162626201BEBEBE01E8E8E806FFFFFF01 + 7C7C7C01E8E8E80CE6E6E601E0E0E001E8E8E808FFFFFF017C7C7C01E8E8E816 + FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01 + E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF01 + 7C7C7C01FFFFFF17 + } + onidle = targetconsoleonidle + moduleclassname = 'tdockform' + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 358 + bounds_cy = 137 + anchors = [] + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + optionsgrid = [og_focuscellonenter, og_autofirstrow, og_colchangeontabkey, og_wrapcol, og_autopopup] + rowcountmax = 5000 + datacols.count = 1 + datacols.items = < + item[terminal] + width = 3000 + options = [co_fill, co_savestate, co_mousescrollrow] + widthmin = 3000 + widgetname = 'terminal' + dataclass = tgridrichstringdatalist + end> + datarowlinewidth = 0 + datarowheight = 14 + reffontheight = 14 + object terminal: tterminal + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 3000 + bounds_cy = 14 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + maxchars = 120 + onsendtext = sendtext + reffontheight = 14 + end + end + object popupmen: tpopupmenu + onupdate = popupupdateexe + menu.submenu.count = 5 + menu.submenu.items = < + item + action = actionsmo.find + end + item + action = actionsmo.repeatfind + end + item + action = actionsmo.findback + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Clear' + state = [as_localcaption, as_localonexecute] + onexecute = clearexe + end> + left = 32 + top = 32 + end +end diff --git a/mseide-msegui/apps/ide/targetconsole.pas b/mseide-msegui/apps/ide/targetconsole.pas new file mode 100644 index 0000000..83ec65d --- /dev/null +++ b/mseide-msegui/apps/ide/targetconsole.pas @@ -0,0 +1,153 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit targetconsole; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,mseterminal,msewidgetgrid,msestrings,msedatalist, + classes,mclasses,msemenus,msestat,msetypes; + +type + ttargetconsolefo = class(tdockform) + terminal: tterminal; + grid: twidgetgrid; + popupmen: tpopupmenu; + procedure sendtext(const sender: tobject; var atext: msestring; + var donotsend: Boolean); + procedure targetconsoleonidle(var again: Boolean); + procedure clearexe(const sender: TObject); + procedure popupupdateexe(const sender: tcustommenu); + private + fbuffer: tmsestringdatalist; + ffindpos: gridcoordty; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; + procedure addtext(const atext: string); + procedure dofind; + procedure repeatfind; + procedure findback; + end; + +var + targetconsolefo: ttargetconsolefo; + +procedure updatestat(const statfiler: tstatfiler); + +implementation +uses + targetconsole_mfm,msegdbutils,main,finddialogform,projectoptionsform, + actionsmodule,sourcepage; + +procedure updatestat(const statfiler: tstatfiler); +begin + updatefindvalues(statfiler,projectoptions.targetconsolefindinfo); +end; + +procedure ttargetconsolefo.sendtext(const sender: tobject; + var atext: msestring; var donotsend: Boolean); +begin + mainfo.gdb.targetwriteln(ansistring(atext)); + donotsend:= true; + terminal.inputcolindex:= length(terminal.text); + terminal.addline(''); +end; + +procedure ttargetconsolefo.clear; +begin + grid.clear; +end; + +procedure ttargetconsolefo.addtext(const atext: string); +begin + fbuffer.addchars(msestring(atext)); +end; + +constructor ttargetconsolefo.create(aowner: tcomponent); +begin + fbuffer:= tmsestringdatalist.create; + fbuffer.maxcount:= 600; + inherited create(aowner); +end; + +destructor ttargetconsolefo.destroy; +begin + inherited; + fbuffer.free; +end; + +procedure ttargetconsolefo.targetconsoleonidle(var again: Boolean); +var + int1: integer; +begin + if fbuffer.count > 0 then begin + terminal.beginupdate; + try + for int1:= 0 to fbuffer.count - 2 do begin + terminal.addchars(fbuffer[int1]+lineend); + end; + terminal.addchars(fbuffer[fbuffer.count-1]); + fbuffer.clear; + finally + terminal.endupdate; + end; + end; +end; + +procedure ttargetconsolefo.clearexe(const sender: TObject); +begin + grid.clear; +end; + +procedure ttargetconsolefo.dofind; +var + ainfo: findinfoty; +begin + ainfo:= projectoptions.targetconsolefindinfo; + if not terminal.hasselection then begin + ainfo.selectedonly:= false; + end; +// ainfo.text:= edit.selectedtext; + if finddialogexecute(ainfo) then begin + projectoptions.targetconsolefindinfo:= ainfo; + findintextedit(terminal,projectoptions.targetconsolefindinfo,ffindpos); + end; +end; + +procedure ttargetconsolefo.repeatfind; +begin + findintextedit(terminal,projectoptions.targetconsolefindinfo,ffindpos); +end; + +procedure ttargetconsolefo.findback; +begin + findintextedit(terminal,projectoptions.targetconsolefindinfo,ffindpos,true); +end; + +procedure ttargetconsolefo.popupupdateexe(const sender: tcustommenu); +begin + with actionsmo do begin + find.enabled:= true; + repeatfind.enabled:= true; + findback.enabled:= true; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/targetconsole_mfm.pas b/mseide-msegui/apps/ide/targetconsole_mfm.pas new file mode 100644 index 0000000..819eab7 --- /dev/null +++ b/mseide-msegui/apps/ide/targetconsole_mfm.pas @@ -0,0 +1,139 @@ +unit targetconsole_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,targetconsole; + +const + objdata: record size: integer; data: array[0..2424] of byte end = + (size: 2425; data: ( + 84,80,70,48,16,116,116,97,114,103,101,116,99,111,110,115,111,108,101,102, + 111,15,116,97,114,103,101,116,99,111,110,115,111,108,101,102,111,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,15,102,114,97, + 109,101,46,103,114,105,112,95,115,105,122,101,2,10,18,102,114,97,109,101, + 46,103,114,105,112,95,111,112,116,105,111,110,115,11,14,103,111,95,99,108, + 111,115,101,98,117,116,116,111,110,16,103,111,95,102,105,120,115,105,122,101, + 98,117,116,116,111,110,14,103,111,95,102,108,111,97,116,98,117,116,116,111, + 110,12,103,111,95,116,111,112,98,117,116,116,111,110,19,103,111,95,98,97, + 99,107,103,114,111,117,110,100,98,117,116,116,111,110,15,103,111,95,110,111, + 108,111,99,107,98,117,116,116,111,110,14,103,111,95,98,117,116,116,111,110, + 104,105,110,116,115,0,9,112,111,112,117,112,109,101,110,117,7,8,112,111, + 112,117,112,109,101,110,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,3,209,0,8,98,111,117,110,100,115,95,121,3,129,1,9, + 98,111,117,110,100,115,95,99,120,3,112,1,9,98,111,117,110,100,115,95, + 99,121,3,137,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97, + 105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100, + 115,1,2,0,2,0,3,102,1,3,137,0,0,20,100,114,97,103,100,111, + 99,107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115, + 97,118,101,112,111,115,10,111,100,95,99,97,110,109,111,118,101,11,111,100, + 95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107, + 11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116, + 105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110, + 115,0,7,111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112, + 111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97, + 116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,14,84, + 97,114,103,101,116,32,67,111,110,115,111,108,101,21,105,99,111,110,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 10,105,99,111,110,46,105,109,97,103,101,10,168,2,0,0,0,0,0,0, + 0,0,0,0,24,0,0,0,24,0,0,0,116,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,124,124,124,23,255,255,255,1,124,124,124,1, + 232,232,232,22,255,255,255,1,124,124,124,1,232,232,232,22,255,255,255,1, + 124,124,124,1,232,232,232,22,255,255,255,1,124,124,124,1,232,232,232,22, + 255,255,255,1,124,124,124,1,232,232,232,22,255,255,255,1,124,124,124,1, + 232,232,232,22,255,255,255,1,124,124,124,1,232,232,232,22,255,255,255,1, + 124,124,124,1,232,232,232,12,222,222,222,1,86,86,86,1,176,176,176,1, + 232,232,232,7,255,255,255,1,124,124,124,1,232,232,232,12,226,226,226,1, + 45,45,45,1,0,0,0,1,34,34,34,1,123,123,123,1,209,209,209,1, + 232,232,232,4,255,255,255,1,124,124,124,1,232,232,232,4,214,214,214,1, + 228,228,228,1,232,232,232,5,228,228,228,1,232,232,232,2,190,190,190,1, + 103,103,103,1,19,19,19,1,4,4,4,1,70,70,70,1,160,160,160,1, + 228,228,228,1,232,232,232,1,255,255,255,1,124,124,124,1,232,232,232,2, + 146,146,146,1,20,20,20,1,0,0,0,1,5,5,5,1,65,65,65,1, + 140,140,140,1,208,208,208,1,186,186,186,1,78,78,78,1,187,187,187,1, + 232,232,232,4,227,227,227,1,159,159,159,1,71,71,71,1,4,4,4,1, + 22,22,22,1,157,157,157,1,255,255,255,1,124,124,124,1,232,232,232,2, + 39,39,39,1,84,84,84,1,125,125,125,1,81,81,81,1,20,20,20,1, + 0,0,0,3,20,20,20,1,205,205,205,1,232,232,232,5,221,221,221,1, + 144,144,144,1,42,42,42,1,0,0,0,1,124,124,124,1,255,255,255,1, + 124,124,124,1,232,232,232,2,192,192,192,1,232,232,232,3,228,228,228,1, + 166,166,166,1,130,130,130,1,153,153,153,1,218,218,218,1,232,232,232,3, + 231,231,231,1,176,176,176,1,87,87,87,1,10,10,10,1,11,11,11,1, + 92,92,92,1,184,184,184,1,232,232,232,1,255,255,255,1,124,124,124,1, + 232,232,232,12,229,229,229,1,118,118,118,1,31,31,31,1,0,0,0,1, + 49,49,49,1,141,141,141,1,221,221,221,1,232,232,232,3,255,255,255,1, + 124,124,124,1,232,232,232,12,220,220,220,1,15,15,15,1,98,98,98,1, + 190,190,190,1,232,232,232,6,255,255,255,1,124,124,124,1,232,232,232,12, + 230,230,230,1,224,224,224,1,232,232,232,8,255,255,255,1,124,124,124,1, + 232,232,232,22,255,255,255,1,124,124,124,1,232,232,232,22,255,255,255,1, + 124,124,124,1,232,232,232,22,255,255,255,1,124,124,124,1,232,232,232,22, + 255,255,255,1,124,124,124,1,232,232,232,22,255,255,255,1,124,124,124,1, + 232,232,232,22,255,255,255,1,124,124,124,1,255,255,255,23,6,111,110,105, + 100,108,101,7,19,116,97,114,103,101,116,99,111,110,115,111,108,101,111,110, + 105,100,108,101,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,9,116,100,111,99,107,102,111,114,109,0,11,116,119,105,100,103,101,116, + 103,114,105,100,4,103,114,105,100,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 3,102,1,9,98,111,117,110,100,115,95,99,121,3,137,0,7,97,110,99, + 104,111,114,115,11,0,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,11,111,112,116,105,111,110,115,103,114, + 105,100,11,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110, + 116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,20, + 111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121, + 10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112, + 111,112,117,112,0,11,114,111,119,99,111,117,110,116,109,97,120,3,136,19, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1,14,100,97, + 116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,116,101,114,109,105, + 110,97,108,1,5,119,105,100,116,104,3,184,11,7,111,112,116,105,111,110, + 115,11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116, + 97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,8,119,105,100,116,104,109,105,110,3,184,11,10,119,105,100,103,101, + 116,110,97,109,101,6,8,116,101,114,109,105,110,97,108,9,100,97,116,97, + 99,108,97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116,114,105, + 110,103,100,97,116,97,108,105,115,116,0,0,16,100,97,116,97,114,111,119, + 108,105,110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,14,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,9,116,116,101,114,109,105,110,97,108,8,116,101,114,109,105, + 110,97,108,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,184,11,9,98, + 111,117,110,100,115,95,99,121,2,14,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101, + 110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99, + 107,118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0, + 8,109,97,120,99,104,97,114,115,2,120,10,111,110,115,101,110,100,116,101, + 120,116,7,8,115,101,110,100,116,101,120,116,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,10,116,112,111,112,117,112,109,101, + 110,117,8,112,111,112,117,112,109,101,110,8,111,110,117,112,100,97,116,101, + 7,14,112,111,112,117,112,117,112,100,97,116,101,101,120,101,18,109,101,110, + 117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,5,18,109,101, + 110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,6,97, + 99,116,105,111,110,7,14,97,99,116,105,111,110,115,109,111,46,102,105,110, + 100,0,1,6,97,99,116,105,111,110,7,20,97,99,116,105,111,110,115,109, + 111,46,114,101,112,101,97,116,102,105,110,100,0,1,6,97,99,116,105,111, + 110,7,18,97,99,116,105,111,110,115,109,111,46,102,105,110,100,98,97,99, + 107,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112, + 97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99, + 97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,6,38, + 67,108,101,97,114,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,8,99, + 108,101,97,114,101,120,101,0,0,4,108,101,102,116,2,32,3,116,111,112, + 2,32,0,0,0) + ); + +initialization + registerobjectdata(@objdata,ttargetconsolefo,''); +end. diff --git a/mseide-msegui/apps/ide/templateeditor.mfm b/mseide-msegui/apps/ide/templateeditor.mfm new file mode 100644 index 0000000..291914b --- /dev/null +++ b/mseide-msegui/apps/ide/templateeditor.mfm @@ -0,0 +1,372 @@ +object templateeditorfo: ttemplateeditorfo + visible = False + bounds_x = 147 + bounds_y = 120 + bounds_cx = 473 + bounds_cy = 399 + container.frame.clientwidthmin = 473 + container.bounds = ( + 0 + 0 + 473 + 399 + ) + options = [fo_freeonclose, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Code Template Editor' + onloaded = createexe + onclosequery = closeq + moduleclassname = 'tmseform' + object tbutton1: tbutton + taborder = 12 + bounds_x = 354 + bounds_y = 376 + bounds_cx = 58 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object tbutton2: tbutton + bounds_x = 418 + bounds_y = 376 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object nameed: tstringedit + frame.caption = '&Name' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 4 + bounds_cx = 109 + bounds_cy = 37 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_notnull] + reffontheight = 14 + end + object commented: tstringedit + frame.caption = 'C&omment' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 112 + bounds_y = 4 + bounds_cx = 361 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + reffontheight = 14 + end + object paramgrid: tstringgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.caption = '&Parameter' + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 46 + bounds_cx = 473 + bounds_cy = 122 + anchors = [an_top] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + datacols.count = 2 + datacols.options = [co_fill, co_savestate, co_mousescrollrow] + datacols.items = < + item + width = 100 + options = [co_savestate, co_mousescrollrow] + valuefalse = '0' + valuetrue = '1' + end + item + width = 336 + options = [co_fill, co_savestate, co_mousescrollrow] + valuefalse = '0' + valuetrue = '1' + end> + fixcols.count = 1 + fixcols.items = < + item + width = 30 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Default Value' + end> + end> + datarowheight = 16 + statfile = tstatfile1 + reffontheight = 14 + end + object tspacer1: tspacer + taborder = 13 + bounds_x = 192 + bounds_y = 41 + bounds_cx = 50 + bounds_cy = 5 + linktop = commented + linkbottom = paramgrid + end + object tsplitter1: tsplitter + color = -1879048189 + taborder = 14 + bounds_x = 0 + bounds_y = 168 + bounds_cx = 473 + bounds_cy = 3 + anchors = [an_top] + options = [spo_vmove, spo_vprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linktop = paramgrid + linkbottom = templgrid + statfile = tstatfile1 + end + object templgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + taborder = 4 + bounds_x = 0 + bounds_y = 171 + bounds_cx = 473 + bounds_cy = 173 + anchors = [an_top, an_bottom] + optionsgrid = [og_focuscellonenter, og_autofirstrow, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 30 + numstart = 1 + numstep = 1 + end> + rowcount = 1 + datacols.count = 1 + datacols.options = [co_leftbuttonfocusonly, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[templed] + width = 1016 + options = [co_leftbuttonfocusonly, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'templed' + dataclass = tgridrichstringdatalist + data = ( + ( + '' + ) + ) + end> + datarowlinewidth = 0 + datarowheight = 15 + reffontheight = 14 + object templed: tundotextedit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 1016 + bounds_cy = 15 + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + oneditnotifcation = editnotify + reffontheight = 14 + end + end + object cursordisp: tstringdisp + frame.caption = 'Cursor' + frame.captiondist = 2 + frame.localprops1 = [frl1_captiondist] + frame.dummy = 0 + frame.outerframe = ( + 0 + 18 + 0 + 0 + ) + taborder = 15 + bounds_x = 8 + bounds_y = 359 + bounds_cx = 68 + bounds_cy = 36 + anchors = [an_left, an_bottom] + textflags = [tf_xcentered, tf_ycentered] + reffontheight = 14 + end + object tsplitter2: tsplitter + color = -1879048189 + taborder = 16 + visible = False + bounds_x = 109 + bounds_y = 16 + bounds_cx = 3 + bounds_cy = 29 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = nameed + linkright = commented + statfile = tstatfile1 + end + object coled: tintegeredit + frame.caption = 'Col' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + bounds_x = 216 + bounds_y = 359 + bounds_cx = 52 + bounds_cy = 37 + anchors = [an_left, an_bottom] + value = 1 + min = 1 + reffontheight = 14 + end + object rowed: tintegeredit + frame.caption = 'Row' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + bounds_x = 160 + bounds_y = 359 + bounds_cx = 52 + bounds_cy = 37 + anchors = [an_left, an_bottom] + value = 1 + min = 1 + reffontheight = 14 + end + object tbutton3: tbutton + taborder = 5 + bounds_x = 80 + bounds_y = 376 + bounds_cx = 74 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption, as_localonexecute] + caption = '&Set Cursor' + onexecute = setcursorex + end + object selected: tbooleanedit + frame.caption = '&select' + frame.captionpos = cp_top + frame.captiondist = 4 + frame.localprops1 = [frl1_captiondist] + frame.dummy = 0 + frame.outerframe = ( + 13 + 20 + 14 + 0 + ) + taborder = 8 + bounds_x = 267 + bounds_y = 359 + bounds_cx = 40 + bounds_cy = 33 + anchors = [an_left, an_bottom] + end + object indented: tbooleanedit + frame.caption = '&indent' + frame.captionpos = cp_top + frame.captiondist = 4 + frame.localprops1 = [frl1_captiondist] + frame.dummy = 0 + frame.outerframe = ( + 14 + 20 + 15 + 0 + ) + taborder = 9 + bounds_x = 306 + bounds_y = 359 + bounds_cx = 42 + bounds_cy = 33 + anchors = [an_left, an_bottom] + end + object deletebu: tbutton + taborder = 11 + bounds_x = 418 + bounds_y = 352 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption, as_localonexecute] + caption = 'Delete' + onexecute = deleteexe + end + object saveasbu: tbutton + taborder = 10 + bounds_x = 354 + bounds_y = 352 + bounds_cx = 58 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption, as_localonexecute] + caption = 'Filename' + onexecute = saveasexe + end + object tstatfile1: tstatfile + filename = 'templedit.sta' + options = [sfo_memory, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + onstatafterread = afterstatreadexe + left = 104 + top = 192 + end + object savefiledialog: tfiledialog + statfile = tstatfile1 + controller.filterlist.data = ( + ( + 'Code Temlate Files' + '*.mct' + ) + ) + controller.defaultext = 'mct' + controller.options = [fdo_save, fdo_checkexist, fdo_savelastdir] + left = 200 + top = 192 + end + object c: tstringcontainer + strings.data = ( + 'Do you want to delete "' + 'Code Template Editor' + 'has been added to ''Project''-''Options''-''Editor''-''Code Templates''.' + ) + left = 104 + top = 232 + end +end diff --git a/mseide-msegui/apps/ide/templateeditor.pas b/mseide-msegui/apps/ide/templateeditor.pas new file mode 100644 index 0000000..796698d --- /dev/null +++ b/mseide-msegui/apps/ide/templateeditor.pas @@ -0,0 +1,222 @@ +unit templateeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msestatfile, + msesimplewidgets,msewidgets,msedataedits,mseedit,msegrids,msestrings,msetypes, + msewidgetgrid,msegraphedits,msesplitter,mseeditglob,msetextedit,msedispwidgets, + msebitmap,msedatanodes,msefiledialog,mselistbrowser,msescrollbar,msesystypes, + msesys,msestringcontainer; +type + ttemplateeditorfo = class(tmseform) + tstatfile1: tstatfile; + tbutton1: tbutton; + tbutton2: tbutton; + nameed: tstringedit; + commented: tstringedit; + paramgrid: tstringgrid; + tspacer1: tspacer; + tsplitter1: tsplitter; + templgrid: twidgetgrid; + templed: tundotextedit; + cursordisp: tstringdisp; + tsplitter2: tsplitter; + coled: tintegeredit; + rowed: tintegeredit; + tbutton3: tbutton; + selected: tbooleanedit; + indented: tbooleanedit; + savefiledialog: tfiledialog; + deletebu: tbutton; + saveasbu: tbutton; + c: tstringcontainer; + procedure afterstatreadexe(const sender: TObject); + procedure editnotify(const sender: TObject; + var info: editnotificationinfoty); + procedure setcursorex(const sender: TObject); + procedure closeq(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure saveasexe(const sender: TObject); + procedure deleteexe(const sender: TObject); + procedure createexe(const sender: TObject); + private + findex: integer; + fpath: filenamety; + fdeleted: boolean; + procedure setpath(const avalue: filenamety); + property path: filenamety read fpath write setpath; + public + constructor create(const aindex: integer); reintroduce; + function show(out aname: msestring): modalresultty; reintroduce; + end; + +implementation +uses + templateeditor_mfm,msecodetemplates,projectoptionsform,sysutils,msefileutils, + msedatalist,msesysintf,msearrayutils,mseformatstr; +type + stringconststy = ( + wantdelete, //0 Do you want to delete " + codetemped, //1 Code Template Editor + hasbeenaddedto + //2 has been added to 'Project'-'Options'-'Editor'-'Code Templates'. + ); + +constructor ttemplateeditorfo.create(const aindex: integer); +begin + findex:= aindex; + inherited create(nil); +end; + +procedure ttemplateeditorfo.afterstatreadexe(const sender: TObject); +var + dir1: filenamety; +begin + if savefiledialog.controller.lastdir = '' then begin + if findfile('',projectoptions.e.texp.codetemplatedirs,dir1) or + findfile('',[expandprmacros('${TEMPLATEDIR}')],dir1) then begin + savefiledialog.controller.lastdir:= dir1; + end; + end; +end; + +procedure ttemplateeditorfo.createexe(const sender: TObject); +begin + projectoptionstofont(templed.font); + templgrid.datarowheight:= templed.font.lineheight; + if (findex >= 0) and (findex <= high(codetemplates.templates)) then begin + with codetemplates.templates[findex] do begin + self.path:= path; + selected.value:= select; + indented.value:= indent; + coled.value:= cursorcol+1; + rowed.value:= cursorrow+1; + commented.value:= comment; + nameed.value:= name; + paramgrid[0].datalist.asarray:= params; + paramgrid[1].datalist.asarray:= paramdefaults; + templed.settext(template); + end; + end + else begin + path:= ''; + end; +end; + + +procedure ttemplateeditorfo.editnotify(const sender: TObject; + var info: editnotificationinfoty); +begin + case info.action of + ea_indexmoved: begin + with templed.editpos do begin + cursordisp.value:= inttostrmse(row+1) + ':'+inttostrmse(col+1); + end; + end; + end; +end; + +procedure ttemplateeditorfo.setcursorex(const sender: TObject); +begin + if templgrid.isdatacell(templgrid.focusedcell) then begin + with templed.editpos do begin + coled.value:= col+1; + rowed.value:= row+1; + end; + end + else begin + coled.value:= 1; + rowed.value:= 1; + end; +end; + +procedure ttemplateeditorfo.closeq(const sender: tcustommseform; + var amodalresult: modalresultty); +var + info1: templateinfoty; + dir1,pa1: filenamety; + int1: integer; +begin + if fdeleted then begin + amodalresult:= mr_ok; + end + else begin + if amodalresult = mr_ok then begin + codetemplates.initinfo(info1); + with info1 do begin + select:= selected.value; + indent:= indented.value; + cursorcol:= coled.value - 1; + cursorrow:= rowed.value - 1; + comment:= commented.value; + name:= nameed.value; + paramgrid.removeappendedrow; + params:= paramgrid[0].datalist.asarray; + paramdefaults:= paramgrid[1].datalist.asarray; + template:= templed.gettext; + if fpath = '' then begin + if not savefiledialog.controller.execute(fpath) then begin + amodalresult:= mr_cancel; + end; + end; + path:= fpath; + end; + if amodalresult = mr_ok then begin + codetemplates.savefile(info1); + dir1:= filedir(info1.path); + pa1:= intermediatefilename(dir1+'template'); + if sys_openfile(pa1,fm_create,[],[],int1) = sye_ok then begin + sys_closefile(int1); + if not findfile(filename(pa1), + projectoptions.e.texp.codetemplatedirs) then begin + deletefile(pa1); + additem(projectoptions.e.t.fcodetemplatedirs,dir1); + expandprojectmacros; + projectoptionsmodified; + showmessage('"'+dir1+'" '+c[ord(hasbeenaddedto)]); + exit; + end; + end; + deletefile(pa1); + end; + end; + end; +end; + +function ttemplateeditorfo.show(out aname: msestring): modalresultty; +begin + result:= inherited show(true); + aname:= nameed.value; +end; + +procedure ttemplateeditorfo.saveasexe(const sender: TObject); +begin + if savefiledialog.controller.execute(fpath) then begin + path:= fpath; + end; +end; + +procedure ttemplateeditorfo.deleteexe(const sender: TObject); +begin + if askyesno(c[ord(wantdelete)]+fpath+'"?') then begin + deletefile(fpath); + fdeleted:= true; + window.modalresult:= mr_cancel; + end; +end; + +procedure ttemplateeditorfo.setpath(const avalue: filenamety); +begin + fpath:= avalue; + if fpath = '' then begin + caption:= c[ord(codetemped)]; + deletebu.enabled:= false; + end + else begin + caption:= shrinkstring(fpath,40); + deletebu.enabled:= true; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/templateeditor_mfm.pas b/mseide-msegui/apps/ide/templateeditor_mfm.pas new file mode 100644 index 0000000..92d26e8 --- /dev/null +++ b/mseide-msegui/apps/ide/templateeditor_mfm.pas @@ -0,0 +1,324 @@ +unit templateeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,templateeditor; + +const + objdata: record size: integer; data: array[0..6132] of byte end = + (size: 6133; data: ( + 84,80,70,48,17,116,116,101,109,112,108,97,116,101,101,100,105,116,111,114, + 102,111,16,116,101,109,112,108,97,116,101,101,100,105,116,111,114,102,111,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,147,0, + 8,98,111,117,110,100,115,95,121,2,120,9,98,111,117,110,100,115,95,99, + 120,3,217,1,9,98,111,117,110,100,115,95,99,121,3,143,1,30,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,99,108,105,101,110,116, + 119,105,100,116,104,109,105,110,3,217,1,16,99,111,110,116,97,105,110,101, + 114,46,98,111,117,110,100,115,1,2,0,2,0,3,217,1,3,143,1,0, + 7,111,112,116,105,111,110,115,11,14,102,111,95,102,114,101,101,111,110,99, + 108,111,115,101,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102, + 111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117, + 116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112, + 111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95, + 115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6, + 20,67,111,100,101,32,84,101,109,112,108,97,116,101,32,69,100,105,116,111, + 114,8,111,110,108,111,97,100,101,100,7,9,99,114,101,97,116,101,101,120, + 101,12,111,110,99,108,111,115,101,113,117,101,114,121,7,6,99,108,111,115, + 101,113,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8, + 116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,49,8,116,97,98,111,114,100,101,114,2,12,8,98,111, + 117,110,100,115,95,120,3,98,1,8,98,111,117,110,100,115,95,121,3,120, + 1,9,98,111,117,110,100,115,95,99,120,2,58,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105, + 103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101, + 11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109, + 111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7, + 116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,8,98,111,117, + 110,100,115,95,120,3,162,1,8,98,111,117,110,100,115,95,121,3,120,1, + 9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95, + 99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97, + 112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,6,110,97,109,101,101,100,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,5,38,78,97,109,101,11, + 102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,4,9,98,111,117,110,100,115, + 95,99,120,2,109,9,98,111,117,110,100,115,95,99,121,2,37,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104, + 105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,10,111,101,95,110,111,116, + 110,117,108,108,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,9,99,111,109,109, + 101,110,116,101,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 8,67,38,111,109,109,101,110,116,11,102,114,97,109,101,46,100,117,109,109, + 121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2, + 2,8,98,111,117,110,100,115,95,120,2,112,8,98,111,117,110,100,115,95, + 121,2,4,9,98,111,117,110,100,115,95,99,120,3,105,1,9,98,111,117, + 110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 11,116,115,116,114,105,110,103,103,114,105,100,9,112,97,114,97,109,103,114, + 105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111, + 99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115, + 101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 10,38,80,97,114,97,109,101,116,101,114,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116, + 97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,46,9,98,111,117,110,100,115,95,99, + 120,3,217,1,9,98,111,117,110,100,115,95,99,121,2,122,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,0,11,111,112,116,105,111,110, + 115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12, + 111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114, + 111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114, + 116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15, + 111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97, + 117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104,97,110, + 103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111, + 108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109,111, + 117,115,101,115,99,114,111,108,108,99,111,108,0,14,100,97,116,97,99,111, + 108,115,46,99,111,117,110,116,2,2,16,100,97,116,97,99,111,108,115,46, + 111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95, + 115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116, + 101,109,115,14,1,5,119,105,100,116,104,2,100,7,111,112,116,105,111,110, + 115,11,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,118,97,108,117,101, + 102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1, + 49,0,1,5,119,105,100,116,104,3,80,1,7,111,112,116,105,111,110,115, + 11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117, + 101,116,114,117,101,6,1,49,0,0,13,102,105,120,99,111,108,115,46,99, + 111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115, + 14,1,5,119,105,100,116,104,2,30,8,110,117,109,115,116,97,114,116,2, + 1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119, + 115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116, + 101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105, + 111,110,115,46,99,111,117,110,116,2,2,14,99,97,112,116,105,111,110,115, + 46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,4,78,97, + 109,101,0,1,7,99,97,112,116,105,111,110,6,13,68,101,102,97,117,108, + 116,32,86,97,108,117,101,0,0,0,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,16,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,7,116,115,112,97,99,101,114,8,116,115,112,97,99, + 101,114,49,8,116,97,98,111,114,100,101,114,2,13,8,98,111,117,110,100, + 115,95,120,3,192,0,8,98,111,117,110,100,115,95,121,2,41,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 5,7,108,105,110,107,116,111,112,7,9,99,111,109,109,101,110,116,101,100, + 10,108,105,110,107,98,111,116,116,111,109,7,9,112,97,114,97,109,103,114, + 105,100,0,0,9,116,115,112,108,105,116,116,101,114,10,116,115,112,108,105, + 116,116,101,114,49,5,99,111,108,111,114,4,3,0,0,144,8,116,97,98, + 111,114,100,101,114,2,14,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,3,168,0,9,98,111,117,110,100,115,95,99,120, + 3,217,1,9,98,111,117,110,100,115,95,99,121,2,3,7,97,110,99,104, + 111,114,115,11,6,97,110,95,116,111,112,0,7,111,112,116,105,111,110,115, + 11,9,115,112,111,95,118,109,111,118,101,9,115,112,111,95,118,112,114,111, + 112,12,115,112,111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100, + 111,99,107,116,111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116, + 14,115,112,111,95,100,111,99,107,98,111,116,116,111,109,0,7,108,105,110, + 107,116,111,112,7,9,112,97,114,97,109,103,114,105,100,10,108,105,110,107, + 98,111,116,116,111,109,7,9,116,101,109,112,108,103,114,105,100,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,0,0, + 11,116,119,105,100,103,101,116,103,114,105,100,9,116,101,109,112,108,103,114, + 105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111, + 99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115, + 101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,171,0,9, + 98,111,117,110,100,115,95,99,120,3,217,1,9,98,111,117,110,100,115,95, + 99,121,3,173,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111, + 112,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115, + 103,114,105,100,11,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110, + 101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111, + 119,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107, + 101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108, + 108,99,111,108,0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2, + 1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105, + 100,116,104,2,30,8,110,117,109,115,116,97,114,116,2,1,7,110,117,109, + 115,116,101,112,2,1,0,0,8,114,111,119,99,111,117,110,116,2,1,14, + 100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1,16,100,97,116, + 97,99,111,108,115,46,111,112,116,105,111,110,115,11,22,99,111,95,108,101, + 102,116,98,117,116,116,111,110,102,111,99,117,115,111,110,108,121,12,99,111, + 95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116, + 97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,7, + 116,101,109,112,108,101,100,1,5,119,105,100,116,104,3,248,3,7,111,112, + 116,105,111,110,115,11,22,99,111,95,108,101,102,116,98,117,116,116,111,110, + 102,111,99,117,115,111,110,108,121,12,99,111,95,115,97,118,101,118,97,108, + 117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,7,116,101,109,112,108,101,100,9,100,97,116,97,99, + 108,97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,4,100,97,116,97,1,1,6,0,0,0, + 0,0,16,100,97,116,97,114,111,119,108,105,110,101,119,105,100,116,104,2, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,15,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,13,116,117,110,100,111, + 116,101,120,116,101,100,105,116,7,116,101,109,112,108,101,100,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,248,3,9,98,111,117,110,100,115,95,99,121,2,15,9,102,111, + 110,116,46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,10,102,111,110,116,46, + 100,117,109,109,121,2,0,17,111,110,101,100,105,116,110,111,116,105,102,99, + 97,116,105,111,110,7,10,101,100,105,116,110,111,116,105,102,121,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,11,116,115,116, + 114,105,110,103,100,105,115,112,10,99,117,114,115,111,114,100,105,115,112,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,6,67,117,114,115,111, + 114,17,102,114,97,109,101,46,99,97,112,116,105,111,110,100,105,115,116,2, + 2,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 16,102,114,108,49,95,99,97,112,116,105,111,110,100,105,115,116,0,11,102, + 114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,18,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,15,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,3,103,1,9,98,111,117,110,100,115, + 95,99,120,2,68,9,98,111,117,110,100,115,95,99,121,2,36,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111, + 116,116,111,109,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114, + 101,100,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,9,116,115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116,101, + 114,50,5,99,111,108,111,114,4,3,0,0,144,8,116,97,98,111,114,100, + 101,114,2,16,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,2,109,8,98,111,117,110,100,115,95,121,2,16,9,98,111,117,110, + 100,115,95,99,120,2,3,9,98,111,117,110,100,115,95,99,121,2,29,7, + 111,112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111,112,12,115, + 112,111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100,111,99,107, + 116,111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116,14,115,112, + 111,95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110,107,108,101, + 102,116,7,6,110,97,109,101,101,100,9,108,105,110,107,114,105,103,104,116, + 7,9,99,111,109,109,101,110,116,101,100,8,115,116,97,116,102,105,108,101, + 7,10,116,115,116,97,116,102,105,108,101,49,0,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,5,99,111,108,101,100,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,3,67,111,108,11,102,114,97,109,101,46,100, + 117,109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,7,8,98,111,117,110,100,115,95,120,3,216,0,8,98,111,117, + 110,100,115,95,121,3,103,1,9,98,111,117,110,100,115,95,99,120,2,52, + 9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0, + 5,118,97,108,117,101,2,1,3,109,105,110,2,1,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,5,114,111,119,101,100,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,3,82,111,119,11,102,114,97,109,101,46,100,117,109, + 109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,6,8,98,111,117,110,100,115,95,120,3,160,0,8,98,111,117,110,100, + 115,95,121,3,103,1,9,98,111,117,110,100,115,95,99,120,2,52,9,98, + 111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,5,118, + 97,108,117,101,2,1,3,109,105,110,2,1,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,8,116, + 98,117,116,116,111,110,51,8,116,97,98,111,114,100,101,114,2,5,8,98, + 111,117,110,100,115,95,120,2,80,8,98,111,117,110,100,115,95,121,3,120, + 1,9,98,111,117,110,100,115,95,99,120,2,74,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116, + 105,111,110,6,11,38,83,101,116,32,67,117,114,115,111,114,9,111,110,101, + 120,101,99,117,116,101,7,11,115,101,116,99,117,114,115,111,114,101,120,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,8,115,101,108,101,99, + 116,101,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,7,38, + 115,101,108,101,99,116,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,17,102,114,97,109,101,46,99,97, + 112,116,105,111,110,100,105,115,116,2,4,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,16,102,114,108,49,95,99,97,112,116, + 105,111,110,100,105,115,116,0,11,102,114,97,109,101,46,100,117,109,109,121, + 2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,13,2,20,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,8, + 8,98,111,117,110,100,115,95,120,3,11,1,8,98,111,117,110,100,115,95, + 121,3,103,1,9,98,111,117,110,100,115,95,99,120,2,40,9,98,111,117, + 110,100,115,95,99,121,2,33,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,8,105,110,100,101,110,116,101,100, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,7,38,105,110,100, + 101,110,116,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,17,102,114,97,109,101,46,99,97,112,116,105, + 111,110,100,105,115,116,2,4,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,16,102,114,108,49,95,99,97,112,116,105,111,110, + 100,105,115,116,0,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,14,2, + 20,2,15,2,0,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111, + 117,110,100,115,95,120,3,50,1,8,98,111,117,110,100,115,95,121,3,103, + 1,9,98,111,117,110,100,115,95,99,120,2,42,9,98,111,117,110,100,115, + 95,99,121,2,33,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,9,97,110,95,98,111,116,116,111,109,0,0,0,7,116,98,117,116, + 116,111,110,8,100,101,108,101,116,101,98,117,8,116,97,98,111,114,100,101, + 114,2,11,8,98,111,117,110,100,115,95,120,3,162,1,8,98,111,117,110, + 100,115,95,121,3,96,1,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11, + 8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,7,99,97,112,116,105,111,110,6,6,68,101,108,101,116,101,9,111, + 110,101,120,101,99,117,116,101,7,9,100,101,108,101,116,101,101,120,101,0, + 0,7,116,98,117,116,116,111,110,8,115,97,118,101,97,115,98,117,8,116, + 97,98,111,114,100,101,114,2,10,8,98,111,117,110,100,115,95,120,3,98, + 1,8,98,111,117,110,100,115,95,121,3,96,1,9,98,111,117,110,100,115, + 95,99,120,2,58,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110, + 99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,8,70,105, + 108,101,110,97,109,101,9,111,110,101,120,101,99,117,116,101,7,9,115,97, + 118,101,97,115,101,120,101,0,0,9,116,115,116,97,116,102,105,108,101,10, + 116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6, + 13,116,101,109,112,108,101,100,105,116,46,115,116,97,7,111,112,116,105,111, + 110,115,11,10,115,102,111,95,109,101,109,111,114,121,15,115,102,111,95,116, + 114,97,110,115,97,99,116,105,111,110,17,115,102,111,95,97,99,116,105,118, + 97,116,111,114,114,101,97,100,18,115,102,111,95,97,99,116,105,118,97,116, + 111,114,119,114,105,116,101,0,15,111,110,115,116,97,116,97,102,116,101,114, + 114,101,97,100,7,16,97,102,116,101,114,115,116,97,116,114,101,97,100,101, + 120,101,4,108,101,102,116,2,104,3,116,111,112,3,192,0,0,0,11,116, + 102,105,108,101,100,105,97,108,111,103,14,115,97,118,101,102,105,108,101,100, + 105,97,108,111,103,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97, + 116,102,105,108,101,49,26,99,111,110,116,114,111,108,108,101,114,46,102,105, + 108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,18,67,111,100, + 101,32,84,101,109,108,97,116,101,32,70,105,108,101,115,6,5,42,46,109, + 99,116,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102,97, + 117,108,116,101,120,116,6,3,109,99,116,18,99,111,110,116,114,111,108,108, + 101,114,46,111,112,116,105,111,110,115,11,8,102,100,111,95,115,97,118,101, + 14,102,100,111,95,99,104,101,99,107,101,120,105,115,116,15,102,100,111,95, + 115,97,118,101,108,97,115,116,100,105,114,0,4,108,101,102,116,3,200,0, + 3,116,111,112,3,192,0,0,0,16,116,115,116,114,105,110,103,99,111,110, + 116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116, + 97,1,6,23,68,111,32,121,111,117,32,119,97,110,116,32,116,111,32,100, + 101,108,101,116,101,32,34,6,20,67,111,100,101,32,84,101,109,112,108,97, + 116,101,32,69,100,105,116,111,114,6,64,104,97,115,32,98,101,101,110,32, + 97,100,100,101,100,32,116,111,32,39,80,114,111,106,101,99,116,39,45,39, + 79,112,116,105,111,110,115,39,45,39,69,100,105,116,111,114,39,45,39,67, + 111,100,101,32,84,101,109,112,108,97,116,101,115,39,46,0,4,108,101,102, + 116,2,104,3,116,111,112,3,232,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,ttemplateeditorfo,''); +end. diff --git a/mseide-msegui/apps/ide/templates/console.prj b/mseide-msegui/apps/ide/templates/console.prj new file mode 100644 index 0000000..b846217 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/console.prj @@ -0,0 +1,970 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/console.prj +mainfile=${PROJECTNAME}.pas +targetfile=${PROJECTNAME}${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=1 + ${TEMPLATEDIR}/console/project.pas +newprojectfilesdest=1 + ${%PROJECTNAME%}.pas +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=12 + Mainform + Simple Form + Docking Form + Sizing Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=12 + form + form + form + form + module + form + form + form + form + report + script + form +newfosources=12 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/sizingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=12 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/sizingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 196671 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=1 + 1 +loadprojectfile=1 + 1 +newinheritedforms=12 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,F,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=110 +firsttab=0 +index=-1 +[layout] +windowlayout=530 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=554 + cx=323 + cy=169 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=276 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=279 + cx=313 + cy=221 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=500 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/console/program.pas b/mseide-msegui/apps/ide/templates/console/program.pas new file mode 100644 index 0000000..0e063a1 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/console/program.pas @@ -0,0 +1,8 @@ +program ${%PROGRAMNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef mswindows}{$apptype console}{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,cwstring,{$endif}{$endif} + sysutils; +begin +end. diff --git a/mseide-msegui/apps/ide/templates/console/project.pas b/mseide-msegui/apps/ide/templates/console/project.pas new file mode 100644 index 0000000..c7e5fcf --- /dev/null +++ b/mseide-msegui/apps/ide/templates/console/project.pas @@ -0,0 +1,8 @@ +program ${%PROJECTNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef mswindows}{$apptype console}{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,cwstring,{$endif}{$endif} + sysutils; +begin +end. diff --git a/mseide-msegui/apps/ide/templates/console/projectarm.pas b/mseide-msegui/apps/ide/templates/console/projectarm.pas new file mode 100644 index 0000000..c7e5fcf --- /dev/null +++ b/mseide-msegui/apps/ide/templates/console/projectarm.pas @@ -0,0 +1,8 @@ +program ${%PROJECTNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef mswindows}{$apptype console}{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,cwstring,{$endif}{$endif} + sysutils; +begin +end. diff --git a/mseide-msegui/apps/ide/templates/console/unit.pas b/mseide-msegui/apps/ide/templates/console/unit.pas new file mode 100644 index 0000000..0cbfb2b --- /dev/null +++ b/mseide-msegui/apps/ide/templates/console/unit.pas @@ -0,0 +1,5 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +end. diff --git a/mseide-msegui/apps/ide/templates/copytarget.sh b/mseide-msegui/apps/ide/templates/copytarget.sh new file mode 100755 index 0000000..078d4c1 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/copytarget.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# parameters: +#1 2 [3] +#SOURCE, DEST, --wait +# +echo Copying by scp \"$1\" to \"$2\" +if scp $1 $2 +then + if [[ $3 == "--wait" ]] + then + echo Please press return key + read + fi +else + echo Please press return key + read +fi \ No newline at end of file diff --git a/mseide-msegui/apps/ide/templates/crossarmconsole.prj b/mseide-msegui/apps/ide/templates/crossarmconsole.prj new file mode 100644 index 0000000..11b497b --- /dev/null +++ b/mseide-msegui/apps/ide/templates/crossarmconsole.prj @@ -0,0 +1,1143 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/templates/crossarmconsole.prj +options=107 + [projectoptionsfo.toolshortcuts] + dropdowncolwidths=3 + 70 + 70 + 70 + [projectoptionsfo.twidgetgrid3] + propcolwidthref=723 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + width4=97 + sortdescend4=0 + width5=78 + sortdescend5=0 + width6=50 + sortdescend6=0 + width7=50 + sortdescend7=0 + width8=99 + sortdescend8=0 + width9=295 + sortdescend9=0 + [projectoptionsfo.twidgetgrid4] + propcolwidthref=549 + width0=96 + sortdescend0=0 + sortdescend1=0 + width2=73 + sortdescend2=0 + width3=263 + sortdescend3=0 + width4=276 + sortdescend4=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [projectoptionsfo.newfile] + firsttab=0 + index=0 + [projectoptionsfo.fontaliasgrid] + propcolwidthref=386 + width0=98 + sortdescend0=0 + width1=375 + sortdescend1=0 + width2=50 + sortdescend2=0 + width3=50 + sortdescend3=0 + width4=50 + sortdescend4=0 + width5=50 + sortdescend5=0 + width6=70 + sortdescend6=0 + [projectoptionsfo.macrosplitter] + x=0 + y=121 + xprop=1 + yprop=0.23984526112186 + [projectoptionsfo.macrogrid] + propcolwidthref=515 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + width6=146 + sortdescend6=0 + width7=503 + sortdescend7=0 + [projectoptionsfo.makegroupbox] + firsttab=0 + index=1 + [projectoptionsfo.exceptionsgrid] + propcolwidthref=707 + width0=47 + sortdescend0=0 + width1=701 + sortdescend1=0 + [projectoptionsfo.ttabwidget1] + firsttab=0 + index=4 + [projectoptionsfo.filefiltergrid] + propcolwidthref=615 + width0=112 + sortdescend0=0 + width1=608 + sortdescend1=0 + [projectoptionsfo.ttabwidget2] + firsttab=0 + index=0 + [projectoptionsfo.ttabwidget3] + firsttab=0 + index=0 + [projectoptionsfo.tabwidget] + firsttab=0 + index=3 + [projectoptionsfo] + stackedunder= + x=19 + y=122 + cx=756 + cy=568 +mainfile=${PROJECTNAME}.pas +targetfile=${PROJECTNAME}${EXEEXT} +makecommand=${COMPILER} +makedir= +unitdirs=0 +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 ${FPCOPT} + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +fontnames=0 +reversepathorder=0 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsmacros=0 +settingstemplates=0 +settingstools=0 +settingsstorage=0 +settingscomponentstore=0 +settingsprojecttree=0 +settingslayout=0 +settingsautoload=0 +settingsautosave=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +componenthints=1 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +pairmarkcolor=-2147483642 +editfontantialiased=1 +editmarkbrackets=1 +editmarkpairwords=0 +backupfilecount=2 +encoding=1 +eolstyle=1 +trimtrailingwhitespace=0 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection=${REMOTETARGET} +uploadcommand=${COPYTARGET} +gdbprocessor=arm +gdbservercommand=${RUNTARGET} +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=2 +nogdbserverexit=1 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +fpcgdbworkaround=1 +macroon=22 + 6 + 6 + 2 + 4 + 6 + 6 + 6 + 6 + 6 + 6 + 57 + 6 + 57 + 6 + 57 + 6 + 6 + 6 + 6 + 2 + 4 + 57 +macronames=22 + TARGETPROJECTDIR + TARGETENV + ABI + ABI + TARGETDIR + HOSTTARGETDIR + MSEDIR + TARGETEXE + TARGETPATH + COPYTARGET + COPYTARGET + RUNTARGET + RUNTARGET + REMOTETARGET + REMOTETARGET + CROSSFPC + DEBUGGER + COMPILER + FPCOPTIONS + FPCOPT + FPCOPT + FPCOPT +macrovalues=22 + your project dir on target example: /home/pi/proj/test + XAUTHORITY=/home/pi/.Xauthority DISPLAY=:0.0 + eabi + eabihf + ${TARGETPROJECTDIR} + ${CROSSDESTDIR}/${TARGETPROJECTDIR} + ${CROSSMSEDIR}/ + ${PROJECTNAME}${EXEEXT} + ${TARGETDIR}/${TARGETEXE} + xterm -e ${TEMPLATEDIR}copytarget.sh ${TARGETEXE} ${REMOTEUSER}@${REMOTEIP}:${TARGETDIR}/${TARGETEXE} + + xterm -e ${TEMPLATEDIR}runsshgdbserver.sh ${HOSTIP} ${REMOTEIP} ${REMOTEPORT} ${REMOTEUSER} "${TARGETENV}" ${TARGETPATH} ${TARGETPARAMS} + + remote ${REMOTEIP}:${REMOTEPORT} + + ${CROSSFPCDIR}/${ABI} + ${CROSSFPC}/bin/gdb + ${CROSSFPC}/lib/fpc/${CROSSFPCVERSION}/ppcrossarm + -n -Xd -viwn -e${CROSSFPC}/bin -Fl${CROSSFPC}/lib -Fu${CROSSFPC}/lib/fpc/${CROSSFPCVERSION}/units/arm-linux/* + ${FPCOPTIONS} + ${FPCOPTIONS} -CpARMV6 -CfVFPV2 + +groupcomments=6 + Local + Remote eabi + Remote eabihf (Raspberry Pi) + + + +toolmenus=0 +toolfiles=0 +toolparams=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=1 + ${TEMPLATEDIR}/console/projectarm.pas +newprojectfilesdest=1 + ${%PROJECTNAME%}.pas +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +expandprojectfilemacros=1 + 1 +loadprojectfile=1 + 1 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +messageoutputfile= +modulenames=0 +moduletypes=0 +modulefiles=0 +macrogroup=2 +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,F,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=114 +firsttab=0 +index=-1 +[layout] +windowlayout=530 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=268582016 + [mainfo] + splitdir=0 + useroptions=838860923 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=554 + cx=323 + cy=169 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=805322875 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=805322859 + stackedunder=cpuarmfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=268451947 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=805322859 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=276 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=268451947 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=805322859 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=805322875 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=279 + cx=313 + cy=221 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=116 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=805355627 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=805331067 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=805331051 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=268460139 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=805322857 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [mainfo.panel1] + splitdir=2 + useroptions=838893035 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=838893035 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=500 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [cpuarmfo] + irqoff=0 + splitdir=0 + useroptions=268451947 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=174 + y=158 + cx=261 + cy=253 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/crossarmdefault.prj b/mseide-msegui/apps/ide/templates/crossarmdefault.prj new file mode 100644 index 0000000..f09d00a --- /dev/null +++ b/mseide-msegui/apps/ide/templates/crossarmdefault.prj @@ -0,0 +1,1175 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/templates/crossarmdefault.prj +options=107 + [projectoptionsfo.toolshortcuts] + dropdowncolwidths=3 + 70 + 70 + 70 + [projectoptionsfo.twidgetgrid3] + propcolwidthref=723 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + width4=97 + sortdescend4=0 + width5=78 + sortdescend5=0 + width6=50 + sortdescend6=0 + width7=50 + sortdescend7=0 + width8=99 + sortdescend8=0 + width9=295 + sortdescend9=0 + [projectoptionsfo.twidgetgrid4] + propcolwidthref=549 + width0=96 + sortdescend0=0 + sortdescend1=0 + width2=73 + sortdescend2=0 + width3=263 + sortdescend3=0 + width4=276 + sortdescend4=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [projectoptionsfo.newfile] + firsttab=0 + index=0 + [projectoptionsfo.fontaliasgrid] + propcolwidthref=386 + width0=98 + sortdescend0=0 + width1=375 + sortdescend1=0 + width2=50 + sortdescend2=0 + width3=50 + sortdescend3=0 + width4=50 + sortdescend4=0 + width5=50 + sortdescend5=0 + width6=70 + sortdescend6=0 + [projectoptionsfo.macrosplitter] + x=0 + y=121 + xprop=1 + yprop=0.23984526112186 + [projectoptionsfo.macrogrid] + propcolwidthref=515 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + width6=146 + sortdescend6=0 + width7=503 + sortdescend7=0 + [projectoptionsfo.makegroupbox] + firsttab=0 + index=1 + [projectoptionsfo.exceptionsgrid] + propcolwidthref=707 + width0=47 + sortdescend0=0 + width1=701 + sortdescend1=0 + [projectoptionsfo.ttabwidget1] + firsttab=0 + index=4 + [projectoptionsfo.filefiltergrid] + propcolwidthref=615 + width0=112 + sortdescend0=0 + width1=608 + sortdescend1=0 + [projectoptionsfo.ttabwidget2] + firsttab=0 + index=0 + [projectoptionsfo.ttabwidget3] + firsttab=0 + index=0 + [projectoptionsfo.tabwidget] + firsttab=0 + index=3 + [projectoptionsfo] + stackedunder= + x=19 + y=122 + cx=756 + cy=568 +mainfile=${PROJECTNAME}.pas +targetfile=${PROJECTNAME}${EXEEXT} +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 ${FPCOPT} + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +fontnames=0 +reversepathorder=0 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsmacros=0 +settingstemplates=0 +settingstools=0 +settingsstorage=0 +settingscomponentstore=0 +settingsprojecttree=0 +settingslayout=0 +settingsautoload=0 +settingsautosave=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 196671 + 65599 + 65599 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +componenthints=1 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +pairmarkcolor=-2147483642 +editfontantialiased=1 +editmarkbrackets=1 +editmarkpairwords=0 +backupfilecount=2 +encoding=1 +eolstyle=1 +trimtrailingwhitespace=0 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection=${REMOTETARGET} +uploadcommand=${COPYTARGET} +gdbprocessor=auto +gdbservercommand=${RUNTARGET} +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=2 +nogdbserverexit=1 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +fpcgdbworkaround=1 +macroon=22 + 6 + 6 + 2 + 4 + 6 + 6 + 6 + 6 + 6 + 6 + 57 + 6 + 57 + 6 + 57 + 6 + 6 + 6 + 6 + 2 + 4 + 57 +macronames=22 + TARGETPROJECTDIR + TARGETENV + ABI + ABI + TARGETDIR + HOSTTARGETDIR + MSEDIR + TARGETEXE + TARGETPATH + COPYTARGET + COPYTARGET + RUNTARGET + RUNTARGET + REMOTETARGET + REMOTETARGET + CROSSFPC + DEBUGGER + COMPILER + FPCOPTIONS + FPCOPT + FPCOPT + FPCOPT +macrovalues=22 + your project dir on target example: /home/pi/proj/test + XAUTHORITY=/home/pi/.Xauthority DISPLAY=:0.0 + eabi + eabihf + ${TARGETPROJECTDIR} + ${CROSSDESTDIR}/${TARGETPROJECTDIR} + ${CROSSMSEDIR}/ + ${PROJECTNAME}${EXEEXT} + ${TARGETDIR}/${TARGETEXE} + xterm -e ${TEMPLATEDIR}copytarget.sh ${TARGETEXE} ${REMOTEUSER}@${REMOTEIP}:${TARGETDIR}/${TARGETEXE} + + xterm -e ${TEMPLATEDIR}runsshgdbserver.sh ${HOSTIP} ${REMOTEIP} ${REMOTEPORT} ${REMOTEUSER} "${TARGETENV}" ${TARGETPATH} ${TARGETPARAMS} + + remote ${REMOTEIP}:${REMOTEPORT} + + ${CROSSFPCDIR}/${ABI} + ${CROSSFPC}/bin/gdb + ${CROSSFPC}/lib/fpc/${CROSSFPCVERSION}/ppcrossarm + -n -Xd -viwn -e${CROSSFPC}/bin -Fl${CROSSFPC}/lib -Fu${CROSSFPC}/lib/fpc/${CROSSFPCVERSION}/units/arm-linux/* + ${FPCOPTIONS} + ${FPCOPTIONS} -CpARMV6 -CfVFPV2 + +groupcomments=6 + Local + Remote eabi + Remote eabihf (Raspberry Pi) + + + +toolmenus=0 +toolfiles=0 +toolparams=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +messageoutputfile= +modulenames=0 +moduletypes=0 +modulefiles=0 +macrogroup=2 +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,F,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ +filename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/default.stg +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=114 +firsttab=0 +index=-1 +[layout] +windowlayout=544 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=268582016 + [mainfo] + splitdir=0 + useroptions=838860923 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=805322875 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=805322859 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=268451947 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=805322859 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=268451947 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=805322859 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=805322875 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=14 + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=116 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=805355627 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=805331067 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=805331051 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=268460139 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=805322857 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=268451947 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=838893035 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=838893035 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/default.prj b/mseide-msegui/apps/ide/templates/default.prj new file mode 100644 index 0000000..811c221 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default.prj @@ -0,0 +1,971 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +mainfile=${PROJECTNAME}.pas +targetfile=${PROJECTNAME}${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=12 + Mainform + Simple Form + Docking Form + Sizing Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=12 + form + form + form + form + module + form + form + form + form + report + script + form +newfosources=12 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/sizingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=12 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/sizingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 196671 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=12 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,F,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=114 +firsttab=0 +index=-1 +[layout] +windowlayout=530 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/default/datamodule.mfm b/mseide-msegui/apps/ide/templates/default/datamodule.mfm new file mode 100644 index 0000000..7f9ac12 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/datamodule.mfm @@ -0,0 +1,9 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + left = 100 + top = 100 + moduleclassname = 'tmsedatamodule' + size = ( + 100 + 100 + ) +end diff --git a/mseide-msegui/apps/ide/templates/default/datamodule.pas b/mseide-msegui/apps/ide/templates/default/datamodule.pas new file mode 100644 index 0000000..5d9c66d --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/datamodule.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseapplication,mseclasses,msedatamodules; + +type + t${%FORMNAME%} = class(tmsedatamodule) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/dockingform.mfm b/mseide-msegui/apps/ide/templates/default/dockingform.mfm new file mode 100644 index 0000000..a6611ca --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/dockingform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 100 + bounds_y = 100 + bounds_cx = 445 + bounds_cy = 354 + moduleclassname = 'tdockform' +end diff --git a/mseide-msegui/apps/ide/templates/default/dockingform.pas b/mseide-msegui/apps/ide/templates/default/dockingform.pas new file mode 100644 index 0000000..f5b5980 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/dockingform.pas @@ -0,0 +1,16 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msedock; + +type + t${%FORMNAME%} = class(tdockform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/dockpanelform.mfm b/mseide-msegui/apps/ide/templates/default/dockpanelform.mfm new file mode 100644 index 0000000..427ac5e --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/dockpanelform.mfm @@ -0,0 +1,20 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_topbutton, go_backgroundbutton, go_lockbutton] + frame.dummy = 0 + bounds_x = 100 + bounds_y = 100 + container.frame.framei_left = 0 + container.frame.framei_top = 0 + container.frame.framei_right = 0 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + container.bounds = ( + 0 + 0 + 340 + 200 + ) + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_acceptsdock, od_dockparent, od_splitvert, od_splithorz, od_tabed, od_proportional, od_propsize] + moduleclassname = 'tdockpanelform' +end diff --git a/mseide-msegui/apps/ide/templates/default/dockpanelform.pas b/mseide-msegui/apps/ide/templates/default/dockpanelform.pas new file mode 100644 index 0000000..5477145 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/dockpanelform.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msedock,msedockpanelform; + +type + t${%FORMNAME%} = class(tdockpanelform) + end; + +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/inheritedform.mfm b/mseide-msegui/apps/ide/templates/default/inheritedform.mfm new file mode 100644 index 0000000..1b33623 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/inheritedform.mfm @@ -0,0 +1,3 @@ +inherited ${%FORMNAME%}: t${%FORMNAME%} + moduleclassname = '${%ANCESTORCLASS%}' +end diff --git a/mseide-msegui/apps/ide/templates/default/inheritedform.pas b/mseide-msegui/apps/ide/templates/default/inheritedform.pas new file mode 100644 index 0000000..768132d --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/inheritedform.pas @@ -0,0 +1,17 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + ${%ANCESTORUNIT%}; + +type + t${%FORMNAME%} = class(${%ANCESTORCLASS%}) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/main.mfm b/mseide-msegui/apps/ide/templates/default/main.mfm new file mode 100644 index 0000000..866f6ea --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/main.mfm @@ -0,0 +1,7 @@ +object mainfo: tmainfo + bounds_x = 291 + bounds_y = 247 + bounds_cx = 403 + bounds_cy = 280 + moduleclassname = 'tmainform' +end diff --git a/mseide-msegui/apps/ide/templates/default/main.pas b/mseide-msegui/apps/ide/templates/default/main.pas new file mode 100644 index 0000000..f78b670 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/main.pas @@ -0,0 +1,16 @@ +unit main; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms; + +type + tmainfo = class(tmainform) + end; +var + mainfo: tmainfo; +implementation +uses + main_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/main_mfm.pas b/mseide-msegui/apps/ide/templates/default/main_mfm.pas new file mode 100644 index 0000000..45702d8 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/main_mfm.pas @@ -0,0 +1,22 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..97] of byte end = + (size: 98; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,8, + 98,111,117,110,100,115,95,120,3,35,1,8,98,111,117,110,100,115,95,121, + 3,247,0,9,98,111,117,110,100,115,95,99,120,3,147,1,9,98,111,117, + 110,100,115,95,99,121,3,24,1,15,109,111,100,117,108,101,99,108,97,115, + 115,110,97,109,101,6,9,116,109,97,105,110,102,111,114,109,0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/apps/ide/templates/default/mainform.mfm b/mseide-msegui/apps/ide/templates/default/mainform.mfm new file mode 100644 index 0000000..03c2aca --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/mainform.mfm @@ -0,0 +1,8 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 290 + bounds_y = 234 + bounds_cx = 403 + bounds_cy = 280 + container.frame.dummy = 0 + moduleclassname = 'tmainform' +end diff --git a/mseide-msegui/apps/ide/templates/default/mainform.pas b/mseide-msegui/apps/ide/templates/default/mainform.pas new file mode 100644 index 0000000..209cf22 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/mainform.pas @@ -0,0 +1,16 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus, + msegui,msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms; + +type + t${%FORMNAME%} = class(tmainform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/pascform.mfm b/mseide-msegui/apps/ide/templates/default/pascform.mfm new file mode 100644 index 0000000..738ac5c --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/pascform.mfm @@ -0,0 +1,11 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + container.bounds_cx = 100 + container.bounds_cy = 100 + container.frame.dummy = 0 + bounds_x = 337 + bounds_y = 266 + bounds_cx = 100 + bounds_cy = 100 + color = -1879048187 + moduleclassname = 'tpascform' +end diff --git a/mseide-msegui/apps/ide/templates/default/pascform.pas b/mseide-msegui/apps/ide/templates/default/pascform.pas new file mode 100644 index 0000000..2055013 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/pascform.pas @@ -0,0 +1,16 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + msepascalscript; +type + t${%FORMNAME%} = class(tpascform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/program.pas b/mseide-msegui/apps/ide/templates/default/program.pas new file mode 100644 index 0000000..b7b663e --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/program.pas @@ -0,0 +1,11 @@ +program ${%PROGRAMNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef FPC} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/apps/ide/templates/default/project.pas b/mseide-msegui/apps/ide/templates/default/project.pas new file mode 100644 index 0000000..b80591b --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/project.pas @@ -0,0 +1,12 @@ +program ${%PROJECTNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef FPC} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} + msegui,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/apps/ide/templates/default/report.mfm b/mseide-msegui/apps/ide/templates/default/report.mfm new file mode 100644 index 0000000..c05cd94 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/report.mfm @@ -0,0 +1,18 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + ppmm = 3 + font.height = 14 + font.name = 'stf_report' + font.dummy = 0 + grid_size = 2 + repdesigninfo = ( + 177 + 159 + 460 + 369 + ) + moduleclassname = 'treport' + object treportpage1: treportpage + pagewidth = 190 + pageheight = 270 + end +end diff --git a/mseide-msegui/apps/ide/templates/default/report.pas b/mseide-msegui/apps/ide/templates/default/report.pas new file mode 100644 index 0000000..4d552dd --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/report.pas @@ -0,0 +1,18 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + msereport; + +type + t${%FORMNAME%} = class(treport) + treportpage1: treportpage; + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/reppageform.mfm b/mseide-msegui/apps/ide/templates/default/reppageform.mfm new file mode 100644 index 0000000..c0c7ccf --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/reppageform.mfm @@ -0,0 +1,14 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + ppmm = 3 + font.height = 14 + font.name = 'stf_report' + font.dummy = 0 + grid_size = 2 + repdesigninfo = ( + 177 + 159 + 460 + 369 + ) + moduleclassname = 'treppageform' +end diff --git a/mseide-msegui/apps/ide/templates/default/reppageform.pas b/mseide-msegui/apps/ide/templates/default/reppageform.pas new file mode 100644 index 0000000..839dda3 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/reppageform.pas @@ -0,0 +1,17 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + msereport; + +type + t${%FORMNAME%} = class(treppageform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/scrollboxform.mfm b/mseide-msegui/apps/ide/templates/default/scrollboxform.mfm new file mode 100644 index 0000000..0d2865d --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/scrollboxform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 100 + bounds_y = 100 + bounds_cx = 100 + bounds_cy = 100 + moduleclassname = 'tscrollboxform' +end diff --git a/mseide-msegui/apps/ide/templates/default/scrollboxform.pas b/mseide-msegui/apps/ide/templates/default/scrollboxform.pas new file mode 100644 index 0000000..547c58c --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/scrollboxform.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms; +type + t${%FORMNAME%} = class(tscrollboxform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/simpleform.mfm b/mseide-msegui/apps/ide/templates/default/simpleform.mfm new file mode 100644 index 0000000..b6b8846 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/simpleform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 337 + bounds_y = 266 + bounds_cx = 100 + bounds_cy = 100 + moduleclassname = 'tmseform' +end diff --git a/mseide-msegui/apps/ide/templates/default/simpleform.pas b/mseide-msegui/apps/ide/templates/default/simpleform.pas new file mode 100644 index 0000000..1bd02bf --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/simpleform.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms; +type + t${%FORMNAME%} = class(tmseform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/sizingform.mfm b/mseide-msegui/apps/ide/templates/default/sizingform.mfm new file mode 100644 index 0000000..bccf9d4 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/sizingform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 100 + bounds_y = 100 + bounds_cx = 445 + bounds_cy = 354 + moduleclassname = 'tsizingform' +end diff --git a/mseide-msegui/apps/ide/templates/default/sizingform.pas b/mseide-msegui/apps/ide/templates/default/sizingform.pas new file mode 100644 index 0000000..e4fa529 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/sizingform.pas @@ -0,0 +1,16 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msesizingform; + +type + t${%FORMNAME%} = class(tsizingform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/subform.mfm b/mseide-msegui/apps/ide/templates/default/subform.mfm new file mode 100644 index 0000000..2eb70a9 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/subform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 100 + bounds_y = 100 + bounds_cx = 100 + bounds_cy = 100 + moduleclassname = 'tsubform' +end diff --git a/mseide-msegui/apps/ide/templates/default/subform.pas b/mseide-msegui/apps/ide/templates/default/subform.pas new file mode 100644 index 0000000..0d57d3d --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/subform.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms; +type + t${%FORMNAME%} = class(tsubform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/tabform.mfm b/mseide-msegui/apps/ide/templates/default/tabform.mfm new file mode 100644 index 0000000..9302e30 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/tabform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 337 + bounds_y = 266 + bounds_cx = 100 + bounds_cy = 100 + moduleclassname = 'ttabform' +end diff --git a/mseide-msegui/apps/ide/templates/default/tabform.pas b/mseide-msegui/apps/ide/templates/default/tabform.pas new file mode 100644 index 0000000..ca704cf --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/tabform.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msetabs; +type + t${%FORMNAME%} = class(ttabform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/unit.pas b/mseide-msegui/apps/ide/templates/default/unit.pas new file mode 100644 index 0000000..0cbfb2b --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/unit.pas @@ -0,0 +1,5 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +end. diff --git a/mseide-msegui/apps/ide/templates/layoutconsole.prj b/mseide-msegui/apps/ide/templates/layoutconsole.prj new file mode 100644 index 0000000..cf5a3b5 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/layoutconsole.prj @@ -0,0 +1,891 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/layoutconsole.prj +mainfile= +targetfile= +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=2 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -CX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=0 +newprojectfilesdest=0 +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=0 +usercolorcomment=0 +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=2 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=0 +loadprojectfile=0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=127 +firsttab=0 +index=-1 +[layout] +windowlayout=528 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=554 + cx=323 + cy=169 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=276 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=279 + cx=313 + cy=221 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=500 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/layoutdockedforms.prj b/mseide-msegui/apps/ide/templates/layoutdockedforms.prj new file mode 100644 index 0000000..ef2fbf6 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/layoutdockedforms.prj @@ -0,0 +1,956 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/layoutdockedforms.prj +mainfile= +targetfile= +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=2 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -CX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=0 +newprojectfilesdest=0 +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=0 +usercolorcomment=0 +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=2 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=0 +loadprojectfile=0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=6 + panel1 + panel2 + panel3 + panel4 + panel5 + panel6 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=127 +firsttab=0 +index=-1 +[layout] +windowlayout=589 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + parent=mainfo.panel5.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=518 + y=0 + cx=233 + cy=517 + rcx=0 + rcy=0 + [objectinspectorfo.grid] + propcolwidthref=233 + width0=86 + sortdescend0=0 + width1=141 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + parent=mainfo.panel4.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=761 + cy=75 + rcx=0 + rcy=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo.panel3 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel3] + splitdir=1 + useroptions=32235 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=249 + y=118 + cx=771 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel4] + splitdir=2 + useroptions=32235 + parent=mainfo.panel3.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=761 + cy=605 + rcx=0 + rcy=0 + [mainfo.panel5] + splitdir=1 + useroptions=32235 + parent=mainfo.panel4.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=78 + cx=761 + cy=517 + rcx=0 + rcy=0 + [mainfo.panel6] + splitdir=2 + useroptions=32235 + parent=mainfo.panel5.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=515 + cy=517 + rcx=0 + rcy=0 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/layoutgui.prj b/mseide-msegui/apps/ide/templates/layoutgui.prj new file mode 100644 index 0000000..04df824 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/layoutgui.prj @@ -0,0 +1,906 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +order19=0 +order20=0 +[projectoptions] +mainfile= +targetfile= +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=2 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -CX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=0 +newprojectfilesdest=0 +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=0 +usercolorcomment=0 +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=2 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=0 +loadprojectfile=0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,0,Pascal Units + ) +cmodules= + ( + a=0,4132,0,C Modules + ) +files= + ( + a=0,4132,0,Text Files + ) +[componentstore] +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=127 +firsttab=0 +index=-1 +[layout] +windowlayout=544 + [mainfo.openform] + filenames=0 + filehistory=0 + filefilterindex=0 + filefilter= + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.projectfiledia] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/layoutgui.prj + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/ + filehistory=10 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/layoutgui.prj + /home/mse/packs/standard/git/mseuniverse/tools/msegit/mse_msegit.prj + /home/mse/packs/standard/git/mseide-msegui/apps/ide/mse_mseide.prj + /home/mse/proj/msegui/testcase/chefou/msegui_zengl/test.prj + /home/mse/packs/standard/git/mseuniverse/samples/widgets/layout/mse_layout.prj + /home/mse/packs/standard/git/mselang/mselang/mse_mselang.prj + /home/mse/packs/standard/git/sak/sak/sak_mse/examples/mse_mse_sak_demo.prj + /home/mse/packs/standard/git/mseuniverse/tools/msespice/mse_msespice.prj + /home/mse/proj/msegui/testcase/mse/process/terminate/terminateprocess.prj + /home/mse/proj/test3/test.prj + filefilterindex=0 + filefilter=*.prj + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filehistory=0 + filefilterindex=0 + filefilter= + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + [componentstorefo.groupfiledialog] + filenames=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + [componentstorefo.compfiledialog] + filenames=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/library.prj b/mseide-msegui/apps/ide/templates/library.prj new file mode 100644 index 0000000..8b39bfd --- /dev/null +++ b/mseide-msegui/apps/ide/templates/library.prj @@ -0,0 +1,263 @@ +[projectoptions] +mainfile=${PROJECTNAME}.pas +targetfile= +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=1 + ${TEMPLATEDIR}/library/project.pas +newprojectfilesdest=1 + ${%PROJECTNAME%}.pas +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=12 + Mainform + Simple Form + Docking Form + Sizing Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=12 + form + form + form + form + module + form + form + form + form + report + script + form +newfosources=12 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/sizingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=12 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/sizingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 196671 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=1 + 1 +loadprojectfile=1 + 1 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,F,F + 30,30,T,F +defaultmake=1 diff --git a/mseide-msegui/apps/ide/templates/library/program.pas b/mseide-msegui/apps/ide/templates/library/program.pas new file mode 100644 index 0000000..801d05e --- /dev/null +++ b/mseide-msegui/apps/ide/templates/library/program.pas @@ -0,0 +1,8 @@ +program ${%PROGRAMNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef mswindows}{$apptype console}{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,cwstring{$endif}{$endif} + sysutils; +begin +end. diff --git a/mseide-msegui/apps/ide/templates/library/project.pas b/mseide-msegui/apps/ide/templates/library/project.pas new file mode 100644 index 0000000..2d6bf00 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/library/project.pas @@ -0,0 +1,5 @@ +library ${%PROJECTNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +exports +begin +end. diff --git a/mseide-msegui/apps/ide/templates/library/unit.pas b/mseide-msegui/apps/ide/templates/library/unit.pas new file mode 100644 index 0000000..0cbfb2b --- /dev/null +++ b/mseide-msegui/apps/ide/templates/library/unit.pas @@ -0,0 +1,5 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +end. diff --git a/mseide-msegui/apps/ide/templates/runsshgdbserver.sh b/mseide-msegui/apps/ide/templates/runsshgdbserver.sh new file mode 100755 index 0000000..347b5ea --- /dev/null +++ b/mseide-msegui/apps/ide/templates/runsshgdbserver.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# parameters: +#1 2 3 4 5 6 7 +#HOSTIP, REMOTEIP, REMOTEPORT, REMOTEUSER, TARGETENV, TARGETPATH, TARGETPARAMS, +if ! ssh -t $4@$2 gdbserver --wrapper env $5 -- $1:$3 $6 $7 ; then + echo Please press enter + read +fi \ No newline at end of file diff --git a/mseide-msegui/apps/ide/templates/zeos.prj b/mseide-msegui/apps/ide/templates/zeos.prj new file mode 100644 index 0000000..3cf9b24 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/zeos.prj @@ -0,0 +1,984 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/zeos.prj +mainfile=${PROJECTNAME}.pas +targetfile=${PROJECTNAME}${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=5 + ${MSEDIR}lib/addon/*/ + ${zeosdir}src/*/ + ${zeosdir}src/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mdelphi -Sh + -gl -O- + -B + -OG2p3 -XX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=5 + 196671 + 983103 + 983103 + 65599 + 65599 +macroon=1 + 63 +macronames=1 + zeosdir +macrovalues=1 + /home/mse/packs/standard/svn/zeos/trunk/ +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=114 +firsttab=0 +index=-1 +[layout] +windowlayout=530 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/threadsform.mfm b/mseide-msegui/apps/ide/threadsform.mfm new file mode 100644 index 0000000..64c4e1b --- /dev/null +++ b/mseide-msegui/apps/ide/threadsform.mfm @@ -0,0 +1,189 @@ +object threadsfo: tthreadsfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 37 + bounds_y = 270 + bounds_cx = 349 + bounds_cy = 276 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 339 + 276 + ) + dragdock.caption = 'Threads' + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Threads' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000000090000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01FC446001F5889801EBE5E601E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EFD3D701F95E7501FC3B5801EFAFB801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01F0B0B901FC3B5801F75C7301E8CCD001 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E9E3E401F2859501FD2D4C01 + F1849401E3DDDE01E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E8CCD001 + F65C7301FB3A5701E9A9B201DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F0018ADCFF01CDE8F301EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301EAAAB301FB3A5701F55A7101E1C5C901DBDBDB01DADADA01B7D8E501 + 8ADCFF01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001B4E9FF0198E0FE01E4EAED01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E1DBDC01EF829201F9415D01DBDBDB01D3DADD01A0E0FC01 + B4E9FF01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001DDF5FF0192DFFF01AFE2F801FF002601E8E8E801FF002601E5E5E501 + FF002601E2E2E201FF002601DFDFDF01FF002601DBDBDB01C2E4F301C6EEFF01 + DDF5FF01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001F8FBFD0195DFFF0194DFFF01FF002601A3E4FF01FF002601A3E4FF01 + FF002601A3E4FF01FF002601A3E4FF01FF002601A3E4FF01E1F6FF01F1FAFF01 + F8FBFD01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001D7EAF30188D6F7018FDBFB01FF002601FFFFFF01FF002601FFFFFF01 + FF002601FFFFFF01FF002601FFFFFF01FF002601FFFFFF01F4F9FB01E7F3F801 + D7EAF301D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001B5D9E90173C7EB017BCDEF01FF002601B5D9E901FF002601B5D9E901 + FF002601B5D9E901FF002601B5D9E901FF002601B5D9E901D2E8F101C5E1EE01 + B5D9E901D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F00194C8DF015EB9DF0166BEE301FF0026016DB4D401FF0026016DB4D401 + FF0026016DB4D401FF0026016DB4D401FF0026016DB4D401AFD6E701A3D0E301 + 94C8DF01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F00173B8D6014AABD30151B0D701FF002601248FBE01FF002601248FBE01 + FF002601248FBE01FF002601248FBE01FF002601248FBE018DC5DD0180BED901 + 73B8D601D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F00152A7CC01359CC70177B9D601FF002601E8E8E801FF002601E5E5E501 + FF002601E2E2E201FF002601DFDFDF01FF002601DBDBDB0190C0D6015EADCF01 + 52A7CC01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F0013196C2013296C001DBE4E801EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01CED5D90149A0C701 + 3196C201D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F0011085B801A2C8D901EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA0198BECE01 + 1085B801D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + } + onshow = threadsfoonshow + moduleclassname = 'tdockform' + object grid: tstringgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 339 + bounds_cy = 276 + anchors = [] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + datacols.count = 3 + datacols.options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + datacols.optionsedit = [scoe_eatreturn, scoe_hintclippedtext] + datacols.items = < + item + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + textflags = [tf_right, tf_ycentered] + textflagsactive = [tf_right, tf_ycentered] + optionsedit = [scoe_undoonesc, scoe_eatreturn, scoe_exitoncursor, scoe_autoselect, scoe_autoselectonfirstclick, scoe_hintclippedtext] + valuefalse = '0' + valuetrue = '1' + end + item + width = 56 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + textflags = [tf_xcentered, tf_ycentered] + optionsedit = [scoe_undoonesc, scoe_eatreturn, scoe_exitoncursor, scoe_autoselect, scoe_autoselectonfirstclick, scoe_hintclippedtext] + valuefalse = '0' + valuetrue = '1' + end + item + width = 201 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy] + optionsedit = [scoe_undoonesc, scoe_eatreturn, scoe_exitoncursor, scoe_autoselect, scoe_autoselectonfirstclick, scoe_hintclippedtext] + valuefalse = '0' + valuetrue = '1' + end> + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 15 + captions.count = 3 + captions.items = < + item + caption = 'ID' + end + item + caption = 'State' + end + item + caption = 'Location' + textflags = [tf_ycentered] + end> + end> + datarowheight = 15 + oncellevent = gridoncellevent + reffontheight = 13 + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Copy to Clipboard' + state = [as_localcaption, as_localonexecute] + onexecute = copytoclipboardexe + end> + left = 88 + top = 144 + end + object c: tstringcontainer + strings.data = ( + '*active*' + 'unknown' + ) + left = 72 + top = 72 + end +end diff --git a/mseide-msegui/apps/ide/threadsform.pas b/mseide-msegui/apps/ide/threadsform.pas new file mode 100644 index 0000000..1a7a870 --- /dev/null +++ b/mseide-msegui/apps/ide/threadsform.pas @@ -0,0 +1,148 @@ +{ MSEide Copyright (c) 1999-2012 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit threadsform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,msegrids,msegdbutils,msetypes,msestrings, + msegridsglob,msemenus,msestringcontainer; + +type + tthreadsfo = class(tdockform) + grid: tstringgrid; + tpopupmenu1: tpopupmenu; + c: tstringcontainer; + procedure threadsfoonshow(const sender: TObject); + procedure gridoncellevent(const sender: TObject; var info: celleventinfoty); + procedure copytoclipboardexe(const sender: TObject); + private + fids: integerarty; + frefreshedrow: integer; + fstopinfo: stopinfoty; + public + gdb: tgdbmi; + procedure refresh; + procedure clear; + property stopinfo: stopinfoty read fstopinfo write fstopinfo; + end; + +var + threadsfo: tthreadsfo; + +implementation +uses + threadsform_mfm,sysutils,sourceform,msefileutils,main,stackform,mseguiintf, + sourcepage,msewidgets,mseformatstr; +type + stringconsts = ( + active, //0 *active* + unknown //1 unknown + ); + +{ tthreadsfo } + +procedure tthreadsfo.clear; +begin + grid.clear; +end; + +procedure tthreadsfo.refresh; +var + int1: integer; + ar1: threadinfoarty; + wstr1: msestring; +begin + frefreshedrow:= -1; + if visible and gdb.cancommand then begin + if gdb.getthreadinfolist(ar1) = gdb_ok then begin + setlength(fids,length(ar1)); + grid.rowcount:= length(ar1); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + fids[int1]:= id; + grid[0][int1]:= inttostrmse(threadid); + case state of + ts_active: begin + wstr1:= c[ord(active)]; + frefreshedrow:= int1; + grid.row:= int1; + end + else begin + wstr1:= c[ord(unknown)]; + end; + end; + grid[1][int1]:= wstr1; + grid[2][int1]:= msestring(stackframe); + end; + end; + end + else begin + clear; + end; + end; +end; + +procedure tthreadsfo.threadsfoonshow(const sender: TObject); +begin + refresh; +end; + +procedure tthreadsfo.gridoncellevent(const sender: TObject; + var info: celleventinfoty); +var + page1: tsourcepage; +begin + case info.eventkind of + cek_enter: begin + if (frefreshedrow <> info.cell.row) and + (gdb.threadselect(fids[info.cell.row], + fstopinfo.filename,fstopinfo.line) = gdb_ok) then begin + refresh; + stackfo.refresh; + mainfo.refreshframe; + if fstopinfo.filename <> '' then begin + fstopinfo.filedir:= ''; + sourcefo.locate(fstopinfo); + end; + end; + end; + end; + if iscellclick(info,[ccr_dblclick]) then begin + page1:= sourcefo.locate(fstopinfo); + if page1 <> nil then begin + page1.activate; + end; +// sourcefo.activate; + end; +end; + +procedure tthreadsfo.copytoclipboardexe(const sender: TObject); +var + mstr1: msestring; + int1: integer; +begin + mstr1:= ''; + for int1:= 0 to grid.rowhigh do begin + mstr1:= mstr1 + '#'+inttostrmse(int1)+' '+grid[0][int1]+' '+ + grid[1][int1]+' '+grid[2][int1]+lineend; + end; + msewidgets.copytoclipboard(mstr1); +end; + +end. diff --git a/mseide-msegui/apps/ide/threadsform_mfm.pas b/mseide-msegui/apps/ide/threadsform_mfm.pas new file mode 100644 index 0000000..039a10c --- /dev/null +++ b/mseide-msegui/apps/ide/threadsform_mfm.pas @@ -0,0 +1,278 @@ +unit threadsform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,threadsform; + +const + objdata: record size: integer; data: array[0..5204] of byte end = + (size: 5205; data: ( + 84,80,70,48,10,116,116,104,114,101,97,100,115,102,111,9,116,104,114,101, + 97,100,115,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117, + 98,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111, + 119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95, + 115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112, + 116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111, + 110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103, + 111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112, + 98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100, + 98,117,116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116, + 111,110,14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,37,8,98, + 111,117,110,100,115,95,121,3,14,1,9,98,111,117,110,100,115,95,99,120, + 3,93,1,9,98,111,117,110,100,115,95,99,121,3,20,1,26,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116, + 97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,83,1, + 3,20,1,0,16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111, + 110,6,7,84,104,114,101,97,100,115,20,100,114,97,103,100,111,99,107,46, + 111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101, + 112,111,115,10,111,100,95,99,97,110,109,111,118,101,11,111,100,95,99,97, + 110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107,11,111,100, + 95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116,105,111,110, + 104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110,115,0,7, + 111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112,111,115,12, + 102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105, + 108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116, + 97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,7,84,104,114,101, + 97,100,115,21,105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103, + 101,10,52,9,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237, + 237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229, + 229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235, + 235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234, + 234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232, + 232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216, + 216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238, + 238,1,252,68,96,1,245,136,152,1,235,229,230,1,232,232,232,1,230,230, + 230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215, + 215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,239,211, + 215,1,249,94,117,1,252,59,88,1,239,175,184,1,230,230,230,1,229,229, + 229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235, + 235,1,240,176,185,1,252,59,88,1,247,92,115,1,232,204,208,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234, + 234,1,233,227,228,1,242,133,149,1,253,45,76,1,241,132,148,1,227,221, + 222,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232, + 232,1,230,230,230,1,232,204,208,1,246,92,115,1,251,58,87,1,233,169, + 178,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216, + 216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,138,220, + 255,1,205,232,243,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230, + 230,1,229,229,229,1,227,227,227,1,234,170,179,1,251,58,87,1,245,90, + 113,1,225,197,201,1,219,219,219,1,218,218,218,1,183,216,229,1,138,220, + 255,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,180,233,255,1,152,224, + 254,1,228,234,237,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229, + 229,1,227,227,227,1,226,226,226,1,225,219,220,1,239,130,146,1,249,65, + 93,1,219,219,219,1,211,218,221,1,160,224,252,1,180,233,255,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,221,245,255,1,146,223,255,1,175,226, + 248,1,255,0,38,1,232,232,232,1,255,0,38,1,229,229,229,1,255,0, + 38,1,226,226,226,1,255,0,38,1,223,223,223,1,255,0,38,1,219,219, + 219,1,194,228,243,1,198,238,255,1,221,245,255,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,248,251,253,1,149,223,255,1,148,223,255,1,255,0, + 38,1,163,228,255,1,255,0,38,1,163,228,255,1,255,0,38,1,163,228, + 255,1,255,0,38,1,163,228,255,1,255,0,38,1,163,228,255,1,225,246, + 255,1,241,250,255,1,248,251,253,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,215,234,243,1,136,214,247,1,143,219,251,1,255,0,38,1,255,255, + 255,1,255,0,38,1,255,255,255,1,255,0,38,1,255,255,255,1,255,0, + 38,1,255,255,255,1,255,0,38,1,255,255,255,1,244,249,251,1,231,243, + 248,1,215,234,243,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,181,217, + 233,1,115,199,235,1,123,205,239,1,255,0,38,1,181,217,233,1,255,0, + 38,1,181,217,233,1,255,0,38,1,181,217,233,1,255,0,38,1,181,217, + 233,1,255,0,38,1,181,217,233,1,210,232,241,1,197,225,238,1,181,217, + 233,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,148,200,223,1,94,185, + 223,1,102,190,227,1,255,0,38,1,109,180,212,1,255,0,38,1,109,180, + 212,1,255,0,38,1,109,180,212,1,255,0,38,1,109,180,212,1,255,0, + 38,1,109,180,212,1,175,214,231,1,163,208,227,1,148,200,223,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,115,184,214,1,74,171,211,1,81,176, + 215,1,255,0,38,1,36,143,190,1,255,0,38,1,36,143,190,1,255,0, + 38,1,36,143,190,1,255,0,38,1,36,143,190,1,255,0,38,1,36,143, + 190,1,141,197,221,1,128,190,217,1,115,184,214,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,82,167,204,1,53,156,199,1,119,185,214,1,255,0, + 38,1,232,232,232,1,255,0,38,1,229,229,229,1,255,0,38,1,226,226, + 226,1,255,0,38,1,223,223,223,1,255,0,38,1,219,219,219,1,144,192, + 214,1,94,173,207,1,82,167,204,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,49,150,194,1,50,150,192,1,219,228,232,1,234,234,234,1,232,232, + 232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,221,221,221,1,219,219,219,1,206,213,217,1,73,160, + 199,1,49,150,194,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,16,133, + 184,1,162,200,217,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230, + 230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,219,219,219,1,218,218,218,1,152,190,206,1,16,133, + 184,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237, + 237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229, + 229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235, + 235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234, + 234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232, + 232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216, + 216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,6,111,110,115,104,111,119,7,15,116,104,114,101,97,100,115,102,111, + 111,110,115,104,111,119,15,109,111,100,117,108,101,99,108,97,115,115,110,97, + 109,101,6,9,116,100,111,99,107,102,111,114,109,0,11,116,115,116,114,105, + 110,103,103,114,105,100,4,103,114,105,100,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119, + 95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,9,112,111,112,117,112,109,101,110,117,7, + 11,116,112,111,112,117,112,109,101,110,117,49,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,83,1,9,98,111,117,110,100,115,95,99,121,3,20,1, + 7,97,110,99,104,111,114,115,11,0,11,111,112,116,105,111,110,115,103,114, + 105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,19,111,103,95, + 102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,20,111,103,95, + 99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103, + 95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117, + 112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,3,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99,111,95,114, + 101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,0,20,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115, + 101,100,105,116,11,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110, + 20,115,99,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,1,7, + 111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,0,9,116,101,120, + 116,102,108,97,103,115,11,8,116,102,95,114,105,103,104,116,12,116,102,95, + 121,99,101,110,116,101,114,101,100,0,15,116,101,120,116,102,108,97,103,115, + 97,99,116,105,118,101,11,8,116,102,95,114,105,103,104,116,12,116,102,95, + 121,99,101,110,116,101,114,101,100,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,14,115, + 99,111,101,95,101,97,116,114,101,116,117,114,110,17,115,99,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,15,115,99,111,101,95,97,117,116, + 111,115,101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,20,115,99,111,101, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,10,118,97, + 108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117, + 101,6,1,49,0,1,5,119,105,100,116,104,2,56,7,111,112,116,105,111, + 110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,0,9,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121, + 99,101,110,116,101,114,101,100,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,14,115,99, + 111,101,95,101,97,116,114,101,116,117,114,110,17,115,99,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,15,115,99,111,101,95,97,117,116,111, + 115,101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,20,115,99,111,101,95, + 104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,10,118,97,108, + 117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101, + 6,1,49,0,1,5,119,105,100,116,104,3,201,0,7,111,112,116,105,111, + 110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110, + 100,111,111,110,101,115,99,14,115,99,111,101,95,101,97,116,114,101,116,117, + 114,110,17,115,99,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 15,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,20,115,99,111,101,95,104,105,110,116,99,108,105,112,112,101, + 100,116,101,120,116,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48, + 9,118,97,108,117,101,116,114,117,101,6,1,49,0,0,13,102,105,120,99, + 111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46, + 105,116,101,109,115,14,1,5,119,105,100,116,104,2,24,8,110,117,109,115, + 116,97,114,116,2,1,7,110,117,109,115,116,101,112,2,1,0,0,13,102, + 105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111, + 119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,15,14, + 99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,3,14,99,97,112, + 116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111, + 110,6,2,73,68,0,1,7,99,97,112,116,105,111,110,6,5,83,116,97, + 116,101,0,1,7,99,97,112,116,105,111,110,6,8,76,111,99,97,116,105, + 111,110,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,0,0,0,0,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,15,11,111,110,99,101,108,108,101,118,101,110,116,7, + 15,103,114,105,100,111,110,99,101,108,108,101,118,101,110,116,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,13,0,0,10,116,112,111,112,117, + 112,109,101,110,117,11,116,112,111,112,117,112,109,101,110,117,49,18,109,101, + 110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,1,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7, + 99,97,112,116,105,111,110,6,17,67,111,112,121,32,116,111,32,67,108,105, + 112,98,111,97,114,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,18, + 99,111,112,121,116,111,99,108,105,112,98,111,97,114,100,101,120,101,0,0, + 4,108,101,102,116,2,88,3,116,111,112,3,144,0,0,0,16,116,115,116, + 114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116,114,105, + 110,103,115,46,100,97,116,97,1,6,8,42,97,99,116,105,118,101,42,6, + 7,117,110,107,110,111,119,110,0,4,108,101,102,116,2,72,3,116,111,112, + 2,72,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tthreadsfo,''); +end. diff --git a/mseide-msegui/apps/ide/toolhandlermodule.mfm b/mseide-msegui/apps/ide/toolhandlermodule.mfm new file mode 100644 index 0000000..b7b32c1 --- /dev/null +++ b/mseide-msegui/apps/ide/toolhandlermodule.mfm @@ -0,0 +1,14 @@ +object toolhandlermo: ttoolhandlermo + bounds_cx = 100 + bounds_cy = 100 + left = 100 + top = 100 + moduleclassname = 'tmsedatamodule' + object proc: tmseprocess + options = [pro_output, pro_erroroutput] + output.oninputavailable = inputavailexe + onprocfinished = procfinishedexe + left = 8 + top = 8 + end +end diff --git a/mseide-msegui/apps/ide/toolhandlermodule.pas b/mseide-msegui/apps/ide/toolhandlermodule.pas new file mode 100644 index 0000000..74db181 --- /dev/null +++ b/mseide-msegui/apps/ide/toolhandlermodule.pas @@ -0,0 +1,66 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit toolhandlermodule; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseapplication,mseclasses,msedatamodules,msepipestream, + mseprocess,mseprocutils,msetypes,msestrings; + +type + ttoolhandlermo = class(tmsedatamodule) + proc: tmseprocess; + procedure inputavailexe(const sender: tpipereader); + procedure procfinishedexe(const sender: TObject); + public + constructor create(const aowner: tcomponent; const acommandline: msestring; + const aoptions: execoptionsty); reintroduce; + end; + +implementation +uses + toolhandlermodule_mfm,make,messageform; + +procedure ttoolhandlermo.inputavailexe(const sender: tpipereader); +begin + addmessagetext(sender,nil); +end; + +procedure ttoolhandlermo.procfinishedexe(const sender: TObject); +begin + release; +end; + +constructor ttoolhandlermo.create(const aowner: tcomponent; + const acommandline: msestring; const aoptions: execoptionsty); +var + opt1: processoptionsty; +begin + inherited create(aowner); + name:= ''; + proc.commandline:= acommandline; + opt1:= [pro_tty,pro_output,pro_errorouttoout]; + if exo_inactive in aoptions then begin + include(opt1,pro_inactive); + end; + proc.options:= opt1; + messagefo.messages.clear; + proc.active:= true; + messagefo.activate; +end; + +end. diff --git a/mseide-msegui/apps/ide/toolhandlermodule_mfm.pas b/mseide-msegui/apps/ide/toolhandlermodule_mfm.pas new file mode 100644 index 0000000..80d6758 --- /dev/null +++ b/mseide-msegui/apps/ide/toolhandlermodule_mfm.pas @@ -0,0 +1,30 @@ +unit toolhandlermodule_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,toolhandlermodule; + +const + objdata: record size: integer; data: array[0..243] of byte end = + (size: 244; data: ( + 84,80,70,48,14,116,116,111,111,108,104,97,110,100,108,101,114,109,111,13, + 116,111,111,108,104,97,110,100,108,101,114,109,111,9,98,111,117,110,100,115, + 95,99,120,2,100,9,98,111,117,110,100,115,95,99,121,2,100,4,108,101, + 102,116,2,100,3,116,111,112,2,100,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,14,116,109,115,101,100,97,116,97,109,111,100,117, + 108,101,0,11,116,109,115,101,112,114,111,99,101,115,115,4,112,114,111,99, + 7,111,112,116,105,111,110,115,11,10,112,114,111,95,111,117,116,112,117,116, + 15,112,114,111,95,101,114,114,111,114,111,117,116,112,117,116,0,23,111,117, + 116,112,117,116,46,111,110,105,110,112,117,116,97,118,97,105,108,97,98,108, + 101,7,13,105,110,112,117,116,97,118,97,105,108,101,120,101,14,111,110,112, + 114,111,99,102,105,110,105,115,104,101,100,7,15,112,114,111,99,102,105,110, + 105,115,104,101,100,101,120,101,4,108,101,102,116,2,8,3,116,111,112,2, + 8,0,0,0) + ); + +initialization + registerobjectdata(@objdata,ttoolhandlermo,''); +end. diff --git a/mseide-msegui/apps/ide/watchform.mfm b/mseide-msegui/apps/ide/watchform.mfm new file mode 100644 index 0000000..07525f7 --- /dev/null +++ b/mseide-msegui/apps/ide/watchform.mfm @@ -0,0 +1,434 @@ +object watchfo: twatchfo + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_destroywidgets] + frame.localprops = [frl_optionsskin] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 291 + bounds_y = 247 + bounds_cx = 310 + bounds_cy = 245 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.color = -2147483645 + container.frame.localprops = [frl_optionsskin] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 300 + 245 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Watches' + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_proportional, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Watches' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 00000000020000001800000018000000CC020000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D0607C7C7C19D9D9D916 + FFFFFF017C7C7C01D9D9D903C8C8C801A1A1A101D9D9D905A6A6A601C2C2C201 + D9D9D904D2D2D2019A9A9A01D9D9D904FFFFFF017C7C7C01D9D9D9024E4E4E01 + 0D0D0D011818180296969601D9D9D901B8B8B8011E1E1E01161616010E0E0E01 + 36363601D9D9D9026A6A6A010F0F0F011C1C1C011111110177777701D9D9D902 + FFFFFF017C7C7C01D9D9D901B6B6B60108080801BFBFBF01D9D9D90152525201 + 30303001D9D9D9014F4F4F0139393901D9D9D901CCCCCC01121212018A8A8A01 + D2D2D2010E0E0E0197979701D9D9D9017979790117171701D9D9D902FFFFFF01 + 7C7C7C01D9D9D9019C9C9C0169696901D9D9D9029F9F9F010E0E0E01D9D9D901 + 63636301A1A1A101D9D9D9023C3C3C0151515101B5B5B50156565601D9D9D902 + D2D2D20102020201C2C2C201D9D9D901FFFFFF017C7C7C01D9D9D90533333301 + 3C3C3C01D9D9D904ABABAB010B0B0B0196969601D9D9D904535353011F1F1F01 + D9D9D902FFFFFF017C7C7C01D9D9D9044E4E4E011A1A1A01CCCCCC01D9D9D903 + C2C2C201131313015E5E5E01D9D9D904717171010E0E0E01B4B4B401D9D9D902 + FFFFFF017C7C7C01D9D9D903B9B9B90109090901B9B9B901D9D9D9044F4F4F01 + 38383801D9D9D9050D0D0D0195959501D9D9D903FFFFFF017C7C7C01D9D9D903 + 8B8B8B0127272701D9D9D9053535350175757501D9D9D904BCBCBC0110101001 + D9D9D904FFFFFF017C7C7C01D9D9D903D2D2D201C5C5C501D9D9D905C7C7C701 + CFCFCF01D9D9D904D5D5D501C2C2C201D9D9D904FFFFFF017C7C7C01D9D9D903 + 6F6F6F0114141401D9D9D9051F1F1F015D5D5D01D9D9D9049C9C9C0100000001 + D5D5D501D9D9D903FFFFFF017C7C7C01D9D9D903B9B9B90192929201D9D9D905 + 99999901B2B2B201D9D9D904C8C8C80186868601D9D9D904FFFFFF017C7C7C01 + D9D9D916FFFFFF017C7C7C01D9D9D916FFFFFF017C7C7C01FFFFFF17D0D0D060 + 00000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000000000000000000000000000 + } + moduleclassname = 'tdockform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [frl_optionsskin] + frame.localprops1 = [] + taborder = 1 + popupmenu = gripopup + bounds_x = 0 + bounds_y = 24 + bounds_cx = 300 + bounds_cy = 221 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 20 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 6 + captions.items = < + item + caption = 'A' + hint = 'Active' + end + item + caption = 'Expression' + hint = 'Expressions starting with # are treated as gdb commands' + end + item + caption = 'Result' + end + item + caption = 'F' + hint = 'Display format'#10'B = Binary'#10'D = Decimal signed'#10'U = Decimal unsigned'#10'H = Hex' + end + item + end + item + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612729 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datacols.count = 5 + datacols.items = < + item[watchon] + width = 13 + options = [co_drawfocus, co_fixwidth, co_savevalue, co_savestate] + widgetname = 'watchon' + dataclass = tgridintegerdatalist + end + item[expression] + width = 152 + options = [co_savevalue, co_savestate] + options1 = [co1_rowcolor, co1_zebracolor] + widgetname = 'expression' + dataclass = tgridmsestringdatalist + end + item[expresult] + width = 80 + options = [co_fill] + widthmin = 50 + oncellevent = resultcellevent + widgetname = 'expresult' + dataclass = tgridmsestringdatalist + end + item[formatcode] + color = -2147483646 + coloractive = -1879048185 + width = 12 + options = [co_fixwidth, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'formatcode' + dataclass = tgridintegerdatalist + end + item[sizecode] + width = 13 + options = [co_invisible, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'sizecode' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + statfile = mainfo.projectstatfile + reffontheight = 14 + object watchon: tbooleanedit + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + statfile = mainfo.projectstatfile + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + ondataentered = expressionondataentered + visible = False + value = True + valuedefault = True + end + object expression: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 14 + bounds_y = 0 + bounds_cx = 152 + bounds_cy = 16 + statfile = mainfo.projectstatfile + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = expressionondataentered + reffontheight = 14 + end + object expresult: tstringedit + optionswidget1 = [ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 167 + bounds_y = 0 + bounds_cx = 80 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + textflags = [tf_ycentered, tf_noselect, tf_ellipseright] + onsetvalue = expresultonsetvalue + end + object formatcode: tdatabutton + taborder = 4 + bounds_x = 248 + bounds_y = 0 + bounds_cx = 12 + bounds_cy = 16 + ondataentered = formatent + state = [as_invisible, as_localimagelist] + imagelist = timagelist1 + focusrectdist = 0 + imagenums.count = 5 + imagenums.items = ( + -1 + 0 + 1 + 2 + 3 + ) + value = 0 + valuedefault = 0 + min = 0 + max = 4 + end + object sizecode: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 5 + visible = False + bounds_x = 261 + bounds_y = 0 + bounds_cx = 13 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + end + object watcheson: tbooleanedit + frame.caption = 'Watches &on' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 77 + 2 + ) + bounds_x = 8 + bounds_y = 4 + bounds_cx = 90 + bounds_cy = 16 + statfile = mainfo.projectstatfile + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + onchange = watchesononchange + onsetvalue = watchesononsetvalue + value = True + end + object gripopup: tpopupmenu + onupdate = popupdate + menu.submenu.count = 21 + menu.submenu.items = < + item + caption = 'Delete all' + state = [as_localcaption, as_localonexecute] + onexecute = deletallexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Add Watchpoint' + state = [as_localcaption, as_localonexecute] + onexecute = addwatchpoint + end + item + caption = 'Address Watchpoint 8' + state = [as_localcaption, as_localonexecute] + onexecute = addresswatch + end + item + caption = 'Address Watchpoint 16' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 1 + onexecute = addresswatch + end + item + caption = 'Address Watchpoint 32' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 2 + onexecute = addresswatch + end + item + caption = 'Address Watchpoint 64' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 3 + onexecute = addresswatch + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Format default' + name = 'format' + state = [as_localchecked, as_localcaption, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + onexecute = formatexecute + end + item + caption = '&Binary' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 1 + onexecute = formatexecute + end + item + caption = 'D&ecimal signed' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 2 + onexecute = formatexecute + end + item + caption = 'Decimal &unsigned' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 3 + onexecute = formatexecute + end + item + caption = '&Hex' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 4 + onexecute = formatexecute + end + item + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_separator, mao_shortcutcaption] + tag = 4 + end + item + caption = '&Size default' + name = 'size' + state = [as_checked, as_localchecked, as_localcaption, as_localgroup, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + group = 1 + onexecute = sizeexecute + end + item + caption = '&8 Bit' + state = [as_localcaption, as_localtag, as_localgroup, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 1 + group = 1 + onexecute = sizeexecute + end + item + caption = '&16 Bit' + state = [as_localcaption, as_localtag, as_localgroup, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 2 + group = 1 + onexecute = sizeexecute + end + item + caption = '&32 Bit' + state = [as_localcaption, as_localtag, as_localgroup, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 3 + group = 1 + onexecute = sizeexecute + end + item + caption = '&64 Bit' + name = '&64 Bit' + state = [as_localcaption, as_localtag, as_localgroup, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 4 + group = 1 + onexecute = sizeexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Reset Formats' + state = [as_localcaption, as_localonexecute] + onexecute = resetformats + end> + menu.name = 'gridpopup' + menu.state = [as_localonexecute] + menu.onexecute = deletallexecute + left = 96 + top = 112 + end + object timagelist1: timagelist + width = 10 + height = 18 + count = 4 + left = 96 + top = 152 + image = { + 00000000020000001400000024000000CC010000000000000000000000000000 + 0000000000000000000000000000000000000000FFFFFF6700000003FFFFFF07 + 00000003FFFFFF0700000001FFFFFF0200000001FFFFFF0600000001FFFFFF02 + 00000001FFFFFF0600000001FFFFFF0200000001FFFFFF0600000001FFFFFF02 + 00000001FFFFFF0600000003FFFFFF0700000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000003FFFFFF0700000003FFFFFFCF00000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000004FFFFFF0600000001FFFFFF0200000001FFFFFF0600000001FFFFFF02 + 00000001FFFFFF0600000001FFFFFF0200000001FFFFFF0600000001FFFFFF02 + 00000001FFFFFF0700000002FFFFFF0700000001FFFFFF0200000001FFFFFF67 + 000010080000D0BF00009008000000000000900838E08005482001C048200100 + 38209108482001004820D1BF4820110838E09008000020080000D0BF00000008 + 000000000000900800008005000000C000000000000090080000000048201108 + 48209108482091084820D1BF48E0010848200100482081053020014000000000 + 00000000000000000000000000000000 + } + end + object c: tstringcontainer + strings.data = ( + 'Do you wish to delete all watches?' + 'Confirmation' + '' + ) + left = 96 + top = 80 + end +end diff --git a/mseide-msegui/apps/ide/watchform.pas b/mseide-msegui/apps/ide/watchform.pas new file mode 100644 index 0000000..9f4c50c --- /dev/null +++ b/mseide-msegui/apps/ide/watchform.pas @@ -0,0 +1,336 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit watchform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + mseforms,msedataedits,msewidgetgrid,msegdbutils,msegraphedits,msedock,msegrids, + msegui,msestrings,msemenus,mseedit,mseevent,msetypes,msegraphics,msebitmap, + msestringcontainer; + +type + twatchfo = class(tdockform) + grid: twidgetgrid; + expression: tstringedit; + expresult: tstringedit; + gripopup: tpopupmenu; + watchon: tbooleanedit; + watcheson: tbooleanedit; + sizecode: tintegeredit; + formatcode: tdatabutton; + timagelist1: timagelist; + c: tstringcontainer; + procedure expressionondataentered(const sender: tobject); + procedure expresultonsetvalue(const sender: tobject; var avalue: msestring; var accept: boolean); + procedure resultcellevent(const sender: TObject; var info: celleventinfoty); + procedure watchesononchange(const sender: TObject); + procedure watchesononsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure deletallexecute(const sender: TObject); + procedure formatexecute(const sender: TObject); + procedure popupdate(const sender: tcustommenu); + procedure sizeexecute(const sender: TObject); + procedure addwatchpoint(const sender: TObject); + procedure addresswatch(const sender: TObject); + procedure formatent(const sender: TObject); + procedure resetformats(const sender: TObject); + public + gdb: tgdbmi; + procedure clear(const all: boolean = false); + procedure refresh; + function refreshitem(const index: integer): boolean; //true if no timeout + procedure addwatch(aexpression: msestring); + end; + +var + watchfo: twatchfo; + + +implementation +uses + watchform_mfm,main,msewidgets,projectoptionsform,actionsmodule,msegraphutils, + mseguiglob,mseformatstr,msebits,sysutils,watchpointsform,memoryform; +type + stringconstants = ( + deleteall, //0 Do you wish to delete all watches? + confirmation, //1 Confirmation + disabled //2 + ); + + numformatty = (nf_default,nf_bin,nf_decs,nf_decu,nf_hex); + numsizety = (ns_default,ns_8,ns_16,ns_32,ns_64); + +{ twatchfo } + +procedure twatchfo.watchesononsetvalue(const sender: TObject; var avalue: Boolean; var accept: Boolean); +begin + actionsmo.watchesonact.checked:= avalue; +end; + +procedure twatchfo.resultcellevent(const sender: TObject; var info: celleventinfoty); +//var +// rect1: rectty; +begin +{ + with info,expresult do begin + if (eventkind = cek_firstmousepark) and textclipped(cell.row,rect1) then begin + inc(rect1.cy,12); + application.showhint(grid,gridvalue[cell.row],rect1,cp_bottomleft,-1); + end; + end; + } +end; + +procedure twatchfo.watchesononchange(const sender: TObject); +begin + projectoptions.modified:= true; + refresh; +end; + +procedure twatchfo.expressionondataentered(const sender: tobject); +begin + projectoptions.modified:= true; + refreshitem(grid.row); +end; + +procedure twatchfo.clear(const all: boolean = false); +begin + if all then begin + grid.clear; + end + else begin + expresult.fillcol(''); + end; +end; + +function twatchfo.refreshitem(const index: integer): boolean; +var + mstr1,mstr2: msestring; + str1: ansistring; + fc: numformatty; + fs: numsizety; + int641: int64; + int2: integer; +begin + result:= true; + if (index >= 0) and gdb.cancommand then begin + if watcheson.value and watchon[index] then begin + mstr2:= expression[index]; + if (mstr2 <> '') and (mstr2[1] = '#') then begin + result:= gdb.executecommand(ansistring( + copy(mstr2,2,bigint)),str1) <> gdb_timeout; + mstr1:= msestring(str1); + end + else begin + result:= gdb.readpascalvariable(ansistring(mstr2),mstr1) <> gdb_timeout; + end; + fc:= numformatty(formatcode[index]); + if fc <> nf_default then begin + if trystrtointvalue64(ansistring(mstr1),qword(int641)) then begin + int2:= highestbit64(int641); + if int2 <= 0 then begin + int2:= 1; + end; + fs:= numsizety(sizecode[index]); + case fc of + nf_bin: begin + int2:= int2+1; //bitcount + case fs of + ns_8: int2:= 8; + ns_16: int2:= 16; + ns_32: int2:= 32; + ns_64: int2:= 64; + end; + mstr1:= '%'+msestring(bintostr(qword(int641),int2)); + end; + nf_decs: begin + case fs of + ns_8: mstr1:= inttostrmse(shortint(int641)); + ns_16: mstr1:= inttostrmse(smallint(int641)); + ns_32: mstr1:= inttostrmse(integer(int641)); + else mstr1:= inttostrmse(int641); + end; + end; + nf_decu: begin + mstr1:= inttostrmse(qword(int641)); + end; + nf_hex: begin + int2:= int2 div 4 + 1; //nibble count + case fs of + ns_8: int2:= 2; + ns_16: int2:= 4; + ns_32: int2:= 8; + ns_64: int2:= 16; + end; + mstr1:= '0x'+hextostrmse(qword(int641),int2); + end; + end; + end; + end; + if (expresult[index] <> mstr1) then begin + grid.rowfontstate[index]:= 0; + end + else begin + grid.rowfontstate[index]:= -1; + end; + expresult[index]:= removelinebreaks(mstr1); + end + else begin + grid.rowfontstate[index]:= -1; + expresult[index]:= c[ord(disabled)]; + end; + end + else begin + expresult[index]:= ''; + end; +end; + +procedure twatchfo.refresh; +var + int1: integer; + bo1: boolean; +begin + bo1:= true; + for int1:= 0 to grid.rowcount -1 do begin + bo1:= bo1 and refreshitem(int1); + if not bo1 then begin + expresult[int1]:= ''; + end; + end; + memoryfo.refresh; +end; + +procedure twatchfo.expresultonsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +var + str1: string; +begin + gdb.interrupttarget; + accept:= gdb.writepascalvariable(ansistring(expression.value), + ansistring(avalue),str1) = gdb_ok; + if accept then begin + refresh; + avalue:= msestring(str1); + end + else begin + showerror(msestring(str1)); + tstringedit(sender).editor.undo; + end; + gdb.restarttarget; +end; + +procedure twatchfo.addwatch(aexpression: msestring); +var + int1: integer; +begin + int1:= grid.appendrow; + expression[int1]:= aexpression; + if gdb.cancommand then begin + refreshitem(int1); + end; +end; + +procedure twatchfo.deletallexecute(const sender: TObject); +begin + if askok(c[ord(deleteall)],c[ord(confirmation)]) then begin + grid.clear; + end; +end; + +procedure twatchfo.formatexecute(const sender: TObject); +var + int1: integer; +begin + with tmenuitem(sender) do begin + int1:= checkedtag; + if formatcode.value <> int1 then begin + formatcode.value:= int1; + refreshitem(grid.row); + end; + end; +end; + +procedure twatchfo.formatent(const sender: TObject); +begin + sizecode.value:= 0; //ns_default + refreshitem(grid.row); +end; + +procedure twatchfo.resetformats(const sender: TObject); +begin + formatcode.fillcol(0); + sizecode.fillcol(0); + refresh; +end; + + +procedure twatchfo.sizeexecute(const sender: TObject); +var + int1: integer; +begin + with tmenuitem(sender) do begin + int1:= checkedtag; + if sizecode.value <> int1 then begin + sizecode.value:= int1; + refreshitem(grid.row); + end; + end; +end; + +procedure twatchfo.popupdate(const sender: tcustommenu); +begin + sender.menu.itembyname('format').checkedtag:= formatcode.value; + sender.menu.itembyname('size').checkedtag:= sizecode.value; +end; + +procedure twatchfo.addwatchpoint(const sender: TObject); +begin + watchpointsfo.addwatch(expression.value); +end; + +procedure twatchfo.addresswatch(const sender: TObject); +//todo: make language independent +var + str1: ansistring; +begin + if gdb.symboladdress(ansistring(expression.value),str1) = gdb_ok then begin + str1:= '('+str1+'^)'; + case tmenuitem(sender).tag of + 0: begin + str1:= 'byte'+str1; + end; + 1: begin + str1:= 'word'+str1; + end; + 2: begin + str1:= 'longword'+str1; + end; + 3: begin + str1:= 'qword'+str1; + end; + end; + watchpointsfo.addwatch(msestring(str1)); + end + else begin + showerror(msestring(str1)); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/watchform_mfm.pas b/mseide-msegui/apps/ide/watchform_mfm.pas new file mode 100644 index 0000000..d543e20 --- /dev/null +++ b/mseide-msegui/apps/ide/watchform_mfm.pas @@ -0,0 +1,509 @@ +unit watchform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,watchform; + +const + objdata: record size: integer; data: array[0..9838] of byte end = + (size: 9839; data: ( + 84,80,70,48,8,116,119,97,116,99,104,102,111,7,119,97,116,99,104,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,15,102,114,108,95,111,112,116,105, + 111,110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95, + 115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112, + 116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111, + 110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103, + 111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112, + 98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100, + 98,117,116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116, + 111,110,14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,35,1,8, + 98,111,117,110,100,115,95,121,3,247,0,9,98,111,117,110,100,115,95,99, + 120,3,54,1,9,98,111,117,110,100,115,95,99,121,3,245,0,23,99,111, + 110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111, + 117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,15,99,111,110,116,97,105, + 110,101,114,46,99,111,108,111,114,4,3,0,0,128,26,99,111,110,116,97, + 105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0,27, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46, + 98,111,117,110,100,115,1,2,0,2,0,3,44,1,3,245,0,0,22,100, + 114,97,103,100,111,99,107,46,115,112,108,105,116,116,101,114,95,115,105,122, + 101,2,0,16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111,110, + 6,7,87,97,116,99,104,101,115,20,100,114,97,103,100,111,99,107,46,111, + 112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112, + 111,115,10,111,100,95,99,97,110,109,111,118,101,11,111,100,95,99,97,110, + 102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107,15,111,100,95, + 112,114,111,112,111,114,116,105,111,110,97,108,11,111,100,95,112,114,111,112, + 115,105,122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,13, + 111,100,95,99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105,111, + 110,115,11,10,102,111,95,115,97,118,101,112,111,115,12,102,111,95,115,97, + 118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,22,109, + 97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108, + 101,7,99,97,112,116,105,111,110,6,7,87,97,116,99,104,101,115,21,105, + 99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,12,105,99,111,110,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,0,10,105,99,111,110,46,105,109,97, + 103,101,10,96,3,0,0,0,0,0,0,2,0,0,0,24,0,0,0,24, + 0,0,0,204,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208, + 208,208,96,124,124,124,25,217,217,217,22,255,255,255,1,124,124,124,1,217, + 217,217,3,200,200,200,1,161,161,161,1,217,217,217,5,166,166,166,1,194, + 194,194,1,217,217,217,4,210,210,210,1,154,154,154,1,217,217,217,4,255, + 255,255,1,124,124,124,1,217,217,217,2,78,78,78,1,13,13,13,1,24, + 24,24,2,150,150,150,1,217,217,217,1,184,184,184,1,30,30,30,1,22, + 22,22,1,14,14,14,1,54,54,54,1,217,217,217,2,106,106,106,1,15, + 15,15,1,28,28,28,1,17,17,17,1,119,119,119,1,217,217,217,2,255, + 255,255,1,124,124,124,1,217,217,217,1,182,182,182,1,8,8,8,1,191, + 191,191,1,217,217,217,1,82,82,82,1,48,48,48,1,217,217,217,1,79, + 79,79,1,57,57,57,1,217,217,217,1,204,204,204,1,18,18,18,1,138, + 138,138,1,210,210,210,1,14,14,14,1,151,151,151,1,217,217,217,1,121, + 121,121,1,23,23,23,1,217,217,217,2,255,255,255,1,124,124,124,1,217, + 217,217,1,156,156,156,1,105,105,105,1,217,217,217,2,159,159,159,1,14, + 14,14,1,217,217,217,1,99,99,99,1,161,161,161,1,217,217,217,2,60, + 60,60,1,81,81,81,1,181,181,181,1,86,86,86,1,217,217,217,2,210, + 210,210,1,2,2,2,1,194,194,194,1,217,217,217,1,255,255,255,1,124, + 124,124,1,217,217,217,5,51,51,51,1,60,60,60,1,217,217,217,4,171, + 171,171,1,11,11,11,1,150,150,150,1,217,217,217,4,83,83,83,1,31, + 31,31,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217,217,4,78, + 78,78,1,26,26,26,1,204,204,204,1,217,217,217,3,194,194,194,1,19, + 19,19,1,94,94,94,1,217,217,217,4,113,113,113,1,14,14,14,1,180, + 180,180,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217,217,3,185, + 185,185,1,9,9,9,1,185,185,185,1,217,217,217,4,79,79,79,1,56, + 56,56,1,217,217,217,5,13,13,13,1,149,149,149,1,217,217,217,3,255, + 255,255,1,124,124,124,1,217,217,217,3,139,139,139,1,39,39,39,1,217, + 217,217,5,53,53,53,1,117,117,117,1,217,217,217,4,188,188,188,1,16, + 16,16,1,217,217,217,4,255,255,255,1,124,124,124,1,217,217,217,3,210, + 210,210,1,197,197,197,1,217,217,217,5,199,199,199,1,207,207,207,1,217, + 217,217,4,213,213,213,1,194,194,194,1,217,217,217,4,255,255,255,1,124, + 124,124,1,217,217,217,3,111,111,111,1,20,20,20,1,217,217,217,5,31, + 31,31,1,93,93,93,1,217,217,217,4,156,156,156,1,0,0,0,1,213, + 213,213,1,217,217,217,3,255,255,255,1,124,124,124,1,217,217,217,3,185, + 185,185,1,146,146,146,1,217,217,217,5,153,153,153,1,178,178,178,1,217, + 217,217,4,200,200,200,1,134,134,134,1,217,217,217,4,255,255,255,1,124, + 124,124,1,217,217,217,22,255,255,255,1,124,124,124,1,217,217,217,22,255, + 255,255,1,124,124,124,1,255,255,255,23,208,208,208,96,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,255,255,255,0,255, + 255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255, + 255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255, + 255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,11, + 116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101, + 115,99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105, + 110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,1,9,112,111,112,117,112,109,101,110, + 117,7,8,103,114,105,112,111,112,117,112,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110,100,115, + 95,99,120,3,44,1,9,98,111,117,110,100,115,95,99,121,3,221,0,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98, + 111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12, + 111,103,95,99,111,108,115,105,122,105,110,103,12,111,103,95,114,111,119,109, + 111,118,105,110,103,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110, + 103,15,111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103, + 95,114,111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117, + 115,99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111, + 102,105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101, + 110,100,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46,99,111,117,110, + 116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5, + 119,105,100,116,104,2,20,8,110,117,109,115,116,97,114,116,2,1,7,110, + 117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115,46,99, + 111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115, + 14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115, + 46,99,111,117,110,116,2,6,14,99,97,112,116,105,111,110,115,46,105,116, + 101,109,115,14,1,7,99,97,112,116,105,111,110,6,1,65,4,104,105,110, + 116,6,6,65,99,116,105,118,101,0,1,7,99,97,112,116,105,111,110,6, + 10,69,120,112,114,101,115,115,105,111,110,4,104,105,110,116,6,55,69,120, + 112,114,101,115,115,105,111,110,115,32,115,116,97,114,116,105,110,103,32,119, + 105,116,104,32,35,32,97,114,101,32,116,114,101,97,116,101,100,32,97,115, + 32,103,100,98,32,99,111,109,109,97,110,100,115,0,1,7,99,97,112,116, + 105,111,110,6,6,82,101,115,117,108,116,0,1,7,99,97,112,116,105,111, + 110,6,1,70,4,104,105,110,116,6,73,68,105,115,112,108,97,121,32,102, + 111,114,109,97,116,10,66,32,61,32,66,105,110,97,114,121,10,68,32,61, + 32,68,101,99,105,109,97,108,32,115,105,103,110,101,100,10,85,32,61,32, + 68,101,99,105,109,97,108,32,117,110,115,105,103,110,101,100,10,72,32,61, + 32,72,101,120,0,1,0,1,0,0,0,0,14,114,111,119,102,111,110,116, + 115,46,99,111,117,110,116,2,1,14,114,111,119,102,111,110,116,115,46,105, + 116,101,109,115,14,1,5,99,111,108,111,114,4,7,0,0,160,4,110,97, + 109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99,97, + 108,101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112, + 95,99,111,108,111,114,10,102,108,112,95,120,115,99,97,108,101,0,0,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,5,14,100,97, + 116,97,99,111,108,115,46,105,116,101,109,115,14,7,7,119,97,116,99,104, + 111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11, + 12,99,111,95,100,114,97,119,102,111,99,117,115,11,99,111,95,102,105,120, + 119,105,100,116,104,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110, + 97,109,101,6,7,119,97,116,99,104,111,110,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,10,101,120,112,114,101,115,115,105,111,110,1,5,119, + 105,100,116,104,3,152,0,7,111,112,116,105,111,110,115,11,12,99,111,95, + 115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97, + 116,101,0,8,111,112,116,105,111,110,115,49,11,12,99,111,49,95,114,111, + 119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111, + 114,0,10,119,105,100,103,101,116,110,97,109,101,6,10,101,120,112,114,101, + 115,115,105,111,110,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114, + 105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0, + 7,9,101,120,112,114,101,115,117,108,116,1,5,119,105,100,116,104,2,80, + 7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,0,8,119, + 105,100,116,104,109,105,110,2,50,11,111,110,99,101,108,108,101,118,101,110, + 116,7,15,114,101,115,117,108,116,99,101,108,108,101,118,101,110,116,10,119, + 105,100,103,101,116,110,97,109,101,6,9,101,120,112,114,101,115,117,108,116, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,102,111,114, + 109,97,116,99,111,100,101,1,5,99,111,108,111,114,4,2,0,0,128,11, + 99,111,108,111,114,97,99,116,105,118,101,4,7,0,0,144,5,119,105,100, + 116,104,2,12,7,111,112,116,105,111,110,115,11,11,99,111,95,102,105,120, + 119,105,100,116,104,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,10,102,111,114,109,97,116,99,111,100,101,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,8,115,105,122,101,99,111,100,101,1,5,119,105, + 100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,105,110, + 118,105,115,105,98,108,101,12,99,111,95,115,97,118,101,118,97,108,117,101, + 12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,8,115,105,122,101,99,111,100,101,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104, + 116,2,16,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,7,119,97,116,99,104,111,110,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105, + 108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116, + 97,116,102,105,108,101,11,111,112,116,105,111,110,115,101,100,105,116,11,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112, + 117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116, + 101,13,111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,0,13,111,110,100,97,116,97,101,110,116, + 101,114,101,100,7,23,101,120,112,114,101,115,115,105,111,110,111,110,100,97, + 116,97,101,110,116,101,114,101,100,7,118,105,115,105,98,108,101,8,5,118, + 97,108,117,101,9,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0, + 0,11,116,115,116,114,105,110,103,101,100,105,116,10,101,120,112,114,101,115, + 115,105,111,110,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,14,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,152,0, + 9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108, + 101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97, + 116,102,105,108,101,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,24,111,101,95,102,111,114,99,101,114,101,116,117,114, + 110,99,104,101,99,107,118,97,108,117,101,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,111,110,100,97, + 116,97,101,110,116,101,114,101,100,7,23,101,120,112,114,101,115,115,105,111, + 110,111,110,100,97,116,97,101,110,116,101,114,101,100,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103, + 101,100,105,116,9,101,120,112,114,101,115,117,108,116,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111,115, + 99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,3,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,167,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 80,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121, + 99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116, + 15,116,102,95,101,108,108,105,112,115,101,114,105,103,104,116,0,10,111,110, + 115,101,116,118,97,108,117,101,7,19,101,120,112,114,101,115,117,108,116,111, + 110,115,101,116,118,97,108,117,101,0,0,11,116,100,97,116,97,98,117,116, + 116,111,110,10,102,111,114,109,97,116,99,111,100,101,8,116,97,98,111,114, + 100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,248,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,12, + 9,98,111,117,110,100,115,95,99,121,2,16,13,111,110,100,97,116,97,101, + 110,116,101,114,101,100,7,9,102,111,114,109,97,116,101,110,116,5,115,116, + 97,116,101,11,12,97,115,95,105,110,118,105,115,105,98,108,101,17,97,115, + 95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,0,9,105,109,97, + 103,101,108,105,115,116,7,11,116,105,109,97,103,101,108,105,115,116,49,13, + 102,111,99,117,115,114,101,99,116,100,105,115,116,2,0,15,105,109,97,103, + 101,110,117,109,115,46,99,111,117,110,116,2,5,15,105,109,97,103,101,110, + 117,109,115,46,105,116,101,109,115,1,2,255,2,0,2,1,2,2,2,3, + 0,5,118,97,108,117,101,2,0,12,118,97,108,117,101,100,101,102,97,117, + 108,116,2,0,3,109,105,110,2,0,3,109,97,120,2,4,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,8,115,105,122,101,99,111,100,101, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,5,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,5,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 13,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,119,97,116,99,104, + 101,115,111,110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11, + 87,97,116,99,104,101,115,32,38,111,110,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,1,2,77,2,2,0,8,98,111, + 117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,4,9, + 98,111,117,110,100,115,95,99,120,2,90,9,98,111,117,110,100,115,95,99, + 121,2,16,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,8,111,110,99,104,97,110,103,101,7,17,119,97,116,99,104, + 101,115,111,110,111,110,99,104,97,110,103,101,10,111,110,115,101,116,118,97, + 108,117,101,7,19,119,97,116,99,104,101,115,111,110,111,110,115,101,116,118, + 97,108,117,101,5,118,97,108,117,101,9,0,0,10,116,112,111,112,117,112, + 109,101,110,117,8,103,114,105,112,111,112,117,112,8,111,110,117,112,100,97, + 116,101,7,9,112,111,112,117,112,100,97,116,101,18,109,101,110,117,46,115, + 117,98,109,101,110,117,46,99,111,117,110,116,2,21,18,109,101,110,117,46, + 115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97,112,116, + 105,111,110,6,10,68,101,108,101,116,101,32,97,108,108,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110, + 101,120,101,99,117,116,101,7,15,100,101,108,101,116,97,108,108,101,120,101, + 99,117,116,101,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95, + 115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99, + 117,116,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110, + 6,14,65,100,100,32,87,97,116,99,104,112,111,105,110,116,5,115,116,97, + 116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111, + 110,101,120,101,99,117,116,101,7,13,97,100,100,119,97,116,99,104,112,111, + 105,110,116,0,1,7,99,97,112,116,105,111,110,6,20,65,100,100,114,101, + 115,115,32,87,97,116,99,104,112,111,105,110,116,32,56,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110, + 101,120,101,99,117,116,101,7,12,97,100,100,114,101,115,115,119,97,116,99, + 104,0,1,7,99,97,112,116,105,111,110,6,21,65,100,100,114,101,115,115, + 32,87,97,116,99,104,112,111,105,110,116,32,49,54,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115, + 95,108,111,99,97,108,116,97,103,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,3,116,97,103,2,1,9,111,110,101,120,101, + 99,117,116,101,7,12,97,100,100,114,101,115,115,119,97,116,99,104,0,1, + 7,99,97,112,116,105,111,110,6,21,65,100,100,114,101,115,115,32,87,97, + 116,99,104,112,111,105,110,116,32,51,50,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111, + 99,97,108,116,97,103,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,3,116,97,103,2,2,9,111,110,101,120,101,99,117,116, + 101,7,12,97,100,100,114,101,115,115,119,97,116,99,104,0,1,7,99,97, + 112,116,105,111,110,6,21,65,100,100,114,101,115,115,32,87,97,116,99,104, + 112,111,105,110,116,32,54,52,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108, + 116,97,103,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,3,116,97,103,2,3,9,111,110,101,120,101,99,117,116,101,7,12, + 97,100,100,114,101,115,115,119,97,116,99,104,0,1,7,111,112,116,105,111, + 110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97, + 111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1, + 7,99,97,112,116,105,111,110,6,15,38,70,111,114,109,97,116,32,100,101, + 102,97,117,108,116,4,110,97,109,101,6,6,102,111,114,109,97,116,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,104,101,99,107,101, + 100,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112,116, + 105,111,110,115,11,15,109,97,111,95,114,97,100,105,111,98,117,116,116,111, + 110,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,9,111,110,101,120,101,99,117,116,101,7,13,102,111,114,109,97,116, + 101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,7,38, + 66,105,110,97,114,121,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97, + 103,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,111,112,116,105,111,110,115,11,15,109,97,111,95,114,97,100,105,111,98, + 117,116,116,111,110,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,0,3,116,97,103,2,1,9,111,110,101,120,101,99,117, + 116,101,7,13,102,111,114,109,97,116,101,120,101,99,117,116,101,0,1,7, + 99,97,112,116,105,111,110,6,15,68,38,101,99,105,109,97,108,32,115,105, + 103,110,101,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111, + 112,116,105,111,110,115,11,15,109,97,111,95,114,97,100,105,111,98,117,116, + 116,111,110,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116, + 105,111,110,0,3,116,97,103,2,2,9,111,110,101,120,101,99,117,116,101, + 7,13,102,111,114,109,97,116,101,120,101,99,117,116,101,0,1,7,99,97, + 112,116,105,111,110,6,17,68,101,99,105,109,97,108,32,38,117,110,115,105, + 103,110,101,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111, + 112,116,105,111,110,115,11,15,109,97,111,95,114,97,100,105,111,98,117,116, + 116,111,110,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116, + 105,111,110,0,3,116,97,103,2,3,9,111,110,101,120,101,99,117,116,101, + 7,13,102,111,114,109,97,116,101,120,101,99,117,116,101,0,1,7,99,97, + 112,116,105,111,110,6,4,38,72,101,120,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111, + 99,97,108,116,97,103,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,7,111,112,116,105,111,110,115,11,15,109,97,111,95,114, + 97,100,105,111,98,117,116,116,111,110,19,109,97,111,95,115,104,111,114,116, + 99,117,116,99,97,112,116,105,111,110,0,3,116,97,103,2,4,9,111,110, + 101,120,101,99,117,116,101,7,13,102,111,114,109,97,116,101,120,101,99,117, + 116,101,0,1,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,3,116,97,103,2,4,0,1,7,99,97,112,116,105,111,110,6,13, + 38,83,105,122,101,32,100,101,102,97,117,108,116,4,110,97,109,101,6,4, + 115,105,122,101,5,115,116,97,116,101,11,10,97,115,95,99,104,101,99,107, + 101,100,15,97,115,95,108,111,99,97,108,99,104,101,99,107,101,100,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,13,97,115,95,108,111, + 99,97,108,103,114,111,117,112,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,15,109,97,111, + 95,114,97,100,105,111,98,117,116,116,111,110,19,109,97,111,95,115,104,111, + 114,116,99,117,116,99,97,112,116,105,111,110,0,5,103,114,111,117,112,2, + 1,9,111,110,101,120,101,99,117,116,101,7,11,115,105,122,101,101,120,101, + 99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,6,38,56,32,66, + 105,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,13,97,115, + 95,108,111,99,97,108,103,114,111,117,112,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,15, + 109,97,111,95,114,97,100,105,111,98,117,116,116,111,110,19,109,97,111,95, + 115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,3,116,97,103, + 2,1,5,103,114,111,117,112,2,1,9,111,110,101,120,101,99,117,116,101, + 7,11,115,105,122,101,101,120,101,99,117,116,101,0,1,7,99,97,112,116, + 105,111,110,6,7,38,49,54,32,66,105,116,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108, + 111,99,97,108,116,97,103,13,97,115,95,108,111,99,97,108,103,114,111,117, + 112,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,111,112,116,105,111,110,115,11,15,109,97,111,95,114,97,100,105,111,98, + 117,116,116,111,110,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,0,3,116,97,103,2,2,5,103,114,111,117,112,2,1, + 9,111,110,101,120,101,99,117,116,101,7,11,115,105,122,101,101,120,101,99, + 117,116,101,0,1,7,99,97,112,116,105,111,110,6,7,38,51,50,32,66, + 105,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,13,97,115, + 95,108,111,99,97,108,103,114,111,117,112,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,15, + 109,97,111,95,114,97,100,105,111,98,117,116,116,111,110,19,109,97,111,95, + 115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,3,116,97,103, + 2,3,5,103,114,111,117,112,2,1,9,111,110,101,120,101,99,117,116,101, + 7,11,115,105,122,101,101,120,101,99,117,116,101,0,1,7,99,97,112,116, + 105,111,110,6,7,38,54,52,32,66,105,116,4,110,97,109,101,6,7,38, + 54,52,32,66,105,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97, + 103,13,97,115,95,108,111,99,97,108,103,114,111,117,112,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111, + 110,115,11,15,109,97,111,95,114,97,100,105,111,98,117,116,116,111,110,19, + 109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0, + 3,116,97,103,2,4,5,103,114,111,117,112,2,1,9,111,110,101,120,101, + 99,117,116,101,7,11,115,105,122,101,101,120,101,99,117,116,101,0,1,7, + 111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116, + 111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105, + 111,110,0,0,1,7,99,97,112,116,105,111,110,6,14,38,82,101,115,101, + 116,32,70,111,114,109,97,116,115,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116, + 101,7,12,114,101,115,101,116,102,111,114,109,97,116,115,0,0,9,109,101, + 110,117,46,110,97,109,101,6,9,103,114,105,100,112,111,112,117,112,10,109, + 101,110,117,46,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,14,109,101,110,117,46,111,110,101,120,101, + 99,117,116,101,7,15,100,101,108,101,116,97,108,108,101,120,101,99,117,116, + 101,4,108,101,102,116,2,96,3,116,111,112,2,112,0,0,10,116,105,109, + 97,103,101,108,105,115,116,11,116,105,109,97,103,101,108,105,115,116,49,5, + 119,105,100,116,104,2,10,6,104,101,105,103,104,116,2,18,5,99,111,117, + 110,116,2,4,4,108,101,102,116,2,96,3,116,111,112,3,152,0,5,105, + 109,97,103,101,10,144,2,0,0,0,0,0,0,2,0,0,0,20,0,0, + 0,36,0,0,0,204,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,255,255,103,0,0,0,3,255,255,255,7,0,0,0,3,255,255,255, + 7,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0, + 1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,3,255,255,255,7,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255, + 6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0, + 1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,3,255,255,255,7,0,0,0,3,255,255,255, + 207,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0, + 1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255, + 6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0, + 1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,4,255,255,255,6,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255, + 6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,7,0,0,0, + 2,255,255,255,7,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255, + 103,0,0,16,8,0,0,208,191,0,0,144,8,0,0,0,0,0,0,144, + 8,56,224,128,5,72,32,1,192,72,32,1,0,56,32,145,8,72,32,1, + 0,72,32,209,191,72,32,17,8,56,224,144,8,0,0,32,8,0,0,208, + 191,0,0,0,8,0,0,0,0,0,0,144,8,0,0,128,5,0,0,0, + 192,0,0,0,0,0,0,144,8,0,0,0,0,72,32,17,8,72,32,145, + 8,72,32,145,8,72,32,209,191,72,224,1,8,72,32,1,0,72,32,129, + 5,48,32,1,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97, + 105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1, + 6,34,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,100,101,108, + 101,116,101,32,97,108,108,32,119,97,116,99,104,101,115,63,6,12,67,111, + 110,102,105,114,109,97,116,105,111,110,6,10,60,100,105,115,97,98,108,101, + 100,62,0,4,108,101,102,116,2,96,3,116,111,112,2,80,0,0,0) + ); + +initialization + registerobjectdata(@objdata,twatchfo,''); +end. diff --git a/mseide-msegui/apps/ide/watchpointsform.mfm b/mseide-msegui/apps/ide/watchpointsform.mfm new file mode 100644 index 0000000..6d1036a --- /dev/null +++ b/mseide-msegui/apps/ide/watchpointsform.mfm @@ -0,0 +1,353 @@ +object watchpointsfo: twatchpointsfo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 120 + bounds_y = 368 + bounds_cx = 483 + bounds_cy = 210 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 473 + 210 + ) + dragdock.caption = 'Watchpoints' + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Watchpoints' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000078070000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01D6D6D6016868680137373701 + 16161601181818013939390165656501CACACA01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB019F9F9F010F0F0F01000000060D0D0D01 + 8B8B8B01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01C5C5C5010A0A0A01 + 000000011B1B1C017D7D9E018181E0017F7FDD017C7C9D011C1C1D0100000001 + 04040401AAAAAA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED014141410100000001 + 06060C010606DD010000FF040606EA010A0A1601000000012A2A2A01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01E5E5E5010606070100000001000077010000FF0600008D01 + 0000000101010201CCCCCC01D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01C5C5CB010B0B460100002A01 + 0000C5010000FF060000B10100000002A8A8AE01D6D6D601D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE017373F601 + 0000FF0900007A0100000001000016013636B801C9C9C901D4D4D401D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001E9E9EE010707FE01 + 0000FF080000C70100000B010000000100005F010303FA0186868B01D2D2D201 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001C0C0F101 + 0000FF080000D1010000110100000001000031010000F1010000FF0151518201 + B0B0B001D2D2D202D0D0D001F5F5F501F3F3F301F2F2F201F0F0F0019090F501 + 0000FF070000CC010000120100000001000022010000E8010000FF023C3CA101 + 91919101D1D1D101D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001 + 9090F5010000FF060000E20100000F010000000100001C010000DC010000FF03 + 3B3BA0017A7A7A01D1D1D101D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001C0C0F1010000FF060000560100000001000018010000DB010000FF04 + 4E4E7F016A6A6A01D0D0D001D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001E9E9EE010707FE010000FF040000FC01000007010000000100009601 + 0000FF040303FA01606065017A7A7A01D1D1D101D2D2D201D0D0D001F5F5F501 + F3F3F301F2F2F201F0F0F001EEEEEE017272F5010000FF040000D80100000002 + 0000D5010000FF042F2FB2016363630191919101D1D1D101D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01E6E6EC012121F4010000FF03 + 0000BE01000008020000ED010000FF031111E4015F5F650164646401B0B0B001 + D2D2D202D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01 + C2C2EB011A1AED010000FF081111E40152527B016363630189898901D2D2D201 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EAEAEA01D5D5DB013A3ABD010303FA010000FF040303FA013131B401 + 616167016464640170707001C9C9C901D4D4D401D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01E9E9E901 + D9D9D9018F8F940134345201020205010202040139395B016363680165656502 + 8A8A8A01CACACA01D6D6D601D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501 + F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E7E7E701 + E3E3E30170707001000000024D4D4D018080800196969601B5B5B501D7D7D703 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001 + EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E6019E9E9E0138383801 + 37373701A9A9A901DCDCDC01DBDBDB01DADADA02D8D8D801D7D7D701D5D5D501 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201 + E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201 + E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501 + D3D3D301D2D2D201D0D0D001 + } + onshow = watchpointsonshow + moduleclassname = 'tdockform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + popupmenu = gripopup + bounds_x = 0 + bounds_y = 0 + bounds_cx = 473 + bounds_cy = 210 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 20 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 7 + captions.items = < + item + caption = 'on' + end + item + caption = 'Kind' + end + item + caption = 'Expression' + end + item + end + item + caption = 'Count' + end + item + caption = 'Ignore' + end + item + caption = 'Condition' + end> + end> + datacols.count = 7 + datacols.items = < + item[wpton] + width = 16 + options = [co_drawfocus, co_fixwidth, co_savestate] + widgetname = 'wpton' + dataclass = tgridintegerdatalist + end + item[wptkind] + width = 33 + options = [co_savevalue, co_savestate] + widgetname = 'wptkind' + dataclass = tgridenumdatalist + end + item[wptexpression] + width = 149 + options = [co_proportional, co_savevalue, co_savestate] + widgetname = 'wptexpression' + dataclass = tgridmsestringdatalist + end + item[wptno] + width = 9 + options = [co_invisible] + widgetname = 'wptno' + dataclass = tgridintegerdatalist + end + item[wptcount] + color = -1879048185 + width = 34 + options = [co_readonly, co_nofocus, co_savestate] + widgetname = 'wptcount' + dataclass = tgridintegerdatalist + end + item[wptignore] + width = 38 + options = [co_savevalue, co_savestate] + widgetname = 'wptignore' + dataclass = tgridintegerdatalist + end + item[wptcondition] + width = 162 + options = [co_fill, co_savevalue, co_savestate] + widgetname = 'wptcondition' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = mainfo.projectstatfile + onrowsdeleting = deleterow + reffontheight = 14 + object wpton: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 16 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + onsetvalue = wptononsetvalue + end + object wptkind: tenumedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + taborder = 2 + visible = False + bounds_x = 17 + bounds_y = 0 + bounds_cx = 33 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + ondataentered = wptondataentered + dropdown.cols.count = 1 + dropdown.cols.items = < + item + data = ( + 'W' + 'R/W' + 'R' + ) + end> + value = 0 + valuedefault = 0 + valuemin = 0 + valuemax = 2 + reffontheight = 14 + end + object wptexpression: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 3 + visible = False + bounds_x = 51 + bounds_y = 0 + bounds_cx = 149 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = wptondataentered + reffontheight = 14 + end + object wptno: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 4 + visible = False + bounds_x = 201 + bounds_y = 0 + bounds_cx = 9 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object wptcount: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 5 + visible = False + bounds_x = 211 + bounds_y = 0 + bounds_cx = 34 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object wptignore: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 6 + visible = False + bounds_x = 246 + bounds_y = 0 + bounds_cx = 38 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + ondataentered = wptondataentered + reffontheight = 14 + end + object wptcondition: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 7 + visible = False + bounds_x = 285 + bounds_y = 0 + bounds_cx = 162 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = wptondataentered + reffontheight = 14 + end + end + object gripopup: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Delete all' + state = [as_localcaption, as_localonexecute] + onexecute = deleteallonexecute + end> + menu.name = 'gridpopup' + left = 112 + top = 88 + end + object c: tstringcontainer + strings.data = ( + 'Watchpoint error.' + 'WATCHPOINT ERROR' + 'Program not loaded.' + 'Do you wish to delete all watchpoints?' + 'Confirmation' + ) + left = 216 + top = 88 + end +end diff --git a/mseide-msegui/apps/ide/watchpointsform.pas b/mseide-msegui/apps/ide/watchpointsform.pas new file mode 100644 index 0000000..4adcc91 --- /dev/null +++ b/mseide-msegui/apps/ide/watchpointsform.pas @@ -0,0 +1,210 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit watchpointsform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msegui,mseclasses,mseforms,msedataedits,msegraphedits,msewidgetgrid, + msestat, + msegdbutils,msesimplewidgets,msemenus,msestrings,msegrids,msestringcontainer; + +type + twatchpointsfo = class(tdockform) + gripopup: tpopupmenu; + wptkind: tenumedit; + wptno: tintegeredit; + wptcondition: tstringedit; + wptignore: tintegeredit; + wptcount: tintegeredit; + wptexpression: tstringedit; + wpton: tbooleanedit; + grid: twidgetgrid; + c: tstringcontainer; + procedure wptondataentered(const sender: TObject); + procedure wptononsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure watchpointsonshow(const sender: TObject); + procedure deleteallonexecute(const sender: TObject); + procedure deleterow(const sender: tcustomgrid; var aindex: Integer; + var acount: Integer); + private + procedure changed; + function watchpointerror(const error: gdbresultty): boolean; + public + gdb: tgdbmi; + procedure refresh(const breakpoints: breakpointinfoarty); + procedure clear(const all: boolean = false); + procedure addwatch(const expression: msestring); + end; + +var + watchpointsfo: twatchpointsfo; + +implementation + +uses + watchpointsform_mfm,projectoptionsform,msewidgets,breakpointsform; +type + stringconstants = ( + watcherror, //0 Watchpoint error. + watcherror2, //1 WATCHPOINT ERROR + programnotloaded, //2 Program not loaded. + deleteall, //3 Do you wish to delete all watchpoints? + confirmation //4 Confirmation + ); + +{ twatchpointsfo } + +procedure twatchpointsfo.refresh(const breakpoints: breakpointinfoarty); +var + int1,int2: integer; +begin + for int1:= 0 to grid.rowhigh do begin + wptcount[int1]:= 0; + for int2:= 0 to high(breakpoints) do begin + with breakpoints[int2] do begin + if bkptno = wptno[int1] then begin + wptcount[int1]:= passcount; + end; + end; + end; + end; +end; + +procedure twatchpointsfo.clear(const all: boolean); +begin + if all then begin + grid.clear; + end + else begin + wpton.fillcol(false); + end; +end; + +procedure twatchpointsfo.changed; +begin + with projectoptions do begin + modified:= true; +// watchpointexpressions:= wptexpression.gridvalues; +// watchpointignore:= wptignore.gridvalues; +// watchpointconditions:= wptcondition.gridvalues; +// watchpointkinds:= wptkind.gridvalues; + end; +end; + +function twatchpointsfo.watchpointerror(const error: gdbresultty): boolean; +var + str1: msestring; +begin + result:= error <> gdb_ok; + if result then begin + if error in [gdb_message,gdb_timeout] then begin + str1:= msestring(gdb.errormessage); + end + else begin + str1:= c[ord(watcherror)]; + end; + showmessage(str1,c[ord(watcherror2)]); + end; +end; + +procedure twatchpointsfo.wptondataentered(const sender: TObject); +begin + changed; + wpton.value:= false; + if gdb.started then begin + wpton.checkvalue; + end; +end; + +procedure twatchpointsfo.watchpointsonshow(const sender: TObject); +begin + breakpointsfo.refresh; +end; + +procedure twatchpointsfo.wptononsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +var + info: watchpointinfoty; +begin + if gdb.started then begin + if avalue then begin + with info do begin + kind:= watchpointkindty(wptkind.value); + expression:= ansistring(wptexpression.value); + ignore:= wptignore.value; + condition:= ansistring(wptcondition.value); + end; + if watchpointerror(gdb.watchinsert(info)) then begin + avalue:= false; + wptno.value:= 0; + end + else begin + wptno.value:= info.wptno; + end; + end + else begin + if wptno.value <> 0 then begin + gdb.breakdelete(wptno.value); + wptno.value:= 0; + end; + end; + end + else begin + showerror(c[ord(programnotloaded)]); + end; +end; + +procedure twatchpointsfo.deleteallonexecute(const sender: TObject); +var + int1,int2: integer; +begin + if askok(c[ord(deleteall)],c[ord(confirmation)]) then begin + int1:= 0; + int2:= grid.rowcount; + deleterow(nil,int1,int2); + grid.clear; + end; +end; + +procedure twatchpointsfo.addwatch(const expression: msestring); +begin + grid.show; + grid.setfocus(false); + if not grid.datacols.rowempty(grid.row) then begin + grid.row:= grid.appendrow; + end; + wptexpression.value:= expression; + wpton.value:= true; + wpton.checkvalue; +end; + +procedure twatchpointsfo.deleterow(const sender: tcustomgrid; + var aindex: Integer; var acount: Integer); +var + int1: integer; +begin + for int1:= aindex to aindex + acount - 1 do begin + if wptno[int1] <> 0 then begin + gdb.breakdelete(wptno[int1]); + end; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/watchpointsform_mfm.pas b/mseide-msegui/apps/ide/watchpointsform_mfm.pas new file mode 100644 index 0000000..e424ee4 --- /dev/null +++ b/mseide-msegui/apps/ide/watchpointsform_mfm.pas @@ -0,0 +1,440 @@ +unit watchpointsform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,watchpointsform; + +const + objdata: record size: integer; data: array[0..8448] of byte end = + (size: 8449; data: ( + 84,80,70,48,14,116,119,97,116,99,104,112,111,105,110,116,115,102,111,13, + 119,97,116,99,104,112,111,105,110,116,115,102,111,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103, + 114,105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105, + 112,95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98, + 117,116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116, + 111,110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111, + 95,116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114, + 111,117,110,100,98,117,116,116,111,110,15,103,111,95,110,111,108,111,99,107, + 98,117,116,116,111,110,14,103,111,95,98,117,116,116,111,110,104,105,110,116, + 115,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 2,120,8,98,111,117,110,100,115,95,121,3,112,1,9,98,111,117,110,100, + 115,95,99,120,3,227,1,9,98,111,117,110,100,115,95,99,121,3,210,0, + 26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2, + 0,3,217,1,3,210,0,0,16,100,114,97,103,100,111,99,107,46,99,97, + 112,116,105,111,110,6,11,87,97,116,99,104,112,111,105,110,116,115,20,100, + 114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111,99,107,11, + 10,111,100,95,115,97,118,101,112,111,115,10,111,100,95,99,97,110,109,111, + 118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100,95,99,97, + 110,100,111,99,107,11,111,100,95,112,114,111,112,115,105,122,101,14,111,100, + 95,99,97,112,116,105,111,110,104,105,110,116,0,7,111,112,116,105,111,110, + 115,11,10,102,111,95,115,97,118,101,112,111,115,12,102,111,95,115,97,118, + 101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,22,109,97, + 105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101, + 7,99,97,112,116,105,111,110,6,11,87,97,116,99,104,112,111,105,110,116, + 115,21,105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103,101,10, + 172,7,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 120,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1, + 214,214,214,1,104,104,104,1,55,55,55,1,22,22,22,1,24,24,24,1, + 57,57,57,1,101,101,101,1,202,202,202,1,219,219,219,1,218,218,218,1, + 216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,159,159,159,1,15,15,15,1, + 0,0,0,6,13,13,13,1,139,139,139,1,218,218,218,1,216,216,216,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,197,197,197,1,10,10,10,1,0,0,0,1,27,27,28,1, + 125,125,158,1,129,129,224,1,127,127,221,1,124,124,157,1,28,28,29,1, + 0,0,0,1,4,4,4,1,170,170,170,1,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 65,65,65,1,0,0,0,1,6,6,12,1,6,6,221,1,0,0,255,4, + 6,6,234,1,10,10,22,1,0,0,0,1,42,42,42,1,216,216,216,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 229,229,229,1,6,6,7,1,0,0,0,1,0,0,119,1,0,0,255,6, + 0,0,141,1,0,0,0,1,1,1,2,1,204,204,204,1,215,215,215,1, + 213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,197,197,203,1, + 11,11,70,1,0,0,42,1,0,0,197,1,0,0,255,6,0,0,177,1, + 0,0,0,2,168,168,174,1,214,214,214,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,115,115,246,1,0,0,255,9,0,0,122,1, + 0,0,0,1,0,0,22,1,54,54,184,1,201,201,201,1,212,212,212,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,233,233,238,1,7,7,254,1,0,0,255,8, + 0,0,199,1,0,0,11,1,0,0,0,1,0,0,95,1,3,3,250,1, + 134,134,139,1,210,210,210,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,192,192,241,1, + 0,0,255,8,0,0,209,1,0,0,17,1,0,0,0,1,0,0,49,1, + 0,0,241,1,0,0,255,1,81,81,130,1,176,176,176,1,210,210,210,2, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 144,144,245,1,0,0,255,7,0,0,204,1,0,0,18,1,0,0,0,1, + 0,0,34,1,0,0,232,1,0,0,255,2,60,60,161,1,145,145,145,1, + 209,209,209,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,144,144,245,1,0,0,255,6,0,0,226,1, + 0,0,15,1,0,0,0,1,0,0,28,1,0,0,220,1,0,0,255,3, + 59,59,160,1,122,122,122,1,209,209,209,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,192,192,241,1, + 0,0,255,6,0,0,86,1,0,0,0,1,0,0,24,1,0,0,219,1, + 0,0,255,4,78,78,127,1,106,106,106,1,208,208,208,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 233,233,238,1,7,7,254,1,0,0,255,4,0,0,252,1,0,0,7,1, + 0,0,0,1,0,0,150,1,0,0,255,4,3,3,250,1,96,96,101,1, + 122,122,122,1,209,209,209,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,114,114,245,1, + 0,0,255,4,0,0,216,1,0,0,0,2,0,0,213,1,0,0,255,4, + 47,47,178,1,99,99,99,1,145,145,145,1,209,209,209,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,230,230,236,1,33,33,244,1,0,0,255,3,0,0,190,1, + 0,0,8,2,0,0,237,1,0,0,255,3,17,17,228,1,95,95,101,1, + 100,100,100,1,176,176,176,1,210,210,210,2,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 194,194,235,1,26,26,237,1,0,0,255,8,17,17,228,1,82,82,123,1, + 99,99,99,1,137,137,137,1,210,210,210,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,234,234,234,1,213,213,219,1,58,58,189,1, + 3,3,250,1,0,0,255,4,3,3,250,1,49,49,180,1,97,97,103,1, + 100,100,100,1,112,112,112,1,201,201,201,1,212,212,212,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,233,233,233,1, + 217,217,217,1,143,143,148,1,52,52,82,1,2,2,5,1,2,2,4,1, + 57,57,91,1,99,99,104,1,101,101,101,2,138,138,138,1,202,202,202,1, + 214,214,214,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,231,231,231,1,227,227,227,1, + 112,112,112,1,0,0,0,2,77,77,77,1,128,128,128,1,150,150,150,1, + 181,181,181,1,215,215,215,3,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1, + 230,230,230,1,158,158,158,1,56,56,56,1,55,55,55,1,169,169,169,1, + 220,220,220,1,219,219,219,1,218,218,218,2,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,6,111,110,115,104,111,119,7,17,119,97,116, + 99,104,112,111,105,110,116,115,111,110,115,104,111,119,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114, + 109,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107, + 111,110,101,115,99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,9,112,111, + 112,117,112,109,101,110,117,7,8,103,114,105,112,111,112,117,112,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,217,1,9,98,111,117,110,100,115,95, + 99,121,3,210,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111, + 112,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115, + 103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12,111, + 103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110, + 115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105, + 110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116, + 101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111, + 103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99, + 104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97, + 112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103, + 95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120, + 99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115, + 46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,20,8,110,117,109, + 115,116,97,114,116,2,1,7,110,117,109,115,116,101,112,2,1,0,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16, + 14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,7,14,99,97, + 112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105, + 111,110,6,2,111,110,0,1,7,99,97,112,116,105,111,110,6,4,75,105, + 110,100,0,1,7,99,97,112,116,105,111,110,6,10,69,120,112,114,101,115, + 115,105,111,110,0,1,0,1,7,99,97,112,116,105,111,110,6,5,67,111, + 117,110,116,0,1,7,99,97,112,116,105,111,110,6,6,73,103,110,111,114, + 101,0,1,7,99,97,112,116,105,111,110,6,9,67,111,110,100,105,116,105, + 111,110,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110, + 116,2,7,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7, + 5,119,112,116,111,110,1,5,119,105,100,116,104,2,16,7,111,112,116,105, + 111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,11,99,111, + 95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97, + 116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,5,119,112,116,111, + 110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110, + 116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,119,112,116,107, + 105,110,100,1,5,119,105,100,116,104,2,33,7,111,112,116,105,111,110,115, + 11,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97, + 118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110,97,109,101,6, + 7,119,112,116,107,105,110,100,9,100,97,116,97,99,108,97,115,115,7,17, + 116,103,114,105,100,101,110,117,109,100,97,116,97,108,105,115,116,0,7,13, + 119,112,116,101,120,112,114,101,115,115,105,111,110,1,5,119,105,100,116,104, + 3,149,0,7,111,112,116,105,111,110,115,11,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103, + 101,116,110,97,109,101,6,13,119,112,116,101,120,112,114,101,115,115,105,111, + 110,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,5,119,112, + 116,110,111,1,5,119,105,100,116,104,2,9,7,111,112,116,105,111,110,115, + 11,12,99,111,95,105,110,118,105,115,105,98,108,101,0,10,119,105,100,103, + 101,116,110,97,109,101,6,5,119,112,116,110,111,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,8,119,112,116,99,111,117,110,116,1,5,99,111, + 108,111,114,4,7,0,0,144,5,119,105,100,116,104,2,34,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,10,99,111, + 95,110,111,102,111,99,117,115,12,99,111,95,115,97,118,101,115,116,97,116, + 101,0,10,119,105,100,103,101,116,110,97,109,101,6,8,119,112,116,99,111, + 117,110,116,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,9,119,112, + 116,105,103,110,111,114,101,1,5,119,105,100,116,104,2,38,7,111,112,116, + 105,111,110,115,11,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110, + 97,109,101,6,9,119,112,116,105,103,110,111,114,101,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,12,119,112,116,99,111,110,100,105,116,105,111, + 110,1,5,119,105,100,116,104,3,162,0,7,111,112,116,105,111,110,115,11, + 7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103, + 101,116,110,97,109,101,6,12,119,112,116,99,111,110,100,105,116,105,111,110, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116, + 97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105,108, + 101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97, + 116,102,105,108,101,14,111,110,114,111,119,115,100,101,108,101,116,105,110,103, + 7,9,100,101,108,101,116,101,114,111,119,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,5,119,112,116,111,110,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,16,9,98,111,117,110,100,115,95,99,121, + 2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101, + 110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101, + 8,10,111,110,115,101,116,118,97,108,117,101,7,15,119,112,116,111,110,111, + 110,115,101,116,118,97,108,117,101,0,0,9,116,101,110,117,109,101,100,105, + 116,7,119,112,116,107,105,110,100,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,102,114,97,109,101, + 46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,2,0,0,128,0,0,8,116,97,98,111, + 114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,17,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,33,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 115,97,118,101,118,97,108,117,101,0,9,116,101,120,116,102,108,97,103,115, + 11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99, + 101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,0, + 13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,16,119,112,116,111, + 110,100,97,116,97,101,110,116,101,114,101,100,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,4,100,97,116, + 97,1,6,1,87,6,3,82,47,87,6,1,82,0,0,0,5,118,97,108, + 117,101,2,0,12,118,97,108,117,101,100,101,102,97,117,108,116,2,0,8, + 118,97,108,117,101,109,105,110,2,0,8,118,97,108,117,101,109,97,120,2, + 2,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,13,119,112,116,101,120,112,114,101, + 115,115,105,111,110,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0, + 128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,3,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,51,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 149,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108, + 117,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,16,119, + 112,116,111,110,100,97,116,97,101,110,116,101,114,101,100,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,5,119,112,116,110,111,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,4,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,201,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,9,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,8,119,112,116,99, + 111,117,110,116,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,5,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,211,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 34,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,9, + 119,112,116,105,103,110,111,114,101,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,6,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,246,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,2,38,9,98,111,117,110,100,115,95,99,121,2,16,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,24, + 111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118, + 97,108,117,101,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,0,13,111,110,100,97,116,97,101,110,116,101, + 114,101,100,7,16,119,112,116,111,110,100,97,116,97,101,110,116,101,114,101, + 100,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,12,119,112,116,99,111,110,100,105, + 116,105,111,110,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,7,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,29,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 162,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108, + 117,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,16,119, + 112,116,111,110,100,97,116,97,101,110,116,101,114,101,100,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,10,116,112,111,112,117, + 112,109,101,110,117,8,103,114,105,112,111,112,117,112,18,109,101,110,117,46, + 115,117,98,109,101,110,117,46,99,111,117,110,116,2,1,18,109,101,110,117, + 46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97,112, + 116,105,111,110,6,10,68,101,108,101,116,101,32,97,108,108,5,115,116,97, + 116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111, + 110,101,120,101,99,117,116,101,7,18,100,101,108,101,116,101,97,108,108,111, + 110,101,120,101,99,117,116,101,0,0,9,109,101,110,117,46,110,97,109,101, + 6,9,103,114,105,100,112,111,112,117,112,4,108,101,102,116,2,112,3,116, + 111,112,2,88,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97,105, + 110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6, + 17,87,97,116,99,104,112,111,105,110,116,32,101,114,114,111,114,46,6,16, + 87,65,84,67,72,80,79,73,78,84,32,69,82,82,79,82,6,19,80,114, + 111,103,114,97,109,32,110,111,116,32,108,111,97,100,101,100,46,6,38,68, + 111,32,121,111,117,32,119,105,115,104,32,116,111,32,100,101,108,101,116,101, + 32,97,108,108,32,119,97,116,99,104,112,111,105,110,116,115,63,6,12,67, + 111,110,102,105,114,109,97,116,105,111,110,0,4,108,101,102,116,3,216,0, + 3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,twatchpointsfo,''); +end. diff --git a/mseide-msegui/apps/myide/mybutton.pas b/mseide-msegui/apps/myide/mybutton.pas new file mode 100644 index 0000000..261fa71 --- /dev/null +++ b/mseide-msegui/apps/myide/mybutton.pas @@ -0,0 +1,80 @@ +unit mybutton; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msesimplewidgets,mseevent,msegraphics,classes,mclasses,msegraphutils,mseact, + mseguiglob; + +const + defaultcolorclicked = cl_red; + +type + tmybutton = class(tbutton) + private + fcolorclicked: colorty; + procedure setcolorclicked(const avalue: colorty); + protected + procedure checkcolor; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + public + constructor create(aowner: tcomponent); override; + published + property colorclicked: colorty read fcolorclicked + write setcolorclicked default defaultcolorclicked; + end; + +implementation +uses + mseshapes; + +{ tmybutton } + +constructor tmybutton.create(aowner: tcomponent); +begin + fcolorclicked:= defaultcolorclicked; + inherited; +end; + +procedure tmybutton.checkcolor; +begin + with finfo do begin + if shs_clicked in state then begin + color:= fcolorclicked; + end + else begin + color:= self.color; + end; + end; +end; + +procedure tmybutton.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + checkcolor; +end; + +procedure tmybutton.dokeydown(var info: keyeventinfoty); +begin + inherited; + checkcolor; +end; + +procedure tmybutton.dokeyup(var info: keyeventinfoty); +begin + inherited; + checkcolor; +end; + +procedure tmybutton.setcolorclicked(const avalue: colorty); +begin + if fcolorclicked <> avalue then begin + fcolorclicked:= avalue; + checkcolor; + invalidate; + end; +end; + +end. diff --git a/mseide-msegui/apps/myide/mymseide.prj b/mseide-msegui/apps/myide/mymseide.prj new file mode 100644 index 0000000..a2a7780 --- /dev/null +++ b/mseide-msegui/apps/myide/mymseide.prj @@ -0,0 +1,1010 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/myide +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/myide/mymseide.prj +mainfile=../ide/mseide.pas +targetfile=mymseide${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=5 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ + ../ide/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 -FE../myide -FU. -dmorecomponents + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=5 + 196671 + 65599 + 196671 + 65599 + 196671 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=3 + 0,0 + 0,-1073741823 + 0,-1073741823 +bookmarks0=0 +bookmarks1=0 +bookmarks2=0 +sourcefiles=3 + /home/mse/packs/standard/git/mseide-msegui/apps/myide/mybutton.pas + /home/mse/packs/standard/git/mseide-msegui/apps/myide/regcomponents.inc + /home/mse/packs/standard/git/mseide-msegui/apps/myide/regmycomps.pas +relpaths=3 + mybutton.pas + regcomponents.inc + regmycomps.pas +ismoduletexts=3 + 0 + 0 + 0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=121 +firsttab=0 +index=0 +[layout] +windowlayout=544 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=14 + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/myide/regcomponents.inc b/mseide-msegui/apps/myide/regcomponents.inc new file mode 100644 index 0000000..b8778a1 --- /dev/null +++ b/mseide-msegui/apps/myide/regcomponents.inc @@ -0,0 +1 @@ +regmycomps, diff --git a/mseide-msegui/apps/myide/regmycomps.pas b/mseide-msegui/apps/myide/regmycomps.pas new file mode 100644 index 0000000..6be4cc3 --- /dev/null +++ b/mseide-msegui/apps/myide/regmycomps.pas @@ -0,0 +1,17 @@ +unit regmycomps; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + msedesignintf,mybutton; + +procedure register; +begin + registercomponents('My',[tmybutton]); +end; + +initialization + register; +end. diff --git a/mseide-msegui/contributed/README.TXT b/mseide-msegui/contributed/README.TXT new file mode 100644 index 0000000..d001c97 --- /dev/null +++ b/mseide-msegui/contributed/README.TXT @@ -0,0 +1,4 @@ +2007-11-15 mse + +Contributed has been moved to +https://gitlab.com/mseuniverse/mseuniverse/tree/master/attic/msedocumenting/mse/trunk/contributed diff --git a/mseide-msegui/help/README.TXT b/mseide-msegui/help/README.TXT new file mode 100644 index 0000000..458522c --- /dev/null +++ b/mseide-msegui/help/README.TXT @@ -0,0 +1,4 @@ +2007-11-15 mse + +Help has been moved to +https://gitlab.com/mseide-msegui/mseuniverse/tree/master/attic/msedocumenting/mse/trunk/help \ No newline at end of file diff --git a/mseide-msegui/icons/buttons/breakpoint.png b/mseide-msegui/icons/buttons/breakpoint.png new file mode 100644 index 0000000..4aab1b8 Binary files /dev/null and b/mseide-msegui/icons/buttons/breakpoint.png differ diff --git a/mseide-msegui/icons/buttons/breakpoint.svg b/mseide-msegui/icons/buttons/breakpoint.svg new file mode 100644 index 0000000..0423863 --- /dev/null +++ b/mseide-msegui/icons/buttons/breakpoint.svg @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/continue.png b/mseide-msegui/icons/buttons/continue.png new file mode 100644 index 0000000..8a8c92a Binary files /dev/null and b/mseide-msegui/icons/buttons/continue.png differ diff --git a/mseide-msegui/icons/buttons/continue.svg b/mseide-msegui/icons/buttons/continue.svg new file mode 100644 index 0000000..e648de7 --- /dev/null +++ b/mseide-msegui/icons/buttons/continue.svg @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/continuedisab.png b/mseide-msegui/icons/buttons/continuedisab.png new file mode 100644 index 0000000..3b20480 Binary files /dev/null and b/mseide-msegui/icons/buttons/continuedisab.png differ diff --git a/mseide-msegui/icons/buttons/continuedisab.svg b/mseide-msegui/icons/buttons/continuedisab.svg new file mode 100644 index 0000000..68edcd0 --- /dev/null +++ b/mseide-msegui/icons/buttons/continuedisab.svg @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/execline.png b/mseide-msegui/icons/buttons/execline.png new file mode 100644 index 0000000..c93651a Binary files /dev/null and b/mseide-msegui/icons/buttons/execline.png differ diff --git a/mseide-msegui/icons/buttons/execline.svg b/mseide-msegui/icons/buttons/execline.svg new file mode 100644 index 0000000..6e73c0d --- /dev/null +++ b/mseide-msegui/icons/buttons/execline.svg @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/finish.png b/mseide-msegui/icons/buttons/finish.png new file mode 100644 index 0000000..3a8d576 Binary files /dev/null and b/mseide-msegui/icons/buttons/finish.png differ diff --git a/mseide-msegui/icons/buttons/finish.svg b/mseide-msegui/icons/buttons/finish.svg new file mode 100644 index 0000000..70f2c70 --- /dev/null +++ b/mseide-msegui/icons/buttons/finish.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/finishdisab.png b/mseide-msegui/icons/buttons/finishdisab.png new file mode 100644 index 0000000..77a81dd Binary files /dev/null and b/mseide-msegui/icons/buttons/finishdisab.png differ diff --git a/mseide-msegui/icons/buttons/finishdisab.svg b/mseide-msegui/icons/buttons/finishdisab.svg new file mode 100644 index 0000000..f6fc77a --- /dev/null +++ b/mseide-msegui/icons/buttons/finishdisab.svg @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/finishi.png b/mseide-msegui/icons/buttons/finishi.png new file mode 100644 index 0000000..8bd8a42 Binary files /dev/null and b/mseide-msegui/icons/buttons/finishi.png differ diff --git a/mseide-msegui/icons/buttons/finishi.svg b/mseide-msegui/icons/buttons/finishi.svg new file mode 100644 index 0000000..81be10e --- /dev/null +++ b/mseide-msegui/icons/buttons/finishi.svg @@ -0,0 +1,423 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + begin int1:= 2; caption:= 'A';end; + + + + diff --git a/mseide-msegui/icons/buttons/interrupt.png b/mseide-msegui/icons/buttons/interrupt.png new file mode 100644 index 0000000..a7d9be4 Binary files /dev/null and b/mseide-msegui/icons/buttons/interrupt.png differ diff --git a/mseide-msegui/icons/buttons/interrupt.svg b/mseide-msegui/icons/buttons/interrupt.svg new file mode 100644 index 0000000..a0b9c90 --- /dev/null +++ b/mseide-msegui/icons/buttons/interrupt.svg @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/interruptdisab.png b/mseide-msegui/icons/buttons/interruptdisab.png new file mode 100644 index 0000000..f6073c8 Binary files /dev/null and b/mseide-msegui/icons/buttons/interruptdisab.png differ diff --git a/mseide-msegui/icons/buttons/interruptdisab.svg b/mseide-msegui/icons/buttons/interruptdisab.svg new file mode 100644 index 0000000..1f27137 --- /dev/null +++ b/mseide-msegui/icons/buttons/interruptdisab.svg @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/next.png b/mseide-msegui/icons/buttons/next.png new file mode 100644 index 0000000..f16771c Binary files /dev/null and b/mseide-msegui/icons/buttons/next.png differ diff --git a/mseide-msegui/icons/buttons/next.svg b/mseide-msegui/icons/buttons/next.svg new file mode 100644 index 0000000..f79bf6f --- /dev/null +++ b/mseide-msegui/icons/buttons/next.svg @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/nextdisab.png b/mseide-msegui/icons/buttons/nextdisab.png new file mode 100644 index 0000000..fb4abd5 Binary files /dev/null and b/mseide-msegui/icons/buttons/nextdisab.png differ diff --git a/mseide-msegui/icons/buttons/nextdisab.svg b/mseide-msegui/icons/buttons/nextdisab.svg new file mode 100644 index 0000000..035a312 --- /dev/null +++ b/mseide-msegui/icons/buttons/nextdisab.svg @@ -0,0 +1,359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/nexti.png b/mseide-msegui/icons/buttons/nexti.png new file mode 100644 index 0000000..6c53ffb Binary files /dev/null and b/mseide-msegui/icons/buttons/nexti.png differ diff --git a/mseide-msegui/icons/buttons/nexti.svg b/mseide-msegui/icons/buttons/nexti.svg new file mode 100644 index 0000000..df211d9 --- /dev/null +++ b/mseide-msegui/icons/buttons/nexti.svg @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/nextidisab.png b/mseide-msegui/icons/buttons/nextidisab.png new file mode 100644 index 0000000..5a334d9 Binary files /dev/null and b/mseide-msegui/icons/buttons/nextidisab.png differ diff --git a/mseide-msegui/icons/buttons/nextidisab.svg b/mseide-msegui/icons/buttons/nextidisab.svg new file mode 100644 index 0000000..e729708 --- /dev/null +++ b/mseide-msegui/icons/buttons/nextidisab.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + + + + diff --git a/mseide-msegui/icons/buttons/path3846.png b/mseide-msegui/icons/buttons/path3846.png new file mode 100644 index 0000000..92c58c2 Binary files /dev/null and b/mseide-msegui/icons/buttons/path3846.png differ diff --git a/mseide-msegui/icons/buttons/reset.png b/mseide-msegui/icons/buttons/reset.png new file mode 100644 index 0000000..c76f21c Binary files /dev/null and b/mseide-msegui/icons/buttons/reset.png differ diff --git a/mseide-msegui/icons/buttons/reset.svg b/mseide-msegui/icons/buttons/reset.svg new file mode 100644 index 0000000..11d44c7 --- /dev/null +++ b/mseide-msegui/icons/buttons/reset.svg @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/resetdisab.png b/mseide-msegui/icons/buttons/resetdisab.png new file mode 100644 index 0000000..d3edb10 Binary files /dev/null and b/mseide-msegui/icons/buttons/resetdisab.png differ diff --git a/mseide-msegui/icons/buttons/resetdisab.svg b/mseide-msegui/icons/buttons/resetdisab.svg new file mode 100644 index 0000000..18d9af8 --- /dev/null +++ b/mseide-msegui/icons/buttons/resetdisab.svg @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/step.png b/mseide-msegui/icons/buttons/step.png new file mode 100644 index 0000000..d97c569 Binary files /dev/null and b/mseide-msegui/icons/buttons/step.png differ diff --git a/mseide-msegui/icons/buttons/step.svg b/mseide-msegui/icons/buttons/step.svg new file mode 100644 index 0000000..7235ea7 --- /dev/null +++ b/mseide-msegui/icons/buttons/step.svg @@ -0,0 +1,475 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/stepdisab.png b/mseide-msegui/icons/buttons/stepdisab.png new file mode 100644 index 0000000..70b7aeb Binary files /dev/null and b/mseide-msegui/icons/buttons/stepdisab.png differ diff --git a/mseide-msegui/icons/buttons/stepdisab.svg b/mseide-msegui/icons/buttons/stepdisab.svg new file mode 100644 index 0000000..996a372 --- /dev/null +++ b/mseide-msegui/icons/buttons/stepdisab.svg @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/stepi.png b/mseide-msegui/icons/buttons/stepi.png new file mode 100644 index 0000000..fb22f4f Binary files /dev/null and b/mseide-msegui/icons/buttons/stepi.png differ diff --git a/mseide-msegui/icons/buttons/stepi.svg b/mseide-msegui/icons/buttons/stepi.svg new file mode 100644 index 0000000..9f5262d --- /dev/null +++ b/mseide-msegui/icons/buttons/stepi.svg @@ -0,0 +1,475 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/stepidisab.png b/mseide-msegui/icons/buttons/stepidisab.png new file mode 100644 index 0000000..eb61795 Binary files /dev/null and b/mseide-msegui/icons/buttons/stepidisab.png differ diff --git a/mseide-msegui/icons/buttons/stepidisab.svg b/mseide-msegui/icons/buttons/stepidisab.svg new file mode 100644 index 0000000..1374fa2 --- /dev/null +++ b/mseide-msegui/icons/buttons/stepidisab.svg @@ -0,0 +1,372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + + begin int1:= 2; caption:= 'A';end; + + + diff --git a/mseide-msegui/icons/buttons/watches.png b/mseide-msegui/icons/buttons/watches.png new file mode 100644 index 0000000..3b9cc1f Binary files /dev/null and b/mseide-msegui/icons/buttons/watches.png differ diff --git a/mseide-msegui/icons/buttons/watches.svg b/mseide-msegui/icons/buttons/watches.svg new file mode 100644 index 0000000..c8bea8c --- /dev/null +++ b/mseide-msegui/icons/buttons/watches.svg @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ??? + + + + + ??? + + diff --git a/mseide-msegui/icons/components/123.png b/mseide-msegui/icons/components/123.png new file mode 100644 index 0000000..b849070 Binary files /dev/null and b/mseide-msegui/icons/components/123.png differ diff --git a/mseide-msegui/icons/components/123s.png b/mseide-msegui/icons/components/123s.png new file mode 100644 index 0000000..53936a0 Binary files /dev/null and b/mseide-msegui/icons/components/123s.png differ diff --git a/mseide-msegui/icons/components/123ss.png b/mseide-msegui/icons/components/123ss.png new file mode 100644 index 0000000..89cb326 Binary files /dev/null and b/mseide-msegui/icons/components/123ss.png differ diff --git a/mseide-msegui/icons/components/1_2.png b/mseide-msegui/icons/components/1_2.png new file mode 100644 index 0000000..eb45498 Binary files /dev/null and b/mseide-msegui/icons/components/1_2.png differ diff --git a/mseide-msegui/icons/components/64.png b/mseide-msegui/icons/components/64.png new file mode 100644 index 0000000..31ec06b Binary files /dev/null and b/mseide-msegui/icons/components/64.png differ diff --git a/mseide-msegui/icons/components/TComponent.bmp b/mseide-msegui/icons/components/TComponent.bmp new file mode 100755 index 0000000..c02e0be Binary files /dev/null and b/mseide-msegui/icons/components/TComponent.bmp differ diff --git a/mseide-msegui/icons/components/TComponent.png b/mseide-msegui/icons/components/TComponent.png new file mode 100644 index 0000000..fad0f80 Binary files /dev/null and b/mseide-msegui/icons/components/TComponent.png differ diff --git a/mseide-msegui/icons/components/TIBConnection.bmp b/mseide-msegui/icons/components/TIBConnection.bmp new file mode 100644 index 0000000..986531b Binary files /dev/null and b/mseide-msegui/icons/components/TIBConnection.bmp differ diff --git a/mseide-msegui/icons/components/TSQLTransaction.bmp b/mseide-msegui/icons/components/TSQLTransaction.bmp new file mode 100644 index 0000000..8ac1d60 Binary files /dev/null and b/mseide-msegui/icons/components/TSQLTransaction.bmp differ diff --git a/mseide-msegui/icons/components/TZConnection.bmp b/mseide-msegui/icons/components/TZConnection.bmp new file mode 100644 index 0000000..c59e541 Binary files /dev/null and b/mseide-msegui/icons/components/TZConnection.bmp differ diff --git a/mseide-msegui/icons/components/TZSequence.bmp b/mseide-msegui/icons/components/TZSequence.bmp new file mode 100644 index 0000000..d0efe30 Binary files /dev/null and b/mseide-msegui/icons/components/TZSequence.bmp differ diff --git a/mseide-msegui/icons/components/TZSqlMetadata.bmp b/mseide-msegui/icons/components/TZSqlMetadata.bmp new file mode 100644 index 0000000..8315968 Binary files /dev/null and b/mseide-msegui/icons/components/TZSqlMetadata.bmp differ diff --git a/mseide-msegui/icons/components/TZSqlMonitor.bmp b/mseide-msegui/icons/components/TZSqlMonitor.bmp new file mode 100644 index 0000000..89983a9 Binary files /dev/null and b/mseide-msegui/icons/components/TZSqlMonitor.bmp differ diff --git a/mseide-msegui/icons/components/TZSqlProcessor.bmp b/mseide-msegui/icons/components/TZSqlProcessor.bmp new file mode 100644 index 0000000..a6b15c5 Binary files /dev/null and b/mseide-msegui/icons/components/TZSqlProcessor.bmp differ diff --git a/mseide-msegui/icons/components/TZStoredProc.bmp b/mseide-msegui/icons/components/TZStoredProc.bmp new file mode 100644 index 0000000..937532f Binary files /dev/null and b/mseide-msegui/icons/components/TZStoredProc.bmp differ diff --git a/mseide-msegui/icons/components/TZUpdateSql.bmp b/mseide-msegui/icons/components/TZUpdateSql.bmp new file mode 100644 index 0000000..99a7b60 Binary files /dev/null and b/mseide-msegui/icons/components/TZUpdateSql.bmp differ diff --git a/mseide-msegui/icons/components/_sta.png b/mseide-msegui/icons/components/_sta.png new file mode 100644 index 0000000..90a30eb Binary files /dev/null and b/mseide-msegui/icons/components/_sta.png differ diff --git a/mseide-msegui/icons/components/a01.png b/mseide-msegui/icons/components/a01.png new file mode 100644 index 0000000..082722c Binary files /dev/null and b/mseide-msegui/icons/components/a01.png differ diff --git a/mseide-msegui/icons/components/a4ss.png b/mseide-msegui/icons/components/a4ss.png new file mode 100644 index 0000000..4bded75 Binary files /dev/null and b/mseide-msegui/icons/components/a4ss.png differ diff --git a/mseide-msegui/icons/components/ab.png b/mseide-msegui/icons/components/ab.png new file mode 100644 index 0000000..b57e2a6 Binary files /dev/null and b/mseide-msegui/icons/components/ab.png differ diff --git a/mseide-msegui/icons/components/abc.png b/mseide-msegui/icons/components/abc.png new file mode 100644 index 0000000..af605b1 Binary files /dev/null and b/mseide-msegui/icons/components/abc.png differ diff --git a/mseide-msegui/icons/components/abc_de.png b/mseide-msegui/icons/components/abc_de.png new file mode 100644 index 0000000..d954beb Binary files /dev/null and b/mseide-msegui/icons/components/abc_de.png differ diff --git a/mseide-msegui/icons/components/abcss.png b/mseide-msegui/icons/components/abcss.png new file mode 100644 index 0000000..864df56 Binary files /dev/null and b/mseide-msegui/icons/components/abcss.png differ diff --git a/mseide-msegui/icons/components/abs.png b/mseide-msegui/icons/components/abs.png new file mode 100644 index 0000000..4dfd8e4 Binary files /dev/null and b/mseide-msegui/icons/components/abs.png differ diff --git a/mseide-msegui/icons/components/abss.png b/mseide-msegui/icons/components/abss.png new file mode 100644 index 0000000..798166e Binary files /dev/null and b/mseide-msegui/icons/components/abss.png differ diff --git a/mseide-msegui/icons/components/breakpoint.png b/mseide-msegui/icons/components/breakpoint.png new file mode 100644 index 0000000..616e6c4 Binary files /dev/null and b/mseide-msegui/icons/components/breakpoint.png differ diff --git a/mseide-msegui/icons/components/capt.png b/mseide-msegui/icons/components/capt.png new file mode 100644 index 0000000..79f985a Binary files /dev/null and b/mseide-msegui/icons/components/capt.png differ diff --git a/mseide-msegui/icons/components/ctrl.png b/mseide-msegui/icons/components/ctrl.png new file mode 100644 index 0000000..033a17d Binary files /dev/null and b/mseide-msegui/icons/components/ctrl.png differ diff --git a/mseide-msegui/icons/components/d_t.png b/mseide-msegui/icons/components/d_t.png new file mode 100644 index 0000000..d3e1f5a Binary files /dev/null and b/mseide-msegui/icons/components/d_t.png differ diff --git a/mseide-msegui/icons/components/d_tss.png.png b/mseide-msegui/icons/components/d_tss.png.png new file mode 100644 index 0000000..6e0ad42 Binary files /dev/null and b/mseide-msegui/icons/components/d_tss.png.png differ diff --git a/mseide-msegui/icons/components/dbf.png b/mseide-msegui/icons/components/dbf.png new file mode 100644 index 0000000..11478bf Binary files /dev/null and b/mseide-msegui/icons/components/dbf.png differ diff --git a/mseide-msegui/icons/components/dirss.png b/mseide-msegui/icons/components/dirss.png new file mode 100644 index 0000000..930b6a8 Binary files /dev/null and b/mseide-msegui/icons/components/dirss.png differ diff --git a/mseide-msegui/icons/components/e_if.png b/mseide-msegui/icons/components/e_if.png new file mode 100644 index 0000000..74d085a Binary files /dev/null and b/mseide-msegui/icons/components/e_if.png differ diff --git a/mseide-msegui/icons/components/enum.png b/mseide-msegui/icons/components/enum.png new file mode 100644 index 0000000..2e5521a Binary files /dev/null and b/mseide-msegui/icons/components/enum.png differ diff --git a/mseide-msegui/icons/components/file.png b/mseide-msegui/icons/components/file.png new file mode 100644 index 0000000..6d3b9b4 Binary files /dev/null and b/mseide-msegui/icons/components/file.png differ diff --git a/mseide-msegui/icons/components/files.png b/mseide-msegui/icons/components/files.png new file mode 100644 index 0000000..40f6cae Binary files /dev/null and b/mseide-msegui/icons/components/files.png differ diff --git a/mseide-msegui/icons/components/finishi.svg b/mseide-msegui/icons/components/finishi.svg new file mode 100644 index 0000000..556ad5d --- /dev/null +++ b/mseide-msegui/icons/components/finishi.svg @@ -0,0 +1,450 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/components/fix.png b/mseide-msegui/icons/components/fix.png new file mode 100644 index 0000000..fb35a7c Binary files /dev/null and b/mseide-msegui/icons/components/fix.png differ diff --git a/mseide-msegui/icons/components/gdi.png b/mseide-msegui/icons/components/gdi.png new file mode 100644 index 0000000..4654d25 Binary files /dev/null and b/mseide-msegui/icons/components/gdi.png differ diff --git a/mseide-msegui/icons/components/hist.png b/mseide-msegui/icons/components/hist.png new file mode 100644 index 0000000..65bd7d6 Binary files /dev/null and b/mseide-msegui/icons/components/hist.png differ diff --git a/mseide-msegui/icons/components/key.png b/mseide-msegui/icons/components/key.png new file mode 100644 index 0000000..d6dd0e7 Binary files /dev/null and b/mseide-msegui/icons/components/key.png differ diff --git a/mseide-msegui/icons/components/lips.svg b/mseide-msegui/icons/components/lips.svg new file mode 100644 index 0000000..1a44622 --- /dev/null +++ b/mseide-msegui/icons/components/lips.svg @@ -0,0 +1,102 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/loc.png b/mseide-msegui/icons/components/loc.png new file mode 100644 index 0000000..ccfd585 Binary files /dev/null and b/mseide-msegui/icons/components/loc.png differ diff --git a/mseide-msegui/icons/components/logo_mysql_sun_a.gif b/mseide-msegui/icons/components/logo_mysql_sun_a.gif new file mode 100644 index 0000000..ff6da3b Binary files /dev/null and b/mseide-msegui/icons/components/logo_mysql_sun_a.gif differ diff --git a/mseide-msegui/icons/components/me.png b/mseide-msegui/icons/components/me.png new file mode 100644 index 0000000..bf7e3e8 Binary files /dev/null and b/mseide-msegui/icons/components/me.png differ diff --git a/mseide-msegui/icons/components/mem.png b/mseide-msegui/icons/components/mem.png new file mode 100644 index 0000000..e2c6a46 Binary files /dev/null and b/mseide-msegui/icons/components/mem.png differ diff --git a/mseide-msegui/icons/components/memo.png b/mseide-msegui/icons/components/memo.png new file mode 100644 index 0000000..cf4ab13 Binary files /dev/null and b/mseide-msegui/icons/components/memo.png differ diff --git a/mseide-msegui/icons/components/mes.png b/mseide-msegui/icons/components/mes.png new file mode 100644 index 0000000..4bfa4ff Binary files /dev/null and b/mseide-msegui/icons/components/mes.png differ diff --git a/mseide-msegui/icons/components/nil.png b/mseide-msegui/icons/components/nil.png new file mode 100644 index 0000000..80f13a7 Binary files /dev/null and b/mseide-msegui/icons/components/nil.png differ diff --git a/mseide-msegui/icons/components/par_env.png b/mseide-msegui/icons/components/par_env.png new file mode 100644 index 0000000..18ab47e Binary files /dev/null and b/mseide-msegui/icons/components/par_env.png differ diff --git a/mseide-msegui/icons/components/pastedpic_11232008_073918.png b/mseide-msegui/icons/components/pastedpic_11232008_073918.png new file mode 100644 index 0000000..8418f47 Binary files /dev/null and b/mseide-msegui/icons/components/pastedpic_11232008_073918.png differ diff --git a/mseide-msegui/icons/components/path3889-4.png b/mseide-msegui/icons/components/path3889-4.png new file mode 100644 index 0000000..0cdac99 Binary files /dev/null and b/mseide-msegui/icons/components/path3889-4.png differ diff --git a/mseide-msegui/icons/components/path3889.png b/mseide-msegui/icons/components/path3889.png new file mode 100644 index 0000000..a2cbc42 Binary files /dev/null and b/mseide-msegui/icons/components/path3889.png differ diff --git a/mseide-msegui/icons/components/path4098.png b/mseide-msegui/icons/components/path4098.png new file mode 100644 index 0000000..d5a9552 Binary files /dev/null and b/mseide-msegui/icons/components/path4098.png differ diff --git a/mseide-msegui/icons/components/path4104.png b/mseide-msegui/icons/components/path4104.png new file mode 100644 index 0000000..dff0390 Binary files /dev/null and b/mseide-msegui/icons/components/path4104.png differ diff --git a/mseide-msegui/icons/components/path4444.png b/mseide-msegui/icons/components/path4444.png new file mode 100644 index 0000000..09990d2 Binary files /dev/null and b/mseide-msegui/icons/components/path4444.png differ diff --git a/mseide-msegui/icons/components/port_land.png b/mseide-msegui/icons/components/port_land.png new file mode 100644 index 0000000..9555780 Binary files /dev/null and b/mseide-msegui/icons/components/port_land.png differ diff --git a/mseide-msegui/icons/components/portss.png b/mseide-msegui/icons/components/portss.png new file mode 100644 index 0000000..bb4d08b Binary files /dev/null and b/mseide-msegui/icons/components/portss.png differ diff --git a/mseide-msegui/icons/components/proc_mon.png b/mseide-msegui/icons/components/proc_mon.png new file mode 100644 index 0000000..3fef43a Binary files /dev/null and b/mseide-msegui/icons/components/proc_mon.png differ diff --git a/mseide-msegui/icons/components/ps.png b/mseide-msegui/icons/components/ps.png new file mode 100644 index 0000000..8b28b74 Binary files /dev/null and b/mseide-msegui/icons/components/ps.png differ diff --git a/mseide-msegui/icons/components/rec.png b/mseide-msegui/icons/components/rec.png new file mode 100644 index 0000000..380d170 Binary files /dev/null and b/mseide-msegui/icons/components/rec.png differ diff --git a/mseide-msegui/icons/components/rect2648.png b/mseide-msegui/icons/components/rect2648.png new file mode 100644 index 0000000..1a45bfb Binary files /dev/null and b/mseide-msegui/icons/components/rect2648.png differ diff --git a/mseide-msegui/icons/components/rect9378.png b/mseide-msegui/icons/components/rect9378.png new file mode 100644 index 0000000..1a45bfb Binary files /dev/null and b/mseide-msegui/icons/components/rect9378.png differ diff --git a/mseide-msegui/icons/components/sdf.png b/mseide-msegui/icons/components/sdf.png new file mode 100644 index 0000000..cdcce69 Binary files /dev/null and b/mseide-msegui/icons/components/sdf.png differ diff --git a/mseide-msegui/icons/components/sel.png b/mseide-msegui/icons/components/sel.png new file mode 100644 index 0000000..2f16a54 Binary files /dev/null and b/mseide-msegui/icons/components/sel.png differ diff --git a/mseide-msegui/icons/components/sigbase.svg b/mseide-msegui/icons/components/sigbase.svg new file mode 100644 index 0000000..32b2773 --- /dev/null +++ b/mseide-msegui/icons/components/sigbase.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SIG + + diff --git a/mseide-msegui/icons/components/sigedit.svg b/mseide-msegui/icons/components/sigedit.svg new file mode 100644 index 0000000..89e5bbc --- /dev/null +++ b/mseide-msegui/icons/components/sigedit.svg @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/sql.png b/mseide-msegui/icons/components/sql.png new file mode 100644 index 0000000..b101d41 Binary files /dev/null and b/mseide-msegui/icons/components/sql.png differ diff --git a/mseide-msegui/icons/components/sql_e.png b/mseide-msegui/icons/components/sql_e.png new file mode 100644 index 0000000..8210d78 Binary files /dev/null and b/mseide-msegui/icons/components/sql_e.png differ diff --git a/mseide-msegui/icons/components/sql_eee.png b/mseide-msegui/icons/components/sql_eee.png new file mode 100644 index 0000000..aa11990 Binary files /dev/null and b/mseide-msegui/icons/components/sql_eee.png differ diff --git a/mseide-msegui/icons/components/sql_qqq.png b/mseide-msegui/icons/components/sql_qqq.png new file mode 100644 index 0000000..4950cf6 Binary files /dev/null and b/mseide-msegui/icons/components/sql_qqq.png differ diff --git a/mseide-msegui/icons/components/symbols.svg b/mseide-msegui/icons/components/symbols.svg new file mode 100644 index 0000000..70d0f2b --- /dev/null +++ b/mseide-msegui/icons/components/symbols.svg @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + SYM + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tacecomp.bmp b/mseide-msegui/icons/components/tacecomp.bmp new file mode 100755 index 0000000..796a3b1 Binary files /dev/null and b/mseide-msegui/icons/components/tacecomp.bmp differ diff --git a/mseide-msegui/icons/components/taction.bmp b/mseide-msegui/icons/components/taction.bmp new file mode 100755 index 0000000..048871c Binary files /dev/null and b/mseide-msegui/icons/components/taction.bmp differ diff --git a/mseide-msegui/icons/components/taction.png b/mseide-msegui/icons/components/taction.png new file mode 100644 index 0000000..62ff6dc Binary files /dev/null and b/mseide-msegui/icons/components/taction.png differ diff --git a/mseide-msegui/icons/components/taction.svg b/mseide-msegui/icons/components/taction.svg new file mode 100644 index 0000000..2fc93e4 --- /dev/null +++ b/mseide-msegui/icons/components/taction.svg @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + GUI + + diff --git a/mseide-msegui/icons/components/tactivator.bmp b/mseide-msegui/icons/components/tactivator.bmp new file mode 100644 index 0000000..8078d19 Binary files /dev/null and b/mseide-msegui/icons/components/tactivator.bmp differ diff --git a/mseide-msegui/icons/components/tactivator.png b/mseide-msegui/icons/components/tactivator.png new file mode 100644 index 0000000..ba5cf8f Binary files /dev/null and b/mseide-msegui/icons/components/tactivator.png differ diff --git a/mseide-msegui/icons/components/tactivator.svg b/mseide-msegui/icons/components/tactivator.svg new file mode 100644 index 0000000..e217ae9 --- /dev/null +++ b/mseide-msegui/icons/components/tactivator.svg @@ -0,0 +1,491 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tanimitemcomp.png b/mseide-msegui/icons/components/tanimitemcomp.png new file mode 100644 index 0000000..1012594 Binary files /dev/null and b/mseide-msegui/icons/components/tanimitemcomp.png differ diff --git a/mseide-msegui/icons/components/tanimitemcomp.svg b/mseide-msegui/icons/components/tanimitemcomp.svg new file mode 100644 index 0000000..4be96df --- /dev/null +++ b/mseide-msegui/icons/components/tanimitemcomp.svg @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tanimtimer.png b/mseide-msegui/icons/components/tanimtimer.png new file mode 100644 index 0000000..5c2a783 Binary files /dev/null and b/mseide-msegui/icons/components/tanimtimer.png differ diff --git a/mseide-msegui/icons/components/tanimtimer.svg b/mseide-msegui/icons/components/tanimtimer.svg new file mode 100644 index 0000000..b7a74ed --- /dev/null +++ b/mseide-msegui/icons/components/tanimtimer.svg @@ -0,0 +1,623 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tasciicommport.bmp b/mseide-msegui/icons/components/tasciicommport.bmp new file mode 100755 index 0000000..c0a96fc Binary files /dev/null and b/mseide-msegui/icons/components/tasciicommport.bmp differ diff --git a/mseide-msegui/icons/components/tasciicommport.png b/mseide-msegui/icons/components/tasciicommport.png new file mode 100644 index 0000000..4b4c877 Binary files /dev/null and b/mseide-msegui/icons/components/tasciicommport.png differ diff --git a/mseide-msegui/icons/components/tasciicommport.svg b/mseide-msegui/icons/components/tasciicommport.svg new file mode 100644 index 0000000..b423e7f --- /dev/null +++ b/mseide-msegui/icons/components/tasciicommport.svg @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + ASCIIPORT + + diff --git a/mseide-msegui/icons/components/tasciiproptport.png b/mseide-msegui/icons/components/tasciiproptport.png new file mode 100644 index 0000000..1cef8fd Binary files /dev/null and b/mseide-msegui/icons/components/tasciiproptport.png differ diff --git a/mseide-msegui/icons/components/tasciiprotport.png b/mseide-msegui/icons/components/tasciiprotport.png new file mode 100644 index 0000000..1cef8fd Binary files /dev/null and b/mseide-msegui/icons/components/tasciiprotport.png differ diff --git a/mseide-msegui/icons/components/tasciiprotport.svg b/mseide-msegui/icons/components/tasciiprotport.svg new file mode 100644 index 0000000..2875619 --- /dev/null +++ b/mseide-msegui/icons/components/tasciiprotport.svg @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + AprotPORT + + diff --git a/mseide-msegui/icons/components/tassistivehandler.png b/mseide-msegui/icons/components/tassistivehandler.png new file mode 100644 index 0000000..f09eba1 Binary files /dev/null and b/mseide-msegui/icons/components/tassistivehandler.png differ diff --git a/mseide-msegui/icons/components/tassistivehandler.svg b/mseide-msegui/icons/components/tassistivehandler.svg new file mode 100644 index 0000000..564f7f3 --- /dev/null +++ b/mseide-msegui/icons/components/tassistivehandler.svg @@ -0,0 +1,130 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tassistivewidgetitem.png b/mseide-msegui/icons/components/tassistivewidgetitem.png new file mode 100644 index 0000000..b161358 Binary files /dev/null and b/mseide-msegui/icons/components/tassistivewidgetitem.png differ diff --git a/mseide-msegui/icons/components/tassistivewidgetitem.svg b/mseide-msegui/icons/components/tassistivewidgetitem.svg new file mode 100644 index 0000000..404c293 --- /dev/null +++ b/mseide-msegui/icons/components/tassistivewidgetitem.svg @@ -0,0 +1,130 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tasymciphercryptohandler.png b/mseide-msegui/icons/components/tasymciphercryptohandler.png new file mode 100644 index 0000000..57a7db5 Binary files /dev/null and b/mseide-msegui/icons/components/tasymciphercryptohandler.png differ diff --git a/mseide-msegui/icons/components/tasymciphercryptohandler.svg b/mseide-msegui/icons/components/tasymciphercryptohandler.svg new file mode 100644 index 0000000..2f54954 --- /dev/null +++ b/mseide-msegui/icons/components/tasymciphercryptohandler.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + ASYM + cryp + + diff --git a/mseide-msegui/icons/components/tasynsercommchannel.png b/mseide-msegui/icons/components/tasynsercommchannel.png new file mode 100644 index 0000000..5f2377f Binary files /dev/null and b/mseide-msegui/icons/components/tasynsercommchannel.png differ diff --git a/mseide-msegui/icons/components/tasynsercommchannel.svg b/mseide-msegui/icons/components/tasynsercommchannel.svg new file mode 100644 index 0000000..edf1b66 --- /dev/null +++ b/mseide-msegui/icons/components/tasynsercommchannel.svg @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + ASYNCHA + + diff --git a/mseide-msegui/icons/components/taudioout.png b/mseide-msegui/icons/components/taudioout.png new file mode 100644 index 0000000..0e686b9 Binary files /dev/null and b/mseide-msegui/icons/components/taudioout.png differ diff --git a/mseide-msegui/icons/components/taudioout.svg b/mseide-msegui/icons/components/taudioout.svg new file mode 100644 index 0000000..b5ff4fd --- /dev/null +++ b/mseide-msegui/icons/components/taudioout.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + AUDIO + + + + + + + diff --git a/mseide-msegui/icons/components/tbandarea.bmp b/mseide-msegui/icons/components/tbandarea.bmp new file mode 100644 index 0000000..b422387 Binary files /dev/null and b/mseide-msegui/icons/components/tbandarea.bmp differ diff --git a/mseide-msegui/icons/components/tbandbroup.bmp b/mseide-msegui/icons/components/tbandbroup.bmp new file mode 100644 index 0000000..bfe7fe5 Binary files /dev/null and b/mseide-msegui/icons/components/tbandbroup.bmp differ diff --git a/mseide-msegui/icons/components/tbandgroup.bmp b/mseide-msegui/icons/components/tbandgroup.bmp new file mode 100644 index 0000000..bfe7fe5 Binary files /dev/null and b/mseide-msegui/icons/components/tbandgroup.bmp differ diff --git a/mseide-msegui/icons/components/tbarcode.png b/mseide-msegui/icons/components/tbarcode.png new file mode 100644 index 0000000..a73489e Binary files /dev/null and b/mseide-msegui/icons/components/tbarcode.png differ diff --git a/mseide-msegui/icons/components/tbarcode.svg b/mseide-msegui/icons/components/tbarcode.svg new file mode 100644 index 0000000..5d3d029 --- /dev/null +++ b/mseide-msegui/icons/components/tbarcode.svg @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + 10 + 10 + + + + diff --git a/mseide-msegui/icons/components/tbase64cryptohandler.png b/mseide-msegui/icons/components/tbase64cryptohandler.png new file mode 100644 index 0000000..efcc38b Binary files /dev/null and b/mseide-msegui/icons/components/tbase64cryptohandler.png differ diff --git a/mseide-msegui/icons/components/tbase64cryptohandler.svg b/mseide-msegui/icons/components/tbase64cryptohandler.svg new file mode 100644 index 0000000..a1af475 --- /dev/null +++ b/mseide-msegui/icons/components/tbase64cryptohandler.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Bas64 + cryp + + diff --git a/mseide-msegui/icons/components/tbase64handler.png b/mseide-msegui/icons/components/tbase64handler.png new file mode 100644 index 0000000..efcc38b Binary files /dev/null and b/mseide-msegui/icons/components/tbase64handler.png differ diff --git a/mseide-msegui/icons/components/tbase64handler.svg b/mseide-msegui/icons/components/tbase64handler.svg new file mode 100644 index 0000000..624ec3b --- /dev/null +++ b/mseide-msegui/icons/components/tbase64handler.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Bas64 + cryp + + diff --git a/mseide-msegui/icons/components/tbitmapcomp.bmp b/mseide-msegui/icons/components/tbitmapcomp.bmp new file mode 100755 index 0000000..0cc7722 Binary files /dev/null and b/mseide-msegui/icons/components/tbitmapcomp.bmp differ diff --git a/mseide-msegui/icons/components/tbitmapcomp.png b/mseide-msegui/icons/components/tbitmapcomp.png new file mode 100644 index 0000000..fc3a36f Binary files /dev/null and b/mseide-msegui/icons/components/tbitmapcomp.png differ diff --git a/mseide-msegui/icons/components/tbitmapcomp.svg b/mseide-msegui/icons/components/tbitmapcomp.svg new file mode 100644 index 0000000..1c083ab --- /dev/null +++ b/mseide-msegui/icons/components/tbitmapcomp.svg @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tbitmapcontainer.bmp b/mseide-msegui/icons/components/tbitmapcontainer.bmp new file mode 100755 index 0000000..ba0ef1c Binary files /dev/null and b/mseide-msegui/icons/components/tbitmapcontainer.bmp differ diff --git a/mseide-msegui/icons/components/tbooleandisp.bmp b/mseide-msegui/icons/components/tbooleandisp.bmp new file mode 100644 index 0000000..9ed55ed Binary files /dev/null and b/mseide-msegui/icons/components/tbooleandisp.bmp differ diff --git a/mseide-msegui/icons/components/tbooleandisp.png b/mseide-msegui/icons/components/tbooleandisp.png new file mode 100644 index 0000000..644163c Binary files /dev/null and b/mseide-msegui/icons/components/tbooleandisp.png differ diff --git a/mseide-msegui/icons/components/tbooleandisp.svg b/mseide-msegui/icons/components/tbooleandisp.svg new file mode 100644 index 0000000..a2e97ac --- /dev/null +++ b/mseide-msegui/icons/components/tbooleandisp.svg @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + T/F + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tbooleanedit.bmp b/mseide-msegui/icons/components/tbooleanedit.bmp new file mode 100755 index 0000000..7f9ca65 Binary files /dev/null and b/mseide-msegui/icons/components/tbooleanedit.bmp differ diff --git a/mseide-msegui/icons/components/tbooleaneditradio.bmp b/mseide-msegui/icons/components/tbooleaneditradio.bmp new file mode 100755 index 0000000..a015c58 Binary files /dev/null and b/mseide-msegui/icons/components/tbooleaneditradio.bmp differ diff --git a/mseide-msegui/icons/components/tbutton.bmp b/mseide-msegui/icons/components/tbutton.bmp new file mode 100755 index 0000000..fca42a3 Binary files /dev/null and b/mseide-msegui/icons/components/tbutton.bmp differ diff --git a/mseide-msegui/icons/components/tbutton.png b/mseide-msegui/icons/components/tbutton.png new file mode 100644 index 0000000..d2981da Binary files /dev/null and b/mseide-msegui/icons/components/tbutton.png differ diff --git a/mseide-msegui/icons/components/tbutton.svg b/mseide-msegui/icons/components/tbutton.svg new file mode 100644 index 0000000..5bae02e --- /dev/null +++ b/mseide-msegui/icons/components/tbutton.svg @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + Capt + + + + diff --git a/mseide-msegui/icons/components/tbytestringdisp.bmp b/mseide-msegui/icons/components/tbytestringdisp.bmp new file mode 100644 index 0000000..fae2784 Binary files /dev/null and b/mseide-msegui/icons/components/tbytestringdisp.bmp differ diff --git a/mseide-msegui/icons/components/tbytestringdisp.png b/mseide-msegui/icons/components/tbytestringdisp.png new file mode 100644 index 0000000..939552e Binary files /dev/null and b/mseide-msegui/icons/components/tbytestringdisp.png differ diff --git a/mseide-msegui/icons/components/tbytestringdisp.svg b/mseide-msegui/icons/components/tbytestringdisp.svg new file mode 100644 index 0000000..f0a156b --- /dev/null +++ b/mseide-msegui/icons/components/tbytestringdisp.svg @@ -0,0 +1,428 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + A01 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tbytestringlist.png b/mseide-msegui/icons/components/tbytestringlist.png new file mode 100644 index 0000000..939552e Binary files /dev/null and b/mseide-msegui/icons/components/tbytestringlist.png differ diff --git a/mseide-msegui/icons/components/tcalendardatetimeedit.bmp b/mseide-msegui/icons/components/tcalendardatetimeedit.bmp new file mode 100644 index 0000000..dff71a6 Binary files /dev/null and b/mseide-msegui/icons/components/tcalendardatetimeedit.bmp differ diff --git a/mseide-msegui/icons/components/tcalendardatetimeedit.png b/mseide-msegui/icons/components/tcalendardatetimeedit.png new file mode 100644 index 0000000..e02bbf5 Binary files /dev/null and b/mseide-msegui/icons/components/tcalendardatetimeedit.png differ diff --git a/mseide-msegui/icons/components/tcalendardatetimeedit.svg b/mseide-msegui/icons/components/tcalendardatetimeedit.svg new file mode 100644 index 0000000..5a3588f --- /dev/null +++ b/mseide-msegui/icons/components/tcalendardatetimeedit.svg @@ -0,0 +1,567 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tcaption.png b/mseide-msegui/icons/components/tcaption.png new file mode 100644 index 0000000..5278500 Binary files /dev/null and b/mseide-msegui/icons/components/tcaption.png differ diff --git a/mseide-msegui/icons/components/tchart.bmp b/mseide-msegui/icons/components/tchart.bmp new file mode 100644 index 0000000..fa56588 Binary files /dev/null and b/mseide-msegui/icons/components/tchart.bmp differ diff --git a/mseide-msegui/icons/components/tchart.png b/mseide-msegui/icons/components/tchart.png new file mode 100644 index 0000000..d8b876e Binary files /dev/null and b/mseide-msegui/icons/components/tchart.png differ diff --git a/mseide-msegui/icons/components/tchart.svg b/mseide-msegui/icons/components/tchart.svg new file mode 100644 index 0000000..f01d610 --- /dev/null +++ b/mseide-msegui/icons/components/tchart.svg @@ -0,0 +1,303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tchartrecorder.bmp b/mseide-msegui/icons/components/tchartrecorder.bmp new file mode 100644 index 0000000..5ddb4c2 Binary files /dev/null and b/mseide-msegui/icons/components/tchartrecorder.bmp differ diff --git a/mseide-msegui/icons/components/tchartrecorder.png b/mseide-msegui/icons/components/tchartrecorder.png new file mode 100644 index 0000000..84552a2 Binary files /dev/null and b/mseide-msegui/icons/components/tchartrecorder.png differ diff --git a/mseide-msegui/icons/components/tchartrecorder.svg b/mseide-msegui/icons/components/tchartrecorder.svg new file mode 100644 index 0000000..2ca2fc6 --- /dev/null +++ b/mseide-msegui/icons/components/tchartrecorder.svg @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tcoloredit.bmp b/mseide-msegui/icons/components/tcoloredit.bmp new file mode 100644 index 0000000..64d011e Binary files /dev/null and b/mseide-msegui/icons/components/tcoloredit.bmp differ diff --git a/mseide-msegui/icons/components/tcoloredit.png b/mseide-msegui/icons/components/tcoloredit.png new file mode 100644 index 0000000..6cefcbf Binary files /dev/null and b/mseide-msegui/icons/components/tcoloredit.png differ diff --git a/mseide-msegui/icons/components/tcoloredit.svg b/mseide-msegui/icons/components/tcoloredit.svg new file mode 100644 index 0000000..431fb1c --- /dev/null +++ b/mseide-msegui/icons/components/tcoloredit.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tcommport.bmp b/mseide-msegui/icons/components/tcommport.bmp new file mode 100755 index 0000000..b88f095 Binary files /dev/null and b/mseide-msegui/icons/components/tcommport.bmp differ diff --git a/mseide-msegui/icons/components/tcommport.png b/mseide-msegui/icons/components/tcommport.png new file mode 100644 index 0000000..299882f Binary files /dev/null and b/mseide-msegui/icons/components/tcommport.png differ diff --git a/mseide-msegui/icons/components/tcommport.svg b/mseide-msegui/icons/components/tcommport.svg new file mode 100644 index 0000000..a9ee115 --- /dev/null +++ b/mseide-msegui/icons/components/tcommport.svg @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + COMMPORT + + diff --git a/mseide-msegui/icons/components/tcommselector.bmp b/mseide-msegui/icons/components/tcommselector.bmp new file mode 100755 index 0000000..8460a08 Binary files /dev/null and b/mseide-msegui/icons/components/tcommselector.bmp differ diff --git a/mseide-msegui/icons/components/tcomponent.svg b/mseide-msegui/icons/components/tcomponent.svg new file mode 100644 index 0000000..294a19a --- /dev/null +++ b/mseide-msegui/icons/components/tcomponent.svg @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tconnectedifidatasource.png b/mseide-msegui/icons/components/tconnectedifidatasource.png new file mode 100644 index 0000000..ff62f7f Binary files /dev/null and b/mseide-msegui/icons/components/tconnectedifidatasource.png differ diff --git a/mseide-msegui/icons/components/tconnectedifidatasource.svg b/mseide-msegui/icons/components/tconnectedifidatasource.svg new file mode 100644 index 0000000..2fea9af --- /dev/null +++ b/mseide-msegui/icons/components/tconnectedifidatasource.svg @@ -0,0 +1,386 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdatabutton.bmp b/mseide-msegui/icons/components/tdatabutton.bmp new file mode 100644 index 0000000..f7bad63 Binary files /dev/null and b/mseide-msegui/icons/components/tdatabutton.bmp differ diff --git a/mseide-msegui/icons/components/tdatabutton.png b/mseide-msegui/icons/components/tdatabutton.png new file mode 100644 index 0000000..7c9e1bc Binary files /dev/null and b/mseide-msegui/icons/components/tdatabutton.png differ diff --git a/mseide-msegui/icons/components/tdatabutton.svg b/mseide-msegui/icons/components/tdatabutton.svg new file mode 100644 index 0000000..4a094ba --- /dev/null +++ b/mseide-msegui/icons/components/tdatabutton.svg @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdataedit.bmp b/mseide-msegui/icons/components/tdataedit.bmp new file mode 100755 index 0000000..a857b7f Binary files /dev/null and b/mseide-msegui/icons/components/tdataedit.bmp differ diff --git a/mseide-msegui/icons/components/tdataicon.bmp b/mseide-msegui/icons/components/tdataicon.bmp new file mode 100755 index 0000000..f2cfdfe Binary files /dev/null and b/mseide-msegui/icons/components/tdataicon.bmp differ diff --git a/mseide-msegui/icons/components/tdataicon.png b/mseide-msegui/icons/components/tdataicon.png new file mode 100644 index 0000000..df30425 Binary files /dev/null and b/mseide-msegui/icons/components/tdataicon.png differ diff --git a/mseide-msegui/icons/components/tdataicon.svg b/mseide-msegui/icons/components/tdataicon.svg new file mode 100644 index 0000000..99473f0 --- /dev/null +++ b/mseide-msegui/icons/components/tdataicon.svg @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdataimage.bmp b/mseide-msegui/icons/components/tdataimage.bmp new file mode 100644 index 0000000..56a0e70 Binary files /dev/null and b/mseide-msegui/icons/components/tdataimage.bmp differ diff --git a/mseide-msegui/icons/components/tdataimage.png b/mseide-msegui/icons/components/tdataimage.png new file mode 100644 index 0000000..2fd5cfd Binary files /dev/null and b/mseide-msegui/icons/components/tdataimage.png differ diff --git a/mseide-msegui/icons/components/tdataimage.svg b/mseide-msegui/icons/components/tdataimage.svg new file mode 100644 index 0000000..6c138cf --- /dev/null +++ b/mseide-msegui/icons/components/tdataimage.svg @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdatasource.bmp b/mseide-msegui/icons/components/tdatasource.bmp new file mode 100644 index 0000000..65d5ed1 Binary files /dev/null and b/mseide-msegui/icons/components/tdatasource.bmp differ diff --git a/mseide-msegui/icons/components/tdatetimedisp.bmp b/mseide-msegui/icons/components/tdatetimedisp.bmp new file mode 100644 index 0000000..d7ea6a1 Binary files /dev/null and b/mseide-msegui/icons/components/tdatetimedisp.bmp differ diff --git a/mseide-msegui/icons/components/tdatetimedisp.png b/mseide-msegui/icons/components/tdatetimedisp.png new file mode 100644 index 0000000..d147a49 Binary files /dev/null and b/mseide-msegui/icons/components/tdatetimedisp.png differ diff --git a/mseide-msegui/icons/components/tdatetimedisp.svg b/mseide-msegui/icons/components/tdatetimedisp.svg new file mode 100644 index 0000000..6504f65 --- /dev/null +++ b/mseide-msegui/icons/components/tdatetimedisp.svg @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + D:T + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdatetimedisplb.svg b/mseide-msegui/icons/components/tdatetimedisplb.svg new file mode 100644 index 0000000..9efbc2e --- /dev/null +++ b/mseide-msegui/icons/components/tdatetimedisplb.svg @@ -0,0 +1,375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdatetimeedit.bmp b/mseide-msegui/icons/components/tdatetimeedit.bmp new file mode 100755 index 0000000..05c92d7 Binary files /dev/null and b/mseide-msegui/icons/components/tdatetimeedit.bmp differ diff --git a/mseide-msegui/icons/components/tdatetimeedit.png b/mseide-msegui/icons/components/tdatetimeedit.png new file mode 100644 index 0000000..686b4a5 Binary files /dev/null and b/mseide-msegui/icons/components/tdatetimeedit.png differ diff --git a/mseide-msegui/icons/components/tdatetimeedit.svg b/mseide-msegui/icons/components/tdatetimeedit.svg new file mode 100644 index 0000000..2b95a12 --- /dev/null +++ b/mseide-msegui/icons/components/tdatetimeedit.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbbarcode.png b/mseide-msegui/icons/components/tdbbarcode.png new file mode 100644 index 0000000..b21aac0 Binary files /dev/null and b/mseide-msegui/icons/components/tdbbarcode.png differ diff --git a/mseide-msegui/icons/components/tdbbarcode.svg b/mseide-msegui/icons/components/tdbbarcode.svg new file mode 100644 index 0000000..8567957 --- /dev/null +++ b/mseide-msegui/icons/components/tdbbarcode.svg @@ -0,0 +1,406 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + 10 + 10 + + + + diff --git a/mseide-msegui/icons/components/tdbbooleandisp.bmp b/mseide-msegui/icons/components/tdbbooleandisp.bmp new file mode 100644 index 0000000..4f00f6f Binary files /dev/null and b/mseide-msegui/icons/components/tdbbooleandisp.bmp differ diff --git a/mseide-msegui/icons/components/tdbbooleandisp.png b/mseide-msegui/icons/components/tdbbooleandisp.png new file mode 100644 index 0000000..8724065 Binary files /dev/null and b/mseide-msegui/icons/components/tdbbooleandisp.png differ diff --git a/mseide-msegui/icons/components/tdbbooleanedit.bmp b/mseide-msegui/icons/components/tdbbooleanedit.bmp new file mode 100644 index 0000000..ccc9db2 Binary files /dev/null and b/mseide-msegui/icons/components/tdbbooleanedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbbooleaneditradio.bmp b/mseide-msegui/icons/components/tdbbooleaneditradio.bmp new file mode 100644 index 0000000..958b07a Binary files /dev/null and b/mseide-msegui/icons/components/tdbbooleaneditradio.bmp differ diff --git a/mseide-msegui/icons/components/tdbbooleantextedit.bmp b/mseide-msegui/icons/components/tdbbooleantextedit.bmp new file mode 100644 index 0000000..ad40395 Binary files /dev/null and b/mseide-msegui/icons/components/tdbbooleantextedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbbooleantextedit.png b/mseide-msegui/icons/components/tdbbooleantextedit.png new file mode 100644 index 0000000..cb30579 Binary files /dev/null and b/mseide-msegui/icons/components/tdbbooleantextedit.png differ diff --git a/mseide-msegui/icons/components/tdbbooleantextedit.svg b/mseide-msegui/icons/components/tdbbooleantextedit.svg new file mode 100644 index 0000000..542e68b --- /dev/null +++ b/mseide-msegui/icons/components/tdbbooleantextedit.svg @@ -0,0 +1,423 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbcalendardatetimeedit.bmp b/mseide-msegui/icons/components/tdbcalendardatetimeedit.bmp new file mode 100644 index 0000000..1dd7f94 Binary files /dev/null and b/mseide-msegui/icons/components/tdbcalendardatetimeedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbcalendardatetimeedit.png b/mseide-msegui/icons/components/tdbcalendardatetimeedit.png new file mode 100644 index 0000000..2f34076 Binary files /dev/null and b/mseide-msegui/icons/components/tdbcalendardatetimeedit.png differ diff --git a/mseide-msegui/icons/components/tdbcalendardatetimeedit.svg b/mseide-msegui/icons/components/tdbcalendardatetimeedit.svg new file mode 100644 index 0000000..346be80 --- /dev/null +++ b/mseide-msegui/icons/components/tdbcalendardatetimeedit.svg @@ -0,0 +1,567 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbcoloredit.bmp b/mseide-msegui/icons/components/tdbcoloredit.bmp new file mode 100644 index 0000000..88f7e1f Binary files /dev/null and b/mseide-msegui/icons/components/tdbcoloredit.bmp differ diff --git a/mseide-msegui/icons/components/tdbcoloredit.png b/mseide-msegui/icons/components/tdbcoloredit.png new file mode 100644 index 0000000..cbb4bbd Binary files /dev/null and b/mseide-msegui/icons/components/tdbcoloredit.png differ diff --git a/mseide-msegui/icons/components/tdbcoloredit.svg b/mseide-msegui/icons/components/tdbcoloredit.svg new file mode 100644 index 0000000..e685360 --- /dev/null +++ b/mseide-msegui/icons/components/tdbcoloredit.svg @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatabutton.bmp b/mseide-msegui/icons/components/tdbdatabutton.bmp new file mode 100644 index 0000000..fa300b3 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatabutton.bmp differ diff --git a/mseide-msegui/icons/components/tdbdatabutton.png b/mseide-msegui/icons/components/tdbdatabutton.png new file mode 100644 index 0000000..46d59c6 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatabutton.png differ diff --git a/mseide-msegui/icons/components/tdbdatabutton.svg b/mseide-msegui/icons/components/tdbdatabutton.svg new file mode 100644 index 0000000..56a6b75 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatabutton.svg @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdataicon.bmp b/mseide-msegui/icons/components/tdbdataicon.bmp new file mode 100644 index 0000000..349d7fc Binary files /dev/null and b/mseide-msegui/icons/components/tdbdataicon.bmp differ diff --git a/mseide-msegui/icons/components/tdbdataicon.png b/mseide-msegui/icons/components/tdbdataicon.png new file mode 100644 index 0000000..3597c07 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdataicon.png differ diff --git a/mseide-msegui/icons/components/tdbdataicon.svg b/mseide-msegui/icons/components/tdbdataicon.svg new file mode 100644 index 0000000..5e256b0 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdataicon.svg @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdataimage.bmp b/mseide-msegui/icons/components/tdbdataimage.bmp new file mode 100644 index 0000000..ba9e28a Binary files /dev/null and b/mseide-msegui/icons/components/tdbdataimage.bmp differ diff --git a/mseide-msegui/icons/components/tdbdataimage.png b/mseide-msegui/icons/components/tdbdataimage.png new file mode 100644 index 0000000..0f0215c Binary files /dev/null and b/mseide-msegui/icons/components/tdbdataimage.png differ diff --git a/mseide-msegui/icons/components/tdbdataimage.svg b/mseide-msegui/icons/components/tdbdataimage.svg new file mode 100644 index 0000000..7ac811c --- /dev/null +++ b/mseide-msegui/icons/components/tdbdataimage.svg @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimedisp.bmp b/mseide-msegui/icons/components/tdbdatetimedisp.bmp new file mode 100644 index 0000000..124eb32 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimedisp.bmp differ diff --git a/mseide-msegui/icons/components/tdbdatetimedisp.png b/mseide-msegui/icons/components/tdbdatetimedisp.png new file mode 100644 index 0000000..99c9d09 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimedisp.png differ diff --git a/mseide-msegui/icons/components/tdbdatetimedisp.svg b/mseide-msegui/icons/components/tdbdatetimedisp.svg new file mode 100644 index 0000000..2ed2fcb --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimedisp.svg @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + D:T + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimedisplb.bmp b/mseide-msegui/icons/components/tdbdatetimedisplb.bmp new file mode 100644 index 0000000..02920f6 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimedisplb.bmp differ diff --git a/mseide-msegui/icons/components/tdbdatetimedisplb.png b/mseide-msegui/icons/components/tdbdatetimedisplb.png new file mode 100644 index 0000000..a7d2852 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimedisplb.png differ diff --git a/mseide-msegui/icons/components/tdbdatetimedisplb.svg b/mseide-msegui/icons/components/tdbdatetimedisplb.svg new file mode 100644 index 0000000..30ac906 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimedisplb.svg @@ -0,0 +1,375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimeedit.bmp b/mseide-msegui/icons/components/tdbdatetimeedit.bmp new file mode 100644 index 0000000..c1cc4ed Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimeedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbdatetimeedit.png b/mseide-msegui/icons/components/tdbdatetimeedit.png new file mode 100644 index 0000000..31a9879 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimeedit.png differ diff --git a/mseide-msegui/icons/components/tdbdatetimeedit.svg b/mseide-msegui/icons/components/tdbdatetimeedit.svg new file mode 100644 index 0000000..97dc7b7 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimeedit.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookup64db.png b/mseide-msegui/icons/components/tdbdatetimelookup64db.png new file mode 100644 index 0000000..cae63dd Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimelookup64db.png differ diff --git a/mseide-msegui/icons/components/tdbdatetimelookup64db.svg b/mseide-msegui/icons/components/tdbdatetimelookup64db.svg new file mode 100644 index 0000000..c5e4897 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimelookup64db.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + D:T + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookup64lb.png b/mseide-msegui/icons/components/tdbdatetimelookup64lb.png new file mode 100644 index 0000000..482dc0a Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimelookup64lb.png differ diff --git a/mseide-msegui/icons/components/tdbdatetimelookup64lb.svg b/mseide-msegui/icons/components/tdbdatetimelookup64lb.svg new file mode 100644 index 0000000..3abef33 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimelookup64lb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookupdb.png b/mseide-msegui/icons/components/tdbdatetimelookupdb.png new file mode 100644 index 0000000..38b8b3a Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimelookupdb.png differ diff --git a/mseide-msegui/icons/components/tdbdatetimelookupdb.svg b/mseide-msegui/icons/components/tdbdatetimelookupdb.svg new file mode 100644 index 0000000..128679f --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimelookupdb.svg @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + D:T + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookuplb.png b/mseide-msegui/icons/components/tdbdatetimelookuplb.png new file mode 100644 index 0000000..f390ab9 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimelookuplb.png differ diff --git a/mseide-msegui/icons/components/tdbdatetimelookuplb.svg b/mseide-msegui/icons/components/tdbdatetimelookuplb.svg new file mode 100644 index 0000000..f9441b8 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimelookuplb.svg @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookupstrdb.png b/mseide-msegui/icons/components/tdbdatetimelookupstrdb.png new file mode 100644 index 0000000..68fe918 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimelookupstrdb.png differ diff --git a/mseide-msegui/icons/components/tdbdatetimelookupstrdb.svg b/mseide-msegui/icons/components/tdbdatetimelookupstrdb.svg new file mode 100644 index 0000000..7de2af2 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimelookupstrdb.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + D:T + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookupstrlb.png b/mseide-msegui/icons/components/tdbdatetimelookupstrlb.png new file mode 100644 index 0000000..a76b944 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdatetimelookupstrlb.png differ diff --git a/mseide-msegui/icons/components/tdbdatetimelookupstrlb.svg b/mseide-msegui/icons/components/tdbdatetimelookupstrlb.svg new file mode 100644 index 0000000..218fca5 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimelookupstrlb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdbenumedit.bmp b/mseide-msegui/icons/components/tdbdbenumedit.bmp new file mode 100644 index 0000000..4925a65 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdbenumedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbdialogstringedit.bmp b/mseide-msegui/icons/components/tdbdialogstringedit.bmp new file mode 100644 index 0000000..0ffe130 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdialogstringedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbdialogstringedit.png b/mseide-msegui/icons/components/tdbdialogstringedit.png new file mode 100644 index 0000000..c2d1b72 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdialogstringedit.png differ diff --git a/mseide-msegui/icons/components/tdbdialogstringedit.svg b/mseide-msegui/icons/components/tdbdialogstringedit.svg new file mode 100644 index 0000000..6141579 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdialogstringedit.svg @@ -0,0 +1,312 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdropdownlistedit.bmp b/mseide-msegui/icons/components/tdbdropdownlistedit.bmp new file mode 100644 index 0000000..c394bb9 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdropdownlistedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbdropdownlistedit.png b/mseide-msegui/icons/components/tdbdropdownlistedit.png new file mode 100644 index 0000000..51cc0d5 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdropdownlistedit.png differ diff --git a/mseide-msegui/icons/components/tdbdropdownlistedit.svg b/mseide-msegui/icons/components/tdbdropdownlistedit.svg new file mode 100644 index 0000000..8ba47f7 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdropdownlistedit.svg @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdropdownlisteditdb.png b/mseide-msegui/icons/components/tdbdropdownlisteditdb.png new file mode 100644 index 0000000..4f58194 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdropdownlisteditdb.png differ diff --git a/mseide-msegui/icons/components/tdbdropdownlisteditdb.svg b/mseide-msegui/icons/components/tdbdropdownlisteditdb.svg new file mode 100644 index 0000000..bb7c1af --- /dev/null +++ b/mseide-msegui/icons/components/tdbdropdownlisteditdb.svg @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdropdownlisteditlb.png b/mseide-msegui/icons/components/tdbdropdownlisteditlb.png new file mode 100644 index 0000000..0c82be4 Binary files /dev/null and b/mseide-msegui/icons/components/tdbdropdownlisteditlb.png differ diff --git a/mseide-msegui/icons/components/tdbdropdownlisteditlb.svg b/mseide-msegui/icons/components/tdbdropdownlisteditlb.svg new file mode 100644 index 0000000..0da17cb --- /dev/null +++ b/mseide-msegui/icons/components/tdbdropdownlisteditlb.svg @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbenum64editdb.bmp b/mseide-msegui/icons/components/tdbenum64editdb.bmp new file mode 100644 index 0000000..873a626 Binary files /dev/null and b/mseide-msegui/icons/components/tdbenum64editdb.bmp differ diff --git a/mseide-msegui/icons/components/tdbenum64editdb.png b/mseide-msegui/icons/components/tdbenum64editdb.png new file mode 100644 index 0000000..29d1881 Binary files /dev/null and b/mseide-msegui/icons/components/tdbenum64editdb.png differ diff --git a/mseide-msegui/icons/components/tdbenum64editdb.svg b/mseide-msegui/icons/components/tdbenum64editdb.svg new file mode 100644 index 0000000..a471aa6 --- /dev/null +++ b/mseide-msegui/icons/components/tdbenum64editdb.svg @@ -0,0 +1,452 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbenum64editlb.bmp b/mseide-msegui/icons/components/tdbenum64editlb.bmp new file mode 100644 index 0000000..cfe0ea3 Binary files /dev/null and b/mseide-msegui/icons/components/tdbenum64editlb.bmp differ diff --git a/mseide-msegui/icons/components/tdbenum64editlb.png b/mseide-msegui/icons/components/tdbenum64editlb.png new file mode 100644 index 0000000..de0fc40 Binary files /dev/null and b/mseide-msegui/icons/components/tdbenum64editlb.png differ diff --git a/mseide-msegui/icons/components/tdbenum64editlb.svg b/mseide-msegui/icons/components/tdbenum64editlb.svg new file mode 100644 index 0000000..884116c --- /dev/null +++ b/mseide-msegui/icons/components/tdbenum64editlb.svg @@ -0,0 +1,452 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbenumedit.bmp b/mseide-msegui/icons/components/tdbenumedit.bmp new file mode 100644 index 0000000..3e2c2d4 Binary files /dev/null and b/mseide-msegui/icons/components/tdbenumedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbenumedit.png b/mseide-msegui/icons/components/tdbenumedit.png new file mode 100644 index 0000000..c71d879 Binary files /dev/null and b/mseide-msegui/icons/components/tdbenumedit.png differ diff --git a/mseide-msegui/icons/components/tdbenumedit.svg b/mseide-msegui/icons/components/tdbenumedit.svg new file mode 100644 index 0000000..ec3f89d --- /dev/null +++ b/mseide-msegui/icons/components/tdbenumedit.svg @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbenumeditdb.bmp b/mseide-msegui/icons/components/tdbenumeditdb.bmp new file mode 100644 index 0000000..4925a65 Binary files /dev/null and b/mseide-msegui/icons/components/tdbenumeditdb.bmp differ diff --git a/mseide-msegui/icons/components/tdbenumeditdb.png b/mseide-msegui/icons/components/tdbenumeditdb.png new file mode 100644 index 0000000..3764f26 Binary files /dev/null and b/mseide-msegui/icons/components/tdbenumeditdb.png differ diff --git a/mseide-msegui/icons/components/tdbenumeditdb.svg b/mseide-msegui/icons/components/tdbenumeditdb.svg new file mode 100644 index 0000000..ce69925 --- /dev/null +++ b/mseide-msegui/icons/components/tdbenumeditdb.svg @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbenumeditlb.bmp b/mseide-msegui/icons/components/tdbenumeditlb.bmp new file mode 100644 index 0000000..ad64866 Binary files /dev/null and b/mseide-msegui/icons/components/tdbenumeditlb.bmp differ diff --git a/mseide-msegui/icons/components/tdbenumeditlb.png b/mseide-msegui/icons/components/tdbenumeditlb.png new file mode 100644 index 0000000..d1056c4 Binary files /dev/null and b/mseide-msegui/icons/components/tdbenumeditlb.png differ diff --git a/mseide-msegui/icons/components/tdbenumeditlb.svg b/mseide-msegui/icons/components/tdbenumeditlb.svg new file mode 100644 index 0000000..4d5ee50 --- /dev/null +++ b/mseide-msegui/icons/components/tdbenumeditlb.svg @@ -0,0 +1,445 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbevent.bmp b/mseide-msegui/icons/components/tdbevent.bmp new file mode 100644 index 0000000..eb7504d Binary files /dev/null and b/mseide-msegui/icons/components/tdbevent.bmp differ diff --git a/mseide-msegui/icons/components/tdbevent.png b/mseide-msegui/icons/components/tdbevent.png new file mode 100644 index 0000000..19ef663 Binary files /dev/null and b/mseide-msegui/icons/components/tdbevent.png differ diff --git a/mseide-msegui/icons/components/tdbevent.svg b/mseide-msegui/icons/components/tdbevent.svg new file mode 100644 index 0000000..5ca0308 --- /dev/null +++ b/mseide-msegui/icons/components/tdbevent.svg @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + GUI + + diff --git a/mseide-msegui/icons/components/tdbf.bmp b/mseide-msegui/icons/components/tdbf.bmp new file mode 100644 index 0000000..baaa3de Binary files /dev/null and b/mseide-msegui/icons/components/tdbf.bmp differ diff --git a/mseide-msegui/icons/components/tdbfilenameedit.bmp b/mseide-msegui/icons/components/tdbfilenameedit.bmp new file mode 100644 index 0000000..2a9c73c Binary files /dev/null and b/mseide-msegui/icons/components/tdbfilenameedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbfilenameedit.png b/mseide-msegui/icons/components/tdbfilenameedit.png new file mode 100644 index 0000000..4500ee1 Binary files /dev/null and b/mseide-msegui/icons/components/tdbfilenameedit.png differ diff --git a/mseide-msegui/icons/components/tdbfilenameedit.svg b/mseide-msegui/icons/components/tdbfilenameedit.svg new file mode 100644 index 0000000..52dec6b --- /dev/null +++ b/mseide-msegui/icons/components/tdbfilenameedit.svg @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbimage.bmp b/mseide-msegui/icons/components/tdbimage.bmp new file mode 100644 index 0000000..789c6b5 Binary files /dev/null and b/mseide-msegui/icons/components/tdbimage.bmp differ diff --git a/mseide-msegui/icons/components/tdbintegerblookup64db.png b/mseide-msegui/icons/components/tdbintegerblookup64db.png new file mode 100644 index 0000000..25b19e1 Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegerblookup64db.png differ diff --git a/mseide-msegui/icons/components/tdbintegerdisp.bmp b/mseide-msegui/icons/components/tdbintegerdisp.bmp new file mode 100644 index 0000000..f74d145 Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegerdisp.bmp differ diff --git a/mseide-msegui/icons/components/tdbintegerdisp.png b/mseide-msegui/icons/components/tdbintegerdisp.png new file mode 100644 index 0000000..0f38cb3 Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegerdisp.png differ diff --git a/mseide-msegui/icons/components/tdbintegerdisp.svg b/mseide-msegui/icons/components/tdbintegerdisp.svg new file mode 100644 index 0000000..6da09d9 --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerdisp.svg @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 123 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerdisplb.bmp b/mseide-msegui/icons/components/tdbintegerdisplb.bmp new file mode 100644 index 0000000..4d5a820 Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegerdisplb.bmp differ diff --git a/mseide-msegui/icons/components/tdbintegerdisplb.png b/mseide-msegui/icons/components/tdbintegerdisplb.png new file mode 100644 index 0000000..834d6dc Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegerdisplb.png differ diff --git a/mseide-msegui/icons/components/tdbintegerdisplb.svg b/mseide-msegui/icons/components/tdbintegerdisplb.svg new file mode 100644 index 0000000..abd688d --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerdisplb.svg @@ -0,0 +1,375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 123 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegeredit.bmp b/mseide-msegui/icons/components/tdbintegeredit.bmp new file mode 100644 index 0000000..27a82ae Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegeredit.bmp differ diff --git a/mseide-msegui/icons/components/tdbintegeredit.png b/mseide-msegui/icons/components/tdbintegeredit.png new file mode 100644 index 0000000..388687a Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegeredit.png differ diff --git a/mseide-msegui/icons/components/tdbintegeredit.svg b/mseide-msegui/icons/components/tdbintegeredit.svg new file mode 100644 index 0000000..cb2eb30 --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegeredit.svg @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookup64db.png b/mseide-msegui/icons/components/tdbintegerlookup64db.png new file mode 100644 index 0000000..25b19e1 Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegerlookup64db.png differ diff --git a/mseide-msegui/icons/components/tdbintegerlookup64db.svg b/mseide-msegui/icons/components/tdbintegerlookup64db.svg new file mode 100644 index 0000000..853095e --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerlookup64db.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 123 + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookup64lb.png b/mseide-msegui/icons/components/tdbintegerlookup64lb.png new file mode 100644 index 0000000..4c9b9d7 Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegerlookup64lb.png differ diff --git a/mseide-msegui/icons/components/tdbintegerlookup64lb.svg b/mseide-msegui/icons/components/tdbintegerlookup64lb.svg new file mode 100644 index 0000000..f213e0e --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerlookup64lb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 123 + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookupdb.png b/mseide-msegui/icons/components/tdbintegerlookupdb.png new file mode 100644 index 0000000..95109be Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegerlookupdb.png differ diff --git a/mseide-msegui/icons/components/tdbintegerlookupdb.svg b/mseide-msegui/icons/components/tdbintegerlookupdb.svg new file mode 100644 index 0000000..9f5f200 --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerlookupdb.svg @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 123 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookuplb.png b/mseide-msegui/icons/components/tdbintegerlookuplb.png new file mode 100644 index 0000000..cef7009 Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegerlookuplb.png differ diff --git a/mseide-msegui/icons/components/tdbintegerlookuplb.svg b/mseide-msegui/icons/components/tdbintegerlookuplb.svg new file mode 100644 index 0000000..1f74eac --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerlookuplb.svg @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 123 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookupstrdb.png b/mseide-msegui/icons/components/tdbintegerlookupstrdb.png new file mode 100644 index 0000000..bc5e85f Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegerlookupstrdb.png differ diff --git a/mseide-msegui/icons/components/tdbintegerlookupstrdb.svg b/mseide-msegui/icons/components/tdbintegerlookupstrdb.svg new file mode 100644 index 0000000..4cee91a --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerlookupstrdb.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 123 + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookupstrlb.png b/mseide-msegui/icons/components/tdbintegerlookupstrlb.png new file mode 100644 index 0000000..18b0c8c Binary files /dev/null and b/mseide-msegui/icons/components/tdbintegerlookupstrlb.png differ diff --git a/mseide-msegui/icons/components/tdbintegerlookupstrlb.svg b/mseide-msegui/icons/components/tdbintegerlookupstrlb.svg new file mode 100644 index 0000000..fb5f0d7 --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerlookupstrlb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 123 + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbkeystringedit.bmp b/mseide-msegui/icons/components/tdbkeystringedit.bmp new file mode 100644 index 0000000..fd7db2a Binary files /dev/null and b/mseide-msegui/icons/components/tdbkeystringedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbkeystringedit.png b/mseide-msegui/icons/components/tdbkeystringedit.png new file mode 100644 index 0000000..b713ebc Binary files /dev/null and b/mseide-msegui/icons/components/tdbkeystringedit.png differ diff --git a/mseide-msegui/icons/components/tdbkeystringedit.svg b/mseide-msegui/icons/components/tdbkeystringedit.svg new file mode 100644 index 0000000..717a40a --- /dev/null +++ b/mseide-msegui/icons/components/tdbkeystringedit.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbkeystringeditdb.bmp b/mseide-msegui/icons/components/tdbkeystringeditdb.bmp new file mode 100644 index 0000000..d85b0c7 Binary files /dev/null and b/mseide-msegui/icons/components/tdbkeystringeditdb.bmp differ diff --git a/mseide-msegui/icons/components/tdbkeystringeditdb.png b/mseide-msegui/icons/components/tdbkeystringeditdb.png new file mode 100644 index 0000000..9c95136 Binary files /dev/null and b/mseide-msegui/icons/components/tdbkeystringeditdb.png differ diff --git a/mseide-msegui/icons/components/tdbkeystringeditdb.svg b/mseide-msegui/icons/components/tdbkeystringeditdb.svg new file mode 100644 index 0000000..2be942a --- /dev/null +++ b/mseide-msegui/icons/components/tdbkeystringeditdb.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbkeystringeditlb.bmp b/mseide-msegui/icons/components/tdbkeystringeditlb.bmp new file mode 100644 index 0000000..2a02055 Binary files /dev/null and b/mseide-msegui/icons/components/tdbkeystringeditlb.bmp differ diff --git a/mseide-msegui/icons/components/tdbkeystringeditlb.png b/mseide-msegui/icons/components/tdbkeystringeditlb.png new file mode 100644 index 0000000..2557e55 Binary files /dev/null and b/mseide-msegui/icons/components/tdbkeystringeditlb.png differ diff --git a/mseide-msegui/icons/components/tdbkeystringeditlb.svg b/mseide-msegui/icons/components/tdbkeystringeditlb.svg new file mode 100644 index 0000000..787edf7 --- /dev/null +++ b/mseide-msegui/icons/components/tdbkeystringeditlb.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdblabel.bmp b/mseide-msegui/icons/components/tdblabel.bmp new file mode 100644 index 0000000..ee16086 Binary files /dev/null and b/mseide-msegui/icons/components/tdblabel.bmp differ diff --git a/mseide-msegui/icons/components/tdblabel.png b/mseide-msegui/icons/components/tdblabel.png new file mode 100644 index 0000000..6a40433 Binary files /dev/null and b/mseide-msegui/icons/components/tdblabel.png differ diff --git a/mseide-msegui/icons/components/tdblabel.svg b/mseide-msegui/icons/components/tdblabel.svg new file mode 100644 index 0000000..bab5e60 --- /dev/null +++ b/mseide-msegui/icons/components/tdblabel.svg @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + A + + + + + + + diff --git a/mseide-msegui/icons/components/tdblookupbuffer.bmp b/mseide-msegui/icons/components/tdblookupbuffer.bmp new file mode 100644 index 0000000..3ee2e1d Binary files /dev/null and b/mseide-msegui/icons/components/tdblookupbuffer.bmp differ diff --git a/mseide-msegui/icons/components/tdblookupbuffer.png b/mseide-msegui/icons/components/tdblookupbuffer.png new file mode 100644 index 0000000..c436aed Binary files /dev/null and b/mseide-msegui/icons/components/tdblookupbuffer.png differ diff --git a/mseide-msegui/icons/components/tdblookupinteger64db.png b/mseide-msegui/icons/components/tdblookupinteger64db.png new file mode 100644 index 0000000..25b19e1 Binary files /dev/null and b/mseide-msegui/icons/components/tdblookupinteger64db.png differ diff --git a/mseide-msegui/icons/components/tdblookupinteger64lb.png b/mseide-msegui/icons/components/tdblookupinteger64lb.png new file mode 100644 index 0000000..4c9b9d7 Binary files /dev/null and b/mseide-msegui/icons/components/tdblookupinteger64lb.png differ diff --git a/mseide-msegui/icons/components/tdblookupintegerlb.png b/mseide-msegui/icons/components/tdblookupintegerlb.png new file mode 100644 index 0000000..cef7009 Binary files /dev/null and b/mseide-msegui/icons/components/tdblookupintegerlb.png differ diff --git a/mseide-msegui/icons/components/tdblookupintegerstrlb.png b/mseide-msegui/icons/components/tdblookupintegerstrlb.png new file mode 100644 index 0000000..18b0c8c Binary files /dev/null and b/mseide-msegui/icons/components/tdblookupintegerstrlb.png differ diff --git a/mseide-msegui/icons/components/tdblookupstring64lb.png b/mseide-msegui/icons/components/tdblookupstring64lb.png new file mode 100644 index 0000000..13e1264 Binary files /dev/null and b/mseide-msegui/icons/components/tdblookupstring64lb.png differ diff --git a/mseide-msegui/icons/components/tdbmemoblookupbuffer.bmp b/mseide-msegui/icons/components/tdbmemoblookupbuffer.bmp new file mode 100644 index 0000000..e09d4de Binary files /dev/null and b/mseide-msegui/icons/components/tdbmemoblookupbuffer.bmp differ diff --git a/mseide-msegui/icons/components/tdbmemoedit.bmp b/mseide-msegui/icons/components/tdbmemoedit.bmp new file mode 100644 index 0000000..0f4d1a9 Binary files /dev/null and b/mseide-msegui/icons/components/tdbmemoedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbmemoedit.png b/mseide-msegui/icons/components/tdbmemoedit.png new file mode 100644 index 0000000..69a673d Binary files /dev/null and b/mseide-msegui/icons/components/tdbmemoedit.png differ diff --git a/mseide-msegui/icons/components/tdbmemoedit.svg b/mseide-msegui/icons/components/tdbmemoedit.svg new file mode 100644 index 0000000..6e9be05 --- /dev/null +++ b/mseide-msegui/icons/components/tdbmemoedit.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbmemolookupbuffer.bmp b/mseide-msegui/icons/components/tdbmemolookupbuffer.bmp new file mode 100644 index 0000000..e09d4de Binary files /dev/null and b/mseide-msegui/icons/components/tdbmemolookupbuffer.bmp differ diff --git a/mseide-msegui/icons/components/tdbmemolookupbuffer.png b/mseide-msegui/icons/components/tdbmemolookupbuffer.png new file mode 100644 index 0000000..a074676 Binary files /dev/null and b/mseide-msegui/icons/components/tdbmemolookupbuffer.png differ diff --git a/mseide-msegui/icons/components/tdbnavigator.bmp b/mseide-msegui/icons/components/tdbnavigator.bmp new file mode 100644 index 0000000..882e612 Binary files /dev/null and b/mseide-msegui/icons/components/tdbnavigator.bmp differ diff --git a/mseide-msegui/icons/components/tdbprogressbar.bmp b/mseide-msegui/icons/components/tdbprogressbar.bmp new file mode 100644 index 0000000..b8d4882 Binary files /dev/null and b/mseide-msegui/icons/components/tdbprogressbar.bmp differ diff --git a/mseide-msegui/icons/components/tdbprogressbar.png b/mseide-msegui/icons/components/tdbprogressbar.png new file mode 100644 index 0000000..1a8c59d Binary files /dev/null and b/mseide-msegui/icons/components/tdbprogressbar.png differ diff --git a/mseide-msegui/icons/components/tdbprogressbar.svg b/mseide-msegui/icons/components/tdbprogressbar.svg new file mode 100644 index 0000000..ee8095b --- /dev/null +++ b/mseide-msegui/icons/components/tdbprogressbar.svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbrealdisp.bmp b/mseide-msegui/icons/components/tdbrealdisp.bmp new file mode 100644 index 0000000..f728f55 Binary files /dev/null and b/mseide-msegui/icons/components/tdbrealdisp.bmp differ diff --git a/mseide-msegui/icons/components/tdbrealdisp.png b/mseide-msegui/icons/components/tdbrealdisp.png new file mode 100644 index 0000000..9affd09 Binary files /dev/null and b/mseide-msegui/icons/components/tdbrealdisp.png differ diff --git a/mseide-msegui/icons/components/tdbrealdisp.svg b/mseide-msegui/icons/components/tdbrealdisp.svg new file mode 100644 index 0000000..ff3646e --- /dev/null +++ b/mseide-msegui/icons/components/tdbrealdisp.svg @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 1.21 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbrealdisplb.bmp b/mseide-msegui/icons/components/tdbrealdisplb.bmp new file mode 100644 index 0000000..b0d1b23 Binary files /dev/null and b/mseide-msegui/icons/components/tdbrealdisplb.bmp differ diff --git a/mseide-msegui/icons/components/tdbrealdisplb.png b/mseide-msegui/icons/components/tdbrealdisplb.png new file mode 100644 index 0000000..b3da193 Binary files /dev/null and b/mseide-msegui/icons/components/tdbrealdisplb.png differ diff --git a/mseide-msegui/icons/components/tdbrealdisplb.svg b/mseide-msegui/icons/components/tdbrealdisplb.svg new file mode 100644 index 0000000..7dcbedb --- /dev/null +++ b/mseide-msegui/icons/components/tdbrealdisplb.svg @@ -0,0 +1,375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 1.21 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbrealedit.bmp b/mseide-msegui/icons/components/tdbrealedit.bmp new file mode 100644 index 0000000..e066c5f Binary files /dev/null and b/mseide-msegui/icons/components/tdbrealedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbrealedit.png b/mseide-msegui/icons/components/tdbrealedit.png new file mode 100644 index 0000000..ee66fc2 Binary files /dev/null and b/mseide-msegui/icons/components/tdbrealedit.png differ diff --git a/mseide-msegui/icons/components/tdbrealedit.svg b/mseide-msegui/icons/components/tdbrealedit.svg new file mode 100644 index 0000000..142295d --- /dev/null +++ b/mseide-msegui/icons/components/tdbrealedit.svg @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookup64db.png b/mseide-msegui/icons/components/tdbreallookup64db.png new file mode 100644 index 0000000..bed69a5 Binary files /dev/null and b/mseide-msegui/icons/components/tdbreallookup64db.png differ diff --git a/mseide-msegui/icons/components/tdbreallookup64db.svg b/mseide-msegui/icons/components/tdbreallookup64db.svg new file mode 100644 index 0000000..88196fb --- /dev/null +++ b/mseide-msegui/icons/components/tdbreallookup64db.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 1.21 + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookup64lb.png b/mseide-msegui/icons/components/tdbreallookup64lb.png new file mode 100644 index 0000000..593be83 Binary files /dev/null and b/mseide-msegui/icons/components/tdbreallookup64lb.png differ diff --git a/mseide-msegui/icons/components/tdbreallookup64lb.svg b/mseide-msegui/icons/components/tdbreallookup64lb.svg new file mode 100644 index 0000000..951cf8b --- /dev/null +++ b/mseide-msegui/icons/components/tdbreallookup64lb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 1.21 + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookupdb.png b/mseide-msegui/icons/components/tdbreallookupdb.png new file mode 100644 index 0000000..4dfdead Binary files /dev/null and b/mseide-msegui/icons/components/tdbreallookupdb.png differ diff --git a/mseide-msegui/icons/components/tdbreallookupdb.svg b/mseide-msegui/icons/components/tdbreallookupdb.svg new file mode 100644 index 0000000..f45757c --- /dev/null +++ b/mseide-msegui/icons/components/tdbreallookupdb.svg @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 1.21 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookuplb.png b/mseide-msegui/icons/components/tdbreallookuplb.png new file mode 100644 index 0000000..25ca30d Binary files /dev/null and b/mseide-msegui/icons/components/tdbreallookuplb.png differ diff --git a/mseide-msegui/icons/components/tdbreallookuplb.svg b/mseide-msegui/icons/components/tdbreallookuplb.svg new file mode 100644 index 0000000..ca7e12a --- /dev/null +++ b/mseide-msegui/icons/components/tdbreallookuplb.svg @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 1.21 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookupstrdb.png b/mseide-msegui/icons/components/tdbreallookupstrdb.png new file mode 100644 index 0000000..a8e9e7c Binary files /dev/null and b/mseide-msegui/icons/components/tdbreallookupstrdb.png differ diff --git a/mseide-msegui/icons/components/tdbreallookupstrdb.svg b/mseide-msegui/icons/components/tdbreallookupstrdb.svg new file mode 100644 index 0000000..6606aea --- /dev/null +++ b/mseide-msegui/icons/components/tdbreallookupstrdb.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 1.21 + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookupstrlb.png b/mseide-msegui/icons/components/tdbreallookupstrlb.png new file mode 100644 index 0000000..45a12b5 Binary files /dev/null and b/mseide-msegui/icons/components/tdbreallookupstrlb.png differ diff --git a/mseide-msegui/icons/components/tdbreallookupstrlb.svg b/mseide-msegui/icons/components/tdbreallookupstrlb.svg new file mode 100644 index 0000000..f962e3e --- /dev/null +++ b/mseide-msegui/icons/components/tdbreallookupstrlb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 1.21 + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbrealspinedit.bmp b/mseide-msegui/icons/components/tdbrealspinedit.bmp new file mode 100644 index 0000000..07b4592 Binary files /dev/null and b/mseide-msegui/icons/components/tdbrealspinedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbrealspinedit.png b/mseide-msegui/icons/components/tdbrealspinedit.png new file mode 100644 index 0000000..b632410 Binary files /dev/null and b/mseide-msegui/icons/components/tdbrealspinedit.png differ diff --git a/mseide-msegui/icons/components/tdbrealspinedit.svg b/mseide-msegui/icons/components/tdbrealspinedit.svg new file mode 100644 index 0000000..ccd39bd --- /dev/null +++ b/mseide-msegui/icons/components/tdbrealspinedit.svg @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbslider.bmp b/mseide-msegui/icons/components/tdbslider.bmp new file mode 100644 index 0000000..78b76de Binary files /dev/null and b/mseide-msegui/icons/components/tdbslider.bmp differ diff --git a/mseide-msegui/icons/components/tdbslider.png b/mseide-msegui/icons/components/tdbslider.png new file mode 100644 index 0000000..6a690ac Binary files /dev/null and b/mseide-msegui/icons/components/tdbslider.png differ diff --git a/mseide-msegui/icons/components/tdbslider.svg b/mseide-msegui/icons/components/tdbslider.svg new file mode 100644 index 0000000..a2b29ac --- /dev/null +++ b/mseide-msegui/icons/components/tdbslider.svg @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstingdisp.png b/mseide-msegui/icons/components/tdbstingdisp.png new file mode 100644 index 0000000..e40048a Binary files /dev/null and b/mseide-msegui/icons/components/tdbstingdisp.png differ diff --git a/mseide-msegui/icons/components/tdbstingdisplb.png b/mseide-msegui/icons/components/tdbstingdisplb.png new file mode 100644 index 0000000..aa0553e Binary files /dev/null and b/mseide-msegui/icons/components/tdbstingdisplb.png differ diff --git a/mseide-msegui/icons/components/tdbstringdisp.bmp b/mseide-msegui/icons/components/tdbstringdisp.bmp new file mode 100644 index 0000000..58fe00b Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringdisp.bmp differ diff --git a/mseide-msegui/icons/components/tdbstringdisp.png b/mseide-msegui/icons/components/tdbstringdisp.png new file mode 100644 index 0000000..6e971e8 Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringdisp.png differ diff --git a/mseide-msegui/icons/components/tdbstringdisp.svg b/mseide-msegui/icons/components/tdbstringdisp.svg new file mode 100644 index 0000000..f455612 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringdisp.svg @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + abc + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringdisplb.bmp b/mseide-msegui/icons/components/tdbstringdisplb.bmp new file mode 100644 index 0000000..34eb2dd Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringdisplb.bmp differ diff --git a/mseide-msegui/icons/components/tdbstringdisplb.png b/mseide-msegui/icons/components/tdbstringdisplb.png new file mode 100644 index 0000000..45da9c2 Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringdisplb.png differ diff --git a/mseide-msegui/icons/components/tdbstringdisplb.svg b/mseide-msegui/icons/components/tdbstringdisplb.svg new file mode 100644 index 0000000..d41c2e4 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringdisplb.svg @@ -0,0 +1,375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringedit.bmp b/mseide-msegui/icons/components/tdbstringedit.bmp new file mode 100644 index 0000000..8920253 Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringedit.bmp differ diff --git a/mseide-msegui/icons/components/tdbstringedit.png b/mseide-msegui/icons/components/tdbstringedit.png new file mode 100644 index 0000000..20469d8 Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringedit.png differ diff --git a/mseide-msegui/icons/components/tdbstringedit.svg b/mseide-msegui/icons/components/tdbstringedit.svg new file mode 100644 index 0000000..11dc1ca --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringedit.svg @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringgrid.bmp b/mseide-msegui/icons/components/tdbstringgrid.bmp new file mode 100644 index 0000000..6128b76 Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringgrid.bmp differ diff --git a/mseide-msegui/icons/components/tdbstringgrid.png b/mseide-msegui/icons/components/tdbstringgrid.png new file mode 100644 index 0000000..518c424 Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringgrid.png differ diff --git a/mseide-msegui/icons/components/tdbstringgrid.svg b/mseide-msegui/icons/components/tdbstringgrid.svg new file mode 100644 index 0000000..a64d968 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringgrid.svg @@ -0,0 +1,564 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + Ugx + 123 + 78 + 00 + 233 + 15 + + + + + + + + + + + + + + + ABC + + + diff --git a/mseide-msegui/icons/components/tdbstringlookup64db.png b/mseide-msegui/icons/components/tdbstringlookup64db.png new file mode 100644 index 0000000..cc9f37e Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringlookup64db.png differ diff --git a/mseide-msegui/icons/components/tdbstringlookup64db.svg b/mseide-msegui/icons/components/tdbstringlookup64db.svg new file mode 100644 index 0000000..cea7995 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringlookup64db.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + abc + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringlookup64lb.png b/mseide-msegui/icons/components/tdbstringlookup64lb.png new file mode 100644 index 0000000..13e1264 Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringlookup64lb.png differ diff --git a/mseide-msegui/icons/components/tdbstringlookup64lb.svg b/mseide-msegui/icons/components/tdbstringlookup64lb.svg new file mode 100644 index 0000000..c183b97 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringlookup64lb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringlookupdb.png b/mseide-msegui/icons/components/tdbstringlookupdb.png new file mode 100644 index 0000000..50d9b7d Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringlookupdb.png differ diff --git a/mseide-msegui/icons/components/tdbstringlookupdb.svg b/mseide-msegui/icons/components/tdbstringlookupdb.svg new file mode 100644 index 0000000..7f4b73f --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringlookupdb.svg @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + abc + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringlookuplb.png b/mseide-msegui/icons/components/tdbstringlookuplb.png new file mode 100644 index 0000000..01a7c05 Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringlookuplb.png differ diff --git a/mseide-msegui/icons/components/tdbstringlookuplb.svg b/mseide-msegui/icons/components/tdbstringlookuplb.svg new file mode 100644 index 0000000..e28bb69 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringlookuplb.svg @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringlookupstrdb.png b/mseide-msegui/icons/components/tdbstringlookupstrdb.png new file mode 100644 index 0000000..d08ec48 Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringlookupstrdb.png differ diff --git a/mseide-msegui/icons/components/tdbstringlookupstrdb.svg b/mseide-msegui/icons/components/tdbstringlookupstrdb.svg new file mode 100644 index 0000000..c35c728 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringlookupstrdb.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + abc + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringlookupstrlb.png b/mseide-msegui/icons/components/tdbstringlookupstrlb.png new file mode 100644 index 0000000..593c215 Binary files /dev/null and b/mseide-msegui/icons/components/tdbstringlookupstrlb.png differ diff --git a/mseide-msegui/icons/components/tdbstringlookupstrlb.svg b/mseide-msegui/icons/components/tdbstringlookupstrlb.svg new file mode 100644 index 0000000..591a6e9 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringlookupstrlb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbwidgetgrid.bmp b/mseide-msegui/icons/components/tdbwidgetgrid.bmp new file mode 100644 index 0000000..8b02ab1 Binary files /dev/null and b/mseide-msegui/icons/components/tdbwidgetgrid.bmp differ diff --git a/mseide-msegui/icons/components/tdbwidgetgrid.png b/mseide-msegui/icons/components/tdbwidgetgrid.png new file mode 100644 index 0000000..dcfb9eb Binary files /dev/null and b/mseide-msegui/icons/components/tdbwidgetgrid.png differ diff --git a/mseide-msegui/icons/components/tdbwidgetgrid.svg b/mseide-msegui/icons/components/tdbwidgetgrid.svg new file mode 100644 index 0000000..f749fbb --- /dev/null +++ b/mseide-msegui/icons/components/tdbwidgetgrid.svg @@ -0,0 +1,534 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + Ugx + 123 + 78 + 00 + 233 + 15 + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdial.bmp b/mseide-msegui/icons/components/tdial.bmp new file mode 100644 index 0000000..07ed842 Binary files /dev/null and b/mseide-msegui/icons/components/tdial.bmp differ diff --git a/mseide-msegui/icons/components/tdialogstringedit.bmp b/mseide-msegui/icons/components/tdialogstringedit.bmp new file mode 100644 index 0000000..fff93a4 Binary files /dev/null and b/mseide-msegui/icons/components/tdialogstringedit.bmp differ diff --git a/mseide-msegui/icons/components/tdialogstringedit.png b/mseide-msegui/icons/components/tdialogstringedit.png new file mode 100644 index 0000000..19f259a Binary files /dev/null and b/mseide-msegui/icons/components/tdialogstringedit.png differ diff --git a/mseide-msegui/icons/components/tdialogstringedit.svg b/mseide-msegui/icons/components/tdialogstringedit.svg new file mode 100644 index 0000000..9b61509 --- /dev/null +++ b/mseide-msegui/icons/components/tdialogstringedit.svg @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AB + + diff --git a/mseide-msegui/icons/components/tdigesthandler.png b/mseide-msegui/icons/components/tdigesthandler.png new file mode 100644 index 0000000..d0471b8 Binary files /dev/null and b/mseide-msegui/icons/components/tdigesthandler.png differ diff --git a/mseide-msegui/icons/components/tdigesthandler.svg b/mseide-msegui/icons/components/tdigesthandler.svg new file mode 100644 index 0000000..1863e24 --- /dev/null +++ b/mseide-msegui/icons/components/tdigesthandler.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + digest + cryp + + diff --git a/mseide-msegui/icons/components/tdintegerblookup64db.png b/mseide-msegui/icons/components/tdintegerblookup64db.png new file mode 100644 index 0000000..25b19e1 Binary files /dev/null and b/mseide-msegui/icons/components/tdintegerblookup64db.png differ diff --git a/mseide-msegui/icons/components/tdirdropdownedit.bmp b/mseide-msegui/icons/components/tdirdropdownedit.bmp new file mode 100755 index 0000000..8c1a2d8 Binary files /dev/null and b/mseide-msegui/icons/components/tdirdropdownedit.bmp differ diff --git a/mseide-msegui/icons/components/tdirdropdownedit.png b/mseide-msegui/icons/components/tdirdropdownedit.png new file mode 100644 index 0000000..fd104ed Binary files /dev/null and b/mseide-msegui/icons/components/tdirdropdownedit.png differ diff --git a/mseide-msegui/icons/components/tdirdropdownedit.svg b/mseide-msegui/icons/components/tdirdropdownedit.svg new file mode 100644 index 0000000..9894ef6 --- /dev/null +++ b/mseide-msegui/icons/components/tdirdropdownedit.svg @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + ilbitrop + + + + + + zfrpti + efkwlfg + + + + + + diff --git a/mseide-msegui/icons/components/tdirtreeview.png b/mseide-msegui/icons/components/tdirtreeview.png new file mode 100644 index 0000000..641ac88 Binary files /dev/null and b/mseide-msegui/icons/components/tdirtreeview.png differ diff --git a/mseide-msegui/icons/components/tdirtreeview.svg b/mseide-msegui/icons/components/tdirtreeview.svg new file mode 100644 index 0000000..0e0a459 --- /dev/null +++ b/mseide-msegui/icons/components/tdirtreeview.svg @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + DIR + + + + + + diff --git a/mseide-msegui/icons/components/tdirtreeview2.svg b/mseide-msegui/icons/components/tdirtreeview2.svg new file mode 100644 index 0000000..e166d06 --- /dev/null +++ b/mseide-msegui/icons/components/tdirtreeview2.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + dirfil.efil2 + + + + + diff --git a/mseide-msegui/icons/components/tdispwidget.bmp b/mseide-msegui/icons/components/tdispwidget.bmp new file mode 100755 index 0000000..fc450e1 Binary files /dev/null and b/mseide-msegui/icons/components/tdispwidget.bmp differ diff --git a/mseide-msegui/icons/components/tdmdatetimedisp.png b/mseide-msegui/icons/components/tdmdatetimedisp.png new file mode 100644 index 0000000..99c9d09 Binary files /dev/null and b/mseide-msegui/icons/components/tdmdatetimedisp.png differ diff --git a/mseide-msegui/icons/components/tdmemoblookupbuffer.bmp b/mseide-msegui/icons/components/tdmemoblookupbuffer.bmp new file mode 100644 index 0000000..e09d4de Binary files /dev/null and b/mseide-msegui/icons/components/tdmemoblookupbuffer.bmp differ diff --git a/mseide-msegui/icons/components/tdockformwidget.bmp b/mseide-msegui/icons/components/tdockformwidget.bmp new file mode 100755 index 0000000..bf3df64 Binary files /dev/null and b/mseide-msegui/icons/components/tdockformwidget.bmp differ diff --git a/mseide-msegui/icons/components/tdockformwidget.png b/mseide-msegui/icons/components/tdockformwidget.png new file mode 100644 index 0000000..9aad4d2 Binary files /dev/null and b/mseide-msegui/icons/components/tdockformwidget.png differ diff --git a/mseide-msegui/icons/components/tdockformwidget.svg b/mseide-msegui/icons/components/tdockformwidget.svg new file mode 100644 index 0000000..f1d4ae5 --- /dev/null +++ b/mseide-msegui/icons/components/tdockformwidget.svg @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + Plioe + + + + + diff --git a/mseide-msegui/icons/components/tdockhandle.bmp b/mseide-msegui/icons/components/tdockhandle.bmp new file mode 100755 index 0000000..6b2da97 Binary files /dev/null and b/mseide-msegui/icons/components/tdockhandle.bmp differ diff --git a/mseide-msegui/icons/components/tdockpanel.bmp b/mseide-msegui/icons/components/tdockpanel.bmp new file mode 100755 index 0000000..4dba151 Binary files /dev/null and b/mseide-msegui/icons/components/tdockpanel.bmp differ diff --git a/mseide-msegui/icons/components/tdockpanel.png b/mseide-msegui/icons/components/tdockpanel.png new file mode 100644 index 0000000..88302ec Binary files /dev/null and b/mseide-msegui/icons/components/tdockpanel.png differ diff --git a/mseide-msegui/icons/components/tdockpanel.svg b/mseide-msegui/icons/components/tdockpanel.svg new file mode 100644 index 0000000..e47eeb4 --- /dev/null +++ b/mseide-msegui/icons/components/tdockpanel.svg @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdockpanelformcontroller.png b/mseide-msegui/icons/components/tdockpanelformcontroller.png new file mode 100644 index 0000000..6ab3c14 Binary files /dev/null and b/mseide-msegui/icons/components/tdockpanelformcontroller.png differ diff --git a/mseide-msegui/icons/components/tdockpanelformcontroller.svg b/mseide-msegui/icons/components/tdockpanelformcontroller.svg new file mode 100644 index 0000000..870ffeb --- /dev/null +++ b/mseide-msegui/icons/components/tdockpanelformcontroller.svg @@ -0,0 +1,481 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Plioe + + + + + diff --git a/mseide-msegui/icons/components/tdrawgrid.bmp b/mseide-msegui/icons/components/tdrawgrid.bmp new file mode 100755 index 0000000..2252e5e Binary files /dev/null and b/mseide-msegui/icons/components/tdrawgrid.bmp differ diff --git a/mseide-msegui/icons/components/tdrawgrid.png b/mseide-msegui/icons/components/tdrawgrid.png new file mode 100644 index 0000000..0fd363d Binary files /dev/null and b/mseide-msegui/icons/components/tdrawgrid.png differ diff --git a/mseide-msegui/icons/components/tdrawgrid.svg b/mseide-msegui/icons/components/tdrawgrid.svg new file mode 100644 index 0000000..dc35fac --- /dev/null +++ b/mseide-msegui/icons/components/tdrawgrid.svg @@ -0,0 +1,613 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + Ugx + 123 + 78 + 00 + 233 + 15 + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdropdownitemedit.bmp b/mseide-msegui/icons/components/tdropdownitemedit.bmp new file mode 100644 index 0000000..a6d1892 Binary files /dev/null and b/mseide-msegui/icons/components/tdropdownitemedit.bmp differ diff --git a/mseide-msegui/icons/components/tdropdownitemedit.png b/mseide-msegui/icons/components/tdropdownitemedit.png new file mode 100644 index 0000000..bedb911 Binary files /dev/null and b/mseide-msegui/icons/components/tdropdownitemedit.png differ diff --git a/mseide-msegui/icons/components/tdropdownitemedit.svg b/mseide-msegui/icons/components/tdropdownitemedit.svg new file mode 100644 index 0000000..b69e46d --- /dev/null +++ b/mseide-msegui/icons/components/tdropdownitemedit.svg @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdropdownlistedit.bmp b/mseide-msegui/icons/components/tdropdownlistedit.bmp new file mode 100755 index 0000000..77b8d4c Binary files /dev/null and b/mseide-msegui/icons/components/tdropdownlistedit.bmp differ diff --git a/mseide-msegui/icons/components/tdropdownlistedit.png b/mseide-msegui/icons/components/tdropdownlistedit.png new file mode 100644 index 0000000..082730a Binary files /dev/null and b/mseide-msegui/icons/components/tdropdownlistedit.png differ diff --git a/mseide-msegui/icons/components/tdropdownlistedit.svg b/mseide-msegui/icons/components/tdropdownlistedit.svg new file mode 100644 index 0000000..0af45a3 --- /dev/null +++ b/mseide-msegui/icons/components/tdropdownlistedit.svg @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdropdownlisteditdb.png b/mseide-msegui/icons/components/tdropdownlisteditdb.png new file mode 100644 index 0000000..fc73e15 Binary files /dev/null and b/mseide-msegui/icons/components/tdropdownlisteditdb.png differ diff --git a/mseide-msegui/icons/components/tdropdownlisteditdb.svg b/mseide-msegui/icons/components/tdropdownlisteditdb.svg new file mode 100644 index 0000000..7b01ef5 --- /dev/null +++ b/mseide-msegui/icons/components/tdropdownlisteditdb.svg @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdropdownlisteditlb.png b/mseide-msegui/icons/components/tdropdownlisteditlb.png new file mode 100644 index 0000000..0c40fb6 Binary files /dev/null and b/mseide-msegui/icons/components/tdropdownlisteditlb.png differ diff --git a/mseide-msegui/icons/components/tdropdownlisteditlb.svg b/mseide-msegui/icons/components/tdropdownlisteditlb.svg new file mode 100644 index 0000000..710410b --- /dev/null +++ b/mseide-msegui/icons/components/tdropdownlisteditlb.svg @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdummycryptohandler.png b/mseide-msegui/icons/components/tdummycryptohandler.png new file mode 100644 index 0000000..a4f8a03 Binary files /dev/null and b/mseide-msegui/icons/components/tdummycryptohandler.png differ diff --git a/mseide-msegui/icons/components/tdummycryptohandler.svg b/mseide-msegui/icons/components/tdummycryptohandler.svg new file mode 100644 index 0000000..a43b6fb --- /dev/null +++ b/mseide-msegui/icons/components/tdummycryptohandler.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Dumy + cryp + + diff --git a/mseide-msegui/icons/components/tedit.bmp b/mseide-msegui/icons/components/tedit.bmp new file mode 100755 index 0000000..a857b7f Binary files /dev/null and b/mseide-msegui/icons/components/tedit.bmp differ diff --git a/mseide-msegui/icons/components/tedit.png b/mseide-msegui/icons/components/tedit.png new file mode 100644 index 0000000..3873b79 Binary files /dev/null and b/mseide-msegui/icons/components/tedit.png differ diff --git a/mseide-msegui/icons/components/tedit.svg b/mseide-msegui/icons/components/tedit.svg new file mode 100644 index 0000000..65885e2 --- /dev/null +++ b/mseide-msegui/icons/components/tedit.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenum64editdb.bmp b/mseide-msegui/icons/components/tenum64editdb.bmp new file mode 100644 index 0000000..dc686b4 Binary files /dev/null and b/mseide-msegui/icons/components/tenum64editdb.bmp differ diff --git a/mseide-msegui/icons/components/tenum64editdb.png b/mseide-msegui/icons/components/tenum64editdb.png new file mode 100644 index 0000000..472ad29 Binary files /dev/null and b/mseide-msegui/icons/components/tenum64editdb.png differ diff --git a/mseide-msegui/icons/components/tenum64editdb.svg b/mseide-msegui/icons/components/tenum64editdb.svg new file mode 100644 index 0000000..b876238 --- /dev/null +++ b/mseide-msegui/icons/components/tenum64editdb.svg @@ -0,0 +1,452 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenum64editlb.bmp b/mseide-msegui/icons/components/tenum64editlb.bmp new file mode 100644 index 0000000..51f2010 Binary files /dev/null and b/mseide-msegui/icons/components/tenum64editlb.bmp differ diff --git a/mseide-msegui/icons/components/tenum64editlb.png b/mseide-msegui/icons/components/tenum64editlb.png new file mode 100644 index 0000000..7457bb4 Binary files /dev/null and b/mseide-msegui/icons/components/tenum64editlb.png differ diff --git a/mseide-msegui/icons/components/tenum64editlb.svg b/mseide-msegui/icons/components/tenum64editlb.svg new file mode 100644 index 0000000..ec9c895 --- /dev/null +++ b/mseide-msegui/icons/components/tenum64editlb.svg @@ -0,0 +1,452 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenumedit.bmp b/mseide-msegui/icons/components/tenumedit.bmp new file mode 100755 index 0000000..18720d9 Binary files /dev/null and b/mseide-msegui/icons/components/tenumedit.bmp differ diff --git a/mseide-msegui/icons/components/tenumedit.png b/mseide-msegui/icons/components/tenumedit.png new file mode 100644 index 0000000..7e04ad8 Binary files /dev/null and b/mseide-msegui/icons/components/tenumedit.png differ diff --git a/mseide-msegui/icons/components/tenumedit.svg b/mseide-msegui/icons/components/tenumedit.svg new file mode 100644 index 0000000..2a1cb6d --- /dev/null +++ b/mseide-msegui/icons/components/tenumedit.svg @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenumeditdb.bmp b/mseide-msegui/icons/components/tenumeditdb.bmp new file mode 100644 index 0000000..1cd7341 Binary files /dev/null and b/mseide-msegui/icons/components/tenumeditdb.bmp differ diff --git a/mseide-msegui/icons/components/tenumeditdb.png b/mseide-msegui/icons/components/tenumeditdb.png new file mode 100644 index 0000000..6420648 Binary files /dev/null and b/mseide-msegui/icons/components/tenumeditdb.png differ diff --git a/mseide-msegui/icons/components/tenumeditdb.svg b/mseide-msegui/icons/components/tenumeditdb.svg new file mode 100644 index 0000000..a9a2357 --- /dev/null +++ b/mseide-msegui/icons/components/tenumeditdb.svg @@ -0,0 +1,445 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenumeditedit.png b/mseide-msegui/icons/components/tenumeditedit.png new file mode 100644 index 0000000..7e04ad8 Binary files /dev/null and b/mseide-msegui/icons/components/tenumeditedit.png differ diff --git a/mseide-msegui/icons/components/tenumeditlb.bmp b/mseide-msegui/icons/components/tenumeditlb.bmp new file mode 100644 index 0000000..82a6a53 Binary files /dev/null and b/mseide-msegui/icons/components/tenumeditlb.bmp differ diff --git a/mseide-msegui/icons/components/tenumeditlb.png b/mseide-msegui/icons/components/tenumeditlb.png new file mode 100644 index 0000000..5867181 Binary files /dev/null and b/mseide-msegui/icons/components/tenumeditlb.png differ diff --git a/mseide-msegui/icons/components/tenumeditlb.svg b/mseide-msegui/icons/components/tenumeditlb.svg new file mode 100644 index 0000000..f5dcbbe --- /dev/null +++ b/mseide-msegui/icons/components/tenumeditlb.svg @@ -0,0 +1,445 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenumtypeedit.bmp b/mseide-msegui/icons/components/tenumtypeedit.bmp new file mode 100644 index 0000000..d03e8f8 Binary files /dev/null and b/mseide-msegui/icons/components/tenumtypeedit.bmp differ diff --git a/mseide-msegui/icons/components/tenumtypeedit.png b/mseide-msegui/icons/components/tenumtypeedit.png new file mode 100644 index 0000000..9b934dc Binary files /dev/null and b/mseide-msegui/icons/components/tenumtypeedit.png differ diff --git a/mseide-msegui/icons/components/tenumtypeedit.svg b/mseide-msegui/icons/components/tenumtypeedit.svg new file mode 100644 index 0000000..ee82e09 --- /dev/null +++ b/mseide-msegui/icons/components/tenumtypeedit.svg @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenvelopeedit.png b/mseide-msegui/icons/components/tenvelopeedit.png new file mode 100644 index 0000000..50736d5 Binary files /dev/null and b/mseide-msegui/icons/components/tenvelopeedit.png differ diff --git a/mseide-msegui/icons/components/tenvelopeedit.svg b/mseide-msegui/icons/components/tenvelopeedit.svg new file mode 100644 index 0000000..d7dca31 --- /dev/null +++ b/mseide-msegui/icons/components/tenvelopeedit.svg @@ -0,0 +1,281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/test.bmp b/mseide-msegui/icons/components/test.bmp new file mode 100644 index 0000000..dadd96f Binary files /dev/null and b/mseide-msegui/icons/components/test.bmp differ diff --git a/mseide-msegui/icons/components/test.pnm b/mseide-msegui/icons/components/test.pnm new file mode 100644 index 0000000..5b065c9 Binary files /dev/null and b/mseide-msegui/icons/components/test.pnm differ diff --git a/mseide-msegui/icons/components/test.svg b/mseide-msegui/icons/components/test.svg new file mode 100644 index 0000000..e4d64df --- /dev/null +++ b/mseide-msegui/icons/components/test.svg @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + ABC + + diff --git a/mseide-msegui/icons/components/teventwidget.bmp b/mseide-msegui/icons/components/teventwidget.bmp new file mode 100755 index 0000000..4a55d7d Binary files /dev/null and b/mseide-msegui/icons/components/teventwidget.bmp differ diff --git a/mseide-msegui/icons/components/teventwidget.png b/mseide-msegui/icons/components/teventwidget.png new file mode 100644 index 0000000..2e6870a Binary files /dev/null and b/mseide-msegui/icons/components/teventwidget.png differ diff --git a/mseide-msegui/icons/components/teventwidget.svg b/mseide-msegui/icons/components/teventwidget.svg new file mode 100644 index 0000000..5664bf5 --- /dev/null +++ b/mseide-msegui/icons/components/teventwidget.svg @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/texpandingwidget.png b/mseide-msegui/icons/components/texpandingwidget.png new file mode 100644 index 0000000..667f90a Binary files /dev/null and b/mseide-msegui/icons/components/texpandingwidget.png differ diff --git a/mseide-msegui/icons/components/texpandingwidget.svg b/mseide-msegui/icons/components/texpandingwidget.svg new file mode 100644 index 0000000..f67d14c --- /dev/null +++ b/mseide-msegui/icons/components/texpandingwidget.svg @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/text3429.png b/mseide-msegui/icons/components/text3429.png new file mode 100644 index 0000000..a7a92d5 Binary files /dev/null and b/mseide-msegui/icons/components/text3429.png differ diff --git a/mseide-msegui/icons/components/tfacecomp.bmp b/mseide-msegui/icons/components/tfacecomp.bmp new file mode 100755 index 0000000..091add5 Binary files /dev/null and b/mseide-msegui/icons/components/tfacecomp.bmp differ diff --git a/mseide-msegui/icons/components/tfacecomp.png b/mseide-msegui/icons/components/tfacecomp.png new file mode 100644 index 0000000..ddd4b66 Binary files /dev/null and b/mseide-msegui/icons/components/tfacecomp.png differ diff --git a/mseide-msegui/icons/components/tfacecomp.svg b/mseide-msegui/icons/components/tfacecomp.svg new file mode 100644 index 0000000..1f80b96 --- /dev/null +++ b/mseide-msegui/icons/components/tfacecomp.svg @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfacelist.bmp b/mseide-msegui/icons/components/tfacelist.bmp new file mode 100644 index 0000000..e046aee Binary files /dev/null and b/mseide-msegui/icons/components/tfacelist.bmp differ diff --git a/mseide-msegui/icons/components/tfacelist.png b/mseide-msegui/icons/components/tfacelist.png new file mode 100644 index 0000000..27744c4 Binary files /dev/null and b/mseide-msegui/icons/components/tfacelist.png differ diff --git a/mseide-msegui/icons/components/tfacelist.svg b/mseide-msegui/icons/components/tfacelist.svg new file mode 100644 index 0000000..1c56313 --- /dev/null +++ b/mseide-msegui/icons/components/tfacelist.svg @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfb3connection.png b/mseide-msegui/icons/components/tfb3connection.png new file mode 100644 index 0000000..e77897a Binary files /dev/null and b/mseide-msegui/icons/components/tfb3connection.png differ diff --git a/mseide-msegui/icons/components/tfb3connection.svg b/mseide-msegui/icons/components/tfb3connection.svg new file mode 100644 index 0000000..9905800 --- /dev/null +++ b/mseide-msegui/icons/components/tfb3connection.svg @@ -0,0 +1,448 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + 3 + + diff --git a/mseide-msegui/icons/components/tfb3service.png b/mseide-msegui/icons/components/tfb3service.png new file mode 100644 index 0000000..a823178 Binary files /dev/null and b/mseide-msegui/icons/components/tfb3service.png differ diff --git a/mseide-msegui/icons/components/tfb3service.svg b/mseide-msegui/icons/components/tfb3service.svg new file mode 100644 index 0000000..0659b85 --- /dev/null +++ b/mseide-msegui/icons/components/tfb3service.svg @@ -0,0 +1,461 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + SERVICE + 3 + + diff --git a/mseide-msegui/icons/components/tfbconnection.png b/mseide-msegui/icons/components/tfbconnection.png new file mode 100644 index 0000000..8f61694 Binary files /dev/null and b/mseide-msegui/icons/components/tfbconnection.png differ diff --git a/mseide-msegui/icons/components/tfbconnection.svg b/mseide-msegui/icons/components/tfbconnection.svg new file mode 100644 index 0000000..28b6abf --- /dev/null +++ b/mseide-msegui/icons/components/tfbconnection.svg @@ -0,0 +1,446 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + 3 + + diff --git a/mseide-msegui/icons/components/tfbservice.png b/mseide-msegui/icons/components/tfbservice.png new file mode 100644 index 0000000..22de8af Binary files /dev/null and b/mseide-msegui/icons/components/tfbservice.png differ diff --git a/mseide-msegui/icons/components/tfbservice.svg b/mseide-msegui/icons/components/tfbservice.svg new file mode 100644 index 0000000..a7ac164 --- /dev/null +++ b/mseide-msegui/icons/components/tfbservice.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + SERVICE + + diff --git a/mseide-msegui/icons/components/tfft.png b/mseide-msegui/icons/components/tfft.png new file mode 100644 index 0000000..fcd8719 Binary files /dev/null and b/mseide-msegui/icons/components/tfft.png differ diff --git a/mseide-msegui/icons/components/tfft.svg b/mseide-msegui/icons/components/tfft.svg new file mode 100644 index 0000000..abfc508 --- /dev/null +++ b/mseide-msegui/icons/components/tfft.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + FFT + + + diff --git a/mseide-msegui/icons/components/tffttableedit.png b/mseide-msegui/icons/components/tffttableedit.png new file mode 100644 index 0000000..cd930ed Binary files /dev/null and b/mseide-msegui/icons/components/tffttableedit.png differ diff --git a/mseide-msegui/icons/components/tffttableedit.svg b/mseide-msegui/icons/components/tffttableedit.svg new file mode 100644 index 0000000..9eda11f --- /dev/null +++ b/mseide-msegui/icons/components/tffttableedit.svg @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfieldfieldlink.bmp b/mseide-msegui/icons/components/tfieldfieldlink.bmp new file mode 100644 index 0000000..9a38e2c Binary files /dev/null and b/mseide-msegui/icons/components/tfieldfieldlink.bmp differ diff --git a/mseide-msegui/icons/components/tfieldfieldlink.png b/mseide-msegui/icons/components/tfieldfieldlink.png new file mode 100644 index 0000000..f117fa8 Binary files /dev/null and b/mseide-msegui/icons/components/tfieldfieldlink.png differ diff --git a/mseide-msegui/icons/components/tfieldfieldlink.svg b/mseide-msegui/icons/components/tfieldfieldlink.svg new file mode 100644 index 0000000..958c8d6 --- /dev/null +++ b/mseide-msegui/icons/components/tfieldfieldlink.svg @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Fi + + + + + + FLD + + + + + + + diff --git a/mseide-msegui/icons/components/tfieldlink.bmp b/mseide-msegui/icons/components/tfieldlink.bmp new file mode 100644 index 0000000..965e299 Binary files /dev/null and b/mseide-msegui/icons/components/tfieldlink.bmp differ diff --git a/mseide-msegui/icons/components/tfieldlink.png b/mseide-msegui/icons/components/tfieldlink.png new file mode 100644 index 0000000..8641570 Binary files /dev/null and b/mseide-msegui/icons/components/tfieldlink.png differ diff --git a/mseide-msegui/icons/components/tfieldlink.svg b/mseide-msegui/icons/components/tfieldlink.svg new file mode 100644 index 0000000..b54e497 --- /dev/null +++ b/mseide-msegui/icons/components/tfieldlink.svg @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + VALFLD + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfieldparamlink.bmp b/mseide-msegui/icons/components/tfieldparamlink.bmp new file mode 100644 index 0000000..334c154 Binary files /dev/null and b/mseide-msegui/icons/components/tfieldparamlink.bmp differ diff --git a/mseide-msegui/icons/components/tfieldparamlink.png b/mseide-msegui/icons/components/tfieldparamlink.png new file mode 100644 index 0000000..4bfc26e Binary files /dev/null and b/mseide-msegui/icons/components/tfieldparamlink.png differ diff --git a/mseide-msegui/icons/components/tfieldparamlink.svg b/mseide-msegui/icons/components/tfieldparamlink.svg new file mode 100644 index 0000000..bd7940e --- /dev/null +++ b/mseide-msegui/icons/components/tfieldparamlink.svg @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Fi + + + + + + PAR + + + + + + + diff --git a/mseide-msegui/icons/components/tfilechangenotifier.png b/mseide-msegui/icons/components/tfilechangenotifier.png new file mode 100644 index 0000000..a41697c Binary files /dev/null and b/mseide-msegui/icons/components/tfilechangenotifier.png differ diff --git a/mseide-msegui/icons/components/tfilechangenotifier.svg b/mseide-msegui/icons/components/tfilechangenotifier.svg new file mode 100644 index 0000000..d9a5d1b --- /dev/null +++ b/mseide-msegui/icons/components/tfilechangenotifier.svg @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + *.* + + diff --git a/mseide-msegui/icons/components/tfilechangenotifyer.bmp b/mseide-msegui/icons/components/tfilechangenotifyer.bmp new file mode 100755 index 0000000..45dba18 Binary files /dev/null and b/mseide-msegui/icons/components/tfilechangenotifyer.bmp differ diff --git a/mseide-msegui/icons/components/tfilechangenotifyer.png b/mseide-msegui/icons/components/tfilechangenotifyer.png new file mode 100644 index 0000000..80fc30d Binary files /dev/null and b/mseide-msegui/icons/components/tfilechangenotifyer.png differ diff --git a/mseide-msegui/icons/components/tfilechangenotifyer.svg b/mseide-msegui/icons/components/tfilechangenotifyer.svg new file mode 100644 index 0000000..139e83a --- /dev/null +++ b/mseide-msegui/icons/components/tfilechangenotifyer.svg @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + *.* + + diff --git a/mseide-msegui/icons/components/tfiledialog.bmp b/mseide-msegui/icons/components/tfiledialog.bmp new file mode 100755 index 0000000..8a9a30f Binary files /dev/null and b/mseide-msegui/icons/components/tfiledialog.bmp differ diff --git a/mseide-msegui/icons/components/tfiledialog.png b/mseide-msegui/icons/components/tfiledialog.png new file mode 100644 index 0000000..3fa9584 Binary files /dev/null and b/mseide-msegui/icons/components/tfiledialog.png differ diff --git a/mseide-msegui/icons/components/tfiledialog.svg b/mseide-msegui/icons/components/tfiledialog.svg new file mode 100644 index 0000000..74b9e58 --- /dev/null +++ b/mseide-msegui/icons/components/tfiledialog.svg @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + Plioe + + + + + + + + diff --git a/mseide-msegui/icons/components/tfilelistview.bmp b/mseide-msegui/icons/components/tfilelistview.bmp new file mode 100755 index 0000000..af26c65 Binary files /dev/null and b/mseide-msegui/icons/components/tfilelistview.bmp differ diff --git a/mseide-msegui/icons/components/tfilelistview.png b/mseide-msegui/icons/components/tfilelistview.png new file mode 100644 index 0000000..cdb5469 Binary files /dev/null and b/mseide-msegui/icons/components/tfilelistview.png differ diff --git a/mseide-msegui/icons/components/tfilelistview.svg b/mseide-msegui/icons/components/tfilelistview.svg new file mode 100644 index 0000000..746babb --- /dev/null +++ b/mseide-msegui/icons/components/tfilelistview.svg @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + File + + + + + + + diff --git a/mseide-msegui/icons/components/tfilenameedit.bmp b/mseide-msegui/icons/components/tfilenameedit.bmp new file mode 100755 index 0000000..a9cba3e Binary files /dev/null and b/mseide-msegui/icons/components/tfilenameedit.bmp differ diff --git a/mseide-msegui/icons/components/tfilenameedit.png b/mseide-msegui/icons/components/tfilenameedit.png new file mode 100644 index 0000000..bc9c980 Binary files /dev/null and b/mseide-msegui/icons/components/tfilenameedit.png differ diff --git a/mseide-msegui/icons/components/tfilenameedit.svg b/mseide-msegui/icons/components/tfilenameedit.svg new file mode 100644 index 0000000..196aafd --- /dev/null +++ b/mseide-msegui/icons/components/tfilenameedit.svg @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfoldedit.png b/mseide-msegui/icons/components/tfoldedit.png new file mode 100644 index 0000000..fad8b54 Binary files /dev/null and b/mseide-msegui/icons/components/tfoldedit.png differ diff --git a/mseide-msegui/icons/components/tfoldedit.svg b/mseide-msegui/icons/components/tfoldedit.svg new file mode 100644 index 0000000..770b2d4 --- /dev/null +++ b/mseide-msegui/icons/components/tfoldedit.svg @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + ab + + + + + diff --git a/mseide-msegui/icons/components/tfontcomp.png b/mseide-msegui/icons/components/tfontcomp.png new file mode 100644 index 0000000..b69d3c9 Binary files /dev/null and b/mseide-msegui/icons/components/tfontcomp.png differ diff --git a/mseide-msegui/icons/components/tfontcomp.svg b/mseide-msegui/icons/components/tfontcomp.svg new file mode 100644 index 0000000..96874cb --- /dev/null +++ b/mseide-msegui/icons/components/tfontcomp.svg @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Fonttmpl + + diff --git a/mseide-msegui/icons/components/tformlink.bmp b/mseide-msegui/icons/components/tformlink.bmp new file mode 100644 index 0000000..ee7b24e Binary files /dev/null and b/mseide-msegui/icons/components/tformlink.bmp differ diff --git a/mseide-msegui/icons/components/tformwidget.bmp b/mseide-msegui/icons/components/tformwidget.bmp new file mode 100755 index 0000000..e6b9c74 Binary files /dev/null and b/mseide-msegui/icons/components/tformwidget.bmp differ diff --git a/mseide-msegui/icons/components/tframecomp.bmp b/mseide-msegui/icons/components/tframecomp.bmp new file mode 100755 index 0000000..686846d Binary files /dev/null and b/mseide-msegui/icons/components/tframecomp.bmp differ diff --git a/mseide-msegui/icons/components/tframecomp.png b/mseide-msegui/icons/components/tframecomp.png new file mode 100644 index 0000000..b298e37 Binary files /dev/null and b/mseide-msegui/icons/components/tframecomp.png differ diff --git a/mseide-msegui/icons/components/tframecomp.svg b/mseide-msegui/icons/components/tframecomp.svg new file mode 100644 index 0000000..10f893b --- /dev/null +++ b/mseide-msegui/icons/components/tframecomp.svg @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfunctableedit.png b/mseide-msegui/icons/components/tfunctableedit.png new file mode 100644 index 0000000..3d87103 Binary files /dev/null and b/mseide-msegui/icons/components/tfunctableedit.png differ diff --git a/mseide-msegui/icons/components/tfunctableedit.svg b/mseide-msegui/icons/components/tfunctableedit.svg new file mode 100644 index 0000000..f51da9f --- /dev/null +++ b/mseide-msegui/icons/components/tfunctableedit.svg @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfuncttableedit.png b/mseide-msegui/icons/components/tfuncttableedit.png new file mode 100644 index 0000000..d99016b Binary files /dev/null and b/mseide-msegui/icons/components/tfuncttableedit.png differ diff --git a/mseide-msegui/icons/components/tfuncttableedit.svg b/mseide-msegui/icons/components/tfuncttableedit.svg new file mode 100644 index 0000000..19e57b1 --- /dev/null +++ b/mseide-msegui/icons/components/tfuncttableedit.svg @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tgdbmi.bmp b/mseide-msegui/icons/components/tgdbmi.bmp new file mode 100755 index 0000000..3c90773 Binary files /dev/null and b/mseide-msegui/icons/components/tgdbmi.bmp differ diff --git a/mseide-msegui/icons/components/tgdiprinter.bmp b/mseide-msegui/icons/components/tgdiprinter.bmp new file mode 100644 index 0000000..d623004 Binary files /dev/null and b/mseide-msegui/icons/components/tgdiprinter.bmp differ diff --git a/mseide-msegui/icons/components/tgdiprinter.png b/mseide-msegui/icons/components/tgdiprinter.png new file mode 100644 index 0000000..176e28a Binary files /dev/null and b/mseide-msegui/icons/components/tgdiprinter.png differ diff --git a/mseide-msegui/icons/components/tgdiprinter.svg b/mseide-msegui/icons/components/tgdiprinter.svg new file mode 100644 index 0000000..ac2ff0c --- /dev/null +++ b/mseide-msegui/icons/components/tgdiprinter.svg @@ -0,0 +1,331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + GDI + + + + + + + + + + Poi Li + Poi oL + + + Poi + + + + diff --git a/mseide-msegui/icons/components/tgroupbox.bmp b/mseide-msegui/icons/components/tgroupbox.bmp new file mode 100755 index 0000000..31f2b0e Binary files /dev/null and b/mseide-msegui/icons/components/tgroupbox.bmp differ diff --git a/mseide-msegui/icons/components/tgroupbox.png b/mseide-msegui/icons/components/tgroupbox.png new file mode 100644 index 0000000..c1ec68e Binary files /dev/null and b/mseide-msegui/icons/components/tgroupbox.png differ diff --git a/mseide-msegui/icons/components/tgroupbox.svg b/mseide-msegui/icons/components/tgroupbox.svg new file mode 100644 index 0000000..d2e5e0c --- /dev/null +++ b/mseide-msegui/icons/components/tgroupbox.svg @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + Ruio + + + diff --git a/mseide-msegui/icons/components/tguiprocess.png b/mseide-msegui/icons/components/tguiprocess.png new file mode 100644 index 0000000..8456c4a Binary files /dev/null and b/mseide-msegui/icons/components/tguiprocess.png differ diff --git a/mseide-msegui/icons/components/tguiprocess.svg b/mseide-msegui/icons/components/tguiprocess.svg new file mode 100644 index 0000000..897ffa6 --- /dev/null +++ b/mseide-msegui/icons/components/tguiprocess.svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Proc + + diff --git a/mseide-msegui/icons/components/tguirttistat.png b/mseide-msegui/icons/components/tguirttistat.png new file mode 100644 index 0000000..2883417 Binary files /dev/null and b/mseide-msegui/icons/components/tguirttistat.png differ diff --git a/mseide-msegui/icons/components/tguirttistat.svg b/mseide-msegui/icons/components/tguirttistat.svg new file mode 100644 index 0000000..a7b7b90 --- /dev/null +++ b/mseide-msegui/icons/components/tguirttistat.svg @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + *.sta + + diff --git a/mseide-msegui/icons/components/tguithreadcomp.bmp b/mseide-msegui/icons/components/tguithreadcomp.bmp new file mode 100644 index 0000000..ccfd293 Binary files /dev/null and b/mseide-msegui/icons/components/tguithreadcomp.bmp differ diff --git a/mseide-msegui/icons/components/tguithreadcomp.png b/mseide-msegui/icons/components/tguithreadcomp.png new file mode 100644 index 0000000..b92b2a0 Binary files /dev/null and b/mseide-msegui/icons/components/tguithreadcomp.png differ diff --git a/mseide-msegui/icons/components/tguithreadcomp.svg b/mseide-msegui/icons/components/tguithreadcomp.svg new file mode 100644 index 0000000..f72e64f --- /dev/null +++ b/mseide-msegui/icons/components/tguithreadcomp.svg @@ -0,0 +1,491 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/thelpcontroller.png b/mseide-msegui/icons/components/thelpcontroller.png new file mode 100644 index 0000000..97801b9 Binary files /dev/null and b/mseide-msegui/icons/components/thelpcontroller.png differ diff --git a/mseide-msegui/icons/components/thelpcontroller.svg b/mseide-msegui/icons/components/thelpcontroller.svg new file mode 100644 index 0000000..852af5a --- /dev/null +++ b/mseide-msegui/icons/components/thelpcontroller.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Help + + diff --git a/mseide-msegui/icons/components/thexstringedit.bmp b/mseide-msegui/icons/components/thexstringedit.bmp new file mode 100644 index 0000000..54b0945 Binary files /dev/null and b/mseide-msegui/icons/components/thexstringedit.bmp differ diff --git a/mseide-msegui/icons/components/thexstringedit.png b/mseide-msegui/icons/components/thexstringedit.png new file mode 100644 index 0000000..d161050 Binary files /dev/null and b/mseide-msegui/icons/components/thexstringedit.png differ diff --git a/mseide-msegui/icons/components/thexstringedit.svg b/mseide-msegui/icons/components/thexstringedit.svg new file mode 100644 index 0000000..6004f2f --- /dev/null +++ b/mseide-msegui/icons/components/thexstringedit.svg @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/thistoryedit.bmp b/mseide-msegui/icons/components/thistoryedit.bmp new file mode 100644 index 0000000..9e8b200 Binary files /dev/null and b/mseide-msegui/icons/components/thistoryedit.bmp differ diff --git a/mseide-msegui/icons/components/thistoryedit.png b/mseide-msegui/icons/components/thistoryedit.png new file mode 100644 index 0000000..a935d61 Binary files /dev/null and b/mseide-msegui/icons/components/thistoryedit.png differ diff --git a/mseide-msegui/icons/components/thistoryedit.svg b/mseide-msegui/icons/components/thistoryedit.svg new file mode 100644 index 0000000..b42da5c --- /dev/null +++ b/mseide-msegui/icons/components/thistoryedit.svg @@ -0,0 +1,447 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/thread.bmp b/mseide-msegui/icons/components/thread.bmp new file mode 100644 index 0000000..ba644d8 Binary files /dev/null and b/mseide-msegui/icons/components/thread.bmp differ diff --git a/mseide-msegui/icons/components/ticon.png b/mseide-msegui/icons/components/ticon.png new file mode 100644 index 0000000..6566d83 Binary files /dev/null and b/mseide-msegui/icons/components/ticon.png differ diff --git a/mseide-msegui/icons/components/ticon.svg b/mseide-msegui/icons/components/ticon.svg new file mode 100644 index 0000000..dcc4099 --- /dev/null +++ b/mseide-msegui/icons/components/ticon.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifiactionendpoint.png b/mseide-msegui/icons/components/tifiactionendpoint.png new file mode 100644 index 0000000..53c61bd Binary files /dev/null and b/mseide-msegui/icons/components/tifiactionendpoint.png differ diff --git a/mseide-msegui/icons/components/tifiactionendpoint.svg b/mseide-msegui/icons/components/tifiactionendpoint.svg new file mode 100644 index 0000000..cfd7c82 --- /dev/null +++ b/mseide-msegui/icons/components/tifiactionendpoint.svg @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifiactionlinkcomp.png b/mseide-msegui/icons/components/tifiactionlinkcomp.png new file mode 100644 index 0000000..54fa488 Binary files /dev/null and b/mseide-msegui/icons/components/tifiactionlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifiactionlinkcomp.svg b/mseide-msegui/icons/components/tifiactionlinkcomp.svg new file mode 100644 index 0000000..c7d46ae --- /dev/null +++ b/mseide-msegui/icons/components/tifiactionlinkcomp.svg @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifibooleanendpoint.png b/mseide-msegui/icons/components/tifibooleanendpoint.png new file mode 100644 index 0000000..9b3fc2e Binary files /dev/null and b/mseide-msegui/icons/components/tifibooleanendpoint.png differ diff --git a/mseide-msegui/icons/components/tifibooleanendpoint.svg b/mseide-msegui/icons/components/tifibooleanendpoint.svg new file mode 100644 index 0000000..23091a9 --- /dev/null +++ b/mseide-msegui/icons/components/tifibooleanendpoint.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + T/F + + diff --git a/mseide-msegui/icons/components/tifibooleanlinkcomp.png b/mseide-msegui/icons/components/tifibooleanlinkcomp.png new file mode 100644 index 0000000..df83265 Binary files /dev/null and b/mseide-msegui/icons/components/tifibooleanlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifibooleanlinkcomp.svg b/mseide-msegui/icons/components/tifibooleanlinkcomp.svg new file mode 100644 index 0000000..2166c67 --- /dev/null +++ b/mseide-msegui/icons/components/tifibooleanlinkcomp.svg @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + T/F + + diff --git a/mseide-msegui/icons/components/tifidatetimeendpoint.png b/mseide-msegui/icons/components/tifidatetimeendpoint.png new file mode 100644 index 0000000..2f18dcb Binary files /dev/null and b/mseide-msegui/icons/components/tifidatetimeendpoint.png differ diff --git a/mseide-msegui/icons/components/tifidatetimeendpoint.svg b/mseide-msegui/icons/components/tifidatetimeendpoint.svg new file mode 100644 index 0000000..f8b9bb0 --- /dev/null +++ b/mseide-msegui/icons/components/tifidatetimeendpoint.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + D:T + + + + diff --git a/mseide-msegui/icons/components/tifidatetimelinkcomp.png b/mseide-msegui/icons/components/tifidatetimelinkcomp.png new file mode 100644 index 0000000..556e700 Binary files /dev/null and b/mseide-msegui/icons/components/tifidatetimelinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifidatetimelinkcomp.svg b/mseide-msegui/icons/components/tifidatetimelinkcomp.svg new file mode 100644 index 0000000..bab8357 --- /dev/null +++ b/mseide-msegui/icons/components/tifidatetimelinkcomp.svg @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + D:T + + + + + diff --git a/mseide-msegui/icons/components/tifidialog.png b/mseide-msegui/icons/components/tifidialog.png new file mode 100644 index 0000000..4293f3c Binary files /dev/null and b/mseide-msegui/icons/components/tifidialog.png differ diff --git a/mseide-msegui/icons/components/tifidialog.svg b/mseide-msegui/icons/components/tifidialog.svg new file mode 100644 index 0000000..9c6acba --- /dev/null +++ b/mseide-msegui/icons/components/tifidialog.svg @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Dialog + + + + diff --git a/mseide-msegui/icons/components/tifidialogendpoint.png b/mseide-msegui/icons/components/tifidialogendpoint.png new file mode 100644 index 0000000..c0698be Binary files /dev/null and b/mseide-msegui/icons/components/tifidialogendpoint.png differ diff --git a/mseide-msegui/icons/components/tifidialogendpoint.svg b/mseide-msegui/icons/components/tifidialogendpoint.svg new file mode 100644 index 0000000..346b86d --- /dev/null +++ b/mseide-msegui/icons/components/tifidialogendpoint.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Dialog + + + + diff --git a/mseide-msegui/icons/components/tifidialoglinkcomp.png b/mseide-msegui/icons/components/tifidialoglinkcomp.png new file mode 100644 index 0000000..8548999 Binary files /dev/null and b/mseide-msegui/icons/components/tifidialoglinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifidialoglinkcomp.svg b/mseide-msegui/icons/components/tifidialoglinkcomp.svg new file mode 100644 index 0000000..967b8d0 --- /dev/null +++ b/mseide-msegui/icons/components/tifidialoglinkcomp.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Dialog + + + + + diff --git a/mseide-msegui/icons/components/tifidropdownendpoint.png b/mseide-msegui/icons/components/tifidropdownendpoint.png new file mode 100644 index 0000000..2ca8111 Binary files /dev/null and b/mseide-msegui/icons/components/tifidropdownendpoint.png differ diff --git a/mseide-msegui/icons/components/tifidropdownendpoint.svg b/mseide-msegui/icons/components/tifidropdownendpoint.svg new file mode 100644 index 0000000..f7cbc30 --- /dev/null +++ b/mseide-msegui/icons/components/tifidropdownendpoint.svg @@ -0,0 +1,483 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifidropdownlistlinkcomp.png b/mseide-msegui/icons/components/tifidropdownlistlinkcomp.png new file mode 100644 index 0000000..8429b03 Binary files /dev/null and b/mseide-msegui/icons/components/tifidropdownlistlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifidropdownlistlinkcomp.svg b/mseide-msegui/icons/components/tifidropdownlistlinkcomp.svg new file mode 100644 index 0000000..b740ac1 --- /dev/null +++ b/mseide-msegui/icons/components/tifidropdownlistlinkcomp.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + DdLi + + diff --git a/mseide-msegui/icons/components/tifienumendpoint.png b/mseide-msegui/icons/components/tifienumendpoint.png new file mode 100644 index 0000000..ce6ef46 Binary files /dev/null and b/mseide-msegui/icons/components/tifienumendpoint.png differ diff --git a/mseide-msegui/icons/components/tifienumendpoint.svg b/mseide-msegui/icons/components/tifienumendpoint.svg new file mode 100644 index 0000000..f194410 --- /dev/null +++ b/mseide-msegui/icons/components/tifienumendpoint.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + Enu + + diff --git a/mseide-msegui/icons/components/tifienumlinkcomp.png b/mseide-msegui/icons/components/tifienumlinkcomp.png new file mode 100644 index 0000000..f28be41 Binary files /dev/null and b/mseide-msegui/icons/components/tifienumlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifienumlinkcomp.svg b/mseide-msegui/icons/components/tifienumlinkcomp.svg new file mode 100644 index 0000000..acf088f --- /dev/null +++ b/mseide-msegui/icons/components/tifienumlinkcomp.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + Enu + + diff --git a/mseide-msegui/icons/components/tififormlinkcomp.png b/mseide-msegui/icons/components/tififormlinkcomp.png new file mode 100644 index 0000000..ff671e0 Binary files /dev/null and b/mseide-msegui/icons/components/tififormlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tififormlinkcomp.svg b/mseide-msegui/icons/components/tififormlinkcomp.svg new file mode 100644 index 0000000..dbd423b --- /dev/null +++ b/mseide-msegui/icons/components/tififormlinkcomp.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Form + + + + + diff --git a/mseide-msegui/icons/components/tifigridlinkcomp.png b/mseide-msegui/icons/components/tifigridlinkcomp.png new file mode 100644 index 0000000..228bd2c Binary files /dev/null and b/mseide-msegui/icons/components/tifigridlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifigridlinkcomp.svg b/mseide-msegui/icons/components/tifigridlinkcomp.svg new file mode 100644 index 0000000..03a0fbe --- /dev/null +++ b/mseide-msegui/icons/components/tifigridlinkcomp.svg @@ -0,0 +1,459 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + 123 + 78 + 00 + 233 + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifigtidlinkcomp.png b/mseide-msegui/icons/components/tifigtidlinkcomp.png new file mode 100644 index 0000000..e8e07e9 Binary files /dev/null and b/mseide-msegui/icons/components/tifigtidlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifiint64endpoint.png b/mseide-msegui/icons/components/tifiint64endpoint.png new file mode 100644 index 0000000..8ce4301 Binary files /dev/null and b/mseide-msegui/icons/components/tifiint64endpoint.png differ diff --git a/mseide-msegui/icons/components/tifiint64endpoint.svg b/mseide-msegui/icons/components/tifiint64endpoint.svg new file mode 100644 index 0000000..3e17d1d --- /dev/null +++ b/mseide-msegui/icons/components/tifiint64endpoint.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 64 + + + + diff --git a/mseide-msegui/icons/components/tifiint64linkcomp.png b/mseide-msegui/icons/components/tifiint64linkcomp.png new file mode 100644 index 0000000..a5ae19b Binary files /dev/null and b/mseide-msegui/icons/components/tifiint64linkcomp.png differ diff --git a/mseide-msegui/icons/components/tifiint64linkcomp.svg b/mseide-msegui/icons/components/tifiint64linkcomp.svg new file mode 100644 index 0000000..ba1cd35 --- /dev/null +++ b/mseide-msegui/icons/components/tifiint64linkcomp.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 64 + + + + + diff --git a/mseide-msegui/icons/components/tifiintegerendpoint.png b/mseide-msegui/icons/components/tifiintegerendpoint.png new file mode 100644 index 0000000..40b77b2 Binary files /dev/null and b/mseide-msegui/icons/components/tifiintegerendpoint.png differ diff --git a/mseide-msegui/icons/components/tifiintegerendpoint.svg b/mseide-msegui/icons/components/tifiintegerendpoint.svg new file mode 100644 index 0000000..663809f --- /dev/null +++ b/mseide-msegui/icons/components/tifiintegerendpoint.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 123 + + + + diff --git a/mseide-msegui/icons/components/tifiintegerlinkcomp.png b/mseide-msegui/icons/components/tifiintegerlinkcomp.png new file mode 100644 index 0000000..dad22a9 Binary files /dev/null and b/mseide-msegui/icons/components/tifiintegerlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifiintegerlinkcomp.svg b/mseide-msegui/icons/components/tifiintegerlinkcomp.svg new file mode 100644 index 0000000..9b354e0 --- /dev/null +++ b/mseide-msegui/icons/components/tifiintegerlinkcomp.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 123 + + + + + diff --git a/mseide-msegui/icons/components/tifiitemlinkcomp.png b/mseide-msegui/icons/components/tifiitemlinkcomp.png new file mode 100644 index 0000000..fd7186a Binary files /dev/null and b/mseide-msegui/icons/components/tifiitemlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifiitemlinkcomp.svg b/mseide-msegui/icons/components/tifiitemlinkcomp.svg new file mode 100644 index 0000000..e17917e --- /dev/null +++ b/mseide-msegui/icons/components/tifiitemlinkcomp.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Item + + + + + diff --git a/mseide-msegui/icons/components/tifilinkcomp.png b/mseide-msegui/icons/components/tifilinkcomp.png new file mode 100644 index 0000000..998432f Binary files /dev/null and b/mseide-msegui/icons/components/tifilinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifilinkcomp.svg b/mseide-msegui/icons/components/tifilinkcomp.svg new file mode 100644 index 0000000..8fe9cf8 --- /dev/null +++ b/mseide-msegui/icons/components/tifilinkcomp.svg @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + IfIlnk + + diff --git a/mseide-msegui/icons/components/tifipointerendpoint.png b/mseide-msegui/icons/components/tifipointerendpoint.png new file mode 100644 index 0000000..df0e1d3 Binary files /dev/null and b/mseide-msegui/icons/components/tifipointerendpoint.png differ diff --git a/mseide-msegui/icons/components/tifipointerendpoint.svg b/mseide-msegui/icons/components/tifipointerendpoint.svg new file mode 100644 index 0000000..2ded721 --- /dev/null +++ b/mseide-msegui/icons/components/tifipointerendpoint.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Po + + + + diff --git a/mseide-msegui/icons/components/tifipointerlinkcomp.png b/mseide-msegui/icons/components/tifipointerlinkcomp.png new file mode 100644 index 0000000..8c1984a Binary files /dev/null and b/mseide-msegui/icons/components/tifipointerlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifipointerlinkcomp.svg b/mseide-msegui/icons/components/tifipointerlinkcomp.svg new file mode 100644 index 0000000..24106be --- /dev/null +++ b/mseide-msegui/icons/components/tifipointerlinkcomp.svg @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Po + + + + + diff --git a/mseide-msegui/icons/components/tifirealendpoint.png b/mseide-msegui/icons/components/tifirealendpoint.png new file mode 100644 index 0000000..3efbfa3 Binary files /dev/null and b/mseide-msegui/icons/components/tifirealendpoint.png differ diff --git a/mseide-msegui/icons/components/tifirealendpoint.svg b/mseide-msegui/icons/components/tifirealendpoint.svg new file mode 100644 index 0000000..3cb0792 --- /dev/null +++ b/mseide-msegui/icons/components/tifirealendpoint.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 1.00 + + + + diff --git a/mseide-msegui/icons/components/tifireallinkcomp.png b/mseide-msegui/icons/components/tifireallinkcomp.png new file mode 100644 index 0000000..d88b13b Binary files /dev/null and b/mseide-msegui/icons/components/tifireallinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifireallinkcomp.svg b/mseide-msegui/icons/components/tifireallinkcomp.svg new file mode 100644 index 0000000..761ef2d --- /dev/null +++ b/mseide-msegui/icons/components/tifireallinkcomp.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 1.00 + + + + + diff --git a/mseide-msegui/icons/components/tifisqlresult.png b/mseide-msegui/icons/components/tifisqlresult.png new file mode 100644 index 0000000..c2c898e Binary files /dev/null and b/mseide-msegui/icons/components/tifisqlresult.png differ diff --git a/mseide-msegui/icons/components/tifisqlresult.svg b/mseide-msegui/icons/components/tifisqlresult.svg new file mode 100644 index 0000000..dae8e87 --- /dev/null +++ b/mseide-msegui/icons/components/tifisqlresult.svg @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifistringendpoint.png b/mseide-msegui/icons/components/tifistringendpoint.png new file mode 100644 index 0000000..be47f22 Binary files /dev/null and b/mseide-msegui/icons/components/tifistringendpoint.png differ diff --git a/mseide-msegui/icons/components/tifistringendpoint.svg b/mseide-msegui/icons/components/tifistringendpoint.svg new file mode 100644 index 0000000..9df7046 --- /dev/null +++ b/mseide-msegui/icons/components/tifistringendpoint.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + ABC + + + + diff --git a/mseide-msegui/icons/components/tifistringlinkcomp.png b/mseide-msegui/icons/components/tifistringlinkcomp.png new file mode 100644 index 0000000..9938632 Binary files /dev/null and b/mseide-msegui/icons/components/tifistringlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifistringlinkcomp.svg b/mseide-msegui/icons/components/tifistringlinkcomp.svg new file mode 100644 index 0000000..a995169 --- /dev/null +++ b/mseide-msegui/icons/components/tifistringlinkcomp.svg @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + ABC + + diff --git a/mseide-msegui/icons/components/tifitreeitemlinkcomp.png b/mseide-msegui/icons/components/tifitreeitemlinkcomp.png new file mode 100644 index 0000000..90192e2 Binary files /dev/null and b/mseide-msegui/icons/components/tifitreeitemlinkcomp.png differ diff --git a/mseide-msegui/icons/components/tifitreeitemlinkcomp.svg b/mseide-msegui/icons/components/tifitreeitemlinkcomp.svg new file mode 100644 index 0000000..79cfa43 --- /dev/null +++ b/mseide-msegui/icons/components/tifitreeitemlinkcomp.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Tree + + + + + diff --git a/mseide-msegui/icons/components/timage.bmp b/mseide-msegui/icons/components/timage.bmp new file mode 100755 index 0000000..bbb38df Binary files /dev/null and b/mseide-msegui/icons/components/timage.bmp differ diff --git a/mseide-msegui/icons/components/timage.png b/mseide-msegui/icons/components/timage.png new file mode 100644 index 0000000..679850c Binary files /dev/null and b/mseide-msegui/icons/components/timage.png differ diff --git a/mseide-msegui/icons/components/timage.svg b/mseide-msegui/icons/components/timage.svg new file mode 100644 index 0000000..39ae161 --- /dev/null +++ b/mseide-msegui/icons/components/timage.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/timagelist.bmp b/mseide-msegui/icons/components/timagelist.bmp new file mode 100755 index 0000000..a063f1e Binary files /dev/null and b/mseide-msegui/icons/components/timagelist.bmp differ diff --git a/mseide-msegui/icons/components/timagelist.png b/mseide-msegui/icons/components/timagelist.png new file mode 100644 index 0000000..88bf105 Binary files /dev/null and b/mseide-msegui/icons/components/timagelist.png differ diff --git a/mseide-msegui/icons/components/timagelist.svg b/mseide-msegui/icons/components/timagelist.svg new file mode 100644 index 0000000..5e2d417 --- /dev/null +++ b/mseide-msegui/icons/components/timagelist.svg @@ -0,0 +1,498 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tint64disp.png b/mseide-msegui/icons/components/tint64disp.png new file mode 100644 index 0000000..0ca8f38 Binary files /dev/null and b/mseide-msegui/icons/components/tint64disp.png differ diff --git a/mseide-msegui/icons/components/tint64disp.svg b/mseide-msegui/icons/components/tint64disp.svg new file mode 100644 index 0000000..5cfadb8 --- /dev/null +++ b/mseide-msegui/icons/components/tint64disp.svg @@ -0,0 +1,381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 64 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tint64edit.png b/mseide-msegui/icons/components/tint64edit.png new file mode 100644 index 0000000..15f76f9 Binary files /dev/null and b/mseide-msegui/icons/components/tint64edit.png differ diff --git a/mseide-msegui/icons/components/tint64edit.svg b/mseide-msegui/icons/components/tint64edit.svg new file mode 100644 index 0000000..ca09dac --- /dev/null +++ b/mseide-msegui/icons/components/tint64edit.svg @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + 64 + + diff --git a/mseide-msegui/icons/components/tintegerdisp.bmp b/mseide-msegui/icons/components/tintegerdisp.bmp new file mode 100755 index 0000000..a7e150b Binary files /dev/null and b/mseide-msegui/icons/components/tintegerdisp.bmp differ diff --git a/mseide-msegui/icons/components/tintegerdisp.png b/mseide-msegui/icons/components/tintegerdisp.png new file mode 100644 index 0000000..a40b26f Binary files /dev/null and b/mseide-msegui/icons/components/tintegerdisp.png differ diff --git a/mseide-msegui/icons/components/tintegerdisp.svg b/mseide-msegui/icons/components/tintegerdisp.svg new file mode 100644 index 0000000..bf0045c --- /dev/null +++ b/mseide-msegui/icons/components/tintegerdisp.svg @@ -0,0 +1,380 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 123 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tintegeredit.bmp b/mseide-msegui/icons/components/tintegeredit.bmp new file mode 100755 index 0000000..737efa8 Binary files /dev/null and b/mseide-msegui/icons/components/tintegeredit.bmp differ diff --git a/mseide-msegui/icons/components/tintegeredit.png b/mseide-msegui/icons/components/tintegeredit.png new file mode 100644 index 0000000..7a8ce5f Binary files /dev/null and b/mseide-msegui/icons/components/tintegeredit.png differ diff --git a/mseide-msegui/icons/components/tintegeredit.svg b/mseide-msegui/icons/components/tintegeredit.svg new file mode 100644 index 0000000..bdc19af --- /dev/null +++ b/mseide-msegui/icons/components/tintegeredit.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/titemedit.bmp b/mseide-msegui/icons/components/titemedit.bmp new file mode 100644 index 0000000..4f7ebec Binary files /dev/null and b/mseide-msegui/icons/components/titemedit.bmp differ diff --git a/mseide-msegui/icons/components/titemedit.png b/mseide-msegui/icons/components/titemedit.png new file mode 100644 index 0000000..8930959 Binary files /dev/null and b/mseide-msegui/icons/components/titemedit.png differ diff --git a/mseide-msegui/icons/components/titemedit.svg b/mseide-msegui/icons/components/titemedit.svg new file mode 100644 index 0000000..11317c5 --- /dev/null +++ b/mseide-msegui/icons/components/titemedit.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tkeystringcontainer.png b/mseide-msegui/icons/components/tkeystringcontainer.png new file mode 100644 index 0000000..4cdcab8 Binary files /dev/null and b/mseide-msegui/icons/components/tkeystringcontainer.png differ diff --git a/mseide-msegui/icons/components/tkeystringcontainer.svg b/mseide-msegui/icons/components/tkeystringcontainer.svg new file mode 100644 index 0000000..7e35be4 --- /dev/null +++ b/mseide-msegui/icons/components/tkeystringcontainer.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Kstr1Kstr2 + + diff --git a/mseide-msegui/icons/components/tkeystringedit.bmp b/mseide-msegui/icons/components/tkeystringedit.bmp new file mode 100644 index 0000000..42765c7 Binary files /dev/null and b/mseide-msegui/icons/components/tkeystringedit.bmp differ diff --git a/mseide-msegui/icons/components/tkeystringedit.png b/mseide-msegui/icons/components/tkeystringedit.png new file mode 100644 index 0000000..720f970 Binary files /dev/null and b/mseide-msegui/icons/components/tkeystringedit.png differ diff --git a/mseide-msegui/icons/components/tkeystringedit.svg b/mseide-msegui/icons/components/tkeystringedit.svg new file mode 100644 index 0000000..a548f72 --- /dev/null +++ b/mseide-msegui/icons/components/tkeystringedit.svg @@ -0,0 +1,442 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tkeystringeditdb.bmp b/mseide-msegui/icons/components/tkeystringeditdb.bmp new file mode 100644 index 0000000..a9484bb Binary files /dev/null and b/mseide-msegui/icons/components/tkeystringeditdb.bmp differ diff --git a/mseide-msegui/icons/components/tkeystringeditdb.png b/mseide-msegui/icons/components/tkeystringeditdb.png new file mode 100644 index 0000000..23d7198 Binary files /dev/null and b/mseide-msegui/icons/components/tkeystringeditdb.png differ diff --git a/mseide-msegui/icons/components/tkeystringeditdb.svg b/mseide-msegui/icons/components/tkeystringeditdb.svg new file mode 100644 index 0000000..61e2df9 --- /dev/null +++ b/mseide-msegui/icons/components/tkeystringeditdb.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tkeystringeditlb.bmp b/mseide-msegui/icons/components/tkeystringeditlb.bmp new file mode 100644 index 0000000..2f9421c Binary files /dev/null and b/mseide-msegui/icons/components/tkeystringeditlb.bmp differ diff --git a/mseide-msegui/icons/components/tkeystringeditlb.png b/mseide-msegui/icons/components/tkeystringeditlb.png new file mode 100644 index 0000000..c89393a Binary files /dev/null and b/mseide-msegui/icons/components/tkeystringeditlb.png differ diff --git a/mseide-msegui/icons/components/tkeystringeditlb.svg b/mseide-msegui/icons/components/tkeystringeditlb.svg new file mode 100644 index 0000000..ff9b967 --- /dev/null +++ b/mseide-msegui/icons/components/tkeystringeditlb.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tlabel.bmp b/mseide-msegui/icons/components/tlabel.bmp new file mode 100755 index 0000000..936d204 Binary files /dev/null and b/mseide-msegui/icons/components/tlabel.bmp differ diff --git a/mseide-msegui/icons/components/tlabel.png b/mseide-msegui/icons/components/tlabel.png new file mode 100644 index 0000000..3317d21 Binary files /dev/null and b/mseide-msegui/icons/components/tlabel.png differ diff --git a/mseide-msegui/icons/components/tlabel.svg b/mseide-msegui/icons/components/tlabel.svg new file mode 100644 index 0000000..d479a49 --- /dev/null +++ b/mseide-msegui/icons/components/tlabel.svg @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + A + + + + + diff --git a/mseide-msegui/icons/components/tlayouter.bmp b/mseide-msegui/icons/components/tlayouter.bmp new file mode 100644 index 0000000..7f1fb49 Binary files /dev/null and b/mseide-msegui/icons/components/tlayouter.bmp differ diff --git a/mseide-msegui/icons/components/tlayouter.png b/mseide-msegui/icons/components/tlayouter.png new file mode 100644 index 0000000..9f8af9d Binary files /dev/null and b/mseide-msegui/icons/components/tlayouter.png differ diff --git a/mseide-msegui/icons/components/tlayouter.svg b/mseide-msegui/icons/components/tlayouter.svg new file mode 100644 index 0000000..32e0d74 --- /dev/null +++ b/mseide-msegui/icons/components/tlayouter.svg @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tlistview.bmp b/mseide-msegui/icons/components/tlistview.bmp new file mode 100755 index 0000000..8d666b1 Binary files /dev/null and b/mseide-msegui/icons/components/tlistview.bmp differ diff --git a/mseide-msegui/icons/components/tlistview.png b/mseide-msegui/icons/components/tlistview.png new file mode 100644 index 0000000..eea0d7c Binary files /dev/null and b/mseide-msegui/icons/components/tlistview.png differ diff --git a/mseide-msegui/icons/components/tlistview.svg b/mseide-msegui/icons/components/tlistview.svg new file mode 100644 index 0000000..69e0067 --- /dev/null +++ b/mseide-msegui/icons/components/tlistview.svg @@ -0,0 +1,555 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Oeps- + Lukip + + + Poli-ui + Wio-l + + diff --git a/mseide-msegui/icons/components/tlocaldataset.png b/mseide-msegui/icons/components/tlocaldataset.png new file mode 100644 index 0000000..289cc4a Binary files /dev/null and b/mseide-msegui/icons/components/tlocaldataset.png differ diff --git a/mseide-msegui/icons/components/tlocaldataset.svg b/mseide-msegui/icons/components/tlocaldataset.svg new file mode 100644 index 0000000..78eacc0 --- /dev/null +++ b/mseide-msegui/icons/components/tlocaldataset.svg @@ -0,0 +1,447 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tlookupbuffer.bmp b/mseide-msegui/icons/components/tlookupbuffer.bmp new file mode 100644 index 0000000..599e343 Binary files /dev/null and b/mseide-msegui/icons/components/tlookupbuffer.bmp differ diff --git a/mseide-msegui/icons/components/tlookupbuffer.png b/mseide-msegui/icons/components/tlookupbuffer.png new file mode 100644 index 0000000..6f05e6a Binary files /dev/null and b/mseide-msegui/icons/components/tlookupbuffer.png differ diff --git a/mseide-msegui/icons/components/tmainmenu.bmp b/mseide-msegui/icons/components/tmainmenu.bmp new file mode 100755 index 0000000..e57b7c0 Binary files /dev/null and b/mseide-msegui/icons/components/tmainmenu.bmp differ diff --git a/mseide-msegui/icons/components/tmainmenu.png b/mseide-msegui/icons/components/tmainmenu.png new file mode 100644 index 0000000..008fdd3 Binary files /dev/null and b/mseide-msegui/icons/components/tmainmenu.png differ diff --git a/mseide-msegui/icons/components/tmainmenu.svg b/mseide-msegui/icons/components/tmainmenu.svg new file mode 100644 index 0000000..b93f7c1 --- /dev/null +++ b/mseide-msegui/icons/components/tmainmenu.svg @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + File + Aitt + View + + + Zuio + + + + + Przio + Iklaba + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmainmenuwidget.bmp b/mseide-msegui/icons/components/tmainmenuwidget.bmp new file mode 100644 index 0000000..b2206f6 Binary files /dev/null and b/mseide-msegui/icons/components/tmainmenuwidget.bmp differ diff --git a/mseide-msegui/icons/components/tmainmenuwidget.png b/mseide-msegui/icons/components/tmainmenuwidget.png new file mode 100644 index 0000000..9b7bac2 Binary files /dev/null and b/mseide-msegui/icons/components/tmainmenuwidget.png differ diff --git a/mseide-msegui/icons/components/tmainmenuwidget.svg b/mseide-msegui/icons/components/tmainmenuwidget.svg new file mode 100644 index 0000000..5f22735 --- /dev/null +++ b/mseide-msegui/icons/components/tmainmenuwidget.svg @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + File + Aitt + View + + + Zuio + + + + + Przio + Iklaba + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmbdropdownitemedit.bmp b/mseide-msegui/icons/components/tmbdropdownitemedit.bmp new file mode 100644 index 0000000..3ecf11e Binary files /dev/null and b/mseide-msegui/icons/components/tmbdropdownitemedit.bmp differ diff --git a/mseide-msegui/icons/components/tmbdropdownitemedit.png b/mseide-msegui/icons/components/tmbdropdownitemedit.png new file mode 100644 index 0000000..62e4cc1 Binary files /dev/null and b/mseide-msegui/icons/components/tmbdropdownitemedit.png differ diff --git a/mseide-msegui/icons/components/tmbdropdownitemedit.svg b/mseide-msegui/icons/components/tmbdropdownitemedit.svg new file mode 100644 index 0000000..1e8fd54 --- /dev/null +++ b/mseide-msegui/icons/components/tmbdropdownitemedit.svg @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmemodialogedit.png b/mseide-msegui/icons/components/tmemodialogedit.png new file mode 100644 index 0000000..6cbcf53 Binary files /dev/null and b/mseide-msegui/icons/components/tmemodialogedit.png differ diff --git a/mseide-msegui/icons/components/tmemodialogedit.svg b/mseide-msegui/icons/components/tmemodialogedit.svg new file mode 100644 index 0000000..b91e7fa --- /dev/null +++ b/mseide-msegui/icons/components/tmemodialogedit.svg @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmemodialogstringedit.svg b/mseide-msegui/icons/components/tmemodialogstringedit.svg new file mode 100644 index 0000000..ffc04c5 --- /dev/null +++ b/mseide-msegui/icons/components/tmemodialogstringedit.svg @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AB + + diff --git a/mseide-msegui/icons/components/tmemoedit.bmp b/mseide-msegui/icons/components/tmemoedit.bmp new file mode 100644 index 0000000..5870f7b Binary files /dev/null and b/mseide-msegui/icons/components/tmemoedit.bmp differ diff --git a/mseide-msegui/icons/components/tmemoedit.png b/mseide-msegui/icons/components/tmemoedit.png new file mode 100644 index 0000000..acb42d7 Binary files /dev/null and b/mseide-msegui/icons/components/tmemoedit.png differ diff --git a/mseide-msegui/icons/components/tmemoedit.svg b/mseide-msegui/icons/components/tmemoedit.svg new file mode 100644 index 0000000..05894d7 --- /dev/null +++ b/mseide-msegui/icons/components/tmemoedit.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmidisource.png b/mseide-msegui/icons/components/tmidisource.png new file mode 100644 index 0000000..242e559 Binary files /dev/null and b/mseide-msegui/icons/components/tmidisource.png differ diff --git a/mseide-msegui/icons/components/tmidisource.svg b/mseide-msegui/icons/components/tmidisource.svg new file mode 100644 index 0000000..b3ed6f5 --- /dev/null +++ b/mseide-msegui/icons/components/tmidisource.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + MIDI + + + diff --git a/mseide-msegui/icons/components/tmodulelink.bmp b/mseide-msegui/icons/components/tmodulelink.bmp new file mode 100644 index 0000000..f767639 Binary files /dev/null and b/mseide-msegui/icons/components/tmodulelink.bmp differ diff --git a/mseide-msegui/icons/components/tmseautoincfield.bmp b/mseide-msegui/icons/components/tmseautoincfield.bmp new file mode 100644 index 0000000..7f6124a Binary files /dev/null and b/mseide-msegui/icons/components/tmseautoincfield.bmp differ diff --git a/mseide-msegui/icons/components/tmseautoincfield.png b/mseide-msegui/icons/components/tmseautoincfield.png new file mode 100644 index 0000000..48f5f16 Binary files /dev/null and b/mseide-msegui/icons/components/tmseautoincfield.png differ diff --git a/mseide-msegui/icons/components/tmseautoincfield.svg b/mseide-msegui/icons/components/tmseautoincfield.svg new file mode 100644 index 0000000..de2ad46 --- /dev/null +++ b/mseide-msegui/icons/components/tmseautoincfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + INC + + + + + diff --git a/mseide-msegui/icons/components/tmsebcdfield.bmp b/mseide-msegui/icons/components/tmsebcdfield.bmp new file mode 100644 index 0000000..a2e93cf Binary files /dev/null and b/mseide-msegui/icons/components/tmsebcdfield.bmp differ diff --git a/mseide-msegui/icons/components/tmsebcdfield.png b/mseide-msegui/icons/components/tmsebcdfield.png new file mode 100644 index 0000000..11ca857 Binary files /dev/null and b/mseide-msegui/icons/components/tmsebcdfield.png differ diff --git a/mseide-msegui/icons/components/tmsebcdfield.svg b/mseide-msegui/icons/components/tmsebcdfield.svg new file mode 100644 index 0000000..ff8d0d9 --- /dev/null +++ b/mseide-msegui/icons/components/tmsebcdfield.svg @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + BCD + + + + + diff --git a/mseide-msegui/icons/components/tmsebinaryfield.bmp b/mseide-msegui/icons/components/tmsebinaryfield.bmp new file mode 100644 index 0000000..2f020fe Binary files /dev/null and b/mseide-msegui/icons/components/tmsebinaryfield.bmp differ diff --git a/mseide-msegui/icons/components/tmsebinaryfield.png b/mseide-msegui/icons/components/tmsebinaryfield.png new file mode 100644 index 0000000..7fc347c Binary files /dev/null and b/mseide-msegui/icons/components/tmsebinaryfield.png differ diff --git a/mseide-msegui/icons/components/tmsebinaryfield.svg b/mseide-msegui/icons/components/tmsebinaryfield.svg new file mode 100644 index 0000000..5de3922 --- /dev/null +++ b/mseide-msegui/icons/components/tmsebinaryfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + BIN + + + + + diff --git a/mseide-msegui/icons/components/tmseblobfield.bmp b/mseide-msegui/icons/components/tmseblobfield.bmp new file mode 100644 index 0000000..0fd3db8 Binary files /dev/null and b/mseide-msegui/icons/components/tmseblobfield.bmp differ diff --git a/mseide-msegui/icons/components/tmseblobfield.png b/mseide-msegui/icons/components/tmseblobfield.png new file mode 100644 index 0000000..9c34463 Binary files /dev/null and b/mseide-msegui/icons/components/tmseblobfield.png differ diff --git a/mseide-msegui/icons/components/tmseblobfield.svg b/mseide-msegui/icons/components/tmseblobfield.svg new file mode 100644 index 0000000..6f9a90c --- /dev/null +++ b/mseide-msegui/icons/components/tmseblobfield.svg @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + Blob + + + + + diff --git a/mseide-msegui/icons/components/tmsebooleanfield.bmp b/mseide-msegui/icons/components/tmsebooleanfield.bmp new file mode 100644 index 0000000..81d3d23 Binary files /dev/null and b/mseide-msegui/icons/components/tmsebooleanfield.bmp differ diff --git a/mseide-msegui/icons/components/tmsebooleanfield.png b/mseide-msegui/icons/components/tmsebooleanfield.png new file mode 100644 index 0000000..c088ce0 Binary files /dev/null and b/mseide-msegui/icons/components/tmsebooleanfield.png differ diff --git a/mseide-msegui/icons/components/tmsebooleanfield.svg b/mseide-msegui/icons/components/tmsebooleanfield.svg new file mode 100644 index 0000000..83606c0 --- /dev/null +++ b/mseide-msegui/icons/components/tmsebooleanfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + T/F + + + + + diff --git a/mseide-msegui/icons/components/tmsebytesfield.bmp b/mseide-msegui/icons/components/tmsebytesfield.bmp new file mode 100644 index 0000000..fb3b084 Binary files /dev/null and b/mseide-msegui/icons/components/tmsebytesfield.bmp differ diff --git a/mseide-msegui/icons/components/tmsebytesfield.png b/mseide-msegui/icons/components/tmsebytesfield.png new file mode 100644 index 0000000..9e58000 Binary files /dev/null and b/mseide-msegui/icons/components/tmsebytesfield.png differ diff --git a/mseide-msegui/icons/components/tmsebytesfield.svg b/mseide-msegui/icons/components/tmsebytesfield.svg new file mode 100644 index 0000000..d06ef30 --- /dev/null +++ b/mseide-msegui/icons/components/tmsebytesfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + Byte + + + + + diff --git a/mseide-msegui/icons/components/tmsecurrencyfield.bmp b/mseide-msegui/icons/components/tmsecurrencyfield.bmp new file mode 100644 index 0000000..1a6506d Binary files /dev/null and b/mseide-msegui/icons/components/tmsecurrencyfield.bmp differ diff --git a/mseide-msegui/icons/components/tmsecurrencyfield.png b/mseide-msegui/icons/components/tmsecurrencyfield.png new file mode 100644 index 0000000..23328bc Binary files /dev/null and b/mseide-msegui/icons/components/tmsecurrencyfield.png differ diff --git a/mseide-msegui/icons/components/tmsecurrencyfield.svg b/mseide-msegui/icons/components/tmsecurrencyfield.svg new file mode 100644 index 0000000..2969aac --- /dev/null +++ b/mseide-msegui/icons/components/tmsecurrencyfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + $.$ + + + + + diff --git a/mseide-msegui/icons/components/tmsedatasource.png b/mseide-msegui/icons/components/tmsedatasource.png new file mode 100644 index 0000000..f9b0dc6 Binary files /dev/null and b/mseide-msegui/icons/components/tmsedatasource.png differ diff --git a/mseide-msegui/icons/components/tmsedatasource.svg b/mseide-msegui/icons/components/tmsedatasource.svg new file mode 100644 index 0000000..1aa096d --- /dev/null +++ b/mseide-msegui/icons/components/tmsedatasource.svg @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsedatefield.bmp b/mseide-msegui/icons/components/tmsedatefield.bmp new file mode 100644 index 0000000..cbfe62e Binary files /dev/null and b/mseide-msegui/icons/components/tmsedatefield.bmp differ diff --git a/mseide-msegui/icons/components/tmsedatefield.png b/mseide-msegui/icons/components/tmsedatefield.png new file mode 100644 index 0000000..9f51f33 Binary files /dev/null and b/mseide-msegui/icons/components/tmsedatefield.png differ diff --git a/mseide-msegui/icons/components/tmsedatefield.svg b/mseide-msegui/icons/components/tmsedatefield.svg new file mode 100644 index 0000000..a8147ce --- /dev/null +++ b/mseide-msegui/icons/components/tmsedatefield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D + + + + + diff --git a/mseide-msegui/icons/components/tmsedatetimefield.bmp b/mseide-msegui/icons/components/tmsedatetimefield.bmp new file mode 100644 index 0000000..2fb428c Binary files /dev/null and b/mseide-msegui/icons/components/tmsedatetimefield.bmp differ diff --git a/mseide-msegui/icons/components/tmsedatetimefield.png b/mseide-msegui/icons/components/tmsedatetimefield.png new file mode 100644 index 0000000..c9fb46b Binary files /dev/null and b/mseide-msegui/icons/components/tmsedatetimefield.png differ diff --git a/mseide-msegui/icons/components/tmsedatetimefield.svg b/mseide-msegui/icons/components/tmsedatetimefield.svg new file mode 100644 index 0000000..88034ce --- /dev/null +++ b/mseide-msegui/icons/components/tmsedatetimefield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + + + + + diff --git a/mseide-msegui/icons/components/tmsedbf.bmp b/mseide-msegui/icons/components/tmsedbf.bmp new file mode 100644 index 0000000..2a1c96a Binary files /dev/null and b/mseide-msegui/icons/components/tmsedbf.bmp differ diff --git a/mseide-msegui/icons/components/tmsedbf.png b/mseide-msegui/icons/components/tmsedbf.png new file mode 100644 index 0000000..6d42173 Binary files /dev/null and b/mseide-msegui/icons/components/tmsedbf.png differ diff --git a/mseide-msegui/icons/components/tmsedbf.svg b/mseide-msegui/icons/components/tmsedbf.svg new file mode 100644 index 0000000..3a72493 --- /dev/null +++ b/mseide-msegui/icons/components/tmsedbf.svg @@ -0,0 +1,440 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsefixdataset.png b/mseide-msegui/icons/components/tmsefixdataset.png new file mode 100644 index 0000000..4b6cfac Binary files /dev/null and b/mseide-msegui/icons/components/tmsefixdataset.png differ diff --git a/mseide-msegui/icons/components/tmsefixedataset.png b/mseide-msegui/icons/components/tmsefixedataset.png new file mode 100644 index 0000000..4b6cfac Binary files /dev/null and b/mseide-msegui/icons/components/tmsefixedataset.png differ diff --git a/mseide-msegui/icons/components/tmsefixedformatdataset.bmp b/mseide-msegui/icons/components/tmsefixedformatdataset.bmp new file mode 100644 index 0000000..73c6334 Binary files /dev/null and b/mseide-msegui/icons/components/tmsefixedformatdataset.bmp differ diff --git a/mseide-msegui/icons/components/tmsefixedformatdataset.png b/mseide-msegui/icons/components/tmsefixedformatdataset.png new file mode 100644 index 0000000..4b6cfac Binary files /dev/null and b/mseide-msegui/icons/components/tmsefixedformatdataset.png differ diff --git a/mseide-msegui/icons/components/tmsefixedformatdataset.svg b/mseide-msegui/icons/components/tmsefixedformatdataset.svg new file mode 100644 index 0000000..b42b4a8 --- /dev/null +++ b/mseide-msegui/icons/components/tmsefixedformatdataset.svg @@ -0,0 +1,440 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsefixedfornatdataset.png b/mseide-msegui/icons/components/tmsefixedfornatdataset.png new file mode 100644 index 0000000..4b6cfac Binary files /dev/null and b/mseide-msegui/icons/components/tmsefixedfornatdataset.png differ diff --git a/mseide-msegui/icons/components/tmsefloatfield.bmp b/mseide-msegui/icons/components/tmsefloatfield.bmp new file mode 100644 index 0000000..e018ad1 Binary files /dev/null and b/mseide-msegui/icons/components/tmsefloatfield.bmp differ diff --git a/mseide-msegui/icons/components/tmsefloatfield.png b/mseide-msegui/icons/components/tmsefloatfield.png new file mode 100644 index 0000000..77eeacd Binary files /dev/null and b/mseide-msegui/icons/components/tmsefloatfield.png differ diff --git a/mseide-msegui/icons/components/tmsefloatfield.svg b/mseide-msegui/icons/components/tmsefloatfield.svg new file mode 100644 index 0000000..e95d0f4 --- /dev/null +++ b/mseide-msegui/icons/components/tmsefloatfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 1.2 + + + + + diff --git a/mseide-msegui/icons/components/tmseflotfield.png b/mseide-msegui/icons/components/tmseflotfield.png new file mode 100644 index 0000000..77eeacd Binary files /dev/null and b/mseide-msegui/icons/components/tmseflotfield.png differ diff --git a/mseide-msegui/icons/components/tmseformwidget.bmp b/mseide-msegui/icons/components/tmseformwidget.bmp new file mode 100755 index 0000000..e6b9c74 Binary files /dev/null and b/mseide-msegui/icons/components/tmseformwidget.bmp differ diff --git a/mseide-msegui/icons/components/tmseformwidget.png b/mseide-msegui/icons/components/tmseformwidget.png new file mode 100644 index 0000000..9dc6d41 Binary files /dev/null and b/mseide-msegui/icons/components/tmseformwidget.png differ diff --git a/mseide-msegui/icons/components/tmseformwidget.svg b/mseide-msegui/icons/components/tmseformwidget.svg new file mode 100644 index 0000000..71d17fb --- /dev/null +++ b/mseide-msegui/icons/components/tmseformwidget.svg @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + Plioe + + + + + diff --git a/mseide-msegui/icons/components/tmsegraphicfield.bmp b/mseide-msegui/icons/components/tmsegraphicfield.bmp new file mode 100644 index 0000000..d210dbf Binary files /dev/null and b/mseide-msegui/icons/components/tmsegraphicfield.bmp differ diff --git a/mseide-msegui/icons/components/tmsegraphicfield.png b/mseide-msegui/icons/components/tmsegraphicfield.png new file mode 100644 index 0000000..81cdc59 Binary files /dev/null and b/mseide-msegui/icons/components/tmsegraphicfield.png differ diff --git a/mseide-msegui/icons/components/tmsegraphicfield.svg b/mseide-msegui/icons/components/tmsegraphicfield.svg new file mode 100644 index 0000000..17dd363 --- /dev/null +++ b/mseide-msegui/icons/components/tmsegraphicfield.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmseguidfield.png b/mseide-msegui/icons/components/tmseguidfield.png new file mode 100644 index 0000000..baa50be Binary files /dev/null and b/mseide-msegui/icons/components/tmseguidfield.png differ diff --git a/mseide-msegui/icons/components/tmseguidfield.svg b/mseide-msegui/icons/components/tmseguidfield.svg new file mode 100644 index 0000000..527346b --- /dev/null +++ b/mseide-msegui/icons/components/tmseguidfield.svg @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Guid + + + + + diff --git a/mseide-msegui/icons/components/tmseibconnection.bmp b/mseide-msegui/icons/components/tmseibconnection.bmp new file mode 100644 index 0000000..986531b Binary files /dev/null and b/mseide-msegui/icons/components/tmseibconnection.bmp differ diff --git a/mseide-msegui/icons/components/tmseibconnection.png b/mseide-msegui/icons/components/tmseibconnection.png new file mode 100644 index 0000000..70b1f81 Binary files /dev/null and b/mseide-msegui/icons/components/tmseibconnection.png differ diff --git a/mseide-msegui/icons/components/tmseibconnection.svg b/mseide-msegui/icons/components/tmseibconnection.svg new file mode 100644 index 0000000..3725773 --- /dev/null +++ b/mseide-msegui/icons/components/tmseibconnection.svg @@ -0,0 +1,432 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmselargeintfield.bmp b/mseide-msegui/icons/components/tmselargeintfield.bmp new file mode 100644 index 0000000..069f373 Binary files /dev/null and b/mseide-msegui/icons/components/tmselargeintfield.bmp differ diff --git a/mseide-msegui/icons/components/tmselargeintfield.png b/mseide-msegui/icons/components/tmselargeintfield.png new file mode 100644 index 0000000..55c1a60 Binary files /dev/null and b/mseide-msegui/icons/components/tmselargeintfield.png differ diff --git a/mseide-msegui/icons/components/tmselargeintfield.svg b/mseide-msegui/icons/components/tmselargeintfield.svg new file mode 100644 index 0000000..5cf59ab --- /dev/null +++ b/mseide-msegui/icons/components/tmselargeintfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + I64 + + + + + diff --git a/mseide-msegui/icons/components/tmselongintfield.bmp b/mseide-msegui/icons/components/tmselongintfield.bmp new file mode 100644 index 0000000..eba265d Binary files /dev/null and b/mseide-msegui/icons/components/tmselongintfield.bmp differ diff --git a/mseide-msegui/icons/components/tmselongintfield.png b/mseide-msegui/icons/components/tmselongintfield.png new file mode 100644 index 0000000..b42e093 Binary files /dev/null and b/mseide-msegui/icons/components/tmselongintfield.png differ diff --git a/mseide-msegui/icons/components/tmselongintfield.svg b/mseide-msegui/icons/components/tmselongintfield.svg new file mode 100644 index 0000000..4363401 --- /dev/null +++ b/mseide-msegui/icons/components/tmselongintfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + I32 + + + + + diff --git a/mseide-msegui/icons/components/tmsememdataset.bmp b/mseide-msegui/icons/components/tmsememdataset.bmp new file mode 100644 index 0000000..624f2aa Binary files /dev/null and b/mseide-msegui/icons/components/tmsememdataset.bmp differ diff --git a/mseide-msegui/icons/components/tmsememdataset.png b/mseide-msegui/icons/components/tmsememdataset.png new file mode 100644 index 0000000..dfb89bf Binary files /dev/null and b/mseide-msegui/icons/components/tmsememdataset.png differ diff --git a/mseide-msegui/icons/components/tmsememdataset.svg b/mseide-msegui/icons/components/tmsememdataset.svg new file mode 100644 index 0000000..9f0fca1 --- /dev/null +++ b/mseide-msegui/icons/components/tmsememdataset.svg @@ -0,0 +1,434 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsememofield.bmp b/mseide-msegui/icons/components/tmsememofield.bmp new file mode 100644 index 0000000..630d0ff Binary files /dev/null and b/mseide-msegui/icons/components/tmsememofield.bmp differ diff --git a/mseide-msegui/icons/components/tmsememofield.png b/mseide-msegui/icons/components/tmsememofield.png new file mode 100644 index 0000000..19f8702 Binary files /dev/null and b/mseide-msegui/icons/components/tmsememofield.png differ diff --git a/mseide-msegui/icons/components/tmsememofield.svg b/mseide-msegui/icons/components/tmsememofield.svg new file mode 100644 index 0000000..5f1e156 --- /dev/null +++ b/mseide-msegui/icons/components/tmsememofield.svg @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + MeMo + + + + + diff --git a/mseide-msegui/icons/components/tmsemysql40connection.bmp b/mseide-msegui/icons/components/tmsemysql40connection.bmp new file mode 100644 index 0000000..e1e00db Binary files /dev/null and b/mseide-msegui/icons/components/tmsemysql40connection.bmp differ diff --git a/mseide-msegui/icons/components/tmsemysql41connection.bmp b/mseide-msegui/icons/components/tmsemysql41connection.bmp new file mode 100644 index 0000000..71230f6 Binary files /dev/null and b/mseide-msegui/icons/components/tmsemysql41connection.bmp differ diff --git a/mseide-msegui/icons/components/tmsemysql50connection.bmp b/mseide-msegui/icons/components/tmsemysql50connection.bmp new file mode 100644 index 0000000..415f2f1 Binary files /dev/null and b/mseide-msegui/icons/components/tmsemysql50connection.bmp differ diff --git a/mseide-msegui/icons/components/tmsemysqlconnection.png b/mseide-msegui/icons/components/tmsemysqlconnection.png new file mode 100644 index 0000000..eab5329 Binary files /dev/null and b/mseide-msegui/icons/components/tmsemysqlconnection.png differ diff --git a/mseide-msegui/icons/components/tmsemysqlconnection.svg b/mseide-msegui/icons/components/tmsemysqlconnection.svg new file mode 100644 index 0000000..dbd518a --- /dev/null +++ b/mseide-msegui/icons/components/tmsemysqlconnection.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmseodbcconnection.bmp b/mseide-msegui/icons/components/tmseodbcconnection.bmp new file mode 100644 index 0000000..8ef2541 Binary files /dev/null and b/mseide-msegui/icons/components/tmseodbcconnection.bmp differ diff --git a/mseide-msegui/icons/components/tmseodbcconnection.png b/mseide-msegui/icons/components/tmseodbcconnection.png new file mode 100644 index 0000000..7bb02ce Binary files /dev/null and b/mseide-msegui/icons/components/tmseodbcconnection.png differ diff --git a/mseide-msegui/icons/components/tmseodbcconnection.svg b/mseide-msegui/icons/components/tmseodbcconnection.svg new file mode 100644 index 0000000..bb0cf89 --- /dev/null +++ b/mseide-msegui/icons/components/tmseodbcconnection.svg @@ -0,0 +1,471 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsepqconnection.bmp b/mseide-msegui/icons/components/tmsepqconnection.bmp new file mode 100644 index 0000000..83e1f6b Binary files /dev/null and b/mseide-msegui/icons/components/tmsepqconnection.bmp differ diff --git a/mseide-msegui/icons/components/tmseprocess.png b/mseide-msegui/icons/components/tmseprocess.png new file mode 100644 index 0000000..96dc6c1 Binary files /dev/null and b/mseide-msegui/icons/components/tmseprocess.png differ diff --git a/mseide-msegui/icons/components/tmseprocess.svg b/mseide-msegui/icons/components/tmseprocess.svg new file mode 100644 index 0000000..84724af --- /dev/null +++ b/mseide-msegui/icons/components/tmseprocess.svg @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Proc + + diff --git a/mseide-msegui/icons/components/tmsesdfdataset.bmp b/mseide-msegui/icons/components/tmsesdfdataset.bmp new file mode 100644 index 0000000..f895f0e Binary files /dev/null and b/mseide-msegui/icons/components/tmsesdfdataset.bmp differ diff --git a/mseide-msegui/icons/components/tmsesdfdataset.png b/mseide-msegui/icons/components/tmsesdfdataset.png new file mode 100644 index 0000000..a3b2fc3 Binary files /dev/null and b/mseide-msegui/icons/components/tmsesdfdataset.png differ diff --git a/mseide-msegui/icons/components/tmsesdfdataset.svg b/mseide-msegui/icons/components/tmsesdfdataset.svg new file mode 100644 index 0000000..4918245 --- /dev/null +++ b/mseide-msegui/icons/components/tmsesdfdataset.svg @@ -0,0 +1,410 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + SDF + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsesmallintfield.bmp b/mseide-msegui/icons/components/tmsesmallintfield.bmp new file mode 100644 index 0000000..f9d7df1 Binary files /dev/null and b/mseide-msegui/icons/components/tmsesmallintfield.bmp differ diff --git a/mseide-msegui/icons/components/tmsesmallintfield.png b/mseide-msegui/icons/components/tmsesmallintfield.png new file mode 100644 index 0000000..966b9ad Binary files /dev/null and b/mseide-msegui/icons/components/tmsesmallintfield.png differ diff --git a/mseide-msegui/icons/components/tmsesmallintfield.svg b/mseide-msegui/icons/components/tmsesmallintfield.svg new file mode 100644 index 0000000..90e03b3 --- /dev/null +++ b/mseide-msegui/icons/components/tmsesmallintfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + I16 + + + + + diff --git a/mseide-msegui/icons/components/tmsesqlite3dataset.bmp b/mseide-msegui/icons/components/tmsesqlite3dataset.bmp new file mode 100644 index 0000000..3122366 Binary files /dev/null and b/mseide-msegui/icons/components/tmsesqlite3dataset.bmp differ diff --git a/mseide-msegui/icons/components/tmsesqlquery.bmp b/mseide-msegui/icons/components/tmsesqlquery.bmp new file mode 100644 index 0000000..b556ba7 Binary files /dev/null and b/mseide-msegui/icons/components/tmsesqlquery.bmp differ diff --git a/mseide-msegui/icons/components/tmsesqlquery.png b/mseide-msegui/icons/components/tmsesqlquery.png new file mode 100644 index 0000000..4a2f9cb Binary files /dev/null and b/mseide-msegui/icons/components/tmsesqlquery.png differ diff --git a/mseide-msegui/icons/components/tmsesqlquery.svg b/mseide-msegui/icons/components/tmsesqlquery.svg new file mode 100644 index 0000000..1f431b4 --- /dev/null +++ b/mseide-msegui/icons/components/tmsesqlquery.svg @@ -0,0 +1,433 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsesqlscript.bmp b/mseide-msegui/icons/components/tmsesqlscript.bmp new file mode 100644 index 0000000..5b04f5a Binary files /dev/null and b/mseide-msegui/icons/components/tmsesqlscript.bmp differ diff --git a/mseide-msegui/icons/components/tmsesqlscript.png b/mseide-msegui/icons/components/tmsesqlscript.png new file mode 100644 index 0000000..0926f81 Binary files /dev/null and b/mseide-msegui/icons/components/tmsesqlscript.png differ diff --git a/mseide-msegui/icons/components/tmsesqlscript.svg b/mseide-msegui/icons/components/tmsesqlscript.svg new file mode 100644 index 0000000..3c2ab28 --- /dev/null +++ b/mseide-msegui/icons/components/tmsesqlscript.svg @@ -0,0 +1,397 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsesqltransaction.bmp b/mseide-msegui/icons/components/tmsesqltransaction.bmp new file mode 100644 index 0000000..8ac1d60 Binary files /dev/null and b/mseide-msegui/icons/components/tmsesqltransaction.bmp differ diff --git a/mseide-msegui/icons/components/tmsesqltransaction.png b/mseide-msegui/icons/components/tmsesqltransaction.png new file mode 100644 index 0000000..c41b8b3 Binary files /dev/null and b/mseide-msegui/icons/components/tmsesqltransaction.png differ diff --git a/mseide-msegui/icons/components/tmsesqltransaction.svg b/mseide-msegui/icons/components/tmsesqltransaction.svg new file mode 100644 index 0000000..b612bb7 --- /dev/null +++ b/mseide-msegui/icons/components/tmsesqltransaction.svg @@ -0,0 +1,432 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsestringfield.bmp b/mseide-msegui/icons/components/tmsestringfield.bmp new file mode 100644 index 0000000..178f1ee Binary files /dev/null and b/mseide-msegui/icons/components/tmsestringfield.bmp differ diff --git a/mseide-msegui/icons/components/tmsestringfield.png b/mseide-msegui/icons/components/tmsestringfield.png new file mode 100644 index 0000000..d3a3d51 Binary files /dev/null and b/mseide-msegui/icons/components/tmsestringfield.png differ diff --git a/mseide-msegui/icons/components/tmsestringfield.svg b/mseide-msegui/icons/components/tmsestringfield.svg new file mode 100644 index 0000000..cabacc5 --- /dev/null +++ b/mseide-msegui/icons/components/tmsestringfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + + + + + diff --git a/mseide-msegui/icons/components/tmsetimefield.bmp b/mseide-msegui/icons/components/tmsetimefield.bmp new file mode 100644 index 0000000..6779a59 Binary files /dev/null and b/mseide-msegui/icons/components/tmsetimefield.bmp differ diff --git a/mseide-msegui/icons/components/tmsetimefield.png b/mseide-msegui/icons/components/tmsetimefield.png new file mode 100644 index 0000000..2887106 Binary files /dev/null and b/mseide-msegui/icons/components/tmsetimefield.png differ diff --git a/mseide-msegui/icons/components/tmsetimefield.svg b/mseide-msegui/icons/components/tmsetimefield.svg new file mode 100644 index 0000000..a5b6176 --- /dev/null +++ b/mseide-msegui/icons/components/tmsetimefield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + T + + + + + diff --git a/mseide-msegui/icons/components/tmsevarbytesfield.bmp b/mseide-msegui/icons/components/tmsevarbytesfield.bmp new file mode 100644 index 0000000..bcba00a Binary files /dev/null and b/mseide-msegui/icons/components/tmsevarbytesfield.bmp differ diff --git a/mseide-msegui/icons/components/tmsevarbytesfield.png b/mseide-msegui/icons/components/tmsevarbytesfield.png new file mode 100644 index 0000000..5f5419c Binary files /dev/null and b/mseide-msegui/icons/components/tmsevarbytesfield.png differ diff --git a/mseide-msegui/icons/components/tmsevarbytesfield.svg b/mseide-msegui/icons/components/tmsevarbytesfield.svg new file mode 100644 index 0000000..4338e99 --- /dev/null +++ b/mseide-msegui/icons/components/tmsevarbytesfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + VBy + + + + + diff --git a/mseide-msegui/icons/components/tmsevarfield.svg b/mseide-msegui/icons/components/tmsevarfield.svg new file mode 100644 index 0000000..0a9f45f --- /dev/null +++ b/mseide-msegui/icons/components/tmsevarfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + I32 + + + + + diff --git a/mseide-msegui/icons/components/tmsevariantfield.png b/mseide-msegui/icons/components/tmsevariantfield.png new file mode 100644 index 0000000..19004ef Binary files /dev/null and b/mseide-msegui/icons/components/tmsevariantfield.png differ diff --git a/mseide-msegui/icons/components/tmsevariantfield.svg b/mseide-msegui/icons/components/tmsevariantfield.svg new file mode 100644 index 0000000..b253652 --- /dev/null +++ b/mseide-msegui/icons/components/tmsevariantfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + VAR + + + + + diff --git a/mseide-msegui/icons/components/tmsewordfield.bmp b/mseide-msegui/icons/components/tmsewordfield.bmp new file mode 100644 index 0000000..91d3476 Binary files /dev/null and b/mseide-msegui/icons/components/tmsewordfield.bmp differ diff --git a/mseide-msegui/icons/components/tmsewordfield.png b/mseide-msegui/icons/components/tmsewordfield.png new file mode 100644 index 0000000..5976382 Binary files /dev/null and b/mseide-msegui/icons/components/tmsewordfield.png differ diff --git a/mseide-msegui/icons/components/tmsewordfield.svg b/mseide-msegui/icons/components/tmsewordfield.svg new file mode 100644 index 0000000..77c9a56 --- /dev/null +++ b/mseide-msegui/icons/components/tmsewordfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + U16 + + + + + diff --git a/mseide-msegui/icons/components/tmsezquery.bmp b/mseide-msegui/icons/components/tmsezquery.bmp new file mode 100644 index 0000000..0ad67ac Binary files /dev/null and b/mseide-msegui/icons/components/tmsezquery.bmp differ diff --git a/mseide-msegui/icons/components/tmsezreadonlyquery.bmp b/mseide-msegui/icons/components/tmsezreadonlyquery.bmp new file mode 100644 index 0000000..039a4d1 Binary files /dev/null and b/mseide-msegui/icons/components/tmsezreadonlyquery.bmp differ diff --git a/mseide-msegui/icons/components/tmseztable.bmp b/mseide-msegui/icons/components/tmseztable.bmp new file mode 100644 index 0000000..8733886 Binary files /dev/null and b/mseide-msegui/icons/components/tmseztable.bmp differ diff --git a/mseide-msegui/icons/components/tnoguiaction.bmp b/mseide-msegui/icons/components/tnoguiaction.bmp new file mode 100644 index 0000000..0503a42 Binary files /dev/null and b/mseide-msegui/icons/components/tnoguiaction.bmp differ diff --git a/mseide-msegui/icons/components/tnoguiaction.png b/mseide-msegui/icons/components/tnoguiaction.png new file mode 100644 index 0000000..17eab9f Binary files /dev/null and b/mseide-msegui/icons/components/tnoguiaction.png differ diff --git a/mseide-msegui/icons/components/tnoguiaction.svg b/mseide-msegui/icons/components/tnoguiaction.svg new file mode 100644 index 0000000..c7a682f --- /dev/null +++ b/mseide-msegui/icons/components/tnoguiaction.svg @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/topenglcanvaswidget.png b/mseide-msegui/icons/components/topenglcanvaswidget.png new file mode 100644 index 0000000..a2ae8ca Binary files /dev/null and b/mseide-msegui/icons/components/topenglcanvaswidget.png differ diff --git a/mseide-msegui/icons/components/topenglcanvaswidget.svg b/mseide-msegui/icons/components/topenglcanvaswidget.svg new file mode 100644 index 0000000..7a8fbeb --- /dev/null +++ b/mseide-msegui/icons/components/topenglcanvaswidget.svg @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + GLCA + + + diff --git a/mseide-msegui/icons/components/topenglwidget.bmp b/mseide-msegui/icons/components/topenglwidget.bmp new file mode 100644 index 0000000..e89b20e Binary files /dev/null and b/mseide-msegui/icons/components/topenglwidget.bmp differ diff --git a/mseide-msegui/icons/components/topenglwidget.png b/mseide-msegui/icons/components/topenglwidget.png new file mode 100644 index 0000000..d5c9c3e Binary files /dev/null and b/mseide-msegui/icons/components/topenglwidget.png differ diff --git a/mseide-msegui/icons/components/topenglwidget.svg b/mseide-msegui/icons/components/topenglwidget.svg new file mode 100644 index 0000000..20655a4 --- /dev/null +++ b/mseide-msegui/icons/components/topenglwidget.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + GL + + + diff --git a/mseide-msegui/icons/components/topensslcryptohandler.png b/mseide-msegui/icons/components/topensslcryptohandler.png new file mode 100644 index 0000000..349a827 Binary files /dev/null and b/mseide-msegui/icons/components/topensslcryptohandler.png differ diff --git a/mseide-msegui/icons/components/topensslcryptohandler.svg b/mseide-msegui/icons/components/topensslcryptohandler.svg new file mode 100644 index 0000000..bf65da6 --- /dev/null +++ b/mseide-msegui/icons/components/topensslcryptohandler.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SSL + crypt + + diff --git a/mseide-msegui/icons/components/tpageorientationselector.png b/mseide-msegui/icons/components/tpageorientationselector.png new file mode 100644 index 0000000..7639bb8 Binary files /dev/null and b/mseide-msegui/icons/components/tpageorientationselector.png differ diff --git a/mseide-msegui/icons/components/tpageorientationselector.svg b/mseide-msegui/icons/components/tpageorientationselector.svg new file mode 100644 index 0000000..149c072 --- /dev/null +++ b/mseide-msegui/icons/components/tpageorientationselector.svg @@ -0,0 +1,430 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpagesizeselector.png b/mseide-msegui/icons/components/tpagesizeselector.png new file mode 100644 index 0000000..b0b4986 Binary files /dev/null and b/mseide-msegui/icons/components/tpagesizeselector.png differ diff --git a/mseide-msegui/icons/components/tpagesizeselector.svg b/mseide-msegui/icons/components/tpagesizeselector.svg new file mode 100644 index 0000000..3112fa9 --- /dev/null +++ b/mseide-msegui/icons/components/tpagesizeselector.svg @@ -0,0 +1,430 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpaintbox.bmp b/mseide-msegui/icons/components/tpaintbox.bmp new file mode 100755 index 0000000..8fb707f Binary files /dev/null and b/mseide-msegui/icons/components/tpaintbox.bmp differ diff --git a/mseide-msegui/icons/components/tpaintbox.png b/mseide-msegui/icons/components/tpaintbox.png new file mode 100644 index 0000000..b9b4f6c Binary files /dev/null and b/mseide-msegui/icons/components/tpaintbox.png differ diff --git a/mseide-msegui/icons/components/tpaintbox.svg b/mseide-msegui/icons/components/tpaintbox.svg new file mode 100644 index 0000000..0e483b2 --- /dev/null +++ b/mseide-msegui/icons/components/tpaintbox.svg @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tparamconnector.png b/mseide-msegui/icons/components/tparamconnector.png new file mode 100644 index 0000000..16a6da9 Binary files /dev/null and b/mseide-msegui/icons/components/tparamconnector.png differ diff --git a/mseide-msegui/icons/components/tparamconnector.svg b/mseide-msegui/icons/components/tparamconnector.svg new file mode 100644 index 0000000..0d677d8 --- /dev/null +++ b/mseide-msegui/icons/components/tparamconnector.svg @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + PAR + + + + + diff --git a/mseide-msegui/icons/components/tparamlink.svg b/mseide-msegui/icons/components/tparamlink.svg new file mode 100644 index 0000000..911d769 --- /dev/null +++ b/mseide-msegui/icons/components/tparamlink.svg @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + PAR + + + + + diff --git a/mseide-msegui/icons/components/tpickwidget.png b/mseide-msegui/icons/components/tpickwidget.png new file mode 100644 index 0000000..84284b6 Binary files /dev/null and b/mseide-msegui/icons/components/tpickwidget.png differ diff --git a/mseide-msegui/icons/components/tpickwidget.svg b/mseide-msegui/icons/components/tpickwidget.svg new file mode 100644 index 0000000..bc7b1b6 --- /dev/null +++ b/mseide-msegui/icons/components/tpickwidget.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpipeiochannel.bmp b/mseide-msegui/icons/components/tpipeiochannel.bmp new file mode 100644 index 0000000..a524656 Binary files /dev/null and b/mseide-msegui/icons/components/tpipeiochannel.bmp differ diff --git a/mseide-msegui/icons/components/tpipereader.png b/mseide-msegui/icons/components/tpipereader.png new file mode 100644 index 0000000..fad1a26 Binary files /dev/null and b/mseide-msegui/icons/components/tpipereader.png differ diff --git a/mseide-msegui/icons/components/tpipereader.svg b/mseide-msegui/icons/components/tpipereader.svg new file mode 100644 index 0000000..a3f3d28 --- /dev/null +++ b/mseide-msegui/icons/components/tpipereader.svg @@ -0,0 +1,473 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpipereadercomp.bmp b/mseide-msegui/icons/components/tpipereadercomp.bmp new file mode 100755 index 0000000..ce3f51e Binary files /dev/null and b/mseide-msegui/icons/components/tpipereadercomp.bmp differ diff --git a/mseide-msegui/icons/components/tpipereadercomp.png b/mseide-msegui/icons/components/tpipereadercomp.png new file mode 100644 index 0000000..df261a5 Binary files /dev/null and b/mseide-msegui/icons/components/tpipereadercomp.png differ diff --git a/mseide-msegui/icons/components/tpipereadercomp.svg b/mseide-msegui/icons/components/tpipereadercomp.svg new file mode 100644 index 0000000..590aa69 --- /dev/null +++ b/mseide-msegui/icons/components/tpipereadercomp.svg @@ -0,0 +1,473 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpointeredit.bmp b/mseide-msegui/icons/components/tpointeredit.bmp new file mode 100644 index 0000000..b4a00e7 Binary files /dev/null and b/mseide-msegui/icons/components/tpointeredit.bmp differ diff --git a/mseide-msegui/icons/components/tpointeredit.png b/mseide-msegui/icons/components/tpointeredit.png new file mode 100644 index 0000000..0728fe9 Binary files /dev/null and b/mseide-msegui/icons/components/tpointeredit.png differ diff --git a/mseide-msegui/icons/components/tpointeredit.svg b/mseide-msegui/icons/components/tpointeredit.svg new file mode 100644 index 0000000..ac594a4 --- /dev/null +++ b/mseide-msegui/icons/components/tpointeredit.svg @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + NIL + + diff --git a/mseide-msegui/icons/components/tpolygon.bmp b/mseide-msegui/icons/components/tpolygon.bmp new file mode 100644 index 0000000..b192142 Binary files /dev/null and b/mseide-msegui/icons/components/tpolygon.bmp differ diff --git a/mseide-msegui/icons/components/tpolygon.png b/mseide-msegui/icons/components/tpolygon.png new file mode 100644 index 0000000..793b0d1 Binary files /dev/null and b/mseide-msegui/icons/components/tpolygon.png differ diff --git a/mseide-msegui/icons/components/tpolygon.svg b/mseide-msegui/icons/components/tpolygon.svg new file mode 100644 index 0000000..a34b863 --- /dev/null +++ b/mseide-msegui/icons/components/tpolygon.svg @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpopupmenu.bmp b/mseide-msegui/icons/components/tpopupmenu.bmp new file mode 100755 index 0000000..2b057c8 Binary files /dev/null and b/mseide-msegui/icons/components/tpopupmenu.bmp differ diff --git a/mseide-msegui/icons/components/tpopupmenu.png b/mseide-msegui/icons/components/tpopupmenu.png new file mode 100644 index 0000000..5c7ac5d Binary files /dev/null and b/mseide-msegui/icons/components/tpopupmenu.png differ diff --git a/mseide-msegui/icons/components/tpopupmenu.svg b/mseide-msegui/icons/components/tpopupmenu.svg new file mode 100644 index 0000000..ad3b5fa --- /dev/null +++ b/mseide-msegui/icons/components/tpopupmenu.svg @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + Zuioilo + + + + + Przio + Iklaba + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpostscriptprinter.bmp b/mseide-msegui/icons/components/tpostscriptprinter.bmp new file mode 100644 index 0000000..d4950bf Binary files /dev/null and b/mseide-msegui/icons/components/tpostscriptprinter.bmp differ diff --git a/mseide-msegui/icons/components/tpostscriptprinter.png b/mseide-msegui/icons/components/tpostscriptprinter.png new file mode 100644 index 0000000..bc3d2da Binary files /dev/null and b/mseide-msegui/icons/components/tpostscriptprinter.png differ diff --git a/mseide-msegui/icons/components/tpostscriptprinter.svg b/mseide-msegui/icons/components/tpostscriptprinter.svg new file mode 100644 index 0000000..2b46435 --- /dev/null +++ b/mseide-msegui/icons/components/tpostscriptprinter.svg @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + Poi Li + Poi oL + + + Poi + + + + diff --git a/mseide-msegui/icons/components/tprinter.bmp b/mseide-msegui/icons/components/tprinter.bmp new file mode 100644 index 0000000..1e11648 Binary files /dev/null and b/mseide-msegui/icons/components/tprinter.bmp differ diff --git a/mseide-msegui/icons/components/tprocessmonitor.bmp b/mseide-msegui/icons/components/tprocessmonitor.bmp new file mode 100644 index 0000000..1ecf478 Binary files /dev/null and b/mseide-msegui/icons/components/tprocessmonitor.bmp differ diff --git a/mseide-msegui/icons/components/tprocessmonitor.png b/mseide-msegui/icons/components/tprocessmonitor.png new file mode 100644 index 0000000..7432a40 Binary files /dev/null and b/mseide-msegui/icons/components/tprocessmonitor.png differ diff --git a/mseide-msegui/icons/components/tprocessmonitor.svg b/mseide-msegui/icons/components/tprocessmonitor.svg new file mode 100644 index 0000000..1bd0626 --- /dev/null +++ b/mseide-msegui/icons/components/tprocessmonitor.svg @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + procmon + + diff --git a/mseide-msegui/icons/components/tprogressbar.bmp b/mseide-msegui/icons/components/tprogressbar.bmp new file mode 100644 index 0000000..de0fde3 Binary files /dev/null and b/mseide-msegui/icons/components/tprogressbar.bmp differ diff --git a/mseide-msegui/icons/components/tprogressbar.png b/mseide-msegui/icons/components/tprogressbar.png new file mode 100644 index 0000000..12f6d1c Binary files /dev/null and b/mseide-msegui/icons/components/tprogressbar.png differ diff --git a/mseide-msegui/icons/components/tprogressbar.svg b/mseide-msegui/icons/components/tprogressbar.svg new file mode 100644 index 0000000..ce84ecc --- /dev/null +++ b/mseide-msegui/icons/components/tprogressbar.svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpsprinter.png b/mseide-msegui/icons/components/tpsprinter.png new file mode 100644 index 0000000..bc3d2da Binary files /dev/null and b/mseide-msegui/icons/components/tpsprinter.png differ diff --git a/mseide-msegui/icons/components/tpsprinter.svg b/mseide-msegui/icons/components/tpsprinter.svg new file mode 100644 index 0000000..387d00e --- /dev/null +++ b/mseide-msegui/icons/components/tpsprinter.svg @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + Poi Li + Poi oL + + + Poi + + + + diff --git a/mseide-msegui/icons/components/tpythonscript.png b/mseide-msegui/icons/components/tpythonscript.png new file mode 100644 index 0000000..2fbc793 Binary files /dev/null and b/mseide-msegui/icons/components/tpythonscript.png differ diff --git a/mseide-msegui/icons/components/tpythonscript.svg b/mseide-msegui/icons/components/tpythonscript.svg new file mode 100644 index 0000000..44e2147 --- /dev/null +++ b/mseide-msegui/icons/components/tpythonscript.svg @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Py + + diff --git a/mseide-msegui/icons/components/tra.png b/mseide-msegui/icons/components/tra.png new file mode 100644 index 0000000..1b205e2 Binary files /dev/null and b/mseide-msegui/icons/components/tra.png differ diff --git a/mseide-msegui/icons/components/trealdisp.bmp b/mseide-msegui/icons/components/trealdisp.bmp new file mode 100755 index 0000000..21954ec Binary files /dev/null and b/mseide-msegui/icons/components/trealdisp.bmp differ diff --git a/mseide-msegui/icons/components/trealdisp.png b/mseide-msegui/icons/components/trealdisp.png new file mode 100644 index 0000000..dc30389 Binary files /dev/null and b/mseide-msegui/icons/components/trealdisp.png differ diff --git a/mseide-msegui/icons/components/trealdisp.svg b/mseide-msegui/icons/components/trealdisp.svg new file mode 100644 index 0000000..3816ff0 --- /dev/null +++ b/mseide-msegui/icons/components/trealdisp.svg @@ -0,0 +1,380 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 1.21 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trealedit.bmp b/mseide-msegui/icons/components/trealedit.bmp new file mode 100755 index 0000000..cf147aa Binary files /dev/null and b/mseide-msegui/icons/components/trealedit.bmp differ diff --git a/mseide-msegui/icons/components/trealedit.png b/mseide-msegui/icons/components/trealedit.png new file mode 100644 index 0000000..5199544 Binary files /dev/null and b/mseide-msegui/icons/components/trealedit.png differ diff --git a/mseide-msegui/icons/components/trealedit.svg b/mseide-msegui/icons/components/trealedit.svg new file mode 100644 index 0000000..fde650d --- /dev/null +++ b/mseide-msegui/icons/components/trealedit.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trealspinedit.bmp b/mseide-msegui/icons/components/trealspinedit.bmp new file mode 100644 index 0000000..9af3f65 Binary files /dev/null and b/mseide-msegui/icons/components/trealspinedit.bmp differ diff --git a/mseide-msegui/icons/components/trealspinedit.png b/mseide-msegui/icons/components/trealspinedit.png new file mode 100644 index 0000000..e1ef8b5 Binary files /dev/null and b/mseide-msegui/icons/components/trealspinedit.png differ diff --git a/mseide-msegui/icons/components/trealspinedit.svg b/mseide-msegui/icons/components/trealspinedit.svg new file mode 100644 index 0000000..674d23e --- /dev/null +++ b/mseide-msegui/icons/components/trealspinedit.svg @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trecordband.bmp b/mseide-msegui/icons/components/trecordband.bmp new file mode 100644 index 0000000..5b5b001 Binary files /dev/null and b/mseide-msegui/icons/components/trecordband.bmp differ diff --git a/mseide-msegui/icons/components/trecordfieldedit.png b/mseide-msegui/icons/components/trecordfieldedit.png new file mode 100644 index 0000000..4bfda3a Binary files /dev/null and b/mseide-msegui/icons/components/trecordfieldedit.png differ diff --git a/mseide-msegui/icons/components/trecordfieldedit.svg b/mseide-msegui/icons/components/trecordfieldedit.svg new file mode 100644 index 0000000..c074329 --- /dev/null +++ b/mseide-msegui/icons/components/trecordfieldedit.svg @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/treportpage.png b/mseide-msegui/icons/components/treportpage.png new file mode 100644 index 0000000..f7afbd3 Binary files /dev/null and b/mseide-msegui/icons/components/treportpage.png differ diff --git a/mseide-msegui/icons/components/treportpage.svg b/mseide-msegui/icons/components/treportpage.svg new file mode 100644 index 0000000..0611b0c --- /dev/null +++ b/mseide-msegui/icons/components/treportpage.svg @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + REPPAG + + + + + diff --git a/mseide-msegui/icons/components/treppagenumdisp.bmp b/mseide-msegui/icons/components/treppagenumdisp.bmp new file mode 100644 index 0000000..c5e022f Binary files /dev/null and b/mseide-msegui/icons/components/treppagenumdisp.bmp differ diff --git a/mseide-msegui/icons/components/trepprintdatedisp.bmp b/mseide-msegui/icons/components/trepprintdatedisp.bmp new file mode 100644 index 0000000..d320675 Binary files /dev/null and b/mseide-msegui/icons/components/trepprintdatedisp.bmp differ diff --git a/mseide-msegui/icons/components/treppsdisp.png b/mseide-msegui/icons/components/treppsdisp.png new file mode 100644 index 0000000..64d43b8 Binary files /dev/null and b/mseide-msegui/icons/components/treppsdisp.png differ diff --git a/mseide-msegui/icons/components/treppsdisp.svg b/mseide-msegui/icons/components/treppsdisp.svg new file mode 100644 index 0000000..938d817 --- /dev/null +++ b/mseide-msegui/icons/components/treppsdisp.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + PS + + + diff --git a/mseide-msegui/icons/components/trepspacer.bmp b/mseide-msegui/icons/components/trepspacer.bmp new file mode 100644 index 0000000..85599b9 Binary files /dev/null and b/mseide-msegui/icons/components/trepspacer.bmp differ diff --git a/mseide-msegui/icons/components/trepvaluedisp.bmp b/mseide-msegui/icons/components/trepvaluedisp.bmp new file mode 100644 index 0000000..32ddc1e Binary files /dev/null and b/mseide-msegui/icons/components/trepvaluedisp.bmp differ diff --git a/mseide-msegui/icons/components/trichbutton.bmp b/mseide-msegui/icons/components/trichbutton.bmp new file mode 100644 index 0000000..b9d1adf Binary files /dev/null and b/mseide-msegui/icons/components/trichbutton.bmp differ diff --git a/mseide-msegui/icons/components/trichbutton.png b/mseide-msegui/icons/components/trichbutton.png new file mode 100644 index 0000000..f04359f Binary files /dev/null and b/mseide-msegui/icons/components/trichbutton.png differ diff --git a/mseide-msegui/icons/components/trichbutton.svg b/mseide-msegui/icons/components/trichbutton.svg new file mode 100644 index 0000000..3a0e623 --- /dev/null +++ b/mseide-msegui/icons/components/trichbutton.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + Capt + + diff --git a/mseide-msegui/icons/components/trichstockglyphbutton.bmp b/mseide-msegui/icons/components/trichstockglyphbutton.bmp new file mode 100644 index 0000000..472ed74 --- /dev/null +++ b/mseide-msegui/icons/components/trichstockglyphbutton.bmp @@ -0,0 +1,66 @@ + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trichstockglyphbutton.png b/mseide-msegui/icons/components/trichstockglyphbutton.png new file mode 100644 index 0000000..7e9cd08 Binary files /dev/null and b/mseide-msegui/icons/components/trichstockglyphbutton.png differ diff --git a/mseide-msegui/icons/components/trichstockglyphbutton.svg b/mseide-msegui/icons/components/trichstockglyphbutton.svg new file mode 100644 index 0000000..849d8a4 --- /dev/null +++ b/mseide-msegui/icons/components/trichstockglyphbutton.svg @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trichstringdisp.png b/mseide-msegui/icons/components/trichstringdisp.png new file mode 100644 index 0000000..d0fec2d Binary files /dev/null and b/mseide-msegui/icons/components/trichstringdisp.png differ diff --git a/mseide-msegui/icons/components/trichstringdisp.svg b/mseide-msegui/icons/components/trichstringdisp.svg new file mode 100644 index 0000000..2d5985d --- /dev/null +++ b/mseide-msegui/icons/components/trichstringdisp.svg @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trttistat.png b/mseide-msegui/icons/components/trttistat.png new file mode 100644 index 0000000..0968de5 Binary files /dev/null and b/mseide-msegui/icons/components/trttistat.png differ diff --git a/mseide-msegui/icons/components/trttistat.svg b/mseide-msegui/icons/components/trttistat.svg new file mode 100644 index 0000000..5af1b3e --- /dev/null +++ b/mseide-msegui/icons/components/trttistat.svg @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + *.sta + + diff --git a/mseide-msegui/icons/components/true_false.png b/mseide-msegui/icons/components/true_false.png new file mode 100644 index 0000000..01fcc9d Binary files /dev/null and b/mseide-msegui/icons/components/true_false.png differ diff --git a/mseide-msegui/icons/components/trxdataset.bmp b/mseide-msegui/icons/components/trxdataset.bmp new file mode 100644 index 0000000..66e1942 Binary files /dev/null and b/mseide-msegui/icons/components/trxdataset.bmp differ diff --git a/mseide-msegui/icons/components/trxwidgetgrid.bmp b/mseide-msegui/icons/components/trxwidgetgrid.bmp new file mode 100644 index 0000000..bef2801 Binary files /dev/null and b/mseide-msegui/icons/components/trxwidgetgrid.bmp differ diff --git a/mseide-msegui/icons/components/tscrollbox.bmp b/mseide-msegui/icons/components/tscrollbox.bmp new file mode 100755 index 0000000..88f91f9 Binary files /dev/null and b/mseide-msegui/icons/components/tscrollbox.bmp differ diff --git a/mseide-msegui/icons/components/tscrollbox.png b/mseide-msegui/icons/components/tscrollbox.png new file mode 100644 index 0000000..f1cbab0 Binary files /dev/null and b/mseide-msegui/icons/components/tscrollbox.png differ diff --git a/mseide-msegui/icons/components/tscrollbox.svg b/mseide-msegui/icons/components/tscrollbox.svg new file mode 100644 index 0000000..9ae5e6a --- /dev/null +++ b/mseide-msegui/icons/components/tscrollbox.svg @@ -0,0 +1,413 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tselector.bmp b/mseide-msegui/icons/components/tselector.bmp new file mode 100644 index 0000000..519ba00 Binary files /dev/null and b/mseide-msegui/icons/components/tselector.bmp differ diff --git a/mseide-msegui/icons/components/tselector.png b/mseide-msegui/icons/components/tselector.png new file mode 100644 index 0000000..92b110c Binary files /dev/null and b/mseide-msegui/icons/components/tselector.png differ diff --git a/mseide-msegui/icons/components/tselector.svg b/mseide-msegui/icons/components/tselector.svg new file mode 100644 index 0000000..c23baa9 --- /dev/null +++ b/mseide-msegui/icons/components/tselector.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsequencelink.bmp b/mseide-msegui/icons/components/tsequencelink.bmp new file mode 100644 index 0000000..b3d7bc5 Binary files /dev/null and b/mseide-msegui/icons/components/tsequencelink.bmp differ diff --git a/mseide-msegui/icons/components/tsequencelink.png b/mseide-msegui/icons/components/tsequencelink.png new file mode 100644 index 0000000..a6f7732 Binary files /dev/null and b/mseide-msegui/icons/components/tsequencelink.png differ diff --git a/mseide-msegui/icons/components/tsequencelink.svg b/mseide-msegui/icons/components/tsequencelink.svg new file mode 100644 index 0000000..c952462 --- /dev/null +++ b/mseide-msegui/icons/components/tsequencelink.svg @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + INC + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsercommchannel.png b/mseide-msegui/icons/components/tsercommchannel.png new file mode 100644 index 0000000..d4daf55 Binary files /dev/null and b/mseide-msegui/icons/components/tsercommchannel.png differ diff --git a/mseide-msegui/icons/components/tsercommchannel.svg b/mseide-msegui/icons/components/tsercommchannel.svg new file mode 100644 index 0000000..e1c20cf --- /dev/null +++ b/mseide-msegui/icons/components/tsercommchannel.svg @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SERCHA + + diff --git a/mseide-msegui/icons/components/tsercommcomp.png b/mseide-msegui/icons/components/tsercommcomp.png new file mode 100644 index 0000000..deb6f18 Binary files /dev/null and b/mseide-msegui/icons/components/tsercommcomp.png differ diff --git a/mseide-msegui/icons/components/tsercommcomp.svg b/mseide-msegui/icons/components/tsercommcomp.svg new file mode 100644 index 0000000..6fc1441 --- /dev/null +++ b/mseide-msegui/icons/components/tsercommcomp.svg @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + ASYNCOMM + + diff --git a/mseide-msegui/icons/components/tshortcut.bmp b/mseide-msegui/icons/components/tshortcut.bmp new file mode 100644 index 0000000..c7a36fb Binary files /dev/null and b/mseide-msegui/icons/components/tshortcut.bmp differ diff --git a/mseide-msegui/icons/components/tshortcutcontroller.bmp b/mseide-msegui/icons/components/tshortcutcontroller.bmp new file mode 100644 index 0000000..584efa7 Binary files /dev/null and b/mseide-msegui/icons/components/tshortcutcontroller.bmp differ diff --git a/mseide-msegui/icons/components/tshortcutcontroller.png b/mseide-msegui/icons/components/tshortcutcontroller.png new file mode 100644 index 0000000..15c9bc1 Binary files /dev/null and b/mseide-msegui/icons/components/tshortcutcontroller.png differ diff --git a/mseide-msegui/icons/components/tshortcutcontroller.svg b/mseide-msegui/icons/components/tshortcutcontroller.svg new file mode 100644 index 0000000..e6dd5b1 --- /dev/null +++ b/mseide-msegui/icons/components/tshortcutcontroller.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Ctrl + + + diff --git a/mseide-msegui/icons/components/tsigadd.png b/mseide-msegui/icons/components/tsigadd.png new file mode 100644 index 0000000..dfba5ad Binary files /dev/null and b/mseide-msegui/icons/components/tsigadd.png differ diff --git a/mseide-msegui/icons/components/tsigadd.svg b/mseide-msegui/icons/components/tsigadd.svg new file mode 100644 index 0000000..20e7125 --- /dev/null +++ b/mseide-msegui/icons/components/tsigadd.svg @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigconnector.png b/mseide-msegui/icons/components/tsigconnector.png new file mode 100644 index 0000000..7f9bfb0 Binary files /dev/null and b/mseide-msegui/icons/components/tsigconnector.png differ diff --git a/mseide-msegui/icons/components/tsigconnector.svg b/mseide-msegui/icons/components/tsigconnector.svg new file mode 100644 index 0000000..fe01046 --- /dev/null +++ b/mseide-msegui/icons/components/tsigconnector.svg @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigcontroller.png b/mseide-msegui/icons/components/tsigcontroller.png new file mode 100644 index 0000000..174aff3 Binary files /dev/null and b/mseide-msegui/icons/components/tsigcontroller.png differ diff --git a/mseide-msegui/icons/components/tsigcontroller.svg b/mseide-msegui/icons/components/tsigcontroller.svg new file mode 100644 index 0000000..ac58162 --- /dev/null +++ b/mseide-msegui/icons/components/tsigcontroller.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + C + + + diff --git a/mseide-msegui/icons/components/tsigdelay.png b/mseide-msegui/icons/components/tsigdelay.png new file mode 100644 index 0000000..db381b0 Binary files /dev/null and b/mseide-msegui/icons/components/tsigdelay.png differ diff --git a/mseide-msegui/icons/components/tsigdelay.svg b/mseide-msegui/icons/components/tsigdelay.svg new file mode 100644 index 0000000..8f90d2e --- /dev/null +++ b/mseide-msegui/icons/components/tsigdelay.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Z + -1 + + diff --git a/mseide-msegui/icons/components/tsigdelayn.png b/mseide-msegui/icons/components/tsigdelayn.png new file mode 100644 index 0000000..676fdf8 Binary files /dev/null and b/mseide-msegui/icons/components/tsigdelayn.png differ diff --git a/mseide-msegui/icons/components/tsigdelayn.svg b/mseide-msegui/icons/components/tsigdelayn.svg new file mode 100644 index 0000000..bb53e57 --- /dev/null +++ b/mseide-msegui/icons/components/tsigdelayn.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Z + -N + + diff --git a/mseide-msegui/icons/components/tsigdelayvar.png b/mseide-msegui/icons/components/tsigdelayvar.png new file mode 100644 index 0000000..1a35109 Binary files /dev/null and b/mseide-msegui/icons/components/tsigdelayvar.png differ diff --git a/mseide-msegui/icons/components/tsigdelayvar.svg b/mseide-msegui/icons/components/tsigdelayvar.svg new file mode 100644 index 0000000..4670601 --- /dev/null +++ b/mseide-msegui/icons/components/tsigdelayvar.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Z + -X + + diff --git a/mseide-msegui/icons/components/tsigenvelope.png b/mseide-msegui/icons/components/tsigenvelope.png new file mode 100644 index 0000000..5a8545b Binary files /dev/null and b/mseide-msegui/icons/components/tsigenvelope.png differ diff --git a/mseide-msegui/icons/components/tsigenvelope.svg b/mseide-msegui/icons/components/tsigenvelope.svg new file mode 100644 index 0000000..5901301 --- /dev/null +++ b/mseide-msegui/icons/components/tsigenvelope.svg @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigfft.png b/mseide-msegui/icons/components/tsigfft.png new file mode 100644 index 0000000..3b458b3 Binary files /dev/null and b/mseide-msegui/icons/components/tsigfft.png differ diff --git a/mseide-msegui/icons/components/tsigfft.svg b/mseide-msegui/icons/components/tsigfft.svg new file mode 100644 index 0000000..ede89af --- /dev/null +++ b/mseide-msegui/icons/components/tsigfft.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + FFT + + + diff --git a/mseide-msegui/icons/components/tsigfilter.png b/mseide-msegui/icons/components/tsigfilter.png new file mode 100644 index 0000000..7a059f0 Binary files /dev/null and b/mseide-msegui/icons/components/tsigfilter.png differ diff --git a/mseide-msegui/icons/components/tsigfilter.svg b/mseide-msegui/icons/components/tsigfilter.svg new file mode 100644 index 0000000..089741e --- /dev/null +++ b/mseide-msegui/icons/components/tsigfilter.svg @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigfilterbank.png b/mseide-msegui/icons/components/tsigfilterbank.png new file mode 100644 index 0000000..8a21bae Binary files /dev/null and b/mseide-msegui/icons/components/tsigfilterbank.png differ diff --git a/mseide-msegui/icons/components/tsigfilterbank.svg b/mseide-msegui/icons/components/tsigfilterbank.svg new file mode 100644 index 0000000..6d77dbb --- /dev/null +++ b/mseide-msegui/icons/components/tsigfilterbank.svg @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigfir.png b/mseide-msegui/icons/components/tsigfir.png new file mode 100644 index 0000000..4099147 Binary files /dev/null and b/mseide-msegui/icons/components/tsigfir.png differ diff --git a/mseide-msegui/icons/components/tsigfir.svg b/mseide-msegui/icons/components/tsigfir.svg new file mode 100644 index 0000000..f8a739f --- /dev/null +++ b/mseide-msegui/icons/components/tsigfir.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + FIR + + + diff --git a/mseide-msegui/icons/components/tsigfunctable.png b/mseide-msegui/icons/components/tsigfunctable.png new file mode 100644 index 0000000..aefe450 Binary files /dev/null and b/mseide-msegui/icons/components/tsigfunctable.png differ diff --git a/mseide-msegui/icons/components/tsigfunctable.svg b/mseide-msegui/icons/components/tsigfunctable.svg new file mode 100644 index 0000000..c905f26 --- /dev/null +++ b/mseide-msegui/icons/components/tsigfunctable.svg @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigfuncttable.png b/mseide-msegui/icons/components/tsigfuncttable.png new file mode 100644 index 0000000..aefe450 Binary files /dev/null and b/mseide-msegui/icons/components/tsigfuncttable.png differ diff --git a/mseide-msegui/icons/components/tsigfuncttable.svg b/mseide-msegui/icons/components/tsigfuncttable.svg new file mode 100644 index 0000000..85235b8 --- /dev/null +++ b/mseide-msegui/icons/components/tsigfuncttable.svg @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigiir.png b/mseide-msegui/icons/components/tsigiir.png new file mode 100644 index 0000000..7374eb4 Binary files /dev/null and b/mseide-msegui/icons/components/tsigiir.png differ diff --git a/mseide-msegui/icons/components/tsigiir.svg b/mseide-msegui/icons/components/tsigiir.svg new file mode 100644 index 0000000..c150e06 --- /dev/null +++ b/mseide-msegui/icons/components/tsigiir.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + IIR + + + diff --git a/mseide-msegui/icons/components/tsigin.png b/mseide-msegui/icons/components/tsigin.png new file mode 100644 index 0000000..6b7856d Binary files /dev/null and b/mseide-msegui/icons/components/tsigin.png differ diff --git a/mseide-msegui/icons/components/tsigin.svg b/mseide-msegui/icons/components/tsigin.svg new file mode 100644 index 0000000..1dd960a --- /dev/null +++ b/mseide-msegui/icons/components/tsigin.svg @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + IN + + + + + + + diff --git a/mseide-msegui/icons/components/tsigkeyboard.png b/mseide-msegui/icons/components/tsigkeyboard.png new file mode 100644 index 0000000..71a5e5f Binary files /dev/null and b/mseide-msegui/icons/components/tsigkeyboard.png differ diff --git a/mseide-msegui/icons/components/tsigkeyboard.svg b/mseide-msegui/icons/components/tsigkeyboard.svg new file mode 100644 index 0000000..db6fbec --- /dev/null +++ b/mseide-msegui/icons/components/tsigkeyboard.svg @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigmidiconnector.png b/mseide-msegui/icons/components/tsigmidiconnector.png new file mode 100644 index 0000000..8bf3f79 Binary files /dev/null and b/mseide-msegui/icons/components/tsigmidiconnector.png differ diff --git a/mseide-msegui/icons/components/tsigmidiconnector.svg b/mseide-msegui/icons/components/tsigmidiconnector.svg new file mode 100644 index 0000000..389d471 --- /dev/null +++ b/mseide-msegui/icons/components/tsigmidiconnector.svg @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + MIDI + + + diff --git a/mseide-msegui/icons/components/tsigmidimulticonnector.png b/mseide-msegui/icons/components/tsigmidimulticonnector.png new file mode 100644 index 0000000..0564709 Binary files /dev/null and b/mseide-msegui/icons/components/tsigmidimulticonnector.png differ diff --git a/mseide-msegui/icons/components/tsigmidimulticonnector.svg b/mseide-msegui/icons/components/tsigmidimulticonnector.svg new file mode 100644 index 0000000..2397db3 --- /dev/null +++ b/mseide-msegui/icons/components/tsigmidimulticonnector.svg @@ -0,0 +1,311 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MIDI + + + diff --git a/mseide-msegui/icons/components/tsigmidisource.png b/mseide-msegui/icons/components/tsigmidisource.png new file mode 100644 index 0000000..e8eaa62 Binary files /dev/null and b/mseide-msegui/icons/components/tsigmidisource.png differ diff --git a/mseide-msegui/icons/components/tsigmidisource.svg b/mseide-msegui/icons/components/tsigmidisource.svg new file mode 100644 index 0000000..d5d0e87 --- /dev/null +++ b/mseide-msegui/icons/components/tsigmidisource.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + MIDI + + + diff --git a/mseide-msegui/icons/components/tsigmult.png b/mseide-msegui/icons/components/tsigmult.png new file mode 100644 index 0000000..79ddc88 Binary files /dev/null and b/mseide-msegui/icons/components/tsigmult.png differ diff --git a/mseide-msegui/icons/components/tsigmult.svg b/mseide-msegui/icons/components/tsigmult.svg new file mode 100644 index 0000000..e14f0ab --- /dev/null +++ b/mseide-msegui/icons/components/tsigmult.svg @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + * + + diff --git a/mseide-msegui/icons/components/tsignoise.png b/mseide-msegui/icons/components/tsignoise.png new file mode 100644 index 0000000..fb38616 Binary files /dev/null and b/mseide-msegui/icons/components/tsignoise.png differ diff --git a/mseide-msegui/icons/components/tsignoise.svg b/mseide-msegui/icons/components/tsignoise.svg new file mode 100644 index 0000000..572994a --- /dev/null +++ b/mseide-msegui/icons/components/tsignoise.svg @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigout.png b/mseide-msegui/icons/components/tsigout.png new file mode 100644 index 0000000..aa6ef42 Binary files /dev/null and b/mseide-msegui/icons/components/tsigout.png differ diff --git a/mseide-msegui/icons/components/tsigout.svg b/mseide-msegui/icons/components/tsigout.svg new file mode 100644 index 0000000..d1de9fd --- /dev/null +++ b/mseide-msegui/icons/components/tsigout.svg @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + OUT + + + + + + + diff --git a/mseide-msegui/icons/components/tsigoutaudio.png b/mseide-msegui/icons/components/tsigoutaudio.png new file mode 100644 index 0000000..b553262 Binary files /dev/null and b/mseide-msegui/icons/components/tsigoutaudio.png differ diff --git a/mseide-msegui/icons/components/tsigoutaudio.svg b/mseide-msegui/icons/components/tsigoutaudio.svg new file mode 100644 index 0000000..a3a4e61 --- /dev/null +++ b/mseide-msegui/icons/components/tsigoutaudio.svg @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + AUDIO + + + + + + + diff --git a/mseide-msegui/icons/components/tsigsampler.png b/mseide-msegui/icons/components/tsigsampler.png new file mode 100644 index 0000000..f31928d Binary files /dev/null and b/mseide-msegui/icons/components/tsigsampler.png differ diff --git a/mseide-msegui/icons/components/tsigsampler.svg b/mseide-msegui/icons/components/tsigsampler.svg new file mode 100644 index 0000000..fe7360a --- /dev/null +++ b/mseide-msegui/icons/components/tsigsampler.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SAMPLE + + + diff --git a/mseide-msegui/icons/components/tsigsamplerfft.png b/mseide-msegui/icons/components/tsigsamplerfft.png new file mode 100644 index 0000000..c046f01 Binary files /dev/null and b/mseide-msegui/icons/components/tsigsamplerfft.png differ diff --git a/mseide-msegui/icons/components/tsigsamplerfft.svg b/mseide-msegui/icons/components/tsigsamplerfft.svg new file mode 100644 index 0000000..01fd6b9 --- /dev/null +++ b/mseide-msegui/icons/components/tsigsamplerfft.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SAMFFT + + + diff --git a/mseide-msegui/icons/components/tsigscope.png b/mseide-msegui/icons/components/tsigscope.png new file mode 100644 index 0000000..f292f6a Binary files /dev/null and b/mseide-msegui/icons/components/tsigscope.png differ diff --git a/mseide-msegui/icons/components/tsigscope.svg b/mseide-msegui/icons/components/tsigscope.svg new file mode 100644 index 0000000..8cc7830 --- /dev/null +++ b/mseide-msegui/icons/components/tsigscope.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigscopefft.png b/mseide-msegui/icons/components/tsigscopefft.png new file mode 100644 index 0000000..af30ac5 Binary files /dev/null and b/mseide-msegui/icons/components/tsigscopefft.png differ diff --git a/mseide-msegui/icons/components/tsigscopefft.svg b/mseide-msegui/icons/components/tsigscopefft.svg new file mode 100644 index 0000000..9e9dcb1 --- /dev/null +++ b/mseide-msegui/icons/components/tsigscopefft.svg @@ -0,0 +1,380 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigwavetable.png b/mseide-msegui/icons/components/tsigwavetable.png new file mode 100644 index 0000000..c67ba4b Binary files /dev/null and b/mseide-msegui/icons/components/tsigwavetable.png differ diff --git a/mseide-msegui/icons/components/tsigwavetable.svg b/mseide-msegui/icons/components/tsigwavetable.svg new file mode 100644 index 0000000..b271e6e --- /dev/null +++ b/mseide-msegui/icons/components/tsigwavetable.svg @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsimplewidget.bmp b/mseide-msegui/icons/components/tsimplewidget.bmp new file mode 100644 index 0000000..41f7694 Binary files /dev/null and b/mseide-msegui/icons/components/tsimplewidget.bmp differ diff --git a/mseide-msegui/icons/components/tsimplewidget.png b/mseide-msegui/icons/components/tsimplewidget.png new file mode 100644 index 0000000..2227dd3 Binary files /dev/null and b/mseide-msegui/icons/components/tsimplewidget.png differ diff --git a/mseide-msegui/icons/components/tsimplewidget.svg b/mseide-msegui/icons/components/tsimplewidget.svg new file mode 100644 index 0000000..4ab12a8 --- /dev/null +++ b/mseide-msegui/icons/components/tsimplewidget.svg @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsimplewidgt.bmp b/mseide-msegui/icons/components/tsimplewidgt.bmp new file mode 100644 index 0000000..6776551 Binary files /dev/null and b/mseide-msegui/icons/components/tsimplewidgt.bmp differ diff --git a/mseide-msegui/icons/components/tskincontroller.bmp b/mseide-msegui/icons/components/tskincontroller.bmp new file mode 100644 index 0000000..c7a36fb Binary files /dev/null and b/mseide-msegui/icons/components/tskincontroller.bmp differ diff --git a/mseide-msegui/icons/components/tskincontroller.png b/mseide-msegui/icons/components/tskincontroller.png new file mode 100644 index 0000000..78d38c0 Binary files /dev/null and b/mseide-msegui/icons/components/tskincontroller.png differ diff --git a/mseide-msegui/icons/components/tskincontroller.svg b/mseide-msegui/icons/components/tskincontroller.svg new file mode 100644 index 0000000..4c1fe9e --- /dev/null +++ b/mseide-msegui/icons/components/tskincontroller.svg @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tskinextender.png b/mseide-msegui/icons/components/tskinextender.png new file mode 100644 index 0000000..1a63ef7 Binary files /dev/null and b/mseide-msegui/icons/components/tskinextender.png differ diff --git a/mseide-msegui/icons/components/tskinextender.svg b/mseide-msegui/icons/components/tskinextender.svg new file mode 100644 index 0000000..204d831 --- /dev/null +++ b/mseide-msegui/icons/components/tskinextender.svg @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tslider.bmp b/mseide-msegui/icons/components/tslider.bmp new file mode 100755 index 0000000..e5c99b9 Binary files /dev/null and b/mseide-msegui/icons/components/tslider.bmp differ diff --git a/mseide-msegui/icons/components/tslider.png b/mseide-msegui/icons/components/tslider.png new file mode 100644 index 0000000..eaae375 Binary files /dev/null and b/mseide-msegui/icons/components/tslider.png differ diff --git a/mseide-msegui/icons/components/tslider.svg b/mseide-msegui/icons/components/tslider.svg new file mode 100644 index 0000000..2a859dc --- /dev/null +++ b/mseide-msegui/icons/components/tslider.svg @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsocketclient.bmp b/mseide-msegui/icons/components/tsocketclient.bmp new file mode 100644 index 0000000..c9c6364 Binary files /dev/null and b/mseide-msegui/icons/components/tsocketclient.bmp differ diff --git a/mseide-msegui/icons/components/tsocketclientiochannel.bmp b/mseide-msegui/icons/components/tsocketclientiochannel.bmp new file mode 100644 index 0000000..c3de896 Binary files /dev/null and b/mseide-msegui/icons/components/tsocketclientiochannel.bmp differ diff --git a/mseide-msegui/icons/components/tsocketclientstdio.bmp b/mseide-msegui/icons/components/tsocketclientstdio.bmp new file mode 100644 index 0000000..248a930 Binary files /dev/null and b/mseide-msegui/icons/components/tsocketclientstdio.bmp differ diff --git a/mseide-msegui/icons/components/tsocketserver.bmp b/mseide-msegui/icons/components/tsocketserver.bmp new file mode 100644 index 0000000..af15eca Binary files /dev/null and b/mseide-msegui/icons/components/tsocketserver.bmp differ diff --git a/mseide-msegui/icons/components/tsocketserveriochannel.bmp b/mseide-msegui/icons/components/tsocketserveriochannel.bmp new file mode 100644 index 0000000..d034f79 Binary files /dev/null and b/mseide-msegui/icons/components/tsocketserveriochannel.bmp differ diff --git a/mseide-msegui/icons/components/tsocketserverstdio.bmp b/mseide-msegui/icons/components/tsocketserverstdio.bmp new file mode 100644 index 0000000..cacc18d Binary files /dev/null and b/mseide-msegui/icons/components/tsocketserverstdio.bmp differ diff --git a/mseide-msegui/icons/components/tsocketstdio.bmp b/mseide-msegui/icons/components/tsocketstdio.bmp new file mode 100644 index 0000000..1c8fd56 Binary files /dev/null and b/mseide-msegui/icons/components/tsocketstdio.bmp differ diff --git a/mseide-msegui/icons/components/tsocketstdiochannel.bmp b/mseide-msegui/icons/components/tsocketstdiochannel.bmp new file mode 100644 index 0000000..f7de9b4 Binary files /dev/null and b/mseide-msegui/icons/components/tsocketstdiochannel.bmp differ diff --git a/mseide-msegui/icons/components/tsourceedit.png b/mseide-msegui/icons/components/tsourceedit.png new file mode 100644 index 0000000..9e77c54 Binary files /dev/null and b/mseide-msegui/icons/components/tsourceedit.png differ diff --git a/mseide-msegui/icons/components/tsourceedit.svg b/mseide-msegui/icons/components/tsourceedit.svg new file mode 100644 index 0000000..95e5c5e --- /dev/null +++ b/mseide-msegui/icons/components/tsourceedit.svg @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + Past fret fejgz Okfrevlfgay OvfrdWios Tzjly Abcs + + + S + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tspacer.bmp b/mseide-msegui/icons/components/tspacer.bmp new file mode 100644 index 0000000..bd1572e Binary files /dev/null and b/mseide-msegui/icons/components/tspacer.bmp differ diff --git a/mseide-msegui/icons/components/tspacer.png b/mseide-msegui/icons/components/tspacer.png new file mode 100644 index 0000000..47e8307 Binary files /dev/null and b/mseide-msegui/icons/components/tspacer.png differ diff --git a/mseide-msegui/icons/components/tspacer.svg b/mseide-msegui/icons/components/tspacer.svg new file mode 100644 index 0000000..3d3d176 --- /dev/null +++ b/mseide-msegui/icons/components/tspacer.svg @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsplitter.bmp b/mseide-msegui/icons/components/tsplitter.bmp new file mode 100755 index 0000000..b72f899 Binary files /dev/null and b/mseide-msegui/icons/components/tsplitter.bmp differ diff --git a/mseide-msegui/icons/components/tsplitter.png b/mseide-msegui/icons/components/tsplitter.png new file mode 100644 index 0000000..ede58ee Binary files /dev/null and b/mseide-msegui/icons/components/tsplitter.png differ diff --git a/mseide-msegui/icons/components/tsplitter.svg b/mseide-msegui/icons/components/tsplitter.svg new file mode 100644 index 0000000..394e5ba --- /dev/null +++ b/mseide-msegui/icons/components/tsplitter.svg @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsqlite3connection.bmp b/mseide-msegui/icons/components/tsqlite3connection.bmp new file mode 100644 index 0000000..3bd6a1e Binary files /dev/null and b/mseide-msegui/icons/components/tsqlite3connection.bmp differ diff --git a/mseide-msegui/icons/components/tsqllookupbuffer.bmp b/mseide-msegui/icons/components/tsqllookupbuffer.bmp new file mode 100644 index 0000000..5cc0ee3 Binary files /dev/null and b/mseide-msegui/icons/components/tsqllookupbuffer.bmp differ diff --git a/mseide-msegui/icons/components/tsqllookupbuffer.png b/mseide-msegui/icons/components/tsqllookupbuffer.png new file mode 100644 index 0000000..6670ca8 Binary files /dev/null and b/mseide-msegui/icons/components/tsqllookupbuffer.png differ diff --git a/mseide-msegui/icons/components/tsqlresult.bmp b/mseide-msegui/icons/components/tsqlresult.bmp new file mode 100644 index 0000000..a85ab5a Binary files /dev/null and b/mseide-msegui/icons/components/tsqlresult.bmp differ diff --git a/mseide-msegui/icons/components/tsqlresult.png b/mseide-msegui/icons/components/tsqlresult.png new file mode 100644 index 0000000..c9ace6f Binary files /dev/null and b/mseide-msegui/icons/components/tsqlresult.png differ diff --git a/mseide-msegui/icons/components/tsqlresult.svg b/mseide-msegui/icons/components/tsqlresult.svg new file mode 100644 index 0000000..460dd08 --- /dev/null +++ b/mseide-msegui/icons/components/tsqlresult.svg @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsqlresultconnector.png b/mseide-msegui/icons/components/tsqlresultconnector.png new file mode 100644 index 0000000..ae2ebdf Binary files /dev/null and b/mseide-msegui/icons/components/tsqlresultconnector.png differ diff --git a/mseide-msegui/icons/components/tsqlresultconnector.svg b/mseide-msegui/icons/components/tsqlresultconnector.svg new file mode 100644 index 0000000..5c90293 --- /dev/null +++ b/mseide-msegui/icons/components/tsqlresultconnector.svg @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + COL + + + + + diff --git a/mseide-msegui/icons/components/tsqlstatement.bmp b/mseide-msegui/icons/components/tsqlstatement.bmp new file mode 100644 index 0000000..0ff9971 Binary files /dev/null and b/mseide-msegui/icons/components/tsqlstatement.bmp differ diff --git a/mseide-msegui/icons/components/tsqlstatement.png b/mseide-msegui/icons/components/tsqlstatement.png new file mode 100644 index 0000000..4f5a22c Binary files /dev/null and b/mseide-msegui/icons/components/tsqlstatement.png differ diff --git a/mseide-msegui/icons/components/tsqlstatement.svg b/mseide-msegui/icons/components/tsqlstatement.svg new file mode 100644 index 0000000..c6bbeb5 --- /dev/null +++ b/mseide-msegui/icons/components/tsqlstatement.svg @@ -0,0 +1,397 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tssl.bmp b/mseide-msegui/icons/components/tssl.bmp new file mode 100644 index 0000000..2ca5d5b Binary files /dev/null and b/mseide-msegui/icons/components/tssl.bmp differ diff --git a/mseide-msegui/icons/components/tstatfile.bmp b/mseide-msegui/icons/components/tstatfile.bmp new file mode 100755 index 0000000..659fd51 Binary files /dev/null and b/mseide-msegui/icons/components/tstatfile.bmp differ diff --git a/mseide-msegui/icons/components/tstatfile.png b/mseide-msegui/icons/components/tstatfile.png new file mode 100644 index 0000000..4f8b5fa Binary files /dev/null and b/mseide-msegui/icons/components/tstatfile.png differ diff --git a/mseide-msegui/icons/components/tstatfile.svg b/mseide-msegui/icons/components/tstatfile.svg new file mode 100644 index 0000000..0de3c89 --- /dev/null +++ b/mseide-msegui/icons/components/tstatfile.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + *.sta + + diff --git a/mseide-msegui/icons/components/tstepbox.bmp b/mseide-msegui/icons/components/tstepbox.bmp new file mode 100755 index 0000000..f9998e2 Binary files /dev/null and b/mseide-msegui/icons/components/tstepbox.bmp differ diff --git a/mseide-msegui/icons/components/tstepbox.png b/mseide-msegui/icons/components/tstepbox.png new file mode 100644 index 0000000..197d826 Binary files /dev/null and b/mseide-msegui/icons/components/tstepbox.png differ diff --git a/mseide-msegui/icons/components/tstepbox.svg b/mseide-msegui/icons/components/tstepbox.svg new file mode 100644 index 0000000..08a3324 --- /dev/null +++ b/mseide-msegui/icons/components/tstepbox.svg @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tstingdisp.png b/mseide-msegui/icons/components/tstingdisp.png new file mode 100644 index 0000000..4d6273c Binary files /dev/null and b/mseide-msegui/icons/components/tstingdisp.png differ diff --git a/mseide-msegui/icons/components/tstockglyphbutton.bmp b/mseide-msegui/icons/components/tstockglyphbutton.bmp new file mode 100755 index 0000000..5ab95b6 Binary files /dev/null and b/mseide-msegui/icons/components/tstockglyphbutton.bmp differ diff --git a/mseide-msegui/icons/components/tstockglyphbutton.png b/mseide-msegui/icons/components/tstockglyphbutton.png new file mode 100644 index 0000000..5322820 Binary files /dev/null and b/mseide-msegui/icons/components/tstockglyphbutton.png differ diff --git a/mseide-msegui/icons/components/tstockglyphbutton.svg b/mseide-msegui/icons/components/tstockglyphbutton.svg new file mode 100644 index 0000000..9838b92 --- /dev/null +++ b/mseide-msegui/icons/components/tstockglyphbutton.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tstockglyphdatabutton.bmp b/mseide-msegui/icons/components/tstockglyphdatabutton.bmp new file mode 100644 index 0000000..87a3aba Binary files /dev/null and b/mseide-msegui/icons/components/tstockglyphdatabutton.bmp differ diff --git a/mseide-msegui/icons/components/tstockglyphdatabutton.png b/mseide-msegui/icons/components/tstockglyphdatabutton.png new file mode 100644 index 0000000..8db6b32 Binary files /dev/null and b/mseide-msegui/icons/components/tstockglyphdatabutton.png differ diff --git a/mseide-msegui/icons/components/tstockglyphdatabutton.svg b/mseide-msegui/icons/components/tstockglyphdatabutton.svg new file mode 100644 index 0000000..603fb2d --- /dev/null +++ b/mseide-msegui/icons/components/tstockglyphdatabutton.svg @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tstringcontainer.png b/mseide-msegui/icons/components/tstringcontainer.png new file mode 100644 index 0000000..878c39e Binary files /dev/null and b/mseide-msegui/icons/components/tstringcontainer.png differ diff --git a/mseide-msegui/icons/components/tstringcontainer.svg b/mseide-msegui/icons/components/tstringcontainer.svg new file mode 100644 index 0000000..69dda92 --- /dev/null +++ b/mseide-msegui/icons/components/tstringcontainer.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Str1Str2 + + diff --git a/mseide-msegui/icons/components/tstringdisp.bmp b/mseide-msegui/icons/components/tstringdisp.bmp new file mode 100755 index 0000000..62ee6e3 Binary files /dev/null and b/mseide-msegui/icons/components/tstringdisp.bmp differ diff --git a/mseide-msegui/icons/components/tstringdisp.png b/mseide-msegui/icons/components/tstringdisp.png new file mode 100644 index 0000000..4d6273c Binary files /dev/null and b/mseide-msegui/icons/components/tstringdisp.png differ diff --git a/mseide-msegui/icons/components/tstringdisp.svg b/mseide-msegui/icons/components/tstringdisp.svg new file mode 100644 index 0000000..22e05ae --- /dev/null +++ b/mseide-msegui/icons/components/tstringdisp.svg @@ -0,0 +1,380 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + abc + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tstringedit.bmp b/mseide-msegui/icons/components/tstringedit.bmp new file mode 100755 index 0000000..ed48b01 Binary files /dev/null and b/mseide-msegui/icons/components/tstringedit.bmp differ diff --git a/mseide-msegui/icons/components/tstringedit.png b/mseide-msegui/icons/components/tstringedit.png new file mode 100644 index 0000000..420957b Binary files /dev/null and b/mseide-msegui/icons/components/tstringedit.png differ diff --git a/mseide-msegui/icons/components/tstringedit.svg b/mseide-msegui/icons/components/tstringedit.svg new file mode 100644 index 0000000..fe34e1d --- /dev/null +++ b/mseide-msegui/icons/components/tstringedit.svg @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tstringgrid.bmp b/mseide-msegui/icons/components/tstringgrid.bmp new file mode 100755 index 0000000..e408e98 Binary files /dev/null and b/mseide-msegui/icons/components/tstringgrid.bmp differ diff --git a/mseide-msegui/icons/components/tstringgrid.png b/mseide-msegui/icons/components/tstringgrid.png new file mode 100644 index 0000000..ad10f3f Binary files /dev/null and b/mseide-msegui/icons/components/tstringgrid.png differ diff --git a/mseide-msegui/icons/components/tstringgrid.svg b/mseide-msegui/icons/components/tstringgrid.svg new file mode 100644 index 0000000..f1133b0 --- /dev/null +++ b/mseide-msegui/icons/components/tstringgrid.svg @@ -0,0 +1,564 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + Ugx + 123 + 78 + 00 + 233 + 15 + + + + + + + + + + + + + + + ABC + + + diff --git a/mseide-msegui/icons/components/tsymciphercryptohandler.png b/mseide-msegui/icons/components/tsymciphercryptohandler.png new file mode 100644 index 0000000..0fbfcfd Binary files /dev/null and b/mseide-msegui/icons/components/tsymciphercryptohandler.png differ diff --git a/mseide-msegui/icons/components/tsymciphercryptohandler.svg b/mseide-msegui/icons/components/tsymciphercryptohandler.svg new file mode 100644 index 0000000..1c7b848 --- /dev/null +++ b/mseide-msegui/icons/components/tsymciphercryptohandler.svg @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SYM + cryp + + diff --git a/mseide-msegui/icons/components/tsyntaxedit.bmp b/mseide-msegui/icons/components/tsyntaxedit.bmp new file mode 100755 index 0000000..c2d4e48 Binary files /dev/null and b/mseide-msegui/icons/components/tsyntaxedit.bmp differ diff --git a/mseide-msegui/icons/components/tsyntaxedit.png b/mseide-msegui/icons/components/tsyntaxedit.png new file mode 100644 index 0000000..9e77c54 Binary files /dev/null and b/mseide-msegui/icons/components/tsyntaxedit.png differ diff --git a/mseide-msegui/icons/components/tsyntaxedit.svg b/mseide-msegui/icons/components/tsyntaxedit.svg new file mode 100644 index 0000000..0ef42fd --- /dev/null +++ b/mseide-msegui/icons/components/tsyntaxedit.svg @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + Past fret fejgz Okfrevlfgay OvfrdWios Tzjly Abcs + + + S + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsyntaxpainter.bmp b/mseide-msegui/icons/components/tsyntaxpainter.bmp new file mode 100755 index 0000000..2f44b98 Binary files /dev/null and b/mseide-msegui/icons/components/tsyntaxpainter.bmp differ diff --git a/mseide-msegui/icons/components/tsysenvmanager.bmp b/mseide-msegui/icons/components/tsysenvmanager.bmp new file mode 100755 index 0000000..b848aa0 Binary files /dev/null and b/mseide-msegui/icons/components/tsysenvmanager.bmp differ diff --git a/mseide-msegui/icons/components/tsysenvmanager.png b/mseide-msegui/icons/components/tsysenvmanager.png new file mode 100644 index 0000000..a3250c8 Binary files /dev/null and b/mseide-msegui/icons/components/tsysenvmanager.png differ diff --git a/mseide-msegui/icons/components/tsysenvmanager.svg b/mseide-msegui/icons/components/tsysenvmanager.svg new file mode 100644 index 0000000..0a7cc39 --- /dev/null +++ b/mseide-msegui/icons/components/tsysenvmanager.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + -par$env + + diff --git a/mseide-msegui/icons/components/ttabbar.bmp b/mseide-msegui/icons/components/ttabbar.bmp new file mode 100755 index 0000000..788e036 Binary files /dev/null and b/mseide-msegui/icons/components/ttabbar.bmp differ diff --git a/mseide-msegui/icons/components/ttabbar.png b/mseide-msegui/icons/components/ttabbar.png new file mode 100644 index 0000000..fca5e09 Binary files /dev/null and b/mseide-msegui/icons/components/ttabbar.png differ diff --git a/mseide-msegui/icons/components/ttabbar.svg b/mseide-msegui/icons/components/ttabbar.svg new file mode 100644 index 0000000..97b4c41 --- /dev/null +++ b/mseide-msegui/icons/components/ttabbar.svg @@ -0,0 +1,440 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + Ode + Pziuo + + diff --git a/mseide-msegui/icons/components/ttabpage.bmp b/mseide-msegui/icons/components/ttabpage.bmp new file mode 100755 index 0000000..63209bf Binary files /dev/null and b/mseide-msegui/icons/components/ttabpage.bmp differ diff --git a/mseide-msegui/icons/components/ttabpage.png b/mseide-msegui/icons/components/ttabpage.png new file mode 100644 index 0000000..a8fa3b5 Binary files /dev/null and b/mseide-msegui/icons/components/ttabpage.png differ diff --git a/mseide-msegui/icons/components/ttabpage.svg b/mseide-msegui/icons/components/ttabpage.svg new file mode 100644 index 0000000..0cac5e3 --- /dev/null +++ b/mseide-msegui/icons/components/ttabpage.svg @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Ode + Pziuo + + diff --git a/mseide-msegui/icons/components/ttabwidget.bmp b/mseide-msegui/icons/components/ttabwidget.bmp new file mode 100755 index 0000000..41fa786 Binary files /dev/null and b/mseide-msegui/icons/components/ttabwidget.bmp differ diff --git a/mseide-msegui/icons/components/ttabwidget.png b/mseide-msegui/icons/components/ttabwidget.png new file mode 100644 index 0000000..398274f Binary files /dev/null and b/mseide-msegui/icons/components/ttabwidget.png differ diff --git a/mseide-msegui/icons/components/ttabwidget.svg b/mseide-msegui/icons/components/ttabwidget.svg new file mode 100644 index 0000000..bb46a70 --- /dev/null +++ b/mseide-msegui/icons/components/ttabwidget.svg @@ -0,0 +1,483 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Ode + Pziuo + + diff --git a/mseide-msegui/icons/components/tterminal.bmp b/mseide-msegui/icons/components/tterminal.bmp new file mode 100755 index 0000000..9f4e859 Binary files /dev/null and b/mseide-msegui/icons/components/tterminal.bmp differ diff --git a/mseide-msegui/icons/components/tterminal.png b/mseide-msegui/icons/components/tterminal.png new file mode 100644 index 0000000..6119cbb Binary files /dev/null and b/mseide-msegui/icons/components/tterminal.png differ diff --git a/mseide-msegui/icons/components/tterminal.svg b/mseide-msegui/icons/components/tterminal.svg new file mode 100644 index 0000000..352f07a --- /dev/null +++ b/mseide-msegui/icons/components/tterminal.svg @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + ~> + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttextedit.bmp b/mseide-msegui/icons/components/ttextedit.bmp new file mode 100755 index 0000000..bf316c5 Binary files /dev/null and b/mseide-msegui/icons/components/ttextedit.bmp differ diff --git a/mseide-msegui/icons/components/ttextedit.png b/mseide-msegui/icons/components/ttextedit.png new file mode 100644 index 0000000..f18afed Binary files /dev/null and b/mseide-msegui/icons/components/ttextedit.png differ diff --git a/mseide-msegui/icons/components/ttextedit.svg b/mseide-msegui/icons/components/ttextedit.svg new file mode 100644 index 0000000..cffb1c8 --- /dev/null +++ b/mseide-msegui/icons/components/ttextedit.svg @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + Past fret fejgz Okfrevlfgay OvfrdWios Tzjly Abcs + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tthreadcomp.bmp b/mseide-msegui/icons/components/tthreadcomp.bmp new file mode 100755 index 0000000..2cd5ac0 Binary files /dev/null and b/mseide-msegui/icons/components/tthreadcomp.bmp differ diff --git a/mseide-msegui/icons/components/tthreadcomp.png b/mseide-msegui/icons/components/tthreadcomp.png new file mode 100644 index 0000000..5aa881d Binary files /dev/null and b/mseide-msegui/icons/components/tthreadcomp.png differ diff --git a/mseide-msegui/icons/components/tthreadcomp.svg b/mseide-msegui/icons/components/tthreadcomp.svg new file mode 100644 index 0000000..7b9c317 --- /dev/null +++ b/mseide-msegui/icons/components/tthreadcomp.svg @@ -0,0 +1,491 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttilearea.bmp b/mseide-msegui/icons/components/ttilearea.bmp new file mode 100644 index 0000000..f0b40f0 Binary files /dev/null and b/mseide-msegui/icons/components/ttilearea.bmp differ diff --git a/mseide-msegui/icons/components/ttimer.bmp b/mseide-msegui/icons/components/ttimer.bmp new file mode 100755 index 0000000..98027cc Binary files /dev/null and b/mseide-msegui/icons/components/ttimer.bmp differ diff --git a/mseide-msegui/icons/components/ttimer.png b/mseide-msegui/icons/components/ttimer.png new file mode 100644 index 0000000..6a7a84f Binary files /dev/null and b/mseide-msegui/icons/components/ttimer.png differ diff --git a/mseide-msegui/icons/components/ttimer.svg b/mseide-msegui/icons/components/ttimer.svg new file mode 100644 index 0000000..4ce3543 --- /dev/null +++ b/mseide-msegui/icons/components/ttimer.svg @@ -0,0 +1,616 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttimestampfieldlink.bmp b/mseide-msegui/icons/components/ttimestampfieldlink.bmp new file mode 100644 index 0000000..36fc0d4 Binary files /dev/null and b/mseide-msegui/icons/components/ttimestampfieldlink.bmp differ diff --git a/mseide-msegui/icons/components/ttimestampfieldlink.png b/mseide-msegui/icons/components/ttimestampfieldlink.png new file mode 100644 index 0000000..72ba61f Binary files /dev/null and b/mseide-msegui/icons/components/ttimestampfieldlink.png differ diff --git a/mseide-msegui/icons/components/ttimestampfieldlink.svg b/mseide-msegui/icons/components/ttimestampfieldlink.svg new file mode 100644 index 0000000..8a495cc --- /dev/null +++ b/mseide-msegui/icons/components/ttimestampfieldlink.svg @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + D:TFLD + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttoolbar.bmp b/mseide-msegui/icons/components/ttoolbar.bmp new file mode 100755 index 0000000..5f37f30 Binary files /dev/null and b/mseide-msegui/icons/components/ttoolbar.bmp differ diff --git a/mseide-msegui/icons/components/ttoolbar.png b/mseide-msegui/icons/components/ttoolbar.png new file mode 100644 index 0000000..ab922d5 Binary files /dev/null and b/mseide-msegui/icons/components/ttoolbar.png differ diff --git a/mseide-msegui/icons/components/ttoolbar.svg b/mseide-msegui/icons/components/ttoolbar.svg new file mode 100644 index 0000000..f63d296 --- /dev/null +++ b/mseide-msegui/icons/components/ttoolbar.svg @@ -0,0 +1,419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttraywidget.png b/mseide-msegui/icons/components/ttraywidget.png new file mode 100644 index 0000000..777fe9e Binary files /dev/null and b/mseide-msegui/icons/components/ttraywidget.png differ diff --git a/mseide-msegui/icons/components/ttraywidget.svg b/mseide-msegui/icons/components/ttraywidget.svg new file mode 100644 index 0000000..82a3411 --- /dev/null +++ b/mseide-msegui/icons/components/ttraywidget.svg @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + Tray + + diff --git a/mseide-msegui/icons/components/ttreeitemedit.bmp b/mseide-msegui/icons/components/ttreeitemedit.bmp new file mode 100644 index 0000000..3ac2d76 Binary files /dev/null and b/mseide-msegui/icons/components/ttreeitemedit.bmp differ diff --git a/mseide-msegui/icons/components/ttreeitemedit.png b/mseide-msegui/icons/components/ttreeitemedit.png new file mode 100644 index 0000000..d67ca7b Binary files /dev/null and b/mseide-msegui/icons/components/ttreeitemedit.png differ diff --git a/mseide-msegui/icons/components/ttreeitemedit.svg b/mseide-msegui/icons/components/ttreeitemedit.svg new file mode 100644 index 0000000..145a690 --- /dev/null +++ b/mseide-msegui/icons/components/ttreeitemedit.svg @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttreeitemitemedit.png b/mseide-msegui/icons/components/ttreeitemitemedit.png new file mode 100644 index 0000000..125564f Binary files /dev/null and b/mseide-msegui/icons/components/ttreeitemitemedit.png differ diff --git a/mseide-msegui/icons/components/ttrigconnector.png b/mseide-msegui/icons/components/ttrigconnector.png new file mode 100644 index 0000000..41a1642 Binary files /dev/null and b/mseide-msegui/icons/components/ttrigconnector.png differ diff --git a/mseide-msegui/icons/components/ttrigconnector.svg b/mseide-msegui/icons/components/ttrigconnector.svg new file mode 100644 index 0000000..d169238 --- /dev/null +++ b/mseide-msegui/icons/components/ttrigconnector.svg @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttxdatagrid.bmp b/mseide-msegui/icons/components/ttxdatagrid.bmp new file mode 100644 index 0000000..f1931b0 Binary files /dev/null and b/mseide-msegui/icons/components/ttxdatagrid.bmp differ diff --git a/mseide-msegui/icons/components/ttxdataset.bmp b/mseide-msegui/icons/components/ttxdataset.bmp new file mode 100644 index 0000000..d1d77c4 Binary files /dev/null and b/mseide-msegui/icons/components/ttxdataset.bmp differ diff --git a/mseide-msegui/icons/components/ttxsqlquery.bmp b/mseide-msegui/icons/components/ttxsqlquery.bmp new file mode 100644 index 0000000..90a5d88 Binary files /dev/null and b/mseide-msegui/icons/components/ttxsqlquery.bmp differ diff --git a/mseide-msegui/icons/components/tundotextedit.png b/mseide-msegui/icons/components/tundotextedit.png new file mode 100644 index 0000000..6544ef5 Binary files /dev/null and b/mseide-msegui/icons/components/tundotextedit.png differ diff --git a/mseide-msegui/icons/components/twavetableedit.png b/mseide-msegui/icons/components/twavetableedit.png new file mode 100644 index 0000000..c9f4395 Binary files /dev/null and b/mseide-msegui/icons/components/twavetableedit.png differ diff --git a/mseide-msegui/icons/components/twavetableedit.svg b/mseide-msegui/icons/components/twavetableedit.svg new file mode 100644 index 0000000..7d70cc6 --- /dev/null +++ b/mseide-msegui/icons/components/twavetableedit.svg @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/twidgetgrid.bmp b/mseide-msegui/icons/components/twidgetgrid.bmp new file mode 100755 index 0000000..a8d34e9 Binary files /dev/null and b/mseide-msegui/icons/components/twidgetgrid.bmp differ diff --git a/mseide-msegui/icons/components/twidgetgrid.png b/mseide-msegui/icons/components/twidgetgrid.png new file mode 100644 index 0000000..3b3fa2a Binary files /dev/null and b/mseide-msegui/icons/components/twidgetgrid.png differ diff --git a/mseide-msegui/icons/components/twidgetgrid.svg b/mseide-msegui/icons/components/twidgetgrid.svg new file mode 100644 index 0000000..7ce22fc --- /dev/null +++ b/mseide-msegui/icons/components/twidgetgrid.svg @@ -0,0 +1,546 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + Ugx + 123 + 78 + 00 + 233 + 15 + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/twindowwidget.bmp b/mseide-msegui/icons/components/twindowwidget.bmp new file mode 100644 index 0000000..f4ffc46 Binary files /dev/null and b/mseide-msegui/icons/components/twindowwidget.bmp differ diff --git a/mseide-msegui/icons/components/twindowwidget.png b/mseide-msegui/icons/components/twindowwidget.png new file mode 100644 index 0000000..40e6353 Binary files /dev/null and b/mseide-msegui/icons/components/twindowwidget.png differ diff --git a/mseide-msegui/icons/components/twindowwidget.svg b/mseide-msegui/icons/components/twindowwidget.svg new file mode 100644 index 0000000..5b84dcb --- /dev/null +++ b/mseide-msegui/icons/components/twindowwidget.svg @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + WH + + + diff --git a/mseide-msegui/icons/components/twmfprinter.png b/mseide-msegui/icons/components/twmfprinter.png new file mode 100644 index 0000000..83bc421 Binary files /dev/null and b/mseide-msegui/icons/components/twmfprinter.png differ diff --git a/mseide-msegui/icons/components/twmfprinter.svg b/mseide-msegui/icons/components/twmfprinter.svg new file mode 100644 index 0000000..1c7e49a --- /dev/null +++ b/mseide-msegui/icons/components/twmfprinter.svg @@ -0,0 +1,331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + WMF + + + + + + + + + + Poi Li + Poi oL + + + Poi + + + + diff --git a/mseide-msegui/icons/components/txserieschartedit.png b/mseide-msegui/icons/components/txserieschartedit.png new file mode 100644 index 0000000..243cc17 Binary files /dev/null and b/mseide-msegui/icons/components/txserieschartedit.png differ diff --git a/mseide-msegui/icons/components/txserieschartedit.svg b/mseide-msegui/icons/components/txserieschartedit.svg new file mode 100644 index 0000000..2f74c8e --- /dev/null +++ b/mseide-msegui/icons/components/txserieschartedit.svg @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/txychartedit.png b/mseide-msegui/icons/components/txychartedit.png new file mode 100644 index 0000000..c7a1e67 Binary files /dev/null and b/mseide-msegui/icons/components/txychartedit.png differ diff --git a/mseide-msegui/icons/components/txychartedit.svg b/mseide-msegui/icons/components/txychartedit.svg new file mode 100644 index 0000000..12a8db3 --- /dev/null +++ b/mseide-msegui/icons/components/txychartedit.svg @@ -0,0 +1,316 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/typ.png b/mseide-msegui/icons/components/typ.png new file mode 100644 index 0000000..3838a43 Binary files /dev/null and b/mseide-msegui/icons/components/typ.png differ diff --git a/mseide-msegui/icons/components/type.png b/mseide-msegui/icons/components/type.png new file mode 100644 index 0000000..7705bae Binary files /dev/null and b/mseide-msegui/icons/components/type.png differ diff --git a/mseide-msegui/icons/components/tzstreamhandler.png b/mseide-msegui/icons/components/tzstreamhandler.png new file mode 100644 index 0000000..d711760 Binary files /dev/null and b/mseide-msegui/icons/components/tzstreamhandler.png differ diff --git a/mseide-msegui/icons/components/tzstreamhandler.svg b/mseide-msegui/icons/components/tzstreamhandler.svg new file mode 100644 index 0000000..6e63a90 --- /dev/null +++ b/mseide-msegui/icons/components/tzstreamhandler.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Zlib + cryp + + diff --git a/mseide-msegui/icons/components/watches.bmp b/mseide-msegui/icons/components/watches.bmp new file mode 100644 index 0000000..b7dda86 Binary files /dev/null and b/mseide-msegui/icons/components/watches.bmp differ diff --git a/mseide-msegui/icons/components/watchon.bmp b/mseide-msegui/icons/components/watchon.bmp new file mode 100755 index 0000000..e6e7a45 Binary files /dev/null and b/mseide-msegui/icons/components/watchon.bmp differ diff --git a/mseide-msegui/icons/components/watchpoints.bmp b/mseide-msegui/icons/components/watchpoints.bmp new file mode 100644 index 0000000..bac9760 Binary files /dev/null and b/mseide-msegui/icons/components/watchpoints.bmp differ diff --git a/mseide-msegui/icons/components/wmf.png b/mseide-msegui/icons/components/wmf.png new file mode 100644 index 0000000..48cb2fc Binary files /dev/null and b/mseide-msegui/icons/components/wmf.png differ diff --git a/mseide-msegui/icons/forms/assembler.png b/mseide-msegui/icons/forms/assembler.png new file mode 100644 index 0000000..c5e6d0b Binary files /dev/null and b/mseide-msegui/icons/forms/assembler.png differ diff --git a/mseide-msegui/icons/forms/assembler.svg b/mseide-msegui/icons/forms/assembler.svg new file mode 100644 index 0000000..a284a17 --- /dev/null +++ b/mseide-msegui/icons/forms/assembler.svg @@ -0,0 +1,454 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + 010 + + diff --git a/mseide-msegui/icons/forms/breakpoints.png b/mseide-msegui/icons/forms/breakpoints.png new file mode 100644 index 0000000..904088a Binary files /dev/null and b/mseide-msegui/icons/forms/breakpoints.png differ diff --git a/mseide-msegui/icons/forms/breakpoints.svg b/mseide-msegui/icons/forms/breakpoints.svg new file mode 100644 index 0000000..8a9ab5e --- /dev/null +++ b/mseide-msegui/icons/forms/breakpoints.svg @@ -0,0 +1,433 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/componentstore.png b/mseide-msegui/icons/forms/componentstore.png new file mode 100644 index 0000000..f64ede9 Binary files /dev/null and b/mseide-msegui/icons/forms/componentstore.png differ diff --git a/mseide-msegui/icons/forms/componentstore.svg b/mseide-msegui/icons/forms/componentstore.svg new file mode 100644 index 0000000..902651f --- /dev/null +++ b/mseide-msegui/icons/forms/componentstore.svg @@ -0,0 +1,569 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/console.png b/mseide-msegui/icons/forms/console.png new file mode 100644 index 0000000..faf9103 Binary files /dev/null and b/mseide-msegui/icons/forms/console.png differ diff --git a/mseide-msegui/icons/forms/console.svg b/mseide-msegui/icons/forms/console.svg new file mode 100644 index 0000000..585a10b --- /dev/null +++ b/mseide-msegui/icons/forms/console.svg @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ~> + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/cpu.png b/mseide-msegui/icons/forms/cpu.png new file mode 100644 index 0000000..1ce1c02 Binary files /dev/null and b/mseide-msegui/icons/forms/cpu.png differ diff --git a/mseide-msegui/icons/forms/cpu.svg b/mseide-msegui/icons/forms/cpu.svg new file mode 100644 index 0000000..fc7c007 --- /dev/null +++ b/mseide-msegui/icons/forms/cpu.svg @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 010 + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/debugger.png b/mseide-msegui/icons/forms/debugger.png new file mode 100644 index 0000000..c35cebd Binary files /dev/null and b/mseide-msegui/icons/forms/debugger.png differ diff --git a/mseide-msegui/icons/forms/debugger.svg b/mseide-msegui/icons/forms/debugger.svg new file mode 100644 index 0000000..010a28c --- /dev/null +++ b/mseide-msegui/icons/forms/debugger.svg @@ -0,0 +1,367 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/findresults.png b/mseide-msegui/icons/forms/findresults.png new file mode 100644 index 0000000..76fd207 Binary files /dev/null and b/mseide-msegui/icons/forms/findresults.png differ diff --git a/mseide-msegui/icons/forms/findresults.svg b/mseide-msegui/icons/forms/findresults.svg new file mode 100644 index 0000000..88c4750 --- /dev/null +++ b/mseide-msegui/icons/forms/findresults.svg @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + ? + + diff --git a/mseide-msegui/icons/forms/memory.png b/mseide-msegui/icons/forms/memory.png new file mode 100644 index 0000000..bb6fd86 Binary files /dev/null and b/mseide-msegui/icons/forms/memory.png differ diff --git a/mseide-msegui/icons/forms/memory.svg b/mseide-msegui/icons/forms/memory.svg new file mode 100644 index 0000000..b0ce81c --- /dev/null +++ b/mseide-msegui/icons/forms/memory.svg @@ -0,0 +1,630 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + a + 12 + 68 + 15 + c + j + o + 91 + 62 + 11 + 00 + 00 + 00 + 61 + 11 + 14 + + + diff --git a/mseide-msegui/icons/forms/messages.png b/mseide-msegui/icons/forms/messages.png new file mode 100644 index 0000000..085a012 Binary files /dev/null and b/mseide-msegui/icons/forms/messages.png differ diff --git a/mseide-msegui/icons/forms/messages.svg b/mseide-msegui/icons/forms/messages.svg new file mode 100644 index 0000000..8a4bfb9 --- /dev/null +++ b/mseide-msegui/icons/forms/messages.svg @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ME + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/msei18n_24x24.png b/mseide-msegui/icons/forms/msei18n_24x24.png new file mode 100644 index 0000000..5b5c3ff Binary files /dev/null and b/mseide-msegui/icons/forms/msei18n_24x24.png differ diff --git a/mseide-msegui/icons/forms/objectinspector.png b/mseide-msegui/icons/forms/objectinspector.png new file mode 100644 index 0000000..4a9690e Binary files /dev/null and b/mseide-msegui/icons/forms/objectinspector.png differ diff --git a/mseide-msegui/icons/forms/objectinspector.svg b/mseide-msegui/icons/forms/objectinspector.svg new file mode 100644 index 0000000..5673bee --- /dev/null +++ b/mseide-msegui/icons/forms/objectinspector.svg @@ -0,0 +1,418 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/palette.png b/mseide-msegui/icons/forms/palette.png new file mode 100644 index 0000000..86a170a Binary files /dev/null and b/mseide-msegui/icons/forms/palette.png differ diff --git a/mseide-msegui/icons/forms/palette.svg b/mseide-msegui/icons/forms/palette.svg new file mode 100644 index 0000000..113c125 --- /dev/null +++ b/mseide-msegui/icons/forms/palette.svg @@ -0,0 +1,542 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + Aiob + Bloo + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/rect6550.png b/mseide-msegui/icons/forms/rect6550.png new file mode 100644 index 0000000..dcc6aa3 Binary files /dev/null and b/mseide-msegui/icons/forms/rect6550.png differ diff --git a/mseide-msegui/icons/forms/source.png b/mseide-msegui/icons/forms/source.png new file mode 100644 index 0000000..7c7f893 Binary files /dev/null and b/mseide-msegui/icons/forms/source.png differ diff --git a/mseide-msegui/icons/forms/source.svg b/mseide-msegui/icons/forms/source.svg new file mode 100644 index 0000000..c7c2900 --- /dev/null +++ b/mseide-msegui/icons/forms/source.svg @@ -0,0 +1,466 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + Abcd ecoe dgrgeeidkl + + diff --git a/mseide-msegui/icons/forms/stack.png b/mseide-msegui/icons/forms/stack.png new file mode 100644 index 0000000..fde8360 Binary files /dev/null and b/mseide-msegui/icons/forms/stack.png differ diff --git a/mseide-msegui/icons/forms/stack.svg b/mseide-msegui/icons/forms/stack.svg new file mode 100644 index 0000000..b266226 --- /dev/null +++ b/mseide-msegui/icons/forms/stack.svg @@ -0,0 +1,461 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + asrs fsf fdfwfasda + Psas aiasaaad + + + diff --git a/mseide-msegui/icons/forms/thread.png b/mseide-msegui/icons/forms/thread.png new file mode 100644 index 0000000..2632dd2 Binary files /dev/null and b/mseide-msegui/icons/forms/thread.png differ diff --git a/mseide-msegui/icons/forms/thread.svg b/mseide-msegui/icons/forms/thread.svg new file mode 100644 index 0000000..d0d5639 --- /dev/null +++ b/mseide-msegui/icons/forms/thread.svg @@ -0,0 +1,519 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/watches.png b/mseide-msegui/icons/forms/watches.png new file mode 100644 index 0000000..d7dc623 Binary files /dev/null and b/mseide-msegui/icons/forms/watches.png differ diff --git a/mseide-msegui/icons/forms/watches.svg b/mseide-msegui/icons/forms/watches.svg new file mode 100644 index 0000000..48bb5d8 --- /dev/null +++ b/mseide-msegui/icons/forms/watches.svg @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ??? + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/watchpoints.png b/mseide-msegui/icons/forms/watchpoints.png new file mode 100644 index 0000000..75890b1 Binary files /dev/null and b/mseide-msegui/icons/forms/watchpoints.png differ diff --git a/mseide-msegui/icons/forms/watchppoints.svg b/mseide-msegui/icons/forms/watchppoints.svg new file mode 100644 index 0000000..5087d82 --- /dev/null +++ b/mseide-msegui/icons/forms/watchppoints.svg @@ -0,0 +1,447 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + ? + + diff --git a/mseide-msegui/icons/frames/demo/0.png b/mseide-msegui/icons/frames/demo/0.png new file mode 100644 index 0000000..e3dd0c4 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/0.png differ diff --git a/mseide-msegui/icons/frames/demo/0.xcf b/mseide-msegui/icons/frames/demo/0.xcf new file mode 100644 index 0000000..87c5f6c Binary files /dev/null and b/mseide-msegui/icons/frames/demo/0.xcf differ diff --git a/mseide-msegui/icons/frames/demo/1.png b/mseide-msegui/icons/frames/demo/1.png new file mode 100644 index 0000000..bf89036 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/1.png differ diff --git a/mseide-msegui/icons/frames/demo/1.xcf b/mseide-msegui/icons/frames/demo/1.xcf new file mode 100644 index 0000000..f8c6b01 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/1.xcf differ diff --git a/mseide-msegui/icons/frames/demo/10.png b/mseide-msegui/icons/frames/demo/10.png new file mode 100644 index 0000000..6ef0d14 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/10.png differ diff --git a/mseide-msegui/icons/frames/demo/10.xcf b/mseide-msegui/icons/frames/demo/10.xcf new file mode 100644 index 0000000..e4675b2 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/10.xcf differ diff --git a/mseide-msegui/icons/frames/demo/11.png b/mseide-msegui/icons/frames/demo/11.png new file mode 100644 index 0000000..2921c40 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/11.png differ diff --git a/mseide-msegui/icons/frames/demo/11.xcf b/mseide-msegui/icons/frames/demo/11.xcf new file mode 100644 index 0000000..cdd07a3 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/11.xcf differ diff --git a/mseide-msegui/icons/frames/demo/12.png b/mseide-msegui/icons/frames/demo/12.png new file mode 100644 index 0000000..d80c282 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/12.png differ diff --git a/mseide-msegui/icons/frames/demo/12.xcf b/mseide-msegui/icons/frames/demo/12.xcf new file mode 100644 index 0000000..f17f2b3 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/12.xcf differ diff --git a/mseide-msegui/icons/frames/demo/13.png b/mseide-msegui/icons/frames/demo/13.png new file mode 100644 index 0000000..43516d0 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/13.png differ diff --git a/mseide-msegui/icons/frames/demo/13.xcf b/mseide-msegui/icons/frames/demo/13.xcf new file mode 100644 index 0000000..fce6efb Binary files /dev/null and b/mseide-msegui/icons/frames/demo/13.xcf differ diff --git a/mseide-msegui/icons/frames/demo/14.png b/mseide-msegui/icons/frames/demo/14.png new file mode 100644 index 0000000..fb08ce1 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/14.png differ diff --git a/mseide-msegui/icons/frames/demo/14.xcf b/mseide-msegui/icons/frames/demo/14.xcf new file mode 100644 index 0000000..8dd1d33 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/14.xcf differ diff --git a/mseide-msegui/icons/frames/demo/15.png b/mseide-msegui/icons/frames/demo/15.png new file mode 100644 index 0000000..3f2062b Binary files /dev/null and b/mseide-msegui/icons/frames/demo/15.png differ diff --git a/mseide-msegui/icons/frames/demo/15.xcf b/mseide-msegui/icons/frames/demo/15.xcf new file mode 100644 index 0000000..df7b36c Binary files /dev/null and b/mseide-msegui/icons/frames/demo/15.xcf differ diff --git a/mseide-msegui/icons/frames/demo/16.png b/mseide-msegui/icons/frames/demo/16.png new file mode 100644 index 0000000..38717de Binary files /dev/null and b/mseide-msegui/icons/frames/demo/16.png differ diff --git a/mseide-msegui/icons/frames/demo/16.xcf b/mseide-msegui/icons/frames/demo/16.xcf new file mode 100644 index 0000000..b7a466c Binary files /dev/null and b/mseide-msegui/icons/frames/demo/16.xcf differ diff --git a/mseide-msegui/icons/frames/demo/17.png b/mseide-msegui/icons/frames/demo/17.png new file mode 100644 index 0000000..8963e6f Binary files /dev/null and b/mseide-msegui/icons/frames/demo/17.png differ diff --git a/mseide-msegui/icons/frames/demo/17.xcf b/mseide-msegui/icons/frames/demo/17.xcf new file mode 100644 index 0000000..4ff30b3 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/17.xcf differ diff --git a/mseide-msegui/icons/frames/demo/18.png b/mseide-msegui/icons/frames/demo/18.png new file mode 100644 index 0000000..8dfc10e Binary files /dev/null and b/mseide-msegui/icons/frames/demo/18.png differ diff --git a/mseide-msegui/icons/frames/demo/18.xcf b/mseide-msegui/icons/frames/demo/18.xcf new file mode 100644 index 0000000..ac8c149 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/18.xcf differ diff --git a/mseide-msegui/icons/frames/demo/19.png b/mseide-msegui/icons/frames/demo/19.png new file mode 100644 index 0000000..f6bd55a Binary files /dev/null and b/mseide-msegui/icons/frames/demo/19.png differ diff --git a/mseide-msegui/icons/frames/demo/19.xcf b/mseide-msegui/icons/frames/demo/19.xcf new file mode 100644 index 0000000..f83e5e4 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/19.xcf differ diff --git a/mseide-msegui/icons/frames/demo/2.png b/mseide-msegui/icons/frames/demo/2.png new file mode 100644 index 0000000..10edeca Binary files /dev/null and b/mseide-msegui/icons/frames/demo/2.png differ diff --git a/mseide-msegui/icons/frames/demo/2.xcf b/mseide-msegui/icons/frames/demo/2.xcf new file mode 100644 index 0000000..2692d8c Binary files /dev/null and b/mseide-msegui/icons/frames/demo/2.xcf differ diff --git a/mseide-msegui/icons/frames/demo/20.png b/mseide-msegui/icons/frames/demo/20.png new file mode 100644 index 0000000..4067a83 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/20.png differ diff --git a/mseide-msegui/icons/frames/demo/20.xcf b/mseide-msegui/icons/frames/demo/20.xcf new file mode 100644 index 0000000..543cee5 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/20.xcf differ diff --git a/mseide-msegui/icons/frames/demo/21.png b/mseide-msegui/icons/frames/demo/21.png new file mode 100644 index 0000000..7eb5355 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/21.png differ diff --git a/mseide-msegui/icons/frames/demo/21.xcf b/mseide-msegui/icons/frames/demo/21.xcf new file mode 100644 index 0000000..c187908 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/21.xcf differ diff --git a/mseide-msegui/icons/frames/demo/22.png b/mseide-msegui/icons/frames/demo/22.png new file mode 100644 index 0000000..7af40f4 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/22.png differ diff --git a/mseide-msegui/icons/frames/demo/22.xcf b/mseide-msegui/icons/frames/demo/22.xcf new file mode 100644 index 0000000..84eecad Binary files /dev/null and b/mseide-msegui/icons/frames/demo/22.xcf differ diff --git a/mseide-msegui/icons/frames/demo/23.png b/mseide-msegui/icons/frames/demo/23.png new file mode 100644 index 0000000..a4fdfab Binary files /dev/null and b/mseide-msegui/icons/frames/demo/23.png differ diff --git a/mseide-msegui/icons/frames/demo/23.xcf b/mseide-msegui/icons/frames/demo/23.xcf new file mode 100644 index 0000000..daa4251 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/23.xcf differ diff --git a/mseide-msegui/icons/frames/demo/24.png b/mseide-msegui/icons/frames/demo/24.png new file mode 100644 index 0000000..cd186f3 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/24.png differ diff --git a/mseide-msegui/icons/frames/demo/24.xcf b/mseide-msegui/icons/frames/demo/24.xcf new file mode 100644 index 0000000..6f95972 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/24.xcf differ diff --git a/mseide-msegui/icons/frames/demo/25.png b/mseide-msegui/icons/frames/demo/25.png new file mode 100644 index 0000000..c41386c Binary files /dev/null and b/mseide-msegui/icons/frames/demo/25.png differ diff --git a/mseide-msegui/icons/frames/demo/25.xcf b/mseide-msegui/icons/frames/demo/25.xcf new file mode 100644 index 0000000..a36e191 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/25.xcf differ diff --git a/mseide-msegui/icons/frames/demo/26.png b/mseide-msegui/icons/frames/demo/26.png new file mode 100644 index 0000000..17c3261 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/26.png differ diff --git a/mseide-msegui/icons/frames/demo/26.xcf b/mseide-msegui/icons/frames/demo/26.xcf new file mode 100644 index 0000000..52d80c0 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/26.xcf differ diff --git a/mseide-msegui/icons/frames/demo/27.png b/mseide-msegui/icons/frames/demo/27.png new file mode 100644 index 0000000..e38a5e5 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/27.png differ diff --git a/mseide-msegui/icons/frames/demo/27.xcf b/mseide-msegui/icons/frames/demo/27.xcf new file mode 100644 index 0000000..3bba2ad Binary files /dev/null and b/mseide-msegui/icons/frames/demo/27.xcf differ diff --git a/mseide-msegui/icons/frames/demo/28.png b/mseide-msegui/icons/frames/demo/28.png new file mode 100644 index 0000000..1a426b2 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/28.png differ diff --git a/mseide-msegui/icons/frames/demo/28.xcf b/mseide-msegui/icons/frames/demo/28.xcf new file mode 100644 index 0000000..b33ecdb Binary files /dev/null and b/mseide-msegui/icons/frames/demo/28.xcf differ diff --git a/mseide-msegui/icons/frames/demo/29.png b/mseide-msegui/icons/frames/demo/29.png new file mode 100644 index 0000000..de8974a Binary files /dev/null and b/mseide-msegui/icons/frames/demo/29.png differ diff --git a/mseide-msegui/icons/frames/demo/29.xcf b/mseide-msegui/icons/frames/demo/29.xcf new file mode 100644 index 0000000..7d56dd7 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/29.xcf differ diff --git a/mseide-msegui/icons/frames/demo/3.png b/mseide-msegui/icons/frames/demo/3.png new file mode 100644 index 0000000..fc3c696 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/3.png differ diff --git a/mseide-msegui/icons/frames/demo/3.xcf b/mseide-msegui/icons/frames/demo/3.xcf new file mode 100644 index 0000000..0aa1dc7 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/3.xcf differ diff --git a/mseide-msegui/icons/frames/demo/30.png b/mseide-msegui/icons/frames/demo/30.png new file mode 100644 index 0000000..8924e03 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/30.png differ diff --git a/mseide-msegui/icons/frames/demo/30.xcf b/mseide-msegui/icons/frames/demo/30.xcf new file mode 100644 index 0000000..6cebc4f Binary files /dev/null and b/mseide-msegui/icons/frames/demo/30.xcf differ diff --git a/mseide-msegui/icons/frames/demo/31.png b/mseide-msegui/icons/frames/demo/31.png new file mode 100644 index 0000000..8fc4a7d Binary files /dev/null and b/mseide-msegui/icons/frames/demo/31.png differ diff --git a/mseide-msegui/icons/frames/demo/31.xcf b/mseide-msegui/icons/frames/demo/31.xcf new file mode 100644 index 0000000..f435955 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/31.xcf differ diff --git a/mseide-msegui/icons/frames/demo/4.png b/mseide-msegui/icons/frames/demo/4.png new file mode 100644 index 0000000..ca34432 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/4.png differ diff --git a/mseide-msegui/icons/frames/demo/4.xcf b/mseide-msegui/icons/frames/demo/4.xcf new file mode 100644 index 0000000..98f9936 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/4.xcf differ diff --git a/mseide-msegui/icons/frames/demo/5.png b/mseide-msegui/icons/frames/demo/5.png new file mode 100644 index 0000000..4cc1b83 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/5.png differ diff --git a/mseide-msegui/icons/frames/demo/5.xcf b/mseide-msegui/icons/frames/demo/5.xcf new file mode 100644 index 0000000..41da66a Binary files /dev/null and b/mseide-msegui/icons/frames/demo/5.xcf differ diff --git a/mseide-msegui/icons/frames/demo/6.png b/mseide-msegui/icons/frames/demo/6.png new file mode 100644 index 0000000..9134be0 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/6.png differ diff --git a/mseide-msegui/icons/frames/demo/6.xcf b/mseide-msegui/icons/frames/demo/6.xcf new file mode 100644 index 0000000..d655fc9 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/6.xcf differ diff --git a/mseide-msegui/icons/frames/demo/7.png b/mseide-msegui/icons/frames/demo/7.png new file mode 100644 index 0000000..952d6ee Binary files /dev/null and b/mseide-msegui/icons/frames/demo/7.png differ diff --git a/mseide-msegui/icons/frames/demo/7.xcf b/mseide-msegui/icons/frames/demo/7.xcf new file mode 100644 index 0000000..3da65d0 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/7.xcf differ diff --git a/mseide-msegui/icons/frames/demo/8.png b/mseide-msegui/icons/frames/demo/8.png new file mode 100644 index 0000000..b4867e7 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/8.png differ diff --git a/mseide-msegui/icons/frames/demo/8.xcf b/mseide-msegui/icons/frames/demo/8.xcf new file mode 100644 index 0000000..8ee78ea Binary files /dev/null and b/mseide-msegui/icons/frames/demo/8.xcf differ diff --git a/mseide-msegui/icons/frames/demo/9.png b/mseide-msegui/icons/frames/demo/9.png new file mode 100644 index 0000000..eba1293 Binary files /dev/null and b/mseide-msegui/icons/frames/demo/9.png differ diff --git a/mseide-msegui/icons/frames/demo/9.xcf b/mseide-msegui/icons/frames/demo/9.xcf new file mode 100644 index 0000000..589e1ac Binary files /dev/null and b/mseide-msegui/icons/frames/demo/9.xcf differ diff --git a/mseide-msegui/icons/frames/frames.png b/mseide-msegui/icons/frames/frames.png new file mode 100644 index 0000000..790b81c Binary files /dev/null and b/mseide-msegui/icons/frames/frames.png differ diff --git a/mseide-msegui/icons/frames/frames.svg b/mseide-msegui/icons/frames/frames.svg new file mode 100644 index 0000000..86b81b0 --- /dev/null +++ b/mseide-msegui/icons/frames/frames.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/mseide-msegui/icons/frames/frames.xcf b/mseide-msegui/icons/frames/frames.xcf new file mode 100644 index 0000000..84e1289 Binary files /dev/null and b/mseide-msegui/icons/frames/frames.xcf differ diff --git a/mseide-msegui/icons/frames/frames0.png b/mseide-msegui/icons/frames/frames0.png new file mode 100644 index 0000000..bc8863a Binary files /dev/null and b/mseide-msegui/icons/frames/frames0.png differ diff --git a/mseide-msegui/icons/frames/frames1.png b/mseide-msegui/icons/frames/frames1.png new file mode 100644 index 0000000..7a966de Binary files /dev/null and b/mseide-msegui/icons/frames/frames1.png differ diff --git a/mseide-msegui/icons/frames/frames2.png b/mseide-msegui/icons/frames/frames2.png new file mode 100644 index 0000000..4d53d8f Binary files /dev/null and b/mseide-msegui/icons/frames/frames2.png differ diff --git a/mseide-msegui/icons/frames/frames3.png b/mseide-msegui/icons/frames/frames3.png new file mode 100644 index 0000000..4571f5c Binary files /dev/null and b/mseide-msegui/icons/frames/frames3.png differ diff --git a/mseide-msegui/icons/frames/frames4.png b/mseide-msegui/icons/frames/frames4.png new file mode 100644 index 0000000..e7b3661 Binary files /dev/null and b/mseide-msegui/icons/frames/frames4.png differ diff --git a/mseide-msegui/icons/frames/frames5.png b/mseide-msegui/icons/frames/frames5.png new file mode 100644 index 0000000..6b7c9df Binary files /dev/null and b/mseide-msegui/icons/frames/frames5.png differ diff --git a/mseide-msegui/icons/frames/frames6.png b/mseide-msegui/icons/frames/frames6.png new file mode 100644 index 0000000..78a3213 Binary files /dev/null and b/mseide-msegui/icons/frames/frames6.png differ diff --git a/mseide-msegui/icons/frames/frames7.png b/mseide-msegui/icons/frames/frames7.png new file mode 100644 index 0000000..62e2681 Binary files /dev/null and b/mseide-msegui/icons/frames/frames7.png differ diff --git a/mseide-msegui/icons/makicon b/mseide-msegui/icons/makicon new file mode 100755 index 0000000..0f2fcff --- /dev/null +++ b/mseide-msegui/icons/makicon @@ -0,0 +1,21 @@ +#!/bin/sh +PROG=/home/mse/packs/standard/git/mseide-msegui/tools/bmp2pas +LIBDIR=/home/mse/packs/standard/git/mseide-msegui/lib/common +DEST=-o$LIBDIR/regcomponents +cd /home/mse/packs/standard/git/mseide-msegui/icons/components +$PROG $DEST/designer_bmp.pas TComponent.png +$PROG $DEST/regkernel_bmp.pas taction.bmp timagelist.png tstatfile.png tstringcontainer.png tkeystringcontainer.png trttistat.png tbitmapcomp.png ttimer.png tanimtimer.png tanimitemcomp.png tpipereadercomp.png tthreadcomp.png tframecomp.png tfacecomp.png tfontcomp.png tactivator.png tpostscriptprinter.png tgdiprinter.png twmfprinter.png tmainmenu.png tpopupmenu.png tnoguiaction.png tskincontroller.png tskinextender.png tshortcutcontroller.png thelpcontroller.png tguiprocess.png tguithreadcomp.png tprocessmonitor.png tfacelist.png tpagesizeselector.png tpageorientationselector.png tassistivehandler.png tassistivewidgetitem.png +$PROG $DEST/regsysutils_bmp.pas tsysenvmanager.png tmseprocess.png tpythonscript.png tfilechangenotifyer.png +$PROG $DEST/regcrypto_bmp.pas tdummycryptohandler.png tbase64handler.png tsymciphercryptohandler.png tasymciphercryptohandler.png tzstreamhandler.png tdigesthandler.png +$PROG $DEST/regwidgets_bmp.pas tsimplewidget.png tbutton.png tdrawgrid.png tstringgrid.png tmainmenuwidget.png taction.png tlabel.png timage.png tdispwidget.bmp tintegerdisp.png tint64disp.png trealdisp.png tstringdisp.png trichstringdisp.png tbooleandisp.png tedit.png ttoolbar.png tsplitter.png tdockhandle.bmp teventwidget.png tdockpanel.png tstockglyphbutton.png tgroupbox.png tscrollbox.png tstepbox.png ttabbar.png ttabpage.png ttabwidget.png tterminal.png tmseformwidget.png tdockformwidget.png tpaintbox.png texpandingwidget.png tspacer.png tlayouter.png tdatetimedisp.png tbytestringdisp.png tlistview.png tbarcode.png tdial.bmp tchart.png tchartrecorder.png twindowwidget.png topenglwidget.png topenglcanvaswidget.png tpolygon.png trichbutton.png trichstockglyphbutton.png txychartedit.png txserieschartedit.png tpickwidget.png ttraywidget.png tdockpanelformcontroller.png ticon.png +$PROG $DEST/regeditwidgets_bmp.pas twidgetgrid.png tdataedit.bmp ttextedit.png tundotextedit.png tslider.png tbooleanedit.bmp tbooleaneditradio.bmp tdataicon.png tdataimage.png tstringedit.png tdropdownlistedit.png tintegeredit.png tint64edit.png trealedit.png trealspinedit.png tdatetimeedit.png tenumedit.png thistoryedit.png tenumtypeedit.png tselector.png titemedit.png trecordfieldedit.png tdropdownitemedit.png tmbdropdownitemedit.png ttreeitemedit.png tfoldedit.png tmemoedit.png tkeystringedit.png tpointeredit.png tcalendardatetimeedit.png tdatabutton.png tstockglyphdatabutton.png tprogressbar.png thexstringedit.png +$PROG $DEST/regdialogs_bmp.pas tfilelistview.png tdirtreeview.png tfiledialog.png tfilenameedit.png tdirdropdownedit.png tcoloredit.png tdialogstringedit.png tmemodialogedit.png tguirttistat.png +$PROG $DEST/regserialcomm_bmp.pas tcommport.png tasciicommport.png tasciiprotport.png tcommselector.bmp tsercommcomp.png tsercommchannel.png tasynsercommchannel.png +$PROG $DEST/regdesignutils_bmp.pas tgdbmi.bmp tsyntaxedit.png tsyntaxpainter.bmp +$PROG $DEST/regdb_bmp.pas tlocaldataset.png tmsesqlquery.png tmsesqltransaction.png tmseibconnection.png tfb3connection.png tfbservice.png tfb3service.png tdatasource.bmp tdbnavigator.bmp tdbstringedit.png tdropdownlisteditdb.png tdropdownlisteditlb.png tdbdropdownlistedit.png tdbdropdownlisteditdb.png tdbdropdownlisteditlb.png tdbbooleantextedit.png tdbmemoedit.png tdbintegeredit.png tdbbooleanedit.bmp tdbdataicon.png tdbbooleaneditradio.bmp tdbrealedit.png tdbrealspinedit.png tdbdatetimeedit.png tdbenumedit.png tdbenumeditdb.png tdbenum64editdb.png tdbenumeditlb.png tdbenum64editlb.png tdbkeystringedit.png tdbkeystringeditdb.png tdbkeystringeditlb.png tdbstringlookuplb.png tdbstringlookupdb.png tdbintegerlookuplb.png tdbintegerlookupdb.png tdbreallookuplb.png tdbreallookupdb.png tdbdatetimelookuplb.png tdbdatetimelookupdb.png tdbstringlookup64lb.png tdbstringlookup64db.png tdbintegerlookup64lb.png tdbintegerlookup64db.png tdbreallookup64lb.png tdbreallookup64db.png tdbdatetimelookup64lb.png tdbdatetimelookup64db.png tdbstringlookupstrlb.png tdbstringlookupstrdb.png tdbintegerlookupstrlb.png tdbintegerlookupstrdb.png tdbreallookupstrlb.png tdbreallookupstrdb.png tdbdatetimelookupstrlb.png tdbdatetimelookupstrdb.png tdbwidgetgrid.png tdbstringgrid.png tlookupbuffer.png tdblookupbuffer.png tdbmemolookupbuffer.png tmsedbf.png tmsefixedformatdataset.png tmsesdfdataset.png tmsememdataset.png tmsepqconnection.bmp tmseodbcconnection.png tmsemysqlconnection.png tenumeditdb.png tenum64editdb.png tenumeditlb.png tenum64editlb.png tkeystringeditdb.png tkeystringeditlb.png tmsestringfield.png tmselongintfield.png tmselargeintfield.png tmsesmallintfield.png tmsewordfield.png tmseautoincfield.png tmsefloatfield.png tmsecurrencyfield.png tmsebooleanfield.png tmsedatetimefield.png tmsedatefield.png tmsetimefield.png tmsebinaryfield.png tmsebytesfield.png tmseguidfield.png tmsevarbytesfield.png tmsebcdfield.png tmseblobfield.png tmsememofield.png tmsegraphicfield.png tmsevariantfield.png tparamconnector.png tsqlresultconnector.png tdblabel.png tdbbarcode.png tdbstringdisp.png tdbintegerdisp.png tdbbooleandisp.png tdbrealdisp.png tdbdatetimedisp.png tdbstringdisplb.png tdbintegerdisplb.png tdbrealdisplb.png tdbdatetimedisplb.png tfieldparamlink.png tmsesqlite3dataset.bmp tdbcalendardatetimeedit.png tsequencelink.png tdbdatabutton.png tdbdialogstringedit.png tdbdataimage.png tfieldfieldlink.png tdbfilenameedit.png tfieldlink.png ttimestampfieldlink.png tdbevent.png tsqlite3connection.bmp tdbslider.png tdbprogressbar.png tdbcoloredit.png tsqlstatement.png tmsesqlscript.png tsqlresult.png tsqllookupbuffer.png tmsedatasource.png +$PROG $DEST/regdeprecated_bmp.pas tmsemysql40connection.bmp tmsemysql41connection.bmp tmsemysql50connection.bmp +$PROG $DEST/regreport_bmp.pas treportpage.png tbandarea.bmp ttilearea.bmp tbandgroup.bmp trecordband.bmp trepvaluedisp.bmp treppagenumdisp.bmp trepprintdatedisp.bmp trepspacer.bmp treppsdisp.png +$PROG $DEST/regzeoslib_bmp.pas tmsezreadonlyquery.bmp tmsezquery.bmp tmseztable.bmp TZConnection.bmp TZSequence.bmp TZSqlMetadata.bmp TZSqlMonitor.bmp TZSqlProcessor.bmp TZStoredProc.bmp TZUpdateSql.bmp +$PROG $DEST/regifirem_bmp.pas tsocketclient.bmp tsocketserver.bmp tsocketstdio.bmp tsocketserverstdio.bmp tpipeiochannel.bmp tsocketstdiochannel.bmp tsocketserveriochannel.bmp tsocketclientiochannel.bmp tformlink.bmp tmodulelink.bmp trxwidgetgrid.bmp ttxdatagrid.bmp trxdataset.bmp ttxdataset.bmp tssl.bmp ttxsqlquery.bmp +$PROG $DEST/regifi_bmp.pas tifiintegerendpoint.png tifiint64endpoint.png tifipointerendpoint.png tifibooleanendpoint.png tifirealendpoint.png tifidatetimeendpoint.png tifistringendpoint.png tifiactionendpoint.png tifilinkcomp.png tifiintegerlinkcomp.png tifiint64linkcomp.png tifipointerlinkcomp.png tifibooleanlinkcomp.png tifistringlinkcomp.png tifidropdownlistlinkcomp.png tifienumlinkcomp.png tifireallinkcomp.png tifidatetimelinkcomp.png tifiactionlinkcomp.png tifigridlinkcomp.png tconnectedifidatasource.png tifisqlresult.png tififormlinkcomp.png tifidialoglinkcomp.png tifidialog.png tifiitemlinkcomp.png tifitreeitemlinkcomp.png +$PROG $DEST/regmath_bmp.pas tfft.png tsigcontroller.png tsigadd.png tsigmult.png tsigdelay.png tsigdelayn.png tsigdelayvar.png tsigfir.png tsigiir.png tsigfft.png tsigin.png tsigout.png tsigconnector.png ttrigconnector.png tsigwavetable.png tsigfuncttable.png tsigenvelope.png tsigsampler.png tsigsamplerfft.png tsigfilter.png tsigfilterbank.png tsigkeyboard.png twavetableedit.png tfuncttableedit.png tffttableedit.png tenvelopeedit.png tsigscope.png tsigscopefft.png tsignoise.png tsigmidisource.png tsigmidiconnector.png tsigmidimulticonnector.png tsigoutaudio.png tmidisource.png taudioout.png diff --git a/mseide-msegui/icons/menus/assembler.png b/mseide-msegui/icons/menus/assembler.png new file mode 100644 index 0000000..cccab4d Binary files /dev/null and b/mseide-msegui/icons/menus/assembler.png differ diff --git a/mseide-msegui/icons/menus/assembler.svg b/mseide-msegui/icons/menus/assembler.svg new file mode 100644 index 0000000..b1977bc --- /dev/null +++ b/mseide-msegui/icons/menus/assembler.svg @@ -0,0 +1,429 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + 010 + + diff --git a/mseide-msegui/icons/menus/breakpoints.png b/mseide-msegui/icons/menus/breakpoints.png new file mode 100644 index 0000000..2a5168a Binary files /dev/null and b/mseide-msegui/icons/menus/breakpoints.png differ diff --git a/mseide-msegui/icons/menus/breakpoints.svg b/mseide-msegui/icons/menus/breakpoints.svg new file mode 100644 index 0000000..4a1fc38 --- /dev/null +++ b/mseide-msegui/icons/menus/breakpoints.svg @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/componentstore.png b/mseide-msegui/icons/menus/componentstore.png new file mode 100644 index 0000000..cb6890c Binary files /dev/null and b/mseide-msegui/icons/menus/componentstore.png differ diff --git a/mseide-msegui/icons/menus/componentstore.svg b/mseide-msegui/icons/menus/componentstore.svg new file mode 100644 index 0000000..219d04b --- /dev/null +++ b/mseide-msegui/icons/menus/componentstore.svg @@ -0,0 +1,536 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/console.png b/mseide-msegui/icons/menus/console.png new file mode 100644 index 0000000..1956b41 Binary files /dev/null and b/mseide-msegui/icons/menus/console.png differ diff --git a/mseide-msegui/icons/menus/console.svg b/mseide-msegui/icons/menus/console.svg new file mode 100644 index 0000000..565b79b --- /dev/null +++ b/mseide-msegui/icons/menus/console.svg @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ~> + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/cpu.png b/mseide-msegui/icons/menus/cpu.png new file mode 100644 index 0000000..c99e62c Binary files /dev/null and b/mseide-msegui/icons/menus/cpu.png differ diff --git a/mseide-msegui/icons/menus/cpu.svg b/mseide-msegui/icons/menus/cpu.svg new file mode 100644 index 0000000..21cb124 --- /dev/null +++ b/mseide-msegui/icons/menus/cpu.svg @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 010 + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/debugger.png b/mseide-msegui/icons/menus/debugger.png new file mode 100644 index 0000000..d9c1ca7 Binary files /dev/null and b/mseide-msegui/icons/menus/debugger.png differ diff --git a/mseide-msegui/icons/menus/debugger.svg b/mseide-msegui/icons/menus/debugger.svg new file mode 100644 index 0000000..6f2ee40 --- /dev/null +++ b/mseide-msegui/icons/menus/debugger.svg @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/findresults.png b/mseide-msegui/icons/menus/findresults.png new file mode 100644 index 0000000..c87cf71 Binary files /dev/null and b/mseide-msegui/icons/menus/findresults.png differ diff --git a/mseide-msegui/icons/menus/findresults.svg b/mseide-msegui/icons/menus/findresults.svg new file mode 100644 index 0000000..88bf419 --- /dev/null +++ b/mseide-msegui/icons/menus/findresults.svg @@ -0,0 +1,456 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + ? + + diff --git a/mseide-msegui/icons/menus/memory.png b/mseide-msegui/icons/menus/memory.png new file mode 100644 index 0000000..60d5524 Binary files /dev/null and b/mseide-msegui/icons/menus/memory.png differ diff --git a/mseide-msegui/icons/menus/memory.svg b/mseide-msegui/icons/menus/memory.svg new file mode 100644 index 0000000..4bd72ae --- /dev/null +++ b/mseide-msegui/icons/menus/memory.svg @@ -0,0 +1,610 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + a + 12 + 68 + 15 + c + j + o + 91 + 62 + 11 + 00 + 00 + 00 + 61 + 11 + 14 + + + + + + + diff --git a/mseide-msegui/icons/menus/messages.png b/mseide-msegui/icons/menus/messages.png new file mode 100644 index 0000000..88b3f7a Binary files /dev/null and b/mseide-msegui/icons/menus/messages.png differ diff --git a/mseide-msegui/icons/menus/messages.svg b/mseide-msegui/icons/menus/messages.svg new file mode 100644 index 0000000..be36d47 --- /dev/null +++ b/mseide-msegui/icons/menus/messages.svg @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ME + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/objectinspector.png b/mseide-msegui/icons/menus/objectinspector.png new file mode 100644 index 0000000..413cb0a Binary files /dev/null and b/mseide-msegui/icons/menus/objectinspector.png differ diff --git a/mseide-msegui/icons/menus/objectinspector.svg b/mseide-msegui/icons/menus/objectinspector.svg new file mode 100644 index 0000000..23c1843 --- /dev/null +++ b/mseide-msegui/icons/menus/objectinspector.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/palette.png b/mseide-msegui/icons/menus/palette.png new file mode 100644 index 0000000..3215e16 Binary files /dev/null and b/mseide-msegui/icons/menus/palette.png differ diff --git a/mseide-msegui/icons/menus/palette.svg b/mseide-msegui/icons/menus/palette.svg new file mode 100644 index 0000000..bfdfae8 --- /dev/null +++ b/mseide-msegui/icons/menus/palette.svg @@ -0,0 +1,561 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + Aiob + Blo + + + + + + + + + diff --git a/mseide-msegui/icons/menus/pastedpic_11162008_154602.png b/mseide-msegui/icons/menus/pastedpic_11162008_154602.png new file mode 100644 index 0000000..a598609 Binary files /dev/null and b/mseide-msegui/icons/menus/pastedpic_11162008_154602.png differ diff --git a/mseide-msegui/icons/menus/source.png b/mseide-msegui/icons/menus/source.png new file mode 100644 index 0000000..39928ea Binary files /dev/null and b/mseide-msegui/icons/menus/source.png differ diff --git a/mseide-msegui/icons/menus/source.svg b/mseide-msegui/icons/menus/source.svg new file mode 100644 index 0000000..08190dc --- /dev/null +++ b/mseide-msegui/icons/menus/source.svg @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + Abcd ecoe dgrgeeidkl + + diff --git a/mseide-msegui/icons/menus/stack.png b/mseide-msegui/icons/menus/stack.png new file mode 100644 index 0000000..a548f4a Binary files /dev/null and b/mseide-msegui/icons/menus/stack.png differ diff --git a/mseide-msegui/icons/menus/stack.svg b/mseide-msegui/icons/menus/stack.svg new file mode 100644 index 0000000..555a077 --- /dev/null +++ b/mseide-msegui/icons/menus/stack.svg @@ -0,0 +1,431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + asrs fsf fdfwfasda + Psas aiasaaad + + + diff --git a/mseide-msegui/icons/menus/symbols.png b/mseide-msegui/icons/menus/symbols.png new file mode 100644 index 0000000..fbbd915 Binary files /dev/null and b/mseide-msegui/icons/menus/symbols.png differ diff --git a/mseide-msegui/icons/menus/thread.png b/mseide-msegui/icons/menus/thread.png new file mode 100644 index 0000000..68038c2 Binary files /dev/null and b/mseide-msegui/icons/menus/thread.png differ diff --git a/mseide-msegui/icons/menus/thread.svg b/mseide-msegui/icons/menus/thread.svg new file mode 100644 index 0000000..0a770d7 --- /dev/null +++ b/mseide-msegui/icons/menus/thread.svg @@ -0,0 +1,486 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/threads.svg b/mseide-msegui/icons/menus/threads.svg new file mode 100644 index 0000000..ee48c52 --- /dev/null +++ b/mseide-msegui/icons/menus/threads.svg @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + asrs fsf fdfwfasda + Psas aiasaaad + + + diff --git a/mseide-msegui/icons/menus/watches.png b/mseide-msegui/icons/menus/watches.png new file mode 100644 index 0000000..35df49d Binary files /dev/null and b/mseide-msegui/icons/menus/watches.png differ diff --git a/mseide-msegui/icons/menus/watches.svg b/mseide-msegui/icons/menus/watches.svg new file mode 100644 index 0000000..543080a --- /dev/null +++ b/mseide-msegui/icons/menus/watches.svg @@ -0,0 +1,425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ??? + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/watchpoints.png b/mseide-msegui/icons/menus/watchpoints.png new file mode 100644 index 0000000..9629b8d Binary files /dev/null and b/mseide-msegui/icons/menus/watchpoints.png differ diff --git a/mseide-msegui/icons/menus/watchppoints.svg b/mseide-msegui/icons/menus/watchppoints.svg new file mode 100644 index 0000000..8fef8d9 --- /dev/null +++ b/mseide-msegui/icons/menus/watchppoints.svg @@ -0,0 +1,440 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + ? + + diff --git a/mseide-msegui/icons/msegui/edelweiss.svg b/mseide-msegui/icons/msegui/edelweiss.svg new file mode 100644 index 0000000..b1d5b2b --- /dev/null +++ b/mseide-msegui/icons/msegui/edelweiss.svg @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/msegui/edelweiss2_16.png b/mseide-msegui/icons/msegui/edelweiss2_16.png new file mode 100644 index 0000000..cb8f1da Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_16.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_16bi.png b/mseide-msegui/icons/msegui/edelweiss2_16bi.png new file mode 100644 index 0000000..4e3feae Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_16bi.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_17.png b/mseide-msegui/icons/msegui/edelweiss2_17.png new file mode 100644 index 0000000..f120232 Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_17.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_17bi.png b/mseide-msegui/icons/msegui/edelweiss2_17bi.png new file mode 100644 index 0000000..782f7ef Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_17bi.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_18.png b/mseide-msegui/icons/msegui/edelweiss2_18.png new file mode 100644 index 0000000..18edcf3 Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_18.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_18bi.png b/mseide-msegui/icons/msegui/edelweiss2_18bi.png new file mode 100644 index 0000000..f09d5cf Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_18bi.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_24.png b/mseide-msegui/icons/msegui/edelweiss2_24.png new file mode 100644 index 0000000..8852496 Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_24.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_24bi.png b/mseide-msegui/icons/msegui/edelweiss2_24bi.png new file mode 100644 index 0000000..7f2f54d Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_24bi.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_32.png b/mseide-msegui/icons/msegui/edelweiss2_32.png new file mode 100644 index 0000000..79a1efa Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_32.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_32bi.png b/mseide-msegui/icons/msegui/edelweiss2_32bi.png new file mode 100644 index 0000000..72b8992 Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_32bi.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_48.png b/mseide-msegui/icons/msegui/edelweiss2_48.png new file mode 100644 index 0000000..eac3568 Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_48.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_48bi.png b/mseide-msegui/icons/msegui/edelweiss2_48bi.png new file mode 100644 index 0000000..fea5228 Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_48bi.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_64.png b/mseide-msegui/icons/msegui/edelweiss2_64.png new file mode 100644 index 0000000..c808ed1 Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_64.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_64bi.ico b/mseide-msegui/icons/msegui/edelweiss2_64bi.ico new file mode 100644 index 0000000..6a22884 Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_64bi.ico differ diff --git a/mseide-msegui/icons/msegui/edelweiss2_64bi.png b/mseide-msegui/icons/msegui/edelweiss2_64bi.png new file mode 100644 index 0000000..bee7db4 Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweiss2_64bi.png differ diff --git a/mseide-msegui/icons/msegui/edelweiss_bi.svg b/mseide-msegui/icons/msegui/edelweiss_bi.svg new file mode 100644 index 0000000..e55856c --- /dev/null +++ b/mseide-msegui/icons/msegui/edelweiss_bi.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/msegui/edelweiss_biround.svg b/mseide-msegui/icons/msegui/edelweiss_biround.svg new file mode 100644 index 0000000..e2c1ccd --- /dev/null +++ b/mseide-msegui/icons/msegui/edelweiss_biround.svg @@ -0,0 +1,344 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/msegui/edelweissgreen_24bi.png b/mseide-msegui/icons/msegui/edelweissgreen_24bi.png new file mode 100644 index 0000000..ccf5098 Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweissgreen_24bi.png differ diff --git a/mseide-msegui/icons/msegui/edelweissgreen_32bi.png b/mseide-msegui/icons/msegui/edelweissgreen_32bi.png new file mode 100644 index 0000000..6269dc1 Binary files /dev/null and b/mseide-msegui/icons/msegui/edelweissgreen_32bi.png differ diff --git a/mseide-msegui/icons/msegui/edelweissgreen_bi.svg b/mseide-msegui/icons/msegui/edelweissgreen_bi.svg new file mode 100644 index 0000000..ef2faf6 --- /dev/null +++ b/mseide-msegui/icons/msegui/edelweissgreen_bi.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/resources/dir.png b/mseide-msegui/icons/resources/dir.png new file mode 100644 index 0000000..7a640f5 Binary files /dev/null and b/mseide-msegui/icons/resources/dir.png differ diff --git a/mseide-msegui/icons/resources/dirgreen.png b/mseide-msegui/icons/resources/dirgreen.png new file mode 100644 index 0000000..0db21d7 Binary files /dev/null and b/mseide-msegui/icons/resources/dirgreen.png differ diff --git a/mseide-msegui/icons/resources/dirgreenwarn.png b/mseide-msegui/icons/resources/dirgreenwarn.png new file mode 100644 index 0000000..e9ea329 Binary files /dev/null and b/mseide-msegui/icons/resources/dirgreenwarn.png differ diff --git a/mseide-msegui/icons/resources/diropen.png b/mseide-msegui/icons/resources/diropen.png new file mode 100644 index 0000000..51a1768 Binary files /dev/null and b/mseide-msegui/icons/resources/diropen.png differ diff --git a/mseide-msegui/icons/resources/diropengreen.png b/mseide-msegui/icons/resources/diropengreen.png new file mode 100644 index 0000000..df91283 Binary files /dev/null and b/mseide-msegui/icons/resources/diropengreen.png differ diff --git a/mseide-msegui/icons/resources/diropengreenwarn.png b/mseide-msegui/icons/resources/diropengreenwarn.png new file mode 100644 index 0000000..c11fdd8 Binary files /dev/null and b/mseide-msegui/icons/resources/diropengreenwarn.png differ diff --git a/mseide-msegui/icons/resources/diropenred.png b/mseide-msegui/icons/resources/diropenred.png new file mode 100644 index 0000000..81feec1 Binary files /dev/null and b/mseide-msegui/icons/resources/diropenred.png differ diff --git a/mseide-msegui/icons/resources/diropenredgreen.png b/mseide-msegui/icons/resources/diropenredgreen.png new file mode 100644 index 0000000..169b50a Binary files /dev/null and b/mseide-msegui/icons/resources/diropenredgreen.png differ diff --git a/mseide-msegui/icons/resources/diropenredgreenwarn.png b/mseide-msegui/icons/resources/diropenredgreenwarn.png new file mode 100644 index 0000000..c004478 Binary files /dev/null and b/mseide-msegui/icons/resources/diropenredgreenwarn.png differ diff --git a/mseide-msegui/icons/resources/diropenredwarn.png b/mseide-msegui/icons/resources/diropenredwarn.png new file mode 100644 index 0000000..7f7148f Binary files /dev/null and b/mseide-msegui/icons/resources/diropenredwarn.png differ diff --git a/mseide-msegui/icons/resources/diropenwhite.png b/mseide-msegui/icons/resources/diropenwhite.png new file mode 100644 index 0000000..2f754c5 Binary files /dev/null and b/mseide-msegui/icons/resources/diropenwhite.png differ diff --git a/mseide-msegui/icons/resources/dirplus.png b/mseide-msegui/icons/resources/dirplus.png new file mode 100644 index 0000000..56082e7 Binary files /dev/null and b/mseide-msegui/icons/resources/dirplus.png differ diff --git a/mseide-msegui/icons/resources/dirplusgreen.png b/mseide-msegui/icons/resources/dirplusgreen.png new file mode 100644 index 0000000..9cd83ca Binary files /dev/null and b/mseide-msegui/icons/resources/dirplusgreen.png differ diff --git a/mseide-msegui/icons/resources/dirplusred.png b/mseide-msegui/icons/resources/dirplusred.png new file mode 100644 index 0000000..93e8011 Binary files /dev/null and b/mseide-msegui/icons/resources/dirplusred.png differ diff --git a/mseide-msegui/icons/resources/dirpluswhite.png b/mseide-msegui/icons/resources/dirpluswhite.png new file mode 100644 index 0000000..9e909b8 Binary files /dev/null and b/mseide-msegui/icons/resources/dirpluswhite.png differ diff --git a/mseide-msegui/icons/resources/dirred.png b/mseide-msegui/icons/resources/dirred.png new file mode 100644 index 0000000..5932ce3 Binary files /dev/null and b/mseide-msegui/icons/resources/dirred.png differ diff --git a/mseide-msegui/icons/resources/dirredgreen.png b/mseide-msegui/icons/resources/dirredgreen.png new file mode 100644 index 0000000..fb99ec4 Binary files /dev/null and b/mseide-msegui/icons/resources/dirredgreen.png differ diff --git a/mseide-msegui/icons/resources/dirredgreenwarn.png b/mseide-msegui/icons/resources/dirredgreenwarn.png new file mode 100644 index 0000000..e9712c7 Binary files /dev/null and b/mseide-msegui/icons/resources/dirredgreenwarn.png differ diff --git a/mseide-msegui/icons/resources/dirredwarn.png b/mseide-msegui/icons/resources/dirredwarn.png new file mode 100644 index 0000000..8fc8f3d Binary files /dev/null and b/mseide-msegui/icons/resources/dirredwarn.png differ diff --git a/mseide-msegui/icons/resources/dirwhite.png b/mseide-msegui/icons/resources/dirwhite.png new file mode 100644 index 0000000..72ddfed Binary files /dev/null and b/mseide-msegui/icons/resources/dirwhite.png differ diff --git a/mseide-msegui/icons/resources/file.png b/mseide-msegui/icons/resources/file.png new file mode 100644 index 0000000..6869d76 Binary files /dev/null and b/mseide-msegui/icons/resources/file.png differ diff --git a/mseide-msegui/icons/resources/filedialogres.png b/mseide-msegui/icons/resources/filedialogres.png new file mode 100644 index 0000000..e32b496 Binary files /dev/null and b/mseide-msegui/icons/resources/filedialogres.png differ diff --git a/mseide-msegui/icons/resources/filegreen.png b/mseide-msegui/icons/resources/filegreen.png new file mode 100644 index 0000000..1594712 Binary files /dev/null and b/mseide-msegui/icons/resources/filegreen.png differ diff --git a/mseide-msegui/icons/resources/filegreenminusred.png b/mseide-msegui/icons/resources/filegreenminusred.png new file mode 100644 index 0000000..c2303ad Binary files /dev/null and b/mseide-msegui/icons/resources/filegreenminusred.png differ diff --git a/mseide-msegui/icons/resources/filegreenred.png b/mseide-msegui/icons/resources/filegreenred.png new file mode 100644 index 0000000..30ddc02 Binary files /dev/null and b/mseide-msegui/icons/resources/filegreenred.png differ diff --git a/mseide-msegui/icons/resources/filegreenredwarn.png b/mseide-msegui/icons/resources/filegreenredwarn.png new file mode 100644 index 0000000..a132087 Binary files /dev/null and b/mseide-msegui/icons/resources/filegreenredwarn.png differ diff --git a/mseide-msegui/icons/resources/filegreenwarn.png b/mseide-msegui/icons/resources/filegreenwarn.png new file mode 100644 index 0000000..61eaf1f Binary files /dev/null and b/mseide-msegui/icons/resources/filegreenwarn.png differ diff --git a/mseide-msegui/icons/resources/fileminusred.png b/mseide-msegui/icons/resources/fileminusred.png new file mode 100644 index 0000000..c40c13b Binary files /dev/null and b/mseide-msegui/icons/resources/fileminusred.png differ diff --git a/mseide-msegui/icons/resources/fileplusgreen.png b/mseide-msegui/icons/resources/fileplusgreen.png new file mode 100644 index 0000000..dccf727 Binary files /dev/null and b/mseide-msegui/icons/resources/fileplusgreen.png differ diff --git a/mseide-msegui/icons/resources/filered.png b/mseide-msegui/icons/resources/filered.png new file mode 100644 index 0000000..58dcb7b Binary files /dev/null and b/mseide-msegui/icons/resources/filered.png differ diff --git a/mseide-msegui/icons/resources/fileredplusgreen.png b/mseide-msegui/icons/resources/fileredplusgreen.png new file mode 100644 index 0000000..581a7ab Binary files /dev/null and b/mseide-msegui/icons/resources/fileredplusgreen.png differ diff --git a/mseide-msegui/icons/resources/fileredwarn.png b/mseide-msegui/icons/resources/fileredwarn.png new file mode 100644 index 0000000..cfef494 Binary files /dev/null and b/mseide-msegui/icons/resources/fileredwarn.png differ diff --git a/mseide-msegui/icons/resources/filterreset.png b/mseide-msegui/icons/resources/filterreset.png new file mode 100644 index 0000000..16b1b51 Binary files /dev/null and b/mseide-msegui/icons/resources/filterreset.png differ diff --git a/mseide-msegui/icons/resources/form.png b/mseide-msegui/icons/resources/form.png new file mode 100644 index 0000000..964d8af Binary files /dev/null and b/mseide-msegui/icons/resources/form.png differ diff --git a/mseide-msegui/icons/resources/imagebackground.png b/mseide-msegui/icons/resources/imagebackground.png new file mode 100644 index 0000000..80d23c3 Binary files /dev/null and b/mseide-msegui/icons/resources/imagebackground.png differ diff --git a/mseide-msegui/icons/resources/mergepending.png b/mseide-msegui/icons/resources/mergepending.png new file mode 100644 index 0000000..d84dcd8 Binary files /dev/null and b/mseide-msegui/icons/resources/mergepending.png differ diff --git a/mseide-msegui/icons/resources/mergependingred.png b/mseide-msegui/icons/resources/mergependingred.png new file mode 100644 index 0000000..3b3575a Binary files /dev/null and b/mseide-msegui/icons/resources/mergependingred.png differ diff --git a/mseide-msegui/icons/resources/opengl.png b/mseide-msegui/icons/resources/opengl.png new file mode 100644 index 0000000..13820db Binary files /dev/null and b/mseide-msegui/icons/resources/opengl.png differ diff --git a/mseide-msegui/icons/resources/pushconflict.png b/mseide-msegui/icons/resources/pushconflict.png new file mode 100644 index 0000000..0256ff6 Binary files /dev/null and b/mseide-msegui/icons/resources/pushconflict.png differ diff --git a/mseide-msegui/icons/resources/pushmergeconflictpending.png b/mseide-msegui/icons/resources/pushmergeconflictpending.png new file mode 100644 index 0000000..a95d432 Binary files /dev/null and b/mseide-msegui/icons/resources/pushmergeconflictpending.png differ diff --git a/mseide-msegui/icons/resources/pushmergepending.png b/mseide-msegui/icons/resources/pushmergepending.png new file mode 100644 index 0000000..7308179 Binary files /dev/null and b/mseide-msegui/icons/resources/pushmergepending.png differ diff --git a/mseide-msegui/icons/resources/pushpending.png b/mseide-msegui/icons/resources/pushpending.png new file mode 100644 index 0000000..69909c9 Binary files /dev/null and b/mseide-msegui/icons/resources/pushpending.png differ diff --git a/mseide-msegui/icons/resources/stg_checkboxparentnotchecked.png b/mseide-msegui/icons/resources/stg_checkboxparentnotchecked.png new file mode 100644 index 0000000..4302d63 Binary files /dev/null and b/mseide-msegui/icons/resources/stg_checkboxparentnotchecked.png differ diff --git a/mseide-msegui/icons/resources/stg_checkboxparentnotchecked.xcf b/mseide-msegui/icons/resources/stg_checkboxparentnotchecked.xcf new file mode 100644 index 0000000..6b0ebc2 Binary files /dev/null and b/mseide-msegui/icons/resources/stg_checkboxparentnotchecked.xcf differ diff --git a/mseide-msegui/icons/resources/unitform.png b/mseide-msegui/icons/resources/unitform.png new file mode 100644 index 0000000..3a49ba6 Binary files /dev/null and b/mseide-msegui/icons/resources/unitform.png differ diff --git a/mseide-msegui/lib/common/COPYING.LGPL b/mseide-msegui/lib/common/COPYING.LGPL new file mode 100644 index 0000000..b1e3f5a --- /dev/null +++ b/mseide-msegui/lib/common/COPYING.LGPL @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 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. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; 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. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/mseide-msegui/lib/common/COPYING.MSE b/mseide-msegui/lib/common/COPYING.MSE new file mode 100644 index 0000000..e2eff9b --- /dev/null +++ b/mseide-msegui/lib/common/COPYING.MSE @@ -0,0 +1,23 @@ +This is the file COPYING.MSE, it applies to the MSEgui Library. + +The source code of the MSEgui Library is +distributed under the Library GNU General Public License +(see the file COPYING) with the following modification: + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent modules, +and to copy and distribute the resulting executable under terms of your choice, +provided that you also meet, for each linked independent module, the terms +and conditions of the license of that module. An independent module is a module +which is not derived from or based on this library. If you modify this +library, you may extend this exception to your version of the library, but you are +not obligated to do so. If you do not wish to do so, delete this exception +statement from your version. + +If you didn't receive a copy of the file COPYING, contact: + Free Software Foundation + 675 Mass Ave + Cambridge, MA 02139 + USA + diff --git a/mseide-msegui/lib/common/assistive/mseassistivehandler.pas b/mseide-msegui/lib/common/assistive/mseassistivehandler.pas new file mode 100644 index 0000000..853681c --- /dev/null +++ b/mseide-msegui/lib/common/assistive/mseassistivehandler.pas @@ -0,0 +1,2596 @@ +{ MSEgui Copyright (c) 2017-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +// +// under construction +// +unit mseassistivehandler; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses,mseassistiveserver,mseevent,mselist, + mseguiglob,mseglob,msestrings,mseinterfaces,mseact,mseshapes, + mseassistiveclient,msemenuwidgets,msegrids,msespeak,msetypes, + msestockobjects,msegraphutils,msegui,msehash,mdb,msestat,msestatfile; + +type + assistivehandlerstatety = + (ahs_active,ahs_speaklocked, + ahs_activated, //set by dowindowactivated() and doapplicationactivated(), + //reset by doapplicationdeactivated() + ahs_applicationactivated, //set by doapplicationactivated(), + //consumed by dowindowactivated() + ahs_nocut, + ahs_windowactivated,ahs_menuactivated,ahs_menuactivatepending, + ahs_dropdownlistclosed,ahs_editcharenter,ahs_editchardelete, + ahs_locatepending,ahs_dropdownpending,ahs_cellwidgetpending, + ahs_dbchangepending, + ahs_textblock,ahs_textblock1); + assistivehandlerstatesty = set of assistivehandlerstatety; + +const + internalstates = [ahs_active,ahs_speaklocked,ahs_activated, + ahs_applicationactivated]; + volumemin = 0.2; + volumemax = 2; + ratemin = 0.2; + ratemax = 5; + +type + tassistivespeak = class(tcustomespeakng) + public + constructor create(aowner: tcomponent); override; + published + property datapath; + property options; + property device; + property bufferlength; + property voicedefault; + property voices; + property language; + property identifier; + property voicename; + property variant; + property gender; + property age; + property variantnum; + property volume; + property rate; + property pitch; + property range; + property wordgap; + property punctuationlist; + property onbeforeconnect; + end; + + tassistivehandler = class; + tassistivewidgetitem = class; + + assistiveeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + var handled: boolean) of object; + assistivemouseeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const info: mouseeventinfoty; var handled: boolean) of object; + assistivefocuschangedeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const oldwidget,newwidget: iassistiveclient; + var handled: boolean) of object; + assistivekeyeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const info: keyeventinfoty; var handled: boolean) of object; + assistivedataeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientdata; + var handled: boolean) of object; + assistivecelleventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientgrid; + const info: celleventinfoty; var handled: boolean) of object; + assistiveediteventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientedit; + var handled: boolean) of object; + assistiveeditstringeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientedit; + const atext: msestring; var handled: boolean) of object; + assistiveeditindexeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientedit; + const index: int32; var handled: boolean) of object; + assistiveeditinputmodeeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientedit; + const amode: editinputmodety; var handled: boolean) of object; + assistiveedittextblockeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring; + var handled: boolean) of object; + assistivedirectioneventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const adirection: graphicdirectionty; + var handled: boolean) of object; + assistivebooleaneventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const avalue: boolean; + var handled: boolean) of object; + assistivedirectiongrideventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; + const intf: iassistiveclientgrid; + const adirection: graphicdirectionty; + var handled: boolean) of object; + assistivestringeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; + const intf: iassistiveclient; var atext: msestring) of object; + assistivedataseteventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const akind: assistivedbeventkindty; const adataset: tdataset; + var handled: boolean) of object; + + tassistivewidgetitem = class(tmsecomponent) + private + fhandler: tassistivehandler; + fwidget: twidget; + fonwindowactivated: assistiveeventty; + fonwindowdeactivated: assistiveeventty; + fonwindowclosed: assistiveeventty; + fonenter: assistiveeventty; + fonactivate: assistiveeventty; + fondeactivate: assistiveeventty; + fonclientmouseevent: assistivemouseeventty; + fonkeydown: assistivekeyeventty; + fonchange: assistiveeventty; + fondataentered: assistivedataeventty; + foncellevent: assistivecelleventty; + foneditcharenter: assistiveeditstringeventty; + foneditchardelete: assistiveeditstringeventty; + foneditwithdrawn: assistiveediteventty; + foneditindexmoved: assistiveeditindexeventty; + foneditinputmodeset: assistiveeditinputmodeeventty; + fonedittextblock: assistiveedittextblockeventty; + fonnavigbordertouched: assistivedirectioneventty; + fontabordertouched: assistivebooleaneventty; + fongetcaption: assistivestringeventty; + fcaption: msestring; + fongettext: assistivestringeventty; + fongethint: assistivestringeventty; + ftext: msestring; + fhint: msestring; + fondbvaluechanged: assistivedataeventty; + fondatasetevent: assistivedataseteventty; + fongridbordertouched: assistivedirectiongrideventty; + procedure sethandler(const avalue:tassistivehandler); + procedure setwidget(const avalue: twidget); + protected + procedure linkhandler(); + procedure unlinkhandler(); + procedure objectevent(const sender: tobject; + const event: objecteventty) override; + procedure dowindowactivated(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure dowindowdeactivated(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure dowindowclosed(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure doenter(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure doactivate(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure dodeactivate(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure doclientmouseevent(const sender:tassistivehandler; + const aintf: iassistiveclient; const info: mouseeventinfoty; + var handled: boolean); + procedure dokeydown(const sender:tassistivehandler; + const aintf: iassistiveclient; const info: keyeventinfoty; + var handled: boolean); + procedure dochange(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure dodbvaluechanged(const sender:tassistivehandler; + const aintf: iassistiveclientdata; var handled: boolean); + procedure dodataentered(const sender:tassistivehandler; + const aintf: iassistiveclientdata; var handled: boolean); + procedure docellevent(const sender:tassistivehandler; + const aintf: iassistiveclientgrid; const info: celleventinfoty; + var handled: boolean); + procedure dogridbordertouched(const sender:tassistivehandler; + const aintf: iassistiveclientgrid; + const adirection: graphicdirectionty; + var handled: boolean); + procedure doeditcharenter(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const achar: msestring; + var handled: boolean); + procedure doeditchardelete(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const achar: msestring; + var handled: boolean); + procedure doeditindexmoved(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const aindex: int32; + var handled: boolean); + procedure doeditwithdrawn(const sender:tassistivehandler; + const aintf: iassistiveclientedit; var handled: boolean); + procedure doedittextblock(const sender:tassistivehandler; + const aintf: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring; + var handled: boolean); + procedure doeditinputmodeset(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const amode: editinputmodety; + var handled: boolean); + procedure donavigbordertouched(const sender:tassistivehandler; + const aintf: iassistiveclient; + const adirection: graphicdirectionty; + var handled: boolean); + procedure dotabordertouched(const sender:tassistivehandler; + const aintf: iassistiveclient; + const adown: boolean; + var handled: boolean); + procedure dodatasetevent(const sender:tassistivehandler; + const aintf: iassistiveclient; const akind: assistivedbeventkindty; + const adataset: tdataset; var handled: boolean); + function getcaption(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; + function gettext(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; + function gethint(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; + public + destructor destroy(); override; + published + property handler: tassistivehandler read fhandler write sethandler; + property widget: twidget read fwidget write setwidget; + property caption: msestring read fcaption write fcaption; + property text: msestring read ftext write ftext; + property hint: msestring read fhint write fhint; + property onwindowactivated: assistiveeventty read fonwindowactivated + write fonwindowactivated; + property onwindowdeactivated: assistiveeventty read fonwindowdeactivated + write fonwindowdeactivated; + property onwindowclosed: assistiveeventty read fonwindowclosed + write fonwindowclosed; + property onenter: assistiveeventty read fonenter write fonenter; + property onactivate: assistiveeventty read fonactivate write fonactivate; + property ondeactivate: assistiveeventty read fondeactivate + write fondeactivate; + property onclientmouseevent: assistivemouseeventty read fonclientmouseevent + write fonclientmouseevent; + property onkeydown: assistivekeyeventty read fonkeydown write fonkeydown; + property onchange: assistiveeventty read fonchange write fonchange; + property ondataentered: assistivedataeventty read fondataentered + write fondataentered; + property ondbvaluechanged: assistivedataeventty read fondbvaluechanged + write fondbvaluechanged; + property oncellevent: assistivecelleventty read foncellevent + write foncellevent; + property ongridbordertouched: assistivedirectiongrideventty + read fongridbordertouched write fongridbordertouched; + property oneditcharenter: assistiveeditstringeventty read foneditcharenter + write foneditcharenter; + property oneditchardelete: assistiveeditstringeventty read foneditchardelete + write foneditchardelete; + property oneditwithdrawn: assistiveediteventty read foneditwithdrawn + write foneditwithdrawn; + property oneditindexmoved: assistiveeditindexeventty read foneditindexmoved + write foneditindexmoved; + property oneditinputmodeset: assistiveeditinputmodeeventty + read foneditinputmodeset write foneditinputmodeset; + property onedittextblock: assistiveedittextblockeventty + read fonedittextblock write fonedittextblock; + property onnavigbordertouched: assistivedirectioneventty + read fonnavigbordertouched write fonnavigbordertouched; + property ontabordertouched: assistivebooleaneventty + read fontabordertouched write fontabordertouched; + property ondatasetevent: assistivedataseteventty + read fondatasetevent write fondatasetevent; + property ongetcaption: assistivestringeventty read fongetcaption + write fongetcaption; + property ongettext: assistivestringeventty read fongettext + write fongettext; + property ongethint: assistivestringeventty read fongethint + write fongethint; + end; + + assistivewidgetdataty = record + item: tassistivewidgetitem; + end; + + assistivewidgethashdataty = record + header: pointerhashdataty; //datapointer = interface + data: assistivewidgetdataty; + end; + passistivewidgethashdataty = ^assistivewidgethashdataty; + + tassistivewidgetitemlist = class(tpointerhashdatalist) + protected + function getrecordsize(): int32 override; + end; + + assistiveservereventty = + procedure(const sender:tassistivehandler; var handled: boolean) of object; + assistiveserverclienteventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclient; var handled: boolean) of object; + assistiveserverkeyeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclient; const info: keyeventinfoty; + var handled: boolean) of object; + assistiveservermouseeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclient; const info: mouseeventinfoty; + var handled: boolean) of object; + assistiveserverdataeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientdata; var handled: boolean) of object; + assistiveservercelleventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientgrid; const info: celleventinfoty; + var handled: boolean) of object; + assistiveservereditstringeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientedit; const achar: msestring; + var handled: boolean) of object; + assistiveserverediteventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientedit; var handled: boolean) of object; + assistiveservereditindexeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientedit; const index: int32; + var handled: boolean) of object; + assistiveservereditinputmodeeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientedit; const amode: editinputmodety; + var handled: boolean) of object; + assistiveserveredittextblockeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring; + var handled: boolean) of object; + assistiveserverdirectioneventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclient; + const adirection: graphicdirectionty; + var handled: boolean) of object; + assistiveserverbooleaneventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclient; + const avalue: boolean; + var handled: boolean) of object; + assistiveservergriddirectioneventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientgrid; + const adirection: graphicdirectionty; + var handled: boolean) of object; + + assistiveserverfocuschangedeventty = + procedure(const sender:tassistivehandler; + const oldwidget,newwidget: iassistiveclient; + var handled: boolean) of object; + assistiveserveractioneventty = + procedure (const sender: tassistivehandler; + const intf: iassistiveclient; //intf can be nil + const actionobj: tobject; const info: actioninfoty; + var handled: boolean) of object; + assistiveserveritemeventty = + procedure (const sender:tassistivehandler; + const intf: iassistiveclient; //intf can be nil + const items: shapeinfoarty; const aindex: integer; + var handled: boolean) of object; + assistiveservermenueventty = + procedure (const sender:tassistivehandler; + const intf: iassistiveclientmenu; + var handled: boolean) of object; + assistiveservermenuitemeventty = + procedure (const sender:tassistivehandler; + const intf: iassistiveclientmenu;//intf can be nil + const items: menucellinfoarty; const aindex: integer; + var handled: boolean) of object; + assistiveserverdataseteventty = + procedure(const handler: tassistivehandler; const intf: iassistiveclient; + const akind: assistivedbeventkindty; const adataset: tdataset; + var handled: boolean) of object; + speakoptionty = (spo_addtext,spo_hint,spo_columncaption,spo_parent,spo_path, + spo_notext, + spo_maincaption); + speakoptionsty = set of speakoptionty; + + tassistivehandler = class(tmsecomponent,iassistiveserver,istatfile) + private + factive: boolean; + fspeaker: tassistivespeak; + fvoicefixed: int32; + fvoicecaption: int32; + fvoicetext: int32; + fonwindowactivated: assistiveserverclienteventty; + fonwindowdeactivated: assistiveserverclienteventty; + fonwindowclosed: assistiveserverclienteventty; + fonenter: assistiveserverclienteventty; + fonactivate: assistiveserverclienteventty; + fondeactivate: assistiveserverclienteventty; + fonclientmouseevent: assistiveservermouseeventty; + fonfocuschanged: assistiveserverfocuschangedeventty; + fonkeydown: assistiveserverkeyeventty; + fonchange: assistiveserverclienteventty; + fondataentered: assistiveserverdataeventty; + foncellevent: assistiveservercelleventty; + foneditcharenter: assistiveservereditstringeventty; + foneditchardelete: assistiveservereditstringeventty; + foneditwithdrawn: assistiveserverediteventty; + foneditindexmoved: assistiveservereditindexeventty; + foneditinputmodeset: assistiveservereditinputmodeeventty; + fonedittextblock: assistiveserveredittextblockeventty; + fonnavigbordertouched: assistiveserverdirectioneventty; + fontabordertouched: assistiveserverbooleaneventty; + fonitementer: assistiveserveritemeventty; + fonmenuitementer: assistiveservermenuitemeventty; + fonactionexecute: assistiveserveractioneventty; + foptions: assistiveoptionsty; + fonapplicationactivated: assistiveservereventty; + fonapplicationdeactivated: assistiveservereventty; + fonmenuactivated: assistiveservermenueventty; + fondbvaluechanged: assistiveserverdataeventty; + fondatasetevent: assistiveserverdataseteventty; + fongridbordertouched: assistiveservergriddirectioneventty; + fvoicetextmessage: int32; + fvoicetextdisp: int32; + fvoicetextedit: int32; + fvoicetexteditreadonly: int32; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: int32; + fmaincaption: msestring; + procedure setactive(const avalue: boolean); + procedure setspeaker(const avalue: tassistivespeak); + procedure setoptions(const avalue: assistiveoptionsty); + procedure setstatfile(const avalue: tstatfile); + protected + fstate: assistivehandlerstatesty; + fspeaklock: int32; + fdataenteredkeyserial: card32; + fitems: tassistivewidgetitemlist; + fgridintf: iassistiveclientgrid; + fnewcell: gridcoordty; + fnewcol: boolean; + {$ifdef mse_debugassistive} + procedure debug(const text: string; + const intf: iassistiveclient); + {$endif} + procedure activate(); + procedure deactivate(); + + procedure loaded() override; + + function canspeak(): boolean; + procedure startspeak(); + + procedure registeritem(const aintf: iassistiveclient; + const aitem: tassistivewidgetitem); + procedure unregisteritem(const aintf: iassistiveclient); + function finditem(aintf: iassistiveclient; + out aitem: tassistivewidgetitem): boolean; + procedure doshortcut(const sender: twidget; var info: keyeventinfoty); + procedure dospeakagain(const sender: twidget); + procedure dospeakpath(const sender: twidget); + procedure checklocatepending(const sender: iassistiveclient); + function gettextvoice(const aflags: assistiveflagsty): int32; + + //iassistiveserver + procedure doapplicationactivated(); + procedure doapplicationdeactivated(); + procedure dowindowactivated(const sender: iassistiveclient); + procedure dowindowdeactivated(const sender: iassistiveclient); + procedure dowindowclosed(const sender: iassistiveclient); + procedure doenter(const sender: iassistiveclient); + procedure doactivate(const sender: iassistiveclient); + procedure dodeactivate(const sender: iassistiveclient); + procedure doclientmouseevent(const sender: iassistiveclient; + const info: mouseeventinfoty); + procedure dokeydown(const sender: iassistiveclient; + const info: keyeventinfoty); + procedure dochange(const sender: iassistiveclient); + procedure dodataentered(const sender: iassistiveclientdata); + procedure dodbvaluechanged(const sender: iassistiveclientdata); + procedure docellevent(const sender: iassistiveclientgrid; + const info: celleventinfoty); + procedure dogridbordertouched(const sender: iassistiveclientgrid; + const adirection: graphicdirectionty); + + procedure doeditcharenter(const sender: iassistiveclientedit; + const achar: msestring); + procedure doeditchardelete(const sender: iassistiveclientedit; + const achar: msestring); + procedure doeditindexmoved(const sender: iassistiveclientedit; + const aindex: int32); + procedure doeditwithdrawn(const sender: iassistiveclientedit); + procedure doedittextblock(const sender: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring); + procedure doeditinputmodeset(const sender: iassistiveclientedit; + const amode: editinputmodety); + procedure donavigbordertouched(const sender: iassistiveclient; + const adirection: graphicdirectionty); + procedure dotabordertouched(const sender: iassistiveclient; + const adown: boolean); + procedure dofocuschanged(const sender: iassistiveclient; + const oldwidget,newwidget: iassistiveclient); + procedure doactionexecute(const sender: iassistiveclient;//sender can be nil + const senderobj: tobject; const info: actioninfoty); + procedure doitementer(const sender: iassistiveclient; //sender can be nil + const items: shapeinfoarty; const aindex: integer); + procedure domenuactivated(const sender: iassistiveclientmenu); + procedure doitementer(const sender: iassistiveclientmenu;//sender can be nil + const items: menucellinfoarty; const aindex: integer); + procedure dodatasetevent(const sender: iassistiveclient; + const akind: assistivedbeventkindty; + const adataset: pointer); //tdataset + //istatfile + procedure dostatread(const reader: tstatreader) virtual; + procedure dostatwrite(const writer: tstatwriter) virtual; + procedure statreading(); + procedure statread(); + function getstatvarname(): msestring; + function getstatpriority(): integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure initnewcomponent(const ascale: real) override; + + procedure setstate(const astate: assistivehandlerstatesty); + procedure resetstate(const astate: assistivehandlerstatesty); + procedure speakstop(const acancel: boolean = false); + procedure speakcontinue(); + procedure wait(); + procedure cancel(); + procedure speaktext(const atext: msestring; const avoice: int32 = 0; + const nocut: boolean = false); + procedure speaktext1(const atext: msestring; const avoice: int32 = 0; + const nocut: boolean = false); + //with cancel + procedure speaktext(const atext: stockcaptionty; const avoice: int32 = 0; + const nocut: boolean = false); + procedure speaktext1(const atext: stockcaptionty; const avoice: int32 = 0; + const nocut: boolean = false); + //with cancel + procedure speakcharacter(const achar: char32; const avoice: int32 = 0; + const nocut: boolean = false); + procedure speakall(const sender: iassistiveclient; aoptions: speakoptionsty); + procedure speakall(const sender: twidget; aoptions: speakoptionsty); + procedure speakgridcell(const sender: iassistiveclientgrid; + const acell: gridcoordty; const acaption: boolean); + procedure speakinput(const sender: iassistiveclientdata); + procedure speakmenustart(const sender: iassistiveclient); + procedure speakallmenu(const sender: iassistiveclientmenu; + const ahint: boolean); + function getcaptiontext(const acaption: msestring): msestring; + function getcaptiontext(const sender: iassistiveclient): msestring; + function gettexttext(const sender: iassistiveclient): msestring; + function gethinttext(const sender: iassistiveclient): msestring; + procedure focusfirstelement(const awidget: twidget); + procedure focuslastelement(const awidget: twidget); + property state: assistivehandlerstatesty read fstate; + published + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read fstatvarname write fstatvarname; + property statpriority: int32 read fstatpriority + write fstatpriority default 0; + property active: boolean read factive write setactive default false; + property options: assistiveoptionsty read foptions + write setoptions default defaultassistiveoptions; + property speaker: tassistivespeak read fspeaker write setspeaker; + property voicefixed: int32 read fvoicefixed + write fvoicefixed default 0; + property maincaption: msestring read fmaincaption write fmaincaption; + property voicecaption: int32 read fvoicecaption + write fvoicecaption default 0; + property voicetextmessage: int32 read fvoicetextmessage + write fvoicetextmessage default 0; + property voicetext: int32 read fvoicetext + write fvoicetext default 0; + property voicetextdisp: int32 read fvoicetextdisp + write fvoicetextdisp default 0; + property voicetextedit: int32 read fvoicetextedit + write fvoicetextedit default 0; + property voicetexteditreadonly: int32 read fvoicetexteditreadonly + write fvoicetexteditreadonly default 0; + property onapplicationactivated: assistiveservereventty + read fonapplicationactivated write fonapplicationactivated; + property onapplicationdeactivated: assistiveservereventty + read fonapplicationdeactivated write fonapplicationdeactivated; + property onwindowactivated: assistiveserverclienteventty + read fonwindowactivated write fonwindowactivated; + property onwindowdeactivated: assistiveserverclienteventty + read fonwindowdeactivated write fonwindowdeactivated; + property onwindowclosed: assistiveserverclienteventty read fonwindowclosed + write fonwindowclosed; + property onenter: assistiveserverclienteventty read fonenter write fonenter; + property onactivate: assistiveserverclienteventty read fonactivate + write fonactivate; + property ondeactivate: assistiveserverclienteventty read fondeactivate + write fondeactivate; + property onclientmouseevent: assistiveservermouseeventty + read fonclientmouseevent write fonclientmouseevent; + property onfocuschanged: assistiveserverfocuschangedeventty + read fonfocuschanged write fonfocuschanged; + property onkeydown: assistiveserverkeyeventty read fonkeydown + write fonkeydown; + property onchange: assistiveserverclienteventty read fonchange + write fonchange; + property ondataentered: assistiveserverdataeventty read fondataentered + write fondataentered; + property ondbvaluechanged: assistiveserverdataeventty read fondbvaluechanged + write fondbvaluechanged; + property oncellevent: assistiveservercelleventty read foncellevent + write foncellevent; + property ongridbordertouched: assistiveservergriddirectioneventty + read fongridbordertouched write fongridbordertouched; + property oneditcharenter: assistiveservereditstringeventty + read foneditcharenter write foneditcharenter; + property oneditchardelete: assistiveservereditstringeventty + read foneditchardelete write foneditchardelete; + property oneditwithdrawn: assistiveserverediteventty read foneditwithdrawn + write foneditwithdrawn; + property oneditindexmoved: assistiveservereditindexeventty + read foneditindexmoved write foneditindexmoved; + property oneditinputmodeset: assistiveservereditinputmodeeventty + read foneditinputmodeset write foneditinputmodeset; + property onedittextblock: assistiveserveredittextblockeventty + read fonedittextblock write fonedittextblock; + property onnavigbordertouched: assistiveserverdirectioneventty + read fonnavigbordertouched write fonnavigbordertouched; + property ontabordertouched: assistiveserverbooleaneventty + read fontabordertouched write fontabordertouched; + property onactionexecute: assistiveserveractioneventty read fonactionexecute + write fonactionexecute; + property onitementer: assistiveserveritemeventty read fonitementer + write fonitementer; + property onmenuactivated: assistiveservermenueventty + read fonmenuactivated write fonmenuactivated; + property onmenuitementer: assistiveservermenuitemeventty + read fonmenuitementer write fonmenuitementer; + property ondatasetevent: assistiveserverdataseteventty + read fondatasetevent write fondatasetevent; + end; + +implementation +uses + msekeyboard,sysutils,msesysutils,mserichstring,msemenus,mseactions, + msegridsglob,mseeditglob,typinfo; + +type + twidget1 = class(twidget); + tpopupmenuwidget1 = class(tpopupmenuwidget); + tmenuitem1 = class(tmenuitem); + +{ tassistivespeak } + +constructor tassistivespeak.create(aowner: tcomponent); +begin + inherited; + setsubcomponent(true); +end; + +{ tassistivewidgetitem } + +destructor tassistivewidgetitem.destroy(); +begin + handler:= nil; + inherited; +end; + +procedure tassistivewidgetitem.sethandler(const avalue:tassistivehandler); +begin + unlinkhandler(); + setlinkedvar(avalue,tmsecomponent(fhandler)); + linkhandler(); +end; + +procedure tassistivewidgetitem.setwidget(const avalue: twidget); +begin + unlinkhandler(); + setlinkedvar(avalue,tmsecomponent(fwidget)); + linkhandler(); +end; + +procedure tassistivewidgetitem.linkhandler(); +begin + if (fwidget <> nil) and (fhandler <> nil) and + not (csdesigning in componentstate) then begin + fhandler.registeritem(twidget1(fwidget).getiassistiveclient,self); + end; +end; + +procedure tassistivewidgetitem.unlinkhandler(); +begin + if (fhandler <> nil) and (fwidget <> nil) and + not (csdesigning in componentstate) then begin + fhandler.unregisteritem(twidget1(fwidget).getiassistiveclient()); + end; +end; + +procedure tassistivewidgetitem.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_destroyed) and (sender = fwidget) then begin + unlinkhandler(); + end; + inherited; +end; + +procedure tassistivewidgetitem.dowindowactivated(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fonwindowactivated)) then begin + fonwindowactivated(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.dowindowdeactivated( + const sender:tassistivehandler; const aintf: iassistiveclient; + var handled: boolean); +begin + if canevent(tmethod(fonwindowdeactivated)) then begin + fonwindowdeactivated(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.dowindowclosed(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fonwindowclosed)) then begin + fonwindowclosed(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.doenter(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fonenter)) then begin + fonenter(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.doactivate(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fonactivate)) then begin + fonactivate(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.dodeactivate(const sender: tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fondeactivate)) then begin + fondeactivate(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.doclientmouseevent( + const sender:tassistivehandler; const aintf: iassistiveclient; + const info: mouseeventinfoty; var handled: boolean); +begin + if canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,sender,aintf,info,handled); + end; +end; + +procedure tassistivewidgetitem.dokeydown(const sender:tassistivehandler; + const aintf: iassistiveclient; const info: keyeventinfoty; + var handled: boolean); +begin + if canevent(tmethod(fonkeydown)) then begin + fonkeydown(self,sender,aintf,info,handled); + end; +end; + +procedure tassistivewidgetitem.dochange(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fonchange)) then begin + fonchange(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.dodbvaluechanged(const sender: tassistivehandler; + const aintf: iassistiveclientdata; var handled: boolean); +begin + if canevent(tmethod(fondbvaluechanged)) then begin + fondbvaluechanged(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.dodataentered(const sender:tassistivehandler; + const aintf: iassistiveclientdata; var handled: boolean); +begin + if canevent(tmethod(fondataentered)) then begin + fondataentered(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.docellevent(const sender:tassistivehandler; + const aintf: iassistiveclientgrid; const info: celleventinfoty; + var handled: boolean); +begin + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,sender,aintf,info,handled); + end; +end; + +procedure tassistivewidgetitem.dogridbordertouched( + const sender: tassistivehandler; + const aintf: iassistiveclientgrid; + const adirection: graphicdirectionty; var handled: boolean); +begin + if canevent(tmethod(fongridbordertouched)) then begin + fongridbordertouched(self,sender,aintf,adirection,handled); + end; +end; + +procedure tassistivewidgetitem.doeditcharenter(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const achar: msestring; + var handled: boolean); +begin + if canevent(tmethod(foneditcharenter)) then begin + foneditcharenter(self,sender,aintf,achar,handled); + end; +end; + +procedure tassistivewidgetitem.doeditchardelete(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const achar: msestring; + var handled: boolean); +begin + if canevent(tmethod(foneditchardelete)) then begin + foneditchardelete(self,sender,aintf,achar,handled); + end; +end; + +procedure tassistivewidgetitem.doeditindexmoved(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const aindex: int32; + var handled: boolean); +begin + if canevent(tmethod(foneditindexmoved)) then begin + foneditindexmoved(self,sender,aintf,aindex,handled); + end; +end; + +procedure tassistivewidgetitem.doeditwithdrawn(const sender:tassistivehandler; + const aintf: iassistiveclientedit; var handled: boolean); +begin + if canevent(tmethod(foneditwithdrawn)) then begin + foneditwithdrawn(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.doedittextblock(const sender:tassistivehandler; + const aintf: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring; + var handled: boolean); +begin + if canevent(tmethod(fonedittextblock)) then begin + fonedittextblock(self,sender,aintf,amode,atext,handled); + end; +end; + +procedure tassistivewidgetitem.doeditinputmodeset( + const sender:tassistivehandler; const aintf: iassistiveclientedit; + const amode: editinputmodety; var handled: boolean); +begin + if canevent(tmethod(foneditinputmodeset)) then begin + foneditinputmodeset(self,sender,aintf,amode,handled); + end; +end; + +procedure tassistivewidgetitem.donavigbordertouched( + const sender:tassistivehandler; const aintf: iassistiveclient; + const adirection: graphicdirectionty; var handled: boolean); +begin + if canevent(tmethod(fonnavigbordertouched)) then begin + fonnavigbordertouched(self,sender,aintf,adirection,handled); + end; +end; + +procedure tassistivewidgetitem.dotabordertouched( + const sender: tassistivehandler; const aintf: iassistiveclient; + const adown: boolean; var handled: boolean); +begin + if canevent(tmethod(fontabordertouched)) then begin + fontabordertouched(self,sender,aintf,adown,handled); + end; +end; + +procedure tassistivewidgetitem.dodatasetevent(const sender: tassistivehandler; + const aintf: iassistiveclient; + const akind: assistivedbeventkindty; const adataset: tdataset; + var handled: boolean); +begin + if canevent(tmethod(fondatasetevent)) then begin + fondatasetevent(self,sender,aintf,akind,adataset,handled); + end; +end; + +function tassistivewidgetitem.getcaption(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; +begin + result:= fcaption; + if canevent(tmethod(fongetcaption)) then begin + fongetcaption(self,sender,aintf,result); + end; +end; + +function tassistivewidgetitem.gettext(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; +begin + result:= ftext; + if canevent(tmethod(fongettext)) then begin + fongettext(self,sender,aintf,result); + end; +end; + +function tassistivewidgetitem.gethint(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; +begin + result:= fhint; + if canevent(tmethod(fongethint)) then begin + fongethint(self,sender,aintf,result); + end; +end; + +{ tassistivewidgetitemlist } + +function tassistivewidgetitemlist.getrecordsize(): int32; +begin + result:= sizeof(assistivewidgethashdataty); +end; + +{tassistivehandler } + +constructor tassistivehandler.create(aowner: tcomponent); +begin + foptions:= defaultassistiveoptions; + fspeaker:= tassistivespeak.create(nil); + fitems:= tassistivewidgetitemlist.create(); + inherited; +end; + +destructor tassistivehandler.destroy(); +begin + inherited; + fspeaker.free(); + fitems.free(); +end; + +procedure tassistivehandler.initnewcomponent(const ascale: real); +begin + fvoicetext:= 1; + fvoicetextmessage:= 1; + fvoicetextdisp:= 2; + fvoicetextedit:= 2; + fvoicetexteditreadonly:= 2; + fspeaker.voices.count:= 3; + with fspeaker.voices[0] do begin + gender:= gen_male; + end; + with fspeaker.voices[1] do begin + gender:= gen_female; + end; + with fspeaker.voices[2] do begin + gender:= gen_female; + punctuation:= pu_all; + end; +end; + +procedure tassistivehandler.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + factive:= avalue; + if not (csloading in componentstate) then begin + if avalue then begin + activate(); + end + else begin + deactivate(); + end; + end; + end; +end; + +procedure tassistivehandler.activate(); +begin + if not (csdesigning in componentstate) then begin + fspeaklock:= 0; + application.registeronshortcut(@doshortcut); + fspeaker.active:= true; + assistiveserver:= iassistiveserver(self); + assistiveoptions:= options; + fstate:= [ahs_active]; +// include(fstate,ahs_active); + application.invalidate(); + end; +end; + +procedure tassistivehandler.deactivate(); +begin + if not (csdesigning in componentstate) then begin + application.unregisteronshortcut(@doshortcut); + assistiveserver:= nil; + assistiveoptions:= []; + fspeaker.active:= false; + exclude(fstate,ahs_active); + application.invalidate(); + end; +end; + +procedure tassistivehandler.setspeaker(const avalue: tassistivespeak); +begin + fspeaker.assign(avalue); +end; + +procedure tassistivehandler.setoptions(const avalue: assistiveoptionsty); +begin + foptions:= avalue; + if ahs_active in fstate then begin + assistiveoptions:= foptions; + end; +end; + +procedure tassistivehandler.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tassistivehandler.loaded(); +begin + inherited; + if factive then begin + factive:= false; + active:= true; + end; +end; + +procedure tassistivehandler.wait(); +begin + fspeaker.wait(); +end; + +procedure tassistivehandler.cancel(); +begin + if (fspeaklock <= 0) then begin + if not (ahs_nocut in fstate) then begin + fspeaker.cancel(); + end; + exclude(fstate,ahs_nocut); + end; +end; + +function tassistivehandler.getcaptiontext(const acaption: msestring): msestring; +var + capt1: richstringty; +begin + captiontorichstring(acaption,capt1); + result:= capt1.text; +end; + +function tassistivehandler.getcaptiontext( + const sender: iassistiveclient): msestring; +var + item1: tassistivewidgetitem; +begin + result:= ''; + if finditem(sender,item1) then begin + result:= item1.getcaption(self,sender); + end; + if result = '' then begin + result:= getcaptiontext(sender.getassistivecaption()); + end; +end; + +function tassistivehandler.gettexttext( + const sender: iassistiveclient): msestring; +var + item1: tassistivewidgetitem; +begin + result:= ''; + if finditem(sender,item1) then begin + result:= item1.gettext(self,sender); + end; + if result = '' then begin + result:= sender.getassistivetext(); + end; +end; + +function tassistivehandler.gethinttext( + const sender: iassistiveclient): msestring; +var + item1: tassistivewidgetitem; +begin + result:= ''; + if finditem(sender,item1) then begin + result:= item1.gethint(self,sender); + end; + if result = '' then begin + result:= sender.getassistivehint(); + end; +end; + +procedure tassistivehandler.focusfirstelement(const awidget: twidget); +var + w1: twidget; +begin + if awidget <> nil then begin + w1:= awidget.window.firstfocuswidget(); + if w1 <> nil then begin + w1.activate(); + end; + end; +end; + +procedure tassistivehandler.focuslastelement(const awidget: twidget); +var + w1: twidget; +begin + if awidget <> nil then begin + w1:= awidget.window.lastfocuswidget(); + if w1 <> nil then begin + w1.activate(); + end; + end; +end; + +function tassistivehandler.canspeak(): boolean; +begin + result:= fstate * [ahs_active,ahs_speaklocked,ahs_activated] = + [ahs_active,ahs_activated]; +end; + +procedure tassistivehandler.speaktext(const atext: msestring; + const avoice: int32 = 0; const nocut: boolean = false); +begin + if canspeak() then begin + if nocut then begin + include(fstate,ahs_nocut); + end; + fspeaker.speak(atext,[so_endpause],avoice); + end; +end; + +procedure tassistivehandler.speaktext1(const atext: msestring; + const avoice: int32 = 0; const nocut: boolean = false); +begin + cancel(); + speaktext(atext,avoice,nocut); +end; + +procedure tassistivehandler.speaktext(const atext: stockcaptionty; + const avoice: int32 = 0; const nocut: boolean = false); +begin + speaktext(stockobjects.captions[atext],avoice,nocut); +end; + +procedure tassistivehandler.speaktext1(const atext: stockcaptionty; + const avoice: int32 = 0; const nocut: boolean = false); +begin + cancel(); + speaktext(atext,avoice,nocut); +end; + +procedure tassistivehandler.speakcharacter(const achar: char32; + const avoice: int32 = 0; const nocut: boolean = false); +begin + if canspeak() then begin + if nocut then begin + include(fstate,ahs_nocut); + end; + fspeaker.speakcharacter(achar,[so_endpause],avoice); + end; +end; + +procedure tassistivehandler.speakall(const sender: iassistiveclient; + aoptions: speakoptionsty); +var + fla1: assistiveflagsty; + s1,s2,s3: msestring; + w1: tpopupmenuwidget1; + intf2: iassistiveclient; + i1: int32; + b1: boolean; +begin + fla1:= sender.getassistiveflags(); + intf2:= sender.getassistiveparent(); + if spo_path in aoptions then begin + exclude(aoptions,spo_parent); + aoptions:= aoptions + [spo_columncaption]; + if intf2 <> nil then begin + exclude(fla1,asf_toplevel); + speakall(intf2,aoptions+[spo_notext]); + include(aoptions,spo_addtext); + exclude(aoptions,spo_maincaption); + intf2:= nil; + end; + end + else begin + if not (spo_parent in aoptions) then begin + intf2:= nil; + end; + end; + i1:= gettextvoice(fla1); + if asf_async in fla1 then begin + include(aoptions,spo_addtext); + end; + pointer(w1):= sender.getinstance(); + if not (spo_addtext in aoptions) then begin + startspeak(); + end; +// s1:= ''; + if asf_menu in fla1 then begin + if w1 is tpopupmenuwidget then begin + speakallmenu(tmenuitem1(w1.flayout.menu).getiassistiveclient(), + spo_hint in aoptions); + exit; + end; + end; + if (intf2 <> nil) and (asf_message in intf2.getassistiveflags()) then begin + speakall(intf2,aoptions - [spo_addtext,spo_parent,spo_maincaption]); + end; + if fla1 * [asf_grid,asf_popup] = [asf_grid,asf_popup] then begin + b1:= aoptions * [spo_parent,spo_path] <> []; + if b1 and not(aso_textfirst in foptions) then begin + speaktext(sc_selection,fvoicefixed); + end; + with iassistiveclientgrid(sender) do begin + speaktext(getassistivecellcaption(mgc(getassistivefocusedcell().col,-1)), + fvoicecaption); + speaktext(getassistivecelltext(getassistivefocusedcell(),fla1),i1); + end; + if b1 and (aso_textfirst in foptions) then begin + speaktext(sc_selection,fvoicefixed); + end; + exit; + end; + s2:= ''; + if asf_button in fla1 then begin + if asf_disabled in fla1 then begin + s2:= stockobjects.captions[sc_disabledbutton] + ' '; + end + else begin + s2:= stockobjects.captions[sc_button] + ' '; + end; + end; + if asf_toplevel in fla1 then begin + if s2 <> '' then begin + s2:= sc(sc_area)+' '+s2; + end + else begin + s2:= sc(sc_area); + end; + end; +// speaktext(s1,fvoicefixed); + s1:= ''; + if (spo_columncaption in aoptions) and (asf_gridwidget in fla1) then begin + s1:= s1+iassistiveclientgridwidget(sender).getassistivecolumncaption(); + end; + s3:= getcaptiontext(sender); + if (spo_maincaption in aoptions) and (maincaption <> '') then begin + if not (asf_mainwindow in fla1) then begin + s3:= maincaption+' '+s3; + end; + end; + if s3 <> '' then begin + if s1 <> '' then begin + s1:= s1 + ' '; + end; +{ + if asf_toplevel in fla1 then begin + s1:= s1 + sc(sc_window) + ' '; + end; +} + s1:= s1 + s3; + end; + if asf_message in fla1 then begin + exclude(aoptions,spo_notext); + end; + if aso_textfirst in foptions then begin + if not (spo_notext in aoptions) then begin + speaktext(gettexttext(sender),i1); + end; + speaktext(s1,fvoicecaption); + speaktext(s2,fvoicefixed); + end + else begin + speaktext(s2,fvoicefixed); + speaktext(s1,fvoicecaption); + if not (spo_notext in aoptions) then begin + speaktext(gettexttext(sender),i1); + end; + end; + if spo_hint in aoptions then begin + speaktext(gethinttext(sender),fvoicecaption); + end; +end; + +procedure tassistivehandler.speakall(const sender: twidget; + aoptions: speakoptionsty); +begin + if sender <> nil then begin + speakall(twidget1(sender).getiassistiveclient(),aoptions); + end; +end; + +procedure tassistivehandler.speakgridcell(const sender: iassistiveclientgrid; + const acell: gridcoordty; const acaption: boolean); +var + i1: int32; + s1: msestring; + f1: assistiveflagsty; +begin + s1:= sender.getassistivecelltext(acell,f1); + i1:= gettextvoice(f1); + if aso_textfirst in foptions then begin + speaktext(s1,i1); + end; + if acaption then begin + speaktext(sender.getassistivecellcaption( + mgc(acell.col,-1)),fvoicecaption); + end; + if not (aso_textfirst in foptions) then begin + speaktext(s1,i1); + end; +end; + +procedure tassistivehandler.speakinput(const sender: iassistiveclientdata); +var + i1: int32; +begin + startspeak(); + i1:= gettextvoice(sender.getassistiveflags); + if aso_textfirst in foptions then begin + speaktext(gettexttext(sender),i1); + end; + speaktext(sc_input,fvoicefixed); + speaktext(getcaptiontext(iassistiveclient(sender)),fvoicecaption); + if not (aso_textfirst in foptions) then begin + speaktext(gettexttext(sender),i1); + end; +end; + +procedure tassistivehandler.speakmenustart(const sender: iassistiveclient); +begin + speaktext(sc_menu,fvoicefixed); +end; + +procedure tassistivehandler.setstate(const astate: assistivehandlerstatesty); +begin + fstate:= fstate + (astate-internalstates); +end; + +procedure tassistivehandler.resetstate(const astate: assistivehandlerstatesty); +begin + fstate:= fstate - (astate-internalstates); +end; + +procedure tassistivehandler.speakstop(const acancel: boolean = false); +begin + if acancel then begin + cancel; + end; + inc(fspeaklock); + if fspeaklock > 0 then begin + include(fstate,ahs_speaklocked); + end; +end; + +procedure tassistivehandler.speakcontinue(); +begin + dec(fspeaklock); + if fspeaklock <= 0 then begin + exclude(fstate,ahs_speaklocked); + end; +end; + +procedure tassistivehandler.startspeak(); +begin + cancel(); +end; + +procedure tassistivehandler.registeritem(const aintf: iassistiveclient; + const aitem: tassistivewidgetitem); +begin + with passistivewidgethashdataty(fitems.add(aintf))^ do begin + data.item:= aitem; + end; +end; + +procedure tassistivehandler.unregisteritem(const aintf: iassistiveclient); +begin + fitems.delete(aintf,true); +end; + +function tassistivehandler.finditem(aintf: iassistiveclient; + out aitem: tassistivewidgetitem): boolean; +var + p1: passistivewidgethashdataty; +begin + result:= false; + aitem:= nil; + p1:= pointer(fitems.find(aintf)); + if p1 <> nil then begin + aitem:= p1^ .data.item; + result:= true; + end; +end; + +function checkassistiveshortcut(const akind: assistiveshortcutty; + var info: keyeventinfoty): boolean; +begin + result:= false; + if not (es_processed in info.eventstate) then begin + if checkactionshortcut(assistiveshortcuts[akind],info) then begin + result:= true; + end + else begin + if not (es_processed in info.eventstate) then begin + if checkactionshortcut(assistiveshortcuts1[akind],info) then begin + result:= true; + end; + end; + end; + end; +end; + +procedure tassistivehandler.doshortcut(const sender: twidget; + var info: keyeventinfoty); +var + sho1: assistiveshortcutty; + f1: flo64; +begin + for sho1:= low(sho1) to high(sho1) do begin + if es_processed in info.eventstate then begin + break; + end; + if checkassistiveshortcut(sho1,info) then begin + case sho1 of + shoa_speakagain: begin + dospeakagain(sender); + end; + shoa_speakpath: begin + dospeakpath(sender); + end; + shoa_firstelement: begin + focusfirstelement(sender); + end; + shoa_lastelement: begin + focuslastelement(sender); + end; + shoa_cancelspeech: begin + cancel(); + end; + shoa_slower: begin + f1:= fspeaker.rate/1.1; + if f1 < ratemin then begin + f1:= ratemin; + end; + fspeaker.rate:= f1; + startspeak(); + speaktext(sc_slower,voicetext); + end; + shoa_faster: begin + f1:= fspeaker.rate*1.1; + if f1 > ratemax then begin + f1:= ratemax; + end; + fspeaker.rate:= f1; + startspeak(); + speaktext(sc_faster,voicetext); + end; + shoa_volumedown: begin + f1:= fspeaker.volume/1.1; + if f1 < volumemin then begin + f1:= volumemin; + end; + fspeaker.volume:= f1; + startspeak(); + speaktext(sc_volumedown,voicetext); + end; + shoa_volumeup: begin + f1:= fspeaker.volume*1.1; + if f1 > volumemax then begin + f1:= volumemax; + end; + fspeaker.volume:= f1; + startspeak(); + speaktext(sc_volumeup,voicetext); + end; + end; + end; + end; +end; + +procedure tassistivehandler.dospeakagain(const sender: twidget); +begin + cancel(); + speakall(twidget1(sender).getiassistiveclient(),[spo_hint,spo_parent, + spo_columncaption]); +end; + +procedure tassistivehandler.dospeakpath(const sender: twidget); +begin + cancel(); + speakall(twidget1(sender).getiassistiveclient(), + [spo_hint,spo_path,spo_maincaption]); +end; + +procedure tassistivehandler.checklocatepending(const sender: iassistiveclient); +begin + if asf_hasdropdown in sender.getassistiveflags then begin + setstate([ahs_locatepending]); + end; +end; + +function tassistivehandler.gettextvoice(const aflags: assistiveflagsty): int32; +begin + result:= fvoicetext; + if aflags * [asf_popup,asf_grid] = [asf_popup,asf_grid] then begin + result:= fvoicetexteditreadonly; + end; + if asf_message in aflags then begin + result:= fvoicetextmessage; + end; + if asf_dispwidget in aflags then begin + result:= fvoicetextdisp; + end; + if [asf_inplaceedit,asf_textedit] * aflags <> [] then begin + if asf_readonly in aflags then begin + result:= fvoicetexteditreadonly; + end + else begin + result:= fvoicetextedit; + end; + end; +end; + +{$ifdef mse_debugassistive} +procedure tassistivehandler.debug(const text: string; + const intf: iassistiveclient); +var + wi1: twidget; +begin + debugwrite('*'+text+':'+ + settostring(ptypeinfo(typeinfo(assistivehandlerstatesty)), + int32(fstate),true)); + if intf <> nil then begin + pointer(wi1):= intf.getassistivewidget(); + if wi1 <> nil then begin + debugwriteln(':'+wi1.name); + end + else begin + debugwriteln(':NIL'); + end; + debugwrite(' '+settostring(ptypeinfo(typeinfo(assistiveflagsty)), + int32(intf.getassistiveflags()),true)); + end; + debugwriteln(''); +end; +{$endif} + +procedure tassistivehandler.doapplicationactivated(); +var + b1: boolean; +begin + fstate:= fstate + [ahs_activated,ahs_applicationactivated]; +{$ifdef mse_debugassistive} + debug('applicationactivated',nil); +{$endif} + b1:= false; + if canevent(tmethod(fonapplicationactivated)) then begin + fonapplicationactivated(self,b1); + end; +end; + +procedure tassistivehandler.doapplicationdeactivated(); +var + b1: boolean; +begin + fstate:= fstate - [ahs_activated,ahs_applicationactivated, + ahs_dropdownlistclosed,ahs_dropdownpending]; +{$ifdef mse_debugassistive} + debug('applicationdeactivated',nil); +{$endif} + b1:= false; + if canevent(tmethod(fonapplicationdeactivated)) then begin + fonapplicationdeactivated(self,b1); + end; + if not b1 then begin + cancel(); + end; +end; + +procedure tassistivehandler.dowindowactivated(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; + fla1: assistiveflagsty; + i1: int32; + s1: msestring; +begin +{$ifdef mse_debugassistive} + debug('windowactivated',sender); +{$endif} + include(fstate,ahs_activated); + setstate([ahs_windowactivated]); + b1:= false; + if finditem(sender,item1) then begin + item1.dowindowactivated(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonwindowactivated)) then begin + fonwindowactivated(self,sender,b1); + end; + if not b1 then begin + fla1:= sender.getassistiveflags(); + if asf_menu in fla1 then begin + { + setstate([ass_menuactivated]); + if not (ass_menuactivatepending in fstate) then begin + startspeak(); + speakmenustart(sender); + end; + } + end + else begin + if fstate*[ahs_dropdownlistclosed,ahs_dropdownpending] = [] then begin + if fla1 * [asf_async,asf_message] <> [asf_async] then begin + startspeak(); + end; + i1:= gettextvoice(fla1); + s1:= getcaptiontext(sender); + if (ahs_applicationactivated in fstate) and (fmaincaption <> '') and + (not (asf_mainwindow in fla1) or (s1 = '')) then begin + s1:= fmaincaption + ' ' + s1; + end; + exclude(fstate,ahs_applicationactivated); + if aso_textfirst in foptions then begin + speaktext(gettexttext(sender),i1); + speaktext(s1,fvoicecaption); + speaktext(sc(sc_areaactivated),fvoicefixed); + end + else begin + speaktext(s1,fvoicecaption); + speaktext(sc(sc_areaactivated),fvoicefixed); + speaktext(gettexttext(sender),i1); + end; + end; + end; + end; + end; + resetstate([ahs_menuactivatepending,ahs_dropdownpending]); +end; + +procedure tassistivehandler.dowindowdeactivated(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('windowdeactivated',sender); +{$endif} + if sender.getassistiveflags() * [asf_popup,asf_grid] = + [asf_popup,asf_grid] then begin + setstate([ahs_dropdownlistclosed]); + end; + b1:= false; + if finditem(sender,item1) then begin + item1.dowindowdeactivated(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonwindowdeactivated)) then begin + fonwindowdeactivated(self,sender,b1); + end; + if not b1 then begin + end; + end; + resetstate([ahs_windowactivated]); +end; + +procedure tassistivehandler.dowindowclosed(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('windowclosed',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dowindowclosed(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonwindowclosed)) then begin + fonwindowclosed(self,sender,b1); + end; + end; +end; + +procedure tassistivehandler.doenter(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('enter',sender); +{$endif} + resetstate([ahs_dropdownpending]); + if (ahs_editcharenter in fstate) and + (sender.getassistiveflags*[asf_popup,asf_grid] = + [asf_popup,asf_grid]) then begin + setstate([ahs_dropdownpending]); + end; + b1:= false; + if finditem(sender,item1) then begin + item1.doenter(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonenter)) then begin + fonenter(self,sender,b1); + end; + end; + resetstate([ahs_editcharenter]); +end; + +procedure tassistivehandler.doactivate(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; + fla1: assistiveflagsty; + opt1: speakoptionsty; +begin +{$ifdef mse_debugassistive} + debug('activate',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.doactivate(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonactivate)) then begin + fonactivate(self,sender,b1); + end; + if twidget(sender.getassistivewidget).focused then begin + if not b1{ and not (ahs_cellwidgetpending in fstate)} then begin + fla1:= sender.getassistiveflags(); + if not (asf_dummy in fla1) then begin + if asf_menu in fla1 then begin + end + else begin + if fla1*[asf_grid,asf_popup] = [asf_grid,asf_popup] then begin + if not (aso_textfirst in foptions) then begin + speaktext(sc_selection,fvoicefixed); + end; + speakgridcell(iassistiveclientgrid(sender), + tcustomgrid(sender.getassistivewidget()).focusedcell,true); + if aso_textfirst in foptions then begin + speaktext(sc_selection,fvoicefixed); + end; + end + else begin + if not (ahs_dropdownlistclosed in fstate) and + not (asf_scrolllimit in fla1) then begin + opt1:= []; + if asf_gridwidget in fla1 then begin + setstate([ahs_dbchangepending]); + if ahs_windowactivated in fstate then begin + include(opt1,spo_columncaption); + end; + end; + if fstate * [ahs_windowactivated,ahs_cellwidgetpending] <> [] then begin + include(opt1,spo_addtext); + end; + speakall(sender,opt1); + if (aso_textfirst in foptions) and + (ahs_cellwidgetpending in fstate) then begin + speakgridcell(fgridintf,fnewcell,fnewcol); + end; + end; + end; + end; + end; + end; + end; + end; + fla1:= sender.getassistiveflags(); + if not (asf_dummy in fla1) then begin + resetstate([ahs_cellwidgetpending]); + if asf_focused in fla1 then begin + resetstate([ahs_windowactivated,ahs_dropdownlistclosed]); + end; + end; +end; + +procedure tassistivehandler.dodeactivate(const sender: iassistiveclient); +var + item1: tassistivewidgetitem; + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('deactivate',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dodeactivate(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fondeactivate)) then begin + fonactivate(self,sender,b1); + end; + end; + resetstate([ahs_dbchangepending]); +end; + +procedure tassistivehandler.doclientmouseevent(const sender: iassistiveclient; + const info: mouseeventinfoty); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('clientmouseevent',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.doclientmouseevent(self,sender,info,b1); + end; + if not b1 then begin + if canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,sender,info,b1); + end; + end; +end; + +procedure tassistivehandler.dofocuschanged(const sender: iassistiveclient; + const oldwidget: iassistiveclient; const newwidget: iassistiveclient); +var + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('focuschanged',sender); +{$endif} + b1:= false; + if canevent(tmethod(fonfocuschanged)) then begin + fonfocuschanged(self,oldwidget,newwidget,b1); + end; +end; + +procedure tassistivehandler.dokeydown(const sender: iassistiveclient; + const info: keyeventinfoty); +//var +// fla1: assistiveflagsty; +begin +{$ifdef mse_debugassistive} + debug('keydown',sender); +{$endif} + if not (es_child in info.eventstate) then begin + { + if (info.key = key_return) and + (info.shiftstate*keyshiftstatesmask = []) then begin + if info.serial <> fdataenteredkeyserial then begin + speakall(sender,false,true); + end; + end; + } + fdataenteredkeyserial:= 0; + end; +end; + +procedure tassistivehandler.doactionexecute(const sender: iassistiveclient; + const senderobj: tobject; const info: actioninfoty); +var + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('actionexecute',sender); +{$endif} + b1:= false; + if canevent(tmethod(fonactionexecute)) then begin + fonactionexecute(self,sender,senderobj,info,b1); + end; +end; + +procedure tassistivehandler.dochange(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('change',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dochange(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonchange)) then begin + fonchange(self,sender,b1); + end; + end; +end; + +procedure tassistivehandler.dodataentered(const sender: iassistiveclientdata); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('dataentered',sender); +{$endif} + fdataenteredkeyserial:= 0; + if application.keyeventinfo <> nil then begin + fdataenteredkeyserial:= application.keyeventinfo^.serial; + end; + b1:= false; + if finditem(sender,item1) then begin + item1.doenter(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonenter)) then begin + fonenter(self,sender,b1); + end; + if not b1 then begin + speakinput(sender); + end; + end; +end; + +procedure tassistivehandler.dodbvaluechanged(const sender: iassistiveclientdata); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('dbvaluechanged',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dodbvaluechanged(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fondbvaluechanged)) then begin + fondbvaluechanged(self,sender,b1); + end; + if not b1 and not (ahs_dbchangepending in fstate) then begin + startspeak(); + speaktext(gettexttext(sender),gettextvoice(sender.getassistiveflags())); + end; + end; + resetstate([ahs_dbchangepending]); +end; + +procedure tassistivehandler.docellevent(const sender: iassistiveclientgrid; + const info: celleventinfoty); +var + b1: boolean; + item1: tassistivewidgetitem; + f1: assistiveflagsty; +begin +{$ifdef mse_debugassistive} + debug('cellevent '+ + getenumname(typeinfo(celleventkindty),int32(info.eventkind)),sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.docellevent(self,sender,info,b1); + end; + if not b1 then begin + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,sender,info,b1); + end; + if {not b1 and} twidget(sender.getassistivewidget()).active then begin + with info do begin + case eventkind of + cek_enter: begin + f1:= sender.getassistiveflags(); + if not b1 and ((cellbefore.col <> cell.col) or + (cellbefore.row <> cell.row)) and + not (asf_scrolllimit in f1) then begin + if not (ahs_locatepending in fstate) then begin + startspeak(); + end; + b1:= cellbefore.col <> cell.col; + if b1 and (asf_widgetcell in f1) then begin + if not (aso_textfirst in foptions) then begin + speakgridcell(sender,cell,b1); + end; + fgridintf:= sender; + fnewcol:= b1; + fnewcell:= cell; + setstate([ahs_cellwidgetpending]); + end + else begin + speakgridcell(sender,cell,b1); + end; + end; + resetstate([ahs_locatepending]); + end; + end; + end; + end; + end; +end; + +procedure tassistivehandler.dogridbordertouched( + const sender: iassistiveclientgrid; + const adirection: graphicdirectionty); +var + b1: boolean; + item1: tassistivewidgetitem; + ca1: stockcaptionty; +begin +{$ifdef mse_debugassistive} + debug('gridbordertouched',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dogridbordertouched(self,sender,adirection,b1); + end; + if not b1 then begin + if canevent(tmethod(fongridbordertouched)) then begin + fongridbordertouched(self,sender,adirection,b1); + end; + if not b1 and twidget(sender.getassistivewidget()).active then begin + case adirection of + gd_left: begin + ca1:= sc_firstcol; + end; + gd_up: begin + if asf_db in sender.getassistiveflags then begin + ca1:= sc_bof; + end + else begin + ca1:= sc_firstrow; + end; + end; + gd_right: begin + ca1:= sc_lastcol; + end; + gd_down: begin + if asf_db in sender.getassistiveflags then begin + ca1:= sc_eof; + end + else begin + ca1:= sc_lastrow; + end; + end; + else begin + exit; + end; + end; + startspeak(); + speaktext(ca1,fvoicefixed); + end; + end; +end; + +procedure tassistivehandler.doeditcharenter(const sender: iassistiveclientedit; + const achar: msestring); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('editcharenter',sender); +{$endif} + setstate([ahs_editcharenter]); + b1:= false; + if finditem(sender,item1) then begin + item1.doeditcharenter(self,sender,achar,b1); + end; + if not b1 then begin + if canevent(tmethod(foneditcharenter)) then begin + foneditcharenter(self,sender,achar,b1); + end; + if not b1 then begin + if not (ahs_textblock1 in fstate) then begin + startspeak(); + end + else begin +// if not(aso_textfirst in foptions) then begin +// speaktext(sc_input,fvoicefixed); +// end; + end; + if length(achar) = 1 then begin + speakcharacter(getucs4char(achar,1),fvoicetextedit); + end + else begin + speaktext(achar,fvoicetextedit); + end; +// if (aso_textfirst in foptions) and (ahs_textblock1 in fstate) then begin +// speaktext(sc_input,fvoicefixed); +// end; + exclude(fstate,ahs_textblock1); + end; + end; + checklocatepending(sender); +end; + +procedure tassistivehandler.doeditchardelete(const sender: iassistiveclientedit; + const achar: msestring); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('editchardelete',sender); +{$endif} + setstate([ahs_textblock,ahs_editchardelete]); + b1:= false; + if finditem(sender,item1) then begin + item1.dochange(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonchange)) then begin + fonchange(self,sender,b1); + end; + end; + if not b1 then begin + startspeak(); + if not(aso_textfirst in foptions) then begin + speaktext(sc_deleted,fvoicefixed); + end; + if length(achar) = 1 then begin + speakcharacter(getucs4char(achar,1),fvoicetextedit); + end + else begin + speaktext(achar,fvoicetextedit); + end; + if aso_textfirst in foptions then begin + speaktext(sc_deleted,fvoicefixed); + end; + end; + checklocatepending(sender); +end; + +procedure tassistivehandler.doeditindexmoved(const sender: iassistiveclientedit; + const aindex: int32); +var + b1: boolean; + item1: tassistivewidgetitem; + s1: msestring; + i1: int32; + f1: assistiveflagsty; +begin +{$ifdef mse_debugassistive} + debug('editindexmoved',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.doeditindexmoved(self,sender,aindex,b1); + end; + if not b1 then begin + if canevent(tmethod(foneditindexmoved)) then begin + foneditindexmoved(self,sender,aindex,b1); + end; + if not b1 then begin + if not (ahs_textblock in fstate) then begin + startspeak(); + end; + s1:= sender.getassistivetext(); + f1:= sender.getassistiveflags(); + i1:= gettextvoice(f1); + if aindex < length(s1) then begin + if aindex = 0 then begin + speaktext(sc_beginoftext,fvoicefixed); + end; + speakcharacter(getucs4char(s1,aindex+1),i1); + end + else begin + speaktext(sc_endoftext,fvoicefixed); + end; + end; + end; + exclude(fstate,ahs_textblock); +end; + +procedure tassistivehandler.doeditwithdrawn(const sender: iassistiveclientedit); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('editwithdrawn',sender); +{$endif} + include(fstate,ahs_textblock); + b1:= false; + if finditem(sender,item1) then begin + item1.doeditwithdrawn(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(foneditwithdrawn)) then begin + foneditwithdrawn(self,sender,b1); + end; + if not b1 then begin + startspeak(); + if not(aso_textfirst in foptions) then begin + speaktext(sc_withdrawn,fvoicefixed); + end; + speaktext(sender.getassistivetext(), + gettextvoice(sender.getassistiveflags())); + if aso_textfirst in foptions then begin + speaktext(sc_withdrawn,fvoicefixed); + end; + end; + end; +end; + +procedure tassistivehandler.doedittextblock(const sender: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring); +var + b1: boolean; + item1: tassistivewidgetitem; + sc1: stockcaptionty; + f1: assistiveflagsty; + i1: int32; +begin +{$ifdef mse_debugassistive} + debug('edittextblock',sender); +{$endif} + fstate:= fstate + [ahs_textblock,ahs_textblock1]; + b1:= false; + if finditem(sender,item1) then begin + item1.doedittextblock(self,sender,amode,atext,b1); + end; + if not b1 then begin + if canevent(tmethod(fonedittextblock)) then begin + fonedittextblock(self,sender,amode,atext,b1); + end; + if not b1 then begin + case amode of + etbm_delete: begin + sc1:= sc_deleted; + end; + etbm_cut: begin + sc1:= sc_cut; + end; + etbm_copy: begin + sc1:= sc_copied; + end; + etbm_insert: begin + sc1:= sc_inserted; + end; + etbm_paste: begin + sc1:= sc_pasted; + end; + else begin + exit; + end; + end; + startspeak(); + f1:= sender.getassistiveflags(); + if not(aso_textfirst in foptions) then begin + speaktext(sc1,fvoicefixed); + end; + i1:= gettextvoice(f1); + speaktext(atext,i1); + if aso_textfirst in foptions then begin + speaktext(sc1,fvoicefixed); + end; + end; + end; +end; + +procedure tassistivehandler.doeditinputmodeset( + const sender: iassistiveclientedit; const amode: editinputmodety); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('editinputmodeset',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.doeditinputmodeset(self,sender,amode,b1); + end; + if not b1 then begin + if canevent(tmethod(foneditinputmodeset)) then begin + foneditinputmodeset(self,sender,amode,b1); + end; + if not b1 then begin + startspeak(); + if not(aso_textfirst in foptions) then begin + speaktext(sc_inputmode,fvoicefixed); + end; + case amode of + eim_insert: begin + speaktext(sc_insert,fvoicetexteditreadonly); + end; + eim_overwrite: begin + speaktext(sc_overwrite,fvoicetexteditreadonly); + end; + end; + if aso_textfirst in foptions then begin + speaktext(sc_inputmode,fvoicefixed); + end; + end; + end; +end; + +procedure tassistivehandler.donavigbordertouched(const sender: iassistiveclient; + const adirection: graphicdirectionty); +var + b1: boolean; + item1: tassistivewidgetitem; + ca1: stockcaptionty; +begin +{$ifdef mse_debugassistive} + debug('navigbordertouched',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.donavigbordertouched(self,sender,adirection,b1); + end; + if not b1 then begin + if canevent(tmethod(fonnavigbordertouched)) then begin + fonnavigbordertouched(self,sender,adirection,b1); + end; + if not b1 then begin + case adirection of + gd_left: begin + ca1:= sc_leftborder; + end; + gd_up: begin + ca1:= sc_topborder; + end; + gd_right: begin + ca1:= sc_rightborder; + end; + gd_down: begin + ca1:= sc_bottomborder; + end; + else begin + exit; + end; + end; + startspeak(); + speaktext(ca1,fvoicefixed); + end; + end; +end; + +procedure tassistivehandler.dotabordertouched(const sender: iassistiveclient; + const adown: boolean); +var + b1: boolean; + item1: tassistivewidgetitem; + ca1: stockcaptionty; +begin +{$ifdef mse_debugassistive} + debug('tabordertouched',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dotabordertouched(self,sender,adown,b1); + end; + if not b1 then begin + if canevent(tmethod(fonnavigbordertouched)) then begin + fontabordertouched(self,sender,adown,b1); + end; + if not b1 then begin + if adown then begin + ca1:= sc_firstfield; + end + else begin + ca1:= sc_lastfield; + end; + startspeak(); + speaktext(ca1,fvoicefixed); + end; + end; +end; + +procedure tassistivehandler.doitementer(const sender: iassistiveclient; + const items: shapeinfoarty; const aindex: integer); +var + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('shapeitementer',sender); +{$endif} + b1:= false; + if canevent(tmethod(fonitementer)) then begin + fonitementer(self,sender,items,aindex,b1); + end; + if not b1 then begin + //todo + end; +end; + +procedure tassistivehandler.speakallmenu(const sender: iassistiveclientmenu; + const ahint: boolean); +begin + startspeak(); + speakmenustart(sender); + speaktext(getcaptiontext(sender.getassistiveselfcaption()),fvoicecaption); + speaktext(getcaptiontext(sender.getassistivecaption()),fvoicetext); + if ahint then begin + speaktext(sender.getassistivehint(),fvoicecaption); + end; +end; + +procedure tassistivehandler.domenuactivated(const sender: iassistiveclientmenu); +var + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('menuactivated',sender); +{$endif} + setstate([ahs_menuactivated]); + b1:= false; + if canevent(tmethod(fonmenuactivated)) then begin + fonmenuactivated(self,sender,b1); + end; + if not b1 then begin + speakallmenu(sender,false); + end; +end; + +procedure tassistivehandler.doitementer(const sender: iassistiveclientmenu; + const items: menucellinfoarty; const aindex: integer); +var + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('menuitementer',sender); +{$endif} + b1:= false; + if canevent(tmethod(fonmenuitementer)) then begin + fonmenuitementer(self,sender,items,aindex,b1); + end; + if not b1 then begin + if not (ahs_menuactivated in fstate) then begin + startspeak(); + speaktext(getcaptiontext(iassistiveclient(sender)),fvoicetext); + end; + end; + resetstate([ahs_menuactivated]); +end; + +procedure tassistivehandler.dodatasetevent(const sender: iassistiveclient; + const akind: assistivedbeventkindty; const adataset: pointer); +var + b1: boolean; + item1: tassistivewidgetitem; + sc1: stockcaptionty; +begin +{$ifdef mse_debugassistive} + debug('datasetevent',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dodatasetevent(self,sender,akind,tdataset(adataset),b1); + end; + if not b1 then begin + if canevent(tmethod(fondatasetevent)) then begin + fondatasetevent(self,sender,akind,tdataset(adataset),b1); + end; + if not b1 then begin + case akind of + adek_bof: begin + sc1:= sc_bof; + end; + adek_eof: begin + sc1:= sc_eof; + end; + else begin + sc1:= sc_none; + end; + end; + if sc1 <> sc_none then begin + startspeak(); + speaktext(sc1,fvoicefixed); + end; + end; + end; +end; + +procedure tassistivehandler.dostatread(const reader: tstatreader); +begin + if reader.canstate then begin + with fspeaker do begin + if aso_savelanguage in foptions then begin + language:= reader.readmsestring('language',language); + end; + if aso_savegender in foptions then begin + gender:= genderty(reader.readinteger('gender',ord(gender),ord(low(gender)), + ord(high(gender)))); + end; + if aso_saveage in foptions then begin + age:= reader.readinteger('age',age,0,100); + end; + if aso_savevolume in foptions then begin + volume:= reader.readreal('volume',volume,0,2); + end; + if aso_saverate in foptions then begin + rate:= reader.readreal('rate',rate,0.1,10); + end; + if aso_savepitch in foptions then begin + pitch:= reader.readreal('pitch',pitch,0.2,5); + end; + if aso_saverange in foptions then begin + range:= reader.readreal('range',pitch,0.2,5); + end; + if aso_savecapitals in foptions then begin + capitals:= reader.readinteger('capitals',capitals,0,300); + end; + if aso_savewordgap in foptions then begin + wordgap:= reader.readinteger('wordgap',wordgap,0,100); + end; + end; + end; +end; + +procedure tassistivehandler.dostatwrite(const writer: tstatwriter); +begin + if writer.canstate then begin + with fspeaker do begin + if aso_savelanguage in foptions then begin + writer.writemsestring('language',msestring(language)); + end; + if aso_savegender in foptions then begin + writer.writeinteger('gender',ord(gender)); + end; + if aso_saveage in foptions then begin + writer.writeinteger('age',age); + end; + if aso_savevolume in foptions then begin + writer.writereal('volume',volume); + end; + if aso_saverate in foptions then begin + writer.writereal('rate',rate); + end; + if aso_savepitch in foptions then begin + writer.writereal('pitch',pitch); + end; + if aso_saverange in foptions then begin + writer.writereal('range',pitch); + end; + if aso_savecapitals in foptions then begin + writer.writeinteger('capitals',capitals); + end; + if aso_savewordgap in foptions then begin + writer.writeinteger('wordgap',wordgap); + end; + end; + end; +end; + +procedure tassistivehandler.statreading(); +begin + //dummy +end; + +procedure tassistivehandler.statread(); +begin + //dummy +end; + +function tassistivehandler.getstatvarname(): msestring; +begin + result:= fstatvarname; +end; + +function tassistivehandler.getstatpriority(): integer; +begin + result:= fstatpriority; +end; + +end. diff --git a/mseide-msegui/lib/common/audio/mseaudio.pas b/mseide-msegui/lib/common/audio/mseaudio.pas new file mode 100644 index 0000000..4386c74 --- /dev/null +++ b/mseide-msegui/lib/common/audio/mseaudio.pas @@ -0,0 +1,357 @@ +{ MSEgui Copyright (c) 2010-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseaudio; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses,msethread,msetypes,msepulseglob,msepulsesimple, + msesys,msestrings; + +type + + sampleformatty = (sfm_u8,sfm_8alaw,sfm_8ulaw, + sfm_s16,sfm_s24,sfm_s32,sfm_f32,smf_s2432, + sfm_s16le,sfm_s24le,sfm_s32le,sfm_f32le,smf_s2432le, + sfm_s16be,sfm_s24be,sfm_s32be,sfm_f32be,smf_s2432be); +const + defaultsampleformat = sfm_s16; + defaultsamplechannels = 1; + defaultsamplerate = 44100; + defaultlatency = 0.1; + +{$ifdef endian_little} + pulsesampleformatmatrix: array[sampleformatty] of pa_sample_format_t = + //sfm_u8, sfm_8alaw, sfm_8ulaw, + (PA_SAMPLE_U8,PA_SAMPLE_ALAW,PA_SAMPLE_ULAW, + //sfm_s16, sfm_s24, sfm_s32, + PA_SAMPLE_S16LE,PA_SAMPLE_S24LE,PA_SAMPLE_S32LE, + //sfm_f32, smf_s2432, + PA_SAMPLE_FLOAT32LE,PA_SAMPLE_S24_32LE, + //sfm_s16le, sfm_s24le, sfm_s32le, + PA_SAMPLE_S16LE,PA_SAMPLE_S24LE,PA_SAMPLE_S32LE, + //sfm_f32le, smf_s2432le, + PA_SAMPLE_FLOAT32LE,PA_SAMPLE_S24_32LE, + //sfm_s16be, sfm_s24be, sfm_s32be, + PA_SAMPLE_S16BE,PA_SAMPLE_S24BE,PA_SAMPLE_S32BE, + //sfm_f32be, smf_s2432be); + PA_SAMPLE_FLOAT32BE,PA_SAMPLE_S24_32BE); +{$else} + pulsesampleformatmatrix: array[sampleformatty] of pa_sample_format_t = + //sfm_u8, sfm_8alaw, sfm_8ulaw, + (PA_SAMPLE_U8,PA_SAMPLE_ALAW,PA_SAMPLE_ULAW, + //sfm_s16, sfm_s24, sfm_s32, + PA_SAMPLE_S16BE,PA_SAMPLE_S24BE,PA_SAMPLE_S32BE, + //sfm_f32, smf_s2432, + PA_SAMPLE_FLOAT32BE,PA_SAMPLE_S24_32BE, + //sfm_s16le, sfm_s24le, sfm_s32le, + PA_SAMPLE_S16LE,PA_SAMPLE_S24LE,PA_SAMPLE_S32LE, + //sfm_f32le, smf_s2432le, + PA_SAMPLE_FLOAT32LE,PA_SAMPLE_S24_32LE, + //sfm_s16be, sfm_s24be, sfm_s32be, + PA_SAMPLE_S16BE,PA_SAMPLE_S24BE,PA_SAMPLE_S32BE, + //sfm_f32be, smf_s2432be); + PA_SAMPLE_FLOAT32BE,PA_SAMPLE_S24_32BE); +{$endif} + + samplesizematrix: array[sampleformatty] of integer = + //sfm_u8, sfm_8alaw, sfm_8ulaw, + (1, 1, 1, + //sfm_s16, sfm_s24, sfm_s32, + 2, 1, 4, + //sfm_f32, smf_s2432, + 4, 4, + //sfm_s16le, sfm_s24le, sfm_s32le, + 2, 1, 4, + //sfm_f32le, smf_s2432le, + 4, 4, + //sfm_s16be, sfm_s24be, sfm_s32be, + 2, 1, 4, + //sfm_f32be, smf_s2432be); + 4, 4); + + samplebuffersizematrix: array[sampleformatty] of integer = + //sfm_u8, sfm_8alaw, sfm_8ulaw, + (1, 1, 1, + //sfm_s16, sfm_s24, sfm_s32, + 2, 3, 4, + //sfm_f32, smf_s2432, + 4, 4, + //sfm_s16le, sfm_s24le, sfm_s32le, + 2, 3, 4, + //sfm_f32le, smf_s2432le, + 4, 4, + //sfm_s16be, sfm_s24be, sfm_s32be, + 2, 3, 4, + //sfm_f32be, smf_s2432be); + 4, 4); + +type + + toutstreamthread = class(tmsethread) + end; + + sendeventty = procedure(var data: pointer) of object; + //data = + //bytearty (sfm_u8,sfm_8alaw,sfm_8ulaw, + // sfm_s24,sfm_s24le,sfm_s24be) + //smallintarty (sfm_s16,sfm_s16le,sfm_s16be) + //integerarty (sfm_s32,smf_s2432,sfm_s32le,smf_s2432le, + // sfm_s32be,smf_s2432be) + //or singlearty (sfm_f32,sfm_f32le,sfm_f32be) + + erroreventty = procedure(const sender: tobject; const errorcode: integer; + const errortext: msestring) of object; + + tcustomaudioout = class(tmsecomponent) + private + fthread: toutstreamthread; + fstacksizekb: integer; + fonsend: sendeventty; + fonerror: erroreventty; + fserver: msestring; + fdev: msestring; + fchannels: integer; + frate: integer; + flatency: real; + procedure setactive(const avalue: boolean); + protected + factive: boolean; + fformat: sampleformatty; + fappname: msestring; + fstreamname: msestring; + fpulsestream: ppa_simple; + procedure initnames; virtual; + procedure loaded; override; + procedure run; virtual; + procedure stop; virtual; + function threadproc(sender: tmsethread): integer; virtual; + procedure raiseerror(const aerror: integer); + procedure doerror(const aerror: integer); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; +// function lock: boolean; +// procedure unlock; + procedure flush(); + procedure drain(); + + property active: boolean read factive write setactive default false; + property server: msestring read fserver write fserver; + property dev: msestring read fdev write fdev; + property appname: msestring read fappname write fappname; + property streamname: msestring read fstreamname write fstreamname; + property channels: integer read fchannels write fchannels + default defaultsamplechannels; + property format: sampleformatty read fformat write fformat + default defaultsampleformat; + property rate: integer read frate write frate default defaultsamplerate; + property stacksizekb: integer read fstacksizekb write fstacksizekb default 0; + property latency: real read flatency write flatency; + //seconds, 0 -> server default + property onsend: sendeventty read fonsend write fonsend; + property onerror: erroreventty read fonerror write fonerror; + end; + + taudioout = class(tcustomaudioout) + published + property active; + property server; + property dev; + property appname; + property streamname; + property channels; + property format; + property rate; + property latency; + property stacksizekb; + property onsend; + property onerror; + end; + +implementation +uses + sysutils,msesysintf,mseapplication,msepulse; + +{ tcustomaudioout } + +constructor tcustomaudioout.create(aowner: tcomponent); +begin +// syserror(sys_mutexcreate(fmutex),self); + fchannels:= defaultsamplechannels; + fformat:= defaultsampleformat; + frate:= defaultsamplerate; + flatency:= defaultlatency; + inherited; +end; + +destructor tcustomaudioout.destroy; +begin + active:= false; + inherited; +// sys_mutexdestroy(fmutex); +end; + +procedure tcustomaudioout.flush(); +begin + if fpulsestream <> nil then begin + pa_simple_flush(fpulsestream,nil); + end; +end; + +procedure tcustomaudioout.drain(); +begin + if fpulsestream <> nil then begin + pa_simple_drain(fpulsestream,nil); + end; +end; + +procedure tcustomaudioout.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + if componentstate * [csloading,csdesigning] = [] then begin + if not avalue then begin + stop; + end + else begin + run; + end; + end + else begin + factive:= avalue; + end; + end; +end; + +procedure tcustomaudioout.stop; +begin + if fthread <> nil then begin + fthread.terminate; + application.waitforthread(fthread); + freeandnil(fthread); + pa_simple_free(fpulsestream); + releasepulsesimple; + end; + factive:= false; +end; + +procedure tcustomaudioout.run; +var + ss: pa_sample_spec; + int1: integer; + buattr: pa_buffer_attr; +begin + initializepulsesimple([]); + fillchar(ss,sizeof(ss),0); + fillchar(buattr,sizeof(buattr),0); + with buattr do begin + maxlength:= longword(-1); + tlength:= longword(-1); + prebuf:= longword(-1); + minreq:= longword(-1); + fragsize:= longword(-1); + end; + if flatency > 0 then begin + int1:= round(flatency*frate*samplebuffersizematrix[fformat]*fchannels); + buattr.tlength:= int1; + end; + ss.format:= pulsesampleformatmatrix[fformat]; + ss.rate:= frate; + ss.channels:= fchannels; + fpulsestream:= pa_simple_new(pointer(string(fserver)), + pointer(string(fappname)), + pa_stream_playback,pointer(string(fdev)), + pointer(string(fstreamname)), + @ss,nil,@buattr,@int1); + if fpulsestream = nil then begin + raiseerror(int1); + end; + fthread:= toutstreamthread.create({$ifdef FPC}@{$endif}threadproc,false, + fstacksizekb); + factive:= true; +end; + +procedure tcustomaudioout.initnames; +begin + if fappname = '' then begin + fappname:= application.applicationname; + end; + if fstreamname = '' then begin + fstreamname:= msestring(name); + end; +end; + +procedure tcustomaudioout.loaded; +begin + inherited; + if not (csdesigning in componentstate) then begin + initnames; + if factive and (fthread = nil) then begin + run; + end; + end; +end; +{ +function tcustomaudioout.lock: boolean; +begin + result:= sys_mutexlock(fmutex) = sye_ok; +end; + +procedure tcustomaudioout.unlock; +begin + sys_mutexunlock(fmutex); +end; +} +function tcustomaudioout.threadproc(sender: tmsethread): integer; +var + data: pointer; + int1: integer; + datasize: integer; +begin + result:= 0; + if canevent(tmethod(fonsend)) then begin + factive:= true; + datasize:= samplesizematrix[fformat]; + while not sender.terminated do begin + data:= nil; +// lock; +// try + fonsend(data); +// finally +// unlock; +// end; + if data <> nil then begin + if pa_simple_write(fpulsestream,data,length(bytearty(data))*datasize, + @int1) <> 0 then begin + doerror(int1); + break; + end; + end; + end; + end; +end; + +procedure tcustomaudioout.raiseerror(const aerror: integer); +begin + raise exception.create(pa_strerror(aerror)); +end; + +procedure tcustomaudioout.doerror(const aerror: integer); +begin + application.lock; + try + if canevent(tmethod(fonerror)) then begin + fonerror(self,aerror,pa_strerror(aerror)); + end; + finally + application.unlock; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/audio/mseespeakng.pas b/mseide-msegui/lib/common/audio/mseespeakng.pas new file mode 100644 index 0000000..3ac3893 --- /dev/null +++ b/mseide-msegui/lib/common/audio/mseespeakng.pas @@ -0,0 +1,465 @@ +{/* eSpeak NG API. + * + * Copyright (C) 2015-2017 Reece H. Dunn + * + * 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 3 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, see . + */} + +unit mseespeakng; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msectypes,msetypes,sysutils,msestrings; + {$packrecords c} + +const +{$ifdef mswindows} +// {$define wincall} + espeaknglib: array[0..0] of filenamety = ( + 'libespeak-ngwo.dll'); +{$else} + espeaknglib: array[0..1] of filenamety = + ('libespeak-ngsync.so.1','libespeak-ngsync.so'); +{$endif} + + ENS_GROUP_MASK = $70000000; + ENS_GROUP_ERRNO = $00000000; //* Values 0-255 map to errno error codes. */ + ENS_GROUP_ESPEAK_NG = $10000000; //* eSpeak NG error codes. */ + +//* eSpeak NG 1.49.0 */ + ENS_OK = 0; + ENS_COMPILE_ERROR = $100001FF; + ENS_VERSION_MISMATCH = $100002FF; + ENS_FIFO_BUFFER_FULL = $100003FF; + ENS_NOT_INITIALIZED = $100004FF; + ENS_AUDIO_ERROR = $100005FF; + ENS_VOICE_NOT_FOUND = $100006FF; + ENS_MBROLA_NOT_FOUND = $100007FF; + ENS_MBROLA_VOICE_NOT_FOUND = $100008FF; + ENS_EVENT_BUFFER_FULL = $100009FF; + ENS_NOT_SUPPORTED = $10000AFF; + ENS_UNSUPPORTED_PHON_FORMAT = $10000BFF; + ENS_NO_SPECT_FRAMES = $10000CFF; + ENS_EMPTY_PHONEME_MANIFEST = $10000DFF; + ENS_SPEECH_STOPPED = $10000EFF; + +//* eSpeak NG 1.49.2 */ + ENS_UNKNOWN_PHONEME_FEATURE = $10000FFF; + ENS_UNKNOWN_TEXT_ENCODING = $100010FF; + + espeakCHARS_AUTO = 0; + espeakCHARS_UTF8 = 1; + espeakCHARS_8BIT = 2; + espeakCHARS_WCHAR = 3; + espeakCHARS_16BIT = 4; + espeakSSML = $10; + espeakPHONEMES = $100; + espeakENDPAUSE = $1000; + espeakKEEP_NAMEDATA = $2000; + + ENOUTPUT_MODE_SYNCHRONOUS = $0001; + ENOUTPUT_MODE_SPEAK_AUDIO = $0002; + +// values for 'value' in espeak_SetParameter(espeakRATE, value, 0), nominally in words-per-minute + espeakRATE_MINIMUM = 80; + espeakRATE_MAXIMUM = 450; + espeakRATE_NORMAL = 175; + +type + espeak_ng_OUTPUT_MODE = cint32; + + espeak_PARAMETER = ( + espeakSILENCE=0, //* internal use */ + espeakRATE=1, + espeakVOLUME=2, + espeakPITCH=3, + espeakRANGE=4, + espeakPUNCTUATION=5, + espeakCAPITALS=6, + espeakWORDGAP=7, + espeakOPTIONS=8, // reserved for misc. options. not yet used + espeakINTONATION=9, + + espeakRESERVED1=10, + espeakRESERVED2=11, + espeakEMPHASIS, //* internal use */ + espeakLINELENGTH, //* internal use */ + espeakVOICETYPE, // internal, 1=mbrola + N_SPEECH_PARAM //* last enum */ + ); + + espeak_POSITION_TYPE = ( + POS_CHARACTER = 1, + POS_WORD, + POS_SENTENCE + ); + + espeak_VOICE = record + name: pcchar; // a given name for this voice. UTF8 string. + languages: pcchar; // list of pairs of (byte) priority + + //(string) language (and dialect qualifier) + identifier: pcchar; // the filename for this voice within + //espeak-ng-data/voices + gender: cuchar; // 0=none 1=male, 2=female, + age: cuchar; // 0=not specified, or age in years + variant: cuchar; // only used when passed as a parameter to + //espeak_SetVoiceByProperties + xx1: cuchar; // for internal use + score: cint; // for internal use + spare: pointer; // for internal use + end; + pespeak_VOICE = ^ espeak_VOICE; + + + espeak_ng_STATUS = cuint; + { + espeak_ng_OUTPUT_MODE = ( + ENOUTPUT_MODE_SYNCHRONOUS = $0001, + ENOUTPUT_MODE_SPEAK_AUDIO = $0002 + ); +} + espeak_ng_CONTEXT_TYPE = ( + ERROR_CONTEXT_FILE, + ERROR_CONTEXT_VERSION + ); + + espeak_ng_ERROR_CONTEXT_ = record + _type: espeak_ng_CONTEXT_TYPE; + name: pchar; + version: cint; + expected_version: cint; + end; + espeak_ng_ERROR_CONTEXT = ^espeak_ng_ERROR_CONTEXT_; + + tespeakerror = class(exception) + public + constructor create(const err: espeak_ng_STATUS; const atext: string=''); + end; + +var + espeak_ng_ClearErrorContext: + procedure(context: espeak_ng_ERROR_CONTEXT) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_GetStatusCodeMessage: + procedure(status: espeak_ng_STATUS; buffer: pcchar; length: size_t) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ +ESPEAK_NG_API void +espeak_ng_PrintStatusCodeMessage(espeak_ng_STATUS status, + FILE *out, + espeak_ng_ERROR_CONTEXT context); +} + espeak_ng_InitializePath: + procedure(path: pcchar){$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_Initialize: + function(context: espeak_ng_ERROR_CONTEXT): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_InitializeOutput: + function(output_mode: espeak_ng_OUTPUT_MODE; buffer_length: cint; + device: pcchar): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_GetSampleRate: + function(): cint {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + espeak_ng_SetParameter: + function(parameter: espeak_PARAMETER; value: cint; + relative: cint): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{from espeak_SetParameter(): +/* Sets the value of the specified parameter. + relative=0 Sets the absolute value of the parameter. + relative=1 Sets a relative value of the parameter. + + parameter: + espeakRATE: speaking speed in word per minute. Values 80 to 450. + + espeakVOLUME: volume in range 0-200 or more. + 0=silence, 100=normal full volume, greater values may produce amplitude compression or distortion + + espeakPITCH: base pitch, range 0-100. 50=normal + + espeakRANGE: pitch range, range 0-100. 0-monotone, 50=normal + + espeakPUNCTUATION: which punctuation characters to announce: + value in espeak_PUNCT_TYPE (none, all, some), + see espeak_GetParameter() to specify which characters are announced. + + espeakCAPITALS: announce capital letters by: + 0=none, + 1=sound icon, + 2=spelling, + 3 or higher, by raising pitch. This values gives the amount in Hz by which the pitch + of a word raised to indicate it has a capital letter. + + espeakWORDGAP: pause between words, units of 10mS (at the default speed) + + Return: EE_OK: operation achieved + EE_BUFFER_FULL: the command can not be buffered; + you may try after a while to call the function again. + EE_INTERNAL_ERROR. +*/} + espeak_ng_SetPunctuationList: + function(punctlist: pwchar_t): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_SetVoiceByName: + function(name: pcchar): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_SetVoiceByProperties: + function(voice_selector: pespeak_VOICE): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_GetCurrentVoice: function(): pespeak_VOICE + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{/* Returns the espeak_VOICE data for the currently selected voice. + This is not affected by temporary voice changes caused by + SSML elements such as and +*/} + + espeak_ng_Synthesize: + function(text: pointer; size: size_t; + position: cuint; + position_type: espeak_POSITION_TYPE; + end_position: cuint; + flags: cuint; + unique_identifier: pcuint; + user_data: pointer): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{from espeak_Synthesize(): +/* Synthesize speech for the specified text. + The speech sound data is passed to the calling + program in buffers by means of the callback function specified by + espeak_SetSynthCallback(). The command is asynchronous: + it is internally buffered and returns as soon as possible. + If espeak_Initialize was previously called with AUDIO_OUTPUT_PLAYBACK + as argument, the sound data are played by eSpeak. + +text: The text to be spoken, terminated by a zero character. + It may be either 8-bit characters, + wide characters (wchar_t), or UTF8 encoding. Which of these is determined + by the "flags" parameter. + +size: Equal to (or greatrer than) the size of the text data, in bytes. + This is used in order + to allocate internal storage space for the text. This value is not used for + AUDIO_OUTPUT_SYNCHRONOUS mode. + +position: The position in the text where speaking starts. Zero indicates + speak from the + start of the text. + +position_type: Determines whether "position" is a number of characters, words, + or sentences. + Values: + +end_position: If set, this gives a character position at which speaking + will stop. A value of zero indicates no end position. + +flags: These may be OR'd together: + Type of character codes, one of: + espeakCHARS_UTF8 UTF8 encoding + espeakCHARS_8BIT The 8 bit ISO-8859 character set for + the particular language. + espeakCHARS_AUTO 8 bit or UTF8 (this is the default) + espeakCHARS_WCHAR Wide characters (wchar_t) + espeakCHARS_16BIT 16 bit characters. + + espeakSSML Elements within < > are treated as SSML elements, + or if not recognised are ignored. + + espeakPHONEMES Text within [[ ]] is treated as phonemes codes + (in espeak's Hirshenbaum encoding). + + espeakENDPAUSE If set then a sentence pause is added at the end of the + text. If not set then this pause is suppressed. + +unique_identifier: This must be either NULL, or point to an integer variable to + which eSpeak writes a message identifier number. + eSpeak includes this number in espeak_EVENT messages which are the result of + this call of espeak_Synth(). + +user_data: a pointer (or NULL) which will be passed to the callback function in + espeak_EVENT messages. + +Return: EE_OK: operation achieved + EE_BUFFER_FULL: the command can not be buffered; + you may try after a while to call the function again. + EE_INTERNAL_ERROR. +} + espeak_ng_SynthesizeMark: + function(text: pointer; size: size_t; + index_mark: pcchar; + end_position: cuint; + flags: cuint; + unique_identifier: pcuint; + user_data: pointer): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{from espeak_SynthesizeMark(): +/* Synthesize speech for the specified text. + Similar to espeak_Synth() but the start position is + specified by the name of a element in the text. + + index_mark: The "name" attribute of a element within the + text which specified the point at which synthesis starts. UTF8 string. + + For the other parameters, see espeak_Synth() + + Return: EE_OK: operation achieved + EE_BUFFER_FULL: the command can not be buffered; + you may try after a while to call the function again. + EE_INTERNAL_ERROR. +*/ +} + espeak_ng_SpeakKeyName: + function(key_name: pchar): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_SpeakCharacter: + function(character: wchar_t): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_IsPlaying: + function(): cint {$ifdef wincall}stdcall{$else}cdecl{$endif}; + //* Returns 1 if audio is played, 0 otherwise. + + espeak_ng_Cancel: + function(): espeak_ng_STATUS {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_SetCancelState: + function(canceled: cint): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_Synchronize: + function(): espeak_ng_STATUS {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_Terminate: + function(): espeak_ng_STATUS {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_CompileDictionary(const char *dsource, + const char *dict_name, + FILE *log, + int flags, + espeak_ng_ERROR_CONTEXT *context); + +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_CompileMbrolaVoice(const char *path, + FILE *log, + espeak_ng_ERROR_CONTEXT *context); + +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_CompilePhonemeData(long rate, + FILE *log, + espeak_ng_ERROR_CONTEXT *context); + +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_CompileIntonation(FILE *log, + espeak_ng_ERROR_CONTEXT *context); + +/* eSpeak NG 1.49.1 */ + +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_CompilePhonemeDataPath(long rate, + const char *source_path, + const char *destination_path, + FILE *log, + espeak_ng_ERROR_CONTEXT *context); +} + +function espeakngerrormessage(const err: espeak_ng_STATUS): string; + +procedure initializeespeakng(const sonames: array of filenamety; + const espeakdatapath: string = ''); //[],'' = default +procedure releaseespeakng(); + +implementation +uses + msedynload; +var + libinfo: dynlibinfoty; + err: espeak_ng_ERROR_CONTEXT_; + +function espeakngerrormessage(const err: espeak_ng_STATUS): string; +var + buf: array[0..500] of char; +begin + espeak_ng_GetStatusCodeMessage(err,@buf,sizeof(buf)); + result:= string(pchar(@buf)) +end; + +procedure checkerror(const astate: espeak_ng_status; const atext: string); +begin + if astate <> 0 then begin + raise tespeakerror.create(astate,atext); + end; +end; + +procedure ini(const data: pointer); +begin + espeak_ng_InitializePath(data); + checkerror(espeak_ng_Initialize(@err), + lineend+'espeak-ng-data directory not found'+lineend+ + string(pchar(data))); +end; + +procedure fini(const data: pointer); +begin + espeak_ng_terminate(); +end; + +procedure initializeespeakng(const sonames: array of filenamety; + const espeakdatapath: string = ''); + +const + funcs: array[0..19] of funcinfoty = ( + (n: 'espeak_ng_ClearErrorContext'; d: @espeak_ng_ClearErrorContext), + (n: 'espeak_ng_GetStatusCodeMessage'; d: @espeak_ng_GetStatusCodeMessage), + (n: 'espeak_ng_InitializePath'; d: @ espeak_ng_InitializePath), + (n: 'espeak_ng_Initialize'; d: @espeak_ng_Initialize), + (n: 'espeak_ng_InitializeOutput'; d: @espeak_ng_InitializeOutput), + (n: 'espeak_ng_GetSampleRate'; d: @espeak_ng_GetSampleRate), + (n: 'espeak_ng_SetParameter'; d: @espeak_ng_SetParameter), + (n: 'espeak_ng_SetPunctuationList'; d: @espeak_ng_SetPunctuationList), + (n: 'espeak_ng_SetVoiceByName'; d: @espeak_ng_SetVoiceByName), + (n: 'espeak_ng_SetVoiceByProperties'; d: @espeak_ng_SetVoiceByProperties), + (n: 'espeak_GetCurrentVoice'; d: @espeak_GetCurrentVoice), + (n: 'espeak_ng_Synthesize'; d: @espeak_ng_Synthesize), + (n: 'espeak_ng_SynthesizeMark'; d: @espeak_ng_SynthesizeMark), + (n: 'espeak_ng_SpeakKeyName'; d: @espeak_ng_SpeakKeyName), + (n: 'espeak_ng_SpeakCharacter'; d: @espeak_ng_SpeakCharacter), + (n: 'espeak_IsPlaying'; d: @espeak_IsPlaying), + (n: 'espeak_ng_Cancel'; d: @espeak_ng_Cancel), + (n: 'espeak_ng_SetCancelState'; d: @espeak_ng_SetCancelState), + (n: 'espeak_ng_Synchronize'; d: @espeak_ng_Synchronize), + (n: 'espeak_ng_Terminate'; d: @espeak_ng_Terminate) + ); + errormessage = 'Can not load eSpeakNG library. '; +begin + if not initializedynlib(libinfo,sonames,espeaknglib,funcs,[], + errormessage,@ini,false,pointer(espeakdatapath)) then begin + espeak_ng_InitializePath(pointer(espeakdatapath)); //ini not called + end;; +end; + +procedure releaseespeakng(); +begin + releasedynlib(libinfo,@fini); +end; + +{ tespeakerror } + +constructor tespeakerror.create(const err: espeak_ng_STATUS; + const atext: string=''); +begin + inherited create('eSpeak error:'+atext+lineend+espeakngerrormessage(err)); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/audio/msemidi.pas b/mseide-msegui/lib/common/audio/msemidi.pas new file mode 100644 index 0000000..be40cfd --- /dev/null +++ b/mseide-msegui/lib/common/audio/msemidi.pas @@ -0,0 +1,833 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msemidi; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msestream,classes,mclasses,mseclasses,sysutils,msestrings,msetimer,msetypes; + +const + defaultmidimaxdatasize = 1000000; +// defaulttimescaleus = 1000000*60/(120*120); + defaulttempo = 120; //beats per minute + defaultticksperbeat = 120; + + mc_endoftrack = 47; + mc_keysig = 89; + mc_timesig = 88; + mc_tempo = 81; + mc_trackname = 3; + mc_instrumentname = 4; + +type + midierrorty = (em_ok,em_nostream,em_fileformat,em_notrack,em_trackdata); + + emidiexception = class(exception); + + midichannelty = (mic_0,mic_1,mic_2,mic_3,mic_4,mic_5,mic_6,mic_7, + mic_8,mic_9,mic_10,mic_11,mic_12,mic_13,mic_14,mic_15); + midichannelsty = set of midichannelty; + + idstringty = array[0..3] of char; + midichunkheaderty = record + id: idstringty; + size: longword; + end; + + midichunkty = record + header: midichunkheaderty; + data: record //variable + end; + end; + + midifileheaderty = record + formattype: word; + numberoftracks: word; + timedivision: word; + end; + + midimessagekindty = (mmk_none,mmk_noteoff,mmk_noteon,mmk_notepressure, + mmk_controller,mmk_programchange,mmk_channelpressure, + mmk_pitchbend,mmk_system); +const + midichannelmessages = [mmk_noteoff,mmk_noteon,mmk_notepressure, + mmk_controller,mmk_programchange,mmk_channelpressure]; +type + midieventinfoty = record + track: integer; + kind: midimessagekindty; + channel: byte; + par1: byte; + par2: byte; + end; + trackeventinfoty = record + delta: longword; + event: midieventinfoty; + end; + ptrackeventinfoty = ^trackeventinfoty; + + tmidistream = class(tbufstream) + private + ftrackcount: integer; + ftimedivision: longword; + ftracksize: longword; + fmetadata: string; + fstatus: byte; + fmaxdatasize: longword; + ftracknum: integer; + protected + function readtrackbyte(out adata: byte): boolean; + function readtrackdatabyte(out adata: byte): boolean; //check bit 7 + function readtrackword(out adata: word): boolean; + function readtracklongword(out adata: word): boolean; + function readtrackdata(out adata; const acount: integer): boolean; overload; + function readtrackvarlength(out adata: longword): boolean; + + function readbyte(out adata: byte): boolean; + function readword(out adata: word): boolean; + function readlongword(out adata: word): boolean; + function readchunkheader(out adata: midichunkheaderty): boolean; + + function checkchunkheader(const aid: idstringty; + const asize: integer): boolean; + function readfileheader(out adata: midifileheaderty): boolean; + function skip(const adist: longword): boolean; + public + constructor create(ahandle: integer); override; + function initfile: boolean; + function starttrack: boolean; + function skiptrack: boolean; + function readtrackdata(out adata: trackeventinfoty): boolean; overload; + function getmetadata(const alen: integer; out avalue: longword): boolean; + property timedivision: longword read ftimedivision; + property metadata: string read fmetadata; + property maxdatasize: longword read fmaxdatasize write fmaxdatasize + default defaultmidimaxdatasize; + end; + + trackeventty = procedure(const sender: tobject; + var ainfo: midieventinfoty) of object; + + midisourcestatety = (mss_inited,mss_tracksloaded,mss_eventsmerged, + mss_endoftrack); + midisourcestatesty = set of midisourcestatety; + +const + loadstates = [mss_inited,mss_tracksloaded,mss_eventsmerged]; +type + trackinfoty = record + disabled: boolean; + trackname: string; + instrumentname: string; + keysig: byte; + tempo: longword; //micro seconds per quarter note + timesig: longword; + channels: midichannelsty; + end; + trackinfoarty = array of trackinfoty; + + trackbufferarty = array of trackeventinfoty; + trackbufferararty = array of trackbufferarty; + + tmidisource = class(tmsecomponent) + private + fstream: tmidistream; + factive: boolean; + fontrackevent: trackeventty; + fstarttime: longword; + feventtime: longword; + ftimer: tsimpletimer; + ftracks: trackinfoarty; + ftrackbuffer: trackbufferararty; + feventbuffer: trackbufferarty; + feventindex: integer; + ftimescale: real; //miditicks to us + ftempo: real; + ftimesum: real; + procedure setstream(const avalue: tmidistream); + procedure setactive(const avalue: boolean); + procedure settempo(const avalue: real); + protected + fstate: midisourcestatesty; + ftrackevent: trackeventinfoty; + function ticksperbeat: integer; + procedure error(const aerror: midierrorty); + procedure clear; + procedure initstream; + procedure mergeevents; + procedure checkdata; + procedure start; + procedure stop; + function checkresult(const aresult: boolean; + const aerror: midierrorty): boolean; {$ifdef FPC}inline;{$endif} + procedure processevent; + procedure dotrackevent; virtual; + procedure dotimer(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure loadtracks; + property active: boolean read factive write setactive; + property stream: tmidistream read fstream write setstream; + //owns the stream + property tracks: trackinfoarty read ftracks; + property tempo: real read ftempo write settempo; //beats per minute + published + property ontrackevent: trackeventty read fontrackevent write fontrackevent; + end; + +const + midimessagetable: array[0..7] of midimessagekindty = ( + mmk_noteoff, //8c + mmk_noteon, //9c + mmk_notepressure, //ac + mmk_controller, //bc + mmk_programchange, //cc + mmk_channelpressure, //dc + mmk_pitchbend, //ec + mmk_system); //fx + + midiparcount: array[midimessagekindty] of integer = ( + // mmk_none,mmk_noteoff,mmk_noteon,mmk_notepressure, + 0, 2, 2, 2, + // mmk_controller,mmk_programchange,mmk_channelpressure, + 2, 1, 1, + // mmk_pitchbend,mmk_system + 2, 0); + +implementation +uses + msesysutils,msedatalist,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + errormessages: array[midierrorty] of msestring = ( + '', + 'No midi stream', + 'No midi file.', + 'No track found.', + 'Invalid track data.' + ); + +function swap(const avalue: word): word; {$ifdef FPC}inline;{$endif} + overload; +begin + result:= (avalue shl 8) or (avalue shr 8); +end; + +procedure swap1(var avalue: word); {$ifdef FPC}inline;{$endif} + overload; +begin + avalue:= (avalue shl 8) or (avalue shr 8); +end; + +function swap(const avalue: longword): longword; {$ifdef FPC}inline;{$endif} + overload; +begin + result:= (swap(word(avalue)) shl 16) or swap(word(avalue shr 16)); +end; + +procedure swap1(var avalue: longword); {$ifdef FPC}inline;{$endif} overload; +begin + avalue:= (swap(word(avalue)) shl 16) or swap(word(avalue shr 16)); +end; + +{ tmidistream } + +constructor tmidistream.create(ahandle: integer); +begin + fmaxdatasize:= defaultmidimaxdatasize; +// ftimescaleus:= defaulttimescaleus; + inherited; +end; + +function tmidistream.readbyte(out adata: byte): boolean; +begin + result:= read(adata,sizeof(adata)) = sizeof(adata); +end; + +function tmidistream.readword(out adata: word): boolean; +begin + result:= read(adata,sizeof(adata)) = sizeof(adata); + swap1(adata); +end; + +function tmidistream.readlongword(out adata: word): boolean; +begin + result:= read(adata,sizeof(adata)) = sizeof(adata); + swap1(adata); +end; + +function tmidistream.readtrackbyte(out adata: byte): boolean; +var + int1: integer; +begin + result:= ftrackcount >= sizeof(adata); + if result then begin + int1:= read(adata,sizeof(adata)); + ftrackcount:= ftrackcount - int1; + result:= int1 = sizeof(adata); + end; +end; + +function tmidistream.readtrackdatabyte(out adata: byte): boolean; +begin + result:= readtrackbyte(adata); + if result and (adata and $80 <> 0) then begin + result:= false; + fstatus:= adata; //try to resync + end; +end; + +function tmidistream.readtrackword(out adata: word): boolean; +var + int1: integer; +begin + result:= ftrackcount >= sizeof(adata); + if result then begin + int1:= read(adata,sizeof(adata)); + ftrackcount:= ftrackcount - int1; + result:= int1 = sizeof(adata); + if result then begin + swap1(adata); + end; + end; +end; + +function tmidistream.readtracklongword(out adata: word): boolean; +var + int1: integer; +begin + result:= ftrackcount >= sizeof(adata); + if result then begin + int1:= read(adata,sizeof(adata)); + ftrackcount:= ftrackcount - int1; + result:= int1 = sizeof(adata); + if result then begin + swap1(adata); + end; + end; +end; + +function tmidistream.readtrackdata(out adata; const acount: integer): boolean; +var + int1: integer; +begin + result:= ftrackcount >= acount; + if result then begin + int1:= read(adata,acount); + ftrackcount:= ftrackcount - int1; + result:= int1 = acount; + end; +end; + +function tmidistream.readchunkheader(out adata: midichunkheaderty): boolean; +begin + result:= read(adata,sizeof(adata)) = sizeof(adata); + swap1(adata.size); +end; + +function tmidistream.checkchunkheader(const aid: idstringty; + const asize: integer): boolean; +var + header1: midichunkheaderty; +begin + result:= readchunkheader(header1) and (header1.size = asize) and + (header1.id = aid); +end; + +function tmidistream.readfileheader(out adata: midifileheaderty): boolean; +begin + result:= checkchunkheader('MThd',6); + if result then begin + result:= read(adata,sizeof(adata)) = sizeof(adata); + if result then begin + with adata do begin + swap1(formattype); + swap1(numberoftracks); + swap1(timedivision); + end; + end; + end; +end; + +function tmidistream.initfile: boolean; +var + header: midifileheaderty; +begin + ftracknum:= -1; + result:= readfileheader(header); + if result then begin + with header do begin + ftrackcount:= numberoftracks; + ftimedivision:= timedivision; + end; + result:= ftimedivision > 0; + end; +end; + +function tmidistream.starttrack: boolean; +var + header: midichunkheaderty; +begin + repeat + result:= readchunkheader(header); + if result then begin + with header do begin + ftracksize:= header.size; + if id = 'MTrk' then begin + ftrackcount:= ftracksize; + inc(ftracknum); + break; + end; + result:= skip(ftracksize); + end; + end; + until not result; +end; + +function tmidistream.skiptrack: boolean; +var + header: midichunkheaderty; +begin + repeat + result:= readchunkheader(header); + if result then begin + with header do begin + ftracksize:= header.size; + if id = 'MTrk' then begin + result:= skip(ftracksize); + inc(ftracknum); + break; + end; + result:= skip(ftracksize); + end; + end; + until not result; +end; + + +function tmidistream.skip(const adist: longword): boolean; +var + lint1: int64; +begin + lint1:= position; + result:= seek(adist,socurrent)-lint1 = adist; +end; + +function tmidistream.readtrackvarlength(out adata: longword): boolean; +var + by1: byte; +begin + result:= true; + adata:= 0; + while result and (ftrackcount > 0) do begin + dec(ftrackcount); + result:= read(by1,1) = 1; + adata:= (adata shl 7) or by1 and $7f; + if by1 and $80 = 0 then begin + break; + end; + end; +end; +{ +function tmidistream.readtrackevent(out adata: trackeventinfoty): boolean; +var + stat1: byte; + lwo1: longword; + rea1: real; +begin + fillchar(adata,sizeof(adata),0); + result:= readtrackvarlength(adata.delta); + if not result then exit; + + if adata.delta <> 0 then begin + ftimesum:= ftimesum + adata.delta*ftimescaleus; + adata.delta:= round(ftimesum); + ftimesum:= ftimesum - adata.delta; + end; + + result:= readtrackbyte(stat1); + if not result then exit; + if (stat1 and $80) <> 0 then begin + fstatus:= stat1; + result:= readtrackdatabyte(adata.event.par1); + if not result then exit; + end + else begin + adata.event.par1:= stat1; + stat1:= fstatus; + end; + adata.event.kind:= messagetable[(stat1 shr 4) and $7]; + if adata.event.kind = mmk_system then begin + result:= readtrackvarlength(lwo1) and (lwo1 <= fmaxdatasize); + if not result then exit; + setlength(fmetadata,lwo1); + if lwo1 > 0 then begin + result:= readtrackdata(pointer(fmetadata)^,lwo1); + end; + end + else begin + adata.event.channel:= stat1 and $0f; + if parcount[adata.event.kind] > 1 then begin + result:= readtrackdatabyte(adata.event.par2); + end; + end; +end; +} +function tmidistream.readtrackdata(out adata: trackeventinfoty): boolean; +var + stat1: byte; + lwo1: longword; +// rea1: real; +begin + fillchar(adata,sizeof(adata),0); + adata.event.track:= ftracknum; + fmetadata:= ''; + result:= readtrackvarlength(adata.delta); + if not result then exit; + result:= readtrackbyte(stat1); + if not result then exit; + if (stat1 and $80) <> 0 then begin + fstatus:= stat1; + result:= readtrackdatabyte(adata.event.par1); + if not result then exit; + end + else begin + adata.event.par1:= stat1; + stat1:= fstatus; + end; + adata.event.kind:= midimessagetable[(stat1 shr 4) and $7]; + if adata.event.kind = mmk_system then begin + result:= readtrackvarlength(lwo1) and (lwo1 <= fmaxdatasize); + if not result then exit; + setlength(fmetadata,lwo1); + if lwo1 > 0 then begin + result:= readtrackdata(pointer(fmetadata)^,lwo1); + end; + end + else begin + adata.event.channel:= stat1 and $0f; + if midiparcount[adata.event.kind] > 1 then begin + result:= readtrackdatabyte(adata.event.par2); + end; + end; +end; + +function tmidistream.getmetadata(const alen: integer; + out avalue: longword): boolean; +var + int1: integer; +begin + result:= length(fmetadata) = alen; + if result then begin + avalue:= 0; + for int1:= 1 to alen do begin + avalue:= (avalue shl 8) or byte(fmetadata[int1]); + end; + end; +end; + +{ tmidisource } + +constructor tmidisource.create(aowner: tcomponent); +begin + tempo:= defaulttempo; + inherited; + ftimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}dotimer,false, + [to_single,to_absolute,to_autostart]); +end; + +destructor tmidisource.destroy; +begin + stream:= nil; + ftimer.free; + inherited; +end; + +function tmidisource.checkresult(const aresult: boolean; + const aerror: midierrorty): boolean; +begin + result:= aresult; + if not aresult then begin + error(aerror); + end; +end; + +procedure tmidisource.clear; +begin + fstate:= fstate - loadstates; + ftracks:= nil; + ftrackbuffer:= nil; + feventbuffer:= nil; + ftempo:= defaulttempo; + feventindex:= 0; + ftimesum:= 0; +end; + +procedure tmidisource.setstream(const avalue: tmidistream); +begin + active:= false; + fstream.free; + fstream:= avalue; + clear; +end; + +procedure tmidisource.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + factive:= avalue; + if avalue then begin + start; + end + else begin + stop; + end; + end; +end; + +procedure tmidisource.error(const aerror: midierrorty); +begin + raise emidiexception.create(self.name+': '+ansistring(errormessages[aerror])); +end; + +procedure tmidisource.dotrackevent; +begin + if assigned(fontrackevent) then begin + fontrackevent(self,ftrackevent.event); + end; +end; + +procedure tmidisource.dotimer(const sender: tobject); +begin + dotrackevent; + processevent; +end; + +procedure tmidisource.processevent; +var + lwo1: longword; +begin + while feventindex <= high(feventbuffer) do begin + ftrackevent:= feventbuffer[feventindex]; + inc(feventindex); + with ftrackevent do begin + if delta = 0 then begin + dotrackevent; + end + else begin + ftimesum:= ftimesum +delta*ftimescale; + lwo1:= round(ftimesum); + ftimesum:= ftimesum - lwo1; + feventtime:= feventtime + lwo1; + ftimer.interval:= feventtime; + break; + end; + end; + end; +end; + +procedure tmidisource.initstream; +begin + if not (mss_inited in fstate) then begin + if fstream = nil then begin + error(em_nostream); + end; + checkresult(fstream.initfile,em_fileformat); + tempo:= tempo; //update timescale + include(fstate,mss_inited); + end; +end; + +procedure tmidisource.loadtracks; +var + int1,int2,int3: integer; + trackdata: trackeventinfoty; +begin + initstream; + if not (mss_tracksloaded in fstate) then begin + setlength(ftracks,fstream.ftrackcount); + setlength(ftrackbuffer,length(ftracks)); + for int1:= 0 to high(ftracks) do begin + checkresult(fstream.starttrack,em_notrack); + with ftracks[int1] do begin + int2:= 0; + while true do begin + checkresult(fstream.readtrackdata(trackdata),em_trackdata); + with trackdata.event do begin + case kind of + mmk_noteoff,mmk_noteon,mmk_notepressure, + mmk_controller,mmk_programchange,mmk_channelpressure, + mmk_pitchbend: begin + int3:= additemindex(ftrackbuffer[int1],typeinfo(trackbufferarty),int2); + ftrackbuffer[int1][int3]:= trackdata; + include(channels,midichannelty(trackdata.event.channel and $0f)); + end; + mmk_system: begin + case par1 of + mc_keysig: begin + keysig:= par2; + end; + mc_tempo: begin + checkresult(fstream.getmetadata(3,tempo),em_trackdata); + end; + mc_timesig: begin + checkresult(fstream.getmetadata(4,timesig),em_trackdata); + end; + mc_trackname: begin + trackname:= fstream.metadata; + end; + mc_instrumentname: begin + instrumentname:= fstream.metadata; + end; + mc_endoftrack: begin + break; + end; + end; + end; + end; + end; + end; + setlength(ftrackbuffer[int1],int2); + end; + end; + if (ftracks <> nil) and (ftracks[0].tempo > 0) then begin + tempo:= 60000000/ftracks[0].tempo; + end; + include(fstate,mss_tracksloaded); + end; +end; + +type + trackmergeinfoty = record + po: ptrackeventinfoty; + time: longword; + end; + trackmergeinfoarty = array of trackmergeinfoty; + +procedure tmidisource.mergeevents; //todo: optimize +var + int1,int2,int3,int4,int5,int6: integer; + ar1: trackmergeinfoarty; + lwo1: longword; +begin + loadtracks; + if high(ftracks) < 0 then begin + exit; + end; + if not (mss_eventsmerged in fstate) then begin + int2:= 0; + int3:= 0; + setlength(ar1,length(ftracks)); + for int1:= 0 to high(ftracks) do begin + if not ftracks[int1].disabled and (ftrackbuffer[int1] <> nil) then begin + int4:= length(ftrackbuffer[int1]); + int2:= int2 + int4; + setlength(ftrackbuffer[int1],int4+1); + ftrackbuffer[int1][int4].delta:= bigint; //endmarker + ar1[int3].po:= pointer(ftrackbuffer[int1]); + inc(int3); + end; + end; + setlength(ar1,int3); + setlength(feventbuffer,int2); + { + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + time:= time + po^.delta; //init + end; + end; + } + lwo1:= 0; + for int1:= 0 to int2 - 1 do begin + with ar1[0] do begin + int4:= time+po^.delta-lwo1; + end; + int5:= 0; + for int3:= 1 to high(ar1) do begin + with ar1[int3] do begin + int6:= time+po^.delta-lwo1; + if int6 < int4 then begin + int4:= int6; + int5:= int3; + end; + end; + end; + with ar1[int5] do begin + feventbuffer[int1]:= po^; + time:= time + po^.delta; + with feventbuffer[int1] do begin + delta:= time-lwo1; + end; + lwo1:= time; + inc(po); + end; + end; + ftrackbuffer:= nil; + include(fstate,mss_eventsmerged); + end; +end; + +{ + fstarttime:= timestamp; + feventtime:= fstarttime; + processevent; +} +procedure tmidisource.checkdata; +begin + mergeevents; +end; + +procedure tmidisource.start; +begin + checkdata; + fstarttime:= timestamp; + feventtime:= fstarttime; + processevent; +end; + +procedure tmidisource.stop; +begin + ftimer.enabled:= false; +end; + +procedure tmidisource.settempo(const avalue: real); +begin + if avalue > 0 then begin + ftempo:= avalue; + ftimescale:= (60000000)/(ticksperbeat*avalue); + end; +end; + +function tmidisource.ticksperbeat: integer; +begin + result:= defaultticksperbeat; + if fstream <> nil then begin + result:= fstream.timedivision; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/audio/msepulse.pas b/mseide-msegui/lib/common/audio/msepulse.pas new file mode 100644 index 0000000..480dc55 --- /dev/null +++ b/mseide-msegui/lib/common/audio/msepulse.pas @@ -0,0 +1,58 @@ +{ MSEgui Copyright (c) 2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepulse; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes{msestrings},msepulseglob,msectypes; + +const +{$ifdef mswindows} + pulsesimplelib: array[0..0] of filenamety = ('libpulse-0.dll'); +{$else} + pulsesimplelib: array[0..1] of filenamety = + ('libpulse.so.0','libpulse.so'); +{$endif} + +var +//** Return a human readable error message for the specified numeric error code */ + pa_strerror: function(error: cint): pchar; cdecl; + +procedure initializepulse(const sonames: array of filenamety); + //[] = default +procedure releasepulse; + +implementation +uses + msedynload,sysutils,msesys; + +var + libinfo: dynlibinfoty; + +procedure initializepulse(const sonames: array of filenamety); //[] = default +const + funcs: array[0..0] of funcinfoty = ( + (n: 'pa_strerror'; d: {$ifndef FPC}@{$endif}@pa_strerror) //0 + ); + errormessage = 'Can not load Pulseaudio simple library. '; +begin + initializedynlib(libinfo,sonames,pulsesimplelib,funcs,[],errormessage); +end; + +procedure releasepulse; +begin + releasedynlib(libinfo); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/audio/msepulseglob.pas b/mseide-msegui/lib/common/audio/msepulseglob.pas new file mode 100644 index 0000000..be685d2 --- /dev/null +++ b/mseide-msegui/lib/common/audio/msepulseglob.pas @@ -0,0 +1,333 @@ +{ MSEgui Copyright (c) 2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +{ +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio 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 Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ +} +{ +/** \mainpage + * + * \section intro_sec Introduction + * + * This document describes the client API for the PulseAudio sound + * server. The API comes in two flavours to accommodate different styles + * of applications and different needs in complexity: + * + * \li The complete but somewhat complicated to use asynchronous API + * \li The simplified, easy to use, but limited synchronous API + * + * All strings in PulseAudio are in the UTF-8 encoding, regardless of current + * locale. Some functions will filter invalid sequences from the string, some + * will simply fail. To ensure reliable behaviour, make sure everything you + * pass to the API is already in UTF-8. + + * \section simple_sec Simple API + * + * Use this if you develop your program in synchronous style and just + * need a way to play or record data on the sound server. See + * \subpage simple for more details. + * + * \section async_sec Asynchronous API + * + * Use this if you develop your programs in asynchronous, event loop + * based style or if you want to use the advanced features of the + * PulseAudio API. A guide can be found in \subpage async. + * + * By using the built-in threaded main loop, it is possible to acheive a + * pseudo-synchronous API, which can be useful in synchronous applications + * where the simple API is insufficient. See the \ref async page for + * details. + * + * \section thread_sec Threads + * + * The PulseAudio client libraries are not designed to be directly + * thread-safe. They are however designed to be reentrant and + * threads-aware. + * + * To use the libraries in a threaded environment, you must assure that + * all objects are only used in one thread at a time. Normally, this means + * that all objects belonging to a single context must be accessed from the + * same thread. + * + * The included main loop implementation is also not thread safe. Take care + * to make sure event objects are not manipulated when any other code is + * using the main loop. + * + * \section pkgconfig pkg-config + * + * The PulseAudio libraries provide pkg-config snippets for the different + * modules: + * + * \li libpulse - The asynchronous API and the internal main loop implementation. + * \li libpulse-mainloop-glib - GLIB 2.x main loop bindings. + * \li libpulse-simple - The simple PulseAudio API. + */ +} +unit msepulseglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes; +{$ifdef FPC} + {$packrecords c} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} +const + PA_CHANNELS_MAX = 32; //** Maximum number of allowed channels */ + PA_RATE_MAX = (48000*4);//** Maximum allowed sample rate */ + +type + uint32_t = longword; + uint8_t = byte; + size_t = ptruint; + pa_usec_t = uint64; + +//** The direction of a pa_stream object */ + pa_stream_direction_t = ( + PA_STREAM_NODIRECTION, //**< Invalid direction */ + PA_STREAM_PLAYBACK, //**< Playback stream */ + PA_STREAM_RECORD, //**< Record stream */ + PA_STREAM_UPLOAD //**< Sample upload stream */ + ); + +//** Sample format */ + pa_sample_format_t = ( + PA_SAMPLE_INVALID = -1,//**< An invalid value */ + PA_SAMPLE_U8 = 0, //**< Unsigned 8 Bit PCM */ + PA_SAMPLE_ALAW, //**< 8 Bit a-Law */ + PA_SAMPLE_ULAW, //**< 8 Bit mu-Law */ + PA_SAMPLE_S16LE,//**< Signed 16 Bit PCM, little endian (PC) */ + PA_SAMPLE_S16BE,//**< Signed 16 Bit PCM, big endian */ + PA_SAMPLE_FLOAT32LE,//**< 32 Bit IEEE floating point, little endian (PC), range -1.0 to 1.0 */ + PA_SAMPLE_FLOAT32BE,//**< 32 Bit IEEE floating point, big endian, range -1.0 to 1.0 */ + PA_SAMPLE_S32LE,//**< Signed 32 Bit PCM, little endian (PC) */ + PA_SAMPLE_S32BE,//**< Signed 32 Bit PCM, big endian */ + PA_SAMPLE_S24LE,//**< Signed 24 Bit PCM packed, little endian (PC). \since 0.9.15 */ + PA_SAMPLE_S24BE,//**< Signed 24 Bit PCM packed, big endian. \since 0.9.15 */ + PA_SAMPLE_S24_32LE,//**< Signed 24 Bit PCM in LSB of 32 Bit words, little endian (PC). \since 0.9.15 */ + PA_SAMPLE_S24_32BE,//**< Signed 24 Bit PCM in LSB of 32 Bit words, big endian. \since 0.9.15 */ + PA_SAMPLE_MAX//**< Upper limit of valid sample types */ + ); + +const +{$ifdef endian_big} + PA_SAMPLE_S16NE = PA_SAMPLE_S16BE; + PA_SAMPLE_FLOAT32NE = PA_SAMPLE_FLOAT32BE; + PA_SAMPLE_S32NE = PA_SAMPLE_S32BE; + PA_SAMPLE_S24NE = PA_SAMPLE_S24BE; + PA_SAMPLE_S24_32NE = PA_SAMPLE_S24_32BE; + PA_SAMPLE_S16RE = PA_SAMPLE_S16LE; + PA_SAMPLE_FLOAT32RE = PA_SAMPLE_FLOAT32LE; + PA_SAMPLE_S32RE = PA_SAMPLE_S32LE; + PA_SAMPLE_S24RE = PA_SAMPLE_S24LE; + PA_SAMPLE_S24_32RE = PA_SAMPLE_S24_32LE; +{$else} + PA_SAMPLE_S16NE = PA_SAMPLE_S16LE; + PA_SAMPLE_FLOAT32NE = PA_SAMPLE_FLOAT32LE; + PA_SAMPLE_S32NE = PA_SAMPLE_S32LE; + PA_SAMPLE_S24NE = PA_SAMPLE_S24LE; + PA_SAMPLE_S24_32NE = PA_SAMPLE_S24_32LE; + PA_SAMPLE_S16RE = PA_SAMPLE_S16BE; + PA_SAMPLE_FLOAT32RE = PA_SAMPLE_FLOAT32BE; + PA_SAMPLE_S32RE = PA_SAMPLE_S32BE; + PA_SAMPLE_S24RE = PA_SAMPLE_S24BE; + PA_SAMPLE_S24_32RE = PA_SAMPLE_S24_32BE; +{$endif} + +type + +//** A sample format and attribute specification */ + pa_sample_spec = record + format: pa_sample_format_t; //**< The sample format */ + rate: uint32_t; //**< The sample rate. (e.g. 44100) */ + channels: uint8_t; //**< Audio channels. (1 for mono, 2 for stereo, ...) */ + end; + ppa_sample_spec = ^pa_sample_spec; + +//** A list of channel mapping definitions for pa_channel_map_init_auto() */ + pa_channel_map_def = ( + PA_CHANNEL_MAP_AIFF, //**< The mapping from RFC3551, which is based on AIFF-C */ + PA_CHANNEL_MAP_ALSA, //**< The default mapping used by ALSA. This mapping is probably + //* not too useful since ALSA's default channel mapping depends on + //* the device string used. */ + PA_CHANNEL_MAP_AUX, //**< Only aux channels */ + PA_CHANNEL_MAP_WAVEEX,//**< Microsoft's WAVEFORMATEXTENSIBLE mapping. This mapping works + //* as if all LSBs of dwChannelMask are set. */ + PA_CHANNEL_MAP_OSS, //**< The default channel mapping used by OSS as defined in the OSS + //* 4.0 API specs. This mapping is probably not too useful since + //* the OSS API has changed in this respect and no longer knows a + //* default channel mapping based on the number of channels. */ + + //**< Upper limit of valid channel mapping definitions */ + PA_CHANNEL_MAP_DEF_MAX + ); + ppa_channel_map_def = ^pa_channel_map_def; + +const + PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF; //**< The default channel map */ + +type + +//** A list of channel labels */ + pa_channel_position_t = ( + PA_CHANNEL_POSITION_INVALID = -1, + PA_CHANNEL_POSITION_MONO = 0, + PA_CHANNEL_POSITION_FRONT_LEFT, //* Apple, Dolby call this 'Left' */ + PA_CHANNEL_POSITION_FRONT_RIGHT, //* Apple, Dolby call this 'Right' */ + PA_CHANNEL_POSITION_FRONT_CENTER, //* Apple, Dolby call this 'Center' */ + PA_CHANNEL_POSITION_REAR_CENTER, //* Microsoft calls this 'Back Center', Apple calls this 'Center Surround', Dolby calls this 'Surround Rear Center' */ + PA_CHANNEL_POSITION_REAR_LEFT, //* Microsoft calls this 'Back Left', Apple calls this 'Left Surround' (!), Dolby calls this 'Surround Rear Left' */ + PA_CHANNEL_POSITION_REAR_RIGHT, //* Microsoft calls this 'Back Right', Apple calls this 'Right Surround' (!), Dolby calls this 'Surround Rear Right' */ + PA_CHANNEL_POSITION_LFE, //* Microsoft calls this 'Low Frequency', Apple calls this 'LFEScreen' */ + PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, //* Apple, Dolby call this 'Left Center' */ + PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, //* Apple, Dolby call this 'Right Center */ + PA_CHANNEL_POSITION_SIDE_LEFT, //* Apple calls this 'Left Surround Direct', Dolby calls this 'Surround Left' (!) */ + PA_CHANNEL_POSITION_SIDE_RIGHT, //* Apple calls this 'Right Surround Direct', Dolby calls this 'Surround Right' (!) */ + PA_CHANNEL_POSITION_AUX0, + PA_CHANNEL_POSITION_AUX1, + PA_CHANNEL_POSITION_AUX2, + PA_CHANNEL_POSITION_AUX3, + PA_CHANNEL_POSITION_AUX4, + PA_CHANNEL_POSITION_AUX5, + PA_CHANNEL_POSITION_AUX6, + PA_CHANNEL_POSITION_AUX7, + PA_CHANNEL_POSITION_AUX8, + PA_CHANNEL_POSITION_AUX9, + PA_CHANNEL_POSITION_AUX10, + PA_CHANNEL_POSITION_AUX11, + PA_CHANNEL_POSITION_AUX12, + PA_CHANNEL_POSITION_AUX13, + PA_CHANNEL_POSITION_AUX14, + PA_CHANNEL_POSITION_AUX15, + PA_CHANNEL_POSITION_AUX16, + PA_CHANNEL_POSITION_AUX17, + PA_CHANNEL_POSITION_AUX18, + PA_CHANNEL_POSITION_AUX19, + PA_CHANNEL_POSITION_AUX20, + PA_CHANNEL_POSITION_AUX21, + PA_CHANNEL_POSITION_AUX22, + PA_CHANNEL_POSITION_AUX23, + PA_CHANNEL_POSITION_AUX24, + PA_CHANNEL_POSITION_AUX25, + PA_CHANNEL_POSITION_AUX26, + PA_CHANNEL_POSITION_AUX27, + PA_CHANNEL_POSITION_AUX28, + PA_CHANNEL_POSITION_AUX29, + PA_CHANNEL_POSITION_AUX30, + PA_CHANNEL_POSITION_AUX31, + PA_CHANNEL_POSITION_TOP_CENTER, //* Apple calls this 'Top Center Surround' */ + PA_CHANNEL_POSITION_TOP_FRONT_LEFT, //* Apple calls this 'Vertical Height Left' */ + PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, //* Apple calls this 'Vertical Height Right' */ + PA_CHANNEL_POSITION_TOP_FRONT_CENTER, //* Apple calls this 'Vertical Height Center' */ + PA_CHANNEL_POSITION_TOP_REAR_LEFT, //* Microsoft and Apple call this 'Top Back Left' */ + PA_CHANNEL_POSITION_TOP_REAR_RIGHT, //* Microsoft and Apple call this 'Top Back Right' */ + PA_CHANNEL_POSITION_TOP_REAR_CENTER, //* Microsoft and Apple call this 'Top Back Center' */ + PA_CHANNEL_POSITION_MAX + ); + +const + PA_CHANNEL_POSITION_LEFT = PA_CHANNEL_POSITION_FRONT_LEFT; + PA_CHANNEL_POSITION_RIGHT = PA_CHANNEL_POSITION_FRONT_RIGHT; + PA_CHANNEL_POSITION_CENTER = PA_CHANNEL_POSITION_FRONT_CENTER; + PA_CHANNEL_POSITION_SUBWOOFER = PA_CHANNEL_POSITION_LFE; + +type + pa_channel_position_aty = array[0..PA_CHANNELS_MAX-1] of pa_channel_position_t; + +//** A channel map which can be used to attach labels to specific +// * channels of a stream. These values are relevant for conversion and +// * mixing of streams */ + pa_channel_map = record + chsnnels: uint8_t; //**< Number of channels */ + map: pa_channel_position_aty; //**< Channel labels */ + end; + ppa_channel_map = ^pa_channel_map; + +//** Playback and record buffer metrics */ + pa_buffer_attr = record + maxlength: uint32_t; + //**< Maximum length of the buffer. Setting this to (uint32_t) -1 + //* will initialize this to the maximum value supported by server, + //* which is recommended. */ + tlength: uint32_t; + //**< Playback only: target length of the buffer. The server tries + //* to assure that at least tlength bytes are always available in + //* the per-stream server-side playback buffer. It is recommended + //* to set this to (uint32_t) -1, which will initialize this to a + //* value that is deemed sensible by the server. However, this + //* value will default to something like 2s, i.e. for applications + //* that have specific latency requirements this value should be + //* set to the maximum latency that the application can deal + //* with. When PA_STREAM_ADJUST_LATENCY is not set this value will + //* influence only the per-stream playback buffer size. When + //* PA_STREAM_ADJUST_LATENCY is set the overall latency of the sink + //* plus the playback buffer size is configured to this value. Set + //* PA_STREAM_ADJUST_LATENCY if you are interested in adjusting the + //* overall latency. Don't set it if you are interested in + //* configuring the server-side per-stream playback buffer + //* size. */ + prebuf: uint32_t; + //**< Playback only: pre-buffering. The server does not start with + //* playback before at least prebuf bytes are available in the + //* buffer. It is recommended to set this to (uint32_t) -1, which + //* will initialize this to the same value as tlength, whatever + //* that may be. Initialize to 0 to enable manual start/stop + //* control of the stream. This means that playback will not stop + //* on underrun and playback will not start automatically. Instead + //* pa_stream_corked() needs to be called explicitly. If you set + //* this value to 0 you should also set PA_STREAM_START_CORKED. */ + minreq: uint32_t; + //**< Playback only: minimum request. The server does not request + //* less than minreq bytes from the client, instead waits until the + //* buffer is free enough to request more bytes at once. It is + //* recommended to set this to (uint32_t) -1, which will initialize + //* this to a value that is deemed sensible by the server. This + //* should be set to a value that gives PulseAudio enough time to + //* move the data from the per-stream playback buffer into the + //* hardware playback buffer. */ + fragsize: uint32_t; + //**< Recording only: fragment size. The server sends data in + //* blocks of fragsize bytes size. Large values diminish + //* interactivity with other operations on the connection context + //* but decrease control overhead. It is recommended to set this to + //* (uint32_t) -1, which will initialize this to a value that is + //* deemed sensible by the server. However, this value will default + //* to something like 2s, i.e. for applications that have specific + //* latency requirements this value should be set to the maximum + //* latency that the application can deal with. If + //* PA_STREAM_ADJUST_LATENCY is set the overall source latency will + //* be adjusted according to this value. If it is not set the + //* source latency is left unmodified. */ + end; + ppa_buffer_attr = ^pa_buffer_attr; + +implementation +end. diff --git a/mseide-msegui/lib/common/audio/msepulsesimple.pas b/mseide-msegui/lib/common/audio/msepulsesimple.pas new file mode 100644 index 0000000..644ff70 --- /dev/null +++ b/mseide-msegui/lib/common/audio/msepulsesimple.pas @@ -0,0 +1,201 @@ +{ MSEgui Copyright (c) 2010-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +{ +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio 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 Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ +} +{ +/** \page simple Simple API + * + * \section overv_sec Overview + * + * The simple API is designed for applications with very basic sound + * playback or capture needs. It can only support a single stream per + * connection and has no handling of complex features like events, channel + * mappings and volume control. It is, however, very simple to use and + * quite sufficent for many programs. + * + * \section conn_sec Connecting + * + * The first step before using the sound system is to connect to the + * server. This is normally done this way: + * + * \code + * pa_simple *s; + * pa_sample_spec ss; + * + * ss.format = PA_SAMPLE_S16NE; + * ss.channels = 2; + * ss.rate = 44100; + * + * s = pa_simple_new(NULL, // Use the default server. + * "Fooapp", // Our application's name. + * PA_STREAM_PLAYBACK, + * NULL, // Use the default device. + * "Music", // Description of our stream. + * &ss, // Our sample format. + * NULL, // Use default channel map + * NULL, // Use default buffering attributes. + * NULL, // Ignore error code. + * ); + * \endcode + * + * At this point a connected object is returned, or NULL if there was a + * problem connecting. + * + * \section transfer_sec Transferring data + * + * Once the connection is established to the server, data can start flowing. + * Using the connection is very similar to the normal read() and write() + * system calls. The main difference is that they're call pa_simple_read() + * and pa_simple_write(). Note that these operations always block. + * + * \section ctrl_sec Buffer control + * + * If a playback stream is used then a few other operations are available: + * + * \li pa_simple_drain() - Will wait for all sent data to finish playing. + * \li pa_simple_flush() - Will throw away all data currently in buffers. + * \li pa_simple_get_playback_latency() - Will return the total latency of + * the playback pipeline. + * + * \section cleanup_sec Cleanup + * + * Once playback or capture is complete, the connection should be closed + * and resources freed. This is done through: + * + * \code + * pa_simple_free(s); + * \endcode + */ + +/** \file + * A simple but limited synchronous playback and recording + * API. This is a synchronous, simplified wrapper around the standard + * asynchronous API. */ + +/** \example pacat-simple.c + * A simple playback tool using the simple API */ + +/** \example parec-simple.c + * A simple recording tool using the simple API */ +} +unit msepulsesimple; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes{msestrings},msepulseglob,msectypes; + +const +{$ifdef mswindows} + pulsesimplelib: array[0..0] of filenamety = ('libpulse-simple-0.dll'); +{$else} + pulsesimplelib: array[0..1] of filenamety = + ('libpulse-simple.so.0','libpulse-simple.so'); +{$endif} +type + pa_simple = record //opaque connection object + end; + ppa_simple = ^pa_simple; + +var + pa_simple_new: function( + const server: pchar; //**< Server name, or NULL for default */ + const name: pchar; //**< A descriptive name for this client + //(application name, ...) */ + dir: pa_stream_direction_t; //**< Open this stream for recording or playback? */ + const dev: pchar; //**< Sink (resp. source) name, or NULL for default */ + const stream_name: pchar; //**< A descriptive name for this client (application name, song title, ...) */ + const ss: ppa_sample_spec; //**< The sample type to use */ + const map: ppa_channel_map; //**< The channel map to use, or NULL for default */ + const attr: ppa_buffer_attr; //**< Buffering attributes, or NULL for default */ + error: pcint //**< A pointer where the error code is stored + //when the routine returns NULL. + //It is OK to pass NULL here. */ + ): ppa_simple; cdecl; +//** Close and free the connection to the server. The connection objects becomes invalid when this is called. */ + pa_simple_free: procedure(s: ppa_simple); cdecl; + +//** Write some data to the server */ + pa_simple_write: function(s: ppa_simple; const data: pointer; + bytes: size_t; error: pcint): cint; cdecl; + +//** Wait until all data already written is played by the daemon */ + pa_simple_drain: function(s: ppa_simple; error: pcint): cint; cdecl; + +//** Read some data from the server */ + pa_simple_read: function(s: ppa_simple; data: pointer; bytes: size_t; + error: pcint): cint; cdecl; +//** Return the playback latency. */ + pa_simple_get_latency: function(s: ppa_simple; + error: pcint): pa_usec_t; cdecl; + +//** Flush the playback buffer. */ + pa_simple_flush: function(s: ppa_simple; error: pcint): cint; cdecl; + +procedure initializepulsesimple(const sonames: array of filenamety); + //[] = default +procedure releasepulsesimple; + +implementation +uses + msedynload,sysutils,msesys,msepulse; + +var + libinfo: dynlibinfoty; + +procedure initializepulsesimple(const sonames: array of filenamety); //[] = default +const + funcs: array[0..6] of funcinfoty = ( + (n: 'pa_simple_new'; d: {$ifndef FPC}@{$endif}@pa_simple_new), //0 + (n: 'pa_simple_free'; d: {$ifndef FPC}@{$endif}@pa_simple_free), //1 + (n: 'pa_simple_write'; d: {$ifndef FPC}@{$endif}@pa_simple_write), //2 + (n: 'pa_simple_drain'; d: {$ifndef FPC}@{$endif}@pa_simple_drain), //3 + (n: 'pa_simple_read'; d: {$ifndef FPC}@{$endif}@pa_simple_read), //4 + (n: 'pa_simple_get_latency'; d: {$ifndef FPC}@{$endif}@pa_simple_get_latency), //5 + (n: 'pa_simple_flush'; d: {$ifndef FPC}@{$endif}@pa_simple_flush) //6 + ); + errormessage = 'Can not load Pulseaudio simple library. '; +begin + initializedynlib(libinfo,sonames,pulsesimplelib,funcs,[],errormessage); + initializepulse([]); +end; + +procedure releasepulsesimple; +begin + releasedynlib(libinfo); + releasepulse; +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/audio/msespeak.pas b/mseide-msegui/lib/common/audio/msespeak.pas new file mode 100644 index 0000000..8fb9db0 --- /dev/null +++ b/mseide-msegui/lib/common/audio/msespeak.pas @@ -0,0 +1,1244 @@ +{ MSEgui Copyright (c) 2017-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +// +// under construction +// +unit msespeak; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,msetypes,mseespeakng,msearrayprops, + msethread,mseevent,msesystypes,mselist; +type + espeakoptionty = (eso_nospeakaudio,eso_speakonidle); + espeakoptionsty = set of espeakoptionty; +const + defaultespeakoptions = [eso_speakonidle]; +type + speakoptionty = (so_cancel,so_wait,so_ssml,so_phonemes,so_endpause); + + speakoptionsty = set of speakoptionty; + + tcustomespeakng = class; + + genderty = (gen_none,gen_male,gen_female); + punctuationty = (pu_none,pu_all,pu_some); + tvoice = class(townedpersistent) + private + fgender: genderty; + fpitch: int32; + frate: int32; + fvolume: int32; + frange: int32; + fpunctuation: punctuationty; + fcapitals: int32; + fwordgap: int32; + flanguage: msestring; + fvoicename: msestring; + fidentifier: msestring; + fvariant: msestring; + fage: card8; + fvariantnum: card8; + fpunctuationlist: msestring; + procedure setgender(const avalue: genderty); + procedure setpitch(const avalue: int32); + procedure setrate(const avalue: int32); + procedure setvolume(const avalue: int32); + procedure setrange(const avalue: int32); + procedure setpunctuation(const avalue: punctuationty); + procedure setcapitals(const avalue: int32); + procedure setwordgap(const avalue: int32); + procedure setlanguage(const avalue: msestring); + procedure setidentifier(const avalue: msestring); + procedure setvoicename(const avalue: msestring); + procedure setvariant(const avalue: msestring); + procedure setage(const avalue: card8); + procedure setvariantnum(const avalue: card8); + procedure setpunctuationlist(const avalue: msestring); + protected + fid: string; + procedure change(); + public + constructor create(aowner: tobject); override; + published + property identifier: msestring read fidentifier write setidentifier; + //voice selection 1. priority + // the filename for this voice within + //espeak-ng-data/voices + property voicename: msestring read fvoicename write setvoicename; + //voice selection used if identifier = '', example: de + property variant: msestring read fvariant write setvariant; + //appended to identifier or voicename, example: f3 + + + //values below used for voice selection if identifier and voicename = '' + property language: msestring read flanguage write setlanguage; + //example: en-uk + property variantnum: card8 read fvariantnum write setvariantnum default 0; + property gender: genderty read fgender write setgender default gen_none; + property age: card8 read fage write setage default 0; + + //voice independent parameters + property rate: int32 read frate write setrate default espeakRATE_NORMAL; + {espeakRATE: speaking speed in word per minute. Values 80 to 450.} + property volume: int32 read fvolume write setvolume default 100; + {espeakVOLUME: volume in range 0-200 or more. + 0=silence, 100=normal full volume, greater values may + produce amplitude compression or distortion} + property pitch: int32 read fpitch write setpitch default 50; + {espeakPITCH: base pitch, range 0-100. 50=normal} + property range: int32 read frange write setrange default 50; + {espeakRANGE: pitch range, range 0-100. 0-monotone, 50=normal} + property punctuationlist: msestring read fpunctuationlist + write setpunctuationlist; + property punctuation: punctuationty read fpunctuation + write setpunctuation default pu_none; + {espeakPUNCTUATION: which punctuation characters to announce: + value in espeak_PUNCT_TYPE (none, all, some), + see espeak_GetParameter() to specify which characters are announced.} + property capitals: int32 read fcapitals write setcapitals default -1; + {espeakCAPITALS: announce capital letters by: + 0=none, + 1=sound icon, + 2=spelling, + 3 or higher, by raising pitch. + This values gives the amount in Hz by which the pitch + of a word raised to indicate it has a capital letter.} + property wordgap: int32 read fwordgap write setwordgap default -1; + //-1 = default + {espeakWORDGAP: pause between words, units of 10mS (at the default speed)} + end; + + tvoices = class(townedpersistentarrayprop) + private + function getitems(const index: int32): tvoice; + procedure setitems(const index: int32; const avalue: tvoice); + protected + procedure setcount1(acount: integer; doinit: boolean); override; + public + constructor create(const aowner: tcustomespeakng); reintroduce; + class function getitemclasstype: persistentclassty; override; + property items[const index: int32]: tvoice read getitems + write setitems; default; + end; + + speakmodety = (smo_text,smo_char,smo_key); + tspeakevent = class(tmseevent) + protected + fmode: speakmodety; + fvoice: int32; + foptions: speakoptionsty; + ftext: msestring; + fchar: char32; + public + constructor create(const text: msestring; const options: speakoptionsty; + const voice: int32); + constructor create(const achar: char32; const options: speakoptionsty; + const voice: int32); + constructor createkey(const key: msestring; const options: speakoptionsty; + const voice: int32); + end; +{ + tspeakthread = class(teventthread) + protected + fidlecond: condty; + public + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); overload; override; + destructor destroy(); override; + procedure clearevents() override; + end; +} + speakstatety = (ss_voicevalid,ss_connected,ss_disconnected, + ss_connecting,ss_espeaknginitialized, + ss_canceled,ss_idle); + speakstatesty = set of speakstatety; + + espeakngeventty = procedure(const sender: tcustomespeakng) of object; + + tcustomespeakng = class(tmsecomponent) + private + factive: boolean; + fdatapath: filenamety; + foptions: espeakoptionsty; + fdevice: msestring; + fbufferlength: int32; + fvoicedefault: int32; + fvoices: tvoices; + fpunctuationlist: msestring; + fvolume: flo64; + frate: flo64; + fpitch: flo64; + frange: flo64; + fwordgap: int32; + flanguage: msestring; + fidentifier: msestring; + fvariant: msestring; + fgender: genderty; + fage: card8; + fvariantnum: card8; + fcapitals: int32; + fvoicename: msestring; + fonbeforeconnect: espeakngeventty; + procedure setactive(const avalue: boolean); + procedure setvoicedefault(avalue: int32); + procedure setvoices(const avalue: tvoices); + procedure setpunctuationlist(const avalue: msestring); + procedure setvolume(const avalue: flo64); + procedure setrate(const avalue: flo64); + procedure setpitch(const avalue: flo64); + procedure setrange(const avalue: flo64); + procedure setwordgap(const avalue: int32); + procedure setlanguage(const avalue: msestring); + procedure setidentifier(const avalue: msestring); + procedure setvariant(const avalue: msestring); + procedure setgender(const avalue: genderty); + procedure setage(const avalue: card8); + procedure setvariantnum(const avalue: card8); + procedure setcapitals(const avalue: int32); + procedure setvoicename(const avalue: msestring); + protected + fstate: speakstatesty; + flastvoice: int32; + fspeakqueue: tcustomeventqueue; + fspeakthread: teventthread; + fidlecond: condty; + procedure doasyncevent(var atag: int32) override; + function speakexe(athread: tmsethread): int32; + procedure loaded() override; + procedure connect(); + procedure disconnect(); + procedure doidle(var again: boolean); + procedure checkerror(const astate: espeak_ng_status); + procedure voicechanged(); + procedure checkvoice(avoice: int32); + procedure internalspeak(const atext: msestring; + const aoptions: speakoptionsty; + const avoice: int32); + procedure internalspeakcharacter(const achar: char32; + const aoptions: speakoptionsty; + const avoice: int32); + procedure internalspeakkeyname(const akey: msestring; + const aoptions: speakoptionsty; + const avoice: int32); + procedure lock(); + procedure unlock(); + procedure beginchange(); + procedure endchange(); + + procedure postidle(); + procedure postevent(const aevent: tspeakevent); + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure speak(const atext: msestring; const aoptions: speakoptionsty = []; + const avoice: int32 = -1); //-1 -> default + procedure speakcharacter(const achar: char32; + const aoptions: speakoptionsty = []; + const avoice: int32 = -1); //-1 -> default + procedure speakkeyname(const akey: msestring; + const aoptions: speakoptionsty = []; + const avoice: int32 = -1); //-1 -> default + procedure wait(); + procedure cancel(); + property active: boolean read factive write setactive default false; + property datapath: filenamety read fdatapath write fdatapath; + property options: espeakoptionsty read foptions write foptions + default defaultespeakoptions; + property device: msestring read fdevice write fdevice; + property bufferlength: int32 read fbufferlength + write fbufferlength default 0; + //ms, 0 -> 60ms + property voicedefault: int32 read fvoicedefault + write setvoicedefault default 0; + property voices: tvoices read fvoices write setvoices; + property identifier: msestring read fidentifier write setidentifier; + property voicename: msestring read fvoicename write setvoicename; + property variant: msestring read fvariant write setvariant; + + property language: msestring read flanguage write setlanguage; + property gender: genderty read fgender write setgender default gen_none; + property age: card8 read fage write setage default 0; + property variantnum: card8 read fvariantnum write setvariantnum default 0; + + property volume: flo64 read fvolume write setvolume; //default 1.0 + property rate: flo64 read frate write setrate; //default 1.0 + property pitch: flo64 read fpitch write setpitch; //default 1.0 + property range: flo64 read frange write setrange; //default 1.0 + property capitals: int32 read fcapitals write setcapitals default 0; + property wordgap: int32 read fwordgap write setwordgap default 0; + //n*10ms + property punctuationlist: msestring read fpunctuationlist + write setpunctuationlist; + //for voice.punctuation pu_some + property onbeforeconnect: espeakngeventty read fonbeforeconnect + write fonbeforeconnect; + end; + + tespeakng = class(tcustomespeakng) + published + property active; + property datapath; + property options; + property device; + property bufferlength; + property voicedefault; + property voices; + property language; + property identifier; + property voicename; + property variant; + property gender; + property age; + property variantnum; + property volume; + property rate; + property pitch; + property range; + property wordgap; + property punctuationlist; + property onbeforeconnect; + end; + +implementation +uses + msestrings,msefileutils,msectypes,mseapplication,msesysintf1, + sysutils,msesysutils{$ifdef mswindows},activex{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +const + disconnecttag = 5936727; + +{ tspeakevent } + +constructor tspeakevent.create(const text: msestring; + const options: speakoptionsty; const voice: int32); +begin + fmode:= smo_text; + foptions:= options; + fvoice:= voice; + ftext:= text; +end; + +constructor tspeakevent.create(const achar: char32; + const options: speakoptionsty; const voice: int32); +begin + fmode:= smo_char; + foptions:= options; + fvoice:= voice; + fchar:= achar; +end; + +constructor tspeakevent.createkey(const key: msestring; + const options: speakoptionsty; const voice: int32); +begin + fmode:= smo_key; + foptions:= options; + fvoice:= voice; + ftext:= key; +end; + +{ tvoices } + +function tvoices.getitems(const index: int32): tvoice; +begin + checkindex(index); + result:= tvoice(fitems[index]); +end; + +procedure tvoices.setitems(const index: int32; const avalue: tvoice); +begin + checkindex(index); + fitems[index].assign(avalue); +end; + +constructor tvoices.create(const aowner: tcustomespeakng); +begin + inherited create(aowner,tvoice); + count:= 1; +end; + +procedure tvoices.setcount1(acount: integer; doinit: boolean); +begin + tcustomespeakng(fowner).lock(); + if (acount < 1) and not (aps_destroying in fstate) then begin + acount:= 1; + end; + inherited; + tcustomespeakng(fowner).unlock(); +end; + +class function tvoices.getitemclasstype: persistentclassty; +begin + result:= tvoice; +end; + +{ tcustomespeakng } + +constructor tcustomespeakng.create(aowner: tcomponent); +begin + fvolume:= 1; + frate:= 1; + fpitch:= 1; + frange:= 1; + foptions:= defaultespeakoptions; + inherited; + fspeakqueue:= tcustomeventqueue.create(true); + fvoices:= tvoices.create(self); +end; + +destructor tcustomespeakng.destroy(); +begin + active:= false; + fvoices.free(); + fspeakqueue.free(); + inherited; +end; + +procedure tcustomespeakng.setactive(const avalue: boolean); +begin + if avalue <> factive then begin + if not(csloading in componentstate) then begin + if avalue then begin + try + connect(); + except + disconnect(); + raise; + end; + end + else begin + disconnect(); + end; + end; + factive:= avalue; + end; +end; + +procedure tcustomespeakng.setvoicedefault(avalue: int32); +begin + if (avalue < 0) or (avalue >= fvoices.count) then begin + avalue:= 0; + end; + fvoicedefault:= avalue; +end; + +procedure tcustomespeakng.setvoices(const avalue: tvoices); +begin + fvoices.assign(avalue); +end; + +procedure tcustomespeakng.setpunctuationlist(const avalue: msestring); +begin + if fpunctuationlist <> avalue then begin + beginchange(); + fpunctuationlist:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setvolume(const avalue: flo64); +begin + if fvolume <> avalue then begin + beginchange(); + fvolume:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setrate(const avalue: flo64); +begin + if frate <> avalue then begin + beginchange(); + frate:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setpitch(const avalue: flo64); +begin + if fpitch <> avalue then begin + beginchange(); + fpitch:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setrange(const avalue: flo64); +begin + if frange <> avalue then begin + beginchange(); + frange:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setwordgap(const avalue: int32); +begin + if fwordgap <> avalue then begin + beginchange(); + fwordgap:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setlanguage(const avalue: msestring); +begin + if flanguage <> avalue then begin + beginchange(); + flanguage:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setidentifier(const avalue: msestring); +begin + if fidentifier <> avalue then begin + beginchange(); + fidentifier:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setvariant(const avalue: msestring); +begin + if fvariant <> avalue then begin + beginchange(); + fvariant:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setvoicename(const avalue: msestring); +begin + if fvoicename <> avalue then begin + beginchange(); + fvoicename:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.doasyncevent(var atag: int32); +begin + if atag = disconnecttag then begin + active:= false; + end + else begin + inherited; + end; +end; + +procedure tcustomespeakng.setgender(const avalue: genderty); +begin + if fgender <> avalue then begin + beginchange(); + fgender:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setage(const avalue: card8); +begin + if fage <> avalue then begin + beginchange(); + fage:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setvariantnum(const avalue: card8); +begin + if fvariantnum <> avalue then begin + beginchange(); + fvariantnum:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setcapitals(const avalue: int32); +begin + if fcapitals <> avalue then begin + beginchange(); + fcapitals:= avalue; + endchange(); + end; +end; + +function tcustomespeakng.speakexe(athread: tmsethread): int32; +var + ev1: tspeakevent; + b1: boolean; +begin +{$ifdef mswindows} + coinitialize(nil); +{$endif} + with teventthread(athread) do begin + while not terminated do begin + pointer(ev1):= waitevent(); + if ev1 is tspeakevent then begin + lock(); + b1:= ss_disconnected in fstate; + checkerror(espeak_ng_setcancelstate(0)); + unlock(); + if not b1 then begin + try + case ev1.fmode of + smo_text: begin + internalspeak(ev1.ftext,ev1.foptions,ev1.fvoice); + end; + smo_char: begin + internalspeakcharacter(ev1.fchar,ev1.foptions,ev1.fvoice); + end; + smo_key: begin + internalspeakkeyname(ev1.ftext,ev1.foptions,ev1.fvoice); + end; + end; + except + application.handleexception(); + end; + end; + end; + ev1.free(); + eventlist.lock(); + if eventlist.count = 0 then begin + postidle(); + end; + eventlist.unlock(); + end; + postidle(); + end; +{$ifdef mswindows} + couninitialize(); +{$endif} + result:= 0; +end; + +procedure tcustomespeakng.loaded(); +begin + inherited; + if factive then begin + factive:= false; + active:= true; + end; +end; + +procedure tcustomespeakng.connect(); +var + m1: espeak_ng_OUTPUT_MODE; + s1: string; +begin + if not (csdesigning in componentstate) then begin + if assigned(fonbeforeconnect) then begin + fonbeforeconnect(self); + end; + include(fstate,ss_connecting); + application.registeronidle(@doidle); + exclude(fstate,ss_disconnected); + include(fstate,ss_idle); + sys_condcreate(fidlecond); + voicechanged(); + s1:= stringtoutf8ansi(tosysfilepath(fdatapath)); + initializeespeakng([],s1); + include(fstate,ss_espeaknginitialized); + + m1:= ENOUTPUT_MODE_SYNCHRONOUS; +// m1:= 0;//ENOUTPUT_MODE_SYNCHRONOUS; + //espeak_ng_cancel() does not work in synchronous mode + if not (eso_nospeakaudio in foptions) then begin + m1:= m1 or ENOUTPUT_MODE_SPEAK_AUDIO; + end; + checkerror(espeak_ng_InitializeOutput(m1,fbufferlength,nil)); + include(fstate,ss_connected); + fspeakthread:= teventthread.create(@speakexe); + end; +end; + +procedure tcustomespeakng.disconnect(); +begin + if not (csdesigning in componentstate) and + (ss_connecting in fstate) then begin + application.unregisteronidle(@doidle); + cancel(); + freeandnil(fspeakthread); + sys_conddestroy(fidlecond); + exclude(fstate,ss_connected); + if ss_espeaknginitialized in fstate then begin + releaseespeakng(); + exclude(fstate,ss_espeaknginitialized); + end; + exclude(fstate,ss_connecting); + end; +end; + +procedure tcustomespeakng.checkerror(const astate: espeak_ng_status); +begin + if (astate <> 0) and (astate <> ENS_SPEECH_STOPPED) then begin + componentexception(self,utf8tostring(espeakngerrormessage(astate))); + end; +end; + +procedure tcustomespeakng.voicechanged(); +begin + exclude(fstate,ss_voicevalid); +end; + +procedure tcustomespeakng.checkvoice(avoice: int32); +var + info1: espeak_voice; + name1,lang1,ident1,variant1: string; + s1: string; + ms1: msestring; + ar1: card32arty; + i1: int32; + err1: espeak_ng_STATUS; +{$ifdef mse_debugassistive} + p1: pespeak_voice; +{$endif} +begin + lock(); + try + if avoice < 0 then begin + avoice:= fvoicedefault; + end; + if (avoice >= fvoices.count) then begin + avoice:= 0; + end; + if not (ss_voicevalid in fstate) or (flastvoice <> avoice) then begin + include(fstate,ss_voicevalid); + flastvoice:= avoice; + fillchar(info1,sizeof(info1),0); + with voices[avoice] do begin + if language <> '' then begin + lang1:= stringtoutf8(language); + end + else begin + lang1:= stringtoutf8(self.flanguage); + end; + info1.languages:= pointer(lang1); + if identifier <> '' then begin + ident1:= stringtoutf8(tosysfilepath(identifier)); + end + else begin + ident1:= stringtoutf8(tosysfilepath(self.identifier)); + end; + info1.identifier:= pointer(ident1); + if voicename <> '' then begin + name1:= stringtoutf8(tosysfilepath(voicename)); + end + else begin + name1:= stringtoutf8(tosysfilepath(self.voicename)); + end; + info1.name:= pointer(name1); + if variant <> '' then begin + variant1:= stringtoutf8(tosysfilepath(variant)); + end + else begin + variant1:= stringtoutf8(tosysfilepath(self.variant)); + end; + info1.name:= pointer(name1); + if gender <> gen_none then begin + info1.gender:= ord(gender); + end + else begin + info1.gender:= ord(self.gender); + end; + if age > 0 then begin + info1.age:= age; + end + else begin + info1.age:= self.age; + end; + if variantnum > 0 then begin + info1.variant:= variantnum; + end + else begin + info1.variant:= self.variantnum; + end; + if punctuationlist <> '' then begin + ms1:= punctuationlist; + end + else begin + ms1:= self.punctuationlist; + end; + setlength(ar1,length(ms1)+1); //terminating #0 + for i1:= 0 to high(ar1)-1 do begin + ar1[i1]:= ord(ms1[i1+1]); + end; + checkerror(espeak_ng_setpunctuationlist(pointer(ar1))); + if fid <> '' then begin + err1:= espeak_ng_setvoicebyname(pchar(fid)); + end + else begin + s1:= ''; + if ident1 <> '' then begin + s1:= ident1; + end + else begin + if name1 <> '' then begin + s1:= name1; + end; + end; + if s1 <> '' then begin + if variant1 <> '' then begin + s1:= s1+'+'+variant1; + end; + err1:= espeak_ng_setvoicebyname(pchar(s1)); + end + else begin + err1:= espeak_ng_setvoicebyproperties(@info1); + end; + if err1 = ENS_OK then begin + fid:= espeak_getcurrentvoice()^.identifier; + end; + end; + {$ifdef mse_debugassistive} + p1:= espeak_getcurrentvoice(); + debugwriteln(inttostr(avoice)+':'+p1^.identifier+':'+p1^.name); + {$endif} + if err1 <> ENS_OK then begin + include(fstate,ss_disconnected); + asyncevent(disconnecttag,[peo_local,peo_first]); + checkerror(err1); + end; + checkerror(espeak_ng_setparameter(espeakRATE,round(rate*self.rate),0)); + checkerror(espeak_ng_setparameter(espeakVOLUME, + round(volume*self.volume),0)); + checkerror(espeak_ng_setparameter(espeakPITCH,round(pitch*self.pitch),0)); + checkerror(espeak_ng_setparameter(espeakRANGE,round(range*self.range),0)); + checkerror(espeak_ng_setparameter(espeakPUNCTUATION, + ord(punctuation),0)); + if capitals < 0 then begin + i1:= self.capitals; + end + else begin + i1:= capitals; + end; + checkerror(espeak_ng_setparameter(espeakCAPITALS,i1,0)); + if wordgap < 0 then begin + i1:= self.wordgap; + end + else begin + i1:= wordgap; + end; + checkerror(espeak_ng_setparameter(espeakWORDGAP,i1,0)); + end; + end; + finally + unlock(); + end; +end; + +procedure tcustomespeakng.wait(); +var + b1: boolean; +begin + if not (ss_connected in fstate) then begin + exit; + end; + doidle(b1); + with fspeakthread do begin + sys_condlock(fidlecond); + while true do begin + if ss_idle in fstate then begin + sys_condunlock(fidlecond); + break; + end + else begin + sys_condwait(fidlecond,0); + end; + end; + end; +// checkerror(espeak_ng_synchronize()); +end; + +procedure tcustomespeakng.cancel(); +begin + if not (ss_connected in fstate) then begin + exit; + end; +{$ifdef mse_debugassistive} + debugwriteln('---cancel'); +{$endif} + fspeakqueue.clear(); + fspeakthread.clearevents(); + include(fstate,ss_canceled); +// fspeakthread.lock(); + checkerror(espeak_ng_setcancelstate(1)); +// fspeakthread.unlock(); +// postidle(); +end; + +procedure tcustomespeakng.internalspeak(const atext: msestring; + const aoptions: speakoptionsty; const avoice: int32); +var + s1: string; + f1: cuint; +begin + checkvoice(avoice); + f1:= espeakCHARS_UTF8; + if so_ssml in aoptions then begin + f1:= f1 or espeakSSML; + end; + if so_phonemes in aoptions then begin + f1:= f1 or espeakPHONEMES; + end; + if so_endpause in aoptions then begin + f1:= f1 or espeakENDPAUSE; + end; + s1:= stringtoutf8(atext); + replacechar1(s1,c_tab,' '); +// {$ifdef mse_debugassistive} +// debugwriteln(inttostr(length(s1))+':'+s1); +// {$endif} + checkerror(espeak_ng_synthesize(pchar(s1),length(s1)+1, //terminating #0 + 0,pos_character,0,f1,nil,nil)); +end; + +procedure tcustomespeakng.lock(); +begin + if ss_connected in fstate then begin + fspeakthread.lock(); + end; +end; + +procedure tcustomespeakng.unlock(); +begin + if ss_connected in fstate then begin + fspeakthread.unlock(); + end; +end; + +procedure tcustomespeakng.beginchange(); +begin + lock(); +end; + +procedure tcustomespeakng.endchange(); +begin + voicechanged(); + unlock(); +end; + +procedure tcustomespeakng.postidle(); +begin + sys_condlock(fidlecond); + include(fstate,ss_idle); + sys_condbroadcast(fidlecond); + sys_condunlock(fidlecond); +end; + +procedure tcustomespeakng.doidle(var again: boolean); +begin + if fspeakqueue.count > 0 then begin + fspeakthread.eventlist.lock(); + sys_condlock(fidlecond); + exclude(fstate,ss_idle); + fspeakthread.eventlist.post(fspeakqueue); + sys_condunlock(fidlecond); + fspeakthread.eventlist.unlock(); + end; +end; + +procedure tcustomespeakng.postevent(const aevent: tspeakevent); +begin + if ss_canceled in fstate then begin + wait(); + exclude(fstate,ss_canceled); + end; + if eso_speakonidle in foptions then begin + fspeakqueue.add(aevent); + end + else begin + fspeakthread.eventlist.lock(); + sys_condlock(fidlecond); + exclude(fstate,ss_idle); + fspeakthread.postevent(aevent); + sys_condunlock(fidlecond); + fspeakthread.eventlist.unlock(); + end; +end; + +procedure tcustomespeakng.speak(const atext: msestring; + const aoptions: speakoptionsty = []; const avoice: int32 = -1); +var + c1: char16; +begin + if not (ss_connected in fstate) then begin + exit; + end; + if so_cancel in aoptions then begin + cancel(); + end; +{$ifdef mse_debugassistive} + debugwriteln('**'+inttostr(avoice)+' '+string(atext)); +{$endif} + if atext <> '' then begin + c1:= atext[length(atext)]; + if (c1 in ['.',',',':',';','?','!']) then begin + postevent(tspeakevent.create(atext+' ',aoptions,avoice)); + //last punctuation not spoken, espeak bug? + end + else begin + postevent(tspeakevent.create(atext,aoptions,avoice)); + end; + end; + if so_wait in aoptions then begin + wait(); + end; +end; + +procedure tcustomespeakng.internalspeakcharacter(const achar: char32; + const aoptions: speakoptionsty; const avoice: int32); +begin + checkvoice(avoice); + checkerror(espeak_ng_speakcharacter(ord(achar))); +end; + +procedure tcustomespeakng.speakcharacter(const achar: char32; + const aoptions: speakoptionsty = []; const avoice: int32 = -1); +begin + if not (ss_connected in fstate) then begin + exit; + end; + if so_cancel in aoptions then begin + cancel(); + end; +{$ifdef mse_debugassistive} + debugwriteln('***'+inttostr(avoice)+' '+string(unicodechar(achar))); +{$endif} + postevent(tspeakevent.create(achar,aoptions,avoice)); + if so_wait in aoptions then begin + wait(); + end; +end; + +procedure tcustomespeakng.internalspeakkeyname(const akey: msestring; + const aoptions: speakoptionsty; const avoice: int32); +begin + checkvoice(avoice); + checkerror(espeak_ng_speakkeyname(pchar(stringtoutf8(akey)))); +end; + +procedure tcustomespeakng.speakkeyname(const akey: msestring; + const aoptions: speakoptionsty = []; const avoice: int32 = -1); +begin + if not (ss_connected in fstate) then begin + exit; + end; + if so_cancel in aoptions then begin + cancel(); + end; +{$ifdef mse_debugassistive} + debugwriteln('****'+inttostr(avoice)+' '+string(akey)); +{$endif} + if akey <> '' then begin + postevent(tspeakevent.createkey(akey,aoptions,avoice)); + end; + if so_wait in aoptions then begin + wait(); + end; +end; + +{ tvoice } + +constructor tvoice.create(aowner: tobject); +begin + fpitch:= 50; + frate:= espeakRATE_NORMAL; + fvolume:= 100; + frange:= 50; + fcapitals:= -1; + fwordgap:= -1; + inherited; +end; +{ +procedure tvoice.beginchange(); +begin + tcustomespeakng(fowner).lock(); +end; + +procedure tvoice.endchange(); +begin + tcustomespeakng(fowner).voicechanged(); + tcustomespeakng(fowner).unlock(); +end; +} +procedure tvoice.setgender(const avalue: genderty); +begin + if avalue <> fgender then begin + change(); + tcustomespeakng(fowner).beginchange(); + fgender:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setpitch(const avalue: int32); +begin + if avalue <> fpitch then begin + change(); + tcustomespeakng(fowner).beginchange(); + fpitch:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setrate(const avalue: int32); +begin + if avalue <> frate then begin + change(); + tcustomespeakng(fowner).beginchange(); + frate:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setvolume(const avalue: int32); +begin + if avalue <> fvolume then begin + change(); + tcustomespeakng(fowner).beginchange(); + fvolume:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setrange(const avalue: int32); +begin + if avalue <> frange then begin + change(); + tcustomespeakng(fowner).beginchange(); + frange:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setpunctuation(const avalue: punctuationty); +begin + if avalue <> fpunctuation then begin + change(); + tcustomespeakng(fowner).beginchange(); + fpunctuation:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setcapitals(const avalue: int32); +begin + if avalue <> fcapitals then begin + change(); + tcustomespeakng(fowner).beginchange(); + fcapitals:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setwordgap(const avalue: int32); +begin + if avalue <> fwordgap then begin + change(); + tcustomespeakng(fowner).beginchange(); + fwordgap:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setvoicename(const avalue: msestring); +begin + if avalue <> fvoicename then begin + change(); + tcustomespeakng(fowner).beginchange(); + fvoicename:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setvariant(const avalue: msestring); +begin + if avalue <> fvariant then begin + change(); + tcustomespeakng(fowner).beginchange(); + fvariant:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setlanguage(const avalue: msestring); +begin + if avalue <> flanguage then begin + change(); + tcustomespeakng(fowner).beginchange(); + flanguage:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setidentifier(const avalue: msestring); +begin + if avalue <> fidentifier then begin + change(); + tcustomespeakng(fowner).beginchange(); + fidentifier:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setage(const avalue: card8); +begin + if avalue <> fage then begin + change(); + tcustomespeakng(fowner).beginchange(); + fage:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setvariantnum(const avalue: card8); +begin + if avalue <> fvariantnum then begin + change(); + tcustomespeakng(fowner).beginchange(); + fvariantnum:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setpunctuationlist(const avalue: msestring); +begin + if avalue <> fpunctuationlist then begin + change(); + tcustomespeakng(fowner).beginchange(); + fpunctuationlist:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.change(); +begin + fid:= ''; +end; + +end. diff --git a/mseide-msegui/lib/common/container/msedatalist.pas b/mseide-msegui/lib/common/container/msedatalist.pas new file mode 100644 index 0000000..7c07bc1 --- /dev/null +++ b/mseide-msegui/lib/common/container/msedatalist.pas @@ -0,0 +1,7128 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedatalist; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifndef FPC} + {$ifdef mswindows} + {$define msestringsarenotrefcounted} + {$endif} +{$endif} + +uses + sysutils,classes,mclasses,msestrings,typinfo,msereal,msetypes,msestream, + mseclasses,mselist,mseglob,msearrayutils; + +type + + dataprocty = procedure(var data) of object; +{ + internallistoptionty = (ilo_needsfree,ilo_needscopy,ilo_needsinit, + ilo_nostreaming,ilo_nogridstreaming, + ilo_propertystreaming); + internallistoptionsty = set of internallistoptionty; +} + tdatalist = class; + tintegerdatalist = class; + + indexeventty = procedure(const sender: tdatalist; const index: integer) of object; +// listlineeventty = procedure (sender: tdatalist; index: integer) of object; + + blockcopymodety = (bcm_none,bcm_copy,bcm_init,bcm_rotate); +{ + idatalist = interface(inullinterface) + procedure listdestroyed(const sender: idatalist); + getlist: tdatalist; + end; + idatalistarty = array of idatalist; +} + copyprocty = procedure(const source,dest:pointer); + copy2procty = procedure(const source1,source2,dest:pointer); + + datalistarty = array of tdatalist; + + listlinkinfoty = record + name: string; //case sensitive + dirtystart,dirtystop: integer; + source: tdatalist; + end; + plistlinkinfoty = ^listlinkinfoty; + + idatalistclient = interface(iobjectlink) + function getobjectlinker: tobjectlinker; + procedure itemchanged(const sender: tdatalist; const aindex: integer); + end; + + dataliststatety = ( + dls_needsfree,dls_needscopy,dls_needsinit, + dls_nostreaming,dls_nogridstreaming, + dls_propertystreaming,dls_selectsetting, + dls_sorted,dls_sortio, + dls_forcenew, //used in tundolist + dls_remote, //used in ificomp datalist + dls_remotelock, + dls_rowdeleting, //used in treeitemeditlist + dls_facultative,dls_binarydata + ); + dataliststatesty = set of dataliststatety; + + tdatalist = class(tlinkedpersistent) + private + fbytelength: integer; //pufferlaenge + Fcapacity: integer; + fnochange: integer; + fonchange: notifyeventty; + fonitemchange: indexeventty; + fmaxcount: integer; + fringpointer: integer; + fcheckeditem: integer; + procedure setcapacity(value: integer); + procedure internalsetcount(value: integer; nochangeandinit: boolean); + procedure checkcapacity; //ev. reduktion des memory + procedure setmaxcount(const Value: integer); + procedure internalfreedata(index,anzahl: integer); //gibt daten frei falls notwendig + procedure internalcopyinstance(index,anzahl: integer); + function getsorted: boolean; + procedure setsorted(const Value: boolean); //datenkopieren + procedure internalcleardata(const index: integer); + procedure remoteitemchange(const alink: pointer); + procedure setcheckeditem(const avalue: integer); + function getfacultative: boolean; + procedure setfacultative(const avalue: boolean); + protected + fdeleting: integer; + fdatapo: pchar; + fsize: integer; + fcount: integer; + fscrolled: integer; + flinkdest: datalistarty; + fstate: dataliststatesty; + fintparam: integer; + frearanged: boolean; //set by rearange + fgridsortdescend: boolean; //set by tdatacols before sorting + function checkassigncompatibility(const source: tpersistent): boolean; virtual; + procedure checkindex1(const index: integer); + function assigndata(const source: tpersistent): boolean; + //false if not possible + procedure assigntodata(const dest: tdatalist); + procedure newbuffer(const acount: integer; const noinit: boolean; + const fillnull: boolean); + procedure clearbuffer; virtual; //buffer release + procedure setcount(const value: integer); virtual; + property nochange: integer read fnochange; + procedure internalgetasarray(const adatapo: pointer; const asize: integer); + procedure internalsetasarray(const source: pointer; const asize: integer; + const acount: integer); + procedure writedata(writer: twriter); + procedure readdata(reader: treader); + procedure readitem(const reader: treader; var value); virtual; + procedure writeitem(const writer: twriter; var value); virtual; + + procedure internalgetdata(index: integer; out ziel); + procedure internalsetdata(index: integer; const quelle); + procedure internalfill(const anzahl: integer; const wert); + procedure getdefaultdata(var dest); //out is not possible because of + //FPC bug 20962 + procedure getgriddefaultdata(var dest); virtual; + procedure getdata(index: integer; var dest); + procedure getgriddata(index: integer; var dest); virtual; + procedure setdata(index: integer; const source); + procedure setgriddata(index: integer; const source); virtual; + function getstatdata(const index: integer): msestring; virtual; + procedure setstatdata(const index: integer; const value: msestring); virtual; + procedure writestate(const writer; const name: msestring); virtual; + //typeless because of recursive interface + procedure readstate(const reader; const acount: integer; + const name: msestring); virtual; + procedure writeappendix(const writer; const aname: msestring); virtual; + procedure readappendix(const reader; const aname: msestring); virtual; + + function poptopdata(var ziel): boolean; //top of stack, false if empty + function popbottomdata(var ziel): boolean; //bottom of stack, false if empty + procedure pushdata(const quelle); + procedure checkbuffersize(increment: integer); //fuer ringpuffer + procedure internalinsertdata(index: integer; const quelle; + const docopy: boolean); + procedure insertdata(const index: integer; const quelle); + procedure defineproperties(const propname: string; + const filer: tfiler); + procedure defineproperties(filer: tfiler); override; + procedure freedata(var data); virtual; //gibt daten frei + procedure beforecopy(var data); virtual; + procedure aftercopy(var data); virtual; + procedure initinstance(var data); virtual; //fuer neue zeilen aufgerufen + function internaladddata(const quelle; docopy: boolean): integer; + function adddata(const quelle): integer; + function compare(const l,r): integer; virtual; + function comparecaseinsensitive(const l,r): integer; virtual; + function getdefault: pointer; virtual; //nil fuer null + procedure normalizering; //macht ringpointer = null + procedure blockcopymovedata(fromindex,toindex: integer; + const acount: integer; const mode: blockcopymodety); + procedure initdata1(const afree: boolean; index: integer; + const acount: integer); + //initialisiert mit defaultwert + procedure forall(startindex: integer; const count: integer; + const proc: dataprocty); + procedure doitemchange(const index: integer); virtual; + procedure dochange; virtual; + procedure internaldeletedata(index: integer; dofree: boolean); + + function getlinkdatatypes(const atag: integer): listdatatypesty; virtual; + procedure initsource(var asource: listlinkinfoty); + procedure removesource(var asource: listlinkinfoty); + procedure checklistdestroyed(var ainfo: listlinkinfoty; + const sender: tdatalist); + procedure unlinksource(var alink: listlinkinfoty); + function internallinksource(const source: tdatalist; + const atag: integer; var variable: tdatalist): boolean; + function sourceischanged(const asource: listlinkinfoty): boolean; + function checksourcechange(var ainfo: listlinkinfoty; + const sender: tdatalist; const aindex: integer): boolean; + function checksourcecopy(var ainfo: listlinkinfoty; + const copyproc: copyprocty): boolean; + function checksourcecopy2(var ainfo: listlinkinfoty; + const source2: tdatalist; const copyproc: copy2procty): boolean; + procedure internalrearange(arangelist: pinteger; const acount: integer); + function islinked(const asource: tdatalist): boolean; + procedure datadeleted(const aindex: integer; const acount: integer); + procedure datainserted(const aindex: integer; const acount: integer); + procedure datamoved(const fromindex: integer; const toindex: integer; + const acount: integer); virtual; + procedure setitemselected(const row: integer; const value: boolean); virtual; + //iificlient + function getifidatatype(): listdatatypety virtual; + public + constructor create; override; + destructor destroy; override; + + //idatalist + procedure listdestroyed(const sender: tdatalist); virtual; + procedure sourcechange(const sender: tdatalist; + const aindex: integer); virtual; + + procedure linkclient(const aclient: idatalistclient); + procedure unlinkclient(const aclient: idatalistclient); + + function getsourcecount: integer; virtual; + function getsourceinfo(const atag: integer): plistlinkinfoty; virtual; + function getsourcename(const atag: integer): string; + procedure linksource(const source: tdatalist; const atag: integer); virtual; + function canlink(const asource: tdatalist; + const atag: integer): boolean; virtual; + + property size: integer read fsize; + property state: dataliststatesty read fstate; + function datapo: pointer; //calls normalizering, + //do not use in copyinstance,initinstance,freedata + function datahighpo: pointer; //points to last item + function getitempo(index: integer): pointer; + //invalid after capacity change + function getastext(const index: integer): msestring; virtual; + procedure setastext(const index: integer; const avalue: msestring); virtual; + + procedure assign(sender: tpersistent); override; + procedure assignb(const source: tdatalist); virtual; + //assign with second value if possible, exception otherwise + procedure assigntob(const dest: tdatalist); virtual; + //assignto with second value if possible, exception otherwise + function getdatablock(const source: pointer; const destsize: integer): integer; + //returns size of datablock + function setdatablock(const dest: pointer; const sourcesize: integer; + const acount: integer): integer; + //returns size of datablock + procedure change(const index: integer); virtual; + //index -1 -> undefined + class function datatype: listdatatypety; virtual; + procedure checkindexrange(const aindex: integer; const acount: integer = 1); + procedure checkindex(var index: integer); + //bringt absolute zeilennummer in ringpuffer + procedure beginupdate; virtual; + procedure endupdate; virtual; + procedure incupdate; + procedure decupdate; + function updating: boolean; + procedure clear; virtual;//loescht daten + procedure initdata(const index,anzahl: integer); + //anzahl -> count, initialisiert mit defaultwert + procedure cleardata(index: integer); + function deleting: boolean; + function checkwritedata(const filer: tfiler): boolean; virtual; + + procedure rearange(const arangelist: tintegerdatalist); overload; + procedure rearange(const arangelist: integerarty); overload; + procedure movedata(const fromindex,toindex: integer); + procedure blockmovedata(const fromindex,toindex,count: integer); + procedure blockcopydata(const fromindex,toindex,count: integer); + procedure deletedata(const index: integer); + procedure deleteitems(index,acount: integer); virtual; + procedure insertitems(index,acount: integer); virtual; + function empty(const index: integer): boolean; virtual; //true wenn leer + + function sort(const comparefunc: sortcomparemethodty; + out arangelist: integerarty; + const dorearange: boolean): boolean; + function sort(out arangelist: integerarty; + const dorearange: boolean): boolean; + function sort(const compareproc: sortcomparemethodty): boolean; + function sort: boolean; //true if changed + function sortcaseinsensitive: boolean; //true if changed + function sortcaseinsensitive(out arangelist: integerarty; + const dorearange: boolean): boolean; + + procedure clean(const start,stop: integer); virtual; + procedure clearmemberitem(const subitem: integer; + const index: integer); virtual; + procedure setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); virtual; + + + property count: integer read Fcount write Setcount; //anzahl zeilen + property capacity: integer read Fcapacity write Setcapacity; + property onchange: notifyeventty read fonchange write fonchange; + property onitemchange: indexeventty read fonitemchange write fonitemchange; + + property maxcount: integer read fmaxcount + write setmaxcount default bigint; //for ring buffer + property sorted: boolean read getsorted write setsorted; + property checkeditem: integer read fcheckeditem write setcheckeditem; + //-1 if none + property facultative: boolean read getfacultative + write setfacultative default false; + //used by objecttovalues() + end; + + pdatalist = ^tdatalist; + + tnonedatalist = class(tdatalist) + public + class function datatype: listdatatypety; override; + end; + + subdatainfoty = record + list: tdatalist; + subindex: integer; //0 = main + end; + subdatainfoarty = array of subdatainfoty; + + tintegerdatalist = class(tdatalist) + private + function Getitems(const index: integer): integer; + procedure Setitems(const index: integer; const Value: integer); + procedure setasarray(const avalue: integerarty); + function getasarray: integerarty; + procedure setasbooleanarray(const avalue: booleanarty); + function getasbooleanarray: booleanarty; + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + procedure writeappendix(const writer; const aname: msestring); override; + procedure readappendix(const reader; const aname: msestring); override; + public + min: integer; + max: integer; + notcheckedvalue: integer; //used for statread + constructor create; override; + class function datatype: listdatatypety; override; + function empty(const index: integer): boolean; override; //true wenn leer + function add(const value: integer): integer; + procedure insert(const index: integer; const item: integer); + procedure number(const start,step: integer); //numeriert daten + function find(value: integer): integer; //bringt index, -1 wenn nicht gefunden + procedure fill(acount: integer; const defaultvalue: integer); overload; + procedure fill(const defaultvalue: integer); overload; + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; const avalue: msestring); override; + + property asarray: integerarty read getasarray write setasarray; + property asbooleanarray: booleanarty read getasbooleanarray write setasbooleanarray; + property items[const index: integer]: integer read Getitems write Setitems; default; + end; + + tbooleandatalist = class(tintegerdatalist) + private + procedure setasarray(const avalue: longboolarty); + function getasarray: longboolarty; + function getitems(const index: integer): boolean; + procedure setitems(const index: integer; const avalue: boolean); + public + procedure fill(acount: integer; const defaultvalue: boolean); overload; + procedure fill(const defaultvalue: boolean); overload; + property asarray: longboolarty read getasarray + write setasarray; + property items[const index: integer]: boolean read Getitems write Setitems; default; + end; + + tint64datalist = class(tdatalist) + private + function Getitems(index: integer): int64; + procedure Setitems(index: integer; const avalue: int64); + procedure setasarray(const value: int64arty); + function getasarray: int64arty; + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + public + constructor create; override; + class function datatype: listdatatypety; override; +// procedure assign(source: tpersistent); override; + function empty(const index: integer): boolean; override; //true wenn leer + function add(const avalue: int64): integer; + procedure insert(const index: integer; const avalue: int64); + function find(const avalue: int64): integer; //bringt index, -1 wenn nicht gefunden + procedure fill(const acount: integer; const defaultvalue: int64); overload; + procedure fill(const defaultvalue: int64); overload; + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; const avalue: msestring); override; + + property asarray: int64arty read getasarray write setasarray; + property items[index: integer]: int64 read Getitems write Setitems; default; + end; + + tcurrencydatalist = class(tdatalist) + private + function Getitems(index: integer): currency; + procedure Setitems(index: integer; const avalue: currency); + procedure setasarray(const value: currencyarty); + function getasarray: currencyarty; + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + public + constructor create; override; + class function datatype: listdatatypety; override; +// procedure assign(source: tpersistent); override; + function empty(const index: integer): boolean; override; //true wenn leer + function add(const avalue: currency): integer; + procedure insert(const index: integer; const avalue: currency); + function find(const avalue: currency): integer; //bringt index, -1 wenn nicht gefunden + procedure fill(const acount: integer; const defaultvalue: currency); overload; + procedure fill(const defaultvalue: currency); overload; + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; const avalue: msestring); override; + + property asarray: currencyarty read getasarray write setasarray; + property items[index: integer]: currency read Getitems write Setitems; default; + end; + + tenumdatalist = class(tintegerdatalist) + private + fgetdefault: getintegereventty; + fdefaultval: integer; + protected + function getdefault: pointer; override; + public + constructor create(agetdefault: getintegereventty); reintroduce; + function empty(const index: integer): boolean; override; //true wenn leer + end; + + tenum64datalist = class(tint64datalist) + private + fgetdefault: getint64eventty; + fdefaultval: int64; + protected + function getdefault: pointer; override; + public + constructor create(agetdefault: getint64eventty); reintroduce; + function empty(const index: integer): boolean; override; //true wenn leer + end; + + tcomplexdatalist = class; + + trealdatalist = class(tdatalist) + private + fdefaultzero: boolean; + fdefaultval: realty; + facceptempty: boolean; + function Getitems(index: integer): realty; + procedure Setitems(index: integer; const Value: realty); + function getasarray: realarty; + procedure setasarray(const data: realarty); + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function getdefault: pointer; override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + procedure copytocomplex(dest: pcomplexty); + public + min: realty; + max: realty; + constructor create; override; + class function datatype: listdatatypety; override; + procedure assignre(const source: tcomplexdatalist); overload; + procedure assignim(const source: tcomplexdatalist); overload; + procedure assignre(const source: complexarty); overload; + procedure assignim(const source: complexarty); overload; + procedure assigntore(const dest: tcomplexdatalist); overload; + procedure assigntoim(const dest: tcomplexdatalist); overload; + procedure assigntore(var dest: complexarty); overload; + procedure assigntoim(var dest: complexarty); overload; + function empty(const index: integer): boolean; override; + function add(const value: real): integer; + procedure insert(index: integer; const item: realty); + procedure number(start,step: real); + procedure fill(acount: integer; const defaultvalue: realty); overload; + procedure fill(const defaultvalue: realty); overload; + procedure minmax(out minval,maxval: realty); + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; const avalue: msestring); override; + + property asarray: realarty read getasarray write setasarray; + property items[index: integer]: realty read Getitems write Setitems; default; + property defaultzero: boolean read fdefaultzero + write fdefaultzero default false; + property acceptempty: boolean read facceptempty + write facceptempty default false; + end; + + tdatetimedatalist = class(trealdatalist) + protected + function getdefault: pointer; override; + public + class function datatype: listdatatypety; override; + function empty(const index: integer): boolean; override; //true wenn leer + procedure fill(acount: integer; const defaultvalue: tdatetime); overload; + procedure fill(const defaultvalue: tdatetime); overload; + end; + + tcomplexdatalist = class(tdatalist) + private + fdefaultzero: boolean; + fdefaultval: complexty; + function Getitems(const index: integer): complexty; + procedure Setitems(const index: integer; const Value: complexty); + procedure setasarray(const data: complexarty); + function getasarray: complexarty; + function getasarrayre: realarty; + procedure setasarrayre(const avalue: realarty); + function getasarrayim: realarty; + procedure setasarrayim(const avalue: realarty); + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function getdefault: pointer; override; + procedure assignto(dest: tpersistent); override; + public + min: realty; //for property editor + max: realty; + + constructor create; override; + class function datatype: listdatatypety; override; + procedure assign(source: tpersistent); override; + procedure assignb(const source: tdatalist); override; + procedure assignre(const source: trealdatalist); + procedure assignim(const source: trealdatalist); + procedure assigntoa(const dest: tdatalist); + procedure assigntob(const dest: tdatalist); override; + function add(const value: complexty): integer; + procedure insert(const index: integer; const item: complexty); + function empty(const index: integer): boolean; override; //true wenn leer + procedure fill(const acount: integer; const defaultvalue: complexty); overload; + procedure fill(const defaultvalue: complexty); overload; + + property asarray: complexarty read getasarray write setasarray; + property asarrayre: realarty read getasarrayre write setasarrayre; + property asarrayim: realarty read getasarrayim write setasarrayim; + property items[const index: integer]: complexty read Getitems write Setitems; default; + property defaultzero: boolean read fdefaultzero + write fdefaultzero default false; + end; + + realintty = record + rea: realty; + int: integer; + end; + prealintty = ^realintty; + realintarty = array of realintty; + realintaty = array[0..0] of realintty; + + trealintdatalist = class(trealdatalist) + private + fdefaultval1: realintty; + function Getdoubleitems(index: integer): realintty; + procedure Setdoubleitems(index: integer; const Value: realintty); + function Getitemsb(index: integer): integer; + procedure Setitemsb(index: integer; const Value: integer); + function getasarray: realintarty; + procedure setasarray(const data: realintarty); + function getasarraya: realarty; + procedure setasarraya(const data: realarty); + function getasarrayb: integerarty; + procedure setasarrayb(const data: integerarty); + protected + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + function getdefault: pointer; override; + public + constructor create; override; +// procedure assign(source: tpersistent); override; + procedure assignb(const source: tdatalist); override; + procedure assigntob(const dest: tdatalist); override; + + class function datatype: listdatatypety; override; + function add(const valuea: realty; const valueb: integer = 0): integer; overload; + function add(const value: realintty): integer; overload; + procedure insert(const index: integer; const item: realty; + const itemint: integer); + procedure fill(const acount: integer; const defaultvalue: realty; + const defaultint: integer); overload; + procedure fill(const defaultvalue: realty; + const defaultint: integer); overload; + + property asarray: realintarty read getasarray write setasarray; + property asarraya: realarty read getasarraya write setasarraya; + property asarrayb: integerarty read getasarrayb write setasarrayb; + property itemsb[index: integer]: integer read Getitemsb write Setitemsb; + property doubleitems[index: integer]: realintty read Getdoubleitems + write Setdoubleitems; default; + end; + + tpointerdatalist = class(tdatalist) + private + function Getitems(index: integer): pointer; + procedure Setitems(index: integer; const Value: pointer); + function getasarray: pointerarty; + procedure setasarray(const data: pointerarty); + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + public + constructor create; override; + property items[index: integer]: pointer read Getitems write Setitems; default; + property asarray: pointerarty read getasarray write setasarray; + end; + + tdynamicdatalist = class(tdatalist) + protected + public + constructor create; override; + end; + + tdynamicpointerdatalist = class(tdynamicdatalist) + public + constructor create; override; + end; + + tansistringdatalist = class(tdynamicpointerdatalist) + private + function Getitems(index: integer): ansistring; + procedure Setitems(index: integer; const Value: ansistring); + function getasarray: stringarty; + procedure setasarray(const avalue: stringarty); + function getasmsestringarray: msestringarty; + procedure setasmsestringarray(const avalue: msestringarty); + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + procedure freedata(var data); override; //gibt daten frei + procedure beforecopy(var data); override; + procedure assignto(dest: tpersistent); override; + function compare(const l,r): integer; override; + function comparecaseinsensitive(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + function textlength: integer; + public + class function datatype: listdatatypety; override; + procedure assign(source: tpersistent); override; + procedure assignopenarray(const data: array of ansistring); +// procedure assignarray(const data: stringarty); overload; +/// procedure assignarray(const data: msestringarty); overload; + procedure insert(index: integer; const item: ansistring); + function add(const value: ansistring): integer; overload; + function addtext(const value: ansistring): integer; + //returns added linecount + function empty(const index: integer): boolean; override; //true wenn leer + procedure fill(acount: integer; const defaultvalue: ansistring); + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; const avalue: msestring); override; + + function gettext: ansistring; + procedure settext(const avalue: ansistring); + + property items[index: integer]: ansistring read Getitems write + setitems; default; + property asarray: stringarty read getasarray write setasarray; + property asmsestringarray: msestringarty read getasmsestringarray + write setasmsestringarray; + end; + + tmsestringdatalist = class; + + addcharoptionty = (aco_processeditchars,aco_stripescsequence, + aco_multilinepara); //breaks lines by maxchars in a + //single list row + addcharoptionsty = set of addcharoptionty; + + tpoorstringdatalist = class(tdynamicpointerdatalist) + private + function Getitems(index: integer): msestring; + procedure Setitems(index: integer; const Value: msestring); + function getasarray: msestringarty; + procedure setasarray(const data: msestringarty); + function getasstringarray: stringarty; + procedure setasstringarray(const data: stringarty); + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + procedure freedata(var data); override; //gibt daten frei +{$ifdef msestringsarenotrefcounted} + procedure aftercopy(var data); override; +{$else} + procedure beforecopy(var data); override; +{$endif} + procedure assignto(dest: tpersistent); override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + function getnoparagraphs(index: integer): boolean; virtual; + function textlength: integer; + public + feditcharindex: integer; + procedure assign(source: tpersistent); override; + procedure assignopenarray(const data: array of msestring); overload; +// procedure assignarray(const data: stringarty); overload; +// procedure assignarray(const data: msestringarty); overload; + procedure insert(const index: integer; const item: msestring); virtual; abstract; + function add(const value: tmsestringdatalist): integer; overload; + function add(const value: msestring): integer; overload; virtual; abstract; + function add(const avalue: msestring; const anoparagraph: boolean): integer; + overload; virtual; + function addchars(const value: msestring; + const aoptions: addcharoptionsty = [aco_processeditchars]; + const maxchars: integer = 0): integer; + //adds characters to last row, returns index + //maxchars = 0 -> no limitation, inserts line breaks otherwise + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; + const avalue: msestring); override; + + function gettext: msestring; + procedure settext(const avalue: msestring); + + function indexof(const value: msestring): integer; + function empty(const index: integer): boolean; override; //true wenn leer + function concatstring(const delim: msestring = ''; + const separator: msestring = ''; + const separatornoparagraph: msestring = ''): msestring; + procedure loadfromfile(const filename: filenamety; + const aencoding: charencodingty = ce_locale); + procedure loadfromstream(const stream: ttextstream); + procedure savetofile(const filename: filenamety; + const aencoding: charencodingty = ce_locale); + procedure savetostream(const stream: ttextstream); + function dataastextstream: ttextstream; + //chars truncated to 8bit, not null terminated + + property asarray: msestringarty read getasarray write setasarray; + property asstringarray:stringarty read getasstringarray write setasstringarray; + property items[index: integer]: msestring read Getitems write Setitems; default; + end; + + stringdatalistoptionty = (sdo_naturalsort); + stringdatalistoptionsty = set of stringdatalistoptionty; + + tmsestringdatalist = class(tpoorstringdatalist) + private + foptions: stringdatalistoptionsty; + protected + function compare(const l,r): integer; override; + function comparecaseinsensitive(const l,r): integer; override; + public + class function datatype: listdatatypety; override; + function add(const value: msestring): integer; override; + procedure insert(const index: integer; const item: msestring); override; + procedure fill(acount: integer; const defaultvalue: msestring); + published + property options: stringdatalistoptionsty read foptions + write foptions default []; + end; + + tdoublemsestringdatalist = class(tpoorstringdatalist) + private + function Getdoubleitems(index: integer): doublemsestringty; + procedure Setdoubleitems(index: integer; const Value: doublemsestringty); + function Getitemsb(index: integer): msestring; + procedure Setitemsb(index: integer; const Value: msestring); + function getasarray: doublemsestringarty; + procedure setasarray(const data: doublemsestringarty); + function getasarraya: msestringarty; + procedure setasarraya(const data: msestringarty); + function getasarrayb: msestringarty; + procedure setasarrayb(const data: msestringarty); + protected + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + function comparecaseinsensitive(const l,r): integer; override; + procedure freedata(var data); override; //gibt daten frei +{$ifdef msestringsarenotrefcounted} + procedure aftercopy(var data); override; +{$else} + procedure beforecopy(var data); override; +{$endif} + public + constructor create; override; +// procedure assign(source: tpersistent); override; + procedure assignb(const source: tdatalist); override; + procedure assigntob(const dest: tdatalist); override; + + class function datatype: listdatatypety; override; + function add(const value: msestring): integer; overload; override; + function add(const valuea: msestring; const valueb: msestring = ''): integer; overload; + function add(const value: doublemsestringty): integer; overload; + procedure insert(const index: integer; const item: msestring); override; + procedure fill(const acount: integer; const defaultvalue: msestring); + + property asarray: doublemsestringarty read getasarray write setasarray; + property asarraya: msestringarty read getasarraya write setasarraya; + property asarrayb: msestringarty read getasarrayb write setasarrayb; + property itemsb[index: integer]: msestring read Getitemsb write Setitemsb; + property doubleitems[index: integer]: doublemsestringty read Getdoubleitems + write Setdoubleitems; default; + end; + + msestringintty = record + mstr: msestring; + int: integer; + end; + pmsestringintty = ^msestringintty; + msestringintarty = array of msestringintty; + msestringintaty = array[0..0] of msestringintty; + pmsestringintaty = ^msestringintaty; + + tmsestringintdatalist = class(tpoorstringdatalist) + private + function Getdoubleitems(index: integer): msestringintty; + procedure Setdoubleitems(index: integer; const Value: msestringintty); + function Getitemsb(index: integer): integer; + procedure Setitemsb(index: integer; const Value: integer); + function getasarray: msestringintarty; + procedure setasarray(const data: msestringintarty); + function getasarraya: msestringarty; + procedure setasarraya(const data: msestringarty); + function getasarrayb: integerarty; + procedure setasarrayb(const data: integerarty); + protected + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + function comparecaseinsensitive(const l,r): integer; override; +// procedure freedata(var data); override; +// procedure copyinstance(var data); override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + public + constructor create; override; +// procedure assign(source: tpersistent); override; + procedure assignb(const source: tdatalist); override; + procedure assigntob(const dest: tdatalist); override; + + class function datatype: listdatatypety; override; + function add(const value: msestring): integer; override; + function add(const valuea: msestring; const valueb: integer): integer; overload; + function add(const value: msestringintty): integer; overload; + procedure insert(const index: integer; const item: msestring); + overload; override; + procedure insert(const index: integer; const item: msestring; + const itemint: integer); reintroduce; overload; + procedure fill(const acount: integer; const defaultvalue: msestring; + const defaultint: integer); + + property asarray: msestringintarty read getasarray write setasarray; + property asarraya: msestringarty read getasarraya write setasarraya; + property asarrayb: integerarty read getasarrayb write setasarrayb; + property itemsb[index: integer]: integer read Getitemsb write Setitemsb; + property doubleitems[index: integer]: msestringintty read Getdoubleitems + write Setdoubleitems; default; + end; + +const + foldhiddenbit = 7; + foldhiddenmask = 1 shl foldhiddenbit; + currentfoldhiddenbit = 6; + currentfoldhiddenmask = 1 shl currentfoldhiddenbit; + foldlevelmask = byte(not (foldhiddenmask or currentfoldhiddenmask)); + foldissumbit = 0; + foldissummask = $01; + rowstatemask = $7f; + + selectedcolmax = 30; //32 bitset, bit31 -> whole row + wholerowselectedmask = $80000000; + mergedcolmax = 32; + mergedcolall = $ffffffff; + +type + rowstatenumty = -1..126; //msb = row readonly flag for rowfontstate, + //reserved for rowcolorstate (used in tcustomstringgrid) +const + rowstatenummask = $7f; +type + + rowinfolevelty = (ril_normal,ril_colmerge,ril_rowheight); + rowstatety = packed record + selected: longword; //bitset lsb = col 0, msb-1 = col 30, msb = whole row + //adressed by fcreateindex + color: byte; //index in rowcolors, 0 = none, 1 = rowcolors[0] + font: byte; //index in rowfonts, 0 = none, 1 = rowfonts[0] + fold: byte; // hc nnnnnn h = hidden c = current hidden, + // nnnnnn = fold level, 0 -> top + flags: byte; // 0000000s s = issum + end; + prowstatety = ^rowstatety; + rowstateaty = array[0..0] of rowstatety; + prowstateaty = ^rowstateaty; + + colmergety = packed record + merged: longword; //bitset lsb = col 1, msb = col32, + // $ffffffff = first col fills whole row + //addressed by column index + end; + rowstatecolmergety = packed record + normal: rowstatety; + colmerge: colmergety; + end; + prowstatecolmergety = ^rowstatecolmergety; + rowstatecolmergeaty = array[0..0] of rowstatecolmergety; + prowstatecolmergeaty = ^rowstatecolmergeaty; + + rowheightty = packed record + height: integer; + ypos: integer; + linewidth: byte; //0 -> default, 1 -> 0, 2 -> 1... + linecolor: byte; //index in rowcolors, 0 = none, 1 = rowcolors[0] + linecolorfix: byte; //index in rowcolors, 0 = none, 1 = rowcolors[0] + end; + rowstaterowheightty = packed record + normal: rowstatety; + colmerge: colmergety; + rowheight: rowheightty; + end; + prowstaterowheightty = ^rowstaterowheightty; + rowstaterowheightaty = array[0..0] of rowstaterowheightty; + prowstaterowheightaty = ^rowstaterowheightaty; + + rowstatememberty = (rsm_select,rsm_color,rsm_font,rsm_readonly, + rsm_foldlevel,rsm_foldissum, + rsm_hidden,rsm_merged,rsm_height); + +const + rowinfosizes: array[rowinfolevelty] of integer = + (sizeof(rowstatety),sizeof(rowstatecolmergety), + sizeof(rowstaterowheightty)); +type + rowlinewidthty = -1..254; //-1 = default + tcustomrowstatelist = class(tdatalist) + private + function getrowstate(const index: integer): rowstatety; + procedure setrowstate(const index: integer; const Value: rowstatety); + function getrowstatecolmerge(const index: integer): rowstatecolmergety; + procedure setrowstatecolmerge(const index: integer; + const Value: rowstatecolmergety); + function getrowstaterowheight(const index: integer): rowstaterowheightty; + procedure setrowstaterowheight(const index: integer; + const Value: rowstaterowheightty); + function getfoldinfoar: bytearty; + function getcolor(const index: integer): rowstatenumty; + procedure setcolor(const index: integer; const avalue: rowstatenumty); + function getfont(const index: integer): rowstatenumty; + procedure setfont(const index: integer; const avalue: rowstatenumty); + function getreadonly(const index: integer): boolean; + procedure setreadonly(const index: integer; const avalue: boolean); + function getflag1(const index: integer): boolean; + procedure setflag1(const index: integer; const avalue: boolean); + function getselected(const index: integer): longword; + procedure setselected(const index: integer; const avalue: longword); + function getmerged(const index: integer): longword; + procedure setmerged(const index: integer; const avalue: longword); + function getlinecolor(const index: integer): rowstatenumty; + procedure setlinecolor(const index: integer; const avalue: rowstatenumty); + function getlinecolorfix(const index: integer): rowstatenumty; + procedure setlinecolorfix(const index: integer; const avalue: rowstatenumty); + function getcolorar: integerarty; + procedure setcolorar(const avalue: integerarty); + function getfontar: integerarty; + procedure setfontar(const avalue: integerarty); + function getfoldlevelar: integerarty; + procedure setfoldlevelar(const avalue: integerarty); + procedure setfoldlevel(const index: integer; const avalue: byte); + function gethiddenar: longboolarty; + procedure sethiddenar(const avalue: longboolarty); + function getfoldissumar: longboolarty; + procedure setfoldissumar(const avalue: longboolarty); + protected + finfolevel: rowinfolevelty; + procedure sethidden(const index: integer; const avalue: boolean); virtual; + procedure setfoldissum(const index: integer; const avalue: boolean); virtual; + procedure checkdirty(const arow: integer); virtual; + function gethidden(const index: integer): boolean; + function getfoldlevel(const index: integer): byte; + function getfoldissum(const index: integer): boolean; + function getheight(const index: integer): integer; + function getlinewidth(const index: integer): rowlinewidthty; + procedure checkinfolevel(const wantedlevel: rowinfolevelty); + procedure initdirty; virtual; + procedure recalchidden; virtual; + function checkassigncompatibility(const source: tpersistent): boolean; override; + procedure readstate(const reader; const acount: integer; + const name: msestring); override; + property flag1[const index: integer]: boolean read getflag1 + write setflag1; + public + constructor create; overload; override; + constructor create(const ainfolevel: rowinfolevelty); reintroduce; overload; + function checkwritedata(const filer: tfiler): boolean; override; + procedure change(const aindex: integer); override; + procedure assign(source: tpersistent); override; + property infolevel: rowinfolevelty read finfolevel; + class function datatype: listdatatypety; override; + function datapocolmerge: pointer; + function dataporowheight: pointer; + function getitempo(const index: integer): prowstatety; + function getitempocolmerge(const index: integer): prowstatecolmergety; + function getitemporowheight(const index: integer): prowstaterowheightty; + property items[const index: integer]: rowstatety read getrowstate + write setrowstate; default; + property itemscolmerge[const index: integer]: rowstatecolmergety + read getrowstatecolmerge write setrowstatecolmerge; + property itemsrowheight[const index: integer]: rowstaterowheightty + read getrowstaterowheight write setrowstaterowheight; + + function mergecols(const arow: integer; const astart: longword; + const acount: longword): boolean; + function unmergecols(const arow: integer): boolean; + + property color[const index: integer]: rowstatenumty read getcolor + write setcolor; + property colorar: integerarty read getcolorar write setcolorar; + property font[const index: integer]: rowstatenumty read getfont + write setfont; + property fontar: integerarty read getfontar write setfontar; + property readonly[const index: integer]: boolean read getreadonly + write setreadonly; + property selected[const index: integer]: longword read getselected + write setselected; + property hidden[const index: integer]: boolean read gethidden write sethidden; + property hiddenar: longboolarty read gethiddenar write sethiddenar; + property foldlevel[const index: integer]: byte read getfoldlevel + write setfoldlevel; //0..64 + property foldlevelar: integerarty read getfoldlevelar write setfoldlevelar; + property foldissum[const index: integer]: boolean read getfoldissum + write setfoldissum; + property foldissumar: longboolarty read getfoldissumar write setfoldissumar; + + property height[const index: integer]: integer read getheight; + property merged[const index: integer]: longword read getmerged + write setmerged; + property linewidth[const index: integer]: rowlinewidthty + read getlinewidth{ write setlineheight}; + property linecolorfix[const index: integer]: rowstatenumty + read getlinecolorfix write setlinecolorfix; + property linecolor[const index: integer]: rowstatenumty + read getlinecolor write setlinecolor; + property foldinfoar: bytearty read getfoldinfoar; + end; + + createobjecteventty = procedure(const sender: tobject; var obj: tobject) of object; + + tobjectdatalist = class(tdynamicpointerdatalist) + private + foncreateobject: createobjecteventty; + function Getitems(index: integer): tobject; + procedure setitems(index: integer; const Value: tobject); + protected + fitemclass: tclass; + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure checkitemclass(const aitem: tobject); + procedure freedata(var data); override; +// procedure copyinstance(var data); override; + procedure initinstance(var data); override; + procedure docreateobject(var instance: tobject); virtual; + public + constructor create; overload; override; + function add(const aitem: tobject): integer; + function extract(const index: integer): tobject; //no finalize + property oncreateobject: createobjecteventty read foncreateobject write foncreateobject; + property items[index: integer]: tobject read Getitems write setitems; default; + end; + + datalistclassty = class of tdatalist; + +// +// array util functions moved to lib/kernel/msearrayutils.pas +// +type + getintegeritemfuncty = function(const index: integer): integer of object; + +function datalisttocomplexar(const re,im: trealdatalist): complexarty; + +function newidentnum(const count: integer; + getfunc: getintegeritemfuncty): integer; + //returns lowest not used value +function getdatalistclass(const adatatype: listdatatypety): datalistclassty; +procedure registerdatalistclass(const adatatype: listdatatypety; + const aclass: datalistclassty); + +procedure setremotedatalist(const aintf: idatalistclient; + const source: tdatalist; var dest: tdatalist); + +implementation +uses + rtlconsts,msestreaming,msesys,msestat,msebits,msefloattostr,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +var + datalistclasses: array[listdatatypety] of datalistclassty = +//dl_none,dl_integer, dl_int64, dl_currency, + (nil,tintegerdatalist,tint64datalist,tcurrencydatalist, +//dl_real, dl_realint, dl_realsum + trealdatalist,trealintdatalist,nil, +//dl_datetime, + trealdatalist, +//dl_pointer, + tpointerdatalist, +//dl_ansistring, dl_msestring, dl_doublemsestring, + tansistringdatalist,tmsestringdatalist,tdoublemsestringdatalist, +//dl_msestringint + tmsestringintdatalist, +//dl_complex, dl_rowstate + tcomplexdatalist,tcustomrowstatelist, +//dl_custom + nil); + +procedure setremotedatalist(const aintf: idatalistclient; + const source: tdatalist; var dest: tdatalist); +begin + aintf.getobjectlinker.setlinkedvar(aintf,source,tlinkedpersistent(dest), + typeinfo(idatalistclient)); + if dest <> nil then begin + include(dest.fstate,dls_remote); + aintf.itemchanged(dest,-1); + end; +end; + +function getdatalistclass(const adatatype: listdatatypety): datalistclassty; +begin + if adatatype <= high(datalistclasses) then begin + result:= datalistclasses[adatatype]; + end + else begin + result:= nil; + end; +end; + +procedure registerdatalistclass(const adatatype: listdatatypety; + const aclass: datalistclassty); +begin + if adatatype > high(datalistclasses) then begin + raise exception.create('Invalid datalist class.'); + end; + datalistclasses[adatatype]:= aclass; +end; + +function datalisttocomplexar(const re,im: trealdatalist): complexarty; +var + int1: integer; + pre,pim: preal; + pres: pcomplexty; + intre,intim: integer; +begin + int1:= re.count; + if im.count < int1 then begin + int1:= im.count; + end; + setlength(result,int1); + pre:= re.datapo; + intre:= re.size; + pim:= im.datapo; + intim:= im.size; + pres:= pointer(result); + for int1:= high(result) downto 0 do begin + pres^.re:= pre^; + pres^.im:= pim^; + inc(pchar(pre),intre); + inc(pchar(pim),intim); + inc(pchar(pres),sizeof(complexty)); + end; +end; + +function newidentnum(const count: integer; getfunc: getintegeritemfuncty): integer; +var + list1: tintegerdatalist; + int1: integer; +begin + list1:= tintegerdatalist.create; + try + list1.count:= count; + for int1:= 0 to count - 1 do begin + list1[int1]:= getfunc(int1); + end; + list1.sort; + for int1:= 0 to count -1 do begin + if list1[int1] > int1 then begin + result:= int1; + exit; + end; + end; + result:= count; + finally + list1.Free; + end; +end; + +procedure variantsnotsupported; +begin + raise exception.create('Variants not supported'); +end; + +{ tdatalist } + +constructor tdatalist.create; +begin + fsize:= 1; + fmaxcount:= bigint; +// fsourcedirtystop:= maxint; +end; + +destructor tdatalist.destroy; +var + int1: integer; +begin + for int1:= 0 to high(flinkdest) do begin + flinkdest[int1].listdestroyed(self); + end; + flinkdest:= nil; + clearbuffer; + inherited; +end; + +procedure tdatalist.listdestroyed(const sender: tdatalist); +begin + removeitems(pointerarty(flinkdest),sender); +end; + +function tdatalist.sourceischanged(const asource: listlinkinfoty): boolean; +begin + with asource do begin + result:= (source <> nil) and (dirtystart >= dirtystop); + end; +end; + +function tdatalist.checksourcechange(var ainfo: listlinkinfoty; + const sender: tdatalist; const aindex: integer): boolean; +begin + with ainfo do begin + result:= (source = sender) and (sender <> nil); + if result then begin + if aindex < 0 then begin + dirtystart:= 0; + dirtystop:= sender.count-1; + end + else begin + if aindex < dirtystart then begin + dirtystart:= aindex; + end; + if aindex > ainfo.dirtystop then begin + dirtystop:= aindex; + end; + end; + end; + end; +end; + +procedure tdatalist.sourcechange(const sender: tdatalist; const aindex: integer); +begin + //dummy +// checksourcechange(flinksource,sender,index,fsourcedirtystart,fsourcedirtystop); +end; + +function tdatalist.islinked(const asource: tdatalist): boolean; +var + int1: integer; + po1: plistlinkinfoty; +begin + result:= asource = self; + if not result then begin + for int1:= 0 to getsourcecount - 1 do begin + po1:= getsourceinfo(int1); + if (po1 <> nil) and (po1^.source <> nil) then begin + result:= po1^.source.islinked(asource); + if result then begin + break; + end; + end; + end; + end; +end; + +function tdatalist.canlink(const asource: tdatalist; + const atag: integer): boolean; +begin + result:= (asource <> nil) and (asource.datatype in getlinkdatatypes(atag)) and + not asource.islinked(self); +end; + +function tdatalist.checksourcecopy(var ainfo: listlinkinfoty; + const copyproc: copyprocty): boolean; +var + int1: integer; + int2,int3: ptruint; + po1,po2: pchar; //delphi needs pchar for pointer arithmetic +begin + with ainfo do begin + result:= (source <> nil) and (dirtystop >= dirtystart); + if result then begin + if dirtystop >= source.count then begin + dirtystop:= source.count - 1; + end; + if dirtystop >= count then begin + dirtystop:= count - 1; + end; + int2:= source.size; + po1:= pchar(source.datapo) + int2 * dirtystart; + int3:= size; + po2:= pchar(datapo) + int3 * dirtystart; + for int1:= dirtystop - dirtystart downto 0 do begin + copyproc(po1,po2); + inc(po1,int2); + inc(po2,int3); + end; + dirtystart:= maxint; + dirtystop:= -1; + end; + end; +end; + +function tdatalist.checksourcecopy2(var ainfo: listlinkinfoty; + const source2: tdatalist; const copyproc: copy2procty): boolean; +var + int1: integer; + int2,int3,int4: ptruint; + po1,po2,po3: pchar; //delphi needs pchar for pointer arithmetic +begin + with ainfo do begin + result:= (source <> nil) and (source2 <> nil) and (dirtystop >= dirtystart); + if result then begin + if dirtystop >= source.count then begin + dirtystop:= source.count - 1; + end; + if dirtystop >= source2.count then begin + dirtystop:= source2.count - 1; + end; + if dirtystop >= count then begin + dirtystop:= count - 1; + end; + int2:= source.size; + po1:= pchar(source.datapo) + int2 * dirtystart; + int3:= source2.size; + po2:= pchar(source2.datapo) + int3 * dirtystart; + int4:= size; + po3:= pchar(datapo) + int4 * dirtystart; + for int1:= dirtystop - dirtystart downto 0 do begin + copyproc(po1,po2,po3); + inc(po1,int2); + inc(po2,int3); + inc(po3,int4); + end; + dirtystart:= maxint; + dirtystop:= -1; + end; + end; +end; + +{ +procedure tdatalist.linkdest(const dest: tdatalist); +begin + if dest.flinksource <> nil then begin + dest.flinksource.unlinkdest(dest); + end; + if dest.canlink(self) then begin + dest.flinksource:= self; + additem(pointerarty(flinkdest),dest); + dest.sourcechange(self,-1); + end; +end; + +procedure tdatalist.unlinkdest(const dest: tdatalist); +begin + removeitems(pointerarty(flinkdest),dest); + dest.flinksource:= nil; +end; +} + +procedure tdatalist.unlinksource(var alink: listlinkinfoty); +begin + if alink.source <> nil then begin + removeitem(pointerarty(alink.source.flinkdest),self); + alink.source:= nil; + end; +end; + +function tdatalist.internallinksource(const source: tdatalist; + const atag: integer; var variable: tdatalist): boolean; +begin + if variable <> nil then begin + removeitem(pointerarty(variable.flinkdest),self); + end; + result:= (source <> nil) and canlink(source,atag); + if result then begin + variable:= source; + additem(pointerarty(source.flinkdest),self); + sourcechange(source,-1); + end; +end; + +procedure tdatalist.linksource(const source: tdatalist; const atag: integer); +begin + //dummy +end; + +procedure tdatalist.clearbuffer; +begin + internalfreedata(0,fcount); + if fdatapo <> nil then begin + freemem(fdatapo); + end; + fdatapo:= nil; + fbytelength:= 0; + fcapacity:= 0; + fcount:= 0; + fringpointer:= 0; +end; + +function tdatalist.sort(const comparefunc: sortcomparemethodty; + out arangelist: integerarty; const dorearange: boolean): boolean; +var + int1: integer; +begin + result:= false; + if fcount > 0 then begin + mergesort(pointer(datapo),fsize,fcount,comparefunc,arangelist); + for int1:= high(arangelist) downto 0 do begin + if arangelist[int1] <> int1 then begin + result:= true; + break; + end; + end; + if result and dorearange then begin + include(fstate,dls_sortio); + rearange(arangelist); + end; + end + else begin + include(fstate,dls_sortio); + end; +end; + +(* +function tdatalist.sort(const compareproc: compareprocty; + const arangelist: tintegerdatalist; dorearange: boolean): boolean; + //true wenn bewegt, refrow erhaelt neue indexpos + + procedure QuickSort(var arangelist: integeraty; L, R: Integer); + var + I, J: Integer; + P, T: integer; + int1: integer; + pp: pointer; + begin + if r >= l then begin + repeat + I := L; + J := R; + P := arangelist[(L + R) shr 1]; + pp:= fdatapo+p*fsize; + repeat + repeat + int1:= 0; + compareproc((fdatapo+arangeList[I]*fsize)^, pp^,int1); + if int1 = 0 then begin + int1:= arangelist[i] - p; + end; + if int1 >= 0 then break; + inc(i); + until false; + repeat + int1:= 0; + compareproc((fdatapo+arangeList[J]*fsize)^, pp^,int1); + if int1 = 0 then begin + int1:= arangelist[j] - p; + end; + if int1 <= 0 then break; + dec(j); + until false; + if I <= J then + begin + if i <> j then begin + result:= true; + T := arangeList[I]; + arangeList[I] := arangeList[J]; + arangeList[J] := T; + end; + Inc(I); + Dec(J); + end; + until I > J; + if L < J then QuickSort(arangelist,L, J); + L := I; + until I >= R; + end; + end; + +begin + arangelist.count:= fcount; + result:= false; + if fcount > 0 then begin + arangelist.number(0,1); + quicksort(pintegeraty(arangelist.datapo)^,0,arangelist.count-1); + if result and dorearange then begin + include(fstate,dls_sortio); + rearange(arangelist); + end; + end + else begin + include(fstate,dls_sortio); + end; +end; +*) + +function tdatalist.sort(out arangelist: integerarty; + const dorearange: boolean): boolean; +begin + result:= sort({$ifdef FPC}@{$endif}compare,arangelist,dorearange); +end; + +function tdatalist.sortcaseinsensitive(out arangelist: integerarty; + const dorearange: boolean): boolean; +begin + result:= sort({$ifdef FPC}@{$endif}comparecaseinsensitive, + arangelist,dorearange); +end; + +function tdatalist.sort(const compareproc: sortcomparemethodty): boolean; +var + ar1: integerarty; +begin + result:= sort(compareproc,ar1,true); +end; + +function tdatalist.sort: boolean; +begin + result:= sort({$ifdef FPC}@{$endif}compare); +end; + +function tdatalist.sortcaseinsensitive: boolean; +begin + result:= sort({$ifdef FPC}@{$endif}comparecaseinsensitive); +end; + +procedure tdatalist.checkindexrange(const aindex: integer; + const acount: integer = 1); +begin + if (aindex < 0) or (aindex >= fcount) then begin + tlist.error(slistindexerror, aindex); + end; + if (aindex+acount > fcount) then begin + tlist.error(slistindexerror, aindex); + end; +end; + +procedure tdatalist.checkindex(var index: integer); +begin + if (Index < 0) or (Index >= FCount) then begin + tlist.Error(SListIndexError, Index); + end; + index:= index + fringpointer; + if index >= fmaxcount then begin + index:= index - fmaxcount; + end; +end; + +procedure tdatalist.checkindex1(const index: integer); +begin + if (Index < 0) or (Index >= FCount) then begin + tlist.Error(SListIndexError, Index); + end; +end; + +function tdatalist.internaladddata(const quelle; docopy: boolean): integer; +var + int1: integer; + po1: pointer; +begin + beginupdate; + try + internalsetcount(fcount + 1,true); + int1:= fcount - 1 + fringpointer; + if int1 >= fmaxcount then begin + dec(int1,fmaxcount); + end; + po1:= fdatapo + int1*fsize; + move(quelle,po1^,fsize); + if docopy and (dls_needscopy in fstate) then begin + beforecopy(po1^); + aftercopy(po1^); + end; + finally + endupdate; + end; + result:= fcount-1; +end; + +function tdatalist.adddata(const quelle): integer; +begin + result:= internaladddata(quelle,true); +end; + +procedure tdatalist.internaldeletedata(index: integer; dofree: boolean); +var + int1: integer; +begin + checkindex(index); + if dofree then begin + internalcleardata(index); + end; + int1:= (index+1)*fsize; + if fringpointer = 0 then begin + move((fdatapo+int1)^,(fdatapo+int1-fsize)^,fcount*fsize-int1); + end + else begin + if index < fringpointer then begin //im unteren bereich + move((fdatapo+int1)^,(fdatapo+int1-fsize)^, + (fcount+fringpointer-fmaxcount)*fsize-int1); + end + else begin //im oberen bereich + move((fdatapo+int1)^,(fdatapo+int1-fsize)^,fmaxcount*fsize-int1); //start + move(fdatapo^,(fdatapo+(fmaxcount-1)*fsize)^,fsize); //ueberlauf + move((fdatapo+fsize)^,fdatapo^,(fcount+fringpointer-fmaxcount-1)*fsize); + //rest + end; + end; + fcount:= fcount-1; + datadeleted(index,1); + change(-1); +end; + +procedure tdatalist.deletedata(const index: integer); +begin + internaldeletedata(index,true); +end; + +procedure tdatalist.deleteitems(index,acount: integer); +begin + if index + acount > fcount then begin + acount:= fcount - index; + end; + if acount > 0 then begin + inc(fdeleting); + try + internalfreedata(index,acount); + blockcopymovedata(index+acount,index,fcount-index-acount,bcm_none); + fcount:= fcount-acount; + checkcapacity; + datadeleted(index,acount); + change(-1); + finally + dec(fdeleting); + end; + end; +end; + +procedure tdatalist.clear; +begin +// beginupdate; + inc(fdeleting); + try + clearbuffer; + change(-1); + finally + dec(fdeleting); +// endupdate; + end; +end; + +procedure tdatalist.insertitems(index,acount: integer); +var + countbefore: integer; +begin + if acount > 0 then begin + countbefore:= fcount; + internalsetcount(fcount + acount,true); + dec(index,acount+countbefore-fcount); //adjust for maxcount + blockcopymovedata(index,index+acount,fcount-index-acount,bcm_none); + initdata1(false,index,acount); + datainserted(index,acount); + change(-1); + end; +end; + +function tdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= false; +end; + +function tdatalist.assigndata(const source: tpersistent): boolean; +begin + if source = self then begin + result:= true; + exit; + end; + result:= checkassigncompatibility(source); +// result:= (datatype < dl_custom) and (source is tdatalist) and +// (tdatalist(source).datatype = datatype) or +// source.inheritsfrom(classtype) or +// inheritsfrom(source.classtype); + if result then begin + tdatalist(source).assigntodata(self); + end; +end; + +procedure tdatalist.assigntodata(const dest: tdatalist); +var + int1: integer; + po1,po2: pointer; + s0,s1,s2: integer; +begin + with dest do begin + newbuffer(self.count,true,size < self.size); + if size = self.size then begin + move(self.datapo^,fdatapo^,fcount*fsize); + end + else begin + po1:= self.datapo; + po2:= fdatapo; + s1:= self.size; + s2:= size; + s0:= s1; + if s0 > s2 then begin + s0:= s2; + end; + for int1:= 0 to fcount-1 do begin + move(po1^,po2^,s0); + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end; + internalcopyinstance(0,fcount); + change(-1); + end; +end; + +procedure tdatalist.internalgetasarray(const adatapo: pointer; + const asize: integer); +var + int1: integer; + po1,po2: pointer; + s1,s2: integer; +begin + if fcount > 0 then begin + normalizering; + if asize < size then begin + po1:= fdatapo; + po2:= adatapo; + s1:= size; + s2:= asize; + for int1:= 0 to count - 1 do begin + move(po1^,po2^,s2); + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end + else begin + move(fdatapo^,adatapo^,fcount*fsize); + end; + if dls_needscopy in fstate then begin + po1:= adatapo; + s1:= asize; + for int1:= 0 to fcount - 1 do begin + beforecopy(po1^); + aftercopy(po1^); + inc(pchar(po1),s1); + end; + end; + end; +end; + +procedure tdatalist.internalsetasarray(const source: pointer; + const asize: integer; const acount: integer); +var + int1: integer; + po1,po2: pointer; + s1,s2,s3: integer; +begin + newbuffer(acount,true,size > asize); + if fcount > 0 then begin + if size <> asize then begin + po1:= fdatapo; + po2:= source; + s1:= size; + s2:= asize; + s3:= size; + if s3 > asize then begin + s3:= asize; + end; + for int1:= 0 to fcount - 1 do begin + move(po2^,po1^,s3); + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end + else begin + move(source^,fdatapo^,fcount*fsize); + end; + internalcopyinstance(0,fcount); + end; + change(-1); +end; + +function tdatalist.getdatablock(const source: pointer; const destsize: integer): integer; + //returns size of datablock +begin + internalgetasarray(source,destsize); + result:= count * destsize; +end; + +function tdatalist.setdatablock(const dest: pointer; const sourcesize: integer; + const acount: integer): integer; + //returns size of datablock +begin + internalsetasarray(dest,sourcesize,acount); + result:= acount * sourcesize; +end; + +procedure tdatalist.internalgetdata(index: integer; out ziel); +begin + checkindex(index); + move((fdatapo+index*fsize)^,ziel,fsize); +end; + +procedure tdatalist.getdata(index: integer; var dest); +var + po1: pointer; +begin + checkindex(index); + po1:= fdatapo+index*fsize; + if dls_needscopy in fstate then begin + beforecopy(po1^); + end; + if dls_needsfree in fstate then begin + freedata(dest); + end; + move(po1^,dest,fsize); + if dls_needscopy in fstate then begin + aftercopy(dest); + end; +end; + +procedure tdatalist.getgriddata(index: integer; var dest); +begin + getdata(index,dest); +end; + +procedure tdatalist.internalsetdata(index: integer; const quelle); +var + po1: pointer; + int1: integer; +begin + int1:= index; + checkindex(index); + if dls_needscopy in fstate then begin + beforecopy((@quelle)^); + end; + po1:= fdatapo+index*fsize; + if dls_needsfree in fstate then begin + freedata(po1^); + end; + move(quelle,po1^,fsize); + if dls_needscopy in fstate then begin + aftercopy(po1^); + end; + change(int1); +end; + +procedure tdatalist.setdata(index: integer; const source); +begin + internalsetdata(index,source); +end; + +procedure tdatalist.setgriddata(index: integer; const source); +begin + internalsetdata(index,source); +end; + +function tdatalist.getstatdata(const index: integer): msestring; +begin + result:= ''; //dummy +end; + +procedure tdatalist.setstatdata(const index: integer; const value: msestring); +begin + //dummy +end; + +procedure tdatalist.writestate(const writer; const name: msestring); +var + int1: integer; +begin + with tstatwriter(writer) do begin + writeinteger(name,fcount); + for int1:= 0 to count - 1 do begin + writelistitem(getstatdata(int1)); + end; + end; +end; + +procedure tdatalist.readstate(const reader; const acount: integer; + const name: msestring); +var + int1: integer; + str1: msestring; +begin + with tstatreader(reader) do begin + try + beginupdate; + count:= acount; + for int1:= 0 to acount - 1 do begin + str1:= readlistitem; + setstatdata(int1,str1); + end; + finally + endupdate; + end; + end; +end; + +procedure tdatalist.writeappendix(const writer; const aname: msestring); +begin + //dummy +end; + +procedure tdatalist.readappendix(const reader; const aname: msestring); +begin + //dummy +end; + +function tdatalist.popbottomdata(var ziel): boolean; +begin + result:= fcount > 0; + if result then begin + checkbuffersize(0); + if @ziel <> nil then begin + getdata(0,ziel); + end; + cleardata(0); + inc(fringpointer); + if fringpointer >= fmaxcount then begin + dec(fringpointer,fmaxcount); + end; + dec(fcount); + end; +end; + +function tdatalist.poptopdata(var ziel): boolean; +begin + result:= fcount > 0; + if result then begin + if @ziel <> nil then begin + getdata(fcount-1,ziel); + end; + count:= fcount-1; + end; +end; + +procedure tdatalist.pushdata(const quelle); +begin + checkbuffersize(1); + adddata(quelle); +end; + +procedure tdatalist.internalinsertdata(index: integer; const quelle; + const docopy: boolean); +var + po1: pchar; +begin + if index = fcount then begin + internaladddata(quelle,docopy); + end + else begin + beginupdate; + try + checkindex(index); + internalsetcount(fcount+1,true); + po1:= fdatapo+index*fsize; + move(po1^,(po1+fsize)^,(fcount-index-1)*fsize); + if @quelle = nil then begin + initdata1(false,index,1); + end + else begin + move(quelle,po1^,fsize); + if (dls_needscopy in fstate) and docopy then begin + beforecopy(po1^); + aftercopy(po1^); + end; + end; + finally + endupdate; + end; + end; +end; + +procedure tdatalist.insertdata(const index: integer; const quelle); +begin + internalinsertdata(index,quelle,true); +end; + +procedure tdatalist.Setcapacity(Value: integer); +begin + if value < fcount then begin + value:= fcount; + end; + if value < fmaxcount then begin + normalizering; + end; + fbytelength:= value*fsize; + reallocmem(fdatapo,fbytelength); + fcapacity:= value; +end; + +procedure tdatalist.initdata1(const afree: boolean; index: integer; + const acount: integer); + //initialisiert mit defaultwert +var + int1,int2: integer; + default,po,po1: pchar; +begin + if acount <= 0 then begin + exit; + end; + if afree then begin + internalfreedata(index,acount); + end; + int1:= index+acount-1; + checkindex(index); + checkindex(int1); + default:= getdefault; + if default = nil then begin + if int1 >= index then begin + fillchar((fdatapo+index*fsize)^,acount*fsize,0); + if dls_needsinit in fstate then begin + for int2:= index to index + acount - 1 do begin + initinstance((fdatapo+int2*fsize)^); + end; + end; + end + else begin + fillchar((fdatapo)^,int1*fsize,0); + fillchar((fdatapo+index*fsize)^,(fmaxcount-index)*fsize,0); + if dls_needsinit in fstate then begin + for int2:= 0 to int1 - 1 do begin + initinstance((fdatapo+int2*fsize)^); + end; + for int2:= index to fmaxcount-index - 1 do begin + initinstance((fdatapo+int2*fsize)^); + end; + end; + end; + end + else begin + po:= fdatapo; + inc(po,index*fsize); + if int1 >= index then begin //one piece + for int1:= 0 to acount-1 do begin + move(default^,po^,fsize); + inc(po,fsize); + end; + if dls_needscopy in fstate then begin + for int2:= index to index + acount - 1 do begin + po1:= fdatapo+int2*fsize; + beforecopy(po1^); + aftercopy(po1^); + end; + end; + end + else begin + for int1:= 0 to fmaxcount - acount - 1 do begin + move(default^,po^,fsize); + inc(po,fsize); + end; + po:= fdatapo; + for int2:= 0 to int1 do begin + move(default^,po^,fsize); + inc(po,fsize); + end; + if dls_needscopy in fstate then begin + for int2:= 0 to int1 - 1 do begin + po1:= fdatapo+int2*fsize; + beforecopy(po1^); + aftercopy(po1^); + end; + for int2:= index to fmaxcount-index - 1 do begin + po1:= fdatapo+int2*fsize; + beforecopy(po1^); + aftercopy(po1^); + end; + end; + end; + end; +end; + +procedure tdatalist.getdefaultdata(var dest); +var + po: pointer; +begin + po:= getdefault; + if po = nil then begin + fillchar(dest,fsize,0); + end + else begin + if dls_needscopy in fstate then begin + beforecopy(po^); + end; + if dls_needsfree in fstate then begin + freedata(dest); + end; + move(po^,dest,fsize); + if dls_needscopy in fstate then begin + aftercopy(dest); + end; + end; +end; + +procedure tdatalist.getgriddefaultdata(var dest); +begin + getdefaultdata(dest); +end; + +procedure tdatalist.internalcleardata(const index: integer); +var + default,po1: pointer; +begin + po1:= fdatapo+index*fsize; + if dls_needsfree in fstate then begin + freedata(po1^); + end; + default:= getdefault; + if default <> nil then begin + move(default^,po1^,fsize); + end + else begin + fillchar(po1^,fsize,0); + end; +end; + +procedure tdatalist.cleardata(index: integer); +begin + checkindex(index); + internalcleardata(index); +end; + + +function tdatalist.deleting: boolean; +begin + result:= fdeleting > 0; +end; + +procedure tdatalist.checkcapacity; +var + int1: integer; +begin +// int1:= ((fcount*12) div 10) + 5; + int1:= fcount*2 + 32; + if fcapacity > int1 then begin + capacity:= fcount; + end; +end; + +procedure tdatalist.internalsetcount(value: integer; nochangeandinit: boolean); +var + int1: integer; + countvorher: integer; +begin + if value < 0 then begin + tlist.Error(SListCountError, value); + end; + + countvorher:= fcount; + if value > fmaxcount then begin + int1:= value-fmaxcount; //last item to init + if int1 > fcount then begin + int1:= fcount; + end; + fscrolled:= fscrolled+int1; + value:= fmaxcount; + if value > fcapacity then begin + capacity:= value; + end; + fcount:= value; + if not nochangeandinit then begin + initdata1(true,0,int1); //free lost oldbuffer + initdata1(false,countvorher,value-countvorher); //init newbuffer + end + else begin + internalfreedata(0,int1); + end; + fringpointer:= fringpointer + int1; + if fringpointer >= fmaxcount then begin + fringpointer:= fringpointer - fmaxcount; + end; + if not nochangeandinit then begin + change(-1); + end; + end + else begin + if value > fcapacity then begin + capacity:= value*2 + 32; +// capacity:= ((value*12) div 10) + 5; //in 20% schritten + end; + if value > countvorher then begin + Fcount:= Value; + // fillchar(datapoty(fdatapo)^[countvorher*fsize],(value-countvorher)*fsize,0); + if not nochangeandinit then begin + initdata1(false,countvorher,value-countvorher); //mit defaultdaten fuellen + end; + end + else begin + if value < countvorher then begin + internalfreedata(value,countvorher-value); + Fcount := Value; + checkcapacity; + end; + end; + if countvorher > value then begin + datadeleted(count,countvorher-count); + end; + if not nochangeandinit and (countvorher <> value) then begin + change(-2); + end; + end; +end; + +procedure tdatalist.newbuffer(const acount: integer; const noinit: boolean; + const fillnull: boolean); +begin + clearbuffer; + fcount:= acount; + if fcount > fmaxcount then begin + fcount:= fmaxcount; + end; + setcapacity(fcount); + if not noinit then begin + initdata1(false,0,fcount); + end + else begin + fillchar(fdatapo^,fcount*fsize,0); + end; +end; + +procedure tdatalist.Setcount(const Value: integer); +begin + internalsetcount(value,false); +end; + +procedure tdatalist.checkbuffersize(increment: integer); +var + int1: integer; +begin + increment:= fcount + increment; + int1:= 2*increment; + if increment > fmaxcount then begin + maxcount:= int1; + end + else begin + if fmaxcount > int1 + increment + 40 then begin + maxcount:= int1; + end + end; + if fcapacity < fmaxcount then begin + capacity:= fmaxcount; + end; +end; + +procedure tdatalist.internalfill(const anzahl: integer; const wert); + //initialisiert mit wert +var + int1: integer; + po1: pchar; +begin + beginupdate; + try + count:= anzahl; + normalizering; + po1:= fdatapo; + if (@wert <> nil) and (dls_needscopy in fstate) then begin + for int1:= 0 to fcount - 1 do begin + beforecopy((@wert)^); + end; + end; + if dls_needsfree in fstate then begin + for int1:= 0 to fcount - 1 do begin + freedata(po1^); + inc(po1,fsize); + end; + end; + if @wert = nil then begin + fillchar(fdatapo^,anzahl*fsize,0); + end + else begin + po1:= fdatapo; + if dls_needscopy in fstate then begin + for int1:= 0 to fcount - 1 do begin + move(wert,po1^,fsize); + aftercopy(po1^); + inc(po1,fsize); + end; + end + else begin + for int1:= 0 to fcount - 1 do begin + move(wert,po1^,fsize); + inc(po1,fsize); + end; + end; + end; + finally + endupdate; + end; +end; + +procedure tdatalist.movedata(const fromindex, toindex: integer); +var + po1: pointer; +begin + if fromindex <> toindex then begin + normalizering; + checkindex1(toindex); + beginupdate; + getmem(po1,fsize); + try + internalgetdata(fromindex,po1^); + if fromindex > toindex then begin + move((fdatapo+toindex*fsize)^,(fdatapo+toindex*fsize+fsize)^, + (fromindex-toindex)*fsize); + end + else begin + move((fdatapo+fromindex*fsize+fsize)^,(fdatapo+fromindex*fsize)^, + (toindex-fromindex)*fsize); + end; + move(po1^,(fdatapo+toindex*fsize)^,fsize); +// internaldeletedata(fromindex,false); +// internalinsertdata(toindex,po1^,false); + datamoved(fromindex,toindex,1); + finally + freemem(po1); + endupdate; + end; + end; +// change(-1); +end; + +procedure tdatalist.blockcopymovedata(fromindex, toindex: integer; + const acount: integer; const mode: blockcopymodety); +var + ueberlappung,freestart,freecount,initstart: integer; + int1,int2: integer; +begin + if (acount > 0) and (fromindex <> toindex) then begin + normalizering; + checkindex(fromindex); + checkindex(toindex); + int1:= fromindex+acount-1; + checkindex(int1); +// if (mode <> bcm_rotate) then begin + int2:= toindex+acount-1; + checkindex(int2); +// end; + if fromindex > toindex then begin + ueberlappung:= toindex+acount-fromindex; + if ueberlappung < 0 then begin + ueberlappung:= 0; + end; + freestart:= toindex; + initstart:= fromindex + ueberlappung; + end + else begin + ueberlappung:= fromindex+acount-toindex; + if ueberlappung < 0 then begin + ueberlappung:= 0; + end; + freestart:= toindex+ueberlappung; + initstart:= fromindex; + end; + freecount:= acount-ueberlappung; + if mode = bcm_rotate then begin + if toindex < fromindex then begin + internalsetcount(fcount + freecount,true); + move((fdatapo+toindex*fsize)^, + (fdatapo+(fcount-freecount)*fsize)^,freecount*fsize); + move((fdatapo+fromindex*fsize)^, + (fdatapo+toindex*fsize)^,acount*fsize); + if ueberlappung = 0 then begin + move((fdatapo+(toindex+acount)*fsize)^, + (fdatapo+(toindex+acount+acount)*fsize)^, + (fromindex-toindex-acount)*fsize); + end; + move((fdatapo+(fcount-freecount)*fsize)^, + (fdatapo+(toindex+acount)*fsize)^, + freecount*fsize); + end + else begin + if ueberlappung = 0 then begin + internalsetcount(fcount + freecount,true); + move((fdatapo+fromindex*fsize)^, + (fdatapo+(fcount-freecount)*fsize)^,freecount*fsize); + move((fdatapo+(fromindex+freecount)*fsize)^, + (fdatapo+fromindex*fsize)^,(toindex-fromindex{-acount+1})*fsize); + move((fdatapo+(fcount-freecount)*fsize)^, + (fdatapo+(toindex{-freecount+1})*fsize)^, + freecount*fsize); + end + else begin + if toindex + acount > fcount then begin + toindex:= fcount-acount; + end; + freecount:= toindex-fromindex; + internalsetcount(fcount + freecount,true); + move((fdatapo+(fromindex+acount)*fsize)^, + (fdatapo+(fcount-freecount)*fsize)^,freecount*fsize); + move((fdatapo+(fromindex)*fsize)^, + (fdatapo+toindex*fsize)^,acount*fsize); + move((fdatapo+(fcount-freecount)*fsize)^, + (fdatapo+fromindex*fsize)^, + freecount*fsize); + end; + end; + fcount:= fcount-freecount; //no free + checkcapacity; + end + else begin + if mode <> bcm_none then begin + internalfreedata(freestart,freecount); + end; + move((fdatapo+fromindex*fsize)^, + (fdatapo+toindex*fsize)^,acount*fsize); + if mode = bcm_copy then begin + internalcopyinstance(initstart,freecount); + end + else begin + if mode = bcm_init then begin + initdata1(false,initstart,freecount); + end + end; + end; + end; +end; + +procedure tdatalist.blockmovedata(const fromindex, toindex, count: integer); +begin + if fromindex <> toindex then begin + if count = 1 then begin + movedata(fromindex,toindex); + end + else begin + blockcopymovedata(fromindex,toindex,count,bcm_rotate); + datamoved(fromindex,toindex,count); + change(-1); + end; + end; +end; + +procedure tdatalist.blockcopydata(const fromindex, toindex, count: integer); +begin + blockcopymovedata(fromindex,toindex,count,bcm_copy); + change(-1); +end; + +procedure tdatalist.readdata(reader: treader); +begin + beginupdate; + try + clear; + reader.readlistbegin; + while not reader.EndOfList do begin + internalsetcount(fcount + 1,false); + readitem(reader,(fdatapo+(fcount-1)*fsize)^); + end; + reader.ReadListEnd; + finally + endupdate; + end; +end; + +procedure tdatalist.writedata(writer: twriter); +var + int1: integer; + po1: pchar; +begin + writer.WriteListBegin; + normalizering; + po1:= fdatapo; + for int1:= 0 to count-1 do begin + writeitem(writer,po1^); + inc(po1,fsize); + end; + writer.writelistend; +end; + +procedure tdatalist.readitem(const reader: treader; var value); +begin + //dummy +end; + +procedure tdatalist.writeitem(const writer: twriter; var value); +begin + //dummy +end; + +function tdatalist.checkwritedata(const filer: tfiler): boolean; +var + int1,int2: integer; + po1: pointer; +begin + if filer.ancestor = nil then begin + result:= (fcount <> 0); + end + else begin + result:= tdatalist(filer.ancestor).fcount <> fcount; + if not result and (filer is twriter) then begin + datapo; //normalize ring + po1:= tdatalist(filer.ancestor).datapo; + for int1:= 0 to fcount-1 do begin + int2:= compare((fdatapo+int1*fsize)^,(pchar(po1)+int1*fsize)^); + if int2 <> 0 then begin + result:= true; + break; + end; + end; + end; + end; +end; + +procedure tdatalist.defineproperties(const propname: string; + const filer: tfiler); +begin + filer.defineproperty(propname, + {$ifdef FPC}@{$endif}readdata,{$ifdef FPC}@{$endif}writedata, + not (dls_nostreaming in fstate) and checkwritedata(filer)); +end; + +procedure tdatalist.defineproperties(filer: tfiler); +begin + inherited; + defineproperties('data',filer); +end; +procedure tdatalist.freedata(var data); +begin + //dummy +end; + +procedure tdatalist.internalfreedata(index, anzahl: integer); +begin + if dls_needsfree in fstate then begin + forall(index,anzahl,{$ifdef FPC}@{$endif}freedata); + end; +end; + +procedure tdatalist.beforecopy(var data); +begin + //dumy +end; + +procedure tdatalist.aftercopy(var data); +begin + //dumy +end; + +procedure tdatalist.initinstance(var data); +begin + //dummy +end; + +procedure tdatalist.internalcopyinstance(index, anzahl: integer); +begin + if dls_needscopy in fstate then begin + forall(index,anzahl,{$ifdef FPC}@{$endif}beforecopy); + forall(index,anzahl,{$ifdef FPC}@{$endif}aftercopy); + end; +end; + +procedure tdatalist.remoteitemchange(const alink: pointer); +begin + with idatalistclient(alink) do begin + itemchanged(self,fintparam); + end; +end; + +procedure tdatalist.doitemchange(const index: integer); +begin + if assigned(fonitemchange) then begin + fonitemchange(self,index); + end; + fintparam:= index; + if (dls_remote in fstate) and (fobjectlinker <> nil) then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}remoteitemchange, + typeinfo(idatalistclient)); + end; +end; + +procedure tdatalist.dochange; +begin + if assigned(fonchange) then begin + fonchange(self); + end; +end; + +procedure tdatalist.change(const index: integer); +var + int1: integer; +begin + exclude(fstate,dls_sortio); + if fcount = 0 then begin + frearanged:= false; + end; + if fnochange = 0 then begin + doitemchange(index); + if sorted then begin + sort; + end; + dochange; + if flinkdest <> nil then begin + for int1:= 0 to high(flinkdest) do begin + flinkdest[int1].sourcechange(self,index); + end; + end; + end; +end; + +procedure tdatalist.beginupdate; +begin + inc(fnochange); +end; + +procedure tdatalist.endupdate; +begin + dec(fnochange); + if fnochange = 0 then begin + change(-1); + end; +end; + +procedure tdatalist.incupdate; +begin + inc(fnochange); +end; + +procedure tdatalist.decupdate; +begin + dec(fnochange); +end; +{ +procedure tdatalist.resetupdate; +begin + fnochange:= 0; +end; +} +function tdatalist.updating: boolean; +begin + result:= fnochange > 0; +end; + +procedure tdatalist.internalrearange(arangelist: pinteger; + const acount: integer); +var + datapo1: pchar; + int1: integer; +begin + frearanged:= true; + normalizering; + getmem(datapo1,fbytelength); + try + for int1:= 0 to acount -1 do begin + move((fdatapo+arangelist^*fsize)^,(datapo1+int1*fsize)^,fsize); + inc(arangelist); + end; + move((fdatapo+acount*fsize)^, + (datapo1+acount*fsize)^, + (fcount-acount)*fsize); //rest kopieren + finally + freemem(fdatapo); + fdatapo:= datapo1; + end; + change(-1); +end; + +procedure tdatalist.rearange(const arangelist: tintegerdatalist); +begin + internalrearange(arangelist.datapo,arangelist.count); +end; + +procedure tdatalist.rearange(const arangelist: integerarty); +begin + internalrearange(pointer(arangelist),length(arangelist)); +end; + +function tdatalist.empty(const index: integer): boolean; +var + int1: integer; + po1: pbyte; +begin + po1:= getitempo(index); + for int1:= 0 to fsize-1 do begin + if po1^ <> 0 then begin + result:= false; + exit; + end; + inc(po1); + end; + result:= true; +end; + +class function tdatalist.datatype: listdatatypety; +begin + result:= dl_custom; +end; + +function tdatalist.compare(const l,r): integer; +begin + result:= 0; +end; + +function tdatalist.comparecaseinsensitive(const l,r): integer; +begin + result:= compare(l,r); +end; + +procedure tdatalist.setmaxcount(const Value: integer); +begin + if fmaxcount <> value then begin + normalizering; + if fcount > value then begin + count:= value; + end; + fmaxcount := Value; + end; +end; + +function tdatalist.getdefault: pointer; +begin + result:= nil; +end; + +procedure tdatalist.normalizering; +var + po: pbyte; + int1,int2,int3: integer; +begin + if fringpointer <> 0 then begin + int1:= fringpointer*fsize; + int2:= fringpointer + fcount; + if int2 > fmaxcount then begin //2 pieces + int2:= (int2 - fmaxcount) * fsize; + getmem(po,int2); + move(fdatapo^,po^,int2); + int3:= fmaxcount * fsize-int1; + move((fdatapo+int1)^,fdatapo^,int3); + move(po^,(fdatapo+int3)^,int2); + freemem(po); + end + else begin + move((fdatapo+int1)^,fdatapo^,int1); + end; + fringpointer:= 0; + end; +end; + +procedure tdatalist.initdata(const index, anzahl: integer); +begin + initdata1(true,index,anzahl); +end; + +procedure tdatalist.forall(startindex: integer; const count: integer; + const proc: dataprocty); +var + int1: integer; + po1: pchar; +begin if count > 0 then begin + int1:= startindex+count-1; + checkindex(startindex); + checkindex(int1); + po1:= fdatapo; + if (fringpointer = 0) or (int1 >= startindex) then begin //ein stueck + inc(po1,startindex*fsize); + for int1:= startindex to int1 do begin + proc(po1^); + inc(po1,fsize); + end; + end + else begin + for int1:= 0 to int1 do begin + proc(po1^); + inc(po1,fsize); + end; + po1:= fdatapo; + inc(po1,startindex*fsize); + for int1:= startindex to fmaxcount-1 do begin + proc(po1^); + inc(po1,fsize); + end; + end; + end; +end; + +function tdatalist.getsorted: boolean; +begin + result:= dls_sorted in fstate; +end; + +procedure tdatalist.setsorted(const Value: boolean); +begin + if sorted <> value then begin + if value then begin + include(fstate,dls_sorted); + sort; + end + else begin + exclude(fstate,dls_sorted); + end; + end; +end; +{ +function tdatalist.Getasvarrec(index: integer): tvarrec; +begin + result.VType:= vtpointer; //dummy + result.VPointer:= nil; +end; + +procedure tdatalist.Setasvarrec(index: integer; const Value: tvarrec); +begin + //dummy +end; +} +{ +procedure tdatalist.invalidateline(index: integer); +begin + if assigned(foninvalidateline) then begin + foninvalidateline(self,index); + end; +end; +} + +procedure tdatalist.assignb(const source: tdatalist); +begin + source.assigntob(self); +end; + +procedure tdatalist.assigntob(const dest: tdatalist); +begin + raise exception.Create('Can not assigntob.'); +end; + +function tdatalist.datapo: pointer; +begin + normalizering; + result:= fdatapo; +end; + +function tdatalist.datahighpo: pointer; +begin + result:= nil; + if fcount > 0 then begin + result:= pchar(datapo) + (fcount-1)*fsize; + end; +end; + +function tdatalist.getitempo(index: integer): pointer; +begin + checkindex(index); + result:= fdatapo + index*fsize; +end; + +procedure tdatalist.assign(sender: tpersistent); +begin + if not assigndata(sender) then begin + inherited; + end; +end; + +procedure tdatalist.clean(const start,stop: integer); +begin + //dummy +end; + +function tdatalist.getsourcecount: integer; +begin + result:= 0; +end; + +function tdatalist.getsourceinfo(const atag: integer): plistlinkinfoty; +begin + result:= nil; +end; + +function tdatalist.getsourcename(const atag: integer): string; +var + po1: plistlinkinfoty; +begin + po1:= getsourceinfo(atag); + if po1 <> nil then begin + result:= po1^.name; + end + else begin + result:= ''; + end; +end; + +function tdatalist.getlinkdatatypes(const atag: integer): listdatatypesty; +begin + result:= [datatype]; +end; + +procedure tdatalist.initsource(var asource: listlinkinfoty); +begin + fillchar(asource,sizeof(asource),0); + with asource do begin + dirtystop:= maxint; + end; +end; + +procedure tdatalist.removesource(var asource: listlinkinfoty); +begin + with asource do begin + if source <> nil then begin + source.listdestroyed(self); + source:= nil; + end; + end; +end; + +procedure tdatalist.checklistdestroyed(var ainfo: listlinkinfoty; + const sender: tdatalist); +begin + if sender = ainfo.source then begin + ainfo.source:= nil; + end; +end; + +procedure tdatalist.clearmemberitem(const subitem: integer; + const index: integer); +begin + //dummy +end; + +procedure tdatalist.setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); +begin + //dummy +end; + +procedure tdatalist.setcheckeditem(const avalue: integer); +begin + if (avalue < 0) or (avalue > fcount) then begin + fcheckeditem:= -1; + end + else begin + fcheckeditem:= avalue; + end; +end; + +function tdatalist.getfacultative: boolean; +begin + result:= dls_facultative in fstate; +end; + +procedure tdatalist.setfacultative(const avalue: boolean); +begin + if avalue then begin + fstate:= fstate+[dls_facultative,dls_propertystreaming]; + end + else begin + exclude(fstate,dls_facultative); + end; +end; + +procedure tdatalist.datadeleted(const aindex: integer; const acount: integer); +begin + if fcheckeditem >= 0 then begin + if fcheckeditem >= aindex then begin + if fcheckeditem < aindex + acount then begin + fcheckeditem:= -1; + end + else begin + fcheckeditem:= fcheckeditem - acount; + if fcheckeditem < 0 then begin + fcheckeditem:= -1; + end; + end; + end; + end; +end; + +procedure tdatalist.datainserted(const aindex: integer; const acount: integer); +begin + if (fcheckeditem >= 0) and (fcheckeditem >= aindex) then begin + fcheckeditem:= fcheckeditem + acount; + if fcheckeditem >= fcount then begin + fcheckeditem:= -1; + end; + end; +end; + +procedure tdatalist.datamoved(const fromindex: integer; const toindex: integer; + const acount: integer); +begin + if (fcheckeditem >= 0) and (fcheckeditem >= fromindex) and + (fcheckeditem < fromindex+acount) then begin + fcheckeditem:= fcheckeditem + toindex - fromindex; + if (fcheckeditem < 0) or (fcheckeditem >= fcount) then begin + fcheckeditem:= -1; + end; + end; +end; + +procedure tdatalist.linkclient(const aclient: idatalistclient); +begin + aclient.getobjectlinker.link(aclient,iobjectlink(self),nil, + typeinfo(idatalistclient)); + include(fstate,dls_remote); + aclient.itemchanged(self,-1); +end; + +procedure tdatalist.unlinkclient(const aclient: idatalistclient); +begin + aclient.getobjectlinker.unlink(aclient,iobjectlink(self),nil); +end; + +function tdatalist.getastext(const index: integer): msestring; +begin + result:= ''; +end; + +procedure tdatalist.setastext(const index: integer; const avalue: msestring); +begin + //dummy +end; + +procedure tdatalist.setitemselected(const row: integer; const value: boolean); +begin + //dummy +end; + +function tdatalist.getifidatatype(): listdatatypety; +begin + result:= datatype; +end; + +{ tintegerdatalist } + +constructor tintegerdatalist.create; +begin + inherited; + fsize:= sizeof(integer); + min:= minint; + max:= maxint; + fcheckeditem:= -1; +end; + +procedure tintegerdatalist.number(const start,step: integer); +var + int1,int2: integer; +begin + int2:= start; + beginupdate; + try + for int1:= 0 to count-1 do begin + internalsetdata(int1,int2); + int2:= int2 + step; + end; + finally + endupdate; + end; +end; + +function tintegerdatalist.add(const value: integer): integer; +begin + result:= adddata(value); +end; +{ +procedure tintegerdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +function tintegerdatalist.Getitems(const index: integer): integer; +begin + internalgetdata(index,result); +end; + +procedure tintegerdatalist.insert(const index: integer; const item: integer); +begin + insertdata(index,item); +end; + +procedure tintegerdatalist.Setitems(const index: integer; const Value: integer); +begin + internalsetdata(index,value); +end; + +class function tintegerdatalist.datatype: listdatatypety; +begin + result:= dl_integer; +end; + +function tintegerdatalist.empty(const index: integer): boolean; +var + po1: pointer; +begin + po1:= getdefault; + if po1 = nil then begin + result:= pinteger(getitempo(index))^ = 0; + end + else begin + result:= pinteger(getitempo(index))^ = pinteger(po1)^; + end; +end; + +function tintegerdatalist.compare(const l,r): integer; +begin + result:= integer(l)-integer(r); +end; + +function tintegerdatalist.find(value: integer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to fcount-1 do begin + if integer(pointer(fdatapo+int1*fsize)^) = value then begin + result:= int1; + break; + end; + end; +end; + +procedure tintegerdatalist.fill(acount: integer; const defaultvalue: integer); +begin + internalfill(count,defaultvalue); +end; + +function tintegerdatalist.getasarray: integerarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(integer)); +end; + +procedure tintegerdatalist.setasarray(const avalue: integerarty); +begin + internalsetasarray(pointer(avalue),sizeof(integer),length(avalue)); +end; + +function tintegerdatalist.getasbooleanarray: booleanarty; +var + po1: pinteger; + int1: integer; +begin + setlength(result,fcount); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= po1^ <> 0; + inc(pchar(po1),fsize); + end; +end; + +procedure tintegerdatalist.setasbooleanarray(const avalue: booleanarty); +var + int1: integer; + po1: plongbool; +begin + newbuffer(length(avalue),true,size > sizeof(integer)); + po1:= pointer(fdatapo); + for int1:= 0 to high(avalue) do begin + po1^:= avalue[int1]; + inc(pchar(po1),fsize); + end; + change(-1); +end; + +function tintegerdatalist.getstatdata(const index: integer): msestring; +begin + result:= inttostrmse(items[index]); +end; + +procedure tintegerdatalist.setstatdata(const index: integer; + const value: msestring); +var + int1: integer; +begin + int1:= strtoint(value); + if int1 < min then begin + int1:= min; + end + else begin + if int1 > max then begin + int1:= max; + end; + end; + setdata(index,int1); +end; + +procedure tintegerdatalist.writeappendix(const writer; const aname: msestring); +begin + with tstatwriter(writer) do begin + writeinteger(aname+'_ci',fcheckeditem); + end; +end; + +procedure tintegerdatalist.readappendix(const reader; const aname: msestring); +var +// po1: plongboolaty; + po1,pe,pchecked: pinteger; +// int1: integer; +begin + with tstatreader(reader) do begin + fcheckeditem:= readinteger(aname+'_ci',fcheckeditem,-1,count-1); + if fcheckeditem >= 0 then begin + po1:= datapo; + pe:= pointer(po1)+fcount*fsize; + pchecked:= pointer(po1) + fcheckeditem*fsize; + while po1 < pe do begin + if po1 <> pchecked then begin + po1^:= notcheckedvalue; + end; + po1:= pointer(po1) + fsize; + end; + { + for int1:= 0 to fcount-1 do begin //fix wrong data + if po1^[int1] <> (int1 = fcheckeditem) then begin + items[int1]:= integer(longbool((int1 = fcheckeditem))); + end; + end; + } + end; + end; +end; + +procedure tintegerdatalist.readitem(const reader: treader; var value); +begin + integer(value):= reader.ReadInteger; +end; + +procedure tintegerdatalist.writeitem(const writer: twriter; var value); +begin + writer.writeinteger(integer(value)) +end; + +function tintegerdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tintegerdatalist); +end; + +function tintegerdatalist.getastext(const index: integer): msestring; +begin + result:= inttostrmse(items[index]); +end; + +procedure tintegerdatalist.setastext(const index: integer; + const avalue: msestring); +var + int1: integer; +begin + if trystrtoint(avalue,int1) then begin + items[index]:= int1; + end; +end; + +procedure tintegerdatalist.fill(const defaultvalue: integer); +begin + fill(count,defaultvalue); +end; + +{ tbooleandatalist } + +procedure tbooleandatalist.setasarray(const avalue: longboolarty); +begin + inherited asarray:= integerarty(avalue); +end; + +function tbooleandatalist.getasarray: longboolarty; +begin + result:= longboolarty(inherited asarray); +end; + +function tbooleandatalist.getitems(const index: integer): boolean; +begin + result:= inherited items[index] <> 0; +end; + +procedure tbooleandatalist.setitems(const index: integer; + const avalue: boolean); +begin + inherited items[index]:= longint(longbool(avalue)); +end; + +procedure tbooleandatalist.fill(acount: integer; const defaultvalue: boolean); +begin + inherited fill(acount,ord(longbool(defaultvalue))); +end; + +procedure tbooleandatalist.fill(const defaultvalue: boolean); +begin + fill(count,defaultvalue); +end; + +{ tint64datalist } + +constructor tint64datalist.create; +begin + inherited; + fsize:= sizeof(int64); +// min:= minint; +// max:= maxint; +end; + +class function tint64datalist.datatype: listdatatypety; +begin + result:= dl_int64; +end; +{ +procedure tint64datalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +function tint64datalist.Getitems(index: integer): int64; +begin + internalgetdata(index,result); +end; + +procedure tint64datalist.Setitems(index: integer; const avalue: int64); +begin + internalsetdata(index,avalue); +end; + +procedure tint64datalist.setasarray(const value: int64arty); +begin + internalsetasarray(pointer(value),sizeof(int64),length(value)); +end; + +function tint64datalist.getasarray: int64arty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(int64)); +end; + +procedure tint64datalist.readitem(const reader: treader; var value); +begin + int64(value):= reader.ReadInt64; +end; + +procedure tint64datalist.writeitem(const writer: twriter; var value); +begin + writer.writeinteger(int64(value)) +end; + +function tint64datalist.compare(const l,r): integer; +begin + result:= int64(l)-int64(r); +end; + +procedure tint64datalist.setstatdata(const index: integer; + const value: msestring); +var + int1: int64; +begin + int1:= strtoint64(value); + setdata(index,int1); +end; + +function tint64datalist.getstatdata(const index: integer): msestring; +begin + result:= inttostrmse(items[index]); +end; + +function tint64datalist.empty(const index: integer): boolean; +var + po1: pointer; +begin + po1:= getdefault; + if po1 = nil then begin + result:= pint64(getitempo(index))^ = 0; + end + else begin + result:= pint64(getitempo(index))^ = pinteger(po1)^; + end; +end; + +function tint64datalist.add(const avalue: int64): integer; +begin + result:= adddata(avalue); +end; + +procedure tint64datalist.insert(const index: integer; const avalue: int64); +begin + insertdata(index,avalue); +end; + +function tint64datalist.find(const avalue: int64): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to fcount-1 do begin + if int64(pointer(fdatapo+int1*fsize)^) = avalue then begin + result:= int1; + break; + end; + end; +end; + +procedure tint64datalist.fill(const acount: integer; const defaultvalue: int64); +begin + internalfill(count,defaultvalue); +end; + +function tint64datalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tint64datalist); +end; + +function tint64datalist.getastext(const index: integer): msestring; +begin + result:= inttostrmse(items[index]); +end; + +procedure tint64datalist.setastext(const index: integer; + const avalue: msestring); +var + int1: int64; +begin + if trystrtoint64(avalue,int1) then begin + items[index]:= int1; + end; +end; + +procedure tint64datalist.fill(const defaultvalue: int64); +begin + fill(count,defaultvalue); +end; + +{ tcurrencydatalist } + +constructor tcurrencydatalist.create; +begin + inherited; + fsize:= sizeof(currency); +// min:= minint; +// max:= maxint; +end; + +class function tcurrencydatalist.datatype: listdatatypety; +begin + result:= dl_currency; +end; +{ +procedure tcurrencydatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +function tcurrencydatalist.Getitems(index: integer): currency; +begin + internalgetdata(index,result); +end; + +procedure tcurrencydatalist.Setitems(index: integer; const avalue: currency); +begin + internalsetdata(index,avalue); +end; + +procedure tcurrencydatalist.setasarray(const value: currencyarty); +begin + internalsetasarray(pointer(value),sizeof(currency),length(value)); +end; + +function tcurrencydatalist.getasarray: currencyarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(currency)); +end; + +procedure tcurrencydatalist.readitem(const reader: treader; var value); +begin + currency(value):= reader.Readcurrency; +end; + +procedure tcurrencydatalist.writeitem(const writer: twriter; var value); +begin + writer.writecurrency(currency(value)) +end; + +function tcurrencydatalist.compare(const l,r): integer; +var + cur1: currency; +begin + result:= 0; + cur1:= currency(l)-currency(r); + if cur1 < 0 then begin + result:= -1; + end + else begin + if cur1 > 0 then begin + result:= 1; + end; + end; +end; + +procedure tcurrencydatalist.setstatdata(const index: integer; + const value: msestring); +var + int1: currency; +begin + int1:= strtocurr(ansistring(value)); + setdata(index,int1); +end; + +function tcurrencydatalist.getstatdata(const index: integer): msestring; +begin + result:= msestring(currtostr(items[index])); +end; + +function tcurrencydatalist.empty(const index: integer): boolean; +var + po1: pointer; +begin + po1:= getdefault; + if po1 = nil then begin + result:= pcurrency(getitempo(index))^ = 0; + end + else begin + result:= pcurrency(getitempo(index))^ = pinteger(po1)^; + end; +end; + +function tcurrencydatalist.add(const avalue: currency): integer; +begin + result:= adddata(avalue); +end; + +procedure tcurrencydatalist.insert(const index: integer; const avalue: currency); +begin + insertdata(index,avalue); +end; + +function tcurrencydatalist.find(const avalue: currency): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to fcount-1 do begin + if currency(pointer(fdatapo+int1*fsize)^) = avalue then begin + result:= int1; + break; + end; + end; +end; + +procedure tcurrencydatalist.fill(const acount: integer; const defaultvalue: currency); +begin + internalfill(count,defaultvalue); +end; + +function tcurrencydatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tcurrencydatalist); +end; + +function tcurrencydatalist.getastext(const index: integer): msestring; +begin + result:= msestring(currtostr(items[index])); +end; + +procedure tcurrencydatalist.setastext(const index: integer; + const avalue: msestring); +var + cu1: currency; +begin + if trystrtocurr(ansistring(avalue),cu1) then begin + items[index]:= cu1; + end; +end; + +procedure tcurrencydatalist.fill(const defaultvalue: currency); +begin + fill(count,defaultvalue); +end; + +{ tenumdatalist } + +constructor tenumdatalist.create(agetdefault: getintegereventty); +begin + inherited create; + fgetdefault:= agetdefault; +end; + +function tenumdatalist.empty(const index: integer): boolean; +begin + result:= integer(getitempo(index)^) = fgetdefault(); +end; + +function tenumdatalist.getdefault: pointer; +begin + fdefaultval:= fgetdefault(); + result:= @fdefaultval; +end; + +{ tenum64datalist } + +constructor tenum64datalist.create(agetdefault: getint64eventty); +begin + inherited create; + fgetdefault:= agetdefault; +end; + +function tenum64datalist.empty(const index: integer): boolean; +begin + result:= int64(getitempo(index)^) = fgetdefault(); +end; + +function tenum64datalist.getdefault: pointer; +begin + fdefaultval:= fgetdefault(); + result:= @fdefaultval; +end; + +{ trealdatalist } + +constructor trealdatalist.create; +begin + inherited; + fsize:= sizeof(real); + min:= emptyreal; + max:= bigreal; + fdefaultval:= emptyreal; +end; + +function trealdatalist.getdefault: pointer; +begin + if fdefaultzero then begin + result:= nil; + end + else begin + result:= @fdefaultval; + end; +end; + +procedure trealdatalist.number(start,step: real); +var + int1: integer; + rea1: real; +begin + beginupdate; + try + for int1:= 0 to count-1 do begin + rea1:= start+int1*step; + internalsetdata(int1,rea1); + end; + finally + endupdate; + end; +end; + +function trealdatalist.add(const value: real): integer; +begin + result:= adddata(value); +end; +{ +procedure trealdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +procedure trealdatalist.assignre(const source: tcomplexdatalist); +begin + source.assigntodata(self); +end; + +procedure trealdatalist.assignim(const source: tcomplexdatalist); +begin + source.assigntob(self); +end; + +procedure trealdatalist.assignre(const source: complexarty); +var + pod,poe: preal; + pos: pcomplexty; +begin + beginupdate; + count:= length(source); + if count > 0 then begin + pod:= datapo; + poe:= pod + fcount; + pos:= pointer(source); + repeat + pod^:= pos^.re; + inc(pos); + inc(pod); + until pod = poe; + end; + endupdate; +end; + +procedure trealdatalist.assignim(const source: complexarty); +var + pod,poe: preal; + pos: pcomplexty; +begin + beginupdate; + count:= length(source); + if count > 0 then begin + pod:= datapo; + poe:= pod + fcount; + pos:= pointer(source); + repeat + pod^:= pos^.im; + inc(pos); + inc(pod); + until pod = poe; + end; + endupdate; +end; + +procedure trealdatalist.copytocomplex(dest: pcomplexty); +var + ps,pe: preal; +begin + if count > 0 then begin + ps:= datapo; + pe:= ps+count; + repeat + dest^.re:= ps^; //dest possibly shifted to im + inc(dest); + inc(ps); + until ps = pe; + end; +end; + +procedure trealdatalist.assigntore(const dest: tcomplexdatalist); +begin + dest.beginupdate; + dest.count:= count; + copytocomplex(dest.datapo); + dest.endupdate; +end; + +procedure trealdatalist.assigntoim(const dest: tcomplexdatalist); +begin + dest.beginupdate; + dest.count:= count; + copytocomplex(pointer(preal(dest.datapo)+1)); + dest.endupdate; +end; + +procedure trealdatalist.assigntore(var dest: complexarty); +begin + setlength(dest,count); + copytocomplex(pointer(dest)); +end; + +procedure trealdatalist.assigntoim(var dest: complexarty); +begin + setlength(dest,count); + copytocomplex(pointer(preal(pointer(dest))+1)); +end; + +procedure trealdatalist.insert(index: integer; const item: realty); +begin + insertdata(index,item); +end; + +function trealdatalist.Getitems(index: integer): realty; +begin + checkindex(index); + result:= prealty(pointer(fdatapo+index*fsize))^; +// internalgetdata(index,result); +end; + +procedure trealdatalist.Setitems(index: integer; const Value: realty); +var + int1: integer; +begin + int1:= index; + checkindex(index); + prealty(pointer(fdatapo+index*fsize))^:= value; + change(int1); +// internalsetdata(index,value); +end; + +function trealdatalist.getasarray: realarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(realty)); +end; + +procedure trealdatalist.setasarray(const data: realarty); +begin + internalsetasarray(pointer(data),sizeof(realty),length(data)); +end; + +class function trealdatalist.datatype: listdatatypety; +begin + result:= dl_real; +end; + +function trealdatalist.empty(const index: integer): boolean; +var + po1: preal; +begin + po1:= preal(getitempo(index)); + result:= po1^ = emptyreal; + if fdefaultzero then begin + result:= result or (po1^ = 0); + end; +end; + +function trealdatalist.compare(const l,r): integer; +begin + result:= cmprealty(real(l),real(r)); +end; + +procedure trealdatalist.fill(acount: integer; const defaultvalue: realty); +begin + internalfill(count,defaultvalue); +end; + +procedure trealdatalist.minmax(out minval,maxval: realty); +var + int1: integer; + po1: prealty; + min1,max1: realty; +begin + min1:= bigreal; + max1:= emptyreal; + po1:= datapo; + for int1:= count-1 downto 0 do begin + if po1^ = emptyreal then begin + min1:= po1^; + end + else begin + if (max1 = emptyreal) or (po1^ > max1) then begin + max1:= po1^; + end; + if not (min1 = emptyreal) and (min1 > po1^) then begin + min1:= po1^; + end; + end; + inc(pchar(po1),fsize); + end; + minval:= min1; + maxval:= max1; +end; + +function trealdatalist.getstatdata(const index: integer): msestring; +begin + result:= realtytostrdotmse(items[index]); +// result:= realtytostrdot(items[index]); +end; + +procedure trealdatalist.setstatdata(const index: integer; const value: msestring); +var + rea1: realty; +begin + if (value = '') and facceptempty then begin + rea1:= emptyreal; + end + else begin + rea1:= strtorealtydot(value); + if cmprealty(rea1,min) < 0 then begin + rea1:= min; + end + else begin + if cmprealty(rea1,max) > 0 then begin + rea1:= max; + end; + end; + end; + items[index]:= rea1; +end; + +procedure trealdatalist.readitem(const reader: treader; var value); +begin + realty(value):= readrealty(reader); +end; + +procedure trealdatalist.writeitem(const writer: twriter; var value); +begin + writer.writefloat(double(value)); +// writerealty(writer,realty(value)); +end; + +function trealdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(trealdatalist); +end; + +function trealdatalist.getastext(const index: integer): msestring; +var + rea1: realty; +begin + result:= ''; + rea1:= items[index]; + if not (rea1 = emptyreal) then begin + result:= doubletostring(rea1,0,fsm_default, + defaultformatsettingsmse.decimalseparator); + end; +end; + +procedure trealdatalist.setastext(const index: integer; + const avalue: msestring); +var + rea1: realty; +begin + if avalue = '' then begin + items[index]:= emptyreal; + end + else begin + if trystrtodouble(avalue,double(rea1)) then begin + items[index]:= rea1; + end; + end; +end; + +procedure trealdatalist.fill(const defaultvalue: realty); +begin + fill(count,defaultvalue); +end; + +{ tdatetimedatalist } + +class function tdatetimedatalist.datatype: listdatatypety; +begin + result:= dl_datetime; +end; + +function tdatetimedatalist.empty(const index: integer): boolean; +begin + result:= preal(getitempo(index))^ = 0; +end; + +procedure tdatetimedatalist.fill(acount: integer; + const defaultvalue: tdatetime); +begin + internalfill(count,defaultvalue); +end; + +function tdatetimedatalist.getdefault: pointer; +begin + result:= nil; //-> 0.0 +end; + +procedure tdatetimedatalist.fill(const defaultvalue: tdatetime); +begin + fill(count,defaultvalue); +end; + +{ tcomplexdatalist } + +constructor tcomplexdatalist.create; +begin + min:= emptyreal; + max:= bigreal; + fdefaultval.re:= emptyreal; + fdefaultval.im:= emptyreal; + inherited; + fsize:= sizeof(complexty); +end; + +function tcomplexdatalist.add(const value: complexty): integer; +begin + result:= adddata(value); +end; + +procedure tcomplexdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + if source is trealdatalist then begin + assignre(trealdatalist(source)); + end + else begin + inherited; + end; + end; +end; + +procedure tcomplexdatalist.assignb(const source: tdatalist); +var + int1: integer; + po1,po2: pcomplexty; + s1,s2: integer; +begin + if source = self then begin + exit; + end; + if source is tcomplexdatalist then begin + beginupdate; + count:= source.count; + po1:= datapo; + po2:= source.datapo; + s1:= size; + s2:= source.size; + for int1:= 0 to fcount-1 do begin + po1^.im:= po2^.im; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + endupdate; + end + else begin + if source is trealdatalist then begin + assignim(trealdatalist(source)); + end + else begin + inherited; + end; + end; +end; + +procedure tcomplexdatalist.assignre(const source: trealdatalist); +begin + source.assigntodata(self); +end; + +procedure tcomplexdatalist.assignim(const source: trealdatalist); +var + int1: integer; + po1: pcomplexty; + po2: prealty; + s1,s2: integer; +begin + beginupdate; + count:= source.count; + po1:= datapo; + po2:= source.datapo; + s1:= size; + s2:= source.size; + for int1:= 0 to fcount-1 do begin + po1^.im:= po2^; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + endupdate; +end; + +procedure tcomplexdatalist.assigntoa(const dest: tdatalist); +begin + dest.assign(self); +end; + +procedure tcomplexdatalist.assigntob(const dest: tdatalist); +var + int1: integer; + po1: pcomplexty; + po2: prealty; + s1,s2: integer; +begin + if dest is trealdatalist then begin + with trealdatalist(dest) do begin + newbuffer(count,true,dest.size > sizeof(real)); + po1:= self.datapo; + po2:= pointer(fdatapo); + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po2^:= po1^.im; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + change(-1); + end; + end + else begin + inherited; + end; +end; + +procedure tcomplexdatalist.assignto(dest: tpersistent); +begin + if dest is trealdatalist then begin + assigntodata(trealdatalist(dest)); + end + else begin + inherited; + end; +end; + +function tcomplexdatalist.Getitems(const index: integer): complexty; +begin + internalgetdata(index,result); +end; + +procedure tcomplexdatalist.insert(const index: integer; const item: complexty); +begin + insertdata(index,item); +end; + +procedure tcomplexdatalist.Setitems(const index: integer; const Value: complexty); +begin + internalsetdata(index,value); +end; + +class function tcomplexdatalist.datatype: listdatatypety; +begin + result:= dl_complex; +end; + +function tcomplexdatalist.empty(const index: integer): boolean; +var + po1: pcomplexty; +begin + po1:= getitempo(index); + result:= (po1^.re = emptyreal) and (po1^.im = emptyreal); + if fdefaultzero then begin + result:= result or (po1^.re = 0) and (po1^.im = 0); + end; +end; + +function tcomplexdatalist.getdefault: pointer; +begin + if fdefaultzero then begin + result:= nil; + end + else begin +// fdefaultval.re:= emptyreal; +// fdefaultval.im:= emptyreal; + result:= @fdefaultval; + end; +end; + +function tcomplexdatalist.getasarray: complexarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(complexty)); +end; + +procedure tcomplexdatalist.setasarray(const data: complexarty); +begin + internalsetasarray(pointer(data),sizeof(complexty),length(data)); +end; + +function tcomplexdatalist.getasarrayre: realarty; +var + int1: integer; + po1: pcomplexty; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= po1^.re; + inc(po1); + end; +end; + +procedure tcomplexdatalist.setasarrayre(const avalue: realarty); +var + int1: integer; + po1: pcomplexty; +begin + beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + po1^.re:= avalue[int1]; + inc(po1); + end; + endupdate; +end; + +function tcomplexdatalist.getasarrayim: realarty; +var + int1: integer; + po1: pcomplexty; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= po1^.im; + inc(po1); + end; +end; + +procedure tcomplexdatalist.setasarrayim(const avalue: realarty); +var + int1: integer; + po1: pcomplexty; +begin + beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + po1^.im:= avalue[int1]; + inc(po1); + end; + endupdate; +end; + + +procedure tcomplexdatalist.fill(const acount: integer; + const defaultvalue: complexty); +begin + internalfill(count,defaultvalue); +end; + +procedure tcomplexdatalist.readitem(const reader: treader; var value); +begin + reader.ReadListBegin; + complexty(value).re:= readrealty(reader); + complexty(value).im:= readrealty(reader); + reader.readlistend; +end; + +procedure tcomplexdatalist.writeitem(const writer: twriter; var value); +begin + with writer do begin + writelistbegin; + writer.writefloat(complexty(value).re); + writer.writefloat(complexty(value).im); +// writerealty(writer,complexty(value).re); +// writerealty(writer,complexty(value).im); + writelistend; + end; +end; + +function tcomplexdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tcomplexdatalist); +end; + +procedure tcomplexdatalist.fill(const defaultvalue: complexty); +begin + fill(count,defaultvalue); +end; + +{ tpointerdatalist } + +constructor tpointerdatalist.create; +begin + inherited; + fsize:= sizeof(pointer); +end; + +function tpointerdatalist.Getitems(index: integer): pointer; +begin + internalgetdata(index,result); +end; + +procedure tpointerdatalist.Setitems(index: integer; const Value: pointer); +begin + internalsetdata(index,value); +end; + +function tpointerdatalist.getasarray: pointerarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(pointer)); +end; + +procedure tpointerdatalist.setasarray(const data: pointerarty); +begin + internalsetasarray(pointer(data),sizeof(pointer),length(data)); +end; + +function tpointerdatalist.checkassigncompatibility( + const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tpointerdatalist); +end; + +procedure tpointerdatalist.readitem(const reader: treader; var value); +begin + ptrint(value):= reader.ReadInt64; +end; + +procedure tpointerdatalist.writeitem(const writer: twriter; var value); +begin + writer.writeinteger(ptrint(value)); +end; + +{ tdynamicdatalist } + +constructor tdynamicdatalist.create; +begin + inherited; + fstate:= fstate + [dls_needsfree,dls_needscopy]; +end; +{ +destructor tdynamicdatalistmse.destroy; +begin + clear; + inherited; +end; +} + +{ tdynamicpointerdatalist } + +constructor tdynamicpointerdatalist.create; +begin + inherited; + fsize:= sizeof(pointer); +end; + +{ tansistringdatalist } + +function tansistringdatalist.add(const value: ansistring): integer; +begin + result:= adddata(value); +end; + +function tansistringdatalist.addtext(const value: ansistring): integer; + //returns added linecount +var + ar1: stringarty; + int1,int2: integer; +begin + ar1:= nil; //compiler warning + if value <> '' then begin + beginupdate; + ar1:= breaklines(value); + int1:= count; + if int1 = 0 then begin + result:= length(ar1); + end + else begin + result:= high(ar1); + end; + count:= count + result; + items[int1]:= items[int1] + ar1[0]; + for int2:= 1 to high(ar1) do begin + items[int1+int2]:= ar1[int2]; + end; + endupdate; + end + else begin + result:= 0; + end; +end; + +procedure tansistringdatalist.assign(source: tpersistent); +var + int1: integer; + po1{,po2}: pansistring; + s1{,s2}: integer; +begin + if not assigndata(source) then begin + if source is tstringlist then begin + with tstringlist(source) do begin + self.newbuffer(count,false,true); + po1:= self.datapo; + s1:= self.size; + for int1:= 0 to self.fcount - 1 do begin + po1^:= strings[int1]; + inc(pchar(po1),s1); + end; + end; + change(-1); + end + else begin + inherited; + end; + end; +end; + +procedure tansistringdatalist.assignopenarray(const data: array of ansistring); +var + po1: pstring; + int1: integer; + s1: integer; +begin + newbuffer(length(data),true,true); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^:= data[int1]; + inc(pchar(po1),s1); + end; + change(-1); +end; +{ +procedure tansistringdatalist.assignarray(const data: stringarty); +var + int1: integer; + po1: pansistring; + s1: integer; +begin + beginupdate; + try + count:= 0; + count:= length(data); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to length(data)-1 do begin + po1^:= data[int1]; + inc(pchar(po1),s1); + end; + finally + endupdate; + end; +end; + +procedure tansistringdatalist.assignarray(const data: msestringarty); +var + int1: integer; + po1: pansistring; + s1: integer; +begin + beginupdate; + try + count:= 0; + count:= length(data); + po1:= datapo; + s1:= size; + for int1:= 0 to length(data)-1 do begin + po1^:= ansistring(data[int1]); + inc(pchar(po1),s1); + end; + finally + endupdate; + end; +end; +} +function tansistringdatalist.Getitems(index: integer): ansistring; +begin + result:= pansistring(getitempo(index))^; +end; + +procedure tansistringdatalist.insert(index: integer; const item: ansistring); +begin + insertdata(index,item); +end; + +procedure tansistringdatalist.Setitems(index: integer; const Value: ansistring); +begin + pansistring(getitempo(index))^:= value; + change(index); +end; + +class function tansistringdatalist.datatype: listdatatypety; +begin + result:= dl_ansistring; +end; + +function tansistringdatalist.empty(const index: integer): boolean; +begin + result:= pansistring(getitempo(index))^ = ''; +end; + +procedure tansistringdatalist.freedata(var data); +begin + ansistring(data):= ''; +end; + +procedure tansistringdatalist.beforecopy(var data); +begin + stringaddref(ansistring(data)); +end; + +procedure tansistringdatalist.assignto(dest: tpersistent); +var + int1: integer; + po1: pansistring; + s1: integer; +begin + if dest is tstringlist then begin + po1:= datapo; + s1:= size; + with tstringlist(dest) do begin + clear; + capacity:= self.count; + for int1:= 0 to self.count-1 do begin + add(po1^); + inc(pchar(po1),s1); + end; + end; + end + else begin + inherited; + end; +end; + +function tansistringdatalist.compare(const l,r): integer; +begin + result:= comparestr(ansistring(l),ansistring(r)); +end; + +function tansistringdatalist.comparecaseinsensitive(const l,r): integer; +begin + result:= comparetext(ansistring(l),ansistring(r)); +end; + +procedure tansistringdatalist.readitem(const reader: treader; var value); +begin + string(value):= reader.ReadString; +end; + +procedure tansistringdatalist.writeitem(const writer: twriter; var value); +begin + writer.WriteString(string(value)); +end; + +procedure tansistringdatalist.fill(acount: integer; + const defaultvalue: ansistring); +begin + internalfill(count,defaultvalue); +end; + +function tansistringdatalist.getstatdata(const index: integer): msestring; +begin + if dls_binarydata in fstate then begin + result:= msestring(encodebase64(items[index])); + end + else begin + result:= msestring(items[index]); + end; +end; + +procedure tansistringdatalist.setstatdata(const index: integer; + const value: msestring); +begin + if dls_binarydata in fstate then begin + items[index]:= decodebase64(ansistring(value)); + end + else begin + items[index]:= ansistring(value); + end; +end; + +function tansistringdatalist.getasarray: stringarty; +begin + result:= nil; + allocuninitedarray(fcount,sizeof(result[0]),result); +// setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(string)); +end; + +procedure tansistringdatalist.setasarray(const avalue: stringarty); +begin + internalsetasarray(pointer(avalue),sizeof(string),length(avalue)); +end; + +function tansistringdatalist.getasmsestringarray: msestringarty; +var + po1: pstring; + int1: integer; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= msestring(po1^); + inc(pchar(pointer(po1)),s1); + end; +end; + +procedure tansistringdatalist.setasmsestringarray(const avalue: msestringarty); +var + po1: pstring; + s1: integer; + int1: integer; +begin + newbuffer(length(avalue),true,true); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to high(avalue) do begin + po1^:= ansistring(avalue[int1]); + inc(pchar(po1),s1); + end; + change(-1); +end; + +function tansistringdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tansistringdatalist); +end; + +function tansistringdatalist.getastext(const index: integer): msestring; +begin + result:= msestring(items[index]); +end; + +procedure tansistringdatalist.setastext(const index: integer; + const avalue: msestring); +begin + items[index]:= ansistring(avalue); +end; + +function tansistringdatalist.textlength: integer; +var + int1,int2: integer; + po1: pchar; +begin + po1:= datapo; + int2:= 0; + for int1:= 0 to fcount - 1 do begin + inc(int2,length(ansistring(pointer(po1)^))); + inc(po1,fsize); + end; + result:= int2; +end; + +function tansistringdatalist.gettext: ansistring; +var + po1: pansistring; + po2: pansichar; + int1: integer; + int2: integer; + ch1,ch2: ansichar; +begin + if count = 0 then begin + result:=''; + exit; + end; + int2:= textlength; + int2:= int2 + count * length(lineend); + setlength(result,int2); + ch1:= string(lineend)[1]; +{$warnings off} + if length(lineend) > 1 then begin + ch2:= string(lineend)[2]; + end; +{$warnings on} + po1:= datapo; + po2:= pointer(result); + for int1:= count-1 downto 0 do begin + int2:= length(po1^); + if int2 <> 0 then begin + move(pointer(po1^)^,po2^,int2*sizeof(ansichar)); + inc(po2,int2); + end; + po2^:= ch1; + inc(po2); +{$warnings off} + if length(lineend) > 1 then begin + po2^:= ch2; + inc(po2); + end; +{$warnings on} + inc(pchar(po1),fsize); + end; + setlength(result,length(result)-length(lineend)); //remove last lineend +end; + +procedure tansistringdatalist.settext(const avalue: ansistring); +begin + asarray:= breaklines(avalue); +end; + +{ tpoorstringdatalist } + +function tpoorstringdatalist.add(const value: tmsestringdatalist): integer; +var + int1,int2: integer; +begin + result:= fcount; + beginupdate; + with value do begin + self.count:= fcount+self.fcount; + int2:= self.fcount-fcount; + int1:= 0; + if int2 < 0 then begin + int1:= int1-int2; + int2:= 0; + end; + for int1:= int1 to fcount - 1 do begin + self.items[int2]:= items[int1]; + inc(int2); + end; + end; + endupdate; +end; + +function tpoorstringdatalist.add(const avalue: msestring; + const anoparagraph: boolean): integer; +begin + result:= add(avalue); +end; + +function tpoorstringdatalist.addchars(const value: msestring; + const aoptions: addcharoptionsty = [aco_processeditchars]; +// const processeditchars: boolean = true; + const maxchars: integer = 0): integer; +var + int1,int2,int3,int4: integer; + ar1,ar2: msestringarty; + ar3,ar4: booleanarty; + first: pmsestring; + mstr1: msestring; + bo1: boolean; +begin + result:= 0; + ar1:= nil; //compilerwarning + if value <> '' then begin + if aco_stripescsequence in aoptions then begin + ar1:= breaklines(stripescapesequences(value)); + end + else begin + ar1:= breaklines(value); + end; + if fcount = 0 then begin + count:= 1; + inc(result); + end; + int1:= fcount - 1; + int2:= int1; + checkindex(int1); + first:= pmsestring(fdatapo+int1*fsize); +// if processeditchars then begin + if aco_processeditchars in aoptions then begin + mstr1:= first^; + addeditchars(ar1[0],mstr1,feditcharindex); + ar1[0]:= mstr1; + for int1:= 1 to high(ar1) do begin + mstr1:= ''; + feditcharindex:= 0; + addeditchars(ar1[int1],mstr1,feditcharindex); + ar1[int1]:= mstr1; + end; + end + else begin + ar1[0]:= first^ + ar1[0]; +// for int1:= 1 to high(ar1) do begin +// add(ar1[int1]); +// inc(result); +// end; + end; + if maxchars <> 0 then begin + int2:= 0; + for int1:= 0 to high(ar1) do begin //calc new linecount + if ar1[int1] = '' then begin + inc(int2); + end + else begin + int2:= int2 + (length(ar1[int1])-1) div maxchars + 1; + end; + end; + if int2 <> length(ar1) then begin //break lines + setlength(ar2,int2); + setlength(ar4,int2); + setlength(ar3,int2+1); + int2:= 0; + bo1:= aco_multilinepara in aoptions; + for int1:= 0 to high(ar1) do begin + ar4[int2]:= true; //paragraph start + int3:= length(ar1[int1]); + if int3 > maxchars then begin + int4:= 1; + while int4 <= int3 do begin //todo: handle surrogate pairs + if bo1 then begin + ar2[int2]:= ar2[int2]+copy(ar1[int1],int4,maxchars)+lineend; + end + else begin + ar2[int2]:= copy(ar1[int1],int4,maxchars); + end; + int4:= int4 + maxchars; + if not bo1 then begin + ar3[int2]:= true; //appended line + inc(int2); + end; + end; + if bo1 then begin + setlength(ar2[int2],length(ar2[int2])-length(lineend)); + inc(int2); + end; + end + else begin + ar2[int2]:= ar1[int1]; + inc(int2); + end; + end; + ar1:= ar2; + end; + end; + setlength(ar3,length(ar1)); + setlength(ar4,length(ar1)); + first^:= ar1[0]; + if high(ar1) > 0 then begin + beginupdate; + result:= result + high(ar1); + for int1:= 1 to high(ar1) do begin + add(ar1[int1],ar3[int1] and not ar4[int1]); + end; + endupdate; + end + else begin + change(fcount-1); + end; + end; +end; + +{ +function tpoorstringdatalist.addchars(const value: msestring; + const processeditchars: boolean = true; + const maxchars: integer = 0): integer; +var + int1,int2: integer; + ar1: msestringarty; + first: pmsestring; + mstr1: msestring; +begin + ar1:= nil; //compilerwarning + if value <> '' then begin + ar1:= breaklines(value); + if high(ar1) > 0 then begin + beginupdate; + end; + if fcount = 0 then begin + count:= 1; + end; + int1:= fcount - 1; + int2:= int1; + checkindex(int1); + first:= pmsestring(fdatapo+int1*fsize); + if processeditchars then begin + addeditchars(ar1[0],first^,feditcharindex); + for int1:= 1 to high(ar1) do begin + mstr1:= ''; + feditcharindex:= 0; + addeditchars(ar1[int1],mstr1,feditcharindex); + add(mstr1); + end; + end + else begin + first^:= first^ + ar1[0]; + for int1:= 1 to high(ar1) do begin + add(ar1[int1]); + end; + end; + if high(ar1) > 0 then begin + endupdate; + end + else begin + change(int2); + end; + end; + result:= fcount-1; +end; +} + +(* +function tpoorstringdatalist.addchars(const value: msestring; + const processeditchars: boolean = true): integer; +var + int1,int2: integer; + po1: pmsestring; + ar1: msestringarty; + backdelete: integer; +begin + ar1:= nil; //compilerwarning + if value <> '' then begin + ar1:= breaklines(value); + backdelete:= 0; + if processeditchars then begin + for int1:= 0 to high(ar1) do begin + int2:= msestrings.processeditchars(ar1[int1],false); + if int1 = 0 then begin + backdelete:= int2; + end; + end; + end; + if high(ar1) > 0 then begin + beginupdate; + end; + for int2:= 0 to high(ar1) do begin + if (fcount = 0) or (int2 > 0) then begin + add(ar1[int2]); + end + else begin + int1:= fcount - 1; + checkindex(int1); + po1:= pointer(fdatapo+int1*fsize); + po1^:= copy(po1^,1,length(po1^)+backdelete) + ar1[int2]; + change(int1); +// doitemchange(int1); + end; + end; + if high(ar1) > 0 then begin + endupdate; + end; + end; + result:= fcount-1; +end; +*) +procedure tpoorstringdatalist.assign(source: tpersistent); +var + int1: integer; + po1{,po2}: pmsestring; + po3: pstring; + s1,s2: integer; +begin + if not assigndata(source) then begin + if source is tansistringdatalist then begin + with tansistringdatalist(source) do begin + self.newbuffer(count,true,true); + po3:= datapo; + po1:= self.datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to count - 1 do begin + po1^:= msestring(po3^); + inc(pchar(po1),s1); + inc(pchar(po3),s2); + end; + end; + change(-1); + end + else begin + inherited; + end; + end; +end; + +function tpoorstringdatalist.Getitems(index: integer): msestring; +var + po1: pmsestring; +begin + checkindex(index); + po1:= pointer(fdatapo+index*fsize); + result:= po1^; +end; + +procedure tpoorstringdatalist.Setitems(index: integer; const Value: msestring); +var + po1: pmsestring; + int1: integer; +begin + int1:= index; + checkindex(index); + po1:= pointer(fdatapo+index*fsize); + po1^:= value; + change(int1); +end; + +function tpoorstringdatalist.empty(const index: integer): boolean; +begin + result:= pmsestring(getitempo(index))^ = ''; +end; +{ +function tpoorstringdatalist.empty(const index: integer): boolean; +var + po1: pmsestring; +begin + checkindex(index); + po1:= pointer(fdatapo+index*fsize); + result:= po1^ = ''; +end; +} +procedure tpoorstringdatalist.freedata(var data); +begin + msestring(data):= ''; +end; + +{$ifdef msestringsarenotrefcounted} +procedure tpoorstringdatalist.aftercopy(var data); +begin + stringaddref(msestring(data)); +end; +{$else} +procedure tpoorstringdatalist.beforecopy(var data); +begin + stringaddref(msestring(data)); +end; +{$endif} + +procedure tpoorstringdatalist.assignto(dest: tpersistent); +var + int1: integer; + po1: pmsestring; +// s1: integer; +begin + if dest is tstringlist then begin + normalizering; +// s1:= size; + with tstringlist(dest) do begin + clear; + capacity:= self.fcount; + po1:= pointer(fdatapo); + for int1:= 0 to self.count-1 do begin + add(ansistring(po1^)); + inc(pchar(po1),fsize); + end; + end; + end + else begin + inherited; + end; +end; + +procedure tpoorstringdatalist.readitem(const reader: treader; var value); +begin +{$ifdef fpcbug4519read} + msestring(value):= readwidestring4519(reader); +{$else} + msestring(value):= treader_readmsestring(reader); +// {$ifdef mse_unicodestring} +// msestring(value):= reader.ReadunicodeString; +// {$else} +// msestring(value):= reader.ReadwideString; +// {$endif} +{$endif} +end; + +procedure tpoorstringdatalist.writeitem(const writer: twriter; var value); +begin +// {$ifdef fpcbug4519} +// writewidestring4519(writer,msestring(value)); +// {$else} + twriter_writemsestring(writer,msestring(value)); +// {$ifdef mse_unicodestring} +// writer.writeunicodestring(msestring(value)); +// {$else} +// writer.WritewideString(msestring(value)); +// {$endif} +// {$endif} +end; + +procedure tpoorstringdatalist.loadfromstream(const stream: ttextstream); +var + mstr1: msestring; + first: boolean; +begin + beginupdate; + try + clear; + first:= true; + while stream.readln(mstr1) do begin + add(mstr1); + first:= false; + end; + if not first or (mstr1 <> '') then begin + add(mstr1); + end; + finally + endupdate; + end; +end; + +procedure tpoorstringdatalist.loadfromfile(const filename: filenamety; + const aencoding: charencodingty = ce_locale); +var + stream: ttextstream; +begin + stream:= ttextstream.Create(filename,fm_read); + stream.encoding:= aencoding; + try + loadfromstream(stream); + finally + stream.Free; + end; +end; + +procedure tpoorstringdatalist.savetofile(const filename: filenamety; + const aencoding: charencodingty = ce_locale); +var + stream: ttextstream; +begin + stream:= ttextstream.Create(filename,fm_create); + stream.encoding:= aencoding; + try + savetostream(stream); + finally + stream.Free; + end; +end; + +procedure tpoorstringdatalist.savetostream(const stream: ttextstream); +var + int1: integer; + po1: pmsestring; + si1: int64; +begin + if fcount > 0 then begin + po1:= datapo; + if stream.ismemorystream then begin + si1:= 0; + for int1:= count - 2 downto 0 do begin + si1:= si1 + length(po1^); + inc(pchar(po1),fsize); + end; + stream.capacity:= stream.capacity + si1 + count*2; + //space for return-linefeed + po1:= datapo; + end; + for int1:= count - 2 downto 0 do begin + stream.writeln(po1^); + inc(pchar(po1),fsize); + end; + stream.write(po1^); + end; +end; + +function tpoorstringdatalist.textlength: integer; +var + int1,int2: integer; + po1: pchar; +begin + po1:= datapo; + int2:= 0; + for int1:= 0 to fcount - 1 do begin + inc(int2,length(msestring(pointer(po1)^))); + inc(po1,fsize); + end; + result:= int2; +end; + +function tpoorstringdatalist.dataastextstream: ttextstream; + //chars truncated to 8bit +var + len: integer; + int1,int2,int3,int4: integer; + po1,po2: pchar; + bo1: boolean; + ch1,ch2: char; + wch1: widechar; +begin + result:= ttextstream.create; //memorystream + int2:= textlength; + if int2 > 0 then begin + len:= int2+(fcount-1)*length(lineend); + result.setsize(len+sizeof(lineend)); +// getmem(result,len+sizeof(lineend)); + po2:= result.memory; + po1:= datapo; + bo1:= length(lineend) > 1; + ch1:= string(lineend)[1]; + if bo1 then begin + ch2:= string(lineend)[2]; + end + else begin + ch2:= ' '; //compiler warning + end; + for int1:= 0 to fcount - 1 do begin + int4:= length(msestring(pointer(po1)^)); + for int3:= int4 - 1 downto 0 do begin + wch1:= msecharaty(pointer(pointer(po1)^)^)[int3]; + if wch1 > #$ff then begin + wch1:= #$ff; + end; + (po2 + int3)^:= char(byte(wch1)); + end; + inc(po2,int4); + po2^:= ch1; + if bo1 then begin + (po2 + 1)^:= ch2; + inc(po2,2); + end + else begin + inc(po2,1); + end; + inc(po1,fsize); + end; + result.setsize(len+sizeof(lineend)); //remove last newline + end; +end; + +function tpoorstringdatalist.getasarray: msestringarty; +begin + result:= nil; + allocuninitedarray(fcount,sizeof(result[0]),result); +// setlength(result,fcount); //possible memory leak in FPC 3.0 + internalgetasarray(pointer(result),sizeof(msestring)); +end; + +procedure tpoorstringdatalist.setasarray(const data: msestringarty); +begin + internalsetasarray(pointer(data),sizeof(msestring),length(data)); +end; + +function tpoorstringdatalist.getasstringarray: stringarty; +var + int1: integer; + po1: pmsestring; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to count - 1 do begin + result[int1]:= ansistring(po1^); + pchar(po1):= pchar(po1)+fsize; + end; +end; + +procedure tpoorstringdatalist.setasstringarray(const data: stringarty); +var + po1: pmsestring; + int1: integer; + s1: integer; +begin + newbuffer(length(data),true,true); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to high(data) do begin + po1^:= msestring(data[int1]); + inc(pchar(po1),s1); + end; + change(-1); +end; + +procedure tpoorstringdatalist.assignopenarray(const data: array of msestring); +var + po1: pmsestring; + s1: integer; + int1: integer; +begin + newbuffer(length(data),true,true); + po1:= datapo; + s1:= size; + for int1:= 0 to high(data) do begin + po1^:= data[int1]; + inc(pchar(po1),s1); + end; + change(-1); +end; +{ +procedure tpoorstringdatalist.assignarray(const data: stringarty); +var + int1: integer; + po1: pmsestring; +begin + beginupdate; + try + count:= 0; + count:= length(data); + po1:= pointer(fdatapo); + for int1:= 0 to length(data)-1 do begin + po1^:= msestring(data[int1]); + inc(pchar(po1),fsize); + end; + finally + endupdate; + end; +end; + +procedure tpoorstringdatalist.assignarray(const data: msestringarty); +var + int1: integer; + po1: pmsestring; +begin + beginupdate; + try + count:= 0; + count:= length(data); + po1:= pointer(fdatapo); + for int1:= 0 to high(data) do begin + po1^:= data[int1]; + inc(pchar(po1),fsize); + end; + finally + endupdate; + end; +end; +} +function tpoorstringdatalist.indexof(const value: msestring): integer; +var + int1: integer; + po1: pmsestring; +begin + result:= -1; + normalizering; + po1:= pointer(fdatapo); + for int1:= 0 to fcount -1 do begin + if po1^ = value then begin + result:= int1; + break; + end; + inc(pchar(po1),fsize); + end; +end; + +function tpoorstringdatalist.concatstring(const delim: msestring = ''; + const separator: msestring = ''; + const separatornoparagraph: msestring = ''): msestring; +var + int1: integer; + po1: pmsestring; +begin + if fcount > 0 then begin + normalizering; + result:= delim + pmsestring(fdatapo)^ + delim; + for int1:= 1 to fcount-1 do begin + po1:= @separator; + if getnoparagraphs(int1) then begin + po1:= @separatornoparagraph; + end; + result:= result + po1^ + delim + pmsestring(fdatapo+int1*fsize)^ + delim; + end; + end + else begin + result:= ''; + end; +end; + +function tpoorstringdatalist.getstatdata(const index: integer): msestring; +begin + result:= items[index]; +end; + +procedure tpoorstringdatalist.setstatdata(const index: integer; + const value: msestring); +begin + items[index]:= value; +end; + +function tpoorstringdatalist.checkassigncompatibility( + const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tpoorstringdatalist); +end; + +function tpoorstringdatalist.getnoparagraphs(index: integer): boolean; +begin + result:= false; +end; + +function tpoorstringdatalist.getastext(const index: integer): msestring; +begin + result:= items[index]; +end; + +procedure tpoorstringdatalist.setastext(const index: integer; + const avalue: msestring); +begin + items[index]:= avalue; +end; + +function tpoorstringdatalist.gettext: msestring; +var + po1: pmsestring; + po2: pmsechar; + int1: integer; + int2: integer; + ch1,ch2: msechar; +begin + if count = 0 then begin + result:=''; + exit; + end; + int2:= textlength; + int2:= int2 + count * length(lineend); + setlength(result,int2); + ch1:= msechar(byte(string(lineend)[1])); +{$warnings off} + if length(lineend) > 1 then begin + ch2:= msechar(byte(string(lineend)[2])); + end; +{$warnings on} + po1:= datapo; + po2:= pointer(result); + for int1:= count-1 downto 0 do begin + int2:= length(po1^); + if int2 <> 0 then begin + move(pointer(po1^)^,po2^,int2*sizeof(msechar)); + inc(po2,int2); + end; + po2^:= ch1; + inc(po2); +{$warnings off} + if length(lineend) > 1 then begin + po2^:= ch2; + inc(po2); + end; +{$warnings on} + inc(pchar(po1),fsize); + end; + setlength(result,length(result)-length(lineend)); //remove last lineend +end; + +procedure tpoorstringdatalist.settext(const avalue: msestring); +begin + asarray:= breaklines(avalue); +end; + +{ tmsestringdatalist } + +class function tmsestringdatalist.datatype: listdatatypety; +begin + result:= dl_msestring; +end; + +function tmsestringdatalist.add(const value: msestring): integer; +begin + result:= adddata(value); +end; + +procedure tmsestringdatalist.insert(const index: integer; const item: msestring); +begin + insertdata(index,item); +end; + +function tmsestringdatalist.compare(const l,r): integer; +begin + if sdo_naturalsort in foptions then begin + result:= msecomparestrnatural(msestring(l),msestring(r)); + end + else begin + result:= msecomparestr(msestring(l),msestring(r)); + end; +end; + +function tmsestringdatalist.comparecaseinsensitive(const l,r): integer; +begin + if sdo_naturalsort in foptions then begin + result:= msecomparetextnatural(msestring(l),msestring(r)); + end + else begin + result:= msecomparetext(msestring(l),msestring(r)); + end; +end; + +procedure tmsestringdatalist.fill(acount: integer; const defaultvalue: msestring); +begin + internalfill(count,defaultvalue); +end; + +{ tdoublemsestringdatalist } + +function tdoublemsestringdatalist.add(const value: msestring): integer; +begin + result:= add(value,''); +end; + +function tdoublemsestringdatalist.add(const valuea: msestring; + const valueb: msestring = ''): integer; +var + dstr1: doublemsestringty; +begin + dstr1.a:= valuea; + dstr1.b:= valueb; + result:= adddata(dstr1); +end; + +function tdoublemsestringdatalist.add(const value: doublemsestringty): integer; +begin + result:= adddata(value); +end; + +{$ifdef msestringsarenotrefcounted} +procedure tdoublemsestringdatalist.aftercopy(var data); +begin + inherited; + stringaddref(doublemsestringty(data).b); +end; +{$else} +procedure tdoublemsestringdatalist.beforecopy(var data); +begin + inherited; + stringaddref(doublemsestringty(data).b); +end; +{$endif} + +constructor tdoublemsestringdatalist.create; +begin + inherited; + fsize:= sizeof(doublemsestringty); +end; + +class function tdoublemsestringdatalist.datatype: listdatatypety; +begin + result:= dl_doublemsestring; +end; + +procedure tdoublemsestringdatalist.fill(const acount: integer; + const defaultvalue: msestring); +var + dstr1: doublemsestringty; +begin + dstr1.a:= defaultvalue; + dstr1.b:= ''; + internalfill(count,dstr1); +end; + +procedure tdoublemsestringdatalist.freedata(var data); +begin + inherited; + doublemsestringty(data).b:= ''; +end; + +function tdoublemsestringdatalist.Getitemsb(index: integer): msestring; +begin + result:= pdoublemsestringty(getitempo(index))^.b; +end; + +procedure tdoublemsestringdatalist.Setitemsb(index: integer; + const Value: msestring); +begin + pdoublemsestringty(getitempo(index))^.b:= value; +end; + +function tdoublemsestringdatalist.Getdoubleitems(index: integer): doublemsestringty; +begin + result:= pdoublemsestringty(getitempo(index))^; +end; + +procedure tdoublemsestringdatalist.Setdoubleitems(index: integer; + const Value: doublemsestringty); +begin + pdoublemsestringty(getitempo(index))^:= value; +end; + +procedure tdoublemsestringdatalist.insert(const index: integer; + const item: msestring); +var + dstr1: doublemsestringty; +begin + dstr1.a:= item; + dstr1.b:= ''; + insertdata(index,dstr1); +end; + +function tdoublemsestringdatalist.compare(const l,r): integer; +begin + result:= msecomparestr(doublemsestringty(l).a,doublemsestringty(r).a); +end; + +function tdoublemsestringdatalist.comparecaseinsensitive(const l,r): integer; +begin + result:= msecomparetext(doublemsestringty(l).a,doublemsestringty(r).a); +end; + +{ +procedure tdoublemsestringdatalist.assign(source: tpersistent); +var + int1: integer; + po1,po2: pdoublemsestringty; + s1,s2: integer; +begin + if source = self then begin + exit; + end; + if source is tdoublemsestringdatalist then begin + beginupdate; + with tdoublemsestringdatalist(source) do begin + po2:= datapo; + self.clear; + self.count:= count; + po1:= self.datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to count - 1 do begin + po1^:= po2^; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end; + endupdate; + end + else begin + inherited; + end; +end; +} +procedure tdoublemsestringdatalist.assignb(const source: tdatalist); +var + int1: integer; + po1,po2: pdoublemsestringty; + po3: pmsestring; + s1,s2: integer; +begin + if source is tdoublemsestringdatalist then begin + beginupdate; + with tdoublemsestringdatalist(source) do begin + self.count:= fcount; + po1:= self.datapo; + po2:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po1^.b:= po2^.b; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end; + endupdate; + end + else begin + if source is tmsestringdatalist then begin + beginupdate; + with tmsestringdatalist(source) do begin + self.count:= fcount; + po1:= self.datapo; + po3:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po1^.b:= po3^; + inc(pchar(po1),s1); + inc(pchar(po3),s2); + end; + end; + endupdate; + end + else begin + inherited; + end; + end; +end; + +procedure tdoublemsestringdatalist.assigntob(const dest: tdatalist); +var + int1: integer; + po1: pdoublemsestringty; + po2: pmsestring; + s1,s2: integer; +begin + if dest is tmsestringdatalist then begin + with tmsestringdatalist(dest) do begin + beginupdate; + clear; + count:= self.fcount; + po1:= self.datapo; + po2:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po2^:= po1^.b; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + endupdate; + end + end + else begin + inherited; + end; +end; + +procedure tdoublemsestringdatalist.setasarray(const data: doublemsestringarty); +begin + internalsetasarray(pointer(data),sizeof(doublemsestringty),length(data)); +end; + +function tdoublemsestringdatalist.getasarray: doublemsestringarty; +begin + result:= nil; + allocuninitedarray(fcount,sizeof(result[0]),result); +// setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(doublemsestringty)); +end; + +function tdoublemsestringdatalist.getasarraya: msestringarty; +var + int1: integer; + po1: pdoublemsestringty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.a; + inc(pchar(po1),s1); + end; +end; + +procedure tdoublemsestringdatalist.setasarraya(const data: msestringarty); +var + int1: integer; + po1: pdoublemsestringty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.a:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +procedure tdoublemsestringdatalist.setasarrayb(const data: msestringarty); +var + int1: integer; + po1: pdoublemsestringty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.b:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +function tdoublemsestringdatalist.getasarrayb: msestringarty; +var + int1: integer; + po1: pdoublemsestringty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.b; + inc(pchar(po1),s1); + end; +end; + +procedure tdoublemsestringdatalist.readitem(const reader: treader; var value); +begin + with reader do begin + readlistbegin; + {$ifdef fpcbug4519read} + doublemsestringty(value).a:= readwidestring4519(reader); + doublemsestringty(value).b:= readwidestring4519(reader); + {$else} + doublemsestringty(value).a:= treader_readmsestring(reader); + doublemsestringty(value).b:= treader_readmsestring(reader); +// {$ifdef mse_unicodestring} +// doublemsestringty(value).a:= readunicodestring; +// doublemsestringty(value).b:= readunicodestring; +// {$else} +// doublemsestringty(value).a:= readwidestring; +// doublemsestringty(value).b:= readwidestring; +// {$endif} + {$endif} + readlistend; + end; +end; + +procedure tdoublemsestringdatalist.writeitem(const writer: twriter; var value); +begin + with writer do begin + writelistbegin; +// {$ifdef fpcbug4519} +// writewidestring4519(writer,doublemsestringty(value).a); +// writewidestring4519(writer,doublemsestringty(value).b); +// {$else} + twriter_writemsestring(writer,doublemsestringty(value).a); + twriter_writemsestring(writer,doublemsestringty(value).b); +// {$ifdef mse_unicodestring} +// writeunicodestring(doublemsestringty(value).a); +// writeunicodestring(doublemsestringty(value).b); +// {$else} +// writewidestring(doublemsestringty(value).a); +// writewidestring(doublemsestringty(value).b); +// {$endif} +// {$endif} + writelistend; + end; +end; + +{ tmsestringintdatalist } + +constructor tmsestringintdatalist.create; +begin + inherited; + fsize:= sizeof(msestringintty); +end; + +class function tmsestringintdatalist.datatype: listdatatypety; +begin + result:= dl_msestringint; +end; + +function tmsestringintdatalist.add(const value: msestring): integer; +begin + result:= add(value,0); +end; + +function tmsestringintdatalist.add(const valuea: msestring; + const valueb: integer): integer; +var + dstr1: msestringintty; +begin + dstr1.mstr:= valuea; + dstr1.int:= valueb; + result:= adddata(dstr1); +end; + +function tmsestringintdatalist.add(const value: msestringintty): integer; +begin + result:= adddata(value); +end; + +procedure tmsestringintdatalist.fill(const acount: integer; + const defaultvalue: msestring; const defaultint: integer); +var + dstr1: msestringintty; +begin + dstr1.mstr:= defaultvalue; + dstr1.int:= defaultint; + internalfill(count,dstr1); +end; + +function tmsestringintdatalist.Getitemsb(index: integer): integer; +begin + result:= pmsestringintty(getitempo(index))^.int; +end; + +procedure tmsestringintdatalist.Setitemsb(index: integer; + const Value: integer); +begin + pmsestringintty(getitempo(index))^.int:= value; + change(index); +end; + +function tmsestringintdatalist.Getdoubleitems(index: integer): msestringintty; +begin + result:= pmsestringintty(getitempo(index))^; +end; + +procedure tmsestringintdatalist.Setdoubleitems(index: integer; + const Value: msestringintty); +begin + pmsestringintty(getitempo(index))^:= value; + change(index); +end; + +procedure tmsestringintdatalist.insert(const index: integer; + const item: msestring); +begin + insert(index,item,0); +end; + +procedure tmsestringintdatalist.insert(const index: integer; + const item: msestring; const itemint: integer); +var + dstr1: msestringintty; +begin + dstr1.mstr:= item; + dstr1.int:= itemint; + insertdata(index,dstr1); +end; + +function tmsestringintdatalist.compare(const l,r): integer; +begin + result:= msecomparestr(msestringintty(l).mstr,msestringintty(r).mstr); +end; + +function tmsestringintdatalist.comparecaseinsensitive(const l,r): integer; +begin + result:= msecomparetext(msestringintty(l).mstr,msestringintty(r).mstr); +end; + +{ +procedure tmsestringintdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +procedure tmsestringintdatalist.assignb(const source: tdatalist); +var + int1: integer; + po1,po2: pmsestringintty; + po3: pinteger; + s1,s2: integer; +begin + if source is tmsestringintdatalist then begin + beginupdate; + count:= source.count; + with tmsestringintdatalist(source) do begin + po1:= self.datapo; + po2:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to self.fcount-1 do begin + po1^.int:= po2^.int; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end; + endupdate; + end + else begin + if source is tintegerdatalist then begin + beginupdate; + count:= source.count; + with tintegerdatalist(source) do begin + po1:= self.datapo; + po3:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po1^.int:= po3^; + inc(pchar(po1),s1); + inc(pchar(po3),s2); + end; + end; + endupdate; + end + else begin + inherited; + end; + end; +end; + +procedure tmsestringintdatalist.assigntob(const dest: tdatalist); +var + int1: integer; + po1: pmsestringintty; + po2: pinteger; + s1,s2: integer; +begin + if dest is tintegerdatalist then begin + with tintegerdatalist(dest) do begin + newbuffer(self.count,true,dest.size > sizeof(integer)); + po1:= self.datapo; + po2:= pointer(fdatapo); + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po2^:= po1^.int; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + change(-1); + end + end + else begin + inherited; + end; +end; + +procedure tmsestringintdatalist.setasarray(const data: msestringintarty); +begin + internalsetasarray(pointer(data),sizeof(msestringintty),length(data)); +end; + +function tmsestringintdatalist.getasarray: msestringintarty; +begin + result:= nil; + allocuninitedarray(fcount,sizeof(result[0]),result); +// setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(msestringintty)); +end; + +function tmsestringintdatalist.getasarraya: msestringarty; +var + int1: integer; + po1: pmsestringintty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.mstr; + inc(pchar(po1),s1); + end; +end; + +procedure tmsestringintdatalist.setasarraya(const data: msestringarty); +var + int1: integer; + po1: pmsestringintty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.mstr:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +procedure tmsestringintdatalist.setasarrayb(const data: integerarty); +var + int1: integer; + po1: pmsestringintty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.int:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +function tmsestringintdatalist.getasarrayb: integerarty; +var + int1: integer; + po1: pmsestringintty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.int; + inc(pchar(po1),s1); + end; +end; + +procedure tmsestringintdatalist.readitem(const reader: treader; var value); +begin + with reader do begin + readlistbegin; + {$ifdef fpcbug4519read} + msestringintty(value).mstr:= readwidestring4519(reader); + {$else} + msestringintty(value).mstr:= treader_readmsestring(reader); +// {$ifdef mse_unicodestring} +// msestringintty(value).mstr:= readunicodestring; +// {$else} +// msestringintty(value).mstr:= readwidestring; +// {$endif} + {$endif} + msestringintty(value).int:= readinteger; + readlistend; + end; +end; + +procedure tmsestringintdatalist.writeitem(const writer: twriter; var value); +begin + with writer do begin + writelistbegin; +// {$ifdef fpcbug4519} +// writewidestring4519(writer,doublemsestringty(value).a); +// writewidestring4519(writer,doublemsestringty(value).b); +// {$else} + twriter_writemsestring(writer,msestringintty(value).mstr); +// {$ifdef mse_unicodestring} +// writeunicodestring(msestringintty(value).mstr); +// {$else} +// writewidestring(msestringintty(value).mstr); +// {$endif} + writeinteger(msestringintty(value).int); +// {$endif} + writelistend; + end; +end; + +procedure tmsestringintdatalist.setstatdata(const index: integer; + const value: msestring); +var + strint1: msestringintty; + int1: integer; +begin + int1:= findchar(value,','); + if int1 > 0 then begin + strint1.int:= strtoint(copy(value,1,int1-1)); + strint1.mstr:= copy(value,int1+1,bigint); + setdata(index,strint1); + end; +end; + +function tmsestringintdatalist.getstatdata(const index: integer): msestring; +begin + with pmsestringintty(getitempo(index))^ do begin + result:= inttostrmse(int)+','+mstr; + end; +end; + +{ trealintdatalist } + +constructor trealintdatalist.create; +begin + fdefaultval1.rea:= emptyreal; + inherited; + fsize:= sizeof(realintty); +end; + +class function trealintdatalist.datatype: listdatatypety; +begin + result:= dl_realint; +end; + +function trealintdatalist.add(const valuea: realty; + const valueb: integer = 0): integer; +var + d1: realintty; +begin + d1.rea:= valuea; + d1.int:= valueb; + result:= adddata(d1); +end; + +function trealintdatalist.add(const value: realintty): integer; +begin + result:= adddata(value); +end; + +procedure trealintdatalist.fill(const acount: integer; + const defaultvalue: realty; const defaultint: integer); +var + d1: realintty; +begin + d1.rea:= defaultvalue; + d1.int:= defaultint; + internalfill(count,d1); +end; + +function trealintdatalist.Getitemsb(index: integer): integer; +begin + result:= prealintty(getitempo(index))^.int; +end; + +procedure trealintdatalist.Setitemsb(index: integer; + const Value: integer); +begin + prealintty(getitempo(index))^.int:= value; + change(index); +end; + +function trealintdatalist.Getdoubleitems(index: integer): realintty; +begin + result:= prealintty(getitempo(index))^; +end; + +procedure trealintdatalist.Setdoubleitems(index: integer; + const Value: realintty); +begin + prealintty(getitempo(index))^:= value; + change(index); +end; + +procedure trealintdatalist.insert(const index: integer; + const item: realty; const itemint: integer); +var + d1: realintty; +begin + d1.rea:= item; + d1.int:= itemint; + insertdata(index,d1); +end; + +function trealintdatalist.compare(const l,r): integer; +begin + result:= cmprealty(realintty(l).rea,realintty(r).rea); +end; +{ +procedure trealintdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +procedure trealintdatalist.assignb(const source: tdatalist); +var + int1: integer; + po1,po2: prealintty; + po3: pinteger; + s1,s2: integer; +begin + if source is trealintdatalist then begin + beginupdate; + count:= source.count; + with trealintdatalist(source) do begin + po1:= self.datapo; + po2:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to self.fcount-1 do begin + po1^.int:= po2^.int; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end; + endupdate; + end + else begin + if source is tintegerdatalist then begin + beginupdate; + count:= source.count; + with tintegerdatalist(source) do begin + po1:= self.datapo; + po3:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po1^.int:= po3^; + inc(pchar(po1),s1); + inc(pchar(po3),s2); + end; + end; + endupdate; + end + else begin + inherited; + end; + end; +end; + +procedure trealintdatalist.assigntob(const dest: tdatalist); +var + int1: integer; + po1: prealintty; + po2: pinteger; + s1,s2: integer; +begin + if dest is tintegerdatalist then begin + with tintegerdatalist(dest) do begin + newbuffer(self.count,true,dest.size > sizeof(integer)); + po1:= self.datapo; + po2:= pointer(fdatapo); + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po2^:= po1^.int; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + change(-1); + end + end + else begin + inherited; + end; +end; + +procedure trealintdatalist.setasarray(const data: realintarty); +begin + internalsetasarray(pointer(data),sizeof(realintty),length(data)); +end; + +function trealintdatalist.getasarray: realintarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(realintty)); +end; + +function trealintdatalist.getasarraya: realarty; +var + int1: integer; + po1: prealintty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.rea; + inc(pchar(po1),s1); + end; +end; + +procedure trealintdatalist.setasarraya(const data: realarty); +var + int1: integer; + po1: prealintty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.rea:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +procedure trealintdatalist.setasarrayb(const data: integerarty); +var + int1: integer; + po1: prealintty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.int:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +function trealintdatalist.getasarrayb: integerarty; +var + int1: integer; + po1: prealintty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.int; + inc(pchar(po1),s1); + end; +end; + +procedure trealintdatalist.readitem(const reader: treader; var value); +begin + with reader do begin + readlistbegin; + realintty(value).rea:= readrealty(reader); + realintty(value).int:= readinteger; + readlistend; + end; +end; + +procedure trealintdatalist.writeitem(const writer: twriter; var value); +begin + with writer do begin + writelistbegin; + writer.writefloat(realintty(value).rea); +// writerealty(writer,realintty(value).rea); + writeinteger(realintty(value).int); + writelistend; + end; +end; + +procedure trealintdatalist.setstatdata(const index: integer; + const value: msestring); +var + d1: realintty; + int1: integer; +begin + int1:= findchar(value,','); + if int1 > 0 then begin + d1.rea:= strtorealtydot(copy(value,1,int1-1)); + if cmprealty(d1.rea,min) < 0 then begin + d1.rea:= min; + end + else begin + if cmprealty(d1.rea,max) > 0 then begin + d1.rea:= max; + end; + end; + d1.int:= strtoint(copy(value,int1+1,bigint)); + setdata(index,d1); + end; +end; + +function trealintdatalist.getstatdata(const index: integer): msestring; +begin + with prealintty(getitempo(index))^ do begin + result:= realtytostrdotmse(rea)+','+inttostrmse(int); + end; +end; + +function trealintdatalist.getdefault: pointer; +begin + if fdefaultzero then begin + result:= nil; + end + else begin + result:= @fdefaultval1; + end; +end; + +procedure trealintdatalist.fill(const defaultvalue: realty; + const defaultint: integer); +begin + fill(count,defaultvalue,defaultint); +end; + +{ tcustomrowstatelist } + +constructor tcustomrowstatelist.create; +begin + inherited; + fsize:= sizeof(rowstatety); +end; + +constructor tcustomrowstatelist.create(const ainfolevel: rowinfolevelty); +begin + finfolevel:= ainfolevel; + inherited create; + case finfolevel of + ril_colmerge: begin + fsize:= sizeof(rowstatecolmergety); + end; + ril_rowheight: begin + fsize:= sizeof(rowstaterowheightty); + end; + else begin + fsize:= sizeof(rowstatety); + end; + end; +end; + +class function tcustomrowstatelist.datatype: listdatatypety; +begin + result:= dl_rowstate; +end; + +function tcustomrowstatelist.getitempo(const index: integer): prowstatety; +begin + result:= prowstatety(inherited getitempo(index)); +end; + +function tcustomrowstatelist.getrowstate(const index: integer): rowstatety; +begin + getdata(index,result); +end; + +procedure tcustomrowstatelist.setrowstate(const index: integer; + const Value: rowstatety); +begin + setdata(index,value); +end; + +function tcustomrowstatelist.getrowstatecolmerge(const index: integer): rowstatecolmergety; +begin + checkinfolevel(ril_colmerge); + getdata(index,result); +end; + +procedure tcustomrowstatelist.setrowstatecolmerge(const index: integer; + const Value: rowstatecolmergety); +begin + checkinfolevel(ril_colmerge); + setdata(index,value); +end; + +function tcustomrowstatelist.getrowstaterowheight(const index: integer): rowstaterowheightty; +begin + checkinfolevel(ril_rowheight); + getdata(index,result); +end; + +procedure tcustomrowstatelist.setrowstaterowheight(const index: integer; + const Value: rowstaterowheightty); +begin + checkinfolevel(ril_rowheight); + setdata(index,value); +end; + +function tcustomrowstatelist.mergecols(const arow: integer; const astart: longword; + const acount: longword): boolean; +var + ca1,ca2: longword; +begin + result:= false; + if (astart < mergedcolmax - 1) and (acount > 0) then begin + with getitempocolmerge(arow)^ do begin + if (astart = 0) and (acount > mergedcolmax) then begin + ca2:= mergedcolall; + end + else begin + ca1:= acount; + if ca1 + astart > mergedcolmax then begin + ca1:= mergedcolmax - astart; + end; + ca2:= colmerge.merged or (bitmask[ca1] shl astart); + end; + if colmerge.merged <> ca2 then begin + colmerge.merged:= ca2; + result:= true; + end; + end; + end; +end; + +function tcustomrowstatelist.unmergecols(const arow: integer): boolean; +var + int1: integer; + po1: prowstatecolmergeaty; +begin + result:= false; + if arow = invalidaxis then begin + po1:= datapocolmerge; + for int1:= 0 to count - 1 do begin + if po1^[int1].colmerge.merged <> 0 then begin + result:= true; + po1^[int1].colmerge.merged:= 0; + end; + end; + end + else begin + with getitempocolmerge(arow)^ do begin + if colmerge.merged <> 0 then begin + result:= true; + colmerge.merged:= 0; + end; + end; + end; +end; + +function tcustomrowstatelist.gethidden(const index: integer): boolean; +begin + result:= getitempo(index)^.fold and foldhiddenmask <> 0; +end; + +function tcustomrowstatelist.getfoldinfoar: bytearty; +var + int1: integer; + po1: prowstatety; +begin + setlength(result,count); + po1:= datapo; + inc(po1,count); + for int1:= high(result) downto 0 do begin + dec(po1); + result[int1]:= po1^.fold; + end; +end; + +function tcustomrowstatelist.getfoldlevel(const index: integer): byte; +begin + result:= getitempo(index)^.fold and foldlevelmask; +end; + +procedure tcustomrowstatelist.setfoldlevel(const index: integer; + const avalue: byte); +begin + with getitempo(index)^ do begin + fold:= replacebits(avalue,fold,foldlevelmask); + end; + checkdirty(index); +end; + +procedure tcustomrowstatelist.sethidden(const index: integer; + const avalue: boolean); +begin + with getitempo(index)^ do begin + updatebit(fold,foldhiddenbit,avalue); + end; + checkdirty(index); +end; + +procedure tcustomrowstatelist.setfoldissum(const index: integer; + const avalue: boolean); +begin + with getitempo(index)^ do begin + updatebit(fold,foldissumbit,avalue); + end; + checkdirty(index); +end; + +function tcustomrowstatelist.getfoldissum(const index: integer): boolean; +begin + result:= getitempo(index)^.flags and foldissummask <> 0; +end; + +{ +procedure tcustomrowstatelist.assign(source: tpersistent); +begin + if source is tcustomrowstatelist then begin + with tcustomrowstatelist(source) do begin + self.beginupdate; + self.count:= count; + move(datapo^,self.datapo^,count*sizeof(rowstatety)); + self.endupdate; + end; + end + else begin + inherited; + end; +end; +} +function tcustomrowstatelist.getcolor(const index: integer): rowstatenumty; +begin + result:= (getitempo(index)^.color and rowstatemask) - 1; +end; + +procedure tcustomrowstatelist.setcolor(const index: integer; + const avalue: rowstatenumty); +begin + with getitempo(index)^ do begin + color:= replacebits(avalue + 1,color,rowstatemask); + end; +end; + +function tcustomrowstatelist.getlinecolor(const index: integer): rowstatenumty; +begin + result:= (getitemporowheight(index)^.rowheight.linecolor and rowstatemask) - 1; +end; + +procedure tcustomrowstatelist.setlinecolor(const index: integer; + const avalue: rowstatenumty); +begin + with getitemporowheight(index)^.rowheight do begin + linecolor:= replacebits(avalue + 1,linecolor,rowstatemask); + end; +end; + +function tcustomrowstatelist.getlinecolorfix(const index: integer): rowstatenumty; +begin + result:= (getitemporowheight(index)^.rowheight.linecolorfix and + rowstatemask) - 1; +end; + +procedure tcustomrowstatelist.setlinecolorfix(const index: integer; + const avalue: rowstatenumty); +begin + with getitemporowheight(index)^.rowheight do begin + linecolorfix:= replacebits(avalue + 1,linecolorfix,rowstatemask); + end; +end; + +function tcustomrowstatelist.getfont(const index: integer): rowstatenumty; +begin + result:= (getitempo(index)^.font and rowstatemask) - 1; +end; + +procedure tcustomrowstatelist.setfont(const index: integer; + const avalue: rowstatenumty); +begin + with getitempo(index)^ do begin + font:= replacebits(avalue + 1,font,rowstatemask); + end; +end; + +function tcustomrowstatelist.getreadonly(const index: integer): boolean; +begin + result:= getitempo(index)^.font and $80 <> 0; +end; + +procedure tcustomrowstatelist.setreadonly(const index: integer; + const avalue: boolean); +begin + with getitempo(index)^ do begin + if avalue then begin + font:= font or $80; + end + else begin + font:= font and not $80; + end; + end; +end; + +function tcustomrowstatelist.getflag1(const index: integer): boolean; +begin + result:= getitempo(index)^.color and $80 <> 0; +end; + +procedure tcustomrowstatelist.setflag1(const index: integer; + const avalue: boolean); +begin + with getitempo(index)^ do begin + if avalue then begin + color:= color or $80; + end + else begin + color:= color and not $80; + end; + end; +end; + +function tcustomrowstatelist.getselected(const index: integer): longword; +begin + result:= getitempo(index)^.selected; +end; + +procedure tcustomrowstatelist.setselected(const index: integer; + const avalue: longword); +begin + getitempo(index)^.selected:= avalue; +end; + +function tcustomrowstatelist.getmerged(const index: integer): longword; +begin + result:= getitempocolmerge(index)^.colmerge.merged; +end; + +procedure tcustomrowstatelist.setmerged(const index: integer; + const avalue: longword); +begin + getitempocolmerge(index)^.colmerge.merged:= avalue; +end; + +function tcustomrowstatelist.getheight(const index: integer): integer; +begin + result:= getitemporowheight(index)^.rowheight.height; + if result < 0 then begin + result:= 0; + end; +end; + +function tcustomrowstatelist.getlinewidth(const index: integer): rowlinewidthty; +begin + result:= getitemporowheight(index)^.rowheight.linewidth-1; +end; + +procedure tcustomrowstatelist.checkinfolevel(const wantedlevel: rowinfolevelty); +begin + if wantedlevel > finfolevel then begin + raise exception.create('Wrong rowinfolevel.'); + end; +end; + +function tcustomrowstatelist.datapocolmerge: pointer; +begin + checkinfolevel(ril_colmerge); + result:= datapo; +end; + +function tcustomrowstatelist.dataporowheight: pointer; +begin + checkinfolevel(ril_rowheight); + result:= datapo; +end; + +function tcustomrowstatelist.getitempocolmerge(const index: integer): prowstatecolmergety; +begin + checkinfolevel(ril_colmerge); + result:= prowstatecolmergety(inherited getitempo(index)); +end; + +function tcustomrowstatelist.getitemporowheight(const index: integer): prowstaterowheightty; +begin + checkinfolevel(ril_rowheight); + result:= prowstaterowheightty(inherited getitempo(index)); +end; + +procedure tcustomrowstatelist.initdirty; +begin + //dummy +end; + +procedure tcustomrowstatelist.recalchidden; +begin + //dummy +end; + +function tcustomrowstatelist.checkassigncompatibility( + const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tcustomrowstatelist); +end; + +procedure tcustomrowstatelist.change(const aindex: integer); +begin + if (aindex < 0) and (aindex <> -2) then begin //no count change + initdirty; + end; + inherited; +end; + +procedure tcustomrowstatelist.readstate(const reader; const acount: integer; + const name: msestring); +begin + initdirty; + inherited; + recalchidden; +end; + +procedure tcustomrowstatelist.assign(source: tpersistent); +begin + inherited; + recalchidden; +end; + +function tcustomrowstatelist.checkwritedata(const filer: tfiler): boolean; +begin + result:= false; +end; + +function tcustomrowstatelist.getcolorar: integerarty; +var + po1: prowstatety; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= (po1^.color and rowstatemask) - 1; + inc(pchar(po1),fsize); + end; +end; + +procedure tcustomrowstatelist.setcolorar(const avalue: integerarty); +var + po1: prowstatety; + int1: integer; +begin +// beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + po1^.color:= replacebits(avalue[int1] + 1,po1^.color,rowstatemask); + inc(pchar(po1),fsize); + end; +// endupdate; +end; + +function tcustomrowstatelist.getfontar: integerarty; +var + po1: prowstatety; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= (po1^.font and rowstatemask) - 1; + inc(pchar(po1),fsize); + end; +end; + +procedure tcustomrowstatelist.setfontar(const avalue: integerarty); +var + po1: prowstatety; + int1: integer; +begin +// beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + po1^.font:= replacebits(avalue[int1] + 1,po1^.font,rowstatemask); + inc(pchar(po1),fsize); + end; +// endupdate; +end; + +function tcustomrowstatelist.getfoldlevelar: integerarty; +var + po1: prowstatety; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= (po1^.fold and foldlevelmask); + inc(pchar(po1),fsize); + end; +end; + +procedure tcustomrowstatelist.setfoldlevelar(const avalue: integerarty); +var + po1: prowstatety; + int1: integer; +begin +// beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + po1^.fold:= replacebits(avalue[int1] + 1,po1^.fold,foldlevelmask); + inc(pchar(po1),fsize); + end; + if avalue <> nil then begin + checkdirty(0); + end; +// endupdate; +end; + +function tcustomrowstatelist.gethiddenar: longboolarty; +var + po1: prowstatety; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= (po1^.fold and foldhiddenmask) <> 0; + inc(pchar(po1),fsize); + end; +end; + +procedure tcustomrowstatelist.sethiddenar(const avalue: longboolarty); +var + po1: prowstatety; + int1: integer; +begin +// beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + updatebit(po1^.fold,foldhiddenbit,avalue[int1]); + inc(pchar(po1),fsize); + end; + if avalue <> nil then begin + checkdirty(0); + end; +// endupdate; +end; + +function tcustomrowstatelist.getfoldissumar: longboolarty; +var + po1: prowstatety; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= (po1^.fold and foldissummask) <> 0; + inc(pchar(po1),fsize); + end; +end; + +procedure tcustomrowstatelist.setfoldissumar(const avalue: longboolarty); +var + po1: prowstatety; + int1: integer; +begin +// beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + updatebit(po1^.fold,foldissumbit,avalue[int1]); + inc(pchar(po1),fsize); + end; + if avalue <> nil then begin + checkdirty(0); + end; +// endupdate; +end; + +procedure tcustomrowstatelist.checkdirty(const arow: integer); +begin + //dummy +end; +(* +{ tlinindexmse } + +function tlinindexmse.find(key: pointer; nearest : boolean): integer; +var + l,r,p: integer; + int1: integer; +begin + l:= 0; + r:= count-1; + result:= -1; + if assigned(fcomparefunc) and (r > 0) then begin + p:= 0; int1:= 0; //compilerwarnungen verhindern + while true do begin + p:= (l+r) shr 1; + int1:= fcomparefunc(list^[p],key); + if l = r then begin + break; + end; + if int1 < 0 then begin + l:= p+1; + end + else begin + r:= p; + end; + end; + if int1 < 0 then begin + inc(p); + end; + if nearest or (int1 = 0) then begin + result:= p; + end; + end; +end; + +function tlinindexmse.insert(value: pointer): integer; +var + int1: integer; +begin + int1:= find(value,true); + if int1 < 0 then begin + int1:= 0; + end; + insert(int1,value); + result:= int1; +end; + +procedure tlinindexmse.QuickSort(L, R: Integer); +var + I, J: Integer; + P,T: Pointer; + pivotnum,pivotsortnum: integer; + int1: integer; +begin + repeat + I := L; + J := R; + pivotnum:= (L + R) shr 1; + pivotsortnum:= fsortnums[pivotnum]; + P := self.list^[pivotnum]; + repeat + while true do begin + int1:= fcomparefunc(self.list^[I], P); + if int1 = 0 then begin + int1:= fsortnums[I]-pivotsortnum; + end; + if int1 >= 0 then begin + break; + end; + Inc(I); + end; + while true do begin + int1:= fcomparefunc(self.list^[J], P); + if int1 = 0 then begin + int1:= fsortnums[J]-pivotsortnum; + end; + if int1 <= 0 then begin + break; + end; + Dec(J); + end; + if I <= J then begin + T := self.list^[I]; + self.list^[I] := self.list^[J]; + self.list^[J] := T; + int1:= fsortnums[I]; + fsortnums[I]:= fsortnums[J]; + fsortnums[J]:= int1; + Inc(I); + Dec(J); + end; + until I > J; + if L < J then + QuickSort(L, J); + L := I; + until I >= R; +end; + +procedure tlinindexmse.reindex; +var + int1: integer; +begin + if assigned(fcomparefunc) and (self.list <> nil) then begin + setlength(fsortnums,count); + for int1:= 0 to count-1 do begin + fsortnums[int1]:= int1; + end; + quicksort(0,count-1); + setlength(fsortnums,0); + end; +end; + +procedure tlinindexmse.Setcomparefunc(const Value: indexcomparety); +begin + if @fcomparefunc <> @value then begin + Fcomparefunc:= Value; + fsortvalid:= false; + end; +end; +*) + +{ tobjectdatalist } + +constructor tobjectdatalist.create; +begin + inherited; + fstate:= (fstate - [dls_needscopy]) + [dls_needsinit]; +end; + +procedure tobjectdatalist.checkitemclass(const aitem: tobject); +begin + if (fitemclass <> nil) and not (aitem is fitemclass) then begin + raise exception.create('Item must be "'+fitemclass.classname+'".'); + end; +end; + +function tobjectdatalist.add(const aitem: tobject): integer; +begin + checkitemclass(aitem); + result:= adddata(aitem); +end; + +function tobjectdatalist.extract(const index: integer): tobject; //no finalize +begin + result:= self[index]; + internaldeletedata(index,false); +end; +{ +procedure tobjectdatalist.copyinstance(var data); +begin + tobject(data):= nil; + initinstance(data); +end; +} +procedure tobjectdatalist.freedata(var data); +begin + freeandnil(tobject(data)); +end; + +procedure tobjectdatalist.docreateobject(var instance: tobject); +begin + if instance = nil then begin + if assigned(foncreateobject) then begin + foncreateobject(self,instance); + end; + end; +end; + +procedure tobjectdatalist.initinstance(var data); +begin + docreateobject(tobject(data)); +end; + +function tobjectdatalist.Getitems(index: integer): tobject; +begin + internalgetdata(index,result); +end; + + +procedure tobjectdatalist.setitems(index: integer; const Value: tobject); +var + po1: pobject; +begin + po1:= getitempo(index); + freedata(po1^); + po1^:= value; +end; + +function tobjectdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tobjectdatalist); +end; + +{ tnonedatalist } + +class function tnonedatalist.datatype: listdatatypety; +begin + result:= dl_none; +end; + +end. diff --git a/mseide-msegui/lib/common/container/msehash.pas b/mseide-msegui/lib/common/container/msehash.pas new file mode 100644 index 0000000..41331f7 --- /dev/null +++ b/mseide-msegui/lib/common/container/msehash.pas @@ -0,0 +1,3280 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msehash; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msestrings,msetypes; +// +//todo: use objects instead of records +// +type + identty = card32; + pidentty = ^identty; + hashvaluety = card32; + phashvaluety = ^hashvaluety; + hashoffsetty = int32;//ptruint; + phashoffsetty = ^hashoffsetty; + hashoffsetarty = array of hashoffsetty; + + hashheaderty = record + prevhash: hashoffsetty; //offset from liststart + nexthash: hashoffsetty; //offset from liststart + prevlist: hashoffsetty; //memory offset to previous item + nextlist: hashoffsetty; //memory offset to next item + hash: hashvaluety; +//dummy: card32; + end; + phashheaderty = ^hashheaderty; +{ + hashdatadataty = record + end; + phashdatadataty = ^hashdatadataty; +} + hashdataty = record + header: hashheaderty; +// data: hashdatadataty; + end; + phashdataty = ^hashdataty; + + hashiteratorprocty = procedure(const aitem: phashdataty) of object; + internalhashiteratorprocty = procedure(const aitem: phashdataty) of object; + keyhashiteratorprocty = procedure(const aitem: phashdataty) of object; + findcheckprocty = procedure(const aitem: phashdataty; + var accept: boolean) of object; + + hashliststatety = (hls_needsnull,hls_needsinit,hls_needsfinalize, + hls_destroying); + hashliststatesty = set of hashliststatety; + + thashdatalist = class + private +// fdatasize: integer; + frecsize: int32; + fcapacity: int32; + fcount: int32; + fassignedfirst: hashoffsetty; //offset to fdata + fassignedlast: hashoffsetty; //offset to fdata + fdeletedroot: hashoffsetty; //offset to fdata + fcurrentitem: hashoffsetty; //offset to fdata.data + fdestpo: phashdataty; + procedure setcapacity(const avalue: integer); + procedure moveitem(const aitem: phashdataty); + function getdatasize: int32; + protected + fdata: pointer; //first record is a dummy + fmask: hashvaluety; + fhashtable: hashoffsetarty;//ptruintarty; + fstate: hashliststatesty; + {$ifdef mse_debug_hash} + procedure checkhash; + procedure checkexists(const aitem: phashdataty); + procedure checknotexists(const aitem: phashdataty); + {$endif} + property data: pointer read fdata; + property assignedfirst: hashoffsetty read fassignedfirst; + property assignedlast: hashoffsetty read fassignedlast; + function getdatapoornil(const aoffset: hashoffsetty): pointer; inline; + function getdatapo(const aoffset: hashoffsetty): pointer; inline; + function getdataoffs(const adata: pointer): hashoffsetty; inline; + function internaladd(const akey): phashdataty; + function internaladdhash(hash1: hashvaluety): phashdataty; + procedure inserthash(ahash: hashvaluety; const adata: phashdataty); + procedure removehash(aitem: phashdataty); // does not delete ithem + procedure internaldeleteitem(const aitem: phashdataty); overload; +// procedure internaldeleteitem(const aitem: phashdatadataty); overload; + procedure internaldelete(const aoffset: hashoffsetty); + function internaldelete(const akey; const all: boolean): boolean; + function internalfind(const akey): phashdataty; overload; + function internalfind(const akey; + hash1: hashvaluety): phashdataty; overload; + function internalfind(const akey; out acount: integer): phashdataty; overload; + function internalfind(const akey; + const acheckproc: findcheckprocty): phashdataty; overload; + function internalfind(const akey; + const acheckproc: findcheckprocty; + out acount: integer): phashdataty; overload; + function internalfindexact(const akey): phashdataty; overload; + function internalfindexact(const akey; + out acount: integer): phashdataty; overload; + procedure checkexact(const aitem: phashdataty; var accept: boolean) virtual; + function hashkey(const akey): hashvaluety; virtual; abstract; + function checkkey(const akey; + const aitem: phashdataty): boolean; virtual; abstract; + function getrecordsize(): int32 virtual abstract; + procedure rehash; + procedure grow; + procedure inititem(const aitem: phashdataty) virtual; + procedure finalizeitem(const aitem: phashdataty) virtual; + procedure internaliterate( + const aiterator: internalhashiteratorprocty); overload; + procedure iterate(const akey; + const aiterator: keyhashiteratorprocty); overload; + function internalfirstx: phashdataty; + function internallastx: phashdataty; + function internalnextx: phashdataty; + function internalprevx: phashdataty; + public + constructor create(); + destructor destroy; override; + procedure clear; virtual; + procedure reset; //next next() will return first, next prev() will return last + property datasize: int32 read getdatasize; + property capacity: integer read fcapacity write setcapacity; + property count: integer read fcount; + procedure mark(out ref: hashoffsetty); + procedure release(const ref: hashoffsetty); + function absdata(const ref: ptrint): pointer; + //returns pointer to hashdataty.data from mark(ref) + property recsize: int32 read frecsize; + procedure iterate(const aiterator: hashiteratorprocty); overload; + end; + + integerdataty = record + key: integer; +// data: record end; + end; + pintegerdataty = ^integerdataty; + integerhashdataty = record + header: hashheaderty; + data: integerdataty; + end; + pintegerhashdataty = ^integerhashdataty; + + tintegerhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(); + function add(const akey: integer): pintegerhashdataty; + function addunique(const akey: integer): pintegerhashdataty; + function addunique(const akey: integer; + out adata: pintegerhashdataty): boolean; + //true if new + function find(const akey: integer): pintegerhashdataty; + function delete(const akey: integer; + const all: boolean = false): boolean; overload; + //true if found + function first: pintegerhashdataty; + function next: pintegerhashdataty; //wraps to first after last + function last: pintegerhashdataty; + function prev: pintegerhashdataty; //wraps to last after first + end; + + doubleintegerty = record + a: integer; + b: integer; + end; + doubleintegerdataty = record + key: doubleintegerty; +// data: record end; + end; + pdoubleintegerdataty = ^doubleintegerdataty; + doubleintegerhashdataty = record + header: hashheaderty; + data: doubleintegerdataty; + end; + pdoubleintegerhashdataty = ^doubleintegerhashdataty; + + tdoubleintegerhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(const datasize: integer); + function add(const akeya,akeyb: integer): pdoubleintegerhashdataty; + function addunique(const akeya,akeyb: integer): pdoubleintegerhashdataty; + function addunique(const akeya,akeyb: integer; + out adata: pdoubleintegerhashdataty): boolean; + //true if new + function find(const akeya,akeyb: integer): pdoubleintegerhashdataty; + function delete(const akeya,akeyb: integer; + const all: boolean = false): boolean; overload; + //true if found + function first: pdoubleintegerhashdataty; + function next: pdoubleintegerhashdataty; //wraps to first after last + function last: pdoubleintegerhashdataty; + function prev: pdoubleintegerhashdataty; //wraps to last after first + end; + + tripleintegerty = record + a: int32; + b: int32; + c: int32; + end; + tripleintegerdataty = record + key: tripleintegerty; +// data: record end; + end; + ptripleintegerdataty = ^tripleintegerdataty; + tripleintegerhashdataty = record + header: hashheaderty; + data: tripleintegerdataty; + end; + ptripleintegerhashdataty = ^tripleintegerhashdataty; + + ttripleintegerhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(const datasize: integer); + function add(const akeya,akeyb,akeyc: int32): ptripleintegerhashdataty; + function addunique(const akeya,akeyb,akeyc: int32): ptripleintegerhashdataty; + function addunique(const akeya,akeyb,akeyc: int32; + out adata: ptripleintegerhashdataty): boolean; + //true if new + function find(const akeya,akeyb,akeyc: int32): ptripleintegerhashdataty; + function delete(const akeya,akeyb,akeyc: int32; + const all: boolean = false): boolean; overload; + //true if found + function first: ptripleintegerhashdataty; + function next: ptripleintegerhashdataty; //wraps to first after last + function last: ptripleintegerhashdataty; + function prev: ptripleintegerhashdataty; //wraps to last after first + end; + + int32int32dataty = record + key: int32; + data: int32; + end; + pint32int32dataty = ^int32int32dataty; + int32int32hashdataty = record + header: hashheaderty; + data: int32int32dataty; + end; + pint32int32hashdataty = ^int32int32hashdataty; + + int32int32iteratorprocty = + procedure(const aitem: pint32int32hashdataty) of object; + + tint32int32hashdatalist = class(tintegerhashdatalist) + protected + function getrecordsize(): int32 override; + public + procedure add(const akey: int32; const avalue: int32); + function addunique(const akey: int32; const avalue: int32): boolean; + //true if found + function find(const akey: int32): int32; overload; + function find(const akey: int32; out avalue: int32): boolean; overload; + function first: pint32int32hashdataty; + function next: pint32int32hashdataty; //wraps to first after last + function last: pint32int32hashdataty; + function prev: pint32int32hashdataty; //wraps to last after first + end; + + pointerdataty = record + key: pointer; +// data: record end; + end; + ppointerdataty = ^pointerdataty; + pointerhashdataty = record + header: hashheaderty; + data: pointerdataty; + end; + ppointerhashdataty = ^pointerhashdataty; + + tpointerhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(const datasize: integer); + function add(const akey: pointer): ppointerhashdataty; + function addunique(const akey: pointer): ppointerhashdataty; + function find(const akey: pointer): ppointerhashdataty; + function delete(const akey: pointer; + const all: boolean = false): boolean; overload; + //true if found + function first: ppointerhashdataty; + function next: ppointerhashdataty; //wraps to first after last + function last: ppointerhashdataty; + function prev: ppointerhashdataty; //wraps to last after first + end; + + pointerint32dataty = record + key: pointer; + data: int32; + end; + ppointerint32dataty = ^pointerint32dataty; + pointerint32hashdataty = record + header: hashheaderty; + data: pointerint32dataty; + end; + ppointerint32hashdataty = ^pointerint32hashdataty; + + pointerint32iteratorprocty = + procedure(const aitem: ppointerint32hashdataty) of object; + + tpointerint32hashdatalist = class(tpointerhashdatalist) + protected + function getrecordsize(): int32 override; + public + procedure add(const akey: pointer; const avalue: int32); + function addunique(const akey: pointer; const avalue: int32): boolean; + //true if found + function find(const akey: pointer): int32; overload; + function find(const akey: pointer; out avalue: int32): boolean; overload; + function first: ppointerint32hashdataty; + function next: ppointerint32hashdataty; //wraps to first after last + function last: ppointerint32hashdataty; + function prev: ppointerint32hashdataty; //wraps to last after first + end; + + ptruintdataty = record + key: ptruint; +// data: record end; + end; + pptruintdataty = ^ptruintdataty; + ptruinthashdataty = record + header: hashheaderty; + data: ptruintdataty; + end; + pptruinthashdataty = ^ptruinthashdataty; + + tptruinthashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(const datasize: integer); + function add(const akey: ptruint): pptruinthashdataty; + function addunique(const akey: ptruint): pptruinthashdataty; + function find(const akey: ptruint): pptruinthashdataty; + function delete(const akey: ptruint; + const all: boolean = false): boolean; overload; + //true if found + function first: pptruinthashdataty; + function next: pptruinthashdataty; //wraps to first after last + function last: pptruinthashdataty; + function prev: pptruinthashdataty; //wraps to last after first + end; + + pointerptruintdataty = record + key: ptruint; + data: pointer; + end; + ppointerptruintdataty = ^pointerptruintdataty; + pointerptruinthashdataty = record + header: hashheaderty; + data: pointerptruintdataty; + end; + ppointerptruinthashdataty = ^pointerptruinthashdataty; + + pointerptruintiteratorprocty = + procedure(const aitem: pointerptruinthashdataty) of object; + + tpointerptruinthashdatalist = class(tptruinthashdatalist) + private + fpointerparam: pointer; + protected + procedure checkexact(const aitem: phashdataty; + var accept: boolean); override; + function getrecordsize(): int32 override; + public +// constructor create; + procedure add(const akey: ptruint; const avalue: pointer); + function addunique(const akey: ptruint; const avalue: pointer): boolean; + //true if found + procedure delete(const akey: ptruint; const avalue: pointer); overload; + function find(const akey: ptruint): pointer; overload; + function find(const akey: ptruint; out avalue: pointer): boolean; overload; + function first: ppointerptruinthashdataty; + function next: ppointerptruinthashdataty; //wraps to first after last + function last: ppointerptruinthashdataty; + function prev: ppointerptruinthashdataty; //wraps to last after first + procedure iterate(const akey: ptruint; + const aiterator: pointerptruintiteratorprocty); overload; + end; + + ansistringptruintdataty = record + key: ptruint; + data: ansistring; + end; + pansistringptruintdataty = ^ansistringptruintdataty; + ansistringptruinthashdataty = record + header: hashheaderty; + data: ansistringptruintdataty; + end; + pansistringptruinthashdataty = ^ansistringptruinthashdataty; + + ansistringptruintiteratorprocty = + procedure(const aitem: pansistringptruinthashdataty) of object; + + tansistringptruinthashdatalist = class(tptruinthashdatalist) + private + fansistringparam: ansistring; + protected + procedure checkexact(const aitem: phashdataty; var accept: boolean) override; + procedure finalizeitem(const aitem: phashdataty) override; + function getrecordsize(): int32 override; + public + constructor create; + procedure add(const akey: ptruint; const avalue: ansistring); + function addunique(const akey: ptruint; const avalue: ansistring): boolean; + //true if found + procedure delete(const akey: ptruint; const avalue: ansistring) overload; + function find(const akey: ptruint): ansistring overload; + function find(const akey: ptruint; out avalue: ansistring): boolean overload; + function first: pansistringptruinthashdataty; + function next: pansistringptruinthashdataty; //wraps to first after last + function last: pansistringptruinthashdataty; + function prev: pansistringptruinthashdataty; //wraps to last after first + procedure iterate(const akey: ptruint; + const aiterator: ansistringptruintiteratorprocty) overload; + function setdata(const akey: ptruint; const avalue: ansistring): boolean; + //false if not found + end; + + msestringptruintdataty = record + key: ptruint; + data: msestring; + end; + pmsestringptruintdataty = ^msestringptruintdataty; + msestringptruinthashdataty = record + header: hashheaderty; + data: msestringptruintdataty; + end; + pmsestringptruinthashdataty = ^msestringptruinthashdataty; + + msestringptruintiteratorprocty = + procedure(const aitem: pmsestringptruinthashdataty) of object; + + tmsestringptruinthashdatalist = class(tptruinthashdatalist) + private + fmsestringparam: msestring; + protected + procedure checkexact(const aitem: phashdataty; + var accept: boolean); override; + procedure finalizeitem(const aitem: phashdataty); override; + function getrecordsize(): int32 override; + public + constructor create; + procedure add(const akey: ptruint; const avalue: msestring); + function addunique(const akey: ptruint; const avalue: msestring): boolean; + //true if found + procedure delete(const akey: ptruint; const avalue: msestring); overload; + function find(const akey: ptruint): msestring; overload; + function find(const akey: ptruint; out avalue: msestring): boolean; overload; + function first: pmsestringptruinthashdataty; + function next: pmsestringptruinthashdataty; //wraps to first after last + function last: pmsestringptruinthashdataty; + function prev: pmsestringptruinthashdataty; //wraps to last after first + procedure iterate(const akey: ptruint; + const aiterator: msestringptruintiteratorprocty); overload; + function setdata(const akey: ptruint; const avalue: msestring): boolean; + //false if not found + end; + + ansistringdataty = record + key: ansistring; +// data: record end; + end; + pansistringdataty = ^ansistringdataty; + ansistringhashdataty = record + header: hashheaderty; + data: ansistringdataty; + end; + pansistringhashdataty = ^ansistringhashdataty; + + ansistringhashiteratorprocty = + procedure(const aitem: pansistringhashdataty) of object; + + tansistringhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function hashlkey(const akey: lstringty): hashvaluety; + function checklkey(const akey: lstringty; + const aitemdata: ansistringdataty): boolean; + procedure finalizeitem(const aitem: phashdataty) override; + function getrecordsize(): int32 override; + public + constructor create(); + function add(const akey: ansistring): pansistringhashdataty; + function addunique(const akey: ansistring): pansistringhashdataty; + function find(const akey: ansistring): pansistringhashdataty; overload; + function find(const akey: lstringty): pansistringhashdataty; overload; + function delete(const akey: ansistring; + const all: boolean = false): boolean; overload; + //true if found + function delete(const akey: lstringty; + const all: boolean = false): boolean; overload; + //true if found + function first: pansistringhashdataty; + function next: pansistringhashdataty; //wraps to first after last + function last: pansistringhashdataty; + function prev: pansistringhashdataty; //wraps to last after first + procedure iterate(const akey: ansistring; + const aiterator: ansistringhashiteratorprocty); overload; + end; + + pointeransistringdataty = record + key: ansistring; + data: pointer; + end; + ppointeransistringdataty = ^pointeransistringdataty; + pointeransistringhashdataty = record + header: hashheaderty; + data: pointeransistringdataty; + end; + ppointeransistringhashdataty = ^pointeransistringhashdataty; + + pointeransistringiteratorprocty = + procedure(const aitem: ppointeransistringhashdataty) of object; + + tpointeransistringhashdatalist = class(tansistringhashdatalist) + private + fpointerparam: pointer; + protected + procedure checkexact(const aitem: phashdataty; var accept: boolean) override; + function getrecordsize(): int32 override; + public +// constructor create; + procedure add(const akey: ansistring; const avalue: pointer); overload; + procedure add(const keys: array of string; + startindex: pointer = pointer($00000001)); overload; + //data = arrayindex + startindex + function addunique(const akey: ansistring; const avalue: pointer): boolean; + //true if found + procedure delete(const akey: ansistring; const avalue: pointer) overload; + function find(const akey: ansistring): pointer; overload; + function find(const akey: ansistring; out avalue: pointer): boolean overload; + function find(const akey: lstringty): pointer; overload; + function first: ppointeransistringhashdataty; + function next: ppointeransistringhashdataty; //wraps to first after last + function last: ppointeransistringhashdataty; + function prev: ppointeransistringhashdataty; //wraps to last after first + procedure iterate(const akey: ansistring; + const aiterator: pointeransistringiteratorprocty) overload; + end; + + msestringdataty = record + key: msestring; +// data: record end; + end; + pmsestringdataty = ^msestringdataty; + msestringhashdataty = record + header: hashheaderty; + data: msestringdataty; + end; + pmsestringhashdataty = ^msestringhashdataty; + + msestringiteratorprocty = + procedure(const aitem: pmsestringhashdataty) of object; + + tmsestringhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function hashlkey(const akey: lmsestringty): hashvaluety; + function checklkey(const akey: lmsestringty; + const aitemdata: msestringdataty): boolean; + procedure finalizeitem(const aitem: phashdataty) override; + function getrecordsize(): int32 override; + public + constructor create(); + function add(const akey: msestring): pmsestringhashdataty; + function addunique(const akey: msestring): pmsestringhashdataty; + function find(const akey: msestring): pmsestringhashdataty; overload; + function find(const akey: lmsestringty): pmsestringhashdataty; overload; + function find(const akey: msestring; + out acount: integer): pmsestringhashdataty; overload; + function delete(const akey: msestring; + const all: boolean = false): boolean; overload; + //true if found + function delete(const akey: lmsestringty; + const all: boolean = false): boolean; overload; + //true if found + function first: pmsestringhashdataty; + function next: pmsestringhashdataty; //wraps to first after last + function last: pmsestringhashdataty; + function prev: pmsestringhashdataty; //wraps to last after first + procedure iterate(const akey: msestring; + const aiterator: msestringiteratorprocty); overload; + end; + + pointermsestringdataty = record + key: msestring; + data: pointer; + end; + ppointermsestringdataty = ^pointermsestringdataty; + pointermsestringhashdataty = record + header: hashheaderty; + data: pointermsestringdataty; + end; + ppointermsestringhashdataty = ^pointermsestringhashdataty; + + pointermsestringiteratorprocty = + procedure(const aitem: ppointermsestringhashdataty) of object; + + tpointermsestringhashdatalist = class(tmsestringhashdatalist) + private + fpointerparam: pointer; + protected + procedure checkexact(const aitem: phashdataty; var accept: boolean) override; + function getrecordsize(): int32 override; + public +// constructor create; + procedure add(const akey: msestring; const avalue: pointer); + function addunique(const akey: msestring; const avalue: pointer): boolean; + //true if found + procedure delete(const akey: msestring; const avalue: pointer); + function find(const akey: msestring): pointer; overload; + function find(const akey: msestring; out avalue: pointer): boolean; overload; + function find(const akey: msestring; out avalue: pointer; + out acount: integer): boolean; overload; + function find(const akey: lmsestringty): pointer; overload; + function first: ppointermsestringhashdataty; + function next: ppointermsestringhashdataty; //wraps to first after last + function last: ppointermsestringhashdataty; + function prev: ppointermsestringhashdataty; //wraps to last after first + procedure iterate(const akey: msestring; + const aiterator: pointermsestringiteratorprocty); overload; + end; + + integermsestringdataty = record + key: msestring; + data: integer; + end; + pintegermsestringdataty = ^integermsestringdataty; + integermsestringhashdataty = record + header: hashheaderty; + data: integermsestringdataty; + end; + pintegermsestringhashdataty = ^integermsestringhashdataty; + + integermsestringiteratorprocty = + procedure(const aitem: pintegermsestringhashdataty) of object; + + tintegermsestringhashdatalist = class(tmsestringhashdatalist) + private + fintegerparam: integer; + protected + procedure checkexact(const aitem: phashdataty; var accept: boolean) override; + function getrecordsize(): int32 override; + public +// constructor create; + procedure add(const akey: msestring; const avalue: integer); + function addunique(const akey: msestring; const avalue: integer): boolean; + //true if found + procedure delete(const akey: msestring; const avalue: integer); + function find(const akey: msestring): integer; overload; //-1 if not found + function find(const akey: msestring; out avalue: integer): boolean; overload; + function find(const akey: msestring; out avalue: integer; + out acount: integer): boolean; overload; + function find(const akey: lmsestringty): integer; overload; //-1 if not found + function first: pintegermsestringhashdataty; + function next: pintegermsestringhashdataty; //wraps to first after last + function last: pintegermsestringhashdataty; + function prev: pintegermsestringhashdataty; //wraps to last after first + procedure iterate(const akey: msestring; + const aiterator: integermsestringiteratorprocty); overload; + end; + + objectmsestringdataty = record + key: msestring; + data: tobject; + end; + pobjectmsestringdataty = ^objectmsestringdataty; + objectmsestringhashdataty = record + header: hashheaderty; + data: objectmsestringdataty; + end; + pobjectmsestringhashdataty = ^objectmsestringhashdataty; + + objectmsestringiteratorprocty = + procedure(const aitem: pobjectmsestringhashdataty) of object; + + tobjectmsestringhashdatalist = class(tpointermsestringhashdatalist) + protected + fownsobjects: boolean; + procedure finalizeitem(const aitem: phashdataty) override; + public + constructor create(const aownsobjects: boolean = true); + procedure add(const akey: msestring; const avalue: tobject); + function addunique(const akey: msestring; const avalue: tobject): boolean; + //true if found + procedure delete(const akey: msestring; const avalue: tobject); + function find(const akey: msestring): tobject; overload; + function find(const akey: msestring; out avalue: tobject): boolean; overload; + function find(const akey: msestring; out avalue: tobject; + out acount: integer): boolean; overload; + function first: pobjectmsestringhashdataty; + function next: pobjectmsestringhashdataty; //wraps to first after last + function last: pobjectmsestringhashdataty; + function prev: pobjectmsestringhashdataty; //wraps to last after first + procedure iterate(const akey: msestring; + const aiterator: objectmsestringiteratorprocty); overload; + end; + +function scramble(const avalue: hashvaluety): hashvaluety; inline; +function datahash(const data; len: integer): longword; //simple +function datahash2(const data; len: integer): longword; +function stringhash(const key: string): longword; overload; +function stringhash(const key: lstringty): longword; overload; +function stringhash(const key: msestring): longword; overload; +function stringhash(const key: lmsestringty): longword; overload; +function pointerhash(const key: pointer): longword; inline; + +procedure addoffs(var dest: hashoffsetarty; const value: hashoffsetty); + +implementation +uses + sysutils,msebits; + +function scramble(const avalue: hashvaluety): hashvaluety; +begin + result:= ((avalue xor (avalue shr 8)) xor (avalue shr 16)) xor (avalue shr 24); +end; + +function datahash(const data; len: integer): longword; +var + po1: pbyte; + int1: integer; + ca1: longword; +begin + ca1:= 0; + po1:= @data; + for int1:= len - 1 downto 0 do begin + inc(ca1,po1^); + inc(po1); + end; + result:= ca1; +end; + +function datahash2(const data; len: integer): longword; +var + po1: pbyte; + int1: integer; + ca1: longword; +begin + ca1:= 0; + po1:= @data; + for int1:= len - 1 downto 0 do begin + ca1:= ((ca1 shl 2) or (ca1 shr (sizeof(ca1) * 8 - 2))) xor po1^; + inc(po1); + end; + result:= ca1; +end; + +function stringhash(const key: string): longword; overload; +var + int1: integer; +begin + result := 0; + for int1 := 1 to length(key) do begin + result := ((result shl 2) or (result shr (sizeof(result) * 8 - 2))) xor + ord(key[int1]); + end; +end; + +function stringhash(const key: lstringty): longword; overload; +var + int1: integer; + po: pcharaty; +begin + result := 0; + po:= pointer(key.po); + for int1:= 0 to key.len - 1 do begin; + result:= ((result shl 2) or (result shr (sizeof(result) * 8 - 2))) xor + ord(po^[int1]); + end; +end; + +function stringhash(const key: msestring): longword; overload; +var + int1: integer; +begin + result:= 0; + for int1 := 1 to length(key) do begin + result := ((result shl 2) or (result shr (sizeof(result) * 8 - 2))) xor + ord(key[int1]); + end; +end; + +function stringhash(const key: lmsestringty): longword; overload; +var + int1: integer; + po: pmsecharaty; +begin + result:= 0; + po:= pointer(key.po); + for int1:= 0 to key.len - 1 do begin + result := ((result shl 2) or (result shr (sizeof(result) * 8 - 2))) xor + ord(po^[int1]); + end; +end; + +function pointerhash(const key: pointer): longword; inline; +begin +{$ifdef cpu64} + result:= scramble((ptruint(key) xor (ptruint(key) shr 32)) xor + (ptruint(key) shr 2)); +{$else} + result:= scramble(ptruint(key) xor (ptruint(key) shr 2)); +{$endif} +end; + +procedure addoffs(var dest: hashoffsetarty; const value: hashoffsetty); +var + i1: int32; +begin + i1:= length(dest); + setlength(dest,i1+1); + dest[i1]:= value; +end; + +{ thashdatalist } + +constructor thashdatalist.create(); +begin +// fdatasize:= datasize; +// frecsize:= (sizeof(hashheaderty) + datasize + 3) and not 3; + frecsize:= (getrecordsize() + 3) and not 3; + inherited create; +end; + +destructor thashdatalist.destroy; +begin + include(fstate,hls_destroying); + clear; + inherited; +end; + +procedure thashdatalist.moveitem(const aitem: phashdataty); +begin + move((pointer(aitem)+sizeof(hashheaderty))^, + (pointer(fdestpo)+sizeof(hashheaderty))^, + frecsize-sizeof(hashheaderty)); + with fdestpo^.header do begin + nextlist:= frecsize; + prevlist:= -frecsize; + hash:= aitem^.header.hash; + end; + inc(pchar(fdestpo),frecsize); +end; + +function thashdatalist.getdatasize: int32; +begin + result:= fcount * frecsize; +end; + +function thashdatalist.getdatapoornil(const aoffset: hashoffsetty): pointer; +begin + result:= nil; + if aoffset <> 0 then begin + result:= fdata+aoffset; + end; +end; + +procedure thashdatalist.setcapacity(const avalue: int32); +var + int1,int2: integer; + po1: pointer; + puint1: hashoffsetty; +begin + if avalue <> fcapacity then begin +{$ifdef mse_debug_hash} + checkhash; +{$endif} + if avalue < fcount then begin + raise exception.create('Capacity < count.'); + end; + if avalue >= {high(ptruint)} maxint div frecsize then begin + raise exception.create('Capacity too big.'); + end; + + if (avalue < fcapacity) and (fdeletedroot <> 0) and + (fcount > 0) then begin //packing necessary + getmem(po1,(avalue+1)*frecsize); + if po1 = nil then begin + raise exception.create('Out of memory.'); + end; + puint1:= frecsize*fcount; + if fcount > 0 then begin + fdestpo:= pointer(pchar(po1) + frecsize); + internaliterate({$ifdef FPC}@{$endif}moveitem); + fassignedlast:= puint1; + fassignedfirst:= frecsize; + end + else begin + fassignedlast:= 0; + fassignedfirst:= 0; + end; + freemem(fdata); + fdata:= po1; + phashdataty(fdata+frecsize)^.header.prevlist:= 0; //end marker + phashdataty(fdata+puint1)^.header.nextlist:= 0; //end marker + if (hls_needsnull in fstate) and (avalue > fcount) then begin + fillchar((pchar(fdata)+puint1+frecsize)^,(avalue-fcount)*frecsize,0); + end; + fdeletedroot:= 0; + end + else begin + {$ifdef FPC} + if reallocmem(fdata,(avalue+1)*frecsize) = nil then begin + raise exception.create('Out of memory.'); + end; + {$else} + reallocmem(fdata,(avalue+1)*frecsize); + {$endif} + if (hls_needsnull in fstate) and (avalue > fcapacity) then begin + fillchar((pchar(fdata)+fcapacity*frecsize+frecsize)^, + (avalue-fcapacity)*frecsize,0); + end; + end; +// phashdataty(fdata)^.header.prevlist:= 0; //end marker +// phashdataty(fdata)^.header.nextlist:= 0; //end marker + //first record is a dummy so offset = 0 -> not assigned + fcapacity:= avalue; + int2:= highestbit(avalue); + int1:= bits[int2]; + if int1 < avalue then begin + int1:= int1 * 2; + inc(int2); + end; + if int1 <> length(fhashtable) then begin + if fhashtable <> nil then begin + fillchar(pointer(fhashtable)^,length(fhashtable)*sizeof(fhashtable[0]),0); + end; + setlength(fhashtable,int1); //additional length nulled by setlength + fmask:= int1 - 1; +// fhashshift:= sizeof(hashvaluety)*8 - int2; + rehash; + end; +{$ifdef mse_debug_hash} + checkhash; +{$endif} + end; +end; + +procedure thashdatalist.rehash; +var + puint2: hashoffsetty; + po1: phashdataty; + po2: phashoffsetty; +begin + if fassignedfirst <> 0 then begin + po1:= pointer(pchar(fdata) + fassignedfirst); + while true do begin + if po1^.header.prevhash >= 0 then begin //hash removed otherwise + po2:= phashoffsetty(pchar(fhashtable) + + (po1^.header.hash and fmask)*sizeof(hashoffsetty)); + puint2:= po2^; + po1^.header.nexthash:= puint2; + po1^.header.prevhash:= 0; + po2^:= pchar(po1) - fdata; + phashdataty(pchar(fdata)+puint2)^.header.prevhash:= po2^; + end; + if po1^.header.nextlist = 0 then begin + break; + end; + inc(pchar(po1),po1^.header.nextlist); + end; + end; +{$ifdef mse_debug_hash} + checkhash; +{$endif} +end; + +procedure thashdatalist.grow; +begin + capacity:= 2*capacity + 256; +end; + +function thashdatalist.internaladdhash(hash1: hashvaluety): phashdataty; +var + puint1,puint2: hashoffsetty;//ptruint; +// hash1: hashvaluety; +begin +{$ifdef mse_debug_hash} + checkhash; +{$endif} + if count = capacity then begin + grow; + end; + if fdeletedroot <> 0 then begin + result:= phashdataty(pchar(fdata)+fdeletedroot); + inc(fdeletedroot,result^.header.nextlist); + if result^.header.nextlist = 0 then begin + fdeletedroot:= 0; + end; + if hls_needsnull in fstate then begin + fillchar((pointer(result)+sizeof(hashheaderty))^, + frecsize-sizeof(hashheaderty),0); + end; + end + else begin + result:= phashdataty(pchar(fdata) + count * frecsize + frecsize); + end; +{$ifdef mse_debug_hash} + checknotexists(result); +{$endif} + result^.header.prevhash:= 0; + result^.header.hash:= hash1; + hash1:= hash1 and fmask; + puint2:= fhashtable[hash1]; + result^.header.nexthash:= puint2; + puint1:= pchar(result) - fdata; + fhashtable[hash1]:= puint1; + phashdataty(pchar(fdata)+puint2)^.header.prevhash:= puint1; + //[0] is dummy + if fcount = 0 then begin + result^.header.prevlist:= 0; + fassignedfirst:= puint1; + end + else begin + result^.header.prevlist:= fassignedlast-puint1; + //memory offset to next item + phashdataty(pchar(fdata)+fassignedlast)^.header.nextlist:= + -result^.header.prevlist; + //memory offset to previous item + end; + result^.header.nextlist:= 0; + fassignedlast:= puint1; //new item is last + inc(fcount); + if hls_needsinit in fstate then begin + inititem(result); + end; +{$ifdef mse_debug_hash} + checkhash; +{$endif} +end; + +function thashdatalist.internaladd(const akey): phashdataty; +begin + result:= internaladdhash(hashkey(akey)); +end; + +procedure thashdatalist.inserthash(ahash: hashvaluety; + const adata: phashdataty); +var + puint1,puint2: hashoffsetty;//ptruint; +begin + adata^.header.prevhash:= 0; + adata^.header.hash:= ahash; + ahash:= ahash and fmask; + puint2:= fhashtable[ahash]; + adata^.header.nexthash:= puint2; + puint1:= pointer(adata) - fdata; + fhashtable[ahash]:= puint1; + phashdataty(fdata+puint2)^.header.prevhash:= puint1; + //[0] is dummy +end; + +procedure thashdatalist.removehash(aitem: phashdataty); +begin + with aitem^.header do begin + if nexthash <> 0 then begin + phashdataty(pchar(fdata)+nexthash)^.header.prevhash:= prevhash; + end; + if prevhash <> 0 then begin + phashdataty(pchar(fdata)+prevhash)^.header.nexthash:= nexthash; + end + else begin + fhashtable[hash and fmask]:= nexthash; + end; + prevhash:= -1; //nothashed mrker + end; +end; + +procedure thashdatalist.internaldeleteitem(const aitem: phashdataty); +var + puint1: hashoffsetty; + bo1: boolean; +begin + if aitem <> nil then begin +{$ifdef mse_debug_hash} + checkexists(aitem); +{$endif} + if pointer(aitem) = pointer(pchar(fdata) + fcurrentitem) then begin + fcurrentitem:= 0; + end; + if hls_needsfinalize in fstate then begin + finalizeitem(aitem); + end; + puint1:= pchar(aitem) - fdata; + with aitem^.header do begin +{$ifdef mse_debug_hash} + if nexthash <> 0 then begin + checkexists(phashdataty(pchar(fdata)+nexthash)); + end; + if prevhash <> 0 then begin + checkexists(phashdataty(pchar(fdata)+prevhash)); + end; +{$endif} + if nexthash <> 0 then begin + phashdataty(pchar(fdata)+nexthash)^.header.prevhash:= prevhash; + end; + if prevhash <> 0 then begin + phashdataty(pchar(fdata)+prevhash)^.header.nexthash:= nexthash; + end + else begin + fhashtable[hash and fmask]:= nexthash; + end; + bo1:= false; + if puint1 <> fassignedfirst then begin //not first + inc(phashdataty(pchar(aitem)+prevlist)^.header.nextlist,nextlist); + end + else begin + bo1:= true; + inc(fassignedfirst,nextlist); + phashdataty(fdata+fassignedfirst)^.header.prevlist:= 0; + end; + if puint1 <> fassignedlast then begin //not last + if not bo1 then begin + inc(phashdataty(pchar(aitem)+nextlist)^.header.prevlist,prevlist); + end; + end + else begin + inc(fassignedlast,prevlist); + phashdataty(fdata+fassignedlast)^.header.nextlist:= 0; + end; + + if fdeletedroot = 0 then begin + nextlist:= 0; + end + else begin + nextlist:= fdeletedroot - puint1; + //memory offset to next deleted item + end; + end; + fdeletedroot:= puint1; + dec(fcount); + if fcount = 0 then begin + fassignedfirst:= 0; + fassignedlast:= 0; + end; +{$ifdef mse_debug_hash} + checkhash; +{$endif} + end; +end; + +procedure thashdatalist.internaldelete(const aoffset: hashoffsetty); +begin + internaldeleteitem(fdata+aoffset); +end; + +procedure thashdatalist.mark(out ref: hashoffsetty); +begin + ref:= fassignedlast; +end; + +procedure thashdatalist.release(const ref: hashoffsetty); +var + po1,pend: phashdataty; +begin + if fassignedlast <> 0 then begin + pend:= pointer(pchar(fdata)+ref); + po1:= pointer(pchar(fdata)+fassignedlast); + while po1 <> pend do begin + internaldeleteitem(po1); + if po1^.header.prevlist = 0 then begin + break; + end; + inc(pchar(po1),po1^.header.prevlist); + end; + end; +end; + +function thashdatalist.absdata(const ref: ptrint): pointer; + //returns pointer to hashdataty.data from mark(ref) +begin + result:= fdata + ref + sizeof(hashheaderty); +end; +{ +procedure thashdatalist.internaldeleteitem(const aitem: phashdatadataty); +begin + if aitem <> nil then begin + internaldeleteitem(phashdataty(pchar(aitem)-sizeof(hashheaderty))); + end; +end; +} +function thashdatalist.internaldelete(const akey; const all: boolean): boolean; +var + po1: phashdataty; +begin + result:= false; + while true do begin + po1:= internalfind(akey); + if po1 = nil then begin + break; + end; + internaldeleteitem(po1); + result:= true; + if not all then begin + break; + end; + end; +end; + +procedure thashdatalist.clear; +begin + if fdata <> nil then begin + if hls_needsfinalize in fstate then begin + iterate({$ifdef FPC}@{$endif}finalizeitem); + end; + freemem(fdata); + fdata:= nil; + fhashtable:= nil; + fcount:= 0; + fcapacity:= 0; + fassignedfirst:= 0; //dummy item + fassignedlast:= 0; //dummy item + fdeletedroot:= 0; //dummy item + end; +end; + +procedure thashdatalist.reset; +begin + fcurrentitem:= 0; +end; + +procedure thashdatalist.iterate(const aiterator: hashiteratorprocty); +var + puint1: hashoffsetty; + po1: phashdataty; +begin + if fcount > 0 then begin + po1:= pointer(pchar(fdata) + fassignedfirst); + while true do begin + puint1:= phashheaderty(po1)^.nextlist; + aiterator(po1); + if puint1 = 0 then begin + break; + end; + inc(pchar(po1),puint1); + end; + end; +end; + +procedure thashdatalist.iterate(const akey; + const aiterator: keyhashiteratorprocty); +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; +begin + po1:= nil; + if count > 0 then begin + ha1:= hashkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + while true do begin + if (po1^.header.hash = ha1) and checkkey(akey,po1) then begin + aiterator(po1); + end; + if po1^.header.nexthash = 0 then begin + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; +end; + +procedure thashdatalist.internaliterate( + const aiterator: internalhashiteratorprocty); +var + po1: phashdataty; +begin + if fcount > 0 then begin + po1:= pointer(pchar(fdata) + fassignedfirst); + while true do begin + aiterator(po1); + if phashheaderty(po1)^.nextlist = 0 then begin + break; + end; + inc(pchar(po1),phashheaderty(po1)^.nextlist); + end; + end; +end; + +procedure thashdatalist.inititem(const aitem: phashdataty); +begin + //dummy +end; + +procedure thashdatalist.finalizeitem(const aitem: phashdataty); +begin + //dummy +end; + +function thashdatalist.internalfind(const akey; + hash1: hashvaluety): phashdataty; +var +// ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; +begin +{$ifdef mse_debug_hash} + checkhash; +{$endif} + po1:= nil; + if count > 0 then begin +// ha1:= hashkey(akey); + uint1:= fhashtable[hash1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + while true do begin + if (po1^.header.hash = hash1) and checkkey(akey,po1) then begin + break; + end; + if po1^.header.nexthash = 0 then begin + po1:= nil; + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; + result:= po1; +end; + +function thashdatalist.internalfind(const akey): phashdataty; +begin + result:= internalfind(akey,hashkey(akey)); +end; + +function thashdatalist.internalfind(const akey; out acount: integer): phashdataty; +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; +begin + result:= nil; + acount:= 0; + if count > 0 then begin + ha1:= hashkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + while true do begin + if (po1^.header.hash = ha1) and checkkey(akey,po1) then begin + if result = nil then begin + result:= po1; + end; + inc(acount); + end + else begin + if result <> nil then begin + break; + end; + end; + if po1^.header.nexthash = 0 then begin + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; +end; + +function thashdatalist.internalfind(const akey; + const acheckproc: findcheckprocty): phashdataty; +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; + bo1: boolean; +begin + po1:= nil; + if count > 0 then begin + ha1:= hashkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + bo1:= false; + while true do begin + if (po1^.header.hash = ha1) and checkkey(akey,po1) then begin + acheckproc(po1,bo1); + if bo1 then begin + break; + end; + end; + if po1^.header.nexthash = 0 then begin + po1:= nil; + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; + result:= po1; +end; + +function thashdatalist.internalfind(const akey; + const acheckproc: findcheckprocty; + out acount: integer): phashdataty; +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; + bo1: boolean; +begin + result:= nil; + acount:= 0; + if count > 0 then begin + ha1:= hashkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + bo1:= false; + while true do begin + if (po1^.header.hash = ha1) and checkkey(akey,po1) then begin + acheckproc(po1,bo1); + if bo1 then begin + if result = nil then begin + result:= po1; + end; + inc(acount); + end + else begin + if result <> nil then begin + break; + end; + end; + end; + if po1^.header.nexthash = 0 then begin + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; +end; + +function thashdatalist.internalfindexact(const akey): phashdataty; +begin + result:= internalfind(akey,{$ifdef FPC}@{$endif}checkexact); +end; + +function thashdatalist.internalfindexact(const akey; + out acount: integer): phashdataty; +begin + result:= internalfind(akey,{$ifdef FPC}@{$endif}checkexact,acount); +end; + +function thashdatalist.internalfirstx: phashdataty; +begin + result:= nil; + if count > 0 then begin + fcurrentitem:= fassignedfirst; + result:= fdata + fcurrentitem; + end; +end; + +function thashdatalist.internallastx: phashdataty; +begin + result:= nil; + if count > 0 then begin + fcurrentitem:= fassignedlast; + result:= fdata + fcurrentitem; + end; +end; + +function thashdatalist.internalnextx: phashdataty; +var + po1: phashdataty; +begin + result:= nil; + if count > 0 then begin + po1:= phashdataty(fdata + fcurrentitem); + if (fcurrentitem = 0) or (po1^.header.nextlist = 0) then begin + fcurrentitem:= fassignedfirst; + end + else begin + fcurrentitem:= fcurrentitem + po1^.header.nextlist; + end; + result:= fdata + fcurrentitem; + end; +end; + +function thashdatalist.internalprevx: phashdataty; +var + po1: phashdataty; +begin + result:= nil; + if count > 0 then begin + po1:= phashdataty(fdata + fcurrentitem); + if (fcurrentitem = 0) or (po1^.header.prevlist = 0) then begin + fcurrentitem:= fassignedlast; + end + else begin + fcurrentitem:= fcurrentitem + po1^.header.prevlist; + end; + result:= fdata + fcurrentitem; + end; +end; + +procedure thashdatalist.checkexact(const aitem: phashdataty; + var accept: boolean); +begin + accept:= false; //dummy +end; + +function thashdatalist.getdatapo(const aoffset: hashoffsetty): pointer; inline; +begin + result:= pchar(fdata)+aoffset; +end; + +function thashdatalist.getdataoffs(const adata: pointer): hashoffsetty; inline; +begin + result:= pchar(adata)-pchar(fdata); +end; + +{$ifdef mse_debug_hash} +procedure thashdatalist.checkhash; +var + int1,int2,int3: integer; + po1,po2: phashdataty; + uint1: hashoffsetty; +begin + if (fmask <> 0) and (fhashtable <> nil) then begin + int3:= 0; + for int1:= 0 to fmask do begin + uint1:= fhashtable[int1]; + if uint1 <> 0 then begin + inc(int3); + po1:= phashdataty(pchar(fdata) + uint1); + if po1^.header.prevhash <> 0 then begin + raise exception.create('prevhash is not 0.'); + end; + int2:= 0; + while po1^.header.nexthash <> 0 do begin + po2:= po1; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + if phashdataty(pchar(fdata)+po1^.header.prevhash) <> po2 then begin + raise exception.create('Wrong hash backlink.'); + end; + inc(int2); + inc(int3); + if int2 > count then begin + raise exception.create('Hash loop.'); + end; + end; + end; + end; + if int3 <> count then begin + raise exception.create('Wrong hash count.'); + end; + end; + if (fassignedfirst <> 0) or (fassignedlast <> 0) then begin + if (fassignedfirst = 0) then begin + raise exception.create('fassignedfirst 0.'); + end; + if (fassignedlast = 0) then begin + raise exception.create('fassignedlast 0.'); + end; + + int1:= 0; + po1:= fdata + fassignedfirst; + if po1^.header.prevlist <> 0 then begin + raise exception.create('fprevlist not 0.'); + end; + while true do begin + inc(int1); + if int1 > fcount then begin + raise exception.create('Forward List loop.'); + end; + if po1^.header.nextlist = 0 then begin + break; + end; + po1:= pointer(po1) + po1^.header.nextlist; + end; + if int1 <> count then begin + raise exception.create('Wrong forward list count.'); + end; + int1:= 0; + po1:= fdata + fassignedlast; + if po1^.header.nextlist <> 0 then begin + raise exception.create('fnextlist not 0.'); + end; + while true do begin + inc(int1); + if int1 > fcount then begin + raise exception.create('Backward List loop.'); + end; + if po1^.header.prevlist = 0 then begin + break; + end; + po1:= pointer(po1) + po1^.header.prevlist; + end; + if int1 <> count then begin + raise exception.create('Wrong backward list count.'); + end; + end + else begin + if fcount <> 0 then begin + raise exception.create('Wrong count.'); + end; + end; + int1:= 0; + if fdeletedroot <> 0 then begin + po1:= fdata + fdeletedroot; + while true do begin + inc(int1); + if int1 > fcapacity-fcount then begin + raise exception.create('Deleted List loop.'); + end; + if po1^.header.nextlist = 0 then begin + break; + end; + po1:= pointer(po1) + po1^.header.nextlist; + end; + end; +end; + +procedure thashdatalist.checkexists(const aitem: phashdataty); +var + int1: integer; + po1: phashdataty; + uint1: hashoffsetty; +begin + checkhash; + if fmask <> 0 then begin + for int1:= 0 to fmask do begin + uint1:= fhashtable[int1]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + if po1 = aitem then begin + exit; + end; + while po1^.header.nexthash <> 0 do begin + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + if po1 = aitem then begin + exit; + end; + end; + end; + end; + raise exception.create('Hash item does not exist.'); + end; +end; + +procedure thashdatalist.checknotexists(const aitem: phashdataty); +var + int1: integer; + po1: phashdataty; + uint1: hashoffsetty; +begin + checkhash; + if fmask <> 0 then begin + for int1:= 0 to fmask do begin + uint1:= fhashtable[int1]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + if po1 = aitem then begin + raise exception.create('Hash item does exist.'); + end; + while po1^.header.nexthash <> 0 do begin + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + if po1 = aitem then begin + raise exception.create('Hash item does exist.'); + end; + end; + end; + end; + end; +end; + +{$endif} + +{ tintegerhasdatalist } +{ +constructor tintegerhashdatalist.create(); +begin + inherited create(datasize + sizeof(integerhashdataty)-sizeof(hashdataty)); +end; +} +function tintegerhashdatalist.hashkey(const akey): hashvaluety; +// todo: optimize +begin + result:= scramble((integer(akey) xor (integer(akey) shr 2))); +end; + +function tintegerhashdatalist.add(const akey: integer): pintegerhashdataty; +begin + result:= pintegerhashdataty(internaladd(akey)); + result^.data.key:= akey; +end; + +function tintegerhashdatalist.find(const akey: integer): pintegerhashdataty; +begin + result:= pintegerhashdataty(internalfind(akey)); +end; + +function tintegerhashdatalist.addunique(const akey: integer): pintegerhashdataty; +begin + result:= find(akey); + if result = nil then begin + result:= add(akey); + end; +end; + +function tintegerhashdatalist.addunique(const akey: integer; + out adata: pintegerhashdataty): boolean; + //true if new +begin + adata:= find(akey); + result:= false; + if adata = nil then begin + adata:= add(akey); + result:= true; + end; +end; + +function tintegerhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + result:= integer(akey) = pintegerhashdataty(aitem)^.data.key; +end; + +function tintegerhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(integerhashdataty); +end; + +function tintegerhashdatalist.first: pintegerhashdataty; +begin + result:= pintegerhashdataty(internalfirstx); +end; + +function tintegerhashdatalist.next: pintegerhashdataty; +begin + result:= pintegerhashdataty(internalnextx); +end; + +function tintegerhashdatalist.last: pintegerhashdataty; +begin + result:= pintegerhashdataty(internallastx); +end; + +function tintegerhashdatalist.prev: pintegerhashdataty; +begin + result:= pintegerhashdataty(internalprevx); +end; + +function tintegerhashdatalist.delete(const akey: integer; + const all: boolean = false): boolean; +begin + result:= internaldelete(akey,all); +end; + +{ tdoubleintegerhashdatalist } + +function mdikey(a,b: integer): doubleintegerty; inline; +begin + result.a:= a; + result.b:= b; +end; + +function tdoubleintegerhashdatalist.hashkey(const akey): hashvaluety; +var + i1: int32; +begin + with doubleintegerty(akey) do begin + i1:= a + b; + end; + result:= scramble((integer(i1) xor (integer(i1) shr 2))); +end; + +function tdoubleintegerhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + with doubleintegerty(akey) do begin + result:= (a = pdoubleintegerhashdataty(aitem)^.data.key.a) and + (b = pdoubleintegerhashdataty(aitem)^.data.key.b); + end; +end; + +function tdoubleintegerhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(doubleintegerhashdataty); +end; + +function tdoubleintegerhashdatalist.add( + const akeya,akeyb: integer): pdoubleintegerhashdataty; +var + k1: doubleintegerty; +begin + k1.a:= akeya; + k1.b:= akeyb; + result:= pdoubleintegerhashdataty(internaladd(k1)); + result^.data.key:= k1; +end; + +function tdoubleintegerhashdatalist.find( + const akeya,akeyb: integer): pdoubleintegerhashdataty; +begin + result:= pdoubleintegerhashdataty(internalfind(mdikey(akeya,akeyb))); +end; + +function tdoubleintegerhashdatalist.addunique( + const akeya,akeyb: integer): pdoubleintegerhashdataty; +begin + result:= find(akeya,akeyb); + if result = nil then begin + result:= add(akeya,akeyb); + end; +end; + +function tdoubleintegerhashdatalist.addunique(const akeya,akeyb: integer; + out adata: pdoubleintegerhashdataty): boolean; +begin + adata:= find(akeya,akeyb); + result:= false; + if adata = nil then begin + adata:= add(akeya,akeyb); + result:= true; + end; +end; + +function tdoubleintegerhashdatalist.first: pdoubleintegerhashdataty; +begin + result:= pdoubleintegerhashdataty(internalfirstx); +end; + +function tdoubleintegerhashdatalist.next: pdoubleintegerhashdataty; +begin + result:= pdoubleintegerhashdataty(internalnextx); +end; + +function tdoubleintegerhashdatalist.last: pdoubleintegerhashdataty; +begin + result:= pdoubleintegerhashdataty(internallastx); +end; + +function tdoubleintegerhashdatalist.prev: pdoubleintegerhashdataty; +begin + result:= pdoubleintegerhashdataty(internalprevx); +end; + +function tdoubleintegerhashdatalist.delete(const akeya,akeyb: integer; + const all: boolean = false): boolean; +begin + result:= internaldelete(mdikey(akeya,akeyb),all); +end; + +{ ttripleintegerhashdatalist } + +function mtikey(a,b,c: int32): tripleintegerty; inline; +begin + result.a:= a; + result.b:= b; + result.c:= c; +end; + +function ttripleintegerhashdatalist.hashkey(const akey): hashvaluety; +var + i1: int32; +begin + with tripleintegerty(akey) do begin + i1:= a + b + c; + end; + result:= scramble((integer(i1) xor (integer(i1) shr 2))); +end; + +function ttripleintegerhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + with tripleintegerty(akey) do begin + result:= (a = ptripleintegerhashdataty(aitem)^.data.key.a) and + (b = ptripleintegerhashdataty(aitem)^.data.key.b) and + (c = ptripleintegerhashdataty(aitem)^.data.key.c); + end; +end; + +function ttripleintegerhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(tripleintegerhashdataty); +end; + +function ttripleintegerhashdatalist.add( + const akeya,akeyb,akeyc: integer): ptripleintegerhashdataty; +var + k1: tripleintegerty; +begin + k1.a:= akeya; + k1.b:= akeyb; + k1.c:= akeyc; + result:= ptripleintegerhashdataty(internaladd(k1)); + result^.data.key:= k1; +end; + +function ttripleintegerhashdatalist.find( + const akeya,akeyb,akeyc: integer): ptripleintegerhashdataty; +begin + result:= ptripleintegerhashdataty(internalfind(mtikey(akeya,akeyb,akeyc))); +end; + +function ttripleintegerhashdatalist.addunique( + const akeya,akeyb,akeyc: integer): ptripleintegerhashdataty; +begin + result:= find(akeya,akeyb,akeyc); + if result = nil then begin + result:= add(akeya,akeyb,akeyc); + end; +end; + +function ttripleintegerhashdatalist.addunique(const akeya,akeyb,akeyc: integer; + out adata: ptripleintegerhashdataty): boolean; +begin + adata:= find(akeya,akeyb,akeyc); + result:= false; + if adata = nil then begin + adata:= add(akeya,akeyb,akeyc); + result:= true; + end; +end; + +function ttripleintegerhashdatalist.first: ptripleintegerhashdataty; +begin + result:= ptripleintegerhashdataty(internalfirstx); +end; + +function ttripleintegerhashdatalist.next: ptripleintegerhashdataty; +begin + result:= ptripleintegerhashdataty(internalnextx); +end; + +function ttripleintegerhashdatalist.last: ptripleintegerhashdataty; +begin + result:= ptripleintegerhashdataty(internallastx); +end; + +function ttripleintegerhashdatalist.prev: ptripleintegerhashdataty; +begin + result:= ptripleintegerhashdataty(internalprevx); +end; + +function ttripleintegerhashdatalist.delete(const akeya,akeyb,akeyc: integer; + const all: boolean = false): boolean; +begin + result:= internaldelete(mtikey(akeya,akeyb,akeyc),all); +end; + +{ tint32int32hashdatalist } + +procedure tint32int32hashdatalist.add(const akey: int32; + const avalue: int32); +begin + pint32int32hashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tint32int32hashdatalist.find(const akey: int32; + out avalue: int32): boolean; +var + po1: pint32int32hashdataty; +begin + po1:= pint32int32hashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= 0; + end; +end; + +function tint32int32hashdatalist.addunique(const akey: int32; + const avalue: int32): boolean; +var + po1: pint32int32hashdataty; +begin + result:= true; + po1:= pint32int32hashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= pint32int32hashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +function tint32int32hashdatalist.getrecordsize(): int32; +begin + result:= sizeof(int32int32hashdataty); +end; + +function tint32int32hashdatalist.find(const akey: int32): int32; +begin + find(akey,result); +end; + +function tint32int32hashdatalist.first: pint32int32hashdataty; +begin + result:= pint32int32hashdataty(internalfirstx); +end; + +function tint32int32hashdatalist.next: pint32int32hashdataty; +begin + result:= pint32int32hashdataty(internalnextx); +end; + +function tint32int32hashdatalist.last: pint32int32hashdataty; +begin + result:= pint32int32hashdataty(internallastx); +end; + +function tint32int32hashdatalist.prev: pint32int32hashdataty; +begin + result:= pint32int32hashdataty(internalprevx); +end; + +{ tpointerhashdatalist } + +function tpointerhashdatalist.hashkey(const akey): hashvaluety; +begin + result:= pointerhash(pointer(akey)); +end; + +function tpointerhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + result:= pointer(akey) = ppointerhashdataty(aitem)^.data.key; +end; + +function tpointerhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(pointerhashdataty); +end; + +function tpointerhashdatalist.add(const akey: pointer): ppointerhashdataty; +begin + result:= ppointerhashdataty(internaladd(akey)); + result^.data.key:= akey; +end; + +function tpointerhashdatalist.addunique( + const akey: pointer): ppointerhashdataty; +begin + result:= find(akey); + if result = nil then begin + result:= add(akey); + end; +end; + +function tpointerhashdatalist.find(const akey: pointer): ppointerhashdataty; +begin + result:= ppointerhashdataty(internalfind(akey)); +end; + +function tpointerhashdatalist.delete(const akey: pointer; + const all: boolean = false): boolean; +begin + result:= internaldelete(akey,all); +end; + +function tpointerhashdatalist.first: ppointerhashdataty; +begin + result:= ppointerhashdataty(internalfirstx); +end; + +function tpointerhashdatalist.next: ppointerhashdataty; +begin + result:= ppointerhashdataty(internalnextx); +end; + +function tpointerhashdatalist.last: ppointerhashdataty; +begin + result:= ppointerhashdataty(internallastx); +end; + +function tpointerhashdatalist.prev: ppointerhashdataty; +begin + result:= ppointerhashdataty(internalprevx); +end; + +{ tpointerint32hashdatalist } + +procedure tpointerint32hashdatalist.add(const akey: pointer; + const avalue: int32); +begin + ppointerint32hashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tpointerint32hashdatalist.find(const akey: pointer; + out avalue: int32): boolean; +var + po1: ppointerint32hashdataty; +begin + po1:= ppointerint32hashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= 0; + end; +end; + +function tpointerint32hashdatalist.addunique(const akey: pointer; + const avalue: int32): boolean; +var + po1: ppointerint32hashdataty; +begin + result:= true; + po1:= ppointerint32hashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= ppointerint32hashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +function tpointerint32hashdatalist.getrecordsize(): int32; +begin + result:= sizeof(pointerint32hashdataty); +end; + +function tpointerint32hashdatalist.find(const akey: pointer): int32; +begin + find(akey,result); +end; + +function tpointerint32hashdatalist.first: ppointerint32hashdataty; +begin + result:= ppointerint32hashdataty(internalfirstx); +end; + +function tpointerint32hashdatalist.next: ppointerint32hashdataty; +begin + result:= ppointerint32hashdataty(internalnextx); +end; + +function tpointerint32hashdatalist.last: ppointerint32hashdataty; +begin + result:= ppointerint32hashdataty(internallastx); +end; + +function tpointerint32hashdatalist.prev: ppointerint32hashdataty; +begin + result:= ppointerint32hashdataty(internalprevx); +end; + +{ tptruinthasdatalist } +{ +constructor tptruinthashdatalist.create(const datasize: integer); +begin + inherited create(datasize + sizeof(ptruintdataty)); +end; +} +function tptruinthashdatalist.hashkey(const akey): hashvaluety; +// todo: optimize +begin + result:= pointerhash(pointer(akey)); +// result:= scramble(ptruint(akey) xor (ptruint(akey) shr 2)); +end; + +function tptruinthashdatalist.add(const akey: ptruint): pptruinthashdataty; +begin + result:= pptruinthashdataty(internaladd(akey)); + result^.data.key:= akey; +end; + +function tptruinthashdatalist.find(const akey: ptruint): pptruinthashdataty; +begin + result:= pptruinthashdataty(internalfind(akey)); +end; + +function tptruinthashdatalist.addunique( + const akey: ptruint): pptruinthashdataty; +begin + result:= find(akey); + if result = nil then begin + result:= add(akey); + end; +end; + +function tptruinthashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + result:= ptruint(akey) = pptruinthashdataty(aitem)^.data.key; +end; + +function tptruinthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(ptruinthashdataty); +end; + +function tptruinthashdatalist.first: pptruinthashdataty; +begin + result:= pptruinthashdataty(internalfirstx); +end; + +function tptruinthashdatalist.next: pptruinthashdataty; +begin + result:= pptruinthashdataty(internalnextx); +end; + +function tptruinthashdatalist.last: pptruinthashdataty; +begin + result:= pptruinthashdataty(internallastx); +end; + +function tptruinthashdatalist.prev: pptruinthashdataty; +begin + result:= pptruinthashdataty(internalprevx); +end; + +function tptruinthashdatalist.delete(const akey: ptruint; + const all: boolean = false): boolean; +begin + result:= internaldelete(akey,all); +end; + +{ tpointerptruinthashdatalist } + +procedure tpointerptruinthashdatalist.add(const akey: ptruint; + const avalue: pointer); +begin + ppointerptruinthashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tpointerptruinthashdatalist.find(const akey: ptruint; + out avalue: pointer): boolean; +var + po1: ppointerptruinthashdataty; +begin + po1:= ppointerptruinthashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= nil; + end; +end; + +function tpointerptruinthashdatalist.addunique(const akey: ptruint; + const avalue: pointer): boolean; +var + po1: ppointerptruinthashdataty; +begin + result:= true; + po1:= ppointerptruinthashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= ppointerptruinthashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tpointerptruinthashdatalist.checkexact( + const aitem: phashdataty; var accept: boolean); +begin + accept:= ppointerptruinthashdataty(aitem)^.data.data = fpointerparam; +end; + +function tpointerptruinthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(pointerptruinthashdataty); +end; + +procedure tpointerptruinthashdatalist.delete(const akey: ptruint; + const avalue: pointer); +//var +// po1: phashdataty; +begin + fpointerparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tpointerptruinthashdatalist.find(const akey: ptruint): pointer; +begin + find(akey,result); +end; + +function tpointerptruinthashdatalist.first: ppointerptruinthashdataty; +begin + result:= ppointerptruinthashdataty(internalfirstx); +end; + +function tpointerptruinthashdatalist.next: ppointerptruinthashdataty; +begin + result:= ppointerptruinthashdataty(internalnextx); +end; + +function tpointerptruinthashdatalist.last: ppointerptruinthashdataty; +begin + result:= ppointerptruinthashdataty(internallastx); +end; + +function tpointerptruinthashdatalist.prev: ppointerptruinthashdataty; +begin + result:= ppointerptruinthashdataty(internalprevx); +end; + +procedure tpointerptruinthashdatalist.iterate(const akey: ptruint; + const aiterator: pointerptruintiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tansistringptruinthashdatalist } + +constructor tansistringptruinthashdatalist.create; +begin + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +procedure tansistringptruinthashdatalist.add(const akey: ptruint; + const avalue: ansistring); +begin + pansistringptruinthashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tansistringptruinthashdatalist.find(const akey: ptruint; + out avalue: ansistring): boolean; +var + po1: pansistringptruinthashdataty; +begin + po1:= pansistringptruinthashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= ''; + end; +end; + +function tansistringptruinthashdatalist.addunique(const akey: ptruint; + const avalue: ansistring): boolean; +var + po1: pansistringptruinthashdataty; +begin + result:= true; + po1:= pansistringptruinthashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= pansistringptruinthashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tansistringptruinthashdatalist.checkexact( + const aitem: phashdataty; var accept: boolean); +begin + accept:= pansistringptruinthashdataty(aitem)^.data.data = fansistringparam; +end; + +procedure tansistringptruinthashdatalist.delete(const akey: ptruint; + const avalue: ansistring); +//var +// po1: phashdataty; +begin + fansistringparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tansistringptruinthashdatalist.find(const akey: ptruint): ansistring; +begin + find(akey,result); +end; + +function tansistringptruinthashdatalist.first: pansistringptruinthashdataty; +begin + result:= pansistringptruinthashdataty(internalfirstx); +end; + +function tansistringptruinthashdatalist.next: pansistringptruinthashdataty; +begin + result:= pansistringptruinthashdataty(internalnextx); +end; + +function tansistringptruinthashdatalist.last: pansistringptruinthashdataty; +begin + result:= pansistringptruinthashdataty(internallastx); +end; + +function tansistringptruinthashdatalist.prev: pansistringptruinthashdataty; +begin + result:= pansistringptruinthashdataty(internalprevx); +end; + +procedure tansistringptruinthashdatalist.iterate(const akey: ptruint; + const aiterator: ansistringptruintiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +procedure tansistringptruinthashdatalist.finalizeitem(const aitem: phashdataty); +begin + finalize(pansistringptruinthashdataty(aitem)^.data); +end; + +function tansistringptruinthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(ansistringptruinthashdataty); +end; + +function tansistringptruinthashdatalist.setdata(const akey: ptruint; + const avalue: ansistring): boolean; +var + po1: pansistringptruinthashdataty; +begin + po1:= pansistringptruinthashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + po1^.data.data:= avalue; + end; +end; + +{ tmsestringptruinthashdatalist } + +constructor tmsestringptruinthashdatalist.create; +begin + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +procedure tmsestringptruinthashdatalist.add(const akey: ptruint; + const avalue: msestring); +begin + pmsestringptruinthashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tmsestringptruinthashdatalist.find(const akey: ptruint; + out avalue: msestring): boolean; +var + po1: pmsestringptruinthashdataty; +begin + po1:= pmsestringptruinthashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= ''; + end; +end; + +function tmsestringptruinthashdatalist.addunique(const akey: ptruint; + const avalue: msestring): boolean; +var + po1: pmsestringptruinthashdataty; +begin + result:= true; + po1:= pmsestringptruinthashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= pmsestringptruinthashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tmsestringptruinthashdatalist.checkexact(const aitem: phashdataty; + var accept: boolean); +begin + accept:= pmsestringptruinthashdataty(aitem)^.data.data = fmsestringparam; +end; + +procedure tmsestringptruinthashdatalist.delete(const akey: ptruint; + const avalue: msestring); +//var +// po1: phashdataty; +begin + fmsestringparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tmsestringptruinthashdatalist.find(const akey: ptruint): msestring; +begin + find(akey,result); +end; + +function tmsestringptruinthashdatalist.first: pmsestringptruinthashdataty; +begin + result:= pmsestringptruinthashdataty(internalfirstx); +end; + +function tmsestringptruinthashdatalist.next: pmsestringptruinthashdataty; +begin + result:= pmsestringptruinthashdataty(internalnextx); +end; + +function tmsestringptruinthashdatalist.last: pmsestringptruinthashdataty; +begin + result:= pmsestringptruinthashdataty(internallastx); +end; + +function tmsestringptruinthashdatalist.prev: pmsestringptruinthashdataty; +begin + result:= pmsestringptruinthashdataty(internalprevx); +end; + +procedure tmsestringptruinthashdatalist.iterate(const akey: ptruint; + const aiterator: msestringptruintiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +procedure tmsestringptruinthashdatalist.finalizeitem(const aitem: phashdataty); +begin + finalize(pmsestringptruinthashdataty(aitem)^.data); +end; + +function tmsestringptruinthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(msestringptruinthashdataty); +end; + +function tmsestringptruinthashdatalist.setdata(const akey: ptruint; + const avalue: msestring): boolean; +var + po1: pmsestringptruinthashdataty; +begin + po1:= pmsestringptruinthashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + po1^.data.data:= avalue; + end; +end; + +{ tansistringhashdatalist } + +constructor tansistringhashdatalist.create(); +begin + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +procedure tansistringhashdatalist.finalizeitem(const aitem: phashdataty); +begin + finalize(pansistringhashdataty(aitem)^.data); +end; + +function tansistringhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(ansistringhashdataty); +end; + +function tansistringhashdatalist.add( + const akey: ansistring): pansistringhashdataty; +begin + result:= pansistringhashdataty(internaladd(akey)); + result^.data.key:= akey; +end; + +function tansistringhashdatalist.find( + const akey: ansistring): pansistringhashdataty; +begin + result:= pansistringhashdataty(internalfind(akey)); +end; + +function tansistringhashdatalist.find( + const akey: lstringty): pansistringhashdataty; +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; +begin + po1:= nil; + if count > 0 then begin + ha1:= hashlkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + while true do begin + if (po1^.header.hash = ha1) and checklkey(akey, + pansistringhashdataty(po1)^.data) then begin + break; + end; + if po1^.header.nexthash = 0 then begin + po1:= nil; + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; + result:= pansistringhashdataty(po1); +end; + +function tansistringhashdatalist.addunique( + const akey: ansistring): pansistringhashdataty; +begin + result:= find(akey); + if result = nil then begin + result:= add(akey); + end; +end; + +function tansistringhashdatalist.hashkey(const akey): hashvaluety; +begin + result:= stringhash(ansistring(akey)); +end; + +function tansistringhashdatalist.hashlkey(const akey: lstringty): hashvaluety; +begin + result:= stringhash(akey); +end; + +function tansistringhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +var + int1: integer; +begin + result:= pointer(akey) = pointer(pansistringhashdataty(aitem)^.data.key); + if not result then begin + int1:= length(ansistring(akey)); + result:= (int1 = length(pansistringhashdataty(aitem)^.data.key)) and + comparemem(pointer(akey), + pointer(pansistringhashdataty(aitem)^.data.key),int1); + end; +end; + +function tansistringhashdatalist.checklkey(const akey: lstringty; + const aitemdata: ansistringdataty): boolean; +begin + result:= (akey.len = length(aitemdata.key)) and + comparemem(akey.po,pointer(aitemdata.key),akey.len); +end; + +function tansistringhashdatalist.delete(const akey: ansistring; + const all: boolean = false): boolean; +begin + result:= internaldelete(akey,all); +end; + +function tansistringhashdatalist.delete(const akey: lstringty; + const all: boolean = false): boolean; +var + str1: string; +begin + str1:= lstringtostring(akey); + result:= internaldelete(str1,all); +end; + +function tansistringhashdatalist.first: pansistringhashdataty; +begin + result:= pansistringhashdataty(internalfirstx); +end; + +function tansistringhashdatalist.next: pansistringhashdataty; +begin + result:= pansistringhashdataty(internalnextx); +end; + +function tansistringhashdatalist.last: pansistringhashdataty; +begin + result:= pansistringhashdataty(internallastx); +end; + +function tansistringhashdatalist.prev: pansistringhashdataty; +begin + result:= pansistringhashdataty(internalprevx); +end; + +procedure tansistringhashdatalist.iterate(const akey: ansistring; + const aiterator: ansistringhashiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tpointeransistringhashdatalist } +{ +constructor tpointeransistringhashdatalist.create; +begin + inherited create(sizeof(pointer)); +end; +} +procedure tpointeransistringhashdatalist.add(const akey: ansistring; + const avalue: pointer); +begin + ppointeransistringhashdataty(inherited add(akey))^.data.data:= avalue; +end; + +procedure tpointeransistringhashdatalist.add(const keys: array of string; + startindex: pointer = pointer($00000001)); +var + ca1: longword; +begin + for ca1:= 0 to high(keys) do begin + add(keys[ca1],pointer(ca1+ptruint(startindex))); + end; +end; + +function tpointeransistringhashdatalist.find(const akey: ansistring; + out avalue: pointer): boolean; +var + po1: ppointeransistringhashdataty; +begin + po1:= ppointeransistringhashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= nil; + end; +end; + +function tpointeransistringhashdatalist.find(const akey: lstringty): pointer; +begin + result:= inherited find(akey); + if result <> nil then begin + result:= ppointeransistringhashdataty(result)^.data.data; + end; +end; + +function tpointeransistringhashdatalist.addunique(const akey: ansistring; + const avalue: pointer): boolean; +var + po1: ppointeransistringhashdataty; +begin + result:= true; + po1:= ppointeransistringhashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= ppointeransistringhashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tpointeransistringhashdatalist.checkexact(const aitem: phashdataty; + var accept: boolean); +begin + accept:= ppointeransistringhashdataty(aitem)^.data.data = fpointerparam; +end; + +function tpointeransistringhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(pointeransistringhashdataty); +end; + +procedure tpointeransistringhashdatalist.delete(const akey: ansistring; + const avalue: pointer); +//var +// po1: phashdataty; +begin + fpointerparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tpointeransistringhashdatalist.find(const akey: ansistring): pointer; +begin + find(akey,result); +end; + +function tpointeransistringhashdatalist.first: ppointeransistringhashdataty; +begin + result:= ppointeransistringhashdataty(internalfirstx); +end; + +function tpointeransistringhashdatalist.next: ppointeransistringhashdataty; +begin + result:= ppointeransistringhashdataty(internalnextx); +end; + +function tpointeransistringhashdatalist.last: ppointeransistringhashdataty; +begin + result:= ppointeransistringhashdataty(internallastx); +end; + +function tpointeransistringhashdatalist.prev: ppointeransistringhashdataty; +begin + result:= ppointeransistringhashdataty(internalprevx); +end; + +procedure tpointeransistringhashdatalist.iterate(const akey: ansistring; + const aiterator: pointeransistringiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tmsestringhashdatalist } + +constructor tmsestringhashdatalist.create(); +begin + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +procedure tmsestringhashdatalist.finalizeitem( + const aitem: phashdataty); +begin + finalize(pmsestringhashdataty(aitem)^.data); +end; + +function tmsestringhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(msestringhashdataty); +end; + +function tmsestringhashdatalist.add( + const akey: msestring): pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internaladd(akey)); + result^.data.key:= akey; +end; + +function tmsestringhashdatalist.find( + const akey: msestring): pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internalfind(akey)); +end; + +function tmsestringhashdatalist.find( + const akey: lmsestringty): pmsestringhashdataty; +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; +begin + po1:= nil; + if count > 0 then begin + ha1:= hashlkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + while true do begin + if (po1^.header.hash = ha1) and checklkey(akey, + pmsestringhashdataty(po1)^.data) then begin + break; + end; + if po1^.header.nexthash = 0 then begin + po1:= nil; + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; + result:= pmsestringhashdataty(po1); +end; + +function tmsestringhashdatalist.find(const akey: msestring; + out acount: integer): pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internalfind(akey,acount)); +end; + +function tmsestringhashdatalist.addunique( + const akey: msestring): pmsestringhashdataty; +begin + result:= find(akey); + if result = nil then begin + result:= add(akey); + end; +end; + +function tmsestringhashdatalist.hashkey(const akey): hashvaluety; +begin + result:= stringhash(msestring(akey)); +end; + +function tmsestringhashdatalist.hashlkey(const akey: lmsestringty): hashvaluety; +begin + result:= stringhash(akey); +end; + +function tmsestringhashdatalist.checklkey(const akey: lmsestringty; + const aitemdata: msestringdataty): boolean; +begin + result:= (akey.len = length(aitemdata.key)) and + comparemem(akey.po,pointer(aitemdata.key), + akey.len*sizeof(msechar)); +end; + +function tmsestringhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +var + int1: integer; +begin + result:= pointer(akey) = pointer(pmsestringhashdataty(aitem)^.data.key); + if not result then begin + int1:= length(msestring(akey)); + result:= (int1 = length(pmsestringhashdataty(aitem)^.data.key)) and + comparemem(pointer(akey),pointer(pmsestringhashdataty(aitem)^.data.key), + int1*sizeof(msechar)); + end; +// result:= msestring(akey) = msestringdataty(aitemdata).key; +end; + +function tmsestringhashdatalist.delete(const akey: msestring; + const all: boolean = false): boolean; +begin + result:= internaldelete(akey,all); +end; + +function tmsestringhashdatalist.delete(const akey: lmsestringty; + const all: boolean = false): boolean; +var + mstr1: msestring; +begin + mstr1:= lstringtostring(akey); + result:= internaldelete(mstr1,all); +end; + +function tmsestringhashdatalist.first: pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internalfirstx); +end; + +function tmsestringhashdatalist.next: pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internalnextx); +end; + +function tmsestringhashdatalist.last: pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internallastx); +end; + +function tmsestringhashdatalist.prev: pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internalprevx); +end; + +procedure tmsestringhashdatalist.iterate(const akey: msestring; + const aiterator: msestringiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tpointermsestringhashdatalist } +{ +constructor tpointermsestringhashdatalist.create; +begin + inherited create(sizeof(pointermsestringhashdataty) - + sizeof(msestringhashdataty)); +end; +} +procedure tpointermsestringhashdatalist.add(const akey: msestring; + const avalue: pointer); +begin + ppointermsestringhashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tpointermsestringhashdatalist.find(const akey: msestring; + out avalue: pointer): boolean; +var + po1: ppointermsestringhashdataty; +begin + po1:= ppointermsestringhashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= nil; + end; +end; + +function tpointermsestringhashdatalist.find(const akey: msestring; + out avalue: pointer; out acount: integer): boolean; +var + po1: ppointermsestringhashdataty; +begin + po1:= ppointermsestringhashdataty(internalfind(akey,acount)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= nil; + end; +end; + +function tpointermsestringhashdatalist.find(const akey: lmsestringty): pointer; +begin + result:= inherited find(akey); + if result <> nil then begin + result:= ppointermsestringhashdataty(result)^.data.data; + end; +end; + +function tpointermsestringhashdatalist.find(const akey: msestring): pointer; +begin + find(akey,result); +end; + +procedure tpointermsestringhashdatalist.delete(const akey: msestring; + const avalue: pointer); +//var +// po1: phashdataty; +begin + fpointerparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tpointermsestringhashdatalist.addunique(const akey: msestring; + const avalue: pointer): boolean; +var + po1: ppointermsestringhashdataty; +begin + result:= true; + po1:= ppointermsestringhashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= ppointermsestringhashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tpointermsestringhashdatalist.checkexact( + const aitem: phashdataty; var accept: boolean); +begin + accept:= ppointermsestringhashdataty(aitem)^.data.data = fpointerparam; +end; + +function tpointermsestringhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(pointermsestringhashdataty); +end; + +function tpointermsestringhashdatalist.first: ppointermsestringhashdataty; +begin + result:= ppointermsestringhashdataty(internalfirstx); +end; + +function tpointermsestringhashdatalist.next: ppointermsestringhashdataty; +begin + result:= ppointermsestringhashdataty(internalnextx); +end; + +function tpointermsestringhashdatalist.last: ppointermsestringhashdataty; +begin + result:= ppointermsestringhashdataty(internallastx); +end; + +function tpointermsestringhashdatalist.prev: ppointermsestringhashdataty; +begin + result:= ppointermsestringhashdataty(internalprevx); +end; + +procedure tpointermsestringhashdatalist.iterate(const akey: msestring; + const aiterator: pointermsestringiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tintegermsestringhashdatalist } +{ +constructor tintegermsestringhashdatalist.create; +begin + inherited create(sizeof(integer)); +end; +} +procedure tintegermsestringhashdatalist.add(const akey: msestring; + const avalue: integer); +begin + pintegermsestringhashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tintegermsestringhashdatalist.find(const akey: msestring; + out avalue: integer): boolean; +var + po1: pintegermsestringhashdataty; +begin + po1:= pintegermsestringhashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= -1; + end; +end; + +function tintegermsestringhashdatalist.find(const akey: msestring; + out avalue: integer; out acount: integer): boolean; +var + po1: pintegermsestringhashdataty; +begin + po1:= pintegermsestringhashdataty(inherited find(akey,acount)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= -1; + end; +end; + +function tintegermsestringhashdatalist.find(const akey: lmsestringty): integer; +var + po1: pintegermsestringhashdataty; +begin + po1:= pintegermsestringhashdataty(inherited find(akey)); + if po1 <> nil then begin + result:= po1^.data.data; + end + else begin + result:= -1; + end; +end; + +function tintegermsestringhashdatalist.find(const akey: msestring): integer; +begin + find(akey,result); +end; + +procedure tintegermsestringhashdatalist.delete(const akey: msestring; + const avalue: integer); +//var +// po1: phashdataty; +begin + fintegerparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tintegermsestringhashdatalist.addunique(const akey: msestring; + const avalue: integer): boolean; +var + po1: pintegermsestringhashdataty; +begin + result:= true; + po1:= pintegermsestringhashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= pintegermsestringhashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tintegermsestringhashdatalist.checkexact(const aitem: phashdataty; + var accept: boolean); +begin + accept:= pintegermsestringhashdataty(aitem)^.data.data = fintegerparam; +end; + +function tintegermsestringhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(integermsestringhashdataty); +end; + +function tintegermsestringhashdatalist.first: pintegermsestringhashdataty; +begin + result:= pintegermsestringhashdataty(internalfirstx); +end; + +function tintegermsestringhashdatalist.next: pintegermsestringhashdataty; +begin + result:= pintegermsestringhashdataty(internalnextx); +end; + +function tintegermsestringhashdatalist.last: pintegermsestringhashdataty; +begin + result:= pintegermsestringhashdataty(internallastx); +end; + +function tintegermsestringhashdatalist.prev: pintegermsestringhashdataty; +begin + result:= pintegermsestringhashdataty(internalprevx); +end; + +procedure tintegermsestringhashdatalist.iterate(const akey: msestring; + const aiterator: integermsestringiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tobjectmsestringhashdatalist } + +constructor tobjectmsestringhashdatalist.create(const aownsobjects: boolean = true); +begin + fownsobjects:= aownsobjects; + inherited create; +end; + +procedure tobjectmsestringhashdatalist.add(const akey: msestring; + const avalue: tobject); +begin + inherited add(akey,avalue); +end; + +function tobjectmsestringhashdatalist.addunique(const akey: msestring; + const avalue: tobject): boolean; +begin + result:= inherited addunique(akey,avalue); +end; + +procedure tobjectmsestringhashdatalist.delete(const akey: msestring; + const avalue: tobject); +begin + inherited delete(akey,avalue); +end; + +function tobjectmsestringhashdatalist.find(const akey: msestring): tobject; +begin + result:= tobject(inherited find(akey)); +end; + +function tobjectmsestringhashdatalist.find(const akey: msestring; + out avalue: tobject): boolean; +begin + result:= inherited find(akey,pointer(avalue)); +end; + +function tobjectmsestringhashdatalist.find(const akey: msestring; + out avalue: tobject; out acount: integer): boolean; +begin + result:= inherited find(akey,pointer(avalue),acount); +end; + +function tobjectmsestringhashdatalist.first: pobjectmsestringhashdataty; +begin + result:= pobjectmsestringhashdataty(internalfirstx); +end; + +function tobjectmsestringhashdatalist.next: pobjectmsestringhashdataty; +begin + result:= pobjectmsestringhashdataty(internalnextx); +end; + +function tobjectmsestringhashdatalist.last: pobjectmsestringhashdataty; +begin + result:= pobjectmsestringhashdataty(internallastx); +end; + +function tobjectmsestringhashdatalist.prev: pobjectmsestringhashdataty; +begin + result:= pobjectmsestringhashdataty(internalprevx); +end; + +procedure tobjectmsestringhashdatalist.iterate(const akey: msestring; + const aiterator: objectmsestringiteratorprocty); +begin + inherited iterate(akey,pointermsestringiteratorprocty(aiterator)); +end; + +procedure tobjectmsestringhashdatalist.finalizeitem(const aitem: phashdataty); +begin + inherited; + if fownsobjects then begin + with pobjectmsestringhashdataty(aitem)^.data do begin + data.free; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/container/msehashstore.pas b/mseide-msegui/lib/common/container/msehashstore.pas new file mode 100644 index 0000000..7351a96 --- /dev/null +++ b/mseide-msegui/lib/common/container/msehashstore.pas @@ -0,0 +1,423 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msehashstore; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +uses + msehash,msetypes; + +const + maxidentvector = 200; + +type + identarty = card32arty; + identvecty = record + high: integer; + d: array[0..maxidentvector] of identty; + end; + + elementheaderty = record + path: identty; //key, sum of names to root + name: identty; + parent: hashoffsetty; //offset in data array + parentlevel: int32; //max = maxidentvector-1 + refcount: int32; + end; + + elementdataty = record + header: elementheaderty; + // data: record + // end; + end; + pelementdataty = ^elementdataty; + elementhashdataty = record + header: hashheaderty; + data: elementdataty; + end; + pelementhashdataty = ^elementhashdataty; + + thashstore = class(thashdatalist) + private + fcurparent: hashoffsetty; + protected + function hashkey(const akey): hashvaluety override; + function checkkey(const akey; const aitem: phashdataty): boolean override; + function find(const aele: elementdataty): pelementhashdataty; +// function internalfind(const idents: identvecty): pelementhashdataty; + function find(const idents: identvecty): pelementhashdataty; +// function internaladd(const idents: identvecty; +// out aelement: pelementhashdataty): hashoffsetty; + function add(const idents: identvecty; + out aelement: pelementhashdataty): hashoffsetty; + function getrecordsize(): int32 override; +// procedure inititem(const aitem: phashdataty) override; + public +// constructor create(); + function datapo(const aoffs: hashoffsetty): pelementhashdataty; + procedure delete(const idents: identvecty); + procedure delete(const item: hashoffsetty); //offset of datapo + end; + + treeelementheaderty = record + element: elementheaderty; + children: hashoffsetty; //offset in data array + prevsibling: hashoffsetty; //offset in data array + nextsibling: hashoffsetty; //offset in data array + end; + + treeelementdataty = record + header: treeelementheaderty; +// data: record +// end; + end; + ptreeelementdataty = ^treeelementdataty; + treeelementhashdataty = record + header: hashheaderty; + data: treeelementdataty; + end; + ptreeelementhashdataty = ^treeelementhashdataty; + + treehashelementiteratorprocty = procedure(const aitem : ptreeelementhashdataty; + const adata: pointer) of object; + thashtree = class(thashstore) + protected + function add(const idents: identvecty; + out aelement: ptreeelementhashdataty): hashoffsetty; + function find(const idents: identvecty): ptreeelementhashdataty; + function find(const idents: identvecty; + out aoffs: hashoffsetty): ptreeelementhashdataty; +// function find(const aele: elementdataty): ptreeelementhashdataty; +// function add(const idents: identvecty; +// out aelement: pointer): hashoffsetty; +// function find(const idents: identvecty): pointer; + function getrecordsize(): int32 override; + procedure inititem(const aitem: phashdataty) override; + public + constructor create(); + function datapo(const aoffs: hashoffsetty): ptreeelementhashdataty; + function root(const aoffs: hashoffsetty): ptreeelementhashdataty; + function root(const aitem: ptreeelementhashdataty): ptreeelementhashdataty; + procedure iteratechildren(const aitem: ptreeelementhashdataty; + const aiterator: treehashelementiteratorprocty; + const adata: pointer); + end; + +implementation + +{ thashstore } +{ +constructor thashstore.create(); +begin + include(fstate,hls_needsinit); + inherited; +end; +} +function thashstore.add(const idents: identvecty; + out aelement: pelementhashdataty): hashoffsetty; +var + p1,pe: pidentty; + ele: elementdataty; + p2: pelementhashdataty; +// off1: hashoffsetty; +begin + if idents.high >= 0 then begin + ele.header.path:= 0; + ele.header.parent:= 0; + ele.header.parentlevel:= 0; + ele.header.refcount:= 0; + p1:= @idents.d; + pe:= p1+idents.high; + fcurparent:= 0; + while p1 <= pe do begin + ele.header.path:= ele.header.path+p1^; + ele.header.name:= p1^; + if (p1 = pe) then begin + p2:= nil; + end + else begin + p2:= find(ele); + end; + if (p2 = nil) then begin + p2:= pointer(internaladdhash(ele.header.path)); + p2^.data.header:= ele.header; + if fcurparent <> 0 then begin + inc(pelementhashdataty(fdata+fcurparent)^.data.header.refcount); + end; + end; + inc(ele.header.parentlevel); + ele.header.parent:= getdataoffs(p2); + fcurparent:= p2-fdata; + inc(p1); + end; + inc(p2^.data.header.refcount); +// adata:= @p2^.data.data; + aelement:= p2; + result:= pointer(p2)-fdata; + end + else begin + result:= 0; + aelement:= nil; + end; +end; + +function thashstore.find(const aele: elementdataty): pelementhashdataty; +var + p1: pelementhashdataty; + uint1: ptruint; +begin + result:= nil; + p1:= fdata; + if count > 0 then begin + uint1:= fhashtable[aele.header.path and fmask]; + while uint1 <> 0 do begin + p1:= pelementhashdataty(fdata + uint1); + with p1^ do begin + if (data.header.path = aele.header.path) and + (data.header.parent = aele.header.parent) then begin + result:= p1; + break; + end; + end; + uint1:= p1^.header.nexthash; + end; + end; +end; + +function thashstore.hashkey(const akey): hashvaluety; +begin + result:= elementdataty(akey).header.path; +end; + +function thashstore.checkkey(const akey; const aitem: phashdataty): boolean; +begin + result:= elementdataty(akey).header.path = + pelementhashdataty(aitem)^.data.header.path; +end; + +function thashstore.find(const idents: identvecty): pelementhashdataty; +var + c1: card32; + p1,p2,pe,ps: pidentty; + ph1,ph2: pelementhashdataty; + uint1: ptruint; +label + nextlab; +begin + result:= nil; + if (count > 0) and (idents.high >= 0) then begin + ps:= @idents.d; + p1:= ps; + pe:= p1+idents.high; + c1:= 0; + while p1 <= pe do begin + c1:= c1 + p1^; + inc(p1); + end; + uint1:= fhashtable[c1 and fmask]; + while uint1 <> 0 do begin + ph1:= pelementhashdataty(fdata + uint1); + with ph1^ do begin + if (data.header.path = c1) and + (data.header.parentlevel = idents.high) then begin + ph2:= ph1; + p2:= pe; + while p2 >= ps do begin + if p2^ <> ph2^.data.header.name then begin + goto nextlab; + end; + ph2:= fdata+ph2^.data.header.parent; + dec(p2); + end; + result:= ph1;//@ph1^.data.data; + exit; + end; + end; +nextlab: + uint1:= ph1^.header.nexthash; + end; + end; +end; +{ +function thashstore.add(const idents: identvecty; + out adata: pointer): hashoffsetty; +begin + result:= internaladd(idents,adata); + adata:= adata+sizeof(elementhashdataty); +end; +} +function thashstore.datapo(const aoffs: hashoffsetty): pelementhashdataty; +begin + result:= fdata+aoffs; +end; + +function thashstore.getrecordsize(): int32; +begin + result:= sizeof(elementhashdataty); +end; + +{ +function thashstore.find(const idents: identvecty): pointer; +begin + result:= internalfind(idents); + if result <> nil then begin + result:= result + sizeof(elementhashdataty); + end; +end; +} +procedure thashstore.delete(const item: hashoffsetty); +var + p1: pelementhashdataty; +begin + p1:= getdatapo(item{-sizeof(elementhashdataty)}); + while true do begin + dec(p1^.data.header.refcount); + if p1^.data.header.refcount > 0 then begin + break; + end; + internaldeleteitem(phashdataty(pointer(p1))); //memory still valid + if p1^.data.header.parent = 0 then begin + break; + end; + p1:= fdata+p1^.data.header.parent; + end; +end; + +procedure thashstore.delete(const idents: identvecty); +var + p1: pelementhashdataty; +begin + p1:= find(idents); + if p1 <> nil then begin + delete(getdataoffs(p1)); + end; +end; + +{ thashtree } + +const + treeheaderext = sizeof(treeelementhashdataty) - sizeof(elementhashdataty); + +constructor thashtree.create(); +begin + include(fstate,hls_needsinit); + inherited create(); +end; + +procedure thashtree.inititem(const aitem: phashdataty); +var + p1,p2: ptreeelementhashdataty; + o1,o2: hashoffsetty; +begin + with ptreeelementhashdataty(aitem)^.data.header do begin + children:= 0; + prevsibling:= 0; + nextsibling:= 0; + p1:= getdatapoornil(fcurparent); + if p1 <> nil then begin + o1:= p1^.data.header.children; + o2:= getdataoffs(aitem); + if o1 <> 0 then begin + p2:= datapo(o1); + p2^.data.header.nextsibling:= o2; + prevsibling:= o1; + end; + p1^.data.header.children:= o2; + end; + end; +end; + +function thashtree.add(const idents: identvecty; + out aelement: ptreeelementhashdataty): hashoffsetty; +{ +var + p1,p2: ptreeelementhashdataty; + o1: hashoffsetty; +} +begin + result:= inherited add(idents,pelementhashdataty(aelement)); +{ + with aelement^ do begin + p1:= getdatapoornil(data.header.element.parent); + if p1 <> nil then begin + o1:= p1^.data.header.children; + if o1 <> 0 then begin + p2:= datapo(o1); + p2^.data.header.nextsibling:= result-o1; + data.header.prevsibling:= pointer(p2) - pointer(aelement); + end; + p1^.data.header.children:= result; + end; + end; +} +// adata:= adata+sizeof(treeelementhashdataty); +end; + +procedure thashtree.iteratechildren(const aitem: ptreeelementhashdataty; + const aiterator: treehashelementiteratorprocty; + const adata: pointer); +var + o1: hashoffsetty; +begin + o1:= aitem^.data.header.children; + while o1 <> 0 do begin + aiterator(datapo(o1),adata); + o1:= datapo(o1)^.data.header.prevsibling; + end; +end; + +function thashtree.find(const idents: identvecty): ptreeelementhashdataty; +begin + result:= ptreeelementhashdataty(inherited find(idents)); +end; + +function thashtree.find(const idents: identvecty; + out aoffs: hashoffsetty): ptreeelementhashdataty; +begin + result:= ptreeelementhashdataty(inherited find(idents)); + if result = nil then begin + aoffs:= 0; + end + else begin + aoffs:= pointer(result)-fdata; + end; +end; + +function thashtree.datapo(const aoffs: hashoffsetty): ptreeelementhashdataty; +begin + result:= fdata+aoffs; +end; + +function thashtree.root(const aoffs: hashoffsetty): ptreeelementhashdataty; +var + o1: hashoffsetty; +begin + result:= nil; + o1:= aoffs; + while o1 <> 0 do begin + result:= fdata+o1; + o1:= result^.data.header.element.parent + end; +end; + +function thashtree.root( + const aitem: ptreeelementhashdataty): ptreeelementhashdataty; +begin + result:= aitem; + if aitem <> nil then begin + result:= root(getdataoffs(aitem)); + end; +end; + +function thashtree.getrecordsize(): int32; +begin + result:= sizeof(treeelementhashdataty); +end; + +end. diff --git a/mseide-msegui/lib/common/container/mselinklist.pas b/mseide-msegui/lib/common/container/mselinklist.pas new file mode 100644 index 0000000..ea4ca96 --- /dev/null +++ b/mseide-msegui/lib/common/container/mselinklist.pas @@ -0,0 +1,437 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mselinklist; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes; + +type + + linkheaderty = record + next: ptruint; //offset in data + end; + plinkheaderty = ^linkheaderty; + linkinfoty = record + header: linkheaderty; + data: record + end; + end; + + doublelinkheaderty = record + lh: linkheaderty; + prev: ptruint; //offset in data + end; + pdoublelinkheaderty = ^doublelinkheaderty; + doublelinkinfoty = record + header: doublelinkheaderty; + data: record + end; + end; + + tlinklist = class(tobject) + private + fcapacity: ptruint; + flast: ptruint; + fdeleted: ptruint; + fcount: integer; + function getcapacity: integer; + procedure setcapacity(const avalue: integer); + protected + fdata: pointer; //dummy item at 0 + fheadersize: integer; + fitemsize: integer; + function getheadersize: integer; virtual; + procedure grow; + function add(out aoffset: ptruint): pointer; + procedure delete(const aoffset: ptruint); + public + constructor create(const adatasize: integer); + destructor destroy; override; + procedure clear; + property count: integer read fcount; + property capacity: integer read getcapacity write setcapacity; + //grow only + end; + + tsinglelinklist = class(tlinklist) + protected + public + end; + + tdoublelinklist = class(tlinklist) + protected + function getheadersize: integer; override; + procedure delete(const aoffset: ptruint); + public + end; + + listadty = card32; + linklistheaderty = record + next: listadty; //offset from list + end; + plinklistheaderty = ^linkheaderty; + linkdataty = record + header: linkheaderty; + data: record + end; + end; + plinkdataty = ^linkdataty; + + linklistty = record + itemsize: integer; + mincapacity: integer; + list: pointer; + current: listadty; //offset from list + capacity: listadty; //offset from list + deleted: listadty; + end; + + resolvehandlerty = procedure(var item); + resolvehandlerdataty = procedure(var item; var data); + checkresolvehandlerty = procedure(var item; var data; var resolved: boolean); + +procedure clearlist(var alist: linklistty; const aitemsize: integer; + const amincapacity: integer); +procedure freelist(var alist: linklistty); +function addlistitem(var alist: linklistty; var aitem: listadty): pointer; +function getlistitem(const alist: linklistty; const aitem: listadty): pointer; +function getnextlistitem(const alist: linklistty; + const aitem: listadty): pointer; +procedure deletelistitem(var alist: linklistty; var achain: listadty); +procedure deletelistchain(var alist: linklistty; var achain: listadty); +procedure invertlist(const alist: linklistty; var achain: listadty); +procedure resolvelist(var alist: linklistty; const handler: resolvehandlerty; + var achain: listadty); +procedure checkresolve(var alist: linklistty; + const handler: checkresolvehandlerty; var achain: listadty; + const data: pointer); +procedure foralllistitems(var alist: linklistty; + const handler: resolvehandlerty; const achain: listadty); +procedure foralllistitemsdata(var alist: linklistty; + const handler: resolvehandlerdataty; const achain: listadty; + const data: pointer); + +implementation + +procedure clearlist(var alist: linklistty; const aitemsize: integer; + const amincapacity: integer); +begin + with alist do begin + itemsize:= aitemsize; + mincapacity:= amincapacity*aitemsize; + if list <> nil then begin + freemem(list); + end; + list:= nil; + current:= 0; + capacity:= 0; + deleted:= 0; + end; +end; + +procedure freelist(var alist: linklistty); +begin + with alist do begin + if list <> nil then begin + freemem(list); + end; + fillchar(alist,sizeof(alist),0); + end; +end; + +function addlistitem(var alist: linklistty; var aitem: listadty): pointer; +var + li1: listadty; +begin + with alist do begin + li1:= deleted; + if li1 = 0 then begin + current:= current + itemsize; + if current >= capacity then begin + capacity:= 2*capacity + mincapacity; + reallocmem(list,capacity); + end; + li1:= current; + result:= list+li1; + end + else begin + result:= list+li1; + deleted:= plinkheaderty(result)^.next; + end; + plinkheaderty(result)^.next:= aitem; + aitem:= li1; + end; +end; + +function getlistitem(const alist: linklistty; const aitem: listadty): pointer; +begin + result:= alist.list+aitem; +end; + +function getnextlistitem(const alist: linklistty; + const aitem: listadty): pointer; +var + i1: listadty; +begin + result:= alist.list+aitem; + i1:= plinkdataty(result)^.header.next; + if i1 = 0 then begin + result:= nil; + end + else begin + result:= alist.list+i1; + end; +end; + +procedure deletelistitem(var alist: linklistty; var achain: listadty); +var + next1: listadty; +begin + if achain <> 0 then begin + with alist do begin + next1:= plinkheaderty(list+achain)^.next; + plinkheaderty(list+achain)^.next:= deleted; + deleted:= achain; + end; + achain:= next1; + end; +end; + +procedure deletelistchain(var alist: linklistty; var achain: listadty); +var + ad1: listadty; + po1: plinkheaderty; +begin + if achain <> 0 then begin + with alist do begin + ad1:= achain; + repeat + po1:= alist.list+ad1; + ad1:= po1^.next; + until ad1 = 0; + po1^.next:= deleted; + deleted:= achain; + end; + achain:= 0; + end; +end; + +procedure invertlist(const alist: linklistty; var achain: listadty); +var + s,s1,d: listadty; +begin + if achain <> 0 then begin + d:= 0; + s:= achain; + repeat + with plinkheaderty(alist.list+s)^ do begin + s1:= next; + next:= d; + end; + d:= s; + s:= s1; + until s = 0; + achain:= d; + end; +end; + +procedure resolvelist(var alist: linklistty; const handler: resolvehandlerty; + var achain: listadty); +var + ad1: listadty; + po1: plinkheaderty; +begin + if achain <> 0 then begin + ad1:= achain; + with alist do begin + while ad1 <> 0 do begin + po1:= alist.list+ad1; + handler(po1^); + ad1:= po1^.next; + end; + plinkheaderty(list+achain)^.next:= deleted; + deleted:= achain; + achain:= 0; + end; + end; +end; + +procedure checkresolve(var alist: linklistty; + const handler: checkresolvehandlerty; var achain: listadty; + const data: pointer); +var + ad1: listadty; + po2: pointer; + po1,po3: plinkheaderty; + bo1: boolean; +begin + if achain <> 0 then begin + po3:= nil; + ad1:= achain; + po2:= alist.list; + while ad1 <> 0 do begin + po1:= po2+ad1; + bo1:= false; + handler(po1^,data^,bo1); + if bo1 then begin + if po3 <> nil then begin + po3^.next:= po1^.next; + end + else begin + achain:= po1^.next; + end; + if alist.deleted <> 0 then begin + plinkheaderty(alist.list+alist.deleted)^.next:= ad1; + end; + alist.deleted:= ad1; + ad1:= po1^.next; + po1^.next:= 0; + end + else begin + ad1:= po1^.next; + end; + po3:= po1; + end; + end; +end; + +procedure foralllistitems(var alist: linklistty; + const handler: resolvehandlerty; const achain: listadty); +var + ad1: listadty; + po2: pointer; + po1: plinkheaderty; +begin + if achain <> 0 then begin + ad1:= achain; + po2:= alist.list; + while ad1 <> 0 do begin + po1:= po2+ad1; + handler(po1^); + ad1:= po1^.next; + end; + end; +end; + +procedure foralllistitemsdata(var alist: linklistty; + const handler: resolvehandlerdataty; const achain: listadty; + const data: pointer); +var + ad1: listadty; + po2: pointer; + po1: plinkheaderty; +begin + if achain <> 0 then begin + ad1:= achain; + po2:= alist.list; + while ad1 <> 0 do begin + po1:= po2+ad1; + handler(po1^,data^); + ad1:= po1^.next; + end; + end; +end; + +{ tlinklist } + +constructor tlinklist.create(const adatasize: integer); +begin + fheadersize:= getheadersize; + fitemsize:= adatasize + fheadersize; +end; + +destructor tlinklist.destroy; +begin + clear; + inherited; +end; + +function tlinklist.getheadersize: integer; +begin + result:= sizeof(linkheaderty); +end; + +function tlinklist.getcapacity: integer; +begin + result:= fcapacity div fitemsize +end; + +procedure tlinklist.setcapacity(const avalue: integer); +var + ca1: ptruint; +begin + ca1:= avalue * fitemsize; + if ca1 > fcapacity then begin + reallocmem(fdata,ca1+fitemsize); + fcapacity:= ca1; + end; +end; + +procedure tlinklist.grow; +begin + capacity:= 2*count+256; +end; + +function tlinklist.add(out aoffset: ptruint): pointer; +begin + if fdeleted = 0 then begin + flast:= flast+fitemsize; + if flast >= fcapacity then begin + grow; + end; + aoffset:= flast; + end + else begin + aoffset:= fdeleted; + fdeleted:= plinkheaderty(fdata + fdeleted)^.next; + end; + inc(fcount); + result:= fdata+aoffset; +end; + +procedure tlinklist.delete(const aoffset: ptruint); +begin + plinkheaderty(fdata+aoffset)^.next:= fdeleted; + fdeleted:= aoffset; + dec(fcount); +end; + +procedure tlinklist.clear; +begin + if fdata <> nil then begin + freemem(fdata); + fdata:= nil; + end; + fcount:= 0; + fdeleted:= 0; + fcapacity:= 0; +end; + +{ tsinglelinklist } + + +{ tdoublelinklist } + +function tdoublelinklist.getheadersize: integer; +begin + result:= sizeof(doublelinkheaderty); +end; + +procedure tdoublelinklist.delete(const aoffset: ptruint); +begin + with pdoublelinkheaderty(fdata+aoffset)^ do begin + pdoublelinkheaderty(fdata+prev)^.lh.next:= lh.next; + pdoublelinkheaderty(fdata+lh.next)^.prev:= prev; + end; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/container/mselist.pas b/mseide-msegui/lib/common/container/mselist.pas new file mode 100644 index 0000000..c988c67 --- /dev/null +++ b/mseide-msegui/lib/common/container/mselist.pas @@ -0,0 +1,1861 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mselist; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msetypes,msestrings,mseglob,Classes,sysutils,msesystypes,msearrayutils; + +type +// compareprocty = procedure (const l,r; var result: integer) of object; + + recordliststatety = (rels_needsinitialize,rels_needsfinalize,rels_needscopy, + rels_destroying); + recordliststatesty = set of recordliststatety; + + trecordlist = class(tnullinterfacedobject) + private + fcapacity: integer; + procedure checkindex(const index: integer); + procedure checkcapacity; + procedure setcapacity(Value: integer); + protected + frecordsize: integer; + fcount: integer; + fdata: pchar; + fstate: recordliststatesty; + procedure inccount; + procedure setcount(const Value: integer); + procedure setitem(const index: integer; const source); + procedure getitem(const index: integer; out dest); + function add(const source): integer; //returns index of new record + function add(): pointer; //returns pointer of new record + procedure insert(const source; const index: integer); + function getitempo(const index: integer): pointer; + //nil if index < 0 + //will be invalid after capacity change! + function isempty(var item): boolean; virtual; + procedure finalizerecord(var item); virtual; + procedure initializerecord(var item); virtual; + procedure copyrecord(var item); virtual; + procedure change; virtual; + property recordsize: integer read frecordsize; + public + constructor create(const arecordsize: integer; + const aoptions: recordliststatesty = []); + destructor destroy; override; + procedure assign(const source: trecordlist); + function invalidindex(const aindex: int32): boolean; inline; + function validindex(const aindex: int32): boolean; inline; + function datapo: pointer; + function dataend: pointer; //after datablock + function newitem: pointer; virtual; + function newitems(const acount: integer): pointer; virtual; + procedure deletelast; + procedure pack; + procedure clear; virtual; + procedure delete(const index: integer); //indexes < 0 are ignored + property count: integer read fcount write setcount; + property capacity: integer read fcapacity write setcapacity; + end; + + torderedrecordlist = class(trecordlist) + private + fsorted: boolean; + procedure setsorted(const avalue: boolean); +// procedure quicksort(var arangelist: integerarty; L, R: Integer); + procedure sort; + protected + fcomparefunc: sortcomparemethodty; + function internalfind(const item; out index: integer): boolean; + //true if exact else next bigger + //for comp: l is item, r are tablevalues + function add(const source): integer; + function indexof(const item): integer; + function deleteitem(const item): integer; + function getcomparefunc: sortcomparemethodty; virtual; abstract; + public + function newitem: pointer; override; + function newitems(const acount: integer): pointer; override; + property sorted: boolean read fsorted write setsorted; + end; + + trecordmap = class(trecordlist) + private + procedure setorder(const avalue: integer); + protected + fcomparefuncs: sortcomparemethodarty; + findexes: pointerararty; + fhasindex: boolean; + forder: integer; + procedure setitem(const index: integer; const source); + procedure getitem(const index: integer; out dest); + function internalgetitempo(const aorder: integer; + const index: integer): pointer; + function getitempo(const index: integer): pointer; + //nil if index < 0 + //will be invalid after capacity change! + procedure sort(const aindexnum: integer); + function internalfind(const aindexnum: integer; const item; + out aindex: integer; out adata: pointer): boolean; + //true if exact else next bigger + //for comp: l is item, r are tablevalues + procedure change; override; + procedure setcomparefuncs(const afuncs: array of sortcomparemethodty); + public + constructor create(const arecordsize: integer; + const aoptions: recordliststatesty = []); + property order: integer read forder write setorder default -1; + end; + + tpointerlist = class(tnullinterfacedobject) + private + fringpointer: integer; //for queue + function getcapacity: integer; + procedure inccount; + protected + fitems: pointerarty; + fcount: integer; + procedure normalizering; + procedure setitems(index: integer; const Value: pointer); + function getitems(index: integer): pointer; + procedure checkindex(var index: integer); virtual; + procedure setcapacity(Value: integer); virtual; + public + destructor destroy; override; + procedure clear; virtual; + function datapo: ppointeraty; + function add(const value: pointer): integer; + procedure add(const values: ppointer; const acount: int32); + function remove(const item: pointer): integer; + function delete(index: integer): pointer; virtual; + procedure insert(index: integer; const value: pointer); virtual; + function indexof(const item: pointer): integer; + function extract(const item: pointer): pointer; + + procedure order(const sourceorderlist: integerarty); + procedure reorder(const destorderlist: integerarty); + procedure sort(compare: arraysortcomparety); overload; + procedure sort(compare: arraysortcomparety; out indexlist: integerarty); overload; + + property items[index: integer]: pointer read getitems write setitems; default; + property count: integer read fcount; + property capacity: integer read getcapacity write setcapacity; + end; + + tpointerqueue = class(tpointerlist) + private + fmaxcount: integer; + procedure setmaxcount(const Value: integer); + protected + fnofinalize: integer; + procedure checkindex(var index: integer); override; + procedure setcapacity(value: integer); override; + procedure finalizeitem(var item: pointer); virtual; + public + function datapo: ppointeraty; virtual; + procedure clear; override; + function delete(index: integer): pointer; override; + function add(const value: pointer): integer; + function indexof(const item: pointer): integer; + //-1 if not found + procedure insert(index: integer; const value: pointer); override; + function getfirst: pointer; + function getlast: pointer; + property maxcount: integer read fmaxcount write setmaxcount; + end; + + tmethodlist = class(trecordlist) + private + function getitems(index: integer): tmethod; + procedure setitems(index: integer; const avalue: tmethod); + protected + factitem: integer; + public + constructor create; + function indexof(const value: tmethod): integer; + function add(const value: tmethod): integer; + //creates no duplicates + function remove(const value: tmethod): integer; + property items[index: integer]: tmethod read getitems + write setitems; default; + end; + + tobjectqueue = class(tpointerqueue) + private + protected + function getitems(index: integer): tobject; + procedure setitems(index: integer; const Value: tobject); + procedure finalizeitem(var item: pointer); override; + public + ownsobjects: boolean; + constructor create(aownsobjects: boolean); + procedure add(value: tobject); + procedure insert(const index: integer; const value: tobject); reintroduce; + function getfirst: tobject; + function getlast: tobject; + property items[index: integer]: tobject read getitems write setitems; + end; + + tlockedobjectqueue = class(tobjectqueue) + private + fmutex: mutexty; + function getitems(index: integer): tobject; + procedure setitems(index: integer; const Value: tobject); + protected + procedure lock; + procedure unlock; + procedure setcapacity(Value: integer); override; + public + constructor create(aownsobjects: boolean); + destructor destroy; override; + //items below are thread safe + procedure add(value: tobject); + procedure insert(const index: integer; const value: tobject); reintroduce; + function getfirst: tobject; + function getlast: tobject; + property items[index: integer]: tobject read getitems write setitems; + end; + + nameidty = integer; + + indexednameinfoty = record + name: string; + id: nameidty + end; + pindexednameinfoty = ^indexednameinfoty; + indexednameinfoaty = array[0..0] of indexednameinfoty; + pindexednameinfoaty = ^indexednameinfoaty; + + tindexednamelist = class(torderedrecordlist) + private + fidnames: stringarty; + function comp(const l,r): integer; + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + function getcomparefunc: sortcomparemethodty; override; + public + constructor create; + function add(const avalue: string): integer; + //returns id + function find(const avalue: string): integer; + //returns id, -1 if not found + function getname(const id: integer): string; + end; + + mseindexednameinfoty = record + name: msestring; + id: nameidty + end; + pmseindexednameinfoty = ^mseindexednameinfoty; + mseindexednameinfoaty = array[0..0] of mseindexednameinfoty; + pmseindexednameinfoaty = ^mseindexednameinfoaty; + + tmseindexednamelist = class(torderedrecordlist) + private + fidnames: msestringarty; + function comp(const l,r): integer; + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + function getcomparefunc: sortcomparemethodty; override; + public + constructor create; + function add(const avalue: msestring): integer; virtual; + //returns id + function find(const avalue: msestring): integer; virtual; + //returns id, -1 if not found + function getname(const id: integer): msestring; + end; + + tindexedfilenamelist = class(tmseindexednamelist) + public + function add(const avalue: msestring): integer; override; + //returns id + function find(const avalue: msestring): integer; override; + //returns id, -1 if not found + end; + + bufferoffsetty = ptrint; + + bufferheaderty = record + size: bufferoffsetty; + data: record + end; + end; + pbufferheaderty = ^bufferheaderty; + + bufferdataliststatety = (bdls_destroying); + bufferdataliststatesty = set of bufferdataliststatety; + tbufferdatalist = class + private + fbuffer: pointer; + fbuffersize: bufferoffsetty; + fbuffercapacity: bufferoffsetty; + fnextitem: bufferoffsetty; + protected + fstate: bufferdataliststatesty; + function adddata(asize: int32): pointer; virtual; + function adddata(const asize: int32; out aoffset: bufferoffsetty): pointer; + public + constructor create(); + destructor destroy(); override; + procedure checkcapacity(const asize: int32); + procedure clear(); virtual; + procedure mark(out ref: bufferoffsetty); + procedure release(const ref: bufferoffsetty); + function absdata(const aoffset: bufferoffsetty): pointer; inline; + function firstdata: pointer; //nil if none + function nextdata: pointer; //nil if none + end; + + tindexbufferdatalist = class(tbufferdatalist) + private + findex: ptrintarty; + fcapacity: int32; + function getitems(index: integer): pointer; + protected + fcount: int32; + function adddata(asize: int32): pointer; override; + public + procedure clear(); override; + property items[index: integer]: pointer read getitems; + property count: int32 read fcount; + end; + +implementation +uses + rtlconsts,msebits,msedatalist,msesysintf1,msesysintf; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +const + growstep = 32; + +{ +procedure QuickSort1(var indexlist: array of integer; SortList: PPointerList; L, R: Integer; + SCompare: TListSortCompare); + //bei compareresult = 0 wird urspruengliche ordnung beibehalten +var + I, J: Integer; + P, T: Pointer; + pivotindex: integer; + pivotoffset: integer; + int1: integer; +label + 1,2; +begin + repeat + I := L; + J := R; + pivotindex:= (L + R) shr 1; + pivotoffset:= indexlist[pivotindex]; + P := SortList^[pivotindex]; + repeat +1: + int1:= SCompare(SortList^[I], P); + if int1 = 0 then begin + int1:= indexlist[i]-pivotoffset; + end; + if int1 < 0 then begin + inc(i); + goto 1; + end; + +// while SCompare(SortList^[I], P) < 0 do +// Inc(I); +2: + int1:= SCompare(SortList^[J], P); + if int1 = 0 then begin + int1:= indexlist[j]-pivotoffset; + end; + if int1 > 0 then begin + dec(j); + goto 2; + end; +// while SCompare(SortList^[J], P) > 0 do +// Dec(J); + if I <= J then + begin + T := SortList^[I]; + int1:= indexlist[i]; + SortList^[I] := SortList^[J]; + indexlist[I] := indexList[J]; + SortList^[J] := T; + indexlist[J] := int1; + Inc(I); + Dec(J); + end; + until I > J; + if L < J then + QuickSort1(indexlist,SortList, L, J, SCompare); + L := I; + until I >= R; +end; + +procedure QuickSortmse(SortList: PPointerList; count: integer; + SCompare: TListSortCompare; out indexlist: integerarty); + //on compareresult = 0 order remains unchanged +var + int1: integer; +begin + setlength(indexlist,count); + if count > 0 then begin + for int1:= 0 to count -1 do begin + indexlist[int1]:= int1; + end; + quicksort1(indexlist,sortlist,0,count-1,scompare); + end; +end; +} +{ tlistmse } +{ +procedure tlistmse.Sort(Compare: TListSortCompare); +var + indexlist: integerarty; +begin + sort(compare,indexlist) +end; + +procedure tlistmse.Sort(Compare: TListSortCompare; out indexlist: integerarty); +begin + if (List <> nil) and (Count > 0) then begin + QuickSortmse(List, Count, Compare,indexlist); + end; +end; +} + +{ trecordlist } + +constructor trecordlist.create(const arecordsize: integer; + const aoptions: recordliststatesty = []); +begin + frecordsize:= arecordsize; + fstate:= aoptions; +end; + +destructor trecordlist.destroy; +begin + clear; + if fdata <> nil then begin + freemem(fdata); + end; + inherited; +end; + +procedure trecordlist.assign(const source: trecordlist); +var + int1: integer; + po1: pchar; +begin + if (rels_needsinitialize in fstate) or (source.ClassType <> self.ClassType) then begin + raise exception.Create('Can not assign'); + end; + clear; + count:= source.count; + move(source.datapo^,fdata^,count*frecordsize); + if rels_needscopy in fstate then begin + po1:= fdata; + for int1:= 0 to fcount - 1 do begin + copyrecord(po1^); + inc(po1,frecordsize); + end; + end; +end; + +function trecordlist.datapo: pointer; +begin + result:= fdata; +end; + +function trecordlist.dataend: pointer; +begin + result:= fdata+fcount*frecordsize; +end; + +function trecordlist.newitem: pointer; +begin + inccount; + result:= getitempo(fcount - 1); +end; + +function trecordlist.newitems(const acount: integer): pointer; +var + int1: integer; +begin + if acount > 0 then begin + int1:= fcount; + count:= count + acount; + result:= fdata + int1 * frecordsize; + end + else begin + result:= nil; + end; +end; + +procedure trecordlist.deletelast; +begin + delete(fcount - 1); +end; + +procedure trecordlist.setcapacity(Value: integer); +begin + if value < fcount then begin + value:= fcount; + end; + if fcapacity <> value then begin + fcapacity := Value; + reallocmem(fdata,value*frecordsize); + end; +end; + +procedure trecordlist.checkcapacity; +begin + if fcapacity > fcount + fcount div 4 + 2*growstep then begin + capacity:= fcount + fcount div 8 + growstep; + end; +end; + +procedure trecordlist.setcount(const Value: integer); +var + int1: integer; + po1: pchar; +begin + if value <> fcount then begin + if value > fcount then begin + if fcapacity < value then begin + capacity:= value + value div 8 + growstep; + end; + fillchar((fdata+fcount*frecordsize)^,(value-fcount)*frecordsize,0); + if rels_needsinitialize in fstate then begin + po1:= fdata + fcount * frecordsize; + for int1:= fcount to value - 1 do begin + initializerecord(po1^); + inc(po1,frecordsize); + end; + end; + fcount:= value; + end + else begin + if rels_needsfinalize in fstate then begin + po1:= fdata + value * frecordsize; + for int1:= value to fcount - 1 do begin + finalizerecord(po1^); + inc(po1,frecordsize); + end; + end; + fcount:= value; + checkcapacity; + end; + change; + end; +end; + +procedure trecordlist.inccount; +begin + count:= fcount + 1; + { + inc(fcount); + if fcapacity < fcount then begin + capacity:= fcount + fcount div 8 + growstep; + end; +} +end; + +function trecordlist.add(const source): integer; +var + po1: pointer; +begin + result:= fcount; + inccount; + po1:= fdata + result * frecordsize; + move(source,po1^,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; +end; + +function trecordlist.add: pointer; +begin + inccount(); + result:= pointer(fdata) + (fcount - 1) * frecordsize; +end; + + +procedure trecordlist.insert(const source; const index: integer); +var + po1: pchar; +begin + inccount; + po1:= fdata+index*frecordsize; + move(po1^,(po1+frecordsize)^,(count-index-1)*frecordsize); + move(source,po1^,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; +end; + +procedure trecordlist.checkindex(const index: integer); +begin + if (index < 0) or (index >= fcount) then begin + tlist.error(slistindexerror,index); + end; +end; + +procedure trecordlist.getitem(const index: integer; out dest); +var + po1: pchar; +begin + checkindex(index); + po1:= fdata+index*frecordsize; + move(po1^,dest,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; +end; + +function trecordlist.getitempo(const index: integer): pointer; +//var +// int1: integer; +begin + if index < 0 then begin + result:= nil; + end + else begin +// int1:= index; + checkindex(index); + result:= fdata + index * frecordsize; + end; +end; + +procedure trecordlist.setitem(const index: integer; const source); +var + po1: pchar; +begin + checkindex(index); + po1:= fdata+index*frecordsize; + if rels_needsfinalize in fstate then begin + finalizerecord(po1^); + end; + move(source,(po1)^,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; + change; +end; + +procedure trecordlist.clear; +begin + count:= 0; +end; + +procedure trecordlist.delete(const index: integer); +begin + if index >= 0 then begin + checkindex(index); + if rels_needsfinalize in fstate then begin + finalizerecord((fdata+index*frecordsize)^); + end; + if index < count-1 then begin + move((fdata+(index+1)*frecordsize)^,(fdata+index*frecordsize)^, + (fcount-index-1)*frecordsize); + end; + fcount:= fcount-1; + checkcapacity; + end; +end; + +function trecordlist.isempty(var item): boolean; +begin + result:= iszero(@item,frecordsize); +end; + +procedure trecordlist.pack; +var + po1,po2,po3: pchar; + int1,int2: integer; +begin + if fcount <> 0 then begin + getmem(po1,fcount*frecordsize); + po3:= po1; + po2:= fdata; + int2:= 0; + for int1:= 0 to fcount -1 do begin + if not isempty(po2^) then begin + move(po2^,po3^,frecordsize); + inc(int2); + inc(po3,frecordsize); + end; + inc(po2,frecordsize); + end; + freemem(fdata); + fdata:= po1; + fcount:= int2; + fcapacity:= fcount; + if fcount > 0 then begin + reallocmem(fdata,fcount*frecordsize); + end + else begin + freemem(fdata); + fdata:= nil; + end; + change; + end; +end; + +procedure trecordlist.initializerecord(var item); +begin + //dummy +end; + +procedure trecordlist.finalizerecord(var item); +begin + //dummy +end; + +procedure trecordlist.copyrecord(var item); +begin + //dummy +end; + +procedure trecordlist.change; +begin + //dummy +end; + +function trecordlist.invalidindex(const aindex: int32): boolean; +begin + result:= (aindex < 0) or (aindex >= fcount); +end; + +function trecordlist.validindex(const aindex: int32): boolean; +begin + result:= (aindex >= 0) and (aindex < fcount); +end; + +{ torderedrecordlist } + +function torderedrecordlist.add(const source): integer; +begin + if fsorted then begin + internalfind(source,result); + insert(source,result); + end + else begin + result:= inherited add(source); + end; +end; + +procedure torderedrecordlist.setsorted(const avalue: boolean); +begin + if avalue <> fsorted then begin + if avalue then begin + sort; + end; + fsorted:= avalue; + end; +end; +(* +procedure torderedrecordlist.quicksort(var arangelist: integerarty; L, R: Integer); +var + I, J: Integer; + P, T: integer; + int1: integer; + pp: pointer; +begin + if r >= l then begin + repeat + I := L; + J := R; + P := arangelist[(L + R) shr 1]; + pp:= fdata+p*frecordsize; + repeat + repeat + int1:= fcomparefunc((fdata+arangeList[I]*frecordsize)^, pp^); + if int1 = 0 then begin + int1:= arangelist[i] - p; + end; + if int1 >= 0 then break; + inc(i); + until false; + repeat + int1:= fcomparefunc((fdata+arangeList[J]*frecordsize)^, pp^); + if int1 = 0 then begin + int1:= arangelist[j] - p; + end; + if int1 <= 0 then break; + dec(j); + until false; +// while (sortfunc(List.items[I], P,self) < 0) do Inc(I); +// while (sortfunc(List.items[J], P,self) > 0) do Dec(J); + if I <= J then + begin + if i <> j then begin + T := arangeList[I]; + arangeList[I] := arangeList[J]; + arangeList[J] := T; + end; + Inc(I); + Dec(J); + end; + until I > J; + if L < J then QuickSort(arangelist,L, J); + L := I; + until I >= R; + end; +end; +*) +procedure torderedrecordlist.sort; + + +var + arangelist: integerarty; + int1: integer; + po1,po2: pchar; +begin + fcomparefunc:= getcomparefunc(); + if fcount > 0 then begin +// setlength(arangelist,fcount); +// for int1:= 0 to high(arangelist) do begin +// arangelist[int1]:= int1; +// end; +// quicksort(arangelist,0,fcount-1); + mergesort(fdata,frecordsize,fcount,fcomparefunc,arangelist); + getmem(po1,fcount*frecordsize); + po2:= po1; + for int1:= 0 to high(arangelist) do begin + move((fdata+arangelist[int1]*frecordsize)^,po2^,frecordsize); + inc(po2,frecordsize); + end; + freemem(fdata); + fdata:= po1; + fcapacity:= fcount; + end; +end; + +function torderedrecordlist.internalfind(const item; out index: integer): boolean; +var + ilo,ihi:integer; + int1,int2: integer; +// bo1: boolean; +begin + sorted:= true; + index:= fcount; + result:= false; + if fcount > 0 then begin + ilo:= 0; + ihi:= fcount - 1; +// bo1:= false; + while true do begin + int1:= (ilo + ihi) div 2; + int2:= fcomparefunc(item,(fdata+int1*frecordsize)^); +// if int2 = 0 then begin +// index:= int1; +// result:= true; +// break; +// end +// else begin + if int2 >= 0 then begin //item <= pivot + if int2 = 0 then begin + result:= true; //found + end; + if ihi = ilo then begin + index:= ihi + 1; + break; + end; + if ilo = int1 then begin + inc(ilo); + end + else begin + ilo:= int1; + end; + end + else begin //item > pivot + if ihi = ilo then begin + index:= ihi; + break; + end; + ihi:= int1; +// end; + end; + end; + if result then begin + dec(index); + end; + end; +end; + +function torderedrecordlist.indexof(const item): integer; +begin + if not internalfind(item,result) then begin + result:= -1; + end; +end; + +function torderedrecordlist.deleteitem(const item): integer; +begin + result:= indexof(item); + if result >= 0 then begin + delete(result); + end; +end; + +function torderedrecordlist.newitem: pointer; +begin + fsorted:= false; + result:= inherited newitem; +end; + +function torderedrecordlist.newitems(const acount: integer): pointer; +begin + fsorted:= false; + result:= inherited newitems(acount); +end; + +{ tpointerlist } + +destructor tpointerlist.destroy; +begin + clear; + inherited; +end; +function tpointerlist.getcapacity: integer; +begin + result:= length(fitems); +end; + +procedure tpointerlist.setcapacity(Value: integer); +begin + if value < fcount then begin + value:= fcount; + end; + setlength(fitems,value); +end; + +procedure tpointerlist.checkindex(var index: integer); +begin + if (index < 0) or (index >= fcount) then begin + tlist.error(slistindexerror,index); + end; +end; + +procedure tpointerlist.setitems(index: integer; const Value: pointer); +begin + checkindex(index); + fitems[index]:= value; +end; + +function tpointerlist.getitems(index: integer): pointer; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure tpointerlist.normalizering; +var + ar1: pointerarty; + int1: integer; +begin + if fringpointer <> 0 then begin + if fringpointer + fcount > length(fitems) then begin //2 pieces + setlength(ar1,count); + int1:= length(fitems)-fringpointer; + move(fitems[fringpointer],ar1[0], + int1*sizeof(pointer)); + move(fitems[0],ar1[int1], + (fcount-int1)*sizeof(pointer)); + fitems:= ar1; + end + else begin + move(fitems[fringpointer],fitems[0],fcount*sizeof(pointer)); + end; + fringpointer:= 0; + end; +end; + +procedure tpointerlist.inccount; +begin + if fcount >= length(fitems) then begin + capacity:= fcount + fcount div 4 + 32; + end; + inc(fcount); +end; + +function tpointerlist.add(const value: pointer): integer; +begin + inccount; + result:= fcount - 1; + setitems(result,value); +end; + +procedure tpointerlist.add(const values: ppointer; const acount: int32); +var + i1: int32; +begin + normalizering(); + i1:= fcount; + fcount:= fcount + acount; + if fcount >= length(fitems) then begin + capacity:= fcount + fcount div 4 + 32; + end; + move(values^,fitems[i1],acount * sizeof(pointer)); +end; + +procedure tpointerlist.clear; +begin + fcount:= 0; +end; + +function tpointerlist.indexof(const item: pointer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to fcount - 1 do begin + if fitems[int1] = item then begin + result:= int1; + exit; + end; + end; +end; + +function tpointerlist.delete(index: integer): pointer; +begin + checkindex(index); + result:= fitems[index]; + move(fitems[index+1],fitems[index],(fcount-index-1)*sizeof(pointer)); + dec(fcount); +end; + +function tpointerlist.remove(const item: pointer): integer; +begin + result:= indexof(item); + if result >= 0 then begin + delete(result); + end; +end; + +procedure tpointerlist.insert(index: integer; const value: pointer); +begin + if index = fcount then begin + add(value); + end + else begin + checkindex(index); + inccount; + move(fitems[index],fitems[index+1],(fcount-index-1)*sizeof(pointer)); + fitems[index]:= value; + end; +end; + +function tpointerlist.extract(const item: pointer): pointer; +var + int1: integer; +begin + int1:= indexof(item); + if int1 >= 0 then begin + result:= fitems[int1]; + delete(int1); + end + else begin + result:= nil; + end; +end; + +procedure tpointerlist.order(const sourceorderlist: integerarty); +var + int1: integer; + ar1: pointerarty; +begin + normalizering; + allocuninitedarray(length(fitems),sizeof(pointer),ar1); + for int1:= 0 to fcount - 1 do begin + ar1[int1]:= fitems[sourceorderlist[int1]]; + end; + fitems:= ar1; +end; + +procedure tpointerlist.reorder(const destorderlist: integerarty); +var + int1: integer; + ar1: pointerarty; +begin + normalizering; + allocuninitedarray(length(fitems),sizeof(pointer),ar1); + for int1:= 0 to fcount - 1 do begin + ar1[destorderlist[int1]]:= fitems[int1]; + end; + fitems:= ar1; +end; + +procedure tpointerlist.sort(compare: arraysortcomparety; + out indexlist: integerarty); +begin + mergesortarray(fitems,sizeof(pointer),fcount,compare,indexlist,false); + order(indexlist); +end; + +procedure tpointerlist.sort(compare: arraysortcomparety); +var + indexlist: integerarty; +begin + sort(compare,indexlist); +end; + +function tpointerlist.datapo: ppointeraty; +begin + result:= ppointeraty(pointer(fitems)); +end; + +{ tpointerqueue } + +procedure tpointerqueue.checkindex(var index: integer); +begin + inherited; + inc(index,fringpointer); + if index >= length(fitems) then begin + dec(index,length(fitems)); + end; +end; + +function tpointerqueue.delete(index: integer): pointer; +begin + normalizering; + result:= inherited delete(index); + if fnofinalize = 0 then begin + finalizeitem(result); + end; +end; + +procedure tpointerqueue.clear; +var + int1: integer; +begin + normalizering; + if fnofinalize = 0 then begin + for int1:= 0 to fcount - 1 do begin + finalizeitem(fitems[int1]); + end; + end; + inherited; +end; + +procedure tpointerqueue.insert(index: integer; const value: pointer); +begin + normalizering; + inherited; +end; + +function tpointerqueue.getfirst: pointer; +begin + if fcount = 0 then begin + result:= nil; + end + else begin + result:= fitems[fringpointer]; + dec(fcount); + inc(fringpointer); + if fringpointer >= length(fitems) then begin + dec(fringpointer,length(fitems)); + end; + end; +end; + +function tpointerqueue.getlast: pointer; +begin + if fcount = 0 then begin + result:= nil; + end + else begin + result:= items[fcount-1]; + dec(fcount); + end; +end; + +function tpointerqueue.indexof(const item: pointer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= fringpointer to fcount - 1 do begin + if int1 >= length(fitems) then begin + break; + end; + if fitems[int1] = item then begin + result:= int1; + exit; + end; + end; + for int1:= 0 to count - (length(fitems) - fringpointer) - 1 do begin + if fitems[int1] = item then begin + result:= int1; + exit; + end; + end; +end; + +procedure tpointerqueue.setcapacity(Value: integer); +begin + normalizering; + inherited; +end; + +function tpointerqueue.add(const value: pointer): integer; +begin + if (fmaxcount <> 0) and (fcount >= fmaxcount) then begin + finalizeitem(fitems[fringpointer]); + getfirst; + end; + result:= inherited add(value); +end; + +procedure tpointerqueue.setmaxcount(const Value: integer); +var + int1: integer; +begin + fmaxcount := Value; + if (fmaxcount <> 0) and (fcount > fmaxcount) then begin + normalizering; + for int1:= 0 to fcount-fmaxcount-1 do begin + finalizeitem(fitems[int1]); + end; + fringpointer:= fcount-fmaxcount; + fcount:= fmaxcount; + capacity:= fmaxcount; + end; +end; + +procedure tpointerqueue.finalizeitem(var item: pointer); +begin + //dummy +end; + +function tpointerqueue.datapo: ppointeraty; +begin + normalizering; + result:= inherited datapo; +end; + +{ tobjectqueue } + +procedure tobjectqueue.finalizeitem(var item: pointer); +begin + if ownsobjects then begin + tobject(item).Free; + item:= nil; + end; +end; + +function tobjectqueue.getitems(index: integer): tobject; +begin + result:= tobject(inherited getitems(index)); +end; + +procedure tobjectqueue.setitems(index: integer; const Value: tobject); +begin + inherited setitems(index,value); +end; + +function tobjectqueue.getfirst: tobject; +begin + result:= tobject(inherited getfirst); +end; + +function tobjectqueue.getlast: tobject; +begin + result:= tobject(inherited getlast); +end; + +procedure tobjectqueue.add(value: tobject); +begin + inherited add(value); +end; + +procedure tobjectqueue.insert(const index: integer; const value: tobject); +begin + inherited insert(index,value); +end; + +constructor tobjectqueue.create(aownsobjects: boolean); +begin + ownsobjects:= aownsobjects; + inherited create; +end; + +{ tmethodlist } + +function tmethodlist.add(const value: tmethod): integer; +begin + result:= indexof(value); + if result < 0 then begin + result:= inherited add(value); + end; +end; + +constructor tmethodlist.create; +begin + inherited create(sizeof(tmethod)); +end; + +function tmethodlist.indexof(const value: tmethod): integer; +var + po1: pmethod; + int1: integer; + +begin + result:= -1; + po1:= pmethod(fdata); + for int1:= 0 to fcount - 1 do begin + if issamemethod(value,po1^) then begin + result:= int1; + break; + end; + inc(po1); + end; +end; + +function tmethodlist.remove(const value: tmethod): integer; +begin + result:= indexof(value); + if result >= 0 then begin + delete(result); + if result <= factitem then begin + dec(factitem); + end; + end; +end; + +function tmethodlist.getitems(index: integer): tmethod; +begin + checkindex(index); + result:= pmethod(fdata+index*sizeof(tmethod))^; +end; + +procedure tmethodlist.setitems(index: integer; const avalue: tmethod); +begin + checkindex(index); + pmethod(fdata+index*sizeof(tmethod))^:= avalue; +end; + +{ tindexednamelist } + +constructor tindexednamelist.create; +begin + inherited create(sizeof(indexednameinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +function tindexednamelist.add(const avalue: string): integer; +var + info: indexednameinfoty; +begin + info.name:= avalue; + result:= find(avalue); + if result < 0 then begin + additem(fidnames,avalue); + info.id:= high(fidnames); + result:= info.id; + inherited add(info); + end; +end; + +procedure tindexednamelist.finalizerecord(var item); +begin + finalize(indexednameinfoty(item)); +end; + +procedure tindexednamelist.copyrecord(var item); +begin + with mseindexednameinfoty(item) do begin + stringaddref(name); + end; +end; + +function tindexednamelist.comp(const l,r): integer; +var + int1: integer; +begin + result:= (length(indexednameinfoty(l).name) - + length(indexednameinfoty(r).name)) shl 16; + if result = 0 then begin + for int1:= length(indexednameinfoty(l).name) - 1 downto 0 do begin + result:= integer(pcharaty(indexednameinfoty(l).name)^[int1]) - + integer(pcharaty(indexednameinfoty(r).name)^[int1]); + if result <> 0 then begin + break; + end; + end; + end; +end; + +function tindexednamelist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}comp; +end; + +function tindexednamelist.find(const avalue: string): integer; +var + info: indexednameinfoty; + int1: integer; +begin + info.name:= avalue; + if internalfind(info,int1) then begin + result:= pindexednameinfoaty(datapo)^[int1].id; + end + else begin + result:= -1; + end; +end; + +function tindexednamelist.getname(const id: integer): string; +begin + if (id < 0) or (id > high(fidnames)) then begin + result:= ''; + end + else begin + result:= fidnames[id]; + end; +end; + + +{ tmseindexednamelist } + +constructor tmseindexednamelist.create; +begin + inherited create(sizeof(mseindexednameinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +function tmseindexednamelist.add(const avalue: msestring): integer; +var + info: mseindexednameinfoty; +begin + info.name:= avalue; + result:= find(avalue); + if result < 0 then begin + additem(fidnames,avalue); + info.id:= high(fidnames); + result:= info.id; + inherited add(info); + end; +end; + +procedure tmseindexednamelist.finalizerecord(var item); +begin + finalize(mseindexednameinfoty(item)); +end; + +procedure tmseindexednamelist.copyrecord(var item); +begin + with mseindexednameinfoty(item) do begin + stringaddref(name); + end; +end; + +function tmseindexednamelist.comp(const l,r): integer; +var + int1: integer; +begin + result:= (length(mseindexednameinfoty(l).name) - + length(mseindexednameinfoty(r).name)) shl 16; + if result = 0 then begin + for int1:= length(mseindexednameinfoty(l).name) - 1 downto 0 do begin + result:= integer(pmsecharaty(mseindexednameinfoty(l).name)^[int1]) - + integer(pmsecharaty(mseindexednameinfoty(r).name)^[int1]); + if result <> 0 then begin + break; + end; + end; + end; +end; + +function tmseindexednamelist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}comp; +end; + +function tmseindexednamelist.find(const avalue: msestring): integer; +var + info: mseindexednameinfoty; + int1: integer; +begin + info.name:= avalue; + if internalfind(info,int1) then begin + result:= pmseindexednameinfoaty(datapo)^[int1].id; + end + else begin + result:= -1; + end; +end; + +function tmseindexednamelist.getname(const id: integer): msestring; +begin + if (id < 0) or (id > high(fidnames)) then begin + result:= ''; + end + else begin + result:= fidnames[id]; + end; +end; + +{ tindexedfilenamelist } + +function tindexedfilenamelist.add(const avalue: msestring): integer; +begin + if sys_filesystemiscaseinsensitive then begin + result:= inherited add(mselowercase(avalue)); + end + else begin + result:= inherited add(avalue); + end; +end; + +function tindexedfilenamelist.find(const avalue: msestring): integer; +begin + if sys_filesystemiscaseinsensitive then begin + result:= inherited find(mselowercase(avalue)); + end + else begin + result:= inherited find(avalue); + end; +end; + +{ tlockedobjectqueue } + +constructor tlockedobjectqueue.create(aownsobjects: boolean); +begin + sys_mutexcreate(fmutex); + inherited; +end; + +destructor tlockedobjectqueue.destroy; +begin + inherited; + sys_mutexdestroy(fmutex); +end; + +function tlockedobjectqueue.getitems(index: integer): tobject; +begin + lock; + result:= inherited getitems(index); + unlock; +end; + +procedure tlockedobjectqueue.setitems(index: integer; const Value: tobject); +begin + lock; + inherited setitems(index,value); + unlock; +end; + +procedure tlockedobjectqueue.lock; +begin + sys_mutexlock(fmutex); +end; + +procedure tlockedobjectqueue.unlock; +begin + sys_mutexunlock(fmutex); +end; + +procedure tlockedobjectqueue.setcapacity(Value: integer); +begin + lock; + inherited; + unlock; +end; + +procedure tlockedobjectqueue.add(value: tobject); +begin + lock; + inherited add(value); + unlock; +end; + +procedure tlockedobjectqueue.insert(const index: integer; const value: tobject); +begin + lock; + inherited insert(index,value); + unlock; +end; + +function tlockedobjectqueue.getfirst: tobject; +begin + lock; + result:= inherited getfirst; + unlock; +end; + +function tlockedobjectqueue.getlast: tobject; +begin + lock; + result:= inherited getlast; + unlock; +end; + +{ trecordmap } + +constructor trecordmap.create(const arecordsize: integer; + const aoptions: recordliststatesty = []); +begin + forder:= -1; + inherited; +end; + +procedure trecordmap.change; +var + int1: integer; +begin + if fhasindex then begin + for int1:= 0 to high(findexes) do begin + findexes[int1]:= nil; + end; + fhasindex:= false; + end; +end; + +procedure trecordmap.setcomparefuncs(const afuncs: array of sortcomparemethodty); +var + int1: integer; +begin + if forder > high(afuncs) then begin + forder:= -1; + end; + change; + setlength(findexes,length(afuncs)); + setlength(fcomparefuncs,length(afuncs)); + for int1:= 0 to high(fcomparefuncs) do begin + fcomparefuncs[int1]:= afuncs[int1]; + end; +end; + +procedure trecordmap.sort(const aindexnum: integer); +begin + mergesortpointer(fdata,frecordsize,fcount,fcomparefuncs[aindexnum], + findexes[aindexnum]); + fhasindex:= true; +end; + +function trecordmap.internalfind(const aindexnum: integer; const item; + out aindex: integer; out adata: pointer): boolean; +begin + result:= false; + aindex:= -1; + adata:= nil; + if fcount > 0 then begin + if findexes[aindexnum] = nil then begin + sort(aindexnum); + end; + result:= findarrayitem(item,findexes[aindexnum], + fcomparefuncs[aindexnum],aindex); + if aindex < fcount then begin + adata:= findexes[aindexnum][aindex]; + end; + end; +end; + +function trecordmap.internalgetitempo(const aorder: integer; + const index: integer): pointer; +begin + checkindex(index); + if aorder >= 0 then begin + if findexes[aorder] = nil then begin + sort(aorder); + end; + result:= findexes[aorder][index]; + end + else begin + result:= fdata + index * frecordsize; + end; +end; + +procedure trecordmap.setitem(const index: integer; const source); +var + po1: pointer; +begin + po1:= internalgetitempo(forder,index); + if rels_needsfinalize in fstate then begin + finalizerecord(po1^); + end; + move(source,(po1)^,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; + change; +end; + +procedure trecordmap.getitem(const index: integer; out dest); +var + po1: pointer; +begin + po1:= internalgetitempo(forder,index); + move(po1^,dest,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; +end; + +function trecordmap.getitempo(const index: integer): pointer; +begin + result:= nil; + if index >= 0 then begin + result:= internalgetitempo(forder,index); + end; +end; + +procedure trecordmap.setorder(const avalue: integer); +begin + if (avalue < -1) or (avalue > high(findexes)) then begin + raise exception.create('Invalid order index '+inttostr(avalue)+'.'); + end; + forder:= avalue; +end; + +{ tbufferdatalist } + +constructor tbufferdatalist.create; +begin +end; + +destructor tbufferdatalist.destroy(); +begin + include(fstate,bdls_destroying); + clear(); +end; + +procedure tbufferdatalist.clear; +begin + if fbuffer <> nil then begin + freemem(fbuffer); + fbuffer:= nil; + fbuffersize:= 0; + fbuffercapacity:= 0; + end; +end; + +procedure tbufferdatalist.mark(out ref: bufferoffsetty); +begin + ref:= fbuffersize; +end; + +procedure tbufferdatalist.release(const ref: bufferoffsetty); +begin + fbuffersize:= ref; +end; + +function tbufferdatalist.absdata(const aoffset: bufferoffsetty): pointer; +begin + result:= fbuffer + aoffset; +end; + +procedure tbufferdatalist.checkcapacity(const asize: int32); +begin + fbuffersize:= fbuffersize + ((asize+3) and not 3); //4 byte align + if fbuffersize > fbuffercapacity then begin + fbuffercapacity:= fbuffersize*2 + 1024; + reallocmem(fbuffer,fbuffercapacity); + end; +end; +{ +procedure tbufferdatalist.add(const asize: int32); +begin + checkcapacity(asize); + fbuffersize:= fbuffersize + asize; +end; +} + +function tbufferdatalist.adddata(asize: int32): pointer; +var + i1: bufferoffsetty; +begin + asize:= asize + sizeof(bufferheaderty); + i1:= fbuffersize; + checkcapacity(asize); + result:= fbuffer + i1; + pbufferheaderty(result)^.size:= fbuffersize-i1; + inc(result,sizeof(bufferheaderty)); +end; + +function tbufferdatalist.adddata(const asize: int32; + out aoffset: bufferoffsetty): pointer; +begin + aoffset:= fbuffersize; + result:= adddata(asize); +end; + +function tbufferdatalist.firstdata: pointer; +begin + result:= nil; + if fbuffersize > 0 then begin + result:= fbuffer; + fnextitem:= pbufferheaderty(result)^.size; + inc(result,sizeof(bufferheaderty)); + end; +end; + +function tbufferdatalist.nextdata: pointer; +begin + result:= nil; + if fnextitem < fbuffersize then begin + result:= fbuffer + fnextitem; + inc(fnextitem,pbufferheaderty(result)^.size); + inc(result,sizeof(bufferheaderty)); + end; +end; + +{ tindexbufferdatalist } + +procedure tindexbufferdatalist.clear; +begin + inherited; + findex:= nil; + fcount:= 0; + fcapacity:= 0; +end; + +function tindexbufferdatalist.adddata(asize: int32): pointer; +begin + result:= inherited adddata(asize); + if fcount >= fcapacity then begin + fcapacity:= 2*fcount + 1024; + reallocuninitedarray(fcapacity,sizeof(findex[0]),findex); + end; + findex[fcount]:= result-fbuffer; + inc(fcount); +end; + +function tindexbufferdatalist.getitems(index: integer): pointer; +begin + if (index < 0) or (index >= fcount) then begin + tlist.error(slistindexerror,index); + end; + result:= fbuffer + findex[index]{ + sizeof(bufferheaderty)}; +end; + +end. + + + + + diff --git a/mseide-msegui/lib/common/container/msestringident.pas b/mseide-msegui/lib/common/container/msestringident.pas new file mode 100644 index 0000000..02f29ce --- /dev/null +++ b/mseide-msegui/lib/common/container/msestringident.pas @@ -0,0 +1,573 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestringident; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + {globtypes,}msehash,msestrings,msetypes; + +//{$define caseinsensitive} +const + firstident = 256; + stridstart = $12345678; //not used + strid0 = $2468ACF1; + strid1 = $48D159E3; + strid2 = $91A2B3C6; + strid3 = $2345678C; + strid4 = $468ACF19; + strid5 = $8D159E33; + strid6 = $1A2B3C66; + strid7 = $345678CD; + strid8 = $68ACF19B; + strid9 = $D159E337; + +type +// keywordty = identty; + + identnamety = record + offset: int32; //relative to data block + end; + + identheaderty = record + ident: identty; + end; + + pidentheaderty = ^identheaderty; + identoffsetty = int32; + + identdataty = record + header:identheaderty; + keyname: identoffsetty; // +// keylen: integer; + end; + identhashdataty = record + header: hashheaderty; + data: identdataty; + end; + pidenthashdataty = ^identhashdataty; + + tidenthashdatalist = class(thashdatalist) + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(const asize: int32); + //total datasize including identheaderty + function adduniquedata(const akey: identty; + out adata: pidenthashdataty): boolean; + //false if duplicate + end; + + tstringidents = class; +// tidenthashdatalist = class; + + indexidentdataty = record + key: identnamety; //index of null terminated string + data: identty; + end; + pindexidentdataty = ^indexidentdataty; + indexidenthashdataty = record + header: hashheaderty; + data: indexidentdataty; + end; + pindexidenthashdataty = ^indexidenthashdataty; + + tindexidenthashdatalist = class(thashdatalist) +// {$ifdef mse_debugparser} + private + fidents: tidenthashdatalist; +// {$endif} + protected + fowner: tstringidents; + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public + constructor create(const aowner: tstringidents); + destructor destroy; override; + procedure clear; override; + function identname(const aident: identty; out aname: lstringty): boolean; + function identname(const aident: identty; out aname: identnamety): boolean; + function getident(const aname: lstringty): pindexidenthashdataty; + end; + + tstringidents = class + protected + fstringident: identty; + fidentlist: tindexidenthashdatalist; + fstringindex,fstringlen: identoffsetty; + fstringdata: pointer; + procedure nextident(); + function storestring(const astr: lstringty): identnamety; + public + constructor create(); + destructor destroy(); override; + function getident(): identty; + function getident(const astart,astop: pchar): identty; + function getident(const aname: lstringty): identty; + function getident(const aname: pchar; const alen: integer): identty; + function getident(const aname: string): identty; + + function getidentname(const aident: identty; out name: identnamety): boolean; + //true if found + function getidentname(const aident: identty; out name: lstringty): boolean; + //true if found + function getidentname(const aname: string): identnamety; + function getidentname(const aident: identty): string; + function getidentnamel(const aident: identty): lstringty; + function getidentnamep(const aident: identty): pchar; +// function getidentnamel(const aeledata: pointer): lstringty; + function getidentname2(const aident: identty): identnamety; +// function getidentname2(const aeledata: pointer): identnamety; + + function nametolstring(const aname: identnamety): lstringty; inline; + + procedure clear(); +// procedure init(); + end; + +implementation +uses + mselfsr; + +const + mindatasize = 1024; + +type + identbufferheaderty = record + len: int32; + end; + identbufferty = record + header: identbufferheaderty; + data: record //null terminated array of char + end; + end; + pidentbufferty = ^identbufferty; + +procedure tstringidents.nextident; +begin + repeat + lfsr321(fstringident); + until fstringident >= firstident; +end; + +function tstringidents.getident(): identty; +begin + result:= fstringident; + nextident; +end; + +function tstringidents.getident(const aname: lstringty): identty; +begin + result:= fidentlist.getident(aname)^.data.data; +end; + +function tstringidents.getident(const aname: pchar; + const alen: integer): identty; +var + lstr1: lstringty; +begin + lstr1.po:= aname; + lstr1.len:= alen; + result:= fidentlist.getident(lstr1)^.data.data; +end; + +function tstringidents.getident(const astart,astop: pchar): identty; +var + lstr1: lstringty; +begin + lstr1.po:= astart; + lstr1.len:= astop-astart; + result:= fidentlist.getident(lstr1)^.data.data; +end; + +function tstringidents.getident(const aname: string): identty; +var + lstr1: lstringty; +begin + lstr1.po:= pointer(aname); + lstr1.len:= length(aname); + result:= fidentlist.getident(lstr1)^.data.data; +end; + +function tstringidents.nametolstring(const aname: identnamety): lstringty; +var + po1: pidentbufferty; +begin + po1:= pointer(fstringdata) + aname.offset; + result.len:= po1^.header.len; + result.po:= @po1^.data; +end; + +function tstringidents.getidentname(const aident: identty; + out name: lstringty): boolean; + //true if found +begin + result:= fidentlist.identname(aident,name); +end; + +function tstringidents.getidentname(const aname: string): identnamety; +begin + result:= fidentlist.getident(stringtolstring(aname))^.data.key; +end; + +function tstringidents.getidentname(const aident: identty; + out name: identnamety): boolean; + //true if found +begin + result:= fidentlist.identname(aident,name); +end; + +function tstringidents.getidentname(const aident: identty): string; +var + lstr1: lstringty; +begin + if getidentname(aident,lstr1) then begin + result:= lstringtostring(lstr1); + end + else begin + result:= '°'; + end; +end; + +function tstringidents.getidentnamel(const aident: identty): lstringty; +begin +{$ifdef mse_checkinternalerror} + if not +{$endif} + getidentname(aident,result) +{$ifdef mse_checkinternalerror} then begin + internalerror(ie_parser,'20151111A'); + end; +{$else} + ; +{$endif} +end; + +(* +function tstringidents.getidentnamel(const aeledata: pointer): lstringty; +begin +{$ifdef mse_checkinternalerror} + if not +{$endif} + getidentname(datatoele(aeledata)^.header.name,result) +{$ifdef mse_checkinternalerror} then begin + internalerror(ie_parser,'20151124A'); + end; +{$else} + ; +{$endif} +end; +*) +function tstringidents.getidentname2(const aident: identty): identnamety; +begin +{$ifdef mse_checkinternalerror} + if not +{$endif} + getidentname(aident,result) +{$ifdef mse_checkinternalerror} then begin + internalerror(ie_parser,'20151111B'); + end; +{$else} + ; +{$endif} +end; + +function tstringidents.getidentnamep(const aident: identty): pchar; +begin + result:= getidentnamel(aident).po; +end; + +(* +function tstringidents.getidentname2(const aeledata: pointer): identnamety; +begin +{$ifdef mse_checkinternalerror} + if not +{$endif} + getidentname(datatoele(aeledata)^.header.name,result) +{$ifdef mse_checkinternalerror} then begin + internalerror(ie_parser,'20151111C'); + end; +{$else} + ; +{$endif} +end; +*) +const + hashmask: array[0..7] of longword = + (%10101010101010100101010101010101, + %01010101010101011010101010101010, + %11001100110011000011001100110011, + %00110011001100111100110011001100, + %01100110011001111001100110011000, + %10011001100110000110011001100111, + %11100110011001100001100110011001, + %00011001100110011110011001100110 + ); + +function hashkey1(const akey: lstringty): hashvaluety; +var + int1: integer; + wo1: word; + by1: byte; + po1: pchar; +begin + result:= 0; + if akey.len > 0 then begin + wo1:= hashmask[0]; + po1:= akey.po; + for int1:= 0 to akey.len-1 do begin + {$ifdef caseinsensitive} + by1:= byte(lowerchars[po1[int1]]); + {$else} + by1:= byte(po1[int1]); + {$endif} + wo1:= ((wo1 + by1) xor by1); + end; + wo1:= (wo1 xor wo1 shl 7); + result:= (wo1 or (longword(wo1) shl 16)) xor hashmask[akey.len and $7]; + end; +end; + +function tstringidents.storestring(const astr: lstringty): identnamety; + //offset from stringdata +var + int1,int2: integer; + po1: pidentbufferty; +begin + int1:= fstringindex; + int2:= astr.len; + fstringindex:= (fstringindex + int2 + 1 + sizeof(identbufferheaderty) + 3) + and not 3; //align 4 + if fstringindex >= fstringlen then begin + fstringlen:= fstringindex*2+mindatasize; + reallocmem(fstringdata,fstringlen); + fillchar((pchar(pointer(fstringdata))+int1)^,fstringlen-int1,0); + //for terminating 0 + end; + po1:= fstringdata + int1; + po1^.header.len:= int2; + move(astr.po^,po1^.data,int2); + result.offset:= int1; + nextident(); +end; + +constructor tstringidents.create(); +begin + fidentlist:= tindexidenthashdatalist.create(self); + clear(); +end; + +destructor tstringidents.destroy(); +begin + clear(); + fidentlist.free(); +end; + +procedure tstringidents.clear(); +begin + fidentlist.clear; + if fstringdata <> nil then begin + freemem(fstringdata); + fstringdata:= nil; + end; + fstringindex:= 0; + fstringlen:= 0; + fstringident:= strid9; + nextident(); +end; +{ +procedure tstringidents.init(); +begin + fstringident:= idstart; //invalid + nextident(); +end; +} +{ tidenthashdatalist } +{ +constructor tidenthashdatalist.create(const asize: int32); +begin + inherited create(asize); +end; +} +function tidenthashdatalist.hashkey(const akey): hashvaluety; +begin + result:= identty(akey); +end; + +function tidenthashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + result:= identty(akey) = pidenthashdataty(aitem)^.data.header.ident; +end; + +function tidenthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(identhashdataty); +end; + +function tidenthashdatalist.adduniquedata(const akey: identty; + out adata: pidenthashdataty): boolean; +begin + adata:= pidenthashdataty(internalfind(akey)); + result:= adata = nil; + if result then begin + adata:= pidenthashdataty(internaladd(akey)); + adata^.data.header.ident:= akey; +// end +// else begin +// inc(adata,sizeof(hashheaderty)); + end; +end; + +{ tindexidenthashdatalist } + +constructor tindexidenthashdatalist.create(const aowner: tstringidents); +begin + fowner:= aowner; + inherited create(); + fidents:= tidenthashdatalist.create(); +end; + +destructor tindexidenthashdatalist.destroy; +begin + inherited; + fidents.free; +end; + +function tindexidenthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(indexidenthashdataty); +end; + +procedure tindexidenthashdatalist.clear; +begin + inherited; + fidents.clear; +end; + +function tindexidenthashdatalist.identname(const aident: identty; + out aname: lstringty): boolean; +var + po1: pidenthashdataty; + po2: pidentbufferty; +begin + po1:= pidenthashdataty(fidents.internalfind(aident,aident)); + if po1 <> nil then begin + result:= true; + po2:= pointer(fowner.fstringdata)+po1^.data.keyname; + aname.len:= po2^.header.len; + aname.po:= @po2^.data; + end + else begin + result:= false; + aname.po:= nil; + aname.len:= 0; + end; +end; + +function tindexidenthashdatalist.identname(const aident: identty; + out aname: identnamety): boolean; +var + po1: pidenthashdataty; +begin + po1:= pidenthashdataty(fidents.internalfind(aident,aident)); + if po1 <> nil then begin + result:= true; + aname.offset:= po1^.data.keyname; + end + else begin + result:= false; + aname.offset:= -1; + end; +end; + +function tindexidenthashdatalist.getident(const aname: lstringty): + pindexidenthashdataty; +var + po1: pindexidenthashdataty; + ha1: hashvaluety; +begin +{ + if aname.len > maxidentlen then begin + errormessage(err_identtoolong,[lstringtostring(aname)]); + result:= nil; + exit; + end; +} + ha1:= hashkey1(aname); + po1:= pointer(internalfind(aname,ha1)); + if po1 = nil then begin + po1:= pointer(internaladdhash(ha1)); + with po1^.data do begin + data:= fowner.fstringident; + key:= fowner.storestring(aname); + with pidenthashdataty(fidents.internaladdhash(data))^.data do begin + header.ident:= data; + keyname:= key.offset; + end; + end; + end; + result:= po1; +// result:= po1^.data.data; +end; + +function tindexidenthashdatalist.hashkey(const akey): hashvaluety; +var + po1,po2: pchar; + wo1: word; + by1: byte; +begin + with indexidentdataty(akey) do begin + po1:= fowner.fstringdata + key.offset + sizeof(identbufferheaderty); + po2:= po1; + wo1:= hashmask[0]; + while true do begin + {$ifdef caseinsensitive} + by1:= byte(lowerchars[po1^]); + {$else} + by1:= byte(po1^); + {$endif} + if by1 = 0 then begin + break; + end; + wo1:= ((wo1 + by1) xor by1); + end; + wo1:= (wo1 xor wo1 shl 7); + result:= (wo1 or (longword(wo1) shl 16)) xor hashmask[(po1-po2) and $7]; + end; +end; + +function tindexidenthashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +var + po1,po2: pchar; + int1: integer; +begin + result:= false; + with lstringty(akey) do begin + po1:= po; + po2:= fowner.fstringdata + pindexidenthashdataty(aitem)^.data.key.offset + + sizeof(identbufferty); + for int1:= 0 to len-1 do begin + {$ifdef caseinsensitive} + if lowerchars[po1[int1]] <> lowerchars[po2[int1]] then begin + {$else} + if po1[int1] <> po2[int1] then begin + {$endif} + exit; + end; + end; + result:= po2[len] = #0; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/container/msesumlist.pas b/mseide-msegui/lib/common/container/msesumlist.pas new file mode 100644 index 0000000..19290f7 --- /dev/null +++ b/mseide-msegui/lib/common/container/msesumlist.pas @@ -0,0 +1,606 @@ +unit msesumlist; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msedatalist,msetypes,msearrayprops,mseclasses,mseglob; + +//todo: optimize!!! + +const +// foldlevelsumname = '#foldlevel'; + sumleveltag = 1; + sumissumtag = 2; + +type + + realsumty = record + data: realintty; + sumup: realty; + sumdown: realty; + issum: boolean; + end; + prealsumty = ^realsumty; + + tsumprop = class(tindexpersistent) + protected + fsum: realty; + fsumindex: integer; + published + end; + psumprop = ^tsumprop; + + optionsumty = (osu_sumsonly,osu_valuesonly, + osu_foldsum{,osu_foldsumdown,osu_folddefaultsum}); + optionssumty = set of optionsumty; + + + tsumarrayprop = class(tindexpersistentarrayprop) + private + protected + function newsum(const alevel: integer; const asum: realty; + const aindex: integer): realty; + public + constructor create(const aowner: tdatalist); reintroduce; + end; + + tsumuparrayprop = class(tsumarrayprop) + end; + + tsumdownarrayprop = class(tsumarrayprop) + end; + + trealsumlist = class(trealintdatalist) + private + fsumsup: tsumuparrayprop; + fsumsdown: tsumdownarrayprop; + fdefaultval: realsumty; + function getsumlevel(index: integer): integer; + procedure setsumlevel(index: integer; const avalue: integer); + function getisfoldsum(index: integer): boolean; + procedure setisfoldsum(index: integer; const avalue: boolean); + procedure setsumsup(const avalue: tsumuparrayprop); + procedure setsumsdown(const avalue: tsumdownarrayprop); + protected + fdirtyup: integer; + fdirtydown: integer; + flinkvalue: listlinkinfoty; + flinklevel: listlinkinfoty; + flinkissum: listlinkinfoty; + foptions: optionssumty; + procedure setoptions(const avalue: optionssumty); virtual; + procedure setsourcevalue(const avalue: string); virtual; + procedure setsourcelevel(const avalue: string); virtual; + procedure setsourceissum(const avalue: string); virtual; + procedure getgriddefaultdata(var dest); override; + procedure getgriddata(index: integer; var dest); override; + procedure setgriddata(index: integer; const source); override; + function getdefault: pointer; override; + function getlinkdatatypes(const atag: integer): listdatatypesty; override; + public + constructor create; override; + destructor destroy; override; + procedure listdestroyed(const sender: tdatalist); override; + procedure clean(const start,stop: integer); override; + procedure change(const index: integer); override; + class function datatype: listdatatypety; override; + procedure sourcechange(const sender: tdatalist; + const index: integer); override; + function getsourcecount: integer; override; + function getsourceinfo(const atag: integer): plistlinkinfoty; override; + procedure linksource(const source: tdatalist; const atag: integer); override; + + procedure clearmemberitem(const subitem: integer; + const index: integer); override; + procedure setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); override; + property sumlevel[index: integer]: integer read getsumlevel + write setsumlevel; + //0 -> no sum > 0 top down, < 0 bottom up, not used for osu_foldsum + property isfoldsum[index: integer]: boolean read getisfoldsum + write setisfoldsum; + //for osu_foldsum only + property sourcevalue: string read flinkvalue.name + write setsourcevalue; + property sourcelevel: string read flinklevel.name + write setsourcelevel; + property sourceissum: string read flinkissum.name + write setsourceissum; + //for osu_foldsum only + published + property sumsup: tsumuparrayprop read fsumsup write setsumsup; + property sumsdown: tsumdownarrayprop read fsumsdown write setsumsdown; + property options: optionssumty read foptions write setoptions + default []; +end; + +implementation +uses + msereal,msebits; + +{ trealsumlist } + +constructor trealsumlist.create; +begin + initsource(flinkvalue); + initsource(flinklevel); + initsource(flinkissum); + inherited; + fsize:= sizeof(realsumty); +{$warnings off} + fsumsup:= tsumuparrayprop.create(self); +{$warnings on} +{$warnings off} + fsumsdown:= tsumdownarrayprop.create(self); +{$warnings on} + fillchar(fdefaultval,sizeof(fdefaultval),0); + fdefaultval.data.rea:= emptyreal; +end; + +destructor trealsumlist.destroy; +begin + removesource(flinkvalue); + removesource(flinklevel); + removesource(flinkissum); + fsumsup.free; + fsumsdown.free; + inherited; +end; + +procedure trealsumlist.listdestroyed(const sender: tdatalist); +begin + inherited; + checklistdestroyed(flinkvalue,sender); + checklistdestroyed(flinklevel,sender); + checklistdestroyed(flinkissum,sender); +end; + +class function trealsumlist.datatype: listdatatypety; +begin + result:= dl_realsum; +end; + +procedure trealsumlist.getgriddefaultdata(var dest); +begin + realty(dest):= emptyreal; +end; + +procedure trealsumlist.getgriddata(index: integer; var dest); +//var +// po1: prealsumty; +begin + clean(index,index); + checkindex(index); + realty(dest):= prealsumty(fdatapo+index*fsize)^.data.rea; +end; + +procedure trealsumlist.setgriddata(index: integer; const source); +var + int1: integer; +begin + int1:= index; + checkindex(index); + with prealsumty(fdatapo+index*fsize)^ do begin + if data.int = 0 then begin + data.rea:= realty(source); + change(int1); + end; + end; +end; + +function trealsumlist.getsumlevel(index: integer): integer; +begin + checkindex(index); + result:= prealsumty(fdatapo+index*fsize)^.data.int; +end; + +procedure trealsumlist.setsumlevel(index: integer; + const avalue: integer); +var + int1: integer; +begin + int1:= index; + checkindex(index); + with prealsumty(fdatapo+index*fsize)^ do begin + if data.int <> avalue then begin + data.int:= avalue; + if not (osu_foldsum in foptions) then begin + if avalue = 0 then begin + if defaultzero then begin + data.rea:= 0; + end + else begin + data.rea:= emptyreal; + end; + end; + sourcechange(flinkvalue.source,int1); //restore value + change(-1); + end; + end; + end; +end; + +function trealsumlist.getisfoldsum(index: integer): boolean; +begin + checkindex(index); + result:= prealsumty(fdatapo+index*fsize)^.issum; +end; + +procedure trealsumlist.setisfoldsum(index: integer; + const avalue: boolean); +var + int1: integer; +begin + int1:= index; + checkindex(index); + with prealsumty(fdatapo+index*fsize)^ do begin + if issum <> avalue then begin + issum:= avalue; + if (osu_foldsum in foptions) then begin + if not avalue then begin + if defaultzero then begin + data.rea:= 0; + end + else begin + data.rea:= emptyreal; + end; + end; + end; + sourcechange(flinklevel.source,int1); //restore sumlevel + sourcechange(flinkvalue.source,int1); //restore value + change(-1); + end; + end; +end; + +procedure copyvalue(const source,dest: pointer); +begin + prealsumty(dest)^.data.rea:= preal(source)^; +end; + +procedure copylevel(const source,dest: pointer); +begin + prealsumty(dest)^.data.int:= pinteger(source)^; +end; + +procedure copylevelrowstate(const source,dest: pointer); +begin + with prowstatety(source)^ do begin + prealsumty(dest)^.issum:= flags and foldissummask <> 0; + if prealsumty(dest)^.issum then begin + prealsumty(dest)^.data.int:= -(fold + 1); + end + else begin + prealsumty(dest)^.data.int:= 0 + end; + end; +end; + +procedure copylevelrowstateissum(const source1,source2,dest: pointer); +begin + with prealsumty(dest)^ do begin + if pinteger(source2)^ <> 0 then begin + data.int:= -(prowstatety(source1)^.fold + 1); + issum:= true; + end + else begin + data.int:= 0; + issum:= false; + end; + end; +end; + +procedure trealsumlist.clean(const start,stop: integer); +var + po1: prealsumty; +// po2: prowstatety; +// po3: pinteger; + int1,int2: integer; + rea1: realty; +begin + checksourcecopy(flinkvalue,@copyvalue); + if flinklevel.source is tcustomrowstatelist then begin + if flinkissum.source <> nil then begin + checksourcecopy2(flinklevel,flinkissum.source,@copylevelrowstateissum); + end + else begin + checksourcecopy(flinklevel,@copylevelrowstate); + end; + end + else begin + checksourcecopy(flinklevel,@copylevel); + end; + if fsumsup.count > 0 then begin + if stop >= fdirtyup then begin + if fdirtyup > 0 then begin + po1:= datapo; + inc(po1,fdirtyup-1); + rea1:= po1^.sumup; + end + else begin + with fsumsup do begin + for int1:= 0 to high(fitems) do begin + with tsumprop(fitems[int1]) do begin + fsum:= emptyreal; + fsumindex:= -1; + end; + end; + end; + rea1:= emptyreal; + end; + po1:= datapo; + inc(po1,fdirtyup); + for int1:= fdirtyup to stop do begin + int2:= po1^.data.int; + if int2 = 0 then begin + rea1:= addrealty(rea1,po1^.data.rea); + end + else begin + if int2 > 0 then begin + if int2 <= high(fsumsup.fitems) then begin + po1^.data.rea:= fsumsup.newsum(int2-1,rea1,int1); + end + else begin + po1^.data.rea:= rea1; + end; + end; + end; + po1^.sumup:= rea1; + inc(po1); + end; + fdirtyup:= stop+1; + end; + end; + if fsumsdown.count > 0 then begin + if start <= fdirtydown then begin + if fdirtydown < count - 1 then begin + po1:= datapo; + inc(po1,fdirtydown+1); + rea1:= po1^.sumdown; + end + else begin + with fsumsdown do begin + for int1:= 0 to high(fitems) do begin + with tsumprop(fitems[int1]) do begin + fsum:= emptyreal; + fsumindex:= maxint; + end; + end; + end; + rea1:= emptyreal; + end; + po1:= datapo; + inc(po1,fdirtydown); + for int1:= fdirtydown downto start do begin + int2:= -po1^.data.int; + if int2 = 0 then begin + rea1:= addrealty(rea1,po1^.data.rea); + end + else begin + if int2 > 0 then begin + if int2 <= high(fsumsdown.fitems) then begin + po1^.data.rea:= fsumsdown.newsum(int2-1,rea1,int1); + end + else begin + po1^.data.rea:= rea1; + end; + end; + end; + po1^.sumdown:= rea1; + dec(po1); + end; + fdirtydown:= start-1; + end; + end; +end; + +procedure trealsumlist.change(const index: integer); +begin + if index < 0 then begin + fdirtyup:= 0; + fdirtydown:= count-1; + end + else begin + with fsumsup do begin + if (fitems <> nil) and + (tsumprop(fitems[high(fitems)]).fsumindex <= index) then begin + fdirtyup:= 0; + end; + end; + with fsumsdown do begin + if (fitems <> nil) and + (tsumprop(fitems[high(fitems)]).fsumindex >= index) then begin + fdirtydown:= self.count-1; + end; + end; + end; + inherited change(-1); //sum invalid +end; + +procedure trealsumlist.setsumsup(const avalue: tsumuparrayprop); +begin + fsumsup.assign(avalue); +end; + +procedure trealsumlist.setsumsdown(const avalue: tsumdownarrayprop); +begin + fsumsdown.assign(avalue); +end; + +function trealsumlist.getdefault: pointer; +begin + if defaultzero then begin + result:= nil; + end + else begin + result:= @fdefaultval; + end; +end; + +procedure trealsumlist.sourcechange(const sender: tdatalist; + const index: integer); +begin + inherited; + if sender <> nil then begin + if sender = flinkvalue.source then begin + checksourcechange(flinkvalue,flinkvalue.source,index); //restore value + change(index); + end + else begin + if (sender = flinkissum.source) then begin + checksourcechange(flinklevel,flinklevel.source,index); //invalid + checksourcechange(flinkvalue,flinkvalue.source,index); //restore value + change(-1); + end + else begin + if checksourcechange(flinklevel,sender,index) then begin + checksourcechange(flinkvalue,flinkvalue.source,index); //restore value + change(-1); + end; + end; + end; + end; +end; + +function trealsumlist.getlinkdatatypes(const atag: integer): listdatatypesty; +begin + result:= inherited getlinkdatatypes(atag); + case atag of + 0: begin + result:= result + [dl_real]; + end; + sumleveltag: begin + if osu_foldsum in foptions then begin + result:= [dl_rowstate]; + end + else begin + result:= [dl_integer]; + end; + end; + sumissumtag: begin + result:= [dl_integer]; + end; + end; +end; + +procedure trealsumlist.setoptions(const avalue: optionssumty); +const + mask1: optionssumty = [osu_sumsonly,osu_valuesonly]; +begin + if foptions <> avalue then begin + foptions:= optionssumty( + setsinglebit({$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask1))); + change(-1); + end; +end; + +procedure trealsumlist.setsourcevalue(const avalue: string); +begin + flinkvalue.name:= avalue; +end; + +procedure trealsumlist.setsourcelevel(const avalue: string); +begin + flinklevel.name:= avalue; +end; + +procedure trealsumlist.setsourceissum(const avalue: string); +begin + flinkissum.name:= avalue; +end; + +procedure trealsumlist.linksource(const source: tdatalist; const atag: integer); +begin + case atag of + 0: begin + internallinksource(source,atag,flinkvalue.source); + end; + sumleveltag: begin + internallinksource(source,atag,flinklevel.source); + end; + sumissumtag: begin + if internallinksource(source,atag,flinkissum.source) and + (flinklevel.source <> nil)then begin + sourcechange(flinklevel.source,-1); //sum level invalid + end; + end; + end; +end; + +function trealsumlist.getsourcecount: integer; +begin + result:= 3; +end; + +function trealsumlist.getsourceinfo(const atag: integer): plistlinkinfoty; +begin + case atag of + 0: begin + result:= @flinkvalue; + end; + sumleveltag: begin + result:= @flinklevel; + end; + sumissumtag: begin + result:= @flinkissum; + end + else begin + result:= nil; + end; + end; +end; + +procedure trealsumlist.clearmemberitem(const subitem: integer; + const index: integer); +begin + if subitem = 1 then begin + if osu_foldsum in foptions then begin + isfoldsum[index]:= false; + end + else begin + sumlevel[index]:= 0; + end; + end; +end; + +procedure trealsumlist.setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); +begin + if subitem = 1 then begin + if osu_foldsum in foptions then begin + isfoldsum[index]:= avalue <> 0; + end + else begin + sumlevel[index]:= avalue; + end; + end; +end; + +{ tsumprop } + +{ tsumarrayprop } + +constructor tsumarrayprop.create(const aowner: tdatalist); +begin + inherited create(aowner,tsumprop); +end; + +function tsumarrayprop.newsum(const alevel: integer; + const asum: realty; const aindex: integer): realty; +var + po1: psumprop; + int1: integer; +begin + po1:= psumprop(@fitems[alevel]); + result:= subrealty(asum,po1^.fsum); + for int1:= alevel to high(fitems) do begin + po1^.fsum:= asum; + po1^.findex:= aindex; + inc(po1); + end; +end; + +initialization + registerdatalistclass(dl_realsum,trealsumlist); +end. diff --git a/mseide-msegui/lib/common/crypto/msecrc.pas b/mseide-msegui/lib/common/crypto/msecrc.pas new file mode 100644 index 0000000..f770a29 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msecrc.pas @@ -0,0 +1,111 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msecrc; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +function crc32(const data: pbyte; const length: integer): longword; overload; +procedure crc32(const data: pbyte; const length: integer; var crc: longword); + + +implementation + +const + crc32table: array[byte] of longword = ( + $00000000,$77073096,$EE0E612C,$990951BA, + $076DC419,$706AF48F,$E963A535,$9E6495A3, + $0EDB8832,$79DCB8A4,$E0D5E91E,$97D2D988, + $09B64C2B,$7EB17CBD,$E7B82D07,$90BF1D91, + $1DB71064,$6AB020F2,$F3B97148,$84BE41DE, + $1ADAD47D,$6DDDE4EB,$F4D4B551,$83D385C7, + $136C9856,$646BA8C0,$FD62F97A,$8A65C9EC, + $14015C4F,$63066CD9,$FA0F3D63,$8D080DF5, + $3B6E20C8,$4C69105E,$D56041E4,$A2677172, + $3C03E4D1,$4B04D447,$D20D85FD,$A50AB56B, + $35B5A8FA,$42B2986C,$DBBBC9D6,$ACBCF940, + $32D86CE3,$45DF5C75,$DCD60DCF,$ABD13D59, + $26D930AC,$51DE003A,$C8D75180,$BFD06116, + $21B4F4B5,$56B3C423,$CFBA9599,$B8BDA50F, + $2802B89E,$5F058808,$C60CD9B2,$B10BE924, + $2F6F7C87,$58684C11,$C1611DAB,$B6662D3D, + $76DC4190,$01DB7106,$98D220BC,$EFD5102A, + $71B18589,$06B6B51F,$9FBFE4A5,$E8B8D433, + $7807C9A2,$0F00F934,$9609A88E,$E10E9818, + $7F6A0DBB,$086D3D2D,$91646C97,$E6635C01, + $6B6B51F4,$1C6C6162,$856530D8,$F262004E, + $6C0695ED,$1B01A57B,$8208F4C1,$F50FC457, + $65B0D9C6,$12B7E950,$8BBEB8EA,$FCB9887C, + $62DD1DDF,$15DA2D49,$8CD37CF3,$FBD44C65, + $4DB26158,$3AB551CE,$A3BC0074,$D4BB30E2, + $4ADFA541,$3DD895D7,$A4D1C46D,$D3D6F4FB, + $4369E96A,$346ED9FC,$AD678846,$DA60B8D0, + $44042D73,$33031DE5,$AA0A4C5F,$DD0D7CC9, + $5005713C,$270241AA,$BE0B1010,$C90C2086, + $5768B525,$206F85B3,$B966D409,$CE61E49F, + $5EDEF90E,$29D9C998,$B0D09822,$C7D7A8B4, + $59B33D17,$2EB40D81,$B7BD5C3B,$C0BA6CAD, + $EDB88320,$9ABFB3B6,$03B6E20C,$74B1D29A, + $EAD54739,$9DD277AF,$04DB2615,$73DC1683, + $E3630B12,$94643B84,$0D6D6A3E,$7A6A5AA8, + $E40ECF0B,$9309FF9D,$0A00AE27,$7D079EB1, + $F00F9344,$8708A3D2,$1E01F268,$6906C2FE, + $F762575D,$806567CB,$196C3671,$6E6B06E7, + $FED41B76,$89D32BE0,$10DA7A5A,$67DD4ACC, + $F9B9DF6F,$8EBEEFF9,$17B7BE43,$60B08ED5, + $D6D6A3E8,$A1D1937E,$38D8C2C4,$4FDFF252, + $D1BB67F1,$A6BC5767,$3FB506DD,$48B2364B, + $D80D2BDA,$AF0A1B4C,$36034AF6,$41047A60, + $DF60EFC3,$A867DF55,$316E8EEF,$4669BE79, + $CB61B38C,$BC66831A,$256FD2A0,$5268E236, + $CC0C7795,$BB0B4703,$220216B9,$5505262F, + $C5BA3BBE,$B2BD0B28,$2BB45A92,$5CB36A04, + $C2D7FFA7,$B5D0CF31,$2CD99E8B,$5BDEAE1D, + $9B64C2B0,$EC63F226,$756AA39C,$026D930A, + $9C0906A9,$EB0E363F,$72076785,$05005713, + $95BF4A82,$E2B87A14,$7BB12BAE,$0CB61B38, + $92D28E9B,$E5D5BE0D,$7CDCEFB7,$0BDBDF21, + $86D3D2D4,$F1D4E242,$68DDB3F8,$1FDA836E, + $81BE16CD,$F6B9265B,$6FB077E1,$18B74777, + $88085AE6,$FF0F6A70,$66063BCA,$11010B5C, + $8F659EFF,$F862AE69,$616BFFD3,$166CCF45, + $A00AE278,$D70DD2EE,$4E048354,$3903B3C2, + $A7672661,$D06016F7,$4969474D,$3E6E77DB, + $AED16A4A,$D9D65ADC,$40DF0B66,$37D83BF0, + $A9BCAE53,$DEBB9EC5,$47B2CF7F,$30B5FFE9, + $BDBDF21C,$CABAC28A,$53B39330,$24B4A3A6, + $BAD03605,$CDD70693,$54DE5729,$23D967BF, + $B3667A2E,$C4614AB8,$5D681B02,$2A6F2B94, + $B40BBE37,$C30C8EA1,$5A05DF1B,$2D02EF8D + ); + +procedure crc32(const data: pbyte; const length: integer; var crc: longword); +var + po1,po2: pbyte; + lwo1: longword; +begin + if length > 0 then begin + lwo1:= not crc; //startvector + po1:= data; + po2:= data+length; + while po1 < po2 do begin + lwo1:= (lwo1 shr 8) xor crc32table[byte(lwo1) xor po1^]; + inc(po1) + end; + crc:= not lwo1; + end; +end; + +function crc32(const data: pbyte; const length: integer): longword; +begin + result:= 0; + crc32(data,length,result); +end; + +end. diff --git a/mseide-msegui/lib/common/crypto/msecryptio.pas b/mseide-msegui/lib/common/crypto/msecryptio.pas new file mode 100644 index 0000000..3e51fce --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msecryptio.pas @@ -0,0 +1,147 @@ +{ MSEgui Copyright (c) 2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msecryptio; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseclasses,sysutils; + +type + + ecryptoio = class(exception) + end; + + tcryptoio = class; + cryptoioclassty = class of tcryptoio; + cryptoiokindty = (cyk_none,cyk_server,cyk_client); + + cryptodataty = array[0..17] of pointer; + cryptoioinfoty = record +// handler: tcryptio; + kind: cryptoiokindty; + classtype: cryptoioclassty; + rxfd: integer; + txfd: integer; + cryptodata: cryptodataty; + end; + pcryptoioinfoty = ^cryptoioinfoty; + + connectionkindty = (cok_server,cok_client); + + tcryptoio = class(tmsecomponent) + protected + class procedure internalunlink(var ainfo: cryptoioinfoty); virtual; + class procedure internalthreadterminate; virtual; + class procedure connect(var ainfo: cryptoioinfoty; + const atimeoutms: integer); virtual; abstract; + class procedure accept(var ainfo: cryptoioinfoty; + const atimeoutms: integer); virtual; abstract; + class function write(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; + const atimeoutms: integer): integer; virtual; abstract; + class function read(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; + const atimeoutms: integer): integer; virtual; abstract; + //atimeoutms < 0 -> nonblocked + public + procedure link(const atxfd,arxfd: integer; + out ainfo: cryptoioinfoty); virtual; + { + class procedure unlink(var ainfo: cryptioinfoty); + class procedure threadterminate(var ainfo: cryptioinfoty); + } + end; + +procedure cryptoconnect(var ainfo: cryptoioinfoty; const atimeoutms: integer); +procedure cryptoaccept(var ainfo: cryptoioinfoty; const atimeoutms: integer); +function cryptowrite(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; +function cryptoread(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; + //atimeoutms < 0 -> nonblocked +procedure cryptounlink(var ainfo: cryptoioinfoty); +procedure cryptothreadterminate(var ainfo: cryptoioinfoty); + +implementation +uses + msesystypes; + +procedure cryptoconnect(var ainfo: cryptoioinfoty; const atimeoutms: integer); +begin + if ainfo.classtype <> nil then begin + ainfo.classtype.connect(ainfo,atimeoutms); + end; +end; + +procedure cryptoaccept(var ainfo: cryptoioinfoty; const atimeoutms: integer); +begin + if ainfo.classtype <> nil then begin + ainfo.classtype.accept(ainfo,atimeoutms); + end; +end; + +function cryptowrite(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; +begin + result:= 0; + if ainfo.classtype <> nil then begin + result:= ainfo.classtype.write(ainfo,buffer,count,atimeoutms); + end; +end; + +function cryptoread(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; +begin + result:= 0; + if ainfo.classtype <> nil then begin + result:= ainfo.classtype.read(ainfo,buffer,count,atimeoutms); + end; +end; + +procedure cryptounlink(var ainfo: cryptoioinfoty); +begin + if ainfo.classtype <> nil then begin + ainfo.classtype.internalunlink(ainfo); + end; +end; + +procedure cryptothreadterminate(var ainfo: cryptoioinfoty); +begin + if ainfo.classtype <> nil then begin + ainfo.classtype.internalthreadterminate; + end; +end; + +{ tcryptoio } + +class procedure tcryptoio.internalunlink(var ainfo: cryptoioinfoty); +begin + with ainfo do begin +// handler:= nil; + classtype:= nil; + txfd:= invalidfilehandle; + rxfd:= invalidfilehandle; + end; +end; + +class procedure tcryptoio.internalthreadterminate; +begin + //dummy +end; + +procedure tcryptoio.link(const atxfd,arxfd: integer; + out ainfo: cryptoioinfoty); +begin +// ainfo.handler:= self; + ainfo.classtype:= cryptoioclassty(classtype); + ainfo.rxfd:= arxfd; + ainfo.txfd:= atxfd; +end; +end. diff --git a/mseide-msegui/lib/common/crypto/msecryptohandler.pas b/mseide-msegui/lib/common/crypto/msecryptohandler.pas new file mode 100644 index 0000000..313a73e --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msecryptohandler.pas @@ -0,0 +1,930 @@ +{ MSEgui Copyright (c) 2012-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msecryptohandler; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +uses + msestream,classes,mclasses,sysutils,msetypes{msestrings},mseformatstr,mseglob; + +type + cryptoerrorty = (cerr_error,cerr_ciphernotfound,cerr_notseekable, + cerr_cipherinit,cerr_invalidopenmode,cerr_digestnotfound, + cerr_cannotwrite,cerr_invalidblocksize, + cerr_invalidkeylength,cerr_invaliddatalength, + cerr_readheader,cerr_writeheader,cerr_nobio, + cerr_nopubkey,cerr_encrypt,cerr_norsakey, + cerr_noprivkey,cerr_decrypt,cerr_nokey, + cerr_cannotrestart,cerr_notactive,cerr_wrongdatadirection); + + ecryptohandler = class(exception) + end; + + tbasecryptohandler = class(tcustomcryptohandler) + protected + procedure error(const err: cryptoerrorty); + procedure checkerror(const err: cryptoerrorty = cerr_error); virtual; + function checknullerror(const avalue: integer; + const err: cryptoerrorty = cerr_error): integer; + {$ifdef FPC} inline;{$endif} + function checknilerror(const avalue: pointer; + const err: cryptoerrorty = cerr_error): pointer; + {$ifdef FPC} inline;{$endif} + end; + + tdummycryptohandler = class(tbasecryptohandler) + end; + + sslhandlerstatety = (sslhs_hasfirstblock,sslhs_eofflag,sslhs_finalized, + sslhs_fileeof); + sslhandlerstatesty = set of sslhandlerstatety; + + padbufty = array[0..0] of byte; //variable + + paddedhandlerdatadty = record + mode: integer; + headersize: integer; + blocksize: integer; //-1 -> variable + bufsize: integer; + padindex: integer; + padcount: integer; + seekoffset: integer; + padbuf: ^padbufty; + blockbuf: pbyte; + state: sslhandlerstatesty; + end; + ppaddedhandlerdatadty = ^paddedhandlerdatadty; + {$if sizeof(paddedhandlerdatadty) > sizeof(cryptohandlerdataty)} + {$error 'buffer overflow'} + {$ifend} + paddedhandlerdataty = record + case integer of + 0: (d: paddedhandlerdatadty;); + 1: (_bufferspace: cryptohandlerdataty;); + end; + + tpaddedcryptohandler = class(tbasecryptohandler) + private + protected + procedure cipherupdate(var aclient: cryptoclientinfoty; + const source: pbyte; const sourcelen: integer; + const dest: pbyte; out destlen: integer); virtual; abstract; + procedure cipherfinal(var aclient: cryptoclientinfoty; + const dest: pbyte; out destlen: integer); virtual; abstract; + function calcwritebuffersize(var aclient: cryptoclientinfoty; + const acount: integer): integer; virtual; + function readdata(var aclient: cryptoclientinfoty; var buffer; + const acount: integer): integer; virtual; + //for variable block size + + function read(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; override; + function write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; override; + function seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; override; + function internalread(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; + function internalwrite(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; + function internalseek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; + function getsize(var aclient: cryptoclientinfoty): int64; override; + procedure restartcipher(var aclient: cryptoclientinfoty); virtual; + procedure open(var aclient: cryptoclientinfoty); override; + procedure close(var aclient: cryptoclientinfoty); override; + procedure initializedata(var aclient: cryptoclientinfoty); virtual; + procedure finalizedata(var aclient: cryptoclientinfoty); virtual; + function padbufsize: integer; virtual; + end; + + base64handlerdatadty = record + p: paddedhandlerdatadty; + linestep: integer; + buf: array[0..2] of byte; + bufindex: integer; + lineindex: integer; + readbuffer: pbyte; + readindex: integer; + readbuffersize: integer; + readbufferlength: integer; + end; + pbase64handlerdatadty = ^base64handlerdatadty; + {$if sizeof(base64handlerdatadty) > sizeof(cryptohandlerdataty)} + {$error 'buffer overflow'} + {$ifend} + base64handlerdataty = record + case integer of + 0: (d: base64handlerdatadty;); + 1: (_bufferspace: cryptohandlerdataty;); + end; + + tbase64handler = class(tpaddedcryptohandler) + private + fmaxlinelength: integer; + protected + procedure initpointers(var aclient: cryptoclientinfoty); + function padbufsize: integer; override; + procedure cipherupdate(var aclient: cryptoclientinfoty; + const source: pbyte; const sourcelen: integer; + const dest: pbyte; out destlen: integer); override; + procedure cipherfinal(var aclient: cryptoclientinfoty; + const dest: pbyte; out destlen: integer); override; + function readdata(var aclient: cryptoclientinfoty; var buffer; + const acount: integer): integer; override; + function calcwritebuffersize(var aclient: cryptoclientinfoty; + const acount: integer): integer; override; + procedure initializedata(var aclient: cryptoclientinfoty); override; + procedure finalizedata(var aclient: cryptoclientinfoty); override; + procedure restartcipher(var aclient: cryptoclientinfoty); override; + public + constructor create(aowner: tcomponent); override; + published + property maxlinelength: integer read fmaxlinelength write fmaxlinelength + default defaultbase64linelength; + end; + +const + cryptoerrormessages: array[cryptoerrorty] of msestring =( + 'OpenSSL error.', + 'Cipher not found.', + 'Stream not seekable.', + 'Can not cipher init.', + 'Invalid open mode.', + 'Digest not found.', + 'Can not write.', + 'Invalid block size.', + 'Invalid key length.', + 'Invalid data length.', + 'Can not read header.', + 'Can not write header.', + 'Can not create BIO.', + 'No public key.', + 'Can not encrypt.', + 'No RSA key.', + 'No private key.', + 'Can not decrypt.', + 'No key.', + 'Can not restart.', + 'Not active.', + 'Wrong data direction.' + ); + +implementation +uses + msebits,msesystypes,msesys; + +{ tbasecryptohandler } + +procedure tbasecryptohandler.checkerror(const err: cryptoerrorty); +begin + //dummy +end; + +function tbasecryptohandler.checknullerror(const avalue: integer; + const err: cryptoerrorty): integer; +begin + result:= avalue; + if avalue = 0 then begin + error(err); + end; +end; + +function tbasecryptohandler.checknilerror(const avalue: pointer; + const err: cryptoerrorty): pointer; +begin + result:= avalue; + if avalue = nil then begin + error(err); + end; +end; + +procedure tbasecryptohandler.error(const err: cryptoerrorty); +begin + checkerror(err); + raise ecryptohandler.create(ansistring(cryptoerrormessages[err])); + //there was no queued error +end; + +{ tpaddedcryptohandler } + +function tpaddedcryptohandler.read(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; +var + ps,pd: pbyte; +// blocksize: integer; + + procedure checkpadding; + var + int1,int2: integer; + begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + int2:= padcount - padindex; + if int2 > 0 then begin + int1:= count; + if int1 > int2 then begin + int1:= int2; + end; + move(padbuf^[padindex],pd^,int1); + padindex:= padindex + int1; + result:= result + int1; + count:= count - int1; + seekoffset:= seekoffset + int1; + inc(pd,int1); + end; + end; + end; //checkpadding + +var + int1,int2,int3,int4: integer; + pb,po1: pbyte; + +begin + if count > 0 then begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + pd:= @buffer; + result:= 0; + if blocksize <> 1 then begin + checkpadding; + end; + if count > 0 then begin + int1:= count; + if blocksize > 1 then begin + if sslhs_eofflag in state then begin + exit; + end; + int1:= ((count+blocksize-1) div blocksize) * blocksize; //whole blocks + if not (sslhs_hasfirstblock in state) then begin + int1:= int1+blocksize; + include(state,sslhs_hasfirstblock); + end; + getmem(po1,int1); + ps:= po1; + try + int2:= inherited read(aclient,(ps)^,int1); + updatebit1({$ifdef FPC}longword{$else}byte{$endif}(state), + ord(sslhs_eofflag),int2 < int1); + seekoffset:= seekoffset + ((count div blocksize) * blocksize - int2); + //set to zero later if eofflag + pb:= pointer(padbuf); + padindex:= 0; + padcount:= 0; + int4:= (int2 div blocksize - 1) * blocksize; + if int4 > count then begin + int4:= (count div blocksize) * blocksize; + end; + if int4 > 0 then begin + cipherupdate(aclient,ps,int4,pd,int3); +// checknullerror(evp_cipherupdate(ctx,pointer(pd),int3,pointer(ps),int4)); + inc(result,int3); + inc(pd,int3); + dec(count,int3); + inc(ps,int4); + end + else begin + int4:= 0; + end; + int4:= int2-int4; + if int4 > 0 then begin + cipherupdate(aclient,ps,int4,pb,padcount); +// checknullerror(evp_cipherupdate(ctx,pointer(pb),padcount, +// pointer(ps),int4)); + inc(pb,padcount); + end; + if sslhs_eofflag in state then begin + cipherfinal(aclient,pb,int3); +// checknullerror(evp_cipherfinal(ctx,pointer(pb),int3)); + include(state,sslhs_finalized); + padcount:= padcount + int3; + end; + checkpadding; + if sslhs_eofflag in state then begin + seekoffset:= 0; + end; + finally + freemem(po1); + end; + end + else begin + if blocksize < 0 then begin //variable + result:= result + readdata(aclient,pd^,int1); + end + else begin + getmem(ps,int1); + try + int2:= inherited read(aclient,ps^,int1); + if int2 > 0 then begin + cipherupdate(aclient,ps,int2,@buffer,result); + // checknullerror(evp_cipherupdate(ctx,@buffer,result,pointer(ps),int2)); + end; + finally + freemem(ps); + end; + end; + end; + end; + end; + end + else begin + result:= inherited read(aclient,buffer,count); + end; +end; + +function tpaddedcryptohandler.calcwritebuffersize( + var aclient: cryptoclientinfoty; const acount: integer): integer; +begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + result:= acount + blocksize; + end; +end; + +function tpaddedcryptohandler.write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; +var + po1: pointer; + int1: integer; +begin + if count > 0 then begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + getmem(po1,calcwritebuffersize(aclient,count)); + try + cipherupdate(aclient,@buffer,count,po1,int1); + if int1 > 0 then begin + result:= inherited write(aclient,po1^,int1); + if result = int1 then begin + result:= count; + seekoffset:= seekoffset + count - int1; + end + else begin + error(cerr_cannotwrite); + end; + end + else begin + result:= count; + seekoffset:= seekoffset + count; + end; + finally + freemem(po1); + end; + end; + end + else begin + result:= inherited write(aclient,buffer,count); + end; +end; + +function tpaddedcryptohandler.seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; +begin + if (offset <> 0) or (origin = soend) then begin + result:= 0; //compiler warning + error(cerr_notseekable); + end + else begin + result:= internalseek(aclient,offset,origin); + with paddedhandlerdataty(aclient.handlerdata).d do begin + case origin of + socurrent: begin + result:= result + seekoffset; + end; + sobeginning: begin + restartcipher(aclient); + end; + soend: begin + error(cerr_notseekable); + end; + end; + end; + end; +end; + +function tpaddedcryptohandler.getsize(var aclient: cryptoclientinfoty): int64; +var + lint1: int64; +begin + with aclient do begin + if stream.handle <> invalidfilehandle then begin + lint1:= fileseek(stream.handle,int64(0),ord(socurrent)); + result:= fileseek(stream.handle,int64(0),ord(soend)); + fileseek(stream.handle,lint1,ord(sobeginning)); + end + else begin + result:= inherited getsize(aclient); + end; + end; +end; + +function tpaddedcryptohandler.internalseek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; +begin + result:= inherited seek(aclient,offset,origin); +end; + +function tpaddedcryptohandler.internalread(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; +begin + result:= inherited read(aclient,buffer,count); +end; + +function tpaddedcryptohandler.internalwrite(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; +begin + result:= inherited write(aclient,buffer,count); +end; + +procedure tpaddedcryptohandler.restartcipher( + var aclient: cryptoclientinfoty); +var + int1: integer; +begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + if not (sslhs_finalized in state) and + (aclient.stream.openmode in [fm_write,fm_create])then begin + cipherfinal(aclient,blockbuf,int1); +// checknullerror(evp_cipherfinal(ctx,@buffer,int1)); + if int1 > 0 then begin + if inherited write(aclient,blockbuf^,int1) <> int1 then begin + error(cerr_cannotwrite); + end; + end; + end; +// checknullerror(evp_cipherinit_ex(ctx,nil,nil,pointer(keybuf), +// pointer(ivbuf),mode),cerr_cipherinit); +// ctx^.iv:= ctx^.iov; + padindex:= 0; + padcount:= 0; + seekoffset:= 0; + state:= []; + if headersize > 0 then begin + internalseek(aclient,int64(headersize),sobeginning); + end; + end; +end; + +procedure tpaddedcryptohandler.open(var aclient: cryptoclientinfoty); +//var +// int1: integer; +begin + inherited; + with paddedhandlerdataty(aclient.handlerdata).d do begin + case aclient.stream.openmode of + fm_read: begin + mode:= 0; //decrypt + end; + fm_create,fm_write: begin + mode:= 1; //encrypt + end; + else begin + error(cerr_invalidopenmode); //todo: allow append + end; + end; + state:= []; + padcount:= 0; + padindex:= 0; + initializedata(aclient); + end; +end; + +procedure tpaddedcryptohandler.close(var aclient: cryptoclientinfoty); +var + int1: integer; +begin + try + with paddedhandlerdataty(aclient.handlerdata).d do begin + if (aclient.stream.openmode in [fm_write,fm_create]) {and + (cipher <> nil)} then begin + if not (sslhs_finalized in state) then begin + cipherfinal(aclient,blockbuf,int1); + include(state,sslhs_finalized); + if int1 > 0 then begin + if inherited write(aclient,blockbuf^,int1) <> int1 then begin + error(cerr_cannotwrite); + end; + end; + end; + end; + end; + finally + finalizedata(aclient); + inherited; + end; +end; + +procedure tpaddedcryptohandler.initializedata(var aclient: cryptoclientinfoty); +begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + bufsize:= padbufsize; + getmem(padbuf,bufsize); + getmem(blockbuf,bufsize); + end; +end; + +procedure tpaddedcryptohandler.finalizedata(var aclient: cryptoclientinfoty); +begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + if padbuf <> nil then begin + fillchar(padbuf^,bufsize,0); + freemem(padbuf); + end; + if blockbuf <> nil then begin + fillchar(blockbuf^,bufsize,0); + freemem(blockbuf); + end; + end; +end; + +function tpaddedcryptohandler.padbufsize: integer; +begin + result:= 1; //dummy +end; + +function tpaddedcryptohandler.readdata(var aclient: cryptoclientinfoty; + var buffer; const acount: integer): integer; +begin + result:= inherited read(aclient,buffer,acount); +end; + +{ tbase64handler } + +constructor tbase64handler.create(aowner: tcomponent); +begin + fmaxlinelength:= defaultbase64linelength; + inherited; +end; + +function tbase64handler.padbufsize: integer; +begin + result:= 6; //4+return linefeed +end; + +type + putinfoty = record + pb: pbyte; + pc: pchar; + pline: pchar; + linest: integer; + end; + +procedure putgroup(var info: putinfoty); +var + by1: byte; +begin + with info do begin + if pc >= pline then begin + pc^:= c_return; + inc(pc); + pc^:= c_linefeed; + inc(pc); + pline:= pc+linest; + end; + by1:= pb^; //s0 + pc^:= base64encoding[by1 shr 2]; //d0 + inc(pb); //s1 + inc(pc); //d1 + pc^:= base64encoding[((by1 shl 4) or (pb^ shr 4)) and base64mask]; + by1:= pb^ shl 2; + inc(pb); //s2 + inc(pc); //d2 + pc^:= base64encoding[(by1 or (pb^ shr 6)) and base64mask]; + inc(pc); //d3 + pc^:= base64encoding[pb^ and base64mask]; + inc(pb); + inc(pc); //d0 + end; +end; + +procedure tbase64handler.cipherupdate(var aclient: cryptoclientinfoty; + const source: pbyte; const sourcelen: integer; const dest: pbyte; + out destlen: integer); +var + po1: pbyte; + pbend: pbyte; + info: putinfoty; + int1: integer; + scount: integer; + +begin + with base64handlerdataty(aclient.handlerdata).d,info do begin + destlen:= 0; + if p.mode <> 0 then begin + linest:= linestep; + pb:= source; + scount:= sourcelen; + while bufindex < 3 do begin + buf[bufindex]:= pb^; + inc(pb); + inc(bufindex); + dec(scount); + if scount = 0 then begin + break; + end; + end; + if bufindex < 3 then begin + exit; + end; + bufindex:= 0; + pc:= pointer(dest); + if linestep > 0 then begin + pline:= pc + linestep - lineindex; + end + else begin + pline:= pointer(ptrint(-1)); + end; + po1:= pb; + pb:= @buf; + putgroup(info); + pb:= po1; + + bufindex:= scount mod 3; //tail + pbend:= pbyte(pchar(source) + sourcelen - bufindex); + while pchar(pb) < pchar(pbend) do begin + putgroup(info); + end; + destlen:= pc - pointer(dest); + for int1:= 0 to bufindex - 1 do begin //store tail + buf[int1]:= pb^; + inc(pb); + end; + if linestep > 0 then begin + lineindex:= pc - pline + linestep; + end; + end; + end; +end; + +procedure tbase64handler.cipherfinal(var aclient: cryptoclientinfoty; + const dest: pbyte; out destlen: integer); +var + pb: pbyte; + pc: pchar; + by1: byte; +begin + with base64handlerdataty(aclient.handlerdata).d do begin + destlen:= 0; + if p.mode <> 0 then begin + if bufindex > 0 then begin + pc:= pointer(dest); + if (linestep > 0) and (lineindex >= linestep) then begin + pc^:= c_return; + inc(pc); + pc^:= c_linefeed; + inc(pc); + end; + pb:= @buf; + by1:= pb^; //s0 + pc^:= base64encoding[by1 shr 2]; //d0 + inc(pc); //d1 + pc^:= base64encoding[(by1 shl 4) and base64mask]; + if bufindex > 1 then begin + inc(pb); //s1 + pc^:= base64encoding[((by1 shl 4) or (pb^ shr 4)) and base64mask]; + inc(pc); //d2 + pc^:= base64encoding[(pb^ shl 2) and base64mask]; + end + else begin + inc(pc); //d2 + pc^:= '='; + end; + inc(pc); //d3 + pc^:= '='; + destlen:= pc-pointer(dest)+1; + end; + end; + end; +end; + +function tbase64handler.calcwritebuffersize(var aclient: cryptoclientinfoty; + const acount: integer): integer; +begin + with base64handlerdataty(aclient.handlerdata).d do begin + result:= ((acount+2) div 3)*4; + if linestep > 0 then begin + result:= result + 2*(result div linestep + 1); //return-linefeed, max + end; + end; +end; + +procedure tbase64handler.initpointers(var aclient: cryptoclientinfoty); +begin + with base64handlerdataty(aclient.handlerdata).d do begin + bufindex:= 0; + lineindex:= 0; + if readbuffer <> nil then begin + freemem(readbuffer); + readbuffer:= nil; + end; + readindex:= 0; + readbufferlength:= 0; + readbuffersize:= 0; + end; +end; + +procedure tbase64handler.initializedata(var aclient: cryptoclientinfoty); +begin + inherited; + initpointers(aclient); + with base64handlerdataty(aclient.handlerdata).d do begin + p.blocksize:= -1; //variable + linestep:= 0; + if fmaxlinelength > 0 then begin + linestep:= fmaxlinelength and $fffffffc; //do not cut 4 char boundary + if fmaxlinelength > 0 then begin + if linestep = 0 then begin + linestep:= 4; + end; + end; + end; + end; +end; + +procedure tbase64handler.restartcipher(var aclient: cryptoclientinfoty); +begin + inherited; + initpointers(aclient); +end; + +{$optimization off} //internal compiler error 200409241 + +function tbase64handler.readdata(var aclient: cryptoclientinfoty; var buffer; + const acount: integer): integer; +var + ps: pbyte; + psend: pbyte; + pd: pbyte; + pdend: pbyte; + psgroup,pdgroup: pbyte; + + function decode: boolean; //true by data end + var + by1: byte; + begin + result:= true; + while (pchar(ps) < pchar(psend)) and (pchar(pd) < pchar(pdend)) do begin + psgroup:= ps; + pdgroup:= pd; + by1:= base64decoding[ord(ps^)]; //s0 + while shortint(by1) < 0 do begin + inc(ps); + if (pchar(ps) >= pchar(psend)) or (char(by1) = '=') then begin + exit; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= by1 shl 2; //d0 + inc(ps); + by1:= base64decoding[ord(ps^)]; //s1 + while shortint(by1) < 0 do begin + inc(ps); + if (pchar(ps) >= pchar(psend)) or (char(by1) = '=') then begin + exit; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or (by1 shr 4); + inc(pd); //d1 + pd^:= by1 shl 4; + inc(ps); + by1:= base64decoding[ord(ps^)]; //s2 + while shortint(by1) < 0 do begin + inc(ps); + if (pchar(ps) >= pchar(psend)) or (char(by1) = '=') then begin + exit; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or by1 shr 2; + inc(pd); //d2 + pd^:= by1 shl 6; + inc(ps); + by1:= base64decoding[ord(ps^)]; //s3 + while shortint(by1) < 0 do begin + inc(ps); + if (pchar(ps) >= pchar(psend)) or (char(by1) = '=') then begin + exit; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or by1; + inc(pd); + inc(ps); //s0 + end; + if pd = pdend then begin + result:= false; + end; + end; + + procedure fillbuffer(const aoffset: integer); + begin + with base64handlerdataty(aclient.handlerdata).d do begin + readbufferlength:= aoffset + + inherited readdata(aclient,(pchar(readbuffer)+aoffset)^, + readbuffersize-aoffset); + if readbufferlength < readbuffersize then begin + include(p.state,sslhs_fileeof); + end; + psend:= pbyte(pchar(readbuffer) + readbufferlength); + end; + end; + + procedure getdata; + var + int1: integer; + newbufsize: integer; + po1: pointer; + begin + with base64handlerdataty(aclient.handlerdata).d do begin + newbufsize:= 2*acount+256; + if readbuffer = nil then begin + readbuffersize:= newbufsize; + getmem(readbuffer,readbuffersize); + readindex:= 0; + fillbuffer(0); + end; + ps:= pbyte(pchar(readbuffer) + readindex); + psend:= pbyte(pchar(readbuffer) + readbufferlength); + while true do begin + if decode then begin + if (pchar(ps) >= pchar(psend)) and (pchar(pd) < pchar(pdend)) then begin + //text end, try to get more + if (sslhs_fileeof in p.state) or ((pchar(ps)-1)^ = '=') then begin + include(p.state,sslhs_eofflag); + break; + end; + int1:= pchar(ps)-pchar(psgroup); + if newbufsize > readbuffersize then begin //need a bigger buffer + po1:= readbuffer; + getmem(readbuffer,readbuffersize); + move(psgroup^,readbuffer^,int1); + freemem(po1); + end + else begin + move(psgroup^,readbuffer^,int1); + end; + readindex:= 0; + fillbuffer(int1); + pd:= pdgroup; + ps:= readbuffer; + continue; + end; + end + else begin + break; + end; + end; + readindex:= pchar(ps) - pchar(readbuffer); + end; + end; + +var + int1: integer; +// by1: byte; + tail: integer; + po1: pbyte; + +begin + with base64handlerdataty(aclient.handlerdata).d do begin + result:= 0; + pd:= @buffer; + tail:= acount mod 3; + if (acount > tail) then begin + pdend:= pbyte(pchar(pd) + acount - tail); + getdata; + result:= pchar(pd) - @buffer; + end; + if not (sslhs_eofflag in p.state) then begin + po1:= pd; + pd:= pointer(p.padbuf); + pdend:= pbyte(pchar(pd) + 3); + getdata; + p.padcount:= pchar(pd) - pchar(pointer(p.padbuf)); + if tail > 0 then begin + int1:= tail; + if int1 > p.padcount then begin + int1:= p.padcount; + end; + move(p.padbuf^,po1^,int1); + result:= result + int1; + p.padindex:= int1; + end; + end; + if pchar(ps) >= pchar(psend) then begin + freemem(readbuffer); + readbuffer:= nil; + readbufferlength:= 0; + end; + end; +end; + +procedure tbase64handler.finalizedata(var aclient: cryptoclientinfoty); +begin + initpointers(aclient); + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/crypto/msecryptstream.pas b/mseide-msegui/lib/common/crypto/msecryptstream.pas new file mode 100644 index 0000000..e865b1d --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msecryptstream.pas @@ -0,0 +1,21 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msecryptstream; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msecryptio; + +type + tblockcipher = class(tcryptio) + end; + +implementation +end. diff --git a/mseide-msegui/lib/common/crypto/mseopenssl.pas b/mseide-msegui/lib/common/crypto/mseopenssl.pas new file mode 100644 index 0000000..4792b5b --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopenssl.pas @@ -0,0 +1,529 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopenssl; +{$ifdef FPC} +{$MODE OBJFPC}{$H+} +{$endif} +interface + +uses + msedynload,msetypes{msestrings},msectypes; +const +{$ifdef mswindows} + openssllib: array[0..1] of filenamety = ('libssl32.dll','ssleay32.dll'); + opensslutillib: array[0..0] of filenamety = ('libeay32.dll'); +{$else} + openssllib: array[0..4] of filenamety = ( + 'libssl.so.1.0.0','libssl.so.0.9.8','libssl.so.0.9.7','libssl.so.0.9.6', + 'libssl.so'); + opensslutillib: array[0..4] of filenamety = ( + 'libcrypto.so.1.0.0','libcrypto.so.0.9.8','libcrypto.so.0.9.7', + 'libcrypto.so.0.9.6','libcrypto.so'); +{$endif} + +const + SHA_DIGEST_LENGTH = 20; + BN_CTX_NUM = 16; + BN_CTX_NUM_POS = 12; + + SSL_CTRL_OPTIONS = 32; // ssl/ssl.h + CRYPTO_LOCK = 1; // ssl/crypto.h + CRYPTO_UNLOCK = 2; + CRYPTO_READ = 4; + CRYPTO_WRITE = 8; + + EVP_MAX_MD_SIZE = 16 + 20; + + SSL_ERROR_NONE = 0; + SSL_ERROR_SSL = 1; + SSL_ERROR_WANT_READ = 2; + SSL_ERROR_WANT_WRITE = 3; + SSL_ERROR_WANT_X509_LOOKUP = 4; + SSL_ERROR_SYSCALL = 5; //look at error stack/return value/errno + SSL_ERROR_ZERO_RETURN = 6; + SSL_ERROR_WANT_CONNECT = 7; + SSL_ERROR_WANT_ACCEPT = 8; + + SSL_OP_NO_SSLv2 = $01000000; + SSL_OP_NO_SSLv3 = $02000000; + SSL_OP_NO_TLSv1 = $04000000; + SSL_OP_ALL = $000FFFFF; + SSL_VERIFY_NONE = $00; + SSL_VERIFY_PEER = $01; + + OPENSSL_DES_DECRYPT = 0; + OPENSSL_DES_ENCRYPT = 1; + + SSL_FILETYPE_ASN1 = 2; + SSL_FILETYPE_PEM = 1; + EVP_PKEY_RSA = 6; + +type + sslsize_t = culong; + SslPtr = Pointer; + pSslPtr = ^SslPtr; + pSSL_CTX = SslPtr; + pSSL = SslPtr; + pSSL_METHOD = SslPtr; + pBIO_METHOD = SslPtr; + pBIO = SslPtr; + pX509 = SslPtr; + ppX509 = ^pX509; + pX509_NAME = SslPtr; + pEVP_MD = SslPtr; +// PInteger = ^Integer; +// EVP_PKEY = SslPtr; + pEVP_CIPHER = SslPtr; + pEVP_PKEY = SslPtr; + ppEVP_PKEY = ^pEVP_PKEY; + pX509_REQ = SslPtr; + ppX509_REQ = ^pX509_REQ; + pX509_CRL = SslPtr; + ppX509_CRL = pX509_CRL; + pPKCS7 = SslPtr; + pASN1_cint = SslPtr; + pSTACK_OFX509 = SslPtr; + pX509_SIG = SslPtr; + pBIGNUM = SslPtr; + pBN_MONT_CTX = SslPtr; + pBN_BLINDING = SslPtr; + pRSA = SslPtr; + ppRSA = ^pRSA; + pDSA = SslPtr; + ppDSA = ^pDSA; + pASN1_UTCTIME = SslPtr; + pASN1_INTEGER = SslPtr; + pASN1_ENUMERATED = SslPtr; + pASN1_OCTET_STRING = SslPtr; + pPasswdCb = SslPtr; + pDH = SslPtr; + pBUF_MEM = SslPtr; + pEC_KEY = SslPtr; + pSTACK = SslPtr; + pPKCS7_SIGNER_INFO = SslPtr; + pAES_KEY = SslPtr; + pENGINE = SslPtr; + pRAND_METHOD = SslPtr; + + pFunction = procedure; cdecl; + pCharacter = PChar; + + CRYPTO_EX_DATA = record + sk: pointer; + dummy: cint; + end; + + TProgressCallbackFunction = procedure(status: cint; progress: cint; + data: pointer); + + // Password ask callback for I/O function prototipe + // It must fill buffer with password and return password length + TPWCallbackFunction = function(buffer: pcuchar; length: cint; + verify: cint; data: pointer): cint; cdecl; + + +var + SSL_new: function(ctx: PSSL_CTX):PSSL; cdecl; + SSL_free: procedure(ssl: PSSL); cdecl; + SSL_ctrl: function(ssl: PSSL; cmd: cint; larg: cint; + parg: pointer): cint; cdecl; + SSL_get_error: function(s: PSSL; ret_code: cint):cint; cdecl; + SSL_library_init: function():cint; cdecl; + SSL_load_error_strings: procedure; cdecl; + SSL_set_cipher_list: function(arg0: PSSL_CTX; str: PChar):cint; cdecl; + + SSL_CTX_set_cipher_list: function(arg0: PSSL_CTX; str: PChar):cint; cdecl; +// SSL_CTX_set_cipher_list: function(arg0: PSSL_CTX; +// var str: String):cint; cdecl; + SSL_CTX_new: function(meth: PSSL_METHOD):PSSL_CTX; cdecl; + SSL_CTX_free: procedure(arg0: PSSL_CTX); cdecl; + SSL_CTX_use_PrivateKey: function(ctx: PSSL_CTX; pkey: SslPtr):cint; cdecl; + SSL_CTX_use_PrivateKey_ASN1: function(pk: cint; ctx: PSSL_CTX; d: pbyte; + len: cint):cint; cdecl; + SSL_CTX_use_PrivateKey_file: function(ctx: PSSL_CTX; _file: PChar; + _type: cint):cint; cdecl; +// SSL_CTX_use_PrivateKey_file: function(ctx: PSSL_CTX; +// const _file: String; _type: cint):cint; cdecl; + SSL_CTX_use_RSAPrivateKey_file: function(ctx: PSSL_CTX; _file: pchar; + _type: cint):cint; cdecl; + SSL_CTX_use_certificate: function(ctx: PSSL_CTX; x: SslPtr):cint; cdecl; + SSL_CTX_use_certificate_ASN1: function(ctx: PSSL_CTX; len: cint; + d: pbyte):cint; cdecl; + SSL_CTX_use_certificate_file: function(ctx: PSSL_CTX; + _file: pchar; _type: cint):cint; cdecl; + SSL_CTX_use_certificate_chain_file: function(ctx: PSSL_CTX; + _file: PChar):cint; cdecl; +// SSL_CTX_use_certificate_chain_file: function(ctx: PSSL_CTX; +// const _file: String):cint; cdecl; + SSL_CTX_check_private_key: function(ctx: PSSL_CTX):cint; cdecl; + SSL_CTX_set_default_passwd_cb: procedure(ctx: PSSL_CTX; cb: PPasswdCb); cdecl; + SSL_CTX_set_default_passwd_cb_userdata: procedure( + ctx: PSSL_CTX; u: SslPtr); cdecl; +// function SSL_CTX_LoadVerifyLocations(ctx: PSSL_CTX; +// const CAfile: PChar; const CApath: PChar):cint; cdecl; + SSL_CTX_load_verify_locations: function(ctx: PSSL_CTX; CAfile: pchar; + CApath: pchar):cint; cdecl; + SSL_CTX_set_verify: procedure(ctx: PSSL_CTX; mode: cint; + arg2: PFunction); cdecl; + +// SSLv2_method: function():PSSL_METHOD; cdecl; + SSLv3_method: function():PSSL_METHOD; cdecl; + TLSv1_method: function():PSSL_METHOD; cdecl; + SSLv23_method: function():PSSL_METHOD; cdecl; + SSL_use_certificate_file: function(ssl: PSSL; + _file: pchar; _type: cint):cint; cdecl; + SSL_use_PrivateKey_file: function(ssl: PSSL; _file: PChar; + _type: cint):cint; cdecl; + + SSL_set_fd: function(s: PSSL; fd: cint):cint; cdecl; + SSL_set_rfd: function(s: PSSL; fd: cint):cint; cdecl; + SSL_set_wfd: function(s: PSSL; fd: cint):cint; cdecl; + SSL_accept: function(ssl: PSSL):cint; cdecl; + SSL_connect: function(ssl: PSSL):cint; cdecl; + SSL_shutdown: function(ssl: PSSL):cint; cdecl; + SSL_read: function(ssl: PSSL; buf: SslPtr; num: cint):cint; cdecl; + SSL_peek: function(ssl: PSSL; buf: SslPtr; num: cint):cint; cdecl; + SSL_write: function(ssl: PSSL; buf: SslPtr; num: cint):cint; cdecl; + SSL_pending: function(ssl: PSSL):cint; cdecl; + SSL_get_version: function(ssl: PSSL): pchar; cdecl; + SSL_get_peer_certificate: function(ssl: PSSL): PX509; cdecl; + SSL_get_current_cipher: function(s: PSSL):SslPtr; cdecl; + SSL_CIPHER_get_name: function(c: SslPtr): pchar; cdecl; + SSL_CIPHER_get_bits: function(c: SslPtr; var alg_bits: cint):cint; cdecl; + SSL_get_verify_result: function(ssl: PSSL):cint; cdecl; + +{$ifndef mswindows} + SSLeay: function: cardinal; cdecl; + OpenSSL_add_all_ciphers: procedure; cdecl; + OpenSSL_add_all_digests: procedure; cdecl; + ERR_load_crypto_strings: procedure; cdecl; + ERR_peek_error: function: cardinal; cdecl; + ERR_peek_last_error: function: cardinal; cdecl; + CRYPTO_malloc: function (length: clong; const f: PCharacter; + line: cint): pointer; cdecl; + CRYPTO_realloc: function(str: PCharacter; length: clong; + const f: PCharacter; line: cint): pointer; cdecl; + CRYPTO_remalloc: function(a: pointer; length: clong; + const f: PCharacter; line: cint): pointer; cdecl; + CRYPTO_free: procedure(str: pointer); cdecl; +{$endif} + // Low level debugable memory management function +//util + SSLeay_version: function(t: cint): pchar; cdecl; + ERR_error_string_n: procedure(e: cint; buf: PChar; len: cint); cdecl; + ERR_get_error: function(): cint; cdecl; + ERR_clear_error: procedure; cdecl; + ERR_free_strings: procedure; cdecl; + ERR_remove_state: procedure(pid: cint); cdecl; + OPENSSL_add_all_algorithms_noconf: procedure; cdecl; + CRYPTO_cleanup_all_ex_data: procedure; cdecl; +// RAND_screen: procedure; cdecl; + i2d_X509_bio: function(b: PBIO; x: PX509): cint; cdecl; + i2d_PrivateKey_Bio: function(b: PBIO; pkey: pEVP_PKEY): cint; cdecl; + + CRYPTO_num_locks: function: cint; cdecl; + CRYPTO_set_locking_callback: procedure(cb: Sslptr); cdecl; + CRYPTO_set_id_callback: procedure(func: pointer); cdecl; + + +// OBJ functions + OBJ_obj2nid: function(asn1_object: pointer): cint; cdecl; + OBJ_txt2nid: function(s: PCharacter): cint; cdecl; + OBJ_txt2obj: function(s: PCharacter; no_name: cint): cint; cdecl; + // safestack functions + sk_new_null: function: pointer; cdecl; + sk_free: procedure(st: pointer); cdecl; + sk_push: function(st: pointer; val: pointer): cint; cdecl; + sk_num: function(st: pointer): cint; cdecl; + sk_value: function(st: pointer; i: cint): pointer; cdecl; + // Internal to DER and DER to internal conversion functions + + +// Helper: convert standard Delphi integer in big-endian integer +function int2bin(n: cint): cint; +// High level memory management function +{$ifndef mswindows} +function OPENSSL_malloc(length: clong): pointer; +function OPENSSL_realloc(address: PCharacter; length: clong): pointer; +function OPENSSL_remalloc(var address: pointer; length: clong): pointer; +procedure OPENSSL_free(address: pointer); // cdecl; ? +{$endif} +function SSL_set_options(ssl: PSSL; options: cint): cint; +//function IsSSLloaded: Boolean; + +procedure initsslinterface; //calls initializeopenssl once +procedure initializeopenssl(const sonames: array of filenamety; + const sonamesutil: array of filenamety); + //[] = default +procedure releaseopenssl; +procedure regopensslinit(const initproc: dynlibprocty); +procedure regopenssldeinit(const deinitproc: dynlibprocty); + +implementation +uses + msesystypes,{$ifdef FPC}dynlibs,{$endif}msesysintf1,msesysintf + {$ifndef FPC},classes_del{$endif}; +var + libinfo,libinfoutil: dynlibinfoty; + +var +// ssllibhandle: integer; +// sslutillibhandle: integer; +// sslloaded: boolean = false; + RAND_screen: procedure; cdecl; + +function SSL_set_options(ssl: PSSL; options: cint): cint; +begin + result:= ssl_ctrl(ssl,ssl_ctrl_options,options,nil); +end; + +function int2bin(n: cint): cint; +begin + result := ((cardinal(n) shr 24) and $000000FF) or + ((cardinal(n) shr 8) and $0000FF00) or + ((cardinal(n) shl 8) and $00FF0000) or + ((cardinal(n) shl 24) and $FF000000); +end; +{$ifndef mswindows} +function OPENSSL_malloc(length: clong): pointer; +begin + OPENSSL_malloc := CRYPTO_malloc(length, nil, 0); +end; + +function OPENSSL_realloc(address: PCharacter; length: clong): pointer; +begin + OPENSSL_realloc := CRYPTO_realloc(address, length, nil, 0); +end; + +function OPENSSL_remalloc(var address: pointer; length: clong): pointer; +begin + OPENSSL_remalloc := CRYPTO_remalloc(address, length, nil, 0); +end; + +procedure OPENSSL_free(address: pointer); +begin + CRYPTO_free(address); +end; +{$endif} +{ +procedure dounload; +begin + if ssllibhandle <> 0 then begin + freelibrary(ssllibhandle); + ssllibhandle:= 0; + end; + if sslutillibhandle <> 0 then begin + freelibrary(sslutillibhandle); + sslutillibhandle:= 0; + end; +end; +} +type + mutexarty = array of mutexty; +var + locks: mutexarty; + +procedure lockingcallback(mode: cint; n: cint; afile: pchar; + line: cint); cdecl; +begin + if mode and crypto_lock <> 0 then begin + sys_mutexlock(locks[n]); + end + else begin + sys_mutexunlock(locks[n]); + end; +end; + +function idcallback: cint; cdecl; +begin + result:= sys_getcurrentthread; +end; + +procedure initssllib(const data: pointer); +var + int1: cint; +begin + //init library + Ssl_Library_Init; + Ssl_Load_Error_Strings; + OPENSSL_add_all_algorithms_noconf; + pointer({$ifndef FPC}@{$endif}rand_screen):= getprocedureaddress( + libinfoutil.libhandle,'RAND_screen'); + if assigned(rand_screen) then begin + Rand_Screen; //windows, todo: better random + end; + setlength(locks,crypto_num_locks()); + for int1:= 0 to high(locks) do begin + sys_mutexcreate(locks[int1]); + end; + crypto_set_locking_callback(@lockingcallback); + crypto_set_id_callback(@idcallback); +end; + +procedure initializeopenssl(const sonames: array of filenamety; + const sonamesutil: array of filenamety); + //[] = default +const + funcs: array[0..{$ifndef mswindows}53{$else}43{$endif}] of funcinfoty = ( + (n: 'SSL_get_error'; d: {$ifndef FPC}@{$endif}@SSL_get_error), + (n: 'SSL_library_init'; d: {$ifndef FPC}@{$endif}@SSL_library_init), + (n: 'SSL_load_error_strings'; d: {$ifndef FPC}@{$endif}@SSL_load_error_strings), + (n: 'SSL_CTX_set_cipher_list'; d: {$ifndef FPC}@{$endif}@SSL_CTX_set_cipher_list), + (n: 'SSL_CTX_new'; d: {$ifndef FPC}@{$endif}@SSL_CTX_new), + (n: 'SSL_CTX_free'; d: {$ifndef FPC}@{$endif}@SSL_CTX_free), + (n: 'SSL_set_fd'; d: {$ifndef FPC}@{$endif}@SSL_set_fd), + (n: 'SSL_set_rfd'; d: {$ifndef FPC}@{$endif}@SSL_set_rfd), + (n: 'SSL_set_wfd'; d: {$ifndef FPC}@{$endif}@SSL_set_wfd), + (n: 'SSL_set_cipher_list'; d: {$ifndef FPC}@{$endif}@SSL_set_cipher_list), +// (n: 'SSLv2_method'; d: {$ifndef FPC}@{$endif}@SSLv2_method), + (n: 'SSLv3_method'; d: {$ifndef FPC}@{$endif}@SSLv3_method), + (n: 'TLSv1_method'; d: {$ifndef FPC}@{$endif}@TLSv1_method), + (n: 'SSLv23_method'; d: {$ifndef FPC}@{$endif}@SSLv23_method), + (n: 'SSL_CTX_use_PrivateKey'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_PrivateKey), + (n: 'SSL_CTX_use_PrivateKey_ASN1'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_PrivateKey_ASN1), + (n: 'SSL_CTX_use_PrivateKey_file'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_PrivateKey_file), + (n: 'SSL_CTX_use_RSAPrivateKey_file'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_RSAPrivateKey_file), + (n: 'SSL_CTX_use_certificate'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_certificate), + (n: 'SSL_CTX_use_certificate_ASN1'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_certificate_ASN1), + (n: 'SSL_CTX_use_certificate_file'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_certificate_file), + (n: 'SSL_CTX_use_certificate_chain_file'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_certificate_chain_file), + (n: 'SSL_CTX_check_private_key'; d: {$ifndef FPC}@{$endif}@SSL_CTX_check_private_key), + (n: 'SSL_CTX_set_default_passwd_cb'; d: {$ifndef FPC}@{$endif}@SSL_CTX_set_default_passwd_cb), + (n: 'SSL_CTX_set_default_passwd_cb_userdata'; d: {$ifndef FPC}@{$endif}@SSL_CTX_set_default_passwd_cb_userdata), + (n: 'SSL_CTX_load_verify_locations'; d: {$ifndef FPC}@{$endif}@SSL_CTX_load_verify_locations), + (n: 'SSL_new'; d: {$ifndef FPC}@{$endif}@SSL_new), + (n: 'SSL_free'; d: {$ifndef FPC}@{$endif}@SSL_free), + (n: 'SSL_ctrl'; d: {$ifndef FPC}@{$endif}@SSL_ctrl), + (n: 'SSL_use_certificate_file'; d: {$ifndef FPC}@{$endif}@SSL_use_certificate_file), + (n: 'SSL_use_PrivateKey_file'; d: {$ifndef FPC}@{$endif}@SSL_use_PrivateKey_file), + (n: 'SSL_accept'; d: {$ifndef FPC}@{$endif}@SSL_accept), + (n: 'SSL_connect'; d: {$ifndef FPC}@{$endif}@SSL_connect), + (n: 'SSL_shutdown'; d: {$ifndef FPC}@{$endif}@SSL_shutdown), + (n: 'SSL_read'; d: {$ifndef FPC}@{$endif}@SSL_read), + (n: 'SSL_peek'; d: {$ifndef FPC}@{$endif}@SSL_peek), + (n: 'SSL_write'; d: {$ifndef FPC}@{$endif}@SSL_write), + (n: 'SSL_pending'; d: {$ifndef FPC}@{$endif}@SSL_pending), + (n: 'SSL_get_peer_certificate'; d: {$ifndef FPC}@{$endif}@SSL_get_peer_certificate), + (n: 'SSL_get_version'; d: {$ifndef FPC}@{$endif}@SSL_get_version), + (n: 'SSL_CTX_set_verify'; d: {$ifndef FPC}@{$endif}@SSL_CTX_set_verify), + (n: 'SSL_get_current_cipher'; d: {$ifndef FPC}@{$endif}@SSL_get_current_cipher), + (n: 'SSL_CIPHER_get_name'; d: {$ifndef FPC}@{$endif}@SSL_CIPHER_get_name), + (n: 'SSL_CIPHER_get_bits'; d: {$ifndef FPC}@{$endif}@SSL_CIPHER_get_bits), + (n: 'SSL_get_verify_result'; d: {$ifndef FPC}@{$endif}@SSL_get_verify_result) + {$ifndef mswindows} + , + (n: 'SSLeay'; d: {$ifndef FPC}@{$endif}@SSLeay), + (n: 'OpenSSL_add_all_ciphers'; d: {$ifndef FPC}@{$endif}@OpenSSL_add_all_ciphers), + (n: 'OpenSSL_add_all_digests'; d: {$ifndef FPC}@{$endif}@OpenSSL_add_all_digests), + (n: 'ERR_load_crypto_strings'; d: {$ifndef FPC}@{$endif}@ERR_load_crypto_strings), + (n: 'ERR_peek_error'; d: {$ifndef FPC}@{$endif}@ERR_peek_error), + (n: 'ERR_peek_last_error'; d: {$ifndef FPC}@{$endif}@ERR_peek_last_error), + (n: 'CRYPTO_malloc'; d: {$ifndef FPC}@{$endif}@CRYPTO_malloc), + (n: 'CRYPTO_realloc'; d: {$ifndef FPC}@{$endif}@CRYPTO_realloc), + (n: 'CRYPTO_remalloc'; d: {$ifndef FPC}@{$endif}@CRYPTO_remalloc), + (n: 'CRYPTO_free'; d: {$ifndef FPC}@{$endif}@CRYPTO_free) + {$endif} + ); + funcsutil: array[0..20] of funcinfoty = ( + (n: 'SSLeay_version'; d: {$ifndef FPC}@{$endif}@SSLeay_version), + (n: 'ERR_error_string_n'; d: {$ifndef FPC}@{$endif}@ERR_error_string_n), + (n: 'ERR_get_error'; d: {$ifndef FPC}@{$endif}@ERR_get_error), + (n: 'ERR_clear_error'; d: {$ifndef FPC}@{$endif}@ERR_clear_error), + (n: 'ERR_free_strings'; d: {$ifndef FPC}@{$endif}@ERR_free_strings), + (n: 'ERR_remove_state'; d: {$ifndef FPC}@{$endif}@ERR_remove_state), + (n: 'OPENSSL_add_all_algorithms_noconf'; d: {$ifndef FPC}@{$endif}@OPENSSL_add_all_algorithms_noconf), + (n: 'CRYPTO_cleanup_all_ex_data'; d: {$ifndef FPC}@{$endif}@CRYPTO_cleanup_all_ex_data), +// 'RAND_screen', + (n: 'i2d_X509_bio'; d: {$ifndef FPC}@{$endif}@i2d_X509_bio), + (n: 'i2d_PrivateKey_bio'; d: {$ifndef FPC}@{$endif}@i2d_PrivateKey_bio), + // 3DES functions + // + (n: 'CRYPTO_num_locks'; d: {$ifndef FPC}@{$endif}@CRYPTO_num_locks), + (n: 'CRYPTO_set_locking_callback'; d: {$ifndef FPC}@{$endif}@CRYPTO_set_locking_callback), + (n: 'CRYPTO_set_id_callback'; d: {$ifndef FPC}@{$endif}@CRYPTO_set_id_callback), + + (n: 'OBJ_obj2nid'; d: {$ifndef FPC}@{$endif}@OBJ_obj2nid), + (n: 'OBJ_txt2nid'; d: {$ifndef FPC}@{$endif}@OBJ_txt2nid), + (n: 'OBJ_txt2obj'; d: {$ifndef FPC}@{$endif}@OBJ_txt2obj), + (n: 'sk_new_null'; d: {$ifndef FPC}@{$endif}@sk_new_null), + (n: 'sk_free'; d: {$ifndef FPC}@{$endif}@sk_free), + (n: 'sk_push'; d: {$ifndef FPC}@{$endif}@sk_push), + (n: 'sk_num'; d: {$ifndef FPC}@{$endif}@sk_num), + (n: 'sk_value'; d: {$ifndef FPC}@{$endif}@sk_value) + + ); + + errormessage = 'Can not load OpenSSL library, '; +begin + initializedynlib(libinfo,sonames,openssllib,funcs,[],errormessage); + initializedynlib(libinfoutil,sonamesutil,opensslutillib, + funcsutil,[],errormessage,@initssllib); +end; + +var + libloaded: boolean; + +procedure initsslinterface; //calls initializeopenssl once +begin + if not libloaded then begin + initializeopenssl([],[]); + libloaded:= true; + end; +end; + +procedure deinitssllib(const data: pointer); +var + int1: cint; +begin + crypto_cleanup_all_ex_data; + err_remove_state(0); + for int1:= 0 to high(locks) do begin + sys_mutexdestroy(locks[int1]); + end; + locks:= nil; +end; + +procedure releaseopenssl; +begin + releasedynlib(libinfoutil); + releasedynlib(libinfo,@deinitssllib); +end; + +procedure regopensslinit(const initproc: dynlibprocty); +begin + regdynlibinit(libinfoutil,initproc); +end; + +procedure regopenssldeinit(const deinitproc: dynlibprocty); +begin + regdynlibdeinit(libinfoutil,deinitproc); +end; + +{ +function issslloaded: boolean; +begin + result:= sslloaded; +end; +} + +{ +finalization + destroysslinterface; +} +initialization + initializelibinfo(libinfo); + initializelibinfo(libinfoutil); +finalization + if libloaded then begin + releaseopenssl; + end; + finalizelibinfo(libinfo); + finalizelibinfo(libinfoutil); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslaes.pas b/mseide-msegui/lib/common/crypto/mseopensslaes.pas new file mode 100644 index 0000000..f4a4686 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslaes.pas @@ -0,0 +1,38 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopensslaes; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +var + AES_set_decrypt_key: function(userKey: PCharacter; bits: cint; + key: pAES_KEY): cint; cdecl; + AES_cbc_encrypt: procedure(buffer: PCharacter; u: PCharacter; length: clong; + key: pAES_KEY; ivec: pointer; enc: cint); cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..1] of funcinfoty = ( + (n: 'AES_set_decrypt_key'; d: @AES_set_decrypt_key), + (n: 'AES_cbc_encrypt'; d: @AES_cbc_encrypt) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslasn.pas b/mseide-msegui/lib/common/crypto/mseopensslasn.pas new file mode 100644 index 0000000..f2ad7d7 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslasn.pas @@ -0,0 +1,75 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopensslasn; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; +type +// ASN1 types + pASN1_OBJECT = pointer; + pASN1_STRING = ^ASN1_STRING; + ASN1_STRING = record + length: cint; + asn1_type: cint; + data: pointer; + flags: clong; + end; + pASN1_IA5STRING = pASN1_STRING; + pASN1_ENUMERATED = pASN1_STRING; + pASN1_TIME = pASN1_STRING; + pASN1_OCTET_STRING = pASN1_STRING; + +var + // ASN.1 functions + ASN1_UTCTIME_New: function(): PASN1_UTCTIME; cdecl; + ASN1_UTCTIME_Free: procedure(a: PASN1_UTCTIME); cdecl; + ASN1_INTEGER_Set: function(a: PASN1_INTEGER; v: cint): cint; cdecl; + ASN1_IA5STRING_new: function: pASN1_IA5STRING; cdecl; + ASN1_INTEGER_free: procedure(x: pASN1_IA5STRING); cdecl; + ASN1_INTEGER_get: function(a: pointer): clong; cdecl; + ASN1_STRING_set_default_mask: procedure(mask: cardinal); cdecl; + ASN1_STRING_get_default_mask: function: cardinal; cdecl; + ASN1_TIME_print: function(fp: pBIO; a: pASN1_TIME): cint; cdecl; + i2d_ASN1_TIME: function(a: pASN1_TIME; pp: PCharacter): cint; cdecl; + d2i_ASN1_TIME: function(var a: pASN1_TIME; pp: PCharacter; + length: clong): pASN1_TIME; cdecl; + // Internal to ASN.1 and ASN.1 to internal conversion functions + i2a_ASN1_INTEGER: function(bp: pBIO; a: pASN1_INTEGER): cint; cdecl; + a2i_ASN1_INTEGER: function(bp: pBIO; bs: pASN1_INTEGER; buf: PCharacter; + size: cint): cint; cdecl; +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..12] of funcinfoty = ( + (n: 'ASN1_UTCTIME_new'; d: @ASN1_UTCTIME_new), + (n: 'ASN1_UTCTIME_free'; d: @ASN1_UTCTIME_free), + (n: 'ASN1_INTEGER_set'; d: @ASN1_INTEGER_set), + (n: 'ASN1_IA5STRING_new'; d: @ASN1_IA5STRING_new), + (n: 'ASN1_INTEGER_free'; d: @ASN1_INTEGER_free), + (n: 'ASN1_INTEGER_get'; d: @ASN1_INTEGER_get), + (n: 'ASN1_STRING_set_default_mask'; d: @ASN1_STRING_set_default_mask), + (n: 'ASN1_STRING_get_default_mask'; d: @ASN1_STRING_get_default_mask), + (n: 'ASN1_TIME_print'; d: @ASN1_TIME_print), + (n: 'i2d_ASN1_TIME'; d: @i2d_ASN1_TIME), + (n: 'd2i_ASN1_TIME'; d: @d2i_ASN1_TIME), + (n: 'i2a_ASN1_INTEGER'; d: @i2a_ASN1_INTEGER), + (n: 'a2i_ASN1_INTEGER'; d: @a2i_ASN1_INTEGER) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslbignum.pas b/mseide-msegui/lib/common/crypto/mseopensslbignum.pas new file mode 100644 index 0000000..8a8e24e --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslbignum.pas @@ -0,0 +1,379 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopensslbignum; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +type + pBN_ULONG = ^BN_ULONG; + BN_ULONG = culong; // system dependent, consider it as a opaque pointer + + pBIGNUM = ^BIGNUM; + BIGNUM = record + d: pBN_ULONG; // Pointer to an array of 'BN_BITS2' bit chunks. + top: cint; // Index of last used d +1. + // The next are internal book keeping for bn_expand. + dmax: cint; // Size of the d array. + neg: cint; // one if the number is negative + flags: cint; + end; + + pBN_CTX = ^BN_CTX; + BN_CTX = record + tos: cint; + bn: array [0..BN_CTX_NUM-1] of BIGNUM; + flags: cint; + depth: cint; + pos: array [0..BN_CTX_NUM_POS-1] of cint; + too_many: cint; + end; + + pBN_BLINDING = ^BN_BLINDING; + BN_BLINDING = record + init: cint; + A: pBIGNUM; + Ai: pBIGNUM; + _mod: pBIGNUM; // just a reference (original name: mod) + end; + + // Used for montgomery multiplication + pBN_MONT_CTX = ^BN_MONT_CTX; + BN_MONT_CTX = record + ri: cint; // number of bits in R + RR: BIGNUM; // used to convert to montgomery form + N: BIGNUM; // The modulus + Ni: BIGNUM; // R*(1/R mod N) - N*Ni = 1 + // (Ni is only stored for bignum algorithm) + n0: BN_ULONG; // least significant word of Ni + flags: cint; + end; + + // Used for reciprocal division/mod functions + // It cannot be shared between threads + pBN_RECP_CTX = ^BN_RECP_CTX; + BN_RECP_CTX = record + N: BIGNUM; // the divisor + Nr: BIGNUM; // the reciprocal + num_bits: cint; + shift: cint; + flags: cint; + end; + +var + // Big number function + BN_new:function: pBIGNUM; cdecl; + BN_init: procedure(bn: pBIGNUM); cdecl; + BN_clear: procedure(bn: pBIGNUM); cdecl; + BN_free: procedure(bn: pBIGNUM); cdecl; + BN_clear_free: procedure(bn: pBIGNUM); cdecl; + BN_set_params: procedure (mul, high, low, mont: cint); cdecl; + BN_get_params: function(which: cint): cint; cdecl; + BN_options:function: PCharacter; cdecl; + BN_CTX_new: function: pBN_CTX; cdecl; + BN_CTX_init: procedure(ctx: pBN_CTX); cdecl; + BN_CTX_start: procedure(ctx: pBN_CTX); cdecl; + BN_CTX_get: function(ctx: pBN_CTX): pBIGNUM; cdecl; + BN_CTX_end: procedure(ctx: pBN_CTX); cdecl; + BN_CTX_free: procedure(ctx: pBN_CTX); cdecl; + BN_MONT_CTX_new: function: pBN_MONT_CTX; cdecl; + BN_MONT_CTX_init: procedure(m_ctx: pBN_MONT_CTX); cdecl; + BN_MONT_CTX_set: function(m_ctx: pBN_MONT_CTX;const modulus: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_MONT_CTX_copy: function(_to: pBN_MONT_CTX; + from: pBN_MONT_CTX): pBN_MONT_CTX; cdecl; + BN_MONT_CTX_free: procedure(m_ctx: pBN_MONT_CTX); cdecl; + BN_mod_mul_montgomery: function(r, a, b: pBIGNUM; m_ctx: pBN_MONT_CTX; + ctx: pBN_CTX): cint; cdecl; + BN_from_montgomery: function(r, a: pBIGNUM; m_ctx: pBN_MONT_CTX; + ctx: pBN_CTX): cint; cdecl; + BN_RECP_CTX_init: procedure(recp: pBN_RECP_CTX); cdecl; + BN_RECP_CTX_set: function(recp: pBN_RECP_CTX; const rdiv: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_RECP_CTX_new: function: pBN_RECP_CTX; cdecl; + BN_RECP_CTX_free: procedure(recp: pBN_RECP_CTX); cdecl; + BN_div_recp: function(dv, rem, a: pBIGNUM; recp: pBN_RECP_CTX; + ctx: pBN_CTX): cint; cdecl; + BN_mod_mul_reciprocal: function(r, a, b: pBIGNUM; recp: pBN_RECP_CTX; + ctx: pBN_CTX): cint; cdecl; + BN_BLINDING_new: function(a: pBIGNUM; Ai: pBIGNUM; + _mod: pBIGNUM): pBN_BLINDING; cdecl; + BN_BLINDING_update: function(b: pBN_BLINDING; + ctx: pBN_CTX): pBN_BLINDING; cdecl; + BN_BLINDING_free: procedure(b: pBN_BLINDING); cdecl; + BN_BLINDING_convert: function(n: pBIGNUM; r: pBN_BLINDING; + ctx: pBN_CTX): cint; cdecl; + BN_BLINDING_invert: function(n: pBIGNUM; b: pBN_BLINDING; + ctx: pBN_CTX): cint; cdecl; + BN_copy: function(_to: pBIGNUM; const from: pBIGNUM): pBIGNUM; cdecl; + BN_dup: function(const from: pBIGNUM): pBIGNUM; cdecl; + BN_bn2bin: function(const n: pBIGNUM; _to: pointer): cint; cdecl; + BN_bin2bn: function(const _from: pointer; len: cint; + ret: pBIGNUM): pBIGNUM; cdecl; + BN_bn2hex: function(const n: pBIGNUM): PCharacter; cdecl; + BN_bn2dec: function(const n: pBIGNUM): PCharacter; cdecl; + BN_hex2bn: function(var n: pBIGNUM; const str: PCharacter): cint; cdecl; + BN_dec2bn: function(var n: pBIGNUM; const str: PCharacter): cint; cdecl; + BN_bn2mpi: function(const a: pBIGNUM; _to: pointer): cint; cdecl; + BN_mpi2bn: function(s: pointer; len: cint; ret: pBIGNUM): pBIGNUM; cdecl; + BN_print: function(fp: pBIO; const a: pointer): cint; cdecl; + // BN_print_fp: function(FILE *fp, const BIGNUM *a): cint; cdecl; + BN_value_one: function: pBIGNUM; cdecl; + BN_set_word: function(n: pBIGNUM; w: cardinal): cint; cdecl; + BN_get_word: function(n: pBIGNUM): cardinal; cdecl; + BN_cmp: function(a: pBIGNUM; b: pBIGNUM): cint; cdecl; + BN_ucmp: function(a: pBIGNUM; b: pBIGNUM): cint; cdecl; + BN_num_bits: function(const a: pBIGNUM): cint; cdecl; + BN_num_bits_word: function(w: BN_ULONG): cint; cdecl; + BN_add: function(r: pBIGNUM; const a, b: pBIGNUM): cint; cdecl; + BN_sub: function(r: pBIGNUM; const a, b: pBIGNUM): cint; cdecl; + BN_uadd: function(r: pBIGNUM; const a, b: pBIGNUM): cint; cdecl; + BN_usub: function(r: pBIGNUM; const a, b: pBIGNUM): cint; cdecl; + BN_mul: function(r: pBIGNUM; a: pBIGNUM; b: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_sqr: function(r: pBIGNUM; a: pBIGNUM; ctx: pBN_CTX): cint; cdecl; + BN_div: function(dv: pBIGNUM; rem: pBIGNUM; const a, d: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_exp: function(r: pBIGNUM; a: pBIGNUM; p: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_mod_exp: function(r, a: pBIGNUM; const p, m: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_gcd: function(r: pBIGNUM; a: pBIGNUM; b: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + // BN_nnmod requires OpenSSL >= 0.9.7 + BN_nnmod: function(rem: pBIGNUM; const a: pBIGNUM; + const m: pBIGNUM; ctx: pBN_CTX): cint; cdecl; + // BN_mod_add requires OpenSSL >= 0.9.7 + BN_mod_add: function(r: pBIGNUM; a: pBIGNUM; b: pBIGNUM; + const m: pBIGNUM; ctx: pBN_CTX): cint;cdecl; + // BN_mod_sub requires OpenSSL >= 0.9.7 + BN_mod_sub: function(r: pBIGNUM; a: pBIGNUM; b: pBIGNUM; + const m: pBIGNUM; ctx: pBN_CTX): cint; cdecl; + // BN_mod_mul requires OpenSSL >= 0.9.7 + BN_mod_mul: function(ret, a, b: pBIGNUM; const m: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + // BN_mod_sqr requires OpenSSL >= 0.9.7 + BN_mod_sqr: function(r: pBIGNUM; a: pBIGNUM; + const m: pBIGNUM; ctx: pBN_CTX): cint; cdecl; + BN_reciprocal: function(r, m: pBIGNUM; ctx: pBN_CTX): cint; cdecl; + BN_mod_exp2_mont: function(r, a1, p1, a2, p2, m: pBIGNUM; + ctx: pBN_CTX; m_ctx: pBN_MONT_CTX): cint; cdecl; + BN_mod_exp_mont: function(r, a: pBIGNUM; const p, m: pBIGNUM; + ctx: pBN_CTX; m_ctx: pBN_MONT_CTX): cint; cdecl; + BN_mod_exp_mont_word: function(r: pBIGNUM; a: BN_ULONG; + const p, m: pBIGNUM; ctx: pBN_CTX; m_ctx: pBN_MONT_CTX): cint; cdecl; + BN_mod_exp_simple: function(r, a, p, m: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_mod_exp_recp: function(r: pBIGNUM; const a, p, m: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_mod_inverse: function(ret, a: pBIGNUM; const n: pBIGNUM; + ctx: pBN_CTX): pBIGNUM; cdecl; + BN_add_word: function (a: pBIGNUM; w: BN_ULONG): cint; cdecl; + // Adds w to a ("a+=w"). + BN_sub_word: function(a: pBIGNUM; w: BN_ULONG): cint; cdecl; + // Subtracts w from a ("a-=w"). + BN_mul_word: function(a: pBIGNUM; w: BN_ULONG): cint; cdecl; + // Multiplies a and w ("a*=b"). + BN_div_word: function(a: pBIGNUM; w: BN_ULONG): BN_ULONG; cdecl; + // Divides a by w ("a/=w") and returns the remainder. + BN_mod_word: function(const a: pBIGNUM; w: BN_ULONG): BN_ULONG; cdecl; + // Returns the remainder of a divided by w ("a%m"). + bn_mul_words: function(rp, ap: pBN_ULONG; num: cint; + w: BN_ULONG): BN_ULONG; cdecl; + bn_mul_add_words: function(rp, ap: pBN_ULONG; num: cint; + w: BN_ULONG): BN_ULONG; cdecl; + bn_sqr_words: procedure(rp, ap: pBN_ULONG; num: cint); cdecl; + bn_div_words: function(h, l, d: BN_ULONG): BN_ULONG; cdecl; + bn_add_words: function(rp, ap, bp: pBN_ULONG; num: cint): BN_ULONG; cdecl; + bn_sub_words: function(rp, ap, bp: pBN_ULONG; num: cint): BN_ULONG; cdecl; + bn_expand2: function(a: pBIGNUM; n: cint): pBIGNUM; cdecl; + BN_set_bit: function(a: pBIGNUM; n: cint): cint; cdecl; + BN_clear_bit: function(a: pBIGNUM; n: cint): cint; cdecl; + BN_is_bit_set: function(const a: pBIGNUM; n: cint): cint; cdecl; + BN_mask_bits: function(a: pBIGNUM; n: cint): cint; cdecl; + BN_lshift: function(r: pBIGNUM; const a: pBIGNUM; n: cint): cint; cdecl; + BN_lshift1: function(r: pBIGNUM; a: pBIGNUM): cint; cdecl; + BN_rshift: function(r: pBIGNUM; const a: pBIGNUM; n: cint): cint; cdecl; + BN_rshift1: function(r: pBIGNUM; a: pBIGNUM): cint; cdecl; + BN_generate_prime: function (ret: pBIGNUM; num, safe: cint; + add, rem: pBIGNUM; + progress: TProgressCallbackFunction; + cb_arg: pointer): pBIGNUM; cdecl; + BN_is_prime: function(const a: pBIGNUM; checks: cint; + progress: TProgressCallbackFunction; ctx: pBN_CTX; + cb_arg: pointer): cint; cdecl; + BN_is_prime_fasttest: function(const a: pBIGNUM; checks: cint; + progress: TProgressCallbackFunction; ctx: pBN_CTX; + cb_arg: pointer; do_trial_division: cint): cint; cdecl; + BN_rand: function(rnd: pBIGNUM; bits, top, bottom: cint): cint; cdecl; + BN_pseudo_rand: function(rnd: pBIGNUM; + bits, top, bottom: cint): cint; cdecl; + BN_rand_range: function(rnd, range: pBIGNUM): cint; cdecl; + // BN_pseudo_rand_range requires OpenSSL >= 0.9.6c + BN_pseudo_rand_range: function(rnd, range: pBIGNUM): cint; cdecl; + BN_bntest_rand: function(rnd: pBIGNUM; + bits, top, bottom: cint): cint; cdecl; + BN_to_ASN1_INTEGER: function(bn: pBIGNUM; + ai: pASN1_INTEGER): pASN1_INTEGER; cdecl; + BN_to_ASN1_ENUMERATED: function(bn: pBIGNUM; + ai: pASN1_ENUMERATED): pASN1_ENUMERATED; cdecl; + +function BN_to_montgomery(r, a: pBIGNUM; m_ctx: pBN_MONT_CTX; + ctx: pBN_CTX): cint; +function BN_zero(n: pBIGNUM): cint; +function BN_one(n: pBIGNUM): cint; +function BN_num_bytes(const a: pBIGNUM): cint; +// BN_mod redefined as BN_div in some DLL version +function BN_mod(rem: pBIGNUM; const a, m: pBIGNUM; ctx: pBN_CTX): cint; + +implementation +uses + msedynload; + +function BN_to_montgomery(r, a: pBIGNUM; m_ctx: pBN_MONT_CTX; + ctx: pBN_CTX): cint; +begin + result := BN_mod_mul_montgomery(r, a, @(m_ctx^.RR), m_ctx, ctx); +end; + +function BN_zero(n: pBIGNUM): cint; +begin + result := BN_set_word(n, 0) +end; + +function BN_one(n: pBIGNUM): cint; +begin + result := BN_set_word(n, 1) +end; + +function BN_num_bytes(const a: pBIGNUM): cint; +begin + result := (BN_num_bits(a) + 7) div 8; +end; + +function BN_mod(rem: pBIGNUM; const a, m: pBIGNUM; ctx: pBN_CTX): cint; +begin + result := BN_div(nil, rem, a, m, ctx); +end; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..101] of funcinfoty = ( + (n: 'BN_new'; d: @BN_new), + (n: 'BN_init'; d: @BN_init), + (n: 'BN_clear'; d: @BN_clear), + (n: 'BN_free'; d: @BN_free), + (n: 'BN_clear_free'; d: @BN_clear_free), + (n: 'BN_set_params'; d: @BN_set_params), + (n: 'BN_get_params'; d: @BN_get_params), + (n: 'BN_options'; d: @BN_options), + (n: 'BN_CTX_new'; d: @BN_CTX_new), + (n: 'BN_CTX_init'; d: @BN_CTX_init), + (n: 'BN_CTX_start'; d: @BN_CTX_start), + (n: 'BN_CTX_get'; d: @BN_CTX_get), + (n: 'BN_CTX_end'; d: @BN_CTX_end), + (n: 'BN_CTX_free'; d: @BN_CTX_free), + (n: 'BN_MONT_CTX_new'; d: @BN_MONT_CTX_new), + (n: 'BN_MONT_CTX_init'; d: @BN_MONT_CTX_init), + (n: 'BN_MONT_CTX_set'; d: @BN_MONT_CTX_set), + (n: 'BN_MONT_CTX_copy'; d: @BN_MONT_CTX_copy), + (n: 'BN_MONT_CTX_free'; d: @BN_MONT_CTX_free), + (n: 'BN_mod_mul_montgomery'; d: @BN_mod_mul_montgomery), + (n: 'BN_from_montgomery'; d: @BN_from_montgomery), + (n: 'BN_RECP_CTX_init'; d: @BN_RECP_CTX_init), + (n: 'BN_RECP_CTX_set'; d: @BN_RECP_CTX_set), + (n: 'BN_RECP_CTX_new'; d: @BN_RECP_CTX_new), + (n: 'BN_RECP_CTX_free'; d: @BN_RECP_CTX_free), + (n: 'BN_div_recp'; d: @BN_div_recp), + (n: 'BN_mod_mul_reciprocal'; d: @BN_mod_mul_reciprocal), + (n: 'BN_BLINDING_new'; d: @BN_BLINDING_new), + (n: 'BN_BLINDING_update'; d: @BN_BLINDING_update), + (n: 'BN_BLINDING_free'; d: @BN_BLINDING_free), + (n: 'BN_BLINDING_convert'; d: @BN_BLINDING_convert), + (n: 'BN_BLINDING_invert'; d: @BN_BLINDING_invert), + (n: 'BN_copy'; d: @BN_copy), + (n: 'BN_dup'; d: @BN_dup), + (n: 'BN_bn2bin'; d: @BN_bn2bin), + (n: 'BN_bin2bn'; d: @BN_bin2bn), + (n: 'BN_bn2hex'; d: @BN_bn2hex), + (n: 'BN_bn2dec'; d: @BN_bn2dec), + (n: 'BN_hex2bn'; d: @BN_hex2bn), + (n: 'BN_dec2bn'; d: @BN_dec2bn), + (n: 'BN_bn2mpi'; d: @BN_bn2mpi), + (n: 'BN_mpi2bn'; d: @BN_mpi2bn), + (n: 'BN_print'; d: @BN_print), + (n: 'BN_value_one'; d: @BN_value_one), + (n: 'BN_set_word'; d: @BN_set_word), + (n: 'BN_get_word'; d: @BN_get_word), + (n: 'BN_cmp'; d: @BN_cmp), + (n: 'BN_ucmp'; d: @BN_ucmp), + (n: 'BN_num_bits'; d: @BN_num_bits), + (n: 'BN_num_bits_word'; d: @BN_num_bits_word), + (n: 'BN_add'; d: @BN_add), + (n: 'BN_sub'; d: @BN_sub), + (n: 'BN_uadd'; d: @BN_uadd), + (n: 'BN_usub'; d: @BN_usub), + (n: 'BN_mul'; d: @BN_mul), + (n: 'BN_sqr'; d: @BN_sqr), + (n: 'BN_div'; d: @BN_div), + (n: 'BN_exp'; d: @BN_exp), + (n: 'BN_mod_exp'; d: @BN_mod_exp), + (n: 'BN_gcd'; d: @BN_gcd), + (n: 'BN_nnmod'; d: @BN_nnmod), + (n: 'BN_mod_add'; d: @BN_mod_add), + (n: 'BN_mod_sub'; d: @BN_mod_sub), + (n: 'BN_mod_mul'; d: @BN_mod_mul), + (n: 'BN_mod_sqr'; d: @BN_mod_sqr), + (n: 'BN_reciprocal'; d: @BN_reciprocal), + (n: 'BN_mod_exp2_mont'; d: @BN_mod_exp2_mont), + (n: 'BN_mod_exp_mont'; d: @BN_mod_exp_mont), + (n: 'BN_mod_exp_mont_word'; d: @BN_mod_exp_mont_word), + (n: 'BN_mod_exp_simple'; d: @BN_mod_exp_simple), + (n: 'BN_mod_exp_recp'; d: @BN_mod_exp_recp), + (n: 'BN_mod_inverse'; d: @BN_mod_inverse), + (n: 'BN_add_word'; d: @BN_add_word), + (n: 'BN_sub_word'; d: @BN_sub_word), + (n: 'BN_mul_word'; d: @BN_mul_word), + (n: 'BN_div_word'; d: @BN_div_word), + (n: 'BN_mod_word'; d: @BN_mod_word), + (n: 'bn_mul_words'; d: @bn_mul_words), + (n: 'bn_mul_add_words'; d: @bn_mul_add_words), + (n: 'bn_sqr_words'; d: @bn_sqr_words), + (n: 'bn_div_words'; d: @bn_div_words), + (n: 'bn_add_words'; d: @bn_add_words), + (n: 'bn_sub_words'; d: @bn_sub_words), + (n: 'bn_expand2'; d: @bn_expand2), + (n: 'BN_set_bit'; d: @BN_set_bit), + (n: 'BN_clear_bit'; d: @BN_clear_bit), + (n: 'BN_is_bit_set'; d: @BN_is_bit_set), + (n: 'BN_mask_bits'; d: @BN_mask_bits), + (n: 'BN_lshift'; d: @BN_lshift), + (n: 'BN_lshift1'; d: @BN_lshift1), + (n: 'BN_rshift'; d: @BN_rshift), + (n: 'BN_rshift1'; d: @BN_rshift1), + (n: 'BN_generate_prime'; d: @BN_generate_prime), + (n: 'BN_is_prime'; d: @BN_is_prime), + (n: 'BN_is_prime_fasttest'; d: @BN_is_prime_fasttest), + (n: 'BN_rand'; d: @BN_rand), + (n: 'BN_pseudo_rand'; d: @BN_pseudo_rand), + (n: 'BN_rand_range'; d: @BN_rand_range), + (n: 'BN_pseudo_rand_range'; d: @BN_pseudo_rand_range), + (n: 'BN_bntest_rand'; d: @BN_bntest_rand), + (n: 'BN_to_ASN1_INTEGER'; d: @BN_to_ASN1_INTEGER), + (n: 'BN_to_ASN1_ENUMERATED'; d: @BN_to_ASN1_ENUMERATED) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslbio.pas b/mseide-msegui/lib/common/crypto/mseopensslbio.pas new file mode 100644 index 0000000..f2236bc --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslbio.pas @@ -0,0 +1,248 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopensslbio; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +const + // These are the 'types' of BIOs + BIO_TYPE_NONE = $0000; + BIO_TYPE_MEM = $0001 or $0400; + BIO_TYPE_FILE = $0002 or $0400; + + BIO_TYPE_FD = $0004 or $0400 or $0100; + BIO_TYPE_SOCKET = $0005 or $0400 or $0100; + BIO_TYPE_NULL = $0006 or $0400; + BIO_TYPE_SSL = $0007 or $0200; + BIO_TYPE_MD = $0008 or $0200; // passive filter + BIO_TYPE_BUFFER = $0009 or $0200; // filter + BIO_TYPE_CIPHER = $00010 or $0200; // filter + BIO_TYPE_BASE64 = $00011 or $0200; // filter + BIO_TYPE_CONNECT = $00012 or $0400 or $0100; // socket - connect + BIO_TYPE_ACCEPT = $00013 or $0400 or $0100; // socket for accept + BIO_TYPE_PROXY_CLIENT = $00014 or $0200; // client proxy BIO + BIO_TYPE_PROXY_SERVER = $00015 or $0200; // server proxy BIO + BIO_TYPE_NBIO_TEST = $00016 or $0200; // server proxy BIO + BIO_TYPE_NULL_FILTER = $00017 or $0200; + BIO_TYPE_BER = $00018 or $0200; // BER -> bin filter + BIO_TYPE_BIO = $00019 or $0400; // (half a; BIO pair + BIO_TYPE_LINEBUFFER = $00020 or $0200; // filter + + BIO_TYPE_DESCRIPTOR = $0100; // socket, fd, connect or accept + BIO_TYPE_FILTER= $0200; + BIO_TYPE_SOURCE_SINK = $0400; + + // BIO ops constants + // BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + // BIO_set_fp(in,stdin,BIO_NOCLOSE); + BIO_NOCLOSE = $00; + BIO_CLOSE = $01; + BIO_FP_READ = $02; + BIO_FP_WRITE = $04; + BIO_FP_APPEND = $08; + BIO_FP_TEXT = $10; + + BIO_C_SET_FD = 104; + BIO_C_GET_FD = 105; + BIO_C_SET_FILENAME = 108; + BIO_CTRL_RESET = 1; // opt - rewind/zero etc + BIO_CTRL_EOF = 2; // opt - are we at the eof + BIO_CTRL_INFO = 3; // opt - extra tit-bits + BIO_CTRL_SET = 4; // man - set the 'IO' type + BIO_CTRL_GET = 5; // man - get the 'IO' type + BIO_CTRL_PUSH = 6; // opt - internal, used to signify change + BIO_CTRL_POP = 7; // opt - internal, used to signify change + BIO_CTRL_GET_CLOSE = 8; // man - set the 'close' on free + BIO_CTRL_SET_CLOSE = 9; // man - set the 'close' on free + BIO_CTRL_PENDING_C = 10; // opt - is their more data buffered + BIO_CTRL_FLUSH = 11; // opt - 'flush' buffered output + BIO_CTRL_DUP = 12; // man - extra stuff for 'duped' BIO + BIO_CTRL_WPENDING = 13; // opt - number of bytes still to write + + BIO_C_GET_MD_CTX = 120; +{ +type + PBIO_METHOD = SslPtr; + PBIO = SslPtr; +} +var + // BIO functions + BIO_new: function(b: PBIO_METHOD): PBIO; cdecl; + BIO_new_fd: function(fd: cint; close_flag: cint): PBIO; cdecl; + BIO_new_file: function(const filename: PCharacter; + const mode: PCharacter): pBIO; cdecl; + BIO_free_all: procedure(b: PBIO); cdecl; + BIO_s_mem: function(): PBIO_METHOD; cdecl; + BIO_s_fd: function: pBIO_METHOD; cdecl; + BIO_s_file: function: pBIO_METHOD; cdecl; + BIO_ctrl_pending: function(b: PBIO): cint; cdecl; + BIO_read: function(b: PBIO; Buf: pbyte; Len: cint): cint; cdecl; + BIO_write: function(b: PBIO; Buf: pbyte; Len: cint): cint; cdecl; + d2i_PKCS12_bio: function(b:PBIO; Pkcs12: SslPtr): SslPtr; cdecl; + BIO_set: function(a: pBIO; _type: pBIO_METHOD): cint; cdecl; + BIO_free: function(a: pBIO): cint; cdecl; + BIO_vfree: procedure(a: pBIO); cdecl; + BIO_push: function(b: pBIO; append: pBIO): pBIO; cdecl; + BIO_pop: function(b: pBIO): pBIO; cdecl; + BIO_ctrl: function(bp: pBIO; cmd: cint; larg: clong; + parg: Pointer): clong; cdecl; + BIO_int_ctrl: function(bp: pBIO; cmd: cint; larg: clong; + iarg: cint): clong; cdecl; + BIO_gets: function(b: pBIO; buf: PCharacter; size: cint): cint; cdecl; + BIO_puts: function(b: pBIO; const buf: PCharacter): cint; cdecl; + BIO_f_base64: function: pBIO_METHOD; cdecl; + +//optional todo: these are probably macros + BIO_set_mem_eof_return: procedure(b: pBIO; v: cint); cdecl; + BIO_set_mem_buf: procedure(b: pBIO; bm: pBUF_MEM; c: cint); cdecl; + BIO_get_mem_ptr: procedure(b: pBIO; var pp: pBUF_MEM); cdecl; + BIO_new_mem_buf: function(buf: pointer; len: cint): pBIO; cdecl; + +function BIO_flush(b: pBIO): cint; +function BIO_get_mem_data(b: pBIO; var pp: PCharacter): clong; +function BIO_get_md_ctx(bp: pBIO; mdcp: Pointer): clong; +function BIO_reset(bp: pBIO): cint; +function BIO_eof(bp: pBIO): cint; +function BIO_set_close(bp: pBIO; c: cint): cint; +function BIO_get_close(bp: pBIO): cint; +function BIO_pending(bp: pBIO): cint; +function BIO_wpending(bp: pBIO): cint; +function BIO_read_filename(bp: pBIO; filename: PCharacter): cint; +function BIO_write_filename(bp: pBIO; filename: PCharacter): cint; +function BIO_append_filename(bp: pBIO; filename: PCharacter): cint; +function BIO_rw_filename(bp: pBIO; filename: PCharacter): cint; +function BIO_set_fd(bp: pBIO; fd: cint; c: cint): clong; +function BIO_get_fd(bp: pBIO; var c: cint): cint; + + +implementation +uses + {$ifdef FPC}dynlibs,{$endif}msedynload; + +function BIO_flush(b: pBIO): cint; +begin + result := BIO_ctrl(b, BIO_CTRL_FLUSH, 0, nil); +end; + +function BIO_get_mem_data(b: pBIO; var pp: PCharacter): clong; +begin + result := BIO_ctrl(b, BIO_CTRL_INFO, 0, @pp); +end; + +function BIO_get_md_ctx(bp: pBIO; mdcp: Pointer): clong; +begin + result := BIO_ctrl(bp, BIO_C_GET_MD_CTX, 0, mdcp); +end; + +function BIO_reset(bp: pBIO): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_RESET, 0, nil); +end; + +function BIO_eof(bp: pBIO): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_EOF, 0, nil); +end; + +function BIO_set_close(bp: pBIO; c: cint): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_SET_CLOSE, c, nil); +end; + +function BIO_get_close(bp: pBIO): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_GET_CLOSE, 0, nil); +end; + +function BIO_pending(bp: pBIO): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_PENDING_C, 0, nil); +end; + +function BIO_wpending(bp: pBIO): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_WPENDING, 0, nil); +end; + +function BIO_read_filename(bp: pBIO; filename: PCharacter): cint; +begin + result := BIO_ctrl(bp, BIO_C_SET_FILENAME, BIO_CLOSE or + BIO_FP_READ, filename); +end; + +function BIO_write_filename(bp: pBIO; filename: PCharacter): cint; +begin + result := BIO_ctrl(bp, BIO_C_SET_FILENAME, BIO_CLOSE or + BIO_FP_WRITE, filename); +end; + +function BIO_append_filename(bp: pBIO; filename: PCharacter): cint; +begin + result := BIO_ctrl(bp, BIO_C_SET_FILENAME, BIO_CLOSE or + BIO_FP_APPEND, filename); +end; + +function BIO_rw_filename(bp: pBIO; filename: PCharacter): cint; +begin + result := BIO_ctrl(bp, BIO_C_SET_FILENAME, BIO_CLOSE or BIO_FP_READ or + BIO_FP_WRITE, filename); +end; + +function BIO_set_fd(bp: pBIO; fd: cint; c: cint): clong; +begin + result:= bio_int_ctrl(bp,bio_c_set_fd,c,fd); +end; + +function BIO_get_fd(bp: pBIO; var c: cint): cint; +begin + result:= bio_ctrl(bp,bio_c_get_fd,0,@c); +end; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..19] of funcinfoty = ( + (n: 'BIO_new'; d: {$ifndef FPC}@{$endif}@BIO_new), + (n: 'BIO_new_fd'; d: {$ifndef FPC}@{$endif}@BIO_new_fd), + (n: 'BIO_free_all'; d: {$ifndef FPC}@{$endif}@BIO_free_all), + (n: 'BIO_s_mem'; d: {$ifndef FPC}@{$endif}@BIO_s_mem), + (n: 'BIO_ctrl_pending'; d: {$ifndef FPC}@{$endif}@BIO_ctrl_pending), + (n: 'BIO_read'; d: {$ifndef FPC}@{$endif}@BIO_read), + (n: 'BIO_write'; d: {$ifndef FPC}@{$endif}@BIO_write), + (n: 'd2i_PKCS12_bio'; d: {$ifndef FPC}@{$endif}@d2i_PKCS12_bio), + (n: 'BIO_new_file'; d: {$ifndef FPC}@{$endif}@BIO_new_file), + (n: 'BIO_set'; d: {$ifndef FPC}@{$endif}@BIO_set), + (n: 'BIO_free'; d: {$ifndef FPC}@{$endif}@BIO_free), + (n: 'BIO_vfree'; d: {$ifndef FPC}@{$endif}@BIO_vfree), + (n: 'BIO_push'; d: {$ifndef FPC}@{$endif}@BIO_push), + (n: 'BIO_pop'; d: {$ifndef FPC}@{$endif}@BIO_pop), + (n: 'BIO_ctrl'; d: {$ifndef FPC}@{$endif}@BIO_ctrl), + (n: 'BIO_gets'; d: {$ifndef FPC}@{$endif}@BIO_gets), + (n: 'BIO_puts'; d: {$ifndef FPC}@{$endif}@BIO_puts), + (n: 'BIO_f_base64'; d: {$ifndef FPC}@{$endif}@BIO_f_base64), + (n: 'BIO_s_fd'; d: {$ifndef FPC}@{$endif}@BIO_s_fd), + (n: 'BIO_s_file'; d: {$ifndef FPC}@{$endif}@BIO_s_file) + ); + funcsopt: array[0..3] of funcinfoty = ( + (n: 'BIO_set_mem_eof_return'; d: {$ifndef FPC}@{$endif}@BIO_set_mem_eof_return), + (n: 'BIO_set_mem_buf'; d: {$ifndef FPC}@{$endif}@BIO_set_mem_buf), + (n: 'BIO_get_mem_ptr'; d: {$ifndef FPC}@{$endif}@BIO_get_mem_ptr), + (n: 'BIO_new_mem_buf'; d: {$ifndef FPC}@{$endif}@BIO_new_mem_buf) + ); + +begin + getprocaddresses(info,funcs); + getprocaddresses(info,funcsopt,true); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopenssldes.pas b/mseide-msegui/lib/common/crypto/mseopenssldes.pas new file mode 100644 index 0000000..554dd12 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopenssldes.pas @@ -0,0 +1,49 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopenssldes; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +type + DES_cblock = array[0..7] of Byte; + PDES_cblock = ^DES_cblock; + des_ks_struct = packed record + ks: DES_cblock; + weak_key: cint; + end; + des_key_schedule = array[0..15] of des_ks_struct; + +var + DES_set_odd_parity: procedure(Key: des_cblock); cdecl; + DES_set_key_checked: function(key: des_cblock; + schedule: des_key_schedule): cint; cdecl; + DES_ecb_encrypt: procedure(Input: des_cblock; output: des_cblock; + ks: des_key_schedule; enc: cint); cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..2] of funcinfoty = ( + (n: 'DES_set_odd_parity'; d: {$ifndef FPC}@{$endif}@DES_set_odd_parity), + (n: 'DES_set_key_checked'; d: {$ifndef FPC}@{$endif}@DES_set_key_checked), + (n: 'DES_ecb_encrypt'; d: {$ifndef FPC}@{$endif}@DES_ecb_encrypt) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopenssldsa.pas b/mseide-msegui/lib/common/crypto/mseopenssldsa.pas new file mode 100644 index 0000000..9b02abd --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopenssldsa.pas @@ -0,0 +1,71 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopenssldsa; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; +type + pDSA = ^DSA; + DSA = record + // This first variable is used to pick up errors where + // a DSA is passed instead of of a EVP_PKEY + pad: cint; + version: cint; + write_params: cint; + p: pointer; + q: pointer; // = 20 + g: pointer; + pub_key: pointer; // y public key + priv_key: pointer; // x private key + kinv: pointer; // Signing pre-calc + r: pointer; // Signing pre-calc + flags: cint; + // Normally used to cache montgomery values + method_mont_p: PCharacter; + references: cint; + ex_data: record + sk: pointer; + dummy: cint; + end; + meth: pointer; + end; + +var + DSA_new: function: pDSA; cdecl; + DSA_free: procedure(r: pDSA); cdecl; + DSA_generate_parameters: function(bits: cint; seed: pointer; + seed_len: cint;var counter_ret: cint; var h_ret: culong; + progress: TProgressCallbackFunction; cb_arg: Pointer): pDSA; cdecl; + DSA_generate_key: function(a: pDSA): cint; cdecl; + d2i_DSAPrivateKey_bio: function(bp: pBIO; dsa: pDSA): pDSA; cdecl; + i2d_DSAPrivateKey_bio: function(bp: pBIO; dsa: pDSA): cint; cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..5] of funcinfoty = ( + (n: 'DSA_new'; d: @DSA_new), + (n: 'DSA_free'; d: @DSA_free), + (n: 'DSA_generate_parameters'; d: @DSA_generate_parameters), + (n: 'DSA_generate_key'; d: @DSA_generate_key), + (n: 'd2i_DSAPrivateKey_bio'; d: @d2i_DSAPrivateKey_bio), + (n: 'i2d_DSAPrivateKey_bio'; d: @i2d_DSAPrivateKey_bio) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslevp.pas b/mseide-msegui/lib/common/crypto/mseopensslevp.pas new file mode 100644 index 0000000..ee80bdd --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslevp.pas @@ -0,0 +1,564 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopensslevp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes,mseopenssldes; +const + EVP_MAX_MD_SIZE = 64; //* longest known is SHA512 */ + EVP_MAX_KEY_LENGTH = 32; + EVP_MAX_IV_LENGTH = 16; + EVP_MAX_BLOCK_LENGTH = 32; + + PKCS5_SALT_LEN = 8; + PKCS5_DEFAULT_ITER = 2048; //* Default PKCS#5 iteration count */ + +//* Values for cipher flags */ + +//* Modes for ciphers */ + + EVP_CIPH_STREAM_CIPHER = $0; + EVP_CIPH_ECB_MODE = $1; + EVP_CIPH_CBC_MODE = $2; + EVP_CIPH_CFB_MODE = $3; + EVP_CIPH_OFB_MODE = $4; + EVP_CIPH_MODE = $7; +//* Set if variable length cipher */ + EVP_CIPH_VARIABLE_LENGTH = $8; +//* Set if the iv handling should be done by the cipher itself */ + EVP_CIPH_CUSTOM_IV = $10; +//* Set if the cipher's init() function should be called if key is NULL */ + EVP_CIPH_ALWAYS_CALL_INIT = $20; +//* Call ctrl() to init cipher parameters */ + EVP_CIPH_CTRL_INIT = $40; +//* Don't use standard key length function */ + EVP_CIPH_CUSTOM_KEY_LENGTH = $80; +//* Don't use standard block padding */ + EVP_CIPH_NO_PADDING = $100; +//* cipher handles random key generation */ + EVP_CIPH_RAND_KEY = $200; + +//* ctrl() values */ + + EVP_CTRL_INIT = $0; + EVP_CTRL_SET_KEY_LENGTH = $1; + EVP_CTRL_GET_RC2_KEY_BITS = $2; + EVP_CTRL_SET_RC2_KEY_BITS = $3; + EVP_CTRL_GET_RC5_ROUNDS = $4; + EVP_CTRL_SET_RC5_ROUNDS = $5; + EVP_CTRL_RAND_KEY = $6; + + +type + MD2_CTX = record + num: cint; + data: array [0..15] of byte; + cksm: array [0..15] of cardinal; + state: array [0..15] of cardinal; + end; + + MD4_CTX = record + A, B, C, D: cardinal; + Nl, Nh: cardinal; + data: array [0..15] of cardinal; + num: cint; + end; + + MD5_CTX = record + A, B, C, D: cardinal; + Nl, Nh: cardinal; + data: array [0..15] of cardinal; + num: cint; + end; + + RIPEMD160_CTX = record + A, B, C, D, E: cardinal; + Nl, Nh: cardinal; + data: array [0..15] of cardinal; + num: cint; + end; + + SHA_CTX = record + h0, h1, h2, h3, h4: cardinal; + Nl, Nh: cardinal; + data: array [0..16] of cardinal; + num: cint; + end; + + MDC2_CTX = record + num: cint; + data: array [0..7] of byte; + h, hh: des_cblock; + pad_type: cint; // either 1 or 2, default 1 + end; + + // Superfluo? No, in EVP_MD ci sono le dimensioni del risultato + pEVP_MD_CTX = ^EVP_MD_CTX; + EVP_MD_CTX = record + digest: pEVP_MD; + case integer of + 0: (base: array [0..3] of byte); + 1: (md2: MD2_CTX); + 8: (md4: MD4_CTX); + 2: (md5: MD5_CTX); + 16: (ripemd160: RIPEMD160_CTX); + 4: (sha: SHA_CTX); + 32: (mdc2: MDC2_CTX); + end; + + pEVP_PKEY = ^EVP_PKEY; + EVP_PKEY_PKEY = record + case integer of + 0: (ptr: pcuchar); + 1: (rsa: pRSA); // ^rsa_st + 2: (dsa: pDSA); // ^dsa_st + 3: (dh: pDH); // ^dh_st + end; + ppEVP_PKEY = ^pEVP_PKEY; + pSTACK_OFX509 = SslPtr; //todo + EVP_PKEY = record //for version 1.0 + _type: cint; + save_type: cint; + references: cint; + ameth: SslPtr; + engine: pENGINE; + pkey: EVP_PKEY_PKEY; + save_parameters: cint; + attributes: pSTACK_OFX509; + end; + + ASN1_TYPE = record //todo + end; + pASN1_TYPE = ^ASN1_TYPE; + + pEVP_CIPHER_CTX = ^EVP_CIPHER_CTX; + EVP_CIPHER = record + nid: cint; + block_size: cint; + key_len: cint; //* Default value for variable length ciphers */ + iv_len: cint; + flags: culong; //* Various flags */ + init: function(ctx: pEVP_CIPHER_CTX; key: pcuchar; iv: pcuchar; + enc: cint): cint; +// int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, +// const unsigned char *iv, int enc); /* init key */ + do_cipher: function (ctx: pEVP_CIPHER_CTX; _out: pcuchar; _in: pcuchar; + inl: cint): cint; //* encrypt/decrypt data */ +// int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, +// const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */ + cleanup: function(ctx: pEVP_CIPHER_CTX): cint; //* cleanup ctx */ +// int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */ + ctx_size: cint; //* how big ctx->cipher_data needs to be */ + set_asn1_parameters: function (ctx: pEVP_CIPHER_CTX; _type: pASN1_TYPE): cint; + //* Populate a ASN1_TYPE with parameters */ +// int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */ + get_asn1_parameters: function(ctx: pEVP_CIPHER_CTX; _type: pASN1_TYPE): cint; + //* Get parameters from a ASN1_TYPE */ +// int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ + ctrl: function(ctx: pEVP_CIPHER_CTX; _type: cint; arg: cint; + ptr: pointer): cint; //* Miscellaneous operations */ +// int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */ + app_data: pointer; //* Application data */ + end; + pEVP_CIPHER = ^EVP_CIPHER; + + pEVP_MD = ^EVP_MD; + EVP_MD = record + _type: cint; + pkey_type: cint; + md_size: cint; + init: pointer; + update: pointer; + final: pointer; + sign: pointer; + verify: pointer; + required_pkey_type: array [0..4] of cint; + block_size: cint; + ctx_size: cint; + end; + ivty = array[0..EVP_MAX_IV_LENGTH-1] of byte; + pENGINE = SslPtr; + EVP_CIPHER_CTX = record + cipher: pEVP_CIPHER; + engine: pENGINE; //* functional reference if 'cipher' is ENGINE-provided */ + encrypt: cint; //* encrypt or decrypt */ + buf_len: cint; //* number we have left */ + + iov: ivty; //* original iv */ + iv: ivty; //* working iv */ + buf: array[0..EVP_MAX_BLOCK_LENGTH-1] of byte; //* saved partial block */ + num: cint; //* used by cfb/ofb mode */ + + app_data: pointer; //* application stuff */ + key_len: cint; //* May change for variable length cipher */ + flags: culong; //* Various flags */ + cipher_data: pointer; //* per EVP data */ + final_used: cint; + block_mask: cint; + final: array[0..EVP_MAX_BLOCK_LENGTH-1] of byte; + //* possible final block */ + end; +// pEVP_CIPHER_CTX = ^EVP_CIPHER_CTX; + +var + EVP_cleanup: procedure; cdecl; + EVP_CIPHER_CTX_init: procedure(ctx: pEVP_CIPHER_CTX); cdecl; + EVP_CIPHER_CTX_cleanup: function(ctx: pEVP_CIPHER_CTX): cint; cdecl; + EVP_CIPHER_CTX_set_padding: function(ctx: pEVP_CIPHER_CTX; + padding: cint): cint; cdecl; + EVP_CIPHER_CTX_set_key_length: function(ctx: pEVP_CIPHER_CTX; + keylen: cint): cint; cdecl; + EVP_get_digestbyname: function(Name: pcchar): pEVP_MD; cdecl; + EVP_get_cipherbyname: function(name: pcchar): pEVP_CIPHER; cdecl; + + EVP_CipherInit: function(ctc: pEVP_CIPHER_CTX; cipher: pEVP_CIPHER; + key: pcuchar; iv: pcuchar; enc: cint): cint; cdecl; + EVP_CipherInit_ex: function(ctx: pEVP_CIPHER_CTX; cipher: pEVP_CIPHER; + impl: pENGINE; key: pcuchar; iv: pcuchar; enc: cint): cint; cdecl; + EVP_CipherUpdate: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; cdecl; + EVP_CipherFinal: function(ctx: pEVP_CIPHER_CTX; outm: pcuchar; + var outl: cint): cint; cdecl; + EVP_CipherFinal_ex: function(ctx: pEVP_CIPHER_CTX; outm: pcuchar; + var outl: cint): cint; cdecl; + + EVP_EncryptInit: function(ctx: pEVP_CIPHER_CTX; _type: pEVP_CIPHER; + key: pcuchar; iv: pcuchar): cint; cdecl; + EVP_EncryptInit_ex: function(ctx: pEVP_CIPHER_CTX; _type: pEVP_CIPHER; + impl: pENGINE; key: pcuchar; iv: pcuchar): cint; cdecl; + EVP_EncryptUpdate: function(ctx: pEVP_CIPHER_CTX;_out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; cdecl; + EVP_EncryptFinal: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint): cint; cdecl; + EVP_EncryptFinal_ex: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint): cint; cdecl; + + EVP_DecryptInit: function(ctx: pEVP_CIPHER_CTX; cipher: pEVP_CIPHER; + key: pcuchar; iv: pcuchar): cint; cdecl; + EVP_DecryptInit_ex: function(ctx: pEVP_CIPHER_CTX; cipher: pEVP_CIPHER; + impl: pENGINE; key: pcuchar; iv: pcuchar): cint; cdecl; + EVP_DecryptUpdate: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; cdecl; + EVP_DecryptFinal: function(ctx: pEVP_CIPHER_CTX; outm: pcuchar; + var outl: cint): cint; cdecl; + EVP_DecryptFinal_ex: function(ctx: pEVP_CIPHER_CTX; outm: pcuchar; + var outl: cint): cint; cdecl; + + EVP_DigestInit: function(ctx: pEVP_MD_CTX; const _type: pEVP_MD): cint; cdecl; + EVP_DigestInit_ex: function(ctx: pEVP_MD_CTX; const _type: pEVP_MD; + impl: pENGINE): cint; cdecl; + EVP_DigestUpdate: function(ctx: pEVP_MD_CTX; const d: Pointer; + cnt: sslsize_t): cint; cdecl; + EVP_DigestFinal: function(ctx: pEVP_MD_CTX; md: pcuchar; + var s: cuint): cint; cdecl; + EVP_DigestFinal_ex: function(ctx: pEVP_MD_CTX; md: pcuchar; + var s: cuint): cint; cdecl; + EVP_SignFinal: function(ctx: pEVP_MD_CTX; sig: pointer; + var s: cuint; key: pEVP_PKEY): cint; cdecl; + EVP_VerifyFinal: function(ctx: pEVP_MD_CTX; sigbuf: pointer; + siglen: cuint; pkey: pEVP_PKEY): cint; cdecl; + + EVP_MD_CTX_copy: function(_out: pEVP_MD_CTX; _in: pEVP_MD_CTX): cint; cdecl; + EVP_CIPHER_CTX_rand_key: function(ctx: pEVP_CIPHER_CTX; + key: pcuchar): cint; cdecl; + + // Hash functions + EVP_md_null: function: pEVP_MD; cdecl; + EVP_md2: function: pEVP_MD; cdecl; //optional! + EVP_md5: function: pEVP_MD; cdecl; + EVP_sha: function: pEVP_MD; cdecl; + EVP_sha1: function: pEVP_MD; cdecl; + EVP_dss: function: pEVP_MD; cdecl; + EVP_dss1: function: pEVP_MD; cdecl; + EVP_mdc2: function: pEVP_MD; cdecl; + EVP_ripemd160: function: pEVP_MD; cdecl; + // Crypt functions + EVP_enc_null: function: pEVP_CIPHER; cdecl; + EVP_des_ecb: function: pEVP_CIPHER; cdecl; + EVP_des_ede: function: pEVP_CIPHER; cdecl; + EVP_des_ede3: function: pEVP_CIPHER; cdecl; + {$ifndef mswindows} + EVP_des_cfb: function: pEVP_CIPHER; cdecl; + EVP_des_ede_cfb: function: pEVP_CIPHER; cdecl; + EVP_des_ede3_cfb: function: pEVP_CIPHER; cdecl; + EVP_des_ofb: function: pEVP_CIPHER; cdecl; + EVP_des_ede_ofb: function: pEVP_CIPHER; cdecl; + EVP_des_ede3_ofb: function: pEVP_CIPHER; cdecl; + EVP_des_cbc: function: pEVP_CIPHER; cdecl; + EVP_des_ede_cbc: function: pEVP_CIPHER; cdecl; + EVP_des_ede3_cbc: function: pEVP_CIPHER; cdecl; + {$endif} + EVP_desx_cbc: function: pEVP_CIPHER; cdecl; + EVP_idea_cbc: function: pEVP_CIPHER; cdecl; + EVP_idea_cfb: function: pEVP_CIPHER; cdecl; + EVP_idea_ecb: function: pEVP_CIPHER; cdecl; + EVP_idea_ofb: function: pEVP_CIPHER; cdecl; + + // EVP Key functions + EVP_PKEY_New: function(): pEVP_PKEY; cdecl; + EVP_PKEY_Free: procedure(pk: pEVP_PKEY); cdecl; + EVP_PKEY_Assign: function(pkey: pEVP_PKEY; _type: cint; + key: pRSA): cint; cdecl; + EVP_PKEY_type: function(keytype: cint): cint; cdecl; + EVP_PKEY_assign_RSA: function(key: pEVP_PKEY; rsa: pRSA): cint; cdecl; + EVP_PKEY_assign_DSA: function(key: pEVP_PKEY; dsa: pDSA): cint; cdecl; + EVP_PKEY_assign_DH: function(key: pEVP_PKEY; dh: pDH): cint; cdecl; + EVP_PKEY_assign_EC_KEY: function(key: pEVP_PKEY; ec: pEC_KEY): cint; cdecl; + EVP_PKEY_set1_RSA: function(key: pEVP_PKEY; rsa: pRSA): cint; cdecl; + EVP_PKEY_set1_DSA: function(key: pEVP_PKEY; dsa: pDSA): cint; cdecl; + EVP_PKEY_set1_DH: function(key: pEVP_PKEY; dh: pDH): cint; cdecl; + EVP_PKEY_set1_EC_KEY: function(key: pEVP_PKEY; ec: pEC_KEY): cint; cdecl; + EVP_PKEY_size: function(key: pEVP_PKEY): cint; cdecl; + EVP_PKEY_get1_RSA: function(key: pEVP_PKEY): pRSA; cdecl; + EVP_PKEY_get1_DSA: function(key: pEVP_PKEY): pDSA; cdecl; + EVP_PKEY_get1_DH: function(key: pEVP_PKEY): pDH; cdecl; + EVP_PKEY_get1_EC_KEY: function(key: pEVP_PKEY): pEC_KEY; cdecl; + // Password prompt for callback function + EVP_set_pw_prompt: procedure(prompt: pcchar);cdecl; + EVP_get_pw_prompt: function: pcchar;cdecl; + // Default callback password function: replace if you want + EVP_read_pw_string: function(buf: pcchar; len: cint; + const prompt: pcchar; verify: cint): cint; cdecl; + EVP_read_pw_string_min: function(buf: pcchar; minlen: cint; maxlen: cint; + prompt: pcchar; verify: cint): cint; cdecl; //openssl 1.0+ + d2i_PrivateKey_bio: function(bp: pBIO; var a: pEVP_PKEY): pEVP_PKEY; cdecl; + d2i_PUBKEY_bio: function(bp: pBIO; var a: pEVP_PKEY): pEVP_PKEY; cdecl; + i2d_PUBKEY_bio: function(bp: pBIO; pkey: pEVP_PKEY): cint; cdecl; + + EVP_MD_type: function(const md: pEVP_MD): cint; cdecl; + EVP_MD_pkey_type: function(const md: pEVP_MD): cint; cdecl; + EVP_MD_block_size: function(const md: pEVP_MD): cint; cdecl; + EVP_MD_flags: function(const md: pEVP_MD): cardinal; cdecl; //openssl 1.0 + + EVP_MD_CTX_md: function(const ctx: pEVP_MD_CTX): pEVP_MD;cdecl; + + EVP_MD_CTX_init: procedure(ctx: pEVP_MD_CTX);cdecl; + EVP_MD_CTX_cleanup: function(ctx: pEVP_MD_CTX): cint;cdecl; + EVP_MD_CTX_create: function: pEVP_MD_CTX;cdecl; + EVP_MD_CTX_destroy: procedure(ctx: pEVP_MD_CTX);cdecl; + + EVP_BytesToKey: function(const _type: pEVP_CIPHER; const md: pEVP_MD; + salt: pcuchar; const data: pcuchar; datalen: cint; + count: cint; key: pcuchar; iv: pcuchar): cint; cdecl; + EVP_SealInit: function(ctx: pEVP_CIPHER_CTX; _type: pEVP_CIPHER; + ek: ppcuchar; ekl: pcint; iv: pcuchar; + pubkey: ppEVP_PKEY; npubk: cint): cint; cdecl; + EVP_SealFinal: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint): cint; cdecl; + EVP_OpenInit: function(ctx: pEVP_CIPHER_CTX;_type: pEVP_CIPHER; + ek: pcuchar; ekl: cint; iv: pcuchar; + priv: pEVP_PKEY): cint; cdecl; + EVP_OpenFinal: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint): cint; cdecl; + +function EVP_SealUpdate(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; +function EVP_OpenUpdate(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; +function EVP_SignInit(ctx: pEVP_MD_CTX; const _type: pEVP_MD): cint; +function EVP_SignUpdate(ctx: pEVP_MD_CTX; const d: Pointer; cnt: cuint): cint; +function EVP_VerifyInit(ctx: pEVP_MD_CTX; const _type: pEVP_MD): cint; +function EVP_VerifyUpdate(ctx: pEVP_MD_CTX; const d: Pointer; cnt: cuint): cint; +function EVP_MD_size(e: pEVP_MD): cint; +function EVP_MD_CTX_size(e: pEVP_MD_CTX): cint; + +function encryptsymkeyrsa(ek: pcuchar; key: pcuchar; key_len: integer; + pubk: pEVP_PKEY): integer; + //like EVP_PKEY_encrypt_old(), -2 if no rsa key, -1 on error +function decryptsymkeyrsa(key: pcuchar; ek: pcuchar; ekl: integer; + priv: pEVP_PKEY): integer; + //like EVP_PKEY_decrypt_old(), -2 if no rsa key, -1 on error + +implementation +uses + msedynload,mseopensslrsa; + +function encryptsymkeyrsa(ek: pcuchar; key: pcuchar; key_len: cint; + pubk: pEVP_PKEY): cint; +begin + result:= -2; + if pubk^._type = EVP_PKEY_RSA then begin + result:= RSA_public_encrypt(key_len,key,ek,EVP_PKEY_get1_RSA(pubk), + RSA_PKCS1_OAEP_PADDING{RSA_PKCS1_PADDING}); + end; +end; + +function decryptsymkeyrsa(key: pcuchar; ek: pcuchar; ekl: integer; + priv: pEVP_PKEY): integer; +begin + result:= -2; + if priv^._type = EVP_PKEY_RSA then begin + result:= RSA_private_decrypt(ekl,ek,key,EVP_PKEY_get1_RSA(priv), + RSA_PKCS1_OAEP_PADDING{RSA_PKCS1_PADDING}); + end; +end; + +function EVP_SealUpdate(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; +begin + result:= evp_encryptupdate(ctx,_out,outl,_in,inl); +end; + +function EVP_OpenUpdate(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; +begin + result:= evp_decryptupdate(ctx,_out,outl,_in,inl); +end; + +function EVP_SignInit(ctx: pEVP_MD_CTX; const _type: pEVP_MD): cint; +begin + result:= EVP_DigestInit(ctx, _type); +end; + +function EVP_SignUpdate(ctx: pEVP_MD_CTX; const d: Pointer; cnt: cardinal): cint; +begin + result:= EVP_DigestUpdate(ctx, d, cnt); +end; + +function EVP_VerifyInit(ctx: pEVP_MD_CTX; const _type: pEVP_MD): cint; +begin + result:= EVP_DigestInit(ctx, _type); +end; + +function EVP_VerifyUpdate(ctx: pEVP_MD_CTX; const d: Pointer; cnt: cardinal): cint; +begin + result:= EVP_DigestUpdate(ctx, d, cnt); +end; + +function EVP_MD_size(e: pEVP_MD): cint; +begin + result := e^.md_size; +end; + +function EVP_MD_CTX_size(e: pEVP_MD_CTX): cint; +begin + result := EVP_MD_size(e^.digest); +end; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0.. {$ifndef mswindows}83{$else}74{$endif}] of funcinfoty = ( + (n: 'EVP_PKEY_new'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_new), + (n: 'EVP_PKEY_free'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_free), + (n: 'EVP_PKEY_assign'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_assign), + (n: 'EVP_CIPHER_CTX_init'; d: {$ifndef FPC}@{$endif}@EVP_CIPHER_CTX_init), + (n: 'EVP_CIPHER_CTX_cleanup'; d: {$ifndef FPC}@{$endif}@EVP_CIPHER_CTX_cleanup), + (n: 'EVP_CIPHER_CTX_set_padding'; d: {$ifndef FPC}@{$endif}@EVP_CIPHER_CTX_set_padding), + (n: 'EVP_CIPHER_CTX_set_key_length'; d: {$ifndef FPC}@{$endif}@EVP_CIPHER_CTX_set_key_length), + (n: 'EVP_cleanup'; d: {$ifndef FPC}@{$endif}@EVP_cleanup), + (n: 'EVP_get_digestbyname'; d: {$ifndef FPC}@{$endif}@EVP_get_digestbyname), + (n: 'EVP_md_null'; d: {$ifndef FPC}@{$endif}@EVP_md_null), + (n: 'EVP_md5'; d: {$ifndef FPC}@{$endif}@EVP_md5), + (n: 'EVP_sha'; d: {$ifndef FPC}@{$endif}@EVP_sha), + (n: 'EVP_sha1'; d: {$ifndef FPC}@{$endif}@EVP_sha1), + (n: 'EVP_dss'; d: {$ifndef FPC}@{$endif}@EVP_dss), + (n: 'EVP_dss1'; d: {$ifndef FPC}@{$endif}@EVP_dss1), + (n: 'EVP_ripemd160'; d: {$ifndef FPC}@{$endif}@EVP_ripemd160), + (n: 'EVP_CipherInit'; d: {$ifndef FPC}@{$endif}@EVP_CipherInit), + (n: 'EVP_CipherInit_ex'; d: {$ifndef FPC}@{$endif}@EVP_CipherInit_ex), + (n: 'EVP_CipherUpdate'; d: {$ifndef FPC}@{$endif}@EVP_CipherUpdate), + (n: 'EVP_CipherFinal'; d: {$ifndef FPC}@{$endif}@EVP_CipherFinal), + (n: 'EVP_CipherFinal_ex'; d: {$ifndef FPC}@{$endif}@EVP_CipherFinal_ex), + (n: 'EVP_EncryptInit'; d: {$ifndef FPC}@{$endif}@EVP_EncryptInit), + (n: 'EVP_EncryptInit_ex'; d: {$ifndef FPC}@{$endif}@EVP_EncryptInit_ex), + (n: 'EVP_EncryptUpdate'; d: {$ifndef FPC}@{$endif}@EVP_EncryptUpdate), + (n: 'EVP_EncryptFinal'; d: {$ifndef FPC}@{$endif}@EVP_EncryptFinal), + (n: 'EVP_EncryptFinal_ex'; d: {$ifndef FPC}@{$endif}@EVP_EncryptFinal_ex), + (n: 'EVP_DecryptInit'; d: {$ifndef FPC}@{$endif}@EVP_DecryptInit), + (n: 'EVP_DecryptInit_ex'; d: {$ifndef FPC}@{$endif}@EVP_DecryptInit_ex), + (n: 'EVP_DecryptUpdate'; d: {$ifndef FPC}@{$endif}@EVP_DecryptUpdate), + (n: 'EVP_DecryptFinal'; d: {$ifndef FPC}@{$endif}@EVP_DecryptFinal), + (n: 'EVP_DecryptFinal_ex'; d: {$ifndef FPC}@{$endif}@EVP_DecryptFinal_ex), + (n: 'EVP_DigestInit'; d: {$ifndef FPC}@{$endif}@EVP_DigestInit), + (n: 'EVP_DigestInit_ex'; d: {$ifndef FPC}@{$endif}@EVP_DigestInit_ex), + (n: 'EVP_DigestUpdate'; d: {$ifndef FPC}@{$endif}@EVP_DigestUpdate), + (n: 'EVP_DigestFinal'; d: {$ifndef FPC}@{$endif}@EVP_DigestFinal), + (n: 'EVP_DigestFinal_ex'; d: {$ifndef FPC}@{$endif}@EVP_DigestFinal_ex), + (n: 'EVP_SignFinal'; d: {$ifndef FPC}@{$endif}@EVP_SignFinal), + (n: 'EVP_VerifyFinal'; d: {$ifndef FPC}@{$endif}@EVP_VerifyFinal), + (n: 'EVP_MD_CTX_copy'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_copy), + (n: 'EVP_enc_null'; d: {$ifndef FPC}@{$endif}@EVP_enc_null), + (n: 'EVP_des_ecb'; d: {$ifndef FPC}@{$endif}@EVP_des_ecb), + (n: 'EVP_des_ede'; d: {$ifndef FPC}@{$endif}@EVP_des_ede), + (n: 'EVP_des_ede3'; d: {$ifndef FPC}@{$endif}@EVP_des_ede3), + {$ifndef mswindows} + (n: 'EVP_des_cfb'; d: {$ifndef FPC}@{$endif}@EVP_des_cfb), + (n: 'EVP_des_ede_cfb'; d: {$ifndef FPC}@{$endif}@EVP_des_ede_cfb), + (n: 'EVP_des_ede3_cfb'; d: {$ifndef FPC}@{$endif}@EVP_des_ede3_cfb), + (n: 'EVP_des_ofb'; d: {$ifndef FPC}@{$endif}@EVP_des_ofb), + (n: 'EVP_des_ede_ofb'; d: {$ifndef FPC}@{$endif}@EVP_des_ede_ofb), + (n: 'EVP_des_ede3_ofb'; d: {$ifndef FPC}@{$endif}@EVP_des_ede3_ofb), + (n: 'EVP_des_cbc'; d: {$ifndef FPC}@{$endif}@EVP_des_cbc), + (n: 'EVP_des_ede_cbc'; d: {$ifndef FPC}@{$endif}@EVP_des_ede_cbc), + (n: 'EVP_des_ede3_cbc'; d: {$ifndef FPC}@{$endif}@EVP_des_ede3_cbc), + {$endif} + (n: 'EVP_desx_cbc'; d: {$ifndef FPC}@{$endif}@EVP_desx_cbc), + (n: 'EVP_get_cipherbyname'; d: {$ifndef FPC}@{$endif}@EVP_get_cipherbyname), + (n: 'EVP_PKEY_type'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_type), + (n: 'EVP_PKEY_set1_RSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_set1_RSA), + (n: 'EVP_PKEY_set1_DSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_set1_DSA), + (n: 'EVP_PKEY_set1_DH'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_set1_DH), + (n: 'EVP_PKEY_set1_EC_KEY'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_set1_EC_KEY), + (n: 'EVP_PKEY_size'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_size), + (n: 'EVP_PKEY_get1_RSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_get1_RSA), + (n: 'EVP_PKEY_get1_DSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_get1_DSA), + (n: 'EVP_PKEY_get1_DH'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_get1_DH), + (n: 'EVP_PKEY_get1_EC_KEY'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_get1_EC_KEY), + (n: 'EVP_set_pw_prompt'; d: {$ifndef FPC}@{$endif}@EVP_set_pw_prompt), + (n: 'EVP_get_pw_prompt'; d: {$ifndef FPC}@{$endif}@EVP_get_pw_prompt), + (n: 'EVP_read_pw_string'; d: {$ifndef FPC}@{$endif}@EVP_read_pw_string), + (n: 'd2i_PrivateKey_bio'; d: {$ifndef FPC}@{$endif}@d2i_PrivateKey_bio), + (n: 'd2i_PUBKEY_bio'; d: {$ifndef FPC}@{$endif}@d2i_PUBKEY_bio), + (n: 'i2d_PUBKEY_bio'; d: {$ifndef FPC}@{$endif}@i2d_PUBKEY_bio), + (n: 'EVP_MD_type'; d: {$ifndef FPC}@{$endif}@EVP_MD_type), + (n: 'EVP_MD_pkey_type'; d: {$ifndef FPC}@{$endif}@EVP_MD_pkey_type), + (n: 'EVP_MD_block_size'; d: {$ifndef FPC}@{$endif}@EVP_MD_block_size), + (n: 'EVP_MD_CTX_md'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_md), + (n: 'EVP_MD_CTX_init'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_init), + (n: 'EVP_MD_CTX_cleanup'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_cleanup), + (n: 'EVP_MD_CTX_create'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_create), + (n: 'EVP_MD_CTX_destroy'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_destroy), + (n: 'EVP_BytesToKey'; d: {$ifndef FPC}@{$endif}@EVP_BytesToKey), + (n: 'EVP_SealInit'; d: {$ifndef FPC}@{$endif}@EVP_SealInit), +// (n: 'EVP_SealUpdate'; d: {$ifndef FPC}@{$endif}@EVP_SealUpdate), //macro + (n: 'EVP_SealFinal'; d: {$ifndef FPC}@{$endif}@EVP_SealFinal), + (n: 'EVP_OpenInit'; d: {$ifndef FPC}@{$endif}@EVP_OpenInit), + (n: 'EVP_OpenFinal'; d: {$ifndef FPC}@{$endif}@EVP_OpenFinal), + (n: 'EVP_CIPHER_CTX_rand_key'; d: {$ifndef FPC}@{$endif}@EVP_CIPHER_CTX_rand_key) +// (n: 'EVP_PKEY_encrypt_old'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_encrypt_old) //version dependent + ); + funcsopt: array[0..10] of funcinfoty = ( + (n: 'EVP_MD_flags'; d: {$ifndef FPC}@{$endif}@EVP_MD_flags), + (n: 'EVP_read_pw_string_min'; d: {$ifndef FPC}@{$endif}@EVP_read_pw_string_min), + (n: 'EVP_md2'; d: {$ifndef FPC}@{$endif}@EVP_md2), + (n: 'EVP_mdc2'; d: {$ifndef FPC}@{$endif}@EVP_mdc2), + (n: 'EVP_idea_cbc'; d: {$ifndef FPC}@{$endif}@EVP_idea_cbc), + (n: 'EVP_idea_ecb'; d: {$ifndef FPC}@{$endif}@EVP_idea_ecb), + (n: 'EVP_idea_ofb'; d: {$ifndef FPC}@{$endif}@EVP_idea_ofb), + (n: 'EVP_PKEY_assign_RSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_assign_RSA), //todo: macros + (n: 'EVP_PKEY_assign_DSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_assign_DSA), + (n: 'EVP_PKEY_assign_DH'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_assign_DH), + (n: 'EVP_PKEY_assign_EC_KEY'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_assign_EC_KEY) + ); + +begin + getprocaddresses(info,funcs); + getprocaddresses(info,funcsopt,true); +end; + +procedure deinit(const info: dynlibinfoty); +begin + evp_cleanup; +end; + +initialization + regopensslinit(@init); + regopenssldeinit(@deinit); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslpem.pas b/mseide-msegui/lib/common/crypto/mseopensslpem.pas new file mode 100644 index 0000000..a258249 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslpem.pas @@ -0,0 +1,85 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopensslpem; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; +var +// PEM functions + PEM_read_bio_RSAPrivateKey: function(bp: pBIO; + x: ppRSA;cb: TPWCallbackFunction; u: pointer): pRSA; cdecl; + PEM_write_bio_RSAPrivateKey: function(bp: pBIO; x: pRSA; + const enc: pEVP_CIPHER; kstr: PCharacter; klen: cint; + cb: TPWCallbackFunction; u: pointer): cint; cdecl; + PEM_read_bio_RSAPublicKey: function(bp: pBIO; x: ppRSA; + cb: TPWCallbackFunction; u: pointer): pRSA; cdecl; + PEM_write_bio_RSAPublicKey: function(bp: pBIO; x: pRSA): cint; cdecl; + PEM_read_bio_DSAPrivateKey: function(bp: pBIO; dsa: ppDSA; + cb: TPWCallbackFunction; data: pointer): pDSA; cdecl; + PEM_write_bio_DSAPrivateKey: function(bp: pBIO; dsa: pDSA; + const enc: pEVP_CIPHER; kstr: PCharacter; klen: cint; + cb: TPWCallbackFunction; data: pointer): cint; cdecl; + PEM_read_bio_PUBKEY: function(bp: pBIO; x: ppEVP_PKEY; + cb: TPWCallbackFunction; u: pointer): pEVP_PKEY; cdecl; + PEM_write_bio_PUBKEY: function(bp: pBIO; x: pEVP_PKEY): cint; cdecl; + PEM_read_bio_X509: function(bp: pBIO; x: ppX509; cb: TPWCallbackFunction; + u: pointer): pX509; cdecl; + PEM_write_bio_X509: function(bp: pBIO; x: pX509): cint; cdecl; + PEM_read_bio_X509_AUX: function(bp: pBIO; x: ppX509; + cb: TPWCallbackFunction; u: pointer): pX509; cdecl; + PEM_write_bio_X509_AUX: function(bp: pBIO; x: pX509): cint; cdecl; + PEM_read_bio_X509_REQ: function(bp: pBIO; x: ppX509_REQ; + cb: TPWCallbackFunction; u: pointer): pX509_REQ; cdecl; + PEM_write_bio_X509_REQ: function(bp: pBIO; x: pX509_REQ): cint; cdecl; + PEM_read_bio_X509_CRL: function(bp: pBIO; x: ppX509_CRL; + cb: TPWCallbackFunction; u: pointer): pX509_CRL; cdecl; + PEM_write_bio_X509_CRL: function(bp: pBIO; x: pX509_CRL): cint; cdecl; + PEM_read_bio_PrivateKey: function(bp: pBIO; x: ppEVP_PKEY; + cb: TPWCallbackFunction; u: pointer): pEVP_PKEY; cdecl; + PEM_write_bio_PrivateKey: function(bp: pBIO; x: pEVP_PKEY; + const enc: pEVP_CIPHER; kstr: PCharacter; klen: cint; + cb: TPWCallbackFunction; u: pointer): cint; cdecl; + PEM_write_bio_PKCS7: function(bp: pBIO; x: pPKCS7): cint; cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..18] of funcinfoty = ( + (n: 'PEM_read_bio_RSAPrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_RSAPrivateKey), + (n: 'PEM_write_bio_RSAPrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_RSAPrivateKey), + (n: 'PEM_read_bio_RSAPublicKey'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_RSAPublicKey), + (n: 'PEM_write_bio_RSAPublicKey'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_RSAPublicKey), + (n: 'PEM_read_bio_DSAPrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_DSAPrivateKey), + (n: 'PEM_write_bio_DSAPrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_DSAPrivateKey), + (n: 'PEM_read_bio_PUBKEY'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_PUBKEY), + (n: 'PEM_write_bio_PUBKEY'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_PUBKEY), + (n: 'PEM_read_bio_X509'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_X509), + (n: 'PEM_write_bio_X509'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_X509), + (n: 'PEM_read_bio_X509_AUX'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_X509_AUX), + (n: 'PEM_write_bio_X509_AUX'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_X509_AUX), + (n: 'PEM_read_bio_X509_REQ'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_X509_REQ), + (n: 'PEM_write_bio_X509_REQ'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_X509_REQ), + (n: 'PEM_read_bio_X509_CRL'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_X509_CRL), + (n: 'PEM_write_bio_X509_CRL'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_X509_CRL), + (n: 'PEM_read_bio_PrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_PrivateKey), + (n: 'PEM_write_bio_PrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_PrivateKey), + (n: 'PEM_write_bio_PKCS7'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_PKCS7) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslpkcs.pas b/mseide-msegui/lib/common/crypto/mseopensslpkcs.pas new file mode 100644 index 0000000..c6963f3 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslpkcs.pas @@ -0,0 +1,173 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopensslpkcs; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +type + + pSTACK_OFPKCS7_SIGNER_INFO = pointer; + + pPKCS7_signed = ^PKCS7_signed; + PKCS7_signed = record + version: pASN1_cint; + md_algs: pointer; // ^STACK_OF(X509_ALGOR) + cert: pointer; // ^STACK_OF(X509) + crl: pointer; // ^STACK_OF(X509_CRL) + signer_info: pSTACK_OFPKCS7_SIGNER_INFO; + contents: pointer; // ^struct pkcs7_st + end; + + pPKCS7_signedandenveloped = ^PKCS7_signedandenveloped; + PKCS7_signedandenveloped = record + version: pASN1_cint; + md_algs: pointer; // ^STACK_OF(X509_ALGOR) + cert: pointer; // ^STACK_OF(X509) + crl: pointer; // ^STACK_OF(X509_CRL) + signer_info: pSTACK_OFPKCS7_SIGNER_INFO; + enc_data: pointer; // ^PKCS7_ENC_CONTENT + recipientinfo: pointer; // ^STACK_OF(PKCS7_RECIP_INFO) + end; + + pPKCS7 = ^PKCS7; + PKCS7 = record + asn1: PCharacter; + length: cint; + state: cint; + detached: cint; + asn1_type: pointer; // ^ASN1_OBJECT + case integer of + 0: (ptr: pASN1_OCTET_STRING); + 1: (data: pointer); // ^PKCS7_SIGNED + 2: (sign: pPKCS7_signed); // ^PKCS7_SIGNED + 3: (enveloped: pointer); // ^PKCS7_ENVELOPE + 4: (signed_and_enveloped: pPKCS7_signedandenveloped); + 5: (digest: pointer); // ^PKCS7_DIGEST + 6: (encrypted: pointer); // ^PKCS7_ENCRYPT + 7: (other: pointer); // ^ASN1_TYPE + end; + + pPKCS12 = ^PKCS12; + PKCS12 = record + version: pointer; + mac: pointer; + authsafes: pPKCS7; + end; + + pPKCS8_Priv_Key_Info = ^PKCS8_Priv_Key_Info; + PKCS8_Priv_Key_Info = record + broken: cint; // Flag for various broken formats */ + version: pASN1_INTEGER; + pkeyalg: Pointer; // X509_ALGOR *pkeyalg; + pkey: Pointer; // ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */ + attributes: Pointer; // STACK_OF(X509_ATTRIBUTE) *attributes; + end; + +var +// PKCS#5 functions + PKCS5_PBKDF2_HMAC_SHA1: function(pass: PCharacter; passlen: cint; + salt: pointer; saltlen: cint; iter: cint; + keylen: cint; u: pointer): cint; cdecl; +// PKCS#7 functions + PKCS7_sign: function(signcert: pX509; pkey: pEVP_PKEY; certs: pointer; + data: pBIO; flags: cint): pPKCS7; cdecl; + PKCS7_get_signer_info: function(p7: pPKCS7): pSTACK_OFPKCS7_SIGNER_INFO; cdecl; + PKCS7_verify: function(p7: pPKCS7; certs: pointer; store: pSTACK_OFX509; + indata: pBIO; _out: pBIO; flags: cint): cint; cdecl; + PKCS7_get0_signers: function(p7: pPKCS7; certs: pSTACK_OFX509; + flags: cint): pSTACK_OFX509; cdecl; + PKCS7_signatureVerify: function(bio: pBIO; p7: pPKCS7; si: pPKCS7_SIGNER_INFO; + x509: pX509): cint; cdecl; + PKCS7_encrypt: function(certs: pSTACK_OFX509; _in: pBIO; + cipher: pEVP_CIPHER; flags: cint): pPKCS7; cdecl; + PKCS7_decrypt: function(p7: pPKCS7; pkey: pEVP_PKEY; cert: pX509; + data: pBIO; flags: cint): cint; cdecl; + PKCS7_free: procedure(p7: pPKCS7); cdecl; + PKCS7_ctrl: function(p7: pPKCS7; cmd: cint; larg: clong; + parg: PCharacter): clong; cdecl; + PKCS7_dataInit: function(p7: pPKCS7; bio: pBIO): pBIO; cdecl; +// PKCS#7 DER/PEM to internal conversion function +{ + d2i_PKCS7_DIGEST @737 + d2i_PKCS7_ENCRYPT @738 + d2i_PKCS7_ENC_CONTENT @739 + d2i_PKCS7_ENVELOPE @740 + d2i_PKCS7_ISSUER_AND_SERIAL @741 + d2i_PKCS7_RECIP_INFO @742 + d2i_PKCS7_SIGNED @743 + d2i_PKCS7_SIGNER_INFO @744 + d2i_PKCS7_SIGN_ENVELOPE @745 } + EVP_PKCS82PKEY: function(p8 : pPKCS8_Priv_Key_Info) : pEVP_PKEY; cdecl; + PKCS8_decrypt: function(p8: pX509_SIG; + Pass: PCharacter; PassLen: cint): pPKCS8_Priv_Key_Info; cdecl; + PKCS8_PRIV_KEY_INFO_free: procedure(var a: pPKCS8_Priv_Key_Info); cdecl; + PKCS12_new: function: pPKCS12; cdecl; + PEM_read_bio_PKCS7: function(bp: pBIO; data: pointer; + cb: TPWCallbackFunction; u: pointer): pPKCS7; cdecl; + PKCS12_parse: function(p12: SslPtr; pass: pchar; pkey, + cert, ca: pSslPtr): cint; cdecl; + PKCS12_free: procedure(p12: SslPtr); cdecl; + i2d_PKCS12_bio: function(bp: pBIO; pkcs12: pPKCS12): cint; cdecl; + d2i_PKCS7: function(var a: pPKCS7; pp: pointer; + length: clong): pPKCS7; cdecl; + d2i_PKCS7_bio: function(bp: pBIO; p7: pPKCS7): pPKCS7; cdecl; + i2d_PKCS7_bio: function(bp: pBIO; p7: pPKCS7): cint; cdecl; + d2i_PKCS8_bio: function(bp: pBIO; p8: pX509_SIG): pX509_SIG; cdecl; + d2i_PKCS8_PRIV_KEY_INFO: function(var a: pPKCS8_Priv_Key_Info; pp: PCharacter; + Length: clong): pPKCS8_Priv_Key_Info; cdecl; + +function PKCS7_get_detached(p7: pPKCS7): pointer; + +implementation +uses + msedynload; + +function PKCS7_get_detached(p7: pPKCS7): pointer; +begin + result := pointer(PKCS7_ctrl(p7, 2, 0, nil)); +end; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..23] of funcinfoty = ( + (n: 'PKCS5_PBKDF2_HMAC_SHA1'; d: @PKCS5_PBKDF2_HMAC_SHA1), + (n: 'PKCS7_sign'; d: @PKCS7_sign), + (n: 'PKCS7_get_signer_info'; d: @PKCS7_get_signer_info), + (n: 'PKCS7_verify'; d: @PKCS7_verify), + (n: 'PKCS7_get0_signers'; d: @PKCS7_get0_signers), + (n: 'PKCS7_signatureVerify'; d: @PKCS7_signatureVerify), + (n: 'PKCS7_encrypt'; d: @PKCS7_encrypt), + (n: 'PKCS7_decrypt'; d: @PKCS7_decrypt), + (n: 'PKCS7_free'; d: @PKCS7_free), + (n: 'PKCS7_ctrl'; d: @PKCS7_ctrl), + (n: 'PKCS7_dataInit'; d: @PKCS7_dataInit), + (n: 'EVP_PKCS82PKEY'; d: @EVP_PKCS82PKEY), + (n: 'PKCS8_decrypt'; d: @PKCS8_decrypt), + (n: 'PKCS8_PRIV_KEY_INFO_free'; d: @PKCS8_PRIV_KEY_INFO_free), + (n: 'PKCS12_new'; d: @PKCS12_new), + (n: 'PEM_read_bio_PKCS7'; d: @PEM_read_bio_PKCS7), + (n: 'PKCS12_parse'; d: @PKCS12_parse), + (n: 'PKCS12_free'; d: @PKCS12_free), + (n: 'i2d_PKCS12_bio'; d: @i2d_PKCS12_bio), + (n: 'd2i_PKCS7'; d: @d2i_PKCS7), + (n: 'd2i_PKCS7_bio'; d: @d2i_PKCS7_bio), + (n: 'i2d_PKCS7_bio'; d: @i2d_PKCS7_bio), + (n: 'd2i_PKCS8_bio'; d: @d2i_PKCS8_bio), + (n: 'd2i_PKCS8_PRIV_KEY_INFO'; d: @d2i_PKCS8_PRIV_KEY_INFO) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslrand.pas b/mseide-msegui/lib/common/crypto/mseopensslrand.pas new file mode 100644 index 0000000..b7ce1fe --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslrand.pas @@ -0,0 +1,67 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopensslrand; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +var + // pseudo-random number generator (PRNG) functions + RAND_seed: procedure(const buf: pointer; num: cint); cdecl; + RAND_add: procedure(const buf: pointer; num: cint; entropy: double); cdecl; + RAND_status: function: cint; cdecl; + // RAND_event: function(UINT iMsg, WPARAM wParam, LPARAM lParam): cint; cdecl; + RAND_file_name: function(buf: PCharacter; size_t: cardinal): PCharacter; cdecl; + RAND_load_file: function(const filename: PCharacter; max_bytes: clong): cint; cdecl; + RAND_write_file: function(const filename: PCharacter): cint; cdecl; + + RAND_set_rand_engine: function(engine: pENGINE): cint; cdecl; + + RAND_bytes: function(buf: pbyte; num: cint): cint; cdecl; + RAND_pseudo_bytes: function(buf: pbyte; num: cint): cint; cdecl; + + RAND_egd: function(path: pchar): cint; cdecl; + + RAND_set_rand_method: procedure(meth: pRAND_METHOD); cdecl; + RAND_get_rand_method: function(): pRAND_METHOD; cdecl; + RAND_SSLeay: function(): pRAND_METHOD; cdecl; + + RAND_cleanup: procedure(); cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..13] of funcinfoty = ( + (n: 'RAND_seed'; d: {$ifndef FPC}@{$endif}@RAND_seed), + (n: 'RAND_add'; d: {$ifndef FPC}@{$endif}@RAND_add), + (n: 'RAND_status'; d: {$ifndef FPC}@{$endif}@RAND_status), + (n: 'RAND_file_name'; d: {$ifndef FPC}@{$endif}@RAND_file_name), + (n: 'RAND_load_file'; d: {$ifndef FPC}@{$endif}@RAND_load_file), + (n: 'RAND_write_file'; d: {$ifndef FPC}@{$endif}@RAND_write_file), + (n: 'RAND_set_rand_engine'; d: {$ifndef FPC}@{$endif}@RAND_set_rand_engine), + (n: 'RAND_bytes'; d: {$ifndef FPC}@{$endif}@RAND_bytes), + (n: 'RAND_pseudo_bytes'; d: {$ifndef FPC}@{$endif}@RAND_pseudo_bytes), + (n: 'RAND_egd'; d: {$ifndef FPC}@{$endif}@RAND_egd), + (n: 'RAND_set_rand_method'; d: {$ifndef FPC}@{$endif}@RAND_set_rand_method), + (n: 'RAND_get_rand_method'; d: {$ifndef FPC}@{$endif}@RAND_get_rand_method), + (n: 'RAND_SSLeay'; d: {$ifndef FPC}@{$endif}@RAND_SSLeay), + (n: 'RAND_cleanup'; d: {$ifndef FPC}@{$endif}@RAND_cleanup) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslrsa.pas b/mseide-msegui/lib/common/crypto/mseopensslrsa.pas new file mode 100644 index 0000000..d0ae420 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslrsa.pas @@ -0,0 +1,120 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopensslrsa; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +const + RSA_PKCS1_PADDING = 1; + RSA_SSLV23_PADDING = 2; + RSA_NO_PADDING = 3; + RSA_PKCS1_OAEP_PADDING = 4; + RSA_X931_PADDING = 5; +//* EVP_PKEY_ only */ + RSA_PKCS1_PSS_PADDING = 6; + + RSA_PKCS1_PADDING_SIZE = 11; + +type + pRSA_METHOD = pointer; + RSA = record + // The first parameter is used to pickup errors where + // this is passed instead of aEVP_PKEY, it is set to 0 + pad: cint; + version: cint; + meth: pRSA_METHOD; + n: pBIGNUM; + e: pBIGNUM; + d: pBIGNUM; + p: pBIGNUM; + q: pBIGNUM; + dmp1: pBIGNUM; + dmq1: pBIGNUM; + iqmp: pBIGNUM; + // be careful using this if the RSA structure is shared + ex_data: CRYPTO_EX_DATA; + references: cint; + flags: cint; + // Used to cache montgomery values + _method_mod_n: pBN_MONT_CTX; + _method_mod_p: pBN_MONT_CTX; + _method_mod_q: pBN_MONT_CTX; + // all BIGNUM values are actually in the following data, if it is not + // NULL + bignum_data: ^byte; + blinding: pBN_BLINDING; + end; + pRSA = ^RSA; + +var + // RSA function + RSA_new: function: pRSA; cdecl; + RSA_free: procedure(r: pRSA); cdecl; + RSA_new_method: function(method: pRSA_METHOD): pRSA; cdecl; + RSA_size: function(pkey: pRSA): cint; cdecl; + RSA_check_key: function(arg0: pRSA): cint; cdecl; + RSA_public_encrypt: function(flen: cint; from: pcuchar; _to: pcuchar; + rsa: pRSA; padding: cint): cint; cdecl; + RSA_private_encrypt: function(flen: cint; from: pcuchar; _to: pcuchar; + rsa: pRSA; padding: cint): cint; cdecl; + RSA_public_decrypt: function(flen: cint; from: pcuchar; _to: pcuchar; + rsa: pRSA; padding: cint): cint; cdecl; + RSA_private_decrypt: function(flen: cint; from: pcuchar; _to: pcuchar; + rsa: pRSA; padding: cint): cint; cdecl; + RSA_flags: function(r: pRSA): cint; cdecl; + RSA_set_default_method: procedure(meth: pRSA_METHOD); cdecl; + RSA_get_default_method: function: pRSA_METHOD; cdecl; + RSA_get_method: function(rsa: pRSA): pRSA_METHOD; cdecl; + RSA_set_method: function(rsa: pRSA; meth: pRSA_METHOD): pRSA_METHOD; cdecl; + RSA_memory_lock: function(r: pRSA):cint; cdecl; + RSA_PKCS1_SSLeay: function: pRSA_METHOD; cdecl; + ERR_load_RSA_strings: procedure;cdecl; + RSA_generate_key: function(bits, e: cint; + callback: PFunction; cb_arg: SslPtr): PRSA; cdecl; + d2i_RSAPrivateKey_bio: function(bp: pBIO; rsa: pRSA): pRSA; cdecl; + i2d_RSAPrivateKey_bio: function(bp: pBIO; rsa: pRSA): cint; cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..19] of funcinfoty = ( + (n: 'RSA_new'; d: {$ifndef FPC}@{$endif}@RSA_new), + (n: 'RSA_free'; d: {$ifndef FPC}@{$endif}@RSA_free), + (n: 'RSA_new_method'; d: {$ifndef FPC}@{$endif}@RSA_new_method), + (n: 'RSA_size'; d: {$ifndef FPC}@{$endif}@RSA_size), + (n: 'RSA_check_key'; d: {$ifndef FPC}@{$endif}@RSA_check_key), + (n: 'RSA_public_encrypt'; d: {$ifndef FPC}@{$endif}@RSA_public_encrypt), + (n: 'RSA_private_encrypt'; d: {$ifndef FPC}@{$endif}@RSA_private_encrypt), + (n: 'RSA_public_decrypt'; d: {$ifndef FPC}@{$endif}@RSA_public_decrypt), + (n: 'RSA_private_decrypt'; d: {$ifndef FPC}@{$endif}@RSA_private_decrypt), + (n: 'RSA_flags'; d: {$ifndef FPC}@{$endif}@RSA_flags), + (n: 'RSA_set_default_method'; d: {$ifndef FPC}@{$endif}@RSA_set_default_method), + (n: 'RSA_get_default_method'; d: {$ifndef FPC}@{$endif}@RSA_get_default_method), + (n: 'RSA_get_method'; d: {$ifndef FPC}@{$endif}@RSA_get_method), + (n: 'RSA_set_method'; d: {$ifndef FPC}@{$endif}@RSA_set_method), + (n: 'RSA_memory_lock'; d: {$ifndef FPC}@{$endif}@RSA_memory_lock), + (n: 'RSA_PKCS1_SSLeay'; d: {$ifndef FPC}@{$endif}@RSA_PKCS1_SSLeay), + (n: 'ERR_load_RSA_strings'; d: {$ifndef FPC}@{$endif}@ERR_load_RSA_strings), + (n: 'RSA_generate_key'; d: {$ifndef FPC}@{$endif}@RSA_generate_key), + (n: 'd2i_RSAPrivateKey_bio'; d: {$ifndef FPC}@{$endif}@d2i_RSAPrivateKey_bio), + (n: 'i2d_RSAPrivateKey_bio'; d: {$ifndef FPC}@{$endif}@i2d_RSAPrivateKey_bio) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslsmime.pas b/mseide-msegui/lib/common/crypto/mseopensslsmime.pas new file mode 100644 index 0000000..e97232a --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslsmime.pas @@ -0,0 +1,38 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopensslsmime; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +var +// SMIME function + SMIME_write_PKCS7: function(bp: pBIO; p7: pPKCS7; + data: pBIO; flags: cint): cint; cdecl; + SMIME_read_PKCS7: function(bp: pBIO; var bcont: pBIO): pPKCS7; cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..1] of funcinfoty = ( + (n: 'SMIME_write_PKCS7'; d: @SMIME_write_PKCS7), + (n: 'SMIME_read_PKCS7'; d: @SMIME_read_PKCS7) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. \ No newline at end of file diff --git a/mseide-msegui/lib/common/crypto/mseopensslx509.pas b/mseide-msegui/lib/common/crypto/mseopensslx509.pas new file mode 100644 index 0000000..6097b9a --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslx509.pas @@ -0,0 +1,386 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopensslx509; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +type + pEVP_PKEY = SslPtr; //todo + pASN1_OBJECT = SslPtr; + pASN1_STRING = SslPtr; + pASN1_TIME = SslPtr; + +const + X509_V_OK = 0; + X509_V_ILLEGAL = 1; + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 2; + X509_V_ERR_UNABLE_TO_GET_CRL = 3; + X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE = 4; + X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE = 5; + X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY = 6; + X509_V_ERR_CERT_SIGNATURE_FAILURE = 7; + X509_V_ERR_CRL_SIGNATURE_FAILURE = 8; + X509_V_ERR_CERT_NOT_YET_VALID = 9; + X509_V_ERR_CERT_HAS_EXPIRED = 10; + X509_V_ERR_CRL_NOT_YET_VALID = 11; + X509_V_ERR_CRL_HAS_EXPIRED = 12; + X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 13; + X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = 14; + X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD = 15; + X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 16; + X509_V_ERR_OUT_OF_MEM = 17; + X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 18; + X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN = 19; + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 20; + X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 21; + X509_V_ERR_CERT_CHAIN_TOO_LONG = 22; + X509_V_ERR_CERT_REVOKED = 23; + X509_V_ERR_INVALID_CA = 24; + X509_V_ERR_PATH_LENGTH_EXCEEDED = 25; + X509_V_ERR_INVALID_PURPOSE = 26; + X509_V_ERR_CERT_UNTRUSTED = 27; + X509_V_ERR_CERT_REJECTED = 28; + //These are 'informational' when looking for issuer cert + X509_V_ERR_SUBJECT_ISSUER_MISMATCH = 29; + X509_V_ERR_AKID_SKID_MISMATCH = 30; + X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH = 31; + X509_V_ERR_KEYUSAGE_NO_CERTSIGN = 32; + X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER = 33; + X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION = 34; + //The application is not happy + X509_V_ERR_APPLICATION_VERIFICATION = 50; + +type + pX509_NAME_ENTRY = ^X509_NAME_ENTRY; + X509_NAME_ENTRY = record + obj: pASN1_OBJECT; + value: pASN1_STRING; + _set: cint; + size: cint; // temp variable + end; + + pX509_NAME = ^X509_NAME; + pDN = ^X509_NAME; + X509_NAME = record + entries: pointer; + modified: cint; + bytes: pointer; + hash: cardinal; + end; + + pX509_VAL = ^X509_VAL; + X509_VAL = record + notBefore: pASN1_TIME; + notAfter: pASN1_TIME; + end; + + pX509_CINF = ^X509_CINF; + X509_CINF = record + version: pointer; + serialNumber: pointer; + signature: pointer; + issuer: pointer; + validity: pX509_VAL; + subject: pointer; + key: pointer; + issuerUID: pointer; + subjectUID: pointer; + extensions: pointer; + end; + + pX509 = ^X509; + X509 = record + cert_info: pX509_CINF; + sig_alg: pointer; // ^X509_ALGOR + signature: pointer; // ^ASN1_BIT_STRING + valid: cint; + references: cint; + name: PCharacter; + ex_data: CRYPTO_EX_DATA; + ex_pathlen: cint; + ex_flags: cint; + ex_kusage: cint; + ex_xkusage: cint; + ex_nscert: cint; + skid: pASN1_OCTET_STRING; + akid: pointer; // ? + sha1_hash: array [0..SHA_DIGEST_LENGTH-1] of char; + aux: pointer; // ^X509_CERT_AUX + end; + + pX509V3_CTX = pointer; + + pX509_REQ = ^X509_REQ; + pX509_REQ_INFO = ^X509_REQ_INFO; + X509_REQ_INFO = record + asn1: pointer; + length: cint; + version: pointer; + subject: pX509_NAME; + pubkey: pointer; + attributes: pointer; + req_kludge: cint; + end; + X509_REQ = record + req_info: pX509_REQ_INFO; + sig_alg: pointer; + signature: pointer; + references: cint; + end; + + pX509_EXTENSION = ^X509_EXTENSION; + X509_EXTENSION = record + obj: pASN1_OBJECT; + critical: Smallint; + netscape_hack: Smallint; + value: pASN1_OCTET_STRING; + method: pointer; // struct v3_ext_method *: V3 method to use + ext_val: pointer; // extension value + end; + pSTACK_OFX509_EXTENSION = pointer; + + pX509_CRL = pointer; + + pX509_SIG = ^X509_SIG; + X509_SIG = record + algor: Pointer; // X509_ALGOR *algor; + digest: pASN1_OCTET_STRING; + end; + + pX509_STORE_CTX = pointer; + // Certificate verification callback + TCertificateVerifyFunction = function(ok: cint; ctx: pX509_STORE_CTX): cint; cdecl; + + pSTACK_OFX509 = pointer; + pX509_STORE = ^X509_STORE; + pX509_LOOKUP = pointer; + pSTACK_OF509LOOKUP = pointer; + pX509_LOOKUP_METHOD = pointer; + X509_STORE = record + cache: cint; + objs: pSTACK_OFX509; + get_cert_methods: pSTACK_OF509LOOKUP; + verify: pointer; // function called to verify a certificate + verify_cb: TCertificateVerifyFunction; + ex_data: pointer; + references: cint; + depth: cint; + end; + +var + X509_new: function(): PX509; cdecl; + X509_free: procedure(x: PX509); cdecl; + X509_NAME_oneline: function(a: PX509_NAME; + buf: pchar; size: cint): pchar; cdecl; + X509_Get_Subject_Name: function(a: PX509):PX509_NAME; cdecl; + X509_Get_Issuer_Name: function(a: PX509):PX509_NAME; cdecl; + X509_NAME_hash: function(x: PX509_NAME):longword; cdecl; +// function SSL_X509Digest(data: PX509; _type: PEVP_MD; md: PChar; +// len: Pcint):cint; cdecl; + X509_digest: function(data: PX509; _type: PEVP_MD; md: pchar; + len: pcint):cint; cdecl; + X509_print: function(b: PBIO; a: PX509): cint; cdecl; + X509_set_version: function(x: PX509; version: cint): cint; cdecl; + X509_set_pubkey: function(x: PX509; pkey: pEVP_PKEY): cint; cdecl; + X509_set_issuer_name: function(x: PX509; name: PX509_NAME): cint; cdecl; + X509_NAME_add_entry_by_txt: function(name: PX509_NAME; field: pchar; + _type: cint; bytes: pbyte; len, loc, _set: cint): cint; cdecl; + X509_sign: function(x: PX509; pkey: pEVP_PKEY; const md: PEVP_MD): cint; cdecl; + X509_gmtime_adj: function(s: PASN1_UTCTIME; adj: cint): PASN1_UTCTIME; cdecl; + X509_set_NotBefore: function(x: PX509; tm: PASN1_UTCTIME): cint; cdecl; + X509_set_NotAfter: function(x: PX509; tm: PASN1_UTCTIME): cint; cdecl; + X509_get_serialNumber: function(x: PX509): PASN1_INTEGER; cdecl; + +// X.509 names (DN) + X509_NAME_new: function: pX509_NAME; cdecl; + X509_NAME_free: procedure(x:pX509_NAME) cdecl; + X509_NAME_get_entry: function(name: pX509_NAME; + loc: cint): pX509_NAME_ENTRY; cdecl; + X509_NAME_get_text_by_NID: function(name: pX509_NAME; nid: cint; + buf: PCharacter; len: cint): cint; cdecl; +// X.509 function + X509_load_cert_file: function(ctx: pX509_LOOKUP; + const filename: PCharacter; _type: cint): cint; cdecl; + X509_get1_email: function(x: pX509): pSTACK; cdecl; + X509_get_pubkey: function(a: pX509): pEVP_PKEY; cdecl; + X509_check_private_key: function(x509: pX509; pkey: pEVP_PKEY): cint; cdecl; + X509_check_purpose: function(x: pX509; id: cint; ca: cint): cint; cdecl; + X509_issuer_and_serial_cmp: function(a: pX509; b: pX509): cint; cdecl; + X509_issuer_and_serial_hash: function(a: pX509): cardinal; cdecl; + X509_verify_cert: function(ctx: pX509_STORE_CTX): cint; cdecl; + X509_verify_cert_error_string: function(n: clong): PCharacter; cdecl; + X509_email_free: procedure(sk: pSTACK); cdecl; + X509_get_ext: function(x: pX509; loc: cint): pX509_EXTENSION; cdecl; + X509_get_ext_by_NID: function(x: pX509; nid, lastpos: cint): cint; cdecl; + X509_get_ext_d2i: function(x: pX509; nid: cint; + var crit, idx: cint): pointer; cdecl; + X509V3_EXT_d2i: function(ext: pX509_EXTENSION): pointer; cdecl; + X509V3_EXT_i2d: function(ext_nid: cint; crit: cint; ext_struc: pointer): + pX509_EXTENSION; cdecl; + X509V3_EXT_conf_nid: function(conf: pointer; ctx: pointer; + ext_nid: cint; value: PCharacter): pX509_EXTENSION; cdecl; + X509_set_subject_name: function(x: pX509; name: pX509_NAME): cint; cdecl; + X509V3_set_ctx: procedure(ctx: pX509V3_CTX; issuer: pX509; + subject: pX509; req: pX509_REQ; crl: pX509_CRL; flags: cint); + X509_SIG_free: procedure(a: pX509_SIG); cdecl; + X509_PUBKEY_get: function(key: pointer): pEVP_PKEY; cdecl; + X509_REQ_new: function: pX509_REQ; cdecl; + X509_REQ_free: procedure(req: pX509_REQ); cdecl; + X509_REQ_set_version: function(req: pX509_REQ; version: clong): cint; cdecl; + X509_REQ_set_subject_name: function(req: pX509_REQ; + name: pX509_NAME): cint; cdecl; + X509_REQ_add1_attr_by_txt: function(req: pX509_REQ; attrname: PCharacter; + asn1_type: cint; bytes: pointer; len: cint): cint; cdecl; + X509_REQ_add_extensions: function(req: pX509_REQ; + exts: pSTACK_OFX509_EXTENSION): cint; cdecl; + X509_REQ_set_pubkey: function(req: pX509_REQ; pkey: pEVP_PKEY): cint; cdecl; + X509_REQ_get_pubkey: function(req: pX509_REQ): pEVP_PKEY; cdecl; + X509_REQ_sign: function(req: pX509_REQ; pkey: pEVP_PKEY; + const md: pEVP_MD): cint; cdecl; +// X.509 collections + X509_STORE_new: function: pX509_STORE; cdecl; + X509_STORE_free: procedure(v: pX509_STORE); cdecl; + X509_STORE_add_cert: function(ctx: pX509_STORE; x: pX509): cint; cdecl; + X509_STORE_add_lookup: function(v: pX509_STORE; + m: pX509_LOOKUP_METHOD): pX509_LOOKUP; cdecl; + X509_STORE_CTX_new: function: pX509_STORE_CTX; cdecl; + X509_STORE_CTX_free: procedure(ctx: pX509_STORE); cdecl; + X509_STORE_CTX_init: procedure(ctx: pX509_STORE_CTX; + store: pX509_STORE; x509: pX509; chain: pSTACK_OFX509); cdecl; + X509_STORE_CTX_get_current_cert: function(ctx: pX509_STORE_CTX): pX509; cdecl; + X509_STORE_CTX_get_error: function(ctx: pX509_STORE_CTX): cint; cdecl; + X509_STORE_CTX_get_error_depth: function(ctx: pX509_STORE_CTX): cint; cdecl; + X509_LOOKUP_new: function(method: pX509_LOOKUP_METHOD): pX509_LOOKUP; cdecl; + X509_LOOKUP_init: function(ctx: pX509_LOOKUP): cint; cdecl; + X509_LOOKUP_free: procedure(ctx: pX509_LOOKUP); cdecl; + X509_LOOKUP_ctrl: function(ctx: pX509_LOOKUP; cmd: cint; + const argc: PCharacter; argl: clong; ret: pointer): cint; cdecl; + X509_LOOKUP_file: function: pX509_LOOKUP_METHOD; cdecl; + d2i_X509_REQ_bio: function(bp: pBIO; req: pX509_REQ): pX509_REQ; cdecl; + i2d_X509_REQ_bio: function(bp: pBIO; req: pX509_REQ): cint; cdecl; + d2i_X509_bio: function(bp: pBIO; x509: pX509): pX509; cdecl; + +function X509_get_version(x: pX509): cint; +function X509_get_notBefore(a: pX509): pASN1_TIME; +function X509_get_notAfter(a: pX509): pASN1_TIME; +function X509_REQ_get_version(req: pX509_REQ): cint; +function X509_REQ_get_subject_name(req: pX509_REQ): pX509_NAME; + +implementation +uses + msedynload,mseopensslasn; + +function X509_get_version(x: pX509): cint; +begin + result := ASN1_INTEGER_get(x^.cert_info^.version); +end; + +function X509_get_notBefore(a: pX509): pASN1_TIME; +begin + result := a^.cert_info^.validity^.notBefore; +end; + +function X509_get_notAfter(a: pX509): pASN1_TIME; +begin + result := a^.cert_info^.validity^.notAfter; +end; + +function X509_REQ_get_version(req: pX509_REQ): cint; +begin + result := ASN1_INTEGER_get(req^.req_info^.version); +end; + +function X509_REQ_get_subject_name(req: pX509_REQ): pX509_NAME; +begin + result := req^.req_info^.subject; +end; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..67] of funcinfoty = ( + (n: 'X509_new'; d: @X509_new), + (n: 'X509_free'; d: @X509_free), + (n: 'X509_NAME_oneline'; d: @X509_NAME_oneline), + (n: 'X509_get_subject_name'; d: @X509_get_subject_name), + (n: 'X509_get_issuer_name'; d: @X509_get_issuer_name), + (n: 'X509_NAME_hash'; d: @X509_NAME_hash), + (n: 'X509_digest'; d: @X509_digest), + (n: 'X509_print'; d: @X509_print), + (n: 'X509_set_version'; d: @X509_set_version), + (n: 'X509_set_pubkey'; d: @X509_set_pubkey), + (n: 'X509_set_issuer_name'; d: @X509_set_issuer_name), + (n: 'X509_NAME_add_entry_by_txt'; d: @X509_NAME_add_entry_by_txt), + (n: 'X509_sign'; d: @X509_sign), + (n: 'X509_gmtime_adj'; d: @X509_gmtime_adj), + (n: 'X509_set_notBefore'; d: @X509_set_notBefore), + (n: 'X509_set_notAfter'; d: @X509_set_notAfter), + (n: 'X509_get_serialNumber'; d: @X509_set_notAfter), + (n: 'X509_NAME_new'; d: @X509_NAME_new), + (n: 'X509_NAME_free'; d: @X509_NAME_free), + (n: 'X509_NAME_get_entry'; d: @X509_NAME_get_entry), + (n: 'X509_NAME_get_text_by_NID'; d: @X509_NAME_get_text_by_NID), + (n: 'X509_load_cert_file'; d: @X509_load_cert_file), + (n: 'X509_get1_email'; d: @X509_get1_email), + (n: 'X509_get_pubkey'; d: @X509_get_pubkey), + (n: 'X509_check_private_key'; d: @X509_check_private_key), + (n: 'X509_check_purpose'; d: @X509_check_purpose), + (n: 'X509_issuer_and_serial_cmp'; d: @X509_issuer_and_serial_cmp), + (n: 'X509_issuer_and_serial_hash'; d: @X509_issuer_and_serial_hash), + (n: 'X509_verify_cert'; d: @X509_verify_cert), + (n: 'X509_verify_cert_error_string'; d: @X509_verify_cert_error_string), + (n: 'X509_email_free'; d: @X509_email_free), + (n: 'X509_get_ext'; d: @X509_get_ext), + (n: 'X509_get_ext_by_NID'; d: @X509_get_ext_by_NID), + (n: 'X509_get_ext_d2i'; d: @X509_get_ext_d2i), + (n: 'X509V3_EXT_d2i'; d: @X509V3_EXT_d2i), + (n: 'X509V3_EXT_i2d'; d: @X509V3_EXT_i2d), + (n: 'X509V3_EXT_conf_nid'; d: @X509V3_EXT_conf_nid), + (n: 'X509_set_subject_name'; d: @X509_set_subject_name), + (n: 'X509V3_set_ctx'; d: @X509V3_set_ctx), + (n: 'X509_SIG_free'; d: @X509_SIG_free), + (n: 'X509_PUBKEY_get'; d: @X509_PUBKEY_get), + (n: 'X509_REQ_new'; d: @X509_REQ_new), + (n: 'X509_REQ_free'; d: @X509_REQ_free), + (n: 'X509_REQ_set_version'; d: @X509_REQ_set_version), + (n: 'X509_REQ_set_subject_name'; d: @X509_REQ_set_subject_name), + (n: 'X509_REQ_add1_attr_by_txt'; d: @X509_REQ_add1_attr_by_txt), + (n: 'X509_REQ_add_extensions'; d: @X509_REQ_add_extensions), + (n: 'X509_REQ_set_pubkey'; d: @X509_REQ_set_pubkey), + (n: 'X509_REQ_get_pubkey'; d: @X509_REQ_get_pubkey), + (n: 'X509_REQ_sign'; d: @X509_REQ_sign), + (n: 'X509_STORE_new'; d: @X509_STORE_new), + (n: 'X509_STORE_free'; d: @X509_STORE_free), + (n: 'X509_STORE_add_cert'; d: @X509_STORE_add_cert), + (n: 'X509_STORE_add_lookup'; d: @X509_STORE_add_lookup), + (n: 'X509_STORE_CTX_new'; d: @X509_STORE_CTX_new), + (n: 'X509_STORE_CTX_free'; d: @X509_STORE_CTX_free), + (n: 'X509_STORE_CTX_init'; d: @X509_STORE_CTX_init), + (n: 'X509_STORE_CTX_get_current_cert'; d: @X509_STORE_CTX_get_current_cert), + (n: 'X509_STORE_CTX_get_error'; d: @X509_STORE_CTX_get_error), + (n: 'X509_STORE_CTX_get_error_depth'; d: @X509_STORE_CTX_get_error_depth), + (n: 'X509_LOOKUP_new'; d: @X509_LOOKUP_new), + (n: 'X509_LOOKUP_init'; d: @X509_LOOKUP_init), + (n: 'X509_LOOKUP_free'; d: @X509_LOOKUP_free), + (n: 'X509_LOOKUP_ctrl'; d: @X509_LOOKUP_ctrl), + (n: 'X509_LOOKUP_file'; d: @X509_LOOKUP_file), + (n: 'd2i_X509_REQ_bio'; d: @d2i_X509_REQ_bio), + (n: 'i2d_X509_REQ_bio'; d: @i2d_X509_REQ_bio), + (n: 'd2i_X509_bio'; d: @d2i_X509_bio) + ); + +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/msessl.pas b/mseide-msegui/lib/common/crypto/msessl.pas new file mode 100644 index 0000000..2f3e117 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msessl.pas @@ -0,0 +1,1076 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msessl; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msecryptio,mseopenssl,mseopensslevp,mseopensslrand, + msestrings,msesystypes,msecryptohandler,msetypes,msesys, + msestream; + +type + essl = class(ecryptoio) + end; + + ssldataty = record + ssl: pssl; + mutex: mutexty; + end; + + sslinfoty = record + case integer of + 0: (d: ssldataty); + 1: (_bufferspace: cryptodataty); + end; + {$if sizeof(ssldataty) > sizeof(cryptodataty)} + {$error 'buffer overflow'} + {$ifend} + + sslprotocolty = (ssp_sslv2,ssp_sslv3,ssp_tlsv1); + sslprotocolsty = set of sslprotocolty; +const + defaultsslprotocols = [ssp_sslv2,ssp_sslv3,ssp_tlsv1]; + defaultcipherlist = 'DEFAULT'; + defaultkeygeniterationcount = 1{5}; //same as openssl enc + +type + + tssl = class(tcryptoio) + private + fctx: pssl_ctx; + fprotocols: sslprotocolsty; + fcipherlist: tstringlist; + fcertfile: filenamety; + fprivkeyfile: filenamety; + procedure ctxchanged; + procedure setcipherlist(const avalue: tstringlist); + protected + class procedure internalunlink(var ainfo: cryptoioinfoty); override; + class procedure internalthreadterminate; override; + class procedure connect(var ainfo: cryptoioinfoty; + const atimeoutms: integer); override; + class procedure accept(var ainfo: cryptoioinfoty; const atimeoutms: integer); override; + class function write(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; override; + class function read(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure link(const arxfd,atxfd: integer; + out ainfo: cryptoioinfoty); override; + published + property protocols: sslprotocolsty read fprotocols write fprotocols + default defaultsslprotocols; + property cipherlist: tstringlist read fcipherlist write setcipherlist; + property certfile: filenamety read fcertfile write fcertfile; + property privkeyfile: filenamety read fprivkeyfile write fprivkeyfile; + end; + + digeststatety = (ds_inited{,ds_final}); + digeststatesty = set of digeststatety; + + digesthandlerdatadty = record + ctx: pevp_md_ctx; + md: pevp_md; + state: digeststatesty; +// digest: pointer; //string + end; + pdigesthandlerdatadty = ^digesthandlerdatadty; + {$if sizeof(digesthandlerdatadty) > sizeof(cryptohandlerdataty)} + {$error 'buffer overflow'} + {$ifend} + digesthandlerdataty = record + case integer of + 0: (d: digesthandlerdatadty;); + 1: (_bufferspace: cryptohandlerdataty;); + end; + + tdigesthandler = class; + +// digesteventty = procedure(const sender: tdigesthandler; +// const astream: tmsefilestream; const adigest: string) of object; + + tdigesthandler = class(tbasecryptohandler) + private + fdigestname: string; +// fondigest: digesteventty; + protected +// procedure finalizeclient(var aclient: cryptoclientinfoty); override; +// procedure dofinal(var aclient: cryptoclientinfoty); + procedure checkerror(const err: cryptoerrorty = cerr_error); override; + procedure open(var aclient: cryptoclientinfoty); override; + procedure close(var aclient: cryptoclientinfoty); override; + function read(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; override; + function write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; override; + function seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; override; + procedure restartdigest(var aclient: cryptoclientinfoty); + public + function digest(const astream: tmsefilestream): string; + published + property digestname: string read fdigestname write fdigestname; +// property ondigest: digesteventty read fondigest write fondigest; + end; + + cipherkindty = (ckt_stream, + ckt_ecb, //electronic codebook + ctk_cbc, //cipher-block chaining + ctk_cfb, //cipher feedback + ctk_ofb);//output feedback + +// padbufty = array[0..3*evp_max_block_length-1] of byte; + keybufty = array[0..evp_max_key_length-1] of byte; + ivbufty = array[0..evp_max_iv_length-1] of byte; +// blockbufty = array[0..evp_max_block_length-1] of byte; + + sslhandlerdatadty = record + p: paddedhandlerdatadty; + ctx: pevp_cipher_ctx; + cipher: pevp_cipher; + digest: pevp_md; + keybuf: ^keybufty; + ivbuf: ^ivbufty; + end; + psslhandlerdatadty = ^sslhandlerdatadty; + {$if sizeof(sslhandlerdatadty) > sizeof(cryptohandlerdataty)} + {$error 'buffer overflow'} + {$ifend} + sslhandlerdataty = record + case integer of + 0: (d: sslhandlerdatadty;); + 1: (_bufferspace: cryptohandlerdataty;); + end; + + getkeyeventty = procedure(const sender: tobject; + var akey,asalt: string) of object; + + opensslcryptooptionty = (sslco_salt,sslco_canrestart); + //stores key and iv for seek(0) + opensslcryptooptionsty = set of opensslcryptooptionty; +const + defaultopensslcryptooptions = [sslco_salt]; + +type + tcustomopensslcryptohandler = class(tpaddedcryptohandler) + private + fciphername: string; + fkey: string; + fsalt: string; + fkeyphrase: msestring; + fongetkey: getkeyeventty; + fkeylength: integer; + foptions: opensslcryptooptionsty; + procedure setkeyphrase(const avalue: msestring); + protected + procedure clearerror; {$ifdef FPC}inline;{$endif} + procedure checkerror(const err: cryptoerrorty = cerr_error); override; + procedure cipherupdate(var aclient: cryptoclientinfoty; + const source: pbyte; const sourcelen: integer; + const dest: pbyte; out destlen: integer); override; + procedure cipherfinal(var aclient: cryptoclientinfoty; + const dest: pbyte; out destlen: integer); override; + procedure initcipher(var aclient: cryptoclientinfoty); virtual; abstract; + procedure restartcipher(var aclient: cryptoclientinfoty); override; + procedure getkey(out akey: string; out asalt: string); virtual; + procedure initializedata(var aclient: cryptoclientinfoty); override; + procedure finalizedata(var aclient: cryptoclientinfoty); override; + function padbufsize: integer; override; + public + constructor create(aowner: tcomponent); override; + property key: string read fkey write fkey; + property options: opensslcryptooptionsty read foptions + write foptions default defaultopensslcryptooptions; + property ciphername: string read fciphername write fciphername; + property keyphrase: msestring read fkeyphrase write setkeyphrase; + property keylength: integer read fkeylength write fkeylength default 0; + //bits, 0 -> use cipher default + property ongetkey: getkeyeventty read fongetkey write fongetkey; + end; +{ + asymkeyfileheader = record + symkeylen: integer; + symkey: array[0..0] of byte; //encrypted, variable length + iv: array[0..0] of byte; //variable length, cipher dependent + end; +} + tsymciphercryptohandler = class(tcustomopensslcryptohandler) + private + fkeydigestname: string; + fkeygeniterationcount: integer; + protected + procedure initcipher(var aclient: cryptoclientinfoty); override; + published + constructor create(aowner: tcomponent); override; + property salt: string read fsalt write fsalt; + property keydigestname: string read fkeydigestname write fkeydigestname; + //default md5 + property keygeniterationcount: integer read fkeygeniterationcount + write fkeygeniterationcount default defaultkeygeniterationcount; + property options; + property ciphername; +// property keydigestname; +// property keygeniterationcount; + property keyphrase; + property keylength; + property ongetkey; + end; + + tasymciphercryptohandler = class(tcustomopensslcryptohandler) + private + fprivkeyfile: filenamety; + fpubkeyfile: filenamety; + protected + procedure initcipher(var aclient: cryptoclientinfoty); override; + published + property privkeyfile: filenamety read fprivkeyfile write fprivkeyfile; + property pubkeyfile: filenamety read fpubkeyfile write fpubkeyfile; + //use '"first" "second" "third"' for multiple + property options; + property ciphername; +// property keydigestname; +// property keygeniterationcount; + property keyphrase; + property keylength; + property ongetkey; + end; + +getkeydataeventty = procedure(out akey: string; out asalt: string) of object; + +function waitforio(const aerror: integer; var ainfo: cryptoioinfoty; + const atimeoutms: integer; + const resultpo: pinteger = nil): boolean; +function filebio(const aname: filenamety; + const aopenmode: fileopenmodety): pbio; +procedure closebio(const abio: pbio); +function readpubkey(const aname: filenamety): pevp_pkey; +function readprivkey(const aname: filenamety; + const getkey: getkeydataeventty): pevp_pkey; +procedure freekey(const akey: pevp_pkey); +function messagedigest(const adata: string; const digestname: string): string; + +implementation +uses + sysutils,msesysintf1,msefileutils,msesocketintf,mseopensslbio,mseopensslpem, + mseopensslrsa,msebits, + msesysintf,msectypes; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure raisesslerror(const err: cryptoerrorty); +const + buffersize = 200; +var + int1: integer; + str1,str2: string; +begin + str1:= ''; + setlength(str2,buffersize); + while true do begin + int1:= err_get_error(); + if int1 = 0 then begin + break; + end; + err_error_string_n(int1,pointer(str2),buffersize); + if str1 <> '' then begin + str1:= str1 + lineend; + end; + str1:= str1 + pchar(str2); + end; + if str1 <> '' then begin + raise essl.create(ansistring(cryptoerrormessages[err])+lineend+str1); + end; +end; + +procedure raiseerror(errco : integer; const amessage: string = ''); +var + buf: array [0..255] of char; + str1: string; +begin + if amessage = '' then begin + str1:= 'SSL error.'; + end + else begin + str1:= amessage; + end; + repeat + err_error_string_n(errco,@buf,sizeof(buf)); + str1:= str1 + lineend + buf; + errco:= err_get_error(); + until errco = 0; + raise essl.create(str1); +end; + +procedure sslerror(const aerror: integer); +begin + if aerror <> 1 then begin + raiseerror(err_get_error()); + end; +end; + +procedure cryptoerror(const aerror: cryptoerrorty); +var + int1: integer; +begin + int1:= err_get_error(); + if int1 <> 0 then begin + raiseerror(int1,ansistring(cryptoerrormessages[aerror])); + end; +end; + +function filebio(const aname: filenamety; + const aopenmode: fileopenmodety): pbio; +var + str1,str2: string; +begin + str1:= stringtoutf8ansi(tosysfilepath(filepath(aname))); + case aopenmode of + fm_write: begin + str2:= 'a+'; //-> append, not supported + end; + fm_readwrite: begin + str2:= 'r+'; + end; + fm_create: begin + str2:= 'w+'; + end; + fm_append: begin + str2:= 'a+'; //sets write filepointer to end! + end + else begin + str2:= 'r'; //fm_read, fm none + end; + end; + result:= bio_new_file(pchar(str1),pchar(str2)); + if result = nil then begin + cryptoerror(cerr_nobio); + end; +end; +{ +function filebio(const aname: filenamety; + const aopenmode: fileopenmodety): pbio; +var + fd: integer; +begin + syserror(sys_openfile(aname,aopenmode,[],[],fd)); + result:= bio_new_fd(fd,1); + if result = nil then begin + cryptoerror(cerr_nobio); + end; +end; +} +{ +function streambio(const aname: filenamety; + const aopenmode: fileopenmodety): pbio; +var + fd: integer; + file1: pfile; + str1: string; +begin + syserror(sys_openfile(aname,aopenmode,[],[],fd)); + file1:= fdopen(fd,pchar(str1); + if file1 = nil then begin + syserror(syelasterror); + end; + bio_new(bio_s_file); + if bio_set +end; +} +procedure closebio(const abio: pbio); +begin + bio_free_all(abio); +end; + +function readpubkey(const aname: filenamety): pevp_pkey; +var + bio: pbio; +begin + bio:= filebio(aname,fm_read); + result:= pem_read_bio_pubkey(bio,nil,nil,nil); + closebio(bio); + if result = nil then begin + cryptoerror(cerr_nopubkey); + end; +end; + +function cb(buf: pcuchar; size: cint; rwflag: cint; u: pointer): cint; cdecl; +var + key,iv: string; +begin + getkeydataeventty(u^)(key,iv); + if length(key) > size then begin + setlength(key,size); + end; + result:= length(key); + move(key[1],buf^,result); +end; + +function readprivkey(const aname: filenamety; + const getkey: getkeydataeventty): pevp_pkey; +var + bio: pbio; +begin + bio:= filebio(aname,fm_read); + result:= pem_read_bio_privatekey(bio,nil,@cb,@getkey); + closebio(bio); + if result = nil then begin + cryptoerror(cerr_noprivkey); + end; +end; + +procedure freekey(const akey: pevp_pkey); +begin + if akey <> nil then begin + evp_pkey_free(akey); + end; +end; + +function checknilerror(const avalue: pointer; + const err: cryptoerrorty = cerr_error): pointer; + {$ifdef FPC} inline;{$endif} +begin + result:= avalue; + if avalue = nil then begin + raisesslerror(err); + end; +end; + +function checknullerror(const avalue: integer; + const err: cryptoerrorty = cerr_error): integer; + {$ifdef FPC} inline;{$endif} +begin + result:= avalue; + if avalue = 0 then begin + raisesslerror(err); + end; +end; + +function messagedigest(const adata: string; const digestname: string): string; +var + ctx: pevp_md_ctx; + md: pevp_md; + int1: integer; + str1: string; +begin + initsslinterface; + ctx:= checknilerror(evp_md_ctx_create()); + try + md:= checknilerror(evp_get_digestbyname(pointer(pchar(digestname)))); + checknullerror(evp_digestinit_ex(ctx,md,nil)); + checknullerror(evp_digestupdate(ctx,pointer(adata),length(adata))); + setlength(str1,evp_max_md_size); + checknullerror(evp_digestfinal_ex(ctx,pointer(str1),cardinal(int1))); + setlength(str1,int1); + result:= str1; + finally + evp_md_ctx_destroy(ctx); + end; +end; + +{ tssl } + +constructor tssl.create(aowner: tcomponent); +begin + fprotocols:= defaultsslprotocols; + fcipherlist:= tstringlist.create; + fcipherlist.text:= defaultcipherlist; + inherited; +end; + +destructor tssl.destroy; +begin + inherited; + if fctx <> nil then begin + ssl_ctx_free(fctx); + fctx:= nil; + end; + fcipherlist.free; +end; + +procedure tssl.ctxchanged; +begin + if fctx <> nil then begin + + end; +end; + +procedure tssl.link(const arxfd,atxfd: integer; out ainfo: cryptoioinfoty); +var + int1: integer; + str1: string; +begin + inherited; + if fctx = nil then begin + initsslinterface; + fctx:= ssl_ctx_new(sslv23_method()); + if fctx = nil then begin + sslerror(0); + end; + ctxchanged; + end; + with ainfo,sslinfoty(cryptodata).d do begin + ssl:= ssl_new(fctx); + if ssl = nil then begin + sslerror(0); + end; + sys_mutexcreate(mutex); + int1:= 0; + if not (ssp_sslv2 in fprotocols) then begin + int1:= int1 or ssl_op_no_sslv2; + end; + if not (ssp_sslv3 in fprotocols) then begin + int1:= int1 or ssl_op_no_sslv3; + end; + if not (ssp_tlsv1 in fprotocols) then begin + int1:= int1 or ssl_op_no_tlsv1; + end; + if int1 <> 0 then begin + ssl_set_options(ssl,int1); + end; + str1:= ''; + for int1:= 0 to fcipherlist.count - 1 do begin + str1:= str1 + fcipherlist[int1] + ':'; + end; + setlength(str1,length(str1)-1); + sslerror(ssl_set_cipher_list(ssl,pchar(str1))); + if fcertfile <> '' then begin + str1:= ansistring(tosysfilepath(filepath(fcertfile))); + sslerror(ssl_use_certificate_file(ssl,pchar(str1),ssl_filetype_pem)); + end; + if fprivkeyfile <> '' then begin + str1:= ansistring(tosysfilepath(filepath(fprivkeyfile))); + sslerror(ssl_use_privatekey_file(ssl,pchar(str1),ssl_filetype_pem)); + end; + sslerror(ssl_set_rfd(ssl,rxfd)); + sslerror(ssl_set_wfd(ssl,txfd)); + end; +end; + +class procedure tssl.internalunlink(var ainfo: cryptoioinfoty); +begin //todo: shutdown + with ainfo,sslinfoty(cryptodata).d do begin + if ssl <> nil then begin + ssl_free(ssl); + end; + sys_mutexdestroy(mutex); + end; + inherited; +end; + +class procedure tssl.internalthreadterminate; +begin + err_remove_state(0); + inherited; +end; + +function {tssl.}waitforio(const aerror: integer; var ainfo: cryptoioinfoty; + const atimeoutms: integer; const resultpo: pinteger = nil): boolean; +var + int1: integer; + err1: syserrorty; + pollres: pollkindsty; +begin + with ainfo,sslinfoty(cryptodata).d do begin + sys_mutexunlock(mutex); + result:= (aerror > 0); + if not result then begin + if aerror < 0 then begin + err1:= sye_ok; + int1:= ssl_get_error(ssl,aerror); + if (int1 = ssl_error_want_read) then begin + if atimeoutms >= 0 then begin + err1:= soc_poll(rxfd,[poka_read],atimeoutms,pollres); + end; + end + else begin + if (int1 = ssl_error_want_write) then begin + if atimeoutms >= 0 then begin + err1:= soc_poll(txfd,[poka_write],atimeoutms,pollres); + end; + end + else begin + raiseerror(int1); + end; + end; + if err1 <> sye_ok then begin + syserror(err1); + end; + end + else begin + sslerror(aerror); + end; + end; + end; + if resultpo <> nil then begin + if (atimeoutms < 0) and (aerror < 0) then begin + resultpo^:= 0; + end + else begin + resultpo^:= aerror; + end; + end; +end; + +class procedure tssl.connect(var ainfo: cryptoioinfoty; + const atimeoutms: integer); +//var +// int1,int2: integer; +// err1: syserrorty; +begin + with ainfo,sslinfoty(cryptodata).d do begin + repeat + sys_mutexlock(mutex); + until waitforio(ssl_connect(ssl),ainfo,atimeoutms); + end; +end; + +class procedure tssl.accept(var ainfo: cryptoioinfoty; + const atimeoutms: integer); +//var +// int1{,int2}: integer; +// err1: syserrorty; +begin + with ainfo,sslinfoty(cryptodata).d do begin + repeat + sys_mutexlock(mutex); + until waitforio(ssl_accept(ssl),ainfo,atimeoutms); + end; +end; + +procedure tssl.setcipherlist(const avalue: tstringlist); +begin + fcipherlist.assign(avalue); +end; + +class function tssl.write(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; +begin + with ainfo,sslinfoty(cryptodata).d do begin + try + repeat + sys_mutexlock(mutex); + until waitforio(ssl_write(ssl,buffer,count),ainfo,atimeoutms,@result); + except + result:= -1; + end; + end; +end; + +class function tssl.read(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; +var + pollres: pollkindsty; +begin + result:= 0; + with ainfo,sslinfoty(cryptodata).d do begin + try + if (atimeoutms < 0) or + (soc_poll(ainfo.rxfd,[poka_read],atimeoutms,pollres) = sye_ok) then begin + repeat + sys_mutexlock(mutex); + until waitforio(ssl_read(ssl,buffer,count),ainfo,atimeoutms,@result) or + (atimeoutms < 0); + end; + except + result:= -1; + end; + end; +end; + +{ tcustomopensslcryptohandler } + +constructor tcustomopensslcryptohandler.create(aowner: tcomponent); +begin + foptions:= defaultopensslcryptooptions; + inherited; +end; + +procedure tcustomopensslcryptohandler.clearerror; +begin + err_clear_error(); +end; + +procedure tcustomopensslcryptohandler.checkerror(const err: cryptoerrorty); +begin + raisesslerror(err); +end; + +procedure tcustomopensslcryptohandler.initializedata( + var aclient: cryptoclientinfoty); +var + int1: integer; +begin + inherited; + initsslinterface; + with sslhandlerdataty(aclient.handlerdata).d do begin + getmem(ctx,sizeof(ctx^)); + evp_cipher_ctx_init(ctx); + getmem(keybuf,sizeof(keybuf^)); + getmem(ivbuf,sizeof(ivbuf^)); + + cipher:= checknilerror(evp_get_cipherbyname(pcchar(pchar(fciphername))), + cerr_ciphernotfound); + checknullerror(evp_cipherinit_ex(ctx,cipher,nil,nil,nil,p.mode), + cerr_cipherinit); + if fkeylength <> 0 then begin + int1:= fkeylength div 8; + if int1 > evp_max_key_length then begin + error(cerr_invalidkeylength); + end; + checknullerror(evp_cipher_ctx_set_key_length(ctx,int1)); + if (ctx^.key_len * 8 <> fkeylength) then begin + error(cerr_invalidkeylength); + end; + end; +{ if (mode = 0) and (cipher^.block_size > 1) then begin + finalizedata(sslhandlerdataty(aclient.handlerdata).d); + error(cerr_invalidblocksize); //todo: implement block ciphers + end; +} + initcipher(aclient); + p.blocksize:= ctx^.cipher^.block_size; + if not (sslco_canrestart in foptions) then begin + fillchar(keybuf^,sizeof(keybuf^),0); + fillchar(ivbuf^,sizeof(ivbuf^),0); + end; + end; +end; + +procedure tcustomopensslcryptohandler.finalizedata( + var aclient: cryptoclientinfoty); +var + data1: psslhandlerdatadty; +begin + inherited; + data1:= @sslhandlerdataty(aclient.handlerdata).d; + with data1^ do begin + if ctx <> nil then begin + evp_cipher_ctx_cleanup(ctx); + freemem(ctx); + end; + if keybuf <> nil then begin + fillchar(keybuf^,sizeof(keybuf^),0); + freemem(keybuf); + end; + if ivbuf <> nil then begin + fillchar(ivbuf^,sizeof(ivbuf^),0); + freemem(ivbuf); + end; + end; + fillchar(data1^,sizeof(data1^),0); +end; + +procedure tcustomopensslcryptohandler.restartcipher( + var aclient: cryptoclientinfoty); +begin + if not (sslco_canrestart in foptions) then begin + error(cerr_cannotrestart); + end; + inherited; + with sslhandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_cipherinit_ex(ctx,nil,nil,pointer(keybuf), + pointer(ivbuf),p.mode),cerr_cipherinit); + ctx^.iv:= ctx^.iov; + end; +end; + +procedure tcustomopensslcryptohandler.setkeyphrase(const avalue: msestring); +begin + fkey:= stringtoutf8ansi(avalue); + fkeyphrase:= avalue; +end; + +procedure tcustomopensslcryptohandler.getkey(out akey: string; out asalt: string); +begin + akey:= fkey; + asalt:= fsalt; + if canevent(tmethod(fongetkey)) then begin + fongetkey(self,akey,asalt); + end; +end; + +procedure tcustomopensslcryptohandler.cipherupdate( + var aclient: cryptoclientinfoty;const source: pbyte; + const sourcelen: integer; const dest: pbyte; + out destlen: integer); +begin + with sslhandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_cipherupdate(ctx,pointer(dest),destlen, + pointer(source),sourcelen)); + end; +end; + +procedure tcustomopensslcryptohandler.cipherfinal( + var aclient: cryptoclientinfoty; + const dest: pbyte; out destlen: integer); +begin + with sslhandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_cipherfinal(ctx,pcuchar(dest),destlen)); + end; +end; + +function tcustomopensslcryptohandler.padbufsize: integer; +begin + result:= 3*evp_max_block_length; +end; + +{ tsymciphercryptohandler} + +constructor tsymciphercryptohandler.create(aowner: tcomponent); +begin + fkeydigestname:= 'md5'; + fkeygeniterationcount:= defaultkeygeniterationcount; + inherited; +end; + +procedure tsymciphercryptohandler.initcipher(var aclient: cryptoclientinfoty); +const + salttag = 'Salted__'; + taglength = length(salttag); + saltlength = 8; + headerlength = taglength + saltlength; +var +// keydata: keybufty; +// ivdata: ivbufty; + key1,salt1: string; +begin + with sslhandlerdataty(aclient.handlerdata).d do begin + digest:= checknilerror(evp_get_digestbyname(pcchar(pchar(fkeydigestname))), + cerr_digestnotfound); + getkey(key1,salt1); + if key1 = '' then begin + error(cerr_nokey); + end; + if salt1 <> '' then begin + salt1:= salt1 + nullstring(8-length(salt1)); + end; + if sslco_salt in foptions then begin + if p.mode = 0 then begin + setlength(salt1,headerlength); + if (internalread(aclient,pointer(salt1)^,headerlength) <> headerlength) or + (pos(salttag,salt1) <> 1) then begin + error(cerr_readheader); + end; + end + else begin + if salt1 = '' then begin + setlength(salt1,saltlength); + checknullerror(rand_bytes(pbyte(pointer(salt1)),saltlength)); + end; + salt1:= salttag+salt1; + if internalwrite(aclient,pointer(salt1)^,length(salt1)) <> + length(salt1) then begin + error(cerr_writeheader); + end; + end; + end; + if sslco_salt in foptions then begin + p.headersize:= headerlength; + end; + checknullerror(evp_bytestokey(cipher,digest, + pointer(pchar(pointer(salt1))+taglength),pointer(key1), + length(key1),fkeygeniterationcount, + pointer(keybuf),pointer(ivbuf))); + checknullerror(evp_cipherinit_ex(ctx,nil,nil,pointer(keybuf),pointer(ivbuf), + p.mode),cerr_cipherinit); + end; +end; + +{ tasymciphercryptohandler } + +procedure tasymciphercryptohandler.initcipher(var aclient: cryptoclientinfoty); +var + asymkey: pevp_pkey; + keybuf1: string; + keydata: string; +// ivdata: ivbufty; + int1,int2: integer; +begin + with sslhandlerdataty(aclient.handlerdata).d do begin + asymkey:= nil; + try + if p.mode = 1 then begin //encrypt + if fpubkeyfile = '' then begin + error(cerr_nopubkey); + end; + asymkey:= readpubkey(fpubkeyfile); +// setlength(keydata,evp_max_key_length); + checknullerror(evp_cipher_ctx_rand_key(ctx,pointer(keybuf))); + if cipher^.iv_len > 0 then begin + checknullerror(rand_bytes(pointer(ivbuf),cipher^.iv_len)); + end; + setlength(keybuf1,evp_pkey_size(asymkey)); + int1:= encryptsymkeyrsa(pointer(keybuf1),pointer(keybuf),ctx^.key_len, + asymkey); + if int1 < -1 then begin + error(cerr_norsakey); + end; + if int1 < 0 then begin + error(cerr_encrypt); + end; + if internalwrite(aclient,pointer(keybuf1)^,int1) <> int1 then begin + error(cerr_writeheader); + end; + if cipher^.iv_len > 0 then begin + if internalwrite(aclient,ivbuf^,cipher^.iv_len) <> + cipher^.iv_len then begin + error(cerr_writeheader); + end; + end; + end + else begin + if fprivkeyfile = '' then begin + error(cerr_nopubkey); + end; + asymkey:= readprivkey(fprivkeyfile,{$ifdef FPC}@{$endif}getkey); + if asymkey^._type <> EVP_PKEY_RSA then begin + error(cerr_norsakey); + end; + int1:= evp_pkey_size(asymkey); + setlength(keybuf1,int1); + if internalread(aclient,pointer(keybuf1)^,int1) <> int1 then begin + error(cerr_readheader); + end; + setlength(keydata,rsa_size(EVP_PKEY_get1_RSA(asymkey))+2); + int2:= decryptsymkeyrsa(pointer(keydata),pointer(keybuf1),length(keybuf1), + asymkey); + if (int2 < 0) or (int2 > sizeof(keybuf^)) then begin + error(cerr_decrypt); + end; + checknullerror(evp_cipher_ctx_set_key_length(ctx,int2)); + move(pointer(keydata)^,keybuf^,int2); + if cipher^.iv_len > 0 then begin + if internalread(aclient,ivbuf^,cipher^.iv_len) <> + cipher^.iv_len then begin + error(cerr_readheader); + end; + end; + end; + p.headersize:= int1 + cipher^.iv_len; + finally + freekey(asymkey); + end; + checknullerror(evp_cipherinit_ex(ctx,nil,nil,pointer(keybuf), + pointer(ivbuf),p.mode),cerr_cipherinit); + end; +end; + +{ tdigesthandler } + +procedure tdigesthandler.open(var aclient: cryptoclientinfoty); +begin + inherited; + initsslinterface; + with digesthandlerdataty(aclient.handlerdata).d do begin + ctx:= checknilerror(evp_md_ctx_create()); + md:= checknilerror(evp_get_digestbyname(pointer(pchar(fdigestname)))); + checknullerror(evp_digestinit_ex(ctx,md,nil)); + include(state,ds_inited); + end; +end; + +procedure tdigesthandler.close(var aclient: cryptoclientinfoty); +begin + inherited; + with digesthandlerdataty(aclient.handlerdata).d do begin + if ctx <> nil then begin + evp_md_ctx_destroy(ctx); + ctx:= nil; + state:= []; + end; + end; +end; + +function tdigesthandler.read(var aclient: cryptoclientinfoty; var buffer; + count: longint): longint; +begin + result:= inherited read(aclient,buffer,count); + with digesthandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_digestupdate(ctx,@buffer,result)); + end; +end; + +function tdigesthandler.write(var aclient: cryptoclientinfoty; const buffer; + count: longint): longint; +begin + with digesthandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_digestupdate(ctx,@buffer,count)); + end; + result:= inherited write(aclient,buffer,count); +end; + +function tdigesthandler.seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; +begin + if (offset <> 0) then begin + error(cerr_notseekable); + end; + result:= inherited seek(aclient,offset,origin); + if origin = sobeginning then begin + restartdigest(aclient); + end; +end; + +procedure tdigesthandler.restartdigest(var aclient: cryptoclientinfoty); +begin + with digesthandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_digestinit_ex(ctx,md,nil)); +// exclude(state,ds_final); + end; +end; + +procedure tdigesthandler.checkerror(const err: cryptoerrorty = cerr_error); +begin + raisesslerror(err); +end; + +function tdigesthandler.digest(const astream: tmsefilestream): string; +var + str1: string; + int1: integer; +begin + with digesthandlerdataty(getclient(astream)^.handlerdata).d do begin + if not (ds_inited in state) then begin + error(cerr_notactive); + end; + setlength(str1,evp_max_md_size); + checknullerror(evp_digestfinal_ex(ctx,pcuchar(pointer(str1)),cardinal(int1))); + setlength(str1,int1); + result:= str1; + checknullerror(evp_digestinit_ex(ctx,md,nil)); + end; +end; + +{ +procedure tdigesthandler.finalizeclient(var aclient: cryptoclientinfoty); +begin + inherited; + with digesthandlerdataty(aclient.handlerdata).d do begin + string(digest):= ''; + end; +end; +} +end. diff --git a/mseide-msegui/lib/common/crypto/msezlib.pas b/mseide-msegui/lib/common/crypto/msezlib.pas new file mode 100644 index 0000000..25db2eb --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msezlib.pas @@ -0,0 +1,743 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msezlib; +{/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.7, May 2nd, 2012 + + Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/} +{/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/} + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + msedynload,msetypes{msestrings},msectypes; +const +{$ifdef mswindows} + zliblib: array[0..0] of filenamety = ('zli1.dll'); +{$else} + zliblib: array[0..1] of filenamety = ('libz.so.1','libz.so'); +{$endif} + +const + ZLIB_VERSION = '1.2.7'; + ZLIB_VERNUM = $1270; + ZLIB_VER_MAJOR = 1; + ZLIB_VER_MINOR = 2; + ZLIB_VER_REVISION = 7; + ZLIB_VER_SUBREVISION = 0; + +{$ifdef FPC} + {$packrecords c} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} + +type + int = cint; + uInt = cuint; + uIntf = uInt; + puIntf = ^uIntf; + + uLong = culong; + uLongf = uLong; + puLongf = ^uLongf; + + Bytef = cchar; + pBytef = ^Bytef; + + alloc_func = function(opaque: pointer; + items: uInt; size: uInt): pointer; cdecl; + free_func = procedure(opaque: pointer; address: pointer); cdecl; + + internal_state = record //opaque + end; + pinternal_state = ^internal_state; + + z_stream = record + next_in: pBytef; {/* next input byte */} + avail_in: uInt; {/* number of bytes available at next_in */} + total_in: uLong; {/* total number of input bytes read so far */} + + next_out: pBytef; {/* next output byte should be put there */} + avail_out: uInt; {/* remaining free space at next_out */} + total_out: uLong; {/* total number of bytes output so far */} + + msg: pchar; {/* last error message, NULL if no error */} + internal_state: pinternal_state; + {/* not visible by applications */} + + zalloc: alloc_func; {/* used to allocate the internal state */} + zfree: free_func; {/* used to free the internal state */} + opaque: pointer; {/* private data object passed to zalloc and zfree */} + + data_type: int; {/* best guess about the data type: binary or text */} + adler: uLong; {/* adler32 value of the uncompressed data */} + reserved: uLong; {/* reserved for future use */} + end; + pz_stream = ^z_stream; + +{/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/} + gz_header = record + text: int; {/* true if compressed data believed to be text */} + time: uLong; {/* modification time */} + xflags: int; {/* extra flags (not used when writing a gzip file) */} + os: int; {/* operating system */} + extra: pBytef; {/* pointer to extra field or Z_NULL if none */} + extra_len: uInt; {/* extra field length (valid if extra != Z_NULL) */} + extra_max: uInt; {/* space at extra (only when reading header) */} + name: pBytef; {/* pointer to zero-terminated file name or Z_NULL */} + name_max: uInt; {/* space at name (only when reading header) */} + comment: pBytef; {/* pointer to zero-terminated comment or Z_NULL */} + comm_max: uInt; {/* space at comment (only when reading header) */} + hcrc: int; {/* true if there was or will be a header crc */} + done: int; {/* true when done reading gzip header (not used + when writing a gzip file) */} + end; + pgz_header = ^gz_header; + +{/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/} + + {/* constants */} +const + Z_NO_FLUSH = 0; + Z_PARTIAL_FLUSH = 1; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + Z_BLOCK = 5; + Z_TREES = 6; +{/* Allowed flush values; see deflate() and inflate() below for details */} + + Z_OK = 0; + Z_STREAM_END = 1; + Z_NEED_DICT = 2; + Z_ERRNO = (-1); + Z_STREAM_ERROR = (-2); + Z_DATA_ERROR = (-3); + Z_MEM_ERROR = (-4); + Z_BUF_ERROR = (-5); + Z_VERSION_ERROR = (-6); +{/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */} + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = (-1); +{/* compression levels */} + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_RLE = 3; + Z_FIXED = 4; + Z_DEFAULT_STRATEGY = 0; +{/* compression strategy; see deflateInit2() below for details */} + + Z_BINARY = 0; + Z_TEXT = 1; + Z_ASCII = Z_TEXT; {/* for compatibility with 1.2.2 and earlier */} + Z_UNKNOWN = 2; +{/* Possible values of the data_type field (though see inflate()) */} + + Z_DEFLATED = 8; +{/* The deflate compression method (the only one supported in this version) */} + + Z_NULL = 0; {/* for initializing zalloc, zfree, opaque */} + +//#define zlib_version zlibVersion() +///* for compatibility with versions < 1.0.2 */ + + + {/* basic functions */} + +function deflateInit(strm: pz_stream; level: int): int; +function deflateInit2(strm: pz_stream; level: int; method: int; + windowBits: int; memLevel: int; strategy: int): int; +function inflateInit(strm: pz_stream): int; +function inflateInit2 (strm: pz_stream; windowBits: int): int; + +var + zlibVersion: function(): pchar; cdecl; +{/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */} + + deflateInit_: function (strm: pz_stream; level: int; version: pchar; + stream_size: cint): cint; cdecl; +{/* + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/} + + deflateInit2_: function(strm: pz_stream; level: int; method: int; + windowBits: int; memLevel: int; strategy: int; + version: pchar; stream_size: int): int; cdecl; +{/* + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/} + + + deflate: function(strm: pz_stream; flush: int): int; cdecl; +{/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/} + + + deflateEnd: function(strm: pz_stream): int; cdecl; +{/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/} + + inflateInit_: function(strm: pz_stream; version: pchar; + stream_size: int): int; cdecl; +{/* + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/} + + inflateInit2_: function(strm: pz_stream; windowBits: int; + version: pchar; stream_size: int): int; cdecl; +{/* + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/} + + inflate: function(strm: pz_stream; flush: int): int; cdecl; +{/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/} + + inflateEnd: function(strm: pz_stream): int; cdecl; +{/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/} + +procedure initializezlib(const sonames: array of filenamety); + //[] = default +procedure initzlib; //calls initializezlib once +procedure releasezlib; + +implementation +uses + msesystypes,{$ifdef FPC}dynlibs,{$endif}msesysintf1,msesysintf; +var + libinfo: dynlibinfoty; + +function deflateInit(strm: pz_stream; level: int): int; +begin + result:= deflateInit_(strm,level,ZLIB_VERSION, sizeof(z_stream)); +end; + +function deflateInit2(strm: pz_stream; level: int; method: int; + windowBits: int; memLevel: int; strategy: int): int; +begin + result:= deflateInit2_(strm,level,method,windowBits,memLevel,strategy, + ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit(strm: pz_stream): int; +begin + result:= inflateInit_(strm,ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit2 (strm: pz_stream; windowBits: int): int; +begin + result:= inflateInit2_(strm,windowBits,ZLIB_VERSION, sizeof(z_stream)); +end; + +procedure initializezlib(const sonames: array of filenamety); + //[] = default +const + errormessage = 'Can not load OpenSSL library, '; + funcs: array[0..8] of funcinfoty = ( + (n: 'zlibVersion'; d: {$ifndef FPC}@{$endif}@zlibVersion), + (n: 'deflateInit_'; d: {$ifndef FPC}@{$endif}@deflateInit_), + (n: 'deflateInit2_'; d: {$ifndef FPC}@{$endif}@deflateInit2_), + (n: 'deflate'; d: {$ifndef FPC}@{$endif}@deflate), + (n: 'deflateEnd'; d: {$ifndef FPC}@{$endif}@deflateEnd), + (n: 'inflateInit_'; d: {$ifndef FPC}@{$endif}@inflateInit_), + (n: 'inflateInit2_'; d: {$ifndef FPC}@{$endif}@inflateInit2_), + (n: 'inflate'; d: {$ifndef FPC}@{$endif}@inflate), + (n: 'inflateEnd'; d: {$ifndef FPC}@{$endif}@inflateEnd) + ); + +begin + initializedynlib(libinfo,sonames,zliblib,funcs,[],errormessage); +end; + +procedure releasezlib; +begin + releasedynlib(libinfo); +end; + +var + libloaded: boolean; + +procedure initzlib; //calls initializezlib once +begin + if not libloaded then begin + initializezlib([]); + libloaded:= true; + end; +end; + +initialization + initializelibinfo(libinfo); +finalization + if libloaded then begin + releasezlib; + end; + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/crypto/msezstream.pas b/mseide-msegui/lib/common/crypto/msezstream.pas new file mode 100644 index 0000000..892b378 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msezstream.pas @@ -0,0 +1,309 @@ +{ MSEgui Copyright (c) 2012-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msezstream; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,msezlib,msecryptohandler,msestream,mseclasses, + msetypes{msestrings}; + +const + defaultzstreambuffersize = 16384; + minzstreambuffersize = 256; + +type + zstreamstatety = (zs_inflate,zs_inited,zs_fileeof); + zstreamstatesty = set of zstreamstatety; + + zstreamhandlerdatadty = record + strm: pz_stream; + buf: pbyte; + bufsize: integer; + state: zstreamstatesty; + end; + pzstreamhandlerdatadty = ^zstreamhandlerdatadty; + {$if sizeof(zstreamhandlerdatadty) > sizeof(cryptohandlerdataty)} + {$error 'buffer overflow'} + {$ifend} + zstreamhandlerdataty = record + case integer of + 0: (d: zstreamhandlerdatadty;); + 1: (_bufferspace: cryptohandlerdataty;); + end; + + tzstreamhandler = class(tbasecryptohandler) + private + fcompressionlevel: integer; + fbuffersize: integer; + procedure setbuffersize(avalue: integer); + protected + procedure internalflush(var aclient: cryptoclientinfoty; + const mode: integer); + procedure flush(var aclient: cryptoclientinfoty); override; + procedure checkinflate(var aclient: cryptoclientinfoty); + {$ifdef FPC}inline;{$endif} + procedure checknoinflate(var aclient: cryptoclientinfoty); + {$ifdef FPC}inline;{$endif} + function writedeflate(var aclient: cryptoclientinfoty; + const aflush: integer): boolean; + procedure open(var aclient: cryptoclientinfoty); override; + procedure close(var aclient: cryptoclientinfoty); override; + procedure checkerror(const aclient: cryptoclientinfoty; + const aerror: integer); reintroduce; + function read(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; override; + function write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; override; + function seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; override; + public + constructor create(aowner: tcomponent); override; + procedure flush(const astream: tmsefilestream; + const mode: integer = Z_SYNC_FLUSH); overload; + published + property compressionlevel: integer read fcompressionlevel + write fcompressionlevel default Z_DEFAULT_COMPRESSION; + property buffersize: integer read fbuffersize write setbuffersize + default defaultzstreambuffersize; + + end; + +implementation +uses + msesys,mseapplication; + +{ tzstreamhandler } + +constructor tzstreamhandler.create(aowner: tcomponent); +begin + fcompressionlevel:= Z_DEFAULT_COMPRESSION; + fbuffersize:= defaultzstreambuffersize; + inherited; +end; + +procedure tzstreamhandler.checkinflate(var aclient: cryptoclientinfoty); +begin + with zstreamhandlerdataty(aclient.handlerdata).d do begin + if not (zs_inflate in state) then begin + error(cerr_wrongdatadirection); + end; + end; +end; + +procedure tzstreamhandler.checknoinflate(var aclient: cryptoclientinfoty); +begin + with zstreamhandlerdataty(aclient.handlerdata).d do begin + if (zs_inflate in state) then begin + error(cerr_wrongdatadirection); + end; + end; +end; + +procedure tzstreamhandler.open(var aclient: cryptoclientinfoty); +begin + if not (aclient.stream.openmode in [fm_read,fm_create,fm_write]) then begin + error(cerr_invalidopenmode); + end; + initzlib; + inherited; + with zstreamhandlerdataty(aclient.handlerdata).d do begin + getmem(strm,sizeof(z_stream)); + getmem(buf,fbuffersize); + bufsize:= fbuffersize; + if aclient.stream.openmode in [fm_read] then begin + include(state,zs_inflate); + end; + with strm^ do begin + zalloc:= nil; + zfree:= nil; + opaque:= nil; + end; + if zs_inflate in state then begin + inflateinit(strm); + include(state,zs_inited); + strm^.next_in:= nil; + strm^.avail_in:= 0; + end + else begin + deflateinit(strm,fcompressionlevel); + include(state,zs_inited); + end; + end; +end; + +procedure tzstreamhandler.close(var aclient: cryptoclientinfoty); +begin + with zstreamhandlerdataty(aclient.handlerdata).d do begin + if strm <> nil then begin + if zs_inited in state then begin + if zs_inflate in state then begin + inflateend(strm); + end + else begin + strm^.next_in:= nil; + strm^.avail_in:= 0; + try + if not writedeflate(aclient,Z_FINISH) then begin + writeerror(aclient); + end; + except + application.handleexception; + end; + deflateend(strm); + end; + end; + freemem(strm); + strm:= nil; + end; + if buf <> nil then begin + freemem(buf); + buf:= nil; + end; + state:= []; + end; + inherited; +end; + +procedure tzstreamhandler.checkerror(const aclient: cryptoclientinfoty; + const aerror: integer); +begin + if aerror < 0 then begin + with zstreamhandlerdataty(aclient.handlerdata).d do begin + componentexception(self,msestring(string(strm^.msg))); + end; + end; +end; + +function tzstreamhandler.read(var aclient: cryptoclientinfoty; var buffer; + count: longint): longint; +var + po1: pbyte; + int1: integer; +begin + checkinflate(aclient); + result:= 0; + po1:= @buffer; + with zstreamhandlerdataty(aclient.handlerdata).d do begin + while true do begin + if not (zs_fileeof in state) and (strm^.avail_in = 0) then begin + strm^.next_in:= pointer(buf); + strm^.avail_in:= inherited read(aclient,buf^,bufsize); + if strm^.avail_in < bufsize then begin + include(state,zs_fileeof); + end; + end; + strm^.avail_out:= count-result; + if strm^.avail_out <= 0 then begin + break; + end; + strm^.next_out:= pointer(po1); + checkerror(aclient,inflate(strm,z_no_flush)); + int1:= pchar(pointer(strm^.next_out)) - pchar(po1); + if (int1 = 0) and (zs_fileeof in state) and (strm^.avail_in = 0) then begin + break; + end; + result:= result + int1; + po1:= pointer(strm^.next_out); + end; + end; +end; + +function tzstreamhandler.writedeflate(var aclient: cryptoclientinfoty; + const aflush: integer): boolean; +var + int1: integer; +begin + result:= true; + with zstreamhandlerdataty(aclient.handlerdata).d do begin + while true do begin + strm^.next_out:= pointer(buf); + strm^.avail_out:= bufsize; + deflate(strm,aflush); + int1:= pchar(pointer(strm^.next_out)) - pchar(buf); + if int1 = 0 then begin + break; + end; + if result then begin + if inherited write(aclient,buf^,int1) <> int1 then begin + result:= false; //can not write + end; + end; + end; + end; +end; + +function tzstreamhandler.write(var aclient: cryptoclientinfoty; const buffer; + count: longint): longint; +//var +// int1: integer; +begin + checknoinflate(aclient); + result:= count; + with zstreamhandlerdataty(aclient.handlerdata).d do begin + if count > 0 then begin + with strm^ do begin + next_in:= @buffer; + avail_in:= count; + if not writedeflate(aclient,z_no_flush) then begin + result:= 0; //can not write + end; + end; + end; + end; +end; + +procedure tzstreamhandler.internalflush(var aclient: cryptoclientinfoty; + const mode: integer); +begin + with zstreamhandlerdataty(aclient.handlerdata).d do begin + if not (zs_inflate in state) then begin + strm^.next_in:= nil; + strm^.avail_in:= 0; + if not writedeflate(aclient,mode) then begin + writeerror(aclient); + end; + end; + end; +end; + +procedure tzstreamhandler.flush(var aclient: cryptoclientinfoty); +begin + internalflush(aclient,Z_SYNC_FLUSH); +end; + +procedure tzstreamhandler.flush(const astream: tmsefilestream; + const mode: integer = Z_SYNC_FLUSH); +var + po1: pcryptoclientinfoty; +begin + po1:= getclient(astream); + if ccs_open in po1^.state then begin + internalflush(po1^,mode); + end; +end; + +procedure tzstreamhandler.setbuffersize(avalue: integer); +begin + if avalue < minzstreambuffersize then begin + avalue:= minzstreambuffersize; + end; + fbuffersize:= avalue; +end; + +function tzstreamhandler.seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; +begin + if (origin <> socurrent) or (offset <> 0) then begin + error(cerr_notseekable); + end; + result:= inherited seek(aclient,offset,origin); +end; + +end. diff --git a/mseide-msegui/lib/common/db/firebird.pas b/mseide-msegui/lib/common/db/firebird.pas new file mode 100644 index 0000000..68bdc87 --- /dev/null +++ b/mseide-msegui/lib/common/db/firebird.pas @@ -0,0 +1,12993 @@ +{ This file was autogenerated by cloop - Cross Language Object Oriented Programming } +{$ifdef fpc} {$mode delphi} {$endif} +unit firebird; + +interface + +uses classes, sysUtils; + +type +{$IFNDEF FPC} + QWord = UInt64; +{$ENDIF} + + IVersioned = class; + IReferenceCounted = class; + IDisposable = class; + IStatus = class; + IMaster = class; + IPluginBase = class; + IPluginSet = class; + IConfigEntry = class; + IConfig = class; + IFirebirdConf = class; + IPluginConfig = class; + IPluginFactory = class; + IPluginModule = class; + IPluginManager = class; + ICryptKey = class; + IConfigManager = class; + IEventCallback = class; + IBlob = class; + ITransaction = class; + IMessageMetadata = class; + IMetadataBuilder = class; + IResultSet = class; + IStatement = class; + IRequest = class; + IEvents = class; + IAttachment = class; + IService = class; + IProvider = class; + IDtcStart = class; + IDtc = class; + IAuth = class; + IWriter = class; + IServerBlock = class; + IClientBlock = class; + IServer = class; + IClient = class; + IUserField = class; + ICharUserField = class; + IIntUserField = class; + IUser = class; + IListUsers = class; + ILogonInfo = class; + IManagement = class; + IWireCryptPlugin = class; + ICryptKeyCallback = class; + IKeyHolderPlugin = class; + IDbCryptPlugin = class; + IExternalContext = class; + IExternalResultSet = class; + IExternalFunction = class; + IExternalProcedure = class; + IExternalTrigger = class; + IRoutineMetadata = class; + IExternalEngine = class; + ITimer = class; + ITimerControl = class; + IVersionCallback = class; + IUtil = class; + IOffsetsCallback = class; + IXpbBuilder = class; + ITraceConnection = class; + ITraceDatabaseConnection = class; + ITraceTransaction = class; + ITraceParams = class; + ITraceStatement = class; + ITraceSQLStatement = class; + ITraceBLRStatement = class; + ITraceDYNRequest = class; + ITraceContextVariable = class; + ITraceProcedure = class; + ITraceFunction = class; + ITraceTrigger = class; + ITraceServiceConnection = class; + ITraceStatusVector = class; + ITraceSweepInfo = class; + ITraceLogWriter = class; + ITraceInitInfo = class; + ITracePlugin = class; + ITraceFactory = class; + IUdrFunctionFactory = class; + IUdrProcedureFactory = class; + IUdrTriggerFactory = class; + IUdrPlugin = class; + + FbException = class(Exception) + public + constructor create(status: IStatus); virtual; + destructor Destroy(); override; + + function getStatus: IStatus; + + class procedure checkException(status: IStatus); + class procedure catchException(status: IStatus; e: Exception); + + private + status: IStatus; + end; + + ISC_DATE = Integer; + ISC_TIME = Integer; + ISC_QUAD = array [1..2] of Integer; + + ntrace_relation_t = Integer; + TraceCounts = Record + trc_relation_id : ntrace_relation_t; + trc_relation_name : PAnsiChar; + trc_counters : ^Int64; + end; + TraceCountsPtr = ^TraceCounts; + PerformanceInfo = Record + pin_time : Int64; + pin_counters : ^Int64; + pin_count : NativeUInt; + pin_tables : TraceCountsPtr; + pin_records_fetched : Int64; + end; + + Dsc = Record + dsc_dtype, dsc_scale: Byte; + dsc_length, dsc_sub_type, dsc_flags: Int16; + dsc_address: ^Byte; + end; + BooleanPtr = ^Boolean; + BytePtr = ^Byte; + CardinalPtr = ^Cardinal; + IKeyHolderPluginPtr = ^IKeyHolderPlugin; + ISC_QUADPtr = ^ISC_QUAD; + Int64Ptr = ^Int64; + NativeIntPtr = ^NativeInt; + PerformanceInfoPtr = ^PerformanceInfo; + dscPtr = ^dsc; + + IReferenceCounted_addRefPtr = procedure(this: IReferenceCounted); cdecl; + IReferenceCounted_releasePtr = function(this: IReferenceCounted): Integer; cdecl; + IDisposable_disposePtr = procedure(this: IDisposable); cdecl; + IStatus_initPtr = procedure(this: IStatus); cdecl; + IStatus_getStatePtr = function(this: IStatus): Cardinal; cdecl; + IStatus_setErrors2Ptr = procedure(this: IStatus; length: Cardinal; value: NativeIntPtr); cdecl; + IStatus_setWarnings2Ptr = procedure(this: IStatus; length: Cardinal; value: NativeIntPtr); cdecl; + IStatus_setErrorsPtr = procedure(this: IStatus; value: NativeIntPtr); cdecl; + IStatus_setWarningsPtr = procedure(this: IStatus; value: NativeIntPtr); cdecl; + IStatus_getErrorsPtr = function(this: IStatus): NativeIntPtr; cdecl; + IStatus_getWarningsPtr = function(this: IStatus): NativeIntPtr; cdecl; + IStatus_clonePtr = function(this: IStatus): IStatus; cdecl; + IMaster_getStatusPtr = function(this: IMaster): IStatus; cdecl; + IMaster_getDispatcherPtr = function(this: IMaster): IProvider; cdecl; + IMaster_getPluginManagerPtr = function(this: IMaster): IPluginManager; cdecl; + IMaster_getTimerControlPtr = function(this: IMaster): ITimerControl; cdecl; + IMaster_getDtcPtr = function(this: IMaster): IDtc; cdecl; + IMaster_registerAttachmentPtr = function(this: IMaster; provider: IProvider; attachment: IAttachment): IAttachment; cdecl; + IMaster_registerTransactionPtr = function(this: IMaster; attachment: IAttachment; transaction: ITransaction): ITransaction; cdecl; + IMaster_getMetadataBuilderPtr = function(this: IMaster; status: IStatus; fieldCount: Cardinal): IMetadataBuilder; cdecl; + IMaster_serverModePtr = function(this: IMaster; mode: Integer): Integer; cdecl; + IMaster_getUtilInterfacePtr = function(this: IMaster): IUtil; cdecl; + IMaster_getConfigManagerPtr = function(this: IMaster): IConfigManager; cdecl; + IMaster_getProcessExitingPtr = function(this: IMaster): Boolean; cdecl; + IPluginBase_setOwnerPtr = procedure(this: IPluginBase; r: IReferenceCounted); cdecl; + IPluginBase_getOwnerPtr = function(this: IPluginBase): IReferenceCounted; cdecl; + IPluginSet_getNamePtr = function(this: IPluginSet): PAnsiChar; cdecl; + IPluginSet_getModuleNamePtr = function(this: IPluginSet): PAnsiChar; cdecl; + IPluginSet_getPluginPtr = function(this: IPluginSet; status: IStatus): IPluginBase; cdecl; + IPluginSet_nextPtr = procedure(this: IPluginSet; status: IStatus); cdecl; + IPluginSet_set_Ptr = procedure(this: IPluginSet; status: IStatus; s: PAnsiChar); cdecl; + IConfigEntry_getNamePtr = function(this: IConfigEntry): PAnsiChar; cdecl; + IConfigEntry_getValuePtr = function(this: IConfigEntry): PAnsiChar; cdecl; + IConfigEntry_getIntValuePtr = function(this: IConfigEntry): Int64; cdecl; + IConfigEntry_getBoolValuePtr = function(this: IConfigEntry): Boolean; cdecl; + IConfigEntry_getSubConfigPtr = function(this: IConfigEntry; status: IStatus): IConfig; cdecl; + IConfig_findPtr = function(this: IConfig; status: IStatus; name: PAnsiChar): IConfigEntry; cdecl; + IConfig_findValuePtr = function(this: IConfig; status: IStatus; name: PAnsiChar; value: PAnsiChar): IConfigEntry; cdecl; + IConfig_findPosPtr = function(this: IConfig; status: IStatus; name: PAnsiChar; pos: Cardinal): IConfigEntry; cdecl; + IFirebirdConf_getKeyPtr = function(this: IFirebirdConf; name: PAnsiChar): Cardinal; cdecl; + IFirebirdConf_asIntegerPtr = function(this: IFirebirdConf; key: Cardinal): Int64; cdecl; + IFirebirdConf_asStringPtr = function(this: IFirebirdConf; key: Cardinal): PAnsiChar; cdecl; + IFirebirdConf_asBooleanPtr = function(this: IFirebirdConf; key: Cardinal): Boolean; cdecl; + IPluginConfig_getConfigFileNamePtr = function(this: IPluginConfig): PAnsiChar; cdecl; + IPluginConfig_getDefaultConfigPtr = function(this: IPluginConfig; status: IStatus): IConfig; cdecl; + IPluginConfig_getFirebirdConfPtr = function(this: IPluginConfig; status: IStatus): IFirebirdConf; cdecl; + IPluginConfig_setReleaseDelayPtr = procedure(this: IPluginConfig; status: IStatus; microSeconds: QWord); cdecl; + IPluginFactory_createPluginPtr = function(this: IPluginFactory; status: IStatus; factoryParameter: IPluginConfig): IPluginBase; cdecl; + IPluginModule_doCleanPtr = procedure(this: IPluginModule); cdecl; + IPluginManager_registerPluginFactoryPtr = procedure(this: IPluginManager; pluginType: Cardinal; defaultName: PAnsiChar; factory: IPluginFactory); cdecl; + IPluginManager_registerModulePtr = procedure(this: IPluginManager; cleanup: IPluginModule); cdecl; + IPluginManager_unregisterModulePtr = procedure(this: IPluginManager; cleanup: IPluginModule); cdecl; + IPluginManager_getPluginsPtr = function(this: IPluginManager; status: IStatus; pluginType: Cardinal; namesList: PAnsiChar; firebirdConf: IFirebirdConf): IPluginSet; cdecl; + IPluginManager_getConfigPtr = function(this: IPluginManager; status: IStatus; filename: PAnsiChar): IConfig; cdecl; + IPluginManager_releasePluginPtr = procedure(this: IPluginManager; plugin: IPluginBase); cdecl; + ICryptKey_setSymmetricPtr = procedure(this: ICryptKey; status: IStatus; type_: PAnsiChar; keyLength: Cardinal; key: Pointer); cdecl; + ICryptKey_setAsymmetricPtr = procedure(this: ICryptKey; status: IStatus; type_: PAnsiChar; encryptKeyLength: Cardinal; encryptKey: Pointer; decryptKeyLength: Cardinal; decryptKey: Pointer); cdecl; + ICryptKey_getEncryptKeyPtr = function(this: ICryptKey; length: CardinalPtr): Pointer; cdecl; + ICryptKey_getDecryptKeyPtr = function(this: ICryptKey; length: CardinalPtr): Pointer; cdecl; + IConfigManager_getDirectoryPtr = function(this: IConfigManager; code: Cardinal): PAnsiChar; cdecl; + IConfigManager_getFirebirdConfPtr = function(this: IConfigManager): IFirebirdConf; cdecl; + IConfigManager_getDatabaseConfPtr = function(this: IConfigManager; dbName: PAnsiChar): IFirebirdConf; cdecl; + IConfigManager_getPluginConfigPtr = function(this: IConfigManager; configuredPlugin: PAnsiChar): IConfig; cdecl; + IConfigManager_getInstallDirectoryPtr = function(this: IConfigManager): PAnsiChar; cdecl; + IConfigManager_getRootDirectoryPtr = function(this: IConfigManager): PAnsiChar; cdecl; + IEventCallback_eventCallbackFunctionPtr = procedure(this: IEventCallback; length: Cardinal; events: BytePtr); cdecl; + IBlob_getInfoPtr = procedure(this: IBlob; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + IBlob_getSegmentPtr = function(this: IBlob; status: IStatus; bufferLength: Cardinal; buffer: Pointer; segmentLength: CardinalPtr): Integer; cdecl; + IBlob_putSegmentPtr = procedure(this: IBlob; status: IStatus; length: Cardinal; buffer: Pointer); cdecl; + IBlob_cancelPtr = procedure(this: IBlob; status: IStatus); cdecl; + IBlob_closePtr = procedure(this: IBlob; status: IStatus); cdecl; + IBlob_seekPtr = function(this: IBlob; status: IStatus; mode: Integer; offset: Integer): Integer; cdecl; + ITransaction_getInfoPtr = procedure(this: ITransaction; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + ITransaction_preparePtr = procedure(this: ITransaction; status: IStatus; msgLength: Cardinal; message: BytePtr); cdecl; + ITransaction_commitPtr = procedure(this: ITransaction; status: IStatus); cdecl; + ITransaction_commitRetainingPtr = procedure(this: ITransaction; status: IStatus); cdecl; + ITransaction_rollbackPtr = procedure(this: ITransaction; status: IStatus); cdecl; + ITransaction_rollbackRetainingPtr = procedure(this: ITransaction; status: IStatus); cdecl; + ITransaction_disconnectPtr = procedure(this: ITransaction; status: IStatus); cdecl; + ITransaction_joinPtr = function(this: ITransaction; status: IStatus; transaction: ITransaction): ITransaction; cdecl; + ITransaction_validatePtr = function(this: ITransaction; status: IStatus; attachment: IAttachment): ITransaction; cdecl; + ITransaction_enterDtcPtr = function(this: ITransaction; status: IStatus): ITransaction; cdecl; + IMessageMetadata_getCountPtr = function(this: IMessageMetadata; status: IStatus): Cardinal; cdecl; + IMessageMetadata_getFieldPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; + IMessageMetadata_getRelationPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; + IMessageMetadata_getOwnerPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; + IMessageMetadata_getAliasPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; + IMessageMetadata_getTypePtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; + IMessageMetadata_isNullablePtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Boolean; cdecl; + IMessageMetadata_getSubTypePtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Integer; cdecl; + IMessageMetadata_getLengthPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; + IMessageMetadata_getScalePtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Integer; cdecl; + IMessageMetadata_getCharSetPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; + IMessageMetadata_getOffsetPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; + IMessageMetadata_getNullOffsetPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; + IMessageMetadata_getBuilderPtr = function(this: IMessageMetadata; status: IStatus): IMetadataBuilder; cdecl; + IMessageMetadata_getMessageLengthPtr = function(this: IMessageMetadata; status: IStatus): Cardinal; cdecl; + IMetadataBuilder_setTypePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; type_: Cardinal); cdecl; + IMetadataBuilder_setSubTypePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; subType: Integer); cdecl; + IMetadataBuilder_setLengthPtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; length: Cardinal); cdecl; + IMetadataBuilder_setCharSetPtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; charSet: Cardinal); cdecl; + IMetadataBuilder_setScalePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; scale: Cardinal); cdecl; + IMetadataBuilder_truncatePtr = procedure(this: IMetadataBuilder; status: IStatus; count: Cardinal); cdecl; + IMetadataBuilder_moveNameToIndexPtr = procedure(this: IMetadataBuilder; status: IStatus; name: PAnsiChar; index: Cardinal); cdecl; + IMetadataBuilder_removePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal); cdecl; + IMetadataBuilder_addFieldPtr = function(this: IMetadataBuilder; status: IStatus): Cardinal; cdecl; + IMetadataBuilder_getMetadataPtr = function(this: IMetadataBuilder; status: IStatus): IMessageMetadata; cdecl; + IResultSet_fetchNextPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; + IResultSet_fetchPriorPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; + IResultSet_fetchFirstPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; + IResultSet_fetchLastPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; + IResultSet_fetchAbsolutePtr = function(this: IResultSet; status: IStatus; position: Integer; message: Pointer): Integer; cdecl; + IResultSet_fetchRelativePtr = function(this: IResultSet; status: IStatus; offset: Integer; message: Pointer): Integer; cdecl; + IResultSet_isEofPtr = function(this: IResultSet; status: IStatus): Boolean; cdecl; + IResultSet_isBofPtr = function(this: IResultSet; status: IStatus): Boolean; cdecl; + IResultSet_getMetadataPtr = function(this: IResultSet; status: IStatus): IMessageMetadata; cdecl; + IResultSet_closePtr = procedure(this: IResultSet; status: IStatus); cdecl; + IResultSet_setDelayedOutputFormatPtr = procedure(this: IResultSet; status: IStatus; format: IMessageMetadata); cdecl; + IStatement_getInfoPtr = procedure(this: IStatement; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + IStatement_getTypePtr = function(this: IStatement; status: IStatus): Cardinal; cdecl; + IStatement_getPlanPtr = function(this: IStatement; status: IStatus; detailed: Boolean): PAnsiChar; cdecl; + IStatement_getAffectedRecordsPtr = function(this: IStatement; status: IStatus): QWord; cdecl; + IStatement_getInputMetadataPtr = function(this: IStatement; status: IStatus): IMessageMetadata; cdecl; + IStatement_getOutputMetadataPtr = function(this: IStatement; status: IStatus): IMessageMetadata; cdecl; + IStatement_executePtr = function(this: IStatement; status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; cdecl; + IStatement_openCursorPtr = function(this: IStatement; status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; flags: Cardinal): IResultSet; cdecl; + IStatement_setCursorNamePtr = procedure(this: IStatement; status: IStatus; name: PAnsiChar); cdecl; + IStatement_freePtr = procedure(this: IStatement; status: IStatus); cdecl; + IStatement_getFlagsPtr = function(this: IStatement; status: IStatus): Cardinal; cdecl; + IRequest_receivePtr = procedure(this: IRequest; status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; + IRequest_sendPtr = procedure(this: IRequest; status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; + IRequest_getInfoPtr = procedure(this: IRequest; status: IStatus; level: Integer; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + IRequest_startPtr = procedure(this: IRequest; status: IStatus; tra: ITransaction; level: Integer); cdecl; + IRequest_startAndSendPtr = procedure(this: IRequest; status: IStatus; tra: ITransaction; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; + IRequest_unwindPtr = procedure(this: IRequest; status: IStatus; level: Integer); cdecl; + IRequest_freePtr = procedure(this: IRequest; status: IStatus); cdecl; + IEvents_cancelPtr = procedure(this: IEvents; status: IStatus); cdecl; + IAttachment_getInfoPtr = procedure(this: IAttachment; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + IAttachment_startTransactionPtr = function(this: IAttachment; status: IStatus; tpbLength: Cardinal; tpb: BytePtr): ITransaction; cdecl; + IAttachment_reconnectTransactionPtr = function(this: IAttachment; status: IStatus; length: Cardinal; id: BytePtr): ITransaction; cdecl; + IAttachment_compileRequestPtr = function(this: IAttachment; status: IStatus; blrLength: Cardinal; blr: BytePtr): IRequest; cdecl; + IAttachment_transactRequestPtr = procedure(this: IAttachment; status: IStatus; transaction: ITransaction; blrLength: Cardinal; blr: BytePtr; inMsgLength: Cardinal; inMsg: BytePtr; outMsgLength: Cardinal; outMsg: BytePtr); cdecl; + IAttachment_createBlobPtr = function(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; cdecl; + IAttachment_openBlobPtr = function(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; cdecl; + IAttachment_getSlicePtr = function(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr): Integer; cdecl; + IAttachment_putSlicePtr = procedure(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr); cdecl; + IAttachment_executeDynPtr = procedure(this: IAttachment; status: IStatus; transaction: ITransaction; length: Cardinal; dyn: BytePtr); cdecl; + IAttachment_preparePtr = function(this: IAttachment; status: IStatus; tra: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; flags: Cardinal): IStatement; cdecl; + IAttachment_executePtr = function(this: IAttachment; status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; cdecl; + IAttachment_openCursorPtr = function(this: IAttachment; status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; cursorName: PAnsiChar; cursorFlags: Cardinal): IResultSet; cdecl; + IAttachment_queEventsPtr = function(this: IAttachment; status: IStatus; callback: IEventCallback; length: Cardinal; events: BytePtr): IEvents; cdecl; + IAttachment_cancelOperationPtr = procedure(this: IAttachment; status: IStatus; option: Integer); cdecl; + IAttachment_pingPtr = procedure(this: IAttachment; status: IStatus); cdecl; + IAttachment_detachPtr = procedure(this: IAttachment; status: IStatus); cdecl; + IAttachment_dropDatabasePtr = procedure(this: IAttachment; status: IStatus); cdecl; + IService_detachPtr = procedure(this: IService; status: IStatus); cdecl; + IService_queryPtr = procedure(this: IService; status: IStatus; sendLength: Cardinal; sendItems: BytePtr; receiveLength: Cardinal; receiveItems: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + IService_startPtr = procedure(this: IService; status: IStatus; spbLength: Cardinal; spb: BytePtr); cdecl; + IProvider_attachDatabasePtr = function(this: IProvider; status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; cdecl; + IProvider_createDatabasePtr = function(this: IProvider; status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; cdecl; + IProvider_attachServiceManagerPtr = function(this: IProvider; status: IStatus; service: PAnsiChar; spbLength: Cardinal; spb: BytePtr): IService; cdecl; + IProvider_shutdownPtr = procedure(this: IProvider; status: IStatus; timeout: Cardinal; reason: Integer); cdecl; + IProvider_setDbCryptCallbackPtr = procedure(this: IProvider; status: IStatus; cryptCallback: ICryptKeyCallback); cdecl; + IDtcStart_addAttachmentPtr = procedure(this: IDtcStart; status: IStatus; att: IAttachment); cdecl; + IDtcStart_addWithTpbPtr = procedure(this: IDtcStart; status: IStatus; att: IAttachment; length: Cardinal; tpb: BytePtr); cdecl; + IDtcStart_startPtr = function(this: IDtcStart; status: IStatus): ITransaction; cdecl; + IDtc_joinPtr = function(this: IDtc; status: IStatus; one: ITransaction; two: ITransaction): ITransaction; cdecl; + IDtc_startBuilderPtr = function(this: IDtc; status: IStatus): IDtcStart; cdecl; + IWriter_resetPtr = procedure(this: IWriter); cdecl; + IWriter_addPtr = procedure(this: IWriter; status: IStatus; name: PAnsiChar); cdecl; + IWriter_setTypePtr = procedure(this: IWriter; status: IStatus; value: PAnsiChar); cdecl; + IWriter_setDbPtr = procedure(this: IWriter; status: IStatus; value: PAnsiChar); cdecl; + IServerBlock_getLoginPtr = function(this: IServerBlock): PAnsiChar; cdecl; + IServerBlock_getDataPtr = function(this: IServerBlock; length: CardinalPtr): BytePtr; cdecl; + IServerBlock_putDataPtr = procedure(this: IServerBlock; status: IStatus; length: Cardinal; data: Pointer); cdecl; + IServerBlock_newKeyPtr = function(this: IServerBlock; status: IStatus): ICryptKey; cdecl; + IClientBlock_getLoginPtr = function(this: IClientBlock): PAnsiChar; cdecl; + IClientBlock_getPasswordPtr = function(this: IClientBlock): PAnsiChar; cdecl; + IClientBlock_getDataPtr = function(this: IClientBlock; length: CardinalPtr): BytePtr; cdecl; + IClientBlock_putDataPtr = procedure(this: IClientBlock; status: IStatus; length: Cardinal; data: Pointer); cdecl; + IClientBlock_newKeyPtr = function(this: IClientBlock; status: IStatus): ICryptKey; cdecl; + IServer_authenticatePtr = function(this: IServer; status: IStatus; sBlock: IServerBlock; writerInterface: IWriter): Integer; cdecl; + IClient_authenticatePtr = function(this: IClient; status: IStatus; cBlock: IClientBlock): Integer; cdecl; + IUserField_enteredPtr = function(this: IUserField): Integer; cdecl; + IUserField_specifiedPtr = function(this: IUserField): Integer; cdecl; + IUserField_setEnteredPtr = procedure(this: IUserField; status: IStatus; newValue: Integer); cdecl; + ICharUserField_getPtr = function(this: ICharUserField): PAnsiChar; cdecl; + ICharUserField_set_Ptr = procedure(this: ICharUserField; status: IStatus; newValue: PAnsiChar); cdecl; + IIntUserField_getPtr = function(this: IIntUserField): Integer; cdecl; + IIntUserField_set_Ptr = procedure(this: IIntUserField; status: IStatus; newValue: Integer); cdecl; + IUser_operationPtr = function(this: IUser): Cardinal; cdecl; + IUser_userNamePtr = function(this: IUser): ICharUserField; cdecl; + IUser_passwordPtr = function(this: IUser): ICharUserField; cdecl; + IUser_firstNamePtr = function(this: IUser): ICharUserField; cdecl; + IUser_lastNamePtr = function(this: IUser): ICharUserField; cdecl; + IUser_middleNamePtr = function(this: IUser): ICharUserField; cdecl; + IUser_commentPtr = function(this: IUser): ICharUserField; cdecl; + IUser_attributesPtr = function(this: IUser): ICharUserField; cdecl; + IUser_activePtr = function(this: IUser): IIntUserField; cdecl; + IUser_adminPtr = function(this: IUser): IIntUserField; cdecl; + IUser_clearPtr = procedure(this: IUser; status: IStatus); cdecl; + IListUsers_listPtr = procedure(this: IListUsers; status: IStatus; user: IUser); cdecl; + ILogonInfo_namePtr = function(this: ILogonInfo): PAnsiChar; cdecl; + ILogonInfo_rolePtr = function(this: ILogonInfo): PAnsiChar; cdecl; + ILogonInfo_networkProtocolPtr = function(this: ILogonInfo): PAnsiChar; cdecl; + ILogonInfo_remoteAddressPtr = function(this: ILogonInfo): PAnsiChar; cdecl; + ILogonInfo_authBlockPtr = function(this: ILogonInfo; length: CardinalPtr): BytePtr; cdecl; + IManagement_startPtr = procedure(this: IManagement; status: IStatus; logonInfo: ILogonInfo); cdecl; + IManagement_executePtr = function(this: IManagement; status: IStatus; user: IUser; callback: IListUsers): Integer; cdecl; + IManagement_commitPtr = procedure(this: IManagement; status: IStatus); cdecl; + IManagement_rollbackPtr = procedure(this: IManagement; status: IStatus); cdecl; + IWireCryptPlugin_getKnownTypesPtr = function(this: IWireCryptPlugin; status: IStatus): PAnsiChar; cdecl; + IWireCryptPlugin_setKeyPtr = procedure(this: IWireCryptPlugin; status: IStatus; key: ICryptKey); cdecl; + IWireCryptPlugin_encryptPtr = procedure(this: IWireCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; + IWireCryptPlugin_decryptPtr = procedure(this: IWireCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; + ICryptKeyCallback_callbackPtr = function(this: ICryptKeyCallback; dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; cdecl; + IKeyHolderPlugin_keyCallbackPtr = function(this: IKeyHolderPlugin; status: IStatus; callback: ICryptKeyCallback): Integer; cdecl; + IKeyHolderPlugin_keyHandlePtr = function(this: IKeyHolderPlugin; status: IStatus; keyName: PAnsiChar): ICryptKeyCallback; cdecl; + IDbCryptPlugin_setKeyPtr = procedure(this: IDbCryptPlugin; status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); cdecl; + IDbCryptPlugin_encryptPtr = procedure(this: IDbCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; + IDbCryptPlugin_decryptPtr = procedure(this: IDbCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; + IExternalContext_getMasterPtr = function(this: IExternalContext): IMaster; cdecl; + IExternalContext_getEnginePtr = function(this: IExternalContext; status: IStatus): IExternalEngine; cdecl; + IExternalContext_getAttachmentPtr = function(this: IExternalContext; status: IStatus): IAttachment; cdecl; + IExternalContext_getTransactionPtr = function(this: IExternalContext; status: IStatus): ITransaction; cdecl; + IExternalContext_getUserNamePtr = function(this: IExternalContext): PAnsiChar; cdecl; + IExternalContext_getDatabaseNamePtr = function(this: IExternalContext): PAnsiChar; cdecl; + IExternalContext_getClientCharSetPtr = function(this: IExternalContext): PAnsiChar; cdecl; + IExternalContext_obtainInfoCodePtr = function(this: IExternalContext): Integer; cdecl; + IExternalContext_getInfoPtr = function(this: IExternalContext; code: Integer): Pointer; cdecl; + IExternalContext_setInfoPtr = function(this: IExternalContext; code: Integer; value: Pointer): Pointer; cdecl; + IExternalResultSet_fetchPtr = function(this: IExternalResultSet; status: IStatus): Boolean; cdecl; + IExternalFunction_getCharSetPtr = procedure(this: IExternalFunction; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; + IExternalFunction_executePtr = procedure(this: IExternalFunction; status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer); cdecl; + IExternalProcedure_getCharSetPtr = procedure(this: IExternalProcedure; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; + IExternalProcedure_openPtr = function(this: IExternalProcedure; status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer): IExternalResultSet; cdecl; + IExternalTrigger_getCharSetPtr = procedure(this: IExternalTrigger; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; + IExternalTrigger_executePtr = procedure(this: IExternalTrigger; status: IStatus; context: IExternalContext; action: Cardinal; oldMsg: Pointer; newMsg: Pointer); cdecl; + IRoutineMetadata_getPackagePtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; + IRoutineMetadata_getNamePtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; + IRoutineMetadata_getEntryPointPtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; + IRoutineMetadata_getBodyPtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; + IRoutineMetadata_getInputMetadataPtr = function(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; + IRoutineMetadata_getOutputMetadataPtr = function(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; + IRoutineMetadata_getTriggerMetadataPtr = function(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; + IRoutineMetadata_getTriggerTablePtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; + IRoutineMetadata_getTriggerTypePtr = function(this: IRoutineMetadata; status: IStatus): Cardinal; cdecl; + IExternalEngine_openPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); cdecl; + IExternalEngine_openAttachmentPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl; + IExternalEngine_closeAttachmentPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl; + IExternalEngine_makeFunctionPtr = function(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalFunction; cdecl; + IExternalEngine_makeProcedurePtr = function(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalProcedure; cdecl; + IExternalEngine_makeTriggerPtr = function(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder): IExternalTrigger; cdecl; + ITimer_handlerPtr = procedure(this: ITimer); cdecl; + ITimerControl_startPtr = procedure(this: ITimerControl; status: IStatus; timer: ITimer; microSeconds: QWord); cdecl; + ITimerControl_stopPtr = procedure(this: ITimerControl; status: IStatus; timer: ITimer); cdecl; + IVersionCallback_callbackPtr = procedure(this: IVersionCallback; status: IStatus; text: PAnsiChar); cdecl; + IUtil_getFbVersionPtr = procedure(this: IUtil; status: IStatus; att: IAttachment; callback: IVersionCallback); cdecl; + IUtil_loadBlobPtr = procedure(this: IUtil; status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); cdecl; + IUtil_dumpBlobPtr = procedure(this: IUtil; status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); cdecl; + IUtil_getPerfCountersPtr = procedure(this: IUtil; status: IStatus; att: IAttachment; countersSet: PAnsiChar; counters: Int64Ptr); cdecl; + IUtil_executeCreateDatabasePtr = function(this: IUtil; status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; stmtIsCreateDb: BooleanPtr): IAttachment; cdecl; + IUtil_decodeDatePtr = procedure(this: IUtil; date: ISC_DATE; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr); cdecl; + IUtil_decodeTimePtr = procedure(this: IUtil; time: ISC_TIME; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr); cdecl; + IUtil_encodeDatePtr = function(this: IUtil; year: Cardinal; month: Cardinal; day: Cardinal): ISC_DATE; cdecl; + IUtil_encodeTimePtr = function(this: IUtil; hours: Cardinal; minutes: Cardinal; seconds: Cardinal; fractions: Cardinal): ISC_TIME; cdecl; + IUtil_formatStatusPtr = function(this: IUtil; buffer: PAnsiChar; bufferSize: Cardinal; status: IStatus): Cardinal; cdecl; + IUtil_getClientVersionPtr = function(this: IUtil): Cardinal; cdecl; + IUtil_getXpbBuilderPtr = function(this: IUtil; status: IStatus; kind: Cardinal; buf: BytePtr; len: Cardinal): IXpbBuilder; cdecl; + IUtil_setOffsetsPtr = function(this: IUtil; status: IStatus; metadata: IMessageMetadata; callback: IOffsetsCallback): Cardinal; cdecl; + IOffsetsCallback_setOffsetPtr = procedure(this: IOffsetsCallback; status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); cdecl; + IXpbBuilder_clearPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl; + IXpbBuilder_removeCurrentPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl; + IXpbBuilder_insertIntPtr = procedure(this: IXpbBuilder; status: IStatus; tag: Byte; value: Integer); cdecl; + IXpbBuilder_insertBigIntPtr = procedure(this: IXpbBuilder; status: IStatus; tag: Byte; value: Int64); cdecl; + IXpbBuilder_insertBytesPtr = procedure(this: IXpbBuilder; status: IStatus; tag: Byte; bytes: Pointer; length: Cardinal); cdecl; + IXpbBuilder_insertStringPtr = procedure(this: IXpbBuilder; status: IStatus; tag: Byte; str: PAnsiChar); cdecl; + IXpbBuilder_insertTagPtr = procedure(this: IXpbBuilder; status: IStatus; tag: Byte); cdecl; + IXpbBuilder_isEofPtr = function(this: IXpbBuilder; status: IStatus): Boolean; cdecl; + IXpbBuilder_moveNextPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl; + IXpbBuilder_rewindPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl; + IXpbBuilder_findFirstPtr = function(this: IXpbBuilder; status: IStatus; tag: Byte): Boolean; cdecl; + IXpbBuilder_findNextPtr = function(this: IXpbBuilder; status: IStatus): Boolean; cdecl; + IXpbBuilder_getTagPtr = function(this: IXpbBuilder; status: IStatus): Byte; cdecl; + IXpbBuilder_getLengthPtr = function(this: IXpbBuilder; status: IStatus): Cardinal; cdecl; + IXpbBuilder_getIntPtr = function(this: IXpbBuilder; status: IStatus): Integer; cdecl; + IXpbBuilder_getBigIntPtr = function(this: IXpbBuilder; status: IStatus): Int64; cdecl; + IXpbBuilder_getStringPtr = function(this: IXpbBuilder; status: IStatus): PAnsiChar; cdecl; + IXpbBuilder_getBytesPtr = function(this: IXpbBuilder; status: IStatus): BytePtr; cdecl; + IXpbBuilder_getBufferLengthPtr = function(this: IXpbBuilder; status: IStatus): Cardinal; cdecl; + IXpbBuilder_getBufferPtr = function(this: IXpbBuilder; status: IStatus): BytePtr; cdecl; + ITraceConnection_getKindPtr = function(this: ITraceConnection): Cardinal; cdecl; + ITraceConnection_getProcessIDPtr = function(this: ITraceConnection): Integer; cdecl; + ITraceConnection_getUserNamePtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceConnection_getRoleNamePtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceConnection_getCharSetPtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceConnection_getRemoteProtocolPtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceConnection_getRemoteAddressPtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceConnection_getRemoteProcessIDPtr = function(this: ITraceConnection): Integer; cdecl; + ITraceConnection_getRemoteProcessNamePtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceDatabaseConnection_getConnectionIDPtr = function(this: ITraceDatabaseConnection): Int64; cdecl; + ITraceDatabaseConnection_getDatabaseNamePtr = function(this: ITraceDatabaseConnection): PAnsiChar; cdecl; + ITraceTransaction_getTransactionIDPtr = function(this: ITraceTransaction): Int64; cdecl; + ITraceTransaction_getReadOnlyPtr = function(this: ITraceTransaction): Boolean; cdecl; + ITraceTransaction_getWaitPtr = function(this: ITraceTransaction): Integer; cdecl; + ITraceTransaction_getIsolationPtr = function(this: ITraceTransaction): Cardinal; cdecl; + ITraceTransaction_getPerfPtr = function(this: ITraceTransaction): PerformanceInfoPtr; cdecl; + ITraceParams_getCountPtr = function(this: ITraceParams): Cardinal; cdecl; + ITraceParams_getParamPtr = function(this: ITraceParams; idx: Cardinal): dscPtr; cdecl; + ITraceStatement_getStmtIDPtr = function(this: ITraceStatement): Int64; cdecl; + ITraceStatement_getPerfPtr = function(this: ITraceStatement): PerformanceInfoPtr; cdecl; + ITraceSQLStatement_getTextPtr = function(this: ITraceSQLStatement): PAnsiChar; cdecl; + ITraceSQLStatement_getPlanPtr = function(this: ITraceSQLStatement): PAnsiChar; cdecl; + ITraceSQLStatement_getInputsPtr = function(this: ITraceSQLStatement): ITraceParams; cdecl; + ITraceSQLStatement_getTextUTF8Ptr = function(this: ITraceSQLStatement): PAnsiChar; cdecl; + ITraceSQLStatement_getExplainedPlanPtr = function(this: ITraceSQLStatement): PAnsiChar; cdecl; + ITraceBLRStatement_getDataPtr = function(this: ITraceBLRStatement): BytePtr; cdecl; + ITraceBLRStatement_getDataLengthPtr = function(this: ITraceBLRStatement): Cardinal; cdecl; + ITraceBLRStatement_getTextPtr = function(this: ITraceBLRStatement): PAnsiChar; cdecl; + ITraceDYNRequest_getDataPtr = function(this: ITraceDYNRequest): BytePtr; cdecl; + ITraceDYNRequest_getDataLengthPtr = function(this: ITraceDYNRequest): Cardinal; cdecl; + ITraceDYNRequest_getTextPtr = function(this: ITraceDYNRequest): PAnsiChar; cdecl; + ITraceContextVariable_getNameSpacePtr = function(this: ITraceContextVariable): PAnsiChar; cdecl; + ITraceContextVariable_getVarNamePtr = function(this: ITraceContextVariable): PAnsiChar; cdecl; + ITraceContextVariable_getVarValuePtr = function(this: ITraceContextVariable): PAnsiChar; cdecl; + ITraceProcedure_getProcNamePtr = function(this: ITraceProcedure): PAnsiChar; cdecl; + ITraceProcedure_getInputsPtr = function(this: ITraceProcedure): ITraceParams; cdecl; + ITraceProcedure_getPerfPtr = function(this: ITraceProcedure): PerformanceInfoPtr; cdecl; + ITraceFunction_getFuncNamePtr = function(this: ITraceFunction): PAnsiChar; cdecl; + ITraceFunction_getInputsPtr = function(this: ITraceFunction): ITraceParams; cdecl; + ITraceFunction_getResultPtr = function(this: ITraceFunction): ITraceParams; cdecl; + ITraceFunction_getPerfPtr = function(this: ITraceFunction): PerformanceInfoPtr; cdecl; + ITraceTrigger_getTriggerNamePtr = function(this: ITraceTrigger): PAnsiChar; cdecl; + ITraceTrigger_getRelationNamePtr = function(this: ITraceTrigger): PAnsiChar; cdecl; + ITraceTrigger_getActionPtr = function(this: ITraceTrigger): Integer; cdecl; + ITraceTrigger_getWhichPtr = function(this: ITraceTrigger): Integer; cdecl; + ITraceTrigger_getPerfPtr = function(this: ITraceTrigger): PerformanceInfoPtr; cdecl; + ITraceServiceConnection_getServiceIDPtr = function(this: ITraceServiceConnection): Pointer; cdecl; + ITraceServiceConnection_getServiceMgrPtr = function(this: ITraceServiceConnection): PAnsiChar; cdecl; + ITraceServiceConnection_getServiceNamePtr = function(this: ITraceServiceConnection): PAnsiChar; cdecl; + ITraceStatusVector_hasErrorPtr = function(this: ITraceStatusVector): Boolean; cdecl; + ITraceStatusVector_hasWarningPtr = function(this: ITraceStatusVector): Boolean; cdecl; + ITraceStatusVector_getStatusPtr = function(this: ITraceStatusVector): IStatus; cdecl; + ITraceStatusVector_getTextPtr = function(this: ITraceStatusVector): PAnsiChar; cdecl; + ITraceSweepInfo_getOITPtr = function(this: ITraceSweepInfo): Int64; cdecl; + ITraceSweepInfo_getOSTPtr = function(this: ITraceSweepInfo): Int64; cdecl; + ITraceSweepInfo_getOATPtr = function(this: ITraceSweepInfo): Int64; cdecl; + ITraceSweepInfo_getNextPtr = function(this: ITraceSweepInfo): Int64; cdecl; + ITraceSweepInfo_getPerfPtr = function(this: ITraceSweepInfo): PerformanceInfoPtr; cdecl; + ITraceLogWriter_writePtr = function(this: ITraceLogWriter; buf: Pointer; size: Cardinal): Cardinal; cdecl; + ITraceInitInfo_getConfigTextPtr = function(this: ITraceInitInfo): PAnsiChar; cdecl; + ITraceInitInfo_getTraceSessionIDPtr = function(this: ITraceInitInfo): Integer; cdecl; + ITraceInitInfo_getTraceSessionNamePtr = function(this: ITraceInitInfo): PAnsiChar; cdecl; + ITraceInitInfo_getFirebirdRootDirectoryPtr = function(this: ITraceInitInfo): PAnsiChar; cdecl; + ITraceInitInfo_getDatabaseNamePtr = function(this: ITraceInitInfo): PAnsiChar; cdecl; + ITraceInitInfo_getConnectionPtr = function(this: ITraceInitInfo): ITraceDatabaseConnection; cdecl; + ITraceInitInfo_getLogWriterPtr = function(this: ITraceInitInfo): ITraceLogWriter; cdecl; + ITracePlugin_trace_get_errorPtr = function(this: ITracePlugin): PAnsiChar; cdecl; + ITracePlugin_trace_attachPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; create_db: Boolean; att_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_detachPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; drop_db: Boolean): Boolean; cdecl; + ITracePlugin_trace_transaction_startPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; tpb_length: Cardinal; tpb: BytePtr; tra_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_transaction_endPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; commit: Boolean; retain_context: Boolean; tra_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_proc_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; procedure_: ITraceProcedure; started: Boolean; proc_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_trigger_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; trigger: ITraceTrigger; started: Boolean; trig_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_set_contextPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; variable: ITraceContextVariable): Boolean; cdecl; + ITracePlugin_trace_dsql_preparePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_dsql_freePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; statement: ITraceSQLStatement; option: Cardinal): Boolean; cdecl; + ITracePlugin_trace_dsql_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; started: Boolean; req_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_blr_compilePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_blr_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; req_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_dyn_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; request: ITraceDYNRequest; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_service_attachPtr = function(this: ITracePlugin; service: ITraceServiceConnection; att_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_service_startPtr = function(this: ITracePlugin; service: ITraceServiceConnection; switches_length: Cardinal; switches: PAnsiChar; start_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_service_queryPtr = function(this: ITracePlugin; service: ITraceServiceConnection; send_item_length: Cardinal; send_items: BytePtr; recv_item_length: Cardinal; recv_items: BytePtr; query_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_service_detachPtr = function(this: ITracePlugin; service: ITraceServiceConnection; detach_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_event_errorPtr = function(this: ITracePlugin; connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; cdecl; + ITracePlugin_trace_event_sweepPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; cdecl; + ITracePlugin_trace_func_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; cdecl; + ITraceFactory_trace_needsPtr = function(this: ITraceFactory): QWord; cdecl; + ITraceFactory_trace_createPtr = function(this: ITraceFactory; status: IStatus; init_info: ITraceInitInfo): ITracePlugin; cdecl; + IUdrFunctionFactory_setupPtr = procedure(this: IUdrFunctionFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); cdecl; + IUdrFunctionFactory_newItemPtr = function(this: IUdrFunctionFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalFunction; cdecl; + IUdrProcedureFactory_setupPtr = procedure(this: IUdrProcedureFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); cdecl; + IUdrProcedureFactory_newItemPtr = function(this: IUdrProcedureFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalProcedure; cdecl; + IUdrTriggerFactory_setupPtr = procedure(this: IUdrTriggerFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder); cdecl; + IUdrTriggerFactory_newItemPtr = function(this: IUdrTriggerFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalTrigger; cdecl; + IUdrPlugin_getMasterPtr = function(this: IUdrPlugin): IMaster; cdecl; + IUdrPlugin_registerFunctionPtr = procedure(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrFunctionFactory); cdecl; + IUdrPlugin_registerProcedurePtr = procedure(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrProcedureFactory); cdecl; + IUdrPlugin_registerTriggerPtr = procedure(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrTriggerFactory); cdecl; + + VersionedVTable = class + version: NativeInt; + end; + + IVersioned = class + vTable: VersionedVTable; + + const VERSION = 0; + + end; + + IVersionedImpl = class(IVersioned) + constructor create; + + end; + + ReferenceCountedVTable = class(VersionedVTable) + addRef: IReferenceCounted_addRefPtr; + release: IReferenceCounted_releasePtr; + end; + + IReferenceCounted = class(IVersioned) + const VERSION = 2; + + procedure addRef(); + function release(): Integer; + end; + + IReferenceCountedImpl = class(IReferenceCounted) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + end; + + DisposableVTable = class(VersionedVTable) + dispose: IDisposable_disposePtr; + end; + + IDisposable = class(IVersioned) + const VERSION = 1; + + procedure dispose(); + end; + + IDisposableImpl = class(IDisposable) + constructor create; + + procedure dispose(); virtual; abstract; + end; + + StatusVTable = class(DisposableVTable) + init: IStatus_initPtr; + getState: IStatus_getStatePtr; + setErrors2: IStatus_setErrors2Ptr; + setWarnings2: IStatus_setWarnings2Ptr; + setErrors: IStatus_setErrorsPtr; + setWarnings: IStatus_setWarningsPtr; + getErrors: IStatus_getErrorsPtr; + getWarnings: IStatus_getWarningsPtr; + clone: IStatus_clonePtr; + end; + + IStatus = class(IDisposable) + const VERSION = 10; + const STATE_WARNINGS = Cardinal(1); + const STATE_ERRORS = Cardinal(2); + const RESULT_ERROR = Integer(-1); + const RESULT_OK = Integer(0); + const RESULT_NO_DATA = Integer(1); + const RESULT_SEGMENT = Integer(2); + + procedure init(); + function getState(): Cardinal; + procedure setErrors2(length: Cardinal; value: NativeIntPtr); + procedure setWarnings2(length: Cardinal; value: NativeIntPtr); + procedure setErrors(value: NativeIntPtr); + procedure setWarnings(value: NativeIntPtr); + function getErrors(): NativeIntPtr; + function getWarnings(): NativeIntPtr; + function clone(): IStatus; + end; + + IStatusImpl = class(IStatus) + constructor create; + + procedure dispose(); virtual; abstract; + procedure init(); virtual; abstract; + function getState(): Cardinal; virtual; abstract; + procedure setErrors2(length: Cardinal; value: NativeIntPtr); virtual; abstract; + procedure setWarnings2(length: Cardinal; value: NativeIntPtr); virtual; abstract; + procedure setErrors(value: NativeIntPtr); virtual; abstract; + procedure setWarnings(value: NativeIntPtr); virtual; abstract; + function getErrors(): NativeIntPtr; virtual; abstract; + function getWarnings(): NativeIntPtr; virtual; abstract; + function clone(): IStatus; virtual; abstract; + end; + + MasterVTable = class(VersionedVTable) + getStatus: IMaster_getStatusPtr; + getDispatcher: IMaster_getDispatcherPtr; + getPluginManager: IMaster_getPluginManagerPtr; + getTimerControl: IMaster_getTimerControlPtr; + getDtc: IMaster_getDtcPtr; + registerAttachment: IMaster_registerAttachmentPtr; + registerTransaction: IMaster_registerTransactionPtr; + getMetadataBuilder: IMaster_getMetadataBuilderPtr; + serverMode: IMaster_serverModePtr; + getUtilInterface: IMaster_getUtilInterfacePtr; + getConfigManager: IMaster_getConfigManagerPtr; + getProcessExiting: IMaster_getProcessExitingPtr; + end; + + IMaster = class(IVersioned) + const VERSION = 12; + + function getStatus(): IStatus; + function getDispatcher(): IProvider; + function getPluginManager(): IPluginManager; + function getTimerControl(): ITimerControl; + function getDtc(): IDtc; + function registerAttachment(provider: IProvider; attachment: IAttachment): IAttachment; + function registerTransaction(attachment: IAttachment; transaction: ITransaction): ITransaction; + function getMetadataBuilder(status: IStatus; fieldCount: Cardinal): IMetadataBuilder; + function serverMode(mode: Integer): Integer; + function getUtilInterface(): IUtil; + function getConfigManager(): IConfigManager; + function getProcessExiting(): Boolean; + end; + + IMasterImpl = class(IMaster) + constructor create; + + function getStatus(): IStatus; virtual; abstract; + function getDispatcher(): IProvider; virtual; abstract; + function getPluginManager(): IPluginManager; virtual; abstract; + function getTimerControl(): ITimerControl; virtual; abstract; + function getDtc(): IDtc; virtual; abstract; + function registerAttachment(provider: IProvider; attachment: IAttachment): IAttachment; virtual; abstract; + function registerTransaction(attachment: IAttachment; transaction: ITransaction): ITransaction; virtual; abstract; + function getMetadataBuilder(status: IStatus; fieldCount: Cardinal): IMetadataBuilder; virtual; abstract; + function serverMode(mode: Integer): Integer; virtual; abstract; + function getUtilInterface(): IUtil; virtual; abstract; + function getConfigManager(): IConfigManager; virtual; abstract; + function getProcessExiting(): Boolean; virtual; abstract; + end; + + PluginBaseVTable = class(ReferenceCountedVTable) + setOwner: IPluginBase_setOwnerPtr; + getOwner: IPluginBase_getOwnerPtr; + end; + + IPluginBase = class(IReferenceCounted) + const VERSION = 4; + + procedure setOwner(r: IReferenceCounted); + function getOwner(): IReferenceCounted; + end; + + IPluginBaseImpl = class(IPluginBase) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + end; + + PluginSetVTable = class(ReferenceCountedVTable) + getName: IPluginSet_getNamePtr; + getModuleName: IPluginSet_getModuleNamePtr; + getPlugin: IPluginSet_getPluginPtr; + next: IPluginSet_nextPtr; + set_: IPluginSet_set_Ptr; + end; + + IPluginSet = class(IReferenceCounted) + const VERSION = 7; + + function getName(): PAnsiChar; + function getModuleName(): PAnsiChar; + function getPlugin(status: IStatus): IPluginBase; + procedure next(status: IStatus); + procedure set_(status: IStatus; s: PAnsiChar); + end; + + IPluginSetImpl = class(IPluginSet) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getName(): PAnsiChar; virtual; abstract; + function getModuleName(): PAnsiChar; virtual; abstract; + function getPlugin(status: IStatus): IPluginBase; virtual; abstract; + procedure next(status: IStatus); virtual; abstract; + procedure set_(status: IStatus; s: PAnsiChar); virtual; abstract; + end; + + ConfigEntryVTable = class(ReferenceCountedVTable) + getName: IConfigEntry_getNamePtr; + getValue: IConfigEntry_getValuePtr; + getIntValue: IConfigEntry_getIntValuePtr; + getBoolValue: IConfigEntry_getBoolValuePtr; + getSubConfig: IConfigEntry_getSubConfigPtr; + end; + + IConfigEntry = class(IReferenceCounted) + const VERSION = 7; + + function getName(): PAnsiChar; + function getValue(): PAnsiChar; + function getIntValue(): Int64; + function getBoolValue(): Boolean; + function getSubConfig(status: IStatus): IConfig; + end; + + IConfigEntryImpl = class(IConfigEntry) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getName(): PAnsiChar; virtual; abstract; + function getValue(): PAnsiChar; virtual; abstract; + function getIntValue(): Int64; virtual; abstract; + function getBoolValue(): Boolean; virtual; abstract; + function getSubConfig(status: IStatus): IConfig; virtual; abstract; + end; + + ConfigVTable = class(ReferenceCountedVTable) + find: IConfig_findPtr; + findValue: IConfig_findValuePtr; + findPos: IConfig_findPosPtr; + end; + + IConfig = class(IReferenceCounted) + const VERSION = 5; + + function find(status: IStatus; name: PAnsiChar): IConfigEntry; + function findValue(status: IStatus; name: PAnsiChar; value: PAnsiChar): IConfigEntry; + function findPos(status: IStatus; name: PAnsiChar; pos: Cardinal): IConfigEntry; + end; + + IConfigImpl = class(IConfig) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function find(status: IStatus; name: PAnsiChar): IConfigEntry; virtual; abstract; + function findValue(status: IStatus; name: PAnsiChar; value: PAnsiChar): IConfigEntry; virtual; abstract; + function findPos(status: IStatus; name: PAnsiChar; pos: Cardinal): IConfigEntry; virtual; abstract; + end; + + FirebirdConfVTable = class(ReferenceCountedVTable) + getKey: IFirebirdConf_getKeyPtr; + asInteger: IFirebirdConf_asIntegerPtr; + asString: IFirebirdConf_asStringPtr; + asBoolean: IFirebirdConf_asBooleanPtr; + end; + + IFirebirdConf = class(IReferenceCounted) + const VERSION = 6; + + function getKey(name: PAnsiChar): Cardinal; + function asInteger(key: Cardinal): Int64; + function asString(key: Cardinal): PAnsiChar; + function asBoolean(key: Cardinal): Boolean; + end; + + IFirebirdConfImpl = class(IFirebirdConf) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getKey(name: PAnsiChar): Cardinal; virtual; abstract; + function asInteger(key: Cardinal): Int64; virtual; abstract; + function asString(key: Cardinal): PAnsiChar; virtual; abstract; + function asBoolean(key: Cardinal): Boolean; virtual; abstract; + end; + + PluginConfigVTable = class(ReferenceCountedVTable) + getConfigFileName: IPluginConfig_getConfigFileNamePtr; + getDefaultConfig: IPluginConfig_getDefaultConfigPtr; + getFirebirdConf: IPluginConfig_getFirebirdConfPtr; + setReleaseDelay: IPluginConfig_setReleaseDelayPtr; + end; + + IPluginConfig = class(IReferenceCounted) + const VERSION = 6; + + function getConfigFileName(): PAnsiChar; + function getDefaultConfig(status: IStatus): IConfig; + function getFirebirdConf(status: IStatus): IFirebirdConf; + procedure setReleaseDelay(status: IStatus; microSeconds: QWord); + end; + + IPluginConfigImpl = class(IPluginConfig) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getConfigFileName(): PAnsiChar; virtual; abstract; + function getDefaultConfig(status: IStatus): IConfig; virtual; abstract; + function getFirebirdConf(status: IStatus): IFirebirdConf; virtual; abstract; + procedure setReleaseDelay(status: IStatus; microSeconds: QWord); virtual; abstract; + end; + + PluginFactoryVTable = class(VersionedVTable) + createPlugin: IPluginFactory_createPluginPtr; + end; + + IPluginFactory = class(IVersioned) + const VERSION = 1; + + function createPlugin(status: IStatus; factoryParameter: IPluginConfig): IPluginBase; + end; + + IPluginFactoryImpl = class(IPluginFactory) + constructor create; + + function createPlugin(status: IStatus; factoryParameter: IPluginConfig): IPluginBase; virtual; abstract; + end; + + PluginModuleVTable = class(VersionedVTable) + doClean: IPluginModule_doCleanPtr; + end; + + IPluginModule = class(IVersioned) + const VERSION = 1; + + procedure doClean(); + end; + + IPluginModuleImpl = class(IPluginModule) + constructor create; + + procedure doClean(); virtual; abstract; + end; + + PluginManagerVTable = class(VersionedVTable) + registerPluginFactory: IPluginManager_registerPluginFactoryPtr; + registerModule: IPluginManager_registerModulePtr; + unregisterModule: IPluginManager_unregisterModulePtr; + getPlugins: IPluginManager_getPluginsPtr; + getConfig: IPluginManager_getConfigPtr; + releasePlugin: IPluginManager_releasePluginPtr; + end; + + IPluginManager = class(IVersioned) + const VERSION = 6; + const TYPE_PROVIDER = Cardinal(1); + const TYPE_FIRST_NON_LIB = Cardinal(2); + const TYPE_AUTH_SERVER = Cardinal(3); + const TYPE_AUTH_CLIENT = Cardinal(4); + const TYPE_AUTH_USER_MANAGEMENT = Cardinal(5); + const TYPE_EXTERNAL_ENGINE = Cardinal(6); + const TYPE_TRACE = Cardinal(7); + const TYPE_WIRE_CRYPT = Cardinal(8); + const TYPE_DB_CRYPT = Cardinal(9); + const TYPE_KEY_HOLDER = Cardinal(10); + const TYPE_COUNT = Cardinal(11); + + procedure registerPluginFactory(pluginType: Cardinal; defaultName: PAnsiChar; factory: IPluginFactory); + procedure registerModule(cleanup: IPluginModule); + procedure unregisterModule(cleanup: IPluginModule); + function getPlugins(status: IStatus; pluginType: Cardinal; namesList: PAnsiChar; firebirdConf: IFirebirdConf): IPluginSet; + function getConfig(status: IStatus; filename: PAnsiChar): IConfig; + procedure releasePlugin(plugin: IPluginBase); + end; + + IPluginManagerImpl = class(IPluginManager) + constructor create; + + procedure registerPluginFactory(pluginType: Cardinal; defaultName: PAnsiChar; factory: IPluginFactory); virtual; abstract; + procedure registerModule(cleanup: IPluginModule); virtual; abstract; + procedure unregisterModule(cleanup: IPluginModule); virtual; abstract; + function getPlugins(status: IStatus; pluginType: Cardinal; namesList: PAnsiChar; firebirdConf: IFirebirdConf): IPluginSet; virtual; abstract; + function getConfig(status: IStatus; filename: PAnsiChar): IConfig; virtual; abstract; + procedure releasePlugin(plugin: IPluginBase); virtual; abstract; + end; + + CryptKeyVTable = class(VersionedVTable) + setSymmetric: ICryptKey_setSymmetricPtr; + setAsymmetric: ICryptKey_setAsymmetricPtr; + getEncryptKey: ICryptKey_getEncryptKeyPtr; + getDecryptKey: ICryptKey_getDecryptKeyPtr; + end; + + ICryptKey = class(IVersioned) + const VERSION = 4; + + procedure setSymmetric(status: IStatus; type_: PAnsiChar; keyLength: Cardinal; key: Pointer); + procedure setAsymmetric(status: IStatus; type_: PAnsiChar; encryptKeyLength: Cardinal; encryptKey: Pointer; decryptKeyLength: Cardinal; decryptKey: Pointer); + function getEncryptKey(length: CardinalPtr): Pointer; + function getDecryptKey(length: CardinalPtr): Pointer; + end; + + ICryptKeyImpl = class(ICryptKey) + constructor create; + + procedure setSymmetric(status: IStatus; type_: PAnsiChar; keyLength: Cardinal; key: Pointer); virtual; abstract; + procedure setAsymmetric(status: IStatus; type_: PAnsiChar; encryptKeyLength: Cardinal; encryptKey: Pointer; decryptKeyLength: Cardinal; decryptKey: Pointer); virtual; abstract; + function getEncryptKey(length: CardinalPtr): Pointer; virtual; abstract; + function getDecryptKey(length: CardinalPtr): Pointer; virtual; abstract; + end; + + ConfigManagerVTable = class(VersionedVTable) + getDirectory: IConfigManager_getDirectoryPtr; + getFirebirdConf: IConfigManager_getFirebirdConfPtr; + getDatabaseConf: IConfigManager_getDatabaseConfPtr; + getPluginConfig: IConfigManager_getPluginConfigPtr; + getInstallDirectory: IConfigManager_getInstallDirectoryPtr; + getRootDirectory: IConfigManager_getRootDirectoryPtr; + end; + + IConfigManager = class(IVersioned) + const VERSION = 6; + const DIR_BIN = Cardinal(0); + const DIR_SBIN = Cardinal(1); + const DIR_CONF = Cardinal(2); + const DIR_LIB = Cardinal(3); + const DIR_INC = Cardinal(4); + const DIR_DOC = Cardinal(5); + const DIR_UDF = Cardinal(6); + const DIR_SAMPLE = Cardinal(7); + const DIR_SAMPLEDB = Cardinal(8); + const DIR_HELP = Cardinal(9); + const DIR_INTL = Cardinal(10); + const DIR_MISC = Cardinal(11); + const DIR_SECDB = Cardinal(12); + const DIR_MSG = Cardinal(13); + const DIR_LOG = Cardinal(14); + const DIR_GUARD = Cardinal(15); + const DIR_PLUGINS = Cardinal(16); + const DIR_COUNT = Cardinal(17); + + function getDirectory(code: Cardinal): PAnsiChar; + function getFirebirdConf(): IFirebirdConf; + function getDatabaseConf(dbName: PAnsiChar): IFirebirdConf; + function getPluginConfig(configuredPlugin: PAnsiChar): IConfig; + function getInstallDirectory(): PAnsiChar; + function getRootDirectory(): PAnsiChar; + end; + + IConfigManagerImpl = class(IConfigManager) + constructor create; + + function getDirectory(code: Cardinal): PAnsiChar; virtual; abstract; + function getFirebirdConf(): IFirebirdConf; virtual; abstract; + function getDatabaseConf(dbName: PAnsiChar): IFirebirdConf; virtual; abstract; + function getPluginConfig(configuredPlugin: PAnsiChar): IConfig; virtual; abstract; + function getInstallDirectory(): PAnsiChar; virtual; abstract; + function getRootDirectory(): PAnsiChar; virtual; abstract; + end; + + EventCallbackVTable = class(ReferenceCountedVTable) + eventCallbackFunction: IEventCallback_eventCallbackFunctionPtr; + end; + + IEventCallback = class(IReferenceCounted) + const VERSION = 3; + + procedure eventCallbackFunction(length: Cardinal; events: BytePtr); + end; + + IEventCallbackImpl = class(IEventCallback) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure eventCallbackFunction(length: Cardinal; events: BytePtr); virtual; abstract; + end; + + BlobVTable = class(ReferenceCountedVTable) + getInfo: IBlob_getInfoPtr; + getSegment: IBlob_getSegmentPtr; + putSegment: IBlob_putSegmentPtr; + cancel: IBlob_cancelPtr; + close: IBlob_closePtr; + seek: IBlob_seekPtr; + end; + + IBlob = class(IReferenceCounted) + const VERSION = 8; + + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + function getSegment(status: IStatus; bufferLength: Cardinal; buffer: Pointer; segmentLength: CardinalPtr): Integer; + procedure putSegment(status: IStatus; length: Cardinal; buffer: Pointer); + procedure cancel(status: IStatus); + procedure close(status: IStatus); + function seek(status: IStatus; mode: Integer; offset: Integer): Integer; + end; + + IBlobImpl = class(IBlob) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + function getSegment(status: IStatus; bufferLength: Cardinal; buffer: Pointer; segmentLength: CardinalPtr): Integer; virtual; abstract; + procedure putSegment(status: IStatus; length: Cardinal; buffer: Pointer); virtual; abstract; + procedure cancel(status: IStatus); virtual; abstract; + procedure close(status: IStatus); virtual; abstract; + function seek(status: IStatus; mode: Integer; offset: Integer): Integer; virtual; abstract; + end; + + TransactionVTable = class(ReferenceCountedVTable) + getInfo: ITransaction_getInfoPtr; + prepare: ITransaction_preparePtr; + commit: ITransaction_commitPtr; + commitRetaining: ITransaction_commitRetainingPtr; + rollback: ITransaction_rollbackPtr; + rollbackRetaining: ITransaction_rollbackRetainingPtr; + disconnect: ITransaction_disconnectPtr; + join: ITransaction_joinPtr; + validate: ITransaction_validatePtr; + enterDtc: ITransaction_enterDtcPtr; + end; + + ITransaction = class(IReferenceCounted) + const VERSION = 12; + + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + procedure prepare(status: IStatus; msgLength: Cardinal; message: BytePtr); + procedure commit(status: IStatus); + procedure commitRetaining(status: IStatus); + procedure rollback(status: IStatus); + procedure rollbackRetaining(status: IStatus); + procedure disconnect(status: IStatus); + function join(status: IStatus; transaction: ITransaction): ITransaction; + function validate(status: IStatus; attachment: IAttachment): ITransaction; + function enterDtc(status: IStatus): ITransaction; + end; + + ITransactionImpl = class(ITransaction) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + procedure prepare(status: IStatus; msgLength: Cardinal; message: BytePtr); virtual; abstract; + procedure commit(status: IStatus); virtual; abstract; + procedure commitRetaining(status: IStatus); virtual; abstract; + procedure rollback(status: IStatus); virtual; abstract; + procedure rollbackRetaining(status: IStatus); virtual; abstract; + procedure disconnect(status: IStatus); virtual; abstract; + function join(status: IStatus; transaction: ITransaction): ITransaction; virtual; abstract; + function validate(status: IStatus; attachment: IAttachment): ITransaction; virtual; abstract; + function enterDtc(status: IStatus): ITransaction; virtual; abstract; + end; + + MessageMetadataVTable = class(ReferenceCountedVTable) + getCount: IMessageMetadata_getCountPtr; + getField: IMessageMetadata_getFieldPtr; + getRelation: IMessageMetadata_getRelationPtr; + getOwner: IMessageMetadata_getOwnerPtr; + getAlias: IMessageMetadata_getAliasPtr; + getType: IMessageMetadata_getTypePtr; + isNullable: IMessageMetadata_isNullablePtr; + getSubType: IMessageMetadata_getSubTypePtr; + getLength: IMessageMetadata_getLengthPtr; + getScale: IMessageMetadata_getScalePtr; + getCharSet: IMessageMetadata_getCharSetPtr; + getOffset: IMessageMetadata_getOffsetPtr; + getNullOffset: IMessageMetadata_getNullOffsetPtr; + getBuilder: IMessageMetadata_getBuilderPtr; + getMessageLength: IMessageMetadata_getMessageLengthPtr; + end; + + IMessageMetadata = class(IReferenceCounted) + const VERSION = 17; + + function getCount(status: IStatus): Cardinal; + function getField(status: IStatus; index: Cardinal): PAnsiChar; + function getRelation(status: IStatus; index: Cardinal): PAnsiChar; + function getOwner(status: IStatus; index: Cardinal): PAnsiChar; + function getAlias(status: IStatus; index: Cardinal): PAnsiChar; + function getType(status: IStatus; index: Cardinal): Cardinal; + function isNullable(status: IStatus; index: Cardinal): Boolean; + function getSubType(status: IStatus; index: Cardinal): Integer; + function getLength(status: IStatus; index: Cardinal): Cardinal; + function getScale(status: IStatus; index: Cardinal): Integer; + function getCharSet(status: IStatus; index: Cardinal): Cardinal; + function getOffset(status: IStatus; index: Cardinal): Cardinal; + function getNullOffset(status: IStatus; index: Cardinal): Cardinal; + function getBuilder(status: IStatus): IMetadataBuilder; + function getMessageLength(status: IStatus): Cardinal; + end; + + IMessageMetadataImpl = class(IMessageMetadata) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getCount(status: IStatus): Cardinal; virtual; abstract; + function getField(status: IStatus; index: Cardinal): PAnsiChar; virtual; abstract; + function getRelation(status: IStatus; index: Cardinal): PAnsiChar; virtual; abstract; + function getOwner(status: IStatus; index: Cardinal): PAnsiChar; virtual; abstract; + function getAlias(status: IStatus; index: Cardinal): PAnsiChar; virtual; abstract; + function getType(status: IStatus; index: Cardinal): Cardinal; virtual; abstract; + function isNullable(status: IStatus; index: Cardinal): Boolean; virtual; abstract; + function getSubType(status: IStatus; index: Cardinal): Integer; virtual; abstract; + function getLength(status: IStatus; index: Cardinal): Cardinal; virtual; abstract; + function getScale(status: IStatus; index: Cardinal): Integer; virtual; abstract; + function getCharSet(status: IStatus; index: Cardinal): Cardinal; virtual; abstract; + function getOffset(status: IStatus; index: Cardinal): Cardinal; virtual; abstract; + function getNullOffset(status: IStatus; index: Cardinal): Cardinal; virtual; abstract; + function getBuilder(status: IStatus): IMetadataBuilder; virtual; abstract; + function getMessageLength(status: IStatus): Cardinal; virtual; abstract; + end; + + MetadataBuilderVTable = class(ReferenceCountedVTable) + setType: IMetadataBuilder_setTypePtr; + setSubType: IMetadataBuilder_setSubTypePtr; + setLength: IMetadataBuilder_setLengthPtr; + setCharSet: IMetadataBuilder_setCharSetPtr; + setScale: IMetadataBuilder_setScalePtr; + truncate: IMetadataBuilder_truncatePtr; + moveNameToIndex: IMetadataBuilder_moveNameToIndexPtr; + remove: IMetadataBuilder_removePtr; + addField: IMetadataBuilder_addFieldPtr; + getMetadata: IMetadataBuilder_getMetadataPtr; + end; + + IMetadataBuilder = class(IReferenceCounted) + const VERSION = 12; + + procedure setType(status: IStatus; index: Cardinal; type_: Cardinal); + procedure setSubType(status: IStatus; index: Cardinal; subType: Integer); + procedure setLength(status: IStatus; index: Cardinal; length: Cardinal); + procedure setCharSet(status: IStatus; index: Cardinal; charSet: Cardinal); + procedure setScale(status: IStatus; index: Cardinal; scale: Cardinal); + procedure truncate(status: IStatus; count: Cardinal); + procedure moveNameToIndex(status: IStatus; name: PAnsiChar; index: Cardinal); + procedure remove(status: IStatus; index: Cardinal); + function addField(status: IStatus): Cardinal; + function getMetadata(status: IStatus): IMessageMetadata; + end; + + IMetadataBuilderImpl = class(IMetadataBuilder) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setType(status: IStatus; index: Cardinal; type_: Cardinal); virtual; abstract; + procedure setSubType(status: IStatus; index: Cardinal; subType: Integer); virtual; abstract; + procedure setLength(status: IStatus; index: Cardinal; length: Cardinal); virtual; abstract; + procedure setCharSet(status: IStatus; index: Cardinal; charSet: Cardinal); virtual; abstract; + procedure setScale(status: IStatus; index: Cardinal; scale: Cardinal); virtual; abstract; + procedure truncate(status: IStatus; count: Cardinal); virtual; abstract; + procedure moveNameToIndex(status: IStatus; name: PAnsiChar; index: Cardinal); virtual; abstract; + procedure remove(status: IStatus; index: Cardinal); virtual; abstract; + function addField(status: IStatus): Cardinal; virtual; abstract; + function getMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + end; + + ResultSetVTable = class(ReferenceCountedVTable) + fetchNext: IResultSet_fetchNextPtr; + fetchPrior: IResultSet_fetchPriorPtr; + fetchFirst: IResultSet_fetchFirstPtr; + fetchLast: IResultSet_fetchLastPtr; + fetchAbsolute: IResultSet_fetchAbsolutePtr; + fetchRelative: IResultSet_fetchRelativePtr; + isEof: IResultSet_isEofPtr; + isBof: IResultSet_isBofPtr; + getMetadata: IResultSet_getMetadataPtr; + close: IResultSet_closePtr; + setDelayedOutputFormat: IResultSet_setDelayedOutputFormatPtr; + end; + + IResultSet = class(IReferenceCounted) + const VERSION = 13; + + function fetchNext(status: IStatus; message: Pointer): Integer; + function fetchPrior(status: IStatus; message: Pointer): Integer; + function fetchFirst(status: IStatus; message: Pointer): Integer; + function fetchLast(status: IStatus; message: Pointer): Integer; + function fetchAbsolute(status: IStatus; position: Integer; message: Pointer): Integer; + function fetchRelative(status: IStatus; offset: Integer; message: Pointer): Integer; + function isEof(status: IStatus): Boolean; + function isBof(status: IStatus): Boolean; + function getMetadata(status: IStatus): IMessageMetadata; + procedure close(status: IStatus); + procedure setDelayedOutputFormat(status: IStatus; format: IMessageMetadata); + end; + + IResultSetImpl = class(IResultSet) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function fetchNext(status: IStatus; message: Pointer): Integer; virtual; abstract; + function fetchPrior(status: IStatus; message: Pointer): Integer; virtual; abstract; + function fetchFirst(status: IStatus; message: Pointer): Integer; virtual; abstract; + function fetchLast(status: IStatus; message: Pointer): Integer; virtual; abstract; + function fetchAbsolute(status: IStatus; position: Integer; message: Pointer): Integer; virtual; abstract; + function fetchRelative(status: IStatus; offset: Integer; message: Pointer): Integer; virtual; abstract; + function isEof(status: IStatus): Boolean; virtual; abstract; + function isBof(status: IStatus): Boolean; virtual; abstract; + function getMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + procedure close(status: IStatus); virtual; abstract; + procedure setDelayedOutputFormat(status: IStatus; format: IMessageMetadata); virtual; abstract; + end; + + StatementVTable = class(ReferenceCountedVTable) + getInfo: IStatement_getInfoPtr; + getType: IStatement_getTypePtr; + getPlan: IStatement_getPlanPtr; + getAffectedRecords: IStatement_getAffectedRecordsPtr; + getInputMetadata: IStatement_getInputMetadataPtr; + getOutputMetadata: IStatement_getOutputMetadataPtr; + execute: IStatement_executePtr; + openCursor: IStatement_openCursorPtr; + setCursorName: IStatement_setCursorNamePtr; + free: IStatement_freePtr; + getFlags: IStatement_getFlagsPtr; + end; + + IStatement = class(IReferenceCounted) + const VERSION = 13; + const PREPARE_PREFETCH_NONE = Cardinal(0); + const PREPARE_PREFETCH_TYPE = Cardinal(1); + const PREPARE_PREFETCH_INPUT_PARAMETERS = Cardinal(2); + const PREPARE_PREFETCH_OUTPUT_PARAMETERS = Cardinal(4); + const PREPARE_PREFETCH_LEGACY_PLAN = Cardinal(8); + const PREPARE_PREFETCH_DETAILED_PLAN = Cardinal(16); + const PREPARE_PREFETCH_AFFECTED_RECORDS = Cardinal(32); + const PREPARE_PREFETCH_FLAGS = Cardinal(64); + const PREPARE_PREFETCH_METADATA = Cardinal(IStatement.PREPARE_PREFETCH_TYPE or IStatement.PREPARE_PREFETCH_FLAGS or IStatement.PREPARE_PREFETCH_INPUT_PARAMETERS or IStatement.PREPARE_PREFETCH_OUTPUT_PARAMETERS); + const PREPARE_PREFETCH_ALL = Cardinal(IStatement.PREPARE_PREFETCH_METADATA or IStatement.PREPARE_PREFETCH_LEGACY_PLAN or IStatement.PREPARE_PREFETCH_DETAILED_PLAN or IStatement.PREPARE_PREFETCH_AFFECTED_RECORDS); + const FLAG_HAS_CURSOR = Cardinal(1); + const FLAG_REPEAT_EXECUTE = Cardinal(2); + const CURSOR_TYPE_SCROLLABLE = Cardinal(1); + + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + function getType(status: IStatus): Cardinal; + function getPlan(status: IStatus; detailed: Boolean): PAnsiChar; + function getAffectedRecords(status: IStatus): QWord; + function getInputMetadata(status: IStatus): IMessageMetadata; + function getOutputMetadata(status: IStatus): IMessageMetadata; + function execute(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; + function openCursor(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; flags: Cardinal): IResultSet; + procedure setCursorName(status: IStatus; name: PAnsiChar); + procedure free(status: IStatus); + function getFlags(status: IStatus): Cardinal; + end; + + IStatementImpl = class(IStatement) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + function getType(status: IStatus): Cardinal; virtual; abstract; + function getPlan(status: IStatus; detailed: Boolean): PAnsiChar; virtual; abstract; + function getAffectedRecords(status: IStatus): QWord; virtual; abstract; + function getInputMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + function getOutputMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + function execute(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; virtual; abstract; + function openCursor(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; flags: Cardinal): IResultSet; virtual; abstract; + procedure setCursorName(status: IStatus; name: PAnsiChar); virtual; abstract; + procedure free(status: IStatus); virtual; abstract; + function getFlags(status: IStatus): Cardinal; virtual; abstract; + end; + + RequestVTable = class(ReferenceCountedVTable) + receive: IRequest_receivePtr; + send: IRequest_sendPtr; + getInfo: IRequest_getInfoPtr; + start: IRequest_startPtr; + startAndSend: IRequest_startAndSendPtr; + unwind: IRequest_unwindPtr; + free: IRequest_freePtr; + end; + + IRequest = class(IReferenceCounted) + const VERSION = 9; + + procedure receive(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); + procedure send(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); + procedure getInfo(status: IStatus; level: Integer; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + procedure start(status: IStatus; tra: ITransaction; level: Integer); + procedure startAndSend(status: IStatus; tra: ITransaction; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); + procedure unwind(status: IStatus; level: Integer); + procedure free(status: IStatus); + end; + + IRequestImpl = class(IRequest) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure receive(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); virtual; abstract; + procedure send(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); virtual; abstract; + procedure getInfo(status: IStatus; level: Integer; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + procedure start(status: IStatus; tra: ITransaction; level: Integer); virtual; abstract; + procedure startAndSend(status: IStatus; tra: ITransaction; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); virtual; abstract; + procedure unwind(status: IStatus; level: Integer); virtual; abstract; + procedure free(status: IStatus); virtual; abstract; + end; + + EventsVTable = class(ReferenceCountedVTable) + cancel: IEvents_cancelPtr; + end; + + IEvents = class(IReferenceCounted) + const VERSION = 3; + + procedure cancel(status: IStatus); + end; + + IEventsImpl = class(IEvents) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure cancel(status: IStatus); virtual; abstract; + end; + + AttachmentVTable = class(ReferenceCountedVTable) + getInfo: IAttachment_getInfoPtr; + startTransaction: IAttachment_startTransactionPtr; + reconnectTransaction: IAttachment_reconnectTransactionPtr; + compileRequest: IAttachment_compileRequestPtr; + transactRequest: IAttachment_transactRequestPtr; + createBlob: IAttachment_createBlobPtr; + openBlob: IAttachment_openBlobPtr; + getSlice: IAttachment_getSlicePtr; + putSlice: IAttachment_putSlicePtr; + executeDyn: IAttachment_executeDynPtr; + prepare: IAttachment_preparePtr; + execute: IAttachment_executePtr; + openCursor: IAttachment_openCursorPtr; + queEvents: IAttachment_queEventsPtr; + cancelOperation: IAttachment_cancelOperationPtr; + ping: IAttachment_pingPtr; + detach: IAttachment_detachPtr; + dropDatabase: IAttachment_dropDatabasePtr; + end; + + IAttachment = class(IReferenceCounted) + const VERSION = 20; + + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + function startTransaction(status: IStatus; tpbLength: Cardinal; tpb: BytePtr): ITransaction; + function reconnectTransaction(status: IStatus; length: Cardinal; id: BytePtr): ITransaction; + function compileRequest(status: IStatus; blrLength: Cardinal; blr: BytePtr): IRequest; + procedure transactRequest(status: IStatus; transaction: ITransaction; blrLength: Cardinal; blr: BytePtr; inMsgLength: Cardinal; inMsg: BytePtr; outMsgLength: Cardinal; outMsg: BytePtr); + function createBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; + function openBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; + function getSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr): Integer; + procedure putSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr); + procedure executeDyn(status: IStatus; transaction: ITransaction; length: Cardinal; dyn: BytePtr); + function prepare(status: IStatus; tra: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; flags: Cardinal): IStatement; + function execute(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; + function openCursor(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; cursorName: PAnsiChar; cursorFlags: Cardinal): IResultSet; + function queEvents(status: IStatus; callback: IEventCallback; length: Cardinal; events: BytePtr): IEvents; + procedure cancelOperation(status: IStatus; option: Integer); + procedure ping(status: IStatus); + procedure detach(status: IStatus); + procedure dropDatabase(status: IStatus); + end; + + IAttachmentImpl = class(IAttachment) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + function startTransaction(status: IStatus; tpbLength: Cardinal; tpb: BytePtr): ITransaction; virtual; abstract; + function reconnectTransaction(status: IStatus; length: Cardinal; id: BytePtr): ITransaction; virtual; abstract; + function compileRequest(status: IStatus; blrLength: Cardinal; blr: BytePtr): IRequest; virtual; abstract; + procedure transactRequest(status: IStatus; transaction: ITransaction; blrLength: Cardinal; blr: BytePtr; inMsgLength: Cardinal; inMsg: BytePtr; outMsgLength: Cardinal; outMsg: BytePtr); virtual; abstract; + function createBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; virtual; abstract; + function openBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; virtual; abstract; + function getSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr): Integer; virtual; abstract; + procedure putSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr); virtual; abstract; + procedure executeDyn(status: IStatus; transaction: ITransaction; length: Cardinal; dyn: BytePtr); virtual; abstract; + function prepare(status: IStatus; tra: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; flags: Cardinal): IStatement; virtual; abstract; + function execute(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; virtual; abstract; + function openCursor(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; cursorName: PAnsiChar; cursorFlags: Cardinal): IResultSet; virtual; abstract; + function queEvents(status: IStatus; callback: IEventCallback; length: Cardinal; events: BytePtr): IEvents; virtual; abstract; + procedure cancelOperation(status: IStatus; option: Integer); virtual; abstract; + procedure ping(status: IStatus); virtual; abstract; + procedure detach(status: IStatus); virtual; abstract; + procedure dropDatabase(status: IStatus); virtual; abstract; + end; + + ServiceVTable = class(ReferenceCountedVTable) + detach: IService_detachPtr; + query: IService_queryPtr; + start: IService_startPtr; + end; + + IService = class(IReferenceCounted) + const VERSION = 5; + + procedure detach(status: IStatus); + procedure query(status: IStatus; sendLength: Cardinal; sendItems: BytePtr; receiveLength: Cardinal; receiveItems: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + procedure start(status: IStatus; spbLength: Cardinal; spb: BytePtr); + end; + + IServiceImpl = class(IService) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure detach(status: IStatus); virtual; abstract; + procedure query(status: IStatus; sendLength: Cardinal; sendItems: BytePtr; receiveLength: Cardinal; receiveItems: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + procedure start(status: IStatus; spbLength: Cardinal; spb: BytePtr); virtual; abstract; + end; + + ProviderVTable = class(PluginBaseVTable) + attachDatabase: IProvider_attachDatabasePtr; + createDatabase: IProvider_createDatabasePtr; + attachServiceManager: IProvider_attachServiceManagerPtr; + shutdown: IProvider_shutdownPtr; + setDbCryptCallback: IProvider_setDbCryptCallbackPtr; + end; + + IProvider = class(IPluginBase) + const VERSION = 9; + + function attachDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; + function createDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; + function attachServiceManager(status: IStatus; service: PAnsiChar; spbLength: Cardinal; spb: BytePtr): IService; + procedure shutdown(status: IStatus; timeout: Cardinal; reason: Integer); + procedure setDbCryptCallback(status: IStatus; cryptCallback: ICryptKeyCallback); + end; + + IProviderImpl = class(IProvider) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function attachDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; virtual; abstract; + function createDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; virtual; abstract; + function attachServiceManager(status: IStatus; service: PAnsiChar; spbLength: Cardinal; spb: BytePtr): IService; virtual; abstract; + procedure shutdown(status: IStatus; timeout: Cardinal; reason: Integer); virtual; abstract; + procedure setDbCryptCallback(status: IStatus; cryptCallback: ICryptKeyCallback); virtual; abstract; + end; + + DtcStartVTable = class(DisposableVTable) + addAttachment: IDtcStart_addAttachmentPtr; + addWithTpb: IDtcStart_addWithTpbPtr; + start: IDtcStart_startPtr; + end; + + IDtcStart = class(IDisposable) + const VERSION = 4; + + procedure addAttachment(status: IStatus; att: IAttachment); + procedure addWithTpb(status: IStatus; att: IAttachment; length: Cardinal; tpb: BytePtr); + function start(status: IStatus): ITransaction; + end; + + IDtcStartImpl = class(IDtcStart) + constructor create; + + procedure dispose(); virtual; abstract; + procedure addAttachment(status: IStatus; att: IAttachment); virtual; abstract; + procedure addWithTpb(status: IStatus; att: IAttachment; length: Cardinal; tpb: BytePtr); virtual; abstract; + function start(status: IStatus): ITransaction; virtual; abstract; + end; + + DtcVTable = class(VersionedVTable) + join: IDtc_joinPtr; + startBuilder: IDtc_startBuilderPtr; + end; + + IDtc = class(IVersioned) + const VERSION = 2; + + function join(status: IStatus; one: ITransaction; two: ITransaction): ITransaction; + function startBuilder(status: IStatus): IDtcStart; + end; + + IDtcImpl = class(IDtc) + constructor create; + + function join(status: IStatus; one: ITransaction; two: ITransaction): ITransaction; virtual; abstract; + function startBuilder(status: IStatus): IDtcStart; virtual; abstract; + end; + + AuthVTable = class(PluginBaseVTable) + end; + + IAuth = class(IPluginBase) + const VERSION = 4; + const AUTH_FAILED = Integer(-1); + const AUTH_SUCCESS = Integer(0); + const AUTH_MORE_DATA = Integer(1); + const AUTH_CONTINUE = Integer(2); + + end; + + IAuthImpl = class(IAuth) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + end; + + WriterVTable = class(VersionedVTable) + reset: IWriter_resetPtr; + add: IWriter_addPtr; + setType: IWriter_setTypePtr; + setDb: IWriter_setDbPtr; + end; + + IWriter = class(IVersioned) + const VERSION = 4; + + procedure reset(); + procedure add(status: IStatus; name: PAnsiChar); + procedure setType(status: IStatus; value: PAnsiChar); + procedure setDb(status: IStatus; value: PAnsiChar); + end; + + IWriterImpl = class(IWriter) + constructor create; + + procedure reset(); virtual; abstract; + procedure add(status: IStatus; name: PAnsiChar); virtual; abstract; + procedure setType(status: IStatus; value: PAnsiChar); virtual; abstract; + procedure setDb(status: IStatus; value: PAnsiChar); virtual; abstract; + end; + + ServerBlockVTable = class(VersionedVTable) + getLogin: IServerBlock_getLoginPtr; + getData: IServerBlock_getDataPtr; + putData: IServerBlock_putDataPtr; + newKey: IServerBlock_newKeyPtr; + end; + + IServerBlock = class(IVersioned) + const VERSION = 4; + + function getLogin(): PAnsiChar; + function getData(length: CardinalPtr): BytePtr; + procedure putData(status: IStatus; length: Cardinal; data: Pointer); + function newKey(status: IStatus): ICryptKey; + end; + + IServerBlockImpl = class(IServerBlock) + constructor create; + + function getLogin(): PAnsiChar; virtual; abstract; + function getData(length: CardinalPtr): BytePtr; virtual; abstract; + procedure putData(status: IStatus; length: Cardinal; data: Pointer); virtual; abstract; + function newKey(status: IStatus): ICryptKey; virtual; abstract; + end; + + ClientBlockVTable = class(ReferenceCountedVTable) + getLogin: IClientBlock_getLoginPtr; + getPassword: IClientBlock_getPasswordPtr; + getData: IClientBlock_getDataPtr; + putData: IClientBlock_putDataPtr; + newKey: IClientBlock_newKeyPtr; + end; + + IClientBlock = class(IReferenceCounted) + const VERSION = 7; + + function getLogin(): PAnsiChar; + function getPassword(): PAnsiChar; + function getData(length: CardinalPtr): BytePtr; + procedure putData(status: IStatus; length: Cardinal; data: Pointer); + function newKey(status: IStatus): ICryptKey; + end; + + IClientBlockImpl = class(IClientBlock) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getLogin(): PAnsiChar; virtual; abstract; + function getPassword(): PAnsiChar; virtual; abstract; + function getData(length: CardinalPtr): BytePtr; virtual; abstract; + procedure putData(status: IStatus; length: Cardinal; data: Pointer); virtual; abstract; + function newKey(status: IStatus): ICryptKey; virtual; abstract; + end; + + ServerVTable = class(AuthVTable) + authenticate: IServer_authenticatePtr; + end; + + IServer = class(IAuth) + const VERSION = 5; + + function authenticate(status: IStatus; sBlock: IServerBlock; writerInterface: IWriter): Integer; + end; + + IServerImpl = class(IServer) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function authenticate(status: IStatus; sBlock: IServerBlock; writerInterface: IWriter): Integer; virtual; abstract; + end; + + ClientVTable = class(AuthVTable) + authenticate: IClient_authenticatePtr; + end; + + IClient = class(IAuth) + const VERSION = 5; + + function authenticate(status: IStatus; cBlock: IClientBlock): Integer; + end; + + IClientImpl = class(IClient) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function authenticate(status: IStatus; cBlock: IClientBlock): Integer; virtual; abstract; + end; + + UserFieldVTable = class(VersionedVTable) + entered: IUserField_enteredPtr; + specified: IUserField_specifiedPtr; + setEntered: IUserField_setEnteredPtr; + end; + + IUserField = class(IVersioned) + const VERSION = 3; + + function entered(): Integer; + function specified(): Integer; + procedure setEntered(status: IStatus; newValue: Integer); + end; + + IUserFieldImpl = class(IUserField) + constructor create; + + function entered(): Integer; virtual; abstract; + function specified(): Integer; virtual; abstract; + procedure setEntered(status: IStatus; newValue: Integer); virtual; abstract; + end; + + CharUserFieldVTable = class(UserFieldVTable) + get: ICharUserField_getPtr; + set_: ICharUserField_set_Ptr; + end; + + ICharUserField = class(IUserField) + const VERSION = 5; + + function get(): PAnsiChar; + procedure set_(status: IStatus; newValue: PAnsiChar); + end; + + ICharUserFieldImpl = class(ICharUserField) + constructor create; + + function entered(): Integer; virtual; abstract; + function specified(): Integer; virtual; abstract; + procedure setEntered(status: IStatus; newValue: Integer); virtual; abstract; + function get(): PAnsiChar; virtual; abstract; + procedure set_(status: IStatus; newValue: PAnsiChar); virtual; abstract; + end; + + IntUserFieldVTable = class(UserFieldVTable) + get: IIntUserField_getPtr; + set_: IIntUserField_set_Ptr; + end; + + IIntUserField = class(IUserField) + const VERSION = 5; + + function get(): Integer; + procedure set_(status: IStatus; newValue: Integer); + end; + + IIntUserFieldImpl = class(IIntUserField) + constructor create; + + function entered(): Integer; virtual; abstract; + function specified(): Integer; virtual; abstract; + procedure setEntered(status: IStatus; newValue: Integer); virtual; abstract; + function get(): Integer; virtual; abstract; + procedure set_(status: IStatus; newValue: Integer); virtual; abstract; + end; + + UserVTable = class(VersionedVTable) + operation: IUser_operationPtr; + userName: IUser_userNamePtr; + password: IUser_passwordPtr; + firstName: IUser_firstNamePtr; + lastName: IUser_lastNamePtr; + middleName: IUser_middleNamePtr; + comment: IUser_commentPtr; + attributes: IUser_attributesPtr; + active: IUser_activePtr; + admin: IUser_adminPtr; + clear: IUser_clearPtr; + end; + + IUser = class(IVersioned) + const VERSION = 11; + const OP_USER_ADD = Cardinal(1); + const OP_USER_MODIFY = Cardinal(2); + const OP_USER_DELETE = Cardinal(3); + const OP_USER_DISPLAY = Cardinal(4); + const OP_USER_SET_MAP = Cardinal(5); + const OP_USER_DROP_MAP = Cardinal(6); + + function operation(): Cardinal; + function userName(): ICharUserField; + function password(): ICharUserField; + function firstName(): ICharUserField; + function lastName(): ICharUserField; + function middleName(): ICharUserField; + function comment(): ICharUserField; + function attributes(): ICharUserField; + function active(): IIntUserField; + function admin(): IIntUserField; + procedure clear(status: IStatus); + end; + + IUserImpl = class(IUser) + constructor create; + + function operation(): Cardinal; virtual; abstract; + function userName(): ICharUserField; virtual; abstract; + function password(): ICharUserField; virtual; abstract; + function firstName(): ICharUserField; virtual; abstract; + function lastName(): ICharUserField; virtual; abstract; + function middleName(): ICharUserField; virtual; abstract; + function comment(): ICharUserField; virtual; abstract; + function attributes(): ICharUserField; virtual; abstract; + function active(): IIntUserField; virtual; abstract; + function admin(): IIntUserField; virtual; abstract; + procedure clear(status: IStatus); virtual; abstract; + end; + + ListUsersVTable = class(VersionedVTable) + list: IListUsers_listPtr; + end; + + IListUsers = class(IVersioned) + const VERSION = 1; + + procedure list(status: IStatus; user: IUser); + end; + + IListUsersImpl = class(IListUsers) + constructor create; + + procedure list(status: IStatus; user: IUser); virtual; abstract; + end; + + LogonInfoVTable = class(VersionedVTable) + name: ILogonInfo_namePtr; + role: ILogonInfo_rolePtr; + networkProtocol: ILogonInfo_networkProtocolPtr; + remoteAddress: ILogonInfo_remoteAddressPtr; + authBlock: ILogonInfo_authBlockPtr; + end; + + ILogonInfo = class(IVersioned) + const VERSION = 5; + + function name(): PAnsiChar; + function role(): PAnsiChar; + function networkProtocol(): PAnsiChar; + function remoteAddress(): PAnsiChar; + function authBlock(length: CardinalPtr): BytePtr; + end; + + ILogonInfoImpl = class(ILogonInfo) + constructor create; + + function name(): PAnsiChar; virtual; abstract; + function role(): PAnsiChar; virtual; abstract; + function networkProtocol(): PAnsiChar; virtual; abstract; + function remoteAddress(): PAnsiChar; virtual; abstract; + function authBlock(length: CardinalPtr): BytePtr; virtual; abstract; + end; + + ManagementVTable = class(PluginBaseVTable) + start: IManagement_startPtr; + execute: IManagement_executePtr; + commit: IManagement_commitPtr; + rollback: IManagement_rollbackPtr; + end; + + IManagement = class(IPluginBase) + const VERSION = 8; + + procedure start(status: IStatus; logonInfo: ILogonInfo); + function execute(status: IStatus; user: IUser; callback: IListUsers): Integer; + procedure commit(status: IStatus); + procedure rollback(status: IStatus); + end; + + IManagementImpl = class(IManagement) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + procedure start(status: IStatus; logonInfo: ILogonInfo); virtual; abstract; + function execute(status: IStatus; user: IUser; callback: IListUsers): Integer; virtual; abstract; + procedure commit(status: IStatus); virtual; abstract; + procedure rollback(status: IStatus); virtual; abstract; + end; + + WireCryptPluginVTable = class(PluginBaseVTable) + getKnownTypes: IWireCryptPlugin_getKnownTypesPtr; + setKey: IWireCryptPlugin_setKeyPtr; + encrypt: IWireCryptPlugin_encryptPtr; + decrypt: IWireCryptPlugin_decryptPtr; + end; + + IWireCryptPlugin = class(IPluginBase) + const VERSION = 8; + + function getKnownTypes(status: IStatus): PAnsiChar; + procedure setKey(status: IStatus; key: ICryptKey); + procedure encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); + procedure decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); + end; + + IWireCryptPluginImpl = class(IWireCryptPlugin) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function getKnownTypes(status: IStatus): PAnsiChar; virtual; abstract; + procedure setKey(status: IStatus; key: ICryptKey); virtual; abstract; + procedure encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); virtual; abstract; + procedure decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); virtual; abstract; + end; + + CryptKeyCallbackVTable = class(VersionedVTable) + callback: ICryptKeyCallback_callbackPtr; + end; + + ICryptKeyCallback = class(IVersioned) + const VERSION = 1; + + function callback(dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; + end; + + ICryptKeyCallbackImpl = class(ICryptKeyCallback) + constructor create; + + function callback(dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; virtual; abstract; + end; + + KeyHolderPluginVTable = class(PluginBaseVTable) + keyCallback: IKeyHolderPlugin_keyCallbackPtr; + keyHandle: IKeyHolderPlugin_keyHandlePtr; + end; + + IKeyHolderPlugin = class(IPluginBase) + const VERSION = 6; + + function keyCallback(status: IStatus; callback: ICryptKeyCallback): Integer; + function keyHandle(status: IStatus; keyName: PAnsiChar): ICryptKeyCallback; + end; + + IKeyHolderPluginImpl = class(IKeyHolderPlugin) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function keyCallback(status: IStatus; callback: ICryptKeyCallback): Integer; virtual; abstract; + function keyHandle(status: IStatus; keyName: PAnsiChar): ICryptKeyCallback; virtual; abstract; + end; + + DbCryptPluginVTable = class(PluginBaseVTable) + setKey: IDbCryptPlugin_setKeyPtr; + encrypt: IDbCryptPlugin_encryptPtr; + decrypt: IDbCryptPlugin_decryptPtr; + end; + + IDbCryptPlugin = class(IPluginBase) + const VERSION = 7; + + procedure setKey(status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); + procedure encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); + procedure decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); + end; + + IDbCryptPluginImpl = class(IDbCryptPlugin) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + procedure setKey(status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); virtual; abstract; + procedure encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); virtual; abstract; + procedure decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); virtual; abstract; + end; + + ExternalContextVTable = class(VersionedVTable) + getMaster: IExternalContext_getMasterPtr; + getEngine: IExternalContext_getEnginePtr; + getAttachment: IExternalContext_getAttachmentPtr; + getTransaction: IExternalContext_getTransactionPtr; + getUserName: IExternalContext_getUserNamePtr; + getDatabaseName: IExternalContext_getDatabaseNamePtr; + getClientCharSet: IExternalContext_getClientCharSetPtr; + obtainInfoCode: IExternalContext_obtainInfoCodePtr; + getInfo: IExternalContext_getInfoPtr; + setInfo: IExternalContext_setInfoPtr; + end; + + IExternalContext = class(IVersioned) + const VERSION = 10; + + function getMaster(): IMaster; + function getEngine(status: IStatus): IExternalEngine; + function getAttachment(status: IStatus): IAttachment; + function getTransaction(status: IStatus): ITransaction; + function getUserName(): PAnsiChar; + function getDatabaseName(): PAnsiChar; + function getClientCharSet(): PAnsiChar; + function obtainInfoCode(): Integer; + function getInfo(code: Integer): Pointer; + function setInfo(code: Integer; value: Pointer): Pointer; + end; + + IExternalContextImpl = class(IExternalContext) + constructor create; + + function getMaster(): IMaster; virtual; abstract; + function getEngine(status: IStatus): IExternalEngine; virtual; abstract; + function getAttachment(status: IStatus): IAttachment; virtual; abstract; + function getTransaction(status: IStatus): ITransaction; virtual; abstract; + function getUserName(): PAnsiChar; virtual; abstract; + function getDatabaseName(): PAnsiChar; virtual; abstract; + function getClientCharSet(): PAnsiChar; virtual; abstract; + function obtainInfoCode(): Integer; virtual; abstract; + function getInfo(code: Integer): Pointer; virtual; abstract; + function setInfo(code: Integer; value: Pointer): Pointer; virtual; abstract; + end; + + ExternalResultSetVTable = class(DisposableVTable) + fetch: IExternalResultSet_fetchPtr; + end; + + IExternalResultSet = class(IDisposable) + const VERSION = 2; + + function fetch(status: IStatus): Boolean; + end; + + IExternalResultSetImpl = class(IExternalResultSet) + constructor create; + + procedure dispose(); virtual; abstract; + function fetch(status: IStatus): Boolean; virtual; abstract; + end; + + ExternalFunctionVTable = class(DisposableVTable) + getCharSet: IExternalFunction_getCharSetPtr; + execute: IExternalFunction_executePtr; + end; + + IExternalFunction = class(IDisposable) + const VERSION = 3; + + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); + procedure execute(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer); + end; + + IExternalFunctionImpl = class(IExternalFunction) + constructor create; + + procedure dispose(); virtual; abstract; + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); virtual; abstract; + procedure execute(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer); virtual; abstract; + end; + + ExternalProcedureVTable = class(DisposableVTable) + getCharSet: IExternalProcedure_getCharSetPtr; + open: IExternalProcedure_openPtr; + end; + + IExternalProcedure = class(IDisposable) + const VERSION = 3; + + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); + function open(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer): IExternalResultSet; + end; + + IExternalProcedureImpl = class(IExternalProcedure) + constructor create; + + procedure dispose(); virtual; abstract; + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); virtual; abstract; + function open(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer): IExternalResultSet; virtual; abstract; + end; + + ExternalTriggerVTable = class(DisposableVTable) + getCharSet: IExternalTrigger_getCharSetPtr; + execute: IExternalTrigger_executePtr; + end; + + IExternalTrigger = class(IDisposable) + const VERSION = 3; + const TYPE_BEFORE = Cardinal(1); + const TYPE_AFTER = Cardinal(2); + const TYPE_DATABASE = Cardinal(3); + const ACTION_INSERT = Cardinal(1); + const ACTION_UPDATE = Cardinal(2); + const ACTION_DELETE = Cardinal(3); + const ACTION_CONNECT = Cardinal(4); + const ACTION_DISCONNECT = Cardinal(5); + const ACTION_TRANS_START = Cardinal(6); + const ACTION_TRANS_COMMIT = Cardinal(7); + const ACTION_TRANS_ROLLBACK = Cardinal(8); + const ACTION_DDL = Cardinal(9); + + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); + procedure execute(status: IStatus; context: IExternalContext; action: Cardinal; oldMsg: Pointer; newMsg: Pointer); + end; + + IExternalTriggerImpl = class(IExternalTrigger) + constructor create; + + procedure dispose(); virtual; abstract; + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); virtual; abstract; + procedure execute(status: IStatus; context: IExternalContext; action: Cardinal; oldMsg: Pointer; newMsg: Pointer); virtual; abstract; + end; + + RoutineMetadataVTable = class(VersionedVTable) + getPackage: IRoutineMetadata_getPackagePtr; + getName: IRoutineMetadata_getNamePtr; + getEntryPoint: IRoutineMetadata_getEntryPointPtr; + getBody: IRoutineMetadata_getBodyPtr; + getInputMetadata: IRoutineMetadata_getInputMetadataPtr; + getOutputMetadata: IRoutineMetadata_getOutputMetadataPtr; + getTriggerMetadata: IRoutineMetadata_getTriggerMetadataPtr; + getTriggerTable: IRoutineMetadata_getTriggerTablePtr; + getTriggerType: IRoutineMetadata_getTriggerTypePtr; + end; + + IRoutineMetadata = class(IVersioned) + const VERSION = 9; + + function getPackage(status: IStatus): PAnsiChar; + function getName(status: IStatus): PAnsiChar; + function getEntryPoint(status: IStatus): PAnsiChar; + function getBody(status: IStatus): PAnsiChar; + function getInputMetadata(status: IStatus): IMessageMetadata; + function getOutputMetadata(status: IStatus): IMessageMetadata; + function getTriggerMetadata(status: IStatus): IMessageMetadata; + function getTriggerTable(status: IStatus): PAnsiChar; + function getTriggerType(status: IStatus): Cardinal; + end; + + IRoutineMetadataImpl = class(IRoutineMetadata) + constructor create; + + function getPackage(status: IStatus): PAnsiChar; virtual; abstract; + function getName(status: IStatus): PAnsiChar; virtual; abstract; + function getEntryPoint(status: IStatus): PAnsiChar; virtual; abstract; + function getBody(status: IStatus): PAnsiChar; virtual; abstract; + function getInputMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + function getOutputMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + function getTriggerMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + function getTriggerTable(status: IStatus): PAnsiChar; virtual; abstract; + function getTriggerType(status: IStatus): Cardinal; virtual; abstract; + end; + + ExternalEngineVTable = class(PluginBaseVTable) + open: IExternalEngine_openPtr; + openAttachment: IExternalEngine_openAttachmentPtr; + closeAttachment: IExternalEngine_closeAttachmentPtr; + makeFunction: IExternalEngine_makeFunctionPtr; + makeProcedure: IExternalEngine_makeProcedurePtr; + makeTrigger: IExternalEngine_makeTriggerPtr; + end; + + IExternalEngine = class(IPluginBase) + const VERSION = 10; + + procedure open(status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); + procedure openAttachment(status: IStatus; context: IExternalContext); + procedure closeAttachment(status: IStatus; context: IExternalContext); + function makeFunction(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalFunction; + function makeProcedure(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalProcedure; + function makeTrigger(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder): IExternalTrigger; + end; + + IExternalEngineImpl = class(IExternalEngine) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + procedure open(status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); virtual; abstract; + procedure openAttachment(status: IStatus; context: IExternalContext); virtual; abstract; + procedure closeAttachment(status: IStatus; context: IExternalContext); virtual; abstract; + function makeFunction(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalFunction; virtual; abstract; + function makeProcedure(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalProcedure; virtual; abstract; + function makeTrigger(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder): IExternalTrigger; virtual; abstract; + end; + + TimerVTable = class(ReferenceCountedVTable) + handler: ITimer_handlerPtr; + end; + + ITimer = class(IReferenceCounted) + const VERSION = 3; + + procedure handler(); + end; + + ITimerImpl = class(ITimer) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure handler(); virtual; abstract; + end; + + TimerControlVTable = class(VersionedVTable) + start: ITimerControl_startPtr; + stop: ITimerControl_stopPtr; + end; + + ITimerControl = class(IVersioned) + const VERSION = 2; + + procedure start(status: IStatus; timer: ITimer; microSeconds: QWord); + procedure stop(status: IStatus; timer: ITimer); + end; + + ITimerControlImpl = class(ITimerControl) + constructor create; + + procedure start(status: IStatus; timer: ITimer; microSeconds: QWord); virtual; abstract; + procedure stop(status: IStatus; timer: ITimer); virtual; abstract; + end; + + VersionCallbackVTable = class(VersionedVTable) + callback: IVersionCallback_callbackPtr; + end; + + IVersionCallback = class(IVersioned) + const VERSION = 1; + + procedure callback(status: IStatus; text: PAnsiChar); + end; + + IVersionCallbackImpl = class(IVersionCallback) + constructor create; + + procedure callback(status: IStatus; text: PAnsiChar); virtual; abstract; + end; + + UtilVTable = class(VersionedVTable) + getFbVersion: IUtil_getFbVersionPtr; + loadBlob: IUtil_loadBlobPtr; + dumpBlob: IUtil_dumpBlobPtr; + getPerfCounters: IUtil_getPerfCountersPtr; + executeCreateDatabase: IUtil_executeCreateDatabasePtr; + decodeDate: IUtil_decodeDatePtr; + decodeTime: IUtil_decodeTimePtr; + encodeDate: IUtil_encodeDatePtr; + encodeTime: IUtil_encodeTimePtr; + formatStatus: IUtil_formatStatusPtr; + getClientVersion: IUtil_getClientVersionPtr; + getXpbBuilder: IUtil_getXpbBuilderPtr; + setOffsets: IUtil_setOffsetsPtr; + end; + + IUtil = class(IVersioned) + const VERSION = 13; + + procedure getFbVersion(status: IStatus; att: IAttachment; callback: IVersionCallback); + procedure loadBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); + procedure dumpBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); + procedure getPerfCounters(status: IStatus; att: IAttachment; countersSet: PAnsiChar; counters: Int64Ptr); + function executeCreateDatabase(status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; stmtIsCreateDb: BooleanPtr): IAttachment; + procedure decodeDate(date: ISC_DATE; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr); + procedure decodeTime(time: ISC_TIME; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr); + function encodeDate(year: Cardinal; month: Cardinal; day: Cardinal): ISC_DATE; + function encodeTime(hours: Cardinal; minutes: Cardinal; seconds: Cardinal; fractions: Cardinal): ISC_TIME; + function formatStatus(buffer: PAnsiChar; bufferSize: Cardinal; status: IStatus): Cardinal; + function getClientVersion(): Cardinal; + function getXpbBuilder(status: IStatus; kind: Cardinal; buf: BytePtr; len: Cardinal): IXpbBuilder; + function setOffsets(status: IStatus; metadata: IMessageMetadata; callback: IOffsetsCallback): Cardinal; + end; + + IUtilImpl = class(IUtil) + constructor create; + + procedure getFbVersion(status: IStatus; att: IAttachment; callback: IVersionCallback); virtual; abstract; + procedure loadBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); virtual; abstract; + procedure dumpBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); virtual; abstract; + procedure getPerfCounters(status: IStatus; att: IAttachment; countersSet: PAnsiChar; counters: Int64Ptr); virtual; abstract; + function executeCreateDatabase(status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; stmtIsCreateDb: BooleanPtr): IAttachment; virtual; abstract; + procedure decodeDate(date: ISC_DATE; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr); virtual; abstract; + procedure decodeTime(time: ISC_TIME; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr); virtual; abstract; + function encodeDate(year: Cardinal; month: Cardinal; day: Cardinal): ISC_DATE; virtual; abstract; + function encodeTime(hours: Cardinal; minutes: Cardinal; seconds: Cardinal; fractions: Cardinal): ISC_TIME; virtual; abstract; + function formatStatus(buffer: PAnsiChar; bufferSize: Cardinal; status: IStatus): Cardinal; virtual; abstract; + function getClientVersion(): Cardinal; virtual; abstract; + function getXpbBuilder(status: IStatus; kind: Cardinal; buf: BytePtr; len: Cardinal): IXpbBuilder; virtual; abstract; + function setOffsets(status: IStatus; metadata: IMessageMetadata; callback: IOffsetsCallback): Cardinal; virtual; abstract; + end; + + OffsetsCallbackVTable = class(VersionedVTable) + setOffset: IOffsetsCallback_setOffsetPtr; + end; + + IOffsetsCallback = class(IVersioned) + const VERSION = 1; + + procedure setOffset(status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); + end; + + IOffsetsCallbackImpl = class(IOffsetsCallback) + constructor create; + + procedure setOffset(status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); virtual; abstract; + end; + + XpbBuilderVTable = class(DisposableVTable) + clear: IXpbBuilder_clearPtr; + removeCurrent: IXpbBuilder_removeCurrentPtr; + insertInt: IXpbBuilder_insertIntPtr; + insertBigInt: IXpbBuilder_insertBigIntPtr; + insertBytes: IXpbBuilder_insertBytesPtr; + insertString: IXpbBuilder_insertStringPtr; + insertTag: IXpbBuilder_insertTagPtr; + isEof: IXpbBuilder_isEofPtr; + moveNext: IXpbBuilder_moveNextPtr; + rewind: IXpbBuilder_rewindPtr; + findFirst: IXpbBuilder_findFirstPtr; + findNext: IXpbBuilder_findNextPtr; + getTag: IXpbBuilder_getTagPtr; + getLength: IXpbBuilder_getLengthPtr; + getInt: IXpbBuilder_getIntPtr; + getBigInt: IXpbBuilder_getBigIntPtr; + getString: IXpbBuilder_getStringPtr; + getBytes: IXpbBuilder_getBytesPtr; + getBufferLength: IXpbBuilder_getBufferLengthPtr; + getBuffer: IXpbBuilder_getBufferPtr; + end; + + IXpbBuilder = class(IDisposable) + const VERSION = 21; + const DPB = Cardinal(1); + const SPB_ATTACH = Cardinal(2); + const SPB_START = Cardinal(3); + const TPB = Cardinal(4); + + procedure clear(status: IStatus); + procedure removeCurrent(status: IStatus); + procedure insertInt(status: IStatus; tag: Byte; value: Integer); + procedure insertBigInt(status: IStatus; tag: Byte; value: Int64); + procedure insertBytes(status: IStatus; tag: Byte; bytes: Pointer; length: Cardinal); + procedure insertString(status: IStatus; tag: Byte; str: PAnsiChar); + procedure insertTag(status: IStatus; tag: Byte); + function isEof(status: IStatus): Boolean; + procedure moveNext(status: IStatus); + procedure rewind(status: IStatus); + function findFirst(status: IStatus; tag: Byte): Boolean; + function findNext(status: IStatus): Boolean; + function getTag(status: IStatus): Byte; + function getLength(status: IStatus): Cardinal; + function getInt(status: IStatus): Integer; + function getBigInt(status: IStatus): Int64; + function getString(status: IStatus): PAnsiChar; + function getBytes(status: IStatus): BytePtr; + function getBufferLength(status: IStatus): Cardinal; + function getBuffer(status: IStatus): BytePtr; + end; + + IXpbBuilderImpl = class(IXpbBuilder) + constructor create; + + procedure dispose(); virtual; abstract; + procedure clear(status: IStatus); virtual; abstract; + procedure removeCurrent(status: IStatus); virtual; abstract; + procedure insertInt(status: IStatus; tag: Byte; value: Integer); virtual; abstract; + procedure insertBigInt(status: IStatus; tag: Byte; value: Int64); virtual; abstract; + procedure insertBytes(status: IStatus; tag: Byte; bytes: Pointer; length: Cardinal); virtual; abstract; + procedure insertString(status: IStatus; tag: Byte; str: PAnsiChar); virtual; abstract; + procedure insertTag(status: IStatus; tag: Byte); virtual; abstract; + function isEof(status: IStatus): Boolean; virtual; abstract; + procedure moveNext(status: IStatus); virtual; abstract; + procedure rewind(status: IStatus); virtual; abstract; + function findFirst(status: IStatus; tag: Byte): Boolean; virtual; abstract; + function findNext(status: IStatus): Boolean; virtual; abstract; + function getTag(status: IStatus): Byte; virtual; abstract; + function getLength(status: IStatus): Cardinal; virtual; abstract; + function getInt(status: IStatus): Integer; virtual; abstract; + function getBigInt(status: IStatus): Int64; virtual; abstract; + function getString(status: IStatus): PAnsiChar; virtual; abstract; + function getBytes(status: IStatus): BytePtr; virtual; abstract; + function getBufferLength(status: IStatus): Cardinal; virtual; abstract; + function getBuffer(status: IStatus): BytePtr; virtual; abstract; + end; + + TraceConnectionVTable = class(VersionedVTable) + getKind: ITraceConnection_getKindPtr; + getProcessID: ITraceConnection_getProcessIDPtr; + getUserName: ITraceConnection_getUserNamePtr; + getRoleName: ITraceConnection_getRoleNamePtr; + getCharSet: ITraceConnection_getCharSetPtr; + getRemoteProtocol: ITraceConnection_getRemoteProtocolPtr; + getRemoteAddress: ITraceConnection_getRemoteAddressPtr; + getRemoteProcessID: ITraceConnection_getRemoteProcessIDPtr; + getRemoteProcessName: ITraceConnection_getRemoteProcessNamePtr; + end; + + ITraceConnection = class(IVersioned) + const VERSION = 9; + const KIND_DATABASE = Cardinal(1); + const KIND_SERVICE = Cardinal(2); + + function getKind(): Cardinal; + function getProcessID(): Integer; + function getUserName(): PAnsiChar; + function getRoleName(): PAnsiChar; + function getCharSet(): PAnsiChar; + function getRemoteProtocol(): PAnsiChar; + function getRemoteAddress(): PAnsiChar; + function getRemoteProcessID(): Integer; + function getRemoteProcessName(): PAnsiChar; + end; + + ITraceConnectionImpl = class(ITraceConnection) + constructor create; + + function getKind(): Cardinal; virtual; abstract; + function getProcessID(): Integer; virtual; abstract; + function getUserName(): PAnsiChar; virtual; abstract; + function getRoleName(): PAnsiChar; virtual; abstract; + function getCharSet(): PAnsiChar; virtual; abstract; + function getRemoteProtocol(): PAnsiChar; virtual; abstract; + function getRemoteAddress(): PAnsiChar; virtual; abstract; + function getRemoteProcessID(): Integer; virtual; abstract; + function getRemoteProcessName(): PAnsiChar; virtual; abstract; + end; + + TraceDatabaseConnectionVTable = class(TraceConnectionVTable) + getConnectionID: ITraceDatabaseConnection_getConnectionIDPtr; + getDatabaseName: ITraceDatabaseConnection_getDatabaseNamePtr; + end; + + ITraceDatabaseConnection = class(ITraceConnection) + const VERSION = 11; + + function getConnectionID(): Int64; + function getDatabaseName(): PAnsiChar; + end; + + ITraceDatabaseConnectionImpl = class(ITraceDatabaseConnection) + constructor create; + + function getKind(): Cardinal; virtual; abstract; + function getProcessID(): Integer; virtual; abstract; + function getUserName(): PAnsiChar; virtual; abstract; + function getRoleName(): PAnsiChar; virtual; abstract; + function getCharSet(): PAnsiChar; virtual; abstract; + function getRemoteProtocol(): PAnsiChar; virtual; abstract; + function getRemoteAddress(): PAnsiChar; virtual; abstract; + function getRemoteProcessID(): Integer; virtual; abstract; + function getRemoteProcessName(): PAnsiChar; virtual; abstract; + function getConnectionID(): Int64; virtual; abstract; + function getDatabaseName(): PAnsiChar; virtual; abstract; + end; + + TraceTransactionVTable = class(VersionedVTable) + getTransactionID: ITraceTransaction_getTransactionIDPtr; + getReadOnly: ITraceTransaction_getReadOnlyPtr; + getWait: ITraceTransaction_getWaitPtr; + getIsolation: ITraceTransaction_getIsolationPtr; + getPerf: ITraceTransaction_getPerfPtr; + end; + + ITraceTransaction = class(IVersioned) + const VERSION = 5; + const ISOLATION_CONSISTENCY = Cardinal(1); + const ISOLATION_CONCURRENCY = Cardinal(2); + const ISOLATION_READ_COMMITTED_RECVER = Cardinal(3); + const ISOLATION_READ_COMMITTED_NORECVER = Cardinal(4); + + function getTransactionID(): Int64; + function getReadOnly(): Boolean; + function getWait(): Integer; + function getIsolation(): Cardinal; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceTransactionImpl = class(ITraceTransaction) + constructor create; + + function getTransactionID(): Int64; virtual; abstract; + function getReadOnly(): Boolean; virtual; abstract; + function getWait(): Integer; virtual; abstract; + function getIsolation(): Cardinal; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceParamsVTable = class(VersionedVTable) + getCount: ITraceParams_getCountPtr; + getParam: ITraceParams_getParamPtr; + end; + + ITraceParams = class(IVersioned) + const VERSION = 2; + + function getCount(): Cardinal; + function getParam(idx: Cardinal): dscPtr; + end; + + ITraceParamsImpl = class(ITraceParams) + constructor create; + + function getCount(): Cardinal; virtual; abstract; + function getParam(idx: Cardinal): dscPtr; virtual; abstract; + end; + + TraceStatementVTable = class(VersionedVTable) + getStmtID: ITraceStatement_getStmtIDPtr; + getPerf: ITraceStatement_getPerfPtr; + end; + + ITraceStatement = class(IVersioned) + const VERSION = 2; + + function getStmtID(): Int64; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceStatementImpl = class(ITraceStatement) + constructor create; + + function getStmtID(): Int64; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceSQLStatementVTable = class(TraceStatementVTable) + getText: ITraceSQLStatement_getTextPtr; + getPlan: ITraceSQLStatement_getPlanPtr; + getInputs: ITraceSQLStatement_getInputsPtr; + getTextUTF8: ITraceSQLStatement_getTextUTF8Ptr; + getExplainedPlan: ITraceSQLStatement_getExplainedPlanPtr; + end; + + ITraceSQLStatement = class(ITraceStatement) + const VERSION = 7; + + function getText(): PAnsiChar; + function getPlan(): PAnsiChar; + function getInputs(): ITraceParams; + function getTextUTF8(): PAnsiChar; + function getExplainedPlan(): PAnsiChar; + end; + + ITraceSQLStatementImpl = class(ITraceSQLStatement) + constructor create; + + function getStmtID(): Int64; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + function getText(): PAnsiChar; virtual; abstract; + function getPlan(): PAnsiChar; virtual; abstract; + function getInputs(): ITraceParams; virtual; abstract; + function getTextUTF8(): PAnsiChar; virtual; abstract; + function getExplainedPlan(): PAnsiChar; virtual; abstract; + end; + + TraceBLRStatementVTable = class(TraceStatementVTable) + getData: ITraceBLRStatement_getDataPtr; + getDataLength: ITraceBLRStatement_getDataLengthPtr; + getText: ITraceBLRStatement_getTextPtr; + end; + + ITraceBLRStatement = class(ITraceStatement) + const VERSION = 5; + + function getData(): BytePtr; + function getDataLength(): Cardinal; + function getText(): PAnsiChar; + end; + + ITraceBLRStatementImpl = class(ITraceBLRStatement) + constructor create; + + function getStmtID(): Int64; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + function getData(): BytePtr; virtual; abstract; + function getDataLength(): Cardinal; virtual; abstract; + function getText(): PAnsiChar; virtual; abstract; + end; + + TraceDYNRequestVTable = class(VersionedVTable) + getData: ITraceDYNRequest_getDataPtr; + getDataLength: ITraceDYNRequest_getDataLengthPtr; + getText: ITraceDYNRequest_getTextPtr; + end; + + ITraceDYNRequest = class(IVersioned) + const VERSION = 3; + + function getData(): BytePtr; + function getDataLength(): Cardinal; + function getText(): PAnsiChar; + end; + + ITraceDYNRequestImpl = class(ITraceDYNRequest) + constructor create; + + function getData(): BytePtr; virtual; abstract; + function getDataLength(): Cardinal; virtual; abstract; + function getText(): PAnsiChar; virtual; abstract; + end; + + TraceContextVariableVTable = class(VersionedVTable) + getNameSpace: ITraceContextVariable_getNameSpacePtr; + getVarName: ITraceContextVariable_getVarNamePtr; + getVarValue: ITraceContextVariable_getVarValuePtr; + end; + + ITraceContextVariable = class(IVersioned) + const VERSION = 3; + + function getNameSpace(): PAnsiChar; + function getVarName(): PAnsiChar; + function getVarValue(): PAnsiChar; + end; + + ITraceContextVariableImpl = class(ITraceContextVariable) + constructor create; + + function getNameSpace(): PAnsiChar; virtual; abstract; + function getVarName(): PAnsiChar; virtual; abstract; + function getVarValue(): PAnsiChar; virtual; abstract; + end; + + TraceProcedureVTable = class(VersionedVTable) + getProcName: ITraceProcedure_getProcNamePtr; + getInputs: ITraceProcedure_getInputsPtr; + getPerf: ITraceProcedure_getPerfPtr; + end; + + ITraceProcedure = class(IVersioned) + const VERSION = 3; + + function getProcName(): PAnsiChar; + function getInputs(): ITraceParams; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceProcedureImpl = class(ITraceProcedure) + constructor create; + + function getProcName(): PAnsiChar; virtual; abstract; + function getInputs(): ITraceParams; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceFunctionVTable = class(VersionedVTable) + getFuncName: ITraceFunction_getFuncNamePtr; + getInputs: ITraceFunction_getInputsPtr; + getResult: ITraceFunction_getResultPtr; + getPerf: ITraceFunction_getPerfPtr; + end; + + ITraceFunction = class(IVersioned) + const VERSION = 4; + + function getFuncName(): PAnsiChar; + function getInputs(): ITraceParams; + function getResult(): ITraceParams; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceFunctionImpl = class(ITraceFunction) + constructor create; + + function getFuncName(): PAnsiChar; virtual; abstract; + function getInputs(): ITraceParams; virtual; abstract; + function getResult(): ITraceParams; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceTriggerVTable = class(VersionedVTable) + getTriggerName: ITraceTrigger_getTriggerNamePtr; + getRelationName: ITraceTrigger_getRelationNamePtr; + getAction: ITraceTrigger_getActionPtr; + getWhich: ITraceTrigger_getWhichPtr; + getPerf: ITraceTrigger_getPerfPtr; + end; + + ITraceTrigger = class(IVersioned) + const VERSION = 5; + const TYPE_ALL = Cardinal(0); + const TYPE_BEFORE = Cardinal(1); + const TYPE_AFTER = Cardinal(2); + + function getTriggerName(): PAnsiChar; + function getRelationName(): PAnsiChar; + function getAction(): Integer; + function getWhich(): Integer; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceTriggerImpl = class(ITraceTrigger) + constructor create; + + function getTriggerName(): PAnsiChar; virtual; abstract; + function getRelationName(): PAnsiChar; virtual; abstract; + function getAction(): Integer; virtual; abstract; + function getWhich(): Integer; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceServiceConnectionVTable = class(TraceConnectionVTable) + getServiceID: ITraceServiceConnection_getServiceIDPtr; + getServiceMgr: ITraceServiceConnection_getServiceMgrPtr; + getServiceName: ITraceServiceConnection_getServiceNamePtr; + end; + + ITraceServiceConnection = class(ITraceConnection) + const VERSION = 12; + + function getServiceID(): Pointer; + function getServiceMgr(): PAnsiChar; + function getServiceName(): PAnsiChar; + end; + + ITraceServiceConnectionImpl = class(ITraceServiceConnection) + constructor create; + + function getKind(): Cardinal; virtual; abstract; + function getProcessID(): Integer; virtual; abstract; + function getUserName(): PAnsiChar; virtual; abstract; + function getRoleName(): PAnsiChar; virtual; abstract; + function getCharSet(): PAnsiChar; virtual; abstract; + function getRemoteProtocol(): PAnsiChar; virtual; abstract; + function getRemoteAddress(): PAnsiChar; virtual; abstract; + function getRemoteProcessID(): Integer; virtual; abstract; + function getRemoteProcessName(): PAnsiChar; virtual; abstract; + function getServiceID(): Pointer; virtual; abstract; + function getServiceMgr(): PAnsiChar; virtual; abstract; + function getServiceName(): PAnsiChar; virtual; abstract; + end; + + TraceStatusVectorVTable = class(VersionedVTable) + hasError: ITraceStatusVector_hasErrorPtr; + hasWarning: ITraceStatusVector_hasWarningPtr; + getStatus: ITraceStatusVector_getStatusPtr; + getText: ITraceStatusVector_getTextPtr; + end; + + ITraceStatusVector = class(IVersioned) + const VERSION = 4; + + function hasError(): Boolean; + function hasWarning(): Boolean; + function getStatus(): IStatus; + function getText(): PAnsiChar; + end; + + ITraceStatusVectorImpl = class(ITraceStatusVector) + constructor create; + + function hasError(): Boolean; virtual; abstract; + function hasWarning(): Boolean; virtual; abstract; + function getStatus(): IStatus; virtual; abstract; + function getText(): PAnsiChar; virtual; abstract; + end; + + TraceSweepInfoVTable = class(VersionedVTable) + getOIT: ITraceSweepInfo_getOITPtr; + getOST: ITraceSweepInfo_getOSTPtr; + getOAT: ITraceSweepInfo_getOATPtr; + getNext: ITraceSweepInfo_getNextPtr; + getPerf: ITraceSweepInfo_getPerfPtr; + end; + + ITraceSweepInfo = class(IVersioned) + const VERSION = 5; + + function getOIT(): Int64; + function getOST(): Int64; + function getOAT(): Int64; + function getNext(): Int64; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceSweepInfoImpl = class(ITraceSweepInfo) + constructor create; + + function getOIT(): Int64; virtual; abstract; + function getOST(): Int64; virtual; abstract; + function getOAT(): Int64; virtual; abstract; + function getNext(): Int64; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceLogWriterVTable = class(ReferenceCountedVTable) + write: ITraceLogWriter_writePtr; + end; + + ITraceLogWriter = class(IReferenceCounted) + const VERSION = 3; + + function write(buf: Pointer; size: Cardinal): Cardinal; + end; + + ITraceLogWriterImpl = class(ITraceLogWriter) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function write(buf: Pointer; size: Cardinal): Cardinal; virtual; abstract; + end; + + TraceInitInfoVTable = class(VersionedVTable) + getConfigText: ITraceInitInfo_getConfigTextPtr; + getTraceSessionID: ITraceInitInfo_getTraceSessionIDPtr; + getTraceSessionName: ITraceInitInfo_getTraceSessionNamePtr; + getFirebirdRootDirectory: ITraceInitInfo_getFirebirdRootDirectoryPtr; + getDatabaseName: ITraceInitInfo_getDatabaseNamePtr; + getConnection: ITraceInitInfo_getConnectionPtr; + getLogWriter: ITraceInitInfo_getLogWriterPtr; + end; + + ITraceInitInfo = class(IVersioned) + const VERSION = 7; + + function getConfigText(): PAnsiChar; + function getTraceSessionID(): Integer; + function getTraceSessionName(): PAnsiChar; + function getFirebirdRootDirectory(): PAnsiChar; + function getDatabaseName(): PAnsiChar; + function getConnection(): ITraceDatabaseConnection; + function getLogWriter(): ITraceLogWriter; + end; + + ITraceInitInfoImpl = class(ITraceInitInfo) + constructor create; + + function getConfigText(): PAnsiChar; virtual; abstract; + function getTraceSessionID(): Integer; virtual; abstract; + function getTraceSessionName(): PAnsiChar; virtual; abstract; + function getFirebirdRootDirectory(): PAnsiChar; virtual; abstract; + function getDatabaseName(): PAnsiChar; virtual; abstract; + function getConnection(): ITraceDatabaseConnection; virtual; abstract; + function getLogWriter(): ITraceLogWriter; virtual; abstract; + end; + + TracePluginVTable = class(ReferenceCountedVTable) + trace_get_error: ITracePlugin_trace_get_errorPtr; + trace_attach: ITracePlugin_trace_attachPtr; + trace_detach: ITracePlugin_trace_detachPtr; + trace_transaction_start: ITracePlugin_trace_transaction_startPtr; + trace_transaction_end: ITracePlugin_trace_transaction_endPtr; + trace_proc_execute: ITracePlugin_trace_proc_executePtr; + trace_trigger_execute: ITracePlugin_trace_trigger_executePtr; + trace_set_context: ITracePlugin_trace_set_contextPtr; + trace_dsql_prepare: ITracePlugin_trace_dsql_preparePtr; + trace_dsql_free: ITracePlugin_trace_dsql_freePtr; + trace_dsql_execute: ITracePlugin_trace_dsql_executePtr; + trace_blr_compile: ITracePlugin_trace_blr_compilePtr; + trace_blr_execute: ITracePlugin_trace_blr_executePtr; + trace_dyn_execute: ITracePlugin_trace_dyn_executePtr; + trace_service_attach: ITracePlugin_trace_service_attachPtr; + trace_service_start: ITracePlugin_trace_service_startPtr; + trace_service_query: ITracePlugin_trace_service_queryPtr; + trace_service_detach: ITracePlugin_trace_service_detachPtr; + trace_event_error: ITracePlugin_trace_event_errorPtr; + trace_event_sweep: ITracePlugin_trace_event_sweepPtr; + trace_func_execute: ITracePlugin_trace_func_executePtr; + end; + + ITracePlugin = class(IReferenceCounted) + const VERSION = 23; + const RESULT_SUCCESS = Cardinal(0); + const RESULT_FAILED = Cardinal(1); + const RESULT_UNAUTHORIZED = Cardinal(2); + const SWEEP_STATE_STARTED = Cardinal(1); + const SWEEP_STATE_FINISHED = Cardinal(2); + const SWEEP_STATE_FAILED = Cardinal(3); + const SWEEP_STATE_PROGRESS = Cardinal(4); + + function trace_get_error(): PAnsiChar; + function trace_attach(connection: ITraceDatabaseConnection; create_db: Boolean; att_result: Cardinal): Boolean; + function trace_detach(connection: ITraceDatabaseConnection; drop_db: Boolean): Boolean; + function trace_transaction_start(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; tpb_length: Cardinal; tpb: BytePtr; tra_result: Cardinal): Boolean; + function trace_transaction_end(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; commit: Boolean; retain_context: Boolean; tra_result: Cardinal): Boolean; + function trace_proc_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; procedure_: ITraceProcedure; started: Boolean; proc_result: Cardinal): Boolean; + function trace_trigger_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; trigger: ITraceTrigger; started: Boolean; trig_result: Cardinal): Boolean; + function trace_set_context(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; variable: ITraceContextVariable): Boolean; + function trace_dsql_prepare(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; time_millis: Int64; req_result: Cardinal): Boolean; + function trace_dsql_free(connection: ITraceDatabaseConnection; statement: ITraceSQLStatement; option: Cardinal): Boolean; + function trace_dsql_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; started: Boolean; req_result: Cardinal): Boolean; + function trace_blr_compile(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; time_millis: Int64; req_result: Cardinal): Boolean; + function trace_blr_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; req_result: Cardinal): Boolean; + function trace_dyn_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; request: ITraceDYNRequest; time_millis: Int64; req_result: Cardinal): Boolean; + function trace_service_attach(service: ITraceServiceConnection; att_result: Cardinal): Boolean; + function trace_service_start(service: ITraceServiceConnection; switches_length: Cardinal; switches: PAnsiChar; start_result: Cardinal): Boolean; + function trace_service_query(service: ITraceServiceConnection; send_item_length: Cardinal; send_items: BytePtr; recv_item_length: Cardinal; recv_items: BytePtr; query_result: Cardinal): Boolean; + function trace_service_detach(service: ITraceServiceConnection; detach_result: Cardinal): Boolean; + function trace_event_error(connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; + function trace_event_sweep(connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; + function trace_func_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; + end; + + ITracePluginImpl = class(ITracePlugin) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function trace_get_error(): PAnsiChar; virtual; abstract; + function trace_attach(connection: ITraceDatabaseConnection; create_db: Boolean; att_result: Cardinal): Boolean; virtual; abstract; + function trace_detach(connection: ITraceDatabaseConnection; drop_db: Boolean): Boolean; virtual; abstract; + function trace_transaction_start(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; tpb_length: Cardinal; tpb: BytePtr; tra_result: Cardinal): Boolean; virtual; abstract; + function trace_transaction_end(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; commit: Boolean; retain_context: Boolean; tra_result: Cardinal): Boolean; virtual; abstract; + function trace_proc_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; procedure_: ITraceProcedure; started: Boolean; proc_result: Cardinal): Boolean; virtual; abstract; + function trace_trigger_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; trigger: ITraceTrigger; started: Boolean; trig_result: Cardinal): Boolean; virtual; abstract; + function trace_set_context(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; variable: ITraceContextVariable): Boolean; virtual; abstract; + function trace_dsql_prepare(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; time_millis: Int64; req_result: Cardinal): Boolean; virtual; abstract; + function trace_dsql_free(connection: ITraceDatabaseConnection; statement: ITraceSQLStatement; option: Cardinal): Boolean; virtual; abstract; + function trace_dsql_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; started: Boolean; req_result: Cardinal): Boolean; virtual; abstract; + function trace_blr_compile(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; time_millis: Int64; req_result: Cardinal): Boolean; virtual; abstract; + function trace_blr_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; req_result: Cardinal): Boolean; virtual; abstract; + function trace_dyn_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; request: ITraceDYNRequest; time_millis: Int64; req_result: Cardinal): Boolean; virtual; abstract; + function trace_service_attach(service: ITraceServiceConnection; att_result: Cardinal): Boolean; virtual; abstract; + function trace_service_start(service: ITraceServiceConnection; switches_length: Cardinal; switches: PAnsiChar; start_result: Cardinal): Boolean; virtual; abstract; + function trace_service_query(service: ITraceServiceConnection; send_item_length: Cardinal; send_items: BytePtr; recv_item_length: Cardinal; recv_items: BytePtr; query_result: Cardinal): Boolean; virtual; abstract; + function trace_service_detach(service: ITraceServiceConnection; detach_result: Cardinal): Boolean; virtual; abstract; + function trace_event_error(connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; virtual; abstract; + function trace_event_sweep(connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; virtual; abstract; + function trace_func_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; virtual; abstract; + end; + + TraceFactoryVTable = class(PluginBaseVTable) + trace_needs: ITraceFactory_trace_needsPtr; + trace_create: ITraceFactory_trace_createPtr; + end; + + ITraceFactory = class(IPluginBase) + const VERSION = 6; + const TRACE_EVENT_ATTACH = Cardinal(0); + const TRACE_EVENT_DETACH = Cardinal(1); + const TRACE_EVENT_TRANSACTION_START = Cardinal(2); + const TRACE_EVENT_TRANSACTION_END = Cardinal(3); + const TRACE_EVENT_SET_CONTEXT = Cardinal(4); + const TRACE_EVENT_PROC_EXECUTE = Cardinal(5); + const TRACE_EVENT_TRIGGER_EXECUTE = Cardinal(6); + const TRACE_EVENT_DSQL_PREPARE = Cardinal(7); + const TRACE_EVENT_DSQL_FREE = Cardinal(8); + const TRACE_EVENT_DSQL_EXECUTE = Cardinal(9); + const TRACE_EVENT_BLR_COMPILE = Cardinal(10); + const TRACE_EVENT_BLR_EXECUTE = Cardinal(11); + const TRACE_EVENT_DYN_EXECUTE = Cardinal(12); + const TRACE_EVENT_SERVICE_ATTACH = Cardinal(13); + const TRACE_EVENT_SERVICE_START = Cardinal(14); + const TRACE_EVENT_SERVICE_QUERY = Cardinal(15); + const TRACE_EVENT_SERVICE_DETACH = Cardinal(16); + const TRACE_EVENT_ERROR = Cardinal(17); + const TRACE_EVENT_SWEEP = Cardinal(18); + const TRACE_EVENT_FUNC_EXECUTE = Cardinal(19); + const TRACE_EVENT_MAX = Cardinal(20); + + function trace_needs(): QWord; + function trace_create(status: IStatus; init_info: ITraceInitInfo): ITracePlugin; + end; + + ITraceFactoryImpl = class(ITraceFactory) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function trace_needs(): QWord; virtual; abstract; + function trace_create(status: IStatus; init_info: ITraceInitInfo): ITracePlugin; virtual; abstract; + end; + + UdrFunctionFactoryVTable = class(DisposableVTable) + setup: IUdrFunctionFactory_setupPtr; + newItem: IUdrFunctionFactory_newItemPtr; + end; + + IUdrFunctionFactory = class(IDisposable) + const VERSION = 3; + + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalFunction; + end; + + IUdrFunctionFactoryImpl = class(IUdrFunctionFactory) + constructor create; + + procedure dispose(); virtual; abstract; + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); virtual; abstract; + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalFunction; virtual; abstract; + end; + + UdrProcedureFactoryVTable = class(DisposableVTable) + setup: IUdrProcedureFactory_setupPtr; + newItem: IUdrProcedureFactory_newItemPtr; + end; + + IUdrProcedureFactory = class(IDisposable) + const VERSION = 3; + + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalProcedure; + end; + + IUdrProcedureFactoryImpl = class(IUdrProcedureFactory) + constructor create; + + procedure dispose(); virtual; abstract; + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); virtual; abstract; + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalProcedure; virtual; abstract; + end; + + UdrTriggerFactoryVTable = class(DisposableVTable) + setup: IUdrTriggerFactory_setupPtr; + newItem: IUdrTriggerFactory_newItemPtr; + end; + + IUdrTriggerFactory = class(IDisposable) + const VERSION = 3; + + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder); + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalTrigger; + end; + + IUdrTriggerFactoryImpl = class(IUdrTriggerFactory) + constructor create; + + procedure dispose(); virtual; abstract; + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder); virtual; abstract; + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalTrigger; virtual; abstract; + end; + + UdrPluginVTable = class(VersionedVTable) + getMaster: IUdrPlugin_getMasterPtr; + registerFunction: IUdrPlugin_registerFunctionPtr; + registerProcedure: IUdrPlugin_registerProcedurePtr; + registerTrigger: IUdrPlugin_registerTriggerPtr; + end; + + IUdrPlugin = class(IVersioned) + const VERSION = 4; + + function getMaster(): IMaster; + procedure registerFunction(status: IStatus; name: PAnsiChar; factory: IUdrFunctionFactory); + procedure registerProcedure(status: IStatus; name: PAnsiChar; factory: IUdrProcedureFactory); + procedure registerTrigger(status: IStatus; name: PAnsiChar; factory: IUdrTriggerFactory); + end; + + IUdrPluginImpl = class(IUdrPlugin) + constructor create; + + function getMaster(): IMaster; virtual; abstract; + procedure registerFunction(status: IStatus; name: PAnsiChar; factory: IUdrFunctionFactory); virtual; abstract; + procedure registerProcedure(status: IStatus; name: PAnsiChar; factory: IUdrProcedureFactory); virtual; abstract; + procedure registerTrigger(status: IStatus; name: PAnsiChar; factory: IUdrTriggerFactory); virtual; abstract; + end; + +// function fb_get_master_interface : IMaster; cdecl; external 'fbclient'; + +const + isc_dpb_version1 = byte(1); + isc_dpb_version2 = byte(2); + isc_dpb_cdd_pathname = byte(1); + isc_dpb_allocation = byte(2); + isc_dpb_journal = byte(3); + isc_dpb_page_size = byte(4); + isc_dpb_num_buffers = byte(5); + isc_dpb_buffer_length = byte(6); + isc_dpb_debug = byte(7); + isc_dpb_garbage_collect = byte(8); + isc_dpb_verify = byte(9); + isc_dpb_sweep = byte(10); + isc_dpb_enable_journal = byte(11); + isc_dpb_disable_journal = byte(12); + isc_dpb_dbkey_scope = byte(13); + isc_dpb_number_of_users = byte(14); + isc_dpb_trace = byte(15); + isc_dpb_no_garbage_collect = byte(16); + isc_dpb_damaged = byte(17); + isc_dpb_license = byte(18); + isc_dpb_sys_user_name = byte(19); + isc_dpb_encrypt_key = byte(20); + isc_dpb_activate_shadow = byte(21); + isc_dpb_sweep_interval = byte(22); + isc_dpb_delete_shadow = byte(23); + isc_dpb_force_write = byte(24); + isc_dpb_begin_log = byte(25); + isc_dpb_quit_log = byte(26); + isc_dpb_no_reserve = byte(27); + isc_dpb_user_name = byte(28); + isc_dpb_password = byte(29); + isc_dpb_password_enc = byte(30); + isc_dpb_sys_user_name_enc = byte(31); + isc_dpb_interp = byte(32); + isc_dpb_online_dump = byte(33); + isc_dpb_old_file_size = byte(34); + isc_dpb_old_num_files = byte(35); + isc_dpb_old_file = byte(36); + isc_dpb_old_start_page = byte(37); + isc_dpb_old_start_seqno = byte(38); + isc_dpb_old_start_file = byte(39); + isc_dpb_drop_walfile = byte(40); + isc_dpb_old_dump_id = byte(41); + isc_dpb_wal_backup_dir = byte(42); + isc_dpb_wal_chkptlen = byte(43); + isc_dpb_wal_numbufs = byte(44); + isc_dpb_wal_bufsize = byte(45); + isc_dpb_wal_grp_cmt_wait = byte(46); + isc_dpb_lc_messages = byte(47); + isc_dpb_lc_ctype = byte(48); + isc_dpb_cache_manager = byte(49); + isc_dpb_shutdown = byte(50); + isc_dpb_online = byte(51); + isc_dpb_shutdown_delay = byte(52); + isc_dpb_reserved = byte(53); + isc_dpb_overwrite = byte(54); + isc_dpb_sec_attach = byte(55); + isc_dpb_disable_wal = byte(56); + isc_dpb_connect_timeout = byte(57); + isc_dpb_dummy_packet_interval = byte(58); + isc_dpb_gbak_attach = byte(59); + isc_dpb_sql_role_name = byte(60); + isc_dpb_set_page_buffers = byte(61); + isc_dpb_working_directory = byte(62); + isc_dpb_sql_dialect = byte(63); + isc_dpb_set_db_readonly = byte(64); + isc_dpb_set_db_sql_dialect = byte(65); + isc_dpb_gfix_attach = byte(66); + isc_dpb_gstat_attach = byte(67); + isc_dpb_set_db_charset = byte(68); + isc_dpb_gsec_attach = byte(69); + isc_dpb_address_path = byte(70); + isc_dpb_process_id = byte(71); + isc_dpb_no_db_triggers = byte(72); + isc_dpb_trusted_auth = byte(73); + isc_dpb_process_name = byte(74); + isc_dpb_trusted_role = byte(75); + isc_dpb_org_filename = byte(76); + isc_dpb_utf8_filename = byte(77); + isc_dpb_ext_call_depth = byte(78); + isc_dpb_auth_block = byte(79); + isc_dpb_client_version = byte(80); + isc_dpb_remote_protocol = byte(81); + isc_dpb_host_name = byte(82); + isc_dpb_os_user = byte(83); + isc_dpb_specific_auth_data = byte(84); + isc_dpb_auth_plugin_list = byte(85); + isc_dpb_auth_plugin_name = byte(86); + isc_dpb_config = byte(87); + isc_dpb_nolinger = byte(88); + isc_dpb_reset_icu = byte(89); + isc_dpb_map_attach = byte(90); + isc_dpb_address = byte(1); + isc_dpb_addr_protocol = byte(1); + isc_dpb_addr_endpoint = byte(2); + isc_dpb_pages = byte(1); + isc_dpb_records = byte(2); + isc_dpb_indices = byte(4); + isc_dpb_transactions = byte(8); + isc_dpb_no_update = byte(16); + isc_dpb_repair = byte(32); + isc_dpb_ignore = byte(64); + isc_dpb_shut_cache = $1; + isc_dpb_shut_attachment = $2; + isc_dpb_shut_transaction = $4; + isc_dpb_shut_force = $8; + isc_dpb_shut_mode_mask = $70; + isc_dpb_shut_default = $0; + isc_dpb_shut_normal = $10; + isc_dpb_shut_multi = $20; + isc_dpb_shut_single = $30; + isc_dpb_shut_full = $40; + RDB_system = byte(1); + RDB_id_assigned = byte(2); + isc_tpb_version1 = byte(1); + isc_tpb_version3 = byte(3); + isc_tpb_consistency = byte(1); + isc_tpb_concurrency = byte(2); + isc_tpb_shared = byte(3); + isc_tpb_protected = byte(4); + isc_tpb_exclusive = byte(5); + isc_tpb_wait = byte(6); + isc_tpb_nowait = byte(7); + isc_tpb_read = byte(8); + isc_tpb_write = byte(9); + isc_tpb_lock_read = byte(10); + isc_tpb_lock_write = byte(11); + isc_tpb_verb_time = byte(12); + isc_tpb_commit_time = byte(13); + isc_tpb_ignore_limbo = byte(14); + isc_tpb_read_committed = byte(15); + isc_tpb_autocommit = byte(16); + isc_tpb_rec_version = byte(17); + isc_tpb_no_rec_version = byte(18); + isc_tpb_restart_requests = byte(19); + isc_tpb_no_auto_undo = byte(20); + isc_tpb_lock_timeout = byte(21); + isc_bpb_version1 = byte(1); + isc_bpb_source_type = byte(1); + isc_bpb_target_type = byte(2); + isc_bpb_type = byte(3); + isc_bpb_source_interp = byte(4); + isc_bpb_target_interp = byte(5); + isc_bpb_filter_parameter = byte(6); + isc_bpb_storage = byte(7); + isc_bpb_type_segmented = $0; + isc_bpb_type_stream = $1; + isc_bpb_storage_main = $0; + isc_bpb_storage_temp = $2; + isc_spb_version1 = byte(1); + isc_spb_current_version = byte(2); + isc_spb_version3 = byte(3); + isc_spb_command_line = byte(105); + isc_spb_dbname = byte(106); + isc_spb_verbose = byte(107); + isc_spb_options = byte(108); + isc_spb_address_path = byte(109); + isc_spb_process_id = byte(110); + isc_spb_trusted_auth = byte(111); + isc_spb_process_name = byte(112); + isc_spb_trusted_role = byte(113); + isc_spb_verbint = byte(114); + isc_spb_auth_block = byte(115); + isc_spb_auth_plugin_name = byte(116); + isc_spb_auth_plugin_list = byte(117); + isc_spb_utf8_filename = byte(118); + isc_spb_client_version = byte(119); + isc_spb_remote_protocol = byte(120); + isc_spb_host_name = byte(121); + isc_spb_os_user = byte(122); + isc_spb_config = byte(123); + isc_spb_expected_db = byte(124); + isc_action_svc_backup = byte(1); + isc_action_svc_restore = byte(2); + isc_action_svc_repair = byte(3); + isc_action_svc_add_user = byte(4); + isc_action_svc_delete_user = byte(5); + isc_action_svc_modify_user = byte(6); + isc_action_svc_display_user = byte(7); + isc_action_svc_properties = byte(8); + isc_action_svc_add_license = byte(9); + isc_action_svc_remove_license = byte(10); + isc_action_svc_db_stats = byte(11); + isc_action_svc_get_ib_log = byte(12); + isc_action_svc_get_fb_log = byte(12); + isc_action_svc_nbak = byte(20); + isc_action_svc_nrest = byte(21); + isc_action_svc_trace_start = byte(22); + isc_action_svc_trace_stop = byte(23); + isc_action_svc_trace_suspend = byte(24); + isc_action_svc_trace_resume = byte(25); + isc_action_svc_trace_list = byte(26); + isc_action_svc_set_mapping = byte(27); + isc_action_svc_drop_mapping = byte(28); + isc_action_svc_display_user_adm = byte(29); + isc_action_svc_validate = byte(30); + isc_action_svc_last = byte(31); + isc_info_svc_svr_db_info = byte(50); + isc_info_svc_get_license = byte(51); + isc_info_svc_get_license_mask = byte(52); + isc_info_svc_get_config = byte(53); + isc_info_svc_version = byte(54); + isc_info_svc_server_version = byte(55); + isc_info_svc_implementation = byte(56); + isc_info_svc_capabilities = byte(57); + isc_info_svc_user_dbpath = byte(58); + isc_info_svc_get_env = byte(59); + isc_info_svc_get_env_lock = byte(60); + isc_info_svc_get_env_msg = byte(61); + isc_info_svc_line = byte(62); + isc_info_svc_to_eof = byte(63); + isc_info_svc_timeout = byte(64); + isc_info_svc_get_licensed_users = byte(65); + isc_info_svc_limbo_trans = byte(66); + isc_info_svc_running = byte(67); + isc_info_svc_get_users = byte(68); + isc_info_svc_auth_block = byte(69); + isc_info_svc_stdin = byte(78); + isc_spb_sec_userid = byte(5); + isc_spb_sec_groupid = byte(6); + isc_spb_sec_username = byte(7); + isc_spb_sec_password = byte(8); + isc_spb_sec_groupname = byte(9); + isc_spb_sec_firstname = byte(10); + isc_spb_sec_middlename = byte(11); + isc_spb_sec_lastname = byte(12); + isc_spb_sec_admin = byte(13); + isc_spb_lic_key = byte(5); + isc_spb_lic_id = byte(6); + isc_spb_lic_desc = byte(7); + isc_spb_bkp_file = byte(5); + isc_spb_bkp_factor = byte(6); + isc_spb_bkp_length = byte(7); + isc_spb_bkp_skip_data = byte(8); + isc_spb_bkp_stat = byte(15); + isc_spb_bkp_ignore_checksums = $01; + isc_spb_bkp_ignore_limbo = $02; + isc_spb_bkp_metadata_only = $04; + isc_spb_bkp_no_garbage_collect = $08; + isc_spb_bkp_old_descriptions = $10; + isc_spb_bkp_non_transportable = $20; + isc_spb_bkp_convert = $40; + isc_spb_bkp_expand = $80; + isc_spb_bkp_no_triggers = $8000; + isc_spb_prp_page_buffers = byte(5); + isc_spb_prp_sweep_interval = byte(6); + isc_spb_prp_shutdown_db = byte(7); + isc_spb_prp_deny_new_attachments = byte(9); + isc_spb_prp_deny_new_transactions = byte(10); + isc_spb_prp_reserve_space = byte(11); + isc_spb_prp_write_mode = byte(12); + isc_spb_prp_access_mode = byte(13); + isc_spb_prp_set_sql_dialect = byte(14); + isc_spb_prp_activate = $0100; + isc_spb_prp_db_online = $0200; + isc_spb_prp_nolinger = $0400; + isc_spb_prp_force_shutdown = byte(41); + isc_spb_prp_attachments_shutdown = byte(42); + isc_spb_prp_transactions_shutdown = byte(43); + isc_spb_prp_shutdown_mode = byte(44); + isc_spb_prp_online_mode = byte(45); + isc_spb_prp_sm_normal = byte(0); + isc_spb_prp_sm_multi = byte(1); + isc_spb_prp_sm_single = byte(2); + isc_spb_prp_sm_full = byte(3); + isc_spb_prp_res_use_full = byte(35); + isc_spb_prp_res = byte(36); + isc_spb_prp_wm_async = byte(37); + isc_spb_prp_wm_sync = byte(38); + isc_spb_prp_am_readonly = byte(39); + isc_spb_prp_am_readwrite = byte(40); + isc_spb_rpr_commit_trans = byte(15); + isc_spb_rpr_rollback_trans = byte(34); + isc_spb_rpr_recover_two_phase = byte(17); + isc_spb_tra_id = byte(18); + isc_spb_single_tra_id = byte(19); + isc_spb_multi_tra_id = byte(20); + isc_spb_tra_state = byte(21); + isc_spb_tra_state_limbo = byte(22); + isc_spb_tra_state_commit = byte(23); + isc_spb_tra_state_rollback = byte(24); + isc_spb_tra_state_unknown = byte(25); + isc_spb_tra_host_site = byte(26); + isc_spb_tra_remote_site = byte(27); + isc_spb_tra_db_path = byte(28); + isc_spb_tra_advise = byte(29); + isc_spb_tra_advise_commit = byte(30); + isc_spb_tra_advise_rollback = byte(31); + isc_spb_tra_advise_unknown = byte(33); + isc_spb_tra_id_64 = byte(46); + isc_spb_single_tra_id_64 = byte(47); + isc_spb_multi_tra_id_64 = byte(48); + isc_spb_rpr_commit_trans_64 = byte(49); + isc_spb_rpr_rollback_trans_64 = byte(50); + isc_spb_rpr_recover_two_phase_64 = byte(51); + isc_spb_rpr_validate_db = $01; + isc_spb_rpr_sweep_db = $02; + isc_spb_rpr_mend_db = $04; + isc_spb_rpr_list_limbo_trans = $08; + isc_spb_rpr_check_db = $10; + isc_spb_rpr_ignore_checksum = $20; + isc_spb_rpr_kill_shadows = $40; + isc_spb_rpr_full = $80; + isc_spb_rpr_icu = $0800; + isc_spb_res_buffers = byte(9); + isc_spb_res_page_size = byte(10); + isc_spb_res_length = byte(11); + isc_spb_res_access_mode = byte(12); + isc_spb_res_fix_fss_data = byte(13); + isc_spb_res_fix_fss_metadata = byte(14); + isc_spb_res_deactivate_idx = $0100; + isc_spb_res_no_shadow = $0200; + isc_spb_res_no_validity = $0400; + isc_spb_res_one_at_a_time = $0800; + isc_spb_res_replace = $1000; + isc_spb_res_create = $2000; + isc_spb_res_use_all_space = $4000; + isc_spb_val_tab_incl = byte(1); + isc_spb_val_tab_excl = byte(2); + isc_spb_val_idx_incl = byte(3); + isc_spb_val_idx_excl = byte(4); + isc_spb_val_lock_timeout = byte(5); + isc_spb_num_att = byte(5); + isc_spb_num_db = byte(6); + isc_spb_sts_table = byte(64); + isc_spb_sts_data_pages = $01; + isc_spb_sts_db_log = $02; + isc_spb_sts_hdr_pages = $04; + isc_spb_sts_idx_pages = $08; + isc_spb_sts_sys_relations = $10; + isc_spb_sts_record_versions = $20; + isc_spb_sts_nocreation = $80; + isc_spb_sts_encryption = $100; + isc_spb_nbk_level = byte(5); + isc_spb_nbk_file = byte(6); + isc_spb_nbk_direct = byte(7); + isc_spb_nbk_no_triggers = $01; + isc_spb_trc_id = byte(1); + isc_spb_trc_name = byte(2); + isc_spb_trc_cfg = byte(3); + isc_sdl_version1 = byte(1); + isc_sdl_eoc = byte(255); + isc_sdl_relation = byte(2); + isc_sdl_rid = byte(3); + isc_sdl_field = byte(4); + isc_sdl_fid = byte(5); + isc_sdl_struct = byte(6); + isc_sdl_variable = byte(7); + isc_sdl_scalar = byte(8); + isc_sdl_tiny_integer = byte(9); + isc_sdl_short_integer = byte(10); + isc_sdl_long_integer = byte(11); + isc_sdl_add = byte(13); + isc_sdl_subtract = byte(14); + isc_sdl_multiply = byte(15); + isc_sdl_divide = byte(16); + isc_sdl_negate = byte(17); + isc_sdl_begin = byte(31); + isc_sdl_end = byte(32); + isc_sdl_do3 = byte(33); + isc_sdl_do2 = byte(34); + isc_sdl_do1 = byte(35); + isc_sdl_element = byte(36); + isc_blob_untyped = byte(0); + isc_blob_text = byte(1); + isc_blob_blr = byte(2); + isc_blob_acl = byte(3); + isc_blob_ranges = byte(4); + isc_blob_summary = byte(5); + isc_blob_format = byte(6); + isc_blob_tra = byte(7); + isc_blob_extfile = byte(8); + isc_blob_debug_info = byte(9); + isc_blob_max_predefined_subtype = byte(10); + fb_shut_confirmation = byte(1); + fb_shut_preproviders = byte(2); + fb_shut_postproviders = byte(4); + fb_shut_finish = byte(8); + fb_shut_exit = byte(16); + fb_cancel_disable = byte(1); + fb_cancel_enable = byte(2); + fb_cancel_raise = byte(3); + fb_cancel_abort = byte(4); + fb_dbg_version = byte(1); + fb_dbg_end = byte(255); + fb_dbg_map_src2blr = byte(2); + fb_dbg_map_varname = byte(3); + fb_dbg_map_argument = byte(4); + fb_dbg_subproc = byte(5); + fb_dbg_subfunc = byte(6); + fb_dbg_map_curname = byte(7); + fb_dbg_arg_input = byte(0); + fb_dbg_arg_output = byte(1); + isc_facility = 20; + isc_err_base = 335544320; + isc_err_factor = 1; + isc_arg_end = 0; (* end of argument list *) + isc_arg_gds = 1; (* generic DSRI status value *) + isc_arg_string = 2; (* string argument *) + isc_arg_cstring = 3; (* count & string argument *) + isc_arg_number = 4; (* numeric argument (long) *) + isc_arg_interpreted = 5; (* interpreted status code (string) *) + isc_arg_vms = 6; (* VAX/VMS status code (long) *) + isc_arg_unix = 7; (* UNIX error code *) + isc_arg_domain = 8; (* Apollo/Domain error code *) + isc_arg_dos = 9; (* MSDOS/OS2 error code *) + isc_arith_except = 335544321; + isc_bad_dbkey = 335544322; + isc_bad_db_format = 335544323; + isc_bad_db_handle = 335544324; + isc_bad_dpb_content = 335544325; + isc_bad_dpb_form = 335544326; + isc_bad_req_handle = 335544327; + isc_bad_segstr_handle = 335544328; + isc_bad_segstr_id = 335544329; + isc_bad_tpb_content = 335544330; + isc_bad_tpb_form = 335544331; + isc_bad_trans_handle = 335544332; + isc_bug_check = 335544333; + isc_convert_error = 335544334; + isc_db_corrupt = 335544335; + isc_deadlock = 335544336; + isc_excess_trans = 335544337; + isc_from_no_match = 335544338; + isc_infinap = 335544339; + isc_infona = 335544340; + isc_infunk = 335544341; + isc_integ_fail = 335544342; + isc_invalid_blr = 335544343; + isc_io_error = 335544344; + isc_lock_conflict = 335544345; + isc_metadata_corrupt = 335544346; + isc_not_valid = 335544347; + isc_no_cur_rec = 335544348; + isc_no_dup = 335544349; + isc_no_finish = 335544350; + isc_no_meta_update = 335544351; + isc_no_priv = 335544352; + isc_no_recon = 335544353; + isc_no_record = 335544354; + isc_no_segstr_close = 335544355; + isc_obsolete_metadata = 335544356; + isc_open_trans = 335544357; + isc_port_len = 335544358; + isc_read_only_field = 335544359; + isc_read_only_rel = 335544360; + isc_read_only_trans = 335544361; + isc_read_only_view = 335544362; + isc_req_no_trans = 335544363; + isc_req_sync = 335544364; + isc_req_wrong_db = 335544365; + isc_segment = 335544366; + isc_segstr_eof = 335544367; + isc_segstr_no_op = 335544368; + isc_segstr_no_read = 335544369; + isc_segstr_no_trans = 335544370; + isc_segstr_no_write = 335544371; + isc_segstr_wrong_db = 335544372; + isc_sys_request = 335544373; + isc_stream_eof = 335544374; + isc_unavailable = 335544375; + isc_unres_rel = 335544376; + isc_uns_ext = 335544377; + isc_wish_list = 335544378; + isc_wrong_ods = 335544379; + isc_wronumarg = 335544380; + isc_imp_exc = 335544381; + isc_random = 335544382; + isc_fatal_conflict = 335544383; + isc_badblk = 335544384; + isc_invpoolcl = 335544385; + isc_nopoolids = 335544386; + isc_relbadblk = 335544387; + isc_blktoobig = 335544388; + isc_bufexh = 335544389; + isc_syntaxerr = 335544390; + isc_bufinuse = 335544391; + isc_bdbincon = 335544392; + isc_reqinuse = 335544393; + isc_badodsver = 335544394; + isc_relnotdef = 335544395; + isc_fldnotdef = 335544396; + isc_dirtypage = 335544397; + isc_waifortra = 335544398; + isc_doubleloc = 335544399; + isc_nodnotfnd = 335544400; + isc_dupnodfnd = 335544401; + isc_locnotmar = 335544402; + isc_badpagtyp = 335544403; + isc_corrupt = 335544404; + isc_badpage = 335544405; + isc_badindex = 335544406; + isc_dbbnotzer = 335544407; + isc_tranotzer = 335544408; + isc_trareqmis = 335544409; + isc_badhndcnt = 335544410; + isc_wrotpbver = 335544411; + isc_wroblrver = 335544412; + isc_wrodpbver = 335544413; + isc_blobnotsup = 335544414; + isc_badrelation = 335544415; + isc_nodetach = 335544416; + isc_notremote = 335544417; + isc_trainlim = 335544418; + isc_notinlim = 335544419; + isc_traoutsta = 335544420; + isc_connect_reject = 335544421; + isc_dbfile = 335544422; + isc_orphan = 335544423; + isc_no_lock_mgr = 335544424; + isc_ctxinuse = 335544425; + isc_ctxnotdef = 335544426; + isc_datnotsup = 335544427; + isc_badmsgnum = 335544428; + isc_badparnum = 335544429; + isc_virmemexh = 335544430; + isc_blocking_signal = 335544431; + isc_lockmanerr = 335544432; + isc_journerr = 335544433; + isc_keytoobig = 335544434; + isc_nullsegkey = 335544435; + isc_sqlerr = 335544436; + isc_wrodynver = 335544437; + isc_funnotdef = 335544438; + isc_funmismat = 335544439; + isc_bad_msg_vec = 335544440; + isc_bad_detach = 335544441; + isc_noargacc_read = 335544442; + isc_noargacc_write = 335544443; + isc_read_only = 335544444; + isc_ext_err = 335544445; + isc_non_updatable = 335544446; + isc_no_rollback = 335544447; + isc_bad_sec_info = 335544448; + isc_invalid_sec_info = 335544449; + isc_misc_interpreted = 335544450; + isc_update_conflict = 335544451; + isc_unlicensed = 335544452; + isc_obj_in_use = 335544453; + isc_nofilter = 335544454; + isc_shadow_accessed = 335544455; + isc_invalid_sdl = 335544456; + isc_out_of_bounds = 335544457; + isc_invalid_dimension = 335544458; + isc_rec_in_limbo = 335544459; + isc_shadow_missing = 335544460; + isc_cant_validate = 335544461; + isc_cant_start_journal = 335544462; + isc_gennotdef = 335544463; + isc_cant_start_logging = 335544464; + isc_bad_segstr_type = 335544465; + isc_foreign_key = 335544466; + isc_high_minor = 335544467; + isc_tra_state = 335544468; + isc_trans_invalid = 335544469; + isc_buf_invalid = 335544470; + isc_indexnotdefined = 335544471; + isc_login = 335544472; + isc_invalid_bookmark = 335544473; + isc_bad_lock_level = 335544474; + isc_relation_lock = 335544475; + isc_record_lock = 335544476; + isc_max_idx = 335544477; + isc_jrn_enable = 335544478; + isc_old_failure = 335544479; + isc_old_in_progress = 335544480; + isc_old_no_space = 335544481; + isc_no_wal_no_jrn = 335544482; + isc_num_old_files = 335544483; + isc_wal_file_open = 335544484; + isc_bad_stmt_handle = 335544485; + isc_wal_failure = 335544486; + isc_walw_err = 335544487; + isc_logh_small = 335544488; + isc_logh_inv_version = 335544489; + isc_logh_open_flag = 335544490; + isc_logh_open_flag2 = 335544491; + isc_logh_diff_dbname = 335544492; + isc_logf_unexpected_eof = 335544493; + isc_logr_incomplete = 335544494; + isc_logr_header_small = 335544495; + isc_logb_small = 335544496; + isc_wal_illegal_attach = 335544497; + isc_wal_invalid_wpb = 335544498; + isc_wal_err_rollover = 335544499; + isc_no_wal = 335544500; + isc_drop_wal = 335544501; + isc_stream_not_defined = 335544502; + isc_wal_subsys_error = 335544503; + isc_wal_subsys_corrupt = 335544504; + isc_no_archive = 335544505; + isc_shutinprog = 335544506; + isc_range_in_use = 335544507; + isc_range_not_found = 335544508; + isc_charset_not_found = 335544509; + isc_lock_timeout = 335544510; + isc_prcnotdef = 335544511; + isc_prcmismat = 335544512; + isc_wal_bugcheck = 335544513; + isc_wal_cant_expand = 335544514; + isc_codnotdef = 335544515; + isc_xcpnotdef = 335544516; + isc_except = 335544517; + isc_cache_restart = 335544518; + isc_bad_lock_handle = 335544519; + isc_jrn_present = 335544520; + isc_wal_err_rollover2 = 335544521; + isc_wal_err_logwrite = 335544522; + isc_wal_err_jrn_comm = 335544523; + isc_wal_err_expansion = 335544524; + isc_wal_err_setup = 335544525; + isc_wal_err_ww_sync = 335544526; + isc_wal_err_ww_start = 335544527; + isc_shutdown = 335544528; + isc_existing_priv_mod = 335544529; + isc_primary_key_ref = 335544530; + isc_primary_key_notnull = 335544531; + isc_ref_cnstrnt_notfound = 335544532; + isc_foreign_key_notfound = 335544533; + isc_ref_cnstrnt_update = 335544534; + isc_check_cnstrnt_update = 335544535; + isc_check_cnstrnt_del = 335544536; + isc_integ_index_seg_del = 335544537; + isc_integ_index_seg_mod = 335544538; + isc_integ_index_del = 335544539; + isc_integ_index_mod = 335544540; + isc_check_trig_del = 335544541; + isc_check_trig_update = 335544542; + isc_cnstrnt_fld_del = 335544543; + isc_cnstrnt_fld_rename = 335544544; + isc_rel_cnstrnt_update = 335544545; + isc_constaint_on_view = 335544546; + isc_invld_cnstrnt_type = 335544547; + isc_primary_key_exists = 335544548; + isc_systrig_update = 335544549; + isc_not_rel_owner = 335544550; + isc_grant_obj_notfound = 335544551; + isc_grant_fld_notfound = 335544552; + isc_grant_nopriv = 335544553; + isc_nonsql_security_rel = 335544554; + isc_nonsql_security_fld = 335544555; + isc_wal_cache_err = 335544556; + isc_shutfail = 335544557; + isc_check_constraint = 335544558; + isc_bad_svc_handle = 335544559; + isc_shutwarn = 335544560; + isc_wrospbver = 335544561; + isc_bad_spb_form = 335544562; + isc_svcnotdef = 335544563; + isc_no_jrn = 335544564; + isc_transliteration_failed = 335544565; + isc_start_cm_for_wal = 335544566; + isc_wal_ovflow_log_required = 335544567; + isc_text_subtype = 335544568; + isc_dsql_error = 335544569; + isc_dsql_command_err = 335544570; + isc_dsql_constant_err = 335544571; + isc_dsql_cursor_err = 335544572; + isc_dsql_datatype_err = 335544573; + isc_dsql_decl_err = 335544574; + isc_dsql_cursor_update_err = 335544575; + isc_dsql_cursor_open_err = 335544576; + isc_dsql_cursor_close_err = 335544577; + isc_dsql_field_err = 335544578; + isc_dsql_internal_err = 335544579; + isc_dsql_relation_err = 335544580; + isc_dsql_procedure_err = 335544581; + isc_dsql_request_err = 335544582; + isc_dsql_sqlda_err = 335544583; + isc_dsql_var_count_err = 335544584; + isc_dsql_stmt_handle = 335544585; + isc_dsql_function_err = 335544586; + isc_dsql_blob_err = 335544587; + isc_collation_not_found = 335544588; + isc_collation_not_for_charset = 335544589; + isc_dsql_dup_option = 335544590; + isc_dsql_tran_err = 335544591; + isc_dsql_invalid_array = 335544592; + isc_dsql_max_arr_dim_exceeded = 335544593; + isc_dsql_arr_range_error = 335544594; + isc_dsql_trigger_err = 335544595; + isc_dsql_subselect_err = 335544596; + isc_dsql_crdb_prepare_err = 335544597; + isc_specify_field_err = 335544598; + isc_num_field_err = 335544599; + isc_col_name_err = 335544600; + isc_where_err = 335544601; + isc_table_view_err = 335544602; + isc_distinct_err = 335544603; + isc_key_field_count_err = 335544604; + isc_subquery_err = 335544605; + isc_expression_eval_err = 335544606; + isc_node_err = 335544607; + isc_command_end_err = 335544608; + isc_index_name = 335544609; + isc_exception_name = 335544610; + isc_field_name = 335544611; + isc_token_err = 335544612; + isc_union_err = 335544613; + isc_dsql_construct_err = 335544614; + isc_field_aggregate_err = 335544615; + isc_field_ref_err = 335544616; + isc_order_by_err = 335544617; + isc_return_mode_err = 335544618; + isc_extern_func_err = 335544619; + isc_alias_conflict_err = 335544620; + isc_procedure_conflict_error = 335544621; + isc_relation_conflict_err = 335544622; + isc_dsql_domain_err = 335544623; + isc_idx_seg_err = 335544624; + isc_node_name_err = 335544625; + isc_table_name = 335544626; + isc_proc_name = 335544627; + isc_idx_create_err = 335544628; + isc_wal_shadow_err = 335544629; + isc_dependency = 335544630; + isc_idx_key_err = 335544631; + isc_dsql_file_length_err = 335544632; + isc_dsql_shadow_number_err = 335544633; + isc_dsql_token_unk_err = 335544634; + isc_dsql_no_relation_alias = 335544635; + isc_indexname = 335544636; + isc_no_stream_plan = 335544637; + isc_stream_twice = 335544638; + isc_stream_not_found = 335544639; + isc_collation_requires_text = 335544640; + isc_dsql_domain_not_found = 335544641; + isc_index_unused = 335544642; + isc_dsql_self_join = 335544643; + isc_stream_bof = 335544644; + isc_stream_crack = 335544645; + isc_db_or_file_exists = 335544646; + isc_invalid_operator = 335544647; + isc_conn_lost = 335544648; + isc_bad_checksum = 335544649; + isc_page_type_err = 335544650; + isc_ext_readonly_err = 335544651; + isc_sing_select_err = 335544652; + isc_psw_attach = 335544653; + isc_psw_start_trans = 335544654; + isc_invalid_direction = 335544655; + isc_dsql_var_conflict = 335544656; + isc_dsql_no_blob_array = 335544657; + isc_dsql_base_table = 335544658; + isc_duplicate_base_table = 335544659; + isc_view_alias = 335544660; + isc_index_root_page_full = 335544661; + isc_dsql_blob_type_unknown = 335544662; + isc_req_max_clones_exceeded = 335544663; + isc_dsql_duplicate_spec = 335544664; + isc_unique_key_violation = 335544665; + isc_srvr_version_too_old = 335544666; + isc_drdb_completed_with_errs = 335544667; + isc_dsql_procedure_use_err = 335544668; + isc_dsql_count_mismatch = 335544669; + isc_blob_idx_err = 335544670; + isc_array_idx_err = 335544671; + isc_key_field_err = 335544672; + isc_no_delete = 335544673; + isc_del_last_field = 335544674; + isc_sort_err = 335544675; + isc_sort_mem_err = 335544676; + isc_version_err = 335544677; + isc_inval_key_posn = 335544678; + isc_no_segments_err = 335544679; + isc_crrp_data_err = 335544680; + isc_rec_size_err = 335544681; + isc_dsql_field_ref = 335544682; + isc_req_depth_exceeded = 335544683; + isc_no_field_access = 335544684; + isc_no_dbkey = 335544685; + isc_jrn_format_err = 335544686; + isc_jrn_file_full = 335544687; + isc_dsql_open_cursor_request = 335544688; + isc_ib_error = 335544689; + isc_cache_redef = 335544690; + isc_cache_too_small = 335544691; + isc_log_redef = 335544692; + isc_log_too_small = 335544693; + isc_partition_too_small = 335544694; + isc_partition_not_supp = 335544695; + isc_log_length_spec = 335544696; + isc_precision_err = 335544697; + isc_scale_nogt = 335544698; + isc_expec_short = 335544699; + isc_expec_long = 335544700; + isc_expec_ushort = 335544701; + isc_escape_invalid = 335544702; + isc_svcnoexe = 335544703; + isc_net_lookup_err = 335544704; + isc_service_unknown = 335544705; + isc_host_unknown = 335544706; + isc_grant_nopriv_on_base = 335544707; + isc_dyn_fld_ambiguous = 335544708; + isc_dsql_agg_ref_err = 335544709; + isc_complex_view = 335544710; + isc_unprepared_stmt = 335544711; + isc_expec_positive = 335544712; + isc_dsql_sqlda_value_err = 335544713; + isc_invalid_array_id = 335544714; + isc_extfile_uns_op = 335544715; + isc_svc_in_use = 335544716; + isc_err_stack_limit = 335544717; + isc_invalid_key = 335544718; + isc_net_init_error = 335544719; + isc_loadlib_failure = 335544720; + isc_network_error = 335544721; + isc_net_connect_err = 335544722; + isc_net_connect_listen_err = 335544723; + isc_net_event_connect_err = 335544724; + isc_net_event_listen_err = 335544725; + isc_net_read_err = 335544726; + isc_net_write_err = 335544727; + isc_integ_index_deactivate = 335544728; + isc_integ_deactivate_primary = 335544729; + isc_cse_not_supported = 335544730; + isc_tra_must_sweep = 335544731; + isc_unsupported_network_drive = 335544732; + isc_io_create_err = 335544733; + isc_io_open_err = 335544734; + isc_io_close_err = 335544735; + isc_io_read_err = 335544736; + isc_io_write_err = 335544737; + isc_io_delete_err = 335544738; + isc_io_access_err = 335544739; + isc_udf_exception = 335544740; + isc_lost_db_connection = 335544741; + isc_no_write_user_priv = 335544742; + isc_token_too_long = 335544743; + isc_max_att_exceeded = 335544744; + isc_login_same_as_role_name = 335544745; + isc_reftable_requires_pk = 335544746; + isc_usrname_too_long = 335544747; + isc_password_too_long = 335544748; + isc_usrname_required = 335544749; + isc_password_required = 335544750; + isc_bad_protocol = 335544751; + isc_dup_usrname_found = 335544752; + isc_usrname_not_found = 335544753; + isc_error_adding_sec_record = 335544754; + isc_error_modifying_sec_record = 335544755; + isc_error_deleting_sec_record = 335544756; + isc_error_updating_sec_db = 335544757; + isc_sort_rec_size_err = 335544758; + isc_bad_default_value = 335544759; + isc_invalid_clause = 335544760; + isc_too_many_handles = 335544761; + isc_optimizer_blk_exc = 335544762; + isc_invalid_string_constant = 335544763; + isc_transitional_date = 335544764; + isc_read_only_database = 335544765; + isc_must_be_dialect_2_and_up = 335544766; + isc_blob_filter_exception = 335544767; + isc_exception_access_violation = 335544768; + isc_exception_datatype_missalignment = 335544769; + isc_exception_array_bounds_exceeded = 335544770; + isc_exception_float_denormal_operand = 335544771; + isc_exception_float_divide_by_zero = 335544772; + isc_exception_float_inexact_result = 335544773; + isc_exception_float_invalid_operand = 335544774; + isc_exception_float_overflow = 335544775; + isc_exception_float_stack_check = 335544776; + isc_exception_float_underflow = 335544777; + isc_exception_integer_divide_by_zero = 335544778; + isc_exception_integer_overflow = 335544779; + isc_exception_unknown = 335544780; + isc_exception_stack_overflow = 335544781; + isc_exception_sigsegv = 335544782; + isc_exception_sigill = 335544783; + isc_exception_sigbus = 335544784; + isc_exception_sigfpe = 335544785; + isc_ext_file_delete = 335544786; + isc_ext_file_modify = 335544787; + isc_adm_task_denied = 335544788; + isc_extract_input_mismatch = 335544789; + isc_insufficient_svc_privileges = 335544790; + isc_file_in_use = 335544791; + isc_service_att_err = 335544792; + isc_ddl_not_allowed_by_db_sql_dial = 335544793; + isc_cancelled = 335544794; + isc_unexp_spb_form = 335544795; + isc_sql_dialect_datatype_unsupport = 335544796; + isc_svcnouser = 335544797; + isc_depend_on_uncommitted_rel = 335544798; + isc_svc_name_missing = 335544799; + isc_too_many_contexts = 335544800; + isc_datype_notsup = 335544801; + isc_dialect_reset_warning = 335544802; + isc_dialect_not_changed = 335544803; + isc_database_create_failed = 335544804; + isc_inv_dialect_specified = 335544805; + isc_valid_db_dialects = 335544806; + isc_sqlwarn = 335544807; + isc_dtype_renamed = 335544808; + isc_extern_func_dir_error = 335544809; + isc_date_range_exceeded = 335544810; + isc_inv_client_dialect_specified = 335544811; + isc_valid_client_dialects = 335544812; + isc_optimizer_between_err = 335544813; + isc_service_not_supported = 335544814; + isc_generator_name = 335544815; + isc_udf_name = 335544816; + isc_bad_limit_param = 335544817; + isc_bad_skip_param = 335544818; + isc_io_32bit_exceeded_err = 335544819; + isc_invalid_savepoint = 335544820; + isc_dsql_column_pos_err = 335544821; + isc_dsql_agg_where_err = 335544822; + isc_dsql_agg_group_err = 335544823; + isc_dsql_agg_column_err = 335544824; + isc_dsql_agg_having_err = 335544825; + isc_dsql_agg_nested_err = 335544826; + isc_exec_sql_invalid_arg = 335544827; + isc_exec_sql_invalid_req = 335544828; + isc_exec_sql_invalid_var = 335544829; + isc_exec_sql_max_call_exceeded = 335544830; + isc_conf_access_denied = 335544831; + isc_wrong_backup_state = 335544832; + isc_wal_backup_err = 335544833; + isc_cursor_not_open = 335544834; + isc_bad_shutdown_mode = 335544835; + isc_concat_overflow = 335544836; + isc_bad_substring_offset = 335544837; + isc_foreign_key_target_doesnt_exist = 335544838; + isc_foreign_key_references_present = 335544839; + isc_no_update = 335544840; + isc_cursor_already_open = 335544841; + isc_stack_trace = 335544842; + isc_ctx_var_not_found = 335544843; + isc_ctx_namespace_invalid = 335544844; + isc_ctx_too_big = 335544845; + isc_ctx_bad_argument = 335544846; + isc_identifier_too_long = 335544847; + isc_except2 = 335544848; + isc_malformed_string = 335544849; + isc_prc_out_param_mismatch = 335544850; + isc_command_end_err2 = 335544851; + isc_partner_idx_incompat_type = 335544852; + isc_bad_substring_length = 335544853; + isc_charset_not_installed = 335544854; + isc_collation_not_installed = 335544855; + isc_att_shutdown = 335544856; + isc_blobtoobig = 335544857; + isc_must_have_phys_field = 335544858; + isc_invalid_time_precision = 335544859; + isc_blob_convert_error = 335544860; + isc_array_convert_error = 335544861; + isc_record_lock_not_supp = 335544862; + isc_partner_idx_not_found = 335544863; + isc_tra_num_exc = 335544864; + isc_field_disappeared = 335544865; + isc_met_wrong_gtt_scope = 335544866; + isc_subtype_for_internal_use = 335544867; + isc_illegal_prc_type = 335544868; + isc_invalid_sort_datatype = 335544869; + isc_collation_name = 335544870; + isc_domain_name = 335544871; + isc_domnotdef = 335544872; + isc_array_max_dimensions = 335544873; + isc_max_db_per_trans_allowed = 335544874; + isc_bad_debug_format = 335544875; + isc_bad_proc_BLR = 335544876; + isc_key_too_big = 335544877; + isc_concurrent_transaction = 335544878; + isc_not_valid_for_var = 335544879; + isc_not_valid_for = 335544880; + isc_need_difference = 335544881; + isc_long_login = 335544882; + isc_fldnotdef2 = 335544883; + isc_invalid_similar_pattern = 335544884; + isc_bad_teb_form = 335544885; + isc_tpb_multiple_txn_isolation = 335544886; + isc_tpb_reserv_before_table = 335544887; + isc_tpb_multiple_spec = 335544888; + isc_tpb_option_without_rc = 335544889; + isc_tpb_conflicting_options = 335544890; + isc_tpb_reserv_missing_tlen = 335544891; + isc_tpb_reserv_long_tlen = 335544892; + isc_tpb_reserv_missing_tname = 335544893; + isc_tpb_reserv_corrup_tlen = 335544894; + isc_tpb_reserv_null_tlen = 335544895; + isc_tpb_reserv_relnotfound = 335544896; + isc_tpb_reserv_baserelnotfound = 335544897; + isc_tpb_missing_len = 335544898; + isc_tpb_missing_value = 335544899; + isc_tpb_corrupt_len = 335544900; + isc_tpb_null_len = 335544901; + isc_tpb_overflow_len = 335544902; + isc_tpb_invalid_value = 335544903; + isc_tpb_reserv_stronger_wng = 335544904; + isc_tpb_reserv_stronger = 335544905; + isc_tpb_reserv_max_recursion = 335544906; + isc_tpb_reserv_virtualtbl = 335544907; + isc_tpb_reserv_systbl = 335544908; + isc_tpb_reserv_temptbl = 335544909; + isc_tpb_readtxn_after_writelock = 335544910; + isc_tpb_writelock_after_readtxn = 335544911; + isc_time_range_exceeded = 335544912; + isc_datetime_range_exceeded = 335544913; + isc_string_truncation = 335544914; + isc_blob_truncation = 335544915; + isc_numeric_out_of_range = 335544916; + isc_shutdown_timeout = 335544917; + isc_att_handle_busy = 335544918; + isc_bad_udf_freeit = 335544919; + isc_eds_provider_not_found = 335544920; + isc_eds_connection = 335544921; + isc_eds_preprocess = 335544922; + isc_eds_stmt_expected = 335544923; + isc_eds_prm_name_expected = 335544924; + isc_eds_unclosed_comment = 335544925; + isc_eds_statement = 335544926; + isc_eds_input_prm_mismatch = 335544927; + isc_eds_output_prm_mismatch = 335544928; + isc_eds_input_prm_not_set = 335544929; + isc_too_big_blr = 335544930; + isc_montabexh = 335544931; + isc_modnotfound = 335544932; + isc_nothing_to_cancel = 335544933; + isc_ibutil_not_loaded = 335544934; + isc_circular_computed = 335544935; + isc_psw_db_error = 335544936; + isc_invalid_type_datetime_op = 335544937; + isc_onlycan_add_timetodate = 335544938; + isc_onlycan_add_datetotime = 335544939; + isc_onlycansub_tstampfromtstamp = 335544940; + isc_onlyoneop_mustbe_tstamp = 335544941; + isc_invalid_extractpart_time = 335544942; + isc_invalid_extractpart_date = 335544943; + isc_invalidarg_extract = 335544944; + isc_sysf_argmustbe_exact = 335544945; + isc_sysf_argmustbe_exact_or_fp = 335544946; + isc_sysf_argviolates_uuidtype = 335544947; + isc_sysf_argviolates_uuidlen = 335544948; + isc_sysf_argviolates_uuidfmt = 335544949; + isc_sysf_argviolates_guidigits = 335544950; + isc_sysf_invalid_addpart_time = 335544951; + isc_sysf_invalid_add_datetime = 335544952; + isc_sysf_invalid_addpart_dtime = 335544953; + isc_sysf_invalid_add_dtime_rc = 335544954; + isc_sysf_invalid_diff_dtime = 335544955; + isc_sysf_invalid_timediff = 335544956; + isc_sysf_invalid_tstamptimediff = 335544957; + isc_sysf_invalid_datetimediff = 335544958; + isc_sysf_invalid_diffpart = 335544959; + isc_sysf_argmustbe_positive = 335544960; + isc_sysf_basemustbe_positive = 335544961; + isc_sysf_argnmustbe_nonneg = 335544962; + isc_sysf_argnmustbe_positive = 335544963; + isc_sysf_invalid_zeropowneg = 335544964; + isc_sysf_invalid_negpowfp = 335544965; + isc_sysf_invalid_scale = 335544966; + isc_sysf_argmustbe_nonneg = 335544967; + isc_sysf_binuuid_mustbe_str = 335544968; + isc_sysf_binuuid_wrongsize = 335544969; + isc_missing_required_spb = 335544970; + isc_net_server_shutdown = 335544971; + isc_bad_conn_str = 335544972; + isc_bad_epb_form = 335544973; + isc_no_threads = 335544974; + isc_net_event_connect_timeout = 335544975; + isc_sysf_argmustbe_nonzero = 335544976; + isc_sysf_argmustbe_range_inc1_1 = 335544977; + isc_sysf_argmustbe_gteq_one = 335544978; + isc_sysf_argmustbe_range_exc1_1 = 335544979; + isc_internal_rejected_params = 335544980; + isc_sysf_fp_overflow = 335544981; + isc_udf_fp_overflow = 335544982; + isc_udf_fp_nan = 335544983; + isc_instance_conflict = 335544984; + isc_out_of_temp_space = 335544985; + isc_eds_expl_tran_ctrl = 335544986; + isc_no_trusted_spb = 335544987; + isc_package_name = 335544988; + isc_cannot_make_not_null = 335544989; + isc_feature_removed = 335544990; + isc_view_name = 335544991; + isc_lock_dir_access = 335544992; + isc_invalid_fetch_option = 335544993; + isc_bad_fun_BLR = 335544994; + isc_func_pack_not_implemented = 335544995; + isc_proc_pack_not_implemented = 335544996; + isc_eem_func_not_returned = 335544997; + isc_eem_proc_not_returned = 335544998; + isc_eem_trig_not_returned = 335544999; + isc_eem_bad_plugin_ver = 335545000; + isc_eem_engine_notfound = 335545001; + isc_attachment_in_use = 335545002; + isc_transaction_in_use = 335545003; + isc_pman_cannot_load_plugin = 335545004; + isc_pman_module_notfound = 335545005; + isc_pman_entrypoint_notfound = 335545006; + isc_pman_module_bad = 335545007; + isc_pman_plugin_notfound = 335545008; + isc_sysf_invalid_trig_namespace = 335545009; + isc_unexpected_null = 335545010; + isc_type_notcompat_blob = 335545011; + isc_invalid_date_val = 335545012; + isc_invalid_time_val = 335545013; + isc_invalid_timestamp_val = 335545014; + isc_invalid_index_val = 335545015; + isc_formatted_exception = 335545016; + isc_async_active = 335545017; + isc_private_function = 335545018; + isc_private_procedure = 335545019; + isc_request_outdated = 335545020; + isc_bad_events_handle = 335545021; + isc_cannot_copy_stmt = 335545022; + isc_invalid_boolean_usage = 335545023; + isc_sysf_argscant_both_be_zero = 335545024; + isc_spb_no_id = 335545025; + isc_ee_blr_mismatch_null = 335545026; + isc_ee_blr_mismatch_length = 335545027; + isc_ss_out_of_bounds = 335545028; + isc_missing_data_structures = 335545029; + isc_protect_sys_tab = 335545030; + isc_libtommath_generic = 335545031; + isc_wroblrver2 = 335545032; + isc_trunc_limits = 335545033; + isc_info_access = 335545034; + isc_svc_no_stdin = 335545035; + isc_svc_start_failed = 335545036; + isc_svc_no_switches = 335545037; + isc_svc_bad_size = 335545038; + isc_no_crypt_plugin = 335545039; + isc_cp_name_too_long = 335545040; + isc_cp_process_active = 335545041; + isc_cp_already_crypted = 335545042; + isc_decrypt_error = 335545043; + isc_no_providers = 335545044; + isc_null_spb = 335545045; + isc_max_args_exceeded = 335545046; + isc_ee_blr_mismatch_names_count = 335545047; + isc_ee_blr_mismatch_name_not_found = 335545048; + isc_bad_result_set = 335545049; + isc_wrong_message_length = 335545050; + isc_no_output_format = 335545051; + isc_item_finish = 335545052; + isc_miss_config = 335545053; + isc_conf_line = 335545054; + isc_conf_include = 335545055; + isc_include_depth = 335545056; + isc_include_miss = 335545057; + isc_protect_ownership = 335545058; + isc_badvarnum = 335545059; + isc_sec_context = 335545060; + isc_multi_segment = 335545061; + isc_login_changed = 335545062; + isc_auth_handshake_limit = 335545063; + isc_wirecrypt_incompatible = 335545064; + isc_miss_wirecrypt = 335545065; + isc_wirecrypt_key = 335545066; + isc_wirecrypt_plugin = 335545067; + isc_secdb_name = 335545068; + isc_auth_data = 335545069; + isc_auth_datalength = 335545070; + isc_info_unprepared_stmt = 335545071; + isc_idx_key_value = 335545072; + isc_forupdate_virtualtbl = 335545073; + isc_forupdate_systbl = 335545074; + isc_forupdate_temptbl = 335545075; + isc_cant_modify_sysobj = 335545076; + isc_server_misconfigured = 335545077; + isc_alter_role = 335545078; + isc_map_already_exists = 335545079; + isc_map_not_exists = 335545080; + isc_map_load = 335545081; + isc_map_aster = 335545082; + isc_map_multi = 335545083; + isc_map_undefined = 335545084; + isc_baddpb_damaged_mode = 335545085; + isc_baddpb_buffers_range = 335545086; + isc_baddpb_temp_buffers = 335545087; + isc_map_nodb = 335545088; + isc_map_notable = 335545089; + isc_miss_trusted_role = 335545090; + isc_set_invalid_role = 335545091; + isc_cursor_not_positioned = 335545092; + isc_dup_attribute = 335545093; + isc_dyn_no_priv = 335545094; + isc_dsql_cant_grant_option = 335545095; + isc_read_conflict = 335545096; + isc_crdb_load = 335545097; + isc_crdb_nodb = 335545098; + isc_crdb_notable = 335545099; + isc_interface_version_too_old = 335545100; + isc_fun_param_mismatch = 335545101; + isc_savepoint_backout_err = 335545102; + isc_domain_primary_key_notnull = 335545103; + isc_invalid_attachment_charset = 335545104; + isc_map_down = 335545105; + isc_login_error = 335545106; + isc_already_opened = 335545107; + isc_bad_crypt_key = 335545108; + isc_encrypt_error = 335545109; + isc_gfix_db_name = 335740929; + isc_gfix_invalid_sw = 335740930; + isc_gfix_incmp_sw = 335740932; + isc_gfix_replay_req = 335740933; + isc_gfix_pgbuf_req = 335740934; + isc_gfix_val_req = 335740935; + isc_gfix_pval_req = 335740936; + isc_gfix_trn_req = 335740937; + isc_gfix_full_req = 335740940; + isc_gfix_usrname_req = 335740941; + isc_gfix_pass_req = 335740942; + isc_gfix_subs_name = 335740943; + isc_gfix_wal_req = 335740944; + isc_gfix_sec_req = 335740945; + isc_gfix_nval_req = 335740946; + isc_gfix_type_shut = 335740947; + isc_gfix_retry = 335740948; + isc_gfix_retry_db = 335740951; + isc_gfix_exceed_max = 335740991; + isc_gfix_corrupt_pool = 335740992; + isc_gfix_mem_exhausted = 335740993; + isc_gfix_bad_pool = 335740994; + isc_gfix_trn_not_valid = 335740995; + isc_gfix_unexp_eoi = 335741012; + isc_gfix_recon_fail = 335741018; + isc_gfix_trn_unknown = 335741036; + isc_gfix_mode_req = 335741038; + isc_gfix_pzval_req = 335741042; + isc_dsql_dbkey_from_non_table = 336003074; + isc_dsql_transitional_numeric = 336003075; + isc_dsql_dialect_warning_expr = 336003076; + isc_sql_db_dialect_dtype_unsupport = 336003077; + isc_sql_dialect_conflict_num = 336003079; + isc_dsql_warning_number_ambiguous = 336003080; + isc_dsql_warning_number_ambiguous1 = 336003081; + isc_dsql_warn_precision_ambiguous = 336003082; + isc_dsql_warn_precision_ambiguous1 = 336003083; + isc_dsql_warn_precision_ambiguous2 = 336003084; + isc_dsql_ambiguous_field_name = 336003085; + isc_dsql_udf_return_pos_err = 336003086; + isc_dsql_invalid_label = 336003087; + isc_dsql_datatypes_not_comparable = 336003088; + isc_dsql_cursor_invalid = 336003089; + isc_dsql_cursor_redefined = 336003090; + isc_dsql_cursor_not_found = 336003091; + isc_dsql_cursor_exists = 336003092; + isc_dsql_cursor_rel_ambiguous = 336003093; + isc_dsql_cursor_rel_not_found = 336003094; + isc_dsql_cursor_not_open = 336003095; + isc_dsql_type_not_supp_ext_tab = 336003096; + isc_dsql_feature_not_supported_ods = 336003097; + isc_primary_key_required = 336003098; + isc_upd_ins_doesnt_match_pk = 336003099; + isc_upd_ins_doesnt_match_matching = 336003100; + isc_upd_ins_with_complex_view = 336003101; + isc_dsql_incompatible_trigger_type = 336003102; + isc_dsql_db_trigger_type_cant_change = 336003103; + isc_dsql_record_version_table = 336003104; + isc_dsql_invalid_sqlda_version = 336003105; + isc_dsql_sqlvar_index = 336003106; + isc_dsql_no_sqlind = 336003107; + isc_dsql_no_sqldata = 336003108; + isc_dsql_no_input_sqlda = 336003109; + isc_dsql_no_output_sqlda = 336003110; + isc_dsql_wrong_param_num = 336003111; + isc_dyn_filter_not_found = 336068645; + isc_dyn_func_not_found = 336068649; + isc_dyn_index_not_found = 336068656; + isc_dyn_view_not_found = 336068662; + isc_dyn_domain_not_found = 336068697; + isc_dyn_cant_modify_auto_trig = 336068717; + isc_dyn_dup_table = 336068740; + isc_dyn_proc_not_found = 336068748; + isc_dyn_exception_not_found = 336068752; + isc_dyn_proc_param_not_found = 336068754; + isc_dyn_trig_not_found = 336068755; + isc_dyn_charset_not_found = 336068759; + isc_dyn_collation_not_found = 336068760; + isc_dyn_role_not_found = 336068763; + isc_dyn_name_longer = 336068767; + isc_dyn_column_does_not_exist = 336068784; + isc_dyn_role_does_not_exist = 336068796; + isc_dyn_no_grant_admin_opt = 336068797; + isc_dyn_user_not_role_member = 336068798; + isc_dyn_delete_role_failed = 336068799; + isc_dyn_grant_role_to_user = 336068800; + isc_dyn_inv_sql_role_name = 336068801; + isc_dyn_dup_sql_role = 336068802; + isc_dyn_kywd_spec_for_role = 336068803; + isc_dyn_roles_not_supported = 336068804; + isc_dyn_domain_name_exists = 336068812; + isc_dyn_field_name_exists = 336068813; + isc_dyn_dependency_exists = 336068814; + isc_dyn_dtype_invalid = 336068815; + isc_dyn_char_fld_too_small = 336068816; + isc_dyn_invalid_dtype_conversion = 336068817; + isc_dyn_dtype_conv_invalid = 336068818; + isc_dyn_zero_len_id = 336068820; + isc_dyn_gen_not_found = 336068822; + isc_max_coll_per_charset = 336068829; + isc_invalid_coll_attr = 336068830; + isc_dyn_wrong_gtt_scope = 336068840; + isc_dyn_coll_used_table = 336068843; + isc_dyn_coll_used_domain = 336068844; + isc_dyn_cannot_del_syscoll = 336068845; + isc_dyn_cannot_del_def_coll = 336068846; + isc_dyn_table_not_found = 336068849; + isc_dyn_coll_used_procedure = 336068851; + isc_dyn_scale_too_big = 336068852; + isc_dyn_precision_too_small = 336068853; + isc_dyn_miss_priv_warning = 336068855; + isc_dyn_ods_not_supp_feature = 336068856; + isc_dyn_cannot_addrem_computed = 336068857; + isc_dyn_no_empty_pw = 336068858; + isc_dyn_dup_index = 336068859; + isc_dyn_package_not_found = 336068864; + isc_dyn_schema_not_found = 336068865; + isc_dyn_cannot_mod_sysproc = 336068866; + isc_dyn_cannot_mod_systrig = 336068867; + isc_dyn_cannot_mod_sysfunc = 336068868; + isc_dyn_invalid_ddl_proc = 336068869; + isc_dyn_invalid_ddl_trig = 336068870; + isc_dyn_funcnotdef_package = 336068871; + isc_dyn_procnotdef_package = 336068872; + isc_dyn_funcsignat_package = 336068873; + isc_dyn_procsignat_package = 336068874; + isc_dyn_defvaldecl_package_proc = 336068875; + isc_dyn_package_body_exists = 336068877; + isc_dyn_invalid_ddl_func = 336068878; + isc_dyn_newfc_oldsyntax = 336068879; + isc_dyn_func_param_not_found = 336068886; + isc_dyn_routine_param_not_found = 336068887; + isc_dyn_routine_param_ambiguous = 336068888; + isc_dyn_coll_used_function = 336068889; + isc_dyn_domain_used_function = 336068890; + isc_dyn_alter_user_no_clause = 336068891; + isc_dyn_duplicate_package_item = 336068894; + isc_dyn_cant_modify_sysobj = 336068895; + isc_dyn_cant_use_zero_increment = 336068896; + isc_dyn_cant_use_in_foreignkey = 336068897; + isc_dyn_defvaldecl_package_func = 336068898; + isc_gbak_unknown_switch = 336330753; + isc_gbak_page_size_missing = 336330754; + isc_gbak_page_size_toobig = 336330755; + isc_gbak_redir_ouput_missing = 336330756; + isc_gbak_switches_conflict = 336330757; + isc_gbak_unknown_device = 336330758; + isc_gbak_no_protection = 336330759; + isc_gbak_page_size_not_allowed = 336330760; + isc_gbak_multi_source_dest = 336330761; + isc_gbak_filename_missing = 336330762; + isc_gbak_dup_inout_names = 336330763; + isc_gbak_inv_page_size = 336330764; + isc_gbak_db_specified = 336330765; + isc_gbak_db_exists = 336330766; + isc_gbak_unk_device = 336330767; + isc_gbak_blob_info_failed = 336330772; + isc_gbak_unk_blob_item = 336330773; + isc_gbak_get_seg_failed = 336330774; + isc_gbak_close_blob_failed = 336330775; + isc_gbak_open_blob_failed = 336330776; + isc_gbak_put_blr_gen_id_failed = 336330777; + isc_gbak_unk_type = 336330778; + isc_gbak_comp_req_failed = 336330779; + isc_gbak_start_req_failed = 336330780; + isc_gbak_rec_failed = 336330781; + isc_gbak_rel_req_failed = 336330782; + isc_gbak_db_info_failed = 336330783; + isc_gbak_no_db_desc = 336330784; + isc_gbak_db_create_failed = 336330785; + isc_gbak_decomp_len_error = 336330786; + isc_gbak_tbl_missing = 336330787; + isc_gbak_blob_col_missing = 336330788; + isc_gbak_create_blob_failed = 336330789; + isc_gbak_put_seg_failed = 336330790; + isc_gbak_rec_len_exp = 336330791; + isc_gbak_inv_rec_len = 336330792; + isc_gbak_exp_data_type = 336330793; + isc_gbak_gen_id_failed = 336330794; + isc_gbak_unk_rec_type = 336330795; + isc_gbak_inv_bkup_ver = 336330796; + isc_gbak_missing_bkup_desc = 336330797; + isc_gbak_string_trunc = 336330798; + isc_gbak_cant_rest_record = 336330799; + isc_gbak_send_failed = 336330800; + isc_gbak_no_tbl_name = 336330801; + isc_gbak_unexp_eof = 336330802; + isc_gbak_db_format_too_old = 336330803; + isc_gbak_inv_array_dim = 336330804; + isc_gbak_xdr_len_expected = 336330807; + isc_gbak_open_bkup_error = 336330817; + isc_gbak_open_error = 336330818; + isc_gbak_missing_block_fac = 336330934; + isc_gbak_inv_block_fac = 336330935; + isc_gbak_block_fac_specified = 336330936; + isc_gbak_missing_username = 336330940; + isc_gbak_missing_password = 336330941; + isc_gbak_missing_skipped_bytes = 336330952; + isc_gbak_inv_skipped_bytes = 336330953; + isc_gbak_err_restore_charset = 336330965; + isc_gbak_err_restore_collation = 336330967; + isc_gbak_read_error = 336330972; + isc_gbak_write_error = 336330973; + isc_gbak_db_in_use = 336330985; + isc_gbak_sysmemex = 336330990; + isc_gbak_restore_role_failed = 336331002; + isc_gbak_role_op_missing = 336331005; + isc_gbak_page_buffers_missing = 336331010; + isc_gbak_page_buffers_wrong_param = 336331011; + isc_gbak_page_buffers_restore = 336331012; + isc_gbak_inv_size = 336331014; + isc_gbak_file_outof_sequence = 336331015; + isc_gbak_join_file_missing = 336331016; + isc_gbak_stdin_not_supptd = 336331017; + isc_gbak_stdout_not_supptd = 336331018; + isc_gbak_bkup_corrupt = 336331019; + isc_gbak_unk_db_file_spec = 336331020; + isc_gbak_hdr_write_failed = 336331021; + isc_gbak_disk_space_ex = 336331022; + isc_gbak_size_lt_min = 336331023; + isc_gbak_svc_name_missing = 336331025; + isc_gbak_not_ownr = 336331026; + isc_gbak_mode_req = 336331031; + isc_gbak_just_data = 336331033; + isc_gbak_data_only = 336331034; + isc_gbak_missing_interval = 336331078; + isc_gbak_wrong_interval = 336331079; + isc_gbak_verify_verbint = 336331081; + isc_gbak_option_only_restore = 336331082; + isc_gbak_option_only_backup = 336331083; + isc_gbak_option_conflict = 336331084; + isc_gbak_param_conflict = 336331085; + isc_gbak_option_repeated = 336331086; + isc_gbak_max_dbkey_recursion = 336331091; + isc_gbak_max_dbkey_length = 336331092; + isc_gbak_invalid_metadata = 336331093; + isc_gbak_invalid_data = 336331094; + isc_gbak_inv_bkup_ver2 = 336331096; + isc_gbak_db_format_too_old2 = 336331100; + isc_dsql_too_old_ods = 336397205; + isc_dsql_table_not_found = 336397206; + isc_dsql_view_not_found = 336397207; + isc_dsql_line_col_error = 336397208; + isc_dsql_unknown_pos = 336397209; + isc_dsql_no_dup_name = 336397210; + isc_dsql_too_many_values = 336397211; + isc_dsql_no_array_computed = 336397212; + isc_dsql_implicit_domain_name = 336397213; + isc_dsql_only_can_subscript_array = 336397214; + isc_dsql_max_sort_items = 336397215; + isc_dsql_max_group_items = 336397216; + isc_dsql_conflicting_sort_field = 336397217; + isc_dsql_derived_table_more_columns = 336397218; + isc_dsql_derived_table_less_columns = 336397219; + isc_dsql_derived_field_unnamed = 336397220; + isc_dsql_derived_field_dup_name = 336397221; + isc_dsql_derived_alias_select = 336397222; + isc_dsql_derived_alias_field = 336397223; + isc_dsql_auto_field_bad_pos = 336397224; + isc_dsql_cte_wrong_reference = 336397225; + isc_dsql_cte_cycle = 336397226; + isc_dsql_cte_outer_join = 336397227; + isc_dsql_cte_mult_references = 336397228; + isc_dsql_cte_not_a_union = 336397229; + isc_dsql_cte_nonrecurs_after_recurs = 336397230; + isc_dsql_cte_wrong_clause = 336397231; + isc_dsql_cte_union_all = 336397232; + isc_dsql_cte_miss_nonrecursive = 336397233; + isc_dsql_cte_nested_with = 336397234; + isc_dsql_col_more_than_once_using = 336397235; + isc_dsql_unsupp_feature_dialect = 336397236; + isc_dsql_cte_not_used = 336397237; + isc_dsql_col_more_than_once_view = 336397238; + isc_dsql_unsupported_in_auto_trans = 336397239; + isc_dsql_eval_unknode = 336397240; + isc_dsql_agg_wrongarg = 336397241; + isc_dsql_agg2_wrongarg = 336397242; + isc_dsql_nodateortime_pm_string = 336397243; + isc_dsql_invalid_datetime_subtract = 336397244; + isc_dsql_invalid_dateortime_add = 336397245; + isc_dsql_invalid_type_minus_date = 336397246; + isc_dsql_nostring_addsub_dial3 = 336397247; + isc_dsql_invalid_type_addsub_dial3 = 336397248; + isc_dsql_invalid_type_multip_dial1 = 336397249; + isc_dsql_nostring_multip_dial3 = 336397250; + isc_dsql_invalid_type_multip_dial3 = 336397251; + isc_dsql_mustuse_numeric_div_dial1 = 336397252; + isc_dsql_nostring_div_dial3 = 336397253; + isc_dsql_invalid_type_div_dial3 = 336397254; + isc_dsql_nostring_neg_dial3 = 336397255; + isc_dsql_invalid_type_neg = 336397256; + isc_dsql_max_distinct_items = 336397257; + isc_dsql_alter_charset_failed = 336397258; + isc_dsql_comment_on_failed = 336397259; + isc_dsql_create_func_failed = 336397260; + isc_dsql_alter_func_failed = 336397261; + isc_dsql_create_alter_func_failed = 336397262; + isc_dsql_drop_func_failed = 336397263; + isc_dsql_recreate_func_failed = 336397264; + isc_dsql_create_proc_failed = 336397265; + isc_dsql_alter_proc_failed = 336397266; + isc_dsql_create_alter_proc_failed = 336397267; + isc_dsql_drop_proc_failed = 336397268; + isc_dsql_recreate_proc_failed = 336397269; + isc_dsql_create_trigger_failed = 336397270; + isc_dsql_alter_trigger_failed = 336397271; + isc_dsql_create_alter_trigger_failed = 336397272; + isc_dsql_drop_trigger_failed = 336397273; + isc_dsql_recreate_trigger_failed = 336397274; + isc_dsql_create_collation_failed = 336397275; + isc_dsql_drop_collation_failed = 336397276; + isc_dsql_create_domain_failed = 336397277; + isc_dsql_alter_domain_failed = 336397278; + isc_dsql_drop_domain_failed = 336397279; + isc_dsql_create_except_failed = 336397280; + isc_dsql_alter_except_failed = 336397281; + isc_dsql_create_alter_except_failed = 336397282; + isc_dsql_recreate_except_failed = 336397283; + isc_dsql_drop_except_failed = 336397284; + isc_dsql_create_sequence_failed = 336397285; + isc_dsql_create_table_failed = 336397286; + isc_dsql_alter_table_failed = 336397287; + isc_dsql_drop_table_failed = 336397288; + isc_dsql_recreate_table_failed = 336397289; + isc_dsql_create_pack_failed = 336397290; + isc_dsql_alter_pack_failed = 336397291; + isc_dsql_create_alter_pack_failed = 336397292; + isc_dsql_drop_pack_failed = 336397293; + isc_dsql_recreate_pack_failed = 336397294; + isc_dsql_create_pack_body_failed = 336397295; + isc_dsql_drop_pack_body_failed = 336397296; + isc_dsql_recreate_pack_body_failed = 336397297; + isc_dsql_create_view_failed = 336397298; + isc_dsql_alter_view_failed = 336397299; + isc_dsql_create_alter_view_failed = 336397300; + isc_dsql_recreate_view_failed = 336397301; + isc_dsql_drop_view_failed = 336397302; + isc_dsql_drop_sequence_failed = 336397303; + isc_dsql_recreate_sequence_failed = 336397304; + isc_dsql_drop_index_failed = 336397305; + isc_dsql_drop_filter_failed = 336397306; + isc_dsql_drop_shadow_failed = 336397307; + isc_dsql_drop_role_failed = 336397308; + isc_dsql_drop_user_failed = 336397309; + isc_dsql_create_role_failed = 336397310; + isc_dsql_alter_role_failed = 336397311; + isc_dsql_alter_index_failed = 336397312; + isc_dsql_alter_database_failed = 336397313; + isc_dsql_create_shadow_failed = 336397314; + isc_dsql_create_filter_failed = 336397315; + isc_dsql_create_index_failed = 336397316; + isc_dsql_create_user_failed = 336397317; + isc_dsql_alter_user_failed = 336397318; + isc_dsql_grant_failed = 336397319; + isc_dsql_revoke_failed = 336397320; + isc_dsql_cte_recursive_aggregate = 336397321; + isc_dsql_mapping_failed = 336397322; + isc_dsql_alter_sequence_failed = 336397323; + isc_dsql_create_generator_failed = 336397324; + isc_dsql_set_generator_failed = 336397325; + isc_dsql_wlock_simple = 336397326; + isc_dsql_firstskip_rows = 336397327; + isc_dsql_wlock_aggregates = 336397328; + isc_dsql_wlock_conflict = 336397329; + isc_dsql_max_exception_arguments = 336397330; + isc_dsql_string_byte_length = 336397331; + isc_dsql_string_char_length = 336397332; + isc_dsql_max_nesting = 336397333; + isc_gsec_cant_open_db = 336723983; + isc_gsec_switches_error = 336723984; + isc_gsec_no_op_spec = 336723985; + isc_gsec_no_usr_name = 336723986; + isc_gsec_err_add = 336723987; + isc_gsec_err_modify = 336723988; + isc_gsec_err_find_mod = 336723989; + isc_gsec_err_rec_not_found = 336723990; + isc_gsec_err_delete = 336723991; + isc_gsec_err_find_del = 336723992; + isc_gsec_err_find_disp = 336723996; + isc_gsec_inv_param = 336723997; + isc_gsec_op_specified = 336723998; + isc_gsec_pw_specified = 336723999; + isc_gsec_uid_specified = 336724000; + isc_gsec_gid_specified = 336724001; + isc_gsec_proj_specified = 336724002; + isc_gsec_org_specified = 336724003; + isc_gsec_fname_specified = 336724004; + isc_gsec_mname_specified = 336724005; + isc_gsec_lname_specified = 336724006; + isc_gsec_inv_switch = 336724008; + isc_gsec_amb_switch = 336724009; + isc_gsec_no_op_specified = 336724010; + isc_gsec_params_not_allowed = 336724011; + isc_gsec_incompat_switch = 336724012; + isc_gsec_inv_username = 336724044; + isc_gsec_inv_pw_length = 336724045; + isc_gsec_db_specified = 336724046; + isc_gsec_db_admin_specified = 336724047; + isc_gsec_db_admin_pw_specified = 336724048; + isc_gsec_sql_role_specified = 336724049; + isc_gstat_unknown_switch = 336920577; + isc_gstat_retry = 336920578; + isc_gstat_wrong_ods = 336920579; + isc_gstat_unexpected_eof = 336920580; + isc_gstat_open_err = 336920605; + isc_gstat_read_err = 336920606; + isc_gstat_sysmemex = 336920607; + isc_fbsvcmgr_bad_am = 336986113; + isc_fbsvcmgr_bad_wm = 336986114; + isc_fbsvcmgr_bad_rs = 336986115; + isc_fbsvcmgr_info_err = 336986116; + isc_fbsvcmgr_query_err = 336986117; + isc_fbsvcmgr_switch_unknown = 336986118; + isc_fbsvcmgr_bad_sm = 336986159; + isc_fbsvcmgr_fp_open = 336986160; + isc_fbsvcmgr_fp_read = 336986161; + isc_fbsvcmgr_fp_empty = 336986162; + isc_fbsvcmgr_bad_arg = 336986164; + isc_utl_trusted_switch = 337051649; + isc_nbackup_missing_param = 337117213; + isc_nbackup_allowed_switches = 337117214; + isc_nbackup_unknown_param = 337117215; + isc_nbackup_unknown_switch = 337117216; + isc_nbackup_nofetchpw_svc = 337117217; + isc_nbackup_pwfile_error = 337117218; + isc_nbackup_size_with_lock = 337117219; + isc_nbackup_no_switch = 337117220; + isc_nbackup_err_read = 337117223; + isc_nbackup_err_write = 337117224; + isc_nbackup_err_seek = 337117225; + isc_nbackup_err_opendb = 337117226; + isc_nbackup_err_fadvice = 337117227; + isc_nbackup_err_createdb = 337117228; + isc_nbackup_err_openbk = 337117229; + isc_nbackup_err_createbk = 337117230; + isc_nbackup_err_eofdb = 337117231; + isc_nbackup_fixup_wrongstate = 337117232; + isc_nbackup_err_db = 337117233; + isc_nbackup_userpw_toolong = 337117234; + isc_nbackup_lostrec_db = 337117235; + isc_nbackup_lostguid_db = 337117236; + isc_nbackup_err_eofhdrdb = 337117237; + isc_nbackup_db_notlock = 337117238; + isc_nbackup_lostguid_bk = 337117239; + isc_nbackup_page_changed = 337117240; + isc_nbackup_dbsize_inconsistent = 337117241; + isc_nbackup_failed_lzbk = 337117242; + isc_nbackup_err_eofhdrbk = 337117243; + isc_nbackup_invalid_incbk = 337117244; + isc_nbackup_unsupvers_incbk = 337117245; + isc_nbackup_invlevel_incbk = 337117246; + isc_nbackup_wrong_orderbk = 337117247; + isc_nbackup_err_eofbk = 337117248; + isc_nbackup_err_copy = 337117249; + isc_nbackup_err_eofhdr_restdb = 337117250; + isc_nbackup_lostguid_l0bk = 337117251; + isc_nbackup_switchd_parameter = 337117255; + isc_nbackup_user_stop = 337117257; + isc_nbackup_deco_parse = 337117259; + isc_trace_conflict_acts = 337182750; + isc_trace_act_notfound = 337182751; + isc_trace_switch_once = 337182752; + isc_trace_param_val_miss = 337182753; + isc_trace_param_invalid = 337182754; + isc_trace_switch_unknown = 337182755; + isc_trace_switch_svc_only = 337182756; + isc_trace_switch_user_only = 337182757; + isc_trace_switch_param_miss = 337182758; + isc_trace_param_act_notcompat = 337182759; + isc_trace_mandatory_switch_miss = 337182760; +implementation + +procedure IReferenceCounted.addRef(); +begin + ReferenceCountedVTable(vTable).addRef(Self); +end; + +function IReferenceCounted.release(): Integer; +begin + Result := ReferenceCountedVTable(vTable).release(Self); +end; + +procedure IDisposable.dispose(); +begin + DisposableVTable(vTable).dispose(Self); +end; + +procedure IStatus.init(); +begin + StatusVTable(vTable).init(Self); +end; + +function IStatus.getState(): Cardinal; +begin + Result := StatusVTable(vTable).getState(Self); +end; + +procedure IStatus.setErrors2(length: Cardinal; value: NativeIntPtr); +begin + StatusVTable(vTable).setErrors2(Self, length, value); +end; + +procedure IStatus.setWarnings2(length: Cardinal; value: NativeIntPtr); +begin + StatusVTable(vTable).setWarnings2(Self, length, value); +end; + +procedure IStatus.setErrors(value: NativeIntPtr); +begin + StatusVTable(vTable).setErrors(Self, value); +end; + +procedure IStatus.setWarnings(value: NativeIntPtr); +begin + StatusVTable(vTable).setWarnings(Self, value); +end; + +function IStatus.getErrors(): NativeIntPtr; +begin + Result := StatusVTable(vTable).getErrors(Self); +end; + +function IStatus.getWarnings(): NativeIntPtr; +begin + Result := StatusVTable(vTable).getWarnings(Self); +end; + +function IStatus.clone(): IStatus; +begin + Result := StatusVTable(vTable).clone(Self); +end; + +function IMaster.getStatus(): IStatus; +begin + Result := MasterVTable(vTable).getStatus(Self); +end; + +function IMaster.getDispatcher(): IProvider; +begin + Result := MasterVTable(vTable).getDispatcher(Self); +end; + +function IMaster.getPluginManager(): IPluginManager; +begin + Result := MasterVTable(vTable).getPluginManager(Self); +end; + +function IMaster.getTimerControl(): ITimerControl; +begin + Result := MasterVTable(vTable).getTimerControl(Self); +end; + +function IMaster.getDtc(): IDtc; +begin + Result := MasterVTable(vTable).getDtc(Self); +end; + +function IMaster.registerAttachment(provider: IProvider; attachment: IAttachment): IAttachment; +begin + Result := MasterVTable(vTable).registerAttachment(Self, provider, attachment); +end; + +function IMaster.registerTransaction(attachment: IAttachment; transaction: ITransaction): ITransaction; +begin + Result := MasterVTable(vTable).registerTransaction(Self, attachment, transaction); +end; + +function IMaster.getMetadataBuilder(status: IStatus; fieldCount: Cardinal): IMetadataBuilder; +begin + Result := MasterVTable(vTable).getMetadataBuilder(Self, status, fieldCount); +// FbException.checkException(status); +end; + +function IMaster.serverMode(mode: Integer): Integer; +begin + Result := MasterVTable(vTable).serverMode(Self, mode); +end; + +function IMaster.getUtilInterface(): IUtil; +begin + Result := MasterVTable(vTable).getUtilInterface(Self); +end; + +function IMaster.getConfigManager(): IConfigManager; +begin + Result := MasterVTable(vTable).getConfigManager(Self); +end; + +function IMaster.getProcessExiting(): Boolean; +begin + Result := MasterVTable(vTable).getProcessExiting(Self); +end; + +procedure IPluginBase.setOwner(r: IReferenceCounted); +begin + PluginBaseVTable(vTable).setOwner(Self, r); +end; + +function IPluginBase.getOwner(): IReferenceCounted; +begin + Result := PluginBaseVTable(vTable).getOwner(Self); +end; + +function IPluginSet.getName(): PAnsiChar; +begin + Result := PluginSetVTable(vTable).getName(Self); +end; + +function IPluginSet.getModuleName(): PAnsiChar; +begin + Result := PluginSetVTable(vTable).getModuleName(Self); +end; + +function IPluginSet.getPlugin(status: IStatus): IPluginBase; +begin + Result := PluginSetVTable(vTable).getPlugin(Self, status); +// FbException.checkException(status); +end; + +procedure IPluginSet.next(status: IStatus); +begin + PluginSetVTable(vTable).next(Self, status); +// FbException.checkException(status); +end; + +procedure IPluginSet.set_(status: IStatus; s: PAnsiChar); +begin + PluginSetVTable(vTable).set_(Self, status, s); +// FbException.checkException(status); +end; + +function IConfigEntry.getName(): PAnsiChar; +begin + Result := ConfigEntryVTable(vTable).getName(Self); +end; + +function IConfigEntry.getValue(): PAnsiChar; +begin + Result := ConfigEntryVTable(vTable).getValue(Self); +end; + +function IConfigEntry.getIntValue(): Int64; +begin + Result := ConfigEntryVTable(vTable).getIntValue(Self); +end; + +function IConfigEntry.getBoolValue(): Boolean; +begin + Result := ConfigEntryVTable(vTable).getBoolValue(Self); +end; + +function IConfigEntry.getSubConfig(status: IStatus): IConfig; +begin + Result := ConfigEntryVTable(vTable).getSubConfig(Self, status); +// FbException.checkException(status); +end; + +function IConfig.find(status: IStatus; name: PAnsiChar): IConfigEntry; +begin + Result := ConfigVTable(vTable).find(Self, status, name); +// FbException.checkException(status); +end; + +function IConfig.findValue(status: IStatus; name: PAnsiChar; value: PAnsiChar): IConfigEntry; +begin + Result := ConfigVTable(vTable).findValue(Self, status, name, value); +// FbException.checkException(status); +end; + +function IConfig.findPos(status: IStatus; name: PAnsiChar; pos: Cardinal): IConfigEntry; +begin + Result := ConfigVTable(vTable).findPos(Self, status, name, pos); +// FbException.checkException(status); +end; + +function IFirebirdConf.getKey(name: PAnsiChar): Cardinal; +begin + Result := FirebirdConfVTable(vTable).getKey(Self, name); +end; + +function IFirebirdConf.asInteger(key: Cardinal): Int64; +begin + Result := FirebirdConfVTable(vTable).asInteger(Self, key); +end; + +function IFirebirdConf.asString(key: Cardinal): PAnsiChar; +begin + Result := FirebirdConfVTable(vTable).asString(Self, key); +end; + +function IFirebirdConf.asBoolean(key: Cardinal): Boolean; +begin + Result := FirebirdConfVTable(vTable).asBoolean(Self, key); +end; + +function IPluginConfig.getConfigFileName(): PAnsiChar; +begin + Result := PluginConfigVTable(vTable).getConfigFileName(Self); +end; + +function IPluginConfig.getDefaultConfig(status: IStatus): IConfig; +begin + Result := PluginConfigVTable(vTable).getDefaultConfig(Self, status); +// FbException.checkException(status); +end; + +function IPluginConfig.getFirebirdConf(status: IStatus): IFirebirdConf; +begin + Result := PluginConfigVTable(vTable).getFirebirdConf(Self, status); +// FbException.checkException(status); +end; + +procedure IPluginConfig.setReleaseDelay(status: IStatus; microSeconds: QWord); +begin + PluginConfigVTable(vTable).setReleaseDelay(Self, status, microSeconds); +// FbException.checkException(status); +end; + +function IPluginFactory.createPlugin(status: IStatus; factoryParameter: IPluginConfig): IPluginBase; +begin + Result := PluginFactoryVTable(vTable).createPlugin(Self, status, factoryParameter); +// FbException.checkException(status); +end; + +procedure IPluginModule.doClean(); +begin + PluginModuleVTable(vTable).doClean(Self); +end; + +procedure IPluginManager.registerPluginFactory(pluginType: Cardinal; defaultName: PAnsiChar; factory: IPluginFactory); +begin + PluginManagerVTable(vTable).registerPluginFactory(Self, pluginType, defaultName, factory); +end; + +procedure IPluginManager.registerModule(cleanup: IPluginModule); +begin + PluginManagerVTable(vTable).registerModule(Self, cleanup); +end; + +procedure IPluginManager.unregisterModule(cleanup: IPluginModule); +begin + PluginManagerVTable(vTable).unregisterModule(Self, cleanup); +end; + +function IPluginManager.getPlugins(status: IStatus; pluginType: Cardinal; namesList: PAnsiChar; firebirdConf: IFirebirdConf): IPluginSet; +begin + Result := PluginManagerVTable(vTable).getPlugins(Self, status, pluginType, namesList, firebirdConf); +// FbException.checkException(status); +end; + +function IPluginManager.getConfig(status: IStatus; filename: PAnsiChar): IConfig; +begin + Result := PluginManagerVTable(vTable).getConfig(Self, status, filename); +// FbException.checkException(status); +end; + +procedure IPluginManager.releasePlugin(plugin: IPluginBase); +begin + PluginManagerVTable(vTable).releasePlugin(Self, plugin); +end; + +procedure ICryptKey.setSymmetric(status: IStatus; type_: PAnsiChar; keyLength: Cardinal; key: Pointer); +begin + CryptKeyVTable(vTable).setSymmetric(Self, status, type_, keyLength, key); +// FbException.checkException(status); +end; + +procedure ICryptKey.setAsymmetric(status: IStatus; type_: PAnsiChar; encryptKeyLength: Cardinal; encryptKey: Pointer; decryptKeyLength: Cardinal; decryptKey: Pointer); +begin + CryptKeyVTable(vTable).setAsymmetric(Self, status, type_, encryptKeyLength, encryptKey, decryptKeyLength, decryptKey); +// FbException.checkException(status); +end; + +function ICryptKey.getEncryptKey(length: CardinalPtr): Pointer; +begin + Result := CryptKeyVTable(vTable).getEncryptKey(Self, length); +end; + +function ICryptKey.getDecryptKey(length: CardinalPtr): Pointer; +begin + Result := CryptKeyVTable(vTable).getDecryptKey(Self, length); +end; + +function IConfigManager.getDirectory(code: Cardinal): PAnsiChar; +begin + Result := ConfigManagerVTable(vTable).getDirectory(Self, code); +end; + +function IConfigManager.getFirebirdConf(): IFirebirdConf; +begin + Result := ConfigManagerVTable(vTable).getFirebirdConf(Self); +end; + +function IConfigManager.getDatabaseConf(dbName: PAnsiChar): IFirebirdConf; +begin + Result := ConfigManagerVTable(vTable).getDatabaseConf(Self, dbName); +end; + +function IConfigManager.getPluginConfig(configuredPlugin: PAnsiChar): IConfig; +begin + Result := ConfigManagerVTable(vTable).getPluginConfig(Self, configuredPlugin); +end; + +function IConfigManager.getInstallDirectory(): PAnsiChar; +begin + Result := ConfigManagerVTable(vTable).getInstallDirectory(Self); +end; + +function IConfigManager.getRootDirectory(): PAnsiChar; +begin + Result := ConfigManagerVTable(vTable).getRootDirectory(Self); +end; + +procedure IEventCallback.eventCallbackFunction(length: Cardinal; events: BytePtr); +begin + EventCallbackVTable(vTable).eventCallbackFunction(Self, length, events); +end; + +procedure IBlob.getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + BlobVTable(vTable).getInfo(Self, status, itemsLength, items, bufferLength, buffer); +// FbException.checkException(status); +end; + +function IBlob.getSegment(status: IStatus; bufferLength: Cardinal; buffer: Pointer; segmentLength: CardinalPtr): Integer; +begin + Result := BlobVTable(vTable).getSegment(Self, status, bufferLength, buffer, segmentLength); +// FbException.checkException(status); +end; + +procedure IBlob.putSegment(status: IStatus; length: Cardinal; buffer: Pointer); +begin + BlobVTable(vTable).putSegment(Self, status, length, buffer); +// FbException.checkException(status); +end; + +procedure IBlob.cancel(status: IStatus); +begin + BlobVTable(vTable).cancel(Self, status); +// FbException.checkException(status); +end; + +procedure IBlob.close(status: IStatus); +begin + BlobVTable(vTable).close(Self, status); +// FbException.checkException(status); +end; + +function IBlob.seek(status: IStatus; mode: Integer; offset: Integer): Integer; +begin + Result := BlobVTable(vTable).seek(Self, status, mode, offset); +// FbException.checkException(status); +end; + +procedure ITransaction.getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + TransactionVTable(vTable).getInfo(Self, status, itemsLength, items, bufferLength, buffer); +// FbException.checkException(status); +end; + +procedure ITransaction.prepare(status: IStatus; msgLength: Cardinal; message: BytePtr); +begin + TransactionVTable(vTable).prepare(Self, status, msgLength, message); +// FbException.checkException(status); +end; + +procedure ITransaction.commit(status: IStatus); +begin + TransactionVTable(vTable).commit(Self, status); +// FbException.checkException(status); +end; + +procedure ITransaction.commitRetaining(status: IStatus); +begin + TransactionVTable(vTable).commitRetaining(Self, status); +// FbException.checkException(status); +end; + +procedure ITransaction.rollback(status: IStatus); +begin + TransactionVTable(vTable).rollback(Self, status); +// FbException.checkException(status); +end; + +procedure ITransaction.rollbackRetaining(status: IStatus); +begin + TransactionVTable(vTable).rollbackRetaining(Self, status); +// FbException.checkException(status); +end; + +procedure ITransaction.disconnect(status: IStatus); +begin + TransactionVTable(vTable).disconnect(Self, status); +// FbException.checkException(status); +end; + +function ITransaction.join(status: IStatus; transaction: ITransaction): ITransaction; +begin + Result := TransactionVTable(vTable).join(Self, status, transaction); +// FbException.checkException(status); +end; + +function ITransaction.validate(status: IStatus; attachment: IAttachment): ITransaction; +begin + Result := TransactionVTable(vTable).validate(Self, status, attachment); +// FbException.checkException(status); +end; + +function ITransaction.enterDtc(status: IStatus): ITransaction; +begin + Result := TransactionVTable(vTable).enterDtc(Self, status); +// FbException.checkException(status); +end; + +function IMessageMetadata.getCount(status: IStatus): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getCount(Self, status); +// FbException.checkException(status); +end; + +function IMessageMetadata.getField(status: IStatus; index: Cardinal): PAnsiChar; +begin + Result := MessageMetadataVTable(vTable).getField(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getRelation(status: IStatus; index: Cardinal): PAnsiChar; +begin + Result := MessageMetadataVTable(vTable).getRelation(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getOwner(status: IStatus; index: Cardinal): PAnsiChar; +begin + Result := MessageMetadataVTable(vTable).getOwner(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getAlias(status: IStatus; index: Cardinal): PAnsiChar; +begin + Result := MessageMetadataVTable(vTable).getAlias(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getType(status: IStatus; index: Cardinal): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getType(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.isNullable(status: IStatus; index: Cardinal): Boolean; +begin + Result := MessageMetadataVTable(vTable).isNullable(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getSubType(status: IStatus; index: Cardinal): Integer; +begin + Result := MessageMetadataVTable(vTable).getSubType(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getLength(status: IStatus; index: Cardinal): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getLength(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getScale(status: IStatus; index: Cardinal): Integer; +begin + Result := MessageMetadataVTable(vTable).getScale(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getCharSet(status: IStatus; index: Cardinal): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getCharSet(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getOffset(status: IStatus; index: Cardinal): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getOffset(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getNullOffset(status: IStatus; index: Cardinal): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getNullOffset(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getBuilder(status: IStatus): IMetadataBuilder; +begin + Result := MessageMetadataVTable(vTable).getBuilder(Self, status); +// FbException.checkException(status); +end; + +function IMessageMetadata.getMessageLength(status: IStatus): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getMessageLength(Self, status); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.setType(status: IStatus; index: Cardinal; type_: Cardinal); +begin + MetadataBuilderVTable(vTable).setType(Self, status, index, type_); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.setSubType(status: IStatus; index: Cardinal; subType: Integer); +begin + MetadataBuilderVTable(vTable).setSubType(Self, status, index, subType); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.setLength(status: IStatus; index: Cardinal; length: Cardinal); +begin + MetadataBuilderVTable(vTable).setLength(Self, status, index, length); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.setCharSet(status: IStatus; index: Cardinal; charSet: Cardinal); +begin + MetadataBuilderVTable(vTable).setCharSet(Self, status, index, charSet); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.setScale(status: IStatus; index: Cardinal; scale: Cardinal); +begin + MetadataBuilderVTable(vTable).setScale(Self, status, index, scale); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.truncate(status: IStatus; count: Cardinal); +begin + MetadataBuilderVTable(vTable).truncate(Self, status, count); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.moveNameToIndex(status: IStatus; name: PAnsiChar; index: Cardinal); +begin + MetadataBuilderVTable(vTable).moveNameToIndex(Self, status, name, index); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.remove(status: IStatus; index: Cardinal); +begin + MetadataBuilderVTable(vTable).remove(Self, status, index); +// FbException.checkException(status); +end; + +function IMetadataBuilder.addField(status: IStatus): Cardinal; +begin + Result := MetadataBuilderVTable(vTable).addField(Self, status); +// FbException.checkException(status); +end; + +function IMetadataBuilder.getMetadata(status: IStatus): IMessageMetadata; +begin + Result := MetadataBuilderVTable(vTable).getMetadata(Self, status); +// FbException.checkException(status); +end; + +function IResultSet.fetchNext(status: IStatus; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchNext(Self, status, message); +// FbException.checkException(status); +end; + +function IResultSet.fetchPrior(status: IStatus; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchPrior(Self, status, message); +// FbException.checkException(status); +end; + +function IResultSet.fetchFirst(status: IStatus; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchFirst(Self, status, message); +// FbException.checkException(status); +end; + +function IResultSet.fetchLast(status: IStatus; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchLast(Self, status, message); +// FbException.checkException(status); +end; + +function IResultSet.fetchAbsolute(status: IStatus; position: Integer; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchAbsolute(Self, status, position, message); +// FbException.checkException(status); +end; + +function IResultSet.fetchRelative(status: IStatus; offset: Integer; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchRelative(Self, status, offset, message); +// FbException.checkException(status); +end; + +function IResultSet.isEof(status: IStatus): Boolean; +begin + Result := ResultSetVTable(vTable).isEof(Self, status); +// FbException.checkException(status); +end; + +function IResultSet.isBof(status: IStatus): Boolean; +begin + Result := ResultSetVTable(vTable).isBof(Self, status); +// FbException.checkException(status); +end; + +function IResultSet.getMetadata(status: IStatus): IMessageMetadata; +begin + Result := ResultSetVTable(vTable).getMetadata(Self, status); +// FbException.checkException(status); +end; + +procedure IResultSet.close(status: IStatus); +begin + ResultSetVTable(vTable).close(Self, status); +// FbException.checkException(status); +end; + +procedure IResultSet.setDelayedOutputFormat(status: IStatus; format: IMessageMetadata); +begin + ResultSetVTable(vTable).setDelayedOutputFormat(Self, status, format); +// FbException.checkException(status); +end; + +procedure IStatement.getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + StatementVTable(vTable).getInfo(Self, status, itemsLength, items, bufferLength, buffer); +// FbException.checkException(status); +end; + +function IStatement.getType(status: IStatus): Cardinal; +begin + Result := StatementVTable(vTable).getType(Self, status); +// FbException.checkException(status); +end; + +function IStatement.getPlan(status: IStatus; detailed: Boolean): PAnsiChar; +begin + Result := StatementVTable(vTable).getPlan(Self, status, detailed); +// FbException.checkException(status); +end; + +function IStatement.getAffectedRecords(status: IStatus): QWord; +begin + Result := StatementVTable(vTable).getAffectedRecords(Self, status); +// FbException.checkException(status); +end; + +function IStatement.getInputMetadata(status: IStatus): IMessageMetadata; +begin + Result := StatementVTable(vTable).getInputMetadata(Self, status); +// FbException.checkException(status); +end; + +function IStatement.getOutputMetadata(status: IStatus): IMessageMetadata; +begin + Result := StatementVTable(vTable).getOutputMetadata(Self, status); +// FbException.checkException(status); +end; + +function IStatement.execute(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; +begin + Result := StatementVTable(vTable).execute(Self, status, transaction, inMetadata, inBuffer, outMetadata, outBuffer); +// FbException.checkException(status); +end; + +function IStatement.openCursor(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; flags: Cardinal): IResultSet; +begin + Result := StatementVTable(vTable).openCursor(Self, status, transaction, inMetadata, inBuffer, outMetadata, flags); +// FbException.checkException(status); +end; + +procedure IStatement.setCursorName(status: IStatus; name: PAnsiChar); +begin + StatementVTable(vTable).setCursorName(Self, status, name); +// FbException.checkException(status); +end; + +procedure IStatement.free(status: IStatus); +begin + StatementVTable(vTable).free(Self, status); +// FbException.checkException(status); +end; + +function IStatement.getFlags(status: IStatus): Cardinal; +begin + Result := StatementVTable(vTable).getFlags(Self, status); +// FbException.checkException(status); +end; + +procedure IRequest.receive(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); +begin + RequestVTable(vTable).receive(Self, status, level, msgType, length, message); +// FbException.checkException(status); +end; + +procedure IRequest.send(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); +begin + RequestVTable(vTable).send(Self, status, level, msgType, length, message); +// FbException.checkException(status); +end; + +procedure IRequest.getInfo(status: IStatus; level: Integer; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + RequestVTable(vTable).getInfo(Self, status, level, itemsLength, items, bufferLength, buffer); +// FbException.checkException(status); +end; + +procedure IRequest.start(status: IStatus; tra: ITransaction; level: Integer); +begin + RequestVTable(vTable).start(Self, status, tra, level); +// FbException.checkException(status); +end; + +procedure IRequest.startAndSend(status: IStatus; tra: ITransaction; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); +begin + RequestVTable(vTable).startAndSend(Self, status, tra, level, msgType, length, message); +// FbException.checkException(status); +end; + +procedure IRequest.unwind(status: IStatus; level: Integer); +begin + RequestVTable(vTable).unwind(Self, status, level); +// FbException.checkException(status); +end; + +procedure IRequest.free(status: IStatus); +begin + RequestVTable(vTable).free(Self, status); +// FbException.checkException(status); +end; + +procedure IEvents.cancel(status: IStatus); +begin + EventsVTable(vTable).cancel(Self, status); +// FbException.checkException(status); +end; + +procedure IAttachment.getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + AttachmentVTable(vTable).getInfo(Self, status, itemsLength, items, bufferLength, buffer); +// FbException.checkException(status); +end; + +function IAttachment.startTransaction(status: IStatus; tpbLength: Cardinal; tpb: BytePtr): ITransaction; +begin + Result := AttachmentVTable(vTable).startTransaction(Self, status, tpbLength, tpb); +// FbException.checkException(status); +end; + +function IAttachment.reconnectTransaction(status: IStatus; length: Cardinal; id: BytePtr): ITransaction; +begin + Result := AttachmentVTable(vTable).reconnectTransaction(Self, status, length, id); +// FbException.checkException(status); +end; + +function IAttachment.compileRequest(status: IStatus; blrLength: Cardinal; blr: BytePtr): IRequest; +begin + Result := AttachmentVTable(vTable).compileRequest(Self, status, blrLength, blr); +// FbException.checkException(status); +end; + +procedure IAttachment.transactRequest(status: IStatus; transaction: ITransaction; blrLength: Cardinal; blr: BytePtr; inMsgLength: Cardinal; inMsg: BytePtr; outMsgLength: Cardinal; outMsg: BytePtr); +begin + AttachmentVTable(vTable).transactRequest(Self, status, transaction, blrLength, blr, inMsgLength, inMsg, outMsgLength, outMsg); +// FbException.checkException(status); +end; + +function IAttachment.createBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; +begin + Result := AttachmentVTable(vTable).createBlob(Self, status, transaction, id, bpbLength, bpb); +// FbException.checkException(status); +end; + +function IAttachment.openBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; +begin + Result := AttachmentVTable(vTable).openBlob(Self, status, transaction, id, bpbLength, bpb); +// FbException.checkException(status); +end; + +function IAttachment.getSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr): Integer; +begin + Result := AttachmentVTable(vTable).getSlice(Self, status, transaction, id, sdlLength, sdl, paramLength, param, sliceLength, slice); +// FbException.checkException(status); +end; + +procedure IAttachment.putSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr); +begin + AttachmentVTable(vTable).putSlice(Self, status, transaction, id, sdlLength, sdl, paramLength, param, sliceLength, slice); +// FbException.checkException(status); +end; + +procedure IAttachment.executeDyn(status: IStatus; transaction: ITransaction; length: Cardinal; dyn: BytePtr); +begin + AttachmentVTable(vTable).executeDyn(Self, status, transaction, length, dyn); +// FbException.checkException(status); +end; + +function IAttachment.prepare(status: IStatus; tra: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; flags: Cardinal): IStatement; +begin + Result := AttachmentVTable(vTable).prepare(Self, status, tra, stmtLength, sqlStmt, dialect, flags); +// FbException.checkException(status); +end; + +function IAttachment.execute(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; +begin + Result := AttachmentVTable(vTable).execute(Self, status, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, outBuffer); +// FbException.checkException(status); +end; + +function IAttachment.openCursor(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; cursorName: PAnsiChar; cursorFlags: Cardinal): IResultSet; +begin + Result := AttachmentVTable(vTable).openCursor(Self, status, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, cursorName, cursorFlags); +// FbException.checkException(status); +end; + +function IAttachment.queEvents(status: IStatus; callback: IEventCallback; length: Cardinal; events: BytePtr): IEvents; +begin + Result := AttachmentVTable(vTable).queEvents(Self, status, callback, length, events); +// FbException.checkException(status); +end; + +procedure IAttachment.cancelOperation(status: IStatus; option: Integer); +begin + AttachmentVTable(vTable).cancelOperation(Self, status, option); +// FbException.checkException(status); +end; + +procedure IAttachment.ping(status: IStatus); +begin + AttachmentVTable(vTable).ping(Self, status); +// FbException.checkException(status); +end; + +procedure IAttachment.detach(status: IStatus); +begin + AttachmentVTable(vTable).detach(Self, status); +// FbException.checkException(status); +end; + +procedure IAttachment.dropDatabase(status: IStatus); +begin + AttachmentVTable(vTable).dropDatabase(Self, status); +// FbException.checkException(status); +end; + +procedure IService.detach(status: IStatus); +begin + ServiceVTable(vTable).detach(Self, status); +// FbException.checkException(status); +end; + +procedure IService.query(status: IStatus; sendLength: Cardinal; sendItems: BytePtr; receiveLength: Cardinal; receiveItems: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + ServiceVTable(vTable).query(Self, status, sendLength, sendItems, receiveLength, receiveItems, bufferLength, buffer); +// FbException.checkException(status); +end; + +procedure IService.start(status: IStatus; spbLength: Cardinal; spb: BytePtr); +begin + ServiceVTable(vTable).start(Self, status, spbLength, spb); +// FbException.checkException(status); +end; + +function IProvider.attachDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; +begin + Result := ProviderVTable(vTable).attachDatabase(Self, status, fileName, dpbLength, dpb); +// FbException.checkException(status); +end; + +function IProvider.createDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; +begin + Result := ProviderVTable(vTable).createDatabase(Self, status, fileName, dpbLength, dpb); +// FbException.checkException(status); +end; + +function IProvider.attachServiceManager(status: IStatus; service: PAnsiChar; spbLength: Cardinal; spb: BytePtr): IService; +begin + Result := ProviderVTable(vTable).attachServiceManager(Self, status, service, spbLength, spb); +// FbException.checkException(status); +end; + +procedure IProvider.shutdown(status: IStatus; timeout: Cardinal; reason: Integer); +begin + ProviderVTable(vTable).shutdown(Self, status, timeout, reason); +// FbException.checkException(status); +end; + +procedure IProvider.setDbCryptCallback(status: IStatus; cryptCallback: ICryptKeyCallback); +begin + ProviderVTable(vTable).setDbCryptCallback(Self, status, cryptCallback); +// FbException.checkException(status); +end; + +procedure IDtcStart.addAttachment(status: IStatus; att: IAttachment); +begin + DtcStartVTable(vTable).addAttachment(Self, status, att); +// FbException.checkException(status); +end; + +procedure IDtcStart.addWithTpb(status: IStatus; att: IAttachment; length: Cardinal; tpb: BytePtr); +begin + DtcStartVTable(vTable).addWithTpb(Self, status, att, length, tpb); +// FbException.checkException(status); +end; + +function IDtcStart.start(status: IStatus): ITransaction; +begin + Result := DtcStartVTable(vTable).start(Self, status); +// FbException.checkException(status); +end; + +function IDtc.join(status: IStatus; one: ITransaction; two: ITransaction): ITransaction; +begin + Result := DtcVTable(vTable).join(Self, status, one, two); +// FbException.checkException(status); +end; + +function IDtc.startBuilder(status: IStatus): IDtcStart; +begin + Result := DtcVTable(vTable).startBuilder(Self, status); +// FbException.checkException(status); +end; + +procedure IWriter.reset(); +begin + WriterVTable(vTable).reset(Self); +end; + +procedure IWriter.add(status: IStatus; name: PAnsiChar); +begin + WriterVTable(vTable).add(Self, status, name); +// FbException.checkException(status); +end; + +procedure IWriter.setType(status: IStatus; value: PAnsiChar); +begin + WriterVTable(vTable).setType(Self, status, value); +// FbException.checkException(status); +end; + +procedure IWriter.setDb(status: IStatus; value: PAnsiChar); +begin + WriterVTable(vTable).setDb(Self, status, value); +// FbException.checkException(status); +end; + +function IServerBlock.getLogin(): PAnsiChar; +begin + Result := ServerBlockVTable(vTable).getLogin(Self); +end; + +function IServerBlock.getData(length: CardinalPtr): BytePtr; +begin + Result := ServerBlockVTable(vTable).getData(Self, length); +end; + +procedure IServerBlock.putData(status: IStatus; length: Cardinal; data: Pointer); +begin + ServerBlockVTable(vTable).putData(Self, status, length, data); +// FbException.checkException(status); +end; + +function IServerBlock.newKey(status: IStatus): ICryptKey; +begin + Result := ServerBlockVTable(vTable).newKey(Self, status); +// FbException.checkException(status); +end; + +function IClientBlock.getLogin(): PAnsiChar; +begin + Result := ClientBlockVTable(vTable).getLogin(Self); +end; + +function IClientBlock.getPassword(): PAnsiChar; +begin + Result := ClientBlockVTable(vTable).getPassword(Self); +end; + +function IClientBlock.getData(length: CardinalPtr): BytePtr; +begin + Result := ClientBlockVTable(vTable).getData(Self, length); +end; + +procedure IClientBlock.putData(status: IStatus; length: Cardinal; data: Pointer); +begin + ClientBlockVTable(vTable).putData(Self, status, length, data); +// FbException.checkException(status); +end; + +function IClientBlock.newKey(status: IStatus): ICryptKey; +begin + Result := ClientBlockVTable(vTable).newKey(Self, status); +// FbException.checkException(status); +end; + +function IServer.authenticate(status: IStatus; sBlock: IServerBlock; writerInterface: IWriter): Integer; +begin + Result := ServerVTable(vTable).authenticate(Self, status, sBlock, writerInterface); +// FbException.checkException(status); +end; + +function IClient.authenticate(status: IStatus; cBlock: IClientBlock): Integer; +begin + Result := ClientVTable(vTable).authenticate(Self, status, cBlock); +// FbException.checkException(status); +end; + +function IUserField.entered(): Integer; +begin + Result := UserFieldVTable(vTable).entered(Self); +end; + +function IUserField.specified(): Integer; +begin + Result := UserFieldVTable(vTable).specified(Self); +end; + +procedure IUserField.setEntered(status: IStatus; newValue: Integer); +begin + UserFieldVTable(vTable).setEntered(Self, status, newValue); +// FbException.checkException(status); +end; + +function ICharUserField.get(): PAnsiChar; +begin + Result := CharUserFieldVTable(vTable).get(Self); +end; + +procedure ICharUserField.set_(status: IStatus; newValue: PAnsiChar); +begin + CharUserFieldVTable(vTable).set_(Self, status, newValue); +// FbException.checkException(status); +end; + +function IIntUserField.get(): Integer; +begin + Result := IntUserFieldVTable(vTable).get(Self); +end; + +procedure IIntUserField.set_(status: IStatus; newValue: Integer); +begin + IntUserFieldVTable(vTable).set_(Self, status, newValue); +// FbException.checkException(status); +end; + +function IUser.operation(): Cardinal; +begin + Result := UserVTable(vTable).operation(Self); +end; + +function IUser.userName(): ICharUserField; +begin + Result := UserVTable(vTable).userName(Self); +end; + +function IUser.password(): ICharUserField; +begin + Result := UserVTable(vTable).password(Self); +end; + +function IUser.firstName(): ICharUserField; +begin + Result := UserVTable(vTable).firstName(Self); +end; + +function IUser.lastName(): ICharUserField; +begin + Result := UserVTable(vTable).lastName(Self); +end; + +function IUser.middleName(): ICharUserField; +begin + Result := UserVTable(vTable).middleName(Self); +end; + +function IUser.comment(): ICharUserField; +begin + Result := UserVTable(vTable).comment(Self); +end; + +function IUser.attributes(): ICharUserField; +begin + Result := UserVTable(vTable).attributes(Self); +end; + +function IUser.active(): IIntUserField; +begin + Result := UserVTable(vTable).active(Self); +end; + +function IUser.admin(): IIntUserField; +begin + Result := UserVTable(vTable).admin(Self); +end; + +procedure IUser.clear(status: IStatus); +begin + UserVTable(vTable).clear(Self, status); +// FbException.checkException(status); +end; + +procedure IListUsers.list(status: IStatus; user: IUser); +begin + ListUsersVTable(vTable).list(Self, status, user); +// FbException.checkException(status); +end; + +function ILogonInfo.name(): PAnsiChar; +begin + Result := LogonInfoVTable(vTable).name(Self); +end; + +function ILogonInfo.role(): PAnsiChar; +begin + Result := LogonInfoVTable(vTable).role(Self); +end; + +function ILogonInfo.networkProtocol(): PAnsiChar; +begin + Result := LogonInfoVTable(vTable).networkProtocol(Self); +end; + +function ILogonInfo.remoteAddress(): PAnsiChar; +begin + Result := LogonInfoVTable(vTable).remoteAddress(Self); +end; + +function ILogonInfo.authBlock(length: CardinalPtr): BytePtr; +begin + Result := LogonInfoVTable(vTable).authBlock(Self, length); +end; + +procedure IManagement.start(status: IStatus; logonInfo: ILogonInfo); +begin + ManagementVTable(vTable).start(Self, status, logonInfo); +// FbException.checkException(status); +end; + +function IManagement.execute(status: IStatus; user: IUser; callback: IListUsers): Integer; +begin + Result := ManagementVTable(vTable).execute(Self, status, user, callback); +// FbException.checkException(status); +end; + +procedure IManagement.commit(status: IStatus); +begin + ManagementVTable(vTable).commit(Self, status); +// FbException.checkException(status); +end; + +procedure IManagement.rollback(status: IStatus); +begin + ManagementVTable(vTable).rollback(Self, status); +// FbException.checkException(status); +end; + +function IWireCryptPlugin.getKnownTypes(status: IStatus): PAnsiChar; +begin + Result := WireCryptPluginVTable(vTable).getKnownTypes(Self, status); +// FbException.checkException(status); +end; + +procedure IWireCryptPlugin.setKey(status: IStatus; key: ICryptKey); +begin + WireCryptPluginVTable(vTable).setKey(Self, status, key); +// FbException.checkException(status); +end; + +procedure IWireCryptPlugin.encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); +begin + WireCryptPluginVTable(vTable).encrypt(Self, status, length, from, to_); +// FbException.checkException(status); +end; + +procedure IWireCryptPlugin.decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); +begin + WireCryptPluginVTable(vTable).decrypt(Self, status, length, from, to_); +// FbException.checkException(status); +end; + +function ICryptKeyCallback.callback(dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; +begin + Result := CryptKeyCallbackVTable(vTable).callback(Self, dataLength, data, bufferLength, buffer); +end; + +function IKeyHolderPlugin.keyCallback(status: IStatus; callback: ICryptKeyCallback): Integer; +begin + Result := KeyHolderPluginVTable(vTable).keyCallback(Self, status, callback); +// FbException.checkException(status); +end; + +function IKeyHolderPlugin.keyHandle(status: IStatus; keyName: PAnsiChar): ICryptKeyCallback; +begin + Result := KeyHolderPluginVTable(vTable).keyHandle(Self, status, keyName); +// FbException.checkException(status); +end; + +procedure IDbCryptPlugin.setKey(status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); +begin + DbCryptPluginVTable(vTable).setKey(Self, status, length, sources, keyName); +// FbException.checkException(status); +end; + +procedure IDbCryptPlugin.encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); +begin + DbCryptPluginVTable(vTable).encrypt(Self, status, length, from, to_); +// FbException.checkException(status); +end; + +procedure IDbCryptPlugin.decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); +begin + DbCryptPluginVTable(vTable).decrypt(Self, status, length, from, to_); +// FbException.checkException(status); +end; + +function IExternalContext.getMaster(): IMaster; +begin + Result := ExternalContextVTable(vTable).getMaster(Self); +end; + +function IExternalContext.getEngine(status: IStatus): IExternalEngine; +begin + Result := ExternalContextVTable(vTable).getEngine(Self, status); +// FbException.checkException(status); +end; + +function IExternalContext.getAttachment(status: IStatus): IAttachment; +begin + Result := ExternalContextVTable(vTable).getAttachment(Self, status); +// FbException.checkException(status); +end; + +function IExternalContext.getTransaction(status: IStatus): ITransaction; +begin + Result := ExternalContextVTable(vTable).getTransaction(Self, status); +// FbException.checkException(status); +end; + +function IExternalContext.getUserName(): PAnsiChar; +begin + Result := ExternalContextVTable(vTable).getUserName(Self); +end; + +function IExternalContext.getDatabaseName(): PAnsiChar; +begin + Result := ExternalContextVTable(vTable).getDatabaseName(Self); +end; + +function IExternalContext.getClientCharSet(): PAnsiChar; +begin + Result := ExternalContextVTable(vTable).getClientCharSet(Self); +end; + +function IExternalContext.obtainInfoCode(): Integer; +begin + Result := ExternalContextVTable(vTable).obtainInfoCode(Self); +end; + +function IExternalContext.getInfo(code: Integer): Pointer; +begin + Result := ExternalContextVTable(vTable).getInfo(Self, code); +end; + +function IExternalContext.setInfo(code: Integer; value: Pointer): Pointer; +begin + Result := ExternalContextVTable(vTable).setInfo(Self, code, value); +end; + +function IExternalResultSet.fetch(status: IStatus): Boolean; +begin + Result := ExternalResultSetVTable(vTable).fetch(Self, status); +// FbException.checkException(status); +end; + +procedure IExternalFunction.getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); +begin + ExternalFunctionVTable(vTable).getCharSet(Self, status, context, name, nameSize); +// FbException.checkException(status); +end; + +procedure IExternalFunction.execute(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer); +begin + ExternalFunctionVTable(vTable).execute(Self, status, context, inMsg, outMsg); +// FbException.checkException(status); +end; + +procedure IExternalProcedure.getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); +begin + ExternalProcedureVTable(vTable).getCharSet(Self, status, context, name, nameSize); +// FbException.checkException(status); +end; + +function IExternalProcedure.open(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer): IExternalResultSet; +begin + Result := ExternalProcedureVTable(vTable).open(Self, status, context, inMsg, outMsg); +// FbException.checkException(status); +end; + +procedure IExternalTrigger.getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); +begin + ExternalTriggerVTable(vTable).getCharSet(Self, status, context, name, nameSize); +// FbException.checkException(status); +end; + +procedure IExternalTrigger.execute(status: IStatus; context: IExternalContext; action: Cardinal; oldMsg: Pointer; newMsg: Pointer); +begin + ExternalTriggerVTable(vTable).execute(Self, status, context, action, oldMsg, newMsg); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getPackage(status: IStatus): PAnsiChar; +begin + Result := RoutineMetadataVTable(vTable).getPackage(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getName(status: IStatus): PAnsiChar; +begin + Result := RoutineMetadataVTable(vTable).getName(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getEntryPoint(status: IStatus): PAnsiChar; +begin + Result := RoutineMetadataVTable(vTable).getEntryPoint(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getBody(status: IStatus): PAnsiChar; +begin + Result := RoutineMetadataVTable(vTable).getBody(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getInputMetadata(status: IStatus): IMessageMetadata; +begin + Result := RoutineMetadataVTable(vTable).getInputMetadata(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getOutputMetadata(status: IStatus): IMessageMetadata; +begin + Result := RoutineMetadataVTable(vTable).getOutputMetadata(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getTriggerMetadata(status: IStatus): IMessageMetadata; +begin + Result := RoutineMetadataVTable(vTable).getTriggerMetadata(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getTriggerTable(status: IStatus): PAnsiChar; +begin + Result := RoutineMetadataVTable(vTable).getTriggerTable(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getTriggerType(status: IStatus): Cardinal; +begin + Result := RoutineMetadataVTable(vTable).getTriggerType(Self, status); +// FbException.checkException(status); +end; + +procedure IExternalEngine.open(status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); +begin + ExternalEngineVTable(vTable).open(Self, status, context, charSet, charSetSize); +// FbException.checkException(status); +end; + +procedure IExternalEngine.openAttachment(status: IStatus; context: IExternalContext); +begin + ExternalEngineVTable(vTable).openAttachment(Self, status, context); +// FbException.checkException(status); +end; + +procedure IExternalEngine.closeAttachment(status: IStatus; context: IExternalContext); +begin + ExternalEngineVTable(vTable).closeAttachment(Self, status, context); +// FbException.checkException(status); +end; + +function IExternalEngine.makeFunction(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalFunction; +begin + Result := ExternalEngineVTable(vTable).makeFunction(Self, status, context, metadata, inBuilder, outBuilder); +// FbException.checkException(status); +end; + +function IExternalEngine.makeProcedure(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalProcedure; +begin + Result := ExternalEngineVTable(vTable).makeProcedure(Self, status, context, metadata, inBuilder, outBuilder); +// FbException.checkException(status); +end; + +function IExternalEngine.makeTrigger(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder): IExternalTrigger; +begin + Result := ExternalEngineVTable(vTable).makeTrigger(Self, status, context, metadata, fieldsBuilder); +// FbException.checkException(status); +end; + +procedure ITimer.handler(); +begin + TimerVTable(vTable).handler(Self); +end; + +procedure ITimerControl.start(status: IStatus; timer: ITimer; microSeconds: QWord); +begin + TimerControlVTable(vTable).start(Self, status, timer, microSeconds); +// FbException.checkException(status); +end; + +procedure ITimerControl.stop(status: IStatus; timer: ITimer); +begin + TimerControlVTable(vTable).stop(Self, status, timer); +// FbException.checkException(status); +end; + +procedure IVersionCallback.callback(status: IStatus; text: PAnsiChar); +begin + VersionCallbackVTable(vTable).callback(Self, status, text); +// FbException.checkException(status); +end; + +procedure IUtil.getFbVersion(status: IStatus; att: IAttachment; callback: IVersionCallback); +begin + UtilVTable(vTable).getFbVersion(Self, status, att, callback); +// FbException.checkException(status); +end; + +procedure IUtil.loadBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); +begin + UtilVTable(vTable).loadBlob(Self, status, blobId, att, tra, file_, txt); +// FbException.checkException(status); +end; + +procedure IUtil.dumpBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); +begin + UtilVTable(vTable).dumpBlob(Self, status, blobId, att, tra, file_, txt); +// FbException.checkException(status); +end; + +procedure IUtil.getPerfCounters(status: IStatus; att: IAttachment; countersSet: PAnsiChar; counters: Int64Ptr); +begin + UtilVTable(vTable).getPerfCounters(Self, status, att, countersSet, counters); +// FbException.checkException(status); +end; + +function IUtil.executeCreateDatabase(status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; stmtIsCreateDb: BooleanPtr): IAttachment; +begin + Result := UtilVTable(vTable).executeCreateDatabase(Self, status, stmtLength, creatDBstatement, dialect, stmtIsCreateDb); +// FbException.checkException(status); +end; + +procedure IUtil.decodeDate(date: ISC_DATE; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr); +begin + UtilVTable(vTable).decodeDate(Self, date, year, month, day); +end; + +procedure IUtil.decodeTime(time: ISC_TIME; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr); +begin + UtilVTable(vTable).decodeTime(Self, time, hours, minutes, seconds, fractions); +end; + +function IUtil.encodeDate(year: Cardinal; month: Cardinal; day: Cardinal): ISC_DATE; +begin + Result := UtilVTable(vTable).encodeDate(Self, year, month, day); +end; + +function IUtil.encodeTime(hours: Cardinal; minutes: Cardinal; seconds: Cardinal; fractions: Cardinal): ISC_TIME; +begin + Result := UtilVTable(vTable).encodeTime(Self, hours, minutes, seconds, fractions); +end; + +function IUtil.formatStatus(buffer: PAnsiChar; bufferSize: Cardinal; status: IStatus): Cardinal; +begin + Result := UtilVTable(vTable).formatStatus(Self, buffer, bufferSize, status); +end; + +function IUtil.getClientVersion(): Cardinal; +begin + Result := UtilVTable(vTable).getClientVersion(Self); +end; + +function IUtil.getXpbBuilder(status: IStatus; kind: Cardinal; buf: BytePtr; len: Cardinal): IXpbBuilder; +begin + Result := UtilVTable(vTable).getXpbBuilder(Self, status, kind, buf, len); +// FbException.checkException(status); +end; + +function IUtil.setOffsets(status: IStatus; metadata: IMessageMetadata; callback: IOffsetsCallback): Cardinal; +begin + Result := UtilVTable(vTable).setOffsets(Self, status, metadata, callback); +// FbException.checkException(status); +end; + +procedure IOffsetsCallback.setOffset(status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); +begin + OffsetsCallbackVTable(vTable).setOffset(Self, status, index, offset, nullOffset); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.clear(status: IStatus); +begin + XpbBuilderVTable(vTable).clear(Self, status); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.removeCurrent(status: IStatus); +begin + XpbBuilderVTable(vTable).removeCurrent(Self, status); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.insertInt(status: IStatus; tag: Byte; value: Integer); +begin + XpbBuilderVTable(vTable).insertInt(Self, status, tag, value); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.insertBigInt(status: IStatus; tag: Byte; value: Int64); +begin + XpbBuilderVTable(vTable).insertBigInt(Self, status, tag, value); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.insertBytes(status: IStatus; tag: Byte; bytes: Pointer; length: Cardinal); +begin + XpbBuilderVTable(vTable).insertBytes(Self, status, tag, bytes, length); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.insertString(status: IStatus; tag: Byte; str: PAnsiChar); +begin + XpbBuilderVTable(vTable).insertString(Self, status, tag, str); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.insertTag(status: IStatus; tag: Byte); +begin + XpbBuilderVTable(vTable).insertTag(Self, status, tag); +// FbException.checkException(status); +end; + +function IXpbBuilder.isEof(status: IStatus): Boolean; +begin + Result := XpbBuilderVTable(vTable).isEof(Self, status); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.moveNext(status: IStatus); +begin + XpbBuilderVTable(vTable).moveNext(Self, status); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.rewind(status: IStatus); +begin + XpbBuilderVTable(vTable).rewind(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.findFirst(status: IStatus; tag: Byte): Boolean; +begin + Result := XpbBuilderVTable(vTable).findFirst(Self, status, tag); +// FbException.checkException(status); +end; + +function IXpbBuilder.findNext(status: IStatus): Boolean; +begin + Result := XpbBuilderVTable(vTable).findNext(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getTag(status: IStatus): Byte; +begin + Result := XpbBuilderVTable(vTable).getTag(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getLength(status: IStatus): Cardinal; +begin + Result := XpbBuilderVTable(vTable).getLength(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getInt(status: IStatus): Integer; +begin + Result := XpbBuilderVTable(vTable).getInt(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getBigInt(status: IStatus): Int64; +begin + Result := XpbBuilderVTable(vTable).getBigInt(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getString(status: IStatus): PAnsiChar; +begin + Result := XpbBuilderVTable(vTable).getString(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getBytes(status: IStatus): BytePtr; +begin + Result := XpbBuilderVTable(vTable).getBytes(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getBufferLength(status: IStatus): Cardinal; +begin + Result := XpbBuilderVTable(vTable).getBufferLength(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getBuffer(status: IStatus): BytePtr; +begin + Result := XpbBuilderVTable(vTable).getBuffer(Self, status); +// FbException.checkException(status); +end; + +function ITraceConnection.getKind(): Cardinal; +begin + Result := TraceConnectionVTable(vTable).getKind(Self); +end; + +function ITraceConnection.getProcessID(): Integer; +begin + Result := TraceConnectionVTable(vTable).getProcessID(Self); +end; + +function ITraceConnection.getUserName(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getUserName(Self); +end; + +function ITraceConnection.getRoleName(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getRoleName(Self); +end; + +function ITraceConnection.getCharSet(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getCharSet(Self); +end; + +function ITraceConnection.getRemoteProtocol(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getRemoteProtocol(Self); +end; + +function ITraceConnection.getRemoteAddress(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getRemoteAddress(Self); +end; + +function ITraceConnection.getRemoteProcessID(): Integer; +begin + Result := TraceConnectionVTable(vTable).getRemoteProcessID(Self); +end; + +function ITraceConnection.getRemoteProcessName(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getRemoteProcessName(Self); +end; + +function ITraceDatabaseConnection.getConnectionID(): Int64; +begin + Result := TraceDatabaseConnectionVTable(vTable).getConnectionID(Self); +end; + +function ITraceDatabaseConnection.getDatabaseName(): PAnsiChar; +begin + Result := TraceDatabaseConnectionVTable(vTable).getDatabaseName(Self); +end; + +function ITraceTransaction.getTransactionID(): Int64; +begin + Result := TraceTransactionVTable(vTable).getTransactionID(Self); +end; + +function ITraceTransaction.getReadOnly(): Boolean; +begin + Result := TraceTransactionVTable(vTable).getReadOnly(Self); +end; + +function ITraceTransaction.getWait(): Integer; +begin + Result := TraceTransactionVTable(vTable).getWait(Self); +end; + +function ITraceTransaction.getIsolation(): Cardinal; +begin + Result := TraceTransactionVTable(vTable).getIsolation(Self); +end; + +function ITraceTransaction.getPerf(): PerformanceInfoPtr; +begin + Result := TraceTransactionVTable(vTable).getPerf(Self); +end; + +function ITraceParams.getCount(): Cardinal; +begin + Result := TraceParamsVTable(vTable).getCount(Self); +end; + +function ITraceParams.getParam(idx: Cardinal): dscPtr; +begin + Result := TraceParamsVTable(vTable).getParam(Self, idx); +end; + +function ITraceStatement.getStmtID(): Int64; +begin + Result := TraceStatementVTable(vTable).getStmtID(Self); +end; + +function ITraceStatement.getPerf(): PerformanceInfoPtr; +begin + Result := TraceStatementVTable(vTable).getPerf(Self); +end; + +function ITraceSQLStatement.getText(): PAnsiChar; +begin + Result := TraceSQLStatementVTable(vTable).getText(Self); +end; + +function ITraceSQLStatement.getPlan(): PAnsiChar; +begin + Result := TraceSQLStatementVTable(vTable).getPlan(Self); +end; + +function ITraceSQLStatement.getInputs(): ITraceParams; +begin + Result := TraceSQLStatementVTable(vTable).getInputs(Self); +end; + +function ITraceSQLStatement.getTextUTF8(): PAnsiChar; +begin + Result := TraceSQLStatementVTable(vTable).getTextUTF8(Self); +end; + +function ITraceSQLStatement.getExplainedPlan(): PAnsiChar; +begin + Result := TraceSQLStatementVTable(vTable).getExplainedPlan(Self); +end; + +function ITraceBLRStatement.getData(): BytePtr; +begin + Result := TraceBLRStatementVTable(vTable).getData(Self); +end; + +function ITraceBLRStatement.getDataLength(): Cardinal; +begin + Result := TraceBLRStatementVTable(vTable).getDataLength(Self); +end; + +function ITraceBLRStatement.getText(): PAnsiChar; +begin + Result := TraceBLRStatementVTable(vTable).getText(Self); +end; + +function ITraceDYNRequest.getData(): BytePtr; +begin + Result := TraceDYNRequestVTable(vTable).getData(Self); +end; + +function ITraceDYNRequest.getDataLength(): Cardinal; +begin + Result := TraceDYNRequestVTable(vTable).getDataLength(Self); +end; + +function ITraceDYNRequest.getText(): PAnsiChar; +begin + Result := TraceDYNRequestVTable(vTable).getText(Self); +end; + +function ITraceContextVariable.getNameSpace(): PAnsiChar; +begin + Result := TraceContextVariableVTable(vTable).getNameSpace(Self); +end; + +function ITraceContextVariable.getVarName(): PAnsiChar; +begin + Result := TraceContextVariableVTable(vTable).getVarName(Self); +end; + +function ITraceContextVariable.getVarValue(): PAnsiChar; +begin + Result := TraceContextVariableVTable(vTable).getVarValue(Self); +end; + +function ITraceProcedure.getProcName(): PAnsiChar; +begin + Result := TraceProcedureVTable(vTable).getProcName(Self); +end; + +function ITraceProcedure.getInputs(): ITraceParams; +begin + Result := TraceProcedureVTable(vTable).getInputs(Self); +end; + +function ITraceProcedure.getPerf(): PerformanceInfoPtr; +begin + Result := TraceProcedureVTable(vTable).getPerf(Self); +end; + +function ITraceFunction.getFuncName(): PAnsiChar; +begin + Result := TraceFunctionVTable(vTable).getFuncName(Self); +end; + +function ITraceFunction.getInputs(): ITraceParams; +begin + Result := TraceFunctionVTable(vTable).getInputs(Self); +end; + +function ITraceFunction.getResult(): ITraceParams; +begin + Result := TraceFunctionVTable(vTable).getResult(Self); +end; + +function ITraceFunction.getPerf(): PerformanceInfoPtr; +begin + Result := TraceFunctionVTable(vTable).getPerf(Self); +end; + +function ITraceTrigger.getTriggerName(): PAnsiChar; +begin + Result := TraceTriggerVTable(vTable).getTriggerName(Self); +end; + +function ITraceTrigger.getRelationName(): PAnsiChar; +begin + Result := TraceTriggerVTable(vTable).getRelationName(Self); +end; + +function ITraceTrigger.getAction(): Integer; +begin + Result := TraceTriggerVTable(vTable).getAction(Self); +end; + +function ITraceTrigger.getWhich(): Integer; +begin + Result := TraceTriggerVTable(vTable).getWhich(Self); +end; + +function ITraceTrigger.getPerf(): PerformanceInfoPtr; +begin + Result := TraceTriggerVTable(vTable).getPerf(Self); +end; + +function ITraceServiceConnection.getServiceID(): Pointer; +begin + Result := TraceServiceConnectionVTable(vTable).getServiceID(Self); +end; + +function ITraceServiceConnection.getServiceMgr(): PAnsiChar; +begin + Result := TraceServiceConnectionVTable(vTable).getServiceMgr(Self); +end; + +function ITraceServiceConnection.getServiceName(): PAnsiChar; +begin + Result := TraceServiceConnectionVTable(vTable).getServiceName(Self); +end; + +function ITraceStatusVector.hasError(): Boolean; +begin + Result := TraceStatusVectorVTable(vTable).hasError(Self); +end; + +function ITraceStatusVector.hasWarning(): Boolean; +begin + Result := TraceStatusVectorVTable(vTable).hasWarning(Self); +end; + +function ITraceStatusVector.getStatus(): IStatus; +begin + Result := TraceStatusVectorVTable(vTable).getStatus(Self); +end; + +function ITraceStatusVector.getText(): PAnsiChar; +begin + Result := TraceStatusVectorVTable(vTable).getText(Self); +end; + +function ITraceSweepInfo.getOIT(): Int64; +begin + Result := TraceSweepInfoVTable(vTable).getOIT(Self); +end; + +function ITraceSweepInfo.getOST(): Int64; +begin + Result := TraceSweepInfoVTable(vTable).getOST(Self); +end; + +function ITraceSweepInfo.getOAT(): Int64; +begin + Result := TraceSweepInfoVTable(vTable).getOAT(Self); +end; + +function ITraceSweepInfo.getNext(): Int64; +begin + Result := TraceSweepInfoVTable(vTable).getNext(Self); +end; + +function ITraceSweepInfo.getPerf(): PerformanceInfoPtr; +begin + Result := TraceSweepInfoVTable(vTable).getPerf(Self); +end; + +function ITraceLogWriter.write(buf: Pointer; size: Cardinal): Cardinal; +begin + Result := TraceLogWriterVTable(vTable).write(Self, buf, size); +end; + +function ITraceInitInfo.getConfigText(): PAnsiChar; +begin + Result := TraceInitInfoVTable(vTable).getConfigText(Self); +end; + +function ITraceInitInfo.getTraceSessionID(): Integer; +begin + Result := TraceInitInfoVTable(vTable).getTraceSessionID(Self); +end; + +function ITraceInitInfo.getTraceSessionName(): PAnsiChar; +begin + Result := TraceInitInfoVTable(vTable).getTraceSessionName(Self); +end; + +function ITraceInitInfo.getFirebirdRootDirectory(): PAnsiChar; +begin + Result := TraceInitInfoVTable(vTable).getFirebirdRootDirectory(Self); +end; + +function ITraceInitInfo.getDatabaseName(): PAnsiChar; +begin + Result := TraceInitInfoVTable(vTable).getDatabaseName(Self); +end; + +function ITraceInitInfo.getConnection(): ITraceDatabaseConnection; +begin + Result := TraceInitInfoVTable(vTable).getConnection(Self); +end; + +function ITraceInitInfo.getLogWriter(): ITraceLogWriter; +begin + Result := TraceInitInfoVTable(vTable).getLogWriter(Self); +end; + +function ITracePlugin.trace_get_error(): PAnsiChar; +begin + Result := TracePluginVTable(vTable).trace_get_error(Self); +end; + +function ITracePlugin.trace_attach(connection: ITraceDatabaseConnection; create_db: Boolean; att_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_attach(Self, connection, create_db, att_result); +end; + +function ITracePlugin.trace_detach(connection: ITraceDatabaseConnection; drop_db: Boolean): Boolean; +begin + Result := TracePluginVTable(vTable).trace_detach(Self, connection, drop_db); +end; + +function ITracePlugin.trace_transaction_start(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; tpb_length: Cardinal; tpb: BytePtr; tra_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_transaction_start(Self, connection, transaction, tpb_length, tpb, tra_result); +end; + +function ITracePlugin.trace_transaction_end(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; commit: Boolean; retain_context: Boolean; tra_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_transaction_end(Self, connection, transaction, commit, retain_context, tra_result); +end; + +function ITracePlugin.trace_proc_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; procedure_: ITraceProcedure; started: Boolean; proc_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_proc_execute(Self, connection, transaction, procedure_, started, proc_result); +end; + +function ITracePlugin.trace_trigger_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; trigger: ITraceTrigger; started: Boolean; trig_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_trigger_execute(Self, connection, transaction, trigger, started, trig_result); +end; + +function ITracePlugin.trace_set_context(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; variable: ITraceContextVariable): Boolean; +begin + Result := TracePluginVTable(vTable).trace_set_context(Self, connection, transaction, variable); +end; + +function ITracePlugin.trace_dsql_prepare(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; time_millis: Int64; req_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_dsql_prepare(Self, connection, transaction, statement, time_millis, req_result); +end; + +function ITracePlugin.trace_dsql_free(connection: ITraceDatabaseConnection; statement: ITraceSQLStatement; option: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_dsql_free(Self, connection, statement, option); +end; + +function ITracePlugin.trace_dsql_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; started: Boolean; req_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_dsql_execute(Self, connection, transaction, statement, started, req_result); +end; + +function ITracePlugin.trace_blr_compile(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; time_millis: Int64; req_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_blr_compile(Self, connection, transaction, statement, time_millis, req_result); +end; + +function ITracePlugin.trace_blr_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; req_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_blr_execute(Self, connection, transaction, statement, req_result); +end; + +function ITracePlugin.trace_dyn_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; request: ITraceDYNRequest; time_millis: Int64; req_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_dyn_execute(Self, connection, transaction, request, time_millis, req_result); +end; + +function ITracePlugin.trace_service_attach(service: ITraceServiceConnection; att_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_service_attach(Self, service, att_result); +end; + +function ITracePlugin.trace_service_start(service: ITraceServiceConnection; switches_length: Cardinal; switches: PAnsiChar; start_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_service_start(Self, service, switches_length, switches, start_result); +end; + +function ITracePlugin.trace_service_query(service: ITraceServiceConnection; send_item_length: Cardinal; send_items: BytePtr; recv_item_length: Cardinal; recv_items: BytePtr; query_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_service_query(Self, service, send_item_length, send_items, recv_item_length, recv_items, query_result); +end; + +function ITracePlugin.trace_service_detach(service: ITraceServiceConnection; detach_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_service_detach(Self, service, detach_result); +end; + +function ITracePlugin.trace_event_error(connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; +begin + Result := TracePluginVTable(vTable).trace_event_error(Self, connection, status, function_); +end; + +function ITracePlugin.trace_event_sweep(connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_event_sweep(Self, connection, sweep, sweep_state); +end; + +function ITracePlugin.trace_func_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_func_execute(Self, connection, transaction, function_, started, func_result); +end; + +function ITraceFactory.trace_needs(): QWord; +begin + Result := TraceFactoryVTable(vTable).trace_needs(Self); +end; + +function ITraceFactory.trace_create(status: IStatus; init_info: ITraceInitInfo): ITracePlugin; +begin + Result := TraceFactoryVTable(vTable).trace_create(Self, status, init_info); +// FbException.checkException(status); +end; + +procedure IUdrFunctionFactory.setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); +begin + UdrFunctionFactoryVTable(vTable).setup(Self, status, context, metadata, inBuilder, outBuilder); +// FbException.checkException(status); +end; + +function IUdrFunctionFactory.newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalFunction; +begin + Result := UdrFunctionFactoryVTable(vTable).newItem(Self, status, context, metadata); +// FbException.checkException(status); +end; + +procedure IUdrProcedureFactory.setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); +begin + UdrProcedureFactoryVTable(vTable).setup(Self, status, context, metadata, inBuilder, outBuilder); +// FbException.checkException(status); +end; + +function IUdrProcedureFactory.newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalProcedure; +begin + Result := UdrProcedureFactoryVTable(vTable).newItem(Self, status, context, metadata); +// FbException.checkException(status); +end; + +procedure IUdrTriggerFactory.setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder); +begin + UdrTriggerFactoryVTable(vTable).setup(Self, status, context, metadata, fieldsBuilder); +// FbException.checkException(status); +end; + +function IUdrTriggerFactory.newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalTrigger; +begin + Result := UdrTriggerFactoryVTable(vTable).newItem(Self, status, context, metadata); +// FbException.checkException(status); +end; + +function IUdrPlugin.getMaster(): IMaster; +begin + Result := UdrPluginVTable(vTable).getMaster(Self); +end; + +procedure IUdrPlugin.registerFunction(status: IStatus; name: PAnsiChar; factory: IUdrFunctionFactory); +begin + UdrPluginVTable(vTable).registerFunction(Self, status, name, factory); +// FbException.checkException(status); +end; + +procedure IUdrPlugin.registerProcedure(status: IStatus; name: PAnsiChar; factory: IUdrProcedureFactory); +begin + UdrPluginVTable(vTable).registerProcedure(Self, status, name, factory); +// FbException.checkException(status); +end; + +procedure IUdrPlugin.registerTrigger(status: IStatus; name: PAnsiChar; factory: IUdrTriggerFactory); +begin + UdrPluginVTable(vTable).registerTrigger(Self, status, name, factory); +// FbException.checkException(status); +end; + +var + IVersionedImpl_vTable: VersionedVTable; + +constructor IVersionedImpl.create; +begin + vTable := IVersionedImpl_vTable; +end; + +procedure IReferenceCountedImpl_addRefDispatcher(this: IReferenceCounted); cdecl; +begin + //try + IReferenceCountedImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IReferenceCountedImpl_releaseDispatcher(this: IReferenceCounted): Integer; cdecl; +begin + //try + Result := IReferenceCountedImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IReferenceCountedImpl_vTable: ReferenceCountedVTable; + +constructor IReferenceCountedImpl.create; +begin + vTable := IReferenceCountedImpl_vTable; +end; + +procedure IDisposableImpl_disposeDispatcher(this: IDisposable); cdecl; +begin + //try + IDisposableImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IDisposableImpl_vTable: DisposableVTable; + +constructor IDisposableImpl.create; +begin + vTable := IDisposableImpl_vTable; +end; + +procedure IStatusImpl_disposeDispatcher(this: IStatus); cdecl; +begin + //try + IStatusImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatusImpl_initDispatcher(this: IStatus); cdecl; +begin + //try + IStatusImpl(this).init(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IStatusImpl_getStateDispatcher(this: IStatus): Cardinal; cdecl; +begin + //try + Result := IStatusImpl(this).getState(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatusImpl_setErrors2Dispatcher(this: IStatus; length: Cardinal; value: NativeIntPtr); cdecl; +begin + //try + IStatusImpl(this).setErrors2(length, value); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatusImpl_setWarnings2Dispatcher(this: IStatus; length: Cardinal; value: NativeIntPtr); cdecl; +begin + //try + IStatusImpl(this).setWarnings2(length, value); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatusImpl_setErrorsDispatcher(this: IStatus; value: NativeIntPtr); cdecl; +begin + //try + IStatusImpl(this).setErrors(value); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatusImpl_setWarningsDispatcher(this: IStatus; value: NativeIntPtr); cdecl; +begin + //try + IStatusImpl(this).setWarnings(value); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IStatusImpl_getErrorsDispatcher(this: IStatus): NativeIntPtr; cdecl; +begin + //try + Result := IStatusImpl(this).getErrors(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IStatusImpl_getWarningsDispatcher(this: IStatus): NativeIntPtr; cdecl; +begin + //try + Result := IStatusImpl(this).getWarnings(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IStatusImpl_cloneDispatcher(this: IStatus): IStatus; cdecl; +begin + //try + Result := IStatusImpl(this).clone(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IStatusImpl_vTable: StatusVTable; + +constructor IStatusImpl.create; +begin + vTable := IStatusImpl_vTable; +end; + +function IMasterImpl_getStatusDispatcher(this: IMaster): IStatus; cdecl; +begin + //try + Result := IMasterImpl(this).getStatus(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getDispatcherDispatcher(this: IMaster): IProvider; cdecl; +begin + //try + Result := IMasterImpl(this).getDispatcher(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getPluginManagerDispatcher(this: IMaster): IPluginManager; cdecl; +begin + //try + Result := IMasterImpl(this).getPluginManager(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getTimerControlDispatcher(this: IMaster): ITimerControl; cdecl; +begin + //try + Result := IMasterImpl(this).getTimerControl(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getDtcDispatcher(this: IMaster): IDtc; cdecl; +begin + //try + Result := IMasterImpl(this).getDtc(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_registerAttachmentDispatcher(this: IMaster; provider: IProvider; attachment: IAttachment): IAttachment; cdecl; +begin + //try + Result := IMasterImpl(this).registerAttachment(provider, attachment); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_registerTransactionDispatcher(this: IMaster; attachment: IAttachment; transaction: ITransaction): ITransaction; cdecl; +begin + //try + Result := IMasterImpl(this).registerTransaction(attachment, transaction); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getMetadataBuilderDispatcher(this: IMaster; status: IStatus; fieldCount: Cardinal): IMetadataBuilder; cdecl; +begin + //try + Result := IMasterImpl(this).getMetadataBuilder(status, fieldCount); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMasterImpl_serverModeDispatcher(this: IMaster; mode: Integer): Integer; cdecl; +begin + //try + Result := IMasterImpl(this).serverMode(mode); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getUtilInterfaceDispatcher(this: IMaster): IUtil; cdecl; +begin + //try + Result := IMasterImpl(this).getUtilInterface(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getConfigManagerDispatcher(this: IMaster): IConfigManager; cdecl; +begin + //try + Result := IMasterImpl(this).getConfigManager(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getProcessExitingDispatcher(this: IMaster): Boolean; cdecl; +begin + //try + Result := IMasterImpl(this).getProcessExiting(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IMasterImpl_vTable: MasterVTable; + +constructor IMasterImpl.create; +begin + vTable := IMasterImpl_vTable; +end; + +procedure IPluginBaseImpl_addRefDispatcher(this: IPluginBase); cdecl; +begin + //try + IPluginBaseImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginBaseImpl_releaseDispatcher(this: IPluginBase): Integer; cdecl; +begin + //try + Result := IPluginBaseImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IPluginBaseImpl_setOwnerDispatcher(this: IPluginBase; r: IReferenceCounted); cdecl; +begin + //try + IPluginBaseImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginBaseImpl_getOwnerDispatcher(this: IPluginBase): IReferenceCounted; cdecl; +begin + //try + Result := IPluginBaseImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IPluginBaseImpl_vTable: PluginBaseVTable; + +constructor IPluginBaseImpl.create; +begin + vTable := IPluginBaseImpl_vTable; +end; + +procedure IPluginSetImpl_addRefDispatcher(this: IPluginSet); cdecl; +begin + //try + IPluginSetImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginSetImpl_releaseDispatcher(this: IPluginSet): Integer; cdecl; +begin + //try + Result := IPluginSetImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginSetImpl_getNameDispatcher(this: IPluginSet): PAnsiChar; cdecl; +begin + //try + Result := IPluginSetImpl(this).getName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginSetImpl_getModuleNameDispatcher(this: IPluginSet): PAnsiChar; cdecl; +begin + //try + Result := IPluginSetImpl(this).getModuleName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginSetImpl_getPluginDispatcher(this: IPluginSet; status: IStatus): IPluginBase; cdecl; +begin + //try + Result := IPluginSetImpl(this).getPlugin(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IPluginSetImpl_nextDispatcher(this: IPluginSet; status: IStatus); cdecl; +begin + //try + IPluginSetImpl(this).next(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IPluginSetImpl_set_Dispatcher(this: IPluginSet; status: IStatus; s: PAnsiChar); cdecl; +begin + //try + IPluginSetImpl(this).set_(status, s); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IPluginSetImpl_vTable: PluginSetVTable; + +constructor IPluginSetImpl.create; +begin + vTable := IPluginSetImpl_vTable; +end; + +procedure IConfigEntryImpl_addRefDispatcher(this: IConfigEntry); cdecl; +begin + //try + IConfigEntryImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_releaseDispatcher(this: IConfigEntry): Integer; cdecl; +begin + //try + Result := IConfigEntryImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_getNameDispatcher(this: IConfigEntry): PAnsiChar; cdecl; +begin + //try + Result := IConfigEntryImpl(this).getName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_getValueDispatcher(this: IConfigEntry): PAnsiChar; cdecl; +begin + //try + Result := IConfigEntryImpl(this).getValue(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_getIntValueDispatcher(this: IConfigEntry): Int64; cdecl; +begin + //try + Result := IConfigEntryImpl(this).getIntValue(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_getBoolValueDispatcher(this: IConfigEntry): Boolean; cdecl; +begin + //try + Result := IConfigEntryImpl(this).getBoolValue(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_getSubConfigDispatcher(this: IConfigEntry; status: IStatus): IConfig; cdecl; +begin + //try + Result := IConfigEntryImpl(this).getSubConfig(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IConfigEntryImpl_vTable: ConfigEntryVTable; + +constructor IConfigEntryImpl.create; +begin + vTable := IConfigEntryImpl_vTable; +end; + +procedure IConfigImpl_addRefDispatcher(this: IConfig); cdecl; +begin + //try + IConfigImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigImpl_releaseDispatcher(this: IConfig): Integer; cdecl; +begin + //try + Result := IConfigImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigImpl_findDispatcher(this: IConfig; status: IStatus; name: PAnsiChar): IConfigEntry; cdecl; +begin + //try + Result := IConfigImpl(this).find(status, name); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IConfigImpl_findValueDispatcher(this: IConfig; status: IStatus; name: PAnsiChar; value: PAnsiChar): IConfigEntry; cdecl; +begin + //try + Result := IConfigImpl(this).findValue(status, name, value); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IConfigImpl_findPosDispatcher(this: IConfig; status: IStatus; name: PAnsiChar; pos: Cardinal): IConfigEntry; cdecl; +begin + //try + Result := IConfigImpl(this).findPos(status, name, pos); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IConfigImpl_vTable: ConfigVTable; + +constructor IConfigImpl.create; +begin + vTable := IConfigImpl_vTable; +end; + +procedure IFirebirdConfImpl_addRefDispatcher(this: IFirebirdConf); cdecl; +begin + //try + IFirebirdConfImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IFirebirdConfImpl_releaseDispatcher(this: IFirebirdConf): Integer; cdecl; +begin + //try + Result := IFirebirdConfImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IFirebirdConfImpl_getKeyDispatcher(this: IFirebirdConf; name: PAnsiChar): Cardinal; cdecl; +begin + //try + Result := IFirebirdConfImpl(this).getKey(name); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IFirebirdConfImpl_asIntegerDispatcher(this: IFirebirdConf; key: Cardinal): Int64; cdecl; +begin + //try + Result := IFirebirdConfImpl(this).asInteger(key); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IFirebirdConfImpl_asStringDispatcher(this: IFirebirdConf; key: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IFirebirdConfImpl(this).asString(key); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IFirebirdConfImpl_asBooleanDispatcher(this: IFirebirdConf; key: Cardinal): Boolean; cdecl; +begin + //try + Result := IFirebirdConfImpl(this).asBoolean(key); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IFirebirdConfImpl_vTable: FirebirdConfVTable; + +constructor IFirebirdConfImpl.create; +begin + vTable := IFirebirdConfImpl_vTable; +end; + +procedure IPluginConfigImpl_addRefDispatcher(this: IPluginConfig); cdecl; +begin + //try + IPluginConfigImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginConfigImpl_releaseDispatcher(this: IPluginConfig): Integer; cdecl; +begin + //try + Result := IPluginConfigImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginConfigImpl_getConfigFileNameDispatcher(this: IPluginConfig): PAnsiChar; cdecl; +begin + //try + Result := IPluginConfigImpl(this).getConfigFileName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginConfigImpl_getDefaultConfigDispatcher(this: IPluginConfig; status: IStatus): IConfig; cdecl; +begin + //try + Result := IPluginConfigImpl(this).getDefaultConfig(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IPluginConfigImpl_getFirebirdConfDispatcher(this: IPluginConfig; status: IStatus): IFirebirdConf; cdecl; +begin + //try + Result := IPluginConfigImpl(this).getFirebirdConf(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IPluginConfigImpl_setReleaseDelayDispatcher(this: IPluginConfig; status: IStatus; microSeconds: QWord); cdecl; +begin + //try + IPluginConfigImpl(this).setReleaseDelay(status, microSeconds); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IPluginConfigImpl_vTable: PluginConfigVTable; + +constructor IPluginConfigImpl.create; +begin + vTable := IPluginConfigImpl_vTable; +end; + +function IPluginFactoryImpl_createPluginDispatcher(this: IPluginFactory; status: IStatus; factoryParameter: IPluginConfig): IPluginBase; cdecl; +begin + //try + Result := IPluginFactoryImpl(this).createPlugin(status, factoryParameter); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IPluginFactoryImpl_vTable: PluginFactoryVTable; + +constructor IPluginFactoryImpl.create; +begin + vTable := IPluginFactoryImpl_vTable; +end; + +procedure IPluginModuleImpl_doCleanDispatcher(this: IPluginModule); cdecl; +begin + //try + IPluginModuleImpl(this).doClean(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IPluginModuleImpl_vTable: PluginModuleVTable; + +constructor IPluginModuleImpl.create; +begin + vTable := IPluginModuleImpl_vTable; +end; + +procedure IPluginManagerImpl_registerPluginFactoryDispatcher(this: IPluginManager; pluginType: Cardinal; defaultName: PAnsiChar; factory: IPluginFactory); cdecl; +begin + //try + IPluginManagerImpl(this).registerPluginFactory(pluginType, defaultName, factory); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IPluginManagerImpl_registerModuleDispatcher(this: IPluginManager; cleanup: IPluginModule); cdecl; +begin + //try + IPluginManagerImpl(this).registerModule(cleanup); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IPluginManagerImpl_unregisterModuleDispatcher(this: IPluginManager; cleanup: IPluginModule); cdecl; +begin + //try + IPluginManagerImpl(this).unregisterModule(cleanup); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginManagerImpl_getPluginsDispatcher(this: IPluginManager; status: IStatus; pluginType: Cardinal; namesList: PAnsiChar; firebirdConf: IFirebirdConf): IPluginSet; cdecl; +begin + //try + Result := IPluginManagerImpl(this).getPlugins(status, pluginType, namesList, firebirdConf); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IPluginManagerImpl_getConfigDispatcher(this: IPluginManager; status: IStatus; filename: PAnsiChar): IConfig; cdecl; +begin + //try + Result := IPluginManagerImpl(this).getConfig(status, filename); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IPluginManagerImpl_releasePluginDispatcher(this: IPluginManager; plugin: IPluginBase); cdecl; +begin + //try + IPluginManagerImpl(this).releasePlugin(plugin); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IPluginManagerImpl_vTable: PluginManagerVTable; + +constructor IPluginManagerImpl.create; +begin + vTable := IPluginManagerImpl_vTable; +end; + +procedure ICryptKeyImpl_setSymmetricDispatcher(this: ICryptKey; status: IStatus; type_: PAnsiChar; keyLength: Cardinal; key: Pointer); cdecl; +begin + //try + ICryptKeyImpl(this).setSymmetric(status, type_, keyLength, key); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ICryptKeyImpl_setAsymmetricDispatcher(this: ICryptKey; status: IStatus; type_: PAnsiChar; encryptKeyLength: Cardinal; encryptKey: Pointer; decryptKeyLength: Cardinal; decryptKey: Pointer); cdecl; +begin + //try + ICryptKeyImpl(this).setAsymmetric(status, type_, encryptKeyLength, encryptKey, decryptKeyLength, decryptKey); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function ICryptKeyImpl_getEncryptKeyDispatcher(this: ICryptKey; length: CardinalPtr): Pointer; cdecl; +begin + //try + Result := ICryptKeyImpl(this).getEncryptKey(length); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ICryptKeyImpl_getDecryptKeyDispatcher(this: ICryptKey; length: CardinalPtr): Pointer; cdecl; +begin + //try + Result := ICryptKeyImpl(this).getDecryptKey(length); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ICryptKeyImpl_vTable: CryptKeyVTable; + +constructor ICryptKeyImpl.create; +begin + vTable := ICryptKeyImpl_vTable; +end; + +function IConfigManagerImpl_getDirectoryDispatcher(this: IConfigManager; code: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getDirectory(code); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigManagerImpl_getFirebirdConfDispatcher(this: IConfigManager): IFirebirdConf; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getFirebirdConf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigManagerImpl_getDatabaseConfDispatcher(this: IConfigManager; dbName: PAnsiChar): IFirebirdConf; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getDatabaseConf(dbName); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigManagerImpl_getPluginConfigDispatcher(this: IConfigManager; configuredPlugin: PAnsiChar): IConfig; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getPluginConfig(configuredPlugin); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigManagerImpl_getInstallDirectoryDispatcher(this: IConfigManager): PAnsiChar; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getInstallDirectory(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigManagerImpl_getRootDirectoryDispatcher(this: IConfigManager): PAnsiChar; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getRootDirectory(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IConfigManagerImpl_vTable: ConfigManagerVTable; + +constructor IConfigManagerImpl.create; +begin + vTable := IConfigManagerImpl_vTable; +end; + +procedure IEventCallbackImpl_addRefDispatcher(this: IEventCallback); cdecl; +begin + //try + IEventCallbackImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IEventCallbackImpl_releaseDispatcher(this: IEventCallback): Integer; cdecl; +begin + //try + Result := IEventCallbackImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IEventCallbackImpl_eventCallbackFunctionDispatcher(this: IEventCallback; length: Cardinal; events: BytePtr); cdecl; +begin + //try + IEventCallbackImpl(this).eventCallbackFunction(length, events); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IEventCallbackImpl_vTable: EventCallbackVTable; + +constructor IEventCallbackImpl.create; +begin + vTable := IEventCallbackImpl_vTable; +end; + +procedure IBlobImpl_addRefDispatcher(this: IBlob); cdecl; +begin + //try + IBlobImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IBlobImpl_releaseDispatcher(this: IBlob): Integer; cdecl; +begin + //try + Result := IBlobImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IBlobImpl_getInfoDispatcher(this: IBlob; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + IBlobImpl(this).getInfo(status, itemsLength, items, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IBlobImpl_getSegmentDispatcher(this: IBlob; status: IStatus; bufferLength: Cardinal; buffer: Pointer; segmentLength: CardinalPtr): Integer; cdecl; +begin + //try + Result := IBlobImpl(this).getSegment(status, bufferLength, buffer, segmentLength); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IBlobImpl_putSegmentDispatcher(this: IBlob; status: IStatus; length: Cardinal; buffer: Pointer); cdecl; +begin + //try + IBlobImpl(this).putSegment(status, length, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IBlobImpl_cancelDispatcher(this: IBlob; status: IStatus); cdecl; +begin + //try + IBlobImpl(this).cancel(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IBlobImpl_closeDispatcher(this: IBlob; status: IStatus); cdecl; +begin + //try + IBlobImpl(this).close(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IBlobImpl_seekDispatcher(this: IBlob; status: IStatus; mode: Integer; offset: Integer): Integer; cdecl; +begin + //try + Result := IBlobImpl(this).seek(status, mode, offset); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IBlobImpl_vTable: BlobVTable; + +constructor IBlobImpl.create; +begin + vTable := IBlobImpl_vTable; +end; + +procedure ITransactionImpl_addRefDispatcher(this: ITransaction); cdecl; +begin + //try + ITransactionImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITransactionImpl_releaseDispatcher(this: ITransaction): Integer; cdecl; +begin + //try + Result := ITransactionImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure ITransactionImpl_getInfoDispatcher(this: ITransaction; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + ITransactionImpl(this).getInfo(status, itemsLength, items, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_prepareDispatcher(this: ITransaction; status: IStatus; msgLength: Cardinal; message: BytePtr); cdecl; +begin + //try + ITransactionImpl(this).prepare(status, msgLength, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_commitDispatcher(this: ITransaction; status: IStatus); cdecl; +begin + //try + ITransactionImpl(this).commit(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_commitRetainingDispatcher(this: ITransaction; status: IStatus); cdecl; +begin + //try + ITransactionImpl(this).commitRetaining(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_rollbackDispatcher(this: ITransaction; status: IStatus); cdecl; +begin + //try + ITransactionImpl(this).rollback(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_rollbackRetainingDispatcher(this: ITransaction; status: IStatus); cdecl; +begin + //try + ITransactionImpl(this).rollbackRetaining(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_disconnectDispatcher(this: ITransaction; status: IStatus); cdecl; +begin + //try + ITransactionImpl(this).disconnect(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function ITransactionImpl_joinDispatcher(this: ITransaction; status: IStatus; transaction: ITransaction): ITransaction; cdecl; +begin + //try + Result := ITransactionImpl(this).join(status, transaction); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function ITransactionImpl_validateDispatcher(this: ITransaction; status: IStatus; attachment: IAttachment): ITransaction; cdecl; +begin + //try + Result := ITransactionImpl(this).validate(status, attachment); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function ITransactionImpl_enterDtcDispatcher(this: ITransaction; status: IStatus): ITransaction; cdecl; +begin + //try + Result := ITransactionImpl(this).enterDtc(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + ITransactionImpl_vTable: TransactionVTable; + +constructor ITransactionImpl.create; +begin + vTable := ITransactionImpl_vTable; +end; + +procedure IMessageMetadataImpl_addRefDispatcher(this: IMessageMetadata); cdecl; +begin + //try + IMessageMetadataImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMessageMetadataImpl_releaseDispatcher(this: IMessageMetadata): Integer; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMessageMetadataImpl_getCountDispatcher(this: IMessageMetadata; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getCount(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getFieldDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getField(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getRelationDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getRelation(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getOwnerDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getOwner(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getAliasDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getAlias(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getTypeDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getType(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_isNullableDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Boolean; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).isNullable(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getSubTypeDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Integer; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getSubType(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getLengthDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getLength(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getScaleDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Integer; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getScale(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getCharSetDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getCharSet(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getOffsetDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getOffset(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getNullOffsetDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getNullOffset(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getBuilderDispatcher(this: IMessageMetadata; status: IStatus): IMetadataBuilder; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getBuilder(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getMessageLengthDispatcher(this: IMessageMetadata; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getMessageLength(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IMessageMetadataImpl_vTable: MessageMetadataVTable; + +constructor IMessageMetadataImpl.create; +begin + vTable := IMessageMetadataImpl_vTable; +end; + +procedure IMetadataBuilderImpl_addRefDispatcher(this: IMetadataBuilder); cdecl; +begin + //try + IMetadataBuilderImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMetadataBuilderImpl_releaseDispatcher(this: IMetadataBuilder): Integer; cdecl; +begin + //try + Result := IMetadataBuilderImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IMetadataBuilderImpl_setTypeDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal; type_: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).setType(status, index, type_); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_setSubTypeDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal; subType: Integer); cdecl; +begin + //try + IMetadataBuilderImpl(this).setSubType(status, index, subType); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_setLengthDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal; length: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).setLength(status, index, length); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_setCharSetDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal; charSet: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).setCharSet(status, index, charSet); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_setScaleDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal; scale: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).setScale(status, index, scale); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_truncateDispatcher(this: IMetadataBuilder; status: IStatus; count: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).truncate(status, count); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_moveNameToIndexDispatcher(this: IMetadataBuilder; status: IStatus; name: PAnsiChar; index: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).moveNameToIndex(status, name, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_removeDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).remove(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMetadataBuilderImpl_addFieldDispatcher(this: IMetadataBuilder; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IMetadataBuilderImpl(this).addField(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMetadataBuilderImpl_getMetadataDispatcher(this: IMetadataBuilder; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IMetadataBuilderImpl(this).getMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IMetadataBuilderImpl_vTable: MetadataBuilderVTable; + +constructor IMetadataBuilderImpl.create; +begin + vTable := IMetadataBuilderImpl_vTable; +end; + +procedure IResultSetImpl_addRefDispatcher(this: IResultSet); cdecl; +begin + //try + IResultSetImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IResultSetImpl_releaseDispatcher(this: IResultSet): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IResultSetImpl_fetchNextDispatcher(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchNext(status, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_fetchPriorDispatcher(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchPrior(status, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_fetchFirstDispatcher(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchFirst(status, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_fetchLastDispatcher(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchLast(status, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_fetchAbsoluteDispatcher(this: IResultSet; status: IStatus; position: Integer; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchAbsolute(status, position, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_fetchRelativeDispatcher(this: IResultSet; status: IStatus; offset: Integer; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchRelative(status, offset, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_isEofDispatcher(this: IResultSet; status: IStatus): Boolean; cdecl; +begin + //try + Result := IResultSetImpl(this).isEof(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_isBofDispatcher(this: IResultSet; status: IStatus): Boolean; cdecl; +begin + //try + Result := IResultSetImpl(this).isBof(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_getMetadataDispatcher(this: IResultSet; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IResultSetImpl(this).getMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IResultSetImpl_closeDispatcher(this: IResultSet; status: IStatus); cdecl; +begin + //try + IResultSetImpl(this).close(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IResultSetImpl_setDelayedOutputFormatDispatcher(this: IResultSet; status: IStatus; format: IMessageMetadata); cdecl; +begin + //try + IResultSetImpl(this).setDelayedOutputFormat(status, format); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IResultSetImpl_vTable: ResultSetVTable; + +constructor IResultSetImpl.create; +begin + vTable := IResultSetImpl_vTable; +end; + +procedure IStatementImpl_addRefDispatcher(this: IStatement); cdecl; +begin + //try + IStatementImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IStatementImpl_releaseDispatcher(this: IStatement): Integer; cdecl; +begin + //try + Result := IStatementImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatementImpl_getInfoDispatcher(this: IStatement; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + IStatementImpl(this).getInfo(status, itemsLength, items, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getTypeDispatcher(this: IStatement; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IStatementImpl(this).getType(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getPlanDispatcher(this: IStatement; status: IStatus; detailed: Boolean): PAnsiChar; cdecl; +begin + //try + Result := IStatementImpl(this).getPlan(status, detailed); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getAffectedRecordsDispatcher(this: IStatement; status: IStatus): QWord; cdecl; +begin + //try + Result := IStatementImpl(this).getAffectedRecords(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getInputMetadataDispatcher(this: IStatement; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IStatementImpl(this).getInputMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getOutputMetadataDispatcher(this: IStatement; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IStatementImpl(this).getOutputMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_executeDispatcher(this: IStatement; status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; cdecl; +begin + //try + Result := IStatementImpl(this).execute(status, transaction, inMetadata, inBuffer, outMetadata, outBuffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_openCursorDispatcher(this: IStatement; status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; flags: Cardinal): IResultSet; cdecl; +begin + //try + Result := IStatementImpl(this).openCursor(status, transaction, inMetadata, inBuffer, outMetadata, flags); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IStatementImpl_setCursorNameDispatcher(this: IStatement; status: IStatus; name: PAnsiChar); cdecl; +begin + //try + IStatementImpl(this).setCursorName(status, name); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IStatementImpl_freeDispatcher(this: IStatement; status: IStatus); cdecl; +begin + //try + IStatementImpl(this).free(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getFlagsDispatcher(this: IStatement; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IStatementImpl(this).getFlags(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IStatementImpl_vTable: StatementVTable; + +constructor IStatementImpl.create; +begin + vTable := IStatementImpl_vTable; +end; + +procedure IRequestImpl_addRefDispatcher(this: IRequest); cdecl; +begin + //try + IRequestImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IRequestImpl_releaseDispatcher(this: IRequest): Integer; cdecl; +begin + //try + Result := IRequestImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IRequestImpl_receiveDispatcher(this: IRequest; status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; +begin + //try + IRequestImpl(this).receive(status, level, msgType, length, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_sendDispatcher(this: IRequest; status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; +begin + //try + IRequestImpl(this).send(status, level, msgType, length, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_getInfoDispatcher(this: IRequest; status: IStatus; level: Integer; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + IRequestImpl(this).getInfo(status, level, itemsLength, items, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_startDispatcher(this: IRequest; status: IStatus; tra: ITransaction; level: Integer); cdecl; +begin + //try + IRequestImpl(this).start(status, tra, level); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_startAndSendDispatcher(this: IRequest; status: IStatus; tra: ITransaction; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; +begin + //try + IRequestImpl(this).startAndSend(status, tra, level, msgType, length, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_unwindDispatcher(this: IRequest; status: IStatus; level: Integer); cdecl; +begin + //try + IRequestImpl(this).unwind(status, level); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_freeDispatcher(this: IRequest; status: IStatus); cdecl; +begin + //try + IRequestImpl(this).free(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IRequestImpl_vTable: RequestVTable; + +constructor IRequestImpl.create; +begin + vTable := IRequestImpl_vTable; +end; + +procedure IEventsImpl_addRefDispatcher(this: IEvents); cdecl; +begin + //try + IEventsImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IEventsImpl_releaseDispatcher(this: IEvents): Integer; cdecl; +begin + //try + Result := IEventsImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IEventsImpl_cancelDispatcher(this: IEvents; status: IStatus); cdecl; +begin + //try + IEventsImpl(this).cancel(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IEventsImpl_vTable: EventsVTable; + +constructor IEventsImpl.create; +begin + vTable := IEventsImpl_vTable; +end; + +procedure IAttachmentImpl_addRefDispatcher(this: IAttachment); cdecl; +begin + //try + IAttachmentImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IAttachmentImpl_releaseDispatcher(this: IAttachment): Integer; cdecl; +begin + //try + Result := IAttachmentImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IAttachmentImpl_getInfoDispatcher(this: IAttachment; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + IAttachmentImpl(this).getInfo(status, itemsLength, items, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_startTransactionDispatcher(this: IAttachment; status: IStatus; tpbLength: Cardinal; tpb: BytePtr): ITransaction; cdecl; +begin + //try + Result := IAttachmentImpl(this).startTransaction(status, tpbLength, tpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_reconnectTransactionDispatcher(this: IAttachment; status: IStatus; length: Cardinal; id: BytePtr): ITransaction; cdecl; +begin + //try + Result := IAttachmentImpl(this).reconnectTransaction(status, length, id); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_compileRequestDispatcher(this: IAttachment; status: IStatus; blrLength: Cardinal; blr: BytePtr): IRequest; cdecl; +begin + //try + Result := IAttachmentImpl(this).compileRequest(status, blrLength, blr); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_transactRequestDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; blrLength: Cardinal; blr: BytePtr; inMsgLength: Cardinal; inMsg: BytePtr; outMsgLength: Cardinal; outMsg: BytePtr); cdecl; +begin + //try + IAttachmentImpl(this).transactRequest(status, transaction, blrLength, blr, inMsgLength, inMsg, outMsgLength, outMsg); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_createBlobDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; cdecl; +begin + //try + Result := IAttachmentImpl(this).createBlob(status, transaction, id, bpbLength, bpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_openBlobDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; cdecl; +begin + //try + Result := IAttachmentImpl(this).openBlob(status, transaction, id, bpbLength, bpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_getSliceDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr): Integer; cdecl; +begin + //try + Result := IAttachmentImpl(this).getSlice(status, transaction, id, sdlLength, sdl, paramLength, param, sliceLength, slice); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_putSliceDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr); cdecl; +begin + //try + IAttachmentImpl(this).putSlice(status, transaction, id, sdlLength, sdl, paramLength, param, sliceLength, slice); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_executeDynDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; length: Cardinal; dyn: BytePtr); cdecl; +begin + //try + IAttachmentImpl(this).executeDyn(status, transaction, length, dyn); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_prepareDispatcher(this: IAttachment; status: IStatus; tra: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; flags: Cardinal): IStatement; cdecl; +begin + //try + Result := IAttachmentImpl(this).prepare(status, tra, stmtLength, sqlStmt, dialect, flags); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_executeDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; cdecl; +begin + //try + Result := IAttachmentImpl(this).execute(status, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, outBuffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_openCursorDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; cursorName: PAnsiChar; cursorFlags: Cardinal): IResultSet; cdecl; +begin + //try + Result := IAttachmentImpl(this).openCursor(status, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, cursorName, cursorFlags); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_queEventsDispatcher(this: IAttachment; status: IStatus; callback: IEventCallback; length: Cardinal; events: BytePtr): IEvents; cdecl; +begin + //try + Result := IAttachmentImpl(this).queEvents(status, callback, length, events); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_cancelOperationDispatcher(this: IAttachment; status: IStatus; option: Integer); cdecl; +begin + //try + IAttachmentImpl(this).cancelOperation(status, option); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_pingDispatcher(this: IAttachment; status: IStatus); cdecl; +begin + //try + IAttachmentImpl(this).ping(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_detachDispatcher(this: IAttachment; status: IStatus); cdecl; +begin + //try + IAttachmentImpl(this).detach(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_dropDatabaseDispatcher(this: IAttachment; status: IStatus); cdecl; +begin + //try + IAttachmentImpl(this).dropDatabase(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IAttachmentImpl_vTable: AttachmentVTable; + +constructor IAttachmentImpl.create; +begin + vTable := IAttachmentImpl_vTable; +end; + +procedure IServiceImpl_addRefDispatcher(this: IService); cdecl; +begin + //try + IServiceImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IServiceImpl_releaseDispatcher(this: IService): Integer; cdecl; +begin + //try + Result := IServiceImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IServiceImpl_detachDispatcher(this: IService; status: IStatus); cdecl; +begin + //try + IServiceImpl(this).detach(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IServiceImpl_queryDispatcher(this: IService; status: IStatus; sendLength: Cardinal; sendItems: BytePtr; receiveLength: Cardinal; receiveItems: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + IServiceImpl(this).query(status, sendLength, sendItems, receiveLength, receiveItems, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IServiceImpl_startDispatcher(this: IService; status: IStatus; spbLength: Cardinal; spb: BytePtr); cdecl; +begin + //try + IServiceImpl(this).start(status, spbLength, spb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IServiceImpl_vTable: ServiceVTable; + +constructor IServiceImpl.create; +begin + vTable := IServiceImpl_vTable; +end; + +procedure IProviderImpl_addRefDispatcher(this: IProvider); cdecl; +begin + //try + IProviderImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IProviderImpl_releaseDispatcher(this: IProvider): Integer; cdecl; +begin + //try + Result := IProviderImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IProviderImpl_setOwnerDispatcher(this: IProvider; r: IReferenceCounted); cdecl; +begin + //try + IProviderImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IProviderImpl_getOwnerDispatcher(this: IProvider): IReferenceCounted; cdecl; +begin + //try + Result := IProviderImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IProviderImpl_attachDatabaseDispatcher(this: IProvider; status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; cdecl; +begin + //try + Result := IProviderImpl(this).attachDatabase(status, fileName, dpbLength, dpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IProviderImpl_createDatabaseDispatcher(this: IProvider; status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; cdecl; +begin + //try + Result := IProviderImpl(this).createDatabase(status, fileName, dpbLength, dpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IProviderImpl_attachServiceManagerDispatcher(this: IProvider; status: IStatus; service: PAnsiChar; spbLength: Cardinal; spb: BytePtr): IService; cdecl; +begin + //try + Result := IProviderImpl(this).attachServiceManager(status, service, spbLength, spb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IProviderImpl_shutdownDispatcher(this: IProvider; status: IStatus; timeout: Cardinal; reason: Integer); cdecl; +begin + //try + IProviderImpl(this).shutdown(status, timeout, reason); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IProviderImpl_setDbCryptCallbackDispatcher(this: IProvider; status: IStatus; cryptCallback: ICryptKeyCallback); cdecl; +begin + //try + IProviderImpl(this).setDbCryptCallback(status, cryptCallback); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IProviderImpl_vTable: ProviderVTable; + +constructor IProviderImpl.create; +begin + vTable := IProviderImpl_vTable; +end; + +procedure IDtcStartImpl_disposeDispatcher(this: IDtcStart); cdecl; +begin + //try + IDtcStartImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IDtcStartImpl_addAttachmentDispatcher(this: IDtcStart; status: IStatus; att: IAttachment); cdecl; +begin + //try + IDtcStartImpl(this).addAttachment(status, att); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IDtcStartImpl_addWithTpbDispatcher(this: IDtcStart; status: IStatus; att: IAttachment; length: Cardinal; tpb: BytePtr); cdecl; +begin + //try + IDtcStartImpl(this).addWithTpb(status, att, length, tpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IDtcStartImpl_startDispatcher(this: IDtcStart; status: IStatus): ITransaction; cdecl; +begin + //try + Result := IDtcStartImpl(this).start(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IDtcStartImpl_vTable: DtcStartVTable; + +constructor IDtcStartImpl.create; +begin + vTable := IDtcStartImpl_vTable; +end; + +function IDtcImpl_joinDispatcher(this: IDtc; status: IStatus; one: ITransaction; two: ITransaction): ITransaction; cdecl; +begin + //try + Result := IDtcImpl(this).join(status, one, two); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IDtcImpl_startBuilderDispatcher(this: IDtc; status: IStatus): IDtcStart; cdecl; +begin + //try + Result := IDtcImpl(this).startBuilder(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IDtcImpl_vTable: DtcVTable; + +constructor IDtcImpl.create; +begin + vTable := IDtcImpl_vTable; +end; + +procedure IAuthImpl_addRefDispatcher(this: IAuth); cdecl; +begin + //try + IAuthImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IAuthImpl_releaseDispatcher(this: IAuth): Integer; cdecl; +begin + //try + Result := IAuthImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IAuthImpl_setOwnerDispatcher(this: IAuth; r: IReferenceCounted); cdecl; +begin + //try + IAuthImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IAuthImpl_getOwnerDispatcher(this: IAuth): IReferenceCounted; cdecl; +begin + //try + Result := IAuthImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IAuthImpl_vTable: AuthVTable; + +constructor IAuthImpl.create; +begin + vTable := IAuthImpl_vTable; +end; + +procedure IWriterImpl_resetDispatcher(this: IWriter); cdecl; +begin + //try + IWriterImpl(this).reset(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IWriterImpl_addDispatcher(this: IWriter; status: IStatus; name: PAnsiChar); cdecl; +begin + //try + IWriterImpl(this).add(status, name); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IWriterImpl_setTypeDispatcher(this: IWriter; status: IStatus; value: PAnsiChar); cdecl; +begin + //try + IWriterImpl(this).setType(status, value); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IWriterImpl_setDbDispatcher(this: IWriter; status: IStatus; value: PAnsiChar); cdecl; +begin + //try + IWriterImpl(this).setDb(status, value); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IWriterImpl_vTable: WriterVTable; + +constructor IWriterImpl.create; +begin + vTable := IWriterImpl_vTable; +end; + +function IServerBlockImpl_getLoginDispatcher(this: IServerBlock): PAnsiChar; cdecl; +begin + //try + Result := IServerBlockImpl(this).getLogin(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IServerBlockImpl_getDataDispatcher(this: IServerBlock; length: CardinalPtr): BytePtr; cdecl; +begin + //try + Result := IServerBlockImpl(this).getData(length); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IServerBlockImpl_putDataDispatcher(this: IServerBlock; status: IStatus; length: Cardinal; data: Pointer); cdecl; +begin + //try + IServerBlockImpl(this).putData(status, length, data); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IServerBlockImpl_newKeyDispatcher(this: IServerBlock; status: IStatus): ICryptKey; cdecl; +begin + //try + Result := IServerBlockImpl(this).newKey(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IServerBlockImpl_vTable: ServerBlockVTable; + +constructor IServerBlockImpl.create; +begin + vTable := IServerBlockImpl_vTable; +end; + +procedure IClientBlockImpl_addRefDispatcher(this: IClientBlock); cdecl; +begin + //try + IClientBlockImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientBlockImpl_releaseDispatcher(this: IClientBlock): Integer; cdecl; +begin + //try + Result := IClientBlockImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientBlockImpl_getLoginDispatcher(this: IClientBlock): PAnsiChar; cdecl; +begin + //try + Result := IClientBlockImpl(this).getLogin(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientBlockImpl_getPasswordDispatcher(this: IClientBlock): PAnsiChar; cdecl; +begin + //try + Result := IClientBlockImpl(this).getPassword(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientBlockImpl_getDataDispatcher(this: IClientBlock; length: CardinalPtr): BytePtr; cdecl; +begin + //try + Result := IClientBlockImpl(this).getData(length); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IClientBlockImpl_putDataDispatcher(this: IClientBlock; status: IStatus; length: Cardinal; data: Pointer); cdecl; +begin + //try + IClientBlockImpl(this).putData(status, length, data); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IClientBlockImpl_newKeyDispatcher(this: IClientBlock; status: IStatus): ICryptKey; cdecl; +begin + //try + Result := IClientBlockImpl(this).newKey(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IClientBlockImpl_vTable: ClientBlockVTable; + +constructor IClientBlockImpl.create; +begin + vTable := IClientBlockImpl_vTable; +end; + +procedure IServerImpl_addRefDispatcher(this: IServer); cdecl; +begin + //try + IServerImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IServerImpl_releaseDispatcher(this: IServer): Integer; cdecl; +begin + //try + Result := IServerImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IServerImpl_setOwnerDispatcher(this: IServer; r: IReferenceCounted); cdecl; +begin + //try + IServerImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IServerImpl_getOwnerDispatcher(this: IServer): IReferenceCounted; cdecl; +begin + //try + Result := IServerImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IServerImpl_authenticateDispatcher(this: IServer; status: IStatus; sBlock: IServerBlock; writerInterface: IWriter): Integer; cdecl; +begin + //try + Result := IServerImpl(this).authenticate(status, sBlock, writerInterface); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IServerImpl_vTable: ServerVTable; + +constructor IServerImpl.create; +begin + vTable := IServerImpl_vTable; +end; + +procedure IClientImpl_addRefDispatcher(this: IClient); cdecl; +begin + //try + IClientImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientImpl_releaseDispatcher(this: IClient): Integer; cdecl; +begin + //try + Result := IClientImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IClientImpl_setOwnerDispatcher(this: IClient; r: IReferenceCounted); cdecl; +begin + //try + IClientImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientImpl_getOwnerDispatcher(this: IClient): IReferenceCounted; cdecl; +begin + //try + Result := IClientImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientImpl_authenticateDispatcher(this: IClient; status: IStatus; cBlock: IClientBlock): Integer; cdecl; +begin + //try + Result := IClientImpl(this).authenticate(status, cBlock); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IClientImpl_vTable: ClientVTable; + +constructor IClientImpl.create; +begin + vTable := IClientImpl_vTable; +end; + +function IUserFieldImpl_enteredDispatcher(this: IUserField): Integer; cdecl; +begin + //try + Result := IUserFieldImpl(this).entered(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserFieldImpl_specifiedDispatcher(this: IUserField): Integer; cdecl; +begin + //try + Result := IUserFieldImpl(this).specified(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUserFieldImpl_setEnteredDispatcher(this: IUserField; status: IStatus; newValue: Integer); cdecl; +begin + //try + IUserFieldImpl(this).setEntered(status, newValue); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUserFieldImpl_vTable: UserFieldVTable; + +constructor IUserFieldImpl.create; +begin + vTable := IUserFieldImpl_vTable; +end; + +function ICharUserFieldImpl_enteredDispatcher(this: ICharUserField): Integer; cdecl; +begin + //try + Result := ICharUserFieldImpl(this).entered(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ICharUserFieldImpl_specifiedDispatcher(this: ICharUserField): Integer; cdecl; +begin + //try + Result := ICharUserFieldImpl(this).specified(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure ICharUserFieldImpl_setEnteredDispatcher(this: ICharUserField; status: IStatus; newValue: Integer); cdecl; +begin + //try + ICharUserFieldImpl(this).setEntered(status, newValue); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function ICharUserFieldImpl_getDispatcher(this: ICharUserField): PAnsiChar; cdecl; +begin + //try + Result := ICharUserFieldImpl(this).get(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure ICharUserFieldImpl_set_Dispatcher(this: ICharUserField; status: IStatus; newValue: PAnsiChar); cdecl; +begin + //try + ICharUserFieldImpl(this).set_(status, newValue); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + ICharUserFieldImpl_vTable: CharUserFieldVTable; + +constructor ICharUserFieldImpl.create; +begin + vTable := ICharUserFieldImpl_vTable; +end; + +function IIntUserFieldImpl_enteredDispatcher(this: IIntUserField): Integer; cdecl; +begin + //try + Result := IIntUserFieldImpl(this).entered(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IIntUserFieldImpl_specifiedDispatcher(this: IIntUserField): Integer; cdecl; +begin + //try + Result := IIntUserFieldImpl(this).specified(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IIntUserFieldImpl_setEnteredDispatcher(this: IIntUserField; status: IStatus; newValue: Integer); cdecl; +begin + //try + IIntUserFieldImpl(this).setEntered(status, newValue); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IIntUserFieldImpl_getDispatcher(this: IIntUserField): Integer; cdecl; +begin + //try + Result := IIntUserFieldImpl(this).get(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IIntUserFieldImpl_set_Dispatcher(this: IIntUserField; status: IStatus; newValue: Integer); cdecl; +begin + //try + IIntUserFieldImpl(this).set_(status, newValue); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IIntUserFieldImpl_vTable: IntUserFieldVTable; + +constructor IIntUserFieldImpl.create; +begin + vTable := IIntUserFieldImpl_vTable; +end; + +function IUserImpl_operationDispatcher(this: IUser): Cardinal; cdecl; +begin + //try + Result := IUserImpl(this).operation(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_userNameDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).userName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_passwordDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).password(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_firstNameDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).firstName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_lastNameDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).lastName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_middleNameDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).middleName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_commentDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).comment(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_attributesDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).attributes(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_activeDispatcher(this: IUser): IIntUserField; cdecl; +begin + //try + Result := IUserImpl(this).active(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_adminDispatcher(this: IUser): IIntUserField; cdecl; +begin + //try + Result := IUserImpl(this).admin(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUserImpl_clearDispatcher(this: IUser; status: IStatus); cdecl; +begin + //try + IUserImpl(this).clear(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUserImpl_vTable: UserVTable; + +constructor IUserImpl.create; +begin + vTable := IUserImpl_vTable; +end; + +procedure IListUsersImpl_listDispatcher(this: IListUsers; status: IStatus; user: IUser); cdecl; +begin + //try + IListUsersImpl(this).list(status, user); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IListUsersImpl_vTable: ListUsersVTable; + +constructor IListUsersImpl.create; +begin + vTable := IListUsersImpl_vTable; +end; + +function ILogonInfoImpl_nameDispatcher(this: ILogonInfo): PAnsiChar; cdecl; +begin + //try + Result := ILogonInfoImpl(this).name(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ILogonInfoImpl_roleDispatcher(this: ILogonInfo): PAnsiChar; cdecl; +begin + //try + Result := ILogonInfoImpl(this).role(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ILogonInfoImpl_networkProtocolDispatcher(this: ILogonInfo): PAnsiChar; cdecl; +begin + //try + Result := ILogonInfoImpl(this).networkProtocol(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ILogonInfoImpl_remoteAddressDispatcher(this: ILogonInfo): PAnsiChar; cdecl; +begin + //try + Result := ILogonInfoImpl(this).remoteAddress(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ILogonInfoImpl_authBlockDispatcher(this: ILogonInfo; length: CardinalPtr): BytePtr; cdecl; +begin + //try + Result := ILogonInfoImpl(this).authBlock(length); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ILogonInfoImpl_vTable: LogonInfoVTable; + +constructor ILogonInfoImpl.create; +begin + vTable := ILogonInfoImpl_vTable; +end; + +procedure IManagementImpl_addRefDispatcher(this: IManagement); cdecl; +begin + //try + IManagementImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IManagementImpl_releaseDispatcher(this: IManagement): Integer; cdecl; +begin + //try + Result := IManagementImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IManagementImpl_setOwnerDispatcher(this: IManagement; r: IReferenceCounted); cdecl; +begin + //try + IManagementImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IManagementImpl_getOwnerDispatcher(this: IManagement): IReferenceCounted; cdecl; +begin + //try + Result := IManagementImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IManagementImpl_startDispatcher(this: IManagement; status: IStatus; logonInfo: ILogonInfo); cdecl; +begin + //try + IManagementImpl(this).start(status, logonInfo); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IManagementImpl_executeDispatcher(this: IManagement; status: IStatus; user: IUser; callback: IListUsers): Integer; cdecl; +begin + //try + Result := IManagementImpl(this).execute(status, user, callback); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IManagementImpl_commitDispatcher(this: IManagement; status: IStatus); cdecl; +begin + //try + IManagementImpl(this).commit(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IManagementImpl_rollbackDispatcher(this: IManagement; status: IStatus); cdecl; +begin + //try + IManagementImpl(this).rollback(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IManagementImpl_vTable: ManagementVTable; + +constructor IManagementImpl.create; +begin + vTable := IManagementImpl_vTable; +end; + +procedure IWireCryptPluginImpl_addRefDispatcher(this: IWireCryptPlugin); cdecl; +begin + //try + IWireCryptPluginImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IWireCryptPluginImpl_releaseDispatcher(this: IWireCryptPlugin): Integer; cdecl; +begin + //try + Result := IWireCryptPluginImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IWireCryptPluginImpl_setOwnerDispatcher(this: IWireCryptPlugin; r: IReferenceCounted); cdecl; +begin + //try + IWireCryptPluginImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IWireCryptPluginImpl_getOwnerDispatcher(this: IWireCryptPlugin): IReferenceCounted; cdecl; +begin + //try + Result := IWireCryptPluginImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IWireCryptPluginImpl_getKnownTypesDispatcher(this: IWireCryptPlugin; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IWireCryptPluginImpl(this).getKnownTypes(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IWireCryptPluginImpl_setKeyDispatcher(this: IWireCryptPlugin; status: IStatus; key: ICryptKey); cdecl; +begin + //try + IWireCryptPluginImpl(this).setKey(status, key); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IWireCryptPluginImpl_encryptDispatcher(this: IWireCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; +begin + //try + IWireCryptPluginImpl(this).encrypt(status, length, from, to_); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IWireCryptPluginImpl_decryptDispatcher(this: IWireCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; +begin + //try + IWireCryptPluginImpl(this).decrypt(status, length, from, to_); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IWireCryptPluginImpl_vTable: WireCryptPluginVTable; + +constructor IWireCryptPluginImpl.create; +begin + vTable := IWireCryptPluginImpl_vTable; +end; + +function ICryptKeyCallbackImpl_callbackDispatcher(this: ICryptKeyCallback; dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; cdecl; +begin + //try + Result := ICryptKeyCallbackImpl(this).callback(dataLength, data, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ICryptKeyCallbackImpl_vTable: CryptKeyCallbackVTable; + +constructor ICryptKeyCallbackImpl.create; +begin + vTable := ICryptKeyCallbackImpl_vTable; +end; + +procedure IKeyHolderPluginImpl_addRefDispatcher(this: IKeyHolderPlugin); cdecl; +begin + //try + IKeyHolderPluginImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IKeyHolderPluginImpl_releaseDispatcher(this: IKeyHolderPlugin): Integer; cdecl; +begin + //try + Result := IKeyHolderPluginImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IKeyHolderPluginImpl_setOwnerDispatcher(this: IKeyHolderPlugin; r: IReferenceCounted); cdecl; +begin + //try + IKeyHolderPluginImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IKeyHolderPluginImpl_getOwnerDispatcher(this: IKeyHolderPlugin): IReferenceCounted; cdecl; +begin + //try + Result := IKeyHolderPluginImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IKeyHolderPluginImpl_keyCallbackDispatcher(this: IKeyHolderPlugin; status: IStatus; callback: ICryptKeyCallback): Integer; cdecl; +begin + //try + Result := IKeyHolderPluginImpl(this).keyCallback(status, callback); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IKeyHolderPluginImpl_keyHandleDispatcher(this: IKeyHolderPlugin; status: IStatus; keyName: PAnsiChar): ICryptKeyCallback; cdecl; +begin + //try + Result := IKeyHolderPluginImpl(this).keyHandle(status, keyName); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IKeyHolderPluginImpl_vTable: KeyHolderPluginVTable; + +constructor IKeyHolderPluginImpl.create; +begin + vTable := IKeyHolderPluginImpl_vTable; +end; + +procedure IDbCryptPluginImpl_addRefDispatcher(this: IDbCryptPlugin); cdecl; +begin + //try + IDbCryptPluginImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IDbCryptPluginImpl_releaseDispatcher(this: IDbCryptPlugin): Integer; cdecl; +begin + //try + Result := IDbCryptPluginImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IDbCryptPluginImpl_setOwnerDispatcher(this: IDbCryptPlugin; r: IReferenceCounted); cdecl; +begin + //try + IDbCryptPluginImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IDbCryptPluginImpl_getOwnerDispatcher(this: IDbCryptPlugin): IReferenceCounted; cdecl; +begin + //try + Result := IDbCryptPluginImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IDbCryptPluginImpl_setKeyDispatcher(this: IDbCryptPlugin; status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); cdecl; +begin + //try + IDbCryptPluginImpl(this).setKey(status, length, sources, keyName); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IDbCryptPluginImpl_encryptDispatcher(this: IDbCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; +begin + //try + IDbCryptPluginImpl(this).encrypt(status, length, from, to_); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IDbCryptPluginImpl_decryptDispatcher(this: IDbCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; +begin + //try + IDbCryptPluginImpl(this).decrypt(status, length, from, to_); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IDbCryptPluginImpl_vTable: DbCryptPluginVTable; + +constructor IDbCryptPluginImpl.create; +begin + vTable := IDbCryptPluginImpl_vTable; +end; + +function IExternalContextImpl_getMasterDispatcher(this: IExternalContext): IMaster; cdecl; +begin + //try + Result := IExternalContextImpl(this).getMaster(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_getEngineDispatcher(this: IExternalContext; status: IStatus): IExternalEngine; cdecl; +begin + //try + Result := IExternalContextImpl(this).getEngine(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalContextImpl_getAttachmentDispatcher(this: IExternalContext; status: IStatus): IAttachment; cdecl; +begin + //try + Result := IExternalContextImpl(this).getAttachment(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalContextImpl_getTransactionDispatcher(this: IExternalContext; status: IStatus): ITransaction; cdecl; +begin + //try + Result := IExternalContextImpl(this).getTransaction(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalContextImpl_getUserNameDispatcher(this: IExternalContext): PAnsiChar; cdecl; +begin + //try + Result := IExternalContextImpl(this).getUserName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_getDatabaseNameDispatcher(this: IExternalContext): PAnsiChar; cdecl; +begin + //try + Result := IExternalContextImpl(this).getDatabaseName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_getClientCharSetDispatcher(this: IExternalContext): PAnsiChar; cdecl; +begin + //try + Result := IExternalContextImpl(this).getClientCharSet(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_obtainInfoCodeDispatcher(this: IExternalContext): Integer; cdecl; +begin + //try + Result := IExternalContextImpl(this).obtainInfoCode(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_getInfoDispatcher(this: IExternalContext; code: Integer): Pointer; cdecl; +begin + //try + Result := IExternalContextImpl(this).getInfo(code); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_setInfoDispatcher(this: IExternalContext; code: Integer; value: Pointer): Pointer; cdecl; +begin + //try + Result := IExternalContextImpl(this).setInfo(code, value); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IExternalContextImpl_vTable: ExternalContextVTable; + +constructor IExternalContextImpl.create; +begin + vTable := IExternalContextImpl_vTable; +end; + +procedure IExternalResultSetImpl_disposeDispatcher(this: IExternalResultSet); cdecl; +begin + //try + IExternalResultSetImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalResultSetImpl_fetchDispatcher(this: IExternalResultSet; status: IStatus): Boolean; cdecl; +begin + //try + Result := IExternalResultSetImpl(this).fetch(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IExternalResultSetImpl_vTable: ExternalResultSetVTable; + +constructor IExternalResultSetImpl.create; +begin + vTable := IExternalResultSetImpl_vTable; +end; + +procedure IExternalFunctionImpl_disposeDispatcher(this: IExternalFunction); cdecl; +begin + //try + IExternalFunctionImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IExternalFunctionImpl_getCharSetDispatcher(this: IExternalFunction; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; +begin + //try + IExternalFunctionImpl(this).getCharSet(status, context, name, nameSize); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IExternalFunctionImpl_executeDispatcher(this: IExternalFunction; status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer); cdecl; +begin + //try + IExternalFunctionImpl(this).execute(status, context, inMsg, outMsg); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IExternalFunctionImpl_vTable: ExternalFunctionVTable; + +constructor IExternalFunctionImpl.create; +begin + vTable := IExternalFunctionImpl_vTable; +end; + +procedure IExternalProcedureImpl_disposeDispatcher(this: IExternalProcedure); cdecl; +begin + //try + IExternalProcedureImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IExternalProcedureImpl_getCharSetDispatcher(this: IExternalProcedure; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; +begin + //try + IExternalProcedureImpl(this).getCharSet(status, context, name, nameSize); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalProcedureImpl_openDispatcher(this: IExternalProcedure; status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer): IExternalResultSet; cdecl; +begin + //try + Result := IExternalProcedureImpl(this).open(status, context, inMsg, outMsg); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IExternalProcedureImpl_vTable: ExternalProcedureVTable; + +constructor IExternalProcedureImpl.create; +begin + vTable := IExternalProcedureImpl_vTable; +end; + +procedure IExternalTriggerImpl_disposeDispatcher(this: IExternalTrigger); cdecl; +begin + //try + IExternalTriggerImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IExternalTriggerImpl_getCharSetDispatcher(this: IExternalTrigger; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; +begin + //try + IExternalTriggerImpl(this).getCharSet(status, context, name, nameSize); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IExternalTriggerImpl_executeDispatcher(this: IExternalTrigger; status: IStatus; context: IExternalContext; action: Cardinal; oldMsg: Pointer; newMsg: Pointer); cdecl; +begin + //try + IExternalTriggerImpl(this).execute(status, context, action, oldMsg, newMsg); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IExternalTriggerImpl_vTable: ExternalTriggerVTable; + +constructor IExternalTriggerImpl.create; +begin + vTable := IExternalTriggerImpl_vTable; +end; + +function IRoutineMetadataImpl_getPackageDispatcher(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getPackage(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getNameDispatcher(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getName(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getEntryPointDispatcher(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getEntryPoint(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getBodyDispatcher(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getBody(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getInputMetadataDispatcher(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getInputMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getOutputMetadataDispatcher(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getOutputMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getTriggerMetadataDispatcher(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getTriggerMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getTriggerTableDispatcher(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getTriggerTable(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getTriggerTypeDispatcher(this: IRoutineMetadata; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getTriggerType(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IRoutineMetadataImpl_vTable: RoutineMetadataVTable; + +constructor IRoutineMetadataImpl.create; +begin + vTable := IRoutineMetadataImpl_vTable; +end; + +procedure IExternalEngineImpl_addRefDispatcher(this: IExternalEngine); cdecl; +begin + //try + IExternalEngineImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalEngineImpl_releaseDispatcher(this: IExternalEngine): Integer; cdecl; +begin + //try + Result := IExternalEngineImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IExternalEngineImpl_setOwnerDispatcher(this: IExternalEngine; r: IReferenceCounted); cdecl; +begin + //try + IExternalEngineImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalEngineImpl_getOwnerDispatcher(this: IExternalEngine): IReferenceCounted; cdecl; +begin + //try + Result := IExternalEngineImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IExternalEngineImpl_openDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); cdecl; +begin + //try + IExternalEngineImpl(this).open(status, context, charSet, charSetSize); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IExternalEngineImpl_openAttachmentDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl; +begin + //try + IExternalEngineImpl(this).openAttachment(status, context); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IExternalEngineImpl_closeAttachmentDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl; +begin + //try + IExternalEngineImpl(this).closeAttachment(status, context); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalEngineImpl_makeFunctionDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalFunction; cdecl; +begin + //try + Result := IExternalEngineImpl(this).makeFunction(status, context, metadata, inBuilder, outBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalEngineImpl_makeProcedureDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalProcedure; cdecl; +begin + //try + Result := IExternalEngineImpl(this).makeProcedure(status, context, metadata, inBuilder, outBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalEngineImpl_makeTriggerDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder): IExternalTrigger; cdecl; +begin + //try + Result := IExternalEngineImpl(this).makeTrigger(status, context, metadata, fieldsBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IExternalEngineImpl_vTable: ExternalEngineVTable; + +constructor IExternalEngineImpl.create; +begin + vTable := IExternalEngineImpl_vTable; +end; + +procedure ITimerImpl_addRefDispatcher(this: ITimer); cdecl; +begin + //try + ITimerImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITimerImpl_releaseDispatcher(this: ITimer): Integer; cdecl; +begin + //try + Result := ITimerImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure ITimerImpl_handlerDispatcher(this: ITimer); cdecl; +begin + //try + ITimerImpl(this).handler(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITimerImpl_vTable: TimerVTable; + +constructor ITimerImpl.create; +begin + vTable := ITimerImpl_vTable; +end; + +procedure ITimerControlImpl_startDispatcher(this: ITimerControl; status: IStatus; timer: ITimer; microSeconds: QWord); cdecl; +begin + //try + ITimerControlImpl(this).start(status, timer, microSeconds); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITimerControlImpl_stopDispatcher(this: ITimerControl; status: IStatus; timer: ITimer); cdecl; +begin + //try + ITimerControlImpl(this).stop(status, timer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + ITimerControlImpl_vTable: TimerControlVTable; + +constructor ITimerControlImpl.create; +begin + vTable := ITimerControlImpl_vTable; +end; + +procedure IVersionCallbackImpl_callbackDispatcher(this: IVersionCallback; status: IStatus; text: PAnsiChar); cdecl; +begin + //try + IVersionCallbackImpl(this).callback(status, text); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IVersionCallbackImpl_vTable: VersionCallbackVTable; + +constructor IVersionCallbackImpl.create; +begin + vTable := IVersionCallbackImpl_vTable; +end; + +procedure IUtilImpl_getFbVersionDispatcher(this: IUtil; status: IStatus; att: IAttachment; callback: IVersionCallback); cdecl; +begin + //try + IUtilImpl(this).getFbVersion(status, att, callback); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUtilImpl_loadBlobDispatcher(this: IUtil; status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); cdecl; +begin + //try + IUtilImpl(this).loadBlob(status, blobId, att, tra, file_, txt); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUtilImpl_dumpBlobDispatcher(this: IUtil; status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); cdecl; +begin + //try + IUtilImpl(this).dumpBlob(status, blobId, att, tra, file_, txt); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUtilImpl_getPerfCountersDispatcher(this: IUtil; status: IStatus; att: IAttachment; countersSet: PAnsiChar; counters: Int64Ptr); cdecl; +begin + //try + IUtilImpl(this).getPerfCounters(status, att, countersSet, counters); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IUtilImpl_executeCreateDatabaseDispatcher(this: IUtil; status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; stmtIsCreateDb: BooleanPtr): IAttachment; cdecl; +begin + //try + Result := IUtilImpl(this).executeCreateDatabase(status, stmtLength, creatDBstatement, dialect, stmtIsCreateDb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUtilImpl_decodeDateDispatcher(this: IUtil; date: ISC_DATE; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr); cdecl; +begin + //try + IUtilImpl(this).decodeDate(date, year, month, day); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUtilImpl_decodeTimeDispatcher(this: IUtil; time: ISC_TIME; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr); cdecl; +begin + //try + IUtilImpl(this).decodeTime(time, hours, minutes, seconds, fractions); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUtilImpl_encodeDateDispatcher(this: IUtil; year: Cardinal; month: Cardinal; day: Cardinal): ISC_DATE; cdecl; +begin + //try + Result := IUtilImpl(this).encodeDate(year, month, day); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUtilImpl_encodeTimeDispatcher(this: IUtil; hours: Cardinal; minutes: Cardinal; seconds: Cardinal; fractions: Cardinal): ISC_TIME; cdecl; +begin + //try + Result := IUtilImpl(this).encodeTime(hours, minutes, seconds, fractions); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUtilImpl_formatStatusDispatcher(this: IUtil; buffer: PAnsiChar; bufferSize: Cardinal; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IUtilImpl(this).formatStatus(buffer, bufferSize, status); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUtilImpl_getClientVersionDispatcher(this: IUtil): Cardinal; cdecl; +begin + //try + Result := IUtilImpl(this).getClientVersion(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUtilImpl_getXpbBuilderDispatcher(this: IUtil; status: IStatus; kind: Cardinal; buf: BytePtr; len: Cardinal): IXpbBuilder; cdecl; +begin + //try + Result := IUtilImpl(this).getXpbBuilder(status, kind, buf, len); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IUtilImpl_setOffsetsDispatcher(this: IUtil; status: IStatus; metadata: IMessageMetadata; callback: IOffsetsCallback): Cardinal; cdecl; +begin + //try + Result := IUtilImpl(this).setOffsets(status, metadata, callback); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUtilImpl_vTable: UtilVTable; + +constructor IUtilImpl.create; +begin + vTable := IUtilImpl_vTable; +end; + +procedure IOffsetsCallbackImpl_setOffsetDispatcher(this: IOffsetsCallback; status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); cdecl; +begin + //try + IOffsetsCallbackImpl(this).setOffset(status, index, offset, nullOffset); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IOffsetsCallbackImpl_vTable: OffsetsCallbackVTable; + +constructor IOffsetsCallbackImpl.create; +begin + vTable := IOffsetsCallbackImpl_vTable; +end; + +procedure IXpbBuilderImpl_disposeDispatcher(this: IXpbBuilder); cdecl; +begin + //try + IXpbBuilderImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IXpbBuilderImpl_clearDispatcher(this: IXpbBuilder; status: IStatus); cdecl; +begin + //try + IXpbBuilderImpl(this).clear(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_removeCurrentDispatcher(this: IXpbBuilder; status: IStatus); cdecl; +begin + //try + IXpbBuilderImpl(this).removeCurrent(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_insertIntDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte; value: Integer); cdecl; +begin + //try + IXpbBuilderImpl(this).insertInt(status, tag, value); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_insertBigIntDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte; value: Int64); cdecl; +begin + //try + IXpbBuilderImpl(this).insertBigInt(status, tag, value); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_insertBytesDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte; bytes: Pointer; length: Cardinal); cdecl; +begin + //try + IXpbBuilderImpl(this).insertBytes(status, tag, bytes, length); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_insertStringDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte; str: PAnsiChar); cdecl; +begin + //try + IXpbBuilderImpl(this).insertString(status, tag, str); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_insertTagDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte); cdecl; +begin + //try + IXpbBuilderImpl(this).insertTag(status, tag); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_isEofDispatcher(this: IXpbBuilder; status: IStatus): Boolean; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).isEof(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_moveNextDispatcher(this: IXpbBuilder; status: IStatus); cdecl; +begin + //try + IXpbBuilderImpl(this).moveNext(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_rewindDispatcher(this: IXpbBuilder; status: IStatus); cdecl; +begin + //try + IXpbBuilderImpl(this).rewind(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_findFirstDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte): Boolean; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).findFirst(status, tag); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_findNextDispatcher(this: IXpbBuilder; status: IStatus): Boolean; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).findNext(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getTagDispatcher(this: IXpbBuilder; status: IStatus): Byte; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getTag(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getLengthDispatcher(this: IXpbBuilder; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getLength(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getIntDispatcher(this: IXpbBuilder; status: IStatus): Integer; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getInt(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getBigIntDispatcher(this: IXpbBuilder; status: IStatus): Int64; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getBigInt(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getStringDispatcher(this: IXpbBuilder; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getString(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getBytesDispatcher(this: IXpbBuilder; status: IStatus): BytePtr; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getBytes(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getBufferLengthDispatcher(this: IXpbBuilder; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getBufferLength(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getBufferDispatcher(this: IXpbBuilder; status: IStatus): BytePtr; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getBuffer(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IXpbBuilderImpl_vTable: XpbBuilderVTable; + +constructor IXpbBuilderImpl.create; +begin + vTable := IXpbBuilderImpl_vTable; +end; + +function ITraceConnectionImpl_getKindDispatcher(this: ITraceConnection): Cardinal; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getKind(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getProcessIDDispatcher(this: ITraceConnection): Integer; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getUserNameDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getUserName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getRoleNameDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getRoleName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getCharSetDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getCharSet(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getRemoteProtocolDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getRemoteProtocol(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getRemoteAddressDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getRemoteAddress(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getRemoteProcessIDDispatcher(this: ITraceConnection): Integer; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getRemoteProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getRemoteProcessNameDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getRemoteProcessName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceConnectionImpl_vTable: TraceConnectionVTable; + +constructor ITraceConnectionImpl.create; +begin + vTable := ITraceConnectionImpl_vTable; +end; + +function ITraceDatabaseConnectionImpl_getKindDispatcher(this: ITraceDatabaseConnection): Cardinal; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getKind(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getProcessIDDispatcher(this: ITraceDatabaseConnection): Integer; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getUserNameDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getUserName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getRoleNameDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getRoleName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getCharSetDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getCharSet(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getRemoteProtocolDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getRemoteProtocol(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getRemoteAddressDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getRemoteAddress(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getRemoteProcessIDDispatcher(this: ITraceDatabaseConnection): Integer; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getRemoteProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getRemoteProcessNameDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getRemoteProcessName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getConnectionIDDispatcher(this: ITraceDatabaseConnection): Int64; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getConnectionID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getDatabaseNameDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getDatabaseName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceDatabaseConnectionImpl_vTable: TraceDatabaseConnectionVTable; + +constructor ITraceDatabaseConnectionImpl.create; +begin + vTable := ITraceDatabaseConnectionImpl_vTable; +end; + +function ITraceTransactionImpl_getTransactionIDDispatcher(this: ITraceTransaction): Int64; cdecl; +begin + //try + Result := ITraceTransactionImpl(this).getTransactionID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTransactionImpl_getReadOnlyDispatcher(this: ITraceTransaction): Boolean; cdecl; +begin + //try + Result := ITraceTransactionImpl(this).getReadOnly(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTransactionImpl_getWaitDispatcher(this: ITraceTransaction): Integer; cdecl; +begin + //try + Result := ITraceTransactionImpl(this).getWait(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTransactionImpl_getIsolationDispatcher(this: ITraceTransaction): Cardinal; cdecl; +begin + //try + Result := ITraceTransactionImpl(this).getIsolation(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTransactionImpl_getPerfDispatcher(this: ITraceTransaction): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceTransactionImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceTransactionImpl_vTable: TraceTransactionVTable; + +constructor ITraceTransactionImpl.create; +begin + vTable := ITraceTransactionImpl_vTable; +end; + +function ITraceParamsImpl_getCountDispatcher(this: ITraceParams): Cardinal; cdecl; +begin + //try + Result := ITraceParamsImpl(this).getCount(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceParamsImpl_getParamDispatcher(this: ITraceParams; idx: Cardinal): dscPtr; cdecl; +begin + //try + Result := ITraceParamsImpl(this).getParam(idx); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceParamsImpl_vTable: TraceParamsVTable; + +constructor ITraceParamsImpl.create; +begin + vTable := ITraceParamsImpl_vTable; +end; + +function ITraceStatementImpl_getStmtIDDispatcher(this: ITraceStatement): Int64; cdecl; +begin + //try + Result := ITraceStatementImpl(this).getStmtID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceStatementImpl_getPerfDispatcher(this: ITraceStatement): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceStatementImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceStatementImpl_vTable: TraceStatementVTable; + +constructor ITraceStatementImpl.create; +begin + vTable := ITraceStatementImpl_vTable; +end; + +function ITraceSQLStatementImpl_getStmtIDDispatcher(this: ITraceSQLStatement): Int64; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getStmtID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getPerfDispatcher(this: ITraceSQLStatement): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getTextDispatcher(this: ITraceSQLStatement): PAnsiChar; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getText(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getPlanDispatcher(this: ITraceSQLStatement): PAnsiChar; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getPlan(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getInputsDispatcher(this: ITraceSQLStatement): ITraceParams; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getInputs(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getTextUTF8Dispatcher(this: ITraceSQLStatement): PAnsiChar; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getTextUTF8(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getExplainedPlanDispatcher(this: ITraceSQLStatement): PAnsiChar; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getExplainedPlan(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceSQLStatementImpl_vTable: TraceSQLStatementVTable; + +constructor ITraceSQLStatementImpl.create; +begin + vTable := ITraceSQLStatementImpl_vTable; +end; + +function ITraceBLRStatementImpl_getStmtIDDispatcher(this: ITraceBLRStatement): Int64; cdecl; +begin + //try + Result := ITraceBLRStatementImpl(this).getStmtID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceBLRStatementImpl_getPerfDispatcher(this: ITraceBLRStatement): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceBLRStatementImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceBLRStatementImpl_getDataDispatcher(this: ITraceBLRStatement): BytePtr; cdecl; +begin + //try + Result := ITraceBLRStatementImpl(this).getData(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceBLRStatementImpl_getDataLengthDispatcher(this: ITraceBLRStatement): Cardinal; cdecl; +begin + //try + Result := ITraceBLRStatementImpl(this).getDataLength(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceBLRStatementImpl_getTextDispatcher(this: ITraceBLRStatement): PAnsiChar; cdecl; +begin + //try + Result := ITraceBLRStatementImpl(this).getText(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceBLRStatementImpl_vTable: TraceBLRStatementVTable; + +constructor ITraceBLRStatementImpl.create; +begin + vTable := ITraceBLRStatementImpl_vTable; +end; + +function ITraceDYNRequestImpl_getDataDispatcher(this: ITraceDYNRequest): BytePtr; cdecl; +begin + //try + Result := ITraceDYNRequestImpl(this).getData(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDYNRequestImpl_getDataLengthDispatcher(this: ITraceDYNRequest): Cardinal; cdecl; +begin + //try + Result := ITraceDYNRequestImpl(this).getDataLength(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDYNRequestImpl_getTextDispatcher(this: ITraceDYNRequest): PAnsiChar; cdecl; +begin + //try + Result := ITraceDYNRequestImpl(this).getText(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceDYNRequestImpl_vTable: TraceDYNRequestVTable; + +constructor ITraceDYNRequestImpl.create; +begin + vTable := ITraceDYNRequestImpl_vTable; +end; + +function ITraceContextVariableImpl_getNameSpaceDispatcher(this: ITraceContextVariable): PAnsiChar; cdecl; +begin + //try + Result := ITraceContextVariableImpl(this).getNameSpace(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceContextVariableImpl_getVarNameDispatcher(this: ITraceContextVariable): PAnsiChar; cdecl; +begin + //try + Result := ITraceContextVariableImpl(this).getVarName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceContextVariableImpl_getVarValueDispatcher(this: ITraceContextVariable): PAnsiChar; cdecl; +begin + //try + Result := ITraceContextVariableImpl(this).getVarValue(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceContextVariableImpl_vTable: TraceContextVariableVTable; + +constructor ITraceContextVariableImpl.create; +begin + vTable := ITraceContextVariableImpl_vTable; +end; + +function ITraceProcedureImpl_getProcNameDispatcher(this: ITraceProcedure): PAnsiChar; cdecl; +begin + //try + Result := ITraceProcedureImpl(this).getProcName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceProcedureImpl_getInputsDispatcher(this: ITraceProcedure): ITraceParams; cdecl; +begin + //try + Result := ITraceProcedureImpl(this).getInputs(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceProcedureImpl_getPerfDispatcher(this: ITraceProcedure): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceProcedureImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceProcedureImpl_vTable: TraceProcedureVTable; + +constructor ITraceProcedureImpl.create; +begin + vTable := ITraceProcedureImpl_vTable; +end; + +function ITraceFunctionImpl_getFuncNameDispatcher(this: ITraceFunction): PAnsiChar; cdecl; +begin + //try + Result := ITraceFunctionImpl(this).getFuncName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFunctionImpl_getInputsDispatcher(this: ITraceFunction): ITraceParams; cdecl; +begin + //try + Result := ITraceFunctionImpl(this).getInputs(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFunctionImpl_getResultDispatcher(this: ITraceFunction): ITraceParams; cdecl; +begin + //try + Result := ITraceFunctionImpl(this).getResult(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFunctionImpl_getPerfDispatcher(this: ITraceFunction): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceFunctionImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceFunctionImpl_vTable: TraceFunctionVTable; + +constructor ITraceFunctionImpl.create; +begin + vTable := ITraceFunctionImpl_vTable; +end; + +function ITraceTriggerImpl_getTriggerNameDispatcher(this: ITraceTrigger): PAnsiChar; cdecl; +begin + //try + Result := ITraceTriggerImpl(this).getTriggerName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTriggerImpl_getRelationNameDispatcher(this: ITraceTrigger): PAnsiChar; cdecl; +begin + //try + Result := ITraceTriggerImpl(this).getRelationName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTriggerImpl_getActionDispatcher(this: ITraceTrigger): Integer; cdecl; +begin + //try + Result := ITraceTriggerImpl(this).getAction(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTriggerImpl_getWhichDispatcher(this: ITraceTrigger): Integer; cdecl; +begin + //try + Result := ITraceTriggerImpl(this).getWhich(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTriggerImpl_getPerfDispatcher(this: ITraceTrigger): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceTriggerImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceTriggerImpl_vTable: TraceTriggerVTable; + +constructor ITraceTriggerImpl.create; +begin + vTable := ITraceTriggerImpl_vTable; +end; + +function ITraceServiceConnectionImpl_getKindDispatcher(this: ITraceServiceConnection): Cardinal; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getKind(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getProcessIDDispatcher(this: ITraceServiceConnection): Integer; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getUserNameDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getUserName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getRoleNameDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getRoleName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getCharSetDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getCharSet(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getRemoteProtocolDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getRemoteProtocol(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getRemoteAddressDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getRemoteAddress(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getRemoteProcessIDDispatcher(this: ITraceServiceConnection): Integer; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getRemoteProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getRemoteProcessNameDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getRemoteProcessName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getServiceIDDispatcher(this: ITraceServiceConnection): Pointer; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getServiceID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getServiceMgrDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getServiceMgr(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getServiceNameDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getServiceName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceServiceConnectionImpl_vTable: TraceServiceConnectionVTable; + +constructor ITraceServiceConnectionImpl.create; +begin + vTable := ITraceServiceConnectionImpl_vTable; +end; + +function ITraceStatusVectorImpl_hasErrorDispatcher(this: ITraceStatusVector): Boolean; cdecl; +begin + //try + Result := ITraceStatusVectorImpl(this).hasError(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceStatusVectorImpl_hasWarningDispatcher(this: ITraceStatusVector): Boolean; cdecl; +begin + //try + Result := ITraceStatusVectorImpl(this).hasWarning(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceStatusVectorImpl_getStatusDispatcher(this: ITraceStatusVector): IStatus; cdecl; +begin + //try + Result := ITraceStatusVectorImpl(this).getStatus(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceStatusVectorImpl_getTextDispatcher(this: ITraceStatusVector): PAnsiChar; cdecl; +begin + //try + Result := ITraceStatusVectorImpl(this).getText(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceStatusVectorImpl_vTable: TraceStatusVectorVTable; + +constructor ITraceStatusVectorImpl.create; +begin + vTable := ITraceStatusVectorImpl_vTable; +end; + +function ITraceSweepInfoImpl_getOITDispatcher(this: ITraceSweepInfo): Int64; cdecl; +begin + //try + Result := ITraceSweepInfoImpl(this).getOIT(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSweepInfoImpl_getOSTDispatcher(this: ITraceSweepInfo): Int64; cdecl; +begin + //try + Result := ITraceSweepInfoImpl(this).getOST(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSweepInfoImpl_getOATDispatcher(this: ITraceSweepInfo): Int64; cdecl; +begin + //try + Result := ITraceSweepInfoImpl(this).getOAT(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSweepInfoImpl_getNextDispatcher(this: ITraceSweepInfo): Int64; cdecl; +begin + //try + Result := ITraceSweepInfoImpl(this).getNext(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSweepInfoImpl_getPerfDispatcher(this: ITraceSweepInfo): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceSweepInfoImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceSweepInfoImpl_vTable: TraceSweepInfoVTable; + +constructor ITraceSweepInfoImpl.create; +begin + vTable := ITraceSweepInfoImpl_vTable; +end; + +procedure ITraceLogWriterImpl_addRefDispatcher(this: ITraceLogWriter); cdecl; +begin + //try + ITraceLogWriterImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceLogWriterImpl_releaseDispatcher(this: ITraceLogWriter): Integer; cdecl; +begin + //try + Result := ITraceLogWriterImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceLogWriterImpl_writeDispatcher(this: ITraceLogWriter; buf: Pointer; size: Cardinal): Cardinal; cdecl; +begin + //try + Result := ITraceLogWriterImpl(this).write(buf, size); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceLogWriterImpl_vTable: TraceLogWriterVTable; + +constructor ITraceLogWriterImpl.create; +begin + vTable := ITraceLogWriterImpl_vTable; +end; + +function ITraceInitInfoImpl_getConfigTextDispatcher(this: ITraceInitInfo): PAnsiChar; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getConfigText(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getTraceSessionIDDispatcher(this: ITraceInitInfo): Integer; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getTraceSessionID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getTraceSessionNameDispatcher(this: ITraceInitInfo): PAnsiChar; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getTraceSessionName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getFirebirdRootDirectoryDispatcher(this: ITraceInitInfo): PAnsiChar; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getFirebirdRootDirectory(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getDatabaseNameDispatcher(this: ITraceInitInfo): PAnsiChar; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getDatabaseName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getConnectionDispatcher(this: ITraceInitInfo): ITraceDatabaseConnection; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getConnection(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getLogWriterDispatcher(this: ITraceInitInfo): ITraceLogWriter; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getLogWriter(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceInitInfoImpl_vTable: TraceInitInfoVTable; + +constructor ITraceInitInfoImpl.create; +begin + vTable := ITraceInitInfoImpl_vTable; +end; + +procedure ITracePluginImpl_addRefDispatcher(this: ITracePlugin); cdecl; +begin + //try + ITracePluginImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_releaseDispatcher(this: ITracePlugin): Integer; cdecl; +begin + //try + Result := ITracePluginImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_get_errorDispatcher(this: ITracePlugin): PAnsiChar; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_get_error(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_attachDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; create_db: Boolean; att_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_attach(connection, create_db, att_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_detachDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; drop_db: Boolean): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_detach(connection, drop_db); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_transaction_startDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; tpb_length: Cardinal; tpb: BytePtr; tra_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_transaction_start(connection, transaction, tpb_length, tpb, tra_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_transaction_endDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; commit: Boolean; retain_context: Boolean; tra_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_transaction_end(connection, transaction, commit, retain_context, tra_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_proc_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; procedure_: ITraceProcedure; started: Boolean; proc_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_proc_execute(connection, transaction, procedure_, started, proc_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_trigger_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; trigger: ITraceTrigger; started: Boolean; trig_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_trigger_execute(connection, transaction, trigger, started, trig_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_set_contextDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; variable: ITraceContextVariable): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_set_context(connection, transaction, variable); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_dsql_prepareDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_dsql_prepare(connection, transaction, statement, time_millis, req_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_dsql_freeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; statement: ITraceSQLStatement; option: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_dsql_free(connection, statement, option); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_dsql_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; started: Boolean; req_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_dsql_execute(connection, transaction, statement, started, req_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_blr_compileDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_blr_compile(connection, transaction, statement, time_millis, req_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_blr_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; req_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_blr_execute(connection, transaction, statement, req_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_dyn_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; request: ITraceDYNRequest; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_dyn_execute(connection, transaction, request, time_millis, req_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_service_attachDispatcher(this: ITracePlugin; service: ITraceServiceConnection; att_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_service_attach(service, att_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_service_startDispatcher(this: ITracePlugin; service: ITraceServiceConnection; switches_length: Cardinal; switches: PAnsiChar; start_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_service_start(service, switches_length, switches, start_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_service_queryDispatcher(this: ITracePlugin; service: ITraceServiceConnection; send_item_length: Cardinal; send_items: BytePtr; recv_item_length: Cardinal; recv_items: BytePtr; query_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_service_query(service, send_item_length, send_items, recv_item_length, recv_items, query_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_service_detachDispatcher(this: ITracePlugin; service: ITraceServiceConnection; detach_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_service_detach(service, detach_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_event_errorDispatcher(this: ITracePlugin; connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_event_error(connection, status, function_); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_event_sweepDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_event_sweep(connection, sweep, sweep_state); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_func_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_func_execute(connection, transaction, function_, started, func_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITracePluginImpl_vTable: TracePluginVTable; + +constructor ITracePluginImpl.create; +begin + vTable := ITracePluginImpl_vTable; +end; + +procedure ITraceFactoryImpl_addRefDispatcher(this: ITraceFactory); cdecl; +begin + //try + ITraceFactoryImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFactoryImpl_releaseDispatcher(this: ITraceFactory): Integer; cdecl; +begin + //try + Result := ITraceFactoryImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure ITraceFactoryImpl_setOwnerDispatcher(this: ITraceFactory; r: IReferenceCounted); cdecl; +begin + //try + ITraceFactoryImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFactoryImpl_getOwnerDispatcher(this: ITraceFactory): IReferenceCounted; cdecl; +begin + //try + Result := ITraceFactoryImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFactoryImpl_trace_needsDispatcher(this: ITraceFactory): QWord; cdecl; +begin + //try + Result := ITraceFactoryImpl(this).trace_needs(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFactoryImpl_trace_createDispatcher(this: ITraceFactory; status: IStatus; init_info: ITraceInitInfo): ITracePlugin; cdecl; +begin + //try + Result := ITraceFactoryImpl(this).trace_create(status, init_info); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + ITraceFactoryImpl_vTable: TraceFactoryVTable; + +constructor ITraceFactoryImpl.create; +begin + vTable := ITraceFactoryImpl_vTable; +end; + +procedure IUdrFunctionFactoryImpl_disposeDispatcher(this: IUdrFunctionFactory); cdecl; +begin + //try + IUdrFunctionFactoryImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUdrFunctionFactoryImpl_setupDispatcher(this: IUdrFunctionFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); cdecl; +begin + //try + IUdrFunctionFactoryImpl(this).setup(status, context, metadata, inBuilder, outBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IUdrFunctionFactoryImpl_newItemDispatcher(this: IUdrFunctionFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalFunction; cdecl; +begin + //try + Result := IUdrFunctionFactoryImpl(this).newItem(status, context, metadata); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUdrFunctionFactoryImpl_vTable: UdrFunctionFactoryVTable; + +constructor IUdrFunctionFactoryImpl.create; +begin + vTable := IUdrFunctionFactoryImpl_vTable; +end; + +procedure IUdrProcedureFactoryImpl_disposeDispatcher(this: IUdrProcedureFactory); cdecl; +begin + //try + IUdrProcedureFactoryImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUdrProcedureFactoryImpl_setupDispatcher(this: IUdrProcedureFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); cdecl; +begin + //try + IUdrProcedureFactoryImpl(this).setup(status, context, metadata, inBuilder, outBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IUdrProcedureFactoryImpl_newItemDispatcher(this: IUdrProcedureFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalProcedure; cdecl; +begin + //try + Result := IUdrProcedureFactoryImpl(this).newItem(status, context, metadata); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUdrProcedureFactoryImpl_vTable: UdrProcedureFactoryVTable; + +constructor IUdrProcedureFactoryImpl.create; +begin + vTable := IUdrProcedureFactoryImpl_vTable; +end; + +procedure IUdrTriggerFactoryImpl_disposeDispatcher(this: IUdrTriggerFactory); cdecl; +begin + //try + IUdrTriggerFactoryImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUdrTriggerFactoryImpl_setupDispatcher(this: IUdrTriggerFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder); cdecl; +begin + //try + IUdrTriggerFactoryImpl(this).setup(status, context, metadata, fieldsBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IUdrTriggerFactoryImpl_newItemDispatcher(this: IUdrTriggerFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalTrigger; cdecl; +begin + //try + Result := IUdrTriggerFactoryImpl(this).newItem(status, context, metadata); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUdrTriggerFactoryImpl_vTable: UdrTriggerFactoryVTable; + +constructor IUdrTriggerFactoryImpl.create; +begin + vTable := IUdrTriggerFactoryImpl_vTable; +end; + +function IUdrPluginImpl_getMasterDispatcher(this: IUdrPlugin): IMaster; cdecl; +begin + //try + Result := IUdrPluginImpl(this).getMaster(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUdrPluginImpl_registerFunctionDispatcher(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrFunctionFactory); cdecl; +begin + //try + IUdrPluginImpl(this).registerFunction(status, name, factory); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUdrPluginImpl_registerProcedureDispatcher(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrProcedureFactory); cdecl; +begin + //try + IUdrPluginImpl(this).registerProcedure(status, name, factory); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUdrPluginImpl_registerTriggerDispatcher(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrTriggerFactory); cdecl; +begin + //try + IUdrPluginImpl(this).registerTrigger(status, name, factory); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUdrPluginImpl_vTable: UdrPluginVTable; + +constructor IUdrPluginImpl.create; +begin + vTable := IUdrPluginImpl_vTable; +end; + +constructor FbException.create(status: IStatus); +begin + inherited Create('FbException'); + self.status := status.clone; +end; + +destructor FbException.Destroy(); +begin + status.dispose; + inherited Destroy; +end; + +function FbException.getStatus: IStatus; +begin + Result := status; +end; + +class procedure FbException.checkException(status: IStatus); +begin + if ((status.getState and status.STATE_ERRORS) <> 0) then + raise FbException.create(status); +end; + +class procedure FbException.catchException(status: IStatus; e: Exception); +var + statusVector: array[0..4] of NativeIntPtr; + msg: AnsiString; +begin + if (e.inheritsFrom(FbException)) then + status.setErrors(FbException(e).getStatus.getErrors) + else + begin + msg := e.message; + + statusVector[0] := NativeIntPtr(isc_arg_gds); + statusVector[1] := NativeIntPtr(isc_random); + statusVector[2] := NativeIntPtr(isc_arg_string); + statusVector[3] := NativeIntPtr(PAnsiChar(msg)); + statusVector[4] := NativeIntPtr(isc_arg_end); + + status.setErrors(@statusVector); + end +end; +initialization + IVersionedImpl_vTable := VersionedVTable.create; + IVersionedImpl_vTable.version := 0; + + IReferenceCountedImpl_vTable := ReferenceCountedVTable.create; + IReferenceCountedImpl_vTable.version := 2; + IReferenceCountedImpl_vTable.addRef := @IReferenceCountedImpl_addRefDispatcher; + IReferenceCountedImpl_vTable.release := @IReferenceCountedImpl_releaseDispatcher; + + IDisposableImpl_vTable := DisposableVTable.create; + IDisposableImpl_vTable.version := 1; + IDisposableImpl_vTable.dispose := @IDisposableImpl_disposeDispatcher; + + IStatusImpl_vTable := StatusVTable.create; + IStatusImpl_vTable.version := 10; + IStatusImpl_vTable.dispose := @IStatusImpl_disposeDispatcher; + IStatusImpl_vTable.init := @IStatusImpl_initDispatcher; + IStatusImpl_vTable.getState := @IStatusImpl_getStateDispatcher; + IStatusImpl_vTable.setErrors2 := @IStatusImpl_setErrors2Dispatcher; + IStatusImpl_vTable.setWarnings2 := @IStatusImpl_setWarnings2Dispatcher; + IStatusImpl_vTable.setErrors := @IStatusImpl_setErrorsDispatcher; + IStatusImpl_vTable.setWarnings := @IStatusImpl_setWarningsDispatcher; + IStatusImpl_vTable.getErrors := @IStatusImpl_getErrorsDispatcher; + IStatusImpl_vTable.getWarnings := @IStatusImpl_getWarningsDispatcher; + IStatusImpl_vTable.clone := @IStatusImpl_cloneDispatcher; + + IMasterImpl_vTable := MasterVTable.create; + IMasterImpl_vTable.version := 12; + IMasterImpl_vTable.getStatus := @IMasterImpl_getStatusDispatcher; + IMasterImpl_vTable.getDispatcher := @IMasterImpl_getDispatcherDispatcher; + IMasterImpl_vTable.getPluginManager := @IMasterImpl_getPluginManagerDispatcher; + IMasterImpl_vTable.getTimerControl := @IMasterImpl_getTimerControlDispatcher; + IMasterImpl_vTable.getDtc := @IMasterImpl_getDtcDispatcher; + IMasterImpl_vTable.registerAttachment := @IMasterImpl_registerAttachmentDispatcher; + IMasterImpl_vTable.registerTransaction := @IMasterImpl_registerTransactionDispatcher; + IMasterImpl_vTable.getMetadataBuilder := @IMasterImpl_getMetadataBuilderDispatcher; + IMasterImpl_vTable.serverMode := @IMasterImpl_serverModeDispatcher; + IMasterImpl_vTable.getUtilInterface := @IMasterImpl_getUtilInterfaceDispatcher; + IMasterImpl_vTable.getConfigManager := @IMasterImpl_getConfigManagerDispatcher; + IMasterImpl_vTable.getProcessExiting := @IMasterImpl_getProcessExitingDispatcher; + + IPluginBaseImpl_vTable := PluginBaseVTable.create; + IPluginBaseImpl_vTable.version := 4; + IPluginBaseImpl_vTable.addRef := @IPluginBaseImpl_addRefDispatcher; + IPluginBaseImpl_vTable.release := @IPluginBaseImpl_releaseDispatcher; + IPluginBaseImpl_vTable.setOwner := @IPluginBaseImpl_setOwnerDispatcher; + IPluginBaseImpl_vTable.getOwner := @IPluginBaseImpl_getOwnerDispatcher; + + IPluginSetImpl_vTable := PluginSetVTable.create; + IPluginSetImpl_vTable.version := 7; + IPluginSetImpl_vTable.addRef := @IPluginSetImpl_addRefDispatcher; + IPluginSetImpl_vTable.release := @IPluginSetImpl_releaseDispatcher; + IPluginSetImpl_vTable.getName := @IPluginSetImpl_getNameDispatcher; + IPluginSetImpl_vTable.getModuleName := @IPluginSetImpl_getModuleNameDispatcher; + IPluginSetImpl_vTable.getPlugin := @IPluginSetImpl_getPluginDispatcher; + IPluginSetImpl_vTable.next := @IPluginSetImpl_nextDispatcher; + IPluginSetImpl_vTable.set_ := @IPluginSetImpl_set_Dispatcher; + + IConfigEntryImpl_vTable := ConfigEntryVTable.create; + IConfigEntryImpl_vTable.version := 7; + IConfigEntryImpl_vTable.addRef := @IConfigEntryImpl_addRefDispatcher; + IConfigEntryImpl_vTable.release := @IConfigEntryImpl_releaseDispatcher; + IConfigEntryImpl_vTable.getName := @IConfigEntryImpl_getNameDispatcher; + IConfigEntryImpl_vTable.getValue := @IConfigEntryImpl_getValueDispatcher; + IConfigEntryImpl_vTable.getIntValue := @IConfigEntryImpl_getIntValueDispatcher; + IConfigEntryImpl_vTable.getBoolValue := @IConfigEntryImpl_getBoolValueDispatcher; + IConfigEntryImpl_vTable.getSubConfig := @IConfigEntryImpl_getSubConfigDispatcher; + + IConfigImpl_vTable := ConfigVTable.create; + IConfigImpl_vTable.version := 5; + IConfigImpl_vTable.addRef := @IConfigImpl_addRefDispatcher; + IConfigImpl_vTable.release := @IConfigImpl_releaseDispatcher; + IConfigImpl_vTable.find := @IConfigImpl_findDispatcher; + IConfigImpl_vTable.findValue := @IConfigImpl_findValueDispatcher; + IConfigImpl_vTable.findPos := @IConfigImpl_findPosDispatcher; + + IFirebirdConfImpl_vTable := FirebirdConfVTable.create; + IFirebirdConfImpl_vTable.version := 6; + IFirebirdConfImpl_vTable.addRef := @IFirebirdConfImpl_addRefDispatcher; + IFirebirdConfImpl_vTable.release := @IFirebirdConfImpl_releaseDispatcher; + IFirebirdConfImpl_vTable.getKey := @IFirebirdConfImpl_getKeyDispatcher; + IFirebirdConfImpl_vTable.asInteger := @IFirebirdConfImpl_asIntegerDispatcher; + IFirebirdConfImpl_vTable.asString := @IFirebirdConfImpl_asStringDispatcher; + IFirebirdConfImpl_vTable.asBoolean := @IFirebirdConfImpl_asBooleanDispatcher; + + IPluginConfigImpl_vTable := PluginConfigVTable.create; + IPluginConfigImpl_vTable.version := 6; + IPluginConfigImpl_vTable.addRef := @IPluginConfigImpl_addRefDispatcher; + IPluginConfigImpl_vTable.release := @IPluginConfigImpl_releaseDispatcher; + IPluginConfigImpl_vTable.getConfigFileName := @IPluginConfigImpl_getConfigFileNameDispatcher; + IPluginConfigImpl_vTable.getDefaultConfig := @IPluginConfigImpl_getDefaultConfigDispatcher; + IPluginConfigImpl_vTable.getFirebirdConf := @IPluginConfigImpl_getFirebirdConfDispatcher; + IPluginConfigImpl_vTable.setReleaseDelay := @IPluginConfigImpl_setReleaseDelayDispatcher; + + IPluginFactoryImpl_vTable := PluginFactoryVTable.create; + IPluginFactoryImpl_vTable.version := 1; + IPluginFactoryImpl_vTable.createPlugin := @IPluginFactoryImpl_createPluginDispatcher; + + IPluginModuleImpl_vTable := PluginModuleVTable.create; + IPluginModuleImpl_vTable.version := 1; + IPluginModuleImpl_vTable.doClean := @IPluginModuleImpl_doCleanDispatcher; + + IPluginManagerImpl_vTable := PluginManagerVTable.create; + IPluginManagerImpl_vTable.version := 6; + IPluginManagerImpl_vTable.registerPluginFactory := @IPluginManagerImpl_registerPluginFactoryDispatcher; + IPluginManagerImpl_vTable.registerModule := @IPluginManagerImpl_registerModuleDispatcher; + IPluginManagerImpl_vTable.unregisterModule := @IPluginManagerImpl_unregisterModuleDispatcher; + IPluginManagerImpl_vTable.getPlugins := @IPluginManagerImpl_getPluginsDispatcher; + IPluginManagerImpl_vTable.getConfig := @IPluginManagerImpl_getConfigDispatcher; + IPluginManagerImpl_vTable.releasePlugin := @IPluginManagerImpl_releasePluginDispatcher; + + ICryptKeyImpl_vTable := CryptKeyVTable.create; + ICryptKeyImpl_vTable.version := 4; + ICryptKeyImpl_vTable.setSymmetric := @ICryptKeyImpl_setSymmetricDispatcher; + ICryptKeyImpl_vTable.setAsymmetric := @ICryptKeyImpl_setAsymmetricDispatcher; + ICryptKeyImpl_vTable.getEncryptKey := @ICryptKeyImpl_getEncryptKeyDispatcher; + ICryptKeyImpl_vTable.getDecryptKey := @ICryptKeyImpl_getDecryptKeyDispatcher; + + IConfigManagerImpl_vTable := ConfigManagerVTable.create; + IConfigManagerImpl_vTable.version := 6; + IConfigManagerImpl_vTable.getDirectory := @IConfigManagerImpl_getDirectoryDispatcher; + IConfigManagerImpl_vTable.getFirebirdConf := @IConfigManagerImpl_getFirebirdConfDispatcher; + IConfigManagerImpl_vTable.getDatabaseConf := @IConfigManagerImpl_getDatabaseConfDispatcher; + IConfigManagerImpl_vTable.getPluginConfig := @IConfigManagerImpl_getPluginConfigDispatcher; + IConfigManagerImpl_vTable.getInstallDirectory := @IConfigManagerImpl_getInstallDirectoryDispatcher; + IConfigManagerImpl_vTable.getRootDirectory := @IConfigManagerImpl_getRootDirectoryDispatcher; + + IEventCallbackImpl_vTable := EventCallbackVTable.create; + IEventCallbackImpl_vTable.version := 3; + IEventCallbackImpl_vTable.addRef := @IEventCallbackImpl_addRefDispatcher; + IEventCallbackImpl_vTable.release := @IEventCallbackImpl_releaseDispatcher; + IEventCallbackImpl_vTable.eventCallbackFunction := @IEventCallbackImpl_eventCallbackFunctionDispatcher; + + IBlobImpl_vTable := BlobVTable.create; + IBlobImpl_vTable.version := 8; + IBlobImpl_vTable.addRef := @IBlobImpl_addRefDispatcher; + IBlobImpl_vTable.release := @IBlobImpl_releaseDispatcher; + IBlobImpl_vTable.getInfo := @IBlobImpl_getInfoDispatcher; + IBlobImpl_vTable.getSegment := @IBlobImpl_getSegmentDispatcher; + IBlobImpl_vTable.putSegment := @IBlobImpl_putSegmentDispatcher; + IBlobImpl_vTable.cancel := @IBlobImpl_cancelDispatcher; + IBlobImpl_vTable.close := @IBlobImpl_closeDispatcher; + IBlobImpl_vTable.seek := @IBlobImpl_seekDispatcher; + + ITransactionImpl_vTable := TransactionVTable.create; + ITransactionImpl_vTable.version := 12; + ITransactionImpl_vTable.addRef := @ITransactionImpl_addRefDispatcher; + ITransactionImpl_vTable.release := @ITransactionImpl_releaseDispatcher; + ITransactionImpl_vTable.getInfo := @ITransactionImpl_getInfoDispatcher; + ITransactionImpl_vTable.prepare := @ITransactionImpl_prepareDispatcher; + ITransactionImpl_vTable.commit := @ITransactionImpl_commitDispatcher; + ITransactionImpl_vTable.commitRetaining := @ITransactionImpl_commitRetainingDispatcher; + ITransactionImpl_vTable.rollback := @ITransactionImpl_rollbackDispatcher; + ITransactionImpl_vTable.rollbackRetaining := @ITransactionImpl_rollbackRetainingDispatcher; + ITransactionImpl_vTable.disconnect := @ITransactionImpl_disconnectDispatcher; + ITransactionImpl_vTable.join := @ITransactionImpl_joinDispatcher; + ITransactionImpl_vTable.validate := @ITransactionImpl_validateDispatcher; + ITransactionImpl_vTable.enterDtc := @ITransactionImpl_enterDtcDispatcher; + + IMessageMetadataImpl_vTable := MessageMetadataVTable.create; + IMessageMetadataImpl_vTable.version := 17; + IMessageMetadataImpl_vTable.addRef := @IMessageMetadataImpl_addRefDispatcher; + IMessageMetadataImpl_vTable.release := @IMessageMetadataImpl_releaseDispatcher; + IMessageMetadataImpl_vTable.getCount := @IMessageMetadataImpl_getCountDispatcher; + IMessageMetadataImpl_vTable.getField := @IMessageMetadataImpl_getFieldDispatcher; + IMessageMetadataImpl_vTable.getRelation := @IMessageMetadataImpl_getRelationDispatcher; + IMessageMetadataImpl_vTable.getOwner := @IMessageMetadataImpl_getOwnerDispatcher; + IMessageMetadataImpl_vTable.getAlias := @IMessageMetadataImpl_getAliasDispatcher; + IMessageMetadataImpl_vTable.getType := @IMessageMetadataImpl_getTypeDispatcher; + IMessageMetadataImpl_vTable.isNullable := @IMessageMetadataImpl_isNullableDispatcher; + IMessageMetadataImpl_vTable.getSubType := @IMessageMetadataImpl_getSubTypeDispatcher; + IMessageMetadataImpl_vTable.getLength := @IMessageMetadataImpl_getLengthDispatcher; + IMessageMetadataImpl_vTable.getScale := @IMessageMetadataImpl_getScaleDispatcher; + IMessageMetadataImpl_vTable.getCharSet := @IMessageMetadataImpl_getCharSetDispatcher; + IMessageMetadataImpl_vTable.getOffset := @IMessageMetadataImpl_getOffsetDispatcher; + IMessageMetadataImpl_vTable.getNullOffset := @IMessageMetadataImpl_getNullOffsetDispatcher; + IMessageMetadataImpl_vTable.getBuilder := @IMessageMetadataImpl_getBuilderDispatcher; + IMessageMetadataImpl_vTable.getMessageLength := @IMessageMetadataImpl_getMessageLengthDispatcher; + + IMetadataBuilderImpl_vTable := MetadataBuilderVTable.create; + IMetadataBuilderImpl_vTable.version := 12; + IMetadataBuilderImpl_vTable.addRef := @IMetadataBuilderImpl_addRefDispatcher; + IMetadataBuilderImpl_vTable.release := @IMetadataBuilderImpl_releaseDispatcher; + IMetadataBuilderImpl_vTable.setType := @IMetadataBuilderImpl_setTypeDispatcher; + IMetadataBuilderImpl_vTable.setSubType := @IMetadataBuilderImpl_setSubTypeDispatcher; + IMetadataBuilderImpl_vTable.setLength := @IMetadataBuilderImpl_setLengthDispatcher; + IMetadataBuilderImpl_vTable.setCharSet := @IMetadataBuilderImpl_setCharSetDispatcher; + IMetadataBuilderImpl_vTable.setScale := @IMetadataBuilderImpl_setScaleDispatcher; + IMetadataBuilderImpl_vTable.truncate := @IMetadataBuilderImpl_truncateDispatcher; + IMetadataBuilderImpl_vTable.moveNameToIndex := @IMetadataBuilderImpl_moveNameToIndexDispatcher; + IMetadataBuilderImpl_vTable.remove := @IMetadataBuilderImpl_removeDispatcher; + IMetadataBuilderImpl_vTable.addField := @IMetadataBuilderImpl_addFieldDispatcher; + IMetadataBuilderImpl_vTable.getMetadata := @IMetadataBuilderImpl_getMetadataDispatcher; + + IResultSetImpl_vTable := ResultSetVTable.create; + IResultSetImpl_vTable.version := 13; + IResultSetImpl_vTable.addRef := @IResultSetImpl_addRefDispatcher; + IResultSetImpl_vTable.release := @IResultSetImpl_releaseDispatcher; + IResultSetImpl_vTable.fetchNext := @IResultSetImpl_fetchNextDispatcher; + IResultSetImpl_vTable.fetchPrior := @IResultSetImpl_fetchPriorDispatcher; + IResultSetImpl_vTable.fetchFirst := @IResultSetImpl_fetchFirstDispatcher; + IResultSetImpl_vTable.fetchLast := @IResultSetImpl_fetchLastDispatcher; + IResultSetImpl_vTable.fetchAbsolute := @IResultSetImpl_fetchAbsoluteDispatcher; + IResultSetImpl_vTable.fetchRelative := @IResultSetImpl_fetchRelativeDispatcher; + IResultSetImpl_vTable.isEof := @IResultSetImpl_isEofDispatcher; + IResultSetImpl_vTable.isBof := @IResultSetImpl_isBofDispatcher; + IResultSetImpl_vTable.getMetadata := @IResultSetImpl_getMetadataDispatcher; + IResultSetImpl_vTable.close := @IResultSetImpl_closeDispatcher; + IResultSetImpl_vTable.setDelayedOutputFormat := @IResultSetImpl_setDelayedOutputFormatDispatcher; + + IStatementImpl_vTable := StatementVTable.create; + IStatementImpl_vTable.version := 13; + IStatementImpl_vTable.addRef := @IStatementImpl_addRefDispatcher; + IStatementImpl_vTable.release := @IStatementImpl_releaseDispatcher; + IStatementImpl_vTable.getInfo := @IStatementImpl_getInfoDispatcher; + IStatementImpl_vTable.getType := @IStatementImpl_getTypeDispatcher; + IStatementImpl_vTable.getPlan := @IStatementImpl_getPlanDispatcher; + IStatementImpl_vTable.getAffectedRecords := @IStatementImpl_getAffectedRecordsDispatcher; + IStatementImpl_vTable.getInputMetadata := @IStatementImpl_getInputMetadataDispatcher; + IStatementImpl_vTable.getOutputMetadata := @IStatementImpl_getOutputMetadataDispatcher; + IStatementImpl_vTable.execute := @IStatementImpl_executeDispatcher; + IStatementImpl_vTable.openCursor := @IStatementImpl_openCursorDispatcher; + IStatementImpl_vTable.setCursorName := @IStatementImpl_setCursorNameDispatcher; + IStatementImpl_vTable.free := @IStatementImpl_freeDispatcher; + IStatementImpl_vTable.getFlags := @IStatementImpl_getFlagsDispatcher; + + IRequestImpl_vTable := RequestVTable.create; + IRequestImpl_vTable.version := 9; + IRequestImpl_vTable.addRef := @IRequestImpl_addRefDispatcher; + IRequestImpl_vTable.release := @IRequestImpl_releaseDispatcher; + IRequestImpl_vTable.receive := @IRequestImpl_receiveDispatcher; + IRequestImpl_vTable.send := @IRequestImpl_sendDispatcher; + IRequestImpl_vTable.getInfo := @IRequestImpl_getInfoDispatcher; + IRequestImpl_vTable.start := @IRequestImpl_startDispatcher; + IRequestImpl_vTable.startAndSend := @IRequestImpl_startAndSendDispatcher; + IRequestImpl_vTable.unwind := @IRequestImpl_unwindDispatcher; + IRequestImpl_vTable.free := @IRequestImpl_freeDispatcher; + + IEventsImpl_vTable := EventsVTable.create; + IEventsImpl_vTable.version := 3; + IEventsImpl_vTable.addRef := @IEventsImpl_addRefDispatcher; + IEventsImpl_vTable.release := @IEventsImpl_releaseDispatcher; + IEventsImpl_vTable.cancel := @IEventsImpl_cancelDispatcher; + + IAttachmentImpl_vTable := AttachmentVTable.create; + IAttachmentImpl_vTable.version := 20; + IAttachmentImpl_vTable.addRef := @IAttachmentImpl_addRefDispatcher; + IAttachmentImpl_vTable.release := @IAttachmentImpl_releaseDispatcher; + IAttachmentImpl_vTable.getInfo := @IAttachmentImpl_getInfoDispatcher; + IAttachmentImpl_vTable.startTransaction := @IAttachmentImpl_startTransactionDispatcher; + IAttachmentImpl_vTable.reconnectTransaction := @IAttachmentImpl_reconnectTransactionDispatcher; + IAttachmentImpl_vTable.compileRequest := @IAttachmentImpl_compileRequestDispatcher; + IAttachmentImpl_vTable.transactRequest := @IAttachmentImpl_transactRequestDispatcher; + IAttachmentImpl_vTable.createBlob := @IAttachmentImpl_createBlobDispatcher; + IAttachmentImpl_vTable.openBlob := @IAttachmentImpl_openBlobDispatcher; + IAttachmentImpl_vTable.getSlice := @IAttachmentImpl_getSliceDispatcher; + IAttachmentImpl_vTable.putSlice := @IAttachmentImpl_putSliceDispatcher; + IAttachmentImpl_vTable.executeDyn := @IAttachmentImpl_executeDynDispatcher; + IAttachmentImpl_vTable.prepare := @IAttachmentImpl_prepareDispatcher; + IAttachmentImpl_vTable.execute := @IAttachmentImpl_executeDispatcher; + IAttachmentImpl_vTable.openCursor := @IAttachmentImpl_openCursorDispatcher; + IAttachmentImpl_vTable.queEvents := @IAttachmentImpl_queEventsDispatcher; + IAttachmentImpl_vTable.cancelOperation := @IAttachmentImpl_cancelOperationDispatcher; + IAttachmentImpl_vTable.ping := @IAttachmentImpl_pingDispatcher; + IAttachmentImpl_vTable.detach := @IAttachmentImpl_detachDispatcher; + IAttachmentImpl_vTable.dropDatabase := @IAttachmentImpl_dropDatabaseDispatcher; + + IServiceImpl_vTable := ServiceVTable.create; + IServiceImpl_vTable.version := 5; + IServiceImpl_vTable.addRef := @IServiceImpl_addRefDispatcher; + IServiceImpl_vTable.release := @IServiceImpl_releaseDispatcher; + IServiceImpl_vTable.detach := @IServiceImpl_detachDispatcher; + IServiceImpl_vTable.query := @IServiceImpl_queryDispatcher; + IServiceImpl_vTable.start := @IServiceImpl_startDispatcher; + + IProviderImpl_vTable := ProviderVTable.create; + IProviderImpl_vTable.version := 9; + IProviderImpl_vTable.addRef := @IProviderImpl_addRefDispatcher; + IProviderImpl_vTable.release := @IProviderImpl_releaseDispatcher; + IProviderImpl_vTable.setOwner := @IProviderImpl_setOwnerDispatcher; + IProviderImpl_vTable.getOwner := @IProviderImpl_getOwnerDispatcher; + IProviderImpl_vTable.attachDatabase := @IProviderImpl_attachDatabaseDispatcher; + IProviderImpl_vTable.createDatabase := @IProviderImpl_createDatabaseDispatcher; + IProviderImpl_vTable.attachServiceManager := @IProviderImpl_attachServiceManagerDispatcher; + IProviderImpl_vTable.shutdown := @IProviderImpl_shutdownDispatcher; + IProviderImpl_vTable.setDbCryptCallback := @IProviderImpl_setDbCryptCallbackDispatcher; + + IDtcStartImpl_vTable := DtcStartVTable.create; + IDtcStartImpl_vTable.version := 4; + IDtcStartImpl_vTable.dispose := @IDtcStartImpl_disposeDispatcher; + IDtcStartImpl_vTable.addAttachment := @IDtcStartImpl_addAttachmentDispatcher; + IDtcStartImpl_vTable.addWithTpb := @IDtcStartImpl_addWithTpbDispatcher; + IDtcStartImpl_vTable.start := @IDtcStartImpl_startDispatcher; + + IDtcImpl_vTable := DtcVTable.create; + IDtcImpl_vTable.version := 2; + IDtcImpl_vTable.join := @IDtcImpl_joinDispatcher; + IDtcImpl_vTable.startBuilder := @IDtcImpl_startBuilderDispatcher; + + IAuthImpl_vTable := AuthVTable.create; + IAuthImpl_vTable.version := 4; + IAuthImpl_vTable.addRef := @IAuthImpl_addRefDispatcher; + IAuthImpl_vTable.release := @IAuthImpl_releaseDispatcher; + IAuthImpl_vTable.setOwner := @IAuthImpl_setOwnerDispatcher; + IAuthImpl_vTable.getOwner := @IAuthImpl_getOwnerDispatcher; + + IWriterImpl_vTable := WriterVTable.create; + IWriterImpl_vTable.version := 4; + IWriterImpl_vTable.reset := @IWriterImpl_resetDispatcher; + IWriterImpl_vTable.add := @IWriterImpl_addDispatcher; + IWriterImpl_vTable.setType := @IWriterImpl_setTypeDispatcher; + IWriterImpl_vTable.setDb := @IWriterImpl_setDbDispatcher; + + IServerBlockImpl_vTable := ServerBlockVTable.create; + IServerBlockImpl_vTable.version := 4; + IServerBlockImpl_vTable.getLogin := @IServerBlockImpl_getLoginDispatcher; + IServerBlockImpl_vTable.getData := @IServerBlockImpl_getDataDispatcher; + IServerBlockImpl_vTable.putData := @IServerBlockImpl_putDataDispatcher; + IServerBlockImpl_vTable.newKey := @IServerBlockImpl_newKeyDispatcher; + + IClientBlockImpl_vTable := ClientBlockVTable.create; + IClientBlockImpl_vTable.version := 7; + IClientBlockImpl_vTable.addRef := @IClientBlockImpl_addRefDispatcher; + IClientBlockImpl_vTable.release := @IClientBlockImpl_releaseDispatcher; + IClientBlockImpl_vTable.getLogin := @IClientBlockImpl_getLoginDispatcher; + IClientBlockImpl_vTable.getPassword := @IClientBlockImpl_getPasswordDispatcher; + IClientBlockImpl_vTable.getData := @IClientBlockImpl_getDataDispatcher; + IClientBlockImpl_vTable.putData := @IClientBlockImpl_putDataDispatcher; + IClientBlockImpl_vTable.newKey := @IClientBlockImpl_newKeyDispatcher; + + IServerImpl_vTable := ServerVTable.create; + IServerImpl_vTable.version := 5; + IServerImpl_vTable.addRef := @IServerImpl_addRefDispatcher; + IServerImpl_vTable.release := @IServerImpl_releaseDispatcher; + IServerImpl_vTable.setOwner := @IServerImpl_setOwnerDispatcher; + IServerImpl_vTable.getOwner := @IServerImpl_getOwnerDispatcher; + IServerImpl_vTable.authenticate := @IServerImpl_authenticateDispatcher; + + IClientImpl_vTable := ClientVTable.create; + IClientImpl_vTable.version := 5; + IClientImpl_vTable.addRef := @IClientImpl_addRefDispatcher; + IClientImpl_vTable.release := @IClientImpl_releaseDispatcher; + IClientImpl_vTable.setOwner := @IClientImpl_setOwnerDispatcher; + IClientImpl_vTable.getOwner := @IClientImpl_getOwnerDispatcher; + IClientImpl_vTable.authenticate := @IClientImpl_authenticateDispatcher; + + IUserFieldImpl_vTable := UserFieldVTable.create; + IUserFieldImpl_vTable.version := 3; + IUserFieldImpl_vTable.entered := @IUserFieldImpl_enteredDispatcher; + IUserFieldImpl_vTable.specified := @IUserFieldImpl_specifiedDispatcher; + IUserFieldImpl_vTable.setEntered := @IUserFieldImpl_setEnteredDispatcher; + + ICharUserFieldImpl_vTable := CharUserFieldVTable.create; + ICharUserFieldImpl_vTable.version := 5; + ICharUserFieldImpl_vTable.entered := @ICharUserFieldImpl_enteredDispatcher; + ICharUserFieldImpl_vTable.specified := @ICharUserFieldImpl_specifiedDispatcher; + ICharUserFieldImpl_vTable.setEntered := @ICharUserFieldImpl_setEnteredDispatcher; + ICharUserFieldImpl_vTable.get := @ICharUserFieldImpl_getDispatcher; + ICharUserFieldImpl_vTable.set_ := @ICharUserFieldImpl_set_Dispatcher; + + IIntUserFieldImpl_vTable := IntUserFieldVTable.create; + IIntUserFieldImpl_vTable.version := 5; + IIntUserFieldImpl_vTable.entered := @IIntUserFieldImpl_enteredDispatcher; + IIntUserFieldImpl_vTable.specified := @IIntUserFieldImpl_specifiedDispatcher; + IIntUserFieldImpl_vTable.setEntered := @IIntUserFieldImpl_setEnteredDispatcher; + IIntUserFieldImpl_vTable.get := @IIntUserFieldImpl_getDispatcher; + IIntUserFieldImpl_vTable.set_ := @IIntUserFieldImpl_set_Dispatcher; + + IUserImpl_vTable := UserVTable.create; + IUserImpl_vTable.version := 11; + IUserImpl_vTable.operation := @IUserImpl_operationDispatcher; + IUserImpl_vTable.userName := @IUserImpl_userNameDispatcher; + IUserImpl_vTable.password := @IUserImpl_passwordDispatcher; + IUserImpl_vTable.firstName := @IUserImpl_firstNameDispatcher; + IUserImpl_vTable.lastName := @IUserImpl_lastNameDispatcher; + IUserImpl_vTable.middleName := @IUserImpl_middleNameDispatcher; + IUserImpl_vTable.comment := @IUserImpl_commentDispatcher; + IUserImpl_vTable.attributes := @IUserImpl_attributesDispatcher; + IUserImpl_vTable.active := @IUserImpl_activeDispatcher; + IUserImpl_vTable.admin := @IUserImpl_adminDispatcher; + IUserImpl_vTable.clear := @IUserImpl_clearDispatcher; + + IListUsersImpl_vTable := ListUsersVTable.create; + IListUsersImpl_vTable.version := 1; + IListUsersImpl_vTable.list := @IListUsersImpl_listDispatcher; + + ILogonInfoImpl_vTable := LogonInfoVTable.create; + ILogonInfoImpl_vTable.version := 5; + ILogonInfoImpl_vTable.name := @ILogonInfoImpl_nameDispatcher; + ILogonInfoImpl_vTable.role := @ILogonInfoImpl_roleDispatcher; + ILogonInfoImpl_vTable.networkProtocol := @ILogonInfoImpl_networkProtocolDispatcher; + ILogonInfoImpl_vTable.remoteAddress := @ILogonInfoImpl_remoteAddressDispatcher; + ILogonInfoImpl_vTable.authBlock := @ILogonInfoImpl_authBlockDispatcher; + + IManagementImpl_vTable := ManagementVTable.create; + IManagementImpl_vTable.version := 8; + IManagementImpl_vTable.addRef := @IManagementImpl_addRefDispatcher; + IManagementImpl_vTable.release := @IManagementImpl_releaseDispatcher; + IManagementImpl_vTable.setOwner := @IManagementImpl_setOwnerDispatcher; + IManagementImpl_vTable.getOwner := @IManagementImpl_getOwnerDispatcher; + IManagementImpl_vTable.start := @IManagementImpl_startDispatcher; + IManagementImpl_vTable.execute := @IManagementImpl_executeDispatcher; + IManagementImpl_vTable.commit := @IManagementImpl_commitDispatcher; + IManagementImpl_vTable.rollback := @IManagementImpl_rollbackDispatcher; + + IWireCryptPluginImpl_vTable := WireCryptPluginVTable.create; + IWireCryptPluginImpl_vTable.version := 8; + IWireCryptPluginImpl_vTable.addRef := @IWireCryptPluginImpl_addRefDispatcher; + IWireCryptPluginImpl_vTable.release := @IWireCryptPluginImpl_releaseDispatcher; + IWireCryptPluginImpl_vTable.setOwner := @IWireCryptPluginImpl_setOwnerDispatcher; + IWireCryptPluginImpl_vTable.getOwner := @IWireCryptPluginImpl_getOwnerDispatcher; + IWireCryptPluginImpl_vTable.getKnownTypes := @IWireCryptPluginImpl_getKnownTypesDispatcher; + IWireCryptPluginImpl_vTable.setKey := @IWireCryptPluginImpl_setKeyDispatcher; + IWireCryptPluginImpl_vTable.encrypt := @IWireCryptPluginImpl_encryptDispatcher; + IWireCryptPluginImpl_vTable.decrypt := @IWireCryptPluginImpl_decryptDispatcher; + + ICryptKeyCallbackImpl_vTable := CryptKeyCallbackVTable.create; + ICryptKeyCallbackImpl_vTable.version := 1; + ICryptKeyCallbackImpl_vTable.callback := @ICryptKeyCallbackImpl_callbackDispatcher; + + IKeyHolderPluginImpl_vTable := KeyHolderPluginVTable.create; + IKeyHolderPluginImpl_vTable.version := 6; + IKeyHolderPluginImpl_vTable.addRef := @IKeyHolderPluginImpl_addRefDispatcher; + IKeyHolderPluginImpl_vTable.release := @IKeyHolderPluginImpl_releaseDispatcher; + IKeyHolderPluginImpl_vTable.setOwner := @IKeyHolderPluginImpl_setOwnerDispatcher; + IKeyHolderPluginImpl_vTable.getOwner := @IKeyHolderPluginImpl_getOwnerDispatcher; + IKeyHolderPluginImpl_vTable.keyCallback := @IKeyHolderPluginImpl_keyCallbackDispatcher; + IKeyHolderPluginImpl_vTable.keyHandle := @IKeyHolderPluginImpl_keyHandleDispatcher; + + IDbCryptPluginImpl_vTable := DbCryptPluginVTable.create; + IDbCryptPluginImpl_vTable.version := 7; + IDbCryptPluginImpl_vTable.addRef := @IDbCryptPluginImpl_addRefDispatcher; + IDbCryptPluginImpl_vTable.release := @IDbCryptPluginImpl_releaseDispatcher; + IDbCryptPluginImpl_vTable.setOwner := @IDbCryptPluginImpl_setOwnerDispatcher; + IDbCryptPluginImpl_vTable.getOwner := @IDbCryptPluginImpl_getOwnerDispatcher; + IDbCryptPluginImpl_vTable.setKey := @IDbCryptPluginImpl_setKeyDispatcher; + IDbCryptPluginImpl_vTable.encrypt := @IDbCryptPluginImpl_encryptDispatcher; + IDbCryptPluginImpl_vTable.decrypt := @IDbCryptPluginImpl_decryptDispatcher; + + IExternalContextImpl_vTable := ExternalContextVTable.create; + IExternalContextImpl_vTable.version := 10; + IExternalContextImpl_vTable.getMaster := @IExternalContextImpl_getMasterDispatcher; + IExternalContextImpl_vTable.getEngine := @IExternalContextImpl_getEngineDispatcher; + IExternalContextImpl_vTable.getAttachment := @IExternalContextImpl_getAttachmentDispatcher; + IExternalContextImpl_vTable.getTransaction := @IExternalContextImpl_getTransactionDispatcher; + IExternalContextImpl_vTable.getUserName := @IExternalContextImpl_getUserNameDispatcher; + IExternalContextImpl_vTable.getDatabaseName := @IExternalContextImpl_getDatabaseNameDispatcher; + IExternalContextImpl_vTable.getClientCharSet := @IExternalContextImpl_getClientCharSetDispatcher; + IExternalContextImpl_vTable.obtainInfoCode := @IExternalContextImpl_obtainInfoCodeDispatcher; + IExternalContextImpl_vTable.getInfo := @IExternalContextImpl_getInfoDispatcher; + IExternalContextImpl_vTable.setInfo := @IExternalContextImpl_setInfoDispatcher; + + IExternalResultSetImpl_vTable := ExternalResultSetVTable.create; + IExternalResultSetImpl_vTable.version := 2; + IExternalResultSetImpl_vTable.dispose := @IExternalResultSetImpl_disposeDispatcher; + IExternalResultSetImpl_vTable.fetch := @IExternalResultSetImpl_fetchDispatcher; + + IExternalFunctionImpl_vTable := ExternalFunctionVTable.create; + IExternalFunctionImpl_vTable.version := 3; + IExternalFunctionImpl_vTable.dispose := @IExternalFunctionImpl_disposeDispatcher; + IExternalFunctionImpl_vTable.getCharSet := @IExternalFunctionImpl_getCharSetDispatcher; + IExternalFunctionImpl_vTable.execute := @IExternalFunctionImpl_executeDispatcher; + + IExternalProcedureImpl_vTable := ExternalProcedureVTable.create; + IExternalProcedureImpl_vTable.version := 3; + IExternalProcedureImpl_vTable.dispose := @IExternalProcedureImpl_disposeDispatcher; + IExternalProcedureImpl_vTable.getCharSet := @IExternalProcedureImpl_getCharSetDispatcher; + IExternalProcedureImpl_vTable.open := @IExternalProcedureImpl_openDispatcher; + + IExternalTriggerImpl_vTable := ExternalTriggerVTable.create; + IExternalTriggerImpl_vTable.version := 3; + IExternalTriggerImpl_vTable.dispose := @IExternalTriggerImpl_disposeDispatcher; + IExternalTriggerImpl_vTable.getCharSet := @IExternalTriggerImpl_getCharSetDispatcher; + IExternalTriggerImpl_vTable.execute := @IExternalTriggerImpl_executeDispatcher; + + IRoutineMetadataImpl_vTable := RoutineMetadataVTable.create; + IRoutineMetadataImpl_vTable.version := 9; + IRoutineMetadataImpl_vTable.getPackage := @IRoutineMetadataImpl_getPackageDispatcher; + IRoutineMetadataImpl_vTable.getName := @IRoutineMetadataImpl_getNameDispatcher; + IRoutineMetadataImpl_vTable.getEntryPoint := @IRoutineMetadataImpl_getEntryPointDispatcher; + IRoutineMetadataImpl_vTable.getBody := @IRoutineMetadataImpl_getBodyDispatcher; + IRoutineMetadataImpl_vTable.getInputMetadata := @IRoutineMetadataImpl_getInputMetadataDispatcher; + IRoutineMetadataImpl_vTable.getOutputMetadata := @IRoutineMetadataImpl_getOutputMetadataDispatcher; + IRoutineMetadataImpl_vTable.getTriggerMetadata := @IRoutineMetadataImpl_getTriggerMetadataDispatcher; + IRoutineMetadataImpl_vTable.getTriggerTable := @IRoutineMetadataImpl_getTriggerTableDispatcher; + IRoutineMetadataImpl_vTable.getTriggerType := @IRoutineMetadataImpl_getTriggerTypeDispatcher; + + IExternalEngineImpl_vTable := ExternalEngineVTable.create; + IExternalEngineImpl_vTable.version := 10; + IExternalEngineImpl_vTable.addRef := @IExternalEngineImpl_addRefDispatcher; + IExternalEngineImpl_vTable.release := @IExternalEngineImpl_releaseDispatcher; + IExternalEngineImpl_vTable.setOwner := @IExternalEngineImpl_setOwnerDispatcher; + IExternalEngineImpl_vTable.getOwner := @IExternalEngineImpl_getOwnerDispatcher; + IExternalEngineImpl_vTable.open := @IExternalEngineImpl_openDispatcher; + IExternalEngineImpl_vTable.openAttachment := @IExternalEngineImpl_openAttachmentDispatcher; + IExternalEngineImpl_vTable.closeAttachment := @IExternalEngineImpl_closeAttachmentDispatcher; + IExternalEngineImpl_vTable.makeFunction := @IExternalEngineImpl_makeFunctionDispatcher; + IExternalEngineImpl_vTable.makeProcedure := @IExternalEngineImpl_makeProcedureDispatcher; + IExternalEngineImpl_vTable.makeTrigger := @IExternalEngineImpl_makeTriggerDispatcher; + + ITimerImpl_vTable := TimerVTable.create; + ITimerImpl_vTable.version := 3; + ITimerImpl_vTable.addRef := @ITimerImpl_addRefDispatcher; + ITimerImpl_vTable.release := @ITimerImpl_releaseDispatcher; + ITimerImpl_vTable.handler := @ITimerImpl_handlerDispatcher; + + ITimerControlImpl_vTable := TimerControlVTable.create; + ITimerControlImpl_vTable.version := 2; + ITimerControlImpl_vTable.start := @ITimerControlImpl_startDispatcher; + ITimerControlImpl_vTable.stop := @ITimerControlImpl_stopDispatcher; + + IVersionCallbackImpl_vTable := VersionCallbackVTable.create; + IVersionCallbackImpl_vTable.version := 1; + IVersionCallbackImpl_vTable.callback := @IVersionCallbackImpl_callbackDispatcher; + + IUtilImpl_vTable := UtilVTable.create; + IUtilImpl_vTable.version := 13; + IUtilImpl_vTable.getFbVersion := @IUtilImpl_getFbVersionDispatcher; + IUtilImpl_vTable.loadBlob := @IUtilImpl_loadBlobDispatcher; + IUtilImpl_vTable.dumpBlob := @IUtilImpl_dumpBlobDispatcher; + IUtilImpl_vTable.getPerfCounters := @IUtilImpl_getPerfCountersDispatcher; + IUtilImpl_vTable.executeCreateDatabase := @IUtilImpl_executeCreateDatabaseDispatcher; + IUtilImpl_vTable.decodeDate := @IUtilImpl_decodeDateDispatcher; + IUtilImpl_vTable.decodeTime := @IUtilImpl_decodeTimeDispatcher; + IUtilImpl_vTable.encodeDate := @IUtilImpl_encodeDateDispatcher; + IUtilImpl_vTable.encodeTime := @IUtilImpl_encodeTimeDispatcher; + IUtilImpl_vTable.formatStatus := @IUtilImpl_formatStatusDispatcher; + IUtilImpl_vTable.getClientVersion := @IUtilImpl_getClientVersionDispatcher; + IUtilImpl_vTable.getXpbBuilder := @IUtilImpl_getXpbBuilderDispatcher; + IUtilImpl_vTable.setOffsets := @IUtilImpl_setOffsetsDispatcher; + + IOffsetsCallbackImpl_vTable := OffsetsCallbackVTable.create; + IOffsetsCallbackImpl_vTable.version := 1; + IOffsetsCallbackImpl_vTable.setOffset := @IOffsetsCallbackImpl_setOffsetDispatcher; + + IXpbBuilderImpl_vTable := XpbBuilderVTable.create; + IXpbBuilderImpl_vTable.version := 21; + IXpbBuilderImpl_vTable.dispose := @IXpbBuilderImpl_disposeDispatcher; + IXpbBuilderImpl_vTable.clear := @IXpbBuilderImpl_clearDispatcher; + IXpbBuilderImpl_vTable.removeCurrent := @IXpbBuilderImpl_removeCurrentDispatcher; + IXpbBuilderImpl_vTable.insertInt := @IXpbBuilderImpl_insertIntDispatcher; + IXpbBuilderImpl_vTable.insertBigInt := @IXpbBuilderImpl_insertBigIntDispatcher; + IXpbBuilderImpl_vTable.insertBytes := @IXpbBuilderImpl_insertBytesDispatcher; + IXpbBuilderImpl_vTable.insertString := @IXpbBuilderImpl_insertStringDispatcher; + IXpbBuilderImpl_vTable.insertTag := @IXpbBuilderImpl_insertTagDispatcher; + IXpbBuilderImpl_vTable.isEof := @IXpbBuilderImpl_isEofDispatcher; + IXpbBuilderImpl_vTable.moveNext := @IXpbBuilderImpl_moveNextDispatcher; + IXpbBuilderImpl_vTable.rewind := @IXpbBuilderImpl_rewindDispatcher; + IXpbBuilderImpl_vTable.findFirst := @IXpbBuilderImpl_findFirstDispatcher; + IXpbBuilderImpl_vTable.findNext := @IXpbBuilderImpl_findNextDispatcher; + IXpbBuilderImpl_vTable.getTag := @IXpbBuilderImpl_getTagDispatcher; + IXpbBuilderImpl_vTable.getLength := @IXpbBuilderImpl_getLengthDispatcher; + IXpbBuilderImpl_vTable.getInt := @IXpbBuilderImpl_getIntDispatcher; + IXpbBuilderImpl_vTable.getBigInt := @IXpbBuilderImpl_getBigIntDispatcher; + IXpbBuilderImpl_vTable.getString := @IXpbBuilderImpl_getStringDispatcher; + IXpbBuilderImpl_vTable.getBytes := @IXpbBuilderImpl_getBytesDispatcher; + IXpbBuilderImpl_vTable.getBufferLength := @IXpbBuilderImpl_getBufferLengthDispatcher; + IXpbBuilderImpl_vTable.getBuffer := @IXpbBuilderImpl_getBufferDispatcher; + + ITraceConnectionImpl_vTable := TraceConnectionVTable.create; + ITraceConnectionImpl_vTable.version := 9; + ITraceConnectionImpl_vTable.getKind := @ITraceConnectionImpl_getKindDispatcher; + ITraceConnectionImpl_vTable.getProcessID := @ITraceConnectionImpl_getProcessIDDispatcher; + ITraceConnectionImpl_vTable.getUserName := @ITraceConnectionImpl_getUserNameDispatcher; + ITraceConnectionImpl_vTable.getRoleName := @ITraceConnectionImpl_getRoleNameDispatcher; + ITraceConnectionImpl_vTable.getCharSet := @ITraceConnectionImpl_getCharSetDispatcher; + ITraceConnectionImpl_vTable.getRemoteProtocol := @ITraceConnectionImpl_getRemoteProtocolDispatcher; + ITraceConnectionImpl_vTable.getRemoteAddress := @ITraceConnectionImpl_getRemoteAddressDispatcher; + ITraceConnectionImpl_vTable.getRemoteProcessID := @ITraceConnectionImpl_getRemoteProcessIDDispatcher; + ITraceConnectionImpl_vTable.getRemoteProcessName := @ITraceConnectionImpl_getRemoteProcessNameDispatcher; + + ITraceDatabaseConnectionImpl_vTable := TraceDatabaseConnectionVTable.create; + ITraceDatabaseConnectionImpl_vTable.version := 11; + ITraceDatabaseConnectionImpl_vTable.getKind := @ITraceDatabaseConnectionImpl_getKindDispatcher; + ITraceDatabaseConnectionImpl_vTable.getProcessID := @ITraceDatabaseConnectionImpl_getProcessIDDispatcher; + ITraceDatabaseConnectionImpl_vTable.getUserName := @ITraceDatabaseConnectionImpl_getUserNameDispatcher; + ITraceDatabaseConnectionImpl_vTable.getRoleName := @ITraceDatabaseConnectionImpl_getRoleNameDispatcher; + ITraceDatabaseConnectionImpl_vTable.getCharSet := @ITraceDatabaseConnectionImpl_getCharSetDispatcher; + ITraceDatabaseConnectionImpl_vTable.getRemoteProtocol := @ITraceDatabaseConnectionImpl_getRemoteProtocolDispatcher; + ITraceDatabaseConnectionImpl_vTable.getRemoteAddress := @ITraceDatabaseConnectionImpl_getRemoteAddressDispatcher; + ITraceDatabaseConnectionImpl_vTable.getRemoteProcessID := @ITraceDatabaseConnectionImpl_getRemoteProcessIDDispatcher; + ITraceDatabaseConnectionImpl_vTable.getRemoteProcessName := @ITraceDatabaseConnectionImpl_getRemoteProcessNameDispatcher; + ITraceDatabaseConnectionImpl_vTable.getConnectionID := @ITraceDatabaseConnectionImpl_getConnectionIDDispatcher; + ITraceDatabaseConnectionImpl_vTable.getDatabaseName := @ITraceDatabaseConnectionImpl_getDatabaseNameDispatcher; + + ITraceTransactionImpl_vTable := TraceTransactionVTable.create; + ITraceTransactionImpl_vTable.version := 5; + ITraceTransactionImpl_vTable.getTransactionID := @ITraceTransactionImpl_getTransactionIDDispatcher; + ITraceTransactionImpl_vTable.getReadOnly := @ITraceTransactionImpl_getReadOnlyDispatcher; + ITraceTransactionImpl_vTable.getWait := @ITraceTransactionImpl_getWaitDispatcher; + ITraceTransactionImpl_vTable.getIsolation := @ITraceTransactionImpl_getIsolationDispatcher; + ITraceTransactionImpl_vTable.getPerf := @ITraceTransactionImpl_getPerfDispatcher; + + ITraceParamsImpl_vTable := TraceParamsVTable.create; + ITraceParamsImpl_vTable.version := 2; + ITraceParamsImpl_vTable.getCount := @ITraceParamsImpl_getCountDispatcher; + ITraceParamsImpl_vTable.getParam := @ITraceParamsImpl_getParamDispatcher; + + ITraceStatementImpl_vTable := TraceStatementVTable.create; + ITraceStatementImpl_vTable.version := 2; + ITraceStatementImpl_vTable.getStmtID := @ITraceStatementImpl_getStmtIDDispatcher; + ITraceStatementImpl_vTable.getPerf := @ITraceStatementImpl_getPerfDispatcher; + + ITraceSQLStatementImpl_vTable := TraceSQLStatementVTable.create; + ITraceSQLStatementImpl_vTable.version := 7; + ITraceSQLStatementImpl_vTable.getStmtID := @ITraceSQLStatementImpl_getStmtIDDispatcher; + ITraceSQLStatementImpl_vTable.getPerf := @ITraceSQLStatementImpl_getPerfDispatcher; + ITraceSQLStatementImpl_vTable.getText := @ITraceSQLStatementImpl_getTextDispatcher; + ITraceSQLStatementImpl_vTable.getPlan := @ITraceSQLStatementImpl_getPlanDispatcher; + ITraceSQLStatementImpl_vTable.getInputs := @ITraceSQLStatementImpl_getInputsDispatcher; + ITraceSQLStatementImpl_vTable.getTextUTF8 := @ITraceSQLStatementImpl_getTextUTF8Dispatcher; + ITraceSQLStatementImpl_vTable.getExplainedPlan := @ITraceSQLStatementImpl_getExplainedPlanDispatcher; + + ITraceBLRStatementImpl_vTable := TraceBLRStatementVTable.create; + ITraceBLRStatementImpl_vTable.version := 5; + ITraceBLRStatementImpl_vTable.getStmtID := @ITraceBLRStatementImpl_getStmtIDDispatcher; + ITraceBLRStatementImpl_vTable.getPerf := @ITraceBLRStatementImpl_getPerfDispatcher; + ITraceBLRStatementImpl_vTable.getData := @ITraceBLRStatementImpl_getDataDispatcher; + ITraceBLRStatementImpl_vTable.getDataLength := @ITraceBLRStatementImpl_getDataLengthDispatcher; + ITraceBLRStatementImpl_vTable.getText := @ITraceBLRStatementImpl_getTextDispatcher; + + ITraceDYNRequestImpl_vTable := TraceDYNRequestVTable.create; + ITraceDYNRequestImpl_vTable.version := 3; + ITraceDYNRequestImpl_vTable.getData := @ITraceDYNRequestImpl_getDataDispatcher; + ITraceDYNRequestImpl_vTable.getDataLength := @ITraceDYNRequestImpl_getDataLengthDispatcher; + ITraceDYNRequestImpl_vTable.getText := @ITraceDYNRequestImpl_getTextDispatcher; + + ITraceContextVariableImpl_vTable := TraceContextVariableVTable.create; + ITraceContextVariableImpl_vTable.version := 3; + ITraceContextVariableImpl_vTable.getNameSpace := @ITraceContextVariableImpl_getNameSpaceDispatcher; + ITraceContextVariableImpl_vTable.getVarName := @ITraceContextVariableImpl_getVarNameDispatcher; + ITraceContextVariableImpl_vTable.getVarValue := @ITraceContextVariableImpl_getVarValueDispatcher; + + ITraceProcedureImpl_vTable := TraceProcedureVTable.create; + ITraceProcedureImpl_vTable.version := 3; + ITraceProcedureImpl_vTable.getProcName := @ITraceProcedureImpl_getProcNameDispatcher; + ITraceProcedureImpl_vTable.getInputs := @ITraceProcedureImpl_getInputsDispatcher; + ITraceProcedureImpl_vTable.getPerf := @ITraceProcedureImpl_getPerfDispatcher; + + ITraceFunctionImpl_vTable := TraceFunctionVTable.create; + ITraceFunctionImpl_vTable.version := 4; + ITraceFunctionImpl_vTable.getFuncName := @ITraceFunctionImpl_getFuncNameDispatcher; + ITraceFunctionImpl_vTable.getInputs := @ITraceFunctionImpl_getInputsDispatcher; + ITraceFunctionImpl_vTable.getResult := @ITraceFunctionImpl_getResultDispatcher; + ITraceFunctionImpl_vTable.getPerf := @ITraceFunctionImpl_getPerfDispatcher; + + ITraceTriggerImpl_vTable := TraceTriggerVTable.create; + ITraceTriggerImpl_vTable.version := 5; + ITraceTriggerImpl_vTable.getTriggerName := @ITraceTriggerImpl_getTriggerNameDispatcher; + ITraceTriggerImpl_vTable.getRelationName := @ITraceTriggerImpl_getRelationNameDispatcher; + ITraceTriggerImpl_vTable.getAction := @ITraceTriggerImpl_getActionDispatcher; + ITraceTriggerImpl_vTable.getWhich := @ITraceTriggerImpl_getWhichDispatcher; + ITraceTriggerImpl_vTable.getPerf := @ITraceTriggerImpl_getPerfDispatcher; + + ITraceServiceConnectionImpl_vTable := TraceServiceConnectionVTable.create; + ITraceServiceConnectionImpl_vTable.version := 12; + ITraceServiceConnectionImpl_vTable.getKind := @ITraceServiceConnectionImpl_getKindDispatcher; + ITraceServiceConnectionImpl_vTable.getProcessID := @ITraceServiceConnectionImpl_getProcessIDDispatcher; + ITraceServiceConnectionImpl_vTable.getUserName := @ITraceServiceConnectionImpl_getUserNameDispatcher; + ITraceServiceConnectionImpl_vTable.getRoleName := @ITraceServiceConnectionImpl_getRoleNameDispatcher; + ITraceServiceConnectionImpl_vTable.getCharSet := @ITraceServiceConnectionImpl_getCharSetDispatcher; + ITraceServiceConnectionImpl_vTable.getRemoteProtocol := @ITraceServiceConnectionImpl_getRemoteProtocolDispatcher; + ITraceServiceConnectionImpl_vTable.getRemoteAddress := @ITraceServiceConnectionImpl_getRemoteAddressDispatcher; + ITraceServiceConnectionImpl_vTable.getRemoteProcessID := @ITraceServiceConnectionImpl_getRemoteProcessIDDispatcher; + ITraceServiceConnectionImpl_vTable.getRemoteProcessName := @ITraceServiceConnectionImpl_getRemoteProcessNameDispatcher; + ITraceServiceConnectionImpl_vTable.getServiceID := @ITraceServiceConnectionImpl_getServiceIDDispatcher; + ITraceServiceConnectionImpl_vTable.getServiceMgr := @ITraceServiceConnectionImpl_getServiceMgrDispatcher; + ITraceServiceConnectionImpl_vTable.getServiceName := @ITraceServiceConnectionImpl_getServiceNameDispatcher; + + ITraceStatusVectorImpl_vTable := TraceStatusVectorVTable.create; + ITraceStatusVectorImpl_vTable.version := 4; + ITraceStatusVectorImpl_vTable.hasError := @ITraceStatusVectorImpl_hasErrorDispatcher; + ITraceStatusVectorImpl_vTable.hasWarning := @ITraceStatusVectorImpl_hasWarningDispatcher; + ITraceStatusVectorImpl_vTable.getStatus := @ITraceStatusVectorImpl_getStatusDispatcher; + ITraceStatusVectorImpl_vTable.getText := @ITraceStatusVectorImpl_getTextDispatcher; + + ITraceSweepInfoImpl_vTable := TraceSweepInfoVTable.create; + ITraceSweepInfoImpl_vTable.version := 5; + ITraceSweepInfoImpl_vTable.getOIT := @ITraceSweepInfoImpl_getOITDispatcher; + ITraceSweepInfoImpl_vTable.getOST := @ITraceSweepInfoImpl_getOSTDispatcher; + ITraceSweepInfoImpl_vTable.getOAT := @ITraceSweepInfoImpl_getOATDispatcher; + ITraceSweepInfoImpl_vTable.getNext := @ITraceSweepInfoImpl_getNextDispatcher; + ITraceSweepInfoImpl_vTable.getPerf := @ITraceSweepInfoImpl_getPerfDispatcher; + + ITraceLogWriterImpl_vTable := TraceLogWriterVTable.create; + ITraceLogWriterImpl_vTable.version := 3; + ITraceLogWriterImpl_vTable.addRef := @ITraceLogWriterImpl_addRefDispatcher; + ITraceLogWriterImpl_vTable.release := @ITraceLogWriterImpl_releaseDispatcher; + ITraceLogWriterImpl_vTable.write := @ITraceLogWriterImpl_writeDispatcher; + + ITraceInitInfoImpl_vTable := TraceInitInfoVTable.create; + ITraceInitInfoImpl_vTable.version := 7; + ITraceInitInfoImpl_vTable.getConfigText := @ITraceInitInfoImpl_getConfigTextDispatcher; + ITraceInitInfoImpl_vTable.getTraceSessionID := @ITraceInitInfoImpl_getTraceSessionIDDispatcher; + ITraceInitInfoImpl_vTable.getTraceSessionName := @ITraceInitInfoImpl_getTraceSessionNameDispatcher; + ITraceInitInfoImpl_vTable.getFirebirdRootDirectory := @ITraceInitInfoImpl_getFirebirdRootDirectoryDispatcher; + ITraceInitInfoImpl_vTable.getDatabaseName := @ITraceInitInfoImpl_getDatabaseNameDispatcher; + ITraceInitInfoImpl_vTable.getConnection := @ITraceInitInfoImpl_getConnectionDispatcher; + ITraceInitInfoImpl_vTable.getLogWriter := @ITraceInitInfoImpl_getLogWriterDispatcher; + + ITracePluginImpl_vTable := TracePluginVTable.create; + ITracePluginImpl_vTable.version := 23; + ITracePluginImpl_vTable.addRef := @ITracePluginImpl_addRefDispatcher; + ITracePluginImpl_vTable.release := @ITracePluginImpl_releaseDispatcher; + ITracePluginImpl_vTable.trace_get_error := @ITracePluginImpl_trace_get_errorDispatcher; + ITracePluginImpl_vTable.trace_attach := @ITracePluginImpl_trace_attachDispatcher; + ITracePluginImpl_vTable.trace_detach := @ITracePluginImpl_trace_detachDispatcher; + ITracePluginImpl_vTable.trace_transaction_start := @ITracePluginImpl_trace_transaction_startDispatcher; + ITracePluginImpl_vTable.trace_transaction_end := @ITracePluginImpl_trace_transaction_endDispatcher; + ITracePluginImpl_vTable.trace_proc_execute := @ITracePluginImpl_trace_proc_executeDispatcher; + ITracePluginImpl_vTable.trace_trigger_execute := @ITracePluginImpl_trace_trigger_executeDispatcher; + ITracePluginImpl_vTable.trace_set_context := @ITracePluginImpl_trace_set_contextDispatcher; + ITracePluginImpl_vTable.trace_dsql_prepare := @ITracePluginImpl_trace_dsql_prepareDispatcher; + ITracePluginImpl_vTable.trace_dsql_free := @ITracePluginImpl_trace_dsql_freeDispatcher; + ITracePluginImpl_vTable.trace_dsql_execute := @ITracePluginImpl_trace_dsql_executeDispatcher; + ITracePluginImpl_vTable.trace_blr_compile := @ITracePluginImpl_trace_blr_compileDispatcher; + ITracePluginImpl_vTable.trace_blr_execute := @ITracePluginImpl_trace_blr_executeDispatcher; + ITracePluginImpl_vTable.trace_dyn_execute := @ITracePluginImpl_trace_dyn_executeDispatcher; + ITracePluginImpl_vTable.trace_service_attach := @ITracePluginImpl_trace_service_attachDispatcher; + ITracePluginImpl_vTable.trace_service_start := @ITracePluginImpl_trace_service_startDispatcher; + ITracePluginImpl_vTable.trace_service_query := @ITracePluginImpl_trace_service_queryDispatcher; + ITracePluginImpl_vTable.trace_service_detach := @ITracePluginImpl_trace_service_detachDispatcher; + ITracePluginImpl_vTable.trace_event_error := @ITracePluginImpl_trace_event_errorDispatcher; + ITracePluginImpl_vTable.trace_event_sweep := @ITracePluginImpl_trace_event_sweepDispatcher; + ITracePluginImpl_vTable.trace_func_execute := @ITracePluginImpl_trace_func_executeDispatcher; + + ITraceFactoryImpl_vTable := TraceFactoryVTable.create; + ITraceFactoryImpl_vTable.version := 6; + ITraceFactoryImpl_vTable.addRef := @ITraceFactoryImpl_addRefDispatcher; + ITraceFactoryImpl_vTable.release := @ITraceFactoryImpl_releaseDispatcher; + ITraceFactoryImpl_vTable.setOwner := @ITraceFactoryImpl_setOwnerDispatcher; + ITraceFactoryImpl_vTable.getOwner := @ITraceFactoryImpl_getOwnerDispatcher; + ITraceFactoryImpl_vTable.trace_needs := @ITraceFactoryImpl_trace_needsDispatcher; + ITraceFactoryImpl_vTable.trace_create := @ITraceFactoryImpl_trace_createDispatcher; + + IUdrFunctionFactoryImpl_vTable := UdrFunctionFactoryVTable.create; + IUdrFunctionFactoryImpl_vTable.version := 3; + IUdrFunctionFactoryImpl_vTable.dispose := @IUdrFunctionFactoryImpl_disposeDispatcher; + IUdrFunctionFactoryImpl_vTable.setup := @IUdrFunctionFactoryImpl_setupDispatcher; + IUdrFunctionFactoryImpl_vTable.newItem := @IUdrFunctionFactoryImpl_newItemDispatcher; + + IUdrProcedureFactoryImpl_vTable := UdrProcedureFactoryVTable.create; + IUdrProcedureFactoryImpl_vTable.version := 3; + IUdrProcedureFactoryImpl_vTable.dispose := @IUdrProcedureFactoryImpl_disposeDispatcher; + IUdrProcedureFactoryImpl_vTable.setup := @IUdrProcedureFactoryImpl_setupDispatcher; + IUdrProcedureFactoryImpl_vTable.newItem := @IUdrProcedureFactoryImpl_newItemDispatcher; + + IUdrTriggerFactoryImpl_vTable := UdrTriggerFactoryVTable.create; + IUdrTriggerFactoryImpl_vTable.version := 3; + IUdrTriggerFactoryImpl_vTable.dispose := @IUdrTriggerFactoryImpl_disposeDispatcher; + IUdrTriggerFactoryImpl_vTable.setup := @IUdrTriggerFactoryImpl_setupDispatcher; + IUdrTriggerFactoryImpl_vTable.newItem := @IUdrTriggerFactoryImpl_newItemDispatcher; + + IUdrPluginImpl_vTable := UdrPluginVTable.create; + IUdrPluginImpl_vTable.version := 4; + IUdrPluginImpl_vTable.getMaster := @IUdrPluginImpl_getMasterDispatcher; + IUdrPluginImpl_vTable.registerFunction := @IUdrPluginImpl_registerFunctionDispatcher; + IUdrPluginImpl_vTable.registerProcedure := @IUdrPluginImpl_registerProcedureDispatcher; + IUdrPluginImpl_vTable.registerTrigger := @IUdrPluginImpl_registerTriggerDispatcher; + +finalization + IVersionedImpl_vTable.destroy; + IReferenceCountedImpl_vTable.destroy; + IDisposableImpl_vTable.destroy; + IStatusImpl_vTable.destroy; + IMasterImpl_vTable.destroy; + IPluginBaseImpl_vTable.destroy; + IPluginSetImpl_vTable.destroy; + IConfigEntryImpl_vTable.destroy; + IConfigImpl_vTable.destroy; + IFirebirdConfImpl_vTable.destroy; + IPluginConfigImpl_vTable.destroy; + IPluginFactoryImpl_vTable.destroy; + IPluginModuleImpl_vTable.destroy; + IPluginManagerImpl_vTable.destroy; + ICryptKeyImpl_vTable.destroy; + IConfigManagerImpl_vTable.destroy; + IEventCallbackImpl_vTable.destroy; + IBlobImpl_vTable.destroy; + ITransactionImpl_vTable.destroy; + IMessageMetadataImpl_vTable.destroy; + IMetadataBuilderImpl_vTable.destroy; + IResultSetImpl_vTable.destroy; + IStatementImpl_vTable.destroy; + IRequestImpl_vTable.destroy; + IEventsImpl_vTable.destroy; + IAttachmentImpl_vTable.destroy; + IServiceImpl_vTable.destroy; + IProviderImpl_vTable.destroy; + IDtcStartImpl_vTable.destroy; + IDtcImpl_vTable.destroy; + IAuthImpl_vTable.destroy; + IWriterImpl_vTable.destroy; + IServerBlockImpl_vTable.destroy; + IClientBlockImpl_vTable.destroy; + IServerImpl_vTable.destroy; + IClientImpl_vTable.destroy; + IUserFieldImpl_vTable.destroy; + ICharUserFieldImpl_vTable.destroy; + IIntUserFieldImpl_vTable.destroy; + IUserImpl_vTable.destroy; + IListUsersImpl_vTable.destroy; + ILogonInfoImpl_vTable.destroy; + IManagementImpl_vTable.destroy; + IWireCryptPluginImpl_vTable.destroy; + ICryptKeyCallbackImpl_vTable.destroy; + IKeyHolderPluginImpl_vTable.destroy; + IDbCryptPluginImpl_vTable.destroy; + IExternalContextImpl_vTable.destroy; + IExternalResultSetImpl_vTable.destroy; + IExternalFunctionImpl_vTable.destroy; + IExternalProcedureImpl_vTable.destroy; + IExternalTriggerImpl_vTable.destroy; + IRoutineMetadataImpl_vTable.destroy; + IExternalEngineImpl_vTable.destroy; + ITimerImpl_vTable.destroy; + ITimerControlImpl_vTable.destroy; + IVersionCallbackImpl_vTable.destroy; + IUtilImpl_vTable.destroy; + IOffsetsCallbackImpl_vTable.destroy; + IXpbBuilderImpl_vTable.destroy; + ITraceConnectionImpl_vTable.destroy; + ITraceDatabaseConnectionImpl_vTable.destroy; + ITraceTransactionImpl_vTable.destroy; + ITraceParamsImpl_vTable.destroy; + ITraceStatementImpl_vTable.destroy; + ITraceSQLStatementImpl_vTable.destroy; + ITraceBLRStatementImpl_vTable.destroy; + ITraceDYNRequestImpl_vTable.destroy; + ITraceContextVariableImpl_vTable.destroy; + ITraceProcedureImpl_vTable.destroy; + ITraceFunctionImpl_vTable.destroy; + ITraceTriggerImpl_vTable.destroy; + ITraceServiceConnectionImpl_vTable.destroy; + ITraceStatusVectorImpl_vTable.destroy; + ITraceSweepInfoImpl_vTable.destroy; + ITraceLogWriterImpl_vTable.destroy; + ITraceInitInfoImpl_vTable.destroy; + ITracePluginImpl_vTable.destroy; + ITraceFactoryImpl_vTable.destroy; + IUdrFunctionFactoryImpl_vTable.destroy; + IUdrProcedureFactoryImpl_vTable.destroy; + IUdrTriggerFactoryImpl_vTable.destroy; + IUdrPluginImpl_vTable.destroy; + +end. diff --git a/mseide-msegui/lib/common/db/ibase60.inc b/mseide-msegui/lib/common/db/ibase60.inc new file mode 100644 index 0000000..38c75cf --- /dev/null +++ b/mseide-msegui/lib/common/db/ibase60.inc @@ -0,0 +1,3241 @@ +{ +} +{$ifdef FPC}{$MODE objfpc}{$MACRO on}{$endif} + +interface + +{$IFDEF LinkDynamically} +uses + {$ifdef FPC}Dynlibs,{$else}{$endif} sysutils, msetypes{msestrings},msectypes; + +const + {$define cvcall} +{$ifdef mswindows} + {$define wincall} + fbembedlib: array[0..0] of filenamety = ('fbembed.dll'); + fbcgdslib: array[0..1] of filenamety = ('fbclient.dll','gds32.dll'); +{$else} + fbembedlib: array[0..4] of filenamety = ( + 'libfbembed.so.2.5','libfbembed.so.2.1','libfbembed.so.2', + 'libfbembed.so.1','libfbembed.so'); + fbcgdslib: array[0..3] of filenamety = ('libfbclient.so.2', + 'libfbclient.so.1','libfbclient.so','libgds.so'); +{$endif} + +var + useembeddedfirebird : boolean = false; + +procedure initializeibase60(const sonames: array of filenamety); + //[] = default +procedure releaseibase60; + +{$ENDIF} +(* +{$DEFINE extdeclvararg:= cdecl} + +{$IFDEF Unix} + {$DEFINE extdecl:=cdecl} +{ + const + gdslib = 'libgds.so'; + fbclib = 'libfbclient.so'; + fbembedlib = 'libfbembed.so'; +} +{$ENDIF} +{$IFDEF Win32} + {$DEFINE extdecl:=stdcall} +{ + const + gdslib = 'gds32.dll'; + fbclib = 'fbclient.dll'; + fbembedlib = 'fbembed.dll'; +} +{$ENDIF} +{$IFDEF Wince} + {$DEFINE extdecl:=stdcall} +{ + const + gdslib = 'gds32.dll'; + fbclib = 'fbclient.dll'; + fbembedlib = 'fbembed.dll'; +} +{$ENDIF} + +*) +type + { Unsigned types } + + UChar = Byte; + UShort = Word; + UInt = DWord; + ULong = DWord; + + { Signed types } + + Int = LongInt; + Long = LongInt; + Short = SmallInt; + Float = Single; + + { Pointers to basic types } + + PInt = ^Int; + PShort = ^Short; + PUShort = ^UShort; + PLong = ^Long; + PULong = ^ULong; + PFloat = ^Float; + PUChar = ^UChar; + PVoid = ^Pointer; + +{$ifdef FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} + + const + ISC_TRUE = 1; + ISC_FALSE = 0; + const + ISC__TRUE = ISC_TRUE; + ISC__FALSE = ISC_FALSE; + +Type + ISC_USHORT = word; + ISC_STATUS = ptrint; //defined as intptr_t in types_pub.h + ISC_INT64 = int64; + ISC_UINT64 = qword; + ISC_LONG = Longint; + + PISC_USHORT = ^ISC_USHORT; + PISC_STATUS = ^ISC_STATUS; + PPISC_STATUS = ^PISC_STATUS; + PISC_INT64 = ^ISC_INT64; + PISC_UINT64 = ^ISC_UINT64; + PISC_LONG = ^ISC_LONG; + + {$IFDEF CPU64} + FB_API_HANDLE = cuint; + {$ELSE} + FB_API_HANDLE = pointer; + {$ENDIF} + + + const + {$IFDEF CPU64} + FB_API_NULLHANDLE = 0; + {$ELSE} + FB_API_NULLHANDLE = nil; + {$ENDIF} + DSQL_close = 1; + DSQL_drop = 2; + + {!!MVC + Removed all ISC_FAR, ISC_EXPORT_VARARG and ISC_EXPORT + macros. + They confuse h2pas... + !!MVC } + { } + { Time & Date Support } + { } +{$ifndef _ISC_TIMESTAMP_} + + type + + ISC_DATE = longint; + ISC_TIME = dword; + ISC_TIMESTAMP = record + timestamp_date : ISC_DATE; + timestamp_time : ISC_TIME; + end; + TISC_DATE = ISC_DATE; + TISC_TIME = ISC_TIME; + TISC_TIMESTAMP = ISC_TIMESTAMP; + PISC_DATE = ^ISC_DATE; + PISC_TIME = ^ISC_TIME; + PISC_TIMESTAMP = ^ISC_TIMESTAMP; + const + _ISC_TIMESTAMP_ = 1; +{$endif} + + const + ISC_TIME_SECONDS_PRECISION = 10000; + ISC_TIME_SECONDS_PRECISION_SCALE = -4; + { } + { Blob id structure } + { } + +Type + + GDS_QUAD = record + gds_quad_high : ISC_LONG; + gds_quad_low : ISC_LONG; + end; + TGDS_QUAD = GDS_QUAD; + PGDS_QUAD = ^GDS_QUAD; + +Type + ISC_QUAD = GDS_QUAD; + TISC_QUAD = ISC_QUAD; + PISC_QUAD = ^ISC_QUAD; + +{ !!field redefinitions !! + isc_quad_high = gds_quad_high; + isc_quad_low = gds_quad_low; +} + +type + + ISC_ARRAY_BOUND = record + array_bound_lower : smallint; + array_bound_upper : smallint; + end; + TISC_ARRAY_BOUND = ISC_ARRAY_BOUND; + PISC_ARRAY_BOUND = ^ISC_ARRAY_BOUND; + + ISC_ARRAY_DESC = record + array_desc_dtype : byte; + array_desc_scale : char; + array_desc_length : word; + array_desc_field_name : array[0..31] of char; + array_desc_relation_name : array[0..31] of char; + array_desc_dimensions : smallint; + array_desc_flags : smallint; + array_desc_bounds : array[0..15] of ISC_ARRAY_BOUND; + end; + TISC_ARRAY_DESC = ISC_ARRAY_DESC; + PISC_ARRAY_DESC = ^ISC_ARRAY_DESC; + + ISC_BLOB_DESC = record + blob_desc_subtype : smallint; + blob_desc_charset : smallint; + blob_desc_segment_size : smallint; + blob_desc_field_name : array[0..31] of byte; + blob_desc_relation_name : array[0..31] of byte; + end; + TISC_BLOB_DESC = ISC_BLOB_DESC; + PISC_BLOB_DESC = ^ISC_BLOB_DESC ; + { } + { Blob control structure } + { } + {!!MVC + !!MVC } + { Source filter } + {!!MVC + !!MVC } + { Argument to pass to source } + { filter } + { Target type } + { Source type } + { Length of buffer } + { Length of current segment } + { Length of blob parameter } + { block } + { Address of blob parameter } + { block } + { Address of segment buffer } + { Length of longest segment } + { Total number of segments } + { Total length of blob } + { Address of status vector } + { Application specific data } + TCTLSourceFunction = function : isc_long; + + PISC_BLOB_CTL = ^ISC_BLOB_CTL ; + ISC_BLOB_CTL = record + ctl_source : TCTLSourceFunction; // was ISC_STATUS ( *ctl_source)(); + ctl_source_handle : pisc_blob_ctl ; // was struct isc_blob_ctl * ctl_source_handle; + ctl_to_sub_type : smallint; + ctl_from_sub_type : smallint; + ctl_buffer_length : word; + ctl_segment_length : word; + ctl_bpb_length : word; + ctl_bpb : Pchar; + ctl_buffer : Pbyte; + ctl_max_segment : ISC_LONG; + ctl_number_segments : ISC_LONG; + ctl_total_length : ISC_LONG; + ctl_status : PISC_STATUS; + ctl_data : array[0..7] of longint; + end; + TISC_BLOB_CTL = ISC_BLOB_CTL; + + { } + { Blob stream definitions } + { } + { Blob handle } + { Address of buffer } + { Next character } + { Length of buffer } + { Characters in buffer } + { (mode) ? OUTPUT : INPUT } + + BSTREAM = record + bstr_blob : pointer; + bstr_buffer : Pchar; + bstr_ptr : Pchar; + bstr_length : smallint; + bstr_cnt : smallint; + bstr_mode : char; + end; + TBSTREAM = BSTREAM; + PBstream = ^BSTREAM; + { } + { Dynamic SQL definitions } + { } + { } + { Declare the extended SQLDA } + { } + { datatype of field } + { scale factor } + { datatype subtype - BLOBs & Text } + { types only } + { length of data area } + { address of data } + { address of indicator variable } + { length of sqlname field } + { name of field, name length + space } + { for NULL } + { length of relation name } + { field's relation name + space for } + { NULL } + { length of owner name } + { relation's owner name + space for } + { NULL } + { length of alias name } + { relation's alias name + space for } + { NULL } + + XSQLVAR = record + sqltype : smallint; + sqlscale : smallint; + sqlsubtype : smallint; + sqllen : smallint; + sqldata : Pchar; + sqlind : Psmallint; + sqlname_length : smallint; + sqlname : array[0..31] of char; + relname_length : smallint; + relname : array[0..31] of char; + ownname_length : smallint; + ownname : array[0..31] of char; + aliasname_length : smallint; + aliasname : array[0..31] of char; + end; + TXSQLVAR = XSQLVAR; + PXSQLVAR =^XSQLVAR; + { version of this XSQLDA } + { XSQLDA name field } + { length in bytes of SQLDA } + { number of fields allocated } + { actual number of fields } + { first field address } + + XSQLDA = record + version : smallint; + sqldaid : array[0..7] of char; + sqldabc : ISC_LONG; + sqln : smallint; + sqld : smallint; + sqlvar : array[0..0] of XSQLVAR; + end; + TXSQLDA = XSQLDA; + PXSQLDA =^XSQLDA; + + function XSQLDA_LENGTH(n: Integer): Integer; + + + const + SQLDA_VERSION1 = 1; + { meaning is same as DIALECT_xsqlda } + SQL_DIALECT_V5 = 1; + { flagging anything that is delimited + by double quotes as an error and + flagging keyword DATE as an error } + SQL_DIALECT_V6_TRANSITION = 2; + { supports SQL delimited identifier, + SQLDATE/DATE, TIME, TIMESTAMP, + CURRENT_DATE, CURRENT_TIME, + CURRENT_TIMESTAMP, and 64-bit exact + numeric type } + SQL_DIALECT_V6 = 3; + { latest IB DIALECT } + SQL_DIALECT_CURRENT = SQL_DIALECT_V6; + { } + { InterBase Handle Definitions } + { } + + type + isc_att_handle = FB_API_HANDLE; + isc_blob_handle = FB_API_HANDLE; + isc_db_handle = FB_API_HANDLE; + isc_form_handle = FB_API_HANDLE; + isc_req_handle = FB_API_HANDLE; + isc_stmt_handle = FB_API_HANDLE; + isc_svc_handle = FB_API_HANDLE; + isc_tr_handle = FB_API_HANDLE; + isc_win_handle = FB_API_HANDLE; + isc_callback = procedure; {$ifdef wincall}cdecl{stdcall}{$else}cdecl{$endif}; + isc_versioncallback = procedure(user_arg: pointer; atext: pchar); + {$ifdef wincall}cdecl{stdcall}{$else}cdecl{$endif}; + isc_resv_handle = ISC_LONG; + tisc_att_handle = isc_att_handle; + tisc_blob_handle = isc_blob_handle; + tisc_db_handle = isc_db_handle; + tisc_form_handle = isc_form_handle; + tisc_req_handle = isc_req_handle; + tisc_stmt_handle = isc_stmt_handle; + tisc_svc_handle = isc_svc_handle; + tisc_tr_handle = isc_tr_handle; + tisc_win_handle = isc_win_handle; + tisc_callback = isc_callback; + tisc_resv_handle = isc_resv_handle; + pisc_att_handle =^isc_att_handle ; + pisc_blob_handle =^isc_blob_handle ; + pisc_db_handle =^isc_db_handle ; + pisc_form_handle =^isc_form_handle ; + pisc_req_handle =^isc_req_handle ; + pisc_stmt_handle =^isc_stmt_handle ; + pisc_svc_handle =^isc_svc_handle ; + pisc_tr_handle =^isc_tr_handle ; + pisc_win_handle =^isc_win_handle ; + pisc_callback = ^isc_callback; + pisc_resv_handle =^isc_resv_handle ; + + + { } + { Security structures } + { } + + const + sec_uid_spec = $01; + sec_gid_spec = $02; + sec_server_spec = $04; + sec_password_spec = $08; + sec_group_name_spec = $10; + sec_first_name_spec = $20; + sec_middle_name_spec = $40; + sec_last_name_spec = $80; + sec_dba_user_name_spec = $100; + sec_dba_password_spec = $200; + sec_protocol_tcpip = 1; + sec_protocol_netbeui = 2; + sec_protocol_spx = 3; + sec_protocol_local = 4; + { which fields are specified } + { the user's id } + { the user's group id } + { protocol to use for connection } + { server to administer } + { the user's name } + { the user's password } + { the group name } + { the user's first name } + { the user's middle name } + { the user's last name } + { the dba user name } + { the dba password } + + type + + USER_SEC_DATA = record + sec_flags : smallint; + uid : longint; + gid : longint; + protocol : longint; + server : Pchar; + user_name : Pchar; + password : Pchar; + group_name : Pchar; + first_name : Pchar; + middle_name : Pchar; + last_name : Pchar; + dba_user_name : Pchar; + dba_password : Pchar; + end; + TUSER_SEC_DATA = USER_SEC_DATA; + PUSER_SEC_DATA = ^USER_SEC_DATA; + + { } + { Actions to pass to the blob filter (ctl_source) } + { } + + const + isc_blob_filter_open = 0; + isc_blob_filter_get_segment = 1; + isc_blob_filter_close = 2; + isc_blob_filter_create = 3; + isc_blob_filter_put_segment = 4; + isc_blob_filter_alloc = 5; + isc_blob_filter_free = 6; + isc_blob_filter_seek = 7; + { } + { Blr definitions } + { } +{$ifndef _JRD_BLR_H_} + + const + blr_text = 14; + blr_text2 = 15; + blr_short = 7; + blr_long = 8; + blr_quad = 9; + blr_int64 = 16; + blr_float = 10; + blr_double = 27; + blr_d_float = 11; + blr_timestamp = 35; + blr_varying = 37; + blr_varying2 = 38; + blr_blob = 261; + blr_cstring = 40; + blr_cstring2 = 41; + blr_blob_id = 45; + blr_sql_date = 12; + blr_sql_time = 13; + { Historical alias for pre V6 applications } + blr_date = blr_timestamp; + blr_inner = 0; + blr_left = 1; + blr_right = 2; + blr_full = 3; + blr_gds_code = 0; + blr_sql_code = 1; + blr_exception = 2; + blr_trigger_code = 3; + blr_default_code = 4; + blr_version4 = 4; + blr_version5 = 5; + blr_eoc = 76; + blr_end = 255; + blr_assignment = 1; + blr_begin = 2; + blr_dcl_variable = 3; + blr_message = 4; + blr_erase = 5; + blr_fetch = 6; + blr_for = 7; + blr_if = 8; + blr_loop = 9; + blr_modify = 10; + blr_handler = 11; + blr_receive = 12; + blr_select = 13; + blr_send = 14; + blr_store = 15; + blr_label = 17; + blr_leave = 18; + blr_store2 = 19; + blr_post = 20; + blr_literal = 21; + blr_dbkey = 22; + blr_field = 23; + blr_fid = 24; + blr_parameter = 25; + blr_variable = 26; + blr_average = 27; + blr_count = 28; + blr_maximum = 29; + blr_minimum = 30; + blr_total = 31; + blr_add = 34; + blr_subtract = 35; + blr_multiply = 36; + blr_divide = 37; + blr_negate = 38; + blr_concatenate = 39; + blr_substring = 40; + blr_parameter2 = 41; + blr_from = 42; + blr_via = 43; + blr_user_name = 44; + blr_null = 45; + blr_eql = 47; + blr_neq = 48; + blr_gtr = 49; + blr_geq = 50; + blr_lss = 51; + blr_leq = 52; + blr_containing = 53; + blr_matching = 54; + blr_starting = 55; + blr_between = 56; + blr_or = 57; + blr_and = 58; + blr_not = 59; + blr_any = 60; + blr_missing = 61; + blr_unique = 62; + blr_like = 63; + blr_stream = 65; + blr_set_index = 66; + blr_rse = 67; + blr_first = 68; + blr_project = 69; + blr_sort = 70; + blr_boolean = 71; + blr_ascending = 72; + blr_descending = 73; + blr_relation = 74; + blr_rid = 75; + blr_union = 76; + blr_map = 77; + blr_group_by = 78; + blr_aggregate = 79; + blr_join_type = 80; + blr_agg_count = 83; + blr_agg_max = 84; + blr_agg_min = 85; + blr_agg_total = 86; + blr_agg_average = 87; + blr_parameter3 = 88; + blr_run_count = 118; + blr_run_max = 89; + blr_run_min = 90; + blr_run_total = 91; + blr_run_average = 92; + blr_agg_count2 = 93; + blr_agg_count_distinct = 94; + blr_agg_total_distinct = 95; + blr_agg_average_distinct = 96; + blr_function = 100; + blr_gen_id = 101; + blr_prot_mask = 102; + blr_upcase = 103; + blr_lock_state = 104; + blr_value_if = 105; + blr_matching2 = 106; + blr_index = 107; + blr_ansi_like = 108; + blr_bookmark = 109; + blr_crack = 110; + blr_force_crack = 111; + blr_seek = 112; + blr_find = 113; + blr_continue = 0; + blr_forward = 1; + blr_backward = 2; + blr_bof_forward = 3; + blr_eof_backward = 4; + blr_lock_relation = 114; + blr_lock_record = 115; + blr_set_bookmark = 116; + blr_get_bookmark = 117; + blr_rs_stream = 119; + blr_exec_proc = 120; + blr_begin_range = 121; + blr_end_range = 122; + blr_delete_range = 123; + blr_procedure = 124; + blr_pid = 125; + blr_exec_pid = 126; + blr_singular = 127; + blr_abort = 128; + blr_block = 129; + blr_error_handler = 130; + blr_cast = 131; + blr_release_lock = 132; + blr_release_locks = 133; + blr_start_savepoint = 134; + blr_end_savepoint = 135; + blr_find_dbkey = 136; + blr_range_relation = 137; + blr_delete_ranges = 138; + blr_plan = 139; + blr_merge = 140; + blr_join = 141; + blr_sequential = 142; + blr_navigational = 143; + blr_indices = 144; + blr_retrieve = 145; + blr_relation2 = 146; + blr_rid2 = 147; + blr_reset_stream = 148; + blr_release_bookmark = 149; + blr_set_generator = 150; + blr_ansi_any = 151; + blr_exists = 152; + blr_cardinality = 153; + { get tid of record } + blr_record_version = 154; + { fake server stall } + blr_stall = 155; + blr_seek_no_warn = 156; + blr_find_dbkey_version = 157; + blr_ansi_all = 158; + blr_extract = 159; + { sub parameters for blr_extract } + blr_extract_year = 0; + blr_extract_month = 1; + blr_extract_day = 2; + blr_extract_hour = 3; + blr_extract_minute = 4; + blr_extract_second = 5; + blr_extract_weekday = 6; + blr_extract_yearday = 7; + blr_current_date = 160; + blr_current_timestamp = 161; + blr_current_time = 162; + { These verbs were added in 6.0, primarily to support 64-bit integers } + blr_add2 = 163; + blr_subtract2 = 164; + blr_multiply2 = 165; + blr_divide2 = 166; + blr_agg_total2 = 167; + blr_agg_total_distinct2 = 168; + blr_agg_average2 = 169; + blr_agg_average_distinct2 = 170; + blr_average2 = 171; + blr_gen_id2 = 172; + blr_set_generator2 = 173; +{$endif} + { _JRD_BLR_H_ } + { } + { Database parameter block stuff } + { } + + const + isc_dpb_version1 = 1; + isc_dpb_cdd_pathname = 1; + isc_dpb_allocation = 2; + isc_dpb_journal = 3; + isc_dpb_page_size = 4; + isc_dpb_num_buffers = 5; + isc_dpb_buffer_length = 6; + isc_dpb_debug = 7; + isc_dpb_garbage_collect = 8; + isc_dpb_verify = 9; + isc_dpb_sweep = 10; + isc_dpb_enable_journal = 11; + isc_dpb_disable_journal = 12; + isc_dpb_dbkey_scope = 13; + isc_dpb_number_of_users = 14; + isc_dpb_trace = 15; + isc_dpb_no_garbage_collect = 16; + isc_dpb_damaged = 17; + isc_dpb_license = 18; + isc_dpb_sys_user_name = 19; + isc_dpb_encrypt_key = 20; + isc_dpb_activate_shadow = 21; + isc_dpb_sweep_interval = 22; + isc_dpb_delete_shadow = 23; + isc_dpb_force_write = 24; + isc_dpb_begin_log = 25; + isc_dpb_quit_log = 26; + isc_dpb_no_reserve = 27; + isc_dpb_user_name = 28; + isc_dpb_password = 29; + isc_dpb_password_enc = 30; + isc_dpb_sys_user_name_enc = 31; + isc_dpb_interp = 32; + isc_dpb_online_dump = 33; + isc_dpb_old_file_size = 34; + isc_dpb_old_num_files = 35; + isc_dpb_old_file = 36; + isc_dpb_old_start_page = 37; + isc_dpb_old_start_seqno = 38; + isc_dpb_old_start_file = 39; + isc_dpb_drop_walfile = 40; + isc_dpb_old_dump_id = 41; + isc_dpb_wal_backup_dir = 42; + isc_dpb_wal_chkptlen = 43; + isc_dpb_wal_numbufs = 44; + isc_dpb_wal_bufsize = 45; + isc_dpb_wal_grp_cmt_wait = 46; + isc_dpb_lc_messages = 47; + isc_dpb_lc_ctype = 48; + isc_dpb_cache_manager = 49; + isc_dpb_shutdown = 50; + isc_dpb_online = 51; + isc_dpb_shutdown_delay = 52; + isc_dpb_reserved = 53; + isc_dpb_overwrite = 54; + isc_dpb_sec_attach = 55; + isc_dpb_disable_wal = 56; + isc_dpb_connect_timeout = 57; + isc_dpb_dummy_packet_interval = 58; + isc_dpb_gbak_attach = 59; + isc_dpb_sql_role_name = 60; + isc_dpb_set_page_buffers = 61; + isc_dpb_working_directory = 62; + isc_dpb_SQL_dialect = 63; + isc_dpb_set_db_readonly = 64; + isc_dpb_set_db_SQL_dialect = 65; + isc_dpb_gfix_attach = 66; + isc_dpb_gstat_attach = 67; + { } + { isc_dpb_verify specific flags } + { } + isc_dpb_pages = 1; + isc_dpb_records = 2; + isc_dpb_indices = 4; + isc_dpb_transactions = 8; + isc_dpb_no_update = 16; + isc_dpb_repair = 32; + isc_dpb_ignore = 64; + { } + { isc_dpb_shutdown specific flags } + { } + isc_dpb_shut_cache = 1; + isc_dpb_shut_attachment = 2; + isc_dpb_shut_transaction = 4; + isc_dpb_shut_force = 8; + { } + { Bit assignments in RDB$SYSTEM_FLAG } + { } + RDB_system = 1; + RDB_id_assigned = 2; + { } + { Transaction parameter block stuff } + { } + isc_tpb_version1 = 1; + isc_tpb_version3 = 3; + isc_tpb_consistency = 1; + isc_tpb_concurrency = 2; + isc_tpb_shared = 3; + isc_tpb_protected = 4; + isc_tpb_exclusive = 5; + isc_tpb_wait = 6; + isc_tpb_nowait = 7; + isc_tpb_read = 8; + isc_tpb_write = 9; + isc_tpb_lock_read = 10; + isc_tpb_lock_write = 11; + isc_tpb_verb_time = 12; + isc_tpb_commit_time = 13; + isc_tpb_ignore_limbo = 14; + isc_tpb_read_committed = 15; + isc_tpb_autocommit = 16; + isc_tpb_rec_version = 17; + isc_tpb_no_rec_version = 18; + isc_tpb_restart_requests = 19; + isc_tpb_no_auto_undo = 20; + isc_tpb_lock_timeout = 21; //TPB = #21,#4, + + { Blob Parameter Block } + { } + isc_bpb_version1 = 1; + isc_bpb_source_type = 1; + isc_bpb_target_type = 2; + isc_bpb_type = 3; + isc_bpb_source_interp = 4; + isc_bpb_target_interp = 5; + isc_bpb_filter_parameter = 6; + isc_bpb_type_segmented = 0; + isc_bpb_type_stream = 1; + + { } + { Service parameter block stuff } + { } + isc_spb_version1 = 1; + isc_spb_current_version = 2; + isc_spb_version = isc_spb_current_version; + isc_spb_user_name = isc_dpb_user_name; //shortstring + isc_spb_sys_user_name = isc_dpb_sys_user_name; + isc_spb_sys_user_name_enc = isc_dpb_sys_user_name_enc; + isc_spb_password = isc_dpb_password; //shortstring + isc_spb_password_enc = isc_dpb_password_enc; + isc_spb_command_line = 105; + isc_spb_dbname = 106; + isc_spb_verbose = 107; + isc_spb_options = 108; + isc_spb_address_path = 109; + isc_spb_process_id = 110; + isc_spb_trusted_auth = 111; + isc_spb_process_name = 112; + isc_spb_trusted_role = 113; + + isc_spb_connect_timeout = isc_dpb_connect_timeout; + isc_spb_dummy_packet_interval = isc_dpb_dummy_packet_interval; + isc_spb_sql_role_name = isc_dpb_sql_role_name; + { + Service action items + } + { Starts database backup process on the server } + isc_action_svc_backup = 1; + { Starts database restore process on the server } + isc_action_svc_restore = 2; + { Starts database repair process on the server } + isc_action_svc_repair = 3; + { Adds a new user to the security database } + isc_action_svc_add_user = 4; + { Deletes a user record from the security database } + isc_action_svc_delete_user = 5; + { Modifies a user record in the security database } + isc_action_svc_modify_user = 6; + { Displays a user record from the security database } + isc_action_svc_display_user = 7; + { Sets database properties } + isc_action_svc_properties = 8; + { Adds a license to the license file } + isc_action_svc_add_license = 9; + { Removes a license from the license file } + isc_action_svc_remove_license = 10; + { Retrieves database statistics } + isc_action_svc_db_stats = 11; + { Retrieves the InterBase log file from the server } + isc_action_svc_get_ib_log = 12; + isc_action_svc_get_fb_log = 12; + //* Retrieves the Firebird log file from the server */ + isc_action_svc_nbak = 20; //* Incremental nbackup */ + isc_action_svc_nrest = 21; //* Incremental database restore */ + isc_action_svc_trace_start = 22; // Start trace session + isc_action_svc_trace_stop = 23; // Stop trace session + isc_action_svc_trace_suspend = 24; // Suspend trace session + isc_action_svc_trace_resume = 25; // Resume trace session + isc_action_svc_trace_list = 26; // List existing sessions + isc_action_svc_set_mapping = 27; + // Set auto admins mapping in security database + isc_action_svc_drop_mapping = 28; + // Drop auto admins mapping in security database + isc_action_svc_display_user_adm = 29; + // Displays user(s) from security database with admin info + isc_action_svc_validate = 30; // Starts database online validation + isc_action_svc_last = 31; // keep it last ! + { + Service information items + } + { Retrieves the number of attachments and databases } + isc_info_svc_svr_db_info = 50; + { Retrieves all license keys and IDs from the license file } + isc_info_svc_get_license = 51; + { Retrieves a bitmask representing licensed options on the server } + isc_info_svc_get_license_mask = 52; + { Retrieves the parameters and values for IB_CONFIG } + isc_info_svc_get_config = 53; //mse: not implemented in fb 2.5.5 + { Retrieves the version of the services manager } + isc_info_svc_version = 54; //card32 + { Retrieves the version of the InterBase server } + isc_info_svc_server_version = 55; //string + { Retrieves the implementation of the InterBase server } + isc_info_svc_implementation = 56; //string + { Retrieves a bitmask representing the server's capabilities } + isc_info_svc_capabilities = 57; //card32 + { Retrieves the path to the security database in use by the server } + isc_info_svc_user_dbpath = 58; //string + { Retrieves the setting of $INTERBASE } + isc_info_svc_get_env = 59; //string + { Retrieves the setting of $INTERBASE_LCK } + isc_info_svc_get_env_lock = 60; //string + { Retrieves the setting of $INTERBASE_MSG } + isc_info_svc_get_env_msg = 61; //string + { Retrieves 1 line of service output per call + mse: up to the size of buffer, remaining text of line in next call + adds a ' ' at end if line, string length 0 -> eof} + isc_info_svc_line = 62; + { Retrieves as much of the server output as will fit in the supplied buffer } + //mse: length 0 -> eof + isc_info_svc_to_eof = 63; + { Sets / signifies a timeout value for reading service information } + isc_info_svc_timeout = 64; + // 4byte 4byte + //mse send params = isc_info_svc_timeout <4> isc_info_end + { Retrieves the number of users licensed for accessing the server } + isc_info_svc_get_licensed_users = 65; + { Retrieve the limbo transactions } + isc_info_svc_limbo_trans = 66; + { Checks to see if a service is running on an attachment } + isc_info_svc_running = 67; + { Returns the user information from isc_action_svc_display_users } + isc_info_svc_get_users = 68; + isc_info_svc_stdin = 78; + //* Returns size of data, needed as stdin for service */ + { + Parameters for isc_action_(add|delete|modify)_user + } + isc_spb_sec_userid = 5; //card32 + isc_spb_sec_groupid = 6; //card32 + isc_spb_sec_username = 7; //string + isc_spb_sec_password = 8; + isc_spb_sec_groupname = 9; + isc_spb_sec_firstname = 10; //string + isc_spb_sec_middlename = 11; + isc_spb_sec_lastname = 12; //string + isc_spb_sec_admin = 13; //card32 + { + Parameters for isc_action_svc_(add|remove)_license, + isc_info_svc_get_license + } + isc_spb_lic_key = 5; + isc_spb_lic_id = 6; + isc_spb_lic_desc = 7; + { + Parameters for isc_action_svc_properties + } + isc_spb_prp_page_buffers = 5; + isc_spb_prp_sweep_interval = 6; + isc_spb_prp_shutdown_db = 7; + isc_spb_prp_deny_new_attachments = 9; + isc_spb_prp_deny_new_transactions = 10; + isc_spb_prp_reserve_space = 11; + isc_spb_prp_write_mode = 12; + isc_spb_prp_access_mode = 13; + isc_spb_prp_set_sql_dialect = 14; + isc_spb_prp_activate = $0100; + isc_spb_prp_db_online = $0200; + isc_spb_prp_force_shutdown = 41; + isc_spb_prp_attachments_shutdown = 42; + isc_spb_prp_transactions_shutdown = 43; + isc_spb_prp_shutdown_mode = 44; + isc_spb_prp_online_mode = 45; +///******************************************** +// * Parameters for isc_spb_prp_shutdown_mode * +// * and isc_spb_prp_online_mode * +// ********************************************/ + isc_spb_prp_sm_normal = 0; + isc_spb_prp_sm_multi = 1; + isc_spb_prp_sm_single = 2; + isc_spb_prp_sm_full = 3; + + { + Parameters for isc_spb_prp_reserve_space + } + isc_spb_prp_res_use_full = 35; + isc_spb_prp_res = 36; + { + Parameters for isc_spb_prp_write_mode + } + isc_spb_prp_wm_async = 37; + isc_spb_prp_wm_sync = 38; + { + Parameters for isc_spb_prp_access_mode + } + isc_spb_prp_am_readonly = 39; + isc_spb_prp_am_readwrite = 40; + { + Parameters for isc_action_svc_backup + } + isc_spb_bkp_file = 5; + isc_spb_bkp_factor = 6; + isc_spb_bkp_length = 7; + isc_spb_bkp_stat = 15; + isc_spb_bkp_ignore_checksums = $01; + isc_spb_bkp_ignore_limbo = $02; + isc_spb_bkp_metadata_only = $04; + isc_spb_bkp_no_garbage_collect = $08; + isc_spb_bkp_old_descriptions = $10; + isc_spb_bkp_non_transportable = $20; + isc_spb_bkp_convert = $40; + isc_spb_bkp_expand = $80; + isc_spb_bkp_no_triggers = $8000; + { + Parameters for isc_action_svc_restore + } + isc_spb_res_buffers = 9; + isc_spb_res_page_size = 10; + isc_spb_res_length = 11; + isc_spb_res_access_mode = 12; + isc_spb_res_fix_fss_data = 13; + isc_spb_res_fix_fss_metadata = 14; + isc_spb_res_stat = isc_spb_bkp_stat; + isc_spb_res_metadata_only = isc_spb_bkp_metadata_only; + isc_spb_res_deactivate_idx = $0100; + isc_spb_res_no_shadow = $0200; + isc_spb_res_no_validity = $0400; + isc_spb_res_one_at_a_time = $0800; + isc_spb_res_replace = $1000; + isc_spb_res_create = $2000; + isc_spb_res_use_all_space = $4000; + +///***************************************** +// * Parameters for isc_action_svc_validate * +// *****************************************/ + isc_spb_val_tab_incl = 1; // include filter based on regular expression + isc_spb_val_tab_excl = 2; // exclude filter based on regular expression + isc_spb_val_idx_incl = 3; // regexp of indices to validate + isc_spb_val_idx_excl = 4; // regexp of indices to NOT validate + isc_spb_val_lock_timeout = 5; // how long to wait for table lock + { + Parameters for isc_action_svc_repair + } + isc_spb_rpr_commit_trans = 15; + isc_spb_rpr_rollback_trans = 34; + isc_spb_rpr_recover_two_phase = 17; + isc_spb_tra_id = 18; + isc_spb_single_tra_id = 19; + isc_spb_multi_tra_id = 20; + isc_spb_tra_state = 21; + isc_spb_tra_state_limbo = 22; + isc_spb_tra_state_commit = 23; + isc_spb_tra_state_rollback = 24; + isc_spb_tra_state_unknown = 25; + isc_spb_tra_host_site = 26; + isc_spb_tra_remote_site = 27; + isc_spb_tra_db_path = 28; + isc_spb_tra_advise = 29; + isc_spb_tra_advise_commit = 30; + isc_spb_tra_advise_rollback = 31; + isc_spb_tra_advise_unknown = 33; + isc_spb_rpr_validate_db = $01; + isc_spb_rpr_sweep_db = $02; + isc_spb_rpr_mend_db = $04; + isc_spb_rpr_list_limbo_trans = $08; + isc_spb_rpr_check_db = $10; + isc_spb_rpr_ignore_checksum = $20; + isc_spb_rpr_kill_shadows = $40; + isc_spb_rpr_full = $80; + { + Parameters for isc_spb_res_access_mode + } + isc_spb_res_am_readonly = isc_spb_prp_am_readonly; + isc_spb_res_am_readwrite = isc_spb_prp_am_readwrite; + { + Parameters for isc_info_svc_svr_db_info + } + isc_spb_num_att = 5; + isc_spb_num_db = 6; + { + Parameters for isc_info_svc_db_stats + } + isc_spb_sts_data_pages = $01; + isc_spb_sts_db_log = $02; + isc_spb_sts_hdr_pages = $04; + isc_spb_sts_idx_pages = $08; + isc_spb_sts_sys_relations = $10; + isc_spb_sts_record_versions = $20; + isc_spb_sts_table = $40; + isc_spb_sts_nocreation = $80; + +//* Not available in Firebird 1.5 */ + +///*************************************** +// * Parameters for isc_action_svc_nbak * +// ***************************************/ + + isc_spb_nbk_level = 5; + isc_spb_nbk_file = 6; + isc_spb_nbk_direct = 7; + isc_spb_nbk_no_triggers = $01; + +///*************************************** +// * Parameters for isc_action_svc_trace * +// ***************************************/ + + isc_spb_trc_id = 1; + isc_spb_trc_name = 2; + isc_spb_trc_cfg = 3; + + + { } + { Information call declarations } + { } + { } + { Common, structural codes } + { } + isc_info_end = 1; + isc_info_truncated = 2; + isc_info_error = 3; + isc_info_data_not_ready = 4; + isc_info_flag_end = 127; + { } + { Database information items } + { } + isc_info_db_id = 4; + isc_info_reads = 5; + isc_info_writes = 6; + isc_info_fetches = 7; + isc_info_marks = 8; + isc_info_implementation = 11; + isc_info_version = 12; + isc_info_base_level = 13; + isc_info_page_size = 14; + isc_info_num_buffers = 15; + isc_info_limbo = 16; + isc_info_current_memory = 17; + isc_info_max_memory = 18; + isc_info_window_turns = 19; + isc_info_license = 20; + isc_info_allocation = 21; + isc_info_attachment_id = 22; + isc_info_read_seq_count = 23; + isc_info_read_idx_count = 24; + isc_info_insert_count = 25; + isc_info_update_count = 26; + isc_info_delete_count = 27; + isc_info_backout_count = 28; + isc_info_purge_count = 29; + isc_info_expunge_count = 30; + isc_info_sweep_interval = 31; + isc_info_ods_version = 32; + isc_info_ods_minor_version = 33; + isc_info_no_reserve = 34; + isc_info_logfile = 35; + isc_info_cur_logfile_name = 36; + isc_info_cur_log_part_offset = 37; + isc_info_num_wal_buffers = 38; + isc_info_wal_buffer_size = 39; + isc_info_wal_ckpt_length = 40; + isc_info_wal_cur_ckpt_interval = 41; + isc_info_wal_prv_ckpt_fname = 42; + isc_info_wal_prv_ckpt_poffset = 43; + isc_info_wal_recv_ckpt_fname = 44; + isc_info_wal_recv_ckpt_poffset = 45; + isc_info_wal_grpc_wait_usecs = 47; + isc_info_wal_num_io = 48; + isc_info_wal_avg_io_size = 49; + isc_info_wal_num_commits = 50; + isc_info_wal_avg_grpc_size = 51; + isc_info_forced_writes = 52; + isc_info_user_names = 53; + isc_info_page_errors = 54; + isc_info_record_errors = 55; + isc_info_bpage_errors = 56; + isc_info_dpage_errors = 57; + isc_info_ipage_errors = 58; + isc_info_ppage_errors = 59; + isc_info_tpage_errors = 60; + isc_info_set_page_buffers = 61; + isc_info_db_SQL_dialect = 62; + isc_info_db_read_only = 63; + isc_info_db_size_in_pages = 64; + { } + { Database information return values } + { } + isc_info_db_impl_rdb_vms = 1; + isc_info_db_impl_rdb_eln = 2; + isc_info_db_impl_rdb_eln_dev = 3; + isc_info_db_impl_rdb_vms_y = 4; + isc_info_db_impl_rdb_eln_y = 5; + isc_info_db_impl_jri = 6; + isc_info_db_impl_jsv = 7; + isc_info_db_impl_isc_a = 25; + isc_info_db_impl_isc_u = 26; + isc_info_db_impl_isc_v = 27; + isc_info_db_impl_isc_s = 28; + isc_info_db_impl_isc_apl_68K = 25; + isc_info_db_impl_isc_vax_ultr = 26; + isc_info_db_impl_isc_vms = 27; + isc_info_db_impl_isc_sun_68k = 28; + isc_info_db_impl_isc_os2 = 29; + isc_info_db_impl_isc_sun4 = 30; + isc_info_db_impl_isc_hp_ux = 31; + isc_info_db_impl_isc_sun_386i = 32; + isc_info_db_impl_isc_vms_orcl = 33; + isc_info_db_impl_isc_mac_aux = 34; + isc_info_db_impl_isc_rt_aix = 35; + isc_info_db_impl_isc_mips_ult = 36; + isc_info_db_impl_isc_xenix = 37; + isc_info_db_impl_isc_dg = 38; + isc_info_db_impl_isc_hp_mpexl = 39; + isc_info_db_impl_isc_hp_ux68K = 40; + isc_info_db_impl_isc_sgi = 41; + isc_info_db_impl_isc_sco_unix = 42; + isc_info_db_impl_isc_cray = 43; + isc_info_db_impl_isc_imp = 44; + isc_info_db_impl_isc_delta = 45; + isc_info_db_impl_isc_next = 46; + isc_info_db_impl_isc_dos = 47; + isc_info_db_impl_isc_winnt = 48; + isc_info_db_impl_isc_epson = 49; + isc_info_db_class_access = 1; + isc_info_db_class_y_valve = 2; + isc_info_db_class_rem_int = 3; + isc_info_db_class_rem_srvr = 4; + isc_info_db_class_pipe_int = 7; + isc_info_db_class_pipe_srvr = 8; + isc_info_db_class_sam_int = 9; + isc_info_db_class_sam_srvr = 10; + isc_info_db_class_gateway = 11; + isc_info_db_class_cache = 12; + { } + { Request information items } + { } + isc_info_number_messages = 4; + isc_info_max_message = 5; + isc_info_max_send = 6; + isc_info_max_receive = 7; + isc_info_state = 8; + isc_info_message_number = 9; + isc_info_message_size = 10; + isc_info_request_cost = 11; + isc_info_access_path = 12; + isc_info_req_select_count = 13; + isc_info_req_insert_count = 14; + isc_info_req_update_count = 15; + isc_info_req_delete_count = 16; + { } + { Access path items } + { } + isc_info_rsb_end = 0; + isc_info_rsb_begin = 1; + isc_info_rsb_type = 2; + isc_info_rsb_relation = 3; + isc_info_rsb_plan = 4; + { } + { Rsb types } + { } + isc_info_rsb_unknown = 1; + isc_info_rsb_indexed = 2; + isc_info_rsb_navigate = 3; + isc_info_rsb_sequential = 4; + isc_info_rsb_cross = 5; + isc_info_rsb_sort = 6; + isc_info_rsb_first = 7; + isc_info_rsb_boolean = 8; + isc_info_rsb_union = 9; + isc_info_rsb_aggregate = 10; + isc_info_rsb_merge = 11; + isc_info_rsb_ext_sequential = 12; + isc_info_rsb_ext_indexed = 13; + isc_info_rsb_ext_dbkey = 14; + isc_info_rsb_left_cross = 15; + isc_info_rsb_select = 16; + isc_info_rsb_sql_join = 17; + isc_info_rsb_simulate = 18; + isc_info_rsb_sim_cross = 19; + isc_info_rsb_once = 20; + isc_info_rsb_procedure = 21; + { } + { Bitmap expressions } + { } + isc_info_rsb_and = 1; + isc_info_rsb_or = 2; + isc_info_rsb_dbkey = 3; + isc_info_rsb_index = 4; + isc_info_req_active = 2; + isc_info_req_inactive = 3; + isc_info_req_send = 4; + isc_info_req_receive = 5; + isc_info_req_select = 6; + isc_info_req_sql_stall = 7; + { } + { Blob information items } + { } + isc_info_blob_num_segments = 4; + isc_info_blob_max_segment = 5; + isc_info_blob_total_length = 6; + isc_info_blob_type = 7; + { } + { Transaction information items } + { } + isc_info_tra_id = 4; + { } + { SQL information items } + { } + isc_info_sql_select = 4; + isc_info_sql_bind = 5; + isc_info_sql_num_variables = 6; + isc_info_sql_describe_vars = 7; + isc_info_sql_describe_end = 8; + isc_info_sql_sqlda_seq = 9; + isc_info_sql_message_seq = 10; + isc_info_sql_type = 11; + isc_info_sql_sub_type = 12; + isc_info_sql_scale = 13; + isc_info_sql_length = 14; + isc_info_sql_null_ind = 15; + isc_info_sql_field = 16; + isc_info_sql_relation = 17; + isc_info_sql_owner = 18; + isc_info_sql_alias = 19; + isc_info_sql_sqlda_start = 20; + isc_info_sql_stmt_type = 21; + isc_info_sql_get_plan = 22; + isc_info_sql_records = 23; + isc_info_sql_batch_fetch = 24; + { } + { SQL information return values } + { } + isc_info_sql_stmt_select = 1; + isc_info_sql_stmt_insert = 2; + isc_info_sql_stmt_update = 3; + isc_info_sql_stmt_delete = 4; + isc_info_sql_stmt_ddl = 5; + isc_info_sql_stmt_get_segment = 6; + isc_info_sql_stmt_put_segment = 7; + isc_info_sql_stmt_exec_procedure = 8; + isc_info_sql_stmt_start_trans = 9; + isc_info_sql_stmt_commit = 10; + isc_info_sql_stmt_rollback = 11; + isc_info_sql_stmt_select_for_upd = 12; + isc_info_sql_stmt_set_generator = 13; + { } + { Server configuration key values } + { } + ISCCFG_LOCKMEM_KEY = 0; + ISCCFG_LOCKSEM_KEY = 1; + ISCCFG_LOCKSIG_KEY = 2; + ISCCFG_EVNTMEM_KEY = 3; + ISCCFG_DBCACHE_KEY = 4; + ISCCFG_PRIORITY_KEY = 5; + ISCCFG_IPCMAP_KEY = 6; + ISCCFG_MEMMIN_KEY = 7; + ISCCFG_MEMMAX_KEY = 8; + ISCCFG_LOCKORDER_KEY = 9; + ISCCFG_ANYLOCKMEM_KEY = 10; + ISCCFG_ANYLOCKSEM_KEY = 11; + ISCCFG_ANYLOCKSIG_KEY = 12; + ISCCFG_ANYEVNTMEM_KEY = 13; + ISCCFG_LOCKHASH_KEY = 14; + ISCCFG_DEADLOCK_KEY = 15; + ISCCFG_LOCKSPIN_KEY = 16; + ISCCFG_CONN_TIMEOUT_KEY = 17; + ISCCFG_DUMMY_INTRVL_KEY = 18; + { Internal Use only } + ISCCFG_TRACE_POOLS_KEY = 19; + ISCCFG_REMOTE_BUFFER_KEY = 20; + { } + { Error codes } + { } + isc_facility = 20; + isc_err_base = 335544320; + isc_err_factor = 1; + isc_arg_end = 0; + isc_arg_gds = 1; + isc_arg_string = 2; + isc_arg_cstring = 3; + isc_arg_number = 4; + isc_arg_interpreted = 5; + isc_arg_vms = 6; + isc_arg_unix = 7; + isc_arg_domain = 8; + isc_arg_dos = 9; + isc_arg_mpexl = 10; + isc_arg_mpexl_ipc = 11; + isc_arg_next_mach = 15; + isc_arg_netware = 16; + isc_arg_win32 = 17; + isc_arg_warning = 18; + + { } + { Dynamic Data Definition Language operators } + { } + { } + { Version number } + { } + + const + isc_dyn_version_1 = 1; + isc_dyn_eoc = 255; + { } + { Operations (may be nested) } + { } + isc_dyn_begin = 2; + isc_dyn_end = 3; + isc_dyn_if = 4; + isc_dyn_def_database = 5; + isc_dyn_def_global_fld = 6; + isc_dyn_def_local_fld = 7; + isc_dyn_def_idx = 8; + isc_dyn_def_rel = 9; + isc_dyn_def_sql_fld = 10; + isc_dyn_def_view = 12; + isc_dyn_def_trigger = 15; + isc_dyn_def_security_class = 120; + isc_dyn_def_dimension = 140; + isc_dyn_def_generator = 24; + isc_dyn_def_function = 25; + isc_dyn_def_filter = 26; + isc_dyn_def_function_arg = 27; + isc_dyn_def_shadow = 34; + isc_dyn_def_trigger_msg = 17; + isc_dyn_def_file = 36; + isc_dyn_mod_database = 39; + isc_dyn_mod_rel = 11; + isc_dyn_mod_global_fld = 13; + isc_dyn_mod_idx = 102; + isc_dyn_mod_local_fld = 14; + isc_dyn_mod_sql_fld = 216; + isc_dyn_mod_view = 16; + isc_dyn_mod_security_class = 122; + isc_dyn_mod_trigger = 113; + isc_dyn_mod_trigger_msg = 28; + isc_dyn_delete_database = 18; + isc_dyn_delete_rel = 19; + isc_dyn_delete_global_fld = 20; + isc_dyn_delete_local_fld = 21; + isc_dyn_delete_idx = 22; + isc_dyn_delete_security_class = 123; + isc_dyn_delete_dimensions = 143; + isc_dyn_delete_trigger = 23; + isc_dyn_delete_trigger_msg = 29; + isc_dyn_delete_filter = 32; + isc_dyn_delete_function = 33; + isc_dyn_delete_shadow = 35; + isc_dyn_grant = 30; + isc_dyn_revoke = 31; + isc_dyn_def_primary_key = 37; + isc_dyn_def_foreign_key = 38; + isc_dyn_def_unique = 40; + isc_dyn_def_procedure = 164; + isc_dyn_delete_procedure = 165; + isc_dyn_def_parameter = 135; + isc_dyn_delete_parameter = 136; + isc_dyn_mod_procedure = 175; + isc_dyn_def_log_file = 176; + isc_dyn_def_cache_file = 180; + isc_dyn_def_exception = 181; + isc_dyn_mod_exception = 182; + isc_dyn_del_exception = 183; + isc_dyn_drop_log = 194; + isc_dyn_drop_cache = 195; + isc_dyn_def_default_log = 202; + { } + { View specific stuff } + { } + isc_dyn_view_blr = 43; + isc_dyn_view_source = 44; + isc_dyn_view_relation = 45; + isc_dyn_view_context = 46; + isc_dyn_view_context_name = 47; + { } + { Generic attributes } + { } + isc_dyn_rel_name = 50; + isc_dyn_fld_name = 51; + isc_dyn_new_fld_name = 215; + isc_dyn_idx_name = 52; + isc_dyn_description = 53; + isc_dyn_security_class = 54; + isc_dyn_system_flag = 55; + isc_dyn_update_flag = 56; + isc_dyn_prc_name = 166; + isc_dyn_prm_name = 137; + isc_dyn_sql_object = 196; + isc_dyn_fld_character_set_name = 174; + { } + { Relation specific attributes } + { } + isc_dyn_rel_dbkey_length = 61; + isc_dyn_rel_store_trig = 62; + isc_dyn_rel_modify_trig = 63; + isc_dyn_rel_erase_trig = 64; + isc_dyn_rel_store_trig_source = 65; + isc_dyn_rel_modify_trig_source = 66; + isc_dyn_rel_erase_trig_source = 67; + isc_dyn_rel_ext_file = 68; + isc_dyn_rel_sql_protection = 69; + isc_dyn_rel_constraint = 162; + isc_dyn_delete_rel_constraint = 163; + { } + { Global field specific attributes } + { } + isc_dyn_fld_type = 70; + isc_dyn_fld_length = 71; + isc_dyn_fld_scale = 72; + isc_dyn_fld_sub_type = 73; + isc_dyn_fld_segment_length = 74; + isc_dyn_fld_query_header = 75; + isc_dyn_fld_edit_string = 76; + isc_dyn_fld_validation_blr = 77; + isc_dyn_fld_validation_source = 78; + isc_dyn_fld_computed_blr = 79; + isc_dyn_fld_computed_source = 80; + isc_dyn_fld_missing_value = 81; + isc_dyn_fld_default_value = 82; + isc_dyn_fld_query_name = 83; + isc_dyn_fld_dimensions = 84; + isc_dyn_fld_not_null = 85; + isc_dyn_fld_precision = 86; + isc_dyn_fld_char_length = 172; + isc_dyn_fld_collation = 173; + isc_dyn_fld_default_source = 193; + isc_dyn_del_default = 197; + isc_dyn_del_validation = 198; + isc_dyn_single_validation = 199; + isc_dyn_fld_character_set = 203; + { } + { Local field specific attributes } + { } + isc_dyn_fld_source = 90; + isc_dyn_fld_base_fld = 91; + isc_dyn_fld_position = 92; + isc_dyn_fld_update_flag = 93; + { } + { Index specific attributes } + { } + isc_dyn_idx_unique = 100; + isc_dyn_idx_inactive = 101; + isc_dyn_idx_type = 103; + isc_dyn_idx_foreign_key = 104; + isc_dyn_idx_ref_column = 105; + isc_dyn_idx_statistic = 204; + { } + { Trigger specific attributes } + { } + isc_dyn_trg_type = 110; + isc_dyn_trg_blr = 111; + isc_dyn_trg_source = 112; + isc_dyn_trg_name = 114; + isc_dyn_trg_sequence = 115; + isc_dyn_trg_inactive = 116; + isc_dyn_trg_msg_number = 117; + isc_dyn_trg_msg = 118; + { } + { Security Class specific attributes } + { } + isc_dyn_scl_acl = 121; + isc_dyn_grant_user = 130; + isc_dyn_grant_proc = 186; + isc_dyn_grant_trig = 187; + isc_dyn_grant_view = 188; + isc_dyn_grant_options = 132; + isc_dyn_grant_user_group = 205; + { } + { Dimension specific information } + { } + isc_dyn_dim_lower = 141; + isc_dyn_dim_upper = 142; + { } + { File specific attributes } + { } + isc_dyn_file_name = 125; + isc_dyn_file_start = 126; + isc_dyn_file_length = 127; + isc_dyn_shadow_number = 128; + isc_dyn_shadow_man_auto = 129; + isc_dyn_shadow_conditional = 130; + { } + { Log file specific attributes } + { } + isc_dyn_log_file_sequence = 177; + isc_dyn_log_file_partitions = 178; + isc_dyn_log_file_serial = 179; + isc_dyn_log_file_overflow = 200; + isc_dyn_log_file_raw = 201; + { } + { Log specific attributes } + { } + isc_dyn_log_group_commit_wait = 189; + isc_dyn_log_buffer_size = 190; + isc_dyn_log_check_point_length = 191; + isc_dyn_log_num_of_buffers = 192; + { } + { Function specific attributes } + { } + isc_dyn_function_name = 145; + isc_dyn_function_type = 146; + isc_dyn_func_module_name = 147; + isc_dyn_func_entry_point = 148; + isc_dyn_func_return_argument = 149; + isc_dyn_func_arg_position = 150; + isc_dyn_func_mechanism = 151; + isc_dyn_filter_in_subtype = 152; + isc_dyn_filter_out_subtype = 153; + isc_dyn_description2 = 154; + isc_dyn_fld_computed_source2 = 155; + isc_dyn_fld_edit_string2 = 156; + isc_dyn_fld_query_header2 = 157; + isc_dyn_fld_validation_source2 = 158; + isc_dyn_trg_msg2 = 159; + isc_dyn_trg_source2 = 160; + isc_dyn_view_source2 = 161; + isc_dyn_xcp_msg2 = 184; + { } + { Generator specific attributes } + { } + isc_dyn_generator_name = 95; + isc_dyn_generator_id = 96; + { } + { Procedure specific attributes } + { } + isc_dyn_prc_inputs = 167; + isc_dyn_prc_outputs = 168; + isc_dyn_prc_source = 169; + isc_dyn_prc_blr = 170; + isc_dyn_prc_source2 = 171; + { } + { Parameter specific attributes } + { } + isc_dyn_prm_number = 138; + isc_dyn_prm_type = 139; + { } + { Relation specific attributes } + { } + isc_dyn_xcp_msg = 185; + { } + { Cascading referential integrity values } + { } + isc_dyn_foreign_key_update = 205; + isc_dyn_foreign_key_delete = 206; + isc_dyn_foreign_key_cascade = 207; + isc_dyn_foreign_key_default = 208; + isc_dyn_foreign_key_null = 209; + isc_dyn_foreign_key_none = 210; + { } + { SQL role values } + { } + isc_dyn_def_sql_role = 211; + isc_dyn_sql_role_name = 212; + isc_dyn_grant_admin_options = 213; + isc_dyn_del_sql_role = 214; + { } + { Last $dyn value assigned } + { } + isc_dyn_last_dyn_value = 216; + { } + { Array slice description language (SDL) } + { } + isc_sdl_version1 = 1; + isc_sdl_eoc = 255; + isc_sdl_relation = 2; + isc_sdl_rid = 3; + isc_sdl_field = 4; + isc_sdl_fid = 5; + isc_sdl_struct = 6; + isc_sdl_variable = 7; + isc_sdl_scalar = 8; + isc_sdl_tiny_integer = 9; + isc_sdl_short_integer = 10; + isc_sdl_long_integer = 11; + isc_sdl_literal = 12; + isc_sdl_add = 13; + isc_sdl_subtract = 14; + isc_sdl_multiply = 15; + isc_sdl_divide = 16; + isc_sdl_negate = 17; + isc_sdl_eql = 18; + isc_sdl_neq = 19; + isc_sdl_gtr = 20; + isc_sdl_geq = 21; + isc_sdl_lss = 22; + isc_sdl_leq = 23; + isc_sdl_and = 24; + isc_sdl_or = 25; + isc_sdl_not = 26; + isc_sdl_while = 27; + isc_sdl_assignment = 28; + isc_sdl_label = 29; + isc_sdl_leave = 30; + isc_sdl_begin = 31; + isc_sdl_end = 32; + isc_sdl_do3 = 33; + isc_sdl_do2 = 34; + isc_sdl_do1 = 35; + isc_sdl_element = 36; + { } + { International text interpretation values } + { } + isc_interp_eng_ascii = 0; + isc_interp_jpn_sjis = 5; + isc_interp_jpn_euc = 6; + { } + { SQL definitions } + { } + SQL_TEXT = 452; + SQL_VARYING = 448; + SQL_SHORT = 500; + SQL_LONG = 496; + SQL_FLOAT = 482; + SQL_DOUBLE = 480; + SQL_D_FLOAT = 530; + SQL_TIMESTAMP = 510; + SQL_BLOB = 520; + SQL_ARRAY = 540; + SQL_QUAD = 550; + SQL_TYPE_TIME = 560; + SQL_TYPE_DATE = 570; + SQL_INT64 = 580; + { Historical alias for pre V6 applications } + SQL_DATE = SQL_TIMESTAMP; + { } + { Blob Subtypes } + { } + { types less than zero are reserved for customer use } + isc_blob_untyped = 0; + { internal subtypes } + isc_blob_text = 1; + isc_blob_blr = 2; + isc_blob_acl = 3; + isc_blob_ranges = 4; + isc_blob_summary = 5; + isc_blob_format = 6; + isc_blob_tra = 7; + isc_blob_extfile = 8; + { the range 20-30 is reserved for dBASE and Paradox types } + isc_blob_formatted_memo = 20; + isc_blob_paradox_ole = 21; + isc_blob_graphic = 22; + isc_blob_dbase_ole = 23; + isc_blob_typed_binary = 24; + +//****************************************/ +//* Shutdown reasons, used by engine */ +//* Users should provide positive values */ +//****************************************/ + + fb_shutrsn_svc_stopped = -1; + fb_shutrsn_no_connection = -2; + fb_shutrsn_app_stopped = -3; + fb_shutrsn_device_removed = -4; + fb_shutrsn_signal = -5; + fb_shutrsn_services = -6; + fb_shutrsn_exit_called = -7; + +{$IFNDEF LinkDynamically} + + { } + { OSRI database functions } + { } + + function isc_attach_database(_para1:PISC_STATUS; _para2:smallint; _para3:Pchar; _para4:Pisc_db_handle; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_gen_sdl(_para1:PISC_STATUS; _para2:PISC_ARRAY_DESC; _para3:Psmallint; _para4:Pchar; _para5:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_get_slice(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:PISC_ARRAY_DESC; + _para6:pointer; _para7:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_lookup_bounds(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Pchar; + _para6:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_lookup_desc(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Pchar; + _para6:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_set_desc(_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar; _para4:Psmallint; _para5:Psmallint; + _para6:Psmallint; _para7:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_put_slice(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:PISC_ARRAY_DESC; + _para6:pointer; _para7:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_blob_default_desc(_para1:PISC_BLOB_DESC; _para2:Pbyte; _para3:Pbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_gen_bpb(_para1:PISC_STATUS; _para2:PISC_BLOB_DESC; _para3:PISC_BLOB_DESC; _para4:word; _para5:Pbyte; + _para6:Pword):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_info(_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:smallint; _para4:Pchar; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_lookup_desc(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pbyte; _para5:Pbyte; + _para6:PISC_BLOB_DESC; _para7:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_set_desc(_para1:PISC_STATUS; _para2:Pbyte; _para3:Pbyte; _para4:smallint; _para5:smallint; + _para6:smallint; _para7:PISC_BLOB_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_cancel_blob(_para1:PISC_STATUS; _para2:Pisc_blob_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_cancel_events(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_close_blob(_para1:PISC_STATUS; _para2:Pisc_blob_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_commit_retaining(_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_commit_transaction(_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_blob(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_blob2(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD; + _para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_database(_para1:PISC_STATUS; _para2:smallint; _para3:Pchar; _para4:Pisc_db_handle; _para5:smallint; + _para6:Pchar; _para7:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_database_info(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:smallint; _para4:Pchar; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_date(_para1:PISC_QUAD; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_sql_date(_para1:PISC_DATE; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_sql_time(_para1:PISC_TIME; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_timestamp(_para1:PISC_TIMESTAMP; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_detach_database(_para1:PISC_STATUS; _para2:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_drop_database(_para1:PISC_STATUS; _para2:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_allocate_statement(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_stmt_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_alloc_statement2(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_stmt_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_describe(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_describe_bind(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_exec_immed2(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:PXSQLDA; _para8:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_execute(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_execute2(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:PXSQLDA; + _para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_execute_immediate(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_fetch(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_finish(_para1:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_free_statement(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_insert(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_prepare(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_set_cursor_name(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:Pchar; _para4:word):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_sql_info(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:smallint; _para4:Pchar; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_date(_para1:pointer; _para2:PISC_QUAD); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_sql_date(_para1:pointer; _para2:PISC_DATE); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_sql_time(_para1:pointer; _para2:PISC_TIME); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_timestamp(_para1:pointer; _para2:PISC_TIMESTAMP); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_event_block(_para1:PPchar; _para2:PPchar; _para3:word; + args: array of const):ISC_LONG; {$ifdef cvcall}cdecl{$else}error{$endif}; external gdslib; + procedure isc_event_count(_para1: PISC_STATUS; _para2: short; + _para3: pchar; _para4: pchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + (*!!MVC + void isc_event_counts (unsigned ISC_LONG , + short, + char , + char ); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + !!MVC *) + procedure isc_expand_dpb(_para1:PPchar; _para2:Psmallint; args:array of const); + {$ifdef cvcall}cdecl{$else}error{$endif}; external gdslib; + + function isc_modify_dpb(_para1:PPchar; _para2:Psmallint; _para3:word; _para4:Pchar; _para5:smallint):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_free(_para1:Pchar):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_get_segment(_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:Pword; _para4:word; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_get_slice(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:smallint; + _para6:Pchar; _para7:smallint; _para8:PISC_LONG; _para9:ISC_LONG; _para10:pointer; + _para11:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_interprete(_para1:Pchar; _para2:PPISC_STATUS):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_open_blob(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_open_blob2(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD; + _para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_prepare_transaction2(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_print_sqlerror(_para1:smallint; _para2:PISC_STATUS); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_print_status(_para1:PISC_STATUS):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_put_segment(_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:word; _para4:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_put_slice(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:smallint; + _para6:Pchar; _para7:smallint; _para8:PISC_LONG; _para9:ISC_LONG; _para10:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_que_events(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:PISC_LONG; _para4:smallint; _para5:Pchar; + _para6:isc_callback; _para7:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_rollback_retaining(_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_rollback_transaction(_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_multiple(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_transaction(_para1:PISC_STATUS; _para2:Pisc_tr_handle; + _para3:smallint; args:array of const):ISC_STATUS; {$ifdef cvcall}cdecl{$else}error{$endif}; external gdslib; + + function isc_sqlcode(_para1:PISC_STATUS):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_sql_interprete(_para1:smallint; _para2:Pchar; _para3:smallint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_transaction_info(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:Pchar; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_transact_request(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:Pchar; _para8:word; _para9:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_vax_integer(_para1:Pchar; _para2:smallint):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_portable_integer(_para1:Pbyte; _para2:smallint):ISC_INT64; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Security Functions } + { } + + + function isc_add_user(_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_delete_user(_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_modify_user(_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Other OSRI functions } + { } + function isc_compile_request(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_req_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_compile_request2(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_req_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_ddl(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_prepare_transaction(_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_receive(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:pointer; + _para6:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_reconnect_transaction(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_release_request(_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_request_info(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:Pchar; + _para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_seek_blob(_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:smallint; _para4:ISC_LONG; _para5:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_send(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:pointer; + _para6:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_and_send(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:smallint; + _para6:pointer; _para7:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_request(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Pisc_tr_handle; _para4:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_unwind_request(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_wait_for_event(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:smallint; _para4:Pchar; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Other Sql functions } + { } + function isc_close(_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_declare(_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_describe(_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_describe_bind(_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_execute(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_execute_immediate(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_fetch(_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_open(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_prepare(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Psmallint; + _para6:Pchar; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Other Dynamic sql functions } + { } + function isc_dsql_execute_m(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:word; _para8:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_execute2_m(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:Pchar; + _para11:word; _para12:word; _para13:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_execute_immediate_m(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:word; + _para11:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_exec_immed3_m(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:word; + _para11:Pchar; _para12:word; _para13:Pchar; _para14:word; _para15:word; + _para16:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_fetch_m(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:Pchar; _para5:word; + _para6:word; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_insert_m(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:Pchar; _para5:word; + _para6:word; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_prepare_m(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_release(_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_close(_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_declare(_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_describe(_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_describe_bind(_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_execute(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_execute2(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA; + _para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_execute_immed(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_fetch(_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_open(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_open2(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA; + _para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_insert(_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_prepare(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:word; + _para6:Pchar; _para7:word; _para8:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_release(_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Other Blob functions } + { } + function BLOB_open(_para1:isc_blob_handle; _para2:Pchar; _para3:longint):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_put(_para1:char; _para2:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_close(_para1:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_get(_para1:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_display(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_dump(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_edit(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_load(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_text_dump(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_text_load(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function Bopen(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + +{$IFDEF Unix} + function Bopen2(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar; _para5:word):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; +{$ENDIF} + + { } + { Other Misc functions } + { } + function isc_ftof(_para1:Pchar; _para2:word; _para3:Pchar; _para4:word):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_print_blr(_para1:Pchar; _para2:isc_callback; _para3:pointer; _para4:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_set_debug(_para1:longint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_qtoq(_para1:PISC_QUAD; _para2:PISC_QUAD); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_vtof(_para1:Pchar; _para2:Pchar; _para3:word); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_vtov(_para1:Pchar; _para2:Pchar; _para3:smallint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_version(_para1:Pisc_db_handle; _para2:isc_versioncallback; _para3:pointer):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_get_client_version(aversion: pchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + function isc_get_client_major_version: integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + function isc_get_client_minor_version: integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + +{$IFDEF Unix} + function isc_reset_fpe(_para1:word):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; +{$ENDIF} + + { } + { Service manager functions } + { } + + function isc_service_attach(status_vector: PISC_STATUS; + service_length: word; service: Pchar; svc_handle: Pisc_svc_handle; + spb_length: word; spb: Pchar): ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + function isc_service_detach(status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + function isc_service_query(status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle; + reserved: Pisc_resv_handle; + send_spb_length: word; send_sbp: Pchar; + request_spb_length: word; request_spb:Pchar; + buffer_length: word; buffer: Pchar):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + function isc_service_start(status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle; reserved: Pisc_resv_handle; + spp_length: word; spb: Pchar):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Forms functions } + { } +{$IFDEF Unix} + function isc_compile_map(_para1:PISC_STATUS; _para2:Pisc_form_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_compile_menu(_para1:PISC_STATUS; _para2:Pisc_form_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_compile_sub_map(_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_window(_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Psmallint; _para4:Pchar; _para5:Psmallint; + _para6:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_delete_window(_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_drive_form(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_win_handle; _para5:Pisc_req_handle; + _para6:Pbyte; _para7:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_drive_menu(_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar; + _para6:Psmallint; _para7:Pchar; _para8:Psmallint; _para9:Psmallint; _para10:Pchar; + _para11:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_form_delete(_para1:PISC_STATUS; _para2:Pisc_form_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_form_fetch(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_req_handle; _para5:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_form_insert(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_req_handle; _para5:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_get_entree(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Psmallint; _para4:Pchar; _para5:PISC_LONG; + _para6:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_initialize_menu(_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_menu(_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_load_form(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_form_handle; _para5:Psmallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_pop_window(_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_put_entree(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Psmallint; _para4:Pchar; _para5:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_reset_form(_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_suspend_window(_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; +{$ENDIF} + + function isc_attach_database:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_gen_sdl:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_get_slice:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_lookup_bounds:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_lookup_desc:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_set_desc:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_put_slice:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_gen_bpb:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_info:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_lookup_desc:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_set_desc:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_cancel_blob:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_cancel_events:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_close_blob:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_commit_retaining:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_commit_transaction:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_compile_request:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_compile_request2:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_blob:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_blob2:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_database:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_database_info:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_ddl:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_date; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_sql_date; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_sql_time; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_timestamp; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_detach_database:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_drop_database:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_date; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_sql_date; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_sql_time; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_timestamp; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_event_block:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_event_counts; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_expand_dpb; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_modify_dpb:longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_free:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_get_segment:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_get_slice:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_interprete:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_open_blob:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_open_blob2:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_prepare_transaction:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_prepare_transaction2:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_print_sqlerror; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_print_status:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_put_segment:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_put_slice:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_que_events:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_receive:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_reconnect_transaction:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_release_request:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_request_info:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + +{$IFDEF Unix} + function isc_reset_fpe:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; +{$ENDIF} + + function isc_rollback_transaction:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_rollback_retaining:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_seek_blob:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_send:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_service_attach:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_service_detach:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_service_query:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_service_start:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_and_send:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_multiple:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_request:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_transaction:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_sqlcode:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_transaction_info:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_transact_request:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_unwind_request:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_wait_for_event:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_ftof:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_print_blr:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_set_debug; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_qtoq; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_vax_integer:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_vtof; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_vtov; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_version:longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Blob functions } + { } + + function Bopen:PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_open:PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + +{$IFDEF Unix} + function Bopen2:PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; +{$ENDIF} + +{$ELSE} // LinkDynamically + +var + +{ } +{ OSRI database functions } +{ } + isc_attach_database : function (_para1:PISC_STATUS; _para2:smallint; _para3:Pchar; _para4:Pisc_db_handle; _para5:smallint;_para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_gen_sdl : function (_para1:PISC_STATUS; _para2:PISC_ARRAY_DESC; _para3:Psmallint; _para4:Pchar; _para5:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_get_slice : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:PISC_ARRAY_DESC;_para6:pointer; _para7:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_lookup_bounds : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Pchar;_para6:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_lookup_desc : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Pchar;_para6:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_set_desc : function (_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar; _para4:Psmallint; _para5:Psmallint;_para6:Psmallint; _para7:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_put_slice : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:PISC_ARRAY_DESC;_para6:pointer; _para7:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_blob_default_desc : procedure (_para1:PISC_BLOB_DESC; _para2:Pbyte; _para3:Pbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_blob_gen_bpb : function (_para1:PISC_STATUS; _para2:PISC_BLOB_DESC; _para3:PISC_BLOB_DESC; _para4:word; _para5:Pbyte;_para6:Pword):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_blob_info : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:smallint; _para4:Pchar; _para5:smallint;_para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_blob_lookup_desc : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pbyte; _para5:Pbyte;_para6:PISC_BLOB_DESC; _para7:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_blob_set_desc : function (_para1:PISC_STATUS; _para2:Pbyte; _para3:Pbyte; _para4:smallint; _para5:smallint;_para6:smallint; _para7:PISC_BLOB_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_cancel_blob : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_cancel_events : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_close_blob : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_commit_retaining : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_commit_transaction : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_create_blob : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_create_blob2 : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD;_para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_create_database : function (_para1:PISC_STATUS; _para2:smallint; _para3:Pchar; _para4:Pisc_db_handle; _para5:smallint;_para6:Pchar; _para7:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_database_info : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:smallint; _para4:Pchar; _para5:smallint;_para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_decode_date : procedure (_para1:PISC_QUAD; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_decode_sql_date : procedure (_para1:PISC_DATE; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_decode_sql_time : procedure (_para1:PISC_TIME; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_decode_timestamp : procedure (_para1:PISC_TIMESTAMP; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_detach_database : function (_para1:PISC_STATUS; _para2:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_drop_database : function (_para1:PISC_STATUS; _para2:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_allocate_statement : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_stmt_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_alloc_statement2 : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_stmt_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_describe : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_describe_bind : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_exec_immed2 : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:PXSQLDA; _para8:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_execute : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_execute2 : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:PXSQLDA;_para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_execute_immediate : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_fetch : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_finish : function (_para1:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_free_statement : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_insert : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_prepare : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar;_para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_set_cursor_name : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:Pchar; _para4:word):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_sql_info : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; + _para3:smallint; _para4:Pchar; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_encode_date : procedure (_para1:pointer; _para2:PISC_QUAD); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_encode_sql_date : procedure (_para1:pointer; _para2:PISC_DATE); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_encode_sql_time : procedure (_para1:pointer; _para2:PISC_TIME); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_encode_timestamp : procedure (_para1:pointer; _para2:PISC_TIMESTAMP); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$warnings off} + isc_event_block : function (_para1:PPchar; _para2:PPchar; _para3:word; + args: array of const):ISC_LONG; {$ifdef cvcall}cdecl{$else}error{$endif}; {varargs;} +{$warnings on} + isc_event_counts: procedure (_para1: PISC_STATUS; _para2: short; + _para3: pchar; _para4: pchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$warnings off} + isc_expand_dpb : procedure (_para1:PPchar; _para2:Psmallint; + args:array of const); {$ifdef cvcall}cdecl{$else}error{$endif}; +{$warnings on} + isc_modify_dpb : function (_para1:PPchar; _para2:Psmallint; _para3:word; _para4:Pchar; _para5:smallint):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_free : function (_para1:Pchar):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_segment : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:Pword; _para4:word; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_slice : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:smallint;_para6:Pchar; _para7:smallint; _para8:PISC_LONG; _para9:ISC_LONG; _para10:pointer;_para11:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_interprete : function (_para1:Pchar; _para2:PPISC_STATUS):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_open_blob : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_open_blob2 : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD;_para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_prepare_transaction2 : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_print_sqlerror : procedure (_para1:smallint; _para2:PISC_STATUS); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_print_status : function (_para1:PISC_STATUS):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_put_segment : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:word; _para4:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_put_slice : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:smallint;_para6:Pchar; _para7:smallint; _para8:PISC_LONG; _para9:ISC_LONG; _para10:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_que_events : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:PISC_LONG; _para4:smallint; _para5:Pchar;_para6:isc_callback; _para7:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_rollback_retaining : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_rollback_transaction : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_start_multiple : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$warnings off} + isc_start_transaction : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; + _para3:smallint; args:array of const):ISC_STATUS; + {$ifdef cvcall}cdecl{$else}error{$endif}; +{$warnings on} + isc_sqlcode : function (_para1:PISC_STATUS):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_sql_interprete : procedure (_para1:smallint; _para2:Pchar; _para3:smallint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_transaction_info : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:Pchar; _para5:smallint;_para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_transact_request : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:Pchar; _para8:word; _para9:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_vax_integer : function (_para1:Pchar; _para2:smallint):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_portable_integer : function (_para1:Pbyte; _para2:smallint):ISC_INT64; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Security Functions } +{ } + isc_add_user : function (_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_delete_user : function (_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_modify_user : function (_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Other OSRI functions } +{ } + isc_compile_request : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_req_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_compile_request2 : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_req_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_ddl : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_prepare_transaction : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_receive : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:pointer;_para6:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_reconnect_transaction : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_release_request : function (_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_request_info : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:Pchar;_para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_seek_blob : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:smallint; _para4:ISC_LONG; _para5:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_send : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:pointer;_para6:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_start_and_send : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:smallint;_para6:pointer; _para7:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_start_request : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Pisc_tr_handle; _para4:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_unwind_request : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_wait_for_event : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:smallint; _para4:Pchar; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Other Sql functions } +{ } + isc_close : function (_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_declare : function (_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_describe : function (_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_describe_bind : function (_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_execute : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_execute_immediate : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_fetch : function (_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_open : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_prepare : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Psmallint;_para6:Pchar; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Other Dynamic sql functions } +{ } + isc_dsql_execute_m : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar;_para6:word; _para7:word; _para8:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_execute2_m : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar;_para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:Pchar;_para11:word; _para12:word; _para13:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_execute_immediate_m : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:word;_para11:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_exec_immed3_m : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:word;_para11:Pchar; _para12:word; _para13:Pchar; _para14:word; _para15:word;_para16:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_fetch_m : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:Pchar; _para5:word;_para6:word; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_insert_m : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:Pchar; _para5:word;_para6:word; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_prepare_m : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar;_para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_release : function (_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_close : function (_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_declare : function (_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_describe : function (_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_describe_bind : function (_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_execute : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_execute2 : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA;_para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_execute_immed : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_fetch : function (_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_open : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_open2 : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA;_para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_insert : function (_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_prepare : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:word;_para6:Pchar; _para7:word; _para8:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_release : function (_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Other Blob functions } +{ } + BLOB_open : function (_para1:isc_blob_handle; _para2:Pchar; _para3:longint):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_put : function (_para1:char; _para2:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_close : function (_para1:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_get : function (_para1:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_display : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_dump : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_edit : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_load : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_text_dump : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_text_load : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + Bopen : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$IFDEF Unix} + Bopen2 : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar; _para5:word):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ENDIF} +{ } +{ Other Misc functions } +{ } + isc_ftof : function (_para1:Pchar; _para2:word; _para3:Pchar; _para4:word):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_print_blr : function (_para1:Pchar; _para2:isc_callback; _para3:pointer; _para4:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_set_debug : procedure (_para1:longint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_qtoq : procedure (_para1:PISC_QUAD; _para2:PISC_QUAD); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_vtof : procedure (_para1:Pchar; _para2:Pchar; _para3:word); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_vtov : procedure (_para1:Pchar; _para2:Pchar; _para3:smallint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_version : function (_para1:Pisc_db_handle; _para2:isc_versioncallback; + _para3:pointer):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_client_version: procedure (aversion: pchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_client_major_version: function: integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_client_minor_version: function: integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$IFDEF Unix} + isc_reset_fpe : function (_para1:word):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ENDIF} +{ } +{ Service manager functions } +{ } + isc_service_attach: function (status_vector: PISC_STATUS; + service_length: word; service: Pchar; svc_handle: Pisc_svc_handle; + spb_length: word; spb: Pchar): ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_service_detach: function (status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_service_query: function (status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle; + reserved: Pisc_resv_handle; + send_spb_length: word; send_sbp: Pchar; + request_spb_length: word; request_spb:Pchar; + buffer_length: word; buffer: Pchar):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_service_start: function (status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle; reserved: Pisc_resv_handle; + spp_length: word; spb: Pchar):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Forms functions } +{ } +{$IFDEF Unix} + isc_compile_map : function (_para1:PISC_STATUS; _para2:Pisc_form_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_compile_menu : function (_para1:PISC_STATUS; _para2:Pisc_form_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_compile_sub_map : function (_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_create_window : function (_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Psmallint; _para4:Pchar; _para5:Psmallint;_para6:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_delete_window : function (_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_drive_form : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_win_handle; _para5:Pisc_req_handle;_para6:Pbyte; _para7:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_drive_menu : function (_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar;_para6:Psmallint; _para7:Pchar; _para8:Psmallint; _para9:Psmallint; _para10:Pchar;_para11:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_form_delete : function (_para1:PISC_STATUS; _para2:Pisc_form_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_form_fetch : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_req_handle; _para5:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_form_insert : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_req_handle; _para5:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_entree : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Psmallint; _para4:Pchar; _para5:PISC_LONG;_para6:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_initialize_menu : function (_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_menu : function (_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_load_form : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_form_handle; _para5:Psmallint;_para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_pop_window : function (_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_put_entree : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Psmallint; _para4:Pchar; _para5:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_reset_form : function (_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_suspend_window : function (_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ENDIF} + + fb_shutdown: function(timeout: cuint; reason: cint): cint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +{$ENDIF} + +{$IFDEF LinkDynamically} +//var +// libname: filenamety; +{$endif} + +implementation +uses + msesys,msesonames,msedynload,msesysintf; + +function XSQLDA_LENGTH(n: Integer): Integer; +begin + Result := SizeOf(XSQLDA) + (n - 1) * SizeOf(XSQLVAR); +end; + +{$IFDEF LinkDynamically} + +ResourceString + SErrEmbeddedFailed = 'Can not load embedded Firebird client "%s". Check your installation.'; + SErrDefaultsFailed = 'Can not load default Firebird clients ("%s" or "%s"). Check your installation.'; + SErrLoadFailed = 'Can not load Firebird client library "%s". Check your installation.'; + SErrAlreadyLoaded = 'Firebird interface already initialized from library %s.'; + +var + libinfo: dynlibinfoty; +// RefCount : integer; +// LoadedLibrary : String; +(* +Function TryInitialiseIBase60(Const LibraryNames: array of filenamety) : Boolean; +var + mstr1: filenamety; +begin + Result:=True; + if (RefCount = 0) then begin + try + IBaseLibraryHandle:= LoadLib(LibraryNames,mstr1); + except + IBaseLibraryHandle:= nilhandle + end; + if IBaseLibraryHandle = nilhandle then begin + result:= false; + exit; + end; +// inc(RefCount); + refcount:= 2; //releasing the library is unsafe! + LoadedLibrary:= mstr1; + getprocaddresses(ibaselibraryhandle, + [ + 'isc_attach_database', //1 + 'isc_array_gen_sdl', //2 + 'isc_array_get_slice', //3 + 'isc_array_lookup_bounds', //4 + 'isc_array_lookup_desc', //5 + 'isc_array_set_desc', //6 + 'isc_array_put_slice', //7 + 'isc_blob_default_desc', //8 + 'isc_blob_gen_bpb', //9 + 'isc_blob_info', //10 + 'isc_blob_lookup_desc', //11 + 'isc_blob_set_desc', //12 + 'isc_cancel_blob', //13 + 'isc_cancel_events', //14 + 'isc_close_blob', //15 + 'isc_commit_retaining', //16 + 'isc_commit_transaction', //17 + 'isc_create_blob', //18 + 'isc_create_blob2', //19 + 'isc_create_database', //20 + 'isc_database_info', //21 + 'isc_decode_date', //22 + 'isc_decode_sql_date', //23 + 'isc_decode_sql_time', //24 + 'isc_decode_timestamp', //25 + 'isc_detach_database', //26 + 'isc_drop_database', //27 + 'isc_dsql_allocate_statement', //28 + 'isc_dsql_alloc_statement2', //29 + 'isc_dsql_describe', //30 + 'isc_dsql_describe_bind', //31 + 'isc_dsql_exec_immed2', //32 + 'isc_dsql_execute', //33 + 'isc_dsql_execute2', //34 + 'isc_dsql_execute_immediate', //35 + 'isc_dsql_fetch', //36 + 'isc_dsql_finish', //37 + 'isc_dsql_free_statement', //38 + 'isc_dsql_insert', //39 + 'isc_dsql_prepare', //40 + 'isc_dsql_set_cursor_name', //41 + 'isc_dsql_sql_info', //42 + 'isc_encode_date', //43 + 'isc_encode_sql_date', //44 + 'isc_encode_sql_time', //45 + 'isc_encode_timestamp', //46 + 'isc_event_block', //47 + 'isc_event_counts', //48 + 'isc_expand_dpb', //49 + 'isc_modify_dpb', //50 + 'isc_free', //51 + 'isc_get_segment', //52 + 'isc_get_slice', //53 + 'isc_interprete', //54 + 'isc_open_blob', //55 + 'isc_open_blob2', //56 + 'isc_prepare_transaction2', //57 + 'isc_print_sqlerror', //58 + 'isc_print_status', //69 + 'isc_put_segment', //60 + 'isc_put_slice', //61 + 'isc_que_events', //62 + 'isc_rollback_retaining', //63 + 'isc_rollback_transaction', //64 + 'isc_start_multiple', //65 + 'isc_start_transaction', //66 + 'isc_sqlcode', //67 + 'isc_sql_interprete', //68 + 'isc_transaction_info', //69 + 'isc_transact_request', //70 + 'isc_vax_integer', //71 + 'isc_portable_integer', //72 + 'isc_add_user', //73 + 'isc_delete_user', //74 + 'isc_modify_user', //75 + 'isc_compile_request', //76 + 'isc_compile_request2', //77 + 'isc_ddl', //78 + 'isc_prepare_transaction', //79 + 'isc_receive', //80 + 'isc_reconnect_transaction', //81 + 'isc_release_request', //82 + 'isc_request_info', //83 + 'isc_seek_blob', //84 + 'isc_send', //85 + 'isc_start_and_send', //86 + 'isc_start_request', //87 + 'isc_unwind_request', //88 + 'isc_wait_for_event', //89 + 'isc_close', //90 + 'isc_declare', //91 + 'isc_describe', //92 + 'isc_describe_bind', //93 + 'isc_execute', //94 + 'isc_execute_immediate', //95 + 'isc_fetch', //96 + 'isc_open', //97 + 'isc_prepare', //98 + 'isc_dsql_execute_m', //99 + 'isc_dsql_execute2_m', //100 + 'isc_dsql_execute_immediate_m', //101 + 'isc_dsql_exec_immed3_m', //102 + 'isc_dsql_fetch_m', //103 + 'isc_dsql_insert_m', //104 + 'isc_dsql_prepare_m', //105 + 'isc_dsql_release', //106 + 'isc_embed_dsql_close', //107 + 'isc_embed_dsql_declare', //108 + 'isc_embed_dsql_describe', //109 + 'isc_embed_dsql_describe_bind', //110 + 'isc_embed_dsql_execute', //111 + 'isc_embed_dsql_execute2', //112 + 'isc_embed_dsql_execute_immed', //113 + 'isc_embed_dsql_fetch', //114 + 'isc_embed_dsql_open', //115 + 'isc_embed_dsql_open2', //116 + 'isc_embed_dsql_insert', //117 + 'isc_embed_dsql_prepare', //118 + 'isc_embed_dsql_release', //119 + 'BLOB_open', //120 + 'BLOB_put', //121 + 'BLOB_close', //122 + 'BLOB_get', //123 + 'BLOB_display', //124 + 'BLOB_dump', //125 + 'BLOB_edit', //126 + 'BLOB_load', //127 + 'BLOB_text_dump', //128 + 'BLOB_text_load', //129 + 'Bopen', //130 +{$IFDEF Unix} + 'Bopen2', //131 +{$ENDIF} + 'isc_ftof', //132 + 'isc_print_blr', //133 + 'isc_set_debug', //134 + 'isc_qtoq', //135 + 'isc_vtof', //136 + 'isc_vtov', //137 + 'isc_version', //138 + 'isc_get_client_version', //139 + 'isc_get_client_major_version', //140 + 'isc_get_client_minor_version', //141 +{$IFDEF Unix} + 'isc_reset_fpe', //142 +{$ENDIF} + 'isc_service_attach', //143 + 'isc_service_detach', //144 + 'isc_service_query', //145 + 'isc_service_start' //146 +{$IFDEF Unix} + , + 'isc_compile_map', //147 + 'isc_compile_menu', //148 + 'isc_compile_sub_map', //149 + 'isc_create_window', //150 + 'isc_delete_window', //151 + 'isc_drive_form', //152 + 'isc_drive_menu', //153 + 'isc_form_delete', //154 + 'isc_form_fetch', //155 + 'isc_form_insert', //156 + 'isc_get_entree', //157 + 'isc_initialize_menu', //158 + 'isc_menu', //159 + 'isc_load_form', //160 + 'isc_pop_window', //161 + 'isc_put_entree', //162 + 'isc_reset_form', //163 + 'isc_suspend_window' //164 +{$ENDIF} + ], + [ + @isc_attach_database, //1 + @isc_array_gen_sdl, //2 + @isc_array_get_slice, //3 + @isc_array_lookup_bounds, //4 + @isc_array_lookup_desc, //5 + @isc_array_set_desc, //6 + @isc_array_put_slice, //7 + @isc_blob_default_desc, //8 + @isc_blob_gen_bpb, //9 + @isc_blob_info, //10 + @isc_blob_lookup_desc, //11 + @isc_blob_set_desc, //12 + @isc_cancel_blob, //13 + @isc_cancel_events, //14 + @isc_close_blob, //15 + @isc_commit_retaining, //16 + @isc_commit_transaction, //17 + @isc_create_blob, //18 + @isc_create_blob2, //19 + @isc_create_database, //20 + @isc_database_info, //21 + @isc_decode_date, //22 + @isc_decode_sql_date, //23 + @isc_decode_sql_time, //24 + @isc_decode_timestamp, //25 + @isc_detach_database, //26 + @isc_drop_database, //27 + @isc_dsql_allocate_statement, //28 + @isc_dsql_alloc_statement2, //29 + @isc_dsql_describe, //30 + @isc_dsql_describe_bind, //31 + @isc_dsql_exec_immed2, //32 + @isc_dsql_execute, //33 + @isc_dsql_execute2, //34 + @isc_dsql_execute_immediate, //35 + @isc_dsql_fetch, //36 + @isc_dsql_finish, //37 + @isc_dsql_free_statement, //38 + @isc_dsql_insert, //39 + @isc_dsql_prepare, //40 + @isc_dsql_set_cursor_name, //41 + @isc_dsql_sql_info, //42 + @isc_encode_date, //43 + @isc_encode_sql_date, //44 + @isc_encode_sql_time, //45 + @isc_encode_timestamp, //46 + @isc_event_block, //47 + @isc_event_counts, //48 + @isc_expand_dpb, //49 + @isc_modify_dpb, //50 + @isc_free, //51 + @isc_get_segment, //52 + @isc_get_slice, //53 + @isc_interprete, //54 + @isc_open_blob, //55 + @isc_open_blob2, //56 + @isc_prepare_transaction2, //57 + @isc_print_sqlerror, //58 + @isc_print_status, //59 + @isc_put_segment, //60 + @isc_put_slice, //61 + @isc_que_events, //62 + @isc_rollback_retaining, //63 + @isc_rollback_transaction, //64 + @isc_start_multiple, //65 + @isc_start_transaction, //66 + @isc_sqlcode, //67 + @isc_sql_interprete, //68 + @isc_transaction_info, //69 + @isc_transact_request, //70 + @isc_vax_integer, //71 + @isc_portable_integer, //72 + @isc_add_user, //73 + @isc_delete_user, //74 + @isc_modify_user, //75 + @isc_compile_request, //76 + @isc_compile_request2, //77 + @isc_ddl, //78 + @isc_prepare_transaction, //79 + @isc_receive, //80 + @isc_reconnect_transaction, //81 + @isc_release_request, //82 + @isc_request_info, //83 + @isc_seek_blob, //84 + @isc_send, //85 + @isc_start_and_send, //86 + @isc_start_request, //87 + @isc_unwind_request, //88 + @isc_wait_for_event, //89 + @isc_close, //90 + @isc_declare, //91 + @isc_describe, //92 + @isc_describe_bind, //93 + @isc_execute, //94 + @isc_execute_immediate, //95 + @isc_fetch, //96 + @isc_open, //97 + @isc_prepare, //98 + @isc_dsql_execute_m, //99 + @isc_dsql_execute2_m, //100 + @isc_dsql_execute_immediate_m, //101 + @isc_dsql_exec_immed3_m, //102 + @isc_dsql_fetch_m, //103 + @isc_dsql_insert_m, //104 + @isc_dsql_prepare_m, //105 + @isc_dsql_release, //106 + @isc_embed_dsql_close, //107 + @isc_embed_dsql_declare, //108 + @isc_embed_dsql_describe, //109 + @isc_embed_dsql_describe_bind, //110 + @isc_embed_dsql_execute, //111 + @isc_embed_dsql_execute2, //112 + @isc_embed_dsql_execute_immed, //113 + @isc_embed_dsql_fetch, //114 + @isc_embed_dsql_open, //115 + @isc_embed_dsql_open2, //116 + @isc_embed_dsql_insert, //117 + @isc_embed_dsql_prepare, //118 + @isc_embed_dsql_release, //119 + @BLOB_open, //120 + @BLOB_put, //121 + @BLOB_close, //122 + @BLOB_get, //123 + @BLOB_display, //124 + @BLOB_dump, //125 + @BLOB_edit, //126 + @BLOB_load, //127 + @BLOB_text_dump, //128 + @BLOB_text_load, //129 + @Bopen, //130 +{$IFDEF Unix} + @Bopen2, //131 +{$ENDIF} + @isc_ftof, //132 + @isc_print_blr, //133 + @isc_set_debug, //134 + @isc_qtoq, //135 + @isc_vtof, //136 + @isc_vtov, //137 + @isc_version, //138 + @isc_get_client_version, //139 + @isc_get_client_major_version, //140 + @isc_get_client_minor_version, //141 +{$IFDEF Unix} + @isc_reset_fpe, //142 +{$ENDIF} + @isc_service_attach, //143 + @isc_service_detach, //144 + @isc_service_query, //145 + @isc_service_start //146 +{$IFDEF Unix} + , + @isc_compile_map, //147 + @isc_compile_menu, //148 + @isc_compile_sub_map, //149 + @isc_create_window, //150 + @isc_delete_window, //151 + @isc_drive_form, //152 + @isc_drive_menu, //153 + @isc_form_delete, //154 + @isc_form_fetch, //155 + @isc_form_insert, //156 + @isc_get_entree, //157 + @isc_initialize_menu, //158 + @isc_menu, //159 + @isc_load_form, //160 + @isc_pop_window, //161 + @isc_put_entree, //162 + @isc_reset_form, //163 + @isc_suspend_window //164 +{$ENDIF} + ],true); //accept missing entries + end + else begin +// If (LoadedLibrary<>LibraryName) then +// Raise EInoutError.CreateFmt(SErrAlreadyLoaded,[LoadedLibrary]); + if (loadedlibrary = mstr1) then begin + inc(RefCount); //mse 2006-11-23 + end; + end; +end; + +procedure checkloaded; +begin + if (loadedlibrary <> '') then begin + raise einouterror.createfmt(serralreadyloaded,[loadedlibrary]); + end; +end; +*) + +Procedure InitializeIBase60(const sonames: array of filenamety); +const + funcs: array[0..{$ifdef unix}164{$else}144{$endif}] of funcinfoty = ( + (n: 'isc_attach_database'; d: {$ifndef FPC}@{$endif}@isc_attach_database), + (n: 'isc_array_gen_sdl'; d: {$ifndef FPC}@{$endif}@isc_array_gen_sdl), + (n: 'isc_array_get_slice'; d: {$ifndef FPC}@{$endif}@isc_array_get_slice), + (n: 'isc_array_lookup_bounds'; d: {$ifndef FPC}@{$endif}@isc_array_lookup_bounds), + (n: 'isc_array_lookup_desc'; d: {$ifndef FPC}@{$endif}@isc_array_lookup_desc), + (n: 'isc_array_set_desc'; d: {$ifndef FPC}@{$endif}@isc_array_set_desc), + (n: 'isc_array_put_slice'; d: {$ifndef FPC}@{$endif}@isc_array_put_slice), + (n: 'isc_blob_default_desc'; d: {$ifndef FPC}@{$endif}@isc_blob_default_desc), + (n: 'isc_blob_gen_bpb'; d: {$ifndef FPC}@{$endif}@isc_blob_gen_bpb), + (n: 'isc_blob_info'; d: {$ifndef FPC}@{$endif}@isc_blob_info), + (n: 'isc_blob_lookup_desc'; d: {$ifndef FPC}@{$endif}@isc_blob_lookup_desc), + (n: 'isc_blob_set_desc'; d: {$ifndef FPC}@{$endif}@isc_blob_set_desc), + (n: 'isc_cancel_blob'; d: {$ifndef FPC}@{$endif}@isc_cancel_blob), + (n: 'isc_cancel_events'; d: {$ifndef FPC}@{$endif}@isc_cancel_events), + (n: 'isc_close_blob'; d: {$ifndef FPC}@{$endif}@isc_close_blob), + (n: 'isc_commit_retaining'; d: {$ifndef FPC}@{$endif}@isc_commit_retaining), + (n: 'isc_commit_transaction'; d: {$ifndef FPC}@{$endif}@isc_commit_transaction), + (n: 'isc_create_blob'; d: {$ifndef FPC}@{$endif}@isc_create_blob), + (n: 'isc_create_blob2'; d: {$ifndef FPC}@{$endif}@isc_create_blob2), + (n: 'isc_create_database'; d: {$ifndef FPC}@{$endif}@isc_create_database), + (n: 'isc_database_info'; d: {$ifndef FPC}@{$endif}@isc_database_info), + (n: 'isc_decode_date'; d: {$ifndef FPC}@{$endif}@isc_decode_date), + (n: 'isc_decode_sql_date'; d: {$ifndef FPC}@{$endif}@isc_decode_sql_date), + (n: 'isc_decode_sql_time'; d: {$ifndef FPC}@{$endif}@isc_decode_sql_time), + (n: 'isc_decode_timestamp'; d: {$ifndef FPC}@{$endif}@isc_decode_timestamp), + (n: 'isc_detach_database'; d: {$ifndef FPC}@{$endif}@isc_detach_database), + (n: 'isc_drop_database'; d: {$ifndef FPC}@{$endif}@isc_drop_database), + (n: 'isc_dsql_allocate_statement'; d: {$ifndef FPC}@{$endif}@isc_dsql_allocate_statement), + (n: 'isc_dsql_alloc_statement2'; d: {$ifndef FPC}@{$endif}@isc_dsql_alloc_statement2), + (n: 'isc_dsql_describe'; d: {$ifndef FPC}@{$endif}@isc_dsql_describe), + (n: 'isc_dsql_describe_bind'; d: {$ifndef FPC}@{$endif}@isc_dsql_describe_bind), + (n: 'isc_dsql_exec_immed2'; d: {$ifndef FPC}@{$endif}@isc_dsql_exec_immed2), + (n: 'isc_dsql_execute'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute), + (n: 'isc_dsql_execute2'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute2), + (n: 'isc_dsql_execute_immediate'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute_immediate), + (n: 'isc_dsql_fetch'; d: {$ifndef FPC}@{$endif}@isc_dsql_fetch), + (n: 'isc_dsql_finish'; d: {$ifndef FPC}@{$endif}@isc_dsql_finish), + (n: 'isc_dsql_free_statement'; d: {$ifndef FPC}@{$endif}@isc_dsql_free_statement), + (n: 'isc_dsql_insert'; d: {$ifndef FPC}@{$endif}@isc_dsql_insert), + (n: 'isc_dsql_prepare'; d: {$ifndef FPC}@{$endif}@isc_dsql_prepare), + (n: 'isc_dsql_set_cursor_name'; d: {$ifndef FPC}@{$endif}@isc_dsql_set_cursor_name), + (n: 'isc_dsql_sql_info'; d: {$ifndef FPC}@{$endif}@isc_dsql_sql_info), + (n: 'isc_encode_date'; d: {$ifndef FPC}@{$endif}@isc_encode_date), + (n: 'isc_encode_sql_date'; d: {$ifndef FPC}@{$endif}@isc_encode_sql_date), + (n: 'isc_encode_sql_time'; d: {$ifndef FPC}@{$endif}@isc_encode_sql_time), + (n: 'isc_encode_timestamp'; d: {$ifndef FPC}@{$endif}@isc_encode_timestamp), + (n: 'isc_event_block'; d: {$ifndef FPC}@{$endif}@isc_event_block), + (n: 'isc_event_counts'; d: {$ifndef FPC}@{$endif}@isc_event_counts), + (n: 'isc_expand_dpb'; d: {$ifndef FPC}@{$endif}@isc_expand_dpb), + (n: 'isc_modify_dpb'; d: {$ifndef FPC}@{$endif}@isc_modify_dpb), + (n: 'isc_free'; d: {$ifndef FPC}@{$endif}@isc_free), + (n: 'isc_get_segment'; d: {$ifndef FPC}@{$endif}@isc_get_segment), + (n: 'isc_get_slice'; d: {$ifndef FPC}@{$endif}@isc_get_slice), + (n: 'isc_interprete'; d: {$ifndef FPC}@{$endif}@isc_interprete), + (n: 'isc_open_blob'; d: {$ifndef FPC}@{$endif}@isc_open_blob), + (n: 'isc_open_blob2'; d: {$ifndef FPC}@{$endif}@isc_open_blob2), + (n: 'isc_prepare_transaction2'; d: {$ifndef FPC}@{$endif}@isc_prepare_transaction2), + (n: 'isc_print_sqlerror'; d: {$ifndef FPC}@{$endif}@isc_print_sqlerror), + (n: 'isc_print_status'; d: {$ifndef FPC}@{$endif}@isc_print_status), + (n: 'isc_put_segment'; d: {$ifndef FPC}@{$endif}@isc_put_segment), + (n: 'isc_put_slice'; d: {$ifndef FPC}@{$endif}@isc_put_slice), + (n: 'isc_que_events'; d: {$ifndef FPC}@{$endif}@isc_que_events), + (n: 'isc_rollback_retaining'; d: {$ifndef FPC}@{$endif}@isc_rollback_retaining), + (n: 'isc_rollback_transaction'; d: {$ifndef FPC}@{$endif}@isc_rollback_transaction), + (n: 'isc_start_multiple'; d: {$ifndef FPC}@{$endif}@isc_start_multiple), + (n: 'isc_start_transaction'; d: {$ifndef FPC}@{$endif}@isc_start_transaction), + (n: 'isc_sqlcode'; d: {$ifndef FPC}@{$endif}@isc_sqlcode), + (n: 'isc_sql_interprete'; d: {$ifndef FPC}@{$endif}@isc_sql_interprete), + (n: 'isc_transaction_info'; d: {$ifndef FPC}@{$endif}@isc_transaction_info), + (n: 'isc_transact_request'; d: {$ifndef FPC}@{$endif}@isc_transact_request), + (n: 'isc_vax_integer'; d: {$ifndef FPC}@{$endif}@isc_vax_integer), + (n: 'isc_portable_integer'; d: {$ifndef FPC}@{$endif}@isc_portable_integer), + (n: 'isc_add_user'; d: {$ifndef FPC}@{$endif}@isc_add_user), + (n: 'isc_delete_user'; d: {$ifndef FPC}@{$endif}@isc_delete_user), + (n: 'isc_modify_user'; d: {$ifndef FPC}@{$endif}@isc_modify_user), + (n: 'isc_compile_request'; d: {$ifndef FPC}@{$endif}@isc_compile_request), + (n: 'isc_compile_request2'; d: {$ifndef FPC}@{$endif}@isc_compile_request2), + (n: 'isc_ddl'; d: {$ifndef FPC}@{$endif}@isc_ddl), + (n: 'isc_prepare_transaction'; d: {$ifndef FPC}@{$endif}@isc_prepare_transaction), + (n: 'isc_receive'; d: {$ifndef FPC}@{$endif}@isc_receive), + (n: 'isc_reconnect_transaction'; d: {$ifndef FPC}@{$endif}@isc_reconnect_transaction), + (n: 'isc_release_request'; d: {$ifndef FPC}@{$endif}@isc_release_request), + (n: 'isc_request_info'; d: {$ifndef FPC}@{$endif}@isc_request_info), + (n: 'isc_seek_blob'; d: {$ifndef FPC}@{$endif}@isc_seek_blob), + (n: 'isc_send'; d: {$ifndef FPC}@{$endif}@isc_send), + (n: 'isc_start_and_send'; d: {$ifndef FPC}@{$endif}@isc_start_and_send), + (n: 'isc_start_request'; d: {$ifndef FPC}@{$endif}@isc_start_request), + (n: 'isc_unwind_request'; d: {$ifndef FPC}@{$endif}@isc_unwind_request), + (n: 'isc_wait_for_event'; d: {$ifndef FPC}@{$endif}@isc_wait_for_event), + (n: 'isc_close'; d: {$ifndef FPC}@{$endif}@isc_close), + (n: 'isc_declare'; d: {$ifndef FPC}@{$endif}@isc_declare), + (n: 'isc_describe'; d: {$ifndef FPC}@{$endif}@isc_describe), + (n: 'isc_describe_bind'; d: {$ifndef FPC}@{$endif}@isc_describe_bind), + (n: 'isc_execute'; d: {$ifndef FPC}@{$endif}@isc_execute), + (n: 'isc_execute_immediate'; d: {$ifndef FPC}@{$endif}@isc_execute_immediate), + (n: 'isc_fetch'; d: {$ifndef FPC}@{$endif}@isc_fetch), + (n: 'isc_open'; d: {$ifndef FPC}@{$endif}@isc_open), + (n: 'isc_prepare'; d: {$ifndef FPC}@{$endif}@isc_prepare), + (n: 'isc_dsql_execute_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute_m), + (n: 'isc_dsql_execute2_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute2_m), + (n: 'isc_dsql_execute_immediate_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute_immediate_m), + (n: 'isc_dsql_exec_immed3_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_exec_immed3_m), + (n: 'isc_dsql_fetch_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_fetch_m), + (n: 'isc_dsql_insert_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_insert_m), + (n: 'isc_dsql_prepare_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_prepare_m), + (n: 'isc_dsql_release'; d: {$ifndef FPC}@{$endif}@isc_dsql_release), + (n: 'isc_embed_dsql_close'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_close), + (n: 'isc_embed_dsql_declare'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_declare), + (n: 'isc_embed_dsql_describe'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_describe), + (n: 'isc_embed_dsql_describe_bind'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_describe_bind), + (n: 'isc_embed_dsql_execute'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_execute), + (n: 'isc_embed_dsql_execute2'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_execute2), + (n: 'isc_embed_dsql_execute_immed'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_execute_immed), + (n: 'isc_embed_dsql_fetch'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_fetch), + (n: 'isc_embed_dsql_open'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_open), + (n: 'isc_embed_dsql_open2'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_open2), + (n: 'isc_embed_dsql_insert'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_insert), + (n: 'isc_embed_dsql_prepare'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_prepare), + (n: 'isc_embed_dsql_release'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_release), + (n: 'BLOB_open'; d: {$ifndef FPC}@{$endif}@BLOB_open), + (n: 'BLOB_put'; d: {$ifndef FPC}@{$endif}@BLOB_put), + (n: 'BLOB_close'; d: {$ifndef FPC}@{$endif}@BLOB_close), + (n: 'BLOB_get'; d: {$ifndef FPC}@{$endif}@BLOB_get), + (n: 'BLOB_display'; d: {$ifndef FPC}@{$endif}@BLOB_display), + (n: 'BLOB_dump'; d: {$ifndef FPC}@{$endif}@BLOB_dump), + (n: 'BLOB_edit'; d: {$ifndef FPC}@{$endif}@BLOB_edit), + (n: 'BLOB_load'; d: {$ifndef FPC}@{$endif}@BLOB_load), + (n: 'BLOB_text_dump'; d: {$ifndef FPC}@{$endif}@BLOB_text_dump), + (n: 'BLOB_text_load'; d: {$ifndef FPC}@{$endif}@BLOB_text_load), + (n: 'Bopen'; d: {$ifndef FPC}@{$endif}@Bopen), + (n: 'isc_ftof'; d: {$ifndef FPC}@{$endif}@isc_ftof), + (n: 'isc_print_blr'; d: {$ifndef FPC}@{$endif}@isc_print_blr), + (n: 'isc_set_debug'; d: {$ifndef FPC}@{$endif}@isc_set_debug), + (n: 'isc_qtoq'; d: {$ifndef FPC}@{$endif}@isc_qtoq), + (n: 'isc_vtof'; d: {$ifndef FPC}@{$endif}@isc_vtof), + (n: 'isc_vtov'; d: {$ifndef FPC}@{$endif}@isc_vtov), + (n: 'isc_version'; d: {$ifndef FPC}@{$endif}@isc_version), + (n: 'isc_get_client_version'; d: {$ifndef FPC}@{$endif}@isc_get_client_version), + (n: 'isc_get_client_major_version'; d: {$ifndef FPC}@{$endif}@isc_get_client_major_version), + (n: 'isc_get_client_minor_version'; d: {$ifndef FPC}@{$endif}@isc_get_client_minor_version), + (n: 'isc_service_attach'; d: {$ifndef FPC}@{$endif}@isc_service_attach), + (n: 'isc_service_detach'; d: {$ifndef FPC}@{$endif}@isc_service_detach), + (n: 'isc_service_query'; d: {$ifndef FPC}@{$endif}@isc_service_query), + (n: 'isc_service_start'; d: {$ifndef FPC}@{$endif}@isc_service_start) + +{$IFDEF Unix} + , + (n: 'Bopen2'; d: {$ifndef FPC}@{$endif}@Bopen2), + (n: 'isc_reset_fpe'; d: {$ifndef FPC}@{$endif}@isc_reset_fpe), + (n: 'isc_compile_map'; d: {$ifndef FPC}@{$endif}@isc_compile_map), + (n: 'isc_compile_menu'; d: {$ifndef FPC}@{$endif}@isc_compile_menu), + (n: 'isc_compile_sub_map'; d: {$ifndef FPC}@{$endif}@isc_compile_sub_map), + (n: 'isc_create_window'; d: {$ifndef FPC}@{$endif}@isc_create_window), + (n: 'isc_delete_window'; d: {$ifndef FPC}@{$endif}@isc_delete_window), + (n: 'isc_drive_form'; d: {$ifndef FPC}@{$endif}@isc_drive_form), + (n: 'isc_drive_menu'; d: {$ifndef FPC}@{$endif}@isc_drive_menu), + (n: 'isc_form_delete'; d: {$ifndef FPC}@{$endif}@isc_form_delete), + (n: 'isc_form_fetch'; d: {$ifndef FPC}@{$endif}@isc_form_fetch), + (n: 'isc_form_insert'; d: {$ifndef FPC}@{$endif}@isc_form_insert), + (n: 'isc_get_entree'; d: {$ifndef FPC}@{$endif}@isc_get_entree), + (n: 'isc_initialize_menu'; d: {$ifndef FPC}@{$endif}@isc_initialize_menu), + (n: 'isc_menu'; d: {$ifndef FPC}@{$endif}@isc_menu), + (n: 'isc_load_form'; d: {$ifndef FPC}@{$endif}@isc_load_form), + (n: 'isc_pop_window'; d: {$ifndef FPC}@{$endif}@isc_pop_window), + (n: 'isc_put_entree'; d: {$ifndef FPC}@{$endif}@isc_put_entree), + (n: 'isc_reset_form'; d: {$ifndef FPC}@{$endif}@isc_reset_form), + (n: 'isc_suspend_window'; d: {$ifndef FPC}@{$endif}@isc_suspend_window) +{$ENDIF} + , + (n: 'fb_shutdown'; d: @fb_shutdown) + ); + + errormessage = 'Can not load Firebird library. '; +begin +// if length(sonames) = 0 then begin + if useembeddedfirebird then begin + initializedynlib(libinfo,sonames,fbembedlib,[],funcs,errormessage); + //accept missing entries + end + else begin + initializedynlib(libinfo,sonames,fbcgdslib,[],funcs,errormessage); + //accept missing entries + end; +// end +// else begin +// initializedynlib(libinfo,sonames,[],[],funcs,errormessage); + //accept missing entries +// end; +end; + +procedure shutdown(const data: pointer); +begin + //FB-embedded crash on Linux exit, probably atexit() call in FB-lib, + //fb_shutdown() call does not help + //workarond: call + // initializeibase60(fbembedlib); + //at program start in order to prevent unloading of FB-lib + if fb_shutdown <> nil then begin + fb_shutdown(100,-fb_shutrsn_app_stopped); + end; +end; + +Procedure ReleaseIBase60; + +begin + releasedynlib(libinfo,@shutdown); +end; + +initialization + initializelibinfo(libinfo); +finalization + if libinfo.refcount > 0 then begin + libinfo.refcount:= 1; + releaseibase60(); + end; + finalizelibinfo(libinfo); +{$ENDIF} + diff --git a/mseide-msegui/lib/common/db/ibase60.pas b/mseide-msegui/lib/common/db/ibase60.pas new file mode 100644 index 0000000..db7a378 --- /dev/null +++ b/mseide-msegui/lib/common/db/ibase60.pas @@ -0,0 +1,9 @@ +{ +} +unit ibase60; + +{$UNDEF LinkDynamically} + +{$i ibase60.inc} + +end. diff --git a/mseide-msegui/lib/common/db/ibase60dyn.pas b/mseide-msegui/lib/common/db/ibase60dyn.pas new file mode 100644 index 0000000..139087b --- /dev/null +++ b/mseide-msegui/lib/common/db/ibase60dyn.pas @@ -0,0 +1,18 @@ +{ + + + Contains the Interbase/Firebird-functions calls + In this stage only the calls needed for IBConnection are implemented + Other calls could be simply implemented, using copy-paste from ibase60 + + Call InitialiseIbase60 before using any of the calls, and call ReleaseIbase60 + when finished. +} + +unit ibase60dyn; + +{$DEFINE LinkDynamically} + +{$i ibase60.inc} + +end. diff --git a/mseide-msegui/lib/common/db/memds.pp b/mseide-msegui/lib/common/db/memds.pp new file mode 100644 index 0000000..633cabd --- /dev/null +++ b/mseide-msegui/lib/common/db/memds.pp @@ -0,0 +1,987 @@ +{ + This file is part of the Free Component Library (FCL) + Copyright (c) 1999-2000 by the Free Pascal development team + Modified 2007 by Martin Schreiber + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +{$mode objfpc} +{$H+} +{ + TMemDataset : In-memory dataset. + - Has possibility to copy Structure/Data from other dataset. + - Can load/save to/from stream. + + Ideas taken from THKMemTab Component by Harri Kasulke - Hamburg/Germany + E-mail: harri.kasulke@okay.net +} + +unit memds; +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + sysutils,classes,mclasses,mdb,msetypes; +const + // Stream Markers. + MarkerSize = SizeOf(Integer); + + smEOF = 0; + smFieldDefs = 1; + smData = 2; + +type + MDSError=class(Exception); + + PRecInfo=^TMTRecInfo; + TMTRecInfo=record + Bookmark: Longint; + BookmarkFlag: TBookmarkFlag; + end; + + PInteger = ^Integer; + PSmallInt = ^SmallInt; + PInt64 = ^Int64; + PFloat = ^Extended; + PBoolean = ^Boolean; + + TMemDataset=class(TDataSet) + private + FOpenStream : TStream; + FFileName : String; + FFileModified : Boolean; + FStream: TMemoryStream; + FRecInfoOffset: integer; + FRecInfoSize: integer; + FRecCount: integer; + FRecSize: integer; + FRecBufferSize: integer; + FCurrRecNo: integer; + FIsOpen: boolean; + FFilterBuffer: PChar; + ffieldoffsets: integerarty; + freadfieldsizes: integerarty; + fwritefieldsizes: integerarty; + procedure calcrecordlayout; + function MDSGetRecordOffset(ARecNo: integer): longint; + function MDSGetFieldOffset(FieldNo: integer): integer; + function MDSGetBufferSize(FieldNo: integer; out fieldsize: integer): integer; + function MDSGetActiveBuffer(var Buffer: PChar): Boolean; + procedure MDSReadRecord(Buffer:PChar;ARecNo:Integer); + procedure MDSWriteRecord(Buffer:PChar;ARecNo:Integer); + procedure MDSAppendRecord(Buffer:PChar); + function MDSFilterRecord(Buffer: PChar): Boolean; + protected + // Mandatory + function AllocRecordBuffer: PChar; override; + procedure FreeRecordBuffer(var Buffer: PChar); override; + procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override; + function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override; + function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override; + function GetRecordSize: Word; override; + procedure InternalAddRecord(Buffer: Pointer; DoAppend: Boolean); override; + procedure InternalClose; override; + procedure InternalDelete; override; + procedure InternalFirst; override; + procedure InternalGotoBookmark(ABookmark: Pointer); override; + procedure InternalInitFieldDefs; override; + procedure InternalInitRecord(Buffer: PChar); override; + procedure InternalLast; override; + procedure InternalOpen; override; + procedure InternalPost; override; + procedure InternalSetToRecord(Buffer: PChar); override; + function IsCursorOpen: Boolean; override; + procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override; + procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override; + + // Optional. + function GetRecordCount: Integer; override; + procedure SetRecNo(Value: Integer); override; + function GetRecNo: Integer; override; + + // Own. + Procedure RaiseError(Fmt : String; Args : Array of const); + Procedure CheckMarker(F : TStream; Marker : Integer); + Procedure WriteMarker(F : TStream; Marker : Integer); + procedure ReadFieldDefsFromStream(F : TStream); + procedure SaveFieldDefsToStream(F : TStream); + // These should be overridden if you want to load more data. + // E.g. index defs. + Procedure LoadDataFromStream(F : TStream); virtual; + // If SaveData=False, a size 0 block should be written. + Procedure SaveDataToStream(F : TStream; SaveData : Boolean); virtual; + + + public + constructor Create(AOwner:tComponent); override; + destructor Destroy; override; + procedure CreateTable; + + Function DataSize : Integer; + + function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override; + procedure SetFieldData(Field: TField; Buffer: Pointer); override; + procedure Clear(ClearDefs : Boolean); + procedure Clear; + Procedure SaveToFile(AFileName : String); + Procedure SaveToFile(AFileName : String; SaveData : Boolean); + Procedure SaveToStream(F : TStream); + Procedure SaveToStream(F : TStream; SaveData : Boolean); + Procedure LoadFromStream(F : TStream); + Procedure LoadFromFile(AFileName : String); + Procedure CopyFromDataset(DataSet : TDataSet); + Procedure CopyFromDataset(DataSet : TDataSet; CopyData : Boolean); + + Property FileModified : Boolean Read FFileModified; + + published + Property FileName : String Read FFileName Write FFileName; + property Filtered; + Property Active default false; + property AutocalcFields default false; + Property FieldDefs; + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; + property BeforeScroll; + property AfterScroll; + property OnDeleteError; + property OnEditError; + property OnNewRecord; + property OnPostError; + property onmodified; + property OnFilterRecord; + end; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +ResourceString + SErrFieldTypeNotSupported = 'Fieldtype of Field "%s" not supported.'; + SErrBookMarkNotFound = 'Bookmark %d not found.'; + SErrInvalidDataStream = 'Error in data stream at position %d'; + SErrInvalidMarkerAtPos = 'Wrong data stream marker at position %d. Got %d, expected %d'; + SErrNoFileName = 'Filename must not be empty.'; + +const + ormask: array[0..7] of byte = (%00000001,%00000010,%00000100,%00001000, + %00010000,%00100000,%01000000,%10000000); + andmask: array[0..7] of byte = (%11111110,%11111101,%11111011,%11110111, + %11101111,%11011111,%10111111,%01111111); + +procedure unsetfieldisnull(nullmask: pbyte; const x: integer); +//var +// int1: integer; +begin + inc(nullmask,(x shr 3)); + nullmask^:= nullmask^ or ormask[x and 7]; +end; + +procedure setfieldisnull(nullmask: pbyte; const x: integer); +begin + inc(nullmask,(x shr 3)); + nullmask^:= nullmask^ and andmask[x and 7]; +end; + +function getfieldisnull(nullmask: pbyte; const x: integer): boolean; +begin + inc(nullmask,(x shr 3)); + result:= nullmask^ and ormask[x and 7] = 0; +end; + + +{ --------------------------------------------------------------------- + Stream functions + ---------------------------------------------------------------------} + +Function ReadInteger(S : TStream) : Integer; + +begin + S.ReadBuffer(Result,SizeOf(Result)); +end; + +Function ReadString(S : TStream) : String; + +Var + L : Integer; + +begin + L:=ReadInteger(S); + Setlength(Result,L); + If (L<>0) then + S.ReadBuffer(Result[1],L); +end; + +Procedure WriteInteger(S : TStream; Value : Integer); + +begin + S.WriteBuffer(Value,SizeOf(Value)); +end; + +Procedure WriteString(S : TStream; Value : String); + +Var + L : Integer; + +begin + L:=Length(Value); + WriteInteger(S,Length(Value)); + If (L<>0) then + S.WriteBuffer(Value[1],L); +end; + +{ --------------------------------------------------------------------- + TMemDataset + ---------------------------------------------------------------------} + + +constructor TMemDataset.Create(AOwner:tComponent); + +begin + inherited create(aOwner); + FStream:=TMemoryStream.Create; + FRecInfoSize:=SizeOf(TMTRecInfo); + FRecCount:=0; + FRecSize:=0; + FRecBufferSize:=0; + FRecInfoOffset:=0; + FCurrRecNo:=-1; + FIsOpen:=False; +end; + +Destructor TMemDataset.Destroy; +begin + FStream.Free; + inherited Destroy; +end; + +function TMemDataset.MDSGetRecordOffset(ARecNo: integer): longint; +begin + Result:=FRecSize*ARecNo +end; + +function TMemDataset.MDSGetFieldOffset(FieldNo: integer): integer; +begin + result:= ffieldoffsets[fieldno-1]; +end; + +Procedure TMemDataset.RaiseError(Fmt : String; Args : Array of const); + +begin + Raise MDSError.CreateFmt(Fmt,Args); +end; + +function TMemDataset.MDSGetBufferSize(FieldNo: integer; + out fieldsize: integer): integer; +var + dt1: tfieldtype; +begin + result:= 0; //compiler warning + dt1:= FieldDefs.Items[FieldNo-1].Datatype; + case dt1 of + ftString: result:=FieldDefs.Items[FieldNo-1].Size+1; + ftBoolean: result:=SizeOf(Wordbool{Boolean}); + ftFloat,ftcurrency: result:=SizeOf(Double{Extended}); + ftLargeInt: result:=SizeOf(int64); + ftSmallInt: result:=SizeOf(SmallInt); + ftInteger: result:=SizeOf(Integer); + ftDate: result:=SizeOf(TDateTime); + ftTime: result:=SizeOf(TDateTime); + else + RaiseError(SErrFieldTypeNotSupported,[FieldDefs.Items[FieldNo-1].Name]); + end; + if dt1 = ftstring then begin + fieldsize:= result - 1; + end + else begin + fieldsize:= result; + end; +end; + +function TMemDataset.MDSGetActiveBuffer(var Buffer: PChar): Boolean; + +begin + case State of + dsBrowse: + if IsEmpty then + Buffer:=nil + else + Buffer:=ActiveBuffer; + + dsEdit, + dsInsert: + Buffer:=ActiveBuffer; + dsFilter: + Buffer:=FFilterBuffer; + else + Buffer:=nil; + end; + Result:=(Buffer<>nil); +end; + +procedure TMemDataset.MDSReadRecord(Buffer:PChar;ARecNo:Integer); //Reads a Rec from Stream in Buffer +begin + FStream.Position:=MDSGetRecordOffset(ARecNo); + FStream.ReadBuffer(Buffer^, FRecSize); +end; + +procedure TMemDataset.MDSWriteRecord(Buffer:PChar;ARecNo:Integer); //Writes a Rec from Buffer to Stream +begin + FStream.Position:=MDSGetRecordOffset(ARecNo); + FStream.WriteBuffer(Buffer^, FRecSize); + FFileModified:=True; +end; + +procedure TMemDataset.MDSAppendRecord(Buffer:PChar); //Appends a Rec (from Buffer) to Stream +begin + FStream.Position:=MDSGetRecordOffset(FRecCount); + FStream.WriteBuffer(Buffer^, FRecSize); + FFileModified:=True; +end; + +//Abstract Overrides +function TMemDataset.AllocRecordBuffer: PChar; +begin + GetMem(Result,FRecBufferSize); +end; + +procedure TMemDataset.FreeRecordBuffer (var Buffer: PChar); +begin + FreeMem(Buffer); +end; + +procedure TMemDataset.InternalInitRecord(Buffer: PChar); + +//var +// I : integer; + +begin + fillchar(buffer^,frecsize,0); +end; + +procedure TMemDataset.InternalDelete; + +Var + TS : TMemoryStream; +// OldPos,NewPos,CopySize1,CopySize2 : longword; + +begin + if (FCurrRecNo<0) or (FCurrRecNo>=FRecCount) then + Exit; + // Very inefficient. We should simply move the last part closer to the beginning in + // The FStream. + TS:=TMemoryStream.Create; + Try + if FCurrRecNo>0 then + begin + FStream.Position:=MDSGetRecordOffset(0); //Delete Rec + if FCurrRecNo=FRecCount then FCurrRecNo:=FRecCount-1; + Finally + TS.Free; + end; + FFileModified:=True; +end; + +procedure TMemDataset.InternalInitFieldDefs; + +begin + If (FOpenStream<>Nil) then + ReadFieldDefsFromStream(FOpenStream); +end; + +Procedure TMemDataset.CheckMarker(F : TStream; Marker : Integer); + +Var + I,P : Integer; + +begin + P:=F.Position; + If F.Read(I,MarkerSize)<>MarkerSize then + RaiseError(SErrInvalidDataStream,[P]) + else + if (I<>Marker) then + RaiseError(SErrInvalidMarkerAtPos,[P,I,Marker]); +end; + +procedure TMemDataset.ReadFieldDefsFromStream(F : TStream); + +Var + I,ACount : Integer; + FN : String; + FS : Integer; + B : Boolean; + FT : TFieldType; + +begin + CheckMarker(F,smFieldDefs); + FieldDefs.Clear; + ACount:=ReadInteger(F); + For I:=1 to ACount do + begin + FN:=ReadString(F); + FS:=ReadInteger(F); + FT:=TFieldType(ReadInteger(F)); + B:=ReadInteger(F)<>0; + TFieldDef.Create(FieldDefs,FN,ft,FS,B,I); + end; + CreateTable; +end; + +procedure TMemDataset.InternalFirst; +begin + FCurrRecNo:=-1; +end; + +procedure TMemDataset.InternalLast; +begin + FCurrRecNo:=FRecCount; +end; + +procedure TMemDataset.InternalOpen; + + +begin + If (FFileName<>'') then + FOpenStream:=TFileStream.Create(FFileName,fmOpenRead); + Try + InternalInitFieldDefs; + if DefaultFields then + CreateFields; + BindFields(True); + FCurrRecNo:=-1; + If (FOpenStream<>Nil) then + begin + LoadDataFromStream(FOpenStream); + CheckMarker(FOpenStream,smEOF); + end; + Finally + FreeAndNil(FOpenStream); + end; + FIsOpen:=True; +end; + +Procedure TMemDataSet.LoadDataFromStream(F : TStream); + +Var + Size : Integer; + +begin + CheckMarker(F,smData); + Size:=ReadInteger(F); + FStream.Clear; + FStream.CopyFrom(F,Size); + FRecCount:=Size div FRecSize; + FCurrRecNo:=-1; +end; + +Procedure TMemDataSet.LoadFromStream(F : TStream); + +begin + Close; + ReadFieldDefsFromStream(F); + LoadDataFromStream(F); + CheckMarker(F,smEOF); + FFileModified:=False; +end; + +Procedure TMemDataSet.LoadFromFile(AFileName : String); + +Var + F : TFileStream; + +begin + F:=TFileStream.Create(AFileName,fmOpenRead); + Try + LoadFromStream(F); + Finally + F.Free; + end; +end; + + +Procedure TMemDataset.SaveToFile(AFileName : String); + +begin + SaveToFile(AFileName,True); +end; + +Procedure TMemDataset.SaveToFile(AFileName : String; SaveData : Boolean); + +Var + F : TFileStream; + +begin + If (AFileName='') then + RaiseError(SErrNoFileName,[]); + F:=TFileStream.Create(AFileName,fmCreate); + try + SaveToStream(F,SaveData); + Finally + F.Free; + end; +end; + +Procedure TMemDataset.WriteMarker(F : TStream; Marker : Integer); + +begin + Writeinteger(F,Marker); +end; + +Procedure TMemDataset.SaveToStream(F : TStream); + +begin + SaveToStream(F,True); +end; + +Procedure TMemDataset.SaveToStream(F : TStream; SaveData : Boolean); + +begin + SaveFieldDefsToStream(F); + If SaveData then + SaveDataToStream(F,SaveData); + WriteMarker(F,smEOF); +end; + +Procedure TMemDataset.SaveFieldDefsToStream(F : TStream); + +Var + I{,ACount} : Integer; +// FN : String; +// FS : Integer; +// B : Boolean; +// FT : TFieldType; + FD : TFieldDef; + +begin + WriteMarker(F,smFieldDefs); + WriteInteger(F,FieldDefs.Count); + For I:=1 to FieldDefs.Count do + begin + FD:=FieldDefs[I-1]; + WriteString(F,FD.Name); + WriteInteger(F,FD.Size); + WriteInteger(F,Ord(FD.DataType)); + WriteInteger(F,Ord(FD.Required)); + end; +end; + +Procedure TMemDataset.SaveDataToStream(F : TStream; SaveData : Boolean); + +begin + if SaveData then + begin + WriteMarker(F,smData); + WriteInteger(F,FStream.Size); + FStream.Position:=0; + F.CopyFrom(FStream,FStream.Size); + FFileModified:=False; + end + else + begin + WriteMarker(F,smData); + WriteInteger(F,0); + end; +end; + +procedure TMemDataset.InternalClose; + +begin + if (FFileModified) and (FFileName<>'') then begin + SaveToFile(FFileName,True); + end; + FIsOpen:=False; + FFileModified:=False; + BindFields(False); + if DefaultFields then begin + DestroyFields; + end; + ffieldoffsets:= nil; + freadfieldsizes:= nil; + fwritefieldsizes:= nil; +end; + +procedure TMemDataset.InternalPost; +begin + CheckActive; + if ((State<>dsEdit) and (State<>dsInsert)) then + Exit; + if (State=dsEdit) then + MDSWriteRecord(ActiveBuffer, FCurrRecNo) + else + InternalAddRecord(ActiveBuffer,True); +end; + +function TMemDataset.IsCursorOpen: Boolean; + +begin + Result:=FIsOpen; +end; + +function TMemDataset.GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult; + +var + Accepted: Boolean; + +begin + Result:=grOk; + Accepted:=False; + if (FRecCount<1) then + begin + Result:=grEOF; + exit; + end; + repeat + case GetMode of + gmCurrent: + if (FCurrRecNo>=FRecCount) or (FCurrRecNo<0) then + Result:=grError; + gmNext: + if (FCurrRecNo0) then + Dec(FCurrRecNo) + else + result:=grBOF; + end; + if result=grOK then + begin + MDSReadRecord(Buffer, FCurrRecNo); + PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=FCurrRecNo; + PRecInfo(Buffer+FRecInfoOffset)^.BookmarkFlag:=bfCurrent; + if (Filtered) then + Accepted:=MDSFilterRecord(Buffer) //Filtering + else + Accepted:=True; + if (GetMode=gmCurrent) and not Accepted then + result:=grError; + end; + until (result<>grOK) or Accepted; +end; + +function TMemDataset.GetFieldData(Field: TField; Buffer: Pointer): Boolean; +var + SrcBuffer: PChar; + int1: integer; +begin + int1:= Field.FieldNo - 1; + result:= (int1 >= 0) and MDSGetActiveBuffer(SrcBuffer) and + not getfieldisnull(pointer(srcbuffer),int1); + if result and (buffer <> nil) then begin + Move((SrcBuffer+ffieldoffsets[int1])^, Buffer^,freadfieldsizes[int1]); + end; +end; + +procedure TMemDataset.SetFieldData(Field: TField; Buffer: Pointer); +var + DestBuffer: PChar; + int1: integer; + +begin + int1:= Field.FieldNo - 1; + if (int1 >= 0) and MDSGetActiveBuffer(DestBuffer) then begin + if buffer = nil then begin + setfieldisnull(pointer(destbuffer),int1); + end + else begin + unsetfieldisnull(pointer(destbuffer),int1); + Move(Buffer^,(DestBuffer+ffieldoffsets[int1])^,fwritefieldsizes[int1]); + dataevent(defieldchange,ptrint(field)); + end; + end; +end; + +function TMemDataset.GetRecordSize: Word; + +begin + Result:= FRecSize; +end; + +procedure TMemDataset.InternalGotoBookmark(ABookmark: Pointer); + +var + ReqBookmark: integer; + +begin + ReqBookmark:=PInteger(ABookmark)^; + if (ReqBookmark>=0) and (ReqBookmarknil then + PInteger(Data)^:=PRecInfo(Buffer+FRecInfoOffset)^.Bookmark; +end; + +procedure TMemDataset.SetBookmarkData(Buffer: PChar; Data: Pointer); + +begin + if Data<>nil then + PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=PInteger(Data)^ + else + PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=0; +end; + +function TMemDataset.MDSFilterRecord(Buffer: PChar): Boolean; + +var + SaveState: TDatasetState; + +begin + Result:=True; + if not Assigned(OnFilterRecord) then + Exit; + SaveState:=SetTempState(dsFilter); + FFilterBuffer:=Buffer; + OnFilterRecord(Self,Result); + RestoreState(SaveState); +end; + +Function TMemDataset.DataSize : Integer; + +begin + Result:=FStream.Size; +end; + +procedure TMemDataset.Clear; + +begin + Clear(True); +end; + +procedure TMemDataset.Clear(ClearDefs : Boolean); + +begin + FStream.Clear; + FRecCount:=0; + FCurrRecNo:=-1; + if Active then + Resync([]); + If ClearDefs then + begin + Close; + FieldDefs.Clear; + end; +end; + +procedure tmemdataset.calcrecordlayout; +var + int1: integer; +begin + int1:= fielddefs.count; + setlength(ffieldoffsets,int1); + setlength(freadfieldsizes,int1); + setlength(fwritefieldsizes,int1); + FRecSize:= (int1+7) div 8; //null mask + for int1:= 0 to high(ffieldoffsets) do begin + ffieldoffsets[int1]:= frecsize; + freadfieldsizes[int1]:= MDSGetbufferSize(int1+1,fwritefieldsizes[int1]); + FRecSize:= FRecSize + freadfieldsizes[int1]; + end; +end; + +procedure TMemDataset.CreateTable; + +begin + FStream.Clear; + FRecCount:=0; + FCurrRecNo:=-1; + FIsOpen:=False; + calcrecordlayout; + FRecInfoOffset:=FRecSize; + FRecSize:=FRecSize+FRecInfoSize; + FRecBufferSize:=FRecSize; +end; + +procedure TMemDataset.InternalAddRecord(Buffer: Pointer; DoAppend: Boolean); + +begin + MDSAppendRecord(ActiveBuffer); + InternalLast; + Inc(FRecCount); +end; + +procedure TMemDataset.SetRecNo(Value: Integer); +begin + CheckBrowseMode; + if (Value>=1) and (Value<=FRecCount) then + begin + FCurrRecNo:=Value-1; + Resync([]); + end; +end; + +Function TMemDataset.GetRecNo: Longint; + +begin + UpdateCursorPos; + if (FCurrRecNo<0) then + Result:=1 + else + Result:=FCurrRecNo+1; +end; + +Function TMemDataset.GetRecordCount: Longint; + +begin + CheckActive; + Result:=FRecCount; +end; + +Procedure TMemDataset.CopyFromDataset(DataSet : TDataSet); + +begin + CopyFromDataset(Dataset,True); +end; + +Procedure TMemDataset.CopyFromDataset(DataSet : TDataSet; CopyData : Boolean); + +Var + I : Integer; + F,F1,F2 : TField; + L1,L2 : TList; + N : String; + +begin + Clear(True); + // NOT from fielddefs. The data may not be available in buffers !! + For I:=0 to Dataset.FieldCount-1 do + begin + F:=Dataset.Fields[I]; + TFieldDef.Create(FieldDefs,F.FieldName,F.DataType,F.Size,F.Required,F.FieldNo); + end; + CreateTable; + If CopyData then + begin + Open; + L1:=TList.Create; + Try + L2:=TList.Create; + Try + For I:=0 to FieldDefs.Count-1 do + begin + N:=FieldDefs[I].Name; + F1:=FieldByName(N); + F2:=DataSet.FieldByName(N); + L1.Add(F1); + L2.Add(F2); + end; + Dataset.DisableControls; + Try + Dataset.Open; + While not Dataset.EOF do + begin + Append; + For I:=0 to L1.Count-1 do + begin + F1:=TField(L1[i]); + F2:=TField(L2[I]); + Case F1.DataType of + ftString : F1.AsString:=F2.AsString; + ftBoolean : F1.AsBoolean:=F2.AsBoolean; + ftFloat,ftcurrency : F1.AsFloat:=F2.AsFloat; + ftLargeInt : F1.AsInteger:=F2.AsInteger; + ftSmallInt : F1.AsInteger:=F2.AsInteger; + ftInteger : F1.AsInteger:=F2.AsInteger; + ftDate : F1.AsDateTime:=F2.AsDateTime; + ftTime : F1.AsDateTime:=F2.AsDateTime; + end; + end; + Try + Post; + except + Cancel; + Raise; + end; + Dataset.Next; + end; + Finally + Dataset.EnableControls; + end; + finally + L2.Free; + end; + finally + l1.Free; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/mibconnection.pas b/mseide-msegui/lib/common/db/mibconnection.pas new file mode 100644 index 0000000..5210be2 --- /dev/null +++ b/mseide-msegui/lib/common/db/mibconnection.pas @@ -0,0 +1,1827 @@ +{ + Copyright (c) 2004 by Joost van der Sluis + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + Modified 2006-2013 by Martin Schreiber + + **********************************************************************} + +unit mibconnection; +{$ifdef FPC}{$mode objfpc}{$H+}{$macro on}{$endif} +{$ifdef linux}{$define unix}{$endif} + +{$Define LinkDynamically} +{$R-} +(* +{$IFDEF Unix} + {$DEFINE extdecl:=cdecl} +{$else} + {$DEFINE extdecl:=stdcall} +{$endif} +*) +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +//todo: use execute_immediate if possible + +uses + classes,mclasses,SysUtils,msqldb,mdb,math, + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},msebufdataset,msedbevents, + msesystypes,msestrings,msedb,msetypes, +{$IfDef LinkDynamically} + ibase60dyn; +{$Else} + ibase60; +{$EndIf} + +type + tibconnection = class; + statusvectorty = array[0..19] of ISC_STATUS; + + eiberror = class(econnectionerror) + private + fstatus: statusvectorty; + fsqlcode: integer; + public + constructor create(const asender: tibconnection; const amessage: msestring; + const aerror: statusvectorty; const asqlcode: integer); + property status: statusvectorty read fstatus; + property sqlcode: integer read fsqlcode; + end; + + TIBCursor = Class(TSQLCursor) + protected + fconnection: tibconnection; + fopen: boolean; + ffetched: boolean; + fempty: boolean; + Status : statusvectorty; + Statement : pointer; + fibstatementtype: integer; + SQLDA : PXSQLDA; + in_SQLDA : PXSQLDA; + fexecsqlda: pxsqlda; + ParamBinding : tparambinding; + paramtypes: fieldtypearty; + public + constructor create(const aowner: icursorclient; + const aconnection: tibconnection); + procedure close; override; + end; + + TIBTrans = Class(TSQLHandle) + protected + TransactionHandle : pointer; + TPB : string; // Transaction parameter buffer + Status : statusvectorty; + end; + + fbeventbufferty = record + event: tdbevent; + name: string; + length: integer; + eventbuffer: pchar; + resultbuffer: pchar; + id: isc_long; + count: integer; + end; + pfbeventbufferty = ^fbeventbufferty; + + ibconnectionoptionty = (ibo_embedded,ibo_sqlinfo); + ibconnectionoptionsty = set of ibconnectionoptionty; + + fbversionty = record + imp: stringarty; + ods: string; + end; + + TIBConnection = class (TSQLConnection,iblobconnection, + idbevent,idbeventcontroller) + private + FSQLDatabaseHandle : pointer; + FStatus : statusvectorty; //array [0..19] of ISC_STATUS; + FDialect : integer; + feventcontroller: tdbeventcontroller; + feventbuffers: array of pfbeventbufferty; + feventcount: integer; + fmutex: mutexty; + foptions: ibconnectionoptionsty; + flasterror: statusvectorty; + flasterrormessage: msestring; + flastsqlcode: integer; + procedure SetDBDialect; + procedure AllocSQLDA(var aSQLDA : PXSQLDA;Count : integer); + procedure TranslateFldType(SQLType,sqlsubtype,SQLLen,SQLScale: integer; + out TrType: TFieldType; out TrLen: word); + //conversion methods + procedure GetDateTime(CurrBuff, Buffer : pointer; AType : integer); + procedure SetDateTime(CurrBuff: pointer; PTime : TDateTime; AType : integer); + procedure GetFloat(const CurrBuff,Buffer: pointer; + const datalength: integer); + procedure SetFloat(CurrBuff: pointer; Dbl: Double; Size: integer); + procedure CheckError(const ProcName : string; + const Status : statusvectorty); overload; + procedure CheckError(const ProcName : string; + const Status: integer); overload; + function getMaxBlobSize(blobHandle : TIsc_Blob_Handle) : longInt; + procedure SetParameters(cursor : TSQLCursor;AParams : TmseParams); + procedure FreeSQLDABuffer(var aSQLDA : PXSQLDA); + function getblobstream(const acursor: tsqlcursor; const blobid: isc_quad; + const forstring: boolean = false): tmemorystream; + function getblobstring(const acursor: tsqlcursor; + const blobid: isc_quad): string; + protected + procedure freeeventbuffer(var abuffer: pfbeventbufferty); + + procedure DoInternalConnect; override; + procedure DoInternalDisconnect; override; + function GetHandle : pointer; override; + + Function AllocateTransactionHandle : TSQLHandle; override; + + procedure internalExecute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; const AParams : TmseParams; + const autf8: boolean); override; + function fetch1(const cursor: tibcursor) : boolean; + function GetTransactionHandle(trans : TSQLHandle): pointer; override; + function Commit(trans : TSQLHandle) : boolean; override; + function RollBack(trans : TSQLHandle) : boolean; override; + function StartdbTransaction(const trans : TSQLHandle; + const AParams : tstringlist) : boolean; override; + procedure internalCommitRetaining(trans : TSQLHandle); override; + procedure internalRollBackRetaining(trans : TSQLHandle); override; + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); override; + function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, + SchemaPattern : msestring) : msestring; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + function getblobdatasize: integer; override; + + procedure writeblobdata(const atransactionhandle: pointer; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); + overload; + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); + overload; + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); +// function blobscached: boolean; + //idbevent + procedure listen(const sender: tdbevent); + procedure unlisten(const sender: tdbevent); + procedure fire(const sender: tdbevent); + //idbeventcontroller + function getdbevent(var aname: string; var aid: int64): boolean; + //false if none + procedure dolisten(const sender: tdbevent); + procedure dounlisten(const sender: tdbevent); + public + constructor Create(AOwner : TComponent); override; + destructor destroy; override; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; override; + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + procedure UnPrepareStatement(cursor : TSQLCursor); override; + procedure FreeFldBuffers(cursor : TSQLCursor); override; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); override; + function Fetch(cursor : TSQLCursor) : boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //zero based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //zero based + procedure createdatabase(const asql: ansistring); + function version: fbversionty; + property lasterror: statusvectorty read flasterror; + property lasterrormessage: msestring read flasterrormessage; + property lastsqlcode: integer read flastsqlcode; + published + property Dialect : integer read FDialect write FDialect default 0; + property options: ibconnectionoptionsty read foptions + write foptions default []; + property DatabaseName; + property KeepConnection; + property Params; + property ongetcredentials; + end; + +function clientversion: string; +function clientmajorversion: integer; +function clientminorversion: integer; + //library must be inited before calling + +implementation +uses + strutils,msesysintf1,msebits,msefloattostr,msedatabase,msesqlresult,msefbutils + {$ifndef FPC},classes_del{$ifdef mswindows},windows{$endif}{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function clientversion: string; +var + buf: array[0..255] of char; +begin + result:= ''; + if assigned(isc_get_client_version) then begin + isc_get_client_version(@buf); + result:= buf; + end; +end; + +function clientmajorversion: integer; +begin + if assigned(isc_get_client_major_version) then begin + result:= isc_get_client_major_version(); + end + else begin + result:= -1; + end; +end; + +function clientminorversion: integer; +begin + if assigned(isc_get_client_minor_version) then begin + result:= isc_get_client_minor_version(); + end + else begin + result:= -1; + end; +end; + +type + TTm = packed record + tm_sec : longint; + tm_min : longint; + tm_hour : longint; + tm_mday : longint; + tm_mon : longint; + tm_year : longint; + tm_wday : longint; + tm_yday : longint; + tm_isdst : longint; + __tm_gmtoff : longint; + __tm_zone : Pchar; + end; + +{ TIBCursor } + +procedure TIBCursor.close; +begin + inherited; + if fopen and (fibstatementtype = isc_info_sql_stmt_select) then begin + if isc_dsql_free_statement(@status, @statement, dsql_close) <> 0 then begin + fconnection.checkerror('close cursor', status{,fname}); + end; + end; + fopen:= false; +end; + +constructor TIBCursor.create(const aowner: icursorclient; + const aconnection: tibconnection); +begin + fconnection:= aconnection; + inherited create(aowner,fconnection.name); +end; + +{ tibconnection } + +procedure TIBConnection.CheckError(const ProcName : string; + const Status: statusvectorty); +var + buf: array [0..1024] of char; + p: pointer; + Msg: msestring; +begin + if ((Status[0] = 1) and (Status[1] <> 0)) then begin + p:= @Status; + msg:= msestring(procname); +{$warnings off} + while isc_interprete(Buf, @p) > 0 do begin + Msg := Msg + lineend +' -' + connectionmessage(Buf); + end; + flasterror:= status; + flasterrormessage:= msg; + flastsqlcode:= isc_sqlcode(@status); + raise eiberror.create(self,msg,status,flastsqlcode); + end; +end; +{$warnings on} + +procedure tibconnection.CheckError(const ProcName : string; + const Status: integer); +begin + if status <> 0 then begin + checkerror(procname,fstatus); + end; +end; + +constructor TIBConnection.Create(AOwner : TComponent); + +begin + sys_mutexcreate(fmutex); + feventcontroller:= tdbeventcontroller.create(idbeventcontroller(self)); + feventcontroller.eventinterval:= -1; //event driven + inherited; + FConnOptions := FConnOptions + [sco_SupportParams,sco_nounprepared]; +end; + +destructor TIBConnection.destroy; +begin + inherited; + feventcontroller.free; + sys_mutexdestroy(fmutex); +end; + +function TIBConnection.GetTransactionHandle(trans : TSQLHandle): pointer; +begin + Result:= TIBtrans(trans).TransactionHandle; +end; + +function TIBConnection.Commit(trans : TSQLHandle) : boolean; +begin + result := false; + with (trans as TIBTrans) do + if isc_commit_transaction(@Status, @TransactionHandle) <> 0 then + CheckError('Commit', Status) + else result := true; +end; + +function TIBConnection.RollBack(trans : TSQLHandle) : boolean; +begin + result:= false; + if isc_rollback_transaction(@TIBTrans(trans).Status, + @TIBTrans(trans).TransactionHandle) <> 0 then begin + CheckError('Rollback', TIBTrans(trans).Status); + end + else begin + result := true; + end; +end; + +function TIBConnection.StartDBTransaction( + const trans : TSQLHandle; const AParams : tstringlist) : boolean; +var + DBHandle : pointer; + tr : TIBTrans; + s : string; + int1: integer; + s2: string; + i2: int32; + + procedure paramerror(); + begin + raise econnectionerror.create(self, + 'Invalid transaction parameter "'+s+'"','',0); + end; //paramerror + +begin + result := false; + + DBHandle := GetHandle; + tr := trans as TIBtrans; + with tr do begin + TPB := chr(isc_tpb_version3); + for int1:= 0 to aparams.count - 1 do begin + s:= trim(aparams[int1]); + if s='isc_tpb_write' then TPB := TPB + chr(isc_tpb_write) + else if s='isc_tpb_read' then TPB := TPB + chr(isc_tpb_read) + else if s='isc_tpb_consistency' then TPB := TPB + chr(isc_tpb_consistency) + else if s='isc_tpb_concurrency' then TPB := TPB + chr(isc_tpb_concurrency) + else if s='isc_tpb_read_committed' then TPB := TPB + chr(isc_tpb_read_committed) + else if s='isc_tpb_rec_version' then TPB := TPB + chr(isc_tpb_rec_version) + else if s='isc_tpb_no_rec_version' then TPB := TPB + chr(isc_tpb_no_rec_version) + else if s='isc_tpb_wait' then TPB := TPB + chr(isc_tpb_wait) + else if s='isc_tpb_nowait' then TPB := TPB + chr(isc_tpb_nowait) + else if s='isc_tpb_shared' then TPB := TPB + chr(isc_tpb_shared) + else if s='isc_tpb_protected' then TPB := TPB + chr(isc_tpb_protected) + else if s='isc_tpb_exclusive' then TPB := TPB + chr(isc_tpb_exclusive) + else if s='isc_tpb_lock_read' then TPB := TPB + chr(isc_tpb_lock_read) + else if s='isc_tpb_lock_write' then TPB := TPB + chr(isc_tpb_lock_write) + else if s='isc_tpb_verb_time' then TPB := TPB + chr(isc_tpb_verb_time) + else if s='isc_tpb_commit_time' then TPB := TPB + chr(isc_tpb_commit_time) + else if s='isc_tpb_ignore_limbo' then TPB := TPB + chr(isc_tpb_ignore_limbo) + else if s='isc_tpb_autocommit' then TPB := TPB + chr(isc_tpb_autocommit) + else if s='isc_tpb_restart_requests' then TPB := TPB + chr(isc_tpb_restart_requests) + else if s='isc_tpb_no_auto_undo' then TPB := TPB + chr(isc_tpb_no_auto_undo) + else if pos('isc_tpb_lock_timeout',s) = 1 then begin + i2:= length('isc_tpb_lock_timeout'); + if length(s) > i2 then begin + s2:= trim(copy(s,i2+1,bigint)); + if trystrtoint(s2,i2) then begin + tpb:= tpb + chr(isc_tpb_lock_timeout)+#4+ + chr(i2)+chr(i2 shr 8)+chr(i2 shr 16)+chr(i2 shr 24); + end + else begin + paramerror(); + end; + end + else begin + paramerror(); + end; + end; + end; + TransactionHandle := nil; + if isc_start_transaction(@Status, @TransactionHandle, 1, + [@DBHandle, Length(TPB), @TPB[1]]) <> 0 then begin + CheckError('StartTransaction',Status); + end + else begin + Result:= True; + end; + end; +end; + +procedure TIBConnection.internalCommitRetaining(trans : TSQLHandle); +begin + with trans as TIBtrans do + if isc_commit_retaining(@Status, @TransactionHandle) <> 0 then + CheckError('CommitRetaining', Status); +end; + +procedure TIBConnection.internalRollBackRetaining(trans : TSQLHandle); +begin + with trans as TIBtrans do + if isc_rollback_retaining(@Status, @TransactionHandle) <> 0 then + CheckError('RollBackRetaining', Status); +end; + + +procedure TIBConnection.DoInternalConnect; +const + utf8name = 'UTF8'; +var + DPB : string; + ADatabaseName : String; + u,p: msestring; + u1,p1: string; + s1: string; +begin +{$IfDef LinkDynamically} + useembeddedfirebird:= ibo_embedded in foptions; + InitializeIBase60([]); + try +{$EndIf} + inherited dointernalconnect; + getcredentials(u,p); + DPB:= chr(isc_dpb_version1); + if (u <> '') then begin + u1:= ansistring(u); + DPB := DPB + chr(isc_dpb_user_name) + chr(Length(u1)) + u1; + stringsafefree(u1,false); + if (p <> '') then begin + p1:= ansistring(p); + DPB := DPB + chr(isc_dpb_password) + chr(Length(p1)) + p1; + stringsafefree(p1,false); + end; + end; + freecredentials(u,p); + if (Role <> '') then begin + s1:= ansistring(role); + DPB := DPB + chr(isc_dpb_sql_role_name) + chr(Length(s1)) + s1; + end; + if Length(CharSet) > 0 then begin + s1:= ansistring(charset); + DPB := DPB + Chr(isc_dpb_lc_ctype) + Chr(Length(s1)) + s1; + end + else begin + if dbo_utf8 in fcontroller.options then begin + DPB := DPB + Chr(isc_dpb_lc_ctype) + Chr(Length(utf8name)) + utf8name; + end; + end; + + FSQLDatabaseHandle := nil; + if HostName <> '' then ADatabaseName := ansistring(HostName)+':'+ + ansistring(DatabaseName) + else ADatabaseName := ansistring(DatabaseName); + if isc_attach_database(@FStatus, Length(ADatabaseName), @ADatabaseName[1], + @FSQLDatabaseHandle,Length(DPB), @DPB[1]) <> 0 then + stringsafefree(dpb,false); + CheckError('DoInternalConnect', FStatus); + stringsafefree(dpb,false); + SetDBDialect; +{$IfDef LinkDynamically} + except + releaseIBase60; + raise; + end; +{$EndIf} + feventcontroller.connect; +end; + +procedure TIBConnection.DoInternalDisconnect; +begin + feventcontroller.disconnect; + if not Connected then begin + FSQLDatabaseHandle:= nil; + Exit; + end; + isc_detach_database(@FStatus[0], @FSQLDatabaseHandle); +// CheckError('Close', FStatus); //no exception on close +{$IfDef LinkDynamically} + ReleaseIBase60; +{$EndIf} +end; + +procedure TIBConnection.SetDBDialect; +const + bufferlength = 40; +var + x : integer; + Len : integer; + Buffer : string; + ResBuf : array [0..bufferlength-1] of byte; + by1: byte; +begin + Buffer:= Chr(isc_info_db_sql_dialect) + Chr(isc_info_end); + if isc_database_info(@FStatus, @FSQLDatabaseHandle, Length(Buffer), + @Buffer[1], SizeOf(ResBuf), @ResBuf) <> 0 then begin + CheckError('SetDBDialect', FStatus); + end; + x := 0; + while x < bufferlength do begin + by1:= resbuf[x]; + inc(x); + len:= isc_vax_integer(@ResBuf[x], 2); + inc(x,2); + case by1 of + isc_info_db_sql_dialect: begin + FDialect:= isc_vax_integer(@ResBuf[x], Len); + end; + isc_info_end: begin + Break; + end; + end; + inc(x,len); + end; +end; + +procedure TIBConnection.AllocSQLDA(var aSQLDA : PXSQLDA;Count : integer); +begin + FreeSQLDABuffer(aSQLDA); + + if count > -1 then + begin + reAllocMem(aSQLDA, XSQLDA_Length(Count)); + { Zero out the memory block to avoid problems with exceptions within the + constructor of this class. } + FillChar(aSQLDA^, XSQLDA_Length(Count), 0); + + aSQLDA^.Version := sqlda_version1; + aSQLDA^.SQLN := Count; + end + else + reAllocMem(aSQLDA,0); +end; + +procedure TIBConnection.TranslateFldType(SQLType,sqlsubtype,SQLLen, + SQLScale: integer; + out TrType: TFieldType; out TrLen: word); +begin + TrLen:= SQLLen; + if SQLScale < 0 then begin + TrLen:= -sqlscale; + if (sqlscale < -4) and (dbo_bcdtofloatif in controller.options) then begin + TrType:= ftfloat; + end + else begin + TrType:= ftBCD + end; + end + else begin + case (SQLType and not 1) of + SQL_VARYING: begin + if sqlsubtype and $ff = 1 then begin //octets + trtype:= ftvarbytes; + end + else begin + TrType:= ftString; + end; + end; + SQL_TEXT: begin + if sqlsubtype and $ff = 1 then begin //octets + trtype:= ftbytes; + end + else begin + TrType:= ftString; + end; + end; + SQL_TYPE_DATE: begin + TrType:= ftDate{Time}; + end; + SQL_TYPE_TIME: begin + TrType:= ftTime;//ftDateTime; + end; + SQL_TIMESTAMP: begin + TrType := ftDateTime; + end; + SQL_ARRAY: begin + TrType := ftArray; + end; + SQL_BLOB: begin + if sqlsubtype = isc_blob_text then begin + trtype:= ftmemo; + end + else begin + TrType:= ftBlob; + end; + end; + SQL_SHORT: begin + TrType:= ftsmallint; + end; + SQL_LONG: begin + TrType:= ftInteger; + end; + SQL_INT64: begin + TrType:= ftLargeInt; + end; + SQL_DOUBLE: begin + TrType:= ftFloat; + end; + SQL_FLOAT: begin + TrType:= ftFloat; + end + else begin + TrType := ftUnknown; + end; + end; + end; +end; + +Function TIBConnection.AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; + +var curs : TIBCursor; + +begin + curs := TIBCursor.create(aowner,self); + curs.sqlda := nil; + curs.statement := nil; + curs.FPrepared := False; + AllocSQLDA(curs.SQLDA,0); + AllocSQLDA(curs.in_SQLDA,0); + result := curs; +end; + +procedure TIBConnection.DeAllocateCursorHandle(var cursor : TSQLCursor); + +begin + if assigned(cursor) then with cursor as TIBCursor do + begin + AllocSQLDA(SQLDA,-1); + AllocSQLDA(in_SQLDA,-1); + end; + FreeAndNil(cursor); +end; + +Function TIBConnection.AllocateTransactionHandle : TSQLHandle; + +begin + result := TIBTrans.create; +end; + +procedure tibconnection.preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); + +var + dh: pointer; + tr: pointer; + x: integer; + TransLen: word; + TransType: TFieldType; + str1: string; + buf1: array[0..15] of byte; + int1: integer; + by1: byte; + +begin + with TIBcursor(cursor) do begin + ffetched:= false; + fempty:= true; + dh := GetHandle; + if isc_dsql_allocate_statement(@Status, @dh, @Statement) <> 0 then begin + CheckError('PrepareStatement', Status); + end; + tr := aTransaction.Handle; + if assigned(AParams) and (AParams.count > 0) then begin + str1:= todbstring(AParams.ParseSQL(asql,false,false,false,psInterbase, + paramBinding)); + end + else begin + str1:= todbstring(asql); + end; + if isc_dsql_prepare(@Status, @tr, @Statement, 0, @str1[1], + Dialect, nil) <> 0 then begin + isc_dsql_free_statement(@fstatus, @statement, dsql_drop); + CheckError('PrepareStatement', Status); + end; + by1:= isc_info_sql_stmt_type; + if isc_dsql_sql_info(@fstatus,@statement,sizeof(by1),@by1, + sizeof(buf1),@buf1[0]) <> 0 then begin + isc_dsql_free_statement(@fstatus, @statement, dsql_drop); + CheckError('PrepareStatement get info', Status); + end; + if buf1[0] = isc_info_sql_stmt_type then begin + int1:= isc_vax_integer(@buf1[1], 2); + fibstatementtype:= isc_vax_integer(@buf1[3],int1); + end; + FPrepared := True; + if assigned(AParams) and (AParams.count > 0) then begin + AllocSQLDA(in_SQLDA,Length(ParamBinding)); + if isc_dsql_describe_bind(@Status, @Statement, 1, in_SQLDA) <> 0 then begin + CheckError('PrepareStatement bind', Status); + end; + if in_SQLDA^.SQLD > in_SQLDA^.SQLN then begin + DatabaseError(SParameterCountIncorrect,self); + end; + setlength(paramtypes,in_SQLDA^.SQLD); + for x := 0 to in_SQLDA^.SQLD - 1 do begin + with in_SQLDA^.SQLVar[x] do begin + TranslateFldType(SQLType,sqlsubtype,SQLLen,SQLScale,TransType,TransLen); + paramtypes[x]:= transtype; + if ((SQLType and not 1) = SQL_VARYING) then begin + SQLData := AllocMem(in_SQLDA^.SQLVar[x].SQLLen+2) + end + else begin + SQLData := AllocMem(in_SQLDA^.SQLVar[x].SQLLen); + end; + sqltype:= sqltype or 1; //always use null flag + New(SQLInd); + end; + end; + end; + fexecsqlda:= nil; + if FStatementType in datareturningtypes then begin + if isc_dsql_describe(@Status, @Statement, 1, SQLDA) <> 0 then begin + CheckError('PrepareSelect', Status); + end; + if SQLDA^.SQLD > SQLDA^.SQLN then begin + AllocSQLDA(SQLDA,SQLDA^.SQLD); + if isc_dsql_describe(@Status, @Statement, 1, SQLDA) <> 0 then begin + CheckError('PrepareSelect', Status); + end; + end; + for x := 0 to SQLDA^.SQLD - 1 do with SQLDA^.SQLVar[x] do begin + if ((SQLType and not 1) = SQL_VARYING) then begin + SQLData := AllocMem(SQLDA^.SQLVar[x].SQLLen+2); + end + else begin + SQLData := AllocMem(SQLDA^.SQLVar[x].SQLLen); + end; + if (SQLType and 1) = 1 then begin //check not null constraint + New(SQLInd); + end; + end; + end; + if fibstatementtype = isc_info_sql_stmt_exec_procedure then begin + fexecsqlda:= sqlda; + end; + end; +end; + +procedure tibconnection.unpreparestatement(cursor: tsqlcursor); +begin + with tibcursor(cursor) do begin + if statement <> nil then begin + if isc_dsql_free_statement(@status, @statement, dsql_drop) <> 0 then begin + checkerror('freestatement', status); + end; + end; + statement:= nil; + fprepared:= false; + fopen:= false; + end; +end; + +procedure TIBConnection.FreeSQLDABuffer(var aSQLDA : PXSQLDA); + +var x : integer; + +begin + if assigned(aSQLDA) then + for x := 0 to aSQLDA^.SQLN - 1 do + begin + reAllocMem(aSQLDA^.SQLVar[x].SQLData,0); + if assigned(aSQLDA^.SQLVar[x].sqlind) then + begin + Dispose(aSQLDA^.SQLVar[x].sqlind); + aSQLDA^.SQLVar[x].sqlind := nil; + end + + end; +end; + +procedure TIBConnection.FreeFldBuffers(cursor : TSQLCursor); + +begin + with cursor as TIBCursor do + begin + FreeSQLDABuffer(SQLDA); + FreeSQLDABuffer(in_SQLDA); + end; +end; + +procedure TIBConnection.internalExecute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; const AParams : TmseParams; + const autf8: boolean); +var + buf1: array[0..127] of byte; + by1: byte; + int1,int2: integer; + datasize: integer; + selectcount: integer; + updatecount: integer; + deletecount: integer; + insertcount: integer; +begin + if Assigned(APArams) and (AParams.count > 0) then begin + SetParameters(cursor, AParams); + end; + with TIBCursor(cursor) do begin + ffetched:= false; + if isc_dsql_execute2(@Status,@cursor.ftrans, + @Statement,1,in_SQLDA,fexecsqlda) <> 0 then begin + CheckError('Execute', Status); + end; + fopen:= true; + fempty:= sqlda^.sqld = 0; + if not fempty and (fexecsqlda = nil) then begin + fempty:= not fetch1(tibcursor(cursor)); //needed for rowsreturned? + end; + frowsaffected:= -1; + frowsreturned:= -1; + if ibo_sqlinfo in foptions then begin + by1:= isc_info_sql_records; + if isc_dsql_sql_info(@fstatus,@statement,sizeof(by1),@by1, + sizeof(buf1),@buf1[0]) <> 0 then begin + CheckError('Execute get records info', Status); + end; + if buf1[0] = isc_info_sql_records then begin + int2:= isc_vax_integer(@buf1[1],2)+3; //record size + if int2 <= sizeof(buf1) then begin + selectcount:= -1; + updatecount:= -1; + deletecount:= -1; + insertcount:= -1; + int1:= 3; + while true do begin + by1:= buf1[int1]; + if (by1 in [isc_info_end,isc_info_truncated]) or + (int1 >= int2-1) then begin + break; + end; + datasize:= isc_vax_integer(@buf1[int1+1],2); + inc(int1,3); + if int1 + datasize > int2 then begin + break; + end; + case by1 of + isc_info_req_select_count: begin + selectcount:= isc_vax_integer(@buf1[int1],datasize); + end; + isc_info_req_update_count: begin + updatecount:= isc_vax_integer(@buf1[int1],datasize); + end; + isc_info_req_delete_count: begin + deletecount:= isc_vax_integer(@buf1[int1],datasize); + end; + isc_info_req_insert_count: begin + insertcount:= isc_vax_integer(@buf1[int1],datasize); + end; + end; + inc(int1,datasize); + end; + if selectcount >= 0 then begin + frowsreturned:= selectcount; + end; + if updatecount > 0 then begin + frowsreturned:= 0; + frowsaffected:= updatecount; + end; + if deletecount > 0 then begin + frowsreturned:= 0; + frowsaffected:= deletecount; + end; + if insertcount > 0 then begin + frowsreturned:= 0; + frowsaffected:= insertcount; + end; + end; + end; + end; + end; +end; + +function sqlvarnametostring(const avalue: pointer): string; +type + sqlnamety = packed record + length: smallint; + name: array[0..31] of char; + end; +begin + with sqlnamety(avalue^) do begin + setlength(result,length); + move(name,result[1],length); + end; +end; + +function sqlsubtypetocharlen(const subtype: smallint; const len: integer): integer; +var + int1: integer; +begin + case subtype and $ff of +// 0,1,2,10,11,12,13,14,19,21,22,39, +// 45,46,47,50,51,52,53,54,55,58: begin +// int1:= 1; + 5,6,{8,}44,56,57{,64}: begin + int1:= 2; + end; + 3: begin + int1:= 3; + end; + 4,59: begin + int1:= 4; + end; + else begin + int1:= 1; + end; + end; + result:= (len) div int1; +end; + +procedure TIBConnection.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TfieldDefs); +var + x: integer; + TransLen: word; + TransType: TFieldType; + FD: TFieldDef; + ar1: fielddefarty; + int1: integer; +begin + ar1:= getfielddefar(fielddefs); + fielddefs.clear; + with tibcursor(cursor) do begin + for x := 0 to SQLDA^.SQLD - 1 do begin + with SQLDA^.SQLVar[x] do begin + TranslateFldType(SQLType,sqlsubtype,SQLLen,SQLScale,TransType,TransLen); + case transtype of + ftstring: begin + translen:= sqlsubtypetocharlen(sqlsubtype,translen); + end; + ftbcd: begin + if translen > 4 then begin + translen:= 4; + end; + end; + ftbytes: begin + if translen = 16 then begin + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if (datatype = ftguid) and (name = aliasname) then begin + transtype:= ftguid; + end; + end; + end; + end; + end; + end; + if not(transtype in varsizefields) then begin + translen:= 0; + end; + FD:= TFieldDef.Create(nil,AliasName,TransType, + TransLen,False,(x + 1)); + if TransType = ftBCD then begin + case sqllen of + 2: fd.precision:= 4; + 4: fd.precision:= 9; + 8: fd.precision:= 18; + else begin + FD.precision:= SQLLen; + end; + end; + end; +// FD.DisplayName:= AliasName; + fd.collection:= fielddefs; + end; + end; + end; +end; + +function TIBConnection.GetHandle: pointer; +begin + Result := FSQLDatabaseHandle; +end; + +function tibconnection.fetch1(const cursor: tibcursor): boolean; +var + retcode: integer; +begin + with cursor do begin + retcode:= isc_dsql_fetch(@Status,@Statement,1,SQLDA); + if (retcode <> 0) and (retcode <> 100) and (retcode <> 335544364) then begin + //request synchronizing error, FireBird bug? + CheckError('Fetch',Status); + end; + end; + Result:= retcode = 0; +end; + +function TIBConnection.Fetch(cursor : TSQLCursor) : boolean; +begin + with TIBCursor(cursor) do begin + result:= not fempty; + if result then begin + if fibstatementtype = isc_info_sql_stmt_exec_procedure then begin + result:= not ffetched; + end + else begin + result:= not ffetched or fetch1(tibcursor(cursor)); + end; + ffetched:= true; + end; + end; +end; + +procedure TIBConnection.SetParameters(cursor: TSQLCursor; AParams: TmseParams); + //todo: remove not needed move operations +var + ParNr,SQLVarNr: integer; + s,str1: string; + i: integer; + li: LargeInt; + currbuff: pchar; + w: word; + cur1: currency; + id1: tguid; + po1: pxsqlvar; + bo1: boolean; + +begin + with tibcursor(cursor) do begin + for SQLVarNr := 0 to High(ParamBinding) do begin + ParNr:= ParamBinding[SQLVarNr]; + po1:= @in_sqlda^.SQLvar[SQLVarNr]; + with AParams[ParNr] do begin + if IsNull then begin + If Assigned(po1^.SQLInd) then begin + po1^.SQLInd^ := -1; + end; + end + else begin + if assigned(po1^.SQLInd) then begin + po1^.SQLInd^ := 0; + end; + case paramtypes[sqlvarnr] of + ftunknown: begin + //null flag only + end; + ftInteger,ftsmallint : begin + if datatype = ftboolean then begin + i:= 0; + if asboolean then begin + i:= 1; + end; + end + else begin + i:= AsInteger; + end; + Move(i, po1^.SQLData^,po1^.SQLLen); + //todo: byte order? + end; + ftbcd: begin + cur1:= ascurrency; + with po1^ do begin + cur1:= scaleexp10(cur1,-(4+sqlscale)); + move(cur1,sqldata^,po1^.sqllen); + end; + end; + ftString,ftFixedChar,ftwidestring,ftbytes,ftvarbytes: begin + if (datatype = ftguid) and (paramtypes[sqlvarnr] = ftbytes) and + (po1^.sqllen = sizeof(tguid)) then begin + with po1^ do begin + id1:= dbstringtoguid(asstring); + move(id1,sqldata^,po1^.sqllen); + end; + end + else begin + bo1:= paramtypes[sqlvarnr] in [ftbytes,ftvarbytes]; + if bo1 then begin + s:= asstring; + end + else begin + s:= aparams.AsdbString(parnr); + end; + w:= length(s); + with po1^ do begin + if ((SQLType and not 1) = SQL_VARYING) then begin + SQLLen:= w; + ReAllocMem(SQLData,SQLLen+sizeof(w)); + CurrBuff:= SQLData; + move(w,CurrBuff^,sizeof(w)); + inc(CurrBuff,sizeof(w)); + end + else begin + if w > sqllen then begin + w:= sqllen; + end; + CurrBuff:= SQLData; + if w < sqllen then begin + if bo1 then begin + fillchar((currbuff+w)^,sqllen-w,0); + end + else begin + fillchar((currbuff+w)^,sqllen-w,' '); + end; + end; + end; + end; + Move(pointer(s)^,CurrBuff^,w); + end; + end; + ftDate, ftTime, ftDateTime: begin + SetDateTime(po1^.SQLData,AsDateTime, po1^.SQLType); + end; + ftLargeInt: begin + li := AsLargeInt; + Move(li, po1^.SQLData^,po1^.SQLLen); + end; + ftblob,ftmemo: begin + if datatype in [ftblob,ftString,ftFixedChar,ftwidestring, + ftbytes,ftvarbytes] then begin + if paramtypes[sqlvarnr] = ftmemo then begin + s:= aparams.asdbstring(parnr); + end + else begin + s:= asstring; + end; + writeblobdata(cursor.ftrans,'',nil,pointer(s),length(s),nil,nil,str1); + move(str1[1],li,sizeof(li)); //blobid + end + else begin + li := AsLargeInt; + end; + Move(li, po1^.SQLData^,po1^.SQLLen); + end; + ftFloat,ftcurrency: begin + with po1^ do begin + if sqlscale < 0 then begin + {$ifdef FPC} + {$ifdef CPUARM} + int64(ar8ty(cur1)):= round(asfloat * intexp10(-SQLScale)); + {$else} + int64(ar8ty(cur1)):= round(asfloat * intexp10(-SQLScale)); + {$endif} + {$else} + int64(ar8ty(cur1)):= round(asfloat * intexp10(-SQLScale)); + {$endif} + move(cur1,sqldata^,po1^.sqllen); + end + else begin + SetFloat(po1^.SQLData,AsFloat,po1^.SQLLen); + end; + end; + end; + else begin + DatabaseErrorFmt(SUnsupportedParameter, + [Fieldtypenames[AParams[ParNr].DataType]],self); + end; + end; {case} + end; + end; + end; + end; +end; + +function tibconnection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize +var + VarcharLen: word; + CurrBuff: pchar; + po1: pxsqlvar; + + function getint64: int64; + begin + case po1^.sqllen of + 2: begin + int64(result):= psmallint(currbuff)^; //sign extend + end; + 4: begin + int64(result):= pinteger(currbuff)^; //sign extend + end; + else begin + result:= pint64(currbuff)^; + end; + end; + end; + +begin + po1:= @TIBCursor(cursor).SQLDA^.SQLVar[fieldnum]; + with TIBCursor(cursor),po1^ do begin + if assigned(SQLInd) and (SQLInd^ = -1) then begin + result:= false + end + else begin + Result := true; + if buffer = nil then begin + exit; + end; + if ((SQLType and not 1) = SQL_VARYING) then begin + Move(SQLData^,VarcharLen,2); + CurrBuff:= SQLData + 2; + end + else begin + CurrBuff:= SQLData; + VarCharLen:= SQLLen; + end; + case DataType of + ftBCD: begin + pint64(buffer)^:= scaleexp10(getint64,4+SQLScale); + end; + ftInteger,ftsmallint: begin + if datatype = ftsmallint then begin + pinteger(buffer)^:= psmallint(currbuff)^; + end + else begin + pinteger(buffer)^:= pinteger(currbuff)^; + end; + end; + ftLargeint: begin + pint64(buffer)^:= pint64(currbuff)^; + end; + ftDate,ftTime,ftDateTime: begin + GetDateTime(CurrBuff,Buffer,SQLType); + end; + ftguid: begin + pguid(buffer)^:= pguid(currbuff)^; + end; + ftString,ftBytes,ftvarbytes: begin + if datatype = ftvarbytes then begin + currbuff:= currbuff - sizeof(word); + varcharlen:= varcharlen + sizeof(word); + end; + if bufsize < varcharlen then begin + bufsize:= -varcharlen; + end + else begin + bufsize:= varcharlen; + move(currbuff^,buffer^,varcharlen); + end; + end; + ftFloat,ftcurrency: begin + if sqlscale < 0 then begin //numeric/decimal + pdouble(buffer)^:= getint64 / intexp10(-SQLScale); + end + else begin + GetFloat(CurrBuff,Buffer,sqllen); + end; + end; + ftBlob,ftmemo,ftgraphic: begin // load the BlobIb in field's buffer + pint64(buffer)^:= getint64; + if wantblobfetch then begin + addblobcache(pint64(buffer)^,getblobstring(cursor,pisc_quad(buffer)^)); + end; + end; + else begin + result := false; + end; + end; + end; + end; +end; + +procedure TIBConnection.GetDateTime(CurrBuff, Buffer : pointer; AType : integer); +var + CTime : TTm; // C struct time + STime : TSystemTime; // System time +begin + case (AType and not 1) of + SQL_TYPE_DATE : + isc_decode_sql_date(PISC_DATE(CurrBuff), @CTime); + SQL_TYPE_TIME : + isc_decode_sql_time(PISC_TIME(CurrBuff), @CTime); + SQL_TIMESTAMP : + isc_decode_timestamp(PISC_TIMESTAMP(CurrBuff), @CTime); + end; + +{$ifdef FPC} +{$warnings off} + STime.Year := CTime.tm_year + 1900; + STime.Month := CTime.tm_mon + 1; + STime.Day := CTime.tm_mday; + STime.Hour := CTime.tm_hour; + STime.Minute := CTime.tm_min; + STime.Second := CTime.tm_sec; + STime.Millisecond := 0; +{$else} + STime.wYear := CTime.tm_year + 1900; + STime.wMonth := CTime.tm_mon + 1; + STime.wDay := CTime.tm_mday; + STime.wHour := CTime.tm_hour; + STime.wMinute := CTime.tm_min; + STime.wSecond := CTime.tm_sec; + STime.wMilliseconds := 0; +{$endif} + pdatetime(buffer)^:= SystemTimeToDateTime(STime); +end; +{$warnings on} + +procedure TIBConnection.SetDateTime(CurrBuff: pointer; PTime : TDateTime; AType : integer); +var + CTime : TTm; // C struct time + STime : TSystemTime; // System time +begin + DateTimeToSystemTime(PTime,STime); + +{$ifdef FPC} + CTime.tm_year := STime.Year - 1900; + CTime.tm_mon := STime.Month -1; + CTime.tm_mday := STime.Day; + CTime.tm_hour := STime.Hour; + CTime.tm_min := STime.Minute; + CTime.tm_sec := STime.Second; +{$else} + CTime.tm_year := STime.wYear - 1900; + CTime.tm_mon := STime.wMonth -1; + CTime.tm_mday := STime.wDay; + CTime.tm_hour := STime.wHour; + CTime.tm_min := STime.wMinute; + CTime.tm_sec := STime.wSecond; +{$endif} + case (AType and not 1) of + SQL_TYPE_DATE : + isc_encode_sql_date(@CTime, PISC_DATE(CurrBuff)); + SQL_TYPE_TIME : + isc_encode_sql_time(@CTime, PISC_TIME(CurrBuff)); + SQL_TIMESTAMP : + isc_encode_timestamp(@CTime, PISC_TIMESTAMP(CurrBuff)); + end; +end; + +function TIBConnection.GetSchemaInfoSQL(SchemaType : TSchemaType; + SchemaObjectName, SchemaPattern : msestring) : msestring; + +begin + result:= fbgetschemainfosql(self,schematype,schemaobjectname,schemapattern); +end; + +procedure tibconnection.updateindexdefs(var indexdefs : tindexdefs; + const atablename : string; const acursor: tsqlcursor); +begin + fbupdateindexdefs(self,indexdefs,atablename); +end; + +procedure TIBConnection.SetFloat(CurrBuff: pointer; Dbl: Double; Size: integer); + +begin + case Size of + 4: begin + psingle(currbuff)^:= Dbl; + end; + 8: begin + pdouble(currbuff)^:= Dbl; + end; + 10: begin + pextended(currbuff)^:= Dbl; + end; + end; +end; + +procedure tibconnection.GetFloat(const CurrBuff,Buffer: pointer; + const datalength: integer); +begin + case datalength of + 4: begin + pdouble(buffer)^:= psingle(currbuff)^; + end; + 8: begin + pdouble(buffer)^:= pdouble(currbuff)^; + end; + 10: begin + pdouble(buffer)^:= pextended(currbuff)^; + end; + end; +end; + + +function TIBConnection.getMaxBlobSize(blobHandle : TIsc_Blob_Handle) : longInt; +var + iscInfoBlobMaxSegment : byte; + blobInfo : array[0..50] of byte; + +begin + result:= 0; + iscInfoBlobMaxSegment:= isc_info_blob_max_segment; + if isc_blob_info(@Fstatus, @blobHandle, sizeof(iscInfoBlobMaxSegment), + @iscInfoBlobMaxSegment, sizeof(blobInfo) - 2, @blobInfo) <> 0 then + CheckError('isc_blob_info', FStatus); + if blobInfo[0] = isc_info_blob_max_segment then + begin + result := isc_vax_integer(pchar(@blobInfo[3]), + isc_vax_integer(pchar(@blobInfo[1]), 2)); + end + else + CheckError('isc_blob_info', FStatus); +end; + +function tibconnection.getblobstream(const acursor: tsqlcursor; + const blobid: isc_quad; const forstring: boolean = false): tmemorystream; +const + isc_segstr_eof = 335544367; +var + blobHandle : Isc_blob_Handle; + blobSegment : pointer; + blobSegLen : word; + maxBlobSize : longInt; +begin + blobseglen:= 0; + blobHandle:= FB_API_NULLHANDLE; + if isc_open_blob(@FStatus, @FSQLDatabaseHandle, @acursor.ftrans, + @blobHandle, @blobId) <> 0 then begin + CheckError('TIBConnection.CreateBlobStream', FStatus); + end; + maxBlobSize:= getMaxBlobSize(blobHandle); + blobSegment:= AllocMem(maxBlobSize); + if forstring then begin + result:= tmemorystringstream.create; + end + else begin + result:= tmemorystream.create; + end; + while isc_get_segment(@FStatus,@blobHandle,@blobSegLen,maxBlobSize, + blobSegment) = 0 do begin + result.writeBuffer(blobSegment^,blobSegLen); + end; + freemem(blobSegment); + result.seek(0,soFromBeginning); + if FStatus[1] = isc_segstr_eof then begin + if isc_close_blob(@FStatus, @blobHandle) <> 0 then begin + CheckError('TIBConnection.CreateBlobStream isc_close_blob', FStatus); + end; + end + else begin + CheckError('TIBConnection.CreateBlobStream isc_get_segment', FStatus); + end; +end; + +function tibconnection.getblobstring(const acursor: tsqlcursor; + const blobid: isc_quad): string; +begin + tmemorystringstream(getblobstream(acursor,blobid,true)).destroyasstring(result); +end; + +function TIBConnection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +var + blobId : ISC_QUAD; + int1: integer; +begin + int1:= sizeof(blobid); + if not loadfield(cursor,ftblob,fieldnum,@blobid,int1,false) then begin + result:= ''; + end + else begin + result:= getblobstring(cursor,blobid); + end; +end; + +function TIBConnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +var + blobId : ISC_QUAD; +begin + result := nil; + if mode = bmRead then begin + if not field.getData(@blobId) then begin + exit; + end; + result:= getblobstream(acursor,blobid); + end; +end; + + +procedure TIBConnection.writeblobdata(const atransactionhandle: pointer; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); + + procedure check(const ares: isc_status); + begin + if ares <> 0 then begin + CheckError('TIBConnection.writeblob', FStatus); + end; + end; +const + defsegsize = $ffff; +var +// transactionhandle: pointer; + blobhandle: isc_blob_handle; + blobid: isc_quad; + step: word; + po1: pointer; + int1: integer; +begin +// transactionhandle:= atransaction.handle; + blobhandle:= FB_API_NULLHANDLE; + fillchar(blobid,sizeof(blobid),0); + check(isc_create_blob2(@fstatus,@fsqldatabasehandle,@atransactionhandle, + @blobhandle,@blobid,0,nil)); + try + int1:= getmaxblobsize(blobhandle); + if (int1 <= 0) or (int1 > defsegsize) then begin + step:= defsegsize; + end + else begin + step:= int1; + end; + po1:= adata; + int1:= alength; + while int1 > 0 do begin + if int1 < step then begin + step:= int1; + end; + check(isc_put_segment(@fstatus,@blobhandle,step,po1)); + dec(int1,step); + inc(pchar(po1),step); + end; + if aparam = nil then begin + setlength(newid,sizeof(blobid)); + move(blobid,newid[1],sizeof(blobid)); + end + else begin + aparam.aslargeint:= int64(blobid); + newid:= ''; //id no more usable + end; + finally + isc_close_blob(@fstatus,@blobhandle); + end; +end; + +procedure TIBConnection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); +begin + writeblobdata(atransaction.handle,tablename,acursor,adata,alength, + afield,aparam,newid); +end; + +procedure tibconnection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +var + blobid: isc_quad; +begin +{ + if afield.isnull then begin + aparam.clear; + end + else begin + } + afield.getdata(@blobid); + aparam.aslargeint:= int64(blobid); +// end; +end; + +function TIBConnection.getblobdatasize: integer; +begin + result:= sizeof(isc_quad); +end; + +procedure TIBConnection.createdatabase(const asql: ansistring); +var + dbha: isc_db_handle; + trha: isc_tr_handle; + bo1: boolean; +begin + dbha:= FB_API_NULLHANDLE; + trha:= FB_API_NULLHANDLE; +{$ifdef linkdynamically} + useembeddedfirebird:= ibo_embedded in foptions; + initializeibase60([]); + try +{$endif} + bo1:= isc_dsql_execute_immediate(@fstatus,@dbha,@trha,length(asql), + pchar(asql),fdialect,nil) <> 0; + if bo1 then begin + checkerror('createdatabase',fstatus); + end + else begin + if dbha <> FB_API_NULLHANDLE then begin + isc_detach_database(@FStatus,@dbha); + end; + end; +{$ifdef linkdynamically} + finally + releaseibase60; + end; +{$endif} +end; +{ +function TIBConnection.blobscached: boolean; +begin + result:= false; +end; +} +procedure TIBConnection.listen(const sender: tdbevent); +begin + feventcontroller.register(sender); + if connected then begin + dolisten(sender); + end; +end; + +procedure TIBConnection.unlisten(const sender: tdbevent); +begin + if connected then begin + dounlisten(sender); + end; + feventcontroller.unregister(sender); +end; + +procedure TIBConnection.fire(const sender: tdbevent); +begin + databaseerror('Event fire not implemented.',self); +end; + +procedure eventcallback(adata: pointer; alength: smallint; aupdated: pchar); + cdecl; +//var +// status: statusvectorty; +begin + with pfbeventbufferty(adata)^,tibconnection(event.database) do begin + sys_mutexlock(fmutex); + inc(count); + inc(feventcount); + move(aupdated^,resultbuffer^,alength); + feventcontroller.eventinterval:= -1; //restart timer + sys_mutexunlock(fmutex); + end; +end; + +function TIBConnection.getdbevent(var aname: string; var aid: int64): boolean; +var + int1: integer; + status: statusvectorty; +begin + result:= false; + if feventcount > 0 then begin + sys_mutexlock(fmutex); + dec(feventcount); + for int1:= 0 to high(feventbuffers) do begin + if feventbuffers[int1] <> nil then begin + with feventbuffers[int1]^ do begin + if count <> 0 then begin + isc_event_counts(@status,length,eventbuffer,resultbuffer); + isc_que_events(@status,@fsqldatabasehandle,@id,length, + eventbuffer,isc_callback(@eventcallback),feventbuffers[int1]); + if count < 0 then begin //first dummy + count:= 0; + end + else begin + dec(count); + aname:= event.eventname; + aid:= id; + result:= true; + end; + break; + end; + end; + end; + end; + sys_mutexunlock(fmutex); + end; +end; + +procedure TIBConnection.dolisten(const sender: tdbevent); +var + int1,int2: integer; +begin + int2:= -1; + for int1:= 0 to high(feventbuffers) do begin + if feventbuffers[int1] = nil then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + int2:= length(feventbuffers); + setlength(feventbuffers,high(feventbuffers)+17); + end; + getmem(feventbuffers[int2],sizeof(fbeventbufferty)); + fillchar(feventbuffers[int2]^,sizeof(fbeventbufferty),0); + with feventbuffers[int2]^ do begin + count:= -2; //remove dummy call + event:= sender; + name:= sender.eventname; + length:= isc_event_block(@eventbuffer,@resultbuffer,1,[pchar(name)]); + checkerror('dolisten',isc_que_events(@fstatus,@fsqldatabasehandle,@id,length, + eventbuffer,isc_callback(@eventcallback),feventbuffers[int2])); + end; +end; + +procedure TIBConnection.dounlisten(const sender: tdbevent); +var + int1: integer; +begin + for int1:= 0 to high(feventbuffers) do begin + if (feventbuffers[int1] <> nil) and + (feventbuffers[int1]^.event = sender) then begin + sys_mutexlock(fmutex); //not save! there can be an event in queue + isc_cancel_events(@fstatus,@fsqldatabasehandle,@feventbuffers[int1]^.id); + freeeventbuffer(feventbuffers[int1]); + sys_mutexunlock(fmutex); + break; + end; + end; +end; + +procedure TIBConnection.freeeventbuffer(var abuffer: pfbeventbufferty); +begin + with abuffer^ do begin + isc_free(eventbuffer); + isc_free(resultbuffer); + end; + finalize(abuffer^); + freemem(abuffer); + abuffer:= nil; +end; + +procedure versioncallback(user_arg: pointer; atext: pchar); +// {$ifdef mswindows}stdcall{$else}cdecl{$endif}; + {$ifdef mswindows}cdecl{$else}cdecl{$endif}; +begin + setlength(stringarty(user_arg^),high(stringarty(user_arg^))+2); + stringarty(user_arg^)[high(stringarty(user_arg^))]:= atext; +end; + +function TIBConnection.version: fbversionty; +var + ar1: stringarty; + int1: integer; +begin + checkconnected; + ar1:= nil; + if isc_version(@fsqldatabasehandle,@versioncallback, + @ar1) <> 0 then begin + raise edatabaseerror(name+': Can not get version info.'); + end; + with result do begin + imp:= nil; + ods:= ''; + if high(ar1) > 0 then begin + setlength(imp,high(ar1)); + for int1:= 0 to high(imp) do begin + imp[int1]:= ar1[int1]; + end; + ods:= ar1[high(ar1)]; + end; + end; +end; + +{ eiberror } + +constructor eiberror.create(const asender: tibconnection; + const amessage: msestring; + const aerror: statusvectorty; const asqlcode: integer); +begin + fstatus:= aerror; + fsqlcode:= asqlcode; + inherited create(asender,ansistring(amessage),amessage,aerror[1]); +end; + +end. \ No newline at end of file diff --git a/mseide-msegui/lib/common/db/mmysql40conn.pas b/mseide-msegui/lib/common/db/mmysql40conn.pas new file mode 100644 index 0000000..307087d --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysql40conn.pas @@ -0,0 +1,26 @@ +{ + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{ + Contains the TMysqlConnection for MySQL 4.0 +} + +unit mmysql40conn; + +{$UNDEF MYSQL41} + +{$i mmysqlconn.inc} + +end. diff --git a/mseide-msegui/lib/common/db/mmysql41conn.pas b/mseide-msegui/lib/common/db/mmysql41conn.pas new file mode 100644 index 0000000..3ab3b09 --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysql41conn.pas @@ -0,0 +1,26 @@ +{ + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{ + Contains the TMysqlConnection for MySQL 4.1 +} + +unit mmysql41conn; + +{$DEFINE MYSQL41} + +{$i mmysqlconn.inc} + +end. diff --git a/mseide-msegui/lib/common/db/mmysql4conn.pas b/mseide-msegui/lib/common/db/mmysql4conn.pas new file mode 100644 index 0000000..1d610b7 --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysql4conn.pas @@ -0,0 +1,28 @@ +{ + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{ + Contains the TMysqlConnection for MySQL 4.0 + + temporary backwards compatibility for Lazarus +} + +unit mmysql4conn; + +{$DEFINE MYSQL4} + +{$i mmysqlconn.inc} + +end. diff --git a/mseide-msegui/lib/common/db/mmysql50conn.pas b/mseide-msegui/lib/common/db/mmysql50conn.pas new file mode 100644 index 0000000..b6d2a00 --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysql50conn.pas @@ -0,0 +1,27 @@ +{ + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{ + Contains the TMysqlConnection for MySQL 5.0 +} + +unit mmysql50conn; + +{$DEFINE MYSQL50} +{$DEFINE MYSQL41} + +{$i mmysqlconn.inc} + +end. diff --git a/mseide-msegui/lib/common/db/mmysqlconn.inc b/mseide-msegui/lib/common/db/mmysqlconn.inc new file mode 100644 index 0000000..5a8fd86 --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysqlconn.inc @@ -0,0 +1,1136 @@ +{ + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{Modified 2006-2010 by Martin Schreiber} + +{$ifdef VER2_1_5} {$define mse_FPC_2_2} {$endif} +{$ifdef VER2_2} {$define mse_FPC_2_2} {$endif} +{$ifdef VER2_3} {$define mse_FPC_2_2} {$endif} +{$ifdef VER2_4} {$define mse_FPC_2_2} {$endif} +{$ifdef VER2_5} {$define mse_FPC_2_2} {$endif} +{$if FPC_FULLVERSION >= 20300} {$define mse_FPC_2_2} {$endif} + +{$mode objfpc}{$H+} +{$MACRO on} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,SysUtils,msqldb,mdb,dynlibs,msetypes{msestrings},msedb, +{$IfDef mysql50} + mysql50dyn; + {$DEFINE TConnectionName:=TMySQL50Connection} + {$DEFINE TTransactionName:=TMySQL50Transaction} + {$DEFINE TCursorName:=TMySQL50Cursor} + {$define eerrorname:= emysql50error} +{$ELSE} + {$IfDef mysql41} + mysql41dyn; + {$DEFINE TConnectionName:=TMySQL41Connection} + {$DEFINE TTransactionName:=TMySQL41Transaction} + {$DEFINE TCursorName:=TMySQL41Cursor} + {$define eerrorname:= emysql41error} + {$ELSE} + {$IFDEF mysql4} // temporary backwards compatibility for Lazarus + mysql40dyn; + {$DEFINE TConnectionName:=TMySQLConnection} + {$DEFINE TTransactionName:=TMySQLTransaction} + {$DEFINE TCursorName:=TMySQLCursor} + {$define eerrorname:= emysqlerror} + {$ELSE} + mysql40dyn; + {$DEFINE TConnectionName:=TMySQL40Connection} + {$DEFINE TTransactionName:=TMySQL40Transaction} + {$DEFINE TCursorName:=TMySQL40Cursor} + {$define eerrorname:= emysql40error} + {$EndIf} + {$EndIf} +{$EndIf} + +Type + + tcursorname = class; + + eerrorname = class(econnectionerror) + private + fsqlcode: string; + public + constructor create(const asender: tcustomsqlconnection; const amessage: ansistring; + const aerrormessage: msestring; const aerror: integer; const asqlcode: string); + property sqlcode: string read fsqlcode; + end; + + TTransactionName = Class(TSQLHandle) + protected + end; + + TCursorName = Class(TSQLCursor) + protected +// FQMySQL : PMySQL; + FRes: PMYSQL_RES; { Record pointer } + FNeedData : Boolean; + fstatementm: msestring; + Row : MYSQL_ROW; +// RowsAffected : QWord; + LastInsertID : QWord; + ParamBinding : TParamBinding; + ParamReplaceString : mseString; + MapDSRowToMSQLRow : array of integer; + fprimarykeyfieldname: string; + end; + + TConnectionName = class (TSQLConnection,iblobconnection) + private + FDialect: integer; + FHostInfo: String; + FServerInfo: String; + FMySQL : PMySQL; +{$if fpc_fullversion >= 20401} +{$else} + FDidConnect : Boolean; +{$endif} + fport: longword; + flasterror: integer; + flasterrormessage: msestring; + flastsqlcode: string; + function GetClientInfo: string; + function GetServerStatus: String; + procedure ConnectMySQL(var HMySQL : PMySQL;H,U,P : pchar); + procedure freeresultbuffer(const cursor: tcursorname); + protected + Procedure checkerror(const Msg: String); + +// function stringtosqltext(const afeildtype: tfieldtype; const avalue: string): string; + function StrToStatementType(s : msestring) : TStatementType; override; + Procedure ConnectToServer; virtual; + Procedure SelectDatabase; virtual; +// function MySQLDataType(AType: enum_field_types; ASize, ADecimals: Integer; var NewType: TFieldType; var NewSize: Integer): Boolean; + function MySQLDataType(const afield: mysql_field; var NewType: TFieldType; var NewSize: Integer): Boolean; + function MySQLWriteData(const acursor: tsqlcursor; AType: enum_field_types; + ASize: Integer; + AFieldType: TFieldType;Source, Dest: PChar): Boolean; + // SQLConnection methods + procedure DoInternalConnect; override; + procedure DoInternalDisconnect; override; + function GetHandle : pointer; override; + +// function GetAsSQLText(Field : TField) : string; overload; override; +// function GetAsSQLText(Param : TParam) : string; overload; override; + + + procedure internalExecute(const cursor: TSQLCursor; + const atransaction:tSQLtransaction; const AParams : TmseParams; + const autf8: boolean); override; + function GetTransactionHandle(trans : TSQLHandle): pointer; override; + function Commit(trans : TSQLHandle) : boolean; override; + function RollBack(trans : TSQLHandle) : boolean; override; + function StartdbTransaction(const trans : TSQLHandle; + const AParams: tstringlist) : boolean; override; + procedure internalCommitRetaining(trans : TSQLHandle); override; + procedure internalRollBackRetaining(trans : TSQLHandle); override; + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); override; + + function getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; override; + procedure updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + function getblobdatasize: integer; override; +// function getfeatures(): databasefeaturesty override; + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); +// function blobscached: boolean; + function identquotechar: msestring; override; + + Public + constructor create(aowner: tcomponent); override; + Function AllocateTransactionHandle : TSQLHandle; override; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; override; + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + procedure UnPrepareStatement(cursor:TSQLCursor); override; + procedure FreeFldBuffers(cursor : TSQLCursor); override; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); override; + function Fetch(cursor : TSQLCursor) : boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //null based + function getinsertid(const atransaction: tsqltransaction): int64; override; + Property ServerInfo : String Read FServerInfo; + Property HostInfo : String Read FHostInfo; + property ClientInfo: string read GetClientInfo; + property ServerStatus : String read GetServerStatus; + property lasterror: integer read flasterror; + property lasterrormessage: msestring read flasterrormessage; + property lastsqlcode: string read flastsqlcode; + published + property Dialect : integer read FDialect write FDialect default 0; + property port: longword read fport write fport default 0; + property DatabaseName; + property HostName; + property KeepConnection; +// property LoginPrompt; + property Params; +// property OnLogin; + end; + +// EMySQLError = Class(Exception); + +implementation +uses + msestrings,dbconst,msebufdataset,msesqlresult; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tmsebufdataset1 = class(tmsebufdataset); + +{ TConnectionName } + +Resourcestring + SErrServerConnectFailed = 'Server connect failed.'; + SErrDatabaseSelectFailed = 'failed to select database: %s'; + SErrDatabaseCreate = 'Failed to create database: %s'; + SErrDatabaseDrop = 'Failed to drop database: %s'; + SErrNoData = 'No data for record'; + SErrExecuting = 'Error executing query: %s'; + SErrFetchingdata = 'Error fetching row data: %s'; + SErrGettingResult = 'Error getting result set: %s'; + SErrNoQueryResult = 'No result from query.'; + SErrNotversion50 = 'TMySQL50Connection can not work with the installed MySQL client version (%s).'; + SErrNotversion41 = 'TMySQL41Connection can not work with the installed MySQL client version (%s).'; + SErrNotversion40 = 'TMySQL40Connection can not work with the installed MySQL client version (%s).'; + +constructor TConnectionName.create(aowner: tcomponent); +begin + inherited; + fconnoptions:= fconnoptions + [sco_supportparams,sco_emulateretaining, + sco_blobscached]; +end; + +Procedure tconnectionname.checkerror(const Msg: String); +var + str1: msestring; +begin + str1:= connectionmessage(mysql_error(fmysql)); + flasterrormessage:= str1; + flasterror:= mysql_errno(fmysql); + flastsqlcode:= strpas(mysql_sqlstate(fmysql)); + raise eerrorname.create(self,format(msg,[str1]),flasterrormessage, + flasterror,flastsqlcode); +end; + +function TConnectionName.StrToStatementType(s : msestring) : TStatementType; + +begin + S:=Lowercase(s); + if s = 'show' then exit(stSelect); + result := inherited StrToStatementType(s); +end; + + +function TConnectionName.GetClientInfo: string; + +{$if fpc_fullversion < 20401} +Var + B : Boolean; +{$endif} + +begin +{$if fpc_fullversion >= 20401} + // To make it possible to call this if there's no connection yet + InitialiseMysql; + Try + Result:=strpas(mysql_get_client_info()); + Finally + ReleaseMysql; + end; +{$else} + // To make it possible to call this if there's no connection yet + B:=(MysqlLibraryHandle=Nilhandle); + If B then + InitialiseMysql; + Try + Result:=strpas(mysql_get_client_info()); + Finally + if B then + ReleaseMysql; + end; +{$endif} +end; + +function TConnectionName.GetServerStatus: String; +begin + CheckConnected; + Result := mysql_stat(FMYSQL); +end; + +procedure TConnectionName.ConnectMySQL(var HMySQL : PMySQL;H,U,P : pchar); + +begin + HMySQL := mysql_init(HMySQL); + HMySQL:=mysql_real_connect(HMySQL,PChar(H),PChar(U),Pchar(P),Nil,fport,Nil,0); + If (HMySQL=Nil) then + databaseerror(SErrServerConnectFailed,Self); +end; +{ +function tconnectionname.stringtosqltext(const afieldtype: tfieldtype; + const avalue: string): string; +var + esc_str : pchar; +begin + Getmem(esc_str,length(avalue)*2+1); + mysql_real_escape_string(FMySQL,esc_str,pchar(str1),length(str1)); + Result := '''' + esc_str + ''''; + Freemem(esc_str); +end; + +function TConnectionName.GetAsSQLText(Field : TField) : string; +var + esc_str : pchar; + str1: string; +begin + if (not assigned(field)) or field.IsNull then begin + Result := 'Null' + end + else begin + if field.DataType in [ftString,ftmemo,ftblob,ftgraphic] then begin + result:= stringtosqltext(field.datatype,field.asstring); + end + else begin + Result := inherited GetAsSqlText(field); + end; + end; +end; + +function TConnectionName.GetAsSQLText(Param: TParam) : string; +var + esc_str : pchar; + str1: string; +begin + if (not assigned(param)) or param.IsNull then begin + Result:= 'Null' + end + else begin + if param.DataType in [ftString,ftmemo,ftblob,ftgraphic] then begin + str1:= param.asstring; + Getmem(esc_str,length(str1)*4+1); + mysql_real_escape_string(FMySQL,esc_str,pchar(str1),length(str1)); + Result:= '''' + esc_str + ''''; + Freemem(esc_str); + end + else begin + Result:= inherited GetAsSqlText(Param); + end; + end; +end; +} + +procedure TConnectionName.ConnectToServer; + +Var + H,U,P : String; + +begin + H:= ansistring(HostName); + U:= ansistring(UserName); + P:= ansistring(Password); + ConnectMySQL(FMySQL,pchar(H),pchar(U),pchar(P)); + FServerInfo := strpas(mysql_get_server_info(FMYSQL)); + FHostInfo := strpas(mysql_get_host_info(FMYSQL)); +end; + +procedure TConnectionName.SelectDatabase; +begin + if mysql_select_db(FMySQL,pchar(ansistring(DatabaseName)))<>0 then + checkerror(SErrDatabaseSelectFailed); +end; + +procedure TConnectionName.DoInternalConnect; +begin +{$if fpc_fullversion >= 20401} +{$else} + FDidConnect:=(MySQLLibraryHandle=NilHandle); + if FDidConnect then +{$endif} + InitialiseMysql; +{$IFDEF mysql50} + if copy(strpas(mysql_get_client_info()),1,3)<>'5.0' then + Raise EInOutError.CreateFmt(SErrNotversion50,[strpas(mysql_get_client_info())]); +{$ELSE} + {$IFDEF mysql41} + if copy(strpas(mysql_get_client_info()),1,3)<>'4.1' then + Raise EInOutError.CreateFmt(SErrNotversion41,[strpas(mysql_get_client_info())]); + {$ELSE} + if copy(strpas(mysql_get_client_info()),1,3)<>'4.0' then + Raise EInOutError.CreateFmt(SErrNotversion40,[strpas(mysql_get_client_info())]); + {$ENDIF} +{$ENDIF} + inherited DoInternalConnect; + ConnectToServer; + SelectDatabase; +end; + +procedure TConnectionName.DoInternalDisconnect; +begin + inherited DoInternalDisconnect; + mysql_close(FMySQL); + FMySQL:=Nil; +{$if fpc_fullversion >= 20401} +{$else} + if FDidConnect then +{$endif} + ReleaseMysql; +end; + +function TConnectionName.GetHandle: pointer; +begin + Result:=FMySQL; +end; + +function TConnectionName.AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; +begin + Result:=TCursorName.Create(aowner,aname); +end; + +Procedure TConnectionName.DeAllocateCursorHandle(var cursor : TSQLCursor); + +begin + FreeAndNil(cursor); +end; + +function TConnectionName.AllocateTransactionHandle: TSQLHandle; +begin +// Result:=TTransactionName.Create; + Result := nil; +end; + +procedure tconnectionname.preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); +begin + With TCursorName(cursor) do begin + FStatementm:= asql; + if assigned(AParams) and (AParams.count > 0) then begin + FStatementm:= AParams.ParseSQL(FStatementm,false,false,false,psSimulated, + paramBinding,ParamReplaceString); + end; + if FStatementType in datareturningtypes then begin + FNeedData:=True; + end; + fprepared:= true; + end; +end; + +procedure TConnectionName.UnPrepareStatement(cursor: TSQLCursor); +begin + with tcursorname(cursor) do begin + fstatementm:= ''; + fprepared:= false; + end; +end; + +procedure tconnectionname.freeresultbuffer(const cursor: tcursorname); +begin + If (Cursor.FRes<>Nil) then begin + Mysql_free_result(Cursor.FRes); + Cursor.FRes:=Nil; + end; +end; + +procedure TConnectionName.FreeFldBuffers(cursor: TSQLCursor); + +Var + C : TCursorName; + +begin + C:= TCursorName(cursor); + if c.FStatementType in datareturningtypes then + c.FNeedData:=False; + freeresultbuffer(c); + SetLength(c.MapDSRowToMSQLRow,0); +end; + +procedure TConnectionName.internalExecute(const cursor: TSQLCursor; + const atransaction: tSQLtransaction; const AParams : TmseParams; + const autf8: boolean); + +var + C: TCursorName; +// i: integer; + str1: ansistring; +// par1: tparam; + mstr1: msestring; +begin + C:= TCursorName(cursor); + c.frowsaffected:= -1; + c.frowsreturned:= -1; + freeresultbuffer(c); + if Assigned(AParams) and (aparams.count > 0) then begin + mstr1:= aparams.expandvalues(c.fstatementm, + c.parambinding,c.paramreplacestring); + end + else begin + mstr1:= c.fstatementm; + end; + if autf8 then begin + str1:= stringtoutf8ansi(mstr1); + end + else begin + str1:= ansistring(mstr1); + end; + + if mysql_query(FMySQL,Pchar(str1))<>0 then begin + checkerror(Format(SErrExecuting,[ + ansistring(connectionmessage(mysql_error(FMySQL)))])) + end + else begin + C.fRowsAffected := mysql_affected_rows(FMYSQL); + C.LastInsertID := mysql_insert_id(FMYSQL); + if C.FNeedData then begin + C.FRes:= mysql_store_result(FMySQL); + c.frowsreturned:= mysql_num_rows(c.fres); + end + else begin + c.frowsreturned:= 0; + end; + end; +end; + +//function TConnectionName.MySQLDataType(AType: enum_field_types; ASize, ADecimals: Integer; +// var NewType: TFieldType; var NewSize: Integer): Boolean; +function TConnectionName.MySQLDataType(const afield: mysql_field; var NewType: TFieldType; + var NewSize: Integer): Boolean; +begin + Result := True; + NewSize:= 0; + with afield do begin + case ftype of + FIELD_TYPE_TINY,FIELD_TYPE_SHORT,FIELD_TYPE_LONG: begin + NewType:= ftInteger; + end; + FIELD_TYPE_LONGLONG,FIELD_TYPE_INT24: begin + newtype:= ftlargeint; + end; + {$ifdef mysql50} + FIELD_TYPE_NEWDECIMAL, + {$endif} + FIELD_TYPE_DECIMAL: begin + if Decimals < 5 then begin + NewType:= ftBCD; + end + else begin + NewType:= ftFloat; + end; + end; + FIELD_TYPE_FLOAT,FIELD_TYPE_DOUBLE: begin + NewType:= ftFloat; + end; + FIELD_TYPE_TIMESTAMP,FIELD_TYPE_DATETIME: begin + NewType:= ftDateTime; + end; + FIELD_TYPE_DATE: begin + NewType:= ftDate; + end; + FIELD_TYPE_TIME: begin + NewType:= ftTime; + end; + FIELD_TYPE_VAR_STRING,FIELD_TYPE_STRING,FIELD_TYPE_ENUM, + FIELD_TYPE_SET: begin + NewType:= ftString; + NewSize:= length; + end; + {$ifdef mysql41} + field_type_blob: begin + newsize:= sizeof(integer); + if charsetnr = 63 then begin //binary + newtype:= ftblob; + end + else begin + newtype:= ftmemo; + end; + end; + {$endif} + else begin + Result:= False; + end; + end; + end; +end; + +procedure TConnectionName.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TfieldDefs); +var + C: TCursorName; + I,TF,FC: Integer; + field: PMYSQL_FIELD; + DFT: TFieldType; + DFS: Integer; + fd: tfielddef; + str1: ansistring; + +begin + fielddefs.clear; + C:=(Cursor as TCursorName); + If (C.FRes=Nil) then begin + checkerror(SErrNoQueryResult); + end; + FC:=mysql_num_fields(C.FRes); + SetLength(c.MapDSRowToMSQLRow,FC); + + TF := 1; + For I:= 0 to FC-1 do begin + field := mysql_fetch_field_direct(C.FRES, I); + with field^ do begin + if (flags and (pri_key_flag or auto_increment_flag) = + (pri_key_flag or auto_increment_flag)) then begin + c.fprimarykeyfieldname:= name; + end; + end; + if MySQLDataType(field^,DFT,DFS) then begin + if (dft = ftmemo) and (cursor.stringmemo) then begin + dft:= ftstring; + dfs:= 0; + end; + str1:= field^.name; + if not(dft in varsizefields) then begin + dfs:= 0; + end; + fd:= TFieldDef.Create(nil,str1,DFT,DFS,False,TF); + fd.collection:= fielddefs; + + c.MapDSRowToMSQLRow[TF-1] := I; + inc(TF); + end + end; +end; + +function TConnectionName.Fetch(cursor: TSQLCursor): boolean; + +Var + C : TCursorName; + +begin + C:=Cursor as TCursorName; + C.Row:=MySQL_Fetch_row(C.FRes); + Result:=(C.Row<>Nil); +end; + +function tconnectionname.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize + +var + field: PMYSQL_FIELD; + row : MYSQL_ROW; + C : TCursorName; + fno: integer; + alen: integer; +begin +// Writeln('LoadFieldsFromBuffer'); + result:= false; + C:= tcursorname(Cursor); + fno:= fieldnum; + if C.Row=nil then + begin + // Writeln('LoadFieldsFromBuffer: row=nil'); + checkerror(SErrFetchingData); + end; + Row:=C.Row; + + inc(Row,c.MapDSRowToMSQLRow[fno]); + if row^ <> nil then begin + if buffer = nil then begin + exit; + end; + field:= mysql_fetch_field_direct(C.FRES,c.MapDSRowToMSQLRow[fno]); + if datatype = ftstring then begin +// alen:= strlen(row^); + alen:= mysql_fetch_lengths(c.fres)[c.MapDSRowToMSQLRow[fno]]; + if bufsize < alen then begin + bufsize:= -alen; + result:= true; + exit; + end + else begin + bufsize:= alen; + end; + end + else begin + if datatype in [ftmemo,ftgraphic,ftblob] then begin + alen:= mysql_fetch_lengths(c.fres)[c.MapDSRowToMSQLRow[fno]]; + end + else begin + alen:= field^.length; + end; + end; + Result:= MySQLWriteData(cursor, field^.ftype,alen, + DataType,Row^,Buffer); + end; +end; + +function TConnectionName.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +var + int1: integer; + row1: MYSQL_ROW; +begin + result:= ''; + with tcursorname(cursor) do begin + if row <> nil then begin + int1:= MapDSRowToMSQLRow[fieldnum]; + row1:= row; + inc(row1,int1); + setlength(result,mysql_fetch_lengths(fres)[int1]); + if result <> '' then begin + move(row1^^,result[1],length(result)); + end; + end; + end; +end; + +function InternalStrToFloat(S: string): Extended; + +var + I: Integer; + Tmp: string; + +begin + Tmp := ''; + for I := 1 to Length(S) do + begin + if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then + Tmp := Tmp + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator + else + Tmp := Tmp + S[I]; + end; + Result := StrToFloat(Tmp); +end; + +function InternalStrToCurrency(S: string): Extended; + +var + I: Integer; + Tmp: string; + +begin + Tmp := ''; + for I := 1 to Length(S) do + begin + if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then + Tmp := Tmp + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator + else + Tmp := Tmp + S[I]; + end; + Result := StrToCurr(Tmp); +end; + +function InternalStrToDate(S: string): TDateTime; + +var + EY, EM, ED: Word; + +begin + EY := StrToInt(Copy(S,1,4)); + EM := StrToInt(Copy(S,6,2)); + ED := StrToInt(Copy(S,9,2)); + if (EY = 0) or (EM = 0) or (ED = 0) then + Result:=0 + else + Result:=EncodeDate(EY, EM, ED); +end; + +function InternalStrToDateTime(S: string): TDateTime; + +var + EY, EM, ED: Word; + EH, EN, ES: Word; + +begin + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 6, 2)); + ED := StrToInt(Copy(S, 9, 2)); + EH := StrToInt(Copy(S, 12, 2)); + EN := StrToInt(Copy(S, 15, 2)); + ES := StrToInt(Copy(S, 18, 2)); + if (EY = 0) or (EM = 0) or (ED = 0) then + Result := 0 + else + Result := EncodeDate(EY, EM, ED); + Result := Result + EncodeTime(EH, EN, ES, 0); +end; + +function InternalStrToTime(S: string): TDateTime; + +var + EH, EM, ES: Word; + +begin + EH := StrToInt(Copy(S, 1, 2)); + EM := StrToInt(Copy(S, 4, 2)); + ES := StrToInt(Copy(S, 7, 2)); + Result := EncodeTime(EH, EM, ES, 0); +end; + +function InternalStrToTimeStamp(S: string): TDateTime; + +var + EY, EM, ED: Word; + EH, EN, ES: Word; + +begin +{$IFNDEF mysql40} + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 6, 2)); + ED := StrToInt(Copy(S, 9, 2)); + EH := StrToInt(Copy(S, 12, 2)); + EN := StrToInt(Copy(S, 15, 2)); + ES := StrToInt(Copy(S, 18, 2)); +{$ELSE} + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 5, 2)); + ED := StrToInt(Copy(S, 7, 2)); + EH := StrToInt(Copy(S, 9, 2)); + EN := StrToInt(Copy(S, 11, 2)); + ES := StrToInt(Copy(S, 13, 2)); +{$ENDIF} + if (EY = 0) or (EM = 0) or (ED = 0) then + Result := 0 + else + Result := EncodeDate(EY, EM, ED); + Result := Result + EncodeTime(EH, EN, ES, 0);; +end; + +function TConnectionName.MySQLWriteData(const acursor: tsqlcursor; + AType: enum_field_types;ASize: Integer; + AFieldType: TFieldType;Source, Dest: PChar): Boolean; + +var + VI: Integer; + VL: largeint; + VF: Double; + VC: Currency; + VD: TDateTime; + Src : String; + int1: integer; +begin + Result:= False; + if Source = Nil then begin + exit; + end; + Result:= True; + case afieldtype of + ftstring: begin + Move(Source^, Dest^, ASize) + end; + ftblob,ftmemo: begin + int1:= acursor.addblobdata(source,asize); + move(int1,dest^,sizeof(int1)); + //save id + end; + else begin + Src:=StrPas(Source); + case AType of + FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_LONG, + FIELD_TYPE_INT24: + begin + if (Src<>'') then + VI := StrToInt(Src) + else + VI := 0; + Move(VI, Dest^, SizeOf(Integer)); + end; + FIELD_TYPE_LONGLONG: + begin + if (Src<>'') then + VL := StrToInt64(Src) + else + VL := 0; + Move(VL, Dest^, SizeOf(LargeInt)); + end; +{$ifdef mysql50} + FIELD_TYPE_NEWDECIMAL, +{$endif} + FIELD_TYPE_DECIMAL, FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE: + if AFieldType = ftBCD then + begin + VC := InternalStrToCurrency(Src); + Move(VC, Dest^, SizeOf(Currency)); + end + else + begin + if Src <> '' then + VF := InternalStrToFloat(Src) + else + VF := 0; + Move(VF, Dest^, SizeOf(Double)); + end; + FIELD_TYPE_TIMESTAMP: + begin + if Src <> '' then + VD := InternalStrToTimeStamp(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_DATETIME: + begin + if Src <> '' then + VD := InternalStrToDateTime(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_DATE: + begin + if Src <> '' then + VD := InternalStrToDate(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_TIME: + begin + if Src <> '' then + VD := InternalStrToTime(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING, FIELD_TYPE_ENUM, FIELD_TYPE_SET: + begin +// if Src<> '' then + Move(Source^, Dest^, ASize) +// else +// Dest^ := #0; + end; + field_type_blob: begin + int1:= acursor.addblobdata(source,asize); + move(int1,dest^,sizeof(int1)); + //save id + end; + end; + end; + end; +end; + +procedure TConnectionName.UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); +var + qry: tsqlresult; + keynamef,{filednamef,}columnnamef,nonuniquef: tdbcol; + str1: string; +begin + if not assigned(Transaction) then begin + DatabaseError(SErrConnTransactionnSet); + end; + qry:= tsqlresult.Create(nil); + try + with qry do begin + database := Self; + sql.text:= 'show index from ' + msestring(aTableName); + active:= true; + keynamef:= datacols.colbyname('Key_name'); + columnnamef:= datacols.colbyname('Column_name'); + nonuniquef:= datacols.colbyname('Non_unique'); + while not eof do begin + with IndexDefs.AddIndexDef do begin + Name:= trim(keynamef.asstring); + if Name = 'PRIMARY' then begin + options:= options + [ixPrimary]; + end; + if nonuniquef.asinteger = 0 then begin + options:= options + [ixUnique]; + end; + str1:= ''; + repeat + str1:= str1 + trim(columnnamef.asstring) + ';'; + next; + until eof or (name <> keynamef.asstring); + setlength(str1,length(str1)-1); //remove last ';' + fields:= str1; + end; + end; + end; + finally + qry.free; + end; +end; + + +function TConnectionName.GetTransactionHandle(trans: TSQLHandle): pointer; +begin + Result:=Nil; +end; + +function TConnectionName.Commit(trans: TSQLHandle): boolean; +begin + result:= true; + // Do nothing. +end; + +function TConnectionName.RollBack(trans: TSQLHandle): boolean; +begin + result:= true; + // Do nothing +end; + +function TConnectionName.StartdbTransaction(const trans: TSQLHandle; + const AParams: tstringlist): boolean; +begin + result:= true; + // Do nothing +end; + +procedure TConnectionName.internalCommitRetaining(trans: TSQLHandle); +begin + // Do nothing +end; + +procedure TConnectionName.internalRollBackRetaining(trans: TSQLHandle); +begin + // Do nothing +end; + +function TConnectionName.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +var + blobid: integer; +// int1,int2: integer; +// str1: string; +// bo1: boolean; +begin + result:= nil; + if mode = bmread then begin + if field.getData(@blobId) then begin + result:= acursor.getcachedblob(blobid); + end; + end; +end; + +function TConnectionName.getblobdatasize: integer; +begin + result:= sizeof(integer); +end; +{ +function TConnectionName.getfeatures(): databasefeaturesty; +begin + result:= inherited getfeatures() + [dbf_blobscached]; +end; +} +procedure TConnectionName.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); +var + str1: string; + int1: integer; +begin + setlength(str1,alength); + move(adata^,str1[1],alength); + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + int1:= acursor.addblobdata(str1); + setlength(newid,sizeof(int1)); + move(int1,newid[1],sizeof(int1)); +end; + +procedure TConnectionName.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +begin + acursor.blobfieldtoparam(afield,aparam,false); +end; +{ +function TConnectionName.blobscached: boolean; +begin + result:= true; +end; +} +function TConnectionName.getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; +begin + result:= tcursorname(acursor).fprimarykeyfieldname; +end; + +function TConnectionName.getinsertid(const atransaction: tsqltransaction): int64; +begin + result:= mysql_insert_id(fmysql); +end; + +procedure TConnectionName.updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); +begin + afield.aslargeint:= getinsertid(nil); + { + with tmsebufdataset1(afield.dataset) do begin + setcurvalue(afield,getinsertid); + end; + } +end; + +function TConnectionName.identquotechar: msestring; +begin + result:= '`'; //needed for reserved words as fieldnames +end; + +{ eerrorname } + +constructor eerrorname.create(const asender: tcustomsqlconnection; + const amessage: ansistring; const aerrormessage: msestring; + const aerror: integer; const asqlcode: string); +begin + fsqlcode:= asqlcode; + inherited create(asender,amessage,aerrormessage,aerror); +end; + +end. diff --git a/mseide-msegui/lib/common/db/mmysqlconn.pas b/mseide-msegui/lib/common/db/mmysqlconn.pas new file mode 100644 index 0000000..9293c9a --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysqlconn.pas @@ -0,0 +1,1965 @@ +{ + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{Modified 2006-2013 by Martin Schreiber} + +unit mmysqlconn; + +{$ifdef FPC}{$mode objfpc}{$H+}{$MACRO on}{$endif} + +{$DEFINE mysql51} + +{$ifdef mysql51} + {$define mysql50} +{$endif} +{$ifdef mysql50} + {$define mysql41} +{$endif} + +interface +uses +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + classes,mclasses,SysUtils,msqldb,mdb,{$ifdef FPC}dynlibs,{$endif}msestrings, + msedb,mysqldyn,msetypes,msectypes; + +Type + + tmysqlcursor = class; + + emysqlerror = class(econnectionerror) + private + fsqlcode: string; + public + constructor create(const asender: tcustomsqlconnection; + const amessage: ansistring; const aerrormessage: msestring; + const aerror: integer; const asqlcode: string); + property sqlcode: string read fsqlcode; + end; + + tmysqltrans = class(TSQLHandle) + protected + fconn: pmysql; + public + property conn: pmysql read fconn; + end; + + bindinginfoty = record + length: culong; + buffer: pointer; + isnull: boolean; //-> cchar + isblob: boolean; //-> cchar + end; + pbindinginfoty = ^bindinginfoty; + bindinginfoarty = array of bindinginfoty; + + tmysqlcursor = class(TSQLCursor) + protected +// FQMySQL : PMySQL; + FRes: PMYSQL_RES; { Record pointer } + FNeedData : Boolean; + fstatementm: msestring; + Row : MYSQL_ROW; +// RowsAffected : QWord; + LastInsertID : QWord; + ParamBinding : TParamBinding; + ParamReplaceString : mseString; + MapDSRowToMSQLRow: integerarty; + fprimarykeyfieldname: string; + fconn: pmysql; + fparambinding: tparambinding; + fprepstatement: pmysql_stmt; + fresultmetadata: pmysql_res; + fresultfieldcount: integer; + fresultbindinginfo: bindinginfoarty; + fresultbindings: pointer; + fresultbuf: pointer; + procedure freeprepstatement; + public + end; + + mysqloptionty = (myo_nopreparedstatements,myo_storeresult,myo_ssl); + mysqloptionsty = set of mysqloptionty; + + tmysqlconnection = class (TSQLConnection,iblobconnection) + private + FDialect: integer; + FHostInfo: String; + FServerInfo: String; + FMySQL1 : PMySQL; +// FDidConnect : Boolean; + fport: longword; + flasterror: integer; + foptions: mysqloptionsty; + flasterrormessage: msestring; + flastsqlcode: string; + ftransactionconnectionused: boolean; + fssl_key: filenamety; + fssl_cert: filenamety; + fssl_ca: filenamety; + fssl_capath: filenamety; + fssl_cipher: filenamety; + function GetClientInfo: string; + function GetServerStatus: String; + procedure ConnectMySQL(var HMySQL : PMySQL;H,U,P : pchar); + procedure freeresultbuffer(const cursor: tmysqlcursor); + procedure begintrans(const aconnection: pmysql; const aparams: ansistring); + procedure openconnection(var aconn: pmysql); + procedure closeconnection(var aconnection: pmysql); + protected + Procedure checkerror(const Msg: String; const aconn: pmysql); + Procedure checkstmterror(const Msg: String; const astmt: pmysql_stmt); + +// function stringtosqltext(const afeildtype: tfieldtype; const avalue: string): string; + function StrToStatementType(s : msestring) : TStatementType; override; +// Procedure ConnectToServer; virtual; +// Procedure SelectDatabase; virtual; +// function MySQLDataType(AType: enum_field_types; ASize, ADecimals: Integer; var NewType: TFieldType; var NewSize: Integer): Boolean; + function MySQLDataType(const afield: mysql_field; + const charsetinfo: my_charset_info; out NewType: TFieldType; + out NewSize: Integer; out newprecision: integer): Boolean; + function MySQLWriteData(const acursor: tsqlcursor; AType: enum_field_types; + ASize: Integer; + AFieldType: TFieldType;Source, Dest: PChar): Boolean; + // SQLConnection methods + procedure DoInternalConnect; override; + procedure executeparams; override; + procedure DoInternalDisconnect; override; + function GetHandle : pointer; override; + +// function GetAsSQLText(Field : TField) : string; overload; override; +// function GetAsSQLText(Param : TParam) : string; overload; override; + + Function AllocateTransactionHandle : TSQLHandle; override; + procedure finalizetransaction(const atransaction: tsqlhandle); override; + + procedure doexecuteunprepared(const c: tmysqlcursor; + const atransaction: tsqltransaction; const asql: string); + procedure internalExecute(const cursor: TSQLCursor; + const atransaction:tSQLtransaction; + const AParams: TmseParams; const autf8: boolean); override; + procedure internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); override; + + function GetTransactionHandle(trans : TSQLHandle): pointer; override; + function Commit(trans : TSQLHandle) : boolean; override; + function RollBack(trans : TSQLHandle) : boolean; override; + function StartdbTransaction(const trans : TSQLHandle; + const AParams: tstringlist) : boolean; override; + procedure internalCommitRetaining(trans : TSQLHandle); override; + procedure internalRollBackRetaining(trans : TSQLHandle); override; + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); override; + + function getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; override; + procedure updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + function getblobdatasize: integer; override; +// function getfeatures(): databasefeaturesty override; + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); +// function blobscached: boolean; + function identquotechar: msestring; override; + + Public + constructor create(aowner: tcomponent); override; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; override; + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + procedure UnPrepareStatement(cursor:TSQLCursor); override; + procedure FreeFldBuffers(cursor : TSQLCursor); override; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); override; + function Fetch(cursor : TSQLCursor) : boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const abuffer: pointer; var abufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //null based + function getinsertid(const atransaction: tsqltransaction): int64; override; + procedure createdatabase(const asql: ansistring); + Property ServerInfo : String Read FServerInfo; + Property HostInfo : String Read FHostInfo; + property ClientInfo: string read GetClientInfo; + property ServerStatus : String read GetServerStatus; + property lasterror: integer read flasterror; + property lasterrormessage: msestring read flasterrormessage; + property lastsqlcode: string read flastsqlcode; + published + property options: mysqloptionsty read foptions write foptions default []; + property Dialect : integer read FDialect write FDialect default 0; + property port: longword read fport write fport default 0; + property ssl_key: filenamety read fssl_key write fssl_key; + property ssl_cert: filenamety read fssl_cert write fssl_cert; + property ssl_ca: filenamety read fssl_ca write fssl_ca; + property ssl_capath: filenamety read fssl_capath write fssl_capath; + property ssl_cipher: filenamety read fssl_cipher write fssl_cipher; + property DatabaseName; + property HostName; + property KeepConnection; +// property LoginPrompt; + property Params; + property ongetcredentials; +// property OnLogin; + end; + +// EMySQLError = Class(Exception); + +implementation +uses + {$ifdef FPC}dbconst{$else}dbconst_del,classes_del{$endif}, + msebufdataset,typinfo,dateutils,msefileutils,msedatabase,msedynload, + msesqlresult; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tmsebufdataset1 = class(tmsebufdataset); +var + is51: boolean; +const + maxprecision = 18; + +Resourcestring + SErrServerConnectFailed = 'Server connect failed: %s'; + SErrDatabaseSelectFailed = 'failed to select database: %s'; + SErrDatabaseCreate = 'Failed to create database: %s'; + SErrDatabaseDrop = 'Failed to drop database: %s'; + sbindresult = 'Failed to bind result: %s'; + serrstarttransaction = 'Failed to start transaction: %s'; + serrcommittransaction = 'Failed to commit transaction: %s'; + serrrollbacktransaction = 'Failed to rollback transaction: %s'; + serrprepare = 'Failed to prepare statement: %s'; + SErrNoData = 'No data for record'; + SErrExecuting = 'Error executing query: %s'; + SErrFetchingdata = 'Error fetching row data: %s'; + SErrGettingResult = 'Error getting result set: %s'; + SErrNoQueryResult = 'No result from query.'; + SErrNotversion50 = 'TMySQL50Connection can not work with the installed MySQL client version (%s).'; + SErrNotversion41 = 'TMySQL41Connection can not work with the installed MySQL client version (%s).'; + SErrNotversion40 = 'TMySQL40Connection can not work with the installed MySQL client version (%s).'; + +function datetimetomysql_time(const datatype: tfieldtype; + const avalue: tdatetime): mysql_time; +var + year1,month1,day1,hour1,minute1,second1,millisecond1: word; +begin + fillchar(result,sizeof(result),0); + decodedatetime(avalue,year1,month1,day1,hour1,minute1,second1,millisecond1); + with result do begin + if datatype in [ftdate,ftdatetime] then begin + year:= year1; + month:= month1; + day:= day1; + time_type:= mysql_timestamp_date; + end; + if datatype in [fttime,ftdatetime] then begin + hour:= hour1; + minute:= minute1; + second:= second1; + second_part:= millisecond1 * 1000; + time_type:= mysql_timestamp_time; + end; + if datatype = ftdatetime then begin + time_type:= mysql_timestamp_datetime; + end; + end; +end; + +function mysql_timetodatetime(const avalue: mysql_time): tdatetime; +begin + result:= 0; + with avalue do begin + case time_type of + mysql_timestamp_date: begin + tryencodedate(year,month,day,result); + end; + mysql_timestamp_time: begin + tryencodetime(hour,minute,second,second_part div 1000, + result); + end; + else begin + tryencodedatetime(year,month,day,hour,minute,second,second_part div 1000, + result); + end; + end; + end; +end; + +function createbindings(const acount: integer): pointer; +var + int1: integer; +begin + result:= nil; + if is51 then begin + int1:= acount * sizeof(mysql_bind_51); + end + else begin + int1:= acount * sizeof(mysql_bind_50); + end; + if int1 > 0 then begin + getmem(result,int1); + fillchar(result^,int1,0); + end; +end; + +function getbind(const abindings: pointer; const index: integer): pointer; +begin +{$ifdef FPC} + if is51 then begin + result:= @pmysql_bind_51(abindings)[index]; + end + else begin + result:= @pmysql_bind_50(abindings)[index]; + end; +{$else} + if is51 then begin + result:= pointer(pchar(abindings)+sizeof(mysql_bind_51)*index); + end + else begin + result:= pointer(pchar(abindings)+sizeof(mysql_bind_50)*index); + end; +{$endif} +end; + +procedure freebindings(var abindings: pointer); +begin + if abindings <> nil then begin + freemem(abindings); + abindings:= nil; + end; +end; + +procedure setupresultbinding(const index: integer; const fieldtype: tfieldtype; + const len: integer; //character count + const bindings: pointer; var bindinginfo: bindinginfoarty); +var + bi: pbindinginfoty; + bufsize: integer; + pbuffer_type: penum_field_types; + pbuffer_length: pculong; +begin + bi:= @bindinginfo[index]; + if is51 then begin +{$ifdef FPC} + with pmysql_bind_51(bindings)[index] do begin +{$else} + with pmysql_bind_51(pointer(pchar(bindings)+sizeof(mysql_bind_51)*index))^ do begin +{$endif} + pbuffer_type:= @buffer_type; + pbuffer_length:= @buffer_length; + length:= @bi^.length; + is_null:= @bi^.isnull; + end; + end + else begin + {$ifdef FPC} + with pmysql_bind_50(bindings)[index] do begin + {$else} + with pmysql_bind_50(pointer(pchar(bindings)+sizeof(mysql_bind_50)*index))^ do begin + {$endif} + pbuffer_type:= @buffer_type; + pbuffer_length:= @buffer_length; + length:= @bi^.length; + is_null:= @bi^.isnull; + end; + end; + case fieldtype of + ftinteger: begin + bufsize:= sizeof(longint); + pbuffer_type^:= mysql_type_long; + end; + ftlargeint: begin + bufsize:= sizeof(int64); + pbuffer_type^:= mysql_type_longlong; + end; + ftbcd,ftfloat: begin + bufsize:= sizeof(double); + pbuffer_type^:= mysql_type_double; + end; + ftdate,ftdatetime,fttime: begin + bufsize:= sizeof(mysql_time); + pbuffer_type^:= mysql_type_datetime; + end; + ftstring: begin + bufsize:= len*4; //room for multibyte encodings + pbuffer_type^:= mysql_type_var_string; + end; + ftblob,ftmemo,ftgraphic: begin + bufsize:= 0; + pbuffer_type^:= mysql_type_blob; + end + else begin + bufsize:= 0; //dummy + pbuffer_type^:= mysql_type_null; + end; + end; + pbuffer_length^:= bufsize; + bi^.length:= bufsize; + bi^.isblob:= bufsize = 0; +end; + +procedure setupinputbinding(const index: integer; const fieldtype: tfieldtype; + const bindings: pointer; var bindinginfo: bindinginfoarty; + const abuffer: pointer; const abufsize: integer); +var + bi: pbindinginfoty; + bufsize: integer; + pbuffer_type: penum_field_types; + pbuffer_length: pculong; +begin + bi:= @bindinginfo[index]; + if is51 then begin +{$ifdef FPC} + with pmysql_bind_51(bindings)[index] do begin +{$else} + with pmysql_bind_51(pointer(pchar(bindings)+sizeof(mysql_bind_51)*index))^ do begin +{$endif} + pbuffer_type:= @buffer_type; + pbuffer_length:= @buffer_length; + length:= @bi^.length; + is_null:= @bi^.isnull; + buffer:= abuffer; + end; + end + else begin +{$ifdef FPC} + with pmysql_bind_50(bindings)[index] do begin +{$else} + with pmysql_bind_50(pointer(pchar(bindings)+sizeof(mysql_bind_50)*index))^ do begin +{$endif} + pbuffer_type:= @buffer_type; + pbuffer_length:= @buffer_length; + length:= @bi^.length; + is_null:= @bi^.isnull; + buffer:= abuffer; + end; + end; + case fieldtype of + ftinteger: begin + bufsize:= sizeof(longint); + pbuffer_type^:= mysql_type_long; + end; + ftlargeint: begin + bufsize:= sizeof(int64); + pbuffer_type^:= mysql_type_longlong; + end; + ftbcd,ftfloat: begin + bufsize:= sizeof(double); + pbuffer_type^:= mysql_type_double; + end; + ftdate,ftdatetime,fttime: begin + bufsize:= sizeof(mysql_time); + pbuffer_type^:= mysql_type_datetime; + end; + ftstring: begin + bufsize:= abufsize; + pbuffer_type^:= mysql_type_var_string; + end; + ftblob,ftmemo,ftgraphic: begin + bufsize:= abufsize; + pbuffer_type^:= mysql_type_blob; + end + else begin + bufsize:= 0; //dummy + pbuffer_type^:= mysql_type_null; + end; + end; + bi^.length:= bufsize; + pbuffer_length^:= bufsize; + bi^.isblob:= bufsize = 0; +end; + +function createbindingbuffers(const bindings: pointer; + var bindinfos: bindinginfoarty): pointer; +var + int1: integer; + bufsum: longword; +begin + bufsum:= 0; + for int1:= 0 to high(bindinfos) do begin + bufsum:= bufsum + bindinfos[int1].length; + end; + getmem(result,bufsum); + bufsum:= 0; + for int1:= 0 to high(bindinfos) do begin + with bindinfos[int1] do begin + if length > 0 then begin + buffer:= pchar(result) + bufsum; + if is51 then begin +{$ifdef FPC} + pmysql_bind_51(bindings)[int1].buffer:= buffer; +{$else} + pmysql_bind_51(pointer(pchar(bindings)+ + sizeof(mysql_bind_51)*int1))^.buffer:= buffer; +{$endif} + end + else begin +{$ifdef FPC} + pmysql_bind_50(bindings)[int1].buffer:= buffer; +{$else} + pmysql_bind_50(pointer(pchar(bindings)+ + sizeof(mysql_bind_50)*int1))^.buffer:= buffer; +{$endif} + end; + bufsum:= bufsum + length; + end; + end; + end; +end; + +procedure freebindingbuffers(var abuffer: pointer); +begin + if abuffer <> nil then begin + freemem(abuffer); + abuffer:= nil; + end; +end; + +procedure setbindingbuffer(const bindings: pointer; const index: integer; + const abuffer: pointer; const alength: integer); +begin + if is51 then begin +{$ifdef FPC} + with pmysql_bind_51(bindings)[index] do begin +{$else} + with pmysql_bind_51(pointer(pchar(bindings)+sizeof(mysql_bind_51)*index))^ do begin +{$endif} + buffer:= abuffer; + buffer_length:= alength; + end; + end + else begin +{$ifdef FPC} + with pmysql_bind_50(bindings)[index] do begin +{$else} + with pmysql_bind_50(pointer(pchar(bindings)+sizeof(mysql_bind_50)*index))^ do begin +{$endif} + buffer:= abuffer; + buffer_length:= alength; + end; + end; +end; + +{ tmysqlcursor } + +procedure tmysqlcursor.freeprepstatement; +begin + if fprepstatement <> nil then begin + mysql_stmt_close(fprepstatement); + fprepstatement:= nil; + end; +end; + +{ tmysqlconnection } + +constructor tmysqlconnection.create(aowner: tcomponent); +begin + inherited; + fconnoptions:= fconnoptions + [sco_supportparams,sco_emulateretaining, + sco_blobscached]; +end; + +Procedure tmysqlconnection.checkerror(const Msg: String; const aconn: pmysql); +var + str1: msestring; +begin + str1:= connectionmessage(mysql_error(aconn)); + flasterrormessage:= str1; + flasterror:= mysql_errno(aconn); + flastsqlcode:= strpas(mysql_sqlstate(aconn)); + raise emysqlerror.create(self,format(msg,[str1]),flasterrormessage, + flasterror,flastsqlcode); +end; + +Procedure tmysqlconnection.checkstmterror(const Msg: String; + const astmt: pmysql_stmt); +var + str1: msestring; +begin + str1:= connectionmessage(mysql_stmt_error(astmt)); + flasterrormessage:= str1; + flasterror:= 0; //??? + flastsqlcode:= ''; //??? + raise emysqlerror.create(self,format(msg,[str1]),flasterrormessage, + flasterror,flastsqlcode); +end; + +function tmysqlconnection.StrToStatementType(s : msestring) : TStatementType; + +begin + S:=Lowercase(s); + if s = 'show' then begin + result:= stSelect; + exit; + end; + result := inherited StrToStatementType(s); +end; + +function tmysqlconnection.GetClientInfo: string; + +//Var +// B : Boolean; + +begin + // To make it possible to call this if there's no connection yet +// B:=(MysqlLibraryHandle=Nilhandle); +// If B then + InitializeMysql([]); + Try + Result:=strpas(mysql_get_client_info()); + Finally +// if B then + ReleaseMysql; + end; +end; + +function tmysqlconnection.GetServerStatus: String; +begin + CheckConnected; + Result := mysql_stat(FMYSQL1); +end; + +procedure tmysqlconnection.ConnectMySQL(var HMySQL : PMySQL;H,U,P : pchar); +var + key,cert,ca,capath,cipher: string; + hmysql1: pmysql; + actcipher: pchar; +begin + dynloadlock; + HMySQL := mysql_init(HMySQL); + dynloadunlock; + if myo_ssl in foptions then begin + key:= ansistring(tosysfilepath(fssl_key)); + cert:= ansistring(tosysfilepath(fssl_cert)); + ca:= ansistring(tosysfilepath(fssl_ca)); + capath:= ansistring(tosysfilepath(fssl_capath)); + cipher:= ansistring(fssl_cipher); + mysql_ssl_set(hmysql,pointer(key),pointer(cert),pointer(ca),pointer(capath), + pointer(cipher)); + end; + HMySQL1:=mysql_real_connect(HMySQL,PChar(H),PChar(U),Pchar(P),Nil,fport,Nil,0); + If (HMySQL1=Nil) then begin + checkerror(SErrServerConnectFailed,hmysql); + end; + if (myo_ssl in foptions) and + ({$ifndef FPC}@{$endif}mysql_get_ssl_cipher <> nil) then begin + actcipher:= mysql_get_ssl_cipher(hmysql); + if actcipher = nil then begin + closeconnection(hmysql); + databaseerror('Can not encrypt connection.',self); + end; + end; +end; +{ +function tmysqlconnection.stringtosqltext(const afieldtype: tfieldtype; + const avalue: string): string; +var + esc_str : pchar; +begin + Getmem(esc_str,length(avalue)*2+1); + mysql_real_escape_string(FMySQL,esc_str,pchar(str1),length(str1)); + Result := '''' + esc_str + ''''; + Freemem(esc_str); +end; + +function tmysqlconnection.GetAsSQLText(Field : TField) : string; +var + esc_str : pchar; + str1: string; +begin + if (not assigned(field)) or field.IsNull then begin + Result := 'Null' + end + else begin + if field.DataType in [ftString,ftmemo,ftblob,ftgraphic] then begin + result:= stringtosqltext(field.datatype,field.asstring); + end + else begin + Result := inherited GetAsSqlText(field); + end; + end; +end; + +function tmysqlconnection.GetAsSQLText(Param: TParam) : string; +var + esc_str : pchar; + str1: string; +begin + if (not assigned(param)) or param.IsNull then begin + Result:= 'Null' + end + else begin + if param.DataType in [ftString,ftmemo,ftblob,ftgraphic] then begin + str1:= param.asstring; + Getmem(esc_str,length(str1)*4+1); + mysql_real_escape_string(FMySQL,esc_str,pchar(str1),length(str1)); + Result:= '''' + esc_str + ''''; + Freemem(esc_str); + end + else begin + Result:= inherited GetAsSqlText(Param); + end; + end; +end; +} + +procedure tmysqlconnection.openconnection(var aconn: pmysql); +Var + H: string; + u,p: msestring; + u1,p1: string; + +begin + H:= ansistring(HostName); + getcredentials(u,p); + u1:= ansistring(u); + p1:= ansistring(p); +// U:= UserName; +// P:= Password; + try + ConnectMySQL(aconn,pchar(H),pchar(U1),pchar(P1)); + finally + stringsafefree(u1,false); + stringsafefree(p1,false); + freecredentials(u,p); + end; + if mysql_select_db(aconn,pchar(ansistring(DatabaseName))) <> 0 then begin + checkerror(SErrDatabaseSelectFailed,aconn); + end; +end; + +procedure tmysqlconnection.closeconnection(var aconnection: pmysql); +begin + mysql_close(aconnection); + aconnection:= nil; +end; + +procedure tmysqlconnection.DoInternalConnect; +var + version: integer; +begin + ftransactionconnectionused:= false; + InitializeMysql([]); + version:= mysql_get_client_version() div 100; + if version < 500 then begin + raise exception.create(name+': MySql client version must be >= 5.0.'); + end; + is51:= version >= 501; + inherited DoInternalConnect; + openconnection(fmysql1); + FServerInfo := strpas(mysql_get_server_info(FMYSQL1)); + FHostInfo := strpas(mysql_get_host_info(FMYSQL1)); + if charset <> '' then begin + mysql_set_character_set(fmysql1,pchar(charset)); + end; +end; + +procedure tmysqlconnection.executeparams; +var + int1: integer; + bo1: boolean; +begin + if params.count > 0 then begin + checktransaction(name,transaction); + bo1:= transaction.active; + try + for int1:= 0 to params.count-1 do begin + executedirect(msestring(params[int1])); + end; + if not bo1 then begin + bo1:= true; + transaction.commit; + end; + finally + if not bo1 then begin + transaction.rollback; + end; + end; + end; +end; + +procedure tmysqlconnection.DoInternalDisconnect; +begin + inherited DoInternalDisconnect; + closeconnection(fmysql1); + ReleaseMysql; +end; + +function tmysqlconnection.GetHandle: pointer; +begin + Result:=FMySQL1; +end; + +function tmysqlconnection.AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; +begin + Result:= tmysqlcursor.Create(aowner,aname); + tmysqlcursor(result).fconn:= fmysql1; //can be overridden by transaction +end; + +Procedure tmysqlconnection.DeAllocateCursorHandle(var cursor : TSQLCursor); + +Var + C : tmysqlcursor; + +begin + if cursor <> nil then begin + C:= tmysqlcursor(cursor); + freeresultbuffer(c); + freebindingbuffers(c.fresultbuf); + FreeAndNil(cursor); + end; +end; + +function tmysqlconnection.AllocateTransactionHandle: TSQLHandle; +begin +// Result:=tmysqltransaction.Create; + Result:= tmysqltrans.create; +end; + +procedure tmysqlconnection.finalizetransaction(const atransaction: tsqlhandle); +begin + with tmysqltrans(atransaction) do begin + if (fconn <> fmysql1) then begin + closeconnection(fconn); + end; + fconn:= nil; + end; +end; + +procedure tmysqlconnection.preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); +var + mstr1: msestring; + str1: ansistring; +// fieldcount: integer; +begin + With tmysqlcursor(cursor) do begin + fconn:= tmysqltrans(atransaction.trans).fconn; + if fconn = nil then begin + fconn:= fmysql1; // dummy transaction + tmysqltrans(atransaction.trans).fconn:= fmysql1; + end; + + if not (myo_nopreparedstatements in foptions) and + (FStatementType in [stInsert,stUpdate,stDelete,stSelect]) then begin + fprepstatement:= mysql_stmt_init(fconn); + if fprepstatement = nil then begin + checkerror(serrprepare,fconn); + end; + if assigned(aparams) then begin + mstr1:= aparams.parsesql(asql,true,false,false,psinterbase,fparambinding); + end + else begin + mstr1:= asql; + end; + mstr1:= trim(mstr1); + if (mstr1 <> '') and (mstr1[length(mstr1)] = ';') then begin + setlength(mstr1,length(mstr1)-1); + end; + str1:= ansistring(mstr1); //utf8? + if mysql_stmt_prepare(fprepstatement,pchar(str1), + length(str1)) <> 0 then begin + try + checkstmterror(serrprepare,fprepstatement); + finally + freeprepstatement; + end; + end; + fresultmetadata:= mysql_stmt_result_metadata(fprepstatement); + if fresultmetadata <> nil then begin + fresultfieldcount:= mysql_num_fields(fresultmetadata); + fresultbindings:= createbindings(fresultfieldcount); + end + else begin + fresultfieldcount:= 0; + end; + end + else begin + FStatementm:= asql; + if assigned(AParams) and (AParams.count > 0) then begin + FStatementm:= AParams.ParseSQL(FStatementm,false,false,false,psSimulated, + paramBinding,ParamReplaceString); + end; + end; + if FStatementType in datareturningtypes then begin + FNeedData:=True; + end; + fprepared:= true; + end; +end; + +procedure tmysqlconnection.UnPrepareStatement(cursor: TSQLCursor); +begin + with tmysqlcursor(cursor) do begin + fstatementm:= ''; + fprepared:= false; + fparambinding:= nil; + freeprepstatement; + freebindings(fresultbindings); + if fresultmetadata <> nil then begin + mysql_free_result(fresultmetadata); + fresultmetadata:= nil; + end; + end; +end; + +procedure tmysqlconnection.freeresultbuffer(const cursor: tmysqlcursor); +begin + if cursor.fres <> nil then begin + mysql_free_result(cursor.fres); + cursor.fres:= nil; + end; + if cursor.fprepstatement <> nil then begin + mysql_stmt_free_result(cursor.fprepstatement); + end; +end; + +procedure tmysqlconnection.FreeFldBuffers(cursor: TSQLCursor); + +Var + C : tmysqlcursor; + +begin + C:= tmysqlcursor(cursor); + if c.FStatementType in datareturningtypes then + c.FNeedData:=False; + freeresultbuffer(c); + c.mapdsrowtomsqlrow:= nil; +// SetLength(c.MapDSRowToMSQLRow,0); + c.fresultbindinginfo:= nil; + freebindingbuffers(c.fresultbuf); +end; + +procedure tmysqlconnection.doexecuteunprepared(const c: tmysqlcursor; + const atransaction: tsqltransaction; const asql: string); +begin + with tmysqltrans(atransaction.trans) do begin + if mysql_query(fconn,Pchar(asql)) <> 0 then begin + checkerror(SErrExecuting,fconn); + end + else begin + C.fRowsAffected := mysql_affected_rows(fconn); + C.LastInsertID := mysql_insert_id(fconn); + if C.FNeedData then begin + if myo_storeresult in foptions then begin + C.FRes:= mysql_store_result(fconn); + end + else begin + C.FRes:= mysql_use_result(fconn); + //needs to call mysql_fetch_row() until all data has been fetched + end; + if myo_storeresult in foptions then begin + c.frowsreturned:= mysql_num_rows(c.fres); + end; + end; + end; + end; +end; + +procedure tmysqlconnection.internalExecute(const cursor: TSQLCursor; + const atransaction: tSQLtransaction; const AParams : TmseParams; + const autf8: boolean); + +var + C: tmysqlcursor; +// i: integer; + str1: ansistring; +// par1: tparam; + int1: integer; + inputparambindings: bindinginfoarty; + paramdata: pointer; + inputbindings: pointer; + strings: stringarty; + dataty1: tfieldtype; + mstr1: msestring; +begin + C:= tmysqlcursor(cursor); + c.frowsaffected:= -1; + c.frowsreturned:= -1; + if not C.FNeedData then begin + c.frowsreturned:= 0; + end; + freeresultbuffer(c); + if c.fprepstatement <> nil then begin + paramdata:= nil; + inputbindings:= nil; + if (aparams <> nil) and (aparams.count > 0) then begin + inputbindings:= createbindings(length(c.fparambinding)); + setlength(inputparambindings,length(c.fparambinding)); + setlength(strings,length(c.fparambinding)); + for int1:= 0 to high(c.fparambinding) do begin + if c.fparambinding[int1] < aparams.count then begin + with aparams[c.fparambinding[int1]] do begin + case datatype of //todo: date and time + ftinteger,ftsmallint,ftword: begin + setupinputbinding(int1,ftinteger,inputbindings, + inputparambindings,nil,sizeof(integer)); + end; + ftlargeint: begin + setupinputbinding(int1,ftlargeint,inputbindings, + inputparambindings,nil,sizeof(int64)); + end; + ftfloat,ftcurrency,ftbcd: begin + setupinputbinding(int1,ftfloat,inputbindings, + inputparambindings,nil,sizeof(double)); + end; + ftdate,ftdatetime,fttime: begin + setupinputbinding(int1,ftdatetime,inputbindings, + inputparambindings,nil,sizeof(mysql_time)); + end; + ftstring,ftwidestring,ftblob,ftmemo,ftfixedchar,ftfixedwidechar: begin + setupinputbinding(int1,ftstring,inputbindings, + inputparambindings,nil,0); + //dummy for NULL, setup later + end; + else begin + freebindings(inputbindings); + databaseerror('Paramtype '+ + getenumname(typeinfo(tfieldtype),ord(datatype))+' not supported.',self); + end; + end; + end; + end; + end; + paramdata:= createbindingbuffers(inputbindings,inputparambindings); + for int1:= 0 to high(c.fparambinding) do begin + if c.fparambinding[int1] < aparams.count then begin + with aparams[c.fparambinding[int1]] do begin + if isnull then begin + inputparambindings[int1].isnull:= true; + end + else begin + case datatype of + ftinteger,ftsmallint,ftword: begin + pinteger(inputparambindings[int1].buffer)^:= asinteger; + end; + ftlargeint: begin + pint64(inputparambindings[int1].buffer)^:= aslargeint; + end; + ftfloat,ftbcd,ftcurrency: begin + pdouble(inputparambindings[int1].buffer)^:= asfloat; + end; + ftdate,ftdatetime,fttime: begin + pmysql_time(inputparambindings[int1].buffer)^:= + datetimetomysql_time(datatype,asdatetime); + end; + ftstring,ftwidestring,ftblob,ftmemo,ftfixedchar,ftfixedwidechar: begin + strings[int1]:= aparams.asdbstring(c.fparambinding[int1]); + dataty1:= datatype; + if dataty1 <> ftblob then begin + dataty1:= ftstring; + end; + setupinputbinding(int1,dataty1,inputbindings, + inputparambindings,pointer(strings[int1]), + length(strings[int1])); + end; + end; + end; + end; + end; + end; + end; + try + if mysql_stmt_bind_param(c.fprepstatement,inputbindings) <> 0 then begin + checkstmterror(serrexecuting,c.fprepstatement); + end; + if mysql_stmt_execute(c.fprepstatement) <> 0 then begin + checkstmterror(serrexecuting,c.fprepstatement); + end; + if myo_storeresult in foptions then begin + if mysql_stmt_store_result(c.fprepstatement) <> 0 then begin + checkstmterror(serrexecuting,c.fprepstatement); + end; + if myo_storeresult in foptions then begin + c.frowsreturned:= mysql_stmt_num_rows(c.fprepstatement); + end; + end; + finally + freebindingbuffers(paramdata); + freebindings(inputbindings); + end; + C.fRowsAffected := mysql_stmt_affected_rows(c.fprepstatement); + C.LastInsertID := mysql_stmt_insert_id(c.fprepstatement); + end + else begin //not prepared + if Assigned(AParams) and (aparams.count > 0) then begin + mstr1:= aparams.expandvalues(c.fstatementm, + c.parambinding,c.paramreplacestring); + end + else begin + mstr1:= c.fstatementm; + end; + if autf8 then begin + str1:= stringtoutf8ansi(mstr1); + end + else begin + str1:= ansistring(mstr1); + end; + doexecuteunprepared(c,atransaction,str1); + end; +// if not C.FNeedData then begin +// c.frowsreturned:= 0; +// end; +end; + +procedure tmysqlconnection.internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); +var + C: tmysqlcursor; +begin + C:= tmysqlcursor(cursor); + c.frowsaffected:= -1; + c.frowsreturned:= -1; + c.fneeddata:= c.FStatementType in datareturningtypes; + if not C.FNeedData then begin + c.frowsreturned:= 0; + end; + freeresultbuffer(c); + doexecuteunprepared(c,atransaction,asql); +end; + +//function tmysqlconnection.MySQLDataType(AType: enum_field_types; ASize, ADecimals: Integer; +// var NewType: TFieldType; var NewSize: Integer): Boolean; +function tmysqlconnection.MySQLDataType(const afield: mysql_field; + const charsetinfo: my_charset_info; + out NewType: TFieldType; out NewSize: Integer; + out newprecision: integer): Boolean; +begin + Result := True; + NewSize:= 0; + newprecision:= 0; + with afield do begin + case ftype of + FIELD_TYPE_TINY,FIELD_TYPE_SHORT,FIELD_TYPE_LONG: begin + NewType:= ftInteger; + end; + FIELD_TYPE_LONGLONG,FIELD_TYPE_INT24: begin + newtype:= ftlargeint; + end; + {$ifdef mysql50} + FIELD_TYPE_NEWDECIMAL, + {$endif} + FIELD_TYPE_DECIMAL: begin + newprecision:= length - 2; + if (Decimals <= 4) or not (dbo_bcdtofloatif in controller.options) then begin + if newprecision > maxprecision then begin + newprecision:= maxprecision; + end; + newsize:= decimals; + if newsize > 4 then begin + newsize:= 4; + end; + NewType:= ftBCD; + end + else begin + NewType:= ftFloat; + end; + end; + FIELD_TYPE_FLOAT,FIELD_TYPE_DOUBLE: begin + NewType:= ftFloat; + end; + FIELD_TYPE_TIMESTAMP,FIELD_TYPE_DATETIME: begin + NewType:= ftDateTime; + end; + FIELD_TYPE_DATE: begin + NewType:= ftDate; + end; + FIELD_TYPE_TIME: begin + NewType:= ftTime; + end; + FIELD_TYPE_VAR_STRING,FIELD_TYPE_STRING,FIELD_TYPE_ENUM, + FIELD_TYPE_SET: begin + NewType:= ftString; + NewSize:= length; + if charsetinfo.mbmaxlen > 0 then begin + newsize:= newsize div charsetinfo.mbmaxlen; + end; + end; + {$ifdef mysql41} + field_type_blob: begin + newsize:= sizeof(integer); + if charsetnr = 63 then begin //binary + newtype:= ftblob; + end + else begin + newtype:= ftmemo; + end; + end; + {$endif} + else begin + Result:= False; + end; + end; + end; +end; + +procedure tmysqlconnection.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TfieldDefs); +var + C: tmysqlcursor; + I,TF,FC: Integer; + field: PMYSQL_FIELD; + DFT: TFieldType; + DFS: Integer; + precision: integer; + fd: tfielddef; + str1: ansistring; + res1: pmysql_res; + charsetinfo: my_charset_info; +begin + fielddefs.clear; + C:= tmysqlcursor(cursor); + mysql_get_character_set_info(c.fconn,@charsetinfo); + if c.fprepstatement <> nil then begin + fc:= c.fresultfieldcount; + c.fresultbindinginfo:= nil; //initialize with zeros + setlength(c.fresultbindinginfo,fc); + res1:= mysql_stmt_result_metadata(c.fprepstatement); + end + else begin + If (C.FRes=Nil) then begin + checkerror(SErrNoQueryResult,c.fconn); + end; + res1:= c.fres; + FC:= mysql_num_fields(res1); + end; + + SetLength(c.MapDSRowToMSQLRow,FC); + TF := 1; + For I:= 0 to FC-1 do begin + field := mysql_fetch_field_direct(res1, I); + with field^ do begin + if (flags and (pri_key_flag or auto_increment_flag) = + (pri_key_flag or auto_increment_flag)) then begin + c.fprimarykeyfieldname:= name; + end; + end; + if MySQLDataType(field^,charsetinfo,DFT,DFS,precision) then begin + if not(dft in varsizefields) then begin + dfs:= 0; + end; + c.MapDSRowToMSQLRow[TF-1] := I; + if c.fprepstatement <> nil then begin + setupresultbinding(i,dft,dfs,c.fresultbindings,c.fresultbindinginfo); + end; + if (dft = ftmemo) and (cursor.stringmemo) then begin + dft:= ftstring; + dfs:= 0; + end; + str1:= field^.name; + + fd:= TFieldDef.Create(nil,str1,DFT,DFS,False,TF); + fd.collection:= fielddefs; + if dft = ftbcd then begin + fd.precision:= precision; + end; + inc(TF); + end + end; + if (c.fprepstatement <> nil) and (res1 <> nil) then begin + freebindingbuffers(c.fresultbuf); //could be refresh operation + c.fresultbuf:= createbindingbuffers(c.fresultbindings,c.fresultbindinginfo); + mysql_free_result(res1); + if mysql_stmt_bind_result(c.fprepstatement,c.fresultbindings) <> 0 then begin + checkstmterror(sbindresult,c.fprepstatement); + end; + end; +end; + +function tmysqlconnection.Fetch(cursor: TSQLCursor): boolean; + +Var + C : tmysqlcursor; + int1: integer; +begin + C:= tmysqlcursor(cursor); + if c.fprepstatement <> nil then begin + int1:= mysql_stmt_fetch(c.fprepstatement); + result:= int1 <> mysql_no_data; + if result and (int1 <> 0) and (int1 <> mysql_data_truncated) then begin + checkstmterror(serrfetchingdata,c.fprepstatement); + end; + end + else begin + C.Row:=MySQL_Fetch_row(C.FRes); + Result:=(C.Row<>Nil); + end; + if not result then begin + freeresultbuffer(c); + end; +end; + +function tmysqlconnection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const abuffer: pointer; var abufsize: integer; + const aisutf8: boolean): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize + +var + field: PMYSQL_FIELD; + row : MYSQL_ROW; + C : tmysqlcursor; + fno: integer; + alen: integer; + int1: integer; + str1: ansistring; + index1: integer; + + procedure loadblob; + begin + with c.fresultbindinginfo[index1] do begin + setlength(str1,length); + if length > 0 then begin + setbindingbuffer(c.fresultbindings,index1,pointer(str1),length); + int1:= mysql_stmt_fetch_column(c.fprepstatement, + getbind(c.fresultbindings,index1),index1,0); + setbindingbuffer(c.fresultbindings,index1,nil,0); + if int1 <> 0 then begin + checkstmterror(serrfetchingdata,c.fprepstatement); + end; + end; + end; + end; + +begin + str1:= ''; + result:= false; + C:= tmysqlcursor(Cursor); + fno:= fieldnum; + if c.fprepstatement <> nil then begin + index1:= c.MapDSRowToMSQLRow[fno]; + with c.fresultbindinginfo[index1] do begin + result:= not isnull; + if abuffer = nil then begin + exit; //check null state + end; + if result then begin + case datatype of //todo: blobs + ftinteger,ftsmallint,ftword: begin + pinteger(abuffer)^:= pinteger(buffer)^; + end; + ftlargeint: begin + pint64(abuffer)^:= pint64(buffer)^; + end; + ftfloat: begin + pdouble(abuffer)^:= pdouble(buffer)^; + end; + ftbcd: begin + pcurrency(abuffer)^:= pdouble(buffer)^; + end; + ftdate,fttime,ftdatetime: begin + pdatetime(abuffer)^:= mysql_timetodatetime(pmysql_time(buffer)^); + end; + ftstring: begin + if length > abufsize then begin + abufsize:= -length; + end + else begin + if isblob then begin //stringmemo + loadblob; + move(pointer(str1)^,abuffer^,length); + abufsize:= length; + end + else begin + move(buffer^,abuffer^,length); + abufsize:= length; + end; + end; + end; + ftblob,ftgraphic,ftmemo: begin + loadblob; + int1:= cursor.addblobdata(pchar(str1),system.length(str1)); + pinteger(abuffer)^:= int1; //save id + end; + else begin + result:= false; //not suported + end; + end; + end; + end; + end + else begin + if C.Row=nil then + begin + // Writeln('LoadFieldsFromBuffer: row=nil'); + checkerror(SErrFetchingData,c.fconn); + end; + Row:=C.Row; + + inc(Row,c.MapDSRowToMSQLRow[fno]); +// inc(row,fno); + if row^ <> nil then begin + if abuffer = nil then begin + result:= true; + exit; + end; + field:= mysql_fetch_field_direct(C.FRES,c.MapDSRowToMSQLRow[fno]); + if datatype = ftstring then begin + // alen:= strlen(row^); +{$ifdef FPC} + alen:= mysql_fetch_lengths(c.fres)[c.MapDSRowToMSQLRow[fno]]; +{$else} + alen:= pculongaty(mysql_fetch_lengths(c.fres))^[c.MapDSRowToMSQLRow[fno]]; +{$endif} + if abufsize < alen then begin + abufsize:= -alen; + result:= true; + exit; + end + else begin + abufsize:= alen; + end; + end + else begin + if datatype in [ftmemo,ftgraphic,ftblob] then begin +{$ifdef FPC} + alen:= mysql_fetch_lengths(c.fres)[c.MapDSRowToMSQLRow[fno]]; +{$else} + alen:= pculongaty(mysql_fetch_lengths(c.fres))^[c.MapDSRowToMSQLRow[fno]]; +{$endif} + end + else begin + alen:= field^.length; + end; + end; + Result:= MySQLWriteData(cursor, field^.ftype,alen, + DataType,Row^,aBuffer); + end; + end; +end; + +function tmysqlconnection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +var + int1: integer; + row1: MYSQL_ROW; +begin + result:= ''; + with tmysqlcursor(cursor) do begin + if row <> nil then begin + int1:= MapDSRowToMSQLRow[fieldnum]; + row1:= row; + inc(row1,int1); +{$ifdef FPC} + setlength(result,mysql_fetch_lengths(fres)[int1]); +{$else} + setlength(result,pculongaty(mysql_fetch_lengths(fres))^[int1]); +{$endif} + if result <> '' then begin + move(row1^^,result[1],length(result)); + end; + end; + end; +end; + +function InternalStrToFloat(S: string): Extended; + +var + I: Integer; + Tmp: string; + +begin + Tmp := ''; + for I := 1 to Length(S) do + begin + if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then + Tmp := Tmp + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator + else + Tmp := Tmp + S[I]; + end; + Result := StrToFloat(Tmp); +end; + +function InternalStrToCurrency(S: string): Extended; + +var + I: Integer; + Tmp: string; + +begin + Tmp := ''; + for I := 1 to Length(S) do + begin + if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then + Tmp := Tmp + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator + else + Tmp := Tmp + S[I]; + end; + Result := StrToCurr(Tmp); +end; + +function InternalStrToDate(S: string): TDateTime; + +var + EY, EM, ED: Word; + +begin + EY := StrToInt(Copy(S,1,4)); + EM := StrToInt(Copy(S,6,2)); + ED := StrToInt(Copy(S,9,2)); + if (EY = 0) or (EM = 0) or (ED = 0) then + Result:=0 + else + Result:=EncodeDate(EY, EM, ED); +end; + +function InternalStrToDateTime(S: string): TDateTime; + +var + EY, EM, ED: Word; + EH, EN, ES: Word; + +begin + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 6, 2)); + ED := StrToInt(Copy(S, 9, 2)); + EH := StrToInt(Copy(S, 12, 2)); + EN := StrToInt(Copy(S, 15, 2)); + ES := StrToInt(Copy(S, 18, 2)); + if (EY = 0) or (EM = 0) or (ED = 0) then + Result := 0 + else + Result := EncodeDate(EY, EM, ED); + Result := Result + EncodeTime(EH, EN, ES, 0); +end; + +function InternalStrToTime(S: string): TDateTime; + +var + EH, EM, ES: Word; + +begin + EH := StrToInt(Copy(S, 1, 2)); + EM := StrToInt(Copy(S, 4, 2)); + ES := StrToInt(Copy(S, 7, 2)); + Result := EncodeTime(EH, EM, ES, 0); +end; + +function InternalStrToTimeStamp(S: string): TDateTime; + +var + EY, EM, ED: Word; + EH, EN, ES: Word; + +begin +{$IFNDEF mysql40} + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 6, 2)); + ED := StrToInt(Copy(S, 9, 2)); + EH := StrToInt(Copy(S, 12, 2)); + EN := StrToInt(Copy(S, 15, 2)); + ES := StrToInt(Copy(S, 18, 2)); +{$ELSE} + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 5, 2)); + ED := StrToInt(Copy(S, 7, 2)); + EH := StrToInt(Copy(S, 9, 2)); + EN := StrToInt(Copy(S, 11, 2)); + ES := StrToInt(Copy(S, 13, 2)); +{$ENDIF} + if (EY = 0) or (EM = 0) or (ED = 0) then + Result := 0 + else + Result := EncodeDate(EY, EM, ED); + Result := Result + EncodeTime(EH, EN, ES, 0);; +end; + +function tmysqlconnection.MySQLWriteData(const acursor: tsqlcursor; + AType: enum_field_types;ASize: Integer; + AFieldType: TFieldType;Source, Dest: PChar): Boolean; + +var + VI: Integer; + VL: largeint; + VF: Double; + VC: Currency; + VD: TDateTime; + Src : String; + int1: integer; +begin + Result:= False; + if Source = Nil then begin + exit; + end; + Result:= True; + case afieldtype of + ftstring: begin + Move(Source^, Dest^, ASize) + end; + ftblob,ftmemo: begin + int1:= acursor.addblobdata(source,asize); + move(int1,dest^,sizeof(int1)); + //save id + end; + else begin + Src:=StrPas(Source); + case AType of + FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_LONG, + FIELD_TYPE_INT24: + begin + if (Src<>'') then + VI := StrToInt(Src) + else + VI := 0; + Move(VI, Dest^, SizeOf(Integer)); + end; + FIELD_TYPE_LONGLONG: + begin + if (Src<>'') then + VL := StrToInt64(Src) + else + VL := 0; + Move(VL, Dest^, SizeOf(LargeInt)); + end; +{$ifdef mysql50} + FIELD_TYPE_NEWDECIMAL, +{$endif} + FIELD_TYPE_DECIMAL, FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE: + if AFieldType = ftBCD then + begin + VC := InternalStrToCurrency(Src); + Move(VC, Dest^, SizeOf(Currency)); + end + else + begin + if Src <> '' then + VF := InternalStrToFloat(Src) + else + VF := 0; + Move(VF, Dest^, SizeOf(Double)); + end; + FIELD_TYPE_TIMESTAMP: + begin + if Src <> '' then + VD := InternalStrToTimeStamp(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_DATETIME: + begin + if Src <> '' then + VD := InternalStrToDateTime(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_DATE: + begin + if Src <> '' then + VD := InternalStrToDate(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_TIME: + begin + if Src <> '' then + VD := InternalStrToTime(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING, FIELD_TYPE_ENUM, FIELD_TYPE_SET: + begin +// if Src<> '' then + Move(Source^, Dest^, ASize) +// else +// Dest^ := #0; + end; + field_type_blob: begin + int1:= acursor.addblobdata(source,asize); + move(int1,dest^,sizeof(int1)); + //save id + end; + end; + end; + end; +end; + +procedure tmysqlconnection.UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); +var + qry: tsqlresult; + keynamef,{filednamef,}columnnamef,nonuniquef: tdbcol; + str1: string; +begin + if not assigned(Transaction) then begin + DatabaseError(SErrConnTransactionnSet); + end; + qry:= tsqlresult.Create(nil); + try + with qry do begin + database:= Self; + sql.text:= 'show index from ' + msestring(aTableName); + active:= true; + keynamef:= datacols.colbyname('Key_name'); + columnnamef:= datacols.colbyname('Column_name'); + nonuniquef:= datacols.colbyname('Non_unique'); + while not eof do begin + with IndexDefs.AddIndexDef do begin + Name:= trim(keynamef.asstring); + if Name = 'PRIMARY' then begin + options:= options + [ixPrimary]; + end; + if nonuniquef.asinteger = 0 then begin + options:= options + [ixUnique]; + end; + str1:= ''; + repeat + str1:= str1 + trim(columnnamef.asstring) + ';'; + qry.next; + until qry.eof or (name <> keynamef.asstring); + setlength(str1,length(str1)-1); //remove last ';' + fields:= str1; + end; + end; + end; + finally + qry.free; + end; +end; + +function tmysqlconnection.GetTransactionHandle(trans: TSQLHandle): pointer; +begin + Result:= trans; +end; + +procedure tmysqlconnection.begintrans(const aconnection: pmysql; + const aparams: ansistring); +var + str1: ansistring; +begin + str1:= 'START TRANSACTION '+aparams; + if mysql_real_query(aconnection,pointer(str1),length(str1)) <> 0 then begin + checkerror(serrstarttransaction,aconnection); + end; +end; + +function tmysqlconnection.Commit(trans: TSQLHandle): boolean; +begin + with tmysqltrans(trans) do begin + if mysql_query(fconn,'COMMIT') <> 0 then begin + checkerror(serrcommittransaction,fconn); + end; + end; + result:= true; +end; + +function tmysqlconnection.RollBack(trans: TSQLHandle): boolean; +begin + with tmysqltrans(trans) do begin + if mysql_query(fconn,'ROLLBACK') <> 0 then begin + checkerror(serrrollbacktransaction,fconn); + end; + end; + result:= true; +end; + +procedure tmysqlconnection.internalCommitRetaining(trans: TSQLHandle); +begin + with tmysqltrans(trans) do begin + if mysql_query(fconn,'COMMIT AND CHAIN') <> 0 then begin + checkerror(serrcommittransaction,fconn); + end; + end; +end; + +procedure tmysqlconnection.internalRollBackRetaining(trans: TSQLHandle); +begin + with tmysqltrans(trans) do begin + if mysql_query(fconn,'ROLLBACK AND CHAIN') <> 0 then begin + checkerror(serrrollbacktransaction,fconn); + end; + end; +end; + +function tmysqlconnection.StartdbTransaction(const trans: TSQLHandle; + const AParams: tstringlist): boolean; +begin + with tmysqltrans(trans) do begin + if fconn = nil then begin + if not ftransactionconnectionused then begin + fconn:= self.fmysql1; + ftransactionconnectionused:= true; + end + else begin + openconnection(fconn); + end; + end; + begintrans(fconn,aparams.text); + end; + result:= true; +end; + +function tmysqlconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +var + blobid: integer; +// int1,int2: integer; +// str1: string; +// bo1: boolean; +begin + result:= nil; + if mode = bmread then begin + if field.getData(@blobId) then begin + result:= acursor.getcachedblob(blobid); + end; + end; +end; + +function tmysqlconnection.getblobdatasize: integer; +begin + result:= sizeof(integer); +end; +{ +function tmysqlconnection.getfeatures(): databasefeaturesty; +begin + result:= inherited getfeatures() + [dbf_blobscached]; +end; +} +procedure tmysqlconnection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); +var + str1: string; + int1: integer; +begin + setlength(str1,alength); + move(adata^,str1[1],alength); + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + int1:= acursor.addblobdata(str1); + setlength(newid,sizeof(int1)); + move(int1,newid[1],sizeof(int1)); +end; + +procedure tmysqlconnection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +begin + acursor.blobfieldtoparam(afield,aparam,false); +end; +{ +function tmysqlconnection.blobscached: boolean; +begin + result:= true; +end; +} +function tmysqlconnection.getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; +begin + result:= tmysqlcursor(acursor).fprimarykeyfieldname; +end; + +function tmysqlconnection.getinsertid(const atransaction: tsqltransaction): int64; +begin + result:= mysql_insert_id(tmysqltrans(atransaction.trans).fconn); +end; + +procedure tmysqlconnection.updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); +begin + if afield.datatype in integerfields then begin + afield.aslargeint:= getinsertid(atransaction); + end; + { + with tmsebufdataset1(afield.dataset) do begin + setcurvalue(afield,getinsertid); + end; + } +end; + +function tmysqlconnection.identquotechar: msestring; +begin + result:= '`'; //needed for reserved words as fieldnames +end; + +procedure tmysqlconnection.createdatabase(const asql: ansistring); +var + bo1: boolean; + po1: pmysql_res; +begin + initializemysql([]); + try + bo1:= fmysql1 = nil; + if bo1 then begin + ConnectMySQL(fmysql1,pchar(hostname),pchar(username),pchar(password)); + end; + try + if mysql_real_query(fmysql1,pointer(asql),length(asql)) <> 0 then begin + checkerror(serrstarttransaction,fmysql1); + end; + po1:= mysql_store_result(fmysql1); + if po1 <> nil then begin + mysql_free_result(po1); + end; + finally + if bo1 then begin + closeconnection(fmysql1); + end; + end; + finally + releasemysql; + end; +end; + +{ emysqlerror } + +constructor emysqlerror.create(const asender: tcustomsqlconnection; + const amessage: ansistring; const aerrormessage: msestring; + const aerror: integer; const asqlcode: string); +begin + fsqlcode:= asqlcode; + inherited create(asender,amessage,aerrormessage,aerror); +end; + +end. diff --git a/mseide-msegui/lib/common/db/modbcconn.pas b/mseide-msegui/lib/common/db/modbcconn.pas new file mode 100644 index 0000000..3e2e89c --- /dev/null +++ b/mseide-msegui/lib/common/db/modbcconn.pas @@ -0,0 +1,1818 @@ +{****************************************************************************** + * * + * (c) 2005 Hexis BV * + * * + * File: odbcconn.pas * + * Author: Bram Kuijvenhoven (bkuijvenhoven@eljakim.nl) * + * Description: ODBC SQLDB unit * + * License: (modified) LGPL * + * * + * Modified 2006-2013 by Martin Schreiber * + ******************************************************************************} + +unit modbcconn; + +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +interface + +uses + classes,mclasses,SysUtils, msqldb, mdb, odbcsqldyn,msetypes,msedb,msestrings; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + + // forward declarations + TODBCConnection = class; + + { TODBCCursor } + + TODBCCursor = class(TSQLCursor) + protected + fconnection: todbcconnection; + ffieldnames: stringarty; + FSTMTHandle:SQLHSTMT; // ODBC Statement Handle + FQuery:string; // last prepared query, with :ParamName converted to ? + FParamIndex:TParamBinding; // maps the i-th parameter in the query to the TParams passed to PrepareStatement + FParamBuf:array of pointer; // buffers that can be used to bind the i-th parameter in the query +// FBlobStreams:TList; // list of Blob TMemoryStreams stored in field buffers (we need this currently as we can't hook into the freeing of TBufDataset buffers) + fcurrentblobbuffer: ansistring; + public + constructor Create(const aowner: icursorclient; const aname: ansistring; + const Connection:TODBCConnection); + destructor Destroy; override; + procedure close; override; + end; + + { TODBCHandle } // this name is a bit confusing, but follows the standards for naming classes in sqldb + + TODBCHandle = class(TSQLHandle) + protected + end; + + { TODBCEnvironment } + + TODBCEnvironment = class + private + finitialized: boolean; + protected + FENVHandle:SQLHENV; // ODBC Environment Handle + public + constructor Create; + destructor Destroy; override; + end; + + { TODBCConnection } + + TODBCConnection = class(TSQLConnection,iblobconnection) + private + FDriver: string; + FEnvironment:TODBCEnvironment; + FDBCHandle:SQLHDBC; // ODBC Connection Handle + FFileDSN: string; + + procedure SetParameters(ODBCCursor:TODBCCursor; AParams:TmseParams); + procedure FreeParamBuffers(ODBCCursor:TODBCCursor); + protected + procedure ODBCCheckResult( + LastReturnCode:SQLRETURN; HandleType:SQLSMALLINT; + AHandle: SQLHANDLE; ErrorMsg: string); overload; + + procedure ODBCCheckResult( + LastReturnCode:SQLRETURN; HandleType:SQLSMALLINT; + AHandle: SQLHANDLE; ErrorMsg: string; + const values: array of const); overload; + // Overrides from TSQLConnection + function GetHandle:pointer; override; + // - Connect/disconnect + procedure DoInternalConnect; override; + procedure DoInternalDisconnect; override; + // - Handle (de)allocation + function AllocateTransactionHandle:TSQLHandle; override; + // - Statement handling + + // - Transaction handling + function GetTransactionHandle(trans:TSQLHandle):pointer; override; + function StartDBTransaction(const trans:TSQLHandle; + const AParams: tstringlist):boolean; override; + function Commit(trans:TSQLHandle):boolean; override; + function Rollback(trans:TSQLHandle):boolean; override; + procedure internalCommitRetaining(trans:TSQLHandle); override; + procedure internalRollbackRetaining(trans:TSQLHandle); override; + // - Statement execution + procedure updaterowcount(const acursor: todbccursor); + procedure internalExecute(const cursor:TSQLCursor; + const ATransaction:TSQLTransaction; const AParams:TmseParams; + const autf8: boolean); override; + procedure internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); override; + + + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + // - UpdateIndexDefs + procedure UpdateIndexDefs(var IndexDefs:TIndexDefs; + const aTableName:string; const acursor: tsqlcursor); override; + // - Schema info + function GetSchemaInfoSQL(SchemaType:TSchemaType; + SchemaObjectName, SchemaObjectPattern:msestring):msestring; override; + + // Internal utility functions + function CreateConnectionString:string; + function getblobdatasize: integer; override; +// function getfeatures(): databasefeaturesty override; + + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); +// function blobscached: boolean; + public + constructor create(aowner: tcomponent); override; + function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; override; + procedure DeAllocateCursorHandle(var cursor:TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + procedure UnPrepareStatement(cursor:TSQLCursor); override; + // - Result retrieving + procedure AddFieldDefs(const cursor:TSQLCursor; + const FieldDefs:TFieldDefs); override; + function Fetch(cursor:TSQLCursor):boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + procedure FreeFldBuffers(cursor:TSQLCursor); override; + property Environment:TODBCEnvironment read FEnvironment; + published + property Driver:string read FDriver write FDriver; // will be passed as DRIVER connection parameter + property FileDSN:string read FFileDSN write FFileDSN; // will be passed as FILEDSN parameter + // Redeclare properties from TSQLConnection + property Password; // will be passed as PWD connection parameter + property Transaction; + property UserName; // will be passed as UID connection parameter + property CharSet; + property HostName; // ignored + // Redeclare properties from TmDatabase + property Connected; + property Role; + property DatabaseName; // will be passed as DSN connection parameter + property KeepConnection; +// property LoginPrompt; // if true, ODBC drivers might prompt for more details that are not in the connection string + property Params; // will be added to connection string +// property OnLogin; + property ongetcredentials; + end; + + EODBCException = class(Exception) + // currently empty; perhaps we can add fields here later that describe the error instead of one simple message string + end; + +implementation +uses + Math, {$ifdef FPC}DBConst{$else}dbconst_del{$endif},msedatabase; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$define ODBCVER3} + +(* odbc type nums +internal enum SQL_TYPE : short + { + BIGINT = (-5), + BINARY = (-2), + BIT = (-7), + CHAR = 1, + DATE = 9, + DECIMAL = 3, + DOUBLE = 8, + GUID = (-11), + INTEGER = 4, + INTERVAL_DAY = (100 + 3), + INTERVAL_DAY_TO_HOUR = (100 + 8), + INTERVAL_DAY_TO_MINUTE = (100 + 9), + INTERVAL_DAY_TO_SECOND = (100 + 10), + INTERVAL_HOUR = (100 + 4), + INTERVAL_HOUR_TO_MINUTE = (100 + 11), + INTERVAL_HOUR_TO_SECOND = (100 + 12), + INTERVAL_MINUTE = (100 + 5), + INTERVAL_MINUTE_TO_SECOND = (100 + 13), + INTERVAL_MONTH = (100 + 2), + INTERVAL_SECOND = (100 + 6), + INTERVAL_YEAR = (100 + 1), + INTERVAL_YEAR_TO_MONTH = (100 + 7), + LONGVARBINARY = (-4), + LONGVARCHAR = (-1), + NUMERIC = 2, + REAL = 7, + SMALLINT = 5, + TIME = 10, + TIMESTAMP = 11, + TINYINT = (-6), + TYPE_DATE = 91, + TYPE_TIME = 92, + TYPE_TIMESTAMP = 93, + VARBINARY = (-3), + VARCHAR = 12, + WCHAR = (-8), + WLONGVARCHAR = (-10), + WVARCHAR = (-9), + UNASSIGNED = Int16.MaxValue + } + + internal enum SQL_C_TYPE : short + { + BINARY = (-2), + BIT = (-7), + BOOKMARK = (4 +(-22)), + CHAR = 1, + DATE = 9, + DEFAULT = 99, + DOUBLE = 8, + FLOAT = 7, + GUID = (-11), + INTERVAL_DAY = (100 + 3), + INTERVAL_DAY_TO_HOUR = (100 + 8), + INTERVAL_DAY_TO_MINUTE = (100 + 9), + INTERVAL_DAY_TO_SECOND = (100 + 10), + INTERVAL_HOUR = (100 + 4), + INTERVAL_HOUR_TO_MINUTE = (100 + 11), + INTERVAL_HOUR_TO_SECOND = (100 + 12), + INTERVAL_MINUTE = (100 + 5), + INTERVAL_MINUTE_TO_SECOND = (100 + 13), + INTERVAL_MONTH = (100 + 2), + INTERVAL_SECOND = (100 + 6), + INTERVAL_YEAR = (100 + 1), + INTERVAL_YEAR_TO_MONTH = (100 + 7), + LONG = 4, + NUMERIC = 2, + SBIGINT = ((-5)+(-20)), + SHORT = 5, + SLONG = (4 +(-20)), + SSHORT = (5 +(-20)), + STINYINT = ((-6)+(-20)), + TCHAR = 1, + TIME = 10, + TIMESTAMP = 11, + TINYINT = (-6), + TYPE_DATE = 91, + TYPE_TIME = 92, + TYPE_TIMESTAMP = 93, + UBIGINT = ((-5)+(-22)), + ULONG = (4 +(-22)), + USHORT = (5 +(-22)), + UTINYINT = ((-6)+(-22)), + WCHAR = (-8), + UNASSIGNED = Int16.MaxValue + } +} +*) + +const + +{$ifdef ODBCVER3} + SQL_C_WCHAR = SQL_WCHAR; +{$endif} + + blobidsize = sizeof(integer); + maxstrlen = 3000; + maxprecision = 18; +var + DefaultEnvironment:TODBCEnvironment = nil; +// ODBCLoadCount:integer = 0; // ODBC is loaded when > 0; modified by TODBCEnvironment.Create/Destroy + +{ Generic ODBC helper functions } + +function ODBCSucces(const Res:SQLRETURN):boolean; +begin + Result:=(Res=SQL_SUCCESS) or (Res=SQL_SUCCESS_WITH_INFO) or + (res = SQL_NO_DATA); +end; + +function ODBCResultToStr(Res:SQLRETURN):string; +begin + case Res of + SQL_SUCCESS: Result:='SQL_SUCCESS'; + SQL_SUCCESS_WITH_INFO:Result:='SQL_SUCCESS_WITH_INFO'; + SQL_ERROR: Result:='SQL_ERROR'; + SQL_INVALID_HANDLE: Result:='SQL_INVALID_HANDLE'; + SQL_NO_DATA: Result:='SQL_NO_DATA'; + SQL_NEED_DATA: Result:='SQL_NEED_DATA'; + SQL_STILL_EXECUTING: Result:='SQL_STILL_EXECUTING'; + else + Result:=''; + end; +end; + +{ todbcconnection } + +constructor TODBCConnection.create(aowner: tcomponent); +begin + inherited; + fconnoptions:= fconnoptions + [sco_supportparams,sco_emulateretaining, + sco_blobscached]; +end; + +procedure todbcconnection.ODBCCheckResult( + LastReturnCode:SQLRETURN; HandleType:SQLSMALLINT; + AHandle: SQLHANDLE; ErrorMsg: string); + + // check return value from SQLGetDiagField/Rec function itself + procedure Check(const Res:SQLRETURN); + begin + case Res of + SQL_INVALID_HANDLE: + raise EODBCException.Create('Invalid handle passed to SQLGetDiagRec/Field'); + SQL_ERROR: + raise EODBCException.Create('An invalid parameter was passed to SQLGetDiagRec/Field'); + SQL_NO_DATA: + raise EODBCException.Create('A too large RecNumber was passed to SQLGetDiagRec/Field'); + end; + end; + +var + NativeError: SQLINTEGER; + reccount: sqlinteger; + TextLength:SQLSMALLINT; + Res:SQLRETURN; + SqlState,MessageText,TotalMessage:string; + RecNumber:SQLSMALLINT; + firstmessage: string; + firsterror: integer; +begin + // check result + if ODBCSucces(LastReturnCode) then begin + Exit; // no error; all is ok + end; + + firstmessage:= ''; + // build TotalMessage for exception to throw + TotalMessage:=Format('%s ODBC error details:',[ErrorMsg]); + // retrieve status records + check(sqlgetdiagfield(handletype,ahandle,0,SQL_DIAG_NUMBER,@reccount, + sizeof(reccount),textlength)); + //unixODBC crashes with too big rec number + + SetLength(SqlState,5); // SqlState buffer + firsterror:= 0; + for RecNumber:=1 to reccount do begin + // dummy call to get correct TextLength + Res:=SQLGetDiagRec(HandleType,AHandle,RecNumber,@(SqlState[1]), + NativeError,nil,0,TextLength); + if Res=SQL_NO_DATA then begin + Break; // no more status records + end; + Check(Res); + if TextLength>0 then begin + // if TextLength=0 we don't need another call; + // also our string buffer would not point to a #0, but be a nil pointer + // allocate large enough buffer + SetLength(MessageText,4*TextLength); + //reserve for multi-byte-encodings, ODBC bug? + // note: ansistrings of Length>0 are always terminated by a #0 character, so this is safe + // actual call + check(SQLGetDiagRec(HandleType,AHandle,RecNumber,@(SqlState[1]), + NativeError,@(MessageText[1]),Length(MessageText)+1,TextLength)); + end + else begin + messagetext:= ''; + end; + if firsterror = 0 then begin + firsterror:= nativeerror; + firstmessage:= strpas(pchar(messagetext)); + end; + // add to TotalMessage + TotalMessage:=TotalMessage + + Format(' Record %d: SqlState: %s; NativeError: %d; Message: %s;', + [RecNumber,SqlState,NativeError, + strpas(pchar(MessageText))]); + //string termination by #0, textlength seems to be unreliable + end; + // raise error +// raise EODBCException.Create(TotalMessage); + raise econnectionerror.create(self, + ansistring(connectionmessage(pchar(totalmessage))), + msestring(firstmessage),firsterror); +end; + +procedure todbcconnection.ODBCCheckResult( + LastReturnCode:SQLRETURN; HandleType:SQLSMALLINT; + AHandle: SQLHANDLE; ErrorMsg: string; + const values: array of const); +begin + if not ODBCSucces(LastReturnCode) then begin + odbccheckresult(lastreturncode,handletype,ahandle,format(errormsg,values)); + end; +end; + + +// Creates a connection string using the current value of the fields +function TODBCConnection.CreateConnectionString: string; + + // encloses a param value with braces if necessary, i.e. when any of the characters []{}(),;?*=!@ is in the value + function EscapeParamValue(const s:string):string; + var + NeedEscape:boolean; + i:integer; + begin + NeedEscape:=false; + for i:=1 to Length(s) do + if s[i] in ['[',']','{','}','(',')',',','*','=','!','@'] then + begin + NeedEscape:=true; + Break; + end; + if NeedEscape then + Result:='{'+s+'}' + else + Result:=s; + end; + +var + i: Integer; + Param: string; + EqualSignPos:integer; + u,p: msestring; + u1,p1: string; +begin + Result:=''; + getcredentials(u,p); + if charset <> '' then begin + result:= result + 'CHARSET='+ ansistring(charset)+';'; + end; + if DatabaseName<>'' then Result:=Result + 'DSN='+ + EscapeParamValue(ansistring(DatabaseName))+';'; + if Driver <>'' then Result:=Result + 'DRIVER='+EscapeParamValue(Driver)+';'; + if U <>'' then begin + u1:= ansistring(u); + p1:= ansistring(p); + Result:=Result + 'UID='+EscapeParamValue(U1)+';PWD='+ + EscapeParamValue(P1)+';'; + stringsafefree(u1,false); + stringsafefree(p1,false); + end; + freecredentials(u,p); + if FileDSN <>'' then Result:=Result + 'FILEDSN='+EscapeParamValue(FileDSN)+''; + for i:=0 to Params.Count-1 do + begin + Param:=Params[i]; + EqualSignPos:=Pos('=',Param); + if EqualSignPos=0 then + raise EODBCException.CreateFmt('Invalid parameter in Params[%d]; can''t find a ''='' in ''%s''',[i, Param]) + else if EqualSignPos=1 then + raise EODBCException.CreateFmt('Invalid parameter in Params[%d]; no identifier before the ''='' in ''%s''',[i, Param]) + else + Result:=Result + EscapeParamValue(Copy(Param,1,EqualSignPos-1))+'='+EscapeParamValue(Copy(Param,EqualSignPos+1,MaxInt))+';'; + end; +end; + +procedure TODBCConnection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); +var + str1: string; + int1: integer; +begin + setlength(str1,alength); + move(adata^,str1[1],alength); + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + int1:= acursor.addblobdata(str1); + setlength(newid,sizeof(int1)); + move(int1,newid[1],sizeof(int1)); +end; + +procedure TODBCConnection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +begin +// acursor.blobfieldtoparam(afield,aparam,afield.datatype = ftmemo); + acursor.blobfieldtoparam(afield,aparam,false); +end; + +function TODBCConnection.getblobdatasize: integer; +begin + result:= sizeof(integer); +end; +{ +function TODBCConnection.getfeatures(): databasefeaturesty; +begin + result:= inherited getfeatures() + [dbf_blobscached]; +end; +} +{ +function TODBCConnection.blobscached: boolean; +begin + result:= true; +end; +} +procedure TODBCConnection.SetParameters(ODBCCursor: TODBCCursor; AParams: TmseParams); + + procedure bindnum(i: integer; valuetype: SQLSMALLINT; parametertype: SQLSMALLINT; + buf: pointer); + begin + ODBCCursor.FParamBuf[i]:=Buf; + ODBCCheckResult( + SQLBindParameter(ODBCCursor.FSTMTHandle, // StatementHandle + i+1, // ParameterNumber + SQL_PARAM_INPUT, // InputOutputType + valuetype, // ValueType + parametertype, // ParameterType + 1, // ColumnSize + 0, // DecimalDigits + Buf, // ParameterValuePtr + 0, // BufferLength + nil), // StrLen_or_IndPtr + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not bind parameter %d',[i] + ); + end; + + procedure bindstr(i: integer; valuetype: SQLSMALLINT; parametertype: SQLSMALLINT; + buf: pointer; strlen: sqlinteger; buflen: sqlinteger + ); + begin + psqlinteger(buf)^:= buflen; + ODBCCursor.FParamBuf[i]:=Buf; + ODBCCheckResult( + SQLBindParameter(ODBCCursor.FSTMTHandle, // StatementHandle + i+1, // ParameterNumber + SQL_PARAM_INPUT, // InputOutputType + valuetype, // ValueType + parametertype, // ParameterType + strlen, // ColumnSize + 0, // DecimalDigits + pchar(buf)+SizeOf(SQLINTEGER), // ParameterValuePtr + buflen, // BufferLength + buf), // StrLen_or_IndPtr + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not bind parameter %d',[i]); + end; + + procedure bindnull(i: integer; valuetype: sqlsmallint; parametertype: sqlsmallint); + var + buf: psqllen; + begin + getmem(buf,sizeof(sqllen)); + ODBCCursor.FParamBuf[i]:= Buf; + buf^:= SQL_NULL_DATA; + ODBCCheckResult( + SQLBindParameter(ODBCCursor.FSTMTHandle, // StatementHandle + i+1, // ParameterNumber + SQL_PARAM_INPUT, // InputOutputType + valuetype, // ValueType + parametertype, // ParameterType + 1, // ColumnSize + 0, // DecimalDigits + nil, // ParameterValuePtr + 0, // BufferLength + buf), // StrLen_or_IndPtr + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not bind parameter %d',[i]); + end; + +var + ParamIndex:integer; + Buf:pointer; + I:integer; +// IntVal:longint; +// largeintval: int64; + StrVal:string; +{$ifdef mswindows} + wideStrVal: msestring; + buflen: SQLINTEGER; +{$endif} +// doubleval: double; + StrLen{,buflen}: SQLINTEGER; +// isnull1: boolean; + datatype1: tfieldtype; + +begin + // Note: it is assumed that AParams is the same as the one passed to PrepareStatement, in the sense that + // the parameters have the same order and names + + if Length(ODBCCursor.FParamIndex)>0 then begin + if not Assigned(AParams) then begin + raise EODBCException.CreateFmt( + 'The query has parameter markers in it, but no actual parameters were passed', + []); + end; + end; + SetLength(ODBCCursor.FParamBuf, Length(ODBCCursor.FParamIndex)); + for i:=0 to High(ODBCCursor.FParamIndex) do begin + ParamIndex:= ODBCCursor.FParamIndex[i]; + if (ParamIndex<0) or (ParamIndex>=AParams.Count) then begin + raise EODBCException.CreateFmt( + 'Parameter %d in query does not have a matching parameter set',[i]); + end; + with AParams[ParamIndex] do begin +// isnull1:= isnull; + datatype1:= datatype; + case datatype1 of + ftInteger,ftboolean,ftword,ftsmallint: begin + if isnull then begin + bindnull(i,SQL_C_LONG,SQL_INTEGER); + end + else begin + GetMem(buf,sizeof(longint)); + plongint(buf)^:= AsInteger; + bindnum(i,SQL_C_LONG,SQL_INTEGER,buf); + end; + end; + ftlargeint: begin + if isnull then begin + bindnull(i,SQL_C_SBIGINT,SQL_BIGINT); + end + else begin + GetMem(buf,sizeof(int64)); + pint64(buf)^:= Aslargeint; + bindnum(i,SQL_C_SBIGINT,SQL_BIGINT,buf); + end; + end; + ftfloat,ftcurrency,ftbcd: begin + if isnull then begin + bindnull(i,SQL_C_CHAR,SQL_CHAR); + end + else begin + GetMem(buf,sizeof(double)); + pdouble(buf)^:= Asfloat; + bindnum(i,SQL_C_DOUBLE,SQL_DOUBLE,buf); + end; + end; + fttime,ftdate,ftdatetime: begin + if isnull then begin + bindnull(i,SQL_C_TYPE_TIMESTAMP,SQL_TYPE_TIMESTAMP); + end + else begin + GetMem(buf,sizeof(sql_timestamp_struct)); + datetime2timestampstruct(psql_timestamp_struct(buf)^,Asdatetime); + bindnum(i,SQL_C_TYPE_TIMESTAMP,SQL_TYPE_TIMESTAMP,buf); + end; + end; + ftguid: begin + if isnull then begin + bindnull(i,SQL_C_GUID,SQL_GUID); + end + else begin + GetMem(buf,sizeof(tguid)); + pguid(buf)^:= dbstringtoguid(asstring); + bindnum(i,SQL_C_guid,SQL_guid,buf); + end; + end; + ftblob,ftmemo: begin + if isnull then begin + bindnull(i,SQL_C_CHAR,SQL_CHAR); + end + else begin + StrVal:= asstring; + StrLen:= Length(StrVal); + GetMem(buf,StrLen+sizeof(sqlinteger)); + Move(StrVal[1],(pchar(buf)+sizeof(sqlinteger))^,StrLen); + if datatype1 = ftmemo then begin + bindstr(i,SQL_C_CHAR,SQL_LONGVARCHAR,buf,strlen,strlen) + end + else begin + bindstr(i,SQL_C_BINARY,SQL_LONGVARBINARY,buf,strlen,strlen) + end; + end; + end; + ftstring,ftfixedchar + {$ifndef mswindows},ftwidestring,ftfixedwidechar{$endif}: begin + if isnull then begin + bindnull(i,SQL_C_CHAR,SQL_CHAR); + end + else begin + StrVal:= AParams.AsdbString(paramindex); + StrLen:= Length(StrVal); + GetMem(buf,StrLen+sizeof(sqlinteger)); + Move(StrVal[1],(pchar(buf)+sizeof(sqlinteger))^,StrLen); + if strlen > maxstrlen then begin + bindstr(i,SQL_C_CHAR,SQL_LONGVARCHAR,buf,strlen,strlen) + end + else begin + bindstr(i,SQL_C_CHAR,SQL_CHAR,buf,strlen,strlen) + end; + end; + end; + ftbytes,ftvarbytes: begin + if isnull then begin + bindnull(i,SQL_C_BINARY,SQL_VARBINARY); + end + else begin + StrVal:= AParams[paramindex].AsString; + StrLen:= Length(StrVal); + GetMem(buf,StrLen+sizeof(sqlinteger)); + Move(StrVal[1],(pchar(buf)+sizeof(sqlinteger))^,StrLen); + if strlen > maxstrlen then begin + bindstr(i,SQL_C_BINARY,SQL_LONGVARBINARY,buf,strlen,strlen) + end + else begin + bindstr(i,SQL_C_BINARY,SQL_VARBINARY,buf,strlen,strlen) + end; + end; + end; + {$ifdef mswindows} + ftwidestring,ftfixedwidechar: begin + if isnull then begin + bindnull(i,SQL_C_WCHAR,SQL_WCHAR); + end + else begin + widestrval:= aparams[paramindex].aswidestring; + strlen:= length(widestrval); + buflen:= strlen*sizeof(msechar); + getmem(buf,buflen+sizeof(sqlinteger)); + move(widestrval[1],(pchar(buf)+sizeof(sqlinteger))^,buflen); + if strlen > maxstrlen then begin + bindstr(i,SQL_C_WCHAR,SQL_WLONGVARCHAR,buf,strlen,buflen); + end + else begin + bindstr(i,SQL_C_WCHAR,SQL_WCHAR,buf,strlen,buflen); + end; + // bindstr(i,SQL_C_WCHAR,SQL_WCHAR,buf,buflen,buflen); + end; + end; + {$endif} + else begin + if isnull then begin + bindnull(i,SQL_C_CHAR,SQL_CHAR); //dummy + end + else begin + raise EDataBaseError.CreateFmt( + 'Parameter %d is of type %s, which not supported yet', + [ParamIndex, Fieldtypenames[AParams[ParamIndex].DataType]]); + end; + end; + end; + end; + end; +end; + +procedure TODBCConnection.FreeParamBuffers(ODBCCursor: TODBCCursor); +var + i:integer; +begin + for i:=0 to High(ODBCCursor.FParamBuf) do begin + FreeMem(ODBCCursor.FParamBuf[i]); + end; + ODBCCursor.FParamBuf:= nil; +end; + +function TODBCConnection.GetHandle: pointer; +begin + // I'm not sure whether this is correct; perhaps we should return nil + // note that FDBHandle is a LongInt, because ODBC handles are integers, not pointers + // I wonder how this will work on 64 bit platforms then (FK) + Result:=pointer(FDBCHandle); +end; + +procedure TODBCConnection.DoInternalConnect; +const + BufferLength = 1024; // should be at least 1024 according to the ODBC specification +var + ConnectionString: string; + OutConnectionString: string; + ActualLength: SQLSMALLINT; +begin + // Do not call the inherited method as it checks for a non-empty DatabaseName, and we don't even use DatabaseName! + // inherited DoInternalConnect; + + // make sure we have an environment + if not Assigned(FEnvironment) then + begin + if DefaultEnvironment = nil then + DefaultEnvironment:= TODBCEnvironment.Create; + FEnvironment:=DefaultEnvironment; + end; + + // allocate connection handle + ODBCCheckResult( + SQLAllocHandle(SQL_HANDLE_DBC,Environment.FENVHandle,FDBCHandle), + SQL_HANDLE_ENV,Environment.FENVHandle,'Could not allocate ODBC Connection handle.' + ); + + // connect + ConnectionString:=CreateConnectionString; + SetLength(OutConnectionString,BufferLength); // allocate completed connection string buffer (using the ansistring #0 trick) + try + ODBCCheckResult( + SQLDriverConnect(FDBCHandle, // the ODBC connection handle + nil, // no parent window (would be required for prompts) + PChar(ConnectionString), // the connection string + Length(ConnectionString), // connection string length + @(OutConnectionString[1]),// buffer for storing the completed connection string + BufferLength, // length of the buffer + ActualLength, // the actual length of the completed connection string + SQL_DRIVER_NOPROMPT), // don't prompt for password etc. + SQL_HANDLE_DBC,FDBCHandle, + 'Could not connect with connection string "%s".',[ConnectionString] + ); + except + stringsafefree(connectionstring,false); + SQLFreeHandle(SQL_HANDLE_DBC, FDBCHandle); + fdbchandle:= nil; + raise; + end; + stringsafefree(connectionstring,false); + +// commented out as the OutConnectionString is not used further at the moment +// if ActualLength 0) then begin + str1:= todbstring(AParams.ParseSQL(asql,false,false,false,psInterbase, + ODBCCursor.FParamIndex)); + end + else begin + str1:= todbstring(asql); + end; + // prepare statement + ODBCCheckResult( + SQLPrepare(ODBCCursor.FSTMTHandle, PChar(str1), Length(str1)), + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not prepare statement.' + ); + + ODBCCursor.FQuery:= str1; + ODBCCursor.fprepared:= true; +end; + +procedure TODBCConnection.UnPrepareStatement(cursor: TSQLCursor); +begin + with todbccursor(cursor) do begin + FQuery:= ''; + fprepared:= false; + end; +end; + +function TODBCConnection.GetTransactionHandle(trans: TSQLHandle): pointer; +begin + result:= nil; + // Tranactions not implemented yet +end; + +function TODBCConnection.StartDBTransaction(const trans: TSQLHandle; + const AParams: tstringlist): boolean; +begin + result:= true; + // Tranactions not implemented yet +end; + +function TODBCConnection.Commit(trans: TSQLHandle): boolean; +begin + result:= true; + // Tranactions not implemented yet +end; + +function TODBCConnection.Rollback(trans: TSQLHandle): boolean; +begin + result:= true; + // Tranactions not implemented yet +end; + +procedure TODBCConnection.internalCommitRetaining(trans: TSQLHandle); +begin + // Tranactions not implemented yet +end; + +procedure TODBCConnection.internalRollbackRetaining(trans: TSQLHandle); +begin + // Tranactions not implemented yet +end; + +procedure todbcconnection.updaterowcount(const acursor: todbccursor); +var + len1: sqllen; + int1: sqlsmallint; +begin + with acursor do begin + if odbcsucces(sqlgetdiagfield(sql_handle_stmt,fstmthandle,0, + sql_diag_cursor_row_count,@len1,0,int1)) then begin + frowsreturned:= len1; + end; + if odbcsucces(sqlgetdiagfield(sql_handle_stmt,fstmthandle,0, + sql_diag_row_count,@len1,0,int1)) then begin + frowsaffected:= len1; + end; + end; +end; + +procedure TODBCConnection.internalExecute(const cursor: TSQLCursor; + const ATransaction: TSQLTransaction; const AParams: TmseParams; + const autf8: boolean); +var + ODBCCursor:TODBCCursor; + Res: SQLRETURN; +begin + ODBCCursor:= TODBCCursor(cursor); + odbccursor.frowsreturned:= -1; + odbccursor.frowsaffected:= -1; + + + // set parameters + if Assigned(APArams) and (AParams.count > 0) then begin + SetParameters(ODBCCursor, AParams); + end; + + // execute the statement + res:= SQLExecute(ODBCCursor.FSTMTHandle); + ODBCCheckResult(res, + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not execute statement.' + ); + updaterowcount(odbccursor); + // free parameter buffers + FreeParamBuffers(ODBCCursor); +end; + +procedure todbcconnection.internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); +var + ODBCCursor:TODBCCursor; + Res: SQLRETURN; +begin + ODBCCursor:= TODBCCursor(cursor); + odbccursor.frowsreturned:= -1; + odbccursor.frowsaffected:= -1; + res:= SQLExecdirect(ODBCCursor.FSTMTHandle,pchar(asql),length(asql)); + ODBCCheckResult(res, + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not execute statement.' + ); + updaterowcount(odbccursor); +end; + +function TODBCConnection.Fetch(cursor: TSQLCursor): boolean; +var + ODBCCursor:TODBCCursor; + Res:SQLRETURN; +begin + ODBCCursor:= TODBCCursor(cursor); + + // fetch new row + Res:=SQLFetch(ODBCCursor.FSTMTHandle); + if Res<>SQL_NO_DATA then + ODBCCheckResult(Res,SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not fetch new row from result set'); + + // result is true iff a new row was available + Result:=Res<>SQL_NO_DATA; +end; + +function todbcconnection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize + +//todo: optimize + +const + DEFAULT_BLOB_BUFFER_SIZE = 1024; +var + ODBCCursor:TODBCCursor; + StrLenOrInd:SQLINTEGER; + ODBCDateStruct:SQL_DATE_STRUCT; + ODBCTimeStruct:SQL_TIME_STRUCT; + ODBCTimeStampStruct:SQL_TIMESTAMP_STRUCT; + DateTime:TDateTime; +// BlobBuffer:pointer; + BlobBufferSize,BytesRead:SQLINTEGER; +// BlobMemoryStream:TMemoryStream; + Res:SQLRETURN; + targettype: sqlsmallint; + fno: integer; + int1: integer; + str1: string; + + buffer1: pointer; + bufsize1: integer; + memolen1: integer; + dummybuf: array [0..31] of byte; + do1: double; + cu1: currency; + +begin + str1:= ''; + ODBCCursor:= TODBCCursor(cursor); + + // load the field using SQLGetData + // Note: optionally we can implement the use of SQLBindCol later for even more speed + // TODO: finish this + + res:= 0; //ok + fno:= fieldnum+1; + bufsize1:= bufsize; + if buffer = nil then begin + buffer1:= @dummybuf; + bufsize1:= 0; + end + else begin + bufsize1:= bufsize; + buffer1:= buffer; + end; + + case DataType of + ftFixedChar,ftString: begin // are both mapped to TStringField + Res:= SQLGetData(ODBCCursor.FSTMTHandle, fno, + SQL_C_CHAR, buffer1, bufsize1{aField.Size}, @StrLenOrInd); + bufsize1:= strlenorind; + if bufsize1 > bufsize then begin + bufsize1:= -bufsize1; + end; + end; + ftwidestring,ftFixedWideChar: begin + Res:= SQLGetData(ODBCCursor.FSTMTHandle, fno, + SQL_C_WCHAR, buffer1, bufsize1{aField.Size}, @StrLenOrInd); + bufsize1:= strlenorind; + if bufsize1 > bufsize then begin + bufsize1:= -bufsize1; + end; + end; + ftSmallint: begin // mapped to TSmallintField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_SSHORT, buffer1, + SizeOf(Smallint), @StrLenOrInd); + end; + ftInteger,ftWord: begin // mapped to TLongintField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_SLONG, buffer1, + SizeOf(Longint), @StrLenOrInd); + end; + ftLargeint: begin // mapped to TLargeintField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_SBIGINT, buffer1, + SizeOf(Largeint), @StrLenOrInd); + end; + ftFloat,ftcurrency: begin // mapped to TFloatField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_DOUBLE, buffer1, + SizeOf(Double), @StrLenOrInd); + end; + ftbcd: begin + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_DOUBLE, @do1, + SizeOf(Double), @StrLenOrInd); + if res = 0 then begin + cu1:= do1; + Move(cu1, buffer1^, SizeOf(cu1)); + end; + end; + ftTime: begin // mapped to TTimeField + Res:= SQLGetData(ODBCCursor.FSTMTHandle,fno,SQL_C_TYPE_TIME, + @ODBCTimeStruct, SizeOf(SQL_TIME_STRUCT),@StrLenOrInd); + if StrLenOrInd <> SQL_NULL_DATA then begin + DateTime:= TimeStructToDateTime(@ODBCTimeStruct); + Move(DateTime,buffer1^,SizeOf(TDateTime)); + end; + end; + ftDate: begin // mapped to TDateField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_TYPE_DATE, + @ODBCDateStruct, SizeOf(SQL_DATE_STRUCT), @StrLenOrInd); + if StrLenOrInd<>SQL_NULL_DATA then begin + DateTime:=DateStructToDateTime(@ODBCDateStruct); + Move(DateTime, buffer1^, SizeOf(TDateTime)); + end; + end; + ftDateTime: begin // mapped to TDateTimeField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_TYPE_TIMESTAMP, + @ODBCTimeStampStruct, SizeOf(SQL_TIMESTAMP_STRUCT), @StrLenOrInd); + if StrLenOrInd<>SQL_NULL_DATA then begin + DateTime:=TimeStampStructToDateTime(@ODBCTimeStampStruct); + Move(DateTime, buffer1^, SizeOf(TDateTime)); + end; + end; + ftBoolean: begin // mapped to TBooleanField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_BIT, buffer1, + SizeOf(Wordbool), @StrLenOrInd); + end; + ftBytes: begin // mapped to TBytesField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_BINARY, buffer1, + bufsize1{aField.Size}, @StrLenOrInd); + end; + ftVarBytes: begin // mapped to TVarBytesField + int1:= bufsize1-sizeof(word); + if int1 < 0 then begin + int1:= 0; + end; + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_BINARY, + pchar(buffer1)+sizeof(word), + int1{aField.Size}, @StrLenOrInd); + pword(buffer1)^:= strlenorind; + end; + ftguid: begin + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_GUID, buffer1, + SizeOf(tguid), @StrLenOrInd); + end; + ftBlob,ftMemo,ftwidememo: begin // BLOBs + // Try to discover BLOB data length + memolen1:= maxint div sizeof(widechar); + if odbccursor.fcurrentblobbuffer = '' then begin + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_BINARY, buffer1, 0, + @StrLenOrInd); + ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get field data for field ''%s'' (index %d).', + [odbccursor.ffieldNames[fieldnum], fno]); + if StrLenOrInd = 0 then begin + strlenorind:= sql_null_data; //length 0 -> NULL + end; + // Read the data if not NULL + if (StrLenOrInd <> SQL_NULL_DATA) and (buffer <> nil) then begin + // Determine size of buffer to use + if StrLenOrInd <> SQL_NO_TOTAL then begin + memolen1:= strlenorind; + if datatype = ftwidememo then begin + memolen1:= memolen1 * sizeof(widechar); + end; + BlobBufferSize:= StrLenOrInd; + case datatype of + ftmemo: begin + blobbuffersize:= blobbuffersize + sizeof(char); //terminating 0 + end; + ftwidememo: begin + blobbuffersize:= (blobbuffersize+1)*sizeof(widechar); //terminating 0 + end; + end; + end + else begin + BlobBufferSize:= DEFAULT_BLOB_BUFFER_SIZE; + end; + if BlobBufferSize > 0 then begin + int1:= 0; //write index + targettype:= SQL_C_BINARY; + if datatype = ftwidememo then begin + targettype:= SQL_C_WCHAR; + end; + repeat + setlength(str1,int1+blobbuffersize); + Res:= SQLGetData(ODBCCursor.FSTMTHandle, fno, targettype, + pchar(pointer(str1))+int1, BlobBufferSize, @StrLenOrInd); + ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get field data for field ''%s'' (index %d).', + [odbccursor.ffieldNames[fieldnum], fno]); + if (StrLenOrInd=SQL_NO_TOTAL) or (StrLenOrInd>BlobBufferSize) then begin + BytesRead:= BlobBufferSize; + end + else begin + BytesRead:= StrLenOrInd; + end; + inc(int1,bytesread); + until Res = SQL_SUCCESS; + case datatype of + ftmemo,ftwidestring: begin + if memolen1 < int1 then begin + int1:= memolen1; //remove terminating 0 + end; + end; + end; + setlength(str1,int1); + end; + if datatype = ftwidememo then begin + bufsize1:= length(str1); + odbccursor.fcurrentblobbuffer:= str1; + bufsize1:= -bufsize1; + end + else begin + int1:= cursor.addblobdata(str1); + move(int1,buffer^,sizeof(int1)); //save id + end; + end; + end + else begin + strlenorind:= sql_null_data; //invalid + if datatype = ftwidememo then begin + bufsize1:= length(odbccursor.fcurrentblobbuffer); + if bufsize1 <= bufsize then begin + strlenorind:= 0; + if buffer <> nil then begin + move(pointer(odbccursor.fcurrentblobbuffer)^,buffer^,bufsize1); + end; + end + else begin + bufsize1:= 0; //data lost + end; + odbccursor.fcurrentblobbuffer:= ''; + end; + end; + end; + else begin // TODO: Loading of other field types + raise EODBCException.CreateFmt('Tried to load field of unsupported field type %s', + [Fieldtypenames[DataType]]); + end; + end; + bufsize:= bufsize1; + ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get field data for field ''%s'' (index %d).', + [odbccursor.ffieldNames[fieldnum], fno]); + Result:=StrLenOrInd<>SQL_NULL_DATA; // Result indicates whether the value is non-null +end; + +function TODBCConnection.CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; +var + blobid: integer; +// int1,int2: integer; +// str1: string; +// bo1: boolean; +begin + result:= nil; + if mode = bmread then begin + if field.getData(@blobId) then begin + result:= acursor.getcachedblob(blobid); + end; + end; +end; + +procedure TODBCConnection.FreeFldBuffers(cursor: TSQLCursor); +var + ODBCCursor:TODBCCursor; +// i: integer; +begin + ODBCCursor:=cursor as TODBCCursor; +{ + // Free TMemoryStreams in cursor.FBlobStreams and clear it + for i:=0 to ODBCCursor.FBlobStreams.Count-1 do + TObject(ODBCCursor.FBlobStreams[i]).Free; + ODBCCursor.FBlobStreams.Clear; +} + ODBCCheckResult( + SQLFreeStmt(ODBCCursor.FSTMTHandle, SQL_CLOSE), + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not close ODBC statement cursor.' + ); +end; + +procedure TODBCConnection.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TFieldDefs); +const + ColNameDefaultLength = 40; // should be > 0, because an ansistring of length 0 is a nil pointer instead of a pointer to a #0 + TypeNameDefaultLength = 80; // idem +var + ODBCCursor:TODBCCursor; + ColumnCount:SQLSMALLINT; + i:integer; + ColNameLength,{TypeNameLength,}DataType,DecimalDigits,Nullable:SQLSMALLINT; + ColumnSize: SQLULEN; + ColName{,TypeName}:string; + FieldType:TFieldType; + FieldSize: integer; + fd: tfielddef; + int1: integer; +begin + fielddefs.clear; + ODBCCursor:=cursor as TODBCCursor; + + // get number of columns in result set + ODBCCheckResult( + SQLNumResultCols(ODBCCursor.FSTMTHandle, ColumnCount), + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not determine number of columns in result set.' + ); + + setlength(odbccursor.ffieldnames,columncount); + for i:=1 to ColumnCount do + begin + SetLength(ColName,ColNameDefaultLength); // also garantuees uniqueness + + // call with default column name buffer + ODBCCheckResult( + SQLDescribeCol(ODBCCursor.FSTMTHandle, // statement handle + i, // column number, is 1-based (Note: column 0 is the bookmark column in ODBC) + @(ColName[1]), // default buffer + ColNameDefaultLength+1, // and its length; we include the #0 terminating any ansistring of Length > 0 in the buffer + ColNameLength, // actual column name length + DataType, // the SQL datatype for the column + ColumnSize, // column size + DecimalDigits, // number of decimal digits + Nullable), // SQL_NO_NULLS, SQL_NULLABLE or SQL_NULLABLE_UNKNOWN + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get column properties for column %d.',[i] + ); + + // truncate buffer or make buffer long enough for entire column name (note: the call is the same for both cases!) + SetLength(ColName,ColNameLength); + // check whether entire column name was returned + if ColNameLength>ColNameDefaultLength then + begin + // request column name with buffer that is long enough + ODBCCheckResult( + SQLColAttribute(ODBCCursor.FSTMTHandle, // statement handle + i, // column number + SQL_DESC_NAME, // the column name or alias + @(ColName[1]), // buffer + ColNameLength+1, // buffer size + @ColNameLength, // actual length + nil), // no numerical output + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get column name for column %d.',[i] + ); + end; + + // convert type + // NOTE: I made some guesses here after I found only limited information about TFieldType; please report any problems + case DataType of + SQL_CHAR: begin FieldType:=ftString; FieldSize:=ColumnSize{+1}; end; + SQL_VARCHAR: begin FieldType:=ftString; FieldSize:=ColumnSize{+1}; end; + SQL_LONGVARCHAR: begin FieldType:=ftMemo; FieldSize:= blobidsize; end; + // is a blob + SQL_WCHAR: begin FieldType:=ftWideString; FieldSize:=ColumnSize{+1}; end; + SQL_WVARCHAR: begin FieldType:=ftWideString; FieldSize:=ColumnSize{+1}; end; + SQL_WLONGVARCHAR: begin + FieldType:= ftwidememo; //for tmsestringfield + FieldSize:= 0; + end; // is a blob + SQL_NUMERIC,SQL_DECIMAL: + begin + if (decimaldigits > 4) and + (dbo_bcdtofloatif in controller.options) then begin + FieldType:= ftFloat; + FieldSize:= 0; + end + else begin + FieldType:= ftbcd; + FieldSize:= decimaldigits; + if fieldsize > 4 then begin + fieldsize:= 4; + end; + end; + end; + SQL_SMALLINT: begin FieldType:=ftSmallint; FieldSize:=0; end; + SQL_INTEGER: begin FieldType:=ftInteger; FieldSize:=0; end; + SQL_REAL: begin FieldType:=ftFloat; FieldSize:=0; end; + SQL_FLOAT: begin FieldType:=ftFloat; FieldSize:=0; end; + SQL_DOUBLE: begin FieldType:=ftFloat; FieldSize:=0; end; + SQL_BIT: begin FieldType:=ftBoolean; FieldSize:=0; end; + SQL_TINYINT: begin FieldType:=ftSmallint; FieldSize:=0; end; + SQL_BIGINT: begin FieldType:=ftLargeint; FieldSize:=0; end; + SQL_BINARY: begin FieldType:=ftBytes; FieldSize:=ColumnSize; end; + SQL_VARBINARY: begin FieldType:=ftVarBytes; FieldSize:=ColumnSize; end; + SQL_LONGVARBINARY: begin FieldType:=ftBlob; FieldSize:=blobidsize; end; + // is a blob + SQL_TYPE_DATE: begin FieldType:=ftDate; FieldSize:=0; end; + SQL_TYPE_TIME: begin FieldType:=ftTime; FieldSize:=0; end; + SQL_TYPE_TIMESTAMP:begin FieldType:=ftDateTime; FieldSize:=0; end; +{ SQL_TYPE_UTCDATETIME:FieldType:=ftUnknown;} +{ SQL_TYPE_UTCTIME: FieldType:=ftUnknown;} +{ SQL_INTERVAL_MONTH: FieldType:=ftUnknown;} +{ SQL_INTERVAL_YEAR: FieldType:=ftUnknown;} +{ SQL_INTERVAL_YEAR_TO_MONTH: FieldType:=ftUnknown;} +{ SQL_INTERVAL_DAY: FieldType:=ftUnknown;} +{ SQL_INTERVAL_HOUR: FieldType:=ftUnknown;} +{ SQL_INTERVAL_MINUTE: FieldType:=ftUnknown;} +{ SQL_INTERVAL_SECOND: FieldType:=ftUnknown;} +{ SQL_INTERVAL_DAY_TO_HOUR: FieldType:=ftUnknown;} +{ SQL_INTERVAL_DAY_TO_MINUTE: FieldType:=ftUnknown;} +{ SQL_INTERVAL_DAY_TO_SECOND: FieldType:=ftUnknown;} +{ SQL_INTERVAL_HOUR_TO_MINUTE: FieldType:=ftUnknown;} +{ SQL_INTERVAL_HOUR_TO_SECOND: FieldType:=ftUnknown;} +{ SQL_INTERVAL_MINUTE_TO_SECOND:FieldType:=ftUnknown;} + SQL_GUID: begin FieldType:=ftGuid; FieldSize:=ColumnSize; end; + else + begin FieldType:=ftUnknown; FieldSize:=ColumnSize; end + end; + +// if (FieldType in [ftString,ftFixedChar]) and // field types mapped to TStringField +// (FieldSize >= dsMaxStringSize) then +// begin +// FieldSize:=dsMaxStringSize-1; +// end; +(* + if FieldType=ftUnknown then // if unknown field type encountered, try finding more specific information about the ODBC SQL DataType + begin + SetLength(TypeName,TypeNameDefaultLength); // also garantuees uniqueness + + ODBCCheckResult( + SQLColAttribute(ODBCCursor.FSTMTHandle, // statement handle + i, // column number + SQL_DESC_TYPE_NAME, // FieldIdentifier indicating the datasource dependent data type name (useful for diagnostics) + @(TypeName[1]), // default buffer + TypeNameDefaultLength+1, // and its length; we include the #0 terminating any ansistring of Length > 0 in the buffer + @TypeNameLength, // actual type name length + nil // no need for a pointer to return a numeric attribute at + ), + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get datasource dependent type name for column %s.',[ColName] + ); + // truncate buffer or make buffer long enough for entire column name (note: the call is the same for both cases!) + SetLength(TypeName,TypeNameLength); + // check whether entire column name was returned + if TypeNameLength>TypeNameDefaultLength then + begin + // request column name with buffer that is long enough + ODBCCheckResult( + SQLColAttribute(ODBCCursor.FSTMTHandle, // statement handle + i, // column number + SQL_DESC_TYPE_NAME, // FieldIdentifier indicating the datasource dependent data type name (useful for diagnostics) + @(TypeName[1]), // buffer + TypeNameLength+1, // buffer size + @TypeNameLength, // actual length + nil), // no need for a pointer to return a numeric attribute at + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get datasource dependent type name for column %s.',[ColName] + ); + end; + DatabaseErrorFmt('Column %s has an unknown or unsupported column type. Datasource dependent type name: %s. ODBC SQL data type code: %d.', [ColName, TypeName, DataType]); + end; +*) + // add FieldDef + if not(fieldtype in varsizefields) then begin + fieldsize:= 0; + end; + fd:= TFieldDef.Create(FieldDefs, ColName, FieldType, FieldSize, False, i); + fd.collection:= fielddefs; + if fieldtype = ftbcd then begin + int1:= columnsize; + if int1 > maxprecision then begin + int1:= maxprecision; + end; + fd.precision:= int1; + end; + odbccursor.ffieldnames[i-1]:= colname; + end; +end; + +procedure TODBCConnection.UpdateIndexDefs(var IndexDefs: TIndexDefs; + const aTableName: string; const acursor: tsqlcursor); +var + StmtHandle:SQLHSTMT; + Res:SQLRETURN; + IndexDef: TIndexDef; + KeyFields, KeyName: String; + // variables for binding + NonUnique :SQLSMALLINT; NonUniqueIndOrLen :SQLINTEGER; + IndexName :string; IndexNameIndOrLen :SQLINTEGER; + _Type :SQLSMALLINT; _TypeIndOrLen :SQLINTEGER; + OrdinalPos:SQLSMALLINT; OrdinalPosIndOrLen:SQLINTEGER; + ColName :string; ColNameIndOrLen :SQLINTEGER; + AscOrDesc :SQLCHAR; AscOrDescIndOrLen :SQLINTEGER; + PKName :string; PKNameIndOrLen :SQLINTEGER; +const + DEFAULT_NAME_LEN = 255; +begin + +// exit; /////////// does not work with MS SQL because of one statement + //per connection limitation + + // allocate statement handle + StmtHandle := SQL_NULL_HANDLE; + ODBCCheckResult( + SQLAllocHandle(SQL_HANDLE_STMT, FDBCHandle, StmtHandle), + SQL_HANDLE_DBC, FDBCHandle, 'Could not allocate ODBC Statement handle.' + ); + + try + // Disabled: only works if we can specify a SchemaName and, if supported by the data source, a CatalogName + // otherwise SQLPrimaryKeys returns error HY0009 (Invalid use of null pointer) + // set the SQL_ATTR_METADATA_ID so parameters to Catalog functions are considered as identifiers (e.g. case-insensitive) + //ODBCCheckResult( + // SQLSetStmtAttr(StmtHandle, SQL_ATTR_METADATA_ID, SQLPOINTER(SQL_TRUE), SQL_IS_UINTEGER), + // SQL_HANDLE_STMT, StmtHandle, 'Could not set SQL_ATTR_METADATA_ID statement attribute to SQL_TRUE.' + //); + + // alloc result column buffers + SetLength(ColName, DEFAULT_NAME_LEN); + SetLength(PKName, DEFAULT_NAME_LEN); + SetLength(IndexName,DEFAULT_NAME_LEN); + + // Fetch primary key info using SQLPrimaryKeys + ODBCCheckResult( + SQLPrimaryKeys( + StmtHandle, + nil, 0, // any catalog + nil, 0, // any schema + PChar(aTableName), Length(aTableName) + ), + SQL_HANDLE_STMT, StmtHandle, + 'Could not retrieve primary key metadata for table %s using SQLPrimaryKeys.', + [aTableName] + ); + + // init key name & fields; we will set the IndexDefs.Option ixPrimary below when there is a match by IndexName=KeyName + KeyName:=''; + KeyFields:=''; + try + // bind result columns; the column numbers are documented in the reference for SQLStatistics + ODBCCheckResult(SQLBindCol(StmtHandle, 4, SQL_C_CHAR , @ColName[1], + Length(ColName)+1, @ColNameIndOrLen), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind primary key metadata column COLUMN_NAME.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 5, SQL_C_SSHORT, @OrdinalPos, 0, + @OrdinalPosIndOrLen), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind primary key metadata column KEY_SEQ.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 6, SQL_C_CHAR , @PKName [1], + Length(PKName )+1, @PKNameIndOrLen ), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind primary key metadata column PK_NAME.'); + + // fetch result + repeat + // go to next row; loads data in bound columns + Res:=SQLFetch(StmtHandle); + // if no more row, break + if Res=SQL_NO_DATA then + Break; + // handle data + if ODBCSucces(Res) then begin + if OrdinalPos=1 then begin + KeyName:=PChar(@PKName[1]); + KeyFields:= PChar(@ColName[1]); + end else begin + KeyFields:=KeyFields+';'+PChar(@ColName[1]); + end; + end else begin + ODBCCheckResult(Res, SQL_HANDLE_STMT, StmtHandle, + 'Could not fetch primary key metadata row.'); + end; + until false; + finally + // unbind columns & close cursor + ODBCCheckResult(SQLFreeStmt(StmtHandle, SQL_UNBIND), SQL_HANDLE_STMT, + StmtHandle, 'Could not unbind columns.'); + ODBCCheckResult(SQLFreeStmt(StmtHandle, SQL_CLOSE), SQL_HANDLE_STMT, + StmtHandle, 'Could not close cursor.'); + end; + + //WriteLn('KeyName: ',KeyName,'; KeyFields: ',KeyFields); + + // use SQLStatistics to get index information + ODBCCheckResult( + SQLStatistics( + StmtHandle, + nil, 0, // catalog unkown; request for all catalogs + nil, 0, // schema unkown; request for all schemas + PChar(aTableName), Length(aTableName), // request information for TableName + SQL_INDEX_ALL, + SQL_QUICK + ), + SQL_HANDLE_STMT, StmtHandle, + 'Could not retrieve index metadata for table %s using SQLStatistics.', + [aTableName] + ); + + try + // bind result columns; the column numbers are documented in the reference for SQLStatistics + ODBCCheckResult(SQLBindCol(StmtHandle, 4, SQL_C_SSHORT, @NonUnique , 0, + @NonUniqueIndOrLen ), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column NON_UNIQUE.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 6, SQL_C_CHAR , @IndexName[1], + Length(IndexName)+1, @IndexNameIndOrLen), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column INDEX_NAME.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 7, SQL_C_SSHORT, @_Type , 0, + @_TypeIndOrLen ), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column TYPE.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 8, SQL_C_SSHORT, @OrdinalPos, 0, + @OrdinalPosIndOrLen), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column ORDINAL_POSITION.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 9, SQL_C_CHAR , @ColName [1], + Length(ColName )+1, @ColNameIndOrLen ), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column COLUMN_NAME.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 10, SQL_C_CHAR , @AscOrDesc , 1, + @AscOrDescIndOrLen ), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column ASC_OR_DESC.'); + + // clear index defs + IndexDef:=nil; + + // fetch result + repeat + // go to next row; loads data in bound columns + Res:=SQLFetch(StmtHandle); + // if no more row, break + if Res=SQL_NO_DATA then + Break; + // handle data + if ODBCSucces(Res) then begin + // note: SQLStatistics not only returns index info, but also statistics; we skip the latter + if _Type<>SQL_TABLE_STAT then begin + if (OrdinalPos=1) or not Assigned(IndexDef) then begin + // create new IndexDef iff OrdinalPos=1 or not Assigned(IndexDef) (the latter should not occur though) + IndexDef:=IndexDefs.AddIndexDef; + IndexDef.Name:=PChar(@IndexName[1]); // treat ansistring as zero terminated string + IndexDef.Fields:=PChar(@ColName[1]); + if NonUnique=SQL_FALSE then + IndexDef.Options:=IndexDef.Options+[ixUnique]; + if (AscOrDescIndOrLen<>SQL_NULL_DATA) and (AscOrDesc='D') then + IndexDef.Options:=IndexDef.Options+[ixDescending]; + if IndexDef.Name=KeyName then + IndexDef.Options:=IndexDef.Options+[ixPrimary]; + // TODO: figure out how we can tell whether COLUMN_NAME is an expression or not + // if it is an expression, we should include ixExpression in Options and set Expression to ColName + end else // NB we re-use the last IndexDef + IndexDef.Fields:=IndexDef.Fields+';'+PChar(@ColName[1]); // NB ; is the separator to be used for IndexDef.Fields + end; + end else begin + ODBCCheckResult(Res, SQL_HANDLE_STMT, StmtHandle, + 'Could not fetch index metadata row.'); + end; + until false; + finally + // unbind columns & close cursor + ODBCCheckResult(SQLFreeStmt(StmtHandle, SQL_UNBIND), SQL_HANDLE_STMT, + StmtHandle, 'Could not unbind columns.'); + ODBCCheckResult(SQLFreeStmt(StmtHandle, SQL_CLOSE), SQL_HANDLE_STMT, + StmtHandle, 'Could not close cursor.'); + end; + + finally + if StmtHandle<>SQL_NULL_HANDLE then begin + // Free the statement handle + Res:=SQLFreeHandle(SQL_HANDLE_STMT, StmtHandle); + if Res=SQL_ERROR then + ODBCCheckResult(Res, SQL_HANDLE_STMT, STMTHandle, + 'Could not free ODBC Statement handle.'); + end; + end; +end; + +function TODBCConnection.GetSchemaInfoSQL(SchemaType: TSchemaType; + SchemaObjectName, SchemaObjectPattern: msestring): msestring; +begin + Result:=inherited GetSchemaInfoSQL( + SchemaType, SchemaObjectName, SchemaObjectPattern); + // TODO: implement this +end; + +{ TODBCEnvironment } + +procedure ODBCCheckResult(LastReturnCode:SQLRETURN; HandleType:SQLSMALLINT; + AHandle: SQLHANDLE; ErrorMsg: string; + const values: array of const); +var + conn: todbcconnection; +begin + if not odbcsucces(lastreturncode) then begin + conn:= todbcconnection.create(nil); + try + conn.odbccheckresult(lastreturncode,handletype,ahandle,errormsg,values); + finally; + conn.free; + end; + end; +end; + +constructor TODBCEnvironment.Create; +var + res: sqlreturn; +begin + // make sure odbc is loaded + initializeodbc([]); + finitialized:= true; + // allocate environment handle + if SQLAllocHandle(SQL_HANDLE_ENV, + SQL_NULL_HANDLE, FENVHandle) = SQL_Error then begin + raise EODBCException.Create('Could not allocate ODBC Environment handle'); + // we can't retrieve any more information, + //because we don't have a handle for the SQLGetDiag* functions + end; + // set odbc version + res:= SQLSetEnvAttr(FENVHandle, SQL_ATTR_ODBC_VERSION, + SQLPOINTER(SQL_OV_ODBC3), 0); + ODBCCheckResult(res, + SQL_HANDLE_ENV, FENVHandle,'Could not set ODBC version to 3.',[]); +end; + +destructor TODBCEnvironment.Destroy; +var + Res:SQLRETURN; +begin + // free environment handle + if FENVHandle <> nil then begin //otherwise exception in create + Res:=SQLFreeHandle(SQL_HANDLE_ENV, FENVHandle); + if Res = SQL_ERROR then + ODBCCheckResult(Res,SQL_HANDLE_ENV, FENVHandle, + 'Could not free ODBC Environment handle.',[]); + + // free odbc if not used by any TODBCEnvironment object anymore + end; +// Dec(ODBCLoadCount); +// if ODBCLoadCount=0 then ReleaseOdbc; + if finitialized then begin + releaseodbc; + end; +end; + +{ TODBCCursor } + +constructor TODBCCursor.Create(const aowner: icursorclient; + const aname: ansistring; const Connection:TODBCConnection); +begin + fconnection:= connection; + inherited create(aowner,aname); + // allocate statement handle + connection.ODBCCheckResult( + SQLAllocHandle(SQL_HANDLE_STMT, Connection.FDBCHandle, FSTMTHandle), + SQL_HANDLE_DBC, Connection.FDBCHandle, + 'Could not allocate ODBC Statement handle.' + ); + + // allocate FBlobStreams +// FBlobStreams:=TList.Create; +end; + +destructor TODBCCursor.Destroy; +var + Res:SQLRETURN; +begin + inherited Destroy; + +// FBlobStreams.Free; + + if pointer(FSTMTHandle) <> pointer(SQL_INVALID_HANDLE) then + begin + // deallocate statement handle + Res:=SQLFreeHandle(SQL_HANDLE_STMT, FSTMTHandle); + if Res=SQL_ERROR then + fconnection.ODBCCheckResult(Res,SQL_HANDLE_STMT, FSTMTHandle, + 'Could not free ODBC Statement handle.'); + end; +end; + +procedure TODBCCursor.close; +begin + sqlclosecursor(fstmthandle); +// ODBCCheckResult(sqlclosecursor(fstmthandle),SQL_HANDLE_STMT, FSTMTHandle, +// 'Could not close Cursor'); + //there is possible no cursor -> no errorcheck + fcurrentblobbuffer:= ''; + inherited; +end; + +{ finalization } + +initialization +finalization + + if Assigned(DefaultEnvironment) then + DefaultEnvironment.Free; + +end. + diff --git a/mseide-msegui/lib/common/db/mpqconnection.pas b/mseide-msegui/lib/common/db/mpqconnection.pas new file mode 100644 index 0000000..562a48e --- /dev/null +++ b/mseide-msegui/lib/common/db/mpqconnection.pas @@ -0,0 +1,1708 @@ +{ + Copyright (c) 2004 by Joost van der Sluis + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + Modified 2006-2013 by Martin Schreiber + + **********************************************************************} + +unit mpqconnection; +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +{$Define LinkDynamically} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,SysUtils, msqldb, mdb, + {$ifdef FPC}dbconst{$else}dbconst_del{$endif}, + msedbevents,msetypes{msestrings},msedb, +{$IfDef LinkDynamically} + postgres3dyn; +{$Else} + postgres3; +{$EndIf} + +type + epqerror = class(econnectionerror) + private + fsqlcode: string; + public + constructor create(const asender: tcustomsqlconnection; const amessage: ansistring; + const aerrormessage: msestring; const asqlcode: string); + public + property sqlcode: string read fsqlcode; + end; + + TPQTrans = Class(TSQLHandle) + protected + fconn: PPGConn; + fparams: ansistring; +// ErrorOccured : boolean; + public + property conn: ppgconn read fconn; + end; + + dbarrayinfoty = record + fieldtype: tfieldtype; + vartype: word; + end; + dbarrayinfoarty = array of dbarrayinfoty; + + TPQCursor = Class(TSQLCursor) + protected + Statementm : msestring; + tr : TPQTrans; + res : PPGresult; + CurTuple : integer; + Nr : string; + fopen: boolean; + ParamBinding : TParamBinding; + ParamReplaceString : mseString; + arrayinfo: dbarrayinfoarty; + public + procedure close; override; + end; + + dbeventarty = array of tdbevent; + + TPQConnection = class (TSQLConnection,iblobconnection,idbevent,idbeventcontroller) + private + FCursorCount : integer; + FConnectString : string; + FHandle: ppgconn; + FIntegerDateTimes : boolean; + feventcontroller: tdbeventcontroller; + ftransactionconnectionused: boolean; + flastsqlcode: string; + flasterrormessage: msestring; + function TranslateFldType(Type_Oid: integer; + out isarray: boolean; out vartype: word) : TFieldType; + function geteventinterval: integer; + procedure seteventinterval(const avalue: integer); + procedure closeconnection(var aconnection: ppgconn); + function constructconnectstring: string; + procedure openconnection(const aconnectstring: ansistring; + var aconnection: ppgconn); + procedure begintrans(const aconnection: ppgconn; const aparams: ansistring); + protected + procedure checkerror(const aconnection: ppgconn; var ares: ppgresult; + const amessage: ansistring); + procedure checkexec(const aconnection: ppgconn; const asql: ansistring; + const amessage: ansistring); + procedure finalizetransaction(const atransaction: tsqlhandle); override; + procedure DoInternalConnect; override; + procedure DoInternalDisconnect; override; + function GetHandle : pointer; override; + + Function AllocateTransactionHandle : TSQLHandle; override; + + procedure internalExecute(const cursor: TSQLCursor; const atransaction: tsqltransaction; + const AParams : TmseParams; const autf8: boolean); override; + procedure internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); override; + function GetTransactionHandle(trans : TSQLHandle): pointer; override; + function RollBack(trans : TSQLHandle) : boolean; override; + function Commit(trans : TSQLHandle) : boolean; override; + procedure internalCommitRetaining(trans : TSQLHandle); override; + function StartdbTransaction(const trans : TSQLHandle; + const AParams: tstringlist) : boolean; override; + procedure internalRollBackRetaining(trans : TSQLHandle); override; + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); override; + function GetSchemaInfoSQL(SchemaType : TSchemaType; + SchemaObjectName, SchemaPattern : msestring) : msestring; override; + procedure dopqexec(const asql: ansistring); overload; + procedure dopqexec(const asql: ansistring; + const aconnection: ppgconn); overload; + + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + function getblobdatasize: integer; override; + function getnumboolean: boolean; override; + + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); +// function getfeatures(): databasefeaturesty override; +// function blobscached: boolean; + + //idbevent + procedure listen(const sender: tdbevent); + procedure unlisten(const sender: tdbevent); + procedure fire(const sender: tdbevent); + //idbeventcontroller + function getdbevent(var aname: string; var aid: int64): boolean; + //false if none + procedure dolisten(const sender: tdbevent); + procedure dounlisten(const sender: tdbevent); + public + constructor Create(AOwner : TComponent); override; + destructor destroy; override; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring) : TSQLCursor; override; + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + procedure FreeFldBuffers(cursor : TSQLCursor); override; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); override; + procedure UnPrepareStatement(cursor : TSQLCursor); override; + function Fetch(cursor : TSQLCursor) : boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //null based + function backendpid: int64; //0 if not connected + procedure createdatabase(const asql: ansistring); + property eventcontroller: tdbeventcontroller read feventcontroller; + property lasterrormessage: msestring read flasterrormessage; + property lastsqlcode: string read flastsqlcode; + published + property DatabaseName; + property KeepConnection; +// property LoginPrompt; + property Params; +// property OnLogin; + property ongetcredentials; + property eventinterval: integer read geteventinterval + write seteventinterval default defaultdbeventinterval; + end; + +implementation +uses + math,msestream,msedatalist,mseformatstr,msedatabase,msectypes,msestrings, + variants,msevariants,msesqlresult{$ifndef FPC},classes_del{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +ResourceString + SErrRollbackFailed = 'Rollback transaction failed'; + SErrCommitFailed = 'Commit transaction failed'; + SErrConnectionFailed = 'Connection to database failed'; + SErrTransactionFailed = 'Start of transaction failed'; + SErrClearSelection = 'Clear of selection failed'; + SErrExecuteFailed = 'Execution of query failed'; + SErrFieldDefsFailed = 'Can not extract field information from query'; + SErrFetchFailed = 'Fetch of data failed'; + SErrPrepareFailed = 'Preparation of query failed.'; + +const + Oid_Bool = 16; + Oid_Bool_ar = 1000; + Oid_Text = 25; + Oid_Text_ar = 1009; + Oid_bytea = 17; + Oid_bytea_ar = 1001; + Oid_Oid = 26; + Oid_Oid_ar = 1028; + Oid_Name = 19; + Oid_Name_ar = 1003; + Oid_Int8 = 20; + Oid_Int8_ar = 1016; + Oid_int2 = 21; + Oid_int2_ar = 1005; + Oid_Int4 = 23; + Oid_Int4_ar = 1007; + Oid_Float4 = 700; + Oid_Float4_ar = 1021; + Oid_Float8 = 701; + Oid_Float8_ar = 1022; + Oid_Unknown = 705; + Oid_Unknown_ar = 0; + Oid_bpchar = 1042; + Oid_bpchar_ar = 1014; + Oid_varchar = 1043; + Oid_varchar_ar = 1015; + Oid_timestamp = 1114; + Oid_timestamp_ar = 1115; + oid_date = 1082; + oid_date_ar = 1182; + oid_time = 1083; + oid_time_ar = 1183; + oid_numeric = 1700; + oid_numeric_ar = 1231; + oid_uuid = 2950; + oid_uuid_ar = 2951; + pg_diag_sqlstate = 'C'; + + inv_read = $40000; + inv_write = $20000; + invalidoid = 0; + + varhdrsz = 4; + nbase = 10000; //base for numeric digits + maxprecision = 18; + +type + tdatabase1 = class(tdatabase); + +{ TPQCursor } + +procedure TPQCursor.close; +begin + inherited; + if fopen then begin + arrayinfo:= nil; + fopen:= false; + if res <> nil then begin + pqclear(res); + end; + end; +end; + +{ tpqconnection } + +constructor tpqconnection.create(aowner: tcomponent); +begin + feventcontroller:= tdbeventcontroller.create(idbeventcontroller(self)); + inherited; + fconnoptions:= fconnoptions + [sco_supportparams,sco_emulateretaining, + sco_blobscached]; +end; + +destructor TPQConnection.destroy; +begin + inherited; + feventcontroller.free; +end; + +function TPQConnection.GetTransactionHandle(trans : TSQLHandle): pointer; +begin + Result := trans; +end; + +procedure TPQConnection.checkerror(const aconnection: ppgconn; + var ares: ppgresult; const amessage: ansistring); +var +// err: integer; + res: texecstatustype; +begin + res:= PQresultStatus(ares); + if not(res in [PGRES_COMMAND_OK,PGRES_TUPLES_OK]) then begin + flastsqlcode:= strpas(pqresulterrorfield(ares,ord(pg_diag_sqlstate))); + flasterrormessage:= connectionmessage(pqresulterrormessage(ares)); + PQclear(ares); + ares:= nil; + raise epqerror.create(self,amessage+' (PostgreSQL: '+ + ansistring(flasterrormessage)+ ')', + flasterrormessage,flastsqlcode); + end + else begin + if res <> pgres_tuples_ok then begin + PQclear(ares); + ares:= nil; + end; + end; +end; + +procedure tpqconnection.checkexec(const aconnection: ppgconn; const asql: ansistring; + const amessage: ansistring); +var + res: ppgresult; +begin + res:= pqexec(aconnection,pchar(asql)); + checkerror(aconnection,res,amessage); +end; + +procedure tpqconnection.begintrans(const aconnection: ppgconn; + const aparams: ansistring); +begin + checkexec(aconnection,'BEGIN '+aparams,sErrTransactionFailed); +end; + +function TPQConnection.StartdbTransaction(const trans : TSQLHandle; + const AParams: tstringlist) : boolean; +var + int1: integer; +begin + with tpqtrans(trans) do begin + if fconn = nil then begin + if not ftransactionconnectionused then begin + fconn:= self.fhandle; + ftransactionconnectionused:= true; + end + else begin + openconnection(fconnectstring,fconn); + end; + end; + fparams:= ''; + if aparams <> nil then begin + for int1:= 0 to aparams.count - 1 do begin + fparams:= fparams + aparams[int1] + ',' + end; + if aparams.count > 0 then begin + setlength(fparams,length(fparams)-1); + end; + end; + begintrans(fconn,fparams); + end; + result:= true; +end; + +function TPQConnection.RollBack(trans : TSQLHandle) : boolean; +begin + checkexec(tpqtrans(trans).fconn,'ROLLBACK',SErrRollbackFailed); + result := true; +end; + +function TPQConnection.Commit(trans : TSQLHandle) : boolean; +begin + checkexec(tpqtrans(trans).fconn,'COMMIT',SErrCommitFailed); + result:= true; +end; + +procedure TPQConnection.internalRollBackRetaining(trans : TSQLHandle); +begin + with tpqtrans(trans) do begin + checkexec(fconn,'ROLLBACK',SErrRollbackFailed); + begintrans(fconn,fparams); + end; +end; + +procedure TPQConnection.internalCommitRetaining(trans : TSQLHandle); +begin + with tpqtrans(trans) do begin + checkexec(fconn,'COMMIT',SErrCommitFailed); + begintrans(fconn,fparams); + end; +end; + +procedure TPQConnection.openconnection(const aconnectstring: string; + var aconnection: ppgconn); +var + msg: ansistring; +begin + aconnection:= PQconnectdb(pchar(aConnectString)); + if (PQstatus(aconnection) = CONNECTION_BAD) then begin + msg:= ansistring(connectionmessage(PQerrorMessage(aconnection))); + pqfinish(aconnection); + aconnection:= nil; + DatabaseError(sErrConnectionFailed + ' (PostgreSQL: ' + msg + ')',self); + end; +end; + +function tpqconnection.constructconnectstring: ansistring; +var + u,p: msestring; //how to define encoding of connectionstring? + u1,p1: string; +begin + result:= ''; + getcredentials(u,p); + if (U <> '') then begin + u1:= ansistring(u); + result := result + ' user=''' + U1 + ''''; + stringsafefree(u1,false); + end; + if (P <> '') then begin + p1:= ansistring(p); + result:= result + ' password=''' + P1 + ''''; + stringsafefree(p1,false); + end; + freecredentials(u,p); + if (HostName <> '') then begin + result:= result + ' host=''' + ansistring(HostName) + ''''; + end; + if (DatabaseName <> '') then begin + result:= result + ' dbname=''' + ansistring(DatabaseName) + ''''; + end + else begin + result:= result + ' dbname=''' + 'postgres' + ''''; + end; + if (Params.Text <> '') then begin + result:= result + ' '+Params.Text; + end; +end; + +procedure TPQConnection.DoInternalConnect; +var +// msg: string; + bo1: boolean; +// int1: integer; +begin +{$IfDef LinkDynamically} + InitializePostgres3([]); +{$EndIf} + ftransactionconnectionused:= false; + inherited dointernalconnect; + fconnectstring:= constructconnectstring; + openconnection(fconnectstring,fhandle); +// This does only work for pg>=8.0, so timestamps won't work with earlier versions of pg which are compiled with integer_datetimes on + if {$ifndef FPC}@{$endif}pqparameterstatus <> nil then begin + FIntegerDatetimes := pqparameterstatus(FHandle,'integer_datetimes') = 'on'; + end; + bo1:= fconnected; + fconnected:= true; + feventcontroller.connect; + fconnected:= bo1; +end; + +procedure TPQConnection.DoInternalDisconnect; +//var +// int1: integer; +begin + feventcontroller.disconnect; + inherited; + closeconnection(fhandle); +{$IfDef LinkDynamically} + ReleasePostgres3; +{$EndIf} +end; + +procedure TPQConnection.createdatabase(const asql: ansistring); +var + conn: ppgconn; +begin +{$IfDef LinkDynamically} + InitializePostgres3([]); +{$EndIf} + try + openconnection(constructconnectstring,conn); + dopqexec(asql,conn); + closeconnection(conn); + finally + {$IfDef LinkDynamically} + ReleasePostgres3; + {$EndIf} + end; +end; + +function TPQConnection.TranslateFldType(Type_Oid : integer; + out isarray: boolean; out vartype: word) : TFieldType; + +begin + isarray:= false; + vartype:= 0; + case Type_Oid of + Oid_varchar,Oid_bpchar, + Oid_name: begin + Result:= ftstring; + end; + Oid_varchar_ar,Oid_bpchar_ar, + Oid_name_ar: begin + Result:= ftstring; + isarray:= true; + vartype:= varolestr; + end; + Oid_text: begin + Result:= ftstring; + end; + Oid_text_ar: begin + Result:= ftstring; + isarray:= true; + vartype:= varolestr; + end; + Oid_bytea: begin + result:= ftBlob; + end; + Oid_bytea_ar: begin + result:= ftBlob; + isarray:= true; + end; + Oid_oid: begin + Result:= ftInteger; + end; + Oid_oid_ar: begin + Result:= ftInteger; + isarray:= true; + vartype:= varinteger; + end; + Oid_int8: begin + Result:= ftLargeInt; + end; + Oid_int8_ar: begin + Result:= ftLargeInt; + isarray:= true; + vartype:= varint64; + end; + Oid_int4: begin + Result:= ftInteger; + end; + Oid_int4_ar: begin + Result:= ftInteger; + isarray:= true; + vartype:= varinteger; + end; + Oid_int2: begin + Result:= ftSmallInt; + end; + Oid_int2_ar: begin + Result:= ftSmallInt; + isarray:= true; + vartype:= varinteger; + end; + Oid_Float4,Oid_Float8: begin + Result:= ftFloat; + end; + Oid_Float4_ar,Oid_Float8_ar: begin + Result:= ftFloat; + isarray:= true; + vartype:= vardouble; + end; + Oid_TimeStamp: begin + Result:= ftDateTime; + end; + Oid_TimeStamp_ar: begin + Result:= ftDateTime; + isarray:= true; + vartype:= vardate; + end; + Oid_Date: begin + Result:= ftDate; + end; + Oid_Date_ar: begin + Result:= ftDate; + isarray:= true; + vartype:= vardate; + end; + Oid_Time: begin + Result:= ftTime; + end; + Oid_Time_ar: begin + Result:= ftTime; + isarray:= true; + vartype:= vardate; + end; + Oid_Bool: begin + Result:= ftBoolean; + end; + Oid_Bool_ar: begin + Result:= ftBoolean; + isarray:= true; + vartype:= varboolean; + end; + Oid_Numeric: begin + Result:= ftBCD; + end; + Oid_Numeric_ar: begin + Result:= ftBCD; + isarray:= true; + vartype:= varcurrency; + end; + oid_uuid: begin + result:= ftguid; + end; + oid_uuid_ar: begin + result:= ftguid; + isarray:= true; + vartype:= varstring; + end; + Oid_Unknown: begin + Result:= ftUnknown; + end; + else begin + Result:= ftUnknown; + end; + end; +end; + +Function TPQConnection.AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; +begin + result:= TPQCursor.create(aowner,aname); +end; + +Procedure TPQConnection.DeAllocateCursorHandle(var cursor : TSQLCursor); + +begin + FreeAndNil(cursor); +end; + +Function TPQConnection.AllocateTransactionHandle : TSQLHandle; + +begin + result:= TPQTrans.create; +end; + +procedure tpqconnection.preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); + +const TypeStrings : array[TFieldType] of string = + ( + 'Unknown', //ftUnknown + 'varchar', //ftString + 'int', //ftSmallint + 'int', //ftInteger + 'int', //ftWord + 'bool', //ftBoolean + 'float', //ftFloat + 'numeric', //ftCurrency + 'numeric', //ftBCD + 'date', //ftDate + 'time', //ftTime + 'timestamp',//ftDateTime + 'Unknown', //ftBytes + 'Unknown', //ftVarBytes + 'Unknown', //ftAutoInc + 'bytea', //ftBlob + 'text', //ftMemo + 'bytea', //ftGraphic + 'Unknown', //ftFmtMemo + 'Unknown', //ftParadoxOle + 'Unknown', //ftDBaseOle + 'Unknown', //ftTypedBinary + 'Unknown', //ftCursor + 'varchar', //ftFixedChar + 'varchar', //ftWideString + 'bigint', //ftLargeint + 'Unknown', //ftADT + 'Unknown', //ftArray + 'Unknown', //ftReference + 'Unknown', //ftDataSet + 'Unknown', //ftOraBlob + 'Unknown', //ftOraClob + 'Unknown', //ftVariant + 'Unknown', //ftInterface + 'Unknown', //ftIDispatch + 'uuid', //ftGuid + 'Unknown', //ftTimeStamp + 'Unknown' //ftFMTBcd + ,'varchar', //ftFixedWideChar + 'Unknown' //ftWideMemo + ); + +const + savepoint = 'mseinternal$prep;'; +var + s: string; + i: integer; + str1: string; + bo1: boolean; + n: integer; +begin + with TPQCursor(cursor) do begin + if tpqtrans(atransaction.trans).fconn = nil then begin + tpqtrans(atransaction.trans).fconn:= fhandle; //fake transaction + end; + FPrepared := False; + // Prior to v8 there is no support for cursors and parameters. + // So that's not supported. + if FStatementType in [stInsert,stUpdate,stDelete,stSelect] then begin + tr:= TPQTrans(aTransaction.Handle); + repeat + n:= interlockedincrement(fcursorcount) and $ffffff; + //limit range 0..167774655 + nr:= inttostr(n); + // Only available for pq 8.0, so don't use it... + // Res := pqprepare(tr,'prepst'+name+nr,pchar(buf),params.Count,pchar('')); + s:= 'prepare prepst'+nr+' '; + if Assigned(AParams) and (AParams.count > 0) then begin + s:= s + '('; + for i := 0 to AParams.count-1 do begin + with AParams[i] do begin + if datatype = ftvariant then begin + s:= s+'unknown,'; + end + else begin + if TypeStrings[DataType] <> 'Unknown' then begin + s:= s + TypeStrings[DataType] + ',' + end + else begin + if DataType = ftUnknown then begin + DatabaseErrorFmt(SUnknownParamFieldType,[Name],self); + end + else begin + DatabaseErrorFmt(SUnsupportedParameter, + [Fieldtypenames[DataType]],self); + end; + end; + end; + end; + end; + s[length(s)]:= ')'; + str1:= todbstring(AParams.ParseSQL(asql,false,false,false,psPostgreSQL)); + end + else begin + str1:= todbstring(asql); + end; + s:= s + ' as ' + str1; + pqexec(tr.fconn,'SAVEPOINT '+savepoint); + res := pqexec(tr.fconn,pchar(s)); + bo1:= (PQresultStatus(res) = PGRES_COMMAND_OK); + if not bo1 then begin + pqexec(tr.fconn,'ROLLBACK TO SAVEPOINT '+savepoint); + end + else begin + pqexec(tr.fconn,'RELEASE SAVEPOINT '+savepoint); + end; + until bo1 or + (strpas(pqresulterrorfield(res,ord(pg_diag_sqlstate))) <> '42P05'); + //no duplicate_prepared_statement + if (PQresultStatus(res) <> PGRES_COMMAND_OK) then begin + s:= ansistring(connectionmessage(pqresulterrormessage(res))); + pqclear(res); + DatabaseError(SErrPrepareFailed + lineend + + ' (PostgreSQL: ' + s + ')',self) + end; + FPrepared := True; + end + else begin + Statementm:= {todbstring(}AParams.ParseSQL(asql,false,false,false,psSimulated, + paramBinding,ParamReplaceString){)}; +// statement := buf; + end; + end; +end; + +procedure TPQConnection.UnPrepareStatement(cursor : TSQLCursor); + +begin + with tpqcursor(cursor) do begin + if FPrepared then begin + close; +// if not tr.ErrorOccured then begin + res := pqexec(tr.fconn,pchar('deallocate prepst'+nr)); + if (PQresultStatus(res) <> PGRES_COMMAND_OK) then begin + pqclear(res); + rollback(tr); + res := pqexec(tr.fconn,pchar('deallocate prepst'+nr)); + { + DatabaseError(SErrPrepareFailed + ' (PostgreSQL: ' + + PQerrorMessage(tr.fconn) + ')',self) + } + end; + //problem with aborted transaction + pqclear(res); +// end; + FPrepared := False; + end; + end; +end; + +procedure TPQConnection.FreeFldBuffers(cursor : TSQLCursor); + +begin +// Do nothing +end; + +procedure TPQConnection.internalExecute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; const AParams : TmseParams; + const autf8: boolean); + +var + ar: array of pointer; + i: integer; + s: string; + lengths,formats: integerarty; + mstr1: msestring; + +begin + with TPQCursor(cursor) do begin + frowsreturned:= -1; + frowsaffected:= -1; + curtuple:= -1; + if FStatementType in [stInsert,stUpdate,stDelete,stSelect] then begin + if Assigned(AParams) and (AParams.count > 0) then begin + setlength(ar,Aparams.count); + setlength(lengths,length(ar)); + setlength(formats,length(ar)); + for i := 0 to AParams.count -1 do begin + with AParams[i] do begin + if not IsNull then begin + case DataType of + ftdatetime: s:= formatdatetime('YYYY-MM-DD hh:nn:ss',AsDateTime); + ftdate: s:= formatdatetime('YYYY-MM-DD',AsDateTime); + fttime: s:= formatdatetime('hh:nn:ss',AsDateTime); + ftfloat,ftcurrency: s:= realtostr(asfloat); + ftbcd: s:= realtostr(ascurrency); + ftvariant: begin + if isutf8 then begin + s:= stringtoutf8ansi(encodesqlvariant(value,true)); + end + else begin + s:= ansistring(encodesqlvariant(value,true)); + end; + end; + else begin + s:= AParams.asdbstring(i); + if datatype = ftblob then begin + formats[i]:= 1; //binary + end; + end; + end; {case} + lengths[i]:= length(s); + GetMem(ar[i],length(s)+1); + StrMove(PChar(ar[i]),Pchar(s),Length(S)+1); + end; + end; + end; + res := PQexecPrepared(tr.fconn,pchar('prepst'+nr),Aparams.count,@Ar[0], + pointer(lengths),pointer(formats),1); + for i := 0 to AParams.count -1 do begin + FreeMem(ar[i]); + end; + end + else begin + res:= PQexecPrepared(tr.fconn,pchar('prepst'+nr),0,nil,nil,nil,1); + end; + end + else begin + tr := TPQTrans(cursor.ftrans); + if aparams <> nil then begin + mstr1:= aparams.expandvalues(statementm,parambinding,paramreplacestring); + end + else begin + mstr1:= statementm; + end; + if autf8 then begin + s:= stringtoutf8ansi(mstr1); + end + else begin + s:= ansistring(mstr1); + end; + res:= pqexec(tr.fconn,pchar(s)); + end; + frowsaffected:= strtointdef(pqcmdtuples(res),-1); + checkerror(tr.fconn,res,'Execution of query failed'); + frowsreturned:= pqntuples(res); + fopen:= true; + end; +end; + +procedure tpqconnection.internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); +begin + with TPQCursor(cursor) do begin + tr := TPQTrans(cursor.ftrans); + frowsreturned:= -1; + frowsaffected:= -1; + curtuple:= -1; +// res:= pqexec(tr.fconn,pchar(asql)); + res:= pqexecparams(tr.fconn,pchar(asql),0,nil,nil,nil,nil,1); + + frowsaffected:= strtointdef(pqcmdtuples(res),-1); + checkerror(tr.fconn,res,'Execution of query failed'); + frowsreturned:= pqntuples(res); + fopen:= true; + end; +end; + +procedure TPQConnection.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); +var + i: integer; + size: integer; +// st: string; + fieldtype: tfieldtype; + nFields: integer; + fd: tfielddef; + str1: ansistring; + int1: integer; + precision: integer; + isarray: boolean; +begin + precision:= 0; + fielddefs.clear; + with tpqcursor(cursor) do begin + nFields:= PQnfields(Res); + setlength(arrayinfo,nfields); + for i:= 0 to nFields-1 do begin + fieldtype:= TranslateFldType(PQftype(Res,i),isarray,arrayinfo[i].vartype); + arrayinfo[i].fieldtype:= fieldtype; + if isarray then begin + fieldtype:= ftvariant; + size:= 0; + end + else begin + size:= PQfsize(Res,i); + case fieldtype of + ftstring: begin + if size = -1 then begin + size:= pqfmod(res,i)-4; + if size = -5 then begin //text + if stringmemo then begin + size:= 0; + end + else begin + fieldtype:= ftmemo; + size:= blobidsize; + end; + end; + end; + end; + ftdate: begin + size:= sizeof(double); + end; + ftblob,ftmemo: begin + size:= blobidsize; + end; + ftbcd: begin + int1:= PQfmod(Res,i) - varhdrsz; //can be -1 - 4 = -5 + size:= int1 and $ffff; + precision:= int1 and $ffff0000 shr 16; + if (dbo_bcdtofloatif in controller.options) and (size > 4) then begin + //for pqfmod = -1 too + fieldtype:= ftfloat; + end + else begin + if size > 4 then begin + size:= 4; + end; + end; + end; + end; + end; + str1:= PQfname(Res,i); + if not(fieldtype in varsizefields) then begin + size:= 0; + end; + fd:= TFieldDef.Create(nil,str1,fieldtype,size,False,(i+1)); + fd.collection:= fielddefs; + if fieldtype = ftbcd then begin + if precision > maxprecision then begin + precision:= maxprecision; + end; + fd.precision:= precision; + end; + end; + end; +end; + +function TPQConnection.GetHandle: pointer; +begin + Result := FHandle; +end; + +function TPQConnection.Fetch(cursor : TSQLCursor) : boolean; + +//var st : string; + +begin + with cursor as TPQCursor do + begin + inc(CurTuple); + Result := (PQntuples(res)>CurTuple); + end; +end; + +type + arraytypeheaderty = record +// size: integer; // total array size (varlena requirement) + ndim: cint; // # of dimensions + flags: cint; // implementation flags + // flags field is currently unused, always zero. + elemtype: oid; // element type OID + end; + arraytype = record + header: arraytypeheaderty; + data: record + //dim: array[ndim] of cint; + // size of each array axis (C array of int) + //dim_lower: array[ndim] of cint; + // lower boundary of each dimension (C array of int) + // // whatever is the stored data + end; + end; + parraytype = ^arraytype; + + vararrayboundarty = array of tvararraybound; + +type + TNumericRecord = record + Digits : SmallInt; + Weight : SmallInt; + Sign : SmallInt; + Scale : Smallint; + end; + pnumericrecord = ^tnumericrecord; + +function tpqconnection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //zero based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize + + +const + numericpos = $0000; + numericneg = $4000; + numericnan = $8000; + numericsigmask = $c000; + +var +// x{,i} : integer; + CurrBuff : pchar; + + function getnumeric(out numericrecord: tnumericrecord): boolean; + begin + NumericRecord.Digits := BEtoN(pNumericRecord(currbuff)^.Digits); + NumericRecord.Scale := BEtoN(pNumericRecord(currbuff)^.Scale); + NumericRecord.Weight := BEtoN(pNumericRecord(currbuff)^.Weight); + numericrecord.sign:= beton(pnumericrecord(currbuff)^.sign); + inc(currbuff,sizeof(TNumericRecord)); + result:= numericrecord.sign and numericnan = 0; +// if (NumericRecord^.Digits = 0) and (NumericRecord^.Scale = 0) then +// = NaN, which is not supported by Currency-type, so we return NULL + //???? 0 in database seems to return digits and scale 0. mse + end; + + function getfloat4: single; + var + si1: single; + begin + {$ifdef FPC} + integer(si1):= beton(pinteger(currbuff)^); + {$else} + integer(ar4ty(si1)):= beton(pinteger(currbuff)^); + {$endif} + result:= si1; + end; + + function getfloat8: double; + begin + {$ifdef FPC} + int64(result):= beton(pint64(currbuff)^); + {$else} + int64(ar8ty(result)):= beton8(pint64(currbuff)^); + {$endif} + end; + + procedure handleitem(const adatatype: tfieldtype;{ const currbuff: pointer;} + const asize: integer; const atype: integer; var buffer: pchar); + var + li : Longint; +// dbl : pdouble; + cur : currency; + lint1: int64; +// sint1: smallint; + wbo1: wordbool; + do1: double; + int1: integer; + tel: byte; + numericrecord: tnumericrecord; + str1: string; + begin + with TPQCursor(cursor) do begin + case aDataType of + ftInteger,ftSmallint,ftword: begin + int1:= 0; + case asize of // postgres returns big-endian numbers + sizeof(integer): begin + int1:= BEtoN(pinteger(CurrBuff)^); + end; + sizeof(smallint): begin + int1:= BEtoN(psmallint(CurrBuff)^); + end; + end; + move(int1,buffer^,sizeof(int1)); + inc(buffer,sizeof(integer)); + inc(currbuff,asize); + end; + ftlargeint: begin + {$ifdef FPC} + lint1:= BEtoN(pint64(CurrBuff)^); + {$else} + lint1:= BEtoN8(pint64(CurrBuff)^); + {$endif} + move(lint1,buffer^,sizeof(lint1)); + inc(buffer,sizeof(int64)); + inc(currbuff,asize); + end; + ftfloat,ftcurrency: begin + if atype = oid_numeric then begin + if getnumeric(numericrecord) then begin + do1:= 0; + for int1 := NumericRecord.Digits - 1 downto 0 do begin + do1:= do1 + beton(pword(currbuff)^) * intpower(nbase,int1); + inc(currbuff,2); + end; + int1:= numericrecord.weight - numericrecord.digits + 1; + if int1 < 0 then begin + do1:= do1 / intpower(nbase,-int1); + end + else begin + do1:= do1 * intpower(nbase,int1); + end; + if NumericRecord.Sign <> 0 then begin + do1:= -do1; + end; + end + else begin + do1:= nan; + end; + end + else begin + if atype = oid_float4 then begin + do1:= getfloat4; + end + else begin + do1:= getfloat8; + end; + end; + Move(do1, Buffer^, sizeof(do1)); + inc(buffer,sizeof(do1)); + inc(currbuff,asize); + end; + ftString: begin + if datatype = ftvariant then begin + setlength(str1,asize); + move(currbuff^,str1[1],asize); + if aisutf8 then begin + pwidestring(buffer)^:= utf8tostringansi(str1); + end + else begin + pwidestring(buffer)^:= msestring(str1); + end; + inc(buffer,sizeof(widestring)); + inc(currbuff,asize); + end + else begin + li:= pqgetlength(res,curtuple,fieldnum); + if bufsize < li then begin + bufsize:= -li; + end + else begin + bufsize:= li; + Move(CurrBuff^,Buffer^,li); + end; + end; + end; + ftblob,ftmemo,ftgraphic: begin + li := pqgetlength(res,curtuple,fieldnum); + int1:= addblobdata(currbuff,li); + move(int1,buffer^,sizeof(int1)); + //save id + end; + ftdate: begin + do1:= BEtoN(plongint(CurrBuff)^) + 36526; + move(do1,buffer^,sizeof(do1)); + inc(buffer,sizeof(do1)); + inc(currbuff,asize); + end; + ftDateTime,fttime: begin + {$ifdef FPC} + do1:= double(BEtoN(pint64(CurrBuff)^)); + {$else} + do1:= double(ar8ty(BEtoN8(pint64(CurrBuff)^))); + {$endif} + if FIntegerDatetimes then begin + do1:= do1/1000000; + end; + do1:= (do1+3.1558464E+009)/86400; // postgres counts seconds elapsed since 1-1-2000 + // Now convert the mathematically-correct datetime to the + // illogical windows/delphi/fpc TDateTime: + if (do1 <= 0) and (frac(do1)<0) then begin + do1:= trunc(do1)-2-frac(do1); + end; + move(do1,buffer^,sizeof(do1)); + inc(buffer,sizeof(do1)); + inc(currbuff,asize); + end; + ftBCD: begin + + case atype of + oid_float4: begin + cur:= getfloat4; + end; + oid_float8: begin + cur:= getfloat8; + end; + else begin + cur := 0; + result:= getnumeric(numericrecord); + if result then begin + for tel := 1 to NumericRecord.Digits do begin + cur := cur + beton(pword(currbuff)^) * intpower(10000,-(tel-1)+ + NumericRecord.weight); + inc(currbuff,2); + end; + if NumericRecord.Sign <> 0 then begin + cur := -cur; + end; + end; + end; + end; + Move(Cur, Buffer^, sizeof(cur)); + inc(buffer,sizeof(cur)); +// inc(currbuff,asize); + end; + ftBoolean: begin + if datatype = ftvariant then begin + pboolean(buffer)^:= CurrBuff[0] <> #0; + inc(buffer,sizeof(boolean)); + end + else begin + wbo1:= CurrBuff[0] <> #0; + move(wbo1,buffer^,sizeof(wbo1)); + inc(buffer,sizeof(wbo1)); + end; + inc(currbuff,asize); + end; + ftguid: begin + {$ifdef FPC} + with pguid(currbuff)^ do begin + pguid(buffer)^.time_low:= beton(time_low); + pguid(buffer)^.time_mid:= beton(time_mid); + pguid(buffer)^.time_hi_and_version:= beton(time_hi_and_version); + pguid(buffer)^.clock_seq_hi_and_reserved:= clock_seq_hi_and_reserved; + pguid(buffer)^.clock_seq_low:= clock_seq_low; + pguid(buffer)^.node:= node; + end; + {$else} + with pguid_fpc(currbuff)^ do begin + pguid_fpc(buffer)^.time_low:= beton(time_low); + pguid_fpc(buffer)^.time_mid:= beton(time_mid); + pguid_fpc(buffer)^.time_hi_and_version:= beton(time_hi_and_version); + pguid_fpc(buffer)^.clock_seq_hi_and_reserved:= clock_seq_hi_and_reserved; + pguid_fpc(buffer)^.clock_seq_low:= clock_seq_low; + pguid_fpc(buffer)^.node:= node; + end; + {$endif} + inc(buffer,sizeof(tguid)); + inc(currbuff,asize); + end; + else begin + result := false; + end; + end; + end; + end; + +var + int1,int2,int3,eltype: integer; + typ1: tfieldtype; + ar1: vararrayboundarty; + po1: pcint; + po2: pointer; + +begin +{$ifdef FPC}{$checkpointer off}{$endif} + with TPQCursor(cursor) do begin + result:= pqgetisnull(res,CurTuple,fieldnum) = 0; + if not result or (buffer = nil) then begin + exit; + end; + CurrBuff := pqgetvalue(res,CurTuple,fieldnum); + if datatype = ftvariant then begin + with parraytype(currbuff)^,header do begin +// int1:= pqgetlength(res,curtuple,fieldnum); + setlength(ar1,beton(ndim)); + if ar1 = nil then begin + result:= false; + exit; + end; + po1:= @data; + int2:= 1; + for int1:= 0 to high(ar1) do begin + int3:= beton(po1^); + ar1[int1].elementcount:= int3; //dim + inc(po1); + ar1[int1].lowbound:= beton(po1^); //dim_lower + int2:= int2*int3; + inc(po1); + end; +// inc(po1,length(ar1)); //skip dim_lower + eltype:= beton(elemtype); + currbuff:= pointer(po1); + typ1:= arrayinfo[fieldnum].fieldtype; + pvariant(buffer)^:= msevararraycreate(pointer(ar1),length(ar1), + arrayinfo[fieldnum].vartype); + po2:= pvardata(buffer)^.varray^.data; + for int1:= 0 to int2-1 do begin + int3:= beton(pinteger(currbuff)^); //alignment? + inc(pinteger(currbuff)); + handleitem(typ1,int3,eltype,pchar(po2)); + end; + end; + end + else begin + po2:= buffer; + handleitem(datatype,{currbuff,}PQfsize(res,fieldnum),pqftype(res,fieldnum), + pchar(po2)); + end; + end; +{$ifdef FPC}{$checkpointer default}{$endif} +end; + +function TPQConnection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +begin + result:= ''; +{$ifdef FPC}{$checkpointer off}{$endif} + with TPQCursor(cursor) do begin + if pqgetisnull(res,CurTuple,fieldnum) <> 1 then begin + setlength(result,pqgetlength(res,curtuple,fieldnum)); + if result <> '' then begin + move(pqgetvalue(res,CurTuple,fieldnum)^,result[1],length(result)); + end; + end; + end; +end; + +procedure tpqconnection.updateindexdefs(var indexdefs : tindexdefs; + const atablename : string; const acursor: tsqlcursor); + +var + qry : tsqlresult; +begin + if not assigned(transaction) then + databaseerror(serrconntransactionnset); + + qry:= tsqlresult.create(nil); + try + with qry do begin + database:= self; + sql.text:= 'select '+ + 'ic.relname as indexname, '+ + 'tc.relname as tablename, '+ + 'ia.attname, '+ + 'i.indisprimary, '+ + 'i.indisunique '+ + 'from '+ + 'pg_attribute ta, '+ + 'pg_attribute ia, '+ + 'pg_class tc, '+ + 'pg_class ic, '+ + 'pg_index i '+ + 'where '+ + '(i.indrelid = tc.oid) and '+ + '(ta.attrelid = tc.oid) and '+ + '(ia.attrelid = i.indexrelid) and '+ + '(ic.oid = i.indexrelid) and '+ + '(ta.attnum = i.indkey[ia.attnum-1]) and '+ + '(upper(tc.relname)=''' + + msestring(UpperCase(aTableName)) +''') '+ + 'order by '+ + 'ic.relname;'; + active:= true; + while not eof do begin + with IndexDefs.AddIndexDef do begin + Name:= trim(qry.cols[0].asstring); + Fields:= trim(qry.cols[2].asstring); + If cols[3].asboolean then begin + options:= options + [ixPrimary]; + end; + If cols[4].asboolean then begin + options:= options + [ixUnique]; + end; + next; + while not qry.eof and (name = cols[0].asstring) do begin + fields:= fields + ';' + trim(cols[2].asstring); + next; + end; + end; + end; + end; + finally + qry.free; + end; +end; + +function TPQConnection.GetSchemaInfoSQL(SchemaType: TSchemaType; + SchemaObjectName, SchemaPattern: msestring): msestring; + +var s : msestring; + +begin + s:= ''; + case SchemaType of + stTables : s := 'select '+ + 'relfilenode as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'relname as table_name, '+ + '0 as table_type '+ + 'from '+ + 'pg_class '+ + 'where '+ + '(relowner > 1) and relkind=''r''' + + 'order by relname'; + + stSysTables : s := 'select '+ + 'relfilenode as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'relname as table_name, '+ + '0 as table_type '+ + 'from '+ + 'pg_class '+ + 'where '+ + 'relkind=''r''' + + 'order by relname'; + else + DatabaseError(SMetadataUnavailable) + end; {case} + result := s; +end; + +function TPQConnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +var + blobid: integer; +// int1,int2: integer; +// str1: string; +// bo1: boolean; +begin + result:= nil; + if mode = bmread then begin + if field.getData(@blobId) then begin + result:= acursor.getcachedblob(blobid); + end; + end; +end; + +procedure TPQConnection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); +var + str1: string; + int1: integer; +begin + setlength(str1,alength); + move(adata^,str1[1],alength); + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + int1:= acursor.addblobdata(str1); + setlength(newid,sizeof(int1)); + move(int1,newid[1],sizeof(int1)); +end; + +procedure TPQConnection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +begin + acursor.blobfieldtoparam(afield,aparam,false); +end; +{ +function TPQConnection.getfeatures(): databasefeaturesty; +begin + result:= inherited getfeatures() + [dbf_blobscached]; +end; +} +function TPQConnection.getblobdatasize: integer; +begin + result:= sizeof(integer); +end; +{ +function TPQConnection.blobscached: boolean; +begin + result:= true; +end; +} +procedure TPQConnection.dolisten(const sender: tdbevent); +begin + dopqexec('LISTEN '+sender.eventname+';'); +end; + +procedure TPQConnection.dounlisten(const sender: tdbevent); +begin + dopqexec('UNLISTEN '+sender.eventname+';'); +end; + +procedure TPQConnection.listen(const sender: tdbevent); +begin + feventcontroller.register(sender); + if connected then begin + dolisten(sender); + end; +end; + +procedure TPQConnection.unlisten(const sender: tdbevent); +begin + if connected then begin + dounlisten(sender); + end; + feventcontroller.unregister(sender); +end; + +procedure TPQConnection.fire(const sender: tdbevent); +begin + dopqexec('NOTIFY '+sender.eventname+';'); +end; + +function TPQConnection.getdbevent(var aname: string; var aid: int64): boolean; +var + info: ppgnotify; +begin + pqconsumeinput(fhandle); + info:= pqnotifies(fhandle); + result:= info <> nil; + if result then begin + aname:= info^.relname; + aid:= info^.be_pid; + pqfreemem(info); + end; +end; + +function TPQConnection.geteventinterval: integer; +begin + result:= feventcontroller.eventinterval; +end; + +procedure TPQConnection.seteventinterval(const avalue: integer); +begin + feventcontroller.eventinterval:= avalue; +end; + +procedure tpqconnection.dopqexec(const asql: ansistring; const aconnection: ppgconn); +var + res: ppgresult; +begin + res:= pqexec(aconnection,pchar(asql)); + if pqresultstatus(res) <> pgres_command_ok then begin + pqclear(res); + databaseerror('PQExecerror'+ ' (postgresql: ' + + ansistring(connectionmessage(pqerrormessage(aconnection))) + + ')',self); + end + else begin + pqclear(res); + end; +end; + +procedure tpqconnection.dopqexec(const asql: ansistring); +begin + dopqexec(asql,fhandle); +end; + +function TPQConnection.backendpid: int64; +begin + if not connected then begin + result:= 0; + end + else begin + result:= pqbackendpid(fhandle); + end; +end; + +function TPQConnection.getnumboolean: boolean; +begin + result:= false; +end; + +procedure TPQConnection.closeconnection(var aconnection: ppgconn); +begin + if aconnection <> nil then begin + PQfinish(aconnection); + aconnection:= nil; + end; +end; + +procedure TPQConnection.finalizetransaction(const atransaction: tsqlhandle); +begin + with tpqtrans(atransaction) do begin + if (fconn <> fhandle) then begin + closeconnection(fconn); + end; + fconn:= nil; + end; +end; + +{ +procedure TPQConnection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const adata: pointer; + const alength: integer; const aparam: tparam); + +var + started: boolean; + + procedure endtrans; + var + res: ppgresult; + begin + res:= pqexec(fsqldatabasehandle,'END'); + pqclear(res); + end; + + procedure doerror; + begin + if started then begin + endtrans; + end; + databaseerror('TPQConnection blob write error.'); + end; + + procedure checkerror(const aresult: ppgresult); + begin + if PQresultStatus(aresult) <> PGRES_COMMAND_OK then begin + pqclear(aresult); + doerror; + end; + pqclear(aresult); + end; + +var + blobid: oid; + fd: integer; + int1,int2: integer; +begin + if alength = 0 then begin + aparam.clear; + end + else begin + started:= false; + checkerror(pqexec(fsqldatabasehandle,'BEGIN')); + started:= true; + blobid:= lo_creat(fsqldatabasehandle,inv_read or inv_write); + if blobid = invalidoid then begin + doerror; + end; + fd:= lo_open(fsqldatabasehandle,blobid,inv_write); + if fd = -1 then begin + doerror; + end; + int1:= alength; + while int1 > 0 do begin + int2:= lo_write(fsqldatabasehandle,fd,adata,int1); + if int2 < 0 then begin + doerror; + end; + dec(int1,int2); + end; + lo_close(fsqldatabasehandle,fd); + endtrans; + aparam.asinteger:= blobid; + end; +end; +} + +{ epqerror } + +constructor epqerror.create(const asender: tcustomsqlconnection; + const amessage: ansistring; const aerrormessage: msestring; + const asqlcode: string); +begin + fsqlcode:= asqlcode; + inherited create(asender,amessage,aerrormessage,-1); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msebufdataset.pas b/mseide-msegui/lib/common/db/msebufdataset.pas new file mode 100644 index 0000000..5b03789 --- /dev/null +++ b/mseide-msegui/lib/common/db/msebufdataset.pas @@ -0,0 +1,10892 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 1999-2000 by Michael Van Canneyt, member of the + Free Pascal development team + + + BufDataset implementation + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + Rewritten 2006-2018 by Martin Schreiber + + **********************************************************************} + +unit msebufdataset; +{$ifdef FPC} + {$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba} + {$define mse_hasvtunicodestring} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mdb,classes,mclasses,variants,msetypes,msearrayprops,mseclasses,mselist, + msestrings, + msedb,msedatabase,mseglob,msearrayutils,msedatalist,msevariants, + msestream; + +const + defaultpacketrecords = -1; + integerindexfields = [ftsmallint,ftinteger,ftword,ftboolean]; + largeintindexfields = [ftlargeint]; + floatindexfields = [ftfloat,{ftcurrency,}ftdatetime,ftdate,fttime]; + currencyindexfields = [ftcurrency,ftbcd]; + stringindexfields = [ftstring,ftfixedchar]; + guidindexfields = [ftguid]; + indexfieldtypes = integerindexfields+largeintindexfields+floatindexfields+ + currencyindexfields+stringindexfields+guidindexfields; + dsbuffieldkinds = [fkcalculated,fklookup]; + bufferfieldkinds = [fkdata]; + + dscheckfilter = ord(high(tdatasetstate)) + 1; + +const + bufstreambuffersize = 4096; + +type + + fieldinfo_0ty = record //version 0 + offset: integer; //data offset in buffer //// + size: integer; //size in buffer // checked by save/restore + fieldtype: tfieldtype; // + dbfieldsize: integer; //maxsize of dbfield //// + {$ifdef cpu64} + field: card32; + {$else} + field: tfield; //last! + {$endif} + end; + + fieldinfobasety = record + offset: integer; //data offset in buffer //// + size: integer; //size in buffer // checked by save/restore + fieldtype: tfieldtype; // + dbfieldsize: integer; //maxsize of dbfield //// + end; + pfieldinfobasety = ^fieldinfobasety; + + fieldinfoextty = record + basetype: tfieldtype; + field: tfield; + uppername: string; + end; + fieldinfoty = record + base: fieldinfobasety; + ext: fieldinfoextty; + end; + + fieldinfoarty = array of fieldinfoty; + + fielddataty = record + nullmask: array[0..0] of byte; //variable length + //fielddata following + end; + + blobcacheinfoty = record + id: int64; + data: string; + end; + blobcacheinfoarty = array of blobcacheinfoty; + + blobinfoty = record + field: tfield; + data: pointer; + datalength: integer; + new: boolean; + end; + + pblobinfoty = ^blobinfoty; + blobinfoarty = array of blobinfoty; + pblobinfoarty = ^blobinfoarty; + + blobstreamfixinfoty = record + id: int64; + new: boolean; + current: boolean; + end; + blobstreaminfoty = record + info: blobstreamfixinfoty; + data: string; + end; + + recheaderty = record + blobinfo: blobinfoarty; + fielddata: fielddataty; + end; + precheaderty = ^recheaderty; + pprecheaderty = ^precheaderty; + + intheaderty = record + end; + + intrecordty = record + intheader: intheaderty; + header: recheaderty; + end; + pintrecordty = ^intrecordty; + ppintrecordty = ^pintrecordty; + + bookmarkdataty = record + recno: integer; + recordpo: pintrecordty; + end; + pbookmarkdataty = ^bookmarkdataty; + + bufbookmarkty = record + data: bookmarkdataty; + flag : tbookmarkflag; + end; + pbufbookmarkty = ^bufbookmarkty; + + dsheaderty = record + bookmark: bufbookmarkty; + end; + dsrecordty = record + dsheader: dsheaderty; + header: recheaderty; + end; + pdsrecordty = ^dsrecordty; + +const + intheadersize = sizeof(intheaderty); + dsheadersize = sizeof(dsheaderty); + +// structure of internal recordbuffer: +// +------------------+ +// intrecheaderty, |recheaderty,nullflags,fielddata| +// |moved to tdataset buffer header| +// |fieldoffsets are in ffieldinfos[].offset +// | | +// structure of dataset recordbuffer: +// +-----------------------------------+ +// +------------------+ | +// dsrecheaderty, |recheaderty,nullflags,fielddata|nullflags,calcfields| +// |moved to internal buffer header| | +// |<-field offsets are in ffieldinfos[].offset | +// |<-calcfield offsets are in fcalcfieldbufpositions | + +type + indexty = record + ind: pointerarty; + end; + pindexty = ^indexty; + + tmsebufdataset = class; + + logflagty = (lf_end,lf_rec,lf_update,lf_cancel,lf_apply,lf_drop); + reclogheader32ty = record + kind: tupdatekind; + po: card32; + end; +{$packrecords 8} + reclogheaderty = record + kind: tupdatekind; + po: card64; //pointer; + end; +{$packrecords default} + updatekindty = (uk_modify=ord(ukmodify),uk_insert=ord(ukinsert), + uk_delete=ord(ukdelete),uk_modifyinupdate); + updatelogheader32ty = record + logging: boolean; + kind: updatekindty; + po: card32; + deletedrecord: card32; + end; +{$packrecords 8} //64 bit compatible + updatelogheaderty = record + logging: boolean; + kind: updatekindty; + po: card64; //pointer; + deletedrecord: card64; //pintrecordty; + end; +{$packrecords default} + logbufferheader32ty = record + case logflag: logflagty of + lf_rec: ( + rec: reclogheader32ty; + ); + lf_update,lf_cancel,lf_apply,lf_drop: ( + update: updatelogheader32ty; + ); + end; +{$packrecords 8} //64 bit compatible + logbufferheaderty = record + case logflag: logflagty of + lf_rec: ( + rec: reclogheaderty; + ); + lf_update,lf_cancel,lf_apply,lf_drop: ( + update: updatelogheaderty; + ); + end; +{$packrecords default} + + tbufstreamwriter = class + private + fstream: tstream; + fowner: tmsebufdataset; + fbuffer: array [0..bufstreambuffersize-1] of byte; + fbufindex: integer; + procedure flushbuffer; + public + constructor create(const aowner: tmsebufdataset; const astream: tstream); + destructor destroy; override; + procedure write(const buffer; length: integer); + procedure writefielddata(const data: precheaderty; + const aindex: integer); + procedure writestring(const avalue: string); + procedure writemsestring(const avalue: msestring); + procedure writeinteger(const avalue: integer); + procedure writepointer(const avalue: pointer); + procedure writevariant(const avalue: variant); + + procedure writefielddef(const afielddef: tfielddef); + procedure writelogbufferheader(const aheader: logbufferheaderty); + procedure writeendmarker; + end; + + tbufstreamreader = class + private + fstream: tstream; + fowner: tmsebufdataset; + fbuffer: array [0..bufstreambuffersize-1] of byte; + fbuflen: integer; + fbufindex: integer; + protected + f32to64: boolean; + public + constructor create(const aowner: tmsebufdataset; const astream: tstream); + function read(out buffer; length: integer): integer; + procedure readbuffer(out buffer; const length: integer); + procedure readfielddata(const data: precheaderty; const aindex: integer); + function readstring: string; + function readmsestring: msestring; + function readinteger: integer; + function readpointer: pointer; + function readvariant: variant; + procedure readfielddef(const aowner: tfielddefs); + function readlogbufferheader(out aheader: logbufferheaderty): boolean; + //false if eof or lf_end + procedure readrecord(const arecord: pintrecordty); + end; + + resolverresponsety = (rr_abort,rr_quiet,rr_revert,rr_again,rr_applied, + rr_skipped); //for fkinternalcalc only updates + resolverresponsesty = set of resolverresponsety; + + updateerroreventty = procedure( + const sender: tmsebufdataset; + var e: edatabaseerror; const updatekind: tupdatekind; + var response: resolverresponsesty) of object; + + tblobbuffer = class(tmemorystream) + private + fowner: tmsebufdataset; + ffield: tfield; + public + constructor create(const aowner: tmsebufdataset; const afield: tfield); + destructor destroy; override; + end; + + tblobcopy = class(tmemorystream) + public + constructor create(const ablob: blobinfoty); + destructor destroy; override; + end; + + indexfieldoptionty = (ifo_desc,ifo_caseinsensitive,ifo_natural); + indexfieldoptionsty = set of indexfieldoptionty; + + tindexfield = class(townedpersistent) + private + ffieldname: string; + foptions: indexfieldoptionsty; + procedure change; + procedure setfieldname(const avalue: string); + procedure setoptions(const avalue: indexfieldoptionsty); + published + property fieldname: string read ffieldname write setfieldname; + property options: indexfieldoptionsty read foptions + write setoptions default []; + end; + + localindexoptionty = (lio_desc,lio_default, + lio_quicksort); //default is mergesort + + localindexoptionsty = set of localindexoptionty; + + tlocalindex = class; + + tindexfields = class(townedpersistentarrayprop) + private + function getitems(const index: integer): tindexfield; + public + constructor create(const aowner: tlocalindex); reintroduce; + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tindexfield read getitems; default; + published + property count default 1; + end; + + intrecordpoaty = array[0..0] of pintrecordty; + pintrecordpoaty = ^intrecordpoaty; + indexfieldinfoty = record + fieldinstance: tfield; + comparefunc: arraysortcomparety; + vtype: integer; + recoffset: integer; + fieldindex: integer; + islookup: boolean; + desc: boolean; + caseinsensitive: boolean; + canpartialstring: boolean; + end; + indexfieldinfoarty = array of indexfieldinfoty; + indexcomparefuncty = function (l,r: pintrecordty; const alastindex: integer; + const apartialstring: boolean): integer of object; + + tlocalindex = class(townedpersistent) + private + ffields: tindexfields; + foptions: localindexoptionsty; + fsortarray: pintrecordpoaty; + findexfieldinfos: indexfieldinfoarty; + finvalid: boolean; + fhaslookup: boolean; + fname: string; + procedure setoptions(const avalue: localindexoptionsty); + procedure setfields(const avalue: tindexfields); + function dolookupcompare(const l,r: pintrecordty; + const ainfo: indexfieldinfoty; + const apartialstring: boolean): integer; + function dolookupcomparea(const lvalue: pointer; r: pintrecordty; + const ainfo: indexfieldinfoty; + const apartialstring: boolean): integer; + //lvalue is compare value, r can be lookup + function compare1(l,r: pintrecordty; const alastindex: integer; + const apartialstring: boolean): integer; + function compare1a(l,r: pintrecordty; const alastindex: integer; + const apartialstring: boolean): integer; + //l is compare value record, r can be lookup + function compare2(l,r: pintrecordty): integer; + {$ifndef FPC} + function compare3(l,r: pointer): integer; + {$endif} + procedure quicksort(l,r: integer); +// procedure mergesort(var adata: pointerarty); + procedure sort(var adata: pointerarty); + function getactive: boolean; + procedure setactive(const avalue: boolean); + procedure bindfields; + function findboundary(const comparefunc: indexcomparefuncty; + const arecord: pintrecordty; + const alastindex: integer; const abigger: boolean): integer; + //returns index of next bigger or lower + function findrecord(const arecord: pintrecordty): integer; + //returns index, -1 if not found + function getdesc: boolean; + procedure setdesc(const avalue: boolean); + function getdefault: boolean; + procedure setdefault(const avalue: boolean); + protected + procedure change; + public + constructor create(aowner: tobject); override; + destructor destroy; override; + function find(const avalues: array of const; + //nil -> NULL field + const aisnull: array of boolean; + //itemcount of avalues and aisnull + //can be smaller than fields count in index + //itemcount of aisnull can be smaller than itemcount of avalues + out abookmark: bookmarkdataty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; overload; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + //string values must be msestring + function find(const avalues: array of const; + //nil -> NULL field + const aisnull: array of boolean; + //itemcount of avalues and aisnull + //can be smaller than fields count in index + //itemcount of aisnull can be smaller than itemcount of avalues + out abookmark: bookmarkty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; overload; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + //string values must be msestring + function findvariant(const avalue: array of variant; + out abookmark: bookmarkty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; overload; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + //string values must be msestring + function find(const avalues: array of tfield; + out abookmark: bookmarkty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; overload; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + function find(const avalues: array of tfield; + out abookmark: bookmarkdataty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; overload; + //true if found else nearest lower or bigger, + + function find(const avalues: array of const; + //nil -> NULL field + const aisnull: array of boolean; + //itemcount of avalues and aisnull + //can be smaller than fields count in index + //itemcount of aisnull can be smaller than itemcount of avalues + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; overload; + //sets dataset cursor if found + function find(const avalues: array of tfield; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; overload; + //sets dataset cursor if found + function findvariant(const avalue: array of variant; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; overload; + //sets dataset cursor if found + + function unique(const avalues: array of const): boolean; + procedure deleteduplicates(); //does not store recupdates, no delete events + function getbookmark(const arecno: integer): bookmarkty; + property desc: boolean read getdesc write setdesc; + property default: boolean read getdefault write setdefault; + published + property fields: tindexfields read ffields write setfields; + property options: localindexoptionsty read foptions + write setoptions default []; + property active: boolean read getactive write setactive default false; + property name: string read fname write fname; + //case sensitive + end; + + bufdataseteventty = procedure(const sender: tmsebufdataset) of object; + + tlocalindexes = class(townedpersistentarrayprop) + private + fonindexchanged: bufdataseteventty; + function getitems(const index: integer): tlocalindex; + procedure bindfields; + function getactiveindex: integer; + procedure setactiveindex(const avalue: integer); + function getdefaultindex: integer; + procedure setdefaultindex(const avalue: integer); + protected + procedure checkinactive; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure doindexchanged; + public + constructor create(const aowner: tmsebufdataset); reintroduce; + class function getitemclasstype: persistentclassty; override; + procedure move(const curindex,newindex: integer); override; + property items[const index: integer]: tlocalindex read getitems; default; + function indexbyname(const aname: string): tlocalindex; //case sensitive + property activeindex: integer read getactiveindex + write setactiveindex; //-1 > none + property defaultindex: integer read getdefaultindex + write setdefaultindex; //-1 > none + function fieldactive(const afield: tfield): boolean; + //true if field in active index + function hasfield(const afield: tfield): boolean; + //true if field in any index + function fieldmodified(const afield: tfield; const delayed: boolean): boolean; + procedure preparefixup; //clear changed indexes + published + property onindexchanged: bufdataseteventty read fonindexchanged + write fonindexchanged; + end; + + recupdateflagty = (ruf_applied,ruf_error,ruf_append,ruf_inupdate); + recupdateflagsty = set of recupdateflagty; + + recupdateinfoty = record + updatekind: tupdatekind; + flags: recupdateflagsty; + bookmark: bookmarkdataty; + end; + recupdateinfoarty = array of recupdateinfoty; + + recupdatebufferty = record + info: recupdateinfoty; + oldvalues: pintrecordty; + end; + precupdatebufferty = ^recupdatebufferty; + + recupdatebufferarty = array of recupdatebufferty; + + + bufdatasetstatety = (bs_opening,bs_loading,bs_fetching, + bs_displaydata,bs_applying,bs_recapplying, + bs_curvaluemodified, + bs_curvalueset,{bs_curindexinvalid,} + bs_connected, + bs_hasindex,bs_fetchall,bs_initinternalcalc, + bs_blobsfetched,bs_blobscached,bs_blobssorted, + bs_hasvalidindex, + bs_editing,bs_append,bs_internalcalc,bs_startedit, + bs_utf8, + bs_hasfilter,bs_visiblerecordcountvalid, + bs_refreshing,bs_restorerecno,bs_idle, + bs_noautoapply, + bs_refreshinsert,bs_refreshupdate, + bs_refreshinsertindex,bs_refreshupdateindex, + bs_inserttoupdate + //used by tsqlquery + ); + bufdatasetstatesty = set of bufdatasetstatety; + + bufdatasetstate1ty = (bs1_needsresync,bs1_inupdatechanged, + bs1_lookupnotifying,bs1_lookupnotifypending,bs1_posting,bs1_recordupdating, + bs1_deferdeleterecupdatebuffer,bs1_restoreupdate, + bs1_onidleregistered); + bufdatasetstates1ty = set of bufdatasetstate1ty; + + internalcalcfieldseventty = procedure(const sender: tmsebufdataset; + const fetching: boolean) of object; + iblobchache = interface(inullinterface) + function blobsarefetched: boolean; + function getblobcache: blobcacheinfoarty; + function addblobcache(const adata: pointer; + const alength: integer): integer; overload; + function addblobcache(const aid: int64; const adata: string): integer; overload; + end; + + ecurrentvalueaccess = class(edatabaseerror) + public + constructor create(const adataset: tdataset; const afield: tfield; + const msg: string); + end; + + eapplyerror = class(edatabaseerror) + private + fresponse: resolverresponsesty; + public + constructor create(const msg: string = ''; + const aresponse: resolverresponsesty = []); + property response: resolverresponsesty read fresponse write fresponse; + end; + + lookupdataty = record //todo: case items? + po: pointer; + int: integer; + lint: int64; + doub: double; + cur: currency; + mstr: msestring; + boo: longbool; + vari: variant; + dt: tdatetime; + guid: tguid; + end; + + getbmvalueeventty = procedure (const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty) of object; + lookupfieldinfoty = record + getvalue: getbmvalueeventty; + keyfieldar: fieldarty; + indexnum: integer; + valuefield: tfield; + lookupvaluefield: tfield; + basedatatype: tfieldtype; + hasindex: boolean; + end; + lookupfieldinfoarty = array of lookupfieldinfoty; + + filterediteventty = procedure(const sender: tmsebufdataset; + const akind: filtereditkindty) of object; + bufdatasetarty = array of tmsebufdataset; + + bufdatasetoptionty = (bdo_postsavepoint,bdo_deletesavepoint, + bdo_cancelupdateonerror,bdo_cancelupdatesonerror, + bdo_cancelupdateondeleteerror, + bdo_editonapplyerror, + bdo_restoreupdateonsavepointrollback, + bdo_rollbackonupdateerror, + bdo_noapply,bdo_autoapply,bdo_autoapplyexceptions, + bdo_autocommitret,bdo_autocommit, + bdo_refreshafterapply,bdo_recnoapplyrefresh, + bdo_refreshtransaction, + bdo_notransactionrefresh,bdo_recnotransactionrefresh, + bdo_checkbrowsemodebylookupchange, + bdo_noprepare, + bdo_cacheblobs, + bdo_offline, //disconnect database after open + bdo_local //do not connect database on open + ); + bufdatasetoptionsty = set of bufdatasetoptionty; +const + defaultbufdatasetoptions = []; + oldbdsoptions = [ + bdo_postsavepoint,bdo_deletesavepoint, + bdo_cancelupdateonerror,bdo_cancelupdatesonerror, + bdo_cancelupdateondeleteerror, + bdo_editonapplyerror, + bdo_restoreupdateonsavepointrollback, + bdo_noapply,bdo_autoapply, + bdo_autocommitret,bdo_autocommit, + bdo_refreshafterapply,bdo_recnoapplyrefresh, + bdo_refreshtransaction, + bdo_notransactionrefresh,bdo_recnotransactionrefresh, + bdo_noprepare, + bdo_cacheblobs, + bdo_offline, //disconnect database after open + bdo_local //do not connect database on open + ]; + +type + tmsebufdataset = class(tmdbdataset,iblobchache,idatasetsum,imasterlink, + idbdata,iobjectlink) + private + fpacketrecords: integer; + fopen: boolean; + fupdatebuffer: recupdatebufferarty; + fcurrentupdatebuffer: integer; +// fstatebefore: tdatasetstate; +// fcurrentbufbefore: pintrecordty; + + frecordsize: integer; + fnullmasksize: integer; + fcalcfieldcount: integer; + finternalcalcfieldcount: integer; + fstringpositions: integerarty; + fvarpositions: integerarty; + + fcalcrecordsize: integer; + fcalcnullmasksize: integer; + fcalcfieldbufpositions: integerarty; + fcalcfieldsizes: integerarty; + fcalcstringpositions: integerarty; + fcalcvarpositions: integerarty; + flookupfieldinfos: lookupfieldinfoarty; + flookupclients: bufdatasetarty; + flookupmasters: bufdatasetarty; + fnotifylookupclientcount: integer; + flookupupdate: integer; + + fbuffercountbefore: integer; + fonupdateerror: updateerroreventty; + + femptybuffer: pintrecordty; + ffilterbuffer: array[filtereditkindty] of pdsrecordty; + fcheckfilterbuffer: pdsrecordty; + fnewvaluebuffer: pdsrecordty; //buffer for applyupdates +// flookupbuffer: pdsrecordty; + flookuppo: pintrecordty; + flookupresult: lookupdataty; + fcalcbuffer1: pchar; + + findexlocal: tlocalindexes; + factindex: integer; + foninternalcalcfields: internalcalcfieldseventty; + fvisiblerecordcount: integer; + floadingstream: tstream; + + flogfilename: filenamety; + flogger: tbufstreamwriter; + fbeforeapplyupdate: tdatasetnotifyevent; + fafterapplyupdate: tdatasetnotifyevent; + fbeforebeginfilteredit: filterediteventty; + fafterbeginfilteredit: filterediteventty; + fbeforeendfilteredit: filterediteventty; + fafterendfilteredit: filterediteventty; + ffiltereditkind: filtereditkindty; + + fobjectlinker: tobjectlinker; + fcryptohandler: tcustomcryptohandler; + fdelayedapplycount: integer; + fbeforefilterchanged: bufdataseteventty; + fafterfilterchanged: bufdataseteventty; + procedure calcrecordsize; + function loadbuffer(var buffer: recheaderty): tgetresult; + function getfieldsize(const datatype: tfieldtype; const varsize: integer; + out basetype: tfieldtype) : longint; + function getrecordupdatebuffer: boolean; + procedure setpacketrecords(avalue: integer); + function intallocrecord: pintrecordty; + procedure finalizevalues(var header: recheaderty); + procedure finalizecalcvalues(var header: recheaderty); + procedure addrefvalues(var header: recheaderty); + procedure intfinalizerecord(const buffer: pintrecordty); + procedure intfreerecord(var buffer: pintrecordty); + procedure freeblobcache(const arec: precheaderty; const afield: tfield); + + procedure clearindex; + procedure checkindexsize; + function appendrecord(const arecord: pintrecordty): integer; + //returns new recno + function insertrecord(arecno: integer; const arecord: pintrecordty): integer; + //returns new recno + procedure deleterecord(const arecno: integer); overload; + procedure deleterecord(const arecord: pintrecordty); overload; + procedure getnewupdatebuffer; + procedure dropupdates1(const apply: boolean); + procedure setindexlocal(const avalue: tlocalindexes); + function insertindexrefs(const arecord: pintrecordty): integer; + //returns new recno of active index + procedure removeindexrefs(const arecord: pintrecordty); + function remove0indexref(const arecord: pintrecordty): integer; + //returns index + procedure internalsetrecno(const avalue: integer); + procedure setactindex(const avalue: integer); + procedure checkindex(const aid: integer{; const force: boolean}); + + function getmsestringdata(const sender: tmsestringfield; + out avalue: msestring): boolean; + procedure setmsestringdata(const sender: tmsestringfield; avalue: msestring); + function getvardata(const sender: tmsevariantfield; + out avalue: variant): boolean; + procedure setvardata(const sender: tmsevariantfield; avalue: variant); + procedure setoninternalcalcfields(const avalue: internalcalcfieldseventty); + procedure checkfilterstate; + procedure checklogfile; + procedure initsavepoint; + procedure dointernalopen; + procedure doloadfromstream; + procedure dointernalclose; + procedure logupdatebuffer(const awriter: tbufstreamwriter; + const abuffer: recupdatebufferty; const adeletedrecord: pintrecordty; + const alogging: boolean; const alogmode: logflagty); + procedure logrecbuffer(const awriter: tbufstreamwriter; + const akind: tupdatekind; const abuffer: pintrecordty); + function getlogging: boolean; + procedure checksumfield(const afield: tfield; const fieldtypes: fieldtypesty); + function getcurrentasfloat(const afield: tfield; aindex: integer): double; + procedure setcurrentasfloat(const afield: tfield; aindex: integer; + const avalue: double); + function getcurrentisnull(const afield: tfield; aindex: integer): boolean; + function getcurrentasboolean(const afield: tfield; aindex: integer): boolean; + procedure setcurrentasboolean(const afield: tfield; aindex: integer; + const avalue: boolean); + function getcurrentasinteger(const afield: tfield; aindex: integer): integer; + procedure setcurrentasinteger(const afield: tfield; aindex: integer; + const avalue: integer); + function getcurrentaslargeint(const afield: tfield; aindex: integer): int64; + procedure setcurrentaslargeint(const afield: tfield; aindex: integer; + const avalue: int64); + function getcurrentasdatetime(const afield: tfield; aindex: integer): tdatetime; + procedure setcurrentasdatetime(const afield: tfield; aindex: integer; + const avalue: tdatetime); + function getcurrentascurrency(const afield: tfield; aindex: integer): currency; + procedure setcurrentascurrency(const afield: tfield; aindex: integer; + const avalue: currency); + function getcurrentasmsestring(const afield: tfield; + aindex: integer): msestring; + procedure setcurrentasmsestring(const afield: tfield; aindex: integer; + const avalue: msestring); + function getcurrentasguid(const afield: tfield; aindex: integer): tguid; + procedure setcurrentasguid(const afield: tfield; aindex: integer; + const avalue: tguid); + function getcurrentasid(const afield: tfield; aindex: integer): int64; + procedure setcurrentasid(const afield: tfield; aindex: integer; + const avalue: int64); + procedure setbookmarkdata1(const avalue: bookmarkdataty); + function getcurrentbmisnull(const afield: tfield; + const abm: bookmarkdataty): boolean; + function getcurrentbmasboolean(const afield: tfield; + const abm: bookmarkdataty): boolean; + procedure setcurrentbmasboolean(const afield: tfield; + const abm: bookmarkdataty; + const avalue: boolean); + function getcurrentbmasinteger(const afield: tfield; + const abm: bookmarkdataty): integer; + procedure setcurrentbmasinteger(const afield: tfield; + const abm: bookmarkdataty; + const avalue: integer); + function getcurrentbmaslargeint(const afield: tfield; + const abm: bookmarkdataty): int64; + procedure setcurrentbmaslargeint(const afield: tfield; + const abm: bookmarkdataty; + const avalue: int64); + function getcurrentbmasid(const afield: tfield; + const abm: bookmarkdataty): int64; + procedure setcurrentbmasid(const afield: tfield; + const abm: bookmarkdataty; + const avalue: int64); + function getcurrentbmasfloat(const afield: tfield; + const abm: bookmarkdataty): double; + procedure setcurrentbmasfloat(const afield: tfield; + const abm: bookmarkdataty; + const avalue: double); + function getcurrentbmasdatetime(const afield: tfield; + const abm: bookmarkdataty): tdatetime; + procedure setcurrentbmasdatetime(const afield: tfield; + const abm: bookmarkdataty; + const avalue: tdatetime); + function getcurrentbmascurrency(const afield: tfield; + const abm: bookmarkdataty): currency; + procedure setcurrentbmascurrency(const afield: tfield; + const abm: bookmarkdataty; + const avalue: currency); + function getcurrentbmasmsestring(const afield: tfield; + const abm: bookmarkdataty): msestring; + procedure setcurrentbmasmsestring(const afield: tfield; + const abm: bookmarkdataty; + const avalue: msestring); + function getcurrentbmasguid(const afield: tfield; + const abm: bookmarkdataty): tguid; + procedure setcurrentbmasguid(const afield: tfield; + const abm: bookmarkdataty; + const avalue: tguid); + procedure docurrentassign(const po1: pointer; + const abasetype: tfieldtype; const df: tfield); + procedure lookupdschanged(const sender: tmsebufdataset); + procedure notifylookupclients; + function getcurrentasvariant(const afield: tfield; aindex: integer): variant; + procedure setcurrentasvariant(const afield: tfield; aindex: integer; + const avalue: variant); + function getchangerecords: recupdateinfoarty; + function getapplyerrorrecords: recupdateinfoarty; + function getcurrentbmasvariant(const afield: tfield; + const abm: bookmarkdataty): variant; + procedure setcurrentbmasvariant(const afield: tfield; + const abm: bookmarkdataty; const avalue: variant); + procedure setcryptohandler(const avalue: tcustomcryptohandler); + function getrecnozerobased: int32; + procedure setrecnozerobased(const avalue: int32); + procedure readstreamingversion(reader: treader); + procedure writestreamingversion(writer: twriter); + procedure setdelayedapplycount(const avalue: integer); + procedure registeronidle; + procedure unregisteronidle; + procedure doonidle(var again: boolean); + protected + foldopts: bufdatasetoptionsty; //transferred from tdatasetcontroller + fcontroller: tdscontroller; + foptions: bufdatasetoptionsty; + fbrecordcount: integer; + ffieldinfos: fieldinfoarty; + ffieldorder: integerarty; + factindexpo: pindexty; + fbstate: bufdatasetstatesty; + fbstate1: bufdatasetstates1ty; + fallpacketsfetched : boolean; + fapplyindex: integer; //take care about canceled updates while applying + ffailedcount: integer; + frecno: integer; //zero based + findexes: array of indexty; + fblobcache: blobcacheinfoarty; + fblobcount: integer; + ffreedblobs: integerarty; + ffreedblobcount: integer; + fcurrentbuf: pintrecordty; + fcurrentupdating: integer; +// flastcurrentrec: pintrecordty; + flastcurrentindex: integer; + fsavepointlevel: integer; + fappliedcount: card32; + + procedure doidleapplyupdates() virtual; + procedure setoptions(const avalue: bufdatasetoptionsty) virtual; + function getdefaultoptions: bufdatasetoptionsty virtual; + procedure openlocal; + procedure fixupcurrentset; virtual; + procedure currentcheckbrowsemode; + + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + + procedure dogetcoldata(const afield: tfield; const afieldtype: tfieldtype; + const step: integer; const data: pointer); + function getcurrentlookuppo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: pintrecordty): pointer; + function getcurrentpo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: pintrecordty): pointer; + function beforecurrentget(const afield: tfield; + const afieldtype: tfieldtype; var aindex: integer): pointer; + function beforecurrentbmget(const afield: tfield; + const afieldtype: tfieldtype; const abm: bookmarkdataty): pointer; + function setcurrentpo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: precheaderty; + const aisnull: boolean; out changed: boolean): pointer; + function beforecurrentset(const afield: tfield; + const afieldtype: tfieldtype; var aindex: integer; + const aisnull: boolean; out changed: boolean): pointer; + procedure aftercurrentset(const afield: tfield); virtual; + function beforecurrentbmset(const afield: tfield; + const afieldtype: tfieldtype; const abm: bookmarkdataty; + const aisnull: boolean; out changed: boolean): pointer; + procedure getbminteger(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmlargeint(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmcurrency(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmfloat(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmstring(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmboolean(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmdatetime(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmvariant(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmguid(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + + function getfieldbuffer(const afield: tfield; + out buffer: pointer; out datasize: integer): boolean; overload; + //read, true if not null + function getfieldbuffer(const afield: tfield; + const aisnull: boolean; out datasize: integer): pointer; + overload; virtual; + //write + procedure fieldchanged(const field: tfield); + function getfiltereditkind: filtereditkindty; + function blobsarefetched: boolean; + function getblobcache: blobcacheinfoarty; + function findcachedblob(var info: blobcacheinfoty): boolean; overload; + function findcachedblob(const id: int64; + out info: blobcacheinfoty): boolean; overload; + function addblobcache(const adata: pointer; + const alength: integer): integer; overload; + function addblobcache(const aid: int64; const adata: string): integer; overload; + procedure updatestate; + function getintblobpo: pblobinfoarty; //in currentrecbuf + procedure internalcancel; override; + procedure FreeFieldBuffers; override; + procedure cancelrecupdate(var arec: recupdatebufferty); + procedure setdatastringvalue(const afield: tfield; const avalue: string); +// function getdsoptions: datasetoptionsty; virtual; + procedure resetblobcache; + procedure sortblobcache; + procedure fetchblobs; + procedure fetchallblobs; + procedure getofflineblob(const data: precheaderty; const aindex: integer; + out ainfo: blobstreaminfoty); + procedure setofflineblob(const adata: precheaderty; const aindex: integer; + const ainfo: blobstreaminfoty); + function getblobrecpo: precheaderty; + +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); virtual; + procedure savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); override; + procedure packrecupdatebuffer; + procedure restorerecupdatebuffer; + procedure postrecupdatebuffer; + procedure recupdatebufferapplied(const abuf: precupdatebufferty); + procedure recupdatebufferdropped(const abuf: precupdatebufferty); + procedure editapplyerror(const arecupdatenum: integer); + procedure internalapplyupdate(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean; + out response: resolverresponsesty); + procedure afterapply; virtual; + procedure freeblob(const ablob: blobinfoty); + procedure freeblobs(var ablobs: blobinfoarty); + procedure deleteblob(var ablobs: blobinfoarty; const aindex: integer; + const afreeblob: boolean); overload; + procedure deleteblob(var ablobs: blobinfoarty; const afield: tfield; + const adeleteitem: boolean); overload; + procedure addblob(const ablob: tblobbuffer); + + procedure setrecno1(value: longint; const nocheck: boolean); + procedure setrecno(value: longint); override; + function getrecno: longint; override; + function getchangecount: integer; virtual; + function getapplyerrorcount: integer; virtual; + function allocrecordbuffer: pchar; override; + procedure internalinitrecord(buffer: pchar); override; + procedure clearcalcfields(buffer: pchar); override; + procedure freerecordbuffer(var buffer: pchar); override; + function getcanmodify: boolean; override; + function getrecord(buffer: pchar; getmode: tgetmode; + docheck: boolean): tgetresult; override; + function GetNextRecord: Boolean; override; + function GetNextRecords: Longint; override; + function bookmarkdatatobookmark(const abookmark: bookmarkdataty): bookmarkty; + function bookmarktobookmarkdata(const abookmark: bookmarkty): bookmarkdataty; + function findbookmarkindex(const abookmark: bookmarkdataty): integer; + procedure checkrecno(const avalue: integer); + procedure setonfilterrecord(const value: tfilterrecordevent); override; + procedure setfiltered(value: boolean); override; + procedure filterchanged1(const aloaded: boolean); + procedure setactive(value: boolean); override; + + procedure CalculateFields(Buffer: PChar); override; + procedure notification(acomponent: tcomponent; + operation: toperation) override; + procedure loaded override; + procedure defineproperties(filer: tfiler) override; + procedure readstate(reader: treader) override; + procedure OpenCursor(InfoQuery: Boolean); override; + procedure internalopen; override; + procedure internalclose; override; + procedure clearbuffers; override; + procedure internalinsert; override; + procedure internaledit; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure checkconnected; + procedure startlogger; + procedure closelogger; + procedure savestate(const awriter: tbufstreamwriter); + + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + function getnextpacket(const all: boolean) : integer; + function getrecordsize: word; override; + procedure saveindex(const oldbuffer,newbuffer: pintrecordty; + var ar1,ar2,ar3: integerarty); + procedure relocateindex(const abuffer: pintrecordty; + const ar1,ar2,ar3: integerarty); + procedure internalpost; override; + procedure internaldelete; override; + procedure internalfirst; override; + procedure internallast; override; + procedure internalsettorecord(buffer: pchar); override; + procedure internalgotobookmark(abookmark: pointer); override; + procedure setbookmarkdata(buffer: pchar; data: pointer); override; + procedure setbookmarkflag(buffer: pchar; value: tbookmarkflag); override; + procedure getbookmarkdata(buffer: pchar; data: pointer); override; + function getbookmarkdata1: bookmarkdataty; + function getbookmarkflag(buffer: pchar): tbookmarkflag; override; + function getfieldblobid(const field: tfield; out aid: blobidty): boolean; + //false if null + function iscursoropen: boolean; override; + function getrecordcount: longint; override; + procedure applyrecupdate(updatekind : tupdatekind); virtual; + procedure setonupdateerror(const avalue: updateerroreventty); + property actindex: integer read factindex write setactindex; + function findrecord(arecordpo: pintrecordty): integer; reintroduce; + //returns index, -1 if not found + procedure dofilterrecord(var acceptable: boolean); virtual; + procedure dobeforeapplyupdate; virtual; + procedure doafterapplyupdate; virtual; + procedure dointernalcalcfields(const fetching: boolean); + + function islocal: boolean; virtual; + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); virtual; + procedure objevent(const sender: iobjectlink; const event: objecteventty); virtual; + function getinstance: tobject; + function getcomponent: tcomponent; + //idscontroller + procedure begindisplaydata; + procedure enddisplaydata; + function getsavepointoptions(): savepointoptionsty; + //idbdata + function getindex(const afield: tfield): integer; //-1 if none + function gettextindex(const afield: tfield; + const acaseinsensitive: boolean): integer; //-1 if none + function lookuptext(const indexnum: integer; const akey: integer; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function lookuptext(const indexnum: integer; const akey: int64; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function lookuptext(const indexnum: integer; const akey: msestring; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function findtext(const indexnum: integer; const searchtext: msestring; + out arecord: integer): boolean; + function getrowtext(const indexnum: integer; const arecord: integer; + const afield: tfield): msestring; + function getrowinteger(const indexnum: integer; const arecord: integer; + const afield: tfield): integer; + function getrowlargeint(const indexnum: integer; const arecord: integer; + const afield: tfield): int64; + + {abstracts, must be overidden by descendents} + function fetch : boolean; virtual; abstract; + function getblobdatasize: integer; virtual; abstract; + function blobscached: boolean; virtual; abstract; + function loadfield(const afieldno: integer; const afieldtype: tfieldtype{const afield: tfield}; + const buffer: pointer; + var bufsize: integer): boolean; virtual; abstract; + //if bufsize < 0 -> buffer was to small, should be -bufsize + property nullmasksize: integer read fnullmasksize; + function islastrecord: boolean; + procedure checkfreebuffer(const afield: tfield); + function callvalidate(const afield: tfield; const avalue: pointer): boolean; + procedure checkvaluebuffer(const afield: tfield; const asize: integer); + {$ifndef FPC} + function refreshrecordvarar(const sourcedatasets: array of tdataset; + const akeyvalue: array of variant; + const keyindex: integer; + const acancelupdate: boolean; + const restorerecno: boolean; + const noinsert: boolean): bookmarkdataty; + {$endif} + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure enablecontrols; override; + procedure beginlookupupdate(); //delays notifylookupclient calls + procedure endlookupupdate(); + procedure updaterecord(); override; + procedure post; override; + procedure gotobookmark(const abookmark: bookmarkdataty); overload; + function findbookmark(const abookmark: bookmarkdataty): boolean; + property bookmarkdata: bookmarkdataty read getbookmarkdata1 + write setbookmarkdata1; + function recnobookmark(const arecnozerobased: int32): bookmarkdataty; + + function createblobstream(field: tfield; + mode: tblobstreammode): tstream; override; + function getfielddata(field: tfield; buffer: pointer; + nativeformat: boolean): boolean; override; + function getfielddata(field: tfield; buffer: pointer): boolean; override; + procedure setfielddata(field: tfield; buffer: pointer; + nativeformat: boolean); override; + procedure setfielddata(field: tfield; buffer: pointer); override; + procedure Append; + procedure notifycontrols; //calls enablecontrols/disablecontrols + + //logging works with persistent fields only + procedure recover; + //load from logfile, start logging, + procedure startlogging; + //close logfile, save state with truncated log, open logfile + procedure stoplogging; //close logfile + property logging: boolean read getlogging; + procedure savetostream(const astream: tstream); + procedure loadfromstream(const astream: tstream); + procedure savetofile(afilename: filenamety = ''; //''-> uselogfilename + const acryptohandler: tcustomcryptohandler = nil); + procedure loadfromfile(afilename: filenamety = ''; + //''-> uselogfilename + const acryptohandler: tcustomcryptohandler = nil); + function streamloading: boolean; + + //imasterlink +// function refreshing: boolean; + + function refreshrecord(const akeyfield: array of tfield; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + function refreshrecord(const sourcedatasets: array of tdataset; + const akeyvalue: array of variant; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + function refreshrecord(const asourcefields: array of tfield; + const akeyfield: array of tfield; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + function refreshrecord(const asourcefields: array of tfield; + const adestfields: array of tfield; + const akeyfield: array of tfield; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + function refreshrecord(const asourcefields: array of tfield; + const adestfields: array of tfield; + const akeyvalue: array of variant; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + function refreshrecord(const asourcevalues: array of variant; + const adestfields: array of tfield; + const akeyvalue: array of variant; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + //keyindex must be unique, copies equally named visible fields, + //inserts record if key not found. + + procedure copyfieldvalues(const bm: bookmarkdataty; + const dest: tdataset); overload; + //copies field values with same name + procedure copyfieldvalues(const bm: bookmarkdataty; + const dest: tmsebufdataset; + const acancelupdate: boolean); overload; + //copies field values with same name + + function isutf8: boolean; virtual; + procedure bindfields(const bind: boolean); + function findfields(const anames: string): fieldarty; overload; + function findfields(const anames: string; out afields: fieldarty): boolean; + overload; + //true if all found + procedure fieldtoparam(const source: tfield; const dest: tparam); + procedure oldfieldtoparam(const source: tfield; const dest: tparam); + procedure stringtoparam(const source: msestring; const dest: tparam); + //takes care about utf8 conversion + function recordisnull(): boolean; //all fields null + procedure clearrecord(); + procedure clearfilter(); + property filtereditkind: filtereditkindty read ffiltereditkind + write ffiltereditkind; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + function beginfiltervalue(const akind: filtereditkindty): tdatasetstate; + procedure endfiltervalue(const astatebefore: tdatasetstate); + procedure filterchanged(); + function fieldfiltervalue(const afield: tfield; + const akind: filtereditkindty = fek_filter): variant; + function fieldfiltervalueisnull(const afield: tfield; + const akind: filtereditkindty = fek_filter): boolean; + function checkfiltervalue(const afield: tfield; + const akind: filtereditkindty = fek_filter; + const acaseinsensitive: boolean = true): boolean; + //returns true if filter value is null or filter condition is fulfilled + function checkfiltervalues(const afield: tfield; + const acaseinsensitive: boolean = true): boolean; + //calls checkfiltervalue() for all filtereditkinds + function checkfiltervalues(const acaseinsensitive: boolean = true): boolean; + //calls checkfiltervalue() for all fields and all filtereditkinds + + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; + function locaterecno(const arecno: integer): boolean; + //moves to next valid recno, //returns true if resulting recno = arecno + + function countvisiblerecords: integer; + procedure fetchall; + procedure resetindex; //deactivates all indexes + function createblobbuffer(const afield: tfield): tblobbuffer; + + property changecount: integer read getchangecount; + property changerecords: recupdateinfoarty read getchangerecords; + property applyerrorcount: integer read getapplyerrorcount; + property applyerrorrecords: recupdateinfoarty read getapplyerrorrecords; + property appliedcount: card32 read fappliedcount; + //total successfully applied records since last open + + procedure applyupdates(const maxerrors: integer = 0); overload; virtual; + procedure applyupdates(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); overload; virtual; + procedure applyupdate(const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); overload; virtual; + procedure applyupdate; overload; virtual; + //applies current record + function recapplying: boolean; + procedure dropupdates(); //delete update info + procedure cancelupdates; virtual; //revert changes + procedure cancelupdate(const norecordcancel: boolean = false); virtual; + //cancels current record, + //if norecordcancel no restoring of old values + function updatestatus: tupdatestatus; overload; override; + function updatestatus(out aflags: recupdateflagsty): tupdatestatus; overload; + + procedure currentbeginupdate; virtual; + procedure currentendupdate; virtual; + function currentrecordhigh: integer; //calls checkbrowsemode + property recnozerobased: int32 read getrecnozerobased + write setrecnozerobased; + + //calls checkbrowsemode, writing for fkInternalCalc only, + //aindex = -1 -> current record + procedure currentclear(const afield: tfield; aindex: integer); + procedure currentassign(const source: tfield; const dest: tfield; + aindex: integer); + property currentisnull[const afield: tfield; aindex: integer]: boolean read + getcurrentisnull; + property currentasvariant[const afield: tfield; aindex: integer]: variant + read getcurrentasvariant write setcurrentasvariant; + property currentasboolean[const afield: tfield; aindex: integer]: boolean + read getcurrentasboolean write setcurrentasboolean; + property currentasinteger[const afield: tfield; aindex: integer]: integer + read getcurrentasinteger write setcurrentasinteger; + property currentaslargeint[const afield: tfield; aindex: integer]: int64 + read getcurrentaslargeint write setcurrentaslargeint; + property currentasid[const afield: tfield; aindex: integer]: int64 + read getcurrentasid write setcurrentasid; //-1 for null + property currentasfloat[const afield: tfield; aindex: integer]: double + read getcurrentasfloat write setcurrentasfloat; + property currentasdatetime[const afield: tfield; aindex: integer]: tdatetime + read getcurrentasdatetime write setcurrentasdatetime; + property currentascurrency[const afield: tfield; aindex: integer]: currency + read getcurrentascurrency write setcurrentascurrency; + property currentasmsestring[const afield: tfield; aindex: integer]: msestring + read getcurrentasmsestring write setcurrentasmsestring; + property currentasguid[const afield: tfield; aindex: integer]: tguid + read getcurrentasguid write setcurrentasguid; + + procedure currentbmclear(const afield: tfield; const abm: bookmarkdataty); + procedure currentbmassign(const source: tfield; const dest: tfield; + const abm: bookmarkdataty); + property currentbmisnull[const afield: tfield; + const abm: bookmarkdataty]: boolean read getcurrentbmisnull; + property currentbmasvariant[const afield: tfield; + const abm: bookmarkdataty]: variant + read getcurrentbmasvariant write setcurrentbmasvariant; + property currentbmasboolean[const afield: tfield; + const abm: bookmarkdataty]: boolean + read getcurrentbmasboolean write setcurrentbmasboolean; + property currentbmasinteger[const afield: tfield; + const abm: bookmarkdataty]: integer + read getcurrentbmasinteger write setcurrentbmasinteger; + property currentbmaslargeint[const afield: tfield; + const abm: bookmarkdataty]: int64 + read getcurrentbmaslargeint write setcurrentbmaslargeint; + property currentbmasid[const afield: tfield; + const abm: bookmarkdataty]: int64 + read getcurrentbmasid write setcurrentbmasid; //-1 for null + property currentbmasfloat[const afield: tfield; + const abm: bookmarkdataty]: double + read getcurrentbmasfloat write setcurrentbmasfloat; + property currentbmasdatetime[const afield: tfield; + const abm: bookmarkdataty]: tdatetime + read getcurrentbmasdatetime write setcurrentbmasdatetime; + property currentbmascurrency[const afield: tfield; + const abm: bookmarkdataty]: currency + read getcurrentbmascurrency write setcurrentbmascurrency; + property currentbmasmsestring[const afield: tfield; + const abm: bookmarkdataty]: msestring + read getcurrentbmasmsestring write setcurrentbmasmsestring; + property currentbmasguid[const afield: tfield; + const abm: bookmarkdataty]: tguid + read getcurrentbmasguid write setcurrentbmasguid; + + procedure getcoldata(const afield: tfield; const adatalist: tdatalist); + procedure asarray(const afield: tfield; out avalue: int64arty); overload; + procedure asarray(const afield: tfield; out avalue: integerarty); overload; + procedure asarray(const afield: tfield; out avalue: stringarty); overload; + procedure asarray(const afield: tfield; out avalue: msestringarty); overload; + procedure asarray(const afield: tfield; out avalue: currencyarty); overload; + procedure asarray(const afield: tfield; out avalue: realarty); overload; + procedure asarray(const afield: tfield; out avalue: datetimearty); overload; + procedure asarray(const afield: tfield; out avalue: booleanarty); overload; + + function getdata(const afields: array of tfield): variantararty; + //[] -> all + procedure sumfield(const afield: tfield; out asum: double); overload; + procedure sumfield(const afield: tfield; out asum: currency); overload; + procedure sumfield(const afield: tfield; out asum: integer); overload; + procedure sumfield(const afield: tfield; out asum: int64); overload; + function sumfielddouble(const afield: tfield): double; + function sumfieldcurrency(const afield: tfield): currency; + function sumfieldinteger(const afield: tfield): integer; + function sumfieldint64(const afield: tfield): int64; + property delayedapplycount: integer read fdelayedapplycount + write setdelayedapplycount default 0; + //0 -> no autoapply + published + property options: bufdatasetoptionsty read foptions + write setoptions default []; + property logfilename: filenamety read flogfilename write flogfilename; + property cryptohandler: tcustomcryptohandler read fcryptohandler + write setcryptohandler; + property packetrecords : integer read fpacketrecords write setpacketrecords + default defaultpacketrecords; + property indexlocal: tlocalindexes read findexlocal write setindexlocal; + + property onupdateerror: updateerroreventty read fonupdateerror + write setonupdateerror; + property oninternalcalcfields: internalcalcfieldseventty + read foninternalcalcfields write setoninternalcalcfields; + property beforeapplyupdate: tdatasetnotifyevent read fbeforeapplyupdate + write fbeforeapplyupdate; + property afterapplyupdate: tdatasetnotifyevent read fafterapplyupdate + write fafterapplyupdate; + property beforebeginfilteredit: filterediteventty + read fbeforebeginfilteredit write fbeforebeginfilteredit; + property afterbeginfilteredit: filterediteventty + read fafterbeginfilteredit write fafterbeginfilteredit; + property beforeendfilteredit: filterediteventty + read fbeforeendfilteredit write fbeforeendfilteredit; + property afterendfilteredit: filterediteventty + read fafterendfilteredit write fafterendfilteredit; + property beforefilterchanged: bufdataseteventty + read fbeforefilterchanged write fbeforefilterchanged; + property afterfilterchanged: bufdataseteventty + read fafterfilterchanged write fafterfilterchanged; + property Active default false; +// property AutocalcFields default false; + end; + +function getfieldflag(nullmask: pbyte; const x: integer): boolean; +procedure setfieldflag(nullmask: pbyte; const x: integer); +procedure clearfieldflag(nullmask: pbyte; const x: integer); +procedure alignfieldpos(var avalue: integer); + +implementation +uses + rtlconsts,{$ifdef FPC}dbconst{$else}dbconst_del,classes_del{$endif},sysutils, + mseformatstr,msereal,msesys,msefileutils,mseapplication,msesysutils,msebits, + typinfo; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tmsestringfield1 = class(tmsestringfield); + tmseblobfield1 = class(tmseblobfield); + tmsevariantfield1 = class(tmsevariantfield); + tmsebooleanfield1 = class(tmsebooleanfield); + tmsedatetimefield1 = class(tmsedatetimefield); + tfield1 = class(tfield); + +const + fielddatacompatibility: array[tfieldtype] of fieldtypesty = ( + //ftUnknown, ftString, ftSmallint, ftInteger, ftWord, + [ftunknown],stringfcomp,longintfcomp,longintfcomp,longintfcomp, + //ftBoolean, ftFloat, ftCurrency, ftBCD, + booleanfcomp,realfcomp+datetimefcomp,realfcomp+datetimefcomp,[ftbcd], + //ftDate, ftTime, tDateTime, + realfcomp+datetimefcomp,realfcomp+datetimefcomp,realfcomp+datetimefcomp, + //ftBytes, ftVarBytes, ftAutoInc, + [ftbytes],[ftvarbytes],[ftautoinc], + // ftBlob, ftMemo, ftGraphic, ftFmtMemo, + blobfcomp,memofcomp,blobfcomp,memofcomp, + //ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, tFixedChar, + [ftParadoxOle],[ftDBaseOle],[ftTypedBinary],[ftCursor],stringfcomp, + //ftWideString, ftLargeint, ftADT, ftArray, ftReference, + stringfcomp,[ftLargeint],[ftADT],[ftArray],[ftReference], + //ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, + [ftDataSet],[ftOraBlob],[ftOraClob],[ftVariant],[ftInterface], + //ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd); + [ftIDispatch],[ftGuid],[ftTimeStamp],[ftFMTBcd], + //ftFixedWideChar,ftWideMemo + stringfcomp, stringfcomp + ); + +function compblobcache(const a,b): integer; +var + lint1: int64; +begin + lint1:= blobcacheinfoty(a).id - blobcacheinfoty(b).id; + result:= 0; + if lint1 < 0 then begin + result:= -1; + end + else begin + if lint1 > 0 then begin + result:= 1; + end; + end; +end; + +function compinteger(const l,r): integer; +begin + result:= integer(l) - integer(r); +end; + +function compint64(const l,r): integer; +begin + if int64(l) > int64(r) then begin + result:= 1; + end + else begin + if int64(l) = int64(r) then begin + result:= 0; + end + else begin + result:= -1; + end; + end; +end; + +function compfloat(const l,r): integer; +begin + result:= 0; + if double(l) > double(r) then begin + inc(result); + end + else begin + if double(l) < double(r) then begin + dec(result); + end; + end; +end; + +function compcurrency(const l,r): integer; +begin + result:= 0; + if currency(l) > currency(r) then begin + inc(result); + end + else begin + if currency(l) < currency(r) then begin + dec(result); + end; + end; +end; + +function compstring(const l,r): integer; +begin + result:= msecomparestr(msestring(l),msestring(r)); +end; + +function compstringi(const l,r): integer; +begin + result:= msecomparetext(msestring(l),msestring(r)); +end; + +function compstringn(const l,r): integer; +begin + result:= msecomparestrnatural(msestring(l),msestring(r)); +end; + +function compstringin(const l,r): integer; +begin + result:= msecomparetextnatural(msestring(l),msestring(r)); +end; + +function compguid(const l,r): integer; +var + int1: integer; +begin + for int1:= 0 to (sizeof(tguid) div sizeof(integer)) - 1 do begin + result:= pintegeraty(@l)^[int1]-pintegeraty(@r)^[int1]; + if result <> 0 then begin + break; + end; + end; +end; + +type + fieldcomparekindty = (fct_integer,fct_largeint,fct_float,fct_currency,fct_text, + fct_guid); + fieldcompareinfoty = record + datatypes: set of tfieldtype; + cvtype: integer; + compfunc: arraysortcomparety; + compfunci: arraysortcomparety; + compfuncn: arraysortcomparety; + compfuncin: arraysortcomparety; + end; + +const + comparefuncs: array[fieldcomparekindty] of fieldcompareinfoty = + ((datatypes: integerindexfields; cvtype: vtinteger; + compfunc: @compinteger; + compfunci: @compinteger; + compfuncn: @compinteger; + compfuncin: @compinteger), + (datatypes: largeintindexfields; cvtype: vtint64; + compfunc: @compint64; + compfunci: @compint64; + compfuncn: @compint64; + compfuncin: @compint64), + (datatypes: floatindexfields; cvtype: vtextended; + compfunc: @compfloat; + compfunci: @compfloat; + compfuncn: @compfloat; + compfuncin: @compfloat), + (datatypes: currencyindexfields; cvtype: vtcurrency; + compfunc: @compcurrency; + compfunci: @compcurrency; + compfuncn: @compcurrency; + compfuncin: @compcurrency), + (datatypes: stringindexfields; + cvtype: {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}; + compfunc: @compstring; + compfunci: @compstringi; + compfuncn: @compstringn; + compfuncin: @compstringin), + (datatypes: guidindexfields; cvtype: mse_vtguid; + compfunc: @compguid; + compfunci: @compguid; + compfuncn: @compguid; + compfuncin: @compguid) +); + +procedure alignfieldpos(var avalue: integer); +const + step = sizeof(pointer); +begin + avalue:= (avalue + step - 1) and -step; //align to pointer +end; + +const +{$ifdef FPC} + ormask: array[0..7] of byte = (%00000001,%00000010,%00000100,%00001000, + %00010000,%00100000,%01000000,%10000000); + andmask: array[0..7] of byte = (%11111110,%11111101,%11111011,%11110111, + %11101111,%11011111,%10111111,%01111111); +{$else} + ormask: array[0..7] of byte = ($01,$02,$04,$08,$10,$20,$40,$80); + andmask: array[0..7] of byte = + (byte(not$01),byte(not$02),byte(not$04),byte(not$08), + byte(not$10),byte(not$20),byte(not$40),byte(not$80)); +{$endif} + +procedure setfieldflag(nullmask: pbyte; const x: integer); +//var +// int1: integer; +begin + inc(nullmask,(x shr 3)); + nullmask^:= nullmask^ or ormask[x and 7]; +end; + +procedure clearfieldflag(nullmask: pbyte; const x: integer); +begin + inc(nullmask,(x shr 3)); + nullmask^:= nullmask^ and andmask[x and 7]; +end; + +function getfieldflag(nullmask: pbyte; const x: integer): boolean; +begin + inc(nullmask,(x shr 3)); + result:= nullmask^ and ormask[x and 7] <> 0; +end; + + +{ tbufstreamwriter } + +constructor tbufstreamwriter.create(const aowner: tmsebufdataset; + const astream: tstream); +begin + fowner:= aowner; + fstream:= astream; +end; + +destructor tbufstreamwriter.destroy; +begin + flushbuffer; + inherited; +end; + +procedure tbufstreamwriter.flushbuffer; +begin + fstream.writebuffer(fbuffer,fbufindex); + fbufindex:= 0; +end; + +procedure tbufstreamwriter.write(const buffer; length: integer); +var + po1: pointer; + int1: integer; +begin + po1:= @buffer; + while length > 0 do begin + int1:= length; + if int1 + fbufindex > bufstreambuffersize then begin + int1:= bufstreambuffersize - fbufindex; + end; + move(po1^,fbuffer[fbufindex],int1); + inc(fbufindex,int1); + if fbufindex >= bufstreambuffersize then begin + flushbuffer; + end; + inc(pchar(po1),int1); + dec(length,int1); + end; +end; + +procedure tbufstreamwriter.writefielddata(const data: precheaderty; + const aindex: integer); +var + fielddata: pointer; + blobinfo: blobstreaminfoty; +begin + with fowner.ffieldinfos[aindex].base do begin + fielddata:= pchar(pointer(data)) + offset; + case fieldtype of + ftstring,ftfixedchar,ftwidestring,ftfixedwidechar: begin + writemsestring(msestring(fielddata^)); + end; + ftmemo,ftblob,ftgraphic: begin + if getfieldflag(@data^.fielddata.nullmask,aindex) then begin + fowner.getofflineblob(data,aindex,blobinfo); + write(blobinfo.info,sizeof(blobinfo.info)); + writestring(blobinfo.data); + end; + end; + ftvariant: begin + writevariant(variant(fielddata^)); + end; + else begin + write(fielddata^,size); + end; + end; + end; +end; + +procedure tbufstreamwriter.writestring(const avalue: string); +begin + writeinteger(length(avalue)); + write(pointer(avalue)^,length(avalue)); +end; + +procedure tbufstreamwriter.writemsestring(const avalue: msestring); +begin + writeinteger(length(avalue)); + write(pointer(avalue)^,length(avalue)*sizeof(msechar)); +end; + +procedure tbufstreamwriter.writeinteger(const avalue: integer); +begin + write(avalue,sizeof(integer)); +end; + +procedure tbufstreamwriter.writefielddef(const afielddef: tfielddef); +begin + with afielddef do begin + writestring(name); + writeinteger(ord(datatype)); + writeinteger(size); + writeinteger(integer(required)); + writeinteger(fieldno); + writeinteger(precision); + end; +end; + +{$ifdef mse_debuglogger} +function logpo(const apo: card64): string; +begin + if apo = 0 then begin + result:= '0'; + end + else begin + result:= hextostr(apo); + end; +end; + +procedure dumplogbufferheader(const aheader: logbufferheaderty); +begin + with aheader do begin + debugwrite('*log '+getenumname(typeinfo(logflag),ord(logflag))); + case aheader.logflag of + lf_end: begin + end; + lf_rec: begin + with rec do begin + debugwriteln(' '+getenumname(typeinfo(kind),ord(kind))+' '+logpo(po)); + end; + end; + else begin + with update do begin + if logging then begin + debugwrite(' logging'); + end; + debugwriteln(' '+getenumname(typeinfo(kind),ord(kind))+' '+ + logpo(po)+' '+logpo(deletedrecord)); + end; + end; + end; + end; +end; +{$endif} + +procedure tbufstreamwriter.writelogbufferheader( + const aheader: logbufferheaderty); +begin +{$ifdef mse_debuglogger} + dumplogbufferheader(aheader); +{$endif} + write(aheader,sizeof(aheader)); +end; + +procedure tbufstreamwriter.writeendmarker; +var + abuffer: logbufferheaderty; +begin + fillchar(abuffer,sizeof(abuffer),0); + abuffer.logflag:= lf_end; + write(abuffer,sizeof(abuffer)); +end; + +procedure tbufstreamwriter.writepointer(const avalue: pointer); +begin + write(avalue,sizeof(pointer)); +end; + +type + pointeraty1 = array[0..1] of pointer; + ppointeraty1 = ^pointeraty1; + +procedure tbufstreamwriter.writevariant(const avalue: variant); +var + int1,int2: integer; +begin + write(avalue,sizeof(variant)); + with tvardata(avalue) do begin + case vtype of + varstring: begin + writestring(ansistring(vstring)); + end; + varolestr: begin + writemsestring(widestring(pointer(volestr))); + end; + end; + if vtype and vararray <> 0 then begin + write(varray^,sizeof(tvararray)); + with varray^ do begin + write(ppointeraty1(varray)^[1],(dimcount-1)*sizeof(tvararrayboundarray)); + //additional dims + int2:= 1; + for int1:= 0 to dimcount-1 do begin + int2:= int2 * bounds[int1].elementcount; + end; + write(data^,elementsize*int2); + case vtype and vartypemask of + varstring: begin + for int1:= 0 to int2 - 1 do begin + writestring(pstringaty(data)^[int1]); + end; + end; + varolestr: begin + for int1:= 0 to int2 - 1 do begin + writemsestring(pwidestringaty(data)^[int1]); + end; + end; + varvariant: begin + for int1:= 0 to int2 - 1 do begin + writevariant(pvariantaty(data)^[int1]); + end; + end; + end; + end; + end; + end; +end; + +{ tbufstreamreader } + +constructor tbufstreamreader.create(const aowner: tmsebufdataset; + const astream: tstream); +begin + fowner:= aowner; + fstream:= astream; +end; + +function tbufstreamreader.read(out buffer; length: integer): integer; +var + po1: pointer; + int1: integer; +begin + po1:= @buffer; + result:= 0; + while length > 0 do begin + int1:= length; + if int1 + fbufindex >= fbuflen then begin + int1:= fbuflen - fbufindex; + end; + move(fbuffer[fbufindex],po1^,int1); + inc(pchar(po1),int1); + inc(result,int1); + dec(length,int1); + inc(fbufindex,int1); + if fbufindex >= fbuflen then begin + fbufindex:= 0; + fbuflen:= fstream.read(fbuffer,bufstreambuffersize); + if fbuflen = 0 then begin + exit; //eof + end; + end; + end; +end; + +procedure tbufstreamreader.readbuffer(out buffer; const length: integer); +begin + if read(buffer,length) < length then begin + raise ereaderror.create(sreaderror); + end; +end; + +procedure tbufstreamreader.readfielddata(const data: precheaderty; + const aindex: integer); +var + fielddata: pointer; + blobinfo: blobstreaminfoty; +begin + with fowner.ffieldinfos[aindex].base do begin + fielddata:= pchar(pointer(data)) + offset; + case fieldtype of + ftstring,ftfixedchar,ftwidestring,ftfixedwidechar: begin + msestring(fielddata^):= readmsestring; + end; + ftmemo,ftblob,ftgraphic: begin + if getfieldflag(@data^.fielddata.nullmask,aindex) then begin + readbuffer(blobinfo.info,sizeof(blobinfo.info)); + blobinfo.data:= readstring; + fowner.setofflineblob(data,aindex,blobinfo); + end; + end; + ftvariant: begin + variant(fielddata^):= readvariant; + end; + else begin + readbuffer(fielddata^,size); + end; + end; + end; +end; + +function tbufstreamreader.readstring: string; +var + int1: integer; +begin + int1:= readinteger; + setlength(result,int1); + readbuffer(pointer(result)^,int1); +end; + +function tbufstreamreader.readmsestring: msestring; +var + int1: integer; +begin + int1:= readinteger; + setlength(result,int1); + readbuffer(pointer(result)^,int1*sizeof(msechar)); +end; + +function tbufstreamreader.readinteger: integer; +begin + readbuffer(result,sizeof(integer)); +end; + +procedure tbufstreamreader.readfielddef(const aowner: tfielddefs); +var + name: string; + datatype: tfieldtype; + size: integer; + required: boolean; + fieldno: integer; + precision: integer; + def1: tfielddef; +begin + name:= readstring; + datatype:= tfieldtype(readinteger); + size:= readinteger; + if datatype in blobfields then begin +// size:= fowner.getblobdatasize; + size:= 0; + end; + required:= boolean(readinteger); + fieldno:= readinteger; + precision:= readinteger; + def1:= tfielddef.create(aowner,name,datatype,size,required,fieldno); + def1.precision:= precision; +end; + +function tbufstreamreader.readlogbufferheader( + out aheader: logbufferheaderty): boolean; +var + rec1: logbufferheader32ty; +begin + if f32to64 then begin + result:= (read(rec1,sizeof(rec1)) = sizeof(rec1)) and + (rec1.logflag <> lf_end); + if result then begin + aheader.logflag:= rec1.logflag; + if rec1.logflag = lf_rec then begin + with aheader.rec do begin + kind:= rec1.rec.kind; + po:= rec1.rec.po; + end; + end + else begin + with aheader.update do begin + logging:= rec1.update.logging; + kind:= rec1.update.kind; + po:= rec1.update.po; + deletedrecord:= rec1.update.deletedrecord; + end; + end; + end; + end + else begin + result:= (read(aheader,sizeof(aheader)) = sizeof(aheader)) and + (aheader.logflag <> lf_end); + end; +{$ifdef mse_debuglogger} + if result then begin + dumplogbufferheader(aheader); + end + else begin + if aheader.logflag = lf_end then begin + debugwriteln('*log lf_end'); + end + else begin + debugwriteln('*log header readerror*'); + end; + end; +{$endif} +end; + +function tbufstreamreader.readpointer: pointer; +begin + readbuffer(result,sizeof(pointer)); +end; + +type + bufdattagty = array[0..15]of char; + tbsfheaderty = packed record + tag: bufdattagty; + byteorder: byte; //bit 0 0 -> little endian, 1 -> big endian + //bit 2 0 -> 32 bit 1 -> 64 bit (version 2) + version: integer; + fieldcount: integer; + fielddefcount: integer; + recordcount: integer; + end; + +procedure tbufstreamreader.readrecord(const arecord: pintrecordty); +var + int1: integer; + datapo: precheaderty; +begin + datapo:= @arecord^.header; + readbuffer(datapo^.fielddata,fowner.fnullmasksize); + for int1:= 0 to high(fowner.ffieldinfos) do begin + readfielddata(datapo,int1); + end; +end; + +function tbufstreamreader.readvariant: variant; +var + int1,int2: integer; +begin + readbuffer(result,sizeof(variant)); + with tvardata(result) do begin + case vtype of + varstring: begin + vtype:= 0; + result:= readstring; + end; + varolestr: begin + vtype:= 0; + result:= readmsestring; + end; + end; + if vtype and vararray <> 0 then begin + getmem(pointer(varray),sizeof(tvararray)); + read(varray^,sizeof(tvararray)); + varray^.lockcount:= 0; + reallocmem(varray,sizeof(tvararray)+ + (varray^.dimcount-1)*sizeof(tvararrayboundarray)); + with varray^ do begin + read(ppointeraty1(varray)^[1],(dimcount-1)*sizeof(tvararrayboundarray)); + int2:= 1; + for int1:= 0 to dimcount-1 do begin + int2:= int2 * bounds[int1].elementcount; + end; + getmem(data,elementsize*int2); + read(data^,elementsize*int2); + case vtype and vartypemask of + varstring: begin + for int1:= 0 to int2 - 1 do begin + ppointeraty(data)^[int1]:= nil; + pansistringaty(data)^[int1]:= readstring; + end; + end; + varolestr: begin + for int1:= 0 to int2 - 1 do begin + ppointeraty(data)^[int1]:= nil; + pwidestringaty(data)^[int1]:= readmsestring; + end; + end; + varvariant: begin + for int1:= 0 to int2 - 1 do begin + pvardataaty(data)^[int1].vtype:= 0; + pvariantaty(data)^[int1]:= readvariant; + end; + end; + end; + end; + end; + end; +end; + +{ tblobbuffer } + +constructor tblobbuffer.create(const aowner: tmsebufdataset; const afield: tfield); +begin + fowner:= aowner; + ffield:= afield; + inherited create; +end; + +destructor tblobbuffer.destroy; +begin + fowner.addblob(self); + setpointer(nil,0); + inherited; +end; + +{ tblobcopy } + +constructor tblobcopy.create(const ablob: blobinfoty); +begin + inherited create; + setpointer(ablob.data,ablob.datalength); +end; + +destructor tblobcopy.destroy; +begin + setpointer(nil,0); + inherited; +end; + +{ eapplyerror } + +constructor eapplyerror.create(const msg: string = ''; + const aresponse: resolverresponsesty = []); +begin + fresponse:= aresponse; + inherited create(msg); +end; + +{ tmsebufdataset } + +constructor tmsebufdataset.Create(AOwner : TComponent); +begin + foptions:= getdefaultoptions(); + frecno:= -1; + findexlocal:= tlocalindexes.create(self); + packetrecords:= defaultpacketrecords; + inherited; + bookmarksize := sizeof(bufbookmarkty); +end; + +destructor tmsebufdataset.destroy; +var + int1: integer; +begin + unregisteronidle(); + inherited destroy; + for int1:= high(flookupclients) downto 0 do begin + removeitem(pointerarty(flookupclients[int1].flookupmasters),pointer(self)); + end; + findexlocal.free; + closelogger; + freeandnil(fobjectlinker); +end; + +procedure tmsebufdataset.setpacketrecords(avalue : integer); +begin + if (avalue = 0) then begin + databaseerror('Packetrecords can not be 0.'{sinvpacketrecordsvalue}); + end; + fpacketrecords:= avalue; + updatestate; +end; + +Function tmsebufdataset.GetCanModify: Boolean; +begin + result:= false; +end; + +function tmsebufdataset.intallocrecord: pintrecordty; +begin + result:= allocmem(frecordsize+intheadersize); + fillchar(result^,frecordsize+intheadersize,0); + { + fillchar(result^,sizeof(intrecordty),0); + for int1:= high(fstringpositions) downto 0 do begin + pointer(pointer(@result^.header)+fstringpositions[int1])^):= nil; + end; + } +end; + +procedure freedbvariant(var avalue: variant); +begin + finalize(avalue); +{ + if avariant <> nil then begin + finalize(avariant^); + freemem(avariant); + avariant:= nil; + end; + } +end; + +procedure addrefdbvariant(var avalue: variant); +var + var1: variant; +begin + move(avalue,var1,sizeof(variant)); + fillchar(avalue,sizeof(variant),0); + avalue:= var1; //deep copy + tvardata(var1).vtype:= 0; +{ + po1:= avariant; + if po1 <> nil then begin + avariant:= getmem(sizeof(variant)); + tvardata(avariant^).vtype:= 0; + avariant^:= po1^; + end; + } +end; + +procedure tmsebufdataset.finalizevalues(var header: recheaderty); +var + int1: integer; +begin + for int1:= high(fstringpositions) downto 0 do begin + pmsestring(pchar(pointer(@header))+fstringpositions[int1])^:= ''; + end; + for int1:= high(fvarpositions) downto 0 do begin + freedbvariant(pvariant(pchar(pointer(@header))+fvarpositions[int1])^); + end; +end; + +procedure tmsebufdataset.finalizecalcvalues(var header: recheaderty); +var + int1: integer; +begin + for int1:= high(fcalcstringpositions) downto 0 do begin + pmsestring(pchar(pointer(@header))+fcalcstringpositions[int1])^:= ''; + end; + for int1:= high(fcalcvarpositions) downto 0 do begin + freedbvariant(pvariant(pchar(pointer(@header))+fcalcvarpositions[int1])^) + end; +end; +{ +procedure tmsebufdataset.finalizechangedvalues(const tocompare: recheaderty; + var tofinalize: recheaderty); +var + int1: integer; +begin + for int1:= high(fstringpositions) downto 0 do begin + if ppointer(pointer(@tocompare)+fstringpositions[int1])^ <> + ppointer(pointer(@tofinalize)+fstringpositions[int1])^ then begin + pmsestring(pointer(@tofinalize)+fstringpositions[int1])^:= ''; + end; + end; + for int1:= high(fvarpositions) downto 0 do begin + if ppointer(pointer(@tocompare)+fvarpositions[int1])^ <> + ppointer(pointer(@tofinalize)+fvarpositions[int1])^ then begin + freedbvariant(ppvariant(pointer(@tofinalize)+fvarpositions[int1])^); + end; + end; +end; +} +procedure tmsebufdataset.addrefvalues(var header: recheaderty); +var + int1: integer; +begin + for int1:= high(fstringpositions) downto 0 do begin + stringaddref(pmsestring(pchar(pointer(@header))+fstringpositions[int1])^); + end; + for int1:= high(fvarpositions) downto 0 do begin + addrefdbvariant(pvariant(pchar(pointer(@header))+fvarpositions[int1])^) + end; +end; + +procedure tmsebufdataset.intfinalizerecord(const buffer: pintrecordty); +begin + freeblobs(buffer^.header.blobinfo); + finalizevalues(buffer^.header); +end; + +procedure tmsebufdataset.intfreerecord(var buffer: pintrecordty); +begin + if buffer <> nil then begin + intfinalizerecord(buffer); + freemem(buffer); + buffer:= nil; + end; +end; + +function tmsebufdataset.allocrecordbuffer: pchar; +var + int1: integer; +begin + int1:= dsheadersize+fcalcrecordsize; + result:= allocmem(int1); + fillchar(result^,int1,0); //init for refcounted calcdata + initrecord(result); +end; + +procedure tmsebufdataset.clearcalcfields(buffer: pchar); +var + int1: integer; +begin + with pdsrecordty(buffer)^ do begin + for int1:= high(fcalcstringpositions) downto 0 do begin + pmsestring(pchar(pointer(@header))+fcalcstringpositions[int1])^:= ''; + end; + for int1:= high(fcalcvarpositions) downto 0 do begin + freedbvariant(pvariant(pchar(pointer(@header))+fcalcvarpositions[int1])^) + end; + fillchar((pchar(pointer(@header))+frecordsize)^,fcalcrecordsize-frecordsize,0); + end; +end; + +procedure tmsebufdataset.internalinitrecord(buffer: pchar); +begin + with pdsrecordty(buffer)^ do begin + finalizecalcvalues(precheaderty(@header)^); + fillchar(header,fcalcrecordsize,#0); //zero the whole buffer + end; +end; +{ +procedure tmsebufdataset.internalinitrecord(buffer: pchar); + +begin + freecalcfields(buffer); +// with pdsrecordty(buffer)^ do begin +// fillchar(header,fcalcrecordsize, #0); +// end; +end; +} +procedure tmsebufdataset.freerecordbuffer(var buffer: pchar); +//var +// int1: integer; +// bo1: boolean; +begin + if buffer <> nil then begin + with pdsrecordty(buffer)^,header do begin +{ there can be copies of invalid buffers + bo1:= false; + for int1:= high(blobinfo) downto 0 do begin + if blobinfo[int1].new then begin + freeblob(blobinfo[int1]); + bo1:= true; + end; + end; + if bo1 then begin + blobinfo:= nil; + end; +} + finalizecalcvalues(header); + end; + reallocmem(buffer,0); + end; +end; + +function tmsebufdataset.getintblobpo: pblobinfoarty; +begin + if bs_recapplying in fbstate then begin + result:= @fnewvaluebuffer^.header.blobinfo; + end + else begin + result:= @fcurrentbuf^.header.blobinfo; + end; +end; + +procedure tmsebufdataset.freeblob(const ablob: blobinfoty); +begin + with ablob do begin + if datalength > 0 then begin + freemem(data); + end; + end; +end; + +function tmsebufdataset.createblobbuffer(const afield: tfield): tblobbuffer; +begin + result:= tblobbuffer.create(self,afield); +end; + +procedure tmsebufdataset.freeblobcache(const arec: precheaderty; + const afield: tfield); +var + fieldindex: integer; + blobid: integer; +begin +//todo: free offline blobs + if bs_blobscached in fbstate then begin + fieldindex:= afield.fieldno-1; + if getfieldflag(@arec^.fielddata.nullmask,fieldindex) then begin + blobid:= pinteger(pchar(arec) + ffieldinfos[fieldindex].base.offset)^; + fblobcache[blobid].data:= ''; + additem(ffreedblobs,blobid,ffreedblobcount{,(high(ffreedblobs)+129)*2}); + end; + end; +end; + +procedure tmsebufdataset.addblob(const ablob: tblobbuffer); +var + int1,int2: integer; + bo1: boolean; + blobfree: boolean; + po2: pointer; + po1: precheaderty; +begin + bo1:= false; + int2:= -1; + if bs_recapplying in fbstate then begin + po1:= @fnewvaluebuffer^.header; + blobfree:= true; + end + else begin + po1:= @pdsrecordty(activebuffer)^.header; + blobfree:= false; + end; + with po1^{pdsrecordty(activebuffer)^.header} do begin + for int1:= high(blobinfo) downto 0 do begin + with blobinfo[int1] do begin + if new then begin + bo1:= true; + end; + if field = ablob.ffield then begin + int2:= int1; + end; + end; + end; + if not bo1 and not (bs_recapplying in fbstate) then begin //copy needed + po2:= pointer(blobinfo); + pointer(blobinfo):= nil; + blobinfo:= copy(blobinfoarty(po2)); + end; + if int2 >= 0 then begin + deleteblob(blobinfo,int2,blobfree); + end + else begin + if blobfree then begin //else necessary for //done in post + //cancelupdate + freeblobcache(po1,ablob.ffield); + end; + end; + setlength(blobinfo,high(blobinfo)+2); + with blobinfo[high(blobinfo)],ablob do begin + data:= memory; + reallocmem(data,size); + datalength:= size; + field:= ffield; + if not (bs_recapplying in fbstate) then begin + new:= true; + end; + if size = 0 then begin + clearfieldflag(@fielddata.nullmask,field.fieldno-1); + end + else begin + setfieldflag(@fielddata.nullmask,field.fieldno-1); + end; + fieldchanged(field); + end; + end; +end; + +procedure tmsebufdataset.freeblobs(var ablobs: blobinfoarty); +var + int1: integer; +begin + for int1:= 0 to high(ablobs) do begin + freeblob(ablobs[int1]); + end; + ablobs:= nil; +end; + +procedure tmsebufdataset.deleteblob(var ablobs: blobinfoarty; + const aindex: integer; const afreeblob: boolean); +begin + if afreeblob then begin + freeblob(ablobs[aindex]); + end; + deleteitem(ablobs,typeinfo(blobinfoarty),aindex); +end; + +procedure tmsebufdataset.deleteblob(var ablobs: blobinfoarty; + const afield: tfield; const adeleteitem: boolean); +var + int1: integer; +begin + for int1:= high(ablobs) downto 0 do begin + if ablobs[int1].field = afield then begin + freeblob(ablobs[int1]); + if adeleteitem then begin + deleteitem(ablobs,typeinfo(blobinfoarty),int1); + end + else begin + ablobs[int1].field:= nil; + end; + exit; + end; + end; + if not adeleteitem then begin //called from post + freeblobcache(@fcurrentbuf^.header,afield); + end; +end; + +procedure tmsebufdataset.initsavepoint; +begin + fsavepointlevel:= -1; + exclude(fbstate1,bs1_deferdeleterecupdatebuffer); +end; + +procedure tmsebufdataset.dointernalopen; +var + int1: integer; + kind1: filtereditkindty; +begin + initsavepoint; + for int1:= 0 to fields.count - 1 do begin + with fields[int1] do begin + if (fieldkind = fkdata) and (fielddefs.indexof(fieldname) < 0) then begin + databaseerrorfmt(sfieldnotfound,[fieldname],self); + end; + end; + end; + include(fbstate,bs_opening); + if bdo_cacheblobs in foptions then begin + include(fbstate,bs_blobsfetched); + end + else begin + exclude(fbstate,bs_blobsfetched); + end; + if isutf8 then begin + include(fbstate,bs_utf8); + end + else begin + exclude(fbstate,bs_utf8); + end; + bindfields(true); //calculate calc fields size + setlength(findexes,1+findexlocal.count); + factindexpo:= @findexes[factindex]; + calcrecordsize; + findexlocal.bindfields; + femptybuffer:= intallocrecord; + for kind1:= low(filtereditkindty) to high(filtereditkindty) do begin + ffilterbuffer[kind1]:= pdsrecordty(allocrecordbuffer); + end; + fnewvaluebuffer:= pdsrecordty(allocrecordbuffer); +// flookupbuffer:= pdsrecordty(allocrecordbuffer); + updatestate; + fallpacketsfetched:= false; + fopen:= true; +end; + +procedure tmsebufdataset.internalopen; +begin + if blobscached then begin + include(fbstate,bs_blobscached); + end + else begin + exclude(fbstate,bs_blobscached); + end; + if streamloading then begin + doloadfromstream; + end + else begin + dointernalopen; + end; + if fdelayedapplycount > 0 then begin + registeronidle; + end; +end; + +procedure tmsebufdataset.openlocal; +var + bo1: boolean; +begin + bo1:= false; + if defaultfields then begin + createfields; + end; + if (floadingstream = nil) and + (flogfilename <> '') and findfile(flogfilename) then begin + floadingstream:= tmsefilestream.create(flogfilename,fm_read); + tmsefilestream(floadingstream).cryptohandler:= fcryptohandler; + bo1:= true; + end; + if floadingstream <> nil then begin + try + doloadfromstream; + finally + if bo1 then begin + freeandnil(floadingstream); + end; + end; + end + else begin + dointernalopen; + fallpacketsfetched:= true; + end; + if (flogfilename <> '') and not (csdesigning in componentstate) then begin + dropupdates1(true); + startlogger; //drop old updates + end; +end; + +procedure tmsebufdataset.dointernalclose; +var + int1: integer; + kind1: filtereditkindty; +begin + unregisteronidle(); + exclude(fbstate,bs_opening); + dropupdates1(false); + closelogger; + frecno:= -1; + resetblobcache; + if fopen then begin + fopen:= false; + with findexes[0] do begin + for int1:= 0 to fbrecordcount - 1 do begin + intfreerecord(pintrecordty(ind[int1])); + end; + end; + intfreerecord(femptybuffer); + for kind1:= low(filtereditkindty) to high(filtereditkindty) do begin + intfinalizerecord(@ffilterbuffer[kind1]^.header); + freerecordbuffer(pchar(ffilterbuffer[kind1])); + end; + freemem(fnewvaluebuffer); //allways copied by move, needs no finalize +// for int1:= 0 to high(fupdatebuffer) do begin +// with fupdatebuffer[int1] do begin +// if bookmark.recordpo <> nil then begin +// intfreerecord(oldvalues); +// end; +// end; +// end; +// fupdatebuffer:= nil; + end; + clearindex; + fbrecordcount:= 0; + + ffieldinfos:= nil; + fstringpositions:= nil; + fvarpositions:= nil; + fcalcfieldbufpositions:= nil; + flookupfieldinfos:= nil; + for int1:= high(flookupmasters) downto 0 do begin + removeitem(pointerarty(flookupmasters[int1].flookupclients),pointer(self)); + end; + flookupmasters:= nil; + fcalcfieldsizes:= nil; + fcalcstringpositions:= nil; + fcalcvarpositions:= nil; + flookupupdate:= 0; + + bindfields(false); +end; + +procedure tmsebufdataset.internalclose; +begin + fappliedcount:= 0; + dointernalclose; +end; + +procedure tmsebufdataset.clearbuffers; +begin + if bs_editing in fbstate then begin + internalcancel; //free data + end; + inherited; +end; + +procedure tmsebufdataset.internalinsert; +begin + include(fbstate,bs_editing); + exclude(fbstate1,bs1_inupdatechanged); + with pdsrecordty(activebuffer)^.dsheader.bookmark.data do begin + recordpo:= nil; + recno:= frecno; + end; + inherited; +end; + +procedure tmsebufdataset.internaledit; +begin + addrefvalues(pdsrecordty(activebuffer)^.header); + fbstate:= fbstate + [bs_startedit,bs_editing]; + exclude(fbstate1,bs1_inupdatechanged); +// include(fbstate,bs_editing); + inherited; +end; + +procedure tmsebufdataset.internalfirst; +begin + internalsetrecno(-1); +end; + +procedure tmsebufdataset.internallast; +begin +{ + repeat + until (getnextpacket < fpacketrecords) or (bs_fetchall in fbstate); +} + getnextpacket(true); + internalsetrecno(fbrecordcount) +end; + +function tmsebufdataset.getrecord(buffer: pchar; getmode: tgetmode; + docheck: boolean): tgetresult; +var + acceptable: boolean; + state1: tdatasetstate; +begin + result:= grok; + acceptable:= true; + fcheckfilterbuffer:= pointer(buffer); + repeat + case getmode of + gmprior: begin + if frecno <= 0 then begin + result := grbof; + end + else begin + internalsetrecno(frecno-1); + end; + end; + gmcurrent: begin + if (frecno < 0) or (frecno >= fbrecordcount) or + (fcurrentbuf = nil) then begin + result := grerror; + end; + end; + gmnext: begin + if frecno >= fbrecordcount - 1 then begin + if getnextpacket(bs_fetchall in fbstate) = 0 then begin + result:= greof; + end + else begin + internalsetrecno(frecno+1); + end; + end + else begin + internalsetrecno(frecno+1); + end; + end; + end; + if result = grok then begin + with pdsrecordty(buffer)^ do begin + with dsheader.bookmark do begin + data.recno:= frecno; + data.recordpo:= fcurrentbuf; + flag:= bfcurrent; + end; + move(fcurrentbuf^.header,header,frecordsize); + getcalcfields(buffer); //get lookup fields + if filtered then begin + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + acceptable:= true; + dofilterrecord(acceptable); + finally + restorestate(state1); + end; + end; + if (getmode = gmcurrent) and not acceptable then begin + result:= grerror; + end; + end; + end; + until acceptable or (result <> grok); + if docheck and (result = grerror) then begin + databaseerror('No record'); + end; +end; + +function tmsebufdataset.getrecordupdatebuffer : boolean; +var + int1: integer; +begin + if bs_recapplying in fbstate then begin + result:= true; //fcurrentupdatebuffer is valid + end + else begin + with pdsrecordty(activebuffer)^.dsheader.bookmark.data do begin + if (fcurrentupdatebuffer >= length(fupdatebuffer)) or + (fupdatebuffer[fcurrentupdatebuffer].info.bookmark.recordpo <> + recordpo) then begin + for int1:= 0 to high(fupdatebuffer) do begin + with fupdatebuffer[int1] do begin + if (info.bookmark.recordpo = recordpo) and + not (ruf_applied in info.flags) then begin + fcurrentupdatebuffer:= int1; + break; + end; + end; + end; + end; + result:= (fcurrentupdatebuffer <= high(fupdatebuffer)) and + (fupdatebuffer[fcurrentupdatebuffer].info.bookmark.recordpo = recordpo) and + (recordpo <> nil); + end; + end; +end; + +procedure tmsebufdataset.internalsettorecord(buffer: pchar); +begin + internalsetrecno(pdsrecordty(buffer)^.dsheader.bookmark.data.recno); +end; + +procedure tmsebufdataset.setbookmarkdata(buffer: pchar; data: pointer); +begin + move(data^,pdsrecordty(buffer)^.dsheader.bookmark,sizeof(bookmarkdataty)); +end; + +procedure tmsebufdataset.setbookmarkflag(buffer: pchar; value: tbookmarkflag); +begin + pdsrecordty(buffer)^.dsheader.bookmark.flag := value; +end; + +procedure tmsebufdataset.GetBookmarkData(Buffer: PChar; Data: Pointer); +begin + move(pdsrecordty(buffer)^.dsheader.bookmark,data^,sizeof(bookmarkdataty)); +end; + +function tmsebufdataset.getbookmarkdata1: bookmarkdataty; +begin + getbookmarkdata(activebuffer,@result); +end; + +function tmsebufdataset.getbookmarkflag(buffer: pchar): tbookmarkflag; +begin + result:= pdsrecordty(buffer)^.dsheader.bookmark.flag; +end; + +function tmsebufdataset.findrecord(arecordpo: pintrecordty): integer; +//-1 if not found +var + int1: integer; + po1: ppointeraty; +begin + if factindex = 0 then begin + result:= -1; + po1:= pointer(findexes[0].ind); + for int1:= fbrecordcount - 1 downto 0 do begin + if po1^[int1] = arecordpo then begin + result:= int1; + break; + end; + end; + end + else begin + result:= findexlocal[factindex-1].findrecord(arecordpo); + end; +end; + +function tmsebufdataset.findbookmarkindex( + const abookmark: bookmarkdataty): integer; +begin + with abookmark do begin + if (recno >= fbrecordcount) or (recno < 0) then begin + databaseerror('Invalid bookmark recno: '+inttostr(recno)+'.'); + end; +// checkindex(false); + checkindex(factindex); + if (factindexpo^.ind[recno] <> recordpo) and (recordpo <> nil) then begin + result:= findrecord(recordpo); + if result < 0 then begin + databaseerror('Invalid bookmarkdata.'); + end; + end + else begin + result:= recno; + end; + end; +end; + +procedure tmsebufdataset.internalgotobookmark(abookmark: pointer); +begin + if abookmark <> nil then begin + internalsetrecno(findbookmarkindex(pbufbookmarkty(abookmark)^.data)); + end; +end; + +function tmsebufdataset.findbookmark(const abookmark: bookmarkdataty): boolean; +var + int1: integer; + bm1: bookmarkdataty; +begin + result:= false; + with abookmark do begin +// checkindex(false); + checkindex(factindex); + if (recno < 0) or (recno >= fbrecordcount) or + (factindexpo^.ind[recno] <> recordpo) and (recordpo <> nil) then begin + int1:= findrecord(recordpo); + end + else begin + int1:= recno; + end; + if int1 >= 0 then begin + bm1:= abookmark; + bm1.recno:= int1; + gotobookmark(@bm1); + result:= true; + end; + end; +end; + +procedure tmsebufdataset.gotobookmark(const abookmark: bookmarkdataty); +begin + gotobookmark(@abookmark); +end; + +function tmsebufdataset.getnextpacket(const all: boolean): integer; +var + state1: tdatasetstate; + int1,int2,int3: integer; + recnobefore: integer; + bufbefore: pointer; + bo1,bo2: boolean; + ar1: fieldarty; + field1: tfield; + {$ifdef mse_debugdataset} + ts: longword; + {$endif} + +begin + result:= 0; + if fallpacketsfetched then begin + exit; + end; + int2:= fbrecordcount; + database.beforeaction; + try +{$ifdef mse_debugdataset} + if all then begin + debugoutstart(ts,self,'getnextpacket all'); + end + else begin + debugoutstart(ts,self,'getnextpacket'); + end; +{$endif} + while ((result < fpacketrecords) or all) and + (loadbuffer(femptybuffer^.header) = grok) do begin + appendrecord(femptybuffer); + femptybuffer:= intallocrecord; + inc(result); + end; + bo1:= checkcanevent(self,tmethod(foninternalcalcfields)); + bo2:= (bs_initinternalcalc in fbstate); + if bo2 then begin + setlength(ar1,fields.count); + int3:= 0; + for int1:= 0 to high(ar1) do begin + field1:= fields[int1]; + with field1 do begin + if (fieldkind = fkinternalcalc) and (defaultexpression <> '') then begin + ar1[int3]:= field1; + inc(int3); + end; + end; + end; + setlength(ar1,int3); + end; + if bo1 or bo2 then begin + state1:= settempstate(dsinternalcalc); + fbstate:= fbstate + [bs_internalcalc,bs_fetching]; + recnobefore:= frecno; + bufbefore:= fcurrentbuf; + try + for int1:= int2 to fbrecordcount-1 do begin + frecno:= int1; + fcurrentbuf:= findexes[0].ind[int1]; + if bo2 then begin + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + asstring:= defaultexpression; + end; + end; + end; + if bo1 then begin + foninternalcalcfields(self,true); + end; + end; + finally + frecno:= recnobefore; + fcurrentbuf:= bufbefore; + fbstate:= fbstate - [bs_internalcalc,bs_opening,bs_fetching]; + restorestate(state1); + end; + end; + exclude(fbstate,bs_opening); + {$ifdef mse_debugdataset} + debugoutend(ts,self,'getnextpacket'); + {$endif} + finally + database.afteraction; + end; +end; + +function tmsebufdataset.getfieldsize(const datatype: tfieldtype; + const varsize: integer; out basetype: tfieldtype): longint; +begin + case datatype of + ftstring,ftfixedchar,ftwidestring,ftfixedwidechar,ftwidememo: begin + result:= sizeof(msestring); + basetype:= ftwidestring; + end; + ftbytes: begin + result:= varsize; + basetype:= ftbytes; + end; + ftvarbytes: begin + result:= varsize + sizeof(word); + basetype:= ftvarbytes; + end; + ftguid: begin + result:= sizeof(tguid); + basetype:= ftguid; + end; + ftsmallint,ftinteger,ftword: begin + result:= sizeof(longint); + basetype:= ftinteger; + end; + ftboolean: begin + result:= sizeof(longbool); + basetype:= ftboolean; + end; + ftbcd: begin + result:= sizeof(currency); + basetype:= ftbcd; + end; + ftfloat,ftcurrency: begin + result:= sizeof(double); + basetype:= ftfloat; + end; + ftlargeint: begin + result:= sizeof(largeint); + basetype:= ftlargeint; + end; + fttime,ftdate,ftdatetime: begin + result:= sizeof(tdatetime); + basetype:= ftdatetime; + end; + ftmemo,ftblob: begin + result:= getblobdatasize; + basetype:= ftblob; + end; + ftvariant: begin + result:= sizeof(variant); + basetype:= ftvariant; + end; + else begin + result:= 0; + basetype:= ftunknown; + end; + end; +end; + +function tmsebufdataset.loadbuffer(var buffer: recheaderty): tgetresult; +var + int1,int2: integer; + str1: string; + field1: tfield; + po2: pmsestring; + fno: integer; +begin + if not fetch then begin + result := greof; + fallpacketsfetched := true; + exit; + end; + pointer(buffer.blobinfo):= nil; + fillchar(buffer.fielddata.nullmask,fnullmasksize,$ff); + for int1:= 0 to fields.count-1 do begin + field1:= fields[ffieldorder[int1]]; //ODBC needs ordered loadfield + fno:= field1.fieldno-1; + with ffieldinfos[fno].base do begin + case field1.fieldkind of + fkdata: begin + int2:= dbfieldsize; + if field1.datatype in charfields then begin + int2:= int2*4+4; //room for multibyte encodings + setlength(str1,int2); + if not loadfield(fno,fieldtype,pointer(str1),int2) then begin + clearfieldflag(@buffer.fielddata.nullmask,fno); + end + else begin + if int2 < 0 then begin //buffer to small + int2:= -int2; + setlength(str1,int2); + loadfield(fno,fieldtype,pointer(str1),int2); + end; + setlength(str1,int2); + po2:= pointer(pchar(@buffer) + offset); + if fieldtype in widecharfields then begin + setlength(po2^,int2 div 2); + move(pointer(str1)^,pointer(po2^)^,int2); + end + else begin + try + if bs_utf8 in fbstate then begin + po2^:= utf8tostringansi(str1); + end + else begin + po2^:= msestring(str1); + end; + except + po2^:= converrorstring; + end; + end; + if (dbfieldsize <> 0) and (length(po2^) > dbfieldsize) then begin + setlength(po2^,dbfieldsize); + end; + end; + end + else begin + if not loadfield(fno,fieldtype,pchar(@buffer)+offset,int2) or + (int2 < 0)then begin + clearfieldflag(@buffer.fielddata.nullmask,fno); //buffer too small + end; + end; + end; + fkinternalcalc: begin + clearfieldflag(@buffer.fielddata.nullmask,fno); + end; + end; + end; + end; + result:= grok; +end; + +function tmsebufdataset.getfieldbuffer(const afield: tfield; + out buffer: pointer; out datasize: integer): boolean; + //read buffer + //true if not null +var + int1: integer; + st1: integer; +begin + result:= false; + buffer:= nil; + if not fopen{active} then begin + exit; + end; + int1:= afield.fieldno - 1; + if (flookuppo <> nil) and (int1 >= 0) then begin + buffer:= flookuppo; + result:= getfieldflag(@precheaderty(buffer)^.fielddata.nullmask,int1); + inc(pchar(buffer),ffieldinfos[int1].base.offset{ffieldbufpositions[int1]}); + datasize:= ffieldinfos[int1].base.size{ffieldsizes[int1]}; + exit; + end; + st1:= ord(state); + if bs_displaydata in fbstate then begin + st1:= ord(dsbrowse); + end; + case st1 of + ord(dscalcfields): begin + buffer:= @pdsrecordty(fcalcbuffer1)^.header; + end; + dscheckfilter: begin + buffer:= @fcheckfilterbuffer^.header; + end; + ord(dsfilter): begin + buffer:= @ffilterbuffer[ffiltereditkind]^.header; + end; + ord(dscurvalue): begin + if (buffercount <= 0) or //probably fetchallblobs() + (pdsrecordty(activebuffer)^.dsheader.bookmark.data.recordpo <> + nil) then begin + buffer:= @fcurrentbuf^.header; + end + else begin + buffer:= @pdsrecordty(activebuffer)^.header; //insert + end; + end; + else begin + if fbstate * [bs_internalcalc,bs_displaydata] = [bs_internalcalc] then begin + if int1 < 0 then begin//calc field + buffer:= @pdsrecordty(activebuffer)^.header; + //values invalid! + end + else begin + buffer:= @fcurrentbuf^.header; + end; + end + else begin + if fbstate*[bs_recapplying,bs_displaydata] = [bs_recapplying] then begin + buffer:= @fnewvaluebuffer^.header; + end + else begin + buffer:= @pdsrecordty(activebuffer)^.header; + end; + end; + end; + end; + if int1 >= 0 then begin // data field + result:= false; + if state = dsoldvalue then begin + if getrecordupdatebuffer then begin + buffer:= fupdatebuffer[fcurrentupdatebuffer].oldvalues; + if buffer <> nil then begin + buffer:= @pintrecordty(buffer)^.header; + end; + end + else begin //there is no old value available + if pdsrecordty(activebuffer)^.dsheader.bookmark.data.recordpo <> nil + then begin //dsinsert otherwise + buffer:= @fcurrentbuf^.header + end; + end; + end; + if buffer <> nil then begin + result:= getfieldflag(@precheaderty(buffer)^.fielddata.nullmask,int1); + inc(pchar(buffer),ffieldinfos[int1].base.offset{ffieldbufpositions[int1]}); + datasize:= ffieldinfos[int1].base.size{ffieldsizes[int1]}; + end + else begin + datasize:= 0; + end; + end + else begin + int1:= -2 - int1; + if int1 >= 0 then begin //calc field + result:= getfieldflag(pointer(pchar(buffer)+frecordsize),int1); + inc(pchar(buffer),fcalcfieldbufpositions[int1]); + datasize:= fcalcfieldsizes[int1]; + end + else begin + buffer:= nil; + datasize:= 0; + end; + end; +end; + +function tmsebufdataset.getfieldbuffer(const afield: tfield; + const aisnull: boolean; out datasize: integer): pointer; + //write buffer +var + int1: integer; + state1: tdatasetstate; +begin + if (bs_recapplying in fbstate) and (state = dsbrowse) then begin + state1:= dsedit; //dummy + include(fbstate,bs_curvaluemodified); + end + else begin + if not ((state in dswritemodes - [dsinternalcalc,dscalcfields]) or + (afield.fieldkind = fkinternalcalc) and + (state = dsinternalcalc) or + (afield.fieldkind = fkcalculated) and + (state = dscalcfields) or + (afield.fieldkind = fklookup) + {or + (bs_curvaluesetting in fbstate) and (state = dscurvalue)}) then begin + databaseerrorfmt(snotediting,[name],self); + end; + state1:= state; + end; + int1:= afield.fieldno-1; + case state1 of + dscalcfields: begin + result:= @pdsrecordty(fcalcbuffer1)^.header; + end; + dsfilter: begin + result:= @ffilterbuffer[ffiltereditkind]^.header; + end; + dscurvalue: begin + result:= @fcurrentbuf^.header; + end; + else begin + if bs_internalcalc in fbstate then begin + if int1 < 0 then begin//calc field + result:= @pdsrecordty(activebuffer)^.header; + //values invalid! + end + else begin + result:= @fcurrentbuf^.header; + end; + end + else begin + if bs_recapplying in fbstate then begin + result:= @fnewvaluebuffer^.header; + end + else begin + result:= @pdsrecordty(activebuffer)^.header; + end; + if (int1 >= 0) and // data field + (of_inupdate in afield.optionsfield) then begin + include(fbstate1,bs1_inupdatechanged); + end; + end; + end; + end; + if int1 >= 0 then begin // data field + if aisnull then begin + clearfieldflag(@precheaderty(result)^.fielddata.nullmask,int1); + end + else begin + setfieldflag(@precheaderty(result)^.fielddata.nullmask,int1); + end; + inc(pchar(result),ffieldinfos[int1].base.offset{ffieldbufpositions[int1]}); + datasize:= ffieldinfos[int1].base.size{ffieldsizes[int1]}; + end + else begin + int1:= -2 - int1; + if int1 >= 0 then begin //calc field + if aisnull then begin + clearfieldflag(pbyte(pchar(result)+frecordsize),int1); + end + else begin + setfieldflag(pbyte(pchar(result)+frecordsize),int1); + end; + inc(pchar(result),fcalcfieldbufpositions[int1]); + datasize:= fcalcfieldsizes[int1]; + end + else begin + result:= nil; + datasize:= 0; + end; + end; +end; + +procedure tmsebufdataset.fieldchanged(const field: tfield); +begin + if {(field.fieldno > 0) and} not + (state in [dscalcfields,dsinternalcalc,{dsfilter,}dsnewvalue]) and + not (bs_recapplying in fbstate) then begin + dataevent(defieldchange, ptrint(field)); + end; +end; + +function tmsebufdataset.getfielddata(field: tfield; buffer: pointer): boolean; +var + po1: pointer; + datasize: integer; +begin + result:= getfieldbuffer(field,po1,datasize); + if (buffer <> nil) and result then begin + move(po1^,buffer^,datasize); + end; +end; + +function tmsebufdataset.getfielddata(field: tfield; buffer: pointer; + nativeformat: boolean): boolean; +begin + result:= getfielddata(field,buffer); +end; + +function tmsebufdataset.getmsestringdata(const sender: tmsestringfield; + out avalue: msestring): boolean; +var + po1: pointer; + int1: integer; +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(sender) do begin + {$ifdef FPC}{$warnings on}{$endif} + if fvalidating then begin + result:= (fvaluebuffer <> nil) and (foffset and 1 = 0); + po1:= fvaluebuffer; + end + else begin + result:= getfieldbuffer(sender,po1,int1); + end; + end; + if result then begin + avalue:= msestring(po1^); + end + else begin + avalue:= ''; + end; +end; + +function tmsebufdataset.getvardata(const sender: tmsevariantfield; + out avalue: variant): boolean; +var + po1: pvariant; + int1: integer; +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(sender) do begin + {$ifdef FPC}{$warnings on}{$endif} + if fvalidating then begin + result:= (fvaluebuffer <> nil) and (foffset and 1 = 0); + po1:= fvaluebuffer; + end + else begin + result:= getfieldbuffer(sender,pointer(po1),int1); + end; + end; + if result then begin + avalue:= po1^; + end + else begin + avalue:= null; + end; +end; + +procedure tmsebufdataset.checkfreebuffer(const afield: tfield); +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(afield) do begin + {$ifdef FPC}{$warnings on}{$endif} + if foffset and 2 <> 0 then begin + freemem(fvaluebuffer); + fvaluebuffer:= nil; + end; + end; +end; + +function tmsebufdataset.callvalidate(const afield: tfield; + const avalue: pointer): boolean; + //true if not nulled +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(afield) do begin + {$ifdef FPC}{$warnings on}{$endif} + foffset:= 0; + fvaluebuffer:= avalue; + afield.validate(avalue); + result:= (avalue <> nil) and (foffset and 1 = 0); + end; +end; + +procedure tmsebufdataset.checkvaluebuffer(const afield: tfield; + const asize: integer); +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(afield) do begin + {$ifdef FPC}{$warnings on}{$endif} + foffset:= foffset and not 1; + if fvaluebuffer = nil then begin + getmem(fvaluebuffer,asize); + fillchar(fvaluebuffer^,asize,0); + foffset:= foffset or 2; + end; + end; +end; + +procedure tmsebufdataset.setfielddata(field: tfield; buffer: pointer); + +var + po1: pointer; + datasize1: integer; +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(field) do begin + {$ifdef FPC}{$warnings on}{$endif} + if fvalidating then begin + if buffer = nil then begin + foffset:= foffset or 1; + end + else begin + getfieldbuffer(field,po1,datasize1); //get data size + checkvaluebuffer(field,datasize1); + move(buffer^,fvaluebuffer^,datasize1); + end; + end + else begin + try + if callvalidate(field,buffer) then begin + po1:= getfieldbuffer(field,false,datasize1); + move(fvaluebuffer^,po1^,datasize1); + end + else begin + po1:= getfieldbuffer(field,true,datasize1); + case field.datatype of + ftstring: begin + pmsestring(po1)^:= ''; + end; + ftvariant: begin + freedbvariant(pvariant(po1)^); + end; + else begin + fillchar(po1^,datasize1,0); + end; + end; + end; + finally + checkfreebuffer(field); + end; + fieldchanged(field); + end; + end; +end; + +procedure tmsebufdataset.setfielddata(field: tfield; buffer: pointer; + nativeformat: boolean); +begin + setfielddata(field,buffer); +end; + +procedure tmsebufdataset.setmsestringdata(const sender: tmsestringfield; + avalue: msestring); +var + po1: pmsestring; + int1: integer; +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(sender) do begin + {$ifdef FPC}{$warnings on}{$endif} + if fvalidating then begin + checkvaluebuffer(sender,sizeof(msestring)); + pmsestring(fvaluebuffer)^:= avalue; + end + else begin + try + if callvalidate(sender,@avalue) then begin + po1:= getfieldbuffer(sender,false,int1); + po1^:= pmsestring(fvaluebuffer)^; + if (sender.characterlength > 0) and + (length(avalue) > sender.characterlength) then begin + setlength(msestring(po1^),sender.characterlength); + end; + end + else begin + po1:= getfieldbuffer(sender,true,int1); + po1^:= ''; + end; + finally + pmsestring(fvaluebuffer)^:= ''; + checkfreebuffer(sender); + end; + fieldchanged(sender); + end; + end; +end; + +procedure tmsebufdataset.setvardata(const sender: tmsevariantfield; + avalue: variant); +var + po1: pvariant; + int1: integer; +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(sender) do begin + {$ifdef FPC}{$warnings on}{$endif} + if fvalidating then begin + checkvaluebuffer(sender,sizeof(variant)); + pvariant(fvaluebuffer)^:= avalue; + end + else begin + try + if callvalidate(sender,@avalue) then begin + po1:= getfieldbuffer(sender,false,int1); + po1^:= pvariant(fvaluebuffer)^; + end + else begin + po1:= getfieldbuffer(sender,true,int1); + finalize(po1^); + fillchar(po1^,sizeof(variant),0); + end; + finally + finalize(pvariant(fvaluebuffer)^); + checkfreebuffer(sender); + end; + fieldchanged(sender); + end; + end; +end; + +procedure tmsebufdataset.getnewupdatebuffer; +begin + setlength(fupdatebuffer,high(fupdatebuffer)+2); + fcurrentupdatebuffer:= high(fupdatebuffer); +end; + +procedure tmsebufdataset.internaldelete; +var + po1: pintrecordty; + recnobefore: integer; +begin + if state = dsedit then begin + internalcancel; + end; + po1:= fcurrentbuf; + recnobefore:= frecno; + deleterecord(frecno); + if not (bdo_noapply in foptions) then begin + if not getrecordupdatebuffer then begin + getnewupdatebuffer; + with fupdatebuffer[fcurrentupdatebuffer] do begin + info.bookmark.recno:= recnobefore; + info.bookmark.recordpo:= po1; + oldvalues:= info.bookmark.recordpo; + end; + end + else begin + with fupdatebuffer[fcurrentupdatebuffer] do begin + intfreerecord(info.bookmark.recordpo); + if info.updatekind = ukmodify then begin + info.bookmark.recordpo:= oldvalues; + end + else begin //ukinsert + info.bookmark.recordpo := nil; //this 'disables' the updatebuffer + end; + end; + end; + fupdatebuffer[fcurrentupdatebuffer].info.updatekind := ukdelete; + if flogger <> nil then begin + logupdatebuffer(flogger,fupdatebuffer[fcurrentupdatebuffer],po1,true,lf_update); + flogger.flushbuffer; + end; + end; +end; + +procedure tmsebufdataset.applyrecupdate(updatekind : tupdatekind); +begin + raise edatabaseerror.create(sapplyrecnotsupported); +end; + +procedure tmsebufdataset.cancelrecupdate(var arec: recupdatebufferty); +begin + if (flogger <> nil) and not (bs_loading in fbstate) then begin + logupdatebuffer(flogger,arec,nil,true,lf_cancel); + flogger.flushbuffer; + end; + with arec do begin + if info.bookmark.recordpo <> nil then begin + if info.updatekind = ukmodify then begin + freeblobs(info.bookmark.recordpo^.header.blobinfo); + finalizevalues(info.bookmark.recordpo^.header); + move(oldvalues^.header,info.bookmark.recordpo^.header,frecordsize); + freemem(oldvalues); //no finalize + end + else begin + if info.updatekind = ukdelete then begin + insertrecord(info.bookmark.recno,info.bookmark.recordpo); + end + else begin + if info.updatekind = ukinsert then begin + deleterecord(info.bookmark.recordpo); + if info.bookmark.recordpo = fcurrentbuf then begin + fcurrentbuf:= nil; + if frecno >= 0 then begin + dec(frecno); + end; + end; + intfreerecord(info.bookmark.recordpo); + end; + end; + end; + end; + end; +end; + +procedure tmsebufdataset.cancelupdate(const norecordcancel: boolean = false); +var + int1: integer; +begin + cancel; + checkbrowsemode; + if (fupdatebuffer <> nil) and (frecno >= 0) then begin + for int1:= high(fupdatebuffer) downto 0 do begin + if fupdatebuffer[int1].info.bookmark.recordpo = fcurrentbuf then begin + if not norecordcancel then begin + cancelrecupdate(fupdatebuffer[int1]); + end + else begin + with fupdatebuffer[int1] do begin + intFreeRecord(OldValues); + info.bookmark.recordpo:= nil + end; + end; + deleteitem(fupdatebuffer,typeinfo(recupdatebufferarty),int1); + if int1 <= fapplyindex then begin + dec(fapplyindex); + end; + resync([]); + break; + end; + end; + end; +end; + +procedure tmsebufdataset.cancelupdates; +var + int1: integer; +begin + cancel; + checkbrowsemode; + if high(fupdatebuffer) >= 0 then begin + for int1:= high(fupdatebuffer) downto 0 do begin + cancelrecupdate(fupdatebuffer[int1]); + end; + fupdatebuffer:= nil; + resync([]); + end; +end; + +procedure tmsebufdataset.dropupdates1(const apply: boolean); +var + po1: precupdatebufferty; + i1: int32; +begin + for i1:= 0 to high(fupdatebuffer) do begin + po1:= @fupdatebuffer[i1]; + with po1^ do begin + if info.bookmark.recordpo <> nil then begin + if apply or (ruf_applied in info.flags) then begin + recupdatebufferapplied(po1); + end + else begin + recupdatebufferdropped(po1); + end; + end; + end; + end; + fupdatebuffer:= nil; +end; + +procedure tmsebufdataset.SetOnUpdateError(const AValue: updateerroreventty); + +begin + FOnUpdateError := AValue; +end; + +procedure tmsebufdataset.recupdatebufferapplied(const abuf: precupdatebufferty); +begin + if flogger <> nil then begin + logupdatebuffer(flogger,abuf^,nil,true,lf_apply); + flogger.flushbuffer; + end; + intFreeRecord(abuf^.OldValues); + abuf^.info.bookmark.recordpo:= nil; +end; + +procedure tmsebufdataset.recupdatebufferdropped(const abuf: precupdatebufferty); +begin + if flogger <> nil then begin + logupdatebuffer(flogger,abuf^,nil,true,lf_drop); + flogger.flushbuffer; + end; + with abuf^ do begin + intfreerecord(oldvalues); + end; +end; + +procedure tmsebufdataset.packrecupdatebuffer; +var + int1,int2: integer; +begin + int2:= 0; + for int1:= 0 to high(fupdatebuffer) do begin //pack + with fupdatebuffer[int1] do begin + if (info.bookmark.recordpo <> nil) or (oldvalues <> nil) then begin + fupdatebuffer[int2]:= fupdatebuffer[int1]; + inc(int2); + end; + end; + end; + setlength(fupdatebuffer,int2); +end; + +procedure tmsebufdataset.restorerecupdatebuffer; +var + int1: integer; +begin + for int1:= high(fupdatebuffer) downto 0 do begin + exclude(fupdatebuffer[int1].info.flags,ruf_applied); + end; +end; + +procedure tmsebufdataset.postrecupdatebuffer; +var + po1: precupdatebufferty; + int1,int2: integer; +begin + int2:= 0; + for int1:= high(fupdatebuffer) downto 0 do begin + po1:= @fupdatebuffer[int1]; + with po1^ do begin + if (ruf_applied in info.flags) and (info.bookmark.recordpo <> nil) then begin + inc(int2); + recupdatebufferapplied(po1); + end; + end; + end; + if int2 = length(fupdatebuffer) then begin + fupdatebuffer:= nil; + end + else begin + packrecupdatebuffer; + end; +end; + +procedure tmsebufdataset.internalapplyupdate(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean; + out response: resolverresponsesty); + + procedure checkrevert; + var + po1: precupdatebufferty; + begin + po1:= @fupdatebuffer[fcurrentupdatebuffer]; + if rr_applied in response then begin + if bs1_deferdeleterecupdatebuffer in fbstate1 then begin + include(po1^.info.flags,ruf_applied); + end + else begin + recupdatebufferapplied(po1); + end; + end + else begin + if (cancelonerror or + cancelondeleteerror and (po1^.info.updatekind = ukdelete)) or + (rr_revert in response) then begin + cancelrecupdate(po1^); + po1^.info.bookmark.recordpo:= nil; + exclude(fbstate,bs_curvaluemodified); + end; + end; + end; //checkrevert + +var + by1,by2: boolean; + e1: exception; + ar1,ar2,ar3: integerarty; +// int1: integer; + origpo: pintrecordty; + +begin + include(fbstate,bs_recapplying); + by1:= not islocal; + by2:= false; + response:= []; + with fupdatebuffer[fcurrentupdatebuffer] do begin + origpo:= info.bookmark.recordpo; + move(origpo^.header,fnewvaluebuffer^.header,frecordsize); + addrefvalues(fnewvaluebuffer^.header); + try + if (info.updatekind <> ukmodify) or (ruf_inupdate in info.flags) then begin + repeat + exclude(fbstate,bs_curvaluemodified); + getcalcfields(pchar(fnewvaluebuffer)); + if rr_again in response then begin + dec(ffailedcount); + exclude(info.flags,ruf_error); + end; + Response:= [rr_applied]; + try + try + if by1 then begin + ApplyRecUpdate(info.UpdateKind); + inc(fappliedcount); + end; + except + on E: EDatabaseError do begin + include(info.flags,ruf_error); + e1:= e; + Inc(fFailedCount); + if e is eapplyerror then begin + response:= eapplyerror(e).response; + end + else begin + if longword(ffailedcount) > longword(MaxErrors) then begin + Response:= [rr_abort] + end + else begin + Response:= []; + end; + end; + e.message:= 'An error occured while applying the updates in a record: '+ + e.message; + if checkcanevent(self,tmethod(OnUpdateError)) then begin + OnUpdateError(Self,edatabaseerror(e1),info.UpdateKind,Response); + if rr_applied in response then begin + dec(ffailedcount); + end; + end; + if rr_abort in response then begin + checkrevert; + if not (rr_quiet in response) then begin + if e = e1 then begin + raise; + end + else begin + if e1 <> nil then begin + Raise e1; + end; + end; + end; + end; + end + else begin + raise; + end; + end; + finally + if bs_curvaluemodified in fbstate then begin + by2:= true; + dointernalcalcfields(false); + // if (updatekind = ukmodify) and + // (bs_refreshupdateindex in fbstate) or + // (updatekind = ukinsert) and + // (bs_refreshinsertindex in fbstate) then begin + // int1:= factindex; + // factindex:= -1; //do not use recno + + saveindex(origpo,@fnewvaluebuffer^.header,ar1,ar2,ar3); + relocateindex(origpo,ar1,ar2,ar3); + // factindex:= int1; + // end; + end; + end; + until response <> [rr_again]; + checkrevert; + end + else begin + response:= [rr_applied,rr_skipped]; + checkrevert(); + end; + finally + exclude(fbstate,bs_recapplying); + if by2 and (info.updatekind <> ukdelete) then begin + include(fbstate1,bs1_needsresync); + finalizevalues(origpo^.header); + move(fnewvaluebuffer^.header,origpo^.header,frecordsize); + end + else begin + finalizevalues(fnewvaluebuffer^.header); + end; + finalizecalcvalues(fnewvaluebuffer^.header); + end; + end; +end; + +procedure tmsebufdataset.afterapply; +begin + //dummy +end; + +procedure tmsebufdataset.editapplyerror(const arecupdatenum: integer); +var + po1: pintrecordty; + info1: recupdatebufferty; +begin + disablecontrols; + try + info1:= fupdatebuffer[arecupdatenum]; + with info1 do begin + if (info.updatekind = ukdelete) or findbookmark(info.bookmark) then begin + po1:= nil; + if info.updatekind in [ukinsert,ukmodify] then begin + po1:= intallocrecord; + move(fcurrentbuf^.header,po1^.header,frecordsize); + addrefvalues(po1^.header); + end; + try + cancelrecupdate(info1); + resync([]); + deleteitem(fupdatebuffer,typeinfo(recupdatebufferarty),arecupdatenum); + if info.updatekind = ukdelete then begin + findbookmark(info.bookmark) + end + else begin + if info.updatekind in [ukmodify,ukinsert] then begin + if info.updatekind = ukmodify then begin + edit; + end + else begin + if ruf_append in info.flags then begin + append(); + end + else begin + insert(); + end; + end; + finalizevalues(pdsrecordty(activebuffer)^.header); + finalizecalcvalues(pdsrecordty(activebuffer)^.header); + move(po1^,pdsrecordty(activebuffer)^.header,frecordsize); + freemem(po1); + setmodified(true); + getcalcfields(activebuffer); + end; + end; + except + if po1 <> nil then begin + intfreerecord(po1); + end; + raise; + end; + end; + end; + finally + enablecontrols; + end; +end; + +procedure tmsebufdataset.applyupdate(const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); + //applies current record +var + response: resolverresponsesty; + canedit1: boolean; + recupdatebuffernum1: integer; +begin + if not (bs_applying in fbstate) then begin + include(fbstate,bs_applying); + try + canedit1:= false; + checkbrowsemode; + dobeforeapplyupdate; + checkbrowsemode; + if getrecordupdatebuffer then begin + canedit1:= editonerror; + if canedit1 then begin + recupdatebuffernum1:= fcurrentupdatebuffer; + end; + ffailedcount:= 0; + exclude(fbstate1,bs1_needsresync); + try + internalapplyupdate(0,cancelonerror,cancelondeleteerror,response); + if rr_applied in response then begin + canedit1:= false; + end; + finally + if (fcurrentupdatebuffer <= high(fupdatebuffer)) and //??? + (FUpdateBuffer[fcurrentupdatebuffer].info.Bookmark.recordpo = nil) then begin + deleteitem(fupdatebuffer,typeinfo(recupdatebufferarty),fcurrentupdatebuffer); + canedit1:= false; + end; + if bs1_needsresync in fbstate1 then begin + resync([]); + end; + end; + if rr_applied in response then begin + dataevent(tdataevent(de_afterapplyupdate),0); + afterapply; //possible commit + end; + end; + doafterapplyupdate; + finally + exclude(fbstate,bs_applying); + if canedit1 then begin + editapplyerror(recupdatebuffernum1); + end; + end; + end; +end; + +procedure tmsebufdataset.ApplyUpdates(const MaxErrors: Integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); +var + recnobefore: integer; + response: resolverresponsesty; + bo1: boolean; + canedit1: boolean; + recupdatenum1: integer; + +begin + if not (bs_applying in fbstate) then begin + include(fbstate,bs_applying); + canedit1:= false; + try + CheckBrowseMode; + dobeforeapplyupdate; + CheckBrowseMode; + disablecontrols; + recnobefore:= frecno; + try + fapplyindex := 0; + fFailedCount := 0; + bo1:= false; + response:= []; + while (fapplyindex <= high(FUpdateBuffer)) and not(rr_abort in response) do begin + canedit1:= editonerror; + fcurrentupdatebuffer:= fapplyindex; + recupdatenum1:= fcurrentupdatebuffer; + with fupdatebuffer[fcurrentupdatebuffer] do begin + if (info.bookmark.recordpo <> nil) and not (ruf_applied in info.flags) then begin + internalapplyupdate(maxerrors,cancelonerror, + cancelondeleteerror,response); + bo1:= bo1 or not (rr_applied in response); + if rr_applied in response then begin + canedit1:= false; + end; + end; + end; + inc(fapplyindex); + // if (bs_idle in fbstate) and not application.idle then begin + // break; + // end; + //win98 is not idle after applyupdate ??? + end; + finally + fcurrentupdatebuffer:= bigint; //invalid + if not (bs1_deferdeleterecupdatebuffer in fbstate1) then begin + if (ffailedcount = 0) and (fapplyindex > high(fupdatebuffer)) then begin + fupdatebuffer:= nil; + end + else begin + packrecupdatebuffer; + end; + end; + if active then begin + internalsetrecno(recnobefore); + resync([]); + enablecontrols; + end + else begin + enablecontrols; + end; + end; + if not bo1 then begin + dataevent(tdataevent(de_afterapplyupdate),0); + afterapply; //possible commit + end; + doafterapplyupdate; + finally + exclude(fbstate,bs_applying); + if canedit1 then begin + editapplyerror(recupdatenum1); + end; + end; + end; +end; + +procedure tmsebufdataset.ApplyUpdates(const maxerrors: integer = 0); +begin + applyupdates(maxerrors,false); +end; + +procedure tmsebufdataset.applyupdate; +begin + applyupdate(false); +end; + +procedure tmsebufdataset.saveindex(const oldbuffer,newbuffer: pintrecordty; + var ar1,ar2,ar3: integerarty); +var + int1: integer; + lastind: integer; +begin + if (bs_hasvalidindex in fbstate) then begin + setlength(ar1,findexlocal.count); + setlength(ar2,length(ar1)); + setlength(ar3,length(ar1)); + for int1:= high(ar1) downto 0 do begin + if findexes[int1+1].ind <> nil then begin + with findexlocal[int1] do begin + lastind:= high(findexfieldinfos); + ar2[int1]:= compare1(oldbuffer,newbuffer,lastind,false); + if ar2[int1] <> 0 then begin + if int1 = factindex - 1 then begin + ar1[int1]:= frecno + 1; //for fast find of bufpo + end + else begin + ar1[int1]:= findboundary(@compare1,oldbuffer,lastind,true); //old boundary + end; + ar3[int1]:= findboundary(@compare1,newbuffer,lastind,true); //new boundary + end; + end; + end; + end; + end; +end; + +procedure tmsebufdataset.relocateindex(const abuffer: pintrecordty; + const ar1,ar2,ar3: integerarty); +var + int1,int2,int3: integer; +begin + if bs_hasvalidindex in fbstate then begin +// with pdsrecordty(activebuffer)^ do begin + for int1:= high(ar1) downto 0 do begin + if findexes[int1+1].ind <> nil then begin + if ar2[int1] <> 0 then begin // position changed + include(fbstate1,bs1_needsresync); + int2:= ar3[int1]; //new boundary + with findexes[int1+1] do begin + for int3:= ar1[int1] - 1 downto 0 do begin + if ind[int3] = abuffer then begin //update indexes + move(ind[int3+1],ind[int3],(fbrecordcount-int3-1)*sizeof(pointer)); + if int3 < int2 then begin + dec(int2); + end; + move(ind[int2],ind[int2+1],(fbrecordcount-int2-1)*sizeof(pointer)); + ind[int2]:= abuffer; + if (int1 = factindex - 1) then begin + frecno:= int2; + end; + break; + end; + end; + end; + end; + end; + end; + end + else begin +// if factindex > 0 then begin +// include(fbstate1,bs1_needsresync); +// end; + end; +// end; +end; + +procedure tmsebufdataset.internalpost; +var + po1,po2: pblobinfoarty; + po3: pointer; + int1{,int2,int3}: integer; + bo1: boolean; + ar1,ar2,ar3: integerarty; + newupdatebuffer: boolean; + canapply: boolean; + +begin + checkindex(factindex); + with pdsrecordty(activebuffer)^ do begin + bo1:= false; + if state = dsinsert then begin + fcurrentbuf:= intallocrecord; + end; + newupdatebuffer:= false; + canapply:= not (bdo_noapply in foptions); + if canapply then begin + newupdatebuffer:= not getrecordupdatebuffer; + if newupdatebuffer then begin + getnewupdatebuffer; + with fupdatebuffer[fcurrentupdatebuffer] do begin + info.bookmark.recordpo:= fcurrentbuf; + info.bookmark.recno:= frecno; + if state = dsedit then begin + oldvalues:= intallocrecord; + move(info.bookmark.recordpo^,oldvalues^,frecordsize+intheadersize); + addrefvalues(oldvalues^.header); + po1:= getintblobpo; + if po1^ <> nil then begin + po2:= @oldvalues^.header.blobinfo; + pointer(po2^):= nil; + setlength(po2^,length(po1^)); + for int1:= high(po1^) downto 0 do begin //copy blobs + po2^[int1]:= po1^[int1]; + with po2^[int1] do begin + if datalength > 0 then begin + getmem(po3,datalength); + move(data^,po3^,datalength); + data:= po3; + end + else begin + data:= nil; + end; + end; + end; + end; + info.updatekind := ukmodify; + end + else begin + info.updatekind := ukinsert; + if frecno = frecordcount-1 then begin + include(info.flags,ruf_append); + end + else begin + exclude(info.flags,ruf_append); + end; + end; + end; + end; + if bs1_inupdatechanged in fbstate1 then begin + with fupdatebuffer[fcurrentupdatebuffer] do begin + include(info.flags,ruf_inupdate); + end; + end; + end; + + with header do begin + for int1:= high(blobinfo) downto 0 do begin + with blobinfo[int1] do begin + if new then begin +// deleteblob(fcurrentbuf^.header.blobinfo,field,false); + deleteblob(fcurrentbuf^.header.blobinfo,field,true); + //no reassign of blobinfo + //blobcache data needed for possible cancelupdate + new:= false; + bo1:= true; + end; + end; + end; + end; + + if (state = dsedit) then begin + saveindex(fcurrentbuf,@header,ar1,ar2,ar3); + end; + if bo1 then begin + fcurrentbuf^.header.blobinfo:= nil; //free old array + end; + finalizevalues(fcurrentbuf^.header); + move(header,fcurrentbuf^.header,frecordsize); //get new field values + + if (flogger <> nil) and canapply then begin + logrecbuffer(flogger,fupdatebuffer[fcurrentupdatebuffer].info.updatekind, + fcurrentbuf); + if newupdatebuffer then begin + logupdatebuffer(flogger,fupdatebuffer[fcurrentupdatebuffer],nil,true, + lf_update); + end; + flogger.flushbuffer; + end; + + if state = dsinsert then begin + with dsheader.bookmark do begin + frecno:= insertrecord(frecno,fcurrentbuf); + if factindexpo^.ind = nil then begin + checkindex(factindex); //for first record + end; + fcurrentbuf:= factindexpo^.ind[frecno]; + data.recordpo:= fcurrentbuf; + data.recno:= frecno; + flag := bfinserted; + end; + end + else begin + if (state = dsedit) then begin + relocateindex(fcurrentbuf,ar1,ar2,ar3); + dsheader.bookmark.data.recno:= frecno; + end; + end; + end; + fbstate:= fbstate - [bs_editing,bs_append]; +end; + +procedure tmsebufdataset.internalcancel; +var + int1: integer; + bo1: boolean; +begin + with pdsrecordty(activebuffer)^,header do begin + finalizevalues(header); + bo1:= false; + for int1:= high(blobinfo) downto 0 do begin + if blobinfo[int1].new then begin + deleteblob(blobinfo,int1,true); + bo1:= true; + end; + end; + if bo1 then begin + blobinfo:= nil; //free copy + end; + end; + fbstate:= fbstate - [bs_editing,bs_append]; +end; + +procedure tmsebufdataset.FreeFieldBuffers; +begin + //dummy +end; + +function comparefieldnum(const l,r): integer; +begin + result:= tfield(l).fieldno - tfield(r).fieldno; +end; + +procedure tmsebufdataset.calcrecordsize; + + procedure addfield(const aindex: integer; const datatype: tfieldtype; + const asize: integer; const afield: tfield); + begin + with ffieldinfos[aindex] do begin + base.offset:= frecordsize; + base.size:= getfieldsize(datatype,asize,ext.basetype); + if ext.basetype = ftvariant then begin + additem(fvarpositions,frecordsize); + end; + if ext.basetype = ftwidestring then begin + additem(fstringpositions,frecordsize); + base.dbfieldsize:= asize; //max size + end + else begin + base.dbfieldsize:= base.size; + end; + base.fieldtype:= datatype; //used for savetostream; + ext.field:= afield; + ext.uppername:= uppercase(afield.fieldname); + inc(frecordsize,base.size); + alignfieldpos(frecordsize); + end; + end; //addfield + +var + lookuprecursion: integer; + + function getbasetype(const afield: tfield): tfieldtype; + var + field1: tfield; + begin + inc(lookuprecursion); + if lookuprecursion > 16 then begin + databaseerror(name+': Recursive lookup field "'+afield.fieldname+'".'); + end; + result:= ftunknown; + if afield.dataset is tmsebufdataset then begin + if (afield.fieldkind = fklookup) and + (afield.lookupdataset <> nil) and + (afield.lookupresultfield <> '') then begin + field1:= afield.lookupdataset.findfield(afield.lookupresultfield); + if field1 <> nil then begin + result:= getbasetype(field1); + end; + end + else begin + getfieldsize(afield.datatype,0,result); + end; + end; + end; //getbasetype + +var + int1,int2,int3,int4: integer; + field1: tfield; + ar1: fieldarty; + ar2: stringarty; + bo1: boolean; +begin + fcalcfieldcount:= 0; + finternalcalcfieldcount:= 0; + for int1:= fields.count - 1 downto 0 do begin + with fields[int1] do begin + if fieldkind in dsbuffieldkinds then begin + inc(fcalcfieldcount); + end; + if fieldkind = fkinternalcalc then begin + inc(finternalcalcfieldcount); + end; + end; + end; + int1:= fielddefs.count+finternalcalcfieldcount; + frecordsize:= sizeof(blobinfoarty); + fnullmasksize:= (int1+7) div 8; + inc(frecordsize,fnullmasksize); + alignfieldpos(frecordsize); + + setlength(ffieldinfos,int1); + fstringpositions:= nil; + fvarpositions:= nil; + for int1:= 0 to fielddefs.count - 1 do begin + with fielddefs[int1] do begin + field1:= fields.findfield(name); + if (field1 <> nil) and (field1.fieldkind = fkdata) then begin + if fieldno = 0 then begin +{$warnings off} + tfield1(field1).ffieldno:= int1 + 1; //local mode without connection +{$warnings on} + end; + addfield(int1,datatype,size,field1); + end; + end; + end; + int2:= fielddefs.count; + for int1:= 0 to fields.count -1 do begin + field1:= fields[int1]; + with field1 do begin + if fieldkind = fkinternalcalc then begin + addfield(int2,datatype,size,field1); +{$warnings off} + tfield1(field1).ffieldno:= int2 + 1; +{$warnings on} + inc(int2); + end; + end; + end; + setlength(fcalcfieldbufpositions,fcalcfieldcount); + flookupfieldinfos:= nil; + setlength(flookupfieldinfos,fcalcfieldcount); + setlength(fcalcfieldsizes,fcalcfieldcount); + fcalcstringpositions:= nil; + fcalcvarpositions:= nil; + fcalcrecordsize:= frecordsize; + fcalcnullmasksize:= (fcalcfieldcount+7) div 8; + inc(fcalcrecordsize,fcalcnullmasksize); + alignfieldpos(fcalcrecordsize); + int2:= 0; + setlength(ar1,fields.count); + for int1:= fields.count - 1 downto 0 do begin + field1:= fields[int1]; + ar1[int1]:= field1; + with field1 do begin + if fieldkind in dsbuffieldkinds then begin +{$warnings off} + tfield1(field1).ffieldno:= -1 - int2; +{$warnings on} + fcalcfieldbufpositions[int2]:= fcalcrecordsize; + if field1 is tmsestringfield then begin + additem(fcalcstringpositions,fcalcrecordsize); + end; + if field1 is tmsevariantfield then begin + additem(fcalcvarpositions,fcalcrecordsize); + end; + fcalcfieldsizes[int2]:= datasize; + with flookupfieldinfos[int2] do begin + valuefield:= field1; + indexnum:= -1; + if (fieldkind = fklookup) and not lookupcache and + (lookupdataset is tmsebufdataset) then begin + if findfields(field1.keyfields,keyfieldar) and + (keyfieldar <> nil) then begin + with tmsebufdataset(lookupdataset) do begin + lookupvaluefield:= findfield(field1.lookupresultfield); + if lookupvaluefield <> nil then begin + lookupvaluefield.freenotification(self); + ar2:= splitstring(lookupkeyfields,';',true); + if high(ar2) = high(keyfieldar) then begin + for int3:= 0 to indexlocal.count - 1 do begin + with indexlocal[int3] do begin + if fields.count > high(keyfieldar) then begin + bo1:= true; + for int4:= 0 to high(keyfieldar) do begin + if not sametext(fields[int4].fieldname,ar2[int4]) then begin + bo1:= false; + break; + end; + end; + if not bo1 then begin + continue; + end + else begin + indexnum:= int3; + lookuprecursion:= 0; + basedatatype:= getbasetype(lookupvaluefield); + case basedatatype of + ftwidestring: begin + getvalue:= {$ifdef FPC}@{$endif}getbmstring; + end; + ftguid: begin + getvalue:= {$ifdef FPC}@{$endif}getbmguid; + end; + ftinteger: begin + getvalue:= {$ifdef FPC}@{$endif}getbminteger; + end; + ftboolean: begin + getvalue:= {$ifdef FPC}@{$endif}getbmboolean; + end; + ftbcd: begin + getvalue:= {$ifdef FPC}@{$endif}getbmcurrency; + end; + ftfloat: begin + getvalue:= {$ifdef FPC}@{$endif}getbmfloat; + end; + ftlargeint: begin + getvalue:= {$ifdef FPC}@{$endif}getbmlargeint; + end; + ftdatetime: begin + getvalue:= {$ifdef FPC}@{$endif}getbmdatetime; + end; + ftvariant: begin + getvalue:= {$ifdef FPC}@{$endif}getbmvariant; + end; + else begin + indexnum:= -1; + end; + end; + end; + adduniqueitem(pointerarty(flookupclients),pointer(self)); + adduniqueitem(pointerarty(self.flookupmasters), + pointer(lookupdataset)); + break; + end + end; + end; + end; + end; + end; + end; + if indexnum < 0 then begin + databaseerror(self.name+', '+name+': no loookup index for KeyFields "'+ + keyfields+'" LookupKeyFields "'+lookupkeyfields+'".'); + end; + end; + end; + inc(fcalcrecordsize,fcalcfieldsizes[int2]); + alignfieldpos(fcalcrecordsize); + inc(int2); + end; + end; + end; + mergesortarray(ar1,sizeof(ar1[0]),length(ar1),@comparefieldnum, + ffieldorder,false); + //MS SQL ODBC needs ordered load field +end; + +function tmsebufdataset.getrecordsize : word; +begin + result:= frecordsize; +end; + +function tmsebufdataset.getchangecount: integer; +begin + result:= length(fupdatebuffer); +end; + +function tmsebufdataset.getapplyerrorcount: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(fupdatebuffer) do begin + if ruf_error in fupdatebuffer[int1].info.flags then begin + inc(result); + end; + end; +end; + +procedure tmsebufdataset.setrecno1(value: longint; const nocheck: boolean); +var + bm: bufbookmarkty; +begin + checkbrowsemode; + if value > recordcount then begin + repeat + until (getnextpacket(bs_fetchall in fbstate) < fpacketrecords) or + (value <= recordcount) or (bs_fetchall in fbstate); + end; + if nocheck then begin + if value > fbrecordcount then begin + value:= fbrecordcount; + end; + if value < 1 then begin + exit; + end; + end; + checkrecno(value); + bm.data.recordpo:= nil; + bm.data.recno:= value-1; + if nocheck then begin + try + gotobookmark(@bm); + except //catch exception by filter + resync([]); //record not found + end; + end + else begin + gotobookmark(@bm); + end; +end; + +procedure tmsebufdataset.setrecno(value: longint); +begin + setrecno1(value,false); +end; + +procedure tmsebufdataset.setrecnozerobased(const avalue: int32); +begin + setrecno1(avalue + 1,false); +end; + +procedure tmsebufdataset.setoptions(const avalue: bufdatasetoptionsty); +begin + if avalue <> foptions then begin + if bdo_restoreupdateonsavepointrollback in avalue then begin + include(fbstate1,bs1_restoreupdate); + end + else begin + if (bs1_restoreupdate in fbstate1) and active and + not (csloading in componentstate) then begin + postrecupdatebuffer; + end; + exclude(fbstate1,bs1_restoreupdate); + end; + foptions:= bufdatasetoptionsty(setsinglebit(card32(avalue),card32(foptions), + [card32([bdo_autocommitret,bdo_autocommit]), + card32([bdo_editonapplyerror,bdo_cancelupdatesonerror, + bdo_cancelupdateonerror,bdo_cancelupdateondeleteerror])])); + end; +end; + +function tmsebufdataset.getdefaultoptions: bufdatasetoptionsty; +begin + result:= defaultbufdatasetoptions; +end; + +function tmsebufdataset.getrecno: longint; +begin + result:= getrecnozerobased + 1; +end; + +function tmsebufdataset.getrecnozerobased: int32; +begin + if bs_internalcalc in fbstate then begin + result:= frecno; + end + else begin + result:= -1; + if activebuffer <> nil then begin + with pdsrecordty(activebuffer)^.dsheader.bookmark do begin + if state = dsinsert then begin + if (bs_append in fbstate) or (fbrecordcount = 0) then begin + result:= fbrecordcount; + end + else begin + result:= data.recno; + end; + end + else begin + if fbrecordcount > 0 then begin + result:= data.recno; + end; + end; + end; + end; + end; +end; + +function tmsebufdataset.iscursoropen: boolean; +begin + result:= fopen; +end; + +function tmsebufdataset.getrecordcount: longint; +begin + result:= fbrecordcount; +end; + +function tmsebufdataset.updatestatus(out aflags: recupdateflagsty): tupdatestatus; +begin + aflags:= []; + result:= usunmodified; + if getrecordupdatebuffer then begin + with fupdatebuffer[fcurrentupdatebuffer] do begin + aflags:= info.flags; + case info.updatekind of + ukmodify : result := usmodified; + ukinsert : result := usinserted; + ukdelete : result := usdeleted; + end; + end; + end; +end; + +function tmsebufdataset.updatestatus: tupdatestatus; +var + stat1: recupdateflagsty; +begin + result:= updatestatus(stat1); +end; + +{ +Function tmsebufdataset.Locate(const KeyFields: string; const KeyValues: Variant; options: TLocateOptions) : boolean; + + + function CompareText0(substr, astr: pchar; len : integer; options: TLocateOptions): integer; + + var + i : integer; Chr1, Chr2: byte; + begin + result := 0; + i := 0; + chr1 := 1; + while (result=0) and (i 0) do + begin + Chr1 := byte(substr[i]); + Chr2 := byte(astr[i]); + inc(i); + if loCaseInsensitive in options then + begin + if Chr1 in [97..122] then + dec(Chr1,32); + if Chr2 in [97..122] then + dec(Chr2,32); + end; + result := Chr1 - Chr2; + end; + if (result <> 0) and (chr1 = 0) and (loPartialKey in options) then result := 0; + end; + + +var keyfield : TField; // Field to search in + ValueBuffer : pchar; // Pointer to value to search for, in TField' internal format + VBLength : integer; + + FieldBufPos : PtrInt; // Amount to add to the record buffer to get the FieldBuffer + CurrLinkItem: Pbufreclinkitem1; + CurrBuff : pchar; + bm : TBufBookmarkty; + + CheckNull : Boolean; + SaveState : TDataSetState; + +begin +// For now it is only possible to search in one field at the same time + result := False; + + if IsEmpty then exit; + + keyfield := FieldByName(keyfields); + CheckNull := VarIsNull(KeyValues); + + if not CheckNull then + begin + SaveState := State; + SetTempState(dsFilter); + keyfield.Value := KeyValues; + RestoreState(SaveState); + + FieldBufPos := FFieldBufPositions[keyfield.FieldNo-1]; + VBLength := keyfield.DataSize; + ValueBuffer := AllocMem(VBLength); + currbuff := pointer(FLastRecBuf)+sizeof(Tbufreclinkitem1)+FieldBufPos; + move(currbuff^,ValueBuffer^,VBLength); + end; + + CurrLinkItem := FFirstRecBuf; + + if CheckNull then + begin + repeat + currbuff := pointer(CurrLinkItem)+sizeof(Tbufreclinkitem1); + if GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then + begin + result := True; + break; + end; + CurrLinkItem := CurrLinkItem^.next; + if CurrLinkItem = FLastRecBuf then getnextpacket; + until CurrLinkItem = FLastRecBuf; + end + else if keyfield.DataType = ftString then + begin + repeat + currbuff := pointer(CurrLinkItem)+sizeof(Tbufreclinkitem1); + if not GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then + begin + inc(CurrBuff,FieldBufPos); + if CompareText0(ValueBuffer,CurrBuff,VBLength,options) = 0 then + begin + result := True; + break; + end; + end; + CurrLinkItem := CurrLinkItem^.next; + if CurrLinkItem = FLastRecBuf then getnextpacket; + until CurrLinkItem = FLastRecBuf; + end + else + begin + repeat + currbuff := pointer(CurrLinkItem)+sizeof(Tbufreclinkitem1); + if not GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then + begin + inc(CurrBuff,FieldBufPos); + if CompareByte(ValueBuffer^,CurrBuff^,VBLength) = 0 then + begin + result := True; + break; + end; + end; + + CurrLinkItem := CurrLinkItem^.next; + if CurrLinkItem = FLastRecBuf then getnextpacket; + until CurrLinkItem = FLastRecBuf; + end; + + + if Result then + begin + bm.BookmarkData := CurrLinkItem; + bm.BookmarkFlag := bfCurrent; + GotoBookmark(@bm); + end; + + ReAllocmem(ValueBuffer,0); +end; +} +function tmsebufdataset.getblobrecpo: precheaderty; +begin + if state = dsoldvalue then begin + if getrecordupdatebuffer then begin + result:= pointer(fupdatebuffer[fcurrentupdatebuffer].oldvalues); + if result <> nil then begin + result:= @pintrecordty(result)^.header; + end; + end + else begin + result:= @fcurrentbuf^.header //there is no old value available + end; + end + else begin + if state = dscurvalue then begin + result:= @fcurrentbuf^.header; + end + else begin + if bs_recapplying in fbstate then begin + result:= @fnewvaluebuffer^.header; + end + else begin + result:= @pdsrecordty(activebuffer)^.header; + end; + end; + end; +end; + +function tmsebufdataset.createblobstream(field: tfield; + mode: tblobstreammode): tstream; +var + int1: integer; + buffer: pointer; +begin + if (mode <> bmread) and not ((state in dseditmodes) or + (bs_recapplying in fbstate)) then begin + databaseerrorfmt(snotediting,[name],self); + end; + result:= nil; + if mode = bmread then begin + buffer:= getblobrecpo; + with precheaderty(buffer)^ do begin + for int1:= high(blobinfo) downto 0 do begin + if blobinfo[int1].field = field then begin + result:= tblobcopy.create(blobinfo[int1]); + break; + end; + end; + end; + end + else begin + if (mode = bmwrite) and (field.fieldno-1 >= 0) and // data field + (of_inupdate in field.optionsfield) then begin + include(fbstate1,bs1_inupdatechanged); + end; + end; +end; + +function tmsebufdataset.getfieldblobid(const field: tfield; + out aid: blobidty): boolean; +var + po1: precheaderty; + po2: pointer; + int1: integer; +begin + result:= getfieldbuffer(field,po2,int1); + if result then begin + po1:= getblobrecpo; + with po1^ do begin + for int1:= high(blobinfo) downto 0 do begin + if blobinfo[int1].field = field then begin + aid.local:= true; + aid.id:= ptrint(blobinfo[int1].data); + result:= aid.id <> 0; + exit; + end; + end; + aid.local:= false; + aid.id:= 0; + move(po2^,aid.id,getblobdatasize); + end; + end; +end; + +procedure tmsebufdataset.fetchallblobs; +begin + fetchall; + fetchblobs; +end; + +function tmsebufdataset.blobsarefetched: boolean; +begin + result:= (bs_blobsfetched in fbstate) or (bdo_cacheblobs in foptions); +end; + +function tmsebufdataset.getblobcache: blobcacheinfoarty; +begin + result:= fblobcache; +end; + +function tmsebufdataset.findcachedblob(var info: blobcacheinfoty): boolean; +var + int1: integer; +begin + if bs_blobscached in fbstate then begin + info:= fblobcache[integer(info.id)]; + result:= true; + end + else begin + if not (bs_blobssorted in fbstate) then begin + sortblobcache; + end; + result:= findarrayvalue(info,fblobcache,sizeof(blobcacheinfoty), + fblobcount,@compblobcache,int1); + if result then begin + info.data:= fblobcache[int1].data; + end + else begin + info.data:= ''; + end; + end +end; + +procedure tmsebufdataset.sortblobcache; +begin + setlength(fblobcache,fblobcount); + sortarray(fblobcache,sizeof(blobcacheinfoty),@compblobcache); + include(fbstate,bs_blobssorted); +end; + +procedure tmsebufdataset.resetblobcache; +begin + fblobcache:= nil; + fblobcount:= 0; + ffreedblobs:= nil; + ffreedblobcount:= 0; + fbstate:= fbstate - [bs_blobssorted,bs_blobsfetched]; +end; + +procedure tmsebufdataset.fetchblobs; +var + datapobefore: pintrecordty; + statebefore: tdatasetstate; + int1,int2,int3: integer; + ind1: pointerarty; + fieldar1: fieldarty; + ar1: integerarty; + stream1: tmemorystream; +// id: int64; +begin + if not blobscached and not (bs_blobsfetched in fbstate) then begin + setlength(fieldar1,fields.count); + int2:= 0; + for int1:= 0 to high(fieldar1) do begin + fieldar1[int2]:= fields[int1]; + if fieldar1[int2].isblob then begin + inc(int2); + end; + end; + if int2 > 0 then begin + setlength(fieldar1,int2); + setlength(ar1,int2); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= fieldar1[int1].fieldno-1; + end; + datapobefore:= fcurrentbuf; + ind1:= findexes[0].ind; + statebefore:= settempstate(dscurvalue); + resetblobcache; + try + for int1:= 0 to recordcount - 1 do begin + fcurrentbuf:= ind1[int1]; + for int2:= 0 to high(fieldar1) do begin + if getfieldflag(@fcurrentbuf^.header.fielddata.nullmask, + ar1[int2]) then begin + stream1:= tmemorystream(createblobstream(fieldar1[int2],bmread)); + int3:= addblobcache(stream1.memory,stream1.size); + fieldar1[int2].getdata(@fblobcache[int3].id); + stream1.free; + end; + end; + end; + finally + fcurrentbuf:= datapobefore; + restorestate(statebefore); + end; + end; + end + else begin + setlength(fblobcache,fblobcount); + end; + include(fbstate,bs_blobsfetched); +end; + +function tmsebufdataset.findcachedblob(const id: int64; + out info: blobcacheinfoty): boolean; +begin + info.id:= id; + result:= findcachedblob(info); +end; + +procedure tmsebufdataset.getofflineblob(const data: precheaderty; + const aindex: integer; out ainfo: blobstreaminfoty); +var + cacheinfo: blobcacheinfoty; + int1: integer; +begin + with ffieldinfos[aindex],base,ext do begin + cacheinfo.id:= 0; //field size can be 32 bit + move((pchar(data)+offset)^,cacheinfo.id,size); + with data^ do begin + for int1:= high(blobinfo) downto 0 do begin + if blobinfo[int1].field = field then begin + with blobinfo[int1] do begin + ainfo.info.id:= cacheinfo.id; + ainfo.info.new:= new; + ainfo.info.current:= true; + setlength(ainfo.data,datalength); + move(data^,pointer(ainfo.data)^,datalength); + //todo: no move + end; + exit; + end; + end; + end; + findcachedblob(cacheinfo); + {$warnings off} + with ainfo,info do begin + id:= cacheinfo.id; + new:= false; + current:= false; + data:= cacheinfo.data; + end; + end; +end; + {$warnings on} + +procedure tmsebufdataset.setofflineblob(const adata: precheaderty; + const aindex: integer; const ainfo: blobstreaminfoty); +begin + with ainfo,info do begin + with ffieldinfos[aindex],base,ext do begin + move(id,(pchar(adata)+offset)^,size); + if current then begin + with adata^ do begin + setlength(blobinfo,high(blobinfo) + 2); + with blobinfo[high(blobinfo)] do begin + field:= ffieldinfos[aindex].ext.field; + new:= info.new; //?? + datalength:= length(ainfo.data); + getmem(data,datalength); //todo: no move + move(pointer(ainfo.data)^,data^,datalength); + end; + end; + end + else begin + addblobcache(id,data); + end; + end; + end; +end; + +procedure tmsebufdataset.setdatastringvalue(const afield: tfield; + const avalue: string); +var + po1: pbyte; + int1: integer; +begin + if bs_recapplying in fbstate then begin +// po1:= pbyte(@fupdatebuffer[fcurrentupdatebuffer].bookmark.recordpo^.header); + po1:= @fnewvaluebuffer^.header; + include(fbstate,bs_curvaluemodified); + end + else begin + po1:= pbyte(@fcurrentbuf^.header); + end; + int1:= afield.fieldno - 1; + if avalue <> '' then begin + move(avalue[1],(pchar(po1)+ffieldinfos[int1].base.offset)^, + length(avalue)); + setfieldflag(@precheaderty(po1)^.fielddata.nullmask,int1); + end + else begin + clearfieldflag(@precheaderty(po1)^.fielddata.nullmask,int1); + end; +end; + +procedure tmsebufdataset.checkindexsize; +var + int1,int2: integer; +begin + if high(factindexpo^.ind) <= fbrecordcount then begin + int2:= (fbrecordcount+16)*2; + setlength(findexes[0].ind,int2); + if bs_hasvalidindex in fbstate then begin + for int1:= 1 to high(findexes) do begin + if (findexes[int1].ind <> nil) or (int1 = factindex) then begin + //init for first insert/append + setlength(findexes[int1].ind,int2); + end; + end; + end; + end; +end; + +function tmsebufdataset.insertindexrefs(const arecord: pintrecordty): integer; +var + int1,int2: integer; +begin + result:= frecno; + if bs_hasvalidindex in fbstate then begin + for int1:= 1 to high(findexes) do begin + if findexes[int1].ind <> nil then begin + with findexlocal[int1-1] do begin + int2:= findboundary(@compare1,arecord,high(findexfieldinfos),true); + end; + with findexes[int1] do begin + if int2 < fbrecordcount then begin + move(ind[int2],ind[int2+1],(fbrecordcount-int2)*sizeof(pointer)); + end; + ind[int2]:= arecord; + if int1 = factindex then begin + result:= int2; + end; + end; + end; + end; + end; +end; + +procedure tmsebufdataset.removeindexrefs(const arecord: pintrecordty); +var + int1,int2: integer; +begin + if bs_hasvalidindex in fbstate then begin + for int1:= 1 to high(findexes) do begin + if findexes[int1].ind <> nil then begin + if int1 <> factindex then begin + int2:= findexlocal[int1-1].findrecord(arecord); + if int2 < 0 then begin + databaseerror('Internal error: Indexed record not found.'); + end; + with findexes[int1] do begin + move(ind[int2+1],ind[int2],(fbrecordcount-int2-1)*sizeof(pointer)); + end; + end; + end; + end; + end; +end; + +function tmsebufdataset.appendrecord(const arecord: pintrecordty): integer; +begin + checkindexsize; + findexes[0].ind[fbrecordcount]:= arecord; + result:= insertindexrefs(arecord); + if factindex = 0 then begin + result:= fbrecordcount; + end; + inc(fbrecordcount); +end; + +function tmsebufdataset.insertrecord(arecno: integer; + const arecord: pintrecordty): integer; +begin + if arecno < 0 then begin + arecno:= 0; + end; + checkindexsize; + result:= insertindexrefs(arecord); + if factindex <> 0 then begin + findexes[0].ind[fbrecordcount]:= arecord; //append + end + else begin + result:= arecno; + move(findexes[0].ind[arecno],findexes[0].ind[arecno+1], + (fbrecordcount-arecno)*sizeof(pointer)); + findexes[0].ind[arecno]:= arecord; + end; + if (frecno > arecno) then begin + inc(frecno); + end; +// fcurrentbuf:= arecord; + fcurrentbuf:= factindexpo^.ind[frecno]; + inc(fbrecordcount); +end; + +function tmsebufdataset.remove0indexref(const arecord: pintrecordty): integer; +var + po1: pintrecordty; + po2: ppointer; + int1: integer; +begin + result:= -1; + dec(fbrecordcount); + po1:= arecord; + with findexes[0] do begin + po2:= pointer(pchar(pointer(ind)) + fbrecordcount*sizeof(pointer)); + for int1:= fbrecordcount downto 0 do begin + if po2^ = po1 then begin + result:= int1; + break; + end; + dec(po2); + end; + if result >= 0 then begin + move(ind[result+1],ind[result],(fbrecordcount-result)*sizeof(pointer)); + end; + end; +end; + +procedure tmsebufdataset.deleterecord(const arecord: pintrecordty); +var + int1: integer; +begin + if bs_hasvalidindex in fbstate then begin + int1:= factindex; + factindex:= 0; + removeindexrefs(arecord); + factindex:= int1; + end; + remove0indexref(arecord); +end; + +procedure tmsebufdataset.deleterecord(const arecno: integer); +var + po1: pintrecordty; +// int1: integer; +begin + po1:= factindexpo^.ind[arecno]; + if bs_hasvalidindex in fbstate then begin + removeindexrefs(po1); + if factindex <> 0 then begin + move(factindexpo^.ind[arecno+1],factindexpo^.ind[arecno], + (fbrecordcount-arecno-1)*sizeof(pointer)); + end; + end; + if factindex = 0 then begin + dec(fbrecordcount); + with findexes[0] do begin + move(ind[arecno+1],ind[arecno],(fbrecordcount-arecno)*sizeof(pointer)); + end; + end + else begin + remove0indexref(po1); + end; + if (frecno > arecno) or (frecno >= fbrecordcount) then begin + dec(frecno); + end; + if frecno < 0 then begin + fcurrentbuf:= nil; + end + else begin + fcurrentbuf:= factindexpo^.ind[frecno]; + end; +end; + +procedure tmsebufdataset.checkindex(const aid: integer); +var + int2: integer; +begin + if aid > 0 then begin + int2:= length(findexes[0].ind); + if int2 > 0 then begin + with findexes[aid] do begin + if ind = nil then begin + allocuninitedarray(int2,sizeof(pointer),ind); + if fbrecordcount > 0 then begin + move(findexes[0].ind[0],ind[0],fbrecordcount*sizeof(pointer)); + findexlocal.items[aid-1].sort(ind); + end; + end; + end; + end; + include(fbstate,bs_hasvalidindex); + end; +end; + +procedure tmsebufdataset.internalsetrecno(const avalue: integer); +begin + frecno:= avalue; + if (avalue < 0) or (avalue >= fbrecordcount) then begin + fcurrentbuf:= nil; + end + else begin + checkindex(factindex); + fcurrentbuf:= factindexpo^.ind[avalue]; + end; +// tdatasetcracker(self).fbof:= frecno = 0; +end; + +procedure tmsebufdataset.clearindex; +begin + findexes:= nil; + factindexpo:= nil; + exclude(fbstate,bs_hasvalidindex); +end; + +procedure tmsebufdataset.setindexlocal(const avalue: tlocalindexes); +begin + findexlocal.assign(avalue); +end; + +procedure tmsebufdataset.updatestate; +begin + if (fpacketrecords < 0) {or assigned(foninternalcalcfields)} then begin + include(fbstate,bs_fetchall); + end + else begin + exclude(fbstate,bs_fetchall); + end; + if findexlocal.count > 0 then begin + fbstate:= fbstate + [bs_hasindex,bs_fetchall]; + end + else begin + exclude(fbstate,bs_hasindex); + end; +end; + +procedure tmsebufdataset.setactindex(const avalue: integer); +//var +// int1: integer; +begin + if factindex <> avalue then begin + if active then begin + checkbrowsemode; + factindex:= avalue; + factindexpo:= @findexes[avalue]; + internalsetrecno(findrecord(fcurrentbuf)); + resync([]); + findexlocal.doindexchanged; + end + else begin + factindex:= avalue; + factindexpo:= @findexes[avalue]; + end; + end; +end; + +procedure tmsebufdataset.resetindex; +var + int1: integer; +begin + actindex:= 0; + for int1:= 1 to high(findexes) do begin + findexes[int1].ind:= nil; + end; + exclude(fbstate,bs_hasvalidindex); +end; + +function tmsebufdataset.GetFieldClass(FieldType: TFieldType): TFieldClass; +begin + result:= getmsefieldclass(fieldtype); +end; + +procedure tmsebufdataset.fieldtoparam(const source: tfield; const dest: tparam); +var +// int1: integer; + mstr1: msestring; +begin + if source is tmsestringfield then begin + with tmsestringfield(source) do begin + if source.isnull then begin + dest.clear; + if fixedchar then begin + dest.datatype:= ftfixedchar; + end + else begin + dest.datatype:= ftstring; + end; + end + else begin + mstr1:= asmsestring; + if (characterlength <> 0) and (length(mstr1) > characterlength) then begin + setlength(mstr1,characterlength); + end; + dest.aswidestring:= mstr1; + if fixedchar then begin + dest.datatype:= ftfixedwidechar; + end; + end; + end; + end + else begin + dest.assignfieldvalue(source,source.value); + end; +end; + +procedure tmsebufdataset.oldfieldtoparam(const source: tfield; + const dest: tparam); +var + bo1:boolean; + mstr1: msestring; +begin + if source is tmsestringfield then begin + mstr1:= tmsestringfield(source).oldmsestring(bo1); + if bo1 then begin + dest.clear; + if tmsestringfield(source).fixedchar then begin + dest.datatype:= ftfixedchar; + end + else begin + dest.datatype:= ftstring; + end; + end + else begin + { + if bs_utf8 in fbstate then begin + dest.asstring:= stringtoutf8ansi(mstr1); + end + else begin + dest.asstring:= mstr1; + end; + } + dest.aswidestring:= mstr1; + if tmsestringfield(source).fixedchar then begin + dest.datatype:= ftfixedwidechar; + end; + end; + end + else begin + dest.assignfieldvalue(source,source.oldvalue); + end; +end; + +procedure tmsebufdataset.stringtoparam(const source: msestring; + const dest: tparam); +begin + if bs_utf8 in fbstate then begin + dest.asstring:= stringtoutf8ansi(source); + end + else begin + dest.asstring:= ansistring(source); + end; +end; + +procedure tmsebufdataset.bindfields(const bind: boolean); +var + int1: integer; + field1: tfield; + int2: integer; + fielddef1: tfielddef; +begin + fielddef1:= nil; + for int1:= fields.count - 1 downto 0 do begin + field1:= fields[int1]; + if bind then begin + if field1.fieldkind = fkdata then begin + fielddef1:= tfielddef(fielddefs.find(field1.fieldname)); + //needed for FPC 2_2 + if fielddef1 <> nil then begin + field1.fieldname:= fielddef1.name; + //get exact name for quoting in update statements + end; + end + else begin + fielddef1:= nil; + end; + end; + if field1 is tmsestringfield then begin + int2:= 0; + if bind then begin + int2:= field1.size; + if fielddef1 <> nil then begin + int2:= fielddef1.size; + end; + tmsestringfield1(field1).setismsestring({$ifdef FPC}@{$endif}getmsestringdata, + {$ifdef FPC}@{$endif}setmsestringdata,int2,(fielddef1 <> nil) and + (fielddef1.datatype in widestringfields)); + end + else begin + tmsestringfield1(field1).setismsestring(nil,nil,int2,false); + end; + end + else begin + if field1 is tmseblobfield then begin + if bind then begin + tmseblobfield1(field1).fgetblobid:= {$ifdef FPC}@{$endif}getfieldblobid; + end + else begin + tmseblobfield1(field1).fgetblobid:= nil; + end; + end + else begin + if field1 is tmsevariantfield then begin + if bind then begin + tmsevariantfield1(field1).fsetvardata:= {$ifdef FPC}@{$endif}setvardata; + tmsevariantfield1(field1).fgetvardata:= {$ifdef FPC}@{$endif}getvardata; + end + else begin + tmsevariantfield1(field1).fsetvardata:= nil; + tmsevariantfield1(field1).fgetvardata:= nil; + end; + end; + end; + end; + end; + inherited bindfields(bind); +end; + +function tmsebufdataset.findfields(const anames: string): fieldarty; +var + ar1: stringarty; + int1: integer; +begin + ar1:= splitstring(anames,';',true); + setlength(result,length(ar1)); + for int1:= 0 to high(result) do begin + result[int1]:= findfield(ar1[int1]); + end; +end; + +function tmsebufdataset.findfields(const anames: string; out afields: fieldarty): boolean; + //true if all found +var + ar1: stringarty; + int1: integer; +begin + ar1:= splitstring(anames,';',true); + setlength(afields,length(ar1)); + result:= true; + for int1:= 0 to high(afields) do begin + afields[int1]:= findfield(ar1[int1]); + if afields[int1] = nil then begin + result:= false; + end; + end; +end; +{ +function tmsebufdataset.refreshing: boolean; +begin + result:= bs_refreshing in fbstate; +end; +} +function tmsebufdataset.isutf8: boolean; +begin + result:= false; //default +end; + +procedure tmsebufdataset.append; +begin + include(fbstate,bs_append); + inherited; +end; + +procedure tmsebufdataset.setoninternalcalcfields( + const avalue: internalcalcfieldseventty); +begin + foninternalcalcfields:= avalue; + updatestate; +end; + +procedure tmsebufdataset.lookupdschanged(const sender: tmsebufdataset); +var + int1,int2: integer; + bo1: boolean; + bm1: bookmarkdataty; +begin + if active and not (csdestroying in componentstate) then begin + int2:= fnotifylookupclientcount; + bo1:= false; + bm1:= bookmarkdata; + for int1:= 0 to high(flookupfieldinfos) do begin + with flookupfieldinfos[int1] do begin + if hasindex and (lookupvaluefield.dataset = sender) then begin + findexlocal.fieldmodified(valuefield,false); + bo1:= true; + end; + end; + end; + if (state in [dsbrowse]) or (state in [dsedit,dsinsert]) and + (bdo_checkbrowsemodebylookupchange in foptions) then begin + //stop recursion triggered by dscalcfields + if bo1 then begin + if state = dsinsert then begin + checkbrowsemode; + end + else begin + if bm1.recordpo <> nil then begin + bookmarkdata:= bm1; + end; + end; + end + else begin + checkbrowsemode; + resync([]); + end; + if int2 = fnotifylookupclientcount then begin + //already called by post otherwise + notifylookupclients; + end; + end; + end; +end; + +procedure tmsebufdataset.notifylookupclients; +var + int1: integer; +begin + if not (bs1_lookupnotifying in fbstate1) then begin + if (fdisablecontrolscount > 0) or (flookupupdate > 0) then begin + include(fbstate1,bs1_lookupnotifypending); + end + else begin + inc(fnotifylookupclientcount); + include(fbstate1,bs1_lookupnotifying); + try + for int1:= 0 to high(flookupclients) do begin + flookupclients[int1].lookupdschanged(self); + end; + exclude(fbstate1,bs1_lookupnotifypending); + finally + exclude(fbstate1,bs1_lookupnotifying); + end; + end; + end; +end; + +procedure tmsebufdataset.beginlookupupdate(); +begin + inc(flookupupdate); +end; + +procedure tmsebufdataset.endlookupupdate(); +begin + dec(flookupupdate); + if (flookupupdate = 0) and (bs1_lookupnotifypending in fbstate1) then begin + notifylookupclients(); + end; +end; + + +procedure tmsebufdataset.enablecontrols(); +begin + inherited; + if (bs1_lookupnotifypending in fbstate1) and (fdisablecontrolscount = 0) and + (flookupupdate = 0) then begin + notifylookupclients(); + end; +end; + +procedure tmsebufdataset.dointernalcalcfields(const fetching: boolean); +begin + if checkcanevent(self,tmethod(foninternalcalcfields)) then begin + foninternalcalcfields(self,fetching); + end; +end; + +procedure tmsebufdataset.dataevent(event: tdataevent; info: ptrint); +var + int1: integer; + field1: tfield; +begin + if (event = decheckbrowsemode) and (state = dsfilter) then begin + databaseerror('Database is in dsFilter state.',self); + end; + if event in [deupdaterecord,dedatasetchange] then begin + exclude(fbstate,bs_visiblerecordcountvalid); + end; + if (event = deupdatestate) and (state = dsbrowse) then begin + updatecursorpos; //update fcurrentbuf after open + end; + if (bs_startedit in fbstate) and (event = derecordchange) and (info = 0) then begin + exclude(fbstate,bs_startedit); + for int1:= 0 to fields.count - 1 do begin + field1:= fields[int1]; + if field1.fieldkind = fkcalculated then begin + dataevent(defieldchange,ptrint(field1)); + end; + exit; + end; + end; + if not ((bs_recapplying in fbstate) and (event = dedatasetchange)) then begin + inherited; + end; + case ord(event) of + ord(deupdaterecord): begin + dointernalcalcfields(false); + end; + de_modified: begin + notifylookupclients(); + end; + end; +end; + +procedure tmsebufdataset.updaterecord(); +var + bo1: boolean; +begin + bo1:= bs1_recordupdating in fbstate1; + include(fbstate1,bs1_recordupdating); + try + inherited; + finally + if not bo1 then begin + exclude(fbstate1,bs1_recordupdating); + end; + end; +end; + +function tmsebufdataset.bookmarkdatatobookmark( + const abookmark: bookmarkdataty): bookmarkty; +begin + if abookmark.recordpo = nil then begin + result:= ''; + end + else begin + setlength(result,sizeof(abookmark)); + move(abookmark,pointer(result)^,sizeof(abookmark)); + end; +end; + +function tmsebufdataset.bookmarktobookmarkdata( + const abookmark: bookmarkty): bookmarkdataty; +begin + if abookmark = '' then begin + result.recordpo:= nil; + result.recno:= -1; + end + else begin + move(pointer(abookmark)^,result,sizeof(result)); + end; +end; + +procedure tmsebufdataset.checkrecno(const avalue: integer); +begin + if (avalue > recordcount) or (avalue < 1) then begin + databaseerror(snosuchrecord,self); + end; +end; + +procedure tmsebufdataset.setonfilterrecord(const value: tfilterrecordevent); +begin + inherited; + if not (csdesigning in componentstate) then begin + checkfilterstate; + filterchanged; + end; +end; + +procedure tmsebufdataset.setfiltered(value: boolean); +begin + inherited; + filterchanged; +end; + +procedure tmsebufdataset.setactive(value: boolean); +var + bo1: boolean; +begin + bo1:= active; + inherited; + if bo1 <> active then begin + notifycontrols; + notifylookupclients; + end; +end; + +procedure tmsebufdataset.filterchanged1(const aloaded: boolean); +begin + if not aloaded then begin + exclude(fbstate,bs_visiblerecordcountvalid); + end; + if checkcanevent(self,tmethod(fbeforefilterchanged)) then begin + fbeforefilterchanged(self); + end; + if not aloaded then begin + if not (state in [dsinactive,dsfilter]) then begin + checkbrowsemode; + resync([]); + end; + end; + if checkcanevent(self,tmethod(fafterfilterchanged)) then begin + fafterfilterchanged(self); + end; +end; + +procedure tmsebufdataset.filterchanged(); +begin + filterchanged1(false); +end; + +function tmsebufdataset.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsebufdataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= locaterecord(self,key,field,options); +end; + +function tmsebufdataset.locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= locaterecord(self,isutf8,key,field,options); +end; +} +function tmsebufdataset.locaterecno(const arecno: integer): boolean; + //moves to next valid recno, //returns true if resulting recno = arecno +var + int1: integer; +begin + result:= false; + int1:= arecno-1; + if int1 <> frecno then begin + if int1 < 0 then begin + int1:= 0; + end; + if int1 >= recordcount then begin + int1:= fbrecordcount - 1; + end; + if int1 >= 0 then begin + internalsetrecno(int1); + resync([]); + result:= int1 = frecno; + end; + end + else begin + result:= true; + end; +end; + +procedure tmsebufdataset.beginfilteredit(const akind: filtereditkindty); +begin + if state <> dsfilter then begin + ffiltereditkind:= akind; + checkbrowsemode; + if checkcanevent(self,tmethod(fbeforebeginfilteredit)) then begin + fbeforebeginfilteredit(self,akind); + end; + fbuffercountbefore:= buffercount; + setbuflistsize(1); + setstate(dsfilter); + dataevent(dedatasetchange,0); + if checkcanevent(self,tmethod(fafterbeginfilteredit)) then begin + fafterbeginfilteredit(self,akind); + end; + end; +end; + +procedure tmsebufdataset.endfilteredit; +begin + if state = dsfilter then begin + dataevent(deupdaterecord, 0); + if checkcanevent(self,tmethod(fbeforeendfilteredit)) then begin + fbeforeendfilteredit(self,ffiltereditkind); + end; + setbuflistsize(fbuffercountbefore); + setstate(dsbrowse); + resync([]); + if checkcanevent(self,tmethod(fafterendfilteredit)) then begin + fafterendfilteredit(self,ffiltereditkind); + end; + filterchanged1(true); + end; +end; + +function tmsebufdataset.beginfiltervalue( + const akind: filtereditkindty): tdatasetstate; +begin + result:= settempstate(dsfilter); + ffiltereditkind:= akind; +end; + +procedure tmsebufdataset.endfiltervalue(const astatebefore: tdatasetstate); +begin + restorestate(astatebefore); +end; + +function tmsebufdataset.fieldfiltervalue(const afield: tfield; + const akind: filtereditkindty = fek_filter): variant; +var + statebefore: tdatasetstate; + kindbefore: filtereditkindty; +begin + statebefore:= settempstate(dsfilter); + kindbefore:= ffiltereditkind; + ffiltereditkind:= akind; + result:= afield.asvariant; + ffiltereditkind:= kindbefore; + restorestate(statebefore); +end; + +function tmsebufdataset.fieldfiltervalueisnull(const afield: tfield; + const akind: filtereditkindty = fek_filter): boolean; +var + statebefore: tdatasetstate; + kindbefore: filtereditkindty; +begin + statebefore:= settempstate(dsfilter); + kindbefore:= ffiltereditkind; + ffiltereditkind:= akind; + result:= afield.isnull; + ffiltereditkind:= kindbefore; + restorestate(statebefore); +end; + +function tmsebufdataset.checkfiltervalue(const afield: tfield; + const akind: filtereditkindty = fek_filter; + const acaseinsensitive: boolean = true): boolean; +var + i1: int32; + p1: precheaderty; + v1: variant; + b1: boolean; +begin + if afield.dataset <> self then begin + databaseerror('Invalid field "'+afield.name+'"',self); + end; + result:= true; //default + i1:= afield.fieldno-1; + p1:= @ffilterbuffer[akind]^.header; + if i1 >= 0 then begin //data field + b1:= not getfieldflag(p1^.fielddata.nullmask,i1); + end + else begin //calc field + i1:= -2 - i1; + if i1 >= 0 then begin //calc field + b1:= not getfieldflag(pointer(p1)+frecordsize,i1); + end + else begin + exit;//invalid field + end; + end; + if not b1 then begin //filter not null + b1:= afield.isnull; + v1:= fieldfiltervalue(afield,akind); + if afield.datatype = ftstring then begin + if acaseinsensitive then begin + i1:= unicodecomparetext(afield.asmsestring,unicodestring(v1)); + end + else begin + i1:= unicodecomparestr(afield.asmsestring,unicodestring(v1)); + end; + case akind of + fek_filtermin: begin + result:= not b1 and (i1 >= 0); + end; + fek_filter: begin + result:= i1 = 0; + end; + fek_filtermax: begin + result:= b1 or (i1 <= 0); + end; + end; + end + else begin + case akind of + fek_filtermin: begin + result:= not b1 and (afield.value >= v1); + end; + fek_filter: begin + result:= afield.value = v1; + end; + fek_filtermax: begin + result:= b1 or (afield.value <= v1); + end; + end; + end; + end; +end; + +function tmsebufdataset.checkfiltervalues(const afield: tfield; + const acaseinsensitive: boolean = true): boolean; + //calls checkfiltervalue() for all filtereditkinds +var + f1: filtereditkindty; +begin + for f1:= low(f1) to fek_filtermax do begin + result:= checkfiltervalue(afield,f1,acaseinsensitive); + if not result then begin + break; + end; + end; +end; + +function tmsebufdataset.checkfiltervalues( + const acaseinsensitive: boolean = true): boolean; + //calls checkfiltervalue() for all fields and all filtereditkinds +var + i1: int32; +begin + result:= true; + for i1:= 0 to fields.count-1 do begin + result:= checkfiltervalues(fields[i1],acaseinsensitive); + if not result then begin + break; + end; + end; +end; + +procedure tmsebufdataset.checkfilterstate; +begin + exclude(fbstate,bs_hasfilter); + if checkcanevent(self,tmethod(onfilterrecord)) then begin + include(fbstate,bs_hasfilter); + end +end; + +procedure tmsebufdataset.loaded; +begin + inherited; + checkfilterstate; + filterchanged1(true); +end; + +procedure tmsebufdataset.readstreamingversion(reader: treader); +begin + reader.readinteger(); + card32(foldopts):= $ffffffff; //none +end; + +procedure tmsebufdataset.writestreamingversion(writer: twriter); +begin + writer.writeinteger(1); +end; + +procedure tmsebufdataset.setdelayedapplycount(const avalue: integer); +begin + if fdelayedapplycount <> avalue then begin + if active and not (csloading in componentstate) then begin + if fdelayedapplycount > 0 then begin + fdelayedapplycount:= 1; + doidleapplyupdates; //apply pending updates. + end; + fdelayedapplycount:= avalue; + if avalue > 0 then begin + registeronidle; + end + else begin + unregisteronidle; + end; + end + else begin + fdelayedapplycount:= avalue; + end; + end; +end; + +procedure tmsebufdataset.registeronidle; +begin + if not(bs1_onidleregistered in fbstate1) then begin + application.registeronidle({$ifdef FPC}@{$endif}doonidle); + include(fbstate1,bs1_onidleregistered); + end; +end; + +procedure tmsebufdataset.unregisteronidle; +begin + if bs1_onidleregistered in fbstate1 then begin + application.unregisteronidle({$ifdef FPC}@{$endif}doonidle); + exclude(fbstate1,bs1_onidleregistered); + end; +end; + +procedure tmsebufdataset.doidleapplyupdates(); +begin + //dummy +end; + +procedure tmsebufdataset.doonidle(var again: boolean); +begin + doidleapplyupdates(); +end; + +procedure tmsebufdataset.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('streamingversion',@readstreamingversion, + @writestreamingversion,true); +end; + +procedure tmsebufdataset.readstate(reader: treader); +begin + inherited; + if card32(foldopts) <> $ffffffff then begin + options:= (options - + (bufdatasetoptionsty(not(card32(foldopts)))*oldbdsoptions) + ) + (foldopts * oldbdsoptions) + end; +end; + +procedure tmsebufdataset.dofilterrecord(var acceptable: boolean); +begin + if checkcanevent(self,tmethod(onfilterrecord)) then begin + onfilterrecord(self,acceptable); + end; +end; + +function tmsebufdataset.recordisnull(): boolean; //all fields null +var + int1: integer; +begin + checkactive(); + result:= true; + for int1:= 0 to fields.count - 1 do begin + if not fields[int1].isnull then begin + result:= false; + break; + end; + end; +end; + +procedure tmsebufdataset.clearrecord(); +var + int1: integer; +begin + checkactive; + try + disablecontrols; + for int1:= 0 to fields.count - 1 do begin + with fields[int1] do begin + if state = dsfilter then begin + if not isblob then begin + clear; + end; + end + else begin + if not readonly then begin + clear; + end; + end; + end; + end; + finally + enablecontrols; + end; +end; + +procedure tmsebufdataset.clearfilter; +var + int1: integer; + statebefore: tdatasetstate; + kindbefore,kind1,firstki,lastki: filtereditkindty; +begin + checkactive; + try + disablecontrols; + statebefore:= settempstate(dsfilter); + kindbefore:= filtereditkind; + if statebefore = dsfilter then begin + firstki:= filtereditkind; + lastki:= firstki; + end + else begin + firstki:= low(filtereditkindty); + lastki:= high(filtereditkindty); + end; + for kind1:= firstki to lastki do begin + filtereditkind:= kind1; + for int1:= 0 to fields.count - 1 do begin + with fields[int1] do begin + if not isblob then begin + clear; + end; + end; + end; + end; + if (statebefore <> dsfilter) then begin + for kind1:= low(filtereditkindty) to high(filtereditkindty) do begin + if checkcanevent(self,tmethod(fbeforeendfilteredit)) then begin + fbeforeendfilteredit(self,kind1); + end; + end; + resync([]); + filterchanged1(true); + end; + finally + filtereditkind:= kindbefore; + restorestate(statebefore); + enablecontrols; + end; +end; + +procedure tmsebufdataset.fetchall; +begin + getnextpacket(true); +end; + +procedure tmsebufdataset.checksumfield(const afield: tfield; + const fieldtypes: fieldtypesty); +begin + checkbrowsemode; + if (afield.fieldno <= 0) or (afield.dataset <> self) or + not (ffieldinfos[afield.fieldno-1].base.fieldtype in + fieldtypes) then begin + raise edatabaseerror.create('Invalid sum field '+'"'+afield.fieldname+'".'); + end; +end; + +procedure tmsebufdataset.sumfield(const afield: tfield; out asum: double); +var + int1,int2: integer; + index1: integer; + po1: precheaderty; + po2: pprecheaderty; + bo1,bo2: boolean; + state1: tdatasetstate; +begin + checksumfield(afield,[ftfloat,ftcurrency]); + index1:= afield.fieldno - 1; + asum:= 0; + bo1:= filtered and assigned(onfilterrecord); + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + int2:= ffieldinfos[index1].base.offset; + po2:= pointer(findexes[0]); + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)^[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag(@fcheckfilterbuffer^.header.fielddata.nullmask, + index1) then begin + asum:= asum + pdouble(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pdouble(pchar(po1)+int2)^; + end; + end; + end; + finally + restorestate(state1); + end; +end; + +procedure tmsebufdataset.sumfield(const afield: tfield; out asum: currency); +var + int1,int2: integer; + index1: integer; + po1: precheaderty; + po2: pprecheaderty; + bo1,bo2: boolean; + state1: tdatasetstate; +begin + checksumfield(afield,[ftbcd,ftfloat]); + index1:= afield.fieldno - 1; + asum:= 0; + bo1:= filtered and assigned(onfilterrecord); + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + int2:= ffieldinfos[index1].base.offset; + po2:= pointer(findexes[0]); + case ffieldinfos[afield.fieldno-1].base.fieldtype of + ftbcd: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) then begin + asum:= asum + pcurrency(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pcurrency(pchar(po1)+int2)^; + end; + end; + end; + end; + ftfloat: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty( + pchar(ppointeraty(po2)^[int1])-sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) then begin + asum:= asum + pdouble(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pdouble(pchar(po1)+int2)^; + end; + end; + end; + end; + end; + finally + restorestate(state1); + end; +end; + +procedure tmsebufdataset.sumfield(const afield: tfield; out asum: int64); +var + int1,int2: integer; + index1: integer; + po1: precheaderty; + po2: pprecheaderty; + bo1,bo2: boolean; + state1: tdatasetstate; +begin + checksumfield(afield,[ftlargeint,ftinteger,ftsmallint,ftword]); + index1:= afield.fieldno - 1; + asum:= 0; + bo1:= filtered and assigned(onfilterrecord); + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + int2:= ffieldinfos[index1].base.offset; + po2:= pointer(findexes[0]); + case ffieldinfos[afield.fieldno-1].base.fieldtype of + ftlargeint: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)^[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) then begin + asum:= asum + pint64(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pint64(pchar(po1)+int2)^; + end; + end; + end; + end; + ftinteger,ftsmallint,ftword: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)^[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) then begin + asum:= asum + pinteger(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pinteger(pchar(po1)+int2)^; + end; + end; + end; + end; + end; + finally + restorestate(state1); + end; +end; + +procedure tmsebufdataset.sumfield(const afield: tfield; out asum: integer); +var + int1,int2: integer; + index1: integer; + po1: precheaderty; + po2: pprecheaderty; + bo1,bo2: boolean; + state1: tdatasetstate; +begin + checksumfield(afield,[ftinteger,ftsmallint,ftword,ftboolean]); + index1:= afield.fieldno - 1; + asum:= 0; + bo1:= filtered and assigned(onfilterrecord); + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + int2:= ffieldinfos[index1].base.offset; + po2:= pointer(findexes[0]); + case ffieldinfos[afield.fieldno-1].base.fieldtype of + ftinteger,ftsmallint,ftword: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)^[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) then begin + asum:= asum + pinteger(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pinteger(pchar(po1)+int2)^; + end; + end; + end; + end; + ftboolean: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)^[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) and + pwordbool(pchar(@fcheckfilterbuffer^.header)+int2)^ then begin + inc(asum); + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) and + pwordbool(pchar(po1)+int2)^ then begin + inc(asum); + end; + end; + end; + end; + end; + finally + restorestate(state1); + end; +end; + +function tmsebufdataset.sumfielddouble(const afield: tfield): double; +begin + sumfield(afield,result); +end; + +function tmsebufdataset.sumfieldcurrency(const afield: tfield): currency; +begin + sumfield(afield,result); +end; + +function tmsebufdataset.sumfieldinteger(const afield: tfield): integer; +begin + sumfield(afield,result); +end; + +function tmsebufdataset.sumfieldint64(const afield: tfield): int64; +begin + sumfield(afield,result); +end; + +function tmsebufdataset.countvisiblerecords: integer; +var + int1{,int2}: integer; +// getresult: tgetresult; +begin + if not (state in [dsinactive,dsfilter]) then begin + checkbrowsemode; + if not (bs_visiblerecordcountvalid in fbstate) then begin + if not filtered then begin + fetchall; + fvisiblerecordcount:= fbrecordcount; + end + else begin + int1:= frecno; + disablecontrols; + getnextpacket(true); + try + fvisiblerecordcount:= 0; + internalsetrecno(0); + if (getrecord(activebuffer,gmcurrent,false) = grok) or + (getrecord(activebuffer,gmnext,false) = grok) then begin + repeat + inc(fvisiblerecordcount); + until getrecord(activebuffer,gmnext,false) <> grok; + end; + finally + internalsetrecno(int1); + getrecord(activebuffer,gmcurrent,false); + enablecontrols; + end; + end; + include(fbstate,bs_visiblerecordcountvalid); + end; + result:= fvisiblerecordcount; + end + else begin + result:= 0; + end; +end; + +const + bufdattag: bufdattagty = 'MSEBUFDAT'#0#0#0#0#0#0; + +// data format: +// +// header: bdsfheaderty +// fielddefs +// currentvalues: recbufferheader,pointer,nullmask,fielddata +// updatebuffer +// updatebufferitem: updatebufferheader,old nullmask,fielddata if not insert +// post log +// endmarker + +procedure tmsebufdataset.logupdatebuffer(const awriter: tbufstreamwriter; + const abuffer: recupdatebufferty; + const adeletedrecord: pintrecordty; + const alogging: boolean; const alogmode: logflagty); +var + header1: logbufferheaderty; + datapo: precheaderty; + int2: integer; +begin + header1.logflag:= alogmode; + with abuffer,header1.update do begin + if (info.bookmark.recordpo <> nil) or (deletedrecord <> 0{nil}) then begin + deletedrecord:= ptruint(adeletedrecord); + logging:= alogging; + if (ruf_inupdate in info.flags) and (info.updatekind = ukmodify) then begin + kind:= uk_modifyinupdate; + end + else begin + kind:= updatekindty(info.updatekind); + end; + po:= ptruint(info.bookmark.recordpo); + awriter.writelogbufferheader(header1); + if (alogmode = lf_update) and + ((kind in [uk_modify,uk_modifyinupdate]) or + not logging and (kind = uk_delete) and (po <> 0{nil})) then begin + datapo:= @(oldvalues^.header); + awriter.write(datapo^.fielddata,fnullmasksize); + for int2:= 0 to high(ffieldinfos) do begin + awriter.writefielddata(datapo,int2); + end; + end; + end; + end; +end; + +procedure tmsebufdataset.logrecbuffer(const awriter: tbufstreamwriter; + const akind: tupdatekind; const abuffer: pintrecordty); +var + datapo: precheaderty; + header1: logbufferheaderty; + int1: integer; +begin + header1.logflag:= lf_rec; + with header1.rec do begin + kind:= akind; + po:= ptruint(abuffer); + end; + awriter.writelogbufferheader(header1); + if akind in [ukmodify,ukinsert] then begin + datapo:= @(abuffer^.header); + awriter.write(datapo^.fielddata,fnullmasksize); + for int1:= 0 to high(ffieldinfos) do begin + awriter.writefielddata(datapo,int1); + end; + end; +end; + +procedure tmsebufdataset.savestate(const awriter: tbufstreamwriter); +var + header: tbsfheaderty; +// writer: tbufstreamwriter; + fieldco: integer; + int1{,int2}: integer; +begin + fieldco:= length(ffieldinfos); + with header do begin + tag:= bufdattag; + byteorder:= 0; + {$ifdef cpu64} + byteorder:= byteorder + 2; + {$endif} + version:= 2; + fieldcount:= fieldco; + fielddefcount:= fielddefs.count; + recordcount:= self.recordcount; + end; + if header.fieldcount > 0 then begin + awriter.write(header,sizeof(header)); + for int1:= 0 to header.fielddefcount - 1 do begin + awriter.writefielddef(fielddefs[int1]); + end; + for int1:= 0 to high(ffieldinfos) do begin + awriter.write(ffieldinfos[int1],sizeof(fieldinfobasety)); + end; + with findexes[0] do begin + for int1:= 0 to recordcount - 1 do begin + logrecbuffer(awriter,ukinsert,pintrecordty(ind[int1])); + end; + end; + for int1:= 0 to high(fupdatebuffer) do begin + with fupdatebuffer[int1] do begin + if info.bookmark.recordpo <> nil then begin + { + if updatekind = ukinsert then begin + logrecbuffer(awriter,updatekind, + bookmark.recordpo); + end; + } + logupdatebuffer(awriter,fupdatebuffer[int1],nil,false,lf_update); + end; + end; + end; + end; +end; + +procedure tmsebufdataset.savetostream(const astream: tstream); +var + writer: tbufstreamwriter; +begin + checkbrowsemode; + fetchallblobs; + writer:= tbufstreamwriter.create(self,astream); + try + savestate(writer); + writer.writeendmarker; + finally + writer.free; + end; +end; + +procedure tmsebufdataset.doloadfromstream; + + procedure formaterror; + begin + databaseerror('Invalid data stream.',self); + end; + +var + header: tbsfheaderty; + reader: tbufstreamreader; + fieldco: integer; + ar2: card64arty;//pointerarty; + ar3: integerarty; + appended: card64arty; //pointerarty; + po1: pointer; + + function findrec(const oldpo: card64{pointer}; out newpo: pointer; + out aindex: integer; + const delete: boolean = false): boolean; + //returns new pointer + var + int1: integer; + begin + result:= findarrayitem(oldpo,ar2,sizeof(card64),@comparecard64,int1); +// result:= findarrayitem(oldpo,ar2,sizeof(pointer),@comparepointer,int1); + if result then begin + aindex:= ar3[int1]; + newpo:= findexes[0].ind[aindex]; + if delete then begin + dec(header.recordcount); + dec(fbrecordcount); + deleteitem(findexes[0].ind,aindex); + deleteitem(ar3,int1); + deleteitem(ar2,int1); + end; + end + else begin + for int1:= 0 to high(appended) do begin + if appended[int1] = oldpo then begin + aindex:= header.recordcount+int1; + newpo:= findexes[0].ind[aindex]; + result:= true; + if delete then begin +// appended[int1]:= nil; + deleteitem(appended,int1); + deleteitem(findexes[0].ind,aindex); + dec(fbrecordcount); + end; + break; + end; + end; + end; + end; + +var + actindexbefore: integer; + oldupdatepointers: card64arty; //pointerarty; +// bo1: boolean; + int1,int2,int3: integer; + header1: logbufferheaderty; + updabuf: recupdatebufferarty; + p2: pfieldinfobasety; + +begin + initsavepoint; + updabuf:= nil; //compilerwarning + actindexbefore:= factindex; + factindex:= 0; + factindexpo:= @findexes[0]; + fbstate:= fbstate - [bs_blobscached]; + resetindex(); +// exclude(fbstate,bs_blobscached); + reader:= tbufstreamreader.create(self,floadingstream); + try + reader.readbuffer(header,sizeof(header)); + if (header.tag <> bufdattag) or (header.fielddefcount > 1000) then begin + formaterror; + end; + try + fielddefs.beginupdate; + try + fielddefs.clear; + for int1:= 0 to header.fielddefcount - 1 do begin + reader.readfielddef(fielddefs); + end; + finally + fielddefs.endupdate; + end; + dointernalopen; + fieldco:= length(ffieldinfos); + if (header.fieldcount <> fieldco) then begin + formaterror; + end; + if fieldco > 0 then begin + if header.version = 0 then begin + int1:= sizeof(fieldinfo_0ty); + end + else begin + int1:= sizeof(fieldinfobasety); + end; + getmem(p2,int1*fieldco); + po1:= p2; + try + reader.readbuffer(p2^,int1*fieldco); + for int2:= 0 to fieldco-1 do begin + with ffieldinfos[int2].base do begin + if (p2^.fieldtype <> fieldtype) or + (p2^.dbfieldsize <> dbfieldsize) then begin + formaterror(); + end; + {$ifdef cpu64} + if (header.version < 2) or + ((p2^.offset < offset) or (p2^.size < size)) then begin + reader.f32to64:= true; + end; + {$endif} + inc(p2); + end; +{ + if not comparemem(pchar(po1)+int1*int2,@ffieldinfos[int2], + sizeof(fieldinfobasety)) then begin + formaterror; + end; +} + end; + {$ifndef cpu64} + if header.version < 2 then begin + reader.f32to64:= true; + end; + {$endif} + finally + freemem(po1); + end; + setlength(ar2,header.recordcount); + {$ifdef mse_debuglogger} + debugwriteln('**log read '+inttostr(header.recordcount)+' records'); + {$endif} + for int1:= 0 to high(ar2) do begin + if not reader.readlogbufferheader(header1) or + (header1.logflag <> lf_rec) then begin + formaterror; + end; + {$ifdef mse_debuglogger} + debugwriteln(' '+inttostr(int1)+' '+hextostr(femptybuffer)); + {$endif} + ar2[int1]:= header1.rec.po; + reader.readrecord(femptybuffer); + appendrecord(femptybuffer); + femptybuffer:= intallocrecord; + end; +// ar1:= nil; + if header.recordcount > 0 then begin +// allocuninitedarray(fbrecordcount,sizeof(pointer),ar1); +// move(pointer(findexes[0])^,pointer(ar1)^,fbrecordcount*sizeof(pointer)); + sortarray(ar2,sizeof(card64),@comparecard64,ar3); + //index of old pointers + end + else begin + ar3:= nil; + end; + int2:= 0; + while reader.readlogbufferheader(header1) do begin + {$ifdef mse_debuglogger} + debugwrite(inttostr(int2)); + {$endif} + case header1.logflag of + lf_rec: begin + with header1.rec do begin + if not findrec(po,po1,int1) then begin + if kind <> ukinsert then begin + formaterror; + end; + {$ifdef mse_debuglogger} + debugwrite(' new '+hextostr(femptybuffer)); + {$endif} + reader.readrecord(femptybuffer); + appendrecord(femptybuffer); + femptybuffer:= intallocrecord; + additem(appended,po); + end + else begin + {$ifdef mse_debuglogger} + debugwrite(' found '+hextostr(po1)); + {$endif} + reader.readrecord(po1); + end; + end; + end; + lf_update: begin + if high(updabuf) < int2 then begin + setlength(updabuf,2*high(updabuf)+258); + setlength(oldupdatepointers,length(updabuf)); + end; + with updabuf[int2],header1.update do begin + if kind = uk_modifyinupdate then begin + info.updatekind:= ukmodify; + include(info.flags,ruf_inupdate); + end + else begin + info.updatekind:= tupdatekind(kind); + exclude(info.flags,ruf_inupdate); + end; + oldupdatepointers[int2]:= po; + int3:= -1; + if deletedrecord <> 0{nil} then begin + for int1:= 0 to int2 - 1 do begin + if oldupdatepointers[int1] = deletedrecord then begin + int3:= int1; + break; + end; + end; + end; + {$ifdef mse_debuglogger} + debugwrite(' '+inttostr(int3)+' '+getenumname(typeinfo(kind),ord(kind))); + {$endif} + if kind = uk_delete then begin + if logging and (po <> deletedrecord) then begin + if (int3 < 0) or not findrec(deletedrecord,po1,int1,true) then begin + formaterror; + end; + if po = 0{nil} then begin + {$ifdef mse_debuglogger} + debugwrite(' inserted '+hextostr(po1)); + {$endif} + info.bookmark.recordpo:= nil; //deleting of inserted record + intfreerecord(pintrecordty(po1)); + end + else begin //deleting of modified record + {$ifdef mse_debuglogger} + debugwrite(' modified '+ + hextostr(updabuf[int3].info.bookmark.recordpo)+ + ' old '+hextostr(updabuf[int3].oldvalues)); + {$endif} + intfreerecord(updabuf[int3].info.bookmark.recordpo); + info.bookmark.recordpo:= updabuf[int3].oldvalues; + info.bookmark.recno:= 0; + end; + updabuf[int3].info.bookmark.recordpo:= nil; //to be removed + end + else begin + if logging then begin + if not findrec(deletedrecord,pointer(info.bookmark.recordpo), + info.bookmark.recno,true) then begin + formaterror; + end; + {$ifdef mse_debuglogger} + debugwrite(' found '+hextostr(info.bookmark.recordpo)); + {$endif} + end + else begin + info.bookmark.recno:= 0; + info.bookmark.recordpo:= intallocrecord; + reader.readrecord(info.bookmark.recordpo); + {$ifdef mse_debuglogger} + debugwrite(' new '+hextostr(info.bookmark.recordpo)); + {$endif} + end; + end; + oldvalues:= info.bookmark.recordpo; + end + else begin + if not findrec(po,pointer(info.bookmark.recordpo), + info.bookmark.recno) then begin + formaterror; //old pointer not found + end; + {$ifdef mse_debuglogger} + debugwrite(' found '+hextostr(info.bookmark.recordpo)); + {$endif} + end; + if kind in [uk_modify,uk_modifyinupdate] then begin + oldvalues:= intallocrecord; + reader.readrecord(oldvalues); + {$ifdef mse_debuglogger} + debugwrite(' new oldvalues '+hextostr(oldvalues)); + {$endif} + end; + end; + inc(int2); + end; + lf_cancel: begin + with header1.update do begin + int3:= -1; + for int1:= 0 to int2 - 1 do begin + if oldupdatepointers[int1] = po then begin + int3:= int1; + break; + end; + end; + if int3 < 0 then begin + formaterror; + end; + case kind of + uk_modify,uk_modifyinupdate: begin + cancelrecupdate(updabuf[int3]); + end; + uk_delete: begin + with updabuf[int3] do begin + appendrecord(info.bookmark.recordpo); + additem(appended,oldupdatepointers[int3]); +// additem(appended,bookmark.recordpo); + end; + end; + uk_insert: begin + if not findrec(oldupdatepointers[int3],po1,int1,true) then begin + formaterror; + end; + with updabuf[int3] do begin + intfreerecord(info.bookmark.recordpo); + end; + end; + end; + updabuf[int3].info.bookmark.recordpo:= nil; + oldupdatepointers[int3]:= 0{nil}; + //inactive + end; + end; + lf_apply,lf_drop: begin + with header1.update do begin + int3:= -1; + for int1:= 0 to int2-1 do begin + if oldupdatepointers[int1] = po then begin + int3:= int1; + break; + end; + end; + if int3 < 0 then begin + formaterror; + end; + with updabuf[int3] do begin + intfreerecord(oldvalues); + info.bookmark.recordpo:= nil; + oldupdatepointers[int3]:= 0{nil}; + //inactive + end; + end; + end; + else begin + formaterror; + end; + end; + {$ifdef mse_debuglogger} + debugwriteln(''); + {$endif} + end; + setlength(updabuf,int2); + setlength(fupdatebuffer,int2); + int2:= 0; //pack updatebuffer + for int1:= 0 to high(updabuf) do begin + if updabuf[int1].info.bookmark.recordpo <> nil then begin + fupdatebuffer[int2]:= updabuf[int1]; + inc(int2); + end; + end; + setlength(fupdatebuffer,int2); + fallpacketsfetched:= true; + end; + include(fbstate,bs_blobsfetched); + sortblobcache; + except + dointernalclose; + raise; + end; + finally + reader.free; + factindex:= actindexbefore; + factindexpo:= @findexes[factindex]; + if active then begin + checkindex(factindex); + end; + end; +end; + +procedure tmsebufdataset.loadfromstream(const astream: tstream); +begin + checkinactive; + floadingstream:= astream; + include(fbstate,bs_loading); + try + active:= true; + finally + exclude(fbstate,bs_loading); + floadingstream:= nil; + end; +end; + +function tmsebufdataset.streamloading: boolean; +begin + result:= bs_loading in fbstate; +end; + +function tmsebufdataset.addblobcache(const adata: pointer; + const alength: integer): integer; +begin + if ffreedblobcount > 0 then begin + dec(ffreedblobcount); + result:= ffreedblobs[ffreedblobcount]; + if (ffreedblobcount = 0) and (high(ffreedblobs) > 10000) then begin + ffreedblobs:= nil; + end; + end + else begin + result:= fblobcount; + inc(fblobcount); + if result > high(fblobcache) then begin + setlength(fblobcache,2*result+256); + end; + end; + with fblobcache[result] do begin + id:= result; + setlength(data,alength); + {$ifdef FPC} {$checkpointer off} {$endif} //adata can be foreign memory + move(adata^,pointer(data)^,alength); + {$ifdef FPC} {$checkpointer default} {$endif} + end; + exclude(fbstate,bs_blobssorted); +end; + +function tmsebufdataset.addblobcache(const aid: int64; + const adata: string): integer; +begin + result:= fblobcount; + inc(fblobcount); + if result > high(fblobcache) then begin + setlength(fblobcache,2*result+256); + end; + with fblobcache[result] do begin + id:= aid; + data:= adata; + end; + exclude(fbstate,bs_blobssorted); +end; +{ +function tmsebufdataset.wantblobfetch: boolean; +begin + result:= false; +end; +} +{ +function tmsebufdataset.getdsoptions: datasetoptionsty; +begin + result:= []; +end; +} +procedure tmsebufdataset.checkconnected; +begin + if not (bs_connected in fbstate) then begin + databaseerror('Not connected.',self); + end; +end; + +procedure tmsebufdataset.savetofile(afilename: filenamety = ''; + const acryptohandler: tcustomcryptohandler = nil); +var + stream1: tmsefilestream; +begin + if afilename = '' then begin + checklogfile(); + afilename:= flogfilename; + end; + stream1:= tmsefilestream.createtransaction(afilename); + try + stream1.cryptohandler:= acryptohandler; + savetostream(stream1); + finally + stream1.free; + end; +end; + +procedure tmsebufdataset.loadfromfile(afilename: filenamety = ''; + const acryptohandler: tcustomcryptohandler = nil); +var + stream1: tmsefilestream; +begin + if afilename = '' then begin + checklogfile(); + afilename:= flogfilename; + end; + stream1:= tmsefilestream.create(afilename,fm_read); + try + stream1.cryptohandler:= acryptohandler; + loadfromstream(stream1); + finally + stream1.free; + end; +end; + +procedure tmsebufdataset.checklogfile; +begin + if trim(flogfilename) = '' then begin + databaseerror('No log file name.',self); + end; +end; + +procedure tmsebufdataset.recover; +begin + checklogfile; +// if islocal then begin +// active:= true; +// end +// else begin + loadfromfile(flogfilename,fcryptohandler); + startlogger; +// end; +end; + +procedure tmsebufdataset.startlogger; +var + stream1: tmsefilestream; +begin + if flogfilename <> '' then begin + if bdo_noapply in foptions then begin + databaseerror('Options bdo_noapply must not be set for logging.',self); + end; + stream1:= tmsefilestream.create(flogfilename,fm_create); + stream1.cryptohandler:= fcryptohandler; + flogger:= tbufstreamwriter.create(self,stream1); + {$ifdef mse_debuglogger} + debugwriteln('*****startlogger'); + {$endif} + savestate(flogger); + {$ifdef mse_debuglogger} + debugwriteln('-----startlogger'); + {$endif} + flogger.flushbuffer; + end; +end; + +procedure tmsebufdataset.closelogger; +var + stream1: tstream; +begin + if flogger <> nil then begin + flogger.writeendmarker; + stream1:= flogger.fstream; + freeandnil(flogger); + stream1.free; + {$ifdef mse_debuglogger} + debugwriteln('*****endlogger'); + {$endif} + end; +end; + +procedure tmsebufdataset.startlogging; + //close logfile, save state with truncated log, open logfile +begin + checklogfile; + checkbrowsemode; + closelogger; + startlogger; +end; + +procedure tmsebufdataset.stoplogging; + //close logfile +begin + closelogger; +end; + +function tmsebufdataset.getlogging: boolean; +begin + result:= flogger <> nil; +end; + +function tmsebufdataset.islocal: boolean; +begin + result:= false; +end; + +procedure tmsebufdataset.dobeforeapplyupdate; +begin + if checkcanevent(self,tmethod(fbeforeapplyupdate)) then begin + fbeforeapplyupdate(self); + end; +end; + +procedure tmsebufdataset.doafterapplyupdate; +begin + if checkcanevent(self,tmethod(fafterapplyupdate)) then begin + fafterapplyupdate(self); + end; +end; + +procedure tmsebufdataset.notifycontrols; +var + int1: integer; +begin + int1:= 0; + try + while controlsdisabled do begin + inc(int1); + enablecontrols; + end; + finally + while int1 > 0 do begin + dec(int1); + disablecontrols; + end; + end; +end; + +procedure tmsebufdataset.OpenCursor(InfoQuery: Boolean); +begin + inherited; +// tdatasetcracker(self).fbof:= true; +end; + +function tmsebufdataset.GetNextRecord: Boolean; +begin + result:= inherited getnextrecord; +// if frecno = 0 then begin +// tdatasetcracker(self).fbof:= true; +// end; +end; + +function tmsebufdataset.GetNextRecords: Longint; +begin + result:= inherited getnextrecords; +// if frecno = 0 then begin +// tdatasetcracker(self).fbof:= true; +// end; +end; + +function tmsebufdataset.getfiltereditkind: filtereditkindty; +begin + result:= ffiltereditkind; +end; + +function tmsebufdataset.getrestorerecno: boolean; +begin + result:= bs_restorerecno in fbstate; +end; + +procedure tmsebufdataset.setrestorerecno(const avalue: boolean); +begin + if avalue then begin + include(fbstate,bs_restorerecno); + end + else begin + exclude(fbstate,bs_restorerecno); + end; +end; + +function tmsebufdataset.islastrecord: boolean; +begin + result:= eof; + if not result then begin + fetchall; + result:= recno = recordcount; + end; +end; + +procedure tmsebufdataset.currentbeginupdate; +begin + currentcheckbrowsemode; + inc(fcurrentupdating); +end; +{ +procedure tmsebufdataset.currentdecupdate; +begin + dec(fcurrentupdating); + if fcurrentupdating = 0 then begin + exclude(fbstate,bs_curvalueset); + end; +end; +} +procedure tmsebufdataset.fixupcurrentset; +begin + if not (bs_recapplying in fbstate) and (fdisablecontrolscount <= 0) then begin + if factindexpo^.ind = nil then begin + bookmark:= bookmark; //possibly invalid recno + end + else begin + resync([]); + end; + end + else begin + include(fbstate1,bs1_needsresync); + end; +end; + +procedure tmsebufdataset.currentendupdate; +begin + dec(fcurrentupdating); + if fcurrentupdating = 0 then begin + if bs_curvalueset in fbstate then begin + exclude(fbstate,bs_curvalueset); + findexlocal.preparefixup; + fixupcurrentset; + end; + end; +end; + +procedure tmsebufdataset.currentcheckbrowsemode; +begin + if (state <> dsbrowse) and (fcurrentupdating = 0) and + ([bs1_recordupdating,bs1_posting] * fbstate1 = []) then begin + checkbrowsemode; + end; +end; + +function tmsebufdataset.getcurrentpo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: pintrecordty): pointer; +var + int1: integer; +begin + int1:= afield.fieldno-1; + if not getfieldflag(@arecord^.header.fielddata.nullmask,int1) then begin + result:= nil; + end + else begin + with ffieldinfos[int1] do begin + if (afieldtype <> ftunknown) and + not (ext.basetype in fielddatacompatibility[afieldtype]) then begin + raise ecurrentvalueaccess.create(self,afield,'Invalid fieldtype.'); + end; + result:= pchar(pointer(arecord)) + base.offset; + end; + end; +end; + +function tmsebufdataset.getcurrentlookuppo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: pintrecordty): pointer; +var + po1: pointer; + bm1: bookmarkdataty; +begin + result:= nil; + with flookupfieldinfos[-1-afield.fieldno] do begin + if indexnum < 0 then begin + raise ecurrentvalueaccess.create(self,afield,'No lookup index.'); + end; + if (afieldtype <> ftunknown) and + not (basedatatype in fielddatacompatibility[afieldtype]) then begin + raise ecurrentvalueaccess.create(self,afield,'Invalid fieldtype.'); + end; + po1:= flookuppo; + flookuppo:= arecord; + try + if afield.lookupdataset.active and + tmsebufdataset(afield.lookupdataset).indexlocal[indexnum].find( + keyfieldar,bm1,false,false,true) then begin + if lookupvaluefield.fieldno > 0 then begin + getvalue(lookupvaluefield,bm1,flookupresult); + result:= flookupresult.po; + end + else begin + if afield.lookupdataset <> nil then begin + with tmsebufdataset(afield.lookupdataset) do begin + currentcheckbrowsemode; + result:= getcurrentlookuppo(lookupvaluefield,afieldtype,bm1.recordpo); + end; + end; + end; + end; + finally + flookuppo:= po1; + end; + end; +end; + +function tmsebufdataset.beforecurrentget(const afield: tfield; + const afieldtype: tfieldtype; var aindex: integer): pointer; +begin + currentcheckbrowsemode; + if afield.dataset <> self then begin + raise ecurrentvalueaccess.create(self,afield,'Wrong dataset.'); + end; + checkindex(factindex); + if aindex < 0 then begin + aindex:= frecno; + end; + if (aindex < 0) or (aindex > high(factindexpo^.ind)) then begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid index '+inttostr(aindex)+'.'); + end; + if afield.fieldkind = fkcalculated then begin + raise ecurrentvalueaccess.create(self,afield, + 'Field can not be be fkCalculated.'); + end; + if afield.fieldno < 0 then begin + result:= getcurrentlookuppo(afield,afieldtype,factindexpo^.ind[aindex]); + end + else begin + result:= getcurrentpo(afield,afieldtype,factindexpo^.ind[aindex]); + end; +end; + +function tmsebufdataset.beforecurrentbmget(const afield: tfield; + const afieldtype: tfieldtype; const abm: bookmarkdataty): pointer; +begin + currentcheckbrowsemode; + if afield.dataset <> self then begin + raise ecurrentvalueaccess.create(self,afield,'Wrong dataset.'); + end; + if afield.fieldkind = fkcalculated then begin + raise ecurrentvalueaccess.create(self,afield, + 'Field can not be be fkCalculated.'); + end; + result:= nil; + if abm.recordpo <> nil then begin + if (afield.fieldno < 0) then begin + result:= getcurrentlookuppo(afield,afieldtype,abm.recordpo); + end + else begin + result:= getcurrentpo(afield,afieldtype,abm.recordpo); + end; + end; +end; + +function tmsebufdataset.setcurrentpo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: precheaderty; + const aisnull: boolean; out changed: boolean): pointer; +var + po1: pbyte; + int1: integer; +begin +// flastcurrentrec:= pointer(arecord) - sizeof(intrecordty.intheader); + po1:= @arecord^.fielddata.nullmask; + int1:= afield.fieldno-1; + with ffieldinfos[int1] do begin + if (afieldtype <> ftunknown) and + not (ext.basetype in fielddatacompatibility[afieldtype]) then begin + raise ecurrentvalueaccess.create(self,afield,'Invalid fieldtype.'); + end; + changed:= not getfieldflag(po1,int1) xor aisnull; + if changed then begin + if aisnull then begin + clearfieldflag(po1,int1); + end + else begin + setfieldflag(po1,int1); + end; + end; + result:= pchar(pointer(arecord)) + base.offset; + end; +end; + +function tmsebufdataset.beforecurrentset(const afield: tfield; + const afieldtype: tfieldtype; var aindex: integer; + const aisnull: boolean; out changed: boolean): pointer; +begin + currentcheckbrowsemode; + if afield.dataset <> self then begin + raise ecurrentvalueaccess.create(self,afield,'Wrong dataset.'); + end; + if (afield.fieldkind <> fkinternalcalc) then begin + raise ecurrentvalueaccess.create(self,afield,'Field must be fkInternalCalc.'); + end; + checkindex(factindex); + if aindex < 0 then begin + aindex:= frecno; + end; + if (aindex < 0) or (aindex > high(factindexpo^.ind)) then begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid index '+inttostr(aindex)+'.'); + end; + flastcurrentindex:= aindex; + result:= setcurrentpo(afield,afieldtype,factindexpo^.ind[aindex], + aisnull,changed); +end; + +function tmsebufdataset.beforecurrentbmset(const afield: tfield; + const afieldtype: tfieldtype; const abm: bookmarkdataty; + const aisnull: boolean; out changed: boolean): pointer; +begin + currentcheckbrowsemode; + if afield.dataset <> self then begin + raise ecurrentvalueaccess.create(self,afield,'Wrong dataset.'); + end; + if (afield.fieldkind <> fkinternalcalc) then begin + raise ecurrentvalueaccess.create(self,afield,'Field must be fkInternalCalc.'); + end; + flastcurrentindex:= -1; + result:= setcurrentpo(afield,afieldtype,@abm.recordpo^.header,aisnull,changed); +end; + +procedure tmsebufdataset.aftercurrentset(const afield: tfield); +//var +// int1: integer; +begin + if fcurrentupdating = 0 then begin + findexlocal.fieldmodified(afield,false); + fixupcurrentset; + end + else begin + include(fbstate,bs_curvalueset); + findexlocal.fieldmodified(afield,true); + end; +end; + +function tmsebufdataset.getcurrentisnull(const afield: tfield; + aindex: integer): boolean; +begin + result:= beforecurrentget(afield,ftunknown,aindex) = nil; +end; + +function tmsebufdataset.getcurrentbmisnull(const afield: tfield; + const abm: bookmarkdataty): boolean; +begin + result:= beforecurrentbmget(afield,ftunknown,abm) = nil; +end; + +procedure tmsebufdataset.currentclear(const afield: tfield; aindex: integer); +var + bo1: boolean; +begin + beforecurrentset(afield,ftunknown,aindex,true,bo1); + if bo1 then begin + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.currentbmclear(const afield: tfield; + const abm: bookmarkdataty); +var + bo1: boolean; +begin + beforecurrentbmset(afield,ftunknown,abm,true,bo1); + if bo1 then begin + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.currentassign(const source: tfield; const dest: tfield; + aindex: integer); +var + po1: pointer; +begin + po1:= beforecurrentget(source,source.datatype,aindex); + if (po1 = nil) or (source.fieldno = 0) then begin + dest.clear; + end + else begin + if source.fieldno > 0 then begin + docurrentassign(po1,ffieldinfos[source.fieldno-1].ext.basetype,dest); + end + else begin + docurrentassign(po1,flookupfieldinfos[-1-source.fieldno].basedatatype,dest); + end; + end; +end; + +procedure tmsebufdataset.currentbmassign(const source: tfield; const dest: tfield; + const abm: bookmarkdataty); +var + po1: pointer; +begin + po1:= beforecurrentbmget(source,source.datatype,abm); + if (po1 = nil) or (source.fieldno = 0) then begin + dest.clear; + end + else begin + if source.fieldno > 0 then begin + docurrentassign(po1,ffieldinfos[source.fieldno-1].ext.basetype,dest); + end + else begin + docurrentassign(po1,flookupfieldinfos[-1-source.fieldno].basedatatype,dest); + end; + end; +end; + +function tmsebufdataset.getcurrentasvariant(const afield: tfield; + aindex: integer): variant; +begin + if currentisnull[afield,aindex] then begin + result:= null; + end + else begin + case afield.datatype of + ftboolean: begin + result:= getcurrentasboolean(afield,aindex); + end; + ftfloat: begin + result:= getcurrentasfloat(afield,aindex); + end; + ftdatetime,fttime,ftdate: begin + result:= getcurrentasdatetime(afield,aindex); + end; + ftbcd: begin + result:= getcurrentascurrency(afield,aindex); + end; + ftinteger,ftword,ftsmallint: begin + result:= getcurrentasinteger(afield,aindex); + end; + ftlargeint: begin + result:= getcurrentaslargeint(afield,aindex); + end; + ftstring: begin + result:= getcurrentasmsestring(afield,aindex); + end; + else begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid fieldtype field "'+afield.fieldname+'".'); + end; + end; + end; +end; + +procedure tmsebufdataset.setcurrentasvariant(const afield: tfield; + aindex: integer; const avalue: variant); +begin + if varisnull(avalue) then begin + currentclear(afield,aindex) + end + else begin + case afield.datatype of + ftboolean: begin + setcurrentasboolean(afield,aindex,avalue); + end; + ftfloat: begin + setcurrentasfloat(afield,aindex,avalue); + end; + ftdatetime,fttime,ftdate: begin + setcurrentasdatetime(afield,aindex,avalue); + end; + ftbcd: begin + setcurrentascurrency(afield,aindex,avalue); + end; + ftinteger,ftword,ftsmallint: begin + setcurrentasinteger(afield,aindex,avalue); + end; + ftlargeint: begin + setcurrentaslargeint(afield,aindex,avalue); + end; + ftstring: begin + setcurrentasmsestring(afield,aindex,avalue); + end; + else begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid fieldtype field "'+afield.fieldname+'".'); + end; + end; + end; +end; + +function tmsebufdataset.getcurrentbmasvariant(const afield: tfield; + const abm: bookmarkdataty): variant; +begin + if currentbmisnull[afield,abm] then begin + result:= null; + end + else begin + case afield.datatype of + ftboolean: begin + result:= getcurrentbmasboolean(afield,abm); + end; + ftfloat: begin + result:= getcurrentbmasfloat(afield,abm); + end; + ftdatetime,fttime,ftdate: begin + result:= getcurrentbmasdatetime(afield,abm); + end; + ftbcd: begin + result:= getcurrentbmascurrency(afield,abm); + end; + ftinteger,ftword,ftsmallint: begin + result:= getcurrentbmasinteger(afield,abm); + end; + ftlargeint: begin + result:= getcurrentbmaslargeint(afield,abm); + end; + ftstring: begin + result:= getcurrentbmasmsestring(afield,abm); + end; + else begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid fieldtype field "'+afield.fieldname+'".'); + end; + end; + end; +end; + +procedure tmsebufdataset.setcurrentbmasvariant(const afield: tfield; + const abm: bookmarkdataty; const avalue: variant); +begin + if varisnull(avalue) then begin + currentbmclear(afield,abm) + end + else begin + case afield.datatype of + ftboolean: begin + setcurrentbmasboolean(afield,abm,avalue); + end; + ftfloat: begin + setcurrentbmasfloat(afield,abm,avalue); + end; + ftdatetime,fttime,ftdate: begin + setcurrentbmasdatetime(afield,abm,avalue); + end; + ftbcd: begin + setcurrentbmascurrency(afield,abm,avalue); + end; + ftinteger,ftword,ftsmallint: begin + setcurrentbmasinteger(afield,abm,avalue); + end; + ftlargeint: begin + setcurrentbmaslargeint(afield,abm,avalue); + end; + ftstring: begin + setcurrentbmasmsestring(afield,abm,avalue); + end; + else begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid fieldtype field "'+afield.fieldname+'".'); + end; + end; + end; +end; + +function tmsebufdataset.getcurrentasguid(const afield: tfield; + aindex: integer): tguid; +var + po1: pguid; +begin + po1:= beforecurrentget(afield,ftfloat,aindex); + if po1 = nil then begin + result:= guid_null; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasguid(const afield: tfield; aindex: integer; + const avalue: tguid); +var + po1: pguid; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftfloat,aindex,false,bo1); + if bo1 or not isequalguid(po1^,avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasfloat(const afield: tfield; + aindex: integer): double; +var + po1: pdouble; +begin + po1:= beforecurrentget(afield,ftfloat,aindex); + if po1 = nil then begin + result:= emptyreal; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasfloat(const afield: tfield; + const abm: bookmarkdataty): double; +var + po1: pdouble; +begin + po1:= beforecurrentbmget(afield,ftfloat,abm); + if po1 = nil then begin + result:= emptyreal; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasfloat(const afield: tfield; + aindex: integer; const avalue: double); +var + po1: pdouble; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftfloat,aindex,avalue = emptyreal,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasfloat(const afield: tfield; + const abm: bookmarkdataty; const avalue: double); +var + po1: pdouble; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftfloat,abm,avalue = emptyreal,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasboolean(const afield: tfield; + aindex: integer): boolean; +var + po1: plongbool; +begin + po1:= beforecurrentget(afield,ftboolean,aindex); + if po1 = nil then begin + result:= false; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasboolean(const afield: tfield; + const abm: bookmarkdataty): boolean; +var + po1: plongbool; +begin + po1:= beforecurrentbmget(afield,ftboolean,abm); + if po1 = nil then begin + result:= false; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasboolean(const afield: tfield; + aindex: integer; const avalue: boolean); +var + po1: plongbool; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftboolean,aindex,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasboolean(const afield: tfield; + const abm: bookmarkdataty; const avalue: boolean); +var + po1: plongbool; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftboolean,abm,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasinteger(const afield: tfield; + aindex: integer): integer; +var + po1: pinteger; +begin + po1:= beforecurrentget(afield,ftinteger,aindex); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasinteger(const afield: tfield; + const abm: bookmarkdataty): integer; +var + po1: pinteger; +begin + po1:= beforecurrentbmget(afield,ftinteger,abm); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasinteger(const afield: tfield; + aindex: integer; const avalue: integer); +var + po1: pinteger; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftinteger,aindex,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasinteger(const afield: tfield; + const abm: bookmarkdataty; const avalue: integer); +var + po1: pinteger; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftinteger,abm,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentaslargeint(const afield: tfield; + aindex: integer): int64; +var + po1: pint64; +begin + po1:= beforecurrentget(afield,ftlargeint,aindex); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmaslargeint(const afield: tfield; + const abm: bookmarkdataty): int64; +var + po1: pint64; +begin + po1:= beforecurrentbmget(afield,ftlargeint,abm); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentaslargeint(const afield: tfield; + aindex: integer; const avalue: int64); +var + po1: pint64; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftlargeint,aindex,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmaslargeint(const afield: tfield; + const abm: bookmarkdataty; const avalue: int64); +var + po1: pint64; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftlargeint,abm,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasid(const afield: tfield; + aindex: integer): int64; +var + po1: pint64; +begin + po1:= beforecurrentget(afield,ftlargeint,aindex); + if po1 = nil then begin + result:= -1; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasid(const afield: tfield; + const abm: bookmarkdataty): int64; +var + po1: pint64; +begin + po1:= beforecurrentbmget(afield,ftlargeint,abm); + if po1 = nil then begin + result:= -1; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasid(const afield: tfield; aindex: integer; + const avalue: int64); +var + po1: pint64; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftlargeint,aindex,avalue = -1,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasid(const afield: tfield; + const abm: bookmarkdataty; const avalue: int64); +var + po1: pint64; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftlargeint,abm,avalue = -1,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasdatetime(const afield: tfield; + aindex: integer): tdatetime; +var + po1: pdatetime; +begin + po1:= beforecurrentget(afield,ftdatetime,aindex); + if po1 = nil then begin + result:= emptydatetime; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasdatetime(const afield: tfield; + const abm: bookmarkdataty): tdatetime; +var + po1: pdatetime; +begin + po1:= beforecurrentbmget(afield,ftdatetime,abm); + if po1 = nil then begin + result:= emptydatetime; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasdatetime(const afield: tfield; + aindex: integer; const avalue: tdatetime); +var + po1: pdouble; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftdatetime,aindex,avalue = emptydatetime,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasdatetime(const afield: tfield; + const abm: bookmarkdataty; const avalue: tdatetime); +var + po1: pdouble; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftdatetime,abm,avalue = emptydatetime,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentascurrency(const afield: tfield; + aindex: integer): currency; +var + po1: pcurrency; +begin + po1:= beforecurrentget(afield,ftbcd,aindex); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmascurrency(const afield: tfield; + const abm: bookmarkdataty): currency; +var + po1: pcurrency; +begin + po1:= beforecurrentbmget(afield,ftbcd,abm); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentascurrency(const afield: tfield; + aindex: integer; const avalue: currency); +var + po1: pcurrency; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftbcd,aindex,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmascurrency(const afield: tfield; + const abm: bookmarkdataty; const avalue: currency); +var + po1: pcurrency; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftbcd,abm,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasmsestring(const afield: tfield; + aindex: integer): msestring; +var + po1: pmsestring; +begin + po1:= beforecurrentget(afield,ftwidestring,aindex); + if po1 = nil then begin + result:= ''; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasmsestring(const afield: tfield; + const abm: bookmarkdataty): msestring; +var + po1: pmsestring; +begin + po1:= beforecurrentbmget(afield,ftwidestring,abm); + if po1 = nil then begin + result:= ''; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasguid(const afield: tfield; + const abm: bookmarkdataty): tguid; +var + po1: pguid; +begin + po1:= beforecurrentbmget(afield,ftguid,abm); + if po1 = nil then begin + result:= guid_null; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasmsestring(const afield: tfield; + aindex: integer; const avalue: msestring); +var + po1: pmsestring; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftwidestring,aindex,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasmsestring(const afield: tfield; + const abm: bookmarkdataty; const avalue: msestring); +var + po1: pmsestring; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftwidestring,abm,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasguid(const afield: tfield; + const abm: bookmarkdataty; + const avalue: tguid); +var + po1: pguid; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftguid,abm,false,bo1); + if bo1 or not isequalguid(po1^,avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.getbminteger(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pinteger; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.int:= po1^; + adata.po:= @adata.int; + end; +end; + +procedure tmsebufdataset.getbmlargeint(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pint64; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.lint:= po1^; + adata.po:= @adata.lint; + end; +end; + +procedure tmsebufdataset.getbmcurrency(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pcurrency; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.cur:= po1^; + adata.po:= @adata.cur; + end; +end; + +procedure tmsebufdataset.getbmfloat(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pdouble; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.doub:= po1^; + adata.po:= @adata.doub; + end; +end; + +procedure tmsebufdataset.getbmstring(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pmsestring; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.mstr:= po1^; + adata.po:= @adata.mstr; + end; +end; + +procedure tmsebufdataset.getbmguid(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pguid; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.guid:= po1^; + adata.po:= @adata.guid; + end; +end; + +procedure tmsebufdataset.getbmboolean(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: plongbool; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.boo:= po1^; + adata.po:= @adata.boo; + end; +end; + +procedure tmsebufdataset.getbmdatetime(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pdatetime; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.dt:= po1^; + adata.po:= @adata.dt; + end; +end; + +procedure tmsebufdataset.getbmvariant(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pvariant; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.vari:= po1^; + adata.po:= @adata.vari; + end; +end; + +procedure tmsebufdataset.dogetcoldata(const afield: tfield; + const afieldtype: tfieldtype; const step: integer; + const data: pointer); +var + po2: pointer; + offs: ptrint; + indexpo: ppointer; + int1: integer; + ft1: tfieldtype; + +begin + if afield.dataset <> self then begin + raise ecurrentvalueaccess.create(self,afield,'Wrong dataset.'); + end; + if afield.index < 0 then begin + raise ecurrentvalueaccess.create(self,afield, + 'Field can not be be fkCalculated or fkLookup.'); + end; + ft1:= afieldtype; + if ft1 = ftwidestring then begin + ft1:= ftstring + end; + checkindex(factindex); + int1:= afield.fieldno-1; + with ffieldinfos[int1] do begin + if not (ext.basetype in fielddatacompatibility[ft1]) then begin + raise ecurrentvalueaccess.create(self,afield,'Invalid fieldtype.'); + end; + offs:= base.offset; + end; + po2:= data; + indexpo:= pointer(factindexpo^.ind); + case afieldtype of + ftinteger: begin + for int1:= 0 to fbrecordcount-1 do begin + pinteger(po2)^:= pinteger(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + ftlargeint: begin + for int1:= 0 to fbrecordcount-1 do begin + pint64(po2)^:= pint64(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + ftboolean: begin + for int1:= 0 to fbrecordcount-1 do begin + pboolean(po2)^:= plongbool(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + ftcurrency: begin + for int1:= 0 to fbrecordcount-1 do begin + pcurrency(po2)^:= pcurrency(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + ftfloat,ftdatetime: begin + for int1:= 0 to fbrecordcount-1 do begin + prealty(po2)^:= pdouble(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + ftstring: begin + for int1:= 0 to fbrecordcount-1 do begin + pansistring(po2)^:= + ansistring(pmsestring(pchar(ppointeraty(indexpo)^[int1])+offs)^); + inc(pchar(po2),step); + end; + end; + ftwidestring: begin + for int1:= 0 to fbrecordcount-1 do begin + pmsestring(po2)^:= pmsestring(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + end; +end; + +procedure tmsebufdataset.getcoldata(const afield: tfield; + const adatalist: tdatalist); +var + type1: tfieldtype; +begin + currentcheckbrowsemode; + with adatalist do begin + type1:= ftunknown; + case adatalist.datatype of + dl_integer: begin + type1:= ftinteger; + end; + dl_int64: begin + type1:= ftlargeint; + end; + dl_currency: begin + type1:= ftcurrency; + end; + dl_real,dl_realint,dl_realsum,dl_datetime: begin + type1:= ftfloat; + end; + dl_ansistring: begin + type1:= ftstring; + end; + dl_msestring,dl_doublemsestring,dl_msestringint: begin + type1:= ftwidestring; + end; + end; + if type1 <> ftunknown then begin + beginupdate; + try + clear; + count:= fbrecordcount; + dogetcoldata(afield,type1,size,datapo); + finally + endupdate; + end; + end + else begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid datalist.'); + end; + end; +end; + +procedure tmsebufdataset.asarray(const afield: tfield; + out avalue: int64arty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftlargeint,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; out avalue: integerarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftinteger,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; out avalue: stringarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftstring,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; + out avalue: msestringarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftwidestring,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; + out avalue: currencyarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftcurrency,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; out avalue: realarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftfloat,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; + out avalue: datetimearty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftdatetime,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; + out avalue: booleanarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftboolean,sizeof(avalue[0]),pointer(avalue)); +end; + +function tmsebufdataset.currentrecordhigh: integer; +begin + currentcheckbrowsemode; + result:= fbrecordcount - 1; +end; + +procedure tmsebufdataset.docurrentassign(const po1: pointer; + const abasetype: tfieldtype; + const df: tfield); +begin + case abasetype of + ftwidestring: begin + if df is tmsestringfield then begin + tmsestringfield(df).asmsestring:= pmsestring(po1)^; + end + else begin + df.asstring:= ansistring(pmsestring(po1)^); + end; + end; + ftinteger: begin + df.asinteger:= pinteger(po1)^; + end; + ftboolean: begin + df.asboolean:= plongbool(po1)^; + end; + ftbcd: begin + df.ascurrency:= pcurrency(po1)^; + end; + ftfloat: begin + df.asfloat:= pdouble(po1)^; + end; + ftlargeint: begin + df.aslargeint:= pint64(po1)^; + end; + ftdatetime: begin + df.asdatetime:= pdatetime(po1)^; + end; + ftvariant: begin + df.asvariant:= pvariant(po1)^; + end + else begin + df.clear; + end; + end; +end; + +procedure tmsebufdataset.copyfieldvalues(const bm: bookmarkdataty; + const dest: tdataset); + //copies field values with same name +var + df: tfield; + int1: integer; + int2: integer; + str1: string; +begin + if not active then begin + exit; + end; + currentcheckbrowsemode; + for int1:= 0 to dest.fieldcount - 1 do begin + df:= dest.fields[int1]; + if not df.readonly then begin + str1:= uppercase(df.fieldname); + for int2:= 0 to high(ffieldinfos)do begin + with ffieldinfos[int2] do begin + if (ext.uppername = str1) and (ext.basetype <> ftblob) and + ext.field.visible and + (ext.field.fieldkind <> fkcalculated) and + (ext.field.fieldkind <> fklookup) then begin + if not getfieldflag(@bm.recordpo^.header.fielddata.nullmask,int2) then begin + df.clear; + end + else begin + docurrentassign(pchar(bm.recordpo)+base.offset, + ffieldinfos[int2].ext.basetype,df); +{ + case ext.basetype of + ftwidestring: begin + if df is tmsestringfield then begin + tmsestringfield(df).asmsestring:= pmsestring(po1)^; + end + else begin + df.asstring:= pmsestring(po1)^; + end; + end; + ftinteger: begin + df.asinteger:= pinteger(po1)^; + end; + ftboolean: begin + df.asboolean:= plongbool(po1)^; + end; + ftbcd: begin + df.ascurrency:= pcurrency(po1)^; + end; + ftfloat: begin + df.asfloat:= pdouble(po1)^; + end; + ftlargeint: begin + df.aslargeint:= pint64(po1)^; + end; + ftdatetime: begin + df.asdatetime:= pdatetime(po1)^; + end; + ftvariant: begin + df.asvariant:= pvariant(po1)^; + end + else begin +// databaseerror(name+': Invalid datatype.'); + end; + end; +} + end; + end; + end; + end; + end; + end; +end; + +procedure tmsebufdataset.copyfieldvalues(const bm: bookmarkdataty; + const dest: tmsebufdataset; const acancelupdate: boolean); +var + bo1: boolean; +begin + with dest do begin + if not self.active or not active or fcontroller.posting1 then begin + exit; + end; + bo1:= state = dsbrowse; + disablecontrols; + try + edit; + self.copyfieldvalues(bm,dest); + if acancelupdate then begin + include(fbstate,bs_noautoapply); + post; + cancelupdate(true); + end + else begin + if bo1 then begin + post; + end; + end; + finally + exclude(fbstate,bs_noautoapply); + enablecontrols; + if bo1 or acancelupdate then begin + dataevent(dedatasetchange,0); + dataevent(tdataevent(de_modified),0); + end; + end; + end; +end; + +function tmsebufdataset.refreshrecord(const asourcevalues: array of variant; + const adestfields: array of tfield; + const akeyvalue: array of variant; const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +var + bm1,bm2: string; + int1: integer; +// bo1: boolean; +begin + if not active or fcontroller.posting1 then begin + exit; + end; + checkbrowsemode; + disablecontrols; + bm2:= bookmark; + try + if keyindex < 0 then begin + edit; + end + else begin + if indexlocal[keyindex].findvariant(akeyvalue,bm1) then begin + bookmark:= bm1; + edit; + end + else begin + if noinsert then begin + result.recno:= -1; + result.recordpo:= nil; + exit; + end; + insert; + end; + end; + for int1:= 0 to high(asourcevalues) do begin + if int1 > high(adestfields) then begin + break; + end; + adestfields[int1].value:= asourcevalues[int1]; + end; + if acancelupdate then begin + include(fbstate,bs_noautoapply); + post; + cancelupdate(true); + end + else begin + post; + end; + result.recno:= frecno; + result.recordpo:= fcurrentbuf; + finally + exclude(fbstate,bs_noautoapply); + if restorerecno and (keyindex >= 0) then begin + bookmark:= bm2; + end; + enablecontrols; + dataevent(dedatasetchange,0); + dataevent(tdataevent(de_modified),0); + end; +end; + +function tmsebufdataset.refreshrecord(const asourcefields: array of tfield; + const adestfields: array of tfield; + const akeyfield: array of tfield; const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +begin + result:= refreshrecord(fieldvariants(asourcefields),adestfields, + fieldvariants(akeyfield),keyindex,acancelupdate,restorerecno, + noinsert); +end; + +function tmsebufdataset.refreshrecord(const asourcefields: array of tfield; + const adestfields: array of tfield; + const akeyvalue: array of variant; const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +begin + result:= refreshrecord(fieldvariants(asourcefields),adestfields,akeyvalue,keyindex, + acancelupdate,restorerecno,noinsert); +end; + +function tmsebufdataset.refreshrecord(const asourcefields: array of tfield; + const akeyfield: array of tfield; const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +var + int1: integer; + ar1: fieldarty; +begin + setlength(ar1,length(asourcefields)); + for int1:= 0 to high(asourcefields) do begin + ar1[int1]:= fieldbyname(asourcefields[int1].fieldname); + end; + result:= refreshrecord(asourcefields,ar1,akeyfield,keyindex, + acancelupdate,restorerecno,noinsert); +end; +{ +procedure tmsebufdataset.refreshrecord(const akeyfield: tfield; + const keyindex: integer = 0; const acancelupdate: boolean = true); +var + int1,int2: integer; + field1,field2: tfield; + sf,df: fieldarty; +begin + with akeyfield.dataset do begin + int2:= 0; + setlength(sf,fields.count); //max + setlength(df,fields.count); //max + for int1:= 0 to high(sf) do begin + field1:= fields[int1]; + if field1.visible then begin + field2:= self.findfield(field1.fieldname); + if (field2 <> nil) and not field2.readonly then begin + sf[int2]:= field1; + df[int2]:= field2; + inc(int2); + end; + end; + end; + end; + setlength(sf,int2); + setlength(df,int2); + refreshrecord(sf,df,akeyfield,keyindex,acancelupdate); +end; +} +function tmsebufdataset.refreshrecord(const sourcedatasets: array of tdataset; + const akeyvalue: array of variant; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +var + int1,int2,int3: integer; + field1,field2: tfield; + sf,df: fieldarty; +begin + int2:= 0; + sf:= nil; //compilerwarning + for int3:= 0 to high(sourcedatasets) do begin + with sourcedatasets[int3] do begin + setlength(sf,length(sf)+fields.count); //max + setlength(df,length(sf)); //max + for int1:= 0 to fields.count-1 do begin + field1:= fields[int1]; + if field1.visible then begin + field2:= self.findfield(field1.fieldname); + if (field2 <> nil) and not field2.readonly then begin + sf[int2]:= field1; + df[int2]:= field2; + inc(int2); + end; + end; + end; + end; + end; + setlength(sf,int2); + setlength(df,int2); + result:= refreshrecord(sf,df,akeyvalue,keyindex,acancelupdate,restorerecno, + noinsert); +end; + +{$ifndef FPC} +function tmsebufdataset.refreshrecordvarar(const sourcedatasets: array of tdataset; + const akeyvalue: array of variant; + const keyindex: integer; + const acancelupdate: boolean; + const restorerecno: boolean; + const noinsert: boolean): bookmarkdataty; +begin + result:= refreshrecord(sourcedatasets,akeyvalue,keyindex,acancelupdate, + restorerecno,noinsert); +end; +{$endif} + +function tmsebufdataset.refreshrecord(const akeyfield: array of tfield; + const keyindex: integer = 0; const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +begin +{$ifdef fpc} + result:= refreshrecord([akeyfield[0].dataset],fieldvariants(akeyfield),keyindex, + acancelupdate,restorerecno,noinsert); +{$else} + result:= refreshrecordvarar([akeyfield[0].dataset],fieldvariants(akeyfield),keyindex, + acancelupdate,restorerecno,noinsert); +{$endif} +end; + +function tmsebufdataset.getindex(const afield: tfield): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to findexlocal.count - 1 do begin + with tlocalindex(findexlocal.fitems[int1]) do begin + if (fields.count > 0) and (high(findexfieldinfos) >= 0) and + (findexfieldinfos[0].fieldinstance = afield) then begin + result:= int1; + break; + end; + end; + end; +end; + +function tmsebufdataset.gettextindex(const afield: tfield; + const acaseinsensitive: boolean): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to findexlocal.count - 1 do begin + with tlocalindex(findexlocal.fitems[int1]) do begin + if (fields.count > 0) and (high(findexfieldinfos) >= 0) and + (findexfieldinfos[0].fieldinstance = afield) and + not (findexfieldinfos[0].caseinsensitive xor + acaseinsensitive) then begin + result:= int1; + break; + end; + end; + end; +end; + +function tmsebufdataset.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +var + int1: integer; +begin + result:= false; + if afield <> nil then begin + for int1:= 0 to findexlocal.count - 1 do begin + with tlocalindex(findexlocal.fitems[int1]) do begin + if (fields.count > 0) and (high(findexfieldinfos) >= 0) and + (findexfieldinfos[0].fieldinstance = afield) then begin + result:= true; + desc:= adescend; + active:= true; + end; + end; + end; + end; + if not result then begin +// findexlocal.activeindex:= -1; + findexlocal.activeindex:= findexlocal.defaultindex; + end; +end; + +procedure tmsebufdataset.setbookmarkdata1(const avalue: bookmarkdataty); +begin + gotobookmark(@avalue); +end; + +function tmsebufdataset.recapplying: boolean; +begin + result:= bs_recapplying in fbstate; +end; + +procedure tmsebufdataset.dropupdates(); +begin + dropupdates1(false); +end; + +function tmsebufdataset.lookuptext(const indexnum: integer; const akey: integer; + const aisnull: boolean; const valuefield: tmsestringfield): msestring; +var + bm1: bookmarkdataty; +begin + result:= ''; + if indexlocal[indexnum].find([akey],[aisnull],bm1,false,false,true) then begin + result:= currentbmasmsestring[valuefield,bm1]; + end; +end; + +function tmsebufdataset.lookuptext(const indexnum: integer; const akey: int64; + const aisnull: boolean; const valuefield: tmsestringfield): msestring; +var + bm1: bookmarkdataty; +begin + result:= ''; + if indexlocal[indexnum].find([akey],[aisnull],bm1,false,false,true) then begin + result:= currentbmasmsestring[valuefield,bm1]; + end; +end; + +function tmsebufdataset.lookuptext(const indexnum: integer; const akey: msestring; + const aisnull: boolean; const valuefield: tmsestringfield): msestring; +var + bm1: bookmarkdataty; +begin + result:= ''; + if indexlocal[indexnum].find([akey],[aisnull],bm1,false,false,true) then begin + result:= currentbmasmsestring[valuefield,bm1]; + end; +end; + +function tmsebufdataset.findtext(const indexnum: integer; const searchtext: msestring; + out arecord: integer): boolean; +var + bm1: bookmarkdataty; +begin + arecord:= -1; + result:= indexlocal[indexnum].find([searchtext],[false],bm1,false,true); + if result then begin + arecord:= bm1.recno; + end; +end; + +function tmsebufdataset.getrowtext(const indexnum: integer; + const arecord: integer; const afield: tfield): msestring; +var + bm1: bookmarkdataty; +begin + if indexnum >= 0 then begin + checkindex(indexnum+1); + end; + bm1.recno:= arecord; + bm1.recordpo:= findexes[indexnum+1].ind[arecord]; + if afield is tmsestringfield then begin + result:= currentbmasmsestring[afield,bm1]; + end + else begin + case afield.datatype of + ftboolean: begin + result:= tmsebooleanfield1(afield).fdisplays[ + false,currentbmasboolean[afield,bm1]]; + end; + ftsmallint,ftword,ftinteger: begin + result:= inttostrmse(currentbmasinteger[afield,bm1]); + end; + ftlargeint: begin + result:= inttostrmse(currentbmasinteger[afield,bm1]); + end; + ftfloat: begin + result:= formatfloatmse(currentbmasfloat[afield,bm1],''); + end; + fttime,ftdate,ftdatetime: begin + result:= tmsedatetimefield1(afield).gettext1( + currentbmasdatetime[afield,bm1],true); + end; + ftbcd: begin + result:= currencytostrmse(currentbmascurrency[afield,bm1]); + end; + else begin + result:= ''; + end; + end; + end; +end; + +function tmsebufdataset.getrowinteger(const indexnum: integer; + const arecord: integer; const afield: tfield): integer; +var + bm1: bookmarkdataty; +begin + if indexnum >= 0 then begin + checkindex(indexnum+1); + end; + bm1.recno:= arecord; + bm1.recordpo:= findexes[indexnum+1].ind[arecord]; + result:= currentbmasinteger[afield,bm1]; +end; + +function tmsebufdataset.getrowlargeint(const indexnum: integer; + const arecord: integer; const afield: tfield): int64; +var + bm1: bookmarkdataty; +begin + if indexnum >= 0 then begin + checkindex(indexnum+1); + end; + bm1.recno:= arecord; + bm1.recordpo:= findexes[indexnum+1].ind[arecord]; + result:= currentbmaslargeint[afield,bm1]; +end; + +procedure CalcLookupValue(const afield: tfield); +begin + with afield do begin + if LookupCache then begin + Value:= LookupList.ValueOfKey(DataSet.FieldValues[KeyFields]) + end + else begin + if Assigned(LookupDataSet) and DataSet.Active then begin + Value:= LookupDataSet.Lookup(LookupKeyfields, + DataSet.FieldValues[KeyFields], LookupresultField); + end; + end; + end; +end; + +procedure tmsebufdataset.CalculateFields(Buffer: PChar); +var + i: Integer; + field1: tfield; + bm1: bookmarkdataty; + state1: tdatasetstate; +begin + FCalcBuffer1:= Buffer; + if not IsUniDirectional and (State <> dsInternalCalc) then begin + state1:= settempstate(dscalcfields); + try + ClearCalcFields(FCalcBuffer1); + for i := 0 to Fields.Count - 1 do begin + field1:= fields[i]; + if (field1.FieldKind = fkLookup) and + (field1.lookupdataset <> nil) then begin + with flookupfieldinfos[-1-field1.fieldno] do begin + if indexnum >= 0 then begin + with tmsebufdataset(field1.lookupdataset) do begin + if active and + indexlocal[indexnum].find(keyfieldar,bm1,false,false,true) then begin + //no checkbrowsemode + currentbmassign(lookupvaluefield,field1,bm1); + end + else begin + field1.clear; + end; + end; + end + else begin + CalcLookupValue(field1); + end; + end; + end; + end; + DoOnCalcFields; + finally + restorestate(state1); + end; + end; +end; + +procedure tmsebufdataset.notification(acomponent: tcomponent; + operation: toperation); +var + i1: int32; +begin + inherited; + if not (csdestroying in componentstate) and (operation = opremove) then begin + for i1:= 0 to high(flookupfieldinfos) do begin + if acomponent = flookupfieldinfos[i1].lookupvaluefield then begin + active:= false; + break; + end; + end; + end; +end; + +procedure tmsebufdataset.begindisplaydata; +begin + include(fbstate,bs_displaydata); +end; + +procedure tmsebufdataset.enddisplaydata; +begin + exclude(fbstate,bs_displaydata); +end; + +function tmsebufdataset.getsavepointoptions(): savepointoptionsty; +begin + result:= []; + if bdo_postsavepoint in foptions then begin + include(result,spo_postsavepoint); + end; + if bdo_deletesavepoint in foptions then begin + include(result,spo_deletesavepoint); + end; +end; + +function tmsebufdataset.getdata(const afields: array of tfield): variantararty; +var + ar1: fieldarty; + int1,int2: integer; + po1: pvariantaty; +begin + checkbrowsemode; + ar1:= getdsfields(self,afields); + try + setlength(result,recordcount); + for int1:= 0 to high(result) do begin + setlength(result[int1],length(ar1)); + po1:= pointer(result[int1]); + for int2:= 0 to high(ar1) do begin + po1^[int2]:= currentasvariant[ar1[int2],int1]; + end; + end; + except + result:= nil; + raise; + end; +end; + +procedure tmsebufdataset.post; +begin +{ + if (bs1_posting in fbstate1) and (state in [dsedit,dsinsert]) then begin + databaseerror('Recursive post.',self); + end; +} + if not (bs1_posting in fbstate1) then begin + include(fbstate1,bs1_posting); + try + inherited; + finally + exclude(fbstate1,bs1_posting); + end; + end; +end; +{ +procedure tmsebufdataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin +end; +} +procedure tmsebufdataset.savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); +begin + if (bs1_restoreupdate in fbstate1) and active and + ((sender = ftransactionwrite) or + (ftransactionwrite = nil) and (sender = ftransaction)) then begin + case akind of + spek_begin: begin + if fsavepointlevel < 0 then begin + fsavepointlevel:= alevel; + include(fbstate1,bs1_deferdeleterecupdatebuffer); + end; + end; + else begin + if alevel <= fsavepointlevel then begin + fsavepointlevel:= -1; + exclude(fbstate1,bs1_deferdeleterecupdatebuffer); + if akind in [spek_release,spek_committrans] then begin + postrecupdatebuffer; + end + else begin + restorerecupdatebuffer; + end; + end; + end; + end; + end; +end; + +function tmsebufdataset.getchangerecords: recupdateinfoarty; +var + int1,int2: integer; +begin + setlength(result,length(fupdatebuffer)); + int2:= 0; + for int1:= 0 to high(result) do begin + with fupdatebuffer[int1] do begin + if (info.bookmark.recordpo <> nil) and + not (ruf_applied in info.flags) then begin + result[int2]:= info; + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +function tmsebufdataset.getapplyerrorrecords: recupdateinfoarty; +var + int1,int2: integer; +begin + setlength(result,length(fupdatebuffer)); + int2:= 0; + for int1:= 0 to high(result) do begin + with fupdatebuffer[int1] do begin + if (info.bookmark.recordpo <> nil) and + (info.flags*[ruf_applied,ruf_error] = [ruf_error]) then begin + result[int2]:= info; + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +procedure tmsebufdataset.setcryptohandler(const avalue: tcustomcryptohandler); +begin + getobjectlinker.setlinkedvar(iobjectlink(self),avalue, + tmsecomponent(fcryptohandler)); +end; + +procedure tmsebufdataset.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +function tmsebufdataset.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(iobjectlink(self),{$ifdef FPC}@{$endif}objectevent, + fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tmsebufdataset.link(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tmsebufdataset.unlink(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tmsebufdataset.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tmsebufdataset.getinstance: tobject; +begin + result:= self; +end; + +function tmsebufdataset.getcomponent: tcomponent; +begin + result:= self; +end; + +function tmsebufdataset.recnobookmark( + const arecnozerobased: int32): bookmarkdataty; +begin + checkrecno(arecnozerobased+1); + result.recno:= arecnozerobased; + result.recordpo:= factindexpo^.ind[arecnozerobased]; +end; + +{ tlocalindexes } + +constructor tlocalindexes.create(const aowner: tmsebufdataset); +begin + inherited create(aowner,tlocalindex); +end; + +class function tlocalindexes.getitemclasstype: persistentclassty; +begin + result:= tlocalindex; +end; + +function tlocalindexes.getitems(const index: integer): tlocalindex; +begin + result:= tlocalindex(inherited items[index]); +end; + +procedure tlocalindexes.checkinactive; +begin + if tmsebufdataset(fowner).active then begin + databaseerror(SActiveDataset,tmsebufdataset(fowner)); + end; +end; + +procedure tlocalindexes.setcount1(acount: integer; doinit: boolean); +begin + checkinactive; + inherited; + if not (aps_destroying in fstate) then begin + tmsebufdataset(fowner).updatestate; + end; +end; + +procedure tlocalindexes.bindfields; +var + int1: integer; +begin + for int1:= count - 1 downto 0 do begin + items[int1].bindfields; + end; +end; + +procedure tlocalindexes.move(const curindex: integer; const newindex: integer); +begin + checkinactive; + inherited; +end; + +function tlocalindexes.getactiveindex: integer; +begin + result:= tmsebufdataset(fowner).actindex - 1; +end; + +procedure tlocalindexes.setactiveindex(const avalue: integer); +begin + if avalue < 0 then begin + tmsebufdataset(fowner).actindex:= 0; + end + else begin + items[avalue].active:= true; + end; +end; + +function tlocalindexes.fieldactive(const afield: tfield): boolean; +var + int1: integer; +begin + result:= tmsebufdataset(fowner).factindex > 0; + if result and (afield <> nil) then begin + result:= false; + with items[tmsebufdataset(fowner).factindex-1] do begin + for int1:= 0 to high(findexfieldinfos) do begin + if findexfieldinfos[int1].fieldinstance = afield then begin + result:= true; + break; + end; + end; + end; + end; +end; + +function tlocalindexes.hasfield(const afield: tfield): boolean; +var + int1,int2: integer; +begin + result:= false; + for int2:= 0 to high(fitems) do begin + with items[int2] do begin + for int1:= 0 to high(findexfieldinfos) do begin + if findexfieldinfos[int1].fieldinstance = afield then begin + result:= true; + break; + end; + end; + end; + if result then begin + break; + end; + end; +end; + +function tlocalindexes.fieldmodified(const afield: tfield; + const delayed: boolean): boolean; +var + int1,int2: integer; +begin + result:= false; + for int1:= 0 to count-1 do begin + with tlocalindex(fitems[int1]) do begin + for int2:= 0 to high(findexfieldinfos) do begin + if (afield = nil) or + (findexfieldinfos[int2].fieldinstance = afield) then begin + result:= true; + if delayed then begin + finvalid:= true; + end + else begin + with tmsebufdataset(fowner) do begin + findexes[int1+1].ind:= nil; +// exclude(tmsebufdataset(fowner).fbstate,bs_indexvalid); + end; + end; + end; + break; + end; + end; + end; +end; + +procedure tlocalindexes.preparefixup; +var + int1: integer; +begin + for int1:= 0 to count-1 do begin + with tlocalindex(fitems[int1]) do begin + if finvalid then begin + finvalid:= false; + with tmsebufdataset(fowner) do begin + findexes[int1+1].ind:= nil; +// exclude(fbstate,bs_indexvalid); + end; + end; + end; + end; +end; + +procedure tlocalindexes.doindexchanged; +begin + if checkcanevent(tmsebufdataset(fowner), + tmethod(fonindexchanged)) then begin + fonindexchanged(tmsebufdataset(fowner)); + end; +end; + +function tlocalindexes.getdefaultindex: integer; +var + int1: integer; +begin + result:= -1; + for int1:= high(fitems) downto 0 do begin + if lio_default in tlocalindex(fitems[int1]).foptions then begin + result:= int1; + break; + end; + end; +end; + +procedure tlocalindexes.setdefaultindex(const avalue: integer); +var + int1: integer; +begin + if avalue < 0 then begin + int1:= defaultindex; + if int1 >= 0 then begin + tlocalindex(fitems[int1]).default:= false; + end + else begin + tlocalindex(fitems[avalue]).default:= true; + end; + end; +end; + +function tlocalindexes.indexbyname(const aname: string): tlocalindex; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fitems) do begin + if tlocalindex(fitems[int1]).name = aname then begin + result:= tlocalindex(fitems[int1]); + end; + end; +end; + +{ tlocalindex } + +constructor tlocalindex.create(aowner: tobject); +begin + ffields:= tindexfields.create(self); + inherited; +end; + +destructor tlocalindex.destroy; +begin + ffields.free; + inherited; +end; + +procedure tlocalindex.setfields(const avalue: tindexfields); +begin + ffields.assign(avalue); +end; + +procedure tlocalindex.change; +var + int1: integer; +begin + with tmsebufdataset(fowner) do begin + if fopen then begin + self.bindfields; + int1:= findexlocal.indexof(self) + 1; + with findexes[int1] do begin + if ind <> nil then begin + if factindex = int1 then begin + checkbrowsemode; + end; + ind:= nil; +// exclude(fbstate,bs_indexvalid); + if factindex = int1 then begin + internalsetrecno(findrecord(fcurrentbuf)); + resync([]); + findexlocal.doindexchanged; + end; + end; + end; + end; + end; +end; + +procedure tlocalindex.setoptions(const avalue: localindexoptionsty); +var + bo1: boolean; + int1: integer; +begin + if foptions <> avalue then begin + bo1:= lio_default in foptions; + foptions:= avalue; + if not bo1 and (lio_default in foptions) then begin + with tmsebufdataset(fowner).findexlocal do begin + for int1:= 0 to high(fitems) do begin + exclude(tlocalindex(fitems[int1]).foptions,lio_default); + end; + end; + include(foptions,lio_default); + end; + change; + end; +end; + +procedure lookup1(const afield: tfield; const apo: pintrecordty; + var adata: lookupdataty); +var + bm1: bookmarkdataty; + po1: pintrecordty; +begin + adata.po:= nil; + with tmsebufdataset(afield.dataset) do begin + flookuppo:= apo; + with flookupfieldinfos[-1-afield.fieldno] do begin + with tmsebufdataset(afield.lookupdataset) do begin + if active then begin + if indexlocal[indexnum].find(keyfieldar,bm1,false,false,true) then begin + if lookupvaluefield.fieldno > 0 then begin + getvalue(lookupvaluefield,bm1,adata); + end + else begin + if lookupvaluefield.lookupdataset is tmsebufdataset then begin + with tmsebufdataset(lookupvaluefield.dataset) do begin + if active then begin + po1:= flookuppo; + try + lookup1(lookupvaluefield,bm1.recordpo,adata); + finally + flookuppo:= po1; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tlocalindex.dolookupcompare(const l,r: pintrecordty; + const ainfo: indexfieldinfoty; const apartialstring: boolean): integer; + +var + ldata,rdata: lookupdataty; + +begin + result:= 0; + with tmsebufdataset(ainfo.fieldinstance.lookupdataset) do begin + if active then begin + try + lookup1(ainfo.fieldinstance,l,ldata); + lookup1(ainfo.fieldinstance,r,rdata); + finally + tmsebufdataset(self.fowner).flookuppo:= nil; + end; + if ldata.po = nil then begin + if rdata.po = nil then begin + exit; + end + else begin + dec(result); + end; + end + else begin + if rdata.po = nil then begin + inc(result); + end + else begin + result:= ainfo.comparefunc(ldata.po^,rdata.po^); + if (result <> 0) and apartialstring then begin + if ainfo.caseinsensitive then begin + result:= msepartialcomparetext(ldata.mstr,rdata.mstr); + end + else begin + result:= msepartialcomparestr(ldata.mstr,rdata.mstr); + end; + end; + end; + end; + end; + end; +end; + +function tlocalindex.dolookupcomparea(const lvalue: pointer; r: pintrecordty; + const ainfo: indexfieldinfoty; const apartialstring: boolean): integer; + //l is compare value, r can be lookup +var + {ldata,}rdata: lookupdataty; + +begin + result:= 0; + with tmsebufdataset(ainfo.fieldinstance.lookupdataset) do begin + if active then begin + try +// lookup1(ainfo.fieldinstance,l,ldata); + lookup1(ainfo.fieldinstance,r,rdata); + finally + tmsebufdataset(self.fowner).flookuppo:= nil; + end; + if lvalue = nil then begin + if rdata.po = nil then begin + exit; + end + else begin + dec(result); + end; + end + else begin + if rdata.po = nil then begin + inc(result); + end + else begin + result:= ainfo.comparefunc(lvalue^,rdata.po^); + if (result <> 0) and apartialstring then begin + if ainfo.caseinsensitive then begin + result:= msepartialcomparetext(pmsestring(lvalue)^,rdata.mstr); + end + else begin + result:= msepartialcomparestr(pmsestring(lvalue)^,rdata.mstr); + end; + end; + end; + end; + end; + end; +end; + +function tlocalindex.compare1(l,r: pintrecordty; const alastindex: integer; + const apartialstring: boolean): integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to alastindex do begin + with findexfieldinfos[int1] do begin + if islookup then begin + result:= dolookupcompare(l,r,findexfieldinfos[int1], + apartialstring and canpartialstring and (int1 = alastindex)); + if desc then begin + result:= -result; + end; + if result <> 0 then begin + break; + end; + end + else begin + if not getfieldflag(@l^.header.fielddata.nullmask,fieldindex) then begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + continue; + end + else begin + dec(result); + end; + end + else begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + inc(result); + end + else begin + result:= comparefunc((pchar(l)+recoffset)^,(pchar(r)+recoffset)^); + end; + end; + if (result <> 0) then begin + if apartialstring and canpartialstring and (int1 = alastindex) then begin + if caseinsensitive then begin + result:= msepartialcomparetext(pmsestring(pointer(pchar(l)+recoffset))^, + pmsestring(pointer(pchar(r)+recoffset))^); + end + else begin + result:= msepartialcomparestr(pmsestring(pointer(pchar(l)+recoffset))^, + pmsestring(pointer(pchar(r)+recoffset))^); + end; + end; + if desc then begin + result:= -result; + end; + break; + end; + end; + end; + end; + if lio_desc in foptions then begin + result:= -result; + end; +end; + +function tlocalindex.compare1a(l,r: pintrecordty; const alastindex: integer; + const apartialstring: boolean): integer; + //l is compare value, r can be lookup +var + int1: integer; + po1: pointer; +begin + result:= 0; + for int1:= 0 to alastindex do begin + with findexfieldinfos[int1] do begin + if islookup then begin + po1:= nil; + if getfieldflag(pointer(l)+tmsebufdataset(fowner).frecordsize, + -2-fieldindex) then begin + po1:= pointer(l) + recoffset; + end; + result:= dolookupcomparea(po1,r,findexfieldinfos[int1], + apartialstring and canpartialstring and (int1 = alastindex)); + if desc then begin + result:= -result; + end; + if result <> 0 then begin + break; + end; + end + else begin + if not getfieldflag(@l^.header.fielddata.nullmask,fieldindex) then begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + continue; + end + else begin + dec(result); + end; + end + else begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + inc(result); + end + else begin + result:= comparefunc((pchar(l)+recoffset)^,(pchar(r)+recoffset)^); + end; + end; + if (result <> 0) then begin + if apartialstring and canpartialstring and (int1 = alastindex) then begin + if caseinsensitive then begin + result:= msepartialcomparetext(pmsestring(pointer(pchar(l)+recoffset))^, + pmsestring(pointer(pchar(r)+recoffset))^); + end + else begin + result:= msepartialcomparestr(pmsestring(pointer(pchar(l)+recoffset))^, + pmsestring(pointer(pchar(r)+recoffset))^); + end; + end; + if desc then begin + result:= -result; + end; + break; + end; + end; + end; + end; + if lio_desc in foptions then begin + result:= -result; + end; +end; + +function tlocalindex.compare2(l,r: pintrecordty): integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(findexfieldinfos) do begin + with findexfieldinfos[int1] do begin + if islookup then begin + result:= dolookupcompare(l,r,findexfieldinfos[int1],false); + if desc then begin + result:= -result; + end; + if result <> 0 then begin + break; + end; + end + else begin + if not getfieldflag(@l^.header.fielddata.nullmask,fieldindex) then begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + continue; + end + else begin + dec(result); + end; + end + else begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + inc(result); + end + else begin + result:= comparefunc((pchar(l)+recoffset)^,(pchar(r)+recoffset)^); + end; + end; + if desc then begin + result:= -result; + end; + if result <> 0 then begin + break; + end; + end; + end; + end; + if lio_desc in foptions then begin + result:= -result; + end; +end; + +{$ifndef FPC} +function tlocalindex.compare3(l,r: pointer): integer; +begin + result:= compare2(l,r); +end; +{$endif} + +procedure tlocalindex.quicksort(l,r: integer); +var + i,j: integer; + p: integer; +// int1: integer; + po1: pintrecordty; +begin + repeat + i:= l; + j:= r; + p:= (l + r) shr 1; + repeat + while compare2(fsortarray^[i],fsortarray^[p]) < 0 do begin + inc(i); + end; + while compare2(fsortarray^[j],fsortarray^[p]) > 0 do begin + dec(j); + end; + if i <= j then begin + po1:= fsortarray^[i]; + fsortarray^[i]:= fsortarray^[j]; + fsortarray^[j]:= po1; + if p = i then begin + p:= j + end + else begin + if p = j then begin + p:= i; + end; + end; + inc(i); + dec(j); + end; + until i > j; + if l < j then begin + quicksort(l,j); + end; + l:= i; + until i >= r; +end; + +procedure tlocalindex.sort(var adata: pointerarty); +{$ifdef mse_debugdataset} +var + ts1: longword; +{$endif} +begin + if adata <> nil then begin +{$ifdef mse_debugdataset} + ts1:= timestamp; +{$endif} + if lio_quicksort in foptions then begin + fsortarray:= @adata[0]; + quicksort(0,tmsebufdataset(fowner).fbrecordcount - 1); + end + else begin + msearrayutils.mergesort(adata,tmsebufdataset(fowner).fbrecordcount, + {$ifdef FPC} + pointercomparemethodty(@compare2)); + {$else} + compare3); + {$endif} +// mergesort(adata); + end; + end; +{$ifdef mse_debugdataset} + debugoutend(ts1,tmsebufdataset(fowner),'Sort index '+ + inttostr(tmsebufdataset(fowner).findexlocal.indexof(self))); +{$endif} +end; + +function tlocalindex.findboundary(const comparefunc: indexcomparefuncty; + const arecord: pintrecordty; + const alastindex: integer; const abigger: boolean): integer; + //returns index of next bigger +var + int1: integer; + lo,up,pivot: integer; +begin + result:= 0; + with tmsebufdataset(fowner) do begin + int1:= findexlocal.indexof(self) + 1; + with findexes[int1] do begin + if fbrecordcount > 0 then begin + checkindex(int1); + int1:= 0; + lo:= 0; + up:= fbrecordcount - 1; + if abigger then begin + while lo <= up do begin + pivot:= (up + lo) div 2; + int1:= comparefunc(arecord,ind[pivot],alastindex,false); + if int1 >= 0 then begin //pivot <= rev + lo:= pivot + 1; + end + else begin + up:= pivot; + if up = lo then begin + break; + end; + end; + end; + result:= lo; + end + else begin + while lo <= up do begin + pivot:= (up + lo + 1) div 2; + int1:= comparefunc(arecord,ind[pivot],alastindex,false); + if int1 <= 0 then begin //pivot >= rev + up:= pivot - 1; + end + else begin + lo:= pivot; + if up = lo then begin + break; + end; + end; + end; + result:= up; + end; + end; + end; + end; +end; + +function tlocalindex.findrecord(const arecord: pintrecordty): integer; +var + int1: integer; + po1: ppointeraty; +begin + result:= -1; + int1:= findboundary(@compare1,arecord,high(findexfieldinfos),true) - 1; + with tmsebufdataset(fowner) do begin + po1:= pointer(findexes[findexlocal.indexof(self) + 1].ind); + end; + for int1:= int1 downto 0 do begin + if po1^[int1] = arecord then begin + result:= int1; + break; + end; + end; +end; + +function tlocalindex.getactive: boolean; +begin + with tmsebufdataset(fowner) do begin + result:= actindex = findexlocal.indexof(self) + 1; + end; +end; + +procedure tlocalindex.setactive(const avalue: boolean); +var + int1: integer; +begin + with tmsebufdataset(fowner) do begin + int1:= findexlocal.indexof(self) + 1; + if avalue then begin + if actindex <> int1 then begin + actindex:= int1; + tmsebufdataset(fowner).findexlocal.doindexchanged; + end; + end + else begin + if actindex = int1 then begin + actindex:= 0; + tmsebufdataset(fowner).findexlocal.doindexchanged; + end; + end; + end; +end; + +procedure tlocalindex.bindfields; +var + int1: integer; + field1: tfield; + kind1: fieldcomparekindty; +begin + setlength(findexfieldinfos,ffields.count); + fhaslookup:= false; + with tmsebufdataset(fowner) do begin + for int1:= 0 to high(findexfieldinfos) do begin + with ffields.items[int1],findexfieldinfos[int1] do begin + field1:= findfield(fieldname); + if field1 = nil then begin + databaseerror('Index field "'+fieldname+'" not found.', + tmsebufdataset(self.fowner)); + end; + fieldinstance:= field1; + with field1 do begin + if not((fieldkind in [fkdata,fkinternalcalc]) or + (fieldkind = fklookup) and + (flookupfieldinfos[-1-fieldno].indexnum >= 0)) or + not (datatype in indexfieldtypes) then begin + databaseerror('Invalid index field "'+fieldname+'".', + tmsebufdataset(self.fowner)); + end; + islookup:= fieldkind = fklookup; + fhaslookup:= fhaslookup or islookup; + for kind1:= low(fieldcomparekindty) to high(fieldcomparekindty) do begin + with comparefuncs[kind1] do begin + if datatype in datatypes then begin + vtype:= cvtype; + if ifo_caseinsensitive in options then begin + if ifo_natural in options then begin + comparefunc:= compfuncin; + end + else begin + comparefunc:= compfunci; + end; + end + else begin + if ifo_natural in options then begin + comparefunc:= compfuncn; + end + else begin + comparefunc:= compfunc; + end; + end; + break; + end; + end; + end; + fieldindex:= fieldno - 1; + if fieldindex >= 0 then begin + recoffset:= ffieldinfos[fieldindex].base.offset + intheadersize; + end + else begin + recoffset:= offset; //calc field + flookupfieldinfos[-2-fieldindex].hasindex:= true; + end; + desc:= ifo_desc in foptions; + caseinsensitive:= ifo_caseinsensitive in foptions; + canpartialstring:= vtype = {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}; + end; + end; + end; + end; +end; + +procedure paramerror(const amessage: msestring = ''); +var + mstr1: msestring; +begin + mstr1:= 'Invalid find parameters.'; + if amessage <> '' then begin + mstr1:= mstr1 + lineend+amessage; + end; + databaseerror(ansistring(mstr1)); +end; + +function tlocalindex.find(const avalues: array of const; + const aisnull: array of boolean; out abookmark: bookmarkdataty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; +var + int1: integer; +// v: tvarrec; + po1: pintrecordty; + po2: pointer; + bo1: boolean; + lastind: integer; + calcfieldpo: pointer; + b1,b2: boolean; + state1: tdatasetstate; + +label + endlab; +begin + if not nocheckbrowsemode and ([bs1_posting,bs1_recordupdating] * + tmsebufdataset(fowner).fbstate1 = []) then begin + tmsebufdataset(fowner).checkbrowsemode; + end; + lastind:= high(avalues); + if lastind > high(findexfieldinfos) then begin + paramerror; + end; + for int1:= lastind downto 0 do begin + if (avalues[int1].vtype <> vtpointer) and + (avalues[int1].vtype <> findexfieldinfos[int1].vtype) then begin + paramerror(msestring(tmsebufdataset(fowner).name)+ + 'field '+ msestring(findexfieldinfos[int1].fieldinstance.fieldname)+ + ' wanted vtype: '+ inttostrmse(findexfieldinfos[int1].vtype)+ + ' actual vtype: '+ inttostrmse(avalues[int1].vtype)); + end; + end; +// po1:= tmsebufdataset(fowner).intallocrecord; + po1:= allocmem(tmsebufdataset(fowner).fcalcrecordsize+intheadersize); + calcfieldpo:= pointer(po1) + tmsebufdataset(fowner).frecordsize; + b1:= false; + try + for int1:= lastind downto 0 do begin + with findexfieldinfos[int1],avalues[int1] do begin + po2:= pchar(po1) + recoffset; + bo1:= false; + case vtype of + vtinteger: begin + pinteger(po2)^:= vinteger; + end; + {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}: begin + ppointer(po2)^:= {$ifdef mse_hasvtunicodestring}vunicodestring + {$else}vwidestring{$endif}; + end; + vtextended: begin + pdouble(po2)^:= vextended^; + bo1:= pdouble(po2)^ = emptyreal; + end; + vtcurrency: begin + pcurrency(po2)^:= vcurrency^; + end; + vtboolean: begin + pwordbool(po2)^:= vboolean; + end; + vtint64: begin + pint64(po2)^:= vint64^; + end; + vtpointer: begin + bo1:= true; + end; + mse_vtguid: begin + pguid(po2)^:= pguid(vpointer)^; + end; + else begin + paramerror; + end; + end; + if int1 <= high(aisnull) then begin + bo1:= bo1 or aisnull[int1]; + end; + if fieldindex < 0 then begin //calcfields + if not bo1 then begin + setfieldflag(calcfieldpo,-2-fieldindex); + end + else begin + clearfieldflag(calcfieldpo,-2-fieldindex); + //buffer is not initialised + end; + end + else begin + if not bo1 then begin + setfieldflag(@po1^.header.fielddata.nullmask,fieldindex); + end + else begin + clearfieldflag(@po1^.header.fielddata.nullmask,fieldindex); + //buffer is not initialised + end; + end; + end; + end; + int1:= findboundary(@compare1a,po1,lastind,abigger); + result:= false; + abookmark.recordpo:= nil; + abookmark.recno:= -1; + b1:= filtered; + with tmsebufdataset(fowner) do begin + b1:= b1 and filtered and assigned(fonfilterrecord); + if b1 then begin + state1:= settempstate(tdatasetstate(dscheckfilter)); + end; + with findexes[findexlocal.indexof(self) + 1] do begin + if abigger then begin + if int1 < 0 then begin + goto endlab; + end; + if b1 then begin + dec(int1); + b2:= false; + while int1 >= 0 do begin //find next filtered record + if compare1a(po1,ind[int1],lastind,partialstring) <> 0 then begin + break; + end; + fcheckfilterbuffer:= ind[int1] - sizeof(dsheaderty); + b2:= true; + onfilterrecord(tmsebufdataset(fowner),b2); + if b2 then begin + break; + end; + dec(int1); + end; + inc(int1); + if not b2 then begin //no exact found + while int1 < fbrecordcount do begin + fcheckfilterbuffer:= ind[int1] - sizeof(dsheaderty); + b2:= true; + onfilterrecord(tmsebufdataset(fowner),b2); + if b2 then begin + break; + end; + inc(int1); + end; + end; + if not b2 then begin + goto endlab; //no bigger found + end; + end; + if (int1 > 0) and (compare1a(po1,ind[int1-1],lastind,false) = 0) then begin + result:= true; + dec(int1); + end; + end + else begin + if b1 then begin + inc(int1); + b2:= false; + while int1 < fbrecordcount do begin //find next filtered record + if compare1a(po1,ind[int1],lastind,partialstring) <> 0 then begin + break; + end; + fcheckfilterbuffer:= ind[int1] - sizeof(dsheaderty); + b2:= true; + onfilterrecord(tmsebufdataset(fowner),b2); + if b2 then begin + break; + end; + inc(int1); + end; + dec(int1); + if not b2 then begin //no exact found + while int1 >= 0 do begin + fcheckfilterbuffer:= ind[int1] - sizeof(dsheaderty); + b2:= true; + onfilterrecord(tmsebufdataset(fowner),b2); + if b2 then begin + break; + end; + dec(int1); + end; + end; + if not b2 then begin + goto endlab; //no lower found + end; + end; + if int1 >= fbrecordcount - 1 then begin + if partialstring and (int1 > 0) and (int1 = fbrecordcount - 1) then begin + result:= compare1a(po1,ind[int1],lastind,true) = 0; + end; + if not result then begin + goto endlab; + end; + end; + if not result then begin + if compare1a(po1,ind[int1+1],lastind,false) = 0 then begin + result:= true; + inc(int1); + end; + end; + end; + if (int1 >= -1) and (int1 < fbrecordcount) then begin + if not result then begin + if partialstring then begin + if int1 >= 0 then begin + result:= compare1a(po1,ind[int1],lastind,true) = 0; + end; + if not result then begin + inc(int1); + if (int1 >= fbrecordcount) or + (compare1a(po1,ind[int1],lastind,true) <> 0) then begin + dec(int1,2); //for reversed order + if (int1 < 0) or + (compare1a(po1,ind[int1],lastind,true) <> 0) then begin + dec(int1); + if (int1 < 0) or + (compare1a(po1,ind[int1],lastind,true) <> 0) then begin + inc(int1,2); + end + else begin + result:= true; + end; + end + else begin + result:= true; + end; + end + else begin + result:= true; + end; + end; + end + else begin + if int1 < 0 then begin + goto endlab; + end; + end; + end; + b2:= true; + if b1 then begin + fcheckfilterbuffer:= ind[int1] - sizeof(dsheaderty); + onfilterrecord(tmsebufdataset(fowner),b2); + result:= result and b2; + end; + if b2 then begin + abookmark.recno:= int1; + abookmark.recordpo:= ind[int1]; + end; + end; + end; + end; +endlab: + finally + if b1 then begin + tmsebufdataset(fowner).restorestate(state1); + end; + freemem(po1); + end; +end; + +{$ifndef FPC} +function tlocalindex.findval(const avalues: array of const; + const aisnull: array of boolean; out abookmark: bookmarkdataty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false): boolean; +begin + result:= find(avalues,aisnull,abookmark,abigger,partialstring,nocheckbrowsemode); +end; +{$endif} + +function tlocalindex.find(const avalues: array of const; const aisnull: array of boolean; + //itemcount of avalues can be smaller than fields count in index + out abookmark: string; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + //string values must be msestring +var + bm1: bookmarkdataty; +begin + result:= find(avalues,aisnull,bm1,abigger,partialstring, + nocheckbrowsemode,filtered); + abookmark:= tmsebufdataset(fowner).bookmarkdatatobookmark(bm1); +end; + +function tlocalindex.find(const avalues: array of const; + const aisnull: array of boolean; + const abigger: boolean = false; const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; + //sets dataset cursor if found +var + str1: string; +begin + result:= find(avalues,aisnull,str1,abigger,partialstring, + nocheckbrowsemode,filtered); + if result or not exact then begin + tmsebufdataset(fowner).bookmark:= str1; + end; +end; + +function tlocalindex.find(const avalues: array of tfield; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; + //sets dataset cursor if found +var + str1: string; +begin + result:= find(avalues,str1,abigger,partialstring, + nocheckbrowsemode,filtered); + if result or not exact then begin + tmsebufdataset(fowner).bookmark:= str1; + end; +end; + +function tlocalindex.findvariant(const avalue: array of variant; + //nil -> NULL field + //itemcount of avalues + //can be smaller than fields count in index + //itemcount of aisnull can be smaller than itemcount of avalues + out abookmark: string; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + //string values must be msestring +var + int1: integer; + vt1: tvartype; + ar1: array of tvarrec; + ar2: msestringarty; + ar3: array of extended; +begin + setlength(ar1,length(avalue)); + setlength(ar2,length(avalue)); + setlength(ar3,length(avalue)); + for int1:= 0 to high(avalue) do begin + with ar1[int1] do begin + if varisnull(avalue[int1]) then begin + vtype:= vtpointer; + // result:= find([nil],[],abigger,partialstring,nocheckbrowsemode); + end + else begin + vt1:= vartype(avalue[int1]); + if vt1 in ordinalvartypes then begin + if vt1 = varint64 then begin + vtype:= vtint64; + vint64:= @tvardata(avalue[int1]).vint64; + end + else begin + if vt1 = varboolean then begin + vtype:= vtboolean; + vboolean:= avalue[int1]; + end + else begin + vtype:= vtinteger; + vinteger:= avalue[int1]; + end; + end; + end + else begin + case vt1 of + varcurrency: begin + vtype:= vtcurrency; + vcurrency:= @tvardata(avalue[int1]).vcurrency; + end; + varsingle,vardouble,vardate: begin + vtype:= vtextended; + ar3[int1]:= avalue[int1]; + vextended:= @ar3[int1]; + end; + varstring,varolestr: begin + vtype:= {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}; + ar2[int1]:= avalue[int1]; + {$ifdef mse_hasvtunicodestring}vunicodestring + {$else}vwidestring{$endif}:= pointer(ar2[int1]); + end + else begin + paramerror; + end; + end; + end; + end; + end; + end; + result:= find(ar1,[],abookmark,abigger,partialstring, + nocheckbrowsemode,filtered); +end; + +function tlocalindex.findvariant(const avalue: array of variant; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; + //sets dataset cursor if found +var + str1: string; +begin + result:= findvariant(avalue,str1,abigger,partialstring, + nocheckbrowsemode,filtered); + if result or not exact then begin + tmsebufdataset(fowner).bookmark:= str1; //ignores '' + end; +end; + +function tlocalindex.find(const avalues: array of tfield; + out abookmark: bookmarkdataty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found +var + mstr1: msestring; + str1: string; + consts1: array of tvarrec; + isnull1: array of boolean; + field1: tfield; + int1: integer; + rea1: extended; + cur1: currency; + lint1: int64; + id1: tguid; + +begin + setlength(consts1,length(avalues)); + setlength(isnull1,length(avalues)); + for int1:= 0 to high(avalues) do begin + field1:= avalues[int1]; + with field1,consts1[int1] do begin + if isnull then begin + isnull1[int1]:= true; + end; + if field1 is tmsestringfield then begin + mstr1:= tmsestringfield(field1).asmsestring; + vtype:= {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}; + {$ifdef mse_hasvtunicodestring}vunicodestring + {$else}vwidestring{$endif}:= pointer(mstr1); + end + else begin + case datatype of + ftString,ftFixedChar,ftmemo,ftblob: begin + str1:= asstring; + vtype:= vtansistring; + vansistring:= pointer(str1); + end; + ftSmallint,ftInteger,ftWord: begin + vtype:= vinteger; + vinteger:= asinteger; + end; + ftBoolean: begin + vboolean:= asboolean; + vtype:= vtboolean + end; + ftFloat,ftcurrency,ftDate,ftTime,ftDateTime,ftTimeStamp,ftFMTBcd: begin + rea1:= asfloat; + vtype:= vtextended; + vextended:= @rea1; + end; + ftBCD: begin + cur1:= ascurrency; + vtype:= vtcurrency; + vcurrency:= @cur1; + end; + ftguid: begin + id1:= asguid; + vtype:= mse_vtguid; + vpointer:= @id1; + end; + ftWideString: begin + mstr1:= aswidestring; + vtype:= {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}; + {$ifdef mse_hasvtunicodestring}vunicodestring + {$else}vwidestring{$endif}:= pointer(mstr1); + end; + ftLargeint: begin + lint1:= aslargeint; + vtype:= vtint64; + vint64:= @lint1; + end; + end; + end; + end; + end; + result:= find(consts1,isnull1,abookmark,abigger,partialstring, + nocheckbrowsemode,filtered); +end; + +function tlocalindex.find(const avalues: array of tfield; + out abookmark: string; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found +var + bm: bookmarkdataty; +begin + result:= find(avalues,bm,abigger,partialstring,nocheckbrowsemode,filtered); + abookmark:= tmsebufdataset(fowner).bookmarkdatatobookmark(bm); +end; + +function tlocalindex.unique(const avalues: array of const): boolean; +var + bm1: bookmarkdataty; +begin + result:= not find(avalues,[],bm1,false,false,true) or + (bm1.recordpo = tmsebufdataset(fowner).bookmarkdata.recordpo); +end; + +procedure tlocalindex.deleteduplicates(); +var + i1,i2: int32; + po1,po2: pointer; + ar1: pointerarty; +begin + with tmsebufdataset(fowner) do begin + checkbrowsemode(); + disablecontrols(); + try + i1:= findexlocal.indexof(self) + 1; + checkindex(i1); + ar1:= findexes[i1].ind; + i2:= 1; + while i2 < fbrecordcount do begin + po1:= ar1[i2-1]; + po2:= ar1[i2]; + while (compare2(po1,po2) = 0) and (i2 < fbrecordcount) do begin + deleterecord(po2); + intfreerecord(po2); + po2:= ar1[i2]; + end; + inc(i2); + end; + finally + frecno:= 0; + if fbrecordcount = 0 then begin + frecno:= -1; + end; + resync([]); + enablecontrols(); + end; + end; +end; + +function tlocalindex.getbookmark(const arecno: integer): bookmarkty; +var + int1: integer; + bm1: bookmarkdataty; +begin + with tmsebufdataset(fowner) do begin + checkrecno(arecno); + int1:= findexlocal.indexof(self) + 1; + checkindex(int1); + bm1.recno:= arecno - 1; + bm1.recordpo:= findexes[int1].ind[arecno-1]; + result:= bookmarkdatatobookmark(bm1); + end; +end; + +function tlocalindex.getdesc: boolean; +begin + result:= lio_desc in foptions; +end; + +procedure tlocalindex.setdesc(const avalue: boolean); +begin + if avalue then begin + options:= options + [lio_desc]; + end + else begin + options:= options - [lio_desc]; + end; +end; + +function tlocalindex.getdefault: boolean; +begin + result:= lio_default in foptions; +end; + +procedure tlocalindex.setdefault(const avalue: boolean); +begin + if avalue then begin + options:= options + [lio_default]; + end + else begin + options:= options - [lio_default]; + end; +end; + +{ tindexfields } + +constructor tindexfields.create(const aowner: tlocalindex); +begin + inherited create(aowner,tindexfield); + count:= 1; +end; + +class function tindexfields.getitemclasstype: persistentclassty; +begin + result:= tindexfield; +end; + +function tindexfields.getitems(const index: integer): tindexfield; +begin + result:= tindexfield(inherited items[index]); +end; + +{ tindexfield } + +procedure tindexfield.change; +begin + tlocalindex(fowner).change; +end; + +procedure tindexfield.setfieldname(const avalue: string); +begin + ffieldname:= avalue; + change; +end; + +procedure tindexfield.setoptions(const avalue: indexfieldoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + change; + end; +end; + +{ ecurrentvalueaccess } + +constructor ecurrentvalueaccess.create(const adataset: tdataset; + const afield: tfield; const msg: string); +begin + inherited create('Current value access: '+msg+lineend+ + 'Dataset: '+adataset.name+' Field: '+ afield.fieldname); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedatabase.pas b/mseide-msegui/lib/common/db/msedatabase.pas new file mode 100644 index 0000000..4d329b6 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedatabase.pas @@ -0,0 +1,1170 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 1999-2000 by Michael Van Canneyt, member of the + Free Pascal development team + + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + Modified 2007-2013 by Martin Schreiber + + **********************************************************************} + +unit msedatabase; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + classes,mclasses,mdb,sysutils,msedb,msestrings,mseclasses,mseglob,msetypes, + mseapplication,mseinterfaces; + +type + databaseoptionty = + (dbo_utf8,dbo_noutf8,dbo_utf8message, + dbo_bcdtofloatif //use ftFloat for scale > 4 instead ftBCD + ); + databaseoptionsty = set of databaseoptionty; + + tmdbdataset = class; + tmdatabase = class; + tmdbtransaction = class; + + idbclient = interface(inullinterface) + function getcomponentinstance: tcomponent; + function getname: ansistring; + function getactive: boolean; + procedure setactive(avalue: boolean); + function gettransaction: tmdbtransaction; + function getrecno: integer; + procedure setrecno(value: integer); + procedure disablecontrols; + procedure enablecontrols; + function moveby(distance: longint): longint; + end; + + savepointeventkindty = (spek_begin,spek_release,spek_rollback, + spek_committrans,spek_rollbacktrans); + + itransactionclient = interface(idbclient) + procedure settransaction(const avalue: tmdbtransaction); + procedure settransactionwrite(const avalue: tmdbtransaction); +// function getwritetransaction: tmbtransaction; +// function getactive: boolean; + procedure checkbrowsemode; + procedure refreshtransaction; +// function getcomponentinstance: tcomponent; + procedure savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); + end; + itransactionclientarty = array of itransactionclient; + pitransactionclientarty = ^itransactionclientarty; + + idatabaseclient = interface(idbclient) + procedure setdatabase(const sender: tmdatabase); +/// procedure setactive(avalue: boolean); + end; + idatabaseclientarty = array of idatabaseclient; + +// tmdbtransactionClass = class of tmdbtransaction; + tmdbtransaction = class(TComponent) + Private + FActive : boolean; + FDatabase : tmdatabase; + FOpenAfterRead : boolean; +// Function GetDataSetCount : Longint; +// Function GetDataset(Index : longint) : tmdbdataset; + fopencount: integer; + procedure RegisterDataset (const DS: itransactionclient; const awrite: boolean); + procedure UnRegisterDataset(const DS: itransactionclient; const awrite: boolean); + procedure RemoveDataSets; + procedure SetActive(Value : boolean); + Protected +// FDataSets : TList; +// fcloselock: integer; + fdatasets: itransactionclientarty; + fdatasetsactive: booleanarty; + fwritedatasets: itransactionclientarty; + fwritedatasetsactive: booleanarty; + Procedure SetDatabase (Value : tmdatabase); virtual; + procedure CloseTrans; virtual; + procedure openTrans; + Procedure CheckDatabase; + Procedure CheckActive; + Procedure CheckInactive; + procedure EndTransaction; virtual; abstract; + procedure StartTransaction; virtual; abstract; + procedure finalizetransaction; virtual; + //called on connection closing + procedure InternalHandleException; virtual; + procedure Loaded; override; + procedure begintrackactivestate; + procedure endtrackactivestate; + Public + constructor Create(AOwner: TComponent); override; + Destructor destroy; override; + procedure CloseDataSets; + procedure refreshdatasets(const awrite: boolean = true; + const aread: boolean = true); +// procedure refresh; //closes transaction and reopens datasets + Property DataBase : tmdatabase Read FDatabase Write SetDatabase; + property datasets: itransactionclientarty read fdatasets; + property writedatasets: itransactionclientarty read fdatasets; + property opencount: integer read fopencount; //increments on every open + published + property Active : boolean read FActive write setactive; + end; + + TLoginEvent = procedure(Sender: TObject; Username, Password: string) of object; + + TCustomConnection = class(TComponent) + private +// FAfterConnect: TNotifyEvent; +// FAfterDisconnect: TNotifyEvent; +// FBeforeConnect: TNotifyEvent; +// FBeforeDisconnect: TNotifyEvent; +// FLoginPrompt: Boolean; +// FOnLogin: TLoginEvent; + FStreamedConnected: Boolean; +// procedure SetAfterConnect(const AValue: TNotifyEvent); +// procedure SetAfterDisconnect(const AValue: TNotifyEvent); +// procedure SetBeforeConnect(const AValue: TNotifyEvent); +// procedure SetBeforeDisconnect(const AValue: TNotifyEvent); + fwaitcursor: boolean; + factioncount: integer; + procedure setwaitcursor(const avalue: boolean); + protected + //iactivatorclient + procedure setactive(const avalue: boolean); virtual; + procedure DoConnect; virtual; + procedure DoDisconnect; virtual; + function GetConnected : boolean; virtual; + Function GetDataset(Index : longint) : TDataset; virtual; +// Function GetDataSetCount : Longint; virtual; + procedure InternalHandleException; virtual; + procedure Loaded; override; + procedure SetConnected (const avalue : boolean); virtual; + public + procedure Close; + destructor Destroy; override; + procedure Open; + procedure beforeaction; + procedure afteraction; +// property DataSetCount: Longint read GetDataSetCount; +// property DataSets[Index: Longint]: TDataSet read GetDataSet; + published + property Connected: Boolean read GetConnected write SetConnected; + property waitcursor: boolean read fwaitcursor + write setwaitcursor default false; +// property LoginPrompt: Boolean read FLoginPrompt write FLoginPrompt; +// property Streamedconnected: Boolean read FStreamedConnected write FStreamedConnected; + +// property AfterConnect : TNotifyEvent read FAfterConnect write fafterconnect; +// property AfterDisconnect : TNotifyEvent read FAfterDisconnect write fAfterDisconnect; +// property BeforeConnect : TNotifyEvent read FBeforeConnect write fBeforeConnect; +// property BeforeDisconnect : TNotifyEvent read FBeforeDisconnect write fBeforeDisconnect; +// property OnLogin: TLoginEvent read FOnLogin write FOnLogin; + end; + + isqlpropertyeditor = interface(inullinterface)[miid_isqlpropertyeditor] + procedure setactive(avalue: boolean); + function getactive: boolean; + function getdatabase: tcustomconnection; + function isutf8: boolean; + end; + + databaseeventty = procedure(const sender: tmdatabase) of object; + databaseerroreventty = procedure(const sender: tmdatabase; + const aexception: exception; var handled: boolean) of object; + + // tmdatabaseClass = Class Of tmdatabase; + tmdatabase = class(TCustomConnection) + private +// FDataSets : TList; + fdatasets: idatabaseclientarty; + FTransactions : TList; + FDirectory : String; + FKeepConnection : Boolean; + FParams : TStringlist; + FSQLBased : Boolean; + fonbeforeconnect: databaseeventty; + fonconnecterror: databaseerroreventty; + fonafterconnect: databaseeventty; + fonbeforedisconnect: databaseeventty; + fonafterdisconnect: databaseeventty; + Function GetTransactionCount : Longint; + Function GetTransaction(Index : longint) : tmdbtransaction; +// procedure RegisterDataset (DS : tmdbdataset); + procedure RegisterDataset(const DS: idatabaseclient); + procedure RegisterTransaction (TA : tmdbtransaction); + procedure UnRegisterDataset(const DS: idatabaseclient); + procedure UnRegisterTransaction(TA : tmdbtransaction); + procedure RemoveDataSets; + procedure RemoveTransactions; + procedure setparams(const avalue: tstringlist); + protected + FDataBaseName : mseString; + FConnected : Boolean; + FOpenAfterRead : boolean; + procedure setconnected(const avalue: boolean); override; + Procedure CheckConnected; + Procedure CheckDisConnected; + procedure DoConnect; override; + procedure DoDisconnect; override; + procedure doafterinternalconnect; virtual; + procedure executeparams; virtual; + procedure dobeforeinternaldisconnect; virtual; + function GetConnected : boolean; override; +// Function GetDataset(Index : longint) : TDataset; override; +// Function GetDataSetCount : Longint; override; + Procedure DoInternalConnect; Virtual;Abstract; + Procedure DoInternalDisConnect; Virtual;Abstract; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure CloseDataSets; + procedure CloseTransactions; +// procedure ApplyUpdates; + procedure StartTransaction; virtual; abstract; + procedure EndTransaction; virtual; abstract; + property TransactionCount: Longint read GetTransactionCount; + property Transactions[Index: Longint]: tmdbtransaction read GetTransaction; + property Directory: string read FDirectory write FDirectory; + property IsSQLBased: Boolean read FSQLBased; + property datasets: idatabaseclientarty read fdatasets; + published + property Connected: Boolean read FConnected write SetConnected default false; + property DatabaseName: msestring read FDatabaseName write FDatabaseName; + property KeepConnection: Boolean read FKeepConnection + write FKeepConnection default false; + property Params : TStringlist read FParams Write setparams; + property onbeforeconnect: databaseeventty read fonbeforeconnect + write fonbeforeconnect; + property onafterconnect: databaseeventty read fonafterconnect + write fonafterconnect; + property onconnecterror: databaseerroreventty read fonconnecterror + write fonconnecterror; + property onbeforedisconnect: databaseeventty read fonbeforedisconnect + write fonbeforedisconnect; + property onafterdisconnect: databaseeventty read fonafterdisconnect + write fonafterdisconnect; + end; + + tmdbdatasetClass = Class of tmdbdataset; + + tmdbdataset = Class(TDataset,idatabaseclient,itransactionclient) + private + protected + fdatabase : tmdatabase; + ftransaction : tmdbtransaction; + ftransactionwrite : tmdbtransaction; + procedure setdatabase (const value: tmdatabase); virtual; + //itransactionclient + procedure settransaction(const value: tmdbtransaction); virtual; + procedure settransactionwrite(const value: tmdbtransaction); virtual; +// procedure checkdatabase; + procedure savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); virtual; + //idbclient + function getcomponentinstance: tcomponent; + function getname: ansistring; + function gettransaction: tmdbtransaction; + procedure refreshtransaction; virtual; abstract; + public + destructor destroy; override; + property database : tmdatabase read fdatabase write setdatabase; + property transaction : tmdbtransaction read ftransaction write settransaction; + property transactionwrite : tmdbtransaction read ftransactionwrite + write settransactionwrite; + end; + + ttacontroller = class(tactivatorcontroller) + protected + procedure setowneractive(const avalue: boolean); override; + public + constructor create(const aowner: tmdbtransaction; + const aintf: iactivatorclient); + end; + + +procedure dosetdatabase(const sender: idatabaseclient; const avalue: tmdatabase; + var dest: tmdatabase); +procedure dosettransaction(const sender: itransactionclient; + const avalue: tmdbtransaction; var dest: tmdbtransaction; + const awrite: boolean); +procedure checkdatabase(const aname: ansistring; const adatabase: tmdatabase); +procedure checktransaction(const aname: ansistring; const atransaction: tmdbtransaction); +procedure checkinactive(const active: boolean; const aname: ansistring); +procedure checkactive(const active: boolean; const aname: ansistring); + +implementation +uses + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},msefileutils,msearrayutils,msebits + {$ifndef FPC},classes_del{$endif}; + +procedure checkdatabase(const aname: ansistring; const adatabase: tmdatabase); +begin + if adatabase = nil then begin + raise edatabaseerror.create(aname+': '+serrdatabasenassigned); + end; +end; + +procedure checktransaction(const aname: ansistring; + const atransaction: tmdbtransaction); +begin + if atransaction = nil then begin + raise edatabaseerror.create(aname+': '+serrtransactionnset); + end; +end; + +procedure checkinactive(const active: boolean; const aname: ansistring); +begin + if active then begin + raise edatabaseerror.create(aname+': Component is active.'); + end; +end; + +procedure checkactive(const active: boolean; const aname: ansistring); +begin + if not active then begin + raise edatabaseerror.create(aname+': Component is not active.'); + end; +end; + +procedure dosetdatabase(const sender: idatabaseclient; const avalue: tmdatabase; + var dest: tmdatabase); +begin + if avalue <> dest then begin + if sender.getactive then begin + raise edatabaseerror.create('Database client "'+sender.getname+'" is active.'); + end; + if dest <> nil then begin + dest.unregisterdataset(sender); + end; + dest:= nil; + if avalue <> nil then begin + avalue.registerdataset(sender); + end; + dest:= avalue; + end; +end; + +procedure dosettransaction(const sender: itransactionclient; + const avalue: tmdbtransaction; var dest: tmdbtransaction; + const awrite: boolean); +begin + if avalue <> dest then begin + if not awrite and sender.getactive then begin + raise edatabaseerror.create('Transaction client "'+sender.getname+'" is active.'); + end; + if dest <> nil then begin + dest.unregisterdataset(sender,awrite); + dest.removefreenotification(sender.getcomponentinstance); + end; + dest:= nil; + if avalue <> nil then begin + avalue.registerdataset(sender,awrite); + avalue.freenotification(sender.getcomponentinstance); //used by IDE for namechange link + end; + dest:= avalue; + end; +end; + +{ tmdatabase } + +constructor tmdatabase.Create(AOwner: TComponent); +begin + inherited create(aowner); + fparams:= tstringlist.create; + ftransactions:= tlist.create; +end; + +destructor tmdatabase.Destroy; + +begin + removedatasets; //needs working connection for closing + removetransactions; + connected:= false; + ftransactions.free; + fparams.free; + inherited destroy; +end; + +procedure tmdatabase.doafterinternalconnect; +begin + fconnected:= true; + executeparams; +end; + +procedure tmdatabase.executeparams; +begin + //dummy +end; + +procedure tmdatabase.dobeforeinternaldisconnect; +begin + //dummy +end; + +procedure tmdatabase.setconnected(const avalue: boolean); +var +// int1: integer; + bo1: boolean; +begin + if avalue <> fconnected then begin + if avalue then begin + if csreading in componentstate then begin + fopenafterread:= true; + exit; + end + else begin + if assigned(onbeforeconnect) then begin + onbeforeconnect(self); + end; + try + dointernalconnect(); + doafterinternalconnect; + if assigned(onafterconnect) then begin + onafterconnect(self); + end; + except + on e: exception do begin + if assigned(onconnecterror) then begin + bo1:= false; + onconnecterror(self,e,bo1); + if not bo1 then begin + raise; + end + else begin + if not connected then begin + abort; + end; + end; + end + else begin + raise; + end; + end; + end; + end; + end + else begin + if csloading in componentstate then begin + fopenafterread := false; + end + else begin + if assigned(onbeforedisconnect) then begin + onbeforedisconnect(self); + end; + dobeforeinternaldisconnect; + closetransactions; + dointernaldisconnect; + fconnected:= avalue; + if assigned(onafterdisconnect) then begin + onafterdisconnect(self); + end; + end; + end; + end; +end; + +{procedure tmdatabase.setconnected(avalue: boolean); +var + bo1: boolean; +begin + if avalue <> connected then begin + if avalue then begin + if csreading in componentstate then begin + fstreamedconnected := true; + exit; + end + else begin + if assigned(fonbeforeconnect) then begin + fonbeforeconnect(self); + end; + try + doconnect; + if assigned(fonafterconnect) then begin + fonafterconnect(self); + end; + except + on e: exception do begin + if assigned(fonconnecterror) then begin + bo1:= false; + fonconnecterror(self,e,bo1); + if not bo1 then begin + raise; + end; + end; + end; + end; + end; + end + else begin + if assigned(fonbeforedisconnect) then begin + fonbeforedisconnect(self); + end; + dodisconnect; + if assigned(fonafterdisconnect) then begin + fonafterdisconnect(self); + end; + end; + end; +end; +} +Procedure tmdatabase.CheckConnected; + +begin + If Not Connected Then + DatabaseError(SNotConnected,Self); +end; + + +Procedure tmdatabase.CheckDisConnected; +begin + If Connected Then + DatabaseError(SConnected,Self); +end; + +procedure tmdatabase.DoConnect; +begin + DoInternalConnect; + FConnected := True; +end; + +procedure tmdatabase.DoDisconnect; +begin + Closedatasets; + Closetransactions; + DoInternalDisConnect; + if csloading in ComponentState then + FOpenAfterRead := false; + FConnected := False; +end; + +function tmdatabase.GetConnected: boolean; +begin + Result:= FConnected; +end; + +procedure tmdatabase.CloseDataSets; +var + int1: integer; +begin + int1:= high(fdatasets); + while int1 > 0 do begin + fdatasets[int1].setactive(false); + dec(int1); + if int1 > high(fdatasets) then begin + int1:= high(fdatasets); //could be destroyed + end; + end; +end; + +procedure tmdatabase.CloseTransactions; + +Var I : longint; + +begin + If Assigned(FTransactions) then begin + For I:=FTransactions.Count-1 downto 0 do begin + with tmdbtransaction(FTransactions[i]) do begin + try + EndTransaction; + except + end; + finalizetransaction; + end; + end; + end; +end; + +procedure tmdatabase.RemoveDataSets; +var + int1: integer; +begin + for int1:= high(fdatasets) downto 0 do begin + with fdatasets[int1] do begin + setactive(false); + setdatabase(nil); + end; + end; +end; + +procedure tmdatabase.RemoveTransactions; + +Var I : longint; + +begin + If Assigned(FTransactions) then begin + For I:=FTransactions.Count-1 downto 0 do begin + with tmdbtransaction(FTransactions[i]) do begin + setactive(false); + Database:=Nil; + end; + end; + end; +end; +{ +Function tmdatabase.GetDataSetCount : Longint; + +begin + If Assigned(FDatasets) Then + Result:=FDatasets.Count + else + Result:=0; +end; +} +Function tmdatabase.GetTransactionCount : Longint; + +begin + If Assigned(FTransactions) Then + Result:=FTransactions.Count + else + Result:=0; +end; +{ +Function tmdatabase.GetDataset(Index : longint) : TDataset; + +begin + If Assigned(FDatasets) then + Result:=TDataset(FDatasets[Index]) + else + begin + result := nil; + DatabaseError(SNoDatasets); + end; +end; +} +Function tmdatabase.GetTransaction(Index : longint) : tmdbtransaction; + +begin + If Assigned(FTransactions) then + Result:=tmdbtransaction(FTransactions[Index]) + else + begin + result := nil; + DatabaseError(SNoTransactions); + end; +end; + +procedure tmdatabase.RegisterDataset(const DS: idatabaseclient); +var + int1: integer; +begin + int1:= high(fdatasets); + if adduniqueitem(pointerarty(fdatasets),pointer(ds)) <= int1 then begin + DatabaseErrorFmt(SDatasetRegistered,[DS.getname]); + end; +end; + +procedure tmdatabase.RegisterTransaction (TA : tmdbtransaction); + +Var I : longint; + +begin + I:=FTransactions.IndexOf(TA); + If I=-1 then + FTransactions.Add(TA) + else + DatabaseErrorFmt(STransactionRegistered,[TA.Name]); +end; + +procedure tmdatabase.UnRegisterDataset(const DS: idatabaseclient); +begin + if removeitem(pointerarty(fdatasets),pointer(ds)) < 0 then begin + DatabaseErrorFmt(SNoDatasetRegistered,[DS.getName]); + end; +end; + +procedure tmdatabase.UnRegisterTransaction (TA : tmdbtransaction); + +Var I : longint; + +begin + I:=FTransactions.IndexOf(TA); + If I<>-1 then + FTransactions.Delete(I) + else + DatabaseErrorFmt(SNoTransactionRegistered,[TA.Name]); +end; + +procedure tmdatabase.setparams(const avalue: tstringlist); +begin + fparams.assign(avalue); +end; + +{ tmdbdataset } + +Procedure tmdbdataset.SetDatabase (const Value : tmdatabase); + +begin + dosetdatabase(idatabaseclient(self),value,fdatabase); +end; + +Procedure tmdbdataset.SetTransaction (const Value : tmdbtransaction); +begin + dosettransaction(itransactionclient(self),value,ftransaction,false); +end; + +procedure tmdbdataset.settransactionwrite(const value : tmdbtransaction); +begin + dosettransaction(itransactionclient(self),value,ftransactionwrite,true); +end; + +function tmdbdataset.getcomponentinstance: tcomponent; +begin + result:= self; +end; + +function tmdbdataset.getname: ansistring; +begin + result:= name; +end; + +function tmdbdataset.gettransaction: tmdbtransaction; +begin + result:= ftransaction; +end; + +Destructor tmdbdataset.Destroy; + +begin + Database:=Nil; + Transaction:=Nil; + transactionwrite:= nil; + Inherited; +end; + +procedure tmdbdataset.savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); +begin + //dummy +end; + +{ tmdbtransaction } + +procedure tmdbtransaction.SetActive(Value : boolean); +begin + if FActive and (not Value) then + EndTransaction + else if (not FActive) and Value then + if csreading in ComponentState then + begin + FOpenAfterRead := true; + exit; + end + else + StartTransaction; +end; + +procedure tmdbtransaction.Loaded; + +begin + inherited; + try + if FOpenAfterRead then SetActive(true); + except + if csDesigning in Componentstate then + InternalHandleException + else + raise; + end; +end; + +Procedure tmdbtransaction.InternalHandleException; + +begin + if assigned(classes.ApplicationHandleException) then + classes.ApplicationHandleException(self) + else + ShowException(ExceptObject,ExceptAddr); +end; + +Procedure tmdbtransaction.CheckActive; + +begin + If not FActive Then + DatabaseError(STransNotActive,Self); +end; + +Procedure tmdbtransaction.CheckInActive; + +begin + If FActive Then + DatabaseError(STransActive,Self); +end; + +Procedure tmdbtransaction.CloseTrans; + +begin + FActive := false; +end; + +procedure tmdbtransaction.opentrans; + +begin + inc(fopencount); + if fopencount = 0 then begin + inc(fopencount); + end; + factive := true; +end; + +Procedure tmdbtransaction.SetDatabase (Value : tmdatabase); + +begin + If Value<>FDatabase then + begin + CheckInactive; + If Assigned(FDatabase) then + FDatabase.UnregisterTransaction(Self); + If Value<>Nil Then + Value.RegisterTransaction(Self); + FDatabase:=Value; + end; +end; + +constructor tmdbtransaction.create(AOwner : TComponent); + +begin + inherited create(AOwner); +// FDatasets:=TList.Create; +end; + +Procedure tmdbtransaction.CheckDatabase; + +begin + If (FDatabase=Nil) then + DatabaseError(SErrNoDatabaseAvailable,Self) +end; + +procedure tmdbtransaction.CloseDataSets; +var + int1: integer; +begin +// if fcloselock = 0 then begin + for int1:= high(fdatasets) downto 0 do begin + fdatasets[int1].setactive(false); + end; +// for int1:= high(fwritedatasets) downto 0 do begin +// fwritedatasets[int1].setactive(false); +// end; +// end; +end; + +procedure tmdbtransaction.refreshdatasets(const awrite: boolean = true; + const aread: boolean = true); +var + int1: integer; +begin + if awrite then begin + for int1:= high(fwritedatasets) downto 0 do begin + with fwritedatasets[int1] do begin + if getactive then begin + refreshtransaction; + end; + end; + end; + end; + if aread then begin + for int1:= high(fdatasets) downto 0 do begin + with fdatasets[int1] do begin + if getactive then begin + refreshtransaction; + end; + end; + end; + end; +end; + +Destructor tmdbtransaction.Destroy; + +begin + active:= false; + RemoveDatasets; + Database:=Nil; +// FDatasets.Free; + Inherited; +end; + +procedure tmdbtransaction.RemoveDataSets; +var + int1: integer; +begin + for int1:= high(fwritedatasets) downto 0 do begin + fwritedatasets[int1].settransactionwrite(nil); + end; + for int1:= high(fdatasets) downto 0 do begin + fdatasets[int1].settransaction(nil); + end; +end; +{ +Function tmdbtransaction.GetDataSetCount : Longint; +begin + If Assigned(FDatasets) Then + Result:=FDatasets.Count + else + Result:=0; +end; +} +procedure tmdbtransaction.UnRegisterDataset(const DS: itransactionclient; + const awrite: boolean); +var + ar1: pitransactionclientarty; + ar2: pbooleanarty; + int1: integer; +begin + if awrite then begin + ar1:= @fwritedatasets; + ar2:= @fwritedatasetsactive; + end + else begin + ar1:= @fdatasets; + ar2:= @fdatasetsactive; + end; + int1:= removeitem(pointerarty(ar1^),pointer(ds)); + if int1 < 0 then begin + DatabaseErrorFmt(SNoDatasetRegistered,[DS.getName]); + end; + if int1 <= high(ar2^) then begin + deleteitem(ar2^,int1); + end; +end; + +procedure tmdbtransaction.RegisterDataset(const DS: itransactionclient; + const awrite: boolean); +var + int1: integer; + ar1: pitransactionclientarty; +begin + if awrite then begin + ar1:= @fwritedatasets; + end + else begin + ar1:= @fdatasets; + end; + int1:= high(ar1^); + if adduniqueitem(pointerarty(ar1^),pointer(ds)) <= int1 then begin + DatabaseErrorFmt(SDatasetRegistered,[DS.getname]); + end; +end; + +procedure tmdbtransaction.finalizetransaction; +begin + //dummy +end; + +procedure tmdbtransaction.begintrackactivestate; +var + int1: integer; +begin + setlength(fdatasetsactive,length(fdatasets)); + for int1:= high(fdatasetsactive) downto 0 do begin + fdatasetsactive[int1]:= fdatasets[int1].getactive; + end; + setlength(fwritedatasetsactive,length(fwritedatasets)); + for int1:= high(fwritedatasetsactive) downto 0 do begin + fwritedatasetsactive[int1]:= fwritedatasets[int1].getactive; + end; +end; + +procedure tmdbtransaction.endtrackactivestate; +begin + fdatasetsactive:= nil; + fwritedatasetsactive:= nil; +end; +{ +Function tmdbtransaction.GetDataset(Index : longint) : tmdbdataset; + +begin + If Assigned(FDatasets) then + Result:=tmdbdataset(FDatasets[Index]) + else + begin + result := nil; + DatabaseError(SNoDatasets); + end; +end; +} +{ TCustomConnection } +{ +procedure TCustomConnection.SetAfterConnect(const AValue: TNotifyEvent); +begin +// if FAfterConnect=AValue then exit; + FAfterConnect:=AValue; +end; +} +function TCustomConnection.GetDataSet(Index: Longint): TDataSet; +begin + Result := nil; +end; +{ +function TCustomConnection.GetDataSetCount: Longint; +begin + Result := 0; +end; +} +procedure TCustomConnection.InternalHandleException; +begin + if assigned(classes.ApplicationHandleException) then + classes.ApplicationHandleException(self) + else + ShowException(ExceptObject,ExceptAddr); +end; +{ +procedure TCustomConnection.SetAfterDisconnect(const AValue: TNotifyEvent); +begin +// if FAfterDisconnect=AValue then exit; + FAfterDisconnect:=AValue; +end; + +procedure TCustomConnection.SetBeforeConnect(const AValue: TNotifyEvent); +begin +// if FBeforeConnect=AValue then exit; + FBeforeConnect:=AValue; +end; +} +procedure TCustomConnection.SetConnected(const avalue: boolean); +begin + If aValue<>Connected then + begin + If aValue then + begin + if csReading in ComponentState then + begin + FStreamedConnected := true; + exit; + end + else + begin +// if Assigned(BeforeConnect) then +// BeforeConnect(self); +// if FLoginPrompt then if assigned(FOnLogin) then +// FOnLogin(self,'',''); + DoConnect; +// if Assigned(AfterConnect) then +// AfterConnect(self); + end; + end + else + begin +// if Assigned(BeforeDisconnect) then +// BeforeDisconnect(self); + DoDisconnect; +// if Assigned(AfterDisconnect) then +// AfterDisconnect(self); + end; + end; +end; + +procedure tcustomconnection.setactive(const avalue: boolean); +begin + connected:= avalue; +end; + +{ +procedure TCustomConnection.SetBeforeDisconnect(const AValue: TNotifyEvent); +begin +// if FBeforeDisconnect=AValue then exit; + FBeforeDisconnect:=AValue; +end; +} +procedure TCustomConnection.DoConnect; + +begin + // Do nothing yet +end; + +procedure TCustomConnection.DoDisconnect; + +begin + // Do nothing yet +end; + +function TCustomConnection.GetConnected: boolean; + +begin + Result := False; +end; + +procedure TCustomConnection.Loaded; +begin + inherited Loaded; + try + if FStreamedConnected then + SetConnected(true); + except + if csDesigning in Componentstate then + InternalHandleException + else + raise; + end; +end; + +procedure TCustomConnection.Close; +begin + Connected := False; +end; + +destructor TCustomConnection.Destroy; +begin + Connected:=False; + Inherited Destroy; +end; + +procedure TCustomConnection.Open; +begin + Connected := True; +end; + +procedure TCustomConnection.setwaitcursor(const avalue: boolean); +var + bo1: boolean; +begin + if avalue <> fwaitcursor then begin + bo1:= fwaitcursor; + fwaitcursor:= avalue; + if bo1 and (factioncount > 0) then begin + application.endwait; + end; + factioncount:= 0; + end; +end; + +procedure tcustomconnection.beforeaction; +begin + if waitcursor then begin + if interlockedincrement(factioncount) = 1 then begin + application.beginwait; + end; + end; +end; + +procedure tcustomconnection.afteraction; +begin + if waitcursor then begin + if interlockeddecrement(factioncount) = 0 then begin + application.endwait; + end; + end; +end; + + +{ ttacontroller } + +constructor ttacontroller.create(const aowner: tmdbtransaction; + const aintf: iactivatorclient); +begin + inherited create(aowner,aintf); +end; + +procedure ttacontroller.setowneractive(const avalue: boolean); +begin + tmdbtransaction(fowner).active:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedb.pas b/mseide-msegui/lib/common/db/msedb.pas new file mode 100644 index 0000000..57dbaa0 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedb.pas @@ -0,0 +1,9363 @@ +{ MSEgui Copyright (c) 2004-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedb; + +{$ifdef FPC} + {$define mse_hasvtunicodestring} +{$endif} +{$define hasaswidestring} +{$define integergetdatasize} + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mdb,mseclasses,mseglob,msestrings,msetypes,msearrayprops, + mseapplication,mseinterfaces, + sysutils,msebintree,mseact,msetimer,maskutils,mseifiglob, + mseificompglob,mseeditglob, + msevariants{$ifndef FPC},classes_del{$endif}; + +const + mse_vtguid = $ff; + guidbuffersize = 36; //aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee + + de_modified = ord(high(tdataevent))+1; + de_afterdelete = ord(high(tdataevent))+2; + de_afterinsert = ord(high(tdataevent))+3; + de_afterpost = ord(high(tdataevent))+4; + de_hasactiveedit = ord(high(tdataevent))+5; + de_afterapplyupdate = ord(high(tdataevent))+6; + + defaultdscontrolleroptions = [{dso_cancelupdateondeleteerror}]; + allfieldkinds = [fkData,fkCalculated,fkLookup,fkInternalCalc]; + +type + lookupdatatypety = (ldt_int32,ldt_int64,ldt_string); + + bookmarkty = string; + //use instead of TBookmarkStr in order to avoid + // FPC deprecated warning +// guidbufferty = array[0..guidbuffersize-1] of char; +// pguidbufferty = ^guidbufferty; + + fieldtypearty = array of tfieldtype; + fieldtypesty = set of tfieldtype; + fieldtypesarty = array of fieldtypesty; + datasetarty = array of tdataset; + + fielddefty = record + datatype: tfieldtype; + size: integer; + name: string; + end; + pfielddefty = ^fielddefty; + fielddefarty = array of fielddefty; + +const + int32fields = [ftsmallint,ftinteger,ftword]; + int64fields = [ftlargeint]; + doublefields = [ftfloat,ftcurrency]; + datetimefields = [ftdate,fttime,ftdatetime]; + charfields = [ftstring,ftfixedchar]; + + widecharfields = [ftwidestring,ftfixedwidechar,ftwidememo]; + textfields = [ftstring,ftfixedchar,ftwidestring,ftfixedwidechar,ftmemo,ftguid]; + memofields = textfields+[ftmemo]; + integerfields = [ftsmallint,ftinteger,ftword,ftlargeint,ftbcd]; + booleanfields = [ftboolean,ftstring,ftfixedchar]+integerfields-[ftbcd]; + realfields = [ftfloat,ftcurrency,ftbcd]; + stringfields = textfields + integerfields + booleanfields + + realfields + datetimefields; + widestringfields = [ftwidestring,ftfixedwidechar,ftwidememo]; + blobfields = [ftblob,ftmemo,ftgraphic{,ftstring}]; +// defaultproviderflags = [pfInInsert,pfInUpdate,pfInWhere]; + + varsizefields = [ftstring,ftfixedchar,ftwidestring,ftfixedwidechar, + ftbytes,ftvarbytes,ftbcd,ftfmtbcd]; + + converrorstring = '?'; + +type + filtereditkindty = (fek_filter,fek_filtermin,fek_filtermax,fek_find); + locateresultty = (loc_timeout,loc_notfound,loc_ok); + recnosearchoptionty = (rso_backward); + recnosearchoptionsty = set of recnosearchoptionty; + + locatekeyoptionty = (lko_caseinsensitive,lko_partialkey,lko_posinsensitive); + locatekeyoptionsty = set of locatekeyoptionty; + locaterecordoptionty = (lro_noforward,lro_nobackward,lro_nocurrent,lro_utf8); + locaterecordoptionsty = set of locaterecordoptionty; + + fieldarty = array of tfield; + + optionmasterlinkty = (mdlo_syncedit,mdlo_syncinsert,mdlo_syncdelete, + mdlo_delayeddetailpost,mdlo_syncfields, + mdlo_inserttoupdate,mdlo_norefresh); + optionsmasterlinkty = set of optionmasterlinkty; + + imasterlink = interface(inullinterface)[miid_imasterlink] + function refreshing: boolean; + end; + + imselocate = interface(inullinterface)[miid_imselocate] + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; + end; + + tmsestringfield = class; + idbdata = interface(inullinterface)[miid_idbdata] + function getindex(const afield: tfield): integer; //-1 if none + function gettextindex(const afield: tfield; + const acaseinsensitive: boolean): integer; //-1 if none + function lookuptext(const indexnum: integer; const akey: integer; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function lookuptext(const indexnum: integer; const akey: int64; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function lookuptext(const indexnum: integer; const akey: msestring; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function findtext(const indexnum: integer; const searchtext: msestring; + out arecord: integer): boolean; + function getrowtext(const indexnum: integer; const arecord: integer; + const afield: tfield): msestring; + function getrowinteger(const indexnum: integer; const arecord: integer; + const afield: tfield): integer; + function getrowlargeint(const indexnum: integer; const arecord: integer; + const afield: tfield): int64; + end; + + idbeditinfo = interface(inullinterface)[miid_idbeditinfo] + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + //propertynames = nil -> propertyname = 'datafield' + end; + + ireccontrol = interface(inullinterface)[miid_ireccontrol] + procedure recchanged; + end; + + ipersistentfieldsinfo = interface(inullinterface)[miid_ipersistentfieldsinfo] + function getfieldnames: stringarty; + end; + + idatasetsum = interface(inullinterface)[miid_idatasetsum] + procedure sumfield(const afield: tfield; out asum: integer); overload; + procedure sumfield(const afield: tfield; out asum: int64); overload; + procedure sumfield(const afield: tfield; out asum: currency); overload; + procedure sumfield(const afield: tfield; out asum: double); overload; + end; + + getdatasourcefuncty = function: tdatasource of object; + + tdbfieldnamearrayprop = class(tstringarrayprop,idbeditinfo) + private + ffieldtypes: fieldtypesty; + fgetdatasource: getdatasourcefuncty; + protected + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + public + constructor create(const afieldtypes: fieldtypesty; + const agetdatasource: getdatasourcefuncty); + property fieldtypes: fieldtypesty read ffieldtypes write ffieldtypes; + end; + + tdscontroller = class; + + ifieldcomponent = interface; + + idsfieldcontroller = interface(inullinterface) + function getcontroller: tdscontroller; + procedure fielddestroyed(const sender: ifieldcomponent); + end; +{ + lookupfieldinfoty = record + end; + plookupfieldinfoty = ^lookupfieldinfoty; +} + ifieldcomponent = interface(inullinterface)[miid_ifieldcomponent] + procedure setdsintf(const avalue: idsfieldcontroller); + function getinstance: tfield; + end; + +// providerflag1ty = (pf1_refreshinsert,pf1_refreshupdate,pf1_nocopyrecord); +// providerflags1ty = set of providerflag1ty; + + imsefield = interface(inullinterface)[miid_imsefield] +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + end; + + fieldstatety = (fis_changing); + fieldstatesty = set of fieldstatety; + + tmsefield = class(tfield,imsefield) + private +// fproviderflags1: providerflags1ty; + fstate: fieldstatesty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +//m function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; +// function getaswidestring: widestring; override; +// procedure setaswidestring(const avalue: widestring); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + + getmsestringdataty = function(const sender: tmsestringfield; + out avalue: msestring): boolean of object; //false if null + setmsestringdataty = procedure(const sender: tmsestringfield; + avalue: msestring) of object; + + tmsestringfield = class(tstringfield,ifieldcomponent,imsefield) + private + fstate: fieldstatesty; + fdsintf: idsfieldcontroller; + fgetmsestringdata: getmsestringdataty; + fsetmsestringdata: setmsestringdataty; + fcharacterlength: integer; +// fvaluebuffer: msestring; +// fvalidating: boolean; + fisftwidestring: boolean; + fdefaultexpressionstr: msestring; + fdefaultexpressionbefore: string; + //synchronize with TField.DefaultExpression +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + //ifieldcomponent + fonsetvalue: msestringfieldsetvalueeventty; + procedure setdsintf(const avalue: idsfieldcontroller); + function getinstance: tfield; + function getdefaultexpression: msestring; + procedure setdefaultexpression(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + procedure setasnullmsestring(const avalue: msestring); + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + procedure setismsestring(const getter: getmsestringdataty; + const setter: setmsestringdataty; + const acharacterlength: integer; + const aisftwidestring: boolean); + function GetDataSize: integer; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + procedure dosetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean) override; + public + destructor destroy; override; + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + property asnullmsestring: msestring read getasunicodestring + write setasnullmsestring; + //'' -> NULL + function oldmsestring(out aisnull: boolean): msestring; overload; + function oldmsestring: msestring; overload; + function curmsestring(out aisnull: boolean): msestring; overload; + function curmsestring: msestring; overload; +// property value: msestring read getasmsestring write setasmsestring; + property characterlength: integer read fcharacterlength; + property isftwidestring: boolean read fisftwidestring; + published + property defaultexpression: msestring read getdefaultexpression + write setdefaultexpression; +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property Transliterate default false; + property onsetvalue: msestringfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + + tmseguidfield = class(tmsefield,imsefield) + private + protected + function getasvariant: variant; override; + procedure setvarvalue(const avalue: variant); override; + function getasstring: string; override; + procedure setasstring(const avalue: string); override; + function getdefaultwidth: longint; override; + function getdatasize: integer; override; + + function getasguid: tguid; override; + procedure setasguid(const avalue: tguid); override; + public + constructor create(aowner: tcomponent); override; + property asguid: tguid read getasguid write setasguid; + property value: tguid read getasguid write setasguid; + published + end; + + tmsenumericfield = class(tnumericfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + tmselongintfield = class(tlongintfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + procedure setasenum(const avalue: integer); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasboolean: boolean; override; + procedure setasboolean(avalue: boolean); override; + procedure setaslargeint(avalue: largeint); override; + function getaslargeint: largeint; override; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; + function asoldid: integer; + function sum: integer; +// property asmsestring: msestring read getasmsestring write setasmsestring; +// property asid: integer read getasid write setasid; //-1 -> NULL + property asenum: integer read getaslongint write setasenum; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmselargeintfield = class(tlargeintfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + function getasid: int64; + procedure setasid(const avalue: int64); + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasboolean: boolean; override; + procedure setasboolean(avalue: boolean); override; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; + function asoldid: int64; + function sum: int64; +// property asmsestring: msestring read getasmsestring write setasmsestring; +// property asid: int64 read getasid write setasid; //-1 -> NULL + property Value: Largeint read GetAsLargeint write SetAsLargeint; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmsesmallintfield = class(tsmallintfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + function getasid: integer; + procedure setasid(const avalue: integer); + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasboolean: boolean; override; + procedure setasboolean(avalue: boolean); override; + procedure setaslargeint(avalue: largeint); override; + function getaslargeint: largeint; override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + property asid: integer read getasid write setasid; //-1 -> NULL + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmsewordfield = class(twordfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasboolean: boolean; override; + procedure setasboolean(avalue: boolean); override; + procedure setaslargeint(avalue: largeint); override; + function getaslargeint: largeint; override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmseautoincfield = class(tautoincfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmsefloatfield = class(tfloatfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasfloat: double; override; + function getascurrency: currency; override; + procedure setasfloat(avalue: double); override; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + function GetAsLongint: Longint; override; + procedure change; override; + function GetAsLargeint: Largeint; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; + function sum: double; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmsecurrencyfield = class(tmsefloatfield) + public + constructor create(aowner: tcomponent); override; + end; + tmsebooleanfield = class(tbooleanfield,imsefield) + private + fstate: fieldstatesty; + fdisplayvalues: msestring; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + procedure setdisplayvalues(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + fdisplays : array[boolean,boolean] of msestring; + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + function GetDataSize: integer; override; + function GetAsBoolean: Boolean; override; + procedure SetAsBoolean(AValue: Boolean); override; + function getasstring: string; override; + procedure setasstring(const avalue: string); override; + function GetDefaultWidth: Longint; override; + function GetAsLongint: Longint; override; + procedure SetAsLongint(AValue: Longint); override; + function GetAsVariant: variant; override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + constructor Create(AOwner: TComponent); override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; + function sum: integer; //counts true values +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property displayvalues: msestring read fdisplayvalues write setdisplayvalues; + property FieldKind default fkData; + property HasConstraints default false; +// property Lookup default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; +// property DisplayWidth default 5; variable! + end; + + datetimefieldoptionty = (dtfo_utc,dtfo_local); //DB time format + datetimefieldoptionsty = set of datetimefieldoptionty; + + tmsedatetimefield = class(tdatetimefield,imsefield) + private + fstate: fieldstatesty; + foptions: datetimefieldoptionsty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + procedure setoptions(const avalue: datetimefieldoptionsty); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasdatetime: tdatetime; override; + procedure setasdatetime(avalue: tdatetime); override; + procedure setasstring(const avalue: string); override; + function gettext1(const r: tdatetime; const adisplaytext: boolean): msestring; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property options: datetimefieldoptionsty read foptions + write setoptions default []; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmsedatefield = class(tmsedatetimefield) + public + constructor create(aowner: tcomponent); override; + end; + tmsetimefield = class(tmsedatetimefield) + public + constructor create(aowner: tcomponent); override; + end; + + tmsebinaryfield = class(tbinaryfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + tmsebytesfield = class(tbytesfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + function getasvariant: variant; override; + function getasstring: string; override; + procedure setasstring(const avalue: string); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + tmsevarbytesfield = class(tvarbytesfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; +// function getaswidestring: widestring; override; +// procedure setaswidestring(const avalue: widestring); override; +// function getasunicodestring: unicodestring; override; +// procedure setasunicodestring(const avalue: unicodestring); override; + function getasvariant: variant; override; + procedure setasstring(const avalue: string); override; + function getasstring: string; override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + tmsebcdfield = class(tbcdfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + procedure setasfloat(avalue: double); override; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + class procedure checktypesize(avalue: longint); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; + function sum: currency; +// property asmsestring: msestring read getasmsestring write setasmsestring; + property Value: Currency read GetAsCurrency write SetAsCurrency; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property precision default 15; +// property displaywidth default 15; variable! + property currency default false; + end; + + blobidty = record + id: int64; + local: boolean; + end; + + getblobidfuncty = function(const afield: tfield; out aid: blobidty): boolean + of object; + + tblobcachenode = class(tstringcachenode) + private + flocal: boolean; + public + constructor create(const akey: blobidty; const adata: string); overload; + end; + + tblobcache = class(tstringcacheavltree) + private + ffindnode: tblobcachenode; + public + constructor create; + destructor destroy; override; + function addnode(const akey: blobidty; + const adata: string): tblobcachenode; overload; + function find(const akey: blobidty; + out anode: tblobcachenode): boolean; overload; + end; + + tmseblobfield = class(tblobfield,imsefield) + private + fcache: tblobcache; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + procedure setcachekb(const avalue: integer); + function getcachekb: integer; + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + fgetblobid: getblobidfuncty; +// function getasmsestring: msestring; virtual; +// procedure setasmsestring(const avalue: msestring); virtual; + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + procedure removecache(const aid: blobidty); overload; virtual; + procedure removecache; overload; + function getasvariant: variant; override; + function getasstring: string; override; + procedure setasstring(const avalue: string); override; +// function getaswidestring: widestring; override; +// procedure setaswidestring(const avalue: widestring); override; + procedure gettext(var atext: string; adisplaytext: boolean); override; + procedure SetDataset(AValue : TDataset); override; + public + destructor destroy; override; + function HasParent: Boolean; override; + procedure Clear; override; + procedure clearcache; virtual; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + procedure LoadFromStream(Stream: TStream); + procedure LoadFromFile(const FileName: filenamety); + procedure SaveToFile(const FileName: filenamety); + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property cachekb: integer read getcachekb write setcachekb default 0; + //cachesize in kilo bytes, 0 -> no cache + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + tmsememofield = class(tmseblobfield,ifieldcomponent) + private + fdsintf: idsfieldcontroller; + //ifieldcomponent + procedure setdsintf(const avalue: idsfieldcontroller); + function getinstance: tfield; + protected + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasunicodestring: msestring; override; + procedure setasunicodestring(const avalue: msestring); override; + function getasvariant: variant; override; + procedure setvarvalue(const avalue: variant); override; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure Clear; override; +// property asmsestring: msestring read getasmsestring write setasmsestring; + function oldmsestring(out aisnull: boolean): msestring; + function assql: msestring; + function asoldsql: msestring; + published + property Transliterate default True; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + + tmsevariantfield = class; + setvardataty = procedure(const sender: tmsevariantfield; + avalue: variant) of object; + getvardataty = function(const sender: tmsevariantfield; + out avalue: variant): boolean of object; + tmsevariantfield = class(tvariantfield,imsefield) + private +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + //imsefield +//m function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + fgetvardata: getvardataty; + fsetvardata: setvardataty; + function getdatasize: integer; override; + function getasvariant: variant; override; + procedure setvarvalue(const avalue: variant); override; + + function getasboolean: boolean; override; + function getasinteger: integer; override; + function getasdatetime: tdatetime; override; + function getasfloat: double; override; +// function getasstring: string; override; +// function getaswidestring: widestring; override; +// function getasunicodestring: unicodestring; override; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + + function getaslongint: longint; override; + procedure setaslongint(avalue: longint); override; + function getaslargeint: largeint; override; + procedure setaslargeint(avalue: largeint); override; + function getascurrency: currency; override; + procedure setascurrency(avalue: currency); override; + procedure SetDataset(AValue : TDataset); override; + public + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 15; + end; + + tmsedatalink = class(tdatalink) + private + function getrecnozerobased: integer; + procedure setrecnozerobased(const avalue: integer); + protected + fcanclosing: integer; + fdscontroller: tdscontroller; + procedure checkcontroller; + procedure activechanged; override; + function getdataset: tdataset; + function getutf8: boolean; + function getfiltereditkind: filtereditkindty; + function GetActiveRecord: Integer; override; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); override; + procedure disabledstatechange; virtual; + function canedit: boolean; + procedure setbuffercount(value: integer); override; + public + destructor destroy; override; + function moveby(distance: integer): integer; override; + function noedit: boolean; + function caninsert: boolean; + function canappend: boolean; + function candelete: boolean; + function canupdate: boolean; + property dataset: tdataset read getdataset; + property dscontroller: tdscontroller read fdscontroller; + property utf8: boolean read getutf8; + property filtereditkind: filtereditkindty read getfiltereditkind; + function canclose: boolean; + property recnozerobased: integer read getrecnozerobased + write setrecnozerobased; + end; + + fielddatalinkstatety = (fds_ismsestring,fds_islargeint,fds_isstring, + fds_editing,fds_modified,fds_filterediting, + fds_filtereditdisabled); + fielddatalinkstatesty = set of fielddatalinkstatety; + + tfieldsdatalink = class(tmsedatalink,iifidataserver) + protected + procedure activechanged; override; + procedure layoutchanged; override; + procedure updatefields; virtual; + procedure fieldchanged; virtual; + //iifiserver + procedure execute(const sender: iificlient); virtual; + procedure valuechanged(const sender: iifidatalink); virtual; + procedure statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); virtual; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); virtual; + procedure dataentered(const sender: iificlient; + const arow: integer); virtual; + procedure closequery(const sender: iificlient; + var amodalresult: modalresultty); virtual; + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); virtual; + procedure updateoptionsedit(var avalue: optionseditty); virtual; + end; + + tfielddatalink = class(tfieldsdatalink) + private + ffield: tfield; + ffieldname: string; + fnullsymbol: msestring; + procedure setfieldname(const Value: string); + function getasmsestring: msestring; + procedure setasmsestring(const avalue: msestring); + function getmsedefaultexpression: msestring; + procedure checkfield; + function GetAsBoolean: Boolean; + procedure SetAsBoolean(const avalue: Boolean); + function GetAsCurrency: Currency; + procedure SetAsCurrency(const avalue: Currency); + function GetAsDateTime: TDateTime; + procedure SetAsDateTime(const avalue: TDateTime); + function GetAsFloat: Double; + procedure SetAsFloat(const avalue: Double); + function GetAsLongint: Longint; + procedure SetAsLongint(const avalue: Longint); + function GetAsLargeInt: LargeInt; + procedure SetAsLargeInt(const avalue: LargeInt); + function GetAsInteger: Integer; + procedure SetAsInteger(const avalue: Integer); + function GetAsString: string; + procedure SetAsString(const avalue: string); + function GetAsVariant: variant; + procedure SetAsVariant(const avalue: variant); + function getislargeint: boolean; + function getismsestring: boolean; + function getisstringfield: boolean; + protected + fstate: fielddatalinkstatesty; + procedure setfield(const value: tfield); virtual; + procedure updatefields; override; + function getsortfield: tfield; virtual; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + procedure dataentered(const sender: iificlient; + const arow: integer); override; + public + function assql: msestring; + function fieldactive: boolean; + procedure clear; + property field: tfield read ffield; + property sortfield: tfield read getsortfield; + property fieldname: string read ffieldname write setfieldname; + property state: fielddatalinkstatesty read fstate; + property islargeint: boolean read getislargeint; + property ismsestring: boolean read getismsestring; + property isstringfield: boolean read getisstringfield; + + property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean; + property AsCurrency: Currency read GetAsCurrency write SetAsCurrency; + property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime; + property AsFloat: Double read GetAsFloat write SetAsFloat; + property AsLongint: Longint read GetAsLongint write SetAsLongint; + property AsLargeInt: LargeInt read GetAsLargeInt write SetAsLargeInt; + property AsInteger: Integer read GetAsInteger write SetAsInteger; + property AsString: string read GetAsString write SetAsString; + property AsVariant: variant read GetAsVariant write SetAsVariant; + property asmsestring: msestring read getasmsestring write setasmsestring; + property msedefaultexpression: msestring read getmsedefaultexpression; + function msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; virtual; + property nullsymbol: msestring read fnullsymbol write fnullsymbol; + end; + +// fieldarrayty = array of tfield; + + fieldclassty = class of tfield; + + fieldclasstypety = (ft_unknown,ft_string,ft_guid,ft_numeric, + ft_longint,ft_largeint,ft_smallint, + ft_word,ft_autoinc,ft_float,ft_currency,ft_boolean, + ft_datetime,ft_date,ft_time, + ft_binary,ft_bytes,ft_varbytes, + ft_bcd,ft_blob,ft_memo,ft_graphic,ft_variant); + fieldclasstypearty = array of fieldclasstypety; + + tmsedatasource = class(tdatasource) + public + procedure bringtofront; //called first by dataset + end; + + tpersistentfields = class(tpersistentarrayprop,ipersistentfieldsinfo) + private + fdataset: tdataset; + procedure readfields(reader: treader); + procedure writefields(writer: twriter); + procedure setitems(const index: integer; const avalue: tfield); + function getitems(const index: integer): tfield; + protected + finvaliditems: booleanarty; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure defineproperties(filer: tfiler); override; + function ispropertystored(index: integer): boolean; override; + public + constructor create(const adataset: tdataset); + class function getitemclasstype: persistentclassty; override; + procedure move(const curindex,newindex: integer); override; + procedure updateorder; + function getfieldnames: stringarty; + property dataset: tdataset read fdataset; + property items[const index: integer]: tfield read getitems write setitems; default; + end; + + datasetoptionty = (dso_utf8,dso_stringmemo,dso_numboolean, + dso_waitcursor, + dso_initinternalcalc, + + //flags below have been moved to + //tsqlquery.options + dso_postsavepoint,dso_deletesavepoint, + dso_cancelupdateonerror,dso_cancelupdatesonerror, + dso_cancelupdateondeleteerror, + dso_editonapplyerror, + dso_restoreupdateonsavepointrollback, + dso_noapply,dso_autoapply, + dso_autocommitret,dso_autocommit, + dso_refreshafterapply,dso_recnoapplyrefresh, + dso_refreshtransaction, + dso_notransactionrefresh,dso_recnotransactionrefresh, + dso_noprepare, + dso_cacheblobs, + dso_offline, //disconnect database after open + dso_local, //do not connect database on open + + dso_refreshwaitcursor, //deprecated + dso_noedit,dso_noinsert,dso_noappend,dso_noupdate, + dso_nodelete, + dso_canceloncheckbrowsemode + {, + dso_syncmasteredit,dso_syncmasterinsert, + -> optionsmasterlink + dso_syncmasterdelete,dso_delayeddetailpost, + dso_inserttoupdate,dso_syncinsertfields}); + datasetoptionsty = set of datasetoptionty; +const + deprecatedbdsoptions = [ + dso_postsavepoint,dso_deletesavepoint, + dso_cancelupdateonerror,dso_cancelupdatesonerror, + dso_cancelupdateondeleteerror, + dso_editonapplyerror, + dso_restoreupdateonsavepointrollback, + dso_noapply,dso_autoapply, + dso_autocommitret,dso_autocommit, + dso_refreshafterapply,dso_recnoapplyrefresh, + dso_refreshtransaction, + dso_notransactionrefresh,dso_recnotransactionrefresh, + dso_noprepare, + dso_cacheblobs, + dso_offline, //disconnect database after open + dso_local //do not connect database on open + ]; +type + savepointoptionty = (spo_postsavepoint,spo_deletesavepoint); + savepointoptionsty = set of savepointoptionty; + + idscontroller = interface(iactivatorclient) + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheritedinsert; + procedure inheriteddelete; + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + procedure openlocal; + procedure inheritedinternaldelete; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind:filtereditkindty); + procedure endfilteredit; + procedure clearfilter; + procedure begindisplaydata; + procedure enddisplaydata; +// procedure doidleapplyupdates; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + property restorerecno: boolean read getrestorerecno write setrestorerecno; + //for refresh + function islastrecord: boolean; + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + function getsavepointoptions(): savepointoptionsty; + end; + + igetdscontroller = interface(inullinterface)[miid_igetdscontroller] + function getcontroller: tdscontroller; + end; + + fieldlinkarty = array of ifieldcomponent; + dscontrollerstatety = (dscs_posting,dscs_posting1,dscs_canceling, + dscs_deleting,dscs_refreshing, + dscs_onidleregistered, + dscs_restorerecno); + dscontrollerstatesty = set of dscontrollerstatety; + + datasetstatechangedeventty = procedure(const sender: tdataset; + const statebefore: tdatasetstate) of object; + masterdataseteventty = procedure(const sender: tdataset; + const master: tdataset) of object; + slavedataseteventty = procedure(const sender: tdataset; + const slave: tdataset) of object; + afterdbopeventty = procedure(const sender: tdataset; + var ok: boolean) of object; + epostcancel = class(eabort); + + opkindty = (opk_post,opk_delete,opk_insert); + + tdscontroller = class(tactivatorcontroller,idsfieldcontroller) + private + ffields: tpersistentfields; +// fintf: idscontroller; + frecno: integer; + frecnovalid: boolean; + fscrollsum: integer; + factiverecordbefore: integer; + fbuffercountbefore: integer; + frecnooffset: integer; + fmovebylock: boolean; + fcancelresync: boolean; + finsertbm: bookmarkty; + flinkedfields: fieldlinkarty; + fstate: dscontrollerstatesty; +// fdelayedapplycount: integer; + fbmbackup: bookmarkty; + fupdatecount: integer; + fstatebefore: tdatasetstate; + fonstatechanged: datasetstatechangedeventty; + fonupdatemasteredit: masterdataseteventty; + fonupdatemasterinsert: masterdataseteventty; + ftimer: tsimpletimer; + fonbeforepost: tdatasetnotifyevent; + fonafterpost: afterdbopeventty; + fonbeforecopyrecord: tdatasetnotifyevent; + fonaftercopyrecord: tdatasetnotifyevent; + fonbeforedelete: tdatasetnotifyevent; + fonafterdelete: afterdbopeventty; + procedure setfields(const avalue: tpersistentfields); + function getcontroller: tdscontroller; + procedure updatelinkedfields; + function getrecnozerobased: integer; + procedure setrecnozerobased(const avalue: integer); + function getrecno: integer; + procedure setrecno(const avalue: integer); +// procedure registeronidle; +// procedure unregisteronidle; +// procedure setdelayedapplycount(const avalue: integer); + function getnoedit: boolean; + procedure setnoedit(const avalue: boolean); + procedure nosavepoint; + function getasmsestring(const afieldname: string): msestring; + procedure setasmsestring(const afieldname: string; const avalue: msestring); + function getnoinsert: boolean; + procedure setnoinsert(const avalue: boolean); + function getnoappend: boolean; + procedure setnoappend(const avalue: boolean); + function getnoupdate: boolean; + procedure setnoupdate(const avalue: boolean); + function getnodelete: boolean; + procedure setnodelete(const avalue: boolean); + procedure readdelayedapplycount(reader: treader); + protected + foptions: datasetoptionsty; + procedure setoptions(const avalue: datasetoptionsty); virtual; + procedure setowneractive(const avalue: boolean); override; + procedure fielddestroyed(const sender: ifieldcomponent); +// procedure doonidle(var again: boolean); + procedure dorefresh(const sender: tobject); + function savepointbegin: integer; virtual; + procedure savepointrollback(const aindex: integer = -1); virtual; + //-1 = toplevel + procedure savepointrelease; virtual; + function execoperation(const akind: opkindty; + const aafterop: afterdbopeventty): boolean; + procedure defineproperties(filer: tfiler) override; + public + constructor create(const aowner: tdataset; const aintf: idscontroller; + const arecnooffset: integer = -1; + const acancelresync: boolean = true); + destructor destroy; override; + function isutf8: boolean; + function getfieldar(const afieldkinds: tfieldkinds = allfieldkinds): fieldarty; + function filtereditkind: filtereditkindty; + procedure beginupdate; //calls diablecontrols, stores bookmark + procedure endupdate; //restores bookmark, calls enablecontrols + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; + procedure appendrecord(const values: array of const); + procedure appendrecord1(const values: array of const; + const aisnull: array of boolean); + procedure appendrecord(const values: array of const; + const afields: array of tfield); + procedure appendrecord1(const values: array of const; + const aisnull: array of boolean; const afields: array of tfield); + procedure appendrecord(const values: variantarty); + procedure appenddata(const adata: variantararty; + const afields: array of tfield); + //[] -> all + procedure getfieldclass(const fieldtype: tfieldtype; out result: tfieldclass); + procedure beginfilteredit(const akind: filtereditkindty); + procedure clearfilter(); + procedure endfilteredit; + procedure begindisplaydata; {$ifdef FPC}inline;{$endif} + procedure enddisplaydata; {$ifdef FPC}inline;{$endif} + function getcanmodify: boolean; + function updatesortfield(const alink: tfielddatalink; + const adescend: boolean): boolean; + //true if index active + + procedure modified; + procedure dataevent(const event: tdataevent; info: ptrint); + property recno: integer read getrecno write setrecno; + property recnozerobased: integer read getrecnozerobased + write setrecnozerobased; + property recnooffset: integer read frecnooffset; + function findrecno(const arecno: integer; + const options: recnosearchoptionsty = []): integer; + function findrecnozerobased(const arecno: integer; + const options: recnosearchoptionsty = []): integer; + + function moveby(const distance: integer): integer; + function islastrecord: boolean; + procedure internalinsert; + procedure internaldelete; + procedure internalopen; + procedure internalclose; + procedure closequery(var amodalresult: modalresultty); overload; + function closequery: boolean; overload; //true if ok + function post(const aafterpost: afterdbopeventty = nil): boolean; + //calls post if in edit or insert state, + //returns true if ok +// procedure insert(const aafterinsert: afterdbopeventty = nil); + function delete(const aafterdelete: afterdbopeventty = nil): boolean; + function posting: boolean; //true if in inner post procedure + function posting1: boolean; //true if in outer post procedure + procedure postcancel; //can be called in BeforePost, calls cancel after abort + procedure cancel; + function canceling: boolean; + function refreshing(): boolean; + function deleting(): boolean; + function emptyinsert: boolean; + procedure refresh(const restorerecno: boolean = false; + const delayus: integer = -1); + //-1 -> no delay, 0 -> in onidle + procedure checkrefresh; //makes pending delayed refresh + procedure copyrecord(const aappend: boolean = false); + function copying(): boolean; + + function assql(const avalue: boolean): msestring; overload; + function assql(const avalue: msestring): msestring; overload; + function assql(const avalue: integer): msestring; overload; + function assql(const avalue: int64): msestring; overload; + function assql(const avalue: currency): msestring; overload; + function assqlcurrency(const avalue: realty): msestring; overload; + function assql(const avalue: realty): msestring; overload; + function assql(const avalue: tdatetime): msestring; overload; + function assqldate(const avalue: tdatetime): msestring; + function assqltime(const avalue: tdatetime): msestring; + + property noedit: boolean read getnoedit write setnoedit; + property noinsert: boolean read getnoinsert write setnoinsert; + property noappend: boolean read getnoappend write setnoappend; + property noupdate: boolean read getnoupdate write setnoupdate; + property nodelete: boolean read getnodelete write setnodelete; + property asmsestring[const afieldname: string]: msestring + read getasmsestring write setasmsestring; + + published + property fields: tpersistentfields read ffields write setfields; + property options: datasetoptionsty read foptions write setoptions + default defaultdscontrolleroptions; +// property delayedapplycount: integer read fdelayedapplycount +// write setdelayedapplycount default 0; + //0 -> no autoapply + property onstatechanged: datasetstatechangedeventty read fonstatechanged + write fonstatechanged; + property onupdatemasteredit: masterdataseteventty read fonupdatemasteredit + write fonupdatemasteredit; + property onupdatemasterinsert: masterdataseteventty + read fonupdatemasterinsert write fonupdatemasterinsert; + property onbeforepost: tdatasetnotifyevent read fonbeforepost + write fonbeforepost; + property onafterpost: afterdbopeventty read fonafterpost write fonafterpost; + //always called + property onbeforedelete: tdatasetnotifyevent read fonbeforedelete + write fonbeforedelete; + property onafterdelete: afterdbopeventty read fonafterdelete + write fonafterdelete; + //always called + property onbeforecopyrecord: tdatasetnotifyevent read fonbeforecopyrecord + write fonbeforecopyrecord; + property onaftercopyrecord: tdatasetnotifyevent read fonaftercopyrecord + write fonaftercopyrecord; + end; + + idbcontroller = interface(iactivatorclient)[miid_idbcontroller] + procedure setinheritedconnected(const avalue: boolean); + function readsequence(const sequencename: string): msestring; + function sequencecurrvalue(const sequencename: string): msestring; + function writesequence(const sequencename: string; + const avalue: largeint): msestring; + function ExecuteDirect(const SQL : mseString; + const aisutf8: boolean): integer; + procedure updateutf8(var autf8: boolean); + end; + + tfieldlink = class; + + tfieldlinkdatalink = class(tfielddatalink) + private + fdatasource: tdatasource; + fowner: tfieldlink; + protected + procedure updatedata; override; + public + constructor create(const aowner: tfieldlink); + destructor destroy; override; + end; + + fieldeventty = procedure(const afield: tfield) of object; + + fieldlinkoptionty = (flo_disabled,flo_onlyifnull,flo_notifunmodifiedinsert, + flo_utc); + fieldlinkoptionsty = set of fieldlinkoptionty; + + tfieldlink = class(tmsecomponent,idbeditinfo) + private + fdestdatalink: tfieldlinkdatalink; + fonupdatedata: fieldeventty; + foptions: fieldlinkoptionsty; + function getdestdataset: tdataset; + procedure setdestdataset(const avalue: tdataset); + function getdestdatafield: string; + procedure setdestdatafield(const avalue: string); + //idbeditinfo + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + function getdataset(const aindex: integer): tdataset; + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + protected + procedure updatedata(const afield: tfield); virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function field: tfield; + property enabled: boolean read getenabled write setenabled; + published + property destdataset: tdataset read getdestdataset write setdestdataset; + property destdatafield: string read getdestdatafield write setdestdatafield; + property options: fieldlinkoptionsty read foptions write foptions default []; + property onupdatedata: fieldeventty read fonupdatedata write fonupdatedata; + end; + + ttimestampfieldlink = class(tfieldlink) + protected + procedure updatedata(const afield: tfield); override; + end; + + tfieldfieldlink = class(tfieldlink,idbeditinfo) + private + fsourcedatalink: tfielddatalink; + function getfieldname: string; + procedure setfieldname(const avalue: string); + function getdatasource: tdatasource; + function getdatasource1(const aindex: integer): tdatasource; + procedure setdatasource(const avalue: tdatasource); + procedure readdatafield(reader: treader); + //idbeditinfo + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + function getdataset(const aindex: integer): tdataset; + protected + procedure updatedata(const afield: tfield); override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function sourcefield: tfield; + published + property fieldname: string read getfieldname + write setfieldname; + property datasource: tdatasource read getdatasource write setdatasource; + end; + + tparamconnector = class; + + tmseparam = class(tparam,idbeditinfo) + private + fconnector: tparamconnector; + fdatalink: tfielddatalink; + procedure setasvariant(const avalue: variant); +// function getasid: int64; +// procedure setasid(const avalue: int64); +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + function getdatasource: tdatasource; + procedure setdatasource(const avalue: tdatasource); + function getfieldname: string; + procedure setfieldname(const avalue: string); + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + function isparamstored: boolean; + procedure setconnector(const avalue: tparamconnector); + public + constructor Create(ACollection: TCollection); overload; override; + destructor destroy; override; +// property asid: int64 read getasid write setasid; //-1 -> null +// property asmsestring: msestring read getasmsestring write setasmsestring; + published + property connector: tparamconnector read fconnector write setconnector; + property datasource: tdatasource read getdatasource write setdatasource; + property fieldname: string read getfieldname write setfieldname; + property value : variant read getasvariant write setasvariant + stored isparamstored; + end; + + tparamconnector = class(tmsecomponent) + private + fparam: tmseparam; + function getparam: tmseparam; + public + destructor destroy; override; + property param: tmseparam read getparam; + end; + + tmseparams = class(tparams) + private + fisutf8: boolean; + function getitem(const index: integer): tmseparam; + procedure setitem(const index: integer; const avalue: tmseparam); + function getvalues: variantarty; + procedure setvalues(const avalue: variantarty); + public + constructor create(aowner: tpersistent); overload; + constructor create; overload; + procedure updatevalues; + Function ParseSQL(const SQL: mseString; const DoCreate: Boolean): mseString; overload; + Function ParseSQL(const SQL: mseString; + const DoCreate,EscapeSlash,EscapeRepeat: Boolean; + const ParameterStyle : TParamStyle): mseString; overload; + Function ParseSQL(const SQL: mseString; + const DoCreate,EscapeSlash,EscapeRepeat: Boolean; + const ParameterStyle : TParamStyle; + var ParamBinding: TParambinding): mseString; overload; + Function ParseSQL(const SQL: mseString; + const DoCreate,EscapeSlash,EscapeRepeat: Boolean; + const ParameterStyle : TParamStyle; var ParamBinding: TParambinding; + var ReplaceString : msestring): mseString; overload; + function expandvalues(sql: msestring; const aparambindings: tparambinding; + const aparamreplacestring: msestring): msestring; overload; + //sql parsed with psSimulated + function expandvalues(const sql: msestring): msestring; overload; + function asdbstring(const index: integer): string; + function bindnames(const anames: msestringarty): integerarty; + //returns index in anames for paramnames, -1 if not found + //case sensitive + property isutf8: boolean read fisutf8 write fisutf8; + property items[const index: integer]: tmseparam read getitem write setitem; default; + property values: variantarty read getvalues write setvalues; + end; + +const + fieldtypeclasses: array[fieldclasstypety] of fieldclassty = + (tfield,tstringfield,tguidfield,tnumericfield, + tlongintfield,tlargeintfield,tsmallintfield, + twordfield,tautoincfield,tfloatfield,tcurrencyfield, + tbooleanfield, + tdatetimefield,tdatefield,ttimefield, + tbinaryfield,tbytesfield,tvarbytesfield, + tbcdfield,tblobfield,tmemofield,tgraphicfield, + tvariantfield); + + tfieldtypetotypety: array[tfieldtype] of fieldclasstypety = ( + //ftUnknown, ftString, ftSmallint, ftInteger, ftWord, + ft_unknown,ft_string,ft_smallint,ft_longint,ft_word, + //ftBoolean, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime, + ft_boolean,ft_float,ft_currency,ft_bcd,ft_date,ft_time,ft_datetime, + //ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic, ftFmtMemo, + ft_bytes,ft_varbytes,ft_autoinc,ft_blob,ft_memo,ft_graphic,ft_memo, + //ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, ftFixedChar, + ft_unknown,ft_unknown,ft_unknown,ft_unknown,ft_string, + //ftWideString, ftLargeint, ftADT, ftArray, ftReference, + ft_string,ft_largeint,ft_unknown,ft_unknown,ft_unknown, + //ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, + ft_unknown,ft_unknown,ft_unknown,ft_variant,ft_unknown, + //ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd + ft_unknown, ft_guid,ft_unknown, ft_unknown + //ftFixedWideChar,ftWideMemo + ,ft_string, ft_string + ); + + realfcomp = [ftfloat,ftcurrency]; + datetimefcomp = [ftdate,fttime,ftdatetime]; + blobfcomp = [ftblob,ftgraphic,ftmemo]; + memofcomp = [ftmemo]; + longintfcomp = [ftboolean,ftsmallint,ftinteger,ftword]; + largeintfcomp = longintfcomp + [ftlargeint]; + stringfcomp = [ftstring,ftguid,ftfixedchar,ftwidestring,ftfixedwidechar, + ftwidememo]; + booleanfcomp = [ftboolean,ftsmallint,ftinteger,ftword]; + + fieldcompatibility: array[tfieldtype] of fieldtypesty = ( + //ftUnknown, ftString, ftSmallint, ftInteger, ftWord, + [ftunknown],stringfcomp,longintfcomp,longintfcomp,longintfcomp, + //ftBoolean, ftFloat, ftCurrency, ftBCD, + booleanfcomp,realfcomp,realfcomp,[ftbcd], + //ftDate, ftTime, tDateTime, + datetimefcomp,datetimefcomp,datetimefcomp, + //ftBytes, ftVarBytes, ftAutoInc, + [ftbytes],[ftvarbytes],[ftautoinc], + // ftBlob, ftMemo, ftGraphic, ftFmtMemo, + blobfcomp,memofcomp,blobfcomp,memofcomp, + //ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, tFixedChar, + [ftParadoxOle],[ftDBaseOle],[ftTypedBinary],[ftCursor],stringfcomp, + //ftWideString, ftLargeint, ftADT, ftArray, ftReference, + stringfcomp,[ftLargeint],[ftADT],[ftArray],[ftReference], + //ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, + [ftDataSet],[ftOraBlob],[ftOraClob],[ftVariant],[ftInterface], + //ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd); + [ftIDispatch],[ftGuid],[ftTimeStamp],[ftFMTBcd] + //ftFixedWideChar,ftWideMemo + ,stringfcomp,stringfcomp + ); + +function getdsfields(const adataset: tdataset; + const afields: array of tfield): fieldarty; + //[] -> all +function getfielddefar(const fielddefs: tfielddefs): fielddefarty; + +function getmsefieldclass(const afieldtype: tfieldtype): tfieldclass; overload; +function getmsefieldclass(const afieldtype: fieldclasstypety): tfieldclass; overload; +function fieldvariants(const afields: array of tfield): variantarty; +function fieldclasstoclasstyp(const fieldclass: fieldclassty): fieldclasstypety; +function fieldtosql(const field: tfield): msestring; +function fieldtooldsql(const field: tfield): msestring; +function paramtosql(const aparam: tparam): msestring; +function fieldchanged(const field: tfield): boolean; +function curfieldchanged(const field: tfield): boolean; +procedure fieldtoparam(const field: tfield; const param: tparam); +procedure copyfieldvalues(const source: tdataset; const dest: tdataset); +procedure msestringtoparam(const avalue: msestring; const param: tparam); +function getasmsestring(const field: tfield; const utf8: boolean = true): msestring; +procedure setasmsestring(const avalue: msestring; + const field: tfield; const utf8: boolean = true); +function checkfieldcompatibility(const afield: tfield; + const adatatype: tfieldtype): boolean; + //true if ok +function vartorealty(const avalue: variant): realty; +{ +function locaterecord(const adataset: tdataset; const autf8: boolean; + const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +function locaterecord(const adataset: tdataset; const key: integer; + const field: tfield; + const options: locateoptionsty = []): locateresultty; +} +function locaterecord(const adataset: tdataset; const fields: array of tfield; + const keys: array of const; //nil -> NULL field + const isnull: array of boolean; + const keyoptions: array of locatekeyoptionsty; + const options: locaterecordoptionsty): locateresultty; + +function encodesqlstring(const avalue: msestring): msestring; +function encodesqlcstring(const avalue: msestring): msestring; +function encodesqlblob(const avalue: string): msestring; +function encodesqlinteger(const avalue: integer): msestring; +function encodesqllongword(const avalue: longword): msestring; +function encodesqllargeint(const avalue: int64): msestring; +function encodesqlqword(const avalue: qword): msestring; +function encodesqldatetime(const avalue: tdatetime): msestring; +function encodesqldate(const avalue: tdatetime): msestring; +function encodesqltime(const avalue: tdatetime): msestring; +function encodesqlfloat(const avalue: real): msestring; +function encodesqlcurrency(const avalue: currency): msestring; +function encodesqlboolean(const avalue: boolean): msestring; +function encodesqlvariant(const avalue: variant; cstyle: boolean): msestring; + +procedure regfieldclass(const atype: fieldclasstypety; const aclass: fieldclassty); + +procedure varianttorealty(const value: variant; out dest: realty); overload; +function varianttorealty(const value: variant):realty; overload; +procedure realtytovariant(const value: realty; out dest: variant); overload; +function realtytovariant(const value: realty): variant; overload; +function varianttoid(const value: variant): int64; //null -> -1 +function idtovariant(const value: int64): variant; //-1 -> null +function varianttomsestring(const value: variant): msestring; //null -> '' +function msestringtovariant(const value: msestring): variant; //'' -> null + +function dbtrystringtoguid(const value: string; out guid: tguid): boolean; +function dbstringtoguid(const value: string): tguid; +function dbguidtostring(const avalue: tguid): string; +function dbcreateguidstring: string; +function guidparam(const value: tguid): varrecarty; + +function opentodynarrayft(const items: array of tfieldtype): fieldtypearty; + +implementation +uses + rtlconsts,msefileutils,typinfo,{$ifdef FPC}dbconst{$else}dbconst_del{$endif}, + msearrayutils,mseformatstr,msebits,msefloattostr,msebufdataset, + msereal,variants,msedate,msesys,sysconst + {,msedbgraphics}{$ifdef unix},cwstring{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +const + fieldnamedummy = ';%)(mse'; +var + msefieldtypeclasses: array[fieldclasstypety] of fieldclassty = + // ft_unknown, ft_string, ft_guid, ft_numeric, + (tmsefield,tmsestringfield,tmseguidfield,tmsenumericfield, + // ft_longint, ft_largeint, ft_smallint, + tmselongintfield,tmselargeintfield,tmsesmallintfield, + // ft_word, ft_autoinc, ft_float, ft_currency, + tmsewordfield,tmseautoincfield,tmsefloatfield,tmsecurrencyfield, + // ft_boolean, + tmsebooleanfield, + // ft_datetime, ft_date, ft_time, + tmsedatetimefield,tmsedatefield,tmsetimefield, + // ft_binary, ft_bytes, ft_varbytes, + tmsebinaryfield,tmsebytesfield,tmsevarbytesfield, + // ft_bcd, ft_blob, ft_memo, ft_graphic, + tmsebcdfield,tmseblobfield,tmsememofield,nil{tmsegraphicfield}, + // ft_variant + tmsevariantfield); + +type + tdataset1 = class(tdataset); + tfielddef1 = class(tfielddef); + tcollection1 = class(tcollection); + tparam1 = class(tparam); + tdatasource1 = class(tdatasource); + tmsebufdataset1 = class(tmsebufdataset); + tfield1 = class(tfield); + +function dbtrystringtoguid(const value: string; out guid: tguid): boolean; +var + int1: integer; + po1: pchar; + + function readbyte: byte; + var + by1: byte; + begin + by1:= hexchars[po1^]; + inc(po1); + if shortint(by1) < 0 then begin + dbtrystringtoguid:= false; + end; + result:= hexchars[po1^]; + inc(po1); + if shortint(result) < 0 then begin + dbtrystringtoguid:= false; + end; + result:= result or (by1 shl 4); + end; + + function checkhyphen: boolean; {$ifdef FPC}inline;{$endif} + begin + result:= po1^ = '-'; + inc(po1); + end; + +begin + po1:= pointer(value); + result:= length(value) = guidbuffersize; + if not result and (length(value) = guidbuffersize+2) and (value[1]='{') and + (value[guidbuffersize+2]='}') then begin + inc(po1); + result:= true; + end; + if result then begin + with {$ifndef FPC}tguid_fpc({$endif}guid{$ifndef FPC}){$endif} do begin + time_low:= (readbyte shl 24) or (readbyte shl 16) or (readbyte shl 8) or + readbyte; +{$warnings off} + if checkhyphen then begin + time_mid:= (readbyte shl 8) or readbyte; + if checkhyphen then begin + time_hi_and_version:= (readbyte shl 8) or readbyte; + if checkhyphen then begin + clock_seq_hi_and_reserved:= readbyte; + clock_seq_low:= readbyte; + if checkhyphen then begin + for int1:= 0 to high(node) do begin + node[int1]:= readbyte; + end; + end; + end; + end; + end; + end; + end; +end; +{$warnings on} + +function dbstringtoguid(const value: string): tguid; +begin + if not dbtrystringtoguid(value,result) then begin + raise econverterror.createfmt(sinvalidguid, [value]); + end; +end; + +function dbguidtostring(const avalue: tguid): string; +var + int1: integer; +begin + with {$ifndef FPC}tguid_fpc({$endif}avalue{$ifndef FPC}){$endif}do begin + result:= valtohex(time_low)+'-'+valtohex(time_mid)+'-'+ + valtohex(time_hi_and_version)+'-'+ + valtohex(clock_seq_hi_and_reserved)+valtohex(clock_seq_low)+'-'; + for int1:= 0 to high(node) do begin + result:= result+valtohex(node[int1]); + end; + end; +end; + +function dbcreateguidstring: string; +var + id: tguid; +begin + createguid(id); + result:= dbguidtostring(id); +end; + +function guidparam(const value: tguid): varrecarty; +begin + setlength(result,1); + with result[0] do begin + vtype:= mse_vtguid; + vpointer:= @value; + end; +end; + +function opentodynarrayft(const items: array of tfieldtype): fieldtypearty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function getnumdisplaytext(const sender: tnumericfield; const avalue: double; + const adisplaytext: boolean; const acurrency: boolean): string; +var + str1: ansistring; +begin + with sender do begin + if adisplaytext then begin + str1:= sender.displayformat; + if (str1 = '') and acurrency then begin + str1:= 'c'; + end; + end + else begin + str1:= editformat; + end; + end; + result:= ansistring(formatfloatmse(avalue,msestring(str1))); +end; + +procedure varianttorealty(const value: variant; out dest: realty); +begin + if varisnull(value) then begin + dest:= emptyreal; + end + else begin + real(dest):= value; + end; +end; + +function varianttorealty(const value: variant): realty; overload; +begin + if varisnull(value) then begin + result:= emptyreal; + end + else begin + real(result):= value; + end; +end; + +procedure realtytovariant(const value: realty; out dest: variant); +begin + if value = emptyreal then begin + dest:= null; + end + else begin + dest:= value; + end; +end; + +function realtytovariant(const value: realty): variant; overload; +begin + if value = emptyreal then begin + result:= null; + end + else begin + result:= value; + end; +end; + +function varianttoid(const value: variant): int64; +begin + if varisnull(value) or varisempty(value) then begin + result:= -1; + end + else begin + result:= value; + end; +end; + +function idtovariant(const value: int64): variant; +begin + if value = -1 then begin + result:= null; + end + else begin + result:= value; + end; +end; + +function varianttomsestring(const value: variant): msestring; //null -> '' +begin + if varisnull(value) or varisempty(value) then begin + result:= ''; + end + else begin + result:= value; + end; +end; + +function msestringtovariant(const value: msestring): variant; //'' -> null +begin + if value = '' then begin + result:= null; + end + else begin + result:= value; + end; +end; + +function getdsfields(const adataset: tdataset; + const afields: array of tfield): fieldarty; +var + int1: integer; +begin + if high(afields) >= 0 then begin + setlength(result,length(afields)); + for int1:= 0 to high(result) do begin + result[int1]:= afields[int1]; + end; + end + else begin + with adataset do begin + setlength(result,fields.count); + for int1:= 0 to high(result) do begin + result[int1]:= fields[int1]; + end; + end; + end; +end; + +function getfielddefar(const fielddefs: tfielddefs): fielddefarty; +var + po1: pfielddefty; + int1: integer; +begin + setlength(result,fielddefs.count); + for int1:= 0 to high(result) do begin + po1:= @result[int1]; + with fielddefs[int1] do begin + po1^.datatype:= datatype; + po1^.size:= size; + po1^.name:= name; + end; + end; +end; + +procedure regfieldclass(const atype: fieldclasstypety; + const aclass: fieldclassty); +begin + msefieldtypeclasses[atype]:= aclass; +end; + +function getmsefieldclass(const afieldtype: tfieldtype): tfieldclass; +begin + result:= msefieldtypeclasses[tfieldtypetotypety[afieldtype]]; +end; + +function getmsefieldclass(const afieldtype: fieldclasstypety): tfieldclass; +begin + result:= msefieldtypeclasses[afieldtype]; +end; + +function fieldvariants(const afields: array of tfield): variantarty; +var + int1: integer; +begin + setlength(result,length(afields)); + for int1:= 0 to high(result) do begin + result[int1]:= afields[int1].asvariant; + end; +end; + +{ +function getasmsestring(const field: tfield): msestring; +begin + if field is tmsestringfield then begin + result:= tmsestringfield(field).asmsestring; + end + else begin + if field is tmsememofield then begin + result:= tmsememofield(field).asmsestring; + end + else begin + result:= field.asstring; + end; + end; +end; +} +function getasmsestring(const field: tfield; const utf8: boolean = true): msestring; +begin + if field = nil then begin + result:= ''; + end + else begin + if field is tmsestringfield then begin + result:= tmsestringfield(field).asmsestring; + end + else begin + if field is tmsememofield then begin + result:= tmsememofield(field).asmsestring; + end + else begin + if utf8 then begin + result:= utf8tostringansi(field.asstring); + end + else begin + result:= msestring(field.asstring); + end; + end; + end; + end; +end; + +procedure setasmsestring(const avalue: msestring; + const field: tfield; const utf8: boolean = true); +begin + if field <> nil then begin + if field is tmsestringfield then begin + tmsestringfield(field).asmsestring:= avalue; + end + else begin + if field is tmsememofield then begin + tmsememofield(field).asmsestring:= avalue; + end + else begin + if utf8 then begin + field.asstring:= stringtoutf8ansi(avalue); + end + else begin + field.asstring:= ansistring(avalue); + end; + end; + end; + end; +end; + +procedure msestringtoparam(const avalue: msestring; const param: tparam); +var + intf1: igetdscontroller; +begin + with param do begin + if dataset <> nil then begin + if getcorbainterface(dataset,typeinfo(igetdscontroller),intf1) then begin + if dso_utf8 in intf1.getcontroller.options then begin + param.asstring:= stringtoutf8ansi(avalue); + exit; + end; + end; + end; + param.asstring:= ansistring(avalue); + end; +end; + +procedure fieldtoparam(const field: tfield; const param: tparam); +begin + param.value:= field.value; //paramvalue is variant anyway + { + with param do begin + case field.datatype of + ftUnknown: DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + // Need TField.AsSmallInt + ftSmallint: AsSmallInt:= Field.AsInteger; + // Need TField.AsWord + ftWord: AsWord:= Field.AsInteger; + ftInteger, + ftAutoInc: AsInteger:= Field.AsInteger; + // Need TField.AsCurrency + ftCurrency: AsCurrency:= Field.asFloat; + ftFloat: AsFloat:= Field.asFloat; + ftBoolean: AsBoolean:= Field.AsBoolean; + ftBlob, + ftGraphic..ftTypedBinary, + ftOraBlob, + ftOraClob, + ftString, + ftMemo, + ftAdt, + ftFixedChar: AsString:= Field.AsString; + ftTime, + ftDate, + ftDateTime: AsDateTime:= Field.AsDateTime; + ftBytes, + ftVarBytes: ; // Todo. + else begin + if not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then begin + DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet); + end; + end; + end; + end; + } +end; + +procedure copyfieldvalues(const source: tdataset; const dest: tdataset); +var + int1: integer; + df: tfield; +begin + for int1:= 0 to source.fieldcount-1 do begin + with source.fields[int1] do begin + if visible then begin + df:= dest.findfield(fieldname); + if (df <> nil) and not df.readonly then begin + df.value:= value; + end; + end; + end; + end; +end; + +function encodesqlstring(const avalue: msestring): msestring; +var + int1: integer; + str1: msestring; + po1: pmsechar; +begin + str1:= avalue; + setlength(result,length(str1)*2 + 2); //max + po1:= pmsechar(result); + po1^:= ''''; + inc(po1); + for int1:= 1 to length(str1) do begin + po1^:= str1[int1]; + if po1^ = '''' then begin + inc(po1); + po1^:= ''''; + end; + inc(po1); + end; + po1^:= ''''; + setlength(result,po1-pmsechar(result)+1); +end; + +function encodesqlcstring(const avalue: msestring): msestring; +var + po1: pmsechar; + innum: boolean; +begin + result:= '"'; + po1:= pmsechar(avalue); + innum:= false; + while po1^ <> #0 do begin + if (po1^ < #$20) {or (po1^ > #$ff)} or (po1^ = #$7f) then begin + innum:= true; + if po1^ < #$100 then begin + result:= result + '\x'+hextostrmse(ord(po1^),2); + end + else begin + result:= result + '\x'+hextostrmse(ord(po1^),4); + end; + end + else begin + if po1^ = '"' then begin + result:= result + '\"'; + innum:= false; + end + else begin + if innum then begin + result:= result + '" "'+po1^; + innum:= false; + end + else begin + result:= result + po1^; + end; + end; + end; + inc(po1); + end; + result:= result + '"'; +end; + +function encodesqlblob(const avalue: string): msestring; +var + int1: integer; + po1: pmsechar; + po2: pbyte; + +begin + setlength(result,length(avalue)*2+3); + po1:= pmsechar(result); + po1^:= 'x'; + inc(po1); + po1^:= ''''; + inc(po1); + po2:= pointer(avalue); + for int1:= 0 to length(avalue) - 1 do begin + po1^:= msechar(byte(charhex[po2^ shr 4])); + inc(po1); + po1^:= msechar(byte(charhex[po2^ and $0f])); + inc(po1); + inc(po2); + end; + po1^:= ''''; +end; + +function encodesqlinteger(const avalue: integer): msestring; +begin + result:= inttostrmse(avalue); +end; + +function encodesqllongword(const avalue: longword): msestring; +begin + result:= msestring(wordtostr(avalue)); +end; + +function encodesqllargeint(const avalue: int64): msestring; +begin + result:= inttostrmse(avalue); +end; + +function encodesqlqword(const avalue: qword): msestring; +begin + result:= inttostrmse(avalue); +end; + +function encodesqldatetime(const avalue: tdatetime): msestring; +begin + result := '''' + + msestring(formatdatetime('yyyy-mm-dd hh:mm:ss',avalue)) + ''''; +end; + +function encodesqldate(const avalue: tdatetime): msestring; +begin + result:= '''' + msestring(formatdatetime('yyyy-mm-dd',avalue)) + ''''; +end; + +function encodesqltime(const avalue: tdatetime): msestring; +begin + result:= '''' + msestring(formatdatetime('hh:mm:ss',avalue)) + ''''; +end; + +function encodesqlfloat(const avalue: real): msestring; +begin +// result:= floattostr(avalue,defaultformatsettingsdot); + result:= doubletostring(avalue); +// result:= replacechar(floattostr(avalue), +// defaultformatsettings.decimalseparator,'.'); +//( result:= formatfloatmse(avalue,''); +end; + +function encodesqlcurrency(const avalue: currency): msestring; +begin +// result:= formatfloat('0.####',avalue,defaultformatsettingsdot); + result:= formatfloatmse(avalue,'0.####',defaultformatsettingsmse,true); +// result:= replacechar(formatfloat('0.####',avalue), +// defaultformatsettings.decimalseparator,'.') +// result:= formatfloatmse(avalue,'0.####'); +end; + +function encodesqlboolean(const avalue: boolean): msestring; +begin + if avalue then begin + result:= '''t'''; + end + else begin + result:= '''f'''; + end; +end; + +function encodesqlvariant(const avalue: variant; + cstyle: boolean): msestring; + + function encode(const atype: word; const abase: pointer): msestring; + begin + result:= ''; + case atype of + varnull: result:= 'NULL'; + varsmallint: result:= encodesqlinteger(psmallint(abase)^); + varinteger: result:= encodesqlinteger(pinteger(abase)^); +{$ifndef FPUNONE} + varsingle: result:= encodesqlfloat(psingle(abase)^); + vardouble: result:= encodesqlfloat(pdouble(abase)^); + vardate: result:= encodesqldatetime(pdatetime(abase)^); +{$endif} + varcurrency: result:= encodesqlcurrency(pcurrency(abase)^); + varolestr: begin + if cstyle then begin + result:= encodesqlcstring(pwidestring(abase)^); + end + else begin + result:= encodesqlstring(pwidestring(abase)^); + end; + end; +// vardispatch = 9; +// varerror = 10; + varboolean: begin + if cstyle then begin + if pboolean(abase)^ then begin + result:= '"t"'; + end + else begin + result:= '"f"'; + end; + end + else begin + result:= encodesqlboolean(pboolean(abase)^); + end; + end; + varvariant: result:= encodesqlvariant(pvariant(abase)^,cstyle); +// varunknown = 13; +// vardecimal = 14; + varshortint: result:= encodesqlinteger(pshortint(abase)^); + varbyte: result:= encodesqlinteger(pbyte(abase)^); + varword: result:= encodesqlinteger(pword(abase)^); + varlongword: result:= encodesqlinteger(plongword(abase)^); + varint64: result:= encodesqllargeint(pint64(abase)^); +{$ifdef FPC} + varqword: result:= encodesqlinteger(pinteger(abase)^); +{$endif} +// varrecord = 36; + +// varstrarg = $48; + varstring: begin + if cstyle then begin + result:= encodesqlstring(msestring(pansistring(abase)^)); + end + else begin + result:= encodesqlcstring(msestring(pansistring(abase)^)); + end; + end; + end; + end; //encode + + procedure handlearray(const bounds: tvararrayboundarray; + const boundsindex: integer; + var data: pointer; const atype: word; const elementsize: integer); + var + int1: integer; + begin + if cstyle then begin + result:= result + '{'; + end + else begin + result:= result + '['; + end; + if boundsindex = 0 then begin + for int1:= 0 to bounds[boundsindex].elementcount-1 do begin + if int1 <> 0 then begin + result:= result+','; + end; + result:= result + encode(atype,data); + inc(pchar(data),elementsize); + end; + end + else begin + for int1:= 0 to bounds[boundsindex].elementcount-1 do begin + if int1 <> 0 then begin + result:= result+','; + end; + handlearray(bounds,boundsindex-1,data,atype,elementsize); + end; + end; + if cstyle then begin + result:= result + '}'; + end + else begin + result:= result + ']'; + end; + end; + +var + po1: pointer; +begin + with tvardata(avalue) do begin + if vtype and vararray <> 0 then begin + if not cstyle then begin + result:= 'ARRAY'; + end + else begin + result:= ''; + end; + with varray^ do begin + po1:= data; + handlearray(bounds,dimcount-1,po1,vtype and vartypemask,elementsize); + end; + end + else begin + cstyle:= false; + result:= encode(vtype,@vsmallint); + end; + end; +end; + +function fieldtosql(const field: tfield): msestring; +begin + if (field = nil) or field.isnull then begin + result:= 'NULL' + end + else begin + case field.datatype of + ftstring,ftguid: begin + if not (field is tmsestringfield) {or + (tmsestringfield(field).fdsintf = nil)} then begin + result:= encodesqlstring(msestring(field.asstring)); +// result:= tmsestringfield(field).assql; + end + else begin + with tmsestringfield(field) do begin + result:= encodesqlstring(asmsestring); +// result:= fdsintf.getcontroller.assql(asmsestring); + end; + end; + end; + ftmemo: begin + if field is tmsememofield then begin + result:= encodesqlstring(tmsememofield(field).asmsestring); + end + else begin + result:= encodesqlstring(msestring(field.asstring)); + end; + end; + ftblob,ftgraphic,ftbytes,ftvarbytes: begin + result:= encodesqlblob(field.asstring); + end; + ftdate: begin + result := encodesqldate(field.asdatetime) + end; + fttime: begin + result := encodesqltime(field.asdatetime) + end; + ftdatetime: begin + result:= encodesqldatetime(field.asdatetime); + end; + ftfloat,ftcurrency: begin + result:= encodesqlfloat(field.asfloat); + end; + ftbcd: begin + result:= encodesqlcurrency(field.ascurrency); + end; + ftboolean: begin + result:= encodesqlboolean(field.asboolean); + end; + ftvariant: begin + result:= encodesqlvariant(field.asvariant,false); + end; + else begin + result := msestring(field.asstring); + end; + end; + end; +end; + +function fieldtooldsql(const field: tfield): msestring; +var + statebefore: tdatasetstate; +begin + statebefore:= field.dataset.state; + tdataset1(field.dataset).settempstate(dsoldvalue); + result:= fieldtosql(field); + tdataset1(field.dataset).restorestate(statebefore); +end; + +function paramtosql(const aparam: tparam): msestring; +begin + with aparam do begin + if (aparam = nil) or isnull then begin + result:= 'NULL' + end + else begin + case datatype of + { + ftstring,ftwidestring: begin + if (aparam.collection is tmseparams) and + tmseparams(aparam.collection).isutf8 then begin + result:= encodesqlstring(stringtoutf8ansi(aswidestring)); + end + else begin + result:= encodesqlstring(asstring); + end; + end; + } + ftwidestring: begin + result:= encodesqlstring(aswidestring); + end; + ftstring,ftguid: begin + result:= encodesqlstring(msestring(asstring)); + end; + ftmemo: begin + if (aparam.collection is tmseparams) and tmseparams(collection).isutf8 then begin + result:= encodesqlstring(utf8tostringansi(asstring)); + end + else begin + result:= encodesqlstring(msestring(asstring)); + end; + end; + ftblob,ftgraphic,ftbytes,ftvarbytes: begin + result:= encodesqlblob(asstring); + end; + ftdate: begin + result := encodesqldate(asdatetime) + end; + fttime: begin + result := encodesqltime(asdatetime) + end; + ftdatetime: begin + result:= encodesqldatetime(asdatetime); + end; + ftfloat,ftcurrency: begin + result:= encodesqlfloat(asfloat); + end; + ftbcd: begin + result:= encodesqlcurrency(ascurrency); + end; + ftboolean: begin + result:= encodesqlboolean(asboolean); + end; + ftvariant: begin + result:= encodesqlvariant(value,false); + end; + else begin + result:= msestring(asstring); + end; + end; + end; + end; +end; + +function dofieldchanged(const field: tfield; const astate: tdatasetstate): boolean; + //todo: fast compare in tbufdataset +var + statebefore: tdatasetstate; + isnull: boolean; + ds1: tdataset1; + int1: integer; + bo1: boolean; + str1: string; + wstr1: widestring; + mstr1: msestring; + rea1: real; + int641: int64; + cur1: currency; +begin + result:= false; + if field.fieldno > 0 then begin + ds1:= tdataset1(field.dataset); + statebefore:= ds1.state; + isnull:= field.isnull; + if field is tmsestringfield then begin + mstr1:= tmsestringfield(field).asmsestring; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or + (mstr1 <> tmsestringfield(field).asmsestring); + end + else begin + case field.datatype of + ftString,ftFixedChar,ftmemo,ftblob,ftguid: begin + str1:= field.asstring; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or (str1 <> field.asstring); + end; + ftSmallint,ftInteger,ftWord: begin + int1:= field.asinteger; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or (int1 <> field.asinteger); + end; + ftBoolean: begin + bo1:= field.asboolean; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or (bo1 <> field.asboolean); + end; + ftFloat,ftcurrency,ftDate,ftTime,ftDateTime,ftTimeStamp,ftFMTBcd: begin + rea1:= field.asfloat; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or (rea1 <> field.asfloat); + end; + {ftCurrency,}ftBCD: begin + cur1:= field.ascurrency; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or (cur1 <> field.ascurrency); + end; + // ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic, ftFmtMemo, + // ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, + ftWideString: begin + // wstr1:= field.aswidestring; + wstr1:= widestring(field.asstring); + ds1.settempstate(astate); + // result:= (field.isnull xor isnull) or (wstr1 <> field.aswidestring); + result:= (field.isnull xor isnull) or + (wstr1 <> widestring(field.asstring)); + end; + ftLargeint: begin + int641:= tlargeintfield(field).aslargeint; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or + (int641 <> tlargeintfield(field).aslargeint); + end; + // ftADT, ftArray, ftReference, + // ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, + // ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd); + + end; + end; + ds1.restorestate(statebefore); + end; +end; + +function fieldchanged(const field: tfield): boolean; +begin + result:= dofieldchanged(field,dsoldvalue); +end; + +function curfieldchanged(const field: tfield): boolean; +begin + result:= dofieldchanged(field,dscurvalue); +end; + +function fieldclasstoclasstyp(const fieldclass: fieldclassty): fieldclasstypety; +var + type1: fieldclasstypety; +begin + result:= fieldclasstypety(-1); + for type1:= low(fieldclasstypety) to high(fieldclasstypety) do begin + if fieldclass = fieldtypeclasses[type1] then begin + result:= type1; + break; + end; + end; + if ord(result) = -1 then begin + result:= ft_unknown; + for type1:= low(fieldclasstypety) to high(fieldclasstypety) do begin + if fieldclass = msefieldtypeclasses[type1] then begin + result:= type1; + break; + end; + end; + end; +end; + +function checkfieldcompatibility(const afield: tfield; + const adatatype: tfieldtype): boolean; + //true if ok +begin + result:= (afield.datatype in fieldcompatibility[adatatype]) or + (adatatype = ftguid) and (afield.datatype = ftbytes) and + (afield.size = 16); +end; + +function vartorealty(const avalue: variant): realty; +begin + if varisnull(avalue) then begin + result:= emptyreal; + end + else begin + real(result):= avalue; + end; +end; + +procedure fieldsetmsestring(const avalue: msestring; const sender: tfield; + const aintf: idsfieldcontroller); +begin + if (aintf <> nil) and (dso_utf8 in aintf.getcontroller.options) then begin + sender.asstring:= stringtoutf8ansi(avalue); + end + else begin + sender.asstring:= ansistring(avalue); //locale conversion + end; +end; + +function fieldgetmsestring(const sender: tfield; + const aintf: idsfieldcontroller): msestring; +begin + if (aintf <> nil) and (dso_utf8 in aintf.getcontroller.options) then begin + result:= utf8tostringansi(sender.asstring); + end + else begin + {$ifdef unix} + try + result:= msestring(sender.asstring); + except + on e: eiconv do begin + //no crash by iconverror + end + else begin + raise; + end; + end; + {$else} + result:= msestring(sender.asstring); + {$endif} + end; +end; +{ +function locaterecord(const adataset: tdataset; const key: integer; + const field: tfield; + const options: locateoptionsty = []): locateresultty; +var + bm: string; +begin + with adataset do begin + checkbrowsemode; + result:= loc_notfound; + bm:= bookmark; + disablecontrols; + try + if not (loo_noforward in options) then begin + while not eof do begin + if field.asinteger = key then begin + result:= loc_ok; + exit; + end; + next; + end; + end; + bookmark:= bm; + if not (loo_nobackward in options) then begin + while true do begin + if field.asinteger = key then begin + result:= loc_ok; + exit; + end; + if bof then begin + break; + end; + prior; + end; + end; + finally + try + if result <> loc_ok then begin + bookmark:= bm; + end; + finally + enablecontrols; + end; + end; + end; +end; + +function locaterecord(const adataset: tdataset; const key: int64; + const field: tfield; + const options: locateoptionsty = []): locateresultty; +var + bm: string; +begin + with adataset do begin + checkbrowsemode; + result:= loc_notfound; + bm:= bookmark; + disablecontrols; + try + if not (loo_noforward in options) then begin + while not eof do begin + if field.aslargeint = key then begin + result:= loc_ok; + exit; + end; + next; + end; + end; + bookmark:= bm; + if not (loo_nobackward in options) then begin + while true do begin + if field.aslargeint = key then begin + result:= loc_ok; + exit; + end; + if bof then begin + break; + end; + prior; + end; + end; + finally + try + if result <> loc_ok then begin + bookmark:= bm; + end; + finally + enablecontrols; + end; + end; + end; +end; + +function locaterecord(const adataset: tdataset; const autf8: boolean; + const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +var + int2: integer; + str1,str2,bm: string; + mstr1,mstr2: msestring; + caseinsensitive: boolean; + ismsestringfield: boolean; + + function checkmsestring: boolean; + var + int1: integer; + po1,po2: pmsechar; + begin + if ismsestringfield then begin + mstr2:= tmsestringfield(field).asmsestring; + end + else begin + if autf8 then begin + mstr2:= utf8tostringansi(field.asstring); + end + else begin + mstr2:= field.asstring; + end; + end; + if caseinsensitive then begin + mstr2:= mseuppercase(mstr2); //todo: optimize + end; + if loo_posinsensitive in options then begin + result:= pos(mstr1,mstr2) > 0; + end + else begin + result:= true; + po1:= pmsechar(mstr1); + po2:= pmsechar(mstr2); + for int1:= 0 to int2 - 1 do begin + if po1[int1] <> po2[int1] then begin + result:= false; + break; + end; + if po1[int1] = #0 then begin + break; + end; + end; + end; + end; + + function checkcasesensitive: boolean; + var + int1: integer; + begin + str2:= field.asstring; + if loo_posinsensitive in options then begin + result:= pos(str1,str2) > 0; + end + else begin + result:= true; + for int1:= 0 to int2 - 1 do begin + if pchar(str1)[int1] <> pchar(str2)[int1] then begin + result:= false; + break; + end; + if pchar(str1)[int1] = #0 then begin + break; + end; + end; + end; + end; + +begin + ismsestringfield:= field is tmsestringfield; + with adataset do begin + checkbrowsemode; + result:= loc_notfound; + bm:= bookmark; + caseinsensitive:= loo_caseinsensitive in options; + if caseinsensitive or ismsestringfield then begin + if caseinsensitive then begin + mstr1:= mseuppercase(key); + end + else begin + mstr1:= key; + end; + if loo_partialkey in options then begin + int2:= length(mstr1); + end + else begin + int2:= bigint; + end; + end + else begin + if autf8 then begin + str1:= stringtoutf8ansi(key); + end + else begin + str1:= key; + end; + if loo_partialkey in options then begin + int2:= length(str1); + end + else begin + int2:= bigint; + end; + end; + disablecontrols; + try + if not (loo_noforward in options) then begin + if caseinsensitive or ismsestringfield then begin + while not eof do begin + if checkmsestring then begin + result:= loc_ok; + exit; + end; + next; + end; + end + else begin + while not eof do begin + if checkcasesensitive then begin + result:= loc_ok; + exit; + end; + next; + end; + end; + bookmark:= bm; + end; + if not (loo_nobackward in options) then begin + if caseinsensitive or ismsestringfield then begin + while true do begin + if checkmsestring then begin + result:= loc_ok; + exit; + end; + if bof then begin + break; + end; + prior; + end; + end + else begin + while true do begin + if checkcasesensitive then begin + result:= loc_ok; + exit; + end; + if bof then begin + break; + end; + prior; + end; + end; + end; + finally + try + if result <> loc_ok then begin + bookmark:= bm; + end; + finally + enablecontrols; + end; + end; + end; +end; +} +type + locatefuncty = function (const key; const afield: tfield): boolean; + +function locatenull(const key; const afield: tfield): boolean; +begin + result:= afield.isnull; +end; + +function locateinteger(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vinteger = afield.asinteger; +end; + +function locateint64(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vint64^ = afield.aslargeint; +end; + +function locateboolean(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vboolean = afield.asboolean; +end; + +function locateextended(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vextended^ = afield.asfloat; +end; + +function locatecurrency(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vcurrency^ = afield.ascurrency; +end; + +function locatevariant(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vvariant^ = afield.asvariant; +end; + +function locateansistring(const key; const afield: tfield): boolean; +begin + result:= ansistring(tvarrec(key).vansistring) = afield.asstring; +end; + +function locatemsestring(const key; const afield: tfield): boolean; +begin + result:= msestring(tvarrec(key).vwidestring) = + tmsestringfield(afield).asmsestring; +end; + +function locateansistringupper(const key; const afield: tfield): boolean; +begin + result:= ansistring(tvarrec(key).vansistring) = ansiuppercase(afield.asstring); +end; + +function locatemsestringupper(const key; const afield: tfield): boolean; +begin + result:= msestring(tvarrec(key).vwidestring) = + mseuppercase(tmsestringfield(afield).asmsestring); +end; + +function locateansistringpartial(const key; const afield: tfield): boolean; +begin + result:= ansistring(tvarrec(key).vansistring) = copy(afield.asstring,1, + length(ansistring(tvarrec(key).vansistring))); +end; + +function locatemsestringpartial(const key; const afield: tfield): boolean; +begin + result:= msestring(tvarrec(key).vwidestring) = + copy(tmsestringfield(afield).asmsestring,1, + length(msestring(tvarrec(key).vwidestring))); +end; + +function locateansistringupperpartial(const key; const afield: tfield): boolean; +begin + result:= ansistring(tvarrec(key).vansistring) = ansiuppercase(copy(afield.asstring,1, + length(ansistring(tvarrec(key).vansistring)))); +end; + +function locatemsestringupperpartial(const key; const afield: tfield): boolean; +begin + result:= msestring(tvarrec(key).vwidestring) = + mseuppercase(copy(tmsestringfield(afield).asmsestring,1, + length(msestring(tvarrec(key).vwidestring)))); +end; + +function locateansistringposins(const key; const afield: tfield): boolean; +begin + result:= pos(ansistring(tvarrec(key).vansistring),afield.asstring) > 0; +end; + +function locatemsestringposins(const key; const afield: tfield): boolean; +begin + result:= pos(msestring(tvarrec(key).vwidestring), + tmsestringfield(afield).asmsestring) > 0; +end; + +function locateansistringupperposins(const key; const afield: tfield): boolean; +begin + result:= pos(ansistring(tvarrec(key).vansistring), + ansiuppercase(afield.asstring)) > 0; +end; + +function locatemsestringupperposins(const key; const afield: tfield): boolean; +begin + result:= pos(msestring(tvarrec(key).vwidestring), + mseuppercase(tmsestringfield(afield).asmsestring)) > 0; +end; + +const + ansistringcomp: array[0..7] of locatefuncty = + ({$ifdef FPC}@{$endif}locateansistring, + {$ifdef FPC}@{$endif}locateansistringupper, + {$ifdef FPC}@{$endif}locateansistringpartial, + {$ifdef FPC}@{$endif}locateansistringupperpartial, + {$ifdef FPC}@{$endif}locateansistringposins, + {$ifdef FPC}@{$endif}locateansistringupperposins, + {$ifdef FPC}@{$endif}locateansistringposins, + {$ifdef FPC}@{$endif}locateansistringupperposins); + msestringcomp: array[0..7] of locatefuncty = + ({$ifdef FPC}@{$endif}locatemsestring, + {$ifdef FPC}@{$endif}locatemsestringupper, + {$ifdef FPC}@{$endif}locatemsestringpartial, + {$ifdef FPC}@{$endif}locatemsestringupperpartial, + {$ifdef FPC}@{$endif}locatemsestringposins, + {$ifdef FPC}@{$endif}locatemsestringupperposins, + {$ifdef FPC}@{$endif}locatemsestringposins, + {$ifdef FPC}@{$endif}locatemsestringupperposins); + +function locaterecord(const adataset: tdataset; + const fields: array of tfield; + const keys: array of const; //nil -> NULL field + const isnull: array of boolean; + const keyoptions: array of locatekeyoptionsty; + const options: locaterecordoptionsty): locateresultty; +var + comparefuncar: array of locatefuncty; + + function check: boolean; + var + int1: integer; + begin + result:= true; + for int1:= 0 to high(comparefuncar) do begin + result:= comparefuncar[int1](keys[int1],fields[int1]); + if not result then begin + break; + end; + end; + end; + +var + keymsestrings: msestringarty; + keyansistrings: stringarty; + int1: integer; + bm: bookmarkty; + opt1: locatekeyoptionsty; +begin + int1:= high(keys); + if high(fields) < int1 then begin + int1:= high(fields); + end; + inc(int1); + setlength(comparefuncar,int1); + setlength(keymsestrings,int1); + setlength(keyansistrings,int1); + + for int1:= 0 to high(comparefuncar) do begin + opt1:= []; + if int1 <= high(keyoptions) then begin + opt1:= keyoptions[int1]; + end; + if (int1 <= high(isnull)) and isnull[int1] then begin + comparefuncar[int1]:= @locatenull; + end + else begin + with tvarrec(keys[int1]) do begin + case vtype of + vtpointer: begin + comparefuncar[int1]:= @locatenull; + end; + vtinteger: begin + comparefuncar[int1]:= @locateinteger; + end; + vtint64: begin + comparefuncar[int1]:= @locateint64; + end; + vtboolean: begin + comparefuncar[int1]:= @locateboolean; + end; + vtextended: begin + if vextended^ = emptyreal then begin + comparefuncar[int1]:= @locatenull; + end + else begin + comparefuncar[int1]:= @locateextended; + end; + end; + vtcurrency: begin + comparefuncar[int1]:= @locatecurrency; + end; + {$ifdef mse_hasvtunicodestring} + vtunicodestring, + {$endif} + vtwidestring: begin + if fields[int1] is tmsestringfield then begin + comparefuncar[int1]:= msestringcomp[{$ifdef FPC}longword{$else}byte{$endif}(opt1)]; + if lko_caseinsensitive in opt1 then begin + {$ifdef mse_hasvtunicodestring} + if vtype = vtunicodestring then begin + keymsestrings[int1]:= + mseuppercase(msestring(tvarrec(keys[int1]).vunicodestring)); + pvarrec(@keys[int1])^.vunicodestring:= pointer(keymsestrings[int1]); + end + else begin + {$endif} + keymsestrings[int1]:= + mseuppercase(msestring(tvarrec(keys[int1]).vwidestring)); + pvarrec(@keys[int1])^.vwidestring:= pointer(keymsestrings[int1]); + {$ifdef mse_hasvtunicodestring} + end; + {$endif} + end + end + else begin + if lro_utf8 in options then begin + if lko_caseinsensitive in opt1 then begin + {$ifdef mse_hasvtunicodestring} + if vtype = vtunicodestring then begin + keyansistrings[int1]:= stringtoutf8ansi(mseuppercase( + msestring(tvarrec(keys[int1]).vunicodestring))); + end + else begin + {$endif} + keyansistrings[int1]:= stringtoutf8ansi(mseuppercase( + msestring(tvarrec(keys[int1]).vwidestring))); + {$ifdef mse_hasvtunicodestring} + end; + {$endif} + end + else begin + {$ifdef mse_hasvtunicodestring} + if vtype = vtunicodestring then begin + keyansistrings[int1]:= + stringtoutf8ansi(msestring(tvarrec(keys[int1]).vunicodestring)); + end + else begin + {$endif} + keyansistrings[int1]:= + stringtoutf8ansi(msestring(tvarrec(keys[int1]).vwidestring)); + {$ifdef mse_hasvtunicodestring} + end; + {$endif} + end; + end + else begin + if lko_caseinsensitive in opt1 then begin + {$ifdef mse_hasvtunicodestring} + if vtype = vtunicodestring then begin + keyansistrings[int1]:= ansistring(mseuppercase( + msestring(tvarrec(keys[int1]).vunicodestring))); + end + else begin + {$endif} + keyansistrings[int1]:= ansistring( + mseuppercase(msestring(tvarrec(keys[int1]).vwidestring))); + {$ifdef mse_hasvtunicodestring} + end; + {$endif} + end + else begin + keyansistrings[int1]:= + ansistring(msestring(tvarrec(keys[int1]).vwidestring)); + end; + end; + pvarrec(@keys[int1])^.vansistring:= pointer(keyansistrings[int1]); + comparefuncar[int1]:= + ansistringcomp[{$ifdef FPC}longword{$else}byte{$endif}(opt1)]; + end; + end; + vtansistring: begin + if fields[int1] is tmsestringfield then begin + comparefuncar[int1]:= + msestringcomp[{$ifdef FPC}longword{$else}byte{$endif}(opt1)]; + if lko_caseinsensitive in opt1 then begin + keymsestrings[int1]:= + mseuppercase(msestring( + ansistring(tvarrec(keys[int1]).vansistring))); + end + else begin + keymsestrings[int1]:= msestring( + ansistring(tvarrec(keys[int1]).vansistring)); + end; + pvarrec(@keys[int1])^.vwidestring:= pointer(keymsestrings[int1]); + end + else begin + if lko_caseinsensitive in opt1 then begin + keyansistrings[int1]:= + ansiuppercase(ansistring(tvarrec(keys[int1]).vansistring)); + pvarrec(@keys[int1])^.vansistring:= pointer(keyansistrings[int1]); + end + else begin + keyansistrings[int1]:= + ansistring(tvarrec(keys[int1]).vansistring); +// keyansistrings[int1]:= +// msestring(tvarrec(keys[int1]).vwidestring); + end; + comparefuncar[int1]:= + ansistringcomp[{$ifdef FPC}longword{$else}byte{$endif}(opt1)]; + end; + end; + vtvariant: begin + comparefuncar[int1]:= @locatevariant; + end; + else begin + raise exception.create('Invalid locate data type.'); + end; + end; + end; + end; + end; + with adataset do begin + checkbrowsemode; + result:= loc_notfound; + bm:= bookmark; + disablecontrols; + try + if not (lro_nocurrent in options) then begin + if check then begin + result:= loc_ok; + exit; + end; + end; + if not (lro_noforward in options) then begin + next; + while not eof do begin + if check then begin + result:= loc_ok; + exit; + end; + next; + end; + bookmark:= bm; + end; + if not (lro_nobackward in options) then begin + prior; + while not bof do begin + if check then begin + result:= loc_ok; + exit; + end; + prior; + end; + end; + { + if not (lro_nobackward in options) then begin + while true do begin + if check then begin + result:= loc_ok; + exit; + end; + if bof then begin + break; + end; + prior; + end; + end; + } + finally + try + if result <> loc_ok then begin + bookmark:= bm; + end; + finally + enablecontrols; + end; + end; + end; +end; + +{ tmsefield } + +function tmsefield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; +{ +procedure tmsefield.setmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsefield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsefield.Clear; +begin + setdata(nil); +end; + + +function tmsefield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +function tmsefield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsefield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsefield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; +} +procedure tmsefield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsefield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; +{ +function tmsefield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsefield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsefield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; + +{ tmsestringfield } + +destructor tmsestringfield.destroy; +begin + if fdsintf <> nil then begin + fdsintf.fielddestroyed(ifieldcomponent(self)); + end; + inherited; +end; + +function tmsestringfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsestringfield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +function tmsestringfield.getasunicodestring: unicodestring; +begin + if assigned(fgetmsestringdata) then begin + fgetmsestringdata(self,result); + end + else begin + result:= fieldgetmsestring(self,fdsintf); + end; +end; + +procedure tmsestringfield.setasnullmsestring(const avalue: msestring); +begin + if avalue = '' then begin + clear; + end + else begin + setasunicodestring(avalue); + end; +end; + +procedure tmsestringfield.setasunicodestring(const avalue: msestring); +begin + if assigned(fsetmsestringdata) then begin + fsetmsestringdata(self,avalue); + end + else begin + fieldsetmsestring(avalue,self,fdsintf); + end; +end; + +procedure tmsestringfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsestringfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsestringfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsestringfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsestringfield.setdsintf(const avalue: idsfieldcontroller); +begin + fdsintf:= avalue; +end; + +function tmsestringfield.getinstance: tfield; +begin + result:= self; +end; + +procedure tmsestringfield.Clear; +begin + setdata(nil); +end; + +function tmsestringfield.oldmsestring(out aisnull: boolean): msestring; +var + statebefore: tdatasetstate; +begin + statebefore:= tdataset1(dataset).settempstate(dsoldvalue); + aisnull:= not getdata(nil); + result:= getasunicodestring; + tdataset1(dataset).restorestate(statebefore); +end; + +function tmsestringfield.oldmsestring: msestring; +var + bo1: boolean; +begin + result:= curmsestring(bo1); +end; + +function tmsestringfield.curmsestring(out aisnull: boolean): msestring; +var + statebefore: tdatasetstate; +begin + statebefore:= tdataset1(dataset).settempstate(dscurvalue); + aisnull:= not getdata(nil); + result:= getasunicodestring; + tdataset1(dataset).restorestate(statebefore); +end; + + +function tmsestringfield.curmsestring: msestring; +var + bo1: boolean; +begin + result:= curmsestring(bo1); +end; + +procedure tmsestringfield.setismsestring(const getter: getmsestringdataty; + const setter: setmsestringdataty; const acharacterlength: integer; + const aisftwidestring: boolean); +begin + fcharacterlength:= acharacterlength; + size:= acharacterlength; + fgetmsestringdata:= getter; + fsetmsestringdata:= setter; + fisftwidestring:= aisftwidestring; +end; + +function tmsestringfield.GetDataSize: integer; +begin + if assigned(fgetmsestringdata) then begin + result:= sizeof(msestring); + end + else begin + result:= inherited getdatasize; + end; +end; + +function tmsestringfield.GetAsString: string; +begin + if assigned(fgetmsestringdata) then begin + result:= ansistring(getasunicodestring); + end + else begin + result:= inherited getasstring; + end; +end; + +function tmsestringfield.GetAsVariant: variant; +var + mstr1: msestring; +begin + if assigned(fgetmsestringdata) then begin + if fgetmsestringdata(self,mstr1) then begin + result:= mstr1; + end + else begin + result:= null; + end; + end + else begin + result:= inherited getasvariant; + end; +end; + +procedure tmsestringfield.SetAsString(const AValue: string); +begin + if assigned(fsetmsestringdata) then begin + fsetmsestringdata(self,msestring(avalue)); + end + else begin + inherited; + end; +end; + +procedure tmsestringfield.SetVarValue(const AValue: Variant); +begin + if assigned(fsetmsestringdata) then begin + fsetmsestringdata(self,avalue); + end + else begin + inherited; + end; +end; + +function tmsestringfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmsestringfield.getdefaultexpression: msestring; +begin + if inherited defaultexpression <> fdefaultexpressionbefore then begin + fdefaultexpressionbefore:= inherited defaultexpression; + fdefaultexpressionstr:= msestring(fdefaultexpressionbefore); + end; + result:= fdefaultexpressionstr; +end; + +procedure tmsestringfield.setdefaultexpression(const avalue: msestring); +begin + fdefaultexpressionstr:= avalue; + try + fdefaultexpressionbefore:= ansistring(avalue); + inherited defaultexpression:= fdefaultexpressionbefore; + except //catch conversion exception + fdefaultexpressionbefore:= ''; + inherited defaultexpression:= ''; + end; +end; +{ +function tmsestringfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsestringfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsestringfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; + +procedure tmsestringfield.dosetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,avalue,accept); + end; +end; + +{ tmsememofield } + +constructor tmsememofield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftmemo); +end; + +destructor tmsememofield.destroy; +begin + if fdsintf <> nil then begin + fdsintf.fielddestroyed(ifieldcomponent(self)); + end; + inherited; +end; + +function tmsememofield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +function tmsememofield.getasunicodestring: msestring; +begin + result:= fieldgetmsestring(self,fdsintf); +end; + +procedure tmsememofield.setasunicodestring(const avalue: msestring); +begin + fieldsetmsestring(avalue,self,fdsintf); +end; + +function tmsememofield.getaswidestring: widestring; +begin + result:= fieldgetmsestring(self,fdsintf); +end; + +procedure tmsememofield.setaswidestring(const avalue: widestring); +begin + fieldsetmsestring(avalue,self,fdsintf); +end; + +procedure tmsememofield.setdsintf(const avalue: idsfieldcontroller); +begin + fdsintf:= avalue; +end; + +function tmsememofield.getinstance: tfield; +begin + result:= self; +end; + +procedure tmsememofield.Clear; +begin + setdata(nil); +end; + +function tmsememofield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmsememofield.getasvariant: variant; +begin + if isnull then begin + result:= NULL; + end + else begin + result:= getasunicodestring; + end; +end; + +procedure tmsememofield.setvarvalue(const avalue: variant); +begin + setasunicodestring(avalue); +end; + +function tmsememofield.oldmsestring(out aisnull: boolean): msestring; +var + statebefore: tdatasetstate; +begin + statebefore:= tdataset1(dataset).settempstate(dsoldvalue); + aisnull:= getdata(nil); + result:= getasunicodestring; + tdataset1(dataset).restorestate(statebefore); +end; + +procedure tmsememofield.gettext(var thetext: string; adisplaytext: boolean); +begin + thetext:= asstring; +end; + +{ tmseguidfield } + +constructor tmseguidfield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftguid); +end; + +function tmseguidfield.getasstring: string; +var + id1: tguid; +begin + if not getdata(@id1) then begin + result:= ''; + end + else begin + result:= dbguidtostring(id1); + end; +end; + +procedure tmseguidfield.setasstring(const avalue: string); +begin + if avalue = '' then begin + clear; + end + else begin + if avalue[1] = '{' then begin + asguid:= stringtoguid(avalue); + end + else begin + asguid:= dbstringtoguid(avalue); + end; + end; +end; + +function tmseguidfield.getdefaultwidth: longint; +begin + result:= guidbuffersize; +end; + +function tmseguidfield.getasguid: tguid; +begin + if not getdata(@result) then begin + result:= GUID_NULL; + end; +end; + +procedure tmseguidfield.setasguid(const avalue: tguid); +begin + setdata(@avalue); +end; + +function tmseguidfield.getasvariant: variant; +var + id1: tguid; +begin + if not getdata(@id1) then begin + result:= null; + end + else begin + result:= dbguidtostring(id1); + end; +end; + +procedure tmseguidfield.setvarvalue(const avalue: variant); +begin + asstring:= avalue; +end; + +function tmseguidfield.getdatasize: integer; +begin + result:= sizeof(tguid); +end; + +{ tmsenumericfield } + +function tmsenumericfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsenumericfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsenumericfield.setasmsestring(const avalue: msestring); +begin + asstring:= value; +end; + +function tmsenumericfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsenumericfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsenumericfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsenumericfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsenumericfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsenumericfield.Clear; +begin + setdata(nil); +end; + +function tmsenumericfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsenumericfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsenumericfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsenumericfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsenumericfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmselongintfield } + +function tmselongintfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmselongintfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmselongintfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmselongintfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmselongintfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmselongintfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmselongintfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmselongintfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmselongintfield.getasboolean: boolean; +begin + result:= asinteger <> 0; +end; + +procedure tmselongintfield.setasboolean(avalue: boolean); +begin + if avalue then begin + asinteger:= 1; + end + else begin + asinteger:= 0; + end; +end; + +procedure tmselongintfield.Clear; +begin + setdata(nil); +end; + +procedure tmselongintfield.setasenum(const avalue: integer); +begin + if avalue = -1 then begin + clear; + end + else begin + asinteger:= avalue; + end; +end; + +function tmselongintfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +procedure tmselongintfield.setaslargeint(avalue: largeint); +begin + if (avalue < minint) or (avalue > maxint) then begin + rangeerror(avalue,minint,maxint); + end; + setaslongint(avalue); +end; + +function tmselongintfield.getaslargeint: largeint; +begin + result:= getaslongint; +end; + +function tmselongintfield.sum: integer; +var + bm: bookmarkty; + int1: integer; + intf1: idatasetsum; +begin + result:= 0; + if (dataset <> nil) and dataset.active then begin + if (fieldkind in [fkdata,fkinternalcalc]) and + getcorbainterface(dataset,typeinfo(idatasetsum),intf1) then begin + intf1.sumfield(tfield(self),result); + end + else begin + with dataset do begin + disablecontrols; + try + bm:= bookmark; + first; + while not eof do begin + if getdata(@int1) then begin + result:= result + int1; + end; + next; + end; + bookmark:= bm; + finally + enablecontrols; + end; + end; + end; + end; +end; + +procedure tmselongintfield.gettext(var thetext: string; adisplaytext: boolean); +var + int1: integer; +begin + thetext:=''; + if getdata(@int1) then begin + thetext:= getnumdisplaytext(self,int1,adisplaytext,false); + end; +end; +{ +function tmselongintfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +{ +function tmselongintfield.getasid: integer; +begin + if isnull then begin + result:= -1; + end + else begin + result:= asinteger; + end; +end; + +procedure tmselongintfield.setasid(const avalue: integer); +begin + if avalue = -1 then begin + clear; + end + else begin + asinteger:= avalue; + end; +end; +} +procedure tmselongintfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +function tmselongintfield.asoldid: integer; +var + stat1: tdatasetstate; +begin + stat1:= tdataset1(dataset).settempstate(dsoldvalue); + result:= asid; + tdataset1(dataset).restorestate(stat1); +end; + +procedure tmselongintfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmselongintfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmselargeintfield } + +function tmselargeintfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmselargeintfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmselargeintfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmselargeintfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmselargeintfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmselargeintfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmselargeintfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmselargeintfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmselargeintfield.getasboolean: boolean; +begin + result:= asinteger <> 0; +end; + +procedure tmselargeintfield.setasboolean(avalue: boolean); +begin + if avalue then begin + asinteger:= 1; + end + else begin + asinteger:= 0; + end; +end; + +procedure tmselargeintfield.Clear; +begin + setdata(nil); +end; + +function tmselargeintfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmselargeintfield.asoldid: int64; +var + stat1: tdatasetstate; +begin + stat1:= tdataset1(dataset).settempstate(dsoldvalue); + result:= asid; + tdataset1(dataset).restorestate(stat1); +end; + +procedure tmselargeintfield.gettext(var thetext: string; adisplaytext: boolean); +var + int1: int64; +begin + thetext:=''; + if getdata(@int1) then begin + thetext:= getnumdisplaytext(self,int1,adisplaytext,false); + end; +end; + +function tmselargeintfield.sum: int64; +var + bm: bookmarkty; + lint1: int64; + intf1: idatasetsum; +begin + result:= 0; + if (dataset <> nil) and dataset.active then begin + if (fieldkind in [fkdata,fkinternalcalc]) and + getcorbainterface(dataset,typeinfo(idatasetsum),intf1) then begin + intf1.sumfield(tfield(self),result); + end + else begin + with dataset do begin + disablecontrols; + try + bm:= bookmark; + first; + while not eof do begin + if getdata(@lint1) then begin + result:= result + lint1; + end; + next; + end; + bookmark:= bm; + finally + enablecontrols; + end; + end; + end; + end; +end; +{ +function tmselargeintfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +function tmselargeintfield.getasid: int64; +begin + if isnull then begin + result:= -1; + end + else begin + result:= aslargeint; + end; +end; + +procedure tmselargeintfield.setasid(const avalue: int64); +begin + if avalue = -1 then begin + clear; + end + else begin + aslargeint:= avalue; + end; +end; + +procedure tmselargeintfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmselargeintfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmselargeintfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsesmallintfield } + +function tmsesmallintfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsesmallintfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsesmallintfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsesmallintfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsesmallintfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsesmallintfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsesmallintfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsesmallintfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmsesmallintfield.getasboolean: boolean; +begin + result:= asinteger <> 0; +end; + +procedure tmsesmallintfield.setasboolean(avalue: boolean); +begin + if avalue then begin + asinteger:= 1; + end + else begin + asinteger:= 0; + end; +end; + +procedure tmsesmallintfield.setaslargeint(avalue: largeint); +begin + if (avalue < low(smallint)) or (avalue > high(smallint)) then begin + rangeerror(avalue,low(smallint),high(smallint)); + end; + setaslongint(avalue); +end; + +function tmsesmallintfield.getaslargeint: largeint; +begin + result:= getaslongint; +end; + +procedure tmsesmallintfield.Clear; +begin + setdata(nil); +end; + +function tmsesmallintfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsesmallintfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsesmallintfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsesmallintfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; + +function tmsesmallintfield.getasid: integer; +begin + if isnull then begin + result:= -1; + end + else begin + result:= asinteger; + end; +end; + +procedure tmsesmallintfield.setasid(const avalue: integer); +begin + if avalue = -1 then begin + clear; + end + else begin + asinteger:= avalue; + end; +end; +{ +function tmsesmallintfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsewordfield } + +function tmsewordfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsewordfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsewordfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsewordfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsewordfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsewordfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsewordfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsewordfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmsewordfield.getasboolean: boolean; +begin + result:= asinteger <> 0; +end; + +procedure tmsewordfield.setasboolean(avalue: boolean); +begin + if avalue then begin + asinteger:= 1; + end + else begin + asinteger:= 0; + end; +end; + +procedure tmsewordfield.setaslargeint(avalue: largeint); +begin + if (avalue < low(word)) or (avalue > high(word)) then begin + rangeerror(avalue,low(word),high(word)); + end; + setaslongint(avalue); +end; + +function tmsewordfield.getaslargeint: largeint; +begin + result:= getaslongint; +end; + +procedure tmsewordfield.Clear; +begin + setdata(nil); +end; + +function tmsewordfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsewordfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsewordfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsewordfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsewordfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmseautoincfield } + +function tmseautoincfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmseautoincfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmseautoincfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmseautoincfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmseautoincfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmseautoincfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmseautoincfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmseautoincfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmseautoincfield.Clear; +begin + setdata(nil); +end; + +function tmseautoincfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmseautoincfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmseautoincfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmseautoincfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmseautoincfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsefloatfield } + +function tmsefloatfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsefloatfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsefloatfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsefloatfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsefloatfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsefloatfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsefloatfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsefloatfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmsefloatfield.getasfloat: double; +begin + if not getdata(@result) then begin + result:= emptyreal; + end; +end; + +function tmsefloatfield.getascurrency: currency; +begin + result:= inherited getasfloat; +end; + +function tmsefloatfield.GetAsLongint: Longint; +begin + result:= round(inherited getasfloat); +end; + +function tmsefloatfield.GetAsLargeint: Largeint; +begin + result:= round(inherited getasfloat); +end; + + +procedure tmsefloatfield.setasfloat(avalue: double); +begin + if avalue = emptyreal then begin + clear; + end + else begin + inherited; + end; +end; + +procedure tmsefloatfield.Clear; +begin + setdata(nil); +end; + +function tmsefloatfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +procedure tmsefloatfield.gettext(var thetext: string; adisplaytext: boolean); +var + do1: double; +begin + thetext:=''; + if getdata(@do1) then begin + thetext:= getnumdisplaytext(self,do1,adisplaytext,currency); + end; +end; + +function tmsefloatfield.sum: double; +var + bm: bookmarkty; + do1: double; + intf1: idatasetsum; +begin + result:= 0; + if (dataset <> nil) and dataset.active then begin + if (fieldkind in [fkdata,fkinternalcalc]) and + getcorbainterface(dataset,typeinfo(idatasetsum),intf1) then begin + intf1.sumfield(self,result); + end + else begin + with dataset do begin + disablecontrols; + try + bm:= bookmark; + first; + while not eof do begin + if getdata(@do1) then begin + result:= result + do1; + end; + next; + end; + bookmark:= bm; + finally + enablecontrols; + end; + end; + end; + end; +end; +{ +function tmsefloatfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsefloatfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsefloatfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsefloatfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsecurrencyfield } + +constructor tmsecurrencyfield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftcurrency); + currency:= true; +end; + +{ tmsebooleanfield } + +constructor tmsebooleanfield.Create(AOwner: TComponent); +begin + inherited; + displayvalues:= 'True;False'; +end; + +function tmsebooleanfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsebooleanfield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +procedure tmsebooleanfield.setasunicodestring(const avalue: msestring); +var + mstr1: msestring; +begin + if avalue= '' then begin + clear; + end + else begin + mstr1:= mseuppercase(avalue); + if (mstr1 = '0') or (pos(mstr1,fdisplays[true,false]) = 1) then begin + asboolean:= false; + end + else begin + if (mstr1 = '1') or (pos(mstr1,fdisplays[true,true]) = 1) then begin + asboolean:= true; + end + else begin + DatabaseErrorFmt(SNotABoolean,[string(AValue)]); + end; + end; + end; +end; + +function tmsebooleanfield.getasunicodestring: unicodestring; +var + int1: integer; +begin + int1:= 0; + if getdata(@int1) then begin + result:= fdisplays[false,int1 <> 0] + end + else begin + result:=''; + end; +end; + +procedure tmsebooleanfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsebooleanfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsebooleanfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsebooleanfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsebooleanfield.Clear; +begin + setdata(nil); +end; + +procedure tmsebooleanfield.setdisplayvalues(const avalue: msestring); +var + ar1: msestringarty; +begin + if fdisplayvalues <> avalue then begin + ar1:= splitstring(avalue,msechar(';')); + if (high(ar1) <> 1) or (ar1[0] = ar1[1]) then begin + databaseerrorfmt(SInvalidDisplayValues,[string(avalue)]); + end; + fdisplayvalues:= avalue; + // Store display values and their uppercase equivalents; + fdisplays[false,true]:= ar1[0]; + fdisplays[true,true]:= mseUpperCase(ar1[0]); + fdisplays[false,false]:= ar1[1]; + fdisplays[true,false]:= mseuppercase(ar1[1]); + propertychanged(true); + end; +end; + +function tmsebooleanfield.getasstring: string; +begin + result:= ansistring(getasunicodestring()); +end; + +procedure tmsebooleanfield.setasstring(const avalue: string); +begin + setasunicodestring(msestring(avalue)); +end; + +function tmsebooleanfield.GetDefaultWidth: Longint; +begin + result:= length(fdisplays[false,false]); + if result < length(fdisplays[false,true]) then begin + result:= length(fdisplays[false,true]); + end; +end; + +function tmsebooleanfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmsebooleanfield.GetAsLongint: Longint; +begin + if getasboolean then begin +// result:= -1; + result:= 1; + end + else begin + result:= 0; + end; +end; + +procedure tmsebooleanfield.SetAsLongint(AValue: Longint); +begin + if avalue = 0 then begin + setasboolean(false); + end + else begin + setasboolean(true); + end; +end; + +function tmsebooleanfield.GetDataSize: integer; +begin + result:= sizeof(longbool); +end; + +function tmsebooleanfield.GetAsBoolean: Boolean; +var + int1: integer; +begin + int1:= 0; + if getdata(@int1) then begin + result:= int1 <> 0; + end + else begin + result:= false; + end; +end; + +procedure tmsebooleanfield.SetAsBoolean(AValue: Boolean); +var + int1: integer; +begin + if avalue then begin +// int1:= -1; + int1:= 1; + end + else begin + int1:= 0; + end; + setdata(@int1); +end; + +function tmsebooleanfield.GetAsVariant: variant; +var + int1: integer; +begin + int1:= 0; + if getdata(@int1) then begin + result:= int1 <> 0; + end + else begin + result:= null; + end; +end; + +function tmsebooleanfield.sum: integer; +var + bm: bookmarkty; +// int1: integer; + intf1: idatasetsum; + bo1: wordbool; +begin + result:= 0; + if (dataset <> nil) and dataset.active then begin + if (fieldkind in [fkdata,fkinternalcalc]) and + getcorbainterface(dataset,typeinfo(idatasetsum),intf1) then begin + intf1.sumfield(tfield(self),result); + end + else begin + with dataset do begin + disablecontrols; + try + bm:= bookmark; + first; + while not eof do begin + if getdata(@bo1) and bo1 then begin + inc(result); + end; + next; + end; + bookmark:= bm; + finally + enablecontrols; + end; + end; + end; + end; +end; +{ +function tmsebooleanfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsebooleanfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsebooleanfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsebooleanfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsedatetimefield } + +function tmsedatetimefield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsedatetimefield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsedatetimefield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsedatetimefield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsedatetimefield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsedatetimefield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsedatetimefield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsedatetimefield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmsedatetimefield.getasdatetime: tdatetime; +begin + if not getdata(@result,false) then begin + result:= emptydatetime; + end + else begin + if dtfo_utc in foptions then begin + result:= utctolocaltime(result); + end; + if dtfo_local in foptions then begin + result:= localtimetoutc(result); + end; + end; +end; + +procedure tmsedatetimefield.setasdatetime(avalue: tdatetime); +begin + if avalue = emptydatetime then begin + clear; + end + else begin + if dtfo_utc in foptions then begin + avalue:= localtimetoutc(avalue); + end; + if dtfo_local in foptions then begin + avalue:= utctolocaltime(avalue); + end; + inherited; + end; +end; + +procedure tmsedatetimefield.Clear; +begin + setdata(nil); +end; + +function tmsedatetimefield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +procedure tmsedatetimefield.setoptions(const avalue: datetimefieldoptionsty); +const + mask: datetimefieldoptionsty = [dtfo_utc,dtfo_local]; +begin + foptions:= datetimefieldoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); +end; + +procedure tmsedatetimefield.setasstring(const avalue: string); +begin + setasdatetime(strtodatetime(avalue)); +end; + +function tmsedatetimefield.gettext1(const r: tdatetime; + const adisplaytext: boolean): msestring; +var + f: string; +begin + if adisplaytext and (length(displayformat) <> 0) then begin + f:= displayformat; + end + else begin + case datatype of + fttime: f:= {$ifdef FPC}defaultformatsettings.{$endif}shorttimeformat; + ftdate: f:= {$ifdef FPC}defaultformatsettings.{$endif}shortdateformat; + else f:= 'c' + end; + end; + result:= formatdatetimemse(msestring(f),r); +end; + +procedure tmsedatetimefield.gettext(var thetext: string; adisplaytext: boolean); +//var +// r: tdatetime; +// f: string; +begin + if isnull then begin + thetext:= ''; + end + else begin + thetext:= ansistring(gettext1(getasdatetime,adisplaytext)); + end; +end; +{ +function tmsedatetimefield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsedatetimefield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsedatetimefield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsedatetimefield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsedatefield } + +constructor tmsedatefield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftdate); +end; + +{ tmsetimefield } + +constructor tmsetimefield.create(aowner: tcomponent); +begin + inherited; + setdatatype(fttime); +end; + +{ tmsebinaryfield } + +function tmsebinaryfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsebinaryfield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +procedure tmsebinaryfield.setasunicodestring(const avalue: msestring); +begin + asstring:= ansistring(avalue); +end; + +function tmsebinaryfield.getasunicodestring: msestring; +begin + result:= msestring(asstring); +end; + +procedure tmsebinaryfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsebinaryfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsebinaryfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsebinaryfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsebinaryfield.Clear; +begin + setdata(nil); +end; + +function tmsebinaryfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsebinaryfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsebinaryfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsebinaryfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsebinaryfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsebytesfield } + +function tmsebytesfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsebytesfield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +procedure tmsebytesfield.setasunicodestring(const avalue: unicodestring); +begin + asstring:= ansistring(avalue); +end; + +function tmsebytesfield.getasunicodestring: msestring; +begin + result:= asunicodestring; +end; + +procedure tmsebytesfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsebytesfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsebytesfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsebytesfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsebytesfield.Clear; +begin + setdata(nil); +end; + +function tmsebytesfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmsebytesfield.getasvariant: variant; +begin + if isnull then begin + result:= null; + end + else begin + result:= asstring; + end; +end; + +procedure tmsebytesfield.setasstring(const avalue: string); +var + int1,int2: integer; + str1: string; +begin + int1:= datasize; + int2:= length(avalue); + if int2 < int1 then begin + str1:= avalue; + setlength(str1,int1); + fillchar((pchar(pointer(str1))+int2)^,int1-int2,0); + setdata(pointer(str1)); + end + else begin + setdata(pointer(avalue)); + end; +end; + +function tmsebytesfield.getasstring: string; +begin + setlength(result,datasize); + if not getdata(pointer(result)) then begin + result:= ''; + end; +end; +{ +function tmsebytesfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsebytesfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsebytesfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsebytesfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsevarbytesfield } + +function tmsevarbytesfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsevarbytesfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsevarbytesfield.setasunicodestring(const avalue: unicodestring); +begin + asstring:= avalue; +end; + +function tmsevarbytesfield.getasunicodestring: unicodestring; +begin + result:= asstring; +end; +} +procedure tmsevarbytesfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsevarbytesfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; +{ +function tmsevarbytesfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsevarbytesfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; +} +procedure tmsevarbytesfield.Clear; +begin + setdata(nil); +end; + +function tmsevarbytesfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmsevarbytesfield.getasvariant: variant; +begin + if isnull then begin + result:= null; + end + else begin + result:= asstring; + end; +end; + +procedure tmsevarbytesfield.setasstring(const avalue: string); +var + int1,int2: integer; + str1: string; +begin + int1:= datasize; + int2:= length(avalue); + if int2 > int1 - sizeof(word) then begin + int2:= int1 - sizeof(word); + end; + setlength(str1,int1); + pword(pointer(str1))^:= int2; + move((pchar(pointer(avalue)))^,(pchar(pointer(str1))+sizeof(word))^,int2); + setdata(pointer(str1)); +end; + +function tmsevarbytesfield.getasstring: string; +var + wo1: word; +begin + setlength(result,datasize); + if not getdata(pointer(result)) then begin + result:= ''; + end + else begin + wo1:= pword(pointer(result))^; + move((pchar(pointer(result))+2)^,pchar(pointer(result))^,wo1); + setlength(result,wo1); + end +end; +{ +function tmsevarbytesfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsevarbytesfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsevarbytesfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsevarbytesfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsebcdfield } + +function tmsebcdfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsebcdfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsebcdfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsebcdfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsebcdfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsebcdfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsebcdfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsebcdfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsebcdfield.Clear; +begin + setdata(nil); +end; + +function tmsebcdfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +procedure tmsebcdfield.setasfloat(avalue: double); +begin + if avalue = emptyreal then begin + clear; + end + else begin + inherited; + end; +end; + +class procedure tmsebcdfield.checktypesize(avalue: longint); +begin + if (avalue < 0) or (avalue > 8) then begin + databaseerrorfmt(sinvalidfieldsize,[avalue]); + end; +end; + +procedure tmsebcdfield.gettext(var thetext: string; adisplaytext: boolean); +var + cu1: system.currency; +begin + thetext:=''; + if getdata(@cu1) then begin + thetext:= getnumdisplaytext(self,cu1,adisplaytext,currency); + end; +end; + +function tmsebcdfield.sum: currency; +var + curr1: system.currency; + bm: bookmarkty; + intf1: idatasetsum; +begin + result:= 0; + if (dataset <> nil) and dataset.active then begin + if (fieldkind in [fkdata,fkinternalcalc]) and + getcorbainterface(dataset,typeinfo(idatasetsum),intf1) then begin + intf1.sumfield(tfield(self),result); + end + else begin + with dataset do begin + disablecontrols; + try + bm:= bookmark; + first; + while not eof do begin + if getdata(@curr1) then begin + result:= result + curr1; + end; + next; + end; + bookmark:= bm; + finally + enablecontrols; + end; + end; + end; + end; +end; +{ +function tmsebcdfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsebcdfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsebcdfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsebcdfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} + +{ tmseblobfield } + +destructor tmseblobfield.destroy; +begin + freeandnil(fcache); + inherited; +end; + +function tmseblobfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmseblobfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmseblobfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmseblobfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmseblobfield.LoadFromStream(Stream: TStream); +begin + removecache; + inherited; +end; + +procedure tmseblobfield.LoadFromFile(const FileName: filenamety); +begin + if filename = '' then begin + clear; + end + else begin + removecache; + inherited loadfromfile(ansistring(tosysfilepath(filename))); + end; +end; + +procedure tmseblobfield.SaveToFile(const FileName: filenamety); +begin + inherited savetofile(ansistring(tosysfilepath(filename))); +end; + +function tmseblobfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmseblobfield.getasvariant: variant; +begin + if isnull then begin + result:= NULL; + end + else begin + result:= getasstring; + end; +end; + +procedure tmseblobfield.setcachekb(const avalue: integer); +begin + if cachekb <> avalue then begin + if avalue > 0 then begin + if fcache = nil then begin + fcache:= tblobcache.create; + end; + fcache.maxsize:= avalue * 1024; + end + else begin + freeandnil(fcache); + end; + end; +end; + +function tmseblobfield.getcachekb: integer; +begin + result:= 0; + if fcache <> nil then begin + result:= fcache.maxsize div 1024; + end; +end; +(* +function tmseblobfield.getblobid(out aid: blobidty): boolean; +begin + result:= assigned(fgetblobid); + if result then begin + fgetblobid(aid); + end; + { + aid:= 0; + case size of + 4,8: begin + result:= getdata(@aid); + end; + else begin + if size > 0 then begin + databaseerror('Invalid cache field: '''+fieldname+'''.',self); + end; + end; + end; + } +end; +*) +function tmseblobfield.getasstring: string; +var + id1: blobidty; + n1: tblobcachenode; +begin + if (fcache <> nil) and assigned(fgetblobid) then begin + result:= ''; + if fgetblobid(self,id1) then begin + if fcache.find(id1,n1) then begin + result:= n1.data; + end + else begin + result:= inherited getasstring; + fcache.addnode(id1,result); + end; + end; + end + else begin + result:= inherited getasstring; + end; +end; + +procedure tmseblobfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmseblobfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +procedure tmseblobfield.removecache(const aid: blobidty); +var + n1: tblobcachenode; +begin + if fcache <> nil then begin + if fcache.find(aid,n1) then begin + fcache.removenode(n1); + n1.free; + end; + end; +end; + +procedure tmseblobfield.removecache; +var + id1: blobidty; +begin + if assigned(fgetblobid) and fgetblobid(self,id1) then begin + removecache(id1); + end; +end; + +procedure tmseblobfield.setasstring(const avalue: string); +begin + removecache; + inherited; +end; + +procedure tmseblobfield.Clear; +begin + removecache; + inherited; +end; + +procedure tmseblobfield.clearcache; +begin + if fcache <> nil then begin + fcache.clear; + end; +end; + +procedure tmseblobfield.gettext(var atext: string; adisplaytext: boolean); +begin + if isnull then begin + atext:= '(blob)'; + end + else begin + atext:= '(BLOB)'; + end; +end; +{ +function tmseblobfield.getaswidestring: widestring; +begin + result:= getasmsestring; +end; + +procedure tmseblobfield.setaswidestring(const avalue: widestring); +begin + setasmsestring(avalue); +end; +} +{ +function tmseblobfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmseblobfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmseblobfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsevariantfield } + +function tmsevariantfield.getdatasize: integer; +begin + result:= sizeof(variant); +end; + +function tmsevariantfield.getasvariant: variant; +begin + if assigned(fgetvardata) then begin + fgetvardata(self,result); + end + else begin + result:= null; + end; +end; + +procedure tmsevariantfield.setvarvalue(const avalue: variant); +begin + if assigned(fsetvardata) then begin + fsetvardata(self,avalue); + end; +end; + +function tmsevariantfield.getasboolean: boolean; +begin + if isnull then begin + result:= false; + end + else begin + result:= getasvariant; + end; +end; + +function tmsevariantfield.getasdatetime: tdatetime; +begin + if isnull then begin + result:= emptydatetime; + end + else begin + result:= getasvariant; + end; +end; + +function tmsevariantfield.getasfloat: double; +begin + if isnull then begin + result:= emptyreal; + end + else begin + result:= getasvariant; + end; +end; + +function tmsevariantfield.getasinteger: longint; +begin + if isnull then begin + result:= 0; + end + else begin + result:= getasvariant; + end; +end; +{ +function tmsevariantfield.getasstring: string; +begin + if isnull then begin + result:= ''; + end + else begin + result:= getasvariant; + end; +end; + +function tmsevariantfield.getaswidestring: widestring; +begin + if isnull then begin + result:= ''; + end + else begin + result:= getasvariant; + end; +end; +} +function tmsevariantfield.getaslongint: longint; +begin + if isnull then begin + result:= 0; + end + else begin + result:= getasvariant; + end; +end; + +procedure tmsevariantfield.setaslongint(avalue: longint); +begin + setvarvalue(avalue); +end; + +function tmsevariantfield.getaslargeint: largeint; +begin + if isnull then begin + result:= 0; + end + else begin + result:= getasvariant; + end; +end; + +procedure tmsevariantfield.setaslargeint(avalue: largeint); +begin + setvarvalue(avalue); +end; + +function tmsevariantfield.getascurrency: currency; +begin + if isnull then begin + result:= 0; + end + else begin + result:= getasvariant; + end; +end; + +procedure tmsevariantfield.setascurrency(avalue: currency); +begin + setvarvalue(avalue); +end; + +function tmsevariantfield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +function tmsevariantfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsevariantfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsevariantfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsevariantfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tdbfieldnamearrayprop } + +constructor tdbfieldnamearrayprop.create(const afieldtypes: fieldtypesty; + const agetdatasource: getdatasourcefuncty); +begin + ffieldtypes:= afieldtypes; + fgetdatasource:= agetdatasource; + inherited create; +end; + +function tdbfieldnamearrayprop.getdataset(const aindex: integer): tdataset; +var + dso1: tdatasource; +begin + result:= nil; + dso1:= fgetdatasource(); + if dso1 <> nil then begin + result:= dso1.dataset; + end; +end; + +procedure tdbfieldnamearrayprop.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + setlength(afieldtypes,1); + afieldtypes[0]:= ffieldtypes; +end; + +{ tmsedatalink } + +procedure tmsedatalink.checkcontroller; +var + intf1: igetdscontroller; +begin + fdscontroller:= nil; + if dataset <> nil then begin + if getcorbainterface(dataset,typeinfo(igetdscontroller),intf1) then begin + fdscontroller:= intf1.getcontroller; + end; + end; +end; + +procedure tmsedatalink.activechanged; +//var +// intf1: igetdscontroller; +begin + checkcontroller; + inherited; +end; + +function tmsedatalink.getutf8: boolean; +begin + result:= (fdscontroller <> nil) and (dso_utf8 in fdscontroller.foptions); +end; + +function tmsedatalink.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; + if fdscontroller <> nil then begin + result:= fdscontroller.filtereditkind; + end; +end; + +function tmsedatalink.getdataset: tdataset; +begin + result:= nil; + if datasource <> nil then begin + result:= datasource.dataset; + end; +end; + +function tmsedatalink.moveby(distance: integer): integer; + +begin + result:= 0; + if (distance <> 0) and active then begin + if fdscontroller <> nil then begin + result:= fdscontroller.moveby(distance); + end + else begin + result:= inherited moveby(distance); + end; + end; +end; + +function tmsedatalink.GetActiveRecord: Integer; +begin + if (dataset = nil) or (csdestroying in dataset.componentstate) then begin + result:= -1; + end + else begin + result:= inherited getactiverecord; + end; +end; + +procedure tmsedatalink.DataEvent(Event: TDataEvent; Info: Ptrint); +begin + inherited; + if event = dedisabledstatechange then begin + disabledstatechange; + end; +end; + +function tmsedatalink.canclose: boolean; +begin + result:= (fcanclosing > 0) or not active; + if not result then begin + inc(fcanclosing); + try + dataset.checkbrowsemode; + result:= true; + except + application.handleexception(nil); + end; + dec(fcanclosing); + end; +end; + +function tmsedatalink.getrecnozerobased: integer; +var + ds1: tdataset; +begin + result:= -1; + if fdscontroller <> nil then begin + result:= fdscontroller.recnozerobased; + end + else begin + ds1:= dataset; + if (ds1 <> nil) and ds1.active then begin + result:= ds1.recno -1; + end; + end; +end; + +procedure tmsedatalink.setrecnozerobased(const avalue: integer); +var + ds1: tdataset; +begin + if fdscontroller <> nil then begin + fdscontroller.recnozerobased:= avalue; + end + else begin + ds1:= dataset; + if (ds1 <> nil) and ds1.active then begin + ds1.recno:= avalue + 1; + end; + end; +end; + +function tmsedatalink.noedit: boolean; +begin + result:= readonly or (dataset <> nil) and not dataset.canmodify; +end; + +function tmsedatalink.canedit: boolean; +begin + result:= active and not noedit; +end; + +function tmsedatalink.caninsert: boolean; +begin + result:= canedit and ((fdscontroller = nil) or not fdscontroller.noinsert); +end; + +function tmsedatalink.canappend: boolean; +begin + result:= canedit and ((fdscontroller = nil) or not fdscontroller.noappend); +end; + +function tmsedatalink.candelete: boolean; +begin + result:= canedit and ((fdscontroller = nil) or not fdscontroller.nodelete); +end; + +function tmsedatalink.canupdate: boolean; +begin + result:= canedit and ((fdscontroller = nil) or not fdscontroller.noupdate); +end; + +procedure tmsedatalink.disabledstatechange; +begin + //dummy +end; + +destructor tmsedatalink.destroy; +var + int1: integer; + ds1: tdataset1; +begin + int1:= 0; +{$warnings off} + ds1:= tdataset1(dataset); +{$warnings on} + if ds1 <> nil then begin + int1:= ds1.buffercount; + end; + inherited; + if (ds1 <> nil) and (ds1.buffercount < int1) then begin + ds1.dataevent(dedatasetchange,0); + end; +end; + +procedure tmsedatalink.setbuffercount(value: integer); +begin + inherited; + if active then begin + dataset.updatecursorpos(); + end; +end; + +{ tfieldsdatalink } + +procedure tfieldsdatalink.updatefields; +begin + //dummy +end; + +procedure tfieldsdatalink.activechanged; +begin + inherited; + updatefields; +end; + +procedure tfieldsdatalink.layoutchanged; +begin + inherited; + updatefields; +end; + +procedure tfieldsdatalink.fieldchanged; +begin + updateactive(); //active flag must be valid + recordchanged(nil); +end; + +procedure tfieldsdatalink.execute(const sender: iificlient); +begin +end; + +procedure tfieldsdatalink.valuechanged(const sender: iifidatalink); +begin + //dummy +end; + +procedure tfieldsdatalink.statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); +begin + if datasource <> nil then begin + tdatasource1(datasource).ifistatechanged(self,sender,astate); + end; +end; + +procedure tfieldsdatalink.setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); +begin + //dummy +end; + +procedure tfieldsdatalink.dataentered(const sender: iificlient; + const arow: integer); +begin + //dummy +end; + +procedure tfieldsdatalink.closequery(const sender: iificlient; + var amodalresult: modalresultty); +begin + //dummy +end; + +procedure tfieldsdatalink.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +begin + //dummy +end; + +procedure tfieldsdatalink.updateoptionsedit(var avalue: optionseditty); +begin + //dummy +end; + +{ tfielddatalink } + +procedure tfielddatalink.setfieldname(const Value: string); +begin + if ffieldname <> value then begin + ffieldname := value; + updatefields; + end; +end; + +procedure tfielddatalink.setfield(const value: tfield); +const + mask: fielddatalinkstatesty = [fds_ismsestring,fds_islargeint, + fds_isstring]; +var + state1: fielddatalinkstatesty; +begin + if ffield <> value then begin + ffield := value; + state1:= []; + if (ffield <> nil) then begin + if ffield is tmsestringfield then begin + include(state1,fds_ismsestring); + end; + if (ffield.datatype = ftlargeint) then begin + include(state1,fds_islargeint); + end; + if (ffield.datatype in textfields) then begin + include(state1,fds_isstring); + end; + end; + replacebits1({$ifdef FPC}longword{$else}byte{$endif}(fstate), + {$ifdef FPC}longword{$else}byte{$endif}(state1), + {$ifdef FPC}longword{$else}byte{$endif}(mask)); + fieldchanged; + editingchanged; //??? + end; +end; + +procedure tfielddatalink.updatefields; +begin + if (datasource <> nil) and (datasource.dataset <> nil) and + datasource.dataset.active and (ffieldname <> '') then begin +// if active and (ffieldname <> '') then begin + setfield(datasource.dataset.fieldbyname(ffieldname)); + end + else begin + setfield(nil); + end; +end; + +function tfielddatalink.getasmsestring: msestring; +begin + if fds_ismsestring in fstate then begin + result:= tmsestringfield(ffield).asmsestring; + end + else begin + try + if utf8 then begin + result:= utf8tostringansi(field.asstring); + end + else begin + result:= msestring(field.asstring); + end; + except + result:= converrorstring; + end; + end; +end; + +function tfielddatalink.getmsedefaultexpression: msestring; +begin + if fds_ismsestring in fstate then begin + result:= tmsestringfield(ffield).defaultexpression; + if result = #0 then begin + result:= ''; + end; + end + else begin + result:= msestring(ffield.defaultexpression); + end; +end; + +procedure tfielddatalink.setasmsestring(const avalue: msestring); +begin + if fds_ismsestring in fstate then begin + tmsestringfield(field).asmsestring:= avalue; + end + else begin + if utf8 then begin + ffield.asstring:= stringtoutf8ansi(avalue); + end + else begin + ffield.asstring:= ansistring(avalue); + end; + end; +end; + +function tfielddatalink.msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; + function defaulttext: msestring; + begin + if utf8 and (ffield.datatype in textfields) then begin + result:= utf8tostringansi(ffield.displaytext); + end + else begin + if aedit then begin + result:= msestring(ffield.text); + end + else begin + result:= msestring(ffield.displaytext); + end; + end; + end; + +begin + result:= ''; + if ffield <> nil then begin + if not ffield.isnull then begin + if fds_ismsestring in fstate then begin + result:= aformat + tmsestringfield(ffield).asmsestring; + end + else begin + if aformat <> '' then begin + case ffield.datatype of + ftsmallint,ftinteger,ftword,ftlargeint,ftbcd,ftfloat,ftcurrency: begin + result:= formatfloatmse(field.asfloat,aformat); + end; + ftboolean: begin + result:= formatfloatmse(ord(field.asboolean),aformat); + end; + ftdate,fttime,ftdatetime: begin + result:= formatdatetimemse(aformat,field.asdatetime); + end; + else begin + result:= aformat + defaulttext; + end; + end; + end + else begin + result:= defaulttext; + end; + end; + end + else begin + result:= fnullsymbol; + end; + end; +end; + +function tfielddatalink.assql: msestring; +begin + result:= fieldtosql(ffield); +end; + +procedure tfielddatalink.checkfield; +begin + if ffield = nil then begin + raise exception.create('Field is nil.'); + end; +end; + +procedure tfielddatalink.clear; +begin + checkfield; + field.clear; +end; + +function tfielddatalink.GetAsBoolean: Boolean; +begin + checkfield; + result:= field.asboolean; +end; + +procedure tfielddatalink.SetAsBoolean(const avalue: Boolean); +begin + checkfield; + field.asboolean:= avalue; +end; + +function tfielddatalink.GetAsCurrency: Currency; +begin + checkfield; + result:= field.ascurrency; +end; + +procedure tfielddatalink.SetAsCurrency(const avalue: Currency); +begin + checkfield; + field.ascurrency:= avalue; +end; + +function tfielddatalink.GetAsDateTime: TDateTime; +begin + checkfield; + result:= field.asdatetime; +end; + +procedure tfielddatalink.SetAsDateTime(const avalue: TDateTime); +begin + checkfield; + field.asdatetime:= avalue; +end; + +function tfielddatalink.GetAsFloat: Double; +begin + checkfield; + result:= field.asfloat; +end; + +procedure tfielddatalink.SetAsFloat(const avalue: Double); +begin + checkfield; + field.asfloat:= avalue; +end; + +function tfielddatalink.GetAsLongint: Longint; +begin + checkfield; + result:= field.aslongint; +end; + +procedure tfielddatalink.SetAsLongint(const avalue: Longint); +begin + checkfield; + field.aslongint:= avalue; +end; + +function tfielddatalink.GetAsLargeInt: LargeInt; +begin + checkfield; + result:= field.aslargeint; +end; + +procedure tfielddatalink.SetAsLargeInt(const avalue: LargeInt); +begin + checkfield; + field.aslargeint:= avalue; +end; + +function tfielddatalink.GetAsInteger: Integer; +begin + checkfield; + result:= field.asinteger; +end; + +procedure tfielddatalink.SetAsInteger(const avalue: Integer); +begin + checkfield; + field.asinteger:= avalue; +end; + +function tfielddatalink.GetAsString: string; +begin + checkfield; + result:= field.asstring; +end; + +procedure tfielddatalink.SetAsString(const avalue: string); +begin + checkfield; + field.asstring:= avalue; +end; + +function tfielddatalink.GetAsVariant: variant; +begin + checkfield; + result:= field.asvariant; +end; + +procedure tfielddatalink.SetAsVariant(const avalue: variant); +begin + checkfield; + field.asvariant:= avalue; +end; + +function tfielddatalink.fieldactive: boolean; +begin + result:= (ffield <> nil) and (dataset <> nil) and (dataset.state <> dsinactive); +// result:= active and (ffield <> nil); //unreliable +end; + +function tfielddatalink.getislargeint: boolean; +begin + result:= fds_islargeint in fstate; +end; + +function tfielddatalink.getismsestring: boolean; +begin + result:= fds_ismsestring in fstate; +end; + +function tfielddatalink.getisstringfield: boolean; +begin + result:= fds_isstring in fstate; +end; + +function tfielddatalink.getsortfield: tfield; +begin + if ffield = nil then begin + updatefields; + end; + result:= ffield; +end; + +procedure tfielddatalink.setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); +begin + inherited; + if ffield <> nil then begin + case sender.getifidatatype() of + dl_integer: begin + tfield1(ffield).dosetvalue(sender.getinstance,int32(avalue),accept); + end; + dl_int64: begin + tfield1(ffield).dosetvalue(sender.getinstance,int64(avalue),accept); + end; + dl_currency: begin + tfield1(ffield).dosetvalue(sender.getinstance,currency(avalue),accept); + end; + dl_real: begin + tfield1(ffield).dosetvalue(sender.getinstance,flo64(avalue),accept); + end; + dl_msestring: begin + tfield1(ffield).dosetvalue(sender.getinstance,msestring(avalue),accept); + end; + dl_ansistring: begin + tfield1(ffield).dosetvalue(sender.getinstance,ansistring(avalue),accept); + end; + end; + end; +end; + +procedure tfielddatalink.dataentered(const sender: iificlient; + const arow: integer); +begin + inherited; + if ffield <> nil then begin + tfield1(ffield).dodataentered(sender.getinstance); + end; +end; + +{ tpersistentfields } + +constructor tpersistentfields.create(const adataset: tdataset); +begin + fdataset:= adataset; + inherited create(nil); +end; + +class function tpersistentfields.getitemclasstype: persistentclassty; +begin + result:= tfield; +end; + +procedure tpersistentfields.createitem(const index: integer; + var item: tpersistent); +begin + if csloading in fdataset.componentstate then begin + item:= nil; + end + else begin + item:= tfield.create(nil); + tfield(item).dataset:= fdataset; + end; +end; + +procedure tpersistentfields.readfields(reader: treader); +var + int1: integer; + fieldtypes: fieldclasstypearty; + wantedclass: fieldclassty; + str1: string; +begin + setlength(fieldtypes,count); + int1:= 0; + reader.readlistbegin; + reader.readlistbegin; + while not reader.endoflist do begin + if int1 > high(fieldtypes) then begin + reader.readident; + //skip + end + else begin + fieldtypes[int1]:= fieldclasstypety(getenumvalue(typeinfo(fieldclasstypety), + reader.readident)); + inc(int1); + end; + end; + reader.readlistend; + for int1:= 0 to high(fieldtypes) do begin + wantedclass:= msefieldtypeclasses[fieldtypes[int1]]; + if (fitems[int1] <> nil) and (fieldtypes[int1] <> ft_unknown) and + not (tfield(fitems[int1]) is wantedclass) then begin + if (fitems[high(fitems)] = nil) then begin + moveitem(pointerarty(fitems),high(fitems),int1); //probably inserted field + end; + { + else begin + for int2:= int1+1 to high(fitems) do begin + if tfield(fitems[int2]) is wantedclass then begin + moveitem(pointerarty(fitems),int2,int1); //try to correct invalid order + break; + end; + end; + end; + } + end; + str1:= ''; + if (fitems[int1] <> nil) and (fieldtypes[int1] <> ft_unknown) and + not (tfield(fitems[int1]) is wantedclass) then begin + str1:= tfield(fitems[int1]).fieldname; + freeandnil(tfield(fitems[int1])); //there is something wrong + end; + if fitems[int1] = nil then begin + fitems[int1]:= wantedclass.create(nil); + tfield(fitems[int1]).fieldname:= str1; + end; + end; + for int1:= 0 to high(fitems) do begin + with tfield(fitems[int1]) do begin + dataset:= fdataset; + end; + end; + readcollection(reader); + reader.readlistend; +end; + +procedure tpersistentfields.writefields(writer: twriter); +var + int1: integer; + class1: fieldclassty; +begin + writer.writelistbegin; + writer.writelistbegin; + finvaliditems:= nil; + setlength(finvaliditems,count); + for int1:= 0 to high(fitems) do begin + class1:= fieldclassty(fitems[int1].classtype); + if (writer.ancestor <> nil) and + not ((writer is twritermse) and twritermse(writer).masterancestor) then begin + with tpersistentfields(writer.ancestor) do begin + if (int1 < count) then begin + if (fitems[int1].classtype <> class1) then begin + class1:= fieldclassty(fitems[int1].classtype); + //do not change inherited field type + self.finvaliditems[int1]:= true; + end + else begin + class1:= nil; + end; + end; + end; + end; + writer.writeident(getenumname(typeinfo(fieldclasstypety), + ord(fieldclasstoclasstyp(class1)))); + end; + writer.writelistend; + writecollection(writer); + finvaliditems:= nil; + writer.writelistend; +end; + +procedure tpersistentfields.defineproperties(filer: tfiler); +//var +// int1: integer; +begin + filer.defineproperty('fields',{$ifdef FPC}@{$endif}readfields, + {$ifdef FPC}@{$endif}writefields,count > 0); +end; + +procedure tpersistentfields.setitems(const index: integer; const avalue: tfield); +begin + items[index].assign(avalue); +end; + +function tpersistentfields.getitems(const index: integer): tfield; +begin + result:= tfield(inherited getitems(index)); +end; + +procedure tpersistentfields.updateorder; +var + int1: integer; + bo1: boolean; +begin + bo1:= fdataset.active; + fdataset.active:= false; + for int1:= 0 to count - 1 do begin + items[int1].index:= int1; + end; + fdataset.active:= bo1; +end; + +procedure tpersistentfields.move(const curindex: integer; const newindex: integer); +begin + inherited; + updateorder; +end; + +function tpersistentfields.getfieldnames: stringarty; +var + int1: integer; +begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= tfield(fitems[int1]).fieldname; + end; +end; + +function tpersistentfields.ispropertystored(index: integer): boolean; +begin + result:= inherited ispropertystored(index) and not finvaliditems[index]; +end; + + +{ tdscontroller } + +constructor tdscontroller.create(const aowner: tdataset; + const aintf: idscontroller; + const arecnooffset: integer = -1; + const acancelresync: boolean = true); +begin + ffields:= tpersistentfields.create(aowner); +// fintf:= aintf; + frecnooffset:= arecnooffset; + fcancelresync:= acancelresync; + foptions:= defaultdscontrolleroptions; + inherited create(aowner,aintf); + if aowner is tmsebufdataset then begin + with tmsebufdataset1(aowner) do begin + foldopts:= getdefaultoptions * oldbdsoptions; + end; + end; +end; + +destructor tdscontroller.destroy; +var + int1: integer; + field1: tfield; +begin +// unregisteronidle; + tdataset(fowner).active:= false; //avoid later calls from fowner + for int1:= 0 to high(flinkedfields) do begin + flinkedfields[int1].setdsintf(nil); + end; + flinkedfields:= nil; + with tdataset(fowner).fields do begin + for int1:= count-1 downto 0 do begin + field1:= fields[int1]; + if (field1.owner <> nil) and not + (csdestroying in field1.componentstate) then begin + field1.dataset:= nil; + end; + end; + end; + ffields.free; + freeandnil(ftimer); + inherited; +end; + +procedure tdscontroller.fielddestroyed(const sender: ifieldcomponent); +begin + removeitem(pointerarty(flinkedfields),pointer(sender)); +end; + +procedure tdscontroller.setowneractive(const avalue: boolean); +begin + tdataset(fowner).active:= avalue; +end; + +function tdscontroller.locate(const afields: array of tfield; + const akeys: array of const; + const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(tdataset(fowner),afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tdscontroller.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= locaterecord(tdataset(fowner),key,field,options); +end; + +function tdscontroller.locate(const key: int64; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= locaterecord(tdataset(fowner),key,field,options); +end; + +function tdscontroller.locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= locaterecord(tdataset(fowner),dso_utf8 in foptions,key,field,options); +end; +} +procedure tdscontroller.appendrecord1(const values: array of const; + const aisnull: array of boolean; + const afields: array of tfield); +var + int1,int2: integer; + field1: tfield; +begin + with tdataset(fowner) do begin + append; + int2:= high(values); + if int2 > high(afields) then begin + int2:= high(afields); + end; + for int1:= 0 to int2 do begin + field1:= afields[int1]; + if (int1 <= high(aisnull)) and aisnull[int1] then begin + field1.clear(); + end + else begin + with values[int1] do begin + case vtype of + vtInteger: field1.asinteger:= VInteger; + vtInt64: field1.aslargeint:= VInt64^; + vtBoolean: field1.asboolean:= VBoolean; + vtChar: field1.asstring:= VChar; + vtWideChar: field1.asstring:= ansistring(VWideChar); + vtExtended: field1.asfloat:= VExtended^; + vtString: field1.asstring:= VString^; + // vtPointer: + vtPChar: field1.asstring:= VPChar; + // vtObject: + // vtClass: + vtPWideChar: field1.asstring:= VPWideChar; + vtAnsiString: field1.asstring:= ansistring(VAnsiString); + vtCurrency: field1.ascurrency:= VCurrency^; + vtVariant: field1.asvariant:= VVariant^; + // vtInterface: + {$ifdef mse_hasvtunicodestring} + vtunicodestring: begin + if (field1 is tmsestringfield) then begin + tmsestringfield(field1).asmsestring:= msestring(vunicodestring); + end + else begin + if (field1 is tmsememofield) then begin + tmsememofield(field1).asmsestring:= msestring(vunicodestring); + end + else begin + field1.asstring:= ansistring(widestring(vunicodestring)); + end; + end; + end; + {$endif} + vtWideString: begin + if (field1 is tmsestringfield) then begin + tmsestringfield(field1).asmsestring:= msestring(vwidestring); + end + else begin + if (field1 is tmsememofield) then begin + tmsememofield(field1).asmsestring:= msestring(vwidestring); + end + else begin + field1.asstring:= ansistring(widestring(vwidestring)); + end; + end; + end; + // vtInt64: + // vtQWord: + end; + end; + end; + end; + end; +end; + +procedure tdscontroller.appendrecord(const values: array of const; + const afields: array of tfield); +begin + appendrecord1(values,[],afields); +end; + +procedure tdscontroller.appendrecord1(const values: array of const; + const aisnull: array of boolean); +var + ar1: fieldarty; + int1: integer; +begin + with tdataset(fowner) do begin + setlength(ar1,fields.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= fields[int1]; + end; + end; + appendrecord1(values,aisnull,ar1); +end; + +procedure tdscontroller.appendrecord(const values: array of const); +begin + appendrecord1(values,[]); +end; + +procedure tdscontroller.appendrecord(const values: variantarty); +var + int1: integer; +begin + with tdataset(fowner) do begin + append; + for int1:= 0 to high(values) do begin + fields[int1].value:= values[int1]; + end; + end; +end; + +procedure tdscontroller.appenddata(const adata: variantararty; const afields: array of tfield); + //[] -> all +var + int1,int2{,int3}: integer; + ar1: fieldarty; +begin + ar1:= getdsfields(tdataset(fowner),afields); + with tdataset(fowner) do begin + checkbrowsemode; + for int1:= 0 to high(adata) do begin + if state = dsinsert then begin + post; + end; + append; + for int2:= 0 to high(ar1) do begin + if int2 > high(adata[int1]) then begin + break; + end; + ar1[int2].value:= adata[int1][int2]; + end; + end; + if state = dsinsert then begin + post; + end + end; +end; + +procedure tdscontroller.setfields(const avalue: tpersistentfields); +begin + ffields.assign(avalue); +end; + +procedure tdscontroller.getfieldclass(const fieldtype: tfieldtype; out result: tfieldclass); +begin + result:= msefieldtypeclasses[tfieldtypetotypety[fieldtype]]; +end; + +function tdscontroller.getrecnozerobased: integer; +begin + with tdataset1(fowner) do begin + if bof and eof then begin + result:= -1; + end + else begin + if not frecnovalid or tdataset(fowner).filtered or + (fbuffercountbefore <> tdataset1(fowner).buffercount) then begin + fbuffercountbefore:= tdataset1(fowner).buffercount; + if bof then begin + frecno:= 0; + end + else begin + if eof then begin + frecno:= recordcount - 1; + end + else begin + frecno:= recno + frecnooffset; + end; + end; + frecnovalid:= not tdataset(fowner).filtered; + end + else begin + inc(frecno,fscrollsum + activerecord - factiverecordbefore); + end; + factiverecordbefore:= activerecord; + fscrollsum:= 0; + result:= frecno; + end; + if (state = dsinsert) and (getbookmarkflag(activebuffer) = bfeof) then begin + inc(result); //append mode + end; + end; +end; + +procedure tdscontroller.setrecnozerobased(const avalue: integer); +begin + if avalue <> getrecnozerobased then begin + tdataset1(fowner).recno:= avalue - recnooffset; + frecno:= avalue; + factiverecordbefore:= tdataset1(fowner).activerecord; + fscrollsum:= 0; + frecnovalid:= not tdataset1(fowner).filtered; + end; +{ + if not frecnovalid or (avalue <> frecno) then begin + tdataset1(fowner).recno:= avalue - recnooffset; + frecno:= avalue; + factiverecordbefore:= tdataset1(fowner).activerecord; + fscrollsum:= 0; + frecnovalid:= true; + end; + } +end; + +function tdscontroller.getrecno: integer; +begin + result:= recnozerobased - frecnooffset; +end; + +procedure tdscontroller.setrecno(const avalue: integer); +begin + recnozerobased:= avalue + frecnooffset; +end; + +function tdscontroller.findrecno(const arecno: integer; + const options: recnosearchoptionsty): integer; +begin + result:= findrecnozerobased(arecno+frecnooffset,options)-frecnooffset; +end; + +function tdscontroller.findrecnozerobased(const arecno: integer; + const options: recnosearchoptionsty = []): integer; +begin + try + recnozerobased:= arecno; + except + with tdataset(fowner) do begin + disablecontrols; + try + resync([]); + if (recnozerobased > arecno) and (rso_backward in options) then begin + prior; + end; + finally + enablecontrols; + end; + end; + end; + result:= recnozerobased; +end; + +procedure tdscontroller.updatelinkedfields; +var + int1: integer; + intf1: ifieldcomponent; + field1: tfield; +begin + with tdataset(fowner) do begin + for int1:= 0 to fields.count - 1 do begin + field1:= fields[int1]; + if getcorbainterface(field1,typeinfo(ifieldcomponent),intf1) and + (finditem(pointerarty(flinkedfields),pointer(intf1)) < 0) then begin + additem(pointerarty(flinkedfields),pointer(intf1)); + intf1.setdsintf(idsfieldcontroller(self)); + end; + end; + for int1:= high(flinkedfields) downto 0 do begin + if fields.indexof(flinkedfields[int1].getinstance) < 0 then begin + flinkedfields[int1].setdsintf(nil); + deleteitem(pointerarty(flinkedfields),int1); + end; + end; + end; +end; + +procedure tdscontroller.dataevent(const event: tdataevent; info: ptrint); +var +// field1: tfield; + state1,state2: tdatasetstate; +begin + case event of + dedatasetscroll: begin + fmovebylock:= false; + dec(fscrollsum,info); + end; + dedatasetchange,deupdatestate: begin + frecnovalid:= false; + end; + defieldlistchange: begin + updatelinkedfields; + end; + decheckbrowsemode: begin + if (dso_canceloncheckbrowsemode in foptions) and + ([dscs_posting,dscs_canceling]*fstate = []) then begin + cancel; + end; + end; + end; + if not fmovebylock or (event <> dedatasetchange) then begin + with tdataset(fowner) do begin + if (event = deupdaterecord) and not modified and (state = dsinsert) then begin + idscontroller(fintf).inheriteddataevent(event,info); //for second notnull check + end; + end; + idscontroller(fintf).inheriteddataevent(event,info); + end; + state1:= tdataset(fowner).state; + if (state1 <> fstatebefore) then begin + state2:= fstatebefore; + fstatebefore:= state1; + if checkcanevent(fowner,tmethod(fonstatechanged)) then begin + fonstatechanged(tdataset(fowner),state2); + end; + end; +end; + +procedure tdscontroller.cancel; +var + bo1: boolean; +begin + try + include(fstate,dscs_canceling); + with tdataset1(fowner) do begin + bo1:= state = dsinsert; + if bo1 then begin + dobeforescroll; + end; + if fcancelresync and (state = dsinsert) and not modified then begin + idscontroller(fintf).inheritedcancel; + try + if finsertbm <> '' then begin + bookmark:= finsertbm; + end; + except + end; + finsertbm:= ''; + end + else begin + idscontroller(fintf).inheritedcancel; + end; + if bo1 then begin + doafterscroll; + end; + end; + finally + exclude(fstate,dscs_canceling); + end; +end; + +function tdscontroller.canceling: boolean; +begin + result:= dscs_canceling in fstate; +end; + +function tdscontroller.refreshing(): boolean; +begin + result:= dscs_refreshing in fstate; +end; + +function tdscontroller.deleting(): boolean; +begin + result:= dscs_deleting in fstate; +end; + +function tdscontroller.moveby(const distance: integer): integer; +begin + with tdataset1(fowner) do begin + if (abs(distance) = 1) and (state = dsinsert) and not modified then begin + checkbrowsemode; + end + else begin + if state = dsbrowse then begin + fmovebylock:= true; + end; + try + result:= idscontroller(fintf).inheritedmoveby(distance); + if fmovebylock then begin + fmovebylock:= false; + dataevent(dedatasetscroll,0); + end; + finally + fmovebylock:= false; + end; + end; + end; +end; + +procedure tdscontroller.internalinsert; +begin + finsertbm:= tdataset(fowner).bookmark; + idscontroller(fintf).inheritedinternalinsert; +end; + +procedure tdscontroller.internaldelete; +begin + idscontroller(fintf).inheritedinternaldelete; + modified; + tdataset1(fowner).dataevent(tdataevent(de_afterdelete),0); +end; + +procedure tdscontroller.internalopen; +var + int1,int2: integer; + bo1: boolean; +// blobdatasize: integer; +begin +// blobdatasize:= fintf.getblobdatasize; + with tdataset(fowner) do begin + { + for int1:= 0 to fields.count - 1 do begin + with fields[int1] do begin + if datatype in blobfields then begin + size:= blobdatasize; + end; + end; + end; + } + for int1:= 0 to fielddefs.count - 1 do begin +{$warnings off} + with tfielddef1(fielddefs[int1]) do begin +{$warnings on} + if ffieldno = 0 then begin + ffieldno:= int1 + 1; + end; +// if fdatatype in blobfields then begin +// fsize:= blobdatasize; +// end; + end; + end; + updatelinkedfields; + bo1:= dso_waitcursor in foptions; + if bo1 then begin + application.beginwait; + end; + try +// if dso_local in foptions then begin +// idscontroller(fintf).openlocal; +// end +// else begin + idscontroller(fintf).inheritedinternalopen; +// end; + finally + if bo1 then begin + application.endwait; + end; + end; + for int1:= 0 to fields.count - 1 do begin + with fields[int1] do begin + int2:= fielddefs.indexof(fieldname); + if (int2 >= 0) and not checkfieldcompatibility(fields[int1], + fielddefs[int2].datatype) then begin + databaseerror('Datatype mismatch dataset '''+fowner.name+''' field '''+ + fieldname+''''+lineend+ + 'expected: '''+getenumname(typeinfo(tfieldtype), + ord(fielddefs[int2].datatype))+''' actual: '''+ + getenumname(typeinfo(tfieldtype),ord(datatype))+'''.'); + end; + end; + end; + updatelinkedfields; //second check + end; +{ + if fdelayedapplycount > 0 then begin + registeronidle; + end; +} +end; +{ +procedure tdscontroller.doonidle(var again: boolean); +begin + idscontroller(fintf).doidleapplyupdates; +end; +} +(* +procedure tdscontroller.registeronidle; +begin + if not(dscs_onidleregistered in fstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doonidle); + include(fstate,dscs_onidleregistered); + end; +end; + +procedure tdscontroller.unregisteronidle; +begin + if dscs_onidleregistered in fstate then begin + application.unregisteronidle({$ifdef FPC}@{$endif}doonidle); + exclude(fstate,dscs_onidleregistered); + end; +end; +*) +procedure tdscontroller.internalclose; +var + int1: integer; + field1: tfield; +begin +// unregisteronidle; + idscontroller(fintf).inheritedinternalclose; + with tdataset(fowner) do begin + for int1:= 0 to fields.count - 1 do begin + field1:= fields[int1]; + if field1 is tmseblobfield then begin + tmseblobfield(field1).clearcache; + end; + end; + end; +end; + +function tdscontroller.getcontroller: tdscontroller; +begin + result:= self; +end; + +function tdscontroller.assql(const avalue: boolean): msestring; +begin + if idscontroller(fintf).getnumboolean then begin + if avalue then begin + result:= '1'; + end + else begin + result:= '0'; + end; + end + else begin + result:= encodesqlboolean(avalue); + end; +end; + +function tdscontroller.assql(const avalue: msestring): msestring; +begin + if avalue = '' then begin + result:= 'NULL'; + end + else begin +// if dso_utf8 in foptions then begin +// result:= encodesqlstring(stringtoutf8ansi(avalue)); +// end +// else begin + result:= encodesqlstring(avalue); +// end; + end; +end; + +function tdscontroller.assql(const avalue: integer): msestring; +begin + result:= inttostrmse(avalue); +end; + +function tdscontroller.assql(const avalue: int64): msestring; +begin + result:= inttostrmse(avalue); +end; + +function tdscontroller.assql(const avalue: realty): msestring; +begin + if avalue = emptyreal then begin + result:= 'NULL'; + end + else begin + result:= realtostrmse(avalue); + end; +end; + +function tdscontroller.assqlcurrency(const avalue: realty): msestring; +begin + if avalue = emptyreal then begin + result:= 'NULL'; + end + else begin + {$ifdef FPC} + result:= assql(currency(avalue)); + {$else} + if idscontroller(fintf).getint64currency then begin + result:= inttostr(int64(ar8ty(currency(avalue)))); + end + else begin + result:= encodesqlcurrency(avalue); + end; + {$endif} + end; +end; + +function tdscontroller.assql(const avalue: currency): msestring; +begin + if idscontroller(fintf).getint64currency then begin + {$ifdef FPC} + result:= inttostrmse(int64(avalue)); + {$else} + result:= inttostrmse(int64(ar8ty(avalue))); + {$endif} + end + else begin + result:= encodesqlcurrency(avalue); + end; +end; + +function tdscontroller.assql(const avalue: tdatetime): msestring; +begin + if avalue = emptydatetime then begin + result:= 'NULL'; + end + else begin + if idscontroller(fintf).getfloatdate then begin + result:= encodesqlfloat(avalue); + end + else begin + result:= encodesqldatetime(avalue); + end; + end; +end; + +function tdscontroller.assqldate(const avalue: tdatetime): msestring; +begin + if avalue = emptydatetime then begin + result:= 'NULL'; + end + else begin + if idscontroller(fintf).getfloatdate then begin + result:= inttostrmse(trunc(avalue)); + end + else begin + result:= encodesqldate(avalue); + end; + end; +end; + +function tdscontroller.assqltime(const avalue: tdatetime): msestring; +begin + if avalue = emptydatetime then begin + result:= 'NULL'; + end + else begin + if idscontroller(fintf).getfloatdate then begin + result:= encodesqlfloat(frac(avalue)); + end + else begin + result:= encodesqltime(avalue); + end; + end; +end; + +procedure tdscontroller.closequery(var amodalresult: modalresultty); +begin + try + with tdataset(fowner) do begin; + if state in dseditmodes then begin + checkbrowsemode; + end; + end; + except + amodalresult:= mr_exception; + application.handleexception(nil); + end; +end; + +function tdscontroller.closequery: boolean; //true if ok +var + modres1: modalresultty; +begin + modres1:= mr_canclose; + closequery(modres1); + result:= modres1 = mr_canclose; +end; + +function tdscontroller.execoperation(const akind: opkindty; + const aafterop: afterdbopeventty): boolean; +var + bo1,bo2,b3: boolean; + int1: integer; + savepointoptions: savepointoptionsty; +begin +// bo3:= dscs_posting1 in fstate; + if not (dscs_posting1 in fstate) then begin + include(fstate,dscs_posting1); + b3:= dscs_deleting in fstate; + if akind = opk_delete then begin + include(fstate,dscs_deleting); + end; + try + case akind of + opk_post: begin + if checkcanevent(tdataset(fowner),tmethod(self.fonbeforepost)) then begin + fonbeforepost(tdataset(fowner)); + end; + end; + opk_delete: begin + if checkcanevent(tdataset(fowner),tmethod(self.fonbeforedelete)) then begin + fonbeforedelete(tdataset(fowner)); + end; + end; + end; + try + savepointoptions:= idscontroller(fintf).getsavepointoptions; + case akind of + opk_post: begin + bo1:= spo_postsavepoint in savepointoptions; + end; + opk_delete: begin + bo1:= spo_deletesavepoint in savepointoptions; + end; + else begin + bo1:= false; + end; + end; + try + if bo1 then begin + int1:= savepointbegin; + end; + result:= true; + include(fstate,dscs_posting); + try + try + case akind of + opk_post: begin + idscontroller(fintf).inheritedpost(); + end; + opk_delete: begin + idscontroller(fintf).inheriteddelete(); + end; + opk_insert: begin + idscontroller(fintf).inheritedinsert(); + end; + end; + except + on epostcancel do begin + if bo1 then begin + bo1:= false; + savepointrollback(int1); + end; + result:= false; + tdataset(fowner).cancel; + end + else begin + if bo1 then begin + bo1:= false; + savepointrollback(int1); + end; + raise; + end; + end; + finally + exclude(fstate,dscs_posting); + end; + bo2:= result; + try + if result and assigned(aafterop) then begin + aafterop(tdataset(fowner),result); + end; + if result then begin + if akind = opk_post then begin + tdataset1(fowner).dataevent(tdataevent(de_afterpost),0); + end; + end; + finally + if bo2 then begin + self.modified; + end; + end; + if bo1 then begin + bo1:= false; + if result then begin + savepointrelease; + end + else begin + savepointrollback(int1); + end; + end; + except + if bo1 then begin + savepointrollback(int1); + end; + raise; + end; + finally + case akind of + opk_post: begin + if checkcanevent(tdataset(fowner),tmethod(self.fonafterpost)) then begin + fonafterpost(tdataset(fowner),result); + end; + end; + opk_delete: begin + if checkcanevent(tdataset(fowner),tmethod(self.fonafterdelete)) then begin + fonafterdelete(tdataset(fowner),result); + end; + end; + end; + end; + finally + if not b3 then begin + exclude(fstate,dscs_deleting); + end; + exclude(fstate,dscs_posting1); + end; + end; +end; + +procedure tdscontroller.readdelayedapplycount(reader: treader); +var + i1: int32; +begin + i1:= reader.readinteger(); + if fowner is tmsebufdataset then begin + tmsebufdataset(fowner).delayedapplycount:= i1; + end; +end; + +procedure tdscontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('delayedapplycount',@readdelayedapplycount,nil,false); +end; + +function tdscontroller.post(const aafterpost: afterdbopeventty = nil): boolean; +begin + with tdataset(fowner) do begin + if state in dseditmodes then begin + result:= execoperation(opk_post,aafterpost); + end + else begin + result:= false; + end; + end; +end; +{ +procedure tdscontroller.insert(const aafterinsert: afterdbopeventty = nil); +begin + execoperation(opk_insert,aafterinsert); +end; +} +function tdscontroller.delete( + const aafterdelete: afterdbopeventty = nil): boolean; +begin + if tdataset(fowner).state = dsinsert then begin + cancel(); + result:= true; + end + else begin + result:= execoperation(opk_delete,aafterdelete); + end; +end; + +procedure tdscontroller.postcancel; +begin + raise epostcancel.create('Post canceled'); +end; + +function tdscontroller.emptyinsert: boolean; +begin + result:= false; + if not posting then begin + with tdataset1(fowner) do begin + if state = dsinsert then begin + DataEvent(deUpdateRecord,0); + result:= not modified; + end; + end; + end; +end; + +function tdscontroller.posting: boolean; +begin + result:= dscs_posting in fstate; +end; + +function tdscontroller.posting1: boolean; +begin + result:= dscs_posting1 in fstate; +end; + +procedure tdscontroller.modified; +begin + tdataset1(fowner).dataevent(tdataevent(de_modified),0); +end; + +procedure tdscontroller.setoptions(const avalue: datasetoptionsty); +{$ifndef FPC} +const + mask1: datasetoptionsty = [dso_autocommitret,dso_autocommit]; + mask2: datasetoptionsty = [dso_editonapplyerror,dso_cancelupdatesonerror, + dso_cancelupdateonerror,dso_cancelupdateondeleteerror]; +{$endif} +var + opt,options1{,optionsbefore}: datasetoptionsty; + bdopt: bufdatasetoptionsty; +begin + if (csreading in fowner.componentstate) and + (fowner is tmsebufdataset) then begin + with tmsebufdataset1(fowner) do begin + if card32(foldopts) <> card32($ffffffff) then begin //old streaming version + bdopt:= []; + if dso_postsavepoint in avalue then include(bdopt,bdo_postsavepoint); + if dso_postsavepoint in avalue then include(bdopt,bdo_postsavepoint); + if dso_deletesavepoint in avalue then include(bdopt,bdo_deletesavepoint); + if dso_cancelupdateonerror in avalue then include(bdopt,bdo_cancelupdateonerror); + if dso_cancelupdatesonerror in avalue then include(bdopt,bdo_cancelupdatesonerror); + if dso_cancelupdateondeleteerror in avalue then include(bdopt,bdo_cancelupdateondeleteerror); + if dso_editonapplyerror in avalue then include(bdopt,bdo_editonapplyerror); + if dso_restoreupdateonsavepointrollback in avalue then include(bdopt,bdo_restoreupdateonsavepointrollback); + if dso_noapply in avalue then include(bdopt,bdo_noapply); + if dso_autoapply in avalue then include(bdopt,bdo_autoapply); + if dso_autocommitret in avalue then include(bdopt,bdo_autocommitret); + if dso_autocommit in avalue then include(bdopt,bdo_autocommit); + if dso_refreshafterapply in avalue then include(bdopt,bdo_refreshafterapply); + if dso_recnoapplyrefresh in avalue then include(bdopt,bdo_recnoapplyrefresh); + if dso_refreshtransaction in avalue then include(bdopt,bdo_refreshtransaction); + if dso_notransactionrefresh in avalue then include(bdopt,bdo_notransactionrefresh); + if dso_recnotransactionrefresh in avalue then include(bdopt,bdo_recnotransactionrefresh); + if dso_noprepare in avalue then include(bdopt,bdo_noprepare); + if dso_cacheblobs in avalue then include(bdopt,bdo_cacheblobs); + if dso_offline in avalue then include(bdopt,bdo_offline); + if dso_local in avalue then include(bdopt,bdo_local); + foldopts:= bdopt; + end; + end; + end; +// optionsbefore:= foptions; + opt:= avalue; + if dso_refreshwaitcursor in avalue then begin + include(opt,dso_waitcursor); + end; + opt:= opt - [dso_refreshwaitcursor]-deprecatedbdsoptions; + options1:= datasetoptionsty(longword(foptions) xor longword(opt)); + foptions:= opt; +(* +{$ifdef FPC} + foptions:= datasetoptionsty(setsinglebit(longword(opt),longword(foptions), + [longword([dso_autocommitret,dso_autocommit]), + longword([dso_editonapplyerror,dso_cancelupdatesonerror, + dso_cancelupdateonerror,dso_cancelupdateondeleteerror])])); +{$else} + foptions:= datasetoptionsty(setsinglebitar32(longword(opt),longword(foptions), + [longword(mask1),longword(mask2)])); +{$endif} +*) + if [dso_noedit,dso_noinsert,dso_noappend,dso_noupdate,dso_nodelete] * + options1 <> [] then begin + if ([dso_noedit,dso_noupdate] * opt <> []) and + tdataset(fowner).active then begin + tdataset(fowner).checkbrowsemode; + end; + tdataset1(fowner).dataevent(dedisabledstatechange,0); + end; +{ + if optionsbefore <> foptions then begin + idscontroller(fintf).dscontrolleroptionschanged(foptions); + end; +} +end; + +function tdscontroller.isutf8: boolean; +begin + result:= dso_utf8 in foptions; +end; + +function tdscontroller.filtereditkind: filtereditkindty; +begin + result:= idscontroller(fintf).getfiltereditkind; +end; + +procedure tdscontroller.beginupdate; //calls diablecontrols, stores bookmark +begin + with tdataset(fowner) do begin + if fupdatecount = 0 then begin + fbmbackup:= bookmark; + end; + inc(fupdatecount); + disablecontrols; + end; +end; + +procedure tdscontroller.endupdate; //restores bookmark, calls enablecontrols +begin + with tdataset(fowner) do begin + dec(fupdatecount); + if fupdatecount = 0 then begin + bookmark:= fbmbackup; + end; + enablecontrols; + end; +end; + +procedure tdscontroller.beginfilteredit(const akind: filtereditkindty); +begin + idscontroller(fintf).beginfilteredit(akind); +end; + +procedure tdscontroller.clearfilter; +begin + idscontroller(fintf).clearfilter; +end; + +procedure tdscontroller.endfilteredit; +begin + idscontroller(fintf).endfilteredit; +end; + +function tdscontroller.getfieldar( + const afieldkinds: tfieldkinds = allfieldkinds): fieldarty; +var + int1,int2: integer; +begin + with tdataset(fowner).fields do begin + setlength(result,count); + int2:= 0; + for int1:= 0 to high(result) do begin + result[int2]:= fields[int1]; + if result[int2].fieldkind in afieldkinds then begin + inc(int2); + end; + end; + setlength(result,int2); + end; +end; +{ +procedure tdscontroller.setdelayedapplycount(const avalue: integer); +begin + if fdelayedapplycount <> avalue then begin + if tdataset(fowner).active and not (csloading in fowner.componentstate) then begin + if fdelayedapplycount > 0 then begin + fdelayedapplycount:= 1; + idscontroller(fintf).doidleapplyupdates; //apply pending updates. + end; + fdelayedapplycount:= avalue; + if avalue > 0 then begin + registeronidle; + end + else begin + unregisteronidle; + end; + end + else begin + fdelayedapplycount:= avalue; + end; + end; +end; +} +function tdscontroller.getnoedit: boolean; +begin + result:= dso_noedit in foptions; +end; + +procedure tdscontroller.setnoedit(const avalue: boolean); +begin + if avalue then begin + options:= options + [dso_noedit]; + end + else begin + options:= options - [dso_noedit]; + end; +end; + +function tdscontroller.getnoinsert: boolean; +begin + result:= dso_noinsert in foptions; +end; + +procedure tdscontroller.setnoinsert(const avalue: boolean); +begin + if avalue then begin + options:= options + [dso_noinsert]; + end + else begin + options:= options - [dso_noinsert]; + end; +end; + +function tdscontroller.getnoappend: boolean; +begin + result:= dso_noappend in foptions; +end; + +procedure tdscontroller.setnoappend(const avalue: boolean); +begin + if avalue then begin + options:= options + [dso_noappend]; + end + else begin + options:= options - [dso_noappend]; + end; +end; + +function tdscontroller.getnoupdate: boolean; +begin + result:= dso_noupdate in foptions; +end; + +procedure tdscontroller.setnoupdate(const avalue: boolean); +begin + if avalue then begin + options:= options + [dso_noupdate]; + end + else begin + options:= options - [dso_noupdate]; + end; +end; + +function tdscontroller.getnodelete: boolean; +begin + result:= dso_nodelete in foptions; +end; + +procedure tdscontroller.setnodelete(const avalue: boolean); +begin + if avalue then begin + options:= options + [dso_nodelete]; + end + else begin + options:= options - [dso_nodelete]; + end; +end; + +function tdscontroller.getcanmodify: boolean; +begin + result:= not (dso_noedit in foptions); +end; + +procedure tdscontroller.dorefresh(const sender: tobject); +var + bo1,bo2,bo3: boolean; +begin + if (sender = nil) or //not delayed + (tdataset(fowner).state = dsbrowse) then begin + bo2:= dso_waitcursor in foptions; + bo3:= dscs_refreshing in fstate; + if bo2 then begin + application.beginwait; + end; + try + if not tdataset(fowner).active then begin + tdataset(fowner).open; + end + else begin + if dscs_restorerecno in fstate then begin + exclude(fstate,dscs_restorerecno); + bo1:= idscontroller(fintf).restorerecno; + idscontroller(fintf).restorerecno:= true; + try + tdataset(fowner).refresh; + finally + if not bo1 then begin + idscontroller(fintf).restorerecno:= false; + end; + end; + end + else begin + tdataset(fowner).refresh; + end; + end; + finally + if bo2 then begin + application.endwait; + end; + if not bo3 then begin + exclude(fstate,dscs_refreshing); + end; + end; + end; +end; + +procedure tdscontroller.refresh(const restorerecno: boolean; + const delayus: integer = -1); +begin + if restorerecno then begin + include(fstate,dscs_restorerecno); + end; + if delayus < 0 then begin + freeandnil(ftimer); + dorefresh(nil); + end + else begin + if ftimer = nil then begin + ftimer:= tsimpletimer.create(delayus,{$ifdef FPC}@{$endif}dorefresh, + true,[to_single]); + end + else begin + ftimer.interval:= delayus; //single shot + ftimer.enabled:= true; + end; + end; +end; + +procedure tdscontroller.checkrefresh; //makes pending delayed refresh +begin + if ftimer <> nil then begin + ftimer.firependingandstop; //cancel wait + end; +end; + +function tdscontroller.islastrecord: boolean; +begin + with tdataset1(fowner) do begin + result:= eof; + if not result then begin + if filtered then begin + settempstate(state); + try + next; + result:= eof; + if not result then begin + prior; + end; + finally + restorestate(state); + end; + end + else begin + result:= idscontroller(fintf).islastrecord; + end; + end; + end; +end; + +procedure tdscontroller.nosavepoint; +begin + raise exception.create('Savepoints not supported.'); +end; + +function tdscontroller.savepointbegin: integer; +begin + result:= -1; + nosavepoint; +end; + +procedure tdscontroller.savepointrollback(const aindex: integer); +begin + nosavepoint; +end; + +procedure tdscontroller.savepointrelease; +begin + nosavepoint; +end; + +function tdscontroller.updatesortfield(const alink: tfielddatalink; + const adescend: boolean): boolean; +var + field1: tfield; +begin + field1:= nil; + if alink <> nil then begin + field1:= alink.sortfield; + end; + result:= idscontroller(fintf).updatesortfield(field1,adescend); +end; + +function tdscontroller.getasmsestring(const afieldname: string): msestring; +var + field1: tfield; +begin + field1:= tdataset(fowner).fieldbyname(afieldname); + if field1 is tmsestringfield then begin + result:= tmsestringfield(field1).asmsestring; + end + else begin + if field1 is tmsememofield then begin + result:= tmsememofield(field1).asmsestring; + end + else begin + if isutf8 then begin + result:= utf8tostringansi(field1.asstring); + end + else begin + result:= msestring(field1.asstring); + end; + end; + end; +end; + +procedure tdscontroller.setasmsestring(const afieldname: string; + const avalue: msestring); +var + field1: tfield; +begin + field1:= tdataset(fowner).fieldbyname(afieldname); + if field1 is tmsestringfield then begin + tmsestringfield(field1).asmsestring:= avalue; + end + else begin + if field1 is tmsememofield then begin + tmsememofield(field1).asmsestring:= avalue; + end + else begin + if isutf8 then begin + field1.asstring:= stringtoutf8ansi(avalue); + end + else begin + field1.asstring:= ansistring(avalue); + end; + end; + end; +end; + +procedure tdscontroller.begindisplaydata; +begin + idscontroller(fintf).begindisplaydata; +end; + +procedure tdscontroller.enddisplaydata; +begin + idscontroller(fintf).enddisplaydata; +end; + +procedure tdscontroller.copyrecord(const aappend: boolean = false); +var + ar1: variantarty; + ar2: booleanarty; + field1: tfield; +// intf1: imsefield; + int1: integer; + bo1: boolean; +begin + if checkcanevent(tdataset(fowner),tmethod(fonbeforecopyrecord)) then begin + fonbeforecopyrecord(tdataset(fowner)); + end; + with tdataset1(fowner) do begin + include(finternalstate,dsis_recordcopy); + try + setlength(ar1,fields.count); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + field1:= fields[int1]; + bo1:= (field1.fieldkind in [fkdata,fkinternalcalc]) and + not (of_nocopyrecord in field1.optionsfield); + if bo1 then begin + ar2[int1]:= true; + ar1[int1]:= field1.value; + end; + end; + if aappend then begin + append; + end + else begin + insert; + end; + for int1:= 0 to high(ar1) do begin + if ar2[int1] and not varisnull(ar1[int1]) then begin + field1:= fields[int1]; + if field1.isnull or (of_initcopy in field1.optionsfield) then begin + field1.value:= ar1[int1]; + end; + end; + end; + finally + exclude(finternalstate,dsis_recordcopy); + end; + end; + if checkcanevent(tdataset(fowner),tmethod(fonaftercopyrecord)) then begin + fonaftercopyrecord(tdataset(fowner)); + end; +end; + +function tdscontroller.copying(): boolean; +begin + result:= dsis_recordcopy in tdataset1(fowner).finternalstate; +end; + +{ tfieldlinkdatalink } + +constructor tfieldlinkdatalink.create(const aowner: tfieldlink); +begin + fowner:= aowner; + inherited create; + fdatasource:= tdatasource.create(nil); + datasource:= fdatasource; +end; + +destructor tfieldlinkdatalink.destroy; +begin + fdatasource.free; + inherited; +end; + +procedure tfieldlinkdatalink.updatedata; +begin + if field <> nil then begin + if not (flo_disabled in fowner.options) and + (not (flo_onlyifnull in fowner.foptions) or (field.isnull)) and + (not (flo_notifunmodifiedinsert in fowner.foptions) or + (datasource.dataset.modified)) then begin + fowner.updatedata(field); + end; + end; +end; + +{ tfieldlink } + +constructor tfieldlink.create(aowner: tcomponent); +begin + inherited; + fdestdatalink:= tfieldlinkdatalink.create(self); +end; + +destructor tfieldlink.destroy; +begin + fdestdatalink.free; + inherited; +end; + +procedure tfieldlink.setdestdataset(const avalue: tdataset); +begin + fdestdatalink.fdatasource.dataset:= avalue; +end; + +function tfieldlink.getdestdataset: tdataset; +begin + result:= fdestdatalink.dataset; +end; + +function tfieldlink.getdestdatafield: string; +begin + result:= fdestdatalink.fieldname; +end; + +procedure tfieldlink.setdestdatafield(const avalue: string); +begin + fdestdatalink.fieldname:= avalue; +end; + +function tfieldlink.field: tfield; +begin + result:= fdestdatalink.field; +end; + +procedure tfieldlink.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + fieldtypes:= nil; +end; + +function tfieldlink.getdataset(const aindex: integer): tdataset; +begin + result:= fdestdatalink.dataset; +end; + +procedure tfieldlink.updatedata(const afield: tfield); +begin + if not (flo_disabled in foptions) and + canevent(tmethod(fonupdatedata)) then begin + fonupdatedata(afield); + end; +end; + +function tfieldlink.getenabled: boolean; +begin + result:= not (flo_disabled in foptions); +end; + +procedure tfieldlink.setenabled(const avalue: boolean); +begin + if avalue then begin + exclude(foptions,flo_disabled); + end + else begin + include(foptions,flo_disabled); + end; +end; + +{ tfieldfieldlink } + +constructor tfieldfieldlink.create(aowner: tcomponent); +begin + inherited; + fsourcedatalink:= tfielddatalink.create; +end; + +destructor tfieldfieldlink.destroy; +begin + fsourcedatalink.free; + inherited; +end; + +function tfieldfieldlink.getfieldname: string; +begin + result:= fsourcedatalink.fieldname; +end; + +procedure tfieldfieldlink.setfieldname(const avalue: string); +begin + fsourcedatalink.fieldname:= avalue; +end; + +function tfieldfieldlink.getdatasource: tdatasource; +begin + result:= fsourcedatalink.datasource; +end; + +function tfieldfieldlink.getdatasource1(const aindex: integer): tdatasource; +begin + if aindex = 0 then begin + result:= fsourcedatalink.datasource; + end + else begin + result:= fdestdatalink.datasource; + end; +end; + +procedure tfieldfieldlink.setdatasource(const avalue: tdatasource); +begin + fsourcedatalink.datasource:= avalue; +end; + +function tfieldfieldlink.sourcefield: tfield; +begin + result:= fsourcedatalink.field; +end; + +procedure tfieldfieldlink.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + setlength(propertynames,2); + propertynames[0]:= 'fieldname'; + propertynames[1]:= 'destdatafield'; + setlength(fieldtypes,2); + fieldtypes[0]:= []; + fieldtypes[1]:= []; +end; + +function tfieldfieldlink.getdataset(const aindex: integer): tdataset; +begin + result:= nil; + case aindex of + 0: begin + result:= fsourcedatalink.dataset; + end; + 1: begin + result:= fdestdatalink.dataset; + end; + end; +end; + +procedure tfieldfieldlink.updatedata(const afield: tfield); +begin + if not (flo_disabled in foptions) and + (fsourcedatalink.field <> nil) then begin + field.value:= fsourcedatalink.field.value; + end; + inherited; +end; + +procedure tfieldfieldlink.readdatafield(reader: treader); +begin + fieldname:= reader.readstring; +end; + +procedure tfieldfieldlink.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('datafield',{$ifdef FPC}@{$endif}readdatafield,nil,false); +end; + +{ ttimestampfieldlink } + +procedure ttimestampfieldlink.updatedata(const afield: tfield); +begin + if flo_utc in foptions then begin + afield.asdatetime:= nowutc; + end + else begin + afield.asdatetime:= nowlocal; + end; + inherited; +end; + +{ tmseparams } + +constructor tmseparams.create(aowner: tpersistent); +begin + inherited create(aowner); +{$warnings off} + tcollection1(self).fitemclass:= tmseparam; +{$warnings on} +end; + +constructor tmseparams.create; +begin + create(tpersistent(nil)); +end; + +function tmseparams.parsesql(const sql: msestring; + const docreate,EscapeSlash,EscapeRepeat: boolean; + const parameterstyle: tparamstyle; + var parambinding: tparambinding; + var replacestring: msestring): msestring; + +type + // used for ParamPart + TStringPart = record + Start,Stop:integer; + end; + +const + ParamAllocStepSize = 8; + +var + IgnorePart:boolean; + p,ParamNameStart,BufStart: PmseChar; + ParamName: msestring; + QuestionMarkParamCount,ParameterIndex,NewLength:integer; + ParamCount:integer; // actual number of parameters encountered so far; + // always <= Length(ParamPart) = Length(Parambinding) + // Parambinding will have length ParamCount in the end + ParamPart:array of TStringPart; // describe which parts of buf are parameters +// NewQueryLength:integer; + NewQuery: msestring; + NewQueryIndex,BufIndex,CopyLen,i:integer; // Parambinding will have length ParamCount in the end + b:integer; + tmpParam:TParam; + +begin +// if DoCreate then Clear; //2006-11-23 mse + + // Parse the SQL and build ParamBinding + ParamCount:=0; + paramname:= ''; + paramnamestart:= nil; +// NewQueryLength:=Length(SQL); + SetLength(ParamPart,ParamAllocStepSize); + SetLength(Parambinding,ParamAllocStepSize); + QuestionMarkParamCount:=0; // number of ? params found in query so far + + ReplaceString := '$'; + if ParameterStyle = psSimulated then + while pos(ReplaceString,SQL) > 0 do ReplaceString := ReplaceString+'$'; + + p:= PmseChar(SQL); + BufStart:=p; // used to calculate ParamPart.Start values + repeat + case p^ of + '''': // single quote delimited string + begin + Inc(p); + while not ((p^ = #0) or (p^ = '''')) do + begin + if p^='\' then Inc(p,2) // make sure we handle \' and \\ correct + else Inc(p); + end; + if p^='''' then Inc(p); // skip final ' + end; + '"': // double quote delimited string + begin + Inc(p); + while not ((p^ = #0) or (p^ = '"')) do + begin + if p^='\' then Inc(p,2) // make sure we handle \" and \\ correct + else Inc(p); + end; + if p^='"' then Inc(p); // skip final " + end; + '-': // possible start of -- comment + begin + Inc(p); + if p^='-' then // -- comment + begin + repeat // skip until at end of line + Inc(p); + until (p^ = #10) or (p^ = #0); + end + end; + '/': // possible start of /* */ comment + begin + Inc(p); + if p^='*' then // /* */ comment + begin + repeat + Inc(p); + if p^='*' then // possible end of comment + begin + Inc(p); + if p^='/' then Break; // end of comment + end; + until p^=#0; + if p^='/' then Inc(p); // skip final / + end; + end; + ':','?': // parameter + begin + IgnorePart := False; + if p^=':' then + begin // find parameter name + Inc(p); + if p^=':' then // ignore ::, since some databases uses this as a cast (wb 4813) + begin + IgnorePart := True; + Inc(p); + end + else + begin + ParamNameStart:=p; + while (p^ > #127) or + not (char(byte(p^)) in (SQLDelimiterCharacters + + [#0,'=','+','-','*','\','[',']'])) do + Inc(p); + ParamName:=Copy(ParamNameStart,1,p-ParamNameStart); + end; + end + else + begin + Inc(p); + ParamNameStart:=p; + ParamName:=''; + end; + + if not IgnorePart then + begin + Inc(ParamCount); + if ParamCount>Length(ParamPart) then + begin + NewLength:=Length(ParamPart)+ParamAllocStepSize; + SetLength(ParamPart,NewLength); + SetLength(ParamBinding,NewLength); + end; + + if DoCreate then + begin + // Check if this is the first occurance of the parameter + tmpParam := FindParam(ansistring(ParamName)); + // If so, create the parameter and assign the Parameterindex + if not assigned(tmpParam) then + ParameterIndex := CreateParam(ftUnknown, + ansistring(ParamName), ptInput).Index + else // else only assign the ParameterIndex + ParameterIndex := tmpParam.Index; + end + // else find ParameterIndex + else + begin + if ParamName<>'' then + ParameterIndex:=ParamByName(ansistring(ParamName)).Index + else + begin + ParameterIndex:=QuestionMarkParamCount; + Inc(QuestionMarkParamCount); + end; + end; + { + if ParameterStyle in [psPostgreSQL,psSimulated] then + begin + if ParameterIndex > 8 then + inc(NewQueryLength,2) + else + inc(NewQueryLength,1) + end; + } + // store ParameterIndex in FParamIndex, ParamPart data + ParamBinding[ParamCount-1]:=ParameterIndex; + ParamPart[ParamCount-1].Start:=ParamNameStart-BufStart; + ParamPart[ParamCount-1].Stop:=p-BufStart+1; + + // update NewQueryLength +// Dec(NewQueryLength,p-ParamNameStart); + end; + end; + #0:Break; + else + Inc(p); + end; + until false; + + SetLength(ParamPart,ParamCount); + SetLength(ParamBinding,ParamCount); + + if ParamCount>0 then begin + //replace :ParamName by '?' for interbase, + //by '$x ' for postgresql and psSimulated + //(using ParamPart array and NewQueryLength) + SetLength(NewQuery,length(sql)+paramcount*(length(ReplaceString)+8)); + //reserve '$1234567 ' + NewQueryIndex:=1; + BufIndex:=1; + for i:=0 to High(ParamPart) do begin + CopyLen:=ParamPart[i].Start-BufIndex; + Move(SQL[BufIndex],NewQuery[NewQueryIndex],CopyLen*sizeof(msechar)); + Inc(NewQueryIndex,CopyLen); + case ParameterStyle of + psInterbase : NewQuery[NewQueryIndex]:='?'; + psPostgreSQL, + psSimulated : begin + ParamName:= IntToStrmse(ParamBinding[i]+1); + for b:= 1 to length(ReplaceString) do begin + NewQuery[NewQueryIndex]:='$'; + Inc(NewQueryIndex); + end; + for b:= 1 to length(paramname) do begin + NewQuery[NewQueryIndex]:= paramname[b]; + Inc(NewQueryIndex); + end; + newquery[newqueryindex]:= ' '; + end; + end; + Inc(NewQueryIndex); + BufIndex:=ParamPart[i].Stop; + end; + CopyLen:=Length(SQL)+1-BufIndex; + Move(SQL[BufIndex],NewQuery[NewQueryIndex],CopyLen*sizeof(msechar)); + setlength(newquery,newqueryindex+copylen-1); + end + else begin + NewQuery:=SQL; + end; + Result:= NewQuery; +end; + +function tmseparams.parsesql(const sql: msestring; + const docreate,EscapeSlash,EscapeRepeat: boolean; + const parameterstyle : tparamstyle; var parambinding: tparambinding): msestring; +var + rs: msestring; +begin + result := parsesql(sql,docreate,escapeslash,escaperepeat,parameterstyle, + parambinding,rs); +end; + +function tmseparams.parsesql(const sql: msestring; + const docreate,EscapeSlash,EscapeRepeat: boolean; + const parameterstyle: tparamstyle): msestring; +var + pb: tparambinding; + rs: msestring; +begin + result:= parsesql(sql,docreate,escapeslash,escaperepeat,parameterstyle,pb,rs); +end; + +function tmseparams.parsesql(const sql: msestring; const docreate: boolean): msestring; +var + pb: TParamBinding; + rs: msestring; +begin + result:= parsesql(sql,docreate,false,false,psinterbase,pb,rs); +end; + +function tmseparams.expandvalues(sql: msestring; + const aparambindings: tparambinding; + const aparamreplacestring: msestring): msestring; +var + int1,int2,int3,int4: integer; + po1: pmsechar; +begin + if high(aparambindings) >= 0 then begin + int3:= 1; + result:= ''; + uniquestring(sql); + po1:= pmsechar(sql)-1; + for int1:= 0 to high(aparambindings) do begin + int2:= pos(aparamreplacestring,sql); + for int4:= int2 to int2+length(aparamreplacestring)-1 do begin + (po1+int4)^:= ' '; //remove marker + end; + result:= result + copy(sql,int3,int2-int3) + + paramtosql(items[aparambindings[int1]]); + int3:= int2 + length(aparamreplacestring); + while (sql[int3] >= '0') and (sql[int3] <= '9') do begin + inc(int3); + end; + end; + result:= result + copy(sql,int3,bigint); //tail + end + else begin + result:= sql; + end; +end; + +function tmseparams.expandvalues(const sql: msestring): msestring; +var + pb: tparambinding; + str1,str2: msestring; +begin + str2:= parsesql(sql,false,false,false,pssimulated,pb,str1); + result:= expandvalues(str2,pb,str1); +end; + +function tmseparams.asdbstring(const index: integer): string; +begin + with items[index] do begin + if not (datatype in [ftblob,ftmemo,ftbytes,ftvarbytes]) and isutf8 then begin + if vartype(value) = varolestr then begin + result:= stringtoutf8ansi(aswidestring); + end + else begin + result:= stringtoutf8ansi(msestring(asstring)); + end; + end + else begin + result:= asstring; + end; + end; +end; + +function tmseparams.getitem(const index: integer): tmseparam; +begin + result:= tmseparam(inherited items[index]); +end; + +procedure tmseparams.setitem(const index: integer; const avalue: tmseparam); +begin + inherited items[index]:= avalue; +end; + +function tmseparams.bindnames(const anames: msestringarty): integerarty; +var + mstr1: msestring; + int1,int2: integer; +begin + setlength(result,count); + for int1:= high(result) downto 0 do begin + result[int1]:= -1; + mstr1:= msestring(items[int1].name); + for int2:= high(anames) downto 0 do begin + if anames[int2] = mstr1 then begin + result[int1]:= int2; + break; + end; + end; + end; +end; + +function tmseparams.getvalues: variantarty; +var + int1: integer; +begin + setlength(result,count); + for int1:= high(result) downto 0 do begin + result[int1]:= items[int1].value; + end; +end; + +procedure tmseparams.setvalues(const avalue: variantarty); +var + int1: integer; +begin + for int1:= high(avalue) downto 0 do begin + items[int1].value:= avalue[int1]; + end; +end; + +procedure tmseparams.updatevalues; +var + int1: integer; +begin + for int1:= 0 to count-1 do begin + with tmseparam(items[int1]) do begin + if fdatalink.field <> nil then begin + if pos('OLD_',name) = 1 then begin + value:= fdatalink.field.oldvalue; + end + else begin + value:= fdatalink.field.value; + end; + end; + end; + end; +end; + +{ tblobcachenode } + +constructor tblobcachenode.create(const akey: blobidty; const adata: string); +begin + flocal:= akey.local; + inherited create(akey.id,adata); +end; + +{ tblobcache } + +function compareblobid(const left,right: tavlnode): integer; +var + lint1: int64; +begin + result:= integer(tblobcachenode(left).flocal) - + integer(tblobcachenode(right).flocal); + if result = 0 then begin + lint1:= tblobcachenode(left).fkey - tblobcachenode(right).fkey; + if lint1 > 0 then begin + result:= 1; + end + else begin + if lint1 < 0 then begin + result:= -1; + end; + end; + end; +end; + +constructor tblobcache.create; +begin + ffindnode:= tblobcachenode.create; + inherited; + fcompare:= {$ifdef FPC}@{$endif}compareblobid; +end; + +destructor tblobcache.destroy; +begin + inherited; + ffindnode.free; +end; + +function tblobcache.addnode(const akey: blobidty; + const adata: string): tblobcachenode; +begin + result:= tblobcachenode.create(akey,adata); + addnode(result); +end; + +function tblobcache.find(const akey: blobidty; + out anode: tblobcachenode): boolean; +begin + ffindnode.fkey:= akey.id; + ffindnode.flocal:= akey.local; + result:= find(ffindnode,tavlnode(anode)); +end; + +{ tmseparam } + +constructor tmseparam.Create(ACollection: TCollection); +begin + fdatalink:= tfielddatalink.create; + inherited; +end; + +destructor tmseparam.destroy; +begin + connector:= nil; + fdatalink.free; + inherited; +end; + +procedure tmseparam.setconnector(const avalue: tparamconnector); +begin + if fconnector <> avalue then begin + if fconnector <> nil then begin + fconnector.fparam:= nil; + end; + fconnector:= avalue; + if fconnector <> nil then begin + if fconnector.fparam <> nil then begin + fconnector.fparam.fconnector:= nil; + end; + fconnector.fparam:= self; + end; + end; +end; + +//{$ifdef mse_withpublishedparamvalue} +procedure tmseparam.setasvariant(const avalue: variant); +begin + inherited setasvariant(avalue); +{$warnings off} + tparam1(self).fbound:= not varisclear(avalue); +{$warnings on} +end; +//{$endif mse_withpublishedparamvalue} +{ +function tmseparam.getasid: int64; +begin + if isnull then begin + result:= -1; + end + else begin + result:= aslargeint; + end; +end; + +procedure tmseparam.setasid(const avalue: int64); +begin + if avalue = -1 then begin + clear; + end + else begin + aslargeint:= avalue; + end; +end; +} +function tmseparam.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tmseparam.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; +end; + +function tmseparam.getfieldname: string; +begin + result:= fdatalink.fieldname; +end; + +procedure tmseparam.setfieldname(const avalue: string); +begin + fdatalink.fieldname:= avalue; +end; + +function tmseparam.getdataset(const aindex: integer): tdataset; +begin + result:= fdatalink.dataset; +end; + +procedure tmseparam.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + afieldtypes:= nil; +end; + +function tmseparam.isparamstored: boolean; +begin + result:= bound; +end; +{ +function tmseparam.getasmsestring: msestring; +begin + result:= getaswidestring; +end; + +procedure tmseparam.setasmsestring(const avalue: msestring); +begin + setaswidestring(avalue); +end; +} +{ tparamconnector } + +destructor tparamconnector.destroy; +begin + if fparam <> nil then begin + fparam.connector:= nil; + end; + inherited; +end; + +function tparamconnector.getparam: tmseparam; +begin + if fparam = nil then begin + raise exception.create(name+': no param source.'); + end; + result:= fparam; +end; + +{ tmsedatasource } + +procedure tmsedatasource.bringtofront; +var + int1: integer; +begin + if (dataset <> nil) then begin +{$warnings off} + with tdataset1(dataset) do begin +{$warnings on} + int1:= fdatasources.indexof(self); + if int1 >= 0 then begin + fdatasources.move(int1,0); + end; + sortdatasources(); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbcalendardatetimeedit.pas b/mseide-msegui/lib/common/db/msedbcalendardatetimeedit.pas new file mode 100644 index 0000000..6864b04 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbcalendardatetimeedit.pas @@ -0,0 +1,202 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit msedbcalendardatetimeedit; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mdb,classes,mclasses,msecalendardatetimeedit,msedbedit,msedb,msegui, + msewidgetgrid,mseevent,msegraphics, + msedatalist,mseeditglob,msegrids,msemenus,mseguiglob,mseedit,msedataedits, + msestrings,msetypes; + +type + tdbcalendardatetimeedit = class(tcustomcalendardatetimeedit,idbeditfieldlink, + ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property dropdown; + property valuemin {stored false}; + property valuemax {stored false}; + property formatedit; + property formatdisp; + property kind; + property options; + property onsetvalue; + end; + +implementation +type + teditwidgetdatalink1 = class(teditwidgetdatalink); + +{ tdbcalendardatetimeedit } + +constructor tdbcalendardatetimeedit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbcalendardatetimeedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbcalendardatetimeedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbcalendardatetimeedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbcalendardatetimeedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbcalendardatetimeedit.valuetofield; +begin + if value = emptydatetime then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asdatetime:= value; + end; +end; + +procedure tdbcalendardatetimeedit.fieldtovalue; +var + da1: tdatetime; +begin + if fdatalink.field.isnull then begin + value:= 0; + end + else begin + da1:= fdatalink.field.asdatetime; + value:= da1; + end; +end; + +function tdbcalendardatetimeedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getdatetimebuffer( + fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbcalendardatetimeedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbcalendardatetimeedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbcalendardatetimeedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbcalendardatetimeedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= datetimefields; +end; + +function tdbcalendardatetimeedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbcalendardatetimeedit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbcalendardatetimeedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbcalendardatetimeedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbcalendardatetimeedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbcalendardatetimeedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbcalendardatetimeedit.doenter; +begin + teditwidgetdatalink1(fdatalink).doenter(self); + inherited; +end; + +procedure tdbcalendardatetimeedit.doexit; +begin + teditwidgetdatalink1(fdatalink).doexit(self); + inherited; +end; +} +end. diff --git a/mseide-msegui/lib/common/db/msedbdialog.pas b/mseide-msegui/lib/common/db/msedbdialog.pas new file mode 100644 index 0000000..c8f5564 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbdialog.pas @@ -0,0 +1,812 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit msedbdialog; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,mseguiglob,msefiledialog,mdb,mseinplaceedit,msedbedit,msegui, + msewidgetgrid, + msedatalist,mseeditglob,msegrids,msetypes,msedb,msemenus,mseedit, + msedataedits,mseevent,msestrings,msecolordialog,msegraphutils,msedialog, + mseglob,msegraphics; + +type + tdbfilenameedit = class(tcustomfilenameedit,idbeditfieldlink,ireccontrol) + private + fdatalink: tstringeditwidgetdatalink; + procedure setdatalink(const avalue: tstringeditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure editnotification(var info: editnotificationinfoty); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + function getfieldlink: tcustomeditwidgetdatalink; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property frame; + property passwordchar; + property maxlength; + property onsetvalue; + property controller; + end; + + tdbremotefilenameedit = class(tcustomremotefilenameedit,idbeditfieldlink, + ireccontrol) + private + fdatalink: tstringeditwidgetdatalink; + procedure setdatalink(const avalue: tstringeditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure editnotification(var info: editnotificationinfoty); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + function getfieldlink: tcustomeditwidgetdatalink; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property frame; + property passwordchar; + property maxlength; + property onsetvalue; + property dialog; + end; + + tdbcoloredit = class(tcustomcoloredit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + + function internaldatatotext1( + const avalue: integer): msestring; override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; virtual; + procedure fieldtovalue; virtual; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property options; + property dropdown; + property onsetvalue; + property frame; + end; + + tdbdialogstringedit = class(tdbstringedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: stringdialogexeceventty; + procedure setonexecute(const avalue: stringdialogexeceventty); + protected + fcontroller: tstringdialogcontroller; + function createdialogcontroller: tstringdialogcontroller; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property textflags default defaulttextflagsnoycentered; + property textflagsactive default defaulttextflagsactivenoycentered; + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: stringdialogexeceventty read getonexecute write setonexecute; + end; + + tdbmemodialogedit = class(tdbdialogstringedit) + protected + function createdialogcontroller: tstringdialogcontroller; override; + public + end; + + tdbdialogrealedit = class(tdbrealedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: realdialogexeceventty; + procedure setonexecute(const avalue: realdialogexeceventty); + protected + fdialogcontroller: trealdialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: realdialogexeceventty read getonexecute + write setonexecute; + end; + + tdbdialogdatetimeedit = class(tdbdatetimeedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: datetimedialogexeceventty; + procedure setonexecute(const avalue: datetimedialogexeceventty); + protected + fdialogcontroller: tdatetimedialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: datetimedialogexeceventty read getonexecute + write setonexecute; + end; + + tdbdialogintegeredit = class(tdbintegeredit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: integerdialogexeceventty; + procedure setonexecute(const avalue: integerdialogexeceventty); + protected + fdialogcontroller: tintegerdialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: integerdialogexeceventty read getonexecute + write setonexecute; + end; + +implementation +uses + typinfo,msememodialog; +type + teditwidgetdatalink1 = class(teditwidgetdatalink); + tstringeditwidgetdatalink1 = class(tstringeditwidgetdatalink); + treader1 = class(treader); + +{ tdbfilenameedit } + +constructor tdbfilenameedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbfilenameedit.destroy; +begin + inherited; + fdatalink.free; +end; +{ +procedure tdbfilenameedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbfilenameedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbfilenameedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbfilenameedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbfilenameedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + end + else begin + fdatalink.asmsestring:= value; + end; +end; + +procedure tdbfilenameedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tdbfilenameedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbfilenameedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbfilenameedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbfilenameedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbfilenameedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdbfilenameedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); +{$warnings off} + teditwidgetdatalink1(fdatalink).nullcheckneeded(result); +{$warnings on} +end; + +procedure tdbfilenameedit.setdatalink(const avalue: tstringeditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbfilenameedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbfilenameedit.editnotification(var info: editnotificationinfoty); +var + int1: integer; +begin + inherited; + if info.action = ea_textedited then begin + if fdatalink.cuttext(text,int1) then begin + text:= copy(text,1,int1); + end; + end; +end; + +procedure tdbfilenameedit.recchanged; +begin +{$warnings off} + teditwidgetdatalink1(fdatalink).recordchanged(nil); +{$warnings on} +end; + +function tdbfilenameedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbfilenameedit.doenter; +begin + tstringeditwidgetdatalink1(fdatalink).doenter(self); + inherited; +end; + +procedure tdbfilenameedit.doexit; +begin + tstringeditwidgetdatalink1(fdatalink).doexit(self); + inherited; +end; +} +{ tdbremotefilenameedit } + +constructor tdbremotefilenameedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbremotefilenameedit.destroy; +begin + inherited; + fdatalink.free; +end; +{ +procedure tdbremotefilenameedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbremotefilenameedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbremotefilenameedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbremotefilenameedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbremotefilenameedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + end + else begin + fdatalink.asmsestring:= value; + end; +end; + +procedure tdbremotefilenameedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tdbremotefilenameedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbremotefilenameedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbremotefilenameedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbremotefilenameedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbremotefilenameedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdbremotefilenameedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); +{$warnings off} + teditwidgetdatalink1(fdatalink).nullcheckneeded(result); +{$warnings on} +end; + +procedure tdbremotefilenameedit.setdatalink(const avalue: tstringeditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbremotefilenameedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbremotefilenameedit.editnotification(var info: editnotificationinfoty); +var + int1: integer; +begin + inherited; + if info.action = ea_textedited then begin + if fdatalink.cuttext(text,int1) then begin + text:= copy(text,1,int1); + end; + end; +end; + +procedure tdbremotefilenameedit.recchanged; +begin +{$warnings off} + teditwidgetdatalink1(fdatalink).recordchanged(nil); +{$warnings on} +end; + +function tdbremotefilenameedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbremotefilenameedit.doenter; +begin + tstringeditwidgetdatalink1(fdatalink).doenter(self); + inherited; +end; + +procedure tdbremotefilenameedit.doexit; +begin + tstringeditwidgetdatalink1(fdatalink).doexit(self); + inherited; +end; +} +{ tdbcoloredit } + +constructor tdbcoloredit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.create(idbeditfieldlink(self)); + inherited; + valuedefault:= colorty(-1); +end; + +destructor tdbcoloredit.destroy; +begin + inherited; + fdatalink.free; +end; +{ +procedure tdbcoloredit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbcoloredit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbcoloredit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbcoloredit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); + frame.readonly:= oe_readonly in result; +end; +} +procedure tdbcoloredit.valuetofield; +begin + if value = colorty(-1) then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asinteger:= value; + end; +end; + +procedure tdbcoloredit.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= fvaluedefault1; + end + else begin + value:= fdatalink.field.asinteger; + end; +end; + +function tdbcoloredit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink). + getintegerbuffer(fdatalink.field,arow); + if result = nil then begin + result:= @fvaluedefault; + end; + end + else begin + result:= @fvaluedefault; + end; +end; + +function tdbcoloredit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbcoloredit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbcoloredit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbcoloredit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +function tdbcoloredit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbcoloredit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbcoloredit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbcoloredit.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +function tdbcoloredit.internaldatatotext1(const avalue: integer): msestring; +begin + if avalue = -1 then begin + result:= ''; + end + else begin + result:= inherited internaldatatotext1(avalue); + end; +end; + +function tdbcoloredit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbcoloredit.doenter; +begin + teditwidgetdatalink1(fdatalink).doenter(self); + inherited; +end; + +procedure tdbcoloredit.doexit; +begin + teditwidgetdatalink1(fdatalink).doexit(self); + inherited; +end; +} +{ tdbdialogstringedit } + +constructor tdbdialogstringedit.create(aowner: tcomponent); +begin + inherited; + ftextflags:= defaulttextflagsnoycentered; + ftextflagsactive:= defaulttextflagsactivenoycentered; + updatetextflags(); + if fcontroller = nil then begin + fcontroller:= createdialogcontroller; + end; +end; + +destructor tdbdialogstringedit.destroy; +begin + inherited; + fcontroller.free; +end; + +function tdbdialogstringedit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdbdialogstringedit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdbdialogstringedit.getonexecute: stringdialogexeceventty; +begin + result:= fcontroller.onexecute; +end; + +procedure tdbdialogstringedit.setonexecute(const avalue: stringdialogexeceventty); +begin + fcontroller.onexecute:= avalue; +end; + +function tdbdialogstringedit.createdialogcontroller: tstringdialogcontroller; +begin + result:= tstringdialogcontroller.create(self); +end; + +{ tdbmemodialogedit } + +function tdbmemodialogedit.createdialogcontroller: tstringdialogcontroller; +begin + result:= tmemodialogcontroller.create(self); +end; + +{ tdbdialogrealedit } + +constructor tdbdialogrealedit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= trealdialogcontroller.create(self); + end; +end; + +destructor tdbdialogrealedit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdbdialogrealedit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdbdialogrealedit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdbdialogrealedit.getonexecute: realdialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdbdialogrealedit.setonexecute(const avalue: realdialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +{ tdbdialogdatetimeedit } + +constructor tdbdialogdatetimeedit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= tdatetimedialogcontroller.create(self); + end; +end; + +destructor tdbdialogdatetimeedit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdbdialogdatetimeedit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdbdialogdatetimeedit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdbdialogdatetimeedit.getonexecute: datetimedialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdbdialogdatetimeedit.setonexecute(const avalue: datetimedialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +{ tdbdialogintegeredit } + +constructor tdbdialogintegeredit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= tintegerdialogcontroller.create(self); + end; +end; + +destructor tdbdialogintegeredit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdbdialogintegeredit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdbdialogintegeredit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdbdialogintegeredit.getonexecute: integerdialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdbdialogintegeredit.setonexecute(const avalue: integerdialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbdispwidgets.pas b/mseide-msegui/lib/common/db/msedbdispwidgets.pas new file mode 100644 index 0000000..8203a5d --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbdispwidgets.pas @@ -0,0 +1,997 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedbdispwidgets; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + mdb,classes,mclasses,msesimplewidgets,msedb,msetypes,mseclasses,mseguiglob, + mseglob,mseinterfaces,msegraphics, + msedispwidgets,msestrings,mselookupbuffer,msegui,msemenus,mseevent, + msebarcode; + +type + tdispfielddatalink = class; + + idbdispfieldlink = interface(inullinterface)[miid_idbdispfieldlink] + procedure fieldtovalue; + procedure setnullvalue; + function getwidget: twidget; + procedure getfieldtypes(var afieldtypes: fieldtypesty); //[] = all + function getfieldlink(): tdispfielddatalink; + end; + + tdispfielddatalink = class(tfielddatalink,idbeditinfo) + private + procedure readdatasource(reader: treader); + procedure readdatafield(reader: treader); + protected + fintf: idbdispfieldlink; + procedure activechanged; override; + function getdataset(const aindex: integer): tdataset; virtual; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); virtual; + public + constructor create(const intf: idbdispfieldlink); + procedure fixupproperties(filer: tfiler); //read moved properties + procedure recordchanged(afield: tfield); override; + published + property datasource; + property fieldname; + end; + + tdblabel = class(tcustomlabel,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); + procedure fieldtovalue; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property options; //first + property datalink: tdispfielddatalink read fdatalink write setdatalink; + property bounds_cx default defaultlabelwidgetwidth; + property bounds_cy default defaultlabelwidgetheight; + property optionswidget default defaultlabeloptionswidget; + property font; + property textflags; + end; + + tdbstringdisp = class(tcustomstringdisp,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); virtual; + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + end; + + tdbstringdisplb = class(tdbstringdisp,idbdispfieldlink,ireccontrol, + ilookupbufferfieldinfo) + private + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: lookupbufferfieldnoty; + flookupvaluefieldno: lookupbufferfieldnoty; + fkeyvalue: integer; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + //idbdispfieldlink + procedure getfieldtypes(var fieldtypes: fieldtypesty); override; + procedure fieldtovalue; override; + procedure setkeyvalue(const avalue: integer); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + property keyvalue: integer read fkeyvalue write setkeyvalue; + published + property lookupbuffer: tcustomlookupbuffer read flookupbuffer + write setlookupbuffer; + property lookupkeyfieldno: lookupbufferfieldnoty read flookupkeyfieldno + write flookupkeyfieldno default 0; + property lookupvaluefieldno: lookupbufferfieldnoty read flookupvaluefieldno + write flookupvaluefieldno default 0; + end; + + tdbintegerdisp = class(tcustomintegerdisp,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + fisnotnull: boolean; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + function getvaluetext: msestring; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + end; + + tdbintegerdisplb = class(tdbintegerdisp,idbdispfieldlink,ireccontrol, + ilookupbufferfieldinfo) + private + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: lookupbufferfieldnoty; + flookupvaluefieldno: lookupbufferfieldnoty; + fkeyvalue: integer; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + //idbdispfieldlink + procedure fieldtovalue; override; + procedure setkeyvalue(const avalue: integer); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + property keyvalue: integer read fkeyvalue write setkeyvalue; + published + property lookupbuffer: tcustomlookupbuffer read flookupbuffer + write setlookupbuffer; + property lookupkeyfieldno: lookupbufferfieldnoty read flookupkeyfieldno + write flookupkeyfieldno default 0; + property lookupvaluefieldno: lookupbufferfieldnoty read flookupvaluefieldno + write flookupvaluefieldno default 0; + end; + + tdbbooleandisp = class(tcustombooleandisp,idbdispfieldlink,ireccontrol) + private + fisnotnull: boolean; + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); + procedure fieldtovalue; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + function getvaluetext: msestring; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + end; + + tdbrealdisp = class(tcustomrealdisp,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); virtual; + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + end; + + tdbrealdisplb = class(tdbrealdisp,idbdispfieldlink,ireccontrol, + ilookupbufferfieldinfo) + private + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: lookupbufferfieldnoty; + flookupvaluefieldno: lookupbufferfieldnoty; + fkeyvalue: integer; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + //idbdispfieldlink + procedure getfieldtypes(var fieldtypes: fieldtypesty); override; + procedure fieldtovalue; override; + procedure setkeyvalue(const avalue: integer); + protected + procedure objectevent(const sender: tobject; const event: objecteventty); override; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + property keyvalue: integer read fkeyvalue write setkeyvalue; + published + property lookupbuffer: tcustomlookupbuffer read flookupbuffer write setlookupbuffer; + property lookupkeyfieldno: lookupbufferfieldnoty read flookupkeyfieldno write flookupkeyfieldno default 0; + property lookupvaluefieldno: lookupbufferfieldnoty read flookupvaluefieldno write flookupvaluefieldno default 0; + end; + + tdbdatetimedisp = class(tcustomdatetimedisp,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); virtual; + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + end; + + tdbdatetimedisplb = class(tdbdatetimedisp,idbdispfieldlink,ireccontrol, + ilookupbufferfieldinfo) + private + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: lookupbufferfieldnoty; + flookupvaluefieldno: lookupbufferfieldnoty; + fkeyvalue: integer; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + //idbdispfieldlink + procedure getfieldtypes(var fieldtypes: fieldtypesty); override; + procedure fieldtovalue; override; + procedure setkeyvalue(const avalue: integer); + protected + procedure objectevent(const sender: tobject; const event: objecteventty); override; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + property keyvalue: integer read fkeyvalue write setkeyvalue; + published + property lookupbuffer: tcustomlookupbuffer read flookupbuffer write setlookupbuffer; + property lookupkeyfieldno: lookupbufferfieldnoty read flookupkeyfieldno write flookupkeyfieldno default 0; + property lookupvaluefieldno: lookupbufferfieldnoty read flookupvaluefieldno write flookupvaluefieldno default 0; + end; + + tdbbarcode = class(tcustombarcode1,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); virtual; + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + published + property options; + property kind; + property direction; + property colorbar; + property colorspace; + property fontbar; + end; + +implementation +uses + msereal,sysutils,typinfo; +type + treader1 = class(treader); + +{ tdispfielddatalink } + +constructor tdispfielddatalink.create(const intf: idbdispfieldlink); +begin + fintf:= intf; + inherited create; + visualcontrol:= true; +end; + +procedure tdispfielddatalink.readdatasource(reader: treader); +begin + treader1(reader).readpropvalue(self, + getpropinfo(typeinfo(tdispfielddatalink),'datasource')); +end; + +procedure tdispfielddatalink.readdatafield(reader: treader); +begin + fieldname:= reader.readstring; +end; + +procedure tdispfielddatalink.fixupproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('datasource',{$ifdef FPC}@{$endif}readdatasource,nil,false); + filer.defineproperty('datafield',{$ifdef FPC}@{$endif}readdatafield,nil,false); + //move values to datalink +end; + +function tdispfielddatalink.getdataset(const aindex: integer): tdataset; +begin + result:= dataset; +end; + +procedure tdispfielddatalink.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + setlength(afieldtypes,1); + afieldtypes[0]:= []; + fintf.getfieldtypes(afieldtypes[0]); + if afieldtypes[0] = [] then begin + afieldtypes:= nil; + end; +end; + +procedure tdispfielddatalink.recordchanged(afield: tfield); +begin + if (afield = nil) or (afield = field) then begin + if active and (field <> nil) and + not (dataset.eof and dataset.bof and + (dataset.state <> dsinsert)) then begin + if field.isnull then begin + fintf.setnullvalue; + end + else begin + fintf.fieldtovalue; + end; + end + else begin + fintf.setnullvalue; + end; + end; +end; + +procedure tdispfielddatalink.activechanged; +begin + try + inherited; + except + on e: exception do begin + e.message:= fintf.getwidget.name + ': ' + e.message; + raise + end; + end; +end; + +{ tdblabel } + +constructor tdblabel.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdblabel.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdblabel.getfieldtypes(var fieldtypes: fieldtypesty); +begin + //all types +end; + +procedure tdblabel.fieldtovalue; +begin + caption:= msestring(datalink.field.displaytext); //tmsestringfield? +end; + +procedure tdblabel.setnullvalue; +begin + caption:= ''; +end; + +procedure tdblabel.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdblabel.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdblabel.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdblabel.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbstringdisp } + +constructor tdbstringdisp.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbstringdisp.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbstringdisp.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= textfields; +end; + +procedure tdbstringdisp.fieldtovalue; +begin + value:= datalink.asmsestring; +end; + +procedure tdbstringdisp.setnullvalue; +begin + value:= ''; +end; + +procedure tdbstringdisp.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbstringdisp.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbstringdisp.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbstringdisp.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbbarcode } + +constructor tdbbarcode.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbbarcode.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbbarcode.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= textfields+integerfields; +end; + +procedure tdbbarcode.fieldtovalue; +begin + value:= datalink.asmsestring; +end; + +procedure tdbbarcode.setnullvalue; +begin + value:= ''; +end; + +procedure tdbbarcode.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbbarcode.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +function tdbbarcode.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbstringdisplb } + +procedure tdbstringdisplb.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= integerfields; +end; + +procedure tdbstringdisplb.fieldtovalue; +begin + keyvalue:= datalink.field.asinteger; +end; + +procedure tdbstringdisplb.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); +end; + +procedure tdbstringdisplb.setkeyvalue(const avalue: integer); +var + int1: integer; +begin + fkeyvalue:= avalue; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,fkeyvalue,int1) then begin + value:= flookupbuffer.textvaluephys(flookupvaluefieldno,int1); + end + else begin + setnullvalue; + end; + end + else begin + setnullvalue; + end; +end; + +procedure tdbstringdisplb.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + setkeyvalue(fkeyvalue); + end; +end; + +function tdbstringdisplb.getlbdatakind(const apropname: string): lbdatakindty; +begin + if apropname = 'lookupkeyfieldno' then begin + result:= lbdk_integer; + end + else begin + result:= lbdk_text; + end; +end; + +function tdbstringdisplb.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +{ tdbintegerdisp } + +constructor tdbintegerdisp.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbintegerdisp.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbintegerdisp.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= integerfields; +end; + +procedure tdbintegerdisp.fieldtovalue; +begin + fisnotnull:= true; + value:= datalink.field.asinteger; +end; + +procedure tdbintegerdisp.setnullvalue; +begin + fisnotnull:= false; + value:= 0; +end; + +function tdbintegerdisp.getvaluetext: msestring; +begin + if fisnotnull then begin + result:= inherited getvaluetext; + end + else begin + result:= ''; + end; +end; + +procedure tdbintegerdisp.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbintegerdisp.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbintegerdisp.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbintegerdisp.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbintegerdisplb } + +procedure tdbintegerdisplb.fieldtovalue; +begin + keyvalue:= datalink.field.asinteger; +end; + +procedure tdbintegerdisplb.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); +end; + +procedure tdbintegerdisplb.setkeyvalue(const avalue: integer); +var + int1: integer; +begin + fkeyvalue:= avalue; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,fkeyvalue,int1) then begin + fisnotnull:= true; + value:= flookupbuffer.integervaluephys(flookupvaluefieldno,int1); + end + else begin + setnullvalue; + end; + end + else begin + setnullvalue; + end; +end; + +procedure tdbintegerdisplb.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + setkeyvalue(fkeyvalue); + end; +end; + +function tdbintegerdisplb.getlbdatakind(const apropname: string): lbdatakindty; +begin + if apropname = 'lookupkeyfieldno' then begin + result:= lbdk_integer; + end + else begin + result:= lbdk_integer; + end; +end; + +function tdbintegerdisplb.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +{ tdbbooleandisp } + +constructor tdbbooleandisp.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbbooleandisp.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbbooleandisp.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= booleanfields; +end; + +procedure tdbbooleandisp.fieldtovalue; +begin + fisnotnull:= true; + value:= datalink.field.asboolean; +end; + +procedure tdbbooleandisp.setnullvalue; +begin + fisnotnull:= false; + value:= false; +end; + +function tdbbooleandisp.getvaluetext: msestring; +begin + if fisnotnull then begin + result:= inherited getvaluetext; + end + else begin + result:= ''; + end; +end; + +procedure tdbbooleandisp.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbbooleandisp.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbbooleandisp.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbbooleandisp.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbrealdisp } + +constructor tdbrealdisp.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbrealdisp.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbrealdisp.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= realfields; +end; + +procedure tdbrealdisp.fieldtovalue; +begin + value:= datalink.field.asfloat; +end; + +procedure tdbrealdisp.setnullvalue; +begin + value:= emptyreal; +end; + +procedure tdbrealdisp.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbrealdisp.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbrealdisp.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbrealdisp.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbrealdisplb } + +procedure tdbrealdisplb.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= integerfields; +end; + +procedure tdbrealdisplb.fieldtovalue; +begin + keyvalue:= datalink.field.asinteger; +end; + +procedure tdbrealdisplb.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); +end; + +procedure tdbrealdisplb.setkeyvalue(const avalue: integer); +var + int1: integer; +begin + fkeyvalue:= avalue; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,fkeyvalue,int1) then begin + value:= flookupbuffer.floatvaluephys(flookupvaluefieldno,int1); + end + else begin + setnullvalue; + end; + end + else begin + setnullvalue; + end; +end; + +procedure tdbrealdisplb.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + setkeyvalue(fkeyvalue); + end; +end; + +function tdbrealdisplb.getlbdatakind(const apropname: string): lbdatakindty; +begin + if apropname = 'lookupkeyfieldno' then begin + result:= lbdk_integer; + end + else begin + result:= lbdk_float; + end; +end; + +function tdbrealdisplb.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +{ tdbdatetimedisp } + +constructor tdbdatetimedisp.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbdatetimedisp.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbdatetimedisp.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= datetimefields; +end; + +procedure tdbdatetimedisp.fieldtovalue; +var + da1: tdatetime; +begin + da1:= datalink.field.asdatetime; + value:= da1; +end; + +procedure tdbdatetimedisp.setnullvalue; +begin + value:= emptydatetime; +end; + +procedure tdbdatetimedisp.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbdatetimedisp.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdatetimedisp.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbdatetimedisp.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbdatetimedisplb } + +procedure tdbdatetimedisplb.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= integerfields; +end; + +procedure tdbdatetimedisplb.fieldtovalue; +begin + keyvalue:= datalink.field.asinteger; +end; + +procedure tdbdatetimedisplb.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); +end; + +procedure tdbdatetimedisplb.setkeyvalue(const avalue: integer); +var + int1: integer; +begin + fkeyvalue:= avalue; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,fkeyvalue,int1) then begin + value:= flookupbuffer.floatvaluephys(flookupvaluefieldno,int1); + end + else begin + setnullvalue; + end; + end + else begin + setnullvalue; + end; +end; + +procedure tdbdatetimedisplb.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + setkeyvalue(fkeyvalue); + end; +end; + +function tdbdatetimedisplb.getlbdatakind(const apropname: string): lbdatakindty; +begin + if apropname = 'lookupkeyfieldno' then begin + result:= lbdk_integer; + end + else begin + result:= lbdk_float; + end; +end; + +function tdbdatetimedisplb.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbedit.pas b/mseide-msegui/lib/common/db/msedbedit.pas new file mode 100644 index 0000000..daa9b13 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbedit.pas @@ -0,0 +1,12722 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit msedbedit; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +//{$ifndef mse_no_ifi} + {$define mse_with_ifi} +//{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mdb,classes,mclasses,mseguiglob,mseclasses,msegui,msetoolbar, + mseeditglob, + mseglob,msewidgetgrid,msearrayutils,msedatalist,mseinterfaces, + msetypes,msegrids,msegraphics,mseevent,msekeyboard,mseassistiveclient, + msegraphedits,msestrings,msegraphutils,mselist,msedropdownlist, + msescrollbar,msedataedits,msewidgets,msearrayprops,msedb,mselookupbuffer, + msedialog,mseinplaceedit,msemenus,mseedit,msestat,msegridsglob,typinfo + {$ifdef mse_with_ifi},mseifiglob,mseificompglob,mseificomp{$endif}; + +type + //0 1 2 3 4 + dbnavigbuttonty = (dbnb_first,dbnb_prior,dbnb_next,dbnb_last,dbnb_insert, + // 5 6 7 + dbnb_delete,dbnb_copyrecord,dbnb_edit, + // 8 9 10 + dbnb_post,dbnb_cancel,dbnb_refresh, + // 11 12 13 14 + dbnb_filter,dbnb_filtermin,dbnb_filtermax,dbnb_filterclear, + // 15 16 + dbnb_filteronoff,dbnb_find, + // 17 18 + dbnb_autoedit,dbnb_dialog); + + dbnavigbuttonsty = set of dbnavigbuttonty; + +const + defaultdbscrollbaroptions = + (defaultthumbtrackscrollbaroptions - [sbo_showauto])+ + [sbo_show,sbo_thumbtrack]; + + defaultvisibledbnavigbuttons = + [dbnb_first,dbnb_prior,dbnb_next,dbnb_last,dbnb_insert, + dbnb_delete,dbnb_edit,dbnb_post,dbnb_cancel,dbnb_refresh]; + filterdbnavigbuttons = [dbnb_filter,dbnb_filtermin,dbnb_filtermax, + dbnb_filterclear,dbnb_find,dbnb_filteronoff]; + defaultdbnavigatorheight = 24; + defaultdbnavigatorwidth = (ord(dbnb_refresh))*defaultdbnavigatorheight; + + defaultindicatorcoloptions = [fco_mousefocus]; + + maxautodisplaywidth = 20; + +type + dbnavigatoroptionty = (dno_confirmdelete,dno_confirmcopy, + dno_append,dno_nomultiinsert,dno_shortcuthint, + dno_norefreshrecno, + dno_dialogifinactive,dno_nodialogifempty, + dno_nodialogifnoeditmode,dno_nodialogifreadonly, + dno_nonavig, //disable navigation buttons + dno_noinsert,dno_nodelete,dno_noedit, //disable buttons + dno_customdialogupdate, + dno_postbeforedialog,dno_postoncanclose, + dno_candefocuswindow); + dbnavigatoroptionsty = set of dbnavigatoroptionty; + optioneditdbty = (oed_autoedit,oed_noautoedit,oed_readonly,oed_noreadonly, + oed_autopost, + oed_nullcheckifunmodified, + oed_syncedittonavigator,oed_focusoninsert, + oed_nofilteredit,oed_nofilterminedit, + oed_nofiltermaxedit,oed_nofindedit, + oed_nonullset, //use TField.DefaultExpression for textedit + oed_nullset, //don't use TField.DefaultExpression for + //empty edit value + oed_limitcharlen); + optionseditdbty = set of optioneditdbty; + + griddatalinkoptionty = (gdo_propscrollbar,gdo_thumbtrack, + gdo_checkbrowsemodeonexit,gdo_selectautopost); + griddatalinkoptionsty = set of griddatalinkoptionty; + +const + defaultgriddatalinkoptions = [gdo_propscrollbar,gdo_thumbtrack, + gdo_selectautopost]; + defaulteditwidgetdatalinkoptions = [{oed_syncedittonavigator}]; + defaultdbnavigatoroptions = [dno_confirmdelete,dno_confirmcopy,{dno_append,} + dno_shortcuthint]; + designdbnavigbuttons = [dbnb_first,dbnb_prior,dbnb_next,dbnb_last]; + editnavigbuttons = [dbnb_insert,dbnb_delete,dbnb_edit]; + + defaultdbdropdownoptions = [deo_selectonly,deo_autodropdown,deo_keydropdown]; + defaultdropdowndatalinkoptions = [gdo_propscrollbar,gdo_thumbtrack]; + + defaulteddropdownoptions = [deo_selectonly,deo_autodropdown,deo_keydropdown]; + +type + updaterowdataeventty = procedure(const sender: tcustomgrid; + const arow: integer; const adataset: tdataset)of object; + + optiondbty = (odb_copyitems,odb_opendataset,odb_closedataset,odb_directdata); + optionsdbty = set of optiondbty; + + idbnaviglink = interface(inullinterface) + procedure setactivebuttons(const abuttons: dbnavigbuttonsty; + const afiltered: boolean); + procedure setcheckedbuttons(const abuttons: dbnavigbuttonsty; + const achecked: boolean); + function getwidget: twidget; + function getnavigoptions: dbnavigatoroptionsty; + procedure dodialogexecute; + procedure updatereadonly(const force: boolean = false); + end; + + navigdatalinkstatety = (nds_prior,nds_next,nds_datasetscrolled); + navigdatalinkstatesty = set of navigdatalinkstatety; + + tnavigdatalink = class(tmsedatalink) + private + protected + fintf: idbnaviglink; + fstate: navigdatalinkstatesty; + procedure updatebuttonstate; + procedure activechanged; override; + procedure datasetchanged; override; + procedure editingchanged; override; + procedure recordchanged(Field: TField); override; + procedure disabledstatechange; override; + procedure datasetscrolled(distance: integer) override; + function canassistive(out aintf: iassistiveclient): boolean; + public + constructor create(const intf: idbnaviglink); + procedure execbutton(const abutton: dbnavigbuttonty); + end; + + tdbnavigbutton = class(tcustomstockglyphtoolbutton) + private + procedure readtag(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + published + property imagelist; + property imagenr; + property imagenrdisabled; + property colorglyph; + property color; + property imagecheckedoffset; + property hint; + property action; + property state; + property shortcut; + property shortcut1; +// property tag; + property options; + property group; +// property onexecute; +// property onbeforeexecute; + end; + + tdbnavigbuttons = class(tstockglyphtoolbuttons) + protected + class function getbuttonclass: toolbuttonclassty; override; + end; + + tdbnavigator = class(tcustomtoolbar,idbnaviglink) + private + fdatalink: tnavigdatalink; + fvisiblebuttons: dbnavigbuttonsty; + fshortcuts: array[dbnavigbuttonty] of shortcutty; + foptions: dbnavigatoroptionsty; + fondialogexecute: notifyeventty; + fonreadonlychange: booleanchangedeventty; + fcanautoeditbefore: boolean; + function getdatasource: tdatasource; + procedure setdatasource(const Value: tdatasource); + procedure setvisiblebuttons(const avalue: dbnavigbuttonsty); + function getcolorglyph: colorty; + procedure setcolorglyph(const avalue: colorty); + procedure setoptions(const avalue: dbnavigatoroptionsty); + function getbuttonface: tface; + procedure setbuttonface(const avalue: tface); + function gettoolbutton: tdbnavigbutton; + procedure settoolbutton(const avalue: tdbnavigbutton); + function getautoedit: boolean; + procedure setautoedit(const avalue: boolean); + function getbuttonwidth: integer; + procedure setbuttonwidth(const avalue: integer); + function getbuttonheight: integer; + procedure setbuttonheight(const avalue: integer); +// function getnonavig: boolean; +// procedure setnonavig(const avalue: boolean); + protected + procedure inithints; + procedure doexecute(const sender: tobject); + procedure loaded; override; + procedure internalshortcut(var info: keyeventinfoty; const sender: twidget); + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + procedure doasyncevent(var atag: integer); override; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + + //idbnaviglink + procedure setactivebuttons(const abuttons: dbnavigbuttonsty; + const afiltered: boolean); + procedure setcheckedbuttons(const abuttons: dbnavigbuttonsty; + const achecked: boolean); + function getnavigoptions: dbnavigatoroptionsty; + procedure dodialogexecute; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function canclose(const newfocus: twidget = nil): boolean; override; + procedure edit(); + function canautoedit(): boolean; + procedure updatereadonly(const force: boolean = false); + //call onreadonlychange +// property nonavig: boolean read getnonavig write setnonavig; + published + property statfile; + property datasource: tdatasource read getdatasource write setdatasource; + property visiblebuttons: dbnavigbuttonsty read fvisiblebuttons + write setvisiblebuttons default defaultvisibledbnavigbuttons; + property colorglyph: colorty read getcolorglyph write setcolorglyph + default cl_default; + property buttonface: tface read getbuttonface write setbuttonface; + property buttonwidth: integer read getbuttonwidth write setbuttonwidth + default 0; + property buttonheight: integer read getbuttonheight write setbuttonheight + default 0; + property bounds_cx default defaultdbnavigatorwidth; + property bounds_cy default defaultdbnavigatorheight; + property shortcut_first: shortcutty read fshortcuts[dbnb_first] + write fshortcuts[dbnb_first] default key_modctrl + ord(key_pageup); + property shortcut_prior: shortcutty read fshortcuts[dbnb_prior] + write fshortcuts[dbnb_prior] default ord(key_pageup); + property shortcut_next: shortcutty read fshortcuts[dbnb_next] + write fshortcuts[dbnb_next] default ord(key_pagedown); + property shortcut_last: shortcutty read fshortcuts[dbnb_last] + write fshortcuts[dbnb_last] default key_modctrl + ord(key_pagedown); + property shortcut_insert: shortcutty read fshortcuts[dbnb_insert] + write fshortcuts[dbnb_insert] default ord(key_none); + property shortcut_delete: shortcutty read fshortcuts[dbnb_delete] + write fshortcuts[dbnb_delete] default ord(key_none); + property shortcut_copyrecord: shortcutty read fshortcuts[dbnb_copyrecord] + write fshortcuts[dbnb_copyrecord] default ord(key_none); + property shortcut_edit: shortcutty read fshortcuts[dbnb_edit] + write fshortcuts[dbnb_edit] default ord(key_f2); + property shortcut_post: shortcutty read fshortcuts[dbnb_post] + write fshortcuts[dbnb_post] default ord(key_f2); + property shortcut_cancel: shortcutty read fshortcuts[dbnb_cancel] + write fshortcuts[dbnb_cancel] default ord(key_none); + property shortcut_refresh: shortcutty read fshortcuts[dbnb_refresh] + write fshortcuts[dbnb_refresh] default ord(key_none); + property shortcut_filter: shortcutty read fshortcuts[dbnb_filter] + write fshortcuts[dbnb_filter] default ord(key_none); + property shortcut_filtermin: shortcutty read fshortcuts[dbnb_filtermax] + write fshortcuts[dbnb_filtermin] default ord(key_none); + property shortcut_filtermax: shortcutty read fshortcuts[dbnb_filtermax] + write fshortcuts[dbnb_filtermax] default ord(key_none); + property shortcut_filteronoff: shortcutty read fshortcuts[dbnb_filteronoff] + write fshortcuts[dbnb_filteronoff] default ord(key_none); + property shortcut_find: shortcutty read fshortcuts[dbnb_find] + write fshortcuts[dbnb_find] default ord(key_none); + property shortcut_autoedit: shortcutty read fshortcuts[dbnb_autoedit] + write fshortcuts[dbnb_autoedit] default ord(key_none); +// property shortcut_dialog: shortcutty read fshortcuts[dbnb_dialog] +// write fshortcuts[dbnb_dialog] default ord(key_f3); + //use dialogbutton property! + property options: dbnavigatoroptionsty read foptions write setoptions + default defaultdbnavigatoroptions; + property autoedit: boolean read getautoedit write setautoedit default false; +// property dialoghint: msestring read getdialoghint write setdialoghint; +// + property dialogbutton: tdbnavigbutton read gettoolbutton write settoolbutton; + property ondialogexecute: notifyeventty read fondialogexecute + write fondialogexecute; + property onreadonlychange: booleanchangedeventty read fonreadonlychange + write fonreadonlychange; + end; + + tcustomeditwidgetdatalink = class; + + idbeditfieldlink = interface(inullinterface)[miid_idbeditfieldlink] + function getwidget: twidget; + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function getgridintf: iwidgetgrid; + function getgriddatasource: tdatasource; + function getedited: boolean; + function seteditfocus: boolean; + procedure initeditfocus; + function checkvalue(const quiet: boolean = false): boolean; + procedure valuetofield; + procedure fieldtovalue; + procedure setnullvalue; + function getoptionsedit: optionseditty; + procedure updatereadonlystate; + procedure getfieldtypes(var afieldtypes: fieldtypesty); //[] = all + function geteditstate: dataeditstatesty; + procedure seteditstate(const avalue: dataeditstatesty); +// procedure setisdb; + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //iificlient + procedure setifiserverintf(const aintf: iifiserver); + end; + + tgriddatalink = class; + +// editwidgetdatalinkstatety = (ewds_editing,ewds_modified,ewds_filterediting, +// ewds_filtereditdisabled); +// editwidgetdatalinkstatesty = set of editwidgetdatalinkstatety; + + tcustomeditwidgetdatalink = class(tfielddatalink,idbeditinfo,iobjectlink) + private +// fstate: editwidgetdatalinkstatesty; + frecordchange: integer; + fbeginedit: integer; + fmaxlength: integer; + fposting: integer; + fonbeginedit: notifyeventty; + fonendedit: notifyeventty; + fondataentered: notifyeventty; + fnavigator: tdbnavigator; + function canmodify: boolean; + procedure setediting(avalue: boolean); + function getasnullmsestring: msestring; + procedure setasnullmsestring(const avalue: msestring); + procedure readdatasource(reader: treader); + procedure readdatafield(reader: treader); + procedure readoptionsdb(reader: treader); + function getownerwidget: twidget; + procedure setnavigator(const avalue: tdbnavigator); + procedure setoptions(const avalue: optionseditdbty); + protected + fintf: idbeditfieldlink; + foptions: optionseditdbty; + fobjectlinker: tobjectlinker; + function datasourcereadonly(): boolean override; + function getobjectlinker: tobjectlinker; + function getdatasource1: tdatasource; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure activechanged; override; + procedure editingchanged; override; + procedure focuscontrol(afield: tfieldref); override; + procedure updatedata; override; + procedure disabledstatechange; override; + procedure fieldchanged; override; + procedure bindingchanged; + procedure objectevent(const sender: tobject; const event: objecteventty); virtual; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); virtual; + //iifiserver + procedure updateoptionsedit(var avalue: optionseditty); override; + procedure valuechanged(const sender: iifidatalink); override; + public + constructor create(const intf: idbeditfieldlink); + destructor destroy; override; + procedure fixupproperties(filer: tfiler); //read moved properties + procedure recordchanged(afield: tfield); override; + procedure datasetscrolled(distance: integer) override; + procedure nullcheckneeded(var avalue: boolean); + procedure setwidgetdatasource(const avalue: tdatasource); + procedure griddatasourcechanged; + function edit: Boolean; + procedure modified; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); + +// procedure datachanged; +// procedure updateoptionsedit(var aoptions: optionseditty); + function cuttext(const atext: msestring; out maxlength: integer): boolean; + //true if text too long + property options: optionseditdbty read foptions write setoptions + default defaulteditwidgetdatalinkoptions; + property asnullmsestring: msestring read getasnullmsestring + write setasnullmsestring; + //uses nulltext + property navigator: tdbnavigator read fnavigator write setnavigator; + property onbeginedit: notifyeventty read fonbeginedit write fonbeginedit; + property onendedit: notifyeventty read fonendedit write fonendedit; + property ondataentered: notifyeventty read fondataentered + write fondataentered; + property owner: twidget read getownerwidget; + end; + + teditwidgetdatalink = class(tcustomeditwidgetdatalink) + private + published + property datasource: tdatasource read getdatasource1 + write setwidgetdatasource; + property navigator; + property fieldname; + property options; + property onbeginedit; + property onendedit; + property ondataentered; + end; + + tlookupeditdatalink = class(teditwidgetdatalink) + private + ffieldnametext: string; + ffieldtext: tfield; + procedure setfieldnametext(const avalue: string); + protected + fowner: tcustomdataedit; + fdatatype: lookupdatatypety; + procedure updatefields; override; + function getsortfield: tfield; override; + property fieldtext: tfield read ffieldtext; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); override; + public + constructor create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idbeditfieldlink); + function msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; override; + published + property fieldnametext: string read ffieldnametext write setfieldnametext; + end; + + tstringeditwidgetdatalink = class(teditwidgetdatalink) + published + property nullsymbol; + end; + + tstringlookupeditdatalink = class(tlookupeditdatalink) + published + property nullsymbol; + end; + + tdbstringedit = class(tcustomstringedit,idbeditfieldlink,ireccontrol) + private + fdatalink: tstringeditwidgetdatalink; + procedure setdatalink(const adatalink: tstringeditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; +// procedure editnotification(var info: editnotificationinfoty); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + + function getrowdatapo(const arow: integer): pointer; override; + function getnulltext: msestring; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property passwordchar; + property maxlength; + property onsetvalue; + end; + + +{ + tdbdialogstringedit = class(tcustomdialogstringedit,idbeditfieldlink,ireccontrol) + private + fdatalink: tstringeditwidgetdatalink; + procedure setdatalink(const avalue: tstringeditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + function getoptionsedit: optionseditty; override; + procedure dochange; override; + + function getrowdatapo(const info: cellinfoty): pointer; override; + function getnulltext: msestring; override; + + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property passwordchar; + property maxlength; + property onsetvalue; + property onexecute; + end; +} + idbifidropdownlistdatalink = interface(iifidropdownlistdatalink) + end; + + tcustomdbdropdownlistedit = class(tcustomdropdownlistedit,idbeditfieldlink, + ireccontrol,idbifidropdownlistdatalink) + private + fdatalink: tstringeditwidgetdatalink; + fdropdownifilink: tifidropdownlistlinkcomp; + fdropdownifiserverintf: iifiserver; + procedure setdatalink(const avalue: tstringeditwidgetdatalink); + function getdropdownifilink: tifidropdownlistlinkcomp; + procedure setdropdownifilink(const avalue: tifidropdownlistlinkcomp); + procedure dropdownsetifiserverintf(const aintf: iifiserver); + procedure idbifidropdownlistdatalink.setifiserverintf = + dropdownsetifiserverintf; + procedure dropdownifisetvalue(var avalue; var accept: boolean); + procedure idbifidropdownlistdatalink.ifisetvalue = dropdownifisetvalue; + protected + procedure defineproperties(filer: tfiler); override; + + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + function getnulltext: msestring; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property dropdownifilink: tifidropdownlistlinkcomp read getdropdownifilink + write setdropdownifilink; //for dropdownlist + end; + + idbdropdownlist = interface(idropdownlist) + procedure recordselected(const arecordnum: integer; const akey: keyty); + //-2 = empty row, -1 = none + end; + + ilbdropdownlist = interface(idropdownlist) + procedure recordselected(const arecordnum: integer; const akey: keyty); + //-2 = empty row, -1 = none + function getlbkeydatakind: lbdatakindty; + end; + + tdbdropdownlistedit = class(tcustomdbdropdownlistedit) + published + property datalink; + property dropdown; + property dropdownifilink; + property onsetvalue; + property onbeforedropdown; + property onafterclosedropdown; + end; + + tcustomdbdropdownlistcontroller = class; +// tdbdropdownlistcontroller = class; + tdropdownlistcontrollerdb = class; + tcustomlbdropdownlistcontroller = class; + tdropdownlistcontrollerlb = class; + + tdbdropdownlisteditdb = class(tdbdropdownlistedit,idbdropdownlist) + private + function getdropdown: tdropdownlistcontrollerdb; + procedure setdropdown(const avalue: tdropdownlistcontrollerdb); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + published + property dropdown: tdropdownlistcontrollerdb read getdropdown + write setdropdown; + end; + + tdbdropdownlisteditlb = class(tdbdropdownlistedit,ilbdropdownlist) + private + function getdropdown: tdropdownlistcontrollerlb; + procedure setdropdown(const avalue: tdropdownlistcontrollerlb); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + //ilbdropdownlist + function getlbkeydatakind: lbdatakindty; + published + property dropdown: tdropdownlistcontrollerlb read getdropdown + write setdropdown; + end; + + tdropdownlisteditdb = class(tdropdownlistedit,idbdropdownlist) + private + function getdropdown: tdropdownlistcontrollerdb; + procedure setdropdown(const avalue: tdropdownlistcontrollerdb); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + published + property dropdown: tdropdownlistcontrollerdb read getdropdown write setdropdown; + end; + + tdropdownlisteditlb = class(tdropdownlistedit,ilbdropdownlist) + private + function getdropdown: tdropdownlistcontrollerlb; + procedure setdropdown(const avalue: tdropdownlistcontrollerlb); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + //ilbdropdownlist + function getlbkeydatakind: lbdatakindty; + published + property dropdown: tdropdownlistcontrollerlb read getdropdown + write setdropdown; + end; + + tdbkeystringedit = class(tcustomkeystringedit,idbeditfieldlink,ireccontrol) + private + fdatalink: tstringlookupeditdatalink; + procedure setdatalink(const avalue: tstringlookupeditdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + function getnulltext: msestring; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringlookupeditdatalink read fdatalink + write setdatalink; + property dropdown; + property valuedefault; + property onsetvalue; + property onbeforedropdown; + property onafterclosedropdown; + property oninit; + end; + + tdbmemoedit = class(tcustommemoedit,idbeditfieldlink,ireccontrol) + private + fdatalink: tstringeditwidgetdatalink; + procedure setdatalink(const avalue: tstringeditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + function getnulltext: msestring; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property onsetvalue; + property frame; + end; + + tdbintegeredit = class(tcustomintegeredit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function internaldatatotext(const data): msestring; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; +// procedure setnullvalue; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property isnull: boolean read fisnull; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property base; + property bitcount; + property valuemin; + property valuemax; + property onsetvalue; + end; + + tdbbooleanedit = class(tcustombooleanedit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property onsetvalue; + property bounds_cx default defaultboxsize; + property bounds_cy default defaultboxsize; + property group; + end; + + tdbdataicon = class(tcustomdataicon,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; +// function getoptionsedit: optionseditty; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property onsetvalue; + property onpaintglyph; + property valuemin; + property valuemax; + property imagelist; + property imageoffset; + property imagenums; + end; + + tdbdatabutton = class(tcustomdatabutton,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property optionswidget; + property optionsskin; + property valuefaces; + property valuecaptions; + property valuefonts; + property font; + property action; + property caption; + property imagepos; + property shortcut; + property shortcut1; + property textflags; + property captiondist; + property imagelist; + property imagenr; + property imagenrdisabled; + property imagedist; + property imagedist1; + property imagedist2; + property colorglyph; + property options; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + property onmouseevent; + property onclientmouseevent; + + property imageoffset; + property imageoffsetdisabled; + property imageoffsetmouse; + property imageoffsetclicked; + property imagenums; + property onsetvalue; + property onpaintglyph; + property valuedefault; + property valuemin; + property valuemax; + property valuedisabled; + end; + + tdbbooleaneditradio = class(tcustombooleaneditradio,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; + function docheckvalue(var avalue; const quiet: boolean): boolean; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property onsetvalue; + property bounds_cx default defaultboxsize; + property bounds_cy default defaultboxsize; + property group; + end; + + tdbrealedit = class(tcustomrealedit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property valuemin {stored false}; + property valuemax {stored false}; + property formatedit; + property formatdisp; + property valuerange; + property valuestart; + property onsetvalue; + property onsetintvalue; + end; + + tdbrealspinedit = class(tcustomrealspinedit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property valuemin {stored false}; + property valuemax {stored false}; + property formatedit; + property formatdisp; + property valuerange; + property valuestart; + property onsetvalue; + property onsetintvalue; + property step; + end; + + tdbslider = class(tcustomslider,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + fvaluerange: real; + fvaluestart: real; + procedure setdatalink(const avalue: teditwidgetdatalink); + procedure readvaluescale(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; + published + property valuerange: real read fvaluerange write fvaluerange; + property valuestart: real read fvaluestart write fvaluestart; + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property scrollbar; + property onsetvalue; + property direction; + property onpaintglyph; + end; + + tdbprogressbar = class(tcustomprogressbar,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function getrowdatapo(const arow: integer): pointer; override; + procedure griddatasourcechanged; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property onpaintglyph; + end; + + tdbdatetimeedit = class(tcustomdatetimeedit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property valuemin {stored false}; + property valuemax {stored false}; + property formatedit; + property formatdisp; + property kind; + property options; + property onsetvalue; + end; + + tcustomdbenumedit = class(tcustomenumedit,idbeditfieldlink,ireccontrol, + idbifidropdownlistdatalink) + private + fdatalink: tlookupeditdatalink; + fdropdownifilink: tifienumlinkcomp; + fdropdownifiserverintf: iifiserver; + procedure setdatalink(const avalue: tlookupeditdatalink); + function getdropdownifilink: tifienumlinkcomp; + procedure setdropdownifilink(const avalue: tifienumlinkcomp); + procedure dropdownsetifiserverintf(const aintf: iifiserver); + procedure idbifidropdownlistdatalink.setifiserverintf = + dropdownsetifiserverintf; + procedure dropdownifisetvalue(var avalue; var accept: boolean); + procedure idbifidropdownlistdatalink.ifisetvalue = dropdownifisetvalue; + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; virtual; + procedure fieldtovalue; virtual; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property datalink: tlookupeditdatalink read fdatalink write setdatalink; + property dropdownifilink: tifienumlinkcomp read getdropdownifilink + write setdropdownifilink; //for dropdownlist + end; + + tdbenumedit = class(tcustomdbenumedit) + published + property valueoffset; //before value + property datalink; + property dropdown; + property dropdownifilink; + property valuedefault; + property valueempty; + property base; + property bitcount; + property valuemin; + property valuemax; + property onsetvalue; + property onbeforedropdown; + property onafterclosedropdown; + property oninit; + end; + + tdbbooleantextedit = class(tcustomdbenumedit) + private + ftext_false: msestring; + ftext_true: msestring; + function getvalue: boolean; + procedure setvalue(const avalue: boolean); + procedure settext_false(const avalue: msestring); + procedure settext_true(const avalue: msestring); + procedure booltextchanged; + protected + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; override; + procedure fieldtovalue; override; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + public + constructor create(aowner: tcomponent); override; + property value: boolean read getvalue write setvalue; + published + property text_false: msestring read ftext_false write settext_false; + property text_true: msestring read ftext_true write settext_true; + property datalink; + property valuedefault; + property onsetvalue; + end; + + tnolistdropdowncol = class(tdropdowncol) + end; + + tnolistdropdowncols = class(tdropdowncols) + end; + + tdbdropdowncol = class(tnolistdropdowncol,idbeditinfo) + private + fdatafield: string; + procedure setdatafield(const avalue: string); + protected + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + published + property datafield: string read fdatafield write setdatafield; + end; + + tdbdropdowncols = class(tnolistdropdowncols) + private + function getitems(const index: integer): tdbdropdowncol; + protected + function getcolclass: dropdowncolclassty; override; + public + property items[const index: integer]: tdbdropdowncol read getitems; default; + end; + + tdropdownlistdatalink = class; + + dropdowndatalinkstatety = (ddlnks_lookupvalid); + dropdowndatalinkstatesty = set of dropdowndatalinkstatety; + + tdropdowndatalink = class(tmsedatalink) + private + fowner: tcustomdbdropdownlistcontroller; + fvaluefield: tfield; + fvaluefieldname: string; + ftextfield: tfield; + procedure setvaluefield(value: tfield); + procedure setvaluefieldname(const value: string); + procedure settextfield(value: tfield); + procedure updatefields; + procedure updatelookupvalue; + function getvalueasmsestring: msestring; + function getvalueasinteger: integer; + function getvalueaslargeint: int64; + function gettextasmsestring: msestring; + protected + fdataintf: idbdata; + fkeyindex: integer; + ftextindex: integer; + flookuptext: msestring; + flastintegerkey: integer; + flastint64key: int64; + flaststringkey: msestring; + fstate: dropdowndatalinkstatesty; + procedure layoutchanged; override; + procedure activechanged; override; + procedure editingchanged; override; + public + constructor create(const aowner: tcustomdbdropdownlistcontroller); + function getlookuptext(const key: integer): msestring; overload; + function getlookuptext(const key: int64): msestring; overload; + function getlookuptext(const key: msestring): msestring; overload; + property valuefieldName: string read fvaluefieldname write setvaluefieldname; + property valuefield: tfield read fvaluefield; + property valueasmsestring: msestring read getvalueasmsestring; + property valueasinteger: integer read getvalueasinteger; + property valueaslargeint: int64 read getvalueaslargeint; + property textfield: tfield read ftextfield; + property textasmsestring: msestring read gettextasmsestring; + end; + + tdbdropdownstringcol = class(tdropdownstringcol) + private + fdatalink: tfielddatalink; + protected + function getrowtext(const arow: integer): msestring; override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + end; + + igriddatalink = interface(inullinterface)[miid_iggriddatalink] + function getdbindicatorcol: integer; + procedure setnavigator(const avalue: tdbnavigator); + function getdatalink(): tgriddatalink; + end; + + gridrowinfoty = record + row: integer; + end; + + griddatalinkstatety = (gdls_hasrowstatefield,gdls_booleanmerged, + gdls_booleanselected); + griddatalinkstatesty = set of griddatalinkstatety; + + tgriddatalink = class(tfieldsdatalink,ievent,idbeditinfo,iobjectlink) + private + fintf: igriddatalink; + fgrid: tcustomgrid; + factiverecordbefore: integer; + ffirstrecordshift: integer; + fzebraoffset: integer; + ffirstrecordbefore: integer; + fdatasetstatebefore: tdatasetstate; + fdummystringbuffer: ansistring; + fansistringbuffer: ansistring; + fstringbuffer: msestring; + fintegerbuffer: integer; + fint64buffer: int64; + frealtybuffer: realty; + fgridinvalidated: boolean; + fstate: griddatalinkstatesty; + foptions: griddatalinkoptionsty; + fonupdaterowdata: updaterowdataeventty; + fnullchecking: integer; + fdatasetchangedlock: integer; + fobjectlinker: tobjectlinker; +// fcolordatalink: tfielddatalink; +// ffontdatalink: tfielddatalink; + frowexited: integer; + feditingbefore: boolean; + fautoinserting: boolean; + finserting: boolean; + finsertingbefore: boolean; + fonbeginedit: notifyeventty; + fonendedit: notifyeventty; + ffield_state: tfield; + ffieldname_state: string; + ffield_color: tfield; + ffieldname_color: string; + ffield_font: tfield; + ffieldname_font: string; + ffield_readonly: tfield; + ffieldname_readonly: string; + ffield_merged: tfield; + ffieldname_merged: string; + ffield_selected: tfield; + ffieldname_selected: string; + fnavigator: tdbnavigator; + fdescend: boolean; + fsortdatalink: tfielddatalink; + fmovebydistance: int32; + procedure checkzebraoffset; + procedure checkscroll; + procedure checkscrollbar; virtual; + procedure doupdaterowdata(const row: integer); + procedure beginnullchecking; + procedure endnullchecking; + procedure setfieldname_state(const avalue: string); + procedure forcecalcrange; + function getobjectlinker: tobjectlinker; + function updateoptionsgrid(const avalue: optionsgridty): optionsgridty; + function updatesortfield(const avalue: tfielddatalink; + const adescend: boolean): boolean; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); virtual; + procedure objevent(const sender: iobjectlink; const event: objecteventty); virtual; + function getinstance: tobject; + //ievent + procedure receiveevent(const event: tobjectevent); + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + function getdatasource1: tdatasource; + procedure settadasource1(const avalue: tdatasource); + procedure setfield_state(const avalue: tfield); + procedure setfield_color(const avalue: tfield); + procedure setfield_font(const avalue: tfield); + procedure setfield_readonly(const avalue: tfield); + procedure setfield_merged(const avalue: tfield); + procedure setfield_selected(const avalue: tfield); + procedure readdatafield(reader: treader); + procedure setfieldname_merged(const avalue: string); + procedure setfieldname_selected(const avalue: string); + procedure setfieldname_color(const avalue: string); + procedure setfieldname_font(const avalue: string); + procedure setfieldname_readonly(const avalue: string); + procedure setnavigator(const avalue: tdbnavigator); + protected + function canautoinsert: boolean; + procedure checkdelayedautoinsert; + function checkvalue: boolean; + procedure updatelayout; + procedure updaterowcount; + function begingridrow(const arow: integer; + out ainfo: gridrowinfoty): boolean; + //false if row invalid + procedure endgridrow(const ainfo: gridrowinfoty); + function getfirstrecord: integer; virtual; + procedure checkactiverecord; virtual; + function getrecordcount: integer; override; + procedure datasetscrolled(distance: integer); override; + procedure fieldchanged; override; + procedure activechanged; override; + procedure editingchanged; override; + procedure recordchanged(afield: tfield); override; + procedure datasetchanged; override; + procedure updatedata; override; + procedure updatefields; override; + procedure focuscell(var cell: gridcoordty); virtual; + procedure cellevent(var info: celleventinfoty); virtual; + procedure invalidateindicator; + function scrollevent(sender: tcustomscrollbar; + event: scrolleventty): boolean; virtual; + //true if processed + procedure doinsertrow; + procedure doappendrow; + procedure dodeleterow; + procedure rowdown; + procedure lastrow; + procedure firstrow; + function getzebrastart: integer; + procedure gridinvalidate; + function arecord: integer; + function hasdata: boolean; + procedure readdatasource(reader: treader); + procedure fixupproperties(filer: tfiler); //read moved properties + procedure defineproperties(filer: tfiler); override; + public + constructor create(const aowner: tcustomgrid; const aintf: igriddatalink); + destructor destroy; override; + property firstrecord: integer read getfirstrecord; + function getdummystringbuffer: pansistring; + function getrowfieldisnull(const afield: tfield; const row: integer): boolean; + function getansistringbuffer(const afield: tfield; const row: integer): pointer; + function getstringbuffer(const afield: tfield; const row: integer): pointer; + function getdisplaystringbuffer(const afield: tfield; const row: integer{; + const aedit: boolean}): pointer; + function getbooleanbuffer(const afield: tfield; const row: integer): pointer; + function getintegerbuffer(const afield: tfield; const row: integer): pointer; + function getint64buffer(const afield: tfield; const row: integer): pointer; + function getrealtybuffer(const afield: tfield; const row: integer): pointer; + function getdatetimebuffer(const afield: tfield; const row: integer): pointer; + function canclose(const newfocus: twidget): boolean; + procedure painted; + procedure loaded; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); + procedure setselected(const cell: gridcoordty; + const avalue: boolean); + procedure beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); + function domoveby(const distance: integer): integer; virtual; + function moveby(distance: integer): integer; override; + function rowtorecnozerobased(const row: integer): integer; + function isfirstrow: boolean; + function islastrow: boolean; + property owner: tcustomgrid read fgrid; + property field_state: tfield read ffield_state; + property field_color: tfield read ffield_color; + property field_font: tfield read ffield_font; + property field_readonly: tfield read ffield_readonly; + property field_merged: tfield read ffield_merged; + property field_selected: tfield read ffield_selected; + published + property options: griddatalinkoptionsty read foptions write foptions + default defaultgriddatalinkoptions; + property onupdaterowdata: updaterowdataeventty read fonupdaterowdata + write fonupdaterowdata; + property datasource: tdatasource read getdatasource1 write settadasource1; + property fieldname_state: string read ffieldname_state + write setfieldname_state; + //integer field, selects grid rowcolor (field value and $7f), + //readonlystate (field value and $80) and + //grid rowfont ((fieldvalue shr 8) and $7f). + // $xx7f = default color, $7fxx = default font. + property fieldname_color: string read ffieldname_color + write setfieldname_color; + property fieldname_font: string read ffieldname_font + write setfieldname_font; + property fieldname_readonly: string read ffieldname_readonly + write setfieldname_readonly; + property fieldname_merged: string read ffieldname_merged + write setfieldname_merged; + property fieldname_selected: string read ffieldname_selected + write setfieldname_selected; + property navigator: tdbnavigator read fnavigator write setnavigator; + property onbeginedit: notifyeventty read fonbeginedit write fonbeginedit; + property onendedit: notifyeventty read fonendedit write fonendedit; + end; + + rowpositionty = (ropo_nearest,ropo_centeredif,ropo_bottom, + ropo_centered,ropo_top); + tdropdownlistdatalink = class(tgriddatalink) + private + fdataintf: idbdata; + fkeyindex: integer; + ftextindex: integer; + ffirstrecord: integer; + fcurrentrecord: integer; + fmaxrowcount: integer; + procedure setcurrentrecord(const avalue: integer; + const arowpos: rowpositionty); + procedure updatedatawindow(const arowpos: rowpositionty); + protected + function getasmsestring(const afield: tfield): msestring; + function getasinteger(const afield: tfield): integer; + function getaslargeint(const afield: tfield): int64; + + procedure cellevent(var info: celleventinfoty); override; + function getrecordcount: integer; override; + //workaround FPC bug 19290 +// function GetBufferCount: Integer; override; + procedure SetBufferCount(Value: Integer); override; + function getfirstrecord: integer; override; + procedure updatefocustext; + procedure recordchanged(afield: tfield); override; + function GetActiveRecord: Integer; override; + procedure SetActiveRecord(Value: Integer); override; + procedure checkscrollbar; override; + function scrollevent(sender: tcustomscrollbar; + event: scrolleventty): boolean; override; + //true if processed + procedure focuscell(var cell: gridcoordty); override; + property currentrecord: integer read fcurrentrecord{ write setcurrentrecord}; + public + constructor create(const aowner: tcustomgrid; const aintf: igriddatalink; + const adatalink: tdropdowndatalink); + function domoveby(const distance: integer): integer; override; + end; + + tdbdropdownlist = class(tdropdownlist,igriddatalink) + private + fdatalink: tdropdownlistdatalink; + //igriddatalink + function getdbindicatorcol: integer; + procedure setnavigator(const avalue: tdbnavigator); + function getdatalink(): tgriddatalink; + protected + function getassistiveflags(): assistiveflagsty override; + procedure internalcreateframe; override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure initcols(const acols: tdropdowncols); override; + procedure docellevent(var info: celleventinfoty); override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + procedure setactiveitem(const aitemindex: integer); override; + function locate(const filter: msestring): boolean; override; + procedure dopaint(const acanvas: tcanvas); override; + procedure dohide; override; + + public + constructor create(const acontroller: tcustomdbdropdownlistcontroller; + acols: tdropdowncols); + destructor destroy; override; + procedure rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false) override; + procedure rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false) override; + procedure pageup(const action: focuscellactionty = fca_focusin); override; + procedure pagedown(const action: focuscellactionty = fca_focusin); override; + procedure wheelup(const action: focuscellactionty = fca_focusin); override; + procedure wheeldown(const action: focuscellactionty = fca_focusin); override; + end; + +// dbdropdownliststatety = (ddls_isstringkey); +// dbdropdownliststatesty = set of dbdropdownliststatety; + + tcustomdbdropdownlistcontroller = class( + tcustomdropdownlistcontroller,idbeditinfo) + private + fdatalink: tdropdowndatalink; +// fisstringkey: boolean; + foptionsdatalink: griddatalinkoptionsty; + foptionsdb: optionsdbty; + fbookmarks: stringarty; + function getdatasource: tdatasource; overload; + procedure setdatasource(const avalue: tdatasource); + procedure setkeyfield(const avalue: string); + function getkeyfield: string; + function getcols: tdbdropdowncols; + procedure setcols(const avalue: tdbdropdowncols); + procedure setoptionsdb(const avalue: optionsdbty); + protected +// fstate: dbdropdownliststatesty; + procedure valuecolchanged; override; + function getbuttonframeclass: dropdownbuttonframeclassty; override; + function getdropdowncolsclass: dropdowncolsclassty; override; + function createdropdownlist: tdropdownlist; override; + function candropdown: boolean; override; + procedure itemselected(const index: integer; const akey: keyty); override; + procedure doafterclosedropdown; override; + + function getasmsestring(const afield: tfield; const utf8: boolean): msestring; + function getasinteger(const afield: tfield): integer; + function getaslargeint(const afield: tfield): int64; + + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + public + constructor create(const intf: idbdropdownlist; const aisstringkey: boolean); + destructor destroy; override; + procedure dropdown; override; + property datalink: tdropdowndatalink read fdatalink; + property datasource: tdatasource read getdatasource write setdatasource; + property keyfield: string read getkeyfield write setkeyfield; + property options default defaultdbdropdownoptions; + property optionsdatalink: griddatalinkoptionsty read foptionsdatalink + write foptionsdatalink default defaultdropdowndatalinkoptions; + property optionsdb: optionsdbty read foptionsdb write setoptionsdb default []; + + property cols: tdbdropdowncols read getcols write setcols; + end; + + tdbdropdownlistcontroller = class(tcustomdbdropdownlistcontroller) + published + property datasource; + property keyfield; + property options; + property optionsdatalink; + property optionsdb; + property cols; + property dropdownrowcount; + property delay; + property valuecol; + property width; + property datarowlinewidth; + property datarowlinecolor; + property buttonlength; + property buttonminlength; + property buttonendlength; + end; + + tdropdownlistcontrollerdb = class(tcustomdbdropdownlistcontroller) + published + property datasource; +// property keyfield; + property options; + property optionsdatalink; + property optionsdb; + property cols; + property dropdownrowcount; + property delay; + property valuecol; + property width; + property datarowlinewidth; + property datarowlinecolor; + property buttonlength; + property buttonminlength; + property buttonendlength; + end; + + tdbenumeditdb = class(tdbenumedit,idbdropdownlist,ireccontrol) + private + function getdropdown: tdbdropdownlistcontroller; + procedure setdropdown(const avalue: tdbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + function internaldatatotext(const data): msestring; override; + published + property dropdown: tdbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tenumeditdb = class(tenumedit,idbdropdownlist) + private + function getdropdown: tdbdropdownlistcontroller; + procedure setdropdown(const avalue: tdbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + function internaldatatotext(const data): msestring; override; + published + property dropdown: tdbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tdbkeystringeditdb = class(tdbkeystringedit,idbdropdownlist,ireccontrol) + private +// fkeyvalue: msestring; + function getdropdown: tdbdropdownlistcontroller; + procedure setdropdown(const avalue: tdbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + function internaldatatotext(const data): msestring; override; + published + property dropdown: tdbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tkeystringeditdb = class(tkeystringedit,idbdropdownlist) + private + function getdropdown: tdbdropdownlistcontroller; + procedure setdropdown(const avalue: tdbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + function internaldatatotext(const data): msestring; override; + published + property dropdown: tdbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tdbwidgetindicatorcol = class(twidgetfixcol) + private + fcolorindicator: colorty; + procedure setcolorindicator(const avalue: colorty); + protected + procedure drawcell(const canvas: tcanvas); override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + published + property colorindicator: colorty read fcolorindicator + write setcolorindicator default cl_glyph; + property options default defaultindicatorcoloptions; + end; + + tdbwidgetfixcols = class(twidgetfixcols) + private + fdbindicatorcol: integer; + fdatalink: tgriddatalink; + procedure setdbindicatorcol(const Value: integer); + function getdbindicatorcol: integer; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure setcount1(acount: integer; doinit: boolean); override; + public + constructor create(const aowner: tcustomwidgetgrid; + const adatalink: tgriddatalink); + published + property dbindicatorcol: integer read getdbindicatorcol + write setdbindicatorcol default -1; + end; + + tdbscrollbar = class(tthumbtrackscrollbar) + protected + procedure setoptions(const avalue: scrollbaroptionsty); override; + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property options default defaultdbscrollbaroptions; + property buttonlength default -1; + end; + + tdbgridframe = class(tgridframe) + protected + procedure scrollpostoclientpos(var aclientrect: rectty); override; + function getscrollbarclass(vert: boolean): framescrollbarclassty; override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + public + constructor create(const aintf: iscrollframe; const owner: twidget; + const autoscrollintf: iautoscrollframe); + end; + + tdbwidgetcol = class(twidgetcol) + protected + fdatalink: tfielddatalink; + + procedure dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); override; + procedure doafterdrawcell(const acanvas: tcanvas); override; + procedure setwidget(const awidget: twidget); override; + public + property datalink: tfielddatalink read fdatalink; + end; + + tdbwidgetcols = class(twidgetcols) + private + function getcols(const index: integer): tdbwidgetcol; + protected + public + class function getitemclasstype: persistentclassty; override; + property cols[const index: integer]: tdbwidgetcol read getcols; default; + end; + + tcustomdbwidgetgrid = class(tcustomwidgetgrid,igriddatalink) + private + fdatalink: tgriddatalink; +// function getdatasource: tdatasource; +// procedure setdatasource(const Value: tdatasource); + function getdatalink: tgriddatalink; + procedure setdatalink(const avalue: tgriddatalink); + function getfixcols: tdbwidgetfixcols; + procedure setfixcols(const avalue: tdbwidgetfixcols); + function getdatacols: tdbwidgetcols; + procedure setdatacols(const avalue: tdbwidgetcols); + protected + function getassistiveflags(): assistiveflagsty override; + function createdatacols: tdatacols; override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + function canautoappend: boolean; override; + function getgriddatalink: pointer; override; + procedure setoptionsgrid(const avalue: optionsgridty); override; + function getfieldlink(const acol: integer): tcustomeditwidgetdatalink; + function updatesortcol(const avalue: integer): integer; override; + procedure internalcreateframe; override; + function createfixcols: tfixcols; override; + procedure dolayoutchanged; override; + procedure docellevent(var info: celleventinfoty); override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + function getzebrastart: integer; override; + function getnumoffset: integer; override; + procedure dopaint(const acanvas: tcanvas); override; + procedure dohide; override; + procedure loaded; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + + procedure setselected(const cell: gridcoordty; + const avalue: boolean); override; + procedure doinsertrow(const sender: tobject); override; + procedure doappendrow(const sender: tobject); override; + procedure dodeleterow(const sender: tobject); override; + procedure beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); override; + function caninsertrow: boolean; override; + function canappendrow: boolean; override; + function candeleterow: boolean; override; + function isfirstrow: boolean; override; + function islastrow: boolean; override; + procedure defineproperties(filer: tfiler); override; +// procedure doenter; override; +// procedure doexit; override; + //igriddatalink + function getdbindicatorcol: integer; + procedure setnavigator(const avalue: tdbnavigator); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; override; + //true if ok + function canclose(const newfocus: twidget): boolean; override; + procedure rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure pageup(const action: focuscellactionty = fca_focusin); override; + procedure pagedown(const action: focuscellactionty = fca_focusin); override; + procedure wheelup(const action: focuscellactionty = fca_focusin); override; + procedure wheeldown(const action: focuscellactionty = fca_focusin); override; + procedure lastrow(const action: focuscellactionty = fca_focusin); override; + procedure firstrow(const action: focuscellactionty = fca_focusin); override; +// property datasource: tdatasource read getdatasource write setdatasource; + property datalink: tgriddatalink read fdatalink write setdatalink; + property zebra_step default 0; + property fixcols: tdbwidgetfixcols read getfixcols write setfixcols; + property datacols: tdbwidgetcols read getdatacols write setdatacols; + end; + + tdbwidgetgrid = class(tcustomdbwidgetgrid) + published +// property datasource; + property optionsgrid; + property optionsgrid1; + property fixcols; + property fixrows; +// property font; + property fontempty; + property gridframecolor; +// property gridframewidth; + property rowcolors; + property rowfonts; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property datacols; + property datalink; + + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datarowheight; + property datarowheightmin; + property datarowheightmax; + + property statfile; + property statvarname; + property statpriority; + + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property oncolmoving; + property oncolmoved; + property onrowcountchanged; + property onrowdatachanged; + property onrowsdatachanged; +// property onrowsmoving; +// property onrowsmoved; +// property onrowsinserting; +// property onrowsinserted; +// property onrowsdeleting; +// property onrowsdeleted; + property oncellevent; + property onsortchanged; + property drag; + end; + + tstringcoldatalink = class(tcustomeditwidgetdatalink) + private +// fowner: tcustomstringcol; + protected + procedure updatedata; override; + procedure layoutchanged; override; + end; + + tdbstringcol = class(tcustomstringcol,idbeditfieldlink, + idbeditinfo,iificlient,iifidatalink) + private + fdatalink: tstringcoldatalink; + fmaxlength: integer; + fifiserverintf: iifiserver; + function getdatafield: string; + procedure setdatafield(const avalue: string); + //iifidatalink + procedure setifiserverintf(const aintf: iifiserver); + function getdefaultifilink: iificlient; virtual; + function getifilinkkind: ptypeinfo; + function getifidatatype(): listdatatypety virtual; + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue); //for pointer property without RTTI + procedure setifivalue(const avalue); //for pointer property without RTTI + + //idbeditinfo + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); overload; + function getdataset(const aindex: integer): tdataset; + function getoptionsdb: optionseditdbty; + procedure setoptionsdb(const avalue: optionseditdbty); + function getnullsymbol: msestring; + procedure setnullsymbol(const avalue: msestring); + protected + function getoptionsedit: optionseditty; override; + function getitems(aindex: integer): msestring; override; + procedure setitems(aindex: integer; const Value: msestring); override; + procedure modified; override; + procedure dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); override; + procedure doafterdrawcell(const acanvas: tcanvas); override; + function getrowtext(const arow: integer): msestring; override; + function createdatalist: tdatalist; override; +// procedure docellevent(var info: celleventinfoty); override; + procedure docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); override; + //idbeditfieldlink + procedure getfieldtypes(var afieldtypes: fieldtypesty); overload; + function getgriddatasource: tdatasource; virtual; + function getgridintf: iwidgetgrid; + function getwidget: twidget; + function seteditfocus: boolean; + function getedited: boolean; + procedure initeditfocus; + function checkvalue(const quiet: boolean = false): boolean; + procedure valuetofield; + procedure fieldtovalue; + procedure setnullvalue; + procedure updatereadonlystate; + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + property datalink: tstringcoldatalink read fdatalink; + published + property datafield: string read getdatafield write setdatafield; + property optionsdb: optionseditdbty read getoptionsdb write setoptionsdb default []; + property nullsymbol: msestring read getnullsymbol write setnullsymbol; + property focusrectdist; + property textflags; + property textflagsactive; + property optionsedit1; //before optionsedit! + property optionsedit; + property passwordchar; + property font; + property colorselect; + property fontselect; + property onsetvalue; + property ondataentered; + property oncopytoclipboard; + property onpastefromclipboard; + property ondrawcell; + end; + + tdbstringcols = class(tstringcols) + private + foptionsdb: optionseditdbty; + function getcols(const index: integer): tdbstringcol; + procedure setoptionsdb(const avalue: optionseditdbty); + protected + function getcolclass: stringcolclassty; override; + procedure datasourcechanged; override; + public + class function getitemclasstype: persistentclassty; override; + property cols[const index: integer]: tdbstringcol read getcols; default; //last! + published + property optionsdb: optionseditdbty read foptionsdb write setoptionsdb default []; + end; + + tdbstringindicatorcol = class(tfixcol) + private + fcolorindicator: colorty; + procedure setcolorindicator(const avalue: colorty); + protected + procedure drawcell(const canvas: tcanvas); override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + published + property colorindicator: colorty read fcolorindicator + write setcolorindicator default cl_glyph; + property options default defaultindicatorcoloptions; + end; + + tdbstringfixcols = class(tfixcols) + private + fdbindicatorcol: integer; + fdatalink: tgriddatalink; + procedure setdbindicatorcol(const Value: integer); + function getdbindicatorcol: integer; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure setcount1(acount: integer; doinit: boolean); override; + public + constructor create(const aowner: tcustomgrid; + const adatalink: tgriddatalink); + published + property dbindicatorcol: integer read getdbindicatorcol + write setdbindicatorcol default -1; + end; + + dbstringgridoptionty = (dsgo_autofields); + dbstringgridoptionsty = set of dbstringgridoptionty; + + tstringgriddatalink = class(tgriddatalink) + protected + procedure activechanged; override; + end; + + tcustomdbstringgrid = class(tcustomstringgrid,iwidgetgrid,igriddatalink) + private + fdatalink: tstringgriddatalink; + foptions: dbstringgridoptionsty; + ffieldnamedisplayfixrow: integer; +// function getdatasource: tdatasource; +// procedure setdatasource(const Value: tdatasource); + function getdatacols: tdbstringcols; + procedure setdatacols(const avalue: tdbstringcols); + + //iwidgetgrid (dummy) + function getbrushorigin: pointty; + function getcol: twidgetcol; + procedure getdata(var index: integer; var dest); + procedure setdata(var index: integer; const source; + const noinvalidate: boolean = false); + procedure datachange(const arow: integer); + function getrow: integer; + procedure setrow(arow: integer); + procedure changed(); + procedure edited(); + function empty(index: integer): boolean; + procedure updateeditoptions(var aoptions: optionseditty; + const aoptions1: optionsedit1ty); + procedure showrect(const arect: rectty; const aframe: tcustomframe); + procedure widgetpainted(const canvas: tcanvas); + function nullcheckneeded(const newfocus: twidget): boolean; + function nonullcheck: boolean; + function getgrid: tcustomwidgetgrid; + function getdatapo(const arow: integer): pointer; + function getrowdatapo: pointer; + {$ifdef mse_with_ifi} + procedure updateifigriddata(const alist: tdatalist); + {$endif} + procedure setoptions(const avalue: dbstringgridoptionsty); + procedure checkautofields; + procedure setfieldnamedisplayfixrow(const avalue: integer); + function getdatalink: tgriddatalink; //igriddatalink + procedure setdatalink(const avalue: tstringgriddatalink); + function getfixcols: tdbstringfixcols; + procedure setfixcols(const avalue: tdbstringfixcols); + protected + function getassistiveflags(): assistiveflagsty override; + function canautoappend: boolean; override; + procedure setupeditor(const acell: gridcoordty; const focusin: boolean); override; +// procedure doenter; override; +// procedure doexit; override; + //igriddatalink + function getdbindicatorcol: integer; + procedure setnavigator(const avalue: tdbnavigator); + + procedure setselected(const cell: gridcoordty; + const avalue: boolean); override; + procedure updatelayout; override; +// procedure editnotification(var info: editnotificationinfoty); override; + procedure setoptionsgrid(const avalue: optionsgridty); override; + function getfieldlink(const acol: integer): tfielddatalink; + function updatesortcol(const avalue: integer): integer; override; + procedure doasyncevent(var atag: integer); override; + procedure internalcreateframe; override; +// function getoptionsedit: optionseditty; override; + function createfixcols: tfixcols; override; + function createdatacols: tdatacols; override; +// procedure initcellinfo(var info: cellinfoty); override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + function getzebrastart: integer; override; + function getnumoffset: integer; override; + procedure checkcellvalue(var accept: boolean); override; + procedure dopaint(const acanvas: tcanvas); override; + procedure dohide; override; + procedure loaded; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + function cangridcopy: boolean; + + function caninsertrow: boolean; override; + function canappendrow: boolean; override; + function candeleterow: boolean; override; + + procedure doinsertrow(const sender: tobject); override; + procedure doappendrow(const sender: tobject); override; + procedure dodeleterow(const sender: tobject); override; + procedure beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); override; + procedure coloptionstoeditoptions(var dest: optionseditty; + var dest1: optionsedit1ty); + function isfirstrow: boolean; override; + function islastrow: boolean; override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; override; + //true if ok + procedure docellevent(var info: celleventinfoty); override; + function canclose(const newfocus: twidget): boolean; override; + procedure rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure pageup(const action: focuscellactionty = fca_focusin); override; + procedure pagedown(const action: focuscellactionty = fca_focusin); override; + procedure wheelup(const action: focuscellactionty = fca_focusin); override; + procedure wheeldown(const action: focuscellactionty = fca_focusin); override; + procedure lastrow(const action: focuscellactionty = fca_focusin); override; + procedure firstrow(const action: focuscellactionty = fca_focusin); override; +// property datasource: tdatasource read getdatasource write setdatasource; + property datacols: tdbstringcols read getdatacols write setdatacols; + property datalink: tstringgriddatalink read fdatalink write setdatalink; + property options: dbstringgridoptionsty read foptions + write setoptions default []; + property fieldnamedisplayfixrow: integer read ffieldnamedisplayfixrow write + setfieldnamedisplayfixrow default -1; + //negative rowindex, 0-> none + property zebra_step default 0; + property fixcols: tdbstringfixcols read getfixcols write setfixcols; + end; + + tdbstringgrid = class(tcustomdbstringgrid) + published +// property datasource; + property options; + property fieldnamedisplayfixrow; + + property optionsgrid; + property optionsgrid1; + property datacols; + property datalink; + property fixcols; + property fixrows; + property gridframecolor; +// property gridframewidth; + property rowcolors; + property rowfonts; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datarowheight; + property datarowheightmin; + property datarowheightmax; + property caretwidth; + + property statfile; + property statvarname; + property statpriority; + + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property oncolmoving; + property oncolmoved; + property onrowcountchanged; + property onrowdatachanged; + property onrowsdatachanged; +// property onrowsmoving; +// property onrowsmoved; +// property onrowsinserting; +// property onrowsinserted; +// property onrowsdeleting; +// property onrowsdeleted; + property oncellevent; + property onsortchanged; + property drag; + end; + + tlbdropdownlistcontroller = class; + + tlbdropdownstringcol = class(tdropdownstringcol) + private + flookupbuffer: tcustomlookupbuffer; + ffieldno: integer; + fsortfieldno: integer; + funsorted: boolean; + protected + function getrowtext(const arow: integer): msestring; override; + public + end; + + tcopydropdownlist = class(tdropdownlist) + private + protected + function locate(const filter: msestring): boolean; override; + end; + + eddstatety = (edds_filtered,edds_bof,edds_eof); + eddstatesty = set of eddstatety; + + texterndatadropdownlistcontroller = class; + + texterndatadropdownlist = class(tdropdownlist) + private + ffirstrecord: integer; + frecnums: integerarty; + feddstate: eddstatesty; + function getactiverecord: integer; + procedure setactiverecord(const avalue: integer); + protected + procedure dokeydown(var info: keyeventinfoty); override; + procedure findprev(var recno: integer); + procedure findnext(var recno: integer); virtual; abstract; + function getrecno(const aindex: integer): integer; + procedure dorowcountchanged(const countbefore,newcount: integer); override; + procedure internalcreateframe; override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure docellevent(var info: celleventinfoty); override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + procedure dbscrolled(distance: integer); + procedure moveby(distance: integer); + procedure filterchanged; + procedure resyncfilter; + property activerecord: integer read getactiverecord write setactiverecord; + public + constructor create(const acontroller: texterndatadropdownlistcontroller; + acols: tdropdowncols); + procedure rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure pageup(const action: focuscellactionty = fca_focusin); override; + procedure pagedown(const action: focuscellactionty = fca_focusin); override; + procedure wheelup(const action: focuscellactionty = fca_focusin); override; + procedure wheeldown(const action: focuscellactionty = fca_focusin); override; + end; + + tlbdropdownlist = class(texterndatadropdownlist) + private + protected + procedure initcols(const acols: tdropdowncols); override; + function locate(const filter: msestring): boolean; override; + procedure findnext(var recno: integer); override; + public + constructor create(const acontroller: tcustomlbdropdownlistcontroller; + acols: tdropdowncols); + end; + + tlbdropdowncol = class(tdropdowncol,ilookupbufferfieldinfo) + private + ffieldno: lookupbufferfieldnoty; + procedure setfieldno(const avalue: lookupbufferfieldnoty); + protected + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + published + property fieldno: lookupbufferfieldnoty read ffieldno write setfieldno + default 0; + //colindex in lookupbuffer + end; + + tlbdropdowncols = class(tnolistdropdowncols) + private + function getitems(const index: integer): tlbdropdowncol; + protected + function getcolclass: dropdowncolclassty; override; + public + property items[const index: integer]: tlbdropdowncol read getitems; default; + end; + + optionlbty = (olb_copyitems,olb_unsorted); + optionslbty = set of optionlbty; + + texterndatadropdownlistcontroller = class(tcustomdropdownlistcontroller) + private + fedrecnums: integerarty; + protected + procedure dofilter(var recno: integer; var accept: boolean); virtual; abstract; + procedure valuecolchanged; override; + function getbuttonframeclass: dropdownbuttonframeclassty; override; + function getdropdowncolsclass: dropdowncolsclassty; override; + public + constructor create(const intf: ilbdropdownlist); + procedure dropdown; override; + property options default defaulteddropdownoptions; + end; + + tcustomlbdropdownlistcontroller = class(texterndatadropdownlistcontroller, + ilookupbufferfieldinfo) + private + fsortfieldno: integer; + flookupbuffer: tcustomlookupbuffer; + fkeyfieldno: lookupbufferfieldnoty; + fonfilter: lbfiltereventty; + foptionslb: optionslbty; + fonbeforefilter: dataediteventty; + function getcols: tlbdropdowncols; + procedure setcols(const avalue: tlbdropdowncols); + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + protected + procedure dofilter(var recno: integer; var accept: boolean); override; + function reloadlist: integer; override; + function createdropdownlist: tdropdownlist; override; + function candropdown: boolean; override; + procedure itemselected(const index: integer; const akey: keyty); override; + procedure objectevent(const sender: tobject; const event: objecteventty); override; + function getremoterowcount: integer; override; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + property optionslb: optionslbty read foptionslb write foptionslb default []; + property cols: tlbdropdowncols read getcols write setcols; + property lookupbuffer: tcustomlookupbuffer read flookupbuffer write setlookupbuffer; + property keyfieldno: lookupbufferfieldnoty read fkeyfieldno write fkeyfieldno default 0; + property onfilter: lbfiltereventty read fonfilter write fonfilter; + property onbeforefilter: dataediteventty read fonbeforefilter + write fonbeforefilter; + end; + + tlbdropdownlistcontroller = class(tcustomlbdropdownlistcontroller) + published + property lookupbuffer; + property keyfieldno; + property optionslb; + property options; + property cols; + property onbeforefilter; + property onfilter; + property dropdownrowcount; + property delay; + property valuecol; + property width; + property datarowlinewidth; + property datarowlinecolor; + property buttonlength; + property buttonminlength; + property buttonendlength; + end; + + tdropdownlistcontrollerlb = class(tcustomlbdropdownlistcontroller) + published + property lookupbuffer; +// property keyfieldno; + property optionslb; + property options; + property cols; + property onbeforefilter; + property onfilter; + property dropdownrowcount; + property delay; + property valuecol; + property width; + property datarowlinewidth; + property datarowlinecolor; + property buttonlength; + property buttonminlength; + property buttonendlength; + end; + + tdbenumeditlb = class(tdbenumedit,ilbdropdownlist) + private + function getdropdown: tlbdropdownlistcontroller; + procedure setdropdown(const avalue: tlbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + function getlbkeydatakind: lbdatakindty; + published + property dropdown: tlbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tenumeditlb = class(tenumedit,ilbdropdownlist) + private + function getdropdown: tlbdropdownlistcontroller; + procedure setdropdown(const avalue: tlbdropdownlistcontroller); + {$ifdef mse_with_ifi} + function getifilink: tifiintegerlinkcomp; + procedure setifilink1(const avalue: tifiintegerlinkcomp); + {$endif} + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + function getlbkeydatakind: lbdatakindty; + public + published + property dropdown: tlbdropdownlistcontroller read getdropdown write setdropdown; +{$ifdef mse_with_ifi} + property ifilink: tifiintegerlinkcomp read getifilink write setifilink1; +{$endif} + end; + + tcustomenum64edit = class(tcustomdropdownlistedit) + private + fonsetvalue1: setint64eventty; + function getgridvalue(const index: integer): int64; + procedure setgridvalue(const index: integer; aValue: int64); + function getgridvalues: int64arty; + procedure setgridvalues(const avalue: int64arty); + procedure setvalue(const avalue: int64); + {$ifdef mse_with_ifi} + function getifilink: tifiint64linkcomp; + procedure setifilink1(const avalue: tifiint64linkcomp); + {$endif} + protected + fvalue1: int64; + fvaluedefault1: int64; + + function getdefaultvalue: pointer; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure texttodata(const atext: msestring; var data); override; + procedure setnullvalue; override; //for dbedits + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + + {$ifdef mse_with_ifi} + function getifidatalinkintf: iifidatalink; override; + //iifidatalink + function getifilinkkind: ptypeinfo; override; + {$endif} + public + constructor create(aowner: tcomponent); override; + property gridvalue[const index: integer]: int64 + read getgridvalue write setgridvalue; default; + property gridvalues: int64arty read getgridvalues write setgridvalues; + property value: int64 read fvalue1 write setvalue default -1; +{$ifdef mse_with_ifi} + property ifilink: tifiint64linkcomp read getifilink write setifilink1; +{$endif} + property valuedefault: int64 read fvaluedefault1 write fvaluedefault1 default -1; + property onsetvalue: setint64eventty read fonsetvalue1 write fonsetvalue1; + end; + + tcustomenum64editlb = class(tcustomenum64edit,ilbdropdownlist) + private + function getdropdown: tlbdropdownlistcontroller; + procedure setdropdown(const avalue: tlbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + function getlbkeydatakind: lbdatakindty; + public + property dropdown: tlbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tenum64editlb = class(tcustomenum64editlb) + published +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property value; + property valuedefault; + property onsetvalue; + end; + + tdbenum64editlb = class(tcustomenum64editlb,idbeditfieldlink,ireccontrol) + private + fdatalink: tlookupeditdatalink; + procedure setdatalink(const avalue: tlookupeditdatalink); + protected + procedure defineproperties(filer: tfiler); override; + + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; virtual; + procedure fieldtovalue; virtual; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tlookupeditdatalink read fdatalink write setdatalink; + property dropdown; + property onsetvalue; + end; + + tcustomenum64editdb = class(tcustomenum64edit,idbdropdownlist) + private + function getdropdown: tdbdropdownlistcontroller; + procedure setdropdown(const avalue: tdbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + public + property dropdown: tdbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tenum64editdb = class(tcustomenum64editdb) + published +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property value; + property valuedefault; + property onsetvalue; + end; + + tdbenum64editdb = class(tcustomenum64editdb,idbeditfieldlink,ireccontrol) + private + fdatalink: tlookupeditdatalink; + procedure setdatalink(const avalue: tlookupeditdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; virtual; + procedure fieldtovalue; virtual; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tlookupeditdatalink read fdatalink write setdatalink; + property dropdown; + property onsetvalue; + end; + + tdbkeystringeditlb = class(tdbkeystringedit,ilbdropdownlist) + private + function getdropdown: tlbdropdownlistcontroller; + procedure setdropdown(const avalue: tlbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + function getlbkeydatakind: lbdatakindty; + published + property dropdown: tlbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tkeystringeditlb = class(tkeystringedit,ilbdropdownlist) + private + function getdropdown: tlbdropdownlistcontroller; + procedure setdropdown(const avalue: tlbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + function getlbkeydatakind: lbdatakindty; + published + property dropdown: tlbdropdownlistcontroller read getdropdown write setdropdown; + end; + +function encoderowstate(const color: integer = -1; const font: integer = -1; + const readonly: boolean = false): integer; + +implementation +uses + msestockobjects,mseshapes,msereal,msebits, + mseassistiveserver, + mseactions,mseact,rtlconsts,msedrawtext,sysutils,msedbdispwidgets; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcomponent1 = class(tcomponent); + twidget1 = class(twidget); + tcustomgrid1 = class(tcustomgrid); + tcustomdataedit1 = class(tcustomdataedit); + tdatacols1 = class(tdatacols); + tdropdowncols1 = class(tdropdowncols); + tdataedit1 = class(tdataedit); + tdataset1 = class(tdataset); + tdatasource1 = class(tdatasource); + ttoolbuttons1 = class(ttoolbuttons); + tcustomstringgrid1 = class(tcustomstringgrid); + treader1 = class(treader); + tcols1 = class(tcols); + + hasactiveeditinfoty = record + field: tfield; + hasedit: boolean; + end; + phasactiveeditinfoty = ^hasactiveeditinfoty; + +function encoderowstate(const color: integer = -1; const font: integer = -1; + const readonly: boolean = false): integer; +begin + result:= (color and $7f) or ((font and $7f) shl 8); + if readonly then begin + result:= result or $80; + end; +end; + +procedure drawindicatorcell(const canvas: tcanvas; const datalink: tgriddatalink; + const acolor: colorty); +var + glyph: stockglyphty; +begin + with cellinfoty(canvas.drawinfopo^) do begin + with datalink do begin + case dataset.state of + dsbrowse: glyph:= stg_dbindbrowse; + dsedit: glyph:= stg_dbindedit; + dsinsert: glyph:= stg_dbindinsert; + else glyph:= stockglyphty(-1); + end; + if ord(glyph) >= 0 then begin + stockobjects.glyphs.paint(canvas,ord(glyph),innerrect, + [al_xcentered,al_ycentered],acolor); + end; + end; + end; +end; + +function confirmdeleterecord: boolean; +begin + with stockobjects do begin + result:= askok(captions[sc_Delete_record_question],captions[sc_confirmation]) + end; +end; + +function confirmcopyrecord: boolean; +begin + with stockobjects do begin + result:= askok(captions[sc_Copy_record_question],captions[sc_confirmation]) + end; +end; + +{ tnavigdatalink } + +constructor tnavigdatalink.Create(const intf: idbnaviglink); +begin + fintf:= intf; + inherited create; + visualcontrol:= true; + fintf.setactivebuttons([],false); +end; + +procedure tnavigdatalink.updatebuttonstate; +var + bu1: dbnavigbuttonsty; + bo1: boolean; + options1: dbnavigatoroptionsty; +begin + options1:= fintf.getnavigoptions; + bu1:= [dbnb_autoedit]; + if dno_dialogifinactive in options1 then begin + bu1:= bu1+[dbnb_dialog]; + end; + bo1:= false; + if active then begin + bu1:= bu1+[dbnb_first,dbnb_prior,dbnb_next,dbnb_last]+ + filterdbnavigbuttons+[dbnb_dialog]; + if bof then begin + bu1:= bu1 - [dbnb_first,dbnb_prior]; + end; + if eof then begin + bu1:= bu1 - [dbnb_next,dbnb_last]; + end; + if (dno_dialogifinactive in options1) and bof and eof then begin + bu1:= bu1 - [dbnb_dialog]; + end; + if (dno_nodialogifnoeditmode in options1) and + not (datasource.state in dseditmodes) then begin + bu1:= bu1 - [dbnb_dialog]; + end; + if (dno_nodialogifreadonly in options1) and not canupdate then begin + bu1:= bu1 - [dbnb_dialog]; + end; + case datasource.state of + dsfilter: begin + case filtereditkind of + fek_filter: bu1:= [dbnb_filter]; + fek_filtermin: bu1:= [dbnb_filtermin]; + fek_filtermax: bu1:= [dbnb_filtermax]; + fek_find: bu1:= [dbnb_find]; + end; + fintf.setcheckedbuttons(bu1,true); + bu1:= bu1+[dbnb_filterclear]; + end; + dsedit,dsinsert: begin + bu1:= bu1 + [dbnb_post,dbnb_cancel,dbnb_refresh,dbnb_insert,dbnb_delete]; + if (datasource.state = dsinsert) and + (dno_nomultiinsert in options1) then begin + exclude(bu1,dbnb_insert); + end; + end; + else begin + fintf.setcheckedbuttons( + [dbnb_filter,dbnb_filtermin,dbnb_filtermax,dbnb_find],false); + bu1:= bu1 + [dbnb_refresh,dbnb_insert,dbnb_delete,dbnb_edit, + dbnb_filteronoff,dbnb_copyrecord]; + end; + end; +// if (fdscontroller <> nil) and fdscontroller.noedit then begin +// bu1:= bu1 - editnavigbuttons; +// end; + if not canupdate then begin + bu1:= bu1 - [dbnb_edit,dbnb_autoedit]; + end; + if dno_append in options1 then begin + if not canappend then begin + bu1:= bu1 - [dbnb_insert,dbnb_copyrecord]; + end; + end + else begin + if not caninsert then begin + bu1:= bu1 - [dbnb_insert,dbnb_copyrecord]; + end; + end; + if not candelete then begin + exclude(bu1,dbnb_delete); + end; + if bof and eof then begin + bu1:= bu1 - [dbnb_delete,dbnb_copyrecord]; + end; +// if not datasource.dataset.canmodify then begin +// bu1:= bu1 - [dbnb_edit,dbnb_delete,dbnb_insert,dbnb_copyrecord]; +// end; + if csdesigning in dataset.componentstate then begin + bu1:= bu1 * designdbnavigbuttons; + end; + bo1:= datasource.dataset.filtered; + end; + if dno_nonavig in options1 then begin + bu1:= bu1 - ([dbnb_first,dbnb_prior,dbnb_next,dbnb_last, + dbnb_insert,dbnb_delete,dbnb_filteronoff,dbnb_copyrecord]+ + filterdbnavigbuttons); + end; + if dno_nodelete in options1 then begin + bu1:= bu1 - [dbnb_delete]; + end; + if dno_noinsert in options1 then begin + bu1:= bu1 - [dbnb_insert]; + end; + if dno_noedit in options1 then begin + bu1:= bu1 - [dbnb_edit]; + end; + fintf.setactivebuttons(bu1,bo1); +end; + +procedure tnavigdatalink.activechanged; +var + intf1: igetdscontroller; +begin + fdscontroller:= nil; + if active then begin + if getcorbainterface(dataset,typeinfo(igetdscontroller),intf1) then begin + fdscontroller:= intf1.getcontroller; + end; + end; + inherited; + updatebuttonstate; +end; + +procedure tnavigdatalink.datasetchanged; +begin + inherited; + updatebuttonstate; +end; + +procedure tnavigdatalink.editingchanged; +begin + inherited; + updatebuttonstate(); + fintf.updatereadonly(); + with twidget1(fintf.getwidget) do begin + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; + end; +end; + +procedure tnavigdatalink.recordchanged(field: tfield); +begin + inherited; + updatebuttonstate; +end; + +procedure tnavigdatalink.execbutton(const abutton: dbnavigbuttonty); +var + widget1: twidget; + options1: dbnavigatoroptionsty; + intf1: iassistiveclient; +begin + if (datasource <> nil) and (datasource.State <> dsinactive) then begin + widget1:= fintf.getwidget; + options1:= fintf.getnavigoptions; + if not (abutton in [dbnb_cancel,dbnb_delete,dbnb_autoedit]) then begin + if dno_candefocuswindow in options1 then begin + if not widget1.rootwidget.canparentclose then begin + exit; + end; + end + else begin + if (widget1.parentwidget <> nil) and + not widget1.parentwidget.canparentclose then begin + exit; + end; + end; + end; + with datasource.dataset do begin + case abutton of + dbnb_first: first; + dbnb_prior: begin + include(fstate,nds_prior); + exclude(fstate,nds_datasetscrolled); + try + self.moveby(-1); + if not (nds_datasetscrolled in fstate) and canassistive(intf1) then begin + assistiveserver.dodatasetevent(intf1,adek_bof,dataset); + end; + finally + exclude(fstate,nds_prior); + end; + end; + dbnb_next: begin + include(fstate,nds_next); + try + self.moveby(1); + finally + exclude(fstate,nds_next); + end; + end; + dbnb_last: last; + dbnb_insert: begin + if dno_append in options1 then begin + append; + end + else begin + insert; + end; + end; + dbnb_delete: begin + if not (dno_confirmdelete in options1) or confirmdeleterecord then begin + delete; + end; + end; + dbnb_edit: edit; + dbnb_post: post; + dbnb_cancel: cancel; + dbnb_refresh: begin + if dscontroller <> nil then begin + dscontroller.refresh(not (dno_norefreshrecno in options1)); + end + else begin + refresh; + end; + end; + dbnb_filteronoff: filtered:= not filtered; + dbnb_dialog: begin + if (dno_postbeforedialog in options1) and (state in dseditmodes) then begin + post; + end; + fintf.dodialogexecute; + end; + dbnb_autoedit: begin + with twidget1(widget1) do begin + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; + end; + fintf.updatereadonly(); + end; + dbnb_copyrecord: begin + if (dscontroller <> nil) and + not (dno_confirmcopy in options1) or confirmcopyrecord then begin + dscontroller.copyrecord(dno_append in options1); + end; + end; + end; + if fdscontroller <> nil then begin + if state = dsfilter then begin + case abutton of + dbnb_filterclear: fdscontroller.clearfilter(); + else begin + fdscontroller.endfilteredit; + end; + end; + end + else begin + case abutton of + dbnb_filter: fdscontroller.beginfilteredit(fek_filter); + dbnb_filtermin: fdscontroller.beginfilteredit(fek_filtermin); + dbnb_filtermax: fdscontroller.beginfilteredit(fek_filtermax); + dbnb_filterclear: fdscontroller.clearfilter(); + dbnb_find: fdscontroller.beginfilteredit(fek_find); + end; + end; + end; + end; + end; +end; + +procedure tnavigdatalink.disabledstatechange; +begin + updatebuttonstate; +end; + +function tnavigdatalink.canassistive(out aintf: iassistiveclient): boolean; +var + wi1: twidget1; +begin + result:= false; + aintf:= nil; + if (assistiveserver <> nil) and active then begin + wi1:= twidget1(fintf.getwidget()); + result:= wi1.window.active; + if result then begin + aintf:= wi1.getiassistiveclient(); + end; + end; +end; + +procedure tnavigdatalink.datasetscrolled(distance: integer); +var + k1: assistivedbeventkindty; + intf1: iassistiveclient; +begin + include(fstate,nds_datasetscrolled); + inherited; + if (distance = 0) and canassistive(intf1) then begin + k1:= adek_none; + if nds_prior in fstate then begin + k1:= adek_bof; + end; + if nds_next in fstate then begin + k1:= adek_eof; + end; + if k1 <> adek_none then begin + assistiveserver.dodatasetevent(intf1,k1,dataset); + end; + end; +end; + +{ tdbnavigator } +const + dbnavigimages: array[dbnavigbuttonty] of stockglyphty = + //dbnb_first,dbnb_prior,dbnb_next,dbnb_last,dbnb_insert, + (stg_dbfirst,stg_dbprior,stg_dbnext,stg_dblast,stg_dbinsert, + +// dbnb_delete,dbnb_copyrecord,dbnb_edit, + stg_dbdelete,stg_doublesquare,stg_dbedit, +// dbnb_post,dbnb_cancel,dbnb_refresh, + stg_dbpost,stg_dbcancel,stg_dbrefresh, +// dbnb_filter,dbnb_filtermin,dbnb_filtermax,dbnb_filterclear,dbnb_filteronoff, + stg_dbfilter,stg_dbfiltermin,stg_dbfiltermax,stg_dbfilterclear,stg_dbfilteron, +// dbnb_find, + stg_dbfind, +// dbnb_autoedit,dbnb_dialog + stg_triabig,stg_ellipsesmall +); + + dbnavighints: array[dbnavigbuttonty] of stockcaptionty = + //dbnb_first,dbnb_prior,dbnb_next,dbnb_last,dbnb_insert, + (sc_first,sc_prior,sc_next,sc_last,sc_append, + +// dbnb_delete,dbnb_copyrecord,dbnb_edit, + sc_delete,sc_copy,sc_edit, +// dbnb_post,dbnb_cancel,dbnb_refresh, + sc_post,sc_cancel,sc_refresh, +// dbnb_filter,dbnb_filtermin, dbnb_filtermax, dbnb_filterclear, + sc_edit_filter,sc_edit_filter_min,sc_edit_filter_max,sc_reset_filter, +// dbnb_filteronoff,dbnb_find, + sc_filter_on,sc_search, +// dbnb_autoedit,dbnb_dialog + sc_auto_edit,sc_dialog +); + +{ tdbnavigbuttons } + +class function tdbnavigbuttons.getbuttonclass: toolbuttonclassty; +begin + result:= tdbnavigbutton; +end; + +constructor tdbnavigator.create(aowner: tcomponent); +var + int1: integer; +begin + if flayout.buttons = nil then begin + flayout.buttons:= tdbnavigbuttons.create(self); + end; + foptions:= defaultdbnavigatoroptions; + fshortcuts[dbnb_first]:= key_modctrl + ord(key_pageup); + fshortcuts[dbnb_prior]:= ord(key_pageup); + fshortcuts[dbnb_next]:= ord(key_pagedown); + fshortcuts[dbnb_last]:= key_modctrl + ord(key_pagedown); + fshortcuts[dbnb_edit]:= ord(key_f2); + fshortcuts[dbnb_post]:= ord(key_f2); +// fshortcuts[dbnb_dialog]:= ord(key_f3); + inherited; + fwidgetstate1:= fwidgetstate1 + [ws1_designactive,ws1_nodisabledclick]; + size:= makesize(defaultdbnavigatorwidth,defaultdbnavigatorheight); + include(ttoolbuttons1(buttons).fbuttonstate,tbs_nocandefocus); + buttons.count:= ord(high(dbnavigbuttonty))+1; + for int1:= 0 to ord(high(dbnavigbuttonty)) do begin + with buttons[int1] do begin + imagelist:= stockobjects.glyphs; + imagenr:= ord(dbnavigimages[dbnavigbuttonty(int1)]); + tag:= int1; + onexecute:= {$ifdef FPC}@{$endif}doexecute; + end; + end; + with buttons[ord(dbnb_autoedit)] do begin + options:= options + [mao_checkbox]; + end; + with buttons[ord(dbnb_filter)] do begin + options:= options + [mao_checkbox]; + end; + with buttons[ord(dbnb_filtermin)] do begin + options:= options + [mao_checkbox]; + end; + with buttons[ord(dbnb_filtermax)] do begin + options:= options + [mao_checkbox]; + end; + with buttons[ord(dbnb_find)] do begin + options:= options + [mao_checkbox]; + end; + with buttons[ord(dbnb_filteronoff)] do begin + options:= options + [mao_checkbox]; + end; + + fdatalink:= tnavigdatalink.Create(idbnaviglink(self)); + visiblebuttons:= defaultvisibledbnavigbuttons; +end; + +destructor tdbnavigator.destroy; +begin +// fdatalink.Free; + inherited; + fdatalink.Free; +end; + +procedure tdbnavigator.inithints; +var + int1: integer; + sc1: int32; +begin + for int1:= 0 to ord(high(dbnavigbuttonty)) do begin + with buttons[int1] do begin +// hint:= stockobjects.captions[stockcaptionty(int1+ord(sc_first))]; + hint:= stockobjects.captions[dbnavighints[dbnavigbuttonty(int1)]]; + if (dno_shortcuthint in foptions) then begin + if dbnavigbuttonty(int1) = dbnb_dialog then begin + sc1:= shortcut; + end + else begin + sc1:= fshortcuts[dbnavigbuttonty(int1)]; + end; + if sc1 <> 0 then begin + hint:= hint + ' (' + encodeshortcutname(sc1)+')'; + end; + end; + end; + end; + with buttons[ord(dbnb_insert)] do begin + if dno_append in self.options then begin + hint:= stockobjects.captions[sc_append]; + end + else begin + hint:= stockobjects.captions[sc_insert]; + end; + if (dno_shortcuthint in foptions) and + (fshortcuts[dbnb_insert] <> 0) then begin + hint:= hint + ' (' + + encodeshortcutname(fshortcuts[dbnb_insert])+')'; + end; + end; +end; + +procedure tdbnavigator.doasyncevent(var atag: integer); +begin + if atag = 0 then begin + application.mouseparkevent; + end + else begin + inherited; + end; +end; + +procedure tdbnavigator.setactivebuttons(const abuttons: dbnavigbuttonsty; + const afiltered: boolean); +var + bu1: dbnavigbuttonty; +begin + beginupdate; + try + with buttons[ord(dbnb_filteronoff)] do begin + checked:= afiltered; + { + if afiltered then begin + imagenr:= ord(stg_dbfilteroff); + hint:= stockobjects.captions[sc_filter_off]; + end + else begin + imagenr:= ord(stg_dbfilteron); + hint:= stockobjects.captions[sc_filter_on]; + end; + if (dno_shortcuthint in foptions) and + (fshortcuts[dbnb_filteronoff] <> 0) then begin + hint:= hint + ' (' + + encodeshortcutname(fshortcuts[dbnb_filteronoff])+')'; + end; + } + end; + for bu1:= low(dbnavigbuttonty) to high(dbnavigbuttonty) do begin + if (bu1 <> dbnb_dialog) or not (dno_customdialogupdate in foptions) then begin + with buttons[ord(bu1)] do begin + if bu1 in abuttons then begin + state:= state - [as_disabled]; + end + else begin + state:= state + [as_disabled]; + end; + end; + end; + end; + dialogbutton.doupdate; + finally + endupdate; + end; + if application.mousewidget = self then begin + asyncevent(0); + end; +end; + +procedure tdbnavigator.setcheckedbuttons(const abuttons: dbnavigbuttonsty; + const achecked: boolean); +var + bu1: dbnavigbuttonty; +begin + beginupdate; + try + for bu1:= low(dbnavigbuttonty) to high(dbnavigbuttonty) do begin + if bu1 in abuttons then begin + with buttons[ord(bu1)] do begin + if achecked then begin + state:= state + [as_checked]; + end + else begin + state:= state - [as_checked]; + end; + end; + end; + end; + dialogbutton.doupdate; + finally + endupdate; + end; +end; + +function tdbnavigator.getdatasource: tdatasource; +begin + result:= fdatalink.DataSource; +end; + +procedure tdbnavigator.setvisiblebuttons(const avalue: dbnavigbuttonsty); +var + bu1: dbnavigbuttonty; +begin + if fvisiblebuttons <> avalue then begin + beginupdate; + for bu1:= low(dbnavigbuttonty) to high(dbnavigbuttonty) do begin + buttons[ord(bu1)].visible:= bu1 in avalue; + end; + fvisiblebuttons:= avalue; + endupdate; + end; +end; + +function tdbnavigator.getcolorglyph: colorty; +begin + result:= buttons.colorglyph; +end; + +procedure tdbnavigator.setcolorglyph(const avalue: colorty); +begin + buttons.colorglyph:= avalue; +end; + +function tdbnavigator.getbuttonface: tface; +begin + result:= buttons.face; +end; + +procedure tdbnavigator.setbuttonface(const avalue: tface); +begin + buttons.face:= avalue; +end; + +procedure tdbnavigator.loaded; +begin + inherited; + colorglyph:= colorglyph; + inithints; + updatereadonly(true); +end; + +procedure tdbnavigator.internalshortcut(var info: keyeventinfoty; + const sender: twidget); +var + bu1: dbnavigbuttonty; +begin + if not (csdesigning in componentstate) then begin + for bu1:= low(dbnavigbuttonty) to dbnb_autoedit do begin + if checkshortcutcode(fshortcuts[bu1],info) then begin + if buttons[ord(bu1)].enabled or + (assistiveserver <> nil) and (bu1 in [dbnb_prior,dbnb_next]) then begin + fdatalink.execbutton(bu1); + include(info.eventstate,es_processed); + break; + end; + end; + end; + end; +end; + +procedure tdbnavigator.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + internalshortcut(info,sender); + if not (es_processed in info.eventstate) then begin; + inherited; + end; +end; + +procedure tdbnavigator.setdatasource(const Value: tdatasource); +begin + fdatalink.DataSource:= value; +end; + +procedure tdbnavigator.doexecute(const sender: tobject); +begin + with ttoolbutton(sender) do begin + fdatalink.execbutton(dbnavigbuttonty(tag)); + if action <> nil then begin + action.execute(); + end; + end; +end; + +function tdbnavigator.getnavigoptions: dbnavigatoroptionsty; +begin + result:= foptions; +end; + +procedure tdbnavigator.setoptions(const avalue: dbnavigatoroptionsty); +var + diff: dbnavigatoroptionsty; +begin + diff:= avalue >< foptions; + if diff <> [] then begin + foptions:= avalue; + if not (csloading in componentstate) then begin + inithints; + if dno_nonavig in diff then begin + fdatalink.updatebuttonstate() + end; + end; + end; +end; + +procedure tdbnavigator.dodialogexecute(); +begin + if canevent(tmethod(fondialogexecute)) then begin + fondialogexecute(self); + end; +end; + +procedure tdbnavigator.updatereadonly(const force: boolean = false); +var + b1: boolean; +begin + b1:= canautoedit; + if (b1 <> fcanautoeditbefore) or force then begin + fcanautoeditbefore:= b1; + if canevent(tmethod(fonreadonlychange)) then begin + fonreadonlychange(self,not b1); + end; + end; +end; + +function tdbnavigator.gettoolbutton: tdbnavigbutton; +begin + result:= tdbnavigbutton(buttons[ord(dbnb_dialog)]); +end; + +procedure tdbnavigator.settoolbutton(const avalue: tdbnavigbutton); +begin + buttons[ord(dbnb_dialog)]:= avalue; +end; + +function tdbnavigator.getautoedit: boolean; +begin + result:= buttons[ord(dbnb_autoedit)].checked; +end; + +procedure tdbnavigator.setautoedit(const avalue: boolean); +begin + if buttons[ord(dbnb_autoedit)].checked <> avalue then begin + buttons[ord(dbnb_autoedit)].checked:= avalue; + updatereadonly(); + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; + end; +end; + +procedure tdbnavigator.dostatread(const reader: tstatreader); +begin + autoedit:= reader.readboolean('autoedit',autoedit); +end; + +procedure tdbnavigator.dostatwrite(const writer: tstatwriter); +begin + writer.writeboolean('autoedit',autoedit); +end; + +procedure tdbnavigator.edit; +var + int1: integer; +begin + if fdatalink.active and (fdatalink.dataset.state = dsbrowse) then begin + int1:= -1; + if buttons[ord(dbnb_edit)].enabled then begin + int1:= ord(dbnb_edit); + end + else begin + if buttons[ord(dbnb_insert)].enabled then begin + int1:= ord(dbnb_insert); + end + end; + if int1 >= 0 then begin + fdatalink.execbutton(dbnavigbuttonty(int1)); + end; + end; +end; + +function tdbnavigator.canautoedit(): boolean; +begin + result:= autoedit or fdatalink.active and + (fdatalink.dataset.state in [dsedit,dsinsert]) +end; + +function tdbnavigator.canclose(const newfocus: twidget = nil): boolean; +begin + if (dno_postoncanclose in foptions) and fdatalink.active and + (newfocus = nil) then begin + fdatalink.dataset.checkbrowsemode; + end; + result:= inherited canclose(newfocus); +end; + +function tdbnavigator.getbuttonwidth: integer; +begin + result:= flayout.buttons.width; +end; + +procedure tdbnavigator.setbuttonwidth(const avalue: integer); +begin + flayout.buttons.width:= avalue; +end; + +function tdbnavigator.getbuttonheight: integer; +begin + result:= flayout.buttons.height; +end; + +procedure tdbnavigator.setbuttonheight(const avalue: integer); +begin + flayout.buttons.height:= avalue; +end; +{ +function tdbnavigator.getnonavig: boolean; +begin + result:= dno_nonavig in foptions; +end; + +procedure tdbnavigator.setnonavig(const avalue: boolean); +begin + if avalue then begin + options:= options + [dno_nonavig]; + end + else begin + options:= options - [dno_nonavig]; + end; +end; +} +{ tcustomeditwidgetdatalink } + +constructor tcustomeditwidgetdatalink.create(const intf: idbeditfieldlink); +//var +// intf1: iificlient; +begin + foptions:= defaulteditwidgetdatalinkoptions; + fintf:= intf; + fintf.setifiserverintf(iifidataserver(self)); +// if getcorbainterface(intf.getwidget,typeinfo(iificlient),intf1) then begin +// intf1.setifiserverintf(iifiserver(self)); +// end; + inherited Create; + visualcontrol:= true; + fintf.seteditstate(fintf.geteditstate+[des_isdb]); +// fintf.setisdb; +end; + +destructor tcustomeditwidgetdatalink.destroy; +begin + inherited; + freeandnil(fobjectlinker); +end; + +procedure tcustomeditwidgetdatalink.readdatasource(reader: treader); +begin + treader1(reader).readpropvalue(self, + getpropinfo(typeinfo(teditwidgetdatalink),'datasource')); +end; + +procedure tcustomeditwidgetdatalink.readdatafield(reader: treader); +begin + fieldname:= reader.readstring; +end; + +procedure tcustomeditwidgetdatalink.readoptionsdb(reader: treader); +begin + treader1(reader).readpropvalue(self, + getpropinfo(typeinfo(teditwidgetdatalink),'options')); +end; + +procedure tcustomeditwidgetdatalink.fixupproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('datasource',{$ifdef FPC}@{$endif}readdatasource,nil,false); + filer.defineproperty('datafield',{$ifdef FPC}@{$endif}readdatafield,nil,false); + filer.defineproperty('optionsdb',{$ifdef FPC}@{$endif}readoptionsdb,nil,false); + //move values to datalink +end; + +function tcustomeditwidgetdatalink.getasnullmsestring: msestring; +begin + if field.isnull then begin + result:= nullsymbol; + end + else begin + result:= asmsestring; + end; +end; + +procedure tcustomeditwidgetdatalink.setasnullmsestring(const avalue: msestring); +begin + if avalue = nullsymbol then begin + if oed_nonullset in foptions then begin + asmsestring:= msedefaultexpression; + end + else begin + field.clear; + end; + end + else begin + asmsestring:= avalue; + end; +end; + +procedure tcustomeditwidgetdatalink.setediting(avalue: boolean); +begin + if (fds_editing in fstate) <> avalue then begin + if avalue then begin + include(fstate,fds_editing); + end + else begin + exclude(fstate,fds_editing); + end; + exclude(fstate,fds_modified); + end; +end; + +function tcustomeditwidgetdatalink.edit: Boolean; +begin + if canmodify then begin + if (dataset.state = dsbrowse) and + ((oed_autoedit in foptions) or + (fnavigator <> nil) and fnavigator.canautoedit() + ) then begin + dataset.edit; + end + else begin + inherited edit; + end; + end; + result:= fds_editing in fstate; +end; + +function tcustomeditwidgetdatalink.canmodify: Boolean; +begin + result:= (field <> nil) and + ((fds_filterediting in fstate) or + canupdate and not field.readonly); +end; + +procedure tcustomeditwidgetdatalink.modified; +begin + if not editing and (frecordchange = 0) and + not (fds_filterediting in fstate) then begin + inc(fbeginedit); + try + edit; + finally + dec(fbeginedit); + end; + end; + include(fstate,fds_modified); +end; + +procedure tcustomeditwidgetdatalink.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + if (info.eventstate * [es_preview,es_processed] = []) and + (fnavigator <> nil) and fnavigator.showing and + fnavigator.isenabled then begin + fnavigator.internalshortcut(info,sender); + end; +end; + +procedure tcustomeditwidgetdatalink.updateoptionsedit(var avalue: optionseditty); +var + state1: tcomponentstate; +begin + state1:= fintf.getwidget.ComponentState; + if state1 * [cswriting,csdesigning] = [] then begin + if not (fds_filterediting in fstate) and + (not canmodify or + not editing and + not (canmodify and + not (oed_noautoedit in foptions) and + ((oed_autoedit in foptions) or + (datasource <> nil) and datasource.AutoEdit or + (fnavigator <> nil) and fnavigator.canautoedit + ) + ) + ) then begin + include(avalue,oe_readonly); + end; + if (field <> nil) and field.required then begin + include(avalue,oe_notnull); + end; + end; +end; + +procedure tcustomeditwidgetdatalink.editingchanged; +var + widget1: twidget; +begin + inherited; + widget1:= fintf.getwidget; + if not editing and assigned(fonendedit) and + widget1.canevent(tmethod(fonendedit)) then begin + fonendedit(self); + end; + setediting(inherited editing and canmodify); + fintf.updatereadonlystate; + if editing then begin + if (fnavigator <> nil) and (oed_syncedittonavigator in foptions) and + (dataset.state = dsedit) then begin + fnavigator.edit(); + end; + if (oed_focusoninsert in foptions) and (dataset.state = dsinsert) then begin + fintf.seteditfocus(); + end; + if assigned(fonbeginedit) and + fintf.getwidget.canevent(tmethod(fonbeginedit)) then begin + fonbeginedit(self); + end; + end; +end; + +procedure tcustomeditwidgetdatalink.dataevent(event: tdataevent; info: ptrint); +var + bo1: boolean; + bo2: boolean; +begin + bo1:= fds_filterediting in fstate; + case ord(event) of + ord(deupdatestate): begin + if (dataset <> nil) and (dataset.state = dsfilter) then begin + include(fstate,fds_filterediting); + end + else begin + exclude(fstate,fds_filterediting); + end; + end; + de_hasactiveedit: begin + with phasactiveeditinfoty(info)^ do begin + hasedit:= hasedit or (field = self.field) and + fintf.getwidget.window.active; + end; + end; + end; + inherited; + if bo1 <> (fds_filterediting in fstate) then begin + if bo1 then begin + if fds_filtereditdisabled in fstate then begin + exclude(fstate,fds_filtereditdisabled); + fintf.setenabled(true); + end; + end + else begin + case filtereditkind of + fek_filtermin: bo2:= oed_nofilterminedit in foptions; + fek_filtermax: bo2:= oed_nofiltermaxedit in foptions; + fek_find: bo2:= oed_nofindedit in foptions; + else bo2:= oed_nofilteredit in foptions; //fek_filter + end; + if bo2 then begin + include(fstate,fds_filtereditdisabled); + fintf.setenabled(false); + end; + end; + fintf.updatereadonlystate; + end; +end; + +procedure tcustomeditwidgetdatalink.bindingchanged; +begin + if active and (field <> nil) and isstringfield{ + (field.datatype in [ftstring,ftfixedchar])} then begin + if ismsestring then begin + fmaxlength:= tmsestringfield(field).characterlength; + end + else begin + fmaxlength:= field.size; + end; + if fmaxlength < 0 then begin + fmaxlength:= 0; + end; + end + else begin + fmaxlength:= 0; + end; + + if oed_limitcharlen in foptions then begin + if fmaxlength = 0 then begin + fintf.setmaxlength(-1); + end + else begin + fintf.setmaxlength(fmaxlength); + end; + end; +end; + +procedure tcustomeditwidgetdatalink.activechanged; +begin + if not active then begin + fstate:= fstate - [fds_filterediting,fds_filtereditdisabled]; + end; + fintf.updatereadonlystate; + try + inherited; + except + on e: exception do begin + e.message:= fintf.getwidget.name + ': ' + e.message; + raise + end; + end; + bindingchanged; +end; + +procedure tcustomeditwidgetdatalink.disabledstatechange; +begin + inherited; + fintf.updatereadonlystate; +end; + +function tcustomeditwidgetdatalink.getdataset(const aindex: integer): tdataset; +begin + result:= dataset; +end; + +procedure tcustomeditwidgetdatalink.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + setlength(afieldtypes,1); + fintf.getfieldtypes(afieldtypes[0]); + if afieldtypes[0] = [] then begin + afieldtypes:= nil; + end; +end; + +procedure tcustomeditwidgetdatalink.focuscontrol(afield: tfieldref); +begin + if (afield^ = field) and (field <> nil) then begin + if fintf.seteditfocus then begin + afield^:= nil; + end; + end; +end; + +procedure tcustomeditwidgetdatalink.recordchanged(afield: tfield); +var + wi1: twidget; + intf1: iassistiveclientdata; +begin + if (afield = nil) or (afield = field) then begin + if (fbeginedit = 0) and (frecordchange = 0) then begin + inc(frecordchange); + try + if (field <> nil) and active and + not (dataset.eof and dataset.bof and + not (dataset.state in [dsinsert,dsfilter])) then begin + if field.isnull then begin + fintf.setnullvalue; + end + else begin + fintf.fieldtovalue; + end; + end + else begin + fintf.setnullvalue; + end; + wi1:= fintf.getwidget; + if wi1.focused then begin + fintf.initeditfocus; + end; + if (assistiveserver <> nil) and wi1.active and + wi1.getcorbainterface(typeinfo(iassistiveclientdata),intf1) then begin + assistiveserver.dodbvaluechanged(intf1); + end; + finally + dec(frecordchange); + end; + end; + exclude(fstate,fds_modified); + end; +end; + +procedure tcustomeditwidgetdatalink.datasetscrolled(distance: integer); +begin + if distance <> 0 then begin + inherited; + end; +end; + +procedure tcustomeditwidgetdatalink.updatedata; +var + stat1: dataeditstatesty; +begin + inc(fcanclosing); + stat1:= fintf.geteditstate; + if not (des_dbnullcheck in stat1) then begin + fintf.seteditstate(stat1+[des_dbnullcheck]); + end; + try + with fintf.getwidget do begin + if canclose(nil) then begin + exclude(fstate,fds_modified); + end + else begin + activate; + raise eabort.create(''); + end; + end; + if not (oed_nullset in foptions) and (field <> nil) then begin + if ismsestring then begin + with tmsestringfield(field) do begin + if (defaultexpression <> '') and isnull and + (dataset.modified or + (fdscontroller <> nil) and fdscontroller.posting) then begin + asmsestring:= self.msedefaultexpression; + end; + end; + end + else begin + with field do begin + if (defaultexpression <> '') and isnull and + (dataset.modified or + (fdscontroller <> nil) and fdscontroller.posting) then begin + asstring:= defaultexpression; + end; + end; + end; + end; + inherited; + finally + dec(fcanclosing); + if not (des_dbnullcheck in stat1) then begin + fintf.seteditstate(fintf.geteditstate-[des_dbnullcheck]); + end; + end; +end; + +function tcustomeditwidgetdatalink.getdatasource1: tdatasource; +begin + result:= inherited datasource; +end; + +procedure tcustomeditwidgetdatalink.setwidgetdatasource(const avalue: tdatasource); +begin + if not ((csloading in fintf.getwidget.componentstate) and datasourcefixed or + (fintf.getgridintf <> nil)) then begin + inherited datasource:= avalue; + end; +end; + +procedure tcustomeditwidgetdatalink.griddatasourcechanged; +var + datasource1: tdatasource; +begin + datasource1:= fintf.getgriddatasource; + if datasource <> datasource1 then begin + datasource:= datasource1; + end; +end; + +procedure tcustomeditwidgetdatalink.nullcheckneeded(var avalue: boolean); + function findactivedatalink: boolean; + var + info1: hasactiveeditinfoty; + begin + with info1 do begin + hasedit:= false; + field:= self.field; + tdataset1(dataset).dataevent(tdataevent(de_hasactiveedit),ptruint(@info1)); + result:= hasedit; + end; + end; //findactivedatalink + +begin + avalue:= active and + ( + (avalue or fintf.getedited and (oed_autopost in foptions) or + (fcanclosing > 0) + ) and + ((dataset.state in [dsinsert,dsedit]) and + (dataset.modified or + avalue and (oed_nullcheckifunmodified in foptions) or + (dataset.state <> dsinsert) or + (fdscontroller <> nil) and fdscontroller.posting + ) + ) + ); + avalue:= avalue and (fintf.getwidget.window.active or not findactivedatalink); +end; + +function tcustomeditwidgetdatalink.cuttext(const atext: msestring; + out maxlength: integer): boolean; +begin + maxlength:= fmaxlength; + result:= (maxlength > 0) and (length(atext) > maxlength); +end; + +function tcustomeditwidgetdatalink.getownerwidget: twidget; +begin + result:= fintf.getwidget; +end; + +procedure tcustomeditwidgetdatalink.setnavigator(const avalue: tdbnavigator); +begin + getobjectlinker.setlinkedvar(iobjectlink(self),tmsecomponent(avalue), + tmsecomponent(fnavigator)); +end; + +function tcustomeditwidgetdatalink.getobjectlinker: tobjectlinker; +begin + createobjectlinker(self,{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + result:= fobjectlinker; +end; + +procedure tcustomeditwidgetdatalink.link(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tcustomeditwidgetdatalink.unlink(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tcustomeditwidgetdatalink.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tcustomeditwidgetdatalink.getinstance: tobject; +begin + result:= self; +end; + +procedure tcustomeditwidgetdatalink.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (sender = fnavigator) and (event = oe_changed) then begin + fintf.updatereadonlystate; + end; +end; + +procedure tcustomeditwidgetdatalink.fieldchanged; +begin + bindingchanged; + inherited; +end; + +procedure tcustomeditwidgetdatalink.setoptions(const avalue: optionseditdbty); +begin + foptions:= optionseditdbty( + setsinglebit(card32(avalue), + card32(foptions),[card32([oed_autoedit,oed_noautoedit]), + card32([oed_readonly,oed_noreadonly])])); +end; + +function tcustomeditwidgetdatalink.datasourcereadonly(): boolean; +begin + result:= inherited datasourcereadonly(); + if oed_readonly in foptions then begin + result:= true; + end; + if oed_noreadonly in foptions then begin + result:= false; + end; +end; + +procedure tcustomeditwidgetdatalink.valuechanged(const sender: iifidatalink); +var + widget1: twidget; + bo1,bo2: boolean; +begin + if (frecordchange = 0) and (fposting = 0) then begin + widget1:= fintf.getwidget; + if not (ws_loadedproc in widget1.widgetstate) and (field <> nil) and + not ((oe_checkmrcancel in fintf.getoptionsedit) and + (widget1.window.modalresult = mr_cancel)) then begin + if fds_filterediting in fstate then begin + fintf.valuetofield; + end + else begin + if editing then begin + fintf.valuetofield; + if assigned(fondataentered) and + fintf.getwidget.canevent(tmethod(fondataentered)) then begin + fondataentered(self); + end; + if (oed_autopost in foptions) and active then begin + widget1:= widget1.parentwidget; + try + inc(fposting); + if (widget1 <> nil) then begin + if widget1.parentwidget is tcustomgrid then begin + with tcustomgrid1(widget1.parentwidget) do begin + bo1:= fnonullcheck > 0; + if bo1 then begin + dec(fnonullcheck); //remove colchangelock + end; + end; + end + else begin + bo1:= false; + end; + try + bo2:= widget1.canparentclose; + finally + if bo1 then begin + inc(tcustomgrid1(widget1.parentwidget).fnonullcheck); + end; + end; + end; + if bo2 then begin + dataset.post; + end; + finally + dec(fposting); + end; + end; + end; + end; + end; + end; +end; +{ +procedure tcustomeditwidgetdatalink.statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); +begin +end; + +procedure tcustomeditwidgetdatalink.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin +end; + +procedure tcustomeditwidgetdatalink.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +begin +end; + +procedure tcustomeditwidgetdatalink.dataentered(const sender: iificlient; + const arow: integer); +begin +end; +} + +{ tdbstringedit } + +constructor tdbstringedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbstringedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbstringedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbstringedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbstringedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbstringedit.valuetofield; +begin + fdatalink.asnullmsestring:= value; +end; + +procedure tdbstringedit.fieldtovalue; +begin + value:= fdatalink.asnullmsestring; +end; + +function tdbstringedit.getnulltext: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +function tdbstringedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbstringedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbstringedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbstringedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbstringedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdbstringedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbstringedit.setdatalink(const adatalink: tstringeditwidgetdatalink); +begin + fdatalink.assign(adatalink); +end; + +procedure tdbstringedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + + { repaced by oed_limitcharlen + +procedure tdbstringedit.editnotification(var info: editnotificationinfoty); +var + int1: integer; +begin + inherited; + if info.action = ea_textedited then begin + if fdatalink.cuttext(text,int1) then begin + text:= copy(text,1,int1); + end; + end; +end; + } + +procedure tdbstringedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbstringedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; + +procedure tdbstringedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbstringedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +function tdbstringedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +{ +constructor tdbdialogstringedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbdialogstringedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbdialogstringedit.modified; +begin + fdatalink.Modified; + inherited; +end; + +function tdbdialogstringedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; + +procedure tdbdialogstringedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + end + else begin + fdatalink.asmsestring:= value; + end; +end; + +procedure tdbdialogstringedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tdbdialogstringedit.getrowdatapo(const info: cellinfoty): pointer; +begin + with info do begin + if griddatalink <> nil then begin + result:= tgriddatalink(griddatalink).getstringbuffer(fdatalink.field,cell.row); + end + else begin + result:= nil; + end; + end; +end; + +function tdbdialogstringedit.getnulltext: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +function tdbdialogstringedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbdialogstringedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbdialogstringedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbdialogstringedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdbdialogstringedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbdialogstringedit.setdatalink(const avalue: tstringeditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdialogstringedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbdialogstringedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbdialogstringedit.dochange; +begin + fdatalink.dataentered; + inherited; +end; +} + +{ tcustomdbdropdownlistedit } + +constructor tcustomdbdropdownlistedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tcustomdbdropdownlistedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tcustomdbdropdownlistedit.modified; +begin + fdatalink.Modified; + inherited; +end; + +procedure tcustomdbdropdownlistedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tcustomdbdropdownlistedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tcustomdbdropdownlistedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + end + else begin + fdatalink.asmsestring:= value; + end; +end; + +procedure tcustomdbdropdownlistedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tcustomdbdropdownlistedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tcustomdbdropdownlistedit.getnulltext: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +function tcustomdbdropdownlistedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tcustomdbdropdownlistedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tcustomdbdropdownlistedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tcustomdbdropdownlistedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tcustomdbdropdownlistedit.nullcheckneeded( + const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tcustomdbdropdownlistedit.setdatalink( + const avalue: tstringeditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tcustomdbdropdownlistedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tcustomdbdropdownlistedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tcustomdbdropdownlistedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tcustomdbdropdownlistedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +function tcustomdbdropdownlistedit.getdropdownifilink: tifidropdownlistlinkcomp; +begin + result:= fdropdownifilink; +end; + +procedure tcustomdbdropdownlistedit.setdropdownifilink( + const avalue: tifidropdownlistlinkcomp); +begin + mseificomp.setifilinkcomp(idbifidropdownlistdatalink(self),avalue, + tifilinkcomp(fdropdownifilink)); +end; + +procedure tcustomdbdropdownlistedit.dropdownsetifiserverintf( + const aintf: iifiserver); +begin + fdropdownifiserverintf:= aintf; +end; + +procedure tcustomdbdropdownlistedit.dropdownifisetvalue(var avalue; + var accept: boolean); +begin + //dummy +end; +{ +procedure tcustomdbdropdownlistedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tcustomdbdropdownlistedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbkeystringedit } + +constructor tdbkeystringedit.create(aowner: tcomponent); +begin + fdatalink:= tstringlookupeditdatalink.Create(self,ldt_string, + idbeditfieldlink(self)); + inherited; +end; + +destructor tdbkeystringedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbkeystringedit.modified; +begin + fdatalink.modified; + inherited; +end; +{ +function tdbkeystringedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +// frame.readonly:= oe_readonly in result; +end; +} +procedure tdbkeystringedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + if fdatalink.fieldtext <> nil then begin + fdatalink.fieldtext.clear; + end; + end + else begin + fdatalink.asmsestring:= value; + setasmsestring(text,fdatalink.fieldtext,fdatalink.utf8) + end; +end; + +procedure tdbkeystringedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tdbkeystringedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbkeystringedit.getnulltext: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +function tdbkeystringedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbkeystringedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbkeystringedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbkeystringedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdbkeystringedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbkeystringedit.setdatalink(const avalue: tstringlookupeditdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbkeystringedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbkeystringedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbkeystringedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbkeystringedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbkeystringedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbkeystringedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbmemoedit } + +constructor tdbmemoedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbmemoedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbmemoedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbmemoedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbmemoedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbmemoedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + end + else begin + fdatalink.asmsestring:= value; + end; +end; + +procedure tdbmemoedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tdbmemoedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbmemoedit.getnulltext: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +function tdbmemoedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbmemoedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbmemoedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbmemoedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= memofields; +end; + +function tdbmemoedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbmemoedit.setdatalink(const avalue: tstringeditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbmemoedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbmemoedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbmemoedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbmemoedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbmemoedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbmemoedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbintegeredit } + +constructor tdbintegeredit.create(aowner: tcomponent); +begin + fisnull:= true; + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbintegeredit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbintegeredit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbintegeredit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbintegeredit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +{ +procedure tdbintegeredit.setnullvalue; +begin + inherited; + fisnull:= true; +end; +} +function tdbintegeredit.internaldatatotext(const data): msestring; +begin + if (@data = nil) and fisnull then begin + result:= ''; + end + else begin + result:= inherited internaldatatotext(data); + end; +end; + +procedure tdbintegeredit.texttovalue(var accept: boolean; const quiet: boolean); +begin + fisnull:= text = ''; + inherited; +end; + +procedure tdbintegeredit.valuetofield; +begin + if fisnull then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asinteger:= value; + end; +end; + +procedure tdbintegeredit.fieldtovalue; +begin + fisnull:= false; + value:= fdatalink.field.asinteger; +end; + +function tdbintegeredit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getintegerbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +procedure tdbintegeredit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbintegeredit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +function tdbintegeredit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbintegeredit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +function tdbintegeredit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbintegeredit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbintegeredit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbintegeredit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbintegeredit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbintegeredit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbintegeredit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbintegeredit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbbooleanedit } + +constructor tdbbooleanedit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbbooleanedit.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbbooleanedit.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; + //dummy +end; +{ +function tdbbooleanedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbbooleanedit.valuetofield; +begin + fdatalink.field.asboolean:= value; +end; + +procedure tdbbooleanedit.fieldtovalue; +begin + value:= fdatalink.field.asboolean; +end; + +function tdbbooleanedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getbooleanbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbbooleanedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbbooleanedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbbooleanedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbbooleanedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= booleanfields; +end; + +procedure tdbbooleanedit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbbooleanedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbbooleanedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbbooleanedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbbooleanedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbbooleanedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdbbooleanedit.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbbooleanedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbbooleanedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbbooleanedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbdataicon } + +constructor tdbdataicon.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbdataicon.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbdataicon.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; + //dummy +end; +{ +function tdbdataicon.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbdataicon.valuetofield; +begin + if value = -1 then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asinteger:= value; + end; +end; + +procedure tdbdataicon.fieldtovalue; +begin + value:= fdatalink.field.asinteger; +end; + +function tdbdataicon.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getintegerbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbdataicon.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbdataicon.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbdataicon.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbdataicon.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +procedure tdbdataicon.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdataicon.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbdataicon.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbdataicon.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbdataicon.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbdataicon.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdbdataicon.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbdataicon.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbdataicon.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbdataicon.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbdatabutton } + +constructor tdbdatabutton.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbdatabutton.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbdatabutton.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; + //dummy +end; +{ +function tdbdatabutton.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbdatabutton.valuetofield; +begin + if value = -1 then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asinteger:= value; + end; +end; + +procedure tdbdatabutton.fieldtovalue; +begin + value:= fdatalink.field.asinteger; +end; + +function tdbdatabutton.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getintegerbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbdatabutton.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbdatabutton.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbdatabutton.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbdatabutton.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +procedure tdbdatabutton.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdatabutton.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbdatabutton.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbdatabutton.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbdatabutton.modified; +begin + if fresetting = 0 then begin + fdatalink.modified; + end; + inherited; +end; + +procedure tdbdatabutton.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdbdatabutton.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbdatabutton.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbdatabutton.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbdatabutton.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbbooleaneditradio } + +constructor tdbbooleaneditradio.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbbooleaneditradio.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbbooleaneditradio.checkvalue(const quiet: boolean = false): boolean; +begin + result:= true;//dummy +end; + +function tdbbooleaneditradio.docheckvalue(var avalue; + const quiet: boolean): boolean; +var + widget: twidget; + int1: integer; + bo1: boolean; +begin + if boolean(avalue) and (fparentwidget <> nil) then begin + bo1:= false; + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget:= fparentwidget.widgets[int1]; + if (widget is tdbbooleaneditradio) and (widget <> self) and + (tcustombooleaneditradio(widget).group = group) then begin + tdbbooleaneditradio(widget).docheckvalue(bo1,quiet); + end; + end; + end; + result:= inherited docheckvalue(avalue,quiet); +end; +{ +procedure tdbbooleaneditradio.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbbooleaneditradio.modified; +begin + if fresetting = 0 then begin + fdatalink.modified; + end; + inherited; +end; + +procedure tdbbooleaneditradio.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbbooleaneditradio.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbbooleaneditradio.valuetofield; +begin + fdatalink.field.asboolean:= value; +end; + +procedure tdbbooleaneditradio.fieldtovalue; +begin + value:= fdatalink.field.asboolean; +end; + +function tdbbooleaneditradio.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getbooleanbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbbooleaneditradio.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbbooleaneditradio.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbbooleaneditradio.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbbooleaneditradio.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= booleanfields; +end; + +procedure tdbbooleaneditradio.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbbooleaneditradio.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbbooleaneditradio.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbbooleaneditradio.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbbooleaneditradio.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbbooleaneditradio.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbbooleaneditradio.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbrealedit } + +constructor tdbrealedit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbrealedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbrealedit.modified; +begin + fdatalink.Modified; + inherited; +end; + +procedure tdbrealedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbrealedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbrealedit.valuetofield; +begin + if value = emptyreal then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asfloat:= value; + end; +end; + +procedure tdbrealedit.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= emptyreal; + end + else begin + value:= fdatalink.field.asfloat; + end; +end; + +function tdbrealedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getrealtybuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbrealedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbrealedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbrealedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbrealedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= realfields + integerfields; +end; + +function tdbrealedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbrealedit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbrealedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbrealedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbrealedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbrealedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbrealedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbrealedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbrealspinedit } + +constructor tdbrealspinedit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbrealspinedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbrealspinedit.modified; +begin + fdatalink.Modified; + inherited; +end; + +procedure tdbrealspinedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbrealspinedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbrealspinedit.valuetofield; +begin + if value = emptyreal then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asfloat:= value; + end; +end; + +procedure tdbrealspinedit.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= emptyreal; + end + else begin + value:= fdatalink.field.asfloat; + end; +end; + +function tdbrealspinedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getrealtybuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbrealspinedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbrealspinedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbrealspinedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbrealspinedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= realfields + integerfields; +end; + +function tdbrealspinedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbrealspinedit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbrealspinedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbrealspinedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbrealspinedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbrealspinedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbrealspinedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbrealspinedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbslider } + +constructor tdbslider.create(aowner: tcomponent); +begin +// fisdb:= true; + fvaluerange:= 1; + fdatalink:= teditwidgetdatalink.create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbslider.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbslider.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; + //dummy +end; +{ +function tdbslider.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbslider.valuetofield; +begin + if value = emptyreal then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asfloat:= applyrange(value,valuerange,valuestart); + end; +end; + +procedure tdbslider.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= emptyreal; + end + else begin + value:= reapplyrange(fdatalink.field.asfloat,valuerange,valuestart); + end; +end; + +function tdbslider.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getrealtybuffer(fdatalink.field,arow); + if result <> nil then begin + preal(result)^:= reapplyrange(preal(result)^,valuerange,valuestart); + end; + end + else begin + result:= nil; + end; +end; + +function tdbslider.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbslider.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbslider.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbslider.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= realfields + integerfields; +end; + +procedure tdbslider.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbslider.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tdbslider.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + +procedure tdbslider.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbslider.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbslider.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbslider.doshortcut(var info: keyeventinfoty; const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdbslider.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbslider.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbslider.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbslider.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbprogressbar } + +constructor tdbprogressbar.create(aowner: tcomponent); +begin +// fisdb:= true; + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbprogressbar.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbprogressbar.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getrealtybuffer(fdatalink.field,arow); + if result <> nil then begin + preal(result)^:= reapplyrange(preal(result)^,valuerange,valuestart); + end; + end + else begin + result:= nil; + end; +end; + +procedure tdbprogressbar.valuetofield; +//var +// rea1: real; +begin + if value = emptyreal then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asfloat:= applyrange(value,valuerange,valuestart); + end; +end; + +procedure tdbprogressbar.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= emptyreal; + end + else begin + value:= reapplyrange(fdatalink.field.asfloat,valuerange,valuestart); + end; +end; + +procedure tdbprogressbar.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= realfields + integerfields; +end; + +procedure tdbprogressbar.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +function tdbprogressbar.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +function tdbprogressbar.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +function tdbprogressbar.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; //dummy +end; + +procedure tdbprogressbar.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbprogressbar.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbprogressbar.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +procedure tdbprogressbar.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbprogressbar.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +{ tdbdatetimeedit } + +constructor tdbdatetimeedit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbdatetimeedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbdatetimeedit.modified; +begin + fdatalink.modified; + inherited; +end; +{ +function tdbdatetimeedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbdatetimeedit.valuetofield; +begin + if value = emptydatetime then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asdatetime:= value; + end; +end; + +procedure tdbdatetimeedit.fieldtovalue; +var + da1: tdatetime; +begin + if fdatalink.field.isnull then begin + value:= 0; + end + else begin + da1:= fdatalink.field.asdatetime; + value:= da1; + end; +end; + +function tdbdatetimeedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getdatetimebuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbdatetimeedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbdatetimeedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbdatetimeedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbdatetimeedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= datetimefields; +end; + +function tdbdatetimeedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbdatetimeedit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdatetimeedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbdatetimeedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbdatetimeedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbdatetimeedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbdatetimeedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbdatetimeedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} + +{ tcustomdbenumedit } + +constructor tcustomdbenumedit.create(aowner: tcomponent); +begin + fdatalink:= tlookupeditdatalink.create(self,ldt_int32,idbeditfieldlink(self)); + inherited; +end; + +destructor tcustomdbenumedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tcustomdbenumedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tcustomdbenumedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tcustomdbenumedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +// frame.readonly:= oe_readonly in result; +end; +} +procedure tcustomdbenumedit.valuetofield; +begin + if value = fvalueempty then begin + fdatalink.field.clear; + if fdatalink.fieldtext <> nil then begin + fdatalink.fieldtext.clear; + end; + end + else begin + fdatalink.field.asinteger:= value; + setasmsestring(text,fdatalink.fieldtext,fdatalink.utf8) + end; +end; + +procedure tcustomdbenumedit.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= fvaluedefault1; + end + else begin + value:= fdatalink.field.asinteger; + end; +end; + +function tcustomdbenumedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink). + getintegerbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tcustomdbenumedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tcustomdbenumedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tcustomdbenumedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tcustomdbenumedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +function tcustomdbenumedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tcustomdbenumedit.setdatalink(const avalue: tlookupeditdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tcustomdbenumedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tcustomdbenumedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tcustomdbenumedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tcustomdbenumedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +function tcustomdbenumedit.getdropdownifilink: tifienumlinkcomp; +begin + result:= fdropdownifilink; +end; + +procedure tcustomdbenumedit.setdropdownifilink(const avalue: tifienumlinkcomp); +begin + mseificomp.setifilinkcomp(idbifidropdownlistdatalink(self),avalue, + tifilinkcomp(fdropdownifilink)); +end; + +procedure tcustomdbenumedit.dropdownsetifiserverintf(const aintf: iifiserver); +begin + fdropdownifiserverintf:= aintf; +end; + +procedure tcustomdbenumedit.dropdownifisetvalue(var avalue; + var accept: boolean); +begin + //dummy +end; +{ +procedure tcustomdbenumedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tcustomdbenumedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbbooleantextedit } + +constructor tdbbooleantextedit.create(aowner: tcomponent); +begin + ftext_false:= 'F'; + ftext_true:= 'T'; + inherited; + booltextchanged; +end; + +procedure tdbbooleantextedit.booltextchanged; +begin + with tenumdropdowncontroller(fdropdown) do begin + cols.count:= 1; + cols[0].count:= 2; + cols[0][0]:= ftext_false; + cols[0][1]:= ftext_true; + end; + formatchanged; +end; + +procedure tdbbooleantextedit.settext_false(const avalue: msestring); +begin + ftext_false:= avalue; + booltextchanged; +end; + +procedure tdbbooleantextedit.settext_true(const avalue: msestring); +begin + ftext_true:= avalue; + booltextchanged; +end; + +procedure tdbbooleantextedit.valuetofield; +begin + case inherited value of + -1: fdatalink.field.clear; + 0: fdatalink.field.asboolean:= false; + else fdatalink.field.asboolean:= true; + end; +end; + +procedure tdbbooleantextedit.fieldtovalue; +begin + if fdatalink.field.isnull then begin + inherited value:= -1; + end + else begin + value:= fdatalink.field.asboolean; + end; +end; + +procedure tdbbooleantextedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= booleanfields; +end; + +function tdbbooleantextedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getbooleanbuffer(fdatalink.field,arow); + if result = nil then begin + result:= @fvaluedefault; + end; + end + else begin + result:= @fvaluedefault; + end; +end; + +function tdbbooleantextedit.getvalue: boolean; +begin + result:= inherited value >= 0; +end; + +procedure tdbbooleantextedit.setvalue(const avalue: boolean); +begin + if avalue then begin + inherited value:= 1; + end + else begin + inherited value:= 0; + end; +end; + +{ tdbdropdowncol } + +procedure tdbdropdowncol.setdatafield(const avalue: string); +begin + if fdatafield <> avalue then begin + fdatafield:= avalue; + tcustomdbdropdownlistcontroller(fowner).fdatalink.updatefields; + end; +end; + +function tdbdropdowncol.getdataset(const aindex: integer): tdataset; +begin + if fowner is tcustomdbdropdownlistcontroller then begin + result:= tcustomdbdropdownlistcontroller(fowner).fdatalink.dataset; + end + else begin + result:= nil; + end; +end; + +procedure tdbdropdowncol.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + setlength(fieldtypes,1); + fieldtypes[0]:= textfields; +end; + +{ tdbdropdowncols } + +function tdbdropdowncols.getitems(const index: integer): tdbdropdowncol; +begin + result:= tdbdropdowncol(inherited getitems(index)); +end; + +function tdbdropdowncols.getcolclass: dropdowncolclassty; +begin + result:= tdbdropdowncol; +end; + +{ tdropdowndatalink } + +constructor tdropdowndatalink.create( + const aowner: tcustomdbdropdownlistcontroller); +begin + flastintegerkey:= -1; + fowner:= aowner; +end; + +procedure tdropdowndatalink.setvaluefieldname(const value: string); +begin + if fvaluefieldname <> value then begin + fvaluefieldname := value; + updatefields; + end; +end; + +procedure tdropdowndatalink.setvaluefield(value: tfield); +begin + if fvaluefield <> value then begin + fvaluefield:= value; + EditingChanged; + RecordChanged(nil); + end; +end; + +procedure tdropdowndatalink.settextfield(value: tfield); +begin + if ftextfield <> value then begin + ftextfield:= value; + end; +end; + +procedure tdropdowndatalink.updatefields; + + procedure doerror(const afield: tfield); + begin + if afield <> nil then begin + raise exception.create(dataset.name+ + ': No matching local index for "'+afield.fieldname+'".'); + end; + end; //doerror + +begin + if Active and (fvaluefieldname <> '') then begin + setvaluefield(datasource.dataset.fieldbyname(fvaluefieldname)); + end + else begin + setvaluefield(nil); + end; + with fowner do begin + if active and (valuecol >= 0) and (valuecol < cols.count) and + (tdbdropdowncol(cols[valuecol]).datafield <> '') then begin + settextfield(datasource.dataset.fieldbyname( + tdbdropdowncol(cols[valuecol]).datafield)); + end + else begin + settextfield(nil); + end; + end; + fdataintf:= nil; + fkeyindex:= -1; + ftextindex:= -1; + if active then begin + if odb_directdata in fowner.foptionsdb then begin + if getcorbainterface(dataset,typeinfo(idbdata),fdataintf) then begin + if fvaluefield <> nil then begin + fkeyindex:= fdataintf.getindex(fvaluefield); + end; + if ftextfield <> nil then begin + ftextindex:= fdataintf.gettextindex(ftextfield, + not (deo_casesensitive in fowner.foptions)); + end; + end; + if fkeyindex < 0 then begin + doerror(fvaluefield); + end; + if ftextindex < 0 then begin + doerror(ftextfield); + end; + end; + end; +end; + +procedure tdropdowndatalink.updatelookupvalue; +begin + exclude(fstate,ddlnks_lookupvalid); + with tdataedit1(fowner.fintf.getwidget) do begin + if fgridintf <> nil then begin + fgridintf.getcol.changed; + end + else begin + valuetotext; + end; + end; +end; + +procedure tdropdowndatalink.activechanged; +begin + flastintegerkey:= -1; + updatefields; + inherited; + updatelookupvalue; + fowner.updatereadonlystate; +end; + +procedure tdropdowndatalink.editingchanged; +begin + inherited; + if not editing then begin + updatelookupvalue; + end; +end; + +procedure tdropdowndatalink.LayoutChanged; +begin + updatefields; + inherited; +end; + +function tdropdowndatalink.getlookuptext(const key: integer): msestring; +var + str1: string; +begin + if flastintegerkey <> key then begin + exclude(fstate,ddlnks_lookupvalid); + end; + if ddlnks_lookupvalid in fstate then begin + result:= flookuptext; + end + else begin + result:= ''; + if active and (fdscontroller <> nil) and + (fvaluefield <> nil) and (ftextfield <> nil) then begin + flastintegerkey:= key; + if fkeyindex >= 0 then begin + result:= fdataintf.lookuptext(fkeyindex,key,false, + tmsestringfield(ftextfield)); + end + else begin + dataset.disablecontrols; + try + str1:= dataset.bookmark; + if fdscontroller.locate([fvaluefield],[key],[],[]) = loc_ok then begin + result:= getasmsestring(ftextfield,utf8); + end; + dataset.bookmark:= str1; + finally + dataset.enablecontrols; + end; + end; + include(fstate,ddlnks_lookupvalid); + end; + flookuptext:= result; + end; +end; + +function tdropdowndatalink.getlookuptext(const key: int64): msestring; +var + str1: string; +begin + if flastint64key <> key then begin + exclude(fstate,ddlnks_lookupvalid); + end; + if ddlnks_lookupvalid in fstate then begin + result:= flookuptext; + end + else begin + result:= ''; + if active and (fdscontroller <> nil) and + (fvaluefield <> nil) and (ftextfield <> nil) then begin + flastint64key:= key; + if fkeyindex >= 0 then begin + result:= fdataintf.lookuptext(fkeyindex,key,false, + tmsestringfield(ftextfield)); + end + else begin + dataset.disablecontrols; + try + str1:= dataset.bookmark; + if fdscontroller.locate([fvaluefield],[key],[],[]) = loc_ok then begin + result:= getasmsestring(ftextfield,utf8); + end; + dataset.bookmark:= str1; + finally + dataset.enablecontrols; + end; + end; + include(fstate,ddlnks_lookupvalid); + end; + flookuptext:= result; + end; +end; + +function tdropdowndatalink.getlookuptext(const key: msestring): msestring; +var + str1: string; +begin + if flaststringkey <> key then begin + exclude(fstate,ddlnks_lookupvalid); + end; + if ddlnks_lookupvalid in fstate then begin + result:= flookuptext; + end + else begin + result:= ''; + if active and (fdscontroller <> nil) and + (fvaluefield <> nil) and (ftextfield <> nil) then begin + flaststringkey:= key; + if fkeyindex >= 0 then begin + result:= fdataintf.lookuptext(fkeyindex,key,false, + tmsestringfield(ftextfield)); + end + else begin + dataset.disablecontrols; + try + str1:= dataset.bookmark; + if fdscontroller.locate([fvaluefield],[key],[],[]) = loc_ok then begin + result:= getasmsestring(ftextfield,utf8); + end; + dataset.bookmark:= str1; + finally + dataset.enablecontrols; + end; + end; + include(fstate,ddlnks_lookupvalid); + end; + flookuptext:= result; + end; +end; + +function tdropdowndatalink.getvalueasmsestring: msestring; +begin + result:= ''; + if active and (fvaluefield <> nil) then begin + result:= getasmsestring(fvaluefield,utf8); + end; +end; + +function tdropdowndatalink.getvalueasinteger: integer; +begin + result:= 0; + if active and (fvaluefield <> nil) then begin + result:= fvaluefield.asinteger; + end; +end; + +function tdropdowndatalink.getvalueaslargeint: int64; +begin + result:= 0; + if active and (fvaluefield <> nil) then begin + result:= fvaluefield.aslargeint; + end; +end; + +function tdropdowndatalink.gettextasmsestring: msestring; +begin + result:= ''; + if active and (ftextfield <> nil) then begin +// with fgridlink do begin +// if fdataintf <> nil then begin +// result:= fdataintf.getrowtext(ftextindex,fcurrentrecord,ftextfield); +// end +// else begin + result:= getasmsestring(ftextfield,utf8); +// end; +// end; + end; +end; + +{ tdbdropdownstringcol } + +constructor tdbdropdownstringcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fdatalink:= tfielddatalink.create; + inherited; +end; + +destructor tdbdropdownstringcol.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbdropdownstringcol.getrowtext(const arow: integer): msestring; +var + int1: integer; +begin + if fdatalink.active and (fdatalink.field <> nil) then begin + with tdbdropdownlist(fcellinfo.grid).fdatalink do begin + if fdataintf <> nil then begin + result:= fdataintf.getrowtext(ftextindex,arow+ffirstrecord,fdatalink.field); + end + else begin + int1:= activerecord; + activerecord:= arow; + result:= fdatalink.asmsestring; + activerecord:= int1; + end; + end; + end + else begin + result:= ''; + end; +end; + +{ tdropdownlistdatalink } + +constructor tdropdownlistdatalink.create(const aowner: tcustomgrid; + const aintf: igriddatalink; const adatalink: tdropdowndatalink); +begin + with adatalink do begin + self.fdataintf:= fdataintf; + self.ftextindex:= ftextindex; + self.fkeyindex:= fkeyindex; + end; + inherited create(aowner,aintf); +end; + +procedure tdropdownlistdatalink.updatefocustext; +begin + with tdbdropdownlist(fgrid) do begin + if isdatacell(ffocusedcell) then begin + feditor.text:= tdbdropdownstringcol(datacols[ffocusedcell.col]). + getrowtext(ffocusedcell.row); + end; + end; +end; + +procedure tdropdownlistdatalink.recordchanged(afield: tfield); +begin + inherited; + updatefocustext; +end; + +function tdropdownlistdatalink.GetActiveRecord: Integer; +begin + if fdataintf = nil then begin + result:= inherited getactiverecord; + end + else begin + result:= fcurrentrecord-ffirstrecord; + end; +end; + +procedure tdropdownlistdatalink.SetActiveRecord(Value: Integer); +begin + if fdataintf = nil then begin + inherited; + end; +end; + +function tdropdownlistdatalink.domoveby(const distance: integer): integer; +var + int1: integer; +begin + if fdataintf = nil then begin + result:= inherited domoveby(distance); + end + else begin + int1:= fcurrentrecord; + setcurrentrecord(fcurrentrecord+distance,ropo_nearest); + result:= fcurrentrecord-int1; + end; +end; + +procedure tdropdownlistdatalink.checkscrollbar; +var + rea1: real; + int1: integer; +begin + if fdataintf = nil then begin + inherited; + end + else begin + int1:= dataset.recordcount-1; + if int1 <= fgrid.rowcount then begin + rea1:= 1; + end + else begin + rea1:= fgrid.rowcount/(int1+1+fgrid.rowcount); + end; + fgrid.frame.sbvert.pagesize:= rea1; + if int1 > 0 then begin + rea1:= fcurrentrecord/int1; + end + else begin + rea1:= 0; + end; + fgrid.frame.sbvert.value:= rea1; + end; +end; + +function tdropdownlistdatalink.scrollevent(sender: tcustomscrollbar; + event: scrolleventty): boolean; +//var +// int1: integer; +begin + if (fdataintf = nil) or (sender.tag <> 1) or + not (event in [sbe_thumbtrack,sbe_thumbposition]) then begin + result:= inherited scrollevent(sender,event); + end + else begin + result:= false; + if (event <> sbe_thumbtrack) or (gdo_thumbtrack in foptions) then begin + if self.active then begin + setcurrentrecord(round( + fgrid.frame.sbvert.value * dataset.recordcount),ropo_nearest); + result:= true; + end; + end; + end; +end; + +procedure tdropdownlistdatalink.focuscell(var cell: gridcoordty); +begin + if fdataintf = nil then begin + inherited; + end + else begin + if (cell.row >= 0) and (cell.row <> fgrid.row) then begin + moveby(cell.row-fgrid.row); + end; + end; +end; + +procedure tdropdownlistdatalink.setcurrentrecord(const avalue: integer; + const arowpos: rowpositionty); +var + int1,int2: integer; +begin + if active then begin + if avalue <> fcurrentrecord then begin + int2:= fcurrentrecord; + fcurrentrecord:= avalue; + if fcurrentrecord < 0 then begin + fcurrentrecord:= 0; + if int2 = 0 then begin + include(tcustomgrid1(fgrid).fstate1,gs1_scrolllimit); + end; + end; + int1:= dataset.recordcount; + if fcurrentrecord >= dataset.recordcount then begin + fcurrentrecord:= int1 - 1; + if int2 = fcurrentrecord then begin + include(tcustomgrid1(fgrid).fstate1,gs1_scrolllimit); + end; + end; + updatedatawindow(arowpos); + end; + recordchanged(nil); + end; +end; + +procedure tdropdownlistdatalink.updatedatawindow(const arowpos: rowpositionty); +var + int1,int2: integer; +begin + int1:= recordcount; + case arowpos of + ropo_top: begin + ffirstrecord:= fcurrentrecord; + end; + ropo_bottom: begin + ffirstrecord:= fcurrentrecord-int1+1; + end; + ropo_centered,ropo_centeredif: begin + if (arowpos = ropo_centered) or + (fcurrentrecord < ffirstrecord) or + (fcurrentrecord >= ffirstrecord + int1) then begin + ffirstrecord:= fcurrentrecord - int1 div 2; + end; + end; + end; + int2:= dataset.recordcount; + if ffirstrecord + int1 > int2 then begin + ffirstrecord:= int2 - int1; + end; + if ffirstrecord < 0 then begin + ffirstrecord:= 0; + end; + if fcurrentrecord >= ffirstrecord+fmaxrowcount then begin + ffirstrecord:= fcurrentrecord - fmaxrowcount + 1; + end; + if fcurrentrecord < ffirstrecord then begin + ffirstrecord:= fcurrentrecord; + end; +end; +{ +function tdropdownlistdatalink.GetBufferCount: Integer; +begin + if (fdataintf = nil) or (fmaxrowcount <= 0) then begin + result:= inherited getbuffercount; + end + else begin + result:= fmaxrowcount; + end; +end; +} +procedure tdropdownlistdatalink.SetBufferCount(Value: Integer); +begin + if fdataintf = nil then begin + inherited; + end + else begin + fmaxrowcount:= value; + end; +end; + +function tdropdownlistdatalink.getfirstrecord: integer; +begin + if fdataintf = nil then begin + result:= inherited getfirstrecord; + end + else begin + result:= ffirstrecord; + end; +end; + +function tdropdownlistdatalink.getrecordcount: integer; +begin + if fdataintf = nil then begin + result:= inherited getrecordcount; + end + else begin + result:= dataset.recordcount; + if result > fmaxrowcount then begin + result:= fmaxrowcount; + end; + end; +end; + +function tdropdownlistdatalink.getasmsestring(const afield: tfield): msestring; +begin + if fdataintf = nil then begin + result:= msedb.getasmsestring(afield,utf8); + end + else begin + result:= fdataintf.getrowtext(ftextindex,fcurrentrecord,afield); + end; +end; + +function tdropdownlistdatalink.getasinteger(const afield: tfield): integer; +begin + if fdataintf = nil then begin + result:= afield.asinteger; + end + else begin + result:= fdataintf.getrowinteger(ftextindex,fcurrentrecord,afield); + end; +end; + +function tdropdownlistdatalink.getaslargeint(const afield: tfield): int64; +begin + if fdataintf = nil then begin + result:= afield.aslargeint; + end + else begin + result:= fdataintf.getrowlargeint(ftextindex,fcurrentrecord,afield); + end; +end; + +procedure tdropdownlistdatalink.cellevent(var info: celleventinfoty); +var + int1: integer; +begin + int1:= info.newcell.row-activerecord; + inherited; + with info do begin + if (eventkind = cek_enter) and active and (int1 = 0) and + (newcell.col >= 0) then begin + updatefocustext; + end; + end; +end; + +{ tdbdropdownlist } + +constructor tdbdropdownlist.create( + const acontroller: tcustomdbdropdownlistcontroller; acols: tdropdowncols); +var + int1: integer; +begin + fdatalink:= tdropdownlistdatalink.create(self,igriddatalink(self), + acontroller.fdatalink); + inherited create(acontroller,acols,nil); + include(fstate,gs_isdb); + fzebra_step:= 0; + fdatalink.datasource:= acontroller.datasource; + fdatalink.buffercount:= acontroller.dropdownrowcount; + int1:= fdatalink.recordcount; + if int1 < 0 then begin + int1:= 0; + end; + rowcount:= int1; +end; + +destructor tdbdropdownlist.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbdropdownlist.pagedown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(rowcount-1); +end; + +procedure tdbdropdownlist.pageup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-rowcount+1); +end; + +procedure tdbdropdownlist.wheeldown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(wheelheight); +end; + +procedure tdbdropdownlist.wheelup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-wheelheight); +end; + +procedure tdbdropdownlist.rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); +begin + fdatalink.MoveBy(1); +end; + +procedure tdbdropdownlist.rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); +begin + fdatalink.MoveBy(-1); +end; + +procedure tdbdropdownlist.internalcreateframe; +begin + tdbgridframe.create(iscrollframe(self),self,iautoscrollframe(self)); +end; + +procedure tdbdropdownlist.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= tdbdropdownstringcol.create(self,fdatacols); +end; + +procedure tdbdropdownlist.initcols(const acols: tdropdowncols); +var + int1: integer; + dbstrcol1: tdbdropdownstringcol; + datasource1: tdatasource; +begin + inherited; + datasource1:= tcustomdbdropdownlistcontroller(fcontroller).datasource; + for int1:= 0 to fdatacols.count - 1 do begin + dbstrcol1:= tdbdropdownstringcol(fdatacols[int1]); + with tdbdropdowncol(acols[int1]) do begin + dbstrcol1.fdatalink.datasource:= datasource1; + dbstrcol1.fdatalink.fieldname:= datafield; + end; + end; +end; + +procedure tdbdropdownlist.docellevent(var info: celleventinfoty); +begin + inherited; + fdatalink.cellevent(info); +end; + +procedure tdbdropdownlist.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +begin + if not fdatalink.scrollevent(sender,event) then begin + inherited; + end; +end; + +function tdbdropdownlist.locate(const filter: msestring): boolean; +var + row1: integer; +begin + result:= false; + if (datacols.count > 0) then begin + with tdbdropdownstringcol(datacols[0]).fdatalink do begin + if (dscontroller <> nil) and (field <> nil) then begin + with tcustomdbdropdownlistcontroller(fcontroller).fdatalink do begin + if ftextindex >= 0 then begin + result:= fdataintf.findtext(ftextindex,filter,row1); + if result then begin + fdatalink.setcurrentrecord(row1,ropo_top); + end; + end + else begin + result:= dscontroller.locate([field],[filter],[], + [[lko_caseinsensitive]]) = loc_ok; + if not result then begin + result:= dscontroller.locate([field],[filter],[], + [[lko_caseinsensitive,lko_partialkey]]) = loc_ok; + end; + if result then begin + dataset.resync([rmcenter]); + end; + end; + end; + end; + end; + end; + if not result then begin + focuscell(makegridcoord(ffocusedcell.col,-1)); + end; +end; + +procedure tdbdropdownlist.dopaint(const acanvas: tcanvas); +begin + inherited; + fdatalink.painted; +end; + +procedure tdbdropdownlist.dohide; +begin + fdatalink.painted; + inherited; +end; + +function tdbdropdownlist.getdbindicatorcol: integer; +begin + result:= 0; //none +end; + +procedure tdbdropdownlist.setnavigator(const avalue: tdbnavigator); +begin + //dummy +end; + +function tdbdropdownlist.getdatalink(): tgriddatalink; +begin + result:= fdatalink; +end; + +function tdbdropdownlist.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_db]; +end; + +procedure tdbdropdownlist.setactiveitem(const aitemindex: integer); +begin + inherited; + fdatalink.recordchanged(nil); +end; + +{ tcustomdbdropdownlistcontroller } + +constructor tcustomdbdropdownlistcontroller.create(const intf: idbdropdownlist; + const aisstringkey: boolean); +begin + if aisstringkey then begin + include(fstate,dcs_isstringkey); + end; +// fisstringkey:= aisstringkey; + foptionsdatalink:= defaultdropdowndatalinkoptions; + fdatalink:= tdropdowndatalink.create(self); + inherited create(intf); + options:= defaultdbdropdownoptions; +end; + +destructor tcustomdbdropdownlistcontroller.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tcustomdbdropdownlistcontroller.dropdown; +begin + tdropdowncols1(fcols).fitemindex:= -1; + inherited; +end; + +function tcustomdbdropdownlistcontroller.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tcustomdbdropdownlistcontroller.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; +end; + +procedure tcustomdbdropdownlistcontroller.setkeyfield(const avalue: string); +begin + fdatalink.valuefieldname:= avalue; +end; + +function tcustomdbdropdownlistcontroller.getkeyfield: string; +begin + result:= fdatalink.valuefieldname; +end; + +function tcustomdbdropdownlistcontroller.getcols: tdbdropdowncols; +begin + result:= tdbdropdowncols(fcols); +end; + +procedure tcustomdbdropdownlistcontroller.setcols(const avalue: tdbdropdowncols); +begin + fcols.assign(avalue); +end; + +function tcustomdbdropdownlistcontroller.getbuttonframeclass(): + dropdownbuttonframeclassty; +begin + result:= tdropdownmultibuttonframe; +end; + +procedure tcustomdbdropdownlistcontroller.valuecolchanged; +begin + inherited; + fdatalink.updatefields; +end; + +function tcustomdbdropdownlistcontroller.getdropdowncolsclass: dropdowncolsclassty; +begin + result:= tdbdropdowncols; +end; + +function tcustomdbdropdownlistcontroller.createdropdownlist: tdropdownlist; +type + pmsestringaarty = array of pmsestringaty; +var + int1,int2: integer; + datas: tdataset; + ar1: fieldarty; + ar2: pmsestringaarty; + bm: string; +begin + datas:= fdatalink.dataset; + if (datas <> nil) and (odb_closedataset in foptionsdb) then begin + datas.active:= true; + end; + if odb_copyitems in foptionsdb then begin + fcols.clear; + datas:= fdatalink.dataset; + if (datas <> nil) and datas.active then begin + setlength(ar1,fcols.count); + setlength(ar2,fcols.count); + for int1:= 0 to high(ar1) do begin + setlength(fbookmarks,datas.recordcount); + with cols[int1] do begin + count:= length(fbookmarks); //max + ar2[int1]:= datapo; + ar1[int1]:= datas.fieldbyname(datafield); + end; + end; + datas.disablecontrols; + try + bm:= datas.bookmark; + try + int2:= 0; + datas.first; + while not datas.eof do begin + fbookmarks[int2]:= datas.bookmark; + for int1:= 0 to high(ar1) do begin + ar2[int1]^[int2]:= msedb.getasmsestring(ar1[int1],fdatalink.utf8); + end; + inc(int2); + datas.next; + end; + for int1:= 0 to cols.count-1 do begin + cols[int1].count:= int2; + end; + setlength(fbookmarks,int2); + finally + datas.bookmark:= bm; + end; + finally + datas.enablecontrols; + end; + end; + result:= tdropdownlist.create(self,fcols,nil); + end + else begin + result:= tdbdropdownlist.create(self,fcols); + with tdbdropdownlist(result) do begin + fdatalink.options:= foptionsdatalink; + if gdo_propscrollbar in fdatalink.options then begin + with frame.sbvert do begin + pagesize:= 1; + end; + end; + end; + end; +end; + +function tcustomdbdropdownlistcontroller.candropdown: boolean; +begin + result:= inherited candropdown and + (fdatalink.active or + (odb_opendataset in foptionsdb) and (fdatalink.dataset <> nil)); +end; + +procedure tcustomdbdropdownlistcontroller.doafterclosedropdown; +begin + inherited; + if (odb_closedataset in foptionsdb) and fdatalink.active then begin + fdatalink.dataset.active:= false; + end; +end; + +procedure tcustomdbdropdownlistcontroller.itemselected(const index: integer; + const akey: keyty); +begin + if index < 0 then begin + if index = -2 then begin + tdropdowncols1(fcols).fitemindex:= fintf.getvalueempty; + end; + end + else begin + if odb_copyitems in foptionsdb then begin + fdatalink.dataset.bookmark:= fbookmarks[index]; + end; + tdropdowncols1(fcols).fitemindex:= index; + end; + if odb_copyitems in foptionsdb then begin + cols.clear; + fbookmarks:= nil; + end; + idbdropdownlist(fintf).recordselected(index,akey); +end; + +procedure tcustomdbdropdownlistcontroller.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + setlength(propertynames,1); + propertynames[0]:= 'keyfield'; + setlength(fieldtypes,1); + if dcs_isstringkey in fstate then begin + fieldtypes[0]:= textfields; + end + else begin + fieldtypes[0]:= integerfields; + end; +end; + +function tcustomdbdropdownlistcontroller.getdataset(const aindex: integer): tdataset; +begin + result:= fdatalink.dataset; +end; + +procedure tcustomdbdropdownlistcontroller.setoptionsdb(const avalue: optionsdbty); +//var +// optionsbefore: optionsdbty; +begin + if avalue <> foptionsdb then begin + foptionsdb:= avalue; + updatereadonlystate; + end; +end; + +function tcustomdbdropdownlistcontroller.getasmsestring(const afield: tfield; + const utf8: boolean): msestring; +begin + if afield = nil then begin + result:= ''; + end + else begin + if (fdropdownlist is tdbdropdownlist) then begin + result:= tdbdropdownlist(fdropdownlist).fdatalink.getasmsestring(afield); + end + else begin + result:= msedb.getasmsestring(afield,utf8); + end; + end; +end; + +function tcustomdbdropdownlistcontroller.getasinteger(const afield: tfield): integer; +begin + if afield = nil then begin + result:= 0; + end + else begin + if (fdropdownlist is tdbdropdownlist) then begin + result:= tdbdropdownlist(fdropdownlist).fdatalink.getasinteger(afield); + end + else begin + result:= afield.asinteger; + end; + end; +end; + +function tcustomdbdropdownlistcontroller.getaslargeint(const afield: tfield): int64; +begin + if afield = nil then begin + result:= 0; + end + else begin + if (fdropdownlist is tdbdropdownlist) then begin + result:= tdbdropdownlist(fdropdownlist).fdatalink.getaslargeint(afield); + end + else begin + result:= afield.aslargeint; + end; + end; +end; + +{ tdbenumeditdb } + +function tdbenumeditdb.getdropdown: tdbdropdownlistcontroller; +begin +{$warnings off} + result:= tdbdropdownlistcontroller(inherited dropdown); +{$warnings on} +end; + +procedure tdbenumeditdb.setdropdown(const avalue: tdbdropdownlistcontroller); +begin + inherited dropdown.assign(avalue); +end; + +function tdbenumeditdb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdbdropdownlistcontroller.create(idbdropdownlist(self),false); +end; + +procedure tdbenumeditdb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdbdropdownlistcontroller(fdropdown) do begin +// text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); +// tdropdowncols1(fcols).fitemindex:= fdatalink.valuefield.asinteger + text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); + tdropdowncols1(fcols).fitemindex:= getasinteger(fdatalink.valuefield); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdbenumeditdb.internaldatatotext(const data): msestring; +var + int1: integer; +begin + if @data = nil then begin + int1:= value; + end + else begin + int1:= integer(data); + end; + result:= tdbdropdownlistcontroller(fdropdown).fdatalink.getlookuptext(int1); +end; + +{ tdbdropdownlisteditdb } + +function tdbdropdownlisteditdb.getdropdown: tdropdownlistcontrollerdb; +begin +{$warnings off} + result:= tdropdownlistcontrollerdb(inherited dropdown); +{$warnings on} +end; + +procedure tdbdropdownlisteditdb.setdropdown(const avalue: tdropdownlistcontrollerdb); +begin + inherited dropdown.assign(avalue); +end; + +function tdbdropdownlisteditdb.createdropdowncontroller: + tcustomdropdowncontroller; +begin + result:= tdropdownlistcontrollerdb.create(idbdropdownlist(self),false); +end; + +procedure tdbdropdownlisteditdb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdropdownlistcontrollerdb(fdropdown) do begin + setdropdowntext(getasmsestring(fdatalink.textfield,fdatalink.utf8),true, + false,akey); + end; + exit; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + if deo_selectonly in dropdown.options then begin + feditor.undo; + end; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +{ tdropdownlisteditdb } + +function tdropdownlisteditdb.getdropdown: tdropdownlistcontrollerdb; +begin +{$warnings off} + result:= tdropdownlistcontrollerdb(inherited dropdown); +{$warnings on} +end; + +procedure tdropdownlisteditdb.setdropdown(const avalue: tdropdownlistcontrollerdb); +begin + inherited dropdown.assign(avalue); +end; + +function tdropdownlisteditdb.createdropdowncontroller: + tcustomdropdowncontroller; +begin + result:= tdropdownlistcontrollerdb.create(idbdropdownlist(self),false); +end; + +procedure tdropdownlisteditdb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdropdownlistcontrollerdb(fdropdown) do begin + setdropdowntext(getasmsestring(fdatalink.textfield,fdatalink.utf8),true, + false,akey); + end; + exit; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + if deo_selectonly in dropdown.options then begin + feditor.undo; + end; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +{ tdbdropdownlisteditlb } + +function tdbdropdownlisteditlb.getdropdown: tdropdownlistcontrollerlb; +begin +{$warnings off} + result:= tdropdownlistcontrollerlb(inherited dropdown); +{$warnings on} +end; + +procedure tdbdropdownlisteditlb.setdropdown( + const avalue: tdropdownlistcontrollerlb); +begin + inherited dropdown.assign(avalue); +end; + +function tdbdropdownlisteditlb.createdropdowncontroller: + tcustomdropdowncontroller; +begin + result:= tdropdownlistcontrollerlb.create(ilbdropdownlist(self)); +end; + +procedure tdbdropdownlisteditlb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdropdownlistcontrollerlb(fdropdown) do begin + setdropdowntext(flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum), + true,false,akey); + end; + exit; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + if deo_selectonly in dropdown.options then begin + feditor.undo; + end; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdbdropdownlisteditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_none; +end; + +{ tdropdownlisteditlb } + +function tdropdownlisteditlb.getdropdown: tdropdownlistcontrollerlb; +begin +{$warnings off} + result:= tdropdownlistcontrollerlb(inherited dropdown); +{$warnings on} +end; + +procedure tdropdownlisteditlb.setdropdown( + const avalue: tdropdownlistcontrollerlb); +begin + inherited dropdown.assign(avalue); +end; + +function tdropdownlisteditlb.createdropdowncontroller: + tcustomdropdowncontroller; +begin + result:= tdropdownlistcontrollerlb.create(ilbdropdownlist(self)); +end; + +procedure tdropdownlisteditlb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdropdownlistcontrollerlb(fdropdown) do begin + setdropdowntext(flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum), + true,false,akey); + end; + exit; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + if deo_selectonly in dropdown.options then begin + feditor.undo; + end; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdropdownlisteditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_none; +end; + +{ tenumeditdb } + +function tenumeditdb.getdropdown: tdbdropdownlistcontroller; +begin +{$warnings off} + result:= tdbdropdownlistcontroller(inherited dropdown); +{$warnings on} +end; + +procedure tenumeditdb.setdropdown(const avalue: tdbdropdownlistcontroller); +begin + inherited dropdown.assign(avalue); +end; + +function tenumeditdb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdbdropdownlistcontroller.create(idbdropdownlist(self),false); +end; + +procedure tenumeditdb.recordselected(const arecordnum: integer; const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdbdropdownlistcontroller(fdropdown) do begin + text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); + tdropdowncols1(fcols).fitemindex:= getasinteger(fdatalink.valuefield); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tenumeditdb.internaldatatotext(const data): msestring; +var + int1: integer; +begin + if @data = nil then begin + int1:= value; + end + else begin + int1:= integer(data); + end; + result:= tdbdropdownlistcontroller(fdropdown).fdatalink.getlookuptext(int1); +end; + +{ tdbkeystringeditdb } + +function tdbkeystringeditdb.getdropdown: tdbdropdownlistcontroller; +begin +{$warnings off} + result:= tdbdropdownlistcontroller(inherited dropdown); +{$warnings on} +end; + +procedure tdbkeystringeditdb.setdropdown(const avalue: tdbdropdownlistcontroller); +begin + inherited dropdown.assign(avalue); +end; + +function tdbkeystringeditdb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdbdropdownlistcontroller.create(idbdropdownlist(self),true); +end; + +procedure tdbkeystringeditdb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdbdropdownlistcontroller(fdropdown) do begin + text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); + tdropdowncols1(fcols).fkeyvalue:= getasmsestring(fdatalink.valuefield, + fdatalink.utf8); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdbkeystringeditdb.internaldatatotext(const data): msestring; +var + mstr1: msestring; +begin + if @data = nil then begin + mstr1:= value; + end + else begin + mstr1:= msestring(data); + end; + result:= tdbdropdownlistcontroller(fdropdown).fdatalink.getlookuptext(mstr1); +end; + +{ tkeystringeditdb } + +function tkeystringeditdb.getdropdown: tdbdropdownlistcontroller; +begin +{$warnings off} + result:= tdbdropdownlistcontroller(inherited dropdown); +{$warnings on} +end; + +procedure tkeystringeditdb.setdropdown(const avalue: tdbdropdownlistcontroller); +begin + inherited dropdown.assign(avalue); +end; + +function tkeystringeditdb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdbdropdownlistcontroller.create(idbdropdownlist(self),true); +end; + +procedure tkeystringeditdb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdbdropdownlistcontroller(fdropdown) do begin + text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); + tdropdowncols1(fcols).fkeyvalue:= getasmsestring(fdatalink.valuefield, + fdatalink.utf8); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tkeystringeditdb.internaldatatotext(const data): msestring; +var + mstr1: msestring; +begin + if @data = nil then begin + mstr1:= value; + end + else begin + mstr1:= msestring(data); + end; + result:= tdbdropdownlistcontroller(fdropdown).fdatalink.getlookuptext(mstr1); +end; + +{ tgriddatalink } + +constructor tgriddatalink.create(const aowner: tcustomgrid; + const aintf: igriddatalink); +begin + fintf:= aintf; + fgrid:= aowner; + include(tcustomgrid1(fgrid).fstate,gs_isdb); + iificlient(aowner).setifiserverintf(iifidataserver(self)); + inherited create; + options:= defaultgriddatalinkoptions; +// visualcontrol:= true; +end; + +destructor tgriddatalink.destroy; +begin + inc(fdatasetchangedlock); + inherited; + fobjectlinker.free; +end; + +procedure tgriddatalink.setfieldname_state(const avalue: string); +begin + if ffieldname_state <> avalue then begin + ffieldname_state:= avalue; + updatefields; + end; +end; + +procedure tgriddatalink.setfieldname_color(const avalue: string); +begin + if ffieldname_color <> avalue then begin + ffieldname_color:= avalue; + updatefields; + end; +end; + +procedure tgriddatalink.setfieldname_font(const avalue: string); +begin + if ffieldname_font <> avalue then begin + ffieldname_font:= avalue; + updatefields; + end; +end; + +procedure tgriddatalink.setfieldname_readonly(const avalue: string); +begin + if ffieldname_readonly <> avalue then begin + ffieldname_readonly:= avalue; + updatefields; + end; +end; + +procedure tgriddatalink.setfieldname_merged(const avalue: string); +begin + if ffieldname_merged <> avalue then begin + ffieldname_merged:= avalue; + updatefields; + end; +end; + +procedure tgriddatalink.setfieldname_selected(const avalue: string); +begin + if ffieldname_selected <> avalue then begin + ffieldname_selected:= avalue; + updatefields; + end; +end; + +function tgriddatalink.getfirstrecord: integer; +begin + result:= inherited firstrecord; +end; + +procedure tgriddatalink.doupdaterowdata(const row: integer); + + procedure fieldtorowstate(const arow: integer); + var + int1: integer; + longword1: longword; + begin + if field_state <> nil then begin + if field_state.isnull then begin + fgrid.rowcolorstate[arow]:= -1; + fgrid.rowfontstate[arow]:= -1; + fgrid.rowreadonlystate[arow]:= false; + end + else begin + int1:= field_state.asinteger; + fgrid.rowcolorstate[arow]:= rowstatenumty(int1 and $7f); + fgrid.rowreadonlystate[arow]:= rowstatenumty(int1 and $80) <> 0; + fgrid.rowfontstate[arow]:= rowstatenumty((int1 shr 8) and $7f); + end; + end; + if (field_color <> nil) then begin + if field_color.isnull then begin + fgrid.rowcolorstate[arow]:= -1; + end + else begin + fgrid.rowcolorstate[arow]:= field_color.asinteger; + end; + end; + if (field_font <> nil) then begin + if field_font.isnull then begin + fgrid.rowfontstate[arow]:= -1; + end + else begin + fgrid.rowfontstate[arow]:= field_font.asinteger; + end; + end; + if (field_readonly <> nil) then begin + fgrid.rowreadonlystate[arow]:= field_readonly.asboolean; + end; + if field_merged <> nil then begin + if gdls_booleanmerged in fstate then begin + if field_merged.asboolean then begin + longword1:= mergedcolall; + end + else begin + longword1:= 0; + end; + end + else begin + longword1:= longword(field_merged.asinteger); + end; + with tdatacols1(fgrid.datacols) do begin + if rowstate.merged[arow] <> longword1 then begin + rowstate.merged[arow]:= longword1; + mergechanged(arow); + end; + end; + end; + if field_selected <> nil then begin + if gdls_booleanselected in fstate then begin + if field_selected.asboolean then begin + longword1:= wholerowselectedmask; + end + else begin + longword1:= 0; + end; + end + else begin + longword1:= longword(field_selected.asinteger); + end; + with tdatacols1(fgrid.datacols) do begin + if rowstate.selected[arow] <> longword1 then begin + rowstate.selected[arow]:= longword1; + fgrid.invalidaterow(arow); + end; + end; + end; + end; + +var + int1,int2: integer; + dataset1: tdataset; + buffercount1: int32; +begin + if (fgrid.componentstate * [csloading,csdesigning,csdestroying] = []) and + (row < fgrid.rowcount) then begin + dataset1:= dataset; + if dataset1 <> nil then begin + buffercount1:= buffercount; + if gdls_hasrowstatefield in fstate then begin + if row >= 0 then begin + if row < buffercount1 then begin + fieldtorowstate(row); + end; + end + else begin + int2:= activerecord; + try + for int1:= 0 to fgrid.rowhigh do begin + if int1 >= buffercount1 then begin + break; //buffer invalid + end; + activerecord:= int1; + fieldtorowstate(int1); + end; + finally + activerecord:= int2; + end; + end; + end; + if assigned(fonupdaterowdata) then begin + if row >= 0 then begin + fonupdaterowdata(fgrid,row,dataset1); + end + else begin + int2:= activerecord; + try + for int1:= 0 to fgrid.rowhigh do begin + if int1 >= buffercount1 then begin + break; //buffer invalid + end; + activerecord:= int1; + fonupdaterowdata(fgrid,int1,dataset1); + end; + finally + activerecord:= int2; + end; + end; + end; + tdatacols1(fgrid.datacols).invalidatemaxsize(-1); + end; + end; + if row < 0 then begin + fgridinvalidated:= false; //grid possibly invisible -> no painted call + end; +end; + +function tgriddatalink.hasdata: boolean; +begin + result:= active and datasource.enabled and (recordcount > 0); +end; + +procedure tgriddatalink.readdatasource(reader: treader); +begin + treader1(reader).readpropvalue(self, + getpropinfo(typeinfo(tgriddatalink),'datasource')); +end; + +procedure tgriddatalink.fixupproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('datasource',{$ifdef FPC}@{$endif}readdatasource,nil,false); + //move values to datalink +end; + +procedure tgriddatalink.readdatafield(reader: treader); +begin + fieldname_state:= reader.readstring; +end; + +procedure tgriddatalink.defineproperties(filer: tfiler); +begin + filer.defineproperty('datafield',{$ifdef FPC}@{$endif}readdatafield,nil,false); +end; + +function tgriddatalink.getrowfieldisnull(const afield: tfield; + const row: integer): boolean; +var + rowinfo: gridrowinfoty; +begin + result:= true; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + result:= afield.isnull; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getansistringbuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fansistringbuffer; + fansistringbuffer:= afield.asstring; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getstringbuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fstringbuffer; + if afield is tmsestringfield then begin + fstringbuffer:= tmsestringfield(afield).asmsestring; + end + else begin + if utf8 and (afield.datatype in textfields) then begin + fstringbuffer:= utf8tostringansi(afield.asstring); + end + else begin + fstringbuffer:= msestring(afield.asstring); + end; + end; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getdisplaystringbuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fstringbuffer; + if afield is tmsestringfield then begin + fstringbuffer:= tmsestringfield(afield).asmsestring; + end + else begin + if afield is tmsememofield then begin + fstringbuffer:= tmsememofield(afield).asmsestring; + end + else begin + if utf8 and (afield.datatype in textfields) then begin + fstringbuffer:= utf8tostringansi(afield.displaytext); + end + else begin + fstringbuffer:= msestring(afield.displaytext); + end; + end; + end; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getbooleanbuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fintegerbuffer; + fintegerbuffer:= integer(afield.asboolean); + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getintegerbuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fintegerbuffer; + fintegerbuffer:= afield.asinteger; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getint64buffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fint64buffer; + fint64buffer:= afield.aslargeint; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getrealtybuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @frealtybuffer; + frealtybuffer:= afield.asfloat; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getdatetimebuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @frealtybuffer; + frealtybuffer:= afield.asdatetime; + end; + endgridrow(rowinfo); + end; +end; + +procedure tgriddatalink.updatelayout; +var +// ar1: integerarty; + int1: integer; +begin + with tcustomgrid1(fgrid) do begin + int1:= fgrid.rowsperpage + 1; + if int1 = 0 then begin + int1:= 1; + end; + BufferCount:= int1; + if self.active then begin + forcecalcrange; + checkscroll; + end; + int1:= fgrid.rowcount; + self.updaterowcount; + if int1 <> fgrid.rowcount then begin + tcustomgrid1(fgrid).updatelayout; //again + exit; + end; + end; + checkscrollbar; + checkactiverecord; //show cell +end; + +procedure tgriddatalink.updaterowcount; +var + int1: integer; +begin + if not (csdestroying in fgrid.componentstate) then begin + if active then begin + int1:= recordcount; + end + else begin + int1:= 0; + end; + if fgrid.rowcount <> int1 then begin + gridinvalidate; + fgrid.rowcount:= int1; + end; + end; +end; + +procedure tgriddatalink.datasetchanged; +//var +// state1: tdatasetstate; +begin + if (fdatasetchangedlock = 0) and not (csdestroying in fgrid.componentstate) then begin + finserting:= (dataset <> nil) and (dataset.state = dsinsert); + if recordcount > fgrid.rowcount then begin + updaterowcount; //for append + end; + inherited; + gridinvalidate; + if finserting and not finsertingbefore and (fgrid.datacols.newrowcol >= 0) then begin + fgrid.col:= fgrid.datacols.newrowcol; + end; + finsertingbefore:= finserting; + checkdelayedautoinsert; + end; +end; + +procedure tgriddatalink.datasetscrolled(distance: integer); +begin + if (fmovebydistance < 0) and bof or (fmovebydistance > 0) and eof then begin + include(tcustomgrid1(fgrid).fstate1,gs1_scrolllimit); + end; + fmovebydistance:= 0; + ffirstrecordbefore:= firstrecord - distance; + recordchanged(nil); +end; + +procedure tgriddatalink.forcecalcrange; +begin + if active then begin + inc(fdatasetchangedlock); + try + dataevent(dedatasetchange,0); //force tdatalink.calcrange + finally + dec(fdatasetchangedlock); + end; + end; +end; + +procedure tgriddatalink.activechanged; +begin + inherited; + if not active then begin + fzebraoffset:= 0; + factiverecordbefore:= 0; + ffirstrecordbefore:= 0; + fdatasetstatebefore:= dsinactive; + fdscontroller:= nil; + inherited firstrecord:= 0; + end + else begin + if (fsortdatalink <> nil) and (fdscontroller <> nil) then begin + fdscontroller.updatesortfield(fsortdatalink,fdescend); + end; + end; + updaterowcount; + checkscroll; + gridinvalidate; + checkscrollbar; + if active then begin + forcecalcrange; + if (fgrid.rowcount > 0) then begin + if (fgrid.col < 0) and (fgrid.entered) then begin + fgrid.focuscell(makegridcoord(fgrid.col,activerecord),fca_entergrid); + end + else begin + fgrid.focuscell(makegridcoord(fgrid.col,activerecord)); + end; + end; + factiverecordbefore:= activerecord; + checkdelayedautoinsert; + end; +end; + +procedure tgriddatalink.checkzebraoffset; +begin + if active and (gs_needszebraoffset in tcustomgrid1(fgrid).fstate) then begin + fzebraoffset:= -(arecord - activerecord); + end + else begin + fzebraoffset:= 0; + end; +end; + +procedure tgriddatalink.checkscroll; +var + rect1,rect2: rectty; + distance: integer; +// rowbefore: integer; + int1: integer; + +begin + checkzebraoffset; + distance:= firstrecord - ffirstrecordbefore; + ffirstrecordbefore:= firstrecord; + with tcustomgrid1(fgrid) do begin +// rowbefore:= row; + if distance <> 0 then begin + inc(frowexited); + row:= invalidaxis; + end; + if (abs(distance) >= rowcount) then begin + gridinvalidate; + end + else begin + if (distance <> 0) then begin + if not fgridinvalidated then begin + rect1:= fdatarecty; + if (og_rowheight in foptionsgrid) then begin + invalidaterect(rect1,org_client); //scrolling not possible + end + else begin + int1:= -distance*ystep; + rect2:= rect1; + if int1 < 0 then begin + dec(rect2.y,int1); + inc(rect2.cy,int1); + end + else begin + dec(rect2.cy,int1); + end; + if (rect2.cy > 0) and testintersectrect(rect2,updaterect) then begin + ffirstrecordshift:= distance; + inc(fzebraoffset,distance); + try + update; //draw old position + finally + dec(fzebraoffset,distance); + ffirstrecordshift:= 0; + end; + end; + dec(factiverecordbefore,distance); + scrollrect(makepoint(0,int1),rect1,true); + end; + { + if (og_rowheight in foptionsgrid) or testintersectrect(rect1,updaterect) then begin + invalidaterect(rect1,org_client); //scrolling not possible + end + else begin + dec(factiverecordbefore,distance); + scrollrect(makepoint(0,-distance*ystep),rect1,true); + end; + } + end; + inc(fnoinvalidate); + try + doupdaterowdata(-1); + finally + dec(fnoinvalidate); + end; + if (gs_needsrowheight in fstate) then begin + fdatacols.rowstate.change(-1); + end; + end; + end; + if (activerecord < rowcount) and + not (csdestroying in componentstate) then begin + inc(fnocheckvalue); + try + row:= activerecord; + finally + dec(fnocheckvalue); + end; + end; + end; +end; + +procedure tgriddatalink.checkactiverecord; +var + int1: integer; +begin + int1:= activerecord; + if (int1 < fgrid.rowcount) and active and + (tcustomgrid1(fgrid).fcellvaluechecking = 0) then begin + with tcustomgrid1(fgrid) do begin + inc(fnocheckvalue); + try + row:= int1; //else empty dataset + showcell(makegridcoord(invalidaxis,fgrid.row),cep_nearest,true); + finally + dec(fnocheckvalue); + end; + end; + end; +end; + +procedure tgriddatalink.recordchanged(afield: tfield); +var + int1: integer; + i2: int32; +// b1: boolean; +begin + int1:= frowexited; + with tcustomgrid1(fgrid) do begin + i2:= row; + if fcellvaluechecking = 0 then begin +// b1:= gs1_nocellassistive in fstate1; +// try +// include(fstate1,gs1_nocellassistive); + checkscroll(); +// finally +// if not b1 then begin +// exclude(fstate1,gs1_nocellassistive); +// end; +// end; + end; + fgrid.invalidaterow(activerecord); + tcustomgrid1(fgrid).beginnonullcheck; + tcustomgrid1(fgrid).beginnocheckvalue; + try +// b1:= gs1_nocellassistive in fstate1; +// if row <> i2 then begin +// include(fstate1,gs1_nocellassistive); +// end; + if (row = i2) and (afield = nil) and (frowexited = int1) and + (feditingbefore = editing) then begin + fgrid.row:= invalidaxis; + end; + checkactiverecord; + finally +// if not b1 then begin +// exclude(fstate1,gs1_nocellassistive); +// end; + tcustomgrid1(fgrid).endnonullcheck; + tcustomgrid1(fgrid).endnocheckvalue; + feditingbefore:= editing; + end; + fgrid.invalidaterow(factiverecordbefore); + factiverecordbefore:= activerecord; + if afield = nil then begin + updaterowcount; + checkscrollbar; + end; + end; + doupdaterowdata(activerecord); +end; + +function tgriddatalink.arecord: integer; +begin + if fdscontroller <> nil then begin + result:= fdscontroller.recnozerobased; + end + else begin + result:= dataset.recno; + end; +end; + +function tgriddatalink.rowtorecnozerobased(const row: integer): integer; +begin + if active then begin + result:= recnozerobased + row - activerecord; + end + else begin + result:= -1; + end; +end; + +function tgriddatalink.isfirstrow: boolean; +begin + result:= not active or bof; +end; + +function tgriddatalink.islastrow: boolean; +begin + result:= not active or eof; +end; + +procedure tgriddatalink.checkscrollbar; +var + rea1: real; + int1: integer; +begin + rea1:= 0.5; + if active then begin + int1:= dataset.recordcount - 1; + if bof then begin + rea1:= 0; + end + else begin + if eof then begin + rea1:= 1; + end + else begin + if (gdo_propscrollbar in foptions) and (int1 > 0) then begin + rea1:= arecord / int1; + end; + end; + end; + if int1 < 0 then begin + int1:= 0 + end; + fgrid.frame.sbvert.pagesize:= fgrid.rowcount / (int1+1+fgrid.rowcount); + end + else begin + fgrid.frame.sbvert.pagesize:= 1; + end; + fgrid.frame.sbvert.value:= rea1; +end; + +procedure tgriddatalink.cellevent(var info: celleventinfoty); +var + int1: integer; +begin + with info do begin + if (eventkind = cek_enter) and active then begin + int1:= newcell.row-activerecord; + if int1 <> 0 then begin + moveby(int1); + end; + end; + end; +end; + +procedure tgriddatalink.invalidateindicator; +var + int1,int2: integer; +begin + int1:= fintf.getdbindicatorcol; + int2:= activerecord; + if (int1 < 0) and (int2 >= 0) then begin + fgrid.invalidatecell(makegridcoord(int1,int2)); + end; +end; + +function tgriddatalink.scrollevent(sender: tcustomscrollbar; + event: scrolleventty): boolean; + //true if processed +var + int1,int2: integer; +begin + result:= true; + if sender.tag = 1 then begin + with fgrid do begin + case event of + sbe_stepup: rowdown(fca_focusin); + sbe_stepdown: rowup(fca_focusin); + sbe_pageup: pagedown(fca_focusin); + sbe_pagedown: pageup(fca_focusin); + sbe_wheelup: wheeldown(fca_focusin); + sbe_wheeldown: wheelup(fca_focusin); + {sbe_thumbtrack,}sbe_valuechanged: begin + end; + sbe_thumbtrack,sbe_thumbposition: begin + if (event <> sbe_thumbtrack) or (gdo_thumbtrack in foptions) then begin + if self.active then begin + if (sender.value = 0) then begin + if not dataset.bof then begin + dataset.first; + end; + end + else begin + if sender.value >= 1.0 then begin + if not dataset.eof then begin + dataset.last + end; + end + else begin + if (not dataset.filtered or (dscontroller <> nil)) and + (gdo_propscrollbar in foptions) then begin + int1:= dataset.recordcount; + if int1 >= 0 then begin + int2:= round(int1 * sender.value)+1; + //are recnos allways 1-based? + if (int2 >= int1) then begin + if not dataset.eof then begin + dataset.last; + end; + end + else begin + if dscontroller = nil then begin + dataset.recno:= int2; + end + else begin + dscontroller.findrecno(int2); //use cached recno +// dscontroller.recno:= int2; //use cached recno + end; + end; + end; + end + else begin + if event <> sbe_thumbtrack then begin + if sender.value < 0.5 then begin + moveby(-fgrid.rowhigh); + end + else begin + moveby(fgrid.rowhigh); + end; + sender.value:= 0.5; + end; + end; + end; + end; + end + else begin + if event <> sbe_thumbtrack then begin + sender.value:= 0.5; + end; + end; + end + end; + else result:= false; + end; + end; + end + else begin + result:= false; + end; +end; + +procedure tgriddatalink.doinsertrow; +begin + if checkvalue and caninsert then begin + dataset.insert; + with fgrid,datacols do begin + if newrowcol >= 0 then begin + focuscell(makegridcoord(newrowcol,row)); + end; + end; + end; +end; + +procedure tgriddatalink.doappendrow; +begin + if checkvalue and canappend then begin + if not eof then begin + moveby(1); + end; + if not eof then begin + dataset.insert; + end + else begin + dataset.append; + end; + with fgrid,datacols do begin + if newrowcol >= 0 then begin + focuscell(makegridcoord(newrowcol,row)); + end; + end; + end; +end; + +procedure tgriddatalink.dodeleterow; +begin + if candelete and confirmdeleterecord then begin + dataset.delete; + end; +end; + +procedure tgriddatalink.rowdown; +begin + if checkvalue then begin + moveby(1); + if (og_autoappend in tcustomgrid1(fgrid).foptionsgrid) and canappend and eof and + (datasource.autoedit or + (navigator <> nil) and navigator.autoedit) then begin + dataset.append; + with fgrid,datacols do begin + if newrowcol >= 0 then begin + focuscell(makegridcoord(newrowcol,row)); + end; + end; + end; + end; +end; + +procedure tgriddatalink.lastrow; +begin + if active and checkvalue then begin + dataset.last; + end; +end; + +procedure tgriddatalink.firstrow; +begin + if active and checkvalue then begin + dataset.first; + end; +end; + +function tgriddatalink.getzebrastart: integer; +begin + result:= tcustomgrid1(fgrid).fzebra_start + fzebraoffset; +end; + +procedure tgriddatalink.gridinvalidate; +begin + if not fgridinvalidated then begin + fgrid.invalidate; + fgridinvalidated:= true; + application.postevent(tobjectevent.create(ek_dbupdaterowdata,ievent(self))); + end; +end; + +procedure tgriddatalink.painted; +begin + fgridinvalidated:= false; +end; + +procedure tgriddatalink.loaded; +begin + doupdaterowdata(-1); + with tcustomgrid1(fgrid) do begin + if fdatacols.sortcol >= 0 then begin + optionsgrid:= optionsgrid + [og_sorted]; + end; + end; +end; + +procedure tgriddatalink.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + if (info.eventstate * [es_preview,es_processed] = []) and + (fnavigator <> nil) and fnavigator.showing and + fnavigator.isenabled then begin + fnavigator.internalshortcut(info,sender); + end; +end; + +function tgriddatalink.checkvalue: boolean; +begin + if editing then begin + result:= fgrid.canparentclose; + end + else begin + result:= true; + end; +end; + +procedure tgriddatalink.beginnullchecking; +begin + inc(fnullchecking); + tcustomgrid1(fgrid).beginnullchecking; +end; + +procedure tgriddatalink.endnullchecking; +begin + tcustomgrid1(fgrid).endnullchecking; + dec(fnullchecking); +end; + +function tgriddatalink.domoveby(const distance: integer): integer; +begin + result:= 0; + if active and (dataset.state <> dsfilter) then begin + fmovebydistance:= distance; + result:= inherited moveby(distance); + end; +end; + +function tgriddatalink.moveby(distance: integer): integer; +begin + invalidateindicator; //grid can be defocused + result:= 0; + if fnullchecking = 0 then begin + beginnullchecking; + try + if checkvalue then begin + result:= domoveby(distance); + end + else begin + tcustomgrid1(fgrid).beginnonullcheck; + try + checkactiverecord; + finally + tcustomgrid1(fgrid).endnonullcheck; + end; + end; + finally + endnullchecking; + end; + end; +end; + +function tgriddatalink.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(ievent(self),nil,fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tgriddatalink.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tgriddatalink.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tgriddatalink.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tgriddatalink.getinstance: tobject; +begin + result:= self; +end; + +procedure tgriddatalink.receiveevent(const event: tobjectevent); +begin + case event.kind of + ek_dbedit: begin + edit; + end; + ek_dbupdaterowdata: begin + doupdaterowdata(-1); + end; + ek_dbinsert: begin + if fautoinserting then begin + try + if canautoinsert then begin + dataset.insert; + end; + finally + fautoinserting:= false; + end; + end; + end; + end; +end; + +procedure tgriddatalink.updatedata; +begin + beginnullchecking; + tcustomgrid1(fgrid).beginnonullcheck; + try + if checkvalue then begin + if (og_appendempty in fgrid.optionsgrid) and + (dataset.state = dsinsert) then begin + tdataset1(dataset).setmodified(true); //FPC fixes_2_6 compatibility + //force append empty row +// dataset.modified:= true; //force append empty row + end; + inherited; + end + else begin + abort; + end; + finally + tcustomgrid1(fgrid).endnonullcheck; + endnullchecking; + end; +end; + +function tgriddatalink.getdataset(const aindex: integer): tdataset; +begin + result:= dataset; +end; + +procedure tgriddatalink.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + setlength(fieldtypes,1); + fieldtypes[0]:= integerfields; +end; + +function tgriddatalink.canautoinsert: boolean; +begin +// result:= fgrid.focused and active and (recordcount = 0) and + result:= fgrid.entered and active and (recordcount = 0) and + (og_autofirstrow in fgrid.optionsgrid) and + (datasource.autoedit or + (navigator <> nil) and navigator.autoedit); +end; + +procedure tgriddatalink.checkdelayedautoinsert; +begin + if canautoinsert and not fautoinserting then begin + fautoinserting:= true; + application.postevent(tobjectevent.create(ek_dbinsert,ievent(self))); + end; +end; + +procedure tgriddatalink.beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); +begin + if (selectaction = fca_entergrid) and canautoinsert and + not fautoinserting then begin + fautoinserting:= true; + try + dataset.insert; + fgrid.focuscell(fgrid.focusedcell,selectaction); + //focus col if necessary + finally + fautoinserting:= false; + end; + end; +end; + +function tgriddatalink.getdummystringbuffer: pansistring; +begin + fdummystringbuffer:= ''; + result:= @fdummystringbuffer; +end; + +function tgriddatalink.canclose(const newfocus: twidget): boolean; +begin + result:= not (gdo_checkbrowsemodeonexit in foptions) or + (fgrid.widgetstate * [ws_entered,ws_exiting] = []) or + fgrid.checkdescendent(newfocus) or inherited canclose; +end; + +procedure tgriddatalink.focuscell(var cell: gridcoordty); +var + int1,int2,int3,int4: integer; + ds1: tdataset; +begin + if (cell.row >= 0) and (cell.row <> fgrid.row) then begin + ds1:= dataset; + if (ds1 <> nil) then begin + int1:= rowtorecnozerobased(cell.row); + if not (finserting and not finsertingbefore) then begin + int3:= recnozerobased; + if (ds1.state <> dsfilter) and not fautoinserting and + (tcustomgrid1(fgrid).fnocheckvalue = 0) then begin + ds1.checkbrowsemode; + end; + int4:= recnozerobased; + if (int1 < int3) and (int1 >= int4) then begin + inc(int1); + end + else begin + if (int1 > int3) and (int1 <= int4) then begin + dec(int1); + end; + end; + end; + int2:= ds1.recordcount; + if (int1 >= 0) and (int1 < int2) and (ds1.state <> dsfilter) then begin + invalidateindicator; //grid can be defocused + int1:= int1-recnozerobased; + if int1 <> 0 then begin + dataset.moveby(int1); + end; + end; + cell.row:= activerecord; + end; + end; +end; + +procedure tgriddatalink.editingchanged; +begin + updaterowcount; //for insert + invalidateindicator; + inherited; + if editing and fgrid.canevent(tmethod(fonbeginedit)) then begin + fonbeginedit(self); + end; + if not editing and fgrid.canevent(tmethod(fonendedit)) then begin + fonendedit(self); + end; +end; + +function tgriddatalink.getdatasource1: tdatasource; +begin + result:= inherited datasource; +end; + +procedure tgriddatalink.settadasource1(const avalue: tdatasource); +begin + inherited datasource:= avalue; + tdatacols1(fgrid.datacols).datasourcechanged; +end; + +procedure tgriddatalink.updatefields; +begin + if active then begin + if (ffieldname_state <> '') then begin + setfield_state(datasource.dataset.fieldbyname(ffieldname_state)); + end + else begin + setfield_state(nil); + end; + if (ffieldname_color <> '') then begin + setfield_color(datasource.dataset.fieldbyname(ffieldname_color)); + end + else begin + setfield_color(nil); + end; + if (ffieldname_font <> '') then begin + setfield_font(datasource.dataset.fieldbyname(ffieldname_font)); + end + else begin + setfield_font(nil); + end; + if (ffieldname_readonly <> '') then begin + setfield_readonly(datasource.dataset.fieldbyname(ffieldname_readonly)); + end + else begin + setfield_readonly(nil); + end; + if (ffieldname_merged <> '') then begin + setfield_merged(datasource.dataset.fieldbyname(ffieldname_merged)); + end + else begin + setfield_merged(nil); + end; + if (ffieldname_selected <> '') then begin + setfield_selected(datasource.dataset.fieldbyname(ffieldname_selected)); + end + else begin + setfield_selected(nil); + end; + end + else begin + setfield_state(nil); + setfield_color(nil); + setfield_font(nil); + setfield_readonly(nil); + setfield_merged(nil); + setfield_selected(nil); + end; +end; + +procedure tgriddatalink.setfield_state(const avalue: tfield); +begin + if ffield_state <> avalue then begin + ffield_state:= avalue; + fieldchanged; + end; +end; + +procedure tgriddatalink.setfield_color(const avalue: tfield); +begin + if ffield_color <> avalue then begin + ffield_color:= avalue; + fieldchanged; + end; +end; + +procedure tgriddatalink.setfield_font(const avalue: tfield); +begin + if ffield_font <> avalue then begin + ffield_font:= avalue; + fieldchanged; + end; +end; + +procedure tgriddatalink.setfield_readonly(const avalue: tfield); +begin + if ffield_readonly <> avalue then begin + ffield_readonly:= avalue; + fieldchanged; + end; +end; + +procedure tgriddatalink.setfield_merged(const avalue: tfield); +begin + if ffield_merged <> avalue then begin + ffield_merged:= avalue; + if avalue is tbooleanfield then begin + include(fstate,gdls_booleanmerged); + end + else begin + exclude(fstate,gdls_booleanmerged); + end; + fieldchanged; + end; +end; + +procedure tgriddatalink.setfield_selected(const avalue: tfield); +begin + if ffield_selected <> avalue then begin + ffield_selected:= avalue; + if avalue is tbooleanfield then begin + include(fstate,gdls_booleanselected); + end + else begin + exclude(fstate,gdls_booleanselected); + end; + fieldchanged; + end; +end; + +procedure tgriddatalink.fieldchanged; +begin + if (ffield_state <> nil) or (ffield_color <> nil) or (ffield_font <> nil) or + (ffield_readonly <> nil) or (ffield_merged <> nil) or + (ffield_selected <> nil) then begin + include(fstate,gdls_hasrowstatefield); + end + else begin + exclude(fstate,gdls_hasrowstatefield); + end; + inherited; +end; + +procedure tgriddatalink.setselected(const cell: gridcoordty; + const avalue: boolean); +var + bo1: boolean; +begin + if (ffield_selected <> nil) and (cell.row >= 0) and + (cell.row = activerecord) then begin + bo1:= editing; + dataset.edit; + if gdls_booleanselected in fstate then begin + ffield_selected.asboolean:= avalue; + end + else begin + if cell.col < 0 then begin + if avalue then begin + ffield_selected.asinteger:= integer(wholerowselectedmask); + end + else begin + ffield_selected.asinteger:= 0; + end; + end + else begin + if cell.col <= selectedcolmax then begin + if avalue then begin + ffield_selected.asinteger:= ffield_selected.asinteger or bits[cell.col]; + end + else begin + ffield_selected.asinteger:= ffield_selected.asinteger and + not bits[cell.col]; + end; + end; + end; + end; + if not bo1 and (gdo_selectautopost in foptions) then begin + dataset.post; + end; + end; +end; + +function tgriddatalink.updateoptionsgrid( + const avalue: optionsgridty): optionsgridty; +begin + result:= avalue - [og_sorted]; + with tcustomgrid1(fgrid) do begin + if og_sorted in avalue then begin + if not (gs1_dbsorted in fstate1) then begin + include(fstate1,gs1_dbsorted); + invalidate; + end + end + else begin + if gs1_dbsorted in fstate1 then begin + exclude(fstate1,gs1_dbsorted); + updatesortfield(nil,false); + invalidate; + end; + end; + end; +end; + +function tgriddatalink.updatesortfield(const avalue: tfielddatalink; + const adescend: boolean): boolean; +begin + fdescend:= adescend; + fsortdatalink:= avalue; + result:= true; + if active then begin + result:= false; + if fdscontroller <> nil then begin + result:= fdscontroller.updatesortfield(avalue,adescend); + end; + end; +end; + +function tgriddatalink.begingridrow(const arow: integer; + out ainfo: gridrowinfoty): boolean; +var + int1: integer; +begin + int1:= arow - ffirstrecordshift; + result:= (int1 >= 0) and (int1 < recordcount); + ainfo.row:= activerecord; + if result then begin + ainfo.row:= activerecord; + { + if ainfo.row <> fgrid.row then begin + //probably changed by tdatalink.destroy -> dataset.recalcbuflistsize + result:= false; + checkzebraoffset; + checkactiverecord; + fgrid.invalidaterow(invalidaxis); + exit; + end; + } + if (fdscontroller <> nil) and (datasource.state <> dsfilter) then begin + fdscontroller.begindisplaydata; + end; + activerecord:= int1; + end; +end; + +procedure tgriddatalink.endgridrow(const ainfo: gridrowinfoty); +begin + if (fdscontroller <> nil) and (datasource.state <> dsfilter) then begin + fdscontroller.enddisplaydata; + end; + activerecord:= ainfo.row; +end; + +procedure tgriddatalink.setnavigator(const avalue: tdbnavigator); +begin + if fnavigator <> avalue then begin + getobjectlinker.setlinkedvar(iobjectlink(self),tmsecomponent(avalue), + tmsecomponent(fnavigator)); + fintf.setnavigator(avalue); + end; +end; + +function tgriddatalink.getrecordcount: integer; +begin + result:= 1; + if dataset.state <> dsfilter then begin + result:= inherited getrecordcount; + end; +end; + + +{ tdbwidgetindicatorcol } + +constructor tdbwidgetindicatorcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fcolorindicator:= cl_glyph; + inherited; + options:= defaultindicatorcoloptions; + width:= 15; +end; + +procedure tdbwidgetindicatorcol.drawcell(const canvas: tcanvas); +begin + with cellinfoty(canvas.drawinfopo^),tdbwidgetfixcols(prop) do begin + if fdatalink.active and (cell.row = fdatalink.activerecord) then begin + include(drawstate,cds_notext); + inherited; + drawindicatorcell(canvas,fdatalink,fcolorindicator); + end + else begin + inherited; + end; + end; +end; + +procedure tdbwidgetindicatorcol.setcolorindicator(const avalue: colorty); +begin + if fcolorindicator <> avalue then begin + fcolorindicator:= avalue; + changed; + end; +end; + +{ tdbwidgetfixcols } + +constructor tdbwidgetfixcols.create(const aowner: tcustomwidgetgrid; + const adatalink: tgriddatalink); +begin + fdatalink:= adatalink; + inherited create(aowner); +end; + +procedure tdbwidgetfixcols.createitem(const index: integer; var item: tpersistent); +begin + if index = fdbindicatorcol then begin + item:= tdbwidgetindicatorcol.create(fgrid,self); + end + else begin + inherited; + end; +end; + +procedure tdbwidgetfixcols.setcount1(acount: integer; doinit: boolean); +begin + if (acount <= 0) and not (csdestroying in fgrid.componentstate) then begin + acount:= 1; + end; + if fdbindicatorcol >= acount then begin + fdbindicatorcol:= acount - 1; + end; + inherited; +end; + +procedure tdbwidgetfixcols.setdbindicatorcol(const Value: integer); +var + int1,int2: integer; +begin + int1:= -1 - value; + if int1 < 0 then begin + int1:= 0; + end; + if int1 >= count then begin + int1:= count-1; + end; + int2:= fdbindicatorcol; + if int1 <> int2 then begin + move(int2,int1); + fdbindicatorcol := int1; + end; +end; + +function tdbwidgetfixcols.getdbindicatorcol: integer; +begin + result:= -1-fdbindicatorcol; +end; + +{ tdbscrollbar } + +constructor tdbscrollbar.create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); +begin + inherited; + foptions:= defaultdbscrollbaroptions; + buttonlength:= -1; +end; + +procedure tdbscrollbar.setoptions(const avalue: scrollbaroptionsty); +begin + inherited setoptions(avalue + [sbo_thumbtrack]); +end; + +{ tdbgridframe } + +constructor tdbgridframe.create(const aintf: iscrollframe; const owner: twidget; + const autoscrollintf: iautoscrollframe); +begin + inherited; + include(fstate,fs_sbvertfix); +end; + +function tdbgridframe.getscrollbarclass(vert: boolean): framescrollbarclassty; +begin + if vert then begin + result:= tdbscrollbar; + end + else begin + result:= inherited getscrollbarclass(vert); + end; +end; + +procedure tdbgridframe.scrollevent(sender: tcustomscrollbar; event: scrolleventty); +begin + if sender.tag = 1 then begin + fintf1.scrollevent(sender,event); + end + else begin + inherited; + end; +end; + +procedure tdbgridframe.scrollpostoclientpos(var aclientrect: rectty); +begin + with aclientrect do begin + x:= - round(fhorz.value * (cx-fpaintrect.cx)); + y:= tcustomgrid1(fowner).fscrollrect.y; + end; +end; + +{ tcustomdbwidgetgrid } + +constructor tcustomdbwidgetgrid.create(aowner: tcomponent); +begin + fdatalink:= tgriddatalink.create(self,igriddatalink(self)); + inherited; + fzebra_step:= 0; + ffixcols.count:= 1; +end; + +destructor tcustomdbwidgetgrid.destroy; +begin + inherited; + fdatalink.free; +end; + +function tcustomdbwidgetgrid.getdatalink: tgriddatalink; +begin + result:= fdatalink; +end; + +procedure tcustomdbwidgetgrid.setoptionsgrid(const avalue: optionsgridty); +begin + inherited setoptionsgrid(fdatalink.updateoptionsgrid(avalue)); +end; + +procedure tcustomdbwidgetgrid.internalcreateframe; +begin + tdbgridframe.create(iscrollframe(self),self,iautoscrollframe(self)); +end; + +function tcustomdbwidgetgrid.createfixcols: tfixcols; +begin + result:= tdbwidgetfixcols.create(self,fdatalink); +end; +{ +function tcustomdbwidgetgrid.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tcustomdbwidgetgrid.setdatasource(const Value: tdatasource); +begin + fdatalink.datasource:= value; + datacols.datasourcechanged; +end; +} +procedure tcustomdbwidgetgrid.dolayoutchanged; +begin + inherited; + fdatalink.updatelayout; +end; +{ +procedure tcustomdbwidgetgrid.initcellinfo(var info: cellinfoty); +begin + inherited; + info.griddatalink:= fdatalink; +end; +} +procedure tcustomdbwidgetgrid.docellevent(var info: celleventinfoty); +begin + inherited; + fdatalink.cellevent(info); +end; + +procedure tcustomdbwidgetgrid.scrollevent(sender: tcustomscrollbar; event: scrolleventty); +begin + if not fdatalink.scrollevent(sender,event) then begin + inherited; + end; +end; + +function tcustomdbwidgetgrid.getzebrastart: integer; +begin + result:= fdatalink.getzebrastart; +end; + +function tcustomdbwidgetgrid.getnumoffset: integer; +begin + result:= -fdatalink.fzebraoffset; +end; + +procedure tcustomdbwidgetgrid.dopaint(const acanvas: tcanvas); +begin + inherited; + fdatalink.painted; +end; + +procedure tcustomdbwidgetgrid.dohide; +begin + fdatalink.painted; + inherited; +end; + +procedure tcustomdbwidgetgrid.pagedown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(rowcount-1); +end; + +procedure tcustomdbwidgetgrid.pageup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-rowcount+1); +end; + +procedure tcustomdbwidgetgrid.wheeldown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(wheelheight); +end; + +procedure tcustomdbwidgetgrid.wheelup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-wheelheight); +end; + +procedure tcustomdbwidgetgrid.rowdown( + const action: focuscellactionty = fca_focusin; const nowrap: boolean = false); +begin + fdatalink.rowdown; +end; + +procedure tcustomdbwidgetgrid.rowup( + const action: focuscellactionty = fca_focusin;const nowrap: boolean = false); +begin + fdatalink.MoveBy(-1); +end; + +procedure tcustomdbwidgetgrid.lastrow(const action: focuscellactionty = fca_focusin); +begin + fdatalink.lastrow; +end; + +procedure tcustomdbwidgetgrid.firstrow(const action: focuscellactionty = fca_focusin); +begin + fdatalink.firstrow; +end; + +procedure tcustomdbwidgetgrid.dodeleterow(const sender: tobject); +begin + fdatalink.dodeleterow; +end; + +procedure tcustomdbwidgetgrid.doinsertrow(const sender: tobject); +begin + fdatalink.doinsertrow; +end; + +procedure tcustomdbwidgetgrid.doappendrow(const sender: tobject); +begin + fdatalink.doappendrow; +end; + + +procedure tcustomdbwidgetgrid.setdatalink(const avalue: tgriddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tcustomdbwidgetgrid.loaded; +begin + inherited; + fdatalink.loaded; +end; + +procedure tcustomdbwidgetgrid.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +function tcustomdbwidgetgrid.getgriddatalink: pointer; +begin + result:= fdatalink; +end; + +procedure tcustomdbwidgetgrid.beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); +begin + fdatalink.beforefocuscell(cell,selectaction); +end; + +function tcustomdbwidgetgrid.canclose(const newfocus: twidget): boolean; +begin + result:= inherited canclose(newfocus) and fdatalink.canclose(newfocus); +end; + +function tcustomdbwidgetgrid.focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; +begin + fdatalink.focuscell(cell); + result:= inherited focuscell(cell,selectaction,selectmode,ashowcell); +end; + +function tcustomdbwidgetgrid.isfirstrow: boolean; +begin + result:= fdatalink.isfirstrow; +end; + +function tcustomdbwidgetgrid.islastrow: boolean; +begin + result:= fdatalink.islastrow; +end; + +procedure tcustomdbwidgetgrid.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tcustomdbwidgetgrid.getdbindicatorcol: integer; +begin + result:= fixcols.dbindicatorcol; +end; + +function tcustomdbwidgetgrid.getfixcols: tdbwidgetfixcols; +begin + result:= tdbwidgetfixcols(inherited fixcols); +end; + +procedure tcustomdbwidgetgrid.setfixcols(const avalue: tdbwidgetfixcols); +begin + inherited +end; + +procedure tcustomdbwidgetgrid.setselected(const cell: gridcoordty; + const avalue: boolean); +begin + fdatalink.setselected(cell,avalue); +end; + +function tcustomdbwidgetgrid.updatesortcol(const avalue: integer): integer; +begin + result:= inherited updatesortcol(avalue); + if not fdatalink.updatesortfield(getfieldlink(avalue), + getsortdescend(avalue)) then begin + result:= -1; + end; +end; + +function tcustomdbwidgetgrid.getfieldlink( + const acol: integer): tcustomeditwidgetdatalink; +var + widget1: twidget; + intf1: idbeditfieldlink; +begin + result:= nil; + if (acol >= 0) and (acol < fdatacols.count) then begin + widget1:= twidgetcol(tdatacols1(fdatacols).fitems[acol]).editwidget; + if (widget1 <> nil) and + widget1.getcorbainterface(typeinfo(idbeditfieldlink),intf1) then begin + result:= intf1.getfieldlink; + end; + end; +end; + +function tcustomdbwidgetgrid.canautoappend: boolean; +begin + result:= inherited canautoappend and fdatalink.canautoinsert; +end; + +procedure tcustomdbwidgetgrid.setnavigator(const avalue: tdbnavigator); +var + int1: integer; + fieldlink1: tcustomeditwidgetdatalink; +begin + if not (csloading in componentstate) then begin + for int1:= 0 to fdatacols.count - 1 do begin + fieldlink1:= getfieldlink(int1); + if fieldlink1 <> nil then begin + fieldlink1.navigator:= avalue; + end; + end; + end; +end; + +function tcustomdbwidgetgrid.createdatacols: tdatacols; +begin + result:= tdbwidgetcols.create(self); +end; + +function tcustomdbwidgetgrid.caninsertrow: boolean; +begin + result:= inherited caninsertrow and fdatalink.caninsert; +end; + +function tcustomdbwidgetgrid.canappendrow: boolean; +begin + result:= inherited canappendrow and fdatalink.canappend; +end; + +function tcustomdbwidgetgrid.candeleterow: boolean; +begin + result:= inherited candeleterow and fdatalink.candelete; +end; + +procedure tcustomdbwidgetgrid.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= tdbwidgetcol.create(self,fdatacols); +end; + +function tcustomdbwidgetgrid.getdatacols: tdbwidgetcols; +begin + result:= tdbwidgetcols(fdatacols); +end; + +procedure tcustomdbwidgetgrid.setdatacols(const avalue: tdbwidgetcols); +begin + inherited; +end; + +function tcustomdbwidgetgrid.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_db]; +end; +{ +procedure tcustomdbwidgetgrid.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tcustomdbwidgetgrid.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tstringcoldatalink } + +procedure tstringcoldatalink.layoutchanged; +begin + inherited; + tcustomdbstringgrid(fintf.getwidget).checkautofields; +end; + +procedure tstringcoldatalink.updatedata; +var + grid1: tcustomdbstringgrid; +begin + grid1:= tcustomdbstringgrid(fintf.getwidget); + inc(grid1.fdatalink.fcanclosing); + try + inherited; + finally + dec(grid1.fdatalink.fcanclosing); + end; +end; + +{ tdbstringcol } + +constructor tdbstringcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fdatalink:= tstringcoldatalink.create(idbeditfieldlink(self)); + fdatalink.options:= tdbstringcols(aowner).foptionsdb; + fdatalink.navigator:= tcustomdbstringgrid(agrid).datalink.navigator; + inherited; + fdatalink.griddatasourcechanged; +end; + +destructor tdbstringcol.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbstringcol.getdatafield: string; +begin + result:= fdatalink.fieldname; +end; + +procedure tdbstringcol.setdatafield(const avalue: string); +begin + fdatalink.fieldname:= avalue; +end; + +procedure tdbstringcol.modified; +begin + inherited; + fdatalink.modified; +end; + +function tdbstringcol.getrowtext(const arow: integer): msestring; +var + po1: pmsestring; +begin + po1:= pmsestring( + tcustomdbstringgrid(fcellinfo.grid).fdatalink.getdisplaystringbuffer( + fdatalink.field,arow)); + if po1 = nil then begin + result:= fdatalink.nullsymbol; + end + else begin + result:= po1^; + end; +end; + +function tdbstringcol.getitems(aindex: integer): msestring; +begin +// if aindex = fgrid.row then begin +// result:= inherited getitems(aindex); +// end +// else begin + result:= getrowtext(aindex); +// end; +end; + +procedure tdbstringcol.setitems(aindex: integer; const Value: msestring); +begin + //dummy +end; + +function tdbstringcol.getgriddatasource: tdatasource; +begin + result:= tcustomdbstringgrid(fcellinfo.grid).datalink.datasource; +end; + +function tdbstringcol.getgridintf: iwidgetgrid; +begin + result:= iwidgetgrid(tcustomdbstringgrid(fcellinfo.grid)); +end; + +function tdbstringcol.getwidget: twidget; +begin + result:= fcellinfo.grid; +end; + +function tdbstringcol.seteditfocus: boolean; +begin + if not readonly then begin + grid.col:= index; + if not grid.focused then begin + if grid.canfocus then begin + grid.setfocus; + end; + end; + end; + result:= grid.entered and (grid.col = index); +end; + +function tdbstringcol.getedited: boolean; +begin + result:= fds_modified in fdatalink.fstate; +end; + +procedure tdbstringcol.initeditfocus; +begin + with tcustomstringgrid1(fcellinfo.grid) do begin + if (ffocusedcell.col = index) and (ffocusedcell.row >= 0) then begin + feditor.dofocus; + end; + end; +end; + +procedure tdbstringcol.updatereadonlystate; +begin + if (fcellinfo.grid.col = self.index) and (fcellinfo.grid.row >= 0) then begin + tcustomstringgrid1(fcellinfo.grid).feditor.updatecaret; + end; +end; + +function tdbstringcol.checkvalue(const quiet: boolean = false): boolean; +begin + result:= true; + tcustomdbstringgrid(fcellinfo.grid).checkcellvalue(result); +end; + +procedure tdbstringcol.valuetofield; +//var +// int1: integer; +// mstr1: msestring; +begin + with tcustomdbstringgrid(fcellinfo.grid) do begin + if col = index then begin + self.fdatalink.asnullmsestring:= feditor.text; + end; + end; +// int1:= tcustomdbstringgrid(fgrid).fdatalink.activerecord; +// if (int1 >= 0) and (int1 < fgrid.rowcount) then begin +// fdatalink.asnullmsestring:= items[int1]; +// end; +end; + +procedure tdbstringcol.fieldtovalue; +//var +// int1: integer; +begin + with tcustomdbstringgrid(fcellinfo.grid) do begin + if col = index then begin + feditor.text:= self.fdatalink.msedisplaytext('',true); + end + else begin + self.invalidatecell(fdatalink.activerecord); + end; + end; + datachange(fdatalink.activerecord); +// int1:= tcustomdbstringgrid(fgrid).fdatalink.activerecord; +// if (int1 >= 0) and (int1 < fgrid.rowcount) then begin +// items[int1]:= fdatalink.msedisplaytext('',true); +// end; +end; + +procedure tdbstringcol.setnullvalue; +//var +// int1: integer; +begin + with tcustomdbstringgrid(fcellinfo.grid) do begin + if col = index then begin + feditor.text:= self.fdatalink.nullsymbol; + end + else begin + self.invalidatecell(fdatalink.activerecord); + end; + end; +// int1:= tcustomdbstringgrid(fgrid).fdatalink.activerecord; +// if (int1 >= 0) and (int1 < fgrid.rowcount) then begin +// items[int1]:= fdatalink.nullsymbol; +// end; +end; + +procedure tdbstringcol.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= stringfields; +end; + +procedure tdbstringcol.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + setlength(fieldtypes,1); + fieldtypes[0]:= stringfields; +end; + +function tdbstringcol.getdataset(const aindex: integer): tdataset; +begin + result:= tcustomdbstringgrid(fcellinfo.grid).datalink.dataset; +end; + +function tdbstringcol.getoptionsdb: optionseditdbty; +begin + result:= fdatalink.options; +end; + +procedure tdbstringcol.setoptionsdb(const avalue: optionseditdbty); +begin + fdatalink.options:= avalue; +end; + +function tdbstringcol.getnullsymbol: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +procedure tdbstringcol.setnullsymbol(const avalue: msestring); +begin + fdatalink.nullsymbol:= avalue; +end; + +function tdbstringcol.createdatalist: tdatalist; +begin + result:= nil; +end; + +procedure tdbstringcol.setmaxlength(const avalue: integer); +begin + fmaxlength:= avalue; +end; + +function tdbstringcol.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +procedure tdbstringcol.setifiserverintf(const aintf: iifiserver); +begin + fifiserverintf:= aintf; +end; + +procedure tdbstringcol.docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); +var + state1: ifiwidgetstatesty; + int1: integer; +begin + int1:= tcustomgrid1(fcellinfo.grid).ffocuscount; + inherited; + if int1 = tcustomgrid1(fcellinfo.grid).ffocuscount then begin + state1:= []; + if enter then begin + include(state1,iws_focused); + end; + if visible then begin + include(state1,iws_visible); + end; + if fcellinfo.grid.active then begin + include(state1,iws_active); + end; + fdatalink.statechanged(iificlient(self),state1); + end; +end; + +procedure tdbstringcol.dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); +var + info: gridrowinfoty; +begin + tcustomdbstringgrid(grid).fdatalink.begingridrow( + fcellinfo.cell.row,info); + try + inherited; + finally + tcustomdbstringgrid(grid).fdatalink.endgridrow(info); + end; +end; + +procedure tdbstringcol.doafterdrawcell(const acanvas: tcanvas); +var + info: gridrowinfoty; +begin + tcustomdbstringgrid(grid).fdatalink.begingridrow( + fcellinfo.cell.row,info); + try + inherited; + finally + tcustomdbstringgrid(grid).fdatalink.endgridrow(info); + end; +end; + +function tdbstringcol.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + if fifiserverintf <> nil then begin + fifiserverintf.updateoptionsedit(result); + end; +end; + +function tdbstringcol.getdefaultifilink: iificlient; +begin + result:= iificlient(self); +end; + +function tdbstringcol.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +function tdbstringcol.getifidatatype(): listdatatypety; +begin + result:= dl_msestring; +end; + +procedure tdbstringcol.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +function tdbstringcol.getgriddata: tdatalist; +begin + result:= nil; +end; + +function tdbstringcol.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure tdbstringcol.getifivalue(var avalue); +begin + //dummy +end; + +procedure tdbstringcol.setifivalue(const avalue); +begin + //dummy +end; + +{ +procedure tdbstringcol.docellevent(var info: celleventinfoty); +begin + with info do begin + if cellbefore.col <> newcell.col then begin + if (info.eventkind = cek_enter) and (newcell.col = index) then begin + fdatalink.doenter(self); + end + else begin + if (info.eventkind = cek_exit) and (cellbefore.col = index) then begin + fdatalink.doexit(self); + end; + end; + end; + end; + inherited; +end; +} +{ tdropdowndbstringcol } + +{ tdbstringcols } + +class function tdbstringcols.getitemclasstype: persistentclassty; +begin + result:= tdbstringcol; +end; + +function tdbstringcols.getcols(const index: integer): tdbstringcol; +begin + result:= tdbstringcol(items[index]); +end; + +function tdbstringcols.getcolclass: stringcolclassty; +begin + result:= tdbstringcol; +end; + +procedure tdbstringcols.datasourcechanged; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + cols[int1].fdatalink.griddatasourcechanged; + end; +end; + +procedure tdbstringcols.setoptionsdb(const avalue: optionseditdbty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}word{$endif}; +begin + if foptionsdb <> avalue then begin + mask:= {$ifdef FPC}longword{$else}word{$endif}(avalue) xor + {$ifdef FPC}longword{$else}word{$endif}(foptionsdb); + foptionsdb := avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tdbstringcol(items[int1]).optionsdb:= optionseditdbty( + replacebits({$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(tdbstringcol(items[int1]).optionsdb), + mask)); + end; + end; + end; +end; + +{ tdbstringindicatorcol } + +constructor tdbstringindicatorcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fcolorindicator:= cl_glyph; + inherited; + options:= defaultindicatorcoloptions; + width:= 15; +end; + +procedure tdbstringindicatorcol.drawcell(const canvas: tcanvas); +begin + with cellinfoty(canvas.drawinfopo^),tdbstringfixcols(prop) do begin + if fdatalink.active and (cell.row = fdatalink.activerecord) then begin + include(drawstate,cds_notext); + inherited; + drawindicatorcell(canvas,fdatalink,fcolorindicator); + end + else begin + inherited; + end; + end; +end; + +procedure tdbstringindicatorcol.setcolorindicator(const avalue: colorty); +begin + if fcolorindicator <> avalue then begin + fcolorindicator:= avalue; + changed; + end; +end; + +{ tdbstringfixcols } + +constructor tdbstringfixcols.create(const aowner: tcustomgrid; + const adatalink: tgriddatalink); +begin + fdatalink:= adatalink; + inherited create(aowner); +end; + +procedure tdbstringfixcols.createitem(const index: integer; var item: tpersistent); +begin + if index = fdbindicatorcol then begin + item:= tdbstringindicatorcol.create(fgrid,self); + end + else begin + inherited; + end; +end; + +procedure tdbstringfixcols.setcount1(acount: integer; doinit: boolean); +begin + if (acount <= 0) and not (csdestroying in fgrid.componentstate) then begin + acount:= 1; + end; + if fdbindicatorcol >= acount then begin + fdbindicatorcol:= acount - 1; + end; + inherited; +end; + +procedure tdbstringfixcols.setdbindicatorcol(const Value: integer); +var + int1,int2: integer; +begin + int1:= -1 - value; + if int1 < 0 then begin + int1:= 0; + end; + if int1 >= count then begin + int1:= count-1; + end; + int2:= fdbindicatorcol; + if int1 <> int2 then begin + move(int2,int1); + fdbindicatorcol := int1; + end; +end; + +function tdbstringfixcols.getdbindicatorcol: integer; +begin + result:= -1-fdbindicatorcol; +end; + +{ tstringgriddatalink } + +procedure tstringgriddatalink.activechanged; +begin + if active then begin + tcustomdbstringgrid(fgrid).checkautofields; + end; + inherited; +end; + +{ tcustomdbstringgrid } + +constructor tcustomdbstringgrid.create(aowner: tcomponent); +begin + ffieldnamedisplayfixrow:= -1; + fdatalink:= tstringgriddatalink.create(self,igriddatalink(self)); + inherited; + fzebra_step:= 0; + ffixcols.count:= 1; +end; + +destructor tcustomdbstringgrid.destroy; +begin + inherited; + fdatalink.free; +end; + +//iwidgetgrid (dummy) + +function tcustomdbstringgrid.getbrushorigin: pointty; +begin + result:= nullpoint; +end; + +function tcustomdbstringgrid.getcol: twidgetcol; +begin + result:= nil; +end; + +procedure tcustomdbstringgrid.getdata(var index: integer; var dest); +begin + //dummy +end; + +procedure tcustomdbstringgrid.setdata(var index: integer; const source; + const noinvalidate: boolean = false); +begin + //dummy +end; + +procedure tcustomdbstringgrid.datachange(const arow: integer); +begin + //dummy +end; + +function tcustomdbstringgrid.getrow: integer; +begin + result:= ffocusedcell.row; +end; + +procedure tcustomdbstringgrid.setrow(arow: integer); +begin + row:= arow; +end; + +procedure tcustomdbstringgrid.changed; +begin + //dummy +end; + +procedure tcustomdbstringgrid.edited(); +begin + //dummy +end; + +function tcustomdbstringgrid.empty(index: integer): boolean; +begin + result:= false; +end; + +procedure tcustomdbstringgrid.updateeditoptions(var aoptions: optionseditty; + const aoptions1: optionsedit1ty); +begin + //dummy +end; + +procedure tcustomdbstringgrid.showrect(const arect: rectty; + const aframe: tcustomframe); +begin + //dummy +end; + +procedure tcustomdbstringgrid.widgetpainted(const canvas: tcanvas); +begin + //dummy +end; + +function tcustomdbstringgrid.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= fnonullcheck = 0; +end; + +function tcustomdbstringgrid.nonullcheck: boolean; +begin + result:= fnonullcheck > 0; +end; + +procedure tcustomdbstringgrid.internalcreateframe; +begin + tdbgridframe.create(iscrollframe(self),self,iautoscrollframe(self)); +end; +{ +function tcustomdbstringgrid.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + if ffocusedcell.col >= 0 then begin + datacols[ffocusedcell.col].fdatalink.updateoptionsedit(result); + end; +end; +} +function tcustomdbstringgrid.createfixcols: tfixcols; +begin + result:= tdbstringfixcols.create(self,fdatalink); +end; + +function tcustomdbstringgrid.createdatacols: tdatacols; +begin + result:= tdbstringcols.create(self); +end; +{ +function tcustomdbstringgrid.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tcustomdbstringgrid.setdatasource(const Value: tdatasource); +begin + fdatalink.datasource:= value; + datacols.datasourcechanged; +end; +} +function tcustomdbstringgrid.getdatacols: tdbstringcols; +begin + result:= tdbstringcols(fdatacols); +end; + +procedure tcustomdbstringgrid.setdatacols(const avalue: tdbstringcols); +begin + fdatacols.assign(avalue); +end; + +procedure tcustomdbstringgrid.updatelayout; +begin + inherited; + fdatalink.updatelayout; +end; +{ +procedure tcustomdbstringgrid.initcellinfo(var info: cellinfoty); +begin + inherited; + info.griddatalink:= fdatalink; +end; +} +procedure tcustomdbstringgrid.docellevent(var info: celleventinfoty); +begin + inherited; + fdatalink.cellevent(info); +end; + +procedure tcustomdbstringgrid.scrollevent(sender: tcustomscrollbar; event: scrolleventty); +begin + if not fdatalink.scrollevent(sender,event) then begin + inherited; + end; +end; + +function tcustomdbstringgrid.getzebrastart: integer; +begin + result:= fdatalink.getzebrastart; +end; + +function tcustomdbstringgrid.getnumoffset: integer; +begin + result:= -fdatalink.fzebraoffset; +end; + +procedure tcustomdbstringgrid.checkcellvalue(var accept: boolean); +var + co1: tdbstringcol; +begin + inherited; + if accept and (ffocusedcell.col >= 0) then begin + co1:= datacols[ffocusedcell.col]; + with co1 do begin; + if (fds_modified in fdatalink.fstate) and self.fdatalink.active then begin +// fdatalink.datachanged; + fdatalink.valuechanged(iifidatalink(co1)); + end; + end; + end; +end; + +function tcustomdbstringgrid.canclose(const newfocus: twidget): boolean; +begin + result:= true; + checkcellvalue(result); + result:= result and fdatalink.canclose(newfocus); +end; + +procedure tcustomdbstringgrid.dopaint(const acanvas: tcanvas); +begin + inherited; + fdatalink.painted; +end; + +procedure tcustomdbstringgrid.dohide; +begin + fdatalink.painted; + inherited; +end; + +procedure tcustomdbstringgrid.pagedown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(rowcount-1); +end; + +procedure tcustomdbstringgrid.pageup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-rowcount+1); +end; + +procedure tcustomdbstringgrid.wheeldown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(wheelheight); +end; + +procedure tcustomdbstringgrid.wheelup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-wheelheight); +end; + +procedure tcustomdbstringgrid.rowdown( + const action: focuscellactionty = fca_focusin; const nowrap: boolean = false); +begin + fdatalink.rowdown; +end; + +procedure tcustomdbstringgrid.rowup( + const action: focuscellactionty = fca_focusin; const nowrap: boolean = false); +begin + fdatalink.MoveBy(-1); +end; + +procedure tcustomdbstringgrid.lastrow(const action: focuscellactionty = fca_focusin); +begin + fdatalink.lastrow; +end; + +procedure tcustomdbstringgrid.firstrow(const action: focuscellactionty = fca_focusin); +begin + fdatalink.firstrow; +end; + +procedure tcustomdbstringgrid.dodeleterow(const sender: tobject); +begin + fdatalink.dodeleterow; +end; + +procedure tcustomdbstringgrid.doinsertrow(const sender: tobject); +begin + fdatalink.doinsertrow; +end; + +procedure tcustomdbstringgrid.doappendrow(const sender: tobject); +begin + fdatalink.doappendrow; +end; + +procedure tcustomdbstringgrid.setoptions(const avalue: dbstringgridoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + checkautofields; + end; +end; + +procedure tcustomdbstringgrid.setfieldnamedisplayfixrow(const avalue: integer); +begin + if avalue <> ffieldnamedisplayfixrow then begin + ffieldnamedisplayfixrow:= avalue; + if ffieldnamedisplayfixrow > 0 then begin + ffieldnamedisplayfixrow:= 0; + end; + checkautofields; + end; +end; + +function tcustomdbstringgrid.getdatalink: tgriddatalink; +begin + result:= fdatalink; +end; + +procedure tcustomdbstringgrid.setoptionsgrid(const avalue: optionsgridty); +begin + inherited setoptionsgrid(fdatalink.updateoptionsgrid(avalue)); +end; + +procedure tcustomdbstringgrid.doasyncevent(var atag: integer); +var + int1,int2: integer; + field1: tfield; + charwi: integer; + focusedcellbefore: gridcoordty; +begin + if tag = 0 then begin + beginupdate; + try + focusedcellbefore:= focusedcell; + datacols.count:= 0; + charwi:= getcanvas.getstringwidth('o'); + if fdatalink.dataset <> nil then begin + for int1:= 0 to fdatalink.dataset.fields.count - 1 do begin + field1:= fdatalink.dataset.fields[int1]; + with field1 do begin + if (datatype in stringfields) and visible then begin + datacols.count:= datacols.count + 1; + with datacols[datacols.count-1] do begin + if readonly then begin + options:= options + [co_readonly]; + end; + datafield:= fieldname; + int2:= displaywidth; + if (int2 = 0) or (int2 > maxautodisplaywidth) then begin + int2:= maxautodisplaywidth; + end; + width:= charwi * int2; + textflags:= textflags - [tf_xcentered,tf_right]; + case alignment of + tacenter: begin + textflags:= textflags + [tf_xcentered]; + end; + tarightjustify: begin + textflags:= textflags + [tf_right]; + end; + end; + if (ffieldnamedisplayfixrow < 0) and + (-ffieldnamedisplayfixrow <= ffixrows.count) then begin + with ffixrows[ffieldnamedisplayfixrow] do begin + captions.count:= datacols.count; + captions[datacols.count-1].caption:= msestring(displaylabel); + end; + end; + end; + end; + end; + end; + end; + focuscell(focusedcellbefore); + finally + endupdate; + end; + end; +end; + +procedure tcustomdbstringgrid.checkautofields; +var + int1: integer; +begin + if dsgo_autofields in foptions then begin + for int1:= 0 to datacols.count - 1 do begin + datacols[int1].datafield:= ''; + end; + asyncevent(0); //datalinks can not be destroyed + end; +end; + +procedure tcustomdbstringgrid.setdatalink(const avalue: tstringgriddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tcustomdbstringgrid.loaded; +begin + inherited; + fdatalink.loaded; +end; + +procedure tcustomdbstringgrid.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +function tcustomdbstringgrid.cangridcopy: boolean; +begin + result:= fdatacols.hasselection; +end; + +function tcustomdbstringgrid.getgrid: tcustomwidgetgrid; +begin + result:= nil; +end; + +function tcustomdbstringgrid.getdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +function tcustomdbstringgrid.getrowdatapo: pointer; +begin + result:= nil; +end; +{$ifdef mse_with_ifi} +procedure tcustomdbstringgrid.updateifigriddata(const alist: tdatalist); +begin + //dummy +end; +{$endif} + +procedure tcustomdbstringgrid.beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); +begin + fdatalink.beforefocuscell(cell,selectaction); +end; + +{ replaced by oed_limitcharlen +procedure tcustomdbstringgrid.editnotification(var info: editnotificationinfoty); +var + int1: integer; +begin + inherited; + if isdatacell(ffocusedcell) and (info.action = ea_textedited) and + datacols[ffocusedcell.col].fdatalink.cuttext(feditor.text,int1) then begin + feditor.text:= copy(feditor.text,1,int1); + end; +end; +} +function tcustomdbstringgrid.focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; +begin + fdatalink.focuscell(cell); + result:= inherited focuscell(cell,selectaction,selectmode,ashowcell); +end; + +function tcustomdbstringgrid.getfixcols: tdbstringfixcols; +begin + result:= tdbstringfixcols(inherited fixcols); +end; + +procedure tcustomdbstringgrid.setfixcols(const avalue: tdbstringfixcols); +begin + inherited; +end; + +function tcustomdbstringgrid.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_db]; +end; + +function tcustomdbstringgrid.getdbindicatorcol: integer; +begin + result:= fixcols.dbindicatorcol; +end; + +procedure tcustomdbstringgrid.coloptionstoeditoptions(var dest: optionseditty; + var dest1: optionsedit1ty); +begin + //dummy +end; + +function tcustomdbstringgrid.isfirstrow: boolean; +begin + result:= fdatalink.isfirstrow; +end; + +function tcustomdbstringgrid.islastrow: boolean; +begin + result:= fdatalink.islastrow; +end; + +procedure tcustomdbstringgrid.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tcustomdbstringgrid.setselected(const cell: gridcoordty; + const avalue: boolean); +begin + fdatalink.setselected(cell,avalue); +end; + +procedure tcustomdbstringgrid.setupeditor(const acell: gridcoordty; + const focusin: boolean); +begin + if acell.col >= 0 then begin + with tdbstringcol(tdatacols1(fdatacols).fitems[acell.col]) do begin + if (fmaxlength = 0){or not (oed_limitcharlen in fdatalink.foptions)} then begin + feditor.maxlength:= -1; + end + else begin + feditor.maxlength:= fmaxlength; + end; + end; + end; + inherited; +end; + +function tcustomdbstringgrid.updatesortcol(const avalue: integer): integer; +begin + result:= inherited updatesortcol(avalue); + if not fdatalink.updatesortfield(getfieldlink(avalue),getsortdescend(avalue)) then begin + result:= -1; + end; +end; + +function tcustomdbstringgrid.getfieldlink(const acol: integer): tfielddatalink; +begin + if (acol < 0) or (acol >= fdatacols.count) then begin + result:= nil; + end + else begin + result:= tdbstringcol(tdbstringcols(fdatacols).fitems[acol]).fdatalink; + end; +end; + +function tcustomdbstringgrid.canautoappend: boolean; +begin + result:= inherited canautoappend and fdatalink.canautoinsert; +end; + +procedure tcustomdbstringgrid.setnavigator(const avalue: tdbnavigator); +var + int1: integer; +begin + for int1:= 0 to fdatacols.count - 1 do begin + tdbstringcol(tdbstringcols(fdatacols).fitems[int1]).fdatalink.navigator:= avalue; + end; +end; + +function tcustomdbstringgrid.caninsertrow: boolean; +begin + result:= inherited caninsertrow and fdatalink.caninsert; +end; + +function tcustomdbstringgrid.canappendrow: boolean; +begin + result:= inherited canappendrow and fdatalink.canappend; +end; + +function tcustomdbstringgrid.candeleterow: boolean; +begin + result:= inherited candeleterow and fdatalink.candelete; +end; +{ +procedure tcustomdbstringgrid.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tcustomdbstringgrid.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tlbdropdowncol } + +procedure tlbdropdowncol.setfieldno(const avalue: lookupbufferfieldnoty); +begin + if avalue <> ffieldno then begin + ffieldno:= avalue; + end; +end; + +function tlbdropdowncol.getlbdatakind(const apropname: string): lbdatakindty; +begin + result:= lbdk_text; +end; + +function tlbdropdowncol.getlookupbuffer: tcustomlookupbuffer; +begin + result:= tcustomlbdropdownlistcontroller(fowner).lookupbuffer; +end; + +{ tlbdropdowncols } + +function tlbdropdowncols.getitems(const index: integer): tlbdropdowncol; +begin + result:= tlbdropdowncol(inherited getitems(index)); +end; + +function tlbdropdowncols.getcolclass: dropdowncolclassty; +begin + result:= tlbdropdowncol; +end; + +{ texterndatadropdownlistcontroller } + +constructor texterndatadropdownlistcontroller.create(const intf: ilbdropdownlist); +begin + inherited create(intf); + options:= defaulteddropdownoptions; +end; + +procedure texterndatadropdownlistcontroller.valuecolchanged; +begin + //dummy +end; + +function texterndatadropdownlistcontroller.getbuttonframeclass: + dropdownbuttonframeclassty; +begin + result:= tdropdownmultibuttonframe; +end; + +function texterndatadropdownlistcontroller.getdropdowncolsclass: + dropdowncolsclassty; +begin + result:= tlbdropdowncols; +end; + + +procedure texterndatadropdownlistcontroller.dropdown; +begin + tdropdowncols1(fcols).fitemindex:= -1; + inherited; +end; + +{ tdbenumeditlb } + +function tdbenumeditlb.getdropdown: tlbdropdownlistcontroller; +begin + result:= tlbdropdownlistcontroller(fdropdown); +end; + +procedure tdbenumeditlb.setdropdown(const avalue: tlbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tdbenumeditlb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tlbdropdownlistcontroller.create(ilbdropdownlist(self)); +end; + +procedure tdbenumeditlb.recordselected(const arecordnum: integer; const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tlbdropdownlistcontroller(fdropdown) do begin + text:= flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum); + tdropdowncols1(fcols).fitemindex:= + flookupbuffer.integervaluephys(fkeyfieldno,arecordnum); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdbenumeditlb.internaldatatotext(const data): msestring; +var + int1,int2,int3,int4: integer; +begin + if @data = nil then begin + int1:= value; + end + else begin + int1:= integer(data); + end; + with tlbdropdownlistcontroller(fdropdown) do begin + int3:= cols[valuecol].ffieldno; + int4:= fkeyfieldno; + end; + with dropdown do begin + if (flookupbuffer <> nil) and (int3 < flookupbuffer.fieldcounttext) and + (int4 < flookupbuffer.fieldcountinteger) and + flookupbuffer.find(int4,int1,int2) then begin + result:= flookupbuffer.textvaluephys(int3, + flookupbuffer.integerindex(int4,int2)); + end + else begin + result:= ''; + end; + end; +end; + +function tdbenumeditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +{ tenumeditlb } + +function tenumeditlb.getdropdown: tlbdropdownlistcontroller; +begin + result:= tlbdropdownlistcontroller(fdropdown); +end; + +procedure tenumeditlb.setdropdown(const avalue: tlbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tenumeditlb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tlbdropdownlistcontroller.create(ilbdropdownlist(self)); +end; + +procedure tenumeditlb.recordselected(const arecordnum: integer; const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tlbdropdownlistcontroller(fdropdown) do begin + text:= flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum); + tdropdowncols1(fcols).fitemindex:= + flookupbuffer.integervaluephys(fkeyfieldno,arecordnum); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin //empty row selected + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tenumeditlb.internaldatatotext(const data): msestring; +var + int1,int2,int3,int4: integer; +begin + if @data = nil then begin + int1:= value; + end + else begin + int1:= integer(data); + end; + with tlbdropdownlistcontroller(fdropdown) do begin + int3:= cols[valuecol].ffieldno; + int4:= fkeyfieldno; + end; + with dropdown do begin + if (flookupbuffer <> nil) and (int3 < flookupbuffer.fieldcounttext) and + (int4 < flookupbuffer.fieldcountinteger) and + flookupbuffer.find(int4,int1,int2) then begin + result:= flookupbuffer.textvaluephys(int3, + flookupbuffer.integerindex(int4,int2)); + end + else begin + result:= ''; + end; + end; +end; + +function tenumeditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +{$ifdef mse_with_ifi} +function tenumeditlb.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure tenumeditlb.setifilink1(const avalue: tifiintegerlinkcomp); +begin + setifilink0(avalue); +end; +{$endif mse_with_ifi} + +{ tcustomenum64edit } + +constructor tcustomenum64edit.create(aowner: tcomponent); +begin + fvalue1:= -1; + fvaluedefault1:= -1; + inherited; +end; + +function tcustomenum64edit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridenum64datalist.create(sender); +end; + +function tcustomenum64edit.getdatalistclass: datalistclassty; +begin + result:= tgridenum64datalist; +end; + +function tcustomenum64edit.getgridvalue(const index: integer): int64; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomenum64edit.setgridvalue(const index: integer; aValue: int64); +begin + internalsetgridvalue(index,avalue); +end; + +function tcustomenum64edit.getgridvalues: int64arty; +begin + result:= tint64datalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tcustomenum64edit.setgridvalues(const avalue: int64arty); +begin + tint64datalist(fgridintf.getcol.datalist).asarray:= avalue; +end; + +procedure tcustomenum64edit.setvalue(const avalue: int64); +begin +{$warnings off} + tdropdowncols1(tlbdropdownlistcontroller(fdropdown).cols).fkeyvalue64:= + avalue; +{$warnings on} + fvalue1:= avalue; + valuechanged; +end; + +function tcustomenum64edit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault1; +end; + +procedure tcustomenum64edit.texttovalue(var accept: boolean; const quiet: boolean); +var + lint1: int64; +begin + if (tdropdownlistcontroller(fdropdown).itemindex < 0) and + (trim(text) = '') then begin + lint1:= valuedefault; + end + else begin +{$warnings off} + lint1:= tdropdowncols1(tlbdropdownlistcontroller(fdropdown).cols).fkeyvalue64; +{$warnings on} + end; + //no checktext call + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetvalue1)) then begin + fonsetvalue1(self,lint1,accept); + end; +{$ifdef mse_with_ifi} + ifisetvalue(lint1,accept); +{$endif} + end; + if accept then begin + value:= lint1; + end; + end; +end; + +procedure tcustomenum64edit.texttodata(const atext: msestring; var data); +begin + //not supported +end; + +procedure tcustomenum64edit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue1); +end; + +procedure tcustomenum64edit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue1); + valuetotext; +end; + +procedure tcustomenum64edit.readstatvalue(const reader: tstatreader); +begin + if fgridintf <> nil then begin + fgridintf.getcol.dostatread(reader); + end + else begin + value:= reader.readint64(valuevarname,value); + end; +end; + +procedure tcustomenum64edit.writestatvalue(const writer: tstatwriter); +begin + writer.writeint64(valuevarname,value); +end; + +{$ifdef mse_with_ifi} +function tcustomenum64edit.getifilink: tifiint64linkcomp; +begin + result:= tifiint64linkcomp(fifilink); +end; + +procedure tcustomenum64edit.setifilink1(const avalue: tifiint64linkcomp); +begin + setifilink0(avalue); +end; + +function tcustomenum64edit.getifidatalinkintf: iifidatalink; +begin + result:= iifidatalink(self); +end; + +function tcustomenum64edit.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +{$endif mse_with_ifi} + +procedure tcustomenum64edit.setnullvalue; +begin + dropdown.itemindex:= -1; + nullvalueset(); +end; + { tcustomenum64editlb } + +function tcustomenum64editlb.getdropdown: tlbdropdownlistcontroller; +begin + result:= tlbdropdownlistcontroller(fdropdown); +end; + +procedure tcustomenum64editlb.setdropdown(const avalue: tlbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tcustomenum64editlb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tlbdropdownlistcontroller.create(ilbdropdownlist(self)); +end; + +procedure tcustomenum64editlb.recordselected(const arecordnum: integer; const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tlbdropdownlistcontroller(fdropdown) do begin + text:= flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum); + tdropdowncols1(fcols).fkeyvalue64:= + flookupbuffer.int64valuephys(fkeyfieldno,arecordnum); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin //empty row selected + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tcustomenum64editlb.internaldatatotext(const data): msestring; +var + lint1: int64; + int2,int3,int4: integer; +begin + if @data = nil then begin + lint1:= value; + end + else begin + lint1:= int64(data); + end; + with tlbdropdownlistcontroller(fdropdown) do begin + int3:= cols[valuecol].ffieldno; + int4:= fkeyfieldno; + if (flookupbuffer <> nil) and (int3 < flookupbuffer.fieldcounttext) and + (int4 < flookupbuffer.fieldcountint64) and + flookupbuffer.find(int4,lint1,int2) then begin + result:= flookupbuffer.textvaluephys(int3, + flookupbuffer.int64index(int4,int2)); + end + else begin + result:= ''; + end; + end; +end; + +function tcustomenum64editlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_int64; +end; + + { tcustomenum64editdb } + +function tcustomenum64editdb.getdropdown: tdbdropdownlistcontroller; +begin + result:= tdbdropdownlistcontroller(fdropdown); +end; + +procedure tcustomenum64editdb.setdropdown(const avalue: tdbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tcustomenum64editdb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdbdropdownlistcontroller.create(idbdropdownlist(self),false); +end; + +procedure tcustomenum64editdb.recordselected( + const arecordnum: integer; const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdbdropdownlistcontroller(fdropdown) do begin + text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); + tdropdowncols1(fcols).fkeyvalue64:= getaslargeint(fdatalink.valuefield) + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + text:= ''; + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tcustomenum64editdb.internaldatatotext(const data): msestring; +var + lint1: int64; +begin + if @data = nil then begin + lint1:= value; + end + else begin + lint1:= int64(data); + end; + result:= tdbdropdownlistcontroller(fdropdown).fdatalink.getlookuptext(lint1); +end; + +{ tdbenum64editlb } + +constructor tdbenum64editlb.create(aowner: tcomponent); +begin + fdatalink:= tlookupeditdatalink.create(self,ldt_int64,idbeditfieldlink(self)); + inherited; +end; + +destructor tdbenum64editlb.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbenum64editlb.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbenum64editlb.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbenum64editlb.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +// frame.readonly:= oe_readonly in result; +end; +} +procedure tdbenum64editlb.valuetofield; +begin + if value = -1 then begin + fdatalink.field.clear; + if fdatalink.fieldtext <> nil then begin + fdatalink.fieldtext.clear; + end; + end + else begin + fdatalink.field.aslargeint:= value; + setasmsestring(text,fdatalink.fieldtext,fdatalink.utf8) + end; +end; + +procedure tdbenum64editlb.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= fvaluedefault1; + end + else begin + value:= fdatalink.field.aslargeint; + end; +end; + +function tdbenum64editlb.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink). + getint64buffer(fdatalink.field,arow); + if result = nil then begin + result:= @fvaluedefault; + end; + end + else begin + result:= @fvaluedefault; + end; +end; + +function tdbenum64editlb.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbenum64editlb.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbenum64editlb.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbenum64editlb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +procedure tdbenum64editlb.setdatalink(const avalue: tlookupeditdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbenum64editlb.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbenum64editlb.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbenum64editlb.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbenum64editlb.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbenum64editlb.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbenum64editlb.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbenum64editlb.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbenum64editdb } + +constructor tdbenum64editdb.create(aowner: tcomponent); +begin + fdatalink:= tlookupeditdatalink.create(self,ldt_int64,idbeditfieldlink(self)); + inherited; +end; + +destructor tdbenum64editdb.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbenum64editdb.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbenum64editdb.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbenum64editdb.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +// frame.readonly:= oe_readonly in result; +end; +} +procedure tdbenum64editdb.valuetofield; +begin + if value = -1 then begin + fdatalink.field.clear; + if fdatalink.fieldtext <> nil then begin + fdatalink.fieldtext.clear; + end; + end + else begin + fdatalink.field.aslargeint:= value; + setasmsestring(text,fdatalink.fieldtext,fdatalink.utf8) + end; +end; + +procedure tdbenum64editdb.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= fvaluedefault1; + end + else begin + value:= fdatalink.field.aslargeint; + end; +end; + +function tdbenum64editdb.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink). + getint64buffer(fdatalink.field,arow); + if result = nil then begin + result:= @fvaluedefault; + end; + end + else begin + result:= @fvaluedefault; + end; +end; + +function tdbenum64editdb.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbenum64editdb.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbenum64editdb.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbenum64editdb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +procedure tdbenum64editdb.setdatalink(const avalue: tlookupeditdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbenum64editdb.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbenum64editdb.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbenum64editdb.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbenum64editdb.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbenum64editdb.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbenum64editdb.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbenum64editdb.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbkeystringeditlb } + +function tdbkeystringeditlb.getdropdown: tlbdropdownlistcontroller; +begin + result:= tlbdropdownlistcontroller(fdropdown); +end; + +procedure tdbkeystringeditlb.setdropdown(const avalue: tlbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tdbkeystringeditlb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tlbdropdownlistcontroller.create(ilbdropdownlist(self)); +end; + +procedure tdbkeystringeditlb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tlbdropdownlistcontroller(fdropdown) do begin + text:= flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum); + tdropdowncols1(fcols).fitemindex:= arecordnum; + tdropdowncols1(fcols).fkeyvalue:= + flookupbuffer.textvaluephys(fkeyfieldno,arecordnum); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdbkeystringeditlb.internaldatatotext(const data): msestring; +var + mstr1: msestring; + int2,int3,int4: integer; +begin + if @data = nil then begin + mstr1:= value; + end + else begin + mstr1:= msestring(data); + end; + with tlbdropdownlistcontroller(fdropdown) do begin + int3:= cols[valuecol].ffieldno; + int4:= fkeyfieldno; + end; + with dropdown do begin + if (flookupbuffer <> nil) and (int3 < flookupbuffer.fieldcounttext) and + (int4 < flookupbuffer.fieldcounttext) and + flookupbuffer.find(int4,mstr1,int2,false) then begin + result:= flookupbuffer.textvaluephys(int3, + flookupbuffer.textindex(int4,int2,false)); + end + else begin + result:= ''; + end; + end; +end; + +function tdbkeystringeditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +{ tkeystringeditlb } + +function tkeystringeditlb.getdropdown: tlbdropdownlistcontroller; +begin + result:= tlbdropdownlistcontroller(fdropdown); +end; + +procedure tkeystringeditlb.setdropdown(const avalue: tlbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tkeystringeditlb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tlbdropdownlistcontroller.create(ilbdropdownlist(self)); +end; + +procedure tkeystringeditlb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tlbdropdownlistcontroller(fdropdown) do begin + text:= flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum); + tdropdowncols1(fcols).fitemindex:= arecordnum; + tdropdowncols1(fcols).fkeyvalue:= + flookupbuffer.textvaluephys(fkeyfieldno,arecordnum); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tkeystringeditlb.internaldatatotext(const data): msestring; +var + mstr1: msestring; + int2,int3,int4: integer; +begin + if @data = nil then begin + mstr1:= value; + end + else begin + mstr1:= msestring(data); + end; + with tlbdropdownlistcontroller(fdropdown) do begin + int3:= cols[valuecol].ffieldno; + int4:= fkeyfieldno; + end; + with dropdown do begin + if (flookupbuffer <> nil) and (int3 < flookupbuffer.fieldcounttext) and + (int4 < flookupbuffer.fieldcounttext) and + flookupbuffer.find(int4,mstr1,int2,false) then begin + result:= flookupbuffer.textvaluephys(int3, + flookupbuffer.textindex(int4,int2,false)); + end + else begin + result:= ''; + end; + end; +end; + +function tkeystringeditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +{ tcopydropdownlist } + +function tcopydropdownlist.locate(const filter: msestring): boolean; +var + int1: integer; + po1: pointer; + co1: gridcoordty; +begin + po1:= cols[0].datalist.datapo; //workaround internal error 200304235 in 2.0.2 + result:= findarrayvalue(filter,po1,sizeof(msestring),rowcount, + @compareimsestring,int1); + if not result then begin + result:= (int1 < rowcount) and (msecomparetextlen(filter,cols[0][int1]) = 0); + end; + if not result then begin + inc(int1); + result:= (int1 < rowcount) and (msecomparetextlen(filter,cols[0][int1]) = 0); + end; + if result then begin + co1:= makegridcoord(ffocusedcell.col,int1); + showcell(co1,cep_top); + focuscell(makegridcoord(ffocusedcell.col,int1)); + end + else begin + focuscell(makegridcoord(ffocusedcell.col,-1)); + end; +end; + +{ tlbdropdownstringcol } + +function tlbdropdownstringcol.getrowtext(const arow: integer): msestring; +var + int1: integer; +begin + int1:= tlbdropdownlist(fcellinfo.grid).getrecno(arow); + if int1 >= 0 then begin + if funsorted then begin + result:= flookupbuffer.textvaluephys(ffieldno,int1); + end + else begin + result:= flookupbuffer.textvaluephys(ffieldno, + flookupbuffer.textindex(fsortfieldno,int1,true)); + end; + end + else begin + result:= ''; + end; +end; + +{ texterndatadropdownlist } + +constructor texterndatadropdownlist.create( + const acontroller: texterndatadropdownlistcontroller; acols: tdropdowncols); +var + int1: integer; +begin + inherited create(acontroller,acols,nil); + include(fstate,gs_isdb); + int1:= acontroller.dropdownrowcount; + if (edds_filtered in feddstate) then begin + resyncfilter; + end + else begin + if int1 > acontroller.getremoterowcount then begin + int1:= acontroller.getremoterowcount; + frame.sbvert.options:= frame.sbvert.options-[sbo_show]; + end; + rowcount:= int1; + end; + if rowcount > 0 then begin + row:= 0; + end; + with frame.sbvert do begin + buttonlength:= 0; + if acontroller.getremoterowcount > 0 then begin + pagesize:= rowcount / acontroller.getremoterowcount; + end; + end; +end; + +procedure texterndatadropdownlist.resyncfilter; +var + int1,int2,int3: integer; +begin + int1:= fcontroller.dropdownrowcount; + rowcount:= int1; //init frecnums; + int3:= -1; + for int2:= 0 to rowcount - 1 do begin + findnext(int3); + if int3 < 0 then begin + int1:= int2; + break; + end; + frecnums[int2]:= int3; + end; + ffirstrecord:= frecnums[0]; + if int3 < 0 then begin + frame.sbvert.options:= frame.sbvert.options-[sbo_show]; + rowcount:= int1; + end + else begin + frame.sbvert.options:= frame.sbvert.options+[sbo_show]; + end; +end; + +procedure texterndatadropdownlist.filterchanged; +begin + if (edds_filtered in feddstate) then begin + resyncfilter; + end; +end; + +procedure texterndatadropdownlist.dbscrolled(distance: integer); +var + rect1: rectty; +// int1: integer; +begin + if abs(distance) >= rowcount then begin + invalidate; + end + else begin + if distance <> 0 then begin + rect1:= fdatarecty; + rect1.cy:= rowcount*ystep; + scrollrect(makepoint(0,-distance*ystep),rect1,true); + end; + end; +end; + +procedure texterndatadropdownlist.moveby(distance: integer); +var + int1,int2,int3,int4,int5,int6: integer; + rowbefore: integer; + rea1: real; + ar1: integerarty; +begin + if rowcount = 0 then begin + exit; + end; + rowbefore:= row; + int1:= row + distance; + if int1 < 0 then begin + if (edds_filtered in feddstate) then begin + setlength(ar1,rowcount); + int4:= 0; + for int3:= -int1-1 downto 0 do begin + int2:= ffirstrecord; + findprev(ffirstrecord); + if ffirstrecord < 0 then begin + ffirstrecord:= int2; + break; + end; + if int3 <= high(ar1) then begin + ar1[int3]:= ffirstrecord; + end; + dec(int4); + end; + if int4 <> int1 then begin + include(feddstate,edds_bof); + int2:= ffirstrecord; + frecnums[0]:= int2; + for int3:= 1 to rowhigh do begin + findnext(int2); + if int2 < 0 then begin + for int6:= int3 to high(frecnums) do begin + frecnums[int6]:= -1; + end; + break; + end; + frecnums[int3]:= int2; + end; + end + else begin + exclude(feddstate,edds_bof); + if int4 <= - rowcount then begin + frecnums:= ar1; + end + else begin + move(frecnums[0],frecnums[-int4],(length(frecnums)+int4)*sizeof(integer)); + move(ar1[int1-int4],frecnums[0],-int4*sizeof(integer)); + end; + end; + int1:= int4; + end + else begin + ffirstrecord:= ffirstrecord + int1; + if ffirstrecord < 0 then begin + int1:= int1 - ffirstrecord; + ffirstrecord:= 0; + end; + end; + dbscrolled(int1); + dec(rowbefore,int1); + row:= 0; + end + else begin + if int1 >= rowcount then begin + int1:= int1 - rowcount + 1; + if (edds_filtered in feddstate) then begin + setlength(ar1,rowcount); + int5:= frecnums[rowcount-1]; + int4:= 0; + for int3:= 0 to int1-1 do begin + int2:= int5; + findnext(int5); + if int5 < 0 then begin + int5:= int2; + break; + end; + inc(int4); + int6:= int1 - int4; + if int6 <= high(ar1) then begin + ar1[high(ar1)-int6]:= int5; + end; + end; + if int4 <> int1 then begin + include(feddstate,edds_eof); + frecnums[rowhigh]:= int5; + for int3:= rowhigh - 1 downto 0 do begin + findprev(int5); + if int5 < 0 then begin + for int6:= int3 downto 0 do begin + frecnums[int6]:= -1; + end; + break; + end; + frecnums[int3]:= int5; + end; + end + else begin + exclude(feddstate,edds_eof); + if int4 >= rowcount then begin + frecnums:= ar1; + end + else begin + move(frecnums[int4],frecnums[0],(rowcount-int4)*sizeof(integer)); + move(ar1[rowcount-int1],frecnums[rowcount-int4],int4*sizeof(integer)); + end; + end; + ffirstrecord:= frecnums[0]; + int1:= int4; + end + else begin + ffirstrecord:= ffirstrecord + int1; + int2:= ffirstrecord + rowcount - + texterndatadropdownlistcontroller(fcontroller).getremoterowcount; + if int2 > 0 then begin + int1:= int1 - int2; + ffirstrecord:= ffirstrecord - int2; + end; + end; + dbscrolled(int1); + dec(rowbefore,int1); + row:= rowcount - 1; + end + else begin + row:= row + distance; + end; + end; + invalidaterow(rowbefore); + invalidaterow(row); + if (col >= 0) and (row >= 0) then begin + feditor.text:= tlbdropdownstringcol(fdatacols[col]).getrowtext(row); + end + else begin + feditor.text:= ''; + end; + int1:= texterndatadropdownlistcontroller(fcontroller).getremoterowcount - 1; + if int1 <= 0 then begin + rea1:= 0.5; + end + else begin + if (edds_filtered in feddstate) then begin + if edds_eof in feddstate then begin + rea1:= 1; + end + else begin + if edds_bof in feddstate then begin + rea1:= 0; + end + else begin + rea1:= 0.5; + end; + end; + end + else begin + rea1:= activerecord / int1; + end; + end; + frame.sbvert.value:= rea1; +end; + +procedure texterndatadropdownlist.pagedown(const action: focuscellactionty = fca_focusin); +begin + moveby(rowcount-1); +end; + +procedure texterndatadropdownlist.pageup(const action: focuscellactionty = fca_focusin); +begin + moveby(-rowcount+1); +end; + +procedure texterndatadropdownlist.wheeldown(const action: focuscellactionty = fca_focusin); +begin + MoveBy(wheelheight); +end; + +procedure texterndatadropdownlist.wheelup(const action: focuscellactionty = fca_focusin); +begin + MoveBy(-wheelheight); +end; + +procedure texterndatadropdownlist.rowdown( + const action: focuscellactionty = fca_focusin; const nowrap: boolean = false); +begin + moveby(1); +end; + +procedure texterndatadropdownlist.rowup( + const action: focuscellactionty = fca_focusin; const nowrap: boolean = false); +begin + moveby(-1); +end; + +function texterndatadropdownlist.getactiverecord: integer; +begin + if (edds_filtered in feddstate) then begin + result:= frecnums[row]; + end + else begin + result:= ffirstrecord + row; + end; +end; + +procedure texterndatadropdownlist.setactiverecord(const avalue: integer); +var + int1,int2,int3: integer; +begin + if rowcount > 0 then begin + if (edds_filtered in feddstate) then begin + if ffirstrecord >= 0 then begin + for int1:= 0 to high(frecnums) do begin + if frecnums[int1] = avalue then begin + if int1 > 0 then begin + exclude(feddstate,edds_bof); + end; + if int1 < rowhigh then begin + exclude(feddstate,edds_eof); + end; + moveby(int1-row); + exit; + end; + end; + end; + ffirstrecord:= avalue; + int2:= avalue; + frecnums[0]:= int2; + for int1:= 1 to rowhigh do begin + findnext(int2); + if int2 < 0 then begin + move(frecnums[0],frecnums[rowcount-int1],int1*sizeof(integer)); + int2:= avalue; + for int3:= rowhigh - int1 downto 0 do begin + findprev(int2); + frecnums[int3]:= int2; + end; + ffirstrecord:= frecnums[0]; + invalidate; + moveby((rowcount - int1)-row); + exit; + end; + frecnums[int1]:= int2 + end; + invalidate; + moveby(-row); + end + else begin + if ffirstrecord < 0 then begin + ffirstrecord:= avalue; + int1:= texterndatadropdownlistcontroller(fcontroller).getremoterowcount; + if ffirstrecord + rowcount > int1 then begin + ffirstrecord:= int1 - rowcount; + end; + moveby(avalue-ffirstrecord-row); + invalidate; + end + else begin + moveby(avalue-activerecord); + end; + end; + end; +end; + +procedure texterndatadropdownlist.internalcreateframe; +begin + tdbgridframe.create(iscrollframe(self),self,iautoscrollframe(self)); +end; + +procedure texterndatadropdownlist.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= tlbdropdownstringcol.create(self,fdatacols); +end; + +procedure texterndatadropdownlist.docellevent(var info: celleventinfoty); +begin + inherited; + with info do begin + if (eventkind = cek_enter) and active then begin + if (edds_filtered in feddstate) then begin + activerecord:= frecnums[newcell.row]; + end + else begin + activerecord:= ffirstrecord + newcell.row; + end; + end; + end; +end; + +procedure texterndatadropdownlist.scrollevent(sender: tcustomscrollbar; event: scrolleventty); +var + int1: integer; + bo1: boolean; +begin + bo1:= true; + if sender.tag = 1 then begin + case event of + sbe_stepup: rowdown(fca_focusin); + sbe_stepdown: rowup(fca_focusin); + sbe_pageup: pagedown(fca_focusin); + sbe_pagedown: pageup(fca_focusin); + sbe_wheelup: wheeldown(fca_focusin); + sbe_wheeldown: wheelup(fca_focusin); + sbe_valuechanged: begin end; + sbe_thumbtrack,sbe_thumbposition: begin + int1:= texterndatadropdownlistcontroller(fcontroller).getremoterowcount - 1; + if int1 >= 0 then begin + if (edds_filtered in feddstate) then begin + if event <> sbe_thumbtrack then begin + if sender.value <= 0 then begin + moveby(minint); + end + else begin + if sender. value >= 1 then begin + moveby(maxint); + end + else begin + if sender.value < 0.5 then begin + moveby(-rowhigh); + end + else begin + moveby(rowhigh); + end; + end; + end; + end; + end + else begin + activerecord:= round(int1 * sender.value); + end; + end + else begin + sender.value:= 0.5; + end; + end; + else begin + bo1:= false; + end; + end; + end + else begin + bo1:= false; + end; + if not bo1 then begin + inherited; + end; +end; + +procedure texterndatadropdownlist.dorowcountchanged(const countbefore: integer; + const newcount: integer); +var + int1: integer; +begin + inherited; + setlength(frecnums,newcount); + for int1:= countbefore to newcount - 1 do begin + frecnums[int1]:= -1; + end; +end; + +procedure texterndatadropdownlist.findprev(var recno: integer); +var + bo1: boolean; +begin + with texterndatadropdownlistcontroller(fcontroller) do begin + repeat + dec(recno); + if recno < 0 then begin + recno:= -1; + break; + end; + bo1:= true; + dofilter(recno,bo1); + until bo1; + end; +end; + +function texterndatadropdownlist.getrecno(const aindex: integer): integer; +//var +// int1{,int2}: integer; +begin + if (edds_filtered in feddstate) then begin + result:= frecnums[aindex]; + end + else begin + result:= ffirstrecord + aindex; + end; +end; + +procedure texterndatadropdownlist.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if shiftstate = [ss_ctrl] then begin + include(info.eventstate,es_processed); + case key of + key_pageup: begin + moveby(-bigint); + end; + key_pagedown: begin + moveby(bigint); + end + else begin + exclude(eventstate,es_processed); + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +{ tlbdropdownlist } + +constructor tlbdropdownlist.create( + const acontroller: tcustomlbdropdownlistcontroller; acols: tdropdowncols); +begin + if assigned(acontroller.fonfilter) then begin + include(feddstate,edds_filtered); + end; + inherited create(acontroller,acols); +end; + +procedure tlbdropdownlist.initcols(const acols: tdropdowncols); +var + int1: integer; + lookupbuffer1: tcustomlookupbuffer; +begin + inherited; + with tcustomlbdropdownlistcontroller(fcontroller) do begin + lookupbuffer1:= lookupbuffer; + fsortfieldno:= cols[0].ffieldno; + end; + for int1:= 0 to fdatacols.count - 1 do begin + with tlbdropdownstringcol(fdatacols[int1]) do begin + flookupbuffer:= lookupbuffer1; + fsortfieldno:= tcustomlbdropdownlistcontroller(fcontroller).fsortfieldno; + ffieldno:= tlbdropdowncol(acols[int1]).ffieldno; + funsorted:= olb_unsorted in + tlbdropdownlistcontroller(fcontroller).foptionslb; + end; + end; +end; + +function tlbdropdownlist.locate(const filter: msestring): boolean; +var + int1: integer; +begin + int1:= 0; + result:= false; + if (datacols.count > 0) then begin + with tlbdropdownstringcol(datacols[0]) do begin + result:= flookupbuffer.find(ffieldno,filter,int1,true, + tcustomlbdropdownlistcontroller(fcontroller).fonfilter); + if not result then begin + result:= (int1 < flookupbuffer.count) and + (msepartialcomparetext(filter, + flookupbuffer.textvaluelog(ffieldno,int1,true)) = 0); + end; + if funsorted then begin + int1:= flookupbuffer.textindex(ffieldno,int1,true); //get phys recno + end; + end; + end; + if not result then begin + focuscell(makegridcoord(ffocusedcell.col,-1)); + end + else begin + ffirstrecord:= -1; + activerecord:= int1; + end; +end; + +procedure tlbdropdownlist.findnext(var recno: integer); +var + bo1: boolean; +begin + with tcustomlbdropdownlistcontroller(fcontroller) do begin + repeat + inc(recno); + if recno >= flookupbuffer.count then begin + recno:= -1; + break; + end; + bo1:= true; + dofilter(recno,bo1); + until bo1; + end; +end; + +{ tcustomlbdropdownlistcontroller } + +function tcustomlbdropdownlistcontroller.getcols: tlbdropdowncols; +begin + result:= tlbdropdowncols(fcols); +end; + +procedure tcustomlbdropdownlistcontroller.setcols(const avalue: tlbdropdowncols); +begin + fcols.assign(avalue); +end; + +procedure tcustomlbdropdownlistcontroller.dofilter(var recno: integer; + var accept: boolean); +begin + fonfilter(flookupbuffer,flookupbuffer.textindex(fsortfieldno,recno,true),accept); +end; + +function tcustomlbdropdownlistcontroller.reloadlist: integer; +var + int1,int2,int3,int4: integer; + sortfieldno: integer; + bo1: boolean; + po1: pmsestringaty; + ar1: msestringarty; +begin + result:= 0; + if assigned(fonbeforefilter) then begin + fonbeforefilter(tcustomdataedit(fintf.getwidget)); + end; + if olb_copyitems in foptionslb then begin + flookupbuffer.checkbuffer; //possibly load buffer + sortfieldno:= cols[0].fieldno; + setlength(fedrecnums,flookupbuffer.count); + if assigned(fonfilter) then begin + int3:= 0; + for int1:= 0 to high(fedrecnums) do begin + if olb_unsorted in foptionslb then begin + int4:= int1; + end + else begin + int4:= flookupbuffer.textindex(sortfieldno,int1,true); + end; + bo1:= true; + fonfilter(flookupbuffer,int4,bo1); + if bo1 then begin + fedrecnums[int3]:= int4; + inc(int3); + end; + end; + setlength(fedrecnums,int3); + end + else begin + if olb_unsorted in foptionslb then begin + setlength(fedrecnums,flookupbuffer.count); + for int1:= 0 to high(fedrecnums) do begin + fedrecnums[int1]:= int1; + end; + end + else begin + fedrecnums:= flookupbuffer.textindexar(sortfieldno,true); + end; + end; + for int1:= 0 to fcols.count - 1 do begin + with cols[int1] do begin + count:= length(fedrecnums); + int2:= fieldno; + po1:= datapo; + ar1:= flookupbuffer.textar(int2); + for int3:= 0 to high(fedrecnums) do begin + po1^[int3]:= ar1[fedrecnums[int3]]; + end; + end; + end; + end + else begin + tlbdropdownlist(fdropdownlist).filterchanged; + end; +end; + +function tcustomlbdropdownlistcontroller.createdropdownlist: tdropdownlist; +begin + if olb_copyitems in foptionslb then begin + reloadlist; + if olb_unsorted in foptionslb then begin + result:= tdropdownlist.create(self,fcols,nil); //normal locate + end + else begin + result:= tcopydropdownlist.create(self,fcols,nil); + end; + end + else begin + result:= tlbdropdownlist.create(self,fcols); + end; +end; + +function tcustomlbdropdownlistcontroller.candropdown: boolean; +begin + result:= (flookupbuffer <> nil) and (flookupbuffer.count > 0) and + (fcols.count > 0) and inherited candropdown; +end; + +procedure tcustomlbdropdownlistcontroller.itemselected(const index: integer; + const akey: keyty); +var + int1: integer; +begin + int1:= index; + if index < 0 then begin + if index = -2 then begin + tdropdowncols1(fcols).fitemindex:= fintf.getvalueempty; + end; + end + else begin + if olb_copyitems in foptionslb then begin + int1:= fedrecnums[int1]; + cols.clear; + fedrecnums:= nil; + end + else begin + int1:= tlbdropdownlist(fdropdownlist).getrecno(index); + if not (olb_unsorted in foptionslb) then begin + int1:= flookupbuffer.textindex(cols[0].fieldno,int1,true) + end; + end; + tdropdowncols1(fcols).fitemindex:= int1; + end; + ilbdropdownlist(fintf).recordselected(int1,akey); + if olb_copyitems in foptionslb then begin + cols.clear; + fedrecnums:= nil; + end; +// ilbdropdownlist(fintf).recordselected(int1,akey); +end; + +function tcustomlbdropdownlistcontroller.getremoterowcount: integer; +begin + result:= flookupbuffer.count; +end; + +procedure tcustomlbdropdownlistcontroller.setlookupbuffer( + const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); +end; + +procedure tcustomlbdropdownlistcontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) + and not (csloading in flookupbuffer.componentstate) then begin + with tdataedit1(fintf.getwidget) do begin + if fgridintf <> nil then begin + fgridintf.getcol.changed; + {$ifdef FPC} {$checkpointer off} {$endif} + feditor.text:= datatotext(nil^); + {$ifdef FPC} {$checkpointer default} {$endif} + end + else begin + {$ifdef FPC} {$checkpointer off} {$endif} + feditor.text:= datatotext(nil^); + {$ifdef FPC} {$checkpointer default} {$endif} + end; + end; + updatereadonlystate; + end; +end; + +function tcustomlbdropdownlistcontroller.getlbdatakind(const apropname: string): lbdatakindty; +begin + result:= ilbdropdownlist(fintf).getlbkeydatakind; +end; + +function tcustomlbdropdownlistcontroller.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +{ tlookupeditdatalink } + +constructor tlookupeditdatalink.create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; const intf: idbeditfieldlink); +begin + inherited create(intf); + fowner:= aowner; + fdatatype:= adatatype; +end; + +function tlookupeditdatalink.msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; +var + i1: int32; + li1: int64; + s1: msestring; +begin + if fowner <> nil then begin + result:= ''; + if (field <> nil) and not field.isnull then begin + case fdatatype of + ldt_int32: begin + i1:= field.asinteger; + result:= tcustomdataedit1(fowner).internaldatatotext(i1); + end; + ldt_int64: begin + li1:= field.aslargeint; + result:= tcustomdataedit1(fowner).internaldatatotext(li1); + end; + ldt_string: begin + s1:= field.asunicodestring; + result:= tcustomdataedit1(fowner).internaldatatotext(s1); + end; + end; + end; + end + else begin + result:= inherited msedisplaytext(aformat,aedit); + end; +end; + +procedure tlookupeditdatalink.setfieldnametext(const avalue: string); +begin + if ffieldnametext <> avalue then begin + ffieldnametext := avalue; + updatefields; + end; +end; + +procedure tlookupeditdatalink.updatefields; +begin + if active and (ffieldnametext <> '') then begin + ffieldtext:= datasource.dataset.fieldbyname(ffieldnametext); + end + else begin + ffieldtext:= nil; + end; + inherited; +end; + +procedure tlookupeditdatalink.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + inherited; + setlength(apropertynames,2); + apropertynames[0]:= 'fieldname'; + apropertynames[1]:= 'fieldnametext'; + setlength(afieldtypes,2); + afieldtypes[1]:= textfields; +end; + +function tlookupeditdatalink.getsortfield: tfield; +begin + if ffieldtext = nil then begin + updatefields; + end; + result:= ffieldtext; + if result = nil then begin + result:= inherited getsortfield; + end; +end; + +{ tdbnavigbutton } + +procedure tdbnavigbutton.readtag(reader: treader); +begin + reader.readinteger; //dummy +end; + +procedure tdbnavigbutton.defineproperties(filer: tfiler); +begin + inherited; //backward compatibility + filer.defineproperty('tag',{$ifdef FPC}@{$endif}readtag,nil,false); +end; + +{ tdbwidgetcols } + +class function tdbwidgetcols.getitemclasstype: persistentclassty; +begin + result:= tdbwidgetcol; +end; + +function tdbwidgetcols.getcols(const index: integer): tdbwidgetcol; +begin + result:= tdbwidgetcol(items[index]); +end; + +{ tdbwidgetcol } + +procedure tdbwidgetcol.setwidget(const awidget: twidget); +var + intf1: idbeditfieldlink; + intf2: idbdispfieldlink; +begin + inherited; + if (awidget <> nil) then begin + if awidget.getcorbainterface(typeinfo(idbeditfieldlink),intf1) then begin + fdatalink:= intf1.getfieldlink(); + if fdatalink <> nil then begin + tcustomeditwidgetdatalink(fdatalink).navigator:= + tdbwidgetgrid(fcellinfo.grid).fdatalink.navigator; + end; + end + else begin + if awidget.getcorbainterface(typeinfo(idbdispfieldlink),intf2) then begin + fdatalink:= intf2.getfieldlink(); + end; + end; + end + else begin + fdatalink:= nil; + end; +end; + +procedure tdbwidgetcol.dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); +var + info: gridrowinfoty; +begin + tcustomdbwidgetgrid(grid).fdatalink.begingridrow( + fcellinfo.cell.row,info); + try + inherited; + finally + tcustomdbwidgetgrid(grid).fdatalink.endgridrow(info); + end; +end; + +procedure tdbwidgetcol.doafterdrawcell(const acanvas: tcanvas); +var + info: gridrowinfoty; +begin + tcustomdbwidgetgrid(grid).fdatalink.begingridrow( + fcellinfo.cell.row,info); + try + inherited; + finally + tcustomdbwidgetgrid(grid).fdatalink.endgridrow(info); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbevents.pas b/mseide-msegui/lib/common/db/msedbevents.pas new file mode 100644 index 0000000..cfbbf58 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbevents.pas @@ -0,0 +1,276 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedbevents; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + classes,mclasses,msearrayprops,mseclasses,msqldb,mdb,mseglob,msetimer, + msedatabase,mseinterfaces; + +const + defaultdbeventinterval = 1000000; //us +type + tdbevent = class; + idbevent = interface(inullinterface)[miid_idbevent] + procedure listen(const sender: tdbevent); + procedure unlisten(const sender: tdbevent); + procedure fire(const sender: tdbevent); + end; + idbeventcontroller = interface(inullinterface) + function getdbevent(var aname: string; var aid: int64): boolean; + //false if none + procedure dolisten(const sender: tdbevent); + procedure dounlisten(const sender: tdbevent); + end; + + dbeventty = procedure(const sender: tdbevent; const aid: int64) of object; + + tdbevent = class(tmsecomponent) + private + feventname: string; + fonexecute: dbeventty; + flisten: boolean; + fdatabase: tmdatabase; + fintf: idbevent; + procedure seteventname(const avalue: string); + procedure setlisten(const avalue: boolean); + procedure setdatabase(const avalue: tmdatabase); + protected + procedure doexecute(const aid: int64); virtual; + procedure checkinactive; + procedure checkactive; + procedure loaded; override; + procedure notification(acomponent: tcomponent; operation: toperation); override; + public + destructor destroy; override; + procedure fire; + published + property database: tmdatabase read fdatabase write setdatabase; + property eventname: string read feventname write seteventname; + property listen: boolean read flisten write setlisten default false; + property onexecute: dbeventty read fonexecute write fonexecute; + end; + + dbeventarty = array of tdbevent; + + tdbeventcontroller = class + private + fintf: idbeventcontroller; + ftimer: tsimpletimer; + fevents: dbeventarty; + function geteventinterval: integer; + procedure seteventinterval(const avalue: integer); + protected + procedure dotimer(const sender: tobject); + public + constructor create(const aintf: idbeventcontroller); + destructor destroy; override; + procedure register(const sender: tdbevent); + procedure unregister(const sender: tdbevent); + procedure connect; + procedure disconnect; + procedure getevents; + property eventinterval: integer read geteventinterval write seteventinterval; + end; + +implementation +uses + msearrayutils,msetypes; + +{ tdbevent } + +destructor tdbevent.destroy; +begin + listen:= false; + inherited; +end; + +procedure tdbevent.checkinactive; +begin + if (fdatabase <> nil) and fdatabase.connected and listen then begin + databaseerror('Not inactive.',self); + end; +end; + +procedure tdbevent.checkactive; +begin + if fdatabase = nil then begin + databaseerror('Database not assigned.',self); + end; + if not fdatabase.connected then begin + databaseerror('Database not connected.',self); + end; +end; + +procedure tdbevent.seteventname(const avalue: string); +begin + if avalue <> feventname then begin + if componentstate*[csloading,csdesigning] = [] then begin + checkinactive; + end; + feventname:= avalue; + end; +end; + +procedure tdbevent.setlisten(const avalue: boolean); +begin + if avalue <> flisten then begin + if (componentstate * [csloading,csdesigning] = []) and (fdatabase <> nil) then begin + if eventname = '' then begin + databaseerror('No eventname.',self); + end; + if avalue then begin + fintf.listen(self); + end + else begin + fintf.unlisten(self); + end; + end; + flisten:= avalue; + end; +end; + +procedure tdbevent.setdatabase(const avalue: tmdatabase); +begin + if avalue <> nil then begin + if not mseclasses.getcorbainterface(avalue,typeinfo(idbevent),fintf) then begin + databaseerror('Invalid Database.',self); + end; + end; + if fdatabase <> nil then begin + fdatabase.removefreenotification(self); + end; + fdatabase:= avalue; + if fdatabase <> nil then begin + fdatabase.freenotification(self); + end; +end; + +procedure tdbevent.fire; +begin + checkactive; + fintf.fire(self); +end; + +procedure tdbevent.doexecute(const aid: int64); +begin + if canevent(tmethod(fonexecute)) then begin + fonexecute(self,aid); + end; +end; + +procedure tdbevent.loaded; +begin + inherited; + if flisten and not (csdesigning in componentstate) then begin + flisten:= false; + listen:= true; + end; +end; + +procedure tdbevent.notification(acomponent: tcomponent; operation: toperation); +begin + if (operation = opremove) and (acomponent = fdatabase) then begin + fdatabase:= nil; + fintf:= nil; + end; + inherited; +end; + +{ tdbeventcontroller } + +constructor tdbeventcontroller.create(const aintf: idbeventcontroller); +begin + fintf:= aintf; + ftimer:= tsimpletimer.create(defaultdbeventinterval, + {$ifdef FPC}@{$endif}dotimer,false,[]); + inherited create; +end; + +destructor tdbeventcontroller.destroy; +begin + ftimer.free; + inherited; +end; + +procedure tdbeventcontroller.register(const sender: tdbevent); +begin + if finditem(pointerarty(fevents),sender) < 0 then begin + additem(pointerarty(fevents),sender); + end; +end; + +procedure tdbeventcontroller.unregister(const sender: tdbevent); +begin + removeitem(pointerarty(fevents),sender); +end; + +procedure tdbeventcontroller.connect; +var + int1: integer; +begin + for int1:= 0 to high(fevents) do begin + fintf.dolisten(fevents[int1]); + end; + ftimer.enabled:= ftimer.interval <> 0; +end; + +procedure tdbeventcontroller.disconnect; +var + int1: integer; +begin + ftimer.enabled:= false; + for int1:= 0 to high(fevents) do begin + try + fintf.dounlisten(fevents[int1]); + except + end; + end; +end; + +procedure tdbeventcontroller.dotimer(const sender: tobject); +var + str1: string; + lint1: int64; + int1: integer; +begin + while fintf.getdbevent(str1,lint1) do begin + for int1:= 0 to high(fevents) do begin + if fevents[int1].eventname = str1 then begin + fevents[int1].doexecute(lint1); + end; + end; + end; +end; + +function tdbeventcontroller.geteventinterval: integer; +begin + result:= ftimer.interval; +end; + +procedure tdbeventcontroller.seteventinterval(const avalue: integer); +begin + ftimer.interval:= abs(avalue); + if avalue < 0 then begin + ftimer.singleshot:= true; + ftimer.enabled:= true; //trigger oneshot + end + else begin + ftimer.singleshot:= false; + end; +end; + +procedure tdbeventcontroller.getevents; +begin + dotimer(nil); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbf.pas b/mseide-msegui/lib/common/db/msedbf.pas new file mode 100644 index 0000000..629e52e --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbf.pas @@ -0,0 +1,375 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedbf; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses +{$warnings off} + classes,mclasses,mdb,mdbf,msedb,msetypes{msestrings},dbf_idxfile, + mseapplication; +{$warnings on} + +type + tmsedbf = class(tdbf,imselocate,idscontroller,igetdscontroller, + iactivatorclient) + private + ffilepath: filenamety; + fcontroller: tdscontroller; + procedure setfilepath(const avalue: filenamety); + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller +// procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalclose; override; + procedure internalinsert; override; + procedure internaldelete; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; + { + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; + } + procedure AppendRecord(const Values: array of const); + function moveby(const distance: integer): integer; + procedure cancel; override; + procedure post; override; + published + property FilePath: filenamety read ffilepath write setfilepath; + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + property FilterOptions default []; + end; + +implementation +uses + msefileutils; + +{ tmsedbf } + +constructor tmsedbf.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsedbf.destroy; +begin + fcontroller.free; + inherited; +end; +{ +function tmsedbf.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tmsedbf.locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +function tmsedbf.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= msedb.locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; + +procedure tmsedbf.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsedbf.setfilepath(const avalue: filenamety); +begin + ffilepath:= tomsefilepath(avalue); + inherited filepath:= ansistring( + tosysfilepath(msefileutils.filepath(avalue,fk_default,true))); +end; + +procedure tmsedbf.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +procedure tmsedbf.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +function tmsedbf.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsedbf.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsedbf.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +procedure tmsedbf.cancel; +begin + fcontroller.cancel; +end; + +function tmsedbf.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsedbf.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsedbf.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +{ +procedure tmsedbf.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsedbf.Resync(Mode: TResyncMode); +begin + fcontroller.resync(mode); +end; +} +procedure tmsedbf.inheritedcancel; +begin + inherited cancel; +end; + +function tmsedbf.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +function tmsedbf.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsedbf.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsedbf.internalinsert; +begin + fcontroller.internalinsert; +end; + +procedure tmsedbf.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsedbf.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsedbf.inheritedpost; +begin + inherited post; +end; + +procedure tmsedbf.post; +begin + fcontroller.post; +end; + +procedure tmsedbf.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsedbf.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsedbf.openlocal; +begin + inherited internalopen; +end; + +procedure tmsedbf.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsedbf.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsedbf.getblobdatasize: integer; +begin + result:= 0; //no blobid? +end; + +function tmsedbf.getnumboolean: boolean; +begin + result:= false; +end; + +function tmsedbf.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsedbf.getint64currency: boolean; +begin + result:= false; +end; + +function tmsedbf.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsedbf.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsedbf.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsedbf.endfilteredit; +begin + //dummy +end; + +procedure tmsedbf.clearfilter; +begin + //dummy +end; +{ +procedure tmsedbf.doidleapplyupdates; +begin + //dummy +end; +} +function tmsedbf.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsedbf.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsedbf.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsedbf.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsedbf.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +function tmsedbf.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsedbf.begindisplaydata; +begin + //dummy +end; + +procedure tmsedbf.enddisplaydata; +begin + ///dummy +end; + +procedure tmsedbf.inheriteddelete; +begin + inherited delete(); +end; + +procedure tmsedbf.inheritedinsert; +begin + inherited insert(); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbgraphics.pas b/mseide-msegui/lib/common/db/msedbgraphics.pas new file mode 100644 index 0000000..3324ca9 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbgraphics.pas @@ -0,0 +1,579 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedbgraphics; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + classes,mclasses,mdb,mseimage,mseguiglob,msedataimage,msedbdispwidgets,msedb, + msetypes,msedbedit,typinfo, + msegrids,msewidgetgrid,msedatalist,msebitmap,msebintree,msegraphics, + msemenus,mseevent,msegui,mseifiglob,mseificompglob; + +{ add the needed graphic format units to your project: + mseformatbmpicoread, + mseformatjpgwrite,mseformatpngwrite, + mseformatpnmread,mseformattgaread,mseformatxpmread, +} + +type + idbgraphicfieldlink = interface(idbeditfieldlink) + procedure setformat(const avalue: string); + end; + + timagecachenode = class(tcachenode) + private + fimage: maskedimagety; + fformat: string; + protected + flocal: boolean; + public + constructor create(const aid: blobidty); overload; + destructor destroy; override; + property format: string read fformat write fformat; + end; + + timagecache = class(tcacheavltree) + protected + ffindnode: timagecachenode; + public + constructor create; + destructor destroy; override; + function find(const akey: blobidty; out anode: timagecachenode): boolean; + overload; + end; + + tmsegraphicfield = class(tmseblobfield) + private + fformat: string; + fimagecache: timagecache; + function getimagecachekb: integer; + procedure setimagecachekb(const avalue: integer); + protected + procedure removecache(const aid: blobidty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function loadbitmap(const adest: tmaskedbitmap; + aformat: string = ''): string; //returns format + procedure storebitmap(const asource: tmaskedbitmap; + aformat: string = ''); overload; + procedure storebitmap(const asource: tmaskedbitmap; aformat: string; + const params: array of const); overload; + procedure clearcache; override; + published + property format: string read fformat write fformat; + property imagecachekb: integer read getimagecachekb + write setimagecachekb default 0; + //cachesize in kilo bytes, 0 -> no cache + end; + + tgraphicdatalink = class(teditwidgetdatalink) + protected + procedure setfield(const value: tfield); override; + public + constructor create(const intf: idbgraphicfieldlink); + function loadbitmap(const adest: tmaskedbitmap; + const aformat: string): string; //returns format + end; + + tdbdataimage = class(tcustomdataimage,idbgraphicfieldlink, + ireccontrol,iifidatalink) + private + fdatalink: tgraphicdatalink; +// fvaluebuffer: string; + //iifidatalink + function getifilinkkind: ptypeinfo; + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue); //for pointer property without RTTI + procedure setifivalue(const avalue); //for pointer property without RTTI + //idbeditfieldlink + function getgriddatasource: tdatasource; + function getedited: boolean; + procedure initeditfocus; + function checkvalue(const quiet: boolean = false): boolean; + procedure valuetofield; + procedure updatereadonlystate; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //idbgraphicfieldlink + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tgraphicdatalink); + protected +// procedure doenter; override; +// procedure doexit; override; + procedure griddatasourcechanged; override; + procedure loadcellbmp(const acanvas: tcanvas; const abmp: tmaskedbitmap); override; + function getrowdatapo(const arow: integer): pointer; override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure defineproperties(filer: tfiler); override; + procedure setvalue(const avalue: string); override; + procedure gridtovalue(row: integer); override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tgraphicdatalink read fdatalink write setdatalink; + property format; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + +implementation +uses + msestream,sysutils,msegraphicstream; + +type + tsimplebitmap1 = class(tsimplebitmap); + treader1 = class(treader); + + { tdbdataimage } + +function tdbdataimage.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure tdbdataimage.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +function tdbdataimage.getgriddata: tdatalist; +begin + result:= nil; +end; + +function tdbdataimage.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure tdbdataimage.getifivalue(var avalue); +begin + //dummy +end; + +procedure tdbdataimage.setifivalue(const avalue); +begin + //dummy +end; + +constructor tdbdataimage.create(aowner: tcomponent); +begin + fdatalink:= tgraphicdatalink.create(idbgraphicfieldlink(self)); + inherited; +{$warnings off} + include(tsimplebitmap1(bitmap).fstate,pms_nosave); +{$warnings on} +end; + +destructor tdbdataimage.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbdataimage.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= blobfields + [ftstring]; +end; + +procedure tdbdataimage.fieldtovalue; +begin + fcurformat:= datalink.loadbitmap(bitmap,format); +end; + +procedure tdbdataimage.setnullvalue; +begin + bitmap.clear; +end; + +procedure tdbdataimage.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbdataimage.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbdataimage.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +function tdbdataimage.getedited: boolean; +begin + result:= false; +end; + +procedure tdbdataimage.initeditfocus; +begin + //dummy +end; + +function tdbdataimage.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; + //dummy +end; + +procedure tdbdataimage.valuetofield; +begin + if fvalue{buffer} = '' then begin + fdatalink.clear; + end + else begin + fdatalink.asstring:= fvalue{buffer}; + end; +end; + +procedure tdbdataimage.updatereadonlystate; +begin + //dummy +end; + +function tdbdataimage.getrowdatapo(const arow: integer): pointer; +begin + if (fgriddatalink <> nil) and not + tgriddatalink(fgriddatalink).getrowfieldisnull( + fdatalink.field,arow) then begin + result:= tgriddatalink(fgriddatalink).getdummystringbuffer; + pstring(result)^:= ' '; + end + else begin + result:= nil; + end; +end; + +procedure tdbdataimage.loadcellbmp(const acanvas: tcanvas; + const abmp: tmaskedbitmap); +var + int1: integer; +begin + with cellinfoty(acanvas.drawinfopo^) do begin + if fdatalink.field is tmsegraphicfield then begin + with tgriddatalink(fgriddatalink) do begin + int1:= activerecord; + activerecord:= cell.row; + tmsegraphicfield(fdatalink.field).loadbitmap(abmp,format); + activerecord:= int1; + end; + end + else begin + abmp.loadfromstring( + string(tgriddatalink(fgriddatalink).getansistringbuffer( + fdatalink.field,cell.row)^),format,[]); + end; + end; +end; + +function tdbdataimage.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbdataimage.setdatalink(const avalue: tgraphicdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdataimage.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbdataimage.gridtovalue(row: integer); +begin + //dummy +end; + +procedure tdbdataimage.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdbdataimage.setvalue(const avalue: string); +//var +// bufferbefore: string; +begin +// bufferbefore:= fvaluebuffer; +// fvaluebuffer:= avalue; +// try + fdatalink.modified; + inherited; + fdatalink.valuechanged(iifidatalink(self)); +// finally +// fvaluebuffer:= bufferbefore; +// end; +end; + +procedure tdbdataimage.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbdataimage.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +{ tmsegraphicfield } + +constructor tmsegraphicfield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftgraphic); +end; + +destructor tmsegraphicfield.destroy; +begin + freeandnil(fimagecache); + inherited; +end; + +function tmsegraphicfield.loadbitmap(const adest: tmaskedbitmap; + aformat: string = ''): string; +var + stream1: tstringcopystream; + str1: string; + id1: blobidty; + n1: timagecachenode; +begin + result:= ''; + if isnull then begin + adest.clear; + end + else begin + if (fimagecache = nil) or not assigned(fgetblobid) or not fgetblobid(self,id1) or + not fimagecache.find(id1,n1) then begin + str1:= asstring; + if str1 = '' then begin + adest.clear; + end + else begin + if aformat = '' then begin + aformat:= format; + end; + stream1:= tstringcopystream.create(str1); + try + result:= adest.loadfromstream(stream1,aformat,[]); + except + result:= ''; + adest.clear; + end; + stream1.free; + end; + if (fimagecache <> nil) and assigned(fgetblobid) then begin + n1:= timagecachenode.create(id1); + n1.format:= result; + adest.savetomaskedimage(n1.fimage); + n1.fsize:= (n1.fimage.image.length + n1.fimage.mask.length) * + sizeof(longword); + fimagecache.addnode(n1); + end; + end + else begin + adest.loadfrommaskedimage(n1.fimage); + result:= n1.format; + end; + end; +end; + +procedure tmsegraphicfield.storebitmap(const asource: tmaskedbitmap; + aformat: string; const params: array of const); +var + stream1: tmsefilestream; +begin + if aformat = '' then begin + aformat:= format; + end; + stream1:= tmsefilestream.create; + try + writegraphic(stream1,asource,aformat,params); + stream1.position:= 0; + loadfromstream(stream1); + finally + stream1.free; + end; +end; + +procedure tmsegraphicfield.storebitmap(const asource: tmaskedbitmap; + aformat: string = ''); +begin + storebitmap(asource,aformat,[]); +end; + +function tmsegraphicfield.getimagecachekb: integer; +begin + result:= 0; + if fimagecache <> nil then begin + result:= fimagecache.maxsize div 1024; + end; +end; + +procedure tmsegraphicfield.setimagecachekb(const avalue: integer); +begin + if imagecachekb <> avalue then begin + if avalue > 0 then begin + if fimagecache = nil then begin + fimagecache:= timagecache.create; + end; + fimagecache.maxsize:= avalue * 1024; + end + else begin + freeandnil(fimagecache); + end; + end; +end; + +procedure tmsegraphicfield.clearcache; +begin + if fimagecache <> nil then begin + fimagecache.clear; + end; + inherited; +end; + +procedure tmsegraphicfield.removecache(const aid: blobidty); +var + n1: timagecachenode; +begin + if fimagecache <> nil then begin + if fimagecache.find(aid,n1) then begin + fimagecache.removenode(n1); + n1.free; + end; + end; + inherited; +end; + +{ tgraphicdatalink } + +constructor tgraphicdatalink.create(const intf: idbgraphicfieldlink); +begin + inherited create(intf); +end; + +procedure tgraphicdatalink.setfield(const value: tfield); +begin + if value is tmsegraphicfield then begin + idbgraphicfieldlink(fintf).setformat(tmsegraphicfield(value).format); + end; + inherited; +end; + +function tgraphicdatalink.loadbitmap(const adest: tmaskedbitmap; + const aformat: string): string; +var + stream1: tstringcopystream; + str1: string; +begin + if field is tmsegraphicfield then begin + with tmsegraphicfield(field) do begin + result:= loadbitmap(adest,aformat); + end; + end + else begin + str1:= field.asstring; + if str1 = '' then begin + adest.clear; + end + else begin + stream1:= tstringcopystream.create(str1); + try + result:= adest.loadfromstream(stream1,aformat,[]); + except + result:= ''; + adest.clear; + end; + stream1.free; + end; + end; +end; + +{ timagecachenode } + +constructor timagecachenode.create(const aid: blobidty); +begin + flocal:= aid.local; + inherited create(aid.id); +end; + +destructor timagecachenode.destroy; +begin + freeimage(fimage); + inherited; +end; + +{ timagecache } + +function compareblobid(const left,right: tavlnode): integer; +var + lint1: int64; +begin + result:= integer(timagecachenode(left).flocal) - + integer(timagecachenode(right).flocal); + if result = 0 then begin + lint1:= timagecachenode(left).fkey - timagecachenode(right).fkey; + if lint1 > 0 then begin + result:= 1; + end + else begin + if lint1 < 0 then begin + result:= -1; + end; + end; + end; +end; + +constructor timagecache.create; +begin + ffindnode:= timagecachenode.create; + inherited; + fcompare:= {$ifdef FPC}@{$endif}compareblobid; +end; + +destructor timagecache.destroy; +begin + inherited; + ffindnode.free; +end; + +function timagecache.find(const akey: blobidty; + out anode: timagecachenode): boolean; +begin + ffindnode.fkey:= akey.id; + ffindnode.flocal:= akey.local; + result:= find(ffindnode,tavlnode(anode)); +end; + +initialization + regfieldclass(ft_graphic,tmsegraphicfield); +end. diff --git a/mseide-msegui/lib/common/db/msedblookup.pas b/mseide-msegui/lib/common/db/msedblookup.pas new file mode 100644 index 0000000..1aba58b --- /dev/null +++ b/mseide-msegui/lib/common/db/msedblookup.pas @@ -0,0 +1,2759 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedblookup; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,msewidgetgrid,msedataedits,mseeditglob,msestrings, + msedatalist, + msedbedit,msedb,msegui,msegrids,msedbdispwidgets,mselookupbuffer,mseclasses, + mseformatstr,msetypes,mseglob,msemenus,mseguiglob,msebufdataset, + msegraphics; + +const + defaultlookupoptionsedit = defaultoptionsedit + [oe_readonly]; + +type + idblookupdispfieldlink = interface(idbdispfieldlink) + procedure formatchanged; + procedure refreshfieldvalue; + end; + + idblookuplbdispfieldlink = interface(idblookupdispfieldlink) + procedure setlookupvalue(const aindex: integer); + function lookuptext(const aindex: integer): msestring; + function getdatalbdatakind: lbdatakindty; + end; + + idblookupdbdispfieldlink = interface(idblookupdispfieldlink) + procedure setlookupvalue(const aindex: bookmarkdataty); + function lookuptext(const aindex: bookmarkdataty): msestring; + function getlookupvaluefieldtypes: fieldtypesty; + end; + + tdblookup32lb = class; + + tlookupdispfielddatalink = class(tdispfielddatalink) + private + function getdatasource1: tdatasource; + procedure setwidgetdatasource(const avalue: tdatasource); + procedure griddatasourcechanged; + protected + fowner: tcustomdataedit; + fdatatype: lookupdatatypety; + fisnull: boolean; + procedure lookupchange; + function datatotext(const data): msestring; virtual; abstract; + procedure updatelookupvalue; virtual; abstract; + procedure fieldtovalue; virtual; abstract; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; virtual; abstract; + public + constructor create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idblookupdispfieldlink); + function msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; override; + published + property datasource: tdatasource read getdatasource1 write setwidgetdatasource; + end; + + tlookupdbdispfielddatalink = class; + + tlookupdatalink = class(tfielddatalink) + private + fkeyfield: tfield; + fkeyfieldname: string; + protected + fdisplink: tlookupdbdispfielddatalink; + fcanlookup: boolean; + flookupindexnum: integer; + procedure updatefields; override; + procedure activechanged; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure fieldchanged; override; + end; + + tlookupdbdispfielddatalink = class(tlookupdispfielddatalink) + private + flookupdatalink: tlookupdatalink; + procedure setlookupkeyfield(const avalue: string); + procedure setlookupvaluefield(const avalue: string); + function getlookupkeyfield: string; + function getlookupvaluefield: string; + function getlookupdatasource: tdatasource; + procedure setlookupdatasource(const avalue: tdatasource); + protected + function getintegerlookupvalue(const abm: bookmarkdataty): integer; + function getstringlookupvalue(const abm: bookmarkdataty): msestring; + function getfloatlookupvalue(const abm: bookmarkdataty): double; + function getdataset(const aindex: integer): tdataset; override; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); override; + public + constructor create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idblookupdbdispfieldlink); + destructor destroy; override; + published + property lookupdatasource: tdatasource read getlookupdatasource + write setlookupdatasource; + property lookupkeyfield: string read getlookupkeyfield + write setlookupkeyfield; + property lookupvaluefield: string read getlookupvaluefield + write setlookupvaluefield; + end; + + tlookuplbdispfielddatalink = class(tlookupdispfielddatalink, + ilookupbufferfieldinfo,iobjectlink) + private + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: lookupbufferfieldnoty; + flookupvaluefieldno: lookupbufferfieldnoty; + fobjectlinker: tobjectlinker; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + procedure setlookupkeyfieldno(const avalue: lookupbufferfieldnoty); + procedure setlookupvaluefieldno(const avalue: lookupbufferfieldnoty); + protected + function getkeylbdatakind: lbdatakindty; virtual; abstract; + procedure objectevent(const sender: tobject; const event: objecteventty); + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + constructor create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idblookuplbdispfieldlink); + destructor destroy; override; + published + property lookupbuffer: tcustomlookupbuffer read flookupbuffer + write setlookupbuffer; + property lookupkeyfieldno: lookupbufferfieldnoty read flookupkeyfieldno + write setlookupkeyfieldno default 0; + property lookupvaluefieldno: lookupbufferfieldnoty read flookupvaluefieldno + write setlookupvaluefieldno default 0; + end; + + tlookup32lbdispfielddatalink = class(tlookuplbdispfielddatalink) + protected + fkey: integer; + function getkeylbdatakind: lbdatakindty; override; + procedure updatelookupvalue; override; + function datatotext(const data): msestring; override; + procedure fieldtovalue; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tlookup64lbdispfielddatalink = class(tlookuplbdispfielddatalink) + protected + fkey: int64; + function getkeylbdatakind: lbdatakindty; override; + procedure updatelookupvalue; override; + function datatotext(const data): msestring; override; + procedure fieldtovalue; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tlookupstrlbdispfielddatalink = class(tlookuplbdispfielddatalink) + protected + fkey: msestring; + function getkeylbdatakind: lbdatakindty; override; + procedure updatelookupvalue; override; + function datatotext(const data): msestring; override; + procedure fieldtovalue; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tlookup32dbdispfielddatalink = class(tlookupdbdispfielddatalink) + protected + fkey: integer; + procedure updatelookupvalue; override; + procedure fieldtovalue; override; + function datatotext(const data): msestring; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tlookup64dbdispfielddatalink = class(tlookupdbdispfielddatalink) + protected + fkey: int64; + procedure updatelookupvalue; override; + procedure fieldtovalue; override; + function datatotext(const data): msestring; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tlookupstrdbdispfielddatalink = class(tlookupdbdispfielddatalink) + protected + fkey: msestring; + procedure updatelookupvalue; override; + procedure fieldtovalue; override; + function datatotext(const data): msestring; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tdblookup1 = class(tcustomdataedit,idblookupdispfieldlink,idbdispfieldlink) + private + fdatalink: tlookupdispfielddatalink; + procedure setdatalink(const avalue: tlookupdispfielddatalink); + function getisnull: boolean; + protected + function createdatalink: tlookupdispfielddatalink; virtual; abstract; + procedure dochange; override; + + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(row: integer); override; + procedure griddatasourcechanged; override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getoptionsedit: optionseditty; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure setnullvalue; override; + + function internaldatatotext(const data): msestring; override; + function getrowdatapo(const arow: integer): pointer; override; + + //idispfieldlink + function getfieldlink: tdispfielddatalink; + procedure fieldtovalue; + procedure valuetofield; + procedure getfieldtypes(var afieldtypes: fieldtypesty); virtual; + procedure refreshfieldvalue; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property isnull: boolean read getisnull; + published + + property empty_color; + property empty_font; + property empty_fontstyle; + property empty_textflags; + property empty_text; + property empty_options; + property empty_textcolor; + property empty_textcolorbackground; + property optionsedit default defaultlookupoptionsedit; + property font; + property textflags; + property textflagsactive; + property caretwidth; + property onchange; + property ongettext; + property onkeydown; + property onkeyup; + end; + + tdblookup = class(tdblookup1) + private + protected + published + property datalink: tlookupdispfielddatalink read fdatalink write setdatalink; + end; + + tdblookupdb = class(tdblookup,idblookupdbdispfieldlink) + private + function getdatalink: tlookupdbdispfielddatalink; + procedure setdatalink(const avalue: tlookupdbdispfielddatalink); + protected + procedure setlookupvalue(const abm: bookmarkdataty); virtual; abstract; + function lookuptext(const abm: bookmarkdataty): msestring; virtual; abstract; + function getlookupvaluefieldtypes: fieldtypesty; virtual; abstract; + public + published + property datalink: tlookupdbdispfielddatalink read getdatalink + write setdatalink; + end; + + tdblookup32db = class(tdblookupdb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + end; + + tdblookup64db = class(tdblookupdb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + end; + + tdblookupstrdb = class(tdblookupdb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + end; + + tdblookuplb = class(tdblookup,idblookuplbdispfieldlink) + private + procedure readlookupkeyfieldno(reader: treader); + procedure readlookupvaluefieldno(reader: treader); + function getlookupbuffer: tcustomlookupbuffer; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + function getdatalink: tlookuplbdispfielddatalink; + procedure setdatalink(const avalue: tlookuplbdispfielddatalink); + protected + function getdatalbdatakind: lbdatakindty; virtual; abstract; + procedure defineproperties(filer: tfiler); override; + procedure setlookupvalue(const aindex: integer); virtual; abstract; + //aindex -1 -> NULL + function lookuptext(const aindex: integer): msestring; virtual; abstract; + public + published + property datalink: tlookuplbdispfielddatalink read getdatalink + write setdatalink; +{ + property lookupbuffer: tcustomlookupbuffer read getlookupbuffer + write setlookupbuffer; deprecated; + //use datalink.lookupbuffer +} + end; + + tdblookup32lb = class(tdblookuplb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + public + end; + + tdblookup64lb = class(tdblookuplb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + //idbeditfieldlink + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + public + end; + + tdblookupstrlb = class(tdblookuplb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + //idbeditfieldlink + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + public + end; + + tdbstringlookuplb = class(tdblookup32lb) + private + fvalue: msestring; + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + property value: msestring read fvalue; + end; + + tdbstringlookup64lb = class(tdblookup64lb) + private + fvalue: msestring; + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + property value: msestring read fvalue; + end; + + tdbstringlookupstrlb = class(tdblookupstrlb) + private + fvalue: msestring; + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + property value: msestring read fvalue; + end; + + tdbstringlookupdb = class(tdblookup32db) + private + fvalue: msestring; + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + property value: msestring read fvalue; + end; + + tdbstringlookup64db = class(tdblookup64db) + private + fvalue: msestring; + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + property value: msestring read fvalue; + end; + + tdbstringlookupstrdb = class(tdblookupstrdb) + private + fvalue: msestring; + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + property value: msestring read fvalue; + end; + + tdbintegerlookuplb = class(tdblookup32lb) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbintegerlookup64lb = class(tdblookup64lb) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbintegerlookupstrlb = class(tdblookupstrlb) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbintegerlookupdb = class(tdblookup32db) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbintegerlookup64db = class(tdblookup64db) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbintegerlookupstrdb = class(tdblookupstrdb) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbreallookuplb = class(tdblookup32lb) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + procedure readvaluescale(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbreallookup64lb = class(tdblookup64lb) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + procedure readvaluescale(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbreallookupstrlb = class(tdblookupstrlb) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + procedure readvaluescale(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbreallookupdb = class(tdblookup32db) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbreallookup64db = class(tdblookup64db) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbreallookupstrdb = class(tdblookupstrdb) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbdatetimelookuplb = class(tdblookup32lb) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + property value: tdatetime read fvalue; + end; + + tdbdatetimelookup64lb = class(tdblookup64lb) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + property value: tdatetime read fvalue; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + end; + + tdbdatetimelookupstrlb = class(tdblookupstrlb) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + property value: tdatetime read fvalue; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + end; + + tdbdatetimelookupdb = class(tdblookup32db) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + property value: tdatetime read fvalue; + end; + + tdbdatetimelookup64db = class(tdblookup64db) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + property value: tdatetime read fvalue; + end; + + tdbdatetimelookupstrdb = class(tdblookupstrdb) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + property value: tdatetime read fvalue; + end; + +implementation +uses + msereal,sysutils; +type + tcustomdataedit1 = class(tcustomdataedit); + +{ tlookupdispfielddatalink } + +constructor tlookupdispfielddatalink.create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idblookupdispfieldlink); +begin + fowner:= aowner; + fdatatype:= adatatype; + fisnull:= true; + inherited create(intf); +end; + +procedure tlookupdispfielddatalink.setwidgetdatasource(const avalue: tdatasource); +begin + if not ((csloading in fowner.componentstate) and datasourcefixed or + (fowner.gridintf <> nil)) then begin + inherited datasource:= avalue; + end; +end; + +procedure tlookupdispfielddatalink.griddatasourcechanged; +var + dso1: tdatasource; +begin + with fowner do begin + dso1:= tcustomdbwidgetgrid(gridintf.getcol.grid).datalink.datasource; + end; + if dso1 <> datasource then begin + inherited datasource:= dso1; + end; +end; + +function tlookupdispfielddatalink.getdatasource1: tdatasource; +begin + result:= inherited datasource; +end; + +procedure tlookupdispfielddatalink.lookupchange; +begin + if not (csloading in fowner.componentstate) and active and + (field <> nil) then begin + idblookupdispfieldlink(fintf).formatchanged; + idblookupdispfieldlink(fintf).fieldtovalue; + end; +end; + +function tlookupdispfielddatalink.msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; +var + i1: int32; + li1: int64; + s1: msestring; +begin + if fowner <> nil then begin + result:= ''; + if (field <> nil) and not field.isnull then begin + case fdatatype of + ldt_int32: begin + i1:= field.asinteger; + result:= tcustomdataedit1(fowner).internaldatatotext(i1); + end; + ldt_int64: begin + li1:= field.aslargeint; + result:= tcustomdataedit1(fowner).internaldatatotext(li1); + end; + ldt_string: begin + s1:= field.asunicodestring; + result:= tcustomdataedit1(fowner).internaldatatotext(s1); + end; + end; + end; + end + else begin + result:= inherited msedisplaytext(aformat,aedit); + end; +end; + +{ tdblookup1 } + +constructor tdblookup1.create(aowner: tcomponent); +begin + if fdatalink = nil then begin + fdatalink:= createdatalink; + end; + inherited; + foptionsedit:= defaultlookupoptionsedit; +end; + +destructor tdblookup1.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdblookup1.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit + [oe_readonly]; +end; + +procedure tdblookup1.setnullvalue; +begin + inherited; + fdatalink.fisnull:= true; + changed; +end; + +procedure tdblookup1.texttovalue(var accept: boolean; const quiet: boolean); +begin + fdatalink.fisnull:= text = ''; +end; + +procedure tdblookup1.valuetofield; +begin + //dummy +end; + +procedure tdblookup1.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdblookup1.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdblookup1.setdatalink(const avalue: tlookupdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdblookup1.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +function tdblookup1.getdatalistclass: datalistclassty; +begin + result:= tnonedatalist; +end; + +procedure tdblookup1.valuetogrid(row: integer); +begin + //dummy +end; + +procedure tdblookup1.refreshfieldvalue; +begin + valuetotext; + changed; +end; + +procedure tdblookup1.fieldtovalue; +begin + fdatalink.fieldtovalue; + exclude(fstate,des_dbnull); + refreshfieldvalue; +end; + +procedure tdblookup1.getfieldtypes(var afieldtypes: fieldtypesty); +begin + //dummy +end; + +procedure tdblookup1.dochange; +begin + fdatalink.updatelookupvalue; + inherited; +end; + +function tdblookup1.internaldatatotext(const data): msestring; +begin + result:= fdatalink.datatotext(data); +end; + +function tdblookup1.getisnull: boolean; +begin + result:= fdatalink.fisnull; +end; + +function tdblookup1.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= fdatalink.getrowdatapo(tgriddatalink(fgriddatalink),arow); + end + else begin + result:= nil; + end; +end; + +function tdblookup1.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdblookuplb } + +{ tdblookup32lb } + +procedure tdblookup32lb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +function tdblookup32lb.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookup32lbdispfielddatalink.create(self,ldt_int32, + idblookuplbdispfieldlink(self)); +end; + +procedure tdblookup64lb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +function tdblookup64lb.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookup64lbdispfielddatalink.create(self,ldt_int64, + idblookuplbdispfieldlink(self)); +end; + +procedure tdblookupstrlb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdblookupstrlb.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookupstrlbdispfielddatalink.create(self,ldt_string, + idblookuplbdispfieldlink(self)); +end; + +{ tdbstringlookuplb } + +procedure tdbstringlookuplb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= ''; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbstringlookuplb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; +end; + +function tdbstringlookuplb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +{ tdbstringlookupdb } + +procedure tdbstringlookupdb.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookupdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookupdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= charfields; +end; + +{ tdbstringlookup64db } + +procedure tdbstringlookup64db.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookup64db.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookup64db.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= charfields; +end; + +{ tdbstringlookupstrdb } + +procedure tdbstringlookupstrdb.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookupstrdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookupstrdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= charfields; +end; + +{ tdbintegerlookuplb } + +constructor tdbintegerlookuplb.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookuplb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= 0; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.integervaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbintegerlookuplb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= msestring(intvaluetostr(flookupbuffer.integervaluephys( + flookupvaluefieldno,aindex),fbase,fbitcount)); + end; +end; + +procedure tdbintegerlookuplb.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookuplb.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookuplb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +{ tdbintegerlookupdb } + +constructor tdbintegerlookupdb.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookupdb.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm); +end; + +function tdbintegerlookupdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= msestring(intvaluetostr( + tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm), + fbase,fbitcount)); +end; + +procedure tdbintegerlookupdb.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookupdb.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookupdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= int32fields; +end; + +{ tdbintegerlookup64db } + +constructor tdbintegerlookup64db.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookup64db.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm); +end; + +function tdbintegerlookup64db.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= msestring(intvaluetostr( + tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm), + fbase,fbitcount)); +end; + +procedure tdbintegerlookup64db.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookup64db.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookup64db.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= int32fields; +end; + +{ tdbintegerlookupstrdb } + +constructor tdbintegerlookupstrdb.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookupstrdb.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm); +end; + +function tdbintegerlookupstrdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= msestring(intvaluetostr( + tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm), + fbase,fbitcount)); +end; + +procedure tdbintegerlookupstrdb.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookupstrdb.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookupstrdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= int32fields; +end; + +{ tdbreallookuplb } + +constructor tdbreallookuplb.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookuplb.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookuplb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptyreal; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(flookupbuffer.floatvaluephys( + flookupvaluefieldno,aindex),valuerange,valuestart); + end; + end; +end; + +function tdbreallookuplb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= realtytostring(flookupbuffer.floatvaluephys( + flookupvaluefieldno,aindex),fformat); + end; +end; + +procedure tdbreallookuplb.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookuplb.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +procedure tdbreallookuplb.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tdbreallookuplb.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + +function tdbreallookuplb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdbreallookupdb } + +constructor tdbreallookupdb.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookupdb.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookupdb.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptyreal; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(getfloatlookupvalue(abm),valuerange,valuestart); + end; + end; +end; + +function tdbreallookupdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + result:= realtytostring(getfloatlookupvalue(abm),fformat); + end; +end; + +procedure tdbreallookupdb.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookupdb.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +function tdbreallookupdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= doublefields; +end; + +{ tdbreallookup64db } + +constructor tdbreallookup64db.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookup64db.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookup64db.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptyreal; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(getfloatlookupvalue(abm),valuerange,valuestart); + end; + end; +end; + +function tdbreallookup64db.lookuptext(const abm: bookmarkdataty): msestring; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + result:= realtytostring(getfloatlookupvalue(abm),fformat); + end; +end; + +procedure tdbreallookup64db.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookup64db.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +function tdbreallookup64db.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= doublefields; +end; + +{ tdbreallookupstrdb } + +constructor tdbreallookupstrdb.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookupstrdb.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookupstrdb.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptyreal; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(getfloatlookupvalue(abm),valuerange,valuestart); + end; + end; +end; + +function tdbreallookupstrdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + result:= realtytostring(getfloatlookupvalue(abm),fformat); + end; +end; + +procedure tdbreallookupstrdb.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookupstrdb.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +function tdbreallookupstrdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= doublefields; +end; + +{ tdatetimelookuplb } + +procedure tdbdatetimelookuplb.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookuplb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptydatetime; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbdatetimelookuplb.lookuptext(const aindex: integer): msestring; +var + dat1: tdatetime; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + dat1:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookuplb.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookuplb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdatetimelookupdb } + +procedure tdbdatetimelookupdb.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookupdb.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptydatetime; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= getfloatlookupvalue(abm); + end; + end; +end; + +function tdbdatetimelookupdb.lookuptext(const abm: bookmarkdataty): msestring; +var + dat1: tdatetime; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + dat1:= getfloatlookupvalue(abm); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookupdb.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookupdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= datetimefields; +end; + +{ tdatetimelookup64db } + +procedure tdbdatetimelookup64db.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookup64db.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptydatetime; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= getfloatlookupvalue(abm); + end; + end; +end; + +function tdbdatetimelookup64db.lookuptext(const abm: bookmarkdataty): msestring; +var + dat1: tdatetime; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + dat1:= getfloatlookupvalue(abm); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookup64db.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookup64db.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= datetimefields; +end; + +{ tdatetimelookupstrdb } + +procedure tdbdatetimelookupstrdb.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookupstrdb.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptydatetime; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= getfloatlookupvalue(abm); + end; + end; +end; + +function tdbdatetimelookupstrdb.lookuptext(const abm: bookmarkdataty): msestring; +var + dat1: tdatetime; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + dat1:= getfloatlookupvalue(abm); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookupstrdb.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookupstrdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= datetimefields; +end; + +{ tdbstringlookup64lb } + +procedure tdbstringlookup64lb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= ''; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbstringlookup64lb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; +end; + +function tdbstringlookup64lb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +{ tdbintegerlookup64lb } + +constructor tdbintegerlookup64lb.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookup64lb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= 0; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.integervaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbintegerlookup64lb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= msestring(intvaluetostr(flookupbuffer.integervaluephys( + flookupvaluefieldno,aindex),fbase,fbitcount)); + end; +end; + +procedure tdbintegerlookup64lb.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookup64lb.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookup64lb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +{ tdbreallookup64lb } + +constructor tdbreallookup64lb.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookup64lb.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookup64lb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptyreal; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex), + valuerange,valuestart); + end; + end; +end; + +function tdbreallookup64lb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= realtytostring(flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex), + fformat); + end; +end; + +procedure tdbreallookup64lb.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookup64lb.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +procedure tdbreallookup64lb.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tdbreallookup64lb.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + + +function tdbreallookup64lb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdatetimelookup64lb } + +procedure tdbdatetimelookup64lb.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookup64lb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptydatetime; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbdatetimelookup64lb.lookuptext(const aindex: integer): msestring; +var + dat1: tdatetime; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + dat1:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookup64lb.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookup64lb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdbstringlookupstrlb } + +function tdbstringlookupstrlb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; +end; + +procedure tdbstringlookupstrlb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= ''; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbstringlookupstrlb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +{ tdbintegerlookupstrlb } + +constructor tdbintegerlookupstrlb.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookupstrlb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= 0; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.integervaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbintegerlookupstrlb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= msestring(intvaluetostr(flookupbuffer.integervaluephys( + flookupvaluefieldno,aindex),fbase,fbitcount)); + end; +end; + +procedure tdbintegerlookupstrlb.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookupstrlb.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookupstrlb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +{ tdbreallookupstrlb } + +constructor tdbreallookupstrlb.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookupstrlb.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookupstrlb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptyreal; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex), + valuerange,valuestart); + end; + end; +end; + +function tdbreallookupstrlb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= realtytostring(flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex), + fformat); + end; +end; + +procedure tdbreallookupstrlb.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookupstrlb.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +procedure tdbreallookupstrlb.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tdbreallookupstrlb.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + +function tdbreallookupstrlb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdatetimelookupstrlb } + +procedure tdbdatetimelookupstrlb.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookupstrlb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptydatetime; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbdatetimelookupstrlb.lookuptext(const aindex: integer): msestring; +var + dat1: tdatetime; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + dat1:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookupstrlb.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookupstrlb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdblookupdb } +{ +constructor tdblookupdb.create(aowner: tcomponent); +begin + inherited; +end; +} +function tdblookupdb.getdatalink: tlookupdbdispfielddatalink; +begin + result:= tlookupdbdispfielddatalink(fdatalink); +end; + +procedure tdblookupdb.setdatalink(const avalue: tlookupdbdispfielddatalink); +begin + inherited setdatalink(avalue); +end; + +{ tlookupdatalink } + +procedure tlookupdatalink.updatefields; +var + int1: integer; +begin + inherited; + fcanlookup:= false; + if active and (fkeyfieldname <> '') then begin + fkeyfield:= datasource.dataset.fieldbyname(fkeyfieldname); + flookupindexnum:= -1; + if dataset is tmsebufdataset then begin + with tmsebufdataset(dataset).indexlocal do begin + for int1:= 0 to count-1 do begin + with items[int1] do begin + if (fields.count > 0) and + sametext(fields[0].fieldname,fkeyfieldname) then begin + flookupindexnum:= int1; + break; + end; + end; + end; + end; + end; + if flookupindexnum < 0 then begin + databaseerror(dataset.name+': no loookup index for keyfield "'+ + fkeyfield.fieldname+'".'); + end; + fcanlookup:= true; + end + else begin + fkeyfield:= nil; + end; +end; + +procedure tlookupdatalink.activechanged; +begin + if not active then begin + fcanlookup:= false; + end; + inherited; + fdisplink.lookupchange; +end; + +procedure tlookupdatalink.dataevent(event: tdataevent; info: ptrint); +begin + inherited; + if event = tdataevent(de_modified) then begin + fdisplink.lookupchange; + end; +end; + +procedure tlookupdatalink.fieldchanged; +begin + inherited; + fdisplink.lookupchange; +end; + +{ tlookupdbdispfielddatalink } + +constructor tlookupdbdispfielddatalink.create( + const aowner: tcustomdataedit; const adatatype: lookupdatatypety; + const intf: idblookupdbdispfieldlink); +begin + flookupdatalink:= tlookupdatalink.create; + flookupdatalink.fdisplink:= self; + inherited create(aowner,adatatype,intf); +end; + +destructor tlookupdbdispfielddatalink.destroy; +begin + flookupdatalink.free; + inherited; +end; + +procedure tlookupdbdispfielddatalink.setlookupkeyfield(const avalue: string); +begin + with flookupdatalink do begin + if fkeyfieldname <> avalue then begin + fkeyfieldname:= avalue; + updatefields; + lookupchange; + end; + end; +end; + +procedure tlookupdbdispfielddatalink.setlookupvaluefield(const avalue: string); +begin + flookupdatalink.fieldname:= avalue; +end; + +function tlookupdbdispfielddatalink.getlookupkeyfield: string; +begin + result:= flookupdatalink.fkeyfieldname; +end; + +function tlookupdbdispfielddatalink.getlookupvaluefield: string; +begin + result:= flookupdatalink.fieldname; +end; + +function tlookupdbdispfielddatalink.getlookupdatasource: tdatasource; +begin + result:= flookupdatalink.datasource; +end; + +procedure tlookupdbdispfielddatalink.setlookupdatasource(const avalue: tdatasource); +begin + flookupdatalink.datasource:= avalue; +end; + +function tlookupdbdispfielddatalink.getintegerlookupvalue( + const abm: bookmarkdataty): integer; +begin + result:= 0; + with flookupdatalink do begin + if (abm.recordpo <> nil) and fieldactive and fcanlookup then begin + result:= tmsebufdataset(dataset).currentbmasinteger[field,abm]; + end; + end; +end; + +function tlookupdbdispfielddatalink.getstringlookupvalue( + const abm: bookmarkdataty): msestring; +begin + result:= ''; + with flookupdatalink do begin + if (abm.recordpo <> nil) and fieldactive and fcanlookup then begin + result:= tmsebufdataset(dataset).currentbmasmsestring[field,abm]; + end; + end; +end; + +function tlookupdbdispfielddatalink.getfloatlookupvalue( + const abm: bookmarkdataty): double; +begin + result:= emptyreal; + with flookupdatalink do begin + if (abm.recordpo <> nil) and fieldactive and fcanlookup then begin + result:= tmsebufdataset(dataset).currentbmasfloat[field,abm]; + end; + end; +end; + +function tlookupdbdispfielddatalink.getdataset(const aindex: integer): tdataset; +begin + result:= nil; + case aindex of + 0: begin + result:= inherited getdataset(aindex); + end; + 1,2: begin + result:= flookupdatalink.dataset; + end; + end; +end; + +procedure tlookupdbdispfielddatalink.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + inherited; + setlength(apropertynames,3); + apropertynames[1]:= 'lookupkeyfield'; + apropertynames[2]:= 'lookupvaluefield'; + setlength(afieldtypes,3); + afieldtypes[1]:= afieldtypes[0]; //same as datafield + afieldtypes[2]:= idblookupdbdispfieldlink(fintf).getlookupvaluefieldtypes; +end; + +{ tdblookup32db } + +procedure tdblookup32db.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= int32fields; +end; + +function tdblookup32db.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookup32dbdispfielddatalink.create(self,ldt_int32, + idblookupdbdispfieldlink(self)); +end; + +{ tdblookup64db } + +procedure tdblookup64db.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= int64fields; +end; + +function tdblookup64db.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookup64dbdispfielddatalink.create(self,ldt_int64, + idblookupdbdispfieldlink(self)); +end; + +{ tdblookupstrdb } + +procedure tdblookupstrdb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= charfields; +end; + +function tdblookupstrdb.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookupstrdbdispfielddatalink.create(self,ldt_string, + idblookupdbdispfieldlink(self)); +end; + +{ tdblookup } + +{ tlookup32dbdispfielddatalink } + +function tlookup32dbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: integer); + var + bm1: bookmarkdataty; + begin + result:= ''; + with flookupdatalink do begin + if fcanlookup and (field <> nil) and + tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([akey],[],bm1,false,false,true) then begin + result:= idblookupdbdispfieldlink(fintf).lookuptext(bm1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(integer(data)); + end; + end; +end; + +procedure tlookup32dbdispfielddatalink.updatelookupvalue; +var + bm1: bookmarkdataty; +begin + bm1.recordpo:= nil; + with flookupdatalink do begin + if fcanlookup then begin + if not tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([fkey],[],bm1,false,false,true) then begin + bm1.recordpo:= nil; + end; + end; + end; + idblookupdbdispfieldlink(fintf).setlookupvalue(bm1); +end; + +function tlookup32dbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getintegerbuffer(field,arow); +end; + +procedure tlookup32dbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= field.asinteger; +end; + +{ tlookup64dbdispfielddatalink } + +function tlookup64dbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: int64); + var + bm1: bookmarkdataty; + begin + result:= ''; + with flookupdatalink do begin + if fcanlookup and (field <> nil) and + tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([akey],[],bm1,false,false,true) then begin + result:= idblookupdbdispfieldlink(fintf).lookuptext(bm1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(int64(data)); + end; + end; +end; + +procedure tlookup64dbdispfielddatalink.updatelookupvalue; +var + bm1: bookmarkdataty; +begin + bm1.recordpo:= nil; + with flookupdatalink do begin + if not fisnull and fcanlookup then begin + if not tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([fkey],[],bm1,false,false,true) then begin + bm1.recordpo:= nil; + end; + end; + end; + idblookupdbdispfieldlink(fintf).setlookupvalue(bm1); +end; + +function tlookup64dbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getint64buffer(field,arow); +end; + +procedure tlookup64dbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= field.aslargeint; +end; + +{ tlookupstrdbdispfielddatalink } + +function tlookupstrdbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: msestring); + var + bm1: bookmarkdataty; + begin + result:= ''; + with flookupdatalink do begin + if fcanlookup and (field <> nil) and + tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([akey],[],bm1,false,false,true) then begin + result:= idblookupdbdispfieldlink(fintf).lookuptext(bm1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(msestring(data)); + end; + end; +end; + +procedure tlookupstrdbdispfielddatalink.updatelookupvalue; +var + bm1: bookmarkdataty; +begin + bm1.recordpo:= nil; + with flookupdatalink do begin + if not fisnull and fcanlookup then begin + if not tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([fkey],[],bm1,false,false,true) then begin + bm1.recordpo:= nil; + end; + end; + end; + idblookupdbdispfieldlink(fintf).setlookupvalue(bm1); +end; + +function tlookupstrdbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getstringbuffer(field,arow); +end; + +procedure tlookupstrdbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= asmsestring; +end; + +{ tlookuplbdispfielddatalink } + +constructor tlookuplbdispfielddatalink.create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idblookuplbdispfieldlink); +begin + fobjectlinker:= tobjectlinker.create(iobjectlink(self), + {$ifdef FPC}@{$endif}objectevent); + inherited create(aowner,adatatype,intf); +end; + +destructor tlookuplbdispfielddatalink.destroy; +begin + fobjectlinker.free; + inherited; +end; + +function tlookuplbdispfielddatalink.getlbdatakind(const apropname: string): lbdatakindty; +begin + if apropname = 'lookupkeyfieldno' then begin + result:= getkeylbdatakind; + end + else begin + result:= idblookuplbdispfieldlink(fintf).getdatalbdatakind; + end; +end; + +function tlookuplbdispfielddatalink.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +procedure tlookuplbdispfielddatalink.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + if avalue <> flookupbuffer then begin + fobjectlinker.setlinkedvar(iobjectlink(self),avalue, + tmsecomponent(flookupbuffer)); + lookupchange; + end; +end; + +procedure tlookuplbdispfielddatalink.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + lookupchange; + end; +end; + +procedure tlookuplbdispfielddatalink.link(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + fobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tlookuplbdispfielddatalink.unlink(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil); +begin + fobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tlookuplbdispfielddatalink.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + fobjectlinker.objevent(sender,event); +end; + +function tlookuplbdispfielddatalink.getinstance: tobject; +begin + result:= self; +end; + +procedure tlookuplbdispfielddatalink.setlookupkeyfieldno(const avalue: lookupbufferfieldnoty); +begin + if flookupkeyfieldno <> avalue then begin + flookupkeyfieldno:= avalue; + lookupchange; + end; +end; + +procedure tlookuplbdispfielddatalink.setlookupvaluefieldno(const avalue: lookupbufferfieldnoty); +begin + if flookupvaluefieldno <> avalue then begin + flookupvaluefieldno:= avalue; + lookupchange; + end; +end; + +{ tlookup32lbdispfielddatalink } + +procedure tlookup32lbdispfielddatalink.updatelookupvalue; +var + int1: integer; +begin + int1:= -1; + if not fisnull and (flookupbuffer <> nil) then begin + flookupbuffer.findphys(flookupkeyfieldno,fkey,int1); + end; + idblookuplbdispfieldlink(fintf).setlookupvalue(int1); +end; + +function tlookup32lbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: integer); + var + int1: integer; + begin + result:= ''; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,akey,int1) then begin + result:= idblookuplbdispfieldlink(fintf).lookuptext(int1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(integer(data)); + end; + end; +end; + +function tlookup32lbdispfielddatalink.getkeylbdatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +procedure tlookup32lbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= field.asinteger; +end; + +function tlookup32lbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getintegerbuffer(field,arow); +end; + +{ tlookup64lbdispfielddatalink } + +procedure tlookup64lbdispfielddatalink.updatelookupvalue; +var + int1: integer; +begin + int1:= -1; + if not fisnull and (flookupbuffer <> nil) then begin + flookupbuffer.findphys(flookupkeyfieldno,fkey,int1); + end; + idblookuplbdispfieldlink(fintf).setlookupvalue(int1); +end; + +function tlookup64lbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: int64); + var + int1: integer; + begin + result:= ''; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,akey,int1) then begin + result:= idblookuplbdispfieldlink(fintf).lookuptext(int1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(int64(data)); + end; + end; +end; + +function tlookup64lbdispfielddatalink.getkeylbdatakind: lbdatakindty; +begin + result:= lbdk_int64; +end; + +procedure tlookup64lbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= field.aslargeint; +end; + +function tlookup64lbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getint64buffer(field,arow); +end; + +{ tlookupstrlbdispfielddatalink } + +procedure tlookupstrlbdispfielddatalink.updatelookupvalue; +var + int1: integer; +begin + int1:= -1; + if not fisnull and (flookupbuffer <> nil) then begin + flookupbuffer.findphys(flookupkeyfieldno,fkey,int1,false); + end; + idblookuplbdispfieldlink(fintf).setlookupvalue(int1); +end; + +function tlookupstrlbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: msestring); + var + int1: integer; + begin + result:= ''; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,akey,int1,true) then begin + result:= idblookuplbdispfieldlink(fintf).lookuptext(int1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(msestring(data)); + end; + end; +end; + +function tlookupstrlbdispfielddatalink.getkeylbdatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +procedure tlookupstrlbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= asmsestring; +end; + +function tlookupstrlbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getstringbuffer(field,arow); +end; + +{ tdblookuplb } + +procedure tdblookuplb.readlookupkeyfieldno(reader: treader); +begin + tlookuplbdispfielddatalink(fdatalink).lookupkeyfieldno:= reader.readinteger; +end; + +procedure tdblookuplb.readlookupvaluefieldno(reader: treader); +begin + tlookuplbdispfielddatalink(fdatalink).lookupvaluefieldno:= reader.readinteger; +end; + +procedure tdblookuplb.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('lookupkeyfieldno', + {$ifdef FPC}@{$endif}readlookupkeyfieldno,nil,false); + filer.defineproperty('lookupvaluefieldno', + {$ifdef FPC}@{$endif}readlookupvaluefieldno,nil,false); +end; + + +function tdblookuplb.getlookupbuffer: tcustomlookupbuffer; +begin + result:= nil; +end; + +procedure tdblookuplb.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + tlookuplbdispfielddatalink(fdatalink).lookupbuffer:= avalue; +end; + +function tdblookuplb.getdatalink: tlookuplbdispfielddatalink; +begin + result:= tlookuplbdispfielddatalink(fdatalink); +end; + +procedure tdblookuplb.setdatalink(const avalue: tlookuplbdispfielddatalink); +begin + inherited setdatalink(avalue); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefb3connection.pas b/mseide-msegui/lib/common/db/msefb3connection.pas new file mode 100644 index 0000000..3ac8b52 --- /dev/null +++ b/mseide-msegui/lib/common/db/msefb3connection.pas @@ -0,0 +1,1981 @@ +{ MSEgui Copyright (c) 2016-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +// +// todo: - prepare-less execute and openCursor (needs FB-optimisation) +// - move dbcontroller interface to tcustomsqlconnection +// +unit msefb3connection; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,firebird,msqldb,msestrings,msetypes,mdb,msedb,msedatabase, + sysutils,msefirebird,msedbevents,msesystypes; + +const + SQL_DIALECT_V6 = 3; + +type + pimessagemetadata = ^imessagemetadata; + + fbconnectionoptionty = (fbo_sqlinfo); + fbconnectionoptionsty = set of fbconnectionoptionty; + + tfb3connection = class; + + tfbtrans = class(tsqlhandle) + protected + fconnection: tfb3connection; + ftransaction: itransaction; + public + constructor create(const aconnection: tfb3connection); + destructor destroy(); override; + end; + + cursorstatety = (cs_hasstatement); + cursorstatesty = set of cursorstatety; + + pfbfieldinfoty = ^fbfieldinfoty; + fetchfuncty = procedure(const info: pfbfieldinfoty; const dest: pointer); + + tfbcursor = class; + + fbfieldinfoty = record + buffer: pointer; + name: string; + _type: card32; + scale: int32; + offset: card32; + nulloffset: int32; //-1 = none + fetchfunc: fetchfuncty; + _cursor: tfbcursor; + datatype: tfieldtype; + size: int32; +// precision: int32; + buffersizead: pint32; //temp + end; + + fbfieldinfoarty = array of fbfieldinfoty; + + tfbcursor = class(tsqlcursor) + protected + fconnection: tfb3connection; + fparambinding: tparambinding; + fstatement: istatement; + fstatementflags: card32; + fempty: boolean; + ffirstfetch: boolean; //set for execute() if there is outputdata + fresultset: iresultset; + fcursorstate: cursorstatesty; + ffieldinfos: fbfieldinfoarty; + frowbuffer: string; + public + constructor create(const aowner: icursorclient; + const aconnection: tfb3connection); + destructor destroy(); override; + procedure close() override; + end; + + fbeventinfoty = record + event: tdbevent; + name: string; + count: integer; + countbefore: card32; + end; + pfbeventinfoty = ^fbeventinfoty; + + tfbeventcallback = class(ieventcallbackimpl) + private + frefcount: int32; + protected + fowner: tfb3connection; + fmutex: mutexty; + ffired: boolean; + freleased: boolean; + public + constructor create(const aowner: tfb3connection); + destructor destroy(); override; + procedure addRef() override; + function release(): Integer override; + procedure eventCallbackFunction(length: Cardinal; events: BytePtr) override; + procedure destroylocked(); + procedure storestate(); //copy current event counts to feventitems + procedure queueevents(const first: boolean); //must be locked + end; + + paramblockkindty = (pbk_database,pbk_transaction); + paramblockvaluekindty = (pbvk_none,pbvk_int,pbvk_str); + paraminfoty = record + id: int32; + name: string; + valuekind: paramblockvaluekindty; + end; + pparaminfoty = ^paraminfoty; + + tfb3connection = class(tcustomsqlconnection,iblobconnection, + idbevent,idbeventcontroller) + private + fdialect: integer; + flasterrormessage: msestring; + flastsqlcode: int32; + foptions: fbconnectionoptionsty; + function getblobstream(const acursor: tsqlcursor; const blobid: isc_quad; + const forstring: boolean = false): tmemorystream; + function getblobstring(const acursor: tsqlcursor; + const blobid: isc_quad): string; + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + fapi: fbapity; + fattachment: iattachment; + feventcallback: tfbeventcallback; + feventcontroller: tdbeventcontroller; + feventitems: array of fbeventinfoty; + fevents: ievents; + flistencount: int32; + feventcount: int32; + feventlength: int32; + feventbuffer: pbyte; + feventcountbuffer: array of ULONG; +// procedure iniapi(); +// procedure finiapi(); + function getpb(const akind: paramblockkindty): ixpbbuilder; + function buildpb(const akind: paramblockkindty; + const ainfo: pparaminfoty; const acount: int32; + const aparams: tstringlist; + const force: boolean): ixpbbuilder; + procedure clearstatus(); inline; + function statusok(): boolean; inline; + procedure checkstatus(const aerrormessage: msestring); + procedure dointernalconnect override; + procedure dointernaldisconnect override; + + function allocatetransactionhandle : tsqlhandle override; + function gettransactionhandle(trans : tsqlhandle): pointer override; + + function startdbtransaction(const trans : tsqlhandle; + const aparams : tstringlist) : boolean override; + function commit(trans : tsqlhandle) : boolean override; + function rollback(trans : tsqlhandle) : boolean override; + procedure internalcommitretaining(trans : tsqlhandle) override; + procedure internalrollbackretaining(trans : tsqlhandle) override; + + procedure cursorclose(const cursor: tfbcursor); + procedure updateresultmetadata(const acursor: tfbcursor; + const outmetadata: pimessagemetadata); + procedure internalexecute(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const aparams : tmseparams; + const autf8: boolean) override; +{ not ready, needs FB3 improvement + procedure internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; + const asql: string; const origsql: msestring; + const aparams: tmseparams) override; +} + procedure updateindexdefs(var indexdefs : tindexdefs; + const atablename : string; const acursor: tsqlcursor) override; + function getschemainfosql(schematype : tschematype; + schemaobjectname, schemapattern : msestring) : msestring override; + + function createblobstream(const field: tfield; const mode: tblobstreammode; + const acursor: tsqlcursor): tstream; override; + function getblobdatasize: integer; override; + + procedure updateevents(const aerrormessage: msestring); + procedure clearevents(); + procedure loaded() override; + //idbcontroller + function readsequence(const sequencename: string): msestring override; + function sequencecurrvalue(const sequencename: string): msestring override; + function writesequence(const sequencename: string; + const avalue: largeint): msestring override; + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); + overload; + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); + //idbevent + procedure listen(const sender: tdbevent); + procedure unlisten(const sender: tdbevent); + procedure fire(const sender: tdbevent); + //idbeventcontroller + function getdbevent(var aname: string; var aid: int64): boolean; + //false if none + procedure dolisten(const sender: tdbevent); + procedure dounlisten(const sender: tdbevent); + //idbcontroller + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure createdatabase(const asql: ansistring); + function allocatecursorhandle(const aowner: icursorclient; + const aname: ansistring): tsqlcursor override; + procedure deallocatecursorhandle(var cursor : tsqlcursor) override; + procedure freefldbuffers(cursor : tsqlcursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams) override; + procedure unpreparestatement(cursor : tsqlcursor) override; + procedure addfielddefs(const cursor: tsqlcursor; + const fielddefs : tfielddefs) override; + function fetch(cursor : tsqlcursor) : boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //zero based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //zero based + function version: msestring; + property lasterrormessage: msestring read flasterrormessage; + property lastsqlcode: int32 read flastsqlcode; + published + property dialect: integer read fdialect write fdialect + default sql_dialect_v6; + property options: fbconnectionoptionsty read foptions + write foptions default []; + property Transaction; + property transactionwrite; + property CharSet; + property HostName; + property controller; + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + property Password; + property UserName; + property Role; + property ongetcredentials; + property afterconnect; + property beforedisconnect; + end; + + efberror = class(econnectionerror) + private + fgdscode: ptrint; + public + constructor create(const asender: tfb3connection; + const astatus: istatus; const aerrormessage: msestring); + property gdscode: ptrint read fgdscode; + end; + +implementation +uses + dbconst,msefbinterface,msefbutils,msesqldb,msebufdataset,msedate,msefloattostr, + msebits,msesysintf1,msearrayutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + textblobtypes = [ftmemo,ftwidememo]; + +{ tfbeventcallback } + +constructor tfbeventcallback.create(const aowner: tfb3connection); +begin + fowner:= aowner; + sys_mutexcreate(fmutex); + inherited create(); +end; + +destructor tfbeventcallback.destroy(); +begin + inherited; + sys_mutexdestroy(fmutex); +end; + +procedure tfbeventcallback.addRef(); +begin + sys_mutexlock(fmutex); + inc(frefcount); + sys_mutexunlock(fmutex); +end; + +function tfbeventcallback.release(): Integer; +begin + sys_mutexlock(fmutex); + dec(frefcount); + result:= frefcount; + if frefcount = 0 then begin + destroy(); + exit; + end; + sys_mutexunlock(fmutex); +end; + +procedure tfbeventcallback.eventCallbackFunction(length: Cardinal; + events: BytePtr); +var + i1,i2,i3: int32; +begin + sys_mutexlock(fmutex); + if not freleased and (fowner <> nil) and //owner alive + (length > 0) then begin + //no call from queevents() + with fowner do begin + i3:= feventcount; + isc_event_counts(pointer(feventcountbuffer),length,feventbuffer,events); + for i1:= 0 to high(feventcountbuffer) do begin + i2:= feventcountbuffer[i1]; + with feventitems[i1] do begin + if count < 0 then begin //first + count:= 0; + i2:= 0; + end + else begin + count:= count + i2; + end; + end; + i3:= i3 + i2; + end; + feventcount:= i3; + feventcontroller.eventinterval:= -1; //restart timer + end; + ffired:= true; + end; + sys_mutexunlock(fmutex); +end; + +procedure tfbeventcallback.destroylocked(); +var + i1: int32; +begin + fowner.feventcallback:= nil; + freleased:= true; + if (fowner <> nil) then begin + with fowner do begin + if fevents <> nil then begin + fevents.release(); + end; + fevents:= nil; + end; + end; + fowner:= nil; + i1:= frefcount; + release(); + if i1 <> 1 then begin //destroyed otherwise + sys_mutexunlock(fmutex); + end; +end; + +type + countbufferty = array[0..3] of byte; + +procedure tfbeventcallback.storestate(); + //copy current event counts to feventitems +var + i1: int32; + po1: pbyte; + bu1: countbufferty; +begin + po1:= fowner.feventbuffer + 1; //first name + for i1:= 0 to high(fowner.feventitems) do begin + po1:= po1 + po1^ + 1; //name length + bu1[0]:= po1^; + inc(po1); + bu1[1]:= po1^; + inc(po1); + bu1[2]:= po1^; + inc(po1); + bu1[3]:= po1^; + inc(po1); + fowner.feventitems[i1].countbefore:= card32(bu1); //endianess? + end; +end; + +procedure tfbeventcallback.queueevents(const first: boolean); +var + i1: int32; + po1: pbyte; + bu1: countbufferty; +begin + ffired:= false; + with fowner do begin + if fevents <> nil then begin + fevents.release(); + end; + fevents:= fattachment.queevents( + fapi.status,feventcallback,feventlength,feventbuffer); + if first then begin //restore count values + po1:= fowner.feventbuffer + 1; //first name + for i1:= 0 to high(fowner.feventitems) do begin + bu1:= countbufferty(fowner.feventitems[i1].countbefore); //endianess? + po1:= po1 + po1^ + 1; //name length + po1^:= bu1[0]; + inc(po1); + po1^:= bu1[1]; + inc(po1); + po1^:= bu1[2]; + inc(po1); + po1^:= bu1[3]; + inc(po1); + end; + end; + end; +end; + +{ efberror } + +constructor efberror.create(const asender: tfb3connection; + const astatus: istatus; const aerrormessage: msestring); +var + str1: string; + msg1: msestring; + po1: nativeintptr; + err1: integer; +begin + str1:= formatstatus(astatus); + msg1:= aerrormessage; + if str1 <> '' then begin + msg1:= msg1 + lineend + msestring(str1); + end; + po1:= astatus.geterrors; + err1:= 0; + if po1 <> nil then begin + err1:= gds__sqlcode(po1); + if po1[0] = isc_arg_gds then begin + fgdscode:= po1[1]; + end; + end; + if asender <> nil then begin + asender.flasterrormessage:= msg1; + asender.flastsqlcode:= err1; + end; + inherited create(asender,ansistring(msg1),msg1,err1); +end; + +{ tfb3connection } + +constructor tfb3connection.create(aowner: tcomponent); +begin + fdialect:= sql_dialect_v6; + feventcontroller:= tdbeventcontroller.create(idbeventcontroller(self)); + feventcontroller.eventinterval:= -1; //event driven + inherited; + FConnOptions := FConnOptions + [sco_SupportParams,sco_forceparams, + sco_nounprepared]; + //unprepared not yet possible because FB3 provides + //no output messagemetadata for execute() +end; + +destructor tfb3connection.destroy(); +begin + inherited; + feventcontroller.free; +end; + +procedure tfb3connection.createdatabase(const asql: ansistring); +var + inited1: boolean; + bo1: boolean; + attachment1: iattachment; +begin + inited1:= fapi.master = nil; + if inited1 then begin + inifbapi(fapi); + end; + try + clearstatus(); + attachment1:= fapi.util.executecreatedatabase(fapi.status,length(asql), + pchar(asql),fdialect,@bo1); + if attachment1 <> nil then begin + attachment1.release(); + end; + checkstatus('createdatabase'); + finally + if inited1 then begin + finifbapi(fapi); + end; + end; +end; +{ +procedure tfb3connection.iniapi(); +begin + initializefirebird([],true); + with fapi do begin + if master = nil then begin + master:= fb_get_master_interface(); + end; + if status = nil then begin + status:= master.getstatus(); + end; + if provider = nil then begin + provider:= master.getdispatcher(); + end; + if util = nil then begin + util:= master.getutilinterface(); + end; + end; +end; + +procedure tfb3connection.finiapi(); +begin + with fapi do begin + util:= nil; + provider:= nil; + if status <> nil then begin + status.dispose(); + status:= nil; + end; + master:= nil; + end; +end; +} +procedure tfb3connection.clearstatus(); inline; +begin + fapi.status.init(); +end; + +function tfb3connection.statusok(): boolean; inline; +begin + result:= fapi.status.getstate() and istatus.state_errors = 0 +end; + +procedure tfb3connection.checkstatus(const aerrormessage: msestring); +begin + if fapi.status.getstate() and istatus.state_errors <> 0 then begin + raise efberror.create(self,fapi.status,aerrormessage); + end; +end; + +function tfb3connection.getpb(const akind: paramblockkindty): ixpbbuilder; +var + kind1: card32; +begin + case akind of + pbk_database: kind1:= ixpbbuilder.DPB; + pbk_transaction: kind1:= ixpbbuilder.TPB; + else begin + raise exception.create('Internalerror 20160924A'); + end; + end; + result:= fapi.util.getxpbbuilder(fapi.status,kind1,nil,0); +end; + +const + paramblockkindnames: array[paramblockkindty] of string = ( +// pbk_database,pbk_transaction + 'database', 'transaction'); + +function tfb3connection.buildpb(const akind: paramblockkindty; + const ainfo: pparaminfoty; const acount: int32; + const aparams: tstringlist; const force: boolean): ixpbbuilder; + + procedure paramerror(const s: string); + begin + raise econnectionerror.create(self, + 'Invalid '+paramblockkindnames[akind]+ + ' parameter "'+s+'"','',0); + end; //paramerror + +var + i1,i2,i3: int32; + s1,s2: string; + po1: pchar; +label + next; + +begin + result:= nil; + if (aparams.count > 0) or force then begin + result:= getpb(akind); + for i1:= 0 to aparams.count - 1 do begin + s1:= aparams[i1]; + if s1 <> '' then begin + po1:= strscan(pointer(s1),'='); + if po1 <> nil then begin + s2:= copy(s1,po1-pchar(pointer(s1))+2,bigint); + s1:= psubstr(pointer(s1),po1); + end; + s1:= trim(s1); + for i2:= 0 to acount-1 do begin + with ainfo[i2] do begin + if s1 = name then begin + if po1 <> nil then begin + case valuekind of + pbvk_int: begin + if trystrtoint(trim(s2),i3) then begin + result.insertint(fapi.status,id,i3); + goto next; + end + else begin + paramerror(aparams[i1]); + end; + end; + pbvk_str: begin + result.insertstring(fapi.status,id,pchar(unquotestring(s2,'"'))); + goto next; + end; + else begin + paramerror(aparams[i1]); + end; + end; + end; + result.inserttag(fapi.status,id); + goto next; + end; + end; + end; + paramerror(aparams[i1]); + end; +next: + end; + end; +end; + +procedure tfb3connection.dointernalconnect(); +const + utf8name = 'UTF8'; + paramconsts: array[0..3] of paraminfoty = + ((id: isc_dpb_user_name; name: 'isc_dpb_user_name'; + valuekind: pbvk_str), + (id: isc_dpb_password; name: 'isc_dpb_password'; + valuekind: pbvk_str), + (id: isc_dpb_lc_ctype; name: 'isc_dpb_lc_ctype'; + valuekind: pbvk_str), + (id: isc_dpb_sql_role_name; name: 'isc_dpb_sql_role_name'; + valuekind: pbvk_str) + ); +var + pb: ixpbbuilder; + databasename1: msestring; + u,p: msestring; + u1,p1: string; +begin + flistencount:= 0; + inifbapi(fapi); + try + inherited dointernalconnect; + pb:= buildpb(pbk_database,@paramconsts,length(paramconsts),params,true); + pb.inserttag(fapi.status,isc_dpb_utf8_filename); + getcredentials(u,p); + if u <> '' then begin + u1:= stringtoutf8(u); + pb.insertstring(fapi.status,isc_dpb_user_name,pointer(u1)); + stringsafefree(u1,false); + end; + if p <> '' then begin + p1:= stringtoutf8(p); + pb.insertstring(fapi.status,isc_dpb_password,pointer(p1)); + stringsafefree(p1,false); + end; + freecredentials(u,p); //fill with #0 before release + if role <> '' then begin + pb.insertstring(fapi.status,isc_dpb_sql_role_name, + pointer(stringtoutf8(role))); + end; + if charset <> '' then begin + pb.insertstring(fapi.status,isc_dpb_lc_ctype,pointer(stringtoutf8(charset))); + end + else begin + if dbo_utf8 in fcontroller.options then begin + pb.insertstring(fapi.status,isc_dpb_lc_ctype,utf8name); + end; + end; + if hostname <> '' then begin + databasename1:= msestring(hostname)+':'+ fdatabasename; + end + else begin + databasename1:= fdatabasename; + end; + fattachment:= nil; + clearstatus(); + fattachment:= fapi.provider.attachdatabase(fapi.status, + pchar(stringtoutf8ansi(databasename1)), + pb.getbufferlength(fapi.status),pb.getbuffer(fapi.status)); + pb.dispose(); + checkstatus('dointernalconnect'); + fattachment.addref(); + except + finifbapi(fapi); +// releasefirebird; + raise; + end; + feventcontroller.connect(); +end; + +procedure tfb3connection.dointernaldisconnect; +begin + inherited; + if fattachment <> nil then begin + fattachment.detach(fapi.status); + fattachment.release(); + fattachment:= nil; + end; + clearevents(); + feventcontroller.disconnect(); + finifbapi(fapi); +end; + +function tfb3connection.allocatetransactionhandle: tsqlhandle; +begin + result:= tfbtrans.create(self); +end; + +function tfb3connection.gettransactionhandle(trans: tsqlhandle): pointer; +begin + result:= tfbtrans(trans).ftransaction; +end; + +function tfb3connection.startdbtransaction(const trans: tsqlhandle; + const aparams: tstringlist): boolean; + +const + paramconsts: array[0..20] of paraminfoty = + ((id: isc_tpb_write; name: 'isc_tpb_write'; + valuekind: pbvk_none), + (id: isc_tpb_read; name: 'isc_tpb_read'; + valuekind: pbvk_none), + (id: isc_tpb_consistency; name: 'isc_tpb_consistency'; + valuekind: pbvk_none), + (id: isc_tpb_concurrency; name: 'isc_tpb_concurrency'; + valuekind: pbvk_none), + (id: isc_tpb_read_committed; name: 'isc_tpb_read_committed'; + valuekind: pbvk_none), + (id: isc_tpb_rec_version; name: 'isc_tpb_rec_version'; + valuekind: pbvk_none), + (id: isc_tpb_no_rec_version; name: 'isc_tpb_no_rec_version'; + valuekind: pbvk_none), + (id: isc_tpb_wait; name: 'isc_tpb_wait'; + valuekind: pbvk_none), + (id: isc_tpb_nowait; name: 'isc_tpb_nowait'; + valuekind: pbvk_none), + (id: isc_tpb_shared; name: 'isc_tpb_shared'; + valuekind: pbvk_none), + (id: isc_tpb_protected; name: 'isc_tpb_protected'; + valuekind: pbvk_none), + (id: isc_tpb_exclusive; name: 'isc_tpb_exclusive'; + valuekind: pbvk_none), + (id: isc_tpb_lock_read; name: 'isc_tpb_lock_read'; + valuekind: pbvk_none), + (id: isc_tpb_lock_write; name: 'isc_tpb_lock_write'; + valuekind: pbvk_none), + (id: isc_tpb_verb_time; name: 'isc_tpb_verb_time'; + valuekind: pbvk_none), + (id: isc_tpb_commit_time; name: 'isc_tpb_commit_time'; + valuekind: pbvk_none), + (id: isc_tpb_ignore_limbo; name: 'isc_tpb_ignore_limbo'; + valuekind: pbvk_none), + (id: isc_tpb_autocommit; name: 'isc_tpb_autocommit'; + valuekind: pbvk_none), + (id: isc_tpb_restart_requests; name: 'isc_tpb_restart_requests'; + valuekind: pbvk_none), + (id: isc_tpb_no_auto_undo; name: 'isc_tpb_no_auto_undo'; + valuekind: pbvk_none), + (id: isc_tpb_lock_timeout; name: 'isc_tpb_lock_timeout'; + valuekind: pbvk_int) + ); +var + pb: ixpbbuilder; + pbbuffer: pointer; + pblen: int32; +begin + result := false; + pb:= buildpb(pbk_transaction,@paramconsts,length(paramconsts),aparams,false); + + if pb <> nil then begin + pblen:= pb.getbufferlength(fapi.status); + pbbuffer:= pb.getbuffer(fapi.status); + end + else begin + pblen:= 0; + pbbuffer:= nil; + end; + with tfbtrans(trans) do begin + clearstatus(); + ftransaction:= fattachment.starttransaction(fapi.status,pblen,pbbuffer); + if pb <> nil then begin + pb.dispose(); + end; + checkstatus('startdbtransaction'); + end; + result:= true; +end; + +function tfb3connection.commit(trans: tsqlhandle): boolean; +begin + with tfbtrans(trans) do begin + clearstatus(); + ftransaction.commit(fconnection.fapi.status); + checkstatus('commit'); + ftransaction:= nil; + result:= true; + end; +end; + +function tfb3connection.rollback(trans: tsqlhandle): boolean; +begin + with tfbtrans(trans) do begin + clearstatus(); + ftransaction.rollback(fconnection.fapi.status); + checkstatus('rollback'); + ftransaction:= nil; + result:= true; + end; +end; + +procedure tfb3connection.internalcommitretaining(trans: tsqlhandle); +begin + with tfbtrans(trans) do begin + clearstatus(); + ftransaction.commitretaining(fapi.status); + checkstatus('commitretaining'); + end; +end; + +procedure tfb3connection.internalrollbackretaining(trans: tsqlhandle); +begin + with tfbtrans(trans) do begin + clearstatus(); + ftransaction.rollbackretaining(fapi.status); + checkstatus('rollbackretaining'); + end; +end; + +function tfb3connection.allocatecursorhandle(const aowner: icursorclient; + const aname: ansistring): tsqlcursor; +begin + result:= tfbcursor.create(aowner,self); +end; + +procedure tfb3connection.deallocatecursorhandle(var cursor: tsqlcursor); +begin + freeandnil(cursor); +end; + +procedure tfb3connection.freefldbuffers(cursor: tsqlcursor); +begin + with tfbcursor(cursor) do begin + frowbuffer:= ''; + end; +end; + +procedure tfb3connection.preparestatement(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: msestring; + const aparams: tmseparams); +var + str1: string; +begin + with tfbcursor(cursor) do begin + if assigned(aparams) and (aparams.count > 0) then begin + str1:= todbstring(aparams.parsesql(asql,false,false,false,psinterbase, + fparambinding)); + end + else begin + fparambinding:= nil; + str1:= todbstring(asql); + end; + with tfbtrans(atransaction.trans) do begin + clearstatus(); + fstatement:= fattachment.prepare(fapi.status,ftransaction,length(str1), + pointer(str1),dialect, + IStatement.PREPARE_PREFETCH_FLAGS or + IStatement.PREPARE_PREFETCH_OUTPUT_PARAMETERS); + if fstatement <> nil then begin + fstatementflags:= fstatement.getflags(fapi.status); + end; + checkstatus('preparestatement'); + include(fcursorstate,cs_hasstatement); + cursor.fprepared:= true; + end; + end; +end; + +procedure tfb3connection.unpreparestatement(cursor: tsqlcursor); +begin + with tfbcursor(cursor) do begin + if cs_hasstatement in fcursorstate then begin + fparambinding:= nil; + cursorclose(tfbcursor(cursor)); + clearstatus(); + fstatement.free(fapi.status); + if not statusok then begin + fstatement.release(); + end; + fstatement:= nil; + exclude(fcursorstate,cs_hasstatement); + end; + fprepared:= false; + end; +end; + +procedure tfb3connection.cursorclose(const cursor: tfbcursor); +begin + with cursor do begin + frowbuffer:= ''; + ffieldinfos:= nil; + if fresultset <> nil then begin + clearstatus(); + fresultset.close(fapi.status); + if not statusok() then begin + fresultset.release(); + end; + fresultset:= nil; + end; + end; +end; + +procedure fetchboolean(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pwordbool(dest)^:= pcard8(ainfo^.buffer + ainfo^.offset)^ <> 0; +end; + +procedure fetchint16(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pint32(dest)^:= pint16(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchint32(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pint32(dest)^:= pint32(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchint64(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pint64(dest)^:= pint64(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchbcd1(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pcurrency(dest)^:= pcurrency(ainfo^.buffer + ainfo^.offset)^ * 1000; +end; + +procedure fetchbcd2(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pcurrency(dest)^:= pcurrency(ainfo^.buffer + ainfo^.offset)^ * 100; +end; + +procedure fetchbcd3(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pcurrency(dest)^:= pcurrency(ainfo^.buffer + ainfo^.offset)^ * 10; +end; + +procedure fetchbcd4(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pcurrency(dest)^:= pcurrency(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchbcdtofloat(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pdouble(dest)^:= pint64(ainfo^.buffer + ainfo^.offset)^ * + intexp10(ainfo^.scale); +end; + +procedure fetchbcd(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pint64(dest)^:= scaleexp10(pint64(ainfo^.buffer + ainfo^.offset)^, + 4+ainfo^.scale); +end; + +procedure fetchfloat(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pdouble(dest)^:= psingle(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchdouble(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pdouble(dest)^:= pdouble(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchtime(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pdatetime(dest)^:= pisc_time(ainfo^.buffer + ainfo^.offset)^ / + (3600*24*ISC_TIME_SECONDS_PRECISION); +end; + +procedure fetchdate(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pdatetime(dest)^:= pisc_date(ainfo^.buffer + ainfo^.offset)^ + fbdatetimeoffset; +end; + +procedure fetchtimestamp(const ainfo: pfbfieldinfoty; const dest: pointer); +var + ti,da: double; + po1: pisc_timestamp; +begin + po1:= ainfo^.buffer + ainfo^.offset; + da:= po1^.timestamp_date + fbdatetimeoffset; + ti:= po1^.timestamp_time / (3600*24*ISC_TIME_SECONDS_PRECISION); + if da < 0 then begin + pdatetime(dest)^:= da - ti; + end + else begin + pdatetime(dest)^:= da + ti; + end; +end; + +procedure fetchtext(const ainfo: pfbfieldinfoty; const dest: pointer); +var + i1: int32; + po1: pchar; +begin + po1:= ainfo^.buffer + ainfo^.offset; + i1:= ainfo^.size; + if i1 > ainfo^.buffersizead^ then begin + ainfo^.buffersizead^:= -i1; + end + else begin + ainfo^.buffersizead^:= i1; + move(po1^,dest^,i1); + end; +end; + +procedure fetchguid(const ainfo: pfbfieldinfoty; const dest: pointer); +var + po1: pguid; +begin + po1:= ainfo^.buffer + ainfo^.offset; + pguid(dest)^:= po1^; +end; + +procedure fetchvarchar(const ainfo: pfbfieldinfoty; const dest: pointer); +var + i1: int32; + po1: pvary; +begin + po1:= ainfo^.buffer + ainfo^.offset; + i1:= po1^.vary_length; + if i1 > ainfo^.buffersizead^ then begin + ainfo^.buffersizead^:= -i1; + end + else begin + ainfo^.buffersizead^:= i1; + move(po1^.vary_string,dest^,i1); + end; +end; + +procedure fetchvarbytes(const ainfo: pfbfieldinfoty; const dest: pointer); +var + i1: int32; + po1: pvary; +begin + po1:= ainfo^.buffer + ainfo^.offset; + i1:= po1^.vary_length + sizeof(card16); + if i1 > ainfo^.buffersizead^ then begin + ainfo^.buffersizead^:= -i1; + end + else begin + ainfo^.buffersizead^:= i1; + pcard16(dest)^:= po1^.vary_length; + move(po1^.vary_string,(dest+sizeof(card16))^,po1^.vary_length); + end; +end; + +procedure fetchblobid(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pisc_quad(dest)^:= pisc_quad(ainfo^.buffer + ainfo^.offset)^; + //todo: wantblobfetch +end; + +procedure fetchblobidanddata(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pisc_quad(dest)^:= pisc_quad(ainfo^.buffer + ainfo^.offset)^; + ainfo^._cursor.addblobcache(pint64(dest)^, + ainfo^._cursor.fconnection.getblobstring( + ainfo^._cursor,pisc_quad(dest)^)); +end; + +procedure tfb3connection.updateresultmetadata(const acursor: tfbcursor; + const outmetadata: pimessagemetadata); +var + metadata: imessagemetadata; + i1,i2,i3: int32; + +begin + with acursor do begin + ffirstfetch:= false; + fempty:= false; + if fresultset = nil then begin //execute() + metadata:= fstatement.getoutputmetadata(fapi.status); + if metadata <> nil then begin + ffirstfetch:= true; + end + else begin + fempty:= true; + end; + end + else begin //openCursor() + metadata:= fresultset.getmetadata(fapi.status); + end; + if outmetadata <> nil then begin + outmetadata^:= metadata; + if metadata <> nil then begin + metadata.addref(); + end; + end; + if metadata <> nil then begin + i1:= metadata.getcount(fapi.status); + if (i1 = 0) and (fresultset = nil) then begin + ffirstfetch:= false; //there is no outputdata + end; + setlength(frowbuffer,metadata.getmessagelength(fapi.status)); + if statusok() then begin + setlength(ffieldinfos,i1); + for i1:= 0 to i1-1 do begin + with ffieldinfos[i1] do begin + buffer:= pointer(frowbuffer); + name:= metadata.getalias(fapi.status,i1); + offset:= metadata.getoffset(fapi.status,i1); + _type:= metadata.gettype(fapi.status,i1); + scale:= metadata.getscale(fapi.status,i1); + if metadata.isnullable(fapi.status,i1) then begin + nulloffset:= metadata.getnulloffset(fapi.status,i1); + end + else begin + nulloffset:= -1; + end; + size:= 0; + case _type of + SQL_BOOLEAN: begin + datatype:= ftboolean; + fetchfunc:= @fetchboolean; + end; + SQL_SHORT: begin + datatype:= ftsmallint; + fetchfunc:= @fetchint16; + end; + SQL_LONG: begin + datatype:= ftinteger; + fetchfunc:= @fetchint32; + end; + SQL_INT64,SQL_QUAD: begin + if (scale <> 0) then begin + datatype:= ftbcd; + case scale of + -1: begin + fetchfunc:= @fetchbcd1; + end; + -2: begin + fetchfunc:= @fetchbcd2; + end; + -3: begin + fetchfunc:= @fetchbcd3; + end; + -4: begin + fetchfunc:= @fetchbcd4; + end; + else begin + if (dbo_bcdtofloatif in controller.options) then begin + datatype:= ftfloat; + fetchfunc:= @fetchbcdtofloat; + end + else begin + fetchfunc:= @fetchbcd; + end; + end; + end; + end + else begin + datatype:= ftlargeint; + fetchfunc:= @fetchint64; + end; + end; + SQL_FLOAT: begin + datatype:= ftfloat; + fetchfunc:= @fetchfloat; + end; + SQL_DOUBLE,SQL_D_FLOAT: begin + datatype:= ftfloat; + fetchfunc:= @fetchdouble; + end; + SQL_TIMESTAMP: begin + datatype:= ftdatetime; + fetchfunc:= @fetchtimestamp; + end; + SQL_TYPE_DATE: begin + datatype:= ftdate; + fetchfunc:= @fetchdate; + end; + SQL_TYPE_TIME: begin + datatype:= fttime; + fetchfunc:= @fetchtime; + end; + SQL_TEXT,SQL_VARYING: begin + size:= metadata.getlength(fapi.status,i1); + datatype:= ftstring; + i2:= metadata.getcharset(fapi.status,i1); + if _type = SQL_TEXT then begin + fetchfunc:= @fetchtext; + if i2 = cs_binary then begin + if size = 16 then begin + datatype:= ftguid; + fetchfunc:= @fetchguid; + size:= 0; + end + else begin + datatype:= ftbytes; + end; + end; + end + else begin + if i2 = cs_binary then begin + datatype:= ftvarbytes; + fetchfunc:= @fetchvarbytes; + end + else begin + fetchfunc:= @fetchvarchar; + end; + end; + case i2 of + 5,6,{8,}44,56,57{,64}: begin + i3:= 2; + end; + 3: begin + i3:= 3; + end; + 4,59: begin + i3:= 4; + end; + else begin + i3:= 1; + end; + end; + size:= size div i3; + end; + SQL_BLOB: begin + size:= 8; + if wantblobfetch then begin + fetchfunc:= @fetchblobidanddata; + _cursor:= acursor; + end + else begin + fetchfunc:= @fetchblobid; + end; + if metadata.getsubtype(fapi.status,i1) = isc_blob_text then begin + datatype:= ftmemo; + end + else begin + datatype:= ftblob; + end; + end; + SQL_ARRAY: begin //todo: support slice access + size:= 8; + datatype:= ftlargeint; + fetchfunc:= @fetchint64; + end; + else begin + datatype:= ftunknown; + fetchfunc:= nil; + end; + end; + end; + end; + end; + metadata.release(); + end; + end; +end; + +procedure tfb3connection.internalexecute(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const aparams: tmseparams; + const autf8: boolean); +var + paramdata: tparamdata; //inherits from imessagemetadata + parambuffer: pointer; + outdata1: imessagemetadata; + buf1: array[0..127] of byte; + by1: byte; + i1,i2,i3: int32; + datasize: int32; + selectcount: int32; + updatecount: int32; + deletecount: int32; + insertcount: int32; + +begin + with tfbcursor(cursor) do begin + frowsaffected:= -1; + frowsreturned:= -1; + if assigned(aparams) and (aparams.count > 0) and + (fparambinding <> nil) then begin + paramdata:= tparamdata.create(tfbcursor(cursor),aparams); + parambuffer:= paramdata.parambuffer; + end + else begin + paramdata:= nil; + parambuffer:= nil; + end; + with tfbtrans(atransaction.trans) do begin + clearstatus(); + if fstatementflags and istatement.FLAG_HAS_CURSOR <> 0 then begin + fresultset:= fstatement.opencursor(fapi.status,ftransaction, + paramdata,parambuffer,nil,0); + end + else begin + updateresultmetadata(tfbcursor(cursor),@outdata1); + fstatement.execute(fapi.status,ftransaction,paramdata,parambuffer, + outdata1,pointer(frowbuffer)); + end; + if paramdata <> nil then begin + paramdata.release(); + end; + if fresultset <> nil then begin + updateresultmetadata(tfbcursor(cursor),nil); + if fbo_sqlinfo in foptions then begin + if fetch(cursor) then begin //fetch necessary for valid sqlinfo + ffirstfetch:= true; + end + else begin + fempty:= true; + end; + end; + end; + if fbo_sqlinfo in foptions then begin + by1:= isc_info_sql_records; + fstatement.getinfo(fapi.status,1,@by1,sizeof(buf1),@buf1); + if statusok() then begin + if buf1[0] = isc_info_sql_records then begin + i2:= gds__vax_integer(@buf1[1],2)+3; //record size + if i2 <= sizeof(buf1) then begin + selectcount:= -1; + updatecount:= -1; + deletecount:= -1; + insertcount:= -1; + i1:= 3; + while true do begin + by1:= buf1[i1]; + if (by1 in [isc_info_end,isc_info_truncated]) or + (i1 >= i2-1) then begin + break; + end; + datasize:= gds__vax_integer(@buf1[i1+1],2); + inc(i1,3); + if i1 + datasize > i2 then begin + break; + end; + i3:= gds__vax_integer(@buf1[i1],datasize); + case by1 of + isc_info_req_select_count: begin + selectcount:= i3; + end; + isc_info_req_update_count: begin + updatecount:= i3; + end; + isc_info_req_delete_count: begin + deletecount:= i3; + end; + isc_info_req_insert_count: begin + insertcount:= i3; + end; + end; + inc(i1,datasize); + end; + if selectcount >= 0 then begin + frowsreturned:= selectcount; + end; + if updatecount > 0 then begin +// frowsreturned:= 0; + frowsaffected:= updatecount; + end; + if deletecount > 0 then begin +// frowsreturned:= 0; + frowsaffected:= deletecount; + end; + if insertcount > 0 then begin +// frowsreturned:= 0; + frowsaffected:= insertcount; + end; + end; + end; + end; + end; + checkstatus('execute'); + end; + end; +end; + +(* not ready, needs FB3 improvement + +procedure tfb3connection.internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); + //not used +var + paramdata: tparamdata; //inherits from imessagemetadata + parambuffer: pointer; + str1: string; +begin + with tfbcursor(cursor) do begin + frowsaffected:= -1; + frowsreturned:= -1; + if assigned(aparams) and (aparams.count > 0) then begin + str1:= todbstring(aparams.parsesql(origsql,false,false,false,psinterbase, + fparambinding)); + paramdata:= tparamdata.create(tfbcursor(cursor),aparams); + parambuffer:= paramdata.parambuffer; + end + else begin + fparambinding:= nil; + str1:= asql; + paramdata:= nil; + parambuffer:= nil; + end; + with tfbtrans(atransaction.trans) do begin + clearstatus(); + // fstatement.execute(fapi.status,ftransaction,nil,nil,nil,nil); + fresultset:= fattachment.opencursor(fapi.status,ftransaction,length(str1), + pchar(str1),dialect,paramdata,parambuffer,nil,nil,0); + if paramdata <> nil then begin + paramdata.release(); + end; + if fresultset <> nil then begin + updateresultmetadata(tfbcursor(cursor),nil); + end; + checkstatus('executeunprepared'); + end; + todo: rowsreturned, rowsaffected + end; +end; +*) + +procedure tfb3connection.addfielddefs(const cursor: tsqlcursor; + const fielddefs: tfielddefs); +var + i1: int32; +begin + with tfbcursor(cursor) do begin + fielddefs.clear(); + for i1:= 0 to high(ffieldinfos) do begin + with ffieldinfos[i1] do begin + with tfielddef.create(fielddefs,name,datatype,size,false,i1+1) do begin + end; + end; + end; + end; +end; + +procedure tfb3connection.updateindexdefs(var indexdefs: tindexdefs; + const atablename: string; const acursor: tsqlcursor); +begin + fbupdateindexdefs(self,indexdefs,atablename); +end; + +function tfb3connection.getschemainfosql(schematype : tschematype; + schemaobjectname, schemapattern : msestring) : msestring; +begin + result:= fbgetschemainfosql(self,schematype,schemaobjectname,schemapattern); +end; + +function tfb3connection.fetch(cursor: tsqlcursor): boolean; +var + i1: int32; +begin + result:= false; + with tfbcursor(cursor) do begin + if ffirstfetch then begin + result:= true; //output data from exec() + ffirstfetch:= false; + end + else begin + if not fempty then begin + if fresultset <> nil then begin + clearstatus(); + i1:= fresultset.fetchnext(fapi.status,pointer(frowbuffer)); + result:= i1 = istatus.RESULT_OK; + checkstatus('fetch'); + end; + end; + end; + end; +end; + +function tfb3connection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; +var + po1: pfbfieldinfoty; +begin + with tfbcursor(cursor) do begin + po1:= @ffieldinfos[fieldnum]; + if (po1^.nulloffset >= 0) and + (pisc_short(po1^.buffer + po1^.nulloffset)^ <> 0) or + (po1^.fetchfunc = nil) then begin + result:= false; + end + else begin + if buffer <> nil then begin //else null check; + po1^.buffersizead:= @bufsize; + po1^.fetchfunc(po1,buffer); + end; + result:= true; + end; + end; +end; + +function tfb3connection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +var + blobId : ISC_QUAD; + int1: integer; +begin + int1:= sizeof(blobid); + if not loadfield(cursor,ftblob,fieldnum,@blobid,int1,false) then begin + result:= ''; + end + else begin + result:= getblobstring(cursor,blobid); + end; +end; + +function tfb3connection.version: msestring; +var + versioncallback: tversioncallback; +begin + checkconnected(); + versioncallback:= tversioncallback.create; + clearstatus(); + fapi.util.getfbversion(fapi.status,fattachment,versioncallback); + if isutf8 then begin + result:= utf8tostring(versioncallback.text); + end + else begin + result:= msestring(versioncallback.text); + end; + versioncallback.destroy(); + checkstatus('get version'); +end; + +const + infotags: array[0..1] of byte = + (isc_info_blob_max_segment,isc_info_blob_total_length); + +function tfb3connection.getblobstream(const acursor: tsqlcursor; + const blobid: isc_quad; + const forstring: boolean = false): tmemorystream; +var + blob: iblob; + buffer: array[0..63] of byte; + maxsegment,totallength: int32; + i1,i2,i3: int32; + po1,pe: pcard8; + by1: byte; +begin + clearstatus(); + blob:= fattachment.openblob(fapi.status,itransaction(acursor.ftrans), + @blobid,0,nil); + checkstatus('open blob'); + try + blob.getinfo(fapi.status,length(infotags),@infotags,sizeof(buffer),@buffer); + checkstatus('get blob info'); + po1:= @buffer; + pe:= po1 + sizeof(buffer); + maxsegment:= -1; + totallength:= -1; + while (po1 < pe) and (po1^ <> isc_info_end) do begin + by1:= po1^; + inc(po1); + i2:= gds__vax_integer(po1,2); + inc(po1,2); + i3:= gds__vax_integer(po1,i2); + inc(po1,i2); + case by1 of + isc_info_blob_max_segment: begin + maxsegment:= i3; + end; + isc_info_blob_total_length: begin + totallength:= i3; + end; + else begin + break; + end; + end; + end; + if (maxsegment < 0) or (totallength < 0) or + (maxsegment = 0) and (totallength <> 0)then begin + databaseerror('Invalid blob info result',self); + end; + if forstring then begin + result:= tmemorystringstream.create; + end + else begin + result:= tmemorystream.create; + end; + result.size:= totallength; + po1:= result.memory; + repeat + i3:= totallength; + if i3 > maxsegment then begin + i3:= maxsegment; + end; + i2:= blob.getsegment(fapi.status,i3,po1,@i1); + checkstatus('read blob'); + po1:= po1 + i1; + totallength:= totallength - i1; + until (totallength <= 0) or + not ((i2 = istatus.RESULT_OK) or (i2 = istatus.RESULT_SEGMENT)); + finally + blob.release(); + end; +end; + +function tfb3connection.getblobstring(const acursor: tsqlcursor; + const blobid: isc_quad): string; +begin + tmemorystringstream(getblobstream(acursor,blobid,true)).destroyasstring(result); +end; + +function tfb3connection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tfb3connection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tfb3connection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tfb3connection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tfb3connection.createblobstream(const field: tfield; + const mode: tblobstreammode; const acursor: tsqlcursor): tstream; +var + blobId : ISC_QUAD; +begin + result := nil; + if mode = bmRead then begin + if not field.getData(@blobId) then begin + exit; + end; + result:= getblobstream(acursor,blobid); + end + else begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end; + end; +end; + +function tfb3connection.getblobdatasize: integer; +begin + result:= 8; +end; + +procedure tfb3connection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); +const + maxsegment = $ffff; +var + blob: iblob; + id: isc_quad; + po1: pcard8; + i1: int32; +begin + clearstatus(); + blob:= fattachment.createblob(fapi.status, + tfbtrans(atransaction.trans).ftransaction,@id,0,nil); + checkstatus('createblob'); + i1:= alength; + po1:= adata; + try + while i1 > 0 do begin + if i1 > maxsegment then begin + blob.putsegment(fapi.status,maxsegment,po1); + end + else begin + blob.putsegment(fapi.status,i1,po1); + end; + inc(po1,maxsegment); + dec(i1,maxsegment); + checkstatus('put segment'); + end; + blob.close(fapi.status); + finally + blob.release(); + end; + checkstatus('writeblobdata'); + + if aparam <> nil then begin + aparam.aslargeint:= int64(id); + if afield.datatype in textblobtypes then begin + aparam.blobkind:= bk_text; + end + else begin + aparam.blobkind:= bk_binary; + end; + end + else begin + setlength(newid,sizeof(isc_quad)); + pisc_quad(pointer(newid))^:= id; + end; +end; + +procedure tfb3connection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +var + blobid: isc_quad; +begin + afield.getdata(@blobid); + aparam.aslargeint:= int64(blobid); + if afield.datatype in textblobtypes then begin + aparam.blobkind:= bk_text; + end + else begin + aparam.blobkind:= bk_binary; + end; +end; + +procedure tfb3connection.listen(const sender: tdbevent); +begin + feventcontroller.register(sender); + if connected then begin + dolisten(sender); + end; +end; + +procedure tfb3connection.unlisten(const sender: tdbevent); +begin + if connected then begin + dounlisten(sender); + end; + feventcontroller.unregister(sender); +end; + +procedure tfb3connection.fire(const sender: tdbevent); +var + trans: tmsesqltransaction; +begin + trans:= tmsesqltransaction.create(nil); + try + trans.database:= self; + executedirect('execute block as begin post_event '+ + encodesqlstring(msestring(sender.eventname))+'; end', + trans,nil,isutf8,true); + trans.commit(); + finally + trans.destroy(); + end; +end; + +function tfb3connection.getdbevent(var aname: string; var aid: int64): boolean; +var + i1: int32; +begin + result:= false; + if feventcallback <> nil then begin + sys_mutexlock(feventcallback.fmutex); + if feventcount > 0 then begin + dec(feventcount); + for i1:= 0 to high(feventitems) do begin + with feventitems[i1] do begin + if count > 0 then begin + dec(count); + aname:= event.eventname; + aid:= i1; + result:= true; + break; + end; + end; + end; + end; + if feventcallback.ffired then begin //restart listen + clearstatus(); + feventcallback.queueevents(false); + sys_mutexunlock(feventcallback.fmutex); + checkstatus('getdbevent'); + end + else begin + sys_mutexunlock(feventcallback.fmutex); + end; + end; +end; + +procedure tfb3connection.clearevents(); +begin + if feventcallback <> nil then begin + sys_mutexlock(feventcallback.fmutex); + feventcallback.destroylocked(); + end; + if fevents <> nil then begin + fevents.cancel(fapi.status); + fevents.release(); + fevents:= nil; + end; + freeeventblock(feventbuffer); + feventitems:= nil; + feventcountbuffer:= nil; +end; + +procedure tfb3connection.loaded(); +begin + inherited; + fcontroller.loaded; +end; + +function tfb3connection.readsequence(const sequencename: string): msestring; +begin + result:= 'select gen_id('+msestring(sequencename)+ + ',1) as res from RDB$DATABASE;'; +end; + +function tfb3connection.sequencecurrvalue(const sequencename: string): msestring; +begin + result:= 'select gen_id('+msestring(sequencename)+ + ',0) as res from RDB$DATABASE;'; +end; + +function tfb3connection.writesequence(const sequencename: string; + const avalue: largeint): msestring; +begin + result:= 'set generator '+msestring(sequencename)+ + ' to '+inttostrmse(avalue)+';'; +end; + +procedure tfb3connection.updateevents(const aerrormessage: msestring); + //mutex must be locked, event leaks possible +var + i1: integer; + ar1: array of string; +begin + if feventcallback <> nil then begin + feventcallback.destroylocked(); + end; + setlength(ar1,length(feventitems)); + setlength(feventcountbuffer,length(feventitems)); + for i1:= 0 to high(feventitems) do begin + ar1[i1]:= feventitems[i1].name; + end; + if feventitems <> nil then begin + feventcallback:= tfbeventcallback.create(self); + feventcallback.addref(); + sys_mutexlock(feventcallback.fmutex); + freeeventblock(feventbuffer); + feventlength:= event_block(feventbuffer,ar1); + + clearstatus(); + feventcallback.queueevents(true); + if fevents = nil then begin //error in queueevents + feventcallback.destroylocked(); + clearevents(); + end; + checkstatus(aerrormessage); + //eventcallback allready destroyed in case of error + end + else begin + clearevents(); + end; + if feventcallback <> nil then begin + sys_mutexunlock(feventcallback.fmutex); + end; +end; + +procedure tfb3connection.dolisten(const sender: tdbevent); +begin + if feventcallback <> nil then begin + sys_mutexlock(feventcallback.fmutex); + feventcallback.storestate(); //copy current event counts to feventitems + end; + setlength(feventitems,high(feventitems)+2); + with feventitems[high(feventitems)] do begin + count:= -1; //first + event:= sender; + name:= sender.eventname; + end; + updateevents('dolisten'); +end; + +procedure tfb3connection.dounlisten(const sender: tdbevent); +var + i1: integer; + po1: pfbeventinfoty; +begin + if feventcallback <> nil then begin + sys_mutexlock(feventcallback.fmutex); + feventcallback.storestate(); //copy current event counts to feventitems + end; + for i1:= 0 to high(feventitems) do begin + po1:= @feventitems[i1]; + if po1^.event = sender then begin + if i1 <> high(feventitems) then begin + with feventitems[high(feventitems)] do begin + stringaddref(name); //compensate decref by setlength in deleteitem() + end; + finalize(po1^); + end; + deleteitem(feventitems,typeinfo(feventitems),i1); + break; + end; + end; + updateevents('dounlisten'); +end; + +{ tfbtrans } + +constructor tfbtrans.create(const aconnection: tfb3connection); +begin + fconnection:= aconnection; +end; + +destructor tfbtrans.destroy(); +begin + inherited; + if ftransaction <> nil then begin + ftransaction.release(); + end; +end; + +{ tfbcursor } + +constructor tfbcursor.create(const aowner: icursorclient; + const aconnection: tfb3connection); +begin + fconnection:= aconnection; + inherited create(aowner,fconnection.name); +end; + +destructor tfbcursor.destroy(); +begin + inherited; + if fresultset <> nil then begin + close(); //first, close needs valid statment + end; + if fstatement <> nil then begin + fstatement.release(); + end; +end; + +procedure tfbcursor.close(); +begin + inherited; + fconnection.cursorclose(self); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefb3service.pas b/mseide-msegui/lib/common/db/msefb3service.pas new file mode 100644 index 0000000..6f30393 --- /dev/null +++ b/mseide-msegui/lib/common/db/msefb3service.pas @@ -0,0 +1,1759 @@ +unit msefb3service; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$if fpc_fullversion >= 30000} + {$define mse_fpc_3} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseclasses,firebird,msefirebird,msetypes,mdb,msestrings, + msefb3connection, +// mibconnection, + msethread,sysutils; + +const + defaultinfotimeout = 60; //seconds + +type + fbserverinfoty = record + version: card32; + server_version: msestring; + _implementation: msestring; + capabilities: card32; + user_dbpath: msestring; + get_env: msestring; + get_env_lock: msestring; + get_env_msg: msestring; + end; + + fbuserinfoty = record + username: msestring; + firstname: msestring; + middlename: msestring; + lastname: msestring; + groupname: msestring; + rolename: msestring; + userid: card32; + groupid: card32; + admin: card32; + password: ansistring; + end; + pfbuserinfoty = ^fbuserinfoty; + fbuserinfoarty = array of fbuserinfoty; + + fbuseritemty = (fbu_username,fbu_firstname,fbu_middlename,fbu_lastname, + fbu_groupname,fbu_rolename,fbu_userid,fbu_groupid,fbu_admin, + fbu_password); + fbuseritemsty = set of fbuseritemty; + +const + allfbuseritems = [fbu_username,fbu_firstname,fbu_middlename,fbu_lastname, + fbu_groupname,fbu_rolename,fbu_userid,fbu_groupid,fbu_admin, + fbu_password]; + +type + accessmodety = (amo_readonly,amo_readwrite); + writemodety = (wmo_async,wmo_sync); + runmodety = (rmo_normal,rmo_multi,rmo_single,rmo_full); + reservespacety = (rsp_full,rsp_res); + propertyoptionty = (pro_activate,pro_dbonline); + propertyoptionsty = set of propertyoptionty; + + fbpropertyinfoty = record + pagebuffers: card32; + sweepinterval: card32; + shutdowndb: card32; + denynewattachments: card32; + denynewtransactions: card32; + reservespace: reservespacety; + writemode: writemodety; + accessmode: accessmodety; + setsqldialect: card32; + options: propertyoptionsty; + forceshutdown: card32; + attachmentsshutdown: card32; + transactionsshutdown: card32; + shutdownmode: runmodety; + onlinemode: runmodety; + end; + + fbpropertyitemty = (fbp_pagebuffers,fbp_sweepinterval,fbp_shutdowndb, + fbp_denynewattachments,fbp_denynewtransactions, + fbp_reservespace,fbp_writemode,fbp_accessmode, + fbp_setsqldialect,fbp_options,fbp_forceshutdown, + fbp_attachmentsshutdown,fbp_transactionsshutdown, + fbp_shutdownmode,fbp_onlinemode); + fbpropertyitemsty = set of fbpropertyitemty; + +const + allfbpropertyitems = [fbp_pagebuffers,fbp_sweepinterval,fbp_shutdowndb, + fbp_denynewattachments,fbp_denynewtransactions, + fbp_reservespace,fbp_writemode,fbp_accessmode, + fbp_setsqldialect,fbp_options,fbp_forceshutdown, + fbp_attachmentsshutdown,fbp_transactionsshutdown, + fbp_shutdownmode,fbp_onlinemode]; + +type + dbstatoptionty = (dbsto_datapages,dbsto_dblog,dbsto_hdrpages, + dbsto_idxpages,dbsto_sysrelations,dbsto_recordversions, + dbsto_table,dbsto_nocreation); + dbstatoptionsty = set of dbstatoptionty; + + backupoptionty = (bao_ignorechecksums,bao_ignorelimbo,bao_metadataonly, + bao_no_garbagecollect,bao_olddescriptions,bao_nontransportable, + bao_convert,bao_expand,bao_notriggers {=$8000}); + backupoptionsty = set of backupoptionty; + + restoreoptionty = (reo_deactivateidx,reo_no_shadow,reo_no_validity, + reo_one_at_a_time,reo_replace,reo_create,reo_use_all_space); + restoreoptionsty = set of restoreoptionty; + + repairoptionty = (rpo_validate_db,rpo_sweep_db,rpo_mend_db,limbo_trans, + rpo_check_db,rpo_ignore_checksum,rpo_kill_shadows,rpo_full); + repairoptionsty = set of repairoptionty; + + nbakoptionty = (nbo_notriggers); + nbakoptionsty = set of nbakoptionty; + + tfb3service = class; + + efbserviceerror3 = class(edatabaseerror) + private + ferror: integer; + ferrormessage: msestring; + fsender: tfb3service; +// fstatus: statusvectorty; + public + constructor create(const asender: tfb3service; + const astatus: istatus; const aerrormessage: msestring); + property sender: tfb3service read fsender; + property error: integer read ferror; + property errormessage: msestring read ferrormessage; +// property status: statusvectorty read fstatus; + end; + + fbservicestatety = (fbss_connected,fbss_busy); + fbservicestatesty = set of fbservicestatety; + fbserviceoptionty = (fbso_utf8,fbso_utf8message); + fbserviceoptionsty = set of fbserviceoptionty; + + fbservicetexteventty = procedure (const sender: tfb3service; + const atext: msestring) of object; + fbserviceerroreventty = procedure (const sender: tfb3service; + var e: exception; var handled: boolean) of object; + fbserviceendeventty = procedure (const sender: tfb3service; + const aborted: boolean) of object; + tfbservicemonitor3 = class(tmsethread) + private + fprocname: msestring; + protected + fowner: tfb3service; + function execute(thread: tmsethread): integer; override; + public + constructor create(const aowner: tfb3service; const procname: msestring); + destructor destroy(); override; + end; + + tfb3service = class(tmsecomponent) + private + fhostname: ansistring; + fusername: ansistring; + fpassword: ansistring; + fstate: fbservicestatesty; + fservice: iservice; +// fstatus: statusvectorty; //array [0..19] of isc_status; +// flasterror: istatus; + flasterrormessage: msestring; + foptions: fbserviceoptionsty; + finfotimeout: int32; + fonasynctext: fbservicetexteventty; + fmonitor: tfbservicemonitor3; + fonerror: fbserviceerroreventty; + fonasyncend: fbserviceendeventty; + fasynctext: msestringarty; + fasyncmaxrowcount: int32; + fonasyncendmain: fbserviceendeventty; + function getconnected: boolean; + procedure setconnected(const avalue: boolean); + protected + fapi: fbapity; + function connectionmessage(atext: pchar): msestring; + procedure loaded(); override; + procedure doasyncevent(var atag: int32); override; + procedure clearstatus(); inline; + function statusok(): boolean; inline; + procedure checkstatus(const aerrormessage: msestring); + procedure connect(); + procedure closeconn(); + procedure disconnect(); + procedure readstate(reader: treader); override; + procedure raiseerror(const e: exception; const dberr: boolean); + procedure dberror(const msg: msestring; const comp: tcomponent; + const dberr: boolean); +// procedure checkerror(const procname : string; +// const status : istatus); +// procedure checkerror(const procname : string; +// const status: integer); + procedure checkbusy(); + procedure invalidresponse(const procname: msestring); + + procedure start(const procname: msestring; const params: string); + function getinfo(const procname: msestring; const items: array of byte; + const async: boolean): string; + procedure runcommand(const procname: msestring; const params: string); + function getmsestringitem(var buffer: pointer; out res: msestring; + const cutspace: boolean = false): boolean; + //returns eof state + function getmsestringitem(var buffer: pointer; const id: int32; + var value: msestring): boolean; + procedure addmseparam(var params: string; const id: int32; + const value: msestring); + //value limited to 65535 chars + function internalusers(const ausername: string): fbuserinfoarty; + procedure gettext(const procname: msestring; const params: string; + var res: msestringarty; const maxrowcount: integer); + //ring buffer + procedure startmonitor(const procname: msestring; const aparams: string); + function serviceisrunning: boolean; + procedure tagaction(const aprocname: msestring; const aaction: int32; + var res: msestringarty; + const maxrowcount: int32); + procedure tagaction(const aprocname: msestring; const aaction: int32); + procedure traceaction(const aprocname: msestring; const aaction: int32; + const aid: card32; var res: msestringarty; + const maxrowcount: int32); + procedure adduserparams(var params1: string; + const ainfo: fbuserinfoty; const aitems: fbuseritemsty); + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + function todbstring(const avalue: msestring): string; + function tomsestring(const avalue: string): msestring; + procedure cancel(); + function busy(): boolean; + + function serverinfo(): fbserverinfoty; + function users(): fbuserinfoarty; + function user(const ausername: msestring; var ainfo: fbuserinfoty): boolean; + //false if not found + procedure adduser(const ainfo: fbuserinfoty; const items: fbuseritemsty); + procedure modifyuser(const ainfo: fbuserinfoty; const items: fbuseritemsty); + //fbu_username must be set + procedure deleteuser(const ausername: msestring; + const arolename: msestring = ''); + procedure getlog(var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracestart(const cfg: msestring; const _name: msestring = ''); + //async, stop it by connected:= false or call of cancel() + procedure tracelist(var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracestop(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracesuspend(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure traceresume(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure setmapping(); + procedure dropmapping(); + + procedure dbstats(const adbname: msestring; + const aoptions: dbstatoptionsty; const acommandline: msestring; + var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure properties(const adbname: msestring; + const ainfo: fbpropertyinfoty; const aitems: fbpropertyitemsty; + var res: msestringarty; const maxrowcount: integer= -1); + //ring buffer, -1 -> unlimited + + procedure validatestart(const dbname: msestring; + const tabincl: msestring = ''; const tabexcl: msestring = ''; + const idxincl: msestring = ''; const idxexcl: msestring = ''; + const locktimeout: card32 = 0); + procedure backupstart(const dbname: msestring; + const backupfiles: array of msestring; + const lengths: array of card32; //bytes, no item for last file + const verbose: boolean = false; const stat: string = ''; + //stat for FB 2.5.5 only, 1..4 chars, valid chars = T|D|R|W + const aoptions: backupoptionsty = []; const factor: card32 = 0); + procedure restorestart(const backupfiles: array of msestring; + const dbfiles: array of msestring; const lengths: array of card32; + //pages, none for last dbfile + const verbose: boolean = false; const stat: string = ''; + //stat for FB 2.5.5 only, 1..4 chars, valid chars = T|D|R|W + const aoptions: restoreoptionsty = []; + const accessmode: accessmodety = amo_readwrite; + const buffers: card32 = 0; const pagesize: card32 = 0; + const fixfssdata: string = ''; const fixfssmetadata: string = ''); + //CHARACTER SET CHARACTER SET + procedure nbakstart(const dbname: msestring; const _file: msestring; + const level: card32; const options: nbakoptionsty; + const direct: string = ''); + //'on or 'off' + procedure nreststart(const dbname: msestring; + const files: array of msestring; const options: nbakoptionsty); + procedure repairstart(const adbname: msestring; + const aoptions: repairoptionsty); + +// property lasterror: statusvectorty read flasterror; + property lasterrormessage: msestring read flasterrormessage; + property asynctext: msestringarty read fasynctext write fasynctext; + published + property asyncmaxrowcount: int32 read fasyncmaxrowcount + write fasyncmaxrowcount default 0; //-1 = unlimited + property hostname : ansistring read fhostname write fhostname; + property username : ansistring read fusername write fusername; + property password : ansistring read fpassword write fpassword; + property connected: boolean read getconnected + write setconnected default false; + //connected will be reset by a server error + property options: fbserviceoptionsty read foptions write foptions default []; + property infotimeout: int32 read finfotimeout write finfotimeout + default defaultinfotimeout; //seconds, -1 -> none + property onasynctext: fbservicetexteventty read fonasynctext + write fonasynctext; + property onasyncend: fbserviceendeventty read fonasyncend + write fonasyncend; //runs in service thread + property onasyncendmain: fbserviceendeventty read fonasyncendmain + write fonasyncendmain; //runs in main thread + + property onerror: fbserviceerroreventty read fonerror write fonerror; + end; + +implementation +uses + msebits,msearrayutils,mseapplication,msesysintf,msefileutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + restoreconsts: array[restoreoptionty] of card32 = (isc_spb_res_deactivate_idx, + isc_spb_res_no_shadow,isc_spb_res_no_validity,isc_spb_res_one_at_a_time, + isc_spb_res_replace,isc_spb_res_create,isc_spb_res_use_all_space); + accessmodeconsts: array[accessmodety] of card32 = (isc_spb_prp_am_readonly, + isc_spb_prp_am_readwrite); + writemodeconsts: array[writemodety] of card32 = (isc_spb_prp_wm_async, + isc_spb_prp_wm_sync); + propertyconsts: array[propertyoptionty] of card32 = (isc_spb_prp_activate, + isc_spb_prp_db_online); + reservespaceconsts: array[reservespacety] of card32 = (isc_spb_prp_res_use_full, + isc_spb_prp_res); +const + asyncendtag = 5790432; //not aborted, +1 -> aborted + +function readvalue16(var buffer: pbyte): card16; +begin + result:= buffer^; + inc(buffer); + result:= result + buffer^ shl 8; + inc(buffer); +end; + +function readvalue32(var buffer: pbyte): card16; +begin + result:= buffer^; + inc(buffer); + result:= result + buffer^ shl 8; + inc(buffer); + result:= result + buffer^ shl 16; + inc(buffer); + result:= result + buffer^ shl 24; + inc(buffer); +end; + +procedure storevalue(var buffer: pbyte; const value: card16); +begin + buffer^:= value; + inc(buffer); + buffer^:= value shr 8; + inc(buffer); +end; + +procedure storevalue(var buffer: pbyte; const value: card32); +begin + buffer^:= value; + inc(buffer); + buffer^:= value shr 8; + inc(buffer); + buffer^:= value shr 16; + inc(buffer); + buffer^:= value shr 24; + inc(buffer); +end; + +procedure addshortparam(var params: string; const id: int32; + const value: string); + //value limited to 255 chars +var + i1,i2: int32; + po1: pbyte; +begin + i1:= length(value); + if i1 > 255 then begin + i1:= 255; + end; + i2:= length(params); + setlength(params,i2+2+i1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + po1^:= i1; + inc(po1); + move(pointer(value)^,po1^,i1); +end; + +procedure addparam(var params: string; const id: int32; + const value: string); + //value limited to 65535 chars +var + i1,i2: int32; + po1: pbyte; +begin + i1:= length(value); + if i1 > 65535 then begin + i1:= 65553; + end; + i2:= length(params); + setlength(params,i2+3+i1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + storevalue(po1,card16(i1)); + move(pointer(value)^,po1^,i1); +end; + +procedure addparam(var params: string; const id: int32; + const value: card32); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+4); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + storevalue(po1,value); +end; + +procedure addparam(var params: string; const id: int32); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+0); + po1:= pointer(params)+i2; + po1^:= id; +end; + +procedure addparam(var params: string; const id: int32; + const value: card8); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + po1^:= value; + inc(po1); +end; + +procedure addtimeout(var params: string; const atimeout: card32); +var + i2: int32; + po1: pbyte; +begin + if int32(atimeout) >= 0 then begin + i2:= length(params); + setlength(params,i2+1+4+4+1); + po1:= pointer(params)+i2; + po1^:= isc_info_svc_timeout; + inc(po1); + storevalue(po1,card16(4)); //len + storevalue(po1,atimeout); + inc(po1); + po1^:= isc_info_end; + end; +end; + +function getvalueitem(var buffer: pointer; const id: int32; + var value: card32): boolean; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + value:= readvalue32(buffer); + result:= true; + end; +end; + +function getstringitem(var buffer: pointer; const id: int32; + var value: string): boolean; +var + i1: int32; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + i1:= readvalue16(buffer); + setlength(value,i1); + move((buffer)^,pointer(value)^,i1); + inc(buffer,i1); + result:= true; + end; +end; + +{ efbserviceerror3 } + +constructor efbserviceerror3.create(const asender: tfb3service; + const astatus: istatus; const aerrormessage: msestring); +var + str1: string; + msg1: msestring; + po1: nativeintptr; + err1: integer; +begin + str1:= formatstatus(astatus); + msg1:= aerrormessage; + if str1 <> '' then begin + msg1:= msg1 + lineend + msestring(str1); + end; + po1:= astatus.geterrors; + err1:= 0; + if po1 <> nil then begin + err1:= gds__sqlcode(po1); + end; + fsender:= sender; + ferror:= err1; + ferrormessage:= msg1; + if sender <> nil then begin + sender.flasterrormessage:= msg1; + end; + inherited create(asender.name+': '+ansistring(msg1)); +end; + +{ tfbservicemonitor3 } + +constructor tfbservicemonitor3.create(const aowner: tfb3service; + const procname: msestring); +begin + fowner:= aowner; + fprocname:= procname; + inherited create(); +end; + +destructor tfbservicemonitor3.destroy(); +begin + terminate(); + application.waitforthread(self); + inherited; +end; + +function tfbservicemonitor3.execute(thread: tmsethread): integer; + + procedure cancel(); + begin + if fowner.connected then begin + fowner.closeconn(); + fowner.connected:= true; + end; + end; //cancel + +var + params1,items1,buffer1: string; + po1: pointer; + i1,i2,rowmax1: int32; + str1: string; + ok: boolean; + ar1: msestringarty; + ar2: pointerarty; + rowindex1: int32; + mstr1,remainder: msestring; + po2,ps,pe: pmsechar; + + procedure add(); + begin + if length(ar1) < rowmax1 then begin + additem(ar1,remainder); + end + else begin + if rowmax1 <> 0 then begin + ar1[rowindex1]:= remainder; + inc(rowindex1); + if rowindex1 >= rowmax1 then begin + rowindex1:= 0; + end; + end; + end; + remainder:= ''; + end; //add + + procedure endtext(const canceled: boolean); + var + i1: int32; + begin + if rowindex1 = 0 then begin + fowner.fasynctext:= ar1; + end + else begin + allocuninitedarray(length(ar1),sizeof(pointer),ar2); + i1:= rowmax1-rowindex1; + move(ar1[rowindex1],ar2[0],i1*sizeof(pointer)); + move(ar1[0],ar2[i1],rowindex1*sizeof(pointer)); + fowner.fasynctext:= nil; + pointer(fowner.fasynctext):= pointer(ar1); + pointer(ar1):= nil; + end; + if assigned(fowner.fonasyncend) then begin + fowner.fonasyncend(fowner,true); + end; + if assigned(fowner.fonasyncendmain) then begin + if canceled then begin + fowner.asyncevent(asyncendtag+1); + end + else begin + fowner.asyncevent(asyncendtag); + end; + end; + end; + +const + buffersize = 4096; +begin + ok:= false; + params1:= ''; + addtimeout(params1,1); //1 sec min timeout + setlength(buffer1,buffersize); + items1:= char(isc_info_svc_to_eof); + str1:= ''; + remainder:= ''; + rowindex1:= 0; + rowmax1:= 0; + ar1:= nil; + try + while not terminated and not application.terminated do begin + fowner.clearstatus(); + fowner.fservice.query(fowner.fapi.status,length(params1),pointer(params1), + length(items1),pointer(items1),length(buffer1),pointer(buffer1)); + // fowner.checkerror(fprocname,isc_service_query(@fowner.fstatus,@fowner.fhandle, + // nil,length(params1),pointer(params1),length(items1),pointer(items1), + // length(buffer1),pointer(buffer1))); + fowner.checkstatus(fprocname); + if terminated or application.terminated then begin + break; + end; + case pbyte(pointer(buffer1))^ of + isc_info_svc_to_eof: begin + po1:= pointer(buffer1)+1; + i1:= readvalue16(po1); + if i1 > 0 then begin + i2:= length(str1); + setlength(str1,i1+i2); + move(po1^,(pointer(str1)+i2)^,i1); + end; + if i1 < buffersize-10 then begin + //not truncated, firebird seems not to fill buffer completely + if str1 <> '' then begin + application.lock(); + try + mstr1:= fowner.tomsestring(str1); + rowmax1:= fowner.fasyncmaxrowcount; + if rowmax1 < 0 then begin + rowmax1:= high(rowmax1); + end; + if length(ar1) > rowmax1 then begin + setlength(ar1,rowmax1); + end; + if rowindex1 > rowmax1 then begin + rowindex1:= 0; + end; + if rowmax1 > 0 then begin + po2:= pointer(mstr1); + ps:= po2; + pe:= po2+length(mstr1); + while po2 < pe do begin + if (po2^ = c_return) or (po2^ = c_linefeed) then begin + addstringsegment(remainder,ps,po2); + add(); + if (po2^ = c_return) then begin + inc(po2); + end; + if (po2^ = c_linefeed) then begin + inc(po2); + end; + ps:= po2; + end + else begin + inc(po2); + end; + end; + addstringsegment(remainder,ps,po2); + end; + if assigned(fowner.fonasynctext) then begin + fowner.fonasynctext(fowner,mstr1); + end; + finally + application.unlock(); + end; + str1:= ''; + end + else begin + application.lock(); + try + if not fowner.serviceisrunning() then begin + add(); + ok:= true; + cancel(); + endtext(false); + break; + end; + finally + application.unlock(); + end; + end; + end; + end; + else begin + fowner.invalidresponse(fprocname); + end; + end; + end; + finally + if not ok then begin + application.lock(); + try + add(); + cancel(); + endtext(true); + finally + application.unlock(); + end; + end; + end; + result:= 0; +end; + +{ tfb3service } + +constructor tfb3service.create(aowner: tcomponent); +begin +// fhandle:= FB_API_NULLHANDLE; + finfotimeout:= defaultinfotimeout; + inherited; +end; + +destructor tfb3service.destroy(); +begin + disconnect(); + inherited; +end; + +procedure tfb3service.cancel(); +begin + freeandnil(fmonitor); + if connected then begin + connected:= false; + connected:= true; + end; +end; + +function tfb3service.busy(): boolean; +begin + result:= fbss_busy in fstate; +end; + +function tfb3service.getconnected: boolean; +begin + result:= fservice <> nil; +end; + +procedure tfb3service.setconnected(const avalue: boolean); +begin + if csreading in componentstate then begin + updatebit1(card32(fstate),ord(fbss_connected),avalue); + end + else begin + if avalue then begin + connect(); + end + else begin + disconnect(); + end; + end; +end; + +function tfb3service.connectionmessage(atext: pchar): msestring; +begin + if fbso_utf8message in foptions then begin + result:= utf8tostring(atext); + end + else begin + result:= atext; + end; +end; + +procedure tfb3service.loaded(); +begin + inherited; + if fbss_connected in fstate then begin + connect(); + end; +end; + +procedure tfb3service.doasyncevent(var atag: int32); +begin + inherited; + if canevent(tmethod(fonasyncendmain)) then begin + if atag = asyncendtag then begin + fonasyncendmain(self,false); + end + else begin + if (atag = asyncendtag+1) then begin + fonasyncendmain(self,false); + end; + end; + end; +end; + +procedure tfb3service.clearstatus(); +begin + fapi.status.init(); +end; + +function tfb3service.statusok(): boolean; +begin + result:= fapi.status.getstate() and istatus.state_errors = 0 +end; + +procedure tfb3service.checkstatus(const aerrormessage: msestring); +begin + if fapi.status.getstate() and istatus.state_errors <> 0 then begin + raise efbserviceerror3.create(self,fapi.status,aerrormessage); + end; +end; + +procedure tfb3service.connect(); +const + servicename = 'service_mgr'; +var + params1: string; + str1: string; +begin + if fservice = nil then begin + try + inifbapi(fapi); + if fhostname = '' then begin + str1:= servicename; + end + else begin + str1:= fhostname + ':' + servicename; //tcp/ip + end; + params1:= char(isc_spb_version)+char(isc_spb_current_version); + addshortparam(params1,isc_spb_user_name,fusername); + addshortparam(params1,isc_spb_password,fpassword); + clearstatus(); +// checkerror('Connect',isc_service_attach(@fstatus,length(str1),pointer(str1), +// @fhandle,length(params1),pointer(params1))); + fservice:= fapi.provider.attachservicemanager(fapi.status,pchar(str1), + length(params1),pointer(params1)); + checkstatus('Connect'); + fservice.addref(); + except + exclude(fstate,fbss_connected); + fservice:= nil; + finifbapi(fapi); + raise; + end; + end; + include(fstate,fbss_connected); +end; + +procedure tfb3service.closeconn(); +begin + fstate:= fstate - [fbss_connected,fbss_busy]; + if fservice <> nil then begin + fservice.detach(fapi.status); + fservice.release(); + fservice:= nil; + finifbapi(fapi); + end; +end; + +procedure tfb3service.disconnect(); +begin + if (fmonitor <> nil) and + (sys_getcurrentthread() <> fmonitor.id) then begin + freeandnil(fmonitor); + end; + closeconn(); +end; + +procedure tfb3service.readstate(reader: treader); +begin + disconnect(); + inherited; +end; + +procedure tfb3service.raiseerror(const e: exception; const dberr: boolean); +var + bo1: boolean; + e1: exception; +begin + application.lock(); + try + if dberr then begin + connected:= false; //cancel possible running task + end; + e1:= e; + if canevent(tmethod(fonerror)) then begin + bo1:= false; + try + fonerror(self,e1,bo1); + except + e1.free; + raise; + end; + if bo1 then begin + e1.free; + end + else begin + raise e1; + end; + end + else begin + raise e1; + end; + finally + application.unlock(); + end; +end; + +procedure tfb3service.dberror(const msg: msestring; const comp: tcomponent; + const dberr: boolean); +begin + raiseerror(edatabaseerror.create(ansistring(msg),comp),dberr); +end; +(* +procedure tfb3service.checkerror(const procname: string; + const status: statusvectorty); +var + buf: array [0..1024] of char; + p: pointer; + Msg: msestring; +begin + if ((Status[0] = 1) and (Status[1] <> 0)) then begin + p:= @Status; + msg:= msestring(procname); +//{$warnings off} + while isc_interprete(Buf, @p) > 0 do begin + Msg := Msg + lineend +' -' + connectionmessage(Buf); + end; + flasterror:= status; + flasterrormessage:= msg; + raiseerror(efbserviceerror3.create(self,msg,status),true); + end; +end; +//{$warnings on} + +procedure tfb3service.checkerror(const procname: string; const status: integer); +begin + if status <> 0 then begin + checkerror(procname,fstatus); + end; +end; +*) +procedure tfb3service.checkbusy(); +begin + if not connected then begin + dberror('Not connected',self,false); + end; + if busy then begin + dberror('Busy',self,false); + end; +end; + +procedure tfb3service.invalidresponse(const procname: msestring); +begin + raiseerror(edatabaseerror.create( + ansistring('Invalid '+procname+' response'),self),true); +end; + +function tfb3service.todbstring(const avalue: msestring): string; +begin + if fbso_utf8 in foptions then begin + result:= stringtoutf8ansi(avalue); + end + else begin + result:= ansistring(avalue); + end; +end; + +function tfb3service.tomsestring(const avalue: string): msestring; +begin + if fbso_utf8 in foptions then begin + result:= utf8tostring(avalue); + end + else begin + result:= msestring(avalue); + end; +end; + +procedure tfb3service.start(const procname: msestring; const params: string); +begin + checkbusy(); + fasynctext:= nil; + clearstatus(); + fservice.start(fapi.status,length(params),pointer(params)); +// checkerror(procname,isc_service_start(@fstatus,@fhandle,nil, +// length(params),pointer(params))); + checkstatus(procname); + include(fstate,fbss_busy); +end; + +function tfb3service.getinfo(const procname: msestring; + const items: array of byte; const async: boolean): string; +var + params1: string; +begin + params1:= ''; + addtimeout(params1,finfotimeout); + setlength(result,1024); + while true do begin + clearstatus(); + fservice.query(fapi.status,length(params1),pointer(params1), + length(items),@items[0],length(result),pointer(result)); +// checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), +// pointer(params1),length(items),@items[0],length(result),pointer(result))); + checkstatus(procname); + if pbyte(pointer(result))^ <> isc_info_truncated then begin + if not async then begin + exclude(fstate,fbss_busy); + end; + break; + end; + setlength(result,2*length(result)); + end; +end; + +procedure tfb3service.runcommand(const procname: msestring; + const params: string); +var + ar1: msestringarty; +begin + gettext(procname,params,ar1,1); +end; + +function tfb3service.getmsestringitem(var buffer: pointer; out res: msestring; + const cutspace: boolean = false): boolean; +var + i1,i2: int32; +begin + i1:= readvalue16(buffer); + i2:= i1; + result:= i1 <= 0; + if cutspace and not result and (pchar(buffer)[i1-1] = ' ') then begin + dec(i2); + end; + if fbso_utf8 in foptions then begin + res:= utf8tostring(buffer,i2); + end + else begin + widestringmanager.ansi2unicodemoveproc(buffer, + {$ifdef mse_fpc_3}cp_acp,{$endif}res,i2); + end; + inc(buffer,i1); +end; + +function tfb3service.getmsestringitem(var buffer: pointer; const id: int32; + var value: msestring): boolean; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + getmsestringitem(buffer,value); + result:= true; + end; +end; + +procedure tfb3service.addmseparam(var params: string; const id: int32; + const value: msestring); +begin + addparam(params,id,todbstring(value)); +end; +{ +function tfb3service.getline(const procname: string; + var res: msestring; out eof: boolean): boolean; +var + params1: string; + items1: string; + buffer1: string; + po1: pointer; +begin + result:= true; + eof:= true; + params1:= ''; + addparam(params1,isc_info_svc_timeout,1); //minimal timeout (1sec) + setlength(buffer1,1024); //max line length + items1:= char(isc_info_svc_line); +// addparam(items1,isc_info_svc_timeout,1); //minimal timeout (1sec) + checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), + pointer(params1),length(items1),pointer(items1), + length(buffer1),pointer(buffer1))); + case pbyte(pointer(buffer1))^ of + isc_info_svc_line: begin //timeout? + po1:= pointer(buffer1)+1; + eof:= getmsestringitem(po1,res,true); + end; + else begin + invalidresponse(procname); + end; + end; +end; +} +function tfb3service.serverinfo(): fbserverinfoty; +var + buffer: string; + po1: pbyte; +begin + checkbusy(); + finalize(result); + fillchar(result,sizeof(result),0); + buffer:= getinfo('serverinfo',[isc_info_svc_version, + isc_info_svc_server_version,isc_info_svc_implementation, + isc_info_svc_capabilities,isc_info_svc_user_dbpath, + isc_info_svc_get_env,isc_info_svc_get_env_lock, + isc_info_svc_get_env_msg],false); + po1:= pointer(buffer); + with result do begin + while (po1^ <> isc_info_end) and (po1^ <> 0) do begin + if not (getvalueitem(po1,isc_info_svc_version,version) or + getmsestringitem(po1,isc_info_svc_server_version,server_version) or + getmsestringitem(po1,isc_info_svc_implementation,_implementation) or + getvalueitem(po1,isc_info_svc_capabilities,capabilities) or + getmsestringitem(po1,isc_info_svc_user_dbpath,user_dbpath) or + getmsestringitem(po1,isc_info_svc_get_env,get_env) or + getmsestringitem(po1,isc_info_svc_get_env_lock,get_env_lock) or + getmsestringitem(po1,isc_info_svc_get_env_msg,get_env_msg)) then begin + invalidresponse('serverinfo'); + end; + end; + end; +end; + +function tfb3service.internalusers(const ausername: string): fbuserinfoarty; +var + params1,buffer1: string; + po1: pbyte; + count: int32; + po2: pfbuserinfoty; +begin + checkbusy(); + params1:= char(isc_action_svc_display_user_adm); + if ausername <> '' then begin + addparam(params1,isc_spb_sec_username,ausername); + end; + start('users',params1); + result:= nil; + count:= 0; + buffer1:= getinfo('users',[isc_info_svc_get_users],false); + po1:= pointer(buffer1); + if po1^ <> isc_info_svc_get_users then begin + invalidresponse('users'); + end; + inc(po1,3); //additional bytes 50 0 ??? + while (po1^ <> isc_info_flag_end) and (po1^ <> isc_info_end) and + (po1^ <> 0) do begin + if po1^ = isc_spb_sec_username then begin //must be first field + additem(result,typeinfo(result),count); + po2:= @result[count-1]; + getmsestringitem(po1,isc_spb_sec_username,po2^.username) + end + else begin + if result = nil then begin + invalidresponse('users'); + end; + end; + with po2^ do begin + while (po1^ <> isc_spb_sec_username) and (po1^ <> isc_info_flag_end) and + (po1^ <> isc_info_end) and (po1^ <> 0) do begin + if not (getmsestringitem(po1,isc_spb_sec_firstname,firstname) or + getmsestringitem(po1,isc_spb_sec_middlename,middlename) or + getmsestringitem(po1,isc_spb_sec_lastname,lastname) or + getmsestringitem(po1,isc_spb_sec_groupname,groupname) or + getmsestringitem(po1,isc_spb_sql_role_name,rolename) or + getvalueitem(po1,isc_spb_sec_userid,userid) or + getvalueitem(po1,isc_spb_sec_groupid,groupid) or + getvalueitem(po1,isc_spb_sec_admin,admin)) then begin + invalidresponse('users'); + end; + end; + end; + end; + setlength(result,count); +end; + +function tfb3service.users(): fbuserinfoarty; +begin + result:= internalusers(''); +end; + +function tfb3service.user(const ausername: msestring; + var ainfo: fbuserinfoty): boolean; +var + ar1: fbuserinfoarty; +begin + ar1:= internalusers(todbstring(ausername)); + result:= ar1 <> nil; + if result then begin + ainfo:= ar1[0]; + end; +end; + +procedure tfb3service.adduserparams(var params1: string; + const ainfo: fbuserinfoty; const aitems: fbuseritemsty); +begin + with ainfo do begin + if fbu_username in aitems then begin + addmseparam(params1,isc_spb_sec_username,username); + end; + if fbu_firstname in aitems then begin + addmseparam(params1,isc_spb_sec_firstname,firstname); + end; + if fbu_middlename in aitems then begin + addmseparam(params1,isc_spb_sec_middlename,middlename); + end; + if fbu_lastname in aitems then begin + addmseparam(params1,isc_spb_sec_lastname,lastname); + end; + if fbu_groupname in aitems then begin + addmseparam(params1,isc_spb_sec_groupname,groupname); + end; + if fbu_rolename in aitems then begin + addmseparam(params1,isc_spb_sql_role_name,rolename); + end; + if fbu_userid in aitems then begin + addparam(params1,isc_spb_sec_userid,userid); + end; + if fbu_groupid in aitems then begin + addparam(params1,isc_spb_sec_groupid,groupid); + end; + if fbu_admin in aitems then begin + addparam(params1,isc_spb_sec_admin,admin); + end; + if fbu_password in aitems then begin + addparam(params1,isc_spb_sec_password,password); + end; + end; +end; + +procedure tfb3service.adduser(const ainfo: fbuserinfoty; + const items: fbuseritemsty); +var + params1: string; +begin + params1:= char(isc_action_svc_add_user); + adduserparams(params1,ainfo,items); + runcommand('adduser',params1); +end; + +procedure tfb3service.modifyuser(const ainfo: fbuserinfoty; + const items: fbuseritemsty); +var + params1: string; +begin + params1:= char(isc_action_svc_modify_user); + adduserparams(params1,ainfo,items); + runcommand('modifyuser',params1); +end; + +procedure tfb3service.deleteuser(const ausername: msestring; + const arolename: msestring = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_delete_user); + addmseparam(params1,isc_spb_sec_username,ausername); + if arolename <> '' then begin + addmseparam(params1,isc_spb_sql_role_name,arolename); + end; + runcommand('deleteuser',params1); +end; + +procedure tfb3service.gettext(const procname: msestring; const params: string; + var res: msestringarty; const maxrowcount: integer); + +var + circindex: int32; + + procedure add(const atext: pchar; const len: int32); + var + mstr1: msestring; + begin + if fbso_utf8 in foptions then begin + mstr1:= utf8tostring(atext,len); + end + else begin + widestringmanager.ansi2unicodemoveproc(atext, + {$ifdef mse_fpc_3}cp_acp,{$endif}mstr1,len); + end; + if (maxrowcount > 0) and (length(res) >= maxrowcount) then begin + res[circindex]:= mstr1; + inc(circindex); + if circindex >= maxrowcount then begin + circindex:= 0; + end; + end + else begin + additem(res,mstr1); + end; + end; + +var + params1,items1,buffer1: string; + po1: pointer; + pa,pb,pc,pe: pchar; + i1: int32; + remainder: string; + ar1: pointerarty; +begin + checkbusy(); + start(procname,params); + res:= nil; + params1:= ''; + addtimeout(params1,finfotimeout); + setlength(buffer1,4096); + items1:= char(isc_info_svc_to_eof); + remainder:= ''; + circindex:= 0; + while true do begin + clearstatus(); + fservice.query(fapi.status,length(params1),pointer(params1), + length(items1),pointer(items1),length(buffer1),pointer(buffer1)); + checkstatus(procname); +// checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), +// pointer(params1),length(items1),pointer(items1), +// length(buffer1),pointer(buffer1))); + case pbyte(pointer(buffer1))^ of + isc_info_svc_to_eof: begin + po1:= pointer(buffer1)+1; + i1:= readvalue16(po1); + if i1 <= 0 then begin + if serviceisrunning() then begin + dberror(procname+': Timeout',self,true); + end; + break; //eof + end; + if i1 > length(buffer1)-1-2 then begin + invalidresponse(procname); + end; + if maxrowcount <> 0 then begin + pa:= po1; + pb:= pa; + pe:= pa + i1; + while (pb < pe) do begin + if pb^ = c_linefeed then begin + pc:= pb; + if (pc > pa) and ((pc-1)^ = c_return) then begin + dec(pc); + end; + if remainder <> '' then begin + remainder:= remainder+stringsegment(pa,pb); + add(pointer(remainder),length(remainder)); + remainder:= ''; + end + else begin + add(pa,pc-pa); + end; + pa:= pb+1; + end; + inc(pb); + end; + remainder:= remainder+stringsegment(pa,pe); + end; + end; + else begin + invalidresponse(procname); + end; + end; + end; + if maxrowcount <> 0 then begin + add(pointer(remainder),length(remainder)); + end; + if circindex > 0 then begin + allocuninitedarray(length(res),sizeof(pointer),ar1); + i1:= maxrowcount-circindex; + move(res[circindex],ar1[0],i1*sizeof(pointer)); + move(res[0],ar1[i1],circindex*sizeof(pointer)); + res:= pointer(ar1); + pointer(ar1):= nil; + +// ar1:= copy(res,circindex,maxrowcount-circindex); +// stackarray(copy(res,0,circindex),ar1); +// res:= ar1; + end; + exclude(fstate,fbss_busy); +end; + +procedure tfb3service.startmonitor(const procname: msestring; + const aparams: string); +begin +// checkbusy(); + start(procname,aparams); + freeandnil(fmonitor); + fmonitor:= tfbservicemonitor3.create(self,procname); +end; + +function tfb3service.serviceisrunning(): boolean; +var + buffer1: string; + po1: pointer; + ca1: card32; +begin + result:= false; + if busy then begin + buffer1:= getinfo('serviceisrunning',[isc_info_svc_running],true); + po1:= pointer(buffer1); + if getvalueitem(po1,isc_info_svc_running,ca1) then begin + result:= ca1 <> 0; + end; + end; +end; + +procedure tfb3service.getlog(var res: msestringarty; + const maxrowcount: int32 = -1); +begin + tagaction('getlog',isc_action_svc_get_fb_log,res,maxrowcount); +end; + +procedure tfb3service.tracestart(const cfg: msestring; + const _name: msestring = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_trace_start); + addmseparam(params1,isc_spb_trc_cfg,cfg); + if _name <> '' then begin + addmseparam(params1,isc_spb_trc_name,_name); + end; + startmonitor('tracestart',params1); +end; + +procedure tfb3service.tagaction(const aprocname: msestring; + const aaction: int32; var res: msestringarty; + const maxrowcount: int32); +begin + gettext(aprocname,char(aaction),res,maxrowcount); +end; + +procedure tfb3service.tagaction(const aprocname: msestring; + const aaction: int32); +var + ar1: msestringarty; +begin + tagaction(aprocname,aaction,ar1,1); +end; + +procedure tfb3service.tracelist(var res: msestringarty; + const maxrowcount: int32 = -1); +begin + tagaction('tracelist',isc_action_svc_trace_list,res,maxrowcount); +end; + +procedure tfb3service.traceaction(const aprocname: msestring; + const aaction: int32; const aid: card32; var res: msestringarty; + const maxrowcount: int32); +var + params1: string; +begin + params1:= char(aaction); + addparam(params1,isc_spb_trc_id,aid); + gettext(aprocname,params1,res,maxrowcount); +end; + +procedure tfb3service.tracestop(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('tracestop',isc_action_svc_trace_stop,aid,res,maxrowcount); +end; + +procedure tfb3service.tracesuspend(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('tracesuspend',isc_action_svc_trace_suspend,aid,res,maxrowcount); +end; + +procedure tfb3service.traceresume(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('traceresume',isc_action_svc_trace_resume,aid,res,maxrowcount); +end; + +procedure tfb3service.setmapping(); +begin + tagaction('setmapping',isc_action_svc_set_mapping); +end; + +procedure tfb3service.dropmapping(); +begin + tagaction('dropmapping',isc_action_svc_drop_mapping); +end; + +procedure tfb3service.dbstats(const adbname: msestring; + const aoptions: dbstatoptionsty; const acommandline: msestring; + var res: msestringarty; const maxrowcount: int32 = -1); +var + params1: string; +begin + params1:= char(isc_action_svc_db_stats); + addmseparam(params1,isc_spb_dbname,adbname); + addparam(params1,isc_spb_options,card32(aoptions)); + if acommandline <> '' then begin + addmseparam(params1,isc_spb_command_line,acommandline); + end; + gettext('dbstats',params1,res,maxrowcount); +end; + +procedure tfb3service.properties(const adbname: msestring; + const ainfo: fbpropertyinfoty; const aitems: fbpropertyitemsty; + var res: msestringarty; const maxrowcount: integer); +var + params1: string; + ca1: card32; + opt1: propertyoptionty; +begin + params1:= char(isc_action_svc_properties); + addmseparam(params1,isc_spb_dbname,adbname); + with ainfo do begin + if fbp_pagebuffers in aitems then begin + addparam(params1,isc_spb_prp_page_buffers,pagebuffers); + end; + if fbp_sweepinterval in aitems then begin + addparam(params1,isc_spb_prp_sweep_interval,sweepinterval); + end; + if fbp_shutdowndb in aitems then begin + addparam(params1,isc_spb_prp_shutdown_db,shutdowndb); + end; + if fbp_denynewattachments in aitems then begin + addparam(params1,isc_spb_prp_deny_new_attachments,denynewattachments); + end; + if fbp_denynewtransactions in aitems then begin + addparam(params1,isc_spb_prp_deny_new_transactions,denynewtransactions); + end; + if fbp_reservespace in aitems then begin + addparam(params1,isc_spb_prp_reserve_space, + card8(reservespaceconsts[reservespace])); + end; + if fbp_writemode in aitems then begin + addparam(params1,isc_spb_prp_write_mode, + card8(writemodeconsts[writemode])); + end; + if fbp_accessmode in aitems then begin + addparam(params1,isc_spb_prp_access_mode, + card8(accessmodeconsts[accessmode])); + end; + if fbp_setsqldialect in aitems then begin + addparam(params1,isc_spb_prp_set_sql_dialect,setsqldialect); + end; + if fbp_options in aitems then begin + ca1:= 0; + for opt1:= low(opt1) to high(opt1) do begin + ca1:= ca1 or propertyconsts[opt1]; + end; + addparam(params1,isc_spb_options,ca1); + end; + if fbp_forceshutdown in aitems then begin + addparam(params1,isc_spb_prp_force_shutdown,forceshutdown); + end; + if fbp_attachmentsshutdown in aitems then begin + addparam(params1,isc_spb_prp_attachments_shutdown,attachmentsshutdown); + end; + if fbp_transactionsshutdown in aitems then begin + addparam(params1,isc_spb_prp_transactions_shutdown,transactionsshutdown); + end; + if fbp_shutdownmode in aitems then begin + addparam(params1,isc_spb_prp_shutdown_mode,card8(shutdownmode)); + end; + if fbp_onlinemode in aitems then begin + addparam(params1,isc_spb_prp_online_mode,card8(onlinemode)); + end; + end; + gettext('properties',params1,res,maxrowcount); +end; + +procedure tfb3service.validatestart(const dbname: msestring; + const tabincl: msestring = ''; const tabexcl: msestring = ''; + const idxincl: msestring = ''; const idxexcl: msestring = ''; + const locktimeout: card32 = 0); +var + params1: string; +begin + params1:= char(isc_action_svc_validate); + addmseparam(params1,isc_spb_dbname,dbname); + if tabincl <> '' then begin + addmseparam(params1,isc_spb_val_tab_incl,tabincl); + end; + if tabexcl <> '' then begin + addmseparam(params1,isc_spb_val_tab_excl,tabexcl); + end; + if idxincl <> '' then begin + addmseparam(params1,isc_spb_val_idx_incl,idxincl); + end; + if idxexcl <> '' then begin + addmseparam(params1,isc_spb_val_idx_excl,idxexcl); + end; + if locktimeout <> 0 then begin + addparam(params1,isc_spb_val_lock_timeout,locktimeout); + end; + startmonitor('validatestart',params1); +end; + +procedure tfb3service.backupstart(const dbname: msestring; + const backupfiles: array of msestring; const lengths: array of card32; + const verbose: boolean = false; const stat: string = ''; + const aoptions: backupoptionsty = []; + const factor: card32 = 0); +var + params1: string; + i1: int32; + ca1: card32; +begin + params1:= char(isc_action_svc_backup); + addmseparam(params1,isc_spb_dbname,dbname); + for i1:= 0 to high(backupfiles) do begin + addmseparam(params1,isc_spb_bkp_file,backupfiles[i1]); + if i1 <= high(lengths) then begin + addparam(params1,isc_spb_bkp_length,lengths[i1]); + end; + end; + if verbose then begin + addparam(params1,isc_spb_verbose); + end; + if stat <> '' then begin + addparam(params1,isc_spb_bkp_stat,stat); + end; + ca1:= card32(aoptions - [bao_notriggers]); + if bao_notriggers in aoptions then begin + ca1:= ca1 or $8000; + end; + addparam(params1,isc_spb_options,ca1); + startmonitor('backupstart',params1); +end; + +procedure tfb3service.restorestart(const backupfiles: array of msestring; + const dbfiles: array of msestring; const lengths: array of card32; + const verbose: boolean = false; const stat: string = ''; + const aoptions: restoreoptionsty = []; + const accessmode: accessmodety = amo_readwrite; + const buffers: card32 = 0; const pagesize: card32 = 0; + const fixfssdata: string = ''; const fixfssmetadata: string = ''); +var + params1: string; + i1: int32; + ca1: card32; + opt1: restoreoptionty; +begin + params1:= char(isc_action_svc_restore); + for i1:= 0 to high(backupfiles) do begin + addmseparam(params1,isc_spb_bkp_file,tosysfilepath(backupfiles[i1])); + end; + for i1:= 0 to high(dbfiles) do begin + addmseparam(params1,isc_spb_dbname,tosysfilepath(dbfiles[i1])); + if i1 <= high(lengths) then begin + addparam(params1,isc_spb_res_length,lengths[i1]); + end; + end; + if verbose then begin + addparam(params1,isc_spb_verbose); + end; + if stat <> '' then begin + addparam(params1,isc_spb_res_stat,stat); + end; + if aoptions <> [] then begin + ca1:= 0; + for opt1:= low(opt1) to high(opt1) do begin + if opt1 in aoptions then begin + ca1:= ca1 or restoreconsts[opt1]; + end; + end; + addparam(params1,isc_spb_options,ca1); + end; + addparam(params1,isc_spb_res_access_mode,card8(accessmodeconsts[accessmode])); + if buffers <> 0 then begin + addparam(params1,isc_spb_res_buffers,buffers); + end; + if pagesize <> 0 then begin + addparam(params1,isc_spb_res_page_size,pagesize); + end; + if fixfssdata <> '' then begin + addparam(params1,isc_spb_res_fix_fss_data,fixfssdata); + end; + if fixfssmetadata <> '' then begin + addparam(params1,isc_spb_res_fix_fss_metadata,fixfssmetadata); + end; + startmonitor('restorestart',params1); +end; + +procedure tfb3service.nbakstart(const dbname: msestring; const _file: msestring; + const level: card32; const options: nbakoptionsty; + const direct: string = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_nbak); + addmseparam(params1,isc_spb_dbname,dbname); + addmseparam(params1,isc_spb_nbk_file,_file); + addparam(params1,isc_spb_nbk_level,level); + addparam(params1,isc_spb_options,card32(options)); + if direct <> '' then begin + addparam(params1,isc_spb_nbk_direct,direct); + end; + startmonitor('nbak',params1); +end; + +procedure tfb3service.nreststart(const dbname: msestring; + const files: array of msestring; const options: nbakoptionsty); +var + params1: string; + i1: int32; +begin + params1:= char(isc_action_svc_nrest); + addmseparam(params1,isc_spb_dbname,dbname); + for i1:= 0 to high(files) do begin + addmseparam(params1,isc_spb_nbk_file,files[i1]); + end; + addparam(params1,isc_spb_options,card32(options)); + startmonitor('nrest',params1); +end; + +procedure tfb3service.repairstart(const adbname: msestring; + const aoptions: repairoptionsty); +var + params1: string; +begin + params1:= char(isc_action_svc_repair); + addmseparam(params1,isc_spb_dbname,adbname); + addparam(params1,isc_spb_options,card32(aoptions)); + startmonitor('repairstart',params1); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefbinterface.pas b/mseide-msegui/lib/common/db/msefbinterface.pas new file mode 100644 index 0000000..78e19c0 --- /dev/null +++ b/mseide-msegui/lib/common/db/msefbinterface.pas @@ -0,0 +1,397 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +// +// specialised api interfaces +// +unit msefbinterface; +{$ifdef FPC}{$mode delphi}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + firebird,msetypes,msefb3connection,mdb,msedb,msestrings; +type + + paraminfoty = record + _type: card32; + subtype: int32; + scale: int32; + charset: card32; + _length: card32; + offset: card32; + nulloffset: card32; + _isnull: boolean; + end; + paraminfoarty = array of paraminfoty; + + tparamdata = class(imessagemetadataimpl) + private + frefcount: int32; + fparambuffer: pointer; + fitems: paraminfoarty; + fcount: int32; + fmessagelength: int32; + public + constructor create(const cursor: tfbcursor; const params: tmseparams); + destructor destroy(); override; + procedure addRef() override; + function release(): Integer override; + function getCount(status: IStatus): Cardinal override; + function getField(status: IStatus; index: Cardinal): PAnsiChar override; + function getRelation(status: IStatus; index: Cardinal): PAnsiChar override; + function getOwner(status: IStatus; index: Cardinal): PAnsiChar override; + function getAlias(status: IStatus; index: Cardinal): PAnsiChar override; + function getType(status: IStatus; index: Cardinal): Cardinal override; + function isNullable(status: IStatus; index: Cardinal): Boolean override; + function getSubType(status: IStatus; index: Cardinal): Integer override; + function getLength(status: IStatus; index: Cardinal): Cardinal override; + function getScale(status: IStatus; index: Cardinal): Integer override; + function getCharSet(status: IStatus; index: Cardinal): Cardinal override; + function getOffset(status: IStatus; index: Cardinal): Cardinal override; + function getNullOffset(status: IStatus; index: Cardinal): Cardinal override; + function getBuilder(status: IStatus): IMetadataBuilder override; + function getMessageLength(status: IStatus): Cardinal override; + property parambuffer: pointer read fparambuffer; + end; + + tversioncallback = class(iversioncallbackimpl) + private + ftext: string; + public + procedure callback(status: IStatus; atext: PAnsiChar); override; + property text: string read ftext; + end; + +implementation +uses + msefirebird,dbconst,sysutils,msedate; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tfbcursor1 = class(tfbcursor); + tfbconnection1 = class(tfb3connection); + +{ tparamdata } + +constructor tparamdata.create(const cursor: tfbcursor; + const params: tmseparams); +var + i1: int32; + data: stringarty; + sqltype,sqllen: card32; + po1: pointer; + totsize1: int32; + align1: int32; + str1,str2: string; + dt1: tdatetime; + +begin + inherited create(); + addref(); + with tfbcursor1(cursor) do begin + fcount:= length(fparambinding); + totsize1:= 0; + if fcount > 0 then begin + setlength(fitems,fcount); + setlength(data,fcount); //string buffer + for i1:= 0 to fcount-1 do begin + sqltype:= 0; + sqllen:= 0; + align1:= 0; + with params[fparambinding[i1]],fitems[i1] do begin + _isnull:= isnull; + scale:= 0; + case datatype of + ftunknown: begin + if _isnull then begin + sqltype:= SQL_NULL+1; + end; + end; + ftboolean: begin + sqltype:= SQL_BOOLEAN+1; + sqllen:= 1; + end; + ftinteger,ftsmallint,ftword: begin + sqltype:= SQL_LONG+1; + sqllen:= 4; + align1:= 3; + end; + ftlargeint,ftbcd: begin + sqltype:= SQL_INT64+1; + sqllen:= 8; + if datatype = ftbcd then begin + scale:= -4; + end; + case blobkind of + bk_binary: begin + subtype:= isc_blob_untyped; + align1:= 3; //sizeof(SLONG), SLONG always 32 bit + end; + bk_text: begin + subtype:= isc_blob_text; + align1:= 3; //sizeof(SLONG), SLONG always 32 bit + end; + else begin + align1:= 7; + end; + end; + end; + ftfloat: begin + sqltype:= SQL_DOUBLE+1; + sqllen:= sizeof(double); + align1:= FB_DOUBLE_ALIGN-1; + end; + fttime,ftdate,ftdatetime: begin + sqltype:= SQL_TIMESTAMP+1; + sqllen:= sizeof(ISC_TIMESTAMP); + align1:= sizeof(ISC_DATE)-1; + end; + ftstring,ftwidestring,ftmemo,ftwidememo: begin + sqltype:= SQL_TEXT+1; + if not isnull then begin + data[i1]:= params.asdbstring(fparambinding[i1]); + sqllen:= length(data[i1]); + end; + end; + ftblob,ftgraphic,ftbytes,ftvarbytes,ftguid: begin + sqltype:= SQL_TEXT+1; + charset:= cs_binary; + if not isnull then begin + if datatype = ftguid then begin + setlength(data[i1],sizeof(tguid)); + pguid(pointer(data[i1]))^:= dbstringtoguid(asstring); + end + else begin + data[i1]:= asstring; + end; + sqllen:= length(data[i1]); + end; + end; + end; + if sqltype = 0 then begin + databaseerrorfmt(sunsupportedparameter,[fieldtypenames[datatype]], + fconnection); + end; + _type:= sqltype; + _length:= sqllen; + totsize1:= (totsize1 + align1) and not align1; + offset:= totsize1; + totsize1:= totsize1 + sqllen; + totsize1:= (totsize1 + 1) and not 1; + nulloffset:= totsize1; + totsize1:= totsize1 + 2; //null flag + end; + end; + getmem(fparambuffer,totsize1); + fmessagelength:= totsize1; + for i1:= 0 to fcount-1 do begin + with fitems[i1] do begin + po1:= fparambuffer + offset; + with params[fparambinding[i1]] do begin + if _isnull then begin + pisc_short(fparambuffer+nulloffset)^:= -1; + end + else begin; + pisc_short(fparambuffer+nulloffset)^:= 0; + end; + if _isnull then begin + if blobkind <> bk_none then begin + _type:= SQL_BLOB+1; + end; + end + else begin + case _type of + SQL_BOOLEAN+1: begin + pcard8(po1)^:= card8(asboolean); + end; + SQL_LONG+1: begin + pint32(po1)^:= asinteger; + end; + SQL_INT64+1: begin + if blobkind <> bk_none then begin + _type:= SQL_BLOB+1; + pisc_quad(po1)^:= ISC_QUAD(aslargeint); + end + else begin + if scale = -4 then begin + pcurrency(po1)^:= ascurrency; + end + else begin + pint64(po1)^:= aslargeint; + end; + end; + end; + SQL_DOUBLE+1: begin + pdouble(po1)^:= asfloat; + end; + SQL_TIMESTAMP+1: begin + dt1:= asdatetime; + pisc_timestamp(po1)^.timestamp_date:= trunc(dt1) - fbdatetimeoffset; + dt1:= abs(frac(dt1)); + pisc_timestamp(po1)^.timestamp_time:= + round(dt1*3600*24*ISC_TIME_SECONDS_PRECISION); + end; + SQL_TEXT+1: begin + move(pointer(data[i1])^,po1^,length(data[i1])); + end; + SQL_BLOB+1: begin + if subtype = isc_blob_text then begin + str1:= params.asdbstring(i1); + end + else begin + str1:= asstring; + end; + tfbconnection1(fconnection).writeblobdata(cursor.ftrans,'',nil, + pointer(str1),length(str1),nil,nil,str2); + pisc_quad(po1)^:= pisc_quad(pointer(str2))^; + end; + else begin + raise exception.create('Internal error 20160908A'); + end; + end; + end; + end; + end; + end; + end; + end; +end; + +destructor tparamdata.destroy(); +begin + inherited; + if fparambuffer <> nil then begin + freemem(fparambuffer); + end; +end; + +procedure tparamdata.addRef(); +begin + inc(frefcount); +end; + +function tparamdata.release(): Integer; +begin + dec(frefcount); + result:= frefcount; + if frefcount = 0 then begin + destroy(); + end; +end; + +function tparamdata.getCount(status: IStatus): Cardinal; +begin + result:= fcount; +end; + +function tparamdata.getField(status: IStatus; + index: Cardinal): PAnsiChar; +begin + result:= nil; +end; + +function tparamdata.getRelation(status: IStatus; + index: Cardinal): PAnsiChar; +begin + result:= nil; +end; + +function tparamdata.getOwner(status: IStatus; + index: Cardinal): PAnsiChar; +begin + result:= nil; +end; + +function tparamdata.getAlias(status: IStatus; + index: Cardinal): PAnsiChar; +begin + result:= nil; +end; + +function tparamdata.getType(status: IStatus; + index: Cardinal): Cardinal; +begin + result:= fitems[index]._type; +end; + +function tparamdata.isNullable(status: IStatus; + index: Cardinal): Boolean; +begin + result:= fitems[index]._type and 1 <> 0; +end; + +function tparamdata.getSubType(status: IStatus; + index: Cardinal): Integer; +begin + result:= fitems[index].subtype; +end; + +function tparamdata.getLength(status: IStatus; + index: Cardinal): Cardinal; +begin + result:= fitems[index]._length; +end; + +function tparamdata.getScale(status: IStatus; + index: Cardinal): Integer; +begin + result:= fitems[index].scale; +end; + +function tparamdata.getCharSet(status: IStatus; + index: Cardinal): Cardinal; +begin + result:= fitems[index].charset; +end; + +function tparamdata.getOffset(status: IStatus; + index: Cardinal): Cardinal; +begin + result:= fitems[index].offset; +end; + +function tparamdata.getNullOffset(status: IStatus; + index: Cardinal): Cardinal; +begin + result:= fitems[index].nulloffset; +end; + +function tparamdata.getBuilder(status: IStatus): IMetadataBuilder; +begin + result:= nil; +end; + +function tparamdata.getMessageLength(status: IStatus): Cardinal; +begin + result:= fmessagelength; +end; + +{ tversioncallback } + +procedure tversioncallback.callback(status: IStatus; atext: PAnsiChar); +begin + ftext:= ftext+atext+lineend; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefbservice.pas b/mseide-msegui/lib/common/db/msefbservice.pas new file mode 100644 index 0000000..397df18 --- /dev/null +++ b/mseide-msegui/lib/common/db/msefbservice.pas @@ -0,0 +1,1695 @@ +unit msefbservice; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$if fpc_fullversion >= 30000} + {$define mse_fpc_3} +{$endif} + +interface +uses + classes,mclasses,mseclasses,ibase60dyn,msetypes,mdb,msestrings,mibconnection, + msethread,sysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + defaultinfotimeout = 60; //seconds + +type + fbserverinfoty = record + version: card32; + server_version: msestring; + _implementation: msestring; + capabilities: card32; + user_dbpath: msestring; + get_env: msestring; + get_env_lock: msestring; + get_env_msg: msestring; + end; + + fbuserinfoty = record + username: msestring; + firstname: msestring; + middlename: msestring; + lastname: msestring; + groupname: msestring; + rolename: msestring; + userid: card32; + groupid: card32; + admin: card32; + password: ansistring; + end; + pfbuserinfoty = ^fbuserinfoty; + fbuserinfoarty = array of fbuserinfoty; + + fbuseritemty = (fbu_username,fbu_firstname,fbu_middlename,fbu_lastname, + fbu_groupname,fbu_rolename,fbu_userid,fbu_groupid,fbu_admin, + fbu_password); + fbuseritemsty = set of fbuseritemty; + +const + allfbuseritems = [fbu_username,fbu_firstname,fbu_middlename,fbu_lastname, + fbu_groupname,fbu_rolename,fbu_userid,fbu_groupid,fbu_admin, + fbu_password]; + +type + accessmodety = (amo_readonly,amo_readwrite); + writemodety = (wmo_async,wmo_sync); + runmodety = (rmo_normal,rmo_multi,rmo_single,rmo_full); + reservespacety = (rsp_full,rsp_res); + propertyoptionty = (pro_activate,pro_dbonline); + propertyoptionsty = set of propertyoptionty; + + fbpropertyinfoty = record + pagebuffers: card32; + sweepinterval: card32; + shutdowndb: card32; + denynewattachments: card32; + denynewtransactions: card32; + reservespace: reservespacety; + writemode: writemodety; + accessmode: accessmodety; + setsqldialect: card32; + options: propertyoptionsty; + forceshutdown: card32; + attachmentsshutdown: card32; + transactionsshutdown: card32; + shutdownmode: runmodety; + onlinemode: runmodety; + end; + + fbpropertyitemty = (fbp_pagebuffers,fbp_sweepinterval,fbp_shutdowndb, + fbp_denynewattachments,fbp_denynewtransactions, + fbp_reservespace,fbp_writemode,fbp_accessmode, + fbp_setsqldialect,fbp_options,fbp_forceshutdown, + fbp_attachmentsshutdown,fbp_transactionsshutdown, + fbp_shutdownmode,fbp_onlinemode); + fbpropertyitemsty = set of fbpropertyitemty; + +const + allfbpropertyitems = [fbp_pagebuffers,fbp_sweepinterval,fbp_shutdowndb, + fbp_denynewattachments,fbp_denynewtransactions, + fbp_reservespace,fbp_writemode,fbp_accessmode, + fbp_setsqldialect,fbp_options,fbp_forceshutdown, + fbp_attachmentsshutdown,fbp_transactionsshutdown, + fbp_shutdownmode,fbp_onlinemode]; + +type + dbstatoptionty = (dbsto_datapages,dbsto_dblog,dbsto_hdrpages, + dbsto_idxpages,dbsto_sysrelations,dbsto_recordversions, + dbsto_table,dbsto_nocreation); + dbstatoptionsty = set of dbstatoptionty; + + backupoptionty = (bao_ignorechecksums,bao_ignorelimbo,bao_metadataonly, + bao_no_garbagecollect,bao_olddescriptions,bao_nontransportable, + bao_convert,bao_expand,bao_notriggers {=$8000}); + backupoptionsty = set of backupoptionty; + + restoreoptionty = (reo_deactivateidx,reo_no_shadow,reo_no_validity, + reo_one_at_a_time,reo_replace,reo_create,reo_use_all_space); + restoreoptionsty = set of restoreoptionty; + + repairoptionty = (rpo_validate_db,rpo_sweep_db,rpo_mend_db,limbo_trans, + rpo_check_db,rpo_ignore_checksum,rpo_kill_shadows,rpo_full); + repairoptionsty = set of repairoptionty; + + nbakoptionty = (nbo_notriggers); + nbakoptionsty = set of nbakoptionty; + + tfbservice = class; + + efbserviceerror = class(edatabaseerror) + private + ferror: integer; + ferrormessage: msestring; + fsender: tfbservice; + fstatus: statusvectorty; + public + constructor create(const asender: tfbservice; const amessage: msestring; + const aerror: statusvectorty); + property sender: tfbservice read fsender; + property error: integer read ferror; + property errormessage: msestring read ferrormessage; + property status: statusvectorty read fstatus; + end; + + fbservicestatety = (fbss_connected,fbss_busy); + fbservicestatesty = set of fbservicestatety; + fbserviceoptionty = (fbso_utf8,fbso_utf8message); + fbserviceoptionsty = set of fbserviceoptionty; + + fbservicetexteventty = procedure (const sender: tfbservice; + const atext: msestring) of object; + fbserviceerroreventty = procedure (const sender: tfbservice; + var e: exception; var handled: boolean) of object; + fbserviceendeventty = procedure (const sender: tfbservice; + const aborted: boolean) of object; + tfbservicemonitor = class(tmsethread) + private + fprocname: string; + protected + fowner: tfbservice; + function execute(thread: tmsethread): integer; override; + public + constructor create(const aowner: tfbservice; const procname: string); + destructor destroy(); override; + end; + + tfbservice = class(tmsecomponent) + private + fhostname: ansistring; + fusername: ansistring; + fpassword: ansistring; + fstate: fbservicestatesty; + fhandle: isc_svc_handle; + fstatus: statusvectorty; //array [0..19] of isc_status; + flasterror: statusvectorty; + flasterrormessage: msestring; + foptions: fbserviceoptionsty; + finfotimeout: int32; + fonasynctext: fbservicetexteventty; + fmonitor: tfbservicemonitor; + fonerror: fbserviceerroreventty; + fonasyncend: fbserviceendeventty; + fasynctext: msestringarty; + fasyncmaxrowcount: int32; + fonasyncendmain: fbserviceendeventty; + function getconnected: boolean; + procedure setconnected(const avalue: boolean); + protected + function connectionmessage(atext: pchar): msestring; + procedure loaded(); override; + procedure doasyncevent(var atag: int32); override; + procedure connect(); + procedure closeconn(); + procedure disconnect(); + procedure readstate(reader: treader); override; + procedure raiseerror(const e: exception; const dberr: boolean); + procedure dberror(const msg: string; const comp: tcomponent; + const dberr: boolean); + procedure checkerror(const procname : string; + const status : statusvectorty); + procedure checkerror(const procname : string; + const status: integer); + procedure checkbusy(); + procedure invalidresponse(const procname: string); + + procedure start(const procname: string; const params: string); + function getinfo(const procname: string; const items: array of byte; + const async: boolean): string; + procedure runcommand(const procname: string; const params: string); + function getmsestringitem(var buffer: pointer; out res: msestring; + const cutspace: boolean = false): boolean; + //returns eof state + function getmsestringitem(var buffer: pointer; const id: int32; + var value: msestring): boolean; + procedure addmseparam(var params: string; const id: int32; + const value: msestring); + //value limited to 65535 chars + function internalusers(const ausername: string): fbuserinfoarty; + procedure gettext(const procname: string; const params: string; + var res: msestringarty; const maxrowcount: integer); + //ring buffer + procedure startmonitor(const procname: string; const aparams: string); + function serviceisrunning: boolean; + procedure tagaction(const aprocname: string; const aaction: int32; + var res: msestringarty; + const maxrowcount: int32); + procedure tagaction(const aprocname: string; const aaction: int32); + procedure traceaction(const aprocname: string; const aaction: int32; + const aid: card32; var res: msestringarty; + const maxrowcount: int32); + procedure adduserparams(var params1: string; + const ainfo: fbuserinfoty; const aitems: fbuseritemsty); + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + function todbstring(const avalue: msestring): string; + function tomsestring(const avalue: string): msestring; + procedure cancel(); + function busy(): boolean; + + function serverinfo(): fbserverinfoty; + function users(): fbuserinfoarty; + function user(const ausername: msestring; var ainfo: fbuserinfoty): boolean; + //false if not found + procedure adduser(const ainfo: fbuserinfoty; const items: fbuseritemsty); + procedure modifyuser(const ainfo: fbuserinfoty; const items: fbuseritemsty); + //fbu_username must be set + procedure deleteuser(const ausername: msestring; + const arolename: msestring = ''); + procedure getlog(var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracestart(const cfg: msestring; const _name: msestring = ''); + //async, stop it by connected:= false or call of cancel() + procedure tracelist(var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracestop(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracesuspend(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure traceresume(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure setmapping(); + procedure dropmapping(); + + procedure dbstats(const adbname: msestring; + const aoptions: dbstatoptionsty; const acommandline: msestring; + var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure properties(const adbname: msestring; + const ainfo: fbpropertyinfoty; const aitems: fbpropertyitemsty; + var res: msestringarty; const maxrowcount: integer= -1); + //ring buffer, -1 -> unlimited + + procedure validatestart(const dbname: msestring; + const tabincl: msestring = ''; const tabexcl: msestring = ''; + const idxincl: msestring = ''; const idxexcl: msestring = ''; + const locktimeout: card32 = 0); + procedure backupstart(const dbname: msestring; + const backupfiles: array of msestring; + const lengths: array of card32; //bytes, no item for last file + const verbose: boolean = false; const stat: string = ''; + //stat for FB 2.5.5 only, 1..4 chars, valid chars = T|D|R|W + const aoptions: backupoptionsty = []; const factor: card32 = 0); + procedure restorestart(const backupfiles: array of msestring; + const dbfiles: array of msestring; const lengths: array of card32; + //pages, none for last dbfile + const verbose: boolean = false; const stat: string = ''; + //stat for FB 2.5.5 only, 1..4 chars, valid chars = T|D|R|W + const aoptions: restoreoptionsty = []; + const accessmode: accessmodety = amo_readwrite; + const buffers: card32 = 0; const pagesize: card32 = 0; + const fixfssdata: string = ''; const fixfssmetadata: string = ''); + //CHARACTER SET CHARACTER SET + procedure nbakstart(const dbname: msestring; const _file: msestring; + const level: card32; const options: nbakoptionsty; + const direct: string = ''); + //'on or 'off' + procedure nreststart(const dbname: msestring; + const files: array of msestring; const options: nbakoptionsty); + procedure repairstart(const adbname: msestring; + const aoptions: repairoptionsty); + + property lasterror: statusvectorty read flasterror; + property lasterrormessage: msestring read flasterrormessage; + property asynctext: msestringarty read fasynctext write fasynctext; + published + property asyncmaxrowcount: int32 read fasyncmaxrowcount + write fasyncmaxrowcount default 0; //-1 = unlimited + property hostname : ansistring read fhostname write fhostname; + property username : ansistring read fusername write fusername; + property password : ansistring read fpassword write fpassword; + property connected: boolean read getconnected + write setconnected default false; + //connected will be reset by a server error + property options: fbserviceoptionsty read foptions write foptions default []; + property infotimeout: int32 read finfotimeout write finfotimeout + default defaultinfotimeout; //seconds, -1 -> none + property onasynctext: fbservicetexteventty read fonasynctext + write fonasynctext; + property onasyncend: fbserviceendeventty read fonasyncend + write fonasyncend; //runs in service thread + property onasyncendmain: fbserviceendeventty read fonasyncendmain + write fonasyncendmain; //runs in main thread + + property onerror: fbserviceerroreventty read fonerror write fonerror; + end; + +implementation +uses + msebits,msearrayutils,mseapplication,msesysintf; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + restoreconsts: array[restoreoptionty] of card32 = (isc_spb_res_deactivate_idx, + isc_spb_res_no_shadow,isc_spb_res_no_validity,isc_spb_res_one_at_a_time, + isc_spb_res_replace,isc_spb_res_create,isc_spb_res_use_all_space); + accessmodeconsts: array[accessmodety] of card32 = (isc_spb_prp_am_readonly, + isc_spb_prp_am_readwrite); + writemodeconsts: array[writemodety] of card32 = (isc_spb_prp_wm_async, + isc_spb_prp_wm_sync); + propertyconsts: array[propertyoptionty] of card32 = (isc_spb_prp_activate, + isc_spb_prp_db_online); + reservespaceconsts: array[reservespacety] of card32 = (isc_spb_prp_res_use_full, + isc_spb_prp_res); +const + asyncendtag = 5790432; //not aborted, +1 -> aborted + +function readvalue16(var buffer: pbyte): card16; +begin + result:= buffer^; + inc(buffer); + result:= result + buffer^ shl 8; + inc(buffer); +end; + +function readvalue32(var buffer: pbyte): card16; +begin + result:= buffer^; + inc(buffer); + result:= result + buffer^ shl 8; + inc(buffer); + result:= result + buffer^ shl 16; + inc(buffer); + result:= result + buffer^ shl 24; + inc(buffer); +end; + +procedure storevalue(var buffer: pbyte; const value: card16); +begin + buffer^:= value; + inc(buffer); + buffer^:= value shr 8; + inc(buffer); +end; + +procedure storevalue(var buffer: pbyte; const value: card32); +begin + buffer^:= value; + inc(buffer); + buffer^:= value shr 8; + inc(buffer); + buffer^:= value shr 16; + inc(buffer); + buffer^:= value shr 24; + inc(buffer); +end; + +procedure addshortparam(var params: string; const id: int32; + const value: string); + //value limited to 255 chars +var + i1,i2: int32; + po1: pbyte; +begin + i1:= length(value); + if i1 > 255 then begin + i1:= 255; + end; + i2:= length(params); + setlength(params,i2+2+i1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + po1^:= i1; + inc(po1); + move(pointer(value)^,po1^,i1); +end; + +procedure addparam(var params: string; const id: int32; + const value: string); + //value limited to 65535 chars +var + i1,i2: int32; + po1: pbyte; +begin + i1:= length(value); + if i1 > 65535 then begin + i1:= 65553; + end; + i2:= length(params); + setlength(params,i2+3+i1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + storevalue(po1,card16(i1)); + move(pointer(value)^,po1^,i1); +end; + +procedure addparam(var params: string; const id: int32; + const value: card32); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+4); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + storevalue(po1,value); +end; + +procedure addparam(var params: string; const id: int32); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+0); + po1:= pointer(params)+i2; + po1^:= id; +end; + +procedure addparam(var params: string; const id: int32; + const value: card8); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + po1^:= value; + inc(po1); +end; + +procedure addtimeout(var params: string; const atimeout: card32); +var + i2: int32; + po1: pbyte; +begin + if int32(atimeout) >= 0 then begin + i2:= length(params); + setlength(params,i2+1+4+4+1); + po1:= pointer(params)+i2; + po1^:= isc_info_svc_timeout; + inc(po1); + storevalue(po1,card16(4)); //len + storevalue(po1,atimeout); + inc(po1); + po1^:= isc_info_end; + end; +end; + +function getvalueitem(var buffer: pointer; const id: int32; + var value: card32): boolean; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + value:= readvalue32(buffer); + result:= true; + end; +end; + +function getstringitem(var buffer: pointer; const id: int32; + var value: string): boolean; +var + i1: int32; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + i1:= readvalue16(buffer); + setlength(value,i1); + move((buffer)^,pointer(value)^,i1); + inc(buffer,i1); + result:= true; + end; +end; + +{ efbserviceerror } + +constructor efbserviceerror.create(const asender: tfbservice; + const amessage: msestring; const aerror: statusvectorty); +begin + fstatus:= aerror; + fsender:= sender; + ferror:= aerror[1]; + ferrormessage:= amessage; + inherited create(asender.name+': '+ansistring(amessage)); +end; + +{ tfbservicemonitor } + +constructor tfbservicemonitor.create(const aowner: tfbservice; + const procname: string); +begin + fowner:= aowner; + fprocname:= procname; + inherited create(); +end; + +destructor tfbservicemonitor.destroy(); +begin + terminate(); + application.waitforthread(self); + inherited; +end; + +function tfbservicemonitor.execute(thread: tmsethread): integer; + + procedure cancel(); + begin + if fowner.connected then begin + fowner.closeconn(); + fowner.connected:= true; + end; + end; //cancel + +var + params1,items1,buffer1: string; + po1: pointer; + i1,i2,rowmax1: int32; + str1: string; + ok: boolean; + ar1: msestringarty; + ar2: pointerarty; + rowindex1: int32; + mstr1,remainder: msestring; + po2,ps,pe: pmsechar; + + procedure add(); + begin + if length(ar1) < rowmax1 then begin + additem(ar1,remainder); + end + else begin + if rowmax1 <> 0 then begin + ar1[rowindex1]:= remainder; + inc(rowindex1); + if rowindex1 >= rowmax1 then begin + rowindex1:= 0; + end; + end; + end; + remainder:= ''; + end; //add + + procedure endtext(const canceled: boolean); + var + i1: int32; + begin + if rowindex1 = 0 then begin + fowner.fasynctext:= ar1; + end + else begin + allocuninitedarray(length(ar1),sizeof(pointer),ar2); + i1:= rowmax1-rowindex1; + move(ar1[rowindex1],ar2[0],i1*sizeof(pointer)); + move(ar1[0],ar2[i1],rowindex1*sizeof(pointer)); + fowner.fasynctext:= nil; + pointer(fowner.fasynctext):= pointer(ar1); + pointer(ar1):= nil; + end; + if assigned(fowner.fonasyncend) then begin + fowner.fonasyncend(fowner,true); + end; + if assigned(fowner.fonasyncendmain) then begin + if canceled then begin + fowner.asyncevent(asyncendtag+1); + end + else begin + fowner.asyncevent(asyncendtag); + end; + end; + end; + +const + buffersize = 4096; +begin + ok:= false; + params1:= ''; + addtimeout(params1,1); //1 sec min timeout + setlength(buffer1,buffersize); + items1:= char(isc_info_svc_to_eof); + str1:= ''; + remainder:= ''; + rowindex1:= 0; + rowmax1:= 0; + ar1:= nil; + try + while not terminated and not application.terminated do begin + fowner.checkerror(fprocname,isc_service_query(@fowner.fstatus,@fowner.fhandle, + nil,length(params1),pointer(params1),length(items1),pointer(items1), + length(buffer1),pointer(buffer1))); + if terminated or application.terminated then begin + break; + end; + case pbyte(pointer(buffer1))^ of + isc_info_svc_to_eof: begin + po1:= pointer(buffer1)+1; + i1:= readvalue16(po1); + if i1 > 0 then begin + i2:= length(str1); + setlength(str1,i1+i2); + move(po1^,(pointer(str1)+i2)^,i1); + end; + if i1 < buffersize-10 then begin + //not truncated, firebird seems not to fill buffer completely + if str1 <> '' then begin + application.lock(); + try + mstr1:= fowner.tomsestring(str1); + rowmax1:= fowner.fasyncmaxrowcount; + if rowmax1 < 0 then begin + rowmax1:= high(rowmax1); + end; + if length(ar1) > rowmax1 then begin + setlength(ar1,rowmax1); + end; + if rowindex1 > rowmax1 then begin + rowindex1:= 0; + end; + if rowmax1 > 0 then begin + po2:= pointer(mstr1); + ps:= po2; + pe:= po2+length(mstr1); + while po2 < pe do begin + if (po2^ = c_return) or (po2^ = c_linefeed) then begin + addstringsegment(remainder,ps,po2); + add(); + if (po2^ = c_return) then begin + inc(po2); + end; + if (po2^ = c_linefeed) then begin + inc(po2); + end; + ps:= po2; + end + else begin + inc(po2); + end; + end; + addstringsegment(remainder,ps,po2); + end; + if assigned(fowner.fonasynctext) then begin + fowner.fonasynctext(fowner,mstr1); + end; + finally + application.unlock(); + end; + str1:= ''; + end + else begin + application.lock(); + try + if not fowner.serviceisrunning() then begin + add(); + ok:= true; + cancel(); + endtext(false); + break; + end; + finally + application.unlock(); + end; + end; + end; + end; + else begin + fowner.invalidresponse(fprocname); + end; + end; + end; + finally + if not ok then begin + application.lock(); + try + add(); + cancel(); + endtext(true); + finally + application.unlock(); + end; + end; + end; + result:= 0; +end; + +{ tfbservice } + +constructor tfbservice.create(aowner: tcomponent); +begin + fhandle:= FB_API_NULLHANDLE; + finfotimeout:= defaultinfotimeout; + inherited; +end; + +destructor tfbservice.destroy(); +begin + disconnect(); + inherited; +end; + +procedure tfbservice.cancel(); +begin + freeandnil(fmonitor); + if connected then begin + connected:= false; + connected:= true; + end; +end; + +function tfbservice.busy(): boolean; +begin + result:= fbss_busy in fstate; +end; + +function tfbservice.getconnected: boolean; +begin + result:= fhandle <> FB_API_NULLHANDLE; +end; + +procedure tfbservice.setconnected(const avalue: boolean); +begin + if csreading in componentstate then begin + updatebit1(card32(fstate),ord(fbss_connected),avalue); + end + else begin + if avalue then begin + connect(); + end + else begin + disconnect(); + end; + end; +end; + +function tfbservice.connectionmessage(atext: pchar): msestring; +begin + if fbso_utf8message in foptions then begin + result:= utf8tostring(atext); + end + else begin + result:= atext; + end; +end; + +procedure tfbservice.loaded(); +begin + inherited; + if fbss_connected in fstate then begin + connect(); + end; +end; + +procedure tfbservice.doasyncevent(var atag: int32); +begin + inherited; + if canevent(tmethod(fonasyncendmain)) then begin + if atag = asyncendtag then begin + fonasyncendmain(self,false); + end + else begin + if (atag = asyncendtag+1) then begin + fonasyncendmain(self,false); + end; + end; + end; +end; + +procedure tfbservice.connect(); +const + servicename = 'service_mgr'; +var + params1: string; + str1: string; +begin + if fhandle = FB_API_NULLHANDLE then begin + try + initializeibase60([]); + if fhostname = '' then begin + str1:= servicename; + end + else begin + str1:= fhostname + ':' + servicename; //tcp/ip + end; + params1:= char(isc_spb_version)+char(isc_spb_current_version); + addshortparam(params1,isc_spb_user_name,fusername); + addshortparam(params1,isc_spb_password,fpassword); + checkerror('Connect',isc_service_attach(@fstatus,length(str1),pointer(str1), + @fhandle,length(params1),pointer(params1))); + except + exclude(fstate,fbss_connected); + fhandle:= FB_API_NULLHANDLE; + releaseibase60(); + raise; + end; + end; + include(fstate,fbss_connected); +end; + +procedure tfbservice.closeconn(); +begin + fstate:= fstate - [fbss_connected,fbss_busy]; + if fhandle <> FB_API_NULLHANDLE then begin + isc_service_detach(@fstatus,@fhandle); + fhandle:= FB_API_NULLHANDLE; + releaseibase60(); + end; +end; + +procedure tfbservice.disconnect(); +begin + if (fmonitor <> nil) and + (sys_getcurrentthread() <> fmonitor.id) then begin + freeandnil(fmonitor); + end; + closeconn(); +end; + +procedure tfbservice.readstate(reader: treader); +begin + disconnect(); + inherited; +end; + +procedure tfbservice.raiseerror(const e: exception; const dberr: boolean); +var + bo1: boolean; + e1: exception; +begin + application.lock(); + try + if dberr then begin + connected:= false; //cancel possible running task + end; + e1:= e; + if canevent(tmethod(fonerror)) then begin + bo1:= false; + try + fonerror(self,e1,bo1); + except + e1.free; + raise; + end; + if bo1 then begin + e1.free; + end + else begin + raise e1; + end; + end + else begin + raise e1; + end; + finally + application.unlock(); + end; +end; + +procedure tfbservice.dberror(const msg: string; const comp: tcomponent; + const dberr: boolean); +begin + raiseerror(edatabaseerror.create(msg,comp),dberr); +end; + +procedure tfbservice.checkerror(const procname: string; + const status: statusvectorty); +var + buf: array [0..1024] of char; + p: pointer; + Msg: msestring; +begin + if ((Status[0] = 1) and (Status[1] <> 0)) then begin + p:= @Status; + msg:= msestring(procname); +//{$warnings off} + while isc_interprete(Buf, @p) > 0 do begin + Msg := Msg + lineend +' -' + connectionmessage(Buf); + end; + flasterror:= status; + flasterrormessage:= msg; + raiseerror(efbserviceerror.create(self,msg,status),true); + end; +end; +//{$warnings on} + +procedure tfbservice.checkerror(const procname: string; const status: integer); +begin + if status <> 0 then begin + checkerror(procname,fstatus); + end; +end; + +procedure tfbservice.checkbusy(); +begin + if not connected then begin + dberror('Not connected',self,false); + end; + if busy then begin + dberror('Busy',self,false); + end; +end; + +procedure tfbservice.invalidresponse(const procname: string); +begin + raiseerror(edatabaseerror.create('Invalid '+procname+' response',self),true); +end; + +function tfbservice.todbstring(const avalue: msestring): string; +begin + if fbso_utf8 in foptions then begin + result:= stringtoutf8ansi(avalue); + end + else begin + result:= ansistring(avalue); + end; +end; + +function tfbservice.tomsestring(const avalue: string): msestring; +begin + if fbso_utf8 in foptions then begin + result:= utf8tostring(avalue); + end + else begin + result:= msestring(avalue); + end; +end; + +procedure tfbservice.start(const procname: string; const params: string); +begin + checkbusy(); + fasynctext:= nil; + checkerror(procname,isc_service_start(@fstatus,@fhandle,nil, + length(params),pointer(params))); + include(fstate,fbss_busy); +end; + +function tfbservice.getinfo(const procname: string; + const items: array of byte; const async: boolean): string; +var + params1: string; +begin + params1:= ''; + addtimeout(params1,finfotimeout); + setlength(result,1024); + while true do begin + checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), + pointer(params1),length(items),@items[0],length(result),pointer(result))); + if pbyte(pointer(result))^ <> isc_info_truncated then begin + if not async then begin + exclude(fstate,fbss_busy); + end; + break; + end; + setlength(result,2*length(result)); + end; +end; + +procedure tfbservice.runcommand(const procname: string; + const params: string); +var + ar1: msestringarty; +begin + gettext(procname,params,ar1,1); +end; + +function tfbservice.getmsestringitem(var buffer: pointer; out res: msestring; + const cutspace: boolean = false): boolean; +var + i1,i2: int32; +begin + i1:= readvalue16(buffer); + i2:= i1; + result:= i1 <= 0; + if cutspace and not result and (pchar(buffer)[i1-1] = ' ') then begin + dec(i2); + end; + if fbso_utf8 in foptions then begin + res:= utf8tostring(buffer,i2); + end + else begin + widestringmanager.ansi2unicodemoveproc(buffer, + {$ifdef mse_fpc_3}cp_acp,{$endif}res,i2); + end; + inc(buffer,i1); +end; + +function tfbservice.getmsestringitem(var buffer: pointer; const id: int32; + var value: msestring): boolean; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + getmsestringitem(buffer,value); + result:= true; + end; +end; + +procedure tfbservice.addmseparam(var params: string; const id: int32; + const value: msestring); +begin + addparam(params,id,todbstring(value)); +end; +{ +function tfbservice.getline(const procname: string; + var res: msestring; out eof: boolean): boolean; +var + params1: string; + items1: string; + buffer1: string; + po1: pointer; +begin + result:= true; + eof:= true; + params1:= ''; + addparam(params1,isc_info_svc_timeout,1); //minimal timeout (1sec) + setlength(buffer1,1024); //max line length + items1:= char(isc_info_svc_line); +// addparam(items1,isc_info_svc_timeout,1); //minimal timeout (1sec) + checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), + pointer(params1),length(items1),pointer(items1), + length(buffer1),pointer(buffer1))); + case pbyte(pointer(buffer1))^ of + isc_info_svc_line: begin //timeout? + po1:= pointer(buffer1)+1; + eof:= getmsestringitem(po1,res,true); + end; + else begin + invalidresponse(procname); + end; + end; +end; +} +function tfbservice.serverinfo(): fbserverinfoty; +var + buffer: string; + po1: pbyte; +begin + checkbusy(); + finalize(result); + fillchar(result,sizeof(result),0); + buffer:= getinfo('serverinfo',[isc_info_svc_version, + isc_info_svc_server_version,isc_info_svc_implementation, + isc_info_svc_capabilities,isc_info_svc_user_dbpath, + isc_info_svc_get_env,isc_info_svc_get_env_lock, + isc_info_svc_get_env_msg],false); + po1:= pointer(buffer); + with result do begin + while (po1^ <> isc_info_end) and (po1^ <> 0) do begin + if not (getvalueitem(po1,isc_info_svc_version,version) or + getmsestringitem(po1,isc_info_svc_server_version,server_version) or + getmsestringitem(po1,isc_info_svc_implementation,_implementation) or + getvalueitem(po1,isc_info_svc_capabilities,capabilities) or + getmsestringitem(po1,isc_info_svc_user_dbpath,user_dbpath) or + getmsestringitem(po1,isc_info_svc_get_env,get_env) or + getmsestringitem(po1,isc_info_svc_get_env_lock,get_env_lock) or + getmsestringitem(po1,isc_info_svc_get_env_msg,get_env_msg)) then begin + invalidresponse('serverinfo'); + end; + end; + end; +end; + +function tfbservice.internalusers(const ausername: string): fbuserinfoarty; +var + params1,buffer1: string; + po1: pbyte; + count: int32; + po2: pfbuserinfoty; +begin + checkbusy(); + params1:= char(isc_action_svc_display_user_adm); + if ausername <> '' then begin + addparam(params1,isc_spb_sec_username,ausername); + end; + start('users',params1); + result:= nil; + count:= 0; + buffer1:= getinfo('users',[isc_info_svc_get_users],false); + po1:= pointer(buffer1); + if po1^ <> isc_info_svc_get_users then begin + invalidresponse('users'); + end; + inc(po1,3); //additional bytes 50 0 ??? + while (po1^ <> isc_info_flag_end) and (po1^ <> isc_info_end) and + (po1^ <> 0) do begin + if po1^ = isc_spb_sec_username then begin //must be first field + additem(result,typeinfo(result),count); + po2:= @result[count-1]; + getmsestringitem(po1,isc_spb_sec_username,po2^.username) + end + else begin + if result = nil then begin + invalidresponse('users'); + end; + end; + with po2^ do begin + while (po1^ <> isc_spb_sec_username) and (po1^ <> isc_info_flag_end) and + (po1^ <> isc_info_end) and (po1^ <> 0) do begin + if not (getmsestringitem(po1,isc_spb_sec_firstname,firstname) or + getmsestringitem(po1,isc_spb_sec_middlename,middlename) or + getmsestringitem(po1,isc_spb_sec_lastname,lastname) or + getmsestringitem(po1,isc_spb_sec_groupname,groupname) or + getmsestringitem(po1,isc_spb_sql_role_name,rolename) or + getvalueitem(po1,isc_spb_sec_userid,userid) or + getvalueitem(po1,isc_spb_sec_groupid,groupid) or + getvalueitem(po1,isc_spb_sec_admin,admin)) then begin + invalidresponse('users'); + end; + end; + end; + end; + setlength(result,count); +end; + +function tfbservice.users(): fbuserinfoarty; +begin + result:= internalusers(''); +end; + +function tfbservice.user(const ausername: msestring; + var ainfo: fbuserinfoty): boolean; +var + ar1: fbuserinfoarty; +begin + ar1:= internalusers(todbstring(ausername)); + result:= ar1 <> nil; + if result then begin + ainfo:= ar1[0]; + end; +end; + +procedure tfbservice.adduserparams(var params1: string; + const ainfo: fbuserinfoty; const aitems: fbuseritemsty); +begin + with ainfo do begin + if fbu_username in aitems then begin + addmseparam(params1,isc_spb_sec_username,username); + end; + if fbu_firstname in aitems then begin + addmseparam(params1,isc_spb_sec_firstname,firstname); + end; + if fbu_middlename in aitems then begin + addmseparam(params1,isc_spb_sec_middlename,middlename); + end; + if fbu_lastname in aitems then begin + addmseparam(params1,isc_spb_sec_lastname,lastname); + end; + if fbu_groupname in aitems then begin + addmseparam(params1,isc_spb_sec_groupname,groupname); + end; + if fbu_rolename in aitems then begin + addmseparam(params1,isc_spb_sql_role_name,rolename); + end; + if fbu_userid in aitems then begin + addparam(params1,isc_spb_sec_userid,userid); + end; + if fbu_groupid in aitems then begin + addparam(params1,isc_spb_sec_groupid,groupid); + end; + if fbu_admin in aitems then begin + addparam(params1,isc_spb_sec_admin,admin); + end; + if fbu_password in aitems then begin + addparam(params1,isc_spb_sec_password,password); + end; + end; +end; + +procedure tfbservice.adduser(const ainfo: fbuserinfoty; + const items: fbuseritemsty); +var + params1: string; +begin + params1:= char(isc_action_svc_add_user); + adduserparams(params1,ainfo,items); + runcommand('adduser',params1); +end; + +procedure tfbservice.modifyuser(const ainfo: fbuserinfoty; + const items: fbuseritemsty); +var + params1: string; +begin + params1:= char(isc_action_svc_modify_user); + adduserparams(params1,ainfo,items); + runcommand('modifyuser',params1); +end; + +procedure tfbservice.deleteuser(const ausername: msestring; + const arolename: msestring = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_delete_user); + addmseparam(params1,isc_spb_sec_username,ausername); + if arolename <> '' then begin + addmseparam(params1,isc_spb_sql_role_name,arolename); + end; + runcommand('deleteuser',params1); +end; + +procedure tfbservice.gettext(const procname: string; const params: string; + var res: msestringarty; const maxrowcount: integer); + +var + circindex: int32; + + procedure add(const atext: pchar; const len: int32); + var + mstr1: msestring; + begin + if fbso_utf8 in foptions then begin + mstr1:= utf8tostring(atext,len); + end + else begin + widestringmanager.ansi2unicodemoveproc(atext, + {$ifdef mse_fpc_3}cp_acp,{$endif}mstr1,len); + end; + if (maxrowcount > 0) and (length(res) >= maxrowcount) then begin + res[circindex]:= mstr1; + inc(circindex); + if circindex >= maxrowcount then begin + circindex:= 0; + end; + end + else begin + additem(res,mstr1); + end; + end; + +var + params1,items1,buffer1: string; + po1: pointer; + pa,pb,pc,pe: pchar; + i1: int32; + remainder: string; + ar1: pointerarty; +begin + checkbusy(); + start(procname,params); + res:= nil; + params1:= ''; + addtimeout(params1,finfotimeout); + setlength(buffer1,4096); + items1:= char(isc_info_svc_to_eof); + remainder:= ''; + circindex:= 0; + while true do begin + checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), + pointer(params1),length(items1),pointer(items1), + length(buffer1),pointer(buffer1))); + case pbyte(pointer(buffer1))^ of + isc_info_svc_to_eof: begin + po1:= pointer(buffer1)+1; + i1:= readvalue16(po1); + if i1 <= 0 then begin + if serviceisrunning() then begin + dberror(procname+': Timeout',self,true); + end; + break; //eof + end; + if i1 > length(buffer1)-1-2 then begin + invalidresponse(procname); + end; + if maxrowcount <> 0 then begin + pa:= po1; + pb:= pa; + pe:= pa + i1; + while (pb < pe) do begin + if pb^ = c_linefeed then begin + pc:= pb; + if (pc > pa) and ((pc-1)^ = c_return) then begin + dec(pc); + end; + if remainder <> '' then begin + remainder:= remainder+stringsegment(pa,pb); + add(pointer(remainder),length(remainder)); + remainder:= ''; + end + else begin + add(pa,pc-pa); + end; + pa:= pb+1; + end; + inc(pb); + end; + remainder:= remainder+stringsegment(pa,pe); + end; + end; + else begin + invalidresponse(procname); + end; + end; + end; + if maxrowcount <> 0 then begin + add(pointer(remainder),length(remainder)); + end; + if circindex > 0 then begin + allocuninitedarray(length(res),sizeof(pointer),ar1); + i1:= maxrowcount-circindex; + move(res[circindex],ar1[0],i1*sizeof(pointer)); + move(res[0],ar1[i1],circindex*sizeof(pointer)); + res:= pointer(ar1); + pointer(ar1):= nil; + +// ar1:= copy(res,circindex,maxrowcount-circindex); +// stackarray(copy(res,0,circindex),ar1); +// res:= ar1; + end; + exclude(fstate,fbss_busy); +end; + +procedure tfbservice.startmonitor(const procname: string; const aparams: string); +begin +// checkbusy(); + start(procname,aparams); + freeandnil(fmonitor); + fmonitor:= tfbservicemonitor.create(self,procname); +end; + +function tfbservice.serviceisrunning(): boolean; +var + buffer1: string; + po1: pointer; + ca1: card32; +begin + result:= false; + if busy then begin + buffer1:= getinfo('serviceisrunning',[isc_info_svc_running],true); + po1:= pointer(buffer1); + if getvalueitem(po1,isc_info_svc_running,ca1) then begin + result:= ca1 <> 0; + end; + end; +end; + +procedure tfbservice.getlog(var res: msestringarty; + const maxrowcount: int32 = -1); +begin + tagaction('getlog',isc_action_svc_get_fb_log,res,maxrowcount); +end; + +procedure tfbservice.tracestart(const cfg: msestring; + const _name: msestring = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_trace_start); + addmseparam(params1,isc_spb_trc_cfg,cfg); + if _name <> '' then begin + addmseparam(params1,isc_spb_trc_name,_name); + end; + startmonitor('tracestart',params1); +end; + +procedure tfbservice.tagaction(const aprocname: string; const aaction: int32; + var res: msestringarty; + const maxrowcount: int32); +begin + gettext(aprocname,char(aaction),res,maxrowcount); +end; + +procedure tfbservice.tagaction(const aprocname: string; const aaction: int32); +var + ar1: msestringarty; +begin + tagaction(aprocname,aaction,ar1,1); +end; + +procedure tfbservice.tracelist(var res: msestringarty; + const maxrowcount: int32 = -1); +begin + tagaction('tracelist',isc_action_svc_trace_list,res,maxrowcount); +end; + +procedure tfbservice.traceaction(const aprocname: string; const aaction: int32; + const aid: card32; var res: msestringarty; + const maxrowcount: int32); +var + params1: string; +begin + params1:= char(aaction); + addparam(params1,isc_spb_trc_id,aid); + gettext(aprocname,params1,res,maxrowcount); +end; + +procedure tfbservice.tracestop(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('tracestop',isc_action_svc_trace_stop,aid,res,maxrowcount); +end; + +procedure tfbservice.tracesuspend(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('tracesuspend',isc_action_svc_trace_suspend,aid,res,maxrowcount); +end; + +procedure tfbservice.traceresume(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('traceresume',isc_action_svc_trace_resume,aid,res,maxrowcount); +end; + +procedure tfbservice.setmapping(); +begin + tagaction('setmapping',isc_action_svc_set_mapping); +end; + +procedure tfbservice.dropmapping(); +begin + tagaction('dropmapping',isc_action_svc_drop_mapping); +end; + +procedure tfbservice.dbstats(const adbname: msestring; + const aoptions: dbstatoptionsty; const acommandline: msestring; + var res: msestringarty; const maxrowcount: int32 = -1); +var + params1: string; +begin + params1:= char(isc_action_svc_db_stats); + addmseparam(params1,isc_spb_dbname,adbname); + addparam(params1,isc_spb_options,card32(aoptions)); + if acommandline <> '' then begin + addmseparam(params1,isc_spb_command_line,acommandline); + end; + gettext('dbstats',params1,res,maxrowcount); +end; + +procedure tfbservice.properties(const adbname: msestring; + const ainfo: fbpropertyinfoty; const aitems: fbpropertyitemsty; + var res: msestringarty; const maxrowcount: integer); +var + params1: string; + ca1: card32; + opt1: propertyoptionty; +begin + params1:= char(isc_action_svc_properties); + addmseparam(params1,isc_spb_dbname,adbname); + with ainfo do begin + if fbp_pagebuffers in aitems then begin + addparam(params1,isc_spb_prp_page_buffers,pagebuffers); + end; + if fbp_sweepinterval in aitems then begin + addparam(params1,isc_spb_prp_sweep_interval,sweepinterval); + end; + if fbp_shutdowndb in aitems then begin + addparam(params1,isc_spb_prp_shutdown_db,shutdowndb); + end; + if fbp_denynewattachments in aitems then begin + addparam(params1,isc_spb_prp_deny_new_attachments,denynewattachments); + end; + if fbp_denynewtransactions in aitems then begin + addparam(params1,isc_spb_prp_deny_new_transactions,denynewtransactions); + end; + if fbp_reservespace in aitems then begin + addparam(params1,isc_spb_prp_reserve_space, + card8(reservespaceconsts[reservespace])); + end; + if fbp_writemode in aitems then begin + addparam(params1,isc_spb_prp_write_mode, + card8(writemodeconsts[writemode])); + end; + if fbp_accessmode in aitems then begin + addparam(params1,isc_spb_prp_access_mode, + card8(accessmodeconsts[accessmode])); + end; + if fbp_setsqldialect in aitems then begin + addparam(params1,isc_spb_prp_set_sql_dialect,setsqldialect); + end; + if fbp_options in aitems then begin + ca1:= 0; + for opt1:= low(opt1) to high(opt1) do begin + ca1:= ca1 or propertyconsts[opt1]; + end; + addparam(params1,isc_spb_options,ca1); + end; + if fbp_forceshutdown in aitems then begin + addparam(params1,isc_spb_prp_force_shutdown,forceshutdown); + end; + if fbp_attachmentsshutdown in aitems then begin + addparam(params1,isc_spb_prp_attachments_shutdown,attachmentsshutdown); + end; + if fbp_transactionsshutdown in aitems then begin + addparam(params1,isc_spb_prp_transactions_shutdown,transactionsshutdown); + end; + if fbp_shutdownmode in aitems then begin + addparam(params1,isc_spb_prp_shutdown_mode,card8(shutdownmode)); + end; + if fbp_onlinemode in aitems then begin + addparam(params1,isc_spb_prp_online_mode,card8(onlinemode)); + end; + end; + gettext('properties',params1,res,maxrowcount); +end; + +procedure tfbservice.validatestart(const dbname: msestring; + const tabincl: msestring = ''; const tabexcl: msestring = ''; + const idxincl: msestring = ''; const idxexcl: msestring = ''; + const locktimeout: card32 = 0); +var + params1: string; +begin + params1:= char(isc_action_svc_validate); + addmseparam(params1,isc_spb_dbname,dbname); + if tabincl <> '' then begin + addmseparam(params1,isc_spb_val_tab_incl,tabincl); + end; + if tabexcl <> '' then begin + addmseparam(params1,isc_spb_val_tab_excl,tabexcl); + end; + if idxincl <> '' then begin + addmseparam(params1,isc_spb_val_idx_incl,idxincl); + end; + if idxexcl <> '' then begin + addmseparam(params1,isc_spb_val_idx_excl,idxexcl); + end; + if locktimeout <> 0 then begin + addparam(params1,isc_spb_val_lock_timeout,locktimeout); + end; + startmonitor('validatestart',params1); +end; + +procedure tfbservice.backupstart(const dbname: msestring; + const backupfiles: array of msestring; const lengths: array of card32; + const verbose: boolean = false; const stat: string = ''; + const aoptions: backupoptionsty = []; + const factor: card32 = 0); +var + params1: string; + i1: int32; + ca1: card32; +begin + params1:= char(isc_action_svc_backup); + addmseparam(params1,isc_spb_dbname,dbname); + for i1:= 0 to high(backupfiles) do begin + addmseparam(params1,isc_spb_bkp_file,backupfiles[i1]); + if i1 <= high(lengths) then begin + addparam(params1,isc_spb_bkp_length,lengths[i1]); + end; + end; + if verbose then begin + addparam(params1,isc_spb_verbose); + end; + if stat <> '' then begin + addparam(params1,isc_spb_bkp_stat,stat); + end; + ca1:= card32(aoptions - [bao_notriggers]); + if bao_notriggers in aoptions then begin + ca1:= ca1 or $8000; + end; + addparam(params1,isc_spb_options,ca1); + startmonitor('backupstart',params1); +end; + +procedure tfbservice.restorestart(const backupfiles: array of msestring; + const dbfiles: array of msestring; const lengths: array of card32; + const verbose: boolean = false; const stat: string = ''; + const aoptions: restoreoptionsty = []; + const accessmode: accessmodety = amo_readwrite; + const buffers: card32 = 0; const pagesize: card32 = 0; + const fixfssdata: string = ''; const fixfssmetadata: string = ''); +var + params1: string; + i1: int32; + ca1: card32; + opt1: restoreoptionty; +begin + params1:= char(isc_action_svc_restore); + for i1:= 0 to high(backupfiles) do begin + addmseparam(params1,isc_spb_bkp_file,backupfiles[i1]); + end; + for i1:= 0 to high(dbfiles) do begin + addmseparam(params1,isc_spb_dbname,dbfiles[i1]); + if i1 <= high(lengths) then begin + addparam(params1,isc_spb_res_length,lengths[i1]); + end; + end; + if verbose then begin + addparam(params1,isc_spb_verbose); + end; + if stat <> '' then begin + addparam(params1,isc_spb_res_stat,stat); + end; + if aoptions <> [] then begin + ca1:= 0; + for opt1:= low(opt1) to high(opt1) do begin + if opt1 in aoptions then begin + ca1:= ca1 or restoreconsts[opt1]; + end; + end; + addparam(params1,isc_spb_options,ca1); + end; + addparam(params1,isc_spb_res_access_mode,card8(accessmodeconsts[accessmode])); + if buffers <> 0 then begin + addparam(params1,isc_spb_res_buffers,buffers); + end; + if pagesize <> 0 then begin + addparam(params1,isc_spb_res_page_size,pagesize); + end; + if fixfssdata <> '' then begin + addparam(params1,isc_spb_res_fix_fss_data,fixfssdata); + end; + if fixfssmetadata <> '' then begin + addparam(params1,isc_spb_res_fix_fss_metadata,fixfssmetadata); + end; + startmonitor('restorestart',params1); +end; + +procedure tfbservice.nbakstart(const dbname: msestring; const _file: msestring; + const level: card32; const options: nbakoptionsty; + const direct: string = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_nbak); + addmseparam(params1,isc_spb_dbname,dbname); + addmseparam(params1,isc_spb_nbk_file,_file); + addparam(params1,isc_spb_nbk_level,level); + addparam(params1,isc_spb_options,card32(options)); + if direct <> '' then begin + addparam(params1,isc_spb_nbk_direct,direct); + end; + startmonitor('nbak',params1); +end; + +procedure tfbservice.nreststart(const dbname: msestring; + const files: array of msestring; const options: nbakoptionsty); +var + params1: string; + i1: int32; +begin + params1:= char(isc_action_svc_nrest); + addmseparam(params1,isc_spb_dbname,dbname); + for i1:= 0 to high(files) do begin + addmseparam(params1,isc_spb_nbk_file,files[i1]); + end; + addparam(params1,isc_spb_options,card32(options)); + startmonitor('nrest',params1); +end; + +procedure tfbservice.repairstart(const adbname: msestring; + const aoptions: repairoptionsty); +var + params1: string; +begin + params1:= char(isc_action_svc_repair); + addmseparam(params1,isc_spb_dbname,adbname); + addparam(params1,isc_spb_options,card32(aoptions)); + startmonitor('repairstart',params1); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefbutils.pas b/mseide-msegui/lib/common/db/msefbutils.pas new file mode 100644 index 0000000..155d261 --- /dev/null +++ b/mseide-msegui/lib/common/db/msefbutils.pas @@ -0,0 +1,165 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefbutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,msqldb,msetypes{msestrings}; + +procedure fbupdateindexdefs(const sender: tcustomsqlconnection; + var indexdefs : tindexdefs; + const atablename : string); +function fbgetschemainfosql(const sender: tcustomsqlconnection; + schematype: tschematype; + schemaobjectname,schemapattern: msestring): msestring; + +implementation +uses + msesqlresult,dbconst,sysutils; + +procedure fbupdateindexdefs(const sender: tcustomsqlconnection; + var indexdefs : tindexdefs; + const atablename : string); +var + res: tsqlresult; + str1: ansistring; +begin + with sender do begin + if not assigned(Transaction) then begin + DatabaseError(SErrConnTransactionnSet); + end; + res:= tsqlresult.Create(nil); + try + with res do begin + database:= sender; + sql.text:= 'select '+ + 'ind.rdb$index_name, '+ + 'ind.rdb$relation_name, '+ + 'ind.rdb$unique_flag, '+ + 'ind_seg.rdb$field_name, '+ + 'rel_con.rdb$constraint_type '+ + 'from '+ + 'rdb$index_segments ind_seg, '+ + 'rdb$indices ind '+ + 'left outer join '+ + 'rdb$relation_constraints rel_con '+ + 'on '+ + 'rel_con.rdb$index_name = ind.rdb$index_name '+ + 'where '+ + '(ind_seg.rdb$index_name = ind.rdb$index_name) and '+ + '(ind.rdb$relation_name=''' + + msestring(uppercase(atablename)) +''') '+ + 'order by '+ + 'ind.rdb$index_name;'; + active:= true; + while not eof do begin + with indexdefs.AddIndexDef do begin + str1:= datacols[0].asstring; + name:= trim(str1); + fields:= trim(res.datacols[3].asstring); + if datacols[4].asstring = 'PRIMARY KEY' then begin + options:= options + [ixPrimary]; + end; + if datacols[2].asinteger = 1 then begin + options:= options + [ixUnique]; + end; + next; + while not eof and (str1 = datacols[0].asstring) do begin + fields:= fields + ';' + trim(datacols[3].asstring); + next; + end; + end; + end; + end; + finally + res.free; + end; + end; +end; + +function fbgetschemainfosql(const sender: tcustomsqlconnection; + schematype: tschematype; + schemaobjectname,schemapattern: msestring): msestring; +var + s : msestring; + +begin + with sender do begin + s:= ''; + case SchemaType of + stTables : s := 'select '+ + 'rdb$relation_id as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'rdb$relation_name as table_name, '+ + '0 as table_type '+ + 'from '+ + 'rdb$relations '+ + 'where '+ + '(rdb$system_flag = 0 or rdb$system_flag is null) ' + // and rdb$view_blr is null + 'order by rdb$relation_name'; + + stSysTables : s := 'select '+ + 'rdb$relation_id as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'rdb$relation_name as table_name, '+ + '0 as table_type '+ + 'from '+ + 'rdb$relations '+ + 'where '+ + '(rdb$system_flag > 0) ' + // and rdb$view_blr is null + 'order by rdb$relation_name'; + + stProcedures : s := 'select '+ + 'rdb$procedure_id as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'rdb$procedure_name as proc_name, '+ + '0 as proc_type, '+ + 'rdb$procedure_inputs as in_params, '+ + 'rdb$procedure_outputs as out_params '+ + 'from '+ + 'rdb$procedures '+ + 'WHERE '+ + '(rdb$system_flag = 0 or rdb$system_flag is null)'; + stColumns : s := 'select '+ + 'rdb$field_id as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'rdb$relation_name as table_name, '+ + 'rdb$field_name as column_name, '+ + 'rdb$field_position as column_position, '+ + '0 as column_type, '+ + '0 as column_datatype, '+ + ''''' as column_typename, '+ + '0 as column_subtype, '+ + '0 as column_precision, '+ + '0 as column_scale, '+ + '0 as column_length, '+ + '0 as column_nullable '+ + 'from '+ + 'rdb$relation_fields '+ + 'WHERE '+ + '(rdb$system_flag = 0 or rdb$system_flag is null) and'+ + ' (rdb$relation_name = ''' + Uppercase(SchemaObjectName) + ''') ' + + 'order by rdb$field_name'; + else + DatabaseError(SMetadataUnavailable) + end; {case} + result := s; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefirebird.pas b/mseide-msegui/lib/common/db/msefirebird.pas new file mode 100644 index 0000000..fbb993c --- /dev/null +++ b/mseide-msegui/lib/common/db/msefirebird.pas @@ -0,0 +1,469 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefirebird; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + firebird,msestrings,msectypes,msetypes; +{$define cvcall} +const +{$ifdef mswindows} + {$define wincall} + firebirdlib: array[0..0] of filenamety = ('fbclient.dll'); +{$else} + firebirdlib: array[0..2] of filenamety = + ('libfbclient.so.3','libfbclient.so.2','libfbclient.so'); +{$endif} + +const + SQL_TEXT = 452; + SQL_VARYING = 448; + SQL_SHORT = 500; + SQL_LONG = 496; + SQL_FLOAT = 482; + SQL_DOUBLE = 480; + SQL_D_FLOAT = 530; + SQL_TIMESTAMP = 510; + SQL_BLOB = 520; + SQL_ARRAY = 540; + SQL_QUAD = 550; + SQL_TYPE_TIME = 560; + SQL_TYPE_DATE = 570; + SQL_INT64 = 580; + SQL_BOOLEAN = 32764; + SQL_NULL = 32766; + + CS_NONE = 0; //* No Character Set */ + CS_BINARY = 1; //* BINARY BYTES */ + CS_ASCII = 2; //* ASCII */ + CS_UNICODE_FSS = 3; //* UNICODE in FSS format */ + CS_UTF8 = 4; //* UTF-8 */ + +{$ifdef cpu64} + FB_DOUBLE_ALIGN = 8; +{$else} + FB_DOUBLE_ALIGN = 4; //check! +{$endif} + ISC_TIME_SECONDS_PRECISION = 10000; + GDS_EPOCH_START = 40617; + fbdatetimeoffset = -15018; //fpdate -> tdatetime; + EPB_version1 = 1; + +(* +#define dtype_unknown 0 +#define dtype_text 1 +#define dtype_cstring 2 +#define dtype_varying 3 + +#define dtype_packed 6 +#define dtype_byte 7 +#define dtype_short 8 +#define dtype_long 9 +#define dtype_quad 10 +#define dtype_real 11 +#define dtype_double 12 +#define dtype_d_float 13 +#define dtype_sql_date 14 +#define dtype_sql_time 15 +#define dtype_timestamp 16 +#define dtype_blob 17 +#define dtype_array 18 +#define dtype_int64 19 +#define dtype_dbkey 20 +#define dtype_boolean 21 +#define DTYPE_TYPE_MAX 22 + +static const USHORT type_alignments[DTYPE_TYPE_MAX] = +{ + 0, + 0, /* dtype_text */ + 0, /* dtype_cstring */ + sizeof(SSHORT), /* dtype_varying */ + 0, /* unused */ + 0, /* unused */ + sizeof(SCHAR), /* dtype_packed */ + sizeof(SCHAR), /* dtype_byte */ + sizeof(SSHORT), /* dtype_short */ + sizeof(SLONG), /* dtype_long */ + sizeof(SLONG), /* dtype_quad */ + sizeof(float), /* dtype_real */ + FB_DOUBLE_ALIGN, /* dtype_double */ + FB_DOUBLE_ALIGN, /* dtype_d_float */ + sizeof(GDS_DATE), /* dtype_sql_date */ + sizeof(GDS_TIME), /* dtype_sql_time */ + sizeof(GDS_DATE), /* dtype_timestamp */ + sizeof(SLONG), /* dtype_blob */ + sizeof(SLONG), /* dtype_array */ + sizeof(SINT64), /* dtype_int64 */ + sizeof(ULONG), /* dtype_dbkey */ + sizeof(UCHAR) /* dtype_boolean */ +}; + +static const USHORT type_lengths[DTYPE_TYPE_MAX] = +{ + 0, + 0, /* dtype_text */ + 0, /* dtype_cstring */ + 0, /* dtype_varying */ + 0, /* unused */ + 0, /* unused */ + 0, /* dtype_packed */ + sizeof(SCHAR), /* dtype_byte */ + sizeof(SSHORT), /* dtype_short */ + sizeof(SLONG), /* dtype_long */ + sizeof(ISC_QUAD), /* dtype_quad */ + sizeof(float), /* dtype_real */ + sizeof(double), /* dtype_double */ + sizeof(double), /* dtype_d_float */ + sizeof(GDS_DATE), /* dtype_sql_date */ + sizeof(GDS_TIME), /* dtype_sql_time */ + sizeof(GDS_TIMESTAMP), /* dtype_timestamp */ + sizeof(ISC_QUAD), /* dtype_blob */ + sizeof(ISC_QUAD), /* dtype_array */ + sizeof(SINT64), /* dtype_int64 */ + sizeof(RecordNumber::Packed), /*dtype_dbkey */ + sizeof(UCHAR) /* dtype_boolean */ +}; +*) + +//****************************/ +//* Common, structural codes */ +//****************************/ + + isc_info_end = 1; + isc_info_truncated = 2; + isc_info_error = 3; + isc_info_data_not_ready = 4; + isc_info_length = 126; + isc_info_flag_end = 127; + +//**************************/ +//* Blob information items */ +//**************************/ + + isc_info_blob_num_segments = 4; + isc_info_blob_max_segment = 5; + isc_info_blob_total_length = 6; + isc_info_blob_type = 7; + +//*************************/ +//* SQL information items */ +//*************************/ + + isc_info_sql_select = 4; + isc_info_sql_bind = 5; + isc_info_sql_num_variables = 6; + isc_info_sql_describe_vars = 7; + isc_info_sql_describe_end = 8; + isc_info_sql_sqlda_seq = 9; + isc_info_sql_message_seq = 10; + isc_info_sql_type = 11; + isc_info_sql_sub_type = 12; + isc_info_sql_scale = 13; + isc_info_sql_length = 14; + isc_info_sql_null_ind = 15; + isc_info_sql_field = 16; + isc_info_sql_relation = 17; + isc_info_sql_owner = 18; + isc_info_sql_alias = 19; + isc_info_sql_sqlda_start = 20; + isc_info_sql_stmt_type = 21; + isc_info_sql_get_plan = 22; + isc_info_sql_records = 23; + isc_info_sql_batch_fetch = 24; + isc_info_sql_relation_alias = 25; + isc_info_sql_explain_plan = 26; + isc_info_sql_stmt_flags = 27; + +//*********************************/ +//* SQL information return values */ +//*********************************/ + + isc_info_sql_stmt_select = 1; + isc_info_sql_stmt_insert = 2; + isc_info_sql_stmt_update = 3; + isc_info_sql_stmt_delete = 4; + isc_info_sql_stmt_ddl = 5; + isc_info_sql_stmt_get_segment = 6; + isc_info_sql_stmt_put_segment = 7; + isc_info_sql_stmt_exec_procedure = 8; + isc_info_sql_stmt_start_trans = 9; + isc_info_sql_stmt_commit = 10; + isc_info_sql_stmt_rollback = 11; + isc_info_sql_stmt_select_for_upd = 12; + isc_info_sql_stmt_set_generator = 13; + isc_info_sql_stmt_savepoint = 14; + +//*****************************/ +//* Request information items */ +//*****************************/ + + isc_info_number_messages = 4; + isc_info_max_message = 5; + isc_info_max_send = 6; + isc_info_max_receive = 7; + isc_info_state = 8; + isc_info_message_number = 9; + isc_info_message_size = 10; + isc_info_request_cost = 11; + isc_info_access_path = 12; + isc_info_req_select_count = 13; + isc_info_req_insert_count = 14; + isc_info_req_update_count = 15; + isc_info_req_delete_count = 16; + + isc_spb_version = isc_spb_current_version; + isc_spb_user_name = isc_dpb_user_name; //shortstring + isc_spb_password = isc_dpb_password; //shortstring + isc_spb_sql_role_name = isc_dpb_sql_role_name; + isc_spb_res_stat = isc_spb_bkp_stat; + +type + {$packrecords c} + SSHORT = cshort; + USHORT = cushort; + SLONG = int32; + ULONG = card32; + pULONG = ^ULONG; + ISC_USHORT = cushort; + ISC_SHORT = cshort; + pISC_SHORT = ^ISC_SHORT; + ISC_LONG = SLONG; + pISC_QUAD = ^ISC_QUAD; + + ISC_DATE = int32; + pISC_DATE = ^ISC_DATE; + ISC_TIME = card32; + pISC_TIME = ^ISC_TIME; + + ISC_TIMESTAMP = record + timestamp_date: ISC_DATE; + timestamp_time: ISC_TIME; + end; + pISC_TIMESTAMP = ^ISC_TIMESTAMP; + ISC_STATUS = ptrint; + pISC_STATUS = ^ISC_STATUS; + + vary = record + vary_length: ISC_USHORT; + vary_string: record + end; + end; + pvary = ^vary; + + fbapity = record + master: imaster; + status: istatus; + provider: iprovider; + util: iutil; + end; + +procedure inifbapi(var api: fbapity); +procedure finifbapi(var api: fbapity); + +procedure initializefirebird(const sonames: array of filenamety; + const onlyonce: boolean = false); + //[] = default +procedure releasefirebird(); + +function formatstatus(status: istatus): string; +function event_block(out eventbuffer: pbyte; + const names: array of string): int32; +procedure freeeventblock(var eventbuffer: pbyte); + +var + fb_get_master_interface: function: IMaster + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_client_major_version: function(): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_client_minor_version: function(): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gds__alloc: function (size_request: SLONG): pointer + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gds__free: function(blk: pointer): ULONG; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gds__vax_integer: function (ptr: pbyte; length: SSHORT): ISC_LONG; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +(* + gds__event_block: function (event_buffer: ppbyte; result_buffer: ppbyte; + count: USHORT; names: array of const):ISC_LONG + {$ifdef cvcall}cdecl{$else}error{$endif}; {varargs;} +*) + isc_event_counts: procedure (result_vector: pULONG; legth: SSHORT; + before: pbyte; after: pbyte) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gds__sqlcode: function(status_vector: pISC_STATUS): SLONG + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +implementation +uses + msedynload,sysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +var + libinfo: dynlibinfoty; + master: imaster; + util: iutil; + +procedure initfb(const data: pointer); +begin + master:= fb_get_master_interface(); + util:= master.getutilinterface(); +end; + +procedure releasefb(const data: pointer); +begin + master.getdispatcher().shutdown(nil,0,0); +end; + +procedure inifbapi(var api: fbapity); +begin + initializefirebird([],true); + with api do begin + if master = nil then begin + master:= fb_get_master_interface(); + end; + if status = nil then begin + status:= master.getstatus(); + end; + if provider = nil then begin + provider:= master.getdispatcher(); + end; + if util = nil then begin + util:= master.getutilinterface(); + end; + end; +end; + +procedure finifbapi(var api: fbapity); +begin + with api do begin + util:= nil; + provider:= nil; + if status <> nil then begin + status.dispose(); + status:= nil; + end; + master:= nil; + end; +end; + +procedure initializefirebird(const sonames: array of filenamety; //[] = default + const onlyonce: boolean = false); + +const + funcs: array[0..7] of funcinfoty = ( + (n: 'fb_get_master_interface'; d: @fb_get_master_interface), + (n: 'isc_get_client_major_version'; d: @isc_get_client_major_version), + (n: 'isc_get_client_minor_version'; d: @isc_get_client_minor_version), + (n: 'gds__vax_integer'; d: @gds__vax_integer), +// (n: 'gds__event_block'; d: @gds__event_block), + (n: 'isc_event_counts'; d: @isc_event_counts), + (n: 'gds__alloc'; d: @gds__alloc), + (n: 'gds__free'; d: @gds__free), + (n: 'gds__sqlcode'; d: @gds__sqlcode) + ); + errormessage = 'Can not load Firebird library. '; + +begin + if not onlyonce or (libinfo.refcount = 0) then begin + initializedynlib(libinfo,sonames,firebirdlib,funcs,[],errormessage,@initfb); + end; +end; + +procedure releasefirebird(); +begin + releasedynlib(libinfo,@releasefb); +end; + +function event_block(out eventbuffer: pbyte; + const names: array of string): int32; +var + i1,i2,i3: int32; + po1: pbyte; +begin + i2:= 1; + for i1:= 0 to high(names) do begin + i3:= length(names[i1]); + if i3 > 255 then begin + raise exception.create('event_block: name too long'); + end; + i2:= i2 + i3 + 5; + end; + result:= i2; + po1:= gds__alloc(i2); + eventbuffer:= po1; + po1^:= EPB_version1; + inc(po1); + for i1:= 0 to high(names) do begin + i3:= length(names[i1]); + po1^:= i3; + inc(po1); + move(pointer(names[i1])^,po1^,i3); + inc(po1,i3); + po1^:= 0; + inc(po1); + po1^:= 0; + inc(po1); + po1^:= 0; + inc(po1); + po1^:= 0; + inc(po1); + end; +end; + +procedure freeeventblock(var eventbuffer: pbyte); +begin + if eventbuffer <> nil then begin + gds__free(eventbuffer); + eventbuffer:= nil; + end; +end; + +function formatstatus(status: istatus): string; +var + ca1: card32; +begin + setlength(result,256); + while true do begin + ca1:= util.formatstatus(pointer(result),length(result),status); + if ca1 < length(result) then begin + break; + end; + setlength(result,2*length(result)); + end; + setlength(result,ca1); +end; + +initialization + initializelibinfo(libinfo); +finalization + if libinfo.refcount > 0 then begin + libinfo.refcount:= 1; + releasefirebird(); + end; + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/db/mseibconnection.pas b/mseide-msegui/lib/common/db/mseibconnection.pas new file mode 100644 index 0000000..bdb2aa7 --- /dev/null +++ b/mseide-msegui/lib/common/db/mseibconnection.pas @@ -0,0 +1,110 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseibconnection; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mclasses,mibconnection,msetypes{msestrings}, + msedb,msesqldb,msqldb,ibase60dyn, + msebufdataset,msedatabase; +type + tmseibconnection = class(tibconnection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + //idbcontroller + function readsequence(const sequencename: string): msestring; override; + function sequencecurrvalue(const sequencename: string): msestring; override; + function writesequence(const sequencename: string; + const avalue: largeint): msestring; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils,sysutils,mseformatstr; + +{ tmseibconnection } + +procedure tmseibconnection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmseibconnection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmseibconnection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tmseibconnection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tmseibconnection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmseibconnection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tmseibconnection.readsequence(const sequencename: string): msestring; +begin + result:= 'select gen_id('+msestring(sequencename)+ + ',1) as res from RDB$DATABASE;'; +end; + +function tmseibconnection.sequencecurrvalue( + const sequencename: string): msestring; +begin + result:= 'select gen_id('+msestring(sequencename)+ + ',0) as res from RDB$DATABASE;'; +end; + +function tmseibconnection.writesequence(const sequencename: string; + const avalue: largeint): msestring; +begin + result:= 'set generator '+msestring(sequencename)+ + ' to '+inttostrmse(avalue)+';'; +end; + +function tmseibconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/mselocaldataset.pas b/mseide-msegui/lib/common/db/mselocaldataset.pas new file mode 100644 index 0000000..756fd6e --- /dev/null +++ b/mseide-msegui/lib/common/db/mselocaldataset.pas @@ -0,0 +1,426 @@ +{ MSEgui Copyright (c) 2009-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mselocaldataset; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,msestrings,msebufdataset,msedb,mseapplication,msetypes; + +const + defaultlocaldsoptions = defaultdscontrolleroptions + [dso_utf8]; + defaultlocalbdsoptions = defaultbufdatasetoptions + [bdo_local,bdo_noapply]; +type + tlocaldscontroller = class(tdscontroller) + protected +// procedure setoptions(const avalue: datasetoptionsty); override; + public + constructor create(const aowner: tdataset; const aintf: idscontroller; + const arecnooffset: integer = 0; + const acancelresync: boolean = true); + published + property options default defaultlocaldsoptions; + end; + + tlocaldataset = class(tmsebufdataset,imselocate,idscontroller,igetdscontroller, + iactivatorclient) + private +// fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; +// function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; +// function getfiltereditkind: filtereditkindty; +// procedure beginfilteredit(const akind: filtereditkindty); +// procedure endfilteredit; +// procedure doidleapplyupdates; + protected + procedure setoptions(const avalue: bufdatasetoptionsty) override; + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; +// procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; + function islocal: boolean; override; +// procedure dscontrolleroptionschanged( +// const aoptions: datasetoptionsty); override; + + function fetch : boolean; override; + function getblobdatasize: integer; override; + function blobscached: boolean; override; + function loadfield(const afieldno: integer; const afieldtype: tfieldtype{const afield: tfield}; + const buffer: pointer; + var bufsize: integer): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; +{ + function locate(const akeys: array of const; + const afields: array of tfield; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +} +{ + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +} + function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override; + procedure appendrecord(const values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property options default defaultlocalbdsoptions; + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property FieldDefs; + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; + property BeforeScroll; + property AfterScroll; + property OnCalcFields; + property OnDeleteError; + property OnEditError; + property OnFilterRecord; + property OnNewRecord; + property OnPostError; + property onmodified; + property AutoCalcFields; + end; + +implementation + +{ tlocaldscontroller } + +constructor tlocaldscontroller.create(const aowner: tdataset; + const aintf: idscontroller; const arecnooffset: integer = 0; + const acancelresync: boolean = true); +begin + inherited; + foptions:= defaultlocaldsoptions; +end; +{ +procedure tlocaldscontroller.setoptions(const avalue: datasetoptionsty); +begin + inherited setoptions(avalue + [dso_local]); +end; +} +{ tlocaldataset } + +constructor tlocaldataset.create(aowner: tcomponent); +begin + inherited; + foptions:= defaultlocalbdsoptions; + fcontroller:= tlocaldscontroller.create(self,idscontroller(self),-1,false); +end; + +destructor tlocaldataset.destroy; +begin + fcontroller.free; + inherited; +end; +{ +function tlocaldataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tlocaldataset.locate(const key: msestring; + const field: tfield; const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +procedure tlocaldataset.appendrecord(const values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tlocaldataset.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tlocaldataset.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tlocaldataset.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tlocaldataset.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tlocaldataset.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +procedure tlocaldataset.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tlocaldataset.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tlocaldataset.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tlocaldataset.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tlocaldataset.inheritedcancel; +begin + inherited cancel; +end; + +procedure tlocaldataset.cancel; +begin + fcontroller.cancel; +end; + +function tlocaldataset.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tlocaldataset.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tlocaldataset.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tlocaldataset.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tlocaldataset.inheritedinternalopen; +begin + openlocal(); +// inherited internalopen; +end; + +procedure tlocaldataset.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tlocaldataset.inheritedpost; +begin + inherited post; +end; + +procedure tlocaldataset.post; +begin + fcontroller.post; +end; + +procedure tlocaldataset.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tlocaldataset.internaldelete; +begin + fcontroller.internaldelete; +end; +{ +procedure tlocaldataset.openlocal; +begin + inherited internalopen; +end; +} +procedure tlocaldataset.inheritedinternalclose; +begin + if not (bs_refreshing in fbstate) then begin + if DefaultFields then begin + DestroyFields; + end; + end; + inherited internalclose; +end; + +procedure tlocaldataset.internalclose; +begin + fcontroller.internalclose; +end; + +function tlocaldataset.getblobdatasize: integer; +begin + result:= sizeof(int64); //max +end; + +function tlocaldataset.getnumboolean: boolean; +begin + result:= true; +end; + +function tlocaldataset.getfloatdate: boolean; +begin + result:= true; +end; + +function tlocaldataset.getint64currency: boolean; +begin + result:= true; +end; +{ +function tlocaldataset.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; +} +{ +procedure tlocaldataset.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tlocaldataset.endfilteredit; +begin + //dummy +end; +} +{ +procedure tlocaldataset.doidleapplyupdates; +begin + //dummy +end; +} +procedure tlocaldataset.setoptions(const avalue: bufdatasetoptionsty); +begin + inherited setoptions(avalue + [bdo_local]); +end; + +function tlocaldataset.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify; +end; + +function tlocaldataset.fetch: boolean; +begin + result:= false; +end; + +function tlocaldataset.blobscached: boolean; +begin + result:= false; +end; + +function tlocaldataset.islocal: boolean; +begin + result:= true; +end; + +function tlocaldataset.loadfield(const afieldno: integer; + const afieldtype: tfieldtype; const buffer: pointer; + var bufsize: integer): boolean; +begin + result:= false; +end; + +function tlocaldataset.CreateBlobStream(Field: TField; + Mode: TBlobStreamMode): TStream; +var + info: blobcacheinfoty; +// int1: integer; + blob1: blobinfoty; +begin + result:= inherited createblobstream(field,mode); + if result = nil then begin + if (bs_blobsfetched in fbstate) and (mode = bmread) then begin + info.id:= 0; //fieldsize can be 32 bit + if field.getdata(@info.id) and findcachedblob(info) then begin + blob1.data:= pointer(info.data); + blob1.datalength:= length(info.data); + result:= tblobcopy.create(blob1); + end; + end + else begin + if mode = bmwrite then begin + result:= createblobbuffer(field); + end; + end; + end; +end; + +procedure tlocaldataset.inheriteddelete(); +begin + inherited delete(); +end; + +procedure tlocaldataset.inheritedinsert(); +begin + inherited insert(); +end; +{ +procedure tlocaldataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +end. diff --git a/mseide-msegui/lib/common/db/mselookupbuffer.pas b/mseide-msegui/lib/common/db/mselookupbuffer.pas new file mode 100644 index 0000000..002c246 --- /dev/null +++ b/mseide-msegui/lib/common/db/mselookupbuffer.pas @@ -0,0 +1,1963 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mselookupbuffer; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface + +uses + classes,mclasses,mdb,msedb,msetypes,msestrings,mseclasses,msearrayprops,mselist, + msearrayutils,mseapplication,mseglob,mseinterfaces; + +const + changeeventtag = 85839; +type + tcustomlookupbuffer = class; + tcustomdblookupbuffer = class; + + lookupbufferfieldnoty = type integer; + lbdatakindty = (lbdk_none,lbdk_integer,lbdk_int64,lbdk_float,lbdk_text); + + ilookupbufferfieldinfo = interface(inullinterface)[miid_ilookupbufferfieldinfo] + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + end; + + lbfiltereventty = procedure(const sender: tcustomlookupbuffer; + const physindex: integer; var valid: boolean) of object; + + tlookupbufferdatalink = class(tmsedatalink) + private + fowner: tcustomlookupbuffer; + public + constructor create(const aowner: tcustomlookupbuffer); + end; + + tlookupbufferfieldsdatalink = class(tlookupbufferdatalink) + private + procedure datachanged; + protected + procedure activechanged; override; + procedure updatedata; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + public + constructor create(const aowner: tcustomdblookupbuffer); + end; + + tlookupbuffermemodatalink = class(tlookupbufferdatalink) + protected + procedure recordchanged(field: tfield); override; + end; + + stringindexinfoty = record + indexcasesensitive: integerarty; + indexcaseinsensitive: integerarty; + data: msestringarty; + end; + stringindexinfoarty = array of stringindexinfoty; + + integerindexinfoty = record + index: integerarty; + data: integerarty; + end; + integerindexinfoarty = array of integerindexinfoty; + + int64indexinfoty = record + index: integerarty; + data: int64arty; + end; + int64indexinfoarty = array of int64indexinfoty; + + floatindexinfoty = record + index: integerarty; + data: realarty; + end; + floatindexinfoarty = array of floatindexinfoty; + + lookupbufferstatety = (lbs_changed,lbs_buffervalid,lbs_changeeventposted, + lbs_sourceclosed); + lookupbufferstatesty = set of lookupbufferstatety; + lookupbuffereventty = procedure(const sender: tcustomlookupbuffer) of object; + + tcustomlookupbuffer = class(tactcomponent) + private + // fbuffervalid: boolean; + fonchange: notifyeventty; + fbeforeload: lookupbuffereventty; + fafterload: lookupbuffereventty; + procedure checkindex(const index: integer); + function internalfind(const avalue; var index: integerarty; + var data; const itemsize: integer; + compfunc: arraysortcomparety; const filter: lbfiltereventty; + out aindex: integer): boolean;//true if exact else next bigger + protected + fupdating: integer; + fcount: integer; + fstate: lookupbufferstatesty; + ftextdata: stringindexinfoarty; + fintegerdata: integerindexinfoarty; + ffloatdata: floatindexinfoarty; + fint64data: int64indexinfoarty; + function getfieldcounttext: integer; virtual; + function getfieldcountinteger: integer; virtual; + function getfieldcountfloat: integer; virtual; + function getfieldcountint64: integer; virtual; + procedure setfieldcounttext(const avalue: integer); virtual; + procedure setfieldcountinteger(const avalue: integer); virtual; + procedure setfieldcountfloat(const avalue: integer); virtual; + procedure setfieldcountint64(const avalue: integer); virtual; + procedure invalidatebuffer; + procedure readonlyprop; + procedure changed; + procedure asyncchanged; //calls changed by postevent + procedure doasyncevent(var atag: integer); override; + procedure setcount(const avalue: integer); + procedure loaded; override; + function checkfilter(const filter: lbfiltereventty; + const index: integerarty; var aindex: integer): boolean; + procedure checkindexar(var aitem: integerindexinfoty); overload; + procedure checkindexar(var aitem: floatindexinfoty); overload; + procedure checkindexar(var aitem: int64indexinfoty); overload; + procedure checkindexar(var aitem: stringindexinfoty; + const caseinsensitive: boolean); overload; + procedure checkarrayindex(const value; const index: integer); + //calls checkbuffer + procedure doloadbuffer() virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure beginupdate; + procedure endupdate; + procedure clearbuffer; virtual; + procedure checkbuffer; //automatically called + procedure loadbuffer; + + function find(const fieldno: integer; const avalue: integer; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //logical index, true if found else next bigger + function find(const fieldno: integer; const avalue: realty; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //logical index, true if found else next bigger + function find(const fieldno: integer; const avalue: int64; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //logical index, true if found else next bigger + function find(const fieldno: integer; const avalue: msestring; + out aindex: integer; + const caseinsensitive: boolean; + const filter: lbfiltereventty = nil): boolean; overload; + //logical index, true if found else next bigger + + function findphys(const fieldno: integer; const avalue: integer; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //physical index, true if found else -1 + function findphys(const fieldno: integer; const avalue: realty; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //physical index, true if found else -1 + function findphys(const fieldno: integer; const avalue: int64; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //physical index, true if found else -1 + function findphys(const fieldno: integer; const avalue: msestring; + out aindex: integer; + const caseinsensitive: boolean; + const filter: lbfiltereventty = nil): boolean; overload; + //physical index, true if found else -1 + + function integervaluephys(const fieldno,aindex: integer): integer; + //physical index + function integervaluelog(const fieldno,aindex: integer): integer; + //logical index + function integerindex(const fieldno,aindex: integer): integer; + //logical -> physical index + function integerindexar(const fieldno: integer): integerarty; + function integerar(const fieldno: integer): integerarty; + + function floatvaluephys(const fieldno,aindex: integer): realty; + //physical index + function floatvaluelog(const fieldno,aindex: integer): realty; + //logical index + function floatindex(const fieldno,aindex: integer): integer; + //logical -> physical index + function floatindexar(const fieldno: integer): integerarty; + function floatar(const fieldno: integer): realarty; + + function int64valuephys(const fieldno,aindex: integer): int64; + //physical index + function int64valuelog(const fieldno,aindex: integer): int64; + //logical index + function int64index(const fieldno,aindex: integer): integer; + //logical -> physical index + function int64indexar(const fieldno: integer): integerarty; + function int64ar(const fieldno: integer): int64arty; + + function textvaluephys(const fieldno,aindex: integer): msestring; + //physical index + function textvaluelog(const fieldno,aindex: integer; + const caseinsensitive: boolean): msestring; + //logical index + function textindex(const fieldno,aindex: integer; + const caseinsensitive: boolean): integer; + //logical -> physical index + function textindexar(const fieldno: integer; + const caseinsensitive: boolean): integerarty; + function textar(const fieldno: integer): msestringarty; + + function lookupinteger(const integerkeyfieldno,integerfieldno, + keyvalue: integer; + const adefault: integer = 0): integer; overload; + function lookupinteger(const int64keyfieldno,integerfieldno: integer; + const keyvalue: int64; + const adefault: integer = 0): integer; overload; + function lookupinteger(const stringkeyfieldno,integerfieldno: integer; + const keyvalue: msestring; + const adefault: integer = 0): integer; overload; + function lookupint64(const integerkeyfieldno,int64fieldno, + keyvalue: integer; + const adefault: int64 = 0): int64; overload; + function lookupint64(const int64keyfieldno,int64fieldno: integer; + const keyvalue: int64; + const adefault: int64 = 0): int64; overload; + function lookupint64(const stringkeyfieldno,int64fieldno: integer; + const keyvalue: msestring; + const adefault: int64 = 0): int64; overload; + function lookuptext(const integerkeyfieldno,textfieldno, + keyvalue: integer; + const adefault: msestring = ''): msestring; overload; + function lookuptext(const int64keyfieldno,textfieldno: integer; + const keyvalue: int64; + const adefault: msestring = ''): msestring; overload; + function lookuptext(const stringkeyfieldno,textfieldno: integer; + const keyvalue: msestring; + const adefault: msestring = ''): msestring; overload; + function lookupfloat(const integerkeyfieldno,floatfieldno,keyvalue: integer; + const adefault: realty = emptyreal): realty; overload; + function lookupfloat(const int64keyfieldno,floatfieldno: integer; + const keyvalue: int64; + const adefault: realty = emptyreal): realty; overload; + function lookupfloat(const stringkeyfieldno,floatfieldno: integer; + const keyvalue: msestring; + const adefault: realty = emptyreal): realty; overload; + + function count: integer; virtual; + procedure addrow(const integervalues: array of integer; + const textvalues: array of msestring; + const floatvalues: array of realty; + const int64values: array of int64); + procedure addrows(const integervalues: array of integerarty; + const textvalues: array of msestringarty; + const floatvalues: array of realarty; + const int64values: array of int64arty); + + function fieldnamestext: stringarty; virtual; + function fieldnamesfloat: stringarty; virtual; + function fieldnamesinteger: stringarty; virtual; + function fieldnamesint64: stringarty; virtual; + + property fieldcounttext: integer read getfieldcounttext + write setfieldcounttext default 0; + property fieldcountfloat: integer read getfieldcountfloat + write setfieldcountfloat default 0; + property fieldcountinteger: integer read getfieldcountinteger + write setfieldcountinteger default 0; + property fieldcountint64: integer read getfieldcountint64 + write setfieldcountint64 default 0; + property integervalue[const fieldno,aindex: integer]: integer + read integervaluephys; + property floatvalue[const fieldno,aindex: integer]: realty + read floatvaluephys; + property int64value[const fieldno,aindex: integer]: int64 + read int64valuephys; + property textvalue[const fieldno,aindex: integer]: msestring + read textvaluephys; + property beforeload: lookupbuffereventty read fbeforeload write fbeforeload; + property afterload: lookupbuffereventty read fafterload write fafterload; + property onchange: notifyeventty read fonchange write fonchange; + end; + + tlookupbuffer = class(tcustomlookupbuffer) + public +{ + procedure addrow(const integervalues: array of integer; + const textvalues: array of msestring; + const floatvalues: array of realty; + const int64values: array of int64); + procedure addrows(const integervalues: array of integerarty; + const textvalues: array of msestringarty; + const floatvalues: array of realarty; + const int64values: array of int64arty); +} + published + property fieldcounttext; + property fieldcountinteger; + property fieldcountint64; + property fieldcountfloat; + property beforeload; + property afterload; + property onchange; + end; + + tdatalookupbuffer = class(tcustomlookupbuffer) + protected + procedure loaded; override; + procedure setfieldcounttext(const avalue: integer); override; + procedure setfieldcountinteger(const avalue: integer); override; + procedure setfieldcountfloat(const avalue: integer); override; + procedure setfieldcountint64(const avalue: integer); override; + procedure fieldschanged(const sender: tarrayprop; const index: integer); + public + function count: integer; override; + published + property beforeload; + property afterload; + property onchange; + end; + + lbdboptionty = (olbdb_closedataset,olbdb_invalidateifmodified); + lbdboptionsty = set of lbdboptionty; + + tcustomdblookupbuffer = class(tdatalookupbuffer) + private + fdatalink: tlookupbufferdatalink; + ftextfields: tdbfieldnamearrayprop; + fintegerfields: tdbfieldnamearrayprop; + ffloatfields: tdbfieldnamearrayprop; + fint64fields: tdbfieldnamearrayprop; + foptionsdb: lbdboptionsty; + function getdatasource: tdatasource; + procedure setdatasource(const avalue: tdatasource); + procedure settextfields(const avalue: tdbfieldnamearrayprop); + procedure setintegerfields(const avalue: tdbfieldnamearrayprop); + procedure setfloatfields(const avalue: tdbfieldnamearrayprop); + procedure setint64fields(const avalue: tdbfieldnamearrayprop); + procedure getfields(out aintegerfields,atextfields,afloatfields, + aint64fields: fieldarty); + protected + function getfieldcounttext: integer; override; + function getfieldcountinteger: integer; override; + function getfieldcountfloat: integer; override; + function getfieldcountint64: integer; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clearbuffer; override; + property datasource: tdatasource read getdatasource write setdatasource; + + function fieldnamestext: stringarty; override; + function fieldnamesfloat: stringarty; override; + function fieldnamesinteger: stringarty; override; + function fieldnamesint64: stringarty; override; + + property textfields: tdbfieldnamearrayprop read ftextfields write settextfields; + property integerfields: tdbfieldnamearrayprop read fintegerfields write setintegerfields; + property floatfields: tdbfieldnamearrayprop read ffloatfields write setfloatfields; + property int64fields: tdbfieldnamearrayprop read fint64fields write setint64fields; + property optionsdb: lbdboptionsty read foptionsdb write foptionsdb default []; + end; + + tdblookupbuffer = class(tcustomdblookupbuffer) + protected + procedure doloadbuffer; override; + public + constructor create(aowner: tcomponent); override; + published + property datasource; + property textfields; + property integerfields; + property int64fields; + property floatfields; + property optionsdb; + end; + + tdbmemolookupbuffer = class(tcustomdblookupbuffer) + protected + procedure doloadbuffer; override; + public + constructor create(aowner: tcomponent); override; + published + property datasource; + property textfields; + property integerfields; + property floatfields; + end; + +implementation +uses + rtlconsts,sysutils,{msereal,}mseformatstr; + +type + tarrayprop1 = class(tarrayprop); + +{ tcustomlookupbuffer } + +constructor tcustomlookupbuffer.create(aowner: tcomponent); +begin + inherited; +end; + +destructor tcustomlookupbuffer.destroy; +begin + inherited; +end; + +procedure tcustomlookupbuffer.invalidatebuffer; +begin + exclude(fstate,lbs_buffervalid); +// fbuffervalid:= false; +end; + +procedure tcustomlookupbuffer.clearbuffer; +var + int1: integer; +begin + for int1:= 0 to high(fintegerdata) do begin + with fintegerdata[int1] do begin + index:= nil; + data:= nil; + end; + end; + for int1:= 0 to high(fint64data) do begin + with fint64data[int1] do begin + index:= nil; + data:= nil; + end; + end; + for int1:= 0 to high(ftextdata) do begin + with ftextdata[int1] do begin + indexcasesensitive:= nil; + indexcaseinsensitive:= nil; + data:= nil; + end; + end; + for int1:= 0 to high(ffloatdata) do begin + with ffloatdata[int1] do begin + index:= nil; + data:= nil; + end; + end; + for int1:= 0 to high(fint64data) do begin + with fint64data[int1] do begin + index:= nil; + data:= nil; + end; + end; + fcount:= 0; + exclude(fstate,lbs_buffervalid); +// fbuffervalid:= false; + changed; +end; + +procedure tcustomlookupbuffer.doloadbuffer(); +begin + include(fstate,lbs_buffervalid); +// fbuffervalid:= true; +end; + +procedure tcustomlookupbuffer.loadbuffer; +begin + beginupdate(); + try + clearbuffer(); + if canevent(tmethod(fbeforeload)) then begin + fbeforeload(self); + end; + doloadbuffer(); + if canevent(tmethod(fafterload)) then begin + fafterload(self); + end; + finally + endupdate(); + end; +end; + +procedure tcustomlookupbuffer.checkbuffer; +begin + if not (lbs_buffervalid in fstate) then begin + loadbuffer; + end; +end; + +function tcustomlookupbuffer.checkfilter(const filter: lbfiltereventty; + const index: integerarty; var aindex: integer): boolean; +var + int1: integer; + bo1: boolean; +begin + for int1:= aindex to high(index) do begin + bo1:= true; + filter(self,index[int1],bo1); + if bo1 then begin + aindex:= int1; + result:= true; + exit; + end; + end; + result:= false; + aindex:= length(index); +end; + +function tcustomlookupbuffer.internalfind(const avalue; var index: integerarty; + var data; const itemsize: integer; + compfunc: arraysortcomparety; const filter: lbfiltereventty; + out aindex: integer): boolean; //true if found else next bigger +var + int1: integer; + bo1: boolean; +begin + result:= findarrayvalue(avalue,data,itemsize,index,compfunc,aindex); + if assigned(filter) then begin + if result then begin + result:= false; + for int1:= aindex downto 0 do begin + if compfunc((pchar(data)+index[int1]*itemsize)^,avalue) <> 0 then begin + break; //not found + end; + bo1:= true; + filter(self,index[int1],bo1); + if bo1 then begin + result:= true; + aindex:= int1; + break; + end; + end; + end; + if aindex <= high(index) then begin + for int1:= aindex to high(index) do begin + bo1:= true; + filter(self,index[int1],bo1); + if bo1 then begin + aindex:= int1; + exit; + end; + end; + aindex:= length(index); + end; + end; +end; + +procedure tcustomlookupbuffer.checkindexar(var aitem: integerindexinfoty); +begin + with aitem do begin + if (index = nil) and (data <> nil) then begin + application.beginwait; + try + mergesortarray(data,sizeof(integer),length(data),@compareinteger, + index,false); + finally + application.endwait; + end; + end; + end; +end; + +function tcustomlookupbuffer.find(const fieldno: integer; const avalue: integer; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; +begin +// checkbuffer; + checkarrayindex(fintegerdata,fieldno); + checkindexar(fintegerdata[fieldno]); + with fintegerdata[fieldno] do begin + result:= internalfind(avalue,index,data,sizeof(integer), + @compareinteger,filter,aindex); + end; +end; + +procedure tcustomlookupbuffer.checkindexar(var aitem: floatindexinfoty); +begin + with aitem do begin + if (index = nil) and (data <> nil) then begin + application.beginwait; + try + mergesortarray(data,sizeof(realty),length(data),@comparerealty,index,false); + finally + application.endwait; + end; + end; + end; +end; + +function tcustomlookupbuffer.find(const fieldno: integer; const avalue: realty; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; +begin + checkarrayindex(ffloatdata,fieldno); + checkindexar(ffloatdata[fieldno]); + with ffloatdata[fieldno] do begin + result:= internalfind(avalue,index,data,sizeof(realty), + @comparerealty,filter,aindex); + end; +end; + +procedure tcustomlookupbuffer.checkindexar(var aitem: int64indexinfoty); +begin + with aitem do begin + if (index = nil) and (data <> nil) then begin + application.beginwait; + try + mergesortarray(data,sizeof(int64),length(data),@compareint64,index,false); + finally + application.endwait; + end; + end; + end; +end; + +function tcustomlookupbuffer.find(const fieldno: integer; const avalue: int64; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; +begin + checkarrayindex(fint64data,fieldno); + checkindexar(fint64data[fieldno]); + with fint64data[fieldno] do begin + result:= internalfind(avalue,index,data,sizeof(int64), + @compareint64,filter,aindex); + end; +end; + +procedure tcustomlookupbuffer.checkindexar(var aitem: stringindexinfoty; + const caseinsensitive: boolean); +begin + with aitem do begin + if caseinsensitive then begin + if (indexcaseinsensitive = nil) and (data <> nil) then begin + application.beginwait; + try + mergesortarray(data,sizeof(msestring),length(data),@compareimsestring, + indexcaseinsensitive,false); + finally + application.endwait; + end; + end; + end + else begin + if (indexcasesensitive = nil) and (data <> nil) then begin + application.beginwait; + try + mergesortarray(data,sizeof(msestring),length(data),@comparemsestring, + indexcasesensitive,false); + finally + application.endwait; + end; + end; + end; + end; +end; + +function tcustomlookupbuffer.find(const fieldno: integer; const avalue: msestring; + out aindex: integer; const caseinsensitive: boolean; + const filter: lbfiltereventty = nil): boolean; +//var +// int1: integer; +begin +// checkbuffer; + checkarrayindex(ftextdata,fieldno); + checkindexar(ftextdata[fieldno],caseinsensitive); + with ftextdata[fieldno] do begin + if caseinsensitive then begin + result:= internalfind(avalue,indexcaseinsensitive,data,sizeof(msestring), + @compareimsestring,filter,aindex); + end + else begin + result:= internalfind(avalue,indexcasesensitive,data,sizeof(msestring), + @comparemsestring,filter,aindex); + end; + end; +end; + +function tcustomlookupbuffer.findphys(const fieldno: integer; const avalue: integer; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; + //physical index, true if found else -1 +var + int1: integer; +begin + result:= find(fieldno,avalue,int1,filter); + if result then begin + aindex:= integerindex(fieldno,int1); + end + else begin + aindex:= -1; + end; +end; + +function tcustomlookupbuffer.findphys(const fieldno: integer; + const avalue: realty; out aindex: integer; + const filter: lbfiltereventty = nil): boolean; + //physical index, true if found else -1 +var + int1: integer; +begin + result:= find(fieldno,avalue,int1,filter); + if result then begin + aindex:= floatindex(fieldno,int1); + end + else begin + aindex:= -1; + end; +end; + +function tcustomlookupbuffer.findphys(const fieldno: integer; + const avalue: int64; out aindex: integer; + const filter: lbfiltereventty = nil): boolean; + //physical index, true if found else -1 +var + int1: integer; +begin + result:= find(fieldno,avalue,int1,filter); + if result then begin + aindex:= int64index(fieldno,int1); + end + else begin + aindex:= -1; + end; +end; + +function tcustomlookupbuffer.findphys(const fieldno: integer; const avalue: msestring; + out aindex: integer; + const caseinsensitive: boolean; + const filter: lbfiltereventty = nil): boolean; + //physical index, true if found else -1 +var + int1: integer; +begin + result:= find(fieldno,avalue,int1,caseinsensitive,filter); + if result then begin + aindex:= textindex(fieldno,int1,caseinsensitive); + end + else begin + aindex:= -1; + end; +end; + +procedure tcustomlookupbuffer.checkindex(const index: integer); +begin + if (index < 0) or (index >= fcount) then begin + tlist.Error(SListIndexError, Index); + end; +end; + +function tcustomlookupbuffer.integervaluephys(const fieldno,aindex: integer): integer; +begin + checkarrayindex(fintegerdata,fieldno); + checkindex(aindex); + result:= fintegerdata[fieldno].data[aindex]; +end; + +function tcustomlookupbuffer.integervaluelog(const fieldno,aindex: integer): integer; +begin + checkarrayindex(fintegerdata,fieldno); + checkindexar(fintegerdata[fieldno]); + checkindex(aindex); + with fintegerdata[fieldno] do begin + result:= data[index[aindex]]; + end; +end; + +function tcustomlookupbuffer.integerindex(const fieldno,aindex: integer): integer; +begin + checkarrayindex(fintegerdata,fieldno); + checkindexar(fintegerdata[fieldno]); + checkindex(aindex); + result:= fintegerdata[fieldno].index[aindex]; +end; + +function tcustomlookupbuffer.integerindexar(const fieldno: integer): integerarty; +begin + checkarrayindex(fintegerdata,fieldno); + checkindexar(fintegerdata[fieldno]); + result:= fintegerdata[fieldno].index; +end; + +function tcustomlookupbuffer.integerar(const fieldno: integer): integerarty; +begin + checkarrayindex(fintegerdata,fieldno); + result:= fintegerdata[fieldno].data; +end; + +function tcustomlookupbuffer.floatvaluephys(const fieldno,aindex: integer): realty; +begin + checkarrayindex(ffloatdata,fieldno); + checkindex(aindex); + result:= ffloatdata[fieldno].data[aindex]; +end; + +function tcustomlookupbuffer.floatvaluelog(const fieldno,aindex: integer): realty; +begin + checkarrayindex(ffloatdata,fieldno); + checkindexar(ffloatdata[fieldno]); + checkindex(aindex); + with ffloatdata[fieldno] do begin + result:= data[index[aindex]]; + end; +end; + +function tcustomlookupbuffer.floatindex(const fieldno,aindex: integer): integer; +begin + checkarrayindex(ffloatdata,fieldno); + checkindexar(ffloatdata[fieldno]); + checkindex(aindex); + result:= ffloatdata[fieldno].index[aindex]; +end; + +function tcustomlookupbuffer.floatindexar(const fieldno: integer): integerarty; +begin + checkarrayindex(ffloatdata,fieldno); + checkindexar(ffloatdata[fieldno]); + result:= ffloatdata[fieldno].index; +end; + +function tcustomlookupbuffer.floatar(const fieldno: integer): realarty; +begin + checkarrayindex(ffloatdata,fieldno); + result:= ffloatdata[fieldno].data; +end; + +function tcustomlookupbuffer.int64valuephys(const fieldno,aindex: integer): int64; +begin + checkarrayindex(fint64data,fieldno); + checkindex(aindex); + result:= fint64data[fieldno].data[aindex]; +end; + +function tcustomlookupbuffer.int64valuelog(const fieldno,aindex: integer): int64; +begin + checkarrayindex(fint64data,fieldno); + checkindexar(fint64data[fieldno]); + checkindex(aindex); + with fint64data[fieldno] do begin + result:= data[index[aindex]]; + end; +end; + +function tcustomlookupbuffer.int64index(const fieldno,aindex: integer): integer; +begin + checkarrayindex(fint64data,fieldno); + checkindexar(fint64data[fieldno]); + checkindex(aindex); + result:= fint64data[fieldno].index[aindex]; +end; + +function tcustomlookupbuffer.int64indexar(const fieldno: integer): integerarty; +begin + checkarrayindex(fint64data,fieldno); + checkindexar(fint64data[fieldno]); + result:= fint64data[fieldno].index; +end; + +function tcustomlookupbuffer.int64ar(const fieldno: integer): int64arty; +begin + checkarrayindex(fint64data,fieldno); + result:= fint64data[fieldno].data; +end; + +function tcustomlookupbuffer.textvaluephys(const fieldno,aindex: integer): msestring; +begin + checkarrayindex(ftextdata,fieldno); + checkindex(aindex); + result:= ftextdata[fieldno].data[aindex]; +end; + +function tcustomlookupbuffer.textvaluelog(const fieldno,aindex: integer; + const caseinsensitive: boolean): msestring; +begin + checkarrayindex(ftextdata,fieldno); + checkindexar(ftextdata[fieldno],caseinsensitive); + checkindex(aindex); + with ftextdata[fieldno] do begin + if caseinsensitive then begin + result:= data[indexcaseinsensitive[aindex]]; + end + else begin + result:= data[indexcasesensitive[aindex]]; + end; + end; +end; + +function tcustomlookupbuffer.textindex(const fieldno,aindex: integer; + const caseinsensitive: boolean): integer; +begin + checkarrayindex(ftextdata,fieldno); + checkindexar(ftextdata[fieldno],caseinsensitive); + checkindex(aindex); + with ftextdata[fieldno] do begin + if caseinsensitive then begin + result:= indexcaseinsensitive[aindex]; + end + else begin + result:= indexcasesensitive[aindex]; + end; + end; +end; + +function tcustomlookupbuffer.textindexar(const fieldno: integer; + const caseinsensitive: boolean): integerarty; +begin + checkarrayindex(ftextdata,fieldno); + checkindexar(ftextdata[fieldno],caseinsensitive); + if caseinsensitive then begin + result:= ftextdata[fieldno].indexcaseinsensitive; + end + else begin + result:= ftextdata[fieldno].indexcasesensitive; + end; +end; + +function tcustomlookupbuffer.textar(const fieldno: integer): msestringarty; +begin + checkarrayindex(ftextdata,fieldno); + result:= ftextdata[fieldno].data; +end; + +function tcustomlookupbuffer.count: integer; +begin + result:= fcount; +end; + +function tcustomlookupbuffer.getfieldcounttext: integer; +begin + result:= length(ftextdata); +end; + +procedure tcustomlookupbuffer.setfieldcounttext(const avalue: integer); +begin + clearbuffer; + setlength(ftextdata,avalue); +end; + +function tcustomlookupbuffer.getfieldcountinteger: integer; +begin + result:= length(fintegerdata); +end; + +procedure tcustomlookupbuffer.setfieldcountinteger(const avalue: integer); +begin + clearbuffer; + setlength(fintegerdata,avalue); +end; + +function tcustomlookupbuffer.getfieldcountfloat: integer; +begin + result:= length(ffloatdata); +end; + +function tcustomlookupbuffer.getfieldcountint64: integer; +begin + result:= length(fint64data); +end; + +procedure tcustomlookupbuffer.setfieldcountfloat(const avalue: integer); +begin + clearbuffer; + setlength(ffloatdata,avalue); +end; + +procedure tcustomlookupbuffer.setfieldcountint64(const avalue: integer); +begin + clearbuffer; + setlength(fint64data,avalue); +end; + +procedure tcustomlookupbuffer.readonlyprop; +begin + raise exception.create('Property is readonly'); +end; + +procedure tcustomlookupbuffer.beginupdate; +begin + inc(fupdating); +end; + +procedure tcustomlookupbuffer.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + changed; + end; +end; + +procedure tcustomlookupbuffer.changed; +begin + if fupdating = 0 then begin + if csloading in componentstate then begin + include(fstate,lbs_changed); + end + else begin + exclude(fstate,lbs_changed); + inc(fupdating); + try + sendchangeevent; + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + finally + dec(fupdating); + end; + end; + end; +end; + +procedure tcustomlookupbuffer.doasyncevent(var atag: integer); +begin + inherited; + if atag = changeeventtag then begin + exclude(fstate,lbs_changeeventposted); + changed; + end; +end; + +procedure tcustomlookupbuffer.asyncchanged; +begin + if not (lbs_changeeventposted in fstate) and (fupdating = 0) then begin + include(fstate,lbs_changeeventposted); + asyncevent(changeeventtag); + end; +end; + +procedure tcustomlookupbuffer.setcount(const avalue: integer); +var + int1: integer; +begin + if avalue <> fcount then begin + for int1:= 0 to high(fintegerdata) do begin + with fintegerdata[int1] do begin + setlength(data,avalue); + index:= nil; + end; + end; + for int1:= 0 to high(ftextdata) do begin + with ftextdata[int1] do begin + setlength(data,avalue); + indexcasesensitive:= nil; + indexcaseinsensitive:= nil; + end; + end; + for int1:= 0 to high(ffloatdata) do begin + with ffloatdata[int1] do begin + setlength(data,avalue); + index:= nil; + end; + end; + for int1:= 0 to high(fint64data) do begin + with fint64data[int1] do begin + setlength(data,avalue); + index:= nil; + end; + end; + fcount:= avalue; +// exclude(fstate,lbs_buffervalid); + end; +end; + +procedure tcustomlookupbuffer.loaded; +begin + inherited; + if not (lbs_buffervalid in fstate) or (lbs_changed in fstate) then begin + changed; + end; +end; + +function tcustomlookupbuffer.lookupinteger(const integerkeyfieldno,integerfieldno, + keyvalue: integer; + const adefault: integer = 0): integer; +var + int1: integer; +begin + if findphys(integerkeyfieldno,keyvalue,int1) then begin + result:= integervaluephys(integerfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupinteger(const int64keyfieldno, + integerfieldno: integer; const keyvalue: int64; + const adefault: integer = 0): integer; +var + int1: integer; +begin + if findphys(int64keyfieldno,keyvalue,int1) then begin + result:= integervaluephys(integerfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupinteger(const stringkeyfieldno: integer; + const integerfieldno: integer; + const keyvalue: msestring; + const adefault: integer = 0): integer; +var + int1: integer; +begin + if findphys(stringkeyfieldno,keyvalue,int1,false) then begin + result:= integervaluephys(integerfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupint64(const integerkeyfieldno,int64fieldno, + keyvalue: integer; + const adefault: int64 = 0): int64; +var + int1: integer; +begin + if findphys(integerkeyfieldno,keyvalue,int1) then begin + result:= int64valuephys(int64fieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupint64(const int64keyfieldno, + int64fieldno: integer; const keyvalue: int64; + const adefault: int64 = 0): int64; +var + int1: integer; +begin + if findphys(int64keyfieldno,keyvalue,int1) then begin + result:= int64valuephys(int64fieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupint64(const stringkeyfieldno, + int64fieldno: integer; + const keyvalue: msestring; + const adefault: int64 = 0): int64; +var + int1: integer; +begin + if findphys(stringkeyfieldno,keyvalue,int1,false) then begin + result:= int64valuephys(int64fieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookuptext(const integerkeyfieldno: integer; + const textfieldno: integer; const keyvalue: integer; + const adefault: msestring = ''): msestring; +var + int1: integer; +begin + if findphys(integerkeyfieldno,keyvalue,int1) then begin + result:= textvaluephys(textfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookuptext(const int64keyfieldno: integer; + const textfieldno: integer; const keyvalue: int64; + const adefault: msestring = ''): msestring; +var + int1: integer; +begin + if findphys(int64keyfieldno,keyvalue,int1) then begin + result:= textvaluephys(textfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookuptext(const stringkeyfieldno: integer; + const textfieldno: integer; + const keyvalue: msestring; + const adefault: msestring = ''): msestring; +var + int1: integer; +begin + if findphys(stringkeyfieldno,keyvalue,int1,false) then begin + result:= textvaluephys(textfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupfloat(const integerkeyfieldno: integer; + const floatfieldno: integer; const keyvalue: integer; + const adefault: realty = emptyreal): realty; +var + int1: integer; +begin + if findphys(integerkeyfieldno,keyvalue,int1) then begin + result:= floatvaluephys(floatfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupfloat(const int64keyfieldno: integer; + const floatfieldno: integer; const keyvalue: int64; + const adefault: realty = emptyreal): realty; +var + int1: integer; +begin + if findphys(int64keyfieldno,keyvalue,int1) then begin + result:= floatvaluephys(floatfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupfloat(const stringkeyfieldno, + floatfieldno: integer; const keyvalue: msestring; + const adefault: realty = emptyreal): realty; +var + int1: integer; +begin + if findphys(stringkeyfieldno,keyvalue,int1,false) then begin + result:= floatvaluephys(floatfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +procedure tcustomlookupbuffer.checkarrayindex(const value; + const index: integer); +begin + checkbuffer; + msearrayutils.checkarrayindex(value,index); +end; + +function tcustomlookupbuffer.fieldnamestext: stringarty; +begin + result:= nil; +end; + +function tcustomlookupbuffer.fieldnamesfloat: stringarty; +begin + result:= nil; +end; + +function tcustomlookupbuffer.fieldnamesinteger: stringarty; +begin + result:= nil; +end; + +function tcustomlookupbuffer.fieldnamesint64: stringarty; +begin + result:= nil; +end; + +procedure tcustomlookupbuffer.addrow(const integervalues: array of integer; + const textvalues: array of msestring; + const floatvalues: array of realty; + const int64values: array of int64); +var + int1: integer; +begin + setcount(fcount + 1); + for int1:= 0 to high(integervalues) do begin + if int1 > high(fintegerdata) then begin + break; + end; + fintegerdata[int1].data[fcount-1]:= integervalues[int1]; + end; + for int1:= 0 to high(textvalues) do begin + if int1 > high(ftextdata) then begin + break; + end; + ftextdata[int1].data[fcount-1]:= textvalues[int1]; + end; + for int1:= 0 to high(floatvalues) do begin + if int1 > high(ffloatdata) then begin + break; + end; + ffloatdata[int1].data[fcount-1]:= floatvalues[int1]; + end; + for int1:= 0 to high(int64values) do begin + if int1 > high(fint64data) then begin + break; + end; + fint64data[int1].data[fcount-1]:= int64values[int1]; + end; + changed; +end; + +procedure tcustomlookupbuffer.addrows(const integervalues: array of integerarty; + const textvalues: array of msestringarty; + const floatvalues: array of realarty; + const int64values: array of int64arty); +var + int1,int2,int3,countbefore: integer; +begin + int2:= bigint; + for int1:= 0 to high(integervalues) do begin + if high(integervalues[int1]) < int2 then begin + int2:= high(integervalues[int1]); + end; + end; + for int1:= 0 to high(textvalues) do begin + if high(textvalues[int1]) < int2 then begin + int2:= high(textvalues[int1]); + end; + end; + for int1:= 0 to high(floatvalues) do begin + if high(floatvalues[int1]) < int2 then begin + int2:= high(floatvalues[int1]); + end; + end; + for int1:= 0 to high(int64values) do begin + if high(int64values[int1]) < int2 then begin + int2:= high(int64values[int1]); + end; + end; + countbefore:= fcount; + setcount(fcount+int2+1); + for int1:= 0 to high(integervalues) do begin + if int1 > high(fintegerdata) then begin + break; + end; + for int3:= 0 to int2 do begin + fintegerdata[int1].data[int3+countbefore]:= integervalues[int1][int3]; + end; + end; + for int1:= 0 to high(textvalues) do begin + if int1 > high(ftextdata) then begin + break; + end; + for int3:= 0 to int2 do begin + ftextdata[int1].data[int3+countbefore]:= textvalues[int1][int3]; + end; + end; + for int1:= 0 to high(floatvalues) do begin + if int1 > high(ffloatdata) then begin + break; + end; + for int3:= 0 to int2 do begin + ffloatdata[int1].data[int3+countbefore]:= floatvalues[int1][int3]; + end; + end; + for int1:= 0 to high(int64values) do begin + if int1 > high(fint64data) then begin + break; + end; + for int3:= 0 to int2 do begin + fint64data[int1].data[int3+countbefore]:= int64values[int1][int3]; + end; + end; +end; + +{ tlookupbuffer } +{ +procedure tlookupbuffer.addrow(const integervalues: array of integer; + const textvalues: array of msestring; + const floatvalues: array of realty; + const int64values: array of int64); +var + int1: integer; +begin + setcount(fcount + 1); + for int1:= 0 to high(integervalues) do begin + if int1 > high(fintegerdata) then begin + break; + end; + fintegerdata[int1].data[fcount-1]:= integervalues[int1]; + end; + for int1:= 0 to high(textvalues) do begin + if int1 > high(ftextdata) then begin + break; + end; + ftextdata[int1].data[fcount-1]:= textvalues[int1]; + end; + for int1:= 0 to high(floatvalues) do begin + if int1 > high(ffloatdata) then begin + break; + end; + ffloatdata[int1].data[fcount-1]:= floatvalues[int1]; + end; + for int1:= 0 to high(int64values) do begin + if int1 > high(fint64data) then begin + break; + end; + fint64data[int1].data[fcount-1]:= int64values[int1]; + end; + changed; +end; + +procedure tlookupbuffer.addrows(const integervalues: array of integerarty; + const textvalues: array of msestringarty; + const floatvalues: array of realarty; + const int64values: array of int64arty); +var + int1,int2,int3,countbefore: integer; +begin + int2:= bigint; + for int1:= 0 to high(integervalues) do begin + if high(integervalues[int1]) < int2 then begin + int2:= high(integervalues[int1]); + end; + end; + for int1:= 0 to high(textvalues) do begin + if high(textvalues[int1]) < int2 then begin + int2:= high(textvalues[int1]); + end; + end; + for int1:= 0 to high(floatvalues) do begin + if high(floatvalues[int1]) < int2 then begin + int2:= high(floatvalues[int1]); + end; + end; + for int1:= 0 to high(int64values) do begin + if high(int64values[int1]) < int2 then begin + int2:= high(int64values[int1]); + end; + end; + countbefore:= fcount; + setcount(fcount+int2+1); + for int1:= 0 to high(integervalues) do begin + if int1 > high(fintegerdata) then begin + break; + end; + for int3:= 0 to int2 do begin + fintegerdata[int1].data[int3+countbefore]:= integervalues[int1][int3]; + end; + end; + for int1:= 0 to high(textvalues) do begin + if int1 > high(ftextdata) then begin + break; + end; + for int3:= 0 to int2 do begin + ftextdata[int1].data[int3+countbefore]:= textvalues[int1][int3]; + end; + end; + for int1:= 0 to high(floatvalues) do begin + if int1 > high(ffloatdata) then begin + break; + end; + for int3:= 0 to int2 do begin + ffloatdata[int1].data[int3+countbefore]:= floatvalues[int1][int3]; + end; + end; + for int1:= 0 to high(int64values) do begin + if int1 > high(fint64data) then begin + break; + end; + for int3:= 0 to int2 do begin + fint64data[int1].data[int3+countbefore]:= int64values[int1][int3]; + end; + end; +end; +} +{ tdatalokupbuffer } + +procedure tdatalookupbuffer.loaded; +begin + if not (lbs_buffervalid in fstate) then begin + clearbuffer; + end; + inherited; +end; + +procedure tdatalookupbuffer.setfieldcountinteger(const avalue: integer); +begin + readonlyprop; +end; + +procedure tdatalookupbuffer.setfieldcountfloat(const avalue: integer); +begin + readonlyprop; +end; + +procedure tdatalookupbuffer.setfieldcountint64(const avalue: integer); +begin + readonlyprop; +end; + +procedure tdatalookupbuffer.setfieldcounttext(const avalue: integer); +begin + readonlyprop; +end; + +function tdatalookupbuffer.count: integer; +begin + checkbuffer; + result:= inherited count; +end; + +procedure tdatalookupbuffer.fieldschanged(const sender: tarrayprop; + const index: integer); +begin + invalidatebuffer; +end; + +{ tlookupbufferdatalink } + +constructor tlookupbufferdatalink.create(const aowner: tcustomlookupbuffer); +begin + fowner:= aowner; + inherited create; +end; + +{ tcustomdblookupbuffer } + +constructor tcustomdblookupbuffer.create(aowner: tcomponent); +begin + if fdatalink = nil then begin + fdatalink:= tlookupbufferdatalink.create(self); + end; + fintegerfields:= tdbfieldnamearrayprop.create( + msedb.integerfields+[ftboolean], + {$ifdef FPC}@{$endif}getdatasource); + ftextfields:= tdbfieldnamearrayprop.create( + msedb.textfields+[ftboolean], + {$ifdef FPC}@{$endif}getdatasource); + ffloatfields:= tdbfieldnamearrayprop.create(msedb.realfields + msedb.datetimefields, + {$ifdef FPC}@{$endif}getdatasource); + fint64fields:= tdbfieldnamearrayprop.create([ftlargeint], + {$ifdef FPC}@{$endif}getdatasource); + fintegerfields.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + ftextfields.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + ffloatfields.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + fint64fields.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + inherited; +end; + +destructor tcustomdblookupbuffer.destroy; +begin + inherited; + fdatalink.free; + fintegerfields.free; + ftextfields.free; + ffloatfields.free; + fint64fields.free; +end; + +function tcustomdblookupbuffer.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tcustomdblookupbuffer.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; +end; + +procedure tcustomdblookupbuffer.setintegerfields(const avalue: tdbfieldnamearrayprop); +begin + fintegerfields.assign(avalue); +end; + +procedure tcustomdblookupbuffer.setfloatfields(const avalue: tdbfieldnamearrayprop); +begin + ffloatfields.assign(avalue); +end; + +procedure tcustomdblookupbuffer.setint64fields(const avalue: tdbfieldnamearrayprop); +begin + fint64fields.assign(avalue); +end; + +procedure tcustomdblookupbuffer.settextfields(const avalue: tdbfieldnamearrayprop); +begin + ftextfields.assign(avalue); +end; + +procedure tcustomdblookupbuffer.clearbuffer; +begin + setlength(fintegerdata,fintegerfields.count); + setlength(ftextdata,ftextfields.count); + setlength(ffloatdata,ffloatfields.count); + setlength(fint64data,fint64fields.count); + inherited; +end; + +function tcustomdblookupbuffer.getfieldcounttext: integer; +begin + result:= ftextfields.count; +end; + +function tcustomdblookupbuffer.getfieldcountinteger: integer; +begin + result:= fintegerfields.count; +end; + +function tcustomdblookupbuffer.getfieldcountfloat: integer; +begin + result:= floatfields.count; +end; + +function tcustomdblookupbuffer.getfieldcountint64: integer; +begin + result:= int64fields.count; +end; + +procedure tcustomdblookupbuffer.getfields(out aintegerfields,atextfields, + afloatfields,aint64fields: fieldarty); +var + int1: integer; +begin + with fdatalink.datasource.dataset do begin + setlength(aintegerfields,fintegerfields.count); + for int1:= 0 to high(aintegerfields) do begin + aintegerfields[int1]:= fieldbyname(fintegerfields[int1]); + end; + setlength(atextfields,ftextfields.count); + for int1:= 0 to high(atextfields) do begin + atextfields[int1]:= fieldbyname(ftextfields[int1]); + end; + setlength(afloatfields,ffloatfields.count); + for int1:= 0 to high(afloatfields) do begin + afloatfields[int1]:= fieldbyname(ffloatfields[int1]); + end; + setlength(aint64fields,fint64fields.count); + for int1:= 0 to high(aint64fields) do begin + aint64fields[int1]:= fieldbyname(fint64fields[int1]); + end; + end; +end; + +function tcustomdblookupbuffer.fieldnamestext: stringarty; +begin + result:= ftextfields.itemar; +end; + +function tcustomdblookupbuffer.fieldnamesfloat: stringarty; +begin + result:= ffloatfields.itemar; +end; + +function tcustomdblookupbuffer.fieldnamesinteger: stringarty; +begin + result:= fintegerfields.itemar; +end; + +function tcustomdblookupbuffer.fieldnamesint64: stringarty; +begin + result:= fint64fields.itemar; +end; + +{ tlookupbufferfieldsdatalink } + +constructor tlookupbufferfieldsdatalink.create(const aowner: tcustomdblookupbuffer); +begin + inherited create(aowner); +end; + +procedure tlookupbufferfieldsdatalink.datachanged; +begin + with tcustomdblookupbuffer(fowner) do begin + if active or + not active and (lbs_buffervalid in fstate) and + not (olbdb_closedataset in foptionsdb) then begin + exclude(fstate,lbs_buffervalid); + asyncchanged; + end; + end; +end; + +procedure tlookupbufferfieldsdatalink.activechanged; +begin + inherited; + datachanged; +end; + +procedure tlookupbufferfieldsdatalink.updatedata; +begin + inherited; +// if olbdb_invalidateonupdatedata in tcustomdblookupbuffer(fowner).foptionsdb then begin +// datachanged; +// end; +end; + +procedure tlookupbufferfieldsdatalink.dataevent(event: tdataevent; info: ptrint); +begin + inherited; + if (event = tdataevent(de_modified)) and + (olbdb_invalidateifmodified in + tcustomdblookupbuffer(fowner).foptionsdb) then begin + datachanged; + end; +end; + +{ tdblookupbuffer } + +constructor tdblookupbuffer.create(aowner: tcomponent); +begin + fdatalink:= tlookupbufferfieldsdatalink.create(self); + inherited; +end; + +procedure tdblookupbuffer.doloadbuffer; +var + int1,int3,int4: integer; + bm: string; + textf: fieldarty; + integerf: fieldarty; + realf: fieldarty; + int64f: fieldarty; + datas: tdataset; + utf8: boolean; + bo1: boolean; + ismsestringfield: booleanarty; + statebefore: tdatasetstate; + eofbefore: boolean; +begin +{ + beginupdate; + try + clearbuffer; +} + datas:= fdatalink.dataset; + if (datas <> nil) and + (datas.active or + (olbdb_closedataset in foptionsdb) and + (lbs_sourceclosed in fstate) and + not (csloading in datas.componentstate)) then begin + utf8:= fdatalink.utf8; + bo1:= fdatalink.active; + if bo1 then begin + exclude(fstate,lbs_sourceclosed); + end; + application.beginwait; + try + datas.disablecontrols; + try + datas.active:= true; + try + bm:= datas.bookmark; + statebefore:= datas.state; + eofbefore:= datas.eof; + try + getfields(integerf,textf,realf,int64f); + setlength(ismsestringfield,length(textf)); + for int1:= high(ismsestringfield) downto 0 do begin + ismsestringfield[int1]:= textf[int1] is tmsestringfield; + end; + datas.first; + int3:= fcount; + int1:= fcount; + try + while not datas.eof do begin + if int3 <= int1 then begin + int3:= (int3 * 3) div 2 + 100; + for int4:= 0 to high(ftextdata) do begin + setlength(ftextdata[int4].data,int3); + end; + for int4:= 0 to high(fintegerdata) do begin + setlength(fintegerdata[int4].data,int3); + end; + for int4:= 0 to high(fint64data) do begin + setlength(fint64data[int4].data,int3); + end; + for int4:= 0 to high(ffloatdata) do begin + setlength(ffloatdata[int4].data,int3); + end; + end; + for int4:= 0 to high(integerf) do begin + if integerf[int4] <> nil then begin + fintegerdata[int4].data[int1]:= integerf[int4].asinteger; + end; + end; + for int4:= 0 to high(int64f) do begin + if int64f[int4] <> nil then begin + fint64data[int4].data[int1]:= int64f[int4].aslargeint; + end; + end; + for int4:= 0 to high(realf) do begin + if realf[int4] <> nil then begin + if realf[int4].isnull then begin + ffloatdata[int4].data[int1]:= emptyreal; + end + else begin + ffloatdata[int4].data[int1]:= realf[int4].asfloat; + end; + end; + end; + for int4:= 0 to high(textf) do begin + if textf[int4] <> nil then begin + if ismsestringfield[int4] then begin + ftextdata[int4].data[int1]:= tmsestringfield(textf[int4]).asmsestring; + end + else begin + try + if utf8 then begin + ftextdata[int4].data[int1]:= utf8tostringansi(textf[int4].asstring); + end + else begin + ftextdata[int4].data[int1]:= msestring(textf[int4].asstring); + end; + except + ftextdata[int4].data[int1]:= converrorstring; + end; + end; + end; + end; + inc(int1); + datas.next; + end; + finally + for int4:= 0 to high(fintegerdata) do begin + setlength(fintegerdata[int4].data,int1); + end; + for int4:= 0 to high(fint64data) do begin + setlength(fint64data[int4].data,int1); + end; + for int4:= 0 to high(ftextdata) do begin + setlength(ftextdata[int4].data,int1); + end; + for int4:= 0 to high(ffloatdata) do begin + setlength(ffloatdata[int4].data,int1); + end; + fcount:= int1; + end; + finally + datas.bookmark:= bm; + if statebefore = dsinsert then begin + if eofbefore then begin + datas.append; + end + else begin + datas.insert; + end; + end; + end; + finally + if {not bo1 and} (olbdb_closedataset in foptionsdb) and + not (csdesigning in componentstate)then begin + include(fstate,lbs_sourceclosed); + datas.active:= false; + end; + end; + include(fstate,lbs_buffervalid); //no recursion in enablecontrols + finally + datas.enablecontrols; + end; + finally + application.endwait; + end; + end; + include(fstate,lbs_buffervalid); +{ + finally + endupdate; + end; +} +end; + +{ tlookupbuffermemodatalink } + +procedure tlookupbuffermemodatalink.recordchanged(field: tfield); +begin + with fowner do begin + if (fupdating = 0) and (lbs_buffervalid in fstate) then begin + exclude(fstate,lbs_buffervalid); +// fbuffervalid:= false; + changed; + end; + end; +end; + +{ tdbmemolookupbuffer } + +constructor tdbmemolookupbuffer.create(aowner: tcomponent); +begin + fdatalink:= tlookupbuffermemodatalink.create(self); + inherited; + fintegerfields.fieldtypes:= memofields + msedb.textfields; + ftextfields.fieldtypes:= memofields + msedb.textfields; + ffloatfields.fieldtypes:= memofields + msedb.textfields; +end; + +procedure tdbmemolookupbuffer.doloadbuffer; +var + textf: fieldarty; + integerf: fieldarty; + realf: fieldarty; + int64f: fieldarty; + ar3: stringarty; + int1,int2: integer; + utf8: boolean; +begin +{ + beginupdate; + try + clearbuffer; +} + if fdatalink.active then begin + utf8:= fdatalink.utf8; + getfields(integerf,textf,realf,int64f); + for int1:= 0 to high(integerf) do begin + if not integerf[int1].isnull then begin + ar3:= breaklines(integerf[int1].asstring); + setlength(fintegerdata[int1].data,length(ar3)); + for int2:= 0 to high(ar3) do begin + fintegerdata[int1].data[int2]:= strtoint(ar3[int2]); + end; + end; + end; + for int1:= 0 to high(realf) do begin + if not realf[int1].isnull then begin + ar3:= breaklines(realf[int1].asstring); + setlength(ffloatdata[int1].data,length(ar3)); + for int2:= 0 to high(ar3) do begin + ffloatdata[int1].data[int2]:= strtorealty(ar3[int2]); + end; + end; + end; + for int1:= 0 to high(int64f) do begin + if not int64f[int1].isnull then begin + ar3:= breaklines(int64f[int1].asstring); + setlength(fint64data[int1].data,length(ar3)); + for int2:= 0 to high(ar3) do begin + fint64data[int1].data[int2]:= strtoint64(ar3[int2]); + end; + end; + end; + for int1:= 0 to high(textf) do begin + if utf8 then begin + ftextdata[int1].data:= breaklines(utf8tostringansi(textf[int1].asstring)); + end + else begin + ftextdata[int1].data:= breaklines(msestring(textf[int1].asstring)); + end; + end; + int2:= bigint; + for int1:= 0 to high(fintegerdata) do begin + if high(fintegerdata[int1].data) < int2 then begin + int2:= high(fintegerdata[int1].data); + end; + end; + for int1:= 0 to high(fint64data) do begin + if high(fint64data[int1].data) < int2 then begin + int2:= high(fint64data[int1].data); + end; + end; + for int1:= 0 to high(ffloatdata) do begin + if high(ffloatdata[int1].data) < int2 then begin + int2:= high(ffloatdata[int1].data); + end; + end; + for int1:= 0 to high(ftextdata) do begin + if high(ftextdata[int1].data) < int2 then begin + int2:= high(ftextdata[int1].data); + end; + end; + setcount(int2+1); + end; + include(fstate,lbs_buffervalid); +{ + finally +// fbuffervalid:= true; + endupdate; + end; +} +end; + +end. diff --git a/mseide-msegui/lib/common/db/msememds.pas b/mseide-msegui/lib/common/db/msememds.pas new file mode 100644 index 0000000..e2157ad --- /dev/null +++ b/mseide-msegui/lib/common/db/msememds.pas @@ -0,0 +1,354 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msememds; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,memds,msedb,msestrings,mseapplication; +type + tmsememdataset = class(tmemdataset,imselocate,idscontroller,igetdscontroller, + iactivatorclient) + private + fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + end; + +implementation + +{ tmsememdataset } + +constructor tmsememdataset.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsememdataset.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsememdataset.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsememdataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tmsememdataset.locate(const key: msestring; + const field: tfield; const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +procedure tmsememdataset.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsememdataset.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsememdataset.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsememdataset.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsememdataset.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsememdataset.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsememdataset.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsememdataset.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsememdataset.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsememdataset.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsememdataset.cancel; +begin + fcontroller.cancel; +end; + +function tmsememdataset.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsememdataset.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsememdataset.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tmsememdataset.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsememdataset.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsememdataset.internalopen; +begin + if getrecordsize = 0 then begin + createtable; + end; + fcontroller.internalopen; +end; + +procedure tmsememdataset.inheritedpost; +begin + inherited post; +end; + +procedure tmsememdataset.post; +begin + fcontroller.post; +end; + +procedure tmsememdataset.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsememdataset.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsememdataset.openlocal; +begin + inherited internalopen; +end; + +procedure tmsememdataset.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsememdataset.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsememdataset.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsememdataset.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsememdataset.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsememdataset.getint64currency: boolean; +begin + result:= false; +end; + +function tmsememdataset.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsememdataset.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsememdataset.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsememdataset.endfilteredit; +begin + //dummy +end; + +procedure tmsememdataset.clearfilter; +begin + //dummy +end; +{ +procedure tmsememdataset.doidleapplyupdates; +begin + //dummy +end; +} +function tmsememdataset.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsememdataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsememdataset.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsememdataset.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsememdataset.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +procedure tmsememdataset.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmsememdataset.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsememdataset.begindisplaydata; +begin + //dummy +end; + +procedure tmsememdataset.enddisplaydata; +begin + //dummy +end; + +procedure tmsememdataset.inheriteddelete; +begin + inherited delete(); +end; + +procedure tmsememdataset.inheritedinsert; +begin + inherited insert(); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msemysql40conn.pas b/mseide-msegui/lib/common/db/msemysql40conn.pas new file mode 100644 index 0000000..e40d42e --- /dev/null +++ b/mseide-msegui/lib/common/db/msemysql40conn.pas @@ -0,0 +1,65 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msemysql40conn; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mmysql40conn,msetypes{msestrings},msedb,msedatabase,msqldb; + +type + tmsemysql40connection = class(tmysql40connection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils; + +{ tmsemysql40connection } + +procedure tmsemysql40connection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmsemysql40connection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmsemysql40connection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsemysql40connection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmsemysql40connection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msemysql41conn.pas b/mseide-msegui/lib/common/db/msemysql41conn.pas new file mode 100644 index 0000000..b33f74a --- /dev/null +++ b/mseide-msegui/lib/common/db/msemysql41conn.pas @@ -0,0 +1,86 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msemysql41conn; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mclasses,mmysql41conn,msetypes{msestrings}, + msedb,msqldb,msedatabase; + +type + tmsemysql41connection = class(tmysql41connection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils,msesqldb,msebufdataset; + +{ tmsemysql41connection } + +procedure tmsemysql41connection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmsemysql41connection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmsemysql41connection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tmsemysql41connection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsemysql41connection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmsemysql41connection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tmsemysql41connection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msemysql50conn.pas b/mseide-msegui/lib/common/db/msemysql50conn.pas new file mode 100644 index 0000000..c016010 --- /dev/null +++ b/mseide-msegui/lib/common/db/msemysql50conn.pas @@ -0,0 +1,85 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msemysql50conn; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mclasses,mmysql50conn,msetypes{msestrings},msedb, + msqldb,msedatabase; + +type + tmsemysql50connection = class(tmysql50connection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils,msesqldb,msebufdataset; + +{ tmsemysql50connection } + +procedure tmsemysql50connection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmsemysql50connection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmsemysql50connection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tmsemysql50connection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsemysql50connection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmsemysql50connection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tmsemysql50connection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msemysqlconn.pas b/mseide-msegui/lib/common/db/msemysqlconn.pas new file mode 100644 index 0000000..1bb5454 --- /dev/null +++ b/mseide-msegui/lib/common/db/msemysqlconn.pas @@ -0,0 +1,84 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msemysqlconn; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mclasses,mmysqlconn,msetypes{msestrings},msedb,msqldb,msedatabase; + +type + tmsemysqlconnection = class(tmysqlconnection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils,msesqldb,msebufdataset; + +{ tmsemysqlconnection } + +procedure tmsemysqlconnection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmsemysqlconnection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmsemysqlconnection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tmsemysqlconnection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsemysqlconnection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmsemysqlconnection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tmsemysqlconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/mseodbcconn.pas b/mseide-msegui/lib/common/db/mseodbcconn.pas new file mode 100644 index 0000000..31585fc --- /dev/null +++ b/mseide-msegui/lib/common/db/mseodbcconn.pas @@ -0,0 +1,78 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseodbcconn; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mclasses,modbcconn,msetypes{msestrings},msedb,msedatabase,msqldb; +type + tmseodbcconnection = class(todbcconnection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils,msesqldb,msebufdataset; + +{ tmseodbcconnection } + +procedure tmseodbcconnection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmseodbcconnection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmseodbcconnection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmseodbcconnection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmseodbcconnection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tmseodbcconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + + +end. diff --git a/mseide-msegui/lib/common/db/msepqconnection.pas b/mseide-msegui/lib/common/db/msepqconnection.pas new file mode 100644 index 0000000..067b877 --- /dev/null +++ b/mseide-msegui/lib/common/db/msepqconnection.pas @@ -0,0 +1,189 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepqconnection; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,mpqconnection,msestrings,msedb,msetypes,msqldb,mdb, + msedatabase; +type + pqconnectionoptionty = (pqco_usesavepoint,pqco_closetransactiononfail); + pqconnectionoptionsty = set of pqconnectionoptionty; + +const + defaultpqconnectionoptionsty = [pqco_usesavepoint]; + +type + tmsepqconnection = class(tpqconnection,idbcontroller) + private + foptions: pqconnectionoptionsty; + fsavepointlock: boolean; + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + procedure setoptions(const avalue: pqconnectionoptionsty); + protected + procedure loaded; override; + procedure internalexecute(const cursor: tsqlcursor; + const atransaction: tsqltransaction; + const aparams: tmseparams; const autf8: boolean); override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + //idbcontroller + function readsequence(const sequencename: string): msestring; override; + function sequencecurrvalue(const sequencename: string): msestring; override; + function writesequence(const sequencename: string; + const avalue: largeint): msestring; override; + public + constructor create(aowner: tcomponent); override; + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected + default false; + property options: pqconnectionoptionsty read foptions write setoptions + default defaultpqconnectionoptionsty; +end; + +implementation +uses + msefileutils,msebits,sysutils,msedatalist,msesqldb,msebufdataset,postgres3dyn, + mseformatstr; + +{ tmsepqconnection } + +constructor tmsepqconnection.create(aowner: tcomponent); +begin + foptions:= defaultpqconnectionoptionsty; + inherited; +end; + +procedure tmsepqconnection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmsepqconnection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmsepqconnection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tmsepqconnection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsepqconnection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmsepqconnection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +procedure tmsepqconnection.internalexecute(const cursor: tsqlcursor; + const atransaction: tsqltransaction; + const aparams: tmseparams; const autf8: boolean); +const + savepointname = 'mseinternal$savepoint'; +var + bo1: boolean; + conn1: ppgconn; +begin + if fsavepointlock then begin + inherited; + end + else begin + conn1:= TPQTrans(aTransaction.Handle).conn; + fsavepointlock:= true; + bo1:= (pqco_usesavepoint in foptions) and not (tao_fake in atransaction.options); + try + if bo1 then begin +// executedirect('SAVEPOINT '+savepointname+';',atransaction); + dopqexec('SAVEPOINT '+savepointname+';',conn1); + end; + try + inherited; + except + if pqco_closetransactiononfail in foptions then begin + atransaction.active:= false; + end + else begin + if bo1 then begin +// executedirect('ROLLBACK TO SAVEPOINT '+savepointname+';',atransaction); + dopqexec('ROLLBACK TO SAVEPOINT '+savepointname+';',conn1); +// executedirect('RELEASE SAVEPOINT '+savepointname+';',atransaction); + dopqexec('RELEASE SAVEPOINT '+savepointname+';',conn1); + end; + end; + raise; + end; + if bo1 then begin +// executedirect('RELEASE SAVEPOINT '+savepointname+';',atransaction); + dopqexec('RELEASE SAVEPOINT '+savepointname+';',conn1); + end; + finally + fsavepointlock:= false; + end; + end; +end; + +procedure tmsepqconnection.setoptions(const avalue: pqconnectionoptionsty); +const + mask: pqconnectionoptionsty = [pqco_usesavepoint,pqco_closetransactiononfail]; +begin + foptions:= pqconnectionoptionsty( + setsinglebit({$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); +end; + +function tmsepqconnection.readsequence(const sequencename: string): msestring; +begin + result:= 'select nextval(''' +msestring(sequencename)+''') as res;'; +end; + +function tmsepqconnection.sequencecurrvalue( + const sequencename: string): msestring; +begin + result:= 'select last_value from ' + msestring(sequencename) + ';'; +end; + +function tmsepqconnection.writesequence(const sequencename: string; + const avalue: largeint): msestring; +begin + result:= 'select setval(''' +msestring(sequencename)+''','+ + inttostrmse(avalue)+');'; +end; + +function tmsepqconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msesdfdata.pas b/mseide-msegui/lib/common/db/msesdfdata.pas new file mode 100644 index 0000000..f5ea821 --- /dev/null +++ b/mseide-msegui/lib/common/db/msesdfdata.pas @@ -0,0 +1,725 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesdfdata; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,msdfdata,msedb,msetypes{msestrings},mseapplication; +type + tmsefixedformatdataset = class(tfixedformatdataset,imselocate, + idscontroller,igetdscontroller,iactivatorclient) + private + ffilename: filenamety; + fcontroller: tdscontroller; + procedure setfilename(const avalue: filenamety); + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller +// procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; + { + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; + } + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property FileName: filenamety read ffilename write setfilename; + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + property FileMustExist default true; + property Readonly default false; + end; + + tmsesdfdataset = class(tsdfdataset,imselocate,idscontroller,igetdscontroller, + iactivatorclient) + private + ffilename: filenamety; + fcontroller: tdscontroller; + procedure setfilename(const avalue: filenamety); + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller +// procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalclose; override; + procedure internalinsert; override; + procedure internaldelete; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const options: locateoptionsty= []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property FileName: filenamety read ffilename write setfilename; + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + property FileMustExist default true; + property Readonly default false; + property FirstLineAsSchema default false; + end; + +implementation +uses + msefileutils; + +{ tmsefixedformatdataset } + +constructor tmsefixedformatdataset.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsefixedformatdataset.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsefixedformatdataset.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsefixedformatdataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tmsefixedformatdataset.locate(const key: msestring; + const field: tfield; const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +procedure tmsefixedformatdataset.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsefixedformatdataset.setfilename(const avalue: filenamety); +begin + ffilename:= tomsefilepath(avalue); + inherited filename:= ansistring( + tosysfilepath(filepath(avalue,fk_default,true))); +end; + +procedure tmsefixedformatdataset.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsefixedformatdataset.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsefixedformatdataset.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsefixedformatdataset.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsefixedformatdataset.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsefixedformatdataset.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsefixedformatdataset.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsefixedformatdataset.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; +{ +procedure tmsefixedformatdataset.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsefixedformatdataset.Resync(Mode: TResyncMode); +begin + fcontroller.resync(mode); +end; +} +procedure tmsefixedformatdataset.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsefixedformatdataset.cancel; +begin + fcontroller.cancel; +end; + +function tmsefixedformatdataset.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsefixedformatdataset.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsefixedformatdataset.internalinsert; +begin + fcontroller.internalinsert; +end; + + +procedure tmsefixedformatdataset.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsefixedformatdataset.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsefixedformatdataset.inheritedpost; +begin + inherited post; +end; + +procedure tmsefixedformatdataset.post; +begin + fcontroller.post; +end; + +function tmsefixedformatdataset.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsefixedformatdataset.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsefixedformatdataset.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsefixedformatdataset.openlocal; +begin + inherited internalopen; +end; + +procedure tmsefixedformatdataset.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsefixedformatdataset.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsefixedformatdataset.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsefixedformatdataset.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsefixedformatdataset.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsefixedformatdataset.getint64currency: boolean; +begin + result:= false; +end; + +function tmsefixedformatdataset.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsefixedformatdataset.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsefixedformatdataset.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsefixedformatdataset.endfilteredit; +begin + //dummy +end; + +procedure tmsefixedformatdataset.clearfilter; +begin + //dummy +end; +{ +procedure tmsefixedformatdataset.doidleapplyupdates; +begin + //dummy +end; +} +function tmsefixedformatdataset.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsefixedformatdataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsefixedformatdataset.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsefixedformatdataset.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsefixedformatdataset.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +function tmsefixedformatdataset.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsefixedformatdataset.begindisplaydata; +begin + //dummy +end; + +procedure tmsefixedformatdataset.enddisplaydata; +begin + //dummy +end; + +procedure tmsefixedformatdataset.inheriteddelete; +begin + inherited delete(); +end; + +procedure tmsefixedformatdataset.inheritedinsert; +begin + inherited insert(); +end; + +{ tmsesdfdataset } + +constructor tmsesdfdataset.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsesdfdataset.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsesdfdataset.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsesdfdataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tmsesdfdataset.locate(const key: msestring; + const field: tfield; const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +procedure tmsesdfdataset.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsesdfdataset.setfilename(const avalue: filenamety); +begin + ffilename:= tomsefilepath(avalue); + inherited filename:= ansistring( + tosysfilepath(filepath(avalue,fk_default,true))); +end; + +procedure tmsesdfdataset.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsesdfdataset.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsesdfdataset.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsesdfdataset.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsesdfdataset.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsesdfdataset.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsesdfdataset.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsesdfdataset.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +{ +procedure tmsesdfdataset.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsesdfdataset.Resync(Mode: TResyncMode); +begin + fcontroller.resync(mode); +end; +} +procedure tmsesdfdataset.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsesdfdataset.cancel; +begin + fcontroller.cancel; +end; + +function tmsesdfdataset.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsesdfdataset.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsesdfdataset.internalinsert; +begin + fcontroller.internalinsert; +end; + +procedure tmsesdfdataset.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsesdfdataset.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsesdfdataset.inheritedpost; +begin + inherited post; +end; + +procedure tmsesdfdataset.post; +begin + fcontroller.post; +end; + +function tmsesdfdataset.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsesdfdataset.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsesdfdataset.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsesdfdataset.openlocal; +begin + inherited internalopen; +end; + +procedure tmsesdfdataset.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsesdfdataset.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsesdfdataset.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsesdfdataset.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsesdfdataset.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsesdfdataset.getint64currency: boolean; +begin + result:= false; +end; + +function tmsesdfdataset.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsesdfdataset.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsesdfdataset.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsesdfdataset.endfilteredit; +begin + //dummy +end; + +procedure tmsesdfdataset.clearfilter; +begin + //dummy +end; +{ +procedure tmsesdfdataset.doidleapplyupdates; +begin + //dummy +end; +} +function tmsesdfdataset.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsesdfdataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsesdfdataset.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsesdfdataset.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsesdfdataset.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +function tmsesdfdataset.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsesdfdataset.begindisplaydata; +begin + //dummy +end; + +procedure tmsesdfdataset.enddisplaydata; +begin + //dummy +end; + +procedure tmsesdfdataset.inheriteddelete; +begin + inherited delete(); +end; + +procedure tmsesdfdataset.inheritedinsert; +begin + inherited insert(); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msesqldb.pas b/mseide-msegui/lib/common/db/msesqldb.pas new file mode 100644 index 0000000..b84d563 --- /dev/null +++ b/mseide-msegui/lib/common/db/msesqldb.pas @@ -0,0 +1,1992 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesqldb; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mdb,msebufdataset,msqldb,msedb,mseclasses,msetypes,mseglob, + msedatabase,sysutils,msetimer,msestrings,msearrayprops,mseapplication, + msesqlquery,mseinterfaces; + +type + fieldparamlinkoptionty = ( + fplo_disabled, + fplo_autorefresh,fplo_refreshifactiveonly, + fplo_refreshifchangedonly,fplo_checkbrowsemodeonrefresh, + fplo_restorerecno, + fplo_syncmasterpost,fplo_delayedsyncmasterpost, + fplo_syncmastercancel, + fplo_syncmastercancelupdates, + fplo_syncmasterapplyupdates, + fplo_syncmastercheckbrowsemode, + fplo_syncmasteredit, + fplo_syncmasterinsert, + fplo_syncmasterdelete, + fplo_syncslavepost,fplo_delayedsyncslavepost, + fplo_syncslavecancel, + fplo_syncslaveedit, + fplo_syncslaveinsert,fplo_syncslaveinserttoedit, + fplo_syncslavedelete,fplo_syncslavedeletetoedit + ); + fieldparamlinkoptionsty = set of fieldparamlinkoptionty; +const + defaultfieldparamlinkoptions = [fplo_autorefresh,fplo_refreshifchangedonly]; + + defaultsqlcontrolleroptions = defaultdscontrolleroptions; + defaultsqlbdsoptions = defaultbufdatasetoptions + + [bdo_autoapply,bdo_autocommitret]; +type + tmsesqltransaction = class(tsqltransaction,iactivatorclient) + private + fcontroller: ttacontroller; + function getactive: boolean; + procedure setactive(const avalue: boolean); + procedure setcontroller(const avalue: ttacontroller); + protected + procedure loaded; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property Active : boolean read getactive write setactive default false; + property controller: ttacontroller read fcontroller write setcontroller; + end; + + tmsesqlquery = class; + + applyrecupdateeventty = + procedure(const sender: tmsesqlquery; const updatekind: tupdatekind; + var asql: msestring; var done: boolean) of object; + afterapplyrecupdateeventty = + procedure(const sender: tmsesqlquery; + const updatekind: tupdatekind) of object; + updateerroreventty = procedure(const sender: tmsesqlquery; + const aupdatekind: tupdatekind; + var aupdateaction: tupdateaction) of object; + + tsqldscontroller = class(tdscontroller) + protected + function savepointbegin: integer; override; + procedure savepointrollback(const alevel: integer = -1); override; + procedure savepointrelease; override; + public + constructor create(const aowner: tmsesqlquery); + published + property options default defaultsqlcontrolleroptions; + end; + + tmsesqlquery = class(tsqlquery,imselocate,idscontroller,igetdscontroller, + isqlpropertyeditor,iactivatorclient) + private + fsqlonchangebefore: notifyeventty; +// fcontroller: tdscontroller; + fonapplyrecupdate: applyrecupdateeventty; + fonapplyrecupdate2: afterapplyrecupdateeventty; + fafterapplyrecupdate: afterapplyrecupdateeventty; + ftransopenref: integer; + procedure setcontroller(const avalue: tdscontroller); + procedure setactive1(value : boolean); + function getactive: boolean; + procedure setonapplyrecupdate(const avalue: applyrecupdateeventty); + procedure setonapplyrecupdate2(const avalue: afterapplyrecupdateeventty); + function getcontroller: tdscontroller; + function getindexdefs: TIndexDefs; + procedure setindexdefs(const avalue: TIndexDefs); +// function getetstatementtype: TStatementType; +// procedure setstatementtype(const avalue: TStatementType); + procedure checkcanupdate; + protected + function getdefaultoptions(): bufdatasetoptionsty override; + procedure dobeforeapplyupdate; override; + procedure checkpendingupdates; override; + procedure setactive(avalue: boolean); override; + procedure setcontrolleractive(const avalue: boolean); + procedure idscontroller.setactive = setcontrolleractive; + procedure iactivatorclient.setactive = setcontrolleractive; + procedure afterapply; override; + procedure updateindexdefs; override; + procedure sqlonchange(const sender: tobject); + procedure loaded; override; + procedure internalopen; override; + procedure internalclose; override; + procedure DoAfterDelete; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure applyrecupdate(updatekind: tupdatekind); override; + function getcanmodify: boolean; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + function islocal: boolean; override; + //icursorclient + function stringmemo: boolean; override; + //memo fields are text(0) fields + //idscontroller + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; virtual; + procedure inheritedinternaldelete; virtual; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + procedure doidleapplyupdates() override; + +// function wantblobfetch: boolean; override; +// function getdsoptions: datasetoptionsty; override; + procedure afterpost(const sender: tdataset; var ok: boolean); +// function cantransactionrefresh: boolean; override; +//, function refreshtransdatasets: boolean; override; + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function isutf8: boolean; override; + procedure appendrecord(const values: array of const); + procedure appendrecord(const values: array of const; + const aisnull: array of boolean); + function moveby(const distance: integer): integer; + procedure cancel; override; + function post1(): boolean; //true if OK + procedure post override; + function delete1(): boolean; //true if ok + procedure delete override; +// procedure insert; override; + procedure applyupdates(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); overload; override; + procedure applyupdates(const maxerrors: integer = 0); overload; override; + procedure applyupdate; overload; override; + published + property FieldDefs; + property delayedapplycount; + property options default defaultsqlbdsoptions; + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive1 default false; + property onapplyrecupdate: applyrecupdateeventty read fonapplyrecupdate + write setonapplyrecupdate; + //raise eupdateerror in order to skip update of the record + property onapplyrecupdate2: afterapplyrecupdateeventty + read fonapplyrecupdate2 + write setonapplyrecupdate2; + //called after inherited + property afterapplyrecupdate: afterapplyrecupdateeventty + read fafterapplyrecupdate write fafterapplyrecupdate; + property UpdateMode default upWhereKeyOnly; + property UsePrimaryKeyAsKey default true; + property IndexDefs : TIndexDefs read getindexdefs write setindexdefs; + //must be writable because it is streamed +// property StatementType : TStatementType read getetstatementtype +// write setstatementtype default stnone; + //must be writable because it was streamed in FPC 2.0.4 + end; + + idbparaminfo = interface(inullinterface)[miid_idbparaminfo] + function getdestdataset: tsqlquery; + end; + + tfieldparamlink = class; + + setparameventty = procedure(const sender: tfieldparamlink; + var done: boolean) of object; + + tparamsourcedatalink = class(tfielddatalink) + private + fownerlink: tfieldparamlink; + fparamset: boolean; + fchangelock: integer; + frefreshlock: integer; + protected +// procedure checkrefresh; + procedure recordchanged(afield: tfield); override; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); override; + procedure CheckBrowseMode; override; + public + constructor create(const aowner: tfieldparamlink); + procedure loaded; + end; + + tparamdestdatalink = class(tmsedatalink) + private + fownerlink: tfieldparamlink; + protected + procedure updatedata; override; + function cansync(out sourceds: tdataset): boolean; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); override; + procedure CheckBrowseMode; override; + public + constructor create(const aowner: tfieldparamlink); + end; + + tdestvalue = class(townedpersistent,idbeditinfo,idbparaminfo) + private + fdatalink: tfielddatalink; +// fparamname: string; + function getdatasource: tdatasource; + procedure setdatasource(const avalue: tdatasource); + function getfieldname: string; + procedure setfieldname(const avalue: string); + protected + //idbeditinfo + function getdataset(const aindex: integer): tdataset; virtual; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); virtual; + //idbparaminfo + function getdestdataset: tsqlquery; + public + constructor create(aowner: tobject); override; + destructor destroy; override; + published + property datasource: tdatasource read getdatasource write setdatasource; + property fieldname: string read getfieldname write setfieldname; +// property paramname: string read fparamname write fparamname; + end; + + tdestparam = class(tdestvalue) + private + fparamname: string; + published + property paramname: string read fparamname write fparamname; + end; + + tdestparams = class(townedpersistentarrayprop) + public + constructor create(const aowner: tfieldparamlink); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + end; + + destfieldoptionty = (dfo_onlyifnull,dfo_notifunmodifiedinsert); + destfieldoptionsty = set of destfieldoptionty; + + tdestfield = class(tdestvalue) + private + fdestfieldname: string; + foptions: destfieldoptionsty; + protected + //idbeditinfo + function getdataset(const aindex: integer): tdataset; override; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); override; + published + property destfieldname: string read fdestfieldname write fdestfieldname; + property options: destfieldoptionsty read foptions write foptions default []; + end; + + tdestfields = class(townedpersistentarrayprop) + public + constructor create(const aowner: tfieldparamlink); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + end; + + tfieldparamlink = class(tmsecomponent,idbeditinfo,idbparaminfo) + private + fsourcedatalink: tparamsourcedatalink; + fdestdataset: tsqlquery; + fdestdatasource: tdatasource; + fdestdatalink: tparamdestdatalink; + fdestcontroller: tdscontroller; + fparamname: string; + fonsetparam: setparameventty; + fonaftersetparam: notifyeventty; + fonrefresh: notifyeventty; + foptions: fieldparamlinkoptionsty; + fdelayus: integer; + fnodelay: integer; + fonupdatemasteredit: masterdataseteventty; + fonupdatemasterinsert: masterdataseteventty; + fonupdateslaveedit: slavedataseteventty; + fonupdateslaveinsert: slavedataseteventty; + fdestparams: tdestparams; + fdestfields: tdestfields; + fonmasterdelete: masterdataseteventty; + fonslavedelete: slavedataseteventty; + fonmasterpost: masterdataseteventty; + fonslavepost: slavedataseteventty; + fonmasterapplyupdate: masterdataseteventty; + function getdatasource: tdatasource; overload; + procedure setdatasource(const avalue: tdatasource); + function getvisualcontrol: boolean; + procedure setvisualcontrol(const avalue: boolean); + function getdestdataset: tsqlquery; + procedure setdestdataset(const avalue: tsqlquery); + procedure setdelayus(const avalue: integer); + procedure setdestparams(const avalue: tdestparams); + function getfieldname: string; + procedure setfieldname(const avalue: string); + procedure readdatafield(reader: treader); + procedure setdestfields(const avalue: tdestfields); + procedure setoptions(const avalue: fieldparamlinkoptionsty); + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + protected + fcheckbrowsemodelock: int32; + procedure loaded; override; + procedure defineproperties(filer: tfiler); override; + //idbeditinfo + function getdataset(const aindex: integer): tdataset; overload; + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + procedure notification(acomponent: tcomponent; + operation: toperation); override; + function truedelayus: integer; + function param(const aname: string): tparam; overload; + function field(const aname: string): tfield; overload; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function param: tparam; overload; + function field: tfield; overload; + procedure checkrefresh; + procedure delayoff; + procedure delayon; + property enabled: boolean read getenabled write setenabled; + published + property fieldname: string read getfieldname write setfieldname; + property datasource: tdatasource read getdatasource write setdatasource; + property visualcontrol: boolean read getvisualcontrol + write setvisualcontrol default false; + property destdataset: tsqlquery read getdestdataset write setdestdataset; + property paramname: string read fparamname write fparamname; + property delayus: integer read fdelayus write setdelayus default -1; + //-1 -> off, 0 -> on idle + property options: fieldparamlinkoptionsty read foptions write setoptions + default defaultfieldparamlinkoptions; + property destparams: tdestparams read fdestparams + write setdestparams; + property destfields: tdestfields read fdestfields + write setdestfields; + property onsetparam: setparameventty read fonsetparam write fonsetparam; + property onaftersetparam: notifyeventty read fonaftersetparam + write fonaftersetparam; + property onrefresh: notifyeventty read fonrefresh + write fonrefresh; + property onupdatemasteredit: masterdataseteventty read fonupdatemasteredit + write fonupdatemasteredit; + property onupdatemasterinsert: masterdataseteventty read fonupdatemasterinsert + write fonupdatemasterinsert; + property onupdateslaveedit: slavedataseteventty read fonupdateslaveedit + write fonupdateslaveedit; + property onupdateslaveinsert: slavedataseteventty read fonupdateslaveinsert + write fonupdateslaveinsert; + property onmasterdelete: masterdataseteventty read fonmasterdelete + write fonmasterdelete; + property onslavedelete: slavedataseteventty read fonslavedelete + write fonslavedelete; + property onmasterpost: masterdataseteventty read fonmasterpost + write fonmasterpost; + property onslavepost: slavedataseteventty read fonslavepost + write fonslavepost; + property onmasterapplyupdate: masterdataseteventty read fonmasterapplyupdate + write fonmasterapplyupdate; + end; + + tsequencelink = class; + + tsequencedatalink = class(tfielddatalink) + private + fownerlink: tsequencelink; + protected + procedure updatedata; override; + public + constructor create(const aowner: tsequencelink); + end; + + tsequencelink = class(tmsecomponent,idbeditinfo) + private + fsequencename: string; + fdatabase: tsqlconnection; + fdbintf: idbcontroller; + fdatalink: tfielddatalink; + fonupdatevalue: updateint64eventty; + flastvalue: largeint; + procedure checkintf; + procedure setdatabase(const avalue: tsqlconnection); + procedure setsequencename(const avalue: string); + function getaslargeint: largeint; + procedure setaslargeint(const avalue: largeint); + function getasinteger: integer; + procedure setasinteger(const avalue: integer); + function getdatasource: tdatasource; overload; + procedure setdatasource(const avalue: tdatasource); + function getdatafield: string; + procedure setdatafield(const avalue: string); + //idbeditinfo + function getdataset(const aindex: integer): tdataset; overload; + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + protected + procedure notification(acomponent: tcomponent; operation: toperation); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property aslargeint: largeint read getaslargeint write setaslargeint; + property asinteger: integer read getasinteger write setasinteger; + function assql: string; + property lastvalue: largeint read flastvalue; + function currvalue: largeint; + published + property database: tsqlconnection read fdatabase write setdatabase; + property datasource: tdatasource read getdatasource write setdatasource; + property datafield: string read getdatafield write setdatafield; + property sequencename: string read fsequencename write setsequencename; + + property onupdatevalue: updateint64eventty read fonupdatevalue write fonupdatevalue; + end; + +implementation +uses + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},msesysutils,typinfo,msedatalist, + msesqlresult,msebits; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tmsesqltransaction } + +constructor tmsesqltransaction.create(aowner: tcomponent); +begin + inherited; + fcontroller:= ttacontroller.create(self,iactivatorclient(self)); +end; + +destructor tmsesqltransaction.destroy; +begin + inherited; + fcontroller.free; +end; + +function tmsesqltransaction.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsesqltransaction.setactive(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited active:= avalue; + end; +end; + +procedure tmsesqltransaction.setcontroller(const avalue: ttacontroller); +begin + fcontroller.assign(avalue); +end; + +procedure tmsesqltransaction.loaded; +begin + inherited; + fcontroller.loaded; +end; + +{ tmsesqlquery } + +constructor tmsesqlquery.create(aowner: tcomponent); +begin + inherited; +// updatemode:= upwhereall; + fsqlonchangebefore:= sql.onchange; + sql.onchange:= {$ifdef FPC}@{$endif}sqlonchange; + fcontroller:= tsqldscontroller.create(self); +end; + +destructor tmsesqlquery.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsesqlquery.getindexdefs: TIndexDefs; +begin + result:= inherited indexdefs; +end; + +procedure tmsesqlquery.setindexdefs(const avalue: TIndexDefs); +begin + inherited indexdefs.assign(avalue); +end; + +procedure tmsesqlquery.updateindexdefs; +begin + indexdefs.clear; + inherited; +end; + +procedure tmsesqlquery.appendrecord(const values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsesqlquery.appendrecord(const values: array of const; + const aisnull: array of boolean); +begin + fcontroller.appendrecord1(values,aisnull); +end; + +procedure tmsesqlquery.sqlonchange(const sender: tobject); +begin + if (csdesigning in componentstate) and active then begin + active:= false; + fsqlonchangebefore(sender); + active:= true; + end + else begin + fsqlonchangebefore(sender); + end; +end; + +procedure tmsesqlquery.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +procedure tmsesqlquery.setactive1(value: boolean); +begin + if fcontroller.setactive(value) then begin + setactive(value); + end; +end; + +procedure tmsesqlquery.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsesqlquery.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsesqlquery.inheritedinternalopen; +begin + if bdo_local in foptions then begin + openlocal(); + end + else begin + inherited internalopen; + end; +end; + +procedure tmsesqlquery.internalopen; +var + intf1: idbcontroller; + bo1: boolean; +begin + if dso_initinternalcalc in fcontroller.options then begin + include(fbstate,bs_initinternalcalc); + end + else begin + exclude(fbstate,bs_initinternalcalc); + end; + if (database <> nil) and + getcorbainterface(database,typeinfo(idbcontroller),intf1) then begin + bo1:= dso_utf8 in fcontroller.options; + intf1.updateutf8(bo1); + if bo1 then begin + fcontroller.options:= fcontroller.options + [dso_utf8]; + end + else begin + fcontroller.options:= fcontroller.options - [dso_utf8]; + end; + end; + fcontroller.internalopen; + if not streamloading and not (bdo_local in foptions) then begin + connected:= not (bdo_offline in foptions); + end; +end; + +procedure tmsesqlquery.setonapplyrecupdate(const avalue: applyrecupdateeventty); +begin + if not (csloading in componentstate) then begin + checkinactive; + end; + if assigned(avalue) and not (csdesigning in componentstate) then begin + include(fmstate,sqs_userapplyrecupdate); + end + else begin + if not assigned(fonapplyrecupdate2) then begin + exclude(fmstate,sqs_userapplyrecupdate); + end; + end; + fonapplyrecupdate:= avalue; +end; + +procedure tmsesqlquery.setonapplyrecupdate2( + const avalue: afterapplyrecupdateeventty); +begin + if not (csloading in componentstate) then begin + checkinactive; + end; + if assigned(avalue) and not (csdesigning in componentstate) then begin + include(fmstate,sqs_userapplyrecupdate); + end + else begin + if not assigned(fonapplyrecupdate) then begin + exclude(fmstate,sqs_userapplyrecupdate); + end; + end; + fonapplyrecupdate2:= avalue; +end; + +function tmsesqlquery.getcanmodify: Boolean; +begin + result:= fcontroller.getcanmodify and + (inherited getcanmodify or not readonly and + (sqs_userapplyrecupdate in fmstate)); +end; + +procedure tmsesqlquery.applyrecupdate(updatekind: tupdatekind); +var + bo1: boolean; + str1: msestring; +begin + try + if sqs_userapplyrecupdate in fmstate then begin + if assigned(fonapplyrecupdate) then begin + bo1:= false; + fonapplyrecupdate(self,updatekind,str1,bo1); + if not bo1 then begin + if str1 = '' then begin + inherited; + end + else begin + {$ifdef debugsqlquery} + debugwriteln(getenumname(typeinfo(tupdatekind),ord(updatekind))+' '+str1); + {$endif} + tsqlconnection(database).executedirect(str1,writetransaction); + end; + end; + end + else begin + inherited; + end; + if assigned(fonapplyrecupdate2) then begin + fonapplyrecupdate2(self,updatekind); + end; + end + else begin + internalapplyrecupdate(updatekind); + end; + if checkcanevent(self,tmethod(fafterapplyrecupdate)) then begin + fafterapplyrecupdate(self,updatekind); + end; + except + include(fmstate,sqs_updateerror); + if bdo_rollbackonupdateerror in foptions then begin + if writetransaction <> nil then begin + writetransaction.rollback(); + end; + end; + raise; + end; +end; + +procedure tmsesqlquery.afterpost(const sender: tdataset; var ok: boolean); +begin + if (bdo_autoapply in foptions) and + not(bs_noautoapply in fbstate) then begin + if bdo_autoapplyexceptions in foptions then begin + applyupdate(); + end + else begin + try + applyupdate; + except + ok:= false; + application.handleexception(self); + end; + end; + end; +end; + +function tmsesqlquery.post1(): boolean; +begin + result:= fcontroller.post(@afterpost); +end; + +procedure tmsesqlquery.post; +begin + post1(); +end; + +function tmsesqlquery.delete1(): boolean; +begin + result:= fcontroller.delete(); +end; + +procedure tmsesqlquery.delete; +begin + delete1(); +end; + +{ +procedure tmsesqlquery.insert; +begin + fcontroller.insert(); +end; +} +procedure tmsesqlquery.afterapply; +begin + if writetransaction <> nil then begin //can be nil in local mode + if (ftransopenref = writetransaction.opencount) then begin + if (writetransaction.savepointlevel < 0) then begin + if bdo_autocommitret in foptions then begin + writetransaction.commitretaining; + end; + if bdo_autocommit in foptions then begin + writetransaction.commit; + end; + end + else begin + if bdo_autocommitret in foptions then begin + writetransaction.pendingaction:= cacommitretaining; + end; + if bdo_autocommit in foptions then begin + writetransaction.pendingaction:= cacommit; + end; + end; + end; + end; + if bdo_refreshafterapply in foptions then begin + fcontroller.refresh(bdo_recnoapplyrefresh in foptions); + end; +end; + +procedure tmsesqlquery.dobeforeapplyupdate; +begin + inherited; + if writetransaction <> nil then begin + with writetransaction do begin + ftransopenref:= opencount; + end; + end; +end; + +procedure tmsesqlquery.checkcanupdate; +begin + if not islocal and (transactionwrite = nil) then begin + checkconnected; + end; +end; + +function tmsesqlquery.getdefaultoptions(): bufdatasetoptionsty; +begin + result:= defaultsqlbdsoptions; +end; + +procedure tmsesqlquery.applyupdates(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); +begin + checkcanupdate; + try + fmstate:= fmstate - [sqs_updateabort,sqs_updateerror]; + inherited; + finally + if (sqs_updateerror in fmstate) and + (bdo_cancelupdatesonerror in foptions) then begin + cancelupdates; + end; + end; +end; + +procedure tmsesqlquery.doidleapplyupdates; +var + bo1: boolean; +begin + if not (bs_idle in fbstate) and (changecount > 0) and + (changecount >= delayedapplycount) then begin + application.beginwait; + include(fbstate,bs_idle); + bo1:= false; + try + applyupdates; + except + bo1:= true; + application.endwait; + application.handleexception(self); + end; + exclude(fbstate,bs_idle); + if not bo1 then begin + application.endwait; + end; + end; +end; + +procedure tmsesqlquery.checkpendingupdates; +begin + if (state <> dsinactive) and (delayedapplycount > 0) and + (changecount > 0) then begin +// (dso_applyonidle in fcontroller.options) and (changecount > 0) then begin + applyupdates; + end; +end; + +procedure tmsesqlquery.setactive(avalue: boolean); +begin + if not avalue then begin + checkpendingupdates; + end; + inherited; +end; + +procedure tmsesqlquery.applyupdates(const maxerrors: integer = 0); +begin + applyupdates(maxerrors,foptions * + [bdo_cancelupdateonerror,bdo_cancelupdatesonerror] <> [], + bdo_cancelupdateondeleteerror in foptions, + bdo_editonapplyerror in foptions); +end; + +procedure tmsesqlquery.applyupdate; +begin + checkcanupdate; + inherited applyupdate(foptions * + [bdo_cancelupdateonerror,bdo_cancelupdatesonerror] <> [], + bdo_cancelupdateondeleteerror in foptions, + bdo_editonapplyerror in foptions); +end; + +function tmsesqlquery.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +procedure tmsesqlquery.cancel; +begin + fcontroller.cancel; +end; + +procedure tmsesqlquery.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmsesqlquery.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsesqlquery.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsesqlquery.inheritedcancel; +begin + inherited cancel; +end; + +function tmsesqlquery.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +function tmsesqlquery.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsesqlquery.internalinsert; +begin + fcontroller.internalinsert; +end; + +procedure tmsesqlquery.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsesqlquery.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsesqlquery.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsesqlquery.DoAfterDelete; +begin + inherited; + if (bdo_autoapply in foptions) and + not(bs_noautoapply in fbstate) then begin + applyupdates; + end; +end; +{ +function tmsesqlquery.getetstatementtype: TStatementType; +begin + result:= inherited statementtype; +end; + +procedure tmsesqlquery.setstatementtype(const avalue: TStatementType); +begin + //dummy +end; +} +procedure tmsesqlquery.inheritedpost; +begin + inherited post; +end; + +function tmsesqlquery.isutf8: boolean; +begin + result:= fcontroller.isutf8; +end; +{ +function tmsesqlquery.getdsoptions: datasetoptionsty; +begin + result:= fcontroller.options; +end; +} +{ +function tmsesqlquery.wantblobfetch: boolean; +begin + result:= (dso_cacheblobs in fcontroller.options); +end; + +function tmsesqlquery.closetransactiononrefresh: boolean; +begin + result:= (dso_refreshtransaction in fcontroller.options); +end; +} +{ +function tmsesqlquery.refreshtransdatasets: boolean; +begin + result:= (dso_refreshtransdatasets in fcontroller.options); +end; +} + +function tmsesqlquery.islocal: boolean; +begin + result:= (bdo_local in foptions) and not connected; +end; + +procedure tmsesqlquery.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsesqlquery.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsesqlquery.stringmemo: boolean; +begin + result:= dso_stringmemo in fcontroller.options; +end; + +procedure tmsesqlquery.setcontrolleractive(const avalue: boolean); +begin + setactive(avalue); +end; + +procedure tmsesqlquery.inheriteddelete(); +begin + inherited delete(); +end; + +procedure tmsesqlquery.inheritedinsert(); +begin + inherited insert(); +end; + +{ +procedure tmsesqlquery.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +{ +function tmsesqlquery.cantransactionrefresh: boolean; +begin + result:= not (dso_notransactionrefresh in fcontroller.options); +end; +} +{ tparamsourcedatalink } + +constructor tparamsourcedatalink.create(const aowner: tfieldparamlink); +begin + fownerlink:= aowner; + inherited create; +end; + +procedure tparamsourcedatalink.recordchanged(afield: tfield); +var + bo1,bo2: boolean; + int1: integer; + var1: variant; +begin + if not (csloading in fownerlink.componentstate) then begin + inherited; +// if frefreshlock = 0 then begin + if not (fplo_disabled in fownerlink.foptions) then begin + if active and (field <> nil) and + ((afield = nil) or (afield = self.field)) then begin + if fchangelock <> 0 then begin + databaseerror('Recursive recordchanged.',fownerlink); + end; + inc(fchangelock); + try + with fownerlink do begin + if not (csdesigning in componentstate) then begin + fparamset:= true; + bo1:= false; + bo2:= not (fplo_refreshifchangedonly in foptions) or + (fdestdataset = nil) or not fdestdataset.active; + if not bo2 then begin + var1:= param.value; + end; + if assigned(fonsetparam) then begin + fonsetparam(fownerlink,bo1); + end; + if not bo1 and (dataset <> nil) then begin + if fparamname <> '' then begin + fieldtoparam(self.field,param); + end; + with fdestparams do begin + for int1:= 0 to high(fitems) do begin + with tdestparam(fitems[int1]) do begin + if (fdatalink.field <> nil) and (fparamname <> '') then begin + fieldtoparam(fdatalink.field,param(fparamname)); + end; + end; + end; + end; + end; + if assigned(fonaftersetparam) then begin + fonaftersetparam(fownerlink); + end; + bo2:= bo2 or (var1 <> param.value); + if (frefreshlock = 0) and bo2 then begin + if (fplo_autorefresh in foptions) and + (destdataset <> nil) and + (fdestdataset.active or + not (fplo_refreshifactiveonly in foptions)) and + not((fdestdataset.state = dsinsert) and + (dataset.state = dsinsert) and + (fplo_syncmasterinsert in foptions)) and + not ((fplo_delayedsyncmasterpost in foptions) and + (self.fdscontroller <> nil) and + self.fdscontroller.posting1) then begin + if fdestdataset.active then begin + if fplo_checkbrowsemodeonrefresh in foptions then begin + fdestdataset.checkbrowsemode; + end + else begin + fdestdataset.cancel; + end; + if fdestcontroller <> nil then begin + fdestcontroller.refresh(fplo_restorerecno in foptions,truedelayus); + end + else begin + fdestdataset.refresh; + end; + end + else begin + fdestdataset.active:= true; + end; + end; + if assigned(fonrefresh) then begin + fonrefresh(fownerlink); + end; + end; + end; + end; + finally + dec(fchangelock); + end; + end; + end; + end; +end; + +procedure tparamsourcedatalink.loaded; +begin + if not fparamset then begin + recordchanged(nil); + end; +end; + +procedure tparamsourcedatalink.DataEvent(Event: TDataEvent; Info: Ptrint); +var + b1: boolean; +begin + inherited; + with fownerlink do begin + if not (fplo_disabled in foptions) then begin + b1:= (destdataset <> nil) and destdataset.active; + inc(frefreshlock); + try + case ord(event) of + ord(deupdatestate): begin + if b1 then begin + if (fplo_syncmasteredit in foptions) and (dataset.state = dsedit) and + not (fownerlink.destdataset.state = dsedit) then begin + destdataset.edit; + end; + if (fplo_syncmasterinsert in foptions) and(dataset.state = dsinsert) and + not (destdataset.state = dsinsert) then begin + destdataset.insert(); + end; + end; + end; + de_afterdelete: begin + if b1 and (fplo_syncmasterdelete in foptions) and + not destdataset.isempty then begin + destdataset.delete(); + end; + if assigned(fonmasterdelete) then begin + fonmasterdelete(destdataset,dataset); + end; + end; + de_afterpost: begin + if b1 and (fplo_delayedsyncmasterpost in foptions) and + (destdataset.state in [dsinsert,dsedit]) then begin + destdataset.post(); + end; + if assigned(fonmasterpost) then begin + fonmasterpost(destdataset,dataset); + end; + end; + de_afterapplyupdate: begin + if b1 and (fplo_syncmasterapplyupdates in foptions) then begin + destdataset.applyupdates(); + end; + if assigned(fonmasterapplyupdate) then begin + fonmasterapplyupdate(destdataset,dataset); + end; + end; + end; + finally + dec(frefreshlock); + end; + end; + end; +end; + +procedure tparamsourcedatalink.CheckBrowseMode; +label + endlab; +var + intf: igetdscontroller; + posted1: boolean; +begin + with fownerlink do begin + if not (fplo_disabled in foptions) and + (destdataset <> nil) and destdataset.active then begin + inc(frefreshlock); + try + posted1:= false; + if foptions * [fplo_syncmasteredit,fplo_syncmasterinsert, + fplo_syncmastercancel] <> [] then begin + if mseclasses.getcorbainterface(dataset, + typeinfo(igetdscontroller),intf) and + intf.getcontroller.canceling then begin + destdataset.cancel; + if fplo_syncmastercancelupdates in foptions then begin + destdataset.cancelupdates(); + end; + exit; + end + else begin + if (destdataset.state = dsinsert) and + (fplo_syncmasterpost in foptions) and + (dataset.state in [dsedit,dsinsert]) then begin + if fplo_delayedsyncmasterpost in foptions then begin + exit; + end; + dataset.updaterecord; + if dataset.modified then begin + posted1:= true; + destdataset.post; + goto endlab; + end; + end; + end; + end; + if (fplo_syncmasterpost in foptions) then begin + if fplo_delayedsyncmasterpost in foptions then begin + exit; + end; + posted1:= true; + destdataset.post; +// destdataset.checkbrowsemode; + end + else begin + if (fplo_syncmastercheckbrowsemode in foptions) and + (fcheckbrowsemodelock = 0) then begin + destdataset.checkbrowsemode(); + end; + end; + inherited; + endlab: + if (dataset.state in [dsedit,dsinsert]) and + (foptions * [fplo_syncmasteredit,fplo_syncmasterinsert] <> []) and + posted1 then begin + dataset.updaterecord; //synchronize fields + end; + if (dataset.state = dsinsert) and assigned(onupdatemasterinsert) then begin + onupdatemasterinsert(destdataset,dataset); + end; + if (dataset.state = dsedit) and assigned(onupdatemasteredit) then begin + onupdatemasteredit(destdataset,dataset); + end; + finally + dec(frefreshlock); + end; + end + else begin + inherited; + end; + end; +end; + +{ tparamdestdatalink } + +constructor tparamdestdatalink.create(const aowner: tfieldparamlink); +begin + fownerlink:= aowner; + inherited create; +end; + +function tparamdestdatalink.cansync(out sourceds: tdataset): boolean; +begin + with fownerlink.fsourcedatalink do begin + result:= false; + sourceds:= dataset; + if sourceds <> nil then begin + result:= sourceds.active; + end; + end; +end; + +procedure tparamdestdatalink.DataEvent(Event: TDataEvent; Info: Ptrint); +var + sourceds: tdataset; + b1: boolean; +begin + inherited; + with fownerlink do begin + if not (fplo_disabled in foptions) then begin + b1:= cansync(sourceds); + case ord(event) of + ord(deupdatestate): begin + if b1 then begin + if (fplo_syncslaveedit in foptions) and (dataset.state = dsedit) and + not (sourceds.state = dsedit) then begin + sourceds.edit; + end; + if ([fplo_syncslaveinsert,fplo_syncslaveinserttoedit] * foptions <> + []) and (dataset.state = dsinsert) then begin + inc(fcheckbrowsemodelock); + try + if (fplo_syncslaveinsert in foptions) and + (sourceds.state <> dsinsert) then begin + sourceds.insert(); + end + else begin + if (fplo_syncslaveinserttoedit in foptions) and + (sourceds.state <> dsedit) then begin + sourceds.edit(); + end; + end; + finally + dec(fcheckbrowsemodelock); + end; + end; + end; + end; + de_afterdelete: begin + if b1 then begin + if (fplo_syncslavedelete in foptions) and + not sourceds.isempty then begin + sourceds.delete; + end; + if fplo_syncslavedeletetoedit in foptions then begin + sourceds.edit(); + end; + end; + if assigned(fonslavedelete) then begin + fonslavedelete(destdataset,dataset); + end; + end; + de_afterpost: begin + if b1 and (fplo_delayedsyncslavepost in foptions) and + (sourceds.state in [dsinsert,dsedit]) then begin + sourceds.checkbrowsemode(); + end; + if assigned(fonslavepost) then begin + fonslavepost(destdataset,dataset); + end; + end; + end; + end; + end; +end; + +procedure tparamdestdatalink.CheckBrowseMode; +label + endlab; +var + intf: igetdscontroller; + sourceds: tdataset; + canceling: boolean; +begin + with fownerlink do begin + if not (fplo_disabled in foptions) and + cansync(sourceds) then begin + inc(fsourcedatalink.frefreshlock); + try + canceling:= mseclasses.getcorbainterface( + dataset,typeinfo(igetdscontroller),intf) and + intf.getcontroller.canceling; + if fplo_syncslavecancel in foptions then begin + if canceling then begin + if fsourcedatalink.frefreshlock = 1 then begin + sourceds.cancel; + end; + exit; + end + else begin + if (sourceds.state = dsinsert) and (dataset.state <> dsbrowse) and + (fplo_syncslavepost in foptions) then begin + dataset.updaterecord; + if dataset.modified then begin + destdataset.post; + updatedata; + goto endlab; + end; + end; + end; + end; + if (fplo_syncslavepost in foptions) and + (dataset.state <> dsbrowse) and not canceling then begin + if fplo_delayedsyncslavepost in foptions then begin + exit; + end; + sourceds.post; + updatedata; + end; + inherited; + endlab: + if (dataset.state in [dsedit,dsinsert]) and not canceling and + (foptions * [fplo_syncslaveedit,fplo_syncslaveinsert] <> []) then begin + dataset.updaterecord; //synchronize fields + end; + if (dataset.state = dsinsert) and assigned(onupdateslaveinsert) then begin + onupdateslaveinsert(destdataset,dataset); + end; + if (dataset.state = dsedit) and assigned(onupdateslaveedit) then begin + onupdateslaveedit(destdataset,dataset); + end; + finally + dec(fsourcedatalink.frefreshlock); + end; + end + else begin + inherited; + end; + end; +end; + +procedure tparamdestdatalink.updatedata(); +var + int1: integer; + field1: tfield; +begin + with fownerlink do begin + if not (fplo_disabled in foptions) then begin + with fdestfields do begin + for int1:= 0 to high(fitems) do begin + with tdestfield(fitems[int1]) do begin + if (fdatalink.field <> nil) and (fdestfieldname <> '') then begin + field1:= field(fdestfieldname); + if (not (dfo_onlyifnull in foptions) or (field1.isnull)) and + (not (dfo_notifunmodifiedinsert in foptions) or + dataset.modified) then begin + field1.value:= fdatalink.field.value; + end; + end; + end; + end; + end; + end; + end; +end; + +{ tfieldparamlink } + +constructor tfieldparamlink.create(aowner: tcomponent); +begin + fdelayus:= -1; + foptions:= defaultfieldparamlinkoptions; + fsourcedatalink:= tparamsourcedatalink.create(self); + fdestdatasource:= tdatasource.create(nil); + fdestdatalink:= tparamdestdatalink.create(self); + fdestdatalink.datasource:= fdestdatasource; + fdestparams:= tdestparams.create(self); + fdestfields:= tdestfields.create(self); +// fdestdatasource:= tlinkdatasource.create(nil); + inherited; +end; + +destructor tfieldparamlink.destroy; +begin +// freeandnil(ftimer); + inherited; + fsourcedatalink.free; + fdestdatalink.free; + fdestdatasource.free; + fdestparams.free; + fdestfields.free; +// fdestdatasource.free; +end; +{ +procedure tfieldparamlink.dotimer(const sender: tobject); +begin + fsourcedatalink.checkrefresh; +end; +} +function tfieldparamlink.getfieldname: string; +begin + result:= fsourcedatalink.fieldname; +end; + +procedure tfieldparamlink.setfieldname(const avalue: string); +begin + fsourcedatalink.fieldname:= avalue; +end; + +function tfieldparamlink.getdatasource: tdatasource; +begin + result:= fsourcedatalink.datasource; +end; + +procedure tfieldparamlink.setdatasource(const avalue: tdatasource); +begin + fsourcedatalink.datasource:= avalue; +end; + +function tfieldparamlink.getvisualcontrol: boolean; +begin + result:= fsourcedatalink.visualcontrol; +end; + +procedure tfieldparamlink.setvisualcontrol(const avalue: boolean); +begin + fsourcedatalink.visualcontrol:= avalue; +end; + +function tfieldparamlink.getdestdataset: tsqlquery; +begin + result:= fdestdataset; +end; + +procedure tfieldparamlink.setdestdataset(const avalue: tsqlquery); +var + intf: igetdscontroller; +begin + fdestdatasource.dataset:= avalue; + if fdestdataset <> nil then begin + fdestdataset.removefreenotification(self); + end; + fdestdataset:= avalue; + fdestcontroller:= nil; + if avalue <> nil then begin + avalue.freenotification(self); + if mseclasses.getcorbainterface(avalue, + typeinfo(igetdscontroller),intf) then begin + fdestcontroller:= intf.getcontroller; + end; + end; +end; + +procedure tfieldparamlink.notification(acomponent: tcomponent; + operation: toperation); +begin + if (operation = opremove) and (acomponent = fdestdataset) then begin + fdestdataset:= nil; + end; + inherited; +end; + +function tfieldparamlink.param(const aname: string): tparam; +begin + result:= nil; + if fdestdataset = nil then begin + databaseerror(name+': No destdataset'); + end + else begin + result:= fdestdataset.params.findparam(aname); + if result = nil then begin + databaseerror(name+': param "'+aname+'" not found'); + end; + end; +end; + +function tfieldparamlink.field(const aname: string): tfield; +begin + result:= nil; + if fdestdataset = nil then begin + databaseerror(name+': No destdataset'); + end + else begin + result:= fdestdataset.fieldbyname(aname); + if result = nil then begin + databaseerror(name+': field "'+aname+'" not found'); + end; + end; +end; + +function tfieldparamlink.param: tparam; +begin + result:= param(fparamname); +end; + +function tfieldparamlink.field: tfield; +begin + result:= fsourcedatalink.field; +end; + +procedure tfieldparamlink.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + fieldtypes:= nil; +end; + +procedure tfieldparamlink.loaded; +begin + inherited; + fsourcedatalink.loaded; +end; + +function tfieldparamlink.getdataset(const aindex: integer): tdataset; +begin + result:= fsourcedatalink.dataset; +end; + +procedure tfieldparamlink.setdelayus(const avalue: integer); +begin + fdelayus:= avalue; + if fdelayus < 0 then begin + fdelayus:= -1; + checkrefresh; + end; +end; + +function tfieldparamlink.truedelayus: integer; +begin + result:= fdelayus; + if fnodelay > 0 then begin + result:= -1; + end; +end; + +procedure tfieldparamlink.checkrefresh; +begin + if fdestcontroller <> nil then begin + fdestcontroller.checkrefresh; + end; +end; + +procedure tfieldparamlink.delayoff; +begin + inc(fnodelay); + if fnodelay = 1 then begin + checkrefresh; + end; +end; + +procedure tfieldparamlink.delayon; +begin + dec(fnodelay); +end; + +procedure tfieldparamlink.setdestparams(const avalue: tdestparams); +begin + fdestparams.assign(avalue); +end; + +procedure tfieldparamlink.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('datafield',{$ifdef FPC}@{$endif}readdatafield,nil,false); +end; + +procedure tfieldparamlink.readdatafield(reader: treader); +begin + fieldname:= reader.readstring; +end; + +procedure tfieldparamlink.setdestfields(const avalue: tdestfields); +begin + fdestfields.assign(avalue); +end; + +procedure tfieldparamlink.setoptions(const avalue: fieldparamlinkoptionsty); +begin + foptions:= fieldparamlinkoptionsty(setsinglebit(card32(avalue), + card32(foptions), + [card32([fplo_syncslaveinsert,fplo_syncslaveinserttoedit]), + card32([fplo_syncslavedelete,fplo_syncslavedeletetoedit])])); + if fplo_syncmastercancelupdates in avalue then begin + foptions:= foptions + [fplo_syncmastercancel]; + end; + if not (fplo_syncmastercancel in avalue) then begin + foptions:= foptions - [fplo_syncmastercancelupdates]; + end; +end; + +function tfieldparamlink.getenabled: boolean; +begin + result:= not (fplo_disabled in foptions); +end; + +procedure tfieldparamlink.setenabled(const avalue: boolean); +begin + if avalue then begin + exclude(foptions,fplo_disabled); + end + else begin + include(foptions,fplo_disabled); + end; +end; + +{ tsequencedatalink } + +constructor tsequencedatalink.create(const aowner: tsequencelink); +begin + fownerlink:= aowner; + inherited create; +end; + +procedure tsequencedatalink.updatedata; +begin + inherited; + if (field <> nil) and field.isnull and (dataset <> nil) and + ((dataset.modified) or + (fdscontroller <> nil) and fdscontroller.posting) then begin + if field.datatype in [ftlargeint,ftfloat,ftcurrency,ftbcd] then begin + field.aslargeint:= fownerlink.aslargeint; + end + else begin + field.asinteger:= fownerlink.asinteger; + end; + end; +end; + +{ tsequencelink } + +constructor tsequencelink.create(aowner: tcomponent); +begin + fdatalink:= tsequencedatalink.create(self); + inherited; +end; + +destructor tsequencelink.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tsequencelink.setdatabase(const avalue: tsqlconnection); +begin + if fdatabase <> avalue then begin + fdbintf:= nil; + if fdatabase <> nil then begin + fdatabase.removefreenotification(self); + end; + if avalue <> nil then begin + avalue.freenotification(self); + mseclasses.getcorbainterface(avalue,typeinfo(idbcontroller),fdbintf); + end; + fdatabase:= avalue; + end; +end; + +procedure tsequencelink.setsequencename(const avalue: string); +begin + fsequencename:= avalue; +end; + +procedure tsequencelink.notification(acomponent: tcomponent; + operation: toperation); +begin + inherited; + if (acomponent = fdatabase) and (operation = opremove) then begin + fdatabase:= nil; + end; +end; + +procedure tsequencelink.checkintf; +begin + if fdbintf = nil then begin + raise edatabaseerror.create(name+': Database has no idscontroller interface.'); + end; + if fsequencename = '' then begin + raise edatabaseerror.create(name+': No sequencename.'); + end; +end; + +function tsequencelink.getaslargeint: largeint; +begin + checkintf; + flastvalue:= getsqlresultvar(fdatabase.transaction, + fdbintf.readsequence(fsequencename),[]); + if canevent(tmethod(fonupdatevalue)) then begin + fonupdatevalue(self,flastvalue); + end; + result:= flastvalue; +end; +{ +function tsequencelink.getaslargeint: largeint; +var //todo: optimize + ds1: tsqlquery; +begin + checkintf; + ds1:= tsqlquery.create(nil); + try + ds1.parsesql:= false; + ds1.sql.add(fdbintf.readsequence(fsequencename)); + ds1.database:= fdatabase; + ds1.active:= true; + flastvalue:= ds1.fields[0].aslargeint; + finally + ds1.free; + end; + if canevent(tmethod(fonupdatevalue)) then begin + fonupdatevalue(self,flastvalue); + end; + result:= flastvalue; +end; +} +function tsequencelink.currvalue: largeint; +begin + checkintf; + result:= getsqlresultvar(fdatabase.transaction, + fdbintf.sequencecurrvalue(fsequencename),[]); +end; + +procedure tsequencelink.setaslargeint(const avalue: largeint); +begin + checkintf; + fdbintf.executedirect( + fdbintf.writesequence(fsequencename,avalue),false); +end; + +function tsequencelink.getasinteger: integer; +begin + result:= getaslargeint; +end; + +procedure tsequencelink.setasinteger(const avalue: integer); +begin + setaslargeint(avalue); +end; + +function tsequencelink.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tsequencelink.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; + if (csdesigning in componentstate) and (fdatabase = nil) and + (fdatalink.dataset is tsqlquery) then begin + database:= tsqlconnection(tsqlquery(fdatalink.dataset).database); + end; +end; + +function tsequencelink.getdatafield: string; +begin + result:= fdatalink.fieldname; +end; + +procedure tsequencelink.setdatafield(const avalue: string); +begin + fdatalink.fieldname:= avalue; +end; + +procedure tsequencelink.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + setlength(fieldtypes,1); + fieldtypes[0]:= integerfields; +end; + +function tsequencelink.assql: string; +begin + result:= inttostr(aslargeint); +end; + +function tsequencelink.getdataset(const aindex: integer): tdataset; +begin + result:= fdatalink.dataset; +end; + + +{ tsqldscontroller } + +function tsqldscontroller.savepointbegin: integer; +begin + result:= 0; + with tmsesqlquery(fowner) do begin + if writetransaction <> nil then begin + result:= writetransaction.savepointbegin; + end; + end; +end; + +procedure tsqldscontroller.savepointrollback(const alevel: integer = -1); +begin + with tmsesqlquery(fowner) do begin + if (writetransaction <> nil) and writetransaction.active then begin + writetransaction.savepointrollback(alevel); + end; + end; +end; + +procedure tsqldscontroller.savepointrelease; +begin + with tmsesqlquery(fowner) do begin + if (writetransaction <> nil) and writetransaction.active then begin + writetransaction.savepointrelease; + end; + end; +end; + +constructor tsqldscontroller.create(const aowner: tmsesqlquery); +begin + inherited create(aowner,idscontroller(aowner),-1,false); + foptions:= defaultsqlcontrolleroptions; +end; + +{ tdestparams } + +constructor tdestparams.create(const aowner: tfieldparamlink); +begin + inherited create(aowner,tdestparam); +end; + +class function tdestparams.getitemclasstype: persistentclassty; +begin + result:= tdestparam; +end; + +{ tdestfields } + +constructor tdestfields.create(const aowner: tfieldparamlink); +begin + inherited create(aowner,tdestfield); +end; + +class function tdestfields.getitemclasstype: persistentclassty; +begin + result:= tdestfield; +end; + +{ tdestvalue } + +constructor tdestvalue.create(aowner: tobject); +begin + inherited; + fdatalink:= tfielddatalink.create; +end; + +destructor tdestvalue.destroy; +begin + fdatalink.free; +end; + +function tdestvalue.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tdestvalue.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; +end; + +function tdestvalue.getfieldname: string; +begin + result:= fdatalink.fieldname; +end; + +procedure tdestvalue.setfieldname(const avalue: string); +begin + fdatalink.fieldname:= avalue; +end; + +function tdestvalue.getdataset(const aindex: integer): tdataset; +begin + result:= fdatalink.dataset; +end; + +procedure tdestvalue.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + afieldtypes:= nil; +end; + +function tdestvalue.getdestdataset: tsqlquery; +begin + result:= tfieldparamlink(fowner).destdataset; +end; + +{ tdestfield } + +function tdestfield.getdataset(const aindex: integer): tdataset; +begin + result:= nil; + case aindex of + 0: result:= fdatalink.dataset; + 1: result:= tfieldparamlink(fowner).fdestdataset; + end; +end; + +procedure tdestfield.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + setlength(apropertynames,2); + apropertynames[0]:= 'filedname'; + apropertynames[1]:= 'destfieldname'; + afieldtypes:= nil; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msesqlite3conn.pas b/mseide-msegui/lib/common/db/msesqlite3conn.pas new file mode 100644 index 0000000..f0a5413 --- /dev/null +++ b/mseide-msegui/lib/common/db/msesqlite3conn.pas @@ -0,0 +1,1160 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesqlite3conn; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,msedb,msqldb,msestrings,mdb,sqlite3dyn,msetypes,msedatabase; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ + Type name SQLite storage class Field type Data type ++--------------------+---------------------+-------------+-------------+ +| INTEGER or INT | INTEGER 4 | ftinteger | integer | +| LARGEINT | INTEGER 8 | ftlargeint | largeint | +| BIGINT | INTEGER 8 | ftlargeint | largeint | +| WORD | INTEGER 2 | ftword | word | +| SMALLINT | INTEGER 2 | ftsmallint | smallint | +| BOOLEAN | INTEGER 2 | ftboolean | wordbool | +| FLOAT[...] or REAL | REAL | ftfloat | double | +| or DOUBLE[...] | | | | +| CURRENCY | REAL | ftcurrency | double! | +| DATETIME or | REAL | ftdatetime | tdatetime | +| TIMESTAMP | | | | +| DATE | REAL | ftdate | tdatetime | +| TIME | REAL | fttime | tdatetime | +| NUMERIC[...] | INTEGER 8 (*10'000) | ftbcd | currency | +| VARCHAR[(n)] | TEXT | ftstring | msestring | +| TEXT | TEXT | ftmemo | utf8 string | +| TEXT | TEXT dso_stringmemo | ftstring | msestring | +| BLOB | BLOB | ftblob | string | ++--------------------+---------------------+-------------+-------------+ +} +type + esqlite3error = class(econnectionerror) + end; + + tsqlitetrans = class(TSQLHandle) + protected + fparams: ansistring; + end; + + sqliteoptionty = (slo_transactions,slo_designtransactions, + slo_negboolean, //boolean true = -1 instead of 1 + slo_64bitprimarykey); + //use ftlargint for "integer" primarykeyfield + sqliteoptionsty = set of sqliteoptionty; + + tsqlite3connection = class(tcustomsqlconnection,idbcontroller,iblobconnection) + private + fhandle: psqlite3; + foptions: sqliteoptionsty; + fbusytimeoutms: integer; + flasterror: integer; + flasterrormessage: msestring; + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); + function blobscached: boolean; + + procedure setoptions(const avalue: sqliteoptionsty); + procedure setbusytimeoutms(const avalue: integer); + procedure checkbusytimeout; + protected + procedure loaded; override; + function getfloatdate: boolean; override; + function getint64currency: boolean; override; + + function getassqltext(const field : tfield) : msestring; override; + function getassqltext(const param : tparam) : msestring; override; + + procedure resetstatement(const astatement: psqlite3_stmt); + procedure checkerror(const aerror: integer); + function cantransaction: boolean; + + procedure DoInternalConnect; override; + procedure DoInternalDisconnect; override; + function GetHandle : pointer; override; + + Function AllocateTransactionHandle : TSQLHandle; override; + + procedure internalExecute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; const AParams : TmseParams; + const autf8: boolean); override; + + function GetTransactionHandle(trans : TSQLHandle): pointer; override; + function Commit(trans : TSQLHandle) : boolean; override; + function RollBack(trans : TSQLHandle) : boolean; override; + function StartdbTransaction(const trans : TSQLHandle; + const aParams: tstringlist) : boolean; override; + procedure internalCommitRetaining(trans : TSQLHandle); override; + procedure internalRollBackRetaining(trans : TSQLHandle); override; + function getblobdatasize: integer; override; + + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + procedure execsql(const asql: string); + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); override; + function getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; override; + procedure updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); override; + procedure beginupdate; override; + procedure endupdate; override; + public + constructor create(aowner: tcomponent); override; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring) : TSQLCursor; override; + //aowner used as blob cache + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + function Fetch(cursor : TSQLCursor) : boolean; override; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); override; + procedure UnPrepareStatement(cursor : TSQLCursor); override; + procedure FreeFldBuffers(cursor : TSQLCursor); override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + procedure updateutf8(var autf8: boolean); override; + function getinsertid(const atransaction: tsqltransaction): int64; override; + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //null based + function stringquery(const asql: string): stringarty; + function stringsquery(const asql: string): stringararty; + property lasterror: integer read flasterror; + property lasterrormessage: msestring read flasterrormessage; + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + property controller: tdbcontroller read fcontroller write setcontroller; + property options: sqliteoptionsty read foptions write setoptions default []; + property busytimeoutms: integer read fbusytimeoutms + write setbusytimeoutms default 0; + property Transaction; + property transactionwrite; + property afterconnect; + property beforedisconnect; + end; + +implementation +uses + msesqldb,msebufdataset,mseformatstr, + {$ifdef FPC}dbconst{$else}dbconst_del,classes_del{$endif}, + sysutils,typinfo,dateutils,msesysintf,msedate, + msefileutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + maxprecision = 18; +type + tmsebufdataset1 = class(tmsebufdataset); + + storagetypety = (st_none,st_integer,st_float,st_text,st_blob,st_null); + + tsqlite3cursor = class(tsqlcursor) + private + fstatement: psqlite3_stmt; + ftail: pchar; + fstate: integer; + fparambinding: tparambinding; + fopen: boolean; + fconnection: tsqlite3connection; + fprimarykeyfield: string; + public + constructor create(const aowner: icursorclient; const aname: ansistring; + const aconnection: tsqlite3connection); + procedure close; override; + end; + +{ tsqlite3cursor } + +constructor tsqlite3cursor.create(const aowner: icursorclient; + const aname: ansistring; const aconnection: tsqlite3connection); +begin + fconnection:= aconnection; + inherited create(aowner,aname); +end; + +procedure tsqlite3cursor.close; +begin + inherited; + if fopen then begin + fconnection.resetstatement(fstatement); + fopen:= false; + end; +end; + +{ tsqlite3connection } + +constructor tsqlite3connection.create(aowner: tcomponent); +begin + inherited; + fconnoptions:= fconnoptions + [sco_supportparams,sco_emulateretaining]; +end; + +function tsqlite3connection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tsqlite3connection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +procedure tsqlite3connection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tsqlite3connection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tsqlite3connection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tsqlite3connection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tsqlite3connection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +var + blobid: integer; +// int1,int2: integer; +// str1: string; +// bo1: boolean; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= nil; + if mode = bmread then begin + if field.getData(@blobId) then begin + result:= acursor.getcachedblob(blobid); + end; + end; + end; +end; + +function tsqlite3connection.AllocateTransactionHandle: TSQLHandle; +begin + result:= tsqlitetrans.create; +end; + +function tsqlite3connection.AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; +begin + result:= tsqlite3cursor.create(aowner,aname,self); +end; + +procedure tsqlite3connection.DeAllocateCursorHandle(var cursor: TSQLCursor); +begin + freeandnil(cursor); +end; + +procedure tsqlite3connection.preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); +var + str1: string; +begin + with tsqlite3cursor(cursor) do begin + if assigned(aparams) and (aparams.count > 0) then begin + str1:= todbstring(aparams.parsesql(asql,false,false,false, + psinterbase,fparambinding)); + end + else begin + str1:= todbstring(asql); + end; + checkerror(sqlite3_prepare(fhandle,pchar(str1),length(str1),@fstatement, + @ftail)); + fprepared:= true; + end; +end; + +procedure tsqlite3connection.UnPrepareStatement(cursor: TSQLCursor); +//var +// int1: integer; +begin + with tsqlite3cursor(cursor) do begin +// int1:= sqlite3_finalize(fstatement); + sqlite3_finalize(fstatement); + fprepared:= false; + fopen:= false; + end; +end; + +procedure freebindstring(astring: pointer); cdecl; +begin + if astring <> pchar('') then begin + string(astring):= ''; + end; +end; + +procedure tsqlite3connection.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TfieldDefs); +const + fieldsizes: array[tfieldtype] of integer = ( //-1 invalid, -2 use fielddefs + //ftUnknown,ftString,ftSmallint, ftInteger, ftWord, + -1, -2, sizeof(smallint),sizeof(integer),sizeof(word), + //ftBoolean, ftFloat, ftCurrency, ftBCD, + sizeof(wordbool),sizeof(double),sizeof(double),sizeof(currency), + //ftDate, ftTime, ftDateTime, + sizeof(tdatetime),sizeof(tdatetime),sizeof(tdatetime), + //ftBytes,ftVarBytes,ftAutoInc,ftBlob, ftMemo, ftGraphic,ftFmtMemo, + -1, -1, -1, blobidsize,blobidsize,-1, -1, + //ftParadoxOle,ftDBaseOle,ftTypedBinary,ftCursor,ftFixedChar, + -1, -1, -1, -1, -1, + //ftWideString,ftLargeint, ftADT,ftArray,ftReference, + -1, sizeof(largeint),-1, -1, -1, + //ftDataSet,ftOraBlob,ftOraClob,ftVariant,ftInterface, + -1, -1, -1, -1, -1, + //ftIDispatch,ftGuid,ftTimeStamp,ftFMTBcd, + -1, -1, -1, -1 + // ftFixedWideChar,ftWideMemo + ,-1, -1 + ); + +var + int1,int2,int3: integer; + str1,str2: string; + ft1: tfieldtype; + size1: integer; + ar1: stringarty; + defsbefore: fielddefarty; + fd: tfielddef; +begin + defsbefore:= getfielddefar(fielddefs); + fielddefs.clear; + with tsqlite3cursor(cursor) do begin + for int1:= 0 to sqlite3_column_count(fstatement) - 1 do begin + str1:= sqlite3_column_name(fstatement,int1); + str2:= uppercase(sqlite3_column_decltype(fstatement,int1)); + ft1:= ftunknown; + size1:= 0; + if pos('INT',str2) = 1 then begin //or 'INTEGER' + ft1:= ftinteger; + if (slo_64bitprimarykey in foptions) and (str1 = fprimarykeyfield) then begin + ft1:= ftlargeint; + end; + end + else begin + if (str2 = 'LARGEINT') or (str2 = 'BIGINT') then begin + ft1:= ftlargeint; + end + else begin + if str2 = 'WORD' then begin + ft1:= ftword; + end + else begin + if str2 = 'SMALLINT' then begin + ft1:= ftsmallint; + end + else begin + if str2 = 'BOOLEAN' then begin + ft1:= ftboolean; + end + else begin + if (str2 = 'REAL') or (pos('FLOAT',str2) = 1) or + (pos('DOUBLE',str2) = 1) then begin + ft1:= ftfloat; + end + else begin + if (str2 = 'DATETIME') or (str2 = 'TIMESTAMP') then begin + ft1:= ftdatetime; + end + else begin + if str2 = 'DATE' then begin + ft1:= ftdate; + end + else begin + if str2 = 'TIME' then begin + ft1:= fttime; + end + else begin + if pos('NUMERIC',str2) = 1 then begin + ft1:= ftbcd; + end + else begin + if str2 = 'CURRENCY' then begin + ft1:= ftcurrency; + end + else begin + if pos('VARCHAR',str2) = 1 then begin + ft1:= ftstring; + ar1:= splitstring(str2,'('); + if high(ar1) >= 1 then begin + ar1:= splitstring(ar1[1],')'); + if high(ar1) >= 0 then begin + if not trystrtoint(ar1[0],size1) then begin + size1:= 0; + end; + end; + end; + end + else begin + if str2 = 'TEXT' then begin + if stringmemo then begin + ft1:= ftstring; + end + else begin + ft1:= ftmemo; + end; + end + else begin + if str2 = 'BLOB' then begin + ft1:= ftblob; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + if (ft1 = ftunknown) then begin + int3:= -1; + for int2:= 0 to high(defsbefore) do begin + if defsbefore[int2].name = str1 then begin + int3:= int2; + break; + end; + end; + if int3 >= 0 then begin + with defsbefore[int3] do begin + ft1:= datatype; + if ft1 = ftstring then begin + size1:= size; + end; + end; + end; + if ft1 = ftunknown then begin + size1:= 0; + case storagetypety(sqlite3_column_type(fstatement,int1)) of + st_integer: ft1:= ftinteger; + st_float: ft1:= ftfloat; + st_text: ft1:= ftstring; + st_blob: ft1:= ftblob; + end; + end; + end; + if ft1 <> ftstring then begin + size1:= fieldsizes[ft1]; + end; + if ft1 = ftbcd then begin + size1:= 4; //scale fix + end; + if size1 < 0 then begin + ft1:= ftunknown; + size1:= 0; + end; + if not(ft1 in varsizefields) then begin + size1:= 0; + end; + fd:= tfielddef.create(nil,str1,ft1,size1,false,int1+1); + fd.collection:= fielddefs; + if ft1 = ftbcd then begin + fd.precision:= maxprecision; //precision fix + end; + end; + end; +end; + +procedure tsqlite3connection.resetstatement(const astatement: psqlite3_stmt); +begin + checkerror(sqlite3_reset(astatement)); + checkerror(sqlite3_clear_bindings(astatement)); +end; + +procedure tsqlite3connection.internalExecute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; const AParams: TmseParams; + const autf8: boolean); +var + int1: integer; + str1: string; + cu1: currency; + do1: double; +{$ifndef CPUARM} + wo1: word; +{$endif} + po1: pchar; + i1: int32; +begin + with tsqlite3cursor(cursor) do begin + frowsaffected:= -1; + frowsreturned:= -1; + if aparams <> nil then begin + for int1:= 0 to high(fparambinding) do begin + with aparams[fparambinding[int1]] do begin + if isnull then begin + checkerror(sqlite3_bind_null(fstatement,int1+1)); + end + else begin + case datatype of + ftinteger,ftsmallint: begin + checkerror(sqlite3_bind_int(fstatement,int1+1,asinteger)); + end; + ftboolean: begin + i1:= asinteger; + if (i1 <> 0) and not (slo_negboolean in foptions) then begin + i1:= 1; + end; + checkerror(sqlite3_bind_int(fstatement,int1+1,i1)); + end; + ftword: begin + checkerror(sqlite3_bind_int(fstatement,int1+1,asword)); + end; + ftlargeint: begin + checkerror(sqlite3_bind_int64(fstatement,int1+1,aslargeint)); + end; + ftbcd: begin + cu1:= ascurrency; + checkerror(sqlite3_bind_int64(fstatement,int1+1,pint64(@cu1)^)); + end; + ftfloat,ftcurrency,ftdatetime,ftdate,fttime: begin + do1:= asfloat; + checkerror(sqlite3_bind_double(fstatement,int1+1,do1)); + end; + ftstring,ftwidestring,ftmemo,ftfixedchar,ftfixedwidechar: begin + str1:= aparams.asdbstring(fparambinding[int1]); + if str1 = '' then begin + po1:= pchar(''); + end + else begin + stringaddref(str1); + po1:= pchar(str1); + end; + checkerror(sqlite3_bind_text(fstatement,int1+1,po1, + length(str1),@freebindstring)); + end; + ftblob: begin + str1:= asstring; + stringaddref(str1); + checkerror(sqlite3_bind_blob(fstatement,int1+1,pointer(str1), + length(str1),@freebindstring)); + end; + else begin + databaseerror('Parameter type '+getenumname(typeinfo(tfieldtype), + ord(datatype))+' not supported.',self); + end; + end; + end; + end; + end; + end; + {$ifndef CPUARM} + wo1:= get8087cw; + set8087cw(wo1 or $1f); //mask exceptions, Sqlite3 has overflow + {$endif} + fstate:= sqlite3_step(fstatement); + {$ifndef CPUARM} + set8087cw(wo1); //restore + {$endif} + if fstate = sqlite_row then begin + fstate:= sqliteerrormax; //first row + fopen:= true; + end + else begin + resetstatement(fstatement); + end; + frowsaffected:= sqlite3_changes(fhandle); + end; +end; + +function tsqlite3connection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; +var + st1: storagetypety; + fnum: integer; +// i: integer; +// i64: int64; + int1,int2: integer; + str1: string; + ar1,ar2: stringarty; + year,month,day,hour,minute,second: integer; +begin + with tsqlite3cursor(cursor) do begin + fnum:= fieldnum; + st1:= storagetypety(sqlite3_column_type(fstatement,fnum)); + result:= st1 <> st_null; + if result then begin + if buffer = nil then begin + exit; + end; + case datatype of + ftinteger: begin + integer(buffer^):= sqlite3_column_int(fstatement,fnum); + end; + ftsmallint: begin + smallint(buffer^):= sqlite3_column_int(fstatement,fnum); + end; + ftword: begin + word(buffer^):= sqlite3_column_int(fstatement,fnum); + end; + ftboolean: begin + wordbool(buffer^):= sqlite3_column_int(fstatement,fnum) <> 0; + end; + ftlargeint,ftbcd: begin + largeint(buffer^):= sqlite3_column_int64(fstatement,fnum); + end; + ftfloat,ftcurrency: begin + double(buffer^):= sqlite3_column_double(fstatement,fnum); + end; + ftdatetime,ftdate,fttime: begin + if st1 = st_text then begin + result:= false; + setlength(str1,sqlite3_column_bytes(fstatement,fnum)); + move(sqlite3_column_text(fstatement,fnum)^,str1[1],length(str1)); + try + ar1:= splitstring(str1,' '); + if high(ar1) = 1 then begin + ar2:= splitstring(ar1[0],'-'); + if high(ar2) = 2 then begin + year:= strtoint(ar2[0]); + month:= strtoint(ar2[1]); + day:= strtoint(ar2[2]); + ar2:= splitstring(ar1[1],':'); + if high(ar2) = 2 then begin + hour:= strtoint(ar2[0]); + minute:= strtoint(ar2[1]); + second:= strtoint(ar2[2]); + tdatetime(buffer^):= encodedatetime(year,month,day, + hour,minute,second,0); + result:= true; + end; + end; + end + else begin + if high(ar1) = 0 then begin + ar2:= splitstring(ar1[0],'-'); + if high(ar2) = 2 then begin + year:= strtoint(ar2[0]); + month:= strtoint(ar2[1]); + day:= strtoint(ar2[2]); + tdatetime(buffer^):= encodedate(year,month,day); + result:= true; + end + else begin + ar2:= splitstring(ar1[0],':'); + if high(ar2) = 2 then begin + hour:= strtoint(ar2[0]); + minute:= strtoint(ar2[1]); + second:= strtoint(ar2[2]); + tdatetime(buffer^):= encodetime(hour,minute,second,0); + result:= true; + end; + end; + end; + end; + except + end; + end + else begin + tdatetime(buffer^):= sqlite3_column_double(fstatement,fnum); + end; + end; + ftstring,ftfixedchar: begin + int1:= sqlite3_column_bytes(fstatement,fnum); + if int1 > bufsize then begin + bufsize:= - int1; + end + else begin + bufsize:= int1; + if int1 > 0 then begin + move(sqlite3_column_text(fstatement,fnum)^,buffer^,int1); + end; + end; + end; + ftmemo: begin + int2:= sqlite3_column_bytes(fstatement,fnum); + int1:= addblobdata(sqlite3_column_text(fstatement,fnum),int2); + move(int1,buffer^,sizeof(int1)); + //save id + end; + ftblob: begin + int2:= sqlite3_column_bytes(fstatement,fnum); + int1:= addblobdata(sqlite3_column_blob(fstatement,fnum),int2); + move(int1,buffer^,sizeof(int1)); + //save id + end; + else begin + result:= false; // unknown + end; + end; + end; + end; +end; + +function tsqlite3connection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +begin + result:= ''; + with tsqlite3cursor(cursor) do begin + if storagetypety(sqlite3_column_type(fstatement,fieldnum)) <> st_null then begin + setlength(result,sqlite3_column_bytes(fstatement,fieldnum)); + if result <> '' then begin + move(sqlite3_column_blob(fstatement,fieldnum)^,result[1],length(result)); + end; + end; + end; +end; + +function tsqlite3connection.Fetch(cursor: TSQLCursor): boolean; +begin + with tsqlite3cursor(cursor) do begin + if fstate = sqliteerrormax then begin + fstate:= sqlite_row; //first row; + end + else begin + if fstate = sqlite_row then begin + fstate:= sqlite3_step(fstatement); + if fstate <= sqliteerrormax then begin + checkerror(sqlite3_reset(fstatement)); //right error returned?? + end; + end; + end; + result:= fstate = sqlite_row; + end; +end; + +procedure tsqlite3connection.FreeFldBuffers(cursor: TSQLCursor); +begin + //dummy +end; + +function tsqlite3connection.GetTransactionHandle(trans: TSQLHandle): pointer; +begin + result:= nil; +end; + +function tsqlite3connection.Commit(trans: TSQLHandle): boolean; +begin + if cantransaction then begin + execsql('COMMIT'); + end; + result:= true; +end; + +function tsqlite3connection.RollBack(trans: TSQLHandle): boolean; +begin + if cantransaction then begin + execsql('ROLLBACK'); + end; + result:= true; +end; + +function tsqlite3connection.StartdbTransaction(const trans: TSQLHandle; + const aParams: tstringlist): boolean; +begin + if cantransaction then begin + with tsqlitetrans(trans) do begin + fparams:= aparams.text; + execsql('BEGIN '+fparams); + end; + end; + result:= true; +end; + +procedure tsqlite3connection.internalCommitRetaining(trans: TSQLHandle); +begin + commit(trans); + if cantransaction then begin + with tsqlitetrans(trans) do begin + execsql('BEGIN '+fparams); + end; + end; +end; + +procedure tsqlite3connection.internalRollBackRetaining(trans: TSQLHandle); +begin + rollback(trans); + if cantransaction then begin + with tsqlitetrans(trans) do begin + execsql('BEGIN '+fparams); + end; + end; +end; + +function tsqlite3connection.getblobdatasize: integer; +begin + result:= blobidsize; +end; + +procedure tsqlite3connection.DoInternalConnect; +var + str1: string; +begin +// if (inherited databasename = '') then begin +// DatabaseError(SErrNoDatabaseName,self); +// end; + initializesqlite3([]); + str1:= stringtoutf8ansi(msestring(inherited databasename)); + checkerror(sqlite3_open(pchar(str1),@fhandle)); + checkbusytimeout; +end; + +procedure tsqlite3connection.DoInternalDisconnect; +//var +// int1: integer; +begin + if fhandle <> nil then begin +// int1:= sqlite3_close(fhandle); + sqlite3_close(fhandle); +// if int1 = sqlite_busy then begin +// checkerror(int1); +// end; + fhandle:= nil; + releasesqlite3; + end; +end; + +function tsqlite3connection.GetHandle: pointer; +begin + result:= fhandle; +end; + +procedure tsqlite3connection.checkerror(const aerror: integer); +begin + if aerror <> sqlite_ok then begin + flasterror:= aerror; + flasterrormessage:= utf8tostringansi(sqlite3_errmsg(fhandle)); + raise esqlite3error.create(self,ansistring(flasterrormessage), + flasterrormessage,flasterror); + end; +end; + +procedure tsqlite3connection.execsql(const asql: string); +var + err: pchar; + str1: string; + int1: integer; +begin + str1:= ''; + err:= nil; +{$ifdef FPC} {$checkpointer off} {$endif}; + int1:= sqlite3_exec(fhandle,pchar(asql),nil,nil^,@err); +{$ifdef FPC} {$checkpointer default} {$endif}; + if err <> nil then begin + str1:= err; + sqlite3_free(err); + end; + if int1 <> sqlite_ok then begin + databaseerror(str1); + end; +end; + +procedure tsqlite3connection.updateutf8(var autf8: boolean); +begin + autf8:= true; +end; + +procedure tsqlite3connection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); +var + str1: string; + int1: integer; +begin + setlength(str1,alength); + move(adata^,str1[1],alength); + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + int1:= acursor.addblobdata(str1); + setlength(newid,sizeof(int1)); + move(int1,newid[1],sizeof(int1)); +end; + +procedure tsqlite3connection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +begin + acursor.blobfieldtoparam(afield,aparam,false); +end; + +function tsqlite3connection.blobscached: boolean; +begin + result:= true; +end; + +function execcallback(var adata; ncols: longint; //adata = stringarty + avalues: PPchar; anames: PPchar):longint; cdecl; +var + int1: integer; +begin + setlength(stringarty(adata),ncols); + for int1:= 0 to ncols - 1 do begin + stringarty(adata)[int1]:= pcharpoaty(avalues)^[int1]; + end; + result:= 0; +end; + +function tsqlite3connection.stringquery(const asql: string): stringarty; +begin + result:= nil; + checkerror(sqlite3_exec(fhandle,pchar(asql),@execcallback,result,nil)); +end; + +function execscallback(var adata; ncols: longint; //adata = stringarty + avalues: PPchar; anames: PPchar):longint; cdecl; +var + int1: integer; + po1: pstringarty; + po2: pstring; +begin + //@ operator and some indexing do not work with -O2 and FPC 2.2 + setlength(stringararty(adata),high(stringararty(adata))+2); + po1:= pointer(pchar(pointer(adata)) + high(stringararty(adata))*sizeof(pointer)); + setlength(po1^,ncols); + po2:= pointer(po1^); + for int1:= 0 to ncols - 1 do begin + po2^:= pcharpoaty(avalues)^[int1]; + inc(po2); + end; + result:= 0; +end; + +function tsqlite3connection.stringsquery(const asql: string): stringararty; +begin + result:= nil; +// checkerror(sqlite3_exec(fhandle,pchar(asql),@execscallback,@result,nil)); + checkerror(sqlite3_exec(fhandle,pchar(asql),@execscallback,result,nil)); +end; + +function tsqlite3connection.getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; +var + int1{,int2}: integer; + ar1: stringararty; +// str1: string; +begin + result:= ''; + if atablename <> '' then begin + try + ar1:= stringsquery('PRAGMA table_info('+atablename+');'); + for int1:= 0 to high(ar1) do begin + if (high(ar1[int1]) >= 5) and (ar1[int1][5] <> '0') then begin + result:= ar1[int1][1]; + break; + end; + end; + except + end; + end; + tsqlite3cursor(acursor).fprimarykeyfield:= result; +end; + +procedure tsqlite3connection.UpdateIndexDefs(var IndexDefs: TIndexDefs; + const aTableName: string; const acursor: tsqlcursor); +var + str1: string; +begin + try + str1:= getprimarykeyfield(atablename,acursor); + except + str1:= ''; + end; + if str1 <> '' then begin + indexdefs.add('$PRIMARY_KEY$',str1,[ixPrimary,ixUnique]); + end; +end; +{ +procedure tsqlite3connection.UpdateIndexDefs(var IndexDefs: TIndexDefs; + const TableName: string); +var + int1,int2: integer; + ar1: stringararty; + str1: string; +begin + ar1:= stringsquery('PRAGMA table_info('+tablename+');'); + for int1:= 0 to high(ar1) do begin + if (high(ar1[int1]) >= 5) and (ar1[int1][5] <> '0') then begin + indexdefs.add('$PRIMARY_KEY$',ar1[int1][1],[ixPrimary,ixUnique]); + break; + end; + end; +end; +} + +function tsqlite3connection.getinsertid(const atransaction: tsqltransaction): int64; +begin + result:= sqlite3_last_insert_rowid(fhandle); +end; + +procedure tsqlite3connection.updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); +begin + if afield.datatype in integerfields then begin + afield.aslargeint:= getinsertid(nil); + end; + { + with tmsebufdataset1(afield.dataset) do begin + setcurvalue(afield,getinsertid); + end; + } +end; + +function tsqlite3connection.cantransaction: boolean; +begin + result:= (slo_transactions in foptions) and + ((slo_designtransactions in foptions) or not (csdesigning in componentstate)); +end; + +procedure tsqlite3connection.setoptions(const avalue: sqliteoptionsty); +begin + if avalue <> foptions then begin + checkdisconnected; + foptions:= avalue; + end; +end; + +procedure tsqlite3connection.setbusytimeoutms(const avalue: integer); +begin + if avalue <> fbusytimeoutms then begin + fbusytimeoutms:= avalue; + checkbusytimeout; + end; +end; + +procedure tsqlite3connection.checkbusytimeout; +begin + if fhandle <> nil then begin + sqlite3_busy_timeout(fhandle,fbusytimeoutms); + end; +end; + +procedure tsqlite3connection.beginupdate; +begin + if not (slo_transactions in foptions) then begin + execsql('BEGIN'); + end; +end; + +procedure tsqlite3connection.endupdate; +begin + if not (slo_transactions in foptions) then begin + execsql('COMMIT'); + end; +end; + +function tsqlite3connection.getassqltext(const field: tfield): msestring; +begin + if field.isnull then begin + result:= inherited getassqltext(field); + end + else begin + case field.datatype of + ftdate,ftdatetime,fttime: begin + result:= encodesqlfloat(field.asdatetime); + end; + ftbcd: begin + {$ifdef FPC} + result:= inttostrmse(int64(field.ascurrency)); + {$else} + result:= inttostrmse(int64(ar8ty(field.ascurrency))); + {$endif} + end; + else begin + result:= inherited getassqltext(field); + end; + end; + end; +end; + +function tsqlite3connection.getassqltext(const param: tparam): msestring; +begin + if param.isnull then begin + result:= inherited getassqltext(param); + end + else begin + case param.datatype of + ftdate,ftdatetime,fttime: begin + result:= encodesqlfloat(param.asdatetime); + end; + ftbcd: begin + {$ifdef FPC} + result:= inttostrmse(int64(param.ascurrency)); + {$else} + result:= inttostrmse(int64(ar8ty(param.ascurrency))); + {$endif} + end; + else begin + result:= inherited getassqltext(param); + end; + end; + end; +end; + +function tsqlite3connection.getfloatdate: boolean; +begin + result:= true; +end; + +function tsqlite3connection.getint64currency: boolean; +begin + result:= true; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msesqlquery.pas b/mseide-msegui/lib/common/db/msesqlquery.pas new file mode 100644 index 0000000..57bce30 --- /dev/null +++ b/mseide-msegui/lib/common/db/msesqlquery.pas @@ -0,0 +1,2409 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesqlquery; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} + +interface +uses + classes,mclasses,mdb,msetimer,msebufdataset,msqldb,msedb,msestrings, + msedatabase,mseclasses,msetypes,msesqlresult; + +type + tsqlquery = class; + tsqlmasterparamsdatalink = class(tmasterparamsdatalink) + private + fquery: tsqlquery; + frefreshlock: integer; +// fdelayus: integer; + ftimer: tsimpletimer; + protected + procedure domasterdisable; override; + procedure domasterchange; override; + procedure CheckBrowseMode; override; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); override; + procedure checkrefresh; //makes pending delayed refresh + procedure dorefresh(const sender: tobject); + public + constructor create(const aowner: tsqlquery); reintroduce; + destructor destroy; override; + Procedure RefreshParamNames; override; + Procedure CopyParamsFromMaster(CopyBound : Boolean); override; +// published +// property delayus: integer read fdelayus write fdelayus default -1; + end; + + sqlquerystatety = (sqs_userapplyrecupdate,sqs_updateabort,sqs_updateerror); + sqlquerystatesty = set of sqlquerystatety; + + tupdatestringlist = class(tsqlstringlist) + end; + + tsqlquery = class (tmsebufdataset,isqlclient,icursorclient) + private + fcursor: tsqlcursor; + fupdateable: boolean; + fsql: tsqlstringlist; +// fsqlupdate,fsqlinsert: tupdatesqlstringlist; +// fsqldelete: tsqlstringlist; + fiseof: boolean; + floadingfielddefs: boolean; + findexdefs: tindexdefs; + fupdatemode: tupdatemode; + fparams: tmseparams; + fuseprimarykeyaskey: boolean; + fsqlbuf: msestring; + fsqlprepbuf: msestring; + ffrompart: msestring; + fwherestartpos: integer; + fwherestoppos: integer; + fparsesql: boolean; + fstatementtype: tstatementtype; + fmasterlink: tsqlmasterparamsdatalink; + fapplyqueries: array[tupdatekind] of tsqlresult; + fapplysql: array[tupdatekind] of tupdatestringlist; +// fupdateqry,fdeleteqry,finsertqry: tsqlquery; + fupdaterowsaffected: integer; + fblobintf: iblobconnection; + fbeforeexecute: tcustomsqlstatement; + faftercursorclose: tcustomsqlstatement; + fmasterdelayus: integer; + procedure freefldbuffers; + function getindexdefs : tindexdefs; +// function getstatementtype : tstatementtype; + procedure setindexdefs(avalue : tindexdefs); + procedure setreadonly(avalue : boolean); + procedure setparsesql(avalue : boolean); + procedure setstatementtype(const avalue: tstatementtype); + procedure setuseprimarykeyaskey(avalue : boolean); + procedure setupdatemode(avalue : tupdatemode); + procedure onchangesql(const sender : tobject); + procedure onchangemodifysql(const sender : tobject); + procedure execute; + procedure sqlparser(var asql: msestring); + procedure applyfilter; + function addfilter(sqlstr : msestring) : msestring; + function getdatabase1: tcustomsqlconnection; + procedure setdatabase1(const avalue: tcustomsqlconnection); + procedure setparams(const avalue: tmseparams); + function getconnected: boolean; + procedure setconnected(const avalue: boolean); + procedure setfsql(const avalue: tsqlstringlist); + procedure setfsqlupdate(const avalue: tupdatestringlist); + procedure setfsqlinsert(const avalue: tupdatestringlist); + procedure setfsqldelete(const avalue: tupdatestringlist); + procedure setbeforeexecute(const avalue: tcustomsqlstatement); + procedure setaftercursorclose(const avalue: tcustomsqlstatement); + function getsqltransaction: tsqltransaction; + procedure setsqltransaction(const avalue: tsqltransaction); + function getsqltransactionwrite: tsqltransaction; + procedure setsqltransactionwrite(const avalue: tsqltransaction); + procedure resetparsing; + procedure dorefresh; +// procedure setmasterlink(const avalue: tsqlmasterparamsdatalink); +// procedure setmasterdelayus(const avalue: integer); + procedure settablename(const avalue: string); + protected + fmstate: sqlquerystatesty; + FTableName: string; + FReadOnly: boolean; + fprimarykeyfield: tfield; + futf8: boolean; + foptionsmasterlink: optionsmasterlinkty; + function getdatabase: tcustomconnection; //for isqlpropertyeditor + procedure settransactionwrite(const avalue: tmdbtransaction); override; + procedure checkpendingupdates; virtual; + procedure notification(acomponent: tcomponent; operation: toperation); override; + // abstract & virtual methods of TBufDataset + function Fetch : boolean; override; + function getblobdatasize: integer; override; + function getnumboolean: boolean; virtual; + function getfloatdate: boolean; virtual; + function getint64currency: boolean; virtual; + function blobscached: boolean; override; + function loadfield(const afieldno: integer; const afieldtype: tfieldtype; + const buffer: pointer; var bufsize: integer): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + // abstract & virtual methods of TDataset +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + procedure updateindexdefs; override; + procedure setdatabase(const value: tmdatabase); override; + procedure settransaction(const value : tmdbtransaction); override; + procedure internaladdrecord(buffer: pointer; aappend: boolean); override; + procedure internalclose; override; + procedure internalinitfielddefs; override; + procedure connect(const aexecute: boolean); + procedure freemodifyqueries; + procedure freequery; + procedure disconnect{(const aexecute: boolean)}; + procedure checkrecursivedatasource(const avalue: tdatasource); + procedure internalopen; override; + procedure internalrefresh; override; + procedure refreshtransaction; override; + procedure dobeforeedit; override; + procedure dobeforeinsert; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + + function getcanmodify: boolean; override; + procedure updatewherepart(var sql_where : msestring; const afield: tfield); + procedure internalapplyrecupdate(updatekind : tupdatekind); + procedure dobeforeapplyupdate; override; + procedure applyrecupdate(updatekind : tupdatekind); override; + function isprepared: boolean; virtual; + Procedure SetActive (Value : Boolean); override; + procedure SetFiltered(Value: Boolean); override; + procedure SetFilterText(const Value: string); override; + Function GetDataSource : TDatasource; override; + Procedure SetDataSource(AValue : TDatasource); + //icursorclient + function stringmemo: boolean; virtual; + //memo fields are text(0) fields + public + constructor Create(AOwner : TComponent); override; + destructor Destroy; override; + function isutf8: boolean; override; + procedure applyupdate(const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); override; + procedure applyupdates(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); override; + function refreshrecquery(const update: boolean): msestring; + procedure checktablename; + function updaterecquery : msestring; + function insertrecquery : msestring; + function deleterecquery : msestring; + function writetransaction: tsqltransaction; + //self.transaction if self.transactionwrite = nil + procedure refresh(const aparams: array of variant); overload; + procedure Prepare; virtual; + procedure UnPrepare; virtual; + procedure ExecSQL; virtual; + function executedirect(const asql: msestring): integer; + //uses writetransaction of tsqlquery + function rowsreturned: integer; //-1 if not supported + function rowsaffected: integer; //-1 if not supported + property updaterowsaffected: integer read fupdaterowsaffected; + //sum of rowsaffected of insert, update and delete query, + //reset by close, applyupdate and applyupdates, -1 if not supported. +// procedure SetSchemaInfo( SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string); virtual; + function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override; + property Prepared : boolean read IsPrepared; + property connected: boolean read getconnected write setconnected; + published + property ReadOnly : Boolean read FReadOnly write SetReadOnly default false; + property ParseSQL : Boolean read FParseSQL write SetParseSQL default true; + property params : tmseparams read fparams write setparams; + //before SQL + property SQL : tsqlstringlist read FSQL write setFSQL; + property SQLUpdate : tupdatestringlist read Fapplysql[ukmodify] + write setFSQLUpdate; + property SQLInsert : tupdatestringlist read Fapplysql[ukinsert] + write setFSQLInsert; + property SQLDelete : tupdatestringlist read Fapplysql[ukdelete] + write setFSQLDelete; + property beforeexecute: tcustomsqlstatement read fbeforeexecute write setbeforeexecute; + property aftercursorclose: tcustomsqlstatement read faftercursorclose + write setaftercursorclose; + property IndexDefs : TIndexDefs read GetIndexDefs; + property UpdateMode : TUpdateMode read FUpdateMode write SetUpdateMode; + property UsePrimaryKeyAsKey : boolean read FUsePrimaryKeyAsKey write SetUsePrimaryKeyAsKey; + property tablename: string read ftablename write settablename; + property StatementType : TStatementType read fstatementtype + write setstatementtype default stnone; + Property DataSource : TDatasource Read GetDataSource Write SetDatasource; + property masterdelayus: integer read fmasterdelayus + write fmasterdelayus default -1; + property optionsmasterlink: optionsmasterlinkty read foptionsmasterlink + write foptionsmasterlink default []; + // property masterlink: tsqlmasterparamsdatalink read fmasterlink + // write setmasterlink; + property database: tcustomsqlconnection read getdatabase1 write setdatabase1; + +// property SchemaInfo : TSchemaInfo read FSchemaInfo default stNoSchema; + // redeclared data set properties + property Active; + property Filter; + property Filtered; +// property FilterOptions; + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; + property BeforeScroll; + property AfterScroll; + property BeforeRefresh; + property AfterRefresh; + property OnCalcFields; + property OnDeleteError; + property OnEditError; + property OnFilterRecord; + property OnNewRecord; + property OnPostError; + property onmodified; + property AutoCalcFields; +// property Database; + + property Transaction: tsqltransaction read getsqltransaction write setsqltransaction; + property transactionwrite: tsqltransaction read getsqltransactionwrite + write setsqltransactionwrite; + end; + +procedure querytoupdateparams(const source: tsqlquery; const dest: tparams); +function SkipComments(var p: PmseChar) : boolean; + +implementation +uses + sysutils,{$ifdef FPC}dbconst{$else}dbconst_del,classes_del{$endif},msearrayutils,typinfo; + +type + tcustomsqlconnection1 = class(tcustomsqlconnection); + tcustomsqlstatement1 = class(tcustomsqlstatement); + tsqltransaction1 = class(tsqltransaction); + tsqlresult1 = class(tsqlresult); + tdataset1 = class(tdataset); + +function SkipComments(var p: PmseChar) : boolean; +begin + result := false; + case p^ of + '''': // single quote delimited string + begin + Inc(p); + Result := True; + while not ((p^ = #0) or (p^ = '''')) do + begin + if p^='\' then Inc(p,2) // make sure we handle \' and \\ correct + else Inc(p); + end; + if p^='''' then Inc(p); // skip final ' + end; + '"': // double quote delimited string + begin + Inc(p); + Result := True; + while not ((p^ = #0) or (p^ = '"')) do + begin + if p^='\' then Inc(p,2) // make sure we handle \" and \\ correct + else Inc(p); + end; + if p^='"' then Inc(p); // skip final " + end; + '-': // possible start of -- comment + begin + Inc(p); + if p^='-' then // -- comment + begin + Result := True; + repeat // skip until at end of line + Inc(p); + until (p^ = #10) or (p^ = #0); + end + end; + '/': // possible start of /* */ comment + begin + Inc(p); + if p^='*' then // /* */ comment + begin + Result := True; + repeat + Inc(p); + if p^='*' then // possible end of comment + begin + Inc(p); + if p^='/' then Break; // end of comment + end; + until p^=#0; + if p^='/' then Inc(p); // skip final / + end; + end; + end; {case} +end; + +procedure querytoupdateparams(const source: tsqlquery; const dest: tparams); +var + x: integer; + param1,param2: tparam; + fld: tfield; +begin + for x := 0 to dest.Count-1 do begin + param1:= dest[x]; + with param1 do begin + if leftstr(name,4)='OLD_' then begin + Fld:= source.FieldByName(copy(name,5,length(name)-4)); + source.oldfieldtoparam(fld,param1); +// AssignFieldValue(Fld,Fld.OldValue); + end + else begin + fld:= source.findfield(name); + if fld = nil then begin //search for param + param2:= source.params.findparam(name); + if param2 = nil then begin + source.fieldbyname(name); //raise exception + end + else begin + value:= param2.value; + end; + end + else begin //use field + source.fieldtoparam(fld,param1); + end; + end; + end; + end; +end; + +{ tsqlmasterparamsdatalink } + +constructor tsqlmasterparamsdatalink.create(const aowner: tsqlquery); +begin + fquery:= aowner; + inherited create(aowner); +end; + +destructor tsqlmasterparamsdatalink.destroy; +begin + freeandnil(ftimer); + inherited; +end; + +procedure tsqlmasterparamsdatalink.dorefresh(const sender: tobject); +begin + if Assigned(Params) and Assigned(DetailDataset) and + DetailDataset.Active then begin + detaildataset.refresh; + end; +end; + +procedure tsqlmasterparamsdatalink.checkrefresh; +begin + if ftimer <> nil then begin + ftimer.firependingandstop; //cancel wait + end; +end; + +procedure tsqlmasterparamsdatalink.domasterchange; +var + intf: igetdscontroller; +begin + if (frefreshlock = 0) and + (not getcorbainterface(dataset,typeinfo(igetdscontroller),intf) or + not intf.getcontroller.posting) then begin + if assigned(onmasterchange) then begin + onmasterchange(self); + end; + if assigned(params) and assigned(detaildataset) and + (detaildataset.state = dsbrowse) and + not (mdlo_norefresh in fquery.foptionsmasterlink) then begin + if fquery.masterdelayus < 0 then begin + freeandnil(ftimer); + dorefresh(nil); + end + else begin + if ftimer = nil then begin + ftimer:= tsimpletimer.create(fquery.masterdelayus, + {$ifdef FPC}@{$endif}dorefresh,true,[to_single]); + end + else begin + ftimer.interval:= fquery.masterdelayus; //single shot + ftimer.enabled:= true; + end; + end; + end; + end; +end; + +procedure tsqlmasterparamsdatalink.domasterdisable; +var + intf: imasterlink; +begin + if (dataset = nil) or + not getcorbainterface(dataset,typeinfo(imasterlink),intf) or + not intf.refreshing then begin + if assigned(onmasterdisable) then begin + onmasterdisable(self); + end; + if assigned(detaildataset) and detaildataset.active then begin + detaildataset.close; + end; + end; +end; + +procedure tsqlmasterparamsdatalink.DataEvent(Event: TDataEvent; Info: Ptrint); +begin + inherited; + with tsqlquery(detaildataset) do begin + if active then begin + case ord(event) of + ord(deupdaterecord): begin + if state in [dsinsert,dsedit] then begin + updaterecord; + if modified then begin + tdataset1(dataset).setmodified(true); //FPC fixes_2_6 compatibility +// dataset.modified:= true; + end; + end; + end; + ord(deupdatestate): begin + if (mdlo_syncedit in foptionsmasterlink) and + (dataset.state = dsedit) and not (state = dsedit) then begin + edit; + end; + if (mdlo_syncinsert in foptionsmasterlink) and + (dataset.state = dsinsert) and not (state = dsinsert) then begin + insert; + end; + end; + de_afterdelete: begin + if (mdlo_syncdelete in foptionsmasterlink) then begin + delete; + end; + end; + de_afterpost: begin + if (mdlo_delayeddetailpost in foptionsmasterlink) then begin + if (mdlo_inserttoupdate in foptionsmasterlink) and + (state = dsinsert) then begin + tdataset1(detaildataset).setmodified(true); //FPC fixes_2_6 compatibility +// detaildataset.modified:= true; + include(fbstate,bs_inserttoupdate); + try + detaildataset.checkbrowsemode; + finally + exclude(fbstate,bs_inserttoupdate); + end; + end + else begin + detaildataset.checkbrowsemode; + end; + end; + end; + end; + end; + end; +end; + +procedure tsqlmasterparamsdatalink.CheckBrowseMode; +label + endlab; +var + intf: igetdscontroller; + detailoptions: optionsmasterlinkty; +begin + if detaildataset.active then begin + inc(frefreshlock); + try + detailoptions:= tsqlquery(detaildataset).foptionsmasterlink; + if detailoptions * + [mdlo_syncedit,mdlo_syncinsert] <> [] then begin + if getcorbainterface(dataset,typeinfo(igetdscontroller),intf) and + intf.getcontroller.canceling then begin + detaildataset.cancel; + exit; + end + else begin + if mdlo_delayeddetailpost in detailoptions then begin + exit; + end; + if detaildataset.state = dsinsert then begin + dataset.updaterecord; + if dataset.modified then begin + detaildataset.post; + goto endlab; + end; + end; + end; + end; + inherited; + endlab: + if (dataset.state in [dsedit,dsinsert]) and + (detailoptions * [mdlo_syncedit,mdlo_syncinsert] <> []) then begin + dataset.updaterecord; //synchronize fields + end; + if getcorbainterface(detaildataset,typeinfo(igetdscontroller),intf) then begin + with intf.getcontroller do begin + if (dataset.state = dsinsert) and assigned(onupdatemasterinsert) then begin + onupdatemasterinsert(detaildataset,dataset); + end; + if (dataset.state = dsedit) and assigned(onupdatemasteredit) then begin + onupdatemasteredit(detaildataset,dataset); + end; + end; + end; + finally + dec(frefreshlock); + end; + end; +end; + +procedure tsqlmasterparamsdatalink.CopyParamsFromMaster(CopyBound: Boolean); +begin + if not (mdlo_norefresh in fquery.foptionsmasterlink) then begin + inherited; + end; +end; + +procedure tsqlmasterparamsdatalink.RefreshParamNames; +begin + if not (mdlo_norefresh in fquery.foptionsmasterlink) then begin + inherited; + end + else begin + fieldnames:= ''; + end; +end; + +{ TSQLQuery } + +constructor TSQLQuery.Create(AOwner : TComponent); +var + k1: tupdatekind; +begin + fmasterdelayus:= -1; + inherited Create(AOwner); + FParams := TmseParams.create(self); + FSQL := TsqlStringList.Create; + FSQL.OnChange := {$ifdef FPC}@{$endif}OnChangeSQL; + + for k1:= low(tupdatekind) to high(tupdatekind) do begin + fapplysql[k1]:= tupdatestringlist.create; + fapplysql[k1].onchange:= {$ifdef FPC}@{$endif}onchangemodifysql; + end; + { + FSQLUpdate := TupdatesqlStringList.Create; + FSQLUpdate.OnChange := @OnChangeModifySQL; + FSQLInsert := TupdatesqlStringList.Create; + FSQLInsert.OnChange := @OnChangeModifySQL; + FSQLDelete := TsqlStringList.Create; + FSQLDelete.OnChange := @OnChangeModifySQL; +} + FIndexDefs := TIndexDefs.Create(Self); + FReadOnly := false; + FParseSQL := True; + fstatementtype:= stnone; +// Delphi has upWhereAll as default, but since strings and oldvalue's don't work yet +// (variants) set it to upWhereKeyOnly + FUpdateMode := upWhereKeyOnly; + FUsePrimaryKeyAsKey := True; +end; + +destructor TSQLQuery.Destroy; +var + k1: tupdatekind; +begin + if Active then Close; + UnPrepare; + if assigned(FCursor) then (Database as tcustomsqlconnection).DeAllocateCursorHandle(FCursor); + FreeAndNil(FMasterLink); + FreeAndNil(FParams); + FreeAndNil(FSQL); + for k1:= low(tupdatekind) to high(tupdatekind) do begin + freeandnil(fapplyqueries[k1]); + freeandnil(fapplysql[k1]); + end; + { + FreeAndNil(FSQLInsert); + FreeAndNil(FSQLDelete); + FreeAndNil(FSQLUpdate); + } + FreeAndNil(FIndexDefs); + { + freeandnil(finsertqry); + freeandnil(fupdateqry); + freeandnil(fdeleteqry); + } + inherited Destroy; +end; + +procedure TSQLQuery.OnChangeSQL(const Sender : TObject); + +//var ParamName : String; +begin + UnPrepare; + if (FSQL <> nil) then + begin + FParams.ParseSQL(FSQL.Text,True); + If Assigned(FMasterLink) then + FMasterLink.RefreshParamNames; + end; +end; + +procedure TSQLQuery.OnChangeModifySQL(const Sender : TObject); +var + k1: tupdatekind; +begin + if not (csdesigning in componentstate) then begin +// CheckInactive; + if connected then begin + for k1:= low(tupdatekind) to high(tupdatekind) do begin + if sender = fapplysql[k1] then begin + with fapplyqueries[k1] do begin + active:= false; + sql.assign(fapplysql[k1]); + end; + break; + end; + end; + end; + end; +end; + +Procedure TSQLQuery.SetTransaction(const Value : tmdbtransaction); +begin + if ftransaction <> value then begin + checksqltransaction(name,value); + UnPrepare; + inherited; + end; +end; + +procedure TSQLQuery.SetDatabase(const Value : tmdatabase); +begin + dosetsqldatabase(isqlclient(self),value,fcursor,fdatabase); +{ + if (fDatabase <> Value) then begin + checksqlconnection(name,value); + UnPrepare; + if assigned(FCursor) then begin + tcustomsqlconnection(database).DeAllocateCursorHandle(FCursor); + end; + dosetsqldatabase(isqlclient(self),tcustomsqlconnection(value), + tcustomsqlconnection(fdatabase)); + } + { + inherited setdatabase(value); + with tcustomsqlconnection(value) do begin + if (value <> nil) and (self.Transaction = nil) and + (Transaction <> nil) then begin + self.transaction:= Transaction; + end; + end; + } +// end; +end; + +Function TSQLQuery.IsPrepared : Boolean; + +begin + Result := Assigned(FCursor) and FCursor.FPrepared; +end; + +Function TSQLQuery.AddFilter(SQLstr : msestring) : msestring; + +begin + if FWhereStartPos = 0 then + SQLstr := SQLstr + ' where (' + msestring(Filter) + ')' + else if FWhereStopPos > 0 then + system.insert(' and ('+msestring(Filter)+') ',SQLstr,FWhereStopPos+1) + else + system.insert(' where ('+msestring(Filter)+') ',SQLstr,FWhereStartPos); + Result := SQLstr; +end; + +procedure tsqlquery.applyfilter; +//var +// s: string; +begin + freefldbuffers; + tcustomsqlconnection(database).unpreparestatement(fcursor); + fiseof := false; + inherited internalclose; + if filtered and (filter <> '') then begin + fsqlprepbuf:= addfilter(fsqlbuf); + end + else begin + fsqlprepbuf:= fsqlbuf; + end; + if not (bdo_noprepare in foptions) then begin + tcustomsqlconnection(database).preparestatement(fcursor, + tsqltransaction(transaction),fsqlprepbuf,fparams); + end; + execute; + inherited internalopen; + first; +end; + +Procedure TSQLQuery.SetActive (Value : Boolean); + +begin + inherited SetActive(Value); +// The query is UnPrepared, so that if a transaction closes all datasets +// they also get unprepared + if not Value and IsPrepared then UnPrepare; +end; + + +procedure TSQLQuery.SetFiltered(Value: Boolean); + +begin + if Value and not FParseSQL and (filter <> '') then begin + DatabaseErrorFmt(SNoParseSQL,['Filtering ']); + end; + if (Filtered <> Value) then begin + inherited setfiltered(Value); + if active then begin + if filter <> '' then begin + ApplyFilter; + end + else begin + resync([]); + end; + end; + end; +end; + +procedure TSQLQuery.SetFilterText(const Value: string); +begin + if Value <> Filter then + begin + inherited SetFilterText(Value); + if active then ApplyFilter; + end; +end; + +procedure tsqlquery.refresh(const aparams: array of variant); +var + i1: int32; +begin + for i1:= 0 to high(aparams) do begin + params[i1].value:= aparams[i1]; + end; + if active then begin + inherited refresh(); + end + else begin + active:= true; + end; +end; + +procedure TSQLQuery.Prepare; +var + db: tcustomsqlconnection; + sqltr: tsqltransaction; + int1: integer; +const + endchars = ' '#$09#$0a#$0d; +begin + if not IsPrepared then begin + db:= tcustomsqlconnection(database); + sqltr:= tsqltransaction(transaction); + checkdatabase(name,db); + checktransaction(name,sqltr); + + if not Db.Connected then begin + db.Open; + end; + if not sqltr.Active then begin + sqltr.StartTransaction; + end; + + if not assigned(fcursor) then begin + FCursor:= Db.AllocateCursorHandle(icursorclient(self),name); + end; + fcursor.ftrans:= sqltr.handle; + + FSQLBuf:= TrimRight(FSQL.Text); + + if FSQLBuf = '' then begin + DatabaseError(SErrNoStatement); + end; + SQLParser(FSQLBuf); + + if filtered and (filter <> '') then begin + fsqlprepbuf:= AddFilter(FSQLBuf); + end + else begin + fsqlprepbuf:= fsqlbuf; + end; + if not (bdo_noprepare in foptions) then begin + Db.PrepareStatement(Fcursor,sqltr,fsqlprepBuf,FParams); + end; +// ftablename:= ''; + if (FCursor.FStatementType in datareturningtypes) then begin + FCursor.FInitFieldDef := True; + fupdateable:= not readonly and + ( + (sqs_userapplyrecupdate in fmstate) or + (fapplysql[ukmodify].count > 0) and + (fapplysql[ukinsert].count > 0) and + (fapplysql[ukdelete].count > 0) + ); + if fparsesql and (pos(',',FFromPart) <= 0) then begin + //don't change tablename otherwise + ftablename:= ansistring(ffrompart); + int1:= findchars(ftablename,endchars); + if int1 > 0 then begin + setlength(ftablename,int1-1); //use real name only + end; +// fupdateable:= not readonly; + end; + fupdateable:= fupdateable or not readonly and (ftablename <> ''); + end; + end; +end; + +procedure TSQLQuery.UnPrepare; + +begin + if connected then begin + CheckInactive; + end; + if IsPrepared and not (bs_refreshing in fbstate) then begin + with tcustomsqlconnection(Database) do begin + UnPrepareStatement(FCursor); + end; + end; +end; + +procedure TSQLQuery.FreeFldBuffers; +begin + if not (bs_refreshing in fbstate) and assigned(FCursor) then begin + tcustomsqlconnection(database).FreeFldBuffers(FCursor); + end; +end; + +function TSQLQuery.Fetch : boolean; +begin + if not (Fcursor.FStatementType in datareturningtypes) then begin + result:= false; + Exit; + end; + if not FIsEof then begin + FIsEOF:= not tcustomsqlconnection(database).Fetch(Fcursor); + if fiseof then begin + fcursor.close; + end; + end; + Result := not FIsEOF; +end; + +procedure TSQLQuery.Execute; +var +// int1: integer; + bo1: boolean; +begin + If (FParams.Count>0) and Assigned(FMasterLink) then begin + FMasterLink.CopyParamsFromMaster(False); + end; + bo1:= isutf8; + updateparams(fparams,bo1); + fcursor.ftrans:= tsqltransaction(ftransaction).handle; + if bdo_noprepare in foptions then begin + tcustomsqlconnection1(fdatabase).executeunprepared(fcursor, + tsqltransaction(ftransaction),fParams,fsqlprepbuf,bo1); + end + else begin + tcustomsqlconnection1(fdatabase).execute(fcursor, + tsqltransaction(ftransaction),fParams,bo1); + end; +// doexecute(fparams,ftransaction,fcursor,fdatabase,isutf8); +end; + +function tsqlquery.loadfield(const afieldno: integer; + const afieldtype: tfieldtype; const buffer: pointer; + var bufsize: integer): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize +begin + result:= tcustomsqlconnection(database).LoadField(FCursor,aFieldtype, + afieldno,buffer,bufsize,isutf8) +end; + +procedure TSQLQuery.InternalAddRecord(Buffer: Pointer; AAppend: Boolean); +begin + // not implemented - sql dataset +end; + +procedure tsqlquery.freemodifyqueries; +var + k1: tupdatekind; +begin + fbstate:= fbstate - [bs_refreshinsert,bs_refreshupdate, + bs_refreshinsertindex,bs_refreshupdateindex]; + for k1:= low(tupdatekind) to high(tupdatekind) do begin + freeandnil(fapplyqueries[k1]); + end; + { + FreeAndNil(FUpdateQry); + FreeAndNil(FInsertQry); + FreeAndNil(FDeleteQry); + } +end; + +procedure tsqlquery.freequery; +begin + if not (bs_refreshing in fbstate) then begin + if ({not }IsPrepared) and (assigned(database)) and (assigned(FCursor)) then begin + tcustomsqlconnection(database).UnPrepareStatement(FCursor); + end; + if ftransactionwrite = nil then begin + freemodifyqueries; + end; + end; +end; + +procedure TSQLQuery.disconnect{(const aexecute: boolean)}; +begin + if bs_connected in fbstate then begin + if fcursor <> nil then begin + fcursor.close; + end; + freequery; + if not (bs_refreshing in fbstate) then begin + database.deallocatecursorhandle(fcursor); + end; + exclude(fbstate,bs_connected); + if faftercursorclose <> nil then begin + tcustomsqlstatement1(faftercursorclose).execute; +// faftercursorclose.execute(database,tsqltransaction(transaction)); + end; + end; +end; + +procedure TSQLQuery.InternalClose; +begin +// Database and FCursor could be nil, for example if the database is not +// assigned, and .open is called + try + disconnect{(true)}; + finally + if not (bs_refreshing in fbstate) then begin + freemodifyqueries; + fprimarykeyfield:= nil; + if DefaultFields then begin + DestroyFields; + end; + end; + fupdaterowsaffected:= 0; + fblobintf:= nil; +// if StatementType in datareturningtypes then FreeFldBuffers; + FIsEOF := False; + inherited internalclose; + end; +end; + +procedure TSQLQuery.InternalInitFieldDefs; +begin + if FLoadingFieldDefs then begin + Exit; + end; + FLoadingFieldDefs := True; + try + tcustomsqlconnection(database).AddFieldDefs(fcursor,FieldDefs); + finally + FLoadingFieldDefs := False; + end; +end; + +procedure tsqlquery.resetparsing; +begin + FWhereStartPos := 0; + FWhereStopPos := 0; + ffrompart:= ''; +// ftablename:= ''; +end; + +procedure TSQLQuery.SQLParser(var ASQL: msestring); + +type TParsePart = (ppStart,ppSelect,ppWhere,ppFrom,ppGroup,ppOrder,ppComment,ppBogus); + +Var + PSQL,CurrentP, + PhraseP, PStatementPart : pmsechar; + S : msestring; + ParsePart : TParsePart; + StrLength : Integer; + +begin + PSQL:=Pmsechar(ASQL); + ParsePart := ppStart; + PStatementPart:= nil; + CurrentP := PSQL-1; + PhraseP := PSQL; + resetparsing; + + repeat begin + inc(CurrentP); + + if SkipComments(CurrentP) then + if ParsePart = ppStart then PhraseP := CurrentP; + if (currentp^<#128) and + (char(byte(CurrentP^)) in [' ',#13,#10,#9,#0,'(',')',';']) then begin { if(1) } + if (CurrentP-PhraseP > 0) or (CurrentP^ = ';') or + (currentp^ = #0) then begin { if(2) } + strLength := CurrentP-PhraseP; + Setlength(S,strLength); + + if strLength > 0 then Move(PhraseP^,S[1],strLength*sizeof(msechar)); + s := uppercase(s); + + case ParsePart of + ppStart : begin + FCursor.FStatementType:= + tcustomsqlconnection1(database).StrToStatementType(s); + + if FCursor.FStatementType = stSelect then + ParsePart := ppSelect + else + break; + + if not FParseSQL then break; + PStatementPart := CurrentP; + end; {ppStart} + ppSelect : begin + if s = 'FROM' then begin + ParsePart := ppFrom; + PhraseP := CurrentP; + PStatementPart := CurrentP; + end; + end; {ppSelect} + ppFrom : begin + + if (s = 'WHERE') or (s = 'GROUP') or (s = 'ORDER') or (CurrentP^=#0) or (CurrentP^=';') then begin + if (s = 'WHERE') then begin + ParsePart := ppWhere; + StrLength := PhraseP-PStatementPart; + end else if (s = 'GROUP') then begin + ParsePart := ppGroup; + StrLength := PhraseP-PStatementPart + end else if (s = 'ORDER') then begin + ParsePart := ppOrder; + StrLength := PhraseP-PStatementPart + end else begin + ParsePart := ppBogus; + StrLength := CurrentP-PStatementPart; + end; + + Setlength(FFromPart,StrLength); + Move(PStatementPart^,FFromPart[1],StrLength*sizeof(msechar)); + FFrompart := trim(FFrompart); + FWhereStartPos := PStatementPart-PSQL+StrLength+1; + PStatementPart := CurrentP; + end; + + end; {ppFrom} + ppWhere : begin + if (s = 'GROUP') or (s = 'ORDER') or (CurrentP^=#0) or (CurrentP^=';') then begin + ParsePart := ppBogus; + FWhereStartPos := PStatementPart-PSQL; + + if (s = 'GROUP') or (s = 'ORDER') then + FWhereStopPos := PhraseP-PSQL+1 + else + FWhereStopPos := CurrentP-PSQL+1; + end; + end; + end; {ppWhere} + + end; {case} + + PhraseP := CurrentP+1; + end; { if(2) } + end; { if(1) } + until CurrentP^=#0; {repeat} + + if (FWhereStartPos > 0) and (FWhereStopPos > 0) and + filtered and (filter <> '') then begin + system.insert('(',ASQL,FWhereStartPos+1); + inc(FWhereStopPos); + system.insert(')',ASQL,FWhereStopPos); + end; + if not fparsesql and (fstatementtype <> stnone) then begin + fCursor.FStatementType := fstatementtype; + end; +//writeln(ASQL); +end; +(* +procedure TSQLQuery.SQLParser(var ASQL : string); + +type TParsePart = (ppStart,ppSelect,ppWhere,ppFrom,ppOrder,ppComment,ppBogus); + +Var + PSQL,CurrentP, + PhraseP, PStatementPart : pchar; + S : string; + ParsePart : TParsePart; + StrLength : Integer; + +begin + PSQL:=Pchar(ASQL); + ParsePart := ppStart; + + CurrentP := PSQL-1; + PhraseP := PSQL; + + FWhereStartPos := 0; + FWhereStopPos := 0; + + repeat + begin + inc(CurrentP); + + if CurrentP^ in [' ',#13,#10,#9,#0,'(',')',';'] then + begin + if (CurrentP-PhraseP > 0) or (CurrentP^ in [';',#0]) then + begin + strLength := CurrentP-PhraseP; + Setlength(S,strLength); + if strLength > 0 then Move(PhraseP^,S[1],(strLength)); + s := uppercase(s); + + case ParsePart of + ppStart : begin + FCursor.FStatementType := (Database as tcustomsqlconnection).StrToStatementType(s); + if FCursor.FStatementType = stSelect then ParsePart := ppSelect + else break; + if not FParseSQL then break; + PStatementPart := CurrentP; + end; + ppSelect : begin + if s = 'FROM' then + begin + ParsePart := ppFrom; + PhraseP := CurrentP; + PStatementPart := CurrentP; + end; + end; + ppFrom : begin + if (s = 'WHERE') or (s = 'ORDER') or (CurrentP^=#0) or (CurrentP^=';') then + begin + if (s = 'WHERE') then + begin + ParsePart := ppWhere; + StrLength := PhraseP-PStatementPart; + end + else if (s = 'ORDER') then + begin + ParsePart := ppOrder; + StrLength := PhraseP-PStatementPart + end + else + begin + ParsePart := ppBogus; + StrLength := CurrentP-PStatementPart; + end; + Setlength(FFromPart,StrLength); + Move(PStatementPart^,FFromPart[1],(StrLength)); + FFrompart := trim(FFrompart); + FWhereStartPos := PStatementPart-PSQL+StrLength+1; + PStatementPart := CurrentP; + end; + end; + ppWhere : begin + if (s = 'ORDER') or (CurrentP^=#0) or (CurrentP^=';') then + begin + ParsePart := ppBogus; + FWhereStartPos := PStatementPart-PSQL; + if s = 'ORDER' then + FWhereStopPos := PhraseP-PSQL+1 + else + FWhereStopPos := CurrentP-PSQL+1; + end; + end; + end; {case} + end; + PhraseP := CurrentP+1; + end + end; + until CurrentP^=#0; + if (FWhereStartPos > 0) and (FWhereStopPos > 0) then + begin + system.insert('(',ASQL,FWhereStartPos+1); + inc(FWhereStopPos); + system.insert(')',ASQL,FWhereStopPos); + end +end; +*) +{ +procedure TSQLQuery.InitUpdates(ASQL : string); +begin + if pos(',',FFromPart) > 0 then begin + FUpdateable:= (fsqlupdate.count > 0) and (fsqlinsert.count > 0) and + (fsqldelete.count > 0); + // select-statements from more then one table are not updateable + end + else begin + FUpdateable := True; + FTableName := FFromPart; + end; +end; +} + +procedure tsqlquery.connect(const aexecute: boolean); +var + tel{,fieldc}: integer; + f: TField; +// s: string; + ar1: stringarty; + IndexFields: stringarty; + str1: string; + int1: integer; + k1: tupdatekind; +begin + if database <> nil then begin + getcorbainterface(database,typeinfo(iblobconnection),fblobintf); + end; + if not streamloading then begin + try + Prepare; + if FCursor.FStatementType in datareturningtypes then begin + indexfields:= nil; + if FUpdateable then begin + if FusePrimaryKeyAsKey and not (bs_refreshing in fbstate) then begin + UpdateIndexDefs; //must be before execute because + //of MS SQL ODBC one statement per connection limitation + for tel := 0 to indexdefs.count-1 do begin + if ixPrimary in indexdefs[tel].options then begin + ar1:= nil; + splitstringquoted(indexdefs[tel].fields,ar1,'"',';'); + stackarray(ar1,indexfields); + end; + end; + end; + end; + + if aexecute then begin + if fbeforeexecute <> nil then begin + tcustomsqlstatement1(fbeforeexecute).execute; +// fbeforeexecute.execute(database,tsqltransaction(transaction)); + end; + Execute; + if FCursor.FInitFieldDef and not (bs_refreshing in fbstate) then begin + InternalInitFieldDefs; + end; + end; + if not (bs_refreshing in fbstate) then begin + if DefaultFields and aexecute then begin + CreateFields; + end; + for int1:= 0 to high(indexfields) do begin + F := Findfield(IndexFields[int1]); + if F <> nil then begin + F.optionsfield:= F.optionsfield + [of_InKey]; + end; + end; + if (database <> nil) and (ftablename <> '') then begin + str1:= tcustomsqlconnection1(database).getprimarykeyfield( + ftablename,fcursor); + if (str1 <> '') then begin + fprimarykeyfield:= fields.findfield(str1); + end; + end; + if fupdateable then begin + for k1:= low(tupdatekind) to high(tupdatekind) do begin + if fapplyqueries[k1] = nil then begin + fapplyqueries[k1]:= tsqlresult.create(nil); + with fapplyqueries[k1] do begin + transaction:= self.writetransaction; + database:= self.database; + sql.assign(fapplysql[k1]); + statementtype:= updatestatementtypes[k1]; + end; + end; + end; + end; + end; + end + else begin + DatabaseError(SErrNoSelectStatement,Self); + end; + except + on E:Exception do + raise; + end; + include(fbstate,bs_connected); + end; +end; + +procedure tsqlquery.internalopen; +{$ifdef mse_debugdataset} +var + ts: longword; +{$endif} +begin +{$ifdef mse_debugdataset} + debugoutstart(ts,self,'connect'); +{$endif} + connect(true); +{$ifdef mse_debugdataset} + debugoutend(ts,self,'connect'); +{$endif} +{$ifdef mse_debugdataset} + debugoutstart(ts,self,'internalopen'); +{$endif} + if fmasterlink <> nil then begin + checkrecursivedatasource(fmasterlink.datasource); + end; + inherited; +{$ifdef mse_debugdataset} + debugoutend(ts,self,'internalopen'); +{$endif} +end; + +procedure tsqlquery.dorefresh; +var + int1: integer; +begin + int1:= recno; + include(fbstate,bs_refreshing); + try + active:= false; + active:= true; + if (recno <> int1) and (bs_restorerecno in fbstate) then begin + setrecno1(int1,true); + end; + finally + exclude(fbstate,bs_refreshing); + if not active then begin + freefieldbuffers; + freequery; + end; + end; +end; + +procedure tsqlquery.refreshtransaction; +var + bo1: boolean; +begin + if not (bdo_notransactionrefresh in foptions) then begin + if bdo_recnotransactionrefresh in foptions then begin + bo1:= bs_restorerecno in fbstate; + include(fbstate,bs_restorerecno); + try + dorefresh; + finally + if not bo1 then begin + exclude(fbstate,bs_restorerecno); + end; + end; + end + else begin + dorefresh; + end; + end; +end; + +procedure tsqlquery.internalrefresh; +begin + if bdo_refreshtransaction in foptions then begin + if transaction.savepointlevel < 0 then begin + transaction.refresh; + end + else begin + transaction.pendingrefresh:= true; + end; + end + else begin + dorefresh; + end; +end; + +procedure TSQLQuery.ExecSQL; +begin + try + Prepare; + Execute; + finally + // FCursor has to be assigned, or else the prepare went wrong before PrepareStatment was + // called, so UnPrepareStatement shoudn't be called either + if (not IsPrepared) and (assigned(database)) and (assigned(FCursor)) then begin + (database as tcustomsqlconnection).UnPrepareStatement(Fcursor); + end; + end; +end; + +procedure TSQLQuery.SetReadOnly(AValue : Boolean); + +begin + CheckInactive; + freadonly:= avalue; +// if not AValue then +// begin +// if FParseSQL then FReadOnly := False +// else DatabaseErrorFmt(SNoParseSQL,['Updating ']); +// end +// else FReadOnly := True; +end; + +procedure TSQLQuery.SetParseSQL(AValue : Boolean); + +begin + CheckInactive; + if fparsesql <> avalue then begin + fparsesql:= avalue; + if not AValue then begin + Filtered:= False; + resetparsing; + end; + unprepare; //refresh sqlparser + end; +end; + +procedure tsqlquery.setstatementtype(const avalue: tstatementtype); +begin + CheckInactive; + if fstatementtype <> avalue then begin + fstatementtype:= avalue; + unprepare; //refresh sqlparser + end; +end; + +procedure TSQLQuery.SetUsePrimaryKeyAsKey(AValue : Boolean); + +begin + if not Active then FusePrimaryKeyAsKey := AValue + else + begin + // Just temporary, this should be possible in the future + DatabaseError(SActiveDataset); + end; +end; + +Procedure TSQLQuery.UpdateIndexDefs; + +begin + findexdefs.clear; + if assigned(DataBase) and (ftablename <> '') then begin + tcustomsqlconnection1(database).UpdateIndexDefs(FIndexDefs,FTableName,fcursor); + end; +end; + +procedure tsqlquery.updatewherepart(var sql_where : msestring; const afield: tfield); +var + quotechar: msestring; +begin + if database <> nil then begin + quotechar:= tcustomsqlconnection1(database).identquotechar; + end + else begin + quotechar:= '"'; + end; + with afield do begin + if (of_InKey in optionsfield) or + ((FUpdateMode = upWhereAll) and (of_InWhere in optionsfield)) or + ((FUpdateMode = UpWhereChanged) and + (of_InWhere in optionsfield) and + (value <> oldvalue)) then begin + sql_where := sql_where + '(' + quotechar+msestring(FieldName)+quotechar+ + '= :OLD_' + msestring(FieldName) + ') and '; + end; + end; +end; + +function tsqlquery.refreshrecquery(const update: boolean): msestring; +var + int1,int2: integer; +// intf1: imsefield; + field1: tfield; +// flags1: providerflags1ty; +begin + result:= ''; + int2:= 0; + for int1:= 0 to fields.count - 1 do begin + field1:= fields[int1]; + if (field1.fieldkind = fkdata) {and + getcorbainterface(field1,typeinfo(imsefield),intf1)} then begin +// flags1:= intf1.getproviderflags1; + if (of_refreshupdate in field1.optionsfield) and update or + (of_refreshinsert in field1.optionsfield) and not update then begin + if int2 = 0 then begin + result:= ' returning '; + end; + result:= result + msestring(field1.fieldname) + ','; + inc(int2); + if update then begin + if not (bs_refreshupdateindex in fbstate) and + indexlocal.hasfield(field1) then begin + include(fbstate,bs_refreshupdateindex); + end; + end + else begin + if not (bs_refreshinsertindex in fbstate) and + indexlocal.hasfield(field1) then begin + include(fbstate,bs_refreshinsertindex); + end; + end; + end; + end; + end; + if int2 > 0 then begin + if update then begin + include(fbstate,bs_refreshupdate); + end + else begin + include(fbstate,bs_refreshinsert); + end; + setlength(result,length(result)-1); + end + else begin + end; +end; + +procedure tsqlquery.checktablename; +begin + if ftablename = '' then begin + databaseerror('No table name in apply recupdate statement',self); + end; +end; + +function tsqlquery.updaterecquery : msestring; +var + x: integer; + sql_set: msestring; + sql_where: msestring; + field1: tfield; + quotechar: msestring; +begin + checktablename; + quotechar:= tcustomsqlconnection1(database).identquotechar; + sql_set:= ''; + sql_where:= ''; + for x := 0 to Fields.Count -1 do begin + field1:= fields[x]; + with field1 do begin + if fieldkind = fkdata then begin + UpdateWherePart(sql_where,field1); + if (of_InUpdate in optionsfield) then begin + sql_set:= sql_set + quotechar+msestring(FieldName)+quotechar + '=:' + + msestring(FieldName) + ','; + end; + end; + end; + end; + if sql_set = '' then begin + databaseerror('No "set" part in SQLUpdate statement.',self); + end; + if sql_where = '' then begin + databaseerror('No "where" part in SQLUpdate statement.',self); + end; + setlength(sql_set,length(sql_set)-1); + setlength(sql_where,length(sql_where)-5); + result := 'update ' + msestring(FTableName) + ' set ' + sql_set + + ' where ' + sql_where; + result:= result + refreshrecquery(true); +end; + + +function tsqlquery.insertrecquery: msestring; +var + x: integer; + sql_fields: msestring; + sql_values: msestring; + quotechar: msestring; +begin + checktablename; + quotechar:= tcustomsqlconnection1(database).identquotechar; + sql_fields := ''; + sql_values := ''; + for x := 0 to Fields.Count -1 do begin + with fields[x] do begin + if (fieldkind = fkdata) {and not IsNull} and + (of_InInsert in optionsfield) then begin + sql_fields:= sql_fields + quotechar+msestring(FieldName)+quotechar+ ','; + sql_values:= sql_values + ':' + msestring(FieldName) + ','; + end; + end; + end; + if sql_fields = '' then begin + databaseerror('No "values" part in SQLInsert statement.',self); + end; + setlength(sql_fields,length(sql_fields)-1); + setlength(sql_values,length(sql_values)-1); + result := 'insert into ' + msestring(FTableName) + + ' (' + sql_fields + ') values (' +sql_values + ')'; + result:= result + refreshrecquery(false); +end; + +function tsqlquery.deleterecquery : msestring; +var + x: integer; + sql_where: msestring; + field1: tfield; +begin + checktablename; + sql_where := ''; + for x := 0 to Fields.Count -1 do begin + field1:= fields[x]; + if field1.fieldkind = fkdata then begin + UpdateWherePart(sql_where,field1); + end; + end; + if sql_where = '' then begin + databaseerror('No "where" part in SQLDelete statement.',self); + end; + setlength(sql_where,length(sql_where)-5); + result := 'delete from ' + msestring(FTableName) + ' where ' + sql_where; +end; + +Procedure TSQLQuery.internalApplyRecUpdate(UpdateKind : TUpdateKind); +var + x: integer; + fld1: tfield; + param1,param2: tparam; + int1: integer; + blobspo: pblobinfoarty; + str1: string; + bo1: boolean; + freeblobar: pointerarty; + statementtypebefore: tstatementtype; + oldisnew: boolean; + rowsaffected1: integer; + +begin + oldisnew:= (updatekind = ukinsert) and (bs_inserttoupdate in fbstate); + if oldisnew then begin + updatekind:= ukmodify; + end; + blobspo:= getintblobpo; + if fapplyqueries[updatekind] = nil then begin + databaseerror(name+': No rec apply query for '+ + getenumname(typeinfo(tupdatekind),ord(updatekind))+'.'); + end; + with tsqlresult1(fapplyqueries[updatekind]) do begin + if sql.count = 0 then begin + case updatekind of + ukinsert: begin + sql.add(self.insertrecquery); + end; + ukmodify: begin + sql.add(self.updaterecquery); + end; + ukdelete: begin + sql.add(self.deleterecquery); + end; + end; + end; + futf8:= self.isutf8; + transaction.active:= true; + freeblobar:= nil; + try + for x := 0 to Params.Count-1 do begin + param1:= params[x]; + with param1 do begin + str1:= name; + bo1:= pos('OLD_',str1) = 1; + if bo1 then begin + str1:= copy(str1,5,bigint); + end; + if bo1 and not oldisnew then begin + fld1:= self.FieldByName(str1); + oldfieldtoparam(fld1,param1); + end + else begin + fld1:= self.findfield(str1); + if fld1 = nil then begin //search for param + param2:= self.params.findparam(str1); + if param2 = nil then begin + fieldbyname(str1); //raise exception + end + else begin + value:= param2.value; + end; + end + else begin //use field + if fld1 is tblobfield and (self.fblobintf <> nil) then begin + if fld1.isnull then begin + clear; + datatype:= fld1.datatype; + end + else begin + bo1:= false; + for int1:= 0 to high(blobspo^) do begin + if blobspo^[int1].field = fld1 then begin + self.fblobintf.writeblobdata(tsqltransaction(self.transaction), + self.ftablename,self.fcursor, + blobspo^[int1].data,blobspo^[int1].datalength,fld1,params[x],str1); + if str1 <> '' then begin + self.setdatastringvalue(fld1,str1); + additem(freeblobar,fld1); + end; + bo1:= true; + break; + end; + end; + if not bo1 then begin + self.fblobintf.setupblobdata(fld1,self.fcursor,params[x]); + end; + end; + end + else begin + self.fieldtoparam(fld1,param1); + end; + end; + end; + end; + end; + + if (updatekind = ukmodify) and + (bs_refreshupdate in self.fbstate) or + (updatekind = ukinsert) and + (bs_refreshinsert in self.fbstate) then begin + statementtypebefore:= statementtype; + try + statementtype:= stselect; + refresh; + if not eof then begin + for int1:= 0 to datacols.count - 1 do begin + with datacols[int1] do begin + fld1:= self.fields.fieldbyname(fieldname); + fld1.value:= asvariant; + end; + end; + end; + rowsaffected1:= fcursor.frowsaffected; + finally + clear; + statementtype:= statementtypebefore; + end; + end + else begin + execute; + rowsaffected1:= fcursor.frowsaffected; + end; + + if not (bs_refreshinsert in fbstate) and (updatekind = ukinsert) and + (self.fprimarykeyfield <> nil) then begin + tcustomsqlconnection1(database).updateprimarykeyfield( + self.fprimarykeyfield,transaction); + end; + if (self.fupdaterowsaffected < 0) or (rowsaffected1 < 0) then begin + self.fupdaterowsaffected:= rowsaffected1; + end + else begin + self.fupdaterowsaffected:= self.fupdaterowsaffected + rowsaffected1; + end; + { + if self.fupdaterowsaffected >= 0 then begin + if self.fcursor.frowsaffected < 0 then begin + self.fupdaterowsaffected:= -1; + end + else begin + inc(self.fupdaterowsaffected,rowsaffected1); + end; + end; + } + finally + for int1:= high(freeblobar) downto 0 do begin + deleteblob(blobspo^,tfield(freeblobar[int1]),true); + end; + end; + end; +end; + +Procedure TSQLQuery.ApplyRecUpdate(UpdateKind : TUpdateKind); +begin + internalapplyrecupdate(updatekind); +end; + +{ +Procedure TSQLQuery.ApplyRecUpdate(UpdateKind : TUpdateKind); + +var + s : string; + + procedure UpdateWherePart(var sql_where : string;x : integer); + + begin + if (pfInKey in Fields[x].ProviderFlags) or + ((FUpdateMode = upWhereAll) and (pfInWhere in Fields[x].ProviderFlags)) or + ((FUpdateMode = UpWhereChanged) and (pfInWhere in Fields[x].ProviderFlags) and (fields[x].value <> fields[x].oldvalue)) then + sql_where := sql_where + '(' + fields[x].FieldName + '= :OLD_' + fields[x].FieldName + ') and '; + end; + + function ModifyRecQuery : string; + + var x : integer; + sql_set : string; + sql_where : string; + + begin + sql_set := ''; + sql_where := ''; + for x := 0 to Fields.Count -1 do + begin + UpdateWherePart(sql_where,x); + + if (pfInUpdate in Fields[x].ProviderFlags) then + sql_set := sql_set + fields[x].FieldName + '=:' + fields[x].FieldName + ','; + end; + + setlength(sql_set,length(sql_set)-1); + setlength(sql_where,length(sql_where)-5); + result := 'update ' + FTableName + ' set ' + sql_set + ' where ' + sql_where; + + end; + + function InsertRecQuery : string; + + var x : integer; + sql_fields : string; + sql_values : string; + + begin + sql_fields := ''; + sql_values := ''; + for x := 0 to Fields.Count -1 do + begin + if not fields[x].IsNull then + begin + sql_fields := sql_fields + fields[x].FieldName + ','; + sql_values := sql_values + ':' + fields[x].FieldName + ','; + end; + end; + setlength(sql_fields,length(sql_fields)-1); + setlength(sql_values,length(sql_values)-1); + + result := 'insert into ' + FTableName + ' (' + sql_fields + ') values (' + sql_values + ')'; + end; + + function DeleteRecQuery : string; + + var x : integer; + sql_where : string; + + begin + sql_where := ''; + for x := 0 to Fields.Count -1 do + UpdateWherePart(sql_where,x); + + setlength(sql_where,length(sql_where)-5); + + result := 'delete from ' + FTableName + ' where ' + sql_where; + end; + +var qry : TSQLQuery; + x : integer; + Fld : TField; + +begin + case UpdateKind of + ukModify : begin + qry := FUpdateQry; + if trim(qry.sql.Text) = '' then qry.SQL.Add(ModifyRecQuery); + end; + ukInsert : begin + qry := FInsertQry; + if trim(qry.sql.Text) = '' then qry.SQL.Add(InsertRecQuery); + end; + ukDelete : begin + qry := FDeleteQry; + if trim(qry.sql.Text) = '' then qry.SQL.Add(DeleteRecQuery); + end; + end; + with qry do + begin + for x := 0 to Params.Count-1 do with params[x] do if leftstr(name,4)='OLD_' then + begin + Fld := self.FieldByName(copy(name,5,length(name)-4)); + AssignFieldValue(Fld,Fld.OldValue); + end + else + begin + Fld := self.FieldByName(name); + AssignFieldValue(Fld,Fld.Value); + end; + execsql; + end; +end; +} + +Function TSQLQuery.GetCanModify: Boolean; + +begin + if not connected then begin + result:= active and not freadonly; + end + else begin + if (fcursor <> nil) and + (FCursor.FStatementType in datareturningtypes) then begin + Result:= Active and + (FUpdateable or (bdo_noapply in foptions)) and (not FReadOnly) + end + else begin + Result:= False; + end; + end; +end; + +function TSQLQuery.GetIndexDefs : TIndexDefs; + +begin + Result := FIndexDefs; +end; + +procedure TSQLQuery.SetIndexDefs(AValue : TIndexDefs); + +begin + FIndexDefs := AValue; +end; + +procedure TSQLQuery.SetUpdateMode(AValue : TUpdateMode); + +begin + FUpdateMode := AValue; +end; +{ +procedure TSQLQuery.SetSchemaInfo( SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string); + +begin + ReadOnly := True; + SQL.Clear; + SQL.Add(tcustomsqlconnection1(database).GetSchemaInfoSQL( + SchemaType, SchemaObjectName, SchemaPattern)); +end; +} +function TSQLQuery.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; +var + info: blobcacheinfoty; +// int1: integer; + blob1: blobinfoty; +begin + result:= inherited createblobstream(field,mode); + if result = nil then begin + if (bs_blobsfetched in fbstate) and (mode = bmread) then begin + info.id:= 0; //fieldsize can be 32 bit + if field.getdata(@info.id) and findcachedblob(info) then begin + blob1.data:= pointer(info.data); + blob1.datalength:= length(info.data); + result:= tblobcopy.create(blob1); + end; + end + else begin + if database = nil then begin + if mode = bmwrite then begin + result:= createblobbuffer(field); + end; + end + else begin + result:= tcustomsqlconnection1(database).CreateBlobStream(Field, + Mode,fcursor); + end; + end; + end; +end; +{ +function TSQLQuery.GetStatementType : TStatementType; + +begin + if assigned(FCursor) then Result := FCursor.FStatementType + else Result := stNone; +end; +} +procedure tsqlquery.checkrecursivedatasource(const avalue: tdatasource); +var + dso1: tdatasource; + ds1: tdataset; + int1: integer; +begin + dso1:= avalue; + int1:= 0; + while dso1 <> nil do begin + inc(int1); + if (dso1.dataset = self) or (int1 > 100) then begin + databaseerror('Recursive datasource.',self); + end; + ds1:= dso1.dataset; + if ds1 is tsqlquery then begin + dso1:= tsqlquery(ds1).datasource; + end + else begin + break; + end; + end; +end; + +Procedure TSQLQuery.SetDataSource(AVAlue : TDatasource); +Var + DS : TDatasource; +begin + checkrecursivedatasource(avalue); + DS:=DataSource; + If (AValue<>DS) then begin + If Assigned(DS) then begin + DS.RemoveFreeNotification(Self); + end; + If Assigned(AValue) then begin + AValue.FreeNotification(Self); + FMasterLink:= TsqlMasterParamsDataLink.Create(Self); + FMasterLink.Datasource:= AValue; + end + else begin + FreeAndNil(FMasterLink); + end; + end; +end; + +Function TSQLQuery.GetDataSource : TDatasource; + +begin + If Assigned(FMasterLink) then + Result:=FMasterLink.DataSource + else + Result:=Nil; +end; + +procedure tsqlquery.notification(acomponent: tcomponent; operation: toperation); +begin + inherited; + if operation = opremove then begin + if acomponent = datasource then begin + datasource:= nil; + end; + if acomponent = fbeforeexecute then begin + fbeforeexecute:= nil; + end; + if acomponent = faftercursorclose then begin + faftercursorclose:= nil; + end; + end; +end; + +function TSQLQuery.getblobdatasize: integer; +begin + if database = nil then begin + result:= sizeof(int64); //max + end + else begin + result:= tcustomsqlconnection1(database).getblobdatasize; + end; +end; + +function TSQLQuery.getdatabase1: tcustomsqlconnection; +begin + result:= tcustomsqlconnection(inherited database); +end; + +function tsqlquery.getdatabase: tcustomconnection; //for isqlpropertyeditor +begin + result:= database; +end; + +procedure TSQLQuery.setdatabase1(const avalue: tcustomsqlconnection); +begin + inherited database:= avalue; +end; +{ +procedure TSQLQuery.checkdatabase; +begin + docheckdatabase(name,fdatabase); + if inherited database = nil then begin + databaseerror(serrdatabasenassigned); + end; +end; +} +function TSQLQuery.executedirect(const asql: msestring): integer; +begin + checkdatabase(name,fdatabase); + result:= database.executedirect(asql,writetransaction); +end; + +procedure TSQLQuery.setparams(const avalue: TmseParams); +begin + fparams.assign(avalue); +end; + +function tsqlquery.getconnected: boolean; +begin + result:= bs_connected in fbstate; +// result:= (transaction <> nil) and transaction.active; +end; + +function tsqlquery.blobscached: boolean; +begin + result:= (fblobintf <> nil) and fblobintf.blobscached; +end; + +procedure TSQLQuery.setconnected(const avalue: boolean); +var + int1: integer; + uk1: tupdatekind; +begin //todo: check connect disconnect sequence + if not (bs_opening in fbstate) then begin + checkactive; + end; + if avalue <> connected then begin + if avalue then begin + closelogger; + connect(false); + end + else begin + if transaction.active then begin + fetchallblobs; + int1:= 0; + if (ftransactionwrite = nil) or (ftransactionwrite = ftransaction) then begin + for uk1:= low(tupdatekind) to high(tupdatekind) do begin + if fapplyqueries[uk1] <> nil then begin + inc(int1); + end; + end; + end; + tsqltransaction1(transaction).disconnect(self,int1); + disconnect{(false)}; + unprepare; + tcustomsqlconnection(database).DeAllocateCursorHandle(FCursor); + startlogger; + end; + end; + end; +end; + +procedure tsqlquery.setfsql(const avalue: tsqlstringlist); +begin + fsql.assign(avalue); +end; + +procedure tsqlquery.setfsqlupdate(const avalue: tupdatestringlist); +begin + fapplysql[ukmodify].assign(avalue); +end; + +procedure tsqlquery.setfsqlinsert(const avalue: tupdatestringlist); +begin + fapplysql[ukinsert].assign(avalue); +end; + +procedure tsqlquery.setfsqldelete(const avalue: tupdatestringlist); +begin + fapplysql[ukdelete].assign(avalue); +end; + +procedure TSQLQuery.setbeforeexecute(const avalue: tcustomsqlstatement); +begin + if fbeforeexecute <> nil then begin + fbeforeexecute.removefreenotification(self); + end; + fbeforeexecute:= avalue; + if fbeforeexecute <> nil then begin + fbeforeexecute.freenotification(self); + end; +end; + +procedure TSQLQuery.setaftercursorclose(const avalue: tcustomsqlstatement); +begin + if faftercursorclose <> nil then begin + faftercursorclose.removefreenotification(self); + end; + faftercursorclose:= avalue; + if faftercursorclose <> nil then begin + faftercursorclose.freenotification(self); + end; +end; + +function TSQLQuery.getnumboolean: boolean; +begin + result:= tcustomsqlconnection1(database).getnumboolean; +end; + +function TSQLQuery.getfloatdate: boolean; +begin + result:= tcustomsqlconnection1(database).getfloatdate; +end; + +function TSQLQuery.getint64currency: boolean; +begin + result:= tcustomsqlconnection1(database).getint64currency; +end; + +function TSQLQuery.getsqltransaction: tsqltransaction; +begin + result:= tsqltransaction(inherited transaction); +end; + +procedure TSQLQuery.setsqltransaction(const avalue: tsqltransaction); +begin + inherited transaction:= avalue; +end; + +function TSQLQuery.getsqltransactionwrite: tsqltransaction; +begin + result:= tsqltransaction(inherited transactionwrite); +end; + +procedure TSQLQuery.settransactionwrite(const avalue: tmdbtransaction); +begin + if avalue <> ftransactionwrite then begin + checkpendingupdates; + end; + inherited; +end; + +procedure TSQLQuery.setsqltransactionwrite(const avalue: tsqltransaction); +begin + inherited transactionwrite:= avalue; +end; + +procedure TSQLQuery.applyupdate(const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); +begin + fupdaterowsaffected:= 0; + inherited; +end; + +procedure TSQLQuery.applyupdates(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); +begin + fupdaterowsaffected:= 0; + if fdatabase = nil then begin + inherited; + end + else begin + tcustomsqlconnection1(fdatabase).beginupdate; + try + inherited; + finally + tcustomsqlconnection1(fdatabase).endupdate; + end; + end; +end; + +function TSQLQuery.writetransaction: tsqltransaction; +begin + result:= tsqltransaction(ftransactionwrite); + if result = nil then begin + result:= transaction; + end; +end; + +procedure TSQLQuery.dobeforeapplyupdate; +begin + inherited; + if writetransaction <> nil then begin + writetransaction.active:= true; + end; +end; + +function TSQLQuery.rowsreturned: integer; +begin + if active and (fcursor <> nil) then begin + result:= fcursor.frowsreturned; + end + else begin + result:= -1; + end; +end; + +function TSQLQuery.rowsaffected: integer; +begin + if active and (fcursor <> nil) then begin + result:= fcursor.frowsaffected; + end + else begin + result:= -1; + end; +end; + +procedure TSQLQuery.checkpendingupdates; +begin + //dummy +end; + +function TSQLQuery.stringmemo: boolean; +begin + result:= false; + //dummy +end; + +function TSQLQuery.isutf8: boolean; +begin + result:= futf8; +// if fdatabase <> nil then begin +// tcustomsqlconnection(fdatabase).updateutf8(result); +// end; +end; +{ +procedure TSQLQuery.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + fmasterlinkoptions:= []; + if dso_syncmasteredit in aoptions then begin + include(fmasterlinkoptions,mdlo_syncedit); + end; + if dso_syncmasterinsert in aoptions then begin + include(fmasterlinkoptions,mdlo_syncinsert); + end; + if dso_syncmasterdelete in aoptions then begin + include(fmasterlinkoptions,mdlo_syncdelete); + end; + if dso_delayeddetailpost in aoptions then begin + include(fmasterlinkoptions,mdlo_delayeddetailpost); + end; + if dso_syncinsertfields in aoptions then begin + include(fmasterlinkoptions,mdlo_syncinsertfields); + end; +end; +} +{ +procedure TSQLQuery.setmasterlink(const avalue: tsqlmasterparamsdatalink); +begin + fmasterlink.assign(avalue); +end; +} +procedure TSQLQuery.dobeforeedit; +begin + if (fmasterlink <> nil) then begin + fmasterlink.checkrefresh; + end; + inherited; +end; + +procedure TSQLQuery.dobeforeinsert; +begin + if (fmasterlink <> nil) then begin + fmasterlink.checkrefresh; + end; + inherited; +end; + +procedure TSQLQuery.settablename(const avalue: string); +begin + checkinactive; + ftablename:= avalue; +end; + +procedure TSQLQuery.dataevent(event: tdataevent; info: ptrint); +var + int1: integer; + sf,df: tfield; + str1: string; +begin + case event of + deupdaterecord: begin + if (mdlo_syncfields in foptionsmasterlink) and (fmasterlink <> nil) and + fmasterlink.active then begin + for int1:= 0 to fparams.count - 1 do begin + str1:= fparams[int1].name; + if (str1 <> '') then begin + df:= findfield(str1); + if df <> nil then begin + sf:= fmasterlink.dataset.findfield(str1); + if (sf <> nil) and (df.value <> sf.value) then begin + //no modified touch + df.value:= sf.value; + end; + end; + end; + end; + end; + end; + end; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msesqlresult.pas b/mseide-msegui/lib/common/db/msesqlresult.pas new file mode 100644 index 0000000..20ac0a0 --- /dev/null +++ b/mseide-msegui/lib/common/db/msesqlresult.pas @@ -0,0 +1,2458 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesqlresult; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifdef VER2_1_5} {$define mse_FPC_2_2} {$endif} +{$ifdef VER2_2} {$define mse_FPC_2_2} {$endif} +uses + classes,mclasses,mdb,msqldb,mseclasses,msedb,msedatabase,msearrayprops, + msestrings,msereal,mseinterfaces, + msetypes,mselookupbuffer,mseglob,msedatalist,msevariants,mseevent; +type + tsqlresult = class; + + tdbcol = class(tvirtualpersistent) + private + function getassql1: msestring; + function getasid: int64; + protected + fuppername: ansistring; + ffieldname: ansistring; + fsqlresult: tsqlresult; + fcursor: tsqlcursor; + fdatatype: tfieldtype; + ffieldnum: integer; + futf8: boolean; + fdatasize: integer; + function accesserror(const typename: string): edatabaseerror; + function getvariantvar: variant; virtual; + function getasvariant: variant; virtual; + function getasboolean: boolean; virtual; + function getascurrency: currency; virtual; + function getaslargeint: largeint; virtual; + function getasdatetime: tdatetime; virtual; + function getasdatetime1: tdatetime; virtual; + function getasfloat: double; virtual; + function getasfloat1: double; virtual; + function getasinteger: longint; virtual; + function getasstring: string; virtual; + function getasstring1: string; virtual; + function getasmsestring: msestring; virtual; + function getasmsestring1: msestring; virtual; + function getassql: msestring; virtual; + function getasguid: tguid; virtual; + function getisnull: boolean; virtual; + function loadfield(const buffer: pointer; var bufsize: integer): boolean; overload; + //false if null or inactive + function loadfield(const buffer: pointer): boolean; overload; + //false if null or inactive + public + constructor create(const asqlresult: tsqlresult; + const acursor: tsqlcursor; const afielddef: tfielddef); reintroduce; + property datatype: tfieldtype read fdatatype; + property fieldname: ansistring read ffieldname; + property size: integer read fdatasize; + + property asvariant: variant read getasvariant; + //empty variant returned for null fields + property asboolean: boolean read getasboolean; + property ascurrency: currency read getascurrency; + property aslargeint: largeint read getaslargeint; + property asdatetime: tdatetime read getasdatetime1; + property asfloat: double read getasfloat1; + property asinteger: longint read getasinteger; + property asstring: ansistring read getasstring1; + property asmsestring: msestring read getasmsestring1; + property assql: msestring read getassql1; + property asid: int64 read getasid; + property asguiid: tguid read getasguid; + property isnull: boolean read getisnull; + + end; + dbcolclassty = class of tdbcol; + dbcolarty = array of tdbcol; + + tstringdbcol = class(tdbcol) + private + protected + function getasmsestring1: msestring; override; + function getasmsestring: msestring; override; + function getasstring: ansistring; override; + function getasstring1: ansistring; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + public + property value: msestring read getasmsestring; + end; + + tguiddbcol = class(tdbcol) + private + protected + function getasguid: tguid; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + end; + + tnumericdbcol = class(tdbcol) + private + protected + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + function getasmsestring: msestring; override; + end; + + tlongintdbcol = class(tnumericdbcol) + protected + function getasinteger: integer; override; + public + property value: integer read getasinteger; + end; + + tlargeintdbcol = class(tnumericdbcol) + private + protected + function getaslargeint: largeint; override; + function getasinteger: integer; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + function getasmsestring: msestring; override; + public + property value: largeint read getaslargeint; + end; + + tsmallintdbcol = class(tnumericdbcol) + protected + function getasinteger: integer; override; + public + property value: integer read getasinteger; + end; + + tworddbcol = class(tnumericdbcol) + protected + function getasinteger: integer; override; + public + property value: integer read getasinteger; + end; + +// tautoincdbcol = class(tdbcol); + + tfloatdbcol = class(tdbcol) + private + protected + function getasfloat: double; override; + function getasfloat1: double; override; + function getascurrency: currency; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + function getasmsestring: msestring; override; + public + property value: double read getasfloat; + end; + + tcurrencydbcol = class(tdbcol) + private + protected + function getascurrency: currency; override; + function getasfloat: double; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + public + property value: currency read getascurrency; + end; + + tbooleandbcol = class(tdbcol) + private + protected + function getasboolean: boolean; override; + function getasinteger: integer; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + public + property value: boolean read getasboolean; + end; + + tdatetimedbcol = class(tfloatdbcol) + private + protected + function getasdatetime: tdatetime; override; + function getasdatetime1: tdatetime; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + public + property value: tdatetime read getasdatetime; + end; + +// tdatedbcol = class(tdbcol); +// ttimedbcol = class(tdbcol); +// tbinarydbcol = class(tdbcol); +// tbytesdbcol = class(tdbcol); +// tvarbytesdbcol = class(tdbcol); +// tbcddbcol = class(tdbcol); + + tblobdbcol = class(tdbcol) + private + protected + function getasstring: ansistring; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + public + property value: ansistring read getasstring; + end; + + tmemodbcol = class(tblobdbcol) + private + protected + function getvariantvar: variant; override; + function getassql: msestring; override; + public + property value: msestring read getasmsestring; + end; + + tvariantdbcol = class(tdbcol) + private + protected + function getvariantvar: variant; override; + public + property value: variant read getvariantvar; + end; + +// tgraphicdbcol = class(tdbcol); + + getnamefuncty = function:ansistring of object; + + tdbcols = class(tpersistentarrayprop) + private + fgetname: getnamefuncty; + function getitems(const index: integer): tdbcol; + procedure initfields(const asqlresult: tsqlresult; + const acursor: tsqlcursor; const afielddefs: tfielddefs); + public + constructor create(const agetname: getnamefuncty); + function findcol(const aname: ansistring): tdbcol; + function findcolindex(const aname: ansistring): integer; + function colbyname(const aname: ansistring): tdbcol; + function colsbyname(const anames: array of ansistring): dbcolarty; + //invalid after close! + function colsindexbyname(const anames: array of ansistring): integerarty; + property items[const index: integer]: tdbcol read getitems; default; + end; + +// tsqlresultfielddef = class; + + dbcolnamety = string; + + tsqlresultconnector = class(tmsecomponent) + private + fcol: tdbcol; +// ffielddef: tsqlresultfielddef; + fsource: tsqlresult; + fcolname: dbcolnamety; + function getcol: tdbcol; + procedure setsource(const avalue: tsqlresult); + procedure setcolname(const avalue: dbcolnamety); + protected + procedure objevent(const sender: iobjectlink; + const event: objecteventty); override; + public + destructor destroy; override; + property col: tdbcol read getcol; + published + property source: tsqlresult read fsource write setsource; + property colname: dbcolnamety read fcolname write setcolname; + end; +{ + tsqlresultfielddef = class(tfielddef) + destructor destroy; override; + private + fconnector: tsqlresultconnector; + procedure setconnector(const avalue: tsqlresultconnector); + published + property connector: tsqlresultconnector read fconnector write setconnector; + end; +} + tsqlresultfielddefs = class(tfielddefs) + private +// fsqlresult: tsqlresult; + protected + procedure setitemname(aitem: tcollectionitem); override; +// procedure bindconnectors; +// public +// constructor create(const aowner: tsqlresult); + end; + + sqlresultoptionty = (sro_utf8); + sqlresultoptionsty = set of sqlresultoptionty; + + sqlresulteventty = procedure(const sender: tsqlresult) of object; + + tsqlresult = class(tcursorsqlstatement,isqlpropertyeditor, + isqlclient,itransactionclient) + private +// fsql: tsqlstringlist; + fopenafterread: boolean; + factive: boolean; +// fdatabase: tcustomsqlconnection; +// ftransaction: tsqltransaction; +// fcursor: tsqlcursor; +// fparams: tmseparams; + ffielddefs: tsqlresultfielddefs; + fdatacols: tdbcols; + feof: boolean; + fbof: boolean; +// foptions: sqlresultoptionsty; + fbeforeopen: tmsesqlscript; + fafteropen: tmsesqlscript; + fonbeforeopen: sqlresulteventty; + fonafteropen: sqlresulteventty; + procedure setsql(const avalue: tsqlstringlist); + procedure setdatabase1(const avalue: tcustomsqlconnection); + function getsqltransaction: tsqltransaction; + procedure setsqltransaction(const avalue: tsqltransaction); + procedure setparams(const avalue: tmseparams); + procedure setbeforeopen(const avalue: tmsesqlscript); + procedure setafteropen(const avalue: tmsesqlscript); + procedure changed; + procedure setfielddefs(const avalue: tsqlresultfielddefs); + function getcols(const index: int32): tdbcol; + procedure setcols(const index: int32; const avalue: tdbcol); + protected + procedure dosqlchange(const sender : tobject); override; + function getactive: boolean; override; + procedure setactive(avalue: boolean); override; + procedure loaded; override; + procedure freefldbuffers; +// function isprepared: boolean; + procedure doclear(const isclose: boolean); + procedure checkautocommit; override; +// procedure execute; + //itransactionclient + procedure settransaction(const avalue: tmdbtransaction); + procedure settransactionwrite(const avalue: tmdbtransaction); + procedure savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); + //isqlclient + procedure setdatabase(const avalue: tmdatabase); + function getname: ansistring; + function gettransaction: tmdbtransaction; + function getrecno: integer; + procedure setrecno(value: integer); + procedure disablecontrols; + procedure enablecontrols; + function moveby(distance: longint): longint; + function getsqltransactionwrite: tsqltransaction; + procedure setsqltransactionwrite(const avalue: tsqltransaction); + procedure checkbrowsemode; + procedure refreshtransaction; + procedure internalloaddatalists(const acols: integerarty; + const datalists: array of tdatalist); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; +// function isutf8: boolean; + procedure prepare; override; + procedure unprepare; override; + procedure open(const aparams: array of variant); + procedure open(); + procedure close; + procedure clear; //frees buffers, does not unprepare + procedure refresh(const aparams: array of variant); + procedure refresh; + procedure next; + function countrest(): int32; //including current record + function rowsaffected: integer; //-1 if not supported + function rowsreturned: integer; //-1 if not supported +// procedure asvariant(out avalue: variant); overload; //internal compiler error + function asvariant(const aclose: boolean = false): variant; + //value of first field of first row, + //empty variant returned for null fields + function asvariantar(const aclose: boolean = false): variantarty; + //first row, empty variant returned for null fields + function asvariantarar(const aclose: boolean = false): variantararty; + //whole resultset, empty variant returned for null fields + procedure loaddatalists(const datalists: array of tdatalist); + property datacols: tdbcols read fdatacols; + property cols[const index: int32]: tdbcol read getcols write setcols; default; + property bof: boolean read fbof; + property eof: boolean read feof; + published +// property params : tmseparams read fparams write setparams; //before sql property + +// property sql: tsqlstringlist read fsql write setsql; + property beforeopen: tmsesqlscript read fbeforeopen write setbeforeopen; + property afteropen: tmsesqlscript read fafteropen write setafteropen; +// property database: tcustomsqlconnection read fdatabase write setdatabase1; +// property transaction: tsqltransaction read getsqltransaction +// write setsqltransaction; + property active: boolean read getactive write setactive default false; +// property options: sqlresultoptionsty read foptions write foptions default []; + property fielddefs: tsqlresultfielddefs read ffielddefs write setfielddefs; + property onbeforeopen: sqlresulteventty read fonbeforeopen write fonbeforeopen; + property onafteropen: sqlresulteventty read fonafteropen write fonafteropen; + + property params; + property sql; + property database; + property transaction; + property options; + property statementtype default stselect; + property onbeforeexecute; + property onafterexecute; + property onerror; + end; + + idbcolinfo = interface(inullinterface)[miid_idbcolinfo] + function getsqlresult(const aindex: integer): tsqlresult; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + end; + + getsqlresultfuncty = function(const aindex: integer): tsqlresult of object; + + tdbcolnamearrayprop = class(tstringarrayprop,idbcolinfo) + private + ffieldtypes: fieldtypesty; + fgetsqlresult: getsqlresultfuncty; + protected + //idbcolinfo + function getsqlresult(const aindex: integer): tsqlresult; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + public + constructor create(const afieldtypes: fieldtypesty; + const agetsqlresult: getsqlresultfuncty); + property fieldtypes: fieldtypesty read ffieldtypes write ffieldtypes; + end; + + lbsqoptionty = (olbsq_closesqlresult); + lbsqoptionsty = set of lbsqoptionty; + + tsqllookupbuffer = class(tdatalookupbuffer) + private + fsource: tsqlresult; + ftextcols: tdbcolnamearrayprop; + fintegercols: tdbcolnamearrayprop; + fint64cols: tdbcolnamearrayprop; + ffloatcols: tdbcolnamearrayprop; + foptionsdb: lbsqoptionsty; + procedure setsource(const avalue: tsqlresult); + function getsqlresult(const aindex: integer): tsqlresult; + procedure settextcols(const avalue: tdbcolnamearrayprop); + procedure setintegercols(const avalue: tdbcolnamearrayprop); + procedure setint64cols(const avalue: tdbcolnamearrayprop); + procedure setfloatcols(const avalue: tdbcolnamearrayprop); + protected + function getfieldcounttext: integer; override; + function getfieldcountinteger: integer; override; + function getfieldcountint64: integer; override; + function getfieldcountfloat: integer; override; + procedure setfieldcounttext(const avalue: integer); override; + procedure setfieldcountinteger(const avalue: integer); override; + procedure setfieldcountint64(const avalue: integer); override; + procedure setfieldcountfloat(const avalue: integer); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure doloadbuffer; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function fieldnamestext: stringarty; override; + function fieldnamesfloat: stringarty; override; + function fieldnamesinteger: stringarty; override; + function fieldnamesint64: stringarty; override; + procedure clearbuffer; override; + published + property source: tsqlresult read fsource write setsource; + property textcols: tdbcolnamearrayprop read ftextcols write settextcols; + property integercols: tdbcolnamearrayprop read fintegercols write setintegercols; + property int64cols: tdbcolnamearrayprop read fint64cols write setint64cols; + property floatcols: tdbcolnamearrayprop read ffloatcols write setfloatcols; + property optionsdb: lbsqoptionsty read foptionsdb write foptionsdb default []; + end; + +//empty variant returned for null fields +procedure getsqlresult(out avalue: variant; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //first field of first row +procedure getsqlresult(out avalue: variantarty; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //first row +procedure getsqlresult(out avalue: variantararty; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //whole resultset +procedure getsqlresult(const avalues: array of tdatalist; + const atransaction: tsqltransaction; const asql: msestring; + const aparams: array of variant); overload; + //whole resultset +function getsqlresultvar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variant; +function getsqlresultvarar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variantarty; +function getsqlresultvararar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variantararty; + +implementation +uses + sysutils,{$ifdef FPC}dbconst{$else}dbconst_del,classes_del{$endif},rtlconsts, + mseapplication,variants,mseformatstr,msefloattostr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +const + msedbcoltypeclasses: array[fieldclasstypety] of dbcolclassty = +// ft_unknown,ft_string, ft_guid, ft_numeric, + (tdbcol, tstringdbcol,tguiddbcol,tlongintdbcol, +// ft_longint, ft_largeint, ft_smallint, + tlongintdbcol,tlargeintdbcol,tsmallintdbcol, +// ft_word, ft_autoinc, ft_float, ft_currency, ft_boolean, + tworddbcol,tlongintdbcol,tfloatdbcol,tcurrencydbcol,tbooleandbcol, +// ft_datetime, ft_date, ft_time, + tdatetimedbcol,tdatetimedbcol,tdatetimedbcol, +// ft_binary,ft_bytes, ft_varbytes, + tdbcol, tstringdbcol, tstringdbcol, +// ft_bcd, ft_blob, ft_memo, ft_graphic, ft_variant); + tcurrencydbcol,tblobdbcol,tmemodbcol,tblobdbcol,tvariantdbcol); + SBoolean = 'Boolean'; + SDateTime = 'TDateTime'; + SFloat = 'Float'; + SInteger = 'Integer'; + SLargeInt = 'LargeInt'; + SVariant = 'Variant'; + SString = 'String'; +type + tdatalist1 = class(tdatalist); +// tcursorsqlstatement1 = class(tcursorsqlstatement); + +function dogetsqlresult(const atransaction: tsqltransaction; const asql: msestring; + const aparams: array of variant): tsqlresult; +var + int1: integer; +begin + result:= tsqlresult.create(nil); + try + result.database:= atransaction.database; + result.transaction:= atransaction; + result.sql.text:= asql; + result.prepare; + for int1:= 0 to high(aparams) do begin + result.params[int1].value:= aparams[int1]; + end; + except + result.free; + raise + end; +end; + +procedure getsqlresult(out avalue: variant; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //first field of first row +var + sqlresult: tsqlresult; +begin + sqlresult:= dogetsqlresult(atransaction,asql,aparams); + try +// sqlresult.asvariant(avalue); //internal error 2006122804 + avalue:= sqlresult.asvariant; + finally + sqlresult.free; + end; +end; + +procedure getsqlresult(out avalue: variantarty; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //first row +var + sqlresult: tsqlresult; +begin + sqlresult:= dogetsqlresult(atransaction,asql,aparams); + try + avalue:= sqlresult.asvariantar; + finally + sqlresult.free; + end; +end; + +procedure getsqlresult(out avalue: variantararty; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //whole resultset +var + sqlresult: tsqlresult; +begin + sqlresult:= dogetsqlresult(atransaction,asql,aparams); + try + avalue:= sqlresult.asvariantarar; + finally + sqlresult.free; + end; +end; + +procedure getsqlresult(const avalues: array of tdatalist; + const atransaction: tsqltransaction; const asql: msestring; + const aparams: array of variant); overload; + //whole resultset +var + sqlresult: tsqlresult; +begin + sqlresult:= dogetsqlresult(atransaction,asql,aparams); + try + sqlresult.loaddatalists(avalues); + finally + sqlresult.free; + end; +end; + +function getsqlresultvar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variant; +begin + getsqlresult(result,atransaction,asql,aparams); +end; + +function getsqlresultvarar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variantarty; +begin + getsqlresult(result,atransaction,asql,aparams); +end; + +function getsqlresultvararar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variantararty; +begin + getsqlresult(result,atransaction,asql,aparams); +end; + + +{ tdbcol } + +constructor tdbcol.create(const asqlresult: tsqlresult; + const acursor: tsqlcursor; const afielddef: tfielddef); +begin + fsqlresult:= asqlresult; + fcursor:= acursor; + ffieldname:= afielddef.name; + fuppername:= uppercase(ffieldname); + fdatatype:= afielddef.datatype; + ffieldnum:= afielddef.fieldno-1; + fdatasize:= afielddef.size; //used for stringcol + futf8:= asqlresult.isutf8; + inherited create; +end; + +function tdbcol.accesserror(const typename: string): edatabaseerror; +begin + result:= edatabaseerror.createfmt(sinvalidtypeconversion,[typename,ffieldname]); +end; + +function tdbcol.getvariantvar: variant; +begin + raise accesserror('variant'); + result:= 0; //compiler warning; +end; + +function tdbcol.getasvariant: variant; +begin + if isnull then begin + result:= null;//unassigned; + end + else begin + result:= getvariantvar; + end; +end; + +function tdbcol.getasboolean: boolean; +begin + result:= getasinteger <> 0; +end; + +function tdbcol.getascurrency: currency; +begin + result:= getasfloat; +end; + +function tdbcol.getaslargeint: largeint; +begin + result:= getasinteger; +end; + +function tdbcol.getasdatetime: tdatetime; +begin + raise accesserror(sdatetime); + result:= 0; //compiler warning; +end; + +function tdbcol.getasfloat: double; +begin + result:= getaslargeint; +end; + +function tdbcol.getasinteger: longint; +begin + raise accesserror(sinteger); + result:= 0; //compiler warning; +end; + +function tdbcol.getasstring: string; +begin + raise accesserror(sstring); + result:= ''; //compiler warning; +end; + +function tdbcol.getasmsestring: msestring; +var + str1: ansistring; +begin + str1:= getasstring; + if futf8 then begin + result:= utf8tostringansi(str1); + end + else begin + result:= msestring(str1); + end; +end; + +function tdbcol.getassql: msestring; +begin + raise accesserror('SQL'); + result:= ''; //compiler warning; +end; + +function tdbcol.getasguid: tguid; +begin + raise accesserror('Guid'); + result:= guid_null; //compiler warning; +end; + +function tdbcol.getassql1: msestring; +begin + if isnull then begin + result:= 'NULL'; + end + else begin + result:= getassql; + end; +end; + +function tdbcol.getisnull: boolean; +var + int1: integer; +begin + int1:= 0; + result:= not fsqlresult.active or fsqlresult.eof or + not fsqlresult.database.loadfield(fsqlresult.fcursor, + fdatatype,ffieldnum,nil,int1,false); +end; + +function tdbcol.loadfield(const buffer: pointer; var bufsize: integer): boolean; +begin + result:= fsqlresult.active; + if result then begin + result:= fsqlresult.fdatabase.loadfield(fsqlresult.fcursor, + fdatatype,ffieldnum,buffer,bufsize,futf8); + end; +end; + +function tdbcol.loadfield(const buffer: pointer): boolean; +var + int1: integer; +begin + int1:= 0; + result:= fsqlresult.active; + if result then begin + result:= fsqlresult.fdatabase.loadfield(fsqlresult.fcursor, + fdatatype,ffieldnum,buffer,int1,futf8); + end; +end; + +function tdbcol.getasid: int64; +begin + if isnull then begin + result:= -1; + end + else begin + result:= getaslargeint; + end; +end; + +function tdbcol.getasdatetime1: tdatetime; +begin + if isnull then begin + result:= emptydatetime; + end + else begin + result:= getasdatetime; + end; +end; + +function tdbcol.getasfloat1: double; +begin + if isnull then begin + result:= emptyreal; + end + else begin + result:= getasfloat; + end; +end; + +function tdbcol.getasstring1: string; +begin + if isnull then begin + result:= ''; + end + else begin + result:= getasstring; + end; +end; + +function tdbcol.getasmsestring1: msestring; +begin + if isnull then begin + result:= ''; + end + else begin + result:= getasmsestring; + end; +end; + +{ tlongintdbcol } + +function tlongintdbcol.getasinteger: integer; +begin + if not loadfield(@result) then begin + result:= 0; + end; +end; + +{ tlargeintdbcol } + +function tlargeintdbcol.getaslargeint: largeint; +begin + if not loadfield(@result) then begin + result:= 0; + end; +end; + +function tlargeintdbcol.getasinteger: integer; +begin + result:= getaslargeint; +end; + +function tlargeintdbcol.getvariantvar: variant; +begin + result:= aslargeint; +end; + +function tlargeintdbcol.getassql: msestring; +begin + result:= encodesqllargeint(aslargeint); +end; + +function tlargeintdbcol.getasstring: string; +begin + result:= inttostr(aslargeint); +end; + +function tlargeintdbcol.getasmsestring: msestring; +begin + result:= inttostrmse(aslargeint); +end; + +{ tsmallintdbcol } + +function tsmallintdbcol.getasinteger: integer; +var + buf: smallint; +begin + if not loadfield(@buf) then begin + result:= 0; + end + else begin + result:= buf; + end; +end; + +{ tworddbcol } + +function tworddbcol.getasinteger: integer; +var + buf: word; +begin + if not loadfield(@buf) then begin + result:= 0; + end + else begin + result:= buf; + end; +end; + +{ tfloatdbcol } + +function tfloatdbcol.getasfloat: double; +begin + if not loadfield(@result) then begin + result:= emptyreal; + end; +end; + +function tfloatdbcol.getasfloat1: double; +begin + result:= getasfloat; +end; + +function tfloatdbcol.getascurrency: currency; +var + do1: double; +begin + if not loadfield(@do1) then begin + result:= 0; + end + else begin + result:= do1; + end; +end; + +function tfloatdbcol.getvariantvar: variant; +begin + result:= asfloat; +end; + +function tfloatdbcol.getassql: msestring; +begin + result:= encodesqlfloat(asfloat); +end; + +function tfloatdbcol.getasstring: string; +begin + result:= ansistring(getasmsestring); +end; + +function tfloatdbcol.getasmsestring: msestring; +begin + result:= doubletostring(asfloat,0); +end; + +{ tcurrencydbcol } + +function tcurrencydbcol.getascurrency: currency; +begin + if not loadfield(@result) then begin + result:= 0; + end; +end; + +function tcurrencydbcol.getasfloat: double; +begin + result:= getascurrency; +end; + +function tcurrencydbcol.getvariantvar: variant; +begin + result:= ascurrency; +end; + +function tcurrencydbcol.getassql: msestring; +begin + result:= encodesqlcurrency(ascurrency); +end; + +function tcurrencydbcol.getasstring: string; +begin + result:= currtostr(ascurrency); +end; + +{ tbooleandbcol } + +function tbooleandbcol.getasboolean: boolean; +var + buf: wordbool; +begin + if not loadfield(@buf) then begin + result:= false; + end + else begin + result:= buf; + end; +end; + +function tbooleandbcol.getasinteger: integer; +begin + if getasboolean() then begin + result:= 1; + end + else begin + result:= 0; + end; +end; + +function tbooleandbcol.getvariantvar: variant; +begin + result:= asboolean; +end; + +function tbooleandbcol.getassql: msestring; +begin + result:= encodesqlboolean(asboolean); +end; + +function tbooleandbcol.getasstring: string; +begin + if getasboolean then begin + result:= '1'; + end + else begin + result:= '0'; + end; +end; + +{ tdatetimedbcol } + +function tdatetimedbcol.getasdatetime: tdatetime; +begin + if not loadfield(@result) then begin + result:= emptydatetime; + end +end; + +function tdatetimedbcol.getvariantvar: variant; +begin + result:= asdatetime; +end; + +function tdatetimedbcol.getassql: msestring; +begin + result:= encodesqldatetime(asdatetime); +end; + +function tdatetimedbcol.getasdatetime1: tdatetime; +begin + result:= getasdatetime; +end; + +{ tstringdbcol } + +function tstringdbcol.getasstring: ansistring; +var + int1: integer; +begin + if fdatatype in widecharfields then begin + result:= ansistring(getasmsestring); + end + else begin + int1:= fdatasize; + if not (fdatatype in [ftbytes,ftvarbytes]) then begin + int1:= int1*4+4; //room for multibyte encodings + end; + setlength(result,int1); + if not loadfield(pointer(result),int1) then begin + result:= ''; + end + else begin + if int1 < 0 then begin //too small + int1:= -int1; + setlength(result,int1); + loadfield(pointer(result),int1); + end; + setlength(result,int1); + if fdatatype = ftvarbytes then begin + int1:= int1 - sizeof(word); + move((pchar(pointer(result))+sizeof(word))^,(pchar(pointer(result)))^,int1); + setlength(result,int1); + end; + end; + end; +end; + +function tstringdbcol.getasmsestring: msestring; +var + int1: integer; +begin + if fdatatype in widecharfields then begin + int1:= fdatasize*2+4; //room for multibyte encodings + setlength(result,int1); + if not loadfield(pointer(result),int1) then begin + result:= ''; + end + else begin + if int1 < 0 then begin //too small + int1:= -int1; + setlength(result,(int1+1) div 2); + loadfield(pointer(result),int1); + end; + setlength(result,int1 div 2); + end; + end + else begin + result:= inherited getasmsestring; + end; +end; + +function tstringdbcol.getvariantvar: variant; +begin + result:= asmsestring; +end; + +function tstringdbcol.getassql: msestring; +begin + result:= encodesqlstring(asmsestring); +end; + +function tstringdbcol.getasstring1: ansistring; +begin + result:= getasstring; +end; + +function tstringdbcol.getasmsestring1: msestring; +begin + result:= getasmsestring; +end; + +{ tblobdbcol } + +function tblobdbcol.getasstring: ansistring; +begin + with fsqlresult do begin + if active then begin + result:= fdatabase.fetchblob(fcursor,ffieldnum); + end + else begin + result:= ''; + end; + end; +end; + +function tblobdbcol.getvariantvar: variant; +begin + result:= asstring; +end; + +function tblobdbcol.getassql: msestring; +begin + result:= encodesqlblob(asstring); +end; + +{ tguiddbcol } + +function tguiddbcol.getvariantvar: variant; +begin + result:= asstring; +end; + +function tguiddbcol.getassql: msestring; +begin + result:= encodesqlstring(msestring(asstring)); +end; + +function tguiddbcol.getasstring: string; +var + id1: tguid; +begin + if not loadfield(@id1) then begin + result:= ''; + end + else begin + result:= dbguidtostring(id1); + end; +end; + +function tguiddbcol.getasguid: tguid; +begin + if not loadfield(@result) then begin + result:= guid_null; + end; +end; + +{ tnumericdbcol } + +function tnumericdbcol.getvariantvar: variant; +begin + result:= asinteger; +end; + +function tnumericdbcol.getassql: msestring; +begin + result:= encodesqlinteger(asinteger); +end; + +function tnumericdbcol.getasstring: string; +begin + result:= inttostr(asinteger); +end; + +function tnumericdbcol.getasmsestring: msestring; +begin + result:= inttostrmse(asinteger); +end; + +{ tmemodbcol } + +function tmemodbcol.getvariantvar: variant; +begin + result:= asmsestring; +end; + +function tmemodbcol.getassql: msestring; +begin + result:= encodesqlstring(asmsestring); +end; + +{ tvariantdbcol } + +function tvariantdbcol.getvariantvar: variant; +begin + if not loadfield(@result) then begin + result:= null; + end; +end; + +{ tdbcols } + +constructor tdbcols.create(const agetname: getnamefuncty); +begin + fgetname:= agetname; + inherited create(tdbcol); +end; + +function tdbcols.getitems(const index: integer): tdbcol; +begin + result:= tdbcol (inherited getitems(index)); +end; + +procedure tdbcols.initfields(const asqlresult: tsqlresult; + const acursor: tsqlcursor; const afielddefs: tfielddefs); +var + int1: integer; + fdef1: tfielddef; +begin + for int1:= 0 to afielddefs.count - 1 do begin + fdef1:= afielddefs[int1]; + add(msedbcoltypeclasses[tfieldtypetotypety[fdef1.datatype]]. + create(asqlresult,acursor,fdef1)); + end; +end; + +function tdbcols.findcol(const aname: ansistring): tdbcol; +var + str1: ansistring; + int1: integer; +begin + str1:= uppercase(aname); + for int1:= 0 to high(fitems) do begin + result:= tdbcol(fitems[int1]); + if result.fuppername = str1 then begin + exit; + end; + end; + result:= nil; +end; + +function tdbcols.findcolindex(const aname: ansistring): integer; +var + str1: ansistring; + int1: integer; +begin + result:= -1; + str1:= uppercase(aname); + for int1:= 0 to high(fitems) do begin + with tdbcol(fitems[int1]) do begin + if fuppername = str1 then begin + result:= int1; + exit; + end; + end; + end; +end; + +function tdbcols.colbyname(const aname: ansistring): tdbcol; +begin + result:= findcol(aname); + if result = nil then begin + raise edatabaseerror.create(fgetname()+': col "'+aname+'" not found.'); + end; +end; + +function tdbcols.colsbyname(const anames: array of ansistring): dbcolarty; +var + int1: integer; +begin + setlength(result,high(anames)+1); + for int1:= 0 to high(result) do begin + result[int1]:= colbyname(anames[int1]); + end; +end; + +function tdbcols.colsindexbyname(const anames: array of ansistring): integerarty; +var + int1: integer; +begin + setlength(result,high(anames)+1); + for int1:= 0 to high(result) do begin + result[int1]:= findcolindex(anames[int1]); + if result[int1] < 0 then begin + raise edatabaseerror.create(fgetname()+': col "'+anames[int1]+'" not found.'); + end; + end; +end; + +{ tsqlresult } + +constructor tsqlresult.create(aowner: tcomponent); +begin + fbof:= true; + feof:= true; +// fparams:= tmseparams.create(self); + fdatacols:= tdbcols.create({$ifdef FPC}@{$endif}getname); + ffielddefs:= tsqlresultfielddefs.create(nil); +// fsql:= tsqlstringlist.create; +// fsql.onchange:= @onchangesql; + inherited; + statementtype:= stselect; +end; + +destructor tsqlresult.destroy; +begin + active:= false; + database:= nil; + transaction:= nil; + inherited; +// fsql.free; +// fparams.free; + ffielddefs.free; + fdatacols.free; +end; + +procedure tsqlresult.setsql(const avalue: tsqlstringlist); +begin + fsql.assign(avalue); +end; + +function tsqlresult.getactive: boolean; +begin + result:= factive; +end; + +procedure tsqlresult.setactive(avalue: boolean); +begin + if csreading in componentstate then begin + fopenafterread:= avalue; + end + else begin + if factive <> avalue then begin + if avalue then begin + open; + end + else begin + fopenafterread:= false; + close; + end; + end + else begin + if not avalue then begin + inherited setactive(false); //free cursor for exec call + end; + end; + end; +end; +{ +function tsqlresult.isutf8: boolean; +begin + result:= (sro_utf8 in foptions); + if fdatabase <> nil then begin + fdatabase.updateutf8(result); + end; +end; +} +procedure tsqlresult.setdatabase1(const avalue: tcustomsqlconnection); +begin + setdatabase(avalue); +end; + +procedure tsqlresult.setdatabase(const avalue: tmdatabase); +begin + dosetsqldatabase(isqlclient(self),avalue,fcursor,tmdatabase(fdatabase)); +end; + +function tsqlresult.getname: ansistring; +begin + result:= name; +end; + +function tsqlresult.getsqltransaction: tsqltransaction; +begin + result:= ftransaction; +end; + +procedure tsqlresult.setsqltransaction(const avalue: tsqltransaction); +begin + settransaction(avalue); +end; + +procedure tsqlresult.settransaction(const avalue: tmdbtransaction); +begin + dosettransaction(itransactionclient(self),avalue, + tmdbtransaction(ftransaction),false); +end; + +procedure tsqlresult.settransactionwrite(const avalue: tmdbtransaction); +begin + //dummy +end; + +procedure tsqlresult.open(const aparams: array of variant); +begin + if canevent(tmethod(fonbeforeopen)) then begin + fonbeforeopen(self); + end; + if fbeforeopen <> nil then begin + fbeforeopen.execute; + end; +// prepare; + execute(aparams); +// ffielddefs.clear; + fdatabase.addfielddefs(fcursor,ffielddefs); + fdatacols.initfields(self,fcursor,ffielddefs); +// ffielddefs.bindconnectors; + factive:= true; + feof:= false; + next; + fbof:= true; + sendchangeevent(oe_bindfields); + if fafteropen <> nil then begin + fafteropen.execute; + end; + changed; + inherited checkautocommit; + if canevent(tmethod(fonafteropen)) then begin + fonafteropen(self); + end; +end; + +procedure tsqlresult.open; +begin + open([]); +end; + +procedure tsqlresult.doclear(const isclose: boolean); +begin + if not isclose and (fcursor <> nil) then begin + fcursor.close; + end; + feof:= true; + fbof:= true; + //fcols.clear; +end; + +procedure tsqlresult.clear; +begin + doclear(false); + changed; +end; + +procedure tsqlresult.close; +begin + factive:= false; +// feof:= true; +// fbof:= true; + doclear(true); + sendchangeevent(oe_releasefields); + freefldbuffers; + inherited setactive(false); + fdatacols.clear; + changed; +end; + +procedure tsqlresult.freefldbuffers; +begin + if fcursor <> nil then begin + tcustomsqlconnection(database).FreeFldBuffers(FCursor); + end; +end; + +procedure tsqlresult.unprepare; +begin + CheckInactive(active,name); + inherited; +{ + if IsPrepared then begin + with tcustomsqlconnection(Database) do begin + UnPrepareStatement(FCursor); + end; + end; +} +end; + +{ +procedure tsqlresult.prepare; +var + db: tcustomsqlconnection; + trans: tsqltransaction; + str1: msestring; + bo1: boolean; +begin + if not isprepared then begin + checkdatabase(name,fdatabase); + bo1:= sro_utf8 in foptions; + fdatabase.updateutf8(bo1); + if bo1 then begin + foptions:= foptions + [sro_utf8]; + end + else begin + foptions:= foptions - [sro_utf8]; + end; + checktransaction(name,ftransaction); + str1:= trimright(fsql.text); + if str1 = '' then begin + raise edatabaseerror.create(name+': Empty query.'); + end; + db:= tcustomsqlconnection(fdatabase); + trans:= tsqltransaction(ftransaction); + db.connected:= true; + trans.active:= true; + if not assigned(fcursor) then begin + fcursor:= db.allocatecursorhandle(nil,name); + end; + fcursor.ftrans:= trans.handle; + fcursor.fstatementtype:= stselect; + + Db.PrepareStatement(Fcursor,trans,str1,FParams); + FCursor.FInitFieldDef:= True; + end; +end; +} + +procedure tsqlresult.prepare; +begin + inherited; + fcursor.finitfielddef:= true; +end; + +procedure tsqlresult.setparams(const avalue: tmseparams); +begin + fparams.assign(avalue); +end; +{ +procedure tsqlresult.execute; +begin + doexecute(fparams,ftransaction,fcursor,fdatabase,isutf8); +end; +} +procedure tsqlresult.loaded; +begin + inherited; + try + active:= fopenafterread; + except + if csdesigning in componentstate then begin + application.handleexception(self); + end + else begin + raise; + end; + end; +end; + +procedure tsqlresult.dosqlchange(const sender: tobject); +var + bo1: boolean; +begin + bo1:= (csdesigning in componentstate) and active; + if bo1 then begin + active:= false; + end; + inherited; +// unprepare; +// fparams.parsesql(fsql.text,true); + if bo1 then begin + active:= true; + end; +end; + +procedure tsqlresult.next; +begin + checkactive(active,name); + fbof:= false; + if feof then begin + raise edatabaseerror.create(name+': EOF.'); + end; + feof:= not fdatabase.fetch(fcursor); +end; + +function tsqlresult.countrest(): int32; +begin + result:= 0; + while not eof do begin + inc(result); + next(); + end; +end; + +procedure tsqlresult.refresh(const aparams: array of variant); +begin + if not active then begin + open(aparams); +// active:= true; + end + else begin + doclear(false); + feof:= false; + execute(aparams); + next; + fbof:= true; + changed(); + end; +end; + +procedure tsqlresult.refresh; +begin + refresh([]); +end; + +procedure tsqlresult.refreshtransaction; +begin + refresh; +end; + +procedure tsqlresult.setbeforeopen(const avalue: tmsesqlscript); +begin + setlinkedvar(avalue,tmsecomponent(fbeforeopen)); +end; + +procedure tsqlresult.setafteropen(const avalue: tmsesqlscript); +begin + setlinkedvar(avalue,tmsecomponent(fafteropen)); +end; + +procedure tsqlresult.changed; +begin + sendchangeevent; +end; + +procedure tsqlresult.setfielddefs(const avalue: tsqlresultfielddefs); +begin + ffielddefs.assign(avalue); +end; + +function tsqlresult.getcols(const index: int32): tdbcol; +begin + result:= fdatacols[index]; +end; + +procedure tsqlresult.setcols(const index: int32; const avalue: tdbcol); +begin + fdatacols[index].assign(avalue); +end; + +function tsqlresult.getsqltransactionwrite: tsqltransaction; +begin + result:= nil; +end; + +procedure tsqlresult.setsqltransactionwrite(const avalue: tsqltransaction); +begin + //dummy +end; +{ +function tsqlresult.asvariant: variant; +var + int1,int2: integer; + var1: variant; +begin + refresh; + if eof or (cols.count = 0) then begin + result:= null; + end + else begin + var1:= vararraycreate([0,cols.count-1],varvariant); + for int1:= 0 to cols.count - 1 do begin + var1[int1]:= cols[int1].asvariant; + end; + next; + if eof then begin + result:= var1; + end + else begin + result:= vararraycreate([0,cols.count-1,0,1],varvariant); + for int1:= 0 to cols.count - 1 do begin + result[int1,0]:= var1[int1]; + end; + int2:= 1; + while true do begin + for int1:= 0 to cols.count - 1 do begin + result[int1,int2]:= cols[int1].asvariant; + end; + next; + if eof then begin + break; + end; + inc(int2); + vararrayredim(result,int2); + end; + end; + end; +end; +} + +function tsqlresult.asvariant(const aclose: boolean = false): variant; +begin + refresh; + if eof or (fdatacols.count = 0) then begin + result:= null;//unassigned; + end + else begin + result:= fdatacols[0].asvariant; + end; + if aclose then begin + active:= false; + end + else begin + while not eof do begin + next; //eat the rest; + end; + end; +end; + +function tsqlresult.asvariantar(const aclose: boolean = false): variantarty; +var + int1: integer; +begin + refresh; + if eof or (fdatacols.count = 0) then begin + result:= null;//unassigned; + end + else begin + setlength(result,fdatacols.count); + for int1:= 0 to high(result) do begin + result[int1]:= fdatacols[int1].asvariant; + end; + end; + if aclose then begin + active:= false; + end + else begin + while not eof do begin + next; //eat the rest; + end; + end; +end; + +function tsqlresult.asvariantarar(const aclose: boolean = false): variantararty; +var + int1,int2: integer; +begin + refresh; + if eof or (fdatacols.count = 0) then begin + result:= nil; + while not eof do begin + next; //eat the rest; + end; + end + else begin + setlength(result,256); + int2:= 0; + while not eof do begin + if int2 > high(result) then begin + setlength(result,high(result)*2); + end; + setlength(result[int2],fdatacols.count); + for int1:= 0 to fdatacols.count - 1 do begin + result[int2][int1]:= tdbcol(fdatacols.fitems[int1]).asvariant; + end; + inc(int2); + next; + end; + setlength(result,int2); + end; + if aclose then begin + active:= false; + end; +end; + +type + datagetprocty = procedure(const source: tdbcol; const dest: pointer); + datagetprocarty = array of datagetprocty; + +procedure getintegerdata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pinteger(dest)^:= source.asinteger; + end; +end; + +procedure getint64data(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pint64(dest)^:= source.aslargeint; + end; +end; + +procedure getcurrencydata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pcurrency(dest)^:= source.aslargeint; + end; +end; + +procedure getrealdata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + preal(dest)^:= source.asfloat; + end; +end; + +procedure getdatetimedata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pdatetime(dest)^:= source.asdatetime; + end; +end; + +procedure getansistringdata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pansistring(dest)^:= source.asstring; + end; +end; + +procedure getmsestringdata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pmsestring(dest)^:= source.asmsestring; + end; +end; + +procedure tsqlresult.internalloaddatalists(const acols: integerarty; + const datalists: array of tdatalist); + //todo: optimize, use rowsreturned and internal list grow +var + int1,int2,int3: integer; + proc1: datagetprocarty; + col1: dbcolarty; +begin +// refresh; + int2:= length(acols); + setlength(col1,int2); + setlength(proc1,int2); + dec(int2); + for int1:= 0 to int2 do begin + col1[int1]:= tdbcol(fdatacols.fitems[acols[int1]]); + if datalists[int1] <> nil then begin + case datalists[int1].datatype of + dl_integer: begin + proc1[int1]:= @getintegerdata; + end; + dl_int64: begin + proc1[int1]:= @getint64data; + end; + dl_currency: begin + proc1[int1]:= @getcurrencydata; + end; + dl_real: begin + proc1[int1]:= @getrealdata; + end; + dl_datetime: begin + proc1[int1]:= @getdatetimedata; + end; + dl_ansistring: begin + proc1[int1]:= @getansistringdata; + end; + dl_msestring: begin + proc1[int1]:= @getmsestringdata; + end; + else begin + raise exception.create(name+ + ' tsqlresult.loaddatalists(): Invalid datalist.'); + end; + end; + end; + end; + for int1:= 0 to int2 do begin + if datalists[int1] <> nil then begin + with datalists[int1] do begin + beginupdate; + count:= 0; + end; + end; + end; + try + int3:= 0; + while not eof do begin + for int1:= 0 to int2 do begin + if datalists[int1] <> nil then begin + with datalists[int1] do begin + count:= int3 + 1; + proc1[int1](col1[int1],getitempo(int3)); + end; + end; + end; + inc(int3); + next; + end; + finally + for int1:= 0 to high(datalists) do begin + if datalists[int1] <> nil then begin + with datalists[int1] do begin + try + endupdate; + except + application.handleexception; + end; + end; + end; + end; + end; +end; + +procedure tsqlresult.loaddatalists(const datalists: array of tdatalist); +var + int1: integer; + ar1: integerarty; +begin + refresh(); + if length(datalists) > fdatacols.count then begin + componentexception(self,'Too many datalists.'); + end; + setlength(ar1,length(datalists)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= int1; + end; + internalloaddatalists(ar1,datalists); +end; + +function tsqlresult.rowsreturned: integer; +begin + if active then begin + result:= fcursor.frowsreturned; + end + else begin + result:= -1 + end; +end; + +function tsqlresult.rowsaffected: integer; +begin + if active then begin + result:= fcursor.frowsaffected; + end + else begin + result:= -1 + end; +end; + +function tsqlresult.gettransaction: tmdbtransaction; +begin + result:= ftransaction; +end; + +function tsqlresult.getrecno: integer; +begin + result:= -1; +end; + +procedure tsqlresult.setrecno(value: integer); +begin + //dummy +end; + +procedure tsqlresult.disablecontrols; +begin + //dummy +end; + +procedure tsqlresult.enablecontrols; +begin + //dummy +end; + +function tsqlresult.moveby(distance: longint): longint; +begin + result:= 0; +end; + +procedure tsqlresult.checkbrowsemode; +begin + //dummy +end; + +procedure tsqlresult.savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); +begin + //dummy +end; + +procedure tsqlresult.checkautocommit; +begin + //dummy +end; + +{ tdbcolnamearrayprop } + +constructor tdbcolnamearrayprop.create(const afieldtypes: fieldtypesty; + const agetsqlresult: getsqlresultfuncty); +begin + ffieldtypes:= afieldtypes; + fgetsqlresult:= agetsqlresult; + inherited create; +end; + +function tdbcolnamearrayprop.getsqlresult(const aindex: integer): tsqlresult; +begin + result:= fgetsqlresult(aindex); +end; + +procedure tdbcolnamearrayprop.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + setlength(afieldtypes,1); + afieldtypes[0]:= ffieldtypes; +end; + +{ tsqllookupbuffer } + +constructor tsqllookupbuffer.create(aowner: tcomponent); +begin + fintegercols:= tdbcolnamearrayprop.create( + msedb.integerfields+[ftboolean], + {$ifdef FPC}@{$endif}getsqlresult); + fint64cols:= tdbcolnamearrayprop.create([ftlargeint], + {$ifdef FPC}@{$endif}getsqlresult); + ftextcols:= tdbcolnamearrayprop.create( + msedb.textfields+[ftboolean], + {$ifdef FPC}@{$endif}getsqlresult); + ffloatcols:= tdbcolnamearrayprop.create(msedb.realfields + msedb.datetimefields, + {$ifdef FPC}@{$endif}getsqlresult); + fintegercols.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + fint64cols.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + ftextcols.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + ffloatcols.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + inherited; +end; + +destructor tsqllookupbuffer.destroy; +begin + fintegercols.free; + fint64cols.free; + ftextcols.free; + ffloatcols.free; + inherited; +end; + +procedure tsqllookupbuffer.setsource(const avalue: tsqlresult); +begin + setlinkedvar(avalue,tmsecomponent(fsource)); + invalidatebuffer; +end; + +procedure tsqllookupbuffer.settextcols(const avalue: tdbcolnamearrayprop); +begin + ftextcols.assign(avalue); +end; + +procedure tsqllookupbuffer.setintegercols(const avalue: tdbcolnamearrayprop); +begin + fintegercols.assign(avalue); +end; + +procedure tsqllookupbuffer.setint64cols(const avalue: tdbcolnamearrayprop); +begin + fint64cols.assign(avalue); +end; + +procedure tsqllookupbuffer.setfloatcols(const avalue: tdbcolnamearrayprop); +begin + ffloatcols.assign(avalue); +end; + +function tsqllookupbuffer.getsqlresult(const aindex: integer): tsqlresult; +begin + result:= fsource; +end; + +procedure tsqllookupbuffer.clearbuffer; +begin + setlength(fintegerdata,fintegercols.count); + setlength(fint64data,fint64cols.count); + setlength(ftextdata,ftextcols.count); + setlength(ffloatdata,ffloatcols.count); + inherited; +end; + +function tsqllookupbuffer.getfieldcounttext: integer; +begin + result:= ftextcols.count; +end; + +function tsqllookupbuffer.getfieldcountinteger: integer; +begin + result:= fintegercols.count; +end; + +function tsqllookupbuffer.getfieldcountint64: integer; +begin + result:= fint64cols.count; +end; + +function tsqllookupbuffer.getfieldcountfloat: integer; +begin + result:= ffloatcols.count; +end; + +procedure tsqllookupbuffer.setfieldcounttext(const avalue: integer); +begin + readonlyprop; +end; + +procedure tsqllookupbuffer.setfieldcountinteger(const avalue: integer); +begin + readonlyprop; +end; + +procedure tsqllookupbuffer.setfieldcountint64(const avalue: integer); +begin + readonlyprop; +end; + +procedure tsqllookupbuffer.setfieldcountfloat(const avalue: integer); +begin + readonlyprop; +end; + +procedure tsqllookupbuffer.doloadbuffer; +var + int1,int3,int4: integer; + textf: dbcolarty; + integerf: dbcolarty; + int64f: dbcolarty; + realf: dbcolarty; + ar1: ansistringarty; + bo1: boolean; +begin + application.beginwait; +{ + beginupdate; +} + try +// clearbuffer; + with fsource do begin + if (fsource <> nil) and (active or (olbsq_closesqlresult in foptionsdb) and + (lbs_sourceclosed in fstate) and + not (csloading in componentstate)) then begin + try + bo1:= active; + if bo1 then begin + exclude(fstate,lbs_sourceclosed); + end; + if not bof or not active then begin + refresh; + end; + try + setlength(ar1,ftextcols.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= ftextcols[int1]; + end; + textf:= fdatacols.colsbyname(ar1); + setlength(ar1,fintegercols.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= fintegercols[int1]; + end; + integerf:= fdatacols.colsbyname(ar1); + setlength(ar1,fint64cols.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= fint64cols[int1]; + end; + int64f:= fdatacols.colsbyname(ar1); + setlength(ar1,floatcols.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= ffloatcols[int1]; + end; + realf:= fdatacols.colsbyname(ar1); + int3:= fcount; + int1:= fcount; + try + while not fsource.eof do begin + if int3 <= int1 then begin + int3:= (int3 * 3) div 2 + 100; + for int4:= 0 to high(ftextdata) do begin + setlength(ftextdata[int4].data,int3); + end; + for int4:= 0 to high(fintegerdata) do begin + setlength(fintegerdata[int4].data,int3); + end; + for int4:= 0 to high(fint64data) do begin + setlength(fint64data[int4].data,int3); + end; + for int4:= 0 to high(ffloatdata) do begin + setlength(ffloatdata[int4].data,int3); + end; + end; + for int4:= 0 to high(integerf) do begin + if integerf[int4] <> nil then begin + fintegerdata[int4].data[int1]:= integerf[int4].asinteger; + end; + end; + for int4:= 0 to high(int64f) do begin + if int64f[int4] <> nil then begin + fint64data[int4].data[int1]:= int64f[int4].aslargeint; + end; + end; + for int4:= 0 to high(realf) do begin + if realf[int4] <> nil then begin + if realf[int4].isnull then begin + ffloatdata[int4].data[int1]:= emptyreal; + end + else begin + ffloatdata[int4].data[int1]:= realf[int4].asfloat; + end; + end; + end; + for int4:= 0 to high(textf) do begin + if textf[int4] <> nil then begin + ftextdata[int4].data[int1]:= textf[int4].asmsestring; + end; + end; + inc(int1); + fsource.next; + end; + finally + for int4:= 0 to high(fintegerdata) do begin + setlength(fintegerdata[int4].data,int1); + end; + for int4:= 0 to high(fint64data) do begin + setlength(fint64data[int4].data,int1); + end; + for int4:= 0 to high(ftextdata) do begin + setlength(ftextdata[int4].data,int1); + end; + for int4:= 0 to high(ffloatdata) do begin + setlength(ffloatdata[int4].data,int1); + end; + fcount:= int1; + end; + finally + if {not bo1 and} (olbsq_closesqlresult in foptionsdb) and + not (csdesigning in componentstate) then begin + include(fstate,lbs_sourceclosed); + fsource.active:= false; + end; + end; + except + if csdesigning in componentstate then begin + application.handleexception(self); + end + else begin + raise; + end; + end; + end; + end; + include(fstate,lbs_buffervalid); + finally + application.endwait; +// endupdate; + end; +end; + +procedure tsqllookupbuffer.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = fsource) and (event = oe_changed) and (fupdating = 0) and + (fsource <> nil) and + (fsource.active or not (olbsq_closesqlresult in foptionsdb)) then begin + invalidatebuffer; + changed; + end; +end; + +function tsqllookupbuffer.fieldnamestext: stringarty; +begin + result:= ftextcols.itemar; +end; + +function tsqllookupbuffer.fieldnamesfloat: stringarty; +begin + result:= ffloatcols.itemar; +end; + +function tsqllookupbuffer.fieldnamesinteger: stringarty; +begin + result:= fintegercols.itemar; +end; + +function tsqllookupbuffer.fieldnamesint64: stringarty; +begin + result:= fint64cols.itemar; +end; + +{ tsqlresultfielddefs } +{ +constructor tsqlresultfielddefs.create(const aowner: tsqlresult); +begin + fsqlresult:= aowner; + tdefcollection(self).create(nil,owner,tsqlresultfielddef); +end; +} +procedure tsqlresultfielddefs.setitemname(aitem: tcollectionitem); +begin + {$ifdef mse_FPC_2_2} + if aitem is tnameditem then begin + with tnameditem(aitem) do begin + {$else} + if aitem is tfielddef then begin + with tfielddef(aitem) do begin + {$endif} + if name = '' then begin + name:= 'fielddef' + inttostr(id+1); + end + else begin + inherited; + end; + end; + end + else begin + inherited; + end; +end; +{ +procedure tsqlresultfielddefs.bindconnectors; +var + int1,int2: integer; + str1: string; + col1: tdbcol; +begin + for int1:= 0 to count - 1 do begin + with tsqlresultfielddef(items[int1]) do begin + if fconnector <> nil then begin + str1:= uppercase(name); + fconnector.fcol:= nil; + for int2:= 0 to high(fsqlresult.fcols.fitems) do begin + col1:= tdbcol(fsqlresult.fcols.fitems[int2]); + if col1.fuppername = str1 then begin + fconnector.fcol:= col1; + break; + end; + end; +// if fconnector.fcol = nil then begin +// raise exception.create(fsqlresult.name+': Field "'+name+'" not found.'); +// end; + end; + end; + end; +end; +} +(* +{ tsqlresultfielddef } + +destructor tsqlresultfielddef.destroy; +begin + connector:= nil; + inherited; +end; + +procedure tsqlresultfielddef.setconnector(const avalue: tsqlresultconnector); +begin + if fconnector <> avalue then begin + if fconnector <> nil then begin + fconnector.fcol:= nil; + fconnector.ffielddef:= nil; + end; + fconnector:= avalue; + if fconnector <> nil then begin + fconnector.fcol:= nil; + fconnector.ffielddef:= self; + end; + end; +end; +*) +{ tsqlresultconnector } + +destructor tsqlresultconnector.destroy; +begin +// if ffielddef <> nil then begin +// ffielddef.connector:= nil; +// end; + inherited; +end; + +function tsqlresultconnector.getcol: tdbcol; +begin + result:= fcol; + if result = nil then begin + raise exception.create(name+': Connector not bound'); + end; +end; + +procedure tsqlresultconnector.setsource(const avalue: tsqlresult); +begin + fcol:= nil; + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fsource)); +end; + +procedure tsqlresultconnector.setcolname(const avalue: dbcolnamety); +begin + fcolname:= avalue; + fcol:= nil; +end; + +procedure tsqlresultconnector.objevent(const sender: iobjectlink; + const event: objecteventty); +var + str1: string; + int1: integer; + col1: tdbcol; +begin + inherited; + case event of + oe_bindfields: begin + if (fcolname <> '') and (sender.getinstance = fsource) then begin + fcol:= nil; + str1:= uppercase(fcolname); + with fsource.fdatacols do begin + for int1:= 0 to high(fitems) do begin + col1:= tdbcol(fitems[int1]); + if col1.fuppername = str1 then begin + fcol:= col1; + break; + end; + end; + end; + end; + end; + oe_releasefields: begin + if sender.getinstance = fsource then begin + fcol:= nil; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msezeos.pas b/mseide-msegui/lib/common/db/msezeos.pas new file mode 100644 index 0000000..6121af6 --- /dev/null +++ b/mseide-msegui/lib/common/db/msezeos.pas @@ -0,0 +1,1385 @@ +unit msezeos; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,ZDataset,msedb,ZStoredProcedure,msestrings, + msedbgraphics,mseapplication,msedatabase; +type + tmsezgraphicfield = class(tmsegraphicfield) + public + constructor create(aowner: tcomponent); override; + end; + + tmsezreadonlyquery = class(tzreadonlyquery,imselocate,idscontroller, + igetdscontroller,isqlpropertyeditor,iactivatorclient) + private + fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + function isutf8: boolean; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheritedinsert(); + procedure inheriteddelete(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter(); +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + //isqlpropertyeditor + function getdatabase: tcustomconnection; //for isqlpropertyeditor + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + end; + + tmsezquery = class(tzquery,imselocate,idscontroller,igetdscontroller, + isqlpropertyeditor,iactivatorclient) + private + fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + function isutf8: boolean; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheritedinsert(); + procedure inheriteddelete(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + //isqlpropertyeditor + function getdatabase: tcustomconnection; //for isqlpropertyeditor + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + end; + + tmseztable = class(tztable,imselocate,idscontroller, + igetdscontroller,iactivatorclient) + private + fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheritedinsert(); + procedure inheriteddelete(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + end; + + tmsezstoredproc = class(tzstoredproc,imselocate,idscontroller, + igetdscontroller,iactivatorclient) + private + fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheritedinsert(); + procedure inheriteddelete(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + end; + +implementation + +{ tmsezreadonlyquery } + +constructor tmsezreadonlyquery.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsezreadonlyquery.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsezreadonlyquery.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsezreadonlyquery.locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; + +function tmsezreadonlyquery.locate(const key: msestring; + const field: tfield; const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; +} +procedure tmsezreadonlyquery.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsezreadonlyquery.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsezreadonlyquery.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsezreadonlyquery.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsezreadonlyquery.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsezreadonlyquery.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsezreadonlyquery.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsezreadonlyquery.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsezreadonlyquery.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsezreadonlyquery.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsezreadonlyquery.cancel; +begin + fcontroller.cancel; +end; + +function tmsezreadonlyquery.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsezreadonlyquery.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsezreadonlyquery.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tmsezreadonlyquery.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsezreadonlyquery.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsezreadonlyquery.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsezreadonlyquery.inheritedpost; +begin + inherited post; +end; + +procedure tmsezreadonlyquery.post; +begin + fcontroller.post; +end; + +procedure tmsezreadonlyquery.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsezreadonlyquery.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsezreadonlyquery.openlocal; +begin + inherited internalopen; +end; + +procedure tmsezreadonlyquery.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsezreadonlyquery.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsezreadonlyquery.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsezreadonlyquery.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsezreadonlyquery.isutf8: boolean; +begin + result:= fcontroller.isutf8; +end; + +function tmsezreadonlyquery.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsezreadonlyquery.getint64currency: boolean; +begin + result:= false; +end; + +function tmsezreadonlyquery.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsezreadonlyquery.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsezreadonlyquery.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsezreadonlyquery.endfilteredit; +begin + //dummy +end; + +procedure tmsezreadonlyquery.clearfilter; +begin + //dummy +end; +{ +procedure tmsezreadonlyquery.doidleapplyupdates; +begin + //dummy +end; +} +function tmsezreadonlyquery.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsezreadonlyquery.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsezreadonlyquery.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsezreadonlyquery.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsezreadonlyquery.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +procedure tmsezreadonlyquery.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmsezreadonlyquery.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsezreadonlyquery.begindisplaydata; +begin + //dummy +end; + +procedure tmsezreadonlyquery.enddisplaydata; +begin + //dummy +end; + +procedure tmsezreadonlyquery.inheritedinsert; +begin + inherited insert(); +end; + +procedure tmsezreadonlyquery.inheriteddelete; +begin + inherited delete(); +end; + +function tmsezreadonlyquery.getdatabase: tcustomconnection; +begin + result:= nil; +end; + +{ tmsezquery } + +constructor tmsezquery.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsezquery.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsezquery.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsezquery.locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; + +function tmsezquery.locate(const key: msestring; + const field: tfield; const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; +} +procedure tmsezquery.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsezquery.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsezquery.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsezquery.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsezquery.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsezquery.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsezquery.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsezquery.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsezquery.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsezquery.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsezquery.cancel; +begin + fcontroller.cancel; +end; + +function tmsezquery.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsezquery.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsezquery.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tmsezquery.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsezquery.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsezquery.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsezquery.inheritedpost; +begin + inherited post; +end; + +procedure tmsezquery.post; +begin + fcontroller.post; +end; + +procedure tmsezquery.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsezquery.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsezquery.openlocal; +begin + inherited internalopen; +end; + +procedure tmsezquery.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsezquery.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsezquery.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsezquery.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsezquery.isutf8: boolean; +begin + result:= fcontroller.isutf8; +end; + +function tmsezquery.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsezquery.getint64currency: boolean; +begin + result:= false; +end; + +function tmsezquery.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsezquery.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsezquery.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsezquery.endfilteredit; +begin + //dummy +end; + +procedure tmsezquery.clearfilter; +begin + //dummy +end; +{ +procedure tmsezquery.doidleapplyupdates; +begin + //dummy +end; +} +function tmsezquery.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsezquery.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsezquery.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsezquery.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsezquery.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +procedure tmsezquery.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmsezquery.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsezquery.begindisplaydata; +begin + //dummy +end; + +procedure tmsezquery.enddisplaydata; +begin + //dummy +end; + +procedure tmsezquery.inheritedinsert; +begin + inherited insert(); +end; + +procedure tmsezquery.inheriteddelete; +begin + inherited delete(); +end; + +function tmsezquery.getdatabase: tcustomconnection; +begin + result:= nil; +end; + +{ tmseztable } + +constructor tmseztable.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmseztable.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmseztable.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmseztable.locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; + +function tmseztable.locate(const key: msestring; + const field: tfield; const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; +} +procedure tmseztable.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmseztable.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmseztable.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmseztable.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmseztable.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmseztable.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmseztable.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmseztable.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmseztable.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmseztable.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmseztable.cancel; +begin + fcontroller.cancel; +end; + +function tmseztable.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmseztable.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmseztable.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tmseztable.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmseztable.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmseztable.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmseztable.inheritedpost; +begin + inherited post; +end; + +procedure tmseztable.post; +begin + fcontroller.post; +end; + +procedure tmseztable.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmseztable.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmseztable.openlocal; +begin + inherited internalopen; +end; + +procedure tmseztable.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmseztable.internalclose; +begin + fcontroller.internalclose; +end; + +function tmseztable.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmseztable.getnumboolean: boolean; +begin + result:= true; +end; + +function tmseztable.getfloatdate: boolean; +begin + result:= false; +end; + +function tmseztable.getint64currency: boolean; +begin + result:= false; +end; + +function tmseztable.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmseztable.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmseztable.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmseztable.endfilteredit; +begin + //dummy +end; + +procedure tmseztable.clearfilter; +begin + //dummy +end; +{ +procedure tmseztable.doidleapplyupdates; +begin + //dummy +end; +} +function tmseztable.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmseztable.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmseztable.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmseztable.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmseztable.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +procedure tmseztable.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmseztable.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmseztable.begindisplaydata; +begin + //dummy +end; + +procedure tmseztable.enddisplaydata; +begin + //dummy +end; + +procedure tmseztable.inheritedinsert; +begin + inherited insert(); +end; + +procedure tmseztable.inheriteddelete; +begin + inherited delete(); +end; + +{ tmsezstoredproc } + +constructor tmsezstoredproc.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsezstoredproc.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsezstoredproc.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsezstoredproc.locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; + +function tmsezstoredproc.locate(const key: msestring; + const field: tfield; const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; +} +procedure tmsezstoredproc.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsezstoredproc.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsezstoredproc.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsezstoredproc.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsezstoredproc.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsezstoredproc.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsezstoredproc.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsezstoredproc.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsezstoredproc.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsezstoredproc.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsezstoredproc.cancel; +begin + fcontroller.cancel; +end; + +function tmsezstoredproc.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsezstoredproc.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsezstoredproc.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tmsezstoredproc.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsezstoredproc.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsezstoredproc.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsezstoredproc.inheritedpost; +begin + inherited post; +end; + +procedure tmsezstoredproc.post; +begin + fcontroller.post; +end; + +procedure tmsezstoredproc.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsezstoredproc.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsezstoredproc.openlocal; +begin + inherited internalopen; +end; + +procedure tmsezstoredproc.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsezstoredproc.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsezstoredproc.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsezstoredproc.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsezstoredproc.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsezstoredproc.getint64currency: boolean; +begin + result:= false; +end; + +function tmsezstoredproc.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsezstoredproc.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsezstoredproc.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsezstoredproc.endfilteredit; +begin +//dummy +end; + +procedure tmsezstoredproc.clearfilter; +begin +//dummy +end; +{ +procedure tmsezstoredproc.doidleapplyupdates; +begin + //dummy +end; +} +function tmsezstoredproc.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsezstoredproc.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsezstoredproc.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsezstoredproc.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsezstoredproc.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +procedure tmsezstoredproc.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmsezstoredproc.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsezstoredproc.begindisplaydata; +begin + //dummy +end; + +procedure tmsezstoredproc.enddisplaydata; +begin + //dummy +end; + +procedure tmsezstoredproc.inheritedinsert; +begin + inherited insert(); +end; + +procedure tmsezstoredproc.inheriteddelete; +begin + inherited delete(); +end; + +{ tmsezgraphicfield } + +constructor tmsezgraphicfield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftblob); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msqldb.pas b/mseide-msegui/lib/common/db/msqldb.pas new file mode 100644 index 0000000..efe84e1 --- /dev/null +++ b/mseide-msegui/lib/common/db/msqldb.pas @@ -0,0 +1,2880 @@ +{ + Copyright (c) 2004 by Joost van der Sluis + + SQL database & dataset + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + Modified 2006-2017 by Martin Schreiber + + **********************************************************************} + +unit msqldb; + +{$ifdef FPC} +{$mode objfpc}{$interfaces corba}{$goto on}{$H+} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + sysutils,classes,mclasses,mdb,msebufdataset,msetypes,msedb,mseclasses, + msedatabase,msestrings,msearrayutils,msedatalist,mseinterfaces, + mseapplication,mseglob,msetimer,msearrayprops,msemacros; + +type + TSchemaType = (stNoSchema,stTables,stSysTables,stProcedures,stColumns, + stProcedureParams,stIndexes,stPackages); + sqlconnoptionty = (sco_supportparams,sco_forceparams, + sco_emulateretaining,sco_nounprepared, + sco_blobscached); +// dbf_params,dbf_blobscached + sqlconnoptionsty = set of sqlconnoptionty; + +// TSQLQuery = class; + + TStatementType = (stNone, stSelect, stInsert, stUpdate, stDelete, + stDDL, stGetSegment, stPutSegment, stExecProcedure, + stStartTrans, stCommit, stRollback, stSelectForUpd); + +const + updatestatementtypes: array[tupdatekind] of tstatementtype = + //(ukModify, ukInsert, ukDelete) + (stupdate, stinsert, stdelete); + StatementTokens : Array[TStatementType] of msestring = + ('(none)', 'select', + 'insert', 'update', 'delete', + 'create', 'get', 'put', 'execute', + 'start','commit','rollback', '?' + ); + datareturningtypes = [stselect,stexecprocedure]; + +type + tcustomsqlconnection = class; + TSQLTransaction = class; + + tsqlstringlist = class(tmacrostringlist) + end; + + TSQLHandle = Class(TObject) + end; + + icursorclient = interface(iblobchache) + function stringmemo: boolean; //memo fields are text(0) fields + end; + + TSQLCursor = Class(TSQLHandle) + private + fblobs: stringarty; + fblobcount: integer; + fowner: icursorclient; + protected + public + FPrepared : Boolean; + FInitFieldDef : Boolean; + FStatementType : TStatementType; + ftrans: pointer; + fname: ansistring; + frowsaffected: integer; + frowsreturned: integer; + constructor create(const aowner: icursorclient; const aname: ansistring); + //aowner can be nil + procedure close; virtual; + function wantblobfetch: boolean; + function stringmemo: boolean; + function getcachedblob(const blobid: integer): tstream; + function addblobdata(const adata: pointer; const alength: integer): integer; + overload; + procedure addblobcache(const aid: int64; const adata: string); + function addblobdata(const adata: string): integer; overload; + procedure blobfieldtoparam(const afield: tfield; const aparam: tparam; + const asstring: boolean = false); + end; + + econnectionerror = class(edatabaseerror) + private + ferror: integer; + ferrormessage: msestring; + fsender: tcustomsqlconnection; + public + constructor create(const asender: tcustomsqlconnection; + const amessage: ansistring; + const aerrormessage: msestring; const aerror: integer); + property sender: tcustomsqlconnection read fsender; + property error: integer read ferror; + property errormessage: msestring read ferrormessage; + end; + + tdbcontroller = class(tactivatorcontroller) + private + fdatabasename: filenamety; +// fintf: idbcontroller; + foptions: databaseoptionsty; +// factioncount: integer; +// factionwait: boolean; + procedure setoptions(const avalue: databaseoptionsty); + protected + procedure setowneractive(const avalue: boolean); override; + public + constructor create(const aowner: tmdatabase; const aintf: idbcontroller); + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + published + property options: databaseoptionsty read foptions write setoptions default []; + end; + + getcredentialseventty = procedure(const sender: tcustomsqlconnection; + var ausername: msestring; var apassword: msestring) + of object; + tmsesqlscript = class; + tcustomsqlconnection = class(TmDatabase,idbcontroller,iactivatorclient) + private + FPassword : msestring; + FTransaction : TSQLTransaction; + FUserName : msestring; + FHostName : msestring; + FCharSet : msestring; + FRole : mseString; + + fafterconnect: tmsesqlscript; + fbeforedisconnect: tmsesqlscript; +// fdatasets1: datasetarty; +// frecnos: integerarty; + ftransactionwrite: tsqltransaction; + fongetcredentials: getcredentialseventty; + procedure setcontroller(const avalue: tdbcontroller); + procedure settransaction(const avalue : tsqltransaction); + procedure settransactionwrite(const avalue: tsqltransaction); + procedure GetDBInfo(const SchemaType : TSchemaType; + const SchemaObjectName, ReturnField : string; + out list: msestringarty); +// function getconnected: boolean; + procedure setafteconnect(const avalue: tmsesqlscript); + procedure setbeforedisconnect(const avalue: tmsesqlscript); +// procedure closeds; +// procedure reopends; + protected + FConnOptions: sqlconnoptionsty; + fcontroller: tdbcontroller; + function connectionmessage(atext: pchar): msestring; + procedure finalizetransaction(const atransaction: tsqlhandle); virtual; +// procedure setconnected(const avalue: boolean); + procedure notification(acomponent: tcomponent; operation: toperation); override; + + function StrToStatementType(s : msestring) : TStatementType; virtual; + procedure getcredentials(var ausername: msestring; var apassword: msestring); + procedure freecredentials(var ausername: msestring; var apassword: msestring); + //fill with #0 before free + procedure DoInternalConnect; override; + procedure doafterinternalconnect; override; + procedure dobeforeinternaldisconnect; override; + procedure DoInternalDisconnect; override; + function GetAsSQLText(const Field : TField) : msestring; overload; virtual; + function GetAsSQLText(const Param : TParam) : msestring; overload; virtual; + function GetHandle : pointer; virtual; + procedure updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); virtual; + + Function AllocateTransactionHandle : TSQLHandle; virtual; abstract; + + procedure internalexecute(const cursor: tsqlcursor; const atransaction: tsqltransaction; + const aparams : tmseparams; const autf8: boolean); virtual; abstract; + procedure internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; + const asql: string; const origsql: msestring; + const aparams: tmseparams); virtual; + + procedure Execute(const cursor: TSQLCursor; const atransaction: tsqltransaction; + const AParams : TmseParams; const autf8: boolean); + procedure Executeunprepared(const cursor: TSQLCursor; + const atransaction: tsqltransaction; + const AParams : TmseParams; + const asql: msestring; const autf8: boolean); + function GetTransactionHandle(trans : TSQLHandle): pointer; virtual; abstract; + function Commit(trans : TSQLHandle) : boolean; virtual; abstract; + function RollBack(trans : TSQLHandle) : boolean; virtual; abstract; + function StartdbTransaction(const trans : TSQLHandle; + const aParams: tstringlist) : boolean; virtual; abstract; + procedure internalcommitretaining(trans : tsqlhandle); virtual; abstract; + procedure internalrollbackretaining(trans : tsqlhandle); virtual; abstract; + + procedure CommitRetaining(trans : TSQLHandle); virtual; + procedure RollBackRetaining(trans : TSQLHandle); virtual; + function getblobdatasize: integer; virtual; abstract; + function getnumboolean: boolean; virtual; + function getfloatdate: boolean; virtual; + function getint64currency: boolean; virtual; + + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); virtual; + function getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; virtual; + function GetSchemaInfoSQL(SchemaType : TSchemaType; + SchemaObjectName, SchemaPattern : msestring) : msestring; virtual; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; virtual; + + procedure closeds(out activeds: integerarty); + procedure reopends(const activeds: integerarty); + function identquotechar: msestring; virtual; + procedure beginupdate; virtual; + procedure endupdate; virtual; + function internalExecuteDirect(const aSQL: mseString; + ATransaction: TSQLTransaction; + const aparams: tmseparams; aparamvars: array of variant; + aisutf8: boolean; const noprepare: boolean): integer; + //idbcontroller + procedure setinheritedconnected(const avalue: boolean); + function readsequence(const sequencename: string): msestring; virtual; + function sequencecurrvalue(const sequencename: string): msestring; virtual; + function writesequence(const sequencename: string; + const avalue: largeint): msestring; virtual; +// function getfeatures(): databasefeaturesty virtual; + function blobscached: boolean; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure updateutf8(var autf8: boolean); virtual; + function isutf8: boolean; + function todbstring(const avalue: msestring): string; + function tomsestring(const avalue: string): msestring; + procedure FreeFldBuffers(cursor : TSQLCursor); virtual; abstract; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; virtual; abstract; + //aowner can be nil + //aowner used as blob cache + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); virtual; abstract; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); + overload; virtual; abstract; + procedure UnPrepareStatement(cursor : TSQLCursor); virtual; abstract; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TfieldDefs); virtual; abstract; + function Fetch(cursor : TSQLCursor) : boolean; virtual; abstract; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; virtual; abstract; + //if bufsize < 0 -> buffer was to small, should be -bufsize + //buffer can be nil + //false if null + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; virtual; + //null based + + procedure Close; + procedure Open; + property Handle: Pointer read GetHandle; + procedure StartTransaction; override; + procedure EndTransaction; override; + property ConnOptions: sqlconnoptionsty read FConnOptions; + function executedirect(const asql: msestring; + const aisutf8: boolean = false): integer; overload; + //returns rowsaffected or -1 if not supported + function executedirect(const asql: msestring; + atransaction: tsqltransaction; + const aparams: tmseparams = nil; + const aisutf8: boolean = false; + const anoprepare: boolean = false): integer; overload; + function ExecuteDirect(const aSQL: mseString; + ATransaction: TSQLTransaction; + const aparams: array of variant; + const aisutf8: boolean = false; + const anoprepare: boolean = false): integer; overload; + procedure GetTableNames(out List: msestringarty; + SystemTables: Boolean = false); virtual; + procedure GetProcedureNames(out List: msestringarty); virtual; + procedure GetFieldNames(const TableName: string; + out List: msestringarty); virtual; + function getinsertid(const atransaction: tsqltransaction): int64; virtual; + function fieldtosql(const afield: tfield): msestring; + function fieldtooldsql(const afield: tfield): msestring; + function paramtosql(const aparam: tparam): msestring; + + property Password : msestring read FPassword write FPassword; + property Transaction : TSQLTransaction read FTransaction write SetTransaction; + property transactionwrite : tsqltransaction read ftransactionwrite + write settransactionwrite; + property UserName : msestring read FUserName write FUserName; + property CharSet : msestring read FCharSet write FCharSet; + property HostName : msestring Read FHostName Write FHostName; + + property Connected: boolean read getconnected write setconnected default false; + Property Role : msestring read FRole write FRole; + property afterconnect: tmsesqlscript read fafterconnect write setafteconnect; + property beforedisconnect: tmsesqlscript read fbeforedisconnect write setbeforedisconnect; + property controller: tdbcontroller read fcontroller write setcontroller; + property ongetcredentials: getcredentialseventty read fongetcredentials + write fongetcredentials; + end; + + tsqlconnection = class(tcustomsqlconnection) + published + property Password; + property Transaction; + property transactionwrite; + property UserName; + property CharSet; + property HostName; + property controller; + + property Connected; + Property Role; + property DatabaseName; + property KeepConnection; +// property LoginPrompt; + property Params; + property ongetcredentials; + property afterconnect; + property beforedisconnect; +// property OnLogin; + end; + + TCommitRollbackAction = (caNone, caCommit, caCommitRetaining, caRollback, + caRollbackRetaining); + transactionoptionty = (tao_fake,tao_fakeretaining, + tao_catcherror,tao_rollbackonerror, + tao_refreshdatasets); + transactionoptionsty = set of transactionoptionty; + sqltransactioneventty = procedure(const sender: tsqltransaction) of object; + commiterroreventty = procedure(const sender: tsqltransaction; + const aexception: exception; var handled: boolean) of object; + + TSQLTransaction = class (TmDBTransaction) + private + FTrans: TSQLHandle; + FAction: TCommitRollbackAction; + FParams: TStringList; + fstartcount: integer; + foptions: transactionoptionsty; + fonbeforestart: sqltransactioneventty; + fonafterstart: sqltransactioneventty; + fonbeforecommit: sqltransactioneventty; + fonaftercommit: sqltransactioneventty; + fonbeforecommitretaining: sqltransactioneventty; + fonaftercommitretaining: sqltransactioneventty; + fonbeforerollbackretaining: sqltransactioneventty; + fonafterrollbackretaining: sqltransactioneventty; + fonbeforerollback: sqltransactioneventty; + fonafterrollback: sqltransactioneventty; + foncommiterror: commiterroreventty; + fonbeforestop: sqltransactioneventty; + fonafterstop: sqltransactioneventty; + fpendingaction: tcommitrollbackaction; + fpendingrefresh: boolean; + procedure setparams(const avalue: TStringList); + function getdatabase: tcustomsqlconnection; + procedure setdatabase1(const avalue: tcustomsqlconnection); + function docommit(const retaining: boolean): boolean; + procedure setpendingaction(const avalue: tcommitrollbackaction); + protected + fsavepointlevel: integer; + procedure CloseTrans; override; + function GetHandle : Pointer; virtual; + Procedure SetDatabase (Value : tmdatabase); override; + procedure disconnect(const sender: itransactionclient; + const auxclients: integer); + procedure finalizetransaction; override; + procedure doendtransaction(const aaction: tcommitrollbackaction); + procedure dobeforestop; + procedure doafterstop; + procedure checkpendingaction; + procedure savepointevent(const akind: savepointeventkindty; + const alevel: integer); + procedure execerror(); + public + constructor Create(AOwner : TComponent); override; + destructor Destroy; override; + procedure refresh(aaction: tcommitrollbackaction = canone); + //canone -> action property + //closes transaction, calls refreshdatasets + function Commit(const checksavepoint: boolean = true): boolean; virtual; //true if ok + function CommitRetaining(const checksavepoint: boolean = true): boolean; virtual; + procedure Rollback; virtual; + procedure RollbackRetaining; virtual; + procedure StartTransaction; override; + property Handle: Pointer read GetHandle; + procedure EndTransaction; override; + function savepointbegin: integer; + procedure savepointrollback(alevel: integer = -1); + //-1 -> toplevel + procedure savepointrelease; + property savepointlevel: integer read fsavepointlevel; + property trans: tsqlhandle read ftrans; + property pendingaction: tcommitrollbackaction read fpendingaction + write setpendingaction; + //will be executed on savepointlevel 0 + property pendingrefresh: boolean read fpendingrefresh + write fpendingrefresh; + published + property options: transactionoptionsty read foptions write foptions default []; + property Action : TCommitRollbackAction read FAction write FAction default canone; + property Database: tcustomsqlconnection read getdatabase write setdatabase1; + property Params : TStringList read FParams write setparams; + property oncommiterror: commiterroreventty read foncommiterror + write foncommiterror; + property onbeforestart: sqltransactioneventty read fonbeforestart + write fonbeforestart; + property onafterstart: sqltransactioneventty read fonafterstart + write fonafterstart; + property onbeforestop: sqltransactioneventty read fonbeforestop + write fonbeforestop; + property onafterstop: sqltransactioneventty read fonafterstop + write fonafterstop; + property onbeforecommit: sqltransactioneventty read fonbeforecommit + write fonbeforecommit; + property onaftercommit: sqltransactioneventty read fonaftercommit + write fonaftercommit; + property onbeforecommitretaining: sqltransactioneventty + read fonbeforecommitretaining write fonbeforecommitretaining; + property onaftercommitretaining: sqltransactioneventty + read fonaftercommitretaining write fonaftercommitretaining; + property onbeforerollback: sqltransactioneventty read fonbeforerollback + write fonbeforerollback; + property onafterrollback: sqltransactioneventty read fonafterrollback + write fonafterrollback; + property onbeforerollbackretaining: sqltransactioneventty + read fonbeforerollbackretaining + write fonbeforerollbackretaining; + property onafterrollbackretaining: sqltransactioneventty + read fonafterrollbackretaining + write fonafterrollbackretaining; + end; + + tcustomsqlstatement = class; + + sqlstatementeventty = procedure(const sender: tcustomsqlstatement; + const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction) of object; + sqlstatementerroreventty = procedure(const sender: tcustomsqlstatement; + const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction; const e: exception; + var handled: boolean) of object; + + sqlstatementoptionty = (sso_utf8,sso_autocommit,sso_autocommitret, + sso_noprepare, + sso_savepoint //for tmsesqlscript + ); + sqlstatementoptionsty = set of sqlstatementoptionty; + + tcustomsqlstatement = class(tmsecomponent,itransactionclient,idatabaseclient) + private + fonbeforeexecute: sqlstatementeventty; + fonafterexecute: sqlstatementeventty; + fonerror: sqlstatementerroreventty; + procedure setsql(const avalue: tsqlstringlist); + procedure setdatabase1(const avalue: tcustomsqlconnection); + procedure setparams(const avalue: tmseparams); + procedure settransaction1(const avalue: tsqltransaction); + procedure setoptions(const avalue: sqlstatementoptionsty); + //itransactionclient + function getname: string; + function getactive: boolean; virtual; + procedure settransaction(const avalue: tmdbtransaction); + procedure settransactionwrite(const avalue: tmdbtransaction); + procedure checkbrowsemode; + procedure refreshtransaction; + procedure savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); + //idbclient + procedure setdatabase(const avalue: tmdatabase); + function gettransaction: tmdbtransaction; + function getrecno: integer; + procedure setrecno(value: integer); + procedure disablecontrols; + procedure enablecontrols; + function moveby(distance: longint): longint; +// procedure readoptionsold(areader: treader); +// procedure readoptions(areader: treader); +// procedure writeoptions(awriter: twriter); + protected + fsql: tsqlstringlist; + fdatabase: tcustomsqlconnection; + ftransaction: tsqltransaction; + fparams: tmseparams; + foptions: sqlstatementoptionsty; +// procedure defineproperties(afiler: tfiler); override; + function getdatabase: tcustomconnection; //for isqlpropertyeditor + procedure setactive(avalue: boolean); virtual; + procedure execute; virtual; abstract; + procedure dobeforeexecute(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction); + procedure doafterexecute(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction); + procedure doerror(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction; const e: exception; + var handled: boolean); + procedure dosqlchange(const sender: tobject); virtual; + property onbeforeexecute: sqlstatementeventty read fonbeforeexecute + write fonbeforeexecute; + property onafterexecute: sqlstatementeventty read fonafterexecute + write fonafterexecute; + property onerror: sqlstatementerroreventty read fonerror write fonerror; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function isutf8: boolean; + property params : tmseparams read fparams write setparams; + property sql: tsqlstringlist read fsql write setsql; + property database: tcustomsqlconnection read fdatabase write setdatabase1; + property transaction: tsqltransaction read ftransaction write settransaction1; + //can be nil + property options: sqlstatementoptionsty read foptions + write setoptions {stored false} default [] ; + end; + + msesqlscripteventty = procedure(const sender: tmsesqlscript) of object; + + tmsesqlscript = class(tcustomsqlstatement) + private + fstatementnr: integer; + fstatementcount: integer; +// fstatements: msestringarty; + fonbeforestatement: msesqlscripteventty; + fonafterstatement: msesqlscripteventty; + fterm: msechar; + fcharescapement: boolean; + protected + procedure execute; overload; override; + public + constructor create(aowner: tcomponent); override; + procedure execute(adatabase: tcustomsqlconnection = nil; + atransaction: tsqltransaction = nil); overload; + property statementnr: integer read fstatementnr; //zero based + property statementcount: integer read fstatementcount; +// property fstatements: msestringarty read fstatements; + published + property term: msechar read fterm write fterm default ';'; + property charescapement: boolean read fcharescapement + write fcharescapement default false; + property onbeforestatement: msesqlscripteventty read fonbeforestatement + write fonbeforestatement; + property onafterstatement: msesqlscripteventty read fonafterstatement + write fonafterstatement; + property params; + property sql; + property database; + property transaction; + //can be nil + property options; + property onbeforeexecute; + property onafterexecute; + property onerror; + end; + + tcursorsqlstatement = class(tcustomsqlstatement) + private + protected + fcursor: tsqlcursor; + fstatementtype: tstatementtype; + procedure internalclose; + function getactive: boolean; override; + procedure setactive(avalue: boolean); override; + procedure dosqlchange(const sender: tobject); override; + procedure checkautocommit; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function isprepared: boolean; + procedure prepare; virtual; + procedure unprepare; virtual; + procedure execute; overload; override; + procedure execute(const aparams: array of variant); overload; + function rowsaffected: integer; + //-1 if not supported + property statementtype : tstatementtype read fstatementtype + write fstatementtype default stnone; + end; + + tsqlstatement = class(tcursorsqlstatement) + published + property params; + property sql; + property database; + property transaction; + //can be nil + property options; + property statementtype; + property onbeforeexecute; + property onafterexecute; + property onerror; + end; + +const + blobidsize = sizeof(integer); +type + iblobconnection = interface(inullinterface)[miid_iblobconnection] + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); //'' -> null, id binary otherwise + //returns blobid or data in param + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); + function blobscached: boolean; + end; + + isqlclient = interface(idatabaseclient) + function getsqltransaction: tsqltransaction; + procedure setsqltransaction(const avalue: tsqltransaction); + function getsqltransactionwrite: tsqltransaction; + procedure setsqltransactionwrite(const avalue: tsqltransaction); + procedure unprepare; + end; + +procedure updateparams(const aparams: tmseparams; const autf8: boolean); +procedure doexecute(const aparams: tmseparams; const atransaction: tmdbtransaction; + const acursor: tsqlcursor; adatabase: tmdatabase; + const autf8: boolean); +procedure checksqlconnection(const aname: ansistring; const avalue: tmdatabase); +procedure checksqltransaction(const aname: ansistring; const avalue: tmdbtransaction); +procedure dosetsqldatabase(const sender: isqlclient; const avalue: tmdatabase; + var acursor: tsqlcursor; var dest: tmdatabase); + +function splitsql(const asql: msestring; const term: msechar = ';'; + const charescapement: boolean = false): msestringarty; + +//function splitsqlstatements(const asqltext: msestring): msestringarty; + +implementation +uses + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},strutils,msereal,msestream, + msebits,msefileutils,mseformatstr,typinfo,msesysutils,msesqlresult; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdataset1 = class(tdataset); + tmdatabase1 = class(tmdatabase); + +procedure updateparams(const aparams: tmseparams; const autf8: boolean); +var + int1: integer; +begin + if aparams <> nil then begin + aparams.isutf8:= autf8; + for int1:= 0 to aparams.count - 1 do begin + with aparams[int1] do begin + if not isnull and (datatype in [ftFloat,ftcurrency,ftDate,ftTime,ftDateTime]) and + (asfloat = emptyreal) then begin + clear; + end; + end; + end; + end; +end; + +procedure doexecute(const aparams: tmseparams; const atransaction: tmdbtransaction; + const acursor: tsqlcursor; adatabase: tmdatabase; + const autf8: boolean); +begin + updateparams(aparams,autf8); + acursor.ftrans:= tsqltransaction(atransaction).handle; + tcustomsqlconnection(adatabase).execute(acursor,tsqltransaction(atransaction), + aParams,autf8); +end; + +procedure checksqlconnection(const aname: ansistring; const avalue: tmdatabase); +begin + if (avalue <> nil) and not (avalue is tcustomsqlconnection) then begin + exception.create(aname+': Database must be tcustomsqlconnection.'); + end; +end; + +procedure checksqltransaction(const aname: ansistring; const avalue: tmdbtransaction); +begin + if (avalue <> nil) and not (avalue is tsqltransaction) then begin + exception.create(aname+': Transaction must be tsqltransaction.'); + end; +end; + +procedure dosetsqldatabase(const sender: isqlclient; const avalue: tmdatabase; + var acursor: tsqlcursor; var dest: tmdatabase); +begin + if (dest <> avalue) then begin + checksqlconnection(sender.getname,avalue); + sender.unprepare; + if acursor <> nil then begin + tcustomsqlconnection(dest).deallocatecursorhandle(acursor); + end; + dosetdatabase(sender,avalue,dest); + if (avalue <> nil) then begin + if (sender.getsqltransaction = nil) then begin + sender.setsqltransaction(tcustomsqlconnection(avalue).transaction); + end; + if (sender.getsqltransactionwrite = nil) then begin + sender.setsqltransactionwrite(tcustomsqlconnection(avalue).transactionwrite); + end; + end; + end; +end; + +function splitsql(const asql: msestring; + const term: msechar = ';'; + const charescapement: boolean = false): msestringarty; +var + po1,po2: pmsechar; + + procedure addstatement; + begin + setlength(result,high(result)+2); + setlength(result[high(result)],po1-po2); + move(po2^,result[high(result)][1],length(result[high(result)])*sizeof(msechar)); + end; + + procedure checkescape(var apo: pmsechar); + begin + if charescapement and (apo^ = '\') then begin + inc(apo); + if (apo^ <> #0) then begin + inc(apo); + end; + end + else begin + inc(apo); + end; + end; + +//var +// po3: pmsechar; +begin + result:= nil; + po1:= pmsechar(asql); + po2:= po1; + while po1^ <> #0 do begin + if po1^ = term then begin + po1^:= ';'; + inc(po1); + addstatement; + (po1-1)^:= term; + po2:= po1; + end + else begin + case po1^ of + '''': begin + inc(po1); + while (po1^ <> '''') and (po1^ <> #0) do begin + checkescape(po1); + end; + if po1^ = '''' then begin + inc(po1); + end; + end; + '"': begin + inc(po1); + while (po1^ <> '"') and (po1^ <> #0) do begin + checkescape(po1); + end; + if po1^ = '"' then begin + inc(po1); + end; + end; + '-': begin// possible start of -- comment + inc(po1); + if po1^ = '-' then begin // -- comment + repeat // skip until at end of line + inc(po1); + until (po1^ = #0) or (po1^ = #10); + end; + end; + '/': begin // possible start of /* */ comment + inc(po1); + if po1^ = '*' then begin // /* */ comment + repeat + inc(po1); + if po1^ = '*' then begin// possible end of comment + inc(po1); + if po1^ = '/' then begin + break; // end of comment + end; + end; + until po1^ = #0; + if po1^ = '/' then begin + inc(po1); // skip final / + end; + end; + end; + else begin + inc(po1); + end; + end; //case + end; + end; + { + if po1 <> po2 then begin //no terminating ';' + po3:= po1; + while po3 > po2 do begin //remove trailing space //////what about newline? + dec(po3); + if po3^ <> ' ' then begin + break; + end; + end; + if po3 <> po2 then begin //not empty + addstatement; + end; + end; + } +end; + + +{ tdbcontroller } + +constructor tdbcontroller.create(const aowner: tmdatabase; const aintf: idbcontroller); +begin +// fintf:= aintf; + inherited create(aowner,aintf); +end; + +procedure tdbcontroller.setowneractive(const avalue: boolean); +//var +// bo1: boolean; +begin + idbcontroller(fintf).setinheritedconnected(avalue); + { + if avalue then begin + with tmdatabase(fowner) do begin + if checkcanevent(fowner,tmethod(fonbeforeconnect)) then begin + fonbeforeconnect(tmdatabase(fowner)); + end; + try + fintf.setinheritedconnected(avalue); + except + on e: exception do begin + if checkcanevent(fowner,tmethod(fonconnecterror)) then begin + bo1:= false; + fonconnecterror(tmdatabase(fowner),e,bo1); + if not bo1 then begin + raise; + end; + end; + end; + end; + if checkcanevent(fowner,tmethod(fonafterconnect)) then begin + fonafterconnect(tmdatabase(fowner)); + end; + end; + end + else begin + fintf.setinheritedconnected(avalue); +// tmdatabase(fowner).connected:= avalue; + end; + } +end; + +function tdbcontroller.getdatabasename: filenamety; +begin + result:= fdatabasename; +end; + +procedure tdbcontroller.setdatabasename(const avalue: filenamety); +var + str1: filenamety; +begin + str1:= trim(avalue); + if (str1 <> '') and (str1[1] = '''') and + (str1[length(str1)] = '''') then begin + fdatabasename:= str1; + tmdatabase(fowner).databasename:= copy(str1,2,length(str1)-2); + end + else begin + fdatabasename:= tomsefilepath(str1); + tmdatabase(fowner).databasename:= + tosysfilepath(filepath(str1,fk_default,true)); + end; +end; + +procedure tdbcontroller.setoptions(const avalue: databaseoptionsty); +const + mask: databaseoptionsty = [dbo_utf8,dbo_noutf8]; +begin + if foptions <> avalue then begin +// tmdatabase1(fowner).checkdisconnected; + foptions:= databaseoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + end; +end; + +{ tcustomsqlconnection } + +constructor tcustomsqlconnection.create(aowner: tcomponent); +begin + fcontroller:= tdbcontroller.create(self,idbcontroller(self)); + inherited; +end; + +destructor tcustomsqlconnection.destroy; +begin + inherited; + fcontroller.free; +end; + +function tcustomsqlconnection.connectionmessage(atext: pchar): msestring; +begin + if dbo_utf8message in fcontroller.foptions then begin + result:= utf8tostring(atext); + end + else begin + result:= atext; + end; +end; + +procedure tcustomsqlconnection.setinheritedconnected(const avalue: boolean); +begin + connected:= avalue; +end; + +function tcustomsqlconnection.readsequence( + const sequencename: string): msestring; +begin + result:= ''; //dummy +end; + +function tcustomsqlconnection.sequencecurrvalue( + const sequencename: string): msestring; +begin + result:= ''; //dummy +end; + +function tcustomsqlconnection.writesequence(const sequencename: string; + const avalue: largeint): msestring; +begin + result:= ''; //dummy +end; +{ +function tcustomsqlconnection.getfeatures(): databasefeaturesty; +begin + result:= []; +end; +} +function tcustomsqlconnection.blobscached: boolean; +begin + result:= sco_blobscached in fconnoptions; +// result:= dbf_blobscached in getfeatures; +end; + +procedure tcustomsqlconnection.updateutf8(var autf8: boolean); +begin + if dbo_utf8 in fcontroller.options then begin + autf8:= true; + end; + if dbo_noutf8 in fcontroller.options then begin + autf8:= false; + end; +end; + +function tcustomsqlconnection.isutf8: boolean; +begin + result:= false; + updateutf8(result); +end; + +function tcustomsqlconnection.StrToStatementType(s: msestring) : TStatementType; + +var T : TStatementType; + +begin + result:= stnone; + S:= mseLowercase(s); + For t:= stselect to strollback do + if (S=StatementTokens[t]) then begin + result:= t; + Exit; + end; +end; + +procedure tcustomsqlconnection.getcredentials(var ausername: msestring; + var apassword: msestring); +begin + if assigned(fongetcredentials) then begin + ausername:= username; + apassword:= ''; + fongetcredentials(self,ausername,apassword); + end + else begin + ausername:= username; + apassword:= password; + end; + uniquestring(ausername); + uniquestring(apassword); +end; + +procedure tcustomsqlconnection.freecredentials(var ausername: msestring; + var apassword: msestring); +begin + stringsafefree(ausername,false); + stringsafefree(apassword,false); +end; + +procedure tcustomsqlconnection.settransaction(const avalue : tsqltransaction); +begin + if ftransaction <> avalue then begin + if assigned(ftransaction) and ftransaction.active then begin + databaseerror(serrasstransaction); + end; + if assigned(avalue) then begin + avalue.database:= self; + end; + ftransaction:= avalue; + end; +end; + +procedure tcustomsqlconnection.settransactionwrite(const avalue : tsqltransaction); +begin + if ftransactionwrite <> avalue then begin + if assigned(ftransactionwrite) and ftransactionwrite.active then begin + databaseerror(serrasstransaction); + end; + if assigned(avalue) then begin + avalue.database:= self; + end; + ftransactionwrite:= avalue; + end; +end; + + +procedure tcustomsqlconnection.UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); + +begin + //dummy +end; + +procedure tcustomsqlconnection.DoInternalConnect; +begin + if (DatabaseName = '') then + DatabaseError(SErrNoDatabaseName,self); +end; + +procedure tcustomsqlconnection.DoInternalDisconnect; +begin + //dummy +end; + +procedure tcustomsqlconnection.StartTransaction; +begin + if not assigned(Transaction) then + DatabaseError(SErrConnTransactionnSet) + else + Transaction.StartTransaction; +end; + +procedure tcustomsqlconnection.EndTransaction; +begin + if not assigned(Transaction) then + DatabaseError(SErrConnTransactionnSet) + else + Transaction.EndTransaction; +end; + +function tcustomsqlconnection.executedirect(const asql: msestring; + const aisutf8: boolean = false): integer; +begin + result:= executedirect(asql,ftransaction,[],aisutf8); +end; + +function tcustomsqlconnection.internalExecuteDirect(const aSQL: mseString; + ATransaction: TSQLTransaction; + const aparams: tmseparams; aparamvars: array of variant; + aisutf8: boolean; const noprepare: boolean): integer; +var + Cursor: TSQLCursor; + params1: tmseparams; + bo1,bo2: boolean; + int1: integer; +// str1: ansistring; +begin + if atransaction = nil then begin + atransaction:= ftransaction; + end; + bo1:= (aparams = nil) and (high(aparamvars) >= 0); + if bo1 then begin + params1:= tmseparams.create; + params1.parsesql(asql,true); + for int1:= 0 to high(aparamvars) do begin + params1[int1].value:= aparamvars[int1]; + end; + end + else begin + params1:= aparams; + end; + try + if not assigned(ATransaction) then begin + DatabaseError(SErrTransactionnSet); + end; + connected:= true; + if not ATransaction.Active then begin + ATransaction.StartTransaction; + end; + try + Cursor:= AllocateCursorHandle(nil,name); + cursor.ftrans:= atransaction.handle; + if trimright(asql) = '' then begin + DatabaseError(SErrNoStatement); + end; + Cursor.FStatementType := stNone; + if not noprepare then begin + PrepareStatement(cursor,ATransaction,aSQL,params1); + end; + cursor.ftrans:= atransaction.handle; + updateutf8(aisutf8); + if params1 <> nil then begin + bo2:= params1.isutf8; + params1.isutf8:= aisutf8; + end; + try + try + if noprepare then begin + executeunprepared(cursor,atransaction,params1,asql,aisutf8); + end + else begin + execute(cursor,atransaction,params1,aisutf8); + end; + except + atransaction.execerror(); + raise; + end; + result:= cursor.frowsaffected; + finally + UnPrepareStatement(Cursor); + if params1 <> nil then begin + params1.isutf8:= bo2; + end; + end; + finally; + DeAllocateCursorHandle(Cursor); + end; + finally + if bo1 then begin + params1.free; + end; + end; +end; + +function tcustomsqlconnection.ExecuteDirect(const aSQL: mseString; + ATransaction: TSQLTransaction; + const aparams: tmseparams = nil; + const aisutf8: boolean = false; + const anoprepare: boolean = false): integer; +begin + result:= internalexecutedirect(asql,atransaction,aparams,[],aisutf8, + anoprepare and not (sco_nounprepared in fconnoptions)); +end; + +function tcustomsqlconnection.ExecuteDirect(const aSQL: mseString; + ATransaction: TSQLTransaction; + const aparams: array of variant; + const aisutf8: boolean = false; + const anoprepare: boolean = false): integer; +begin + result:= internalexecutedirect(asql,atransaction,nil,aparams,aisutf8, + anoprepare and not (sco_nounprepared in fconnoptions)); +end; + +procedure tcustomsqlconnection.GetDBInfo(const SchemaType: TSchemaType; + const SchemaObjectName, ReturnField : string; + out list: msestringarty); +var + res: tsqlresult; + col1: tdbcol; + int1: integer; +begin + if not assigned(Transaction) then begin + DatabaseError(SErrConnTransactionnSet); + end; + res:= tsqlresult.create(nil); + try + with res do begin + database:= Self; + sql.text:= GetSchemaInfoSQL(SchemaType, msestring(SchemaObjectName), ''); + active:= true; + col1:= datacols.colbyname(returnfield); + if rowsreturned >= 0 then begin + setlength(list,rowsreturned); + end + else begin + list:= nil; + end; + int1:= 0; + while not eof do begin + if high(list) < int1 then begin + setlength(list,2*high(list)+18); + end; + list[int1]:= col1.asmsestring; + inc(int1); + next; + end; + end; + setlength(list,int1); + finally + res.free; + end; +end; + +(* +procedure tcustomsqlconnection.GetDBInfo(const SchemaType : TSchemaType; + const SchemaObjectName, ReturnField : string; List: TStrings); + +var + qry: TSQLQuery; + +begin + if not assigned(Transaction) then + DatabaseError(SErrConnTransactionnSet); + + qry := TSQLQuery.Create(nil); + qry.transaction := Transaction; + qry.database := Self; + with qry do + begin + ParseSQL := False; + SetSchemaInfo(SchemaType,SchemaObjectName,''); + open; + List.Clear; + while not eof do + begin + List.Append(fieldbyname(ReturnField).asstring); + Next; + end; + end; + qry.free; +end; +*) + +procedure tcustomsqlconnection.GetTableNames(out List: msestringarty; + SystemTables: Boolean); +begin + if not systemtables then GetDBInfo(stTables,'','table_name',List) + else GetDBInfo(stSysTables,'','table_name',List); +end; + +procedure tcustomsqlconnection.GetProcedureNames(out List: msestringarty); +begin + GetDBInfo(stProcedures,'','proc_name',List); +end; + +procedure tcustomsqlconnection.GetFieldNames(const TableName: string; + out List: msestringarty); +begin + GetDBInfo(stColumns,TableName,'column_name',List); +end; + +function tcustomsqlconnection.GetAsSQLText(const Field: TField): msestring; +begin + result:= msedb.fieldtosql(field); +end; + +function tcustomsqlconnection.GetAsSQLText(const Param: TParam): msestring; +begin + result:= msedb.paramtosql(param); +end; + + +function tcustomsqlconnection.GetHandle: pointer; +begin + Result := nil; +end; + +procedure tcustomsqlconnection.Execute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; + const AParams : TmseParams; const autf8: boolean); +begin + if aparams <> nil then begin + aparams.updatevalues; + end; + beforeaction; + try + try + internalexecute(cursor,atransaction,aparams,autf8); + except + atransaction.execerror(); + raise; + end; + finally + afteraction; + end; +end; + +procedure tcustomsqlconnection.internalexecuteunprepared( + const cursor: tsqlcursor; const atransaction: tsqltransaction; + const asql: string; const origsql: msestring; + const aparams: tmseparams); +begin + raise edatabaseerror.create(name+': executeunprepared not supported.'); +end; + +procedure tcustomsqlconnection.Executeunprepared(const cursor: TSQLCursor; + const atransaction: tsqltransaction; + const AParams : TmseParams; + const asql: msestring; const autf8: boolean); +var + mstr1: msestring; + str1: ansistring; + par1: tmseparams; +begin + if aparams <> nil then begin + aparams.updatevalues; + end; + beforeaction; + try + par1:= nil; + if (aparams <> nil) and (aparams.count > 0) then begin +// if dbf_params in getfeatures then begin + if sco_forceparams in fconnoptions then begin + par1:= aparams; //asql used directly + end + else begin + mstr1:= aparams.expandvalues(asql); + end; + end + else begin + mstr1:= asql; + end; + if mstr1 <> '' then begin + if autf8 then begin + str1:= stringtoutf8ansi(mstr1); + end + else begin + str1:= ansistring(mstr1); + end; + end; + try + internalexecuteunprepared(cursor,atransaction,str1,asql,par1); + except + atransaction.execerror(); + raise; + end; + finally + afteraction; + end; +end; + +function tcustomsqlconnection.GetSchemaInfoSQL( SchemaType : TSchemaType; + SchemaObjectName, SchemaPattern : msestring) : msestring; + +begin + result:= ''; //compiler warning + DatabaseError(SMetadataUnavailable); +end; + +function tcustomsqlconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; + +begin + result:= nil; //compiler warning + DatabaseErrorFmt(SUnsupportedFieldType,['Blob']); +end; + +procedure tcustomsqlconnection.closeds(out activeds: integerarty); +var + int1: integer; +begin + setlength(activeds,length(datasets)); + for int1:= 0 to high(activeds) do begin + with datasets[int1] do begin + if getactive then begin + activeds[int1]:= datasets[int1].getrecno; + setactive(false); + end + else begin + activeds[int1]:= -2; + end; + end; + end; +end; + +procedure tcustomsqlconnection.reopends(const activeds: integerarty); +var + int1: integer; +begin + for int1:= 0 to high(activeds) do begin + if activeds[int1] >= -1 then begin + with datasets[int1] do begin + setactive(true); + disablecontrols; + if activeds[int1] >= 0 then begin + try + moveby(maxint); + setrecno(activeds[int1]); + except + end; + end; + enablecontrols; + end; + end; + end; +end; +{ +function tcustomsqlconnection.getconnected: boolean; +begin + result:= inherited connected; +end; +} +procedure tcustomsqlconnection.doafterinternalconnect; +begin + inherited; + if fafterconnect <> nil then begin + fafterconnect.execute(self); + end; +end; + +procedure tcustomsqlconnection.dobeforeinternaldisconnect; +var + int1: integer; +begin + if fbeforedisconnect <> nil then begin + fbeforedisconnect.execute(self); + end; + for int1:= high(datasets) downto 0 do begin + with datasets[int1] do begin + if (gettransaction = nil) or (gettransaction.active) then begin + setactive(false); //not disconnected + end; + end; + end; + { + for int1:= datasetcount - 1 downto 0 do begin + with tsqlquery(datasets[int1]) do begin + if (transaction = nil) or (transaction.active) then begin + close; //not disconnected + end; + end; + end; + } +end; +{ +procedure tcustomsqlconnection.setconnected(const avalue: boolean); +var + int1: integer; + bo1: boolean; +begin + if avalue <> fconnected then begin + if avalue then begin + if csreading in componentstate then begin + fopenafterread:= true; + exit; + end + else begin + if assigned(onbeforeconnect) then begin + onbeforeconnect(self); + end; + try + dointernalconnect; + doafterinternalconnect; + if assigned(onafterconnect) then begin + onafterconnect(self); + end; + except + on e: exception do begin + if assigned(onconnecterror) then begin + bo1:= false; + onconnecterror(self,e,bo1); + if not bo1 then begin + raise; + end + else begin + if not connected then begin + abort; + end; + end; + end + else begin + raise; + end; + end; + end; + end; + end + else begin + if assigned(onbeforedisconnect) then begin + onbeforedisconnect(self); + end; + dobeforeinternaldisconnect; + for int1:= datasetcount - 1 downto 0 do begin + with tsqlquery(datasets[int1]) do begin + if (transaction = nil) or (transaction.active) then begin + close; //not disconnected + end; + end; + end; + closetransactions; + dointernaldisconnect; + if csloading in componentstate then begin + fopenafterread := false; + end; + end; + fconnected:= avalue; + end; +end; +} +procedure tcustomsqlconnection.setafteconnect(const avalue: tmsesqlscript); +begin + if fafterconnect <> nil then begin + fafterconnect.removefreenotification(self); + end; + fafterconnect:= avalue; + if fafterconnect <> nil then begin + fafterconnect.freenotification(self); + end; +end; + +procedure tcustomsqlconnection.setbeforedisconnect(const avalue: tmsesqlscript); +begin + if fbeforedisconnect <> nil then begin + fbeforedisconnect.removefreenotification(self); + end; + fbeforedisconnect:= avalue; + if fbeforedisconnect <> nil then begin + fbeforedisconnect.freenotification(self); + end; +end; + +procedure tcustomsqlconnection.notification(acomponent: tcomponent; + operation: toperation); +//var +// int1: integer; +begin + if operation = opremove then begin + if acomponent = fafterconnect then begin + fafterconnect:= nil; + end; + if acomponent = fbeforedisconnect then begin + fbeforedisconnect:= nil; + end; + { + int1:= finditem(pointerarty(fdatasets1),acomponent); + if int1 >= 0 then begin + fdatasets1[int1]:= nil; + end; + } + end; + inherited; +end; + +procedure tcustomsqlconnection.Close; +begin + connected:= false; +end; + +procedure tcustomsqlconnection.Open; +begin + connected:= true; +end; + +procedure tcustomsqlconnection.updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); +begin + //dummy +end; + +function tcustomsqlconnection.getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; +begin + result:= ''; +end; + +function tcustomsqlconnection.getnumboolean: boolean; +begin + result:= true; +end; + +function tcustomsqlconnection.getfloatdate: boolean; +begin + result:= false; +end; + +function tcustomsqlconnection.getint64currency: boolean; +begin + result:= false; +end; + +function tcustomsqlconnection.getinsertid(const atransaction: tsqltransaction): int64; +begin + databaseerror('Connection has no insert ID''s.'); + result:= 0; //compiler warning +end; +{ +procedure tcustomsqlconnection.closeds; +var + int1: integer; +begin + setlength(fdatasets1,datasetcount); + setlength(frecnos,length(fdatasets1)); + for int1:= high(fdatasets1) downto 0 do begin + fdatasets1[int1]:= datasets[int1]; + with fdatasets1[int1] do begin + freenotification(self); + if active then begin + frecnos[int1]:= recno; + end + else begin + frecnos[int1]:= -2; + end; + end; + end; + for int1:= high(fdatasets1) downto 0 do begin + if (fdatasets1[int1] <> nil) and + (tmdbdataset(fdatasets1[int1]).database = self) then begin + with fdatasets1[int1] do begin + active:= false; + end; + end; + end; +end; + +procedure tcustomsqlconnection.reopends; +var + int1: integer; +begin + for int1:= 0 to high(fdatasets1) do begin + if fdatasets1[int1] <> nil then begin + if frecnos[int1] >= -1 then begin + with tmdbdataset(fdatasets1[int1]) do begin + if database = self then begin + disablecontrols; + active:= true; + if frecnos[int1] >= 0 then begin + try + moveby(frecnos[int1]-recno); + except + end; + end; + enablecontrols; + end; + end; + end; + end; + end; +end; +} +procedure tcustomsqlconnection.CommitRetaining(trans: TSQLHandle); +begin + internalcommitretaining(trans); + { + if sco_emulateretaining in fconnoptions then begin + closeds; //cursors are lost + try + try + internalcommitretaining(trans); + finally + reopends; + end; + finally + fdatasets1:= nil; + frecnos:= nil; + end; + end + else begin + internalcommitretaining(trans); + end; + } +end; + +procedure tcustomsqlconnection.RollBackRetaining(trans: TSQLHandle); +begin + internalrollbackretaining(trans); +{ + if sco_emulateretaining in fconnoptions then begin + closeds; //cursors are lost + try + try + internalrollbackretaining(trans); + finally + reopends; + end; + finally + fdatasets1:= nil; + frecnos:= nil; + end; + end + else begin + internalrollbackretaining(trans); + end; +} +end; + +procedure tcustomsqlconnection.finalizetransaction(const atransaction: tsqlhandle); +begin + //dummy +end; + +function tcustomsqlconnection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +begin + raise edatabaseerror.create(name+': fetchblob not supported.'); + result:= ''; //compiler warning +end; + +function tcustomsqlconnection.todbstring(const avalue: msestring): string; +begin + if isutf8 then begin + result:= stringtoutf8ansi(avalue); + end + else begin + result:= ansistring(avalue); + end; +end; + +function tcustomsqlconnection.tomsestring(const avalue: string): msestring; +begin + if isutf8 then begin + result:= utf8tostring(avalue); + end + else begin + result:= msestring(avalue); + end; +end; + +function tcustomsqlconnection.identquotechar: msestring; +begin + result:= '"'; +end; + +procedure tcustomsqlconnection.beginupdate; +begin + //dummy +end; + +procedure tcustomsqlconnection.endupdate; +begin + //dummy +end; + +function tcustomsqlconnection.fieldtosql(const afield: tfield): msestring; +begin + result:= getassqltext(afield); +end; + +function tcustomsqlconnection.fieldtooldsql(const afield: tfield): msestring; +var + statebefore: tdatasetstate; +begin + statebefore:= afield.dataset.state; + tdataset1(afield.dataset).settempstate(dsoldvalue); + result:= fieldtosql(afield); + tdataset1(afield.dataset).restorestate(statebefore); +end; + +function tcustomsqlconnection.paramtosql(const aparam: tparam): msestring; +begin + result:= getassqltext(aparam); +end; + +procedure tcustomsqlconnection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +{ TSQLTransaction } + +constructor TSQLTransaction.Create(AOwner : TComponent); +begin + fsavepointlevel:= -1; + inherited Create(AOwner); + FParams := TStringList.Create; +end; + +destructor TSQLTransaction.Destroy; +var + bo1: boolean; +begin + bo1:= active; + Rollback; + if not bo1 then begin + closedatasets; //close disconnected + end; + inherited Destroy; + FreeAndNil(FParams); + freeandnil(ftrans); +end; + +procedure TSQLTransaction.StartTransaction; +var + db: tcustomsqlconnection; + int1: integer; +begin + if Active then begin + DatabaseError(SErrTransAlreadyActive); + end; + db:= tcustomsqlconnection(database); + if Db = nil then begin + DatabaseError(SErrDatabasenAssigned); + end; + inc(fstartcount); + int1:= fstartcount; + if checkcanevent(self,tmethod(fonbeforestart)) then begin + fonbeforestart(self); + end; + if not Db.Connected then begin + Db.Open; + end; + if (int1 <> fstartcount) or not db.connected then begin + exit; + end; + if not assigned(FTrans) then begin + FTrans:= Db.AllocateTransactionHandle; + end; + if (tao_fake in foptions) or + Db.StartdbTransaction(FTrans,FParams) then begin + OpenTrans; + end; + if checkcanevent(self,tmethod(fonafterstart)) then begin + fonafterstart(self); + end; +end; + +procedure tsqltransaction.doendtransaction( + const aaction: tcommitrollbackaction); +begin + case aaction of + cacommit: commit; + cacommitretaining: commitretaining; + carollbackretaining: rollbackretaining; + else rollback; //canone,carollback + end; +end; + +procedure tsqltransaction.endtransaction; + +begin + doendtransaction(faction); +end; + +procedure tsqltransaction.refresh(aaction: tcommitrollbackaction = canone); + //canone -> action property + //closes transaction, calls refreshdatasets +var + int1: integer; +begin + int1:= bigint; + while true do begin + if int1 > high(fdatasets) then begin + int1:= high(fdatasets); + end; + if int1 < 0 then begin + break; + end; + if fdatasets[int1].getactive then begin + fdatasets[int1].checkbrowsemode; + end; + dec(int1); + end; + int1:= bigint; + while true do begin + if int1 > high(fwritedatasets) then begin + int1:= high(fwritedatasets); + end; + if int1 < 0 then begin + break; + end; + if fwritedatasets[int1].getactive then begin + fwritedatasets[int1].checkbrowsemode; + end; + dec(int1); + end; + if aaction = canone then begin + aaction:= action; + end; +// if aaction in [cacommit,cacommitretaining] then begin +// aaction:= cacommitretaining; +// end +// else begin +// aaction:= carollbackretaining; +// end; + try +// inc(fcloselock); +// try + begintrackactivestate; + try + doendtransaction(aaction); +// finally +// dec(fcloselock); +// end; + if not active then begin + starttransaction; + int1:= bigint; + while true do begin + if int1 > high(fdatasetsactive) then begin + int1:= high(fdatasetsactive); + end; + if int1 < 0 then begin + break; + end; + if fdatasetsactive[int1] then begin + fdatasets[int1].setactive(true); + end; + dec(int1); + end; + int1:= bigint; + while true do begin + if int1 > high(fwritedatasetsactive) then begin + int1:= high(fwritedatasetsactive); + end; + if int1 < 0 then begin + break; + end; + if fwritedatasetsactive[int1] then begin + fwritedatasets[int1].setactive(true); + end; + dec(int1); + end; + end + else begin + if (tao_refreshdatasets in foptions) or (aaction <> cacommit) then begin + refreshdatasets; + end; + end; + finally + endtrackactivestate; + end; + except + closedatasets; + raise; + end; +end; + +function TSQLTransaction.GetHandle: pointer; +begin + Result := (Database as tcustomsqlconnection).GetTransactionHandle(FTrans); +end; + +function tsqltransaction.docommit(const retaining: boolean): boolean; + + procedure dofinish; + begin + if retaining then begin + if tao_fakeretaining in foptions then begin + closetrans(); + starttransaction(); + end; + if (tao_refreshdatasets in foptions) then begin + refreshdatasets(true,true); + end; + end + else begin + closetrans; + closedatasets; + end; + end; + +var + bo1: boolean; +begin + result:= false; + if not (tao_fake in foptions) then begin + try + if retaining and not (tao_fakeretaining in foptions) then begin + tcustomsqlconnection(database).commitretaining(FTrans); + end + else begin + tcustomsqlconnection(database).commit(FTrans); + end; + savepointevent(spek_committrans,0); + except + on e: exception do begin + bo1:= false; + if checkcanevent(self,tmethod(foncommiterror)) then begin + foncommiterror(self,e,bo1); + end; + if not bo1 then begin + if tao_catcherror in foptions then begin + application.handleexception(self); + exit; + end + else begin + if tao_rollbackonerror in foptions then begin + try + rollback(); + except //no secondary exceptions + end; + raise; + end; + dofinish(); + raise; + end; + end; + end; + end; + end + else begin + savepointevent(spek_committrans,0); + end; + fsavepointlevel:= -1; + dofinish; + result:= true; +end; + +function TSQLTransaction.Commit(const checksavepoint: boolean = true): boolean; +begin + result:= true; + if active then begin + if checksavepoint and (fsavepointlevel >= 0) then begin + pendingaction:= cacommit; + exit; + end; + dobeforestop; + if checkcanevent(self,tmethod(fonbeforecommit)) then begin + fonbeforecommit(self); + end; + result:= docommit(false); + if result and checkcanevent(self,tmethod(fonaftercommit)) then begin + fonaftercommit(self); + end; + doafterstop; + end; +end; + +function TSQLTransaction.CommitRetaining( + const checksavepoint: boolean = true): boolean; +begin + result:= true; + if active then begin + if checksavepoint and (fsavepointlevel >= 0) then begin + pendingaction:= cacommitretaining; + exit; + end; + if checkcanevent(self,tmethod(fonbeforecommitretaining)) then begin + fonbeforecommitretaining(self); + end; + result:= docommit(true); + if result and checkcanevent(self,tmethod(fonaftercommitretaining)) then begin + fonaftercommitretaining(self); + end; + end; +end; + +procedure TSQLTransaction.Rollback; +begin + if active then begin + dobeforestop; + if checkcanevent(self,tmethod(fonbeforerollback)) then begin + fonbeforerollback(self); + end; + savepointevent(spek_rollbacktrans,0); + closedatasets; + try + if not (tao_fake in foptions) then begin + tcustomsqlconnection(database).RollBack(FTrans); + end; + finally + fsavepointlevel:= -1; + CloseTrans; + if checkcanevent(self,tmethod(fonafterrollback)) then begin + fonafterrollback(self); + end; + doafterstop; + end; + end; +end; + +procedure TSQLTransaction.RollbackRetaining; +begin + if active then begin + if checkcanevent(self,tmethod(fonbeforerollbackretaining)) then begin + fonbeforerollback(self); + end; + try + if not (tao_fake in foptions) then begin + if tao_fakeretaining in foptions then begin + tcustomsqlconnection(database).rollback(ftrans); + closetrans(); + starttransaction(); + end + else begin + tcustomsqlconnection(database).rollbackretaining(ftrans); + end; + end; + savepointevent(spek_rollbacktrans,0); + finally + fsavepointlevel:= -1; + end; + refreshdatasets(); + if checkcanevent(self,tmethod(fonafterrollbackretaining)) then begin + fonafterrollback(self); + end; + end; +end; + +procedure tsqltransaction.disconnect(const sender: itransactionclient; + const auxclients: integer); +//var +// int1: integer; +// intf1: itransactionclient; +// k1: tupdatekind; +begin +{ + int1:= 1; + if (self = sender.getwritetransaction) then begin + for k1:= low(tupdatekind) to high(tupdatekind) do begin + if sender.fapplyqueries[k1] <> nil then begin + inc(int1); + end; + end; +} + { + if sender.fupdateqry <> nil then begin + inc(int1); + end; + if sender.fdeleteqry <> nil then begin + inc(int1); + end; + if sender.finsertqry <> nil then begin + inc(int1); + end; + } +// end; + if high(fdatasets) > auxclients then begin + databaseerror('Offline mode needs exclusive transaction.', + sender.getcomponentinstance); + end; +// intf1:= itransactionclient(sender); + removeitem(pointerarty(fdatasets),pointer(sender)); + try + active:= false; + finally + insertitem(pointerarty(fdatasets),0,pointer(sender)); + end; + { + if fdatasets.count > int1 then begin + databaseerror('Offline mode needs exclusive transaction.',sender); + end; + fdatasets.remove(sender); + try + active:= false; + finally + fdatasets.insert(0,sender); + end; + } +end; + +Procedure TSQLTransaction.SetDatabase(Value : tmdatabase); + +begin + If Value <> Database then begin + CheckInactive; + If Assigned(Database) then begin + finalizetransaction; + with tcustomsqlconnection(database) do begin + if Transaction = self then begin + Transaction:= nil; + end; + if Transactionwrite = self then begin + Transactionwrite:= nil; + end; + end; + end; + inherited SetDatabase(Value); + end; +end; + +function tsqltransaction.getdatabase: tcustomsqlconnection; +begin + result:= tcustomsqlconnection(inherited database); +end; + +procedure tsqltransaction.setdatabase1(const avalue: tcustomsqlconnection); +begin + setdatabase(avalue); +end; + +procedure TSQLTransaction.setparams(const avalue: TStringList); +begin + fparams.assign(avalue); +end; + +procedure TSQLTransaction.finalizetransaction; +begin + if (database <> nil) and (ftrans <> nil) then begin + tsqlconnection(database).finalizetransaction(ftrans); + end; +end; + +function TSQLTransaction.savepointbegin: integer; +var + mstr1: msestring; +begin + active:= true; + inc(fsavepointlevel); + result:= fsavepointlevel; + mstr1:= 'sp'+inttostrmse(result); + database.executedirect('SAVEPOINT '+mstr1+';',self,nil,false,true); + savepointevent(spek_begin,result); +end; + +procedure tsqltransaction.checkpendingaction; +var + act1: tcommitrollbackaction; + bo1: boolean; +begin + if (fpendingaction <> canone) and (fsavepointlevel < 0) and active then begin + act1:= fpendingaction; + bo1:= fpendingrefresh; + fpendingaction:= canone; + fpendingrefresh:= false; + if bo1 then begin + refresh(act1); + end + else begin + doendtransaction(act1); + end; + end; +end; + +procedure TSQLTransaction.savepointrollback(alevel: integer = -1); +begin + checkactive; + if alevel = -1 then begin + alevel:= fsavepointlevel; + end; + if alevel >= 0 then begin + database.executedirect('ROLLBACK TO '+'sp'+inttostrmse(alevel)+';', + self,nil,false,true); + fsavepointlevel:= alevel-1; + savepointevent(spek_rollback,alevel); + checkpendingaction; + end; +end; + +procedure TSQLTransaction.savepointrelease; +begin + checkactive; + if fsavepointlevel >= 0 then begin + database.executedirect('RELEASE SAVEPOINT '+'sp'+ + inttostrmse(fsavepointlevel)+';',self,nil,false,true); + dec(fsavepointlevel); + savepointevent(spek_release,fsavepointlevel+1); + checkpendingaction; + end; +end; + +procedure TSQLTransaction.dobeforestop; +begin + if checkcanevent(self,tmethod(fonbeforestop)) then begin + fonbeforestop(self); + end; +end; + +procedure TSQLTransaction.doafterstop; +begin + if checkcanevent(self,tmethod(fonafterstop)) then begin + fonafterstop(self); + end; +end; + +procedure TSQLTransaction.setpendingaction(const avalue: tcommitrollbackaction); +begin + fpendingaction:= avalue; + if not (avalue in [cacommitretaining,carollbackretaining]) then begin + fpendingrefresh:= false; + end; +end; + +procedure TSQLTransaction.CloseTrans; +begin + inherited; + freeandnil(ftrans); +end; + +procedure TSQLTransaction.savepointevent(const akind: savepointeventkindty; + const alevel: integer); +var + int1: integer; +begin + int1:= bigint; + while true do begin + if int1 > high(fdatasets) then begin + int1:= high(fdatasets); + end; + if int1 < 0 then begin + break; + end; + if fdatasets[int1].getactive then begin + fdatasets[int1].savepointevent(self,akind,alevel); + end; + dec(int1); + end; + int1:= bigint; + while true do begin + if int1 > high(fwritedatasets) then begin + int1:= high(fwritedatasets); + end; + if int1 < 0 then begin + break; + end; + if fwritedatasets[int1].getactive then begin + fwritedatasets[int1].savepointevent(self,akind,alevel); + end; + dec(int1); + end; +end; + +procedure TSQLTransaction.execerror(); +begin + if (tao_rollbackonerror in foptions) and active then begin + try + rollback(); + except //no secondary exceptions + end; + end; +end; + + +{ TSQLCursor } + +constructor TSQLCursor.create(const aowner: icursorclient; const aname: ansistring); +begin + fowner:= aowner; + fname:= aname; + frowsaffected:= -1; + frowsreturned:= -1; + inherited create; +end; + +function TSQLCursor.addblobdata(const adata: pointer; + const alength: integer): integer; +begin + if fowner = nil then begin + result:= fblobcount; + inc(fblobcount); + if result > high(fblobs) then begin + setlength(fblobs,2*result+256); + end; + setlength(fblobs[result],alength); + {$ifdef FPC} {$checkpointer off} {$endif} //adata can be foreign memory + move(adata^,fblobs[result][1],alength); + {$ifdef FPC} {$checkpointer default} {$endif} + end + else begin + result:= fowner.addblobcache(adata,alength); + end; +end; + +function TSQLCursor.addblobdata(const adata: string): integer; +begin + result:= addblobdata(pointer(adata),length(adata)); +end; + +procedure TSQLCursor.addblobcache(const aid: int64; const adata: string); +begin + fowner.addblobcache(aid,adata); +end; + +procedure TSQLCursor.blobfieldtoparam(const afield: tfield; + const aparam: tparam; const asstring: boolean = false); +var + blobid: integer; + str1: string; +begin + if afield.getdata(@blobid) then begin + if fowner = nil then begin + str1:= fblobs[blobid]; + end + else begin + str1:= fowner.getblobcache[blobid].data; + end; + if asstring then begin + aparam.asstring:= str1; + end + else begin + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + end; + end + else begin + aparam.clear; + end; +end; + +function TSQLCursor.getcachedblob(const blobid: integer): tstream; +begin + if fowner = nil then begin + result:= tstringcopystream.create(fblobs[blobid]); + end + else begin + result:= tstringcopystream.create(fowner.getblobcache[blobid].data); + end; +end; + +procedure TSQLCursor.close; +begin + fblobs:= nil; + fblobcount:= 0; +end; + +function TSQLCursor.wantblobfetch: boolean; +begin + result:= (fowner <> nil) and fowner.blobsarefetched(); +end; + +function TSQLCursor.stringmemo: boolean; +begin + result:= (fowner <> nil) and fowner.stringmemo; +end; + +{ tcustomsqlstatement } + +constructor tcustomsqlstatement.create(aowner: tcomponent); +begin + fparams:= tmseparams.create(self); + fsql:= tsqlstringlist.create; + fsql.onchange:= {$ifdef FPC}@{$endif}dosqlchange; + inherited; +end; + +destructor tcustomsqlstatement.destroy; +begin + database:= nil; + transaction:= nil; + fparams.free; + fsql.free; + inherited; +end; + +procedure tcustomsqlstatement.setsql(const avalue: tsqlstringlist); +begin + fsql.assign(avalue); +end; + +procedure tcustomsqlstatement.setdatabase1(const avalue: tcustomsqlconnection); +begin + setdatabase(avalue); +end; + +procedure tcustomsqlstatement.setparams(const avalue: tmseparams); +begin + fparams.assign(avalue); +end; + +procedure tcustomsqlstatement.dobeforeexecute(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction); +begin + if canevent(tmethod(fonbeforeexecute)) then begin + fonbeforeexecute(self,adatabase,atransaction); + end; +end; + +procedure tcustomsqlstatement.doafterexecute(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction); +begin + if canevent(tmethod(fonafterexecute)) then begin + fonafterexecute(self,adatabase,atransaction); + end; +end; + +procedure tcustomsqlstatement.doerror(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction; const e: exception; + var handled: boolean); +begin + if canevent(tmethod(fonerror)) then begin + fonerror(self,adatabase,atransaction,e,handled); + end; +end; + +procedure tcustomsqlstatement.dosqlchange(const sender: tobject); +begin + fparams.parsesql(fsql.text,true); +end; + +procedure tcustomsqlstatement.settransaction1(const avalue: tsqltransaction); +begin + settransaction(avalue); +end; + +function tcustomsqlstatement.getname: string; +begin + result:= name; +end; + +function tcustomsqlstatement.getactive: boolean; +begin + result:= false; +end; + +function tcustomsqlstatement.getdatabase: tcustomconnection; + //for isqlpropertyeditor +begin + result:= fdatabase; +end; + +procedure tcustomsqlstatement.setactive(avalue: boolean); +begin + //dummy +end; + +procedure tcustomsqlstatement.settransaction(const avalue: tmdbtransaction); +begin + dosettransaction(itransactionclient(self),avalue, + tmdbtransaction(ftransaction),false); +end; + +procedure tcustomsqlstatement.settransactionwrite(const avalue: tmdbtransaction); +begin + //dummy +end; + +procedure tcustomsqlstatement.refreshtransaction; +begin + //dummy +end; + +procedure tcustomsqlstatement.setdatabase(const avalue: tmdatabase); +var + intf1: idbcontroller; + bo1: boolean; +begin + dosetdatabase(idatabaseclient(self),avalue,tmdatabase(fdatabase)); + if (avalue <> nil) then begin + if (ftransaction = nil) then begin + transaction:= tsqlconnection(avalue).transaction; + end; + if mseclasses.getcorbainterface( + database,typeinfo(idbcontroller),intf1) then begin + bo1:= sso_utf8 in foptions; + intf1.updateutf8(bo1); + if bo1 then begin + foptions:= foptions + [sso_utf8]; + end + else begin + foptions:= foptions - [sso_utf8]; + end; + end; + end; +end; + +function tcustomsqlstatement.isutf8: boolean; +begin + result:= sso_utf8 in foptions; +end; +{ +function tcustomsqlstatement.isutf8(const adatabase): boolean; +begin + result:= sso_utf8 in foptions; +end; +} +procedure tcustomsqlstatement.setoptions(const avalue: sqlstatementoptionsty); +const + mask: sqlstatementoptionsty = [sso_autocommit,sso_autocommitret]; +begin + if foptions <> avalue then begin + foptions:= sqlstatementoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + end; +end; + +function tcustomsqlstatement.gettransaction: tmdbtransaction; +begin + result:= ftransaction; +end; + +function tcustomsqlstatement.getrecno: integer; +begin + result:= -1; +end; + +procedure tcustomsqlstatement.setrecno(value: integer); +begin + //dummy +end; + +procedure tcustomsqlstatement.disablecontrols; +begin + //dummy +end; + +procedure tcustomsqlstatement.enablecontrols; +begin + //dummy +end; + +function tcustomsqlstatement.moveby(distance: longint): longint; +begin + result:= 0; +end; + +procedure tcustomsqlstatement.checkbrowsemode; +begin + //dummy +end; + +procedure tcustomsqlstatement.savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); +begin + //dummy +end; + +{ tmsesqlscript } + +constructor tmsesqlscript.create(aowner: tcomponent); +begin + fterm:= ';'; + inherited; +end; + +procedure tmsesqlscript.execute(adatabase: tcustomsqlconnection = nil; + atransaction: tsqltransaction = nil); +var + str1: msestring; + ar1: msestringarty; + int1,int2: integer; + bo1: boolean; +begin + if adatabase = nil then begin + adatabase:= fdatabase; + end; + if atransaction = nil then begin + atransaction:= ftransaction; + end; + if adatabase = nil then begin + databaseerror(serrdatabasenassigned,self); + end; + if sso_savepoint in foptions then begin + int2:= atransaction.savepointbegin; + end; + try + dobeforeexecute(adatabase,atransaction); + updateparams(fparams,isutf8{(adatabase)}); + str1:= fsql.text; + ar1:= splitsql(str1,fterm,fcharescapement); + fstatementcount:= length(ar1); + if high(ar1) < 0 then begin + databaseerror(serrnostatement,self); + end; + for int1:= 0 to high(ar1) do begin + fstatementnr:= int1; + if canevent(tmethod(fonbeforestatement)) then begin + fonbeforestatement(self); + end; + try + adatabase.executedirect(ar1[int1],atransaction,fparams,isutf8, + sso_noprepare in foptions); + except + on e: exception do begin + bo1:= false; + doerror(adatabase,atransaction,e,bo1); + if not bo1 then begin + raise; + end; + end; + end; + if canevent(tmethod(fonafterstatement)) then begin + fonafterstatement(self); + end; + end; + if sso_autocommit in foptions then begin + atransaction.commit; + end + else begin + if sso_autocommitret in foptions then begin + atransaction.commitretaining; + end; + end; + doafterexecute(adatabase,atransaction); + if sso_savepoint in foptions then begin + atransaction.savepointrelease; + end; + except + if sso_savepoint in foptions then begin + atransaction.savepointrollback(int2); + end; + raise; + end; +end; + +procedure tmsesqlscript.execute; +begin + execute(nil,nil); +end; + +{ tcursorsqlstatement } + +constructor tcursorsqlstatement.create(aowner: tcomponent); +begin + inherited; +end; + +destructor tcursorsqlstatement.destroy; +begin + internalclose; +// setactive(false); + inherited; +end; + +procedure tcursorsqlstatement.internalclose; +begin + unprepare; + if fcursor <> nil then begin + fdatabase.deallocatecursorhandle(fcursor); + end; +end; + +procedure tcursorsqlstatement.dosqlchange(const sender: tobject); +begin + unprepare; + inherited; +end; + +procedure tcursorsqlstatement.prepare; +var + mstr1: msestring; +begin + if (fcursor = nil) or not fcursor.fprepared then begin + checkdatabase(name,fdatabase); + checktransaction(name,ftransaction); + mstr1:= trim(fsql.text); + if mstr1 = '' then begin + raise edatabaseerror.create(name+': Empty query.'); + end; + if not fdatabase.Connected then begin + fdatabase.Open; + end; + if not ftransaction.Active then begin + ftransaction.StartTransaction; + end; + if not assigned(fcursor) then begin + FCursor:= fdatabase.AllocateCursorHandle(nil,name); + end; + fcursor.ftrans:= ftransaction.handle; + fcursor.fstatementtype:= fstatementtype; + if not (sso_noprepare in foptions) then begin + fdatabase.PrepareStatement(Fcursor,ftransaction,mstr1,FParams); +// fcursor.fprepared:= true; + end; + end; +end; + +function tcursorsqlstatement.isprepared: boolean; +begin + result:= (fcursor <> nil) and fcursor.fprepared; +end; + +procedure tcursorsqlstatement.unprepare; +begin + if (fcursor <> nil) and fcursor.fprepared then begin + fdatabase.unpreparestatement(fcursor); + //fcursor.fprepared:= false; + end; +end; + +procedure tcursorsqlstatement.checkautocommit; +begin + if not (csdesigning in componentstate) then begin + if sso_autocommit in foptions then begin + ftransaction.commit; + end + else begin + if sso_autocommitret in foptions then begin + ftransaction.commitretaining; + end; + end; + end; +end; + +procedure tcursorsqlstatement.execute; +var + bo1: boolean; +begin + dobeforeexecute(fdatabase,ftransaction); + prepare; + updateparams(fparams,isutf8); + fcursor.ftrans:= tsqltransaction(ftransaction).handle; + try + if sso_noprepare in foptions then begin + tcustomsqlconnection(fdatabase).executeunprepared(fcursor, + tsqltransaction(ftransaction),fparams,fsql.text,isutf8); + end + else begin + tcustomsqlconnection(fdatabase).execute(fcursor,tsqltransaction(ftransaction), + fparams,isutf8); + end; +// fcursor.close; + checkautocommit; + doafterexecute(fdatabase,ftransaction); + except + on e: exception do begin + bo1:= false; + doerror(fdatabase,ftransaction,e,bo1); + if not bo1 then begin + raise; + end; + end; + end; +end; + +function tcursorsqlstatement.getactive: boolean; +begin + result:= fcursor <> nil; +end; + +procedure tcursorsqlstatement.setactive(avalue: boolean); +begin + if not avalue then begin + internalclose; + end; +end; + +procedure tcursorsqlstatement.execute(const aparams: array of variant); +var + int1: integer; +begin + for int1:= 0 to high(aparams) do begin + fparams[int1].value:= aparams[int1]; + end; + execute; +end; + +function tcursorsqlstatement.rowsaffected: integer; +begin + if fcursor = nil then begin + result:= -1; + end + else begin + result:= fcursor.frowsaffected; + end; +end; + +{ econnectionerror } + +constructor econnectionerror.create(const asender: tcustomsqlconnection; + const amessage: ansistring; const aerrormessage: msestring; + const aerror: integer); +begin + fsender:= sender; + ferror:= aerror; + ferrormessage:= aerrormessage; + if asender <> nil then begin + inherited create(asender.name+': '+amessage); + end + else begin + inherited create(amessage); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/mysqldyn.pas b/mseide-msegui/lib/common/db/mysqldyn.pas new file mode 100644 index 0000000..c7b6a93 --- /dev/null +++ b/mseide-msegui/lib/common/db/mysqldyn.pas @@ -0,0 +1,2297 @@ +{ + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{ + This file is created by H2Pas, and thereafter heavily edited to make it + readable and dynamically loadable. + + The goal was not to be complete, but to make it work and maintainable. + + The mysql_com.h, mysql.h and some other files are merged together into this + one file. + + Automatically converted by H2Pas 1.0.0 from mysql_com.h / mysql.h + The following command line parameters were used: + -p + -D + -l + mysqlclient + mysql_com.h / mysql.h + +Modified 2008..2009 by Martin Schreiber + +} +unit mysqldyn; + +{$DEFINE LinkDynamically} + +{$DEFINE mysql51} + +{$ifdef mysql51} + {$define mysql50} +{$endif} +{$IFDEF mysql50} + {$DEFINE mysql41} +{$ENDIF mysql50} +{$ifdef FPC}{$MODE objfpc}{$MACRO on}{$endif} + +interface + +uses +{$IFDEF LinkDynamically} + sysutils, +{$ENDIF} + {$ifdef FPC}dynlibs,{$endif}msectypes,msetypes{msestrings}; + +const +{$ifdef mswindows} + mysqllib: array[0..0] of filenamety = ('libmysql.dll'); +{$else} + mysqllib: array[0..3] of filenamety = ('libmysqlclient.so.18', + 'libmysqlclient.so.16','libmysqlclient.so.15','libmysqlclient.so'); +{$endif} + +procedure initializemysql(const sonames: array of filenamety); + //[] = default +procedure releasemysql; + +{$IFDEF Unix} +// {$DEFINE extdecl:=cdecl} +(* + const + mysqllib = 'libmysqlclient.'+sharedsuffix; + + {$IF DEFINED(mysql50)} + mysqlvlib = 'libmysqlclient.'+sharedsuffix+'.15'; + {$ELSEIF DEFINED(mysql41)} + mysqlvlib = 'libmysqlclient.'+sharedsuffix+'.14'; + {$ELSE} + mysqlvlib = 'libmysqlclient.'+sharedsuffix+'.12'; + {$ENDIF} +*) +{$ENDIF} +{$IFDEF msWindows} +// {$DEFINE extdecl:=stdcall} + {$define wincall} +(* + const + mysqllib = 'libmysql.dll'; + mysqlvlib = 'libmysql.dll'; +*) +{$ENDIF} + +{$ifdef FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} + + { Copyright (C) 2000-2003 MySQL AB + + 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 } + + type +// my_bool = cchar; + my_bool = byte; + Pmy_bool = ^my_bool; + + PVIO = Pointer; + + Pgptr = ^gptr; + gptr = ^cchar; + + Pmy_socket = ^my_socket; + my_socket = cint; + + pppchar = ^ppchar; + PPByte = ^PByte; + + pculong = ^culong; + +{ ------------ Start of declaration in "my_list.h" --------------------- } + + pst_list = ^st_list; + st_list = record + prev,next: pst_list; + data: pointer; + end; + LIST = st_list; + +{ ------------ Start of declaration in "mysql_time.h" --------------------- } + +{ + Structure which is used to represent datetime values inside MySQL. + + We assume that values in this structure are normalized, i.e. year <= 9999, + month <= 12, day <= 31, hour <= 23, hour <= 59, hour <= 59. Many functions + in server such as my_system_gmt_sec() or make_time() family of functions + rely on this (actually now usage of make_*() family relies on a bit weaker + restriction). Also functions that produce MYSQL_TIME as result ensure this. + There is one exception to this rule though if this structure holds time + value (time_type == MYSQL_TIMESTAMP_TIME) days and hour member can hold + bigger values. +} +type + enum_mysql_timestamp_type = ( + MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1, + MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2); + + MYSQL_TIME = record + year, month, day, hour, minute, second: cuint; + second_part: culong; + neg: my_bool; + time_type: enum_mysql_timestamp_type; + end; + pmysql_time = ^mysql_time; + +{ ------------ Start of declaration in "mysql_com.h" --------------------- } + + { + ** Common definition between mysql server & client + } + + { Field/table name length } + + const + NAME_LEN = 64; + HOSTNAME_LENGTH = 60; + USERNAME_LENGTH = 16; + SERVER_VERSION_LENGTH = 60; + SQLSTATE_LENGTH = 5; + LOCAL_HOST = 'localhost'; + LOCAL_HOST_NAMEDPIPE = '.'; + + const + MYSQL_NAMEDPIPE = 'MySQL'; + MYSQL_SERVICENAME = 'MySQL'; + + type + enum_server_command = (COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY, + COM_FIELD_LIST,COM_CREATE_DB,COM_DROP_DB, + COM_REFRESH,COM_SHUTDOWN,COM_STATISTICS, + COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL, + COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT, + COM_CHANGE_USER,COM_BINLOG_DUMP,COM_TABLE_DUMP, + COM_CONNECT_OUT,COM_REGISTER_SLAVE, +{$IFDEF mysql50} + COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE, + COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, +{$ELSE} + {$IFDEF mysql41} + COM_PREPARE,COM_EXECUTE,COM_LONG_DATA,COM_CLOSE_STMT, + COM_RESET_STMT,COM_SET_OPTION, + {$ENDIF} +{$ENDIF} + COM_END + ); + + { + Length of random string sent by server on handshake; this is also length of + obfuscated password, recieved from client + } + + const + SCRAMBLE_LENGTH = 20; + SCRAMBLE_LENGTH_323 = 8; + + { length of password stored in the db: new passwords are preceeded with '*' } + + SCRAMBLED_PASSWORD_CHAR_LENGTH = SCRAMBLE_LENGTH*2+1; + SCRAMBLED_PASSWORD_CHAR_LENGTH_323 = SCRAMBLE_LENGTH_323*2; + + + NOT_NULL_FLAG = 1; // Field can't be NULL + PRI_KEY_FLAG = 2; // Field is part of a primary key + UNIQUE_KEY_FLAG = 4; // Field is part of a unique key + MULTIPLE_KEY_FLAG = 8; // Field is part of a key + BLOB_FLAG = 16; // Field is a blob + UNSIGNED_FLAG = 32; // Field is unsigned + ZEROFILL_FLAG = 64; // Field is zerofill + BINARY_FLAG = 128; // Field is binary + + { The following are only sent to new clients } + + ENUM_FLAG = 256; // field is an enum + AUTO_INCREMENT_FLAG = 512; // field is a autoincrement field + TIMESTAMP_FLAG = 1024; // Field is a timestamp + SET_FLAG = 2048; // field is a set +{$IFDEF mysql50} + NO_DEFAULT_VALUE_FLAG=4096; // Field doesn't have default value +{$ENDIF} + NUM_FLAG = 32768; // Field is num (for clients) + PART_KEY_FLAG = 16384; // Intern; Part of some key + GROUP_FLAG = 32768; // Intern: Group field + UNIQUE_FLAG = 65536; // Intern: Used by sql_yacc + BINCMP_FLAG = 131072; // Intern: Used by sql_yacc + + REFRESH_GRANT = 1; // Refresh grant tables + REFRESH_LOG = 2; // Start on new log file + REFRESH_TABLES = 4; // close all tables + REFRESH_HOSTS = 8; // Flush host cache + REFRESH_STATUS = 16; // Flush status variables + REFRESH_THREADS = 32; // Flush thread cache + REFRESH_SLAVE = 64; // Reset master info and restart slave thread + REFRESH_MASTER = 128; // Remove all bin logs in the index and truncate the index + + { The following can't be set with mysql_refresh() } + REFRESH_READ_LOCK = 16384; // Lock tables for read + REFRESH_FAST = 32768; // Intern flag + REFRESH_QUERY_CACHE = 65536; // RESET (remove all queries) from query cache + REFRESH_QUERY_CACHE_FREE = $20000; // pack query cache + + REFRESH_DES_KEY_FILE = $40000; + REFRESH_USER_RESOURCES = $80000; + + CLIENT_LONG_PASSWORD = 1; // new more secure passwords + CLIENT_FOUND_ROWS = 2; // Found instead of affected rows + CLIENT_LONG_FLAG = 4; // Get all column flags + CLIENT_CONNECT_WITH_DB = 8; // One can specify db on connect + CLIENT_NO_SCHEMA = 16; // Don't allow database.table.column + CLIENT_COMPRESS = 32; // Can use compression protocol + CLIENT_ODBC = 64; // Odbc client + CLIENT_LOCAL_FILES = 128; // Can use LOAD DATA LOCAL + CLIENT_IGNORE_SPACE = 256; // Ignore spaces before '(' + CLIENT_PROTOCOL_41 = 512; // New 4.1 protocol + CLIENT_INTERACTIVE = 1024; // This is an interactive client + CLIENT_SSL = 2048; // Switch to SSL after handshake + CLIENT_IGNORE_SIGPIPE = 4096; // IGNORE sigpipes + CLIENT_TRANSACTIONS = 8192; // Client knows about transactions + CLIENT_RESERVED = 16384; // Old flag for 4.1 protocol + CLIENT_SECURE_CONNECTION = 32768; // New 4.1 authentication + CLIENT_MULTI_STATEMENTS = 65536; // Enable/disable multi-stmt support + CLIENT_MULTI_RESULTS = 131072; // Enable/disable multi-results +// CLIENT_REMEMBER_OPTIONS : longword = 1 shl 31; + CLIENT_REMEMBER_OPTIONS = 1 shl 31; + + + SERVER_STATUS_IN_TRANS = 1; // Transaction has started + SERVER_STATUS_AUTOCOMMIT = 2; // Server in auto_commit mode + SERVER_STATUS_MORE_RESULTS = 4; // More results on server + SERVER_MORE_RESULTS_EXISTS = 8; // Multi query - next query exists + SERVER_QUERY_NO_GOOD_INDEX_USED = 16; + SERVER_QUERY_NO_INDEX_USED = 32; +{$IFDEF mysql50} + { The server was able to fulfill the clients request and opened a + read-only non-scrollable cursor for a query. This flag comes + in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands. } + SERVER_STATUS_CURSOR_EXISTS = 64; + { This flag is sent when a read-only cursor is exhausted, in reply to + COM_STMT_FETCH command. } + SERVER_STATUS_LAST_ROW_SENT = 128; +{$ENDIF} + SERVER_STATUS_DB_DROPPED = 256; // A database was dropped +{$IFDEF mysql50} + SERVER_STATUS_NO_BACKSLASH_ESCAPES = 512; +{$ENDIF} + +{$IFDEF mysql41} + MYSQL_ERRMSG_SIZE = 512; +{$ELSE} + MYSQL_ERRMSG_SIZE = 200; +{$ENDIF} + NET_READ_TIMEOUT = 30; // Timeout on read + NET_WRITE_TIMEOUT = 60; // Timeout on write + NET_WAIT_TIMEOUT = 8*60*60; // Wait for new query +{$IFDEF mysql50} + ONLY_KILL_QUERY = 1; +{$ENDIF} + + + const + MAX_TINYINT_WIDTH = 3; // Max width for a TINY w.o. sign + MAX_SMALLINT_WIDTH = 5; // Max width for a SHORT w.o. sign + MAX_MEDIUMINT_WIDTH = 8; // Max width for a INT24 w.o. sign + MAX_INT_WIDTH = 10; // Max width for a LONG w.o. sign + MAX_BIGINT_WIDTH = 20; // Max width for a LONGLONG + MAX_CHAR_WIDTH = 255; // Max length for a CHAR colum + MAX_BLOB_WIDTH = 8192; // Default width for blob + + type + Pst_net = ^st_net; + st_net = record +{ $if !defined(CHECK_EMBEDDED_DIFFERENCES) || !defined(EMBEDDED_LIBRARY)} + vio : PVio; + buff : pcuchar; + buff_end : pcuchar; + write_pos : pcuchar; + read_pos : pcuchar; + fd : my_socket; // For Perl DBI/dbd + max_packet : culong; + max_packet_size : culong; +{$IFNDEF mysql41} + last_errno : cuint; +{$ENDIF} + pkt_nr : cuint; + compress_pkt_nr : cuint; + write_timeout : cuint; + read_timeout : cuint; + retry_count : cuint; + fcntl : cint; +{$IFNDEF mysql41} + last_error : array[0..(MYSQL_ERRMSG_SIZE)-1] of char; + error : cuchar; + return_errno : my_bool; +{$ENDIF} + compress : my_bool; + { The following variable is set if we are doing several queries in one + command ( as in LOAD TABLE ... FROM MASTER ), + and do not want to confuse the client with OK at the wrong time } + remain_in_buf : culong; + length : culong; + buf_length : culong; + where_b : culong; + return_status : pcint; + reading_or_writing : cuchar; + save_char : cchar; + no_send_ok : my_bool; // For SPs and other things that do multiple stmts +{$IFDEF mysql50} + no_send_eof : my_bool; // For SPs' first version read-only cursors + no_send_error : my_bool; // Set if OK packet is already sent, and + // we do not need to send error messages +{$ENDIF} + { Pointer to query object in query cache, do not equal NULL (0) for + queries in cache that have not stored its results yet } +{ $endif} +{$IFDEF mysql41} + last_error : array[0..(MYSQL_ERRMSG_SIZE)-1] of char; + sqlstate : array[0..(SQLSTATE_LENGTH+1)-1] of char; + last_errno : cuint; + error : cuchar; +{$ENDIF} + query_cache_query : gptr; +{$IFDEF mysql41} + report_error : my_bool; // We should report error (we have unreported error) + return_errno : my_bool; +{$ENDIF} + end; + NET = st_net; + PNET = ^NET; + + const + packet_error : culong = culong(not(0)); + + {$ifdef FPC} + type + enum_field_types = (MYSQL_TYPE_DECIMAL,MYSQL_TYPE_TINY, + MYSQL_TYPE_SHORT,MYSQL_TYPE_LONG,MYSQL_TYPE_FLOAT, + MYSQL_TYPE_DOUBLE,MYSQL_TYPE_NULL, + MYSQL_TYPE_TIMESTAMP,MYSQL_TYPE_LONGLONG, + MYSQL_TYPE_INT24,MYSQL_TYPE_DATE,MYSQL_TYPE_TIME, + MYSQL_TYPE_DATETIME,MYSQL_TYPE_YEAR, + MYSQL_TYPE_NEWDATE, +{$IFDEF mysql50} + MYSQL_TYPE_VARCHAR, MYSQL_TYPE_BIT, MYSQL_TYPE_NEWDECIMAL=246, +{$ENDIF} + MYSQL_TYPE_ENUM := 247, + MYSQL_TYPE_SET := 248,MYSQL_TYPE_TINY_BLOB := 249, + MYSQL_TYPE_MEDIUM_BLOB := 250,MYSQL_TYPE_LONG_BLOB := 251, + MYSQL_TYPE_BLOB := 252,MYSQL_TYPE_VAR_STRING := 253, + MYSQL_TYPE_STRING := 254,MYSQL_TYPE_GEOMETRY := 255 + ); + { For backward compatibility } + {$else} + const + MYSQL_TYPE_DECIMAL = 0; + MYSQL_TYPE_TINY = 1; + MYSQL_TYPE_SHORT = 2; + MYSQL_TYPE_LONG = 3; + MYSQL_TYPE_FLOAT = 4; + MYSQL_TYPE_DOUBLE = 5; + MYSQL_TYPE_NULL = 6; + MYSQL_TYPE_TIMESTAMP = 7; + MYSQL_TYPE_LONGLONG = 8; + MYSQL_TYPE_INT24 = 9; + MYSQL_TYPE_DATE = 10; + MYSQL_TYPE_TIME = 11; + MYSQL_TYPE_DATETIME = 12; + MYSQL_TYPE_YEAR = 13; + MYSQL_TYPE_NEWDATE = 14; +{$IFDEF mysql50} + MYSQL_TYPE_VARCHAR = 15; + MYSQL_TYPE_BIT = 16; + MYSQL_TYPE_NEWDECIMAL = 246; +{$ENDIF} + MYSQL_TYPE_ENUM = 247; + MYSQL_TYPE_SET = 248; + MYSQL_TYPE_TINY_BLOB = 249; + MYSQL_TYPE_MEDIUM_BLOB = 250; + MYSQL_TYPE_LONG_BLOB = 251; + MYSQL_TYPE_BLOB = 252; + MYSQL_TYPE_VAR_STRING = 253; + MYSQL_TYPE_STRING = 254; + MYSQL_TYPE_GEOMETRY = 255; +type + enum_field_types = cint; //correct? + {$endif} + penum_field_types = ^enum_field_types; + + const + CLIENT_MULTI_QUERIES = CLIENT_MULTI_STATEMENTS; + FIELD_TYPE_DECIMAL = MYSQL_TYPE_DECIMAL; +{$IFDEF mysql50} + FIELD_TYPE_NEWDECIMAL = MYSQL_TYPE_NEWDECIMAL; +{$ENDIF} + FIELD_TYPE_TINY = MYSQL_TYPE_TINY; + FIELD_TYPE_SHORT = MYSQL_TYPE_SHORT; + FIELD_TYPE_LONG = MYSQL_TYPE_LONG; + FIELD_TYPE_FLOAT = MYSQL_TYPE_FLOAT; + FIELD_TYPE_DOUBLE = MYSQL_TYPE_DOUBLE; + FIELD_TYPE_NULL = MYSQL_TYPE_NULL; + FIELD_TYPE_TIMESTAMP = MYSQL_TYPE_TIMESTAMP; + FIELD_TYPE_LONGLONG = MYSQL_TYPE_LONGLONG; + FIELD_TYPE_INT24 = MYSQL_TYPE_INT24; + FIELD_TYPE_DATE = MYSQL_TYPE_DATE; + FIELD_TYPE_TIME = MYSQL_TYPE_TIME; + FIELD_TYPE_DATETIME = MYSQL_TYPE_DATETIME; + FIELD_TYPE_YEAR = MYSQL_TYPE_YEAR; + FIELD_TYPE_NEWDATE = MYSQL_TYPE_NEWDATE; + FIELD_TYPE_ENUM = MYSQL_TYPE_ENUM; + FIELD_TYPE_SET = MYSQL_TYPE_SET; + FIELD_TYPE_TINY_BLOB = MYSQL_TYPE_TINY_BLOB; + FIELD_TYPE_MEDIUM_BLOB = MYSQL_TYPE_MEDIUM_BLOB; + FIELD_TYPE_LONG_BLOB = MYSQL_TYPE_LONG_BLOB; + FIELD_TYPE_BLOB = MYSQL_TYPE_BLOB; + FIELD_TYPE_VAR_STRING = MYSQL_TYPE_VAR_STRING; + FIELD_TYPE_STRING = MYSQL_TYPE_STRING; + FIELD_TYPE_CHAR = MYSQL_TYPE_TINY; + FIELD_TYPE_INTERVAL = MYSQL_TYPE_ENUM; + FIELD_TYPE_GEOMETRY = MYSQL_TYPE_GEOMETRY; +{$IFDEF mysql50} + FIELD_TYPE_BIT = MYSQL_TYPE_BIT; +{$ENDIF} + { Shutdown/kill enums and constants } + { Bits for THD::killable. } + MYSQL_SHUTDOWN_KILLABLE_CONNECT : cuchar = 1 shl 0; + MYSQL_SHUTDOWN_KILLABLE_TRANS : cuchar = 1 shl 1; + MYSQL_SHUTDOWN_KILLABLE_LOCK_TABLE : cuchar = 1 shl 2; + MYSQL_SHUTDOWN_KILLABLE_UPDATE : cuchar = 1 shl 3; + + + { We want levels to be in growing order of hardness (because we use number + comparisons). Note that DEFAULT does not respect the growing property, but + it's ok. } + {$ifdef FPC} + type + mysql_enum_shutdown_level = (SHUTDOWN_DEFAULT := 0, + SHUTDOWN_WAIT_CONNECTIONS := 1, //MYSQL_SHUTDOWN_KILLABLE_CONNECT, // wait for existing connections to finish + SHUTDOWN_WAIT_TRANSACTIONS := 2, //MYSQL_SHUTDOWN_KILLABLE_TRANS, // wait for existing trans to finish + SHUTDOWN_WAIT_UPDATES := 8, //MYSQL_SHUTDOWN_KILLABLE_UPDATE, // wait for existing updates to finish (=> no partial MyISAM update) + SHUTDOWN_WAIT_ALL_BUFFERS := 16, //MYSQL_SHUTDOWN_KILLABLE_UPDATE shl 1,// flush InnoDB buffers and other storage engines' buffers + SHUTDOWN_WAIT_CRITICAL_BUFFERS := 17, //(MYSQL_SHUTDOWN_KILLABLE_UPDATE shl 1)+1, // don't flush InnoDB buffers, flush other storage engines' buffers + { Now the 2 levels of the KILL command } +{ $if MYSQL_VERSION_ID >= 50000} + KILL_QUERY := 254, +{ $endif} + KILL_CONNECTION := 255 + ); + {$else} +const + SHUTDOWN_DEFAULT = 0; + SHUTDOWN_WAIT_CONNECTIONS = 1; //MYSQL_SHUTDOWN_KILLABLE_CONNECT, // wait for existing connections to finish + SHUTDOWN_WAIT_TRANSACTIONS = 2; //MYSQL_SHUTDOWN_KILLABLE_TRANS, // wait for existing trans to finish + SHUTDOWN_WAIT_UPDATES = 8; //MYSQL_SHUTDOWN_KILLABLE_UPDATE, // wait for existing updates to finish (=> no partial MyISAM update) + SHUTDOWN_WAIT_ALL_BUFFERS = 16; //MYSQL_SHUTDOWN_KILLABLE_UPDATE shl 1,// flush InnoDB buffers and other storage engines' buffers + SHUTDOWN_WAIT_CRITICAL_BUFFERS = 17; //(MYSQL_SHUTDOWN_KILLABLE_UPDATE shl 1)+1, // don't flush InnoDB buffers, flush other storage engines' buffers + { Now the 2 levels of the KILL command } +{ $if MYSQL_VERSION_ID >= 50000} + KILL_QUERY = 254; +{ $endif} + KILL_CONNECTION = 255; +type + mysql_enum_shutdown_level = cint; //correct? + {$endif} + +{$IFDEF mysql50} + {$ifdef FPC} + enum_cursor_type = (CURSOR_TYPE_NO_CURSOR := 0,CURSOR_TYPE_READ_ONLY := 1, + CURSOR_TYPE_FOR_UPDATE := 2,CURSOR_TYPE_SCROLLABLE := 4 + ); + {$else} +const + CURSOR_TYPE_NO_CURSOR = 0; + CURSOR_TYPE_READ_ONLY = 1; + CURSOR_TYPE_FOR_UPDATE = 2; + CURSOR_TYPE_SCROLLABLE = 4; +type + enum_cursor_type = cint; //correct? + {$endif} +{$ENDIF} + +{$ifdef FPC} + enum_mysql_stmt_state = (MYSQL_STMT_INIT_DONE := 1,MYSQL_STMT_PREPARE_DONE, + MYSQL_STMT_EXECUTE_DONE,MYSQL_STMT_FETCH_DONE + ); +{$else} +const + MYSQL_STMT_INIT_DONE = 1; + MYSQL_STMT_PREPARE_DONE = 2; + MYSQL_STMT_EXECUTE_DONE = 3; + MYSQL_STMT_FETCH_DONE = 4; +type + enum_mysql_stmt_state = cint; //correct? +{$endif} + + { options for mysql_set_option } + enum_mysql_set_option = (MYSQL_OPTION_MULTI_STATEMENTS_ON, + MYSQL_OPTION_MULTI_STATEMENTS_OFF + ); + + function net_new_transaction(net : st_net) : st_net; + +{$IFNDEF LinkDynamically} + function my_net_init(net:PNET; vio:PVio):my_bool;cdecl;external mysqllib name 'my_net_init'; + procedure my_net_local_init(net:PNET);cdecl;external mysqllib name 'my_net_local_init'; + procedure net_end(net:PNET);cdecl;external mysqllib name 'net_end'; + procedure net_clear(net:PNET);cdecl;external mysqllib name 'net_clear'; + function net_realloc(net:PNET; length:culong):my_bool;cdecl;external mysqllib name 'net_realloc'; + function net_flush(net:PNET):my_bool;cdecl;external mysqllib name 'net_flush'; + function my_net_write(net:PNET; packet:Pchar; len:culong):my_bool;cdecl;external mysqllib name 'my_net_write'; + function net_write_command(net:PNET; command:cuchar; header:Pchar; head_len:culong; packet:Pchar; + len:culong):my_bool;cdecl;external mysqllib name 'net_write_command'; + function net_real_write(net:PNET; packet:Pchar; len:culong):cint;cdecl;external mysqllib name 'net_real_write'; + function my_net_read(net:PNET):culong;cdecl;external mysqllib name 'my_net_read'; +{$ENDIF} + { The following function is not meant for normal usage + Currently it's used internally by manager.c } + + type + Psockaddr = ^sockaddr; + sockaddr = record + // undefined structure + end; +{$IFNDEF LinkDynamically} + function my_connect(s:my_socket; name:Psockaddr; namelen:cuint; timeout:cuint):cint;cdecl;external mysqllib name 'my_connect'; +{$ENDIF} + + type + Prand_struct = ^rand_struct; + rand_struct = record + seed1 : culong; + seed2 : culong; + max_value : culong; + max_value_dbl : cdouble; + end; + + { The following is for user defined functions } +{$IFDEF mysql50} + Item_result = (STRING_RESULT,REAL_RESULT,INT_RESULT, + ROW_RESULT); +{$ELSE} + Item_result = (STRING_RESULT := 0,REAL_RESULT,INT_RESULT, + ROW_RESULT,DECIMAL_RESULT); +{$ENDIF} + PItem_result = ^Item_result; + + Pst_udf_args = ^st_udf_args; + st_udf_args = record + arg_count : cuint; // Number of arguments + arg_type : PItem_result; // Pointer to item_results + args : PPChar; // Pointer to item_results + lengths : pculong; // Length of string arguments + maybe_null : Pchar; // Length of string arguments +{$IFDEF mysql50} + attributes : PPChar; // Pointer to attribute name + attribute_lengths : pculong; // Length of attribute arguments +{$ENDIF} + end; + UDF_ARGS = st_udf_args; + PUDF_ARGS = ^UDF_ARGS; + + { This holds information about the result } + + Pst_udf_init = ^st_udf_init; + st_udf_init = record + maybe_null : my_bool; // 1 if function can return NULL + decimals : cuint; // for real functions + max_length : culong; // For string functions + ptr : Pchar; // free pointer for function data + const_item : my_bool; // free pointer for function data + end; + UDF_INIT = st_udf_init; + PUDF_INIT = ^UDF_INIT; + + { Constants when using compression } + const + NET_HEADER_SIZE = 4; // standard header size + COMP_HEADER_SIZE = 3; // compression header extra size + + { Prototypes to password functions } + + { These functions are used for authentication by client and server and + implemented in sql/password.c } +{$IFNDEF LinkDynamically} + procedure randominit(_para1:Prand_struct; seed1:culong; seed2:culong);cdecl;external mysqllib name 'randominit'; + function my_rnd(_para1:Prand_struct):cdouble;cdecl;external mysqllib name 'my_rnd'; + procedure create_random_string(fto:Pchar; length:cuint; rand_st:Prand_struct);cdecl;external mysqllib name 'create_random_string'; + procedure hash_password(fto:culong; password:Pchar; password_len:cuint);cdecl;external mysqllib name 'hash_password'; + procedure make_scrambled_password_323(fto:Pchar; password:Pchar);cdecl;external mysqllib name 'make_scrambled_password_323'; + procedure scramble_323(fto:Pchar; message:Pchar; password:Pchar);cdecl;external mysqllib name 'scramble_323'; + function check_scramble_323(_para1:Pchar; message:Pchar; salt:culong):my_bool;cdecl;external mysqllib name 'check_scramble_323'; + procedure get_salt_from_password_323(res:pculong; password:Pchar);cdecl;external mysqllib name 'get_salt_from_password_323'; + procedure make_password_from_salt_323(fto:Pchar; salt:pculong);cdecl;external mysqllib name 'make_password_from_salt_323'; +{$IFDEF mysql50} + function octet2hex(fto:Pchar; str:Pchar; len:cuint):pchar;cdecl;external mysqllib name 'octet2hex'; +{$ENDIF} + procedure make_scrambled_password(fto:Pchar; password:Pchar);cdecl;external mysqllib name 'make_scrambled_password'; + procedure scramble(fto:Pchar; message:Pchar; password:Pchar);cdecl;external mysqllib name 'scramble'; + function check_scramble(reply:Pchar; message:Pchar; hash_stage2:Pbyte):my_bool;cdecl;external mysqllib name 'check_scramble'; + procedure get_salt_from_password(res:Pbyte; password:Pchar);cdecl;external mysqllib name 'get_salt_from_password'; + procedure make_password_from_salt(fto:Pchar; hash_stage2:Pbyte);cdecl;external mysqllib name 'make_password_from_salt'; + { end of password.c } + + function get_tty_password(opt_message:Pchar):Pchar;cdecl;external mysqllib name 'get_tty_password'; + function mysql_errno_to_sqlstate(mysql_errno:cuint):Pchar;cdecl;external mysqllib name 'mysql_errno_to_sqlstate'; + + { Some other useful functions } +{$IFDEF mysql50} + function modify_defaults_file(file_location:Pchar; option:Pchar; option_value:Pchar; section_name:Pchar; remove_option:cint):cint;cdecl;external mysqllib name 'load_defaults'; +{$ENDIF} + + function load_defaults(conf_file:Pchar; groups:PPchar; argc:pcint; argv:PPPchar):cint;cdecl;external mysqllib name 'load_defaults'; + function my_init:my_bool;cdecl;external mysqllib name 'my_init'; + function my_thread_init:my_bool;cdecl;external mysqllib name 'my_thread_init'; + procedure my_thread_end;cdecl;external mysqllib name 'my_thread_end'; +{$ELSE} +{$ENDIF} + +{$ifdef _global_h} +{$IFNDEF LinkDynamically} + function net_field_length(packet:PPuchar):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'net_field_length_ll'; + function net_field_length_ll(packet:PPuchar):my_ulonglong;cdecl;external mysqllib name 'net_field_length_ll'; + function net_store_length(pkg:Pchar; length:ulonglong):Pchar;cdecl;external mysqllib name 'net_store_length'; +{$ENDIF} +{$endif} + + const + NULL_LENGTH : culong = culong(not(0)); // For net_store_length + + const + MYSQL_STMT_HEADER = 4; + MYSQL_LONG_DATA_HEADER = 6; + +{ ------------ Stop of declaration in "mysql_com.h" ----------------------- } + +{ $include "mysql_time.h"} +{ $include "mysql_version.h"} +{ $include "typelib.h"} +{ $include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */} + +{$IFNDEF LinkDynamically} + var + mysql_port : cuint;cvar;external; + mysql_unix_port : Pchar;cvar;external; +{$ENDIF} + + const + CLIENT_NET_READ_TIMEOUT = 365*24*3600; // Timeout on read + CLIENT_NET_WRITE_TIMEOUT = 365*24*3600; // Timeout on write + +{$ifdef NETWARE} +(** unsupported pragma#pragma pack(push, 8) /* 8 byte alignment */*) +{$endif} + + type + Pst_mysql_field = ^st_mysql_field; + st_mysql_field = record + name : Pchar; // Name of column +{$IFDEF mysql41} + org_name : Pchar; // Original column name, if an alias +{$ENDIF} + table : Pchar; // Table of column if column was a field + org_table : Pchar; // Org table name, if table was an alias + db : Pchar; // Database for table +{$IFDEF mysql41} + catalog : Pchar; // Catalog for table +{$ENDIF} + def : Pchar; // Default value (set by mysql_list_fields) + length : culong; // Width of column (create length) + max_length : culong; // Max width for selected set +{$IFDEF mysql41} + name_length : cuint; + org_name_length : cuint; + table_length : cuint; + org_table_length : cuint; + db_length : cuint; + catalog_length : cuint; + def_length : cuint; +{$ENDIF} + flags : cuint; // Div flags + decimals : cuint; // Number of decimals in field +{$IFDEF mysql41} + charsetnr : cuint; // Character set +{$ENDIF} + ftype : enum_field_types; // Type of field. See mysql_com.h for types +{$ifdef mysql51} + extension: pointer; +{$endif} + end; + MYSQL_FIELD = st_mysql_field; + PMYSQL_FIELD = ^MYSQL_FIELD; + + PMYSQL_ROW = ^MYSQL_ROW; // return data as array of strings + MYSQL_ROW = ppchar; + + PMYSQL_FIELD_OFFSET = ^MYSQL_FIELD_OFFSET; // offset to current field + MYSQL_FIELD_OFFSET = cuint; + + function IS_PRI_KEY(n : longint) : boolean; + function IS_NOT_NULL(n : longint) : boolean; + function IS_BLOB(n : longint) : boolean; + function IS_NUM(t : enum_field_types) : boolean; + function INTERNAL_NUM_FIELD(f : Pst_mysql_field) : boolean; + function IS_NUM_FIELD(f : Pst_mysql_field) : boolean; + + type +{$if defined(NO_CLIENT_LONG_LONG)} + my_ulonglong = culong; +{$elseif defined(mswindows)} + my_ulonglong = cint64; +{$else} + my_ulonglong = culonglong; +{$ifend} + Pmy_ulonglong = ^my_ulonglong; + + const + MYSQL_COUNT_ERROR = not (my_ulonglong(0)); + + type + Pst_mysql_rows = ^st_mysql_rows; + st_mysql_rows = record + next : Pst_mysql_rows; // list of rows + data : MYSQL_ROW; +{$IFDEF mysql41} + length : culong; +{$ENDIF} + end; + MYSQL_ROWS = st_mysql_rows; + PMYSQL_ROWS = ^MYSQL_ROWS; + + PMYSQL_ROW_OFFSET = ^MYSQL_ROW_OFFSET; // offset to current row + MYSQL_ROW_OFFSET = MYSQL_ROWS; + +{ ------------ Start of declaration in "my_alloc.h" -------------------- } +{ $include "my_alloc.h"} + + const + ALLOC_MAX_BLOCK_TO_DROP = 4096; + ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP = 10; + + { struct for once_alloc (block) } + type + Pst_used_mem = ^st_used_mem; + st_used_mem = record + next : Pst_used_mem; // Next block in use + left : cuint; // memory left in block + size : cuint; // size of block + end; + USED_MEM = st_used_mem; + PUSED_MEM = ^USED_MEM; + + + Pst_mem_root = ^st_mem_root; + st_mem_root = record + free : PUSED_MEM; // blocks with free memory in it + used : PUSED_MEM; // blocks almost without free memory + pre_alloc : PUSED_MEM; // preallocated block + min_malloc : cuint; // if block have less memory it will be put in 'used' list + block_size : cuint; // initial block size + block_num : cuint; // allocated blocks counter + { first free block in queue test counter (if it exceed + MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list) } + first_block_usage : cuint; + error_handler : procedure ;cdecl; + end; + MEM_ROOT = st_mem_root; + PMEM_ROOT = ^MEM_ROOT; + +{ ------------ Stop of declaration in "my_alloc.h" ---------------------- } + + type + Pst_mysql_data = ^st_mysql_data; +{$ifdef mysql51} + st_mysql_data = record + data : PMYSQL_ROWS; + prev_ptr : ^PMYSQL_ROWS; + alloc : MEM_ROOT; + rows : my_ulonglong; + fields : cuint; + extension: pointer; + end; +{$else} + st_mysql_data = record + rows : my_ulonglong; + fields : cuint; + data : PMYSQL_ROWS; + alloc : MEM_ROOT; +{ $if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)} +{$IFDEF mysql41} + prev_ptr : ^PMYSQL_ROWS; +{$ENDIF} + end; +{$endif} + MYSQL_DATA = st_mysql_data; + PMYSQL_DATA = ^MYSQL_DATA; + mysql_option = (MYSQL_OPT_CONNECT_TIMEOUT,MYSQL_OPT_COMPRESS, + MYSQL_OPT_NAMED_PIPE,MYSQL_INIT_COMMAND, + MYSQL_READ_DEFAULT_FILE,MYSQL_READ_DEFAULT_GROUP, + MYSQL_SET_CHARSET_DIR,MYSQL_SET_CHARSET_NAME, + MYSQL_OPT_LOCAL_INFILE,MYSQL_OPT_PROTOCOL, + MYSQL_SHARED_MEMORY_BASE_NAME,MYSQL_OPT_READ_TIMEOUT, + MYSQL_OPT_WRITE_TIMEOUT,MYSQL_OPT_USE_RESULT, + MYSQL_OPT_USE_REMOTE_CONNECTION,MYSQL_OPT_USE_EMBEDDED_CONNECTION, + MYSQL_OPT_GUESS_CONNECTION,MYSQL_SET_CLIENT_IP, + MYSQL_SECURE_AUTH +{$IFDEF MYSQL50} + ,MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT +{$ENDIF} + ); + + const + MAX_MYSQL_MANAGER_ERR = 256; + MAX_MYSQL_MANAGER_MSG = 256; + MANAGER_OK = 200; + MANAGER_INFO = 250; + MANAGER_ACCESS = 401; + MANAGER_CLIENT_ERR = 450; + MANAGER_INTERNAL_ERR = 500; + + type + st_dynamic_array = record + buffer : ^char; + elements : cuint; + max_element : cuint; + alloc_increment : cuint; + size_of_element : cuint; + end; + DYNAMIC_ARRAY = st_dynamic_array; + Pst_dynamic_array = ^st_dynamic_array; + + Pst_mysql_options = ^st_mysql_options; + st_mysql_options = record + connect_timeout : cuint; +{$IFNDEF mysql41} + client_flag : cuint; + port : cuint; +{$ELSE} + read_timeout : cuint; + write_timeout : cuint; +{$ENDIF} +{$IFDEF mysql41} + port : cuint; + protocol : cuint; + client_flag : culong; +{$ENDIF} + host : Pchar; +{$IFNDEF mysql41} + init_command: Pchar; +{$ENDIF} + user : Pchar; + password : Pchar; + unix_socket : Pchar; + db : Pchar; +{$IFDEF mysql41} + init_commands : Pst_dynamic_array; +{$ENDIF} + my_cnf_file : Pchar; + my_cnf_group : Pchar; + charset_dir : Pchar; + charset_name : Pchar; + ssl_key : Pchar; // PEM key file + ssl_cert : Pchar; // PEM cert file + ssl_ca : Pchar; // PEM CA file + ssl_capath : Pchar; // PEM directory of CA-s? + ssl_cipher : Pchar; // cipher to use +{$IFDEF mysql41} + shared_memory_base_name : Pchar; +{$ENDIF} + max_allowed_packet : culong; + use_ssl : my_bool; // if to use SSL or not + compress : my_bool; + named_pipe : my_bool; + { On connect, find out the replication role of the server, and + establish connections to all the peers } + rpl_probe : my_bool; + { Each call to mysql_real_query() will parse it to tell if it is a read + or a write, and direct it to the slave or the master } + rpl_parse : my_bool; + { If set, never read from a master, only from slave, when doing + a read that is replication-aware } + no_master_reads : my_bool; +{ $if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)} +{$IFDEF mysql41} + separate_thread : my_bool; +{ $endif} + methods_to_use : mysql_option; + client_ip : Pchar; + secure_auth : my_bool; // Refuse client connecting to server if it uses old (pre-4.1.1) protocol +{$IFDEF mysql50} + report_data_truncation : my_bool;// 0 - never report, 1 - always report (default) +{$ENDIF} + { function pointers for local infile support } + local_infile_init : function (_para1:Ppointer; _para2:Pchar; _para3:pointer):cint;cdecl; + local_infile_read : function (_para1:pointer; _para2:Pchar; _para3:cuint):cint; + local_infile_end : procedure (_para1:pointer); + local_infile_error : function (_para1:pointer; _para2:Pchar; _para3:cuint):cint; + local_infile_userdata : pointer; +{$ENDIF} +{$ifdef mysql51} + extension: pointer; +{$endif} + end; + + mysql_status = (MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT, + MYSQL_STATUS_USE_RESULT); + + mysql_protocol_type = (MYSQL_PROTOCOL_DEFAULT,MYSQL_PROTOCOL_TCP, + MYSQL_PROTOCOL_SOCKET,MYSQL_PROTOCOL_PIPE, + MYSQL_PROTOCOL_MEMORY); + + { There are three types of queries - the ones that have to go to + the master, the ones that go to a slave, and the adminstrative + type which must happen on the pivot connectioin } + mysql_rpl_type = (MYSQL_RPL_MASTER,MYSQL_RPL_SLAVE,MYSQL_RPL_ADMIN + ); + + charset_info_st = record + number : cuint; + primary_number : cuint; + binary_number : cuint; + state : cuint; + csname : ^char; + name : ^char; + comment : ^char; + tailoring : ^char; + ftype : ^cuchar; + to_lower : ^cuchar; + to_upper : ^cuchar; + sort_order : ^cuchar; + contractions : ^cuint16; + sort_order_big : ^pword; + tab_to_uni : ^cuint16; + tab_from_uni : pointer; // was ^MY_UNI_IDX + state_map : ^cuchar; + ident_map : ^cuchar; + strxfrm_multiply : cuint; + mbminlen : cuint; + mbmaxlen : cuint; + min_sort_char : cuint16; + max_sort_char : cuint16; + escape_with_backslash_is_dangerous : my_bool; + cset : pointer; // was ^MY_CHARSET_HANDLER + coll : pointer; // was ^MY_COLLATION_HANDLER; + end; + CHARSET_INFO = charset_info_st; + Pcharset_info_st = ^charset_info_st; + +{$IFDEF mysql50} + Pcharacter_set = ^character_set; + character_set = record + number : cuint; + state : cuint; + csname : Pchar; + name : Pchar; + comment : Pchar; + dir : Pchar; + mbminlen : cuint; + mbmaxlen : cuint; + end; + MY_CHARSET_INFO = character_set; + PMY_CHARSET_INFO = ^MY_CHARSET_INFO; +{$ENDIF} + + Pst_mysql_methods = ^st_mysql_methods; + + Pst_mysql = ^st_mysql; + st_mysql = record + net : NET; // Communication parameters +{$ifdef mysql51} + connector_fd: pbyte; // ConnectorFd for SSL +{$else} + connector_fd : gptr; // ConnectorFd for SSL +{$endif} + host : Pchar; + user : Pchar; + passwd : Pchar; + unix_socket : Pchar; + server_version : Pchar; + host_info : Pchar; + info : Pchar; + db : Pchar; + charset : Pcharset_info_st; + fields : PMYSQL_FIELD; + field_alloc : MEM_ROOT; + affected_rows : my_ulonglong; + insert_id : my_ulonglong; // id if insert on table with NEXTNR + extra_info : my_ulonglong; // Used by mysqlshow, not used by mysql 5.0 and up + thread_id : culong; // Id for connection in server + packet_length : culong; + port : cuint; + client_flag : culong; + server_capabilities : culong; + protocol_version : cuint; + field_count : cuint; + server_status : cuint; + server_language : cuint; + warning_count : cuint; + options : st_mysql_options; + status : mysql_status; + free_me : my_bool; // If free in mysql_close + reconnect : my_bool; // set to 1 if automatic reconnect + scramble : array[0..(SCRAMBLE_LENGTH+1)-1] of char; // session-wide random string + { Set if this is the original connection, not a master or a slave we have + added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave() } + rpl_pivot : my_bool; + { Pointers to the master, and the next slave connections, points to + itself if lone connection. } + master : Pst_mysql; + next_slave : Pst_mysql; + last_used_slave : Pst_mysql; // needed for round-robin slave pick + last_used_con : Pst_mysql; // needed for send/read/store/use result to work correctly with replication +{$IFDEF mysql41} + stmts : Pointer; // was PList, list of all statements + methods : Pst_mysql_methods; + thd : pointer; + { Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag + from mysql_stmt_close if close had to cancel result set of this object. } + unbuffered_fetch_owner : Pmy_bool; +{$ENDIF} +{$ifdef mysql51} + info_buffer: pchar; + extension: pointer; +{$endif} + end; + MYSQL = st_mysql; + PMYSQL = ^MYSQL; + + + Pst_mysql_res = ^st_mysql_res; +{$ifdef mysql51} + st_mysql_res = record + row_count : my_ulonglong; + fields : PMYSQL_FIELD; + data : PMYSQL_DATA; + data_cursor : PMYSQL_ROWS; + lengths : pculong; // column lengths of current row + handle : PMYSQL; // for unbuffered reads + methods : Pst_mysql_methods; + row : MYSQL_ROW; // If unbuffered read + current_row : MYSQL_ROW; // buffer to current row + field_alloc : MEM_ROOT; + field_count : cuint; + current_field : cuint; + eof : my_bool; // Used by mysql_fetch_row + unbuffered_fetch_cancelled : my_bool; // mysql_stmt_close() had to cancel this result + extension: pointer; + end; +{$else} + st_mysql_res = record + row_count : my_ulonglong; + fields : PMYSQL_FIELD; + data : PMYSQL_DATA; + data_cursor : PMYSQL_ROWS; + lengths : pculong; // column lengths of current row + handle : PMYSQL; // for unbuffered reads + field_alloc : MEM_ROOT; + field_count : cuint; + current_field : cuint; + row : MYSQL_ROW; // If unbuffered read + current_row : MYSQL_ROW; // buffer to current row + eof : my_bool; // Used by mysql_fetch_row +{$IFDEF mysql41} + unbuffered_fetch_cancelled : my_bool; // mysql_stmt_close() had to cancel this result + + methods : Pst_mysql_methods; +{$ENDIF} + end; +{$endif} + MYSQL_RES = st_mysql_res; + PMYSQL_RES = ^MYSQL_RES; + + Pst_mysql_stmt = ^st_mysql_stmt; + PMYSQL_STMT = ^MYSQL_STMT; + + st_mysql_methods = record + read_query_result : function (mysql:PMYSQL):my_bool;cdecl; +{$ifdef mysql51} + advanced_command : function (mysql:PMYSQL; command:enum_server_command; header:Pbyte; header_length:culong; arg:Pbyte; + arg_length:culong; skip_check:my_bool):my_bool; +{$else} + advanced_command : function (mysql:PMYSQL; command:enum_server_command; header:Pchar; header_length:culong; arg:Pchar; + arg_length:culong; skip_check:my_bool):my_bool; +{$endif} + read_rows : function (mysql:PMYSQL; mysql_fields:PMYSQL_FIELD; fields:cuint):PMYSQL_DATA; + use_result : function (mysql:PMYSQL):PMYSQL_RES; + fetch_lengths : procedure (fto:pculong; column:MYSQL_ROW; field_count:cuint); + flush_use_result : procedure (mysql:PMYSQL); +{ $if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY)} + list_fields : function (mysql:PMYSQL):PMYSQL_FIELD; + read_prepare_result : function (mysql:PMYSQL; stmt:PMYSQL_STMT):my_bool; + stmt_execute : function (stmt:PMYSQL_STMT):cint; + read_binary_rows : function (stmt:PMYSQL_STMT):cint; + unbuffered_fetch : function (mysql:PMYSQL; row:PPchar):cint; + free_embedded_thd : procedure (mysql:PMYSQL); + read_statistics : function (mysql:PMYSQL):Pchar; + next_result : function (mysql:PMYSQL):my_bool; + read_change_user_result : function (mysql:PMYSQL; buff:Pchar; passwd:Pchar):cint; +{$IFDEF mysql50} + read_rowsfrom_cursor : function (stmt:PMYSQL_STMT):cint; +{$ENDIF mysql50} +{ $endif} + end; + MYSQL_METHODS = st_mysql_methods; + PMYSQL_METHODS = ^MYSQL_METHODS; + + + Pst_mysql_manager = ^st_mysql_manager; +{$ifdef mysql51} + st_mysql_manager = record + net : NET; + host : Pchar; + user : Pchar; + passwd : Pchar; + net_buf : Pchar; + net_buf_pos : Pchar; + net_data_end : Pchar; + port : cuint; + cmd_status : cint; + last_errno : cint; + net_buf_size : cint; + free_me : my_bool; + eof : my_bool; + last_error : array[0..(MAX_MYSQL_MANAGER_ERR)-1] of char; + extension: pointer; + end; +{$else} + st_mysql_manager = record + net : NET; + host : Pchar; + user : Pchar; + passwd : Pchar; + port : cuint; + free_me : my_bool; + eof : my_bool; + cmd_status : cint; + last_errno : cint; + net_buf : Pchar; + net_buf_pos : Pchar; + net_data_end : Pchar; + net_buf_size : cint; + last_error : array[0..(MAX_MYSQL_MANAGER_ERR)-1] of char; + end; +{$endif} + MYSQL_MANAGER = st_mysql_manager; + PMYSQL_MANAGER = ^MYSQL_MANAGER; + + Pst_mysql_parameters = ^st_mysql_parameters; + st_mysql_parameters = record + p_max_allowed_packet : pculong; + p_net_buffer_length : pculong; + end; + MYSQL_PARAMETERS = st_mysql_parameters; + PMYSQL_PARAMETERS = ^MYSQL_PARAMETERS; + + { The following definitions are added for the enhanced + client-server protocol } + + { statement state } + + { + Note: this info is from the mysql-5.0 version: + + This structure is used to define bind information, and + internally by the client library. + Public members with their descriptions are listed below + (conventionally `On input' refers to the binds given to + mysql_stmt_bind_param, `On output' refers to the binds given + to mysql_stmt_bind_result): + + buffer_type - One of the MYSQL_* types, used to describe + the host language type of buffer. + On output: if column type is different from + buffer_type, column value is automatically converted + to buffer_type before it is stored in the buffer. + buffer - On input: points to the buffer with input data. + On output: points to the buffer capable to store + output data. + The type of memory pointed by buffer must correspond + to buffer_type. See the correspondence table in + the comment to mysql_stmt_bind_param. + + The two above members are mandatory for any kind of bind. + + buffer_length - the length of the buffer. You don't have to set + it for any fixed length buffer: float, double, + int, etc. It must be set however for variable-length + types, such as BLOBs or STRINGs. + + length - On input: in case when lengths of input values + are different for each execute, you can set this to + point at a variable containining value length. This + way the value length can be different in each execute. + If length is not NULL, buffer_length is not used. + Note, length can even point at buffer_length if + you keep bind structures around while fetching: + this way you can change buffer_length before + each execution, everything will work ok. + On output: if length is set, mysql_stmt_fetch will + write column length into it. + + is_null - On input: points to a boolean variable that should + be set to TRUE for NULL values. + This member is useful only if your data may be + NULL in some but not all cases. + If your data is never NULL, is_null should be set to 0. + If your data is always NULL, set buffer_type + to MYSQL_TYPE_NULL, and is_null will not be used. + + is_unsigned - On input: used to signify that values provided for one + of numeric types are unsigned. + On output describes signedness of the output buffer. + If, taking into account is_unsigned flag, column data + is out of range of the output buffer, data for this column + is regarded truncated. Note that this has no correspondence + to the sign of result set column, if you need to find it out + use mysql_stmt_result_metadata. + error - where to write a truncation error if it is present. + possible error value is: + 0 no truncation + 1 value is out of range or buffer is too small + + Please note that MYSQL_BIND also has internals members. + } + +{$ifdef mysql51} + Pst_mysql_bind_51 = ^st_mysql_bind_51; + st_mysql_bind_51 = record + length : pculong; // output length pointer + is_null : Pmy_bool; // Pointer to null indicator + buffer : pointer; // buffer to get/put data + error: pmy_bool; // set this if you want to track data truncations happened during fetch + row_ptr : PByte; // for the current data position + store_param_func : procedure (net:PNET; param:Pst_mysql_bind_51);cdecl; + fetch_result : procedure (_para1:Pst_mysql_bind_51; _para2:PMYSQL_FIELD; row:PPbyte); + skip_result : procedure (_para1:Pst_mysql_bind_51; _para2:PMYSQL_FIELD; row:PPbyte); + buffer_length : culong; // buffer length, must be set for str/binary + offset : culong; // offset position for char/binary fetch + length_value : culong; // Used if length is 0 + param_number : cuint; // For null count and error messages + pack_length : cuint; // Internal length for packed data + buffer_type : enum_field_types; // buffer type + error_value : my_bool; // used if error is 0 + is_unsigned : my_bool; // set if integer type is unsigned + long_data_used : my_bool; // If used with mysql_send_long_data + is_null_value : my_bool; // Used if is_null is 0 + extension: pointer; + end; + + MYSQL_BIND_51 = st_mysql_bind_51; + PMYSQL_BIND_51 = ^MYSQL_BIND_51; + + Pst_mysql_bind_50 = ^st_mysql_bind_50; + st_mysql_bind_50 = record + length : pculong; // output length pointer + is_null : Pmy_bool; // Pointer to null indicator + buffer : pointer; // buffer to get/put data + error: pmy_bool; // set this if you want to track data truncations happened during fetch + buffer_type : enum_field_types; // buffer type + buffer_length : culong; // buffer length, must be set for str/binary + { Following are for internal use. Set by mysql_stmt_bind_param } + row_ptr : PByte; // for the current data position + offset : culong; // offset position for char/binary fetch + length_value : culong; // Used if length is 0 + param_number : cuint; // For null count and error messages + pack_length : cuint; // Internal length for packed data + error_value : my_bool; // used if error is 0 + is_unsigned : my_bool; // set if integer type is unsigned + long_data_used : my_bool; // If used with mysql_send_long_data + is_null_value : my_bool; // Used if is_null is 0 + store_param_func : procedure (net:PNET; param:Pst_mysql_bind_50);cdecl; + fetch_result : procedure (_para1:Pst_mysql_bind_50; _para2:PMYSQL_FIELD; row:PPbyte); + skip_result : procedure (_para1:Pst_mysql_bind_50; _para2:PMYSQL_FIELD; row:PPbyte); + end; + + MYSQL_BIND_50 = st_mysql_bind_50; + PMYSQL_BIND_50 = ^MYSQL_BIND_50; +{$else} + Pst_mysql_bind = ^st_mysql_bind; + st_mysql_bind = record + length : pculong; // output length pointer + is_null : Pmy_bool; // Pointer to null indicator + buffer : pointer; // buffer to get/put data +{$IFDEF mysql50} + error: pmy_bool; // set this if you want to track data truncations happened during fetch +{$ENDIF} + buffer_type : enum_field_types; // buffer type + buffer_length : culong; // buffer length, must be set for str/binary + { Following are for internal use. Set by mysql_stmt_bind_param } +{$IFNDEF mysql50} + inter_buffer : Pbyte; // for the current data position +{$ELSE} + row_ptr : PByte; // for the current data position +{$ENDIF} + offset : culong; // offset position for char/binary fetch +{$IFNDEF mysql50} + internal_length : culong; // Used if length is 0 +{$ELSE} + length_value : culong; // Used if length is 0 +{$ENDIF} + param_number : cuint; // For null count and error messages + pack_length : cuint; // Internal length for packed data +{$IFDEF mysql50} + error_value : my_bool; // used if error is 0 +{$ENDIF} + is_unsigned : my_bool; // set if integer type is unsigned + long_data_used : my_bool; // If used with mysql_send_long_data +{$IFNDEF mysql50} + internal_is_null : my_bool; // Used if is_null is 0 +{$ELSE} + is_null_value : my_bool; // Used if is_null is 0 +{$ENDIF} + store_param_func : procedure (net:PNET; param:Pst_mysql_bind);cdecl; + fetch_result : procedure (_para1:Pst_mysql_bind; _para2:PMYSQL_FIELD; row:PPbyte); + skip_result : procedure (_para1:Pst_mysql_bind; _para2:PMYSQL_FIELD; row:PPbyte); + end; + MYSQL_BIND = st_mysql_bind; + PMYSQL_BIND = ^MYSQL_BIND; +{$endif} + + { statement handler } +{$ifdef mysql51} + st_mysql_stmt = record + mem_root : MEM_ROOT; // root allocations + list : LIST; // list to keep track of all stmts + mysql : PMYSQL; // connection handle + params : PMYSQL_BIND_51; // input parameters + bind : PMYSQL_BIND_51; // input parameters + fields : PMYSQL_FIELD; // result set metadata + result : MYSQL_DATA; // cached result set + data_cursor : PMYSQL_ROWS; // current row in cached result + { mysql_stmt_fetch() calls this function to fetch one row (it's different + for buffered, unbuffered and cursor fetch). } + read_row_func : function (stmt:Pst_mysql_stmt; row:PPbyte):cint;cdecl; + affected_rows : my_ulonglong; // copy of mysql->affected_rows after statement execution + insert_id : my_ulonglong; // copy of mysql->insert_id + stmt_id : culong; // Id for prepared statement + flags : culong; // i.e. type of cursor to open + prefetch_rows : culong; // number of rows per one COM_FETCH + server_status : cuint; // Copied from mysql->server_status after execute/fetch to know + // server-side cursor status for this statement. + last_errno : cuint; // error code + param_count : cuint; // input parameter count + field_count : cuint; // number of columns in result set + state : enum_mysql_stmt_state; // statement state + last_error : array[0..(MYSQL_ERRMSG_SIZE)-1] of char; // error message + sqlstate : array[0..(SQLSTATE_LENGTH+1)-1] of char; + send_types_to_server : my_bool; // Types of input parameters should be sent to server + bind_param_done : my_bool; // input buffers were supplied + bind_result_done : cuchar; // output buffers were supplied + + unbuffered_fetch_cancelled : my_bool; // mysql_stmt_close() had to cancel this result + { Is set to true if we need to calculate field->max_length for + metadata fields when doing mysql_stmt_store_result. } + update_max_length : my_bool; + extension: pointer; + end; +{$else} + st_mysql_stmt = record + mem_root : MEM_ROOT; // root allocations + list : LIST; // list to keep track of all stmts + mysql : PMYSQL; // connection handle + params : PMYSQL_BIND; // input parameters + bind : PMYSQL_BIND; // input parameters + fields : PMYSQL_FIELD; // result set metadata + result : MYSQL_DATA; // cached result set + data_cursor : PMYSQL_ROWS; // current row in cached result + affected_rows : my_ulonglong; // copy of mysql->affected_rows after statement execution + insert_id : my_ulonglong; // copy of mysql->insert_id + { mysql_stmt_fetch() calls this function to fetch one row (it's different + for buffered, unbuffered and cursor fetch). } + read_row_func : function (stmt:Pst_mysql_stmt; row:PPbyte):cint;cdecl; + stmt_id : culong; // Id for prepared statement +{$IFDEF mysql50} + flags : culong; // i.e. type of cursor to open + prefetch_rows : culong; // number of rows per one COM_FETCH + server_status : cuint; // Copied from mysql->server_status after execute/fetch to know + // server-side cursor status for this statement. +{$ENDIF} + last_errno : cuint; // error code + param_count : cuint; // input parameter count + field_count : cuint; // number of columns in result set + state : enum_mysql_stmt_state; // statement state + last_error : array[0..(MYSQL_ERRMSG_SIZE)-1] of char; // error message + sqlstate : array[0..(SQLSTATE_LENGTH+1)-1] of char; + send_types_to_server : my_bool; // Types of input parameters should be sent to server + bind_param_done : my_bool; // input buffers were supplied +{$IFNDEF mysql50} + bind_result_done : my_bool; // output buffers were supplied +{$ELSE} + bind_result_done : cuchar; // output buffers were supplied +{$ENDIF} + + unbuffered_fetch_cancelled : my_bool; // mysql_stmt_close() had to cancel this result + { Is set to true if we need to calculate field->max_length for + metadata fields when doing mysql_stmt_store_result. } + update_max_length : my_bool; + end; +{$endif} + + MYSQL_STMT = st_mysql_stmt; + { When doing mysql_stmt_store_result calculate max_length attribute + of statement metadata. This is to be consistent with the old API, + where this was done automatically. + In the new API we do that only by request because it slows down + mysql_stmt_store_result sufficiently. } + enum_stmt_attr_type = (STMT_ATTR_UPDATE_MAX_LENGTH +{$IFDEF mysql50} + ,STMT_ATTR_CURSOR_TYPE, // unsigned long with combination of cursor flags (read only, for update, etc) + STMT_ATTR_PREFETCH_ROWS // Amount of rows to retrieve from server per one fetch if using cursors. + // Accepts unsigned long attribute in the range 1 - ulong_max +{$ENDIF} + ); + + +//#define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet) +//#define net_buffer_length (*mysql_get_parameters()->p_net_buffer_length) + +{$IFNDEF LinkDynamically} + { Set up and bring down the server; to ensure that applications will + work when linked against either the standard client library or the + embedded server library, these functions should be called. } + function mysql_server_init(argc:cint; argv:PPchar; groups:PPchar):cint;cdecl;external mysqllib name 'mysql_server_init'; + procedure mysql_server_end;cdecl;external mysqllib name 'mysql_server_end'; + + { mysql_server_init/end need to be called when using libmysqld or + libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so + you don't need to call it explicitely; but you need to call + mysql_server_end() to free memory). The names are a bit misleading + (mysql_SERVER* to be used when using libmysqlCLIENT). So we add more general + names which suit well whether you're using libmysqld or libmysqlclient. We + intend to promote these aliases over the mysql_server* ones. } + + function mysql_library_init(argc:cint; argv:PPchar; groups:PPchar):cint;cdecl;external mysqllib name 'mysql_server_init'; + procedure mysql_library_end;cdecl;external mysqllib name 'mysql_server_end'; + + function mysql_get_parameters:PMYSQL_PARAMETERS;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_parameters'; + + { Set up and bring down a thread; these function should be called + for each thread in an application which opens at least one MySQL + connection. All uses of the connection(s) should be between these + function calls. } + function mysql_thread_init:my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_thread_init'; + procedure mysql_thread_end;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_thread_end'; + { Functions to get information from the MYSQL and MYSQL_RES structures + Should definitely be used if one uses shared libraries. } + function mysql_num_rows(res:PMYSQL_RES):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_num_rows'; + function mysql_num_fields(res:PMYSQL_RES):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_num_fields'; + function mysql_eof(res:PMYSQL_RES):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_eof'; + function mysql_fetch_field_direct(res:PMYSQL_RES; fieldnr:cuint):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_fetch_field_direct'; + function mysql_fetch_fields(res:PMYSQL_RES):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_fetch_fields'; + function mysql_row_tell(res:PMYSQL_RES):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_row_tell'; + function mysql_field_tell(res:PMYSQL_RES):MYSQL_FIELD_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_field_tell'; + function mysql_field_count(mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_field_count'; + function mysql_affected_rows(mysql:PMYSQL):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_affected_rows'; + function mysql_insert_id(mysql:PMYSQL):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_insert_id'; + function mysql_errno(mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_errno'; + function mysql_error(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_error'; + function mysql_sqlstate(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_sqlstate'; + function mysql_warning_count(mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_warning_count'; + function mysql_info(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_info'; + function mysql_thread_id(mysql:PMYSQL):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_thread_id'; + function mysql_character_set_name(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_character_set_name'; + function mysql_set_character_set(mysql:PMYSQL; csname:Pchar):longint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_set_character_set'; + function mysql_init(mysql:PMYSQL):PMYSQL;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_init'; + function mysql_ssl_set(mysql:PMYSQL; key:Pchar; cert:Pchar; ca:Pchar; capath:Pchar; + cipher:Pchar):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_ssl_set'; + function mysql_change_user(mysql:PMYSQL; user:Pchar; passwd:Pchar; db:Pchar):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_change_user'; + function mysql_real_connect(mysql:PMYSQL; host:Pchar; user:Pchar; passwd:Pchar; db:Pchar; + port:cuint; unix_socket:Pchar; clientflag:culong):PMYSQL;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_real_connect'; + function mysql_select_db(mysql:PMYSQL; db:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_select_db'; + function mysql_query(mysql:PMYSQL; q:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_query'; + function mysql_send_query(mysql:PMYSQL; q:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_send_query'; + function mysql_real_query(mysql:PMYSQL; q:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_real_query'; + function mysql_store_result(mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_store_result'; + function mysql_use_result(mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_use_result'; + +{$ELSE} + +{$ENDIF} + +{$IFNDEF LinkDynamically} + { perform query on master } + function mysql_master_query(mysql:PMYSQL; q:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_master_query'; + function mysql_master_send_query(mysql:PMYSQL; q:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_master_send_query'; + + { perform query on slave } + function mysql_slave_query(mysql:PMYSQL; q:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_slave_query'; + function mysql_slave_send_query(mysql:PMYSQL; q:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_slave_send_query'; +{$IFDEF mysql50} + procedure mysql_get_character_set_info(mysql : PMYSQL; charset : PMY_CHARSET_INFO);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_character_set_info'; +{$ENDIF} +{$ENDIF} + + { local infile support } + + const + LOCAL_INFILE_ERROR_LEN = 512; + +{$IFNDEF LinkDynamically} +{ procedure mysql_set_local_infile_handler(mysql:PMYSQL; local_infile_init:function (_para1:Ppointer; _para2:Pchar; _para3:pointer):longint; local_infile_read:function (_para1:pointer; _para2:Pchar; _para3:dword):longint; local_infile_end:procedure (_pa + _para6:pointer);cdecl;external mysqllib name 'mysql_set_local_infile_handler';} + procedure mysql_set_local_infile_default(mysql:PMYSQL);cdecl;external mysqllib name 'mysql_set_local_infile_default'; + + { enable/disable parsing of all queries to decide if they go on master or + slave } + procedure mysql_enable_rpl_parse(mysql:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_enable_rpl_parse'; + procedure mysql_disable_rpl_parse(mysql:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_disable_rpl_parse'; + + { get the value of the parse flag } + function mysql_rpl_parse_enabled(mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_rpl_parse_enabled'; + + { enable/disable reads from master } + procedure mysql_enable_reads_from_master(mysql:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_enable_reads_from_master'; + procedure mysql_disable_reads_from_master(mysql:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_disable_reads_from_master'; + + { get the value of the master read flag } + function mysql_reads_from_master_enabled(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_reads_from_master_enabled'; + + function mysql_rpl_query_type(q : pchar;len : cint):mysql_rpl_type;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_rpl_query_type'; + + { discover the master and its slaves } + function mysql_rpl_probe(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_rpl_probe'; + + { set the master, close/free the old one, if it is not a pivot } + function mysql_set_master(mysql:PMYSQL; host:Pchar; port:cuint; user:Pchar; passwd:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_set_master'; + function mysql_add_slave(mysql:PMYSQL; host:Pchar; port:cuint; user:Pchar; passwd:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_add_slave'; + function mysql_shutdown(mysql:PMYSQL; shutdown_level:mysql_enum_shutdown_level):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_shutdown'; + function mysql_dump_debug_info(mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_dump_debug_info'; + function mysql_refresh(mysql:PMYSQL; refresh_options:cuint):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_refresh'; + function mysql_kill(mysql:PMYSQL; pid:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_kill'; + function mysql_set_server_option(mysql:PMYSQL; option:enum_mysql_set_option):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_set_server_option'; + function mysql_ping(mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_ping'; + function mysql_stat(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stat'; + function mysql_get_server_info(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_server_info'; + function mysql_get_client_info:Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_client_info'; + function mysql_get_client_version:culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_client_version'; + function mysql_get_host_info(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_host_info'; + function mysql_get_server_version(mysql:PMYSQL):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_server_version'; + function mysql_get_proto_info(mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_proto_info'; + function mysql_list_dbs(mysql:PMYSQL; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_list_dbs'; + + function mysql_list_tables(mysql:PMYSQL; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_list_tables'; + function mysql_list_processes(mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_list_processes'; +{$ifdef mysql51} + function mysql_options(mysql:PMYSQL; option:mysql_option; arg: pointer):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_options'; +{$else} + function mysql_options(mysql:PMYSQL; option:mysql_option; arg:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_options'; +{$endif} + procedure mysql_free_result(result:PMYSQL_RES);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_free_result'; + procedure mysql_data_seek(result:PMYSQL_RES; offset:my_ulonglong);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_data_seek'; + function mysql_row_seek(result:PMYSQL_RES; offset:MYSQL_ROW_OFFSET):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_row_seek'; + function mysql_field_seek(result:PMYSQL_RES; offset:MYSQL_FIELD_OFFSET):MYSQL_FIELD_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_field_seek'; + function mysql_fetch_row(result:PMYSQL_RES):MYSQL_ROW;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_fetch_row'; + function mysql_fetch_lengths(result:PMYSQL_RES):pculong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_fetch_lengths'; + function mysql_fetch_field(result:PMYSQL_RES):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_fetch_field'; + function mysql_list_fields(mysql:PMYSQL; table:Pchar; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_list_fields'; + function mysql_escape_string(fto:Pchar; from:Pchar; from_length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_escape_string'; + function mysql_hex_string(fto:Pchar; from:Pchar; from_length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_hex_string'; + function mysql_real_escape_string(mysql:PMYSQL; fto:Pchar; from:Pchar; length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_real_escape_string'; + procedure mysql_debug(debug:Pchar);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_debug'; +(* function mysql_odbc_escape_string(mysql:PMYSQL; fto:Pchar; to_length:dword; from:Pchar; from_length:dword; + param:pointer; extend_buffer:function (_para1:pointer; to:Pchar; length:Pdword):Pchar):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_odbc_escape_string';*) + procedure myodbc_remove_escape(mysql:PMYSQL; name:Pchar);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'myodbc_remove_escape'; + function mysql_thread_safe:cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_thread_safe'; + function mysql_embedded:my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_embedded'; + function mysql_manager_init(con:PMYSQL_MANAGER):PMYSQL_MANAGER;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_manager_init'; + function mysql_manager_connect(con:PMYSQL_MANAGER; host:Pchar; user:Pchar; passwd:Pchar; port:cuint):PMYSQL_MANAGER;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_manager_connect'; + procedure mysql_manager_close(con:PMYSQL_MANAGER);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_manager_close'; + function mysql_manager_command(con:PMYSQL_MANAGER; cmd:Pchar; cmd_len:cint):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_manager_command'; + function mysql_manager_fetch_line(con:PMYSQL_MANAGER; res_buf:Pchar; res_buf_size:cint):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_manager_fetch_line'; + function mysql_read_query_result(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_read_query_result'; + + function mysql_stmt_init(mysql:PMYSQL):PMYSQL_STMT;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_init'; + function mysql_stmt_prepare(stmt:PMYSQL_STMT; query:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_prepare'; + function mysql_stmt_execute(stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_execute'; + function mysql_stmt_fetch(stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_fetch'; +{$ifdef mysql51} + function mysql_stmt_fetch_column(stmt:PMYSQL_STMT; bind: pointer{PMYSQL_BIND}; column:cuint; offset:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_fetch_column'; +{$else} + function mysql_stmt_fetch_column(stmt:PMYSQL_STMT; bind:PMYSQL_BIND; column:cuint; offset:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_fetch_column'; +{$endif} + function mysql_stmt_store_result(stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_store_result'; + function mysql_stmt_param_count(stmt:PMYSQL_STMT):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_param_count'; + function mysql_stmt_attr_set(stmt:PMYSQL_STMT; attr_type:enum_stmt_attr_type; attr:pointer):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_attr_set'; + function mysql_stmt_attr_get(stmt:PMYSQL_STMT; attr_type:enum_stmt_attr_type; attr:pointer):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_attr_get'; + function mysql_stmt_bind_param(stmt:PMYSQL_STMT; bnd:PMYSQL_BIND):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_bind_param'; + function mysql_stmt_bind_result(stmt:PMYSQL_STMT; bnd:PMYSQL_BIND):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_bind_result'; + function mysql_stmt_close(stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_close'; + function mysql_stmt_reset(stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_reset'; + function mysql_stmt_free_result(stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_free_result'; + function mysql_stmt_send_long_data(stmt:PMYSQL_STMT; param_number:cuint; data:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_send_long_data'; + function mysql_stmt_result_metadata(stmt:PMYSQL_STMT):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_result_metadata'; + function mysql_stmt_param_metadata(stmt:PMYSQL_STMT):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_param_metadata'; + function mysql_stmt_errno(stmt:PMYSQL_STMT):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_errno'; + function mysql_stmt_error(stmt:PMYSQL_STMT):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_error'; + function mysql_stmt_sqlstate(stmt:PMYSQL_STMT):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_sqlstate'; + function mysql_stmt_row_seek(stmt:PMYSQL_STMT; offset:MYSQL_ROW_OFFSET):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_row_seek'; + function mysql_stmt_row_tell(stmt:PMYSQL_STMT):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_row_tell'; + procedure mysql_stmt_data_seek(stmt:PMYSQL_STMT; offset:my_ulonglong);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_data_seek'; + function mysql_stmt_num_rows(stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_num_rows'; + function mysql_stmt_affected_rows(stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_affected_rows'; + function mysql_stmt_insert_id(stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_insert_id'; + function mysql_stmt_field_count(stmt:PMYSQL_STMT):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_field_count'; + + function mysql_commit(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_commit'; + function mysql_rollback(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_rollback'; + function mysql_autocommit(mysql:PMYSQL; auto_mode:my_bool):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_autocommit'; + function mysql_more_results(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_more_results'; + function mysql_next_result(mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_next_result'; + procedure mysql_close(sock:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_close'; + +{$ELSE} + +{$ENDIF} + + + { status return codes } + + const + MYSQL_NO_DATA = 100; + MYSQL_DATA_TRUNCATED = 101; + + function mysql_reload(mysql : PMySQL) : cint; + +{$IFNDEF LinkDynamically} +{$ifdef USE_OLD_FUNCTIONS} + function mysql_connect(mysql:PMYSQL; host:Pchar; user:Pchar; passwd:Pchar):PMYSQL;{$ifdef wincall}stdcall{$else}cdecl{$endif};external External_library name 'mysql_connect'; + function mysql_create_db(mysql:PMYSQL; DB:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external External_library name 'mysql_create_db'; + function mysql_drop_db(mysql:PMYSQL; DB:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external External_library name 'mysql_drop_db'; + function mysql_reload(mysql : PMySQL) : cint; +{$endif} +{$endif} + +{$define HAVE_MYSQL_REAL_CONNECT} + { The following functions are mainly exported because of mysqlbinlog; + They are not for general usage } + + function simple_command(mysql,command,arg,length,skip_check : cint) : cint; +{$IFNDEF LinkDynamically} + function net_safe_read(mysql:PMYSQL):cuint;cdecl;external mysqllib name 'net_safe_read'; +{$ENDIF} + +{$ifdef NETWARE} +(** unsupported pragma#pragma pack(pop) /* restore alignment */*) +{$endif} + +{$IFDEF LinkDynamically} +//Function InitialiseMysql(Const LibraryName : String) : Integer; +//Function InitialiseMysql : Integer; + +//var MysqlLibraryHandle : TLibHandle; +{$ENDIF} + +// var +// my_init : function :my_bool;cdecl; +// my_thread_init : function :my_bool;cdecl; +// my_thread_end : procedure ;cdecl; + var + mysql_server_init: function (argc:cint; argv:PPchar; groups:PPchar):cint;cdecl; + mysql_server_end: procedure ;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_library_init: function (argc:cint; argv:PPchar; groups:PPchar):cint;cdecl; + mysql_library_end: procedure ;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_num_rows: function (res:PMYSQL_RES):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_num_fields: function (res:PMYSQL_RES):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_eof: function (res:PMYSQL_RES):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_fetch_field_direct: function (res:PMYSQL_RES; fieldnr:cuint):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_fetch_fields: function (res:PMYSQL_RES):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_row_tell: function (res:PMYSQL_RES):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_field_tell: function (res:PMYSQL_RES):MYSQL_FIELD_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_field_count: function (mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_affected_rows: function (mysql:PMYSQL):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_insert_id: function (mysql:PMYSQL):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_errno: function (mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_error: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_sqlstate: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_warning_count: function (mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_info: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_thread_id: function (mysql:PMYSQL):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_character_set_name: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_set_character_set: function (mysql:PMYSQL; csname:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_character_set_info: procedure(mysql : PMYSQL; charset : PMY_CHARSET_INFO);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_init: function (mysql:PMYSQL):PMYSQL;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_ssl_set: function (mysql:PMYSQL; key:Pchar; cert:Pchar; ca:Pchar; capath:Pchar; + cipher:Pchar):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_ssl_cipher: function (mysql: pmysql): pchar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_change_user: function (mysql:PMYSQL; user:Pchar; passwd:Pchar; db:Pchar):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_real_connect: function (mysql:PMYSQL; host:Pchar; user:Pchar; passwd:Pchar; db:Pchar; + port:cuint; unix_socket:Pchar; clientflag:culong):PMYSQL;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_select_db: function (mysql:PMYSQL; db:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_query: function (mysql:PMYSQL; q:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_send_query: function (mysql:PMYSQL; q:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_real_query: function (mysql:PMYSQL; q:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_store_result: function (mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_use_result: function (mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + var + mysql_shutdown: function (mysql:PMYSQL; shutdown_level:mysql_enum_shutdown_level):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_dump_debug_info: function (mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_refresh: function (mysql:PMYSQL; refresh_options:cuint):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_kill: function (mysql:PMYSQL; pid:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_set_server_option: function (mysql:PMYSQL; option:enum_mysql_set_option):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_ping: function (mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stat: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_server_info: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_client_info: function :Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_client_version: function :culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_host_info: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_server_version: function (mysql:PMYSQL):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_proto_info: function (mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_list_dbs: function (mysql:PMYSQL; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + + mysql_list_tables: function (mysql:PMYSQL; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_list_processes: function (mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ifdef mysql51} + mysql_options: function (mysql:PMYSQL; option:mysql_option; arg: pointer):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$else} + mysql_options: function (mysql:PMYSQL; option:mysql_option; arg:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$endif} + mysql_free_result: procedure (result:PMYSQL_RES);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_data_seek: procedure (result:PMYSQL_RES; offset:my_ulonglong);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_row_seek: function (result:PMYSQL_RES; offset:MYSQL_ROW_OFFSET):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_field_seek: function (result:PMYSQL_RES; offset:MYSQL_FIELD_OFFSET):MYSQL_FIELD_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_fetch_row: function (result:PMYSQL_RES):MYSQL_ROW;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_fetch_lengths: function (result:PMYSQL_RES):pculong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_fetch_field: function (result:PMYSQL_RES):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_list_fields: function (mysql:PMYSQL; table:Pchar; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_escape_string: function (fto:Pchar; from:Pchar; from_length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_hex_string: function (fto:Pchar; from:Pchar; from_length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_real_escape_string: function (mysql:PMYSQL; fto:Pchar; from:Pchar; length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_debug: procedure (debug:Pchar);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + + mysql_rollback: function (mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_autocommit: function (mysql:PMYSQL; auto_mode:my_bool):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_commit: function (mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_more_results: function (mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_next_result: function (mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_close: procedure (sock:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + + mysql_stmt_init: function (mysql:PMYSQL):PMYSQL_STMT;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_prepare: function (stmt:PMYSQL_STMT; query:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_execute: function (stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_fetch: function (stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ifdef mysql51} + mysql_stmt_fetch_column: function (stmt:PMYSQL_STMT; bind:pointer{PMYSQL_BIND}; column:cuint; offset:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$else} + mysql_stmt_fetch_column: function (stmt:PMYSQL_STMT; bind:PMYSQL_BIND; column:cuint; offset:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$endif} + mysql_stmt_store_result: function (stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_param_count: function (stmt:PMYSQL_STMT):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_attr_set: function (stmt:PMYSQL_STMT; attr_type:enum_stmt_attr_type; attr:pointer):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_attr_get: function (stmt:PMYSQL_STMT; attr_type:enum_stmt_attr_type; attr:pointer):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ifdef mysql51} + mysql_stmt_bind_param: function (stmt:PMYSQL_STMT; bnd:pointer{PMYSQL_BIND}):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_bind_result: function (stmt:PMYSQL_STMT; bnd:pointer{PMYSQL_BIND}):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$else} + mysql_stmt_bind_param: function (stmt:PMYSQL_STMT; bnd:PMYSQL_BIND):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_bind_result: function (stmt:PMYSQL_STMT; bnd:PMYSQL_BIND):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$endif} + mysql_stmt_close: function (stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_reset: function (stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_free_result: function (stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_send_long_data: function (stmt:PMYSQL_STMT; param_number:cuint; data:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_result_metadata: function (stmt:PMYSQL_STMT):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_param_metadata: function (stmt:PMYSQL_STMT):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_errno: function (stmt:PMYSQL_STMT):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_error: function (stmt:PMYSQL_STMT):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_sqlstate: function (stmt:PMYSQL_STMT):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_row_seek: function (stmt:PMYSQL_STMT; offset:MYSQL_ROW_OFFSET): + MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_row_tell: function (stmt:PMYSQL_STMT):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_data_seek: procedure (stmt:PMYSQL_STMT; offset:my_ulonglong);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_num_rows: function (stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_affected_rows: function (stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_insert_id: function (stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_field_count: function (stmt:PMYSQL_STMT):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + +implementation +uses + msesys,msesysintf{,msesonames} + {$IFDEF LinkDynamically},msedynload{$endif}; + +{$IFDEF LinkDynamically} + +ResourceString + SErrAlreadyLoaded = 'MySQL interface already initialized from library %s.'; + SErrLoadFailed = 'Can not load MySQL library "%s". Please check your installation.'; + SErrDefaultsFailed = 'Can not load default MySQL library ("%s" or "%s"). Check your installation.'; + +var + libinfo: dynlibinfoty; +// liblock: mutexty; +// RefCount : integer; +// LoadedLibrary : String; + + function net_new_transaction(net : st_net) : st_net; + begin + net.pkt_nr := 0; + result := net; + end; + + function IS_PRI_KEY(n : longint) : boolean; + begin + IS_PRI_KEY:=(n and PRI_KEY_FLAG)<>0; + end; + + function IS_NOT_NULL(n : longint) : boolean; + begin + IS_NOT_NULL:=(n and NOT_NULL_FLAG)<>0; + end; + + function IS_BLOB(n : longint) : boolean; + begin + IS_BLOB:=(n and BLOB_FLAG)<>0; + end; + + function IS_NUM_FIELD(f : pst_mysql_field) : boolean; + begin + IS_NUM_FIELD:=((f^.flags) and NUM_FLAG)<>0; + end; + + function IS_NUM(t : enum_field_types) : boolean; + begin +{$IFDEF mysql50} + IS_NUM := (t <= FIELD_TYPE_INT24) or (t=FIELD_TYPE_YEAR) or (t=FIELD_TYPE_NEWDECIMAL); +{$ELSE} + IS_NUM := (t <= FIELD_TYPE_INT24) or (t=FIELD_TYPE_YEAR); +{$ENDIF} + end; + + function INTERNAL_NUM_FIELD(f : Pst_mysql_field) : boolean; + begin + INTERNAL_NUM_FIELD := (f^.ftype <= FIELD_TYPE_INT24) and ((f^.ftype <> FIELD_TYPE_TIMESTAMP) + or (f^.length = 14) or (f^.length=8)) or (f^.ftype=FIELD_TYPE_YEAR); + end; + + function mysql_reload(mysql : PMySQL) : cint; + begin + mysql_reload:=mysql_refresh(mysql,REFRESH_GRANT); + end; + + function simple_command(mysql,command,arg,length,skip_check : longint) : longint; + begin + //simple_command:=mysql^.(methods^.advanced_command)(mysqlcommandNullS0arglengthskip_check); + result := -1; + end; + +(* +function tryinitialisemysql(const alibnames: array of filenamety): boolean; +var + mstr1: filenamety; +begin + sys_mutexlock(liblock); + try + result:= true; + if refcount = 0 then begin + mysqllibraryhandle:= loadlib(alibnames,mstr1); + if mysqllibraryhandle = nilhandle then begin + result:= false; + exit; + end; + try + getprocaddresses(mysqllibraryhandle, + [ + // 'my_init', //0 + // 'my_thread_init', //1 + // 'my_thread_end', //2 + 'mysql_affected_rows', //3 + 'mysql_autocommit', //4 + 'mysql_change_user', //5 + 'mysql_close', //6 + 'mysql_commit', //7 + 'mysql_data_seek', //8 + 'mysql_debug', //9 + 'mysql_dump_debug_info', //10 + 'mysql_eof', //11 + 'mysql_errno', //12 + 'mysql_error', //13 + 'mysql_escape_string', //14 + 'mysql_fetch_field', //15 + 'mysql_fetch_field_direct', //16 + 'mysql_fetch_fields', //17 + 'mysql_fetch_lengths', //18 + 'mysql_fetch_row', //19 + 'mysql_field_seek', //20 + 'mysql_field_count', //21 + 'mysql_field_tell', //22 + 'mysql_free_result', //23 + 'mysql_get_client_info', //24 + 'mysql_get_client_version', //25 + 'mysql_get_host_info', //26 + 'mysql_get_server_version', //27 + 'mysql_get_proto_info', //28 + 'mysql_get_server_info', //29 + 'mysql_info', //30 + 'mysql_init', //31 + 'mysql_insert_id', //32 + 'mysql_kill', //33 + 'mysql_server_end', //34 + 'mysql_server_init', //35 + 'mysql_list_dbs', //36 + 'mysql_list_fields', //37 + 'mysql_list_processes', //38 + 'mysql_list_tables', //39 + 'mysql_more_results', //40 + 'mysql_next_result', //41 + 'mysql_num_fields', //42 + 'mysql_num_rows', //43 + 'mysql_options', //44 + 'mysql_ping', //45 + 'mysql_query', //46 + 'mysql_real_connect', //47 + 'mysql_real_escape_string', //48 + 'mysql_real_query', //49 + 'mysql_refresh', //50 + 'mysql_rollback', //51 + 'mysql_row_seek', //52 + 'mysql_row_tell', //53 + 'mysql_select_db', //54 + 'mysql_server_end', //55 ??? + 'mysql_server_init', //56 ??? + 'mysql_set_server_option', //57 + 'mysql_sqlstate', //58 + 'mysql_shutdown', //59 + 'mysql_stat', //60 + 'mysql_store_result', //61 + 'mysql_thread_id', //62 + 'mysql_use_result', //63 + 'mysql_warning_count', //64 + 'mysql_stmt_init', //65 + 'mysql_stmt_prepare', //66 + 'mysql_stmt_execute', //67 + 'mysql_stmt_fetch', //68 + 'mysql_stmt_fetch_column', //69 + 'mysql_stmt_store_result', //70 + 'mysql_stmt_param_count', //71 + 'mysql_stmt_attr_set', //72 + 'mysql_stmt_attr_get', //73 + 'mysql_stmt_bind_param', //74 + 'mysql_stmt_bind_result', //75 + 'mysql_stmt_close', //76 + 'mysql_stmt_reset', //77 + 'mysql_stmt_free_result', //78 + 'mysql_stmt_send_long_data', //79 + 'mysql_stmt_result_metadata', //80 + 'mysql_stmt_param_metadata', //81 + 'mysql_stmt_errno', //82 + 'mysql_stmt_error', //83 + 'mysql_stmt_sqlstate', //84 + 'mysql_stmt_row_seek', //85 + 'mysql_stmt_row_tell', //86 + 'mysql_stmt_data_seek', //87 + 'mysql_stmt_num_rows', //88 + 'mysql_stmt_affected_rows', //89 + 'mysql_stmt_insert_id', //90 + 'mysql_stmt_field_count', //91 + 'mysql_ssl_set' //92 + ], + [ + // @my_init, //0 + // @my_thread_init, //1 + // @my_thread_end, //2 + @mysql_affected_rows, //3 + @mysql_autocommit, //4 + @mysql_change_user, //5 + @mysql_close, //6 + @mysql_commit, //7 + @mysql_data_seek, //8 + @mysql_debug, //9 + @mysql_dump_debug_info, //10 + @mysql_eof, //11 + @mysql_errno, //12 + @mysql_error, //13 + @mysql_escape_string, //14 + @mysql_fetch_field, //15 + @mysql_fetch_field_direct, //16 + @mysql_fetch_fields, //17 + @mysql_fetch_lengths, //18 + @mysql_fetch_row, //19 + @mysql_field_seek, //20 + @mysql_field_count, //21 + @mysql_field_tell, //22 + @mysql_free_result, //23 + @mysql_get_client_info, //24 + @mysql_get_client_version, //25 + @mysql_get_host_info, //26 + @mysql_get_server_version, //27 + @mysql_get_proto_info, //28 + @mysql_get_server_info, //29 + @mysql_info, //30 + @mysql_init, //31 + @mysql_insert_id, //32 + @mysql_kill, //33 + @mysql_server_end, //34 + @mysql_server_init, //35 + @mysql_list_dbs, //36 + @mysql_list_fields, //37 + @mysql_list_processes, //38 + @mysql_list_tables, //39 + @mysql_more_results, //40 + @mysql_next_result, //41 + @mysql_num_fields, //42 + @mysql_num_rows, //43 + @mysql_options, //44 + @mysql_ping, //45 + @mysql_query, //46 + @mysql_real_connect, //47 + @mysql_real_escape_string, //48 + @mysql_real_query, //49 + @mysql_refresh, //50 + @mysql_rollback, //51 + @mysql_row_seek, //52 + @mysql_row_tell, //53 + @mysql_select_db, //54 + @mysql_library_end, //55 + @mysql_library_init, //56 + @mysql_set_server_option, //57 + @mysql_sqlstate, //58 + @mysql_shutdown, //59 + @mysql_stat, //60 + @mysql_store_result, //61 + @mysql_thread_id, //62 + @mysql_use_result, //63 + @mysql_warning_count, //64 + @mysql_stmt_init, //65 + @mysql_stmt_prepare, //66 + @mysql_stmt_execute, //67 + @mysql_stmt_fetch, //68 + @mysql_stmt_fetch_column, //69 + @mysql_stmt_store_result, //70 + @mysql_stmt_param_count, //71 + @mysql_stmt_attr_set, //72 + @mysql_stmt_attr_get, //73 + @mysql_stmt_bind_param, //74 + @mysql_stmt_bind_result, //75 + @mysql_stmt_close, //76 + @mysql_stmt_reset, //77 + @mysql_stmt_free_result, //78 + @mysql_stmt_send_long_data, //79 + @mysql_stmt_result_metadata, //80 + @mysql_stmt_param_metadata, //81 + @mysql_stmt_errno, //82 + @mysql_stmt_error, //83 + @mysql_stmt_sqlstate, //84 + @mysql_stmt_row_seek, //85 + @mysql_stmt_row_tell, //86 + @mysql_stmt_data_seek, //87 + @mysql_stmt_num_rows, //88 + @mysql_stmt_affected_rows, //89 + @mysql_stmt_insert_id, //90 + @mysql_stmt_field_count, //91 + @mysql_ssl_set //92 + ]); +// mysql_library_init(-1,nil,nil); + getprocaddresses(mysqllibraryhandle, + [ + 'mysql_get_ssl_cipher' + ], + [ + @mysql_get_ssl_cipher],true); + except + on e: exception do begin + e.message:= 'Library "'+mstr1+'": '+e.message; + result:= false; + if unloadlibrary(mysqllibraryhandle) then begin + mysqllibraryhandle:= nilhandle; + end; + raise; + end; + end; + end; + inc(refcount); + finally + sys_mutexunlock(liblock); + end; +end; +*) +{ +Function InitialiseMysql : Integer; + +begin + Result := 0; + If (TryInitialiseMysql(mysqlvlib) = 0) and + (TryInitialiseMysql(mysqllib) = 0) then + Raise EInOutError.CreateFmt(SErrDefaultsFailed,[mysqlvlib,mysqllib]); + Result := RefCount; +end; +} +{ +Function InitialiseMysql(Const LibraryName : String) : Integer; + +begin + Result := TryInitialiseMysql(LibraryName); + If Result = 0 then + Raise EInOutError.CreateFmt(SErrLoadFailed,[LibraryName]) + else If (LibraryName<>LoadedLibrary) then + begin + Dec(RefCount); + Result := RefCount; + Raise EInOUtError.CreateFmt(SErrAlreadyLoaded,[LoadedLibrary]); + end; +end; +} +{ +Procedure ReleaseMysql; +begin + if RefCount> 1 then + Dec(RefCount) + else if UnloadLibrary(MysqlLibraryHandle) then + begin + Dec(RefCount); + MysqlLibraryHandle := NilHandle; + LoadedLibrary:=''; + end; +end; +} + +procedure releasemysql; +begin + releasedynlib(libinfo); +end; + +procedure initializemysql(const sonames: array of filenamety); +const + funcs: array[0..92] of funcinfoty = ( + (n: 'mysql_affected_rows'; d: {$ifndef FPC}@{$endif}@mysql_affected_rows), + (n: 'mysql_autocommit'; d: {$ifndef FPC}@{$endif}@mysql_autocommit), + (n: 'mysql_change_user'; d: {$ifndef FPC}@{$endif}@mysql_change_user), + (n: 'mysql_close'; d: {$ifndef FPC}@{$endif}@mysql_close), + (n: 'mysql_commit'; d: {$ifndef FPC}@{$endif}@mysql_commit), + (n: 'mysql_data_seek'; d: {$ifndef FPC}@{$endif}@mysql_data_seek), + (n: 'mysql_debug'; d: {$ifndef FPC}@{$endif}@mysql_debug), + (n: 'mysql_dump_debug_info'; d: {$ifndef FPC}@{$endif}@mysql_dump_debug_info), + (n: 'mysql_eof'; d: {$ifndef FPC}@{$endif}@mysql_eof), + (n: 'mysql_errno'; d: {$ifndef FPC}@{$endif}@mysql_errno), + (n: 'mysql_error'; d: {$ifndef FPC}@{$endif}@mysql_error), + (n: 'mysql_escape_string'; d: {$ifndef FPC}@{$endif}@mysql_escape_string), + (n: 'mysql_fetch_field'; d: {$ifndef FPC}@{$endif}@mysql_fetch_field), + (n: 'mysql_fetch_field_direct'; d: {$ifndef FPC}@{$endif}@mysql_fetch_field_direct), + (n: 'mysql_fetch_fields'; d: {$ifndef FPC}@{$endif}@mysql_fetch_fields), + (n: 'mysql_fetch_lengths'; d: {$ifndef FPC}@{$endif}@mysql_fetch_lengths), + (n: 'mysql_fetch_row'; d: {$ifndef FPC}@{$endif}@mysql_fetch_row), + (n: 'mysql_field_seek'; d: {$ifndef FPC}@{$endif}@mysql_field_seek), + (n: 'mysql_field_count'; d: {$ifndef FPC}@{$endif}@mysql_field_count), + (n: 'mysql_field_tell'; d: {$ifndef FPC}@{$endif}@mysql_field_tell), + (n: 'mysql_free_result'; d: {$ifndef FPC}@{$endif}@mysql_free_result), + (n: 'mysql_get_client_info'; d: {$ifndef FPC}@{$endif}@mysql_get_client_info), + (n: 'mysql_get_client_version'; d: {$ifndef FPC}@{$endif}@mysql_get_client_version), + (n: 'mysql_get_host_info'; d: {$ifndef FPC}@{$endif}@mysql_get_host_info), + (n: 'mysql_get_server_version'; d: {$ifndef FPC}@{$endif}@mysql_get_server_version), + (n: 'mysql_get_proto_info'; d: {$ifndef FPC}@{$endif}@mysql_get_proto_info), + (n: 'mysql_get_server_info'; d: {$ifndef FPC}@{$endif}@mysql_get_server_info), + (n: 'mysql_info'; d: {$ifndef FPC}@{$endif}@mysql_info), + (n: 'mysql_init'; d: {$ifndef FPC}@{$endif}@mysql_init), + (n: 'mysql_insert_id'; d: {$ifndef FPC}@{$endif}@mysql_insert_id), + (n: 'mysql_kill'; d: {$ifndef FPC}@{$endif}@mysql_kill), + (n: 'mysql_server_end'; d: {$ifndef FPC}@{$endif}@mysql_server_end), + (n: 'mysql_server_init'; d: {$ifndef FPC}@{$endif}@mysql_server_init), + (n: 'mysql_list_dbs'; d: {$ifndef FPC}@{$endif}@mysql_list_dbs), + (n: 'mysql_list_fields'; d: {$ifndef FPC}@{$endif}@mysql_list_fields), + (n: 'mysql_list_processes'; d: {$ifndef FPC}@{$endif}@mysql_list_processes), + (n: 'mysql_list_tables'; d: {$ifndef FPC}@{$endif}@mysql_list_tables), + (n: 'mysql_more_results'; d: {$ifndef FPC}@{$endif}@mysql_more_results), + (n: 'mysql_next_result'; d: {$ifndef FPC}@{$endif}@mysql_next_result), + (n: 'mysql_num_fields'; d: {$ifndef FPC}@{$endif}@mysql_num_fields), + (n: 'mysql_num_rows'; d: {$ifndef FPC}@{$endif}@mysql_num_rows), + (n: 'mysql_options'; d: {$ifndef FPC}@{$endif}@mysql_options), + (n: 'mysql_ping'; d: {$ifndef FPC}@{$endif}@mysql_ping), + (n: 'mysql_query'; d: {$ifndef FPC}@{$endif}@mysql_query), + (n: 'mysql_real_connect'; d: {$ifndef FPC}@{$endif}@mysql_real_connect), + (n: 'mysql_real_escape_string'; d: {$ifndef FPC}@{$endif}@mysql_real_escape_string), + (n: 'mysql_real_query'; d: {$ifndef FPC}@{$endif}@mysql_real_query), + (n: 'mysql_refresh'; d: {$ifndef FPC}@{$endif}@mysql_refresh), + (n: 'mysql_rollback'; d: {$ifndef FPC}@{$endif}@mysql_rollback), + (n: 'mysql_row_seek'; d: {$ifndef FPC}@{$endif}@mysql_row_seek), + (n: 'mysql_row_tell'; d: {$ifndef FPC}@{$endif}@mysql_row_tell), + (n: 'mysql_select_db'; d: {$ifndef FPC}@{$endif}@mysql_select_db), + (n: 'mysql_server_end'; d: {$ifndef FPC}@{$endif}@mysql_server_end), + (n: 'mysql_server_init'; d: {$ifndef FPC}@{$endif}@mysql_server_init), + (n: 'mysql_set_server_option'; d: {$ifndef FPC}@{$endif}@mysql_set_server_option), + (n: 'mysql_sqlstate'; d: {$ifndef FPC}@{$endif}@mysql_sqlstate), + (n: 'mysql_shutdown'; d: {$ifndef FPC}@{$endif}@mysql_shutdown), + (n: 'mysql_stat'; d: {$ifndef FPC}@{$endif}@mysql_stat), + (n: 'mysql_store_result'; d: {$ifndef FPC}@{$endif}@mysql_store_result), + (n: 'mysql_thread_id'; d: {$ifndef FPC}@{$endif}@mysql_thread_id), + (n: 'mysql_use_result'; d: {$ifndef FPC}@{$endif}@mysql_use_result), + (n: 'mysql_warning_count'; d: {$ifndef FPC}@{$endif}@mysql_warning_count), + (n: 'mysql_stmt_init'; d: {$ifndef FPC}@{$endif}@mysql_stmt_init), + (n: 'mysql_stmt_prepare'; d: {$ifndef FPC}@{$endif}@mysql_stmt_prepare), + (n: 'mysql_stmt_execute'; d: {$ifndef FPC}@{$endif}@mysql_stmt_execute), + (n: 'mysql_stmt_fetch'; d: {$ifndef FPC}@{$endif}@mysql_stmt_fetch), + (n: 'mysql_stmt_fetch_column'; d: {$ifndef FPC}@{$endif}@mysql_stmt_fetch_column), + (n: 'mysql_stmt_store_result'; d: {$ifndef FPC}@{$endif}@mysql_stmt_store_result), + (n: 'mysql_stmt_param_count'; d: {$ifndef FPC}@{$endif}@mysql_stmt_param_count), + (n: 'mysql_stmt_attr_set'; d: {$ifndef FPC}@{$endif}@mysql_stmt_attr_set), + (n: 'mysql_stmt_attr_get'; d: {$ifndef FPC}@{$endif}@mysql_stmt_attr_get), + (n: 'mysql_stmt_bind_param'; d: {$ifndef FPC}@{$endif}@mysql_stmt_bind_param), + (n: 'mysql_stmt_bind_result'; d: {$ifndef FPC}@{$endif}@mysql_stmt_bind_result), + (n: 'mysql_stmt_close'; d: {$ifndef FPC}@{$endif}@mysql_stmt_close), + (n: 'mysql_stmt_reset'; d: {$ifndef FPC}@{$endif}@mysql_stmt_reset), + (n: 'mysql_stmt_free_result'; d: {$ifndef FPC}@{$endif}@mysql_stmt_free_result), + (n: 'mysql_stmt_send_long_data'; d: {$ifndef FPC}@{$endif}@mysql_stmt_send_long_data), + (n: 'mysql_stmt_result_metadata'; d: {$ifndef FPC}@{$endif}@mysql_stmt_result_metadata), + (n: 'mysql_stmt_param_metadata'; d: {$ifndef FPC}@{$endif}@mysql_stmt_param_metadata), + (n: 'mysql_stmt_errno'; d: {$ifndef FPC}@{$endif}@mysql_stmt_errno), + (n: 'mysql_stmt_error'; d: {$ifndef FPC}@{$endif}@mysql_stmt_error), + (n: 'mysql_stmt_sqlstate'; d: {$ifndef FPC}@{$endif}@mysql_stmt_sqlstate), + (n: 'mysql_stmt_row_seek'; d: {$ifndef FPC}@{$endif}@mysql_stmt_row_seek), + (n: 'mysql_stmt_row_tell'; d: {$ifndef FPC}@{$endif}@mysql_stmt_row_tell), + (n: 'mysql_stmt_data_seek'; d: {$ifndef FPC}@{$endif}@mysql_stmt_data_seek), + (n: 'mysql_stmt_num_rows'; d: {$ifndef FPC}@{$endif}@mysql_stmt_num_rows), + (n: 'mysql_stmt_affected_rows'; d: {$ifndef FPC}@{$endif}@mysql_stmt_affected_rows), + (n: 'mysql_stmt_insert_id'; d: {$ifndef FPC}@{$endif}@mysql_stmt_insert_id), + (n: 'mysql_stmt_field_count'; d: {$ifndef FPC}@{$endif}@mysql_stmt_field_count), + (n: 'mysql_ssl_set'; d: {$ifndef FPC}@{$endif}@mysql_ssl_set), + (n: 'mysql_character_set_name'; d: {$ifndef FPC}@{$endif}@mysql_character_set_name), + (n: 'mysql_get_character_set_info'; d: {$ifndef FPC}@{$endif}@mysql_get_character_set_info), + (n: 'mysql_set_character_set'; d: {$ifndef FPC}@{$endif}@mysql_set_character_set) + ); + funcsopt: array[0..0] of funcinfoty = ( + (n: 'mysql_get_ssl_cipher'; d: {$ifndef FPC}@{$endif}@mysql_get_ssl_cipher) + ); + errormessage = 'Can not load MySQL library. '; +begin + initializedynlib(libinfo,sonames,mysqllib,funcs,funcsopt,errormessage); +end; + + +{$ENDIF} + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. + diff --git a/mseide-msegui/lib/common/db/odbcsqldyn.pas b/mseide-msegui/lib/common/db/odbcsqldyn.pas new file mode 100644 index 0000000..566de7c --- /dev/null +++ b/mseide-msegui/lib/common/db/odbcsqldyn.pas @@ -0,0 +1,1771 @@ +unit odbcsqldyn; +{modified 2010-2012 by Martin Schreiber} + +{$DEFINE DYNLOADINGODBC} + +{$ifdef fpc} +{$mode objfpc} +{$macro on} +{$endif} + +{$h+} + +{$ifdef fpc} + // define ODBC version 3.51 by default +{$define ODBCVER:=$0351} +{$if defined(FPC) and (ODBCVER >= $0300)} + {$define ODBCVER3} +{$ifend} +{$if defined(FPC) and (ODBCVER >= $0350)} + {$define ODBCVER35} +{$ifend} +{$else fpc} + {$define ODBCVER3} + {$define ODBCVER35} +{$endif fpc} + +{$ifndef DYNLOADINGODBC} + {$linklib odbc} +{$endif} + +interface + +uses + msetypes,msestrings, + msectypes, + sysutils; + +{$IFDEF Unix} + {$DEFINE extdecl:=cdecl} +// const +// odbclib = 'libodbc.'+sharedsuffix; +{$ENDIF} +{$IFDEF msWindows} + {$DEFINE extdecl:=stdcall} +// const +// odbclib = 'odbc32.dll'; +{$ENDIF} + + +const +{$ifdef mswindows} + odbclib: array[0..0] of filenamety = ('odbc32.dll'); +{$else} + odbclib: array[0..2] of filenamety = ('libodbc.so.2','libodbc.so.1', + 'libodbc.so'); +{$endif} + +procedure initializeodbc(const sonames: array of filenamety); +procedure releaseodbc; + +(* DATA TYPES CORRESPONDENCE + BDE fields ODBC types + ---------- ------------------ + ftBlob SQL_BINARY + ftBoolean SQL_BIT + ftDate SQL_TYPE_DATE + ftTime SQL_TYPE_TIME + ftDateTime SQL_TYPE_TIMESTAMP + ftInteger SQL_INTEGER + ftSmallint SQL_SMALLINT + ftFloat SQL_DOUBLE + ftString SQL_CHAR + ftMemo SQL_BINARY // SQL_VARCHAR +*) + +type + SQLCHAR = char; + SQLSMALLINT = csshort; + SQLUSMALLINT = cushort; + SQLRETURN = SQLSMALLINT; + SQLHANDLE = pointer; + SQLHENV = SQLHANDLE; + SQLHDBC = SQLHANDLE; + SQLHSTMT = SQLHANDLE; + SQLHDESC = SQLHANDLE; + SQLINTEGER = clong; + SQLUINTEGER = culong; + SQLLEN = ptrint; + SQLULEN = ptruint; + {$ifdef CPU64} + SQLSETPOSIROW = ptruint; + {$else} + SQLSETPOSIROW = SQLUSMALLINT; + {$endif} + SQLPOINTER = pointer; + SQLREAL = cfloat; + SQLDOUBLE = cdouble; + SQLFLOAT = cdouble; + SQLHWND = pointer; + PSQLCHAR = PChar; + PSQLINTEGER = ^SQLINTEGER; + PSQLUINTEGER = ^SQLUINTEGER; + PSQLLEN = ^SQLLEN; + PSQLULEN = ^SQLULEN; + PSQLSMALLINT = ^SQLSMALLINT; + PSQLUSMALLINT = ^SQLUSMALLINT; + PSQLREAL = ^SQLREAL; + PSQLDOUBLE = ^SQLDOUBLE; + PSQLFLOAT = ^SQLFLOAT; + PSQLHANDLE = ^SQLHANDLE; + +const + { SQL data type codes } + SQL_UNKNOWN_TYPE = 0; + SQL_LONGVARCHAR =(-1); + SQL_BINARY =(-2); + SQL_VARBINARY =(-3); + SQL_LONGVARBINARY =(-4); + SQL_BIGINT =(-5); + SQL_TINYINT =(-6); + SQL_BIT =(-7); + SQL_WCHAR =(-8); + SQL_WVARCHAR =(-9); + SQL_WLONGVARCHAR =(-10); + + + SQL_CHAR = 1; + SQL_NUMERIC = 2; + SQL_DECIMAL = 3; + SQL_INTEGER = 4; + SQL_SMALLINT = 5; + SQL_FLOAT = 6; + SQL_REAL = 7; + SQL_DOUBLE = 8; + {$ifdef ODBCVER3} + SQL_DATETIME = 9; + {$endif} + SQL_VARCHAR = 12; + + {$ifdef ODBCVER3} + SQL_TYPE_DATE = 91; + SQL_TYPE_TIME = 92; + SQL_TYPE_TIMESTAMP= 93; + {$endif} + + SQL_DATE = 9; + SQL_TIME = 10; + SQL_TIMESTAMP = 11; + {$ifdef ODBCVER3} + SQL_INTERVAL = 10; + {$endif} + {$ifdef ODBCVER35} + SQL_GUID = -11; + {$endif} + + { interval codes} + {$ifdef ODBCVER3} + SQL_CODE_YEAR = 1; + SQL_CODE_MONTH = 2; + SQL_CODE_DAY = 3; + SQL_CODE_HOUR = 4; + SQL_CODE_MINUTE = 5; + SQL_CODE_SECOND = 6; + SQL_CODE_YEAR_TO_MONTH = 7; + SQL_CODE_DAY_TO_HOUR = 8; + SQL_CODE_DAY_TO_MINUTE = 9; + SQL_CODE_DAY_TO_SECOND = 10; + SQL_CODE_HOUR_TO_MINUTE = 11; + SQL_CODE_HOUR_TO_SECOND = 12; + SQL_CODE_MINUTE_TO_SECOND = 13; + + SQL_INTERVAL_YEAR = 100 + SQL_CODE_YEAR; + SQL_INTERVAL_MONTH = 100 + SQL_CODE_MONTH; + SQL_INTERVAL_DAY = 100 + SQL_CODE_DAY; + SQL_INTERVAL_HOUR = 100 + SQL_CODE_HOUR; + SQL_INTERVAL_MINUTE = 100 + SQL_CODE_MINUTE; + SQL_INTERVAL_SECOND = 100 + SQL_CODE_SECOND; + SQL_INTERVAL_YEAR_TO_MONTH = 100 + SQL_CODE_YEAR_TO_MONTH; + SQL_INTERVAL_DAY_TO_HOUR = 100 + SQL_CODE_DAY_TO_HOUR; + SQL_INTERVAL_DAY_TO_MINUTE = 100 + SQL_CODE_DAY_TO_MINUTE; + SQL_INTERVAL_DAY_TO_SECOND = 100 + SQL_CODE_DAY_TO_SECOND; + SQL_INTERVAL_HOUR_TO_MINUTE = 100 + SQL_CODE_HOUR_TO_MINUTE; + SQL_INTERVAL_HOUR_TO_SECOND = 100 + SQL_CODE_HOUR_TO_SECOND; + SQL_INTERVAL_MINUTE_TO_SECOND = 100 + SQL_CODE_MINUTE_TO_SECOND; + {$else} + SQL_INTERVAL_YEAR = -80; + SQL_INTERVAL_MONTH = -81; + SQL_INTERVAL_YEAR_TO_MONTH = -82; + SQL_INTERVAL_DAY = -83; + SQL_INTERVAL_HOUR = -84; + SQL_INTERVAL_MINUTE = -85; + SQL_INTERVAL_SECOND = -86; + SQL_INTERVAL_DAY_TO_HOUR = -87; + SQL_INTERVAL_DAY_TO_MINUTE = -88; + SQL_INTERVAL_DAY_TO_SECOND = -89; + SQL_INTERVAL_HOUR_TO_MINUTE = -90; + SQL_INTERVAL_HOUR_TO_SECOND = -91; + SQL_INTERVAL_MINUTE_TO_SECOND = -92; + {$endif} + + { Unicode data type codes } + {$ifndef ODBCVER3} + SQL_UNICODE = -95; + SQL_UNICODE_VARCHAR = -96; + SQL_UNICODE_LONGVARCHAR = -97; + SQL_UNICODE_CHAR = SQL_UNICODE; + {$else} + { The previous definitions for SQL_UNICODE_ are historical and obsolete } + SQL_UNICODE = SQL_WCHAR; + SQL_UNICODE_VARCHAR = SQL_WVARCHAR; + SQL_UNICODE_LONGVARCHAR = SQL_WLONGVARCHAR; + SQL_UNICODE_CHAR = SQL_WCHAR; + {$endif} + + { C datatype to SQL datatype mapping } + SQL_C_CHAR = SQL_CHAR; + SQL_C_WCHAR = SQL_WCHAR; + SQL_C_LONG = SQL_INTEGER; + SQL_C_SHORT = SQL_SMALLINT; + SQL_C_FLOAT = SQL_REAL; + SQL_C_DOUBLE = SQL_DOUBLE; +{$ifdef ODBCVER3} + SQL_C_NUMERIC = SQL_NUMERIC; +{$endif} + SQL_C_DEFAULT = 99; + + SQL_SIGNED_OFFSET = -20; + SQL_UNSIGNED_OFFSET = -22; + + SQL_C_DATE = SQL_DATE; + SQL_C_TIME = SQL_TIME; + SQL_C_TIMESTAMP = SQL_TIMESTAMP; +{$ifdef ODBCVER3} + SQL_C_TYPE_DATE = SQL_TYPE_DATE; + SQL_C_TYPE_TIME = SQL_TYPE_TIME; + SQL_C_TYPE_TIMESTAMP = SQL_TYPE_TIMESTAMP; + SQL_C_INTERVAL_YEAR = SQL_INTERVAL_YEAR; + SQL_C_INTERVAL_MONTH = SQL_INTERVAL_MONTH; + SQL_C_INTERVAL_DAY = SQL_INTERVAL_DAY; + SQL_C_INTERVAL_HOUR = SQL_INTERVAL_HOUR; + SQL_C_INTERVAL_MINUTE = SQL_INTERVAL_MINUTE; + SQL_C_INTERVAL_SECOND = SQL_INTERVAL_SECOND; + SQL_C_INTERVAL_YEAR_TO_MONTH = SQL_INTERVAL_YEAR_TO_MONTH; + SQL_C_INTERVAL_DAY_TO_HOUR = SQL_INTERVAL_DAY_TO_HOUR; + SQL_C_INTERVAL_DAY_TO_MINUTE = SQL_INTERVAL_DAY_TO_MINUTE; + SQL_C_INTERVAL_DAY_TO_SECOND = SQL_INTERVAL_DAY_TO_SECOND; + SQL_C_INTERVAL_HOUR_TO_MINUTE = SQL_INTERVAL_HOUR_TO_MINUTE; + SQL_C_INTERVAL_HOUR_TO_SECOND = SQL_INTERVAL_HOUR_TO_SECOND; + SQL_C_INTERVAL_MINUTE_TO_SECOND = SQL_INTERVAL_MINUTE_TO_SECOND; +{$endif} + SQL_C_BINARY = SQL_BINARY; + SQL_C_BIT = SQL_BIT; +{$ifdef ODBCVER3} + SQL_C_SBIGINT = SQL_BIGINT+SQL_SIGNED_OFFSET; // SIGNED BIGINT + SQL_C_UBIGINT = SQL_BIGINT+SQL_UNSIGNED_OFFSET; // UNSIGNED BIGINT +{$endif} + SQL_C_TINYINT = SQL_TINYINT; + SQL_C_SLONG = SQL_C_LONG +SQL_SIGNED_OFFSET; // SIGNED INTEGER + SQL_C_SSHORT = SQL_C_SHORT+SQL_SIGNED_OFFSET; // SIGNED SMALLINT + SQL_C_STINYINT = SQL_TINYINT+SQL_SIGNED_OFFSET; // SIGNED TINYINT + SQL_C_ULONG = SQL_C_LONG +SQL_UNSIGNED_OFFSET; // UNSIGNED INTEGER + SQL_C_USHORT = SQL_C_SHORT+SQL_UNSIGNED_OFFSET; // UNSIGNED SMALLINT + SQL_C_UTINYINT = SQL_TINYINT+SQL_UNSIGNED_OFFSET; // UNSIGNED TINYINT + SQL_C_BOOKMARK = SQL_C_ULONG; // BOOKMARK + +{$ifdef ODBCVER35} + SQL_C_GUID = SQL_GUID; +{$endif} + + SQL_TYPE_NULL = 0; +{$ifndef ODBCVER3} + SQL_TYPE_MIN = SQL_BIT; + SQL_TYPE_MAX = SQL_VARCHAR; +{$endif} + +{$ifdef ODBCVER3} + SQL_C_VARBOOKMARK = SQL_C_BINARY; +{$endif} + + SQL_API_SQLDESCRIBEPARAM=58; + SQL_NO_TOTAL = -4; + +type + SQL_DATE_STRUCT = packed record + Year : SQLSMALLINT; + Month : SQLUSMALLINT; + Day : SQLUSMALLINT; + end; + PSQL_DATE_STRUCT = ^SQL_DATE_STRUCT; + + SQL_TIME_STRUCT = packed record + Hour : SQLUSMALLINT; + Minute : SQLUSMALLINT; + Second : SQLUSMALLINT; + end; + PSQL_TIME_STRUCT = ^SQL_TIME_STRUCT; + + SQL_TIMESTAMP_STRUCT = packed record + Year : SQLUSMALLINT; + Month : SQLUSMALLINT; + Day : SQLUSMALLINT; + Hour : SQLUSMALLINT; + Minute : SQLUSMALLINT; + Second : SQLUSMALLINT; + Fraction : SQLUINTEGER; + end; + PSQL_TIMESTAMP_STRUCT = ^SQL_TIMESTAMP_STRUCT; + +const + SQL_NAME_LEN = 128; + + SQL_OV_ODBC3 = 3; + SQL_OV_ODBC2 = 2; + SQL_ATTR_ODBC_VERSION = 200; + + { Options for SQLDriverConnect } + SQL_DRIVER_NOPROMPT = 0; + SQL_DRIVER_COMPLETE = 1; + SQL_DRIVER_PROMPT = 2; + SQL_DRIVER_COMPLETE_REQUIRED = 3; + + { whether an attribute is a pointer or not } + SQL_IS_POINTER = (-4); + SQL_IS_UINTEGER = (-5); + SQL_IS_INTEGER = (-6); + SQL_IS_USMALLINT = (-7); + SQL_IS_SMALLINT = (-8); + { SQLExtendedFetch "fFetchType" values } + SQL_FETCH_BOOKMARK = 8; + + SQL_SCROLL_OPTIONS = 44; + + { SQL_USE_BOOKMARKS options } + SQL_UB_OFF = 0; + SQL_UB_ON = 1; + SQL_UB_DEFAULT = SQL_UB_OFF; + SQL_UB_FIXED = SQL_UB_ON; + SQL_UB_VARIABLE = 2; + + { SQL_SCROLL_OPTIONS masks } + SQL_SO_FORWARD_ONLY = $01; + SQL_SO_KEYSET_DRIVEN = $02; + SQL_SO_DYNAMIC = $04; + SQL_SO_MIXED = $08; + SQL_SO_STATIC = $10; + + SQL_BOOKMARK_PERSISTENCE = 82; + SQL_STATIC_SENSITIVITY = 83; + + { SQL_BOOKMARK_PERSISTENCE values } + SQL_BP_CLOSE = $01; + SQL_BP_DELETE = $02; + SQL_BP_DROP = $04; + SQL_BP_TRANSACTION = $08; + SQL_BP_UPDATE = $10; + SQL_BP_OTHER_HSTMT = $20; + SQL_BP_SCROLL = $40; + + SQL_DYNAMIC_CURSOR_ATTRIBUTES1 = 144; + SQL_DYNAMIC_CURSOR_ATTRIBUTES2 = 145; + SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 = 146; + SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 = 147; + SQL_INDEX_KEYWORDS = 148; + SQL_INFO_SCHEMA_VIEWS = 149; + SQL_KEYSET_CURSOR_ATTRIBUTES1 = 150; + SQL_KEYSET_CURSOR_ATTRIBUTES2 = 151; + SQL_STATIC_CURSOR_ATTRIBUTES1 = 167; + SQL_STATIC_CURSOR_ATTRIBUTES2 = 168; + + { supported SQLFetchScroll FetchOrientation's } + SQL_CA1_NEXT = 1; + SQL_CA1_ABSOLUTE = 2; + SQL_CA1_RELATIVE = 4; + SQL_CA1_BOOKMARK = 8; + + { supported SQLSetPos LockType's } + SQL_CA1_LOCK_NO_CHANGE= $40; + SQL_CA1_LOCK_EXCLUSIVE= $80; + SQL_CA1_LOCK_UNLOCK =$100; + + { supported SQLSetPos Operations } + SQL_CA1_POS_POSITION = $200; + SQL_CA1_POS_UPDATE = $400; + SQL_CA1_POS_DELETE = $800; + SQL_CA1_POS_REFRESH =$1000; + + { positioned updates and deletes } + SQL_CA1_POSITIONED_UPDATE=$2000; + SQL_CA1_POSITIONED_DELETE=$4000; + SQL_CA1_SELECT_FOR_UPDATE=$8000; + + { supported SQLBulkOperations operations } + SQL_CA1_BULK_ADD =$10000; + SQL_CA1_BULK_UPDATE_BY_BOOKMARK =$20000; + SQL_CA1_BULK_DELETE_BY_BOOKMARK =$40000; + SQL_CA1_BULK_FETCH_BY_BOOKMARK =$80000; + + { supported values for SQL_ATTR_SCROLL_CONCURRENCY } + SQL_CA2_READ_ONLY_CONCURRENCY = 1; + SQL_CA2_LOCK_CONCURRENCY = 2; + SQL_CA2_OPT_ROWVER_CONCURRENCY= 4; + SQL_CA2_OPT_VALUES_CONCURRENCY= 8; + + { sensitivity of the cursor to its own inserts, deletes, and updates } + SQL_CA2_SENSITIVITY_ADDITIONS =$10; + SQL_CA2_SENSITIVITY_DELETIONS =$20; + SQL_CA2_SENSITIVITY_UPDATES =$40; + +{ semantics of SQL_ATTR_MAX_ROWS } + SQL_CA2_MAX_ROWS_SELECT = $80; + SQL_CA2_MAX_ROWS_INSERT =$100; + SQL_CA2_MAX_ROWS_DELETE =$200; + SQL_CA2_MAX_ROWS_UPDATE =$400; + SQL_CA2_MAX_ROWS_CATALOG =$800; + SQL_CA2_MAX_ROWS_AFFECTS_ALL =(SQL_CA2_MAX_ROWS_SELECT or + SQL_CA2_MAX_ROWS_INSERT or SQL_CA2_MAX_ROWS_DELETE or + SQL_CA2_MAX_ROWS_UPDATE or SQL_CA2_MAX_ROWS_CATALOG); + + { semantics of SQL_DIAG_CURSOR_ROW_COUNT } + SQL_CA2_CRC_EXACT = $1000; + SQL_CA2_CRC_APPROXIMATE = $2000; + + { the kinds of positioned statements that can be simulated } + SQL_CA2_SIMULATE_NON_UNIQUE = $4000; + SQL_CA2_SIMULATE_TRY_UNIQUE = $8000; + SQL_CA2_SIMULATE_UNIQUE =$10000; + + { Operations in SQLBulkOperations } + SQL_ADD = 4; + SQL_SETPOS_MAX_OPTION_VALUE = SQL_ADD; + SQL_UPDATE_BY_BOOKMARK = 5; + SQL_DELETE_BY_BOOKMARK = 6; + SQL_FETCH_BY_BOOKMARK = 7; + + { Operations in SQLSetPos } + SQL_POSITION = 0; + SQL_REFRESH = 1; + SQL_UPDATE = 2; + SQL_DELETE = 3; + + { Lock options in SQLSetPos } + SQL_LOCK_NO_CHANGE = 0; + SQL_LOCK_EXCLUSIVE = 1; + SQL_LOCK_UNLOCK = 2; + + { SQLExtendedFetch "rgfRowStatus" element values } + SQL_ROW_SUCCESS = 0; + SQL_ROW_DELETED = 1; + SQL_ROW_UPDATED = 2; + SQL_ROW_NOROW = 3; + SQL_ROW_ADDED = 4; + SQL_ROW_ERROR = 5; + SQL_ROW_SUCCESS_WITH_INFO = 6; + + SQL_ROW_PROCEED = 0; + SQL_ROW_IGNORE = 1; + + SQL_MAX_DSN_LENGTH = 32; { maximum data source name size } + + SQL_MAX_OPTION_STRING_LENGTH = 256; + + SQL_ODBC_CURSORS = 110; + SQL_ATTR_ODBC_CURSORS = SQL_ODBC_CURSORS; + { SQL_ODBC_CURSORS options } + SQL_CUR_USE_IF_NEEDED = 0; + SQL_CUR_USE_ODBC = 1; + SQL_CUR_USE_DRIVER = 2; + SQL_CUR_DEFAULT = SQL_CUR_USE_DRIVER; + + SQL_PARAM_TYPE_UNKNOWN = 0; + SQL_PARAM_INPUT = 1; + SQL_PARAM_INPUT_OUTPUT = 2; + SQL_RESULT_COL = 3; + SQL_PARAM_OUTPUT = 4; + SQL_RETURN_VALUE = 5; + + { special length/indicator values } + SQL_NULL_DATA = (-1); + SQL_DATA_AT_EXEC = (-2); + + SQL_SUCCESS = 0; + SQL_SUCCESS_WITH_INFO = 1; + + SQL_NO_DATA = 100; + SQL_ERROR = (-1); + SQL_INVALID_HANDLE = (-2); + + SQL_STILL_EXECUTING = 2; + SQL_NEED_DATA = 99; + { flags for null-terminated string } + SQL_NTS = (-3); + + { maximum message length } + SQL_MAX_MESSAGE_LENGTH = 512; + + { date/time length constants } +{$ifdef ODBCVER3} + SQL_DATE_LEN = 10; + SQL_TIME_LEN = 8; { add P+1 if precision is nonzero } + SQL_TIMESTAMP_LEN = 19; { add P+1 if precision is nonzero } +{$endif} + + { handle type identifiers } + SQL_HANDLE_ENV = 1; + SQL_HANDLE_DBC = 2; + SQL_HANDLE_STMT = 3; + SQL_HANDLE_DESC = 4; + +{$ifdef ODBCVER3} + { environment attribute } + SQL_ATTR_OUTPUT_NTS = 10001; + { connection attributes } + SQL_ATTR_AUTO_IPD = 10001; + SQL_ATTR_METADATA_ID = 10014; +{$endif} { ODBCVER >= 0x0300 } + + { statement attributes } + SQL_ATTR_APP_ROW_DESC = 10010; + SQL_ATTR_APP_PARAM_DESC = 10011; + SQL_ATTR_IMP_ROW_DESC = 10012; + SQL_ATTR_IMP_PARAM_DESC = 10013; + SQL_ATTR_CURSOR_SCROLLABLE = (-1); + SQL_ATTR_CURSOR_SENSITIVITY = (-2); + SQL_QUERY_TIMEOUT =0; + SQL_MAX_ROWS =1; + SQL_NOSCAN =2; + SQL_MAX_LENGTH =3; + SQL_ASYNC_ENABLE =4; // same as SQL_ATTR_ASYNC_ENABLE */ + SQL_BIND_TYPE =5; + SQL_CURSOR_TYPE = 6; + SQL_CONCURRENCY = 7; + SQL_KEYSET_SIZE =8; + SQL_ROWSET_SIZE =9; + SQL_SIMULATE_CURSOR =10; + SQL_RETRIEVE_DATA =11; + SQL_USE_BOOKMARKS =12; + SQL_GET_BOOKMARK =13; // GetStmtOption Only */ + SQL_ROW_NUMBER = 14; // GetStmtOption Only */ + + SQL_ATTR_CURSOR_TYPE = SQL_CURSOR_TYPE; + SQL_ATTR_CONCURRENCY = SQL_CONCURRENCY; + SQL_ATTR_FETCH_BOOKMARK_PTR = 16; + SQL_ATTR_ROW_STATUS_PTR = 25; + SQL_ATTR_ROWS_FETCHED_PTR = 26; + SQL_AUTOCOMMIT = 102; + SQL_ATTR_AUTOCOMMIT = SQL_AUTOCOMMIT; + + SQL_ATTR_ROW_NUMBER = SQL_ROW_NUMBER; + SQL_TXN_ISOLATION = 108; + SQL_ATTR_TXN_ISOLATION = SQL_TXN_ISOLATION; + SQL_ATTR_MAX_ROWS = SQL_MAX_ROWS; + SQL_ATTR_USE_BOOKMARKS = SQL_USE_BOOKMARKS; + +//* connection attributes */ + SQL_ACCESS_MODE =101; +// SQL_AUTOCOMMIT =102; + SQL_LOGIN_TIMEOUT =103; + SQL_OPT_TRACE =104; + SQL_OPT_TRACEFILE =105; + SQL_TRANSLATE_DLL =106; + SQL_TRANSLATE_OPTION =107; +// SQL_TXN_ISOLATION =108; + SQL_CURRENT_QUALIFIER =109; +// SQL_ODBC_CURSORS =110; + SQL_QUIET_MODE =111; + SQL_PACKET_SIZE =112; + + +//* connection attributes with new names */ + SQL_ATTR_ACCESS_MODE =SQL_ACCESS_MODE; +// SQL_ATTR_AUTOCOMMIT =SQL_AUTOCOMMIT; + SQL_ATTR_CONNECTION_DEAD =1209; //* GetConnectAttr only */ + SQL_ATTR_CONNECTION_TIMEOUT =113; + SQL_ATTR_CURRENT_CATALOG =SQL_CURRENT_QUALIFIER; + SQL_ATTR_DISCONNECT_BEHAVIOR=114; + SQL_ATTR_ENLIST_IN_DTC =1207; + SQL_ATTR_ENLIST_IN_XA =1208; + SQL_ATTR_LOGIN_TIMEOUT =SQL_LOGIN_TIMEOUT; +// SQL_ATTR_ODBC_CURSORS =SQL_ODBC_CURSORS; + SQL_ATTR_PACKET_SIZE =SQL_PACKET_SIZE; + SQL_ATTR_QUIET_MODE =SQL_QUIET_MODE; + SQL_ATTR_TRACE =SQL_OPT_TRACE; + SQL_ATTR_TRACEFILE =SQL_OPT_TRACEFILE; + SQL_ATTR_TRANSLATE_LIB =SQL_TRANSLATE_DLL; + SQL_ATTR_TRANSLATE_OPTION =SQL_TRANSLATE_OPTION; +// SQL_ATTR_TXN_ISOLATION =SQL_TXN_ISOLATION; + +//* SQL_ACCESS_MODE options */ + SQL_MODE_READ_WRITE =0; + SQL_MODE_READ_ONLY =1; + SQL_MODE_DEFAULT =SQL_MODE_READ_WRITE; + + //* SQL_AUTOCOMMIT options */ + SQL_AUTOCOMMIT_OFF = 0; + SQL_AUTOCOMMIT_ON = 1; + SQL_AUTOCOMMIT_DEFAULT = SQL_AUTOCOMMIT_ON; + { SQL_ATTR_CURSOR_SCROLLABLE values } + SQL_NONSCROLLABLE = 0; + SQL_SCROLLABLE = 1; + { SQL_CURSOR_TYPE options } + SQL_CURSOR_FORWARD_ONLY = 0; + SQL_CURSOR_KEYSET_DRIVEN = 1; + SQL_CURSOR_DYNAMIC = 2; + SQL_CURSOR_STATIC = 3; + SQL_CURSOR_TYPE_DEFAULT = SQL_CURSOR_FORWARD_ONLY;{ Default value } + + { SQL_CONCURRENCY options } + SQL_CONCUR_READ_ONLY = 1; + SQL_CONCUR_LOCK = 2; + SQL_CONCUR_ROWVER = 3; + SQL_CONCUR_VALUES = 4; + SQL_CONCUR_DEFAULT = SQL_CONCUR_READ_ONLY; { Default value } + + { identifiers of fields in the SQL descriptor } + {$ifdef ODBCVER3} + SQL_DESC_COUNT = 1001; + SQL_DESC_TYPE = 1002; + SQL_DESC_LENGTH = 1003; + SQL_DESC_OCTET_LENGTH_PTR = 1004; + SQL_DESC_PRECISION = 1005; + SQL_DESC_SCALE = 1006; + SQL_DESC_DATETIME_INTERVAL_CODE = 1007; + SQL_DESC_NULLABLE = 1008; + SQL_DESC_INDICATOR_PTR = 1009; + SQL_DESC_DATA_PTR = 1010; + SQL_DESC_NAME = 1011; + SQL_DESC_UNNAMED = 1012; + SQL_DESC_OCTET_LENGTH = 1013; + SQL_DESC_ALLOC_TYPE = 1099; + {$endif} + + { identifiers of fields in the diagnostics area } +{$ifdef ODBCVER3} + SQL_DIAG_RETURNCODE = 1; + SQL_DIAG_NUMBER = 2; + SQL_DIAG_ROW_COUNT = 3; + SQL_DIAG_SQLSTATE = 4; + SQL_DIAG_NATIVE = 5; + SQL_DIAG_MESSAGE_TEXT = 6; + SQL_DIAG_DYNAMIC_FUNCTION = 7; + SQL_DIAG_CLASS_ORIGIN = 8; + SQL_DIAG_SUBCLASS_ORIGIN = 9; + SQL_DIAG_CONNECTION_NAME = 10; + SQL_DIAG_SERVER_NAME = 11; + SQL_DIAG_DYNAMIC_FUNCTION_CODE = 12; +{$endif} + + { dynamic function codes } +{$ifdef ODBCVER3} + SQL_DIAG_ALTER_TABLE = 4; + SQL_DIAG_CREATE_INDEX = (-1); + SQL_DIAG_CREATE_TABLE = 77; + SQL_DIAG_CREATE_VIEW = 84; + SQL_DIAG_DELETE_WHERE = 19; + SQL_DIAG_DROP_INDEX = (-2); + SQL_DIAG_DROP_TABLE = 32; + SQL_DIAG_DROP_VIEW = 36; + SQL_DIAG_DYNAMIC_DELETE_CURSOR = 38; + SQL_DIAG_DYNAMIC_UPDATE_CURSOR = 81; + SQL_DIAG_GRANT = 48; + SQL_DIAG_INSERT = 50; + SQL_DIAG_REVOKE = 59; + SQL_DIAG_SELECT_CURSOR = 85; + SQL_DIAG_UNKNOWN_STATEMENT = 0; + SQL_DIAG_UPDATE_WHERE = 82; + SQL_DIAG_CURSOR_ROW_COUNT = -1249; +{$endif} { ODBCVER >= 0x0300 } + + { Statement attribute values for cursor sensitivity } +{$ifdef ODBCVER3} + SQL_UNSPECIFIED = 0; + SQL_INSENSITIVE = 1; + SQL_SENSITIVE = 2; +{$endif} + + { GetTypeInfo() request for all data types } + SQL_ALL_TYPES = 0; + + { Default conversion code for SQLBindCol(), SQLBindParam() and SQLGetData() } +{$ifdef ODBCVER3} + SQL_DEFAULT = 99; +{$endif} + + { SQLGetData() code indicating that the application row descriptor + specifies the data type } +{$ifdef ODBCVER3} + SQL_ARD_TYPE = (-99); +{$endif} + + { SQL date/time type subcodes } +{$ifdef ODBCVER3} + SQL_CODE_DATE = 1; + SQL_CODE_TIME = 2; + SQL_CODE_TIMESTAMP = 3; +{$endif} + + { CLI option values } +{$ifdef ODBCVER3} + SQL_FALSE = 0; + SQL_TRUE = 1; +{$endif} + + { values of NULLABLE field in descriptor } + SQL_NO_NULLS = 0; + SQL_NULLABLE = 1; + +{ Value returned by SQLGetTypeInfo() to denote that it is + not known whether or not a data type supports null values. } + + SQL_NULLABLE_UNKNOWN = 2; +{ +/* Values returned by SQLGetTypeInfo() to show WHERE clause + * supported + +#if (ODBCVER >= 0x0300) +#define SQL_PRED_NONE 0 +#define SQL_PRED_CHAR 1 +#define SQL_PRED_BASIC 2 +#endif + +/* values of UNNAMED field in descriptor */ +#if (ODBCVER >= 0x0300) +#define SQL_NAMED 0 +#define SQL_UNNAMED 1 +#endif + +/* values of ALLOC_TYPE field in descriptor */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_ALLOC_AUTO 1 +#define SQL_DESC_ALLOC_USER 2 +#endif +} + { FreeStmt() options } + SQL_CLOSE = 0; + SQL_DROP = 1; + SQL_UNBIND = 2; + SQL_RESET_PARAMS = 3; + + { Codes used for FetchOrientation in SQLFetchScroll(), + and in SQLDataSources() } + SQL_FETCH_NEXT = 1; + SQL_FETCH_FIRST = 2; +{$ifdef odbcver3} + SQL_FETCH_FIRST_USER = 31; + SQL_FETCH_FIRST_SYSTEM = 32; +{$endif} + + { Other codes used for FetchOrientation in SQLFetchScroll() } + SQL_FETCH_LAST = 3; + SQL_FETCH_PRIOR = 4; + SQL_FETCH_ABSOLUTE = 5; + SQL_FETCH_RELATIVE = 6; +{ +/* SQLEndTran() options */ +#define SQL_COMMIT 0 +#define SQL_ROLLBACK 1} + +//* null handles returned by SQLAllocHandle() */ + SQL_NULL_HENV = SQLHENV(0); + SQL_NULL_HDBC = SQLHDBC(0); + SQL_NULL_HSTMT = SQLHSTMT(0); +{$ifdef odbcver3} + SQL_NULL_HDESC = SQLHDESC(0); +{$endif} + +//* null handle used in place of parent handle when allocating HENV */ + SQL_NULL_HANDLE = SQLHANDLE(0); + +//* Values that may appear in the result set of SQLSpecialColumns() */ + SQL_SCOPE_CURROW = 0; + SQL_SCOPE_TRANSACTION = 1; + SQL_SCOPE_SESSION = 2; + +//* Column types and scopes in SQLSpecialColumns. */ + SQL_BEST_ROWID = 1; + SQL_ROWVER = 2; + +{ +#define SQL_PC_UNKNOWN 0 +#if (ODBCVER >= 0x0300) +#define SQL_PC_NON_PSEUDO 1 +#endif +#define SQL_PC_PSEUDO 2 +} + +//* Reserved value for the IdentifierType argument of SQLSpecialColumns() */ +{$ifdef ODBCVER3} + SQL_ROW_IDENTIFIER = 1; +{$endif} + +//* Reserved values for UNIQUE argument of SQLStatistics() */ + SQL_INDEX_UNIQUE = 0; + SQL_INDEX_ALL = 1; + +//* Reserved values for RESERVED argument of SQLStatistics() */ + SQL_QUICK = 0; + SQL_ENSURE = 1; + +//* Values that may appear in the result set of SQLStatistics() */ + SQL_TABLE_STAT = 0; + SQL_INDEX_CLUSTERED = 1; + SQL_INDEX_HASHED = 2; + SQL_INDEX_OTHER = 3; +// SQL_INDEX_BTREE = ???; +// SQL_INDEX_CONTENT = ???; + +{ +/* Information requested by SQLGetInfo() */ +#if (ODBCVER >= 0x0300) +#define SQL_MAX_DRIVER_CONNECTIONS 0 +#define SQL_MAXIMUM_DRIVER_CONNECTIONS SQL_MAX_DRIVER_CONNECTIONS +#define SQL_MAX_CONCURRENT_ACTIVITIES 1 +#define SQL_MAXIMUM_CONCURRENT_ACTIVITIES SQL_MAX_CONCURRENT_ACTIVITIES +#endif +#define SQL_DATA_SOURCE_NAME 2 +#define SQL_FETCH_DIRECTION 8 +#define SQL_SERVER_NAME 13 +#define SQL_SEARCH_PATTERN_ESCAPE 14 +#define SQL_DBMS_NAME 17 +#define SQL_DBMS_VER 18 +#define SQL_ACCESSIBLE_TABLES 19 +#define SQL_ACCESSIBLE_PROCEDURES 20 +#define SQL_CURSOR_COMMIT_BEHAVIOR 23 +#define SQL_DATA_SOURCE_READ_ONLY 25 +#define SQL_DEFAULT_TXN_ISOLATION 26 +#define SQL_IDENTIFIER_CASE 28 +#define SQL_IDENTIFIER_QUOTE_CHAR 29 +#define SQL_MAX_COLUMN_NAME_LEN 30 +#define SQL_MAXIMUM_COLUMN_NAME_LENGTH SQL_MAX_COLUMN_NAME_LEN +#define SQL_MAX_CURSOR_NAME_LEN 31 +#define SQL_MAXIMUM_CURSOR_NAME_LENGTH SQL_MAX_CURSOR_NAME_LEN +#define SQL_MAX_SCHEMA_NAME_LEN 32 +#define SQL_MAXIMUM_SCHEMA_NAME_LENGTH SQL_MAX_SCHEMA_NAME_LEN +#define SQL_MAX_CATALOG_NAME_LEN 34 +#define SQL_MAXIMUM_CATALOG_NAME_LENGTH SQL_MAX_CATALOG_NAME_LEN +#define SQL_MAX_TABLE_NAME_LEN 35 +} + SQL_SCROLL_CONCURRENCY = 43; + SQL_TXN_CAPABLE = 46; + SQL_TRANSACTION_CAPABLE = SQL_TXN_CAPABLE; + SQL_USER_NAME = 47; + SQL_TXN_ISOLATION_OPTION = 72; + SQL_TRANSACTION_ISOLATION_OPTION = SQL_TXN_ISOLATION_OPTION; +{ +#define SQL_INTEGRITY 73 +#define SQL_GETDATA_EXTENSIONS 81 +#define SQL_NULL_COLLATION 85 +#define SQL_ALTER_TABLE 86 +#define SQL_ORDER_BY_COLUMNS_IN_SELECT 90 +#define SQL_SPECIAL_CHARACTERS 94 +#define SQL_MAX_COLUMNS_IN_GROUP_BY 97 +#define SQL_MAXIMUM_COLUMNS_IN_GROUP_BY SQL_MAX_COLUMNS_IN_GROUP_BY +#define SQL_MAX_COLUMNS_IN_INDEX 98 +#define SQL_MAXIMUM_COLUMNS_IN_INDEX SQL_MAX_COLUMNS_IN_INDEX +#define SQL_MAX_COLUMNS_IN_ORDER_BY 99 +#define SQL_MAXIMUM_COLUMNS_IN_ORDER_BY SQL_MAX_COLUMNS_IN_ORDER_BY +#define SQL_MAX_COLUMNS_IN_SELECT 100 +#define SQL_MAXIMUM_COLUMNS_IN_SELECT SQL_MAX_COLUMNS_IN_SELECT +#define SQL_MAX_COLUMNS_IN_TABLE 101 +#define SQL_MAX_INDEX_SIZE 102 +#define SQL_MAXIMUM_INDEX_SIZE SQL_MAX_INDEX_SIZE +#define SQL_MAX_ROW_SIZE 104 +#define SQL_MAXIMUM_ROW_SIZE SQL_MAX_ROW_SIZE +#define SQL_MAX_STATEMENT_LEN 105 +#define SQL_MAXIMUM_STATEMENT_LENGTH SQL_MAX_STATEMENT_LEN +#define SQL_MAX_TABLES_IN_SELECT 106 +#define SQL_MAXIMUM_TABLES_IN_SELECT SQL_MAX_TABLES_IN_SELECT +#define SQL_MAX_USER_NAME_LEN 107 +#define SQL_MAXIMUM_USER_NAME_LENGTH SQL_MAX_USER_NAME_LEN} +{$ifdef ODBCVER3} + SQL_OJ_CAPABILITIES = 115; + SQL_OUTER_JOIN_CAPABILITIES = SQL_OJ_CAPABILITIES; +{$endif} { ODBCVER >= 0x0300 } + +{$ifdef ODBCVER3} + SQL_XOPEN_CLI_YEAR = 10000; + SQL_CURSOR_SENSITIVITY = 10001; + SQL_DESCRIBE_PARAMETER = 10002; + SQL_CATALOG_NAME = 10003; + SQL_COLLATION_SEQ = 10004; + SQL_MAX_IDENTIFIER_LEN = 10005; + SQL_MAXIMUM_IDENTIFIER_LENGTH = SQL_MAX_IDENTIFIER_LEN; +{$endif} { ODBCVER >= 0x0300 } + +{/* SQL_ALTER_TABLE bitmasks */ +#if (ODBCVER >= 0x0200) +#define SQL_AT_ADD_COLUMN 0x00000001L +#define SQL_AT_DROP_COLUMN 0x00000002L +#endif /* ODBCVER >= 0x0200 */ + +#if (ODBCVER >= 0x0300) +#define SQL_AT_ADD_CONSTRAINT 0x00000008L + +/* The following bitmasks are ODBC extensions and defined in sqlext.h +*#define SQL_AT_COLUMN_SINGLE 0x00000020L +*#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L +*#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L +*#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L +*#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L +*#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L +*#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L +*#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L +*#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L +*#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L +*#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L +*#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L +*#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L +*#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L +*#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L + +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_ASYNC_MODE values */ +#if (ODBCVER >= 0x0300) +#define SQL_AM_NONE 0 +#define SQL_AM_CONNECTION 1 +#define SQL_AM_STATEMENT 2 +#endif + +/* SQL_CURSOR_COMMIT_BEHAVIOR values */ +#define SQL_CB_DELETE 0 +#define SQL_CB_CLOSE 1 +#define SQL_CB_PRESERVE 2 + +/* SQL_FETCH_DIRECTION bitmasks */ +#define SQL_FD_FETCH_NEXT 0x00000001L +#define SQL_FD_FETCH_FIRST 0x00000002L +#define SQL_FD_FETCH_LAST 0x00000004L +#define SQL_FD_FETCH_PRIOR 0x00000008L +#define SQL_FD_FETCH_ABSOLUTE 0x00000010L +#define SQL_FD_FETCH_RELATIVE 0x00000020L + +/* SQL_GETDATA_EXTENSIONS bitmasks */ +#define SQL_GD_ANY_COLUMN 0x00000001L +#define SQL_GD_ANY_ORDER 0x00000002L + +/* SQL_IDENTIFIER_CASE values */ +#define SQL_IC_UPPER 1 +#define SQL_IC_LOWER 2 +#define SQL_IC_SENSITIVE 3 +#define SQL_IC_MIXED 4 + +/* SQL_OJ_CAPABILITIES bitmasks */ +/* NB: this means 'outer join', not what you may be thinking */ + + +#if (ODBCVER >= 0x0201) +#define SQL_OJ_LEFT 0x00000001L +#define SQL_OJ_RIGHT 0x00000002L +#define SQL_OJ_FULL 0x00000004L +#define SQL_OJ_NESTED 0x00000008L +#define SQL_OJ_NOT_ORDERED 0x00000010L +#define SQL_OJ_INNER 0x00000020L +#define SQL_OJ_ALL_COMPARISON_OPS 0x00000040L +#endif +} +{ SQL_SCROLL_CONCURRENCY bitmasks } + SQL_SCCO_READ_ONLY = 1; + SQL_SCCO_LOCK = 2; + SQL_SCCO_OPT_ROWVER = 4; + SQL_SCCO_OPT_VALUES = 8; + +//* SQL_TXN_CAPABLE values */ + SQL_TC_NONE = 0; + SQL_TC_DML = 1; + SQL_TC_ALL = 2; + SQL_TC_DDL_COMMIT = 3; + SQL_TC_DDL_IGNORE = 4; + +//* SQL_TXN_ISOLATION_OPTION bitmasks */ + SQL_TXN_READ_UNCOMMITTED = 1; + SQL_TRANSACTION_READ_UNCOMMITTED = SQL_TXN_READ_UNCOMMITTED; + SQL_TXN_READ_COMMITTED = 2; + SQL_TRANSACTION_READ_COMMITTED = SQL_TXN_READ_COMMITTED; + SQL_TXN_REPEATABLE_READ = 4; + SQL_TRANSACTION_REPEATABLE_READ = SQL_TXN_REPEATABLE_READ; + SQL_TXN_SERIALIZABLE = 8; + SQL_TRANSACTION_SERIALIZABLE = SQL_TXN_SERIALIZABLE; +{ +/* SQL_NULL_COLLATION values */ +#define SQL_NC_HIGH 0 +#define SQL_NC_LOW 1 + +} + +{ SQL_STATIC_SENSITIVITY values } + + SQL_SS_ADDITIONS = 1; + SQL_SS_DELETIONS = 2; + SQL_SS_UPDATES = 4; + +{ SQLColAttributes defines } + SQL_COLUMN_COUNT = 0; + SQL_COLUMN_NAME = 1; + SQL_COLUMN_TYPE = 2; + SQL_COLUMN_LENGTH = 3; + SQL_COLUMN_PRECISION = 4; + SQL_COLUMN_SCALE = 5; + SQL_COLUMN_DISPLAY_SIZE = 6; + SQL_COLUMN_NULLABLE = 7; + SQL_COLUMN_UNSIGNED = 8; + SQL_COLUMN_MONEY = 9; + SQL_COLUMN_UPDATABLE = 10; + SQL_COLUMN_AUTO_INCREMENT = 11; + SQL_COLUMN_CASE_SENSITIVE = 12; + SQL_COLUMN_SEARCHABLE = 13; + SQL_COLUMN_TYPE_NAME = 14; + SQL_COLUMN_TABLE_NAME = 15; + SQL_COLUMN_OWNER_NAME = 16; + SQL_COLUMN_QUALIFIER_NAME = 17; + SQL_COLUMN_LABEL = 18; + SQL_COLATT_OPT_MAX = SQL_COLUMN_LABEL; +{$ifdef ODBCVER3} + SQL_COLUMN_DRIVER_START = 1000; +{$endif} { ODBCVER >= 0x0300 } + + { SQLColAttribute defines } +{$ifdef ODBCVER3} + SQL_DESC_ARRAY_SIZE = 20; + SQL_DESC_ARRAY_STATUS_PTR = 21; + SQL_DESC_AUTO_UNIQUE_VALUE = SQL_COLUMN_AUTO_INCREMENT; + SQL_DESC_BASE_COLUMN_NAME = 22; + SQL_DESC_BASE_TABLE_NAME = 23; + SQL_DESC_BIND_OFFSET_PTR = 24; + SQL_DESC_BIND_TYPE = 25; + SQL_DESC_CASE_SENSITIVE = SQL_COLUMN_CASE_SENSITIVE; + SQL_DESC_CATALOG_NAME = SQL_COLUMN_QUALIFIER_NAME; + SQL_DESC_CONCISE_TYPE = SQL_COLUMN_TYPE; + SQL_DESC_DATETIME_INTERVAL_PRECISION = 26; + SQL_DESC_DISPLAY_SIZE = SQL_COLUMN_DISPLAY_SIZE; + SQL_DESC_FIXED_PREC_SCALE = SQL_COLUMN_MONEY; + SQL_DESC_LABEL = SQL_COLUMN_LABEL; + SQL_DESC_LITERAL_PREFIX = 27; + SQL_DESC_LITERAL_SUFFIX = 28; + SQL_DESC_LOCAL_TYPE_NAME = 29; + SQL_DESC_MAXIMUM_SCALE = 30; + SQL_DESC_MINIMUM_SCALE = 31; + SQL_DESC_NUM_PREC_RADIX = 32; + SQL_DESC_PARAMETER_TYPE = 33; + SQL_DESC_ROWS_PROCESSED_PTR = 34; + SQL_DESC_SCHEMA_NAME = SQL_COLUMN_OWNER_NAME; + SQL_DESC_SEARCHABLE = SQL_COLUMN_SEARCHABLE; + SQL_DESC_TYPE_NAME = SQL_COLUMN_TYPE_NAME; + SQL_DESC_TABLE_NAME = SQL_COLUMN_TABLE_NAME; + SQL_DESC_UNSIGNED = SQL_COLUMN_UNSIGNED; + SQL_DESC_UPDATABLE = SQL_COLUMN_UPDATABLE; +{$endif} + +//* SQLEndTran() options */ + SQL_COMMIT = 0; + SQL_ROLLBACK = 1; + + SQL_ATTR_ROW_ARRAY_SIZE = 27; + +//* SQLConfigDataSource() options */ + ODBC_ADD_DSN = 1; + ODBC_CONFIG_DSN = 2; + ODBC_REMOVE_DSN = 3; + ODBC_ADD_SYS_DSN = 4; + ODBC_CONFIG_SYS_DSN = 5; + ODBC_REMOVE_SYS_DSN = 6; + +{$ifdef DYNLOADINGODBC} +var + SQLAllocHandle: function(HandleType: SQLSMALLINT; + InputHandle:SQLHANDLE; Var OutputHandlePtr: SQLHANDLE): SQLRETURN; + {$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSetEnvAttr: function (EnvironmentHandle:SQLHENV; + Attribute:SQLINTEGER;Value:SQLPOINTER; + StringLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLFreeHandle: function (HandleType:SQLSMALLINT; + Handle:SQLHANDLE):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetDiagRec: function (HandleType:SQLSMALLINT; + Handle:SQLHANDLE;RecNumber:SQLSMALLINT; + Sqlstate:PSQLCHAR;var NativeError:SQLINTEGER; + MessageText:PSQLCHAR;BufferLength:SQLSMALLINT; + var TextLength:SQLSMALLINT ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetDiagField: function (HandleType:SQLSMALLINT; + Handle:SQLHANDLE;RecNumber:SQLSMALLINT; + DiagIdentifier:SQLSMALLINT;DiagInfoPtr:SQLPOINTER; + BufferLength:SQLSMALLINT;var StringLengthPtr:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLConnect: function (ConnectionHandle:SQLHDBC; + ServerName:PSQLCHAR;NameLength1:SQLSMALLINT; + UserName:PSQLCHAR;NameLength2:SQLSMALLINT; + Authentication:PSQLCHAR;NameLength3:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLDisconnect: function(ConnectionHandle:SQLHDBC):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLDriverConnect: function (hdbc: SQLHDBC; + hwnd: SQLHWND;szCsin: PChar; + szCLen: SQLSMALLINT;szCsout: PChar; + cbCSMax: SQLSMALLINT;Var cbCsOut: SQLSMALLINT; + f: SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLExecDirect: function (StatementHandle:SQLHSTMT; + StatementText:PSQLCHAR;TextLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLPrepare: function (StatementHandle:SQLHSTMT; + StatementText:PSQLCHAR;TextLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLCloseCursor: function (StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLExecute: function (StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLFetch: function (StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLNumResultCols: function (StatementHandle:SQLHSTMT; + var ColumnCount:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLDescribeCol: function (StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT;ColumnName:PSQLCHAR; + BufferLength:SQLSMALLINT;var NameLength:SQLSMALLINT; + var DataType:SQLSMALLINT;var ColumnSize:SQLULEN; + var DecimalDigits:SQLSMALLINT;var Nullable:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLFetchScroll: function (StatementHandle:SQLHSTMT; + FetchOrientation:SQLSMALLINT;FetchOffset:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLExtendedFetch: function (hstmt:SQLHSTMT; + fFetchType:SQLUSMALLINT;irow:SQLLEN; + pcrow:PSQLULEN;rgfRowStatus:PSQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetData: function (StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT;TargetType:SQLSMALLINT; + TargetValue:SQLPOINTER;BufferLength:SQLLEN; + StrLen_or_Ind:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSetStmtAttr: function (StatementHandle:SQLHSTMT; + Attribute:SQLINTEGER;Value:SQLPOINTER; + StringLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetStmtAttr: function (StatementHandle:SQLHSTMT; + Attribute:SQLINTEGER;Value:SQLPOINTER; + BufferLength:SQLINTEGER;StringLength:PSQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetInfo: function (ConnectionHandle:SQLHDBC; + InfoType:SQLUSMALLINT;InfoValue:SQLPOINTER; + BufferLength:SQLSMALLINT;StringLength:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLBulkOperations: function (StatementHandle: SQLHSTMT; + Operation:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLPutData: function (StatementHandle:SQLHSTMT; + Data:SQLPOINTER;StrLen_or_Ind:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLBindCol: function (StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT;TargetType:SQLSMALLINT; + TargetValue:SQLPOINTER;BufferLength:SQLLEN; + StrLen_or_Ind:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSetPos: function (hstmt:SQLHSTMT; + irow:SQLSETPOSIROW;fOption:SQLUSMALLINT; + fLock:SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLDataSources: function (EnvironmentHandle:SQLHENV; + Direction:SQLUSMALLINT;ServerName:PSQLCHAR; + BufferLength1:SQLSMALLINT;NameLength1:PSQLSMALLINT; + Description:PSQLCHAR;BufferLength2:SQLSMALLINT; + NameLength2:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLDrivers: function (EnvironmentHandle:SQLHENV; + Direction:SQLUSMALLINT;DriverDescription:PSQLCHAR; + BufferLength1:SQLSMALLINT;DescriptionLength1:PSQLSMALLINT; + DriverAttributes:PSQLCHAR;BufferLength2:SQLSMALLINT; + AttributesLength2:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSetConnectAttr: function (ConnectionHandle:SQLHDBC; + Attribute:SQLINTEGER; Value:SQLPOINTER; + StringLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetCursorName: function (StatementHandle:SQLHSTMT; + CursorName:PSQLCHAR; BufferLength:SQLSMALLINT; + NameLength:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSetCursorName: function (StatementHandle:SQLHSTMT; + CursorName:PSQLCHAR; NameLength:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLRowCount: function (StatementHandle:SQLHSTMT; + Var RowCount:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLBindParameter: function (hstmt:SQLHSTMT; + ipar:SQLUSMALLINT;fParamType:SQLSMALLINT; + fCType:SQLSMALLINT;fSqlType:SQLSMALLINT; + cbColDef:SQLULEN;ibScale:SQLSMALLINT; + rgbValue:SQLPOINTER;cbValueMax:SQLLEN; + pcbValue:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLFreeStmt: function (StatementHandle:SQLHSTMT; + Option:SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLColAttribute: function (StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT;FieldIdentifier:SQLUSMALLINT; + CharacterAttribute:PSQLCHAR;BufferLength:SQLSMALLINT; + StringLength:PSQLSMALLINT;NumericAttribute:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLEndTran: function (HandleType:SQLSMALLINT; + Handle:SQLHANDLE;CompletionType:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLTables: function ( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR;cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR;cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR;cbTableName : SQLSMALLINT; + szTableType : PSQLCHAR;cbTableType : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLColumns: function ( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR;cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR;cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR;cbTableName : SQLSMALLINT; + szColumnName : PSQLCHAR;cbColumnName : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSpecialColumns: function (StatementHandle:SQLHSTMT; + IdentifierType:SQLUSMALLINT;CatalogName:PSQLCHAR; + NameLength1:SQLSMALLINT;SchemaName:PSQLCHAR; + NameLength2:SQLSMALLINT;TableName:PSQLCHAR; + NameLength3:SQLSMALLINT;Scope:SQLUSMALLINT; + Nullable:SQLUSMALLINT) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLProcedures: function ( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR;cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR;cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR;cbTableName : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLPrimaryKeys: function (hstmt : SQLHSTMT; + CatalogName:PSQLCHAR;NameLength1:SQLSMALLINT; + SchemaName:PSQLCHAR;NameLength2:SQLSMALLINT; + TableName:PSQLCHAR;NameLength3:SQLSMALLINT ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + SQLProcedureColumns: function(hstmt: SQLHSTMT; + CatalogName: PSQLCHAR; NameLength1: SQLSMALLINT; + SchemaName: PSQLCHAR; NameLength2: SQLSMALLINT; + ProcName: PSQLCHAR; NameLength3: SQLSMALLINT; + ColumnName: PSQLCHAR; NameLength4: SQLSMALLINT): SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + SQLStatistics: function (hstmt: SQLHSTMT; + CatalogName:PSQLCHAR; NameLength1:SQLSMALLINT; + SchemaName:PSQLCHAR; NameLength2:SQLSMALLINT; + TableName:PSQLCHAR; NameLength3:SQLSMALLINT; + Unique:SQLUSMALLINT; + Reserved:SQLUSMALLINT): SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + +// odbcversion: word; + +{$else} + + function SQLAllocHandle( + HandleType: SQLSMALLINT; + InputHandle:SQLHANDLE; + Var OutputHandlePtr: SQLHANDLE):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLSetEnvAttr( + EnvironmentHandle:SQLHENV; + Attribute: SQLINTEGER; + Value: SQLPOINTER; + StringLength: SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetEnvAttr( + EnvironmentHandle:SQLHENV; + Attribute:SQLINTEGER; + Value:SQLPOINTER; + BufferLength:SQLINTEGER; + StringLength:PSQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLFreeHandle( + HandleType: SQLSMALLINT; + Handle: SQLHANDLE):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetDiagRec( + HandleType: SQLSMALLINT; + Handle: SQLHANDLE; + RecNumber: SQLSMALLINT; + Sqlstate: PSQLCHAR; + var NativeError: SQLINTEGER; + MessageText: PSQLCHAR; + BufferLength: SQLSMALLINT; + var TextLength: SQLSMALLINT ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetDiagField( + HandleType:SQLSMALLINT; + Handle:SQLHANDLE; + RecNumber:SQLSMALLINT; + DiagIdentifier:SQLSMALLINT; + DiagInfoPtr:SQLPOINTER; + BufferLength:SQLSMALLINT; + var StringLengthPtr:SQLSMALLINT ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLConnect( + ConnectionHandle:SQLHDBC; + ServerName:PSQLCHAR; NameLength1:SQLSMALLINT; + UserName:PSQLCHAR; NameLength2:SQLSMALLINT; + Authentication:PSQLCHAR;NameLength3:SQLSMALLINT + ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLDisconnect( + ConnectionHandle:SQLHDBC):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLDriverConnect( + hdbc: SQLHDBC; + hwnd: SQLHWND; + szCsin: PChar; + szCLen: SQLSMALLINT; + szCsout: PChar; + cbCSMax: SQLSMALLINT; + Var cbCsOut: SQLSMALLINT; + f: SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLBrowseConnect( + hdbc : SQLHDBC; + szConnStrIn :PSQLCHAR; + cbConnStrIn: SQLSMALLINT; + szConnStrOut : PSQLCHAR; + cbConnStrOutMax : SQLSMALLINT; + Var cbConnStrOut : SQLSMALLINT) : SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLExecDirect( + StatementHandle:SQLHSTMT; + StatementText: PSQLCHAR; + TextLength: SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLPrepare( + StatementHandle:SQLHSTMT; + StatementText:PSQLCHAR; + TextLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLCloseCursor( + StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLExecute( + StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLFetch( + StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLNumResultCols( + StatementHandle:SQLHSTMT; + var ColumnCount:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLDescribeCol( + StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT; + ColumnName:PSQLCHAR; + BufferLength:SQLSMALLINT; + var NameLength:SQLSMALLINT; + var DataType:SQLSMALLINT; + var ColumnSize:SQLULEN; + var DecimalDigits:SQLSMALLINT; + var Nullable:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLFetchScroll( + StatementHandle:SQLHSTMT; + FetchOrientation:SQLSMALLINT; + FetchOffset:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLExtendedFetch( + hstmt:SQLHSTMT; + fFetchType:SQLUSMALLINT; + irow:SQLLEN; + pcrow:PSQLULEN; + rgfRowStatus:PSQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetData( + StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT; + TargetType:SQLSMALLINT; + TargetValue:SQLPOINTER; + BufferLength:SQLLEN; + StrLen_or_Ind:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLSetStmtAttr( + StatementHandle:SQLHSTMT; + Attribute:SQLINTEGER; + Value:SQLPOINTER; + StringLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetStmtAttr( + StatementHandle:SQLHSTMT; + Attribute:SQLINTEGER; + Value:SQLPOINTER; + BufferLength:SQLINTEGER; + StringLength:PSQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetInfo( + ConnectionHandle:SQLHDBC; + InfoType:SQLUSMALLINT; + InfoValue:SQLPOINTER; + BufferLength:SQLSMALLINT; + StringLength:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLBulkOperations( + StatementHandle: SQLHSTMT; + Operation:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLPutData( + StatementHandle:SQLHSTMT; + Data:SQLPOINTER; + StrLen_or_Ind:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLBindCol( + StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT; + TargetType:SQLSMALLINT; + TargetValue:SQLPOINTER; + BufferLength:SQLLEN; + StrLen_or_Ind:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLSetPos( + hstmt:SQLHSTMT; + irow:SQLSETPOSIROW; + fOption:SQLUSMALLINT; + fLock:SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLDataSources( + EnvironmentHandle:SQLHENV; + Direction:SQLUSMALLINT; + ServerName:PSQLCHAR; + BufferLength1:SQLSMALLINT; + NameLength1:PSQLSMALLINT; + Description:PSQLCHAR; + BufferLength2:SQLSMALLINT; + NameLength2:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLDrivers( + EnvironmentHandle:SQLHENV; + Direction:SQLUSMALLINT; + DriverDescription:PSQLCHAR; + BufferLength1:SQLSMALLINT; + DescriptionLength1:PSQLSMALLINT; + DriverAttributes:PSQLCHAR; + BufferLength2:SQLSMALLINT; + AttributesLength2:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLSetConnectAttr( + ConnectionHandle:SQLHDBC; + Attribute:SQLINTEGER; Value:SQLPOINTER; + StringLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetCursorName( + StatementHandle:SQLHSTMT; + CursorName:PSQLCHAR; BufferLength:SQLSMALLINT; + NameLength:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLSetCursorName( + StatementHandle:SQLHSTMT; + CursorName:PSQLCHAR; NameLength:SQLSMALLINT + ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLRowCount( + StatementHandle:SQLHSTMT; + Var RowCount:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLBindParameter( + hstmt:SQLHSTMT; + ipar:SQLUSMALLINT; + fParamType:SQLSMALLINT; + fCType:SQLSMALLINT; + fSqlType:SQLSMALLINT; + cbColDef:SQLULEN; + ibScale:SQLSMALLINT; + rgbValue:SQLPOINTER; + cbValueMax:SQLLEN; + pcbValue:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLFreeStmt( + StatementHandle:SQLHSTMT; + Option:SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLColAttribute ( + StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT; + FieldIdentifier:SQLUSMALLINT; + CharacterAttribute:PSQLCHAR; + BufferLength:SQLSMALLINT; + StringLength:PSQLSMALLINT; + NumericAttribute:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; +{$ifdef ODBCVER3} + function SQLEndTran( + HandleType:SQLSMALLINT; + Handle:SQLHANDLE; + CompletionType:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; +{$endif} + function SQLTables( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR; + cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR; + cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR; + cbTableName : SQLSMALLINT; + szTableType : PSQLCHAR; + cbTableType : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; external odbclib; + function SQLColumns( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR; + cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR; + cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR; + cbTableName : SQLSMALLINT; + szColumnName : PSQLCHAR; + cbColumnName : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; external odbclib; + function SQLSpecialColumns(StatementHandle:SQLHSTMT; + IdentifierType:SQLUSMALLINT; + CatalogName:PSQLCHAR; + NameLength1:SQLSMALLINT; + SchemaName:PSQLCHAR; + NameLength2:SQLSMALLINT; + TableName:PSQLCHAR; + NameLength3:SQLSMALLINT; + Scope:SQLUSMALLINT; + Nullable:SQLUSMALLINT) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; external odbclib; + function SQLProcedures( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR; + cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR; + cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR; + cbTableName : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; external odbclib; + function SQLPrimaryKeys(hstmt : SQLHSTMT; + CatalogName:PSQLCHAR;NameLength1:SQLSMALLINT; + SchemaName:PSQLCHAR;NameLength2:SQLSMALLINT; + TableName:PSQLCHAR; + NameLength3:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLProcedureColumns(hstmt: SQLHSTMT; + CatalogName: PSQLCHAR; NameLength1: SQLSMALLINT; + SchemaName: PSQLCHAR; NameLength2: SQLSMALLINT; + ProcName: PSQLCHAR; NameLength3: SQLSMALLINT; + ColumnName: PSQLCHAR; NameLength4: SQLSMALLINT): SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + external odbclib; + function SQLStatistics(hstmt: SQLHSTMT; + CatalogName:PSQLCHAR; NameLength1:SQLSMALLINT; + SchemaName:PSQLCHAR; NameLength2:SQLSMALLINT; + TableName:PSQLCHAR; NameLength3:SQLSMALLINT; + Unique:SQLUSMALLINT; + Reserved:SQLUSMALLINT): SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; external odbclib; +{$endif} +// This function always load dynamic + +function DateStructToDateTime( b:PSQL_DATE_STRUCT):TDateTime; +function DateTimeToDateStruct( b:TDateTime):SQL_DATE_STRUCT; +procedure DateTime2TimeStampStruct( var Value:SQL_TIMESTAMP_STRUCT; b:TDateTime); +Function TimeStampStructToDateTime( B : PSQL_TIMESTAMP_STRUCT) : TDateTime; +Function TimeStructToDateTime (B : PSQL_TIME_STRUCT) : TDateTime; + + +{$IFDEF DYNLOADINGODBC} +//Procedure InitialiseODBC(OverrideName : string =''); +//Procedure ReleaseODBC; + +//var ODBCLibraryHandle : TLibHandle; +{$ENDIF} + +implementation + +{$IFDEF DYNLOADINGODBC} +uses + msedynload,msesys; + +var + libinfo: dynlibinfoty; + +//var RefCount : integer; +(* +Procedure InitialiseODBC(OverrideName : string =''); + +var libname : string; + +begin + inc(RefCount); + if RefCount = 1 then + begin + if OverrideName='' then + libname:=odbclib + else + libname:=OverrideName; + ODBCLibraryHandle := loadlibrary(libname); + if ODBCLibraryHandle = nilhandle then + begin + RefCount := 0; + Raise EInOutError.Create('Can not load ODBC client. Is it installed? ('+odbclib+')'); + end; + +{$ifdef fpc} + pointer(SQLAllocHandle) := GetProcedureAddress(ODBCLibraryHandle,'SQLAllocHandle'); + pointer(SQLSetEnvAttr) := GetProcedureAddress(ODBCLibraryHandle,'SQLSetEnvAttr'); + pointer(SQLFreeHandle) := GetProcedureAddress(ODBCLibraryHandle,'SQLFreeHandle'); + pointer(SQLGetInfo) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetInfo'); + pointer(SQLProcedures) := GetProcedureAddress(ODBCLibraryHandle,'SQLProcedures'); + pointer(SQLColumns) := GetProcedureAddress(ODBCLibraryHandle,'SQLColumns'); + pointer(SQLSpecialColumns) := GetProcedureAddress(ODBCLibraryHandle,'SQLSpecialColumns'); + pointer(SQLGetDiagRec) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetDiagRec'); + pointer(SQLGetDiagField) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetDiagField'); + pointer(SQLConnect) := GetProcedureAddress(ODBCLibraryHandle,'SQLConnect'); + pointer(SQLDisconnect) := GetProcedureAddress(ODBCLibraryHandle,'SQLDisconnect'); + pointer(SQLDriverConnect) := GetProcedureAddress(ODBCLibraryHandle,'SQLDriverConnect'); + pointer(SQLExecDirect) := GetProcedureAddress(ODBCLibraryHandle,'SQLExecDirect'); + pointer(SQLPrepare) := GetProcedureAddress(ODBCLibraryHandle,'SQLPrepare'); + pointer(SQLCloseCursor) := GetProcedureAddress(ODBCLibraryHandle,'SQLCloseCursor'); + pointer(SQLExecute) := GetProcedureAddress(ODBCLibraryHandle,'SQLExecute'); + pointer(SQLFetch) := GetProcedureAddress(ODBCLibraryHandle,'SQLFetch'); + pointer(SQLNumResultCols) := GetProcedureAddress(ODBCLibraryHandle,'SQLNumResultCols'); + pointer(SQLDescribeCol) := GetProcedureAddress(ODBCLibraryHandle,'SQLDescribeCol'); + pointer(SQLFetchScroll) := GetProcedureAddress(ODBCLibraryHandle,'SQLFetchScroll'); + pointer(SQLExtendedFetch) := GetProcedureAddress(ODBCLibraryHandle,'SQLExtendedFetch'); + pointer(SQLGetData) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetData'); + pointer(SQLSetStmtAttr) := GetProcedureAddress(ODBCLibraryHandle,'SQLSetStmtAttr'); + pointer(SQLGetStmtAttr) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetStmtAttr'); + pointer(SQLBulkOperations) := GetProcedureAddress(ODBCLibraryHandle,'SQLBulkOperations'); + pointer(SQLPutData) := GetProcedureAddress(ODBCLibraryHandle,'SQLPutData'); + pointer(SQLBindCol) := GetProcedureAddress(ODBCLibraryHandle,'SQLBindCol'); + pointer(SQLSetPos) := GetProcedureAddress(ODBCLibraryHandle,'SQLSetPos'); + pointer(SQLDataSources) := GetProcedureAddress(ODBCLibraryHandle,'SQLDataSources'); + pointer(SQLDrivers) := GetProcedureAddress(ODBCLibraryHandle,'SQLDrivers'); + pointer(SQLSetConnectAttr) := GetProcedureAddress(ODBCLibraryHandle,'SQLSetConnectAttr'); + pointer(SQLGetCursorName) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetCursorName'); + pointer(SQLSetCursorName) := GetProcedureAddress(ODBCLibraryHandle,'SQLSetCursorName'); + pointer(SQLRowCount) := GetProcedureAddress(ODBCLibraryHandle,'SQLRowCount'); + pointer(SQLBindParameter) := GetProcedureAddress(ODBCLibraryHandle,'SQLBindParameter'); + pointer(SQLFreeStmt) := GetProcedureAddress(ODBCLibraryHandle,'SQLFreeStmt'); + pointer(SQLColAttribute) := GetProcedureAddress(ODBCLibraryHandle,'SQLColAttribute'); + pointer(SQLEndTran) := GetProcedureAddress(ODBCLibraryHandle,'SQLEndTran'); + pointer(SQLTables) := GetProcedureAddress(ODBCLibraryHandle,'SQLTables'); + pointer(SQLPrimaryKeys) := GetProcedureAddress(ODBCLibraryHandle,'SQLPrimaryKeys'); + pointer(SQLProcedureColumns) := GetProcedureAddress(ODBCLibraryHandle,'SQLProcedureColumns'); + pointer(SQLStatistics) := GetProcedureAddress(ODBCLibraryHandle,'SQLStatistics'); +{$else} + SQLAllocHandle := GetProcedureAddress(ODBCLibraryHandle,'SQLAllocHandle'); + SQLSetEnvAttr := GetProcedureAddress(ODBCLibraryHandle,'SQLSetEnvAttr'); + SQLFreeHandle := GetProcedureAddress(ODBCLibraryHandle,'SQLFreeHandle'); + SQLGetInfo := GetProcedureAddress(ODBCLibraryHandle,'SQLGetInfo'); + SQLProcedures := GetProcedureAddress(ODBCLibraryHandle,'SQLProcedures'); + SQLColumns := GetProcedureAddress(ODBCLibraryHandle,'SQLColumns'); + SQLSpecialColumns := GetProcedureAddress(ODBCLibraryHandle,'SQLSpecialColumns'); + SQLGetDiagRec := GetProcedureAddress(ODBCLibraryHandle,'SQLGetDiagRec'); + SQLGetDiagField := GetProcedureAddress(ODBCLibraryHandle,'SQLGetDiagField'); + SQLConnect := GetProcedureAddress(ODBCLibraryHandle,'SQLConnect'); + SQLDisconnect := GetProcedureAddress(ODBCLibraryHandle,'SQLDisconnect'); + SQLDriverConnect := GetProcedureAddress(ODBCLibraryHandle,'SQLDriverConnect'); + SQLExecDirect := GetProcedureAddress(ODBCLibraryHandle,'SQLExecDirect'); + SQLPrepare := GetProcedureAddress(ODBCLibraryHandle,'SQLPrepare'); + SQLCloseCursor := GetProcedureAddress(ODBCLibraryHandle,'SQLCloseCursor'); + SQLExecute := GetProcedureAddress(ODBCLibraryHandle,'SQLExecute'); + SQLFetch := GetProcedureAddress(ODBCLibraryHandle,'SQLFetch'); + SQLNumResultCols := GetProcedureAddress(ODBCLibraryHandle,'SQLNumResultCols'); + SQLDescribeCol := GetProcedureAddress(ODBCLibraryHandle,'SQLDescribeCol'); + SQLFetchScroll := GetProcedureAddress(ODBCLibraryHandle,'SQLFetchScroll'); + SQLExtendedFetch := GetProcedureAddress(ODBCLibraryHandle,'SQLExtendedFetch'); + SQLGetData := GetProcedureAddress(ODBCLibraryHandle,'SQLGetData'); + SQLSetStmtAttr := GetProcedureAddress(ODBCLibraryHandle,'SQLSetStmtAttr'); + SQLGetStmtAttr := GetProcedureAddress(ODBCLibraryHandle,'SQLGetStmtAttr'); + SQLBulkOperations := GetProcedureAddress(ODBCLibraryHandle,'SQLBulkOperations'); + SQLPutData := GetProcedureAddress(ODBCLibraryHandle,'SQLPutData'); + SQLBindCol := GetProcedureAddress(ODBCLibraryHandle,'SQLBindCol'); + SQLSetPos := GetProcedureAddress(ODBCLibraryHandle,'SQLSetPos'); + SQLDataSources := GetProcedureAddress(ODBCLibraryHandle,'SQLDataSources'); + SQLDrivers := GetProcedureAddress(ODBCLibraryHandle,'SQLDrivers'); + SQLSetConnectAttr := GetProcedureAddress(ODBCLibraryHandle,'SQLSetConnectAttr'); + SQLGetCursorName := GetProcedureAddress(ODBCLibraryHandle,'SQLGetCursorName'); + SQLSetCursorName := GetProcedureAddress(ODBCLibraryHandle,'SQLSetCursorName'); + SQLRowCount := GetProcedureAddress(ODBCLibraryHandle,'SQLRowCount'); + SQLBindParameter := GetProcedureAddress(ODBCLibraryHandle,'SQLBindParameter'); + SQLGetFunctions := GetProcedureAddress(ODBCLibraryHandle,'SQLGetFunctions'); + SQLDescribeParam :=GetProcedureAddress(ODBCLibraryHandle,'SQLDescribeParam'); + SQLFreeStmt := GetProcedureAddress(ODBCLibraryHandle,'SQLFreeStmt'); + SQLColAttribute := GetProcedureAddress(ODBCLibraryHandle,'SQLColAttribute'); + SQLEndTran := GetProcedureAddress(ODBCLibraryHandle,'SQLEndTran'); + SQLTables := GetProcedureAddress(ODBCLibraryHandle,'SQLTables'); + SQLPrimaryKeys := GetProcedureAddress(ODBCLibraryHandle,'SQLPrimaryKeys'); + SQLProcedureColumns := GetProcedureAddress(ODBCLibraryHandle,'SQLProcedureColumns'); + SQLStatistics := GetProcedureAddress(ODBCLibraryHandle,'SQLStatistics'); +{$endif} + end; +end; + +Procedure ReleaseODBC; + +begin + if RefCount > 0 then dec(RefCount); + if RefCount = 0 then + begin + if not UnloadLibrary(ODBCLibraryHandle) then inc(RefCount); + end; +end; +*) +{$ENDIF} + +function DateStructToDateTime( b:PSQL_DATE_STRUCT):TDateTime; +begin + Result:=EncodeDate( b^.Year, b^.Month, b^.Day); +end; + +function DateTimeToDateStruct( b:TDateTime):SQL_DATE_STRUCT; +var + y,m,d: Word; +begin + DecodeDate( b, y, m, d); + with Result do + begin + Year:=y; Month:=m; Day:=d; + end; +end; + +procedure DateTime2TimeStampStruct( var Value:SQL_TIMESTAMP_STRUCT; b:TDateTime); +var + w1,w2,w3,w4: Word; +begin + with Value do + begin + DecodeDate(b,w1,w2,w3); + Year := w1; + Month := w2; + Day := w3; + DecodeTime(b,w1,w2,w3,w4); + Hour := w1; + Minute := w2; + Second := w3; + fraction := Integer(w4)*1000000; + end; +end; +{ + SQL_DATE_STRUCT = packed record + Year : SQLSMALLINT; + Month : SQLUSMALLINT; + Day : SQLUSMALLINT; + end; + PSQL_DATE_STRUCT = ^SQL_DATE_STRUCT; +} + +Function TimeStampStructToDateTime( B : PSQL_TIMESTAMP_STRUCT) : TDateTime; + +begin + With B^ do + Result:=EncodeDate(Year,Month,Day)+ + EncodeTime(Hour,Minute,Second,0); +end; + +Function TimeStructToDateTime (B : PSQL_TIME_STRUCT) : TDateTime; +begin + With B^ do + Result:=EncodeTime(Hour,Minute,Second,0); +end; + +procedure initializeodbc(const sonames: array of filenamety); + +const + funcs: array[0..41] of funcinfoty = ( + (n: 'SQLAllocHandle'; d: {$ifndef FPC}@{$endif}@SQLAllocHandle), + (n: 'SQLSetEnvAttr'; d: {$ifndef FPC}@{$endif}@SQLSetEnvAttr), + (n: 'SQLFreeHandle'; d: {$ifndef FPC}@{$endif}@SQLFreeHandle), + (n: 'SQLGetInfo'; d: {$ifndef FPC}@{$endif}@SQLGetInfo), + (n: 'SQLProcedures'; d: {$ifndef FPC}@{$endif}@SQLProcedures), + (n: 'SQLColumns'; d: {$ifndef FPC}@{$endif}@SQLColumns), + (n: 'SQLSpecialColumns'; d: {$ifndef FPC}@{$endif}@SQLSpecialColumns), + (n: 'SQLGetDiagRec'; d: {$ifndef FPC}@{$endif}@SQLGetDiagRec), + (n: 'SQLGetDiagField'; d: {$ifndef FPC}@{$endif}@SQLGetDiagField), + (n: 'SQLConnect'; d: {$ifndef FPC}@{$endif}@SQLConnect), + (n: 'SQLDisconnect'; d: {$ifndef FPC}@{$endif}@SQLDisconnect), + (n: 'SQLDriverConnect'; d: {$ifndef FPC}@{$endif}@SQLDriverConnect), + (n: 'SQLExecDirect'; d: {$ifndef FPC}@{$endif}@SQLExecDirect), + (n: 'SQLPrepare'; d: {$ifndef FPC}@{$endif}@SQLPrepare), + (n: 'SQLCloseCursor'; d: {$ifndef FPC}@{$endif}@SQLCloseCursor), + (n: 'SQLExecute'; d: {$ifndef FPC}@{$endif}@SQLExecute), + (n: 'SQLFetch'; d: {$ifndef FPC}@{$endif}@SQLFetch), + (n: 'SQLNumResultCols'; d: {$ifndef FPC}@{$endif}@SQLNumResultCols), + (n: 'SQLDescribeCol'; d: {$ifndef FPC}@{$endif}@SQLDescribeCol), + (n: 'SQLFetchScroll'; d: {$ifndef FPC}@{$endif}@SQLFetchScroll), + (n: 'SQLExtendedFetch'; d: {$ifndef FPC}@{$endif}@SQLExtendedFetch), + (n: 'SQLGetData'; d: {$ifndef FPC}@{$endif}@SQLGetData), + (n: 'SQLSetStmtAttr'; d: {$ifndef FPC}@{$endif}@SQLSetStmtAttr), + (n: 'SQLGetStmtAttr'; d: {$ifndef FPC}@{$endif}@SQLGetStmtAttr), + (n: 'SQLBulkOperations'; d: {$ifndef FPC}@{$endif}@SQLBulkOperations), + (n: 'SQLPutData'; d: {$ifndef FPC}@{$endif}@SQLPutData), + (n: 'SQLBindCol'; d: {$ifndef FPC}@{$endif}@SQLBindCol), + (n: 'SQLSetPos'; d: {$ifndef FPC}@{$endif}@SQLSetPos), + (n: 'SQLDataSources'; d: {$ifndef FPC}@{$endif}@SQLDataSources), + (n: 'SQLDrivers'; d: {$ifndef FPC}@{$endif}@SQLDrivers), + (n: 'SQLSetConnectAttr'; d: {$ifndef FPC}@{$endif}@SQLSetConnectAttr), + (n: 'SQLGetCursorName'; d: {$ifndef FPC}@{$endif}@SQLGetCursorName), + (n: 'SQLSetCursorName'; d: {$ifndef FPC}@{$endif}@SQLSetCursorName), + (n: 'SQLRowCount'; d: {$ifndef FPC}@{$endif}@SQLRowCount), + (n: 'SQLBindParameter'; d: {$ifndef FPC}@{$endif}@SQLBindParameter), +// (n: 'SQLGetFunctions'; d: {$ifndef FPC}@{$endif}@SQLGetFunctions), +// (n: 'SQLDescribeParam'; d: {$ifndef FPC}@{$endif}@SQLDescribeParam), + (n: 'SQLFreeStmt'; d: {$ifndef FPC}@{$endif}@SQLFreeStmt), + (n: 'SQLColAttribute'; d: {$ifndef FPC}@{$endif}@SQLColAttribute), + (n: 'SQLEndTran'; d: {$ifndef FPC}@{$endif}@SQLEndTran), + (n: 'SQLTables'; d: {$ifndef FPC}@{$endif}@SQLTables), + (n: 'SQLPrimaryKeys'; d: {$ifndef FPC}@{$endif}@SQLPrimaryKeys), + (n: 'SQLProcedureColumns'; d: {$ifndef FPC}@{$endif}@SQLProcedureColumns), + (n: 'SQLStatistics'; d: {$ifndef FPC}@{$endif}@SQLStatistics) + ); + errormessage = 'Can not load ODBC library. '; +begin + initializedynlib(libinfo,sonames,odbclib,funcs,[],errormessage); +end; + +procedure releaseodbc; +begin + releasedynlib(libinfo); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/db/postgres3dyn.pas b/mseide-msegui/lib/common/db/postgres3dyn.pas new file mode 100644 index 0000000..f227b00 --- /dev/null +++ b/mseide-msegui/lib/common/db/postgres3dyn.pas @@ -0,0 +1,594 @@ +{ + modified 2009-2010 by Martin Schreiber +} + +{ + Contains the Postgres protocol 3 functions calls + + Call InitialisePostgres3 before using any of the calls, and call ReleasePostgres3 + when finished. +} + +unit postgres3dyn; + +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +interface + +uses + {$ifdef FPC}dynlibs,{$else}{$endif} SysUtils, msectypes,msetypes{msestrings}; + +const +{$ifdef mswindows} + postgreslib: array[0..0] of filenamety = ('libpq.dll'); +{$else} + postgreslib: array[0..2] of filenamety = ('libpq.so.5.4','libpq.so.5','libpq.so'); +{$endif} + +procedure initializepostgres3(const sonames: array of filenamety); +procedure releasepostgres3; + +(* +{$IFDEF Unix} + const + pqlib = 'libpq.'+sharedsuffix; +{$ENDIF} +{$IFDEF Win32} + const + pqlib = 'libpq.dll'; +{$ENDIF} +*) +{$ifdef FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} +//{$i postgres3types.inc} +Type + size_t = sizeint; + psize_t = ^size_t; + TFILE = Longint; + PFIle = ^TFILE; + POid = ^Oid; + Oid = dword; + +type + { Pointer types } + PDllist= ^TDllist; + PDlelem= ^TDlelem; + + TDlelem = record + dle_next : PDlelem; + dle_prev : PDlElem; + dle_val : pointer; + dle_list : PDllist; + end; + + TDllist = record + dll_head : PDlelem; + dll_tail : PDlelem; + end; + +var + DLNewList : function : PDllist;cdecl; + DLFreeList : procedure (_para1:PDllist);cdecl; + DLNewElem : function (val : pointer) :PDlelem;cdecl; + DLFreeElem : procedure (_para1:PDlelem);cdecl; + DLGetHead : function (_para1:PDllist):PDlelem;cdecl; + DLGetTail : function (_para1:PDllist):PDlelem;cdecl; + DLRemTail : function (l:PDllist):PDlelem;cdecl; + DLGetPred : function (_para1:PDlelem):PDlelem;cdecl; + DLGetSucc : function (_para1:PDlelem):PDlelem;cdecl; + DLRemove : procedure (_para1:PDlelem);cdecl; + DLAddHead : procedure (list:PDllist; node:PDlelem);cdecl; + DLAddTail : procedure (list:PDllist; node:PDlelem);cdecl; + DLRemHead : function (list:PDllist):PDlelem;cdecl; + +{ Macro translated } +Function DLE_VAL(elem : PDlelem) : pointer; + +const + ERROR_MSG_LENGTH = 4096; + CMDSTATUS_LEN = 40; + +Type + TSockAddr = Array [1..112] of byte; + TPGresAttDesc = record + name : Pchar; + adtid : Oid; + adtsize : integer; + end; + PPGresAttDesc= ^TPGresAttDesc; + PPPGresAttDesc= ^PPGresAttDesc; + TPGresAttValue = record + len : longint; + value : Pchar; + end; + PPGresAttValue= ^TPGresAttValue; + PPPGresAttValue= ^PPGresAttValue; + + PExecStatusType = ^TExecStatusType; + TExecStatusType = (PGRES_EMPTY_QUERY{$ifdef PFC} := 0{$endif},PGRES_COMMAND_OK, + PGRES_TUPLES_OK,PGRES_COPY_OUT,PGRES_COPY_IN, + PGRES_BAD_RESPONSE,PGRES_NONFATAL_ERROR, + PGRES_FATAL_ERROR); + + + TPGlobjfuncs = record + fn_lo_open : Oid; + fn_lo_close : Oid; + fn_lo_creat : Oid; + fn_lo_unlink : Oid; + fn_lo_lseek : Oid; + fn_lo_tell : Oid; + fn_lo_read : Oid; + fn_lo_write : Oid; + end; + PPGlobjfuncs= ^TPGlobjfuncs; + + PConnStatusType = ^TConnStatusType; + TConnStatusType = (CONNECTION_OK,CONNECTION_BAD,CONNECTION_STARTED, + CONNECTION_MADE,CONNECTION_AWAITING_RESPONSE, + CONNECTION_AUTH_OK,CONNECTION_SETENV, + CONNECTION_SSL_STARTUP,CONNECTION_NEEDED); + + TPGconn = record + pghost : Pchar; + pgtty : Pchar; + pgport : Pchar; + pgoptions : Pchar; + dbName : Pchar; + status : TConnStatusType; + errorMessage : array[0..(ERROR_MSG_LENGTH)-1] of char; + Pfin : PFILE; + Pfout : PFILE; + Pfdebug : PFILE; + sock : longint; + laddr : TSockAddr; + raddr : TSockAddr; + salt : array[0..(2)-1] of char; + asyncNotifyWaiting : longint; + notifyList : PDllist; + pguser : Pchar; + pgpass : Pchar; + lobjfuncs : PPGlobjfuncs; + end; + PPGconn= ^TPGconn; + + TPGresult = record + ntups : longint; + numAttributes : longint; + attDescs : PPGresAttDesc; + tuples : PPPGresAttValue; + tupArrSize : longint; + resultStatus : TExecStatusType; + cmdStatus : array[0..(CMDSTATUS_LEN)-1] of char; + binary : longint; + conn : PPGconn; + end; + PPGresult= ^TPGresult; + + + + + + PPostgresPollingStatusType = ^PostgresPollingStatusType; + PostgresPollingStatusType = (PGRES_POLLING_FAILED{$ifdef FPC} := 0{$endif}, + PGRES_POLLING_READING, + PGRES_POLLING_WRITING,PGRES_POLLING_OK, + PGRES_POLLING_ACTIVE); + + + PPGTransactionStatusType = ^PGTransactionStatusType; + PGTransactionStatusType = (PQTRANS_IDLE,PQTRANS_ACTIVE,PQTRANS_INTRANS, + PQTRANS_INERROR,PQTRANS_UNKNOWN); + + PPGVerbosity = ^PGVerbosity; + PGVerbosity = (PQERRORS_TERSE,PQERRORS_DEFAULT,PQERRORS_VERBOSE); + + PpgNotify = ^pgNotify; + pgNotify = record + relname : Pchar; + be_pid : longint; + extra : Pchar; + end; + +{ Function types for notice-handling callbacks } + PQnoticeReceiver = procedure (arg:pointer; res:PPGresult);cdecl; + PQnoticeProcessor = procedure (arg:pointer; message:Pchar);cdecl; +{ Print options for PQprint() } + Ppqbool = ^pqbool; + pqbool = char; + + P_PQprintOpt = ^_PQprintOpt; + _PQprintOpt = record + header : pqbool; + align : pqbool; + standard : pqbool; + html3 : pqbool; + expanded : pqbool; + pager : pqbool; + fieldSep : Pchar; + tableOpt : Pchar; + caption : Pchar; + fieldName : ^Pchar; + end; + PQprintOpt = _PQprintOpt; + PPQprintOpt = ^PQprintOpt; + + { ---------------- + * Structure for the conninfo parameter definitions returned by PQconndefaults + * + * All fields except "val" point at static strings which must not be altered. + * "val" is either NULL or a malloc'd current-value string. PQconninfoFree() + * will release both the val strings and the PQconninfoOption array itself. + * ---------------- + } + + P_PQconninfoOption = ^_PQconninfoOption; + _PQconninfoOption = record + keyword : Pchar; + envvar : Pchar; + compiled : Pchar; + val : Pchar; + _label : Pchar; + dispchar : Pchar; + dispsize : longint; + end; + PQconninfoOption = _PQconninfoOption; + PPQconninfoOption = ^PQconninfoOption; + { ---------------- + * PQArgBlock -- structure for PQfn() arguments + * ---------------- + } + { can't use void (dec compiler barfs) } + + PPQArgBlock = ^PQArgBlock; + PQArgBlock = record + len : longint; + isint : longint; + u : record + case longint of + 0 : ( ptr : Plongint ); + 1 : ( integer : longint ); + end; + end; + +var +{ ---------------- +* Exported functions of libpq +* ---------------- +} +{ === in fe-connect.c === } +{ make a new client connection to the backend } +{ Asynchronous (non-blocking) } +(* Const before type ignored *) + PQconnectStart : function (conninfo:Pchar):PPGconn;cdecl; + PQconnectPoll : function (conn:PPGconn):PostgresPollingStatusType;cdecl; +{ Synchronous (blocking) } +(* Const before type ignored *) + PQconnectdb : function (conninfo:Pchar):PPGconn;cdecl; + PQsetdbLogin : function (pghost:Pchar; pgport:Pchar; pgoptions:Pchar; pgtty:Pchar; dbName:Pchar;login:Pchar; pwd:Pchar):PPGconn;cdecl; +{ was #define dname(params) para_def_expr } +{ argument types are unknown } +{ return type might be wrong } +{ close the current connection and free the PGconn data structure } + PQfinish : procedure (conn:PPGconn);cdecl; +{ get info about connection options known to PQconnectdb } + PQconndefaults : function : PPQconninfoOption;cdecl; +{ free the data structure returned by PQconndefaults() } + PQconninfoFree : procedure (connOptions:PPQconninfoOption);cdecl; +{ +* close the current connection and restablish a new one with the same +* parameters +} +{ Asynchronous (non-blocking) } + PQresetStart : function (conn:PPGconn):longint;cdecl; + PQresetPoll : function (conn:PPGconn):PostgresPollingStatusType;cdecl; +{ Synchronous (blocking) } + PQreset : procedure (conn:PPGconn);cdecl; +{ issue a cancel request } + PQrequestCancel : function (conn:PPGconn):longint;cdecl; +{ Accessor functions for PGconn objects } + PQdb : function (conn:PPGconn):Pchar;cdecl; + PQuser : function (conn:PPGconn):Pchar;cdecl; + PQpass : function (conn:PPGconn):Pchar;cdecl; + PQhost : function (conn:PPGconn):Pchar;cdecl; + PQport : function (conn:PPGconn):Pchar;cdecl; + PQtty : function (conn:PPGconn):Pchar;cdecl; + PQoptions : function (conn:PPGconn):Pchar;cdecl; + PQstatus : function (conn:PPGconn):TConnStatusType;cdecl; + PQtransactionStatus : function (conn:PPGconn):PGTransactionStatusType;cdecl; + PQparameterStatus : function (conn:PPGconn; paramName:Pchar):Pchar;cdecl; + PQprotocolVersion : function (conn:PPGconn):longint;cdecl; + PQerrorMessage : function (conn:PPGconn):Pchar;cdecl; + PQsocket : function (conn:PPGconn):longint;cdecl; + PQbackendPID : function (conn:PPGconn):longint;cdecl; + PQclientEncoding : function (conn:PPGconn):longint;cdecl; + PQsetClientEncoding : function (conn:PPGconn; encoding:Pchar):longint;cdecl; +{ Set verbosity for PQerrorMessage and PQresultErrorMessage } + PQsetErrorVerbosity : function (conn:PPGconn; verbosity:PGVerbosity):PGVerbosity;cdecl; +{ Enable/disable tracing } + PQtrace : procedure (conn:PPGconn; debug_port:PFILE);cdecl; + PQuntrace : procedure (conn:PPGconn);cdecl; +{ Override default notice handling routines } + PQsetNoticeReceiver : function (conn:PPGconn; proc:PQnoticeReceiver; arg:pointer):PQnoticeReceiver;cdecl; + PQsetNoticeProcessor : function (conn:PPGconn; proc:PQnoticeProcessor; arg:pointer):PQnoticeProcessor;cdecl; +{ === in fe-exec.c === } +{ Simple synchronous query } + PQexec : function (conn:PPGconn; query:Pchar):PPGresult;cdecl; + PQexecParams : function (conn:PPGconn; command:Pchar; nParams:longint; paramTypes:POid; paramValues:PPchar;paramLengths:Plongint; paramFormats:Plongint; resultFormat:longint):PPGresult;cdecl; + PQexecPrepared : function (conn:PPGconn; stmtName:Pchar; nParams:longint; paramValues:PPchar; paramLengths:Plongint;paramFormats:Plongint; resultFormat:longint):PPGresult;cdecl; + PQPrepare : function (conn:PPGconn; stmtName:Pchar; query:Pchar; nParams:longint; paramTypes:POid):PPGresult;cdecl; +{ Interface for multiple-result or asynchronous queries } + PQsendQuery : function (conn:PPGconn; query:Pchar):longint;cdecl; + PQsendQueryParams : function (conn:PPGconn; command:Pchar; nParams:longint; paramTypes:POid; paramValues:PPchar;paramLengths:Plongint; paramFormats:Plongint; resultFormat:longint):longint;cdecl; + PQsendQueryPrepared : function (conn:PPGconn; stmtName:Pchar; nParams:longint; paramValues:PPchar; paramLengths:Plongint;paramFormats:Plongint; resultFormat:longint):longint;cdecl; + PQgetResult : function (conn:PPGconn):PPGresult;cdecl; +{ Routines for managing an asynchronous query } + PQisBusy : function (conn:PPGconn):longint;cdecl; + PQconsumeInput : function (conn:PPGconn):longint;cdecl; +{ LISTEN/NOTIFY support } + PQnotifies : function (conn:PPGconn):PPGnotify;cdecl; +{ Routines for copy in/out } + PQputCopyData : function (conn:PPGconn; buffer:Pchar; nbytes:longint):longint;cdecl; + PQputCopyEnd : function (conn:PPGconn; errormsg:Pchar):longint;cdecl; + PQgetCopyData : function (conn:PPGconn; buffer:PPchar; async:longint):longint;cdecl; +{ Deprecated routines for copy in/out } + PQgetline : function (conn:PPGconn; _string:Pchar; length:longint):longint;cdecl; + PQputline : function (conn:PPGconn; _string:Pchar):longint;cdecl; + PQgetlineAsync : function (conn:PPGconn; buffer:Pchar; bufsize:longint):longint;cdecl; + PQputnbytes : function (conn:PPGconn; buffer:Pchar; nbytes:longint):longint;cdecl; + PQendcopy : function (conn:PPGconn):longint;cdecl; +{ Set blocking/nonblocking connection to the backend } + PQsetnonblocking : function (conn:PPGconn; arg:longint):longint;cdecl; + PQisnonblocking : function (conn:PPGconn):longint;cdecl; +{ Force the write buffer to be written (or at least try) } + PQflush : function (conn:PPGconn):longint;cdecl; +{ +* "Fast path" interface --- not really recommended for application +* use +} + PQfn : function (conn:PPGconn; fnid:longint; result_buf:Plongint; result_len:Plongint; result_is_int:longint;args:PPQArgBlock; nargs:longint):PPGresult;cdecl; +{ Accessor functions for PGresult objects } + PQresultStatus : function (res:PPGresult):TExecStatusType;cdecl; + PQresStatus : function (status:TExecStatusType):Pchar;cdecl; + PQresultErrorMessage : function (res:PPGresult):Pchar;cdecl; + PQresultErrorField : function (res:PPGresult; fieldcode:longint):Pchar;cdecl; + PQntuples : function (res:PPGresult):longint;cdecl; + PQnfields : function (res:PPGresult):longint;cdecl; + PQbinaryTuples : function (res:PPGresult):longint;cdecl; + PQfname : function (res:PPGresult; field_num:longint):Pchar;cdecl; + PQfnumber : function (res:PPGresult; field_name:Pchar):longint;cdecl; + PQftable : function (res:PPGresult; field_num:longint):Oid;cdecl; + PQftablecol : function (res:PPGresult; field_num:longint):longint;cdecl; + PQfformat : function (res:PPGresult; field_num:longint):longint;cdecl; + PQftype : function (res:PPGresult; field_num:longint):Oid;cdecl; + PQfsize : function (res:PPGresult; field_num:longint):longint;cdecl; + PQfmod : function (res:PPGresult; field_num:longint):longint;cdecl; + PQcmdStatus : function (res:PPGresult):Pchar;cdecl; + PQoidStatus : function (res:PPGresult):Pchar;cdecl; +{ old and ugly } + PQoidValue : function (res:PPGresult):Oid;cdecl; +{ new and improved } + PQcmdTuples : function (res:PPGresult):Pchar;cdecl; + PQgetvalue : function (res:PPGresult; tup_num:longint; field_num:longint):Pchar;cdecl; + PQgetlength : function (res:PPGresult; tup_num:longint; field_num:longint):longint;cdecl; + PQgetisnull : function (res:PPGresult; tup_num:longint; field_num:longint):longint;cdecl; +{ Delete a PGresult } + PQclear : procedure (res:PPGresult);cdecl; +{ For freeing other alloc'd results, such as PGnotify structs } + PQfreemem : procedure (ptr:pointer);cdecl; +{ Exists for backward compatibility. bjm 2003-03-24 } +{ was #define dname(params) para_def_expr } +{ argument types are unknown } +{ return type might be wrong } +// function PQfreeNotify(ptr : longint) : longint; +{ +* Make an empty PGresult with given status (some apps find this +* useful). If conn is not NULL and status indicates an error, the +* conn's errorMessage is copied. +} + PQmakeEmptyPGresult : function (conn:PPGconn; status:TExecStatusType):PPGresult;cdecl; +{ Quoting strings before inclusion in queries. } + PQescapeString : function (till:Pchar; from:Pchar; length:size_t):size_t;cdecl; + PQescapeBytea : function (bintext:Pbyte; binlen:size_t; bytealen:Psize_t):Pbyte;cdecl; + PQunescapeBytea : function (strtext:Pbyte; retbuflen:Psize_t):Pbyte;cdecl; +{ === in fe-print.c === } +{ output stream } + PQprint : procedure (fout:PFILE; res:PPGresult; ps:PPQprintOpt);cdecl; +{ option structure } +{ +* really old printing routines +} +{ where to send the output } +{ pad the fields with spaces } +{ field separator } +{ display headers? } + PQdisplayTuples : procedure (res:PPGresult; fp:PFILE; fillAlign:longint; fieldSep:Pchar; printHeader:longint;quiet:longint);cdecl; +(* Const before type ignored *) +{ output stream } +{ print attribute names } +{ delimiter bars } + PQprintTuples : procedure (res:PPGresult; fout:PFILE; printAttName:longint; terseOutput:longint; width:longint);cdecl; +{ width of column, if 0, use variable +* width } +{ === in fe-lobj.c === } +{ Large-object access routines } + lo_open : function (conn:PPGconn; lobjId:Oid; mode:longint):longint;cdecl; + lo_close : function (conn:PPGconn; fd:longint):longint;cdecl; + lo_read : function (conn:PPGconn; fd:longint; buf:Pchar; len:size_t):longint;cdecl; + lo_write : function (conn:PPGconn; fd:longint; buf:Pchar; len:size_t):longint;cdecl; + lo_lseek : function (conn:PPGconn; fd:longint; offset:longint; whence:longint):longint;cdecl; + lo_creat : function (conn:PPGconn; mode:longint):Oid;cdecl; + lo_tell : function (conn:PPGconn; fd:longint):longint;cdecl; + lo_unlink : function (conn:PPGconn; lobjId:Oid):longint;cdecl; + lo_import : function (conn:PPGconn; filename:Pchar):Oid;cdecl; + lo_export : function (conn:PPGconn; lobjId:Oid; filename:Pchar):longint;cdecl; +{ === in fe-misc.c === } +{ Determine length of multibyte encoded char at *s } + PQmblen : function (s:Pbyte; encoding:longint):longint;cdecl; +{ Get encoding id from environment variable PGCLIENTENCODING } + PQenv2encoding: function :longint;cdecl; + +//{$ifdef USE_SSL} +{ Get the SSL structure associated with a connection } +// PQgetssl : function (conn:PPGconn):PSSL;cdecl; + PQgetssl : function (conn:PPGconn): pointer;cdecl; +//{$endif} + +implementation +uses + {msesonames,}msedynload,msesys; + +var + libinfo: dynlibinfoty; + +// This function is also defined in postgres3! +function PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME : pchar) : ppgconn; +begin + PQsetdb:=PQsetdbLogin(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME,'',''); +end; + +// This function is also defined in Dllist! +Function DLE_VAL(elem : PDlelem) : pointer; +begin + DLE_VAL:=elem^.dle_val +end; + +procedure initializepostgres3(const sonames: array of filenamety); +const + funcs: array[0..97] of funcinfoty = ( + (n: 'PQconnectStart'; d: {$ifndef FPC}@{$endif}@PQconnectStart), + (n: 'PQconnectPoll'; d: {$ifndef FPC}@{$endif}@PQconnectPoll), + (n: 'PQconnectdb'; d: {$ifndef FPC}@{$endif}@PQconnectdb), + (n: 'PQsetdbLogin'; d: {$ifndef FPC}@{$endif}@PQsetdbLogin), + (n: 'PQfinish'; d: {$ifndef FPC}@{$endif}@PQfinish), + (n: 'PQconndefaults'; d: {$ifndef FPC}@{$endif}@PQconndefaults), + (n: 'PQconninfoFree'; d: {$ifndef FPC}@{$endif}@PQconninfoFree), + (n: 'PQresetStart'; d: {$ifndef FPC}@{$endif}@PQresetStart), + (n: 'PQresetPoll'; d: {$ifndef FPC}@{$endif}@PQresetPoll), + (n: 'PQreset'; d: {$ifndef FPC}@{$endif}@PQreset), + (n: 'PQrequestCancel'; d: {$ifndef FPC}@{$endif}@PQrequestCancel), + (n: 'PQdb'; d: {$ifndef FPC}@{$endif}@PQdb), + (n: 'PQuser'; d: {$ifndef FPC}@{$endif}@PQuser), + (n: 'PQpass'; d: {$ifndef FPC}@{$endif}@PQpass), + (n: 'PQhost'; d: {$ifndef FPC}@{$endif}@PQhost), + (n: 'PQport'; d: {$ifndef FPC}@{$endif}@PQport), + (n: 'PQtty'; d: {$ifndef FPC}@{$endif}@PQtty), + (n: 'PQoptions'; d: {$ifndef FPC}@{$endif}@PQoptions), + (n: 'PQstatus'; d: {$ifndef FPC}@{$endif}@PQstatus), + (n: 'PQtransactionStatus'; d: {$ifndef FPC}@{$endif}@PQtransactionStatus), + (n: 'PQparameterStatus'; d: {$ifndef FPC}@{$endif}@PQparameterStatus), + (n: 'PQprotocolVersion'; d: {$ifndef FPC}@{$endif}@PQprotocolVersion), + (n: 'PQerrorMessage'; d: {$ifndef FPC}@{$endif}@PQerrorMessage), + (n: 'PQsocket'; d: {$ifndef FPC}@{$endif}@PQsocket), + (n: 'PQbackendPID'; d: {$ifndef FPC}@{$endif}@PQbackendPID), + (n: 'PQclientEncoding'; d: {$ifndef FPC}@{$endif}@PQclientEncoding), + (n: 'PQsetClientEncoding'; d: {$ifndef FPC}@{$endif}@PQsetClientEncoding), + (n: 'PQsetErrorVerbosity'; d: {$ifndef FPC}@{$endif}@PQsetErrorVerbosity), + (n: 'PQtrace'; d: {$ifndef FPC}@{$endif}@PQtrace), + (n: 'PQuntrace'; d: {$ifndef FPC}@{$endif}@PQuntrace), + (n: 'PQsetNoticeReceiver'; d: {$ifndef FPC}@{$endif}@PQsetNoticeReceiver), + (n: 'PQsetNoticeProcessor'; d: {$ifndef FPC}@{$endif}@PQsetNoticeProcessor), + (n: 'PQexec'; d: {$ifndef FPC}@{$endif}@PQexec), + (n: 'PQexecParams'; d: {$ifndef FPC}@{$endif}@PQexecParams), + (n: 'PQexecPrepared'; d: {$ifndef FPC}@{$endif}@PQexecPrepared), + (n: 'PQprepare'; d: {$ifndef FPC}@{$endif}@PQprepare), + (n: 'PQsendQuery'; d: {$ifndef FPC}@{$endif}@PQsendQuery), + (n: 'PQsendQueryParams'; d: {$ifndef FPC}@{$endif}@PQsendQueryParams), + (n: 'PQsendQueryPrepared'; d: {$ifndef FPC}@{$endif}@PQsendQueryPrepared), + (n: 'PQgetResult'; d: {$ifndef FPC}@{$endif}@PQgetResult), + (n: 'PQisBusy'; d: {$ifndef FPC}@{$endif}@PQisBusy), + (n: 'PQconsumeInput'; d: {$ifndef FPC}@{$endif}@PQconsumeInput), + (n: 'PQnotifies'; d: {$ifndef FPC}@{$endif}@PQnotifies), + (n: 'PQputCopyData'; d: {$ifndef FPC}@{$endif}@PQputCopyData), + (n: 'PQputCopyEnd'; d: {$ifndef FPC}@{$endif}@PQputCopyEnd), + (n: 'PQgetCopyData'; d: {$ifndef FPC}@{$endif}@PQgetCopyData), + (n: 'PQgetline'; d: {$ifndef FPC}@{$endif}@PQgetline), + (n: 'PQputline'; d: {$ifndef FPC}@{$endif}@PQputline), + (n: 'PQgetlineAsync'; d: {$ifndef FPC}@{$endif}@PQgetlineAsync), + (n: 'PQputnbytes'; d: {$ifndef FPC}@{$endif}@PQputnbytes), + (n: 'PQendcopy'; d: {$ifndef FPC}@{$endif}@PQendcopy), + (n: 'PQsetnonblocking'; d: {$ifndef FPC}@{$endif}@PQsetnonblocking), + (n: 'PQisnonblocking'; d: {$ifndef FPC}@{$endif}@PQisnonblocking), + (n: 'PQflush'; d: {$ifndef FPC}@{$endif}@PQflush), + (n: 'PQfn'; d: {$ifndef FPC}@{$endif}@PQfn), + (n: 'PQresultStatus'; d: {$ifndef FPC}@{$endif}@PQresultStatus), + (n: 'PQresStatus'; d: {$ifndef FPC}@{$endif}@PQresStatus), + (n: 'PQresultErrorMessage'; d: {$ifndef FPC}@{$endif}@PQresultErrorMessage), + (n: 'PQresultErrorField'; d: {$ifndef FPC}@{$endif}@PQresultErrorField), + (n: 'PQntuples'; d: {$ifndef FPC}@{$endif}@PQntuples), + (n: 'PQnfields'; d: {$ifndef FPC}@{$endif}@PQnfields), + (n: 'PQbinaryTuples'; d: {$ifndef FPC}@{$endif}@PQbinaryTuples), + (n: 'PQfname'; d: {$ifndef FPC}@{$endif}@PQfname), + (n: 'PQfnumber'; d: {$ifndef FPC}@{$endif}@PQfnumber), + (n: 'PQftable'; d: {$ifndef FPC}@{$endif}@PQftable), + (n: 'PQftablecol'; d: {$ifndef FPC}@{$endif}@PQftablecol), + (n: 'PQfformat'; d: {$ifndef FPC}@{$endif}@PQfformat), + (n: 'PQftype'; d: {$ifndef FPC}@{$endif}@PQftype), + (n: 'PQfsize'; d: {$ifndef FPC}@{$endif}@PQfsize), + (n: 'PQfmod'; d: {$ifndef FPC}@{$endif}@PQfmod), + (n: 'PQcmdStatus'; d: {$ifndef FPC}@{$endif}@PQcmdStatus), + (n: 'PQoidStatus'; d: {$ifndef FPC}@{$endif}@PQoidStatus), + (n: 'PQoidValue'; d: {$ifndef FPC}@{$endif}@PQoidValue), + (n: 'PQcmdTuples'; d: {$ifndef FPC}@{$endif}@PQcmdTuples), + (n: 'PQgetvalue'; d: {$ifndef FPC}@{$endif}@PQgetvalue), + (n: 'PQgetlength'; d: {$ifndef FPC}@{$endif}@PQgetlength), + (n: 'PQgetisnull'; d: {$ifndef FPC}@{$endif}@PQgetisnull), + (n: 'PQclear'; d: {$ifndef FPC}@{$endif}@PQclear), + (n: 'PQfreemem'; d: {$ifndef FPC}@{$endif}@PQfreemem), + (n: 'PQmakeEmptyPGresult'; d: {$ifndef FPC}@{$endif}@PQmakeEmptyPGresult), + (n: 'PQescapeString'; d: {$ifndef FPC}@{$endif}@PQescapeString), + (n: 'PQescapeBytea'; d: {$ifndef FPC}@{$endif}@PQescapeBytea), + (n: 'PQunescapeBytea'; d: {$ifndef FPC}@{$endif}@PQunescapeBytea), + (n: 'PQprint'; d: {$ifndef FPC}@{$endif}@PQprint), + (n: 'PQdisplayTuples'; d: {$ifndef FPC}@{$endif}@PQdisplayTuples), + (n: 'PQprintTuples'; d: {$ifndef FPC}@{$endif}@PQprintTuples), + (n: 'lo_open'; d: {$ifndef FPC}@{$endif}@lo_open), + (n: 'lo_close'; d: {$ifndef FPC}@{$endif}@lo_close), + (n: 'lo_read'; d: {$ifndef FPC}@{$endif}@lo_read), + (n: 'lo_write'; d: {$ifndef FPC}@{$endif}@lo_write), + (n: 'lo_lseek'; d: {$ifndef FPC}@{$endif}@lo_lseek), + (n: 'lo_creat'; d: {$ifndef FPC}@{$endif}@lo_creat), + (n: 'lo_tell'; d: {$ifndef FPC}@{$endif}@lo_tell), + (n: 'lo_unlink'; d: {$ifndef FPC}@{$endif}@lo_unlink), + (n: 'lo_import'; d: {$ifndef FPC}@{$endif}@lo_import), + (n: 'lo_export'; d: {$ifndef FPC}@{$endif}@lo_export), + (n: 'PQmblen'; d: {$ifndef FPC}@{$endif}@PQmblen), + (n: 'PQenv2encoding'; d: {$ifndef FPC}@{$endif}@PQenv2encoding) + ); + + funcsopt: array[0..13] of funcinfoty = ( + (n: 'PQgetssl'; d: {$ifndef FPC}@{$endif}@PQgetssl), + + (n: 'DLNewList'; d: {$ifndef FPC}@{$endif}@DLNewList), //these functions seem not to be exported by + (n: 'DLFreeList'; d: {$ifndef FPC}@{$endif}@DLFreeList),//pqlib?? + (n: 'DLNewElem'; d: {$ifndef FPC}@{$endif}@DLNewElem), + (n: 'DLFreeElem'; d: {$ifndef FPC}@{$endif}@DLFreeElem), + (n: 'DLGetHead'; d: {$ifndef FPC}@{$endif}@DLGetHead), + (n: 'DLGetTail'; d: {$ifndef FPC}@{$endif}@DLGetTail), + (n: 'DLRemTail'; d: {$ifndef FPC}@{$endif}@DLRemTail), + (n: 'DLGetPred'; d: {$ifndef FPC}@{$endif}@DLGetPred), + (n: 'DLGetSucc'; d: {$ifndef FPC}@{$endif}@DLGetSucc), + (n: 'DLRemove'; d: {$ifndef FPC}@{$endif}@DLRemove), + (n: 'DLAddHead'; d: {$ifndef FPC}@{$endif}@DLAddHead), + (n: 'DLAddTail'; d: {$ifndef FPC}@{$endif}@DLAddTail), + (n: 'DLRemHead'; d: {$ifndef FPC}@{$endif}@DLRemHead) + ); + errormessage = 'Can not load Postgres library. '; +begin + initializedynlib(libinfo,sonames,postgreslib,funcs,funcsopt,errormessage); +end; + +procedure releasepostgres3; +begin + releasedynlib(libinfo); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/db/sqlite3dyn.pas b/mseide-msegui/lib/common/db/sqlite3dyn.pas new file mode 100644 index 0000000..4917e59 --- /dev/null +++ b/mseide-msegui/lib/common/db/sqlite3dyn.pas @@ -0,0 +1,948 @@ +unit sqlite3dyn; +{$ifdef FPC}{$mode objfpc} {$h+}{$endif} + +{$ifdef BSD} + {$linklib c} + {$linklib pthread} +{$endif} + +// use mse_sqlite3static for static linking of the SQLite3 library +// + +interface +uses + {msesonames,}msedynload,msetypes{msestrings}{$ifndef FPC}{$endif}; +const +{$ifdef mswindows} + sqlite3lib: array[0..0] of filenamety = ('sqlite3.dll'); +{$else} + sqlite3lib: array[0..1] of filenamety = ('libsqlite3.so.0','libsqlite3.so'); +{$endif} + +{ + Automatically converted by H2Pas 0.99.16 from sqlite3.h + The following command line parameters were used: + -D + -c + sqlite3.h + + Manual corrections made by Luiz Am?rico - 2005 + Martin Schreiber 2007 +} + +procedure initializesqlite3(const sonames: array of filenamety); //[] = default +procedure releasesqlite3; + +{$ifdef FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} +const + +{$ifdef mse_sqlite3static} + {$ifdef mswindows} + sqlite3lib = 'sqlite3.dll'; + {$else} + sqlite3lib = 'libsqlite3.so'; + {$endif} +{$endif} + + SQLITE_INTEGER = 1; + SQLITE_FLOAT = 2; +{ #define SQLITE_TEXT 3 // See below } + SQLITE_BLOB = 4; + SQLITE_NULL = 5; + SQLITE_TEXT = 3; + SQLITE3_TEXT = 3; + SQLITE_UTF8 = 1; + SQLITE_UTF16LE = 2; + SQLITE_UTF16BE = 3; +{ Use native byte order } + SQLITE_UTF16 = 4; +{ sqlite3_create_function only } + SQLITE_ANY = 5; + + //sqlite_exec return values + SQLITE_OK = 0; + SQLITE_ERROR = 1;{ SQL error or missing database } + SQLITE_INTERNAL = 2;{ An internal logic error in SQLite } + SQLITE_PERM = 3; { Access permission denied } + SQLITE_ABORT = 4; { Callback routine requested an abort } + SQLITE_BUSY = 5; { The database file is locked } + SQLITE_LOCKED = 6;{ A table in the database is locked } + SQLITE_NOMEM = 7; { A malloc() failed } + SQLITE_READONLY = 8;{ Attempt to write a readonly database } + SQLITE_INTERRUPT = 9;{ Operation terminated by sqlite3_interrupt() } + SQLITE_IOERR = 10; { Some kind of disk I/O error occurred } + SQLITE_CORRUPT = 11; { The database disk image is malformed } + SQLITE_NOTFOUND = 12; { (Internal Only) Table or record not found } + SQLITE_FULL = 13; { Insertion failed because database is full } + SQLITE_CANTOPEN = 14; { Unable to open the database file } + SQLITE_PROTOCOL = 15; { Database lock protocol error } + SQLITE_EMPTY = 16; { Database is empty } + SQLITE_SCHEMA = 17; { The database schema changed } + SQLITE_TOOBIG = 18; { Too much data for one row of a table } + SQLITE_CONSTRAINT = 19; { Abort due to contraint violation } + SQLITE_MISMATCH = 20; { Data type mismatch } + SQLITE_MISUSE = 21; { Library used incorrectly } + SQLITE_NOLFS = 22; { Uses OS features not supported on host } + SQLITE_AUTH = 23; { Authorization denied } + SQLITE_FORMAT = 24; { Auxiliary database format error } + SQLITE_RANGE = 25; { 2nd parameter to sqlite3_bind out of range } + SQLITE_NOTADB = 26; { File opened that is not a database file } + SQLITE_ROW = 100; { sqlite3_step() has another row ready } + SQLITE_DONE = 101; { sqlite3_step() has finished executing } + + sqliteerrormax = 99; + +type + sqlite_int64 = int64; + sqlite_uint64 = qword; + PPPChar = ^PPChar; + Psqlite3 = Pointer; + PPSqlite3 = ^PSqlite3; + Psqlite3_context = Pointer; + Psqlite3_stmt = Pointer; + PPsqlite3_stmt = ^Psqlite3_stmt; + Psqlite3_value = Pointer; + PPsqlite3_value = ^Psqlite3_value; + +//Callback function types +//Notice that most functions were named using as prefix the function name that uses them, +//rather than describing their functions + +// sqlite3_callback = function (_para1:pointer; _para2:longint; _para3:PPchar; _para4:PPchar):longint;cdecl; + sqlite3_callback = function (var _para1; _para2:longint; + _para3:PPchar; _para4:PPchar):longint;cdecl; + //@ operator does not work with dynamic arrays, -O2 and FPC 2_2 + busy_handler_func = function (_para1:pointer; _para2:longint):longint;cdecl; + sqlite3_set_authorizer_func = function (_para1:pointer; _para2:longint; _para3:Pchar; _para4:Pchar; _para5:Pchar; _para6:Pchar):longint;cdecl; + sqlite3_trace_func = procedure (_para1:pointer; _para2:Pchar);cdecl; + sqlite3_progress_handler_func = function (_para1:pointer):longint;cdecl; + sqlite3_commit_hook_func = function (_para1:pointer):longint;cdecl; + bind_destructor_func = procedure (_para1:pointer);cdecl; + create_function_step_func = procedure (_para1:Psqlite3_context; _para2:longint; _para3:PPsqlite3_value);cdecl; + create_function_func_func = procedure (_para1:Psqlite3_context; _para2:longint; _para3:PPsqlite3_value);cdecl; + create_function_final_func = procedure (_para1:Psqlite3_context);cdecl; + sqlite3_set_auxdata_func = procedure (_para1:pointer);cdecl; + sqlite3_result_func = procedure (_para1:pointer);cdecl; + sqlite3_create_collation_func = function (_para1:pointer; _para2:longint; _para3:pointer; _para4:longint; _para5:pointer):longint;cdecl; + sqlite3_collation_needed_func = procedure (_para1:pointer; _para2:Psqlite3; eTextRep:longint; _para4:Pchar);cdecl; + +//{$ifndef win32} +//var +// //This is not working under windows. Any clues? +// sqlite3_temp_directory : Pchar;cvar;external; +//{$endif} + +const + SQLITE_COPY = 0; +{ Index Name Table Name } + SQLITE_CREATE_INDEX = 1; +{ Table Name NULL } + SQLITE_CREATE_TABLE = 2; +{ Index Name Table Name } + SQLITE_CREATE_TEMP_INDEX = 3; +{ Table Name NULL } + SQLITE_CREATE_TEMP_TABLE = 4; +{ Trigger Name Table Name } + SQLITE_CREATE_TEMP_TRIGGER = 5; +{ View Name NULL } + SQLITE_CREATE_TEMP_VIEW = 6; +{ Trigger Name Table Name } + SQLITE_CREATE_TRIGGER = 7; +{ View Name NULL } + SQLITE_CREATE_VIEW = 8; +{ Table Name NULL } + SQLITE_DELETE = 9; +{ Index Name Table Name } + SQLITE_DROP_INDEX = 10; +{ Table Name NULL } + SQLITE_DROP_TABLE = 11; +{ Index Name Table Name } + SQLITE_DROP_TEMP_INDEX = 12; +{ Table Name NULL } + SQLITE_DROP_TEMP_TABLE = 13; +{ Trigger Name Table Name } + SQLITE_DROP_TEMP_TRIGGER = 14; +{ View Name NULL } + SQLITE_DROP_TEMP_VIEW = 15; +{ Trigger Name Table Name } + SQLITE_DROP_TRIGGER = 16; +{ View Name NULL } + SQLITE_DROP_VIEW = 17; +{ Table Name NULL } + SQLITE_INSERT = 18; +{ Pragma Name 1st arg or NULL } + SQLITE_PRAGMA = 19; +{ Table Name Column Name } + SQLITE_READ = 20; +{ NULL NULL } + SQLITE_SELECT = 21; +{ NULL NULL } + SQLITE_TRANSACTION = 22; +{ Table Name Column Name } + SQLITE_UPDATE = 23; +{ Filename NULL } + SQLITE_ATTACH = 24; +{ Database Name NULL } + SQLITE_DETACH = 25; +{ Database Name Table Name } + SQLITE_ALTER_TABLE = 26; +{ Index Name NULL } + SQLITE_REINDEX = 27; + +{ #define SQLITE_OK 0 // Allow access (This is actually defined above) } +{ Abort the SQL statement with an error } + SQLITE_DENY = 1; +{ Don't allow access, but don't generate an error } + SQLITE_IGNORE = 2; + +// Original from sqlite3.h: +//#define SQLITE_STATIC ((void(*)(void *))0) +//#define SQLITE_TRANSIENT ((void(*)(void *))-1) +Const + SQLITE_STATIC = 0; + SQLITE_TRANSIENT = -1; + +{$ifdef mse_sqlite3static} + function sqlite3_close(_para1:Psqlite3):longint; cdecl; external sqlite3lib; +// sqlite3_exec: function(_para1: Psqlite3; sql: Pchar; _para3: sqlite3_callback; +// _para4: pointer; errmsg: PPchar): longint; cdecl; + function sqlite3_exec(_para1: Psqlite3; sql: Pchar; _para3: sqlite3_callback; + var _para4; errmsg: PPchar): longint; cdecl; external sqlite3lib; + function sqlite3_last_insert_rowid(_para1: Psqlite3): sqlite_int64; cdecl; external sqlite3lib; + function sqlite3_changes(_para1: Psqlite3): longint; cdecl; external sqlite3lib; + function sqlite3_total_changes(_para1: Psqlite3): longint; cdecl; external sqlite3lib; + procedure sqlite3_interrupt(_para1: Psqlite3); cdecl; external sqlite3lib; + function sqlite3_complete(sql: Pchar): longint; cdecl; external sqlite3lib; + function sqlite3_complete16(sql: pointer):longint; cdecl; external sqlite3lib; + function sqlite3_busy_handler(_para1: Psqlite3; _para2: busy_handler_func; + _para3: pointer):longint; cdecl; external sqlite3lib; + function sqlite3_busy_timeout(_para1: Psqlite3; ms: longint):longint; cdecl; external sqlite3lib; + function sqlite3_get_table(_para1: Psqlite3; sql: Pchar; resultp: PPPchar; + nrow: Plongint; ncolumn: Plongint; errmsg: PPchar):longint;cdecl; external sqlite3lib; + procedure sqlite3_free_table(result:PPchar);cdecl; external sqlite3lib; + +// Todo: see how translate sqlite3_mprintf, sqlite3_vmprintf, sqlite3_snprintf +// function sqlite3_mprintf(_para1:Pchar; args:array of const):Pchar;cdecl;external External_library name 'sqlite3_mprintf'; + function sqlite3_mprintf(_para1:Pchar):Pchar;cdecl; external sqlite3lib; +//function sqlite3_vmprintf(_para1:Pchar; _para2:va_list):Pchar;cdecl;external External_library name 'sqlite3_vmprintf'; + procedure sqlite3_free(z:Pchar);cdecl; external sqlite3lib; +//function sqlite3_snprintf(_para1:longint; _para2:Pchar; _para3:Pchar; args:array of const):Pchar;cdecl;external External_library name 'sqlite3_snprintf'; + function sqlite3_snprintf(_para1:longint; _para2:Pchar; _para3:Pchar):Pchar;cdecl; external sqlite3lib; + + function sqlite3_set_authorizer(_para1:Psqlite3; xAuth:sqlite3_set_authorizer_func; pUserData:pointer):longint;cdecl; external sqlite3lib; + + + function sqlite3_trace(_para1:Psqlite3; xTrace:sqlite3_trace_func; + _para3:pointer):pointer;cdecl; external sqlite3lib; + procedure sqlite3_progress_handler(_para1:Psqlite3; _para2:longint; + _para3:sqlite3_progress_handler_func; _para4:pointer);cdecl; external sqlite3lib; + function sqlite3_commit_hook(_para1:Psqlite3; + _para2:sqlite3_commit_hook_func; _para3:pointer):pointer;cdecl; external sqlite3lib; + function sqlite3_open(filename:Pchar; ppDb:PPsqlite3):longint;cdecl; external sqlite3lib; + function sqlite3_open16(filename:pointer; ppDb:PPsqlite3):longint;cdecl; external sqlite3lib; + function sqlite3_errcode(db:Psqlite3):longint;cdecl; external sqlite3lib; + function sqlite3_errmsg(_para1:Psqlite3):Pchar;cdecl; external sqlite3lib; + function sqlite3_errmsg16(_para1:Psqlite3):pointer;cdecl; external sqlite3lib; + function sqlite3_prepare(db:Psqlite3; zSql:Pchar; nBytes:longint; + ppStmt:PPsqlite3_stmt; pzTail:PPchar):longint;cdecl; external sqlite3lib; + function sqlite3_prepare16(db:Psqlite3; zSql:pointer; nBytes:longint; + ppStmt:PPsqlite3_stmt; pzTail:Ppointer):longint;cdecl; external sqlite3lib; +// sqlite3_prepare_v2: function(db:Psqlite3; zSql:Pchar; nBytes:longint; +// ppStmt:PPsqlite3_stmt; pzTail:PPchar):longint;cdecl; external sqlite3lib; +// sqlite3_prepare16_v2: function(db:Psqlite3; zSql:pointer; nBytes:longint; +// ppStmt:PPsqlite3_stmt; pzTail:Ppointer):longint;cdecl; external sqlite3lib; + function sqlite3_bind_blob(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; n:longint; _para5:bind_destructor_func):longint;cdecl; external sqlite3lib; + function sqlite3_bind_double(_para1:Psqlite3_stmt; _para2:longint; + _para3:double):longint;cdecl; external sqlite3lib; + function sqlite3_bind_int(_para1:Psqlite3_stmt; _para2:longint; + _para3:longint):longint;cdecl; external sqlite3lib; + function sqlite3_bind_int64(_para1:Psqlite3_stmt; _para2:longint; + _para3:sqlite_int64):longint;cdecl; external sqlite3lib; + function sqlite3_bind_null(_para1:Psqlite3_stmt; + _para2:longint):longint;cdecl; external sqlite3lib; + function sqlite3_bind_text(_para1:Psqlite3_stmt; _para2:longint; + _para3:Pchar; n:longint; _para5:bind_destructor_func):longint;cdecl; external sqlite3lib; + function sqlite3_bind_text16(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; _para4:longint; _para5:bind_destructor_func):longint;cdecl; external sqlite3lib; +//function sqlite3_bind_value(_para1:Psqlite3_stmt; _para2:longint; _para3:Psqlite3_value):longint;cdecl; external sqlite3lib;external External_library name 'sqlite3_bind_value'; + + +//These overloaded functions were introduced to allow the use of SQLITE_STATIC and SQLITE_TRANSIENT +//It's the c world man ;-) + function sqlite3_bind_blob1(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; n:longint; _para5:longint):longint;cdecl; external sqlite3lib; + function sqlite3_bind_text1(_para1:Psqlite3_stmt; _para2:longint; + _para3:Pchar; n:longint; _para5:longint):longint;cdecl; external sqlite3lib; + function sqlite3_bind_text161(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; _para4:longint; _para5:longint):longint;cdecl; external sqlite3lib; + + function sqlite3_bind_parameter_count(_para1:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_bind_parameter_name(_para1:Psqlite3_stmt; + _para2:longint):Pchar;cdecl; external sqlite3lib; + function sqlite3_bind_parameter_index(_para1:Psqlite3_stmt; + zName:Pchar):longint;cdecl; external sqlite3lib; + function sqlite3_clear_bindings(_para1:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_column_count(pStmt:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_column_name(_para1:Psqlite3_stmt; + _para2:longint):Pchar;cdecl; external sqlite3lib; + function sqlite3_column_name16(_para1:Psqlite3_stmt; + _para2:longint):pointer;cdecl; external sqlite3lib; + function sqlite3_column_decltype(_para1:Psqlite3_stmt; + i:longint):Pchar;cdecl; external sqlite3lib; + function sqlite3_column_decltype16(_para1:Psqlite3_stmt; + _para2:longint):pointer;cdecl; external sqlite3lib; + function sqlite3_step(_para1:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_data_count(pStmt:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_column_blob(_para1:Psqlite3_stmt; + iCol:longint):pointer;cdecl; external sqlite3lib; + function sqlite3_column_bytes(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; external sqlite3lib; + function sqlite3_column_bytes16(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; external sqlite3lib; + function sqlite3_column_double(_para1:Psqlite3_stmt; + iCol:longint):double;cdecl; external sqlite3lib; + function sqlite3_column_int(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; external sqlite3lib; + function sqlite3_column_int64(_para1:Psqlite3_stmt; + iCol:longint):sqlite_int64;cdecl; external sqlite3lib; + function sqlite3_column_text(_para1:Psqlite3_stmt; + iCol:longint):PChar;cdecl; external sqlite3lib; + function sqlite3_column_text16(_para1:Psqlite3_stmt; + iCol:longint):pointer;cdecl; external sqlite3lib; + function sqlite3_column_type(_para1:Psqlite3_stmt; iCol:longint):longint;cdecl; external sqlite3lib; + function sqlite3_finalize(pStmt:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_reset(pStmt:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_create_function(_para1:Psqlite3; zFunctionName:Pchar; + nArg:longint; eTextRep:longint; _para5:pointer; + xFunc:create_function_func_func; xStep:create_function_step_func; + xFinal:create_function_final_func):longint;cdecl; external sqlite3lib; + function sqlite3_create_function16(_para1:Psqlite3; zFunctionName:pointer; + nArg:longint; eTextRep:longint; _para5:pointer; + xFunc:create_function_func_func; xStep:create_function_step_func; + xFinal:create_function_final_func):longint;cdecl; external sqlite3lib; + function sqlite3_aggregate_count(_para1:Psqlite3_context):longint;cdecl; external sqlite3lib; + function sqlite3_value_blob(_para1:Psqlite3_value):pointer;cdecl; external sqlite3lib; + function sqlite3_value_bytes(_para1:Psqlite3_value):longint;cdecl; external sqlite3lib; + function sqlite3_value_bytes16(_para1:Psqlite3_value):longint;cdecl; external sqlite3lib; + function sqlite3_value_double(_para1:Psqlite3_value):double;cdecl; external sqlite3lib; + function sqlite3_value_int(_para1:Psqlite3_value):longint;cdecl; external sqlite3lib; + function sqlite3_value_int64(_para1:Psqlite3_value):sqlite_int64;cdecl; external sqlite3lib; + function sqlite3_value_text(_para1:Psqlite3_value):PChar;cdecl; external sqlite3lib; + function sqlite3_value_text16(_para1:Psqlite3_value):pointer;cdecl; external sqlite3lib; + function sqlite3_value_text16le(_para1:Psqlite3_value):pointer;cdecl; external sqlite3lib; + function sqlite3_value_text16be(_para1:Psqlite3_value):pointer;cdecl; external sqlite3lib; + function sqlite3_value_type(_para1:Psqlite3_value):longint;cdecl; external sqlite3lib; + function sqlite3_aggregate_context(_para1:Psqlite3_context; + nBytes:longint):pointer;cdecl; external sqlite3lib; + function sqlite3_user_data(_para1:Psqlite3_context):pointer;cdecl; external sqlite3lib; + function sqlite3_get_auxdata(_para1:Psqlite3_context; + _para2:longint):pointer;cdecl; external sqlite3lib; + procedure sqlite3_set_auxdata(_para1:Psqlite3_context; _para2:longint; + _para3:pointer; _para4:sqlite3_set_auxdata_func);cdecl; external sqlite3lib; + procedure sqlite3_result_blob(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; external sqlite3lib; + procedure sqlite3_result_double(_para1:Psqlite3_context; + _para2:double);cdecl; external sqlite3lib; + procedure sqlite3_result_error(_para1:Psqlite3_context; + _para2:Pchar; _para3:longint);cdecl; external sqlite3lib; + procedure sqlite3_result_error16(_para1:Psqlite3_context; + _para2:pointer; _para3:longint);cdecl; external sqlite3lib; + procedure sqlite3_result_int(_para1:Psqlite3_context; _para2:longint);cdecl; external sqlite3lib; + procedure sqlite3_result_int64(_para1:Psqlite3_context; + _para2:sqlite_int64);cdecl; external sqlite3lib; + procedure sqlite3_result_null(_para1:Psqlite3_context);cdecl; external sqlite3lib; + procedure sqlite3_result_text(_para1:Psqlite3_context; _para2:Pchar; + _para3:longint; _para4:sqlite3_result_func);cdecl; external sqlite3lib; + procedure sqlite3_result_text16(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; external sqlite3lib; + procedure sqlite3_result_text16le(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; external sqlite3lib; + procedure sqlite3_result_text16be(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; external sqlite3lib; + procedure sqlite3_result_value(_para1:Psqlite3_context; + _para2:Psqlite3_value);cdecl; external sqlite3lib; + + function sqlite3_create_collation(_para1:Psqlite3; zName:Pchar; + eTextRep:longint; _para4:pointer; + xCompare:sqlite3_create_collation_func):longint;cdecl; external sqlite3lib; + function sqlite3_create_collation16(_para1:Psqlite3; zName:Pchar; + eTextRep:longint; _para4:pointer; + xCompare:sqlite3_create_collation_func):longint;cdecl; external sqlite3lib; + + function sqlite3_collation_needed(_para1:Psqlite3; _para2:pointer; + _para3:sqlite3_collation_needed_func):longint;cdecl; external sqlite3lib; + function sqlite3_collation_needed16(_para1:Psqlite3; _para2:pointer; + _para3:sqlite3_collation_needed_func):longint;cdecl; external sqlite3lib; + + function sqlite3_libversion:PChar;cdecl; external sqlite3lib; +//Alias for allowing better code portability (win32 is not working with external variables) + function sqlite3_version: PChar;cdecl; external sqlite3lib; + +// Not published functions + function sqlite3_libversion_number:longint;cdecl; external sqlite3lib; +// sqlite3_key: function(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; external sqlite3lib; +// sqlite3_rekey: function(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; external sqlite3lib; +// sqlite3_sleep: function(_para1:longint):longint;cdecl; external sqlite3lib; +// sqlite3_expired: function(_para1:Psqlite3_stmt):longint;cdecl; external sqlite3lib; +// sqlite3_global_recover: function:longint;cdecl; external sqlite3lib; +{$else} +var + sqlite3_close: function(_para1:Psqlite3):longint; cdecl; +// sqlite3_exec: function(_para1: Psqlite3; sql: Pchar; _para3: sqlite3_callback; +// _para4: pointer; errmsg: PPchar): longint; cdecl; + sqlite3_exec: function(_para1: Psqlite3; sql: Pchar; _para3: sqlite3_callback; + var _para4; errmsg: PPchar): longint; cdecl; + sqlite3_last_insert_rowid: function(_para1: Psqlite3): sqlite_int64; cdecl; + sqlite3_changes: function(_para1: Psqlite3): longint; cdecl; + sqlite3_total_changes: function(_para1: Psqlite3): longint; cdecl; + sqlite3_interrupt: procedure(_para1: Psqlite3); cdecl; + sqlite3_complete: function(sql: Pchar): longint; cdecl; + sqlite3_complete16: function(sql: pointer):longint; cdecl; + sqlite3_busy_handler: function(_para1: Psqlite3; _para2: busy_handler_func; + _para3: pointer):longint; cdecl; + sqlite3_busy_timeout: function(_para1: Psqlite3; ms: longint):longint; cdecl; + sqlite3_get_table: function(_para1: Psqlite3; sql: Pchar; resultp: PPPchar; + nrow: Plongint; ncolumn: Plongint; errmsg: PPchar):longint;cdecl; + sqlite3_free_table: procedure(result:PPchar);cdecl; + +// Todo: see how translate sqlite3_mprintf, sqlite3_vmprintf, sqlite3_snprintf +// function sqlite3_mprintf(_para1:Pchar; args:array of const):Pchar;cdecl;external External_library name 'sqlite3_mprintf'; + sqlite3_mprintf: function(_para1:Pchar):Pchar;cdecl; +//function sqlite3_vmprintf(_para1:Pchar; _para2:va_list):Pchar;cdecl;external External_library name 'sqlite3_vmprintf'; + sqlite3_free: procedure(z:Pchar);cdecl; +//function sqlite3_snprintf(_para1:longint; _para2:Pchar; _para3:Pchar; args:array of const):Pchar;cdecl;external External_library name 'sqlite3_snprintf'; + sqlite3_snprintf: function(_para1:longint; _para2:Pchar; _para3:Pchar):Pchar;cdecl; + + sqlite3_set_authorizer: function(_para1:Psqlite3; xAuth:sqlite3_set_authorizer_func; pUserData:pointer):longint;cdecl; + + + sqlite3_trace: function(_para1:Psqlite3; xTrace:sqlite3_trace_func; + _para3:pointer):pointer;cdecl; + sqlite3_progress_handler: procedure(_para1:Psqlite3; _para2:longint; + _para3:sqlite3_progress_handler_func; _para4:pointer);cdecl; + sqlite3_commit_hook: function(_para1:Psqlite3; + _para2:sqlite3_commit_hook_func; _para3:pointer):pointer;cdecl; + sqlite3_open: function(filename:Pchar; ppDb:PPsqlite3):longint;cdecl; + sqlite3_open16: function(filename:pointer; ppDb:PPsqlite3):longint;cdecl; + sqlite3_errcode: function(db:Psqlite3):longint;cdecl; + sqlite3_errmsg: function(_para1:Psqlite3):Pchar;cdecl; + sqlite3_errmsg16: function(_para1:Psqlite3):pointer;cdecl; + sqlite3_prepare: function(db:Psqlite3; zSql:Pchar; nBytes:longint; + ppStmt:PPsqlite3_stmt; pzTail:PPchar):longint;cdecl; + sqlite3_prepare16: function(db:Psqlite3; zSql:pointer; nBytes:longint; + ppStmt:PPsqlite3_stmt; pzTail:Ppointer):longint;cdecl; +// sqlite3_prepare_v2: function(db:Psqlite3; zSql:Pchar; nBytes:longint; +// ppStmt:PPsqlite3_stmt; pzTail:PPchar):longint;cdecl; +// sqlite3_prepare16_v2: function(db:Psqlite3; zSql:pointer; nBytes:longint; +// ppStmt:PPsqlite3_stmt; pzTail:Ppointer):longint;cdecl; + sqlite3_bind_blob: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; n:longint; _para5:bind_destructor_func):longint;cdecl; + sqlite3_bind_double: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:double):longint;cdecl; + sqlite3_bind_int: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:longint):longint;cdecl; + sqlite3_bind_int64: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:sqlite_int64):longint;cdecl; + sqlite3_bind_null: function(_para1:Psqlite3_stmt; + _para2:longint):longint;cdecl; + sqlite3_bind_text: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:Pchar; n:longint; _para5:bind_destructor_func):longint;cdecl; + sqlite3_bind_text16: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; _para4:longint; _para5:bind_destructor_func):longint;cdecl; +//function sqlite3_bind_value(_para1:Psqlite3_stmt; _para2:longint; _para3:Psqlite3_value):longint;cdecl;external External_library name 'sqlite3_bind_value'; + + +//These overloaded functions were introduced to allow the use of SQLITE_STATIC and SQLITE_TRANSIENT +//It's the c world man ;-) + sqlite3_bind_blob1: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; n:longint; _para5:longint):longint;cdecl; + sqlite3_bind_text1: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:Pchar; n:longint; _para5:longint):longint;cdecl; + sqlite3_bind_text161: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; _para4:longint; _para5:longint):longint;cdecl; + + sqlite3_bind_parameter_count: function(_para1:Psqlite3_stmt):longint;cdecl; + sqlite3_bind_parameter_name: function(_para1:Psqlite3_stmt; + _para2:longint):Pchar;cdecl; + sqlite3_bind_parameter_index: function(_para1:Psqlite3_stmt; + zName:Pchar):longint;cdecl; + sqlite3_clear_bindings: function(_para1:Psqlite3_stmt):longint;cdecl; + sqlite3_column_count: function(pStmt:Psqlite3_stmt):longint;cdecl; + sqlite3_column_name: function(_para1:Psqlite3_stmt; + _para2:longint):Pchar;cdecl; + sqlite3_column_name16: function(_para1:Psqlite3_stmt; + _para2:longint):pointer;cdecl; + sqlite3_column_decltype: function(_para1:Psqlite3_stmt; + i:longint):Pchar;cdecl; + sqlite3_column_decltype16: function(_para1:Psqlite3_stmt; + _para2:longint):pointer;cdecl; + sqlite3_step: function(_para1:Psqlite3_stmt):longint;cdecl; + sqlite3_data_count: function(pStmt:Psqlite3_stmt):longint;cdecl; + sqlite3_column_blob: function(_para1:Psqlite3_stmt; + iCol:longint):pointer;cdecl; + sqlite3_column_bytes: function(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; + sqlite3_column_bytes16: function(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; + sqlite3_column_double: function(_para1:Psqlite3_stmt; + iCol:longint):double;cdecl; + sqlite3_column_int: function(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; + sqlite3_column_int64: function(_para1:Psqlite3_stmt; + iCol:longint):sqlite_int64;cdecl; + sqlite3_column_text: function(_para1:Psqlite3_stmt; + iCol:longint):PChar;cdecl; + sqlite3_column_text16: function(_para1:Psqlite3_stmt; + iCol:longint):pointer;cdecl; + sqlite3_column_type: function(_para1:Psqlite3_stmt; iCol:longint):longint;cdecl; + sqlite3_finalize: function(pStmt:Psqlite3_stmt):longint;cdecl; + sqlite3_reset: function(pStmt:Psqlite3_stmt):longint;cdecl; + sqlite3_create_function: function(_para1:Psqlite3; zFunctionName:Pchar; + nArg:longint; eTextRep:longint; _para5:pointer; + xFunc:create_function_func_func; xStep:create_function_step_func; + xFinal:create_function_final_func):longint;cdecl; + sqlite3_create_function16: function(_para1:Psqlite3; zFunctionName:pointer; + nArg:longint; eTextRep:longint; _para5:pointer; + xFunc:create_function_func_func; xStep:create_function_step_func; + xFinal:create_function_final_func):longint;cdecl; + sqlite3_aggregate_count: function(_para1:Psqlite3_context):longint;cdecl; + sqlite3_value_blob: function(_para1:Psqlite3_value):pointer;cdecl; + sqlite3_value_bytes: function(_para1:Psqlite3_value):longint;cdecl; + sqlite3_value_bytes16: function(_para1:Psqlite3_value):longint;cdecl; + sqlite3_value_double: function(_para1:Psqlite3_value):double;cdecl; + sqlite3_value_int: function(_para1:Psqlite3_value):longint;cdecl; + sqlite3_value_int64: function(_para1:Psqlite3_value):sqlite_int64;cdecl; + sqlite3_value_text: function(_para1:Psqlite3_value):PChar;cdecl; + sqlite3_value_text16: function(_para1:Psqlite3_value):pointer;cdecl; + sqlite3_value_text16le: function(_para1:Psqlite3_value):pointer;cdecl; + sqlite3_value_text16be: function(_para1:Psqlite3_value):pointer;cdecl; + sqlite3_value_type: function(_para1:Psqlite3_value):longint;cdecl; + sqlite3_aggregate_context: function(_para1:Psqlite3_context; + nBytes:longint):pointer;cdecl; + sqlite3_user_data: function(_para1:Psqlite3_context):pointer;cdecl; + sqlite3_get_auxdata: function(_para1:Psqlite3_context; + _para2:longint):pointer;cdecl; + sqlite3_set_auxdata: procedure(_para1:Psqlite3_context; _para2:longint; + _para3:pointer; _para4:sqlite3_set_auxdata_func);cdecl; + sqlite3_result_blob: procedure(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; + sqlite3_result_double: procedure(_para1:Psqlite3_context; + _para2:double);cdecl; + sqlite3_result_error: procedure(_para1:Psqlite3_context; + _para2:Pchar; _para3:longint);cdecl; + sqlite3_result_error16: procedure(_para1:Psqlite3_context; + _para2:pointer; _para3:longint);cdecl; + sqlite3_result_int: procedure(_para1:Psqlite3_context; _para2:longint);cdecl; + sqlite3_result_int64: procedure(_para1:Psqlite3_context; + _para2:sqlite_int64);cdecl; + sqlite3_result_null: procedure(_para1:Psqlite3_context);cdecl; + sqlite3_result_text: procedure(_para1:Psqlite3_context; _para2:Pchar; + _para3:longint; _para4:sqlite3_result_func);cdecl; + sqlite3_result_text16: procedure(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; + sqlite3_result_text16le: procedure(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; + sqlite3_result_text16be: procedure(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; + sqlite3_result_value: procedure(_para1:Psqlite3_context; + _para2:Psqlite3_value);cdecl; + + sqlite3_create_collation: function(_para1:Psqlite3; zName:Pchar; + eTextRep:longint; _para4:pointer; + xCompare:sqlite3_create_collation_func):longint;cdecl; + sqlite3_create_collation16: function(_para1:Psqlite3; zName:Pchar; + eTextRep:longint; _para4:pointer; + xCompare:sqlite3_create_collation_func):longint;cdecl; + + sqlite3_collation_needed: function(_para1:Psqlite3; _para2:pointer; + _para3:sqlite3_collation_needed_func):longint;cdecl; + sqlite3_collation_needed16: function(_para1:Psqlite3; _para2:pointer; + _para3:sqlite3_collation_needed_func):longint;cdecl; + + sqlite3_libversion: function:PChar;cdecl; +//Alias for allowing better code portability (win32 is not working with external variables) +// sqlite3_version: function:PChar;cdecl; macro in 3.7.7 + +// Not published functions + sqlite3_libversion_number: function:longint;cdecl; +// sqlite3_key: function(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; +// sqlite3_rekey: function(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; +// sqlite3_sleep: function(_para1:longint):longint;cdecl; +// sqlite3_expired: function(_para1:Psqlite3_stmt):longint;cdecl; +// sqlite3_global_recover: function:longint;cdecl; + +function sqlite3_version: PChar; + +{$endif} //not mse_sqlite3static +implementation +uses + sysutils,{$ifndef mse_sqlite3static}{$ifdef FPC}dynlibs,{$endif}{$endif}msesys,msesysintf; +{$ifndef mse_sqlite3static} +var + libinfo: dynlibinfoty; + +function sqlite3_version: PChar; +begin + result:= sqlite3_libversion(); +end; + +(* +function tryinitialisesqlite3(const alibnames: array of filenamety): boolean; +var + mstr1: filenamety; +begin + sys_mutexlock(liblock); + try + result:= true; + if refcount = 0 then begin + sqlite3libraryhandle:= loadlib(alibnames,mstr1); + if sqlite3libraryhandle = nilhandle then begin + result:= false; + exit; + end; + try + getprocaddresses(sqlite3libraryhandle, + [ + 'sqlite3_close', //0 + 'sqlite3_exec', //1 + 'sqlite3_last_insert_rowid', //2 + 'sqlite3_changes', //3 + 'sqlite3_total_changes', //4 + 'sqlite3_interrupt', //5 + 'sqlite3_complete', //6 + 'sqlite3_complete16', //7 + 'sqlite3_busy_handler', //8 + 'sqlite3_busy_timeout', //9 + 'sqlite3_get_table', //10 + 'sqlite3_free_table', //11 + 'sqlite3_mprintf', //12 + 'sqlite3_free', //13 + 'sqlite3_snprintf', //14 + 'sqlite3_set_authorizer', //15 + 'sqlite3_trace', //16 + 'sqlite3_progress_handler', //17 + 'sqlite3_commit_hook', //18 + 'sqlite3_open', //19 + 'sqlite3_open16', //20 + 'sqlite3_errcode', //21 + 'sqlite3_errmsg', //22 + 'sqlite3_errmsg16', //23 + 'sqlite3_prepare', //24 + 'sqlite3_prepare16', //25 + 'sqlite3_bind_blob', //26 + 'sqlite3_bind_double', //27 + 'sqlite3_bind_int', //28 + 'sqlite3_bind_int64', //29 + 'sqlite3_bind_null', //30 + 'sqlite3_bind_text', //31 + 'sqlite3_bind_text16', //32 + 'sqlite3_bind_blob', //33 + 'sqlite3_bind_text', //34 + 'sqlite3_bind_text16', //35 + 'sqlite3_bind_parameter_count', //36 + 'sqlite3_bind_parameter_name', //37 + 'sqlite3_bind_parameter_index', //38 + 'sqlite3_column_count', //39 + 'sqlite3_column_name', //40 + 'sqlite3_column_name16', //41 + 'sqlite3_column_decltype', //42 + 'sqlite3_column_decltype16', //43 + 'sqlite3_step', //44 + 'sqlite3_data_count', //45 + 'sqlite3_column_blob', //46 + 'sqlite3_column_bytes', //47 + 'sqlite3_column_bytes16', //48 + 'sqlite3_column_double', //49 + 'sqlite3_column_int', //50 + 'sqlite3_column_int64', //51 + 'sqlite3_column_text', //52 + 'sqlite3_column_text16', //53 + 'sqlite3_column_type', //54 + 'sqlite3_finalize', //55 + 'sqlite3_reset', //56 + 'sqlite3_create_function', //57 + 'sqlite3_create_function16', //58 + 'sqlite3_aggregate_count', //59 + 'sqlite3_value_blob', //60 + 'sqlite3_value_bytes', //61 + 'sqlite3_value_bytes16', //62 + 'sqlite3_value_double', //63 + 'sqlite3_value_int', //64 + 'sqlite3_value_int64', //65 + 'sqlite3_value_text', //66 + 'sqlite3_value_text16', //67 + 'sqlite3_value_text16le', //68 + 'sqlite3_value_text16be', //69 + 'sqlite3_value_type', //70 + 'sqlite3_aggregate_context', //71 + 'sqlite3_user_data', //72 + 'sqlite3_get_auxdata', //73 + 'sqlite3_set_auxdata', //74 + 'sqlite3_result_blob', //75 + 'sqlite3_result_double', //76 + 'sqlite3_result_error', //77 + 'sqlite3_result_error16', //78 + 'sqlite3_result_int', //79 + 'sqlite3_result_int64', //80 + 'sqlite3_result_null', //81 + 'sqlite3_result_text', //82 + 'sqlite3_result_text16', //83 + 'sqlite3_result_text16le', //84 + 'sqlite3_result_text16be', //85 + 'sqlite3_result_value', //86 + 'sqlite3_create_collation', //87 + 'sqlite3_create_collation16', //88 + 'sqlite3_collation_needed', //89 + 'sqlite3_collation_needed16', //90 + 'sqlite3_libversion', //91 + 'sqlite3_version', //92 + 'sqlite3_libversion_number', //93 + 'sqlite3_clear_bindings' //94 + ], + [ + @sqlite3_close, //0 + @sqlite3_exec, //1 + @sqlite3_last_insert_rowid, //2 + @sqlite3_changes, //3 + @sqlite3_total_changes, //4 + @sqlite3_interrupt, //5 + @sqlite3_complete, //6 + @sqlite3_complete16, //7 + @sqlite3_busy_handler, //8 + @sqlite3_busy_timeout, //9 + @sqlite3_get_table, //10 + @sqlite3_free_table, //11 + @sqlite3_mprintf, //12 + @sqlite3_free, //13 + @sqlite3_snprintf, //14 + @sqlite3_set_authorizer, //15 + @sqlite3_trace, //16 + @sqlite3_progress_handler, //17 + @sqlite3_commit_hook, //18 + @sqlite3_open, //19 + @sqlite3_open16, //20 + @sqlite3_errcode, //21 + @sqlite3_errmsg, //22 + @sqlite3_errmsg16, //23 + @sqlite3_prepare, //24 + @sqlite3_prepare16, //25 + @sqlite3_bind_blob, //26 + @sqlite3_bind_double, //27 + @sqlite3_bind_int, //28 + @sqlite3_bind_int64, //29 + @sqlite3_bind_null, //30 + @sqlite3_bind_text, //31 + @sqlite3_bind_text16, //32 + @sqlite3_bind_blob1, //33 + @sqlite3_bind_text1, //34 + @sqlite3_bind_text161, //35 + @sqlite3_bind_parameter_count, //36 + @sqlite3_bind_parameter_name, //37 + @sqlite3_bind_parameter_index, //38 + @sqlite3_column_count, //39 + @sqlite3_column_name, //40 + @sqlite3_column_name16, //41 + @sqlite3_column_decltype, //42 + @sqlite3_column_decltype16, //43 + @sqlite3_step, //44 + @sqlite3_data_count, //45 + @sqlite3_column_blob, //46 + @sqlite3_column_bytes, //47 + @sqlite3_column_bytes16, //48 + @sqlite3_column_double, //49 + @sqlite3_column_int, //50 + @sqlite3_column_int64, //51 + @sqlite3_column_text, //52 + @sqlite3_column_text16, //53 + @sqlite3_column_type, //54 + @sqlite3_finalize, //55 + @sqlite3_reset, //56 + @sqlite3_create_function, //57 + @sqlite3_create_function16, //58 + @sqlite3_aggregate_count, //59 + @sqlite3_value_blob, //60 + @sqlite3_value_bytes, //61 + @sqlite3_value_bytes16, //62 + @sqlite3_value_double, //63 + @sqlite3_value_int, //64 + @sqlite3_value_int64, //65 + @sqlite3_value_text, //66 + @sqlite3_value_text16, //67 + @sqlite3_value_text16le, //68 + @sqlite3_value_text16be, //69 + @sqlite3_value_type, //70 + @sqlite3_aggregate_context, //71 + @sqlite3_user_data, //72 + @sqlite3_get_auxdata, //73 + @sqlite3_set_auxdata, //74 + @sqlite3_result_blob, //75 + @sqlite3_result_double, //76 + @sqlite3_result_error, //77 + @sqlite3_result_error16, //78 + @sqlite3_result_int, //79 + @sqlite3_result_int64, //80 + @sqlite3_result_null, //81 + @sqlite3_result_text, //82 + @sqlite3_result_text16, //83 + @sqlite3_result_text16le, //84 + @sqlite3_result_text16be, //85 + @sqlite3_result_value, //86 + @sqlite3_create_collation, //87 + @sqlite3_create_collation16, //88 + @sqlite3_collation_needed, //89 + @sqlite3_collation_needed16, //90 + @sqlite3_libversion, //91 + @sqlite3_version, //92 + @sqlite3_libversion_number, //93 + @sqlite3_clear_bindings //94 + ]); + except + on e: exception do begin + e.message:= 'Library "'+mstr1+'": '+e.message; + result:= false; + if unloadlibrary(sqlite3libraryhandle) then begin + sqlite3libraryhandle:= nilhandle; + end; + raise; + end; + end; + end; + inc(refcount); + finally + sys_mutexunlock(liblock); + end; +end; +*) + +procedure initializesqlite3(const sonames: array of filenamety); +const + funcs: array[0..93] of funcinfoty = ( + (n: 'sqlite3_close'; d: {$ifndef FPC}@{$endif}@sqlite3_close), + (n: 'sqlite3_exec'; d: {$ifndef FPC}@{$endif}@sqlite3_exec), + (n: 'sqlite3_last_insert_rowid'; d: {$ifndef FPC}@{$endif}@sqlite3_last_insert_rowid), + (n: 'sqlite3_changes'; d: {$ifndef FPC}@{$endif}@sqlite3_changes), + (n: 'sqlite3_total_changes'; d: {$ifndef FPC}@{$endif}@sqlite3_total_changes), + (n: 'sqlite3_interrupt'; d: {$ifndef FPC}@{$endif}@sqlite3_interrupt), + (n: 'sqlite3_complete'; d: {$ifndef FPC}@{$endif}@sqlite3_complete), + (n: 'sqlite3_complete16'; d: {$ifndef FPC}@{$endif}@sqlite3_complete16), + (n: 'sqlite3_busy_handler'; d: {$ifndef FPC}@{$endif}@sqlite3_busy_handler), + (n: 'sqlite3_busy_timeout'; d: {$ifndef FPC}@{$endif}@sqlite3_busy_timeout), + (n: 'sqlite3_get_table'; d: {$ifndef FPC}@{$endif}@sqlite3_get_table), + (n: 'sqlite3_free_table'; d: {$ifndef FPC}@{$endif}@sqlite3_free_table), + (n: 'sqlite3_mprintf'; d: {$ifndef FPC}@{$endif}@sqlite3_mprintf), + (n: 'sqlite3_free'; d: {$ifndef FPC}@{$endif}@sqlite3_free), + (n: 'sqlite3_snprintf'; d: {$ifndef FPC}@{$endif}@sqlite3_snprintf), + (n: 'sqlite3_set_authorizer'; d: {$ifndef FPC}@{$endif}@sqlite3_set_authorizer), + (n: 'sqlite3_trace'; d: {$ifndef FPC}@{$endif}@sqlite3_trace), + (n: 'sqlite3_progress_handler'; d: {$ifndef FPC}@{$endif}@sqlite3_progress_handler), + (n: 'sqlite3_commit_hook'; d: {$ifndef FPC}@{$endif}@sqlite3_commit_hook), + (n: 'sqlite3_open'; d: {$ifndef FPC}@{$endif}@sqlite3_open), + (n: 'sqlite3_open16'; d: {$ifndef FPC}@{$endif}@sqlite3_open16), + (n: 'sqlite3_errcode'; d: {$ifndef FPC}@{$endif}@sqlite3_errcode), + (n: 'sqlite3_errmsg'; d: {$ifndef FPC}@{$endif}@sqlite3_errmsg), + (n: 'sqlite3_errmsg16'; d: {$ifndef FPC}@{$endif}@sqlite3_errmsg16), + (n: 'sqlite3_prepare'; d: {$ifndef FPC}@{$endif}@sqlite3_prepare), + (n: 'sqlite3_prepare16'; d: {$ifndef FPC}@{$endif}@sqlite3_prepare16), + (n: 'sqlite3_bind_blob'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_blob), + (n: 'sqlite3_bind_double'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_double), + (n: 'sqlite3_bind_int'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_int), + (n: 'sqlite3_bind_int64'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_int64), + (n: 'sqlite3_bind_null'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_null), + (n: 'sqlite3_bind_text'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_text), + (n: 'sqlite3_bind_text16'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_text16), + (n: 'sqlite3_bind_blob'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_blob), + (n: 'sqlite3_bind_text'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_text), + (n: 'sqlite3_bind_text16'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_text16), + (n: 'sqlite3_bind_parameter_count'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_parameter_count), + (n: 'sqlite3_bind_parameter_name'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_parameter_name), + (n: 'sqlite3_bind_parameter_index'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_parameter_index), + (n: 'sqlite3_column_count'; d: {$ifndef FPC}@{$endif}@sqlite3_column_count), + (n: 'sqlite3_column_name'; d: {$ifndef FPC}@{$endif}@sqlite3_column_name), + (n: 'sqlite3_column_name16'; d: {$ifndef FPC}@{$endif}@sqlite3_column_name16), + (n: 'sqlite3_column_decltype'; d: {$ifndef FPC}@{$endif}@sqlite3_column_decltype), + (n: 'sqlite3_column_decltype16'; d: {$ifndef FPC}@{$endif}@sqlite3_column_decltype16), + (n: 'sqlite3_step'; d: {$ifndef FPC}@{$endif}@sqlite3_step), + (n: 'sqlite3_data_count'; d: {$ifndef FPC}@{$endif}@sqlite3_data_count), + (n: 'sqlite3_column_blob'; d: {$ifndef FPC}@{$endif}@sqlite3_column_blob), + (n: 'sqlite3_column_bytes'; d: {$ifndef FPC}@{$endif}@sqlite3_column_bytes), + (n: 'sqlite3_column_bytes16'; d: {$ifndef FPC}@{$endif}@sqlite3_column_bytes16), + (n: 'sqlite3_column_double'; d: {$ifndef FPC}@{$endif}@sqlite3_column_double), + (n: 'sqlite3_column_int'; d: {$ifndef FPC}@{$endif}@sqlite3_column_int), + (n: 'sqlite3_column_int64'; d: {$ifndef FPC}@{$endif}@sqlite3_column_int64), + (n: 'sqlite3_column_text'; d: {$ifndef FPC}@{$endif}@sqlite3_column_text), + (n: 'sqlite3_column_text16'; d: {$ifndef FPC}@{$endif}@sqlite3_column_text16), + (n: 'sqlite3_column_type'; d: {$ifndef FPC}@{$endif}@sqlite3_column_type), + (n: 'sqlite3_finalize'; d: {$ifndef FPC}@{$endif}@sqlite3_finalize), + (n: 'sqlite3_reset'; d: {$ifndef FPC}@{$endif}@sqlite3_reset), + (n: 'sqlite3_create_function'; d: {$ifndef FPC}@{$endif}@sqlite3_create_function), + (n: 'sqlite3_create_function16'; d: {$ifndef FPC}@{$endif}@sqlite3_create_function16), + (n: 'sqlite3_aggregate_count'; d: {$ifndef FPC}@{$endif}@sqlite3_aggregate_count), + (n: 'sqlite3_value_blob'; d: {$ifndef FPC}@{$endif}@sqlite3_value_blob), + (n: 'sqlite3_value_bytes'; d: {$ifndef FPC}@{$endif}@sqlite3_value_bytes), + (n: 'sqlite3_value_bytes16'; d: {$ifndef FPC}@{$endif}@sqlite3_value_bytes16), + (n: 'sqlite3_value_double'; d: {$ifndef FPC}@{$endif}@sqlite3_value_double), + (n: 'sqlite3_value_int'; d: {$ifndef FPC}@{$endif}@sqlite3_value_int), + (n: 'sqlite3_value_int64'; d: {$ifndef FPC}@{$endif}@sqlite3_value_int64), + (n: 'sqlite3_value_text'; d: {$ifndef FPC}@{$endif}@sqlite3_value_text), + (n: 'sqlite3_value_text16'; d: {$ifndef FPC}@{$endif}@sqlite3_value_text16), + (n: 'sqlite3_value_text16le'; d: {$ifndef FPC}@{$endif}@sqlite3_value_text16le), + (n: 'sqlite3_value_text16be'; d: {$ifndef FPC}@{$endif}@sqlite3_value_text16be), + (n: 'sqlite3_value_type'; d: {$ifndef FPC}@{$endif}@sqlite3_value_type), + (n: 'sqlite3_aggregate_context'; d: {$ifndef FPC}@{$endif}@sqlite3_aggregate_context), + (n: 'sqlite3_user_data'; d: {$ifndef FPC}@{$endif}@sqlite3_user_data), + (n: 'sqlite3_get_auxdata'; d: {$ifndef FPC}@{$endif}@sqlite3_get_auxdata), + (n: 'sqlite3_set_auxdata'; d: {$ifndef FPC}@{$endif}@sqlite3_set_auxdata), + (n: 'sqlite3_result_blob'; d: {$ifndef FPC}@{$endif}@sqlite3_result_blob), + (n: 'sqlite3_result_double'; d: {$ifndef FPC}@{$endif}@sqlite3_result_double), + (n: 'sqlite3_result_error'; d: {$ifndef FPC}@{$endif}@sqlite3_result_error), + (n: 'sqlite3_result_error16'; d: {$ifndef FPC}@{$endif}@sqlite3_result_error16), + (n: 'sqlite3_result_int'; d: {$ifndef FPC}@{$endif}@sqlite3_result_int), + (n: 'sqlite3_result_int64'; d: {$ifndef FPC}@{$endif}@sqlite3_result_int64), + (n: 'sqlite3_result_null'; d: {$ifndef FPC}@{$endif}@sqlite3_result_null), + (n: 'sqlite3_result_text'; d: {$ifndef FPC}@{$endif}@sqlite3_result_text), + (n: 'sqlite3_result_text16'; d: {$ifndef FPC}@{$endif}@sqlite3_result_text16), + (n: 'sqlite3_result_text16le'; d: {$ifndef FPC}@{$endif}@sqlite3_result_text16le), + (n: 'sqlite3_result_text16be'; d: {$ifndef FPC}@{$endif}@sqlite3_result_text16be), + (n: 'sqlite3_result_value'; d: {$ifndef FPC}@{$endif}@sqlite3_result_value), + (n: 'sqlite3_create_collation'; d: {$ifndef FPC}@{$endif}@sqlite3_create_collation), + (n: 'sqlite3_create_collation16'; d: {$ifndef FPC}@{$endif}@sqlite3_create_collation16), + (n: 'sqlite3_collation_needed'; d: {$ifndef FPC}@{$endif}@sqlite3_collation_needed), + (n: 'sqlite3_collation_needed16'; d: {$ifndef FPC}@{$endif}@sqlite3_collation_needed16), + (n: 'sqlite3_libversion'; d: {$ifndef FPC}@{$endif}@sqlite3_libversion), +// (n: 'sqlite3_version'; d: {$ifndef FPC}@{$endif}@sqlite3_version), + (n: 'sqlite3_libversion_number'; d: {$ifndef FPC}@{$endif}@sqlite3_libversion_number), + (n: 'sqlite3_clear_bindings'; d: {$ifndef FPC}@{$endif}@sqlite3_clear_bindings) + ); + errormessage = 'Can not load Sqlite3 library. '; +begin + initializedynlib(libinfo,sonames,sqlite3lib,funcs,[],errormessage); +end; + +procedure releasesqlite3; +begin + releasedynlib(libinfo); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +{$else} +procedure initialisesqlite3; +begin + //dummy +end; + +procedure releasesqlite3; +begin + //dummy +end; + +{$endif} //mse_sqlite3static +end. diff --git a/mseide-msegui/lib/common/designutils/msecomponenteditors.pas b/mseide-msegui/lib/common/designutils/msecomponenteditors.pas new file mode 100644 index 0000000..4cbed04 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msecomponenteditors.pas @@ -0,0 +1,172 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msecomponenteditors; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,msedesignintf,mseglob,mseguiglob,mseclasses,mselist,msetypes; + +type + + componentinfoty = record + name: string; + instance: tcomponent; + end; + pcomponentinfoty = ^componentinfoty; + + tcomponenteditor = class(tnullinterfacedobject,icomponenteditor) + protected + fcomponent: tcomponent; + fstate: componenteditorstatesty; + fdesigner: idesigner; + public + constructor create(const adesigner: idesigner; acomponent: tcomponent); virtual; + function state: componenteditorstatesty; + procedure edit; virtual; + property component: tcomponent read fcomponent; + end; + + componenteditorclassty = class of tcomponenteditor; + + timagelisteditor = class(tcomponenteditor) + public + constructor create(const adesigner: idesigner; + acomponent: tcomponent); override; + procedure edit; override; + end; + + componenteditorinfoty = record + componentclass: componentclassty; + componenteditorclass: componenteditorclassty; + end; + pcomponenteditorinfoty = ^componenteditorinfoty; + + tcomponenteditors = class(trecordlist) + protected + procedure add(componentclass: componentclassty; componenteditorclass: componenteditorclassty); + public + constructor create; + function geteditorclass(const component: componentclassty): componenteditorclassty; + end; + +function componenteditors: tcomponenteditors; +procedure registercomponenteditor(componentclass: componentclassty; + componenteditorclass: componenteditorclassty); + +implementation +uses + msegui,mseimagelisteditor,msebitmap,SysUtils; + +var + acomponenteditors: tcomponenteditors; + +function componenteditors: tcomponenteditors; +begin + if acomponenteditors = nil then begin + acomponenteditors:= tcomponenteditors.create; + end; + result:= acomponenteditors; +end; + +procedure registercomponenteditor(componentclass: componentclassty; + componenteditorclass: componenteditorclassty); +begin + componenteditors.add(componentclass,componenteditorclass) +end; + + +{ tcomponenteditors } + +procedure tcomponenteditors.add(componentclass: componentclassty; + componenteditorclass: componenteditorclassty); +var + info: componenteditorinfoty; +begin + fillchar(info,sizeof(info),0); + info.componentclass:= componentclass; + info.componenteditorclass:= componenteditorclass; + inherited add(info); +end; + +constructor tcomponenteditors.create; +begin + inherited create(sizeof(componentinfoty)); +end; + +function tcomponenteditors.geteditorclass( + const component: componentclassty): componenteditorclassty; +var + level: integer; + int1: integer; + int2: integer; + po1: pcomponenteditorinfoty; + class1: tclass; +begin + result:= nil; + level:= bigint; + po1:= pcomponenteditorinfoty(fdata); + for int1:= 0 to count - 1 do begin + with po1^ do begin + class1:= component; + int2:= 0; + while (class1 <> componentclass) and (class1 <> nil) do begin + inc(int2); + class1:= class1.ClassParent; + end; + if (class1 <> nil) and (int2 < level) then begin + level:= int2; + result:= componenteditorclass; + end; + end; + inc(po1); + end; +end; + +{ tcomponenteditor } + +constructor tcomponenteditor.create(const adesigner: idesigner; acomponent: tcomponent); +begin + fdesigner:= adesigner; + fcomponent:= acomponent; +end; + +function tcomponenteditor.state: componenteditorstatesty; +begin + result:= fstate; +end; + +procedure tcomponenteditor.edit; +begin + //dummy +end; + +{ timagelisteditor } + +constructor timagelisteditor.create(const adesigner: idesigner; + acomponent: tcomponent); +begin + inherited; + fstate:= fstate + [cs_canedit]; +end; + +procedure timagelisteditor.edit; +begin + if editimagelist(timagelist(fcomponent)) = mr_ok then begin + fdesigner.componentmodified(fcomponent); + end; +end; + +initialization + acomponenteditors:= tcomponenteditors.Create; +finalization + freeandnil(acomponenteditors); +end. diff --git a/mseide-msegui/lib/common/designutils/msecornermaskeditor.mfm b/mseide-msegui/lib/common/designutils/msecornermaskeditor.mfm new file mode 100644 index 0000000..176cbd1 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msecornermaskeditor.mfm @@ -0,0 +1,130 @@ +object msecornermaskeditorfo: tmsecornermaskeditorfo + visible = False + bounds_x = 337 + bounds_y = 266 + bounds_cx = 383 + bounds_cy = 334 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 383 + 334 + ) + options = [fo_freeonclose, fo_createmodal, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = statfile1 + caption = 'Cornermask Editor' + oncreate = createexe + onclosequery = closequexe + moduleclassname = 'tmseform' + object tsplitter1: tsplitter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + bounds_x = 258 + bounds_y = 293 + bounds_cx = 123 + bounds_cy = 32 + anchors = [an_right, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = grid + grip = stb_none + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 58 + bounds_y = 10 + bounds_cx = 52 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 0 + bounds_y = 10 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object tspacer2: tspacer + taborder = 2 + bounds_x = 50 + bounds_y = 10 + bounds_cx = 8 + bounds_cy = 20 + linkleft = tbutton1 + linkright = tbutton2 + options = [spao_glueright] + end + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 383 + bounds_cy = 293 + anchors = [an_top] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 1 + captions.items = < + item + caption = 'Width' + end> + captionsfix.count = 1 + captionsfix.items = < + item + caption = 'Row' + end> + end> + datacols.count = 1 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[maskwidthed] + width = 77 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow, co_rowdatachange] + name = 'index' + widgetname = 'maskwidthed' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + reffontheight = 14 + object maskwidthed: tintegeredit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 77 + bounds_cy = 16 + max = 524287 + reffontheight = 14 + end + end + object statfile1: tstatfile + filename = 'cornermask.sta' + options = [sfo_memory, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + left = 80 + top = 112 + end +end diff --git a/mseide-msegui/lib/common/designutils/msecornermaskeditor.pas b/mseide-msegui/lib/common/designutils/msecornermaskeditor.pas new file mode 100644 index 0000000..54036a5 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msecornermaskeditor.pas @@ -0,0 +1,80 @@ +unit msecornermaskeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msesplitter, + msesimplewidgets,msedataedits,mseedit,mseificomp,mseificompglob,mseifiglob, + msestatfile,msestream,msestrings,sysutils,msegrids,msewidgetgrid,msegraphedits, + msescrollbar,msebitmap; +type + tmsecornermaskeditorfo = class(tmseform) + tsplitter1: tsplitter; + tbutton2: tbutton; + tbutton1: tbutton; + tspacer2: tspacer; + grid: twidgetgrid; + maskwidthed: tintegeredit; + statfile1: tstatfile; + procedure createexe(const sender: TObject); + procedure closequexe(const sender: tcustommseform; + var amodalresult: modalresultty); + protected + findexlist: pmsestring; + fok: pboolean; + public + constructor create(var indexlist: msestring; out ok: boolean); + end; + +function editcornermask(var indexlist: msestring): boolean; + +implementation +uses + msecornermaskeditor_mfm; + +function editcornermask(var indexlist: msestring): boolean; +begin + tmsecornermaskeditorfo.create(indexlist,result); +end; + +{ tmsecornermaskeditorfo } + +constructor tmsecornermaskeditorfo.create(var indexlist: msestring; + out ok: boolean); +begin + findexlist:= @indexlist; + fok:= @ok; + inherited create(nil); +end; + +procedure tmsecornermaskeditorfo.createexe(const sender: TObject); +var + i1: int32; + po1: pint16; +begin + grid.beginupdate(); + grid.rowcount:= length(findexlist^); + po1:= pointer(findexlist^); + for i1:= 0 to grid.rowhigh do begin + maskwidthed[i1]:= po1[i1]; + end; + grid.endupdate(); +end; + +procedure tmsecornermaskeditorfo.closequexe(const sender: tcustommseform; + var amodalresult: modalresultty); +var + i1: int32; + po1: pint16; +begin + fok^:= amodalresult = mr_ok; + if fok^ then begin + setlength(findexlist^,grid.rowcount); + po1:= pointer(findexlist^); + for i1:= 0 to grid.rowhigh do begin + po1[i1]:= maskwidthed[i1]; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msecornermaskeditor_mfm.pas b/mseide-msegui/lib/common/designutils/msecornermaskeditor_mfm.pas new file mode 100644 index 0000000..0d4d34a --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msecornermaskeditor_mfm.pas @@ -0,0 +1,153 @@ +unit msecornermaskeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msecornermaskeditor; + +const + objdata: record size: integer; data: array[0..2718] of byte end = + (size: 2719; data: ( + 84,80,70,48,22,116,109,115,101,99,111,114,110,101,114,109,97,115,107,101, + 100,105,116,111,114,102,111,21,109,115,101,99,111,114,110,101,114,109,97,115, + 107,101,100,105,116,111,114,102,111,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,81,1,8,98,111,117,110,100,115,95,121,3, + 10,1,9,98,111,117,110,100,115,95,99,120,3,127,1,9,98,111,117,110, + 100,115,95,99,121,3,78,1,26,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111, + 117,110,100,115,1,2,0,2,0,3,127,1,3,78,1,0,7,111,112,116, + 105,111,110,115,11,14,102,111,95,102,114,101,101,111,110,99,108,111,115,101, + 14,102,111,95,99,114,101,97,116,101,109,111,100,97,108,13,102,111,95,99, + 108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97, + 100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116, + 97,116,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118, + 101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101, + 0,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101, + 49,7,99,97,112,116,105,111,110,6,17,67,111,114,110,101,114,109,97,115, + 107,32,69,100,105,116,111,114,8,111,110,99,114,101,97,116,101,7,9,99, + 114,101,97,116,101,101,120,101,12,111,110,99,108,111,115,101,113,117,101,114, + 121,7,10,99,108,111,115,101,113,117,101,120,101,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0, + 9,116,115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116,101,114, + 49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,8,98,111,117,110, + 100,115,95,120,3,2,1,8,98,111,117,110,100,115,95,121,3,37,1,9, + 98,111,117,110,100,115,95,99,120,2,123,9,98,111,117,110,100,115,95,99, + 121,2,32,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104, + 116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115, + 115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111, + 115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110, + 100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,7,108,105,110,107, + 116,111,112,7,4,103,114,105,100,4,103,114,105,112,7,8,115,116,98,95, + 110,111,110,101,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111, + 110,50,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111, + 119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116, + 111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,58,8,98,111,117,110,100,115,95,121,2,10, + 9,98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95, + 99,121,2,22,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38, + 67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9, + 109,114,95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116, + 116,111,110,49,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97, + 117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,10,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,12,98,111,117,110, + 100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97, + 116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75, + 11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,115, + 112,97,99,101,114,8,116,115,112,97,99,101,114,50,8,116,97,98,111,114, + 100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,50,8,98,111,117, + 110,100,115,95,121,2,10,9,98,111,117,110,100,115,95,99,120,2,8,9, + 98,111,117,110,100,115,95,99,121,2,20,8,108,105,110,107,108,101,102,116, + 7,8,116,98,117,116,116,111,110,49,9,108,105,110,107,114,105,103,104,116, + 7,8,116,98,117,116,116,111,110,50,7,111,112,116,105,111,110,115,11,14, + 115,112,97,111,95,103,108,117,101,114,105,103,104,116,0,0,0,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,127,1, + 9,98,111,117,110,100,115,95,99,121,3,37,1,7,97,110,99,104,111,114, + 115,11,6,97,110,95,116,111,112,0,11,111,112,116,105,111,110,115,103,114, + 105,100,11,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95, + 107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105, + 110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116, + 105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119,115,100, + 101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108, + 111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116, + 114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103, + 95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108, + 0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105, + 120,99,111,108,115,46,105,116,101,109,115,14,1,7,110,117,109,115,116,101, + 112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,1,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,5,87,105,100,116,104,0,0,17,99,97, + 112,116,105,111,110,115,102,105,120,46,99,111,117,110,116,2,1,17,99,97, + 112,116,105,111,110,115,102,105,120,46,105,116,101,109,115,14,1,7,99,97, + 112,116,105,111,110,6,3,82,111,119,0,0,0,0,14,100,97,116,97,99, + 111,108,115,46,99,111,117,110,116,2,1,16,100,97,116,97,99,111,108,115, + 46,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118, + 101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115, + 14,7,11,109,97,115,107,119,105,100,116,104,101,100,1,5,119,105,100,116, + 104,2,77,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,16,99,111,95,114,111,119,100,97,116, + 97,99,104,97,110,103,101,0,4,110,97,109,101,6,5,105,110,100,101,120, + 10,119,105,100,103,101,116,110,97,109,101,6,11,109,97,115,107,119,105,100, + 116,104,101,100,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105, + 100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,0,13,100, + 97,116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,11,109,97,115,107,119,105,100,116,104,101,100,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,77,9,98,111,117,110,100,115,95,99,121,2,16,3,109,97,120, + 4,255,255,7,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,0,9,116,115,116,97,116,102,105,108,101,9,115,116,97,116,102, + 105,108,101,49,8,102,105,108,101,110,97,109,101,6,14,99,111,114,110,101, + 114,109,97,115,107,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115, + 102,111,95,109,101,109,111,114,121,15,115,102,111,95,116,114,97,110,115,97, + 99,116,105,111,110,17,115,102,111,95,97,99,116,105,118,97,116,111,114,114, + 101,97,100,18,115,102,111,95,97,99,116,105,118,97,116,111,114,119,114,105, + 116,101,0,4,108,101,102,116,2,80,3,116,111,112,2,112,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsecornermaskeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msedbfieldeditor.mfm b/mseide-msegui/lib/common/designutils/msedbfieldeditor.mfm new file mode 100644 index 0000000..461bf15 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedbfieldeditor.mfm @@ -0,0 +1,333 @@ +object msedbfieldeditorfo: tmsedbfieldeditorfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 29 + bounds_y = 248 + bounds_cx = 601 + bounds_cy = 216 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + container.frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + container.bounds = ( + 0 + 0 + 601 + 216 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + oneventloopstart = formloaded + moduleclassname = 'tmseform' + object tbutton1: tbutton + taborder = 3 + bounds_x = 472 + bounds_y = 184 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object tbutton2: tbutton + bounds_x = 536 + bounds_y = 184 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object fielddefli: tstringgrid + frame.caption = 'Fielddefs' + frame.captionpos = cp_top + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 336 + bounds_y = 7 + bounds_cx = 258 + bounds_cy = 171 + bounds_cxmin = 50 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup] + datacols.count = 2 + datacols.options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + datacols.items = < + item + width = 123 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate] + optionsedit = [scoe_eatreturn] + valuefalse = '0' + valuetrue = '1' + end + item + width = 129 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate] + optionsedit = [scoe_eatreturn] + valuefalse = '0' + valuetrue = '1' + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Type' + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612732 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datarowheight = 16 + oncellevent = defscellevent + onselectionchanged = defsselectioncha + reffontheight = 14 + end + object fields: twidgetgrid + frame.caption = 'Fields' + frame.captionpos = cp_top + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 7 + bounds_cx = 323 + bounds_cy = 171 + anchors = [an_left, an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_sorted, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 15 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 5 + captions.items = < + item + end + item + end + item + caption = 'Name' + end + item + caption = 'Class type' + end + item + caption = 'Field kind' + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612732 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datacols.count = 5 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + datacols.items = < + item[index] + width = 13 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate] + widgetname = 'index' + dataclass = tgridintegerdatalist + end + item[fieldpo] + width = 12 + options = [co_invisible, co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + widgetname = 'fieldpo' + dataclass = tgridpointerdatalist + end + item[fieldname] + width = 97 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate] + widgetname = 'fieldname' + dataclass = tgridmsestringdatalist + end + item[classty] + width = 92 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate] + widgetname = 'classty' + dataclass = tgridenumdatalist + end + item[fieldkind] + width = 84 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate] + widgetname = 'fieldkind' + dataclass = tgridenumdatalist + end> + datarowheight = 16 + onrowsdeleting = fieldrowsdeleting + onrowsdeleted = fieldsrowdel + oncellevent = fieldcellevent + onselectionchanged = fieldselectioncha + onsort = fieldsort + reffontheight = 14 + object index: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_noskin] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 13 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + object fieldpo: tpointeredit + optionsskin = [osk_noskin] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cx = 12 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object fieldname: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 27 + bounds_y = 0 + bounds_cx = 97 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = fieldsdataentered + onsetvalue = fieldnamesetvalue + reffontheight = 14 + end + object classty: tenumtypeedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -1879048187 + taborder = 4 + visible = False + bounds_x = 125 + bounds_y = 0 + bounds_cx = 92 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_notnull] + valuedefault = 0 + min = 0 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = initcla + reffontheight = 14 + end + object fieldkind: tenumtypeedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.width = 15 + frame.button.color = -1879048187 + taborder = 5 + visible = False + bounds_x = 218 + bounds_y = 0 + bounds_cx = 84 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_notnull] + valuedefault = 0 + min = 0 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = initfieldkind + reffontheight = 14 + end + end + object splitter: tsplitter + color = -1879048189 + taborder = 6 + bounds_x = 331 + bounds_y = 24 + bounds_cx = 5 + bounds_cy = 154 + anchors = [an_left, an_top, an_bottom] + options = [spo_hmove, spo_hprop] + linkleft = fields + linkright = fielddefli + statfile = tstatfile1 + onupdatelayout = splitterupda + end + object deftofield: tstockglyphbutton + optionswidget = [ow_destroywidgets] + taborder = 5 + bounds_x = 338 + bounds_y = 5 + bounds_cx = 28 + bounds_cy = 15 + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowleft + onexecute = transferfields + end + object fieldtodef: tstockglyphbutton + optionswidget = [ow_destroywidgets] + taborder = 4 + bounds_x = 303 + bounds_y = 5 + bounds_cx = 28 + bounds_cy = 15 + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowright + onexecute = deletefields + end + object tstatfile1: tstatfile + filename = 'dbfieldeditor.sta' + options = [sfo_memory] + left = 24 + top = 152 + end + object c: tstringcontainer + strings.data = ( + 'Dataset' + ) + left = 152 + top = 152 + end +end diff --git a/mseide-msegui/lib/common/designutils/msedbfieldeditor.pas b/mseide-msegui/lib/common/designutils/msedbfieldeditor.pas new file mode 100644 index 0000000..1cb6795 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedbfieldeditor.pas @@ -0,0 +1,457 @@ +{ MSEide Copyright (c) 1999-2011 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msedbfieldeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mdb,msegui,mseclasses,mseforms,msedb,msestat,msestatfile,msesimplewidgets, + msegrids,msewidgetgrid,msesplitter,msedataedits,msetypes{msestrings},mseeditglob, + msegraphedits,mseglob,msegridsglob,msestringcontainer; + +const + dbfieldeditorstatname = 'dbfieldeditor.sta'; +type + tmsedbfieldeditorfo = class(tmseform) + tbutton1: tbutton; + tbutton2: tbutton; + index: tintegeredit; + fieldkind: tenumtypeedit; + splitter: tsplitter; + fieldpo: tpointeredit; + classty: tenumtypeedit; + tstatfile1: tstatfile; + fielddefli: tstringgrid; + fields: twidgetgrid; + fieldname: tstringedit; + deftofield: tstockglyphbutton; + fieldtodef: tstockglyphbutton; + c: tstringcontainer; + procedure formloaded(const sender: TObject); + procedure initcla(const sender: tenumtypeedit); + procedure splitterupda(const sender: TObject); + procedure defscellevent(const sender: TObject; var info: celleventinfoty); + procedure defsselectioncha(const sender: TObject); + procedure fieldnamesetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure fieldsdataentered(const sender: TObject); + procedure fieldsrowdel(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); + procedure transferfields(const sender: TObject); + procedure fieldrowsdeleting(const sender: tcustomgrid; var aindex: Integer; + var acount: Integer); + procedure initfieldkind(const sender: tenumtypeedit); + procedure fieldcellevent(const sender: TObject; var info: celleventinfoty); + procedure fieldselectioncha(const sender: TObject); + procedure deletefields(const sender: TObject); + procedure fieldsort(const sender: tcustomgrid; const index1: Integer; + const index2: Integer; var aresult: Integer); + private + ffields: tpersistentfields; + procedure checkfielddefs; + function findfielddef(aname: msestring): integer; + public + constructor create(const afields: tpersistentfields); reintroduce; + end; + +function editpersistentfields(const instance: tpersistentfields): boolean; + +implementation +uses + mseguiglob,msedbfieldeditor_mfm,typinfo,msewidgets,msestrings; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tpersistentfields1 = class(tpersistentfields); + stringconststy = ( + str_dataset //0 Dataset + ); + +function editpersistentfields(const instance: tpersistentfields): boolean; +var + fo: tmsedbfieldeditorfo; + int1,int2: integer; + ct1: fieldclassty; + ar1: fieldarty; + activebefore: boolean; +begin + result:= false; + fo:= tmsedbfieldeditorfo.create(instance); + try + with fo,tpersistentfields1(instance) do begin + activebefore:= dataset.active; + dataset.active:= false; + for int1:= 0 to count - 1 do begin + items[int1].dataset:= nil; + end; + try + if show(true) = mr_ok then begin + fo.window.nofocus; //remove empty last line + result:= true; + setlength(ar1,fields.rowcount-dataset.fields.count); + for int1:= 0 to high(ar1) do begin + ct1:= getmsefieldclass(fieldclasstypety(classty[int1])); +// ct1:= msefieldtypeclasses[fieldclasstypety(classty[int1])]; + int2:= index[int1]; + if int2 > 0 then begin + dec(int2); + if ct1 <> items[int2].classtype then begin + ar1[int1]:= ct1.create(nil); + ar1[int1].dataset:= dataset; + end + else begin + ar1[int1]:= items[int2]; + fitems[int2]:= nil; + end; + end + else begin + if fieldpo[int1] <> nil then begin + ar1[int1]:= tfield(fieldpo[int1]); + fieldpo[int1]:= nil; + end + else begin + ar1[int1]:= ct1.create(nil); + try + ar1[int1].dataset:= dataset; + except + application.handleexception(nil); + end; + end; + end; + try + ar1[int1].fieldname:= ansistring(fieldname[int1]); + except + application.handleexception(nil); + end; + ar1[int1].fieldkind:= tfieldkind(fieldkind[int1]); + end; + for int1:= 0 to count - 1 do begin + items[int1].free; + end; + for int1:= 0 to high(ar1) do begin + tfield(fieldpo[int1]).free; + end; + fitems:= persistentarty(ar1); + end; + finally + for int1:= 0 to count - 1 do begin + items[int1].dataset:= dataset; + end; + if result then begin + for int1:= 0 to high(ar1) do begin + items[int1].index:= int1; + end; + for int1:= length(ar1) to fields.rowhigh do begin + tfield(fieldpo[int1]).index:= int1; + end; + end; + if activebefore then begin + try + dataset.active:= true; + except + application.handleexception(dataset); + end; + end; + end; + end; + finally + fo.free; + end; +end; + +{ tmsedbfieldeditorfo } + +constructor tmsedbfieldeditorfo.create(const afields: tpersistentfields); +begin + ffields:= afields; + inherited create(nil); +end; + +procedure tmsedbfieldeditorfo.formloaded(const sender: TObject); +var + int1: integer; + field1: tfield; +begin + with ffields.dataset do begin + caption:= c[ord(str_dataset)]+': ' + msestring(name); + fielddefli.rowcount:= fielddefs.count; + for int1:= 0 to fielddefs.count-1 do begin + fielddefli[0][int1]:= msestring(fielddefs[int1].name); + fielddefli[1][int1]:= msestring(getenumname(typeinfo(tfieldtype), + ord(fielddefs[int1].datatype))); + end; + end; + fields.rowcount:= ffields.count + ffields.dataset.fields.count; + for int1:= 0 to ffields.count - 1 do begin + index[int1]:= int1+1; + fieldname[int1]:= msestring(ffields[int1].fieldname); + classty[int1]:= ord(fieldclasstoclasstyp(fieldclassty(ffields[int1].classtype))); + fieldkind[int1]:= ord(ffields[int1].fieldkind); + end; + for int1:= ffields.count to fields.rowhigh do begin + index[int1]:= int1+1; + field1:= ffields.dataset.fields[int1-ffields.count]; + fieldpo[int1]:= field1; + with field1 do begin + self.fieldname[int1]:= msestring(fieldname); + classty[int1]:= ord(fieldclasstoclasstyp(fieldclassty(classtype))); + self.fieldkind[int1]:= ord(fieldkind); + end; + fields.rowfontstate[int1]:= 0; + end; + checkfielddefs; +end; + +procedure tmsedbfieldeditorfo.initcla(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(fieldclasstypety); +end; + +procedure tmsedbfieldeditorfo.initfieldkind(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(tfieldkind); +end; + +procedure tmsedbfieldeditorfo.splitterupda(const sender: TObject); +begin + deftofield.left:= splitter.left+splitter.bounds_cx; + fieldtodef.left:= splitter.left-fieldtodef.bounds_cx; +// alignx(wam_center,[splitter,deftofield]); +end; + +procedure tmsedbfieldeditorfo.defscellevent(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if (eventkind = cek_select) and selected and + (fielddefli.rowfontstate[cell.row] <> -1) then begin + accept:= false; + end; + end; +end; + +procedure tmsedbfieldeditorfo.defsselectioncha(const sender: TObject); +begin + deftofield.enabled:= fielddefli.datacols.hasselection; +end; + +procedure tmsedbfieldeditorfo.fieldnamesetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var + mstr1: msestring; + int1: integer; +begin + mstr1:= mseuppercase(avalue); + for int1:= 0 to fields.rowcount-1 do begin + if (int1 <> fields.row) and (mstr1 = mseuppercase(fieldname[int1])) then begin + showerror('Field name exists.'); + accept:= false; + break; + end; + end; +end; + +procedure tmsedbfieldeditorfo.checkfielddefs; +var + int1,int2: integer; + ar1: msestringarty; + mstr1: msestring; +begin + setlength(ar1,fields.rowcount); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= mseuppercase(fieldname[int1]); + end; + for int1:= 0 to fielddefli.rowcount - 1 do begin + mstr1:= mseuppercase(fielddefli[0][int1]); + fielddefli.rowfontstate[int1]:= -1; + for int2:= 0 to high(ar1) do begin + if mstr1 = ar1[int2] then begin + fielddefli.rowfontstate[int1]:= 0; + fielddefli.datacols.selected[makegridcoord(-1,int1)]:= false; + break; + end; + end; + end; +end; + +procedure tmsedbfieldeditorfo.fieldsdataentered(const sender: TObject); +begin + checkfielddefs; +end; + +procedure tmsedbfieldeditorfo.fieldsrowdel(const sender: tcustomgrid; + const aindex: Integer; const acount: Integer); +begin + checkfielddefs; +end; + +procedure tmsedbfieldeditorfo.transferfields(const sender: TObject); +var + int1,int2: integer; + ar1,ar2: integerarty; +begin + ar1:= fielddefli.datacols.selectedrows; + if high(ar1) >= 0 then begin + setlength(ar2,length(ar1)); + int2:= 0; + fields.beginupdate; + for int1:= 0 to high(ar1) do begin + fields.appendrow(true); + try + fields.row:= fields.rowhigh; + fieldpo[fields.rowhigh]:= + ffields.dataset.fielddefs[ar1[int1]].createfield(nil); + tfield(fieldpo[fields.rowhigh]).dataset:= nil; + fieldname[fields.rowhigh]:= fielddefli[0][ar1[int1]]; + classty[fields.rowhigh]:= ord(fieldclasstoclasstyp( + ffields.dataset.fielddefs[ar1[int1]].fieldclass)); + fieldkind[fields.rowhigh]:= ord(tfield(fieldpo[fields.rowhigh]).fieldkind); + ar2[int2]:= fields.rowhigh; + inc(int2); + except + fields.rowcount:= fields.rowcount - 1; + application.handleexception(nil); + end; + fielddefli.datacols.clearselection; + end; + setlength(ar2,int2); + fields.datacols.selectedrows:= ar2; + fields.endupdate; + // fields.sort; + checkfielddefs; + for int1:= ar1[high(ar1)] + 1 to fielddefli.rowhigh do begin + if fielddefli.rowfontstate[int1] = -1 then begin + fielddefli.row:= int1; + exit; + end; + end; + for int1:= 0 to fielddefli.rowhigh do begin + if fielddefli.rowfontstate[int1] = -1 then begin + fielddefli.row:= int1; + exit; + end; + end; + end; +end; + +procedure tmsedbfieldeditorfo.fieldrowsdeleting(const sender: tcustomgrid; + var aindex: Integer; var acount: Integer); +var + int1: integer; +begin + for int1:= aindex to aindex + acount - 1 do begin + if sender.rowfontstate[int1] <> -1 then begin + acount:= 0; + break; + end; + end; + for int1:= aindex to aindex + acount - 1 do begin + tfield(fieldpo[int1]).free; + end; +end; + +procedure tmsedbfieldeditorfo.fieldsort(const sender: tcustomgrid; + const index1: Integer; const index2: Integer; + var aresult: Integer); +begin + aresult:= fields.rowfontstate[index1] - fields.rowfontstate[index2]; +end; + +procedure tmsedbfieldeditorfo.fieldcellevent(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if eventkind = cek_enter then begin + if fields.rowfontstate[cell.row] = -1 then begin + fields.datacols.options:= fields.datacols.options - [co_readonly]; + fields.optionsgrid:= fields.optionsgrid + [og_rowdeleting]; + end + else begin + fields.datacols.options:= fields.datacols.options + [co_readonly]; + fields.optionsgrid:= fields.optionsgrid - [og_rowdeleting]; + end; + end; + if (eventkind = cek_select) and selected then begin + if fields.rowfontstate[cell.row] <> -1 then begin + accept:= false; + end; + end; + end; +end; + +procedure tmsedbfieldeditorfo.fieldselectioncha(const sender: TObject); +begin + fieldtodef.enabled:= fields.datacols.hasselection and + (length(fields.datacols.selectedrows) > 0); +end; + +function tmsedbfieldeditorfo.findfielddef(aname: msestring): integer; +var + int1: integer; +begin + result:= invalidaxis; + aname:= struppercase(aname); + for int1:= 0 to fielddefli.rowhigh do begin + if msestringicompupper(fielddefli[0][int1],aname) = 0 then begin + result:= int1; + break; + end; + end; +end; + +procedure tmsedbfieldeditorfo.deletefields(const sender: TObject); +var + ar1,ar2: integerarty; + int1: integer; + int2: integer; +begin + ar1:= fields.datacols.selectedrows; + setlength(ar2,length(ar1)); //max + int2:= 0; + for int1:= high(ar1) downto 0 do begin + ar2[int2]:= findfielddef(fieldname[ar1[int1]]); + if ar2[int2] >= 0 then begin + inc(int2); + end; + end; + ffields.beginupdate; + for int1:= high(ar1) downto 0 do begin + fields.deleterow(ar1[int1]); + end; + ffields.endupdate; + if int2 > 0 then begin + setlength(ar2,int2); + fielddefli.row:= ar2[high(ar2)]; + fielddefli.datacols.selectedrows:= ar2; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msedbfieldeditor_mfm.pas b/mseide-msegui/lib/common/designutils/msedbfieldeditor_mfm.pas new file mode 100644 index 0000000..504cf97 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedbfieldeditor_mfm.pas @@ -0,0 +1,435 @@ +unit msedbfieldeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msedbfieldeditor; + +const + objdata: record size: integer; data: array[0..8359] of byte end = + (size: 8360; data: ( + 84,80,70,48,19,116,109,115,101,100,98,102,105,101,108,100,101,100,105,116, + 111,114,102,111,18,109,115,101,100,98,102,105,101,108,100,101,100,105,116,111, + 114,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102, + 111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,2,29,8,98,111,117,110,100,115, + 95,121,3,248,0,9,98,111,117,110,100,115,95,99,120,3,89,2,9,98, + 111,117,110,100,115,95,99,121,3,216,0,23,99,111,110,116,97,105,110,101, + 114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97, + 110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99, + 116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110, + 0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1, + 2,0,2,0,3,89,2,3,216,0,0,7,111,112,116,105,111,110,115,11, + 13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117, + 116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114, + 105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,12,102, + 111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108, + 101,7,10,116,115,116,97,116,102,105,108,101,49,16,111,110,101,118,101,110, + 116,108,111,111,112,115,116,97,114,116,7,10,102,111,114,109,108,111,97,100, + 101,100,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8, + 116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,49,8,116,97,98,111,114,100,101,114,2,3,8,98,111, + 117,110,100,115,95,120,3,216,1,8,98,111,117,110,100,115,95,121,3,184, + 0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,22,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105, + 103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101, + 11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,2,79,75,11,109,111, + 100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116, + 98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,8,98,111,117,110, + 100,115,95,120,3,24,2,8,98,111,117,110,100,115,95,121,3,184,0,9, + 98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99, + 121,2,22,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104, + 116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112, + 116,105,111,110,6,6,67,97,110,99,101,108,11,109,111,100,97,108,114,101, + 115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0,0,11,116,115, + 116,114,105,110,103,103,114,105,100,10,102,105,101,108,100,100,101,102,108,105, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,9,70,105,101,108, + 100,100,101,102,115,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114, + 108,95,111,112,116,105,111,110,115,115,107,105,110,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,1,8,98,111,117,110,100,115,95,120,3,80,1,8,98,111,117,110, + 100,115,95,121,2,7,9,98,111,117,110,100,115,95,99,120,3,2,1,9, + 98,111,117,110,100,115,95,99,121,3,171,0,12,98,111,117,110,100,115,95, + 99,120,109,105,110,2,50,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116, + 9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103, + 114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,19,111,103, + 95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,20,111,103, + 95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2, + 16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116, + 12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108, + 116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99, + 116,12,99,111,95,115,97,118,101,115,116,97,116,101,0,14,100,97,116,97, + 99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,123, + 7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108, + 121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,14,115,99,111,101,95,101,97,116,114,101,116,117, + 114,110,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97, + 108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,3,129, + 0,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110, + 108,121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111, + 112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97, + 116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111, + 101,95,101,97,116,114,101,116,117,114,110,0,10,118,97,108,117,101,102,97, + 108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0, + 0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105, + 120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116, + 2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,2,14, + 99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112, + 116,105,111,110,6,4,78,97,109,101,0,1,7,99,97,112,116,105,111,110, + 6,4,84,121,112,101,0,0,0,0,14,114,111,119,102,111,110,116,115,46, + 99,111,117,110,116,2,1,14,114,111,119,102,111,110,116,115,46,105,116,101, + 109,115,14,1,5,99,111,108,111,114,4,4,0,0,160,4,110,97,109,101, + 6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99,97,108,101, + 2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99, + 111,108,111,114,10,102,108,112,95,120,115,99,97,108,101,0,0,0,13,100, + 97,116,97,114,111,119,104,101,105,103,104,116,2,16,11,111,110,99,101,108, + 108,101,118,101,110,116,7,13,100,101,102,115,99,101,108,108,101,118,101,110, + 116,18,111,110,115,101,108,101,99,116,105,111,110,99,104,97,110,103,101,100, + 7,16,100,101,102,115,115,101,108,101,99,116,105,111,110,99,104,97,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,119,105, + 100,103,101,116,103,114,105,100,6,102,105,101,108,100,115,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,6,70,105,101,108,100,115,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112,116,105,111,110, + 115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110, + 100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,7,9,98,111, + 117,110,100,115,95,99,120,3,67,1,9,98,111,117,110,100,115,95,99,121, + 3,171,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111, + 112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105, + 122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103, + 95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119, + 105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101, + 116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101, + 110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119, + 13,111,103,95,97,117,116,111,97,112,112,101,110,100,9,111,103,95,115,111, + 114,116,101,100,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116, + 97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95, + 97,117,116,111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46,99, + 111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115, + 14,1,5,119,105,100,116,104,2,15,7,110,117,109,115,116,101,112,2,1, + 0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102, + 105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104, + 116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,5, + 14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,0,1,0, + 1,7,99,97,112,116,105,111,110,6,4,78,97,109,101,0,1,7,99,97, + 112,116,105,111,110,6,10,67,108,97,115,115,32,116,121,112,101,0,1,7, + 99,97,112,116,105,111,110,6,10,70,105,101,108,100,32,107,105,110,100,0, + 0,0,0,14,114,111,119,102,111,110,116,115,46,99,111,117,110,116,2,1, + 14,114,111,119,102,111,110,116,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,4,0,0,160,4,110,97,109,101,6,11,115,116,102,95,100, + 101,102,97,117,108,116,6,120,115,99,97,108,101,2,1,10,108,111,99,97, + 108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111,114,10,102,108, + 112,95,120,115,99,97,108,101,0,0,0,14,100,97,116,97,99,111,108,115, + 46,99,111,117,110,116,2,5,16,100,97,116,97,99,111,108,115,46,111,112, + 116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111, + 95,115,97,118,101,115,116,97,116,101,0,14,100,97,116,97,99,111,108,115, + 46,105,116,101,109,115,14,7,5,105,110,100,101,120,1,5,119,105,100,116, + 104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,105,110,118,105, + 115,105,98,108,101,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95, + 115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97, + 116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,5,105,110,100,101, + 120,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110, + 116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,102,105,101,108, + 100,112,111,1,5,119,105,100,116,104,2,12,7,111,112,116,105,111,110,115, + 11,12,99,111,95,105,110,118,105,115,105,98,108,101,12,99,111,95,100,114, + 97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110, + 97,109,101,6,7,102,105,101,108,100,112,111,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,112,111,105,110,116,101,114,100,97,116,97, + 108,105,115,116,0,7,9,102,105,101,108,100,110,97,109,101,1,5,119,105, + 100,116,104,2,97,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118, + 101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,0, + 10,119,105,100,103,101,116,110,97,109,101,6,9,102,105,101,108,100,110,97, + 109,101,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,7,99, + 108,97,115,115,116,121,1,5,119,105,100,116,104,2,92,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118, + 97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119, + 105,100,103,101,116,110,97,109,101,6,7,99,108,97,115,115,116,121,9,100, + 97,116,97,99,108,97,115,115,7,17,116,103,114,105,100,101,110,117,109,100, + 97,116,97,108,105,115,116,0,7,9,102,105,101,108,100,107,105,110,100,1, + 5,119,105,100,116,104,2,84,7,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110,97, + 109,101,6,9,102,105,101,108,100,107,105,110,100,9,100,97,116,97,99,108, + 97,115,115,7,17,116,103,114,105,100,101,110,117,109,100,97,116,97,108,105, + 115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16, + 14,111,110,114,111,119,115,100,101,108,101,116,105,110,103,7,17,102,105,101, + 108,100,114,111,119,115,100,101,108,101,116,105,110,103,13,111,110,114,111,119, + 115,100,101,108,101,116,101,100,7,12,102,105,101,108,100,115,114,111,119,100, + 101,108,11,111,110,99,101,108,108,101,118,101,110,116,7,14,102,105,101,108, + 100,99,101,108,108,101,118,101,110,116,18,111,110,115,101,108,101,99,116,105, + 111,110,99,104,97,110,103,101,100,7,17,102,105,101,108,100,115,101,108,101, + 99,116,105,111,110,99,104,97,6,111,110,115,111,114,116,7,9,102,105,101, + 108,100,115,111,114,116,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,12,116,105,110,116,101,103,101,114,101,100,105,116,5,105,110,100, + 101,120,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11, + 111,112,116,105,111,110,115,115,107,105,110,11,10,111,115,107,95,110,111,115, + 107,105,110,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,13,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,112, + 111,105,110,116,101,114,101,100,105,116,7,102,105,101,108,100,112,111,11,111, + 112,116,105,111,110,115,115,107,105,110,11,10,111,115,107,95,110,111,115,107, + 105,110,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,14,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,12,9,98,111,117,110,100,115,95,99,121,2,16, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7, + 118,105,115,105,98,108,101,8,0,0,11,116,115,116,114,105,110,103,101,100, + 105,116,9,102,105,101,108,100,110,97,109,101,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,3,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,27,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,97, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,17,102,105,101, + 108,100,115,100,97,116,97,101,110,116,101,114,101,100,10,111,110,115,101,116, + 118,97,108,117,101,7,17,102,105,101,108,100,110,97,109,101,115,101,116,118, + 97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,13,116,101,110,117,109,116,121,112,101,101,100,105,116,7,99,108,97, + 115,115,116,121,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,18,102,114,97,109,101,46,98,117,116, + 116,111,110,46,99,111,108,111,114,4,5,0,0,144,8,116,97,98,111,114, + 100,101,114,2,4,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,125,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,92,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115, + 97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110, + 114,101,97,100,111,110,108,121,10,111,101,95,110,111,116,110,117,108,108,0, + 12,118,97,108,117,101,100,101,102,97,117,108,116,2,0,3,109,105,110,2, + 0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110, + 116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116, + 101,109,115,14,1,0,0,6,111,110,105,110,105,116,7,7,105,110,105,116, + 99,108,97,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,101,110,117,109,116,121,112,101,101,100,105,116,9,102,105,101,108, + 100,107,105,110,100,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,18,102,114,97,109,101,46,98,117, + 116,116,111,110,46,119,105,100,116,104,2,15,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,8,116,97,98, + 111,114,100,101,114,2,5,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,3,218,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,84,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101, + 49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101, + 116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99, + 116,111,110,114,101,97,100,111,110,108,121,10,111,101,95,110,111,116,110,117, + 108,108,0,12,118,97,108,117,101,100,101,102,97,117,108,116,2,0,3,109, + 105,110,2,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99, + 111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115, + 46,105,116,101,109,115,14,1,0,0,6,111,110,105,110,105,116,7,13,105, + 110,105,116,102,105,101,108,100,107,105,110,100,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,9,116,115,112,108,105,116,116,101, + 114,8,115,112,108,105,116,116,101,114,5,99,111,108,111,114,4,3,0,0, + 144,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95, + 120,3,75,1,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110, + 100,115,95,99,120,2,5,9,98,111,117,110,100,115,95,99,121,3,154,0, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,7,111,112,116,105, + 111,110,115,11,9,115,112,111,95,104,109,111,118,101,9,115,112,111,95,104, + 112,114,111,112,0,8,108,105,110,107,108,101,102,116,7,6,102,105,101,108, + 100,115,9,108,105,110,107,114,105,103,104,116,7,10,102,105,101,108,100,100, + 101,102,108,105,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116, + 102,105,108,101,49,14,111,110,117,112,100,97,116,101,108,97,121,111,117,116, + 7,12,115,112,108,105,116,116,101,114,117,112,100,97,0,0,17,116,115,116, + 111,99,107,103,108,121,112,104,98,117,116,116,111,110,10,100,101,102,116,111, + 102,105,101,108,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8, + 116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3, + 82,1,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115, + 95,99,120,2,28,9,98,111,117,110,100,115,95,99,121,2,15,5,115,116, + 97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16,97,115,95, + 108,111,99,97,108,100,105,115,97,98,108,101,100,17,97,115,95,108,111,99, + 97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108, + 105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,5,103,108,121,112,104,7,13,115,116,103,95,97,114, + 114,111,119,108,101,102,116,9,111,110,101,120,101,99,117,116,101,7,14,116, + 114,97,110,115,102,101,114,102,105,101,108,100,115,0,0,17,116,115,116,111, + 99,107,103,108,121,112,104,98,117,116,116,111,110,10,102,105,101,108,100,116, + 111,100,101,102,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116, + 97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,47, + 1,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95, + 99,120,2,28,9,98,111,117,110,100,115,95,99,121,2,15,5,115,116,97, + 116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16,97,115,95,108, + 111,99,97,108,100,105,115,97,98,108,101,100,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,5,103,108,121,112,104,7,14,115,116,103,95,97,114,114, + 111,119,114,105,103,104,116,9,111,110,101,120,101,99,117,116,101,7,12,100, + 101,108,101,116,101,102,105,101,108,100,115,0,0,9,116,115,116,97,116,102, + 105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110, + 97,109,101,6,17,100,98,102,105,101,108,100,101,100,105,116,111,114,46,115, + 116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111, + 114,121,0,4,108,101,102,116,2,24,3,116,111,112,3,152,0,0,0,16, + 116,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115, + 116,114,105,110,103,115,46,100,97,116,97,1,6,7,68,97,116,97,115,101, + 116,0,4,108,101,102,116,3,152,0,3,116,111,112,3,152,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsedbfieldeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msedesignintf.pas b/mseide-msegui/lib/common/designutils/msedesignintf.pas new file mode 100644 index 0000000..3dc0922 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedesignintf.pas @@ -0,0 +1,1674 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedesignintf; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$ifndef mse_methodswap} + {$define mse_nomethodswap} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegraphutils,mselist,sysutils,typinfo,msebitmap, + msetypes,msestrings,msegraphics,msegui,mseglob,msearrayutils, + mseclasses,mseforms,msestat,mserichstring,msecomptree; +const + defaultmoduleclassname = 'tmseform'; +type + initcomponentprocty = + procedure(const acomponent: tcomponent; const aparent: tcomponent) of object; + + componentclassinfoty = record + classtyp: tcomponentclass; + icon: integer; + page: integer; + defaultindex: integer; + end; + pcomponentclassinfoty = ^componentclassinfoty; + + comppagety = record + caption: msestring; + hint: msestring; + end; + comppagearty = array of comppagety; + + tcomponentclasslist = class(torderedrecordlist) + private + fselectedclass: tcomponentclass; + fimagelist: timagelist; + fpagenames: comppagearty; + fpagecomporders: integerararty; + fdefaultindex: integer; + fdefaultorder: boolean; + function getpagecomporders(const index: integer): integerarty; + procedure setpagecomporders(const index: integer; + const Value: integerarty); + procedure checkpageindex(const index: integer); + procedure setdefaultorder(const avalue: boolean); + protected + function findpage(const pagename: msestring): integer; + function addpage(const pagename: msestring): integer; + function getcomparefunc: sortcomparemethodty; override; + function compare(const l,r): integer; + function componentcounts: integerarty; + public + constructor create; + destructor destroy; override; + function indexof(const value: tcomponentclass): integer; //-1 if not found + function add(var value: componentclassinfoty): integer; + //-1 if allready registred + function itempo(const index: integer): pcomponentclassinfoty; + procedure registercomponents(const page: msestring; + const componentclasses: array of tcomponentclass); + procedure registercomponenttabhints(const pages: array of msestring; + const hints: array of msestring); + //pages are case sensitive, pages mustexist + function pagehigh: integer; + function pagenames: comppagearty; + property pagecomporders[const index: integer]: integerarty + read getpagecomporders write setpagecomporders; + procedure drawcomponenticon(const acomponent: tcomponent; + const canvas: tcanvas; const dest: rectty); + procedure updatestat(const filer: tstatfiler); + property selectedclass: tcomponentclass read fselectedclass write fselectedclass; + property imagelist: timagelist read fimagelist; + property defaultorder: boolean read fdefaultorder write setdefaultorder; + //nil for unselect + end; + + idesignerselections = interface(inullinterface) + function add(const item: tcomponent): integer; + function equals(const list: idesignerselections): boolean; + function get(index: integer): tcomponent; + function getcount: integer; + function getarray: componentarty; + property count: integer read getcount; + property items[index: integer]: tcomponent read get; default; + end; + + componenteditorstatety = (cs_canedit); + componenteditorstatesty = set of componenteditorstatety; + + icomponenteditor = interface(inullinterface) + procedure edit; + function state: componenteditorstatesty; + end; + + compfilterfuncty = function(const acomponent: tcomponent): boolean of object; + + idesigner = interface(inullinterface) + procedure componentmodified(const component: tobject; + const apropname: string = ''; const apropindex: int32 = -1); + function createcurrentcomponent(const module: tmsecomponent): tcomponent; + function hascurrentcomponent: boolean; + procedure addcomponent(const module: tmsecomponent; + const acomponent: tcomponent); + procedure deleteselection(adoall: Boolean = False); + procedure deletecomponent(const acomponent: tcomponent); + procedure clearselection; + procedure selectcomponent(instance: tcomponent); + procedure setselections(const list: idesignerselections); + procedure noselection; + function getmethod(const name: string; const methodowner: tmsecomponent; + const atype: ptypeinfo; const searchancestors: boolean): tmethod; + function getmethodname(const method: tmethod; const comp: tcomponent): string; + procedure changemethodname(const method: tmethod; newname: string; + const atypeinfo: ptypeinfo); + function createmethod(const name: string; const module: tmsecomponent; + const atype: ptypeinfo): tmethod; + procedure checkmethod(const method: tmethod; const name: string; + const module: tmsecomponent; const atype: ptypeinfo); + function isownedmethod(const root: tcomponent; + const method: tmethod): boolean; + function getcomponentname(const comp: tcomponent): string; + //returns qualified name + procedure validaterename(const acomponent: tcomponent; const curname, newname: string); + function getcomponentdispname(const comp: tcomponent): string; + //returns qualified name into root + function getclassname(const comp: tcomponent): string; + //returns submoduleclass if appropriate + function getcomponent(const aname: string; const aroot: tcomponent): tcomponent; + //handles qualified names for foreign forms + function componentcanedit: boolean; + function getcomponenteditor: icomponenteditor; + function getcomponentlist(const acomponentclass: tcomponentclass; + const filter: compfilterfuncty = nil; + const allmodules: boolean = false): componentarty; + function getcomponentnamelist(const acomponents: componentarty; + const amodule: tmsecomponent): msestringarty; overload; + //nil values ignored + function getcomponentnamelist(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil): msestringarty; overload; + function getcomponentnametree(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const findmode: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil; + const amodule: tcomponent = nil): tcompnameitem; + procedure setactivemodule(const adesignform: tcustommseform); + function getmodulex(const amodule: tmsecomponent): integer; + procedure setmodulex(const amodule: tmsecomponent; avalue: integer); + function getmoduley(const amodule: tmsecomponent): integer; + procedure setmoduley(const amodule: tmsecomponent; avalue: integer); + procedure modulesizechanged(const amodule: tmsecomponent); + end; + + idesignnotification = interface(inullinterface) + procedure itemdeleted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure iteminserted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure itemsmodified(const adesigner: idesigner; const aitem: tobject); + //nil for undefined aitem + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure selectionchanged(const adesigner: idesigner; + const aselection: idesignerSelections); + + procedure moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); + + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); + + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + end; + + selectedinfoty = record + instance: tcomponent; + end; + pselectedinfoty = ^selectedinfoty; + + objinfoty = record + owner: tcomponent; + parent: twidget; + ownerindex: integer; + parentindex: integer; + objtext: string; + end; + objinfoarty = array of objinfoty; + + tdesignerselections = class(trecordlist,idesignerselections) + private + fupdating: integer; + factcomp: tcomponent; + fpasteowner: tcomponent; + fpasteroot: tcomponent; + function Getitems(const index: integer): tcomponent; + procedure Setitems(const index: integer; const Value: tcomponent); + procedure dosetactcomp(component: tcomponent); + procedure doadd(component: tcomponent); + {$ifdef mse_nomethodswap} + procedure setpastemethodproperty(reader: treader; + instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); + {$else} + procedure findpastemethod(Reader: TReader; + const aMethodName: string; var Address: Pointer; var Error: Boolean); + {$endif} + procedure referencepastename(reader: treader; var name: string); + protected + procedure dochanged; virtual; + function getrecordsize: integer; virtual; + procedure addchildren(child: tcomponent); + public + constructor create; + procedure change; override; + procedure beginupdate; + procedure endupdate; + procedure decupdate; + // idesignerselections + function Add(const Item: Tcomponent): Integer; + function Equals(const List: IDesignerSelections): Boolean; reintroduce; + function Get(Index: Integer): Tcomponent; + function GetCount: Integer; + function getarray: componentarty; + + function getobjinfoar: objinfoarty; + function getobjecttext: string; + function pastefromobjecttext(const aobjecttext: string; + aowner,aparent: tcomponent; + initproc: initcomponentprocty): componentarty; + procedure copytoclipboard; + function pastefromclipboard(aowner,aparent: tcomponent; + initproc: initcomponentprocty): componentarty; + + function itempo(const index: integer): pselectedinfoty; + function indexof(const ainstance: tcomponent): integer; + function remove(const ainstance: tcomponent): integer; virtual; + procedure assign(const source: idesignerselections); + property items[const index: integer]: tcomponent + read Getitems write Setitems; default; + function isembedded(const component: tcomponent): boolean; + //true if subchild of another selected component + end; + + tdesignnotifications = class(tpointerlist) + public + procedure ItemDeleted(const ADesigner: IDesigner; const amodule: tmsecomponent; + const AItem: tcomponent); + procedure ItemInserted(const ADesigner: IDesigner; const amodule: tmsecomponent; + const AItem: tcomponent); + procedure ItemsModified(const ADesigner: IDesigner; const aitem: tobject); + //nil for undefined aitem + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure SelectionChanged(const ADesigner: IDesigner; + const ASelection: IDesignerSelections); + procedure moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; out cancel: boolean); + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + + procedure Registernotification(const DesignNotification: IDesignNotification); + procedure Unregisternotification(const DesignNotification: IDesignNotification); + end; + + unitgroupinfoty = record + dependents: stringarty; + group: stringarty; + end; + punitgroupinfoty = ^unitgroupinfoty; + + tunitgroups = class(trecordlist) + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + public + constructor create; + procedure registergroups(const adependents: array of string; + const agroup: array of string); + function getneededunits(const aunitname: string): stringarty; + end; + + createdesignmodulefuncty = function(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + initdesigncomponentprocty = procedure(const amodule: tcomponent; + const acomponent: tcomponent); + getdesignscalefuncty = function(const amodule: tcomponent): real; + sourcetoformfuncty = function(const amodule: tmsecomponent; + const source: trichstringdatalist): boolean; + //true if ok + designmoduleintfty = record + createfunc: createdesignmodulefuncty; + initnewcomponent: initdesigncomponentprocty; + getscale: getdesignscalefuncty; + sourcetoform: sourcetoformfuncty; + end; + pdesignmoduleintfty = ^designmoduleintfty; + +procedure registercomponents(const page: msestring; + const componentclasses: array of tcomponentclass); +procedure registercomponenttabhints(const pages: array of msestring; + const hints: array of msestring); + //pages are case sensitive, pages mustexist +function registeredcomponents: tcomponentclasslist; +function unitgroups: tunitgroups; +procedure registerunitgroup(const adependents,agroup: array of string); + +function designnotifications: tdesignnotifications; + +procedure setcomponentpos(const component: tcomponent; const pos: pointty); +function getcomponentpos(const component: tcomponent): pointty; + +implementation +uses + msesysutils,msestream,msewidgets,msedatalist,rtlconsts,msedesigner, + msetabs,mseapplication,mseobjecttext,msedatamodules,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + treader1 = class(treader); + twriter1 = class(twriter); + tcomponent1 = class(tcomponent); + +var + adesignnotifications: tdesignnotifications; + aregisteredcomponents: tcomponentclasslist; +// aregistereddesignmoduleclasses: designmoduleinfoarty; + aunitgroups: tunitgroups; + +{$ifdef FPC} +var + componentposreversed: boolean; +{$endif} + +procedure setcomponentpos(const component: tcomponent; const pos: pointty); +var + lo1: longint; +begin + {$ifdef fpc} //fpbug + if componentposreversed then begin + longrec(lo1).hi:= pos.x; + longrec(lo1).lo:= pos.y; + end + else begin + longrec(lo1).lo:= pos.x; + longrec(lo1).hi:= pos.y; + end; + {$else} + longrec(lo1).lo:= pos.x; + longrec(lo1).hi:= pos.y; + {$endif} + component.designinfo:= lo1; +end; + +function getcomponentpos(const component: tcomponent): pointty; +begin + {$ifdef fpc} //fpbug + if componentposreversed then begin + result.x:= smallint(longrec(component.designinfo).hi); + result.y:= smallint(longrec(component.designinfo).lo); + end + else begin + result.x:= smallint(longrec(component.designinfo).lo); + result.y:= smallint(longrec(component.designinfo).hi); + end; + {$else} + result.x:= smallint(longrec(component.designinfo).lo); + result.y:= smallint(longrec(component.designinfo).hi); + {$endif} +end; + +function registeredcomponents: tcomponentclasslist; +begin + if aregisteredcomponents = nil then begin + aregisteredcomponents:= tcomponentclasslist.create; + end; + result:= aregisteredcomponents; +end; + +function unitgroups: tunitgroups; +begin + if aunitgroups = nil then begin + aunitgroups:= tunitgroups.create; + end; + result:= aunitgroups; +end; + +function designnotifications: tdesignnotifications; +begin + result:= adesignnotifications; +end; + +procedure registercomponents(const page: msestring; + const componentclasses: array of tcomponentclass); +begin + registeredcomponents.registercomponents(page,componentclasses); +end; + +procedure registercomponenttabhints(const pages: array of msestring; + const hints: array of msestring); + //pages are case sensitive, pages mustexist +begin + registeredcomponents.registercomponenttabhints(pages,hints); +end; + +procedure registerunitgroup(const adependents,agroup: array of string); +begin + unitgroups.registergroups(adependents,agroup); +end; + +{ tcomponentclasslist } + +constructor tcomponentclasslist.create; +begin + fimagelist:= timagelist.create(nil); + fimagelist.size:= makesize(24,24); + fimagelist.colormask:= true; + inherited create(sizeof(componentclassinfoty)); +end; + +destructor tcomponentclasslist.destroy; +begin + fimagelist.Free; + inherited; +end; + +function tcomponentclasslist.add(var value: componentclassinfoty): integer; +begin + if indexof(value.classtyp) < 0 then begin + value.defaultindex:= fdefaultindex; + inc(fdefaultindex); + result:= inherited add(value); + end + else begin + result:= -1; + end; +end; + +procedure tcomponentclasslist.registercomponents(const page: msestring; + const componentclasses: array of tcomponentclass); +var + info: componentclassinfoty; + int1: integer; + bitmap: tbitmapcomp; + class1: tclass; + pagenr: integer; +begin + pagenr:= addpage(page); + bitmap:= tbitmapcomp.create(nil); + try + if fimagelist.count = 0 then begin + bitmap.name:= 'TComponent'; + initmsecomponent1(bitmap,nil); + fimagelist.addimage(bitmap.bitmap); + end; + with info do begin + for int1:= 0 to high(componentclasses) do begin + classtyp:= componentclasses[int1]; + page:= pagenr; + icon:= 0; + class1:= classtyp; + while class1 <> nil do begin + bitmap.bitmap.clear; + bitmap.bitmap.colormask:= false; + bitmap.name:= class1.classname; + if initmsecomponent1(bitmap,nil) then begin + if not bitmap.bitmap.colormask then begin + bitmap.bitmap.automask; + end; + icon:= fimagelist.addimage(bitmap.bitmap); + break; + end; + class1:= class1.ClassParent; + end; + mclasses.registerclass(info.classtyp); + add(info); + end; + end; + finally + bitmap.Free; + end; +end; + +procedure tcomponentclasslist.registercomponenttabhints( + const pages: array of msestring; const hints: array of msestring); + //pages are case sensitive, pages mustexist +var + int1: integer; + int2: integer; +begin + for int1:= 0 to high(pages) do begin + int2:= findpage(pages[int1]); + if (int2 >= 0) then begin + with fpagenames[int2] do begin + if int1 <= high(hints) then begin + hint:= hints[int1]; + end + else begin + hint:= ''; + end; + end; + end; + end; +end; + +function tcomponentclasslist.indexof( + const value: tcomponentclass): integer; +begin + result:= inherited indexof(value); +end; + +function tcomponentclasslist.itempo( + const index: integer): pcomponentclassinfoty; +begin + result:= pcomponentclassinfoty(getitempo(index)); +end; + +function tcomponentclasslist.findpage(const pagename: msestring): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(fpagenames) do begin + if fpagenames[int1].caption = pagename then begin + result:= int1; + break; + end; + end; +end; + +function tcomponentclasslist.addpage(const pagename: msestring): integer; +begin + result:= findpage(pagename); + if result < 0 then begin + setlength(fpagenames,length(fpagenames) + 1); + setlength(fpagecomporders,length(fpagenames)); + result:= high(fpagenames); + fpagenames[result].caption:= pagename; + end; +end; + +function tcomponentclasslist.pagenames: comppagearty; +begin + result:= fpagenames; +end; + +function tcomponentclasslist.pagehigh: integer; +begin + result:= high(fpagenames); +end; + +procedure tcomponentclasslist.drawcomponenticon(const acomponent: tcomponent; + const canvas: tcanvas; const dest: rectty); +var + int1: integer; +begin + int1:= indexof(tcomponentclass(acomponent.classtype)); + if int1 >= 0 then begin + fimagelist.paint(canvas,itempo(int1)^.icon,dest); + end; +end; + +function tcomponentclasslist.componentcounts: integerarty; +var + int1: integer; +begin + setlength(result,length(fpagenames)); + for int1:= 0 to count - 1 do begin + with itempo(int1)^ do begin + if page <= high(result) then begin + inc(result[page]); + end; + end; + end; +end; + +procedure tcomponentclasslist.updatestat(const filer: tstatfiler); +var + int1,int2: integer; + ar1,ar2,ar3: integerarty; +begin + ar1:= nil; //compiler warning + ar2:= nil; //compiler warning + filer.setsection('componentpalette'); + if filer.iswriter then begin + for int1:= 0 to high(fpagecomporders) do begin + tstatwriter(filer).writearray('order'+inttostrmse(int1), + fpagecomporders[int1]); + end; + end + else begin + ar2:= componentcounts; + for int1:= 0 to high(fpagecomporders) do begin + ar1:= tstatreader(filer).readarray('order'+inttostrmse(int1), + integerarty(nil)); + if ar1 <> nil then begin + if length(ar1) <> ar2[int1] then begin + ar1:= nil; //invalid + end + else begin + ar3:= copy(ar1); + sortarray(ar3); + for int2:= 0 to high(ar3) do begin + if ar3[int2] <> int2 then begin + ar1:= nil; //invalid + break; + end; + end; + end; + end; + fpagecomporders[int1]:= ar1; + end; + end; + filer.endlist; +end; + +function tcomponentclasslist.compare(const l, r): integer; +begin + if fdefaultorder then begin + result:= componentclassinfoty(l).defaultindex - + componentclassinfoty(r).defaultindex; + end + else begin + result:= ptruint(componentclassinfoty(l).classtyp) - + ptruint(componentclassinfoty(r).classtyp); + end; +end; + +function tcomponentclasslist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}compare; +end; + +procedure tcomponentclasslist.checkpageindex(const index: integer); +begin + if (index < 0) or (index > high(fpagecomporders)) then begin + tlist.Error(SListIndexError, Index); + end; +end; + +function tcomponentclasslist.getpagecomporders( + const index: integer): integerarty; +begin + checkpageindex(index); + result:= fpagecomporders[index]; +end; + +procedure tcomponentclasslist.setpagecomporders(const index: integer; + const Value: integerarty); +begin + checkpageindex(index); + fpagecomporders[index]:= value; +end; + +procedure tcomponentclasslist.setdefaultorder(const avalue: boolean); +begin + if fdefaultorder <> avalue then begin + fdefaultorder:= avalue; + if sorted then begin + sorted:= false; + sorted:= true; + end; + end; +end; + +{ tdesignerselections } + +constructor tdesignerselections.create; +begin + inherited create(getrecordsize); +end; + +function tdesignerselections.itempo(const index: integer): pselectedinfoty; +begin + result:= pselectedinfoty(getitempo(index)); +end; + +procedure tdesignerselections.assign(const source: idesignerselections); +var + int1: integer; +begin + clear; + count:= source.Count; + for int1:= 0 to source.count - 1 do begin + itempo(int1)^.instance:= source.Items[int1]; + end; + change; +end; + +function tdesignerselections.getarray: componentarty; +begin + if fcount > 0 then begin + setlength(result,fcount); + move(datapo^,pointer(result)^,fcount*sizeof(pointer)); + end + else begin + result:= nil; + end; +end; + +function tdesignerselections.Add(const Item: Tcomponent): Integer; +var + info: selectedinfoty; + widget1: twidget; +begin + result:= indexof(item); + if result < 0 then begin + fillchar(info,sizeof(info),0); + info.instance:= item; + result:= inherited add(info); + if item is twidget then begin + widget1:= twidget(item); + while widget1 <> nil do begin + if (widget1 is ttabpage) then begin + ttabpage(widget1).isactivepage:= true; + end; + widget1:= widget1.parentwidget; + end; + end; + change; + end; +end; + +function tdesignerselections.Equals(const List: IDesignerSelections): Boolean; +var + int1: integer; +begin + result:= false; + if list.Count = count then begin + for int1:= 0 to count-1 do begin + if list.Items[int1] <> itempo(int1)^.instance then begin + exit; + end; + end; + end; + result:= true; +end; + +function tdesignerselections.Get(Index: Integer): Tcomponent; +begin + result:= itempo(index)^.instance; +end; + +function tdesignerselections.GetCount: Integer; +begin + result:= count; +end; + +function tdesignerselections.indexof(const ainstance: tcomponent): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to count-1 do begin + if itempo(int1)^.instance = ainstance then begin + result:= int1; + break; + end; + end; +end; + +function tdesignerselections.remove(const ainstance: tcomponent): integer; +begin + result:= indexof(ainstance); + if result >= 0 then begin + delete(result); + change; + end; +end; + +procedure tdesignerselections.dochanged; +begin + //dummy +end; + +function tdesignerselections.getrecordsize: integer; +begin + result:= sizeof(selectedinfoty); +end; + +function tdesignerselections.Getitems(const index: integer): tcomponent; +begin + result:= itempo(index)^.instance; +end; + +procedure tdesignerselections.Setitems(const index: integer; + const Value: tcomponent); +begin + itempo(index)^.instance:= value; +end; + +procedure tdesignerselections.beginupdate; +begin + inc(fupdating); +end; + +procedure tdesignerselections.change; +begin + if fupdating = 0 then begin + dochanged; + end; +end; + +procedure tdesignerselections.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + dochanged; + end; +end; + +procedure tdesignerselections.decupdate; +begin + dec(fupdating); +end; + +function tdesignerselections.isembedded(const component: tcomponent): boolean; + //true if subchild of another selected component +var + comp1: tcomponent; +begin + result:= false; + comp1:= component.getparentcomponent; + while comp1 <> nil do begin + if (indexof(comp1) >= 0) then begin + result:= true; + break; //stored by parent + end; + comp1:= comp1.getparentcomponent; + end; +end; + +function tdesignerselections.getobjecttext: string; +var + binstream: tmemorystream; + textstream: ttextstream; + int1: integer; + component: tcomponent; + writer: twritermse; + comp1,comp2: tcomponent; +{$ifndef mse_nomethodswap} + po1: pointer; + modulepo: pmoduleinfoty; +{$endif} +begin + result:= ''; + if count > 0 then begin + binstream:= tmemorystream.Create; + textstream:= ttextstream.Create; + try + for int1:= 0 to count -1 do begin + component:= items[int1]; + if not isembedded(component) then begin + writer:= twritermse.Create(binstream,4096,true); + comp1:= tcomponent.create(nil); + try + {$ifdef mse_nomethodswap} + writer.onwritemethodproperty:= + {$ifdef FPC}@{$endif}designer.writedesignmethod; + {$else} + modulepo:= designer.modules.findmodulebycomponent(component); + po1:= swapmethodtable(comp1, + modulepo^.methods.createmethodtable( + designer.getancestormethods(modulepo))); + designer.doswapmethodpointers(component,false); + {$endif} + try + writer.Root:= component.Owner; + designer.descendentinstancelist.beginstreaming(nil); + comp2:= designer.descendentinstancelist.findancestor(component); + writer.ancestor:= comp2; + writer.rootancestor:= comp2; + writer.onfindancestor:= {$ifdef FPC}@{$endif}designer.findancestor; + writer.writecomponent(component); + finally + designer.descendentinstancelist.endstreaming; + {$ifndef mse_nomethodswap} + designer.doswapmethodpointers(component,true); + swapmethodtable(comp1,po1); + modulepo^.methods.releasemethodtable; + {$endif} + end; + finally + comp1.free; + writer.Free; + end; + end; + end; + binstream.Position:= 0; + while binstream.Position < binstream.Size do begin + objectbinarytotextmse(binstream,textstream); + end; + textstream.Position:= 0; + result:= textstream.readdatastring; + finally + binstream.Free; + textstream.Free; + end; + end; +end; + +function tdesignerselections.getobjinfoar: objinfoarty; +var + int1: integer; + co1: tcomponent; + binstream: tmemorystream; + textstream: ttextstream; + writer: twritermse; +begin + result:= nil; + for int1:= 0 to count - 1 do begin + co1:= items[int1]; + if not isembedded(co1) then begin + setlength(result,high(result)+2); + with result[high(result)] do begin + owner:= co1.owner; + if owner <> nil then begin + ownerindex:= co1.componentindex; + end + else begin + ownerindex:= -1; + end; + if co1 is twidget then begin + parent:= twidget(co1).parentwidget; + if parent <> nil then begin + parentindex:= twidget(parent).indexofwidget(twidget(co1)); + end + else begin + parentindex:= -1; + end; + end + else begin + parent:= nil; + parentindex:= -1; + end; + binstream:= tmemorystream.create; + writer:= twritermse.create(binstream,4096,true); + textstream:= ttextstream.create; + try + writer.root:= co1.owner; + writer.writecomponent(co1); + freeandnil(writer); + binstream.position:= 0; + objectbinarytotextmse(binstream,textstream); + textstream.position:= 0; + objtext:= textstream.readdatastring; + finally + writer.free; + binstream.free; + textstream.free; + end; + end; + end; + end; +end; + +procedure tdesignerselections.copytoclipboard; +begin + msewidgets.copytoclipboard(msestring(getobjecttext)); +end; + +procedure tdesignerselections.doadd(component: tcomponent); +begin + add(component); +end; + +procedure tdesignerselections.dosetactcomp(component: tcomponent); +begin + factcomp:= component; +end; + +function getglobalcomponent(const Name: string): TComponent; +begin + result:= designer.modules.findmoduleinstancebyname(name); +end; + +var + pastingmodulepo: pmoduleinfoty; + +{$ifdef mse_nomethodswap} +procedure tdesignerselections.setpastemethodproperty(reader: treader; + instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); +var + methodinfopo: pmethodinfoty; + m1: tmethod; +begin + handled:= true; + m1.data:= nil; + m1.code:= nil; + if pastingmodulepo <> nil then begin + methodinfopo:= pastingmodulepo^.methods.findmethodbyname(themethodname); + if methodinfopo <> nil then begin + m1.data:= methodinfopo^.address; + end; + end; + setmethodprop(instance,propinfo,m1); +end; +{$else} +procedure tdesignerselections.findpastemethod(Reader: TReader; + const aMethodName: string; var Address: Pointer; var Error: Boolean); +var + methodinfopo: pmethodinfoty; +begin + error:= false; + if pastingmodulepo <> nil then begin + methodinfopo:= pastingmodulepo^.methods.findmethodbyname(amethodname); + if methodinfopo <> nil then begin + address:= methodinfopo^.address; + end; + end; +end; +{$endif} +const + pastenametrailer = '_15dtz4u67sd3r'; + +procedure tdesignerselections.referencepastename(reader: treader; var name: string); +begin + if (reader.root = fpasteroot) and (fpasteroot.findcomponent(name) = nil) and + (fpasteowner.findcomponent(name+pastenametrailer) <> nil) then begin + name:= name + pastenametrailer; + //this is dangerous, there could be a component with the same name + //but another class type, no possibility found to access the + //propertyinfo of the resolving items :-( + end; +end; + +procedure tdesignerselections.addchildren(child: tcomponent); +begin + add(child); + tcomponent1(child).getchildren({$ifdef FPC}@{$endif}addchildren,fpasteroot); +end; + +type + tpasteroot = class(tcomponent) + private + fowner: tdesignerselections; + protected + procedure notification(acomponent: tcomponent; + operation: toperation); override; + public + constructor create(const aowner: tdesignerselections); reintroduce; + end; + +{ tpasteroot } + +constructor tpasteroot.create(const aowner: tdesignerselections); +begin + fowner:= aowner; + inherited create(nil); +end; + +procedure tpasteroot.notification(acomponent: tcomponent; + operation: toperation); +var + int1: integer; +begin + if (operation = opremove) then begin + if (csdestroying in acomponent.componentstate) then begin + for int1:= 0 to fowner.count-1 do begin + if fowner.items[int1] = acomponent then begin + fowner.items[int1]:= nil; + end; + end; + inherited; + end + else begin + acomponent.freenotification(self); + end; + end + else begin + inherited; + end; +end; + +function tdesignerselections.pastefromobjecttext(const aobjecttext: string; + aowner,aparent: tcomponent; initproc: initcomponentprocty): componentarty; + //returns count of added components +var + binstream: tmemorystream; + textstream: ttextstream; + int1: integer; + countbefore: integer; + reader: treader; + comp1,comp2: tcomponent; + listend: tvaluetype; + validaterenamebefore: validaterenameeventty; + +begin + result:= nil; + if aobjecttext = '' then begin + exit; + end; + if aowner is tmsecomponent then begin + pastingmodulepo:= designer.modules.findmodule(tmsecomponent(aowner)); + end + else begin + pastingmodulepo:= nil; + end; + countbefore:= count; + try + designer.beginpasting; + fpasteowner:= aowner; + textstream:= ttextstream.Create; + comp1:= tpasteroot.create(self); + fpasteroot:= comp1; + tcomponent1(comp1).SetDesigning(true{$ifndef FPC},false{$endif}); + lockfindglobalcomponent; + RegisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + try + listend:= vanull; + textstream.writeln('object comp1: tcomponent'); + textstream.writestr(aobjecttext); + textstream.writeln('end'); + textstream.Position:= 0; + binstream:= tmemorystream.Create; + try + while textstream.position < textstream.Size do begin + binstream.Position:= 0; + objecttexttobinarymse(textstream,binstream); + binstream.Write(listend,sizeof(listend)); + binstream.Position:= 0; + reader:= treader.create(binstream,4096); + try + reader.onreferencename:= {$ifdef FPC}@{$endif}referencepastename; + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= {$ifdef FPC}@{$endif}setpastemethodproperty; + {$else} + reader.onfindmethod:= {$ifdef FPC}@{$endif}findpastemethod; + {$endif} + reader.onancestornotfound:= {$ifdef FPC}@{$endif}designer.ancestornotfound; + reader.onfindcomponentclass:= + {$ifdef FPC}@{$endif}designer.findcomponentclass; + reader.oncreatecomponent:= designer.createcomponent(); + factcomp:= nil; + begingloballoading; + validaterenamebefore:= ondesignvalidaterename; + ondesignvalidaterename:= nil; //no sourceupdate + try + with getcomponentlist(comp1) do begin + for int1:= 0 to aowner.componentcount - 1 do begin + comp2:= aowner.components[int1]; + comp2.name:= comp2.name + pastenametrailer; //avoid nameclash + add(comp2); + end; + end; + try + reader.readrootcomponent(comp1); + finally + for int1:= 0 to aowner.componentcount - 1 do begin + comp2:= aowner.components[int1]; + comp2.name:= copy(comp2.name,1,length(comp2.name) - + length(pastenametrailer)); + //restore original name + end; + end; + finally + ondesignvalidaterename:= validaterenamebefore; + end; + for int1:= aowner.componentcount to comp1.componentcount - 1 do begin + comp2:= comp1.components[int1]; + {$ifndef mse_nomethodswap} + designer.doswapmethodpointers(comp2,true); + {$endif} + if (comp2.getparentcomponent = nil) or (comp2 is tmsedatamodule) then begin +// add(comp2); + addchildren(comp2); + additem(pointerarty(result),pointer(comp2)); + end; + end; + removefixupreferences(comp1,''); + clearpastedcomponents; + if assigned(initproc) then begin + for int1:= comp1.componentcount - 1 downto aowner.componentcount do begin + comp2:= comp1.components[int1]; + if (comp2.getparentcomponent = nil) or (comp2 is tmsedatamodule) then begin + initproc(comp2,aparent); + end; + end; + end; + if pastingmodulepo <> nil then begin + designer.checkmethodtypes(pastingmodulepo,false{,comp1}); + end; + notifygloballoading; + finally + endgloballoading; + clearpastedcomponents; + reader.Free; + end; + end; + finally + binstream.Free; + end; + finally + designer.endpasting; + unlockfindglobalcomponent; + unRegisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + textstream.Free; + clearcomponentlist(comp1); + end; + comp1.destroy(); + except +// comp1:= tpasteroot.create(self); + try + for int1:= countbefore to count -1 do begin + if items[int1] <> nil then begin + items[int1].freenotification(comp1); + end; + end; + for int1:= countbefore to count -1 do begin + items[int1].Free; + end; + count:= countbefore; + application.handleexception; + finally + comp1.destroy(); + end; + end; +// result:= count - countbefore; +end; + +function tdesignerselections.pastefromclipboard(aowner,aparent: tcomponent; + initproc: initcomponentprocty): componentarty; +var + str1: msestring; +begin + result:= nil; + if msewidgets.pastefromclipboard(str1) then begin + result:= pastefromobjecttext(ansistring(str1),aowner,aparent,initproc); + end; +end; + +{ tdesignnotifications } + +procedure tdesignnotifications.RegisterNotification(const DesignNotification: IDesignNotification); +begin + if indexof(pointer(designnotification)) = -1 then begin + add(pointer(designnotification)); + end; +end; + +procedure tdesignnotifications.UnregisterNotification(const DesignNotification: IDesignNotification); +begin + if self <> nil then begin + extract(pointer(designnotification)); + end; +end; +{ +procedure tdesignnotifications.DesignerClosed(const ADesigner: IDesigner; + AGoingDormant: Boolean); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).DesignerClosed(adesigner,agoingdormant); + end; +end; + +procedure tdesignnotifications.DesignerOpened(const ADesigner: IDesigner; + AResurrecting: Boolean); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).Designeropened(adesigner,aresurrecting); + end; +end; +} +procedure tdesignnotifications.ItemDeleted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).itemdeleted(adesigner,amodule,aitem); + end; +end; + +procedure tdesignnotifications.ItemInserted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).iteminserted(adesigner,amodule,aitem); + end; +end; + +procedure tdesignnotifications.ItemsModified(const ADesigner: IDesigner; + const aitem: tobject); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).itemsmodified(adesigner,aitem); + end; +end; + +procedure tdesignnotifications.SelectionChanged(const ADesigner: IDesigner; + const ASelection: IDesignerSelections); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).selectionchanged(adesigner,aselection); + end; +end; + +procedure tdesignnotifications.moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).moduleactivated(adesigner,amodule); + end; +end; + +procedure tdesignnotifications.moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).moduledeactivated(adesigner,amodule); + end; +end; + +procedure tdesignnotifications.moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).moduledestroyed(adesigner,amodule); + end; +end; + +procedure tdesignnotifications.methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).methodcreated(adesigner,amodule,aname,atype); + end; +end; + +procedure tdesignnotifications.methodnamechanged( + const adesigner: idesigner; const amodule: tmsecomponent; const newname, + oldname: string; const atypeinfo: ptypeinfo); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).methodnamechanged(adesigner,amodule, + newname,oldname,atypeinfo); + end; +end; + +procedure tdesignnotifications.showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).showobjecttext(adesigner,afilename, + backupcreated); + end; +end; + +procedure tdesignnotifications.closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; out cancel: boolean); +var + int1: integer; +begin + cancel:= false; + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).closeobjecttext(adesigner,afilename,cancel); + if cancel then begin + break; + end; + end; +end; + +procedure tdesignnotifications.componentnamechanging( + const adesigner: idesigner; const amodule: tmsecomponent; + const aitem: tcomponent; const newname: string); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).componentnamechanging(adesigner,amodule, + aitem,newname); + end; +end; + +procedure tdesignnotifications.moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).moduleclassnamechanging(adesigner,amodule, + newname); + end; +end; + +procedure tdesignnotifications.instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).instancevarnamechanging(adesigner,amodule, + newname); + end; +end; + +procedure tdesignnotifications.beforefilesave(const adesigner: idesigner; + const afilename: filenamety); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).beforefilesave(adesigner,afilename); + end; +end; + +procedure tdesignnotifications.beforemake(const adesigner: idesigner; + const maketag: integer; var abort: boolean); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + if abort then begin + break; + end; + idesignnotification(fitems[int1]).beforemake(adesigner,maketag,abort); + end; +end; + +procedure tdesignnotifications.aftermake(const adesigner: idesigner; + const exitcode: integer); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).aftermake(adesigner,exitcode); + end; +end; + +{ tunitgroups } + +constructor tunitgroups.create; +begin + inherited create(sizeof(unitgroupinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +procedure tunitgroups.registergroups(const adependents: array of string; + const agroup: array of string); +var + info: unitgroupinfoty; + int1: integer; +begin + with info do begin + setlength(dependents,length(adependents)); + for int1:= 0 to high(adependents) do begin + dependents[int1]:= struppercase(adependents[int1]); + end; + setlength(group,length(agroup)); + for int1:= 0 to high(agroup) do begin + group[int1]:= agroup[int1]; + end; + end; + add(info); +end; + +procedure tunitgroups.finalizerecord(var item); +begin + finalize(unitgroupinfoty(item)); +end; + +procedure tunitgroups.copyrecord(var item); +begin + with unitgroupinfoty(item) do begin + arrayaddref(dependents); + arrayaddref(group); + end; +end; + +function tunitgroups.getneededunits(const aunitname: string): stringarty; +//todo: optimize + + procedure doget(const aname: string; out resnormal,resupper: stringarty); + var + po1: punitgroupinfoty; + int1,int2,int3,int4: integer; + begin + resnormal:= nil; + po1:= datapo; + for int1:= 0 to count - 1 do begin + for int2:= 0 to high(po1^.dependents) do begin + if aname = po1^.dependents[int2] then begin + int3:= length(resnormal); + setlength(resnormal,int3+length(po1^.group)); + for int4:= int3 to high(resnormal) do begin + resnormal[int4]:= po1^.group[int4-int3]; + end; + break; + end; + end; + inc(po1); + end; + setlength(resnormal,high(resnormal)+2); + resnormal[high(resnormal)]:= aunitname; //add dependent + setlength(resupper,length(resnormal)); + for int1:= 0 to high(resnormal) do begin + resupper[int1]:= struppercase(resnormal[int1]); + end; + end; + +var + ar1,ar2: stringarty; + ar3: integerarty; + ar4,ar5n,ar5u: stringarty; + int1,int2{,int3,int4}: integer; + str1: string; + level: integer; + highbefore: integer; + +begin + setlength(ar4,1); + ar4[0]:= struppercase(aunitname); + level:= 0; + repeat + highbefore:= high(ar4); + ar5n:= nil; + ar5u:= nil; + for int1:= 0 to high(ar4) do begin + doget(ar4[int1],ar1,ar2); + stackarray(ar1,ar5n); + stackarray(ar2,ar5u); + end; + sortarray(ar5u,{$ifdef FPC}@{$endif}compareasciistring,ar3); + setlength(ar4,length(ar5u)); + setlength(result,length(ar5u)); + str1:= ''; + int2:= 0; + for int1:= 0 to high(ar5u) do begin + if ar5u[int1] <> str1 then begin + ar4[int2]:= ar5u[int1]; + str1:= ar4[int2]; + result[int2]:= ar5n[ar3[int1]]; + inc(int2); + end; + end; + setlength(ar4,int2); + inc(level); + until (high(ar4) = highbefore) or (level > 16); + setlength(result,length(ar4)); +end; + +{$ifdef FPC} +procedure checkreversedcomponentpos; +var + comp1: tcomponent; + writer1: twritermse; + reader1: treader; + stream1: tmemorystream; + int1: integer; + str1: string; +begin + comp1:= tcomponent.create(nil); + comp1.designinfo:= 1; + stream1:= tmemorystream.create; + writer1:= twritermse.create(stream1,256,false); +{$warnings off} + twriter1(writer1).writeproperties(comp1); +{$warnings on} + writer1.free; + stream1.position:= 0; + reader1:= treader.create(stream1,256); + str1:= reader1.driver.beginproperty; + int1:= reader1.readinteger; + componentposreversed:= (int1 = 1) xor (str1 = 'left'); + reader1.free; + stream1.free; + comp1.free; +end; +{$endif} + +initialization + {$ifdef FPC} + checkreversedcomponentpos; + {$endif} + adesignnotifications:= tdesignnotifications.Create; +// aregisteredcomponents:= tcomponentclasslist.create; +finalization + freeandnil(adesignnotifications); + freeandnil(aregisteredcomponents); + freeandnil(aunitgroups); +end. diff --git a/mseide-msegui/lib/common/designutils/msedoublereallisteditor.mfm b/mseide-msegui/lib/common/designutils/msedoublereallisteditor.mfm new file mode 100644 index 0000000..405e6cd --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublereallisteditor.mfm @@ -0,0 +1,151 @@ +object doublereallisteditor: tdoublereallisteditor + bounds_x = 130 + bounds_y = 203 + bounds_cx = 279 + bounds_cy = 211 + container.bounds = ( + 0 + 0 + 279 + 211 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat] + statfile = tstatfile1 + caption = 'Doublereallisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + taborder = 3 + bounds_x = 153 + bounds_y = 177 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + bounds_x = 217 + bounds_y = 177 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object grid: twidgetgrid + taborder = 2 + bounds_x = 8 + bounds_y = 8 + bounds_cx = 261 + bounds_cy = 157 + bounds_cxmin = 240 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol] + fixcols.count = 1 + fixcols.items = < + item + width = 31 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'a' + end + item + caption = 'b' + end> + end> + datacols.count = 2 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[vala] + width = 113 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'vala' + dataclass = tgridrealdatalist + end + item[valb] + width = 110 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_cancopy, co_canpaste] + widgetname = 'valb' + dataclass = tgridrealdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object vala: trealedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.dummy = 0 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 113 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + value = -Inf + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + min = -Inf + max = 1E+300 + reffontheight = 14 + end + object valb: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.dummy = 0 + taborder = 2 + visible = False + bounds_x = 114 + bounds_y = 0 + bounds_cx = 110 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + value = -Inf + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + min = -Inf + max = 1E+038 + reffontheight = 14 + end + end + object rowcount: tintegeredit + frame.caption = 'Rowcount' + frame.captionpos = cp_right + frame.dummy = 0 + frame.outerframe = ( + 0 + 0 + 64 + 0 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 177 + bounds_cx = 114 + anchors = [an_left, an_bottom] + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'doublestringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/msedoublereallisteditor.pas b/mseide-msegui/lib/common/designutils/msedoublereallisteditor.pas new file mode 100644 index 0000000..94c66c2 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublereallisteditor.pas @@ -0,0 +1,58 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedoublereallisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,msestat, + msestatfile; +type + tdoublereallisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + vala: trealedit; + valb: trealedit; + rowcount: tintegeredit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + msedoublereallisteditor_mfm; + +{ tdoublereallisteditor } + +constructor tdoublereallisteditor.create(const aonclosequery: closequeryeventty); +begin + onclosequery:= aonclosequery; + inherited create(nil); +end; + +procedure tdoublereallisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure tdoublereallisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msedoublereallisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msedoublereallisteditor_mfm.pas new file mode 100644 index 0000000..3bb73f9 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublereallisteditor_mfm.pas @@ -0,0 +1,158 @@ +unit msedoublereallisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msedoublereallisteditor; + +const + objdata: record size: integer; data: array[0..2819] of byte end = + (size: 2820; data: ( + 84,80,70,48,21,116,100,111,117,98,108,101,114,101,97,108,108,105,115,116, + 101,100,105,116,111,114,20,100,111,117,98,108,101,114,101,97,108,108,105,115, + 116,101,100,105,116,111,114,8,98,111,117,110,100,115,95,120,3,130,0,8, + 98,111,117,110,100,115,95,121,3,203,0,9,98,111,117,110,100,115,95,99, + 120,3,23,1,9,98,111,117,110,100,115,95,99,121,3,211,0,16,99,111, + 110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3, + 23,1,3,211,0,0,7,111,112,116,105,111,110,115,11,13,102,111,95,99, + 108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97, + 100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116, + 97,116,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102, + 105,108,101,49,7,99,97,112,116,105,111,110,6,20,68,111,117,98,108,101, + 114,101,97,108,108,105,115,116,101,100,105,116,111,114,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109, + 0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,3,153,0,8,98,111,117,110, + 100,115,95,121,3,177,0,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11, + 8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0, + 5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97, + 115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114, + 95,111,107,0,0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108, + 8,98,111,117,110,100,115,95,120,3,217,0,8,98,111,117,110,100,115,95, + 121,3,177,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117, + 110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109, + 111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101, + 108,0,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100, + 8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100,115, + 95,99,120,3,5,1,9,98,111,117,110,100,115,95,99,121,3,157,0,12, + 98,111,117,110,100,115,95,99,120,109,105,110,3,240,0,7,97,110,99,104, + 111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8, + 97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,11, + 111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115, + 105,122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111, + 103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111, + 119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108, + 101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110, + 101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111, + 119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10,111,103,95,119, + 114,97,112,99,111,108,0,13,102,105,120,99,111,108,115,46,99,111,117,110, + 116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5, + 119,105,100,116,104,2,31,7,110,117,109,115,116,101,112,2,1,0,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16, + 14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,2,14,99,97, + 112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105, + 111,110,6,1,97,0,1,7,99,97,112,116,105,111,110,6,1,98,0,0, + 0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16, + 100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108, + 115,46,105,116,101,109,115,14,7,4,118,97,108,97,1,5,119,105,100,116, + 104,2,113,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12, + 99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101, + 115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95, + 99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,4, + 118,97,108,97,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114,105, + 100,114,101,97,108,100,97,116,97,108,105,115,116,0,7,4,118,97,108,98, + 1,5,119,105,100,116,104,2,110,7,111,112,116,105,111,110,115,11,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111, + 95,115,97,118,101,118,97,108,117,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,0,10,119,105,100,103,101, + 116,110,97,109,101,6,4,118,97,108,98,9,100,97,116,97,99,108,97,115, + 115,7,17,116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115,116, + 0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,17,111, + 110,114,111,119,99,111,117,110,116,99,104,97,110,103,101,100,7,21,103,114, + 105,100,111,110,114,111,119,99,111,117,110,116,99,104,97,110,103,101,100,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,9,116,114,101, + 97,108,101,100,105,116,4,118,97,108,97,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,2, + 0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,11,102,114,97,109,101,46,100,117,109,109, + 121,2,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,113,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,5,118, + 97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,12,118,97,108,117, + 101,100,101,102,97,117,108,116,5,0,0,0,0,0,0,0,128,255,255,10, + 118,97,108,117,101,114,97,110,103,101,2,1,10,118,97,108,117,101,115,116, + 97,114,116,2,0,3,109,105,110,5,0,0,0,0,0,0,0,128,255,255, + 3,109,97,120,5,47,221,172,3,64,228,33,191,227,67,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,114,101,97,108,101, + 100,105,116,4,118,97,108,98,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101, + 105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,11,102,114,97,109,101,46,100,117,109,109,121,2,0,8,116,97, + 98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,2,114,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,110,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101, + 49,95,115,97,118,101,118,97,108,117,101,0,5,118,97,108,117,101,5,0, + 0,0,0,0,0,0,128,255,255,12,118,97,108,117,101,100,101,102,97,117, + 108,116,5,0,0,0,0,0,0,0,128,255,255,10,118,97,108,117,101,114, + 97,110,103,101,2,1,10,118,97,108,117,101,115,116,97,114,116,2,0,3, + 109,105,110,5,0,0,0,0,0,0,0,128,255,255,3,109,97,120,5,245, + 136,13,181,80,153,118,150,125,64,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,8,114,111,119,99,111,117,110,116,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,8,82,111,119,99,111,117,110,116,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,64,2, + 0,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,8,8,98,111,117,110,100,115,95,121,3,177,0,9,98,111,117, + 110,100,115,95,99,120,2,114,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,10,111,110,115, + 101,116,118,97,108,117,101,7,18,114,111,119,99,111,117,110,116,111,110,115, + 101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97, + 116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,26,100,111,117, + 98,108,101,115,116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,46, + 115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109, + 111,114,121,0,4,108,101,102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tdoublereallisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.mfm b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.mfm new file mode 100644 index 0000000..99c6221 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.mfm @@ -0,0 +1,173 @@ +object doublestringlisteditor: tdoublestringlisteditor + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + bounds_x = 130 + bounds_y = 203 + bounds_cx = 338 + bounds_cy = 194 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 338 + 194 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat] + statfile = tstatfile1 + caption = 'Stringlisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 3 + bounds_x = 212 + bounds_y = 160 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + bounds_x = 276 + bounds_y = 160 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 8 + bounds_y = 8 + bounds_cx = 320 + bounds_cy = 140 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 31 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 3 + captions.items = < + item + caption = 'a' + textflags = [] + end + item + caption = 'b' + textflags = [] + end + item + end> + end> + datacols.count = 2 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[texta] + width = 137 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'texta' + dataclass = tgridmsestringdatalist + end + item[textb] + width = 145 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'textb' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object texta: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 137 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object textb: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 138 + bounds_y = 0 + bounds_cx = 145 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + end + object rowcount: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Rowcount' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 64 + 0 + ) + taborder = 1 + bounds_x = 36 + bounds_y = 160 + bounds_cx = 114 + anchors = [an_left, an_bottom] + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'doublestringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.pas b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.pas new file mode 100644 index 0000000..864a475 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.pas @@ -0,0 +1,59 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedoublestringlisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,mseedit,mseglob, + msegui,mseguiglob,mseifiglob,msememodialog,msemenus,msestrings,msetypes, + msedialog,msestat,msestatfile; +type + tdoublestringlisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + rowcount: tintegeredit; + textb: tmemodialogedit; + texta: tmemodialogedit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + msedoublestringlisteditor_mfm; + +{ tdoublestringlisteditor } + +constructor tdoublestringlisteditor.create(const aonclosequery: closequeryeventty); +begin + onclosequery:= aonclosequery; + inherited create(nil); +end; + +procedure tdoublestringlisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure tdoublestringlisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msedoublestringlisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor_mfm.pas new file mode 100644 index 0000000..337d024 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor_mfm.pas @@ -0,0 +1,219 @@ +unit msedoublestringlisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msedoublestringlisteditor; + +const + objdata: record size: integer; data: array[0..4037] of byte end = + (size: 4038; data: ( + 84,80,70,48,23,116,100,111,117,98,108,101,115,116,114,105,110,103,108,105, + 115,116,101,100,105,116,111,114,22,100,111,117,98,108,101,115,116,114,105,110, + 103,108,105,115,116,101,100,105,116,111,114,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110, + 0,8,98,111,117,110,100,115,95,120,3,130,0,8,98,111,117,110,100,115, + 95,121,3,203,0,9,98,111,117,110,100,115,95,99,120,3,82,1,9,98, + 111,117,110,100,115,95,99,121,3,194,0,23,99,111,110,116,97,105,110,101, + 114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97, + 110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,82,1,3,194,0,0,7,111,112,116,105, + 111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102, + 111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117, + 116,111,119,114,105,116,101,115,116,97,116,0,8,115,116,97,116,102,105,108, + 101,7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111, + 110,6,16,83,116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,15, + 109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115, + 101,102,111,114,109,0,7,116,98,117,116,116,111,110,2,111,107,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111, + 110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117, + 116,111,115,99,97,108,101,0,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,3,212,0,8,98,111,117,110,100,115,95,121, + 3,160,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110, + 100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97, + 116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75, + 11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98, + 117,116,116,111,110,6,99,97,110,99,101,108,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,8,98,111,117,110,100,115,95,120,3,20,1,8,98,111,117,110, + 100,115,95,121,3,160,0,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11, + 8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101, + 108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97, + 110,99,101,108,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116, + 97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,8, + 8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100,115,95,99, + 120,3,64,1,9,98,111,117,110,100,115,95,99,121,3,140,0,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109, + 0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111, + 108,115,105,122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103, + 15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95, + 114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100, + 101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108, + 111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116, + 114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10,111,103, + 95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117, + 112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0, + 13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120, + 99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,31, + 7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115, + 46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101, + 109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111, + 110,115,46,99,111,117,110,116,2,3,14,99,97,112,116,105,111,110,115,46, + 105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,1,97,9,116, + 101,120,116,102,108,97,103,115,11,0,0,1,7,99,97,112,116,105,111,110, + 6,1,98,9,116,101,120,116,102,108,97,103,115,11,0,0,1,0,0,0, + 0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100, + 97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97, + 99,111,108,115,46,105,116,101,109,115,14,7,5,116,101,120,116,97,1,5, + 119,105,100,116,104,3,137,0,7,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,5,116,101,120,116,97,9,100,97,116,97,99,108,97,115,115, + 7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97, + 108,105,115,116,0,7,5,116,101,120,116,98,1,5,119,105,100,116,104,3, + 145,0,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,5,116,101,120,116,98,9,100,97,116, + 97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105, + 110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119, + 104,101,105,103,104,116,2,16,17,111,110,114,111,119,99,111,117,110,116,99, + 104,97,110,103,101,100,7,21,103,114,105,100,111,110,114,111,119,99,111,117, + 110,116,99,104,97,110,103,101,100,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100, + 105,116,5,116,101,120,116,97,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101, + 105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99, + 111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0, + 0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114, + 4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105, + 109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,1,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 3,137,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14, + 111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111, + 101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108, + 121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,15, + 116,109,101,109,111,100,105,97,108,111,103,101,100,105,116,5,116,101,120,116, + 98,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10, + 102,114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0, + 0,144,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101, + 46,98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,20,102, + 114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2, + 17,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,138,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,145,0,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105, + 102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117, + 115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,8,114,111,119,99,111,117,110,116,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,8,82, + 111,119,99,111,117,110,116,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,64,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,36,8,98,111,117,110,100,115,95,121,3,160,0,9,98,111,117,110,100, + 115,95,99,120,2,114,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,9,97,110,95,98,111,116,116,111,109,0,10,111,110,115,101,116, + 118,97,108,117,101,7,18,114,111,119,99,111,117,110,116,111,110,115,101,116, + 118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116,102, + 105,108,101,49,8,102,105,108,101,110,97,109,101,6,26,100,111,117,98,108, + 101,115,116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,46,115,116, + 97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114, + 121,0,4,108,101,102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tdoublestringlisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msefaceselectorform.mfm b/mseide-msegui/lib/common/designutils/msefaceselectorform.mfm new file mode 100644 index 0000000..cbce007 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefaceselectorform.mfm @@ -0,0 +1,44 @@ +object faceselectorfo: tfaceselectorfo + visible = False + bounds_x = 126 + bounds_y = 231 + bounds_cx = 320 + bounds_cy = 244 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 320 + 244 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Face Selector' + moduleclassname = 'tmseform' + object lv: tlistview + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 320 + bounds_cy = 244 + anchors = [] + optionsgrid = [og_colsizing, og_rowsizing, og_focuscellonenter, og_savestate, og_colchangeontabkey, og_wraprow, og_wrapcol, og_autopopup, og_mousescrollcol] + options = [lvo_readonly, lvo_horz, lvo_drawfocus, lvo_leftbuttonfocusonly, lvo_focusselect, lvo_mouseselect, lvo_savestate] + itemlist.onpaintitem = paintitemexe + itemlist.captionpos = cp_bottom + itemlist.imagewidth = 16 + itemlist.imageheight = 16 + statfile = tstatfile1 + onlayoutchanged = layoutcha + onitemevent = itemev + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'faceselector.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 72 + top = 48 + end +end diff --git a/mseide-msegui/lib/common/designutils/msefaceselectorform.pas b/mseide-msegui/lib/common/designutils/msefaceselectorform.pas new file mode 100644 index 0000000..b8cf375 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefaceselectorform.pas @@ -0,0 +1,109 @@ +{ MSEide Copyright (c) 1999-2015 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msefaceselectorform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msedataedits, + msedatanodes,mseedit,msegrids,mselistbrowser,msestrings,msetypes,msebitmap, + msestatfile; +type + tfaceselectorfo = class(tmseform) + lv: tlistview; + tstatfile1: tstatfile; + procedure itemev(const sender: tcustomlistview; const index: Integer; + var info: celleventinfoty); + procedure paintitemexe(const sender: titemviewlist; const canvas: tcanvas; + const item: tlistedititem); + procedure layoutcha(const sender: tcustomlistview); + private + ffacelist: tfacelist; + ffacenr: integer; + public + constructor create(const aowner: tcomponent; const afacelist: tfacelist; + var afacenr: integer); reintroduce; + end; +implementation +uses + msefaceselectorform_mfm,sysutils,mseformatstr; + +{ tfaceselectorfo } + +constructor tfaceselectorfo.create(const aowner: tcomponent; + const afacelist: tfacelist; var afacenr: integer); +var + int1: integer; +begin + if afacelist <> nil then begin + ffacelist:= afacelist; + ffacenr:= afacenr; + inherited create(aowner); +{ + with lv do begin + int1:= aimagelist.width + 2; + if int1 < 20 then begin + int1:= 20; + end; + cellwidth:= int1; + cellheight:= aimagelist.height + font.lineheight + 3; + cellsize:= ms(35,40); + end; +} + with lv.itemlist do begin +// imagelist:= aimagelist; + count:= afacelist.list.count; +// imagewidth:= aimagelist.width; +// imageheight:= aimagelist.height+2; + for int1:= 0 to count -1 do begin + with items[int1] do begin + imagenr:= int1; + caption:= inttostrmse(int1); + end; + end; + end; + lv.focusedindex:= ffacenr; + show(true); + afacenr:= ffacenr; + end; + release; +end; + +procedure tfaceselectorfo.itemev(const sender: tcustomlistview; + const index: Integer; var info: celleventinfoty); +begin + if iscellclick(info) then begin + ffacenr:= index; + window.modalresult:= mr_ok; + end; +end; + +procedure tfaceselectorfo.paintitemexe(const sender: titemviewlist; + const canvas: tcanvas; const item: tlistedititem); +begin + if ffacelist <> nil then begin + ffacelist.paint(canvas,item.index,sender.layoutinfo.imagerect); + end; +end; + +procedure tfaceselectorfo.layoutcha(const sender: tcustomlistview); +begin + sender.itemlist.imagesize:= + ms(sender.cellwidth,sender.cellheight-sender.font.glyphheight-2); +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msefaceselectorform_mfm.pas b/mseide-msegui/lib/common/designutils/msefaceselectorform_mfm.pas new file mode 100644 index 0000000..60a3e56 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefaceselectorform_mfm.pas @@ -0,0 +1,70 @@ +unit msefaceselectorform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefaceselectorform; + +const + objdata: record size: integer; data: array[0..1056] of byte end = + (size: 1057; data: ( + 84,80,70,48,15,116,102,97,99,101,115,101,108,101,99,116,111,114,102,111, + 14,102,97,99,101,115,101,108,101,99,116,111,114,102,111,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,126,8,98,111,117,110, + 100,115,95,121,3,231,0,9,98,111,117,110,100,115,95,99,120,3,64,1, + 9,98,111,117,110,100,115,95,99,121,3,244,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110, + 101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,64,1,3,244,0, + 0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101,101,110, + 99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111,110,101, + 115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102, + 111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115, + 97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114, + 12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102, + 105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116, + 105,111,110,6,13,70,97,99,101,32,83,101,108,101,99,116,111,114,15,109, + 111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101, + 102,111,114,109,0,9,116,108,105,115,116,118,105,101,119,2,108,118,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,64,1,9,98,111,117,110,100,115,95, + 99,121,3,244,0,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105, + 111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110, + 103,12,111,103,95,114,111,119,115,105,122,105,110,103,19,111,103,95,102,111, + 99,117,115,99,101,108,108,111,110,101,110,116,101,114,12,111,103,95,115,97, + 118,101,115,116,97,116,101,20,111,103,95,99,111,108,99,104,97,110,103,101, + 111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,114,111,119,10, + 111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111, + 112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111, + 108,0,7,111,112,116,105,111,110,115,11,12,108,118,111,95,114,101,97,100, + 111,110,108,121,8,108,118,111,95,104,111,114,122,13,108,118,111,95,100,114, + 97,119,102,111,99,117,115,23,108,118,111,95,108,101,102,116,98,117,116,116, + 111,110,102,111,99,117,115,111,110,108,121,15,108,118,111,95,102,111,99,117, + 115,115,101,108,101,99,116,15,108,118,111,95,109,111,117,115,101,115,101,108, + 101,99,116,13,108,118,111,95,115,97,118,101,115,116,97,116,101,0,20,105, + 116,101,109,108,105,115,116,46,111,110,112,97,105,110,116,105,116,101,109,7, + 12,112,97,105,110,116,105,116,101,109,101,120,101,19,105,116,101,109,108,105, + 115,116,46,99,97,112,116,105,111,110,112,111,115,7,9,99,112,95,98,111, + 116,116,111,109,19,105,116,101,109,108,105,115,116,46,105,109,97,103,101,119, + 105,100,116,104,2,16,20,105,116,101,109,108,105,115,116,46,105,109,97,103, + 101,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105,108,101,7,10, + 116,115,116,97,116,102,105,108,101,49,15,111,110,108,97,121,111,117,116,99, + 104,97,110,103,101,100,7,9,108,97,121,111,117,116,99,104,97,11,111,110, + 105,116,101,109,101,118,101,110,116,7,6,105,116,101,109,101,118,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,116,97, + 116,102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108, + 101,110,97,109,101,6,16,102,97,99,101,115,101,108,101,99,116,111,114,46, + 115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109, + 111,114,121,17,115,102,111,95,97,99,116,105,118,97,116,111,114,114,101,97, + 100,18,115,102,111,95,97,99,116,105,118,97,116,111,114,119,114,105,116,101, + 0,4,108,101,102,116,2,72,3,116,111,112,2,48,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfaceselectorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msefadeedit.mfm b/mseide-msegui/lib/common/designutils/msefadeedit.mfm new file mode 100644 index 0000000..55c3c77 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefadeedit.mfm @@ -0,0 +1,653 @@ +object fadeeditfo: tfadeeditfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 150 + bounds_y = 221 + bounds_cx = 519 + bounds_cy = 443 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 519 + 443 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = formstatfile + caption = 'Fade Edit' + windowopacity = -Inf + oncreate = createev + moduleclassname = 'tmseform' + object cont2: tsimplewidget + visible = True + bounds_x = 0 + bounds_y = 0 + bounds_cx = 519 + bounds_cy = 402 + anchors = [an_top, an_bottom] + object cont1: tsimplewidget + visible = True + bounds_x = 0 + bounds_y = 73 + bounds_cx = 519 + bounds_cy = 330 + anchors = [an_top, an_bottom] + object tsimplewidget7: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -1610612731 + face.fade_direction = gd_down + face.localprops = [fal_fadirection] + taborder = 5 + visible = True + bounds_x = 444 + bounds_y = 56 + bounds_cx = 66 + bounds_cy = 273 + anchors = [an_top, an_right, an_bottom] + end + object gridlayout: tlayouter + bounds_x = 8 + bounds_y = 56 + bounds_cx = 431 + bounds_cy = 274 + bounds_cymin = 90 + anchors = [an_left, an_top, an_right, an_bottom] + object opagrid: twidgetgrid + Tag = 1 + frame.caption = 'Opacity' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 147 + bounds_cx = 433 + bounds_cy = 126 + anchors = [an_left, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autoappend, og_sorted, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 22 + numstep = 1 + end> + datacols.count = 3 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item + colorselect = -2147483642 + width = 24 + onbeforedrawcell = beforedrawev + options = [co_nofocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_mousescrollrow] + end + item[opaposed] + width = 89 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'opapos' + widgetname = 'opaposed' + dataclass = tgridrealdatalist + end + item[opacolored] + width = 290 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 63 + name = 'opacolor' + widgetname = 'opacolored' + dataclass = tgridenumdatalist + end> + datarowheight = 16 + statfile = fadestatfile + onrowsinserted = rowinsertev + onrowsdeleted = rowdeleteev + oncellevent = gridcellev + reffontheight = 14 + object opaposed: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 25 + bounds_y = 0 + bounds_cx = 89 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = dataenteterev + value = -Inf + valuedefault = -Inf + formatedit = '0.000' + formatdisp = '0.000' + valuerange = 1 + valuestart = 0 + valuemin = 0 + valuemax = 1 + reffontheight = 14 + end + object opacolored: tcoloredit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + color = -1879048187 + imagenr = 17 + end> + frame.buttonellipse.color = -1879048187 + frame.buttonellipse.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 115 + bounds_y = 0 + bounds_cx = 290 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue, oe1_thumbtrack] + ondataentered = dataenteterev + valuedefault = -1610612731 + reffontheight = 14 + end + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 433 + bounds_cy = 144 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autoappend, og_sorted, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 22 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 4 + captions.items = < + item + end + item + caption = 'Pos' + end + item + caption = 'Color' + end + item + caption = 'Opacity' + end> + end> + datacols.count = 4 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item + colorselect = -2147483642 + width = 24 + onbeforedrawcell = beforedrawev + options = [co_nofocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_mousescrollrow] + end + item[posed] + width = 89 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'posed' + dataclass = tgridrealdatalist + end + item[colored] + width = 151 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 63 + widgetname = 'colored' + dataclass = tgridenumdatalist + end + item[opaed] + width = 138 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'opaed' + dataclass = tgridenumdatalist + end> + datarowheight = 16 + statfile = fadestatfile + onrowsinserted = rowinsertev + onrowsdeleted = rowdeleteev + oncellevent = gridcellev + reffontheight = 14 + object posed: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 25 + bounds_y = 0 + bounds_cx = 89 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = dataenteterev + value = -Inf + valuedefault = -Inf + formatedit = '0.000' + formatdisp = '0.000' + valuerange = 1 + valuestart = 0 + valuemin = 0 + valuemax = 1 + reffontheight = 14 + end + object colored: tcoloredit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + color = -1879048187 + imagenr = 17 + end> + frame.buttonellipse.color = -1879048187 + frame.buttonellipse.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 115 + bounds_y = 0 + bounds_cx = 151 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue, oe1_thumbtrack] + ondataentered = dataenteterev + valuedefault = -1610612731 + reffontheight = 14 + end + object opaed: tcoloredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + color = -1879048187 + imagenr = 17 + end> + frame.buttonellipse.color = -1879048187 + frame.buttonellipse.imagenr = 17 + taborder = 3 + visible = False + bounds_x = 267 + bounds_y = 0 + bounds_cx = 138 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue, oe1_thumbtrack] + ondataentered = dataenteterev + valuedefault = -1610612730 + reffontheight = 14 + end + end + object splitter: tsplitter + color = -1879048189 + taborder = 2 + bounds_x = 0 + bounds_y = 144 + bounds_cx = 431 + bounds_cy = 3 + anchors = [an_top] + options = [spo_vmove, spo_vprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linktop = grid + linkbottom = opagrid + statfile = formstatfile + end + end + object posedit: tpickwidget + optionswidget = [ow_destroywidgets] + frame.leveli = -1 + frame.framei_bottom = 2 + frame.localprops = [frl_leveli, frl_fibottom] + frame.localprops1 = [] + taborder = 2 + onpaint = pospaintev + bounds_x = 8 + bounds_y = 0 + bounds_cx = 504 + bounds_cy = 50 + anchors = [an_left, an_top, an_right] + onclientmouseevent = mouseev + onresize = resizeev + ongetcursorshape = getcursorshapeev + ongetpickobjects = getpickobjectev + onendpickmove = endpickev + onpaintxorpic = paintxorev + object tsimplewidget3: tsimplewidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousetransparent, ow_destroywidgets] + color = -1610612731 + face.localprops = [] + taborder = 3 + visible = True + bounds_x = 1 + bounds_y = 1 + bounds_cx = 502 + bounds_cy = 40 + anchors = [an_top] + end + object tsimplewidget2: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -1610612730 + taborder = 1 + visible = True + bounds_x = 1 + bounds_y = 0 + bounds_cx = 502 + bounds_cy = 13 + anchors = [an_top] + end + object tsimplewidget4: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -1610612734 + taborder = 2 + visible = True + bounds_x = 1 + bounds_y = 27 + bounds_cx = 502 + bounds_cy = 13 + anchors = [an_top] + end + object fadedisp: tsimplewidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousetransparent, ow_destroywidgets] + color = -2147483645 + face.localprops = [] + visible = True + bounds_x = 1 + bounds_y = 0 + bounds_cx = 502 + bounds_cy = 40 + anchors = [an_top] + end + end + object tsimplewidget5: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -1610612734 + taborder = 3 + visible = True + bounds_x = 445 + bounds_y = 56 + bounds_cx = 23 + bounds_cy = 273 + anchors = [an_top, an_right, an_bottom] + end + object tsimplewidget6: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -1610612730 + taborder = 4 + visible = True + bounds_x = 489 + bounds_y = 56 + bounds_cx = 22 + bounds_cy = 273 + anchors = [an_top, an_right, an_bottom] + end + object fadevert: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -2147483645 + frame.leveli = -1 + frame.localprops = [frl_leveli] + frame.localprops1 = [] + face.fade_direction = gd_down + face.localprops = [fal_fadirection] + taborder = 1 + visible = True + bounds_x = 444 + bounds_y = 56 + bounds_cx = 68 + bounds_cy = 274 + anchors = [an_top, an_right, an_bottom] + end + end + object opaedit: tpickwidget + Tag = 1 + optionswidget = [ow_destroywidgets] + frame.options = [cfo_fixtop] + frame.leveli = -1 + frame.framei_bottom = 2 + frame.caption = 'Opacity' + frame.localprops = [frl_leveli, frl_fibottom] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onpaint = pospaintev + bounds_x = 8 + bounds_y = 0 + bounds_cx = 504 + bounds_cy = 67 + bounds_cxmin = 461 + anchors = [an_left, an_top, an_right] + onclientmouseevent = mouseev + onresize = resizeev + ongetcursorshape = getcursorshapeev + ongetpickobjects = getpickobjectev + onendpickmove = endpickev + onpaintxorpic = paintxorev + object opadisp: tsimplewidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousetransparent, ow_destroywidgets] + color = -2147483645 + face.localprops = [] + visible = True + bounds_x = 1 + bounds_y = 17 + bounds_cx = 502 + bounds_cy = 40 + anchors = [an_top] + end + end + end + object bottomlayout: tlayouter + taborder = 1 + bounds_x = 8 + bounds_y = 407 + bounds_cx = 504 + bounds_cy = 31 + anchors = [an_left, an_right, an_bottom] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_center + place_mindist = 5 + linktop = cont2 + dist_top = 5 + options = [spao_gluebottom] + object switchlayout: tlayouter + bounds_x = 0 + bounds_y = 0 + bounds_cx = 142 + bounds_cy = 30 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_center + place_mindist = 5 + object splitopa: tbooleanedit + frame.caption = 'Separate'#10'Opacity' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 8 + 61 + 9 + ) + bounds_x = 68 + bounds_y = 0 + bounds_cx = 74 + bounds_cy = 30 + onsetvalue = sepopaset + end + object reverse: tbooleanedit + frame.caption = '&reverse' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 50 + 2 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 7 + bounds_cx = 63 + bounds_cy = 16 + ondataentered = reverseenteredev + end + end + object buttonlayout: tlayouter + taborder = 1 + bounds_x = 176 + bounds_y = 0 + bounds_cx = 328 + bounds_cy = 31 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex] + place_mindist = 5 + object tbutton2: tbutton + optionswidget1 = [ow1_autoscale, ow1_autowidth] + bounds_x = 270 + bounds_y = 0 + bounds_cx = 58 + bounds_cy = 31 + bounds_cxmin = 58 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_canclose + end + object tbutton1: tbutton + optionswidget1 = [ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 207 + bounds_y = 0 + bounds_cx = 58 + bounds_cy = 31 + bounds_cxmin = 58 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object tsimplewidget1: tsimplewidget + taborder = 2 + bounds_x = 198 + bounds_y = 8 + bounds_cx = 4 + bounds_cy = 18 + end + object tbutton3: tbutton + optionswidget1 = [ow1_autoscale, ow1_autowidth] + taborder = 3 + bounds_x = 135 + bounds_y = 0 + bounds_cx = 58 + bounds_cy = 31 + bounds_cxmin = 58 + state = [as_localcaption, as_localonexecute] + caption = '&Save' + onexecute = saveex + end + object tbutton4: tbutton + optionswidget1 = [ow1_autoscale, ow1_autowidth] + taborder = 4 + bounds_x = 72 + bounds_y = 0 + bounds_cx = 58 + bounds_cy = 31 + bounds_cxmin = 58 + state = [as_localcaption, as_localonexecute] + caption = '&Load' + onexecute = loadex + end + object clearbu: tbutton + optionswidget1 = [ow1_autoscale, ow1_autowidth] + taborder = 5 + hint = 'Clear opacity gradient' + bounds_x = 0 + bounds_y = 0 + bounds_cx = 67 + bounds_cy = 31 + bounds_cxmin = 58 + state = [as_disabled, as_localdisabled, as_localcaption, as_localhint, as_localonexecute] + caption = 'ClearOpa' + onexecute = clearopaexe + end + end + end + object formstatfile: tstatfile + filename = 'fadeeditor.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 96 + top = 200 + end + object filedialog: tfiledialog + statfile = formstatfile + controller.filterlist.data = ( + ( + 'Fade Files' + '*.fad' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'fad' + controller.options = [fdo_checkexist, fdo_savelastdir] + controller.captionopen = 'Load Fade File' + controller.captionsave = 'Save Fade File' + left = 208 + top = 240 + end + object fadestatfile: tstatfile + filename = 'status.sta' + onstatupdate = fadestatupdateexe + left = 200 + top = 200 + end + object c: tstringcontainer + strings.data = ( + 'Do you want to synchronize opacity gradient' + 'with color gradient?' + 'Do you want to remove opacity gradient?' + ) + left = 88 + top = 344 + end +end diff --git a/mseide-msegui/lib/common/designutils/msefadeedit.pas b/mseide-msegui/lib/common/designutils/msefadeedit.pas new file mode 100644 index 0000000..bcbbfe0 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefadeedit.pas @@ -0,0 +1,1031 @@ +unit msefadeedit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msepickwidget,mseimage,msetypes, + msepointer,msewidgets,msedataedits,mseedit,msegrids,msestrings,msewidgetgrid, + msecolordialog,mseeditglob,msesimplewidgets,{msepropertyeditors,}msestatfile, + msegraphedits,msebitmap,msedatanodes,msefiledialog,mselistbrowser,msesys, + msegridsglob,mseobjectpicker,mseifiglob,msearrayprops,msesplitter, + msestringcontainer,mseificomp,mseificompglob,msescrollbar; + +type + nodeinfoty = record + nodepos: integerarty; + marker: pointarty; + grid: tcustomgrid; + posed: trealedit; + colored: tcoloredit; + opaed: tcoloredit; + end; + pnodeinfoty = ^nodeinfoty; + + tfadeeditfo = class(tmseform) + formstatfile: tstatfile; + filedialog: tfiledialog; + fadestatfile: tstatfile; + cont2: tsimplewidget; + cont1: tsimplewidget; + tsimplewidget7: tsimplewidget; + gridlayout: tlayouter; + opagrid: twidgetgrid; + opaposed: trealedit; + opacolored: tcoloredit; + grid: twidgetgrid; + posed: trealedit; + colored: tcoloredit; + opaed: tcoloredit; + splitter: tsplitter; + posedit: tpickwidget; + tsimplewidget3: tsimplewidget; + tsimplewidget2: tsimplewidget; + tsimplewidget4: tsimplewidget; + fadedisp: tsimplewidget; + tsimplewidget5: tsimplewidget; + tsimplewidget6: tsimplewidget; + fadevert: tsimplewidget; + opaedit: tpickwidget; + opadisp: tsimplewidget; + c: tstringcontainer; + bottomlayout: tlayouter; + switchlayout: tlayouter; + splitopa: tbooleanedit; + reverse: tbooleanedit; + buttonlayout: tlayouter; + tbutton2: tbutton; + tbutton1: tbutton; + tsimplewidget1: tsimplewidget; + tbutton3: tbutton; + tbutton4: tbutton; + clearbu: tbutton; + procedure mouseev(const sender: twidget; var info: mouseeventinfoty); + procedure pospaintev(const sender: twidget; const canvas: tcanvas); + procedure createev(const sender: TObject); + procedure getcursorshapeev(const sender: tcustompickwidget; + const picker: tobjectpicker; + var shape: cursorshapety; var found: Boolean); + procedure getpickobjectev(const sender: tcustompickwidget; + const picker: tobjectpicker; + var objects: integerarty); + procedure paintxorev(const sender: tcustompickwidget; + const picker: tobjectpicker; const canvas: tcanvas); + procedure endpickev(const sender: tcustompickwidget; + const picker: tobjectpicker); + procedure resizeev(const sender: TObject); + procedure dataenteterev(const sender: TObject); + procedure rowdeleteev(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); + procedure gridcellev(const sender: TObject; var info: celleventinfoty); + procedure rowinsertev(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); + procedure beforedrawev(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure reverseenteredev(const sender: TObject); + procedure saveex(const sender: TObject); + procedure loadex(const sender: TObject); + procedure clearopaexe(const sender: TObject); + procedure fadestatupdateexe(const sender: TObject; const filer: tstatfiler); + procedure sepopaset(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + private + fnodeinfo: nodeinfoty; + fnodeinfoopa: nodeinfoty; +// ffadepos,ffadeopapos: trealarrayprop; +// ffadecolor,ffadeopacolor: tcolorarrayprop; + fopacitycleared: boolean; + fopa: boolean; + fopasynced: boolean; + procedure movemarker(const atag: integer; apos: integer); + function findmarker(const atag: integer; const apos: pointty): integer; + //-1 if not found + function limitmarkerpos(const atag: integer; const index: integer; + const aoffset: integer): integer; + procedure setopasynced(const avalue: boolean); + protected + function nodeinfo(const atag: integer): pnodeinfoty; + function syncexe: boolean; + procedure change; + procedure doasyncevent(var atag: integer); override; + property opasynced: boolean read fopasynced write setopasynced; + end; + + +function editfade(var fadedirection: graphicdirectionty; const opa: boolean; + const fadepos,fadeopapos: trealarrayprop; + const fadecolor,fadeopacolor: tcolorarrayprop): modalresultty; + +implementation + +uses + msefadeedit_mfm,msedatalist,msearrayutils; +type + stringconsts = ( + sc_syncopa, //0 + sc_withcolor, //1 + sc_removeopacity //2 + ); + +function editfade(var fadedirection: graphicdirectionty; const opa: boolean; + const fadepos,fadeopapos: trealarrayprop; + const fadecolor,fadeopacolor: tcolorarrayprop): modalresultty; +var + form1: tfadeeditfo; + int1: integer; + bo1: boolean; +begin + form1:= tfadeeditfo.create(nil); + try + with form1 do begin + fopa:= opa; +// ffadepos:= fadepos; +// ffadeopapos:= fadeopapos; +// ffadecolor:= fadecolor; +// ffadeopacolor:= fadeopacolor; + reverse.value:= fadedirection in [gd_left,gd_up]; + end; + if opa then begin + form1.grid.rowcount:= fadeopapos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fadeopapos[int1]; + form1.colored[int1]:= fadeopacolor[int1]; + end; + form1.fopacitycleared:= true; + form1.splitopa.enabled:= false; + form1.opasynced:= true; + end + else begin + bo1:= (fadepos.count = fadeopapos.count) and (fadepos.count <> 0); + form1.grid.rowcount:= fadepos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fadepos[int1]; + form1.colored[int1]:= fadecolor[int1]; + bo1:= bo1 and (fadepos[int1] = fadeopapos[int1]); + end; + if bo1 then begin + for int1:= 0 to form1.grid.rowhigh do begin + form1.opaed[int1]:= fadeopacolor[int1]; + bo1:= bo1 and (fadepos[int1] = fadeopapos[int1]); + end; + end; + form1.fopacitycleared:= fadeopapos.count = 0; + bo1:= bo1 or form1.fopacitycleared; +// form1.splitopa.value:= bo1; + form1.clearbu.enabled:= bo1 and not form1.fopacitycleared; + form1.opasynced:= bo1; + form1.opagrid.rowcount:= fadeopapos.count; + for int1:= 0 to form1.opagrid.rowhigh do begin + form1.opaposed[int1]:= fadeopapos[int1]; + form1.opacolored[int1]:= fadeopacolor[int1]; + end; + form1.grid.datacols[3].visible:= bo1 and not form1.fopacitycleared; + end; + form1.change; + result:= form1.show(true); + if result = mr_ok then begin + if form1.reverse.value then begin + if fadedirection = gd_right then begin + fadedirection:= gd_left; + end + else begin + if fadedirection <> gd_left then begin + fadedirection:= gd_up; + end; + end; + end + else begin + if fadedirection = gd_left then begin + fadedirection:= gd_right; + end + else begin + if fadedirection <> gd_right then begin + fadedirection:= gd_down; + end; + end; + end; + if opa then begin + fadeopapos.assign(form1.fadedisp.face.fade_pos); + fadeopacolor.assign(form1.fadedisp.face.fade_color); + end + else begin + fadepos.assign(form1.fadedisp.face.fade_pos); + fadecolor.assign(form1.fadedisp.face.fade_color); + fadeopapos.assign(form1.fadedisp.face.fade_opapos); + fadeopacolor.assign(form1.fadedisp.face.fade_opacolor); + end; + end; + finally + form1.free; + end; +end; + +{ +procedure editfacefade(const aproperty: tpropertyeditor; const trans: boolean); +var + form1: tfadeeditfo; + int1: integer; + bo1: boolean; +begin + form1:= tfadeeditfo.create(nil); + try + with tcustomface(tpropertyeditor1(aproperty).instance) do begin + form1.reverse.value:= fade_direction in [gd_left,gd_up]; + if trans then begin + form1.grid.rowcount:= fade_transpos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fade_transpos[int1]; + form1.colored[int1]:= fade_transcolor[int1]; + end; + end + else begin + bo1:= fade_pos.count = fade_transpos.count; + form1.grid.rowcount:= fade_pos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fade_pos[int1]; + form1.colored[int1]:= fade_color[int1]; + bo1:= bo1 and (fade_pos[int1] = fade_transpos[int1]); + end; + if bo1 then begin + for int1:= 0 to form1.grid.rowhigh do begin + form1.transed[int1]:= fade_transcolor[int1]; + bo1:= bo1 and (fade_pos[int1] = fade_transpos[int1]); + end; + end; + syncbu.enabled:= not bo1; + end; + form1.change; + end; + if form1.show(true) = mr_ok then begin + with tpropertyeditor1(aproperty) do begin + for int1:= 0 to count - 1 do begin + with tcustomface(instance(int1)) do begin + if form1.reverse.value then begin + if fade_direction = gd_right then begin + fade_direction:= gd_left; + end + else begin + if fade_direction <> gd_left then begin + fade_direction:= gd_up; + end; + end; + end + else begin + if fade_direction = gd_left then begin + fade_direction:= gd_right; + end + else begin + if fade_direction <> gd_right then begin + fade_direction:= gd_down; + end; + end; + end; + if trans then begin + fade_transpos.assign(form1.fadedisp.face.fade_pos); + fade_transcolor.assign(form1.fadedisp.face.fade_color); + end + else begin + fade_pos.assign(form1.fadedisp.face.fade_pos); + fade_color.assign(form1.fadedisp.face.fade_color); + end; + end; + end; + modified; + end; + end; + finally + form1.free; + end; +end; +} + +{ +procedure editfacetemplatefade(const aproperty: tpropertyeditor; + const trans: boolean); +var + form1: tfadeeditfo; + int1: integer; +begin + form1:= tfadeeditfo.create(nil); + try + with tfacetemplate(tpropertyeditor1(aproperty).instance) do begin + form1.reverse.value:= fade_direction in [gd_left,gd_up]; + if trans then begin + form1.grid.rowcount:= fade_transpos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fade_transpos[int1]; + form1.colored[int1]:= fade_transcolor[int1]; + end; + end + else begin + form1.grid.rowcount:= fade_pos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fade_pos[int1]; + form1.colored[int1]:= fade_color[int1]; + end; + end; + form1.change; + end; + if form1.show(true) = mr_ok then begin + with tpropertyeditor1(aproperty) do begin + for int1:= 0 to count - 1 do begin + with tfacetemplate(instance(int1)) do begin + if form1.reverse.value then begin + if fade_direction = gd_right then begin + fade_direction:= gd_left; + end + else begin + if fade_direction <> gd_left then begin + fade_direction:= gd_up; + end; + end; + end + else begin + if fade_direction = gd_left then begin + fade_direction:= gd_right; + end + else begin + if fade_direction <> gd_right then begin + fade_direction:= gd_down; + end; + end; + end; + if trans then begin + fade_transpos.assign(form1.fadedisp.face.fade_pos); + fade_transcolor.assign(form1.fadedisp.face.fade_color); + end + else begin + fade_pos.assign(form1.fadedisp.face.fade_pos); + fade_color.assign(form1.fadedisp.face.fade_color); + end; + end; + end; + modified; + end; + end; + finally + form1.free; + end; +end; +} +{ tfadeeditfo } + +const + markerhalfwidth = 2; + markerheight = markerhalfwidth+1; + +procedure tfadeeditfo.mouseev(const sender: twidget; var info: mouseeventinfoty); +var + ar1: integerarty; + int1,int2: integer; + rea1,rea2,rea3: realty; + rect1: rectty; + posx: integer; +begin + if (info.pos.y < fadedisp.height) and sender.isleftbuttondown(info) then begin + if reverse.value then begin + posx:= posedit.paintsize.cx - info.pos.x; + end + else begin + posx:= info.pos.x; + end; + with nodeinfo(sender.tag)^ do begin + additem(nodepos,posx); + sortarray(nodepos,ar1); + if grid.rowcount < 2 then begin + int1:= grid.rowcount; + grid.rowcount:= 2; + posed[0]:= 0; + posed[1]:= 1; + if int1 < 1 then begin + colored[0]:= defaultfadecolor; + end; + if int1 < 2 then begin + colored[1]:= defaultfadecolor1; + end; + end; + int1:= 0; + for int2 := 0 to high(ar1) do begin + if ar1[int2] = high(ar1) then begin + int1:= int2 + 1; //grid row + break; + end; + end; + grid.beginupdate; + grid.onrowsinserted:= nil; + grid.insertrow(int1); + grid.onrowsinserted:= {$ifdef FPC}@{$endif}rowinsertev; + rect1:= posedit.innerclientrect; + if rect1.cx = 0 then begin + rea1:= 0; + end + else begin + rea1:= (posx - rect1.x) / rect1.cx; + end; + if rea1 < posed[int1-1] then begin + rea1:= posed[int1-1]; + end; + if rea1 > posed[int1+1] then begin + rea1:= posed[int1+1]; + end; + posed[int1]:= rea1; + rea2:= posed[int1+1] - posed[int1-1]; + if rea2 = 0 then begin + rea3:= 0; + end + else begin + rea3:= (rea1 - posed[int1-1]) / rea2; + end; + grid.row:= int1; + grid.focuscell(makegridcoord(1,int1)); + colored[int1]:= blendcolor(rea3,colored[int1-1],colored[int1+1]); + if opaed <> nil then begin + opaed[int1]:= blendcolor(rea3,opaed[int1-1],opaed[int1+1]); + end; + grid.endupdate; + change; + grid.setfocus; + end; + end; +end; + +procedure tfadeeditfo.createev(const sender: TObject); +var + rect1: rectty; +begin + rect1:= posedit.innerclientrect; + with fnodeinfo do begin + grid:= self.grid; + posed:= self.posed; + colored:= self.colored; + opaed:= self.opaed; + setlength(marker,3); + marker[0].y:= rect1.y + rect1.cy - 1; + marker[1].y:= marker[0].y - markerheight; + marker[2].y:= marker[0].y; + end; + with fnodeinfoopa do begin + grid:= self.opagrid; + posed:= self.opaposed; + colored:= self.opacolored; + opaed:= nil; + marker:= copy(fnodeinfo.marker); + end; +end; + +procedure tfadeeditfo.movemarker(const atag: integer; apos: integer); +begin + if reverse.value then begin + apos:= posedit.paintsize.cx - apos; + end; + with nodeinfo(atag)^ do begin + marker[0].x:= apos - markerhalfwidth; + marker[1].x:= apos; + marker[2].x:= apos + markerhalfwidth; + end; +end; + +procedure tfadeeditfo.change; +var + rect1: rectty; + + procedure update(var anodeinfo: nodeinfoty); + var + int1: integer; + begin + with anodeinfo do begin + if grid.rowcount < 3 then begin + nodepos:= nil; + end + else begin + setlength(nodepos,grid.rowcount - 2); + end; + if grid.rowcount > 0 then begin + posed[grid.rowhigh]:= 1; + posed[0]:= 0; + end; + for int1:= 1 to grid.rowcount - 2 do begin + nodepos[int1-1]:= rect1.x + round(posed[int1] * rect1.cx); + end; + end; + end;//update + +var + int1: integer; +// rea1: real; +begin + if reverse.value then begin + fadedisp.face.fade_direction:= gd_left; + opadisp.face.fade_direction:= gd_left; + fadevert.face.fade_direction:= gd_up; + end + else begin + fadedisp.face.fade_direction:= gd_right; + opadisp.face.fade_direction:= gd_right; + fadevert.face.fade_direction:= gd_down; + end; + rect1:= posedit.innerclientrect; + with fadedisp.face do begin + fade_pos.count:= grid.rowcount; + if grid.datacols[3].visible then begin + fade_opapos.count:= grid.rowcount; + for int1:= grid.rowhigh downto 0 do begin + fade_pos[int1]:= posed[int1]; + fade_color[int1]:= colored[int1]; + fade_opapos[int1]:= posed[int1]; + fade_opacolor[int1]:= opaed[int1]; + end; + end + else begin + for int1:= grid.rowhigh downto 0 do begin + fade_pos[int1]:= posed[int1]; + fade_color[int1]:= colored[int1]; + end; + if fopacitycleared then begin + fade_opapos.count:= 0; + opagrid.clear; + end + else begin + fade_opapos.count:= opagrid.rowcount; + for int1:= opagrid.rowhigh downto 0 do begin + fade_opapos[int1]:= opaposed[int1]; + fade_opacolor[int1]:= opacolored[int1]; + end; + end; + end; + fadevert.face.fade_pos.assign(fade_pos); + fadevert.face.fade_color.assign(fade_color); + fadevert.face.fade_opapos.assign(fade_opapos); + fadevert.face.fade_opacolor.assign(fade_opacolor); + opadisp.face.fade_pos.assign(fade_opapos); + opadisp.face.fade_color.assign(fade_opacolor); + end; + update(fnodeinfo); + update(fnodeinfoopa); + posedit.invalidate; + opaedit.invalidate; +end; + +procedure tfadeeditfo.pospaintev(const sender: twidget; const canvas: tcanvas); +var + int1: integer; +begin + with nodeinfo(sender.tag)^ do begin + for int1:= 0 to high(nodepos) do begin + movemarker(sender.tag,nodepos[int1]); + if int1 + 1 = grid.row then begin + canvas.drawlines(marker,true,cl_red); + end + else begin + canvas.drawlines(marker,true,cl_black); + end; + end; + end; +end; + +procedure tfadeeditfo.getcursorshapeev(const sender: tcustompickwidget; + const picker: tobjectpicker; + var shape: cursorshapety; var found: Boolean); +var +// rect1: rectty; + int1{,int2,int3}: integer; +begin +// if picker.shiftstate = [] then begin + int1:= findmarker(sender.tag,picker.pos); + if int1 >= 0 then begin + shape:= cr_sizehor; + found:= true; + end; +// end; +end; + +procedure tfadeeditfo.getpickobjectev(const sender: tcustompickwidget; + const picker: tobjectpicker; var objects: integerarty); +var + int1: integer; +begin + if picker.shiftstate = [ss_left] then begin + int1:= findmarker(sender.tag,picker.pickrect.pos); + if int1 >= 0 then begin + setlength(objects,1); + objects[0]:= int1; + end; + end; +end; + +function tfadeeditfo.findmarker(const atag: integer; + const apos: pointty): integer; +var + rect1: rectty; + int1,int2,int3,int4: integer; + xpos: integer; +begin + with nodeinfo(atag)^ do begin + result:= -1; + rect1:= posedit.innerclientrect; + int1:= rect1.y + rect1.cy; + int4:= high(nodepos); + if reverse.value then begin + xpos:= posedit.paintsize.cx - apos.x; + end + else begin + xpos:= apos.x; + end; + if (apos.y < int1) and (apos.y >= int1 - markerheight) then begin + int2:= xpos - markerhalfwidth; + int3:= int2 + 2 * markerhalfwidth + 1; + for int1:= 0 to int4 do begin + if (nodepos[int1] >= int2) and (nodepos[int1] <= int3) and + not ((int1 < int4) and (nodepos[int1+1] = rect1.x)) then begin + result:= int1; + break; + end; + end; + end; + end; +end; + +function tfadeeditfo.limitmarkerpos(const atag: integer; const index: integer; + const aoffset: integer): integer; +var + rect1: rectty; + +begin + with nodeinfo(atag)^ do begin + if reverse.value then begin + result:= nodepos[index] - aoffset; + end + else begin + result:= nodepos[index] + aoffset; + end; + if (index > 0) and (result < nodepos[index-1]) then begin + result:= nodepos[index-1]; + end + else begin + if index < high(nodepos) then begin + if result >= nodepos[index+1] then begin + result:= nodepos[index+1]; + end + else begin + if result < 0 then begin + result:= 0; + end; + end; + end + else begin + rect1:= posedit.innerclientrect; + rect1.x:= rect1.x + rect1.cx; + if result >= rect1.x then begin + result:= rect1.x - 1; + end; + end; + end; + end; +end; + +procedure tfadeeditfo.paintxorev(const sender: tcustompickwidget; + const picker: tobjectpicker; + const canvas: tcanvas); +begin + movemarker(sender.tag,limitmarkerpos(sender.tag,picker.currentobjects[0], + picker.pickoffset.x)); + with nodeinfo(sender.tag)^ do begin + canvas.drawlines(marker,true,cl_white); + canvas.drawline(makepoint(marker[1].x,marker[1].y-1), + makepoint(marker[1].x,posedit.innerclientpos.y),cl_white); + end; +end; + +procedure tfadeeditfo.endpickev(const sender: tcustompickwidget; + const picker: tobjectpicker); +var + int1: integer; + rect1: rectty; + rea1: real; + offsetx: integer; +begin + offsetx:= picker.pickoffset.x; + if reverse.value then begin + offsetx:= -offsetx; + end; + rect1:= sender.innerclientrect; + int1:= picker.currentobjects[0]; + with nodeinfo(sender.tag)^ do begin + if rect1.cx = 0 then begin + rea1:= 0; + end + else begin + rea1:= (nodepos[int1] - rect1.x + offsetx) / rect1.cx; + end; + if rea1 < posed[int1] then begin + rea1:= posed[int1]; + end; + if rea1 > posed[int1+2] then begin + rea1:= posed[int1+2]; + end; + posed[int1+1]:= rea1; + grid.focuscell(makegridcoord(1,int1+1)); + grid.setfocus; + end; + change; +end; + +procedure tfadeeditfo.resizeev(const sender: TObject); +begin + change; +end; + +procedure tfadeeditfo.dataenteterev(const sender: TObject); +begin + grid.sort; + opagrid.sort; + change; +end; + +procedure tfadeeditfo.rowdeleteev(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); +begin + if grid.rowcount > 0 then begin + posed[grid.rowhigh]:= 1; + posed[0]:= 0; + end; + change; +end; + +procedure tfadeeditfo.gridcellev(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if (eventkind = cek_enter) and (newcell.row <> cellbefore.row) then begin + if tmsecomponent(sender).tag = 0 then begin + posedit.invalidate; //redraw red marker + end + else begin + opaedit.invalidate; //redraw red marker + end; + end; + end; +end; + +procedure tfadeeditfo.rowinsertev(const sender: tcustomgrid; + const aindex: Integer; const acount: Integer); +begin + if sender.userinput then begin + with nodeinfo(sender.tag)^ do begin + grid.beginupdate; + if aindex < grid.rowhigh then begin + if aindex = 0 then begin + colored[0]:= colored[1]; //pos = 0 + if sender.tag = 0 then begin + opaed[0]:= opaed[1]; //pos = 0 + end; + posed[0]:= 0; + end + else begin + colored[aindex]:= blendcolor(0.5,colored[aindex+1],colored[aindex-1]); + if sender.tag = 0 then begin + opaed[aindex]:= blendcolor(0.5,opaed[aindex+1],opaed[aindex-1]); + end; + posed[aindex]:= (posed[aindex+1] + posed[aindex-1]) / 2; + end + end + else begin + if grid.rowhigh = 0 then begin + posed[aindex]:= 0; + end + else begin + colored[aindex]:= colored[grid.rowhigh-1]; + if sender.tag = 0 then begin + opaed[aindex]:= opaed[grid.rowhigh-1]; + end; + posed[aindex]:= 1; + end; + end; + grid.endupdate; + end; + change; + end + else begin + asyncevent; + end; +end; + +procedure tfadeeditfo.beforedrawev(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); +begin + if sender.grid.tag = 0 then begin + cellinfo.color:= colorty(colortorgb(colored[cellinfo.cell.row])); + end + else begin + cellinfo.color:= colorty(colortorgb(opacolored[cellinfo.cell.row])); + end; +end; + +procedure tfadeeditfo.reverseenteredev(const sender: TObject); +begin + change; +end; + +procedure tfadeeditfo.saveex(const sender: TObject); +begin + if filedialog.execute(fdk_save) = mr_ok then begin + fadestatfile.writestat(filedialog.controller.filename); + end; +end; + +procedure tfadeeditfo.loadex(const sender: TObject); +begin + if filedialog.execute(fdk_open) = mr_ok then begin + fadestatfile.readstat(filedialog.controller.filename); + change; + end; +end; + +procedure tfadeeditfo.doasyncevent(var atag: integer); +begin + inherited; + change; +end; + +function tfadeeditfo.syncexe: boolean; + + function scale(const apos,lopos,hipos: real; + const locolor,hicolor: colorty): colorty; + begin + if apos = lopos then begin + result:= locolor; + end + else begin + if apos = hipos then begin + result:= hicolor; + end + else begin + if lopos = hipos then begin + if locolor = hicolor then begin + result:= locolor; + end + else begin + result:= blendcolor(0.5,locolor,hicolor); + end; + end + else begin + result:= blendcolor((apos-lopos)/(hipos-lopos),locolor,hicolor); + end; + end; + end; + end; //scale + +var + int1,int2: integer; +begin + result:= askconfirmation(c[ord(sc_syncopa)]+lineend+c[ord(sc_withcolor)]); + if result then begin + grid.beginupdate; + try + fopacitycleared:= false; + int2:= 0; + if grid.rowcount < fadedisp.face.fade_opapos.count then begin + if grid.rowcount = 0 then begin + grid.rowcount:= 1; + posed[0]:= 0; + end; + if (grid.rowcount < 2) and (grid.rowcount < fadedisp.face.fade_opapos.count) then begin + grid.rowcount:= 2; + posed[1]:= 1; + colored[1]:= colored[0]; + end; + end; + for int1:= 1 to fadedisp.face.fade_opapos.count-2 do begin + while posed[int2] < fadedisp.face.fade_opapos[int1] do begin + inc(int2); + end; + if posed[int2] <> fadedisp.face.fade_opapos[int1] then begin + grid.insertrow(int2); + posed[int2]:= fadedisp.face.fade_opapos[int1]; + colored[int2]:= scale(posed[int2],posed[int2-1],posed[int2+1], + colored[int2-1],colored[int2+1]); + end; + end; + int2:= 0; + for int1:= 0 to grid.rowhigh do begin + while (int2 < fadedisp.face.fade_opapos.count) and + (fadedisp.face.fade_opapos[int2] < posed[int1]) do begin + inc(int2); + end; + case fadedisp.face.fade_opapos.count of + 0: begin + opaed[int1]:= cl_white; + end; + 1: begin + opaed[int1]:= fadedisp.face.fade_opacolor[0]; + end; + else begin + if int2 >= fadedisp.face.fade_opacolor.count then begin + opaed[int1]:= + fadedisp.face.fade_opacolor[fadedisp.face.fade_opacolor.count-1]; + end + else begin + if int2 = 0 then begin + opaed[int1]:= + fadedisp.face.fade_opacolor[0]; + end + else begin + opaed[int1]:= scale(posed[int1],fadedisp.face.fade_opapos[int2-1], + fadedisp.face.fade_opapos[int2], + fadedisp.face.fade_opacolor[int2-1], + fadedisp.face.fade_opacolor[int2]); + end; + end; + end; + end; + end; + grid.datacols[3].visible:= true; + finally + grid.endupdate; + end; +// syncbu.enabled:= false; + clearbu.enabled:= true; + change; + end; +end; + +procedure tfadeeditfo.clearopaexe(const sender: TObject); +begin + if askconfirmation(c[ord(sc_removeopacity)]) then begin + fopacitycleared:= true; + opasynced:= true; + grid.datacols[3].visible:= false; + change; + clearbu.enabled:= false; +// syncbu.enabled:= true; + end; +end; + +procedure tfadeeditfo.setopasynced(const avalue: boolean); +var + bo1: boolean; + int1: integer; +begin + fopasynced:= avalue or fopa; + grid.datacols[3].visible:= fopasynced; + bo1:= not fopasynced; + opaedit.visible:= bo1; + opagrid.visible:= bo1; + splitter.visible:= bo1; + if fopasynced then begin + splitter.linktop:= nil; + grid.height:= gridlayout.height; + cont1.top:= 4; + end + else begin + fopacitycleared:= false; + cont1.top:= opaedit.bottom+4; + splitter.linktop:= grid; + opagrid.rowcount:= fadedisp.face.fade_opapos.count; + for int1:= 0 to opagrid.rowhigh do begin + opaposed[int1]:= fadedisp.face.fade_opapos[int1]; + opacolored[int1]:= fadedisp.face.fade_opacolor[int1]; + end; + end; + cont1.bottom:= cont2.height; + grid.fixrows[-1].visible:= fopasynced; + splitopa.value:= not fopasynced; +end; + +procedure tfadeeditfo.fadestatupdateexe(const sender: TObject; + const filer: tstatfiler); +var + bo1: boolean; +begin + bo1:= opasynced; + if not filer.iswriter or fopa then begin + bo1:= false; + end; + filer.updatevalue('opasynced',bo1); + opasynced:= bo1; +end; + +procedure tfadeeditfo.sepopaset(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + if (avalue = opasynced) and not avalue then begin + accept:= syncexe; + end; + if accept then begin + opasynced:= not avalue; + if avalue then begin + change; + end; + end; +end; + +function tfadeeditfo.nodeinfo(const atag: integer): pnodeinfoty; +begin + if atag = 0 then begin + result:= @fnodeinfo; + end + else begin + result:= @fnodeinfoopa; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msefadeedit_mfm.pas b/mseide-msegui/lib/common/designutils/msefadeedit_mfm.pas new file mode 100644 index 0000000..d39ae0f --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefadeedit_mfm.pas @@ -0,0 +1,657 @@ +unit msefadeedit_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefadeedit; + +const + objdata: record size: integer; data: array[0..12789] of byte end = + (size: 12790; data: ( + 84,80,70,48,11,116,102,97,100,101,101,100,105,116,102,111,10,102,97,100, + 101,101,100,105,116,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,150,0,8,98, + 111,117,110,100,115,95,121,3,221,0,9,98,111,117,110,100,115,95,99,120, + 3,7,2,9,98,111,117,110,100,115,95,99,121,3,187,1,23,99,111,110, + 116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117, + 115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101, + 114,46,98,111,117,110,100,115,1,2,0,2,0,3,7,2,3,187,1,0, + 7,111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110, + 101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16, + 102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95, + 115,97,118,101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101, + 0,8,115,116,97,116,102,105,108,101,7,12,102,111,114,109,115,116,97,116, + 102,105,108,101,7,99,97,112,116,105,111,110,6,9,70,97,100,101,32,69, + 100,105,116,13,119,105,110,100,111,119,111,112,97,99,105,116,121,5,0,0, + 0,0,0,0,0,128,255,255,8,111,110,99,114,101,97,116,101,7,8,99, + 114,101,97,116,101,101,118,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,8,116,109,115,101,102,111,114,109,0,13,116,115,105,109,112, + 108,101,119,105,100,103,101,116,5,99,111,110,116,50,7,118,105,115,105,98, + 108,101,9,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,7,2,9,98, + 111,117,110,100,115,95,99,121,3,146,1,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,0,13, + 116,115,105,109,112,108,101,119,105,100,103,101,116,5,99,111,110,116,49,7, + 118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,73,9,98,111,117,110,100,115,95,99,120, + 3,7,2,9,98,111,117,110,100,115,95,99,121,3,74,1,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116, + 111,109,0,0,13,116,115,105,109,112,108,101,119,105,100,103,101,116,14,116, + 115,105,109,112,108,101,119,105,100,103,101,116,55,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,19,111,119,95,109,111,117,115,101,116,114,97, + 110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,5,99,111,108,111,114,4,5,0,0,160,19,102, + 97,99,101,46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,7, + 103,100,95,100,111,119,110,15,102,97,99,101,46,108,111,99,97,108,112,114, + 111,112,115,11,15,102,97,108,95,102,97,100,105,114,101,99,116,105,111,110, + 0,8,116,97,98,111,114,100,101,114,2,5,7,118,105,115,105,98,108,101, + 9,8,98,111,117,110,100,115,95,120,3,188,1,8,98,111,117,110,100,115, + 95,121,2,56,9,98,111,117,110,100,115,95,99,120,2,66,9,98,111,117, + 110,100,115,95,99,121,3,17,1,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,0,0,9,116,108,97,121,111,117,116,101,114,10,103,114, + 105,100,108,97,121,111,117,116,8,98,111,117,110,100,115,95,120,2,8,8, + 98,111,117,110,100,115,95,121,2,56,9,98,111,117,110,100,115,95,99,120, + 3,175,1,9,98,111,117,110,100,115,95,99,121,3,18,1,12,98,111,117, + 110,100,115,95,99,121,109,105,110,2,90,7,97,110,99,104,111,114,115,11, + 7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,0,11,116,119,105, + 100,103,101,116,103,114,105,100,7,111,112,97,103,114,105,100,3,84,97,103, + 2,1,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,7,79,112, + 97,99,105,116,121,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,3,147,0,9,98,111,117,110,100, + 115,95,99,120,3,177,1,9,98,111,117,110,100,115,95,99,121,2,126,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116, + 105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105, + 110,103,15,111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111, + 103,95,114,111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99, + 117,115,99,101,108,108,111,110,101,110,116,101,114,13,111,103,95,97,117,116, + 111,97,112,112,101,110,100,9,111,103,95,115,111,114,116,101,100,20,111,103, + 95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108, + 0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105, + 120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2, + 22,7,110,117,109,115,116,101,112,2,1,0,0,14,100,97,116,97,99,111, + 108,115,46,99,111,117,110,116,2,3,16,100,97,116,97,99,111,108,115,46, + 111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,1,11,99,111,108,111,114,115,101,108, + 101,99,116,4,6,0,0,128,5,119,105,100,116,104,2,24,16,111,110,98, + 101,102,111,114,101,100,114,97,119,99,101,108,108,7,12,98,101,102,111,114, + 101,100,114,97,119,101,118,7,111,112,116,105,111,110,115,11,10,99,111,95, + 110,111,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,0,7,8,111,112,97,112,111,115,101, + 100,1,5,119,105,100,116,104,2,89,7,111,112,116,105,111,110,115,11,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114, + 116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,4,110,97,109,101,6, + 6,111,112,97,112,111,115,10,119,105,100,103,101,116,110,97,109,101,6,8, + 111,112,97,112,111,115,101,100,9,100,97,116,97,99,108,97,115,115,7,17, + 116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115,116,0,7,10, + 111,112,97,99,111,108,111,114,101,100,1,5,119,105,100,116,104,3,34,1, + 7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,9,99,111,95,110,111, + 115,111,114,116,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99, + 97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,8,119,105,100,116,104,109,105,110,2,63,4,110,97, + 109,101,6,8,111,112,97,99,111,108,111,114,10,119,105,100,103,101,116,110, + 97,109,101,6,10,111,112,97,99,111,108,111,114,101,100,9,100,97,116,97, + 99,108,97,115,115,7,17,116,103,114,105,100,101,110,117,109,100,97,116,97, + 108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116, + 2,16,8,115,116,97,116,102,105,108,101,7,12,102,97,100,101,115,116,97, + 116,102,105,108,101,14,111,110,114,111,119,115,105,110,115,101,114,116,101,100, + 7,11,114,111,119,105,110,115,101,114,116,101,118,13,111,110,114,111,119,115, + 100,101,108,101,116,101,100,7,11,114,111,119,100,101,108,101,116,101,101,118, + 11,111,110,99,101,108,108,101,118,101,110,116,7,10,103,114,105,100,99,101, + 108,108,101,118,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,9,116,114,101,97,108,101,100,105,116,8,111,112,97,112,111,115,101,100, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,25,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,89, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,13,100,97,116, + 97,101,110,116,101,116,101,114,101,118,5,118,97,108,117,101,5,0,0,0, + 0,0,0,0,128,255,255,12,118,97,108,117,101,100,101,102,97,117,108,116, + 5,0,0,0,0,0,0,0,128,255,255,10,102,111,114,109,97,116,101,100, + 105,116,6,5,48,46,48,48,48,10,102,111,114,109,97,116,100,105,115,112, + 6,5,48,46,48,48,48,10,118,97,108,117,101,114,97,110,103,101,2,1, + 10,118,97,108,117,101,115,116,97,114,116,2,0,8,118,97,108,117,101,109, + 105,110,2,0,8,118,97,108,117,101,109,97,120,2,1,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,10,116,99,111,108,111,114, + 101,100,105,116,10,111,112,97,99,111,108,111,114,101,100,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108, + 95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5, + 0,0,144,0,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97, + 103,101,110,114,2,17,0,0,25,102,114,97,109,101,46,98,117,116,116,111, + 110,101,108,108,105,112,115,101,46,99,111,108,111,114,4,5,0,0,144,27, + 102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46, + 105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,2, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,115, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,34,1,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,14,111,101,49,95,116,104,117,109,98,116,114,97,99,107,0, + 13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,13,100,97,116,97, + 101,110,116,101,116,101,114,101,118,12,118,97,108,117,101,100,101,102,97,117, + 108,116,4,5,0,0,160,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103, + 114,105,100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,177,1,9,98,111,117,110,100,115,95,99,121,3,144, + 0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111, + 103,95,99,111,108,115,105,122,105,110,103,15,111,103,95,114,111,119,105,110, + 115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105, + 110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116, + 101,114,13,111,103,95,97,117,116,111,97,112,112,101,110,100,9,111,103,95, + 115,111,114,116,101,100,20,111,103,95,99,111,108,99,104,97,110,103,101,111, + 110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111, + 103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109,111,117,115,101, + 115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111,108,115,46,99, + 111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115, + 14,1,5,119,105,100,116,104,2,22,7,110,117,109,115,116,101,112,2,1, + 0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102, + 105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104, + 116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,4, + 14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,0,1,7, + 99,97,112,116,105,111,110,6,3,80,111,115,0,1,7,99,97,112,116,105, + 111,110,6,5,67,111,108,111,114,0,1,7,99,97,112,116,105,111,110,6, + 7,79,112,97,99,105,116,121,0,0,0,0,14,100,97,116,97,99,111,108, + 115,46,99,111,117,110,116,2,4,16,100,97,116,97,99,111,108,115,46,111, + 112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111, + 108,115,46,105,116,101,109,115,14,1,11,99,111,108,111,114,115,101,108,101, + 99,116,4,6,0,0,128,5,119,105,100,116,104,2,24,16,111,110,98,101, + 102,111,114,101,100,114,97,119,99,101,108,108,7,12,98,101,102,111,114,101, + 100,114,97,119,101,118,7,111,112,116,105,111,110,115,11,10,99,111,95,110, + 111,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111, + 95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,0,7,5,112,111,115,101,100,1,5,119, + 105,100,116,104,2,89,7,111,112,116,105,111,110,115,11,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110, + 97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11, + 99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,5,112,111,115,101,100,9,100,97,116,97,99,108,97,115,115,7,17, + 116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115,116,0,7,7, + 99,111,108,111,114,101,100,1,5,119,105,100,116,104,3,151,0,7,111,112, + 116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111, + 95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,9,99,111,95,110,111,115,111,114, + 116,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,8,119,105,100,116,104,109,105,110,2,63,10,119,105,100,103,101, + 116,110,97,109,101,6,7,99,111,108,111,114,101,100,9,100,97,116,97,99, + 108,97,115,115,7,17,116,103,114,105,100,101,110,117,109,100,97,116,97,108, + 105,115,116,0,7,5,111,112,97,101,100,1,5,119,105,100,116,104,3,138, + 0,7,111,112,116,105,111,110,115,11,12,99,111,95,105,110,118,105,115,105, + 98,108,101,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114, + 111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,9,99,111,95, + 110,111,115,111,114,116,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6, + 5,111,112,97,101,100,9,100,97,116,97,99,108,97,115,115,7,17,116,103, + 114,105,100,101,110,117,109,100,97,116,97,108,105,115,116,0,0,13,100,97, + 116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105, + 108,101,7,12,102,97,100,101,115,116,97,116,102,105,108,101,14,111,110,114, + 111,119,115,105,110,115,101,114,116,101,100,7,11,114,111,119,105,110,115,101, + 114,116,101,118,13,111,110,114,111,119,115,100,101,108,101,116,101,100,7,11, + 114,111,119,100,101,108,101,116,101,101,118,11,111,110,99,101,108,108,101,118, + 101,110,116,7,10,103,114,105,100,99,101,108,108,101,118,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,9,116,114,101,97,108,101,100, + 105,116,5,112,111,115,101,100,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101, + 105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,25,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,89,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115, + 97,118,101,118,97,108,117,101,0,13,111,110,100,97,116,97,101,110,116,101, + 114,101,100,7,13,100,97,116,97,101,110,116,101,116,101,114,101,118,5,118, + 97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,12,118,97,108,117, + 101,100,101,102,97,117,108,116,5,0,0,0,0,0,0,0,128,255,255,10, + 102,111,114,109,97,116,101,100,105,116,6,5,48,46,48,48,48,10,102,111, + 114,109,97,116,100,105,115,112,6,5,48,46,48,48,48,10,118,97,108,117, + 101,114,97,110,103,101,2,1,10,118,97,108,117,101,115,116,97,114,116,2, + 0,8,118,97,108,117,101,109,105,110,2,0,8,118,97,108,117,101,109,97, + 120,2,1,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,10,116,99,111,108,111,114,101,100,105,116,7,99,111,108,111,114,101,100, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116, + 111,110,46,99,111,108,111,114,4,5,0,0,144,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,5,0,0,144,0,1,5,99,111,108,111,114,4,5,0,0, + 144,7,105,109,97,103,101,110,114,2,17,0,0,25,102,114,97,109,101,46, + 98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111,108,111,114,4, + 5,0,0,144,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108, + 105,112,115,101,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114, + 100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,115,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,151,0,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 115,97,118,101,118,97,108,117,101,14,111,101,49,95,116,104,117,109,98,116, + 114,97,99,107,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7, + 13,100,97,116,97,101,110,116,101,116,101,114,101,118,12,118,97,108,117,101, + 100,101,102,97,117,108,116,4,5,0,0,160,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,10,116,99,111,108,111,114,101,100,105, + 116,5,111,112,97,101,100,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,18,102,114,97,109,101,46, + 98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,5,0,0,144,0,1,5,99,111,108,111,114, + 4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0,0,25,102,114, + 97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111, + 108,111,114,4,5,0,0,144,27,102,114,97,109,101,46,98,117,116,116,111, + 110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2,17,8,116, + 97,98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,11,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,138,0,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,14,111,101,49,95,116, + 104,117,109,98,116,114,97,99,107,0,13,111,110,100,97,116,97,101,110,116, + 101,114,101,100,7,13,100,97,116,97,101,110,116,101,116,101,114,101,118,12, + 118,97,108,117,101,100,101,102,97,117,108,116,4,6,0,0,160,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,112, + 108,105,116,116,101,114,8,115,112,108,105,116,116,101,114,5,99,111,108,111, + 114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,144,0, + 9,98,111,117,110,100,115,95,99,120,3,175,1,9,98,111,117,110,100,115, + 95,99,121,2,3,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111, + 112,0,7,111,112,116,105,111,110,115,11,9,115,112,111,95,118,109,111,118, + 101,9,115,112,111,95,118,112,114,111,112,12,115,112,111,95,100,111,99,107, + 108,101,102,116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112,111, + 95,100,111,99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107,98, + 111,116,116,111,109,0,7,108,105,110,107,116,111,112,7,4,103,114,105,100, + 10,108,105,110,107,98,111,116,116,111,109,7,7,111,112,97,103,114,105,100, + 8,115,116,97,116,102,105,108,101,7,12,102,111,114,109,115,116,97,116,102, + 105,108,101,0,0,0,11,116,112,105,99,107,119,105,100,103,101,116,7,112, + 111,115,101,100,105,116,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,105,2,255,19,102,114,97,109, + 101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,2,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,105,12,102,114,108,95,102,105,98,111,116,116,111,109,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,2,7,111,110,112,97,105,110,116,7, + 10,112,111,115,112,97,105,110,116,101,118,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,248,1,9,98,111,117,110,100,115,95,99,121,2,50,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,18,111,110,99,108,105,101,110, + 116,109,111,117,115,101,101,118,101,110,116,7,7,109,111,117,115,101,101,118, + 8,111,110,114,101,115,105,122,101,7,8,114,101,115,105,122,101,101,118,16, + 111,110,103,101,116,99,117,114,115,111,114,115,104,97,112,101,7,16,103,101, + 116,99,117,114,115,111,114,115,104,97,112,101,101,118,16,111,110,103,101,116, + 112,105,99,107,111,98,106,101,99,116,115,7,15,103,101,116,112,105,99,107, + 111,98,106,101,99,116,101,118,13,111,110,101,110,100,112,105,99,107,109,111, + 118,101,7,9,101,110,100,112,105,99,107,101,118,13,111,110,112,97,105,110, + 116,120,111,114,112,105,99,7,10,112,97,105,110,116,120,111,114,101,118,0, + 13,116,115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105,109,112, + 108,101,119,105,100,103,101,116,51,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97, + 114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,5,99,111,108,111,114,4,5,0,0,160,15,102,97,99,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,8,116,97,98,111,114,100,101, + 114,2,3,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100, + 115,95,99,120,3,246,1,9,98,111,117,110,100,115,95,99,121,2,40,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,0,0,13,116, + 115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105,109,112,108,101, + 119,105,100,103,101,116,50,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,5,99,111,108,111,114,4,6,0,0,160,8,116,97,98,111,114,100,101, + 114,2,1,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,246,1,9,98,111,117,110,100,115,95,99,121,2,13,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,0,0,13,116, + 115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105,109,112,108,101, + 119,105,100,103,101,116,52,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,5,99,111,108,111,114,4,2,0,0,160,8,116,97,98,111,114,100,101, + 114,2,2,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,27,9,98,111,117,110,100, + 115,95,99,120,3,246,1,9,98,111,117,110,100,115,95,99,121,2,13,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,0,0,13,116, + 115,105,109,112,108,101,119,105,100,103,101,116,8,102,97,100,101,100,105,115, + 112,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,19,111,119,95, + 109,111,117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111, + 114,4,3,0,0,128,15,102,97,99,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115, + 95,120,2,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,246,1,9,98,111,117,110,100,115,95,99,121,2,40, + 7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,0,0,0, + 13,116,115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105,109,112, + 108,101,119,105,100,103,101,116,53,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97, + 114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,5,99,111,108,111,114,4,2,0,0,160,8,116,97,98,111,114, + 100,101,114,2,3,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100, + 115,95,120,3,189,1,8,98,111,117,110,100,115,95,121,2,56,9,98,111, + 117,110,100,115,95,99,120,2,23,9,98,111,117,110,100,115,95,99,121,3, + 17,1,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,0,0, + 13,116,115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105,109,112, + 108,101,119,105,100,103,101,116,54,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97, + 114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,5,99,111,108,111,114,4,6,0,0,160,8,116,97,98,111,114, + 100,101,114,2,4,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100, + 115,95,120,3,233,1,8,98,111,117,110,100,115,95,121,2,56,9,98,111, + 117,110,100,115,95,99,120,2,22,9,98,111,117,110,100,115,95,99,121,3, + 17,1,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,0,0, + 13,116,115,105,109,112,108,101,119,105,100,103,101,116,8,102,97,100,101,118, + 101,114,116,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,19,111, + 119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 105,2,255,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,105,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,97,99,101,46,102, + 97,100,101,95,100,105,114,101,99,116,105,111,110,7,7,103,100,95,100,111, + 119,110,15,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15, + 102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,0,8,116,97,98, + 111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,9,8,98,111,117, + 110,100,115,95,120,3,188,1,8,98,111,117,110,100,115,95,121,2,56,9, + 98,111,117,110,100,115,95,99,120,2,68,9,98,111,117,110,100,115,95,99, + 121,3,18,1,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0, + 0,0,0,11,116,112,105,99,107,119,105,100,103,101,116,7,111,112,97,101, + 100,105,116,3,84,97,103,2,1,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,13,102,114,97,109,101,46,111,112,116,105,111,110,115,11,10,99, + 102,111,95,102,105,120,116,111,112,0,12,102,114,97,109,101,46,108,101,118, + 101,108,105,2,255,19,102,114,97,109,101,46,102,114,97,109,101,105,95,98, + 111,116,116,111,109,2,2,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,7,79,112,97,99,105,116,121,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,105,12, + 102,114,108,95,102,105,98,111,116,116,111,109,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,7,111,110,112,97,105,110,116,7, + 10,112,111,115,112,97,105,110,116,101,118,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,248,1,9,98,111,117,110,100,115,95,99,121,2,67,12,98, + 111,117,110,100,115,95,99,120,109,105,110,3,205,1,7,97,110,99,104,111, + 114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,0,18,111,110,99,108,105,101,110,116,109,111,117, + 115,101,101,118,101,110,116,7,7,109,111,117,115,101,101,118,8,111,110,114, + 101,115,105,122,101,7,8,114,101,115,105,122,101,101,118,16,111,110,103,101, + 116,99,117,114,115,111,114,115,104,97,112,101,7,16,103,101,116,99,117,114, + 115,111,114,115,104,97,112,101,101,118,16,111,110,103,101,116,112,105,99,107, + 111,98,106,101,99,116,115,7,15,103,101,116,112,105,99,107,111,98,106,101, + 99,116,101,118,13,111,110,101,110,100,112,105,99,107,109,111,118,101,7,9, + 101,110,100,112,105,99,107,101,118,13,111,110,112,97,105,110,116,120,111,114, + 112,105,99,7,10,112,97,105,110,116,120,111,114,101,118,0,13,116,115,105, + 109,112,108,101,119,105,100,103,101,116,7,111,112,97,100,105,115,112,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,19,111,119,95,109,111,117, + 115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3, + 0,0,128,15,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95,120,2, + 1,8,98,111,117,110,100,115,95,121,2,17,9,98,111,117,110,100,115,95, + 99,120,3,246,1,9,98,111,117,110,100,115,95,99,121,2,40,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,0,0,0,0,0,9,116, + 108,97,121,111,117,116,101,114,12,98,111,116,116,111,109,108,97,121,111,117, + 116,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,2,8,8,98,111,117,110,100,115,95,121,3,151,1,9,98,111,117,110, + 100,115,95,99,120,3,248,1,9,98,111,117,110,100,115,95,99,121,2,31, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112, + 116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97, + 110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95, + 101,120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120, + 112,97,110,100,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115, + 108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,120,10,108, + 97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95,103,108,117, + 101,7,10,119,97,109,95,99,101,110,116,101,114,13,112,108,97,99,101,95, + 109,105,110,100,105,115,116,2,5,7,108,105,110,107,116,111,112,7,5,99, + 111,110,116,50,8,100,105,115,116,95,116,111,112,2,5,7,111,112,116,105, + 111,110,115,11,15,115,112,97,111,95,103,108,117,101,98,111,116,116,111,109, + 0,0,9,116,108,97,121,111,117,116,101,114,12,115,119,105,116,99,104,108, + 97,121,111,117,116,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,142,0, + 9,98,111,117,110,100,115,95,99,121,2,30,12,111,112,116,105,111,110,115, + 115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111, + 115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110, + 100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105, + 111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101, + 120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95, + 103,108,117,101,7,10,119,97,109,95,99,101,110,116,101,114,13,112,108,97, + 99,101,95,109,105,110,100,105,115,116,2,5,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,8,115,112,108,105,116,111,112,97,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,16,83,101,112,97,114,97,116,101,10, + 79,112,97,99,105,116,121,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,8,2,61,2,9,0,8,98,111,117,110,100,115, + 95,120,2,68,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,74,9,98,111,117,110,100,115,95,99,121,2,30,10, + 111,110,115,101,116,118,97,108,117,101,7,9,115,101,112,111,112,97,115,101, + 116,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7,114,101,118, + 101,114,115,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,8, + 38,114,101,118,101,114,115,101,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,1,2,50,2,2,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,7,9,98,111,117,110,100,115,95,99,120,2,63,9, + 98,111,117,110,100,115,95,99,121,2,16,13,111,110,100,97,116,97,101,110, + 116,101,114,101,100,7,16,114,101,118,101,114,115,101,101,110,116,101,114,101, + 100,101,118,0,0,0,9,116,108,97,121,111,117,116,101,114,12,98,117,116, + 116,111,110,108,97,121,111,117,116,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,72,1,9,98,111,117, + 110,100,115,95,99,121,2,31,12,111,112,116,105,111,110,115,115,99,97,108, + 101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115, + 104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111, + 115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108, + 97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,120,0,13,112, + 108,97,99,101,95,109,105,110,100,105,115,116,2,5,0,7,116,98,117,116, + 116,111,110,8,116,98,117,116,116,111,110,50,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,98,111, + 117,110,100,115,95,120,3,14,1,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,58,9,98,111,117,110,100,115,95, + 99,121,2,31,12,98,111,117,110,100,115,95,99,120,109,105,110,2,58,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108, + 11,109,111,100,97,108,114,101,115,117,108,116,7,11,109,114,95,99,97,110, + 99,108,111,115,101,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116, + 116,111,110,49,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97, + 117,116,111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,207,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,58,9,98,111,117,110, + 100,115,95,99,121,2,31,12,98,111,117,110,100,115,95,99,120,109,105,110, + 2,58,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116, + 15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111, + 110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5, + 109,114,95,111,107,0,0,13,116,115,105,109,112,108,101,119,105,100,103,101, + 116,14,116,115,105,109,112,108,101,119,105,100,103,101,116,49,8,116,97,98, + 111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,198,0,8, + 98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100,115,95,99,120, + 2,4,9,98,111,117,110,100,115,95,99,121,2,18,0,0,7,116,98,117, + 116,116,111,110,8,116,98,117,116,116,111,110,51,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116, + 97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,3,135, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,58,9,98,111,117,110,100,115,95,99,121,2,31,12,98,111,117, + 110,100,115,95,99,120,109,105,110,2,58,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111, + 110,6,5,38,83,97,118,101,9,111,110,101,120,101,99,117,116,101,7,6, + 115,97,118,101,101,120,0,0,7,116,98,117,116,116,111,110,8,116,98,117, + 116,116,111,110,52,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95, + 97,117,116,111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114,2, + 4,8,98,111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,58,9,98,111,117,110, + 100,115,95,99,121,2,31,12,98,111,117,110,100,115,95,99,120,109,105,110, + 2,58,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,7,99,97,112,116,105,111,110,6,5,38,76,111,97,100,9, + 111,110,101,120,101,99,117,116,101,7,6,108,111,97,100,101,120,0,0,7, + 116,98,117,116,116,111,110,7,99,108,101,97,114,98,117,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0, + 8,116,97,98,111,114,100,101,114,2,5,4,104,105,110,116,6,22,67,108, + 101,97,114,32,111,112,97,99,105,116,121,32,103,114,97,100,105,101,110,116, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,67,9,98,111,117,110,100, + 115,95,99,121,2,31,12,98,111,117,110,100,115,95,99,120,109,105,110,2, + 58,5,115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100, + 16,97,115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,12,97,115,95,108,111,99, + 97,108,104,105,110,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,7,99,97,112,116,105,111,110,6,8,67,108,101,97,114, + 79,112,97,9,111,110,101,120,101,99,117,116,101,7,11,99,108,101,97,114, + 111,112,97,101,120,101,0,0,0,0,9,116,115,116,97,116,102,105,108,101, + 12,102,111,114,109,115,116,97,116,102,105,108,101,8,102,105,108,101,110,97, + 109,101,6,14,102,97,100,101,101,100,105,116,111,114,46,115,116,97,7,111, + 112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,17,115, + 102,111,95,97,99,116,105,118,97,116,111,114,114,101,97,100,18,115,102,111, + 95,97,99,116,105,118,97,116,111,114,119,114,105,116,101,0,4,108,101,102, + 116,2,96,3,116,111,112,3,200,0,0,0,11,116,102,105,108,101,100,105, + 97,108,111,103,10,102,105,108,101,100,105,97,108,111,103,8,115,116,97,116, + 102,105,108,101,7,12,102,111,114,109,115,116,97,116,102,105,108,101,26,99, + 111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116, + 46,100,97,116,97,1,1,6,10,70,97,100,101,32,70,105,108,101,115,6, + 5,42,46,102,97,100,0,1,6,9,65,108,108,32,70,105,108,101,115,6, + 1,42,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102,97, + 117,108,116,101,120,116,6,3,102,97,100,18,99,111,110,116,114,111,108,108, + 101,114,46,111,112,116,105,111,110,115,11,14,102,100,111,95,99,104,101,99, + 107,101,120,105,115,116,15,102,100,111,95,115,97,118,101,108,97,115,116,100, + 105,114,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116,105, + 111,110,111,112,101,110,6,14,76,111,97,100,32,70,97,100,101,32,70,105, + 108,101,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111, + 110,115,97,118,101,6,14,83,97,118,101,32,70,97,100,101,32,70,105,108, + 101,4,108,101,102,116,3,208,0,3,116,111,112,3,240,0,0,0,9,116, + 115,116,97,116,102,105,108,101,12,102,97,100,101,115,116,97,116,102,105,108, + 101,8,102,105,108,101,110,97,109,101,6,10,115,116,97,116,117,115,46,115, + 116,97,12,111,110,115,116,97,116,117,112,100,97,116,101,7,17,102,97,100, + 101,115,116,97,116,117,112,100,97,116,101,101,120,101,4,108,101,102,116,3, + 200,0,3,116,111,112,3,200,0,0,0,16,116,115,116,114,105,110,103,99, + 111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100, + 97,116,97,1,6,43,68,111,32,121,111,117,32,119,97,110,116,32,116,111, + 32,115,121,110,99,104,114,111,110,105,122,101,32,111,112,97,99,105,116,121, + 32,103,114,97,100,105,101,110,116,6,20,119,105,116,104,32,99,111,108,111, + 114,32,103,114,97,100,105,101,110,116,63,6,39,68,111,32,121,111,117,32, + 119,97,110,116,32,116,111,32,114,101,109,111,118,101,32,111,112,97,99,105, + 116,121,32,103,114,97,100,105,101,110,116,63,0,4,108,101,102,116,2,88, + 3,116,111,112,3,88,1,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfadeeditfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msefadepropedit.pas b/mseide-msegui/lib/common/designutils/msefadepropedit.pas new file mode 100644 index 0000000..598994e --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefadepropedit.pas @@ -0,0 +1,256 @@ +{ MSEide Copyright (c) 2007-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msefadepropedit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msepropertyeditors; + +type + tfacefadecoloreditor = class(tcolorarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacefadeposeditor = class(trealarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacetemplatefadecoloreditor = class(tcolorarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacetemplatefadeposeditor = class(trealarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacefadeopacoloreditor = class(tcolorarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacefadeopaposeditor = class(trealarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacetemplatefadeopacoloreditor = class(tcolorarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacetemplatefadeopaposeditor = class(trealarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + +implementation +uses + msegraphutils,msearrayprops,msegui,msefadeedit,mseglob; + +type + tpropertyeditor1 = class(tpropertyeditor); + +procedure editfacefade(const aproperty: tpropertyeditor; const opa: boolean); +var + direct: graphicdirectionty; + fadepos,fadeopapos: trealarrayprop; + fadecolor,fadeopacolor: tcolorarrayprop; + int1: integer; +begin + with tcustomface(tpropertyeditor1(aproperty).instance) do begin + direct:= fade_direction; + fadepos:= fade_pos; + fadeopapos:= fade_opapos; + fadecolor:= fade_color; + fadeopacolor:= fade_opacolor; + if editfade(direct,opa,fade_pos,fade_opapos, + fade_color,fade_opacolor) = mr_ok then begin + fade_direction:= direct; + with tpropertyeditor1(aproperty) do begin + for int1:= 1 to count - 1 do begin + with tcustomface(tpropertyeditor1(aproperty).instance(int1)) do begin + fade_direction:= direct; + if opa then begin + fade_opapos.assign(fadeopapos); + fade_opacolor.assign(fadeopacolor); + end + else begin + fade_opapos.assign(fadepos); + fade_opacolor.assign(fadecolor); + end; + end; + end; + modified; + end; + end; + end; +end; + +procedure editfacetemplatefade(const aproperty: tpropertyeditor; + const opa: boolean); +var + direct: graphicdirectionty; + fadepos,fadeopapos: trealarrayprop; + fadecolor,fadeopacolor: tcolorarrayprop; + int1: integer; +begin + with tfacetemplate(tpropertyeditor1(aproperty).instance) do begin + direct:= fade_direction; + fadepos:= fade_pos; + fadeopapos:= fade_opapos; + fadecolor:= fade_color; + fadeopacolor:= fade_opacolor; + if editfade(direct,opa,fade_pos,fade_opapos, + fade_color,fade_opacolor) = mr_ok then begin + fade_direction:= direct; + with tpropertyeditor1(aproperty) do begin + for int1:= 1 to count - 1 do begin + with tfacetemplate(tpropertyeditor1(aproperty).instance(int1)) do begin + fade_direction:= direct; + if opa then begin + fade_opapos.assign(fadeopapos); + fade_opacolor.assign(fadeopacolor); + end + else begin + fade_opapos.assign(fadepos); + fade_opacolor.assign(fadecolor); + end; + end; + end; + modified; + end; + end; + end; +end; + +{ tfacefadecoloreditor } + +function tfacefadecoloreditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacefadecoloreditor.edit; +begin + editfacefade(self,false); +end; + +{ tfacefadeposeditor } + +function tfacefadeposeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacefadeposeditor.edit; +begin + editfacefade(self,false); +end; + +{ tfacetemplatefadecoloreditor } + +function tfacetemplatefadecoloreditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacetemplatefadecoloreditor.edit; +begin + editfacetemplatefade(self,false); +end; + +{ tfacetemplatefadeposeditor } + +function tfacetemplatefadeposeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacetemplatefadeposeditor.edit; +begin + editfacetemplatefade(self,false); +end; + +{ tfacefadeopacoloreditor } + +function tfacefadeopacoloreditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacefadeopacoloreditor.edit; +begin + editfacefade(self,true); +end; + +{ tfacefadeopaposeditor } + +function tfacefadeopaposeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacefadeopaposeditor.edit; +begin + editfacefade(self,true); +end; + +{ tfacetemplatefadeopacoloreditor } + +function tfacetemplatefadeopacoloreditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacetemplatefadeopacoloreditor.edit; +begin + editfacetemplatefade(self,true); +end; + +{ tfacetemplatefadeopaposeditor } + +function tfacetemplatefadeopaposeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacetemplatefadeopaposeditor.edit; +begin + editfacetemplatefade(self,true); +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msefircoeffeditor.mfm b/mseide-msegui/lib/common/designutils/msefircoeffeditor.mfm new file mode 100644 index 0000000..0e520e0 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefircoeffeditor.mfm @@ -0,0 +1,100 @@ +object fircoeffeditorfo: tfircoeffeditorfo + bounds_x = 72 + bounds_y = 206 + bounds_cx = 229 + bounds_cy = 263 + container.bounds = ( + 0 + 0 + 229 + 263 + ) + statfile = tstatfile1 + caption = 'IIR Filter Coefficients' + moduleclassname = 'tmseform' + object grid: twidgetgrid + bounds_x = 0 + bounds_y = 0 + bounds_cx = 228 + bounds_cy = 221 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_focuscellonenter, og_rowheight, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 62 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 1 + captions.items = < + item + caption = 'Coefficient' + end> + captionsfix.count = 1 + captionsfix.items = < + item + caption = 'sect:z^n' + end> + end> + datacols.count = 1 + datacols.options = [co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[coeffed] + width = 160 + options = [co_mouseselect, co_keyselect, co_multiselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'coeffed' + dataclass = tgridrealdatalist + end> + datarowheight = 16 + reffontheight = 14 + object coeffed: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 160 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + value = 0 + valuedefault = 0 + valuerange = 1 + valuestart = 0 + min = -1E+038 + max = 1E+038 + reffontheight = 14 + end + end + object ok: tbutton + taborder = 1 + bounds_x = 102 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 2 + bounds_x = 166 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object tstatfile1: tstatfile + filename = 'fircoeffeditor.sta' + options = [sfo_memory] + left = 56 + top = 48 + end +end diff --git a/mseide-msegui/lib/common/designutils/msefircoeffeditor.pas b/mseide-msegui/lib/common/designutils/msefircoeffeditor.pas new file mode 100644 index 0000000..83219de --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefircoeffeditor.pas @@ -0,0 +1,22 @@ +unit msefircoeffeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msestatfile, + msedataedits,mseedit,msegrids,mseificomp,mseificompglob,mseifiglob,msestrings, + msewidgetgrid,msesimplewidgets; +type + tfircoeffeditorfo = class(tmseform) + tstatfile1: tstatfile; + grid: twidgetgrid; + ok: tbutton; + cancel: tbutton; + coeffed: trealedit; + end; + +implementation +uses + msefircoeffeditor_mfm; + +end. diff --git a/mseide-msegui/lib/common/designutils/msefircoeffeditor_mfm.pas b/mseide-msegui/lib/common/designutils/msefircoeffeditor_mfm.pas new file mode 100644 index 0000000..d517627 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefircoeffeditor_mfm.pas @@ -0,0 +1,102 @@ +unit msefircoeffeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefircoeffeditor; + +const + objdata: record size: integer; data: array[0..1683] of byte end = + (size: 1684; data: ( + 84,80,70,48,17,116,102,105,114,99,111,101,102,102,101,100,105,116,111,114, + 102,111,16,102,105,114,99,111,101,102,102,101,100,105,116,111,114,102,111,8, + 98,111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,3, + 206,0,9,98,111,117,110,100,115,95,99,120,3,229,0,9,98,111,117,110, + 100,115,95,99,121,3,7,1,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,229,0,3,7,1,0,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99, + 97,112,116,105,111,110,6,23,73,73,82,32,70,105,108,116,101,114,32,67, + 111,101,102,102,105,99,105,101,110,116,115,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,228,0,9,98,111,117,110,100,115,95,99,121, + 3,221,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 12,111,103,95,114,111,119,104,101,105,103,104,116,20,111,103,95,99,111,108, + 99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114, + 97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111, + 103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105, + 120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108, + 115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,62,0,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16, + 14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,1,14,99,97, + 112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105, + 111,110,6,11,67,111,101,102,102,105,99,105,101,110,116,0,0,17,99,97, + 112,116,105,111,110,115,102,105,120,46,99,111,117,110,116,2,1,17,99,97, + 112,116,105,111,110,115,102,105,120,46,105,116,101,109,115,14,1,7,99,97, + 112,116,105,111,110,6,8,115,101,99,116,58,122,94,110,0,0,0,0,14, + 100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1,16,100,97,116, + 97,99,111,108,115,46,111,112,116,105,111,110,115,11,15,99,111,95,112,114, + 111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97, + 99,111,108,115,46,105,116,101,109,115,14,7,7,99,111,101,102,102,101,100, + 1,5,119,105,100,116,104,3,160,0,7,111,112,116,105,111,110,115,11,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,7,99,111,101,102,102,101,100,9,100, + 97,116,97,99,108,97,115,115,7,17,116,103,114,105,100,114,101,97,108,100, + 97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,9,116,114,101,97,108,101,100,105,116,7,99,111,101,102,102,101,100, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114, + 2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,160,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,0,5,118,97,108,117,101,2,0,12,118,97,108,117, + 101,100,101,102,97,117,108,116,2,0,10,118,97,108,117,101,114,97,110,103, + 101,2,1,10,118,97,108,117,101,115,116,97,114,116,2,0,3,109,105,110, + 5,245,136,13,181,80,153,118,150,125,192,3,109,97,120,5,245,136,13,181, + 80,153,118,150,125,64,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98, + 111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,102,8,98, + 111,117,110,100,115,95,121,3,232,0,9,98,111,117,110,100,115,95,99,120, + 2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108, + 116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105, + 111,110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7, + 5,109,114,95,111,107,0,0,7,116,98,117,116,116,111,110,6,99,97,110, + 99,101,108,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,3,166,0,8,98,111,117,110,100,115,95,121,3,232,0,9,98, + 111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121, + 2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116, + 9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116, + 105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108,114,101, + 115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0,0,9,116,115, + 116,97,116,102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102, + 105,108,101,110,97,109,101,6,18,102,105,114,99,111,101,102,102,101,100,105, + 116,111,114,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111, + 95,109,101,109,111,114,121,0,4,108,101,102,116,2,56,3,116,111,112,2, + 48,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfircoeffeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseformdatatools.pas b/mseide-msegui/lib/common/designutils/mseformdatatools.pas new file mode 100644 index 0000000..377c97c --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseformdatatools.pas @@ -0,0 +1,333 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformdatatools; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msetypes,msestrings,msestream,classes,mclasses,mseclasses; +type + objformatty = (of_default,of_delphi,of_fp); + +procedure componentstoobjsource(components: componentarty; + outfilename: filenamety; + usesnames: string; //',' between names: 'unit1,unit2' + unitname: string = ''; objformat: objformatty = of_default); + +procedure formtexttoobjsource(sourcefilename: filenamety; + formclass: string = ''; + unitname: string = ''; + objformat: objformatty = of_default; + langmodule: boolean = false); + //converts objecttext to linkdata, + //if formclass = '' -> extracted from sourcefile, + //if unitname = '' -> unitname = filename + +procedure datatoobjsource(const source: tstream; const dest: ttextstream; + const unitname: msestring); + +procedure getobjforminfo(instream: ttextstream; var formname,formclass: string); + //!!!!todo var -> out (fpcbug 3221) +procedure createlanglib(const libfilename: filenamety; + const langmodules,resourcemodules: stringarty); +procedure writeconstdata(po1: pbyte; length: integer; const dataname: string; + const outstream: ttextstream); + +implementation +uses + msefileutils,sysutils,msesys,mseobjecttext; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + formdataext = '_mfm'; + objdataname = 'objdata'; + +procedure createlanglib(const libfilename: filenamety; + const langmodules,resourcemodules: stringarty); +var + outstream: ttextstream; + str1: string; + int1: integer; +begin + outstream:= ttextstream.create(libfilename,fm_create); + try + outstream.writeln('library ' + filenamebase(libfilename) + ';'); + outstream.writeln(compilerdefaults); + outstream.writeln('uses'); + str1:= ' mselanglink'; + for int1:= 0 to high(langmodules) do begin + str1:= str1 + ',' + langmodules[int1]+formdataext; + end; + for int1:= 0 to high(resourcemodules) do begin + str1:= str1 + ',' + resourcemodules[int1]; + end; + outstream.writeln(str1+';'); + outstream.writeln('exports'); + outstream.writeln(' registerlang,unregisterlang;'); + outstream.writeln('end.'); + finally + outstream.free; + end; +end; + +var + format: objformatty; + +procedure getobjforminfo(instream: ttextstream; var formname,formclass: string); +var + str1: string; + ar1: stringarty; + posbefore: longword; +begin + posbefore:= instream.position; + instream.readln(str1); + instream.position:= posbefore; + splitstring(str1,ar1,' ',true); + if (length(ar1) <> 3) or not((ar1[0] = 'object') or (ar1[0] = 'inherited')) or + (ar1[1][length(ar1[1])] <> ':') then begin + raise exception.Create('Invalid format: "'+str1+'".'); + end; + formname:= copy(ar1[1],1,length(ar1[1])-1); + formclass:= ar1[2]; +end; + +function getbytestring(var data: pbyte; var count: integer): string; +var + int1: integer; + strings: stringarty; +begin + int1:= count; + if int1 > 20 then begin + int1:= 20; + end; + dec(count,int1); + setlength(strings,int1); + for int1:= 0 to int1 - 1 do begin + strings[int1]:= inttostr(data^); + inc(data); + end; + result:= concatstrings(strings,','); +end; + +function getnameext(name: string): string; +begin + if name = '' then begin + result:= '' + end + else begin + result:= '_'+name; + end; +end; + +procedure writeconstdata(po1: pbyte; length: integer; const dataname: string; + const outstream: ttextstream); +begin + outstream.writeln('const'); + outstream.writeln(' '+dataname+': record size: integer; data: array[0..'+ + inttostr(length-1)+'] of byte end ='); + outstream.writeln(' (size: '+inttostr(length)+'; data: ('); + while length > 0 do begin + outstream.write(' '+getbytestring(po1,length)); + if length > 0 then begin + outstream.writeln(','); + end; + end; + outstream.writeln(')'); + outstream.writeln(' );'); + outstream.writeln(''); +end; + +procedure writeobjdata(datastream: tmemorystream; outstream: ttextstream; + name: string; objformat: objformatty); +var + int1: integer; + po1: pbyte; +// str1: string; +begin + int1:= datastream.Size; + po1:= datastream.Memory; +// str1:= getnameext(name); + writeconstdata(po1,int1,objdataname+getnameext(name),outstream); +end; + +procedure writeobjregister(outstream: ttextstream; aclass,name: string); +begin + outstream.writeln(' registerobjectdata(@'+objdataname+getnameext(name)+','+aclass+ + ','''+name+''');'); +end; + +procedure componentstoobjsource(components: componentarty; + outfilename: filenamety; usesnames: string; + unitname: string = ''; objformat: objformatty = of_default); +var + outstream: ttextstream; + memstream: tmemorystream; + int1: integer; + str1: string; +begin + if objformat = of_default then begin + objformat:= format; + end; + if unitname = '' then begin + unitname:= ansistring(removefileext(filename(outfilename))); + end; + outstream:= ttextstream.Create(outfilename,fm_create); + try + outstream.writeln('unit ' + unitname + ';'); + outstream.writeln(compilerdefaults); + outstream.writeln(''); + outstream.writeln('interface'); + outstream.writeln(''); + outstream.writeln('implementation'); + outstream.writeln('uses'); + if usesnames <> '' then begin + str1:= ',' + usesnames; + end + else begin + str1:= ''; + end; + outstream.writeln(' mseclasses'+str1+';'); + outstream.writeln(''); + for int1:= 0 to high(components) do begin + memstream:= tmemorystream.Create; + try + memstream.WriteComponent(components[int1]); + writeobjdata(memstream,outstream,components[int1].Name,objformat) + finally + memstream.Free; + end; + end; + outstream.writeln('initialization'); + for int1:= 0 to high(components) do begin + with components[int1] do begin + writeobjregister(outstream,classname,name); + end; + end; + outstream.writeln('end.'); + finally + outstream.Free; + end; +end; + +procedure formtexttoobjsource(sourcefilename: filenamety; + formclass: string = ''; + unitname: string = ''; + objformat: objformatty = of_default; + langmodule: boolean = false); + //converts objectext to linkdata +var + instream: ttextstream; + outstream: ttextstream; + memstream: tmemorystream; + outname: string; + str1: string; + +begin + if objformat = of_default then begin + objformat:= format; + end; + instream:= ttextstream.create(sourcefilename,fm_read); + try + if formclass = '' then begin + getobjforminfo(instream,str1,formclass); + instream.position:= 0; + end; + if unitname = '' then begin + unitname:= ansistring(removefileext(filename(sourcefilename))); + end; + outname:= ansistring(removefileext(sourcefilename)) + formdataext; + memstream:= tmemorystream.Create; + try + objecttexttobinarymse(instream,memstream); + outstream:= ttextstream.createtransaction(filenamety(outname)+'.pas'); + outstream.usewritebuffer:= true; + try + outstream.writeln('unit ' + unitname + formdataext+';'); + outstream.writeln(compilerdefaults); + outstream.writeln(''); + outstream.writeln('interface'); + outstream.writeln(''); + outstream.writeln('implementation'); + outstream.writeln('uses'); + if langmodule then begin + outstream.writeln(' msei18nglob,mselanglink;'); + outstream.writeln(''); + writeobjdata(memstream,outstream,'',objformat); + outstream.writeln('var'); + outstream.writeln(' hookbefore: registermodulehookty;'); + outstream.writeln(''); + outstream.writeln( + 'procedure registermodule(const registermoduleproc: registermodulety);'); + outstream.writeln('begin'); + outstream.writeln( + ' registermoduleproc(@'+objdataname+','''+formclass+''','''');'); + outstream.writeln(' registermodulehook:= hookbefore;'); + outstream.writeln('end;'); + outstream.writeln(''); + outstream.writeln('initialization'); + outstream.writeln(' hookbefore:= registermodulehook;'); + outstream.writeln(' registermodulehook:= @registermodule;'); + end + else begin + outstream.writeln(' mseclasses,'+unitname+';'); + outstream.writeln(''); + writeobjdata(memstream,outstream,'',objformat); + outstream.writeln('initialization'); + writeobjregister(outstream,formclass,''); + end; + outstream.writeln('end.'); + finally + outstream.Free; + end; + finally + memstream.Free; + end; + finally + instream.Free; + end; +end; + +procedure datatoobjsource(const source: tstream; const dest: ttextstream; + const unitname: msestring); +var + s1: string; +begin + dest.writeln('unit ' + unitname+';'); + dest.writeln(compilerdefaults); + dest.writeln('interface'); + s1:= readstreamdatastring(source); + writeconstdata(pointer(s1),length(s1),'data',dest); + dest.writeln('implementation'); + dest.writeln('end.'); +end; + +initialization +{$ifdef FPC} + format:= of_fp; +{$else} + format:= of_delphi; +{$endif} +end. diff --git a/mseide-msegui/lib/common/designutils/msegdbutils.pas b/mseide-msegui/lib/common/designutils/msegdbutils.pas new file mode 100644 index 0000000..151e895 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msegdbutils.pas @@ -0,0 +1,5038 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegdbutils; + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} +//{$define mse_usedebugbreakprocess} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msestream,mseclasses,classes,mclasses,msetypes,mseevent,msehash,msepipestream, + msestrings,mseapplication,msegui,msedatalist,msesystypes,mseprocess; + +//todo: byte endianess for remote debugging + +type + gdbresultty = (gdb_ok,gdb_error,gdb_timeout,gdb_dataerror,gdb_message, + gdb_running,gdb_writeerror,gdb_notactive); + + sigflagty = (sfl_internal,sfl_stop,sfl_handle); + sigflagsty = set of sigflagty; + + processorty = (pro_i386,pro_x86_64,pro_arm,pro_armm3, + pro_cpu32,pro_avr32,pro_rl78); + languagety = (lan_none,lan_undef,lan_pascal); + +const + gdberrortexts: array[gdbresultty] of string = + ('','Error','Timeout','Data error','Message','Target running', + 'Write error','gdb not active'); + niltext = 'nil'; + processornames: array[processorty] of ansistring = + ('i386','x86_64','arm','armm3','cpu32','avr32','rl78'); + simulatorprocessors = [pro_arm,pro_armm3,pro_rl78]; + +type + gdbstatety = (gs_syncget,gs_syncack,gs_clicommand,gs_clilist, + gs_canstop,gs_started,gs_startup,gs_attaching, + gs_execloaded,gs_attached,gs_detached, + gs_remote,gs_async,gs_downloaded,gs_downloading,gs_runafterload, + gs_internalrunning,gs_running,gs_stopped, + gs_interrupted,gs_restarted, + gs_closing,gs_gdbdied); + gdbstatesty = set of gdbstatety; + + recordclassty = + (rec_done,rec_running,rec_connected,rec_error,rec_exit, + rec_stopped,rec_download, + rec_threadcreated,rec_threadexited,rec_threadgroupexited, + rec_threadselected, + rec_libraryloaded,rec_libraryunloaded, + rec_threadgroupadded,rec_threadgroupstarted,rec_breakpointmodified); + resultclassty = rec_done..rec_exit; + asyncclassty = rec_running..high(recordclassty); +const + recordclassnames: array[recordclassty] of string = + ('done', 'running', 'connected', 'error', 'exit', + 'stopped', 'download', + 'thread-created','thread-exited', 'thread-group-exited', + 'thread-selected', + 'library-loaded','library-unloaded', + 'thread-group-added','thread-group-started','breakpoint-modified'); + recordclassnoname: array[recordclassty] of boolean = + (false, false, false, false, false, + false, true, + false, false, false, + false, + false, false, + false, false, false); + defaultsynctimeout = 2000000; //2 seconds +type + valuekindty = (vk_value,vk_tuple,vk_list); + gdbeventkindty = (gek_done,gek_error,gek_connected,gek_running, + gek_stopped,gek_download,gek_loaded, + gek_targetoutput,gek_writeerror,gek_startup, + gek_gdbdied); + + resultinfoty = record + variablename: string; + valuekind: valuekindty; + value: string; + end; + resultinfoarty = array of resultinfoty; + resultinfoararty = array of resultinfoarty; + + stopreasonty = (sr_none,sr_unknown,sr_error,sr_startup,sr_exception,sr_gdbdied, + sr_breakpoint_hit, + sr_watchpointtrigger,sr_readwatchpointtrigger, + sr_accesswatchpointtrigger, + sr_end_stepping_range,sr_function_finished, + sr_exited_normally,sr_exited,sr_detached,sr_signal_received); + stopreasontextty = array[stopreasonty] of string; +const + defaultstopreasontext: stopreasontextty = ( + '', + 'Unknown', + 'Error', + 'Startup', + 'Exception', + 'GDB died', + 'Breakpoint hit', + 'Watchpoint triggered', + 'Read Watchpoint triggered', + 'Access Watchpoint triggered', + 'End stepping range', + 'Function finished', + 'Exited normally', + 'Exited', + 'Detached', + 'Signal received' + ); +var + stopreasontext: stopreasontextty; + +type + stopinfoty = record + reason: stopreasonty; + time: tdatetime; + bkptno: integer; + threadid: qword; + exitcode: integer; + filename: filenamety; + filedir: filenamety; + line: integer; + addr: qword; + func: string; + language: languagety; + signalname: string; + signalmeaning: string; + messagetext: string; + expression,oldvalue,newvalue: string; + section: string; + sectionsent,sectionsize,totalsent,totalsize: integer; + end; +{ + errorinfoty = record + messagetext: string; + end; +} + breakpointinfoty = record + addressbreakpoint: boolean; + line: integer; //1. line = 1 + path: filenamety; + address: qword; +// filename: string; + bkptno: integer; + bkpton: boolean; + ignore: integer; + passcount: integer; + condition,conditionmessage: string; + end; + pbreakpointinfoty = ^breakpointinfoty; + breakpointinfoarty = array of breakpointinfoty; + + watchpointkindty = (wpk_write,wpk_readwrite,wpk_read); + + watchpointinfoty = record + kind: watchpointkindty; + wptno: integer; + expression: string; + ignore: integer; + condition: string; + conditionmessage: string; + end; + + paraminfoty = record + name: string; + value: string; + end; + paraminfoarty = array of paraminfoty; + + frameinfoty = record + level: integer; + addr: qword; + func: string; + filename: filenamety; + line: integer; + params: paraminfoarty; + end; + frameinfoarty = array of frameinfoty; + + registerinfoty = record + num: integer; + bits: string; //hex notation + end; + registerinfoarty = array of registerinfoty; + + asmlinety = record + address: qword; + instruction: string; + end; + asmlinearty = array of asmlinety; + + disassty = record + line: integer; + asmlines: asmlinearty; + end; + disassarty = array of disassty; + + tgdbmi = class; + + gdbeventty = procedure(const sender: tgdbmi; var eventkind: gdbeventkindty; + const values: resultinfoarty; const stoppinfo: stopinfoty) of object; + + tgdbevent = class(tobjectevent) + private + flastconsoleoutput: ansistring; + fthreadid: integer; + public + eventkind: gdbeventkindty; + values: resultinfoarty; + end; + + tgdbstartupevent = class(tgdbevent) + public + stopinfo: stopinfoty; + constructor create(const dest: ievent); + end; + + setnumprocty = procedure(var dataarray; const index: integer; const text: string); + setlenprocty = procedure(var dataarray; const len: integer); + + threadstatety = (ts_none,ts_active); + + threadinfoty = record + id: qword; //gdb id + threadid: qword; //system id + state: threadstatety; + stackframe: string; + end; + threadinfoarty = array of threadinfoty; + +{$ifdef UNIX} + tpseudoterminal = class + private + fdevicename: string; + finput: tpipereader; + foutput: tpipewriter; + fpty: integer; + procedure closeinp; + procedure setoutecho(const avalue: boolean); + function getoutecho: boolean; + public + constructor create; + destructor destroy; override; + procedure restart; + property devicename: string read fdevicename; + property input: tpipereader read finput; + property output: tpipewriter read foutput; + property outecho: boolean read getoutecho write setoutecho; + end; +{$endif} + + envvarinfoty = record + name: string; + value: string; + unset: boolean; + end; + envvararty = array of envvarinfoty; + + tgdbmi = class(tactcomponent) + private + fgdbto: tpipewriter; + fgdbfrom{,fgdberror}: tpipereader; + {$ifdef UNIX} + ftargetterminal: tpseudoterminal; + ftargetconsole: tcustommseprocess; + {$endif} + fgdb: integer; //processhandle + fstate: gdbstatesty; + fsequence: longword; + fconsolesequence: longword; + frunsequence: longword; + fsyncsequence: longword; + fsyncvalues: resultinfoarty; + fsynceventkind: gdbeventkindty; + fclivalues: string; + fclivaluelist: stringarty; + fonevent: gdbeventty; + fonerror: gdbeventty; + fguiintf: boolean; + fsourcefiles: tmsestringhashdatalist; + fsourcefiledirs: filenamearty; //dirs for fsourcefiles + fexceptionbkpt: integer; + fstartupbreakpoint: integer; + fstartupbreakpoint1: integer; + fstoponexception: boolean; + ferrormessage: string; + fprocid: int64; + fcurrentprocid: int64; + {$ifdef mswindows} + finterruptthreadid: longword; + {$endif} + fworkingdirectory: filenamety; + fprogparameters: string; + finterruptcount: integer; + fignoreexceptionclasses: stringarty; + flogtext: string; + flastbreakpoint: integer; + fenvvars: envvararty; + ftargetdebugbegin,ftargetdebugend: qword; +// {$ifdef mswindows} + fnewconsole: boolean; +// {$endif} + fremoteconnection: msestring; + fgdbdownload: boolean; + fsimulator: boolean; + flastconsoleoutput: ansistring; + fprocessor: processorty; + fbeforeload: filenamety; + fafterload: filenamety; + fbeforerun: filenamety; + fstartupbkpt: longword; + fstartupbkpton: boolean; + foverloadsleepus: integer; + floadtimeoutus: integer; + fstoptime: tdatetime; + fstopinfo: resultinfoarty; + fstopthreadid: integer; + fcurrthreadid: integer; + fsettty: boolean; + fbeforeconnect: filenamety; + fafterconnect: filenamety; + fxtermcommand: filenamety; + fcurrentlanguage: languagety; + ffpcworkaround: boolean; + procedure setstoponexception(const avalue: boolean); + procedure checkactive; + function checkconnection(const proginfo: boolean): gdbresultty; + procedure resetexec; + function getrunning: boolean; + function getexecloaded: boolean; + function getattached: boolean; + procedure setignoreexceptionclasses(const avalue: stringarty); + function getprocessorname: ansistring; + procedure setprocessorname(const avalue: ansistring); + procedure setoverloadsleepus(const avalue: integer); + protected + fpointersize: integer; + fpointerhexdigits: integer; + {$ifdef UNIX} + procedure targetfrom(const sender: tpipereader); + procedure killtargetconsole; + function createtargetconsole: boolean; + procedure xtermfrom(const sender: tpipereader); + {$endif} + procedure gdbfrom(const sender: tpipereader); + procedure gdbpipebroken(const sender: tpipereader); + procedure interpret(const line: string); + procedure consoleoutput(const text: string); + procedure targetoutput(const text: string); + procedure logoutput(const text: string); + procedure sequenceend; + procedure initstopinfo(var ainfo: stopinfoty); + procedure receiveevent(const event: tobjectevent); override; + procedure doevent(const token: longword; const eventkind: gdbeventkindty; + values: resultinfoarty); + procedure postsyncerror; + procedure checkpointersize; + procedure updateenvvars(); + procedure dorun; + function internalcommand(acommand: string): boolean; + function synccommand(const acommand: string; + atimeout: integer = defaultsynctimeout): gdbresultty; + function clicommand(const acommand: string; list: boolean = false; + timeout: integer = defaultsynctimeout): gdbresultty; + function getcliresult(const acommand: string; + var aresult: stringarty): gdbresultty; + function getcliresultstring(const acommand: string; + var aresult: string): gdbresultty; + function getclistring(const aname: string; + const response: string; out aresult: string): boolean; + function getcliinteger(const aname: string; + const response: string; out aresult: integer): boolean; + function getcliint64(const aname: string; + const response: string; out aresult: int64): boolean; + + function decodelist(const noname: boolean; const inp: string; + var value: resultinfoarty): boolean; + function ispointervalue(avalue: string; out pointervalue: qword): boolean; + function matchpascalformat(const typeinfo: string; value: string; + const expression: string): msestring; + function getpcharvar(address: qword): string; + function getpmsecharvar(address: qword): msestring; + function getnumarrayvalue(const response: resultinfoarty; + const aname: string; var avalue; setnumproc: setnumprocty; + setlenproc: setlenprocty): boolean; + function getpascalvalue(const avalue: string): string; + function getbkptid: integer; + function getwptid: integer; + procedure initinternalbkpts; + procedure initproginfo; + function internaldisassemble(out aresult: disassarty; command: string; + const mixed: boolean): gdbresultty; + function getshortstring(const address: string; out avalue: string): boolean; + function setenv(const aname,avalue: string): gdbresultty; + function unsetenv(const aname: string): gdbresultty; + function getsysregnum(const varname: string; out num: integer): boolean; + function currentlang: string; + function assignoperator: string; + function getfullname(const tup: resultinfoarty): string; + function getbreakpointinfo(var atup: resultinfoty; + var info: breakpointinfoty; const full: boolean): boolean; + procedure updatepascalexpression(var aexpression: string); + procedure updatecurrentlanguage(); + function setlangc(): string; //returns currentlang + function setlang(const alanguage: string): gdbresultty; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure startgdb(commandline: msestring); + procedure closegdb; + function interrupttarget: gdbresultty; //stop for breakpointsetting + function restarttarget: gdbresultty; + function tryconnect: boolean; + + function togdbfilepath(const filename: filenamety): filenamety; + + procedure consolecommand(acommand: string); + function source(const afilename: filenamety): gdbresultty; //run script + function micommand(const command: string; + out values: resultinfoarty): gdbresultty; + //false on error or timeout, values = nil on timeout + function geterrormessage(const aresult: gdbresultty): string; + property errormessage: string read ferrormessage; + //for synccommand if error = gdb_message + + function handle(const signame: string; + const aflags: sigflagsty): gdbresultty; + // + function breakinsert(var info: breakpointinfoty): gdbresultty; overload; + function breakinsert(const funcname: string): integer; overload; + //returns bkpt id, -1 on error + function breakinsert(const address: qword): integer; overload; + function breaklist(var list: breakpointinfoarty; + const full: boolean): gdbresultty; + //full = false -> only bkptno, address and passcount + function breakdelete(bkptnum: integer): gdbresultty; //bkptnum = 0 -> all + function breakenable(bkptnum: integer; value: boolean): gdbresultty; + //bkptnum = 0 -> all + function breakafter(bkptnum: integer; const passcount: integer): gdbresultty; + function breakcondition(bkptnum: integer; + const condition: string): gdbresultty; + function infobreakpoint(var info: breakpointinfoty; + const full: boolean = true): gdbresultty; + //updates info for breakpoint info.bkptnum + function watchinsert(var info: watchpointinfoty): gdbresultty; + + function getstopinfo(const response: resultinfoarty; + const lastconsoleoutput: ansistring; + out info: stopinfoty): boolean; + + function getvalueindex(const response: resultinfoarty; + const aname: string): integer; + //-1 if not found + function getenumvalue(const response: resultinfoarty; + const aname: string; const enums: array of string; + var avalue: integer): boolean; + function gettuplevalue(const response: resultinfoarty; const aname: string; + var avalue: resultinfoarty): boolean; overload; + function gettuplevalue(const response: resultinfoty; + var avalue: resultinfoarty): boolean; overload; + function gettuplevalue(const response: resultinfoty; const aname: string; + var avalue: resultinfoarty): boolean; overload; + function gettuplestring(const response: resultinfoarty; const aname: string; + var avalue: string): boolean; overload; + + function getstringvalue(const response: resultinfoarty; const aname: string; + var avalue: string): boolean; overload; + function getstringvalue(const response: resultinfoty; const aname: string; + var avalue: string): boolean; overload; + function getintegervalue(const response: resultinfoarty; const aname: string; + var avalue: integer): boolean; overload; + function getintegervalue(const response: resultinfoty; const aname: string; + var avalue: integer): boolean; overload; + function getinteger64value(const response: resultinfoarty; + const aname: string; + var avalue: int64): boolean; overload; + function getinteger64value(const response: resultinfoty; const aname: string; + var avalue: int64): boolean; overload; + function getbooleanvalue(const response: resultinfoarty; const aname: string; + var avalue: boolean): boolean; + function getqwordvalue(const response: resultinfoarty; const aname: string; + var avalue: qword): boolean; overload; + function getqwordvalue(const response: resultinfoty; const aname: string; + var avalue: qword): boolean; overload; + + function getarrayvalue(const response: resultinfoarty; const aname: string; + const hasitemnames: boolean; + var avalue: resultinfoarty): boolean; + + function gettuplearrayvalue(const response: resultinfoarty; + const aname: string; var avalue: resultinfoararty): boolean; + function getstringarrayvalue(const response: resultinfoarty; + const aname: string; var avalue: stringarty): boolean; + function getbytearrayvalue(const response: resultinfoarty; + const aname: string; var avalue: bytearty): boolean; + function getwordarrayvalue(const response: resultinfoarty; + const aname: string; var avalue: wordarty): boolean; + function getlongwordarrayvalue(const response: resultinfoarty; + const aname: string; var avalue: longwordarty): boolean; + function getqwordarrayvalue(const response: resultinfoarty; + const aname: string; var avalue: card64arty): boolean; + + function fileexec(const filename: filenamety; + const noproginfo: boolean = false): gdbresultty; + function filesymbol(const filename: filenamety): gdbresultty; + function attach(const procid: longword; out info: stopinfoty): gdbresultty; + function attachtarget(out info: stopinfoty): gdbresultty; + function detach: gdbresultty; + function getprocid(var aprocid: int64): boolean; + //true if ok + function clearenvvars: gdbresultty; + function setenvvar(const aname,avalue: string): gdbresultty; + function unsetenvvar(const aname: string): gdbresultty; + + function download(const runafterload: boolean): gdbresultty; + function run: gdbresultty; + procedure continue; + procedure next; + procedure step; + procedure finish; + procedure nexti; + procedure stepi; + procedure interrupt; + procedure abort; + procedure targetwriteln(const avalue: string); + //sends text to target if running + + procedure debugbegin; //calls GUI_DEBUGBEGIN in target + procedure debugend; //calls GUI_DEBUGEND in target, + //automatically on every target start + + function active: boolean; //gdb running + function cancommand: boolean; //active and target not running + function started: boolean; //target active, run command applied or attached + property running: boolean read getrunning; //target running + function downloading: boolean; + function downloaded: boolean; + + function threadselect(const aid: integer; out filename: filenamety; + out line: integer): gdbresultty; + function getthreadidlist(out idlist: integerarty): gdbresultty; + function getthreadinfolist(out infolist: threadinfoarty): gdbresultty; + + function readmemorybytes(const address: qword; const count: integer; + var aresult: bytearty): gdbresultty; + function readmemorywords(const address: qword; const count: integer; + var aresult: wordarty): gdbresultty; + function readmemorylongwords(const address: qword; const count: integer; + var aresult: longwordarty): gdbresultty; + function readmemoryqwords(const address: qword; const count: integer; + var aresult: card64arty): gdbresultty; + function readmemorybyte(const address: qword; + out aresult: byte): gdbresultty; + function readmemoryword(const address: qword; + out aresult: word): gdbresultty; + function readmemorylongword(const address: qword; + out aresult: longword): gdbresultty; + function readmemorypointer(const address: qword; + out aresult: qword): gdbresultty; + function writememory8(const address: qword; + const avalue: card8): gdbresultty; + function writememory16(const address: qword; + const avalue: card16): gdbresultty; + function writememory32(const address: qword; + const avalue: card32): gdbresultty; + function writememory64(const address: qword; + const avalue: card64): gdbresultty; + + function readpascalvariable(varname: string; + out aresult: msestring): gdbresultty; + function writepascalvariable(varname: string; const value: string; + var aresult: string): gdbresultty; + function executecommand(const acommand: string; + out aresult: string): gdbresultty; + function evaluateexpression(expression: string; out aresult: string; + const noupdatepascalexpression: boolean = false): gdbresultty; + function symboltype(symbol: string; + out aresult: ansistring): gdbresultty; + function symboladdress(symbol: string; + out aresult: ansistring): gdbresultty; + function stacklistframes(out list: frameinfoarty; first: integer = 0; + last: integer = 100): gdbresultty; + function selectstackframe(const aframe: integer): gdbresultty; + function selectstackpointer(const aframe: qword): gdbresultty; + function getsourcename(out path: filenamety; out language: languagety; + frame: integer = 0): gdbresultty; + function getprocaddress(const procname: string; + out aaddress: qword): gdbresultty; + + function getpc(out addr: qword): gdbresultty; + function getregistervalue(const aname: string; + out avalue: qword): gdbresultty; + function setregistervalue(const aname: string; + const avalue: qword): gdbresultty; + function listregisternames(out aresult: stringarty): gdbresultty; + function listregistervalues(out aresult: registerinfoarty): gdbresultty; + function listlines(const path: filenamety; out lines: integerarty; + out addresses: qwordarty): gdbresultty; + + function getsystemregister(const anumber: integer; + out avalue: qword): gdbresultty; + function setsystemregister(const anumber: integer; + const avalue: qword): gdbresultty; + //for avr32 + function infoline(const filename: filenamety; const line: integer; + out start,stop: qword): gdbresultty; overload; + function infoline(const address: qword; out filename: filenamety; + out line: integer; + out start,stop: qword): gdbresultty; overload; + function infosymbol(const symbol: msestring; + out info: msestring): gdbresultty; + function infoaddress(const symbol: msestring; + out aresult: msestring): gdbresultty; + function disassemble(out aresult: asmlinearty; const filename: filenamety; + const line: integer; const count: integer): gdbresultty; overload; + function disassemble(out aresult: asmlinearty; + const start,stop: qword): gdbresultty; overload; + function disassemble(out aresult: disassarty; const filename: filenamety; + const line: integer; const count: integer): gdbresultty; overload; + function disassemble(out aresult: disassarty; + const start,stop: qword): gdbresultty; overload; + function getframeaddress(out address: qword): gdbresultty; + + property execloaded: boolean read getexecloaded; + property attached: boolean read getattached; + property stoponexception: boolean read fstoponexception + write setstoponexception default false; + property ignoreexceptionclasses: stringarty read fignoreexceptionclasses + write setignoreexceptionclasses; + property pointersize: integer read fpointersize; + property pointerhexdigits: integer read fpointerhexdigits; + property stoptime: tdatetime read fstoptime; + + property progparameters: string read fprogparameters write fprogparameters; + property workingdirectory: filenamety read fworkingdirectory + write fworkingdirectory; + property loadtimeoutus: integer read floadtimeoutus write floadtimeoutus; + //0 -> default +// {$ifdef mswindows} + property newconsole: boolean read fnewconsole write fnewconsole; +// {$endif} + property processorname: ansistring read getprocessorname + write setprocessorname; + property currentlanguage: languagety read fcurrentlanguage; + published + property guiintf: boolean read fguiintf write fguiintf default false; + //call GUI_DEBUGBEGIN/END + property remoteconnection: msestring read fremoteconnection + write fremoteconnection; + property gdbdownload: boolean read fgdbdownload write fgdbdownload; + property settty: boolean read fsettty write fsettty default true; + property simulator: boolean read fsimulator write fsimulator; + property processor: processorty read fprocessor + write fprocessor default pro_i386; + property beforeconnect: filenamety read fbeforeconnect write fbeforeconnect; + property afterconnect: filenamety read fafterconnect write fafterconnect; + property beforeload: filenamety read fbeforeload write fbeforeload; + property afterload: filenamety read fafterload write fafterload; + property beforerun: filenamety read fbeforerun write fbeforerun; + //gdb script + property startupbkpt: longword read fstartupbkpt write fstartupbkpt; + property startupbkpton: boolean read fstartupbkpton write fstartupbkpton; + property onevent: gdbeventty read fonevent write fonevent; + property onerror: gdbeventty read fonerror write fonerror; + property overloadsleepus: integer read foverloadsleepus + write setoverloadsleepus default -1; + {$warnings off} + property xtermcommand: filenamety read fxtermcommand write fxtermcommand; + //${PTS} expands to tty pts path + //${PTSN} expands to tty pts number + //${PTSH} expands to tty pts handle + {$warnings on} + property fpcworkaround: boolean read ffpcworkaround write + ffpcworkaround default false; + end; + +procedure localizetext; + +implementation +uses + sysutils,mseformatstr,mseprocutils,msesysutils,msefileutils,msemacros, + msebits,msesysintf,msesysintf1,mseguiintf,msearrayutils,msesys,msedate, + actionsmodule + {$ifdef UNIX},mselibc{$else},windows,msedynload{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifdef mswindows} + {$ifdef mse_usedebugbreakprocess} +var + debugbreakprocess: function(Process: HANDLE): BOOL; stdcall; + {$endif} +{$endif} + +type + tpypereader1 = class(tpipereader); +const + stopreasons: array[stopreasonty] of string = + //sr_none sr_unknown, sr_error sr_startup sr_exception sr_gdbdied + ('', '', '', '', '', '', + 'breakpoint-hit','watchpoint-trigger','read-watchpoint-trigger', + 'access-watchpoint-trigger', + 'end-stepping-range','function-finished','exited-normally', + 'exited','detached','signal-received'); + +procedure getcstring(var text: pchar); +var + po1: pchar; +begin + if text <> nil then begin + if text^ = '"' then begin + po1:= text; + repeat + if po1^ = '\' then begin + inc(po1); + if po1^ = #0 then begin + break; + end; + end; + inc(po1); + until (po1^ = '"') or (po1^ = #0); + if po1^ <> #0 then begin + text:= po1+1; + end; + end; + end; +end; + +procedure gettuple(var text: pchar); +var + level: integer; + po1: pchar; +begin + if text <> nil then begin + level:= 0; + po1:= text; + repeat + case po1^ of + '{': begin + inc(level); + end; + '}': begin + dec(level); + end; + '"': begin + getcstring(po1); + dec(po1); + end; + end; + inc(po1); + until (level <= 0) or (po1^ = #0); + text:= po1; + end; +end; + +procedure getlist(var text: pchar); +var + level: integer; + po1: pchar; +begin + if text <> nil then begin + level:= 0; + po1:= text; + repeat + case po1^ of + '[': begin + inc(level); + end; + ']': begin + dec(level); + end; + '"': begin + getcstring(po1); + dec(po1); + end; + '{': begin + gettuple(po1); + dec(po1); + end; + end; + inc(po1); + until (level <= 0) or (po1^ = #0); + text:= po1; + end; +end; + +procedure decoderesult(const noname: boolean; var text: pchar; out resultinfo: resultinfoty); + +var + po1,po2: pchar; +begin + if noname then begin + po1:= text; + end + else begin + po1:= strscan(text,'='); + end; + with resultinfo do begin + if po1 = nil then begin + variablename:= text; + value:= ''; + end + else begin + variablename:= psubstr(text,po1); + if not noname then begin + inc(po1); + end; + case po1^ of + '"': begin + value:= cstringtostringvar(po1); + valuekind:= vk_value; + end; + '{': begin + po2:= po1; + gettuple(po1); + value:= psubstr(po2+1,po1-1); + valuekind:= vk_tuple; + end; + '[': begin + po2:= po1; + getlist(po1); + value:= psubstr(po2+1,po1-1); + valuekind:= vk_list; + end; + end; + end; + end; + text:= po1; +end; + +{ tgdbstartupevent } + +constructor tgdbstartupevent.create(const dest: ievent); +begin + inherited create(ek_none,dest); + eventkind:= gek_startup; +end; + +{ tgdbmi } + +constructor tgdbmi.create(aowner: tcomponent); +begin + fsettty:= true; + fpointersize:= sizeof(pointer); + fpointerhexdigits:= fpointersize * 2; + fgdb:= invalidprochandle; + fguiintf:= true; + fsourcefiles:= tmsestringhashdatalist.create(); +// fsourcefiles:= thashedmsestrings.create; + fstoptime:= emptydatetime; + {$ifdef UNIX} + ftargetterminal:= tpseudoterminal.create; + ftargetterminal.input.oninputavailable:= {$ifdef FPC}@{$endif}targetfrom; + ftargetconsole:= tcustommseprocess.create(nil); + ftargetconsole.options:= [pro_output,pro_errorouttoout]; +// ftargetconsole.filename:= 'xterm'; + ftargetconsole.output.oninputavailable:= {$ifdef FPC}@{$endif}xtermfrom; + {$endif} + foverloadsleepus:= -1; + inherited; +end; + +destructor tgdbmi.destroy; +begin + closegdb; + inherited; + fsourcefiles.free; + {$ifdef UNIX} + ftargetconsole.free; + ftargetterminal.free; + {$endif} +end; + +procedure tgdbmi.resetexec; +begin + fstate:= fstate - [gs_internalrunning,gs_running,gs_stopped, + gs_execloaded,gs_canstop, + gs_attached,gs_attaching,gs_started,gs_startup,gs_detached, + gs_remote,gs_async, + gs_interrupted,gs_restarted, + gs_downloaded,gs_downloading]; + {$ifdef mswindows} + finterruptthreadid:= 0; + {$endif} + finterruptcount:= 0; + fprocid:= 0; + fcurrentprocid:= 0; + flastbreakpoint:= 0; + ftargetdebugbegin:= 0; + ftargetdebugend:= 0; + fstartupbreakpoint:= -1; + fstartupbreakpoint1:= -1; + fstopinfo:= nil; + fstopthreadid:= -1; + fcurrthreadid:= -1; +end; + +procedure tgdbmi.closegdb; +{$ifdef mswindows} +var + int1: integer; +{$endif} +begin + if not (gs_closing in fstate) then begin + include(fstate,gs_closing); + if fgdb <> invalidprochandle then begin + abort; + end; + {$ifdef mswindows} + if fgdb <> invalidprochandle then begin + int1:= fgdb; + fgdb:= invalidprochandle; + killprocess(int1); + end; + {$else} + if fgdbfrom <> nil then begin + fgdbfrom.terminate; + end; + { + if fgdberror <> nil then begin + fgdberror.terminate; + end; + } + if fgdb <> invalidprochandle then begin + killprocess(fgdb); + fgdb:= invalidprochandle; + end; + {$endif} + fgdbto.free; + fgdbto:= nil; + fgdbfrom.free; + fgdbfrom:= nil; +// fgdberror.free; +// fgdberror:= nil; + fsourcefiles.clear; + fsourcefiledirs:= nil; + resetexec; + fstate:= fstate - [gs_closing,gs_gdbdied]; + end; +end; + +procedure tgdbmi.startgdb(commandline: msestring); +const + lcmessages = 'LC_MESSAGES'; +var +(* +{$ifdef UNIX} + bo1: boolean; + str1: string; +{$endif} + *) + haslang: boolean; + langbefore: msestring; +begin + closegdb; + fgdbto:= tpipewriter.create; + fgdbfrom:= tpipereader.create; + fgdbfrom.overloadsleepus:= foverloadsleepus; + fgdbfrom.oninputavailable:= {$ifdef FPC}@{$endif}gdbfrom; + fgdbfrom.onpipebroken:= {$ifdef FPC}@{$endif}gdbpipebroken; + fconsolesequence:= 0; + frunsequence:= 0; + fsequence:= 1; + flastbreakpoint:= 0; + haslang:= sys_getenv(lcmessages,langbefore); + sys_setenv(lcmessages,'C'); + + fgdb:= execmse2(syscommandline(commandline)+' --interpreter=mi --nx', + fgdbto,fgdbfrom,fgdbfrom,-1, + [exo_inactive,exo_tty,exo_winpipewritehandles]); + + if haslang then begin + sys_setenv(lcmessages,langbefore); + end + else begin + sys_unsetenv(lcmessages); + end; + if fgdb <> invalidprochandle then begin + if haslang then begin + setenv(lcmessages,ansistring(langbefore)); + end + else begin + unsetenv(lcmessages); + end; + clicommand('set breakpoint pending on'); + clicommand('set height 0'); + clicommand('set width 0'); + {$ifdef UNIX} + { + bo1:= true; + if synccommand('-gdb-show inferior-tty') = gdb_ok then begin + if getstringvalue(fsyncvalues,'value',str1) and (str1 <> '') then begin + bo1:= false; + end; + end; + if bo1 then begin + } + if fsettty or fnewconsole then begin + clicommand('tty '+ftargetterminal.devicename); + end; + {$endif} + end; +end; + +function tgdbmi.getrunning: boolean; +begin + result:= gs_running in fstate; +end; + +function tgdbmi.getexecloaded: boolean; +begin + result:= gs_execloaded in fstate; +end; + +function tgdbmi.getattached: boolean; +begin + result:= gs_attached in fstate; +end; + +procedure tgdbmi.debugbegin; //calls GUI_DEBUGBEGIN in target +begin + if ftargetdebugbegin <> 0 then begin + if clicommand('call GUI_DEBUGBEGIN()') <> gdb_ok then begin + clicommand('call '+inttostr(ftargetdebugbegin)+'()'); + end; + end; +end; + +procedure tgdbmi.debugend; //calls GUI_DEBUGEND in target +begin + exclude(fstate,gs_stopped); + if ftargetdebugend <> 0 then begin + if clicommand('call GUI_DEBUGEND()') <> gdb_ok then begin + clicommand('call '+inttostr(ftargetdebugend)+'()'); + end; + end; +end; + +function tgdbmi.active: boolean; +begin + result:= fgdb <> invalidprochandle; +end; + +function tgdbmi.cancommand: boolean; +begin + result:= active and not running; +end; + +procedure tgdbmi.setstoponexception(const avalue: boolean); +begin + if fstoponexception <> avalue then begin + if gs_internalrunning in fstate then begin + raise exception.Create('Target running!'); + end; + if fexceptionbkpt >= 0 then begin + breakenable(fexceptionbkpt,avalue); + fstoponexception:= avalue; + end; + end; +end; + +var + workaround: string; + +procedure tgdbmi.setignoreexceptionclasses(const avalue: stringarty); +var + int1: integer; +begin + setlength(fignoreexceptionclasses,length(avalue)); + for int1:= 0 to high(avalue) do begin + workaround:= uppercase(avalue[int1]); //see FPC Mantis 11290 + fignoreexceptionclasses[int1]:= workaround; +// fignoreexceptionclasses[int1]:= uppercase(avalue[int1]); + end; +end; + +procedure tgdbmi.checkactive; +begin + if not active then begin + raise exception.Create('GDB not active!'); + end; +end; + +procedure tgdbmi.consoleoutput(const text: string); +begin +// write(text); +end; + +procedure tgdbmi.targetoutput(const text: string); +var + ev: tgdbevent; +begin + if assigned(fonevent) then begin + ev:= tgdbevent.create(ek_none,ievent(self)); + ev.eventkind:= gek_targetoutput; + setlength(ev.values,1); + ev.values[0].value:= text; + application.postevent(ev); + end; +end; + +procedure tgdbmi.logoutput(const text: string); +begin + flogtext:= text; +// consoleoutput(text); +end; + +function tgdbmi.getprocid(var aprocid: int64): boolean; +var + ar1,ar2: stringarty; + int1: integer; + str1: string; +begin + if fcurrentprocid <> 0 then begin + aprocid:= fcurrentprocid; + result:= true; + exit; + end; + result:= false; + ar2:= nil; + if getcliresult('info program',ar1) = gdb_ok then begin + for int1:= 0 to high(ar1) do begin + if (pos('child thread',ar1[int1]) > 0) or + (pos('attached thread',ar1[int1]) > 0) or + (pos('attached LWP',ar1[int1]) > 0) then begin + splitstring(ar1[int1],ar2,' '); + if high(ar2) > 0 then begin + ar1:= nil; + splitstring(ar2[high(ar2)],ar1,'.'); + if high(ar1) > 0 then begin + if trystrtointvalue64(ar1[0],qword(aprocid)) then begin + result:= true; + end; + end; + end; + break; + end + else begin + if (pos('child Thread',ar1[int1]) > 0) or + (pos('attached Thread',ar1[int1]) > 0) then begin + splitstring(ar1[int1],ar2,' '); + if high(ar2) > 0 then begin + str1:= ar2[high(ar2)]; + if (length(str1) > 2) and (str1[length(str1)-1] = ')') then begin + str1:= copy(str1,1,length(str1) - 2); + if trystrtointvalue64(str1,qword(aprocid)) then begin + result:= true; + end; + end + else begin + if str1 <> '' then begin + ar2:= splitstring(str1,'.'); + if trystrtointvalue64(ar2[0],qword(aprocid)) then begin + result:= true; + end; + end; + end; + end; + break; + end + else begin + if (pos('child process',ar1[int1]) > 0) or + (pos('attached process',ar1[int1]) > 0) then begin + splitstring(ar1[int1],ar2,' '); + if high(ar2) > 0 then begin + str1:= ar2[high(ar2)]; + if (length(str1) > 1) and (str1[length(str1)] = '.') then begin + str1:= copy(str1,1,length(str1) - 1); + try + aprocid:= strtointvalue(str1); + result:= true; + except + end; + end; + end; + break; + end; + end; + end; + end; + end; +end; + +function tgdbmi.clearenvvars: gdbresultty; +var + int1: integer; +begin + result:= gdb_ok; + if active then begin + for int1:= 0 to high(fenvvars) do begin + with fenvvars[int1] do begin + if not unset then begin + result:= clicommand('unset environement '+fenvvars[int1].name); + if result <> gdb_ok then begin + break; + end; + end; + end; + end; + end; + fenvvars:= nil; +end; + +function tgdbmi.setenv(const aname,avalue: string): gdbresultty; +begin + result:= synccommand('-gdb-set environment '+aname+'='+avalue); +end; + +function tgdbmi.unsetenv(const aname: string): gdbresultty; +begin + result:= clicommand('unset environment '+aname); +end; + +function tgdbmi.setenvvar(const aname,avalue: string): gdbresultty; +var + int1: integer; +begin + result:= gdb_ok; + if active then begin + result:= setenv(aname,avalue); + end; + if result = gdb_ok then begin + for int1:= 0 to high(fenvvars) do begin + if aname = fenvvars[int1].name then begin + fenvvars[int1].value:= avalue; + fenvvars[int1].unset:= false; + exit; + end; + end; + setlength(fenvvars,high(fenvvars)+2); + with fenvvars[high(fenvvars)] do begin + name:= aname; + value:= avalue; + end; + end; +end; + +function tgdbmi.unsetenvvar(const aname: string): gdbresultty; +var + int1: integer; +begin + result:= gdb_ok; + if active then begin + unsetenv(aname); + end; + if result = gdb_ok then begin + for int1:= 0 to high(fenvvars) do begin + if aname = fenvvars[int1].name then begin + fenvvars[int1].value:= ''; + fenvvars[int1].unset:= true; + exit; + end; + end; + setlength(fenvvars,high(fenvvars)+2); + with fenvvars[high(fenvvars)] do begin + name:= aname; + unset:= true; + end; + end; +end; + +function tgdbmi.getshortstring(const address: string; out avalue: string): boolean; +var + str1: string; + int1: card64; + ar1: bytearty; +begin + avalue:= ''; + result:= evaluateexpression(address,str1) = gdb_ok; + if result then begin + if trystrtohex64(str1,int1) then begin + if readmemorybytes(int1,1,ar1) = gdb_ok then begin + if ar1[0] <> 0 then begin + if readmemorybytes(int1+1,ar1[0],ar1) = gdb_ok then begin + setlength(avalue,length(ar1)); + move(ar1[0],avalue[1],length(avalue)); + result:= true; + end; + end; + end; + end + else begin + result:= false; + end; + end; +end; + +procedure tgdbmi.initstopinfo(var ainfo: stopinfoty); +begin + finalize(ainfo); + fillchar(ainfo,sizeof(ainfo),0); + ainfo.time:= nowlocal; +end; + +const + getexceptionname: array[processorty] of string = ( +//pro_i386, pro_x86_64, pro_arm, pro_armm3, + '($eax^+12)^','ppointer(ppointer($rax)^+24)^','($r0^+12)^','($r0^+12)^', +//pro_cpu32,pro_avr32,pro_rl78 + '', '', ''); + +procedure tgdbmi.receiveevent(const event: tobjectevent); +var + stopinfo: stopinfoty; + bo1: boolean; + int1: integer; + str1,str2: string; + ar1: resultinfoarty; + {$ifdef mswindows} + threadids: integerarty; + {$endif} + mstr1: filenamety; + +begin + if event is tgdbevent then begin + initstopinfo(stopinfo); + with tgdbevent(event) do begin + case eventkind of + gek_startup: begin + include(self.fstate,gs_canstop); + if gs_startup in self.fstate then begin + exit; //already done + end; + include(self.fstate,gs_startup); + stopinfo:= tgdbstartupevent(event).stopinfo; + eventkind:= gek_stopped; + end; + gek_gdbdied: begin + exclude(self.fstate,gs_running); + fstoptime:= stopinfo.time; + stopinfo.reason:= sr_gdbdied; + stopinfo.messagetext:= 'Process died.'; + if getprocessexitcode(fgdb,int1,2000000) = pee_ok then begin + stopinfo.messagetext:= stopinfo.messagetext + + ' Exitcode: '+inttostr(int1)+'.'; + fgdb:= invalidprochandle; + end; + closegdb; + end; + gek_stopped: begin + exclude(self.fstate,gs_running); + fstoptime:= stopinfo.time; + if gs_canstop in self.fstate then begin + {$ifdef mswindows} + if finterruptthreadid <> 0 then begin + if getthreadidlist(threadids) = gdb_ok then begin + if high(threadids) > 0 then begin + if threadselect(threadids[1],mstr1,int1) = gdb_ok then begin + setlength(values,3); + with values[0] do begin + variablename:= 'reason'; + valuekind:= vk_value; + value:= stopreasons[sr_signal_received]; + end; + with values[1] do begin + variablename:= 'signal-name'; + valuekind:= vk_value; + value:= 'SIGTRAP'; + end; + with values[2] do begin + variablename:= 'thread-id'; + valuekind:= vk_value; + value:= inttostr(threadids[1]); + end; + if gettuplestring(fsyncvalues,'frame',str1) then begin + setlength(values,4); + with values[3] do begin + variablename:= 'frame'; + valuekind:= vk_tuple; + value:= str1; + end; + end; + end; + end; + end; + finterruptthreadid:= 0; + end; + {$endif mswindows} + if fthreadid <> -1 then begin + threadselect(fthreadid,mstr1,int1); + //there was an breakpoint in other thread + end; + bo1:= getstopinfo(values,flastconsoleoutput,stopinfo); + if not bo1 then begin + stopinfo.messagetext:= ansistring(actionsmo.c[ord(ac_stoperror)])+': ' + + stopinfo.messagetext; + end + else begin + if (stopinfo.reason = sr_breakpoint_hit) and + (stopinfo.bkptno = fexceptionbkpt) then begin + if (getexceptionname[processor] <> '') and + getshortstring(getexceptionname[processor],str1) then begin + str2:= uppercase(str1); + bo1:= false; + for int1:= 0 to high(fignoreexceptionclasses) do begin + if str2 = fignoreexceptionclasses[int1] then begin + bo1:= true; + break; + end; + end; + if bo1 then begin + self.fstate:= self.fstate + [gs_restarted,gs_running]; + continue; + stopinfo.reason:= sr_none; + end + else begin + stopinfo.messagetext:= 'Exception '+str1+'.'; + stopinfo.reason:= sr_exception; + end; + end; + end; + if stopinfo.reason in [sr_exited,sr_exited_normally] then begin + self.fstate:= self.fstate - [gs_started,gs_startup]; + end; + if stopinfo.reason = sr_startup then begin + if fstartupbreakpoint >= 0 then begin + breakdelete(fstartupbreakpoint); + fstartupbreakpoint:= -1; + end; + if fstartupbreakpoint1 >= 0 then begin + breakdelete(fstartupbreakpoint1); + fstartupbreakpoint1:= -1; + end; + fprocid:= 0; + getprocid(fprocid); + {$ifdef UNIX} + if not fnewconsole then begin + ftargetterminal.restart; + end; + {$endif} + if gs_startup in self.fstate then begin + exit; //already done + end; + include(self.fstate,gs_startup); + include(self.fstate,gs_started); //gek_running can be missed + end; + end; + end; + end; + gek_running: begin + fstoptime:= emptydatetime; + include(self.fstate,gs_running); + end; + gek_error,gek_writeerror: begin + getstringvalue(values,'msg',stopinfo.messagetext); + end; + gek_done: begin + if gs_downloading in self.fstate then begin + include(self.fstate,gs_downloaded); + with stopinfo do begin + getintegervalue(values,'load-size',totalsent); + if fafterload <> '' then begin + if source(fafterload) <> gdb_ok then begin + exclude(self.fstate,gs_downloaded); + postsyncerror; + end; + end; +// include(self.fstate,gs_downloading); +// //restore downloading flag; + if gs_runafterload in self.fstate then begin + initproginfo; + dorun; + end; + end; + end; + end; + gek_download: begin + if (high(values) >= 0) and gettuplevalue(values[0],ar1) then begin + with stopinfo do begin + getstringvalue(ar1,'section',section); + getintegervalue(ar1,'section-sent',sectionsent); + getintegervalue(ar1,'section-size',sectionsize); + getintegervalue(ar1,'total-sent',totalsent); + getintegervalue(ar1,'total-size',totalsize); + end; + end; + end; + end; + try + if assigned(fonevent) and + not((eventkind = gek_stopped) and (stopinfo.reason = sr_none)) then begin + fonevent(self,eventkind,values,stopinfo); + end; + if (eventkind = gek_error) and assigned(fonerror) then begin + fonerror(self,eventkind,values,stopinfo); + end; + if (eventkind = gek_done) and + (self.fstate * [gs_downloading,gs_runafterload] = + [gs_downloading,gs_runafterload]) then begin + exclude(self.fstate,gs_downloading); + dorun; + end; + finally + if eventkind = gek_done then begin + exclude(self.fstate,gs_downloading); + end; + end; + end; + end + else begin + inherited; + end; +end; + +procedure tgdbmi.doevent(const token: longword; const eventkind: gdbeventkindty; + values: resultinfoarty); +var + ev: tgdbevent; + id1: integer; +begin + id1:= fcurrthreadid; + if (token <> 0) and (token = fsyncsequence) then begin + fsyncvalues:= values; + fsynceventkind:= eventkind; + include(fstate,gs_syncack); + exclude(fstate,gs_syncget); + end; + if not (gs_detached in fstate) then begin + case eventkind of + gek_running: begin + frunsequence:= token; + fstate:= fstate + [gs_internalrunning,gs_started]; + end; + gek_stopped: begin + if values <> nil then begin + fstopinfo:= values; + fstopthreadid:= fcurrthreadid; + id1:= -1; //no thread switch necessary; + end; + values:= fstopinfo; + exclude(fstate,gs_internalrunning); + if gs_attaching in fstate then begin + exit; //ignore + end; + end; + gek_error: begin + exclude(fstate,gs_downloading); + end; + end; + if (eventkind = gek_error) and (token <> 0) and (token = frunsequence) then begin + doevent(token,gek_stopped,values); + end + else begin + if assigned(fonevent) and (eventkind = gek_writeerror) or + not ((eventkind = gek_stopped) and (gs_interrupted in fstate)) and + not ((eventkind = gek_running) and + ([gs_attaching,gs_restarted] * fstate <> [])) and + not ((eventkind = gek_error) and (fsyncsequence <> 0) and + (integer(token-fsyncsequence) < 0)) and + ((token = 0) or (token <> fsyncsequence) or (eventkind = gek_running) or + (eventkind = gek_stopped)) then begin + ev:= tgdbevent.create(ek_none,ievent(self)); + ev.eventkind:= eventkind; + ev.values:= copy(values); + ev.flastconsoleoutput:= flastconsoleoutput; + ev.fthreadid:= id1; + application.postevent(ev); + end; + if eventkind = gek_running then begin + exclude(fstate,gs_restarted); + end; + end; + end; +end; + +procedure tgdbmi.postsyncerror; +begin + doevent(0,gek_error,fsyncvalues); +end; + +procedure tgdbmi.sequenceend; +begin +{ + if fsequence = 1 then begin //startup + consoleoutput('(gdb)'); + end; +} +end; + +function tgdbmi.decodelist(const noname: boolean; const inp: string; + var value: resultinfoarty): boolean; +var + po1: pchar; + int1: integer; + str1: string; +begin + result:= true; + value:= nil; + if (pointer(inp) <> nil) then begin + str1:= inp; //avoid stringrelease + po1:= pchar(str1); + int1:= 0; + while true do begin + if int1 > high(value) then begin + setlength(value,int1+16); + end; + decoderesult(noname,po1,value[int1]); + inc(int1); + if (po1 = nil) or (po1^ <> ',') then begin + break; + end; + inc(po1); + end; + setlength(value,int1); + str1:= ''; //avoid stringrelease + end; +end; + +procedure tgdbmi.interpret(const line: string); + +var + po1,po2: pchar; + token: longword; + ch1: char; + recordclass: recordclassty; + isconsole: boolean; + resultar: resultinfoarty; + + function getrecordinfo(start,stop: recordclassty): boolean; + var + int1: integer; + begin + result:= false; + int1:= length(resultar); + for start:= start to stop do begin + if startsstr(pchar(recordclassnames[start]),po2) then begin + po2:= po2 + length(recordclassnames[start]); + recordclass:= start; + result:= true; + while (po2 <> nil) and (po2^ = ',') do begin + if int1 > high(resultar) then begin + setlength(resultar,2*high(resultar)+8); + end; + inc(po2); + decoderesult(recordclassnoname[recordclass],po2,resultar[int1]); + inc(int1); + end; + break; + end; + end; + setlength(resultar,int1); + end; + +var + targetoutp: boolean; + +begin +//{$ifdef mse_debuggdb} +// debugwriteln(line); +//{$endif} + resultar:= nil; + po1:= pchar(line); + po2:= po1; + while (po2^ >= '0') and (po2^ <= '9') do begin + inc(po2); + end; + if po2 <> po1 then begin + if not trystrtoint(psubstr(po1,po2),token) then begin + token:= 0; + end; + end + else begin + token:= 0; + end; + isconsole:= (token <> 0) and (token = fconsolesequence); + if isconsole then begin + fconsolesequence:= 0; + end; + ch1:= po2^; + inc(po2); + try + targetoutp:= false; + case ch1 of + '~': begin + if gs_clicommand in fstate then begin + if gs_clilist in fstate then begin + setlength(fclivaluelist,high(fclivaluelist)+2); + fclivaluelist[high(fclivaluelist)]:= cstringtostring(po2); + end + else begin + fclivalues:= fclivalues + cstringtostring(po2); + end; + end + else begin + flastconsoleoutput:= cstringtostring(po2); + consoleoutput(flastconsoleoutput); + end; + end; + '@': targetoutput(cstringtostring(po2)); + '&': logoutput(cstringtostring(po2)); + '^': begin //result + if getrecordinfo(low(resultclassty),high(resultclassty)) then begin + case recordclass of + rec_connected: begin + doevent(token,gek_connected,resultar); + end; + rec_running: begin + if not (gs_stopped in fstate) then begin + //no breakpoint while GUI_DEBUGBEGIN + doevent(token,gek_running,resultar); + end; + end; + rec_done: begin + if isconsole then begin + consoleoutput('(gdb)'); + end; + doevent(token,gek_done,resultar); + end; + rec_error: begin + if isconsole then begin + if high(resultar) >= 0 then begin + consoleoutput(resultar[0].value+#$0a'(gdb)'); + end; + end; + doevent(token,gek_error,resultar); + end; + end; + end + else begin + targetoutp:= true; + end; + end; + '*','+','=': begin + if getrecordinfo(low(asyncclassty),high(asyncclassty)) then begin + case recordclass of + rec_stopped: begin + include(fstate,gs_stopped); + doevent(token,gek_stopped,resultar); + end; + rec_download: begin + doevent(token,gek_download,resultar); + end; + rec_threadselected: begin + if not getintegervalue(resultar,'id',fcurrthreadid) then begin + fcurrthreadid:= -1; + end; + end; + rec_threadgroupstarted: begin + getinteger64value(resultar,'pid',fcurrentprocid); + end; + end; + end + else begin + targetoutp:= true; + end; + end; + '(': begin + if startsstr(pchar('gdb)'),po2) then begin + sequenceend; + end; + end; + else begin + targetoutp:= true; + end; + end; + if targetoutp and running then begin + targetoutput(line+lineend); + end; + except + end; +end; + +procedure tgdbmi.gdbpipebroken(const sender: tpipereader); +var + ev: tgdbevent; +begin + if (fgdb <> invalidprochandle) and not (gs_gdbdied in fstate) then begin + include(fstate,gs_gdbdied); + ev:= tgdbevent.create(ek_none,ievent(self)); + ev.eventkind:= gek_gdbdied; + ev.flastconsoleoutput:= flastconsoleoutput; + application.postevent(ev); + end; +end; +{ +procedure tgdbmi.gdberror(const sender: tpipereader); +var + str1: string; +begin +// if fgdberror.eof then begin +// exit; +// end; + str1:= fgdberror.readdatastring; + targetoutput(str1); +// writedebug(str1); +end; +} + +procedure tgdbmi.gdbfrom(const sender: tpipereader); +var + str1,str2: string; + b1,b2: boolean; + int1: integer; +begin + b1:= false; //compiler warning + repeat + (* + if gs_syncget in fstate then begin + bo1:= fgdbfrom.readstrln(str1); + //does not post pipereader semaphore in case of timeout + {$ifdef mse_debuggdb} + if bo1 then begin + debugwriteln(str1); + end; + {$endif} + end + else begin + *) + str1:= ''; + int1:= 0; + while true do begin + b1:= fgdbfrom.readuln(str2,b2); + {$ifdef mse_debuggdb} + if b1 then begin + debugwriteln(str2); + end + else begin + debugwrite(str2); + end; + {$endif} + str1:= str1 + str2; + if str2 <> '' then begin + int1:= 0; + end; + if b1 or (str1 = '') or (int1 > 10) then begin + break; + end; + sys_schedyield; + inc(int1); + sleep(100); //try to get the lineend + end; + { + end; + } + if b1 then begin + interpret(str1); + end + else begin + if str1 <> '' then begin + targetoutput(str1); + end; + end; + until not b2; //all data read +end; + +{$ifdef UNIX} +procedure tgdbmi.targetfrom(const sender: tpipereader); +begin + if not sender.eof then begin + targetoutput(sender.readdatastring); + end; +end; + +procedure tgdbmi.killtargetconsole; +begin + ftargetconsole.kill; + ftargetterminal.outecho:= false; +end; + +function tgdbmi.createtargetconsole: boolean; +var + ar1: stringarty; + pts,ptsn,ptsh: msestring; +begin + result:= false; + if fxtermcommand <> '' then begin + ptsn:= ''; + ftargetterminal.outecho:= true; + pts:= msestring(ftargetterminal.devicename); + ar1:= splitstring(ftargetterminal.devicename,'/'); + if ar1 <> nil then begin + ptsn:= msestring(ar1[high(ar1)]); + end; + ptsh:= inttostrmse(ftargetterminal.fpty); + ftargetconsole.commandline:= +{$ifdef FPC} + expandmacros(fxtermcommand,['PTS','PTSN','PTSH'],[pts,ptsn,ptsh], + [mao_caseinsensitive]); +{$else} + expandmacrosstr(fxtermcommand,['PTS','PTSN','PTSH'],[pts,ptsn,ptsh], + [mao_caseinsensitive]); +{$endif} + ftargetconsole.active:= true; + result:= ftargetconsole.running; + end; +end; + +procedure tgdbmi.xtermfrom(const sender: tpipereader); +begin + targetoutput(sender.readdatastring); +end; + +{$endif} + +function tgdbmi.internalcommand(acommand: string): boolean; +var + ar1: resultinfoarty; +begin + result:= false; + checkactive; + fgdbfrom.responseflag:= false; + try + fgdbto.writeln(inttostr(fsequence)+acommand); + {$ifdef mse_debuggdb} + debugwriteln('>'+inttostr(fsequence)+'>'+acommand); + {$endif} + result:= true; + except + closegdb; + setlength(ar1,1); + with ar1[0] do begin + variablename:= 'msg'; + valuekind:= vk_value; + value:= 'Can not write to gdb.'; + end; + doevent(fsequence,gek_writeerror,ar1); +// raise; + end; + inc(fsequence); + if fsequence = 0 then begin + inc(fsequence); + end; +end; + +procedure tgdbmi.consolecommand(acommand: string); +begin + internalcommand(acommand); + fconsolesequence:= fsequence; +end; + +function tgdbmi.source(const afilename: filenamety): gdbresultty; +begin + result:= synccommand('source '+ + ansistring(quotefilename(tosysfilepath(afilename)))); +end; + +function tgdbmi.synccommand(const acommand: string; + atimeout: integer = defaultsynctimeout): gdbresultty; +var + timestamp: longword; + int1: integer; + +begin + if not active then begin + result:= gdb_notactive; + exit; + end; + result:= gdb_timeout; + interrupttarget; + setlength(fsyncvalues,0); + fsyncsequence:= fsequence; + exclude(fstate,gs_syncack); + include(fstate,gs_syncget); + if not internalcommand(acommand) then begin + result:= gdb_writeerror; + exit; + end; + timestamp:= timestep(atimeout); //max delay + int1:= application.unlockall; + try + while not timeout(timestamp) do begin + if not (gs_syncack in fstate) then begin + if not fgdbfrom.waitforresponse(100000,true) then begin + if not fgdbfrom.active then begin + break; + end; + end; + end + else begin + if fsynceventkind = gek_error then begin + if getstringvalue(fsyncvalues,'msg',ferrormessage) then begin + result:= gdb_message; + end + else begin + result:= gdb_error; + end; + end + else begin + result:= gdb_ok; + end; + break; + end; + end; + finally + application.relockall(int1); + exclude(fstate,gs_syncget); + fsyncsequence:= 0; + restarttarget; + end; + if result = gdb_timeout then begin + ferrormessage:= 'Timeout.'; + end; +end; + +function tgdbmi.geterrormessage(const aresult: gdbresultty): string; +begin + if aresult = gdb_message then begin + result:= errormessage; + end + else begin + if (aresult < low(gdbresultty)) or (aresult > high(gdbresultty)) then begin + result:= 'GDB Error ' + inttostr(ord(aresult)); + end + else begin + result:= gdberrortexts[aresult]; + end; + end; +end; + +function tgdbmi.micommand(const command: string; + out values: resultinfoarty): gdbresultty; + //values = nil on timeout +begin + result:= synccommand('-'+command); + values:= fsyncvalues; +end; + +function tgdbmi.togdbfilepath(const filename: filenamety): filenamety; +begin + result:= quotefilename(tosysfilepath(filepath(filename))); + {$ifdef mswindows} + replacechar1(result,msechar('\'),msechar('/')); + {$endif} +end; + +function tgdbmi.fileexec(const filename: filenamety; + const noproginfo: boolean = false): gdbresultty; +const + {$ifdef cpuarm} + loadwaitus = 20000000; + {$else} + loadwaitus = 10000000; + {$endif} +var + int1: integer; +begin + abort; + resetexec; + if filename = '' then begin + breakdelete(0); + result:= synccommand('-file-exec-and-symbols'); + end + else begin + if floadtimeoutus = 0 then begin + int1:= loadwaitus; + end + else begin + int1:= floadtimeoutus; + end; + result:= synccommand('-file-exec-and-symbols '+ + ansistring(togdbfilepath(filename)),int1); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(gs_execloaded),result = gdb_ok); + if (result = gdb_ok) and not noproginfo then begin + initinternalbkpts; + initproginfo; + end; + end; +end; + +function tgdbmi.filesymbol(const filename: filenamety): gdbresultty; +begin + abort; + resetexec; + if filename = '' then begin + breakdelete(0); + result:= synccommand('-file-symbol-file'); + end + else begin + result:= synccommand('-file-symbol-file '+ansistring(togdbfilepath(filename)), + 10000000); +// updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), +// ord(gs_execloaded),result = gdb_ok); + if result = gdb_ok then begin + initinternalbkpts; + initproginfo; + end; + end; +end; + +function tgdbmi.attach(const procid: longword; out info: stopinfoty): gdbresultty; +var + frames1: frameinfoarty; + wo1: longword; + int1: integer; +begin + abort; + resetexec; + fstate:= fstate+[gs_attaching{,gs_stopped}]; + result:= clicommand('attach '+inttostr(procid),false,10000000); + if result = gdb_ok then begin + wo1:= timestep(5000000); //5 seconds, sometimes necessary for + while (gs_internalrunning in fstate) and not timeout(wo1) do begin + int1:= application.unlockall; + sleepus(50000); //win32 gdb 7.2 sends ^running + application.relockall(int1); + end; + if gs_internalrunning in fstate then begin + result:= gdb_timeout; + end; + end; + exclude(fstate,gs_attaching); + finalize(info); + fillchar(info,sizeof(info),0); + info.reason:= sr_error; + if result = gdb_ok then begin +// if getprocid(fprocid) and (fprocid = procid) then begin + //win32 gdb 7.1 crashes with "info program" + fprocid:= procid; + include(self.fstate,gs_canstop); + result:= stacklistframes(frames1,0,1); + if (result = gdb_ok) or (result = gdb_message) then begin + if result = gdb_message then begin + info.messagetext:= errormessage; + result:= gdb_ok; + end + else begin + info.reason:= sr_startup; + fstate:= fstate + [gs_execloaded,gs_attached,gs_started,gs_startup]; + with frames1[0] do begin + info.filename:= filename; + info.line:= line; + info.messagetext:= 'Attached to process '+inttostr(procid) + ' File: '+ + ansistring(filename)+':'+inttostr(line)+' Function: '+func; + end; + end; +// end; + initinternalbkpts; + initproginfo; + end + else begin + info.messagetext:= 'Can not Attach to process '+inttostr(procid); + end; + end; + if result <> gdb_ok then begin + if result = gdb_message then begin + info.messagetext:= errormessage; + end + else begin + info.messagetext:= gdberrortexts[result]; + end; + end; +end; + +function tgdbmi.attachtarget(out info: stopinfoty): gdbresultty; +var + frames1: frameinfoarty; +begin + abort; + resetexec; + result:= gdb_ok; + finalize(info); + fillchar(info,sizeof(info),0); + info.reason:= sr_error; + result:= checkconnection(true); + if result = gdb_ok then begin + result:= stacklistframes(frames1,0,1); + if (result = gdb_ok) or (result = gdb_message) then begin + if result = gdb_message then begin + info.messagetext:= errormessage; + result:= gdb_ok; + end + else begin + info.reason:= sr_startup; + fstate:= fstate + [gs_execloaded,gs_attached, + gs_started,gs_startup,gs_canstop]; + with frames1[0] do begin + info.filename:= filename; + info.line:= line; + info.messagetext:= 'Attached to target ' + ' File: '+ + ansistring(filename)+':'+inttostr(line)+' Function: '+func; + end; + end; + end; + initinternalbkpts; + initproginfo; + end; + if result <> gdb_ok then begin + if result = gdb_message then begin + info.messagetext:= errormessage; + end + else begin + info.messagetext:= gdberrortexts[result]; + end; + end; +end; + +function tgdbmi.detach: gdbresultty; +var + ev: tgdbevent; +begin + result:= synccommand('-target-detach'); + if result = gdb_ok then begin + ev:= tgdbevent.create(ek_none,ievent(self)); + ev.eventkind:= gek_stopped; + setlength(ev.values,1); + with ev.values[0] do begin + variablename:= 'reason'; + valuekind:= vk_value; + value:= 'detached'; + end; + resetexec; + include(fstate,gs_detached); + application.postevent(ev); + end; +end; + +function tgdbmi.download(const runafterload: boolean): gdbresultty; +begin + result:= checkconnection(false); + if result = gdb_ok then begin + if fbeforeload <> '' then begin + result:= source(fbeforeload); + end; + if result = gdb_ok then begin + if not internalcommand('-target-download') then begin + result:= gdb_writeerror; + end + else begin + fstate:= fstate + [gs_downloading,gs_runafterload]; + if not runafterload then begin + exclude(fstate,gs_runafterload); + end; + end; + end; + end; +end; + +procedure tgdbmi.checkpointersize; +var + str1: string; + int1: integer; +begin + fpointersize:= 4; + if (evaluateexpression('sizeof($pc)',str1) = gdb_ok) or + + (evaluateexpression('sizeof(void*)',str1) = gdb_ok) or + //does not work on gdb win64 7.9 + (evaluateexpression('sizeof(pointer)',str1) = gdb_ok) then begin + //I know there is a gdbcommand for this, I could not find it + if trystrtoint(str1,int1) then begin + fpointersize:= int1; + end; + end + else begin + if (clicommand('show architecture') = gdb_ok) and + (pos('x86-64',fclivalues) > 0) then begin + fpointersize:= 8; + end; + end; + fpointerhexdigits:= 2*fpointersize; +end; + +procedure tgdbmi.updateenvvars(); +var + int1: integer; +begin + for int1:= 0 to high(fenvvars) do begin + with fenvvars[int1] do begin + if unset then begin + unsetenv(name); + end + else begin + setenv(name,value); + end; + end; + end; +end; + +procedure tgdbmi.dorun; +var + int1: integer; + ar1,ar2: stringarty; + ca1: qword; + str1: string; + frames1: frameinfoarty; + ev: tgdbstartupevent; +begin +{$ifdef unix} + killtargetconsole; + if fnewconsole then begin + if not createtargetconsole then begin + raise exception.create('Can not run '+ansistring(ftargetconsole.filename)); + end; + end; +{$endif} + fstartupbreakpoint:= -1; + fstartupbreakpoint1:= -1; + exclude(fstate,gs_startup); + if fbeforerun <> '' then begin + if source(fbeforerun) <> gdb_ok then begin + postsyncerror; + exit; + end; + end; + checkpointersize; + str1:= ''; + if fstartupbkpton then begin + fstartupbreakpoint:= breakinsert(fstartupbkpt); + end + else begin + if (gs_remote in fstate) and + (stacklistframes(frames1,0,1) = gdb_ok) then begin + //already started by gdbserver + ev:= tgdbstartupevent.create(ievent(self)); + with ev do begin + stopinfo.reason:= sr_startup; + with frames1[0] do begin + stopinfo.addr:= addr; + stopinfo.filename:= filename; + stopinfo.line:= line; + stopinfo.messagetext:= 'Startup. File: '+ + ansistring(filename)+':'+inttostr(line)+' Function: '+func; + end; + end; + include(fstate,gs_started); + application.postevent(ev); + exit; + end; + if getcliresult('info file',ar1) = gdb_ok then begin + for int1:= 0 to high(ar1) do begin + if startsstr('Entry point',ar1[int1]) then begin + ar2:= nil; + splitstring(ar1[int1],ar2,' '); + if high(ar2) >= 2 then begin + str1:= ar2[2]; + end; + break; + end; + end; + end; + if str1 <> '' then begin + if trystrtointvalue64(str1,ca1) then begin + fstartupbreakpoint:= breakinsert(ca1); //does not always work + fstartupbreakpoint1:= breakinsert(ca1+1); + if (fstartupbreakpoint < 0) and (fstartupbreakpoint1 < 0) then begin + str1:= ''; + end; + end + else begin + str1:= ''; + end; + end; + if str1 = '' then begin + fstartupbreakpoint:= breakinsert('main'); + end; + end; + synccommand('-exec-arguments '+ fprogparameters); + synccommand('-environment-cd '+ + ansistring(tosysfilepath(filepath(fworkingdirectory)))); + updateenvvars(); + //for remote gdbserver too late, process has already been created + {$ifdef mswindows} + if fnewconsole then begin + synccommand('-gdb-set new-console on'); + end + else begin + synccommand('-gdb-set new-console off'); + end; + {$endif} + if gs_remote in fstate then begin + sys_schedyield(); //maybe gdbserver has to work + sleepus(100000); + application.processmessages; //maybe gdbserver has sent a stop message + end; + if gs_remote in fstate then begin + internalcommand('-exec-continue'); + end + else begin + internalcommand('-exec-run'); + end; + include(fstate,gs_canstop); +end; + +function tgdbmi.checkconnection(const proginfo: boolean): gdbresultty; +begin + result:= gdb_ok; + if fbeforeconnect <> '' then begin + result:= source(fbeforeconnect); + end; + if result = gdb_ok then begin + if fremoteconnection <> '' then begin + if synccommand('-gdb-set target-async 1') = gdb_ok then begin + include(fstate,gs_async); + end; + result:= synccommand('-target-select '+ansistring(fremoteconnection)); + if result <> gdb_ok then begin + exit; + end; + include(fstate,gs_remote); + if proginfo then begin + initproginfo; + end; + end + else begin + {result:= }synccommand('-gdb-set target-async 0'); //fails on older gdb's + end; + end; + if result = gdb_ok then begin + if fafterconnect <> '' then begin + result:= source(fafterconnect); + end; + end; +end; + +function tgdbmi.tryconnect: boolean; +begin + result:= fremoteconnection = ''; + result:= result or + (synccommand('-target-select '+ansistring(fremoteconnection)) = gdb_ok); +end; + +function tgdbmi.run: gdbresultty; +begin + result:= gdb_ok; + if fsimulator then begin + result:= synccommand('-target-select sim'); + if result = gdb_ok then begin + result:= synccommand('-target-download'); + if result = gdb_ok then begin + dorun; + end; + end; + end + else begin + if fgdbdownload and not (gs_downloaded in fstate) then begin + result:= download(true); + end + else begin + result:= checkconnection(true); + if result = gdb_ok then begin + dorun; + end; + end; + end; +end; + +procedure tgdbmi.continue; +begin + debugend; + internalcommand('-exec-continue'); +end; + +procedure tgdbmi.next; +begin + debugend; + internalcommand('-exec-next'); +end; + +procedure tgdbmi.step; +begin + debugend; + internalcommand('-exec-step'); +end; + +procedure tgdbmi.finish; +begin + debugend; + internalcommand('-exec-finish'); +end; + +procedure tgdbmi.nexti; +begin + debugend; + internalcommand('-exec-next-instruction'); +end; + +procedure tgdbmi.stepi; +begin + debugend; + internalcommand('-exec-step-instruction'); +end; + +procedure tgdbmi.interrupt; +{$ifdef mswindows} +type + createremotethreadty = function(hProcess: THandle; lpThreadAttributes: Pointer; + dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; + lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; stdcall; +var + prochandle,modhandle,threadhandle: thandle; + debugbreakaddr: pointer; + createremotethreadaddr: createremotethreadty; + bo1: boolean; +{$endif mswindows} +begin +// internalcommand('-exec-interrupt'); + if fprocid <> 0 then begin + {$ifdef mswindows} + {$ifdef mse_usedebugbreakprocess} + if debugbreakprocess <> nil then begin + debugbreakprocess(fprocid); + end + else begin + {$endif} + prochandle:= openprocess( + PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or + PROCESS_VM_WRITE or PROCESS_VM_READ, False, fprocid); + if prochandle <> 0 then begin + bo1:= false; + modhandle:= GetModuleHandle(kernel32); + if modhandle <> 0 then begin + debugbreakaddr:= windows.getprocaddress(modhandle,'DebugBreak'); + if debugbreakaddr <> nil then begin + {$ifdef FPC}pointer(createremotethreadaddr){$else} + createremotethreadaddr{$endif}:= windows.GetProcAddress(modhandle, 'CreateRemoteThread'); + if assigned(createremotethreadaddr) then begin + threadhandle:= createremotethreadaddr(prochandle, nil, 0, debugbreakaddr, + nil, 0, finterruptthreadid); + if threadhandle <> 0 then begin + closehandle(threadhandle); + bo1:= true; + end; + end; + end; + end; + closehandle(prochandle); + if not bo1 then begin + GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, fprocid); + //for win95 + end; + end; + {$ifdef mse_usedebugbreakprocess} + end; + {$endif} + {$else} + kill(fprocid,sigint); + {$endif !mswindows} + end + else begin + if gs_async in fstate then begin + internalcommand('-exec-interrupt'); //runs in async mode + end + else begin + {$ifdef unix} //how to do on windows? + kill(fgdb,sigint); + {$else} + internalcommand('-exec-interrupt'); //probably no success because + //not in async mode + {$endif} + end; + end; +end; + +function tgdbmi.interrupttarget: gdbresultty; //stop for breakpointsetting +var + timestamp: longword; + int1: integer; +begin + result:= gdb_ok; + inc(finterruptcount); + if finterruptcount = 1 then begin + timestamp:= timestep(1000000); + if (gs_internalrunning in fstate) then begin + include(fstate,gs_interrupted); + interrupt; + int1:= application.unlockall; + repeat + sleep(10); + until not (gs_internalrunning in fstate) or timeout(timestamp); + application.relockall(int1); + if (gs_internalrunning in fstate) then begin + exclude(fstate,gs_interrupted); + dec(finterruptcount); + result:= gdb_timeout; + end; + end; + end; +end; + +function tgdbmi.restarttarget: gdbresultty; +begin + if finterruptcount > 0 then begin + dec(finterruptcount); + if finterruptcount = 0 then begin + if gs_interrupted in fstate then begin + exclude(fstate,gs_interrupted); + include(fstate,gs_restarted); + exclude(fstate,gs_stopped); + internalcommand('-exec-continue'); +// continue; + end; + end; + end; + result:= gdb_ok; +end; + +procedure tgdbmi.abort; +begin +// internalcommand('-exec-abort'); + if started and (interrupttarget = gdb_ok) then begin + exclude(fstate,gs_interrupted); + clicommand('kill'); + finterruptcount:= 0; + end + else begin + if downloading then begin + closegdb; + end; + end; +end; + +procedure tgdbmi.initinternalbkpts; +begin + fexceptionbkpt:= breakinsert('FPC_RAISEEXCEPTION'); + if fexceptionbkpt < 0 then begin + fexceptionbkpt:= breakinsert('__mla__raise'); + end; + if not fstoponexception and (fexceptionbkpt > 0) then begin + breakenable(fexceptionbkpt,false); //disable breakpoint + end; +end; + +procedure tgdbmi.initproginfo; +var + info1: stopinfoty; + ek1: gdbeventkindty; +begin + checkpointersize; + if fguiintf then begin + getprocaddress('MSEGUIINTF_GUI_DEBUGBEGIN',ftargetdebugbegin); + if ftargetdebugbegin = 0 then begin + getprocaddress('MSEGUIINTF_$$_GUI_DEBUGBEGIN',ftargetdebugbegin); + end; + getprocaddress('MSEGUIINTF_GUI_DEBUGEND',ftargetdebugend); + if ftargetdebugend = 0 then begin + getprocaddress('MSEGUIINTF_$$_GUI_DEBUGEND',ftargetdebugend); + end; + end + else begin + ftargetdebugbegin:= 0; + ftargetdebugend:= 0; + end; + if assigned(fonevent) then begin + initstopinfo(info1); + ek1:= gek_loaded; + fonevent(self,ek1,nil,info1); + end; +end; + +function tgdbmi.getbkptid: integer; +var + tup1: resultinfoarty; +begin + result:= -1; + if gettuplevalue(fsyncvalues,'bkpt',tup1) then begin + getintegervalue(tup1,'number',result); + end; + if result <> -1 then begin + flastbreakpoint:= result; + end; +end; + +function tgdbmi.getwptid: integer; +var + tup1: resultinfoarty; +begin + result:= -1; + if gettuplevalue(fsyncvalues,'wpt',tup1) or + gettuplevalue(fsyncvalues,'hw-awpt',tup1) or + gettuplevalue(fsyncvalues,'hw-rwpt',tup1) then begin + getintegervalue(tup1,'number',result); + end; +end; + +function tgdbmi.handle(const signame: string; const aflags: sigflagsty): gdbresultty; +var + str1: string; +begin + if sfl_stop in aflags then begin + str1:= 'stop'; + end + else begin + str1:= 'noprint'; + end; + if sfl_handle in aflags then begin + str1:= str1 + ' nopass'; + end + else begin + str1:= str1 + ' pass'; + end; + result:= clicommand('handle '+signame+' '+str1); +end; + +function tgdbmi.breakinsert(var info: breakpointinfoty): gdbresultty; +var + str1: string; +begin + with info do begin + interrupttarget; + flogtext:= ''; + if addressbreakpoint then begin + str1:= '*'+hextocstr(address,8) + end + else begin + str1:= ansistring(filename(path))+':'+inttostr(line); + end; + result:= synccommand('-break-insert '+ str1); + if (result = gdb_ok) or (result = gdb_message) then begin + if (result = gdb_ok) and (flogtext <> '') or (result = gdb_message) then begin + bkptno:= -1; + result:= clicommand('break '+str1); + inc(flastbreakpoint); + bkptno:= flastbreakpoint; + end + else begin + bkptno:= getbkptid; + end; + if bkptno < 0 then begin + result:= gdb_error; + end + else begin + if not bkpton then begin + result:= breakenable(bkptno,false); + end; + if (result = gdb_ok) and (ignore > 0) then begin + result:= breakafter(bkptno,ignore); + end; + if (result = gdb_ok) and (condition <> '') then begin + result:= breakcondition(bkptno,condition); + if result = gdb_message then begin + conditionmessage:= errormessage; + end; + end; + end; + end + else begin + bkptno:= -1; + end; + restarttarget; + end; +end; + +function tgdbmi.breakinsert(const funcname: string): integer; +begin + if synccommand('-break-insert '+funcname) <> gdb_ok then begin + result:= -1; + end + else begin + result:= getbkptid; + end; +end; + +function tgdbmi.breakinsert(const address: qword): integer; +begin + if synccommand('-break-insert *'+hextocstr(address,0)) <> gdb_ok then begin + result:= -1; + end + else begin + result:= getbkptid; + end; +end; + +function tgdbmi.watchinsert(var info: watchpointinfoty): gdbresultty; +var + str1: string; +begin + with info do begin + case kind of + wpk_readwrite: str1:= ' -a '; + wpk_read: str1:= ' -r '; + else str1:= ' '; + end; + result:= synccommand('-break-watch' + str1 + expression); + if result = gdb_ok then begin + wptno:= getwptid; + if wptno < 0 then begin + result:= gdb_error; + end + else begin + if (result = gdb_ok) and (ignore > 0) then begin + result:= breakafter(wptno,ignore); + end; + if (result = gdb_ok) and (condition <> '') then begin + result:= breakcondition(wptno,condition); + if result = gdb_message then begin + conditionmessage:= errormessage; + end; + end; + end; + { + if not bkpton then begin + result:= breakenable(bkptno,false); + end; + if (result = gdb_ok) and (ignore > 0) then begin + result:= breakafter(bkptno,ignore); + end; + if (result = gdb_ok) and (condition <> '') then begin + result:= breakcondition(bkptno,condition); + if result = gdb_message then begin + conditionmessage:= errormessage; + end; + end; + end; + } + end + else begin + wptno:= -1; + end; + end; +end; + +function tgdbmi.getfullname(const tup: resultinfoarty): string; +begin + result:=''; + if not getstringvalue(tup,'fullname',result) or (result = '') then begin + getstringvalue(tup,'file',result); + end; +end; + +function tgdbmi.getbreakpointinfo(var atup: resultinfoty; + var info: breakpointinfoty; + const full: boolean): boolean; +var + tup1: resultinfoarty; + filename: string; +begin + result:= gettuplevalue(atup,tup1); + if result then begin + with info do begin + getintegervalue(tup1,'number',bkptno); + getintegervalue(tup1,'times',passcount); + getqwordvalue(tup1,'addr',address); + if full then begin + getintegervalue(tup1,'line',line); + filename:= getfullname(tup1); + if filename <> '' then begin + path:= msestring(filename); + end; + getbooleanvalue(tup1,'enabled',bkpton); + end; + end; + end; +end; + +function tgdbmi.breaklist(var list: breakpointinfoarty; + const full: boolean): gdbresultty; +var + ar1: resultinfoarty; + int1: integer; + tup1: resultinfoarty; +begin + result:= synccommand('-break-list'); + if result = gdb_ok then begin + result:= gdb_error; + if gettuplevalue(fsyncvalues,'BreakpointTable',tup1) then begin + if getarrayvalue(tup1,'body',true,ar1) then begin + setlength(list,length(ar1)); + for int1:= 0 to high(ar1) do begin + getbreakpointinfo(ar1[int1],list[int1],full); + end; + result:= gdb_ok; + end; + end; + end; +end; + +function tgdbmi.infobreakpoint(var info: breakpointinfoty; + const full: boolean = true): gdbresultty; +var + ar1: resultinfoarty; + tup1: resultinfoarty; +begin + result:= synccommand('-break-info '+inttostr(info.bkptno)); + if result = gdb_ok then begin + result:= gdb_error; + if gettuplevalue(fsyncvalues,'BreakpointTable',tup1) then begin + if getarrayvalue(tup1,'body',true,ar1) then begin + if high(ar1) = 0 then begin + if getbreakpointinfo(ar1[0],info,full) then begin + result:= gdb_ok; + end; + end; + end; + end; + end; +end; + +function tgdbmi.breakdelete(bkptnum: integer): gdbresultty; +begin + if bkptnum = 0 then begin + result:= synccommand('-break-delete'); + initinternalbkpts; + end + else begin + result:= synccommand('-break-delete '+inttostr(bkptnum)); + end; +end; + +function tgdbmi.breakenable(bkptnum: integer; value: boolean): gdbresultty; //bkptnum = 0 -> all +begin + if value then begin + if bkptnum = 0 then begin + result:= synccommand('-break-enable'); + end + else begin + result:= synccommand('-break-enable '+inttostr(bkptnum)); + end; + end + else begin + if bkptnum = 0 then begin + result:= synccommand('-break-disable'); + end + else begin + result:= synccommand('-break-disable '+inttostr(bkptnum)); + end; + end; +end; + +function tgdbmi.breakafter(bkptnum: integer; const passcount: integer): gdbresultty; +begin + result:= synccommand('-break-after '+inttostr(bkptnum)+' '+inttostr(passcount)); +end; + +function tgdbmi.breakcondition(bkptnum: integer; + const condition: string): gdbresultty; +begin + result:= synccommand('-break-condition '+inttostr(bkptnum)+' '+condition); +end; + +function tgdbmi.getvalueindex(const response: resultinfoarty; + const aname: string): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(response) do begin + if response[int1].variablename = aname then begin + result:= int1; + break; + end; + end; +end; + +function tgdbmi.getstringvalue(const response: resultinfoarty; const aname: string; + var avalue: string): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if int1 >= 0 then begin + with response[int1] do begin + if valuekind = vk_value then begin + avalue:= value; + result:= true; + end; + end; + end; +end; + +function tgdbmi.getstringvalue(const response: resultinfoty; const aname: string; + var avalue: string): boolean; +var + ar1: resultinfoarty; +begin + setlength(ar1,1); + ar1[0]:= response; + result:= getstringvalue(ar1,aname,avalue); +end; + +function tgdbmi.getqwordvalue(const response: resultinfoarty; + const aname: string; var avalue: qword): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if int1 >= 0 then begin + with response[int1] do begin + if valuekind = vk_value then begin + if (length(value) > 1) and (value[1] = '0') and (value[2] <> 'x') and + (value[2] <> 'X') then begin + result:= trystrtointvalue64(msestring(value),nb_oct,avalue); + end + else begin + result:= trystrtointvalue64(value,avalue); + end; + end; + end; + end; +end; + +function tgdbmi.getintegervalue(const response: resultinfoarty; const aname: string; + var avalue: integer): boolean; +var + qwo1: qword; +begin + qwo1:= avalue; + result:= getqwordvalue(response,aname,qwo1); + avalue:= qwo1; +end; + +function tgdbmi.getinteger64value(const response: resultinfoarty; const aname: string; + var avalue: int64): boolean; +var + qwo1: qword; +begin + qwo1:= avalue; + result:= getqwordvalue(response,aname,qwo1); + avalue:= qwo1; +end; + + +function tgdbmi.getqwordvalue(const response: resultinfoty; const aname: string; + var avalue: qword): boolean; + +var + ar1: resultinfoarty; +begin + setlength(ar1,1); + ar1[0]:= response; + result:= getqwordvalue(ar1,aname,avalue); +end; + +function tgdbmi.getbooleanvalue(const response: resultinfoarty; const aname: string; + var avalue: boolean): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if int1 >= 0 then begin + with response[int1] do begin + if valuekind = vk_value then begin + if value = 'y' then begin + avalue:= true; + result:= true; + end + else begin + if value = 'n' then begin + avalue:= false; + result:= true; + end; + end; + end; + end; + end; +end; + +function tgdbmi.getintegervalue(const response: resultinfoty; const aname: string; + var avalue: integer): boolean; +var + qwo1: qword; +begin + qwo1:= avalue; + result:= getqwordvalue(response,aname,qwo1); + avalue:= qwo1; +end; + +function tgdbmi.getinteger64value(const response: resultinfoty; const aname: string; + var avalue: int64): boolean; +var + qwo1: qword; +begin + qwo1:= avalue; + result:= getqwordvalue(response,aname,qwo1); + avalue:= qwo1; +end; + +procedure setstringnum(var dataarray; const index: integer; const text: string); +begin + stringarty(dataarray)[index]:= text; +end; + +procedure setbytenum(var dataarray; const index: integer; const text: string); +begin + bytearty(dataarray)[index]:= strtointvalue(text); +end; + +procedure setwordnum(var dataarray; const index: integer; const text: string); +begin + wordarty(dataarray)[index]:= strtointvalue(text); +end; + +procedure setlongwordnum(var dataarray; const index: integer; const text: string); +begin + longwordarty(dataarray)[index]:= strtointvalue(text); +end; + +procedure setqwordnum(var dataarray; const index: integer; const text: string); +begin + card64arty(dataarray)[index]:= strtointvalue64(text); +end; + +procedure setstringlen(var dataarray; const len: integer); +begin + setlength(stringarty(dataarray),len); +end; + +procedure setbytelen(var dataarray; const len: integer); +begin + setlength(bytearty(dataarray),len); +end; + +procedure setwordlen(var dataarray; const len: integer); +begin + setlength(wordarty(dataarray),len); +end; + +procedure setlongwordlen(var dataarray; const len: integer); +begin + setlength(longwordarty(dataarray),len); +end; + +procedure setqwordlen(var dataarray; const len: integer); +begin + setlength(card64arty(dataarray),len); +end; + +function tgdbmi.getnumarrayvalue(const response: resultinfoarty; const aname: string; + var avalue; setnumproc: setnumprocty; setlenproc: setlenprocty): boolean; +var + int1: integer; + po1,po2: pchar; + str1: string; +begin + result:= false; + bytearty(avalue):= nil; + int1:= getvalueindex(response,aname); + if int1 >= 0 then begin + with response[int1] do begin + if valuekind = vk_list then begin + if value = '' then begin + result:= true; + end + else begin + int1:= 0; + po1:= pointer(value); + while po1^ <> #0 do begin + if po1^ <> '"' then begin + break; + end; + inc(po1); + po2:= po1; + while (po2^ <> '"') and (po2^ <> #0) do begin + inc(po2); + end; + str1:= psubstr(po1,po2); + if high(bytearty(avalue)) < int1 then begin + setlenproc(avalue,int1+16); + end; + try + setnumproc(avalue,int1,str1); + except + bytearty(avalue):= nil; + exit; + end; + inc(int1); + inc(po2); + if po2^ = ',' then begin + inc(po2); + end; + po1:= po2; + end; + setlenproc(avalue,int1); + result:= true; + end; + end; + end; + end; +end; + +function tgdbmi.getstringarrayvalue(const response: resultinfoarty; const aname: string; + var avalue: stringarty): boolean; +begin + result:= getnumarrayvalue(response,aname,avalue,{$ifdef FPC}@{$endif}setstringnum,{$ifdef FPC}@{$endif}setstringlen); +end; + +function tgdbmi.getbytearrayvalue(const response: resultinfoarty; const aname: string; + var avalue: bytearty): boolean; +begin + result:= getnumarrayvalue(response,aname,avalue,{$ifdef FPC}@{$endif}setbytenum,{$ifdef FPC}@{$endif}setbytelen); +end; + +function tgdbmi.getwordarrayvalue(const response: resultinfoarty; const aname: string; + var avalue: wordarty): boolean; +begin + result:= getnumarrayvalue(response,aname,avalue,{$ifdef FPC}@{$endif}setwordnum, + {$ifdef FPC}@{$endif}setwordlen); +end; + +function tgdbmi.getlongwordarrayvalue(const response: resultinfoarty; const aname: string; + var avalue: longwordarty): boolean; +begin + result:= getnumarrayvalue(response,aname,avalue,{$ifdef FPC}@{$endif}setlongwordnum, + {$ifdef FPC}@{$endif}setlongwordlen); +end; + +function tgdbmi.getqwordarrayvalue(const response: resultinfoarty; + const aname: string; var avalue: card64arty): boolean; +begin + result:= getnumarrayvalue(response,aname,avalue,{$ifdef FPC}@{$endif}setqwordnum, + {$ifdef FPC}@{$endif}setqwordlen); +end; + +function tgdbmi.getenumvalue(const response: resultinfoarty; const aname: string; + const enums: array of string; var avalue: integer): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if (int1 >= 0) then begin + with response[int1] do begin + if valuekind = vk_value then begin + for int1:= 0 to high(enums) do begin + if value = enums[int1] then begin + avalue:= int1; + result:= true; + break; + end; + end; + end; + end; + end; +end; + +function tgdbmi.gettuplevalue(const response: resultinfoty; + var avalue: resultinfoarty): boolean; +begin + with response do begin + if valuekind = vk_tuple then begin + result:= decodelist(false,value,avalue); + end + else begin + result:= false; + end; + end; +end; + +function tgdbmi.gettuplevalue(const response: resultinfoty; const aname: string; + var avalue: resultinfoarty): boolean; +begin + with response do begin + if (valuekind = vk_tuple) and (variablename = aname) then begin + result:= decodelist(false,value,avalue); + end + else begin + result:= false; + end; + end; +end; + +function tgdbmi.gettuplevalue(const response: resultinfoarty; + const aname: string; var avalue: resultinfoarty): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if (int1 >= 0) then begin + result:= gettuplevalue(response[int1],avalue); + end; +end; + +function tgdbmi.gettuplestring(const response: resultinfoarty; const aname: string; + var avalue: string): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if (int1 >= 0) then begin + with response[int1] do begin + if valuekind = vk_tuple then begin + avalue:= value; + result:= true; + end; + end; + end; +end; + +function tgdbmi.getarrayvalue(const response: resultinfoarty; + const aname: string; const hasitemnames: boolean; var avalue: resultinfoarty): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if (int1 >= 0) then begin + with response[int1] do begin + if valuekind = vk_list then begin + result:= decodelist(not hasitemnames,value,avalue); + end; + end; + end; +end; + +function tgdbmi.gettuplearrayvalue(const response: resultinfoarty; const aname: string; + var avalue: resultinfoararty): boolean; +var + int1: integer; + ar1: resultinfoarty; +begin + result:= getarrayvalue(response,aname,false,ar1); + setlength(avalue,length(ar1)); + for int1:= 0 to high(ar1) do begin + if (ar1[int1].valuekind <> vk_tuple) or + not gettuplevalue(ar1[int1],avalue[int1]) then begin + result:= false; + break; + end; + end; +end; + +function tgdbmi.getsourcename(out path: filenamety; + out language: languagety;frame: integer = 0): gdbresultty; +var + strar1: stringarty; + int1: integer; + bo1: boolean; +// po1: pchar; + str1: string; + i1: int32; +begin + path:= ''; + str1:= ''; + language:= lan_undef; + if frame <> 0 then begin +// result:= synccommand('-stack-select-frame '+inttostr(frame)); //does not change soourcefile + result:= clicommand('frame ' + inttostr(frame)); + if result <> gdb_ok then begin + exit; + end; + end; + result:= getcliresult('info source',strar1); + if frame <> 0 then begin +// result:= synccommand('-stack-select-frame 0'); //does not change sourcefile + result:= clicommand('frame 0'); + end; + if result = gdb_ok then begin + bo1:= false; + for int1:= 0 to high(strar1) do begin +// if startsstr('Located in ',strar1[int1]) then begin +// path:= copy(strar1[int1],12,bigint); +// break; +// end +// else begin + if startsstr('Source language is ',strar1[int1]) then begin + i1:= findlastchar(strar1[int1],'.'); + if i1 > 0 then begin + str1:= copy(strar1[int1],20,i1-20); + end; + if str1 = 'pascal' then begin + language:= lan_pascal; + end; + end; + if path = '' then begin + if startsstr('Current source file is ',strar1[int1]) then begin + path:= msestring(copy(strar1[int1],24,bigint)); + end; + end + else begin + if not bo1 and startsstr('Compilation directory is ',strar1[int1]) then begin + path:= msestring(copy(strar1[int1],26,bigint)) + path; + bo1:= true; + end; + end; +// end; + end; + end; +end; + +function tgdbmi.getprocaddress(const procname: string; + out aaddress: qword): gdbresultty; +var + str1: string; + ar1: stringarty; + int1: integer; +begin + ar1:= nil; //compiler warning + aaddress:= 0; + result:= getcliresultstring('info address ' + procname,str1); + if result = gdb_ok then begin + result:= gdb_dataerror; + ar1:= splitstring(trim(str1),' ',true); + for int1:= 0 to high(ar1) do begin + str1:= ar1[int1]; + if startsstr('0x',str1) then begin + if str1[length(str1)] = '.' then begin + setlength(str1,length(str1)-1); + end; + if trystrtointvalue64(str1,aaddress) then begin + result:= gdb_ok; + end; + break; + end; + end; + end; +end; + +function tgdbmi.getstopinfo(const response: resultinfoarty; + const lastconsoleoutput: ansistring; + out info: stopinfoty): boolean; +var + int1: integer; + ar1: resultinfoarty; + frame: resultinfoarty; +// str1: string; + wstr1: filenamety; + frames1: frameinfoarty; + res1: gdbresultty; +begin + finalize(info); + fillchar(info,sizeof(info),0); + with info do begin + if response = nil then begin + info.reason:= sr_unknown; + res1:= stacklistframes(frames1,0,1); + result:= res1 = gdb_ok; + if result then begin + with frames1[0] do begin + info.filename:= filename; + info.line:= line; + info.messagetext:= 'Stopped. File: '+ + ansistring(filename)+':'+inttostr(line)+' Function: '+func; + end; + end + else begin + if res1 = gdb_message then begin + info.messagetext:= errormessage; + end + end; + end + else begin + if getenumvalue(response,'reason',stopreasons,int1) then begin + result:= true; + reason:= stopreasonty(int1); + end + else begin + reason:= sr_startup; + result:= false; + end; + if reason = sr_breakpoint_hit then begin + getintegervalue(response,'bkptno',info.bkptno); + if (info.bkptno = fstartupbreakpoint) or + (info.bkptno = fstartupbreakpoint1) then begin + reason:= sr_startup; + result:= false; + end; + end; + if reason = sr_signal_received then begin + getstringvalue(response,'signal-name',signalname); + getstringvalue(response,'signal-meaning',signalmeaning); + if fsimulator and (signalname = '0') then begin + signalmeaning:= lastconsoleoutput; + end; + end; + if reason = sr_watchpointtrigger then begin + if gettuplevalue(response,'wpt',ar1) then begin + getstringvalue(ar1,'exp',expression); + end; + if gettuplevalue(response,'value',ar1) then begin + getstringvalue(ar1,'old',oldvalue); + getstringvalue(ar1,'new',newvalue); + end; + end; + if reason = sr_exited then begin + getintegervalue(response,'exit-code',exitcode); + end + else begin + if not (reason in [sr_exited_normally,sr_detached]) then begin + result:= getqwordvalue(response,'thread-id',threadid); + if gettuplevalue(response,'frame',frame) then begin + filename:= msestring(getfullname(frame)); + getintegervalue(frame,'line',line); + getstringvalue(frame,'func',func); + getinteger64value(frame,'addr',int64(addr)); + if getsourcename(wstr1,language) = gdb_ok then begin + filedir:= msefileutils.filedir(wstr1); + end; + end; + end; + end; + if result then begin + messagetext:= stopreasontext[reason] + '.'; + if signalname <> '' then begin + messagetext:= messagetext + ' Signal: ' + signalname; + end; + if signalmeaning <> '' then begin + messagetext:= messagetext + ', ' + signalmeaning + '.'; + end; + if filename <> '' then begin + messagetext:= messagetext + ' File: ' + ansistring(filename); + end; + if line > 0 then begin + messagetext:= messagetext + ':'+inttostr(line); + end; + if func <> '' then begin + messagetext:= messagetext + ' Function: ' + func; + end; + if exitcode <> 0 then begin + messagetext:= messagetext + ' Exitcode: ' + inttostr(exitcode); + end; + if expression <> '' then begin + messagetext:= messagetext + ' Expression: '+expression; + end; + if oldvalue <> '' then begin + messagetext:= messagetext + ' old: '+oldvalue; + end; + if newvalue <> '' then begin + messagetext:= messagetext + ' new: '+newvalue; + end; + end + else begin + if getstringvalue(response,'msg',messagetext) then begin + if reason = sr_startup then begin + reason:= sr_error; + end; + end; + end; + end; + fcurrentlanguage:= language; + end; +end; +{ +function tgdbmi.geterrorinfo(const response: resultinfoarty; out info: errorinfoty): boolean; +var + int1: integer; +begin + finalize(info); + with info do begin + fillchar(info,sizeof(info),0); + result:= getstringvalue(response,'msg',messagetext); + end; +end; +} +function tgdbmi.executecommand(const acommand: string; + out aresult: string): gdbresultty; +begin + result:= clicommand(acommand); + case result of + gdb_ok: begin + aresult:= fclivalues; + end; + gdb_message: begin + aresult:= errormessage; + end; + else begin + aresult:= gdberrortexts[result]; + end; + end; +end; + +function tgdbmi.evaluateexpression(expression: string; out aresult: string; + const noupdatepascalexpression: boolean = false): gdbresultty; +begin + if not noupdatepascalexpression then begin + updatepascalexpression(expression); + end; + aresult:= ''; + result:= synccommand('-data-evaluate-expression ' + '"'+expression+'"'); + case result of + gdb_ok: begin + getstringvalue(fsyncvalues,'value',aresult); + end; + gdb_error: begin + getstringvalue(fsyncvalues,'msg',aresult); + end; + gdb_message: begin + aresult:= errormessage; + end; + else begin + aresult:= gdberrortexts[result]; + end; + end; +end; + +function tgdbmi.symboltype(symbol: string; + out aresult: string): gdbresultty; +begin + updatepascalexpression(symbol); + result:= clicommand('ptype '+symbol); + case result of + gdb_ok: begin + aresult:= fclivalues; + end; + gdb_message: begin + aresult:= errormessage; + end; + else begin + aresult:= ''; + end; + end; +end; + +function tgdbmi.symboladdress(symbol: ansistring; + out aresult: ansistring): gdbresultty; +begin + updatepascalexpression(symbol); + result:= evaluateexpression('@('+symbol+')',aresult); +end; + +function tgdbmi.threadselect(const aid: integer; out filename: filenamety; + out line: integer): gdbresultty; +var + str1: string; + ar1: resultinfoarty; +begin + filename:= ''; + line:= 0; + result:= synccommand('-thread-select ' + inttostr(aid)); + if result = gdb_ok then begin + if not gettuplevalue(fsyncvalues,'frame',ar1) then begin + ar1:= fsyncvalues; + end; + if getstringvalue(ar1,'file',str1) then begin + filename:= msestring(str1); + end; + getintegervalue(ar1,'line',line); + end; +end; + +function tgdbmi.getthreadidlist(out idlist: integerarty): gdbresultty; +var + ar1: resultinfoarty; + int1: integer; +begin + idlist:= nil; + result:= synccommand('-thread-list-ids'); + if result = gdb_ok then begin + result:= gdb_dataerror; + if gettuplevalue(fsyncvalues,'thread-ids',ar1) then begin + setlength(idlist,length(ar1)); + for int1:= 0 to high(ar1) do begin + if not getintegervalue(ar1[int1],'thread-id',idlist[int1]) then begin + break; + end; + end; + result:= gdb_ok; + end; + end; +end; + +function tgdbmi.getthreadinfolist(out infolist: threadinfoarty): gdbresultty; +var + int1,int2,int3: integer; + ar1,ar2: stringarty; + stackframeindex: integer; +begin + infolist:= nil; + ar1:= nil; //compiler warning + ar2:= nil; //compiler warning + result:= clicommand('info threads',true); + if result = gdb_ok then begin + result:= gdb_dataerror; + setlength(infolist,length(fclivaluelist)); //max + int2:= 0; + for int1:= 0 to high(fclivaluelist) do begin + with infolist[int2] do begin + ar1:= splitstring(trim(fclivaluelist[int1]),' ',true); + if (high(ar1) >= 2) and (ar1[0][1] <> '[') then begin + if ar1[0] = '*' then begin + state:= ts_active; + ar1:= copy(ar1,1,bigint); + end + else begin + state:= ts_none; + end; + if high(ar1) < 2 then begin + system.continue; + end; + if not trystrtoint64(ar1[0],pint64(@id)^) then begin + system.continue; + end; + if ar1[1] = 'Thread' then begin + ar1:= copy(ar1,2,bigint); + if high(ar1) < 2 then begin + system.continue; + end; + end; + threadid:= 0; + stackframeindex:= 3; + ar2:= splitstring(ar1[2],'.'); + if high(ar2) > 0 then begin + trystrtohex64(ar2[1],threadid); + end + else begin + if (high(ar1) > 1) and (ar1[1] = '(LWP') then begin + trystrtoint64(copy(ar1[2],1,length(ar1[2])-1),pint64(@threadid)^); + //delphi compatibility + end + else begin + if not trystrtoint64(ar1[0],pint64(@threadid)^) then begin + if not trystrtohex64(ar1[2],threadid) then begin + ar2:= splitstring(ar1[0],'.'); + if high(ar2) > 0 then begin + stackframeindex:= 1; + trystrtohex64(ar2[1],threadid); + end; + end; + end; + end; + end; + + if high(ar1) >= stackframeindex then begin + stackframe:= ar1[stackframeindex]; + for int3:= stackframeindex + 1 to high(ar1) do begin + stackframe:= stackframe + ' ' + ar1[int3]; + end; + end; + inc(int2); + end; + end; + end; + setlength(infolist,int2); + result:= gdb_ok; + end; +end; + +function tgdbmi.readmemorybytes(const address: qword; const count: integer; + var aresult: bytearty): gdbresultty; +var + ar1,ar2: resultinfoarty; +begin + aresult:= nil; + result:= synccommand('-data-read-memory '+ hextocstr(address,fpointerhexdigits) + ' u 1 1 ' + inttostr(count)); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'memory',false,ar1) then begin + if gettuplevalue(ar1,'',ar2) then begin + if getbytearrayvalue(ar2,'data',aresult) then begin + result:= gdb_ok; + end; + end; + end; + end; +end; + +function tgdbmi.readmemorywords(const address: qword; const count: integer; + var aresult: wordarty): gdbresultty; +var + ar1,ar2: resultinfoarty; +begin + aresult:= nil; + result:= synccommand('-data-read-memory '+ + hextocstr(address,fpointerhexdigits) + ' u 2 1 ' + inttostr(count)); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'memory',false,ar1) then begin + if gettuplevalue(ar1,'',ar2) then begin + if getwordarrayvalue(ar2,'data',aresult) then begin + result:= gdb_ok; + end; + end; + end; + end; +end; + +function tgdbmi.readmemorylongwords(const address: qword; const count: integer; + var aresult: longwordarty): gdbresultty; +var + ar1,ar2: resultinfoarty; +begin + aresult:= nil; + result:= synccommand('-data-read-memory '+ + hextocstr(address,fpointerhexdigits) + ' u 4 1 ' + inttostr(count)); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'memory',false,ar1) then begin + if gettuplevalue(ar1,'',ar2) then begin + if getlongwordarrayvalue(ar2,'data',aresult) then begin + result:= gdb_ok; + end; + end; + end; + end; +end; + +function tgdbmi.readmemoryqwords(const address: qword; const count: integer; + var aresult: card64arty): gdbresultty; +var + ar1,ar2: resultinfoarty; +begin + aresult:= nil; + result:= synccommand('-data-read-memory '+ + hextocstr(address,fpointerhexdigits) + ' u 8 1 ' + inttostr(count)); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'memory',false,ar1) then begin + if gettuplevalue(ar1,'',ar2) then begin + if getqwordarrayvalue(ar2,'data',aresult) then begin + result:= gdb_ok; + end; + end; + end; + end; +end; + +function tgdbmi.readmemorybyte(const address: qword; out aresult: byte): gdbresultty; +var + ar1: bytearty; +begin + result:= readmemorybytes(address,1,ar1); + if result = gdb_ok then begin + aresult:= ar1[0]; + end; +end; + +function tgdbmi.readmemoryword(const address: qword; out aresult: word): gdbresultty; +var + ar1: wordarty; +begin + result:= readmemorywords(address,1,ar1); + if result = gdb_ok then begin + aresult:= ar1[0]; + end; +end; + +function tgdbmi.readmemorylongword(const address: qword; out aresult: longword): gdbresultty; +var + ar1: longwordarty; +begin + result:= readmemorylongwords(address,1,ar1); + if result = gdb_ok then begin + aresult:= ar1[0]; + end; +end; + +function tgdbmi.readmemorypointer(const address: qword; out aresult: qword): gdbresultty; +var + ar1: bytearty; +begin + result:= readmemorybytes(address,fpointersize,ar1); + if result = gdb_ok then begin + if fpointersize = 8 then begin + aresult:= pqword(pointer(ar1))^; + end + else begin + aresult:= plongword(pointer(ar1))^; + end; + end; +end; +{ +function tgdbmi.readmemorypointer(const address: qword; out aresult: qword): gdbresultty; +var + ar1: bytearty; +begin //todo: endianess + result:= readmemorybytes(address,fpointersize,ar1); + if result = gdb_ok then begin + aresult:= pptruint(pointer(ar1))^; + end; +end; +} +function tgdbmi.setlangc(): string; +begin + result:= currentlang(); + if synccommand('set language c') <> gdb_ok then begin + result:= ''; + end; +end; + +function tgdbmi.setlang(const alanguage: string): gdbresultty; +begin + if alanguage <> '' then begin + result:= synccommand('set language '+alanguage); + end; +end; + +function tgdbmi.writememory8(const address: qword; + const avalue: card8): gdbresultty; +var + str1,str2,str3,str4: ansistring; +begin + str2:= hextocstr(address,fpointerhexdigits); + str3:= hextocstr(avalue,2); + str4:= setlangc(); + result:= evaluateexpression('{unsigned char} '+str2+'='+str3,str1,true); + setlang(str4); + +// if currentlang = 'pascal' then begin +// result:= evaluateexpression('pbyte('+str2+')^:='+str3,str1); +// end +// else begin +// result:= evaluateexpression('{char} '+str2+' = '+str3,str1); +// result:= evaluateexpression('*((unsigned char*)'+str2+') = '+str3,str1); +// end; +end; + +function tgdbmi.writememory16(const address: qword; + const avalue: card16): gdbresultty; +var + str1,str2,str3,str4: ansistring; +begin + str2:= hextocstr(address,fpointerhexdigits); + str3:= hextocstr(avalue,4); + str4:= setlangc(); + result:= evaluateexpression('{unsigned short} '+str2+'='+str3,str1,true); + setlang(str4); +{ + if currentlang = 'pascal' then begin + result:= evaluateexpression('pword('+str2+')^:='+str3,str1); + end + else begin + result:= evaluateexpression('*((unsigned short*)'+str2+')='+str3,str1); + end; +} +end; + +function tgdbmi.writememory32(const address: qword; + const avalue: card32): gdbresultty; +var + str1,str2,str3,str4: ansistring; +begin + str2:= hextocstr(address,fpointerhexdigits); + str3:= hextocstr(avalue,8); + str4:= setlangc(); + result:= evaluateexpression('{unsigned long} '+str2+'='+str3,str1,true); + setlang(str4); +{ + if currentlang = 'pascal' then begin + result:= evaluateexpression('plongword('+str2+')^:='+str3,str1); + end + else begin + result:= evaluateexpression('*((unsigned long*)'+str2+')='+str3,str1); + end; +} +end; + +function tgdbmi.writememory64(const address: qword; + const avalue: card64): gdbresultty; +var + str1,str2,str3,str4: ansistring; +begin + str2:= hextocstr(address,fpointerhexdigits); + str3:= hextocstr(avalue,16); + str4:= setlangc(); + result:= evaluateexpression('{unsigned long long} '+str2+'='+str3,str1,true); + setlang(str4); +end; + +function tgdbmi.infoline(const filename: filenamety; const line: integer; + out start,stop: qword): gdbresultty; +var + str1: string; +begin + result:= getcliresultstring('info line '+ansistring(filename)+':'+ + inttostr(line),str1); + if result = gdb_ok then begin + if not getcliint64('starts at address',str1,int64(start)) or + not getcliint64('ends at',str1,int64(stop)) then begin + result:= gdb_dataerror; + end; + end; +end; + +function tgdbmi.infoline(const address: qword; out filename: filenamety; out line: integer; + out start,stop: qword): gdbresultty; +var + str1,str2: string; +begin + result:= getcliresultstring('info line *'+inttostr(address),str1); + if result = gdb_ok then begin + if getclistring('of "',str1,str2) and getcliinteger('Line',str1,line) and + getcliint64('starts at address',str1,int64(start)) and + getcliint64('ends at',str1,int64(stop)) then begin + filename:= msestring(copy(str2,1,length(str2)-1)); + filename:= filepath(filename); + end + else begin + result:= gdb_dataerror; + end; + end; +end; + +function tgdbmi.infoaddress(const symbol: msestring; + out aresult: msestring): gdbresultty; +var + ar1: msestringarty; + mstr1: msestring; +begin + result:= clicommand('info address '+ansistring(symbol)); + case result of + gdb_ok: begin + aresult:= trim(removelinebreaks(msestring(fclivalues))); + ar1:= splitstring(aresult,msechar(' ')); + if (high(ar1) >= 0) then begin + mstr1:= ar1[high(ar1)]; + if msestartsstr('0x',mstr1) then begin + if mstr1[length(mstr1)] = '.' then begin + setlength(mstr1,length(mstr1)-1); + end; + aresult:= mstr1; + end; + end; + end; + gdb_message: begin + aresult:= msestring(errormessage); + end; + else begin + aresult:= ''; + end; + end; +end; + +function tgdbmi.infosymbol(const symbol: msestring; + out info: msestring): gdbresultty; +begin + result:= clicommand('info symbol '+ansistring(symbol)); + case result of + gdb_ok: begin + info:= msestring(fclivalues); + end; + gdb_message: begin + info:= msestring(errormessage); + end; + else begin + info:= ''; + end; + end; +end; + + +function tgdbmi.internaldisassemble(out aresult: disassarty; command: string; + const mixed: boolean): gdbresultty; + + function getasm(const source: resultinfoararty; out dest: asmlinearty): boolean; + var + int1: integer; + begin + result:= false; + setlength(dest,length(source)); + for int1:= 0 to high(source) do begin + with dest[int1] do begin + if not getqwordvalue(source[int1],'address',address) then exit; + if not getstringvalue(source[int1],'inst',instruction) then exit; + end; + end; + result:= true; + end; + +var + ar1,ar2: resultinfoarty; + ar3: resultinfoararty; + int1,int2: integer; +begin + aresult:= nil; + if mixed then begin + command:= command + ' -- 1'; + end + else begin + command:= command + ' -- 0'; + end; + result:= synccommand(command); + if result = gdb_ok then begin + result:= gdb_dataerror; + if mixed then begin + if getarrayvalue(fsyncvalues,'asm_insns',true,ar1) then begin + int2:= 0; + for int1:= 0 to high(ar1) do begin + additem(aresult,typeinfo(disassarty),int2); + if not gettuplevalue(ar1[int1],'src_and_asm_line',ar2) then exit; + with aresult[int2-1] do begin + if not getintegervalue(ar2,'line',line) then exit; + if not gettuplearrayvalue(ar2,'line_asm_insn',ar3) then exit; + if not getasm(ar3,asmlines) then exit; + end; + end; + setlength(aresult,int2); + end; + end + else begin + if not gettuplearrayvalue(fsyncvalues,'asm_insns',ar3) then exit; + setlength(aresult,1); + if not getasm(ar3,aresult[0].asmlines) then exit; + end; + result:= gdb_ok; + end; +end; + +function tgdbmi.disassemble(out aresult: asmlinearty; const filename: filenamety; + const line: integer; const count: integer): gdbresultty; +var + str1: string; + ar1: disassarty; +begin + str1:= '-data-disassemble -f '+ansistring(filename)+' -l '+inttostr(line) + + ' -n ' + inttostr(count); + result:= internaldisassemble(ar1,str1,false); + if result = gdb_ok then begin + aresult:= ar1[0].asmlines; + end; +end; + +function tgdbmi.disassemble(out aresult: asmlinearty; + const start,stop: qword): gdbresultty; +var + str1: string; + ar1: disassarty; +begin + str1:= '-data-disassemble -s '+qwordtocstr(start)+' -e '+qwordtocstr(stop); + result:= internaldisassemble(ar1,str1,false); + if result = gdb_ok then begin + aresult:= ar1[0].asmlines; + end; +end; + +function tgdbmi.disassemble(out aresult: disassarty; const filename: filenamety; + const line: integer; const count: integer): gdbresultty; +var + str1: string; +begin + str1:= '-data-disassemble -f '+ansistring(filename)+' -l '+inttostr(line) + + ' -n ' + inttostr(count); + result:= internaldisassemble(aresult,str1,true); +end; + +function tgdbmi.disassemble(out aresult: disassarty; + const start,stop: qword): gdbresultty; +var + str1: string; +begin + str1:= '-data-disassemble -s '+qwordtocstr(start)+' -e '+qwordtocstr(stop); + result:= internaldisassemble(aresult,str1,true); +end; + +function tgdbmi.getframeaddress(out address: qword): gdbresultty; +var + str1: ansistring; + ar1: stringarty; + int1: integer; +begin + result:= getcliresultstring('info frame',str1); + if result = gdb_ok then begin + result:= gdb_dataerror; + ar1:= splitstring(str1,' ',true); + for int1:= 0 to high(ar1)- 2 do begin + if (ar1[int1] = 'frame') and (ar1[int1+1] = 'at') then begin + setlength(ar1[int1+2],length(ar1[int1+2])-1); //remove ':' + if not trystrtointvalue64(ar1[int1+2],address) then begin + exit; + end; + break; + end; + end; + result:= gdb_ok; + end; +end; + +function tgdbmi.getregistervalue(const aname: string; out avalue: qword): gdbresultty; +var + str1: string; + int1: integer; +begin + result:= evaluateexpression('$'+aname,str1); + if result = gdb_ok then begin + int1:= findchar(str1,' '); + if int1 > 0 then begin + setlength(str1,int1-1); + end; + if not trystrtointvalue64(str1,avalue) then begin + result:= gdb_dataerror; + end; + end; +end; + +function tgdbmi.setregistervalue(const aname: string; + const avalue: qword): gdbresultty; +var + str1: ansistring; +begin + result:= writepascalvariable( + '$'+aname,inttostr(avalue),str1); +end; + +function tgdbmi.getpc(out addr: qword): gdbresultty; +begin + result:= getregistervalue('pc',addr); +end; + +function tgdbmi.listregisternames(out aresult: stringarty): gdbresultty; +{$ifdef mse_debuggdb} +var + int1: integer; +{$endif} +begin + aresult:= nil; + result:= synccommand('-data-list-register-names'); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getstringarrayvalue(fsyncvalues,'register-names',aresult) then begin + result:= gdb_ok; + {$ifdef mse_debuggdb} + debugwriteln('**** registernames'); + for int1:= 0 to high(aresult) do begin + if aresult[int1] <> '' then begin + debugwriteln(inttostr(int1)+': '+aresult[int1]); + end; + end; + {$endif} + end; + end; +end; + +function tgdbmi.listregistervalues(out aresult: registerinfoarty): gdbresultty; +var + ar1,ar2: resultinfoarty; + int1: integer; +begin + aresult:= nil; + result:= synccommand('-data-list-register-values r',2*defaultsynctimeout); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'register-values',false,ar1) then begin + setlength(aresult,length(ar1)); + for int1:= 0 to high(ar1) do begin + if not gettuplevalue(ar1[int1],ar2) then begin + exit; + end; + with aresult[int1] do begin + if not getintegervalue(ar2,'number',num) then begin + exit; + end; + if not getstringvalue(ar2,'value',bits) then begin + exit; + end; + end; + end; + result:= gdb_ok; + end; + end; +end; + +function tgdbmi.listlines(const path: filenamety; + out lines: integerarty; out addresses: qwordarty): gdbresultty; +var + ar1,ar2: resultinfoarty; + int1: integer; +begin + lines:= nil; + addresses:= nil; + result:= synccommand('-symbol-list-lines '+ + ansistring(filename(path)),5*defaultsynctimeout); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'lines',false,ar1) then begin + setlength(lines,length(ar1)); + setlength(addresses,length(ar1)); + for int1:= 0 to high(ar1) do begin + if not gettuplevalue(ar1[int1],ar2) then begin + exit; + end; + if not getqwordvalue(ar2,'pc',addresses[int1]) then begin + exit; + end; + if not getintegervalue(ar2,'line',lines[int1]) then begin + exit; + end; + end; + end; + result:= gdb_ok; + end; +end; + +function tgdbmi.getsystemregister(const anumber: integer; + out avalue: qword): gdbresultty; + //for avr32 +var + str1: ansistring; + ar1: stringarty; +begin + avalue:= 0; + result:= getcliresultstring('show sysreg '+inttostr(anumber),str1); + if result = gdb_ok then begin + result:= gdb_dataerror; + ar1:= splitstring(str1,'=',true); + if high(ar1) = 1 then begin + if trystrtointvalue64(trimright(ar1[1]),avalue) then begin + result:= gdb_ok; + end; + end; + end; +end; + +function tgdbmi.setsystemregister(const anumber: integer; + const avalue: qword): gdbresultty; + //for avr32 +begin + result:= synccommand('set sysreg '+inttostr(anumber)+'='+qwordtocstr(avalue)); +end; + +function tgdbmi.getpcharvar(address: qword): string; +const + maxblocklength = 16; + maxlength = 10000; +var + data: bytearty; + po1: pchar; + int1,int2: integer; + bo1: boolean; + blocklength: integer; +begin + if address = 0 then begin + result:= ''''''; + end + else begin + data:= nil; + result:= ''''; + int1:= 2; + blocklength:= maxblocklength; + bo1:= false; + repeat + while true do begin + if blocklength <= 0 then begin + result:= 'Can not read memory at $'+inttohex(address,8); + exit; + end; + if readmemorybytes(address,blocklength,data) <> gdb_ok then begin + blocklength:= blocklength div 2; + end + else begin + break; + end; + end; + if high(data) >= 0 then begin + po1:= strlscan(pchar(pointer(data)),#0,length(data)); + if po1 = nil then begin + po1:= pchar(pointer(data))+length(data); + end + else begin + bo1:= true; + end; + int2:= po1-pchar(pointer(data)); + setlength(result,length(result)+int2); + move(data[0],result[int1],int2); + inc(int1,int2); + inc(address,int2); + if int1 > maxlength then begin + result:= result + '''...'; + exit; + end; + end; + until bo1 or (length(data) < blocklength); + result:= result + ''''; + end; +end; + +function tgdbmi.getpmsecharvar(address: qword): msestring; +const + maxblocklength = 16; + maxlength = 10000; +var + data: wordarty; + po1: pmsechar; + int1,int2: integer; + bo1: boolean; + blocklength: integer; +begin + data:= nil; + if address = 0 then begin + result:= ''''''; + end + else begin + result:= ''''; + int1:= 2; + blocklength:= maxblocklength; + bo1:= false; + repeat + while true do begin + if blocklength <= 0 then begin + result:= 'Can not read memory at $'+hextostrmse(address,8); + exit; + end; + if readmemorywords(address,blocklength,data) <> gdb_ok then begin + blocklength:= blocklength div 2; + end + else begin + break; + end; + end; + if high(data) >= 0 then begin + po1:= msestrlscan(pmsechar(pointer(data)),#0,length(data)); + if po1 = nil then begin + po1:= pmsechar(pointer(data))+length(data); + end + else begin + bo1:= true; + end; + int2:= po1-pmsechar(pointer(data)); + setlength(result,length(result)+int2); + move(data[0],result[int1],int2*sizeof(msechar)); + inc(int1,int2); + inc(address,int2*sizeof(msechar)); + if int1 > maxlength then begin + result:= result + '''...'; + exit; + end; + end; + until bo1 or (length(data) < blocklength); + result:= result + ''''; + end; +end; + +function tgdbmi.ispointervalue(avalue: string; out pointervalue: qword): boolean; +var + int1: integer; +begin + int1:= findchar(avalue,' '); + if int1 > 0 then begin + setlength(avalue,int1-1); + end; + result:= trystrtointvalue64(avalue,pointervalue); +end; + +function tgdbmi.matchpascalformat(const typeinfo: string; + value: string; const expression: string): msestring; +const + typetoken = 'TYPE = '; + dynartoken = 'ARRAY [0..-1] OF '; + dynartoken2 = 'ARRAY [0..0] OF '; + dynartoken3 = '^(ARRAY [0..-1] OF '; +var + ar1: stringarty; + str1,str2,str3: string; + mstr1: msestring; + ad1,ad2: qword; + ad3: int64; + res1: gdbresultty; + int1: integer; + bo1: boolean; +begin + ar1:= nil; //compiler warning + result:= msestring(value); + ar1:= breaklines(uppercase(typeinfo)); + str1:= ''; + if length(ar1) > 0 then begin + if startsstr(typetoken,ar1[0]) then begin + str1:= copy(ar1[0],length(typetoken)+1,length(ar1[0])-length(typetoken)); + end; +// str1:= struppercase(str1); + if startsstr(dynartoken2,str1) then begin + if evaluateexpression('@('+expression+')',str3) = gdb_ok then begin + if trystrtointvalue64(str3,ad1) then begin + value:= qwordtocstr(ad1); + str1:= dynartoken + copy(str1,length(dynartoken2)+1,bigint); + end; + end; + end; + end; + if ispointervalue(value,ad1) then begin + if str1 <> '' then begin + if (str1 = '^CHARACTER') or (str1 = '^CHAR') then begin + result:= msestring(getpcharvar(ad1)); + end + else begin + if (str1 = '^WCHAR') or (str1 = '^WIDECHAR') then begin + result:= getpmsecharvar(ad1); + end + else begin + str2:= ''; + bo1:= false; + if startsstr(dynartoken,str1) then begin + str2:= dynartoken; + end; + if startsstr(dynartoken3,str1) then begin //dereferenced + str2:= dynartoken3; + setlength(str1,length(str1)-1); + ad2:= ad1; + bo1:= true; + end; + if str2 <> '' then begin + if bo1 or (readmemorypointer(ad1,ad2) = gdb_ok) then begin + if ad2 = 0 then begin + result:= niltext; + end + else begin + if readmemorypointer(ad2-fpointersize,qword(ad3)) = gdb_ok then begin + //read arrayhigh + str3:= '^'+copy(str1,length(str2)+1,bigint)+'('+qwordtocstr(ad2)+')['; + result:= '('; + if ad3 >= 0 then begin + for int1:= 0 to ad3 do begin + if length(result) > 2000 then begin + result:= result +'...,'; + break; + end; + res1:= readpascalvariable(str3+inttostr(int1)+']',mstr1); + result:= result + mstr1 + ','; + if res1 <> gdb_ok then begin + break; + end; + end; + setlength(result,length(result)-1); //remove last comma + end; + result:= result + ')'; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tgdbmi.getsysregnum(const varname: string; out num: integer): boolean; +var + str1: string; + int1: integer; +begin + result:= false; + num:= 0; + if startsstr('sysreg[',varname) then begin + int1:= findchar(varname,']') - 8; + if int1 > 0 then begin + str1:= copy(varname,8,int1); + try + num:= strtoint(str1); + result:= true; + except + end; + end; + end; +end; + +function tgdbmi.currentlang: string; +var +// str1: string; + ar1: stringarty; +// int1{,int2}: integer; +begin +// result:= 'pascal'; //default + result:= ''; + if getcliresult('show language',ar1) = gdb_ok then begin + ar1:= splitstring(ar1[0],' '); + ar1:= splitstring(ar1[high(ar1)],'"'); + if high(ar1) >= 1 then begin + result:= ar1[1]; + end; + end; +end; + +function tgdbmi.assignoperator: string; +begin + if currentlang <> 'pascal' then begin + result:= '='; + end + else begin + result:= ':='; + end; +end; + +function tgdbmi.readpascalvariable(varname: string; + out aresult: msestring): gdbresultty; +var + str1,str2,str3: string; + int1{,int2}: integer; + ar1: stringarty; +begin + if running then begin + result:= gdb_running; + aresult:= ''; + end + else begin + if getsysregnum(varname,int1) then begin + result:= getcliresultstring('show sysreg '+inttostr(int1),str2); + if result = gdb_ok then begin + ar1:= splitstring(str2,'='); + if high(ar1) = 1 then begin + aresult:= msestring(trim(ar1[1])); + end + else begin + aresult:= msestring(str2); + end; + end + else begin + aresult:= msestring(geterrormessage(result)); + end; + exit; + end; + updatepascalexpression(varname); + result:= symboltype(varname,str1); + if (pos('type = ^',str1) = 1) and + (symboltype(varname+'^' ,str3) = gdb_ok) then begin + if pos('type = array of ',str3) = 1 then begin //dwarf dynarray + str1:= 'type = ^(array [0..-1] of '+copy(trim(str3),17,bigint)+')'+lineend; + end; + end; + if result = gdb_ok then begin + result:= evaluateexpression(varname,str2); + case result of + gdb_ok: begin + aresult:= matchpascalformat(str1,str2,varname); + end; + gdb_message: begin + aresult:= msestring(errormessage); + end; + else begin + aresult:= ''; + end; + end; + end + else begin + aresult:= msestring(str1); + end; + end; +end; + +function tgdbmi.writepascalvariable(varname: string; const value: string; + var aresult: string): gdbresultty; +var + int1: integer; + mstr1: msestring; +begin + if getsysregnum(varname,int1) then begin + result:= synccommand('set sysreg '+inttostr(int1)+'='+value); + if result <> gdb_ok then begin + aresult:= geterrormessage(result); + end + else begin + result:= readpascalvariable('sysreg['+inttostr(int1)+']',mstr1); + aresult:= ansistring(mstr1); + end; + end + else begin + updatepascalexpression(varname); + result:= evaluateexpression(varname+assignoperator+value,aresult); + end; +end; + +function tgdbmi.clicommand(const acommand: string; list: boolean = false; + timeout: integer = defaultsynctimeout): gdbresultty; +begin + fclivalues:= ''; + fclivaluelist:= nil; + include(fstate,gs_clicommand); + try + if list then begin + include(fstate,gs_clilist); + end + else begin + exclude(fstate,gs_clilist); + end; + result:= synccommand(acommand,timeout); + finally + exclude(fstate,gs_clicommand); + end; +end; + +function tgdbmi.getcliresult(const acommand: string; var aresult: stringarty): gdbresultty; +var + int1: integer; +begin + result:= clicommand(acommand); + if result = gdb_ok then begin + splitstring(fclivalues,aresult,c_linefeed); + for int1:= 0 to high(aresult) do begin + aresult[int1]:= trim(replacechar(aresult[int1],c_tab,' ')); + end; + end; +end; + +function tgdbmi.getcliresultstring(const acommand: string; var aresult: string): gdbresultty; +begin + result:= clicommand(acommand); + if result = gdb_ok then begin + aresult:= fclivalues; + end; + replacechar1(aresult,#$0a,' '); + replacechar1(aresult,#$0d,' '); +end; + +function tgdbmi.getclistring(const aname: string; const response: string; out aresult: string): boolean; +var + int1: integer; + po1,po2: pchar; +begin + int1:= pos(aname,response); + if int1 > 0 then begin + aresult:= ''; + result:= true; + po1:= @response[int1+length(aname)]; + po2:= strnscan(po1,' '); + if po2 <> nil then begin + po1:= strscan(po2,' '); + if po1 <> nil then begin + setstring(aresult,po2,po1-po2); + end + else begin + setstring(aresult,po2,length(response)-(po1-pchar(pointer(response)))); + end; + end; + end + else begin + result:= false; + end; +end; + +function tgdbmi.getcliinteger(const aname: string; const response: string; out aresult: integer): boolean; +var + str1: string; +begin + result:= getclistring(aname,response,str1) and + trystrtointvalue(str1,longword(aresult)); +end; + +function tgdbmi.getcliint64(const aname: string; const response: string; + out aresult: int64): boolean; +var + str1: string; +begin + result:= getclistring(aname,response,str1) and + trystrtointvalue64(str1,qword(aresult)); +end; + +function tgdbmi.getpascalvalue(const avalue: string): string; +const + ansistringtag = '(ANSISTRING)'; +var + ca1: qword; +begin + if startsstr(ansistringtag,avalue) then begin + if ispointervalue(copy(avalue,length(ansistringtag)+1,bigint),ca1) then begin + result:= getpcharvar(ca1); + exit; + end; + end; + result:= avalue; +end; + +function tgdbmi.stacklistframes(out list: frameinfoarty; first, + last: integer): gdbresultty; +var + ar1,ar2,ar3,ar4: resultinfoarty; + int1,int2: integer; +// str1: string; + {$ifndef FPC} + lint1: int64; + {$endif} +begin + result:= synccommand('-stack-info-depth '+ inttostr(last)); + if result = gdb_ok then begin + getintegervalue(fsyncvalues,'depth',int1); + if int1 < last then begin + last:= int1; + end; + result:= synccommand('-stack-list-frames '+inttostr(first) + ' ' + inttostr(last)); + if result = gdb_ok then begin + if getarrayvalue(fsyncvalues,'stack',true,ar1) then begin + setlength(list,length(ar1)); + for int1:= 0 to high(list) do begin + gettuplevalue(ar1[int1],ar2); + with list[int1] do begin + getintegervalue(ar2,'level',level); + {$ifndef FPC} + getinteger64value(ar2,'addr',lint1); + addr:= lint1; + {$else} + getinteger64value(ar2,'addr',int64(addr)); + {$endif} + getstringvalue(ar2,'func',func); + filename:= msestring(getfullname(ar2)); + getintegervalue(ar2,'line',line); + end; + end; + result:= synccommand('-stack-list-arguments 1 '+inttostr(first) + ' ' + inttostr(last)); + if (result = gdb_ok) and (high(ar1) = high(list)) then begin + if getarrayvalue(fsyncvalues,'stack-args',true,ar1) then begin + for int1:= 0 to high(list) do begin + gettuplevalue(ar1[int1],ar2); + with list[int1] do begin + getarrayvalue(ar2,'args',false,ar3); + setlength(params,length(ar3)); + for int2:= 0 to high(ar3) do begin + decodelist(false,ar3[int2].value,ar4); + if high(ar4) = 1 then begin + params[int2].name:= ar4[0].value; + params[int2].value:= getpascalvalue(ar4[1].value); + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tgdbmi.selectstackframe(const aframe: integer): gdbresultty; +begin +// result:= synccommand('-stack-select-frame '+inttostr(aframe)); does not +// switch info source + result:= synccommand('frame '+inttostr(aframe)); //switches info source + if result = gdb_ok then begin + updatecurrentlanguage(); + end; +end; + +function tgdbmi.selectstackpointer(const aframe: qword): gdbresultty; +begin + result:= synccommand('frame '+qwordtocstr(aframe)); + if result = gdb_ok then begin + updatecurrentlanguage(); + end; +end; + +function tgdbmi.started: boolean; +begin + result:= running or active and (fstate*[gs_started{,gs_attached}] <> []); +end; + +procedure tgdbmi.targetwriteln(const avalue: string); +begin + if running then begin + {$ifdef UNIX} + ftargetterminal.output.writeln(avalue); + {$else} + fgdbto.writeln(avalue); + {$endif} + end; +end; + +function tgdbmi.downloading: boolean; +begin + result:= gs_downloading in fstate; +end; + +function tgdbmi.downloaded: boolean; +begin + result:= gs_downloaded in fstate; +end; + +function tgdbmi.getprocessorname: ansistring; +begin + result:= processornames[fprocessor]; +end; + +procedure tgdbmi.setprocessorname(const avalue: ansistring); +var + pro1: processorty; +begin +{$ifdef CPU64} + fprocessor:= pro_x86_64; +{$else} + {$ifdef CPUARM} + fprocessor:= pro_arm; + {$else} + fprocessor:= pro_i386; + {$endif} +{$endif} + for pro1:= low(processorty) to high(processorty) do begin + if processornames[pro1] = avalue then begin + fprocessor:= pro1; + break; + end; + end; +end; + +procedure tgdbmi.setoverloadsleepus(const avalue: integer); +begin + foverloadsleepus:= avalue; + if fgdbfrom <> nil then begin + fgdbfrom.overloadsleepus:= avalue; + end; +{ + if fgdberror <> nil then begin + fgdberror.overloadsleepus:= avalue; + end; +} +{$ifdef UNIX} + ftargetterminal.input.overloadsleepus:= avalue; +{$endif} +end; + +procedure tgdbmi.updatepascalexpression(var aexpression: string); +begin + if (fcurrentlanguage = lan_pascal) and (pos('$',aexpression) = 0) then begin + //no register name + if ffpcworkaround then begin +// if not startsstr('self.',aexpression) and (aexpression <> 'self') then begin + aexpression:= uppercase(aexpression); + //workaround for gdb bug with class fields +// end; + end; + end; +end; + +procedure tgdbmi.updatecurrentlanguage(); +var + fna1: filenamety; +begin + getsourcename(fna1,fcurrentlanguage); +end; + +{$ifdef UNIX} +{ tpseudoterminal } + +constructor tpseudoterminal.create; + + procedure error; + begin + sys_closefile(fpty); + fpty:= invalidfilehandle; + syserror(syelasterror,'Can not create pseudoterminal:'); + end; + +const + buflen = 100; + +var + ios: termios{ty}; + +begin + fpty:= invalidfilehandle; + fpty:= getpt; + if fpty < 0 then error; + if (grantpt(fpty) < 0) or (unlockpt(fpty) < 0) then error; + setlength(fdevicename,buflen); + if ptsname_r(fpty,@fdevicename[1],buflen) < 0 then error; + setlength(fdevicename,length(pchar(fdevicename))); + fillchar(ios,sizeof(ios),0); + if msetcgetattr(fpty,ios) <> 0 then error; + ios.c_lflag:= ios.c_lflag and not (icanon or echo); + ios.c_cc[vmin]:= #1; + ios.c_cc[vtime]:= #0; + if msetcsetattr(fpty,tcsanow,ios) <> 0 then error; + finput:= tpipereader.create; + foutput:= tpipewriter.create; +// finput.handle:= pty; + foutput.handle:= fpty; +end; + +destructor tpseudoterminal.destroy; +begin + closeinp; + foutput.releasehandle; + finput.releasehandle; + foutput.free; + finput.free; + if fpty <> invalidfilehandle then begin + sys_closefile(fpty); + end; +end; + +procedure tpseudoterminal.closeinp; +var + ios: termios{ty}; +begin + finput.terminate(true); + if finput.active then begin + msetcgetattr(foutput.handle,ios); + ios.c_lflag:= (ios.c_lflag and not (icanon)) or echo; + ios.c_cc[vmin]:= #0; + ios.c_cc[vtime]:= #0; + msetcsetattr(foutput.handle,tcsanow,ios); + foutput.writeln(''); + end; +end; + +procedure tpseudoterminal.restart; +var + ios: termios{ty}; +begin + closeinp; + if foutput.handle <> invalidfilehandle then begin + if msetcgetattr(foutput.handle,ios) = 0 then begin + ios.c_lflag:= ios.c_lflag and not (icanon or echo); + ios.c_cc[vmin]:= #1; + ios.c_cc[vtime]:= #0; + if msetcsetattr(foutput.handle,tcsanow,ios) = 0 then begin + finput.releasehandle; + finput.handle:= foutput.handle; + end; + end; + end; +end; + +procedure tpseudoterminal.setoutecho(const avalue: boolean); +var + ios: termios{ty}; +begin + if msetcgetattr(fpty,ios) = 0 then begin + if avalue then begin + ios.c_lflag:= ios.c_lflag or echo; + end + else begin + ios.c_lflag:= ios.c_lflag and not echo; + end; + msetcsetattr(foutput.handle,tcsanow,ios); + end; +end; + +function tpseudoterminal.getoutecho: boolean; +var + ios: termios{ty}; +begin + result:= false; + if msetcgetattr(fpty,ios) = 0 then begin + result:= ios.c_lflag and echo <> 0; + end; +end; + +{$endif unix} + +procedure localizetext; +var + sr1: stopreasonty; +begin + for sr1:= sr_unknown to high(stopreasonty) do begin + stopreasontext[sr1]:= ansistring(actionsmo.c[ord(ac_sr_unknown)-1+ord(sr1)]); + end; +end; + +initialization + stopreasontext:= defaultstopreasontext; +{$ifdef mswindows} + {$ifdef mse_usedebugbreakprocess} + checkprocaddresses(['Kernel32.dll'], + ['DebugBreakProcess'], + [@DebugBreakProcess]); + {$endif} +{$endif} +end. diff --git a/mseide-msegui/lib/common/designutils/mseificlienteditor.mfm b/mseide-msegui/lib/common/designutils/mseificlienteditor.mfm new file mode 100644 index 0000000..cab67d5 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseificlienteditor.mfm @@ -0,0 +1,120 @@ +object mseificlienteditorfo: tmseificlienteditorfo + visible = False + bounds_x = 137 + bounds_y = 263 + bounds_cx = 284 + bounds_cy = 253 + container.bounds = ( + 0 + 0 + 284 + 253 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'ifi Client Editor' + moduleclassname = 'tmseform' + object grid: twidgetgrid + bounds_x = 0 + bounds_y = 0 + bounds_cx = 284 + bounds_cy = 210 + anchors = [an_top, an_bottom] + optionsgrid = [og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstep = 1 + end> + datacols.count = 2 + datacols.options = [co_savestate, co_mousescrollrow] + datacols.items = < + item[po] + options = [co_invisible, co_drawfocus, co_savestate, co_mousescrollrow] + widgetname = 'po' + dataclass = tgridpointerdatalist + end + item[na] + width = 203 + options = [co_fill, co_savestate, co_mousescrollrow] + oncellevent = celle + widgetname = 'na' + dataclass = titemeditlist + end> + datarowheight = 16 + statfile = tstatfile1 + reffontheight = 14 + object po: tpointeredit + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + end + object na: tmbdropdownitemedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + imagenr = 17 + onexecute = editexe + end> + taborder = 2 + visible = False + bounds_x = 51 + bounds_y = 0 + bounds_cx = 203 + bounds_cy = 16 + optionsedit1 = [] + onkeydown = keydownexe + onsetvalue = setval + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + onbeforedropdown = befdrop + reffontheight = 14 + end + end + object tbutton1: tbutton + taborder = 1 + bounds_x = 168 + bounds_y = 224 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object tbutton2: tbutton + taborder = 2 + bounds_x = 224 + bounds_y = 224 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localdefault, as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object tstatfile1: tstatfile + filename = 'ificlienteditor.sta' + options = [sfo_memory] + onstatupdate = statexe + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseificlienteditor.pas b/mseide-msegui/lib/common/designutils/mseificlienteditor.pas new file mode 100644 index 0000000..11c92e5 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseificlienteditor.pas @@ -0,0 +1,198 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseificlienteditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,mseificomp,msedataedits, + mseedit,msegrids,msestrings,msetypes,msewidgetgrid,msesimplewidgets,msewidgets, + msegraphedits,msedatanodes,mselistbrowser,classes,mclasses,msestatfile; + +type + tmseificlienteditorfo = class(tmseform) + grid: twidgetgrid; + tbutton1: tbutton; + tbutton2: tbutton; + po: tpointeredit; + na: tmbdropdownitemedit; + tstatfile1: tstatfile; + procedure befdrop(const sender: TObject); + procedure setval(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure celle(const sender: TObject; var info: celleventinfoty); + procedure editexe(const sender: TObject); + procedure statexe(const sender: TObject; const filer: tstatfiler); + procedure keydownexe(const sender: twidget; var ainfo: keyeventinfoty); + private + fcomp: tifilinkcomp; + finstances: ppointeraty; + fpath: msestring; + function filtercomponent(const acomponent: tcomponent): boolean; + end; + +function editificlient(const acomponent: tifilinkcomp): modalresultty; + +implementation +uses + mseificlienteditor_mfm,msepropertyeditors,msedesignintf,msedesigner, + objectinspector,typinfo,msearrayutils,msecomptree; +type + tmsecomponent1 = class(tmsecomponent); + +function getdispname(const aobject: tobject): msestring; +begin + if aobject is tcomponent then begin + result:= getcomponentpropname(tcomponent(aobject)); + end + else begin + result:= msestring(aobject.classname); + end; +end; + +function editificlient(const acomponent: tifilinkcomp): modalresultty; +var + edfo: tmseificlienteditorfo; + ar1: objectarty; + int1: integer; + ar2: pointerarty; +begin + edfo:= tmseificlienteditorfo.create(nil); + try +{$warnings off} + ar1:= tmsecomponent1(acomponent).getobjectlinker.linkedobjects( + acomponent.controller); +{$warnings on} + edfo.po.gridvalues:= pointerarty(ar1); + edfo.fcomp:= acomponent; + for int1:= 0 to high(ar1) do begin + edfo.na[int1].caption:= getdispname(ar1[int1]); + end; + edfo.caption:= edfo.caption + ' ('+msestring(acomponent.name)+')'; + result:= edfo.show(true); + if result = mr_ok then begin + ar2:= edfo.po.gridvalues; + for int1:= 0 to high(ar1) do begin //remove not linked + if finditem(ar2,ar1[int1]) < 0 then begin + setobjectprop(ar1[int1],'ifilink',nil); + designer.componentmodified(ar1[int1]); + ar1[int1]:= nil; + end; + end; + for int1:= 0 to high(ar2) do begin //add linked + if (ar2[int1] <> nil) and + (finditem(pointerarty(ar1),ar2[int1]) < 0) then begin + setobjectprop(tobject(ar2[int1]),'ifilink',acomponent); + designer.componentmodified(tcomponent(ar2[int1])); + end; + end; + end; + finally + edfo.free; + end; +end; + +function tmseificlienteditorfo.filtercomponent( + const acomponent: tcomponent): boolean; +var + int1: integer; + po1: ppropinfo; +begin + result:= fcomp.controller.canconnect(acomponent); + if result and (pointer(acomponent) <> po.value) then begin + for int1:= 0 to grid.rowhigh do begin + if finstances^[int1] = pointer(acomponent) then begin + result:= false; + exit; + end; + end; + po1:= getpropinfo(acomponent,'ifilink'); + result:= (po1 <> nil) and (po1^.proptype^.kind = tkclass) and + (fcomp is gettypedata(po1^.proptype{$ifndef FPC}^{$endif})^.classtype); + end; +end; + +procedure tmseificlienteditorfo.befdrop(const sender: TObject); +begin + finstances:= po.griddata.datapo; + with tmbdropdownitemedit(sender) do begin + dropdown.cols[0].asarray:= designer.getcomponentnamelist( + tcomponent,false,nil,{$ifdef FPC}@{$endif}filtercomponent); + end; +end; + +procedure tmseificlienteditorfo.setval(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var + comp1: tcomponent; + int1: integer; +begin + comp1:= designer.getcomponent(ansistring(avalue),fcomp.owner); + po.value:= comp1; + if comp1 <> nil then begin + avalue:= getdispname(tcomponent(po.value)); + fpath:= msestring(ownernamepath(comp1)); + int1:= findlastchar(fpath,'.'); + if int1 > 0 then begin + setlength(fpath,int1-1); + end; + end; +end; + +procedure tmseificlienteditorfo.celle(const sender: TObject; + var info: celleventinfoty); +begin + if iscellclick(info,[ccr_dblclick,ccr_nokeyreturn]) then begin + designer.showformdesigner(designer.modules.findmodulebycomponent( + tcomponent(po.value))); + designer.selectcomponent(tcomponent(po.value)); + window.modalresult:= mr_ok; +// objectinspectorfo.activate; + end; +end; + +procedure tmseificlienteditorfo.editexe(const sender: TObject); +var + tree1: tcompnameitem; + mstr1: msestring; + bo1: boolean; +begin + finstances:= po.griddata.datapo; + tree1:= designer.getcomponentnametree(tcomponent,true,false,nil, + {$ifdef FPC}@{$endif}filtercomponent); + mstr1:= msestring(ownernamepath(tcomponent(po.value))); + if mstr1 = '' then begin + mstr1:= fpath; + end; + if compnamedialog(tree1,mstr1,false) = mr_ok then begin + bo1:= true; + setval(nil,mstr1,bo1); + na.item.caption:= mstr1; + end; + +end; + +procedure tmseificlienteditorfo.statexe(const sender: TObject; + const filer: tstatfiler); +begin + filer.updatevalue('path',fpath); +end; + +procedure tmseificlienteditorfo.keydownexe(const sender: twidget; + var ainfo: keyeventinfoty); +begin + if isenterkey(nil,ainfo.key) and (ainfo.shiftstate = []) and + not na.edited then begin + include(ainfo.eventstate,es_processed); + editexe(nil); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseificlienteditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseificlienteditor_mfm.pas new file mode 100644 index 0000000..7a27c61 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseificlienteditor_mfm.pas @@ -0,0 +1,128 @@ +unit mseificlienteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseificlienteditor; + +const + objdata: record size: integer; data: array[0..2216] of byte end = + (size: 2217; data: ( + 84,80,70,48,21,116,109,115,101,105,102,105,99,108,105,101,110,116,101,100, + 105,116,111,114,102,111,20,109,115,101,105,102,105,99,108,105,101,110,116,101, + 100,105,116,111,114,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,3,137,0,8,98,111,117,110,100,115,95,121,3,7,1, + 9,98,111,117,110,100,115,95,99,120,3,28,1,9,98,111,117,110,100,115, + 95,99,121,3,253,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,28,1,3,253,0,0,7,111,112,116,105, + 111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102, + 111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117, + 116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112, + 111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95, + 115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6, + 17,105,102,105,32,67,108,105,101,110,116,32,69,100,105,116,111,114,15,109, + 111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101, + 102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114, + 105,100,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,28,1,9,98,111, + 117,110,100,115,95,99,121,3,210,0,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111,112, + 116,105,111,110,115,103,114,105,100,11,15,111,103,95,114,111,119,105,110,115, + 101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110, + 103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101, + 114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103, + 95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104, + 97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112, + 99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95, + 109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120,99, + 111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46, + 105,116,101,109,115,14,1,5,119,105,100,116,104,2,24,7,110,117,109,115, + 116,101,112,2,1,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117, + 110,116,2,2,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110, + 115,11,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,2,112,111,1,7,111,112,116,105, + 111,110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,12,99,111, + 95,100,114,97,119,102,111,99,117,115,12,99,111,95,115,97,118,101,115,116, + 97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,2,112,111,9,100,97, + 116,97,99,108,97,115,115,7,20,116,103,114,105,100,112,111,105,110,116,101, + 114,100,97,116,97,108,105,115,116,0,7,2,110,97,1,5,119,105,100,116, + 104,3,203,0,7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,11,111,110,99,101,108,108, + 101,118,101,110,116,7,5,99,101,108,108,101,10,119,105,100,103,101,116,110, + 97,109,101,6,2,110,97,9,100,97,116,97,99,108,97,115,115,7,13,116, + 105,116,101,109,101,100,105,116,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,12,116,112,111,105,110,116,101,114,101,100,105, + 116,2,112,111,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101,49, + 95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97,116, + 114,101,97,100,0,7,118,105,115,105,98,108,101,8,0,0,19,116,109,98, + 100,114,111,112,100,111,119,110,105,116,101,109,101,100,105,116,2,110,97,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 10,102,114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,18,102,114,97,109,101,46,98,117,116,116,111, + 110,46,99,111,108,111,114,4,5,0,0,144,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108, + 111,114,4,5,0,0,144,0,1,7,105,109,97,103,101,110,114,2,17,9, + 111,110,101,120,101,99,117,116,101,7,7,101,100,105,116,101,120,101,0,0, + 8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,2,51,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,3,203,0,9,98,111,117,110, + 100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,0,9,111,110,107,101,121,100,111,119,110,7,10,107,101,121,100,111,119, + 110,101,120,101,10,111,110,115,101,116,118,97,108,117,101,7,6,115,101,116, + 118,97,108,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115, + 11,14,100,101,111,95,115,101,108,101,99,116,111,110,108,121,16,100,101,111, + 95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101, + 121,100,114,111,112,100,111,119,110,0,19,100,114,111,112,100,111,119,110,46, + 99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,16,111,110,98, + 101,102,111,114,101,100,114,111,112,100,111,119,110,7,7,98,101,102,100,114, + 111,112,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,49,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,168, + 0,8,98,111,117,110,100,115,95,121,3,224,0,9,98,111,117,110,100,115, + 95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110, + 99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11, + 109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0, + 7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,224,0, + 8,98,111,117,110,100,115,95,121,3,224,0,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99, + 104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99, + 101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99, + 97,110,99,101,108,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115, + 116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,19,105, + 102,105,99,108,105,101,110,116,101,100,105,116,111,114,46,115,116,97,7,111, + 112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,12, + 111,110,115,116,97,116,117,112,100,97,116,101,7,7,115,116,97,116,101,120, + 101,4,108,101,102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmseificlienteditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseificomponenteditors.pas b/mseide-msegui/lib/common/designutils/mseificomponenteditors.pas new file mode 100644 index 0000000..5244f66 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseificomponenteditors.pas @@ -0,0 +1,47 @@ +{ MSEgui Copyright (c) 2009-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseificomponenteditors; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msecomponenteditors,msedesignintf,classes,mclasses,mseificlienteditor; + +const + ificlienteditorstatname = 'ificlienteditor.sta'; + +type + tifilinkcompeditor = class(tcomponenteditor) + public + constructor create(const adesigner: idesigner; + acomponent: tcomponent); override; + procedure edit; override; + end; + +implementation +uses + mseificomp,mseglob; + +{ tifilinkcompeditor } + +constructor tifilinkcompeditor.create(const adesigner: idesigner; + acomponent: tcomponent); +begin + inherited; + fstate:= fstate + [cs_canedit]; +end; + +procedure tifilinkcompeditor.edit; +begin + if editificlient(tifilinkcomp(fcomponent)) = mr_ok then begin + fdesigner.componentmodified(fcomponent); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseififieldeditor.mfm b/mseide-msegui/lib/common/designutils/mseififieldeditor.mfm new file mode 100644 index 0000000..39a370e --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseififieldeditor.mfm @@ -0,0 +1,336 @@ +object mseififieldeditorfo: tmseififieldeditorfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 29 + bounds_y = 248 + bounds_cx = 601 + bounds_cy = 216 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + container.frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + container.bounds = ( + 0 + 0 + 601 + 216 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + oneventloopstart = formloaded + moduleclassname = 'tmseform' + object tbutton1: tbutton + taborder = 3 + bounds_x = 472 + bounds_y = 184 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object tbutton2: tbutton + bounds_x = 536 + bounds_y = 184 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object fielddefli: tstringgrid + frame.caption = 'Fielddefs' + frame.captionpos = cp_top + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 336 + bounds_y = 7 + bounds_cx = 258 + bounds_cy = 171 + bounds_cxmin = 50 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup] + datacols.count = 2 + datacols.options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + datacols.items = < + item + width = 123 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate] + optionsedit = [scoe_eatreturn] + valuefalse = '0' + valuetrue = '1' + end + item + width = 129 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate] + optionsedit = [scoe_eatreturn] + valuefalse = '0' + valuetrue = '1' + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Type' + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612732 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datarowheight = 16 + oncellevent = defscellevent + onselectionchanged = defsselectioncha + reffontheight = 14 + end + object fields: twidgetgrid + frame.caption = 'Fields' + frame.captionpos = cp_top + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 7 + bounds_cx = 323 + bounds_cy = 171 + anchors = [an_left, an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_sorted, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 15 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 5 + captions.items = < + item + end + item + end + item + caption = 'fieldname' + end + item + caption = 'sourcefieldname' + end + item + caption = 'datatype' + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612732 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datacols.count = 5 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + datacols.items = < + item[index] + width = 13 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate] + widgetname = 'index' + dataclass = tgridintegerdatalist + end + item[fieldpo] + width = 12 + options = [co_invisible, co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + widgetname = 'fieldpo' + dataclass = tgridpointerdatalist + end + item[fieldname] + width = 92 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate] + widgetname = 'fieldname' + dataclass = tgridmsestringdatalist + end + item[sourcefieldname] + width = 119 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate] + widgetname = 'sourcefieldname' + dataclass = tgridmsestringdatalist + end + item[datatype] + width = 62 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate] + widgetname = 'datatype' + dataclass = tgridenumdatalist + end> + datarowheight = 16 + onrowsdeleting = fieldrowsdeleting + onrowsdeleted = fieldsrowdel + oncellevent = fieldcellevent + onselectionchanged = fieldselectioncha + onsort = fieldsort + reffontheight = 14 + object index: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_noskin] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 13 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + object fieldpo: tpointeredit + optionsskin = [osk_noskin] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cx = 12 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object fieldname: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 27 + bounds_y = 0 + bounds_cx = 92 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_notnull] + ondataentered = fieldsdataentered + onsetvalue = fieldnamesetvalue + reffontheight = 14 + end + object sourcefieldname: tdropdownlistedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + taborder = 4 + visible = False + bounds_x = 120 + bounds_y = 0 + bounds_cx = 119 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_notnull] + ondataentered = fieldsdataentered + onsetvalue = sourcefieldsetexe + dropdown.options = [deo_autodropdown, deo_keydropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + onbeforedropdown = sourcebefdropexe + reffontheight = 14 + end + object datatype: tenumtypeedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.width = 15 + frame.button.color = -1879048187 + taborder = 5 + visible = False + bounds_x = 240 + bounds_y = 0 + bounds_cx = 62 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_notnull] + ondataentered = fieldsdataentered + valuedefault = 0 + min = 0 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = initfieldkind + reffontheight = 14 + end + end + object splitter: tsplitter + color = -1879048189 + taborder = 6 + bounds_x = 331 + bounds_y = 24 + bounds_cx = 5 + bounds_cy = 154 + anchors = [an_left, an_top, an_bottom] + options = [spo_hmove, spo_hprop] + linkleft = fields + linkright = fielddefli + statfile = tstatfile1 + onupdatelayout = splitterupda + end + object deftofield: tstockglyphbutton + optionswidget = [ow_destroywidgets] + taborder = 5 + bounds_x = 338 + bounds_y = 5 + bounds_cx = 28 + bounds_cy = 15 + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowleft + onexecute = transferfields + end + object fieldtodef: tstockglyphbutton + optionswidget = [ow_destroywidgets] + taborder = 4 + bounds_x = 303 + bounds_y = 5 + bounds_cx = 28 + bounds_cy = 15 + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowright + onexecute = deletefields + end + object tstatfile1: tstatfile + filename = 'ififieldeditor.sta' + options = [sfo_memory] + left = 24 + top = 152 + end + object c: tstringcontainer + strings.data = ( + 'Connection' + ) + left = 152 + top = 152 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseififieldeditor.pas b/mseide-msegui/lib/common/designutils/mseififieldeditor.pas new file mode 100644 index 0000000..034eb98 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseififieldeditor.pas @@ -0,0 +1,572 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit mseififieldeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mdb,msegui,mseclasses,mseforms,msedb,msestat,msestatfile,msesimplewidgets, + msegrids,msewidgetgrid,msesplitter,msedataedits,msestrings,mseeditglob, + msegraphedits,mseglob,msegridsglob,msestringcontainer,mseificomp,mseifidbcomp, + mseedit,mseguiglob,mseificompglob,mseifiglob,msemenus,msetypes,msedatalist; + +const + ififieldeditorstatname = 'ififieldeditor.sta'; +type + tmseififieldeditorfo = class(tmseform) + tbutton1: tbutton; + tbutton2: tbutton; + index: tintegeredit; + datatype: tenumtypeedit; + splitter: tsplitter; + fieldpo: tpointeredit; + tstatfile1: tstatfile; + fielddefli: tstringgrid; + fields: twidgetgrid; + fieldname: tstringedit; + deftofield: tstockglyphbutton; + fieldtodef: tstockglyphbutton; + c: tstringcontainer; + sourcefieldname: tdropdownlistedit; + procedure formloaded(const sender: TObject); + procedure initcla(const sender: tenumtypeedit); + procedure splitterupda(const sender: TObject); + procedure defscellevent(const sender: TObject; var info: celleventinfoty); + procedure defsselectioncha(const sender: TObject); + procedure fieldnamesetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure fieldsdataentered(const sender: TObject); + procedure fieldsrowdel(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); + procedure transferfields(const sender: TObject); + procedure fieldrowsdeleting(const sender: tcustomgrid; var aindex: Integer; + var acount: Integer); + procedure initfieldkind(const sender: tenumtypeedit); + procedure fieldcellevent(const sender: TObject; var info: celleventinfoty); + procedure fieldselectioncha(const sender: TObject); + procedure deletefields(const sender: TObject); + procedure fieldsort(const sender: tcustomgrid; const index1: Integer; + const index2: Integer; var aresult: Integer); + procedure sourcebefdropexe(const sender: TObject); + procedure sourcefieldsetexe(const sender: TObject; var avalue: msestring; + var accept: Boolean); + private + ffields: tificonnectedfields; + ffieldintf: iifidbdataconnection; + procedure checkfielddefs; + function findfielddef(aname: msestring): integer; + function typeok(const aname: msestring; + const atype: listdatatypety): boolean; + function uniquefieldname(const aname: msestring): msestring; + public + constructor create(const afields: tificonnectedfields); reintroduce; + end; + +function editififields(const instance: tificonnectedfields): boolean; + +implementation +uses + mseififieldeditor_mfm,typinfo,msewidgets,sysutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tificonnectedfields1 = class(tificonnectedfields); + tconnectedifidatasource1 = class(tconnectedifidatasource); + stringconststy = ( + str_connection //0 Connection + ); + +function editififields(const instance: tificonnectedfields): boolean; +var + fo: tmseififieldeditorfo; + int1{,int2}: integer; +// ct1: fieldclassty; +// ar1: fieldarty; +// activebefore: boolean; +begin + result:= false; + fo:= tmseififieldeditorfo.create(instance); + try + with fo do begin + if ffieldintf <> nil then begin + try + if show(true) = mr_ok then begin + fo.window.nofocus; //remove empty last line + result:= true; + instance.beginupdate(); + instance.count:= fields.rowcount; + for int1:= 0 to fields.rowhigh() do begin + with tififieldlink(instance[int1]) do begin + sourcefieldname:= ansistring(fo.sourcefieldname[int1]); + fieldname:= ansistring(fo.fieldname[int1]); + datatype:= listdatatypety(fo.datatype[int1]); + end; + end; + instance.endupdate(); + (* + setlength(ar1,fields.rowcount-dataset.fields.count); + for int1:= 0 to high(ar1) do begin + ct1:= getmsefieldclass(fieldclasstypety(classty[int1])); +// ct1:= msefieldtypeclasses[fieldclasstypety(classty[int1])]; + int2:= index[int1]; + if int2 > 0 then begin + dec(int2); + if ct1 <> items[int2].classtype then begin + ar1[int1]:= ct1.create(nil); + ar1[int1].dataset:= dataset; + end + else begin + ar1[int1]:= items[int2]; + fitems[int2]:= nil; + end; + end + else begin + if fieldpo[int1] <> nil then begin + ar1[int1]:= tfield(fieldpo[int1]); + fieldpo[int1]:= nil; + end + else begin + ar1[int1]:= ct1.create(nil); + try + ar1[int1].dataset:= dataset; + except + application.handleexception(nil); + end; + end; + end; + try + ar1[int1].fieldname:= fieldname[int1]; + except + application.handleexception(nil); + end; + ar1[int1].fieldkind:= tfieldkind(fieldkind[int1]); + end; + for int1:= 0 to count - 1 do begin + items[int1].free; + end; + for int1:= 0 to high(ar1) do begin + tfield(fieldpo[int1]).free; + end; + fitems:= persistentarty(ar1); + *) + end; + finally + { + for int1:= 0 to count - 1 do begin + items[int1].dataset:= dataset; + end; + if result then begin + for int1:= 0 to high(ar1) do begin + items[int1].index:= int1; + end; + for int1:= length(ar1) to fields.rowhigh do begin + tfield(fieldpo[int1]).index:= int1; + end; + end; + if activebefore then begin + try + dataset.active:= true; + except + application.handleexception(dataset); + end; + end; +} + end; + end; + end; + finally + fo.free; + end; +end; + +{ tmsedbfieldeditorfo } + +constructor tmseififieldeditorfo.create(const afields: tificonnectedfields); +begin + ffields:= afields; + mseclasses.getcorbainterface( + tificonnectedfields1(ffields).fowner.connection, + typeinfo(iifidbdataconnection),ffieldintf); + inherited create(nil); +end; + +procedure tmseififieldeditorfo.formloaded(const sender: TObject); +var + int1: integer; +// field1: tfield; + ar1: dbfieldinfoarty; +// ar2: msestringarty; +// ar3: datalistarty; + f1: tififieldlink; +begin + if ffieldintf <> nil then begin + caption:= 'ifi '+c[ord(str_connection)]+': '+ + msestring(tificonnectedfields1(ffields).fowner.name); + ar1:= ffieldintf.getfieldinfos(); + fielddefli.rowcount:= length(ar1); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + fielddefli[0][int1]:= name; + fielddefli[1][int1]:= msestring(getenumname( + typeinfo(tfieldtype),ord(datatype))); + end; + end; + fields.rowcount:= ffields.count; + for int1:= 0 to fields.rowhigh do begin + f1:= tififieldlink(ffields[int1]); + fieldname[int1]:= msestring(f1.fieldname); + sourcefieldname[int1]:= msestring(f1.sourcefieldname); + datatype[int1]:= ord(f1.datatype); + end; + checkfielddefs(); + end; + +{ + with ffields.fowner do begin + caption:= c[ord(str_dataset)]+': '+name; + fielddefli.rowcount:= fielddefs.count; + for int1:= 0 to fielddefs.count-1 do begin + fielddefli[0][int1]:= fielddefs[int1].name; + fielddefli[1][int1]:= getenumname(typeinfo(tfieldtype), + ord(fielddefs[int1].datatype)); + end; + end; + fields.rowcount:= ffields.count + ffields.dataset.fields.count; + for int1:= 0 to ffields.count - 1 do begin + index[int1]:= int1+1; + fieldname[int1]:= ffields[int1].fieldname; + classty[int1]:= ord(fieldclasstoclasstyp(fieldclassty(ffields[int1].classtype))); + fieldkind[int1]:= ord(ffields[int1].fieldkind); + end; + for int1:= ffields.count to fields.rowhigh do begin + index[int1]:= int1+1; + field1:= ffields.dataset.fields[int1-ffields.count]; + fieldpo[int1]:= field1; + with field1 do begin + self.fieldname[int1]:= fieldname; + classty[int1]:= ord(fieldclasstoclasstyp(fieldclassty(classtype))); + self.fieldkind[int1]:= ord(fieldkind); + end; + fields.rowfontstate[int1]:= 0; + end; + checkfielddefs; +} +end; + +procedure tmseififieldeditorfo.sourcebefdropexe(const sender: TObject); +begin + sourcefieldname.dropdown.cols[0].asarray:= + ffieldintf.getfieldnames(listdatatypety(datatype.value)); +end; + +function tmseififieldeditorfo.typeok(const aname: msestring; + const atype: listdatatypety): boolean; +begin + result:= false; +end; + +function tmseififieldeditorfo.uniquefieldname( + const aname: msestring): msestring; +var + ar1: msestringarty; + int1: integer; + mstr1,mstr2: msestring; + int2: integer; +label + startlab; +begin + ar1:= fieldname.gridvalues; + for int1:= 0 to high(ar1) do begin + ar1[int1]:= mseuppercase(ar1[int1]); + end; + mstr1:= mseuppercase(aname); + int2:= 0; +startlab: + mstr2:= mstr1; + if int2 <> 0 then begin + mstr2:= mstr2+inttostrmse(int2); + end; + for int1:= 0 to high(ar1) do begin + if ar1[int1] = mstr2 then begin + inc(int2); + goto startlab; + end; + end; + result:= mstr2; +end; + +procedure tmseififieldeditorfo.sourcefieldsetexe(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var +// ar1: msestringarty; + dl1: listdatatypety; +begin + if (avalue <> '') then begin + if not typeok(avalue,listdatatypety(datatype.value)) then begin + dl1:= ffieldintf.getdatatype(ansistring(avalue)); + if dl1 <> dl_none then begin + datatype.value:= ord(dl1); + end; + end; + if fieldname.value = '' then begin + fieldname.value:= uniquefieldname(avalue); + end; + end; +end; + +procedure tmseififieldeditorfo.initcla(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(fieldclasstypety); +end; + +procedure tmseififieldeditorfo.initfieldkind(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(listdatatypety); +end; + +procedure tmseififieldeditorfo.splitterupda(const sender: TObject); +begin + deftofield.left:= splitter.left+splitter.bounds_cx; + fieldtodef.left:= splitter.left-fieldtodef.bounds_cx; +// alignx(wam_center,[splitter,deftofield]); +end; + +procedure tmseififieldeditorfo.defscellevent(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if (eventkind = cek_select) and selected and + (fielddefli.rowfontstate[cell.row] <> -1) then begin + accept:= false; + end; + end; +end; + +procedure tmseififieldeditorfo.defsselectioncha(const sender: TObject); +begin + deftofield.enabled:= fielddefli.datacols.hasselection; +end; + +procedure tmseififieldeditorfo.fieldnamesetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var + mstr1: msestring; + int1: integer; +begin + mstr1:= mseuppercase(avalue); + for int1:= 0 to fields.rowcount-1 do begin + if (int1 <> fields.row) and (mstr1 = mseuppercase(fieldname[int1])) then begin + showerror('Field name exists.'); + accept:= false; + break; + end; + end; +end; + +procedure tmseififieldeditorfo.checkfielddefs; +var + int1,int2: integer; + ar1: msestringarty; + mstr1: msestring; +begin + setlength(ar1,fields.rowcount); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= mseuppercase(sourcefieldname[int1]); + end; + for int1:= 0 to fielddefli.rowcount - 1 do begin + mstr1:= mseuppercase(fielddefli[0][int1]); + fielddefli.rowfontstate[int1]:= -1; + for int2:= 0 to high(ar1) do begin + if mstr1 = ar1[int2] then begin + fielddefli.rowfontstate[int1]:= 0; + fielddefli.datacols.selected[makegridcoord(-1,int1)]:= false; + break; + end; + end; + end; +end; + +procedure tmseififieldeditorfo.fieldsdataentered(const sender: TObject); +begin + checkfielddefs; +end; + +procedure tmseififieldeditorfo.fieldsrowdel(const sender: tcustomgrid; + const aindex: Integer; const acount: Integer); +begin + checkfielddefs; +end; + +procedure tmseififieldeditorfo.transferfields(const sender: TObject); +var + int1,int2: integer; + ar1,ar2: integerarty; + mstr1: msestring; +begin + ar1:= fielddefli.datacols.selectedrows; + if high(ar1) >= 0 then begin + setlength(ar2,length(ar1)); + int2:= 0; + fields.beginupdate; + for int1:= 0 to high(ar1) do begin + fields.appendrow(true); + try + fields.row:= fields.rowhigh; +// fieldpo[fields.rowhigh]:= +// ffields.dataset.fielddefs[ar1[int1]].createfield(nil); +// tfield(fieldpo[fields.rowhigh]).dataset:= nil; + mstr1:= fielddefli[0][ar1[int1]]; + sourcefieldname[fields.rowhigh]:= mstr1; + fieldname[fields.rowhigh]:= uniquefieldname(mstr1); +// classty[fields.rowhigh]:= ord(fieldclasstoclasstyp( +/// ffields.dataset.fielddefs[ar1[int1]].fieldclass)); + datatype[fields.rowhigh]:= ord(ffieldintf.getdatatype(ansistring(mstr1))); + ar2[int2]:= fields.rowhigh; + inc(int2); + except + fields.rowcount:= fields.rowcount - 1; + application.handleexception(nil); + end; + fielddefli.datacols.clearselection; + end; + setlength(ar2,int2); + fields.datacols.selectedrows:= ar2; + fields.endupdate; + // fields.sort; + checkfielddefs; + for int1:= ar1[high(ar1)] + 1 to fielddefli.rowhigh do begin + if fielddefli.rowfontstate[int1] = -1 then begin + fielddefli.row:= int1; + exit; + end; + end; + for int1:= 0 to fielddefli.rowhigh do begin + if fielddefli.rowfontstate[int1] = -1 then begin + fielddefli.row:= int1; + exit; + end; + end; + end; +end; + +procedure tmseififieldeditorfo.fieldrowsdeleting(const sender: tcustomgrid; + var aindex: Integer; var acount: Integer); +var + int1: integer; +begin + for int1:= aindex to aindex + acount - 1 do begin + if sender.rowfontstate[int1] <> -1 then begin + acount:= 0; + break; + end; + end; + for int1:= aindex to aindex + acount - 1 do begin + tfield(fieldpo[int1]).free; + end; +end; + +procedure tmseififieldeditorfo.fieldsort(const sender: tcustomgrid; + const index1: Integer; const index2: Integer; + var aresult: Integer); +begin + aresult:= fields.rowfontstate[index1] - fields.rowfontstate[index2]; +end; + +procedure tmseififieldeditorfo.fieldcellevent(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if eventkind = cek_enter then begin + if fields.rowfontstate[cell.row] = -1 then begin + fields.datacols.options:= fields.datacols.options - [co_readonly]; + fields.optionsgrid:= fields.optionsgrid + [og_rowdeleting]; + end + else begin + fields.datacols.options:= fields.datacols.options + [co_readonly]; + fields.optionsgrid:= fields.optionsgrid - [og_rowdeleting]; + end; + end; + if (eventkind = cek_select) and selected then begin + if fields.rowfontstate[cell.row] <> -1 then begin + accept:= false; + end; + end; + end; +end; + +procedure tmseififieldeditorfo.fieldselectioncha(const sender: TObject); +begin + fieldtodef.enabled:= fields.datacols.hasselection and + (length(fields.datacols.selectedrows) > 0); +end; + +function tmseififieldeditorfo.findfielddef(aname: msestring): integer; +var + int1: integer; +begin + result:= invalidaxis; + aname:= struppercase(aname); + for int1:= 0 to fielddefli.rowhigh do begin + if msestringicompupper(fielddefli[0][int1],aname) = 0 then begin + result:= int1; + break; + end; + end; +end; + +procedure tmseififieldeditorfo.deletefields(const sender: TObject); +var + ar1,ar2: integerarty; + int1: integer; + int2: integer; +begin + ar1:= fields.datacols.selectedrows; + setlength(ar2,length(ar1)); //max + int2:= 0; + for int1:= high(ar1) downto 0 do begin + ar2[int2]:= findfielddef(fieldname[ar1[int1]]); + if ar2[int2] >= 0 then begin + inc(int2); + end; + end; + ffields.beginupdate; + for int1:= high(ar1) downto 0 do begin + fields.deleterow(ar1[int1]); + end; + ffields.endupdate; + if int2 > 0 then begin + setlength(ar2,int2); + fielddefli.row:= ar2[high(ar2)]; + fielddefli.datacols.selectedrows:= ar2; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseififieldeditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseififieldeditor_mfm.pas new file mode 100644 index 0000000..38dbaaa --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseififieldeditor_mfm.pas @@ -0,0 +1,447 @@ +unit mseififieldeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseififieldeditor; + +const + objdata: record size: integer; data: array[0..8586] of byte end = + (size: 8587; data: ( + 84,80,70,48,20,116,109,115,101,105,102,105,102,105,101,108,100,101,100,105, + 116,111,114,102,111,19,109,115,101,105,102,105,102,105,101,108,100,101,100,105, + 116,111,114,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117, + 98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,29,8,98,111,117,110, + 100,115,95,121,3,248,0,9,98,111,117,110,100,115,95,99,120,3,89,2, + 9,98,111,117,110,100,115,95,99,121,3,216,0,23,99,111,110,116,97,105, + 110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111, + 119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116, + 114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107, + 105,110,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108, + 101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100, + 115,1,2,0,2,0,3,89,2,3,216,0,0,7,111,112,116,105,111,110, + 115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95, + 97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111, + 119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115, + 12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102, + 105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,16,111,110,101,118, + 101,110,116,108,111,111,112,115,116,97,114,116,7,10,102,111,114,109,108,111, + 97,100,101,100,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,8,116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110,8, + 116,98,117,116,116,111,110,49,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,3,216,1,8,98,111,117,110,100,115,95,121, + 3,184,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110, + 100,115,95,99,121,2,22,7,97,110,99,104,111,114,115,11,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97, + 116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,2,79,75,11, + 109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0, + 7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,8,98,111, + 117,110,100,115,95,120,3,24,2,8,98,111,117,110,100,115,95,121,3,184, + 0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,22,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105, + 103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99, + 97,112,116,105,111,110,6,6,67,97,110,99,101,108,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0,0,11, + 116,115,116,114,105,110,103,103,114,105,100,10,102,105,101,108,100,100,101,102, + 108,105,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,9,70,105, + 101,108,100,100,101,102,115,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15, + 102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,80,1,8,98,111, + 117,110,100,115,95,121,2,7,9,98,111,117,110,100,115,95,99,120,3,2, + 1,9,98,111,117,110,100,115,95,99,121,3,171,0,12,98,111,117,110,100, + 115,95,99,120,109,105,110,2,50,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110, + 115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,20, + 111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121, + 10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112, + 111,112,117,112,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116, + 2,2,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11, + 11,99,111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,0,14,100,97, + 116,97,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104, + 2,123,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111, + 110,108,121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105, + 108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,14,115,99,111,101,95,101,97,116,114,101, + 116,117,114,110,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9, + 118,97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104, + 3,129,0,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100, + 111,110,108,121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115, + 116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115, + 99,111,101,95,101,97,116,114,101,116,117,114,110,0,10,118,97,108,117,101, + 102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1, + 49,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13, + 102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103, + 104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2, + 2,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99, + 97,112,116,105,111,110,6,4,78,97,109,101,0,1,7,99,97,112,116,105, + 111,110,6,4,84,121,112,101,0,0,0,0,14,114,111,119,102,111,110,116, + 115,46,99,111,117,110,116,2,1,14,114,111,119,102,111,110,116,115,46,105, + 116,101,109,115,14,1,5,99,111,108,111,114,4,4,0,0,160,4,110,97, + 109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99,97, + 108,101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112, + 95,99,111,108,111,114,10,102,108,112,95,120,115,99,97,108,101,0,0,0, + 13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,11,111,110,99, + 101,108,108,101,118,101,110,116,7,13,100,101,102,115,99,101,108,108,101,118, + 101,110,116,18,111,110,115,101,108,101,99,116,105,111,110,99,104,97,110,103, + 101,100,7,16,100,101,102,115,115,101,108,101,99,116,105,111,110,99,104,97, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116, + 119,105,100,103,101,116,103,114,105,100,6,102,105,101,108,100,115,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,6,70,105,101,108,100,115,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102, + 116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,28,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112,116,105, + 111,110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,7,9, + 98,111,117,110,100,115,95,99,120,3,67,1,9,98,111,117,110,100,115,95, + 99,121,3,171,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0, + 11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108, + 115,105,122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15, + 111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114, + 111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101, + 108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111, + 110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114, + 111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,9,111,103,95, + 115,111,114,116,101,100,20,111,103,95,99,111,108,99,104,97,110,103,101,111, + 110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111, + 103,95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,99,111,108,115, + 46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101, + 109,115,14,1,5,119,105,100,116,104,2,15,7,110,117,109,115,116,101,112, + 2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1, + 13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105, + 103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116, + 2,5,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,0, + 1,0,1,7,99,97,112,116,105,111,110,6,9,102,105,101,108,100,110,97, + 109,101,0,1,7,99,97,112,116,105,111,110,6,15,115,111,117,114,99,101, + 102,105,101,108,100,110,97,109,101,0,1,7,99,97,112,116,105,111,110,6, + 8,100,97,116,97,116,121,112,101,0,0,0,0,14,114,111,119,102,111,110, + 116,115,46,99,111,117,110,116,2,1,14,114,111,119,102,111,110,116,115,46, + 105,116,101,109,115,14,1,5,99,111,108,111,114,4,4,0,0,160,4,110, + 97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99, + 97,108,101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108, + 112,95,99,111,108,111,114,10,102,108,112,95,120,115,99,97,108,101,0,0, + 0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,5,16,100, + 97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,5,105, + 110,100,101,120,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110, + 115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116, + 110,97,109,101,6,5,105,110,100,101,120,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,7,102,105,101,108,100,112,111,1,5,119,105,100,116,104, + 2,12,7,111,112,116,105,111,110,115,11,12,99,111,95,105,110,118,105,115, + 105,98,108,101,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116, + 101,0,10,119,105,100,103,101,116,110,97,109,101,6,7,102,105,101,108,100, + 112,111,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,112, + 111,105,110,116,101,114,100,97,116,97,108,105,115,116,0,7,9,102,105,101, + 108,100,110,97,109,101,1,5,119,105,100,116,104,2,92,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105, + 100,103,101,116,110,97,109,101,6,9,102,105,101,108,100,110,97,109,101,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,15,115,111,117,114, + 99,101,102,105,101,108,100,110,97,109,101,1,5,119,105,100,116,104,2,119, + 7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95, + 115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110,97,109, + 101,6,15,115,111,117,114,99,101,102,105,101,108,100,110,97,109,101,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,7,8,100,97,116,97,116, + 121,112,101,1,5,119,105,100,116,104,2,62,7,111,112,116,105,111,110,115, + 11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103, + 101,116,110,97,109,101,6,8,100,97,116,97,116,121,112,101,9,100,97,116, + 97,99,108,97,115,115,7,17,116,103,114,105,100,101,110,117,109,100,97,116, + 97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104, + 116,2,16,14,111,110,114,111,119,115,100,101,108,101,116,105,110,103,7,17, + 102,105,101,108,100,114,111,119,115,100,101,108,101,116,105,110,103,13,111,110, + 114,111,119,115,100,101,108,101,116,101,100,7,12,102,105,101,108,100,115,114, + 111,119,100,101,108,11,111,110,99,101,108,108,101,118,101,110,116,7,14,102, + 105,101,108,100,99,101,108,108,101,118,101,110,116,18,111,110,115,101,108,101, + 99,116,105,111,110,99,104,97,110,103,101,100,7,17,102,105,101,108,100,115, + 101,108,101,99,116,105,111,110,99,104,97,6,111,110,115,111,114,116,7,9, + 102,105,101,108,100,115,111,114,116,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,12,116,105,110,116,101,103,101,114,101,100,105,116,5, + 105,110,100,101,120,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,10,111,115,107,95, + 110,111,115,107,105,110,0,8,116,97,98,111,114,100,101,114,2,1,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 13,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 12,116,112,111,105,110,116,101,114,101,100,105,116,7,102,105,101,108,100,112, + 111,11,111,112,116,105,111,110,115,115,107,105,110,11,10,111,115,107,95,110, + 111,115,107,105,110,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,12,9,98,111,117,110,100,115,95,99, + 121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97, + 117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121, + 101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116, + 101,0,7,118,105,115,105,98,108,101,8,0,0,11,116,115,116,114,105,110, + 103,101,100,105,116,9,102,105,101,108,100,110,97,109,101,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,3, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,27, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,92,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117, + 114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114, + 101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95, + 101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111, + 110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111, + 110,114,101,97,100,111,110,108,121,10,111,101,95,110,111,116,110,117,108,108, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,17,102,105,101, + 108,100,115,100,97,116,97,101,110,116,101,114,101,100,10,111,110,115,101,116, + 118,97,108,117,101,7,17,102,105,101,108,100,110,97,109,101,115,101,116,118, + 97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,17,116,100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116, + 15,115,111,117,114,99,101,102,105,101,108,100,110,97,109,101,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108, + 101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,5,0,0,144,8,116,97,98,111,114,100,101,114,2,4,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,120,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,119, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101, + 97,100,111,110,108,121,10,111,101,95,110,111,116,110,117,108,108,0,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,17,102,105,101,108,100,115, + 100,97,116,97,101,110,116,101,114,101,100,10,111,110,115,101,116,118,97,108, + 117,101,7,17,115,111,117,114,99,101,102,105,101,108,100,115,101,116,101,120, + 101,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,16, + 100,101,111,95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111, + 95,107,101,121,100,114,111,112,100,111,119,110,0,19,100,114,111,112,100,111, + 119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112, + 100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,16, + 111,110,98,101,102,111,114,101,100,114,111,112,100,111,119,110,7,16,115,111, + 117,114,99,101,98,101,102,100,114,111,112,101,120,101,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,13,116,101,110,117,109,116,121, + 112,101,101,100,105,116,8,100,97,116,97,116,121,112,101,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 2,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,119,105,100,116,104, + 2,15,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,5,0,0,144,8,116,97,98,111,114,100,101,114,2,5,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,240,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 62,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14, + 111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111, + 101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108, + 121,10,111,101,95,110,111,116,110,117,108,108,0,13,111,110,100,97,116,97, + 101,110,116,101,114,101,100,7,17,102,105,101,108,100,115,100,97,116,97,101, + 110,116,101,114,101,100,12,118,97,108,117,101,100,101,102,97,117,108,116,2, + 0,3,109,105,110,2,0,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,105,116,101,109,115,14,1,0,0,6,111,110,105,110,105,116, + 7,13,105,110,105,116,102,105,101,108,100,107,105,110,100,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,112,108,105, + 116,116,101,114,8,115,112,108,105,116,116,101,114,5,99,111,108,111,114,4, + 3,0,0,144,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110, + 100,115,95,120,3,75,1,8,98,111,117,110,100,115,95,121,2,24,9,98, + 111,117,110,100,115,95,99,120,2,5,9,98,111,117,110,100,115,95,99,121, + 3,154,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,7,111, + 112,116,105,111,110,115,11,9,115,112,111,95,104,109,111,118,101,9,115,112, + 111,95,104,112,114,111,112,0,8,108,105,110,107,108,101,102,116,7,6,102, + 105,101,108,100,115,9,108,105,110,107,114,105,103,104,116,7,10,102,105,101, + 108,100,100,101,102,108,105,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,14,111,110,117,112,100,97,116,101,108,97,121, + 111,117,116,7,12,115,112,108,105,116,116,101,114,117,112,100,97,0,0,17, + 116,115,116,111,99,107,103,108,121,112,104,98,117,116,116,111,110,10,100,101, + 102,116,111,102,105,101,108,100,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115, + 95,120,3,82,1,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117, + 110,100,115,95,99,120,2,28,9,98,111,117,110,100,115,95,99,121,2,15, + 5,115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16, + 97,115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,17,97,115,95, + 108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111, + 99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,5,103,108,121,112,104,7,13,115,116,103, + 95,97,114,114,111,119,108,101,102,116,9,111,110,101,120,101,99,117,116,101, + 7,14,116,114,97,110,115,102,101,114,102,105,101,108,100,115,0,0,17,116, + 115,116,111,99,107,103,108,121,112,104,98,117,116,116,111,110,10,102,105,101, + 108,100,116,111,100,101,102,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95, + 120,3,47,1,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110, + 100,115,95,99,120,2,28,9,98,111,117,110,100,115,95,99,121,2,15,5, + 115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16,97, + 115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,17,97,115,95,108, + 111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99, + 97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,5,103,108,121,112,104,7,14,115,116,103,95, + 97,114,114,111,119,114,105,103,104,116,9,111,110,101,120,101,99,117,116,101, + 7,12,100,101,108,101,116,101,102,105,101,108,100,115,0,0,9,116,115,116, + 97,116,102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105, + 108,101,110,97,109,101,6,18,105,102,105,102,105,101,108,100,101,100,105,116, + 111,114,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95, + 109,101,109,111,114,121,0,4,108,101,102,116,2,24,3,116,111,112,3,152, + 0,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114, + 1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,10,67,111, + 110,110,101,99,116,105,111,110,0,4,108,101,102,116,3,152,0,3,116,111, + 112,3,152,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmseififieldeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseiircoeffeditor.mfm b/mseide-msegui/lib/common/designutils/mseiircoeffeditor.mfm new file mode 100644 index 0000000..bcc35c1 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseiircoeffeditor.mfm @@ -0,0 +1,189 @@ +object iircoeffeditorfo: tiircoeffeditorfo + bounds_x = 72 + bounds_y = 206 + bounds_cx = 522 + bounds_cy = 263 + container.bounds = ( + 0 + 0 + 522 + 263 + ) + statfile = tstatfile1 + caption = 'IIR Filter Coefficients' + moduleclassname = 'tmseform' + object grid: twidgetgrid + bounds_x = 0 + bounds_y = 0 + bounds_cx = 521 + bounds_cy = 221 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_focuscellonenter, og_rowheight, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 62 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 4 + captions.items = < + item + caption = 'Numerator' + end + item + caption = 'Denominator' + end + item + caption = 'Internal Num.' + end + item + caption = 'Internal Den.' + end> + captionsfix.count = 1 + captionsfix.items = < + item + caption = 'sect:z^n' + end> + end> + datacols.count = 4 + datacols.options = [co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[numed] + width = 113 + options = [co_mouseselect, co_keyselect, co_multiselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'numed' + dataclass = tgridrealdatalist + end + item[dened] + width = 106 + options = [co_mouseselect, co_keyselect, co_multiselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dened' + dataclass = tgridrealdatalist + end + item[numdi] + color = -1879048185 + width = 114 + options = [co_readonly, co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'numdi' + dataclass = tgridrealdatalist + end + item[dendi] + color = -1879048185 + width = 117 + options = [co_readonly, co_fill, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'dendi' + dataclass = tgridrealdatalist + end> + datarowheight = 16 + reffontheight = 14 + object numed: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 113 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = datentexe + value = 0 + valuedefault = 0 + valuerange = 1 + valuestart = 0 + min = -1E+038 + max = 1E+038 + reffontheight = 14 + end + object dened: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 114 + bounds_y = 0 + bounds_cx = 106 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = datentexe + value = 0 + valuedefault = 0 + valuerange = 1 + valuestart = 0 + min = -1E+038 + max = 1E+038 + reffontheight = 14 + end + object numdi: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 221 + bounds_y = 0 + bounds_cx = 114 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly] + textflagsactive = [tf_right, tf_ycentered] + value = -Inf + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + min = -Inf + max = 1E+038 + reffontheight = 14 + end + object dendi: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 336 + bounds_y = 0 + bounds_cx = 117 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly] + textflagsactive = [tf_right, tf_ycentered] + value = -Inf + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + min = -Inf + max = 1E+038 + reffontheight = 14 + end + end + object ok: tbutton + taborder = 1 + bounds_x = 395 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 2 + bounds_x = 459 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object tstatfile1: tstatfile + filename = 'iircoeffeditor.sta' + options = [sfo_memory] + left = 56 + top = 48 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseiircoeffeditor.pas b/mseide-msegui/lib/common/designutils/mseiircoeffeditor.pas new file mode 100644 index 0000000..075f6bd --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseiircoeffeditor.pas @@ -0,0 +1,44 @@ +unit mseiircoeffeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msestatfile, + msedataedits,mseedit,msegrids,mseificomp,mseificompglob,mseifiglob,msestrings, + msewidgetgrid,msesimplewidgets; +type + tiircoeffeditorfo = class(tmseform) + tstatfile1: tstatfile; + grid: twidgetgrid; + ok: tbutton; + cancel: tbutton; + numed: trealedit; + dened: trealedit; + numdi: trealedit; + dendi: trealedit; + procedure datentexe(const sender: TObject); + end; + +implementation +uses + mseiircoeffeditor_mfm; + +procedure tiircoeffeditorfo.datentexe(const sender: TObject); +var + int1: integer; + norm: real; +begin + norm:= 0; + for int1:= 0 to grid.rowhigh do begin + if (int1 = 0) or (grid.rowlinewidth[int1-1] > 1) then begin + if dened[int1] = 0 then begin + dened[int1]:= 1.0; + end; + norm:= dened[int1]; + end; + numdi[int1]:= numed[int1]/norm; + dendi[int1]:= dened[int1]/norm; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseiircoeffeditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseiircoeffeditor_mfm.pas new file mode 100644 index 0000000..a3c18af --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseiircoeffeditor_mfm.pas @@ -0,0 +1,202 @@ +unit mseiircoeffeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseiircoeffeditor; + +const + objdata: record size: integer; data: array[0..3690] of byte end = + (size: 3691; data: ( + 84,80,70,48,17,116,105,105,114,99,111,101,102,102,101,100,105,116,111,114, + 102,111,16,105,105,114,99,111,101,102,102,101,100,105,116,111,114,102,111,8, + 98,111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,3, + 206,0,9,98,111,117,110,100,115,95,99,120,3,10,2,9,98,111,117,110, + 100,115,95,99,121,3,7,1,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,10,2,3,7,1,0,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99, + 97,112,116,105,111,110,6,23,73,73,82,32,70,105,108,116,101,114,32,67, + 111,101,102,102,105,99,105,101,110,116,115,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,9,2,9,98,111,117,110,100,115,95,99,121, + 3,221,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 12,111,103,95,114,111,119,104,101,105,103,104,116,20,111,103,95,99,111,108, + 99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114, + 97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111, + 103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105, + 120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108, + 115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,62,0,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16, + 14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,4,14,99,97, + 112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105, + 111,110,6,9,78,117,109,101,114,97,116,111,114,0,1,7,99,97,112,116, + 105,111,110,6,11,68,101,110,111,109,105,110,97,116,111,114,0,1,7,99, + 97,112,116,105,111,110,6,13,73,110,116,101,114,110,97,108,32,78,117,109, + 46,0,1,7,99,97,112,116,105,111,110,6,13,73,110,116,101,114,110,97, + 108,32,68,101,110,46,0,0,17,99,97,112,116,105,111,110,115,102,105,120, + 46,99,111,117,110,116,2,1,17,99,97,112,116,105,111,110,115,102,105,120, + 46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,8,115,101, + 99,116,58,122,94,110,0,0,0,0,14,100,97,116,97,99,111,108,115,46, + 99,111,117,110,116,2,4,16,100,97,116,97,99,111,108,115,46,111,112,116, + 105,111,110,115,11,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97, + 118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109, + 115,14,7,5,110,117,109,101,100,1,5,119,105,100,116,104,2,113,7,111, + 112,116,105,111,110,115,11,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114, + 116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,5,110,117,109,101,100,9,100,97,116,97,99,108,97, + 115,115,7,17,116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115, + 116,0,7,5,100,101,110,101,100,1,5,119,105,100,116,104,2,106,7,111, + 112,116,105,111,110,115,11,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114, + 116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,5,100,101,110,101,100,9,100,97,116,97,99,108,97, + 115,115,7,17,116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115, + 116,0,7,5,110,117,109,100,105,1,5,99,111,108,111,114,4,7,0,0, + 144,5,119,105,100,116,104,2,114,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,15,99,111,95,112,114,111,112,111,114, + 116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,5,110,117,109,100,105,9,100,97,116,97,99,108,97,115,115,7, + 17,116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115,116,0,7, + 5,100,101,110,100,105,1,5,99,111,108,111,114,4,7,0,0,144,5,119, + 105,100,116,104,2,117,7,111,112,116,105,111,110,115,11,11,99,111,95,114, + 101,97,100,111,110,108,121,7,99,111,95,102,105,108,108,12,99,111,95,115, + 97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116, + 101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0, + 10,119,105,100,103,101,116,110,97,109,101,6,5,100,101,110,100,105,9,100, + 97,116,97,99,108,97,115,115,7,17,116,103,114,105,100,114,101,97,108,100, + 97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,9,116,114,101,97,108,101,100,105,116,5,110,117,109,101,100,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102, + 111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,113,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97, + 108,117,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,9, + 100,97,116,101,110,116,101,120,101,5,118,97,108,117,101,2,0,12,118,97, + 108,117,101,100,101,102,97,117,108,116,2,0,10,118,97,108,117,101,114,97, + 110,103,101,2,1,10,118,97,108,117,101,115,116,97,114,116,2,0,3,109, + 105,110,5,245,136,13,181,80,153,118,150,125,192,3,109,97,120,5,245,136, + 13,181,80,153,118,150,125,64,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,9,116,114,101,97,108,101,100,105,116,5,100,101,110, + 101,100,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,2,114,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,106,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97, + 118,101,118,97,108,117,101,0,13,111,110,100,97,116,97,101,110,116,101,114, + 101,100,7,9,100,97,116,101,110,116,101,120,101,5,118,97,108,117,101,2, + 0,12,118,97,108,117,101,100,101,102,97,117,108,116,2,0,10,118,97,108, + 117,101,114,97,110,103,101,2,1,10,118,97,108,117,101,115,116,97,114,116, + 2,0,3,109,105,110,5,245,136,13,181,80,153,118,150,125,192,3,109,97, + 120,5,245,136,13,181,80,153,118,150,125,64,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,9,116,114,101,97,108,101,100,105,116, + 5,110,117,109,100,105,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,3,221,0,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,114,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111, + 101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110, + 115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100, + 111,110,108,121,0,15,116,101,120,116,102,108,97,103,115,97,99,116,105,118, + 101,11,8,116,102,95,114,105,103,104,116,12,116,102,95,121,99,101,110,116, + 101,114,101,100,0,5,118,97,108,117,101,5,0,0,0,0,0,0,0,128, + 255,255,12,118,97,108,117,101,100,101,102,97,117,108,116,5,0,0,0,0, + 0,0,0,128,255,255,10,118,97,108,117,101,114,97,110,103,101,2,1,10, + 118,97,108,117,101,115,116,97,114,116,2,0,3,109,105,110,5,0,0,0, + 0,0,0,0,128,255,255,3,109,97,120,5,245,136,13,181,80,153,118,150, + 125,64,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 9,116,114,101,97,108,101,100,105,116,5,100,101,110,100,105,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,4,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,80,1,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,117,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108, + 117,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95, + 114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102, + 116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115, + 114,101,99,116,111,110,114,101,97,100,111,110,108,121,0,15,116,101,120,116, + 102,108,97,103,115,97,99,116,105,118,101,11,8,116,102,95,114,105,103,104, + 116,12,116,102,95,121,99,101,110,116,101,114,101,100,0,5,118,97,108,117, + 101,5,0,0,0,0,0,0,0,128,255,255,12,118,97,108,117,101,100,101, + 102,97,117,108,116,5,0,0,0,0,0,0,0,128,255,255,10,118,97,108, + 117,101,114,97,110,103,101,2,1,10,118,97,108,117,101,115,116,97,114,116, + 2,0,3,109,105,110,5,0,0,0,0,0,0,0,128,255,255,3,109,97, + 120,5,245,136,13,181,80,153,118,150,125,64,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,7,116,98,117,116,116,111,110,2, + 111,107,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,3,139,1,8,98,111,117,110,100,115,95,121,3,232,0,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9, + 97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97,115, + 95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102, + 97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97,108, + 114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117,116, + 116,111,110,6,99,97,110,99,101,108,8,116,97,98,111,114,100,101,114,2, + 2,8,98,111,117,110,100,115,95,120,3,203,1,8,98,111,117,110,100,115, + 95,121,3,232,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111, + 117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97, + 110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11, + 109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99, + 101,108,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116, + 102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,18,105,105,114,99, + 111,101,102,102,101,100,105,116,111,114,46,115,116,97,7,111,112,116,105,111, + 110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116, + 2,56,3,116,111,112,2,48,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tiircoeffeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseimagelisteditor.mfm b/mseide-msegui/lib/common/designutils/mseimagelisteditor.mfm new file mode 100644 index 0000000..f94cbf1 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimagelisteditor.mfm @@ -0,0 +1,286 @@ +object imagelisteditorfo: timagelisteditorfo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 220 + bounds_y = 297 + bounds_cx = 508 + bounds_cy = 355 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 508 + 355 + ) + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = statfile1 + caption = 'Imagelist Editor' + moduleclassname = 'tmseform' + object disp: tlistview + optionswidget1 = [ow1_fontglyphheight] + frame.localprops = [] + frame.localprops1 = [] + popupmenu = popup + bounds_x = 0 + bounds_y = 0 + bounds_cx = 508 + bounds_cy = 293 + anchors = [an_top, an_bottom] + cellheight = 62 + optionsgrid = [og_colsizing, og_rowsizing, og_focuscellonenter, og_wraprow, og_wrapcol, og_autopopup] + options = [lvo_readonly, lvo_mousemoving, lvo_keymoving, lvo_horz, lvo_drawfocus, lvo_focusselect, lvo_mouseselect, lvo_keyselect, lvo_multiselect, lvo_locate] + itemlist.oncreateitem = createitemev + itemlist.captionpos = cp_bottom + itemlist.imagelist = imagelist + itemlist.imagewidth = 16 + itemlist.imageheight = 16 + onlayoutchanged = layoutchanged + onitemevent = disponitemevent + onitemsmoved = disponitemsmoved + reffontheight = 14 + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.framei_bottom = 5 + frame.localprops = [frl_fibottom] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 296 + bounds_cx = 314 + bounds_cy = 59 + anchors = [an_left, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = disp + dist_top = 3 + options = [spao_gluebottom] + object la2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 0 + bounds_y = 33 + bounds_cx = 297 + bounds_cy = 21 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + dist_top = 4 + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 80 + bounds_y = 0 + bounds_cx = 217 + bounds_cy = 21 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex] + place_mindist = 5 + place_maxdist = 5 + dist_top = 3 + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 2 + bounds_x = 110 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 3 + bounds_x = 165 + bounds_y = 1 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object clear: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 55 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption, as_localonexecute] + caption = 'C&lear' + onexecute = clearonexecute + reffontheight = 14 + end + object add: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 0 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption, as_localonexecute] + caption = '&Add' + onexecute = addonexecute + reffontheight = 14 + end + end + object stretch: tbooleanedit + frame.caption = '&stretch' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 48 + 2 + ) + bounds_x = 6 + bounds_y = 3 + bounds_cx = 61 + bounds_cy = 16 + statfile = statfile1 + value = True + end + end + object la1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 6 + bounds_y = 0 + bounds_cx = 308 + bounds_cy = 30 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + linkbottom = la2 + dist_bottom = 3 + object transparentcolor: tcoloredit + frame.caption = '&Transp.'#10'color' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.button.width = 13 + frame.button.color = -2147483646 + frame.buttons.count = 2 + frame.buttons.items = < + item + width = 13 + color = -2147483646 + end + item + width = 13 + color = -2147483646 + imagenr = 17 + end> + frame.buttonellipse.width = 13 + frame.buttonellipse.color = -2147483646 + frame.buttonellipse.imagenr = 17 + frame.outerframe = ( + 0 + 5 + 50 + 5 + ) + taborder = 1 + hint = 'Transparent color' + bounds_x = 69 + bounds_y = 0 + bounds_cx = 156 + bounds_cy = 30 + statfile = statfile1 + value = -2147483647 + reffontheight = 14 + end + object masked: tbooleanedit + frame.caption = '&masked' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 52 + 2 + ) + bounds_x = 0 + bounds_y = 8 + bounds_cx = 65 + bounds_cy = 16 + value = True + end + object versionnum: tenumedit + frame.caption = 'Vers.'#10'Nr.' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 5 + 35 + 5 + ) + taborder = 2 + hint = 'Current imagelist version number' + bounds_x = 229 + bounds_y = 0 + bounds_cx = 79 + bounds_cy = 30 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + ondataentered = versiondatentev + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + value = 0 + valuedefault = 0 + min = 0 + onsetvalue = versionsetev + reffontheight = 14 + end + end + end + object imagelist: timagelist + transparentcolor = -2147483647 + left = 24 + top = 176 + end + object filedialog: tfiledialog + statfile = statfile1 + left = 112 + top = 176 + end + object statfile1: tstatfile + filename = 'imagelisteditor.sta' + options = [sfo_memory] + onstatupdate = statupdateev + left = 200 + top = 176 + end + object popup: tpopupmenu + onupdate = updatemenuexe + menu.submenu.count = 2 + menu.submenu.items = < + item + caption = 'Copy Items' + state = [as_localcaption, as_localonexecute] + onexecute = copyexe + end + item + caption = 'Paste Items' + state = [as_localcaption, as_localonexecute] + onexecute = pasteexe + end> + left = 48 + top = 96 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseimagelisteditor.pas b/mseide-msegui/lib/common/designutils/mseimagelisteditor.pas new file mode 100644 index 0000000..8caed58 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimagelisteditor.pas @@ -0,0 +1,388 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseimagelisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msegui,mseglob,mseguiglob,msebitmap,msesimplewidgets,msegraphics, + mselistbrowser,msegrids,msefiledialog,msestat,msestatfile,msestrings, + msegraphedits,msecolordialog,msemenus,msesplitter,msegraphutils,msewidgets, + mseifiglob,msetypes,msedataedits,mseedit,msedatanodes,mseact,mseapplication, + mseificomp,mseificompglob,msestream,sysutils; + +const + imagelisteditorstatname = 'imagelisteditor.sta'; +type + timagelisteditorfo = class(tmseform) + disp: tlistview; + imagelist: timagelist; + filedialog: tfiledialog; + statfile1: tstatfile; + tlayouter1: tlayouter; + la2: tlayouter; + tlayouter2: tlayouter; + ok: tbutton; + cancel: tbutton; + clear: tbutton; + add: tbutton; + stretch: tbooleanedit; + la1: tlayouter; + transparentcolor: tcoloredit; + masked: tbooleanedit; + popup: tpopupmenu; + versionnum: tenumedit; + procedure addonexecute(const sender: tobject); + procedure clearonexecute(const sender: tobject); + procedure disponitemevent(const sender: tcustomlistview; const index: integer; + var info: celleventinfoty); + procedure disponitemsmoved(const sender: tcustomgrid; + const fromindex,toindex,count: integer); + +// procedure disponpaint(const sender: twidget; const canvas: tcanvas); + procedure layoutchanged(const sender: tcustomlistview); + procedure updatemenuexe(const sender: tcustommenu); + procedure pasteexe(const sender: TObject); + procedure copyexe(const sender: TObject); + procedure versionsetev(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure versiondatentev(const sender: TObject); + procedure createitemev(const sender: tcustomitemlist; + var item: tlistedititem); + procedure statupdateev(const sender: TObject; const filer: tstatfiler); + private + fcopyitems: integerarty; + procedure listchange(const sender: tobject); + procedure updateversion(); + function focuseditem: int32; + end; + +function editimagelist(aimagelist: timagelist): modalresultty; + +implementation +uses + mseimagelisteditor_mfm,mseformatstr,msegridsglob,mseactions, + msekeyboard,msefileutils,msegraphicstream; + +var + currentversion: int32; + +type + timageitem = class(tlistedititem) + public + procedure drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty) override; + end; + +function editimagelist(aimagelist: timagelist): modalresultty; +var + dialog: timagelisteditorfo; + i1: int32; +begin + dialog:= timagelisteditorfo.create(nil); + try + with dialog do begin + imagelist.onchange:= {$ifdef FPC}@{$endif}listchange; + imagelist.Assign(aimagelist); + for i1:= 0 to imagelist.versioncount - 1 do begin + versionnum.dropdown.cols.addrow([inttostrmse(i1)]); + end; + if (currentversion < 0) or + (currentversion >= imagelist.versioncount) then begin + currentversion:= 0; + end; + versionnum.value:= currentversion; +// imagelist.versioncurrent:= versionnum.value; + updateversion(); + + result:= show(true); + if result = mr_ok then begin + aimagelist.Assign(imagelist); + end; + end; + finally + dialog.destroy(); + end; +end; + +{ timagelisteditorfo } + +procedure timagelisteditorfo.addonexecute(const sender: tobject); +var + bmp: tmaskedbitmap; + ar1: filenamearty; + int1: integer; + i1: int32; +begin + filedialog.controller.filename:= filedialog.controller.lastdir; + filedialog.controller.filterlist.asarraya:= graphicfilefilternames; + filedialog.controller.filterlist.asarrayb:= graphicfilefiltermasks; + if filedialog.execute = mr_ok then begin + unquotefilename(filedialog.controller.filename,ar1); + bmp:= tmaskedbitmap.create(bmk_rgb); + try + i1:= focuseditem; + for int1:= 0 to high(ar1) do begin + bmp.transparentcolor:= cl_none; + bmp.loadfromfile(ar1[int1], + graphicformatlabels[filedialog.controller.filterindex],[]); + if not bmp.masked then begin + bmp.transparentcolor:= transparentcolor.value; + end; + bmp.masked:= masked.value; + if bmp.masked then begin + if bmp.colormask then begin + imagelist.colormask:= true; + end + else begin + if bmp.graymask and not imagelist.colormask then begin + imagelist.graymask:= true; + end; + end; + end; + if currentversion = 0 then begin + if stretch.value then begin + imagelist.addimage(bmp,[al_stretchx,al_stretchy,al_intpol]); + end + else begin + imagelist.addimage(bmp); + end; + end + else begin + if stretch.value then begin + imagelist.setimage(i1,bmp,[al_stretchx,al_stretchy,al_intpol], + currentversion); + end + else begin + imagelist.setimage(i1,bmp,[],currentversion); + end; + inc(i1); + if i1 >= imagelist.count then begin + i1:= 0; + end; + end; + end; + finally + bmp.Free; + end; + end; +end; + +procedure timagelisteditorfo.clearonexecute(const sender: tobject); +begin + imagelist.clear; +end; +{ +procedure timagelisteditorfo.disponpaint(const sender: twidget; + const canvas: tcanvas); +var + int1: integer; + dest: rectty; +begin + dest.pos:= nullpoint; + dest.size:= imagelist.size; + for int1:= 0 to fimagelist.count - 1 do begin + fimagelist.paint(canvas,dest,int1); + inc(dest.x,fimagelist.width); + if dest.x + dest.cx > disp.clientrect.cx then begin + dest.x:= 0; + inc(dest.y,fimagelist.height); + end; + end; +end; +} +procedure timagelisteditorfo.disponitemevent(const sender: tcustomlistview; + const index: integer; var info: celleventinfoty); +var + int1,int2: integer; + +begin + if info.eventkind = cek_keydown then begin + if (info.keyeventinfopo^.key = key_delete) and + (info.keyeventinfopo^.shiftstate * shiftstatesrepeatmask = []) then begin + if currentversion = 0 then begin + fcopyitems:= nil; + imagelist.beginupdate; + try + int2:= 0; + for int1:= 0 to disp.itemlist.count - 1 do begin + if ns_selected in disp.itemlist[int1].state then begin + imagelist.deleteimage(int2); + end + else begin + inc(int2); + end; + end; + with disp do begin + datacols.clearselection; + if focusedindex >= 0 then begin + items[focusedindex].selected:= true; + end; + end; + finally + imagelist.endupdate; + end; + end; + end + else begin + if issysshortcut(sho_copy,info.keyeventinfopo^) then begin + copyexe(nil); + end + else begin + if issysshortcut(sho_paste,info.keyeventinfopo^) then begin + pasteexe(nil); + end; + end; + end; + end; +end; + +procedure timagelisteditorfo.disponitemsmoved(const sender: tcustomgrid; + const fromindex,toindex,count: integer); +begin + imagelist.moveimage(fromindex,toindex,currentversion); + listchange(nil); +end; + +procedure timagelisteditorfo.listchange(const sender: tobject); +var + int1{,int2}: integer; +begin +// int2:= disp.itemlist.count; + fcopyitems:= nil; + disp.itemlist.count:= imagelist.count; + disp.beginupdate; + for int1:= 0 {int} to disp.itemlist.count - 1 do begin + with disp.itemlist[int1] do begin + caption:= inttostrmse(int1); + imagenr:= int1; + end; + end; + disp.endupdate; +end; + +procedure timagelisteditorfo.updateversion(); +begin + currentversion:= versionnum.value; + if currentversion = 0 then begin + clear.enabled:= true; + add.caption:= '&Add'; + end + else begin + clear.enabled:= false; + add.caption:= '&Replace'; + end; +end; + +function timagelisteditorfo.focuseditem: int32; +begin + result:= disp.focusedindex; + if result < 0 then begin + result:= 0; + end; +end; + +procedure timagelisteditorfo.layoutchanged(const sender: tcustomlistview); +begin + with sender do begin + itemlist.imagewidth:= cellwidth; + itemlist.imageheight:= cellheight - font.glyphheight; + end; +end; + +procedure timagelisteditorfo.updatemenuexe(const sender: tcustommenu); +begin + popup.menu[1].enabled:= fcopyitems <> nil; +end; + +procedure timagelisteditorfo.pasteexe(const sender: TObject); +var + insertid,copystart: int32; + i1,i2: int32; + bmp1: tmaskedbitmap; +begin + if fcopyitems <> nil then begin + bmp1:= tmaskedbitmap.create(imagelist.kind); + bmp1.maskkind:= imagelist.maskkind; + bmp1.masked:= imagelist.masked; + imagelist.beginupdate(); + insertid:= disp.focusedindex; + copystart:= imagelist.count; + if currentversion = 0 then begin + for i1:= 0 to high(fcopyitems) do begin + imagelist.getimage(fcopyitems[i1],bmp1); + imagelist.addimage(bmp1); + end; + for i1:= 0 to high(fcopyitems) do begin + imagelist.moveimage(copystart+i1,insertid+i1); + end; + end + else begin + i2:= focuseditem; + for i1:= 0 to high(fcopyitems) do begin + imagelist.getimage(fcopyitems[i1],bmp1,currentversion); + imagelist.setimage(i2,bmp1,[],currentversion); + inc(i2); + if i2 >= imagelist.count then begin + i2:= 0; + end; + end; + end; + imagelist.endupdate(); + bmp1.free; + end; +end; + +procedure timagelisteditorfo.copyexe(const sender: TObject); +begin + fcopyitems:= disp.getselectedindexes; +end; + +procedure timagelisteditorfo.versionsetev(const sender: TObject; + var avalue: Integer; var accept: Boolean); +begin + if avalue >= imagelist.versioncount then begin + avalue:= imagelist.versioncount -1; + end; + if avalue < 0 then begin + avalue:= 0; + end; +end; + +procedure timagelisteditorfo.versiondatentev(const sender: TObject); +begin + fcopyitems:= nil; + updateversion(); + disp.invalidate(); +end; + +procedure timagelisteditorfo.createitemev(const sender: tcustomitemlist; + var item: tlistedititem); +begin + item:= timageitem.create(sender); +end; + +procedure timagelisteditorfo.statupdateev(const sender: TObject; + const filer: tstatfiler); +begin + filer.updatevalue('currentversion',currentversion); +end; + +{ timageitem } + +procedure timageitem.drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty); +begin + alayoutinfo.variable.imageversion:= currentversion; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseimagelisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseimagelisteditor_mfm.pas new file mode 100644 index 0000000..39bba86 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimagelisteditor_mfm.pas @@ -0,0 +1,296 @@ +unit mseimagelisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseimagelisteditor; + +const + objdata: record size: integer; data: array[0..5571] of byte end = + (size: 5572; data: ( + 84,80,70,48,18,116,105,109,97,103,101,108,105,115,116,101,100,105,116,111, + 114,102,111,17,105,109,97,103,101,108,105,115,116,101,100,105,116,111,114,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110, + 116,111,110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,3,220,0,8,98,111,117,110,100,115,95,121,3,41,1,9,98,111, + 117,110,100,115,95,99,120,3,252,1,9,98,111,117,110,100,115,95,99,121, + 3,99,1,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117, + 115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101, + 114,46,98,111,117,110,100,115,1,2,0,2,0,3,252,1,3,99,1,0, + 7,111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110, + 101,115,99,17,102,111,95,108,111,99,97,108,115,104,111,114,116,99,117,116, + 115,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111, + 95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97, + 118,101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,7, + 99,97,112,116,105,111,110,6,16,73,109,97,103,101,108,105,115,116,32,69, + 100,105,116,111,114,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,9,116,108,105,115,116,118,105, + 101,119,4,100,105,115,112,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,9,112,111,112,117,112,109,101,110,117,7,5,112,111,112,117,112, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,3,252,1,9,98,111,117,110, + 100,115,95,99,121,3,37,1,7,97,110,99,104,111,114,115,11,6,97,110, + 95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,10,99,101,108,108, + 104,101,105,103,104,116,2,62,11,111,112,116,105,111,110,115,103,114,105,100, + 11,12,111,103,95,99,111,108,115,105,122,105,110,103,12,111,103,95,114,111, + 119,115,105,122,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108, + 111,110,101,110,116,101,114,10,111,103,95,119,114,97,112,114,111,119,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,0,7,111,112,116,105,111,110,115,11,12,108,118,111,95,114,101,97, + 100,111,110,108,121,15,108,118,111,95,109,111,117,115,101,109,111,118,105,110, + 103,13,108,118,111,95,107,101,121,109,111,118,105,110,103,8,108,118,111,95, + 104,111,114,122,13,108,118,111,95,100,114,97,119,102,111,99,117,115,15,108, + 118,111,95,102,111,99,117,115,115,101,108,101,99,116,15,108,118,111,95,109, + 111,117,115,101,115,101,108,101,99,116,13,108,118,111,95,107,101,121,115,101, + 108,101,99,116,15,108,118,111,95,109,117,108,116,105,115,101,108,101,99,116, + 10,108,118,111,95,108,111,99,97,116,101,0,21,105,116,101,109,108,105,115, + 116,46,111,110,99,114,101,97,116,101,105,116,101,109,7,12,99,114,101,97, + 116,101,105,116,101,109,101,118,19,105,116,101,109,108,105,115,116,46,99,97, + 112,116,105,111,110,112,111,115,7,9,99,112,95,98,111,116,116,111,109,18, + 105,116,101,109,108,105,115,116,46,105,109,97,103,101,108,105,115,116,7,9, + 105,109,97,103,101,108,105,115,116,19,105,116,101,109,108,105,115,116,46,105, + 109,97,103,101,119,105,100,116,104,2,16,20,105,116,101,109,108,105,115,116, + 46,105,109,97,103,101,104,101,105,103,104,116,2,16,15,111,110,108,97,121, + 111,117,116,99,104,97,110,103,101,100,7,13,108,97,121,111,117,116,99,104, + 97,110,103,101,100,11,111,110,105,116,101,109,101,118,101,110,116,7,15,100, + 105,115,112,111,110,105,116,101,109,101,118,101,110,116,12,111,110,105,116,101, + 109,115,109,111,118,101,100,7,16,100,105,115,112,111,110,105,116,101,109,115, + 109,111,118,101,100,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117, + 116,101,114,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11, + 111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110, + 116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,19,102,114,97,109,101,46,102,114,97,109,101,105, + 95,98,111,116,116,111,109,2,5,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,12,102,114,108,95,102,105,98,111,116,116,111,109, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,3,40,1,9,98,111,117,110, + 100,115,95,99,120,3,58,1,9,98,111,117,110,100,115,95,99,121,2,59, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110, + 95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108, + 101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115, + 104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111, + 115,99,95,115,104,114,105,110,107,121,0,7,108,105,110,107,116,111,112,7, + 4,100,105,115,112,8,100,105,115,116,95,116,111,112,2,3,7,111,112,116, + 105,111,110,115,11,15,115,112,97,111,95,103,108,117,101,98,111,116,116,111, + 109,0,0,9,116,108,97,121,111,117,116,101,114,3,108,97,50,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102, + 111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,33,9,98,111,117,110,100,115, + 95,99,120,3,41,1,9,98,111,117,110,100,115,95,99,121,2,21,12,111, + 112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112, + 97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99, + 95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121, + 0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111, + 95,97,108,105,103,110,121,0,8,100,105,115,116,95,116,111,112,2,4,0, + 9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114, + 50,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,80,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,217,0,9,98,111,117,110,100,115,95,99,121, + 2,21,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99, + 95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120, + 11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114, + 105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,112,108,97,99,101,120,0,13,112,108,97,99,101,95,109, + 105,110,100,105,115,116,2,5,13,112,108,97,99,101,95,109,97,120,100,105, + 115,116,2,5,8,100,105,115,116,95,116,111,112,2,3,0,7,116,98,117, + 116,116,111,110,2,111,107,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119, + 49,95,97,117,116,111,119,105,100,116,104,0,8,116,97,98,111,114,100,101, + 114,2,2,8,98,111,117,110,100,115,95,120,2,110,8,98,111,117,110,100, + 115,95,121,2,1,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111, + 117,110,100,115,95,99,121,2,20,12,98,111,117,110,100,115,95,99,120,109, + 105,110,2,50,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117, + 108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116, + 105,111,110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116, + 7,5,109,114,95,111,107,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49, + 95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119, + 105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,3,165,0,8,98,111,117,110,100,115,95,121,2,1,9, + 98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99, + 121,2,20,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11, + 109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99, + 101,108,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 7,116,98,117,116,116,111,110,5,99,108,101,97,114,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115, + 99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 55,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117, + 110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111, + 110,6,6,67,38,108,101,97,114,9,111,110,101,120,101,99,117,116,101,7, + 14,99,108,101,97,114,111,110,101,120,101,99,117,116,101,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111, + 110,3,97,100,100,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95, + 97,117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117, + 110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111, + 110,6,4,38,65,100,100,9,111,110,101,120,101,99,117,116,101,7,12,97, + 100,100,111,110,101,120,101,99,117,116,101,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,7,115,116,114,101,116,99,104,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,8,38,115,116,114,101,116,99,104,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,48,2,2, + 0,8,98,111,117,110,100,115,95,120,2,6,8,98,111,117,110,100,115,95, + 121,2,3,9,98,111,117,110,100,115,95,99,120,2,61,9,98,111,117,110, + 100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,9,115,116, + 97,116,102,105,108,101,49,5,118,97,108,117,101,9,0,0,0,9,116,108, + 97,121,111,117,116,101,114,3,108,97,49,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111, + 119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,98,111,117,110,100, + 115,95,120,2,6,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,52,1,9,98,111,117,110,100,115,95,99,121,2, + 30,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95, + 101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11, + 111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105, + 110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10, + 108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105,103,110, + 121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95,115, + 116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116,2,4, + 13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,4,10,108,105,110, + 107,98,111,116,116,111,109,7,3,108,97,50,11,100,105,115,116,95,98,111, + 116,116,111,109,2,3,0,10,116,99,111,108,111,114,101,100,105,116,16,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,14,38,84,114,97,110,115,112,46,10, + 99,111,108,111,114,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,18,102,114,97,109,101,46,98,117, + 116,116,111,110,46,119,105,100,116,104,2,13,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1, + 5,119,105,100,116,104,2,13,5,99,111,108,111,114,4,2,0,0,128,0, + 1,5,119,105,100,116,104,2,13,5,99,111,108,111,114,4,2,0,0,128, + 7,105,109,97,103,101,110,114,2,17,0,0,25,102,114,97,109,101,46,98, + 117,116,116,111,110,101,108,108,105,112,115,101,46,119,105,100,116,104,2,13, + 25,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101, + 46,99,111,108,111,114,4,2,0,0,128,27,102,114,97,109,101,46,98,117, + 116,116,111,110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2, + 17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,5,2,50,2,5,0,8,116,97,98,111,114,100,101,114,2,1,4, + 104,105,110,116,6,17,84,114,97,110,115,112,97,114,101,110,116,32,99,111, + 108,111,114,8,98,111,117,110,100,115,95,120,2,69,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,156,0,9,98, + 111,117,110,100,115,95,99,121,2,30,8,115,116,97,116,102,105,108,101,7, + 9,115,116,97,116,102,105,108,101,49,5,118,97,108,117,101,4,1,0,0, + 128,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,6,109,97,115,107,101,100,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,7,38,109,97,115,107, + 101,100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,1,2,52,2,2,0,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100,115,95,99,120, + 2,65,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101, + 9,0,0,9,116,101,110,117,109,101,100,105,116,10,118,101,114,115,105,111, + 110,110,117,109,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,9, + 86,101,114,115,46,10,78,114,46,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,0, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,5,2,35,2,5,0,8,116,97,98,111,114,100,101,114,2,2,4, + 104,105,110,116,6,32,67,117,114,114,101,110,116,32,105,109,97,103,101,108, + 105,115,116,32,118,101,114,115,105,111,110,32,110,117,109,98,101,114,8,98, + 111,117,110,100,115,95,120,3,229,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,79,9,98,111,117,110,100,115, + 95,99,121,2,30,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,15,118,101,114, + 115,105,111,110,100,97,116,101,110,116,101,118,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,5,118, + 97,108,117,101,2,0,12,118,97,108,117,101,100,101,102,97,117,108,116,2, + 0,3,109,105,110,2,0,10,111,110,115,101,116,118,97,108,117,101,7,12, + 118,101,114,115,105,111,110,115,101,116,101,118,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,0,10,116,105,109,97,103,101,108, + 105,115,116,9,105,109,97,103,101,108,105,115,116,16,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,1,0,0,128,4,108,101,102,116, + 2,24,3,116,111,112,3,176,0,0,0,11,116,102,105,108,101,100,105,97, + 108,111,103,10,102,105,108,101,100,105,97,108,111,103,8,115,116,97,116,102, + 105,108,101,7,9,115,116,97,116,102,105,108,101,49,4,108,101,102,116,2, + 112,3,116,111,112,3,176,0,0,0,9,116,115,116,97,116,102,105,108,101, + 9,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6, + 19,105,109,97,103,101,108,105,115,116,101,100,105,116,111,114,46,115,116,97, + 7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121, + 0,12,111,110,115,116,97,116,117,112,100,97,116,101,7,12,115,116,97,116, + 117,112,100,97,116,101,101,118,4,108,101,102,116,3,200,0,3,116,111,112, + 3,176,0,0,0,10,116,112,111,112,117,112,109,101,110,117,5,112,111,112, + 117,112,8,111,110,117,112,100,97,116,101,7,13,117,112,100,97,116,101,109, + 101,110,117,101,120,101,18,109,101,110,117,46,115,117,98,109,101,110,117,46, + 99,111,117,110,116,2,2,18,109,101,110,117,46,115,117,98,109,101,110,117, + 46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,10,67,111, + 112,121,32,73,116,101,109,115,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,7,99,111,112,121,101,120,101,0,1,7,99,97,112,116,105,111,110,6, + 11,80,97,115,116,101,32,73,116,101,109,115,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101, + 99,117,116,101,7,8,112,97,115,116,101,101,120,101,0,0,4,108,101,102, + 116,2,48,3,116,111,112,2,96,0,0,0) + ); + +initialization + registerobjectdata(@objdata,timagelisteditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseimageselectorform.mfm b/mseide-msegui/lib/common/designutils/mseimageselectorform.mfm new file mode 100644 index 0000000..a89bd7f --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimageselectorform.mfm @@ -0,0 +1,35 @@ +object imageselectorfo: timageselectorfo + visible = False + bounds_x = 126 + bounds_y = 231 + bounds_cx = 320 + bounds_cy = 244 + container.bounds = ( + 0 + 0 + 320 + 244 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Image Selector' + moduleclassname = 'tmseform' + object lv: tlistview + bounds_x = 0 + bounds_y = 0 + bounds_cx = 320 + bounds_cy = 244 + anchors = [] + cellheight = 16 + options = [lvo_readonly, lvo_horz, lvo_drawfocus, lvo_leftbuttonfocusonly, lvo_focusselect, lvo_mouseselect] + itemlist.captionpos = cp_bottom + onitemevent = itemev + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'imageselector.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 72 + top = 48 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseimageselectorform.pas b/mseide-msegui/lib/common/designutils/mseimageselectorform.pas new file mode 100644 index 0000000..2c3ef01 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimageselectorform.pas @@ -0,0 +1,90 @@ +{ MSEide Copyright (c) 1999-2015 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit mseimageselectorform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msedataedits,msedatanodes,mseedit, + msegrids,mselistbrowser,msestrings,msetypes,msebitmap,msestatfile; +type + timageselectorfo = class(tmseform) + lv: tlistview; + tstatfile1: tstatfile; + procedure itemev(const sender: tcustomlistview; const index: Integer; + var info: celleventinfoty); + private + fimagelist: timagelist; + fimagenr: integer; + public + constructor create(const aowner: tcomponent; const aimagelist: timagelist; + var aimagenr: integer); reintroduce; + end; +implementation +uses + mseimageselectorform_mfm,sysutils,mseformatstr; + +{ timageselectorfo } + +constructor timageselectorfo.create(const aowner: tcomponent; + const aimagelist: timagelist; var aimagenr: integer); +var + int1,i2: integer; +begin + if aimagelist <> nil then begin + fimagelist:= aimagelist; + fimagenr:= aimagenr; + inherited create(aowner); + with lv do begin + int1:= aimagelist.width + 2; + i2:= getcanvas().getstringwidth('999')+2; + if int1 < i2 then begin + int1:= i2; + end; + cellwidth:= int1; + cellheight:= aimagelist.height + font.lineheight + 3; + end; + with lv.itemlist do begin + imagelist:= aimagelist; + count:= aimagelist.count; + imagewidth:= aimagelist.width; + imageheight:= aimagelist.height+2; + for int1:= 0 to count -1 do begin + with items[int1] do begin + imagenr:= int1; + caption:= inttostrmse(int1); + end; + end; + end; + lv.focusedindex:= fimagenr; + show(true); + aimagenr:= fimagenr; + end; + release; +end; + +procedure timageselectorfo.itemev(const sender: tcustomlistview; + const index: Integer; var info: celleventinfoty); +begin + if iscellclick(info) then begin + fimagenr:= index; + window.modalresult:= mr_ok; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseimageselectorform_mfm.pas b/mseide-msegui/lib/common/designutils/mseimageselectorform_mfm.pas new file mode 100644 index 0000000..0d6b305 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimageselectorform_mfm.pas @@ -0,0 +1,52 @@ +unit mseimageselectorform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseimageselectorform; + +const + objdata: record size: integer; data: array[0..686] of byte end = + (size: 687; data: ( + 84,80,70,48,16,116,105,109,97,103,101,115,101,108,101,99,116,111,114,102, + 111,15,105,109,97,103,101,115,101,108,101,99,116,111,114,102,111,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,126,8,98,111, + 117,110,100,115,95,121,3,231,0,9,98,111,117,110,100,115,95,99,120,3, + 64,1,9,98,111,117,110,100,115,95,99,121,3,244,0,16,99,111,110,116, + 97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,64,1, + 3,244,0,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114, + 101,101,110,99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101, + 111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97, + 116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102, + 111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114, + 100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99, + 97,112,116,105,111,110,6,14,73,109,97,103,101,32,83,101,108,101,99,116, + 111,114,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8, + 116,109,115,101,102,111,114,109,0,9,116,108,105,115,116,118,105,101,119,2, + 108,118,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,64,1,9,98,111, + 117,110,100,115,95,99,121,3,244,0,7,97,110,99,104,111,114,115,11,0, + 10,99,101,108,108,104,101,105,103,104,116,2,16,7,111,112,116,105,111,110, + 115,11,12,108,118,111,95,114,101,97,100,111,110,108,121,8,108,118,111,95, + 104,111,114,122,13,108,118,111,95,100,114,97,119,102,111,99,117,115,23,108, + 118,111,95,108,101,102,116,98,117,116,116,111,110,102,111,99,117,115,111,110, + 108,121,15,108,118,111,95,102,111,99,117,115,115,101,108,101,99,116,15,108, + 118,111,95,109,111,117,115,101,115,101,108,101,99,116,0,19,105,116,101,109, + 108,105,115,116,46,99,97,112,116,105,111,110,112,111,115,7,9,99,112,95, + 98,111,116,116,111,109,11,111,110,105,116,101,109,101,118,101,110,116,7,6, + 105,116,101,109,101,118,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116, + 102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,17,105,109,97,103, + 101,115,101,108,101,99,116,111,114,46,115,116,97,7,111,112,116,105,111,110, + 115,11,10,115,102,111,95,109,101,109,111,114,121,17,115,102,111,95,97,99, + 116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95,97,99,116,105, + 118,97,116,111,114,119,114,105,116,101,0,4,108,101,102,116,2,72,3,116, + 111,112,2,48,0,0,0) + ); + +initialization + registerobjectdata(@objdata,timageselectorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseindexlookupeditor.mfm b/mseide-msegui/lib/common/designutils/mseindexlookupeditor.mfm new file mode 100644 index 0000000..23d03fd --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseindexlookupeditor.mfm @@ -0,0 +1,161 @@ +object mseindexlookupeditorfo: tmseindexlookupeditorfo + bounds_x = 337 + bounds_y = 266 + bounds_cx = 383 + bounds_cy = 334 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 383 + 334 + ) + options = [fo_freeonclose, fo_createmodal, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = statfile1 + caption = 'Indexlookup Editor' + oncreate = createexe + onclosequery = closequexe + moduleclassname = 'tmseform' + object tsplitter1: tsplitter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + bounds_x = 258 + bounds_y = 293 + bounds_cx = 123 + bounds_cy = 32 + anchors = [an_right, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = grid + grip = stb_none + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 58 + bounds_y = 10 + bounds_cx = 52 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 0 + bounds_y = 10 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object tspacer2: tspacer + taborder = 2 + bounds_x = 50 + bounds_y = 10 + bounds_cx = 8 + bounds_cy = 20 + linkleft = tbutton1 + linkright = tbutton2 + options = [spao_glueright] + end + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 383 + bounds_cy = 293 + anchors = [an_top] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 1 + captions.items = < + item + caption = 'Index' + end> + end> + datacols.count = 3 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[indexed] + width = 77 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow, co_rowdatachange] + name = 'index' + widgetname = 'indexed' + dataclass = tgridintegerdatalist + end + item[icondi] + width = 21 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'icondi' + dataclass = tgridintegerdatalist + end + item[tstockglyphdatabutton1] + color = -2147483646 + width = 18 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'tstockglyphdatabutton1' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + onrowdatachanged = rowdatacha + reffontheight = 14 + object indexed: tintegeredit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 77 + bounds_cy = 16 + min = -2147483648 + reffontheight = 14 + end + object icondi: tdataicon + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 78 + bounds_y = 0 + bounds_cx = 21 + bounds_cy = 16 + visible = False + onpaintglyph = iconpaintexe + end + object tstockglyphdatabutton1: tstockglyphdatabutton + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 100 + bounds_y = 0 + bounds_cx = 18 + bounds_cy = 16 + state = [as_invisible, as_localinvisible, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_ellipsesmall + onexecute = selectexe + end + end + object statfile1: tstatfile + filename = 'indexlookup.sta' + options = [sfo_memory] + left = 80 + top = 112 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseindexlookupeditor.pas b/mseide-msegui/lib/common/designutils/mseindexlookupeditor.pas new file mode 100644 index 0000000..d573a02 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseindexlookupeditor.pas @@ -0,0 +1,131 @@ +unit mseindexlookupeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msesplitter, + msesimplewidgets,msedataedits,mseedit,mseificomp,mseificompglob,mseifiglob, + msestatfile,msestream,msestrings,sysutils,msegrids,msewidgetgrid,msegraphedits, + msescrollbar,msebitmap; +type + tmseindexlookupeditorfo = class(tmseform) + tsplitter1: tsplitter; + tbutton2: tbutton; + tbutton1: tbutton; + tspacer2: tspacer; + grid: twidgetgrid; + indexed: tintegeredit; + tstockglyphdatabutton1: tstockglyphdatabutton; + icondi: tdataicon; + statfile1: tstatfile; + procedure rowdatacha(const sender: tcustomgrid; const acell: gridcoordty); + procedure createexe(const sender: TObject); + procedure closequexe(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure selectexe(const sender: TObject); + procedure iconpaintexe(const sender: tcustomintegergraphdataedit; + const acanvas: tcanvas; const avalue: Integer; + const arow: Integer); + protected + findexlist: pmsestring; + fimagelist: timagelist; + ffacelist: tfacelist; + fok: pboolean; + public + constructor create(var indexlist: msestring; const imagelist: timagelist; + const facelist: tfacelist; out ok: boolean); + end; + +function editlookupindex(var indexlist: msestring; const imagelist: timagelist; + const facelist: tfacelist): boolean; + +implementation +uses + mseindexlookupeditor_mfm,mseimageselectorform,msefaceselectorform; + +function editlookupindex(var indexlist: msestring; + const imagelist: timagelist; const facelist: tfacelist): boolean; +begin + tmseindexlookupeditorfo.create(indexlist,imagelist,facelist,result); +end; + +{ tmseindexlookupeditorfo } + +constructor tmseindexlookupeditorfo.create(var indexlist: msestring; + const imagelist: timagelist; const facelist: tfacelist; + out ok: boolean); +begin + findexlist:= @indexlist; + fimagelist:= imagelist; + ffacelist:= facelist; + fok:= @ok; + inherited create(nil); +end; + +procedure tmseindexlookupeditorfo.rowdatacha(const sender: tcustomgrid; + const acell: gridcoordty); +begin + icondi[acell.row]:= indexed[acell.row]; +end; + +procedure tmseindexlookupeditorfo.createexe(const sender: TObject); +var + i1: int32; + po1: pint16; +begin + grid.beginupdate(); + icondi.imagelist:= fimagelist; + if fimagelist = nil then begin + grid[1].visible:= false; + grid[2].visible:= false; + end; + grid.rowcount:= length(findexlist^); + po1:= pointer(findexlist^); + for i1:= 0 to grid.rowhigh do begin + indexed[i1]:= po1[i1]; + end; + grid.endupdate(); +end; + +procedure tmseindexlookupeditorfo.closequexe(const sender: tcustommseform; + var amodalresult: modalresultty); +var + i1: int32; + po1: pint16; +begin + fok^:= amodalresult = mr_ok; + if fok^ then begin + setlength(findexlist^,grid.rowcount); + po1:= pointer(findexlist^); + for i1:= 0 to grid.rowhigh do begin + po1[i1]:= indexed[i1]; + end; + end; +end; + +procedure tmseindexlookupeditorfo.selectexe(const sender: TObject); +var + i1: int32; +begin + i1:= indexed.value; + if fimagelist <> nil then begin + timageselectorfo.create(nil,fimagelist,i1); + end + else begin + if ffacelist <> nil then begin + tfaceselectorfo.create(nil,ffacelist,i1); + end; + end; + indexed.value:= i1; +end; + +procedure tmseindexlookupeditorfo.iconpaintexe( + const sender: tcustomintegergraphdataedit; const acanvas: tcanvas; + const avalue: Integer; const arow: Integer); +begin + if ffacelist <> nil then begin + ffacelist.paint(acanvas,avalue,sender.clientrect); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseindexlookupeditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseindexlookupeditor_mfm.pas new file mode 100644 index 0000000..36d5d84 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseindexlookupeditor_mfm.pas @@ -0,0 +1,193 @@ +unit mseindexlookupeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseindexlookupeditor; + +const + objdata: record size: integer; data: array[0..3506] of byte end = + (size: 3507; data: ( + 84,80,70,48,23,116,109,115,101,105,110,100,101,120,108,111,111,107,117,112, + 101,100,105,116,111,114,102,111,22,109,115,101,105,110,100,101,120,108,111,111, + 107,117,112,101,100,105,116,111,114,102,111,8,98,111,117,110,100,115,95,120, + 3,81,1,8,98,111,117,110,100,115,95,121,3,10,1,9,98,111,117,110, + 100,115,95,99,120,3,127,1,9,98,111,117,110,100,115,95,99,121,3,78, + 1,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0, + 2,0,3,127,1,3,78,1,0,7,111,112,116,105,111,110,115,11,14,102, + 111,95,102,114,101,101,111,110,99,108,111,115,101,14,102,111,95,99,114,101, + 97,116,101,109,111,100,97,108,15,102,111,95,97,117,116,111,114,101,97,100, + 115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97, + 116,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101, + 122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0, + 8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49, + 7,99,97,112,116,105,111,110,6,18,73,110,100,101,120,108,111,111,107,117, + 112,32,69,100,105,116,111,114,8,111,110,99,114,101,97,116,101,7,9,99, + 114,101,97,116,101,101,120,101,12,111,110,99,108,111,115,101,113,117,101,114, + 121,7,10,99,108,111,115,101,113,117,101,120,101,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0, + 9,116,115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116,101,114, + 49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,8,98,111,117,110, + 100,115,95,120,3,2,1,8,98,111,117,110,100,115,95,121,3,37,1,9, + 98,111,117,110,100,115,95,99,120,2,123,9,98,111,117,110,100,115,95,99, + 121,2,32,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104, + 116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115, + 115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111, + 115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110, + 100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,7,108,105,110,107, + 116,111,112,7,4,103,114,105,100,4,103,114,105,112,7,8,115,116,98,95, + 110,111,110,101,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111, + 110,50,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111, + 119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116, + 111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,58,8,98,111,117,110,100,115,95,121,2,10, + 9,98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95, + 99,121,2,22,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38, + 67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9, + 109,114,95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116, + 116,111,110,49,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97, + 117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,10,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,12,98,111,117,110, + 100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97, + 116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75, + 11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,115, + 112,97,99,101,114,8,116,115,112,97,99,101,114,50,8,116,97,98,111,114, + 100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,50,8,98,111,117, + 110,100,115,95,121,2,10,9,98,111,117,110,100,115,95,99,120,2,8,9, + 98,111,117,110,100,115,95,99,121,2,20,8,108,105,110,107,108,101,102,116, + 7,8,116,98,117,116,116,111,110,49,9,108,105,110,107,114,105,103,104,116, + 7,8,116,98,117,116,116,111,110,50,7,111,112,116,105,111,110,115,11,14, + 115,112,97,111,95,103,108,117,101,114,105,103,104,116,0,0,0,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,127,1, + 9,98,111,117,110,100,115,95,99,121,3,37,1,7,97,110,99,104,111,114, + 115,11,6,97,110,95,116,111,112,0,11,111,112,116,105,111,110,115,103,114, + 105,100,11,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95, + 107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105, + 110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116, + 105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119,115,100, + 101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108, + 111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116, + 114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103, + 95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108, + 0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105, + 120,99,111,108,115,46,105,116,101,109,115,14,1,7,110,117,109,115,116,101, + 112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,1,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,5,73,110,100,101,120,0,0,0,0,14, + 100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,3,16,100,97,116, + 97,99,111,108,115,46,111,112,116,105,111,110,115,11,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46, + 105,116,101,109,115,14,7,7,105,110,100,101,120,101,100,1,5,119,105,100, + 116,104,2,77,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,16,99,111,95,114,111,119,100,97, + 116,97,99,104,97,110,103,101,0,4,110,97,109,101,6,5,105,110,100,101, + 120,10,119,105,100,103,101,116,110,97,109,101,6,7,105,110,100,101,120,101, + 100,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110, + 116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,6,105,99,111,110, + 100,105,1,5,119,105,100,116,104,2,21,7,111,112,116,105,111,110,115,11, + 12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101, + 6,6,105,99,111,110,100,105,9,100,97,116,97,99,108,97,115,115,7,20, + 116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116, + 0,7,22,116,115,116,111,99,107,103,108,121,112,104,100,97,116,97,98,117, + 116,116,111,110,49,1,5,99,111,108,111,114,4,2,0,0,128,5,119,105, + 100,116,104,2,18,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,22,116,115,116,111,99,107,103,108,121,112,104,100,97,116,97,98,117, + 116,116,111,110,49,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,0,13, + 100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,16,111,110,114,111, + 119,100,97,116,97,99,104,97,110,103,101,100,7,10,114,111,119,100,97,116, + 97,99,104,97,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,7,105,110,100,101,120, + 101,100,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98, + 111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,77,9,98,111,117,110,100,115,95,99,121, + 2,16,3,109,105,110,4,0,0,0,128,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,9,116,100,97,116,97,105,99,111,110,6, + 105,99,111,110,100,105,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,78,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,21,9,98,111,117,110,100,115,95,99,121,2,16,7,118,105,115,105,98, + 108,101,8,12,111,110,112,97,105,110,116,103,108,121,112,104,7,12,105,99, + 111,110,112,97,105,110,116,101,120,101,0,0,21,116,115,116,111,99,107,103, + 108,121,112,104,100,97,116,97,98,117,116,116,111,110,22,116,115,116,111,99, + 107,103,108,121,112,104,100,97,116,97,98,117,116,116,111,110,49,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,0,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,2,100,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,18,9,98,111,117,110,100,115, + 95,99,121,2,16,5,115,116,97,116,101,11,12,97,115,95,105,110,118,105, + 115,105,98,108,101,17,97,115,95,108,111,99,97,108,105,110,118,105,115,105, + 98,108,101,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115, + 116,15,97,115,95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121, + 112,104,7,16,115,116,103,95,101,108,108,105,112,115,101,115,109,97,108,108, + 9,111,110,101,120,101,99,117,116,101,7,9,115,101,108,101,99,116,101,120, + 101,0,0,0,9,116,115,116,97,116,102,105,108,101,9,115,116,97,116,102, + 105,108,101,49,8,102,105,108,101,110,97,109,101,6,15,105,110,100,101,120, + 108,111,111,107,117,112,46,115,116,97,7,111,112,116,105,111,110,115,11,10, + 115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116,2,80,3,116, + 111,112,2,112,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmseindexlookupeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseintegerlisteditor.mfm b/mseide-msegui/lib/common/designutils/mseintegerlisteditor.mfm new file mode 100644 index 0000000..73846e2 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseintegerlisteditor.mfm @@ -0,0 +1,106 @@ +object integerlisteditor: tintegerlisteditor + visible = False + bounds_x = 182 + bounds_y = 208 + bounds_cx = 133 + bounds_cy = 298 + container.bounds = ( + 0 + 0 + 133 + 298 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = tstatfile1 + caption = 'Integerlisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + taborder = 3 + bounds_x = 4 + bounds_y = 270 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + bounds_x = 68 + bounds_y = 270 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object grid: twidgetgrid + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 133 + bounds_cy = 242 + anchors = [an_top, an_bottom] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstep = 1 + end> + zebra_start = 1 + zebra_height = 1 + datacols.count = 1 + datacols.items = < + item[valueedit] + width = 103 + options = [co_fill, co_savevalue, co_savestate] + widgetname = 'valueedit' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object valueedit: tintegeredit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.dummy = 0 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 103 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + max = -1 + reffontheight = 14 + end + end + object rowcount: tintegeredit + frame.caption = 'Rowcount' + frame.captionpos = cp_right + frame.dummy = 0 + frame.outerframe = ( + 0 + 0 + 64 + 0 + ) + taborder = 2 + bounds_x = 4 + bounds_y = 246 + bounds_cx = 116 + anchors = [an_left, an_bottom] + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'stringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseintegerlisteditor.pas b/mseide-msegui/lib/common/designutils/mseintegerlisteditor.pas new file mode 100644 index 0000000..cb336a3 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseintegerlisteditor.pas @@ -0,0 +1,61 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseintegerlisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,msetextedit, + msestat,msestatfile; + +const + integerlisteditorstatname = 'integerlisteditor.sta'; + +type + tintegerlisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + rowcount: tintegeredit; + valueedit: tintegeredit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + mseintegerlisteditor_mfm; + +{ tintegerlisteditor } + +constructor tintegerlisteditor.create(const aonclosequery: closequeryeventty); +begin + inherited create(nil); + onclosequery:= aonclosequery; +end; + +procedure tintegerlisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure tintegerlisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseintegerlisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseintegerlisteditor_mfm.pas new file mode 100644 index 0000000..37be381 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseintegerlisteditor_mfm.pas @@ -0,0 +1,105 @@ +unit mseintegerlisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseintegerlisteditor; + +const + objdata: record size: integer; data: array[0..1755] of byte end = + (size: 1756; data: ( + 84,80,70,48,18,116,105,110,116,101,103,101,114,108,105,115,116,101,100,105, + 116,111,114,17,105,110,116,101,103,101,114,108,105,115,116,101,100,105,116,111, + 114,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3, + 182,0,8,98,111,117,110,100,115,95,121,3,208,0,9,98,111,117,110,100, + 115,95,99,120,3,133,0,9,98,111,117,110,100,115,95,99,121,3,42,1, + 16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0, + 2,0,3,133,0,3,42,1,0,7,111,112,116,105,111,110,115,11,13,102, + 111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111, + 114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116, + 101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,0,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99, + 97,112,116,105,111,110,6,17,73,110,116,101,103,101,114,108,105,115,116,101, + 100,105,116,111,114,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110, + 2,111,107,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,2,4,8,98,111,117,110,100,115,95,121,3,14,1,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97, + 110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97,115,95, + 100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97, + 117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0, + 7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97,108,114, + 101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117,116,116, + 111,110,6,99,97,110,99,101,108,8,98,111,117,110,100,115,95,120,2,68, + 8,98,111,117,110,100,115,95,121,3,14,1,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99, + 104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116, + 116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67, + 97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109, + 114,95,99,97,110,99,101,108,0,0,11,116,119,105,100,103,101,116,103,114, + 105,100,4,103,114,105,100,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,133,0,9,98,111,117,110,100,115, + 95,99,121,3,242,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110, + 115,103,114,105,100,11,12,111,103,95,114,111,119,109,111,118,105,110,103,15, + 111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114, + 111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101, + 108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111, + 110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114, + 111,119,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46,99,111,117,110, + 116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5, + 119,105,100,116,104,2,24,7,110,117,109,115,116,101,112,2,1,0,0,11, + 122,101,98,114,97,95,115,116,97,114,116,2,1,12,122,101,98,114,97,95, + 104,101,105,103,104,116,2,1,14,100,97,116,97,99,111,108,115,46,99,111, + 117,110,116,2,1,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115, + 14,7,9,118,97,108,117,101,101,100,105,116,1,5,119,105,100,116,104,2, + 103,7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99, + 111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115, + 116,97,116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,9,118,97, + 108,117,101,101,100,105,116,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,17,111,110, + 114,111,119,99,111,117,110,116,99,104,97,110,103,101,100,7,21,103,114,105, + 100,111,110,114,111,119,99,111,117,110,116,99,104,97,110,103,101,100,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,9,118,97,108,117,101,101,100,105,116,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,11,102,114,97, + 109,101,46,100,117,109,109,121,2,0,8,116,97,98,111,114,100,101,114,2, + 1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,103,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,0,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,8,114,111,119,99,111,117,110,116,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,8,82,111,119,99,111,117,110,116,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 64,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110, + 100,115,95,120,2,4,8,98,111,117,110,100,115,95,121,3,246,0,9,98, + 111,117,110,100,115,95,99,120,2,116,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,10,111, + 110,115,101,116,118,97,108,117,101,7,18,114,111,119,99,111,117,110,116,111, + 110,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115, + 116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,20,115, + 116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,46,115,116,97,7, + 111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0, + 4,108,101,102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tintegerlisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseparser.pas b/mseide-msegui/lib/common/designutils/mseparser.pas new file mode 100644 index 0000000..5e52546 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseparser.pas @@ -0,0 +1,2734 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseparser; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + Classes,msetypes,msestrings,msestream,mselist,msehash,mseglob; + +const + maxincludelevel = 32; + +type + + operatorty = (op_unknown); + tokenkindty = (tk_operator,tk_whitespace,tk_name,tk_number,tk_newline, + tk_fileend,tk_include); + + sourceposty = record + filenum: integer; //0 -> sourcepos empty + offset: integer; //byteoffset in file + filename: nameidty; + line: integer; //absolute linenr + pos: gridcoordty; + end; + psourceposty = ^sourceposty; + + tsourceposlist = class(trecordlist) + private + function getitems(const index: integer): psourceposty; + protected +// procedure copyrecord(var item); override; +// procedure finalizerecord(var item); override; + public + constructor create; + function add(const source: sourceposty): integer; + property items[const index: integer]: psourceposty read getitems; + end; + tokenstatety = (tos_linestart,tos_firstofline); + tokenstatesty = set of tokenstatety; + tokenty = record + value: lstringty; + state: tokenstatesty; + case kind: tokenkindty of + tk_operator: (op: char); + tk_newline: (linenr: integer); + tk_include: (filenr: integer); + end; + ptokenty = ^tokenty; + tokenarty = array of tokenty; + { + tokensequencety = record + token: ptokenty; + count: integer; + index: integer; + end; + } + charsetty = set of char; + tscanner = class + private + ftokens: tokenarty; + ftokencount: integer; + fsource: ansistring; //uppercase + fsourceorig: ansistring; + fpo: pchar; + fscto: ptokenty; + flinenr: integer; + fescapechar: char; + fcasesensitive: boolean; + forigoffset: integer; + ffilename: filenamety; //for check of recursive includefiles + ffileid: nameidty; + fstartline: integer; + fcount: integer; + fincludecount: integer; + flinestart: boolean; + ffirstofline: boolean; + procedure updatecase; + procedure setsource(const Value: ansistring); + procedure clear; + procedure scan; + procedure setcasesensitive(const Value: boolean); + protected + procedure scantoken; + procedure newtoken(akind: tokenkindty); + procedure endtoken; + public + constructor create; overload; virtual; + constructor create(const afilename: filenamety; + const filelist: tmseindexednamelist); overload; + procedure setfilename(const aname: filenamety; + const filelist: tmseindexednamelist); + property origoffset: integer read forigoffset; + property filename: filenamety read ffilename; + property fileid: nameidty read ffileid; + property startline: integer read fstartline; + property count: integer read fcount; + property includecount: integer read fincludecount; + property source: ansistring read fsource write setsource; + property escapechar: char read fescapechar write fescapechar; + //for newline escape + property casesensitive: boolean read fcasesensitive write setcasesensitive; + end; + + tpascalscanner = class(tscanner) + public + constructor create; override; + end; + + tcscanner = class(tscanner) + public + constructor create; override; + end; + +const + identmaxlen = 30; + {$define nohash} //first char of ident is hash value + {$ifdef nohash} + identbucketcount = 128; + {$else} + identbucketcount = 256; + {$endif} +type + identstringty = string[identmaxlen+1]; //terminated with #0 + identinfoty = record + name: identstringty; + ident: integer; + end; + pidentinfoty = ^identinfoty; + identinfoarty = array of identinfoty; + + valuekindty = (vk_none,vk_integer,vk_real,vk_string); + + tokenidty = record + scanner: longword; + token: longword; + end; + tokenidarty = array of tokenidty; + + filestackinfoty = record + tokenid: tokenidty; + lineoffset: integer; + end; + filestackinfoarty = array of filestackinfoty; + + scannerarty = array of tscanner; + + tparser = class; + + getincludefileeventty = procedure(const sender: tparser; + const scanner: tscanner) of object; + scannerclassty = class of tscanner; + +// tdefineslist = class(thashedstrings); + tdefineslist = class(tansistringhashdatalist); + defstatety = (def_none,def_skip); + + tparser = class (tnullinterfacedobject) + private + fcasesensitive: boolean; + fscanner: tscanner; + fownsscanner: boolean; + fscannernum: longword; + ftokennum: longword; + fidents: array[0..identbucketcount-1] of identinfoarty; + ffilestack: filestackinfoarty; + ftokenstack: tokenidarty; + ftokenstackcount: integer; + frecursivecomment: boolean; + flastvalidident: integer; + fincludefiledirs: filenamearty; + fongetincludefile: getincludefileeventty; + feof: boolean; + ffilelist: tmseindexednamelist; + //false if root + fdefines: tdefineslist; + fdefstate: defstatety; + fdefstates: integerarty; + fdefstatecount: integer; + fstartdefines: stringarty; + function getacttoken: tokenidty; + procedure setacttokennum(anum: longword); + procedure setacttoken(const atoken: tokenidty); + procedure enterinclude(anum: longword); + function exitinclude: boolean; + protected + fscanners: scannerarty; + fsyntaxerrorcount: integer; + fto: ptokenty; + function getscanner: tscanner; + procedure setscanner(const Value: tscanner); + procedure internalerror; + procedure syntaxerror; + function getscannerclass: scannerclassty; virtual; + + public + constructor create; overload; + constructor create(const afilelist: tmseindexednamelist); overload; virtual; + constructor create(const afilelist: tmseindexednamelist; const atext: string); overload; + destructor destroy; override; + + procedure reset; + procedure clear; virtual; + procedure initidents; virtual; + procedure parse; virtual; + property token: ptokenty read fto; + property acttoken: tokenidty read getacttoken write setacttoken; + procedure nexttoken; + procedure nextnonwhitetoken; + procedure lasttoken; + procedure lastnonwhitetoken; + + function gettoken: string; + function getorigtoken: string; //original case + function getorigtext(const start: pchar): string; + //returns text from start to actual pos + function getlastorigtext(const start: pchar): string; + //returns text from start to lasttoken + function getident: integer; overload; //-1 if none + function getident(out aident: integer): boolean; overload; + //false if none + function getnameorident(out aident: integer): boolean; overload; + //false if none, -1 if name or none + function getnameorident: boolean; overload; + function getfirstident: integer; //-1 if none or not first token in line + function checkident(const ident: integer): boolean; overload;//true if ok + function checkident(const ident: array of integer): integer; overload; + //returns found ident, -1 if none + function testident(const ident: integer): boolean; + //skips whitespace, true if ident found + function checknamenoident: boolean; + function skipnamenoident: boolean; + function checkname: boolean; overload; + function checkname(const aname: ansistring): boolean; overload; + function getname(out value: lstringty): boolean; overload; + function getorigname(out value: lstringty): boolean; overload; + function getname: string; overload; //'' if none + function getorigname: string; overload; //'' if none + function getnamenoident(out value: lstringty): boolean; + function getorignamenoident(out value: lstringty): boolean; + + function testname(const atoken: tokenty; const aname: string): boolean; + function testnames(const atoken: tokenty; + const anames: array of string): integer; + + function getoperator: char; //#0 if none + function getnextoperator: char; + function testoperator(op: char): boolean; + function checkoperator(op: char): boolean; + function checknextoperator(aoperator: char): boolean; //true if ok + function findoperator(aoperator: char): boolean; //false if not found + function findclosingbracket: boolean; //false if not found; + function getvaluestring(var value: string): valuekindty; virtual; + function getnamelist: lstringarty; //names separated by ',' + function getorignamelist: lstringarty; //names separated by ',' + + function skipcomment: boolean; virtual; //does not skip whitespace + function checknewline: boolean; + function nextline: boolean; //false if fileend + function skipwhitespace: boolean; //and comments, false if no whitespaces + function skipwhitespaceonly: boolean; + function skipnamelist: boolean; //skips [,]{,} false if no name found + function skipidents: boolean; + property eof: boolean read feof; + function isfirstnonwhitetoken: boolean; + {$ifndef nohash} + function hashident(name: pchar; len: integer): byte; overload; + function hashident(const name: string): byte; overload; + {$endif} + + procedure mark; //set mark in tokenstak + function back: boolean; + //restore tokenstack to last mark, mark must be in same file, true if ok + procedure pop; //remove mark from tokenstack + procedure setidents(idents: array of string); + + function sourceoffset: integer; + function sourcepos: sourceposty; + function nextsourcepos: sourceposty; //skips whitespace + function nexttokenornewlinepos: sourceposty; + function getsourcepos(const atoken: tokenidty): sourceposty; + //returns row and col in source + function lasttokenoffset: integer; + function lasttokenpos: sourceposty; + + function addscanner(const ascanner: tscanner): integer; + function dogetincludefile(const afilename: filenamety; + const astatementstart,astatementend: sourceposty): tscanner; virtual; + function includefile(const filename: filenamety; + const statementstart,statementend: sourceposty): integer; + //-1 on error, scanner index otherwise + procedure callincludefile(const filename: filenamety; + const startpos: sourceposty; const anum: integer); + function origoffset: integer; + property scanner: tscanner read getscanner write setscanner; + property recursivecomment: boolean read frecursivecomment + write frecursivecomment default false; + property ongetincludefile: getincludefileeventty read fongetincludefile + write fongetincludefile; + property includefiledirs: filenamearty read fincludefiledirs + write fincludefiledirs; + property startdefines: stringarty read fstartdefines write fstartdefines; + end; + +type + pascalidentty = (pid_invalid = -1, + pid_and=0,pid_array,pid_as,pid_asm,pid_begin,pid_case,pid_class,pid_const, + pid_constructor, + pid_destructor,pid_dispinterface,pid_div,pid_do,pid_downto,pid_else,pid_end, + pid_except, + pid_exports,pid_file,pid_finalization,pid_finally,pid_for,pid_function, + pid_goto,pid_if, + pid_implementation,pid_in,pid_initialization,pid_inline,pid_forward, + pid_interface, + pid_is,pid_label,pid_library,pid_method,pid_mod,pid_nil,pid_not,pid_object, + pid_of,pid_or,pid_out, + pid_overload, + pid_packed,pid_procedure,pid_program,pid_property,pid_raise,pid_record, + pid_repeat, + pid_resourcestring,pid_set,pid_shl,pid_shr,pid_then,pid_threadvar,pid_to, + pid_try,pid_type,pid_unit,pid_until,pid_uses,pid_var,pid_while,pid_with, + pid_xor, + + pid_abstract,pid_inherited,pid_override,pid_reintroduce,pid_virtual, + pid_private,pid_protected,pid_public,pid_published,pid_automated, + + pid_read,pid_write,pid_stored,pid_default,pid_nodefault); + + const + firstpascalident = pid_and; + lastpascalnormalident = integer(pid_xor); + lastpascalclassident = integer(pid_automated); + lastpascalpropertyident = integer(pid_nodefault); + lastpascalident = pid_nodefault; + + pascalidents: array[firstpascalident..lastpascalident] of string = ( + 'and','array','as','asm','begin','case','class','const','constructor', + 'destructor','dispinterface','div','do','downto','else','end','except', + 'exports','file','finalization','finally','for','function','goto','if', + 'implementation','in','initialization','inline','forward','interface', + 'is','label','library','method','mod','nil','not','object','of','or','out', + 'overload', + 'packed','procedure','program','property','raise','record','repeat', + 'resourcestring','set','shl','shr','then','threadvar','to', + 'try','type','unit','until','uses','var','while','with','xor', //default + + 'abstract','inherited','override','reintroduce','virtual', //class + 'private','protected','public','published','automated', + + 'read','write','stored','default','nodefault'); + +type + + tpascalparser = class(tparser) + protected + fnoautoparse: boolean; + function getscannerclass: scannerclassty; override; + public + constructor create(const afilelist: tmseindexednamelist); override; + destructor destroy; override; + procedure clear; override; + procedure initidents; override; + function getvaluestring(var value: string): valuekindty; override; + function skipcomment: boolean; override; //does not skip whitespace + procedure parsecompilerswitch; + function getpascalstring(var value: string): boolean; //true if ok + function concatpascalstring(var value: string): boolean; + //concats +... true if ok + function concatpascalname(var value: string): boolean; + //returns ...., true if ok + + function getclassident: pascalidentty; //-1 if none + function checkclassident(const ident: pascalidentty): boolean; //true if ok + function getpropertyident: pascalidentty; //-1 if none + function checkpropertyident(const ident: pascalidentty): boolean; //true if ok + end; + + cidentty = (cid_invalid = -1, + cid_break = 0,cid_case,cid_continue,cid_default, + cid_do,cid_else,cid_entry,cid_for,cid_goto,cid_if,cid_return, + cid_sizeof, + cid_switch,cid_while, + + cid_auto,{cid_char,}cid_const,{cid_double,}cid_enum,cid_extern,{cid_float,} + {cid_int,cid_long,}cid_register,{cid_short,}cid_signed,cid_static, + cid_struct,cid_typedef,cid_union,cid_unsigned,cid_volatile); + const + firstcident = cid_break; + lastcident = cid_volatile; + cidents: array[firstcident..lastcident] of string = ( + 'break','case','continue','default', + 'do','else','entry','for','goto','if','return', + 'sizeof', + 'switch','while', + + 'auto',{'char',}'const',{'double',}'enum','extern',{'float',} + {'int','long',}'register',{'short',}'signed','static', + 'struct','typedef','union','unsigned','volatile' + ); + + type + tcparser = class(tparser) + protected + fincomment: integer; + function getscannerclass: scannerclassty; override; + procedure parsepreprocdef; + public + constructor create(const afilelist: tmseindexednamelist); override; + procedure initidents; override; + function getvaluestring(var value: string): valuekindty; override; + function skipcomment: boolean; override; //does not skip whitespace + function getcstring(var value: string): boolean; + function skipstatement: boolean; + end; + + constinfoty = record + name: string; + valuetype: tvaluetype; + value: msestring; + resource: boolean; + case integer of + 0:(offset,len: integer); + 1:(hash: card32); + end; + pconstinfoty = ^constinfoty; + constinfoarty = array of constinfoty; + + tconstparser = class(tpascalparser) + public + function getconsts(var ar: constinfoarty): string; + //returns unitname + end; + + tfpcresstringparser = class(tpascalparser) + public + procedure getconsts(var ar: constinfoarty); + end; + + tresstringlistparser = class(tcparser) + public + constructor create(const afilelist: tmseindexednamelist); override; + procedure getconsts(var ar: constinfoarty); + end; + + +function isemptysourcepos(const value: sourceposty): boolean; +function issamesourcepos(const a,b: sourceposty): boolean; +function emptysourcepos: sourceposty; + +implementation +uses + sysutils,mseformatstr,msedatalist,typinfo,msebits,msewidgets, + msefileutils,msearrayutils,mseapplication; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + treader1 = class(treader); + twriter1 = class(twriter); + +function isemptysourcepos(const value: sourceposty): boolean; +begin + result:= value.filenum = 0; +end; + +function issamesourcepos(const a,b: sourceposty): boolean; +begin + result:= (a.filenum <> 0) and (a.filenum = b.filenum) and + (a.pos.col = b.pos.col) and (a.pos.row = b.pos.row); +end; + +function emptysourcepos: sourceposty; +begin + finalize(result); + fillchar(result,sizeof(sourceposty),0); +end; + +{ tsourceposlist } + +constructor tsourceposlist.create; +begin + inherited create(sizeof(sourceposty){,[rels_needsfinalize,rels_needscopy]}); +end; + +function tsourceposlist.add(const source: sourceposty): integer; +begin + result:= inherited add(source); +end; +{ +procedure tsourceposlist.copyrecord(var item); +begin + with sourceposty(item) do begin + stringaddref(filename); + end; +end; + +procedure tsourceposlist.finalizerecord(var item); +begin + finalize(sourceposty(item)); +end; +} +function tsourceposlist.getitems(const index: integer): psourceposty; +begin + result:= getitempo(index); +end; + +{ tscanner } + +constructor tscanner.create; +begin + inherited; +end; + +constructor tscanner.create(const afilename: filenamety; + const filelist: tmseindexednamelist); +var + stream: ttextstream; +begin + create; + setfilename(afilename,filelist); + stream:= ttextstream.create(filename); + try + source:= stream.readdatastring; + finally + stream.Free; + end; +end; + +procedure tscanner.setfilename(const aname: filenamety; + const filelist: tmseindexednamelist); +begin + ffilename:= aname; + ffileid:= filelist.add(aname); +end; + +procedure tscanner.clear; +begin + ftokencount:= 0; + ftokens:= nil; + flinenr:= 0; +end; + +procedure tscanner.newtoken(akind: tokenkindty); +begin + if ftokencount >= high(ftokens) then begin + setlength(ftokens,(3*length(ftokens)) div 2 + 256); + end; + fscto:= @ftokens[ftokencount]; + if flinestart then begin + include(fscto^.state,tos_linestart); + flinestart:= false; + end; + if ffirstofline then begin + include(fscto^.state,tos_firstofline); + if akind <> tk_whitespace then begin + ffirstofline:= false; + end; + end; + inc(ftokencount); + fscto^.kind:= akind; + fscto^.value.po:= fpo; + case akind of + tk_newline: begin + fscto^.linenr:= flinenr; + inc(flinenr); + flinestart:= true; + ffirstofline:= true; + end; + tk_operator: begin + fscto^.op:= fpo^; + end; + end; +end; + +procedure tscanner.endtoken; +begin + fscto^.value.len:= fpo - fscto^.value.po; +end; + +procedure tscanner.scantoken; +var + ch1: char; +begin +// ch1:= upcase(fpo^); + ch1:= upperchars[fpo^]; + if (ch1 = ' ') or (ch1 = c_tab) then begin + newtoken(tk_whitespace); + repeat + inc(fpo); + until not ((fpo^ = ' ') or (fpo^ = c_tab)); + end + else begin + if (ch1 >= 'A') and (ch1 <= 'Z') or (ch1 = '_') then begin + newtoken(tk_name); + repeat + inc(fpo); + ch1:= upcase(fpo^); + until not ((ch1 >= 'A') and (ch1 <= 'Z') or (ch1 = '_') or + (ch1 >= '0') and (ch1 <= '9')); + end + else begin + if (ch1 >= '0') and (ch1 <= '9') then begin + newtoken(tk_number); + repeat + inc(fpo); + until (fpo^ < '0') or (fpo^ > '9'); + end + else begin + if ch1 = c_return then begin + newtoken(tk_newline); + inc(fpo); + if fpo^ = c_linefeed then begin + inc(fpo); + end; + end + else begin + if ch1 = c_linefeed then begin + newtoken(tk_newline); + inc(fpo); + if fpo^ = c_return then begin + inc(fpo); + end; + end + else begin + newtoken(tk_operator); + inc(fpo); + end; + end; + end; + end; + end; +end; + +procedure tscanner.scan; +begin + clear; + fpo:= pointer(fsource); + if fpo <> nil then begin + flinestart:= true; + ffirstofline:= true; + while fpo^ <> #0 do begin + scantoken; + endtoken; + if fescapechar <> #0 then begin + if (ftokens[ftokencount-1].kind = tk_newline) and + (ftokencount > 1) and (ftokens[ftokencount-2].kind = tk_operator) and + (ftokens[ftokencount-2].op = fescapechar) then begin + dec(ftokencount,2); + if ftokencount > 0 then begin + with ftokens[ftokencount-1].value do begin + len:= len + ftokens[ftokencount].value.len + + ftokens[ftokencount+1].value.len; + end; + end; + end; + end; + end; + end; + newtoken(tk_fileend); +end; + +procedure tscanner.updatecase; +begin + if fcasesensitive then begin + fsource:= fsourceorig; + forigoffset:= 0; + end + else begin + fsource:= uppercase(fsourceorig); + forigoffset:= pchar(fsourceorig) - pchar(fsource); + end; +end; + +procedure tscanner.setsource(const Value: ansistring); +begin + fsourceorig:= Value; + updatecase; + scan; +end; + +procedure tscanner.setcasesensitive(const Value: boolean); +begin + if fcasesensitive <> value then begin + fcasesensitive:= Value; + updatecase; + end; +end; + +{ tpascalscanner } + +constructor tpascalscanner.create; +begin + inherited; +end; + +{ tcscanner } + +constructor tcscanner.create; +begin + inherited; + fcasesensitive:= true; + fescapechar:= '\'; +end; + +{ tparser } + +constructor tparser.create(const afilelist: tmseindexednamelist); +begin + if application.waitescaped then begin + abort; + end; + fdefines:= tdefineslist.create(); + ffilelist:= afilelist; + flastvalidident:= bigint; + setlength(fincludefiledirs,1); + fincludefiledirs[0]:= './'; +end; + +constructor tparser.create(const afilelist: tmseindexednamelist; + const atext: string); +var + ascanner: tscanner; +begin + create(afilelist); + fownsscanner:= true; + ascanner:= getscannerclass.create; + ascanner.source:= atext; + scanner:= ascanner; +end; + +constructor tparser.create; +begin + create(nil); +end; + +destructor tparser.destroy; +begin + reset; + inherited; + if fownsscanner then begin + fscanner.Free; + end; + fdefines.free; +end; + +procedure tparser.reset; +var + int1: integer; +begin + for int1:= 1 to high(fscanners) do begin + fscanners[int1].Free; + end; + fscanners:= nil; +end; + +procedure tparser.clear; +begin + feof:= false; + ftokennum:= 0; + ftokenstack:= nil; + ffilestack:= nil; + ftokenstackcount:= 0; + fscannernum:= 0; + if fscanners <> nil then begin + fscanner:= fscanners[0]; + fto:= ptokenty(pointer(fscanner.ftokens)); + setlength(ffilestack,1); + end + else begin + fscanner:= nil; + fto:= nil; + end; + fsyntaxerrorcount:= 0; +end; + +function tparser.addscanner(const ascanner: tscanner): integer; +begin + result:= length(fscanners); + if result = 0 then begin + fscanner:= ascanner; + end + else begin + ascanner.fstartline:= sourcepos.line + 1; + //dummy line for include files + end; + setlength(fscanners,result+1); + fscanners[result]:= ascanner; +end; + +function tparser.dogetincludefile(const afilename: filenamety; + const astatementstart,astatementend: sourceposty): tscanner; +begin + result:= tscanner(fscanners[0].newinstance); + if assigned(fongetincludefile) then begin + result.create; + result.setfilename(afilename,ffilelist); + fongetincludefile(self,result); + end + else begin + result.Create(afilename,ffilelist); + end; +end; + +function tparser.includefile(const filename: filenamety; + const statementstart,statementend: sourceposty): integer; + //returns scanner index +var + str1: filenamety; + ascanner: tscanner; + int1: integer; +begin + result:= -1; + if application.waitescaped then begin + abort;//exit; + end; + if high(ffilestack) < maxincludelevel then begin + if findfile(filename,fincludefiledirs,str1) then begin + for int1:= 0 to high(ffilestack) do begin + if issamefilename(str1,fscanners[ffilestack[int1].tokenid.scanner].ffilename) then begin + //recursive + syntaxerror; + exit; + end; + end; + ascanner:= dogetincludefile(str1,statementstart,statementend); + try + result:= addscanner(ascanner); + except + result:= -1; + ascanner.Free; + end; + end; + end; +end; + +procedure tparser.callincludefile(const filename: filenamety; + const startpos: sourceposty; const anum: integer); +var + int1,int2: integer; +begin + int2:= includefile(filename,startpos,sourcepos); + if int2 >= 0 then begin + for int1:= anum + 1 to ftokennum - 1 do begin + fscanner.ftokens[int1].kind:= tk_whitespace; + end; + with fscanner.ftokens[anum] do begin + kind:= tk_include; + filenr:= int2; + end; + enterinclude(int2); + end; +end; + +function tparser.origoffset: integer; +begin + result:= 0; + if fscanner <> nil then begin + result:= fscanner.forigoffset; + end; +end; + +{$ifndef nohash} + +function tparser.hashident(name: pchar; len: integer): byte; +var + sumb: byte; + xorb: byte; + by1: byte; +begin + sumb:= 0; + xorb:= 0; +// if fcasesensitive then begin + while len > 0 do begin + sumb:= sumb + byte(name^); + xorb:= xorb xor byte(name^); + inc(name); + dec(len); + end; +// end + { + else begin + while len > 0 do begin + by1:= byte(upcase(name^)); + sumb:= sumb + by1; + xorb:= xorb xor by1; + inc(name); + dec(len); + end; + end; + } + result:= sumb xor xorb; +end; + +function tparser.hashident(const name: string): byte; +begin + result:= hashident(pchar(name),length(name)); +end; + +{$endif nohash} + +procedure tparser.setidents(idents: array of string); +var + int1: integer; + str1: string; + by1: byte; +begin + for int1:= 0 to high(idents) do begin + str1:= copy(idents[int1],1,identmaxlen); + if not fcasesensitive then begin + str1:= uppercase(str1); + end; + {$ifdef nohash} + assert((length(str1) > 0) and (ord(str1[1]) < 128), + 'Invalid ident '''+str1+''''); + by1:= byte(str1[1]); + str1:= copy(str1,2,bigint); + {$else} + assert(length(str1) > 0,'Empty ident'); + by1:= hashident(str1); + {$endif} + setlength(fidents[by1],high(fidents[by1])+2); + with fidents[by1][high(fidents[by1])] do begin +// if fcasesensitive then begin + name:= str1; +// end +// else begin +// name:= uppercase(str1); +// end; + name[length(str1)+1]:= #0; + ident:= int1; + end; + end; +end; + +function tparser.sourceoffset: integer; +begin + result:= fto^.value.po - pchar(fscanner.fsource); +end; + +function tparser.getsourcepos(const atoken: tokenidty): sourceposty; + //returns row and col in source +var + int1: integer; +begin +// result.filenum:= fscannernum + 1; +// result.filename:= fscanners[fscannernum].ffileid; + result.filenum:= atoken.scanner + 1; +// with result.pos,fscanner do begin + with result.pos,fscanners[atoken.scanner] do begin + result.filename:= ffileid; + row:= 0; + col:= ftokens[atoken.token].value.po - + pchar(fsource); + result.offset:= col; //byteoffset in file + for int1:= atoken.token-1 downto 0 do begin + with ftokens[int1] do begin + if (kind = tk_newline) then begin + row:= linenr + 1; + col:= col - (ftokens[int1+1].value.po - + pchar(fsource)); + break; + end; + end; + end; + end; + result.line:= result.pos.row; + if high(ffilestack) >= 0 then begin + inc(result.line,ffilestack[high(ffilestack)].lineoffset); + end; +end; + +function tparser.sourcepos: sourceposty; +var + id: tokenidty; +begin + id.scanner:= fscannernum; + id.token:= ftokennum; + result:= getsourcepos(id); +end; + +function tparser.nextsourcepos: sourceposty; //skips whitespace +begin + skipwhitespace; + result:= sourcepos; +end; + +function tparser.nexttokenornewlinepos: sourceposty; +begin + skipwhitespaceonly; + if fto^.kind = tk_newline then begin + nexttoken; + end; + result:= sourcepos; +end; + +function tparser.lasttokenoffset: integer; +var + int1: integer; +begin + result:= 0; + with fscanner do begin + for int1:= ftokennum - 2 downto 0 do begin + if ftokens[int1].kind <> tk_whitespace then begin + result:= ftokens[int1+1].value.po - pchar(fsource); + break; + end; + end; + end; +end; + +function tparser.lasttokenpos: sourceposty; +begin + result:= sourcepos; + result.pos.col:= result.pos.col - sourceoffset + lasttokenoffset; +end; + +function tparser.getacttoken: tokenidty; +begin + result.scanner:= fscannernum; + result.token:= ftokennum; +end; + +procedure tparser.setacttokennum(anum: longword); +begin + with fscanner do begin + if anum <= longword(high(ftokens)) then begin + ftokennum:= anum; + fto:= @ftokens[ftokennum]; + end + else begin + internalerror; + end; + end; +end; + +procedure tparser.setacttoken(const atoken: tokenidty); +var + int1,int2: integer; +begin + with atoken do begin + if scanner > longword(high(fscanners)) then begin + internalerror; + end; + if ffilestack <> nil then begin + int2:= high(ffilestack); + if ffilestack[int2].tokenid.scanner <> scanner then begin + for int1:= int2 downto 0 do begin + if ffilestack[int2].tokenid.scanner = scanner then begin + setlength(ffilestack,int2+1); + end; + end; + end; + end; + fscannernum:= scanner; + fscanner:= fscanners[scanner]; + feof:= false; + with fscanner do begin + if token <= longword(high(ftokens)) then begin + ftokennum:= token; + fto:= @ftokens[ftokennum]; + end + else begin + internalerror; + end; + end; + end; +end; + +procedure tparser.enterinclude(anum: longword); +var + id1: tokenidty; + int1: integer; + aline: integer; +begin + if anum > longword(high(fscanners)) then begin + internalerror; + end; + inc(fscanner.fincludecount); + aline:= sourcepos.line; + int1:= high(ffilestack); + setlength(ffilestack,int1+2); + ffilestack[int1+1].tokenid:= acttoken; + ffilestack[int1+1].lineoffset:= aline + 1; + //dummy line for include files + id1.scanner:= anum; + id1.token:= 0; + setacttoken(id1); +end; + +function tparser.exitinclude: boolean; + //false if root +var + int1,int2: integer; + acount: integer; +begin + int1:= sourcepos.line; + if high(ffilestack) > 0 then begin + int1:= int1 - fscanner.fstartline; + if fscanner.fcount <= 0 then begin + inc(fscanner.fcount,int1); + end; + acount:= fscanner.fcount; + result:= true; + setacttoken(ffilestack[high(ffilestack)].tokenid); + if ffilestack <> nil then begin + for int2:= high(ffilestack) downto 1 do begin + with fscanners[ffilestack[int2].tokenid.scanner] do begin + if fcount <= 0 then begin + dec(fcount,acount); + end; + end; + end; + setlength(ffilestack,high(ffilestack)); + if ffilestack <> nil then begin + inc(ffilestack[high(ffilestack)].lineoffset,int1); + end; + end; + end + else begin + result:= false; + feof:= true; + if fscanners[0].fcount <= 0 then begin + inc(fscanners[0].fcount,int1); + end; + end; +end; + +procedure tparser.nexttoken; +begin + if fto^.kind <> tk_fileend then begin + inc(ftokennum); + fto:= @fscanner.ftokens[ftokennum]; + end + else begin + repeat + until (fto^.kind <> tk_fileend) or not exitinclude; + end; +end; + +procedure tparser.nextnonwhitetoken; +begin + skipwhitespace; + nexttoken; +end; + +procedure tparser.lasttoken; +begin + if ftokennum > 0 then begin + dec(ftokennum); + fto:= @fscanner.ftokens[ftokennum]; + end + else begin + if not exitinclude then begin + internalerror; + end; + end; +end; + +procedure tparser.lastnonwhitetoken; +begin + repeat + if ftokennum > 0 then begin + dec(ftokennum); + fto:= @fscanner.ftokens[ftokennum]; + end + else begin + if not exitinclude then begin + break; + end; + end; + until fto^.kind <> tk_whitespace; +end; + +procedure tparser.mark; +begin + if ftokenstackcount >= high(ftokenstack) then begin + setlength(ftokenstack,high(ftokenstack)+33); + end; + ftokenstack[ftokenstackcount].token:= ftokennum; + ftokenstack[ftokenstackcount].scanner:= fscannernum; + inc(ftokenstackcount); +end; + +function tparser.back: boolean; +begin + if ftokenstackcount = 0 then begin + internalerror; + end; + dec(ftokenstackcount); + if fscannernum = ftokenstack[ftokenstackcount].scanner then begin + setacttoken(ftokenstack[ftokenstackcount]); + result:= true; + end + else begin + result:= false; + end; +end; + +procedure tparser.pop; +begin + if ftokenstackcount = 0 then begin + internalerror; + end; + dec(ftokenstackcount); +end; + +function tparser.gettoken: string; +begin + setstring(result,fto^.value.po,fto^.value.len); + nexttoken; +end; + +function tparser.getorigtoken: string; +begin + setstring(result,fto^.value.po+fscanner.forigoffset,fto^.value.len); + nexttoken; +end; + +function tparser.getorigtext(const start: pchar): string; + //returns text from start to actual pos +begin + if fto^.value.po - start > 0 then begin + setstring(result,start+fscanner.forigoffset,fto^.value.po - start); + end + else begin + result:= ''; + end; +end; + +function tparser.getlastorigtext(const start: pchar): string; + //returns text from start to actual pos +begin + lasttoken; + if fto^.value.po - start > 0 then begin + setstring(result,start+fscanner.forigoffset,fto^.value.po - start); + end + else begin + result:= ''; + end; + nexttoken; +end; + +function tparser.checknextoperator(aoperator: char): boolean; +begin + with fscanner.ftokens[ftokennum+1] do begin + if (kind = tk_operator) and (op = aoperator) then begin + result:= true; + nexttoken; + end + else begin + result:= false; + end; + end; +end; + +function tparser.findoperator(aoperator: char): boolean; +begin + result:= false; + while (fto^.kind <> tk_fileend) or exitinclude do begin + if (fto^.kind = tk_operator) and (fto^.op = aoperator) then begin + nexttoken; + result:= true; + break; + end; + nexttoken; + end; +end; + +function tparser.getnextoperator: char; +begin + result:= #0; + while (fto^.kind <> tk_fileend) or exitinclude do begin + skipwhitespace; + if (fto^.kind = tk_operator) then begin + result:= fto^.op; + nexttoken; + break; + end; + nexttoken; + end; +end; + +function tparser.getoperator: char; +begin + skipwhitespace; + if fto^.kind = tk_operator then begin + result:= fto^.op; + nexttoken; + end + else begin + result:= #0; + end; +end; + +function tparser.testoperator(op: char): boolean; +begin + skipwhitespace; + if fto^.kind = tk_operator then begin + result:= fto^.op = op; + end + else begin + result:= false; + end; +end; + +function tparser.checkoperator(op: char): boolean; +var + ch1: char; +begin + ch1:= getoperator; + result:= op = ch1; + if not result and (ch1 <> #0) then begin + lasttoken; + end; +end; + +function tparser.findclosingbracket: boolean; //false if not found; +var + int1: integer; + ch1: char; +begin + result:= false; + int1:= 1; + repeat + ch1:= getnextoperator; + case ch1 of + ')': begin + dec(int1); + if int1 = 0 then begin + result:= true; + break; + end; + end; + '(': begin + inc(int1); + end; + end; + until ch1 = #0; +end; + +function tparser.isfirstnonwhitetoken: boolean; +var + po1,po2: ptokenty; +begin + result:= true; + po1:= fto; + po2:= @fscanner.ftokens[0]; + while po1 <> po2 do begin + dec(po1); + if po1^.kind = tk_newline then begin + break; + end + else begin + if po1^.kind <> tk_whitespace then begin + result:= false; + break; + end; + end; + end; +end; + +function tparser.skipwhitespace: boolean; +begin + result:= false; + repeat + while (fto^.kind = tk_whitespace) or (fto^.kind = tk_newline) do begin + result:= true; + nexttoken; + end; + while skipcomment do begin + result:= true; + while (fto^.kind = tk_whitespace) or (fto^.kind = tk_newline) do begin + nexttoken; + end; + if fto^.kind = tk_fileend then begin + nexttoken; //exit include file + end; + end; + if fto^.kind = tk_fileend then begin + nexttoken; //exit include file + end; + until not ((fto^.kind = tk_whitespace) or (fto^.kind = tk_newline)); +end; + +function tparser.skipwhitespaceonly: boolean; +begin + result:= false; + while (fto^.kind = tk_whitespace) do begin + result:= true; + nexttoken; + end; +end; + +function tparser.skipnamelist: boolean; + //skips [,]{,} false if no name found +begin + result:= false; + checkoperator(','); + while true do begin + if not getnameorident then begin + break; + end; + result:= true; + if not checkoperator(',') then begin + break; + end; + end; +end; + +function tparser.skipidents: boolean; +begin + result:= false; + while getident >= 0 do begin + end; +end; + +function tparser.getident: integer; +var + by1: byte; + int1,alen: integer; + po1,po2: pchar; + po3: pidentinfoty; +begin + skipwhitespace; + result:= -1; + with fto^ do begin + if kind = tk_name then begin + {$ifdef nohash} + by1:= byte(value.po^); + if by1 >= 128 then begin + exit; + end; + alen:= value.len-1; + {$else} + by1:= hashident(value.po,value.len); + alen:= value.len; + {$endif} + for int1:= 0 to high(fidents[by1]) do begin + po3:= @fidents[by1][int1]; + if length(po3^.name) = alen then begin + {$ifdef nohash} + po1:= value.po + 1; //source + {$else} + po1:= value.po; //source + {$endif} + po2:= @po3^.name[1]; + while (po2^ <> #0) and (po1^ = po2^) do begin + inc(po1); + inc(po2); + end; + if po2^= #0 then begin + result:= po3^.ident; + break; + end; + end; + end; + end; + end; + if result > flastvalidident then begin + result:= -1; + end; + if result >= 0 then begin + nexttoken; + end; +end; + +function tparser.getident(out aident: integer): boolean; + //false if none +begin + aident:= getident(); + result:= aident >= 0; +end; + +function tparser.getnameorident(out aident: integer): boolean; + //false if none, -1 if name or none +begin + aident:= getident; + result:= aident >= 0; + if not result and (fto^.kind = tk_name) then begin + result:= true; + nexttoken; + end; +end; + +function tparser.getnameorident: boolean; + //false if none, -1 if name or none +begin + skipwhitespace; + result:= fto^.kind = tk_name; + if result then begin + nexttoken; + end; +end; + +function tparser.getfirstident: integer; //-1 if none or not first token in line +begin + if (ftokennum = 0) or (fscanner.ftokens[ftokennum-1].kind = tk_newline) then begin + result:= getident; + end + else begin + skipwhitespace; + result:= -1; + end; +end; + +function tparser.testname(const atoken: tokenty; const aname: string): boolean; +begin + result:= (atoken.kind = tk_name) and (lstringcomp(atoken.value,aname) = 0); +end; + +function tparser.testnames(const atoken: tokenty; + const anames: array of string): integer; +var + int1: integer; +begin + result:= -1; + if atoken.kind = tk_name then begin + for int1:= 0 to high(anames) do begin + if (lstringcomp(atoken.value,anames[int1]) = 0) then begin + result:= int1; + break; + end; + end; + end; +end; + +function tparser.checkident(const ident: integer): boolean; +var + int1: integer; +begin + int1:= getident; + result:= ident = int1; + if not result and (int1 >= 0) then begin + lasttoken; + end; +end; + +function tparser.checkident(const ident: array of integer): integer; +var + int1,int2: integer; +begin + int1:= getident; + result:= -1; + if int1 >= 0 then begin + for int2:= 0 to high(ident) do begin + if int1 = ident[int2] then begin + result:= int1; + break; + end; + end; + end; + if (result < 0) and (int1 >= 0) then begin + lasttoken; + end; +end; + +function tparser.testident(const ident: integer): boolean; + //skips whitespace, true if ident found +begin + result:= getident = ident; + if result then begin + lasttoken; + end; +end; + +function tparser.checknamenoident: boolean; +begin + result:= (getident = -1) and (fto^.kind = tk_name); + if result then begin + nexttoken; + end; +end; + +function tparser.skipnamenoident: boolean; +begin + result:= (getident = -1); + if result and (fto^.kind = tk_name) then begin + nexttoken(); + end; +end; + +function tparser.checkname: boolean; +begin + skipwhitespace; + result:= fto^.kind = tk_name; + if result then begin + nexttoken; + end; +end; + +function tparser.checkname(const aname: ansistring): boolean; +begin + skipwhitespace; + result:= (fto^.kind = tk_name) and issamelstring(fto^.value,aname,fcasesensitive); + if result then begin + nexttoken; + end; +end; + +function tparser.getname(out value: lstringty): boolean; +begin + skipwhitespace; + result:= fto^.kind = tk_name; + if result then begin + value:= fto^.value; + nexttoken; + end + else begin + value:= emptylstring; + end; +end; + +function tparser.getname: string; +var + value: lstringty; +begin + getname(value); + setstring(result,value.po,value.len); +end; + +function tparser.getorigname(out value: lstringty): boolean; +begin + skipwhitespace; + result:= fto^.kind = tk_name; + if result then begin + value:= fto^.value; + inc(value.po,fscanner.forigoffset); + nexttoken; + end + else begin + value:= emptylstring; + end; +end; + +function tparser.getorigname: string; +var + value: lstringty; +begin + getorigname(value); + setstring(result,value.po,value.len); +end; + +function tparser.getnamenoident(out value: lstringty): boolean; +begin + if getident < 0 then begin + result:= getname(value); + end + else begin + value:= emptylstring; + result:= false; + lasttoken; + end; +end; + +function tparser.getorignamenoident(out value: lstringty): boolean; +begin + if getident < 0 then begin + result:= getorigname(value); + end + else begin + value:= emptylstring; + result:= false; + lasttoken; + end; +end; + +function tparser.skipcomment: boolean; //does not skip whitespace +begin + result:= false; //dummy +end; + +function tparser.checknewline: boolean; +begin + skipwhitespaceonly; + if fto^.kind = tk_newline then begin + result:= true; + nexttoken; + end + else begin + result:= false; + end; +end; + +function tparser.nextline: boolean; //false if fileend +var + po1: ptokenty; +begin +// result:= false; + po1:= fto; + while (fto^.kind <> tk_fileend) and (fto^.kind <> tk_newline) do begin + inc(fto); + end; + if fto^.kind <> tk_fileend then begin + inc(fto); + result:= true; + end + else begin + result:= exitinclude; + exit; + end; + inc(ftokennum,(pchar(fto)-pchar(po1)) div sizeof(tokenty)); +end; + +function tparser.getvaluestring(var value: string): valuekindty; +var + str1: string; +begin + skipwhitespace; + result:= vk_none; + str1:= ''; + case fto^.kind of + tk_number: begin + mark; + result:= vk_integer; + value:= gettoken; + if (fto^.kind = tk_operator) and (fto^.op = '.') then begin + result:= vk_real; + value:= value + '.'; + nexttoken; + if fto^.kind = tk_number then begin + str1:= str1 + gettoken; + end + end; + if (fto^.kind = tk_name) and (fto^.value.len = 1) and + ((fto^.value.po^ = 'e') or (fto^.value.po^ = 'E')) then begin + result:= vk_real; + nexttoken; + if (fto^.kind = tk_operator) and + ((fto^.op = '+') or (fto^.op = '-')) then begin + value:= value+getoperator; + end; + if (fto^.kind = tk_number) then begin + value:= value + gettoken; + end + else begin + result:= vk_none; + end; + end; + if result <> vk_none then begin + pop; + end + else begin + back; + end; + end; + end; +end; + +function tparser.getnamelist: lstringarty; //names separated by ',' +var + count: integer; +begin + count:= 0; + setlength(result,1); + while not eof do begin + if not getname(result[count]) then begin + break; + end; + inc(count); + if not checkoperator(',') and (fto^.kind = tk_operator) then begin + break; + end; + if high(result) < count then begin + setlength(result,high(result)+33); + end; + end; + setlength(result,count); +end; + +function tparser.getorignamelist: lstringarty; //names separated by ',' +var + count: integer; +begin + count:= 0; + setlength(result,1); + while not eof do begin + if not getorigname(result[count]) then begin + break; + end; + inc(count); + if not checkoperator(',') and (fto^.kind = tk_operator) then begin + break; + end; + if high(result) < count then begin + setlength(result,high(result)+33); + end; + end; + setlength(result,count); +end; + +procedure tparser.internalerror; +begin + raise exception.Create('Internal error'); +end; + +procedure tparser.syntaxerror; +begin + inc(fsyntaxerrorcount) +end; + +function tparser.getscannerclass: scannerclassty; +begin + result:= tscanner; +end; + +{ +procedure tparser.setcasesensitive(const Value: boolean); +begin + fcasesensitive := Value; +end; +} +function tparser.getscanner: tscanner; +begin + if fscanners = nil then begin + result:= nil; + end + else begin + result:= fscanners[0]; + end; +end; + +procedure tparser.setscanner(const Value: tscanner); +begin + value.casesensitive:= fcasesensitive; + reset; + addscanner(value); + clear; + parse; +end; + +procedure tparser.parse; +begin + initidents; +end; + +procedure tparser.initidents; +begin + setidents([]); +end; + +{ tpascalparser } + +type + pskwordty = (pskw_i,pskw_include,pskw_define,pskw_undef,pskw_ifdef,pskw_ifndef, + pskw_else,pskw_endif); +const + pskwords: array[pskwordty] of string = + ('I','INCLUDE','DEFINE','UNDEF','IFDEF','IFNDEF', + 'ELSE','ENDIF'); + +constructor tpascalparser.create(const afilelist: tmseindexednamelist); +begin + inherited; + flastvalidident:= lastpascalnormalident; +end; + +destructor tpascalparser.destroy; +begin + inherited; +end; + +procedure tpascalparser.clear; +var + int1: integer; +begin + inherited; + fdefstate:= def_none; + fdefstates:= nil; + fdefstatecount:= 0; + fdefines.clear; + for int1:= 0 to high(fstartdefines) do begin + fdefines.add(uppercase(fstartdefines[int1])); + end; +end; + +procedure tpascalparser.parsecompilerswitch; + + procedure skiprest; + begin + while (fto^.kind <> tk_fileend) and + not((fto^.kind = tk_operator) and (fto^.op = '}')) do begin + nexttoken; + end; + nexttoken; //skip '}' + end; + + procedure skipskip; + begin + repeat + if not skipcomment then begin + nexttoken; + end; + until (fto^.kind = tk_fileend) or (fdefstate <> def_skip); + end; + +var + int1{,int2}: integer; + str1: string; + filename: filenamety; + anum: longword; + startpos{,endpos}: sourceposty; + lstr1: lstringty; +begin + anum:= ftokennum; + int1:= testnames(fto^,pskwords); + if int1 >= 0 then begin + if int1 > 1 then begin + nexttoken; + end; + case pskwordty(int1) of + pskw_ifdef,pskw_ifndef: begin + additem(fdefstates,integer(fdefstate),fdefstatecount); + if fdefstate <> def_skip then begin + if not (getname(lstr1) and + ((fdefines.find(lstr1) <> nil) xor + (pskwordty(int1) = pskw_ifndef))) then begin + fdefstate:= def_skip; + skiprest; + skipskip; + end + else begin + skiprest; + end; + end + else begin + skiprest; + end; + end; + pskw_else: begin + skiprest; + if fdefstate = def_skip then begin + if (fdefstatecount = 0) or + (defstatety(fdefstates[fdefstatecount-1]) <> def_skip) then begin + fdefstate:= def_none; + end; + end + else begin + if fdefstatecount > 0 then begin + fdefstate:= def_skip; + skipskip; + end; + end; + end; + pskw_endif: begin + if fdefstatecount > 0 then begin + dec(fdefstatecount); + fdefstate:= defstatety(fdefstates[fdefstatecount]); + end; + skiprest; + end; + else begin + if fdefstate <> def_skip then begin + case pskwordty(int1) of + pskw_i,pskw_include: begin + startpos:= sourcepos; + nexttoken; + if checkoperator('''') or checkoperator('#')then begin + lasttoken; + if getpascalstring(str1) then begin + try + filename:= pascalstringtostring(str1); + except + end; + end; + end + else begin + str1:= ''; + skipwhitespaceonly; + while not(fto^.kind in [tk_fileend,tk_newline,tk_whitespace]) and + not((fto^.kind = tk_operator) and (fto^.op = '}')) do begin + str1:= str1 + getorigtoken; + end; + filename:= filenamety(str1); + end; + if findoperator('}') then begin +// endpos:= lasttokenpos; + end + else begin +// endpos:= sourcepos; + end; + if filename <> '' then begin + callincludefile(filename,startpos,anum); + end; + end; + pskw_define: begin + str1:= getname; + if str1 <> '' then begin + fdefines.add(str1); + end; + skiprest; + end; + pskw_undef: begin + if getname(lstr1) then begin + fdefines.delete(lstr1); + end; + skiprest; + end; + end; + end; + end; + end; + end + else begin + skiprest; + end; +end; + +function tpascalparser.skipcomment: boolean; //does not skip whitespace +var + int1: integer; + first: boolean; +begin + result:= false; + if (fto^.kind = tk_operator) and (fto^.op = '/') and + checknextoperator('/') then begin + result:= true; + while not ((fto^.kind = tk_newline) or (fto^.kind = tk_fileend)) do begin + nexttoken; + end; + end + else begin + if (fto^.kind = tk_operator) then begin + if (fto^.op = '{') then begin + nexttoken; + result:= true; + first:= true; + int1:= 1; + while (int1 > 0) and (fto^.kind <> tk_fileend) do begin + if (fto^.kind = tk_operator) then begin + if first and (fto^.op = '$') then begin //compiler switch + nexttoken; + parsecompilerswitch; + int1:= 0; + break; + end; + if fto^.op = '}' then begin + dec(int1); + end; + if (fto^.op = '{') and frecursivecomment then begin + inc(int1); + end; + end; + first:= false; + nexttoken; + end; + if int1 > 0 then begin + syntaxerror; + end; + end + else begin + if (fto^.op = '(') and checknextoperator('*') then begin + nexttoken; + result:= true; + repeat + nexttoken; + if (fto^.kind = tk_operator) and (fto^.op = '*') then begin + nexttoken; + if (fto^.kind = tk_operator) and (fto^.op = ')') then begin + nexttoken; + break; + end; + end; + until fto^.kind = tk_fileend; + end; + end; + end; + end; +end; + +function tpascalparser.getpascalstring(var value: string): boolean; +var + int1: integer; + bo1: boolean; +begin + skipwhitespace; + mark; + value:= ''; + result:= (fto^.kind = tk_operator) and ((fto^.op = '#') or (fto^.op = '''')); + while result do begin + bo1:= false; + while (fto^.kind = tk_operator) and (fto^.op = '#') do begin + value:= value + getorigtoken; + if fto^.kind = tk_number then begin + value:= value + getorigtoken; + bo1:= true; + end + else begin + result:= false; + break; + end; + end; + if result then begin + while (fto^.kind = tk_operator) and (fto^.op = '''') do begin //' + bo1:= true; + int1:= 0; + while (fto^.kind = tk_operator) and (fto^.op = '''') do begin //','','''.. + value:= value + getorigtoken; + inc(int1); + end; + if odd(int1) then begin + while (fto^.kind <> tk_fileend) and (fto^.kind <> tk_newline) and + not ((fto^.kind = tk_operator) and (fto^.op = '''')) do begin + value:= value + getorigtoken; + end; + if (fto^.kind = tk_fileend) or (fto^.kind = tk_newline) then begin + result:= false; + break; + end; + value:= value + getorigtoken; + end; + end; + end; + if not bo1 then begin + break; + end; + end; + if result then begin + pop; + end + else begin + value:= ''; + back; + end; +end; + +function tpascalparser.concatpascalstring(var value: string): boolean; +var + str1: string; +begin + value:= ''; + repeat + result:= getpascalstring(str1); + if not result then begin + break; + end; + value:= value+str1+' '; + until not checkoperator('+'); +end; + +function tpascalparser.concatpascalname(var value: string): boolean; +var + str1: string; +begin + value:= ''; + result:= false; + repeat + str1:= getorigname; + if str1 <> '' then begin + value:= value + str1; + result:= true; + if not checkoperator('.') then begin + break; + end; + value:= value + '.'; + end; + until str1 = ''; +end; + +function tpascalparser.getvaluestring(var value: string): valuekindty; +begin + result:= inherited getvaluestring(value); + if result = vk_none then begin + if getpascalstring(value) then begin + result:= vk_string; + end; + end; +end; + +function tpascalparser.getscannerclass: scannerclassty; +begin + result:= tpascalscanner; +end; + +procedure tpascalparser.initidents; +begin + setidents(pascalidents); +end; + +function tpascalparser.checkclassident(const ident: pascalidentty): boolean; +begin + flastvalidident:= lastpascalclassident; + result:= checkident(integer(ident)); + flastvalidident:= lastpascalnormalident; +end; + +function tpascalparser.getclassident: pascalidentty; +begin + flastvalidident:= lastpascalclassident; + result:= pascalidentty(getident); + flastvalidident:= lastpascalnormalident; +end; + +function tpascalparser.checkpropertyident(const ident: pascalidentty): boolean; +begin + flastvalidident:= lastpascalpropertyident; + result:= checkident(integer(ident)); + flastvalidident:= lastpascalnormalident; +end; + +function tpascalparser.getpropertyident: pascalidentty; +begin + flastvalidident:= lastpascalpropertyident; + result:= pascalidentty(getident); + flastvalidident:= lastpascalnormalident; +end; + +{ tcparser } +type + cskwordty = (cskw_if,cskw_include,cskw_define,cskw_undef,cskw_ifdef,cskw_ifndef, + cskw_else,cskw_endif); +const + cskwords: array[cskwordty] of string = + ('if','include','define','undef','ifdef','ifndef', + 'else','endif'); + +constructor tcparser.create(const afilelist: tmseindexednamelist); +begin + inherited; + fcasesensitive:= true; +end; + +function tcparser.getscannerclass: scannerclassty; +begin + result:= tcscanner; +end; + +procedure tcparser.initidents; +begin + setidents([]); +end; + +function tcparser.getcstring(var value: string): boolean; +begin + skipwhitespace; + mark; + value:= ''; + result:= false; + while (fto^.kind = tk_operator) and (fto^.op = '"') do begin + result:= true; + value:= value + getorigtoken; //leading " + while not ((fto^.kind = tk_operator) and (fto^.op = '"')) do begin + if (fto^.kind = tk_operator) and (fto^.op = '\') then begin + value:= value + getorigtoken; //escapechar + if fto^.kind = tk_newline then begin + value:= value + getorigtoken; + end; + end; + if (fto^.kind = tk_fileend) or (fto^.kind = tk_newline) then begin + result:= false; + break; + end; + value:= value + getorigtoken; + end; + if result then begin + value:= value + getorigtoken; // terminating " + if fto^.kind = tk_whitespace then begin + nexttoken; + if (fto^.kind = tk_operator) and (fto^.op = '"') then begin + lasttoken; + value:= value + getorigtoken; + end; + end; + end + else begin + break; + end; + end; + if result then begin + pop; + end + else begin + value:= ''; + back; + end; +end; + +function tcparser.getvaluestring(var value: string): valuekindty; +begin + result:= inherited getvaluestring(value); + if result = vk_none then begin + if getcstring(value) then begin + result:= vk_string; + end; + end; +end; + +procedure tcparser.parsepreprocdef; + + procedure skiprest; + begin + while not ((fto^.kind = tk_newline) or (fto^.kind = tk_fileend)) do begin + //skip rest of line + nexttoken; + end; + end; + + procedure skipskip; + begin + repeat + if not skipcomment then begin + nexttoken; + end; + until (fdefstate <> def_skip) or eof; + end; + +var + startpos: sourceposty; + anum: integer; + int1: integer; + bo1: boolean; + str1: string; + po1: pchar; + lstr1: lstringty; +begin + startpos:= sourcepos; + anum:= ftokennum; + nexttoken; + int1:= testnames(fto^,cskwords); + if int1 >= 0 then begin + nexttoken; + end; + case cskwordty(int1) of + cskw_ifdef,cskw_ifndef: begin + additem(fdefstates,integer(fdefstate),fdefstatecount); + if fdefstate <> def_skip then begin + if not (getname(lstr1) and + ((fdefines.find(lstr1) <> nil) xor + (cskwordty(int1) = cskw_ifndef))) then begin + fdefstate:= def_skip; + skiprest; + skipskip; + exit; //no skip rest + end + end + end; + cskw_else: begin + skiprest; + if fdefstate = def_skip then begin + if (fdefstatecount = 0) or + (defstatety(fdefstates[fdefstatecount-1]) <> def_skip) then begin + fdefstate:= def_none; + end; + end + else begin + if fdefstatecount > 0 then begin + fdefstate:= def_skip; + skipskip; + exit; + end; + end; + exit; //no skiprest + end; + cskw_endif: begin + if fdefstatecount > 0 then begin + dec(fdefstatecount); + fdefstate:= defstatety(fdefstates[fdefstatecount]); + end; + end; + else begin + if fdefstate <> def_skip then begin + case cskwordty(int1) of + cskw_include: begin + bo1:= getcstring(str1); + if not bo1 and checkoperator('<') then begin + po1:= fto^.value.po; + mark; + bo1:= findoperator('>'); + if bo1 then begin + pop; + str1:= getorigtext(po1); + if str1 <> '' then begin + setlength(str1,length(str1)-1); + end; + end + else begin + back; + end; + end + else begin + str1:= cstringtostring(str1); + end; + skiprest; + if bo1 then begin + callincludefile(filenamety(str1),startpos,anum); + skipcomment; + exit; //no skip of rest of line + end + end; + cskw_define: begin + str1:= getname; + if str1 <> '' then begin + fdefines.add(str1); + end; + end; + cskw_undef: begin + if getname(lstr1) then begin + fdefines.delete(lstr1); + end; + end; + end; + end; + end; + end; + skiprest; +end; + +function tcparser.skipcomment: boolean; +var + int1: integer; +// bo1: boolean; +// str1: ansistring; +begin + result:= false; + if fincomment = 0 then begin + inc(fincomment); + if (fto^.kind = tk_operator) and + ((fto^.op = '/') and checknextoperator('/') or + (fto^.op = '#') and isfirstnonwhitetoken) then begin + if fto^.op = '#' then begin + result:= true; + dec(fincomment); + parsepreprocdef; + inc(fincomment); + end + else begin + while not ((fto^.kind = tk_newline) or (fto^.kind = tk_fileend)) do begin + nexttoken; + end; + result:= true; + end; + end + else begin + if (fto^.kind = tk_operator) and (fto^.op = '/') and checknextoperator('*') then begin + result:= true; + int1:= 1; + while (int1 > 0) and (fto^.kind <> tk_fileend) do begin + if (fto^.kind = tk_operator) then begin + if fto^.op = '*' then begin + if checknextoperator('/') then begin + dec(int1); + end; + end + else begin + if (fto^.op = '/') and frecursivecomment then begin + if checknextoperator('*') then begin + inc(int1); + end; + end; + end; + end; + nexttoken; + end; + if int1 > 0 then begin + syntaxerror; + end; + end; + end; + dec(fincomment); + end; +end; + +function tcparser.skipstatement: boolean; +var +// int1: integer; + ch1: char; +begin + result:= false; +// int1:= 0; + repeat + ch1:= getnextoperator; + case ch1 of + ';','{','}': begin + result:= true; + break; + end; + end; + { + case ch1 of + '(': begin + inc(int1); + end; + ')': begin + dec(int1); + end; + ';': begin + if int1 <= 0 then begin + result:= true; + break; + end; + end; + end; + } + until ch1 = #0; +end; + +{ tconstparser } + +function tconstparser.getconsts(var ar: constinfoarty): string; //returns unitname + +var + count: integer; + + function additem: pconstinfoty; + begin + if high(ar) <= count then begin + setlength(ar,high(ar) + 33); + end; + result:= @ar[count]; + inc(count); + end; + +var + str1,str2: string; + ch1: char; + ident: pascalidentty; + resourceflag: boolean; + apos: pchar; + +begin + ar:= nil; + count:= 0; + result:= ''; + while not eof do begin + ident:= pascalidentty(getident); + if (ident = pid_unit) or (ident = pid_program) then begin + result:= getname; + end; + if (ident = pid_const) or (ident = pid_resourcestring) then begin + resourceflag:= ident = pid_resourcestring; + repeat + mark; + if getident >= 0 then begin + pop; + lasttoken; + break; + end; + str1:= getname; + if str1 <> '' then begin + ch1:= getoperator; + if ch1 = '=' then begin + skipwhitespace; + apos:= fto^.value.po; + case getvaluestring(str2) of + vk_string: begin + with additem^ do begin + valuetype:= vawstring; + name:= str1; + value:= pascalstringtostring(str2); + resource:= resourceflag; + offset:= apos-pchar(pointer(fscanner.fsource)); + len:= fto^.value.po-apos; + end; + end; + else begin + nexttoken; + end; + end; + pop; + end + else begin + back; + end; + end + else begin + pop; + nexttoken; + end; + until not checkoperator(';'); + end + else begin + nexttoken; + end; + end; + setlength(ar,count); +end; + +{ tfpcresstringparser } + +procedure tfpcresstringparser.getconsts(var ar: constinfoarty); +var + count: integer; + str1,str2: string; + apos: pchar; + mstr1: msestring; + po1: pchar; + i1: int32; + +begin + ar:= nil; + count:= 0; + while (fsyntaxerrorcount = 0) and not eof do begin + if testoperator('#') then begin + nextline; + end + else begin + if concatpascalname(str1) and checkoperator('=') then begin + skipwhitespace; + apos:= fto^.value.po; + if concatpascalstring(str2) then begin + additem(ar,typeinfo(constinfoarty),count); + with ar[count-1] do begin + valuetype:= vawstring; + name:= str1; + mstr1:= pascalstringtostring(str2); + setlength(str1,length(mstr1)); + po1:= pointer(str1); + for i1:= 1 to length(mstr1) do begin + po1^:= char(byte(mstr1[i1])); //utf8 is returned as #byte array, + inc(po1); + end; + value:= msestring(str1); //assume locale encoding, + //{$codepage} does not work with FPC 2.6.4 resourcestrings + offset:= apos-pchar(pointer(fscanner.fsource)); + len:= fto^.value.po-apos; + end; + end; + end + else begin + nextline; + end; + end; + end; + setlength(ar,count); +end; + +{ tresstringlistparser } + +constructor tresstringlistparser.create(const afilelist: tmseindexednamelist); +begin + inherited; + fcasesensitive:= true; +end; + +procedure tresstringlistparser.getconsts(var ar: constinfoarty); +type + residentty = (ri_stringtable,ri_begin,ri_end); +const + residents: array[residentty] of string = + ('STRINGTABLE','BEGIN','END'); + +var + count: integer; + + function additem: pconstinfoty; + begin + if high(ar) <= count then begin + setlength(ar,high(ar) + 33); + end; + result:= @ar[count]; + inc(count); + end; + +var + str1,str2: string; + ident: residentty; + apos: pchar; + +begin + setidents(residents); + ar:= nil; + count:= 0; + while (fsyntaxerrorcount = 0) and not eof do begin + ident:= residentty(getfirstident); + if (ident = ri_stringtable) then begin + repeat + until (residentty(getfirstident) = ri_begin) or eof; + while (fsyntaxerrorcount = 0) and not eof do begin + nextline; + if fto^.kind = tk_whitespace then begin + str1:= getname; + if str1 = '' then begin + syntaxerror; + end + else begin + if checkoperator(',') then begin + skipwhitespace; + apos:= fto^.value.po; + if getvaluestring(str2) = vk_string then begin + with additem^ do begin + valuetype:= vawstring; + name:= str1; + value:= msestring(cstringtostring(str2)); + offset:= apos-pchar(pointer(fscanner.fsource)); + len:= fto^.value.po-apos; + end; + end + else begin + syntaxerror; + end; + end + else begin + syntaxerror; + end; + end; + end + else begin + if residentty(getident) <> ri_end then begin + syntaxerror; + end; + break; + end; + end; + end + else begin + nextline; + end; + end; + setlength(ar,count); +end; + + +end. diff --git a/mseide-msegui/lib/common/designutils/msepropertyeditors.pas b/mseide-msegui/lib/common/designutils/msepropertyeditors.pas new file mode 100644 index 0000000..d42c452 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msepropertyeditors.pas @@ -0,0 +1,6158 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepropertyeditors; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + classes,mclasses,TypInfo,msedesignintf,msetypes,msestrings,sysutils, + msearrayutils,msedatalist, + msemenus,mseevent,msegui,mseglob,mseguiglob, + mseclasses,mseforms,msegraphics,mserichstring; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + bmpfiledialogstatname = 'bmpfile.sta'; + numcharchar = msechar('['); + +type + + defaultenumerationty = (null); + defaultsetty = set of defaultenumerationty; + + tpropertyeditor = class; + propertyeditorarty = array of tpropertyeditor; + + propinstancety = record + instance: tobject; + propinfo: ppropinfo; + end; + propinstancearty = array of propinstancety; + ppropinstancearty = ^propinstancearty; + + iobjectinspector = interface(inullinterface) + procedure propertymodified(const sender: tpropertyeditor); + function getproperties(const objects: objectarty; + const amodule: tmsecomponent; + const acomponent: tcomponent): propertyeditorarty; +// procedure componentnamechanged(comp: tcomponent; newname: string); + function getmatchingmethods(const sender: tpropertyeditor; atype: ptypeinfo): msestringarty; + end; + + propertystatety = (ps_expanded,ps_subproperties,ps_volatile, + ps_refresh, //needs refresh by modified + ps_valuelist,ps_dialog,ps_sortlist,ps_owned, + ps_noadditems,ps_nodeleteitems, + ps_isordprop,ps_modified,ps_candefault,ps_component,ps_subprop, + ps_selected,ps_canselect,ps_refreshall, + ps_local, //do not display foreign components + ps_link); //do not display selected components + propertystatesty = set of propertystatety; + + iremotepropertyeditor = interface(inullinterface) + function getordvalue(const index: integer = 0): integer; + procedure setordvalue(const value: longword); overload; + procedure setordvalue(const index: integer; const value: longword); overload; + procedure setbitvalue(const value: boolean; const bitindex: integer); + function getint64value(const index: integer = 0): int64; + procedure setint64value(const value: int64); overload; + procedure setint64value(const index: integer; const value: int64); overload; + function getpointervalue(const index: integer = 0): pointer; + procedure setpointervalue(const value: pointer); overload; + procedure setpointervalue(const index: integer; const value: pointer); overload; + function getfloatvalue(const index: integer = 0): extended; + procedure setfloatvalue(const value: extended); + function getcurrencyvalue(const index: integer = 0): currency; + procedure setcurrencyvalue(const value: currency); + function getstringvalue(const index: integer = 0): string; + procedure setstringvalue(const value: string); + function getutf8stringvalue(const index: integer = 0):utf8string; + procedure setutf8stringvalue(const value: utf8string); + function getmsestringvalue(const index: integer = 0; + const raw: boolean = false): msestring; + procedure setmsestringvalue(const value: msestring; + const raw: boolean = false); + function getvariantvalue(const index: integer = 0): variant; + procedure setvariantvalue(const value: variant); + function getparenteditor: tpropertyeditor; + + function getmethodvalue(const index: integer = 0): tmethod; + procedure setmethodvalue(const value: tmethod); + function getselected: boolean; + procedure setselected(const avalue: boolean); + property selected: boolean read getselected write setselected; + function getselectedpropinstances: objectarty; + end; + + tpropertyeditor = class(tnullinterfacedobject) + private + function getexpanded: boolean; + procedure setexpanded(const Value: boolean); + function getcount: integer; + function getselected: boolean; + procedure setselected(const avalue: boolean); + function getlinkcomponent: tcomponent; + protected + fsortlevel: integer; + ftypeinfo: ptypeinfo; + fstate: propertystatesty; + fparenteditor: tpropertyeditor; + fname: msestring; + fdesigner: idesigner; + fmodule: tmsecomponent; + fcomponent: tcomponent; + fobjectinspector: iobjectinspector; + fprops: propinstancearty; + fremote: iremotepropertyeditor; + procedure properror; + + function instance(const index: integer = 0): tobject; + function typedata: ptypedata; + + function gettypinfo: ptypeinfo; virtual; + function getordvalue(const index: integer = 0): integer; virtual; + procedure setordvalue(const value: longword); virtual; overload; + procedure setordvalue(const index: integer; const value: longword); + virtual; overload; + function getint64value(const index: integer = 0): int64; virtual; + procedure setint64value(const value: int64); virtual; overload; + procedure setint64value(const index: integer; const value: int64); + virtual; overload; + function getpointervalue(const index: integer = 0): pointer; virtual; + procedure setpointervalue(const value: pointer); overload; virtual; + procedure setpointervalue(const index: integer; const value: pointer); + virtual; overload; + + procedure setbitvalue(const value: boolean; const bitindex: integer); + virtual; + function getfloatvalue(const index: integer = 0): extended; virtual; + procedure setfloatvalue(const value: extended); virtual; + function getcurrencyvalue(const index: integer = 0): currency; virtual; + procedure setcurrencyvalue(const value: currency); virtual; + function getstringvalue(const index: integer = 0): string; virtual; + procedure setstringvalue(const value: string); virtual; + function getutf8stringvalue(const index: integer = 0): utf8string virtual; + procedure setutf8stringvalue(const value: utf8string) virtual; + function getmsestringvalue(const index: integer = 0; + const raw: boolean = false): msestring; virtual; + procedure setmsestringvalue(const value: msestring; + const raw: boolean = false); virtual; + function getvariantvalue(const index: integer = 0): variant; virtual; + procedure setvariantvalue(const value: variant); virtual; + + function decodemsestring(const avalue: msestring): msestring; + function encodemsestring(const avalue: msestring): msestring; + + function getmethodvalue(const index: integer = 0): tmethod; + procedure setmethodvalue(const value: tmethod); + function getparenteditor: tpropertyeditor; + function queryselectedpropinstances: objectarty; + + procedure modified; virtual; + function getdefaultstate: propertystatesty; virtual; + procedure setsubprop; virtual; + function getvalueeditor: tpropertyeditor; virtual; + function getlinksource: tcomponent; virtual; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); virtual; + destructor destroy; override; + procedure setremote(intf: iremotepropertyeditor); + procedure updatedefaultvalue; virtual; + function canrevert: boolean; virtual; + procedure copyproperty(const asource: tobject); virtual; + + function propertyname: msestring; virtual; + function name: msestring; virtual; + function allequal: boolean; virtual; + function subproperties: propertyeditorarty; virtual; + function props: propinstancearty; + function rootprops: propinstancearty; + function propowner: componentarty; + //value of classproperty + + procedure setvalue(const value: msestring); virtual; + function getvalue: msestring; virtual; + function getvalues: msestringarty; virtual; + property state: propertystatesty read fstate; + function sortlevel: integer; + procedure dragbegin(var accept: boolean); virtual; + procedure dragover(const sender: tpropertyeditor; var accept: boolean); virtual; + procedure dragdrop(const sender: tpropertyeditor); virtual; + procedure dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); virtual; + procedure dokeydown(var ainfo: keyeventinfoty); virtual; + procedure edit(); virtual; + procedure focused() virtual; + procedure navigevent(); virtual; + property typinfo: ptypeinfo read gettypinfo; + property count: integer read getcount; + property expanded: boolean read getexpanded write setexpanded; + property selected: boolean read getselected write setselected; + property module: tmsecomponent read fmodule; + property component: tcomponent read fcomponent; + property parenteditor: tpropertyeditor read fparenteditor; + property valueeditor: tpropertyeditor read getvalueeditor; + property linksource: tcomponent read getlinksource; + property linkcomponent: tcomponent read getlinkcomponent; + end; + + propertyeditorclassty = class of tpropertyeditor; + + tstringpropertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tutf8stringpropertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + trefreshstringpropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tnamepropertyeditor = class(tstringpropertyeditor) + procedure setvalue(const value: msestring); override; + end; + + tfontnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tmsestringpropertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + trichstringpropertyeditor = class(tmsestringpropertyeditor) + public + procedure edit; override; + end; + + tordinalpropertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tvolatileordinalpropertyeditor = class(tordinalpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tint64propertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tcharpropertyeditor = class(tordinalpropertyeditor) + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + twidecharpropertyeditor = class(tordinalpropertyeditor) + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tbooleanpropertyeditor = class(tordinalpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + end; + + tvolatilebooleanpropertyeditor = class(tbooleanpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + trefreshbooleanpropertyeditor = class(tbooleanpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + trealpropertyeditor = class(tpropertyeditor) + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + trealtypropertyeditor = class(tpropertyeditor) + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tcurrencypropertyeditor = class(tpropertyeditor) + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tdatetimepropertyeditor = class(tpropertyeditor) + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tvariantpropertyeditor = class(tpropertyeditor) + protected + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tenumpropertyeditor = class(tordinalpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + function gettypeinfo: ptypeinfo; virtual; + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + end; + + tshortcutpropertyeditor = class(tenumpropertyeditor) + protected + fsc1: boolean; + fscar: boolean; + function getvaluetext(const avalue: shortcutty): msestring; + function texttovalue(const atext: msestring): shortcutty; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + end; + + tshortcutarpropertyeditor = class(tshortcutpropertyeditor) + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + end; + + tcolorpropertyeditor = class(tenumpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + end; + + tclasspropertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + function checkfreeoptionalclass: boolean; + function dispname: msestring; virtual; + public + function getvalue: msestring; override; + function subproperties: propertyeditorarty; override; + end; + + toptionalclasspropertyeditor = class(tclasspropertyeditor) + protected + function getniltext: msestring; virtual; + function getinstance: tpersistent; virtual; + function getdefaultstate: propertystatesty; override; + procedure deleteinstance; + public + function canrevert: boolean; override; + procedure setvalue(const avalue: msestring); override; + function getvalue: msestring; override; + procedure edit; override; + end; + + ppersistent = ^tpersistent; + tparentclasspropertyeditor = class(toptionalclasspropertyeditor) + protected + function getniltext: msestring; override; + function getinstancepo(acomponent: tobject): ppersistent; virtual; abstract; + function getinstance: tpersistent; override; + public + function subproperties: propertyeditorarty; override; + procedure edit; override; + end; + + tparentfontpropertyeditor = class(tparentclasspropertyeditor) + protected + function getinstancepo(acomponent: tobject): ppersistent; override; + end; + + + //no solution found to link to streamed tpersistent or tobject, + //fork of classes.pp necessary. :-( +{ + tlinkedobjectpropertyeditor = class(tclasspropertyeditor) + protected +// function issubcomponent(const index: integer = 0): boolean; + function getdefaultstate: propertystatesty; override; + procedure checkobj(const avalue: tobject); virtual; + function filterobj(const aobj: tobject): boolean; virtual; + public + function allequal: boolean; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + function getvalues: msestringarty; override; + end; +} + tcomponentpropertyeditor = class(tclasspropertyeditor) + protected + function issubcomponent(const index: integer = 0): boolean; virtual; + function getdefaultstate: propertystatesty; override; + procedure checkcomponent(const avalue: tcomponent); virtual; + function filtercomponent(const acomponent: tcomponent): boolean; virtual; + function getlinksource: tcomponent; override; + public + procedure edit; override; + function allequal: boolean; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + function getvalues: msestringarty; override; + end; + + tsubcomponentpropertyeditor = class(tcomponentpropertyeditor) + protected + function issubcomponent(const index: integer = 0): boolean; override; + end; + + tcomponentinterfacepropertyeditor = class(tcomponentpropertyeditor) + private + fintfinfo: ptypeinfo; + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + function getintfinfo: ptypeinfo; virtual; abstract; + public + procedure updatedefaultvalue; override; + end; + + tsisterwidgetpropertyeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + function getdefaultstate: propertystatesty; override; + public +// function getvalues: msestringarty; override; + end; + + tnochildrenwidgetpropertyeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + function getdefaultstate: propertystatesty; override; + public +// function getvalues: msestringarty; override; + end; + + tchildwidgetpropertyeditor = class(tcomponentpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tlocalcomponentpropertyeditor = class(tcomponentpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tlinkcomponentpropertyeditor = class(tcomponentpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tlocallinkcomponentpropertyeditor = class(tcomponentpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tsetpropertyeditor = class; + tsetelementeditor = class(tpropertyeditor) + protected +// fparent: tsetpropertyeditor; + findex: integer; + function getdefaultstate: propertystatesty; override; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo; + const aparent: tsetpropertyeditor; const aindex: integer); + reintroduce; virtual; + procedure updatedefaultvalue; override; + function canrevert: boolean; override; + function allequal: boolean; override; + function propertyname: msestring; override; + function name: msestring; override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + procedure setvalue(const value: msestring); override; + end; + + setelementeditorclassty = class of tsetelementeditor; + + tsetpropertyeditor = class(tordinalpropertyeditor) + protected + finvisibleitems: tintegerset; + felementeditorclass: setelementeditorclassty; + function getdefaultstate: propertystatesty; override; + function getinvisibleitems: tintegerset; virtual; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + function subproperties: propertyeditorarty; override; + end; + + tvolatilesetpropertyeditor = class(tsetpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + + end; + + tmethodpropertyeditor = class(tpropertyeditor) + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); override; + function getdefaultstate: propertystatesty; override; + function allequal: boolean; override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + procedure setvalue(const value: msestring); override; + procedure navigevent(); override; + function method: tmethod; + end; + + tdialogclasspropertyeditor = class(tclasspropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tbitmappropertyeditor = class(tdialogclasspropertyeditor) + public + procedure edit; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + end; + + tstringspropertyeditor = class(tdialogclasspropertyeditor) + protected + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + public + procedure edit; override; + function getvalue: msestring; override; + end; + + ttextstringspropertyeditor = class(tdialogclasspropertyeditor) + protected + fmodalresult: modalresultty; + forigtext: msestringarty; + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure doafterclosequery(var amodalresult: modalresultty); virtual; + function getsyntaxindex: integer; virtual; + function gettestbutton: boolean; virtual; + function getutf8: boolean; virtual; + function getcaption: msestring; virtual; + procedure updateline(var aline: ansistring); virtual; + function ismsestring: boolean; virtual; + public + procedure edit; override; + procedure setvalue(const avalue: msestring); override; + function getvalue: msestring; override; + end; + + listeditformkindty = (lfk_none,lfk_msestring,lfk_real,lfk_integer, + lfk_msestringint,lfk_complex); + + tdatalistpropertyeditor = class(tdialogclasspropertyeditor) + protected + formkind: listeditformkindty; + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure checkformkind; + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + function getvalue: msestring; override; + end; + + toptionaldatalistpropertyeditor = class(tdatalistpropertyeditor) + protected + function getniltext: msestring; virtual; + function getinstance: tpersistent; virtual; + procedure deleteinstance; + function getdefaultstate: propertystatesty; override; + public + function canrevert: boolean; override; + procedure setvalue(const avalue: msestring); override; + function getvalue: msestring; override; + procedure edit; override; + end; + + tmsestringdatalistpropertyeditor = class(tdialogclasspropertyeditor) + procedure edit; override; + function getvalue: msestring; override; + protected + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + function getdefaultstate: propertystatesty; override; + end; + + tdoublemsestringdatalistpropertyeditor = class(tdialogclasspropertyeditor) + procedure edit; override; + function getvalue: msestring; override; + protected + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + function getdefaultstate: propertystatesty; override; + end; + + tmsestringintdatalistpropertyeditor = class(tdialogclasspropertyeditor) + procedure edit; override; + function getvalue: msestring; override; + protected + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + function getdefaultstate: propertystatesty; override; + end; + +const + propmaxarraycount = 100; + +type + + tarraypropertyeditor = class; + + tarrayelementeditor = class(tpropertyeditor,iremotepropertyeditor) + private + feditor: tpropertyeditor; + protected + findex: integer; + function gettypinfo: ptypeinfo; override; + + procedure doinsert(const sender: tobject); + procedure doappend(const sender: tobject); + procedure dodelete(const sender: tobject); + + function getordvalue(const index: integer = 0): integer; override; + procedure setordvalue(const value: longword); override; overload; + procedure setordvalue(const index: integer; const value: longword); + override; overload; + function getint64value(const index: integer = 0): int64; override; + procedure setint64value(const value: int64); override; overload; + procedure setint64value(const index: integer; const value: int64); + override; overload; + function getpointervalue(const index: integer = 0): pointer; override; + procedure setpointervalue(const value: pointer); override; overload; + procedure setpointervalue(const index: integer; const value: pointer); + override; overload; + + procedure setbitvalue(const value: boolean; const bitindex: integer); + override; + function getfloatvalue(const index: integer = 0): extended; override; + procedure setfloatvalue(const value: extended); override; + function getstringvalue(const index: integer = 0): string; override; + procedure setstringvalue(const value: string); override; + function getmsestringvalue(const index: integer = 0; + const raw: boolean = false): msestring; override; + procedure setmsestringvalue(const value: msestring; + const raw: boolean = false); override; + + function getselectedpropinstances: objectarty; virtual; + + function getdefaultstate: propertystatesty; override; + function getvalueeditor: tpropertyeditor; override; + function getlinksource: tcomponent; override; + public + constructor create(aindex: integer; aparenteditor: tarraypropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); reintroduce; + virtual; + destructor destroy; override; + function canrevert: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + procedure edit; override; + procedure focused() override; + function name: msestring; override; + function subproperties: propertyeditorarty; override; + procedure dragbegin(var accept: boolean); override; + procedure dragover(const sender: tpropertyeditor; var accept: boolean); override; + procedure dragdrop(const sender: tpropertyeditor); override; + procedure dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + property index:int32 read findex; + end; + + elementeditorclassty = class of tarrayelementeditor; + elementeditorarty = array of tarrayelementeditor; + + tarraypropertyeditor = class(tclasspropertyeditor) + private + fsubprops: elementeditorarty; + procedure doappend(const sender: tobject); + procedure doinsert(const sender: tobject); + protected + function getdefaultstate: propertystatesty; override; + function geteditorclass: propertyeditorclassty; virtual; + function getelementeditorclass: elementeditorclassty; virtual; + procedure itemmoved(const source,dest: integer); virtual; + function getitemtypeinfo: ptypeinfo; virtual; + + function itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; virtual; + function itemgetlinksource( + const sender: tarrayelementeditor): tcomponent; virtual; + procedure itemsetvalue(const sender: tarrayelementeditor; + const value: msestring); virtual; + function itemgetvalue(const sender: tarrayelementeditor): msestring; + virtual; + function itemgetvalues( + const sender: tarrayelementeditor): msestringarty; virtual; + procedure itemedit(const sender: tarrayelementeditor); virtual; + procedure itemfocused(const sender: tarrayelementeditor) virtual; + function itemname( + const sender: tarrayelementeditor): msestring; virtual; + function itemsubproperties( + const sender: tarrayelementeditor): propertyeditorarty; virtual; + + public + function itemprefix: msestring; virtual; + procedure move(const curindex,newindex: integer); virtual; + function allequal: boolean; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + function subproperties: propertyeditorarty; override; + function name: msestring; override; + procedure dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + end; + + tconstelementeditor = class(tarrayelementeditor) + protected + fvalue: msestring; + public + constructor create(const avalue: msestring; + aindex: integer; aparenteditor: tarraypropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); reintroduce; + procedure dragdrop(const sender: tpropertyeditor); override; + function getvalue: msestring; override; + end; + + tconstarraypropertyeditor = class(tarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function allequal: boolean; override; + function getvalue: msestring; override; + function name: msestring; override; + procedure setvalue(const value: msestring); override; + end; + + tcollectionpropertyeditor = class; + + tcollectionitemeditor = class(tpropertyeditor,iremotepropertyeditor) + private + findex: integer; + feditor: tpropertyeditor; + protected + function getdefaultstate: propertystatesty; override; +// function getordvalue(const index: integer = 0): integer; +// procedure setordvalue(const value: longword); overload; +// procedure setordvalue(const index: integer; const value: longword); overload; + function getpointervalue(const index: integer = 0): pointer; override; + procedure setpointervalue(const value: pointer); override; overload; + procedure setpointervalue(const index: integer; const value: pointer); + override; overload; + procedure doinsert(const sender: tobject); + procedure doappend(const sender: tobject); + procedure dodelete(const sender: tobject); + function getselectedpropinstances: objectarty; + public + constructor create(aindex: integer; aparenteditor: tcollectionpropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); reintroduce; + destructor destroy; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + procedure edit; override; + function subproperties: propertyeditorarty; override; + function name: msestring; override; + + procedure dragbegin(var accept: boolean); override; + procedure dragover(const sender: tpropertyeditor; var accept: boolean); override; + procedure dragdrop(const sender: tpropertyeditor); override; + procedure dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + end; + + collectionitemeditorclassty = class of tcollectionitemeditor; + + tcollectionpropertyeditor = class(tclasspropertyeditor) + private + procedure doinsert(const sender: tobject); + procedure doappend(const sender: tobject); + protected + function getdefaultstate: propertystatesty; override; + procedure itemmoved(const source,dest: integer); virtual; + public + function name: msestring; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + function subproperties: propertyeditorarty; override; + procedure dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + end; + + tpersistentarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + toptionalpersistentarraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function getniltext: msestring; virtual; + function getinstance: tpersistent; virtual; + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + procedure edit; override; + end; + + tmenuarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + +{ + tordinalelementeditor = class(tarrayelementeditor) + public + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + end; +} + tclasselementeditor = class(tclasspropertyeditor) + protected + function dispname: msestring; override; + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + end; + + tmenuelementeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tintegerarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tsetarrayelementeditor = class(tarrayelementeditor) + public + constructor create(aindex: integer; aparenteditor: tarraypropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); override; + end; +{ + tsetarrayelementpropertyeditor = class(tsetpropertyeditor) + public + function subproperties: propertyeditorarty; override; + end; +} + tsetarraypropertyeditor = class(tarraypropertyeditor) + protected + function getelementeditorclass: elementeditorclassty; override; + function geteditorclass: propertyeditorclassty; override; + end; + + tcolorarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function getitemtypeinfo: ptypeinfo; override; + end; + + tstringarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tmsestringarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + trealarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + trecordpropertyeditor = class(tpropertyeditor) + private + fsubproperties: propertyeditorarty; +// fname: string; + protected + function getdefaultstate: propertystatesty; override; + procedure setsubprop; override; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; const aname: string; + const subprops: propertyeditorarty); reintroduce; + destructor destroy; override; + function allequal: boolean; override; +// function name: msestring; override; + function subproperties: propertyeditorarty; override; + function getvalue: msestring; override; + end; + + propertyeditorinfoty = record + propertytype: ptypeinfo; + propertyownerclass: tclass; + propertyname: string; + editorclass: propertyeditorclassty; + editorclasslevel: integer; + end; + ppropertyeditorinfoty = ^propertyeditorinfoty; + + tpropertyeditors = class(tdynamicdatalist) + private + function getitems(const index: integer): ppropertyeditorinfoty; + protected + procedure freedata(var data); override; + procedure beforecopy(var data); override; + procedure add(apropertytype: ptypeinfo; + apropertyownerclass: tclass; const apropertyname: string; + aeditorclass: propertyeditorclassty); + public + constructor create; override; + function geteditorclass(apropertytype: ptypeinfo; + apropertyownerclass: tclass; apropertyname: string): propertyeditorclassty; + property items[const index: integer]: ppropertyeditorinfoty read getitems; default; + end; + +var + fontaliasnames: msestringarty; + +function textpropertyfont: tfont; +function propertyeditors: tpropertyeditors; +procedure registerpropertyeditor(propertytype: ptypeinfo; + propertyownerclass: tclass; const propertyname: string; + editorclass: propertyeditorclassty); +function imagefilepropedit(out afilename: filenamety; + out aformat: string): modalresultty; +function getcomponentpropname(const acomp: tcomponent): msestring; +function wantpropertydelete(const fromval,toval: int32): boolean; + +implementation +uses + mseformatstr,msebits,msearrayprops,msebitmap, + msefiledialog,mseimagelisteditor,msereal,msewidgets, + mseactions,msehash,msegraphutils, + msestringlisteditor,msedoublestringlisteditor,msestringintlisteditor, + msereallisteditor,msedoublereallisteditor,msecomptree, + mseintegerlisteditor,mseact,msesys, + msecolordialog,msememodialog, + mseshapes,msestockobjects,msetexteditor,mserichstringeditor, + msegraphicstream,msedate, + mseformatbmpicoread{$ifdef FPC},mseformatjpgread,mseformatpngread, + mseformatpnmread,mseformattgaread,mseformatxpmread,mseformattiffread{$endif}, + msestat,msestatfile,msefileutils, + msedesigner,variants,mseeditglob,msepropertyeditorsmodule,objectinspector; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + methodsortlevel = 100; + falsename = 'False'; + truename = 'True'; + +type + tmsecomponent1 = class(tmsecomponent); + twidget1 = class(twidget); + tcustomcaptionframe1 = class(tcustomcaptionframe); + tdesigner1 = class(tdesigner); + tdatalist1 = class(tdatalist); + +var + fpropertyeditors: tpropertyeditors; + ftextpropertyfont: tfont; + mo: tmsepropertyeditorsmo; + +function wantpropertydelete(const fromval,toval: int32): boolean; +begin + result:= (toval < fromval) or + askok(mo.c[ord(wishdelete)]+' '+inttostrmse(fromval) + + ' '+mo.c[ord(str_to)]+' '+ inttostrmse(toval) + '?', + stockobjects.captions[sc_confirmation]); +end; + +function getcomponentpropname(const acomp: tcomponent): msestring; +begin + if acomp = nil then begin + result:= '' + end + else begin + result:= msestring(designer.getcomponentname(acomp)); + end; + if result = '' then begin + result:= msestring(ownernamepath(acomp)); + end; +end; + +function imagefilepropedit(out afilename: filenamety; + out aformat: string): modalresultty; +var + dialog: tfiledialog; + statfile1: tstatfile; +begin + statfile1:= tstatfile.create(nil); + dialog:= tfiledialog.create(nil); + dialog.name:= 'filedialog'; //for statvarname + try + aformat:= ''; + afilename:= ''; + statfile1.options:= [sfo_memory]; + statfile1.filename:= bmpfiledialogstatname; + with dialog,controller do begin + statfile1.options:= [sfo_memory]; + statfile1.filename:= bmpfiledialogstatname; + filterlist.asarraya:= graphicfilefilternames; + filterlist.asarrayb:= graphicfilefiltermasks; + captionopen:= mo.c[ord(openimagefile)];; + statfile:= statfile1; + statfile.readstat; + filename:= filedir(filename); + result:= execute; + if result = mr_ok then begin + aformat:= graphicfilefilterlabel(filterindex); + afilename:= filename; + statfile.writestat; + end; + end; + finally + dialog.free; + statfile1.free; + end; +end; + +procedure checkdatalistnostreaming(const sender: tpropertyeditor; + var defaultstate: propertystatesty); +var + datalist1: tdatalist1; +begin + datalist1:= tdatalist1(sender.getpointervalue); + if (datalist1 = nil) {or + (ilo_nostreaming in datalist1.finternaloptions)} then begin + exclude(defaultstate,ps_dialog); + end; +end; + +function textpropertyfont: tfont; +begin + if ftextpropertyfont = nil then begin + ftextpropertyfont:= tfont.create; + end; + result:= ftextpropertyfont; +end; + +function getpointerprop1(instance: tobject; propinfo : ppropinfo): pointer; +begin +{$ifdef CPU64} + result:= pointer(ptruint(getint64prop(instance,propinfo))); +{$else} + result:= pointer(ptruint(getordprop(instance,propinfo))); +{$endif} +end; + +function propertyeditors: tpropertyeditors; +begin + if fpropertyeditors = nil then begin + fpropertyeditors:= tpropertyeditors.create; + end; + result:= fpropertyeditors; +end; + +procedure registerpropertyeditor(propertytype: ptypeinfo; + propertyownerclass: tclass; const propertyname: string; + editorclass: propertyeditorclassty); +begin + propertyeditors.add(propertytype,propertyownerclass,propertyname,editorclass); +end; + +function settostrings(const value: tintegerset; const typeinfo: ptypeinfo): msestringarty; +var + int1,int2: integer; +begin + setlength(result,32); + int2:= 0; + for int1:= 0 to 31 do begin + if longword(value) and bits[int1] <> 0 then begin + result[int2]:= msestring(getenumname(typeinfo,int1)); + inc(int2); + end; + end; + setlength(result,int2); +end; + +function stringstoset(const value: stringarty; const typeinfo: ptypeinfo): tintegerset; +var + ar1: array[0..31] of boolean; + int1,int2: integer; + typedata: ptypedata; + enumtype: ptypeinfo; +begin + fillchar(ar1,sizeof(ar1),0); + typedata:= gettypedata(typeinfo); + enumtype:= typedata^.comptype{$ifndef FPC}^{$endif}; + for int1:= 0 to high(value) do begin + int2:= getenumvalue(enumtype,value[int1]); + if (int2 < 0) then begin + raise exception.Create( + ansistring(mo.c[ord(invalidsetitem)])+': '''+value[int1]+''''); + end; + ar1[int2]:= true; + end; + result:= []; + for int1:= 0 to gettypedata(enumtype)^.MaxValue do begin + if ar1[int1] then begin + result:= tintegerset(longword(result) or bits[int1]); + end; + end; +end; + +{ tpropertyeditors } + +constructor tpropertyeditors.create; +begin + inherited; + fsize:= sizeof(propertyeditorinfoty); +end; + +procedure tpropertyeditors.add(apropertytype: ptypeinfo; + apropertyownerclass: tclass; const apropertyname: string; + aeditorclass: propertyeditorclassty); +var + info: propertyeditorinfoty; +// po1: ppropertyeditorinfoty; +// bo1: boolean; +// int1: integer; + class1: tclass; + +begin + with info do begin + propertytype:= apropertytype; + propertyownerclass:= apropertyownerclass; + propertyname:= uppercase(apropertyname); + editorclass:= aeditorclass; + class1:= aeditorclass; + editorclasslevel:= 0; + while (class1 <> tpropertyeditor) do begin + class1:= class1.ClassParent; + inc(editorclasslevel); + end; + end; + { + po1:= pointer(fdatapo); + bo1:= false; + for int1:= 0 to fcount - 1 do begin + with po1^ do begin + if (propertytype = info.propertytype) and (componentclass = info.componentclass) and + (propertyname = info.propertyname) then begin + editorclass:= info.editorclass; + bo1:= true; + break; + end; + end; + inc(po1); + end; + } + adddata(info); +end; + +procedure tpropertyeditors.freedata(var data); +begin + propertyeditorinfoty(data).propertyname:= ''; + inherited; +end; + +procedure tpropertyeditors.beforecopy(var data); +begin + stringaddref(propertyeditorinfoty(data).propertyname); +end; + +function tpropertyeditors.getitems( + const index: integer): ppropertyeditorinfoty; +begin + result:= ppropertyeditorinfoty(getitempo(index)); +end; + +function tpropertyeditors.geteditorclass(apropertytype: ptypeinfo; + apropertyownerclass: tclass; + apropertyname: string): propertyeditorclassty; + + //todo: optimize +var + int1: integer; + po1: ppropertyeditorinfoty; + kind: ttypekind; + class1: tclass; + po2: ptypeinfo; + int2: integer; + namelevel,propertyownerclasslevel,typeclasslevel,propertyeditorlevel: integer; + anamelevel,apropertyownerclasslevel,atypeclasslevel: integer; + + procedure savelevel; + begin + namelevel:= anamelevel; + propertyownerclasslevel:= apropertyownerclasslevel; + typeclasslevel:= atypeclasslevel; + propertyeditorlevel:= po1^.editorclasslevel; + result:= po1^.editorclass; + end; + +begin + apropertyname:= uppercase(apropertyname); + result:= tpropertyeditor; + po1:= ppropertyeditorinfoty(fdatapo); + kind:= apropertytype^.Kind; + namelevel:= 1; + propertyownerclasslevel:= bigint; + typeclasslevel:= bigint; + propertyeditorlevel:= 0; + + for int1:= 0 to count - 1 do begin + if kind = po1^.propertytype^.Kind then begin + if (po1^.propertyownerclass <> nil) then begin + class1:= apropertyownerclass; + int2:= 0; + while (class1 <> nil) and (class1 <> po1^.propertyownerclass) do begin + class1:= class1.ClassParent; + inc(int2) + end; + if class1 <> nil then begin + apropertyownerclasslevel:= int2; + end + else begin + apropertyownerclasslevel:= bigint + 1; + end; + end + else begin + apropertyownerclasslevel:= bigint - 1; + end; + + if po1^.propertyname = '' then begin + anamelevel:= 1; + end + else begin + if po1^.propertyname = apropertyname then begin + anamelevel:= 3; + end + else begin + anamelevel:= 0; + end; + end; + + if kind = tkclass then begin + {$ifdef FPC} + po2:= gettypedata(apropertytype)^.classtype.classinfo; + {$else} + po2:= apropertytype; + {$endif} + int2:= 0; + while (po2 <> nil) and (po2 <> po1^.propertytype) do begin + inc(int2); + {$ifdef FPC} + po2:= gettypedata(po2)^.parentinfo; + {$else} + po2:= ptypeinfo(gettypedata(po2)^.parentinfo); + if po2 <> nil then begin + po2:= pptypeinfo(po2)^; + end; + {$endif} + end; + if (po2 <> nil) then begin + atypeclasslevel:= int2 + end + else begin + atypeclasslevel:= bigint + 1; + end; + end + else begin + if (po1^.propertytype = apropertytype) {$ifdef FPC} + or (po1^.propertytype^.name = apropertytype^.name) {$endif} then begin + atypeclasslevel:= 0; + end + else begin + atypeclasslevel:= 1; + if (kind = tkset) and + (po1^.propertytype <> typeinfo(defaultsetty)) then begin + atypeclasslevel:= 2; + end; + if (kind = tkenumeration) and + (po1^.propertytype <> typeinfo(defaultenumerationty)) then begin + atypeclasslevel:= 2; + end; + end; + end; + + if kind = tkclass then begin + if (typeclasslevel > atypeclasslevel) and (anamelevel = 1) and + (apropertyownerclasslevel = bigint-1) then begin + savelevel; + end + else begin + if typeclasslevel >= atypeclasslevel then begin + if (propertyownerclasslevel > apropertyownerclasslevel) and + (anamelevel = 1) then begin + savelevel; + end + else begin + if propertyownerclasslevel >= apropertyownerclasslevel then begin + if namelevel < anamelevel then begin + savelevel; + end + else begin + if (namelevel = anamelevel) and + (propertyeditorlevel <= po1^.editorclasslevel) then begin + savelevel; + end; + end; + end; + end; + end; + end; + end + else begin + if typeclasslevel > atypeclasslevel then begin + savelevel; + end + else begin + if typeclasslevel >= atypeclasslevel then begin + //do not overwrite exact type match + if (propertyownerclasslevel > apropertyownerclasslevel) and + (anamelevel = 1) then begin + savelevel; + end + else begin + if propertyownerclasslevel >= apropertyownerclasslevel then begin + if namelevel < anamelevel then begin + savelevel; + end + else begin + if namelevel = anamelevel then begin + if (typeclasslevel = atypeclasslevel) and + (propertyeditorlevel <= po1^.editorclasslevel) then begin + savelevel; + end; + end; + end; + end; + end; + end; + end; + { + if (propertyownerclasslevel > apropertyownerclasslevel) and (anamelevel = 1) then begin + savelevel; + end + else begin + if propertyownerclasslevel >= apropertyownerclasslevel then begin + if namelevel < anamelevel then begin + savelevel; + end + else begin + if namelevel = anamelevel then begin + if typeclasslevel > atypeclasslevel then begin + savelevel; + end + else begin + if (typeclasslevel = atypeclasslevel) and + (propertyeditorlevel <= po1^.editorclasslevel) then begin + savelevel; + end; + end; + end; + end; + end; + end; + } + end; + end; + inc(po1); + end; +end; + +{ tpropertyeditor } + +constructor tpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fmodule:= amodule; + fcomponent:= acomponent; + fdesigner:= adesigner; + ftypeinfo:= atypeinfo; + fobjectinspector:= aobjectinspector; + if aprops <> nil then begin + fprops:= copy(aprops); //!!!! crash whithout copy, why ? +// reallocarray(fprops,sizeof(props[0])); + fname:= msestring(fprops[0].propinfo^.Name); + end; + fstate:= getdefaultstate; + updatedefaultvalue; +end; + +destructor tpropertyeditor.destroy; +begin + pointer(fdesigner):= nil; + pointer(fobjectinspector):= nil; + pointer(fremote):= nil; +end; + +procedure tpropertyeditor.setremote(intf: iremotepropertyeditor); +begin + fremote:= intf; + if fremote <> nil then begin + fparenteditor:= fremote.getparenteditor; + if (fparenteditor <> nil) and (ps_subprop in fparenteditor.fstate) then begin + include(fstate,ps_subprop); + end; + end; +end; + +function tpropertyeditor.canrevert: boolean; +begin + result:= (ftypeinfo <> nil) and (fremote = nil) and + (csancestor in component.componentstate) and (fprops[0].instance = component); +end; + +procedure tpropertyeditor.copyproperty(const asource: tobject); +begin + case ftypeinfo^.kind of + tkInteger,tkChar,tkEnumeration,tkSet,tkWChar, + {$ifdef FPC}tkBool,{$endif}tkClass: begin + setordvalue(getordprop(asource,fprops[0].propinfo)); + end; + tkFloat: begin + setfloatvalue(getfloatprop(asource,fprops[0].propinfo)); + end; + tkMethod: begin + setmethodvalue(getmethodprop(asource,fprops[0].propinfo)); + end; + {$ifdef FPC}tkSString,tkAString,{$endif}tkLString: begin + setstringvalue(getstrprop(asource,fprops[0].propinfo)); + end; + msestringtypekind: begin + setmsestringvalue(getmsestringprop(asource,fprops[0].propinfo)); + end; +// {$ifdef mse_unicodestring} +// tkUString: begin +// setmsestringvalue(getunicodestrprop(asource,fprops[0].propinfo)); +// end; +// {$endif} + tkInt64{$ifdef FPC},tkQWord{$endif}: begin + setint64value(getint64prop(asource,fprops[0].propinfo)); + end; + end; +end; + +function tpropertyeditor.getvalue: msestring; +begin + result:= mo.c[ord(unknown)]; +end; + +procedure tpropertyeditor.setvalue(const value: msestring); +begin + //dummy +end; + +function tpropertyeditor.name: msestring; +begin + result:= fname; +end; + +function tpropertyeditor.allequal: boolean; +begin + result:= high(fprops) = 0; +end; + +function tpropertyeditor.props: propinstancearty; +begin + result:= fprops; +end; + +function tpropertyeditor.rootprops: propinstancearty; +var + ed1: tpropertyeditor; +begin + result:= nil; + ed1:= getparenteditor; + if ed1 <> nil then begin + result:= ed1.rootprops; + end; + if result = nil then begin + result:= fprops; + end; +end; + +function tpropertyeditor.propowner: componentarty; +var + ed1: tpropertyeditor; + int1: integer; +begin + result:= nil; + ed1:= getparenteditor; + while ed1 <> nil do begin + if (ed1 is tcomponentpropertyeditor) and not + tcomponentpropertyeditor(ed1).issubcomponent then begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= tcomponent(ed1.getpointervalue); + end; + break; + end; + ed1:= ed1.getparenteditor; + end; +end; + +function tpropertyeditor.instance(const index: integer = 0): tobject; +begin + result:= fprops[index].instance; +end; + +function tpropertyeditor.typedata: ptypedata; +begin + result:= gettypedata(ftypeinfo); +end; + +function tpropertyeditor.queryselectedpropinstances: objectarty; +var + editor1: tpropertyeditor; +begin + result:= nil; + editor1:= fparenteditor; + while editor1 <> nil do begin + if (editor1.fremote <> nil) and (editor1.fremote.selected) then begin + result:= editor1.fremote.getselectedpropinstances; + break; + end; + if editor1 is tclasspropertyeditor then begin + break; + end; + editor1:= editor1.fparenteditor; + end; + if result <> nil then begin + include(fstate,ps_refreshall); + end; +end; + +function tpropertyeditor.getordvalue(const index: integer): integer; + +begin + if fremote <> nil then begin + result:= fremote.getordvalue(index); + end + else begin + with fprops[index] do begin + result:= GetOrdProp(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setordvalue(const value: longword); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setordvalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + setordprop(instance, propinfo, value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setordprop(ar1[int1],fprops[0].propinfo,value); + end; + end; + updatedefaultvalue; + modified; + end; +end; + +procedure tpropertyeditor.setordvalue(const index: integer; const value: longword); +begin + if fremote <> nil then begin + fremote.setordvalue(index,value); + end + else begin + with fprops[index] do begin + setordprop(instance, propinfo, value); + end; + updatedefaultvalue; + modified; + end; +end; + +function tpropertyeditor.getint64value(const index: integer): int64; + +begin + if fremote <> nil then begin + result:= fremote.getint64value(index); + end + else begin + with fprops[index] do begin + result:= getint64prop(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setint64value(const value: int64); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setint64value(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + setint64prop(instance, propinfo, value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setint64prop(ar1[int1],fprops[0].propinfo,value); + end; + end; + updatedefaultvalue; + modified; + end; +end; + +procedure tpropertyeditor.setint64value(const index: integer; const value: int64); +begin + if fremote <> nil then begin + fremote.setint64value(index,value); + end + else begin + with fprops[index] do begin + setint64prop(instance, propinfo, value); + end; + updatedefaultvalue; + modified; + end; +end; + +function tpropertyeditor.getpointervalue(const index: integer): pointer; + +begin + if fremote <> nil then begin + result:= fremote.getpointervalue(index); + end + else begin + with fprops[index] do begin +{$ifdef CPU64} + result:= pointer(ptruint(Getint64Prop(instance,propinfo))); +{$else} + result:= pointer(ptruint(GetOrdProp(instance,propinfo))); +{$endif} + end; + end; +end; + +procedure tpropertyeditor.setpointervalue(const value: pointer); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setpointervalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin +{$ifdef CPU64} + setint64prop(instance, propinfo, ptrint(value)); +{$else} + setordprop(instance, propinfo, ptrint(value)); +{$endif} + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin +{$ifdef CPU64} + setint64prop(ar1[int1],fprops[0].propinfo,ptrint(value)); +{$else} + setordprop(ar1[int1],fprops[0].propinfo,ptrint(value)); +{$endif} + end; + end; + updatedefaultvalue; + modified; + end; +end; + +procedure tpropertyeditor.setpointervalue(const index: integer; const value: pointer); +begin + if fremote <> nil then begin + fremote.setpointervalue(index,value); + end + else begin + with fprops[index] do begin +{$ifdef CPU64} + setint64prop(instance, propinfo, ptrint(value)); +{$else} + setordprop(instance, propinfo, ptrint(value)); +{$endif} + end; + updatedefaultvalue; + modified; + end; +end; + +procedure tpropertyeditor.setbitvalue(const value: boolean; const bitindex: integer); +var + int1: integer; + wo1: longword; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setbitvalue(value,bitindex); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + wo1:= getordprop(instance,propinfo); + updatebit(wo1,bitindex,value); + setordprop(instance,propinfo,wo1); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + wo1:= getordprop(ar1[int1],fprops[0].propinfo); + updatebit(wo1,bitindex,value); + setordprop(ar1[int1],fprops[0].propinfo,wo1); + end; + end; + fparenteditor.updatedefaultvalue; + updatedefaultvalue; + modified; + end; +end; + +function tpropertyeditor.getfloatvalue(const index: integer): extended; +begin + if fremote <> nil then begin + result:= fremote.getfloatvalue(index); + end + else begin + with fprops[index] do begin + result:= GetfloatProp(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setfloatvalue(const value: extended); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setfloatvalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + SetfloatProp(Instance, PropInfo, Value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setfloatprop(ar1[int1],fprops[0].propinfo,value); + end; + end; + modified; + end; +end; + +function tpropertyeditor.getcurrencyvalue(const index: integer = 0): currency; +begin + if fremote <> nil then begin + result:= fremote.getcurrencyvalue(index); + end + else begin + with fprops[index] do begin + result:= getfloatprop(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setcurrencyvalue(const value: currency); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setcurrencyvalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + setfloatprop(instance, propinfo, value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setfloatprop(ar1[int1],fprops[0].propinfo,value); + end; + end; + modified; + end; +end; + +function tpropertyeditor.getstringvalue(const index: integer): string; +begin + if fremote <> nil then begin + result:= fremote.getstringvalue(index); + end + else begin + with fprops[index] do begin + result:= ansistring(decodemsestring( + msestring(GetstrProp(instance,propinfo)))); + end; + end; +end; + +procedure tpropertyeditor.setstringvalue(const value: string); +var + int1: integer; + str1: string; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setstringvalue(value); + end + else begin + str1:= ansistring(encodemsestring(msestring(value))); + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + SetstrProp(Instance, PropInfo, str1); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + SetstrProp(ar1[int1], fprops[0].propinfo, str1); + end; + end; + modified; + end; +end; + +function tpropertyeditor.getutf8stringvalue( + const index: integer = 0): utf8string; +begin + if fremote <> nil then begin + result:= fremote.getutf8stringvalue(index); + end + else begin + with fprops[index] do begin + result:= stringtoutf8(decodemsestring( + msestring(GetstrProp(instance,propinfo)))); + end; + end; +end; + +procedure tpropertyeditor.setutf8stringvalue(const value: utf8string); +var + int1: integer; + str1: utf8string; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setutf8stringvalue(value); + end + else begin + str1:= stringtoutf8(encodemsestring(msestring(value))); + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + SetstrProp(Instance, PropInfo, str1); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + SetstrProp(ar1[int1], fprops[0].propinfo, str1); + end; + end; + modified; + end; +end; + +function tpropertyeditor.decodemsestring(const avalue: msestring): msestring; +var + int1: integer; + po1: pmsechar; + mstr1: msestring; +begin + setlength(result,length(avalue) * 10); //max size + if length(avalue) > 0 then begin + po1:= pointer(result); + for int1:= 1 to length(avalue) do begin + case avalue[int1] of + c_tab: begin po1^:= numcharchar; inc(po1); po1^:= 't'; end; + c_linefeed: begin po1^:= numcharchar; inc(po1); po1^:= 'n'; end; + c_return: begin po1^:= numcharchar; inc(po1); po1^:= 'r'; end; + c_softhyphen: begin po1^:= numcharchar; inc(po1); po1^:= 's'; end; + numcharchar: begin po1^:= numcharchar; inc(po1); po1^:= numcharchar; end; + else begin + if avalue[int1] < widechar(32) then begin + mstr1:= numcharchar+inttostrmse(ord(avalue[int1])); + if (avalue[int1+1] >= '0') and (avalue[int1+1] <= '9') or + (avalue[int1+1] = ' ') then begin + mstr1:= mstr1 + ' '; + end; + move(mstr1[1],po1^,length(mstr1)*sizeof(widechar)); + inc(po1,length(mstr1)-1); + end + else begin + po1^:= avalue[int1]; + end; + end; + end; + inc(po1) + end; + setlength(result,po1-pmsechar(pointer(result))); + end; +end; + +function tpropertyeditor.encodemsestring(const avalue: msestring): msestring; +var + int1: integer; + po1: pmsechar; + int2: integer; +begin + setlength(result,length(avalue)); //max + if length(result) > 0 then begin + po1:= pointer(result); + int1:= 1; + while int1 <= length(avalue) do begin + if (avalue[int1] = numcharchar) and (int1 < length(avalue)+1) then begin + case avalue[int1+1] of + numcharchar: po1^:= numcharchar; + 't': po1^:= c_tab; + 'n': po1^:= c_linefeed; + 'r': po1^:= c_return; + 's': po1^:= c_softhyphen; + '0'..'9': begin + int2:= int1+2; + while (avalue[int2] >= '0') and (avalue[int2] <= '9') do begin + inc(int2); + end; + po1^:= widechar(strtoint(copy(avalue,int1+1,int2-int1-1))); + if avalue[int2] = ' ' then begin + inc(int2); + end; + int1:= int2-2; + end; + else begin po1^:= numcharchar; dec(int1); end; + end; + inc(int1,2); + end + else begin + po1^:= avalue[int1]; + inc(int1); + end; + inc(po1); + end; + setlength(result,po1 - pmsechar(pointer(result))); + end; +end; + +function tpropertyeditor.getmsestringvalue( + const index: integer = 0; const raw: boolean = false): msestring; + +begin + if fremote <> nil then begin + result:= fremote.getmsestringvalue(index,raw); + end + else begin + with fprops[index] do begin + if raw then begin + result:= getmsestringprop(instance,propinfo); + end + else begin + result:= decodemsestring(getmsestringprop(instance,propinfo)); + end; +// {$ifdef mse_unicodestring} +// result:= decodemsestring(GetunicodestrProp(instance,propinfo)); +// {$else} +// result:= decodemsestring(GetwidestrProp(instance,propinfo)); +// {$endif} + end; + end; +end; + +procedure tpropertyeditor.setmsestringvalue(const value: msestring; + const raw: boolean=false); +var + mstr1: msestring; + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setmsestringvalue(value); + end + else begin + if raw then begin + mstr1:= value; + end + else begin + mstr1:= encodemsestring(value); + end; + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + setmsestringprop(instance,propinfo,mstr1); +// {$ifdef mse_unicodestring} +// setunicodestrprop(instance,propinfo,mstr1); +// {$else} +// setwidestrprop(instance,propinfo,mstr1); +// {$endif} + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setmsestringprop(ar1[int1],fprops[0].propinfo,mstr1); +// {$ifdef mse_unicodestring} +// setunicodestrprop(ar1[int1],fprops[0].propinfo,mstr1); +// {$else} +// setwidestrprop(ar1[int1],fprops[0].propinfo,mstr1); +// {$endif} + end; + end; + modified; + end; +end; + +function tpropertyeditor.getvariantvalue(const index: integer = 0): variant; +begin + if fremote <> nil then begin + result:= fremote.getvariantvalue(index); + end + else begin + with fprops[index] do begin + result:= getvariantprop(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setvariantvalue(const value: variant); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setvariantvalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + setvariantprop(instance,propinfo,value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setvariantprop(ar1[int1],fprops[0].propinfo,value); + end; + end; + modified; + end; +end; + +function tpropertyeditor.getmethodvalue(const index: integer): tmethod; +begin + if fremote <> nil then begin + result:= fremote.getmethodvalue(index); + end + else begin + with fprops[index] do begin + result:= GetmethodProp(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setmethodvalue(const value: tmethod); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setmethodvalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + SetmethodProp(Instance, PropInfo, Value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setmethodprop(ar1[int1],fprops[0].propinfo,value); + end; + end; + modified; + end; +end; + +function tpropertyeditor.getparenteditor: tpropertyeditor; +begin + if fremote <> nil then begin + result:= fremote.getparenteditor; + end + else begin + result:= fparenteditor; + end; +end; + +function tpropertyeditor.sortlevel: integer; +begin + result:= fsortlevel; +end; + +function tpropertyeditor.getexpanded: boolean; +begin + result:= ps_expanded in fstate; +end; + +function tpropertyeditor.getcount: integer; +begin + result:= length(fprops); +end; + +procedure tpropertyeditor.setexpanded(const Value: boolean); +begin + if value then begin + include(fstate,ps_expanded); + end + else begin + exclude(fstate,ps_expanded); + end; +end; + +procedure tpropertyeditor.modified; +begin + fobjectinspector.propertymodified(self); + exclude(fstate,ps_refreshall); +end; + +function tpropertyeditor.subproperties: propertyeditorarty; +begin + result:= nil; +end; + +procedure tpropertyeditor.edit; +begin + //dummy +end; + +procedure tpropertyeditor.focused(); +begin + //dummy +end; + +function tpropertyeditor.getvalues: msestringarty; +begin + result:= nil; +end; + +procedure tpropertyeditor.properror; +begin + raise exception.Create(ansistring(mo.c[ord(wrongpropertyvalue)])); +end; + +function tpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= []; + if (fparenteditor <> nil) and (ps_subprop in fparenteditor.fstate) then begin + include(result,ps_subprop); + end; +end; + +procedure tpropertyeditor.dragbegin(var accept: boolean); +begin + //dummy +end; + +procedure tpropertyeditor.dragover(const sender: tpropertyeditor; var accept: boolean); +begin + //dummy +end; + +procedure tpropertyeditor.dragdrop(const sender: tpropertyeditor); +begin + //dummy +end; + +procedure tpropertyeditor.dopopup(var amenu: tpopupmenu; + const atransientfor: twidget; var mouseinfo: mouseeventinfoty); +begin + //dummy +end; + +procedure tpropertyeditor.dokeydown(var ainfo: keyeventinfoty); +begin + //dummy +end; + +procedure tpropertyeditor.updatedefaultvalue; +begin + if (fstate * [ps_isordprop,ps_candefault] = [ps_isordprop,ps_candefault]) and + (getordvalue <> fprops[0].propinfo^.default) then begin + include(fstate,ps_modified); + end + else begin + exclude(fstate,ps_modified); + end; +end; + +function tpropertyeditor.propertyname: msestring; +begin + result:= fname; +end; + +function tpropertyeditor.getselected: boolean; +begin + result:= ps_selected in fstate; +end; + +procedure tpropertyeditor.setselected(const avalue: boolean); +begin + if avalue and (ps_canselect in fstate) then begin + include(fstate,ps_selected); + end + else begin + exclude(fstate,ps_selected); + end; +end; + +procedure tpropertyeditor.setsubprop; +begin + include(fstate,ps_subprop); +end; + +function tpropertyeditor.getvalueeditor: tpropertyeditor; +begin + result:= self; +end; + +function tpropertyeditor.getlinksource: tcomponent; +begin + result:= nil; +end; + +function tpropertyeditor.getlinkcomponent: tcomponent; +begin + result:= linksource; + while (result <> nil) and (cssubcomponent in result.componentstyle) do begin + result:= result.owner; + end; +end; + +function tpropertyeditor.gettypinfo(): ptypeinfo; +begin + result:= ftypeinfo; +end; + +procedure tpropertyeditor.navigevent(); +begin + //dummy +end; + +{ tordinalpropertyeditor } + +function tordinalpropertyeditor.allequal: boolean; +var + int1: integer; + int2: integer; +begin + result:= inherited allequal; + if not result then begin + result:= true; + int2:= getordvalue; + for int1:= 1 to high(fprops) do begin + if int2 <> getordvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tordinalpropertyeditor.getvalue: msestring; +begin + result:= inttostrmse(getordvalue); +end; + +procedure tordinalpropertyeditor.setvalue(const value: msestring); +begin + setordvalue(strtointvalue(ansistring(value))); +end; + +function tordinalpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_isordprop,ps_candefault]; +end; + +{ tvolatileintegerpropertyeditor } + +function tvolatileordinalpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +{ tint64propertyeditor } + +function tint64propertyeditor.allequal: boolean; +var + int1: integer; + int2: int64; +begin + result:= inherited allequal; + if not result then begin + result:= true; + int2:= getint64value; + for int1:= 1 to high(fprops) do begin + if int2 <> getint64value(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tint64propertyeditor.getvalue: msestring; +begin + result:= inttostrmse(getint64value); +end; + +procedure tint64propertyeditor.setvalue(const value: msestring); +begin + setint64value(strtointvalue64(ansistring(value))); +end; + +function tint64propertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_isordprop,ps_candefault]; +end; + +{ tcharpropertyeditor } + +procedure tcharpropertyeditor.setvalue(const value: msestring); +var + str1: string; +begin + str1:= ansistring(encodemsestring(value)); + if str1 = '' then begin + setordvalue(0); + end + else begin + setordvalue(ord(str1[1])); + end; +end; + +function tcharpropertyeditor.getvalue: msestring; +var + int1: integer; +begin + int1:= getordvalue; + if int1 = 0 then begin + result:= ''; + end + else begin + result:= decodemsestring(msechar(char(int1))); + end; +end; + +{ twidecharpropertyeditor } + +procedure twidecharpropertyeditor.setvalue(const value: msestring); +var + str1: msestring; +begin + str1:= encodemsestring(value); + if str1 = '' then begin + setordvalue(0); + end + else begin + setordvalue(ord(str1[1])); + end; +end; + +function twidecharpropertyeditor.getvalue: msestring; +var + int1: integer; +begin + int1:= getordvalue; + if int1 = 0 then begin + result:= ''; + end + else begin + result:= decodemsestring(widechar(int1)); + end; +end; + +{ tmethodpropertyeditor } + +constructor tmethodpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; const aprops: propinstancearty; + atypinfo: ptypeinfo); +begin + inherited; + fsortlevel:= methodsortlevel; +end; + +function tmethodpropertyeditor.allequal: boolean; +var + int1: integer; + method1,method2: tmethod; +begin + result:= inherited allequal; + if not result then begin + result:= true; + method1:= getmethodvalue; + for int1:= 1 to high(fprops) do begin + method2:= getmethodvalue(int1); + if (method1.code <> method2.code) or (method1.data <> method2.data) then begin + result:= false; + break; + end; + end; + end; +end; + +function tmethodpropertyeditor.getvalue: msestring; +var + method1: tmethod; +begin + method1:= getmethodvalue; + if method1.data <> nil then begin + result:= msestring(fdesigner.getmethodname(method1,fcomponent)); + end + else begin + result:= ''; + end; +end; + +function tmethodpropertyeditor.method: tmethod; +begin + result:= getmethodvalue; +end; + +procedure tmethodpropertyeditor.setvalue(const value: msestring); + + function isselected: boolean; + var + ar1: msestringarty; + int1: integer; + begin + ar1:= getvalues; + result:= false; + for int1:= 0 to high(ar1) do begin + if value = ar1[int1] then begin + result:= true; + break; + end; + end; + end; + +var + method1,method2: tmethod; +begin + method2:= getmethodvalue; + if value = '' then begin + method1.code:= nil; + method1.data:= nil; + setmethodvalue(method1); + end + else begin + if not isvalidident(ansistring(value)) then begin + raise exception.create(ansistring( + mo.c[ord(invalidmethodname)]+' '''+value+'''.')); + end; + method1:= fdesigner.getmethod(ansistring(value),fmodule, + fprops[0].propinfo^.proptype{$ifndef FPC}^{$endif},true); + if method1.data = nil then begin //method not found + if (method2.data <> nil) and not isselected and + fdesigner.isownedmethod(fmodule,method2)then begin + fdesigner.changemethodname(method2,ansistring(value), + fprops[0].propinfo^.proptype{$ifndef FPC}^{$endif}); + method1:= method2; + end + else begin + if method1.data <> nil then begin + raise exception.create(ansistring(mo.c[ord(str_methodname)]+' '''+value+''' '+ + mo.c[ord(exists)])); + end; + method1:= fdesigner.createmethod(ansistring(value),fmodule, + fprops[0].propinfo^.proptype{$ifndef FPC}^{$endif}); + end; + end + else begin + fdesigner.checkmethod(method1,ansistring(value),fmodule, + fprops[0].propinfo^.proptype{$ifndef FPC}^{$endif}); + end; + setmethodvalue(method1); + end; +// modified; +end; + +function tmethodpropertyeditor.getvalues: msestringarty; +begin + result:= fobjectinspector.getmatchingmethods(self, + fprops[0].propinfo^.proptype{$ifndef FPC}^{$endif}); +end; + +function tmethodpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= [ps_valuelist,ps_sortlist]; +end; + +procedure tmethodpropertyeditor.navigevent; +begin + objectinspectorfo.showmethodsource(self); +end; + +{ tsetpropertyeditor } + +constructor tsetpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + finvisibleitems:= getinvisibleitems; + if felementeditorclass = nil then begin + felementeditorclass:= tsetelementeditor; + end; + inherited; +end; + +function tsetpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_subproperties,ps_refresh]; +end; + +function tsetpropertyeditor.getvalue: msestring; +begin + {$ifdef FPC} + result:= '['+concatstrings(settostrings(tintegerset(longword(getordvalue)), + typedata^.comptype),',')+']'; + {$else} + result:= '['+concatstrings(settostrings(tintegerset(longword(getordvalue)), + typedata^.comptype^),',')+']'; + {$endif} +(* +{$ifdef FPC} + result:= '['+concatstrings(settostrings(tintegerset(longword(getordvalue)), + gettypedata(fprops[0].propinfo^.proptype)^.comptype),',')+']'; +{$else} + result:= '['+concatstrings(settostrings(tintegerset(longword(getordvalue)), + gettypedata(fprops[0].propinfo^.proptype^)^.comptype^),',')+']'; +{$endif} +*) +end; + +procedure tsetpropertyeditor.setvalue(const value: msestring); +var + str1: string; + ar1: stringarty; +begin + str1:= trim(ansistring(value)); + if (length(str1) > 0) and (str1[1] = '[') then begin + str1:= copy(str1,2,bigint); + end; + if (length(str1) > 0) and (str1[length(str1)] = ']') then begin + setlength(str1,length(str1)-1); + end; + ar1:= nil; + splitstring(str1,ar1,',',true); + setordvalue(longword(stringstoset(ar1,ftypeinfo))); +end; + +function tsetpropertyeditor.subproperties: propertyeditorarty; +var + compty: ptypeinfo; + int1: integer; + int2: integer; +begin + compty:= gettypedata(ftypeinfo)^.comptype{$ifndef FPC}^{$endif}; + setlength(result,gettypedata(compty)^.MaxValue+1); + int2:= 0; + for int1:= 0 to high(result) do begin + if not (int1 in finvisibleitems) then begin + result[int2]:= felementeditorclass.create(fdesigner,fmodule,fcomponent, + fobjectinspector,fprops,compty,self,int1); + inc(int2); + end; + end; + setlength(result,int2); +end; + +function tsetpropertyeditor.getinvisibleitems: tintegerset; +begin + result:= []; +end; + +{ tsetelementeditor } + +constructor tsetelementeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo; + const aparent: tsetpropertyeditor; const aindex: integer); +begin + findex:= aindex; + fparenteditor:= aparent; + inherited create(adesigner,amodule,acomponent,aobjectinspector,aprops,atypeinfo); + fremote:= aparent.fremote; +end; + +function tsetelementeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_candefault,ps_refresh]; + if (fparenteditor <> nil) and (ps_volatile in fparenteditor.fstate) then begin + include(result,ps_volatile); + end; +end; + +function tsetelementeditor.getvalue: msestring; +begin + if findex in tintegerset(longword(getordvalue)) then begin + result:= truename; + end + else begin + result:= falsename; + end; +end; + +function tsetelementeditor.allequal: boolean; +var + int1: integer; + bo1: boolean; +begin + result:= inherited allequal; + if not result then begin + result:= true; + bo1:= findex in tintegerset(longword(getordvalue)); + for int1:= 1 to high(fprops) do begin + if bo1 <> (findex in tintegerset(longword(getordvalue(int1)))) then begin + result:= false; + break; + end; + end; + end; +end; + +function tsetelementeditor.getvalues: msestringarty; +begin + setlength(result,2); + result[0]:= falsename; + result[1]:= truename; +end; + +function tsetelementeditor.name: msestring; +begin +{$ifdef FPC} +// result:= getenumname(gettypedata( +// fparent.fprops[0].propinfo^.proptype)^.comptype,findex); +{$else} +// result:= getenumname(gettypedata(fparent.fprops[0].propinfo^.proptype^)^.comptype^,findex); + {$endif} + result:= msestring(getenumname(ftypeinfo,findex)); +end; + +procedure tsetelementeditor.setvalue(const value: msestring); +begin + setbitvalue(value = truename,findex); +// fparenteditor.modified; +end; + +procedure tsetelementeditor.updatedefaultvalue; +begin + if (fparenteditor.getordvalue xor fparenteditor.fprops[0].propinfo^.default) and + (1 shl findex) <> 0 then begin + include(fstate,ps_modified); + end + else begin + exclude(fstate,ps_modified); + end; +end; + +function tsetelementeditor.propertyname: msestring; +begin + result:= name; +end; + +function tsetelementeditor.canrevert: boolean; +begin + result:= false; +end; + +{ tclasspropertyeditor } + +function tclasspropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + + [ps_subproperties,ps_isordprop,ps_refresh]; +end; + +function tclasspropertyeditor.checkfreeoptionalclass: boolean; +begin + result:= askok(mo.c[ord(wishdestroy)]+' ' + fname+' ('+ + msestring(ftypeinfo^.Name)+ + ')?',stockobjects.captions[sc_confirmation]); +end; + +function tclasspropertyeditor.dispname: msestring; +begin + result:= msestring(ftypeinfo^.name); +end; + +function tclasspropertyeditor.getvalue: msestring; + +begin +// result:= '('+fprops[0].propinfo^.proptype^.name+')'; + result:= '<'+dispname+'>'; +end; + +function tclasspropertyeditor.subproperties: propertyeditorarty; +var + ar1: objectarty; + int1: integer; + comp1: tcomponent; +// prop1: tpropertyeditor; +begin + setlength(ar1,count); + for int1:= 0 to high(fprops) do begin + ar1[int1]:= tobject(getpointervalue(int1)); + end; + comp1:= linkcomponent; + if comp1 = nil then begin + comp1:= fcomponent; + end; + result:= fobjectinspector.getproperties(ar1,fmodule,comp1); +// result:= fobjectinspector.getproperties(ar1,fmodule,fcomponent); + for int1:= 0 to high(result) do begin + result[int1].fparenteditor:= self; + end; + if fstate * [ps_component,ps_subprop] <> [] then begin + for int1:= 0 to high(result) do begin + result[int1].setsubprop; + end; + end; +end; + +{ tlinkedpersistentpropertyeditor } +{ +function tlinkedpersistentpropertyeditor.issubcomponent(const index: integer = 0): boolean; +var + comp: tcomponent; +begin + comp:= tcomponent(getpointervalue(index)); + if comp = nil then begin + result:= false; + end + else begin + result:= cssubcomponent in comp.ComponentStyle; + end; +end; +} +{ +function tlinkedobjectpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_volatile,ps_component]; +end; + +function tlinkedobjectpropertyeditor.allequal: boolean; +var + po1: pointer; + int1: integer; +begin + result:= inherited allequal; + if not result then begin + result:= true; + po1:= getpointervalue; + for int1:= 1 to high(fprops) do begin + if getpointervalue(int1) <> po1 then begin + result:= false; + break; + end; + end; + end; +end; + +function tlinkedobjectpropertyeditor.getvalue: msestring; +var + obj1: tobject; +begin + obj1:= tobject(getpointervalue); + if obj1 = nil then begin + result:= ''; + end + else begin + result:= obj1.classname; + end; +end; + +function tlinkedobjectpropertyeditor.getvalues: msestringarty; +begin + result:= nil; +end; + +procedure tlinkedobjectpropertyeditor.setvalue(const value: msestring); +var + obj1: tobject; +begin + obj1:= nil; + if value = '' then begin + setpointervalue(obj1); + end; +end; + +procedure tlinkedobjectpropertyeditor.checkobj(const avalue: tobject); +begin + //dummy +end; + +function tlinkedobjectpropertyeditor.filterobj(const aobj: tobject): boolean; +begin + result:= true; +end; +} +{ tcomponentpropertyeditor } + +function tcomponentpropertyeditor.issubcomponent(const index: integer = 0): boolean; +var + comp: tcomponent; +begin + comp:= tcomponent(getpointervalue(index)); + if comp = nil then begin + result:= false; + end + else begin + result:= (cssubcomponent in comp.ComponentStyle) and + ((comp.owner = nil) or ownscomponent(component,comp) and + (comp is tmsecomponent) and + not (cs_subcompref in tmsecomponent1(comp).fmsecomponentstate)); + end; +end; + +function tcomponentpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + if not issubcomponent then begin + result:= result + [ps_valuelist,ps_volatile,ps_component,ps_dialog]; + end; +end; + +function tcomponentpropertyeditor.allequal: boolean; +var +// ca1: cardinal; + po1: pointer; + int1: integer; +begin + result:= inherited allequal; + if not result then begin + result:= true; + if issubcomponent then begin + for int1:= 1 to high(fprops) do begin + if not issubcomponent(int1) then begin + result:= false; + break; + end; + end; + end + else begin +// ca1:= getordvalue; + po1:= getpointervalue; + for int1:= 1 to high(fprops) do begin +// if cardinal(getordvalue(int1)) <> ca1 then begin + if getpointervalue(int1) <> po1 then begin + result:= false; + break; + end; + end; + end; + end; +end; + +function tcomponentpropertyeditor.getvalue: msestring; +//var +// comp1: tcomponent; +begin + if issubcomponent then begin + result:= inherited getvalue; + end + else begin + result:= getcomponentpropname(tcomponent(getpointervalue)); + end; +end; + +function tcomponentpropertyeditor.getvalues: msestringarty; +var + co1: tcomponent; + ar1: componentarty; + int1,int2: integer; +begin + ar1:= nil; //compiler warning + if issubcomponent then begin + result:= inherited getvalues; + end + else begin + if ps_link in fstate then begin + ar1:= fdesigner.getcomponentlist(tcomponentclass(typedata^.classtype), + {$ifdef FPC}@{$endif}filtercomponent,not (ps_local in fstate)); + if ps_local in fstate then begin + co1:= fcomponent.owner; + for int1:= high(ar1) downto 0 do begin + if ar1[int1].owner <> co1 then begin + ar1[int1]:= nil; + end; + end; + end; + + for int1:= 0 to high(ar1) do begin + with tdesigner1(designer).selections do begin + for int2:= count - 1 downto 0 do begin + if items[int2] = ar1[int1] then begin + ar1[int1]:= nil; //remove selected components + break; + end; + end; + end; + end; + result:= fdesigner.getcomponentnamelist(ar1,fmodule); + { + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> nil then begin + additem(result,msestring(ar1[int1].name)); + end; + end; + } + end + else begin + if ps_local in fstate then begin + co1:= fmodule; + end + else begin + co1:= nil; + end; + result:= fdesigner.getcomponentnamelist( + tcomponentclass(typedata^.classtype),true{false},co1, + {$ifdef FPC}@{$endif}filtercomponent); + end; + end; +end; + +var + fcomppath: msestring; + +procedure tcomponentpropertyeditor.edit; +var + tree1: tcompnameitem; + mstr1: msestring; + co1: tcomponent; +begin + if ps_local in fstate then begin + co1:= fmodule; + end + else begin + co1:= nil; + end; + tree1:= fdesigner.getcomponentnametree( + tcomponentclass(typedata^.classtype),true,false,co1, + {$ifdef FPC}@{$endif}filtercomponent); + co1:= tcomponent(getpointervalue); + if co1 = nil then begin + mstr1:= fcomppath; + if mstr1 = '' then begin + mstr1:= msestring(fmodule.name); + end; + end + else begin + mstr1:= msestring(ownernamepath(co1)); + end; + if compnamedialog(tree1,mstr1,false) = mr_ok then begin + fcomppath:= mstr1; + setvalue(mstr1); + end; +end; + +procedure tcomponentpropertyeditor.setvalue(const value: msestring); +var + comp: tcomponent; + int1: integer; +begin + if issubcomponent then begin + inherited setvalue(value); + end + else begin + if value = '' then begin + comp:= nil; + end + else begin + if value <> getvalue then begin + int1:= pos('<',value); + if int1 > 0 then begin + comp:= fdesigner.getcomponent(copy(ansistring(value),1,int1-1),fmodule); +// comp:= fmodule.findcomponent(copy(value,1,int1-1)); + end + else begin + comp:= fdesigner.getcomponent(ansistring(value),fmodule); + end; + if (comp = nil) or not comp.InheritsFrom(gettypedata(ftypeinfo)^.classtype) then begin + properror; + end; + checkcomponent(comp); + end + else begin + exit; + end; + end; + setpointervalue(comp); + end; +end; + +procedure tcomponentpropertyeditor.checkcomponent(const avalue: tcomponent); +begin + //dummy +end; + +function tcomponentpropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +begin + result:= true; +end; + +function tcomponentpropertyeditor.getlinksource: tcomponent; +begin + result:= tcomponent(getpointervalue); +end; + +{ tsubcomponenteditor } + +function tsubcomponentpropertyeditor.issubcomponent(const index: integer = 0): boolean; +begin + result:= true; +end; + +{ tsisterwidgetpropertyeditor } +{ +function tsisterwidgetpropertyeditor.getvalues: msestringarty; +var + ar1: componentarty; + widget1: twidget; + int1: integer; +begin + ar1:= nil; //compiler warning + if issubcomponent then begin + result:= inherited getvalues; + end + else begin + result:= nil; + widget1:= twidget(fcomponent).parentwidget; + if widget1 <> nil then begin + ar1:= fdesigner.getcomponentlist(tcomponentclass(typedata^.classtype)); + for int1:= 0 to high(ar1) do begin + if (twidget(ar1[int1]).parentwidget <> widget1) or + (ar1[int1] = fcomponent) then begin + ar1[int1]:= nil; + end; + end; + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> nil then begin + additem(result,msestring(ar1[int1].name)); + end; + end; + end; + end; +end; +} + +function tsisterwidgetpropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +begin + result:= (acomponent <> fcomponent) and + (twidget(acomponent).parentwidget = twidget(fcomponent).parentwidget); +end; + +function tsisterwidgetpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_sortlist]; +end; + +{ tnochildrenwidgetpropertyeditor } + +function tnochildrenwidgetpropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +begin + result:= (twidget(acomponent).window = twidget(fcomponent).window) and + not twidget(fcomponent).checkdescendent(twidget(acomponent)); +end; + +function tnochildrenwidgetpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_sortlist]; +end; + +{ tchildwidgetpropertyeditor } + +function tchildwidgetpropertyeditor.getvalues: msestringarty; +var + ar1: componentarty; + widget1: twidget; + int1: integer; +begin + ar1:= nil; //compiler warning + if issubcomponent then begin + result:= inherited getvalues; + end + else begin + result:= nil; + widget1:= twidget(fcomponent); + ar1:= fdesigner.getcomponentlist(tcomponentclass(typedata^.classtype)); + for int1:= 0 to high(ar1) do begin + if (twidget(ar1[int1]).parentwidget <> widget1) then begin + ar1[int1]:= nil; + end; + end; + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> nil then begin + additem(result,msestring(ar1[int1].name)); + end; + end; + end; +end; + +function tchildwidgetpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_sortlist]; +end; + +{ tlocalcomponentpropertyeditor } + +function tlocalcomponentpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_local]; +end; + +{ tlinkcomponentpropertyeditor } + +function tlinkcomponentpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_link]; +end; + +{ tlocallinkcomponentpropertyeditor } + +function tlocallinkcomponentpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_local,ps_link]; +end; + +{ toptionalclasspropertyeditor } + +function toptionalclasspropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog,ps_volatile]; +end; + +procedure toptionalclasspropertyeditor.deleteinstance; +begin + if checkfreeoptionalclass then begin + setordvalue(0); + end; +end; + +procedure toptionalclasspropertyeditor.edit; +var + obj1: tobject; +begin + obj1:= getinstance; + if obj1 = nil then begin + setordvalue(1); + end + else begin + deleteinstance; + end; +end; + +function toptionalclasspropertyeditor.getinstance: tpersistent; +begin + result:= tpersistent(getpointervalue); +end; + +function toptionalclasspropertyeditor.getniltext: msestring; +begin + result:= ''; +end; + +procedure toptionalclasspropertyeditor.setvalue(const avalue: msestring); +begin + if avalue = '' then begin + deleteinstance; + end + else begin + inherited; + end; +end; + +function toptionalclasspropertyeditor.getvalue: msestring; +begin + if getinstance = nil then begin + result:= getniltext; + end + else begin + result:= inherited getvalue; + end; +end; + +function toptionalclasspropertyeditor.canrevert: boolean; +begin + result:= false; +end; + +{ tparentclasspropertyeditor } + +procedure tparentclasspropertyeditor.edit; +var + obj1: tobject; + persist1,persist2: tpersistent; + int1: integer; +begin + obj1:= getinstance; + if obj1 = nil then begin + for int1:= 0 to count - 1 do begin + persist1:= tpersistent(getpointervalue(int1)); + setordvalue(int1,1); //create instance + persist2:= tpersistent(getpointervalue(int1)); + if (persist1 <> nil) and (persist2 <> nil) then begin + persist2.Assign(persist1); //copy default values + end; + end; + end + else begin + if not checkfreeoptionalclass then begin + exit; + end; + setordvalue(0); + end; +end; + +function tparentclasspropertyeditor.getinstance: tpersistent; +begin + result:= getinstancepo(instance)^; +end; + +function tparentclasspropertyeditor.getniltext: msestring; +begin + result:= ''; +end; + +function tparentclasspropertyeditor.subproperties: propertyeditorarty; +begin + if getinstance = nil then begin + result:= nil; + end + else begin + result:= inherited subproperties; + end; +end; + +{ tparentfontproperty } + +function tparentfontpropertyeditor.getinstancepo(acomponent: tobject): ppersistent; +begin + result:= ppersistent(parentfontclassty(typedata^.classtype).getinstancepo(acomponent)); +end; + +{ tstringpropertyeditor } + +function tstringpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_isordprop]; +end; + +function tstringpropertyeditor.allequal: boolean; +var + int1: integer; + str1: string; +begin + result:= inherited allequal; + if not result then begin + result:= true; + str1:= getstringvalue; + for int1:= 1 to high(fprops) do begin + if str1 <> getstringvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tstringpropertyeditor.getvalue: msestring; +begin + result:= msestring(getstringvalue(0)); +end; + +procedure tstringpropertyeditor.setvalue(const value: msestring); +begin + setstringvalue(ansistring(value)); +end; + +{ tutf8stringpropertyeditor } + +function tutf8stringpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_isordprop]; +end; + +function tutf8stringpropertyeditor.allequal: boolean; +var + int1: integer; + str1: utf8string; +begin + result:= inherited allequal; + if not result then begin + result:= true; + str1:= getutf8stringvalue; + for int1:= 1 to high(fprops) do begin + if str1 <> getutf8stringvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tutf8stringpropertyeditor.getvalue: msestring; +begin + result:= utf8tostring(getutf8stringvalue(0)); +end; + +procedure tutf8stringpropertyeditor.setvalue(const value: msestring); +begin + setutf8stringvalue(stringtoutf8(value)); +end; + +{ tmsestringpropertyeditor } + +function tmsestringpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_isordprop,ps_dialog]; +end; + +function tmsestringpropertyeditor.allequal: boolean; +var + int1: integer; + str1: msestring; +begin + result:= inherited allequal; + if not result then begin + result:= true; + str1:= getmsestringvalue; + for int1:= 0 to high(fprops) do begin + if str1 <> getmsestringvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tmsestringpropertyeditor.getvalue: msestring; +begin + result:= getmsestringvalue(0); +end; + +procedure tmsestringpropertyeditor.setvalue(const value: msestring); +begin + setmsestringvalue(value); +end; + +procedure tmsestringpropertyeditor.edit; +var + mstr1: msestring; +begin + mstr1:= encodemsestring(getmsestringvalue(0)); + if memodialog(mstr1,false) = mr_ok then begin + setmsestringvalue(decodemsestring(mstr1)); + end; +end; + +{ trichstringpropertyeditor } + +procedure trichstringpropertyeditor.edit; +var + intf1: irichstringprop; + rstr1: richstringty; + i1: int32; +begin + if getcorbainterface(component,typeinfo(irichstringprop),intf1) then begin + rstr1:= intf1.getrichvalue(); + rstr1.text:= encodemsestring(rstr1.text); + if richstringdialog(rstr1,false) = mr_ok then begin + rstr1.text:= decodemsestring(rstr1.text); + for i1:= 0 to high(fprops) do begin + if getcorbainterface(fprops[i1].instance, + typeinfo(irichstringprop),intf1) then begin + intf1.setrichvalue(rstr1); + end; + end; + modified; + end; + end + else begin + inherited; + end; +end; + +{ tarraypropertyeditor } + +function tarraypropertyeditor.allequal: boolean; +var + int1: integer; + int2: integer; + p1: tarrayprop; +begin + result:= inherited allequal; + if not result then begin + result:= true; + p1:= tarrayprop(getpointervalue); + if p1 <> nil then begin + int2:= p1.count; + for int1:= 1 to high(fprops) do begin + p1:= tarrayprop(getpointervalue(int1)); + if (p1 = nil) or (int2 <> p1.count) then begin + result:= false; + break; + end; + end; + end + else begin + for int1:= 1 to high(fprops) do begin + p1:= tarrayprop(getpointervalue(int1)); + if p1 <> nil then begin + result:= false; + break; + end; + end; + end; + end; +end; + +function tarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tpropertyeditor; +end; + +function tarraypropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tarrayelementeditor; +end; + +function tarraypropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_subproperties,ps_volatile]; +end; + +function tarraypropertyeditor.getvalue: msestring; +begin + result:= inttostrmse(tarrayprop(getpointervalue).count); +end; + +function tarraypropertyeditor.name: msestring; +begin + result:= inherited name +'.count'; +end; +{ +procedure tarraypropertyeditor.setmincount(mincount: integer); +begin + +end; +} +procedure tarraypropertyeditor.setvalue(const value: msestring); +var + int1: integer; + va: integer; +begin + va:= strtoint(value); + if va < 0 then begin + va:= 0; + end + else begin + if va > propmaxarraycount then begin + va:= propmaxarraycount; + end; + end; + int1:= tarrayprop(getpointervalue).count; + if ( int1 > va) and not askok(mo.c[ord(wishdelete)]+' '+inttostrmse(va) + + ' '+mo.c[ord(str_to)]+' '+ inttostrmse(int1-1) + '?', + stockobjects.captions[sc_confirmation]) then begin + exit; + end; + if not ((ps_noadditems in fstate) and (va > int1)) then begin + for int1:= 0 to high(fprops) do begin + tarrayprop(getpointervalue(int1)).count:= va; + end; + modified; + end; +end; + +function tarraypropertyeditor.subproperties: propertyeditorarty; +var + prop: tarrayprop; + int1,int2: integer; +begin + result:= inherited subproperties; + int2:= 0; + for int1:= 0 to high(result) do begin + if result[int1].name = 'count' then begin + result[int1].Free; + end + else begin + result[int2]:= result[int1]; + inc(int2); + end; + end; + setlength(result,int2); + prop:= tarrayprop(getpointervalue); + if prop <> nil then begin + setlength(fsubprops,prop.count); + for int1:= 0 to high(fsubprops) do begin + fsubprops[int1]:= getelementeditorclass.create(int1,self,geteditorclass, + fdesigner,fobjectinspector,fprops,getitemtypeinfo); + end; + stackarray(pointerarty(fsubprops),pointerarty(result)); + end + else begin + setlength(result,0); + end; +end; + +procedure tarraypropertyeditor.itemmoved(const source,dest: integer); +begin + modified; +end; + +procedure tarraypropertyeditor.dopopup(var amenu: tpopupmenu; + const atransientfor: twidget; var mouseinfo: mouseeventinfoty); +begin + if not (ps_noadditems in fstate) then begin + tpopupmenu.additems(amenu,atransientfor,mouseinfo, + ['Insert Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowinsert])+')', + 'Append Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowappend])+')'], + [],[],[@doinsert,@doappend]); + end; + inherited; +end; + +procedure tarraypropertyeditor.dokeydown(var ainfo: keyeventinfoty); +begin + if not (ps_noadditems in fstate) then begin + if issysshortcut(sho_rowinsert,ainfo) then begin + doinsert(nil); + include(ainfo.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowappend,ainfo) then begin + doappend(nil); + include(ainfo.eventstate,es_processed); + end; + end; + end; +end; + +procedure tarraypropertyeditor.doappend(const sender: tobject); +begin + with tarrayprop(getpointervalue) do begin + insertdefault(count); + end; + modified; +end; + +procedure tarraypropertyeditor.doinsert(const sender: tobject); +begin + with tarrayprop(getpointervalue) do begin + insertdefault(0); + end; + modified; +end; + +procedure tarraypropertyeditor.move(const curindex: integer; + const newindex: integer); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + tarrayprop(getpointervalue(int1)).move(curindex,newindex); + end; + itemmoved(curindex,newindex) +end; + +function tarraypropertyeditor.itemprefix: msestring; +begin + result:= 'Item '; +end; + +function tarraypropertyeditor.getitemtypeinfo: ptypeinfo; +begin + result:= ftypeinfo; //default +end; + +function tarraypropertyeditor.itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; +begin + result:= sender.feditor.getdefaultstate(); +end; + +function tarraypropertyeditor.itemgetlinksource( + const sender: tarrayelementeditor): tcomponent; +begin + result:= sender.feditor.getlinksource(); +end; + +procedure tarraypropertyeditor.itemsetvalue( + const sender: tarrayelementeditor; + const value: msestring); +begin + sender.feditor.setvalue(value); +end; + +function tarraypropertyeditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + result:= sender.feditor.getvalue(); +end; + +function tarraypropertyeditor.itemgetvalues( + const sender: tarrayelementeditor): msestringarty; +begin + result:= sender.feditor.getvalues(); +end; + +procedure tarraypropertyeditor.itemedit( + const sender: tarrayelementeditor); +begin + sender.feditor.edit(); +end; + +procedure tarraypropertyeditor.itemfocused(const sender: tarrayelementeditor); +begin + sender.feditor.focused(); +end; + +function tarraypropertyeditor.itemname( + const sender: tarrayelementeditor): msestring; +begin + result:= itemprefix + inttostrmse(sender.findex); +end; + +function tarraypropertyeditor.itemsubproperties( + const sender: tarrayelementeditor): propertyeditorarty; +begin + result:= sender.feditor.subproperties(); +end; + +{ tarrayelementeditor } + +constructor tarrayelementeditor.create(aindex: integer; + aparenteditor: tarraypropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); +begin + findex:= aindex; + fparenteditor:= aparenteditor; + feditor:= aeditorclass.create(adesigner,aparenteditor.fmodule, + aparenteditor.fcomponent,aobjectinspector,aprops,atypinfo); + feditor.setremote(iremotepropertyeditor(self)); + inherited create(adesigner,feditor.fmodule,feditor.fcomponent, + aobjectinspector,aprops,atypinfo); +end; + +destructor tarrayelementeditor.destroy; +begin + feditor.Free; + inherited; +end; + +function tarrayelementeditor.getordvalue(const index: integer = 0): integer; +begin + with fprops[index] do begin + result:= tintegerarrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setordvalue(const value: longword); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + tintegerarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; + +procedure tarrayelementeditor.setordvalue(const index: integer; + const value: longword); +begin + with fprops[index] do begin + tintegerarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + modified; +end; + +function tarrayelementeditor.getint64value(const index: integer = 0): int64; +begin + with fprops[index] do begin + result:= tint64arrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setint64value(const value: int64); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + tint64arrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; + +procedure tarrayelementeditor.setint64value(const index: integer; + const value: int64); +begin + with fprops[index] do begin + tint64arrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + modified; +end; + +function tarrayelementeditor.getpointervalue(const index: integer = 0): pointer; +begin + with fprops[index] do begin + result:= tpointerarrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setpointervalue(const value: pointer); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + tpointerarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; + +procedure tarrayelementeditor.setpointervalue(const index: integer; + const value: pointer); +begin + with fprops[index] do begin + tpointerarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + modified; +end; + +procedure tarrayelementeditor.setbitvalue(const value: boolean; + const bitindex: integer); +var + int1: integer; + wo1: longword; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + wo1:= longword(tsetarrayprop(getpointerprop1(instance,propinfo))[findex]); + updatebit(wo1,bitindex,value); + tsetarrayprop(getpointerprop1(instance,propinfo))[findex]:= tintegerset(wo1); + end; + end; + modified; +end; + +function tarrayelementeditor.getfloatvalue(const index: integer = 0): extended; +begin + with fprops[index] do begin + result:= trealarrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setfloatvalue(const value: extended); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + trealarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; + +function tarrayelementeditor.getstringvalue(const index: integer = 0): string; +begin + with fprops[index] do begin + result:= tstringarrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setstringvalue(const value: string); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + tstringarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; + +function tarrayelementeditor.getmsestringvalue(const index: integer = 0; + const raw: boolean = false): msestring; +begin + with fprops[index] do begin + result:= tmsestringarrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setmsestringvalue(const value: msestring; + const raw: boolean = false); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + tmsestringarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; +{ +function tarrayelementeditor.getclassvalue( + const aindex: integer): tpersistent; +begin + with fprops[aindex] do begin + result:= tpersistentarrayprop(GetOrdProp(instance,propinfo))[findex]; + end; +end; +} +procedure tarrayelementeditor.dragbegin(var accept: boolean); +begin + accept:= true; +end; + +procedure tarrayelementeditor.dragdrop(const sender: tpropertyeditor); +begin + if (sender is tarrayelementeditor) and + (tarrayelementeditor(sender).fparenteditor = fparenteditor) then begin + tarraypropertyeditor(fparenteditor).move(tarrayelementeditor(sender).findex, + findex); + end; +end; + +procedure tarrayelementeditor.dragover(const sender: tpropertyeditor; + var accept: boolean); +begin + accept:= (sender is tarrayelementeditor) and + (tarrayelementeditor(sender).fparenteditor = fparenteditor); +end; + +procedure tarrayelementeditor.dodelete(const sender: tobject); +begin + if askyesno('Do you wish to delete '+getvalue+'?','CONFIRMATION') then begin + tarrayprop(fparenteditor.getpointervalue).delete(findex); + fparenteditor.modified; + end; +end; + +procedure tarrayelementeditor.doinsert(const sender: tobject); +begin + tarrayprop(fparenteditor.getpointervalue).insertdefault(findex); + fparenteditor.modified; +end; + +procedure tarrayelementeditor.doappend(const sender: tobject); +begin + tarrayprop(fparenteditor.getpointervalue).insertdefault(findex+1); + fparenteditor.modified; +end; + +procedure tarrayelementeditor.dopopup(var amenu: tpopupmenu; + const atransientfor: twidget; var mouseinfo: mouseeventinfoty); +begin + if not (ps_noadditems in fparenteditor.fstate) then begin + tpopupmenu.additems(amenu,atransientfor,mouseinfo, + ['Insert Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowinsert])+')', + 'Append Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowappend])+')', + 'Delete Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowdelete])+')'],[],[], + [{$ifdef FPC}@{$endif}doinsert, + {$ifdef FPC}@{$endif}doappend,{$ifdef FPC}@{$endif}dodelete]); + end + else begin + if not (ps_nodeleteitems in fparenteditor.fstate) then begin + tpopupmenu.additems(amenu,atransientfor,mouseinfo, + ['Delete Item'],[],[], + [{$ifdef FPC}@{$endif}dodelete]); + end; + end; + inherited; +end; + +procedure tarrayelementeditor.dokeydown(var ainfo: keyeventinfoty); +begin + if issysshortcut(sho_rowdelete,ainfo) then begin + if not (ps_nodeleteitems in fparenteditor.fstate) then begin + dodelete(nil); + include(ainfo.eventstate,es_processed); + end; + end + else begin + if not (ps_noadditems in fparenteditor.fstate) then begin + if issysshortcut(sho_rowinsert,ainfo) then begin + doinsert(nil); + include(ainfo.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowappend,ainfo) then begin + doappend(nil); + include(ainfo.eventstate,es_processed); + end; + end; + end; + end; +end; + +function tarrayelementeditor.name: msestring; +begin + result:= tarraypropertyeditor(fparenteditor).itemname(self); +// result:= tarraypropertyeditor(fparenteditor).itemprefix + inttostr(findex); +end; + +function tarrayelementeditor.subproperties: propertyeditorarty; +begin + result:= tarraypropertyeditor(fparenteditor).itemsubproperties(self); +end; + +procedure tarrayelementeditor.edit; +begin + tarraypropertyeditor(fparenteditor).itemedit(self); +end; + +procedure tarrayelementeditor.focused(); +begin + tarraypropertyeditor(fparenteditor).itemfocused(self); +end; + +function tarrayelementeditor.getdefaultstate: propertystatesty; +begin + result:= tarraypropertyeditor(fparenteditor).itemgetdefaultstate(self); +end; + +function tarrayelementeditor.getvalue: msestring; +begin + result:= tarraypropertyeditor(fparenteditor).itemgetvalue(self); +end; + +function tarrayelementeditor.getvalues: msestringarty; +begin + result:= tarraypropertyeditor(fparenteditor).itemgetvalues(self); +end; + +procedure tarrayelementeditor.setvalue(const value: msestring); +begin + tarraypropertyeditor(fparenteditor).itemsetvalue(self,value); +end; + +function tarrayelementeditor.canrevert: boolean; +begin + result:= false; +end; + +function tarrayelementeditor.getselectedpropinstances: objectarty; +var + int1,int2: integer; +begin + with tarraypropertyeditor(fparenteditor) do begin + setlength(result,length(fsubprops)); + int2:= 0; + for int1:= 0 to high(fsubprops) do begin + if fsubprops[int1].selected then begin + result[int2]:= tobject(fsubprops[int1].feditor.getpointervalue); + inc(int2); + end; + end; + setlength(result,int2); + end; +end; + +function tarrayelementeditor.getvalueeditor: tpropertyeditor; +begin + result:= feditor; +end; + +function tarrayelementeditor.getlinksource: tcomponent; +begin + result:= tarraypropertyeditor(fparenteditor).itemgetlinksource(self); +end; + +function tarrayelementeditor.gettypinfo: ptypeinfo; +begin + result:= getvalueeditor.typinfo; +end; + +{ tconstarraypropertyeditor } + +function tconstarraypropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + + [ps_subproperties,ps_noadditems,ps_nodeleteitems{,ps_volatile}]; +end; + +function tconstarraypropertyeditor.getvalue: msestring; +begin + result:= '' +end; + +procedure tconstarraypropertyeditor.setvalue(const value: msestring); +begin + //dummy +end; + +function tconstarraypropertyeditor.name: msestring; +begin + result:= fname; +end; + +function tconstarraypropertyeditor.allequal: boolean; +begin + result:= false; +end; + +{ tclasselementeditor } +{ +function tclasselementeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_subproperties]; +end; + +function tclasselementeditor.getvalue: msestring; +begin + result:= '('+fprops[0].propinfo^.proptype^.name+')'; +end; + +function tclasselementeditor.subproperties: propertyeditorarty; +begin + result:= fobjectinspector.getproperties(tobject(getclassvalue)); +end; +} +{ tpersistentarraypropertyeditor } + +function tpersistentarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tclasselementeditor; +end; + +{ toptionalpersistentarraypropertyeditor } + +function toptionalpersistentarraypropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog,ps_volatile]; +end; + +procedure toptionalpersistentarraypropertyeditor.edit; +var + obj1: tobject; +begin + obj1:= getinstance; + if obj1 = nil then begin + setordvalue(1); + end + else begin + if not checkfreeoptionalclass then begin + exit; + end; + setordvalue(0); + end; + modified; +end; + +function toptionalpersistentarraypropertyeditor.getinstance: tpersistent; +begin + result:= tpersistent(getpointervalue); +end; + +function toptionalpersistentarraypropertyeditor.getniltext: msestring; +begin + result:= ''; +end; + +function toptionalpersistentarraypropertyeditor.getvalue: msestring; +begin + if getinstance = nil then begin + result:= getniltext; + end + else begin + result:= inherited getvalue; + end; +end; + +procedure toptionalpersistentarraypropertyeditor.setvalue(const value: msestring); +begin + if getordvalue <> 0 then begin + inherited; + end; +end; + +{ tmenuelementeditor } + +function tmenuelementeditor.getvalue: msestring; +var + item1: tmenuitem; +begin + item1:= tmenuitem(getpointervalue); + if (mao_separator in item1.options) then begin + result:= '<---->'; + end + else begin + result:= '<' + decodemsestring(item1.caption) + '>'; + if item1.name <> '' then begin + result:= result + '<' + msestring(item1.name) + '>'; + end; + end; +end; + +{ tmenuarraypropertyeditor } + +function tmenuarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tmenuelementeditor; +end; + +{ tintegerarraypropertyeditor } + +function tintegerarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tordinalpropertyeditor; +end; + +{ tsetarrayelementeditor } + +constructor tsetarrayelementeditor.create(aindex: integer; + aparenteditor: tarraypropertyeditor; + aeditorclass: propertyeditorclassty; const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); +begin + inherited; + feditor.ftypeinfo:= tsetarrayprop(aparenteditor.getpointervalue).typeinfo; +end; + +{ tsetarraypropertyeditor } + +function tsetarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tsetpropertyeditor; +end; + +function tsetarraypropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tsetarrayelementeditor; +end; + +{ trealarraypropertyeditor} + +function trealarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= trealtypropertyeditor; +end; + +{ tcolorarraypropertyeditor } + +function tcolorarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tcolorpropertyeditor; +end; + +function tcolorarraypropertyeditor.getitemtypeinfo: ptypeinfo; +begin + result:= typeinfo(colorty); +end; + +{ tstringarraypropertyeditor } + +function tstringarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tstringpropertyeditor; +end; + +{ tmsestringarraypropertyeditor } + +function tmsestringarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tmsestringpropertyeditor; +end; + +{ tordinalelementeditor } +{ +function tordinalelementeditor.getvalue: msestring; +begin + result:= inttostr(getordvalue); +end; + +procedure tordinalelementeditor.setvalue(const value: msestring); +begin + setordvalue(strtointvalue(value)); +end; +} +{ tlclasselementeditor } + +function tclasselementeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_canselect]; +end; + +function tclasselementeditor.getvalue: msestring; +var + obj1: tobject; +begin + obj1:= tobject(getpointervalue); + if obj1 = nil then begin + result:= ''; + end + else begin +// result:= '<'+obj1.classtype.classname+'>'; + result:= '<'+dispname+'>'; + end; +end; + +function tclasselementeditor.dispname: msestring; +begin + result:= msestring(tobject(getpointervalue).classtype.classname); +end; + +{ tcllectionitemeditor } + +constructor tcollectionitemeditor.create(aindex: integer; + aparenteditor: tcollectionpropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); +var + props1: propinstancearty; + int1: integer; +begin + setlength(props1,length(aprops)); + for int1:= 0 to high(props1) do begin + props1[int1].propinfo:= aprops[int1].propinfo; + props1[int1].instance:= + tcollection(aparenteditor.getpointervalue(int1)).items[aindex]; + end; + findex:= aindex; + fparenteditor:= aparenteditor; + feditor:= aeditorclass.create(adesigner,aparenteditor.fmodule, + aparenteditor.fcomponent,aobjectinspector,props1,atypinfo); + feditor.setremote(iremotepropertyeditor(self)); + inherited create(adesigner,feditor.fmodule,feditor.fcomponent, + aobjectinspector,aprops,atypinfo); +end; + +destructor tcollectionitemeditor.destroy; +begin + feditor.free; + inherited; +end; + +procedure tcollectionitemeditor.setvalue(const value: msestring); +begin + feditor.setvalue(value); +end; + +function tcollectionitemeditor.getvalue: msestring; +begin + result:= feditor.getvalue; +end; + +function tcollectionitemeditor.getvalues: msestringarty; +begin + result:= feditor.getvalues; +end; + +procedure tcollectionitemeditor.edit; +begin + feditor.edit; +end; + +function tcollectionitemeditor.subproperties: propertyeditorarty; +begin + result:= feditor.subproperties; +end; + +function tcollectionitemeditor.name: msestring; +begin + result:= 'Item '+inttostrmse(findex); +end; +{ +function tcollectionitemeditor.getordvalue(const index: integer = 0): integer; +begin + result:= integer(tcollection(fparenteditor.getpointervalue(index)).items[findex]); +end; + +procedure tcollectionitemeditor.setordvalue(const value: longword); +begin + //dummy +end; + +procedure tcollectionitemeditor.setordvalue(const index: integer; + const value: longword); +begin + //dummy +end; +} +function tcollectionitemeditor.getpointervalue(const index: integer = 0): pointer; +begin + result:= tcollection(fparenteditor.getpointervalue(index)).items[findex]; +end; + +procedure tcollectionitemeditor.setpointervalue(const value: pointer); +begin + //dummy +end; + +procedure tcollectionitemeditor.setpointervalue(const index: integer; + const value: pointer); +begin + //dummy +end; + +procedure tcollectionitemeditor.doinsert(const sender: tobject); +begin + tcollection(fparenteditor.getpointervalue).insert(findex); + fparenteditor.modified; +end; + +procedure tcollectionitemeditor.doappend(const sender: tobject); +begin + tcollection(fparenteditor.getpointervalue).insert(findex+1); + fparenteditor.modified; +end; + +procedure tcollectionitemeditor.dodelete(const sender: tobject); +begin + if askyesno('Do you wish to delete '+getvalue+'?','CONFIRMATION') then begin + tcollection(fparenteditor.getpointervalue).delete(findex); + fparenteditor.modified; + end; +end; + +function tcollectionitemeditor.getdefaultstate: propertystatesty; +begin + result:= feditor.getdefaultstate; +end; + +procedure tcollectionitemeditor.dragbegin(var accept: boolean); +begin + accept:= true; +end; + +procedure tcollectionitemeditor.dragover(const sender: tpropertyeditor; + var accept: boolean); +begin + accept:= (sender is tcollectionitemeditor) and + (tcollectionitemeditor(sender).fparenteditor = fparenteditor); +end; + +procedure tcollectionitemeditor.dragdrop(const sender: tpropertyeditor); +var + source: integer; +begin + if (sender is tcollectionitemeditor) and + (tcollectionitemeditor(sender).fparenteditor = fparenteditor) then begin + source:= tcollectionitemeditor(sender).findex; + tcollection(fparenteditor.getpointervalue).items[source].index:= findex; +// sender.modified; +// modified; + tcollectionpropertyeditor(fparenteditor).itemmoved(source,findex); + end; +end; + +procedure tcollectionitemeditor.dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); +begin + tpopupmenu.additems(amenu,atransientfor,mouseinfo, + ['Insert Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowinsert])+')', + 'Append Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowappend])+')', + 'Delete Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowdelete])+')'],[],[], + [{$ifdef FPC}@{$endif}doinsert, + {$ifdef FPC}@{$endif}doappend,{$ifdef FPC}@{$endif}dodelete]); + inherited; +end; + +procedure tcollectionitemeditor.dokeydown(var ainfo: keyeventinfoty); +begin + if issysshortcut(sho_rowdelete,ainfo) then begin + dodelete(nil); + include(ainfo.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowinsert,ainfo) then begin + doinsert(nil); + include(ainfo.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowappend,ainfo) then begin + doappend(nil); + include(ainfo.eventstate,es_processed); + end; + end; + end; +end; + +function tcollectionitemeditor.getselectedpropinstances: objectarty; +begin + result:= nil; +end; + +{ tcollectionpropertyeditor } + +function tcollectionpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_subproperties,ps_volatile]; +end; + +function tcollectionpropertyeditor.name: msestring; +begin + result:= inherited name +'.count'; +end; + +function tcollectionpropertyeditor.getvalue: msestring; +var + col1: tcollection; +begin + col1:= tcollection(getpointervalue); + if col1 <> nil then begin + result:= inttostrmse(col1.count); + end + else begin + result:= ''; + end; +end; + +procedure tcollectionpropertyeditor.setvalue(const value: msestring); +var + int1,int2: integer; + va: integer; + col1: tcollection; +begin + col1:= tcollection(getpointervalue); + if col1 <> nil then begin + va:= strtoint(value); + if va < 0 then begin + va:= 0; + end + else begin + if va > propmaxarraycount then begin + va:= propmaxarraycount; + end; + end; + int1:= col1.count; + if ( int1 > va) then begin + if askok('Do you wish to delete items '+inttostrmse(va) + + ' to '+ inttostrmse(int1-1) + '?','CONFIRMATION') then begin + for int2:= int1 - 1 downto va do begin + col1.items[int2].free; + end; + end + else begin + exit; + end; + end + else begin + for int1:= 0 to high(fprops) do begin + with tcollection(getpointervalue(int1)) do begin + for int2:= count to va - 1 do begin + add; + end; + end; + end; + end; + modified; + end; +end; + +function tcollectionpropertyeditor.subproperties: propertyeditorarty; +var + col1: tcollection; + itemtypeinfo: ptypeinfo; + edtype: propertyeditorclassty; + int1: integer; +begin + col1:= tcollection(getpointervalue); + if col1 <> nil then begin + setlength(result,col1.count); + itemtypeinfo:= ptypeinfo(col1.itemclass.classinfo); + edtype:= propertyeditors.geteditorclass( + itemtypeinfo,fcomponent.classtype,ansistring(fname)); + for int1:= 0 to high(result) do begin + result[int1]:= tcollectionitemeditor.create(int1,self,edtype,fdesigner, + fobjectinspector,fprops,itemtypeinfo); + end; + end + else begin + result:= nil; + end; +end; + +procedure tcollectionpropertyeditor.dopopup(var amenu: tpopupmenu; + const atransientfor: twidget; var mouseinfo: mouseeventinfoty); +begin + if not (ps_noadditems in fstate) then begin + tpopupmenu.additems(amenu,atransientfor,mouseinfo, + ['Insert Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowinsert])+')', + 'Append Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowappend])+')'], + [],[],[@doinsert,@doappend]); + end; + inherited; +end; + +procedure tcollectionpropertyeditor.dokeydown(var ainfo: keyeventinfoty); +begin + if not (ps_noadditems in fstate) then begin + if issysshortcut(sho_rowinsert,ainfo) then begin + doinsert(nil); + include(ainfo.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowappend,ainfo) then begin + doappend(nil); + include(ainfo.eventstate,es_processed); + end; + end; + end; +end; + +procedure tcollectionpropertyeditor.doappend(const sender: tobject); +begin + with tcollection(getpointervalue) do begin + insert(count); + end; + modified; +end; + +procedure tcollectionpropertyeditor.doinsert(const sender: tobject); +begin + with tcollection(getpointervalue) do begin + insert(0); + end; + modified; +end; + +procedure tcollectionpropertyeditor.itemmoved(const source: integer; + const dest: integer); +begin + modified; +end; + +{ tenumpropertyeditor } + +function tenumpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist]; +end; + +function tenumpropertyeditor.getvalue: msestring; +begin + result:= msestring(getenumname(gettypeinfo,getordvalue)); +end; + +procedure tenumpropertyeditor.setvalue(const value: msestring); +begin + setordvalue(getenumvalue(gettypeinfo,ansistring(value))); +end; + +function tenumpropertyeditor.getvalues: msestringarty; +var + typedata1: ptypedata; + atypeinfo: ptypeinfo; +begin + atypeinfo:= gettypeinfo; + typedata1:= gettypedata(atypeinfo); + with typedata1^ do begin + if minvalue < 0 then begin //for boolean + setlength(result,2); + result[0]:= msestring(getenumname(atypeinfo,0)); + result[1]:= msestring(getenumname(atypeinfo,1)); + end + else begin + result:= getenumnames(atypeinfo); + end; + end; +end; + +function tenumpropertyeditor.gettypeinfo: ptypeinfo; +begin + result:= ftypeinfo; +end; + +{ tfontnamepropertyeditor } + +function tfontnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tfontnamepropertyeditor.getvalues: msestringarty; +begin + result:= getenumnames(typeinfo(stockfontty)); + stackarray(fontaliasnames,result); +end; + +{ tbooleanpropertyeditor } + +function tbooleanpropertyeditor.getdefaultstate: propertystatesty; +begin + Result:= inherited getdefaultstate + [ps_valuelist]; +end; + +procedure tbooleanpropertyeditor.setvalue(const value: msestring); +begin + setordvalue(longword(uppercase(trim(value)) = + uppercase(msestring(truename)))); +end; + +function tbooleanpropertyeditor.getvalue: msestring; +begin + if getordvalue <> 0 then begin + result:= truename; + end + else begin + result:= falsename; + end; +end; + +function tbooleanpropertyeditor.getvalues: msestringarty; +begin + setlength(result,2); + result[0]:= falsename; + result[1]:= truename; +end; + +{ tdialogclasspropertyeditor } + +function tdialogclasspropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog,ps_volatile]; +end; + +{ tbitmappropertyeditor } + +procedure tbitmappropertyeditor.edit; +var + bmp,bmp1: tmaskedbitmap; + int1: integer; + mstr1: filenamety; + format1: string; +begin + if imagefilepropedit(mstr1,format1) = mr_ok then begin + bmp:= tmaskedbitmap.create(bmk_rgb); + try + bmp.options:= bmp.options + [bmo_storeorigformat]; + bmp.loadfromfile(mstr1,format1,[]); + for int1:= 0 to high(fprops) do begin + bmp1:= tmaskedbitmap(getpointervalue(int1)); + if bmp1 <> nil then begin + bmp.alignment:= bmp1.alignment; + bmp.colorbackground:= bmp1.colorbackground; + bmp.colorforeground:= bmp1.colorforeground; + bmp.opacity:= bmp1.opacity; + bmp.transparentcolor:= bmp1.transparentcolor; + end; + setpointervalue(int1,bmp); + end; + modified; + finally + bmp.Free; + end; + end; +end; + +function tbitmappropertyeditor.getvalue: msestring; +begin + with tmaskedbitmap(getpointervalue) do begin + if source <> nil then begin + result:= msestring(fdesigner.getcomponentname(source)); + end + else begin + if isempty then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; + end; + end; +end; + +procedure tbitmappropertyeditor.setvalue(const value: msestring); +var + int1: integer; +begin + if value = '' then begin + for int1:= 0 to high(fprops) do begin + tmaskedbitmap(getpointervalue(int1)).clear; + end; + modified; + end; +end; + +{ trealpropertyeditor } + +function trealpropertyeditor.allequal: boolean; +var + int1: integer; + rea1: real; +begin + result:= inherited allequal; + if not result then begin + result:= true; + rea1:= getfloatvalue; + for int1:= 1 to high(fprops) do begin + if rea1 <> getfloatvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +procedure trealpropertyeditor.setvalue(const value: msestring); +begin + setfloatvalue(strtoreal(value)); +end; + +function trealpropertyeditor.getvalue: msestring; +begin + result:= msestring(realtostr(getfloatvalue)); +end; + +{ tcurrencypropertyeditor } + +function tcurrencypropertyeditor.allequal: boolean; +var + int1: integer; + cu1: currency; +begin + result:= inherited allequal; + if not result then begin + result:= true; + cu1:= getcurrencyvalue; + for int1:= 1 to high(fprops) do begin + if cu1 <> getcurrencyvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +procedure tcurrencypropertyeditor.setvalue(const value: msestring); +begin + setcurrencyvalue(strtoreal(value)); +end; + +function tcurrencypropertyeditor.getvalue: msestring; +begin + result:= currencytostrmse(getcurrencyvalue); +end; + +{ trealtypropertyeditor } + +function trealtypropertyeditor.allequal: boolean; +var + int1: integer; + rea1: real; +begin + result:= inherited allequal; + if not result then begin + result:= true; + rea1:= getfloatvalue; + for int1:= 1 to high(fprops) do begin + if rea1 <> getfloatvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function trealtypropertyeditor.getvalue: msestring; +begin + result:= realtytostring(getfloatvalue); +end; + +procedure trealtypropertyeditor.setvalue(const value: msestring); +begin + setfloatvalue(strtorealty(value)); +end; + +{ tdatetimepropertyeditor } + +function tdatetimepropertyeditor.allequal: boolean; +var + int1: integer; + rea1: real; +begin + result:= inherited allequal; + if not result then begin + result:= true; + rea1:= getfloatvalue; + for int1:= 1 to high(fprops) do begin + if rea1 <> getfloatvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tdatetimepropertyeditor.getvalue: msestring; +var + rea1: real; +begin +// result:= datetimetostring(getfloatvalue,'dddddd t'); + rea1:= getfloatvalue; + if rea1 = emptydatetime then begin + result:= ''; + end + else begin + if trunc(rea1) = 0 then begin + result:= datetimetostring(getfloatvalue,'hh:nn:ss'); + end + else begin + if frac(rea1) = 0 then begin + result:= datetimetostring(getfloatvalue,'yyyy-mm-dd'); + end + else begin + result:= datetimetostring(getfloatvalue,'yyyy-mm-dd hh:nn:ss'); + end; + end; + end; +end; + +procedure tdatetimepropertyeditor.setvalue(const value: msestring); + + function encdate(const str: msestring): real; + var + ar2: msestringarty; + year,month,day: word; + begin + result:= 0; + ar2:= splitstring(str,msechar('-')); + if high(ar2) >= 0 then begin + year:= strtoint(ar2[0]); + month:= 1; + day:= 1; + if high(ar2) > 0 then begin + month:= strtoint(ar2[1]); + if high(ar2) > 1 then begin + day:= strtoint(ar2[2]); + end; + end; + end + else begin + raise exception.create(ansistring(mo.c[ord(emptydate)]+'.')); + end; + result:= encodedate(year,month,day); + end; + + function enctime(const str: msestring): real; + var + ar2: msestringarty; + hour,minute,second: word; + begin + result:= 0; + ar2:= splitstring(str,msechar(':'),true); + if high(ar2) >= 0 then begin + hour:= strtoint(ar2[0]); + minute:= 0; + second:= 0; + if high(ar2) > 0 then begin + minute:= strtoint(ar2[1]); + if high(ar2) > 1 then begin + second:= strtoint(ar2[2]); + end; + end; + result:= encodetime(hour,minute,second,0); + end + else begin + raise exception.create(ansistring(mo.c[ord(emptytime)]+'.')); + end; + end; + +var + rea1,rea2: real; + ar1: msestringarty; + +begin + if value = '' then begin + rea1:= emptydatetime; + end + else begin + if value = ' ' then begin + rea1:= nowlocal; + end + else begin + rea1:= 0; + rea2:= 0; + ar1:= splitstring(value,msechar(' '),true); + if high(ar1) > 0 then begin + rea1:= encdate(ar1[0]); + rea2:= enctime(ar1[1]); + end + else begin + try + rea1:= encdate(ar1[0]); + except + rea1:= enctime(ar1[0]); + end; + end; + rea1:= rea1 + rea2; + end; + end; + setfloatvalue(rea1); +end; + +{ tvariantpropertyeditor } + +function tvariantpropertyeditor.allequal: boolean; +var + int1: integer; + var1: variant; +begin + result:= inherited allequal; + if not result then begin + result:= true; + var1:= getvariantvalue; + for int1:= 1 to high(fprops) do begin + if var1 <> getvariantvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +procedure tvariantpropertyeditor.setvalue(const value: msestring); +var + var1: variant; +begin + if value = '' then begin + fillchar(var1,sizeof(var1),0); + setvariantvalue(var1); + end + else begin + setvariantvalue(value); + end; +end; + +function tvariantpropertyeditor.getvalue: msestring; +var + var1: variant; +begin + var1:= getvariantvalue; + result:= ''; + if not varisnull(var1) then begin + try + result:= var1; + except + end; + end; +end; + +{ tshortcutpropertyeditor } + +constructor tshortcutpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fsc1:= pos('shortcut1',aprops[0].propinfo^.name) = 1; + inherited; +end; + +function tshortcutpropertyeditor.getvaluetext( + const avalue: shortcutty): msestring; +{ +var + int1,int2: integer; + keys: integerarty; + names: msestringarty; +} +begin + result:= getshortcutname(avalue); +{ + int2:= avalue; + if int2 = 0 then begin + result:= ''; + end + else begin + getshortcutlist(keys,names); + for int1:= 0 to high(keys) do begin + if int2 = keys[int1] then begin + result:= names[int1]; + exit; + end; + end; + result:= '$'+intvaluetostr(int2,nb_hex,16); + end; +} +end; + +procedure tshortcutpropertyeditor.setvalue(const value: msestring); +var + ar1: msestringarty; + ar2: shortcutarty; + int1: integer; + intf1: iactionlink; + p1: pointer; +begin + ar1:= splitstring(value,widechar(' ')); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar2[int1]:= texttovalue(ar1[int1]); + end; + for int1:= 0 to high(fprops) do begin + if getcorbainterface(fprops[int1].instance,typeinfo(iactionlink), + intf1) then begin + with intf1.getactioninfopo^ do begin + if fsc1 then begin + intf1.setshortcuts1(ar2); + end + else begin + intf1.setshortcuts(ar2); + end; + end; + modified; + end + else begin + if fscar then begin + p1:= getpointervalue(); + shortcutarty(p1):= ar2; //decref/incref + setpointervalue(p1); + end + else begin + if high(ar2) = 0 then begin + setordvalue(ar2[0]); + end + else begin + setordvalue(int1,0); + end; + end; + end; + end; +end; + +function tshortcutpropertyeditor.getvalue: msestring; + + function getartext(const ashortcuts: shortcutarty): msestring; + var + i1: integer; + begin + result:= ''; + for i1:= 0 to high(ashortcuts) do begin + result:= result + getvaluetext(ashortcuts[i1]) + ' '; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; + end; //getartext + +var + ar1: shortcutarty; + intf1: iactionlink; +begin + result:= ''; + if getcorbainterface(fprops[0].instance,typeinfo(iactionlink),intf1) then begin + with intf1.getactioninfopo^ do begin + if self.fsc1 then begin + ar1:= shortcut1; + end + else begin + ar1:= shortcut; + end; + result:= getartext(ar1); + end; + end + else begin + if fscar then begin + ar1:= shortcutarty(getpointervalue); + result:= getartext(ar1); + end + else begin + result:= getvaluetext(getordvalue); + end; + end; +end; + +function tshortcutpropertyeditor.getvalues: msestringarty; +var + keys: integerarty; + names: msestringarty; +begin + getshortcutlist(keys,names); + result:= names; +end; + +function tshortcutpropertyeditor.texttovalue(const atext: msestring): shortcutty; +var + int1: integer; + keys: integerarty; + s1: msestring; + names: msestringarty; +begin + getshortcutlist(keys,names); + s1:= strlowercase(atext); + for int1:= 0 to high(names) do begin + if s1 = strlowercase(names[int1]) then begin + result:= keys[int1]; + exit; + end; + end; + if atext = '' then begin + result:= 0; + end + else begin + result:= strtointvalue(atext,nb_hex); + end; +end; +{ +procedure tshortcutpropertyeditor.setvalue(const value: msestring); +begin + setordvalue(texttovalue(value)); +end; +} +{ tshortcutarpropertyeditor } + +constructor tshortcutarpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fscar:= true; + inherited; +end; + + { tcolorpropertyeditorty} + +function tcolorpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tcolorpropertyeditor.edit; +var + col1: colorty; +begin + col1:= getordvalue; + if colordialog(col1) = mr_ok then begin + setordvalue(col1); + end; +end; + +function tcolorpropertyeditor.getvalue: msestring; +begin + result:= msestring(colortostring(getordvalue)); +end; + +function tcolorpropertyeditor.getvalues: msestringarty; +begin + result:= getcolornames; +end; + +procedure tcolorpropertyeditor.setvalue(const value: msestring); +begin + setordvalue(stringtocolor(ansistring(value))); +end; + +{ tstringspropertyeditor } + +procedure tstringspropertyeditor.closequery(const sender: tcustommseform; var amodalresult: modalresultty); +var + int1: integer; +begin + if amodalresult = mr_ok then begin + try + with tstringlisteditor(sender),tstrings(getpointervalue) do begin + beginupdate; + try + clear; + for int1:= 0 to grid.rowcount-1 do begin + Add(ansistring(valueedit[int1])); + end; + finally + endupdate + end; + end; + modified; + except + application.handleexception(nil); + amodalresult:= mr_none; + end; + end; +end; + +procedure tstringspropertyeditor.edit; +var + editform: tstringlisteditor; + int1: integer; + strings: tstrings; +begin + strings:= tstrings(getpointervalue); + editform:= tstringlisteditor.create({$ifdef FPC}@{$endif}closequery); + try + with editform do begin + grid.rowcount:= strings.Count; + for int1:= 0 to strings.Count - 1 do begin + valueedit[int1]:= msestring(strings[int1]); + end; + show(true,nil); + end; + finally + editform.Free; + end; +end; + +function tstringspropertyeditor.getvalue: msestring; +begin + if tstrings(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; +end; + +{ ttextstringspropertyeditor } + +procedure ttextstringspropertyeditor.closequery(const sender: tcustommseform; + var amodalresult: modalresultty); +var + int1: integer; + utf8: boolean; + str1: ansistring; + backup: string; + backupm: msestringarty; +begin + fmodalresult:= amodalresult; + forigtext:= nil; + if (amodalresult = mr_ok) or (amodalresult = mr_canclose) then begin + try + with tmsetexteditorfo(sender) do begin + forigtext:= textedit.datalist.asmsestringarray; + try + if ismsestring then begin + with tmsestringdatalist(getpointervalue) do begin + backupm:= asarray; + beginupdate; + try + clear; + for int1:= 0 to grid.rowcount-1 do begin + add(textedit[int1]); + end; + finally + endupdate + end; + end; + end + else begin + with tstrings(getpointervalue) do begin + backup:= text; + utf8:= getutf8; + beginupdate; + try + clear; + for int1:= 0 to grid.rowcount-1 do begin + if utf8 then begin + str1:= stringtoutf8ansi(textedit[int1]); + end + else begin + str1:= ansistring(textedit[int1]); + end; + updateline(str1); + add(str1); + end; + finally + endupdate + end; + end; + end; + doafterclosequery(amodalresult); + finally + if amodalresult = mr_canclose then begin + if ismsestring then begin + with tmsestringdatalist(getpointervalue) do begin + asarray:= backupm; + end; + end + else begin + with tstrings(getpointervalue) do begin + text:= backup; + end; + end; + end; + end; + end; + except + application.handleexception(nil); +// if amodalresult = mr_canclose then begin + amodalresult:= mr_none; +// end; + end; + end; +end; + +procedure ttextstringspropertyeditor.edit; +var + editform: tmsetexteditorfo; + int1: integer; + strings: tstrings; + mstrings: tmsestringdatalist; + utf8: boolean; +begin + fmodalresult:= mr_cancel; + editform:= tmsetexteditorfo.create({$ifdef FPC}@{$endif}closequery, + msetexteditor.syntaxpainter,getsyntaxindex,gettestbutton); + editform.textedit.createfont; + editform.textedit.font.assign(textpropertyfont); + utf8:= getutf8; + try + with editform do begin + caption:= getcaption; + if ismsestring then begin + mstrings:= tmsestringdatalist(getpointervalue); + grid.rowcount:= mstrings.Count; + for int1:= 0 to mstrings.Count - 1 do begin + textedit[int1]:= mstrings[int1]; + end; + end + else begin + strings:= tstrings(getpointervalue); + grid.rowcount:= strings.Count; + for int1:= 0 to strings.Count - 1 do begin + if utf8 then begin + textedit[int1]:= utf8tostringansi(strings[int1]); + end + else begin + textedit[int1]:= msestring(strings[int1]); + end; + end; + end; + if show(true,nil) = mr_ok then begin + modified; + end; + end; + finally + editform.Free; + end; +end; + +function ttextstringspropertyeditor.getvalue: msestring; +begin + if ismsestring then begin + if tmsestringdatalist(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; + end + else begin + if tstrings(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; + end; +end; + +function ttextstringspropertyeditor.getsyntaxindex: integer; +begin + result:= -1; +end; + +procedure ttextstringspropertyeditor.doafterclosequery(var amodalresult: modalresultty); +begin + //dummy +end; + +function ttextstringspropertyeditor.gettestbutton: boolean; +begin + result:= false; +end; + +function ttextstringspropertyeditor.getutf8: boolean; +begin + result:= false; +end; + +procedure ttextstringspropertyeditor.setvalue(const avalue: msestring); +begin + if (avalue = '') and askok(mo.c[ord(wishclear)]+' "'+fname+'"?') then begin + if ismsestring then begin + tmsestringdatalist(getpointervalue).clear; + end + else begin + tstrings(getpointervalue).clear; + end; + end; + inherited; +end; + +function ttextstringspropertyeditor.getcaption: msestring; +begin + result:= mo.c[ord(texteditor)]; +end; + +procedure ttextstringspropertyeditor.updateline(var aline: ansistring); +begin + //dummy +end; + +function ttextstringspropertyeditor.ismsestring: boolean; +begin + result:= false; +end; + +{ tdatalistpropertyeditor } + +procedure tdatalistpropertyeditor.checkformkind; +var + datalist1: tdatalist; +begin + formkind:= lfk_none; + datalist1:= tdatalist(getpointervalue); + if datalist1 is tmsestringdatalist then begin + formkind:= lfk_msestring; + end + else begin + if datalist1 is trealdatalist then begin + formkind:= lfk_real; + end + else begin + if datalist1 is tintegerdatalist then begin + formkind:= lfk_integer; + end + else begin + if datalist1 is tmsestringintdatalist then begin + formkind:= lfk_msestringint; + end + else begin + if datalist1 is tcomplexdatalist then begin + formkind:= lfk_complex; + end + end; + end; + end; + end; +end; + +procedure tdatalistpropertyeditor.edit; +var + editform: tcustommseform; + realdata: trealdatalist; + complexdata: tcomplexdatalist; +begin + checkformkind; + case formkind of + lfk_msestring: begin + editform:= tstringlisteditor.create({$ifdef FPC}@{$endif}closequery); + end; + lfk_real: begin + editform:= treallisteditor.create({$ifdef FPC}@{$endif}closequery); + end; + lfk_integer: begin + editform:= tintegerlisteditor.create({$ifdef FPC}@{$endif}closequery); + end; + lfk_msestringint: begin + editform:= tmsestringintlisteditor.create({$ifdef FPC}@{$endif}closequery); + end; + lfk_complex: begin + editform:= tdoublereallisteditor.create({$ifdef FPC}@{$endif}closequery); + end; + else begin + editform:= nil; + end; + end; + try + if editform <> nil then begin + case formkind of + lfk_msestring: begin + tstringlisteditor(editform).valueedit.datalist.assign( + tmsestringdatalist(getpointervalue)); + end; + lfk_real: begin + realdata:= trealdatalist(getpointervalue); + with treallisteditor(editform).valueedit do begin + griddata.assign(realdata); + if realdata.defaultzero then begin + valuedefault:= 0; + end; + valuemin:= realdata.min; + valuemax:= realdata.max; + end; + end; + lfk_integer: begin + tintegerlisteditor(editform).valueedit.griddata.assign( + tintegerdatalist(getpointervalue)); + end; + lfk_msestringint: begin + with tmsestringintlisteditor(editform) do begin + texta.assigncol(tmsestringdatalist(getpointervalue)); + tmsestringintdatalist(getpointervalue).assigntob(textb.griddata); + end; + end; + lfk_complex: begin + complexdata:= tcomplexdatalist(getpointervalue); + with tdoublereallisteditor(editform) do begin + complexdata.assigntoa(vala.griddata); + complexdata.assigntob(valb.griddata); + if complexdata.defaultzero then begin + vala.valuedefault:= 0; + valb.valuedefault:= 0; + end; + vala.valuemin:= complexdata.min; + vala.valuemax:= complexdata.max; + valb.valuemin:= vala.valuemin; + valb.valuemax:= vala.valuemax; + end; + end; + end; + editform.show(true,nil); + end; + finally + editform.Free; + end; +end; + +function tdatalistpropertyeditor.getvalue: msestring; +var + datalist1: tdatalist; +begin + datalist1:= tdatalist(getpointervalue); + if datalist1 = nil then begin + result:= ''; + end + else begin + if datalist1.count = 0 then begin + result:= ''; + end + else begin + result:= msestring('<'+datalist1.classname+'>'); + end; + end; +end; + +procedure tdatalistpropertyeditor.closequery(const sender: tcustommseform; + var amodalresult: modalresultty); +var + datalist1: tdatalist; + int1: integer; +begin + if amodalresult = mr_ok then begin + try + for int1:= 0 to high (fprops) do begin + datalist1:= tdatalist(getpointervalue(int1)); + case formkind of + lfk_msestring: begin + tmsestringdatalist(datalist1).assign( + tstringlisteditor(sender).valueedit.datalist); + end; + lfk_real: begin + trealdatalist(datalist1).assign( + treallisteditor(sender).valueedit.griddata); + end; + lfk_integer: begin + tintegerdatalist(datalist1).assign( + tintegerlisteditor(sender).valueedit.griddata); + end; + lfk_msestringint: begin + with tmsestringintlisteditor(sender) do begin + tmsestringintdatalist(datalist1).assign(texta.griddata); + tmsestringintdatalist(datalist1).assignb(textb.griddata); + end; + end; + lfk_complex: begin + with tdoublereallisteditor(sender) do begin + tcomplexdatalist(datalist1).assign(vala.griddata); + tcomplexdatalist(datalist1).assignb(valb.griddata); + end; + end; + end; + modified; + end; + except + application.handleexception(nil); + amodalresult:= mr_none; + end; + end; +end; + +function tdatalistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + checkdatalistnostreaming(self,result); +end; + +{ tmsestringdatalistpropertyeditor } + +procedure tmsestringdatalistpropertyeditor.closequery(const sender: tcustommseform; + var amodalresult: modalresultty); +var + int1: integer; +begin + if amodalresult = mr_ok then begin + for int1:= 0 to high(fprops) do begin + try + tmsestringdatalist(getpointervalue(int1)).assign( + tstringlisteditor(sender).valueedit.datalist); + modified; + except + application.handleexception(nil); + amodalresult:= mr_none; + end; + end; + end; +end; + +procedure tmsestringdatalistpropertyeditor.edit; +var + editform: tstringlisteditor; +begin + editform:= tstringlisteditor.create({$ifdef FPC}@{$endif}closequery); + try + with editform do begin + valueedit.datalist.assign(tmsestringdatalist(getpointervalue)); + valueedit.editpos:= mgc(bigint,bigint); + show(true,nil); + end; + finally + editform.Free; + end; +end; + +function tmsestringdatalistpropertyeditor.getvalue: msestring; +begin + if tmsestringdatalist(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; +end; + +function tmsestringdatalistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + checkdatalistnostreaming(self,result); +end; + +{ tdoublemsestringdatalistpropertyeditor } + +procedure tdoublemsestringdatalistpropertyeditor.closequery( + const sender: tcustommseform; var amodalresult: modalresultty); +var + list: tdoublemsestringdatalist; +begin + if amodalresult = mr_ok then begin + try + with tdoublestringlisteditor(sender) do begin + {$warnings off} + list:= tdoublemsestringdatalist.create; + {$warnings on} + try + list.assign(texta.griddata); + list.assignb(textb.griddata); + tdoublemsestringdatalist(getpointervalue).assign(list); + modified; + finally + list.Free; + end; + end; + except + application.handleexception(nil); + amodalresult:= mr_none; + end; + end; +end; + +procedure tdoublemsestringdatalistpropertyeditor.edit; +var + editform: tdoublestringlisteditor; +begin + editform:= tdoublestringlisteditor.create({$ifdef FPC}@{$endif}closequery); + try + with editform do begin + texta.assigncol(tmsestringdatalist(getpointervalue)); + tdoublemsestringdatalist(getpointervalue).assigntob(textb.griddata); + show(true,nil); + end; + finally + editform.Free; + end; +end; + +function tdoublemsestringdatalistpropertyeditor.getvalue: msestring; +begin + if tdoublemsestringdatalist(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; +end; + +function tdoublemsestringdatalistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + checkdatalistnostreaming(self,result); +end; + +{ tmsestringintdatalistpropertyeditor } + +procedure tmsestringintdatalistpropertyeditor.closequery( + const sender: tcustommseform; var amodalresult: modalresultty); +var + list: tmsestringintdatalist; +begin + if amodalresult = mr_ok then begin + try + with tmsestringintlisteditor(sender) do begin +{$warnings off} + list:= tmsestringintdatalist.create; +{$warnings on} + try + list.assign(texta.griddata); + list.assignb(textb.griddata); + tmsestringintdatalist(getpointervalue).assign(list); + modified; + finally + list.Free; + end; + end; + except + application.handleexception(nil); + amodalresult:= mr_none; + end; + end; +end; + +procedure tmsestringintdatalistpropertyeditor.edit; +var + editform: tmsestringintlisteditor; +begin + editform:= tmsestringintlisteditor.create({$ifdef FPC}@{$endif}closequery); + try + with editform do begin + texta.assigncol(tmsestringdatalist(getpointervalue)); + tmsestringintdatalist(getpointervalue).assigntob(textb.griddata); + show(true,nil); + end; + finally + editform.Free; + end; +end; + +function tmsestringintdatalistpropertyeditor.getvalue: msestring; +begin + if tmsestringintdatalist(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; +end; + +function tmsestringintdatalistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + checkdatalistnostreaming(self,result); +end; + +{ trecordpropertyeditor } + +constructor trecordpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; const aname: string; + const subprops: propertyeditorarty); +var + int1: integer; +begin + inherited create(adesigner,amodule,acomponent,aobjectinspector,nil,nil); + fname:= msestring(aname); + fsubproperties:= subprops; + for int1:= 0 to high(fsubproperties) do begin + with fsubproperties[int1] do begin + include(fstate,ps_owned); + fparenteditor:= self; + end; + end; +end; + +function trecordpropertyeditor.allequal: boolean; +begin + result:= true; +end; + + +destructor trecordpropertyeditor.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fsubproperties) do begin + fsubproperties[int1].Free; + end; + inherited; +end; + +function trecordpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= [ps_subproperties]; +end; + +function trecordpropertyeditor.getvalue: msestring; +begin + result:= '_'; +end; + +function trecordpropertyeditor.subproperties: propertyeditorarty; +begin + result:= fsubproperties; +end; + +procedure trecordpropertyeditor.setsubprop; +var + int1: integer; +begin + inherited; + for int1:= 0 to high(fsubproperties) do begin + include(fsubproperties[int1].fstate,ps_subprop); + end; +end; + +{ tconstelementeditor } + +constructor tconstelementeditor.create(const avalue: msestring; aindex: integer; + aparenteditor: tarraypropertyeditor; aeditorclass: propertyeditorclassty; + const adesigner: idesigner; const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); +begin + fvalue:= avalue; + inherited create(aindex,aparenteditor,aeditorclass,adesigner,aobjectinspector, + aprops,atypinfo); +end; + +function tconstelementeditor.getvalue: msestring; +begin + result:= fvalue; +end; + +procedure tconstelementeditor.dragdrop(const sender: tpropertyeditor); +begin + if (sender is tarrayelementeditor) and + (tarrayelementeditor(sender).fparenteditor = fparenteditor) then begin +// sender.modified; +// modified; + tarraypropertyeditor(fparenteditor).itemmoved( + tarrayelementeditor(sender).findex,findex); + end; +end; + +{ tnamepropertyeditor } + +procedure tnamepropertyeditor.setvalue(const value: msestring); +begin + if (value <> '') and not isvalidident(ansistring(value)) then begin + raise exception.create( + ansistring(mo.c[ord(invalidcomponentname)]+' '''+value+'''.')); + end; + inherited; +end; + +{ trefreshstringpropertyeditor } + +function trefreshstringpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_refresh]; +end; + +{ tvolatilebooleanpropertyeditor } + +function tvolatilebooleanpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +{ trefreshbooleanpropertyeditor } + +function trefreshbooleanpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_refresh]; +end; + +{ tcomponentinterfacepropertyeditor } + +function tcomponentinterfacepropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +var + po1: pointer; +begin + result:= getcorbainterface(acomponent,fintfinfo,po1); +end; + +procedure tcomponentinterfacepropertyeditor.updatedefaultvalue; +begin + fintfinfo:= getintfinfo; +end; + +{ toptionaldatalistpropertyeditor } + +function toptionaldatalistpropertyeditor.getniltext: msestring; +begin + result:= ''; +end; + +function toptionaldatalistpropertyeditor.getinstance: tpersistent; +begin + result:= tpersistent(getpointervalue); +end; + +procedure toptionaldatalistpropertyeditor.deleteinstance; +begin + if checkfreeoptionalclass then begin + setordvalue(0); + end; +end; + +function toptionaldatalistpropertyeditor.canrevert: boolean; +begin + result:= false; +end; + +procedure toptionaldatalistpropertyeditor.setvalue(const avalue: msestring); +begin + if avalue = '' then begin + deleteinstance; + end + else begin + inherited; + end; +end; + +function toptionaldatalistpropertyeditor.getvalue: msestring; +begin + if getinstance = nil then begin + result:= getniltext; + end + else begin + result:= inherited getvalue; + end; +end; + +procedure toptionaldatalistpropertyeditor.edit; +var + obj1: tobject; +begin + obj1:= getinstance; + if obj1 = nil then begin + setordvalue(1); + end; + inherited; +end; + +function toptionaldatalistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +{ tvolatilesetpropertyeditor } + +function tvolatilesetpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +constructor tvolatilesetpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + inherited; +end; + +initialization +// apropertyeditors:= tpropertyeditors.Create; + application.createdatamodule(tmsepropertyeditorsmo,mo); +finalization + freeandnil(fpropertyeditors); + freeandnil(ftextpropertyfont); +end. diff --git a/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.mfm b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.mfm new file mode 100644 index 0000000..812d4b3 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.mfm @@ -0,0 +1,28 @@ +object msepropertyeditorsmo: tmsepropertyeditorsmo + bounds_cx = 100 + bounds_cy = 100 + left = 100 + top = 100 + moduleclassname = 'tmsedatamodule' + object c: tstringcontainer + strings.data = ( + 'Open image file' + 'Invalid set item' + 'Unknown' + 'Wrong property value' + 'Invalid method name' + 'Method name' + 'exists' + 'Do you wish to destroy' + 'Do you wish to delete items' + 'to' + 'Empty date' + 'Empty time' + 'Do you wish to clear' + 'Texteditor' + 'Invalid component name' + ) + left = 32 + top = 40 + end +end diff --git a/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.pas b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.pas new file mode 100644 index 0000000..3180753 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.pas @@ -0,0 +1,32 @@ +unit msepropertyeditorsmodule; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseapplication,mseclasses,msedatamodules,msestringcontainer,msestrings; + +type + stringconststy = ( + openimagefile, //0 Open image file + invalidsetitem, //1 Invalid set item + unknown, //2 Unknown + wrongpropertyvalue, //3 Wrong property value + invalidmethodname, //4 Invalid method name + str_methodname, //5 Method name + exists, //6 exists + wishdestroy, //7 Do you wish to destroy + wishdelete, //8 Do you wish to delete items + str_to, //9 to + emptydate, //10 Empty date + emptytime, //11 Empty time + wishclear, //12 Do you wish to clear + texteditor, //13 Texteditor + invalidcomponentname //14 Invalid component name + ); + + tmsepropertyeditorsmo = class(tmsedatamodule) + c: tstringcontainer; + end; +implementation +uses + msepropertyeditorsmodule_mfm; +end. diff --git a/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule_mfm.pas b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule_mfm.pas new file mode 100644 index 0000000..21724a1 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule_mfm.pas @@ -0,0 +1,38 @@ +unit msepropertyeditorsmodule_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msepropertyeditorsmodule; + +const + objdata: record size: integer; data: array[0..413] of byte end = + (size: 414; data: ( + 84,80,70,48,21,116,109,115,101,112,114,111,112,101,114,116,121,101,100,105, + 116,111,114,115,109,111,20,109,115,101,112,114,111,112,101,114,116,121,101,100, + 105,116,111,114,115,109,111,9,98,111,117,110,100,115,95,99,120,2,100,9, + 98,111,117,110,100,115,95,99,121,2,100,4,108,101,102,116,2,100,3,116, + 111,112,2,100,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,14,116,109,115,101,100,97,116,97,109,111,100,117,108,101,0,16,116,115, + 116,114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116,114, + 105,110,103,115,46,100,97,116,97,1,6,15,79,112,101,110,32,105,109,97, + 103,101,32,102,105,108,101,6,16,73,110,118,97,108,105,100,32,115,101,116, + 32,105,116,101,109,6,7,85,110,107,110,111,119,110,6,20,87,114,111,110, + 103,32,112,114,111,112,101,114,116,121,32,118,97,108,117,101,6,19,73,110, + 118,97,108,105,100,32,109,101,116,104,111,100,32,110,97,109,101,6,11,77, + 101,116,104,111,100,32,110,97,109,101,6,6,101,120,105,115,116,115,6,22, + 68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,100,101,115,116,114, + 111,121,6,27,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,100, + 101,108,101,116,101,32,105,116,101,109,115,6,2,116,111,6,10,69,109,112, + 116,121,32,100,97,116,101,6,10,69,109,112,116,121,32,116,105,109,101,6, + 20,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,99,108,101,97, + 114,6,10,84,101,120,116,101,100,105,116,111,114,6,22,73,110,118,97,108, + 105,100,32,99,111,109,112,111,110,101,110,116,32,110,97,109,101,0,4,108, + 101,102,116,2,32,3,116,111,112,2,40,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsepropertyeditorsmo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msereallisteditor.mfm b/mseide-msegui/lib/common/designutils/msereallisteditor.mfm new file mode 100644 index 0000000..a28ec21 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msereallisteditor.mfm @@ -0,0 +1,111 @@ +object reallisteditor: treallisteditor + visible = False + bounds_x = 182 + bounds_y = 208 + bounds_cx = 128 + bounds_cy = 297 + container.bounds = ( + 0 + 0 + 128 + 297 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = tstatfile1 + caption = 'Reallisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + taborder = 3 + bounds_x = 4 + bounds_y = 269 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + bounds_x = 68 + bounds_y = 269 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object grid: twidgetgrid + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 131 + bounds_cy = 241 + anchors = [an_top, an_bottom] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstep = 1 + end> + zebra_start = 1 + zebra_height = 1 + datacols.count = 1 + datacols.items = < + item[valueedit] + width = 101 + options = [co_fill, co_savevalue, co_savestate] + widgetname = 'valueedit' + dataclass = tgridrealdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object valueedit: trealedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.dummy = 0 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 101 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + value = -Inf + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + min = -Inf + max = 1E+038 + reffontheight = 14 + end + end + object rowcount: tintegeredit + frame.caption = 'Rowcount' + frame.captionpos = cp_right + frame.dummy = 0 + frame.outerframe = ( + 0 + 0 + 64 + 0 + ) + taborder = 2 + bounds_x = 4 + bounds_y = 245 + bounds_cx = 116 + anchors = [an_left, an_bottom] + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'stringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/msereallisteditor.pas b/mseide-msegui/lib/common/designutils/msereallisteditor.pas new file mode 100644 index 0000000..4d090c3 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msereallisteditor.pas @@ -0,0 +1,61 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msereallisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,msetextedit, + msestat,msestatfile; + +const + reallisteditorstatname = 'reallisteditor.sta'; + +type + treallisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + rowcount: tintegeredit; + valueedit: trealedit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + msereallisteditor_mfm,mseglob; + +{ treallisteditor } + +constructor treallisteditor.create(const aonclosequery: closequeryeventty); +begin + inherited create(nil); + onclosequery:= aonclosequery; +end; + +procedure treallisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure treallisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msereallisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msereallisteditor_mfm.pas new file mode 100644 index 0000000..9169e3b --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msereallisteditor_mfm.pas @@ -0,0 +1,109 @@ +unit msereallisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msereallisteditor; + +const + objdata: record size: integer; data: array[0..1831] of byte end = + (size: 1832; data: ( + 84,80,70,48,15,116,114,101,97,108,108,105,115,116,101,100,105,116,111,114, + 14,114,101,97,108,108,105,115,116,101,100,105,116,111,114,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,182,0,8,98,111,117, + 110,100,115,95,121,3,208,0,9,98,111,117,110,100,115,95,99,120,3,128, + 0,9,98,111,117,110,100,115,95,99,121,3,41,1,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,128,0,3, + 41,1,0,7,111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115, + 101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116, + 97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10, + 102,111,95,115,97,118,101,112,111,115,0,8,115,116,97,116,102,105,108,101, + 7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110, + 6,14,82,101,97,108,108,105,115,116,101,100,105,116,111,114,15,109,111,100, + 117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111, + 114,109,0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98,111,114, + 100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,4,8,98,111,117, + 110,100,115,95,121,3,13,1,9,98,111,117,110,100,115,95,99,120,2,50, + 9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0, + 5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97, + 115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114, + 95,111,107,0,0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108, + 8,98,111,117,110,100,115,95,120,2,68,8,98,111,117,110,100,115,95,121, + 3,13,1,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110, + 100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7, + 99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100, + 97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0, + 0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,131,0,9,98,111,117,110,100,115,95,99,121,3,241,0,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116, + 116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103, + 95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114,111,119, + 109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116,105, + 110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19,111,103, + 95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15,111,103, + 95,97,117,116,111,102,105,114,115,116,114,111,119,10,111,103,95,119,114,97, + 112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102, + 105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111, + 108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,24,7,110, + 117,109,115,116,101,112,2,1,0,0,11,122,101,98,114,97,95,115,116,97, + 114,116,2,1,12,122,101,98,114,97,95,104,101,105,103,104,116,2,1,14, + 100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1,14,100,97,116, + 97,99,111,108,115,46,105,116,101,109,115,14,7,9,118,97,108,117,101,101, + 100,105,116,1,5,119,105,100,116,104,2,101,7,111,112,116,105,111,110,115, + 11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108, + 117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100, + 103,101,116,110,97,109,101,6,9,118,97,108,117,101,101,100,105,116,9,100, + 97,116,97,99,108,97,115,115,7,17,116,103,114,105,100,114,101,97,108,100, + 97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,16,17,111,110,114,111,119,99,111,117,110,116,99,104,97,110, + 103,101,100,7,21,103,114,105,100,111,110,114,111,119,99,111,117,110,116,99, + 104,97,110,103,101,100,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,9,116,114,101,97,108,101,100,105,116,9,118,97,108,117,101,101, + 100,105,116,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,11,102,114,97,109,101,46,100,117,109,109,121,2,0,8,116,97,98,111, + 114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,101,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 115,97,118,101,118,97,108,117,101,0,5,118,97,108,117,101,5,0,0,0, + 0,0,0,0,128,255,255,12,118,97,108,117,101,100,101,102,97,117,108,116, + 5,0,0,0,0,0,0,0,128,255,255,10,118,97,108,117,101,114,97,110, + 103,101,2,1,10,118,97,108,117,101,115,116,97,114,116,2,0,3,109,105, + 110,5,0,0,0,0,0,0,0,128,255,255,3,109,97,120,5,245,136,13, + 181,80,153,118,150,125,64,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,8, + 114,111,119,99,111,117,110,116,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,8,82,111,119,99,111,117,110,116,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,11, + 102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,64,2,0,0, + 8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120, + 2,4,8,98,111,117,110,100,115,95,121,3,245,0,9,98,111,117,110,100, + 115,95,99,120,2,116,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,9,97,110,95,98,111,116,116,111,109,0,10,111,110,115,101,116, + 118,97,108,117,101,7,18,114,111,119,99,111,117,110,116,111,110,115,101,116, + 118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116,102, + 105,108,101,49,8,102,105,108,101,110,97,109,101,6,20,115,116,114,105,110, + 103,108,105,115,116,101,100,105,116,111,114,46,115,116,97,7,111,112,116,105, + 111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102, + 116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,treallisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseresourcetools.pas b/mseide-msegui/lib/common/designutils/mseresourcetools.pas new file mode 100644 index 0000000..89989e2 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseresourcetools.pas @@ -0,0 +1,163 @@ +{ MSEgui Copyright (c) 2004-2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseresourcetools; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msestrings,sysutils,classes,mclasses,mseparser; + +function rsjgetconsts(const astream: tstream): constinfoarty; +procedure resourcetexttoresourcesource(const sourcefilename: filenamety; + const unitname: string; const fpcformat: boolean); + //FPC resourcestringtable to resourceunit +implementation +uses + mseformdatatools,msefileutils,msestream,msesys,typinfo, + mseclasses,msejson; + +const + destfileext = '.pas'; + dataname = 'resourcedata'; + +procedure rsjarraystart(var adata; const acount: int32); +begin + setlength(constinfoarty(adata),acount); +end; + +procedure rsjarrayitem(var adata; const aindex: int32; + const avalue: jsonvaluety); +begin + with constinfoarty(adata)[aindex] do begin + name:= stringtoutf8ansi(jsonasstring(avalue,['name'])); + value:= jsonasstring(avalue,['value']); + hash:= jsonasint32(avalue,['hash']); + valuetype:= vawstring; + end; +end; + +function rsjgetconsts(const astream: tstream): constinfoarty; +var + json: tjsoncontainer; +begin + json:= nil; + try + try + json:= tjsoncontainer.create(astream.readdatastring); + json.iteratearray(['strings'],result,@rsjarraystart,@rsjarrayitem); + except + on e: exception do begin + if astream is tmsefilestream then begin + e.message:= ansistring(tmsefilestream(astream).filename)+':'+lineend+e.message; + end; + raise; + end; + end; + finally + json.free(); + end; +end; + +procedure resourcetexttoresourcesource(const sourcefilename: filenamety; + const unitname: string; const fpcformat: boolean); +var + instream: ttextstream; + outstream: ttextstream; + outfilename: filenamety; +// mstr1: msestring; + scanner: tscanner; + parser: tparser; + ar1: constinfoarty; + int1: integer; + int2: integer; + str1: string; +// po1: pbyte; +begin + instream:= ttextstream.create(sourcefilename,fm_read); + try + if fpcformat and (fileext(sourcefilename) = 'rsj') then begin + ar1:= rsjgetconsts(instream); + end + else begin + scanner:= nil; + parser:= nil; + try + scanner:= tpascalscanner.Create; + scanner.source:= instream.readdatastring; + if fpcformat then begin + parser:= tfpcresstringparser.create(nil); + end + else begin + parser:= tresstringlistparser.Create(nil); + end; + parser.scanner:= scanner; + if fpcformat then begin + tfpcresstringparser(parser).getconsts(ar1); + end + else begin + tresstringlistparser(parser).getconsts(ar1); + end; + finally + parser.free; + scanner.free; + end; + end; + finally + instream.free; + end; + str1:= ''; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if valuetype = vawstring then begin + if not fpcformat then begin + for int2:= 1 to length(name) do begin + if name[int1] = '_' then begin + name[int1]:= '.'; + break; + end; + end; + end; + str1:= str1 + name + #0 + stringtoutf8ansi(value) + #0; + end; + end; + end; + outfilename:= filedir(sourcefilename) + msestring(unitname) + destfileext; + outstream:= ttextstream.create(outfilename,fm_create); + try + outstream.writeln('unit ' + unitname + ';'); + outstream.writeln(compilerdefaults); + outstream.writeln(''); + outstream.writeln('interface'); + outstream.writeln(''); + outstream.writeln('implementation'); + outstream.writeln('uses'); + outstream.writeln(' msei18nglob,mselanglink;'); + writeconstdata(pbyte(pchar(str1)),length(str1),dataname,outstream); + outstream.writeln('var'); + outstream.writeln(' hookbefore: registerresourcehookty;'); + outstream.writeln(''); + outstream.writeln( + 'procedure registerresource(const registerresourceproc: registerresourcety);'); + outstream.writeln('begin'); + outstream.writeln( + ' registerresourceproc(@'+dataname+');'); + outstream.writeln(' registerresourcehook:= hookbefore;'); + outstream.writeln('end;'); + outstream.writeln(''); + outstream.writeln('initialization'); + outstream.writeln(' hookbefore:= registerresourcehook;'); + outstream.writeln(' registerresourcehook:= @registerresource;'); + outstream.writeln('end.'); + finally + outstream.free; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mserichstringeditor.mfm b/mseide-msegui/lib/common/designutils/mserichstringeditor.mfm new file mode 100644 index 0000000..fa57684 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mserichstringeditor.mfm @@ -0,0 +1,113 @@ +object richstringeditorfo: trichstringeditorfo + visible = False + bounds_x = 110 + bounds_y = 237 + bounds_cx = 409 + bounds_cy = 297 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 409 + 297 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + caption = 'Enter Memo Text' + moduleclassname = 'tmseform' + object memo: trichmemoedit + frame.localprops = [frl_colorclient] + frame.localprops1 = [] + frame.sbhorz.pagesize = 1 + frame.sbvert.pagesize = 1 + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 409 + bounds_cy = 268 + anchors = [an_top, an_bottom] + optionsedit1 = [oe1_multiline, oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_shiftreturn, oe_resetselectonexit, oe_nofirstarrownavig, oe_caretonreadonly] + reffontheight = 14 + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 72 + bounds_y = 272 + bounds_cx = 330 + bounds_cy = 20 + anchors = [an_left, an_right, an_bottom] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 8 + place_maxdist = 8 + place_mode = wam_end + linktop = memo + dist_top = 4 + options = [spao_gluebottom] + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 278 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + font.name = 'stf_default' + font.localprops = [] + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 220 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object tbutton3: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 2 + bounds_x = 126 + bounds_y = 0 + bounds_cx = 86 + bounds_cy = 20 + bounds_cxmin = 50 + action = formatedact + reffontheight = 14 + end + end + object tstatfile1: tstatfile + filename = 'richmemodialog.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 64 + top = 104 + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + action = formatedact + end> + left = 168 + top = 104 + end + object formatedact: taction + caption = '&Font Format' + options = [ao_updateonidle] + onexecute = fontformateditev + onupdate = updateactev + left = 168 + top = 144 + end +end diff --git a/mseide-msegui/lib/common/designutils/mserichstringeditor.pas b/mseide-msegui/lib/common/designutils/mserichstringeditor.pas new file mode 100644 index 0000000..5588846 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mserichstringeditor.pas @@ -0,0 +1,81 @@ +{ MSEgui Copyright (c) 2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mserichstringeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msedataedits,mseedit,msestrings, + msetypes,msestatfile,msesimplewidgets,msewidgets,msedialog,classes,mclasses, + msedropdownlist,msesplitter,mserichstring,mseactions,mseact; + +type + trichstringeditorfo = class(tmseform) + memo: trichmemoedit; + tstatfile1: tstatfile; + tlayouter1: tlayouter; + tbutton2: tbutton; + tbutton1: tbutton; + tpopupmenu1: tpopupmenu; + tbutton3: tbutton; + formatedact: taction; + procedure fontformateditev(const sender: TObject); + procedure updateactev(const sender: tcustomaction); + public + constructor create(const aowner: tcomponent; const readonly: boolean); + reintroduce; + end; + +function richstringdialog(var avalue: richstringty; + const readonly: boolean): modalresultty; + +implementation +uses + mserichstringeditor_mfm,mseeditglob,msekeyboard,msestockobjects, + msefontformatdialog; + +function richstringdialog(var avalue: richstringty; + const readonly: boolean): modalresultty; +var + dia1: trichstringeditorfo; +begin + dia1:= trichstringeditorfo.create(nil,readonly); + try + dia1.memo.richvalue:= avalue; + result:= dia1.show(true); + if result = mr_ok then begin + avalue:= dia1.memo.richvalue; + end; + finally + dia1.free; + end; +end; + +{ trichstringeditorfo } + +constructor trichstringeditorfo.create(const aowner: tcomponent; + const readonly: boolean); +begin + inherited create(aowner); + memo.readonly:= readonly; +end; + +procedure trichstringeditorfo.fontformateditev(const sender: TObject); +begin + memo.formatvalue:= editfontformat(memo.formatvalue, + memo.editor.selstart,memo.editor.sellength); +end; + +procedure trichstringeditorfo.updateactev(const sender: tcustomaction); +begin + sender.enabled:= memo.editor.hasselection; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mserichstringeditor_mfm.pas b/mseide-msegui/lib/common/designutils/mserichstringeditor_mfm.pas new file mode 100644 index 0000000..c0d0669 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mserichstringeditor_mfm.pas @@ -0,0 +1,136 @@ +unit mserichstringeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mserichstringeditor; + +const + objdata: record size: integer; data: array[0..2379] of byte end = + (size: 2380; data: ( + 84,80,70,48,19,116,114,105,99,104,115,116,114,105,110,103,101,100,105,116, + 111,114,102,111,18,114,105,99,104,115,116,114,105,110,103,101,100,105,116,111, + 114,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,2,110,8,98,111,117,110,100,115,95,121,3,237,0,9,98,111,117,110, + 100,115,95,99,120,3,153,1,9,98,111,117,110,100,115,95,99,121,3,41, + 1,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0, + 2,0,3,153,1,3,41,1,0,7,111,112,116,105,111,110,115,11,17,102, + 111,95,115,99,114,101,101,110,99,101,110,116,101,114,101,100,13,102,111,95, + 99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101, + 97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115, + 116,97,116,10,102,111,95,115,97,118,101,112,111,115,12,102,111,95,115,97, + 118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,10,116, + 115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6,15,69, + 110,116,101,114,32,77,101,109,111,32,84,101,120,116,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109, + 0,13,116,114,105,99,104,109,101,109,111,101,100,105,116,4,109,101,109,111, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,21,102,114,97,109, + 101,46,115,98,104,111,114,122,46,112,97,103,101,115,105,122,101,2,1,21, + 102,114,97,109,101,46,115,98,118,101,114,116,46,112,97,103,101,115,105,122, + 101,2,1,9,112,111,112,117,112,109,101,110,117,7,11,116,112,111,112,117, + 112,109,101,110,117,49,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,153, + 1,9,98,111,117,110,100,115,95,99,121,3,12,1,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 109,117,108,116,105,108,105,110,101,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,108, + 105,110,101,98,114,101,97,107,14,111,101,95,115,104,105,102,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,20,111,101,95,110,111,102,105,114,115,116,97,114,114,111,119, + 110,97,118,105,103,18,111,101,95,99,97,114,101,116,111,110,114,101,97,100, + 111,110,108,121,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117, + 116,101,114,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11, + 111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110, + 116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,3,16, + 1,9,98,111,117,110,100,115,95,99,120,3,74,1,9,98,111,117,110,100, + 115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107, + 121,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17, + 111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111, + 112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108, + 97,99,101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105, + 103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112, + 108,97,99,101,95,109,105,110,100,105,115,116,2,8,13,112,108,97,99,101, + 95,109,97,120,100,105,115,116,2,8,10,112,108,97,99,101,95,109,111,100, + 101,7,7,119,97,109,95,101,110,100,7,108,105,110,107,116,111,112,7,4, + 109,101,109,111,8,100,105,115,116,95,116,111,112,2,4,7,111,112,116,105, + 111,110,115,11,15,115,112,97,111,95,103,108,117,101,98,111,116,116,111,109, + 0,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95, + 97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105, + 100,116,104,0,8,98,111,117,110,100,115,95,120,3,22,1,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,52,9, + 98,111,117,110,100,115,95,99,121,2,20,12,98,111,117,110,100,115,95,99, + 120,109,105,110,2,50,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7, + 38,67,97,110,99,101,108,9,102,111,110,116,46,110,97,109,101,6,11,115, + 116,102,95,100,101,102,97,117,108,116,15,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,0,11,109,111,100,97,108,114,101,115,117,108,116, + 7,9,109,114,95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,49,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49, + 95,97,117,116,111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,3,220,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111, + 117,110,100,115,95,99,121,2,20,12,98,111,117,110,100,115,95,99,120,109, + 105,110,2,50,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117, + 108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116, + 105,111,110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116, + 7,5,109,114,95,111,107,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111, + 110,51,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111, + 119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116, + 111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,2,8,98, + 111,117,110,100,115,95,120,2,126,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,86,9,98,111,117,110,100,115,95, + 99,121,2,20,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,6, + 97,99,116,105,111,110,7,11,102,111,114,109,97,116,101,100,97,99,116,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116, + 115,116,97,116,102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8, + 102,105,108,101,110,97,109,101,6,18,114,105,99,104,109,101,109,111,100,105, + 97,108,111,103,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102, + 111,95,109,101,109,111,114,121,17,115,102,111,95,97,99,116,105,118,97,116, + 111,114,114,101,97,100,18,115,102,111,95,97,99,116,105,118,97,116,111,114, + 119,114,105,116,101,0,4,108,101,102,116,2,64,3,116,111,112,2,104,0, + 0,10,116,112,111,112,117,112,109,101,110,117,11,116,112,111,112,117,112,109, + 101,110,117,49,18,109,101,110,117,46,115,117,98,109,101,110,117,46,99,111, + 117,110,116,2,1,18,109,101,110,117,46,115,117,98,109,101,110,117,46,105, + 116,101,109,115,14,1,6,97,99,116,105,111,110,7,11,102,111,114,109,97, + 116,101,100,97,99,116,0,0,4,108,101,102,116,3,168,0,3,116,111,112, + 2,104,0,0,7,116,97,99,116,105,111,110,11,102,111,114,109,97,116,101, + 100,97,99,116,7,99,97,112,116,105,111,110,6,12,38,70,111,110,116,32, + 70,111,114,109,97,116,7,111,112,116,105,111,110,115,11,15,97,111,95,117, + 112,100,97,116,101,111,110,105,100,108,101,0,9,111,110,101,120,101,99,117, + 116,101,7,16,102,111,110,116,102,111,114,109,97,116,101,100,105,116,101,118, + 8,111,110,117,112,100,97,116,101,7,11,117,112,100,97,116,101,97,99,116, + 101,118,4,108,101,102,116,3,168,0,3,116,111,112,3,144,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,trichstringeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msesettings.mfm b/mseide-msegui/lib/common/designutils/msesettings.mfm new file mode 100644 index 0000000..647ddca --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesettings.mfm @@ -0,0 +1,571 @@ +object settingsfo: tsettingsfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 100 + bounds_y = 106 + bounds_cx = 348 + bounds_cy = 570 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 348 + 570 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + caption = 'Configure MSE environment' + windowopacity = -Inf + oncreate = formoncreate + moduleclassname = 'tmseform' + object tsplitter1: tsplitter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + taborder = 2 + bounds_x = 0 + bounds_y = 520 + bounds_cx = 348 + bounds_cy = 38 + anchors = [an_bottom] + optionsscale = [osc_expandy, osc_shrinky] + linktop = macrogrid + grip = stb_none + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 2 + bounds_x = 283 + bounds_y = 16 + bounds_cx = 52 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 225 + bounds_y = 16 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object shortcutbu: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 9 + bounds_y = 16 + bounds_cx = 78 + bounds_cy = 22 + bounds_cxmin = 78 + state = [as_localcaption, as_localonexecute] + caption = '&Shortcuts' + onexecute = editshortcuts + reffontheight = 14 + end + object tspacer2: tspacer + taborder = 3 + bounds_x = 275 + bounds_y = 16 + bounds_cx = 8 + bounds_cy = 20 + linkleft = tbutton1 + linkright = tbutton2 + options = [spao_glueright] + end + end + object tlayouter1: tlayouter + bounds_x = 0 + bounds_y = 0 + bounds_cx = 348 + bounds_cy = 407 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placey] + linkbottom = macrogrid + object tspacer1: tlayouter + taborder = 9 + bounds_x = 8 + bounds_y = 333 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + place_options = [plo_scalesize, plo_endmargin] + object targetosdir: tstringedit + Tag = 11 + frame.caption = '${TARGETOSDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 178 + bounds_y = 0 + bounds_cx = 152 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + reffontheight = 14 + end + object target: tstringedit + Tag = 10 + frame.caption = '${TARGET}' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 82 + bounds_y = 0 + bounds_cx = 92 + bounds_cy = 37 + onsetvalue = setvalue + reffontheight = 14 + end + object exeext: tstringedit + Tag = 9 + frame.caption = '${EXEEXT}' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 78 + bounds_cy = 37 + onsetvalue = setvalue + reffontheight = 14 + end + end + object printcomm: tstringedit + frame.caption = 'Print command' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 10 + bounds_x = 8 + bounds_y = 370 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setprintcomm + reffontheight = 14 + end + object debugger: tfilenameedit + Tag = 8 + frame.caption = '${DEBUGGER}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 8 + hint = 'Path to debugger (gdb).' + bounds_x = 8 + bounds_y = 296 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.captionopen = 'Debugger path' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object compiler: tfilenameedit + Tag = 7 + frame.caption = '${COMPILER}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + hint = 'Path to compiler (ppc386).' + bounds_x = 8 + bounds_y = 259 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.captionopen = 'Compiler path' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object compstoredir: tfilenameedit + Tag = 6 + frame.caption = '${COMPSTOREDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + hint = 'Directory for component store files.' + bounds_x = 8 + bounds_y = 222 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.filterlist.data = ( + ( + 'Project files' + '*.prj' + ) + ) + controller.options = [fdo_directory] + controller.captionopen = 'Directory for component stores' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object templatedir: tfilenameedit + Tag = 5 + frame.caption = '${TEMPLATEDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + hint = 'Directory for project template files.' + bounds_x = 8 + bounds_y = 185 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.filterlist.data = ( + ( + 'Project files' + '*.prj' + ) + ) + controller.options = [fdo_directory] + controller.captionopen = 'Project template directory' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object syntaxdefdir: tfilenameedit + Tag = 4 + frame.caption = '${SYNTAXDEFDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + hint = 'Directory for syntax definition files.' + bounds_x = 8 + bounds_y = 148 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.filterlist.data = ( + ( + 'Syntax definitions' + '*.sdef' + ) + ) + controller.options = [fdo_directory] + controller.captionopen = 'Directory for syntax definition files' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object mselibdir: tfilenameedit + Tag = 3 + frame.caption = '${MSELIBDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + hint = 'Root directory of MSEgui library.' + bounds_x = 8 + bounds_y = 111 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.options = [fdo_directory] + controller.captionopen = 'MSEgui library directory' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object msedir: tfilenameedit + Tag = 2 + frame.caption = '${MSEDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + hint = 'Root directory of MSEgui.' + bounds_x = 8 + bounds_y = 74 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.options = [fdo_directory] + controller.captionopen = 'MSEgui root directory' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object fpclibdir: tfilenameedit + Tag = 1 + frame.caption = '${FPCLIBDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + hint = 'Root directory of FPC library (not used by the default project templates).' + bounds_x = 8 + bounds_y = 37 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + controller.options = [fdo_directory] + controller.captionopen = 'FPC library directory' + reffontheight = 14 + end + object fpcdir: tfilenameedit + frame.caption = '${FPCDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + hint = 'Root directory of Free Pascal system (not used by the default project templates).' + bounds_x = 8 + bounds_y = 0 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.options = [fdo_directory] + controller.captionopen = 'FPC root directory' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + end + object macrogrid: twidgetgrid + frame.caption = 'Global Macros' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 407 + bounds_cx = 330 + bounds_cy = 113 + bounds_cymin = 80 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_noinsertempty, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 28 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 4 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Value' + end + item + end + item + end> + end> + datacols.count = 2 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[macroname] + width = 151 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'macroname' + dataclass = tgridmsestringdatalist + end + item[macrovalue] + width = 144 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'macrovalue' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = tstatfile1 + reffontheight = 14 + object macroname: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 151 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object macrovalue: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 152 + bounds_y = 0 + bounds_cx = 144 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + end + object tstatfile1: tstatfile + filename = 'settingsfo.sta' + options = [sfo_memory] + left = 16 + top = 32 + end +end diff --git a/mseide-msegui/lib/common/designutils/msesettings.pas b/mseide-msegui/lib/common/designutils/msesettings.pas new file mode 100644 index 0000000..c10d9d0 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesettings.pas @@ -0,0 +1,312 @@ +{ MSEide Copyright (c) 2002-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msesettings; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseglob,mseguiglob,msegui,mseclasses,mseforms,msestat,msestatfile, + msesimplewidgets,msefiledialog,msestrings,msemacros,msedataedits,msebitmap, + msedatanodes,mseedit,mseevent,msegraphutils,msegrids,mselistbrowser,msemenus, + msesys,msetypes,msegraphics,msewidgets,mseactions,mseifiglob,msesplitter, + mseificomp,mseificompglob,msememodialog,msewidgetgrid; + +type + settingsmacroty = (sma_fpcdir,sma_fpclibdir,sma_msedir,sma_mselibdir, + sma_syntaxdefdir,sma_templatedir,sma_compstoredir, + sma_compiler,sma_debugger, + sma_exeext,sma_target,sma_targetosdir); +const + statdirname = '^/.mseide'; + settingsmacronames: array[settingsmacroty] of msestring = ( + 'fpcdir','fpclibdir','msedir','mselibdir','syntaxdefdir', + 'templatedir','compstoredir','compiler','debugger', + 'exeext','target','targetosdir'); + {$ifdef mswindows} + defaultsettingmacros: array[settingsmacroty] of msestring = ( + '','','','${MSEDIR}lib/common/','${MSEDIR}apps/ide/syntaxdefs/', + '${MSEDIR}apps/ide/templates/','${MSEDIR}apps/ide/compstore/', + 'ppc386.exe','gdb.exe','.exe','i386-win32','windows'); + {$else} + {$ifdef CPU64} + defaultsettingmacros: array[settingsmacroty] of msestring = ( + '','','','${MSEDIR}lib/common/','${MSEDIR}apps/ide/syntaxdefs/', + '${MSEDIR}apps/ide/templates/','${MSEDIR}apps/ide/compstore/', + 'ppcx64','gdb','','x86_64-linux','linux'); + {$else} + {$ifdef CPUARM} + defaultsettingmacros: array[settingsmacroty] of msestring = ( + '','','','${MSEDIR}lib/common/','${MSEDIR}apps/ide/syntaxdefs/', + '${MSEDIR}apps/ide/templates/','${MSEDIR}apps/ide/compstore/', + 'ppcarm','gdb','','arm-linux','linux'); + {$else} + defaultsettingmacros: array[settingsmacroty] of msestring = ( + '','','','${MSEDIR}lib/common/','${MSEDIR}apps/ide/syntaxdefs/', + '${MSEDIR}apps/ide/templates/','${MSEDIR}apps/ide/compstore/', + 'ppc386','gdb','','i386-linux','linux'); + {$endif} + {$endif} + {$endif} + +type + settingsmacroarty = array[settingsmacroty] of filenamety; + settingsmacrosty = record + macros: settingsmacroarty; + globmacronames: msestringarty; + globmacrovalues: msestringarty; + end; + settingsty = record + macros: settingsmacrosty; + printcommand: msestring; + end; + + tsettingsfo = class(tmseform) + tstatfile1: tstatfile; + tlayouter1: tlayouter; + printcomm: tstringedit; + debugger: tfilenameedit; + compiler: tfilenameedit; + compstoredir: tfilenameedit; + templatedir: tfilenameedit; + syntaxdefdir: tfilenameedit; + mselibdir: tfilenameedit; + msedir: tfilenameedit; + fpclibdir: tfilenameedit; + fpcdir: tfilenameedit; + tspacer1: tlayouter; + targetosdir: tstringedit; + target: tstringedit; + exeext: tstringedit; + tsplitter1: tsplitter; + tbutton2: tbutton; + tbutton1: tbutton; + shortcutbu: tbutton; + macrogrid: twidgetgrid; + macroname: tstringedit; + macrovalue: tmemodialogedit; + tspacer2: tspacer; + procedure epandfilenamemacro(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure formoncreate(const sender: TObject); + procedure setvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure setprintcomm(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure editshortcuts(const sender: TObject); + private + fshortcutcontroller: tshortcutcontroller; + protected + function widgetstomacros: settingsmacrosty; + end; + +var + settings: settingsty; + +procedure updatesettings(const filer: tstatfiler); +function getsettingsmacros: macroinfoarty; +function getsyssettingsmacros: macroinfoarty; +function getprintcommand: msestring; +function editsettings(const acaption: msestring = ''; + const shortcuts: tshortcutcontroller = nil): boolean; + +implementation +uses + msesettings_mfm,classes,mclasses,msesysintf,msefileutils,mseshortcutdialog; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function getsettingsmacros1(var amacros: settingsmacrosty): macroinfoarty; +var + ma1: settingsmacroty; + int1: integer; +begin + with amacros do begin + setlength(globmacrovalues,length(globmacronames)); + setlength(result,ord(high(settingsmacroty))+1+length(globmacronames)); + for ma1:= low(settingsmacroty) to high(settingsmacroty) do begin + result[ord(ma1)].name:= settingsmacronames[ma1]; + result[ord(ma1)].value:= macros[ma1]; + end; + for int1:= 0 to high(globmacronames) do begin + result[ord(high(settingsmacroty))+1+int1].name:= globmacronames[int1]; + result[ord(high(settingsmacroty))+1+int1].value:= globmacrovalues[int1]; + end; + end; +end; + +function getsettingsmacros: macroinfoarty; +begin + result:= getsettingsmacros1(settings.macros); +end; + +function getsyssettingsmacros: macroinfoarty; +var + int1: integer; +begin + result:= getsettingsmacros1(settings.macros); + for int1:= 0 to ord(sma_debugger) do begin + result[int1].value:= tosysfilepath(result[int1].value); + end; +end; + +function getprintcommand: msestring; +begin + result:= settings.printcommand; +end; + +procedure updatesettings(const filer: tstatfiler); +var + ma1: settingsmacroty; +begin + with settings,macros do begin + if filer.iswriter then begin + for ma1:= low(settingsmacroty) to high(settingsmacroty) do begin + filer.updatevalue(settingsmacronames[ma1],macros[ma1]); + end; + end + else begin + with tstatreader(filer) do begin + for ma1:= low(settingsmacroty) to high(settingsmacroty) do begin + macros[ma1]:= readmsestring(settingsmacronames[ma1],defaultsettingmacros[ma1]); + end; + end; + printcommand:= sys_getprintcommand; + end; + filer.updatevalue('printcommand',printcommand); + filer.updatevalue('globmacronames',globmacronames); + filer.updatevalue('globmacrovalues',globmacrovalues); + end; +end; + +function editsettings(const acaption: msestring = ''; + const shortcuts: tshortcutcontroller = nil): boolean; +var + settingsfo: tsettingsfo; +begin + result:= false; + settingsfo:= tsettingsfo.create(nil); + with settingsfo do begin + try + fshortcutcontroller:= shortcuts; + if shortcuts = nil then begin + shortcutbu.visible:= false; + end; + if acaption <> '' then begin + settingsfo.caption:= acaption; + end; + if show(true) = mr_ok then begin + result:= true; + with settings do begin + macros:= widgetstomacros; +// expandprojectmacros; + printcommand:= printcomm.value; + end; + end; + finally + free; + end; + end; +end; + +{ tsettingsfo } + +procedure tsettingsfo.formoncreate(const sender: TObject); +begin + with settings,macros do begin + fpcdir.value:= macros[sma_fpcdir]; + fpclibdir.value:= macros[sma_fpclibdir]; + msedir.value:= macros[sma_msedir]; + mselibdir.value:= macros[sma_mselibdir]; + syntaxdefdir.value:= macros[sma_syntaxdefdir]; + templatedir.value:= macros[sma_templatedir]; + compstoredir.value:= macros[sma_compstoredir]; + compiler.value:= macros[sma_compiler]; + debugger.value:= macros[sma_debugger]; + exeext.value:= macros[sma_exeext]; + target.value:= macros[sma_target]; + targetosdir.value:= macros[sma_targetosdir]; + printcomm.value:= printcommand; + macroname.gridvalues:= globmacronames; + macrovalue.gridvalues:= globmacrovalues; + end; +end; + +function tsettingsfo.widgetstomacros: settingsmacrosty; +begin + with result do begin + macros[sma_fpcdir]:= fpcdir.value; + macros[sma_fpclibdir]:= fpclibdir.value; + macros[sma_msedir]:= msedir.value; + macros[sma_mselibdir]:= mselibdir.value; + macros[sma_syntaxdefdir]:= syntaxdefdir.value; + macros[sma_templatedir]:= templatedir.value; + macros[sma_compstoredir]:= compstoredir.value; + macros[sma_compiler]:= compiler.value; + macros[sma_debugger]:= debugger.value; + macros[sma_exeext]:= exeext.value; + macros[sma_target]:= target.value; + macros[sma_targetosdir]:= targetosdir.value; + globmacronames:= macroname.gridvalues; + globmacrovalues:= macrovalue.gridvalues; + end; +end; + +procedure tsettingsfo.epandfilenamemacro(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var + mac1: settingsmacrosty; +begin + mac1:= widgetstomacros; + avalue:= expandmacros(avalue,getsettingsmacros1(mac1)); +end; + +procedure tsettingsfo.setvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); +begin + if avalue = '' then begin + avalue:= defaultsettingmacros[settingsmacroty(tcomponent(sender).tag)]; + end; +end; + +procedure tsettingsfo.setprintcomm(const sender: TObject; var avalue: msestring; + var accept: Boolean); +begin + if avalue = '' then begin + avalue:= sys_getprintcommand; + end; +end; + +procedure tsettingsfo.editshortcuts(const sender: TObject); +begin + shortcutdialog(fshortcutcontroller); +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msesettings_mfm.pas b/mseide-msegui/lib/common/designutils/msesettings_mfm.pas new file mode 100644 index 0000000..904b01a --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesettings_mfm.pas @@ -0,0 +1,528 @@ +unit msesettings_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msesettings; + +const + objdata: record size: integer; data: array[0..10216] of byte end = + (size: 10217; data: ( + 84,80,70,48,11,116,115,101,116,116,105,110,103,115,102,111,10,115,101,116, + 116,105,110,103,115,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101, + 101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,2,100,8,98,111,117,110,100,115,95,121, + 2,106,9,98,111,117,110,100,115,95,99,120,3,92,1,9,98,111,117,110, + 100,115,95,99,121,3,58,2,26,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111, + 117,110,100,115,1,2,0,2,0,3,92,1,3,58,2,0,7,111,112,116, + 105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15, + 102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97, + 117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101, + 112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99, + 97,112,116,105,111,110,6,25,67,111,110,102,105,103,117,114,101,32,77,83, + 69,32,101,110,118,105,114,111,110,109,101,110,116,13,119,105,110,100,111,119, + 111,112,97,99,105,116,121,5,0,0,0,0,0,0,0,128,255,255,8,111, + 110,99,114,101,97,116,101,7,12,102,111,114,109,111,110,99,114,101,97,116, + 101,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116, + 109,115,101,102,111,114,109,0,9,116,115,112,108,105,116,116,101,114,10,116, + 115,112,108,105,116,116,101,114,49,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95, + 112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3, + 0,0,128,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,8,2,9,98,111, + 117,110,100,115,95,99,120,3,92,1,9,98,111,117,110,100,115,95,99,121, + 2,38,7,97,110,99,104,111,114,115,11,9,97,110,95,98,111,116,116,111, + 109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99, + 95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121, + 0,7,108,105,110,107,116,111,112,7,9,109,97,99,114,111,103,114,105,100, + 4,103,114,105,112,7,8,115,116,98,95,110,111,110,101,0,7,116,98,117, + 116,116,111,110,8,116,98,117,116,116,111,110,50,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116, + 97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,27, + 1,8,98,111,117,110,100,115,95,121,2,16,9,98,111,117,110,100,115,95, + 99,120,2,52,9,98,111,117,110,100,115,95,99,121,2,22,12,98,111,117, + 110,100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109, + 111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101, + 108,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7, + 116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,49,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116, + 111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104, + 0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,3,225,0,8,98,111,117,110,100,115,95,121,2,16,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,12, + 98,111,117,110,100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97, + 115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114, + 95,111,107,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,7,116,98,117,116,116,111,110,10,115,104,111,114,116,99,117,116,98,117, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49, + 95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119, + 105,100,116,104,0,8,98,111,117,110,100,115,95,120,2,9,8,98,111,117, + 110,100,115,95,121,2,16,9,98,111,117,110,100,115,95,99,120,2,78,9, + 98,111,117,110,100,115,95,99,121,2,22,12,98,111,117,110,100,115,95,99, + 120,109,105,110,2,78,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,10,38,83, + 104,111,114,116,99,117,116,115,9,111,110,101,120,101,99,117,116,101,7,13, + 101,100,105,116,115,104,111,114,116,99,117,116,115,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,7,116,115,112,97,99,101,114,8, + 116,115,112,97,99,101,114,50,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,3,19,1,8,98,111,117,110,100,115,95,121, + 2,16,9,98,111,117,110,100,115,95,99,120,2,8,9,98,111,117,110,100, + 115,95,99,121,2,20,8,108,105,110,107,108,101,102,116,7,8,116,98,117, + 116,116,111,110,49,9,108,105,110,107,114,105,103,104,116,7,8,116,98,117, + 116,116,111,110,50,7,111,112,116,105,111,110,115,11,14,115,112,97,111,95, + 103,108,117,101,114,105,103,104,116,0,0,0,0,9,116,108,97,121,111,117, + 116,101,114,10,116,108,97,121,111,117,116,101,114,49,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,92,1,9,98,111,117,110,100,115,95,99,121,3, + 151,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,121,11,111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101, + 120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112, + 97,110,100,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108, + 97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,121,0,10,108, + 105,110,107,98,111,116,116,111,109,7,9,109,97,99,114,111,103,114,105,100, + 0,9,116,108,97,121,111,117,116,101,114,8,116,115,112,97,99,101,114,49, + 8,116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,3,77,1,9,98,111,117,110,100, + 115,95,99,120,3,74,1,9,98,111,117,110,100,115,95,99,121,2,37,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95, + 116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105,111,110, + 115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111, + 117,116,11,10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97, + 108,105,103,110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119, + 97,109,95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105, + 115,116,2,4,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,4, + 13,112,108,97,99,101,95,111,112,116,105,111,110,115,11,13,112,108,111,95, + 115,99,97,108,101,115,105,122,101,13,112,108,111,95,101,110,100,109,97,114, + 103,105,110,0,0,11,116,115,116,114,105,110,103,101,100,105,116,11,116,97, + 114,103,101,116,111,115,100,105,114,3,84,97,103,2,11,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,14,36,123,84,65,82,71,69,84,79, + 83,68,73,82,125,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,2,8,98,111,117,110,100,115,95,120,3,178,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,152,0,9,98, + 111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,8,115,101,116, + 118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,6,116,97,114,103, + 101,116,3,84,97,103,2,10,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,9,36,123,84,65,82,71,69,84,125,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 82,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,92,9,98,111,117,110,100,115,95,99,121,2,37,10,111,110,115, + 101,116,118,97,108,117,101,7,8,115,101,116,118,97,108,117,101,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,6,101,120,101,101,120,116,3,84,97,103,2,9, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,9,36,123,69,88, + 69,69,88,84,125,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,78,9,98,111,117,110,100,115,95,99,121,2,37,10,111,110, + 115,101,116,118,97,108,117,101,7,8,115,101,116,118,97,108,117,101,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,11,116,115, + 116,114,105,110,103,101,100,105,116,9,112,114,105,110,116,99,111,109,109,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,13,80,114,105,110,116, + 32,99,111,109,109,97,110,100,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,10,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117, + 110,100,115,95,121,3,114,1,9,98,111,117,110,100,115,95,99,120,3,74, + 1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114, + 115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,12, + 115,101,116,112,114,105,110,116,99,111,109,109,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101,110,97,109,101, + 101,100,105,116,8,100,101,98,117,103,103,101,114,3,84,97,103,2,8,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,11,36,123,68,69,66, + 85,71,71,69,82,125,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114,2,17,0, + 0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101, + 110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,8,4,104,105,110,116,6,23,80,97,116,104,32,116,111,32,100,101,98, + 117,103,103,101,114,32,40,103,100,98,41,46,8,98,111,117,110,100,115,95, + 120,2,8,8,98,111,117,110,100,115,95,121,3,40,1,9,98,111,117,110, + 100,115,95,99,120,3,74,1,9,98,111,117,110,100,115,95,99,121,2,37, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,10,111,110,115,101,116, + 118,97,108,117,101,7,8,115,101,116,118,97,108,117,101,22,99,111,110,116, + 114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,13, + 68,101,98,117,103,103,101,114,32,112,97,116,104,24,99,111,110,116,114,111, + 108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7,18, + 101,112,97,110,100,102,105,108,101,110,97,109,101,109,97,99,114,111,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105, + 108,101,110,97,109,101,101,100,105,116,8,99,111,109,112,105,108,101,114,3, + 84,97,103,2,7,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 11,36,123,67,79,77,80,73,76,69,82,125,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103, + 101,110,114,2,17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110, + 46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,7,4,104,105,110,116,6,26,80,97,116,104,32, + 116,111,32,99,111,109,112,105,108,101,114,32,40,112,112,99,51,56,54,41, + 46,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95, + 121,3,3,1,9,98,111,117,110,100,115,95,99,120,3,74,1,9,98,111, + 117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,8,115,101,116,118, + 97,108,117,101,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116, + 105,111,110,111,112,101,110,6,13,67,111,109,112,105,108,101,114,32,112,97, + 116,104,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102, + 105,108,101,110,97,109,101,7,18,101,112,97,110,100,102,105,108,101,110,97, + 109,101,109,97,99,114,111,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,12, + 99,111,109,112,115,116,111,114,101,100,105,114,3,84,97,103,2,6,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,15,36,123,67,79,77,80, + 83,84,79,82,69,68,73,82,125,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114, + 2,17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109, + 97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,6,4,104,105,110,116,6,36,68,105,114,101,99,116,111,114, + 121,32,102,111,114,32,99,111,109,112,111,110,101,110,116,32,115,116,111,114, + 101,32,102,105,108,101,115,46,8,98,111,117,110,100,115,95,120,2,8,8, + 98,111,117,110,100,115,95,121,3,222,0,9,98,111,117,110,100,115,95,99, + 120,3,74,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99, + 104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112, + 8,97,110,95,114,105,103,104,116,0,10,111,110,115,101,116,118,97,108,117, + 101,7,8,115,101,116,118,97,108,117,101,26,99,111,110,116,114,111,108,108, + 101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1, + 6,13,80,114,111,106,101,99,116,32,102,105,108,101,115,6,5,42,46,112, + 114,106,0,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105, + 111,110,115,11,13,102,100,111,95,100,105,114,101,99,116,111,114,121,0,22, + 99,111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112, + 101,110,6,30,68,105,114,101,99,116,111,114,121,32,102,111,114,32,99,111, + 109,112,111,110,101,110,116,32,115,116,111,114,101,115,24,99,111,110,116,114, + 111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7, + 18,101,112,97,110,100,102,105,108,101,110,97,109,101,109,97,99,114,111,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102, + 105,108,101,110,97,109,101,101,100,105,116,11,116,101,109,112,108,97,116,101, + 100,105,114,3,84,97,103,2,5,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,14,36,123,84,69,77,80,76,65,84,69,68,73,82,125,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114,97,109,101, + 46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,8,116,97,98,111,114,100,101,114,2,5,4,104,105,110,116, + 6,37,68,105,114,101,99,116,111,114,121,32,102,111,114,32,112,114,111,106, + 101,99,116,32,116,101,109,112,108,97,116,101,32,102,105,108,101,115,46,8, + 98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,3, + 185,0,9,98,111,117,110,100,115,95,99,120,3,74,1,9,98,111,117,110, + 100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116, + 0,10,111,110,115,101,116,118,97,108,117,101,7,8,115,101,116,118,97,108, + 117,101,26,99,111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114, + 108,105,115,116,46,100,97,116,97,1,1,6,13,80,114,111,106,101,99,116, + 32,102,105,108,101,115,6,5,42,46,112,114,106,0,0,18,99,111,110,116, + 114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111,95, + 100,105,114,101,99,116,111,114,121,0,22,99,111,110,116,114,111,108,108,101, + 114,46,99,97,112,116,105,111,110,111,112,101,110,6,26,80,114,111,106,101, + 99,116,32,116,101,109,112,108,97,116,101,32,100,105,114,101,99,116,111,114, + 121,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105, + 108,101,110,97,109,101,7,18,101,112,97,110,100,102,105,108,101,110,97,109, + 101,109,97,99,114,111,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,12,115, + 121,110,116,97,120,100,101,102,100,105,114,3,84,97,103,2,4,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,15,36,123,83,89,78,84,65, + 88,68,69,70,68,73,82,125,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114,2, + 17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97, + 103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,4,4,104,105,110,116,6,38,68,105,114,101,99,116,111,114,121, + 32,102,111,114,32,115,121,110,116,97,120,32,100,101,102,105,110,105,116,105, + 111,110,32,102,105,108,101,115,46,8,98,111,117,110,100,115,95,120,2,8, + 8,98,111,117,110,100,115,95,121,3,148,0,9,98,111,117,110,100,115,95, + 99,120,3,74,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,0,10,111,110,115,101,116,118,97,108, + 117,101,7,8,115,101,116,118,97,108,117,101,26,99,111,110,116,114,111,108, + 108,101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1, + 1,6,18,83,121,110,116,97,120,32,100,101,102,105,110,105,116,105,111,110, + 115,6,6,42,46,115,100,101,102,0,0,18,99,111,110,116,114,111,108,108, + 101,114,46,111,112,116,105,111,110,115,11,13,102,100,111,95,100,105,114,101, + 99,116,111,114,121,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97, + 112,116,105,111,110,111,112,101,110,6,37,68,105,114,101,99,116,111,114,121, + 32,102,111,114,32,115,121,110,116,97,120,32,100,101,102,105,110,105,116,105, + 111,110,32,102,105,108,101,115,24,99,111,110,116,114,111,108,108,101,114,46, + 111,110,103,101,116,102,105,108,101,110,97,109,101,7,18,101,112,97,110,100, + 102,105,108,101,110,97,109,101,109,97,99,114,111,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101,110,97,109, + 101,101,100,105,116,9,109,115,101,108,105,98,100,105,114,3,84,97,103,2, + 3,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,36,123,77, + 83,69,76,73,66,68,73,82,125,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114, + 2,17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109, + 97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,3,4,104,105,110,116,6,33,82,111,111,116,32,100,105,114, + 101,99,116,111,114,121,32,111,102,32,77,83,69,103,117,105,32,108,105,98, + 114,97,114,121,46,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117, + 110,100,115,95,121,2,111,9,98,111,117,110,100,115,95,99,120,3,74,1, + 9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95, + 114,105,103,104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,8,115, + 101,116,118,97,108,117,101,18,99,111,110,116,114,111,108,108,101,114,46,111, + 112,116,105,111,110,115,11,13,102,100,111,95,100,105,114,101,99,116,111,114, + 121,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111, + 110,111,112,101,110,6,24,77,83,69,103,117,105,32,108,105,98,114,97,114, + 121,32,100,105,114,101,99,116,111,114,121,24,99,111,110,116,114,111,108,108, + 101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7,18,101,112, + 97,110,100,102,105,108,101,110,97,109,101,109,97,99,114,111,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101, + 110,97,109,101,101,100,105,116,6,109,115,101,100,105,114,3,84,97,103,2, + 2,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,9,36,123,77, + 83,69,68,73,82,125,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114,2,17,0, + 0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101, + 110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,2,4,104,105,110,116,6,25,82,111,111,116,32,100,105,114,101,99,116, + 111,114,121,32,111,102,32,77,83,69,103,117,105,46,8,98,111,117,110,100, + 115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,74,9,98,111,117, + 110,100,115,95,99,120,3,74,1,9,98,111,117,110,100,115,95,99,121,2, + 37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,10,111,110,115,101, + 116,118,97,108,117,101,7,8,115,101,116,118,97,108,117,101,18,99,111,110, + 116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111, + 95,100,105,114,101,99,116,111,114,121,0,22,99,111,110,116,114,111,108,108, + 101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,21,77,83,69,103, + 117,105,32,114,111,111,116,32,100,105,114,101,99,116,111,114,121,24,99,111, + 110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97, + 109,101,7,18,101,112,97,110,100,102,105,108,101,110,97,109,101,109,97,99, + 114,111,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 13,116,102,105,108,101,110,97,109,101,101,100,105,116,9,102,112,99,108,105, + 98,100,105,114,3,84,97,103,2,1,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,12,36,123,70,80,67,76,73,66,68,73,82,125,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114,97,109,101,46, + 98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,1,4,104,105,110,116,6, + 74,82,111,111,116,32,100,105,114,101,99,116,111,114,121,32,111,102,32,70, + 80,67,32,108,105,98,114,97,114,121,32,40,110,111,116,32,117,115,101,100, + 32,98,121,32,116,104,101,32,100,101,102,97,117,108,116,32,112,114,111,106, + 101,99,116,32,116,101,109,112,108,97,116,101,115,41,46,8,98,111,117,110, + 100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,37,9,98,111, + 117,110,100,115,95,99,120,3,74,1,9,98,111,117,110,100,115,95,99,121, + 2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,18,99,111,110, + 116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111, + 95,100,105,114,101,99,116,111,114,121,0,22,99,111,110,116,114,111,108,108, + 101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,21,70,80,67,32, + 108,105,98,114,97,114,121,32,100,105,114,101,99,116,111,114,121,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108, + 101,110,97,109,101,101,100,105,116,6,102,112,99,100,105,114,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,9,36,123,70,80,67,68,73,82, + 125,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116, + 2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101, + 109,115,14,1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 17,2,0,2,0,0,4,104,105,110,116,6,81,82,111,111,116,32,100,105, + 114,101,99,116,111,114,121,32,111,102,32,70,114,101,101,32,80,97,115,99, + 97,108,32,115,121,115,116,101,109,32,40,110,111,116,32,117,115,101,100,32, + 98,121,32,116,104,101,32,100,101,102,97,117,108,116,32,112,114,111,106,101, + 99,116,32,116,101,109,112,108,97,116,101,115,41,46,8,98,111,117,110,100, + 115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,74,1,9,98,111,117,110,100,115,95,99,121,2, + 37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,10,111,110,115,101, + 116,118,97,108,117,101,7,8,115,101,116,118,97,108,117,101,18,99,111,110, + 116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111, + 95,100,105,114,101,99,116,111,114,121,0,22,99,111,110,116,114,111,108,108, + 101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,18,70,80,67,32, + 114,111,111,116,32,100,105,114,101,99,116,111,114,121,24,99,111,110,116,114, + 111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7, + 18,101,112,97,110,100,102,105,108,101,110,97,109,101,109,97,99,114,111,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,11,116, + 119,105,100,103,101,116,103,114,105,100,9,109,97,99,114,111,103,114,105,100, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,13,71,108,111,98, + 97,108,32,77,97,99,114,111,115,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,8,8,98,111, + 117,110,100,115,95,121,3,151,1,9,98,111,117,110,100,115,95,99,120,3, + 74,1,9,98,111,117,110,100,115,95,99,121,2,113,12,98,111,117,110,100, + 115,95,99,121,109,105,110,2,80,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110, + 115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12, + 111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114, + 111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114, + 116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15, + 111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97, + 117,116,111,97,112,112,101,110,100,16,111,103,95,110,111,105,110,115,101,114, + 116,101,109,112,116,121,20,111,103,95,99,111,108,99,104,97,110,103,101,111, + 110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111, + 103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109,111,117,115,101, + 115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111,108,115,46,99, + 111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115, + 14,1,5,119,105,100,116,104,2,28,8,110,117,109,115,116,97,114,116,2, + 1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119, + 115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116, + 101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105, + 111,110,115,46,99,111,117,110,116,2,4,14,99,97,112,116,105,111,110,115, + 46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,4,78,97, + 109,101,0,1,7,99,97,112,116,105,111,110,6,5,86,97,108,117,101,0, + 1,0,1,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117, + 110,116,2,2,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110, + 115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118, + 101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116, + 101,109,115,14,7,9,109,97,99,114,111,110,97,109,101,1,5,119,105,100, + 116,104,3,151,0,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,9,109,97,99,114,111,110,97,109,101,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,109,97,99,114,111, + 118,97,108,117,101,1,5,119,105,100,116,104,3,144,0,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,10,109,97,99,114,111,118,97,108,117, + 101,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97, + 116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105, + 108,101,7,10,116,115,116,97,116,102,105,108,101,49,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,11,116,115,116,114,105,110,103,101, + 100,105,116,9,109,97,99,114,111,110,97,109,101,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 151,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110, + 114,101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108,105,112, + 112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100, + 105,116,10,109,97,99,114,111,118,97,108,117,101,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0, + 0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101, + 108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101, + 110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116, + 116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100, + 101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,3,152,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,144,0,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105, + 102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117, + 115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,116,97,116, + 102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101, + 110,97,109,101,6,14,115,101,116,116,105,110,103,115,102,111,46,115,116,97, + 7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121, + 0,4,108,101,102,116,2,16,3,116,111,112,2,32,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsettingsfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseskindesign.pas b/mseide-msegui/lib/common/designutils/mseskindesign.pas new file mode 100644 index 0000000..5dcb364 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseskindesign.pas @@ -0,0 +1,87 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit mseskindesign; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseskin,mseclasses,classes; + +type + tskinhandlerdesign = class(tskinhandler) + protected + factiveskincontrollerdesign: skincontrollerarty; + procedure updateactive(const sender: tcustomskincontroller); override; +// procedure updateskindesign(const ainfo: skininfoty); +// procedure removeskindesign(const ainfo: skininfoty); +// procedure doactivate(const sender: tcustomskincontroller); override; +// procedure dodeactivate(const sender: tcustomskincontroller); override; + end; + +implementation +uses + msedesigner; + +{ tskinhandlerdesign } +{ +procedure tskinhandlerdesign.updateskindesign(const ainfo: skininfoty); +begin + updateskin1(ainfo,factiveskincontrollerdesign); +end; + +procedure tskinhandlerdesign.removeskindesign(const ainfo: skininfoty); +begin + removeskin1(ainfo,factiveskincontrollerdesign); +end; +} +procedure tskinhandlerdesign.updateactive(const sender: tcustomskincontroller); +begin + if csdesigning in sender.componentstate then begin + //do nothing +// setactive(sender,factiveskincontrollerdesign, +// @updateskindesign,oninitskinobjectdesign{, +// @removeskindesign,onremoveskinobjectdesign}); + end + else begin + inherited; + end; +end; +{ +procedure tskinhandlerdesign.doactivate(const sender: tcustomskincontroller); +var + int1: integer; +begin + if csdesigning in sender.componentstate then begin + for int1:= 0 to designer.modules.count - 1 do begin + designer.modules.itempo[int1]^.instance.updateskin(true); + end; + end; +end; + +procedure tskinhandlerdesign.dodeactivate(const sender: tcustomskincontroller); +var + int1: integer; +begin + if csdesigning in sender.componentstate then begin + for int1:= 0 to designer.modules.count - 1 do begin + designer.modules.itempo[int1]^.instance.removeskin(true); + end; + end; +end; +} +initialization + setskinhandler(tskinhandlerdesign.create); +end. diff --git a/mseide-msegui/lib/common/designutils/msestringintlisteditor.mfm b/mseide-msegui/lib/common/designutils/msestringintlisteditor.mfm new file mode 100644 index 0000000..9e6d032 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringintlisteditor.mfm @@ -0,0 +1,133 @@ +object msestringintlisteditor: tmsestringintlisteditor + bounds_x = 130 + bounds_y = 203 + bounds_cx = 338 + bounds_cy = 194 + container.bounds = ( + 0 + 0 + 338 + 194 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat] + statfile = tstatfile1 + caption = 'Stringlisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + taborder = 3 + bounds_x = 212 + bounds_y = 160 + bounds_cx = 50 + bounds_cy = 20 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + bounds_x = 276 + bounds_y = 160 + bounds_cx = 50 + bounds_cy = 20 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object grid: twidgetgrid + taborder = 2 + bounds_x = 8 + bounds_y = 8 + bounds_cx = 320 + bounds_cy = 140 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol] + fixcols.count = 1 + fixcols.items = < + item + width = 31 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 3 + captions.items = < + item + caption = 'a' + textflags = [] + end + item + caption = 'b' + end + item + caption = 'b' + textflags = [] + end> + end> + datacols.count = 2 + datacols.items = < + item[texta] + width = 232 + options = [co_fill, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'texta' + dataclass = tgridmsestringdatalist + end + item[textb] + widgetname = 'textb' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object texta: tstringedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.dummy = 0 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 232 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + object textb: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 233 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + end + object rowcount: tintegeredit + frame.caption = 'Rowcount' + frame.captionpos = cp_right + frame.dummy = 0 + frame.outerframe = ( + 0 + 0 + 64 + 0 + ) + taborder = 1 + bounds_x = 36 + bounds_y = 160 + bounds_cx = 114 + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'doublestringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/msestringintlisteditor.pas b/mseide-msegui/lib/common/designutils/msestringintlisteditor.pas new file mode 100644 index 0000000..ebd4c55 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringintlisteditor.pas @@ -0,0 +1,59 @@ +{ MSEgui Copyright (c) 2009-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestringintlisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,mseclasses, + msedialog,mseedit,mseglob,msegraphics,msegraphutils,msegui,mseguiglob,msemenus, + msestrings,msetypes,msestat,msestatfile; +type + tmsestringintlisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + texta: tstringedit; + rowcount: tintegeredit; + textb: tintegeredit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + msestringintlisteditor_mfm; + +{ tmsestringintlisteditor } + +constructor tmsestringintlisteditor.create(const aonclosequery: closequeryeventty); +begin + onclosequery:= aonclosequery; + inherited create(nil); +end; + +procedure tmsestringintlisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure tmsestringintlisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msestringintlisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msestringintlisteditor_mfm.pas new file mode 100644 index 0000000..19c91d6 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringintlisteditor_mfm.pas @@ -0,0 +1,121 @@ +unit msestringintlisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msestringintlisteditor; + +const + objdata: record size: integer; data: array[0..2076] of byte end = + (size: 2077; data: ( + 84,80,70,48,23,116,109,115,101,115,116,114,105,110,103,105,110,116,108,105, + 115,116,101,100,105,116,111,114,22,109,115,101,115,116,114,105,110,103,105,110, + 116,108,105,115,116,101,100,105,116,111,114,8,98,111,117,110,100,115,95,120, + 3,130,0,8,98,111,117,110,100,115,95,121,3,203,0,9,98,111,117,110, + 100,115,95,99,120,3,82,1,9,98,111,117,110,100,115,95,99,121,3,194, + 0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,82,1,3,194,0,0,7,111,112,116,105,111,110,115,11,13, + 102,111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116, + 111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105, + 116,101,115,116,97,116,0,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6,16,83,116, + 114,105,110,103,108,105,115,116,101,100,105,116,111,114,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109, + 0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,3,212,0,8,98,111,117,110, + 100,115,95,121,3,160,0,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,2,20,5,115,116,97,116,101,11,10,97, + 115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101, + 102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97, + 108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117, + 116,116,111,110,6,99,97,110,99,101,108,8,98,111,117,110,100,115,95,120, + 3,20,1,8,98,111,117,110,100,115,95,121,3,160,0,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108, + 11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110, + 99,101,108,0,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114, + 105,100,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,8,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110, + 100,115,95,99,120,3,64,1,9,98,111,117,110,100,115,95,99,121,3,140, + 0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111, + 103,95,99,111,108,115,105,122,105,110,103,12,111,103,95,114,111,119,109,111, + 118,105,110,103,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103, + 15,111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95, + 114,111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115, + 99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102, + 105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110, + 100,10,111,103,95,119,114,97,112,99,111,108,0,13,102,105,120,99,111,108, + 115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116, + 101,109,115,14,1,5,119,105,100,116,104,2,31,7,110,117,109,115,116,101, + 112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,3,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,1,97,9,116,101,120,116,102,108,97,103, + 115,11,0,0,1,7,99,97,112,116,105,111,110,6,1,98,0,1,7,99, + 97,112,116,105,111,110,6,1,98,9,116,101,120,116,102,108,97,103,115,11, + 0,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116, + 2,2,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,5, + 116,101,120,116,97,1,5,119,105,100,116,104,3,232,0,7,111,112,116,105, + 111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101, + 118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,5,116,101,120,116,97,9,100,97,116,97, + 99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,7,5,116,101,120,116,98,1,10,119, + 105,100,103,101,116,110,97,109,101,6,5,116,101,120,116,98,9,100,97,116, + 97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114, + 100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101, + 105,103,104,116,2,16,17,111,110,114,111,119,99,111,117,110,116,99,104,97, + 110,103,101,100,7,21,103,114,105,100,111,110,114,111,119,99,111,117,110,116, + 99,104,97,110,103,101,100,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,11,116,115,116,114,105,110,103,101,100,105,116,5,116,101,120, + 116,97,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 11,102,114,97,109,101,46,100,117,109,109,121,2,0,8,116,97,98,111,114, + 100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,232,0,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 115,97,118,101,118,97,108,117,101,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,5,116,101,120,116,98,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,233,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,8,114,111,119,99,111,117,110,116,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,8,82,111,119,99,111,117,110,116,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,11,102,114,97,109,101,46,100,117,109,109,121,2,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,64,2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,36,8,98,111,117,110,100,115,95,121,3,160, + 0,9,98,111,117,110,100,115,95,99,120,2,114,10,111,110,115,101,116,118, + 97,108,117,101,7,18,114,111,119,99,111,117,110,116,111,110,115,101,116,118, + 97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116,102,105, + 108,101,49,8,102,105,108,101,110,97,109,101,6,26,100,111,117,98,108,101, + 115,116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,46,115,116,97, + 7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121, + 0,4,108,101,102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsestringintlisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msestringlisteditor.mfm b/mseide-msegui/lib/common/designutils/msestringlisteditor.mfm new file mode 100644 index 0000000..102ef4b --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringlisteditor.mfm @@ -0,0 +1,112 @@ +object stringlisteditor: tstringlisteditor + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 177 + bounds_y = 203 + bounds_cx = 275 + bounds_cy = 237 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.bounds = ( + 0 + 0 + 275 + 237 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = tstatfile1 + caption = 'Stringlisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 3 + bounds_x = 160 + bounds_y = 210 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + bounds_x = 216 + bounds_y = 210 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object grid: twidgetgrid + optionswidget1 = [ow1_fontlineheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 275 + bounds_cy = 198 + anchors = [an_top, an_bottom] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstep = 1 + end> + zebra_start = 1 + zebra_height = 1 + datacols.count = 1 + datacols.items = < + item[valueedit] + width = 245 + options = [co_fill, co_savestate, co_mousescrollrow] + widgetname = 'valueedit' + dataclass = tgridrichstringdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object valueedit: ttextedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 245 + bounds_cy = 16 + optionsedit1 = [oe1_keyexecute, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_shiftreturn, oe_eatreturn, oe_exitoncursor] + reffontheight = 14 + end + end + object rowcount: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Rowcount' + frame.captionpos = cp_left + frame.dummy = 0 + frame.outerframe = ( + 64 + 0 + 0 + 0 + ) + taborder = 2 + bounds_x = 16 + bounds_y = 210 + bounds_cx = 116 + anchors = [an_left, an_bottom] + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'stringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/msestringlisteditor.pas b/mseide-msegui/lib/common/designutils/msestringlisteditor.pas new file mode 100644 index 0000000..8ee3809 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringlisteditor.pas @@ -0,0 +1,61 @@ +{ MSEgui Copyright (c) 1999-20012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestringlisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,msetextedit, + msestat,msestatfile; + +const + stringlisteditorstatname = 'stringlisteditor.sta'; + +type + tstringlisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + valueedit: ttextedit; + rowcount: tintegeredit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + msestringlisteditor_mfm,mseeditglob,msetypes; + +{ tstringlisteditor } + +constructor tstringlisteditor.create(const aonclosequery: closequeryeventty); +begin + inherited create(nil); + onclosequery:= aonclosequery; +end; + +procedure tstringlisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure tstringlisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msestringlisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msestringlisteditor_mfm.pas new file mode 100644 index 0000000..925c0ad --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringlisteditor_mfm.pas @@ -0,0 +1,144 @@ +unit msestringlisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msestringlisteditor; + +const + objdata: record size: integer; data: array[0..2532] of byte end = + (size: 2533; data: ( + 84,80,70,48,17,116,115,116,114,105,110,103,108,105,115,116,101,100,105,116, + 111,114,16,115,116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111, + 110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,177,0,8,98,111,117,110,100,115,95,121,3,203,0,9,98,111,117,110, + 100,115,95,99,120,3,19,1,9,98,111,117,110,100,115,95,99,121,3,237, + 0,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11, + 111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101, + 116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,16,99,111,110,116,97,105,110,101,114, + 46,98,111,117,110,100,115,1,2,0,2,0,3,19,1,3,237,0,0,7, + 111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101, + 115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102, + 111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115, + 97,118,101,112,111,115,0,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6,16,83,116, + 114,105,110,103,108,105,115,116,101,100,105,116,111,114,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109, + 0,7,116,98,117,116,116,111,110,2,111,107,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,3,160,0,8,98,111,117,110,100,115,95,121,3,210,0,9,98, + 111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121, + 2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,9, + 97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97,115, + 95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102, + 97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97,108, + 114,101,115,117,108,116,7,5,109,114,95,111,107,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,6, + 99,97,110,99,101,108,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,0,8,98,111, + 117,110,100,115,95,120,3,216,0,8,98,111,117,110,100,115,95,121,3,210, + 0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97, + 112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,119,105,100, + 103,101,116,103,114,105,100,4,103,114,105,100,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,18,111,119,49,95,102,111,110,116,108,105,110, + 101,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13,111, + 119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,19,1,9,98,111, + 117,110,100,115,95,99,121,3,198,0,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111,112, + 116,105,111,110,115,103,114,105,100,11,12,111,103,95,114,111,119,109,111,118, + 105,110,103,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15, + 111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114, + 111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99, + 101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105, + 114,115,116,114,111,119,10,111,103,95,119,114,97,112,99,111,108,12,111,103, + 95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46, + 99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109, + 115,14,1,5,119,105,100,116,104,2,24,7,110,117,109,115,116,101,112,2, + 1,0,0,11,122,101,98,114,97,95,115,116,97,114,116,2,1,12,122,101, + 98,114,97,95,104,101,105,103,104,116,2,1,14,100,97,116,97,99,111,108, + 115,46,99,111,117,110,116,2,1,14,100,97,116,97,99,111,108,115,46,105, + 116,101,109,115,14,7,9,118,97,108,117,101,101,100,105,116,1,5,119,105, + 100,116,104,3,245,0,7,111,112,116,105,111,110,115,11,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103, + 101,116,110,97,109,101,6,9,118,97,108,117,101,101,100,105,116,9,100,97, + 116,97,99,108,97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,17,111,110,114,111,119,99,111,117,110, + 116,99,104,97,110,103,101,100,7,21,103,114,105,100,111,110,114,111,119,99, + 111,117,110,116,99,104,97,110,103,101,100,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,9,116,116,101,120,116,101,100,105,116,9,118, + 97,108,117,101,101,100,105,116,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,245,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,14,111,101,49,95,107,101,121,101,120, + 101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,12,111,101,95,108,105,110,101,98,114,101,97,107,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,8,114,111,119,99,111, + 117,110,116,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,8,82,111,119,99,111,117,110,116,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,7,99,112,95,108,101,102,116, + 11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,64,2,0,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,2,16,8,98,111,117,110,100,115,95,121,3,210,0,9,98,111,117,110, + 100,115,95,99,120,2,116,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,10,111,110,115,101, + 116,118,97,108,117,101,7,18,114,111,119,99,111,117,110,116,111,110,115,101, + 116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116, + 102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,20,115,116,114,105, + 110,103,108,105,115,116,101,100,105,116,111,114,46,115,116,97,7,111,112,116, + 105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101, + 102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstringlisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msesyntaxedit.pas b/mseide-msegui/lib/common/designutils/msesyntaxedit.pas new file mode 100644 index 0000000..12810c3 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesyntaxedit.pas @@ -0,0 +1,1440 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesyntaxedit; + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msetextedit,msesyntaxpainter,mseclasses,msegraphutils, + mseglob,mseguiglob,msetypes,mseevent,mserichstring, + mseeditglob,msestrings,msewidgetgrid,msedatalist,msemenus,msegui,mseinplaceedit, + msegrids,mseedit,msegraphics; + +type + bracketkindty = (bki_none,bki_round,bki_square,bki_curly); + +const + openbrackets: array[bracketkindty] of msechar = (#0,'(','[','{'); + closebrackets: array[bracketkindty] of msechar = (#0,')',']','}'); + defaultpairmaxrowcount = 100; + +type + syntaxeditoptionty = (seo_autoindent,seo_markbrackets,seo_markpairwords, + seo_caseinsensitive,seo_defaultsyntax); + syntaxeditoptionsty = set of syntaxeditoptionty; + + tsyntaxedit = class(tundotextedit) + private + fsyntaxpainter: tsyntaxpainter; + fsyntaxpainterhandle: integer; +// fautoindent: boolean; + flinkpos: gridcoordty; + flinklength: integer; +// fdefaultsyntax: boolean; + fsyntaxchanging: integer; + fbracketsetting: integer; + fbracketchecking: integer; + fpairmarkbkgcolor: colorty; + fpairmaxrowcount: int32; + fpairwords: pairwordsty; +// fpairwordslower: msestringararty; + procedure setsyntaxpainter(const Value: tsyntaxpainter); + procedure unregistersyntaxpainter; + procedure syntaxchanged(const sender: tobject; const index: integer); +// procedure setdefaultsyntax(const avalue: boolean); + procedure checkdefaultsyntax; + procedure readautoindent(reader: treader); + procedure readdefaultsyntax(reader: treader); + function getautoindent: boolean; + procedure setautoindent(const avalue: boolean); + function getmarkbrackets: boolean; + procedure setmarkbrackets(const avalue: boolean); + procedure setoptions(const avalue: syntaxeditoptionsty); + function getmarkpairwords: boolean; + procedure setmarkpairwords(const avalue: boolean); + function getcaseinsensitive: boolean; + procedure setcaseinsensitive(const avalue: boolean); + procedure setpairwords(const avalue: pairwordsty); + protected + foptions: syntaxeditoptionsty; + fmark1,fmark2: markitemty; + procedure initsyntaxparams(); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure gridvaluechanged(const index: integer); override; + procedure insertlinebreak; override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure loaded; override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure defineproperties(filer: tfiler); override; + procedure clearpairmarks(); + procedure checkpairmarks(); + procedure editnotification(var info: editnotificationinfoty); override; + procedure doasyncevent(var atag: integer); override; + procedure doafterpaint(const canvas: tcanvas); override; + function needsfocuspaint: boolean; override; +// procedure updatepairwords(); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure setsyntaxdef(const sourcefilename: filenamety); overload; + //'' for none + procedure setsyntaxdef(const handle: integer); overload; + procedure refreshsyntax(const start,count: integer); + + function charatpos(const apos: gridcoordty): msechar; //0 if none + function charbeforepos(const apos: gridcoordty): msechar; //0 if none + function wordatpos(const apos: gridcoordty; out word: msestring; + const delimchars: msestring; //'' -> default + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): gridcoordty; overload; + function wordatpos(const apos: gridcoordty; out start: gridcoordty; + const delimchars: msestring; + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): msestring; overload; + function wordatpos(const apos: gridcoordty; + const delimchars: msestring; + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): msestring; overload; + procedure indent(const acount: integer; const atabs: boolean); + procedure unindent(const acount: integer); + procedure removelink; + procedure showlink(const apos: gridcoordty; + const delimchars: msestring {= defaultmsedelimchars}); + procedure selectword(const apos: gridcoordty; const delimchars: msestring); + function matchbracket(const apos: gridcoordty; const akind: bracketkindty; + const open: boolean; maxrows: int32 = -1): gridcoordty; + //-1 -> use maxpairrows + function matchpairword(var apos: gridcoordty; //adjusted to word a start + out lena,lenb: int32; maxrows: int32 = -1): gridcoordty; + //-1 -> use maxpairrows + property pairwords: pairwordsty read fpairwords write setpairwords; + //last item of a pairword item is endtoken + //upprcase values must be uppercase for caseinsensitive + property syntaxpainterhandle: integer read fsyntaxpainterhandle; + function syntaxchanging: boolean; + property autoindent: boolean read getautoindent write setautoindent; + property markbrackets: boolean read getmarkbrackets write setmarkbrackets; + property markpairwords: boolean read getmarkpairwords write setmarkpairwords; + property caseinsensitive: boolean read getcaseinsensitive + write setcaseinsensitive; + published + property syntaxpainter: tsyntaxpainter read fsyntaxpainter + write setsyntaxpainter; +// property defaultsyntax: boolean read fdefaultsyntax +// write setdefaultsyntax default false; + property options: syntaxeditoptionsty read foptions write setoptions + default []; + property pairmarkbkgcolor: colorty read fpairmarkbkgcolor + write fpairmarkbkgcolor default cl_none; + //cl_none -> force none, + //cl_default -> use syntaxpainter value if defined else cl_none + //otherwise use syntaxpainter value if defined + property pairmaxrowcount: int32 read fpairmaxrowcount + write fpairmaxrowcount default defaultpairmaxrowcount; + end; + +function checkbracketkind(const achar: msechar; + out open: boolean): bracketkindty; + +implementation +uses + msekeyboard,msepointer; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + checkbrackettag = 84621847; + +type + tundoinplaceedit1 = class(tundoinplaceedit); + ttextundolist1 = class(ttextundolist); + +function checkbracketkind(const achar: msechar; out open: boolean): bracketkindty; +var + br1: bracketkindty; +begin + for br1:= bki_round to high(bracketkindty) do begin + if openbrackets[br1] = achar then begin + result:= br1; + open:= true; + exit; + end; + end; + result:= bki_none; + open:= false; + for br1:= bki_round to high(bracketkindty) do begin + if closebrackets[br1] = achar then begin + result:= br1; + break; + end; + end; +end; + +{ tsyntaxedit } + +const + invalidmark: markitemty = (bold: false; + pos: (col: invalidaxis; row: invalidaxis); len: 0); + +constructor tsyntaxedit.create(aowner: tcomponent); +begin + fsyntaxpainterhandle:= -1; + flinkpos:= invalidcell; + fmark1:= invalidmark; + fmark2:= invalidmark; + fpairmarkbkgcolor:= cl_none; + fpairmaxrowcount:= defaultpairmaxrowcount; + inherited; +end; + +destructor tsyntaxedit.destroy; +begin + unregistersyntaxpainter; + inherited; +end; + +procedure tsyntaxedit.objectevent(const sender: tobject; + const event: objecteventty); +var + int1,int2: integer; + po1: prichstringty; +begin + inherited; + if sender = fsyntaxpainter then begin + if event in [oe_destroyed,oe_disconnect] then begin + fsyntaxpainterhandle:= -1; + if flines <> nil then begin + with flines do begin + int2:= size; + po1:= datapo; + for int1:= count-1 downto 0 do begin + po1^.format:= nil; + inc(pchar(po1),int2); + end; + end; + end; + feditor.format:= nil; + if fgridintf <> nil then begin + fgridintf.changed; + end; +// fsyntaxpainter:= nil; + end; + end; +end; + +procedure tsyntaxedit.unregistersyntaxpainter; +begin + if (fsyntaxpainter <> nil) and (fsyntaxpainterhandle >= 0) then begin + fsyntaxpainter.unregisterclient(fsyntaxpainterhandle); + end; + fsyntaxpainterhandle:= -1; +end; + +procedure tsyntaxedit.checkdefaultsyntax; +begin + if (seo_defaultsyntax in foptions) and not (csloading in componentstate) and + (fsyntaxpainter <> nil) and (flines <> nil) and + (fsyntaxpainterhandle < 0) then begin + setsyntaxdef(fsyntaxpainter.defaultsyntax); + end; +end; + +procedure tsyntaxedit.setsyntaxpainter(const Value: tsyntaxpainter); +begin + if value <> fsyntaxpainter then begin + if fsyntaxpainter <> nil then begin + unregistersyntaxpainter; + end; + setlinkedvar(value,tmsecomponent(fsyntaxpainter)); + checkdefaultsyntax; + end; +end; +{ +procedure tsyntaxedit.setdefaultsyntax(const avalue: boolean); +begin + fdefaultsyntax:= avalue; + checkdefaultsyntax; +end; +} +procedure tsyntaxedit.setsyntaxdef(const sourcefilename: filenamety); +begin + if fsyntaxpainter <> nil then begin + if sourcefilename = '' then begin + unregistersyntaxpainter; + end + else begin + setsyntaxdef(fsyntaxpainter.linkdeffile(sourcefilename)); + end; + end; +end; + +procedure tsyntaxedit.initsyntaxparams(); +begin + caseinsensitive:= fsyntaxpainter.caseinsensitive[fsyntaxpainterhandle]; + pairwords:= fsyntaxpainter.pairwords[fsyntaxpainterhandle]; +end; + +procedure tsyntaxedit.setsyntaxdef(const handle: integer); +begin + if fsyntaxpainter <> nil then begin + unregistersyntaxpainter; + if handle >= 0 then begin + fsyntaxpainterhandle:= fsyntaxpainter.registerclient(self,flines, + {$ifdef FPC}@{$endif}syntaxchanged,handle); + initsyntaxparams(); + refreshsyntax(0,bigint); + end; + end; +end; + +procedure tsyntaxedit.syntaxchanged(const sender: tobject; + const index: integer); +begin + if (index < 0) and (fsyntaxpainterhandle >= 0) and + (sender <> nil) and (sender = fsyntaxpainter) then begin + initsyntaxparams(); + end; + if fgridintf <> nil then begin + inc(fsyntaxchanging); + try + fgridintf.getcol.cellchanged(index); + if index = fgridintf.getrow then begin + feditor.richtext:= flines.richitems[index]; + end; + finally + dec(fsyntaxchanging); + end; + end; +end; + +procedure tsyntaxedit.refreshsyntax(const start, count: integer); +begin + if fsyntaxpainterhandle >= 0 then begin + fsyntaxpainter.paintsyntax(fsyntaxpainterhandle,start,bigint,true); +// fsyntaxpainter.paintsyntax(fsyntaxpainterhandle,start,bigint,false); + end; +end; + +procedure tsyntaxedit.gridvaluechanged(const index: integer); +begin + inherited; + if index >= 0 then begin + refreshsyntax(index,1); + end + else begin + refreshsyntax(0,bigint); + end; +end; + +function tsyntaxedit.charatpos(const apos: gridcoordty): msechar; +var + stringpo: pmsestring; +begin + result:= #0; + if (apos.col >= 0) and (apos.row >= 0) and (apos.row < flines.count) then begin + stringpo:= pmsestring(flines.getitempo(apos.row)); + if apos.col < length(stringpo^) then begin + result:= stringpo^[apos.col+1]; + end; + end; +end; + +function tsyntaxedit.charbeforepos(const apos: gridcoordty): msechar; +var + stringpo: pmsestring; +begin + if apos.col = 0 then begin + result:= charbeforepos(makegridcoord(bigint,apos.row-1)); + end + else begin + result:= #0; + if (apos.row >= 0) and (apos.row < flines.count) and (apos.col >= 0) then begin + stringpo:= pmsestring(flines.getitempo(apos.row)); + if stringpo^ <> '' then begin + if apos.col >= length(stringpo^) then begin + result:= stringpo^[length(stringpo^)]; + end + else begin + result:= stringpo^[apos.col]; + end; + end; + end; + end; +end; + +function tsyntaxedit.wordatpos(const apos: gridcoordty; out word: msestring; + const delimchars: msestring; + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): gridcoordty; + //returns startpos +var + po1,po2: pmsechar; + stringpo: pmsestring; + gc1: gridcoordty; +begin + po2:= nil; + word:= ''; + if (apos.row < 0) or (apos.row >= flines.count) then begin + result:= invalidcell; + end + else begin + result.row:= apos.row; + stringpo:= pmsestring(flines.getitempo(apos.row)); + if stringpo^ <> '' then begin + if delimchars <> '' then begin + wordatindex(stringpo^,apos.col,po1,po2,delimchars,nodelimstrings); + end + else begin + wordatindex(stringpo^,apos.col,po1,po2,defaultmsedelimchars,nodelimstrings); + end; + if po1 = po2 then begin + po1:= nil; + end; + end + else begin + po1:= nil; + end; + if po1 = nil then begin + result.col:= -1; + end + else begin + result.col:= po1 - pmsechar(stringpo^); + word:= copy(msestring(po1),1,po2-po1); + end; + end; + if (word = '') and leftofcursor and (apos.col > 0) then begin + gc1:= apos; + dec(gc1.col); + result:= wordatpos(gc1,word,delimchars,nodelimstrings); + end; +end; + +function tsyntaxedit.wordatpos(const apos: gridcoordty; out start: gridcoordty; + const delimchars: msestring; + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): msestring; +begin + start:= wordatpos(apos,result,delimchars,nodelimstrings,leftofcursor); +end; + +function tsyntaxedit.wordatpos(const apos: gridcoordty; + const delimchars: msestring; + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): msestring; +begin + wordatpos(apos,result,delimchars,nodelimstrings,leftofcursor); +end; + + +procedure tsyntaxedit.indent(const acount: integer; const atabs: boolean); +var + int1,int2: integer; + str1: msestring; + pos1,pos2: gridcoordty; + po1: prichstringaty; + selstart,selend: gridcoordty; + ch1: msechar; +begin + selstart:= selectstart; + selend:= selectend; + getselectedrows(int1,int2); + ch1:= ' '; + if atabs then begin + ch1:= c_tab; + end; + str1:= charstring(ch1,acount); + pos1:= makegridcoord(0,int1); + pos2:= makegridcoord(acount,int1); + po1:= datalist.datapo; + beginupdate; + feditor.begingroup; + try + clearselection; + while (pos1.row <= int2) do begin + richinsert(str1,po1^[pos1.row],1); + tundoinplaceedit1(feditor).fundolist.setpos(pos1,false); + tundoinplaceedit1(feditor).fundolist.inserttext(pos1,pos2,str1,false,false); + inc(pos1.row); + pos2.row:= pos1.row; + end; + if selstart.row = selend.row then begin + editor.richtext:= po1^[int2]; + selstart.col:= selstart.col + acount; + selend.col:= selend.col + acount; + end; + setselection(selstart,selend,true); + finally + feditor.endgroup; + endupdate; + end; +end; + +procedure tsyntaxedit.unindent(const acount: integer); +var + int1,int2,int3,int4: integer; + pos1,pos2: gridcoordty; + selstart,selend: gridcoordty; + str1: msestring; + po1: prichstringaty; + +begin + selstart:= selectstart; + selend:= selectend; + getselectedrows(int1,int2); + pos1:= makegridcoord(0,int1); + pos2.row:= int1; + po1:= datalist.datapo; + beginupdate; + int4:= 0; + feditor.begingroup; + try + clearselection; + for int1:= int1 to int2 do begin + with po1^[pos1.row] do begin + if length(text) < acount then begin + int4:= length(text); + end + else begin + int4:= acount; + end; + for int3:= 1 to int4 do begin + if (text[int3] <> ' ') and (text[int3] <> c_tab) then begin + int4:= int3 - 2; + break; + end; + end; + end; + if int4 >= 0 then begin + pos2.col:= int4; + str1:= copy(po1^[pos1.row].text,1,int4); + richdelete(po1^[pos1.row],1,int4); + tundoinplaceedit1(feditor).fundolist.setpos(pos2,false); + tundoinplaceedit1(feditor).fundolist.deletetext(pos2,pos1,str1,false,true); + end; + inc(pos1.row); + inc(pos2.row); + end; + if selstart.row = selend.row then begin + if int4 < 0 then begin + int4:= 0; + end; + selstart.col:= selstart.col - int4; + selend.col:= selend.col - int4; + end; + setselection(selstart,selend,true); + finally + feditor.endgroup; + endupdate; + end; +end; + +procedure tsyntaxedit.removelink; +begin + if (flinkpos.row >= 0) then begin + application.cursorshape:= cr_default; + if (flinkpos.row < datalist.count) then begin + if updatefontstyle1(datalist.getformatpo(flinkpos.row)^,flinkpos.col, + flinklength,fs_underline,false) then begin + with fgridintf.getcol do begin + cellchanged(flinkpos.row); + if grid.row = flinkpos.row then begin + self.gridtovalue(flinkpos.row); + end; + end; + end; + end; + flinkpos.row:= invalidaxis; + end; +end; + +procedure tsyntaxedit.showlink(const apos: gridcoordty; + const delimchars: msestring {= defaultmsedelimchars}); +var + str1: msestring; + pos1: gridcoordty; + length1: integer; +begin + pos1:= wordatpos(apos,str1,delimchars,[]); + length1:= length(str1); + if (pos1.col <> flinkpos.col) or (pos1.row <> flinkpos.row) or + (length1 <> flinklength) then begin + removelink; + flinkpos:= pos1; + flinklength:= length1; + if flinklength > 0 then begin + application.cursorshape:= cr_pointinghand; + if updatefontstyle1(datalist.getformatpo(flinkpos.row)^,flinkpos.col, + flinklength,fs_underline,true) then begin + with fgridintf.getcol do begin + cellchanged(flinkpos.row); + if grid.row = flinkpos.row then begin + self.gridtovalue(flinkpos.row); + end; + end; + end; + end; + end; +end; + +procedure tsyntaxedit.selectword(const apos: gridcoordty; + const delimchars: msestring); +var + str1: msestring; + pos1: gridcoordty; +begin + pos1:= wordatpos(apos,str1,delimchars,[]); + if str1 = '' then begin + pos1:= wordatpos(apos,str1,delimchars,[],true); + end; + if str1 <> '' then begin + setselection(pos1,makegridcoord(pos1.col+length(str1),pos1.row),true); + end; +end; + +function tsyntaxedit.matchbracket(const apos: gridcoordty; + const akind: bracketkindty; + const open: boolean; maxrows: integer = -1): gridcoordty; + +var + level: integer; + strpo: pmsestring; + x,y: integer; + po1: pmsecharaty; + int1: integer; + openchar,closechar,mch1: msechar; +begin + result:= invalidcell; + level:= 0; + x:= apos.col; + y:= apos.row; + openchar:= openbrackets[akind]; + closechar:= closebrackets[akind]; + if maxrows < 0 then begin + maxrows:= fpairmaxrowcount; + end; + if open then begin + while (maxrows > 0) and (y < flines.count) do begin + strpo:= pmsestring(flines.getitempo(y)); + po1:= pmsecharaty(strpo^); + for int1:= x to length(strpo^)-1 do begin + mch1:= po1^[int1]; + if mch1 = openchar then begin + inc(level); + end; + if mch1 = closechar then begin + dec(level); + if level <= 0 then begin + result.row:= y; + result.col:= int1; + exit; + end; + end; + end; + x:= 0; + dec(maxrows); + inc(y); + end; + end + else begin + strpo:= pmsestring(flines.getitempo(y)); + while (maxrows > 0) do begin + po1:= pmsecharaty(strpo^); + for int1:= x downto 0 do begin + mch1:= po1^[int1]; + if mch1 = closechar then begin + inc(level); + end; + if mch1 = openchar then begin + dec(level); + if level <= 0 then begin + result.row:= y; + result.col:= int1; + exit; + end; + end; + end; + dec(maxrows); + dec(y); + if y < 0 then begin + break; + end; + strpo:= pmsestring(flines.getitempo(y)); + x:= length(strpo^)-1; + end; + end; +end; + +function tsyntaxedit.matchpairword(var apos: gridcoordty; + out lena,lenb: int32; + maxrows: integer = -1): gridcoordty; +var + mstr1,{mstr1l,}mstr2{,mstr2l}: msestring; + forward1: boolean; + strpo,strpe: prichstringty; + pa,pae,{pab,}pal,{palb,}{pb,pbe,pbb,pbl,pblb,}po1,po2,pe: pmsechar; + level1: int32; + i1: int32; + par1,par1l,pare: pmsestringarty; +label + lab1; +begin + if maxrows < 0 then begin + maxrows:= fpairmaxrowcount; + end; + if fpairwords.upper <> nil then begin + mstr1:= ''; + if (apos.row >= 0) and (apos.row < flines.count) then begin + mstr2:= flines.items[apos.row]; + if (mstr2 <> '') and (apos.col >= 0) and + (apos.col <= length(mstr2)) then begin + pe:= pmsechar(pointer(mstr2))+apos.col; + po1:= pe-1; + while isnamechar(pe^) do begin + inc(pe); + end; + while (po1 >= pointer(mstr2)) and isnamechar(po1^) do begin + dec(po1); + end; + inc(po1); + mstr1:= stringsegment(po1,pe); + apos.col:= po1-pmsechar(pointer(mstr2)); + end; + end; + if mstr1 <> '' then begin + if caseinsensitive then begin + mstr1:= mseuppercase(mstr1); + end; + mstr2:= ''; + par1:= pointer(fpairwords.upper); + pare:= par1+high(fpairwords.upper); + while par1 <= pare do begin + for i1:= 0 to high(par1^) do begin + if par1^[i1] = mstr1 then begin + forward1:= i1 < high(par1^); + goto lab1; + end; + end; + inc(par1); + end; +lab1: + if par1 <= pare then begin //found + par1l:= pointer(par1)-pointer(fpairwords.upper)+ + pointer(fpairwords.lower); //lowercase + lena:= length(mstr1); + strpo:= flines.getitempo(apos.row); + if forward1 then begin + level1:= 1; + po1:= @pmsechar(pointer(strpo^.text))[apos.col+lena]; + i1:= flines.count-apos.row; + if i1 > maxrows then begin + i1:= maxrows; + end; + strpe:= strpo + i1; + while true do begin + repeat + while not isnamechar(po1^) and (po1^ <> #0) do begin + inc(po1); + end; + if po1^ <> #0 then begin + for i1:= 0 to high(par1^) do begin + pa:= pmsechar(par1^[i1]); + pal:= pmsechar(par1l^[i1]); + if (po1^ = pa^) or (po1^ = pal^) then begin + po2:= po1; + repeat + inc(pa); + inc(pal); + inc(po2); + if (pa^ = #0) and not isnamechar(po2^) then begin //match + if i1 = high(par1^) then begin //end + dec(level1); + if level1 = 0 then begin //found + lenb:= length(par1^[i1]); + result.col:= po1-pmsechar(pointer(strpo^.text)); + result.row:= strpo-prichstringty(flines.datapo); + exit; + end; + break; + end + else begin + inc(level1); + po1:= po2; + break; + end; + end; + until (po2^ <> pa^) and (po2^ <> pal^); + end; + end; + while isnamechar(po1^) do begin + inc(po1); + end; + end; + until po1^ = #0; + inc(strpo); + if strpo >= strpe then begin + break; + end; + po1:= pmsechar(strpo^.text); + end; + end + else begin //backward + + level1:= 1; + pe:= pointer(strpo^.text); + po1:= pe + apos.col - 1; + i1:= apos.row; + if i1 > maxrows then begin + i1:= maxrows; + end; + strpe:= strpo - i1; + while true do begin + if pe <> nil then begin + repeat + while not isnamechar(po1^) and (po1 >= pe) do begin + dec(po1); + end; + if po1 >= pe then begin + for i1:= 0 to high(par1^) do begin + pae:= pmsechar(par1^[i1]); + pa:= pmsechar(pae+length(par1^[i1])-1); + pal:= pmsechar(par1l^[i1])+length(par1l^[i1])-1; + if (po1^ = pa^) or (po1^ = pal^) then begin + po2:= po1; + repeat + dec(pa); + dec(pal); + dec(po2); + if (pa < pae) and + ((po2 < pe) or not isnamechar(po2^)) then begin //match + if i1 = high(par1^) then begin //end + inc(level1); + po1:= po2; + break; + end + else begin + dec(level1); + if level1 = 0 then begin //found + lenb:= length(par1^[i1]); + result.col:= po2-pmsechar(pointer(strpo^.text))+1; + result.row:= strpo-prichstringty(flines.datapo); + exit; + end; + break; + end; + end; + until (po2^ <> pa^) and (po2^ <> pal^) or (po2 < pe); + end; + end; + while isnamechar(po1^) and (po1 > pe) do begin + dec(po1); + end; + dec(po1); + end; + until po1 < pe; + end; + dec(strpo); + if strpo < strpe then begin + break; + end; + pe:= pointer(strpo^.text); + po1:= pe + length(strpo^.text) - 1; + end; + end; + end; + end; + end; + result:= invalidcell; + lena:= 0; + lenb:= 0; +end; + +const + noboldchars: markinfoty = (backgroundcolor: cl_none; items: nil); + +procedure tsyntaxedit.clearpairmarks(); +var + style1: fontstylety; +begin + if (fmark1.pos.col >= 0) and (fbracketsetting = 0) then begin + inc(fbracketsetting); + try + style1:= fs_force; //do not change + if fmark1.bold then begin + style1:= fs_bold; + end; + setfontstyle(fmark1.pos,mgc(fmark1.pos.col+fmark1.len,fmark1.pos.row), + style1,false,cl_default,cl_transparent); + setfontstyle(fmark2.pos,mgc(fmark2.pos.col+fmark2.len,fmark2.pos.row), + style1,false,cl_default,cl_transparent); + refreshsyntax(fmark1.pos.row,1); + refreshsyntax(fmark2.pos.row,1); + fmark1:= invalidmark; + fmark2:= invalidmark; + if syntaxpainterhandle >= 0 then begin + syntaxpainter.boldchars[syntaxpainterhandle]:= noboldchars; + end; + finally + dec(fbracketsetting); + end; + end; +end; + +procedure tsyntaxedit.checkpairmarks(); +var + mch1: msechar; + br1,br2: bracketkindty; + open,open2: boolean; + pt1,pt2: gridcoordty; + ar1: markitemarty; + boldinfo1: markinfoty; + iswordmark: boolean; +begin + clearpairmarks(); + pt2:= invalidcell; + if seo_markbrackets in foptions then begin + fmark1.bold:= true; + fmark2.bold:= true; + fmark1.len:= 1; + fmark2.len:= 1; + pt1:= editpos; + mch1:= charatpos(pt1); + br1:= checkbracketkind(mch1,open); + if (br1 <> bki_none) then begin + if (pt1.col > 0) then begin + dec(pt1.col); + br2:= checkbracketkind(charatpos(pt1),open2); + if (br2 = bki_none) {or (open <> open2)} then begin + inc(pt1.col); + end + else begin + br1:= br2; + open:= open2; + end; + end; + pt2:= matchbracket(pt1,br1,open); + end + else begin + dec(pt1.col); + if pt1.col >= 0 then begin + mch1:= charatpos(pt1); + br1:= checkbracketkind(mch1,open); + if br1 <> bki_none then begin + pt2:= matchbracket(pt1,br1,open); + end; + end; + end; + end; + iswordmark:= false; + if (seo_markpairwords in foptions) and (pt2.col < 0) then begin + iswordmark:= true; + pt1:= editpos; + pt2:= matchpairword(pt1,fmark1.len,fmark2.len); + end; + if pt2.col >= 0 then begin + fmark1.pos:= pt1; + fmark2.pos:= pt2; + boldinfo1.backgroundcolor:= fpairmarkbkgcolor; + if iswordmark then begin + fmark1.bold:= boldinfo1.backgroundcolor = cl_none; + fmark2.bold:= fmark1.bold; + end; + if syntaxpainterhandle >= 0 then begin + setlength(ar1,2); + ar1[0]:= fmark1; + ar1[1]:= fmark2; + boldinfo1.backgroundcolor:= + syntaxpainter.colors[syntaxpainterhandle].pairmarkbackground; + if (boldinfo1.backgroundcolor = cl_default) or + (fpairmarkbkgcolor = cl_none) then begin + if fpairmarkbkgcolor = cl_default then begin + boldinfo1.backgroundcolor:= cl_none; + end + else begin + boldinfo1.backgroundcolor:= fpairmarkbkgcolor; + end; + end; + if iswordmark then begin + fmark1.bold:= boldinfo1.backgroundcolor = cl_none; + fmark2.bold:= fmark1.bold; + end; + boldinfo1.items:= ar1; + syntaxpainter.boldchars[syntaxpainterhandle]:= boldinfo1; + refreshsyntax(fmark1.pos.row,1); + refreshsyntax(fmark2.pos.row,1); + end; + inc(fbracketsetting); + try + if boldinfo1.backgroundcolor = cl_none then begin + boldinfo1.backgroundcolor:= cl_transparent; + end; + if fmark1.bold then begin + setfontstyle(pt1,makegridcoord(pt1.col+fmark1.len,pt1.row), + fs_bold,true,cl_default, boldinfo1.backgroundcolor); + setfontstyle(pt2,makegridcoord(pt2.col+fmark1.len,pt2.row), + fs_bold,true,cl_default,boldinfo1.backgroundcolor); + end + else begin + setfontstyle(pt1,makegridcoord(pt1.col+fmark1.len,pt1.row),fs_force,false, + cl_default,boldinfo1.backgroundcolor); + setfontstyle(pt2,makegridcoord(pt2.col+fmark2.len,pt2.row),fs_force,false, + cl_default,boldinfo1.backgroundcolor); + end; + finally + dec(fbracketsetting); + end; + end; +end; + +procedure tsyntaxedit.insertlinebreak; +var + mstr1: msestring; + po1: gridcoordty; + po2: pmsechar; +begin + application.caret.remove; + beginupdate; + feditor.begingroup; + try + inherited; + if seo_autoindent in foptions then begin + po1:= editpos; + if po1.row > 0 then begin + mstr1:= gridvalue[po1.row-1]; + po2:= pmsechar(mstr1); + while (po2^ = ' ') or (po2^ = c_tab) do begin + inc(po2); + end; + setlength(mstr1,po2-pmsechar(mstr1)); +// mstr1:= charstring(msechar(' '),countleadingchars(mstr1,msechar(' '))); + if mstr1 <> '' then begin + po1.col:= 0; + inserttext(po1,mstr1); + end; + end; + end; + finally + application.caret.restore; + feditor.endgroup; + endupdate; + end; +end; + +const + stopchars = [' ',c_tab,'=',':',';',',','.','''','-','+','/','*','^', + '[',']','(',')','{','}']; + +procedure tsyntaxedit.dokeydown(var info: keyeventinfoty); + + function isstopchar(const avalue: msechar): boolean; + begin + result:= (word(avalue) < $100) and (char(byte(avalue)) in stopchars) + end; + +var + int1,int2: integer; + co1: gridcoordty; + shiftstate1: shiftstatesty; +begin + with info do begin + shiftstate1:= shiftstate * shiftstatesmask; + if (shiftstate1 = [ss_ctrl]) or (shiftstate1 = [ss_ctrl,ss_shift]) then begin + case key of + key_left: begin + repeat //skip stopchars + int2:= 0; + for int1:= feditor.curindex downto 1 do begin + if not isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = 0 then begin + if editpos.row > 0 then begin + co1.row:= editpos.row - 1; + co1.col:= bigint; + seteditpos(co1,ss_shift in shiftstate1); + end + else begin + break; + end; + end; + until (int2 > 0); + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + int2:= 0; //skip normal chars + for int1:= feditor.curindex downto 1 do begin + if isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + include(eventstate,es_processed); + end; + key_right: begin + repeat //skip stopchars + int2:= bigint; + for int1:= feditor.curindex + 1 to length(feditor.text) do begin + if not isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = bigint then begin + if editpos.row < linecount - 1 then begin + co1.row:= editpos.row + 1; + co1.col:= 0; + seteditpos(co1,ss_shift in shiftstate1); + end + else begin + break; + end; + end; + until (int2 < bigint); + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + int2:= bigint; //skip normal chars + for int1:= feditor.curindex + 1 to length(feditor.text) do begin + if isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + co1.row:= editpos.row; + co1.col:= int2-1; + seteditpos(co1,ss_shift in shiftstate1); + include(eventstate,es_processed); + end; +(* + key_left: begin + repeat + int2:= 0; + for int1:= feditor.curindex downto 1 do begin + if isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = 0 then begin + if editpos.row > 0 then begin + co1.row:= editpos.row - 1; + co1.col:= bigint; + seteditpos(co1,ss_shift in shiftstate1); + if (length(feditor.text) > 0) and + not isstopchar(feditor.text[length(feditor.text)]) then begin + int2:= length(feditor.text); + end; + end; + end; + until (int2 > 0) or (editpos.row <= 0); + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + repeat + int2:= 0; + for int1:= feditor.curindex downto 1 do begin + if not isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = 0 then begin + if editpos.row > 0 then begin + co1.row:= editpos.row - 1; + co1.col:= bigint; + seteditpos(co1,ss_shift in shiftstate1); + end; + end; + until (int2 > 0) or (editpos.row <= 0); + if int2 > 0 then begin + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + end; + include(eventstate,es_processed); + end; + key_right: begin + repeat + int2:= bigint; + for int1:= feditor.curindex + 1 to length(feditor.text) do begin + if isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = bigint then begin + if editpos.row < linecount - 1 then begin + co1.row:= editpos.row + 1; + co1.col:= 0; + seteditpos(co1,ss_shift in shiftstate1); + if (length(feditor.text) > 0) and + not isstopchar(feditor.text[1]) then begin + int2:= 0; + end; + end; + end; + until (int2 < bigint) or (editpos.row >= linecount - 1); + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + repeat + int2:= bigint; + for int1:= feditor.curindex + 1 to length(feditor.text) do begin + if not isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = bigint then begin + if editpos.row < linecount - 1 then begin + co1.row:= editpos.row + 1; + co1.col:= 0; + seteditpos(co1,ss_shift in shiftstate1); + end; + end; + until (int2 < bigint) or (editpos.row >= linecount - 1); + if int2 < bigint then begin + co1.row:= editpos.row; + co1.col:= int2-1; + seteditpos(co1,ss_shift in shiftstate1); + end; + include(eventstate,es_processed); + end; +*) + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +procedure tsyntaxedit.loaded; +begin + inherited; + checkdefaultsyntax; +end; + +function tsyntaxedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= inherited createdatalist(sender); + checkdefaultsyntax; +end; + +function tsyntaxedit.syntaxchanging: boolean; +begin + result:= fsyntaxchanging <> 0; +end; + +procedure tsyntaxedit.readautoindent(reader: treader); +begin + if reader.readboolean then begin + include(foptions,seo_autoindent); + end; +end; + +procedure tsyntaxedit.readdefaultsyntax(reader: treader); +begin + if reader.readboolean then begin + include(foptions,seo_defaultsyntax); + end; +end; + +procedure tsyntaxedit.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('autoindent',@readautoindent,nil,false); + filer.defineproperty('defaultsyntax',@readdefaultsyntax,nil,false); +end; + +procedure tsyntaxedit.editnotification(var info: editnotificationinfoty); +begin + inherited; + if (info.action = ea_beforechange) and not syntaxchanging then begin + clearpairmarks(); + end + else begin + if (options * [seo_markbrackets,seo_markpairwords] <> []) and + (info.action in [ea_indexmoved,ea_delchar,ea_deleteselection, + ea_pasteselection,ea_textentered]) then begin + if (fbracketchecking = 0) then begin + inc(fbracketchecking); + asyncevent(checkbrackettag); + end; + end; + end; +end; + +procedure tsyntaxedit.doasyncevent(var atag: integer); +begin + inherited; + if atag = checkbrackettag then begin + fbracketchecking:= 0; + checkpairmarks(); + end; +end; + +procedure tsyntaxedit.doafterpaint(const canvas: tcanvas); +begin + inherited; + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + fgridintf.widgetpainted(canvas); + end; +end; + +function tsyntaxedit.needsfocuspaint: boolean; +begin + result:= (fgridintf = nil) and inherited needsfocuspaint; +end; +{ +procedure tsyntaxedit.updatepairwords(); +var + i1,i2: int32; +begin + setlength(fpairwordslower,length(fpairwords)); + if caseinsensitive then begin + for i1:= 0 to high(fpairwords) do begin + setlength(fpairwordslower[i1],length(fpairwords[i1])); + for i2:= 0 to high(fpairwords[i1]) do begin + fpairwordslower[i1,i2]:= mselowercase(fpairwords[i1,i2]); + end; + end; + end + else begin + for i1:= 0 to high(fpairwords) do begin + setlength(fpairwordslower[i1],length(fpairwords[i1])); + for i2:= 0 to high(fpairwords[i1]) do begin + fpairwordslower[i1,i2]:= fpairwords[i1,i2]; + end; + end; + end; +end; +} +function tsyntaxedit.getautoindent: boolean; +begin + result:= seo_autoindent in options; +end; + +procedure tsyntaxedit.setautoindent(const avalue: boolean); +begin + if avalue then begin + options:= options + [seo_autoindent]; + end + else begin + options:= options - [seo_autoindent]; + end; +end; + +function tsyntaxedit.getmarkbrackets: boolean; +begin + result:= seo_markbrackets in options; +end; + +procedure tsyntaxedit.setmarkbrackets(const avalue: boolean); +begin + if avalue then begin + options:= options + [seo_markbrackets]; + end + else begin + options:= options - [seo_markbrackets]; + end; +end; + +function tsyntaxedit.getmarkpairwords: boolean; +begin + result:= seo_markpairwords in options; +end; + +procedure tsyntaxedit.setmarkpairwords(const avalue: boolean); +begin + if avalue then begin + options:= options + [seo_markpairwords]; + end + else begin + options:= options - [seo_markpairwords]; + end; +end; + +function tsyntaxedit.getcaseinsensitive: boolean; +begin + result:= seo_caseinsensitive in options; +end; + +procedure tsyntaxedit.setcaseinsensitive(const avalue: boolean); +begin + if avalue then begin + options:= options + [seo_caseinsensitive]; + end + else begin + options:= options - [seo_caseinsensitive]; + end; +end; + +procedure tsyntaxedit.setpairwords(const avalue: pairwordsty); + procedure error(); + begin + componentexception(self,'Invalid pairwords'); + end; //error +var + i1,i2: int32; +begin + with avalue do begin + if high(upper) <> high(lower) then begin + error(); + end; + for i1:= 0 to high(upper) do begin + for i2:= 0 to high(upper[i1]) do begin + if length(upper[i1,i2]) <> length(lower[i1,i2]) then begin + error(); + end; + end; + end; + end; + fpairwords:= avalue; +// updatepairwords(); +end; + +procedure tsyntaxedit.setoptions(const avalue: syntaxeditoptionsty); +var + delta: syntaxeditoptionsty; +begin + delta:= foptions >< avalue; + if delta <> [] then begin + foptions:= avalue; + if seo_defaultsyntax in delta then begin + checkdefaultsyntax; + end; +// if seo_caseinsensitive in delta then begin +// updatepairwords(); +// end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msesyntaxpainter.pas b/mseide-msegui/lib/common/designutils/msesyntaxpainter.pas new file mode 100644 index 0000000..94c27a8 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesyntaxpainter.pas @@ -0,0 +1,1942 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesyntaxpainter; +(* + +sdef file = +{globaldefinition} +{scope} +//last scope is default scope +globaldefinition = CASEINSENSITIVE | keywordchars | addkeywordchars | + keyworddefs | editorcolors | styles | pairwords + +keywordchars = +KEYWORDCHARS newline +{{string} newline} +//default = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy0123456789_' + +addkeywordchars = +ADDKEYWORDCHARS newline +{{string} newline} + +string = +'{character}' + +character = +ASCII-character + +styles = +STYLE newline +{stylename styledef newline} + +styledef = +[stylestring [fontcolor [colorbackground]]] + +stylestring = +'[b][i][u][s]' +//b = bold i = italic u = underline s = strikeout + +keyworddefs = +KEYWORDDEFS keyworddefsname [stylename] newline +{{keyword} newline} + +keyword = +string + +editorcolors = +COLORS [fontcolor [backgroundcolor [statementcolor [pairmarkbackgroundcolor]]]] +// cl_default for MSEide project options settings + +pairwords = +PAIRWORDS newline +{pairbegin {pairbegin} pairend newline} +// used in MSEide + +pairbegin = string +pairend = string + +scope = +SCOPE scopename [stylename] newline +{localdefinition} + +localdefinition = +keywords | calltokens | jumptokens | endtokens | RETURN newline + +keywords = +KEYWORDS [style] newline //style used as default +{keyworddefsname [style] newline} + +calltokens = +CALLTOKENS newline +{{[.|,]string}[.]} scopename newline} + + //. -> whitespace, example: + //'begin' finds 'abeginz ... + //.'begin' finds newline'beginz', ' beginz' ... + //'begin'. finds 'abegin ', 'abegin'newline ... + //.'begin'. finds newline'begin ',' begin ', ' begin'newline ... + //, -> begin of line + +jumptokens = +JUMPTOKENS newline +[{{[.]string}[.]}] scopename newline} + +// scopename newline -> unconditional jump + +endtokens = +ENDTOKENS newline +{{[.]string}[.]} [stylename] newline} + + //'' -> end of line + +*) + +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msestrings,mserichstring,msedatalist, + msestream,msehash,msetimer,msestat,msetypes,mseclasses,mseguiglob,mseevent, + msegraphutils; + +const + defaultkeywordchars: set of char = ['A'..'Z','a'..'z','0'..'9','_']; + defaultlinesperslice = 100; + +type + tokencharsty = set of char; + tokenflagty = (tf_firstofline,tf_startwhitespace,tf_endwhitespace); + tokenflagsty = set of tokenflagty; + tokeninfoty = record + name: msestring; + flags: tokenflagsty; + end; + ptokeninfoty = ^tokeninfoty; + tokeninfoarty = array of tokeninfoty; + + + starttokenty = record + token: tokeninfoty; + hastokenchars: boolean; + tokenchars: tokencharsty; + shortcircuit: boolean; + fontinfonr: integer; + scopenr: integer; + call: boolean; + end; + starttokenpoty = ^starttokenty; + starttokenarty = array of starttokenty; + + endtokenty = record + token: tokeninfoty; + hastokenchars: boolean; + tokenchars: tokencharsty; + fontinfonr: integer; + end; + endtokenpoty = ^endtokenty; + endtokenarty = array of endtokenty; + + keywordinfoty = record + nr: integer; + fontinfonr: integer; + end; + keywordinfoarty = array of keywordinfoty; + + scopeinfoty = record + keywords: keywordinfoarty; + starttokens: starttokenarty; + endtokens: endtokenarty; + hasendtokens: boolean; + defaulttarget: int32; + return: boolean; + fontinfonr: integer; + currfontinfonr: integer; + end; + scopeinfopoty = ^scopeinfoty; + scopeinfoarty = array of scopeinfoty; + charsty = set of char; + charspoty = ^charsty; + + tkeywordlist = class(tpointermsestringhashdatalist) + protected + fdefaultstyle: integer; + public + constructor create; + end; + + keywordarty = array of tkeywordlist; + + refreshinfoty = record + astart,count: integer; + handle: integer; +// startscopenr: integer; + end; + prefreshinfoty = ^refreshinfoty; + + trefreshinfolist = class(tdatalist) + private + function Getitems(index: integer): refreshinfoty; + procedure Setitems(index: integer; const Value: refreshinfoty); //fifo + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + public + constructor create; override; + procedure push(const value: refreshinfoty); + function pop: boolean; overload; + function pop(out value: refreshinfoty): boolean; overload; + property items[index: integer]: refreshinfoty read Getitems + write Setitems; default; + end; + + scopestackcachety = record + startscope: integer; + stack: integerarty; + end; + + scopestackcachearty = array of scopestackcachety; + + markitemty = record + bold: boolean; + pos: gridcoordty; + len: int32; + end; + markitemarty = array of markitemty; + + markinfoty = record + backgroundcolor: colorty; + items: markitemarty; + end; + +const + emptymarkinfo: markinfoty = (backgroundcolor: cl_none; items: nil); + +type + clientinfoty = record + client: tobject; + syntaxdefhandle: integer; + scopestack: integerarty; + scopestackpo: integer; + scopestackcache: scopestackcachearty; + scopestackcachepo: integer; + list: trichstringdatalist; + onlinechanged: integerchangedeventty; + boldchars: markinfoty; + end; + pclientinfoty = ^clientinfoty; + clientinfoarty = array of clientinfoty; + + syntaxcolorinfoty = record + font: colorty; + background: colorty; + statement: colorty; + pairmarkbackground: colorty; + end; + + pairwordsty = record + upper: msestringararty; + lower: msestringararty; + end; + syntaxdefty = record + defdefsnr: integer; //-1 -> mit readdeffile geladen + charstyles: tcharstyledatalist; + pairwords: pairwordsty; + caseinsensitive: boolean; + scopeinfos: scopeinfoarty; + aktscopeinfo: integer; + keywordchars: charsty; + scopeendchars,scopestartchars: charsty; + keywordar: keywordarty; +// keywordnames: thashedstrings; + keywordnames: tpointeransistringhashdatalist; + colors: syntaxcolorinfoty; + end; + + syntaxdefpoty = ^syntaxdefty; + syntaxdefarty = array of syntaxdefty; + + tsyntaxpainter = class(tmsecomponent) + private + ftimer: tsimpletimer; + frefreshlist: trefreshinfolist; + flinesperslice: integer; + fclients: clientinfoarty; + fsyntaxdefs: syntaxdefarty; + fdefdefs: tdoublemsestringdatalist; + fdefsdir: filenamety; + fdeftext: tmsestringdatalist; + fdefaultsyntax: integer; + procedure dotimer(const sender: tobject); + procedure syntaxchanged; + procedure internalpaintsyntax(handle: integer; start,count: integer; + var startscopenr: integer); + //-1 = letzte in fscopeinfos + procedure clearsyntaxdef(handle: integer); + procedure initsyntaxdef(handle: integer); + procedure setdefdefs(const Value: tdoublemsestringdatalist); + procedure setlinesperslice(const Value: integer); + procedure calcrefreshinfo(var info: refreshinfoty; var startscope: integer); + procedure setdeftext(const avalue: tmsestringdatalist); + procedure deflistchanged(const sender: tobject); + function getboldchars(index: integer): markinfoty; + procedure setboldchars(index: integer; const avalue: markinfoty); + function getcolors(index: integer): syntaxcolorinfoty; + function getpairwords(index: int32): pairwordsty; + function getcaseinsensitive(index: int32): boolean; + protected + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; + procedure paintsyntax(handle: integer; start,count: halfinteger; + background: boolean = false); + //-1 = letzte in fscopeinfos + function registerclient(sender: tobject; alist: trichstringdatalist; + aonlinechanged: integerchangedeventty = nil; + asyntaxdefhandle: integer = 0): integer; + //-1 = alles veraendert + + procedure unregisterclient(handle: integer); + //eintreage mit alist loeschen + function readdeffile(stream: ttextstream): integer; overload; + function readdeffile(const afilename: filenamety): integer; overload; + function readdeffile(const atext: string): integer; overload; + procedure freedeffile(handle: integer); + function linkdeffile(const sourcefilename: filenamety): integer; + //-1 if syntaxdef not found + property defaultsyntax: integer read fdefaultsyntax; + property boldchars[index: integer]: markinfoty read getboldchars + write setboldchars; + property colors[index: integer]: syntaxcolorinfoty read getcolors; + property caseinsensitive[index: int32]: boolean read getcaseinsensitive; + property pairwords[index: int32]: pairwordsty read getpairwords; + published + property linesperslice: integer read flinesperslice write setlinesperslice + default defaultlinesperslice; + property defdefs: tdoublemsestringdatalist read fdefdefs write setdefdefs; + //a = filemask, b = deffilename, + // multiple masks quoted + // examples : a b + // '*.pp' 'pas.sdef' + // '"*.pp" "*.pas"' 'pas.sdef' + + property defsdir: filenamety read fdefsdir write fdefsdir; + property deftext: tmsestringdatalist read fdeftext write setdeftext; + end; + +implementation +uses + sysutils,msefileutils,msesys,mseformatstr,msegraphics,mseglob,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure markstartchars(const str: msestring; var chars: charsty; + const caseinsensitive: boolean); overload; +var + ch1: char; +begin + if length(str) = 0 then begin + include(chars,#0); + end + else begin + if getansichar(str[1],ch1) then begin + if caseinsensitive then begin + include(chars,lowerchars[ch1]); + include(chars,upperchars[ch1]); + end + else begin + include(chars,ch1); + end; + end; + end +end; + +procedure markstartchars(const strar: msestringarty; var chars: charsty; + const caseinsensitive: boolean); overload; +var + int1: integer; +begin + for int1:= 0 to high(strar) do begin + markstartchars(strar[int1],chars,caseinsensitive); + end; +end; + +procedure markstartchars(const starttokens: starttokenarty; + var chars: charsty; const caseinsensitive: boolean); overload; +var + int1: integer; + ch1: char; +begin + for int1:= 0 to high(starttokens) do begin + with starttokens[int1] do begin + if hastokenchars then begin + chars:= chars + tokenchars; + end + else begin + if length(token.name) = 0 then begin + include(chars,#0); + end + else begin + if getansichar(starttokens[int1].token.name[1],ch1) then begin + if caseinsensitive then begin + include(chars,lowerchars[ch1]); + include(chars,upperchars[ch1]); + end + else begin + include(chars,ch1); + end; + end; + end; + end; + end; + end; +end; + +{ trefreshinfolist } + +constructor trefreshinfolist.create; +begin + inherited; + fsize:= sizeof(refreshinfoty); +end; + +function trefreshinfolist.Getitems(index: integer): refreshinfoty; +begin + getdata(index,result); +end; + +procedure trefreshinfolist.Setitems(index: integer; + const Value: refreshinfoty); +begin + setdata(index,value); +end; + +function trefreshinfolist.pop: boolean; +var + po1: pbyte; +begin + po1:= nil; + {$ifdef FPC}{$checkpointer off}{$endif} + result:= popbottomdata(po1^); + {$ifdef FPC}{$checkpointer default}{$endif} +end; + +function trefreshinfolist.pop(out value: refreshinfoty): boolean; +begin + result:= popbottomdata(value); +end; + +procedure trefreshinfolist.push(const value: refreshinfoty); +begin + pushdata(value); +end; + +function trefreshinfolist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(trefreshinfolist); +end; + +{ tsyntaxpainter } + +constructor tsyntaxpainter.create(aowner: tcomponent); +begin + frefreshlist:= trefreshinfolist.create; + ftimer:= tsimpletimer.Create(0,{$ifdef FPC}@{$endif}dotimer,false,[to_single]); + flinesperslice:= defaultlinesperslice; + fdefdefs:= tdoublemsestringdatalist.create; + fdefaultsyntax:= -1; +// fdefaultboldbkgcolor:= cl_none; + fdeftext:= tmsestringdatalist.create; + fdeftext.onchange:= {$ifdef FPC}@{$endif}deflistchanged; + inherited; +end; + +destructor tsyntaxpainter.destroy; +begin + clear; + inherited; + ftimer.Free; + frefreshlist.Free; + fdefdefs.free; + fdeftext.free; +end; + +procedure tsyntaxpainter.clear; +var + int1: integer; +begin + frefreshlist.clear; + for int1:= 0 to high(fclients) do begin + if fclients[int1].client <> nil then begin + unregisterclient(int1); + end; + end; + for int1:= 0 to high(fsyntaxdefs) do begin + clearsyntaxdef(int1); + end; + sendchangeevent(oe_disconnect); +end; + +procedure tsyntaxpainter.clearsyntaxdef(handle: integer); +var + int1: integer; +begin + with fsyntaxdefs[handle] do begin + freeandnil(charstyles); + freeandnil(keywordnames); + for int1:= 0 to high(keywordar) do begin + keywordar[int1].Free; + end; + end; + finalize(fsyntaxdefs[handle]); +end; + +procedure tsyntaxpainter.initsyntaxdef(handle: integer); +begin + finalize(fsyntaxdefs[handle]); + fillchar(fsyntaxdefs[handle],sizeof(syntaxdefty),0); + with fsyntaxdefs[handle] do begin + defdefsnr:= -1; + charstyles:= tcharstyledatalist.create; + charstyles.add; //default + keywordchars:= defaultkeywordchars; + keywordnames:= tpointeransistringhashdatalist.create; + with colors do begin + font:= cl_default; + background:= cl_default; + statement:= cl_default; + pairmarkbackground:= cl_default; + end; + end; +end; + +function tsyntaxpainter.registerclient(sender: tobject; + alist: trichstringdatalist; aonlinechanged: integerchangedeventty = nil; + asyntaxdefhandle: integer = 0): integer; + + procedure initclient(var info: clientinfoty); + begin + info.client:= sender; + info.syntaxdefhandle:= asyntaxdefhandle; + info.list:= alist; + info.onlinechanged:= aonlinechanged; + end; + +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + if fclients[int1].client = nil then begin + initclient(fclients[int1]); + result:= int1; + exit; + end; + end; + setlength(fclients,length(fclients)+1); + initclient(fclients[high(fclients)]); + result:= high(fclients); +end; + +procedure tsyntaxpainter.unregisterclient(handle: integer); + //eintreage mit alist loeschen +var + int1: integer; +begin + checkarrayindex(fclients,handle); + int1:= 0; + while int1 < frefreshlist.count do begin + if frefreshlist[int1].handle = handle then begin + frefreshlist.deletedata(int1); + end + else begin + inc(int1); + end; + end; + finalize(fclients[handle]); + fillchar(fclients[handle],sizeof(clientinfoty),0); +end; + +procedure tsyntaxpainter.setlinesperslice(const Value: integer); +var + int1: integer; +begin + if flinesperslice <> value then begin + flinesperslice := Value; + for int1:= 0 to high(fclients) do begin + with fclients[int1] do begin + scopestackcache:= nil; //scopestacks are now invlid + scopestackcachepo:= 0; + end; + end; + end; +end; + +procedure tsyntaxpainter.internalpaintsyntax(handle: integer; + start,count: integer; var startscopenr: integer); +var + scopeinfopo: scopeinfopoty; + + procedure popscope; + begin + with fclients[handle] do begin + if scopestackpo > 0 then begin + dec(scopestackpo); + startscopenr:= scopestack[scopestackpo]; + scopeinfopo:= @fsyntaxdefs[syntaxdefhandle].scopeinfos[startscopenr]; + end; + end; + end; + + procedure pushscope(const starttoken: starttokenty); + var + po1: scopeinfopoty; + begin + with starttoken,fclients[handle] do begin + if call then begin + inc(scopestackpo); + if length(scopestack) <= scopestackpo then begin + setlength(scopestack,scopestackpo+1); + end; + end; + scopestack[scopestackpo]:= scopenr; + po1:= @fsyntaxdefs[syntaxdefhandle].scopeinfos[scopenr]; + if po1^.fontinfonr <> 0 then begin + po1^.currfontinfonr:= po1^.fontinfonr; + end + else begin + if starttoken.fontinfonr <> 0 then begin + po1^.currfontinfonr:= starttoken.fontinfonr; + end + else begin + po1^.currfontinfonr:= scopeinfopo^.currfontinfonr; + end; + end; + scopeinfopo:= po1; + startscopenr:= scopenr; + end; + end; + +var + startpo: pmsechar; + linestart: boolean; + + function checktokenwhitespace(const atoken: tokeninfoty; + const apo: pmsechar): boolean; + var + po1: pmsechar; + begin + result:= not (tf_firstofline in atoken.flags) or linestart; + if result then begin + result:= (not (tf_startwhitespace in atoken.flags) or + (apo = startpo) or ((apo-1)^ = ' ') or ((apo-1)^ = c_tab)); + if result and (tf_endwhitespace in atoken.flags) then begin + po1:= apo+length(atoken.name); + result:= (po1^ = ' ') or (po1^ = c_tab) or (po1^ = #0) or + (po1^ = c_return) or (po1^ = c_linefeed); + end; + end; + end; + +var + str1: msestring; + lstr1: lmsestringty; + po1: pointer; + changed: boolean; + int1,int2,int3: integer; + bo1{,bo2}: boolean; + ristr: prichstringty; + wpo1: pmsechar; + alen,keywordlen: integer; +// ar1: msestringarty; + stok1: starttokenty; + format: formatinfoarty; +// firstrow,lastrow: integer; + wpo2: pmsechar; + +label + endlab; + +begin +// ar1:= nil; //copilerwarning + format:= nil; //copilerwarning + str1:= ''; + int2:= 0; +// firstrow:= start; +// lastrow:= start+count-1; + with fclients[handle] do begin + if (syntaxdefhandle < 0) or (syntaxdefhandle > high(fsyntaxdefs)) or + (fsyntaxdefs[syntaxdefhandle].charstyles = nil) then begin + goto endlab; + end; + with fsyntaxdefs[syntaxdefhandle] do begin + if startscopenr = -1 then begin + startscopenr:= high(scopeinfos); + stok1.scopenr:= startscopenr; + stok1.fontinfonr:= 0; + stok1.call:= true; + scopestackpo:= -1; + scopeinfopo:= @scopeinfos[startscopenr]; + pushscope(stok1); + end; + if (startscopenr >= 0) and (startscopenr < length(scopeinfos)) then begin + scopeinfopo:= @scopeinfos[startscopenr]; + while count > 0 do begin + if start >= list.count then begin + goto endlab; + end; + if (flinesperslice <> 0) and (start mod flinesperslice = 0) then begin + scopestackcachepo:= start div flinesperslice + 1; + if length(scopestackcache) < scopestackcachepo then begin + setlength(scopestackcache,scopestackcachepo); + end; + scopestackcache[scopestackcachepo-1].stack:= + copy(scopestack,0,scopestackpo+1); + scopestackcache[scopestackcachepo-1].startscope:= startscopenr; + end; + changed:= false; + ristr:= list.richitemspo[start]; + format:= ristr^.format; + startpo:= pointer(ristr^.text); + linestart:= true; + wpo1:= startpo; + alen:= length(ristr^.text); + keywordlen:= 0; + changed:= setcharstyle1(format,0,bigint, + charstyles[scopeinfopo^.currfontinfonr]) or + changed; + if alen > 0 then begin + repeat + if (wpo1^ = c_return) or (wpo1^ = c_linefeed) then begin + linestart:= true; + end; + if (keywordlen <= 0) and not scopeinfopo^.return then begin + lstr1.po:= wpo1; + while char(byte(wpo1^)) in keywordchars do begin + inc(wpo1); + end; + lstr1.len:= wpo1-lstr1.po; + if lstr1.len > 0 then begin //keyword suchen + if caseinsensitive then begin + str1:= struppercase(lstr1); + end; + po1:= nil; + for int1:= 0 to high(scopeinfopo^.keywords) do begin + with keywordar[scopeinfopo^.keywords[int1].nr{-1}] do begin + if caseinsensitive then begin + po1:= find(str1); + end + else begin + po1:= find(lstr1); + end; + end; + if po1 <> nil then begin //wort gefunden + if scopeinfopo^.keywords[int1].fontinfonr <> 0 then begin + po1:= pointer(scopeinfopo^.keywords[int1].fontinfonr+1); + end; //eigene fontinfonr dominiert + break; + end; + end; + if po1 <> nil then begin + changed:= setcharstyle1(format,lstr1.po-startpo,lstr1.len, + charstyles[ptruint(po1)-1]) or changed; + dec(alen,lstr1.len); + keywordlen:= 0; + linestart:= false; + end + else begin + keywordlen:= lstr1.len; + dec(wpo1,lstr1.len); //text zurueckgeben + end; + end; + end; + bo1:= true; + if (length(scopeinfopo^.starttokens) > 0) then begin + if (char(byte(wpo1^)) in scopestartchars) then begin + //starttoken suchen + for int1:= 0 to high(scopeinfopo^.starttokens) do begin + with scopeinfopo^.starttokens[int1] do begin + if hastokenchars then begin + wpo2:= wpo1; + while (wpo2^ <= #255) and (char(byte(wpo2^)) in tokenchars) do begin + inc(wpo2); + if not shortcircuit then begin + break; + end; + end; + int2:= wpo2-wpo1; + if int2 > 0 then begin + bo1:= false; + end; + end + else begin + if caseinsensitive and msestartsstrcaseinsensitive( + pointer(token.name),wpo1) or + not caseinsensitive and + msestartsstr(pointer(token.name),wpo1) then begin + if checktokenwhitespace(token,wpo1) then begin + bo1:= false; + int2:= length(token.name); + end; + end; + end; + if not bo1 then begin + if fontinfonr <> 0 then begin + changed:= setcharstyle1(format,wpo1-startpo,int2, + charstyles[fontinfonr]) or changed; + int3:= int2; + end + else begin + int3:= 0; //keine sonderbehandlung + end; + pushscope(scopeinfopo^.starttokens[int1]); + changed:= setcharstyle1(format,wpo1-startpo+int3,bigint, + charstyles[scopeinfopo^.currfontinfonr]) or changed; + inc(wpo1,int2); + dec(alen,int2); + dec(keywordlen,int2); + break; + end; + end; + end; + end + else begin + if scopeinfopo^.defaulttarget >= 0 then begin + pushscope(scopeinfopo^.starttokens[scopeinfopo^.defaulttarget]); + changed:= setcharstyle1(format,wpo1-startpo+int3,bigint, + charstyles[scopeinfopo^.currfontinfonr]) or changed; + end; + end; + end; + if bo1 and (scopeinfopo^.hasendtokens or scopeinfopo^.return) then begin + if (length(scopeinfopo^.endtokens) > 0) then begin + if (char(byte(wpo1^)) in scopeendchars) then begin + //endtoken suchen + for int1:= 0 to high(scopeinfopo^.endtokens) do begin + with scopeinfopo^.endtokens[int1] do begin + if hastokenchars then begin + if (wpo1^ <= #255) and (char(byte(wpo1^)) in tokenchars) then begin + int2:= 1; + bo1:= false; + end; + end + else begin + if (caseinsensitive and msestartsstrcaseinsensitive( + pointer(token.name),wpo1) or + not caseinsensitive and + msestartsstr(pointer(token.name),wpo1)) and + checktokenwhitespace(token,wpo1) then begin +// if msestartsstr(pointer(token.name),wpo1) and +// checktokenwhitespace(token,wpo1) then begin + bo1:= false; + int2:= length(token.name); + end; + end; + if not bo1 then begin + if fontinfonr <> 0 then begin + int3:= fontinfonr; + end + else begin + int3:= scopeinfopo^.currfontinfonr; + end; + changed:= setcharstyle1(format,wpo1-startpo,int2, + charstyles[int3]) or changed; + inc(wpo1,int2); + if int2 = 0 then begin + int2:= 1; //zeilenende + end; + dec(alen,int2); + dec(keywordlen,int2); + popscope; + changed:= setcharstyle1(format,wpo1-startpo,bigint, + charstyles[scopeinfopo^.currfontinfonr]) or changed; + break; + end; + end; + end; + end; + end + else begin //return on any char + if not scopeinfopo^.return and (wpo1^ <> #0) then begin + inc(wpo1); + end; //else return immediately + bo1:= false; + popscope; + changed:= setcharstyle1(format,wpo1-startpo,bigint, + charstyles[scopeinfopo^.fontinfonr]) or changed; + end; + end; + + if bo1 then begin + if (wpo1^ <> ' ') and (wpo1^ <> c_tab) then begin + linestart:= false; + end; + inc(wpo1); + dec(alen); + dec(keywordlen); + end + else begin + linestart:= false; + end; + until alen < 0; + if scopeinfopo^.return then begin + popscope; + end; + end; + if changed then begin + for int1:= 0 to high(boldchars.items) do begin + with boldchars.items[int1],pos do begin + if row = start then begin + if bold then begin + bo1:= not (fs_bold in getcharstyle(format,col).fontstyle); + updatefontstyle1(format,col,len,fs_bold,bo1); + end; + if (boldchars.backgroundcolor <> cl_none) then begin + setcolorbackground1(format,col,len,boldchars.backgroundcolor); + end; + end; + end; + end; + if assigned(onlinechanged) then begin + bo1:= isequalformat(ristr^.format,format); + if not bo1 then begin + ristr^.format:= format; + onlinechanged(self,start); + end; + end + else begin + ristr^.format:= format; + end; + end; + inc(start); + dec(count); + end; + end; + end; +endlab: +{ + for int1:= 0 to high(boldchars.items) do begin + with boldchars.items[int1],pos do begin + if (row >= firstrow) and (row <= lastrow) then begin + bo2:= false; + if bold then begin + bo1:= not (fs_bold in getcharstyle( + list.richitemspo[row]^.format,col).fontstyle); + bo2:= updatefontstyle1(list.richitemspo[row]^.format,col,len,fs_bold,bo1); + end; + bo2:= (boldchars.backgroundcolor <> cl_none) and + setcolorbackground1(list.richitemspo[row]^.format,col,len, + boldchars.backgroundcolor) or bo2; + if bo2 and assigned(onlinechanged) then begin + onlinechanged(self,row); + end; + end; + end; + end; +} + end; +end; + +procedure tsyntaxpainter.calcrefreshinfo(var info: refreshinfoty; var startscope: integer); +var + startbefore: integer; + stackspo: integer; +begin + with info do begin + startbefore:= astart; + if flinesperslice > 0 then begin + stackspo:= astart div flinesperslice; + end + else begin + stackspo:= -1; + end; + with fclients[handle] do begin + if stackspo >= scopestackcachepo then begin + stackspo:= scopestackcachepo-1; + end; + if stackspo >= 0 then begin + astart:= stackspo * flinesperslice; + scopestack:= scopestackcache[stackspo].stack; + scopestackpo:= high(scopestack); + startscope:= scopestackcache[stackspo].startscope; + end + else begin + startscope:= -1; + astart:= 0; //recalc from begining + end; + count:= count + astart - startbefore; + end; + end; +end; + +procedure tsyntaxpainter.paintsyntax(handle: integer; + start,count: halfinteger; background: boolean = false); + + +var + refreshinfo: refreshinfoty; + int1,int2: integer; + startscopenr: integer; + po1: prefreshinfoty; +begin + checkarrayindex(fclients,handle); +// refreshinfo.startscopenr:= -1; + refreshinfo.handle:= handle; + refreshinfo.astart:= start; + refreshinfo.count:= count; + if background then begin + for int1:= 0 to frefreshlist.count - 1 do begin + po1:= frefreshlist.getitempo(int1); + if po1^.handle = handle then begin + int2:= start+count - (po1^.astart + po1^.count); //new endpoint - aendpoint + if po1^.astart <= start then begin + if int2 > 0 then begin //new task longer + inc(po1^.count,int2); //exend end + end; + end + else begin + if int2 > 0 then begin //new task longer + po1^.count:= count; + end + else begin + inc(po1^.count,po1^.astart-start); + end; + po1^.astart:= start; + end; + exit; //task extended + end; + end; + frefreshlist.push(refreshinfo); + ftimer.Enabled:= true; + exit; + end; + calcrefreshinfo(refreshinfo,startscopenr); + internalpaintsyntax(handle,refreshinfo.astart,refreshinfo.count,startscopenr); +end; + +procedure tsyntaxpainter.dotimer(const sender: tobject); +var + po1: prefreshinfoty; + int1: integer; + startscopenr: integer; +begin + if frefreshlist.count > 0 then begin + po1:= prefreshinfoty(frefreshlist.getitempo(0)); + calcrefreshinfo(po1^,startscopenr); + with po1^ do begin + if flinesperslice = 0 then begin + int1:= count; + end + else begin + if count > flinesperslice + 1 then begin + int1:= flinesperslice + 1; + end + else begin + int1:= count; + end; + end; + internalpaintsyntax(handle,astart,int1,startscopenr); + dec(count,int1); + if count <= 0 then begin + frefreshlist.pop + end + else begin + inc(astart,int1); + if astart >= fclients[handle].List.count then begin + frefreshlist.pop; + end + end; + end; + if frefreshlist.count <> 0 then begin + ftimer.Enabled:= true; + end; + end; +end; + +procedure checktokenchars(const ar1: tokeninfoarty; + const caseinsensitive: boolean; + out hastokenchars: boolean; out tokenchars: tokencharsty); +var + int1: integer; + ch1: char; +begin + hastokenchars:= ar1 <> nil; + tokenchars:= []; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if (length(name) <> 1) or (name[1] > #255) or (flags <> []) then begin + hastokenchars:= false; + break; + end; + end; + end; + if hastokenchars then begin + for int1:= 0 to high(ar1) do begin + ch1:= char(byte(ar1[int1].name[1])); + if caseinsensitive then begin + include(tokenchars,upperchars[ch1]); + include(tokenchars,lowerchars[ch1]); + end + else begin + include(tokenchars,ch1); + end; + end; + end; +end; + +function nexttokeninfo(var value: lstringty; out res: string; + out tokenflags: tokenflagsty): boolean; + //false wenn kein quote vorhanden +var + po1: pchar; + int1,int2,int3: integer; +begin + result:= false; + res:= ''; + tokenflags:= []; + po1:= strlnscan(value.po,' ',value.len); //skip spaces + if po1 = nil then begin + int1:= value.len; + end + else begin + int1:= po1-value.po; //startindex + end; + if (po1 <> nil) then begin + if po1^ = '.' then begin + include(tokenflags,tf_startwhitespace); + inc(po1); + end + else begin + if po1^ = ',' then begin + include(tokenflags,tf_firstofline); + inc(po1); + end; + end; + if po1^ = '''' then begin + result:= true; + inc(po1); + int2:= 0; + int3:= value.len-int1; + setlength(res,int3); //maximum + while po1^ <> #0 do begin + if po1^ <> '''' then begin + (pchar(pointer(res))+int2)^:= po1^; + inc(int2); + end + else begin + inc(po1); + if po1^ = '''' then begin + (pchar(pointer(res))+int2)^:= po1^; + inc(int2); + end + else begin + if po1^ = '.' then begin + include(tokenflags,tf_endwhitespace); + inc(po1); + end; + break; + end; + end; + inc(po1); + end; + setlength(res,int2); + int1:= po1-value.po; + end; + end; + inc(value.po,int1); + dec(value.len,int1); +end; + +function tsyntaxpainter.readdeffile(stream: ttextstream): integer; +type + tokennrty = (tn_styles,tn_caseinsensitive,tn_keywordchars,tn_addkeywordchars, + tn_colors,tn_pairwords,tn_keyworddefs, + tn_scope,tn_endtokens,tn_keywords,tn_jumptokens,tn_calltokens, + tn_return); +const + tn_canmultiple = [tn_keyworddefs{,tn_jumptokens,tn_calltokens,tn_endtokens}]; + + nonetoken = 'NONE'; + tokens: array[tokennrty] of string = ( + 'STYLES','CASEINSENSITIVE','KEYWORDCHARS','ADDKEYWORDCHARS', + 'COLORS','PAIRWORDS','KEYWORDDEFS', + 'SCOPE','ENDTOKENS','KEYWORDS','JUMPTOKENS','CALLTOKENS', + 'RETURN'); + tn_localstart = tn_scope; +var + linenr: integer; + line: string; + akttoken: tokennrty; + syntaxdefpo: syntaxdefpoty; + + procedure addkeywordrule(const keywordsnr: integer; afontinfonr: integer); + begin + with syntaxdefpo^ do begin + setlength(scopeinfos[aktscopeinfo].keywords, + length(scopeinfos[aktscopeinfo].keywords)+1); + with scopeinfos[aktscopeinfo].keywords[high(scopeinfos[aktscopeinfo].keywords)] do begin + nr:= keywordsnr; + fontinfonr:= afontinfonr; + end; + end; + end; + + procedure updateaktscope; + var + int1: integer; + begin + with syntaxdefpo^ do begin + if aktscopeinfo < length(scopeinfos) then begin + with scopeinfos[aktscopeinfo] do begin + markstartchars(starttokens,scopestartchars,caseinsensitive); + for int1:= 0 to high(endtokens) do begin + with endtokens[int1] do begin + if hastokenchars then begin + scopeendchars:= scopeendchars + endtokens[int1].tokenchars; + end + else begin + markstartchars(token.name,scopeendchars,caseinsensitive); + end; + end; + end; + end; + end; + end; + end; //updateaktscope + + function addscoperule(const astarttokens: starttokenarty; + const aendtokens: endtokenarty; ahasendtokens: boolean; + areturn: boolean; + afontinfonr: integer; + const akeywords: keywordinfoarty; + const adefaulttarget: int32): integer; + + begin + with syntaxdefpo^ do begin + result:= length(scopeinfos); + aktscopeinfo:= result; + setlength(scopeinfos,result+1); + with scopeinfos[result] do begin + keywords:= akeywords; + starttokens:= copy(astarttokens); + endtokens:= copy(aendtokens); + hasendtokens:= ahasendtokens; + return:= areturn; + fontinfonr:= afontinfonr; + defaulttarget:= adefaulttarget; + end; + updateaktscope; + end; + end; + + + procedure error(text: string); + begin + raise exception.Create(text+'!'); + end; + + function lineinfo: string; + begin + result:= ' at line '+ inttostr(linenr); + end; + + procedure invalidtoken; + begin + error('Invalid token '''+line+''''+lineinfo); + end; + + procedure noscope; + begin + error('No scope'+lineinfo); + end; + + procedure invalidstyle; + begin + error('Invalid style '''+line+''''+lineinfo); + end; + + procedure invalidname; + begin + error('Invalid name '''+line+''''+lineinfo); + end; + + procedure nameexists; + begin + error('Name exists. '''+line+''''+lineinfo); + end; + + procedure namenotfound; + begin + error('Name not found. '''+line+''''+lineinfo); + end; + + procedure invalidstring; + begin + error('Invalid string. '''+line+''''+lineinfo); + end; + + procedure invalidcolor; + begin + error('Invalid color. '''+line+''''+lineinfo); + end; + + function getcolor(var aline: lstringty; out acolor: colorty): boolean; + var + str1: string; + begin + result:= false; + nextword(aline,str1); + if str1 <> '' then begin + try + acolor:= stringtocolor(str1); + except + invalidcolor; + end; + end; + result:= true; + end; + + procedure addname(list: tpointeransistringhashdatalist; + const name: lstringty; nummer: integer); + var + str1: string; + begin + str1:= struppercase(name); + if list.find(str1) <> nil then begin + nameexists; + end; + if (length(str1) = 0) or not ((str1[1] >= 'A') and (str1[1] <= 'Z')) then begin + invalidname; + end; + list.add(str1,pointer(nummer+1)); + end; + + function findname(list: tpointeransistringhashdatalist; const name: lstringty): integer; + begin + result:= ptrint(list.find(struppercase(name))); + if result = 0 then begin + namenotfound; + end; + dec(result); + end; + +var + lstr1: lstringty; + + function nextline: boolean; + begin + if stream.eof then begin + lstr1.len:= 0; + lstr1.po:= nil; + result:= true; + end + else begin + stream.readln(line); + inc(linenr); + result:= (strlnscan(pointer(line),' ',length(line)) <> nil) and + (checkfirstchar(line,'#') = nil); //comment + if result then begin + stringtolstring(line,lstr1); + end; + end; + end; + + procedure addquotedtokens(var ar1: tokeninfoarty; out isnextline: boolean); + var + str1: string; + tf1: tokenflagsty; + begin + isnextline:= false; + if not stream.eof then begin + while true do begin + while nexttokeninfo(lstr1,str1,tf1) do begin + setlength(ar1,high(ar1)+2); + with ar1[high(ar1)] do begin + name:= msestring(str1); + flags:= tf1; + end; + isnextline:= false; + end; + if lstr1.len = 0 then begin + isnextline:= true; + if stream.eof then begin + break; + end; + repeat + until nextline; //skip comments + end + else begin + break; + end; + end; + end; + end; //getquotedstrings + +const + defaultname = 'DEFAULT'; +var + flags: set of tokennrty; + str1{,str2}: string; + keys: tpointeransistringhashdatalist; + scopenames,stylenames: tpointeransistringhashdatalist; + int1,int2,int3,int4: integer; + lstr2,lstr3,lstr4: lstringty; + global: boolean; + wstrar1: msestringarty; + bo1,bo2: boolean; + aktkeywordfontinfonr: integer; + ar1: tokeninfoarty; + ar2: msestringarty; + tokenchars1: tokencharsty; + isnextline: boolean; + tf1: tokenflagsty; + i5: int32; + +begin + result:= -1; + for int1:= 0 to high(fsyntaxdefs) do begin + if fsyntaxdefs[int1].charstyles = nil then begin + result:= int1; + break; + end; + end; + if result = -1 then begin + result:= length(fsyntaxdefs); + setlength(fsyntaxdefs,result+1); + end; + initsyntaxdef(result); + syntaxdefpo:= @fsyntaxdefs[result]; + with syntaxdefpo^ do begin + keys:= tpointeransistringhashdatalist.create; + scopenames:= tpointeransistringhashdatalist.create; + stylenames:= tpointeransistringhashdatalist.create; + keys.add(tokens); + stylenames.add('',pointer(1)); //default + // fcharstyles.add; //default + global:= true; + linenr:= 0; + flags:= []; + akttoken:= tokennrty(-1); + aktkeywordfontinfonr:= 0; + try + isnextline:= false; + repeat + if isnextline or nextline then begin + isnextline:= false; + nextword(lstr1,lstr2); + int1:= ptrint(keys.find(struppercase(lstr2))); + if int1 <> 0 then begin + akttoken:= tokennrty(int1-1); + if akttoken in (flags - tn_canmultiple) then begin + invalidtoken; + end; + include(flags,akttoken); + if akttoken >= tn_localstart then begin + global:= false; + end; + if global then begin + case akttoken of + tn_caseinsensitive: caseinsensitive:= true; + tn_keywordchars: begin + keywordchars:= []; + end; + tn_keyworddefs: begin + nextword(lstr1,lstr3); + if lstr3.len = 0 then begin + invalidtoken; + end; + setlength(keywordar,length(keywordar)+1); +// keywordar[high(keywordar)]:= thashedmsestrings.create; + keywordar[high(keywordar)]:= tkeywordlist.create; + addname(keywordnames,lstr3,high(keywordar)); + nextword(lstr1,lstr4); + if lstr4.len > 0 then begin + keywordar[high(keywordar)].fdefaultstyle:= + findname(stylenames,lstr4); + end; + end; + tn_colors: begin + if getcolor(lstr1,colors.font) then begin + if getcolor(lstr1,colors.background) then begin + if getcolor(lstr1,colors.statement) then begin + if getcolor(lstr1,colors.pairmarkbackground) then begin + end; + end; + end; + end; + end; + tn_addkeywordchars,tn_styles,tn_pairwords: begin + end; + else begin + invalidtoken; + end; + end; + end + else begin + case akttoken of + tn_scope: begin + nextword(lstr1,lstr2); + nextword(lstr1,lstr3); + int1:= findname(stylenames,lstr3); + updateaktscope; + addname(scopenames,lstr2,addscoperule( + nil,nil,false,false,int1,nil,-1)); + flags:= []; + end; + tn_keywords: begin + if length(scopeinfos) = 0 then begin + noscope; + end; + nextword(lstr1,lstr3); + aktkeywordfontinfonr:= findname(stylenames,lstr3); + end; + tn_return,tn_endtokens,tn_calltokens,tn_jumptokens: begin + if length(scopeinfos) = 0 then begin + noscope; + end + else begin + if akttoken = tn_endtokens then begin + if scopeinfos[aktscopeinfo].return then begin + invalidtoken; + end; + scopeinfos[aktscopeinfo].hasendtokens:= true; + end + else begin + if akttoken = tn_return then begin + if scopeinfos[aktscopeinfo].hasendtokens then begin + invalidtoken; + end; + scopeinfos[aktscopeinfo].return:= true; + end; + end; + end; + end; + else begin + invalidtoken; + end; + end; + end; + end + else begin + lstringgoback(lstr1,lstr2); + case akttoken of + tn_keyworddefs: begin + setlength(wstrar1,0); + repeat + bo1:= nextquotedstring(lstr1,str1); + if caseinsensitive then begin + str1:= struppercase(str1); + end; + if bo1 then begin + setlength(wstrar1,length(wstrar1)+1); + wstrar1[high(wstrar1)]:= msestring(str1); + end; + until not bo1; + nextword(lstr1,lstr3); + int2:= findname(stylenames,lstr3); + for int1:= 0 to high(wstrar1) do begin + keywordar[high(keywordar)].add(wstrar1[int1],pointer(int2+1)); + end; + end; + tn_keywordchars,tn_addkeywordchars: begin + nextquotedstring(lstr1,str1); + nextword(lstr1,lstr3); + if lstr3.len <> 0 then begin + invalidstring; + end; + for int1:= 1 to length(str1) do begin + include(keywordchars,str1[int1]); + end; + end; + tn_styles: begin + nextword(lstr1,lstr2); + addname(stylenames,lstr2,charstyles.count); + try + charstyles.add(lstringtostring(lstr1)); + except + invalidstyle; +// error('Invalid style '''+line+''''+lineinfo); + end; + end; + tn_pairwords: begin + ar2:= nil; + while nextquotedstring(lstr1,str1) do begin +// if caseinsensitive then begin +// str1:= struppercase(str1); +// end; + additem(ar2,msestring(str1)); + end; + if ar2 <> nil then begin + additem(pairwords.upper,ar2); + end + else begin + invalidstring; + end; + end; + tn_calltokens,tn_jumptokens: begin + bo1:= nexttokeninfo(lstr1,str1,tf1); +// bo1:= nextquotedstring(lstr1,str1); + if not bo1 then begin //at least one +// invalidstring; + ar1:= nil; //no token def + end + else begin + setlength(ar1,1); + ar1[0].name:= msestring(str1); + ar1[0].flags:= tf1; + addquotedtokens(ar1,isnextline); + end; + if not isnextline then begin + nextword(lstr1,lstr3); + int1:= findname(scopenames,lstr3); + nextword(lstr1,lstr3); + int2:= findname(stylenames,lstr3); + end + else begin + namenotfound; + end; + int3:= length(scopeinfos[aktscopeinfo].starttokens); + checktokenchars(ar1,caseinsensitive,bo2,tokenchars1); + if bo2 then begin + setlength(scopeinfos[aktscopeinfo].starttokens,int3+1); + with scopeinfos[aktscopeinfo].starttokens[int3] do begin + hastokenchars:= hastokenchars or bo1; + tokenchars:= tokenchars1; + fontinfonr:= int2; + scopenr:= int1; + call:= akttoken = tn_calltokens; + shortcircuit:= not call and (scopenr = aktscopeinfo); + end; + end + else begin + if not bo1 then begin + setlength(ar1,1); //empty tokenname + with scopeinfos[aktscopeinfo] do begin + if defaulttarget < 0 then begin //first + defaulttarget:= int3; + end; + end; + end; + i5:= high(ar1); + setlength(scopeinfos[aktscopeinfo].starttokens,int3+i5+1); + for int4:= int3 to int3 + i5 do begin + with scopeinfos[aktscopeinfo].starttokens[int4] do begin + token:= ar1[int4-int3]; + if caseinsensitive then begin + token.name:= struppercase(token.name); + end; + fontinfonr:= int2; + scopenr:= int1; + call:= akttoken = tn_calltokens; + shortcircuit:= not call and (scopenr = aktscopeinfo); + end; + end; + end; + end; + tn_endtokens: begin + with scopeinfos[aktscopeinfo] do begin + ar1:= nil; + addquotedtokens(ar1,isnextline); + int3:= length(endtokens); + if not isnextline then begin + nextword(lstr1,lstr3); + int2:= findname(stylenames,lstr3); + end + else begin + int2:= fontinfonr; + end; + checktokenchars(ar1,caseinsensitive,bo1,tokenchars1); + if bo1 then begin + setlength(endtokens,int3+1); + with endtokens[high(endtokens)] do begin + hastokenchars:= true; + tokenchars:= tokenchars1; + fontinfonr:= int2; + end; + end + else begin + setlength(scopeinfos[aktscopeinfo].endtokens,int3+length(ar1)); + for int4:= int3 to int3 + high(ar1) do begin + with scopeinfos[aktscopeinfo].endtokens[int4] do begin + token:= ar1[int4-int3]; + if caseinsensitive then begin + token.name:= struppercase(token.name); + end; + fontinfonr:= int2; + end; + end; + end; + end; + end; + tn_keywords: begin + nextword(lstr1,lstr3); + if lstr3.len > 0 then begin + int1:= findname(keywordnames,lstr3); + int2:= aktkeywordfontinfonr; + if int2 < 0 then begin + int2:= keywordar[int1].fdefaultstyle; + end; + nextword(lstr1,lstr4); + if lstr4.len > 0 then begin + int2:= findname(stylenames,lstr4); + end; + addkeywordrule(int1,int2); + end; + end; + else begin + invalidtoken; + end; + end; + end; + end; + until stream.eof and not (isnextline and (lstr1.len > 0)); + updateaktscope; + finally + keys.free; + scopenames.free; + stylenames.Free; + end; + with pairwords do begin + setlength(lower,length(upper)); + if caseinsensitive then begin + for int1:= 0 to high(upper) do begin + setlength(lower[int1],length(upper[int1])); + for int2:= 0 to high(upper[int1]) do begin + upper[int1,int2]:= mseuppercase(upper[int1,int2]); + lower[int1,int2]:= mselowercase(upper[int1,int2]); + end; + end; + end + else begin + for int1:= 0 to high(upper) do begin + setlength(lower[int1],length(upper[int1])); + for int2:= 0 to high(upper[int1]) do begin + lower[int1,int2]:= upper[int1,int2]; //copy original + end; + end; + end; + end; + end; + syntaxchanged(); +end; + +function tsyntaxpainter.readdeffile(const afilename: filenamety): integer; +var + stream1: ttextstream; +begin + stream1:= ttextstream.create(afilename,fm_read); + try + result:= readdeffile(stream1); + finally + stream1.free; + end; +end; + +procedure tsyntaxpainter.freedeffile(handle: integer); +begin + checkarrayindex(fsyntaxdefs,handle); + clearsyntaxdef(handle); +end; + +function tsyntaxpainter.readdeffile(const atext: string): integer; +var + stream1: ttextstream; +begin + stream1:= ttextstream.create; + try + stream1.writedatastring(atext); + stream1.position:= 0; + result:= readdeffile(stream1); + finally + stream1.free; + end; +end; + +procedure tsyntaxpainter.syntaxchanged; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + with fclients[int1] do begin + if assigned(onlinechanged) then begin + onlinechanged(self,-1); + end; + end; + end; +end; +{ +procedure tsyntaxpainter.invalidatesyntax(handle, start,count: integer); +var + int1,end1,end2: integer; + refreshinfo: refreshinfoty; +begin + for int1:= 0 to frefreshlist.count - 1 do begin + if frefreshlist[int1].handle = handle then begin + refreshinfo:= frefreshlist[int1]; + if (refreshinfo.astart <= start) then begin + if refreshinfo.count = maxint then begin + exit; //schon in arbeit + end; + end1:= refreshinfo.astart + refreshinfo.count; + if end1 >= start then begin //kann erweitert werden + if count = maxint then begin + refreshinfo.count:= maxint; + frefreshlist[int1]:= refreshinfo; + exit; + end; + end2:= start + count; + if end2 > end1 then begin + refreshinfo.count:= refreshinfo.count + end2-end1; + frefreshlist[int1]:= refreshinfo; + exit; + end; + end; + end; + end; + end; + paintsyntax(handle,start,count,true); +end; +} +procedure tsyntaxpainter.setdefdefs(const Value: tdoublemsestringdatalist); +begin + fdefdefs.assign(Value); +end; + +function tsyntaxpainter.linkdeffile(const sourcefilename: filenamety): integer; +var + int1,int2: integer; + strar1: msestringarty; + stream: ttextstream; + str1: filenamety; + +begin + result:= -1; + for int1:= 0 to fdefdefs.count - 1 do begin + strar1:= nil; + splitstringquoted(defdefs[int1].a,strar1); + for int2:= 0 to high(strar1) do begin + if checkfilename(sourcefilename,strar1[int2],true) then begin + result:= int1; + break; + end; + end; + if result >= 0 then begin + break; + end; + end; + if result >= 0 then begin + int2:= result; + result:= -1; + for int1:= 0 to high(fsyntaxdefs) do begin + with fsyntaxdefs[int1] do begin + if (charstyles <> nil) and (defdefsnr = int2) then begin + result:= int1; + break; + end; + end; + end; + if result < 0 then begin + str1:= fdefdefs[int2].b; + str1:= filepath(fdefsdir,str1); + stream:= ttextstream.create(str1,fm_read); + try + try + result:= readdeffile(stream); + except + on e: exception do begin + e.message:= ansistring( + 'tsyntaxpaintermse: file ''' +str1 + ''' ' +msestring(e.message)); + raise; + end; + end; + fsyntaxdefs[result].defdefsnr:= int2; + finally + stream.Free; + end; + end; + end; +end; + +procedure tsyntaxpainter.setdeftext(const avalue: tmsestringdatalist); +begin + fdeftext.assign(avalue); +end; + +procedure tsyntaxpainter.deflistchanged(const sender: tobject); +var + stream1: ttextstream; +begin + if not (csdesigning in componentstate) then begin + if fdefaultsyntax <> - 1 then begin + freedeffile(fdefaultsyntax); + end; + stream1:= fdeftext.dataastextstream; + try + fdefaultsyntax:= readdeffile(stream1); + finally + stream1.destroy(); + end; + end; +end; + +function tsyntaxpainter.getboldchars(index: integer): markinfoty; +begin + checkarrayindex(fclients,index); + result:= fclients[index].boldchars; +end; + +procedure tsyntaxpainter.setboldchars(index: integer; const avalue: markinfoty); +begin + checkarrayindex(fclients,index); + fclients[index].boldchars:= avalue; +end; + +function tsyntaxpainter.getcolors(index: integer): syntaxcolorinfoty; +begin + checkarrayindex(fclients,index); + result:= fsyntaxdefs[fclients[index].syntaxdefhandle].colors; +end; + +function tsyntaxpainter.getpairwords(index: int32): pairwordsty; +begin + checkarrayindex(fclients,index); + result:= fsyntaxdefs[fclients[index].syntaxdefhandle].pairwords; +end; + +function tsyntaxpainter.getcaseinsensitive(index: int32): boolean; +begin + checkarrayindex(fclients,index); + result:= fsyntaxdefs[fclients[index].syntaxdefhandle].caseinsensitive; +end; + +{ tkeywordlist } + +constructor tkeywordlist.create; +begin + fdefaultstyle:= -1; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.mfm b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.mfm new file mode 100644 index 0000000..0e42915 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.mfm @@ -0,0 +1,538 @@ +object msesysenvmanagereditorfo: tmsesysenvmanagereditorfo + visible = False + bounds_x = 57 + bounds_y = 574 + bounds_cx = 861 + bounds_cy = 229 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 861 + 229 + ) + options = [fo_freeonclose, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = statfile1 + caption = 'Edit tsysenvmanager' + windowopacity = -Inf + moduleclassname = 'tmseform' + object la2: tlayouter + bounds_x = 0 + bounds_y = 200 + bounds_cx = 861 + bounds_cy = 0 + anchors = [an_top] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + dist_top = 4 + end + object tlayouter2: tlayouter + taborder = 1 + bounds_x = 747 + bounds_y = 200 + bounds_cx = 107 + bounds_cy = 21 + anchors = [an_right, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex] + place_mindist = 5 + place_maxdist = 5 + dist_top = 3 + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 0 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 55 + bounds_y = 1 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 861 + bounds_cy = 194 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 16 + captions.items = < + item + caption = 'Kind' + end + item + caption = 'Name' + end + item + caption = 'Alias' + end + item + caption = 'MA' + hint = 'arf_mandatory' + end + item + caption = 'AO' + hint = 'arf_argopt' + end + item + caption = 'FN' + hint = 'arf_filenames' + end + item + caption = 'SO' + hint = 'arf_statoverride' + end + item + caption = 'SA' + hint = 'arf_statadval' + end + item + caption = 'UQ' + hint = 'arf_unquote' + end + item + caption = 'IN' + hint = 'arf_integer' + end + item + caption = 'HE' + hint = 'arf_help' + end + item + caption = 'Initvalue' + end + item + caption = 'Argument' + end + item + caption = 'Help' + end + item + caption = 'Before' + end + item + caption = 'After' + end> + end> + datacols.count = 16 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[kinded] + width = 72 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'kinded' + dataclass = tgridenumdatalist + end + item[nameed] + width = 68 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'nameed' + dataclass = tgridmsestringdatalist + end + item[aliased] + width = 117 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aliased' + dataclass = tgridmsestringdatalist + end + item[mandatory] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'mandatory' + dataclass = tgridintegerdatalist + end + item[argopt] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'argopt' + dataclass = tgridintegerdatalist + end + item[filenames] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'filenames' + dataclass = tgridintegerdatalist + end + item[statoverride] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'statoverride' + dataclass = tgridintegerdatalist + end + item[stataddval] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'stataddval' + dataclass = tgridintegerdatalist + end + item[unquote] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'unquote' + dataclass = tgridintegerdatalist + end + item[integer] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'integer' + dataclass = tgridintegerdatalist + end + item[help] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'help' + dataclass = tgridintegerdatalist + end + item[initvalueed] + width = 121 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'initvalueed' + dataclass = tgridmsestringdatalist + end + item[argumented] + width = 72 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'argumented' + dataclass = tgridmsestringdatalist + end + item[helped] + width = 102 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'helped' + dataclass = tgridmsestringdatalist + end + item[beforeed] + width = 73 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'beforeed' + dataclass = tgridmsestringdatalist + end + item[aftered] + width = 73 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftered' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object kinded: tenumtypeedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + end> + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 72 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = kindedinit + reffontheight = 14 + end + object nameed: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 73 + bounds_y = 0 + bounds_cx = 68 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object aliased: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 3 + visible = False + bounds_x = 142 + bounds_y = 0 + bounds_cx = 117 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object mandatory: tbooleanedit + Tag = 7 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 260 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object argopt: tbooleanedit + Tag = 8 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 278 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object filenames: tbooleanedit + Tag = 9 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 296 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object statoverride: tbooleanedit + Tag = 10 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 7 + bounds_x = 314 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object stataddval: tbooleanedit + Tag = 11 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 8 + bounds_x = 332 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object unquote: tbooleanedit + Tag = 12 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 9 + bounds_x = 350 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object integer: tbooleanedit + Tag = 13 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 10 + bounds_x = 368 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object help: tbooleanedit + Tag = 14 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 11 + bounds_x = 386 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object initvalueed: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 12 + visible = False + bounds_x = 404 + bounds_y = 0 + bounds_cx = 121 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object argumented: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 13 + visible = False + bounds_x = 526 + bounds_y = 0 + bounds_cx = 72 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object helped: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 14 + visible = False + bounds_x = 599 + bounds_y = 0 + bounds_cx = 102 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object beforeed: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 15 + visible = False + bounds_x = 702 + bounds_y = 0 + bounds_cx = 73 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object aftered: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 16 + visible = False + bounds_x = 776 + bounds_y = 0 + bounds_cx = 73 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + end + object statfile1: tstatfile + filename = 'sysenvmanagereditor.sta' + options = [sfo_memory] + left = 192 + top = 72 + end +end diff --git a/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.pas b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.pas new file mode 100644 index 0000000..f9c1ce7 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.pas @@ -0,0 +1,146 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesysenvmanagereditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msesysenv,msesplitter, + msesimplewidgets,msewidgets,msegraphedits,mseifiglob,msetypes,msedataedits, + mseedit,msegrids,msestrings,msewidgetgrid,msememodialog,msestatfile,mseificomp, + mseificompglob,msescrollbar; + +const + sysenvmanagereditorstatname = 'sysenvmanagereditor.sta'; + +type + tmsesysenvmanagereditorfo = class(tmseform) + la2: tlayouter; + tlayouter2: tlayouter; + ok: tbutton; + cancel: tbutton; + grid: twidgetgrid; + kinded: tenumtypeedit; + nameed: tstringedit; + aliased: tmemodialogedit; + argopt: tbooleanedit; + filenames: tbooleanedit; + statoverride: tbooleanedit; + stataddval: tbooleanedit; + integer: tbooleanedit; + initvalueed: tmemodialogedit; + statfile1: tstatfile; + mandatory: tbooleanedit; + helped: tmemodialogedit; + help: tbooleanedit; + argumented: tstringedit; + beforeed: tmemodialogedit; + aftered: tmemodialogedit; + unquote: tbooleanedit; + procedure kindedinit(const sender: tenumtypeedit); + end; + +function editsysenvmanager(asysenvmanager: tsysenvmanager): modalresultty; + +implementation +uses + msesysenvmanagereditor_mfm,typinfo; + +function editsysenvmanager(asysenvmanager: tsysenvmanager): modalresultty; +var + ar1: sysenvdefarty; + int1: integer; +begin + ar1:= asysenvmanager.defs; + with tmsesysenvmanagereditorfo.create(nil) do begin + grid.rowcount:= length(ar1); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + kinded[int1]:= ord(kind); + nameed[int1]:= name; + aliased[int1]:= concatstrings(anames,' ','"'); + mandatory.gridvaluebitmask[int1]:= longword(flags); + initvalueed[int1]:= initvalue; + argumented[int1]:= argument; + helped[int1]:= help; + beforeed[int1]:= before; + aftered[int1]:= after; + end; + end; + result:= show(ml_application); + if result = mr_ok then begin + ar1:= nil; //init with zero + setlength(ar1,grid.datarowhigh+1); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + kind:= argumentkindty(kinded[int1]); + name:= nameed[int1]; + splitstringquoted(aliased[int1],anames); + flags:= argumentflagsty(mandatory.gridvaluebitmask[int1]); + initvalue:= initvalueed[int1]; + argument:= argumented[int1]; + help:= helped[int1]; + before:= beforeed[int1]; + after:= aftered[int1]; + end; + end; + asysenvmanager.defs:= ar1; + end; + end; +end; + +{ +function editsysenvmanager(asysenvmanager: tsysenvmanager): modalresultty; +var + ar1: argumentdefarty; + ar2: stringararty; + int1: integer; + ar3,ar4: stringarty; +begin + try + defstoarguments(asysenvmanager.defs,ar1,ar2); + except + application.handleexception; + end; + with tmsesysenvmanagereditorfo.create(nil) do begin + grid.rowcount:= length(ar1); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + kinded[int1]:= ord(kind); + nameed[int1]:= name; + aliased[int1]:= concatstrings(ar2[int1]); + envdefined.gridvaluebitmask[int1]:= longword(flags); + initvalueed[int1]:= initvalue; + end; + end; + result:= show(ml_application); + if result = mr_ok then begin + setlength(ar4,5); + setlength(ar3,grid.datarowhigh+1); + for int1:= 0 to high(ar3) do begin + ar4[0]:= getenumname(typeinfo(argumentkindty),kinded[int1]); + ar4[1]:= nameed[int1]; + ar4[2]:= aliased[int1]; + ar4[3]:= settostring(ptypeinfo(typeinfo(argumentflagsty)), + envdefined.gridvaluebitmask[int1],false); + ar4[4]:= initvalueed[int1]; + ar3[int1]:= concatstrings(ar4,',','"'); + end; + asysenvmanager.defs:= string(concatstrings(ar3,lineend)); + end; + end; +end; +} +procedure tmsesysenvmanagereditorfo.kindedinit(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(argumentkindty); +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msesysenvmanagereditor_mfm.pas b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor_mfm.pas new file mode 100644 index 0000000..80e760b --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor_mfm.pas @@ -0,0 +1,659 @@ +unit msesysenvmanagereditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msesysenvmanagereditor; + +const + objdata: record size: integer; data: array[0..12827] of byte end = + (size: 12828; data: ( + 84,80,70,48,25,116,109,115,101,115,121,115,101,110,118,109,97,110,97,103, + 101,114,101,100,105,116,111,114,102,111,24,109,115,101,115,121,115,101,110,118, + 109,97,110,97,103,101,114,101,100,105,116,111,114,102,111,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,57,8,98,111,117,110, + 100,115,95,121,3,62,2,9,98,111,117,110,100,115,95,99,120,3,93,3, + 9,98,111,117,110,100,115,95,99,121,3,229,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110, + 101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,93,3,3,229,0, + 0,7,111,112,116,105,111,110,115,11,14,102,111,95,102,114,101,101,111,110, + 99,108,111,115,101,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15, + 102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97, + 117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101, + 112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111, + 95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101, + 7,9,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6, + 19,69,100,105,116,32,116,115,121,115,101,110,118,109,97,110,97,103,101,114, + 13,119,105,110,100,111,119,111,112,97,99,105,116,121,5,0,0,0,0,0, + 0,0,128,255,255,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,9,116,108,97,121,111,117,116, + 101,114,3,108,97,50,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,3,200,0,9,98,111,117,110,100,115,95,99,120,3, + 93,3,9,98,111,117,110,100,115,95,99,121,2,0,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,0,12,111,112,116,105,111,110,115,115, + 99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115, + 99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100, + 121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111, + 110,115,108,97,121,111,117,116,11,10,108,97,111,95,97,108,105,103,110,121, + 0,8,100,105,115,116,95,116,111,112,2,4,0,0,9,116,108,97,121,111, + 117,116,101,114,10,116,108,97,121,111,117,116,101,114,50,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,235,2,8,98, + 111,117,110,100,115,95,121,3,200,0,9,98,111,117,110,100,115,95,99,120, + 2,107,9,98,111,117,110,100,115,95,99,121,2,21,7,97,110,99,104,111, + 114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107, + 120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104, + 114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116, + 11,10,108,97,111,95,112,108,97,99,101,120,0,13,112,108,97,99,101,95, + 109,105,110,100,105,115,116,2,5,13,112,108,97,99,101,95,109,97,120,100, + 105,115,116,2,5,8,100,105,115,116,95,116,111,112,2,3,0,7,116,98, + 117,116,116,111,110,2,111,107,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101, + 105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111, + 119,49,95,97,117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,12, + 98,111,117,110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101, + 11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109, + 111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116, + 116,111,110,6,99,97,110,99,101,108,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101, + 13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,55,8,98,111, + 117,110,100,115,95,121,2,1,9,98,111,117,110,100,115,95,99,120,2,52, + 9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117,110,100,115,95, + 99,120,109,105,110,2,50,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 7,38,67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116, + 7,9,109,114,95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,11,116,119,105,100,103,101,116,103,114, + 105,100,4,103,114,105,100,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,93,3,9,98,111,117,110,100,115,95, + 99,121,3,194,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111, + 112,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115, + 103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12,111, + 103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114,111, + 119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116, + 105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19,111, + 103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15,111, + 103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97,117, + 116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104,97,110,103, + 101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108, + 12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109,111,117, + 115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111,108,115, + 46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101, + 109,115,14,1,5,119,105,100,116,104,2,24,7,110,117,109,115,116,101,112, + 2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1, + 13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105, + 103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116, + 2,16,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7, + 99,97,112,116,105,111,110,6,4,75,105,110,100,0,1,7,99,97,112,116, + 105,111,110,6,4,78,97,109,101,0,1,7,99,97,112,116,105,111,110,6, + 5,65,108,105,97,115,0,1,7,99,97,112,116,105,111,110,6,2,77,65, + 4,104,105,110,116,6,13,97,114,102,95,109,97,110,100,97,116,111,114,121, + 0,1,7,99,97,112,116,105,111,110,6,2,65,79,4,104,105,110,116,6, + 10,97,114,102,95,97,114,103,111,112,116,0,1,7,99,97,112,116,105,111, + 110,6,2,70,78,4,104,105,110,116,6,13,97,114,102,95,102,105,108,101, + 110,97,109,101,115,0,1,7,99,97,112,116,105,111,110,6,2,83,79,4, + 104,105,110,116,6,16,97,114,102,95,115,116,97,116,111,118,101,114,114,105, + 100,101,0,1,7,99,97,112,116,105,111,110,6,2,83,65,4,104,105,110, + 116,6,13,97,114,102,95,115,116,97,116,97,100,118,97,108,0,1,7,99, + 97,112,116,105,111,110,6,2,85,81,4,104,105,110,116,6,11,97,114,102, + 95,117,110,113,117,111,116,101,0,1,7,99,97,112,116,105,111,110,6,2, + 73,78,4,104,105,110,116,6,11,97,114,102,95,105,110,116,101,103,101,114, + 0,1,7,99,97,112,116,105,111,110,6,2,72,69,4,104,105,110,116,6, + 8,97,114,102,95,104,101,108,112,0,1,7,99,97,112,116,105,111,110,6, + 9,73,110,105,116,118,97,108,117,101,0,1,7,99,97,112,116,105,111,110, + 6,8,65,114,103,117,109,101,110,116,0,1,7,99,97,112,116,105,111,110, + 6,4,72,101,108,112,0,1,7,99,97,112,116,105,111,110,6,6,66,101, + 102,111,114,101,0,1,7,99,97,112,116,105,111,110,6,5,65,102,116,101, + 114,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116, + 2,16,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111, + 114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,6, + 107,105,110,100,101,100,1,5,119,105,100,116,104,2,72,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99, + 97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,6,107, + 105,110,100,101,100,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114, + 105,100,101,110,117,109,100,97,116,97,108,105,115,116,0,7,6,110,97,109, + 101,101,100,1,5,119,105,100,116,104,2,68,7,111,112,116,105,111,110,115, + 11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,6,110,97,109,101, + 101,100,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,7,97, + 108,105,97,115,101,100,1,5,119,105,100,116,104,2,117,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99, + 97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,97, + 108,105,97,115,101,100,9,100,97,116,97,99,108,97,115,115,7,22,116,103, + 114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116, + 0,7,9,109,97,110,100,97,116,111,114,121,1,5,119,105,100,116,104,2, + 17,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105, + 120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,10,119,105,100,103,101,116,110,97,109,101,6,9,109,97,110,100,97,116, + 111,114,121,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,6,97,114, + 103,111,112,116,1,5,119,105,100,116,104,2,17,7,111,112,116,105,111,110, + 115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116, + 110,97,109,101,6,6,97,114,103,111,112,116,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,9,102,105,108,101,110,97,109,101,115,1,5,119,105, + 100,116,104,2,17,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114, + 97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99, + 111,95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,9,102,105, + 108,101,110,97,109,101,115,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 7,12,115,116,97,116,111,118,101,114,114,105,100,101,1,5,119,105,100,116, + 104,2,17,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95, + 102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,12,115,116,97,116, + 111,118,101,114,114,105,100,101,9,100,97,116,97,99,108,97,115,115,7,20, + 116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116, + 0,7,10,115,116,97,116,97,100,100,118,97,108,1,5,119,105,100,116,104, + 2,17,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102, + 111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102, + 105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,115,116,97,116,97, + 100,100,118,97,108,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7, + 117,110,113,117,111,116,101,1,5,119,105,100,116,104,2,17,7,111,112,116, + 105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116, + 104,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,7,117,110,113,117,111,116,101,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,7,105,110,116,101,103,101,114,1,5,119,105,100,116, + 104,2,17,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95, + 102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,105,110,116,101, + 103,101,114,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,4,104,101, + 108,112,1,5,119,105,100,116,104,2,17,7,111,112,116,105,111,110,115,11, + 12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,4,104,101,108,112,9,100,97,116,97,99,108,97,115,115,7,20, + 116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116, + 0,7,11,105,110,105,116,118,97,108,117,101,101,100,1,5,119,105,100,116, + 104,2,121,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,11,105,110,105,116,118,97,108,117,101, + 101,100,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,97, + 114,103,117,109,101,110,116,101,100,1,5,119,105,100,116,104,2,72,7,111, + 112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99, + 111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101, + 6,10,97,114,103,117,109,101,110,116,101,100,9,100,97,116,97,99,108,97, + 115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97, + 116,97,108,105,115,116,0,7,6,104,101,108,112,101,100,1,5,119,105,100, + 116,104,2,102,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103, + 101,116,110,97,109,101,6,6,104,101,108,112,101,100,9,100,97,116,97,99, + 108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,7,8,98,101,102,111,114,101,101,100,1, + 5,119,105,100,116,104,2,73,7,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111, + 95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10, + 119,105,100,103,101,116,110,97,109,101,6,8,98,101,102,111,114,101,101,100, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,7,97,102,116, + 101,114,101,100,1,5,119,105,100,116,104,2,73,7,111,112,116,105,111,110, + 115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111, + 112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97, + 116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,97,102,116, + 101,114,101,100,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105, + 100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0, + 13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97, + 116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,13,116,101,110,117,109,116, + 121,112,101,101,100,105,116,6,107,105,110,100,101,100,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95, + 108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108, + 111,114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0, + 0,144,0,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,72,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100, + 111,110,108,121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99, + 111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115, + 46,105,116,101,109,115,14,1,0,0,6,111,110,105,110,105,116,7,10,107, + 105,110,100,101,100,105,110,105,116,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,6, + 110,97,109,101,101,100,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,2,73,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,68,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111, + 99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,15,116,109,101,109, + 111,100,105,97,108,111,103,101,100,105,116,7,97,108,105,97,115,101,100,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114, + 108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0,144, + 7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8, + 116,97,98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,3,142,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,117,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111,101, + 95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121, + 18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,9,109,97,110,100,97,116,111,114, + 121,3,84,97,103,2,7,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,4, + 1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,17,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101, + 49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97, + 116,114,101,97,100,0,7,118,105,115,105,98,108,101,8,5,103,114,111,117, + 112,2,1,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,97, + 114,103,111,112,116,3,84,97,103,2,8,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115, + 95,120,3,22,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,17,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97, + 117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121, + 101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116, + 101,27,111,101,49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101, + 114,115,116,97,116,114,101,97,100,0,7,118,105,115,105,98,108,101,8,5, + 103,114,111,117,112,2,1,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,9,102,105,108,101,110,97,109,101,115,3,84,97,103,2,9,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,6, + 8,98,111,117,110,100,115,95,120,3,40,1,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,17,9,98,111,117,110, + 100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14, + 111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115, + 97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118,97, + 108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,7,118,105, + 115,105,98,108,101,8,5,103,114,111,117,112,2,1,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,12,115,116,97,116,111,118,101,114,114,105, + 100,101,3,84,97,103,2,10,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120,3, + 58,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,17,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111, + 101,49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116, + 97,116,114,101,97,100,0,7,118,105,115,105,98,108,101,8,5,103,114,111, + 117,112,2,1,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,10, + 115,116,97,116,97,100,100,118,97,108,3,84,97,103,2,11,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,8,8,98, + 111,117,110,100,115,95,120,3,76,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,17,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118,97,108,117, + 101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,7,118,105,115,105, + 98,108,101,8,5,103,114,111,117,112,2,1,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,7,117,110,113,117,111,116,101,3,84,97,103,2, + 12,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,9,8,98,111,117,110,100,115,95,120,3,94,1,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,17,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101, + 110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99, + 107,118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0, + 7,118,105,115,105,98,108,101,8,5,103,114,111,117,112,2,1,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,7,105,110,116,101,103,101,114, + 3,84,97,103,2,13,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,10,8,98,111,117,110,100,115,95,120,3,112,1, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,17,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101,49, + 95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97,116, + 114,101,97,100,0,7,118,105,115,105,98,108,101,8,5,103,114,111,117,112, + 2,1,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,4,104,101, + 108,112,3,84,97,103,2,14,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,11,8,98,111,117,110,100,115,95,120,3, + 130,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,17,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111, + 101,49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116, + 97,116,114,101,97,100,0,7,118,105,115,105,98,108,101,8,5,103,114,111, + 117,112,2,1,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100, + 105,116,11,105,110,105,116,118,97,108,117,101,101,100,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3, + 0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118, + 101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116, + 2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101, + 109,115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103, + 101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110, + 46,99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117, + 116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114, + 100,101,114,2,12,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,148,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,121,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105, + 102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117, + 115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110, + 103,101,100,105,116,10,97,114,103,117,109,101,110,116,101,100,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,13,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,14,2,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,72,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110, + 114,101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108,105,112, + 112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100, + 105,116,6,104,101,108,112,101,100,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5, + 99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2,17, + 0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,14, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,87, + 2,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,102,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116, + 117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100, + 111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116, + 111,110,114,101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108, + 105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103, + 101,100,105,116,8,98,101,102,111,114,101,101,100,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0, + 0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101, + 108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101, + 110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116, + 116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100, + 101,114,2,15,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,3,190,2,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,73,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102, + 116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115, + 114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101,95,104,105, + 110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,15,116,109,101,109,111,100,105, + 97,108,111,103,101,100,105,116,7,97,102,116,101,114,101,100,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108, + 101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117, + 110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105, + 116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109, + 97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116, + 111,110,46,99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46, + 98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98, + 111,114,100,101,114,2,16,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,3,8,3,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,73,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111, + 99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,116, + 97,116,102,105,108,101,9,115,116,97,116,102,105,108,101,49,8,102,105,108, + 101,110,97,109,101,6,23,115,121,115,101,110,118,109,97,110,97,103,101,114, + 101,100,105,116,111,114,46,115,116,97,7,111,112,116,105,111,110,115,11,10, + 115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116,3,192,0,3, + 116,111,112,2,72,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsesysenvmanagereditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.mfm b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.mfm new file mode 100644 index 0000000..296184b --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.mfm @@ -0,0 +1,194 @@ +object msetaborderoverrideeditorfo: tmsetaborderoverrideeditorfo + visible = False + bounds_x = 337 + bounds_y = 266 + bounds_cx = 332 + bounds_cy = 245 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 332 + 245 + ) + options = [fo_freeonclose, fo_cancelonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Taborder override' + moduleclassname = 'tmseform' + object tsplitter1: tsplitter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + bounds_x = 208 + bounds_y = 208 + bounds_cx = 123 + bounds_cy = 30 + anchors = [an_right, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = texpandingwidget1 + grip = stb_none + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 58 + bounds_y = 8 + bounds_cx = 52 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 0 + bounds_y = 8 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object tspacer2: tspacer + taborder = 2 + bounds_x = 50 + bounds_y = 8 + bounds_cx = 8 + bounds_cy = 20 + linkleft = tbutton1 + linkright = tbutton2 + options = [spao_glueright] + end + end + object texpandingwidget1: texpandingwidget + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 332 + bounds_cy = 208 + anchors = [an_top] + optionsscale = [osc_expandy, osc_expandshrinkx, osc_expandshrinky] + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 332 + bounds_cy = 208 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 27 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'a' + end + item + caption = 'b' + end> + end> + datacols.count = 2 + datacols.options = [co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[aed] + width = 144 + options = [co_proportional, co_savestate, co_mousescrollrow] + widgetname = 'aed' + dataclass = tgridmsestringdatalist + end + item[bed] + width = 154 + options = [co_fill, co_savestate, co_mousescrollrow] + widgetname = 'bed' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = tstatfile1 + reffontheight = 14 + object aed: tdropdownlistedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + imagenr = 17 + onexecute = dialogexev + end> + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 144 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_cliphint] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object bed: tdropdownlistedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + imagenr = 17 + onexecute = dialogexev + end> + taborder = 2 + visible = False + bounds_x = 145 + bounds_y = 0 + bounds_cx = 154 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_cliphint] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + end + end + object tstatfile1: tstatfile + filename = 'taborderoverrideeditor.sta' + options = [sfo_memory] + left = 16 + top = 216 + end +end diff --git a/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.pas b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.pas new file mode 100644 index 0000000..9ee9279 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.pas @@ -0,0 +1,171 @@ +unit msetaborderoverrideeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msestatfile, + msesplitter,msesimplewidgets,mseact,msedataedits,msedropdownlist,mseedit, + msegrids,mseificomp,mseificompglob,mseifiglob,msestream,msewidgetgrid,sysutils, + classes,mclasses,msestrings; +type + tmsetaborderoverrideeditorfo = class(tmseform) + tstatfile1: tstatfile; + tsplitter1: tsplitter; + tbutton2: tbutton; + tbutton1: tbutton; + tspacer2: tspacer; + texpandingwidget1: texpandingwidget; + grid: twidgetgrid; + aed: tdropdownlistedit; + bed: tdropdownlistedit; + procedure dialogexev(const sender: TObject); + private + frootcomp: tcomponent; + ftopwidget: twidget; + function filterwidgets(const acomponent: tcomponent): boolean; + public + constructor create(const atopwidget: twidget); reintroduce; + function findcomp(const aname: msestring): twidget; + function findwidgetcomp(const aname: msestring): twidget; + function widgetnamepath(awidget: twidget): string; + function compnamepath(acomp: tcomponent): string; + end; + +implementation +uses + msetaborderoverrideeditor_mfm,msedesigner,msecomptree; + +constructor tmsetaborderoverrideeditorfo.create( + const atopwidget: twidget); +var + ar1: msestringarty; +begin + inherited create(nil); + ftopwidget:= atopwidget; + if csinline in atopwidget.componentstate then begin + frootcomp:= atopwidget; + end + else begin + frootcomp:= atopwidget.owner; + if frootcomp = nil then begin + frootcomp:= atopwidget; + end; + end; + ar1:= designer.getwidgetnamelist(nil,ftopwidget,@filterwidgets); + aed.dropdown.cols[0].asarray:= ar1; + bed.dropdown.cols[0].asarray:= ar1; +end; + +function tmsetaborderoverrideeditorfo.findcomp(const aname: msestring): twidget; +var + str1: ansistring; + ar1: stringarty; + i1: int32; + comp1: tcomponent; + w1: twidget; +begin + str1:= ansistring(aname); + ar1:= splitstring(str1,'.'); + comp1:= frootcomp; + w1:= nil; + for i1:= 0 to high(ar1) do begin + w1:= twidget(comp1.findcomponent(ar1[i1])); + if not (w1 is twidget) then begin + w1:= nil; + break; + end; + comp1:= w1; + end; + result:= w1; +end; + +function tmsetaborderoverrideeditorfo.findwidgetcomp( + const aname: msestring): twidget; +var + str1: ansistring; + ar1: stringarty; + i1: int32; + comp1: tcomponent; + w1: twidget; +begin + str1:= ansistring(aname); + ar1:= splitstring(str1,'.'); + comp1:= frootcomp; + w1:= nil; + for i1:= 0 to high(ar1) do begin + w1:= twidget(comp1.findcomponent(ar1[i1])); + if not (w1 is twidget) then begin + w1:= nil; + break; + end; + if csinline in w1.componentstate then begin + comp1:= w1; + end; + end; + result:= w1; +end; + +function tmsetaborderoverrideeditorfo.widgetnamepath(awidget: twidget): string; +begin + result:= ''; + if awidget <> nil then begin + result:= awidget.name; + awidget:= awidget.parentwidget; + while (awidget <> nil) and (awidget <> ftopwidget) do begin + if ws_iswidget in awidget.widgetstate then begin + result:= awidget.name+'.'+result; + end; + awidget:= awidget.parentwidget; + end; + end; +end; + +function tmsetaborderoverrideeditorfo.compnamepath(acomp: tcomponent): string; +begin + result:= ''; + if acomp <> nil then begin + result:= acomp.name; + acomp:= acomp.owner; + while (acomp <> nil) and (acomp <> frootcomp) do begin + result:= acomp.name+'.'+result; + acomp:= acomp.owner; + end; + end; +end; + +function tmsetaborderoverrideeditorfo.filterwidgets( + const acomponent: tcomponent): boolean; +begin + result:= ws_iswidget in twidget(acomponent).widgetstate; +end; + +procedure tmsetaborderoverrideeditorfo.dialogexev(const sender: TObject); +var + w1: tdropdownlistedit; + w2: twidget; + tree1: tcompnameitem; + mstr1: msestring; +begin +// if ftopcomponent is twidget then begin + tree1:= designer.getwidgetnametree(ftopwidget); + w1:= tdropdownlistedit(tcustomframe( + tframebutton(sender).owner).intf.getwidget); + w2:= findcomp(w1.value); + if w2 <> nil then begin + mstr1:= msestring(widgetnamepath(w2)); + end + else begin + mstr1:= w1.value; + end; + if compnamedialog(tree1,mstr1,false) = mr_ok then begin + replacechar1(mstr1,':','.'); + w2:= findwidgetcomp(mstr1); + if w2 <> nil then begin + mstr1:= msestring(compnamepath(w2)); + end; + w1.value:= mstr1; + end; +// end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor_mfm.pas b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor_mfm.pas new file mode 100644 index 0000000..27bfc8c --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor_mfm.pas @@ -0,0 +1,229 @@ +unit msetaborderoverrideeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msetaborderoverrideeditor; + +const + objdata: record size: integer; data: array[0..4238] of byte end = + (size: 4239; data: ( + 84,80,70,48,28,116,109,115,101,116,97,98,111,114,100,101,114,111,118,101, + 114,114,105,100,101,101,100,105,116,111,114,102,111,27,109,115,101,116,97,98, + 111,114,100,101,114,111,118,101,114,114,105,100,101,101,100,105,116,111,114,102, + 111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3, + 81,1,8,98,111,117,110,100,115,95,121,3,10,1,9,98,111,117,110,100, + 115,95,99,120,3,76,1,9,98,111,117,110,100,115,95,99,121,3,245,0, + 26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2, + 0,3,76,1,3,245,0,0,7,111,112,116,105,111,110,115,11,14,102,111, + 95,102,114,101,101,111,110,99,108,111,115,101,14,102,111,95,99,97,110,99, + 101,108,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115, + 116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116, + 10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122, + 111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8, + 115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49, + 7,99,97,112,116,105,111,110,6,17,84,97,98,111,114,100,101,114,32,111, + 118,101,114,114,105,100,101,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,8,116,109,115,101,102,111,114,109,0,9,116,115,112,108,105, + 116,116,101,114,10,116,115,112,108,105,116,116,101,114,49,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99, + 117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99, + 111,108,111,114,4,3,0,0,128,8,98,111,117,110,100,115,95,120,3,208, + 0,8,98,111,117,110,100,115,95,121,3,208,0,9,98,111,117,110,100,115, + 95,99,120,2,123,9,98,111,117,110,100,115,95,99,121,2,30,7,97,110, + 99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114, + 105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99, + 95,115,104,114,105,110,107,121,0,7,108,105,110,107,116,111,112,7,17,116, + 101,120,112,97,110,100,105,110,103,119,105,100,103,101,116,49,4,103,114,105, + 112,7,8,115,116,98,95,110,111,110,101,0,7,116,98,117,116,116,111,110, + 8,116,98,117,116,116,111,110,50,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13, + 111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,58,8,98,111,117, + 110,100,115,95,121,2,8,9,98,111,117,110,100,115,95,99,120,2,52,9, + 98,111,117,110,100,115,95,99,121,2,22,12,98,111,117,110,100,115,95,99, + 120,109,105,110,2,50,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112, + 116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108,114, + 101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116, + 111,110,8,116,98,117,116,116,111,110,49,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112, + 104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108, + 101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,8,9,98, + 111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121, + 2,22,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108, + 116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105, + 111,110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7, + 5,109,114,95,111,107,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114, + 50,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,2,50,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100, + 115,95,99,120,2,8,9,98,111,117,110,100,115,95,99,121,2,20,8,108, + 105,110,107,108,101,102,116,7,8,116,98,117,116,116,111,110,49,9,108,105, + 110,107,114,105,103,104,116,7,8,116,98,117,116,116,111,110,50,7,111,112, + 116,105,111,110,115,11,14,115,112,97,111,95,103,108,117,101,114,105,103,104, + 116,0,0,0,0,16,116,101,120,112,97,110,100,105,110,103,119,105,100,103, + 101,116,17,116,101,120,112,97,110,100,105,110,103,119,105,100,103,101,116,49, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,76,1,9,98,111,117,110,100,115,95,99,121,3,208,0,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,121,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120, + 17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,0, + 11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,3,76,1,9,98,111,117,110,100,115,95,99, + 121,3,208,0,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105,111, + 110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103, + 12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121, + 114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101, + 114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95, + 97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104,97, + 110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99, + 111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109, + 111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111, + 108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105, + 116,101,109,115,14,1,5,119,105,100,116,104,2,27,7,110,117,109,115,116, + 101,112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116, + 2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104, + 101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117, + 110,116,2,2,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14, + 1,7,99,97,112,116,105,111,110,6,1,97,0,1,7,99,97,112,116,105, + 111,110,6,1,98,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99, + 111,117,110,116,2,2,16,100,97,116,97,99,111,108,115,46,111,112,116,105, + 111,110,115,11,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108, + 12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118, + 101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115, + 14,7,3,97,101,100,1,5,119,105,100,116,104,3,144,0,7,111,112,116, + 105,111,110,115,11,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116, + 110,97,109,101,6,3,97,101,100,9,100,97,116,97,99,108,97,115,115,7, + 22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108, + 105,115,116,0,7,3,98,101,100,1,5,119,105,100,116,104,3,154,0,7, + 111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95, + 115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6, + 3,98,101,100,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105, + 100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0, + 13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97, + 116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,17,116,100,114,111,112, + 100,111,119,110,108,105,115,116,101,100,105,116,3,97,101,100,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108, + 101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0, + 144,0,1,7,105,109,97,103,101,110,114,2,17,9,111,110,101,120,101,99, + 117,116,101,7,10,100,105,97,108,111,103,101,120,101,118,0,0,8,116,97, + 98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,144,0,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111, + 101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49, + 95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101, + 115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118,97,108,117,101, + 97,102,116,101,114,115,116,97,116,114,101,97,100,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114, + 101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101,95,104,105,110, + 116,99,108,105,112,112,101,100,116,101,120,116,0,16,100,114,111,112,100,111, + 119,110,46,111,112,116,105,111,110,115,11,14,100,101,111,95,115,101,108,101, + 99,116,111,110,108,121,16,100,101,111,95,97,117,116,111,100,114,111,112,100, + 111,119,110,15,100,101,111,95,107,101,121,100,114,111,112,100,111,119,110,12, + 100,101,111,95,99,108,105,112,104,105,110,116,0,19,100,114,111,112,100,111, + 119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112, + 100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,17,116,100, + 114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,3,98,101,100,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114, + 108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4, + 5,0,0,144,0,1,7,105,109,97,103,101,110,114,2,17,9,111,110,101, + 120,101,99,117,116,101,7,10,100,105,97,108,111,103,101,120,101,118,0,0, + 8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,3,145,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,154,0,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117, + 14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118, + 97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111, + 99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,16,100,114, + 111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,14,100,101,111,95, + 115,101,108,101,99,116,111,110,108,121,16,100,101,111,95,97,117,116,111,100, + 114,111,112,100,111,119,110,15,100,101,111,95,107,101,121,100,114,111,112,100, + 111,119,110,12,100,101,111,95,99,108,105,112,104,105,110,116,0,19,100,114, + 111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,19, + 100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14, + 1,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116,102, + 105,108,101,49,8,102,105,108,101,110,97,109,101,6,26,116,97,98,111,114, + 100,101,114,111,118,101,114,114,105,100,101,101,100,105,116,111,114,46,115,116, + 97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114, + 121,0,4,108,101,102,116,2,16,3,116,111,112,3,216,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsetaborderoverrideeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msetexteditor.mfm b/mseide-msegui/lib/common/designutils/msetexteditor.mfm new file mode 100644 index 0000000..f558df7 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetexteditor.mfm @@ -0,0 +1,213 @@ +object msetexteditorfo: tmsetexteditorfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 74 + bounds_y = 214 + bounds_cx = 369 + bounds_cy = 268 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 369 + 268 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + caption = 'Texteditor' + moduleclassname = 'tmseform' + object ok: tbutton + bounds_x = 248 + bounds_y = 240 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 1 + bounds_x = 312 + bounds_y = 240 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 369 + bounds_cy = 234 + anchors = [an_top, an_bottom] + optionsgrid = [og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + linewidth = 0 + width = 40 + numstart = 1 + numstep = 1 + end> + datacols.count = 1 + datacols.items = < + item[textedit] + width = 2000 + options = [co_leftbuttonfocusonly, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'textedit' + dataclass = tgridrichstringdatalist + end> + datarowlinewidth = 0 + datarowheight = 14 + reffontheight = 14 + object textedit: tsyntaxedit + frame.levelo = 0 + frame.framei_top = 0 + frame.framei_bottom = 0 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 2000 + bounds_cy = 14 + optionsedit1 = [oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_eatreturn, oe_exitoncursor, oe_nofirstarrownavig] + options = [seo_autoindent, seo_markbrackets] + oneditnotifcation = editnotify + reffontheight = 14 + end + end + object linedisp: tstringdisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 4 + bounds_x = 8 + bounds_y = 242 + bounds_cx = 76 + anchors = [an_left, an_bottom] + textflags = [tf_xcentered, tf_ycentered] + reffontheight = 14 + end + object test: tbutton + taborder = 3 + bounds_x = 184 + bounds_y = 240 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_disabled, as_invisible, as_localdisabled, as_localinvisible, as_localcaption, as_localonexecute] + caption = '&Test' + onexecute = testexe + end + object tpopupmenu1: tpopupmenu + onupdate = popupuponupdate + menu.submenu.count = 8 + menu.submenu.items = < + item + action = undoact + name = 'undo' + end + item + action = redoact + name = 'redo' + end + item + caption = '&Copy' + name = 'copy' + state = [as_localcaption, as_localshortcut, as_localonexecute] + onexecute = copyexe + sc = ( + 1 + 16451 + ) + end + item + caption = 'Cu&t' + name = 'cut' + state = [as_localcaption, as_localshortcut, as_localonexecute] + onexecute = cutexe + sc = ( + 1 + 16472 + ) + end + item + caption = '&Paste' + name = 'paste' + state = [as_localcaption, as_localshortcut, as_localonexecute] + onexecute = pasteexe + sc = ( + 1 + 16470 + ) + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Load file' + state = [as_localcaption, as_localonexecute] + onexecute = loadfileexe + end + item + caption = '&Save file' + state = [as_localcaption, as_localonexecute] + onexecute = savefileexe + end> + left = 80 + top = 64 + end + object filedialog: tfiledialog + statfile = tstatfile1 + controller.captionopen = 'Load file' + controller.captionsave = 'Save file' + left = 80 + top = 104 + end + object tstatfile1: tstatfile + filename = 'texteditor.sta' + options = [sfo_memory] + left = 80 + top = 152 + end + object undoact: taction + caption = '&Undo' + options = [ao_globalshortcut] + onexecute = undoexe + left = 216 + top = 72 + sc = ( + 1 + 16474 + ) + end + object redoact: taction + caption = '&Redo' + options = [ao_globalshortcut] + onexecute = redoexe + left = 216 + top = 112 + sc = ( + 1 + 24666 + ) + end + object c: tstringcontainer + strings.data = ( + 'Test OK' + ) + left = 192 + top = 152 + end +end diff --git a/mseide-msegui/lib/common/designutils/msetexteditor.pas b/mseide-msegui/lib/common/designutils/msetexteditor.pas new file mode 100644 index 0000000..530ef48 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetexteditor.pas @@ -0,0 +1,153 @@ +unit msetexteditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegui,mseglob,mseguiglob,mseclasses,mseforms,msesimplewidgets,msewidgetgrid, + msesyntaxedit,msemenus,msefiledialog,msestat,msestatfile,msesyntaxpainter, + msedispwidgets,mseinplaceedit,mseact,mseactions,mseeditglob,msestringcontainer, + msestrings; + +const + texteditorstatname = 'texteditor.sta'; +type + tmsetexteditorfo = class(tmseform) + ok: tbutton; + cancel: tbutton; + filedialog: tfiledialog; + undoact: taction; + redoact: taction; + test: tbutton; + tpopupmenu1: tpopupmenu; + textedit: tsyntaxedit; + tstatfile1: tstatfile; + linedisp: tstringdisp; + grid: twidgetgrid; + c: tstringcontainer; + procedure undoexe(const sender: TObject); + procedure redoexe(const sender: TObject); + procedure popupuponupdate(const sender: tcustommenu); + procedure loadfileexe(const sender: TObject); + procedure savefileexe(const sender: TObject); + procedure editnotify(const sender: TObject; var info: editnotificationinfoty); + procedure copyexe(const sender: TObject); + procedure cutexe(const sender: TObject); + procedure pasteexe(const sender: TObject); + procedure testexe(const sender: TObject); + procedure undoupda(const sender: tcustomaction); + procedure redoupda(const sender: tcustomaction); + public + constructor create(const aonclosequery: closequeryeventty; + const asyntaxpainter: tsyntaxpainter; + const asyntaxindex: integer; const testbutton: boolean); reintroduce; + end; + +var + syntaxpainter: tsyntaxpainter; + +implementation +uses + msetexteditor_mfm,sysutils,msewidgets,mseshapes,mseformatstr; + +const + sqlsyntaxdef = ''; +type + strinconststy = ( + testok //0 Test OK + ); + +constructor tmsetexteditorfo.create(const aonclosequery: closequeryeventty; + const asyntaxpainter: tsyntaxpainter; const asyntaxindex: integer; + const testbutton: boolean); +begin + inherited create(nil); + onclosequery:= aonclosequery; + if (asyntaxpainter <> nil) and (asyntaxindex >= 0) then begin + textedit.syntaxpainter:= asyntaxpainter; + textedit.setsyntaxdef(asyntaxindex); + end; + if testbutton then begin + test.state:= test.state - [as_invisible,as_disabled]; + end; +end; + +procedure tmsetexteditorfo.loadfileexe(const sender: TObject); +begin + if filedialog.execute(fdk_open) = mr_ok then begin + textedit.loadfromfile(filedialog.controller.filename); + end; +end; + +procedure tmsetexteditorfo.savefileexe(const sender: TObject); +begin + if filedialog.execute(fdk_save) = mr_ok then begin + textedit.savetofile(filedialog.controller.filename); + end; +end; + +procedure tmsetexteditorfo.editnotify(const sender: TObject; + var info: editnotificationinfoty); +begin + if info.action = ea_indexmoved then begin + linedisp.value:= inttostrmse(textedit.editpos.row+1) + ':'+ + inttostrmse(textedit.editpos.col+1); + end; +end; + +procedure tmsetexteditorfo.popupuponupdate(const sender: tcustommenu); +begin + sender.menu.itembyname('undo').enabled:= textedit.canundo; + sender.menu.itembyname('redo').enabled:= textedit.canredo; + sender.menu.itembyname('copy').enabled:= textedit.hasselection; + sender.menu.itembyname('cut').enabled:= textedit.hasselection; + sender.menu.itembyname('paste').enabled:= textedit.canpaste; +end; + +procedure tmsetexteditorfo.undoexe(const sender: TObject); +begin + textedit.undo; +end; + +procedure tmsetexteditorfo.redoexe(const sender: TObject); +begin + textedit.redo; +end; + +procedure tmsetexteditorfo.copyexe(const sender: TObject); +begin + textedit.copyselection; +end; + +procedure tmsetexteditorfo.cutexe(const sender: TObject); +begin + textedit.cutselection; +end; + +procedure tmsetexteditorfo.pasteexe(const sender: TObject); +begin + textedit.paste; +end; + +procedure tmsetexteditorfo.testexe(const sender: TObject); +var + modres: modalresultty; +begin + modres:= mr_canclose; + onclosequery(self,modres); + if modres = mr_canclose then begin + showmessage(c[ord(testok)]); + end; +end; + +procedure tmsetexteditorfo.undoupda(const sender: tcustomaction); +begin +end; + +procedure tmsetexteditorfo.redoupda(const sender: tcustomaction); +begin +end; + +initialization + syntaxpainter:= tsyntaxpainter.create(nil); +finalization + syntaxpainter.free; +end. diff --git a/mseide-msegui/lib/common/designutils/msetexteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msetexteditor_mfm.pas new file mode 100644 index 0000000..ad16a59 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetexteditor_mfm.pas @@ -0,0 +1,195 @@ +unit msetexteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msetexteditor; + +const + objdata: record size: integer; data: array[0..3558] of byte end = + (size: 3559; data: ( + 84,80,70,48,16,116,109,115,101,116,101,120,116,101,100,105,116,111,114,102, + 111,15,109,115,101,116,101,120,116,101,100,105,116,111,114,102,111,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117,115,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95, + 104,105,110,116,111,110,0,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,2,74,8,98,111,117,110,100,115,95,121,3,214,0,9, + 98,111,117,110,100,115,95,99,120,3,113,1,9,98,111,117,110,100,115,95, + 99,121,3,12,1,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99, + 117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0, + 2,0,3,113,1,3,12,1,0,7,111,112,116,105,111,110,115,11,13,102, + 111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111, + 114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116, + 101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,12,102,111,95, + 115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6, + 10,84,101,120,116,101,100,105,116,111,114,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,7,116, + 98,117,116,116,111,110,2,111,107,8,98,111,117,110,100,115,95,120,3,248, + 0,8,98,111,117,110,100,115,95,121,3,240,0,9,98,111,117,110,100,115, + 95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,7,97,110, + 99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3, + 38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95, + 111,107,0,0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3, + 56,1,8,98,111,117,110,100,115,95,121,3,240,0,9,98,111,117,110,100, + 115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,7,97, + 110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 7,38,67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116, + 7,9,109,114,95,99,97,110,99,101,108,0,0,11,116,119,105,100,103,101, + 116,103,114,105,100,4,103,114,105,100,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2, + 9,112,111,112,117,112,109,101,110,117,7,11,116,112,111,112,117,112,109,101, + 110,117,49,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,113,1,9,98, + 111,117,110,100,115,95,99,121,3,234,0,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111, + 112,116,105,111,110,115,103,114,105,100,11,19,111,103,95,102,111,99,117,115, + 99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102, + 105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110, + 100,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107, + 101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46,99,111,117,110, + 116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,9, + 108,105,110,101,119,105,100,116,104,2,0,5,119,105,100,116,104,2,40,8, + 110,117,109,115,116,97,114,116,2,1,7,110,117,109,115,116,101,112,2,1, + 0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1,14, + 100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,116,101,120, + 116,101,100,105,116,1,5,119,105,100,116,104,3,208,7,7,111,112,116,105, + 111,110,115,11,22,99,111,95,108,101,102,116,98,117,116,116,111,110,102,111, + 99,117,115,111,110,108,121,12,99,111,95,115,97,118,101,118,97,108,117,101, + 12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,8,116,101,120,116,101,100,105,116,9,100,97,116,97,99,108, + 97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,0,16,100,97,116,97,114,111,119,108,105, + 110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,14,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,11,116,115,121,110,116,97,120,101,100,105,116,8,116,101,120,116,101, + 100,105,116,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,16,102, + 114,97,109,101,46,102,114,97,109,101,105,95,116,111,112,2,0,19,102,114, + 97,109,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,0,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,10,102,114,108,95,102,105,108,101,102,116,9, + 102,114,108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103,104, + 116,12,102,114,108,95,102,105,98,111,116,116,111,109,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,208,7,9,98,111,117,110,100,115,95,99,121, + 2,14,12,111,112,116,105,111,110,115,101,100,105,116,49,11,14,111,101,49, + 95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101, + 118,97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,12,111,101,95,108,105,110,101,98,114,101,97,107,12,111,101, + 95,101,97,116,114,101,116,117,114,110,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,20,111,101,95,110,111,102,105,114,115,116,97,114,114, + 111,119,110,97,118,105,103,0,7,111,112,116,105,111,110,115,11,14,115,101, + 111,95,97,117,116,111,105,110,100,101,110,116,16,115,101,111,95,109,97,114, + 107,98,114,97,99,107,101,116,115,0,17,111,110,101,100,105,116,110,111,116, + 105,102,99,97,116,105,111,110,7,10,101,100,105,116,110,111,116,105,102,121, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,11, + 116,115,116,114,105,110,103,100,105,115,112,8,108,105,110,101,100,105,115,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,3,242,0,9,98,111,117,110,100,115, + 95,99,120,2,76,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,9,97,110,95,98,111,116,116,111,109,0,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102, + 95,121,99,101,110,116,101,114,101,100,0,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,4,116,101, + 115,116,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115, + 95,120,3,184,0,8,98,111,117,110,100,115,95,121,3,240,0,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 22,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9, + 97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,11,97,115, + 95,100,105,115,97,98,108,101,100,12,97,115,95,105,110,118,105,115,105,98, + 108,101,16,97,115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,17, + 97,115,95,108,111,99,97,108,105,110,118,105,115,105,98,108,101,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110, + 6,5,38,84,101,115,116,9,111,110,101,120,101,99,117,116,101,7,7,116, + 101,115,116,101,120,101,0,0,10,116,112,111,112,117,112,109,101,110,117,11, + 116,112,111,112,117,112,109,101,110,117,49,8,111,110,117,112,100,97,116,101, + 7,15,112,111,112,117,112,117,112,111,110,117,112,100,97,116,101,18,109,101, + 110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,8,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,6, + 97,99,116,105,111,110,7,7,117,110,100,111,97,99,116,4,110,97,109,101, + 6,4,117,110,100,111,0,1,6,97,99,116,105,111,110,7,7,114,101,100, + 111,97,99,116,4,110,97,109,101,6,4,114,101,100,111,0,1,7,99,97, + 112,116,105,111,110,6,5,38,67,111,112,121,4,110,97,109,101,6,4,99, + 111,112,121,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,16,97,115,95,108,111,99,97,108,115,104,111,114,116, + 99,117,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,111,110,101,120,101,99,117,116,101,7,7,99,111,112,121,101,120, + 101,2,115,99,1,2,1,3,67,64,0,0,1,7,99,97,112,116,105,111, + 110,6,4,67,117,38,116,4,110,97,109,101,6,3,99,117,116,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 16,97,115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,6,99,117,116,101,120,101,2,115,99,1,2,1, + 3,88,64,0,0,1,7,99,97,112,116,105,111,110,6,6,38,80,97,115, + 116,101,4,110,97,109,101,6,5,112,97,115,116,101,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,16,97,115, + 95,108,111,99,97,108,115,104,111,114,116,99,117,116,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,8,112,97,115,116,101,101,120,101,2,115,99,1,2,1,3, + 86,64,0,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115, + 101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117, + 116,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6, + 10,38,76,111,97,100,32,102,105,108,101,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,11,108,111,97,100,102,105,108,101,101,120,101,0,1,7,99, + 97,112,116,105,111,110,6,10,38,83,97,118,101,32,102,105,108,101,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 9,111,110,101,120,101,99,117,116,101,7,11,115,97,118,101,102,105,108,101, + 101,120,101,0,0,4,108,101,102,116,2,80,3,116,111,112,2,64,0,0, + 11,116,102,105,108,101,100,105,97,108,111,103,10,102,105,108,101,100,105,97, + 108,111,103,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102, + 105,108,101,49,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116, + 105,111,110,111,112,101,110,6,9,76,111,97,100,32,102,105,108,101,22,99, + 111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111,110,115,97,118, + 101,6,9,83,97,118,101,32,102,105,108,101,4,108,101,102,116,2,80,3, + 116,111,112,2,104,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115, + 116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,14,116, + 101,120,116,101,100,105,116,111,114,46,115,116,97,7,111,112,116,105,111,110, + 115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116,2, + 80,3,116,111,112,3,152,0,0,0,7,116,97,99,116,105,111,110,7,117, + 110,100,111,97,99,116,7,99,97,112,116,105,111,110,6,5,38,85,110,100, + 111,7,111,112,116,105,111,110,115,11,17,97,111,95,103,108,111,98,97,108, + 115,104,111,114,116,99,117,116,0,9,111,110,101,120,101,99,117,116,101,7, + 7,117,110,100,111,101,120,101,4,108,101,102,116,3,216,0,3,116,111,112, + 2,72,2,115,99,1,2,1,3,90,64,0,0,0,7,116,97,99,116,105, + 111,110,7,114,101,100,111,97,99,116,7,99,97,112,116,105,111,110,6,5, + 38,82,101,100,111,7,111,112,116,105,111,110,115,11,17,97,111,95,103,108, + 111,98,97,108,115,104,111,114,116,99,117,116,0,9,111,110,101,120,101,99, + 117,116,101,7,7,114,101,100,111,101,120,101,4,108,101,102,116,3,216,0, + 3,116,111,112,2,112,2,115,99,1,2,1,3,90,96,0,0,0,16,116, + 115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116, + 114,105,110,103,115,46,100,97,116,97,1,6,7,84,101,115,116,32,79,75, + 0,4,108,101,102,116,3,192,0,3,116,111,112,3,152,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsetexteditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/panelform.mfm b/mseide-msegui/lib/common/designutils/panelform.mfm new file mode 100644 index 0000000..7e40563 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/panelform.mfm @@ -0,0 +1,37 @@ +object panelfo: tpanelfo + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_lockbutton, go_nolockbutton, go_buttonhints] + onpaint = paintexe + visible = False + bounds_x = 157 + bounds_y = 493 + bounds_cx = 323 + bounds_cy = 195 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent] + container.frame.framei_left = 0 + container.frame.framei_top = 0 + container.frame.framei_right = 0 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + container.frame.localprops1 = [] + container.onpaint = paintexe + container.bounds = ( + 0 + 0 + 313 + 195 + ) + dragdock.tab_options = [tabo_dragsource, tabo_dragdest, tabo_hintclippedtext] + dragdock.tab_textflags = [tf_ycentered, tf_ellipseright] + dragdock.tab_widthmax = 100 + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_acceptsdock, od_dockparent, od_splitvert, od_splithorz, od_tabed, od_proportional, od_propsize, od_captionhint, od_childicons] + dragdock.onlayoutchanged = panellayoutchanged + dragdock.oncaptionchanged = panellayoutchanged + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + onclose = onclo + moduleclassname = 'tdockform' +end diff --git a/mseide-msegui/lib/common/designutils/panelform.pas b/mseide-msegui/lib/common/designutils/panelform.pas new file mode 100644 index 0000000..3fedab6 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/panelform.pas @@ -0,0 +1,292 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit panelform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,msegui,mseclasses,mseforms,msemenus,msestat, + msetypes{msestrings}, + msedock,msegraphutils,msegraphics,mseguiglob,msesimplewidgets,msewidgets, + msestringcontainer; + +type + + tpanelfo = class(tdockform) + procedure onclo(const sender: TObject); + procedure panellayoutchanged(const sender: tdockcontroller); + procedure paintexe(const sender: twidget; const acanvas: tcanvas); + private + fmenuitem: tmenuitem; + fnameindex: integer; //0 for unnumbered + procedure showexecute(const sender: tobject); + protected + procedure updatecaption(acaption: msestring); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function canclose(const newfocus: twidget): boolean; override; + end; + +function newpanel(aname: string = ''): tpanelfo; +procedure updatestat(const filer: tstatfiler); +procedure docktopanel(const controller: tdockcontroller; + const panelname: string; const arect: rectty); +procedure beginpanelplacement(); +procedure endpanelplacement(); + +implementation + +uses + panelform_mfm,main,sysutils,msekeyboard,mselist,msedatalist, + msearrayutils,mseformatstr; + +var + panellist: tpointerlist; + +procedure updatestat(const filer: tstatfiler); +var + ar1: msestringarty; + int1: integer; +begin + ar1:= nil; + if filer.iswriter then begin + setlength(ar1,panellist.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= msestring(tpanelfo(panellist[int1]).name); + end; + end; + filer.updatevalue('panels',ar1); + if not filer.iswriter then begin + for int1:= panellist.count - 1 downto 0 do begin + tpanelfo(panellist[int1]).free; + end; + for int1:= 0 to high(ar1) do begin + try + newpanel(ansistring(ar1[int1])); + except + end; + end; + end; +end; + +procedure docktopanel(const controller: tdockcontroller; + const panelname: string; const arect: rectty); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + if name = panelname then begin + dragdock.dock(controller,arect); + break; + end; + end; + end; +end; + +procedure beginpanelplacement(); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + dragdock.beginplacement(); + end; + end; +end; + +procedure endpanelplacement(); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + try + dragdock.endplacement(); + except + application.handleexception(); + end; + end; + end; +end; + +function newpanel(aname: string = ''): tpanelfo; +var + item1: tmenuitem; + int1,int2: integer; + ar1: integerarty; +begin + item1:= mainfo.mainmenu.menu.itembyname('view').itembyname('panels'); + if aname = '' then begin + setlength(ar1,panellist.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tpanelfo(panellist[int1]).fnameindex; + end; + sortarray(ar1); + int2:= length(ar1); + for int1:= 0 to high(ar1) do begin //find first gap + if ar1[int1] <> int1 then begin + int2:= int1; + break; + end; + end; + end + else begin + int2:= strtoint(copy(aname,6,bigint))-1; + end; + result:= tpanelfo.create(mainfo); + int1:= int2 + 1; + if aname = '' then begin + aname:= 'panel'+inttostr(int1); + end; + with result do begin + name:= aname; + fnameindex:= int2; + fmenuitem:= tmenuitem.create(nil,nil); + updatecaption(''); + end; + if int2 > item1.count - 2 then begin + int2:= item1.count - 2; + end; + item1.submenu.insert(int2,result.fmenuitem); +end; + +{ tpanelfo } + +constructor tpanelfo.create(aowner: tcomponent); +begin + inherited create(aowner); + panellist.add(self); +end; + +destructor tpanelfo.destroy; +begin + if panellist <> nil then begin + panellist.remove(self); + end; + if not (csdestroying in mainfo.componentstate) then begin + fmenuitem.parentmenu.submenu.delete(fmenuitem.index); + end; + inherited; +end; + +procedure tpanelfo.updatecaption(acaption: msestring); + +begin + if acaption = '' then begin + acaption:= 'Panel'; + end; + if length(acaption) > 40 then begin + setlength(acaption,40); + acaption:= acaption+'...'; + end; + with fmenuitem do begin + onexecute:= {$ifdef FPC}@{$endif}showexecute; + if fnameindex < 9 then begin + shortcut:= (ord(key_f1) or key_modctrl) + fnameindex; + caption:= '&' + inttostrmse(fnameindex+1)+' '+acaption; + end + else begin + shortcut:= 0; + caption:= acaption; + end; + if shortcut <> 0 then begin + acaption:= acaption + ' (Ctrl+F' + inttostrmse(fnameindex+1)+')'; + end; + self.caption:= acaption; + end; +end; + +procedure tpanelfo.showexecute(const sender: tobject); +begin + activate; +end; + +function tpanelfo.canclose(const newfocus: twidget): boolean; + + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; + +begin + result:= inherited canclose(newfocus); + { + if result and (newfocus = nil) and containerempty then begin + release; + end; + } +end; + +procedure tpanelfo.onclo(const sender: TObject); + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; +begin + if containerempty then begin + release; + end; +end; + +procedure tpanelfo.panellayoutchanged(const sender: tdockcontroller); +var + intf1: idocktarget; + mstr1: msestring; + int1: integer; + ar1: widgetarty; +begin + mstr1:= ''; + ar1:= sender.getitems; + for int1:= 0 to high(ar1) do begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + mstr1:= mstr1 + intf1.getdockcontroller.getdockcaption+','; + end; + end; + if mstr1 <> '' then begin + setlength(mstr1,length(mstr1)-1); + end; + fdragdock.caption:= mstr1; + updatecaption(mstr1); +end; + +procedure tpanelfo.paintexe(const sender: twidget; const acanvas: tcanvas); +begin + paintdockingareacaption(acanvas,sender,mainfo.c[ord(dockingarea)]); +end; + +initialization + panellist:= tpointerlist.Create; +finalization + freeandnil(panellist); +end. diff --git a/mseide-msegui/lib/common/designutils/panelform_mfm.pas b/mseide-msegui/lib/common/designutils/panelform_mfm.pas new file mode 100644 index 0000000..b40827a --- /dev/null +++ b/mseide-msegui/lib/common/designutils/panelform_mfm.pas @@ -0,0 +1,87 @@ +unit panelform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,panelform; + +const + objdata: record size: integer; data: array[0..1397] of byte end = + (size: 1398; data: ( + 84,80,70,48,8,116,112,97,110,101,108,102,111,7,112,97,110,101,108,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,9,111,119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114, + 105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112, + 95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117, + 116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111, + 110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95, + 116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111, + 117,110,100,98,117,116,116,111,110,13,103,111,95,108,111,99,107,98,117,116, + 116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14, + 103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,111,110,112,97, + 105,110,116,7,8,112,97,105,110,116,101,120,101,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,157,0,8,98,111,117,110,100, + 115,95,121,3,237,1,9,98,111,117,110,100,115,95,99,120,3,67,1,9, + 98,111,117,110,100,115,95,99,121,3,195,0,23,99,111,110,116,97,105,110, + 101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46, + 102,114,97,109,101,105,95,108,101,102,116,2,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,116,111,112, + 2,0,28,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102, + 114,97,109,101,105,95,114,105,103,104,116,2,0,29,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,98,111,116, + 116,111,109,2,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,102,105, + 108,101,102,116,9,102,114,108,95,102,105,116,111,112,11,102,114,108,95,102, + 105,114,105,103,104,116,12,102,114,108,95,102,105,98,111,116,116,111,109,0, + 27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,17,99,111,110,116,97,105,110,101,114, + 46,111,110,112,97,105,110,116,7,8,112,97,105,110,116,101,120,101,16,99, + 111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0, + 3,57,1,3,195,0,0,20,100,114,97,103,100,111,99,107,46,116,97,98, + 95,111,112,116,105,111,110,115,11,15,116,97,98,111,95,100,114,97,103,115, + 111,117,114,99,101,13,116,97,98,111,95,100,114,97,103,100,101,115,116,20, + 116,97,98,111,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,22,100,114,97,103,100,111,99,107,46,116,97,98,95,116,101,120,116,102, + 108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,15,116, + 102,95,101,108,108,105,112,115,101,114,105,103,104,116,0,21,100,114,97,103, + 100,111,99,107,46,116,97,98,95,119,105,100,116,104,109,97,120,2,100,20, + 100,114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111,99,107, + 11,10,111,100,95,115,97,118,101,112,111,115,13,111,100,95,115,97,118,101, + 122,111,114,100,101,114,10,111,100,95,99,97,110,109,111,118,101,11,111,100, + 95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107, + 14,111,100,95,97,99,99,101,112,116,115,100,111,99,107,13,111,100,95,100, + 111,99,107,112,97,114,101,110,116,12,111,100,95,115,112,108,105,116,118,101, + 114,116,12,111,100,95,115,112,108,105,116,104,111,114,122,8,111,100,95,116, + 97,98,101,100,15,111,100,95,112,114,111,112,111,114,116,105,111,110,97,108, + 11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116, + 105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110, + 115,0,24,100,114,97,103,100,111,99,107,46,111,110,108,97,121,111,117,116, + 99,104,97,110,103,101,100,7,18,112,97,110,101,108,108,97,121,111,117,116, + 99,104,97,110,103,101,100,25,100,114,97,103,100,111,99,107,46,111,110,99, + 97,112,116,105,111,110,99,104,97,110,103,101,100,7,18,112,97,110,101,108, + 108,97,121,111,117,116,99,104,97,110,103,101,100,7,111,112,116,105,111,110, + 115,11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118, + 101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101, + 0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112, + 114,111,106,101,99,116,115,116,97,116,102,105,108,101,7,111,110,99,108,111, + 115,101,7,5,111,110,99,108,111,15,109,111,100,117,108,101,99,108,97,115, + 115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,0) + ); + +initialization + registerobjectdata(@objdata,tpanelfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msecolordialog.mfm b/mseide-msegui/lib/common/dialogs/msecolordialog.mfm new file mode 100644 index 0000000..bb272ee --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msecolordialog.mfm @@ -0,0 +1,561 @@ +object colordialogfo: tcolordialogfo + visible = False + bounds_x = 140 + bounds_y = 234 + bounds_cx = 338 + bounds_cy = 298 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = layoutexe + container.bounds = ( + 0 + 0 + 338 + 298 + ) + onshortcut = shortcutexe + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = tstatfile1 + caption = 'Select Color' + onloaded = loadedexe + onmouseevent = mouseeventexe + onlayout = layoutexe + moduleclassname = 'tmseform' + object colorpibu: tdatabutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 6 + bounds_x = 4 + bounds_y = 237 + bounds_cx = 97 + bounds_cy = 18 + bounds_cxmin = 97 + anchors = [an_left, an_bottom] + state = [as_localinvisible, as_localcaption, as_localonexecute] + valuefaces.count = 1 + valuefaces.items = < + item + fade_pos.count = 3 + fade_pos.items = ( + 0 + 0.42629482071713 + 1 + ) + fade_color.count = 3 + fade_color.items = ( + 16762880 + 16772001 + 15903324 + ) + fade_direction = gd_down + localprops = [fal_fadirection] + end> + caption = 'Color &Picker' + onexecute = colorpickexe + reffontheight = 14 + end + object colorarea: tpaintbox + optionswidget = [ow_destroywidgets] + color = -2147483645 + frame.options = [cfo_captionnoclip] + frame.colorframe = -1610612734 + frame.colorclient = -1879048174 + frame.caption = 'new' + frame.captionpos = cp_bottom + frame.localprops = [frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 0 + 17 + ) + taborder = 5 + bounds_x = 51 + bounds_y = 3 + bounds_cx = 50 + bounds_cy = 226 + anchors = [an_left, an_top, an_bottom] + end + object colorareabefore: tpaintbox + optionswidget = [ow_destroywidgets] + color = -2147483645 + frame.options = [cfo_captionnoclip] + frame.colorframe = -1610612734 + frame.colorclient = -1879048180 + frame.caption = 'old' + frame.captionpos = cp_bottom + frame.localprops = [frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 0 + 17 + ) + taborder = 4 + bounds_x = 3 + bounds_y = 3 + bounds_cx = 50 + bounds_cy = 226 + anchors = [an_left, an_top, an_bottom] + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 112 + bounds_y = 219 + bounds_cx = 221 + bounds_cy = 37 + anchors = [an_left, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + linktop = tlayouter3 + linkbottom = tlayouter2 + options = [spao_gluebottom] + object blue: tintegeredit + color = -2147483645 + frame.caption = '&blue' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 185 + bounds_y = 0 + bounds_cx = 36 + bounds_cy = 37 + onchange = rgbchange + ondataentered = componentsdataentered + max = 255 + reffontheight = 14 + end + object green: tintegeredit + color = -2147483645 + frame.caption = '&green' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 1 + 17 + 2 + 0 + ) + taborder = 4 + bounds_x = 147 + bounds_y = 0 + bounds_cx = 39 + bounds_cy = 37 + onchange = rgbchange + ondataentered = componentsdataentered + max = 255 + reffontheight = 14 + end + object red: tintegeredit + color = -2147483645 + frame.caption = '&red' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 111 + bounds_y = 0 + bounds_cx = 36 + bounds_cy = 37 + onchange = rgbchange + ondataentered = componentsdataentered + max = 255 + reffontheight = 14 + end + object bright: tintegeredit + color = -2147483645 + frame.caption = '&BRI' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 72 + bounds_y = 0 + bounds_cx = 36 + bounds_cy = 37 + onchange = hsbchange + ondataentered = componentsdataentered + max = 100 + reffontheight = 14 + end + object sat: tintegeredit + color = -2147483645 + frame.caption = '&SAT' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 36 + bounds_y = 0 + bounds_cx = 36 + bounds_cy = 37 + onchange = hsbchange + ondataentered = componentsdataentered + max = 100 + reffontheight = 14 + end + object hue: tintegeredit + color = -2147483645 + frame.caption = '&HUE' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 36 + bounds_cy = 37 + onchange = hsbchange + ondataentered = componentsdataentered + max = 360 + reffontheight = 14 + end + end + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 11 + bounds_y = 256 + bounds_cx = 324 + bounds_cy = 38 + anchors = [an_left, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + font.name = 'stf_default' + font.localprops = [] + optionslayout = [lao_aligny] + align_glue = wam_start + linktop = tlayouter1 + options = [spao_gluebottom] + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + color = -2147483645 + taborder = 3 + bounds_x = 272 + bounds_y = 17 + bounds_cx = 52 + bounds_cy = 21 + bounds_cxmin = 50 + state = [as_localcaption, as_localcolor] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 2 + bounds_x = 216 + bounds_y = 17 + bounds_cx = 50 + bounds_cy = 21 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object colored: tcoloredit + frame.caption = 'Color' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.buttonellipse.width = -1 + frame.buttonellipse.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 102 + bounds_y = 0 + bounds_cx = 108 + bounds_cy = 37 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + onchange = colorchangeev + ondataentered = coloreddataentered + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + reffontheight = 14 + end + object rgbed: tintegeredit + frame.caption = 'RGB' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 32 + bounds_y = 0 + bounds_cx = 68 + bounds_cy = 37 + ondataentered = rgbeddataentered + base = nb_hex + bitcount = 24 + reffontheight = 14 + end + end + object tlayouter3: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 2 + bounds_x = 112 + bounds_y = 0 + bounds_cx = 221 + bounds_cy = 219 + optionslayout = [lao_aligny] + align_mode = wam_start + object sliderblue: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + taborder = 5 + bounds_x = 196 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 2 + scrollbar.face.fade_pos.items = ( + 0 + 1 + ) + scrollbar.face.fade_color.count = 2 + scrollbar.face.fade_color.items = ( + -1610612734 + -1610612727 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = blueonsetvalue + direction = gd_up + end + object slidergreen: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + taborder = 4 + bounds_x = 160 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 2 + scrollbar.face.fade_pos.items = ( + 0 + 1 + ) + scrollbar.face.fade_color.count = 2 + scrollbar.face.fade_color.items = ( + -1610612734 + -1610612728 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = greenonsetvalue + direction = gd_up + end + object sliderred: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + taborder = 3 + bounds_x = 124 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 2 + scrollbar.face.fade_pos.items = ( + 0 + 1 + ) + scrollbar.face.fade_color.count = 2 + scrollbar.face.fade_color.items = ( + -1610612734 + -1610612729 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = redonsetvalue + direction = gd_up + end + object sliderbright: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + taborder = 2 + bounds_x = 83 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 2 + scrollbar.face.fade_pos.items = ( + 0 + 1 + ) + scrollbar.face.fade_color.count = 2 + scrollbar.face.fade_color.items = ( + -1610612734 + -1610612730 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = brightonsetvalue + direction = gd_up + end + object slidersat: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 48 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 2 + scrollbar.face.fade_pos.items = ( + 0 + 1 + ) + scrollbar.face.fade_color.count = 2 + scrollbar.face.fade_color.items = ( + -1610612730 + -1610612730 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = satonsetvalue + direction = gd_up + end + object sliderhue: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + bounds_x = 12 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 7 + scrollbar.face.fade_pos.items = ( + 0 + 0.166666666 + 0.333333333 + 0.5 + 0.66666666 + 0.83333333 + 1 + ) + scrollbar.face.fade_color.count = 7 + scrollbar.face.fade_color.items = ( + -1610612729 + -1610612724 + -1610612728 + -1610612726 + -1610612727 + -1610612725 + -1610612729 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = hueonsetvalue + direction = gd_up + end + end + object gb: tgroupbox + optionswidget = [ow_parenttabfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + optionsskin = [osk_noskin] + color = -2147483645 + frame.localprops = [frl_levelo, frl_leveli] + frame.localprops1 = [] + taborder = 3 + bounds_x = 3 + bounds_y = 3 + bounds_cx = 100 + bounds_cy = 209 + anchors = [an_left, an_top, an_bottom] + end + object tstatfile1: tstatfile + filename = 'colordialog.sta' + options = [sfo_memory] + left = 24 + top = 104 + end +end diff --git a/mseide-msegui/lib/common/dialogs/msecolordialog.pas b/mseide-msegui/lib/common/dialogs/msecolordialog.pas new file mode 100644 index 0000000..3aefe75 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msecolordialog.pas @@ -0,0 +1,952 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msecolordialog; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,msegraphedits,msewidgets,msesimplewidgets, + msedataedits,msegraphics,mseglob,mseguiglob,msedialog,classes,mclasses, + msetypes,msedropdownlist,msegrids,msestrings,mseedit,msestat,msestatfile, + msegraphutils,msemenus,mseevent,mseificomp,mseificompglob,mseifiglob, + msesplitter,msedispwidgets,mserichstring,msescrollbar; + +const + colordialogstatname = 'colordialog.sta'; + +type + + coloreventty = procedure(const sender: tobject; + const avalue: colorty) of object; + setcoloreventty = procedure(const sender: tobject; var avalue: colorty; + var accept: boolean) of object; + + tellipsedropdownbuttonframe = class(tdropdownmultibuttonframe) + private + function getbuttonellipse: tdropdownbutton; + procedure setbuttonellipse(const avalue: tdropdownbutton); + public + constructor create(const aintf: icaptionframe; + const buttonintf: ibutton); override; + published + property buttonellipse: tdropdownbutton read getbuttonellipse + write setbuttonellipse; + end; + + colordialogoptionty = (cdo_rgbtext); + colordialogoptionsty = set of colordialogoptionty; + + coloreditoptionty = (ceo_rgbtext); + coloreditoptionsty = set of coloreditoptionty; + + tcustomcoloredit = class(tcustomenumedit) + private + foncolorchange: coloreventty; + foptions: coloreditoptionsty; + function getvalue: colorty; + procedure setvalue(avalue: colorty); + function getvaluedefault: colorty; + procedure setvaluedefault(avalue: colorty); + + function getonsetvalue: setcoloreventty; + procedure setonsetvalue(const avalue: setcoloreventty); + function getframe: tellipsedropdownbuttonframe; + procedure setframe(const avalue: tellipsedropdownbuttonframe); + function getgridvalue(const index: integer): colorty; + procedure setgridvalue(const index: integer; const avalue: colorty); + function getgridvalues: colorarty; + procedure setgridvalues(const avalue: colorarty); + procedure setoptions(const avalue: coloreditoptionsty); + protected + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function internaldatatotext1( + const avalue: integer): msestring; virtual; + function internaldatatotext(const data): msestring; override; + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure paintimage(const canvas: tcanvas); override; + function geteditframe: framety; override; + procedure colorenter(const acolor: colorty); + procedure buttonaction(var action: buttonactionty; + const buttonindex: integer); override; + procedure dochange(); override; + procedure docolorchange(const sender: tobject; const acolor: colorty); + public + constructor create(aowner: tcomponent); override; + property value: colorty read getvalue write setvalue default cl_none; + property valuedefault: colorty read getvaluedefault + write setvaluedefault default cl_none; + property options: coloreditoptionsty read foptions + write setoptions default []; + property frame: tellipsedropdownbuttonframe read getframe write setframe; + property gridvalue[const index: integer]: colorty + read getgridvalue write setgridvalue; default; + property gridvalues: colorarty read getgridvalues write setgridvalues; + property onsetvalue: setcoloreventty read getonsetvalue write setonsetvalue; + property oncolorchange: coloreventty read foncolorchange + write foncolorchange; + //sender is tcolordialogfo or tcustomcoloredit + end; + + tcoloredit = class(tcustomcoloredit) + published + property value; + property valuedefault; + property options; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onsetvalue; + property oncolorchange; + property frame; + end; + + tcolordialogfo = class(tmseform) + tstatfile1: tstatfile; + tlayouter1: tlayouter; + blue: tintegeredit; + green: tintegeredit; + red: tintegeredit; + bright: tintegeredit; + sat: tintegeredit; + hue: tintegeredit; + tlayouter2: tlayouter; + cancel: tbutton; + ok: tbutton; + colored: tcoloredit; + rgbed: tintegeredit; + tlayouter3: tlayouter; + sliderblue: tslider; + slidergreen: tslider; + sliderred: tslider; + sliderbright: tslider; + slidersat: tslider; + sliderhue: tslider; + gb: tgroupbox; + colorareabefore: tpaintbox; + colorarea: tpaintbox; + colorpibu: tdatabutton; + procedure hueonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure satonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure brightonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure hsbchange(const sender: TObject); + procedure redonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure greenonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure blueonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure rgbchange(const sender: TObject); + procedure componentsdataentered(const sender: TObject); + procedure layoutexe(const sender: TObject); + procedure rgbeddataentered(const sender: TObject); + procedure coloreddataentered(const sender: TObject); + procedure loadedexe(const sender: TObject); + procedure colorpickexe(const sender: TObject); + procedure mouseeventexe(const sender: twidget; var ainfo: mouseeventinfoty); + procedure shortcutexe(const sender: twidget; var ainfo: keyeventinfoty; + const origin: twidget); + procedure colorchangeev(const sender: TObject); + private + fupdating: boolean; + foncolorchange: coloreventty; + procedure updatecomponents; + protected + fcolorpicking: boolean; + fcolorbefore: colorty; + procedure begincolorpick(); + procedure endcolorpick(); + procedure dochange(); + published + property oncolorchange: coloreventty read foncolorchange + write foncolorchange; + end; + + tcolordropdowncontroller = class(tnocolsdropdownlistcontroller) + protected + fcolorvalues: colorarty; + function getbuttonframeclass: dropdownbuttonframeclassty; override; + function getfixcolclass: dropdownfixcolclassty; override; + public + constructor create(const intf: idropdownlist); + published + property options default defaultautodropdownoptions; + end; + +function colordialog(var acolor: colorty; + const aoncolorchange: coloreventty = nil; + const aoptions: colordialogoptionsty = []): modalresultty; +//threadsafe +procedure paintcolorimage(const sender: twidget; const canvas: tcanvas; + const acolor: colorty); +procedure paintcolorrect(const canvas: tcanvas; const arect: rectty; + const acolor: colorty); + +implementation +uses + msecolordialog_mfm,msestockobjects,mseformatstr,sysutils,msepointer, + msekeyboard,mseguiintf,mseeditglob; +type + twidget1 = class(twidget); + + tcolorfixcol = class(tdropdownfixcol) + protected + ficonrect: rectty; + procedure drawcell(const canvas: tcanvas); override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); override; + end; + +function colordialog(var acolor: colorty; + const aoncolorchange: coloreventty = nil; + const aoptions: colordialogoptionsty = []): modalresultty; +var + fo: tcolordialogfo; + col1: rgbtriplety; +begin + application.lock; + try + fo:= tcolordialogfo.create(nil); + fo.oncolorchange:= aoncolorchange; + fo.colored.options:= coloreditoptionsty(aoptions); + try + try + col1:= colortorgb(acolor); + fo.colored.value:= acolor; + except + fillchar(col1,sizeof(col1),0); + fo.colored.value:= 0; + end; + fo.rgbed.value:= integer(col1); + fo.colorareabefore.frame.colorclient:= colorty(col1); + fo.red.value:= col1.red; + fo.green.value:= col1.green; + fo.blue.value:= col1.blue; + result:= fo.show(true); + if result = mr_ok then begin + acolor:= fo.colored.value; + end + else begin + if fo.canevent(tmethod(aoncolorchange)) then begin + aoncolorchange(fo,acolor); + end; + end; + finally + fo.free; + end; + finally + application.unlock; + end; +end; + +{ tellipsedropdownbuttonframe } + +constructor tellipsedropdownbuttonframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + inherited; + buttons.count:= 2; + buttons[1].assign(buttons[0]); + buttons[1].imagenr:= ord(stg_ellipsesmall); + buttons[0].imagenr:= ord(stg_arrowdownsmall); + activebutton:= 0; +end; + +function tellipsedropdownbuttonframe.getbuttonellipse: tdropdownbutton; +begin + result:= tdropdownbutton(buttons[1]); +end; + +procedure tellipsedropdownbuttonframe.setbuttonellipse( + const avalue: tdropdownbutton); +begin + buttons[1].assign(avalue); +end; + +{ tcolorfixcol } + +constructor tcolorfixcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); +begin + inherited; + width:= agrid.datarowheight; + ficonrect.x:= 1; + ficonrect.y:= 1; + ficonrect.cy:= width - 2; + ficonrect.cx:= ficonrect.cy; +end; + +procedure tcolorfixcol.drawcell(const canvas: tcanvas); +begin + inherited; + with cellinfoty(canvas.drawinfopo^) do begin + paintcolorrect(canvas,ficonrect, + tcolordropdowncontroller(fcontroller).fcolorvalues[cell.row]); + end; +end; + +{ tcolordropdowncontroller } + +constructor tcolordropdowncontroller.create(const intf: idropdownlist); +//var +// int1: integer; +begin + inherited; + valuelist.asarray:= getcolornames; + fcolorvalues:= getcolorvalues; + { + for int1:= 0 to high(fcolorvalues) do begin + fcolorvalues[int1]:= colorty(colortorgb(fcolorvalues[int1])); + end; + } + options:= defaultautodropdownoptions; +end; + +function tcolordropdowncontroller.getbuttonframeclass(): + dropdownbuttonframeclassty; +begin + result:= tellipsedropdownbuttonframe; +end; + +function tcolordropdowncontroller.getfixcolclass: dropdownfixcolclassty; +begin + result:= tcolorfixcol; +end; + +{ tcustomcoloredit } + +constructor tcustomcoloredit.create(aowner: tcomponent); +begin + inherited; + enums:= integerarty(getcolorvalues); + valuemin:= minint; + base:= nb_hex; + valuedefault:= cl_none; + value:= valuedefault; +end; + +function tcustomcoloredit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tcolordropdowncontroller.create(idropdownlist(self)); +end; + +procedure tcustomcoloredit.texttovalue(var accept: boolean; + const quiet: boolean); +var + co1: colorty; + int1: integer; + mstr1: msestring; +begin + if trim(text) = '' then begin + co1:= valuedefault; + end + else begin + int1:= tdropdownlistcontroller(fdropdown).itemindex; + if (int1 >= 0) and (int1 <= high(enums)) then begin + co1:= enums[int1]; + end + else begin + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + if not trystringtocolor(ansistring(mstr1),co1) then begin + accept:= false; + formaterror(quiet); + end; + end; + end; + if accept then begin + if not quiet and canevent(tmethod(fonsetvalue1)) then begin + fonsetvalue1(self,integer(co1),accept); + end; + if accept then begin + value:= co1; + end; + end; +end; + +procedure tcustomcoloredit.colorenter(const acolor: colorty); +begin + tcolordropdowncontroller(fdropdown).resetselection; + text:= msestring(colortostring(acolor)); + checkvalue(); +end; + +procedure tcustomcoloredit.buttonaction(var action: buttonactionty; + const buttonindex: integer); +var + co1: colorty; +begin + if buttonindex = 1 then begin + case action of + ba_buttonpress: begin + if canfocus then begin + setfocus; + end; + end; + ba_click: begin + if focused then begin + co1:= value; + if colordialog(co1, + @docolorchange,colordialogoptionsty(options)) = mr_ok then begin + colorenter(co1); + end; + end; + end; + end; + end; +end; + +function tcustomcoloredit.internaldatatotext1(const avalue: integer): msestring; +begin + if ceo_rgbtext in foptions then begin + result:= msestring(colortostring(colorty(colortorgb(avalue)))); + end + else begin + result:= msestring(colortostring(avalue)); + end; +end; + +function tcustomcoloredit.internaldatatotext(const data): msestring; +var + int1: integer; +begin + if @data = nil then begin + int1:= fvalue1; + end + else begin + int1:= integer(data); + end; + result:= internaldatatotext1(int1); +end; + +function tcustomcoloredit.getvalue: colorty; +begin + result:= inherited value; +end; + +procedure tcustomcoloredit.setvalue(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + inherited value:= avalue; +end; + +function tcustomcoloredit.getvaluedefault: colorty; +begin + result:= inherited valuedefault; +end; + +procedure tcustomcoloredit.setvaluedefault(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + inherited valuedefault:= avalue; +end; + +function tcustomcoloredit.getonsetvalue: setcoloreventty; +begin + result:= setcoloreventty(inherited onsetvalue); +end; + +procedure tcustomcoloredit.setonsetvalue(const avalue: setcoloreventty); +begin + inherited onsetvalue:= setintegereventty(avalue); +end; + +function tcustomcoloredit.getframe: tellipsedropdownbuttonframe; +begin + result:= tellipsedropdownbuttonframe(inherited frame); +end; + +procedure tcustomcoloredit.setframe(const avalue: tellipsedropdownbuttonframe); +begin + inherited frame:= avalue; +end; + +function tcustomcoloredit.getgridvalue(const index: integer): colorty; +begin + result:= inherited gridvalue[index]; +end; + +procedure tcustomcoloredit.setgridvalue(const index: integer; + const avalue: colorty); +begin + inherited gridvalue[index]:= avalue; +end; + +function tcustomcoloredit.getgridvalues: colorarty; +begin + result:= colorarty(inherited gridvalues); +end; + +procedure tcustomcoloredit.setgridvalues(const avalue: colorarty); +begin + inherited gridvalues:= integerarty(avalue); +end; + +procedure tcustomcoloredit.setoptions(const avalue: coloreditoptionsty); +begin + if avalue <> foptions then begin + foptions:= avalue; + formatchanged(); + end; +end; + +function tcustomcoloredit.geteditframe: framety; +begin + result.left:= innerclientsize.cy + 1; + result.right:= 0; + result.top:= 0; + result.bottom:= 0; +end; + +procedure tcustomcoloredit.paintimage(const canvas: tcanvas); +var + co1: colorty; +begin + if canvas.drawinfopo <> nil then begin + with cellinfoty(canvas.drawinfopo^) do begin + co1:= pcolorty(datapo)^; + end; + end + else begin + co1:= value; + end; + paintcolorimage(self,canvas,co1); +end; + +procedure tcustomcoloredit.dochange(); +begin + inherited; + invalidate(); + if not (des_updating in fstate) then begin + if canevent(tmethod(foncolorchange)) then begin + include(fstate,des_updating); + try + foncolorchange(self,value); + finally + exclude(fstate,des_updating); + end; + end; + end; +end; + +procedure tcustomcoloredit.docolorchange(const sender: tobject; + const acolor: colorty); +begin //callback from colordialog + if not (des_updating in fstate) then begin + include(fstate,des_updating); + try + if oe1_thumbtrack in optionsedit1 then begin + colorenter(acolor); + if canevent(tmethod(foncolorchange)) then begin + foncolorchange(sender,value); + end; + end + else begin + if canevent(tmethod(foncolorchange)) then begin + foncolorchange(sender,acolor); + end; + end; + finally + exclude(fstate,des_updating); + end; + end; +end; + +procedure tcustomcoloredit.setvaluedata(const source); +begin + value:= colorty(source); +end; + +procedure tcustomcoloredit.getvaluedata(out dest); +begin + colorty(dest):= value; +end; + +procedure paintcolorrect(const canvas: tcanvas; const arect: rectty; + const acolor: colorty); +var + co1: colorty; +begin + canvas.fillrect(arect,colorty(colortorgb(acolor))); + co1:= cl_black; + if acolor and speccolormask = cl_functional then begin + co1:= cl_gray; + end; + canvas.drawrect(arect,co1); +end; + +procedure paintcolorimage(const sender: twidget; const canvas: tcanvas; + const acolor: colorty); +var + rect1: rectty; +begin + with sender do begin + if canvas.drawinfopo <> nil then begin + with cellinfoty(canvas.drawinfopo^) do begin + rect1:= innerrect; + end; + end + else begin + rect1:= innerclientrect; + end; + rect1.x:= 1; + dec(rect1.cy); + rect1.cx:= rect1.cy; + paintcolorrect(canvas,rect1,acolor); + { + canvas.fillrect(rect1,colorty(colortorgb(acolor))); + co1:= cl_black; + if acolor and speccolormask = cl_functional then begin + co1:= cl_gray; + end; + canvas.drawrect(rect1,co1); + } + end; +end; + +{ tcolordialogfo } + +procedure tcolordialogfo.hueonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + hue.value:= round(avalue * 360); +end; + +procedure tcolordialogfo.satonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + sat.value:= round(avalue * 100); +end; + +procedure tcolordialogfo.brightonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + bright.value:= round(avalue * 100); +end; + +procedure tcolordialogfo.hsbchange(const sender: TObject); +var + r,g,b: real; + r1,g1,b1: integer; + int1: integer; + rea1,rea2: real; +begin + int1:= hue.value; + r:= 0; + g:= 0; + b:= 0; + if int1 < 60 then begin + r:= 60; + g:= int1; + end + else begin + if int1 < 120 then begin + r:= 120 - int1; + g:= 60; + end + else begin + if int1 < 180 then begin + g:= 60; + b:= int1 - 120; + end + else begin + if int1 < 240 then begin + g:= 240 - int1; + b:= 60 + end + else begin + if int1 < 300 then begin + b:= 60; + r:= int1 - 240; + end + else begin + b:= 360 - int1; + r:= 60; + end; + end; + end; + end; + end; + r1:= round(r*255/60); + g1:= round(g*255/60); + b1:= round(b*255/60); + slidersat.scrollbar.face.fade_color[1]:= rgbtocolor(r1,g1,b1); + rea1:= sat.value / 100; + rea2:= 1-rea1; + rea1:= rea1 / 60; + r:= r * rea1 + rea2; + g:= g * rea1 + rea2; + b:= b * rea1 + rea2; + r1:= round(r*255); + g1:= round(g*255); + b1:= round(b*255); + sliderbright.scrollbar.face.fade_color[1]:= rgbtocolor(r1,g1,b1); + rea1:= bright.value / 100; + r:= r*rea1; + g:= g*rea1; + b:= b*rea1; + sliderhue.value:= hue.value/360; + slidersat.value:= sat.value/100; + sliderbright.value:= bright.value/100; + if not fupdating then begin + fupdating:= true; + red.value:= round(r*255); + green.value:= round(g*255); + blue.value:= round(b*255); + fupdating:= false; + end; +end; + +procedure tcolordialogfo.blueonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + blue.value:= round(avalue * 255); +end; + +procedure tcolordialogfo.greenonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + green.value:= round(avalue * 255); +end; + +procedure tcolordialogfo.redonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + red.value:= round(avalue * 255); +end; + + +procedure tcolordialogfo.rgbchange(const sender: TObject); + +type + colorsegmentty = (cs_red,cs_green,cs_blue); +var + min,max: integer; +// r1,g1,b1: integer; + br,sa,hu: real; + segment: colorsegmentty; + + function calchue(l,c,r: integer): real; //range -1 .. +1, 0-> center + begin + if c > min then begin + if l > r then begin + result:= -(l-min)/(c-min); + end + else begin + result:= (r-min)/(c-min); + end; + end + else begin + result:= 0; + end; + end; + +begin + colorarea.frame.colorclient:= rgbtocolor(red.value,green.value,blue.value); + sliderred.value:= red.value / 255; + slidergreen.value:= green.value / 255; + sliderblue.value:= blue.value / 255; + if not fupdating then begin + fupdating:= true; + max:= 0; + segment:= cs_red; + if red.value > max then begin + max:= red.value; + end; + if green.value > max then begin + max:= green.value; + segment:= cs_green; + end; + if blue.value > max then begin + max:= blue.value; + segment:= cs_blue; + end; + min:= 255; + if red.value < min then begin + min:= red.value; + end; + if green.value < min then begin + min:= green.value; + end; + if blue.value < min then begin + min:= blue.value; + end; + br:= max/255; + if br > 0 then begin + sa:= 1-min/(255*br); + if sa < 0 then begin + sa:= 0; + end; + end + else begin + sa:= 0 + end; + bright.value:= round(br*100); + sat.value:= round(sa*100); + case segment of + cs_red: begin + hu:= calchue(blue.value,red.value,green.value); + hue.value:= (round(hu*60)+360) mod 360; + end; + cs_green: begin + hu:= calchue(red.value,green.value,blue.value); + hue.value:= round(hu*60) + 120; + end; + cs_blue: begin + hu:= calchue(green.value,blue.value,red.value); + hue.value:= (round(hu*60) + 240) mod 360; + end; + end; + fupdating:= false; + end; +end; + +procedure tcolordialogfo.updatecomponents; +var + rgb1: rgbtriplety; +begin + if not fupdating then begin + fupdating:= true; + rgb1:= rgbtriplety(rgbed.value); + red.value:= rgb1.red; + green.value:= rgb1.green; + blue.value:= rgb1.blue; + fupdating:= false; + rgbchange(nil); + end; +end; + +procedure tcolordialogfo.componentsdataentered(const sender: TObject); +begin + rgbed.value:= integer(rgbtocolor(red.value,green.value,blue.value)); + colored.value:= rgbed.value; +end; + +procedure tcolordialogfo.layoutexe(const sender: TObject); +begin + gb.height:= sliderhue.height; + colorareabefore.frameheight:= gb.height; + colorarea.frameheight:= gb.height; + aligny(wam_center,[hue,colorpibu]); +end; + +procedure tcolordialogfo.rgbeddataentered(const sender: TObject); +begin + colored.value:= colorty(rgbed.value); + updatecomponents; +end; + +procedure tcolordialogfo.coloreddataentered(const sender: TObject); +begin + rgbed.value:= integer(colortorgb(colored.value)); + updatecomponents; +end; + +procedure tcolordialogfo.loadedexe(const sender: TObject); +begin + colored.activate; +end; + +procedure tcolordialogfo.colorpickexe(const sender: TObject); +begin + begincolorpick(); +end; + +procedure tcolordialogfo.begincolorpick(); +begin + fcolorbefore:= colored.value; + capturemouse(true); + application.cursorshape:= cr_pointinghand; + colorpibu.value:= 0; + colorpibu.createfont; + with colorpibu.font do begin + color:= cl_red; + shadow_color:= cl_white; + end; + fcolorpicking:= true; +end; + +procedure tcolordialogfo.endcolorpick(); +begin + releasemouse(true); + fcolorpicking:= false; + colorpibu.value:= -1; + application.cursorshape:= cr_default; + colorpibu.font:= nil; +end; + +procedure tcolordialogfo.dochange(); +begin + if canevent(tmethod(foncolorchange)) then begin + foncolorchange(self,colored.value); + end; +end; + +procedure tcolordialogfo.mouseeventexe(const sender: twidget; + var ainfo: mouseeventinfoty); +var + px1: pixelty; + co1: colorty; +begin + if fcolorpicking then begin + if (ainfo.eventkind in [ek_buttonpress,ek_mousemove]) and + (ainfo.shiftstate * buttonshiftstatesmask = [ss_left]) then begin + if gui_getpixel(gui_getrootwindow(window.winid), + translatewidgetpoint(ainfo.pos,self,nil),px1) = gue_ok then begin + co1:= gui_pixeltorgb(px1); + if colored.value <> co1 then begin + colored.value:= co1; + colored.checkvalue(); + end; + end; + end + else begin + if (ainfo.eventkind = ek_buttonrelease) then begin + endcolorpick(); + end; + end; + end; +end; + +procedure tcolordialogfo.shortcutexe(const sender: twidget; + var ainfo: keyeventinfoty; const origin: twidget); +begin + if fcolorpicking then begin + if ainfo.key = key_escape then begin + endcolorpick(); + colored.value:= fcolorbefore; + colored.checkvalue(); + end; + include(ainfo.eventstate,es_processed); + end; +end; + +procedure tcolordialogfo.colorchangeev(const sender: TObject); +begin + dochange(); +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msecolordialog_mfm.pas b/mseide-msegui/lib/common/dialogs/msecolordialog_mfm.pas new file mode 100644 index 0000000..c6f9b66 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msecolordialog_mfm.pas @@ -0,0 +1,542 @@ +unit msecolordialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msecolordialog; + +const + objdata: record size: integer; data: array[0..10490] of byte end = + (size: 10491; data: ( + 84,80,70,48,14,116,99,111,108,111,114,100,105,97,108,111,103,102,111,13, + 99,111,108,111,114,100,105,97,108,111,103,102,111,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,140,0,8,98,111,117,110,100, + 115,95,121,3,234,0,9,98,111,117,110,100,115,95,99,120,3,82,1,9, + 98,111,117,110,100,115,95,99,121,3,42,1,26,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,18,99,111,110,116,97,105,110,101, + 114,46,111,110,108,97,121,111,117,116,7,9,108,97,121,111,117,116,101,120, + 101,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,82,1,3,42,1,0,10,111,110,115,104,111,114,116,99,117, + 116,7,11,115,104,111,114,116,99,117,116,101,120,101,7,111,112,116,105,111, + 110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,17,102,111, + 95,108,111,99,97,108,115,104,111,114,116,99,117,116,115,15,102,111,95,97, + 117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119, + 114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,0, + 8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101, + 49,7,99,97,112,116,105,111,110,6,12,83,101,108,101,99,116,32,67,111, + 108,111,114,8,111,110,108,111,97,100,101,100,7,9,108,111,97,100,101,100, + 101,120,101,12,111,110,109,111,117,115,101,101,118,101,110,116,7,13,109,111, + 117,115,101,101,118,101,110,116,101,120,101,8,111,110,108,97,121,111,117,116, + 7,9,108,97,121,111,117,116,101,120,101,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,11,116, + 100,97,116,97,98,117,116,116,111,110,9,99,111,108,111,114,112,105,98,117, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49, + 95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119, + 105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117, + 110,100,115,95,120,2,4,8,98,111,117,110,100,115,95,121,3,237,0,9, + 98,111,117,110,100,115,95,99,120,2,97,9,98,111,117,110,100,115,95,99, + 121,2,18,12,98,111,117,110,100,115,95,99,120,109,105,110,2,97,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98, + 111,116,116,111,109,0,5,115,116,97,116,101,11,17,97,115,95,108,111,99, + 97,108,105,110,118,105,115,105,98,108,101,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,16,118,97,108,117,101,102,97,99,101,115,46,99,111, + 117,110,116,2,1,16,118,97,108,117,101,102,97,99,101,115,46,105,116,101, + 109,115,14,1,14,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2, + 3,14,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1,2,0,5, + 32,226,86,222,146,80,67,218,253,63,2,1,0,16,102,97,100,101,95,99, + 111,108,111,114,46,99,111,117,110,116,2,3,16,102,97,100,101,95,99,111, + 108,111,114,46,105,116,101,109,115,1,4,0,200,255,0,4,161,235,255,0, + 4,92,170,242,0,0,14,102,97,100,101,95,100,105,114,101,99,116,105,111, + 110,7,7,103,100,95,100,111,119,110,10,108,111,99,97,108,112,114,111,112, + 115,11,15,102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,0,0, + 0,7,99,97,112,116,105,111,110,6,13,67,111,108,111,114,32,38,80,105, + 99,107,101,114,9,111,110,101,120,101,99,117,116,101,7,12,99,111,108,111, + 114,112,105,99,107,101,120,101,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,9,116,112,97,105,110,116,98,111,120,9,99,111,108, + 111,114,97,114,101,97,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 5,99,111,108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,111,112, + 116,105,111,110,115,11,17,99,102,111,95,99,97,112,116,105,111,110,110,111, + 99,108,105,112,0,16,102,114,97,109,101,46,99,111,108,111,114,102,114,97, + 109,101,4,2,0,0,160,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,18,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,3,110,101,119,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,9,99,112,95,98,111,116,116,111,109,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,14,102,114,108,95, + 99,111,108,111,114,102,114,97,109,101,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,0,2,17,0,8,116,97,98,111,114, + 100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,51,8,98,111,117, + 110,100,115,95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,3,226,0,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110,95, + 98,111,116,116,111,109,0,0,0,9,116,112,97,105,110,116,98,111,120,15, + 99,111,108,111,114,97,114,101,97,98,101,102,111,114,101,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128, + 13,102,114,97,109,101,46,111,112,116,105,111,110,115,11,17,99,102,111,95, + 99,97,112,116,105,111,110,110,111,99,108,105,112,0,16,102,114,97,109,101, + 46,99,111,108,111,114,102,114,97,109,101,4,2,0,0,160,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,12,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,111,108,100,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,9,99,112,95, + 98,111,116,116,111,109,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,14,102,114,108,95,99,111,108,111,114,102,114,97,109,101,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0, + 2,17,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100, + 115,95,120,2,3,8,98,111,117,110,100,115,95,121,2,3,9,98,111,117, + 110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,3,226, + 0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,0,0,9,116, + 108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,49,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97, + 98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111, + 99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,112,8,98,111,117,110,100,115,95,121,3,219,0,9,98,111,117, + 110,100,115,95,99,120,3,221,0,9,98,111,117,110,100,115,95,99,121,2, + 37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97, + 110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97, + 108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95, + 115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,121,0,7,108,105,110,107,116,111,112,7,10,116,108, + 97,121,111,117,116,101,114,51,10,108,105,110,107,98,111,116,116,111,109,7, + 10,116,108,97,121,111,117,116,101,114,50,7,111,112,116,105,111,110,115,11, + 15,115,112,97,111,95,103,108,117,101,98,111,116,116,111,109,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,4,98,108,117,101,5,99,111,108, + 111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,5,38,98,108,117,101,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3, + 185,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,36,9,98,111,117,110,100,115,95,99,121,2,37,8,111,110, + 99,104,97,110,103,101,7,9,114,103,98,99,104,97,110,103,101,13,111,110, + 100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111,110,101, + 110,116,115,100,97,116,97,101,110,116,101,114,101,100,3,109,97,120,3,255, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,5,103,114,101,101,110,5,99, + 111,108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,6,38,103,114,101,101,110,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,1,2,17,2,2,2, + 0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115, + 95,120,3,147,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,39,9,98,111,117,110,100,115,95,99,121,2,37, + 8,111,110,99,104,97,110,103,101,7,9,114,103,98,99,104,97,110,103,101, + 13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112, + 111,110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,3,109,97, + 120,3,255,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,3,114,101,100,5, + 99,111,108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,4,38,114,101,100,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95, + 120,2,111,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,2,36,9,98,111,117,110,100,115,95,99,121,2,37,8,111, + 110,99,104,97,110,103,101,7,9,114,103,98,99,104,97,110,103,101,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111,110, + 101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,3,109,97,120,3, + 255,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 12,116,105,110,116,101,103,101,114,101,100,105,116,6,98,114,105,103,104,116, + 5,99,111,108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,4,38,66,82,73,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2, + 0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,72,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,36,9,98,111,117,110,100,115,95,99,121,2,37,8, + 111,110,99,104,97,110,103,101,7,9,104,115,98,99,104,97,110,103,101,13, + 111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111, + 110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,3,109,97,120, + 2,100,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 12,116,105,110,116,101,103,101,114,101,100,105,116,3,115,97,116,5,99,111, + 108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,4,38,83,65,84,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 36,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,36,9,98,111,117,110,100,115,95,99,121,2,37,8,111,110,99, + 104,97,110,103,101,7,9,104,115,98,99,104,97,110,103,101,13,111,110,100, + 97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111,110,101,110, + 116,115,100,97,116,97,101,110,116,101,114,101,100,3,109,97,120,2,100,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,3,104,117,101,5,99,111,108,111,114, + 4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 4,38,72,85,69,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,36,9,98,111,117,110,100,115,95,99,121, + 2,37,8,111,110,99,104,97,110,103,101,7,9,104,115,98,99,104,97,110, + 103,101,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111, + 109,112,111,110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,3, + 109,97,120,3,104,1,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121, + 111,117,116,101,114,50,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114, + 101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111, + 119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,8,98,111,117,110,100,115,95,120,2,11, + 8,98,111,117,110,100,115,95,121,3,0,1,9,98,111,117,110,100,115,95, + 99,120,3,68,1,9,98,111,117,110,100,115,95,99,121,2,38,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111, + 116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11, + 111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105, + 110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95, + 115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100,115,104, + 114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105, + 110,107,121,0,9,102,111,110,116,46,110,97,109,101,6,11,115,116,102,95, + 100,101,102,97,117,108,116,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95,103, + 108,117,101,7,9,119,97,109,95,115,116,97,114,116,7,108,105,110,107,116, + 111,112,7,10,116,108,97,121,111,117,116,101,114,49,7,111,112,116,105,111, + 110,115,11,15,115,112,97,111,95,103,108,117,101,98,111,116,116,111,109,0, + 0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116, + 111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104, + 0,5,99,111,108,111,114,4,3,0,0,128,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,3,16,1,8,98,111,117,110, + 100,115,95,121,2,17,9,98,111,117,110,100,115,95,99,120,2,52,9,98, + 111,117,110,100,115,95,99,121,2,21,12,98,111,117,110,100,115,95,99,120, + 109,105,110,2,50,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,13,97,115,95,108,111,99,97,108,99,111,108, + 111,114,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108, + 11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110, + 99,101,108,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,7,116,98,117,116,116,111,110,2,111,107,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,3,216,0,8,98,111,117,110,100,115,95,121,2,17,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 21,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15, + 97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110, + 6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109, + 114,95,111,107,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,10,116,99,111,108,111,114,101,100,105,116,7,99,111,108,111,114,101, + 100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5,67,111,108, + 111,114,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,25,102,114,97,109,101,46,98,117,116,116,111,110,101, + 108,108,105,112,115,101,46,119,105,100,116,104,2,255,27,102,114,97,109,101, + 46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,105,109,97,103,101, + 110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,2,102,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,108,9,98,111,117, + 110,100,115,95,99,121,2,37,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114, + 101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108,105,112,112, + 101,100,116,101,120,116,0,8,111,110,99,104,97,110,103,101,7,13,99,111, + 108,111,114,99,104,97,110,103,101,101,118,13,111,110,100,97,116,97,101,110, + 116,101,114,101,100,7,18,99,111,108,111,114,101,100,100,97,116,97,101,110, + 116,101,114,101,100,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111, + 110,115,11,16,100,101,111,95,97,117,116,111,100,114,111,112,100,111,119,110, + 15,100,101,111,95,107,101,121,100,114,111,112,100,111,119,110,12,100,101,111, + 95,99,108,105,112,104,105,110,116,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,5,114,103,98,101,100,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,3,82,71,66,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,98,111, + 117,110,100,115,95,120,2,32,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,68,9,98,111,117,110,100,115,95,99, + 121,2,37,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,16,114, + 103,98,101,100,100,97,116,97,101,110,116,101,114,101,100,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,24,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116, + 108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,51,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97, + 98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111, + 99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,112,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,221,0,9,98,111,117,110,100,115,95,99,121,3,219, + 0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111, + 95,97,108,105,103,110,121,0,10,97,108,105,103,110,95,109,111,100,101,7, + 9,119,97,109,95,115,116,97,114,116,0,7,116,115,108,105,100,101,114,10, + 115,108,105,100,101,114,98,108,117,101,5,99,111,108,111,114,4,2,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,1,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,10,102,114,108,95,102,105,108,101,102,116,9, + 102,114,108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103,104, + 116,12,102,114,108,95,102,105,98,111,116,116,111,109,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,5,8,98,111,117,110,100,115,95,120,3,196,0,8,98,111,117,110,100, + 115,95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,15,9,98,111, + 117,110,100,115,95,99,121,3,214,0,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110,95,98,111, + 116,116,111,109,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7, + 21,99,111,109,112,111,110,101,110,116,115,100,97,116,97,101,110,116,101,114, + 101,100,5,118,97,108,117,101,2,0,37,115,99,114,111,108,108,98,97,114, + 46,102,97,99,101,46,105,109,97,103,101,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,0,0,0,128,29,115,99,114,111,108,108, + 98,97,114,46,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111, + 117,110,116,2,2,29,115,99,114,111,108,108,98,97,114,46,102,97,99,101, + 46,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1, + 0,31,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100, + 101,95,99,111,108,111,114,46,99,111,117,110,116,2,2,31,115,99,114,111, + 108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111, + 114,46,105,116,101,109,115,1,4,2,0,0,160,4,9,0,0,160,0,29, + 115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95, + 100,105,114,101,99,116,105,111,110,7,5,103,100,95,117,112,25,115,99,114, + 111,108,108,98,97,114,46,102,97,99,101,46,108,111,99,97,108,112,114,111, + 112,115,11,15,102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,13, + 102,97,108,95,102,97,111,112,97,99,105,116,121,0,15,115,99,114,111,108, + 108,98,97,114,46,99,111,108,111,114,4,3,0,0,128,22,115,99,114,111, + 108,108,98,97,114,46,99,111,108,111,114,112,97,116,116,101,114,110,4,6, + 0,0,128,10,111,110,115,101,116,118,97,108,117,101,7,14,98,108,117,101, + 111,110,115,101,116,118,97,108,117,101,9,100,105,114,101,99,116,105,111,110, + 7,5,103,100,95,117,112,0,0,7,116,115,108,105,100,101,114,11,115,108, + 105,100,101,114,103,114,101,101,110,5,99,111,108,111,114,4,2,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,1,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,10,102,114,108,95,102,105,108,101,102,116,9,102, + 114,108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103,104,116, + 12,102,114,108,95,102,105,98,111,116,116,111,109,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 4,8,98,111,117,110,100,115,95,120,3,160,0,8,98,111,117,110,100,115, + 95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,15,9,98,111,117, + 110,100,115,95,99,121,3,214,0,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110,95,98,111,116, + 116,111,109,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,21, + 99,111,109,112,111,110,101,110,116,115,100,97,116,97,101,110,116,101,114,101, + 100,5,118,97,108,117,101,2,0,37,115,99,114,111,108,108,98,97,114,46, + 102,97,99,101,46,105,109,97,103,101,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,0,0,0,128,29,115,99,114,111,108,108,98, + 97,114,46,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117, + 110,116,2,2,29,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46, + 102,97,100,101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0, + 31,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101, + 95,99,111,108,111,114,46,99,111,117,110,116,2,2,31,115,99,114,111,108, + 108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114, + 46,105,116,101,109,115,1,4,2,0,0,160,4,8,0,0,160,0,29,115, + 99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,100, + 105,114,101,99,116,105,111,110,7,5,103,100,95,117,112,25,115,99,114,111, + 108,108,98,97,114,46,102,97,99,101,46,108,111,99,97,108,112,114,111,112, + 115,11,15,102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,13,102, + 97,108,95,102,97,111,112,97,99,105,116,121,0,15,115,99,114,111,108,108, + 98,97,114,46,99,111,108,111,114,4,3,0,0,128,22,115,99,114,111,108, + 108,98,97,114,46,99,111,108,111,114,112,97,116,116,101,114,110,4,6,0, + 0,128,10,111,110,115,101,116,118,97,108,117,101,7,15,103,114,101,101,110, + 111,110,115,101,116,118,97,108,117,101,9,100,105,114,101,99,116,105,111,110, + 7,5,103,100,95,117,112,0,0,7,116,115,108,105,100,101,114,9,115,108, + 105,100,101,114,114,101,100,5,99,111,108,111,114,4,2,0,0,128,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,1,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,10,102,114,108,95,102,105,108,101,102,116,9,102,114,108, + 95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103,104,116,12,102, + 114,108,95,102,105,98,111,116,116,111,109,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,2,124,8,98,111,117,110,100,115,95,121,2, + 3,9,98,111,117,110,100,115,95,99,120,2,15,9,98,111,117,110,100,115, + 95,99,121,3,214,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109, + 112,111,110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,5,118, + 97,108,117,101,2,0,37,115,99,114,111,108,108,98,97,114,46,102,97,99, + 101,46,105,109,97,103,101,46,116,114,97,110,115,112,97,114,101,110,116,99, + 111,108,111,114,4,0,0,0,128,29,115,99,114,111,108,108,98,97,114,46, + 102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2, + 2,29,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100, + 101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,31,115,99, + 114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,99,111, + 108,111,114,46,99,111,117,110,116,2,2,31,115,99,114,111,108,108,98,97, + 114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116, + 101,109,115,1,4,2,0,0,160,4,7,0,0,160,0,29,115,99,114,111, + 108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,100,105,114,101, + 99,116,105,111,110,7,5,103,100,95,117,112,25,115,99,114,111,108,108,98, + 97,114,46,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15, + 102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,13,102,97,108,95, + 102,97,111,112,97,99,105,116,121,0,15,115,99,114,111,108,108,98,97,114, + 46,99,111,108,111,114,4,3,0,0,128,22,115,99,114,111,108,108,98,97, + 114,46,99,111,108,111,114,112,97,116,116,101,114,110,4,6,0,0,128,10, + 111,110,115,101,116,118,97,108,117,101,7,13,114,101,100,111,110,115,101,116, + 118,97,108,117,101,9,100,105,114,101,99,116,105,111,110,7,5,103,100,95, + 117,112,0,0,7,116,115,108,105,100,101,114,12,115,108,105,100,101,114,98, + 114,105,103,104,116,5,99,111,108,111,114,4,2,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,1,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,10,102,114,108,95,102,105,108,101,102,116,9,102,114,108,95,102, + 105,116,111,112,11,102,114,108,95,102,105,114,105,103,104,116,12,102,114,108, + 95,102,105,98,111,116,116,111,109,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,83,8,98,111,117,110,100,115,95,121,2,3,9, + 98,111,117,110,100,115,95,99,120,2,15,9,98,111,117,110,100,115,95,99, + 121,3,214,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,13, + 111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111, + 110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,5,118,97,108, + 117,101,2,0,37,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46, + 105,109,97,103,101,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,0,0,0,128,29,115,99,114,111,108,108,98,97,114,46,102,97, + 99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,29, + 115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95, + 112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,31,115,99,114,111, + 108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111, + 114,46,99,111,117,110,116,2,2,31,115,99,114,111,108,108,98,97,114,46, + 102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109, + 115,1,4,2,0,0,160,4,6,0,0,160,0,29,115,99,114,111,108,108, + 98,97,114,46,102,97,99,101,46,102,97,100,101,95,100,105,114,101,99,116, + 105,111,110,7,5,103,100,95,117,112,25,115,99,114,111,108,108,98,97,114, + 46,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,97, + 108,95,102,97,100,105,114,101,99,116,105,111,110,13,102,97,108,95,102,97, + 111,112,97,99,105,116,121,0,15,115,99,114,111,108,108,98,97,114,46,99, + 111,108,111,114,4,3,0,0,128,22,115,99,114,111,108,108,98,97,114,46, + 99,111,108,111,114,112,97,116,116,101,114,110,4,6,0,0,128,10,111,110, + 115,101,116,118,97,108,117,101,7,16,98,114,105,103,104,116,111,110,115,101, + 116,118,97,108,117,101,9,100,105,114,101,99,116,105,111,110,7,5,103,100, + 95,117,112,0,0,7,116,115,108,105,100,101,114,9,115,108,105,100,101,114, + 115,97,116,5,99,111,108,111,114,4,2,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,1,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,10,102,114,108,95,102,105,108,101,102,116,9,102,114,108,95,102,105,116, + 111,112,11,102,114,108,95,102,105,114,105,103,104,116,12,102,114,108,95,102, + 105,98,111,116,116,111,109,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,48,8,98,111,117,110,100,115,95,121,2,3,9,98,111, + 117,110,100,115,95,99,120,2,15,9,98,111,117,110,100,115,95,99,121,3, + 214,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,13,111,110, + 100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111,110,101, + 110,116,115,100,97,116,97,101,110,116,101,114,101,100,5,118,97,108,117,101, + 2,0,37,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,105,109, + 97,103,101,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,0,0,0,128,29,115,99,114,111,108,108,98,97,114,46,102,97,99,101, + 46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,29,115,99, + 114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,112,111, + 115,46,105,116,101,109,115,1,2,0,2,1,0,31,115,99,114,111,108,108, + 98,97,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46, + 99,111,117,110,116,2,2,31,115,99,114,111,108,108,98,97,114,46,102,97, + 99,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1, + 4,6,0,0,160,4,6,0,0,160,0,29,115,99,114,111,108,108,98,97, + 114,46,102,97,99,101,46,102,97,100,101,95,100,105,114,101,99,116,105,111, + 110,7,5,103,100,95,117,112,25,115,99,114,111,108,108,98,97,114,46,102, + 97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,97,108,95, + 102,97,100,105,114,101,99,116,105,111,110,13,102,97,108,95,102,97,111,112, + 97,99,105,116,121,0,15,115,99,114,111,108,108,98,97,114,46,99,111,108, + 111,114,4,3,0,0,128,22,115,99,114,111,108,108,98,97,114,46,99,111, + 108,111,114,112,97,116,116,101,114,110,4,6,0,0,128,10,111,110,115,101, + 116,118,97,108,117,101,7,13,115,97,116,111,110,115,101,116,118,97,108,117, + 101,9,100,105,114,101,99,116,105,111,110,7,5,103,100,95,117,112,0,0, + 7,116,115,108,105,100,101,114,9,115,108,105,100,101,114,104,117,101,5,99, + 111,108,111,114,4,2,0,0,128,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,1,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108, + 95,102,105,108,101,102,116,9,102,114,108,95,102,105,116,111,112,11,102,114, + 108,95,102,105,114,105,103,104,116,12,102,114,108,95,102,105,98,111,116,116, + 111,109,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 98,111,117,110,100,115,95,120,2,12,8,98,111,117,110,100,115,95,121,2, + 3,9,98,111,117,110,100,115,95,99,120,2,15,9,98,111,117,110,100,115, + 95,99,121,3,214,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109, + 112,111,110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,5,118, + 97,108,117,101,2,0,37,115,99,114,111,108,108,98,97,114,46,102,97,99, + 101,46,105,109,97,103,101,46,116,114,97,110,115,112,97,114,101,110,116,99, + 111,108,111,114,4,0,0,0,128,29,115,99,114,111,108,108,98,97,114,46, + 102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2, + 7,29,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100, + 101,95,112,111,115,46,105,116,101,109,115,1,2,0,5,145,186,162,54,159, + 170,170,170,252,63,5,164,174,168,205,167,170,170,170,253,63,5,0,0,0, + 0,0,0,0,128,254,63,5,106,210,150,8,142,170,170,170,254,63,5,53, + 105,75,4,71,85,85,213,254,63,2,1,0,31,115,99,114,111,108,108,98, + 97,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46,99, + 111,117,110,116,2,7,31,115,99,114,111,108,108,98,97,114,46,102,97,99, + 101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1,4, + 7,0,0,160,4,12,0,0,160,4,8,0,0,160,4,10,0,0,160,4, + 9,0,0,160,4,11,0,0,160,4,7,0,0,160,0,29,115,99,114,111, + 108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,100,105,114,101, + 99,116,105,111,110,7,5,103,100,95,117,112,25,115,99,114,111,108,108,98, + 97,114,46,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15, + 102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,13,102,97,108,95, + 102,97,111,112,97,99,105,116,121,0,15,115,99,114,111,108,108,98,97,114, + 46,99,111,108,111,114,4,3,0,0,128,22,115,99,114,111,108,108,98,97, + 114,46,99,111,108,111,114,112,97,116,116,101,114,110,4,6,0,0,128,10, + 111,110,115,101,116,118,97,108,117,101,7,13,104,117,101,111,110,115,101,116, + 118,97,108,117,101,9,100,105,114,101,99,116,105,111,110,7,5,103,100,95, + 117,112,0,0,0,9,116,103,114,111,117,112,98,111,120,2,103,98,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,17,111,119,95,112,97,114, + 101,110,116,116,97,98,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,10,111,115,107,95,110,111,115,107,105,110,0, + 5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 10,102,114,108,95,108,101,118,101,108,105,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,2,3,8,98,111,117,110,100, + 115,95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,100,9,98,111, + 117,110,100,115,95,99,121,3,209,0,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110,95,98,111, + 116,116,111,109,0,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115, + 116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,15,99, + 111,108,111,114,100,105,97,108,111,103,46,115,116,97,7,111,112,116,105,111, + 110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116, + 2,24,3,116,111,112,2,104,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcolordialogfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msedialog.pas b/mseide-msegui/lib/common/dialogs/msedialog.pas new file mode 100644 index 0000000..e602fc8 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedialog.pas @@ -0,0 +1,673 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedialog; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface + +uses + mseclasses,msegui,mseglob,mseguiglob, + mseforms,msedataedits,mseedit,classes,mclasses,mseevent, + msemenus,msestrings,mseeditglob,msetypes,msegraphics; + +type + tdialogform = class(tmseform) + protected + procedure updatewindowinfo(var info: windowinfoty); override; + class function hasresource: boolean; override; + end; + + tdialog = class(tmsecomponent) + public + function execute: modalresultty; virtual; abstract; + end; + + tellipsebuttonframe = class(tmultibuttonframe) + private + function getbutton: tstockglyphframebutton; + procedure setbutton(const avalue: tstockglyphframebutton); + public + constructor create(const aintf: icaptionframe; + const buttonintf: ibutton); reintroduce; + published + property button: tstockglyphframebutton read getbutton write setbutton; + end; + + tdataeditcontroller = class(teventpersistent) + end; + + tdialogcontroller = class(tdataeditcontroller,ibutton,idataeditcontroller) + protected + fowner: tcustomdataedit; + procedure internalexecute; virtual; abstract; + function iskeyexecute(const info: keyeventinfoty): boolean; virtual; + //ibutton + procedure buttonaction(var action: buttonactionty; const buttonindex: integer); + + //idataeditcontroller + procedure mouseevent(var info: mouseeventinfoty); virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty); virtual; + procedure dokeydown(var info: keyeventinfoty); virtual; + procedure updatereadonlystate; virtual; + procedure internalcreateframe; virtual; + procedure editnotification(var info: editnotificationinfoty); virtual; + public + constructor create(const aowner: tcustomdataedit); reintroduce; + end; + + stringdialogexeceventty = procedure(const sender: tcustomdataedit; + var avalue:msestring; var modresult: modalresultty) of object; + //default mr_ok + tstringdialogcontroller = class(tdialogcontroller) + protected + fonexecute: stringdialogexeceventty; + procedure internalexecute; override; + function execute(var avalue: msestring): boolean; virtual; + procedure setexecresult(var avalue: msestring); virtual; + public + constructor create(const aowner: tcustomstringedit); + property onexecute: stringdialogexeceventty read fonexecute write fonexecute; + end; + + tcustomdialogstringed = class(tstringedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + protected + fdialogcontroller: tdialogcontroller; + function createdialogcontroller: tstringdialogcontroller; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + end; + + tdialogstringed = class(tcustomdialogstringed) + published + property frame; + property passwordchar; + property maxlength; + property value; + property onsetvalue; + end; + + tcustomdialogstringedit = class(tcustomdialogstringed) + private + function getonexecute: stringdialogexeceventty; + procedure setonexecute(const avalue: stringdialogexeceventty); + protected +// function execute(var avalue: msestring): boolean; override; + public + property onexecute: stringdialogexeceventty read getonexecute + write setonexecute; + end; + + tdialogstringedit = class(tcustomdialogstringedit) + published + property onexecute; + end; + + realdialogexeceventty = procedure(const sender: tcustomdataedit; + var avalue: realty; var modresult: modalresultty) of object; + //default mr_ok + trealdialogcontroller = class(tdialogcontroller) + private + protected + fonexecute: realdialogexeceventty; + procedure internalexecute; override; + function execute(var avalue: realty): boolean; virtual; + procedure setexecresult(var avalue: realty); virtual; + public + constructor create(const aowner: tcustomrealedit); + property onexecute: realdialogexeceventty read fonexecute write fonexecute; + end; + + tdialogrealedit = class(trealedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: realdialogexeceventty; + procedure setonexecute(const avalue: realdialogexeceventty); + protected + fdialogcontroller: trealdialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: realdialogexeceventty read getonexecute + write setonexecute; + end; + + datetimedialogexeceventty = procedure(const sender: tcustomdataedit; + var avalue: tdatetime; var modresult: modalresultty) of object; + //default mr_ok + tdatetimedialogcontroller = class(tdialogcontroller) + private + protected + fonexecute: datetimedialogexeceventty; + procedure internalexecute; override; + function execute(var avalue: tdatetime): boolean; virtual; + procedure setexecresult(var avalue: tdatetime); virtual; + public + constructor create(const aowner: tcustomdatetimeedit); + property onexecute: datetimedialogexeceventty read fonexecute write fonexecute; + end; + + tdialogdatetimeedit = class(tdatetimeedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: datetimedialogexeceventty; + procedure setonexecute(const avalue: datetimedialogexeceventty); + protected + fdialogcontroller: tdatetimedialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: datetimedialogexeceventty read getonexecute + write setonexecute; + end; + + integerdialogexeceventty = procedure(const sender: tcustomdataedit; + var avalue: integer; var modresult: modalresultty) of object; + //default mr_ok + tintegerdialogcontroller = class(tdialogcontroller) + private + protected + fonexecute: integerdialogexeceventty; + procedure internalexecute; override; + function execute(var avalue: integer): boolean; virtual; + procedure setexecresult(var avalue: integer); virtual; + public + constructor create(const aowner: tcustomintegeredit); + property onexecute: integerdialogexeceventty read fonexecute write fonexecute; + end; + + tdialogintegeredit = class(tintegeredit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: integerdialogexeceventty; + procedure setonexecute(const avalue: integerdialogexeceventty); + protected + fdialogcontroller: tintegerdialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: integerdialogexeceventty read getonexecute + write setonexecute; + end; + + +implementation +uses + msestockobjects,msekeyboard,mseformatstr,msereal,sysutils; + +type + tcustomdataedit1 = class(tcustomdataedit); + tcustomrealedit1 = class(tcustomrealedit); + tcustomdatetimeedit1 = class(tcustomdatetimeedit); + tcustomintegeredit1 = class(tcustomintegeredit); + tcustomstringedit1 = class(tcustomstringedit); + +{ tdialogform } + +procedure tdialogform.updatewindowinfo(var info: windowinfoty); +begin + inherited; + info.options:= [wo_message]; +end; + +class function tdialogform.hasresource: boolean; +begin + result:= false; +end; + +{ tellipsebuttonframe } + +constructor tellipsebuttonframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + inherited; +// buttons.count:= 1; + with buttons[0] do begin + imagelist:= stockobjects.glyphs; + imagenr:= ord(stg_ellipsesmall); + end; +end; + +function tellipsebuttonframe.getbutton: tstockglyphframebutton; +begin + result:= tstockglyphframebutton(inherited getbutton()); +end; + +procedure tellipsebuttonframe.setbutton(const avalue: tstockglyphframebutton); +begin + inherited setbutton(avalue); +end; + +{ tdialogcontroller } + +constructor tdialogcontroller.create(const aowner: tcustomdataedit); +begin + fowner:= aowner; + tcustomdataedit1(fowner).fcontrollerintf:= idataeditcontroller(self); + internalcreateframe; +end; + +procedure tdialogcontroller.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + with fowner do begin + if action = ba_click then begin + if canfocus and not setfocus then begin + exit; + end; + internalexecute; + end; + end; +end; + +procedure tdialogcontroller.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if iskeyexecute(info) then begin + include(info.eventstate,es_processed); + internalexecute; + end; + end; +end; + +function tdialogcontroller.iskeyexecute(const info: keyeventinfoty): boolean; +begin + with fowner,info do begin + result:= (not readonly or (oe1_readonlydialog in optionsedit1)) and + (oe1_keyexecute in optionsedit1) and (key = key_down) and + (shiftstate = [ss_alt]); + end; +end; + +procedure tdialogcontroller.updatereadonlystate; +begin + with tcustomdataedit1(fowner) do begin + if fframe <> nil then begin + with tcustombuttonframe(fframe) do begin + if buttons.count > 0 then begin + buttons[0].enabled:= not (oe_readonly in getoptionsedit) or + (oe1_readonlydialog in optionsedit1); + end; + end; + end; + end; +end; + +procedure tdialogcontroller.internalcreateframe; +begin + tellipsebuttonframe.create(iscrollframe(fowner),ibutton(self)); + updatereadonlystate; +end; + +procedure tdialogcontroller.mouseevent(var info: mouseeventinfoty); +begin + with tcustomdataedit1(fowner) do begin + tcustombuttonframe(fframe).mouseevent(info); + end; +end; + +procedure tdialogcontroller.domousewheelevent(var info: mousewheeleventinfoty); +begin + //dummy +end; + +procedure tdialogcontroller.editnotification(var info: editnotificationinfoty); +begin + //dummy +end; + +{ tstringdialogcontroller } + +constructor tstringdialogcontroller.create(const aowner: tcustomstringedit); +begin + inherited create(aowner); +end; + +procedure tstringdialogcontroller.internalexecute; +var + str1: msestring; +begin + with tcustomstringedit(fowner) do begin + str1:= text; + if execute(str1) and not readonly then begin + setexecresult(str1); + checkvalue; + end; + end; +end; + +function tstringdialogcontroller.execute(var avalue: msestring): boolean; +var + mr1: modalresultty; +begin + if fowner.canevent(tmethod(fonexecute)) then begin + mr1:= mr_ok; + fonexecute(fowner,avalue,mr1); + result:= mr1 = mr_ok; + end + else begin + result:= false; + end; +end; + +procedure tstringdialogcontroller.setexecresult(var avalue: msestring); +begin + with tcustomstringedit1(fowner) do begin + text:= avalue; //setcurrenttext(avalue); + end; +end; + +{ tcustomdialogstringed } + +constructor tcustomdialogstringed.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= createdialogcontroller; + end; +// fbuttonintf:= ibutton(fcontroller); +// inherited; +// internalcreateframe; +end; + +destructor tcustomdialogstringed.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tcustomdialogstringed.createdialogcontroller: tstringdialogcontroller; +begin + result:= tstringdialogcontroller.create(self); +end; + +function tcustomdialogstringed.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tcustomdialogstringed.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tcustomdialogstringedit.getonexecute: stringdialogexeceventty; +begin + result:= tstringdialogcontroller(fdialogcontroller).onexecute; +end; + +procedure tcustomdialogstringedit.setonexecute(const avalue: stringdialogexeceventty); +begin + tstringdialogcontroller(fdialogcontroller).onexecute:= avalue; +end; + +{ trealdialogcontroller } + +constructor trealdialogcontroller.create(const aowner: tcustomrealedit); +begin + inherited create(aowner); +end; + +procedure trealdialogcontroller.internalexecute; +var + rea1: realty; + bo1: boolean; +begin + with tcustomrealedit1(fowner) do begin + bo1:= true; + rea1:= gettextvalue(bo1,false); + if bo1 and execute(rea1) then begin + setexecresult(rea1); + checkvalue; + end; + end; +end; + +function trealdialogcontroller.execute(var avalue: realty): boolean; +var + mr1: modalresultty; +begin + if fowner.canevent(tmethod(fonexecute)) then begin + mr1:= mr_ok; + fonexecute(fowner,avalue,mr1); + result:= mr1 = mr_ok; + end + else begin + result:= false; + end; +end; + +procedure trealdialogcontroller.setexecresult(var avalue: realty); +begin + with tcustomrealedit(fowner) do begin + text:= realtytostrrange(avalue,formatedit,valuerange,valuestart); + end; +end; + +{ tdialogrealedit } + +constructor tdialogrealedit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= trealdialogcontroller.create(self); + end; +end; + +destructor tdialogrealedit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdialogrealedit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdialogrealedit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdialogrealedit.getonexecute: realdialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdialogrealedit.setonexecute(const avalue: realdialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +{ tdatetimedialogcontroller } + +constructor tdatetimedialogcontroller.create(const aowner: tcustomdatetimeedit); +begin + inherited create(aowner); +end; + +procedure tdatetimedialogcontroller.internalexecute; +var + dat1: tdatetime; + bo1: boolean; +begin + with tcustomdatetimeedit1(fowner) do begin + bo1:= true; + dat1:= gettextvalue(bo1,false); + if bo1 and execute(dat1) then begin + setexecresult(dat1); + checkvalue; + end; + end; +end; + +function tdatetimedialogcontroller.execute(var avalue: tdatetime): boolean; +var + mr1: modalresultty; +begin + if fowner.canevent(tmethod(fonexecute)) then begin + mr1:= mr_ok; + fonexecute(fowner,avalue,mr1); + result:= mr1 = mr_ok; + end + else begin + result:= false; + end; +end; + +procedure tdatetimedialogcontroller.setexecresult(var avalue: tdatetime); +begin + with tcustomdatetimeedit(fowner) do begin + case kind of + dtk_time: begin + text:= mseformatstr.timetostring(avalue,formatedit); + end; + dtk_date: begin + text:= mseformatstr.datetostring(avalue,formatedit); + end; + else begin + text:= mseformatstr.datetimetostring(avalue,formatedit); + end; + end; + end; +end; + +{ tdialogdatetimeedit } + +constructor tdialogdatetimeedit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= tdatetimedialogcontroller.create(self); + end; +end; + +destructor tdialogdatetimeedit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdialogdatetimeedit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdialogdatetimeedit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdialogdatetimeedit.getonexecute: datetimedialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdialogdatetimeedit.setonexecute(const avalue: datetimedialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +{ tintegerdialogcontroller } + +constructor tintegerdialogcontroller.create(const aowner: tcustomintegeredit); +begin + inherited create(aowner); +end; + +procedure tintegerdialogcontroller.internalexecute; +var + int1: integer; + bo1: boolean; +begin + with tcustomintegeredit1(fowner) do begin + bo1:= true; + int1:= gettextvalue(bo1,false); + if bo1 and execute(int1) then begin + setexecresult(int1); + checkvalue; + end; + end; +end; + +function tintegerdialogcontroller.execute(var avalue: integer): boolean; +var + mr1: modalresultty; +begin + if fowner.canevent(tmethod(fonexecute)) then begin + mr1:= mr_ok; + fonexecute(fowner,avalue,mr1); + result:= mr1 = mr_ok; + end + else begin + result:= false; + end; +end; + +procedure tintegerdialogcontroller.setexecresult(var avalue: integer); +begin + with tcustomintegeredit(fowner) do begin + text:= inttostrmse(avalue); + end; +end; + +{ tdialogintegeredit } + +constructor tdialogintegeredit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= tintegerdialogcontroller.create(self); + end; +end; + +destructor tdialogintegeredit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdialogintegeredit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdialogintegeredit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdialogintegeredit.getonexecute: integerdialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdialogintegeredit.setonexecute(const avalue: integerdialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msedirtree.mfm b/mseide-msegui/lib/common/dialogs/msedirtree.mfm new file mode 100644 index 0000000..d628508 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtree.mfm @@ -0,0 +1,70 @@ +object dirtreefo: tdirtreefo + visible = False + bounds_x = 80 + bounds_y = 374 + bounds_cx = 300 + bounds_cy = 203 + bounds_cxmin = 200 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 300 + 203 + ) + optionswindow = [wo_popup, wo_buttonendmodal] + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat] + moduleclassname = 'tmseform' + object grid: twidgetgrid + frame.levelo = 0 + frame.framewidth = 1 + frame.colorframe = -1610612734 + frame.localprops = [frl_levelo, frl_framewidth, frl_colorframe] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 300 + bounds_cy = 203 + anchors = [] + datacols.count = 1 + datacols.items = < + item[treeitem] + linewidth = 0 + colorfocused = -1879048185 + width = 298 + options = [co_readonly, co_fill, co_savevalue] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autocolwidth] + widgetname = 'treeitem' + dataclass = ttreeitemeditlist + datalist.imagelist = filedialogres.images + datalist.imagewidth = 16 + datalist.imageheight = 16 + datalist.onitemnotification = treeitemonitemnotification + datalist.oncreateitem = treeitemoncreateitem + end> + datarowlinewidth = 0 + datarowheight = 16 + reffontheight = 14 + object treeitem: ttreeitemedit + optionsskin = [osk_framebuttononly] + cursor = cr_arrow + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 298 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_forcereturncheckvalue, oe_hintclippedtext, oe_locate] + ondataentered = treeitemondataentered + oncellevent = treeitemoncellevent + options = [teo_treecolnavig, teo_enteronimageclick] + reffontheight = 14 + end + end +end diff --git a/mseide-msegui/lib/common/dialogs/msedirtree.pas b/mseide-msegui/lib/common/dialogs/msedirtree.pas new file mode 100644 index 0000000..6b5290f --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtree.pas @@ -0,0 +1,514 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedirtree; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseforms,msewidgetgrid,mselistbrowser,msedatanodes,msefileutils,msetypes, + msestrings,msegui,mseglob,mseclasses,msegrids,msesys,msegridsglob, + mseapplication,msebitmap,msedataedits,mseedit,msegraphics,msesizingform, + msegraphutils,mseguiglob,mseificomp,mseificompglob,mseifiglob,msemenus,msestat, + msestatfile,msestream,sysutils; +type + + tdirlistitem = class(ttreelistedititem) + private + finfo: fileinfoty; + froot: filenamety; + protected + flistonly: boolean; + procedure updateinfo; + public + constructor create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); override; + procedure setentries(const list: tcustomfiledatalist; + const achecksubdirectories,ashowhidden,acheckbox: boolean); + function findsubdir(const aname: filenamety): tdirlistitem; + function getpath: filenamety; + end; + + dirlistitemarty = array of tdirlistitem; + + dirtreeoptionty = (dto_casesensitive,dto_showhiddenfiles, + dto_checksubdir,dto_checkbox, + dto_nocollapseclear, //normally collapsed nodes are freed + //if dto_checkbox is not set + dto_expandonclick,dto_expandondblclick); + dirtreeoptionsty = set of dirtreeoptionty; + + tdirtreefo = class(tsizingform) + grid: twidgetgrid; + treeitem: ttreeitemedit; + procedure treeitemoncreateitem(const sender: tcustomitemlist; + var item: ttreelistedititem); virtual; + procedure treeitemonitemnotification(const sender: tlistitem; + var action: nodeactionty); virtual; + procedure treeitemondataentered(const sender: tobject); virtual; + procedure treeitemoncellevent(const sender: tobject; + var info: celleventinfoty); virtual; + private +// fshowhiddenfiles: boolean; +// fcasesensitive: boolean; +// fpath: filenamety; + fonpathchanged: notifyeventty; +// fchecksubdir: boolean; + foptionsdir: dirtreeoptionsty; +// fchecksubdir: boolean; + fonselctionchanged: listitemeventty; + fonselectionchanged: listitemeventty; + procedure setpath(const avalue: filenamety); + function getpath: filenamety; + procedure adddir(const aitem: tdirlistitem); + function getshowhiddenfiles: boolean; + procedure setshowhiddenfiles(const avalue: boolean); + function getcasesensitive: boolean; + procedure setcasesensitive(const avalue: boolean); + function getchecksubdir: boolean; + procedure setchecksubdir(const avalue: boolean); + procedure setroot(const avalue: filenamety); + protected + fpath: filenamety; + froot: filenamety; + frootitem: tdirlistitem; + procedure updatepath(); + procedure doondataentered(); virtual; + public + destructor destroy(); override; + function getcheckednodes(const amode: getnodemodety = + gno_nochildren): dirlistitemarty; + function getcheckedfilenames(const amode: getnodemodety = + gno_nochildren): filenamearty; + property casesensitive: boolean read getcasesensitive write setcasesensitive; + property showhiddenfiles: boolean read getshowhiddenfiles + write setshowhiddenfiles; + property checksubdir: boolean read getchecksubdir write setchecksubdir; + property path: filenamety read getpath write setpath; + property root: filenamety read froot write setroot; + property optionsdir: dirtreeoptionsty read foptionsdir + write foptionsdir default []; + property onpathchanged: notifyeventty read fonpathchanged + write fonpathchanged; + property onselectionchanged: listitemeventty read fonselctionchanged + write fonselectionchanged; + end; +{ + tdiredit = class(tstringedit) + private + end; +} +//var +// dirtreefo: tdirtreefo; + +implementation +uses + msedirtree_mfm,msesysintf,mseeditglob,msefiledialog,mseevent, + classes,mclasses; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tdirlistitem } + +constructor tdirlistitem.create(const aowner: tcustomitemlist; + const aparent: ttreelistitem); +begin + inherited; + include(fstate,ns_subitems); +end; + +function tdirlistitem.getpath: filenamety; +begin + if fparent = nil then begin + result:= fcaption; + end + else begin + if froot = '' then begin + result:= copy(concatstrings(rootcaptions,'/'),2,bigint); + end + else begin + result:= filepath(froot,concatstrings(rootcaptions(),'/'),fk_dir); + end; + end; +end; + +procedure tdirlistitem.updateinfo; +begin + updatefileinfo(self,finfo,true); +end; + +procedure tdirlistitem.setentries(const list: tcustomfiledatalist; + const achecksubdirectories,ashowhidden,acheckbox: boolean); +var + po1: pfileinfoty; + ar1: treelistedititemarty; + int1: integer; + item1: tdirlistitem; +// dirstream: dirstreamty; + excl: fileattributesty; + fna1: filenamety; +begin + clear; + if list <> nil then begin + po1:= list.datapo; + if ashowhidden then begin + excl:= []; + end + else begin + excl:= [fa_hidden]; + end; + setlength(ar1,list.count); + for int1:= 0 to list.count - 1 do begin + item1:= tdirlistitem.create; + item1.froot:= froot; + if acheckbox then begin + item1.fstate:= item1.fstate + [ns_checkbox,ns_showchildchecked]; + end; + ar1[int1]:= item1; + item1.finfo:= po1^; + item1.updateinfo; + if achecksubdirectories and + (item1.finfo.extinfo1.filetype = ft_dir) then begin + fna1:= filepath(getpath,item1.finfo.name,fk_file); + if {$ifdef mswindows} + (treelevel = 0) and (length(fna1) = 4) and (fna1[3] = ':') and + (fna1[4] = '/')or + //'/x:/' could be a floppy disk on windows which throws an error + // on query + {$endif} + dirhasentries(fna1,[fa_dir],excl) then begin + include(item1.fstate,ns_subitems); + end + else begin + exclude(item1.fstate,ns_subitems); + end; + end; + inc(po1); + end; + add(ar1); + end; +end; + +function tdirlistitem.findsubdir(const aname: filenamety): tdirlistitem; +begin + result:= tdirlistitem(finditembycaption(aname,true)); + if (result = nil) and sys_filesystemiscaseinsensitive then begin + result:= tdirlistitem(finditembycaption(aname,false)); + end; +end; + +{ tdirtreefo } + +destructor tdirtreefo.destroy(); +begin + freeandnil(frootitem); + inherited; +end; + +procedure tdirtreefo.adddir(const aitem: tdirlistitem); +var + list: tcustomfiledatalist; + exclude: fileattributesty; +begin + list:= tcustomfiledatalist.create; + try + if casesensitive then begin + list.options:= [flo_sortname,flo_casesensitive]; + end + else begin + list.options:= [flo_sortname]; + end; + if showhiddenfiles then begin + exclude:= []; + end + else begin + exclude:= [fa_hidden]; + end; + list.adddirectory(aitem.getpath,fil_name,nil,[fa_dir],exclude); + aitem.setentries(list,checksubdir,showhiddenfiles, + dto_checkbox in foptionsdir); + finally + list.free; + end; +end; + +function tdirtreefo.getshowhiddenfiles: boolean; +begin + result:= dto_showhiddenfiles in foptionsdir; +end; + +procedure tdirtreefo.setshowhiddenfiles(const avalue: boolean); +begin + if avalue then begin + include(foptionsdir,dto_showhiddenfiles); + end + else begin + exclude(foptionsdir,dto_showhiddenfiles); + end; +end; + +function tdirtreefo.getcasesensitive: boolean; +begin + result:= dto_casesensitive in foptionsdir; +end; + +procedure tdirtreefo.setcasesensitive(const avalue: boolean); +begin + if avalue then begin + include(foptionsdir,dto_casesensitive); + end + else begin + exclude(foptionsdir,dto_casesensitive); + end; +end; + +function tdirtreefo.getchecksubdir: boolean; +begin + result:= dto_checksubdir in foptionsdir; +end; + +procedure tdirtreefo.setchecksubdir(const avalue: boolean); +begin + if avalue then begin + include(foptionsdir,dto_checksubdir); + end + else begin + exclude(foptionsdir,dto_checksubdir); + end; +end; + +procedure tdirtreefo.setroot(const avalue: filenamety); +begin + froot:= avalue; + updatepath(); +end; + +function tdirtreefo.getcheckednodes(const amode: getnodemodety = + gno_nochildren): dirlistitemarty; +begin + result:= dirlistitemarty(treeitem.itemlist.getcheckednodes(amode)); +end; + +function tdirtreefo.getcheckedfilenames(const amode: getnodemodety = + gno_nochildren): filenamearty; +var + ar1: dirlistitemarty; + int1: integer; +begin + ar1:= getcheckednodes(amode); + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= ar1[int1].getpath; + end; +end; + +function tdirtreefo.getpath: filenamety; +begin + if treeitem.item = nil then begin + result:= ''; + end + else begin + result:= filepath(tdirlistitem(treeitem.item).getpath,fk_dir); + end; +end; + +procedure tdirtreefo.updatepath(); +var + ar1: msestringarty; + int1: integer; + aitem,item1: tdirlistitem; + {$ifdef mswindows} + uncitem: tdirlistitem; + {$endif} + avalue: filenamety; + info1: fileinfoty; +begin + avalue:= fpath; + if dto_checkbox in foptionsdir then begin + treeitem.itemlist.options:= treeitem.itemlist.options + + [no_checkbox,no_updatechildchecked]; + end + else begin + treeitem.itemlist.options:= treeitem.itemlist.options - + [no_checkbox,no_updatechildchecked]; + end; + treeitem.itemlist.clear; + int1:= 0; + if froot = '' then begin + treeitem.itemlist.options:= treeitem.itemlist.options - [no_nofreeitems]; + treeitem.itemlist.count:= 1; + aitem:= tdirlistitem(treeitem.itemlist[0]); + ar1:= splitrootpath(avalue); + {$ifdef mswindows} + treeitem.itemlist.count:= 2; + uncitem:= tdirlistitem(treeitem.itemlist[1]); + initdirfileinfo(uncitem.finfo,'//'); //UNC + uncitem.updateinfo; + {$endif} + + if (high(ar1) > 0) and (ar1[0] = '') then begin + {$ifdef mswindows} + initdirfileinfo(aitem.finfo,'/'); + aitem.updateinfo; + aitem:= uncitem; + {$else} + initdirfileinfo(aitem.finfo,'//'); //UNC simulation + {$endif} + int1:= 1; + end + else begin + initdirfileinfo(aitem.finfo,'/'); + end; + aitem.updateinfo; + end + else begin + frootitem.free(); + initdirfileinfo(info1,filepath(froot,fk_file)); + frootitem:= tdirlistitem.create(nil,nil); + aitem:= frootitem; + initdirfileinfo(aitem.finfo,filepath(froot)); + aitem.froot:= froot; + aitem.updateinfo; + aitem.expanded:= true; + adddir(aitem); + treeitem.itemlist.options:= treeitem.itemlist.options + [no_nofreeitems]; + //destroyed by root node + treeitem.itemlist.addchildren(aitem); + ar1:= splitfilepath(relativepath(filepath(froot,avalue),froot,fk_file)); + if (ar1 <> nil) and (ar1[0] = '..') then begin + int1:= 1; //UNC + end; + end; + item1:= aitem; + for int1:= int1 to high(ar1) do begin + aitem.expanded:= true; + aitem:= aitem.findsubdir(ar1[int1]); + if aitem = nil then begin + break; + end; + item1:= aitem; + end; + grid.focuscell(makegridcoord(0,treeitem.itemlist.indexof(item1)), + fca_setfocusedcell); +end; + +procedure tdirtreefo.setpath(const avalue: filenamety); +begin + fpath:= avalue; + updatepath(); +end; + +procedure tdirtreefo.treeitemoncellevent(const sender: tobject; + var info: celleventinfoty); +begin + case info.eventkind of + cek_enter: begin + if assigned(fonpathchanged) then begin + fonpathchanged(self); + end; + end; + end; + if treeitem.item <> nil then begin + if (info.zone = cz_caption) then begin + if iscellclick(info) then begin + treeitem.checkvalue; + end; + end; + if iscellclick(info,[],[],keyshiftstatesmask) and + (info.zone in [cz_caption,cz_image]) then begin + if (ss_double in info.mouseeventinfopo^.shiftstate) and + (dto_expandondblclick in foptionsdir) then begin + treeitem.item.expanded:= not treeitem.item.expanded; + end + else begin + if (dto_expandonclick in foptionsdir) then begin + treeitem.item.expanded:= true; + end; + end; + end; + end; +end; + +procedure tdirtreefo.treeitemoncreateitem(const sender: tcustomitemlist; + var item: ttreelistedititem); +begin + item:= tdirlistitem.create(sender); + if dto_checkbox in foptionsdir then begin + with tdirlistitem(item) do begin + fstate:= fstate + [ns_checkbox,ns_showchildchecked]; + froot:= self.froot; + end; + end; +end; + +procedure tdirtreefo.doondataentered(); +begin + window.modalresult:= mr_ok; +end; + +procedure tdirtreefo.treeitemondataentered(const sender: tobject); +begin + doondataentered(); +end; + +procedure tdirtreefo.treeitemonitemnotification(const sender: tlistitem; + var action: nodeactionty); +var + bo1: boolean; +begin + with tdirlistitem(sender) do begin + case action of + na_checkedchange: begin + if canevent(tmethod(fonselectionchanged)) then begin + fonselectionchanged(self,sender); + end; + end; + na_expand: begin + include(finfo.state,fis_diropen); + updateinfo; + if (count = 0) or + (foptionsdir*[dto_checkbox,dto_nocollapseclear] = []) then begin + adddir(tdirlistitem(sender)); + end; + if count = 0 then begin + state:= state - [ns_subitems,ns_expanded]; + action:= na_none; + end; + end; + na_collapse: begin + bo1:= count > 0; + if foptionsdir * [dto_checkbox,dto_nocollapseclear] = [] then begin + clear; + end; + if bo1 then begin + state:= state + [ns_subitems]; + end; + exclude(finfo.state,fis_diropen); + updateinfo; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msedirtree_mfm.pas b/mseide-msegui/lib/common/dialogs/msedirtree_mfm.pas new file mode 100644 index 0000000..306ea2d --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtree_mfm.pas @@ -0,0 +1,98 @@ +unit msedirtree_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msedirtree; + +const + objdata: record size: integer; data: array[0..1604] of byte end = + (size: 1605; data: ( + 84,80,70,48,10,116,100,105,114,116,114,101,101,102,111,9,100,105,114,116, + 114,101,101,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,80,8,98,111,117,110,100,115,95,121,3,118,1,9,98,111, + 117,110,100,115,95,99,120,3,44,1,9,98,111,117,110,100,115,95,99,121, + 3,203,0,12,98,111,117,110,100,115,95,99,120,109,105,110,3,200,0,26, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99, + 111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0, + 3,44,1,3,203,0,0,13,111,112,116,105,111,110,115,119,105,110,100,111, + 119,11,8,119,111,95,112,111,112,117,112,17,119,111,95,98,117,116,116,111, + 110,101,110,100,109,111,100,97,108,0,7,111,112,116,105,111,110,115,11,13, + 102,111,95,99,108,111,115,101,111,110,101,115,99,17,102,111,95,108,111,99, + 97,108,115,104,111,114,116,99,117,116,115,15,102,111,95,97,117,116,111,114, + 101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101, + 115,116,97,116,0,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,11,116,119,105,100,103,101,116, + 103,114,105,100,4,103,114,105,100,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,0,16,102,114,97,109,101,46,102,114,97,109,101,119,105,100,116, + 104,2,1,16,102,114,97,109,101,46,99,111,108,111,114,102,114,97,109,101, + 4,2,0,0,160,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,14,102,114,108,95,102, + 114,97,109,101,119,105,100,116,104,14,102,114,108,95,99,111,108,111,114,102, + 114,97,109,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,44,1, + 9,98,111,117,110,100,115,95,99,121,3,203,0,7,97,110,99,104,111,114, + 115,11,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1, + 14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,116,114, + 101,101,105,116,101,109,1,9,108,105,110,101,119,105,100,116,104,2,0,12, + 99,111,108,111,114,102,111,99,117,115,101,100,4,7,0,0,144,5,119,105, + 100,116,104,3,42,1,7,111,112,116,105,111,110,115,11,11,99,111,95,114, + 101,97,100,111,110,108,121,7,99,111,95,102,105,108,108,12,99,111,95,115, + 97,118,101,118,97,108,117,101,0,8,111,112,116,105,111,110,115,49,11,11, + 99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99, + 111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,18, + 99,111,49,95,114,111,119,99,111,108,111,114,97,99,116,105,118,101,19,99, + 111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15,99, + 111,49,95,114,111,119,114,101,97,100,111,110,108,121,16,99,111,49,95,97, + 117,116,111,99,111,108,119,105,100,116,104,0,10,119,105,100,103,101,116,110, + 97,109,101,6,8,116,114,101,101,105,116,101,109,9,100,97,116,97,99,108, + 97,115,115,7,17,116,116,114,101,101,105,116,101,109,101,100,105,116,108,105, + 115,116,18,100,97,116,97,108,105,115,116,46,105,109,97,103,101,108,105,115, + 116,7,20,102,105,108,101,100,105,97,108,111,103,114,101,115,46,105,109,97, + 103,101,115,19,100,97,116,97,108,105,115,116,46,105,109,97,103,101,119,105, + 100,116,104,2,16,20,100,97,116,97,108,105,115,116,46,105,109,97,103,101, + 104,101,105,103,104,116,2,16,27,100,97,116,97,108,105,115,116,46,111,110, + 105,116,101,109,110,111,116,105,102,105,99,97,116,105,111,110,7,26,116,114, + 101,101,105,116,101,109,111,110,105,116,101,109,110,111,116,105,102,105,99,97, + 116,105,111,110,21,100,97,116,97,108,105,115,116,46,111,110,99,114,101,97, + 116,101,105,116,101,109,7,20,116,114,101,101,105,116,101,109,111,110,99,114, + 101,97,116,101,105,116,101,109,0,0,16,100,97,116,97,114,111,119,108,105, + 110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,13,116,116,114,101,101,105,116,101,109,101,100,105,116,8,116,114,101, + 101,105,116,101,109,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,6, + 99,117,114,115,111,114,7,8,99,114,95,97,114,114,111,119,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,3,42,1,9,98,111,117,110, + 100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108, + 121,12,111,101,95,117,110,100,111,111,110,101,115,99,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,24,111,101,95,102,111,114,99,101, + 114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,18,111,101,95, + 104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,9,111,101,95,108, + 111,99,97,116,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100, + 7,21,116,114,101,101,105,116,101,109,111,110,100,97,116,97,101,110,116,101, + 114,101,100,11,111,110,99,101,108,108,101,118,101,110,116,7,19,116,114,101, + 101,105,116,101,109,111,110,99,101,108,108,101,118,101,110,116,7,111,112,116, + 105,111,110,115,11,16,116,101,111,95,116,114,101,101,99,111,108,110,97,118, + 105,103,21,116,101,111,95,101,110,116,101,114,111,110,105,109,97,103,101,99, + 108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tdirtreefo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msedirtreesub.mfm b/mseide-msegui/lib/common/dialogs/msedirtreesub.mfm new file mode 100644 index 0000000..43e5e28 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtreesub.mfm @@ -0,0 +1,21 @@ +inherited dirtreesubfo: tdirtreesubfo + visible = True + container.bounds = ( + 0 + 0 + 300 + 203 + ) + moduleclassname = 'tdirtreefo' + inherited grid: twidgetgrid + frame.levelo = -2 + frame.framewidth = 0 + datacols.items = < + item[treeitem] + width = 296 + end> + inherited treeitem: ttreeitemedit + bounds_cx = 296 + end + end +end diff --git a/mseide-msegui/lib/common/dialogs/msedirtreesub.pas b/mseide-msegui/lib/common/dialogs/msedirtreesub.pas new file mode 100644 index 0000000..556e414 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtreesub.pas @@ -0,0 +1,35 @@ +unit msedirtreesub; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + msedirtree,msefiledialog,mclasses; + +type + tdirtreesubfo = class(tdirtreefo) + private + protected + procedure doondataentered(); override; + public + constructor create(aowner: tcomponent); override; + published + end; + +implementation +uses + msedirtreesub_mfm; + +{ tdirtreesubfo } + +procedure tdirtreesubfo.doondataentered(); +begin + //do nothing +end; + +constructor tdirtreesubfo.create(aowner: tcomponent); +begin + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msedirtreesub_mfm.pas b/mseide-msegui/lib/common/dialogs/msedirtreesub_mfm.pas new file mode 100644 index 0000000..b43463c --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtreesub_mfm.pas @@ -0,0 +1,29 @@ +unit msedirtreesub_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msedirtreesub; + +const + objdata: record size: integer; data: array[0..230] of byte end = + (size: 231; data: ( + 84,80,70,48,241,13,116,100,105,114,116,114,101,101,115,117,98,102,111,12, + 100,105,114,116,114,101,101,115,117,98,102,111,7,118,105,115,105,98,108,101, + 9,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,44,1,3,203,0,0,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,10,116,100,105,114,116,114,101,101,102,111,0,241, + 11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,254,16,102,114,97,109,101,46,102, + 114,97,109,101,119,105,100,116,104,2,0,14,100,97,116,97,99,111,108,115, + 46,105,116,101,109,115,14,7,8,116,114,101,101,105,116,101,109,1,5,119, + 105,100,116,104,3,40,1,0,0,0,241,13,116,116,114,101,101,105,116,101, + 109,101,100,105,116,8,116,114,101,101,105,116,101,109,9,98,111,117,110,100, + 115,95,99,120,3,40,1,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tdirtreesubfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msefiledialog.mfm b/mseide-msegui/lib/common/dialogs/msefiledialog.mfm new file mode 100644 index 0000000..3d04c98 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialog.mfm @@ -0,0 +1,346 @@ +object filedialogfo: Tfiledialogfo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 14 + bounds_y = 326 + bounds_cx = 587 + bounds_cy = 307 + bounds_cxmin = 360 + bounds_cymin = 150 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = layoutev + container.bounds = ( + 0 + 0 + 587 + 307 + ) + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos] + onloaded = formoncreate + onkeydown = listviewonkeydown + onlayout = layoutev + left = 239 + top = 138 + moduleclassname = 'tmseform' + object listview: tfilelistview + optionswidget = [ow_mousefocus, ow_arrowfocus, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 24 + bounds_cx = 587 + bounds_cy = 236 + anchors = [an_top] + onkeydown = listviewonkeydown + datarowlinecolor = -1610612731 + datacollinecolor = -1610612731 + cellwidth = 174 + cellheight = 15 + optionsgrid = [og_colsizing, og_focuscellonenter, og_mousescrollcol] + options = [lvo_readonly, lvo_drawfocus, lvo_mouseselect, lvo_keyselect, lvo_multiselect, lvo_locate, lvo_hintclippedtext] + itemlist.imagelist = filedialogres.images + itemlist.imagewidth = 16 + itemlist.imageheight = 16 + cellwidthmin = 50 + onselectionchanged = listviewselectionchanged + onitemevent = listviewitemevent + filelist.options = [flo_sortname, flo_sorttype] + onlistread = listviewonlistread + reffontheight = 14 + end + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 0 + bounds_y = 262 + bounds_cx = 585 + bounds_cy = 42 + anchors = [an_left, an_right, an_bottom] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + linktop = listview + dist_top = 2 + options = [spao_gluebottom] + object bucont: tspacer + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_destroywidgets] + taborder = 1 + visible = True + bounds_x = 454 + bounds_y = 0 + bounds_cx = 131 + bounds_cy = 42 + anchors = [an_top, an_right] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linkleft = tlayouter1 + options = [spao_glueright, spao_gluebottom] + object showhidden: tbooleanedit + frame.caption = '&Show hidden files' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 112 + 2 + ) + bounds_x = 6 + bounds_y = 4 + bounds_cx = 125 + bounds_cy = 16 + onsetvalue = showhiddenonsetvalue + end + object tspacer4: tspacer + taborder = 3 + bounds_x = 41 + bounds_y = 22 + bounds_cx = 8 + bounds_cy = 20 + linkleft = ok + linkright = cancel + end + object cancel: tbutton + optionswidget1 = [ow1_autowidth, ow1_autoheight] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 2 + bounds_x = 49 + bounds_y = 22 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 35 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_candefocuswindow] + end + object ok: tbutton + optionswidget1 = [ow1_autowidth, ow1_autoheight] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048187 + taborder = 1 + bounds_x = 6 + bounds_y = 22 + bounds_cx = 35 + bounds_cy = 20 + bounds_cxmin = 35 + state = [as_default, as_localdefault, as_localcaption, as_localonexecute] + caption = '&Ok' + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_candefocuswindow] + onexecute = okonexecute + end + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 1 + bounds_y = 0 + bounds_cx = 453 + bounds_cy = 42 + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_alignx, lao_placey] + align_mode = wam_end + align_glue = wam_end + place_mindist = 2 + place_maxdist = 2 + object filter: tdropdownlistedit + frame.caption = '&Filter' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 0 + 34 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 22 + bounds_cx = 448 + ondataentered = filepathentered + onsetvalue = filteronsetvalue + dropdown.options = [deo_keydropdown, deo_cliphint] + dropdown.cols.count = 2 + dropdown.cols.items = < + item + end + item + options = [co_readonly, co_invisible, co_focusselect, co_fill] + end> + dropdown.valuecol = 1 + onafterclosedropdown = filteronafterclosedropdown + reffontheight = 14 + end + object filename: thistoryedit + frame.caption = '&Name' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 0 + 39 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 453 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + oncopytoclipboard = copytoclip + onpastefromclipboard = pastefromclip + onsetvalue = filenamesetvalue + dropdown.options = [deo_keydropdown, deo_cliphint] + dropdown.dropdownrowcount = 10 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + end> + reffontheight = 14 + end + end + end + object tlayouter3: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 2 + bounds_x = 1 + bounds_y = 2 + bounds_cx = 584 + bounds_cy = 20 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 2 + place_maxdist = 2 + place_options = [plo_endmargin] + linkbottom = listview + dist_bottom = 2 + object createdir: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 5 + bounds_x = 528 + bounds_y = 0 + bounds_cx = 56 + bounds_cy = 20 + bounds_cxmin = 35 + anchors = [an_top, an_right] + state = [as_localcaption, as_localonexecute] + caption = '&New dir' + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_candefocuswindow] + onexecute = createdironexecute + reffontheight = 14 + end + object home: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 4 + bounds_x = 480 + bounds_y = 0 + bounds_cx = 46 + bounds_cy = 20 + bounds_cxmin = 35 + anchors = [an_top, an_right] + state = [as_localcaption, as_localonexecute] + caption = '&Home' + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_candefocuswindow] + onexecute = homeaction + reffontheight = 14 + end + object forward: tstockglyphbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_destroywidgets, ow_disabledhint] + taborder = 3 + onshowhint = buttonshowhint + bounds_x = 465 + bounds_y = 0 + bounds_cx = 13 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localshortcut, as_localonexecute] + glyph = stg_arrowright + autosize_cx = -10 + onexecute = forwardexe + reffontheight = 14 + sc = ( + 1 + 24666 + ) + end + object back: tstockglyphbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_destroywidgets, ow_disabledhint] + taborder = 2 + onshowhint = buttonshowhint + bounds_x = 450 + bounds_y = 0 + bounds_cx = 13 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localshortcut, as_localonexecute] + glyph = stg_arrowleft + autosize_cx = -10 + onexecute = backexe + reffontheight = 14 + sc = ( + 1 + 16474 + ) + end + object up: tstockglyphbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 1 + onshowhint = buttonshowhint + bounds_x = 431 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localshortcut, as_localonexecute] + glyph = stg_arrowup + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_candefocuswindow] + onexecute = upaction + reffontheight = 14 + sc = ( + 1 + 16662 + ) + end + object dir: tdirdropdownedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = '&Dir' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 0 + 20 + 0 + ) + onshowhint = dirshowhint + bounds_x = 0 + bounds_y = 0 + bounds_cx = 429 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + dropdown.options = [deo_selectonly, deo_keydropdown] + onsetvalue = dironsetvalue + reffontheight = 14 + end + end +end diff --git a/mseide-msegui/lib/common/dialogs/msefiledialog.pas b/mseide-msegui/lib/common/dialogs/msefiledialog.pas new file mode 100644 index 0000000..3c43993 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialog.pas @@ -0,0 +1,2811 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefiledialog; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseglob,mseguiglob,mseforms,classes,mclasses,mseclasses,msewidgets,msegrids, + mselistbrowser,mseedit,msesimplewidgets,msedataedits,msedialog,msetypes, + msestrings,msesystypes,msesys,msedispwidgets,msedatalist,msestat,msestatfile, + msebitmap,msedatanodes,msefileutils,msedropdownlist,mseevent,msegraphedits, + mseeditglob,msesplitter,msemenus,msegridsglob,msegraphics,msegraphutils, + msedirtree,msewidgetgrid,mseact,mseapplication,msegui,mseificomp, + mseificompglob,mseifiglob,msestream,sysutils,msemenuwidgets,msescrollbar; + +const + defaultlistviewoptionsfile = defaultlistviewoptions + [lvo_readonly]; + +type + tfilelistitem = class(tlistitem) + private + protected + public + constructor create(const aowner: tcustomitemlist); override; + end; + pfilelistitem = ^tfilelistitem; + + tfileitemlist = class(titemviewlist) + protected + procedure createitem(out item: tlistitem); override; + end; + + getfileiconeventty = procedure(const sender: tobject; const ainfo: fileinfoty; + var imagelist: timagelist; var imagenr: integer) of object; + + tfilelistview = class(tlistview) + private + ffilelist: tfiledatalist; + foptionsfile: filelistviewoptionsty; + fmaskar: filenamearty; + fdirectory: filenamety; + ffilecount: integer; + fincludeattrib,fexcludeattrib: fileattributesty; + fonlistread: notifyeventty; + ffocusmoved: boolean; + fongetfileicon: getfileiconeventty; + foncheckfile: checkfileeventty; + procedure filelistchanged(const sender: tobject); + procedure setfilelist(const Value: tfiledatalist); + function getpath: msestring; + procedure setpath(const Value: msestring); + procedure setdirectory(const Value: msestring); + function getmask: filenamety; + procedure setmask(const value: filenamety); + function getselectednames: filenamearty; + procedure setselectednames(const avalue: filenamearty); + function getchecksubdir: boolean; + procedure setchecksubdir(const avalue: boolean); + procedure setoptionsfile(const avalue: filelistviewoptionsty); + procedure checkcasesensitive; + protected + foptionsdir: dirstreamoptionsty; + fcaseinsensitive: boolean; +// procedure setoptions(const Value: listviewoptionsty); override; + procedure docellevent(var info: celleventinfoty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure readlist; + procedure updir; + function filecount: integer; + property directory: filenamety read fdirectory write setdirectory; + property includeattrib: fileattributesty read fincludeattrib + write fincludeattrib default [fa_all]; + property excludeattrib: fileattributesty read fexcludeattrib + write fexcludeattrib default [fa_hidden]; + property maskar: filenamearty read fmaskar write fmaskar; //nil -> all + property path: filenamety read getpath write setpath; + //calls readlist + property selectednames: filenamearty read getselectednames write setselectednames; + property checksubdir: boolean read getchecksubdir write setchecksubdir; + published + property mask: filenamety read getmask write setmask; //'' -> all + property options default defaultlistviewoptionsfile; + property optionsfile: filelistviewoptionsty read foptionsfile + write setoptionsfile default defaultfilelistviewoptions; + property filelist: tfiledatalist read ffilelist write setfilelist; + property onlistread: notifyeventty read fonlistread write fonlistread; + property ongetfileicon: getfileiconeventty read fongetfileicon + write fongetfileicon; + property oncheckfile: checkfileeventty read foncheckfile write foncheckfile; + end; + +const + defaulthistorymaxcount = 20; + +type + filedialogoptionty = (fdo_filtercasesensitive, //flvo_maskcasesensitive + fdo_filtercaseinsensitive, //flvo_maskcaseinsensitive + fdo_save, + fdo_dispname,fdo_dispnoext,fdo_sysfilename,fdo_params, + fdo_directory,fdo_file, + fdo_absolute,fdo_relative,fdo_lastdirrelative, + fdo_basedirrelative, + fdo_quotesingle, + fdo_link, //links lastdir of controllers with same group + fdo_checkexist,fdo_acceptempty,fdo_single, + fdo_chdir,fdo_savelastdir, + fdo_checksubdir); + filedialogoptionsty = set of filedialogoptionty; +const + defaultfiledialogoptions = [fdo_savelastdir]; +type + filedialogkindty = (fdk_none,fdk_open,fdk_save,fdk_new); + + tfiledialogcontroller = class; + + filedialogbeforeexecuteeventty = procedure(const sender: tfiledialogcontroller; + var dialogkind: filedialogkindty; var aresult: modalresultty) of object; + filedialogafterexecuteeventty = procedure(const sender: tfiledialogcontroller; + var aresult: modalresultty) of object; + + tfiledialogcontroller = class(tlinkedpersistent) + private + fowner: tmsecomponent; + fgroup: integer; + fonchange: proceventty; + ffilenames: filenamearty; + ffilterlist: tdoublemsestringdatalist; + ffilter: filenamety; + ffilterindex: integer; + fcolwidth: integer; + fwindowrect: rectty; + fhistorymaxcount: integer; + fhistory: msestringarty; + fcaptionopen: msestring; + fcaptionsave: msestring; + fcaptionnew: msestring; + finclude: fileattributesty; + fexclude: fileattributesty; + fonbeforeexecute: filedialogbeforeexecuteeventty; + fonafterexecute: filedialogafterexecuteeventty; + fongetfilename: setstringeventty; + fongetfileicon: getfileiconeventty; + foncheckfile: checkfileeventty; + fimagelist: timagelist; + fparams: msestring; + procedure setfilterlist(const Value: tdoublemsestringdatalist); + procedure sethistorymaxcount(const Value: integer); + function getfilename: filenamety; + procedure setfilename(const avalue: filenamety); + procedure dochange; + procedure setdefaultext(const avalue: filenamety); + procedure setoptions(Value: filedialogoptionsty); + procedure checklink; + procedure setlastdir(const avalue: filenamety); + procedure setimagelist(const avalue: timagelist); + function getsysfilename: filenamety; + protected + flastdir: filenamety; + fbasedir: filenamety; + fdefaultext: filenamety; + foptions: filedialogoptionsty; + public + constructor create(const aowner: tmsecomponent = nil; + const onchange: proceventty = nil); reintroduce; + destructor destroy; override; + procedure readstatvalue(const reader: tstatreader); + procedure readstatstate(const reader: tstatreader); + procedure readstatoptions(const reader: tstatreader); + procedure writestatvalue(const writer: tstatwriter); + procedure writestatstate(const writer: tstatwriter); + procedure writestatoptions(const writer: tstatwriter); + function actcaption(const dialogkind: filedialogkindty): msestring; + function execute(dialogkind: filedialogkindty = fdk_none): modalresultty; overload; + //fdk_none -> use options fdo_save + function execute(dialogkind: filedialogkindty; const acaption: msestring; + aoptions: filedialogoptionsty): modalresultty; overload; + function execute(const dialogkind: filedialogkindty; + const acaption: msestring): modalresultty; overload; + function execute(const dialogkind: filedialogkindty; + const aoptions: filedialogoptionsty): modalresultty; overload; + function execute(var avalue: filenamety; + dialogkind: filedialogkindty = fdk_none): boolean; overload; + function execute(var avalue: filenamety; const dialogkind: filedialogkindty; + const acaption: msestring): boolean; overload; + function execute(var avalue: filenamety; const dialogkind: filedialogkindty; + const acaption: msestring; + aoptions: filedialogoptionsty): boolean; overload; + function canoverwrite(): boolean; + //true if current filename is allowed to write + procedure clear; + procedure setfilenamelastdir(const afilename: filenamety); + //lastdir relative + procedure componentevent(const event: tcomponentevent); + property history: msestringarty read fhistory write fhistory; + property filenames: filenamearty read ffilenames write ffilenames; + property syscommandline: filenamety read getsysfilename; deprecated; + property sysfilename: filenamety read getsysfilename; + property params: msestring read fparams; + published + property filename: filenamety read getfilename write setfilename; + property lastdir: filenamety read flastdir write setlastdir; + property basedir: filenamety read fbasedir write fbasedir; + property filter: filenamety read ffilter write ffilter; + property filterlist: tdoublemsestringdatalist read ffilterlist write setfilterlist; + property filterindex: integer read ffilterindex write ffilterindex default 0; + property include: fileattributesty read finclude write finclude default [fa_all]; + property exclude: fileattributesty read fexclude write fexclude default [fa_hidden]; + property colwidth: integer read fcolwidth write fcolwidth default 0; + property defaultext: filenamety read fdefaultext write setdefaultext; + property options: filedialogoptionsty read foptions write setoptions + default defaultfiledialogoptions; + property historymaxcount: integer read fhistorymaxcount + write sethistorymaxcount default defaulthistorymaxcount; + property captionopen: msestring read fcaptionopen write fcaptionopen; + property captionsave: msestring read fcaptionsave write fcaptionsave; + property captionnew: msestring read fcaptionnew write fcaptionnew; + property group: integer read fgroup write fgroup default 0; + property imagelist: timagelist read fimagelist write setimagelist; + property ongetfilename: setstringeventty read fongetfilename write fongetfilename; + property ongetfileicon: getfileiconeventty read fongetfileicon + write fongetfileicon; + property oncheckfile: checkfileeventty read foncheckfile write foncheckfile; + property onbeforeexecute: filedialogbeforeexecuteeventty + read fonbeforeexecute write fonbeforeexecute; + property onafterexecute: filedialogafterexecuteeventty + read fonafterexecute write fonafterexecute; + end; + +const + defaultfiledialogoptionsedit1 = defaultoptionsedit1+ + [oe1_savevalue,oe1_savestate,oe1_saveoptions]; + +type + tfiledialog = class(tdialog,istatfile) + private + fcontroller: tfiledialogcontroller; + fstatvarname: msestring; + fstatfile: tstatfile; + fdialogkind: filedialogkindty; +// foptionsedit: optionseditty; + foptionsedit1: optionsedit1ty; + fstatpriority: integer; + procedure setcontroller(const value: tfiledialogcontroller); + procedure setstatfile(const Value: tstatfile); + procedure readoptionsedit(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function execute: modalresultty; overload; override; + function execute(const akind: filedialogkindty): modalresultty; + reintroduce; overload; + function execute(const akind: filedialogkindty; + const aoptions: filedialogoptionsty): modalresultty; + reintroduce; overload; + procedure componentevent(const event: tcomponentevent); override; + published + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property controller: tfiledialogcontroller read fcontroller + write setcontroller; + property dialogkind: filedialogkindty read fdialogkind write fdialogkind + default fdk_none; + property optionsedit1: optionsedit1ty read foptionsedit1 write foptionsedit1 + default defaultfiledialogoptionsedit1; + end; + + tcustomfilenameedit1 = class; + tfilenameeditcontroller = class(tstringdialogcontroller) + protected + function execute(var avalue: msestring): boolean; override; + public + constructor create(const aowner: tcustomfilenameedit1); + end; + + tcustomfilenameedit1 = class(tcustomdialogstringed) + private + fcontroller: tfiledialogcontroller; + procedure setcontroller(const avalue: tfiledialogcontroller); + function getsysvalue: filenamety; + procedure setsysvalue(const avalue: filenamety); + function getsysvaluequoted: filenamety; + protected + function createdialogcontroller: tstringdialogcontroller; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure updatedisptext(var avalue: msestring); override; + function getvaluetext: msestring; override; + procedure readstatvalue(const reader: tstatreader); override; + procedure readstatstate(const reader: tstatreader); override; + procedure readstatoptions(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure writestatstate(const writer: tstatwriter); override; + procedure writestatoptions(const writer: tstatwriter); override; + procedure valuechanged; override; + procedure updatecopytoclipboard(var atext: msestring); override; + procedure updatepastefromclipboard(var atext: msestring); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure componentevent(const event: tcomponentevent); override; + property controller: tfiledialogcontroller read fcontroller + write setcontroller; + property sysvalue: filenamety read getsysvalue write setsysvalue; + property sysvaluequoted: filenamety read getsysvaluequoted write setsysvalue; + published + property optionsedit1 default defaultfiledialogoptionsedit1; + end; + + tcustomfilenameedit = class(tcustomfilenameedit1) + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + end; + + tcustomremotefilenameedit = class(tcustomfilenameedit1) + private + fdialog: tfiledialog; + procedure setfiledialog(const avalue: tfiledialog); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + property dialog: tfiledialog read fdialog write setfiledialog; + end; + + tfilenameedit = class(tcustomfilenameedit) + published + property frame; + property passwordchar; + property maxlength; + property value; + property onsetvalue; + property controller; + end; + + tremotefilenameedit = class(tcustomremotefilenameedit) + published + property frame; + property passwordchar; + property maxlength; + property value; + property onsetvalue; + property dialog; + end; + + dirdropdowneditoptionty = (ddeo_showhiddenfiles,ddeo_checksubdir); + dirdropdowneditoptionsty = set of dirdropdowneditoptionty; + + tdirdropdownedit = class(tdropdownwidgetedit) + private + foptions: dirdropdowneditoptionsty; + function getshowhiddenfiles: boolean; + procedure setshowhiddenfiles(const avalue: boolean); + function getchecksubdir: boolean; + procedure setchecksubdir(const avalue: boolean); + protected + procedure createdropdownwidget(const atext: msestring; + out awidget: twidget); override; + function getdropdowntext(const awidget: twidget): msestring; override; + procedure pathchanged(const sender: tobject); + procedure doafterclosedropdown; override; + procedure updatecopytoclipboard(var atext: msestring); override; + procedure updatepastefromclipboard(var atext: msestring); override; + public + property showhiddenfiles: boolean read getshowhiddenfiles + write setshowhiddenfiles; + property checksubdir: boolean read getchecksubdir + write setchecksubdir; + published + property options: dirdropdowneditoptionsty read foptions + write foptions default []; + end; + + dirtreepatheventty = procedure(const sender: tobject; + const avalue: msestring) of object; + + tdirtreeview = class(tpublishedwidget,icaptionframe) + private + fonpathchanged: dirtreepatheventty; + fonpathselected: dirtreepatheventty; + fonselectionchanged: listitemeventty; + function getoptions: dirtreeoptionsty; + procedure setoptions(const avalue: dirtreeoptionsty); + function getpath: filenamety; + procedure setpath(const avalue: filenamety); + procedure setroot(const avalue: filenamety); + function getgrid: twidgetgrid; + procedure setgrid(const avalue: twidgetgrid); + function getoptionstree: treeitemeditoptionsty; + procedure setoptionstree(const avalue: treeitemeditoptionsty); + function getoptionsedit: optionseditty; + procedure setoptionsedit(const avalue: optionseditty); + function getcol_color: colorty; + procedure setcol_color(const avalue: colorty); + function getcol_coloractive: colorty; + procedure setcol_coloractive(const avalue: colorty); + function getcol_colorfocused: colorty; + procedure setcol_colorfocused(const avalue: colorty); + function getcell_options: coloptionsty; + procedure setcell_options(const avalue: coloptionsty); + { + function getcell_frame: tcellframe; + procedure setcell_frame(const avalue: tcellframe); + function getcell_face: tcellface; + procedure setcell_face(const avalue: tcellface); + function getcell_datalist: ttreeitemeditlist; + procedure setcell_datalist(const avalue: ttreeitemeditlist); + } + protected + fdirview: tdirtreefo; + fpath: filenamety; + froot: filenamety; + procedure dopathchanged(const sender: tobject); + procedure dopathselected(const sender: tobject); + procedure doselectionchanged(const sender: tobject; const aitem: tlistitem); + procedure internalcreateframe; override; + procedure loaded(); override; + class function classskininfo: skininfoty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure refresh(); + property dirview: tdirtreefo read fdirview; + property path: filenamety read getpath write setpath; + property root: filenamety read froot write setroot; + published + property font: twidgetfont read getfont write setfont stored isfontstored; + property options: dirtreeoptionsty read getoptions + write setoptions default []; + property optionstree: treeitemeditoptionsty read getoptionstree + write setoptionstree default [teo_treecolnavig,teo_enteronimageclick]; + property optionsedit: optionseditty read getoptionsedit write setoptionsedit + default [oe_readonly,oe_undoonesc,oe_checkmrcancel, + oe_forcereturncheckvalue,oe_hintclippedtext,oe_locate]; + property col_color: colorty read getcol_color + write setcol_color default cl_default; + property col_coloractive: colorty read getcol_coloractive + write setcol_coloractive default cl_none; + property col_colorfocused: colorty read getcol_colorfocused + write setcol_colorfocused default cl_active; + property col_options: coloptionsty read getcell_options + write setcell_options default [co_readonly,co_fill,co_savevalue]; +// property col_frame: tcellframe read getcell_frame write setcell_frame; +// property col_face: tcellface read getcell_face write setcell_face; +// property col_datalist: ttreeitemeditlist read getcell_datalist +// write setcell_datalist; + property onpathchanged: dirtreepatheventty read + fonpathchanged write fonpathchanged; + property onpathselected: dirtreepatheventty read + fonpathselected write fonpathselected; + property onselectionchanged: listitemeventty read + fonselectionchanged write fonselectionchanged; //for checkboxes + property optionswidget default defaultoptionswidgetsubfocus; + end; + + tfiledialogfo = class(tmseform) + listview: tfilelistview; + tlayouter2: tlayouter; + bucont: tspacer; + showhidden: tbooleanedit; + tspacer4: tspacer; + cancel: tbutton; + ok: tbutton; + tlayouter1: tlayouter; + filter: tdropdownlistedit; + filename: thistoryedit; + tlayouter3: tlayouter; + createdir: tbutton; + home: tbutton; + forward: tstockglyphbutton; + back: tstockglyphbutton; + up: tstockglyphbutton; + dir: tdirdropdownedit; + procedure createdironexecute(const sender: TObject); + procedure listviewselectionchanged(const sender: tcustomlistview); + procedure listviewitemevent(const sender: tcustomlistview; + const index: Integer; var info: celleventinfoty); + procedure listviewonkeydown(const sender: twidget; var info: keyeventinfoty); + procedure upaction(const sender: TObject); + procedure dironsetvalue(const sender: TObject; var avalue: mseString; + var accept: Boolean); + procedure filenamesetvalue(const sender: TObject; var avalue: mseString; + var accept: Boolean); + procedure listviewonlistread(const sender: tobject); + procedure filteronafterclosedropdown(const sender: tobject); + procedure filteronsetvalue(const sender: tobject; var avalue: msestring; var accept: boolean); + procedure filepathentered(const sender: tobject); + procedure okonexecute(const sender: tobject); + procedure layoutev(const sender: TObject); + procedure showhiddenonsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure formoncreate(const sender: TObject); + procedure dirshowhint(const sender: TObject; var info: hintinfoty); + procedure copytoclip(const sender: TObject; var avalue: msestring); + procedure pastefromclip(const sender: TObject; var avalue: msestring); + procedure homeaction(const sender: TObject); + procedure backexe(const sender: TObject); + procedure forwardexe(const sender: TObject); + procedure buttonshowhint(const sender: TObject; var ainfo: hintinfoty); + private + fselectednames: filenamearty; + finit: boolean; + fcourse: filenamearty; + fcourseid: int32; + fcourselock: boolean; + procedure updatefiltertext; + function tryreadlist(const adir: filenamety; + const errormessage: boolean): boolean; + //restores old dir on error + function changedir(const adir: filenamety): boolean; + procedure checkcoursebuttons(); + procedure course(const adir: filenamety); + procedure doup(); + public + dialogoptions: filedialogoptionsty; + defaultext: filenamety; + filenames: filenamearty; + end; + +function filedialog(var afilenames: filenamearty; + const aoptions: filedialogoptionsty; + const acaption: msestring; //'' -> 'Open' or 'Save' + const filterdesc: array of msestring; + const filtermask: array of msestring; + const adefaultext: filenamety = ''; + const filterindex: pinteger = nil; //nil -> 0 + const filter: pfilenamety = nil; //nil -> unused + const colwidth: pinteger = nil; //nil -> default + const includeattrib: fileattributesty = [fa_all]; + const excludeattrib: fileattributesty = [fa_hidden]; + const history: pmsestringarty = nil; + const historymaxcount: integer = defaulthistorymaxcount; + const imagelist: timagelist = nil; + const ongetfileicon: getfileiconeventty = nil; + const oncheckfile: checkfileeventty = nil + ): modalresultty; overload; +//threadsafe +function filedialog(var afilename: filenamety; + const aoptions: filedialogoptionsty; + const acaption: msestring; + const filterdesc: array of msestring; + const filtermask: array of msestring; + const adefaultext: filenamety = ''; + const filterindex: pinteger = nil; //nil -> 0 + const filter: pfilenamety = nil; //nil -> unused + const colwidth: pinteger = nil; //nil -> default + const includeattrib: fileattributesty = [fa_all]; + const excludeattrib: fileattributesty = [fa_hidden]; + const history: pmsestringarty = nil; + const historymaxcount: integer = defaulthistorymaxcount; + const imagelist: timagelist = nil; + const ongetfileicon: getfileiconeventty = nil; + const oncheckfile: checkfileeventty = nil + ): modalresultty; overload; +//threadsafe + +procedure getfileicon(const info: fileinfoty; var imagelist: timagelist; + out imagenr: integer); +procedure updatefileinfo(const item: tlistitem; const info: fileinfoty; + const withicon: boolean); + +implementation +uses + msefiledialog_mfm,msebits,mseactions, + msestringenter,msefiledialogres,msekeyboard, + msestockobjects,msesysintf,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdirtreefo1 = class(tdirtreefo); + tcomponent1 = class(tcomponent); + +procedure getfileicon(const info: fileinfoty; var imagelist: timagelist; + out imagenr: integer); +begin + with info do begin +// imagelist:= nil; + imagenr:= -1; + if fis_typevalid in state then begin + case extinfo1.filetype of + ft_dir: begin + if fis_diropen in state then begin + filedialogres.getfileicon(fdi_diropen,imagelist,imagenr); + end + else begin + if fis_hasentry in state then begin + filedialogres.getfileicon(fdi_direntry,imagelist,imagenr); + end + else begin + filedialogres.getfileicon(fdi_dir,imagelist,imagenr); + end; + end; + end; + ft_reg,ft_lnk: begin + filedialogres.getfileicon(fdi_file,imagelist,imagenr); + end; + end; + end; + end; +end; + +procedure updatefileinfo(const item: tlistitem; const info: fileinfoty; + const withicon: boolean); +var + aimagelist: timagelist; + aimagenr: integer; +begin + aimagelist:= item.imagelist; + item.caption:= info.name; + if withicon then begin + getfileicon(info,aimagelist,aimagenr); + item.imagelist:= aimagelist; + if aimagelist <> nil then begin + item.imagenr:= aimagenr; + end; + end; +end; + +function filedialog1(dialog: tfiledialogfo; var afilenames: filenamearty; + const filterdesc: array of msestring; + const filtermask: array of msestring; + const filterindex: pinteger; + const afilter: pfilenamety; //nil -> unused + const colwidth: pinteger; //nil -> default + const includeattrib: fileattributesty; + const excludeattrib: fileattributesty; + const history: pmsestringarty; + const historymaxcount: integer; + const acaption: msestring; + const aoptions: filedialogoptionsty; + const adefaultext: filenamety; + const imagelist: timagelist; + const ongetfileicon: getfileiconeventty; + const oncheckfile: checkfileeventty + ): modalresultty; +var + i1: integer; +begin + with dialog do begin + dir.checksubdir:= fdo_checksubdir in aoptions; + listview.checksubdir:= fdo_checksubdir in aoptions; + dialogoptions:= aoptions; + if fdo_filtercasesensitive in aoptions then begin + listview.optionsfile:= listview.optionsfile + [flvo_maskcasesensitive]; + end; + if fdo_filtercaseinsensitive in aoptions then begin + listview.optionsfile:= listview.optionsfile + [flvo_maskcaseinsensitive]; + end; + if fdo_single in aoptions then begin + listview.options:= listview.options - [lvo_multiselect]; + end; + defaultext:= adefaultext; + caption:= acaption; + listview.includeattrib:= includeattrib; + listview.excludeattrib:= excludeattrib; + listview.itemlist.imagelist:= imagelist; + if imagelist <> nil then begin + listview.itemlist.imagesize:= imagelist.size; + end; + listview.ongetfileicon:= ongetfileicon; + listview.oncheckfile:= oncheckfile; + filter.dropdown.cols[0].count:= high(filtermask) + 1; + for i1:= 0 to high(filtermask) do begin + if (i1 <= high(filterdesc)) and (filterdesc[i1] <> '') then begin + filter.dropdown.cols[0][i1]:= filterdesc[i1] + ' ('+filtermask[i1] + ')'; + end + else begin + filter.dropdown.cols[0][i1]:= filtermask[i1]; + end; + end; + filter.dropdown.cols[1].assignopenarray(filtermask); + if filterindex <> nil then begin + filter.dropdown.itemindex:= filterindex^; + end + else begin + filter.dropdown.itemindex:= 0; + end; + if (afilter = nil) or (afilter^ = '') or + (filter.dropdown.itemindex >= 0) and + (afilter^ = filter.dropdown.cols[1][filter.dropdown.itemindex]) then begin + updatefiltertext; + end + else begin + filter.value:= afilter^; + listview.mask:= afilter^; + end; + if history <> nil then begin + filename.dropdown.valuelist.asarray:= history^; + filename.dropdown.historymaxcount:= historymaxcount; + end + else begin + filename.dropdown.options:= [deo_disabled]; + end; + if (high(afilenames) = 0) and (fdo_directory in aoptions) then begin + filename.value:= filepath(afilenames[0]); + end + else begin + filename.value:= quotefilename(afilenames); + end; + if (colwidth <> nil) and (colwidth^ <> 0) then begin + listview.cellwidth:= colwidth^; + end; + finit:= true; + try + filename.checkvalue; + finally + finit:= false; + end; + showhidden.value:= not (fa_hidden in excludeattrib); + show(true); + result:= window.modalresult; + if result <> mr_ok then begin + result:= mr_cancel; + end; + if (colwidth <> nil) then begin + colwidth^:= listview.cellwidth; + end; + if result = mr_ok then begin + afilenames:= filenames; + if fdo_sysfilename in aoptions then begin + for i1:= 0 to high(afilenames) do begin + tosysfilepath1(afilenames[i1]); + end; + end; + if filterindex <> nil then begin + filterindex^:= filter.dropdown.itemindex; + end; + if afilter <> nil then begin + afilter^:= listview.mask; + end; + if high(afilenames) = 0 then begin + filename.dropdown.savehistoryvalue(afilenames[0]); + end; + if history <> nil then begin + history^:= filename.dropdown.valuelist.asarray; + end; + if fdo_chdir in aoptions then begin + setcurrentdirmse(listview.directory); + end; + end; + end; +end; + +function filedialog(var afilenames: filenamearty; + const aoptions: filedialogoptionsty; + const acaption: msestring; + const filterdesc: array of msestring; + const filtermask: array of msestring; + const adefaultext: filenamety = ''; + const filterindex: pinteger = nil; + const filter: pfilenamety = nil; //nil -> unused + const colwidth: pinteger = nil; //nil -> default + const includeattrib: fileattributesty = [fa_all]; + const excludeattrib: fileattributesty = [fa_hidden]; + const history: pmsestringarty = nil; + const historymaxcount: integer = defaulthistorymaxcount; + const imagelist: timagelist = nil; + const ongetfileicon: getfileiconeventty = nil; + const oncheckfile: checkfileeventty = nil + ): modalresultty; +var + dialog: tfiledialogfo; + str1: msestring; +begin + application.lock; + try + dialog:= tfiledialogfo.create(nil); + if acaption = '' then begin + with stockobjects do begin + if fdo_save in aoptions then begin + str1:= captions[sc_save]; + end + else begin + str1:= captions[sc_open]; + end; + end; + end + else begin + str1:= acaption; + end; + try + result:= filedialog1(dialog,afilenames,filterdesc,filtermask, + filterindex,filter,colwidth, + includeattrib,excludeattrib,history,historymaxcount,str1,aoptions, + adefaultext,imagelist,ongetfileicon,oncheckfile); + + finally + dialog.Free; + end; + finally + application.unlock; + end; +end; + +function filedialog(var afilename: filenamety; + const aoptions: filedialogoptionsty; + const acaption: msestring; + const filterdesc: array of msestring; + const filtermask: array of msestring; + const adefaultext: filenamety = ''; + const filterindex: pinteger = nil; + const filter: pfilenamety = nil; //nil -> unused + const colwidth: pinteger = nil; //nil -> default + const includeattrib: fileattributesty = [fa_all]; + const excludeattrib: fileattributesty = [fa_hidden]; + const history: pmsestringarty = nil; + const historymaxcount: integer = defaulthistorymaxcount; + const imagelist: timagelist = nil; + const ongetfileicon: getfileiconeventty = nil; + const oncheckfile: checkfileeventty = nil + ): modalresultty; +var + ar1: filenamearty; +begin + setlength(ar1,1); + ar1[0]:= afilename; + result:= filedialog(ar1,aoptions,acaption,filterdesc,filtermask,adefaultext, + filterindex, + filter,colwidth,includeattrib,excludeattrib,history,historymaxcount, + imagelist,ongetfileicon,oncheckfile); + if result = mr_ok then begin + if (high(ar1) > 0) or (fdo_quotesingle in aoptions) then begin + afilename:= quotefilename(ar1); + end + else begin + if high(ar1) = 0 then begin + afilename:= ar1[0]; + end + else begin + afilename:= ''; + end; + end; + end; +end; + +{ tfilelistview } + +constructor tfilelistview.create(aowner: tcomponent); +begin + fcaseinsensitive:= filesystemiscaseinsensitive; + fincludeattrib:= [fa_all]; + fexcludeattrib:= [fa_hidden]; + fitemlist:= tfileitemlist.create(self); + foptionsfile:= defaultfilelistviewoptions; + ffilelist:= tfiledatalist.create; + ffilelist.onchange:= {$ifdef FPC}@{$endif}filelistchanged; + inherited; + options:= defaultlistviewoptionsfile; + checkcasesensitive; +end; + +destructor tfilelistview.destroy; +begin + inherited; + ffilelist.Free; +end; + +procedure tfilelistview.checkcasesensitive; +begin + fcaseinsensitive:= filesystemiscaseinsensitive; + if flvo_maskcasesensitive in foptionsfile then begin + fcaseinsensitive:= false; + end; + if flvo_maskcaseinsensitive in foptionsfile then begin + fcaseinsensitive:= true; + end; +// options:= options; //set casesensitive +end; +{ +procedure tfilelistview.setoptions(const Value: listviewoptionsty); +begin + if fcaseinsensitive then begin + inherited setoptions(value - [lvo_casesensitive]); + end + else begin + inherited setoptions(value + [lvo_casesensitive]); + end; +end; +} +procedure tfilelistview.docellevent(var info: celleventinfoty); +var + index: integer; +begin + with info do begin + if iscellclick(info,[ccr_buttonpress]) then begin + options:= options + [lvo_focusselect]; + end; + case eventkind of + cek_enter: begin + if ffocusmoved then begin + options:= options + [lvo_focusselect]; + end + else begin + ffocusmoved:= true; + end; + inherited; + end; + cek_select: begin + index:= celltoindex(cell,false); + if index >= 0 then begin + if (flvo_nofileselect in foptionsfile) and + (ffilelist[index].extinfo1.filetype <> ft_dir) then begin + accept:= false; + end + else begin + if (flvo_nodirselect in foptionsfile) and + (ffilelist[index].extinfo1.filetype = ft_dir) then begin + accept:= false; + end; + end; + inherited; + end + else begin + inherited; + end; + end; + else begin + inherited; + end; + end; + end; +end; + +procedure tfilelistview.filelistchanged(const sender: tobject); +var + int1: integer; + po1: pfilelistitem; + po2: pfileinfoty; + imlist1: timagelist; + imnr1: integer; + bo1: boolean; +begin + options:= options - [lvo_focusselect]; + ffocusmoved:= false; + with ffilelist do begin + self.beginupdate; + self.fitemlist.beginupdate; + try + self.fitemlist.clear; + self.fitemlist.count:= count; + po1:= pfilelistitem(self.fitemlist.datapo); + po2:= pfileinfoty(datapo); + bo1:= checksubdir; + for int1:= 0 to count - 1 do begin + if bo1 and (po2^.extinfo1.filetype = ft_dir) and + dirhasentries(path+'/'+po2^.name,includeattrib,excludeattrib) then begin + include(po2^.state,fis_hasentry); + end; + updatefileinfo(po1^,po2^,true); + if assigned(fongetfileicon) then begin + imlist1:= po1^.imagelist; + imnr1:= po1^.imagenr; + fongetfileicon(self,po2^,imlist1,imnr1); + po1^.imagelist:= imlist1; + po1^.imagenr:= imnr1; + end; + inc(po1); + inc(po2); + end; + finally + self.fitemlist.endupdate; + self.endupdate; + end; + end; +end; + +function tfilelistview.getselectednames: msestringarty; +var + int1,int2: integer; +begin + int2:=0; + result:= nil; + for int1:= 0 to ffilelist.count - 1 do begin + if fitemlist[int1].selected then begin + additem(result,ffilelist[int1].name,int2); + end; + end; + setlength(result,int2); +end; + +procedure tfilelistview.setselectednames(const avalue: filenamearty); +var + int1: integer; + item1: tlistitem; + po1: plistitematy; +// cell1: gridcoordty; +begin + po1:= fitemlist.datapo; + fitemlist.beginupdate; + try + for int1:= 0 to fitemlist.count - 1 do begin + po1^[int1].selected:= false; + end; + for int1:= 0 to high(avalue) do begin + item1:= finditembycaption(avalue[int1]); + if item1 <> nil then begin + item1.selected:= true; + end; + end; + finally + fitemlist.endupdate; + end; +{ + for int1:= 0 to high(avalue) do begin + if findcellbycaption(avalue[int1],cell1) then begin + fdatacols.selected[cell1]:= true; + end; + end; + } +// focuscell(cell1); +end; + +procedure tfilelistview.setfilelist(const Value: tfiledatalist); +begin + if ffilelist <> value then begin + ffilelist.Assign(value); + end; +end; + +procedure tfilelistview.readlist; +var + int1: integer; + po1: pfileinfoty; + level1: fileinfolevelty; +begin + beginupdate; + try + defocuscell; + fdatacols.clearselection; + ffilelist.clear; + ffilecount:= 0; + level1:= fil_type; + if assigned(foncheckfile) then begin + level1:= fil_ext2; + end; + if fmaskar = nil then begin + ffilelist.adddirectory(fdirectory,level1,fmaskar, + fincludeattrib,fexcludeattrib,foptionsdir, + foncheckfile); + if ffilelist.count > 0 then begin + po1:= ffilelist.itempo(0); + for int1:= 0 to ffilelist.count - 1 do begin + if not (fa_dir in po1^.extinfo1.attributes) then begin + inc(ffilecount); + end; + inc(po1); + end; + end; + end + else begin + if (fincludeattrib = [fa_all]) or not(fa_dir in fincludeattrib) then begin + ffilelist.adddirectory(fdirectory,level1,nil,[fa_dir], + fexcludeattrib*[fa_hidden],foptionsdir,foncheckfile); + int1:= ffilelist.count; + ffilelist.adddirectory(fdirectory,level1,fmaskar,fincludeattrib, + fexcludeattrib+[fa_dir],foptionsdir,foncheckfile); + ffilecount:= ffilelist.count - int1; + end + else begin + ffilelist.adddirectory(fdirectory,level1,fmaskar, + fincludeattrib,fexcludeattrib,foptionsdir,foncheckfile); + ffilecount:= ffilelist.count; + end; + end; + finally + endupdate; + end; + if assigned(fonlistread) then begin + fonlistread(self); + end; +end; + +procedure tfilelistview.updir; +var + str1: msestring; + int1: integer; +begin + str1:= removelastdir(fdirectory,fdirectory); + if str1 <> '' then begin + readlist; + int1:= ffilelist.indexof(str1); + if int1 >= 0 then begin + focuscell(indextocell(int1),fca_focusin); + end; + end; +end; + +procedure tfilelistview.setdirectory(const Value: msestring); +begin + fdirectory:= filepath(value,fk_dir); +end; + +function tfilelistview.getpath: msestring; +begin + if fmaskar = nil then begin + result:= filepath(fdirectory); + end + else begin + result:= filepath(fdirectory,fmaskar[0]); + end; +end; + +procedure tfilelistview.setpath(const Value: filenamety); +var + str1: msestring; +begin + splitfilepath(value,fdirectory,str1); + mask:= str1; + readlist; +end; + +procedure tfilelistview.setmask(const value: filenamety); +begin + unquotefilename(value,fmaskar); +end; + +function tfilelistview.getmask: filenamety; +begin + result:= quotefilename(fmaskar); +end; + +function tfilelistview.filecount: integer; +begin + if ffilelist.count < ffilecount then begin + ffilecount:= 0; + end; + result:= ffilecount; +end; + +function tfilelistview.getchecksubdir: boolean; +begin + result:= flvo_checksubdir in foptionsfile; +end; + +procedure tfilelistview.setchecksubdir(const avalue: boolean); +begin + if avalue then begin + include(foptionsfile,flvo_checksubdir); + end + else begin + exclude(foptionsfile,flvo_checksubdir); + end; +end; + +procedure tfilelistview.setoptionsfile(const avalue: filelistviewoptionsty); +const + mask1: filelistviewoptionsty = [flvo_maskcasesensitive,flvo_maskcaseinsensitive]; +begin + if avalue <> foptionsfile then begin + foptionsfile:= filelistviewoptionsty( + setsinglebit({$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptionsfile), + {$ifdef FPC}longword{$else}byte{$endif}(mask1))); + foptionsdir:= dirstreamoptionsty(foptionsfile) * + [dso_casesensitive,dso_caseinsensitive]; + checkcasesensitive; + end; +end; + +{ tfilelistitem } + +constructor tfilelistitem.create(const aowner: tcustomitemlist); +begin + inherited; +end; + +{ tfileitemlist } + +procedure tfileitemlist.createitem(out item: tlistitem); +begin + item:= tfilelistitem.create(self); +end; + + { tfiledialogfo } + +procedure Tfiledialogfo.createdironexecute(const sender: TObject); +var + mstr1: msestring; +begin + mstr1:= ''; + with stockobjects do begin + if stringenter(mstr1,captions[sc_name], + captions[sc_create_new_directory]) = mr_ok then begin + mstr1:= filepath(listview.directory,mstr1,fk_file); + msefileutils.createdir(mstr1); + changedir(mstr1); + filename.setfocus; + end; + end; +end; + +procedure tfiledialogfo.listviewselectionchanged(const sender: tcustomlistview); +var + ar1: msestringarty; +begin + ar1:= nil; //compiler warning + if not (fdo_directory in dialogoptions) then begin + ar1:= listview.selectednames; + if length(ar1) > 0 then begin + if length(ar1) > 1 then begin + filename.value:= quotefilename(ar1); + end + else begin + filename.value:= ar1[0]; + end; + end + else begin +// filename.value:= ''; //dir chanaged + end; + end; +end; + +function tfiledialogfo.changedir(const adir: filenamety): boolean; +begin + result:= tryreadlist(filepath(adir),true); + if result then begin + course(adir); + end; + with listview do begin + if filelist.count > 0 then begin + focuscell(makegridcoord(0,0)); + end; + end; +end; + +procedure tfiledialogfo.listviewitemevent(const sender: tcustomlistview; + const index: Integer; var info: celleventinfoty); +var + str1: filenamety; +begin + with tfilelistview(sender) do begin + if iscellclick(info) then begin + if filelist.isdir(index) then begin + str1:= filepath(directory+filelist[index].name); + changedir(str1); + end + else begin + if info.eventkind = cek_keydown then begin + system.exclude(info.keyeventinfopo^.eventstate,es_processed); + //do not eat key_return + end; + if iscellclick(info,[ccr_dblclick,ccr_nokeyreturn]) and + (length(fdatacols.selectedcells) = 1) then begin + okonexecute(nil); + end; + end; + end; + end; +end; + +procedure tfiledialogfo.doup(); +begin + listview.updir(); + course(listview.directory); +end; + +procedure tfiledialogfo.listviewonkeydown(const sender: twidget; var info: keyeventinfoty); +begin + with info do begin + if (key = key_pageup) and (shiftstate = [ss_ctrl]) then begin + doup(); + include(info.eventstate,es_processed); + end; + end; +end; + +procedure Tfiledialogfo.upaction(const sender: TObject); +begin + doup(); +end; +{ +function tfiledialogfo.readlist: boolean; +begin + result:= true; + try + with listview do begin + readlist; + end; + except + on ex: esys do begin + result:= false; + // if esys(ex).error = sye_dirstream then begin + listview.directory:= ''; + with stockobjects do begin + showerror(captions[sc_can_not_read_directory]+ ' ' + esys(ex).text, + captions[sc_error]); +// showerror('Can not read directory '''+ esys(ex).text+'''.','Error'); + end; + try + listview.readlist; + except + application.handleexception(self); + end; +// end +// else begin +// application.handleexception(self); +// end; + end; + else begin + result:= false; + application.handleexception(self); + end; + end; +end; +} +function tfiledialogfo.tryreadlist(const adir: filenamety; + const errormessage: boolean): boolean; + //restores old dir on error +var + dirbefore: filenamety; +begin + dirbefore:= listview.directory; + listview.directory:= adir; + result:= false; + try + listview.readlist; + result:= true; + except + on ex: esys do begin + result:= false; + if errormessage then begin + with stockobjects do begin + showerror(captions[sc_can_not_read_directory]+ ' ' + + msestring(esys(ex).text),captions[sc_error]); + end; + end; + end; + else begin + result:= false; + application.handleexception(self); + end; + end; + if not result then begin + listview.directory:= dirbefore; + try + listview.readlist; + except + listview.directory:= ''; + listview.readlist; + end; + end; +end; + +procedure Tfiledialogfo.filenamesetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var + str1,str2,str3: filenamety; +// ar1: msestringarty; + bo1: boolean; + newdir: filenamety; +begin + newdir:= ''; + avalue:= trim(avalue); + unquotefilename(avalue,fselectednames); + if (fdo_single in dialogoptions) and (high(fselectednames) > 0) then begin + with stockobjects do begin + showmessage(captions[sc_single_item_only]+'.',captions[sc_error]); + end; + accept:= false; + exit; + end; + bo1:= false; + if high(fselectednames) > 0 then begin + str1:= extractrootpath(fselectednames); + if str1 <> '' then begin + bo1:= true; + newdir:= str1; + avalue:= quotefilename(fselectednames); + end; + end + else begin + str3:= filepath(listview.directory,avalue); + splitfilepath(str3,str1,str2); + newdir:= str1; + if hasmaskchars(str2) then begin + filter.value:= str2; + listview.mask:= str2; + str2:= ''; + end + else begin + if searchfile(str3,true) <> '' then begin + newdir:= str3; + str2:= ''; + end; + end; + avalue:= str2; + if str2 = '' then begin + fselectednames:= nil; + end + else begin + setlength(fselectednames,1); + fselectednames[0]:= str2; + end; + bo1:= true; + end; + if bo1 then begin + if tryreadlist(newdir,not finit) then begin + if finit then begin + setlength(fcourse,1); + fcourse[0]:= newdir; + fcourseid:= 0; + end + else begin + course(newdir); + end; + end; + if fdo_directory in dialogoptions then begin + avalue:= listview.directory; + end; + end; + listview.selectednames:= fselectednames; +end; + +procedure tfiledialogfo.filepathentered(const sender: tobject); +begin + tryreadlist(listview.directory,true); +// readlist; +end; + +procedure tfiledialogfo.dironsetvalue(const sender: TObject; + var avalue: mseString; var accept: Boolean); +begin +// + accept:= tryreadlist(avalue,true); + if accept then begin + course(avalue); + end; +// listview.directory:= avalue; +end; + +procedure tfiledialogfo.listviewonlistread(const sender: tobject); +begin + with listview do begin + dir.value:= directory; +// if fa_dir in finclude then begin + if fdo_directory in self.dialogoptions then begin + filename.value:= directory; + end; + end; +end; + +procedure tfiledialogfo.updatefiltertext; +begin + with filter,dropdown do begin + if itemindex >= 0 then begin + value:= cols[0][itemindex]; + listview.mask:= cols[1][itemindex]; + end; + end; +end; + +procedure tfiledialogfo.filteronafterclosedropdown(const sender: tobject); +begin + updatefiltertext; + filter.initfocus; +end; + +procedure tfiledialogfo.filteronsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + listview.mask:= avalue; +end; + +procedure tfiledialogfo.okonexecute(const sender: tobject); +var + bo1: boolean; + int1: integer; + str1: filenamety; +begin +// if filename.checkvalue then begin + if (filename.value <> '') or (fdo_acceptempty in dialogoptions) then begin + if fdo_directory in dialogoptions then begin + str1:= quotefilename(listview.directory); + end + else begin + str1:= quotefilename(listview.directory,filename.value); + end; + unquotefilename(str1,filenames); + if (defaultext <> '') then begin + for int1:= 0 to high(filenames) do begin + if not hasfileext(filenames[int1]) then begin + filenames[int1]:= filenames[int1] + '.'+defaultext; + end; + end; + end; + if (fdo_checkexist in dialogoptions) and + not ((filename.value = '') and (fdo_acceptempty in dialogoptions)) then begin + if fdo_directory in dialogoptions then begin + bo1:= finddir(filenames[0]); + end + else begin + bo1:= findfile(filenames[0]); + end; + if fdo_save in dialogoptions then begin + if bo1 then begin + with stockobjects do begin + if not askok(captions[sc_file]+' "'+filenames[0]+ + '" '+ captions[sc_exists_overwrite], + captions[sc_warningupper]) then begin +// if not askok('File "'+filenames[0]+ +// '" exists, do you want to overwrite?','WARNING') then begin + filename.setfocus; + exit; + end; + end; + end; + end + else begin + if not bo1 then begin + with stockobjects do begin + showerror(captions[sc_file]+' "'+filenames[0]+'" '+ + captions[sc_does_not_exist]+'.', + captions[sc_errorupper]); + end; +// showerror('File "'+filenames[0]+'" does not exist.'); + filename.setfocus; + exit; + end; + end; + end; + window.modalresult:= mr_ok; + end + else begin + filename.setfocus; + end; +// end; +end; + +procedure tfiledialogfo.layoutev(const sender: TObject); +begin +// placeyorder(2,[2],[dir,listview],2); +// aligny(wam_center,[dir,back,forward,home,up,createdir]); + aligny(wam_center,[filename,showhidden]); + if ok.height <= filter.height then begin + aligny(wam_center,[filter,ok,cancel]); + end + else begin + ok.top:= showhidden.bottom + 4; + aligny(wam_center,[ok,cancel]); + end; +// syncpaintwidth([filename,filter],namecont.bounds_cx); + listview.synctofontheight; +end; + +procedure tfiledialogfo.showhiddenonsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + dir.showhiddenfiles:= avalue; + if avalue then begin + listview.excludeattrib:= listview.excludeattrib - [fa_hidden]; + end + else begin + listview.excludeattrib:= listview.excludeattrib + [fa_hidden]; + end; + listview.readlist; +end; + +procedure tfiledialogfo.formoncreate(const sender: TObject); +begin + fcourseid:= -1; + with stockobjects do begin + dir.frame.caption:= captions[sc_dirhk]; + home.caption:= captions[sc_homehk]; +// up.caption:= captions[sc_uphk]; + createdir.caption:= captions[sc_new_dirhk]; + filename.frame.caption:= captions[sc_namehk]; + filter.frame.caption:= captions[sc_filterhk]; + showhidden.frame.caption:= captions[sc_show_hidden_fileshk]; + ok.caption:= modalresulttext[mr_ok]; + cancel.caption:= modalresulttext[mr_cancel]; + end; + back.tag:= ord(sc_back); + forward.tag:= ord(sc_forward); + up.tag:= ord(sc_up); +end; + +procedure tfiledialogfo.dirshowhint(const sender: TObject; + var info: hintinfoty); +begin + if dir.editor.textclipped then begin + info.caption:= dir.value; + end; +end; + +procedure tfiledialogfo.copytoclip(const sender: TObject; var avalue: msestring); +begin + tosysfilepath1(avalue); +end; + +procedure tfiledialogfo.pastefromclip(const sender: TObject; + var avalue: msestring); +begin + tomsefilepath1(avalue); +end; + +procedure tfiledialogfo.homeaction(const sender: TObject); +begin + if tryreadlist(sys_getuserhomedir,true) then begin + dir.value:= listview.directory; + course(listview.directory); + end; +end; + +procedure tfiledialogfo.checkcoursebuttons(); +begin + back.enabled:= fcourseid > 0; + forward.enabled:= fcourseid < high(fcourse); +end; + +procedure tfiledialogfo.course(const adir: filenamety); +begin + if not fcourselock then begin + inc(fcourseid); + setlength(fcourse,fcourseid+1); + fcourse[fcourseid]:= adir; + checkcoursebuttons(); + end; +end; + +procedure tfiledialogfo.backexe(const sender: TObject); +begin + fcourselock:= true; + try + dec(fcourseid); + if changedir(fcourse[fcourseid]) then begin + checkcoursebuttons(); + end + else begin + inc(fcourseid); + end; + finally + fcourselock:= false; + end; +end; + +procedure tfiledialogfo.forwardexe(const sender: TObject); +begin + fcourselock:= true; + try + inc(fcourseid); + if changedir(fcourse[fcourseid]) then begin + checkcoursebuttons(); + end + else begin + dec(fcourseid); + end; + finally + fcourselock:= false; + end; +end; + +procedure tfiledialogfo.buttonshowhint(const sender: TObject; + var ainfo: hintinfoty); +begin + with tcustombutton(sender) do begin + ainfo.caption:= sc(stockcaptionty(tag))+' '+ + '('+encodeshortcutname(shortcut)+')'; + end; +end; + +{ tfiledialogcontroller } + +constructor tfiledialogcontroller.create(const aowner: tmsecomponent = nil; + const onchange: proceventty = nil); +begin + foptions:= defaultfiledialogoptions; + fhistorymaxcount:= defaulthistorymaxcount; + fowner:= aowner; + ffilterlist:= tdoublemsestringdatalist.create; + finclude:= [fa_all]; + fexclude:= [fa_hidden]; + fonchange:= onchange; + inherited create; +end; + +destructor tfiledialogcontroller.destroy; +begin + inherited; + ffilterlist.Free; +end; + +procedure tfiledialogcontroller.readstatvalue(const reader: tstatreader); +begin + ffilenames:= reader.readarray('filenames',ffilenames); + if fdo_params in foptions then begin + fparams:= reader.readmsestring('params',fparams); + end; +end; + +procedure tfiledialogcontroller.readstatstate(const reader: tstatreader); +begin + ffilterindex:= reader.readinteger('filefilterindex',ffilterindex); + ffilter:= reader.readmsestring('filefilter',ffilter); + fwindowrect.x:= reader.readinteger('x',fwindowrect.x); + fwindowrect.y:= reader.readinteger('y',fwindowrect.y); + fwindowrect.cx:= reader.readinteger('cx',fwindowrect.cx); + fwindowrect.cy:= reader.readinteger('cy',fwindowrect.cy); + fcolwidth:= reader.readinteger('filecolwidth',fcolwidth); + if fdo_chdir in foptions then begin +// try + trysetcurrentdirmse(flastdir); +// except +// end; + end; +end; + +procedure tfiledialogcontroller.readstatoptions(const reader: tstatreader); +begin + if fdo_savelastdir in foptions then begin + flastdir:= reader.readmsestring('lastdir',flastdir); + end; + if fhistorymaxcount > 0 then begin + fhistory:= reader.readarray('filehistory',fhistory); + end; +end; + +procedure tfiledialogcontroller.writestatvalue(const writer: tstatwriter); +begin + writer.writearray('filenames',ffilenames); + if fdo_params in foptions then begin + writer.writemsestring('params',fparams); + end; +end; + +procedure tfiledialogcontroller.writestatstate(const writer: tstatwriter); +begin + writer.writeinteger('filecolwidth',fcolwidth); + writer.writeinteger('x',fwindowrect.x); + writer.writeinteger('y',fwindowrect.y); + writer.writeinteger('cx',fwindowrect.cx); + writer.writeinteger('cy',fwindowrect.cy); +end; + +procedure tfiledialogcontroller.writestatoptions(const writer: tstatwriter); +begin + if fdo_savelastdir in foptions then begin + writer.writemsestring('lastdir',flastdir); + end; + if fhistorymaxcount > 0 then begin + writer.writearray('filehistory',fhistory); + end; + writer.writeinteger('filefilterindex',ffilterindex); + writer.writemsestring('filefilter',ffilter); +end; + +procedure tfiledialogcontroller.componentevent(const event: tcomponentevent); +begin + if (fdo_link in foptions) and (event.sender <> self) and + (event.sender is tfiledialogcontroller) then begin + with tfiledialogcontroller(event.sender) do begin + if fgroup = self.fgroup then begin + self.flastdir:= flastdir; + end; + end; + end; +end; + +procedure tfiledialogcontroller.checklink; +begin + if (fdo_link in foptions) and (fowner <> nil) then begin + fowner.sendrootcomponentevent(tcomponentevent.create(self),true); + end; +end; + +function tfiledialogcontroller.execute(dialogkind: filedialogkindty; + const acaption: msestring; + aoptions: filedialogoptionsty): modalresultty; +var + po1: pmsestringarty; + fo: tfiledialogfo; + ara,arb: msestringarty; + rectbefore: rectty; +begin + ara:= nil; //compiler warning + arb:= nil; //compiler warning + result:= mr_ok; + if assigned(fonbeforeexecute) then begin + fonbeforeexecute(self,dialogkind,result); + if result <> mr_ok then begin + exit; + end; + end; + if fhistorymaxcount > 0 then begin + po1:= @fhistory; + end + else begin + po1:= nil; + end; + fo:= tfiledialogfo.create(nil); + try + {$ifdef FPC} {$checkpointer off} {$endif} //todo!!!!! bug 3348 + ara:= ffilterlist.asarraya; + arb:= ffilterlist.asarrayb; + if dialogkind <> fdk_none then begin + if dialogkind in [fdk_save,fdk_new] then begin + system.include(aoptions,fdo_save); + end + else begin + system.exclude(aoptions,fdo_save); + end; + end; + if fdo_relative in foptions then begin + fo.listview.directory:= getcurrentdirmse; + end + else begin + fo.listview.directory:= flastdir; + end; + if (fwindowrect.cx > 0) and (fwindowrect.cy > 0) then begin + fo.widgetrect:= clipinrect(fwindowrect,application.screenrect(fo.window)); + end; + rectbefore:= fo.widgetrect; + result:= filedialog1(fo,ffilenames,ara,arb, + @ffilterindex,@ffilter,@fcolwidth,finclude, + fexclude,po1,fhistorymaxcount,acaption, + aoptions-[fdo_sysfilename],fdefaultext, + fimagelist,fongetfileicon,foncheckfile); + if not rectisequal(fo.widgetrect,rectbefore) then begin + fwindowrect:= fo.widgetrect; + end; + if assigned(fonafterexecute) then begin + fonafterexecute(self,result); + end; + {$ifdef FPC} {$checkpointer default} {$endif} + if result = mr_ok then begin + if fdo_relative in foptions then begin + flastdir:= getcurrentdirmse; + end + else begin + flastdir:= fo.dir.value; + end; + end; + finally + fo.Free; + end; +end; + +function tfiledialogcontroller.execute(const dialogkind: filedialogkindty; + const acaption: msestring): modalresultty; +begin + result:= execute(dialogkind,acaption,foptions); +end; + +function tfiledialogcontroller.actcaption( + const dialogkind: filedialogkindty): msestring; +begin + case dialogkind of + fdk_save: begin + result:= fcaptionsave; + end; + fdk_new: begin + result:= fcaptionnew; + end; + else begin + result:= fcaptionopen; + end; + end; +end; + +function tfiledialogcontroller.execute(const dialogkind: filedialogkindty; + const aoptions: filedialogoptionsty): modalresultty; +begin + result:= execute(dialogkind,actcaption(dialogkind),aoptions); +end; + +function tfiledialogcontroller.execute( + dialogkind: filedialogkindty = fdk_none): modalresultty; +begin + if dialogkind = fdk_none then begin + if fdo_save in foptions then begin + dialogkind:= fdk_save; + end + else begin + dialogkind:= fdk_open; + end; + end; + result:= execute(dialogkind,actcaption(dialogkind)); +end; + +function tfiledialogcontroller.execute(var avalue: filenamety; + dialogkind: filedialogkindty = fdk_none): boolean; +begin + if dialogkind = fdk_none then begin + if fdo_save in foptions then begin + dialogkind:= fdk_save; + end + else begin + dialogkind:= fdk_open; + end; + end; + result:= execute(avalue,dialogkind,actcaption(dialogkind)); +end; + +function tfiledialogcontroller.execute(var avalue: filenamety; + const dialogkind: filedialogkindty; const acaption: msestring; + aoptions: filedialogoptionsty): boolean; +var + wstr1: filenamety; +begin + wstr1:= filename; + if assigned(fongetfilename) then begin + result:= true; + fongetfilename(self,avalue,result); + if not result then begin + exit; + end; + end; + filename:= avalue; + result:= execute(dialogkind,acaption,aoptions) = mr_ok; + if result then begin + avalue:= filename; + checklink; + end + else begin + filename:= wstr1; + end; +end; + +function tfiledialogcontroller.canoverwrite(): boolean; +begin + with stockobjects do begin + result:= not findfile(filename) or + askok(captions[sc_file]+' "'+filename+ + '" '+ captions[sc_exists_overwrite], + captions[sc_warningupper]); + end; +end; + +function tfiledialogcontroller.execute(var avalue: filenamety; + const dialogkind: filedialogkindty; + const acaption: msestring): boolean; +begin + result:= execute(avalue,dialogkind,acaption,foptions); +end; + +function tfiledialogcontroller.getfilename: filenamety; +begin + if (high(ffilenames) > 0) or (fdo_quotesingle in foptions) or + (fdo_params in foptions) and (high(ffilenames) = 0) and + (findchar(pmsechar(ffilenames[0]),' ') > 0) then begin + result:= quotefilename(ffilenames); + end + else begin + if high(ffilenames) = 0 then begin + result:= ffilenames[0]; + end + else begin + result:= ''; + end; + end; + if (fdo_params in foptions) and (fparams <> '') then begin + if fdo_sysfilename in foptions then begin + tosysfilepath1(result); + end; + result:= result + ' '+fparams; + end + else begin + if fdo_sysfilename in foptions then begin + tosysfilepath1(result); + end; + end; +end; + +const + quotechar = msechar('"'); + +procedure tfiledialogcontroller.setfilename(const avalue: filenamety); +var + int1: integer; + akind: filekindty; +begin + unquotefilename(avalue,ffilenames); + if fdo_params in foptions then begin + fparams:= ''; + if high(ffilenames) >= 0 then begin + if avalue[1] = quotechar then begin + fparams:= copy(avalue,length(ffilenames[0])+3,bigint); + if (fparams <> '') and (fparams[1] = ' ') then begin + delete(fparams,1,1); + end; + setlength(ffilenames,1); + end + else begin + int1:= findchar(ffilenames[0],' '); + if int1 > 0 then begin + fparams:= copy(ffilenames[0],int1+1,bigint); + setlength(ffilenames[0],int1-1); + end; + end; + end; + end; + akind:= fk_default; + if fdo_directory in foptions then begin + akind:= fk_dir; + if fdo_file in foptions then begin + akind:= fk_file; + end; + end + else begin + if fdo_file in foptions then begin + akind:= fk_file; + end; + end; + if [fdo_relative,fdo_lastdirrelative,fdo_basedirrelative] * + foptions <> [] then begin + if fdo_relative in foptions then begin + flastdir:= getcurrentdirmse; + end + else begin + if fdo_basedirrelative in foptions then begin + flastdir:= fbasedir; + end; + end; + for int1:= 0 to high(ffilenames) do begin + if isrootpath(filenames[int1]) then begin + ffilenames[int1]:= relativepath(filenames[int1],flastdir,akind); + end; + end; + end + else begin + if high(ffilenames) = 0 then begin + if fdo_directory in foptions{akind = fk_dir} then begin + flastdir:= filepath(avalue,fk_dir); + end + else begin + flastdir:= filedir(avalue); + end; + end; + for int1:= 0 to high(ffilenames) do begin + ffilenames[int1]:= filepath(filenames[int1],akind, + not (fdo_absolute in foptions)); + end; + end; +end; + +procedure tfiledialogcontroller.setfilterlist( + const Value: tdoublemsestringdatalist); +begin + ffilterlist.assign(Value); +end; + +procedure tfiledialogcontroller.sethistorymaxcount(const Value: integer); +begin + fhistorymaxcount := Value; + if length(fhistory) > fhistorymaxcount then begin + setlength(fhistory,fhistorymaxcount); + end; +end; + +procedure tfiledialogcontroller.dochange; +begin + if assigned(fonchange) then begin + fonchange; + end; +end; + +procedure tfiledialogcontroller.setdefaultext(const avalue: filenamety); +begin + if fdefaultext <> avalue then begin + fdefaultext := avalue; + dochange; + end; +end; + +procedure tfiledialogcontroller.setoptions(Value: filedialogoptionsty); +(* +const + mask1: filedialogoptionsty = [fdo_absolute,fdo_relative]; +// mask2: filedialogoptionsty = [fdo_directory,fdo_file]; + mask3: filedialogoptionsty = [fdo_filtercasesensitive,fdo_filtercaseinsensitive]; +*) +begin + value:= filedialogoptionsty(setsinglebit(card32(value),card32(foptions), + [card32([fdo_absolute,fdo_relative,fdo_lastdirrelative, + fdo_basedirrelative]), + card32([fdo_filtercasesensitive,fdo_filtercaseinsensitive])])); + (* + {$ifdef FPC}longword{$else}longword{$endif}(value):= + setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask1)); +// {$ifdef FPC}longword{$else}longword{$endif}(value):= +// setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(value), +// {$ifdef FPC}longword{$else}longword{$endif}(foptions), +// {$ifdef FPC}longword{$else}longword{$endif}(mask2)); + {$ifdef FPC}longword{$else}longword{$endif}(value):= + setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask3)); + *) + if foptions <> value then begin + foptions:= Value; + if not (fdo_params in foptions) then begin + fparams:= ''; + end; + dochange; + end; +end; + +procedure tfiledialogcontroller.clear; +begin + ffilenames:= nil; + flastdir:= ''; + fhistory:= nil; +end; + +procedure tfiledialogcontroller.setfilenamelastdir(const afilename: filenamety); +begin + filename:= filepath(lastdir,afilename); +end; + +procedure tfiledialogcontroller.setlastdir(const avalue: filenamety); +begin + flastdir:= avalue; + checklink; +end; + +procedure tfiledialogcontroller.setimagelist(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); +end; + +function tfiledialogcontroller.getsysfilename: filenamety; +var + bo1: boolean; +begin + bo1:= fdo_sysfilename in foptions; + system.include(foptions,fdo_sysfilename); + result:= getfilename; + if not bo1 then begin + system.exclude(foptions,fdo_sysfilename); + end; +end; + +{ tfiledialog } + +constructor tfiledialog.create(aowner: tcomponent); +begin +// foptionsedit:= defaultfiledialogoptionsedit; + foptionsedit1:= defaultfiledialogoptionsedit1; + fcontroller:= tfiledialogcontroller.create(nil); + inherited; +end; + +destructor tfiledialog.destroy; +begin + inherited; + fcontroller.free; +end; + +function tfiledialog.execute: modalresultty; +begin + result:= fcontroller.execute(fdialogkind); +end; + +function tfiledialog.execute(const akind: filedialogkindty): modalresultty; +begin + result:= fcontroller.execute(akind); +end; + +function tfiledialog.execute(const akind: filedialogkindty; + const aoptions: filedialogoptionsty): modalresultty; +begin + result:= fcontroller.execute(akind,aoptions); +end; + +procedure tfiledialog.setcontroller(const value: tfiledialogcontroller); +begin + fcontroller.assign(value); +end; + +procedure tfiledialog.dostatread(const reader: tstatreader); +begin + if canstatvalue(foptionsedit1,reader) then begin + fcontroller.readstatvalue(reader); + end; + if canstatstate(foptionsedit1,reader) then begin + fcontroller.readstatstate(reader); + end; + if canstatoptions(foptionsedit1,reader) then begin + fcontroller.readstatoptions(reader); + end; +end; + +procedure tfiledialog.dostatwrite(const writer: tstatwriter); +begin + if canstatvalue(foptionsedit1,writer) then begin + fcontroller.writestatvalue(writer); + end; + if canstatstate(foptionsedit1,writer) then begin + fcontroller.writestatstate(writer); + end; + if canstatoptions(foptionsedit1,writer) then begin + fcontroller.writestatoptions(writer); + end; +end; + +function tfiledialog.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tfiledialog.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tfiledialog.statreading; +begin + //dummy +end; + +procedure tfiledialog.statread; +begin + //dummy +end; + +procedure tfiledialog.componentevent(const event: tcomponentevent); +begin + fcontroller.componentevent(event); + inherited; +end; + +function tfiledialog.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tfiledialog.readoptionsedit(reader: treader); +var + opt1: optionseditty; +begin + opt1:= optionseditty(reader.readset(typeinfo(optionseditty))); + updatebit(longword(foptionsedit1),ord(oe1_savevalue),oe_savevalue in opt1); + updatebit(longword(foptionsedit1),ord(oe1_savestate),oe_savestate in opt1); + updatebit(longword(foptionsedit1),ord(oe1_saveoptions),oe_saveoptions in opt1); + updatebit(longword(foptionsedit1),ord(oe1_checkvalueafterstatread), + oe_checkvaluepaststatread in opt1); +end; + +procedure tfiledialog.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('optionsedit',@readoptionsedit,nil,false); +end; + +{ tfilenameeditcontroller } + +constructor tfilenameeditcontroller.create(const aowner: tcustomfilenameedit1); +begin + inherited create(aowner); +end; + +function tfilenameeditcontroller.execute(var avalue: msestring): boolean; +begin + with tcustomfilenameedit1(fowner) do begin + if fcontroller <> nil then begin + result:= fcontroller.execute(avalue); + end + else begin + result:= false; + end; + end; +end; + +{ tcustomfilenameedit1 } + +constructor tcustomfilenameedit1.create(aowner: tcomponent); +begin +// fcontroller:= tfiledialogcontroller.create(self,{$ifdef FPC}@{$endif}formatchanged); + inherited; + optionsedit1:= defaultfiledialogoptionsedit1; +end; + +destructor tcustomfilenameedit1.destroy; +begin + inherited; +// fcontroller.Free; +end; +{ +function tcustomfilenameedit.execute(var avalue: msestring): boolean; +begin + result:= fcontroller.execute(avalue); +end; +} +procedure tcustomfilenameedit1.setcontroller(const avalue: tfiledialogcontroller); +begin + if fcontroller <> nil then begin + fcontroller.assign(avalue); + end; +end; + +procedure tcustomfilenameedit1.readstatvalue(const reader: tstatreader); +begin + if fgridintf <> nil then begin + inherited; + end + else begin + if fcontroller <> nil then begin + fcontroller.readstatvalue(reader); + value:= fcontroller.filename; + end; + end; +end; + +procedure tcustomfilenameedit1.readstatstate(const reader: tstatreader); +begin + if fcontroller <> nil then begin + fcontroller.readstatstate(reader); + end; +end; + +procedure tcustomfilenameedit1.readstatoptions(const reader: tstatreader); +begin + if fcontroller <> nil then begin + fcontroller.readstatoptions(reader); + end; +end; + +procedure tcustomfilenameedit1.writestatvalue(const writer: tstatwriter); +begin + if fgridintf <> nil then begin + inherited; + end + else begin + if fcontroller <> nil then begin + fcontroller.writestatvalue(writer); + end; + end; +end; + +procedure tcustomfilenameedit1.writestatstate(const writer: tstatwriter); +begin + if fcontroller <> nil then begin + fcontroller.writestatstate(writer); + end; +end; + +procedure tcustomfilenameedit1.writestatoptions(const writer: tstatwriter); +begin + if fcontroller <> nil then begin + fcontroller.writestatoptions(writer); + end; +end; + +function tcustomfilenameedit1.getvaluetext: msestring; +begin +// result:= filepath(fcontroller.filename); + if fcontroller <> nil then begin + result:= fcontroller.filename; + end + else begin + result:= ''; + end; +end; + +procedure tcustomfilenameedit1.texttovalue(var accept: boolean; + const quiet: boolean); +var + ar1: filenamearty; + mstr1: filenamety; + int1: integer; +begin + if fcontroller <> nil then begin + if (fcontroller.defaultext <> '') then begin + unquotefilename(text,ar1); + for int1:= 0 to high(ar1) do begin + if not hasfileext(ar1[int1]) then begin + ar1[int1]:= ar1[int1] + '.'+controller.defaultext; + end; + end; + mstr1:= quotefilename(ar1); + end + else begin + mstr1:= text; + end; + fcontroller.filename:= mstr1; + end; + inherited; +end; + +procedure tcustomfilenameedit1.updatedisptext(var avalue: msestring); +begin + if fcontroller <> nil then begin + with fcontroller do begin + if fdo_dispname in foptions then begin + avalue:= msefileutils.filename(avalue); + end; + if fdo_dispnoext in foptions then begin + avalue:= removefileext(avalue); + end; + end; + end; +end; + +procedure tcustomfilenameedit1.valuechanged; +begin + if fcontroller <> nil then begin + fcontroller.filename:= value; + end; + inherited; +end; + +procedure tcustomfilenameedit1.componentevent(const event: tcomponentevent); +begin + if fcontroller <> nil then begin + fcontroller.componentevent(event); + end; + inherited; +end; + +procedure tcustomfilenameedit1.updatecopytoclipboard(var atext: msestring); +begin + tosysfilepath1(atext); + inherited; +end; + +procedure tcustomfilenameedit1.updatepastefromclipboard(var atext: msestring); +begin + tomsefilepath1(atext); + inherited; +end; + +function tcustomfilenameedit1.createdialogcontroller: tstringdialogcontroller; +begin + result:= tfilenameeditcontroller.create(self); +end; + +function tcustomfilenameedit1.getsysvalue: filenamety; +begin + result:= tosysfilepath(value); +end; + +procedure tcustomfilenameedit1.setsysvalue(const avalue: filenamety); +begin + value:= tomsefilepath(avalue); +end; + +function tcustomfilenameedit1.getsysvaluequoted: filenamety; +begin + result:= tosysfilepath(value,true); +end; + +{ tcustomfilenameedit } + +constructor tcustomfilenameedit.create(aowner: tcomponent); +begin + fcontroller:= tfiledialogcontroller.create(self, + {$ifdef FPC}@{$endif}formatchanged); + inherited; +end; + +destructor tcustomfilenameedit.destroy; +begin + inherited; + fcontroller.Free; +end; + +{ tdirdropdownedit } + +procedure tdirdropdownedit.createdropdownwidget(const atext: msestring; + out awidget: twidget); +begin + awidget:= tdirtreefo.create(nil); + with tdirtreefo(awidget) do begin + showhiddenfiles:= ddeo_showhiddenfiles in foptions; + checksubdir:= ddeo_checksubdir in foptions; + path:= atext; + onpathchanged:= {$ifdef FPC}@{$endif}pathchanged; + text:= path; + if deo_colsizing in fdropdown.options then begin + optionssizing:= [osi_right]; + end; + end; + feditor.sellength:= 0; +end; + +procedure tdirdropdownedit.doafterclosedropdown; +begin + text:= value; + feditor.selectall; + inherited; +end; + +function tdirdropdownedit.getdropdowntext(const awidget: twidget): msestring; +begin + result:= tdirtreefo(awidget).path; +end; + +procedure tdirdropdownedit.pathchanged(const sender: tobject); +begin + text:= tdirtreefo(sender).path; +end; + +function tdirdropdownedit.getshowhiddenfiles: boolean; +begin + result:= ddeo_showhiddenfiles in foptions; +end; + +procedure tdirdropdownedit.setshowhiddenfiles(const avalue: boolean); +begin + if avalue then begin + include(foptions,ddeo_showhiddenfiles) + end + else begin + exclude(foptions,ddeo_showhiddenfiles) + end; +end; + +function tdirdropdownedit.getchecksubdir: boolean; +begin + result:= ddeo_checksubdir in foptions; +end; + +procedure tdirdropdownedit.setchecksubdir(const avalue: boolean); +begin + if avalue then begin + include(foptions,ddeo_checksubdir) + end + else begin + exclude(foptions,ddeo_checksubdir) + end; +end; + +procedure tdirdropdownedit.updatecopytoclipboard(var atext: msestring); +begin + tosysfilepath1(atext); + inherited; +end; + +procedure tdirdropdownedit.updatepastefromclipboard(var atext: msestring); +begin + tomsefilepath1(atext); + inherited; +end; + +{ tcustomremotefilenameedit } + +procedure tcustomremotefilenameedit.setfiledialog(const avalue: tfiledialog); +begin + setlinkedvar(avalue,tmsecomponent(fdialog)); + if avalue = nil then begin + fcontroller:= nil; + end + else begin + fcontroller:= avalue.fcontroller; + end; +end; + +procedure tcustomremotefilenameedit.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_destroyed) and (sender = fdialog) then begin + fcontroller:= nil; + end; + inherited; +end; + +{ tdirtreeview } + +constructor tdirtreeview.create(aowner: tcomponent); +begin + inherited; + createframe(); + foptionswidget:= defaultoptionswidgetsubfocus; + fdirview:= tdirtreefo.create(nil,self,false); + //owner must be nil because of streaming + fdirview.onpathchanged:= @dopathchanged; + fdirview.onselectionchanged:= @doselectionchanged; + fdirview.treeitem.ondataentered:= @dopathselected; + fdirview.grid.frame.framewidth:= 0; + fdirview.bounds_cxmin:= 0; + fdirview.anchors:= []; + fdirview.visible:= true; +end; + +destructor tdirtreeview.destroy(); +begin + fdirview.free(); + inherited; //fdirview destroyed by destroy children +end; + +procedure tdirtreeview.refresh(); +begin + tdirtreefo1(fdirview).updatepath(); +end; + +function tdirtreeview.getoptions: dirtreeoptionsty; +begin + result:= fdirview.optionsdir; +end; + +procedure tdirtreeview.setoptions(const avalue: dirtreeoptionsty); +begin + fdirview.optionsdir:= avalue; +end; + +function tdirtreeview.getpath: filenamety; +begin + if csdesigning in componentstate then begin + result:= fpath; + end + else begin + result:= fdirview.path; + end; +end; + +procedure tdirtreeview.setpath(const avalue: filenamety); +begin + fpath:= avalue; + if componentstate * [csdesigning,csloading] = [] then begin + fdirview.path:= avalue; + end; +end; + +procedure tdirtreeview.setroot(const avalue: filenamety); +begin + froot:= avalue; + if componentstate * [csdesigning,csloading] = [] then begin + fdirview.root:= avalue; + end; +end; + +function tdirtreeview.getgrid: twidgetgrid; +begin + result:= fdirview.grid; +end; + +procedure tdirtreeview.setgrid(const avalue: twidgetgrid); +begin + //dummy +end; + +function tdirtreeview.getoptionstree: treeitemeditoptionsty; +begin + result:= fdirview.treeitem.options; +end; + +procedure tdirtreeview.setoptionstree(const avalue: treeitemeditoptionsty); +begin + fdirview.treeitem.options:= avalue; +end; + +function tdirtreeview.getoptionsedit: optionseditty; +begin + result:= fdirview.treeitem.optionsedit; +end; + +procedure tdirtreeview.setoptionsedit(const avalue: optionseditty); +begin + fdirview.treeitem.optionsedit:= avalue; +end; + +function tdirtreeview.getcol_color: colorty; +begin + result:= fdirview.grid.datacols[0].color; +end; + +procedure tdirtreeview.setcol_color(const avalue: colorty); +begin + fdirview.grid.datacols[0].color:= avalue; +end; + +function tdirtreeview.getcol_coloractive: colorty; +begin + result:= fdirview.grid.datacols[0].coloractive; +end; + +procedure tdirtreeview.setcol_coloractive(const avalue: colorty); +begin + fdirview.grid.datacols[0].coloractive:= avalue; +end; + +function tdirtreeview.getcol_colorfocused: colorty; +begin + result:= fdirview.grid.datacols[0].colorfocused; +end; + +procedure tdirtreeview.setcol_colorfocused(const avalue: colorty); +begin + fdirview.grid.datacols[0].colorfocused:= avalue; +end; + +function tdirtreeview.getcell_options: coloptionsty; +begin + result:= fdirview.grid.datacols[0].options; +end; + +procedure tdirtreeview.setcell_options(const avalue: coloptionsty); +begin + fdirview.grid.datacols[0].options:= avalue; +end; +{ +function tdirtreeview.getcell_frame: tcellframe; +begin + if csreading in componentstate then begin + fdirview.grid.datacols[0].createframe(); + end; + result:= fdirview.grid.datacols[0].frame; +end; + +procedure tdirtreeview.setcell_frame(const avalue: tcellframe); +begin + fdirview.grid.datacols[0].frame:= avalue; +end; + +function tdirtreeview.getcell_face: tcellface; +begin + if csreading in componentstate then begin + fdirview.grid.datacols[0].createface(); + end; + result:= fdirview.grid.datacols[0].face; +end; + +procedure tdirtreeview.setcell_face(const avalue: tcellface); +begin + if avalue <> nil then begin + fdirview.grid.datacols[0].createface(); + end; + fdirview.grid.datacols[0].face:= avalue; +end; + +function tdirtreeview.getcell_datalist: ttreeitemeditlist; +begin + result:= ttreeitemeditlist(fdirview.grid.datacols[0].datalist); +end; + +procedure tdirtreeview.setcell_datalist(const avalue: ttreeitemeditlist); +begin + fdirview.grid.datacols[0].datalist:= avalue; +end; +} +procedure tdirtreeview.dopathchanged(const sender: tobject); +begin + if canevent(tmethod(fonpathchanged)) then begin + fonpathchanged(self,fdirview.path); + end; +end; + +procedure tdirtreeview.dopathselected(const sender: tobject); +begin + if canevent(tmethod(fonpathselected)) then begin + fonpathselected(self,fdirview.path); + end; +end; + +procedure tdirtreeview.doselectionchanged(const sender: tobject; + const aitem: tlistitem); +begin + if canevent(tmethod(fonselectionchanged)) then begin + fonselectionchanged(self,aitem); + end; +end; + +procedure tdirtreeview.internalcreateframe; +begin + timpressedcaptionframe.create(icaptionframe(self)); +end; + +procedure tdirtreeview.loaded(); +begin + inherited; + if not (csdesigning in componentstate) then begin + with tdirtreefo1(fdirview) do begin + froot:= self.froot; + path:= self.fpath; + end; + end; +end; + +class function tdirtreeview.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_dataedit; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msefiledialog_mfm.pas b/mseide-msegui/lib/common/dialogs/msefiledialog_mfm.pas new file mode 100644 index 0000000..4105b61 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialog_mfm.pas @@ -0,0 +1,440 @@ +unit msefiledialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefiledialog; + +const + objdata: record size: integer; data: array[0..8445] of byte end = + (size: 8446; data: ( + 84,80,70,48,13,84,102,105,108,101,100,105,97,108,111,103,102,111,12,102, + 105,108,101,100,105,97,108,111,103,102,111,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,14,8,98,111,117,110,100, + 115,95,121,3,70,1,9,98,111,117,110,100,115,95,99,120,3,75,2,9, + 98,111,117,110,100,115,95,99,121,3,51,1,12,98,111,117,110,100,115,95, + 99,120,109,105,110,3,104,1,12,98,111,117,110,100,115,95,99,121,109,105, + 110,3,150,0,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111, + 117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,18,99,111,110,116,97,105,110, + 101,114,46,111,110,108,97,121,111,117,116,7,8,108,97,121,111,117,116,101, + 118,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,75,2,3,51,1,0,7,111,112,116,105,111,110,115,11,17, + 102,111,95,115,99,114,101,101,110,99,101,110,116,101,114,101,100,13,102,111, + 95,99,108,111,115,101,111,110,101,115,99,17,102,111,95,108,111,99,97,108, + 115,104,111,114,116,99,117,116,115,15,102,111,95,97,117,116,111,114,101,97, + 100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116, + 97,116,10,102,111,95,115,97,118,101,112,111,115,0,8,111,110,108,111,97, + 100,101,100,7,12,102,111,114,109,111,110,99,114,101,97,116,101,9,111,110, + 107,101,121,100,111,119,110,7,17,108,105,115,116,118,105,101,119,111,110,107, + 101,121,100,111,119,110,8,111,110,108,97,121,111,117,116,7,8,108,97,121, + 111,117,116,101,118,4,108,101,102,116,3,239,0,3,116,111,112,3,138,0, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109, + 115,101,102,111,114,109,0,13,116,102,105,108,101,108,105,115,116,118,105,101, + 119,8,108,105,115,116,118,105,101,119,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,17,111,119,95,102,111,99, + 117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115,101, + 119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117, + 110,100,115,95,99,120,3,75,2,9,98,111,117,110,100,115,95,99,121,3, + 236,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,9, + 111,110,107,101,121,100,111,119,110,7,17,108,105,115,116,118,105,101,119,111, + 110,107,101,121,100,111,119,110,16,100,97,116,97,114,111,119,108,105,110,101, + 99,111,108,111,114,4,5,0,0,160,16,100,97,116,97,99,111,108,108,105, + 110,101,99,111,108,111,114,4,5,0,0,160,9,99,101,108,108,119,105,100, + 116,104,3,174,0,10,99,101,108,108,104,101,105,103,104,116,2,15,11,111, + 112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105, + 122,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101, + 110,116,101,114,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99, + 111,108,0,7,111,112,116,105,111,110,115,11,12,108,118,111,95,114,101,97, + 100,111,110,108,121,13,108,118,111,95,100,114,97,119,102,111,99,117,115,15, + 108,118,111,95,109,111,117,115,101,115,101,108,101,99,116,13,108,118,111,95, + 107,101,121,115,101,108,101,99,116,15,108,118,111,95,109,117,108,116,105,115, + 101,108,101,99,116,10,108,118,111,95,108,111,99,97,116,101,19,108,118,111, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,18,105,116, + 101,109,108,105,115,116,46,105,109,97,103,101,108,105,115,116,7,20,102,105, + 108,101,100,105,97,108,111,103,114,101,115,46,105,109,97,103,101,115,19,105, + 116,101,109,108,105,115,116,46,105,109,97,103,101,119,105,100,116,104,2,16, + 20,105,116,101,109,108,105,115,116,46,105,109,97,103,101,104,101,105,103,104, + 116,2,16,12,99,101,108,108,119,105,100,116,104,109,105,110,2,50,18,111, + 110,115,101,108,101,99,116,105,111,110,99,104,97,110,103,101,100,7,24,108, + 105,115,116,118,105,101,119,115,101,108,101,99,116,105,111,110,99,104,97,110, + 103,101,100,11,111,110,105,116,101,109,101,118,101,110,116,7,17,108,105,115, + 116,118,105,101,119,105,116,101,109,101,118,101,110,116,16,102,105,108,101,108, + 105,115,116,46,111,112,116,105,111,110,115,11,12,102,108,111,95,115,111,114, + 116,110,97,109,101,12,102,108,111,95,115,111,114,116,116,121,112,101,0,10, + 111,110,108,105,115,116,114,101,97,100,7,18,108,105,115,116,118,105,101,119, + 111,110,108,105,115,116,114,101,97,100,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,9,116,108,97,121,111,117,116,101,114,10,116, + 108,97,121,111,117,116,101,114,50,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95, + 112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,3,6,1,9,98,111,117,110, + 100,115,95,99,120,3,73,2,9,98,111,117,110,100,115,95,99,121,2,42, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112, + 116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97, + 110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95, + 101,120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120, + 112,97,110,100,115,104,114,105,110,107,121,0,7,108,105,110,107,116,111,112, + 7,8,108,105,115,116,118,105,101,119,8,100,105,115,116,95,116,111,112,2, + 2,7,111,112,116,105,111,110,115,11,15,115,112,97,111,95,103,108,117,101, + 98,111,116,116,111,109,0,0,7,116,115,112,97,99,101,114,6,98,117,99, + 111,110,116,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111, + 119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115, + 117,98,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101, + 108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,9, + 8,98,111,117,110,100,115,95,120,3,198,1,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,131,0,9,98,111,117, + 110,100,115,95,99,121,2,42,7,97,110,99,104,111,114,115,11,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105,111, + 110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120, + 11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112, + 97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,8,108,105, + 110,107,108,101,102,116,7,10,116,108,97,121,111,117,116,101,114,49,7,111, + 112,116,105,111,110,115,11,14,115,112,97,111,95,103,108,117,101,114,105,103, + 104,116,15,115,112,97,111,95,103,108,117,101,98,111,116,116,111,109,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,10,115,104,111,119,104,105, + 100,100,101,110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,18, + 38,83,104,111,119,32,104,105,100,100,101,110,32,102,105,108,101,115,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2, + 112,2,2,0,8,98,111,117,110,100,115,95,120,2,6,8,98,111,117,110, + 100,115,95,121,2,4,9,98,111,117,110,100,115,95,99,120,2,125,9,98, + 111,117,110,100,115,95,99,121,2,16,10,111,110,115,101,116,118,97,108,117, + 101,7,20,115,104,111,119,104,105,100,100,101,110,111,110,115,101,116,118,97, + 108,117,101,0,0,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101, + 114,52,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115, + 95,120,2,41,8,98,111,117,110,100,115,95,121,2,22,9,98,111,117,110, + 100,115,95,99,120,2,8,9,98,111,117,110,100,115,95,99,121,2,20,8, + 108,105,110,107,108,101,102,116,7,2,111,107,9,108,105,110,107,114,105,103, + 104,116,7,6,99,97,110,99,101,108,0,0,7,116,98,117,116,116,111,110, + 6,99,97,110,99,101,108,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,13,111,119,49,95,97,117,116,111,119,105,100,116,104,14,111,119, + 49,95,97,117,116,111,104,101,105,103,104,116,0,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,49,8,98,111,117,110,100,115,95,121,2,22,9, + 98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99, + 121,2,20,12,98,111,117,110,100,115,95,99,120,109,105,110,2,35,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11, + 109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99, + 101,108,7,111,112,116,105,111,110,115,11,17,98,111,95,101,120,101,99,117, + 116,101,111,110,99,108,105,99,107,15,98,111,95,101,120,101,99,117,116,101, + 111,110,107,101,121,20,98,111,95,101,120,101,99,117,116,101,111,110,115,104, + 111,114,116,99,117,116,27,98,111,95,101,120,101,99,117,116,101,100,101,102, + 97,117,108,116,111,110,101,110,116,101,114,107,101,121,19,98,111,95,99,97, + 110,100,101,102,111,99,117,115,119,105,110,100,111,119,0,0,0,7,116,98, + 117,116,116,111,110,2,111,107,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,13,111,119,49,95,97,117,116,111,119,105,100,116,104,14,111, + 119,49,95,97,117,116,111,104,101,105,103,104,116,0,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,5,99,111,108,111,114,4,5,0,0,144,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,6, + 8,98,111,117,110,100,115,95,121,2,22,9,98,111,117,110,100,115,95,99, + 120,2,35,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117,110, + 100,115,95,99,120,109,105,110,2,35,5,115,116,97,116,101,11,10,97,115, + 95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102, + 97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7, + 99,97,112,116,105,111,110,6,3,38,79,107,7,111,112,116,105,111,110,115, + 11,17,98,111,95,101,120,101,99,117,116,101,111,110,99,108,105,99,107,15, + 98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98,111,95,101, + 120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27,98,111,95, + 101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101,110,116,101, + 114,107,101,121,19,98,111,95,99,97,110,100,101,102,111,99,117,115,119,105, + 110,100,111,119,0,9,111,110,101,120,101,99,117,116,101,7,11,111,107,111, + 110,101,120,101,99,117,116,101,0,0,0,9,116,108,97,121,111,117,116,101, + 114,10,116,108,97,121,111,117,116,101,114,49,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17, + 111,119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,98,111,117,110, + 100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,197,1,9,98,111,117,110,100,115,95,99,121, + 2,42,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99, + 95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121, + 17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17,111, + 115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111,112, + 116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,97,108,105, + 103,110,120,10,108,97,111,95,112,108,97,99,101,121,0,10,97,108,105,103, + 110,95,109,111,100,101,7,7,119,97,109,95,101,110,100,10,97,108,105,103, + 110,95,103,108,117,101,7,7,119,97,109,95,101,110,100,13,112,108,97,99, + 101,95,109,105,110,100,105,115,116,2,2,13,112,108,97,99,101,95,109,97, + 120,100,105,115,116,2,2,0,17,116,100,114,111,112,100,111,119,110,108,105, + 115,116,101,100,105,116,6,102,105,108,116,101,114,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,7,38,70,105,108,116,101,114,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117, + 110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105, + 116,101,109,115,14,1,0,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,34,2,0,0,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,22,9,98,111,117,110,100,115,95,99,120,3,192, + 1,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,15,102,105,108, + 101,112,97,116,104,101,110,116,101,114,101,100,10,111,110,115,101,116,118,97, + 108,117,101,7,16,102,105,108,116,101,114,111,110,115,101,116,118,97,108,117, + 101,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,15, + 100,101,111,95,107,101,121,100,114,111,112,100,111,119,110,12,100,101,111,95, + 99,108,105,112,104,105,110,116,0,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,99,111,117,110,116,2,2,19,100,114,111,112,100,111,119,110, + 46,99,111,108,115,46,105,116,101,109,115,14,1,0,1,7,111,112,116,105, + 111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95, + 105,110,118,105,115,105,98,108,101,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,7,99,111,95,102,105,108,108,0,0,0,17,100,114,111,112, + 100,111,119,110,46,118,97,108,117,101,99,111,108,2,1,20,111,110,97,102, + 116,101,114,99,108,111,115,101,100,114,111,112,100,111,119,110,7,26,102,105, + 108,116,101,114,111,110,97,102,116,101,114,99,108,111,115,101,100,114,111,112, + 100,111,119,110,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,104,105,115,116,111,114,121,101,100,105,116,8,102,105,108,101, + 110,97,109,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5, + 38,78,97,109,101,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,0,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 39,2,0,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,197,1,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117, + 116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101, + 120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118,97,108,117,101, + 13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,17,111,110,99,111,112,121,116,111,99, + 108,105,112,98,111,97,114,100,7,10,99,111,112,121,116,111,99,108,105,112, + 20,111,110,112,97,115,116,101,102,114,111,109,99,108,105,112,98,111,97,114, + 100,7,13,112,97,115,116,101,102,114,111,109,99,108,105,112,10,111,110,115, + 101,116,118,97,108,117,101,7,16,102,105,108,101,110,97,109,101,115,101,116, + 118,97,108,117,101,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111, + 110,115,11,15,100,101,111,95,107,101,121,100,114,111,112,100,111,119,110,12, + 100,101,111,95,99,108,105,112,104,105,110,116,0,25,100,114,111,112,100,111, + 119,110,46,100,114,111,112,100,111,119,110,114,111,119,99,111,117,110,116,2, + 10,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110, + 116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116, + 101,109,115,14,1,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99, + 116,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,0,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,9, + 116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,51, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116, + 97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102, + 111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,2,9,98,111,117, + 110,100,115,95,99,120,3,72,2,9,98,111,117,110,100,115,95,99,121,2, + 20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105, + 111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100, + 121,11,111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120, + 112,97,110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97, + 121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,120,10,108,97,111, + 95,97,108,105,103,110,121,0,10,97,108,105,103,110,95,103,108,117,101,7, + 9,119,97,109,95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110, + 100,105,115,116,2,2,13,112,108,97,99,101,95,109,97,120,100,105,115,116, + 2,2,13,112,108,97,99,101,95,111,112,116,105,111,110,115,11,13,112,108, + 111,95,101,110,100,109,97,114,103,105,110,0,10,108,105,110,107,98,111,116, + 116,111,109,7,8,108,105,115,116,118,105,101,119,11,100,105,115,116,95,98, + 111,116,116,111,109,2,2,0,7,116,98,117,116,116,111,110,9,99,114,101, + 97,116,101,100,105,114,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49, + 95,97,117,116,111,119,105,100,116,104,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110, + 100,115,95,120,3,16,2,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,56,9,98,111,117,110,100,115,95,99,121, + 2,20,12,98,111,117,110,100,115,95,99,120,109,105,110,2,35,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,7,99,97,112,116,105,111,110,6,8,38,78,101,119,32, + 100,105,114,7,111,112,116,105,111,110,115,11,17,98,111,95,101,120,101,99, + 117,116,101,111,110,99,108,105,99,107,15,98,111,95,101,120,101,99,117,116, + 101,111,110,107,101,121,20,98,111,95,101,120,101,99,117,116,101,111,110,115, + 104,111,114,116,99,117,116,27,98,111,95,101,120,101,99,117,116,101,100,101, + 102,97,117,108,116,111,110,101,110,116,101,114,107,101,121,19,98,111,95,99, + 97,110,100,101,102,111,99,117,115,119,105,110,100,111,119,0,9,111,110,101, + 120,101,99,117,116,101,7,18,99,114,101,97,116,101,100,105,114,111,110,101, + 120,101,99,117,116,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,7,116,98,117,116,116,111,110,4,104,111,109,101,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111, + 110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117, + 116,111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116, + 104,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111, + 114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,224,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 46,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117,110,100,115, + 95,99,120,109,105,110,2,35,7,97,110,99,104,111,114,115,11,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112, + 116,105,111,110,6,5,38,72,111,109,101,7,111,112,116,105,111,110,115,11, + 17,98,111,95,101,120,101,99,117,116,101,111,110,99,108,105,99,107,15,98, + 111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98,111,95,101,120, + 101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27,98,111,95,101, + 120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101,110,116,101,114, + 107,101,121,19,98,111,95,99,97,110,100,101,102,111,99,117,115,119,105,110, + 100,111,119,0,9,111,110,101,120,101,99,117,116,101,7,10,104,111,109,101, + 97,99,116,105,111,110,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,17,116,115,116,111,99,107,103,108,121,112,104,98,117,116,116, + 111,110,7,102,111,114,119,97,114,100,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101, + 0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 15,111,119,95,100,105,115,97,98,108,101,100,104,105,110,116,0,8,116,97, + 98,111,114,100,101,114,2,3,10,111,110,115,104,111,119,104,105,110,116,7, + 14,98,117,116,116,111,110,115,104,111,119,104,105,110,116,8,98,111,117,110, + 100,115,95,120,3,209,1,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,13,9,98,111,117,110,100,115,95,99,121, + 2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,11,97,115,95,100, + 105,115,97,98,108,101,100,16,97,115,95,108,111,99,97,108,100,105,115,97, + 98,108,101,100,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105, + 115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101,110,114,16,97, + 115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121,112,104, + 7,14,115,116,103,95,97,114,114,111,119,114,105,103,104,116,11,97,117,116, + 111,115,105,122,101,95,99,120,2,246,9,111,110,101,120,101,99,117,116,101, + 7,10,102,111,114,119,97,114,100,101,120,101,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,2,115,99,1,2,1,3,90,96,0,0,0, + 17,116,115,116,111,99,107,103,108,121,112,104,98,117,116,116,111,110,4,98, + 97,99,107,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13, + 111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,15,111,119,95,100,105,115, + 97,98,108,101,100,104,105,110,116,0,8,116,97,98,111,114,100,101,114,2, + 2,10,111,110,115,104,111,119,104,105,110,116,7,14,98,117,116,116,111,110, + 115,104,111,119,104,105,110,116,8,98,111,117,110,100,115,95,120,3,194,1, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,13,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104, + 111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116, + 0,5,115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100, + 16,97,115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,17,97,115, + 95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108, + 111,99,97,108,105,109,97,103,101,110,114,16,97,115,95,108,111,99,97,108, + 115,104,111,114,116,99,117,116,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,5,103,108,121,112,104,7,13,115,116,103,95,97, + 114,114,111,119,108,101,102,116,11,97,117,116,111,115,105,122,101,95,99,120, + 2,246,9,111,110,101,120,101,99,117,116,101,7,7,98,97,99,107,101,120, + 101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,2,115,99, + 1,2,1,3,90,64,0,0,0,17,116,115,116,111,99,107,103,108,121,112, + 104,98,117,116,116,111,110,2,117,112,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101, + 0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114, + 100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116,7,14,98,117, + 116,116,111,110,115,104,111,119,104,105,110,116,8,98,111,117,110,100,115,95, + 120,3,175,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,17,9,98,111,117,110,100,115,95,99,121,2,20,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97, + 103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101, + 110,114,16,97,115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,5,103, + 108,121,112,104,7,11,115,116,103,95,97,114,114,111,119,117,112,7,111,112, + 116,105,111,110,115,11,17,98,111,95,101,120,101,99,117,116,101,111,110,99, + 108,105,99,107,15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121, + 20,98,111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117, + 116,27,98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111, + 110,101,110,116,101,114,107,101,121,19,98,111,95,99,97,110,100,101,102,111, + 99,117,115,119,105,110,100,111,119,0,9,111,110,101,120,101,99,117,116,101, + 7,8,117,112,97,99,116,105,111,110,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,2,115,99,1,2,1,3,22,65,0,0,0,16,116, + 100,105,114,100,114,111,112,100,111,119,110,101,100,105,116,3,100,105,114,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,4,38,68,105,114,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,0,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0, + 2,20,2,0,0,10,111,110,115,104,111,119,104,105,110,116,7,11,100,105, + 114,115,104,111,119,104,105,110,116,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,173,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,9,116, + 101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114, + 101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101,108, + 108,105,112,115,101,108,101,102,116,0,16,100,114,111,112,100,111,119,110,46, + 111,112,116,105,111,110,115,11,14,100,101,111,95,115,101,108,101,99,116,111, + 110,108,121,15,100,101,111,95,107,101,121,100,114,111,112,100,111,119,110,0, + 10,111,110,115,101,116,118,97,108,117,101,7,13,100,105,114,111,110,115,101, + 116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,Tfiledialogfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msefiledialogres.mfm b/mseide-msegui/lib/common/dialogs/msefiledialogres.mfm new file mode 100644 index 0000000..a65ffe7 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialogres.mfm @@ -0,0 +1,178 @@ +object filedialogres: tfiledialogres + bounds_cx = 235 + bounds_cy = 117 + left = 93 + top = 396 + moduleclassname = 'tmsedatamodule' + object images: timagelist + count = 16 + left = 32 + top = 32 + image = { + 0000000002000000400000004000000038120000000000000000000000000000 + 0000000000000000000000000000000000000000FF00FFA300000006FF00FF1A + 7F7F7F01000000047F7F7F01FF00FF097F7F7F01000000047F7F7F01FF00FF0B + 00000001FFFFFF0400000002FF00FF097F7F7F01000000047F7F7F01FF00FF0A + 00000001FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0900000001 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0B00000001FFFFFF04 + 00000001FFFFFF0100000001FF00FF0800000001FFFFFF0100FFFF01FFFFFF01 + 00FFFF0100000001FF00FF090000000AFF00FF050000000100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100000003FF00FF0800000001FFFFFF04 + 00000001FFFFFF0200000001FF00FF060000000AFF00FF0600000001FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00000001FF00FF0400000001FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0700000001FFFFFF04 + 00000005FF00FF0500000001FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF050000000100FFFF01 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + 00000001FF00FF040000000100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0700000001FFFFFF08 + 0000000180808001FF00FF040000000100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00000001FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0500000001 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100000001FF00FF0400000001FFFFFF0100FFFF01FFFFFF010000000A + FF00FF0400000001FFFFFF080000000180808001FF00FF0400000001FFFFFF01 + 00FFFF01FFFFFF0100FFFF010000000100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00000001FF00FF050000000100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF040000000100FFFF01 + FFFFFF010000000100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF01 + 00FFFF01BFBFBF0100FFFF0100000001FF00FF0400000001FFFFFF0800000001 + 80808001FF00FF040000000100FFFF01FFFFFF0100000005FFFFFF0100FFFF01 + 00000001FF00FF0500000001FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0400000001FFFFFF01 + 0000000100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01 + BFBFBF0100FFFF0100000001FF00FF0500000001FFFFFF080000000180808001 + FF00FF0400000001FFFFFF0100FFFF01FFFFFF0100FFFF010000000100FFFF01 + FFFFFF0100FFFF01FFFFFF0100000001FF00FF050000000100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF0100000001 + FF00FF040000000200FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF01 + 00FFFF01BFBFBF0100FFFF0100000001FF00FF0600000001FFFFFF0800000001 + 80808001FF00FF040000000100FFFF01FFFFFF0100FFFF01FFFFFF0100000001 + FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF060000000AFF00FF05 + 0000000AFF00FF0700000001FFFFFF080000000180808001FF00FF050000000A + FF00FF260000000A80808001FF00FF368080800AFF00FFF500000006FF00FF1A + 7F7F7F01000000047F7F7F01FF00FF097F7F7F01000000047F7F7F01FF00FF0B + 000000017B00FF0400000002FF00FF097F7F7F01000000047F7F7F01FF00FF0A + 00000001FFFFFF017B00FF01FFFFFF017B00FF0100000001FF00FF0900000001 + 7B00FF01FFFFFF017B00FF01FFFFFF0100000001FF00FF0B000000017B00FF04 + 000000017B00FF0100000001FF00FF0800000001FFFFFF017B00FF01FFFFFF01 + 7B00FF0100000001FF00FF090000000AFF00FF05000000017B00FF01FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF0100000003FF00FF08000000017B00FF04 + 000000017B00FF0200000001FF00FF060000000AFF00FF0600000001FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF01 + 00000001FF00FF0400000001FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF0100000001FF00FF07000000017B00FF04 + 00000005FF00FF0500000001FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF0100000001FF00FF05000000017B00FF01 + FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01 + 00000001FF00FF04000000017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01 + FFFFFF017B00FF01FFFFFF017B00FF0100000001FF00FF07000000017B00FF08 + 0000000180808001FF00FF04000000017B00FF01FFFFFF017B00FF01FFFFFF01 + 00000001FFFFFF017B00FF01FFFFFF017B00FF0100000001FF00FF0500000001 + FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01 + FFFFFF0100000001FF00FF0400000001FFFFFF017B00FF01FFFFFF010000000A + FF00FF04000000017B00FF080000000180808001FF00FF0400000001FFFFFF01 + 7B00FF01FFFFFF017B00FF01000000017B00FF01FFFFFF017B00FF01FFFFFF01 + 00000001FF00FF05000000017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01 + FFFFFF017B00FF01FFFFFF017B00FF0100000001FF00FF04000000017B00FF01 + FFFFFF01000000017B00FF01BFBFBF017B00FF01BFBFBF017B00FF01BFBFBF01 + 7B00FF01BFBFBF017B00FF0100000001FF00FF04000000017B00FF0800000001 + 80808001FF00FF04000000017B00FF01FFFFFF0100000005FFFFFF017B00FF01 + 00000001FF00FF0500000001FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF0100000001FF00FF0400000001FFFFFF01 + 000000017B00FF01BFBFBF017B00FF01BFBFBF017B00FF01BFBFBF017B00FF01 + BFBFBF017B00FF0100000001FF00FF05000000017B00FF080000000180808001 + FF00FF0400000001FFFFFF017B00FF01FFFFFF017B00FF01000000017B00FF01 + FFFFFF017B00FF01FFFFFF0100000001FF00FF05000000017B00FF01FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF0100000001 + FF00FF04000000027B00FF01BFBFBF017B00FF01BFBFBF017B00FF01BFBFBF01 + 7B00FF01BFBFBF017B00FF0100000001FF00FF06000000017B00FF0800000001 + 80808001FF00FF04000000017B00FF01FFFFFF017B00FF01FFFFFF0100000001 + FFFFFF017B00FF01FFFFFF017B00FF0100000001FF00FF060000000AFF00FF05 + 0000000AFF00FF07000000017B00FF080000000180808001FF00FF050000000A + FF00FF260000000A80808001FF00FF368080800AFF00FFF500000006FF00FF1A + 7F7F7F01000000047F7F7F01FF00FF097F7F7F01000000047F7F7F01FF00FF0B + 0000000100FF000400000002FF00FF097F7F7F01000000047F7F7F01FF00FF0A + 00000001FFFFFF0100FF0001FFFFFF0100FF000100000001FF00FF0900000001 + 00FF0001FFFFFF0100FF0001FFFFFF0100000001FF00FF0B0000000100FF0004 + 0000000100FF000100000001FF00FF0800000001FFFFFF0100FF0001FFFFFF01 + 00FF000100000001FF00FF090000000AFF00FF050000000100FF0001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100000003FF00FF080000000100FF0004 + 0000000100FF000200000001FF00FF060000000AFF00FF0600000001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF01 + 00000001FF00FF0400000001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100000001FF00FF070000000100FF0004 + 00000005FF00FF0500000001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100000001FF00FF050000000100FF0001 + FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF0001 + 00000001FF00FF040000000100FF0001FFFFFF0100FF0001FFFFFF0100FF0001 + FFFFFF0100FF0001FFFFFF0100FF000100000001FF00FF070000000100FF0008 + 0000000180808001FF00FF040000000100FF0001FFFFFF0100FF0001FFFFFF01 + 00000001FFFFFF0100FF0001FFFFFF0100FF000100000001FF00FF0500000001 + FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF0001 + FFFFFF0100000001FF00FF0400000001FFFFFF0100FF0001FFFFFF010000000A + FF00FF040000000100FF00080000000180808001FF00FF0400000001FFFFFF01 + 00FF0001FFFFFF0100FF00010000000100FF0001FFFFFF0100FF0001FFFFFF01 + 00000001FF00FF050000000100FF0001FFFFFF0100FF0001FFFFFF0100FF0001 + FFFFFF0100FF0001FFFFFF0100FF000100000001FF00FF040000000100FF0001 + FFFFFF010000000100FF0001BFBFBF0100FF0001BFBFBF0100FF0001BFBFBF01 + 00FF0001BFBFBF0100FF000100000001FF00FF040000000100FF000800000001 + 80808001FF00FF040000000100FF0001FFFFFF0100000005FFFFFF0100FF0001 + 00000001FF00FF0500000001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100000001FF00FF0400000001FFFFFF01 + 0000000100FF0001BFBFBF0100FF0001BFBFBF0100FF0001BFBFBF0100FF0001 + BFBFBF0100FF000100000001FF00FF050000000100FF00080000000180808001 + FF00FF0400000001FFFFFF0100FF0001FFFFFF0100FF00010000000100FF0001 + FFFFFF0100FF0001FFFFFF0100000001FF00FF050000000100FF0001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF000100000001 + FF00FF040000000200FF0001BFBFBF0100FF0001BFBFBF0100FF0001BFBFBF01 + 00FF0001BFBFBF0100FF000100000001FF00FF060000000100FF000800000001 + 80808001FF00FF040000000100FF0001FFFFFF0100FF0001FFFFFF0100000001 + FFFFFF0100FF0001FFFFFF0100FF000100000001FF00FF060000000AFF00FF05 + 0000000AFF00FF070000000100FF00080000000180808001FF00FF050000000A + FF00FF260000000A80808001FF00FF368080800AFF00FFF500000006FF00FF1A + 7F7F7F01000000047F7F7F01FF00FF097F7F7F01000000047F7F7F01FF00FF0B + 00000001FFFFFF0400000002FF00FF097F7F7F01000000047F7F7F01FF00FF0A + 00000001FFFFFF0400000001FF00FF0900000001FFFFFF0400000001FF00FF0B + 00000001FFFFFF0400000001FFFFFF0100000001FF00FF0800000001FFFFFF04 + 00000001FF00FF090000000AFF00FF0500000001FFFFFF0600000003FF00FF08 + 00000001FFFFFF0400000001FFFFFF0200000001FF00FF060000000AFF00FF06 + 00000001FFFFFF0900000001FF00FF0400000001FFFFFF0900000001FF00FF07 + 00000001FFFFFF0400000005FF00FF0500000001FFFFFF0900000001FF00FF05 + 00000001FFFFFF0900000001FF00FF0400000001FFFFFF0900000001FF00FF07 + 00000001FFFFFF080000000180808001FF00FF0400000001FFFFFF0400000001 + FFFFFF0400000001FF00FF0500000001FFFFFF0900000001FF00FF0400000001 + FFFFFF030000000AFF00FF0400000001FFFFFF080000000180808001FF00FF04 + 00000001FFFFFF0400000001FFFFFF0400000001FF00FF0500000001FFFFFF09 + 00000001FF00FF0400000001FFFFFF0200000001FFFFFF01BFBFBF01FFFFFF01 + BFBFBF01FFFFFF01BFBFBF01FFFFFF01BFBFBF01FFFFFF0100000001FF00FF04 + 00000001FFFFFF080000000180808001FF00FF0400000001FFFFFF0200000005 + FFFFFF0200000001FF00FF0500000001FFFFFF0900000001FF00FF0400000001 + FFFFFF0100000001FFFFFF01BFBFBF01FFFFFF01BFBFBF01FFFFFF01BFBFBF01 + FFFFFF01BFBFBF01FFFFFF0100000001FF00FF0500000001FFFFFF0800000001 + 80808001FF00FF0400000001FFFFFF0400000001FFFFFF0400000001FF00FF05 + 00000001FFFFFF0900000001FF00FF0400000002FFFFFF01BFBFBF01FFFFFF01 + BFBFBF01FFFFFF01BFBFBF01FFFFFF01BFBFBF01FFFFFF0100000001FF00FF06 + 00000001FFFFFF080000000180808001FF00FF0400000001FFFFFF0400000001 + FFFFFF0400000001FF00FF060000000AFF00FF050000000AFF00FF0700000001 + FFFFFF080000000180808001FF00FF050000000AFF00FF260000000A80808001 + FF00FF368080800AFF00FF520000000000000000000000000000000000000000 + F8010000F801FC00F803F801F801FC00F807F801FC0FFE07F80FFC0FFC1FFE0F + F81FFC1FFC1FFE0FF83FFC1FFC1FFE7FF83FFC1FFC1FFE7FF83FFC1FFC1FFE3F + F83FFC1FFC1FFE1FF83FFC1FF81FFC0FF83FF81F00000000F83F000000000000 + F03F000000000000000000000000000000000000000000000000000000000000 + F8010000F801FC00F803F801F801FC00F807F801FC0FFE07F80FFC0FFC1FFE0F + F81FFC1FFC1FFE0FF83FFC1FFC1FFE7FF83FFC1FFC1FFE7FF83FFC1FFC1FFE3F + F83FFC1FFC1FFE1FF83FFC1FF81FFC0FF83FF81F00000000F83F000000000000 + F03F000000000000000000000000000000000000000000000000000000000000 + F8010000F801FC00F803F801F801FC00F807F801FC0FFE07F80FFC0FFC1FFE0F + F81FFC1FFC1FFE0FF83FFC1FFC1FFE7FF83FFC1FFC1FFE7FF83FFC1FFC1FFE3F + F83FFC1FFC1FFE1FF83FFC1FF81FFC0FF83FF81F00000000F83F000000000000 + F03F000000000000000000000000000000000000000000000000000000000000 + F8010000F801FC00F803F801F801FC00F807F801FC0FFE07F80FFC0FFC1FFE0F + F81FFC1FFC1FFE0FF83FFC1FFC1FFE7FF83FFC1FFC1FFE7FF83FFC1FFC1FFE3F + F83FFC1FFC1FFE1FF83FFC1FF81FFC0FF83FF81F00000000F83F000000000000 + F03F00000000000000000000 + } + end +end diff --git a/mseide-msegui/lib/common/dialogs/msefiledialogres.pas b/mseide-msegui/lib/common/dialogs/msefiledialogres.pas new file mode 100644 index 0000000..c0bad49 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialogres.pas @@ -0,0 +1,61 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefiledialogres; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseclasses,msebitmap,msegui,msedatamodules; + +type + filedialogiconty = (fdi_dir,fdi_diropen,fdi_file,fdi_direntry); + tfiledialogres = class(tmsedatamodule) + images: timagelist; + public + procedure getfileicon(const aimage: filedialogiconty; var imagelist: timagelist; + out imagenr: integer); + end; + +function filedialogres: tfiledialogres; + +implementation + +uses + msefiledialogres_mfm,sysutils; +var + ffiledialogres: tfiledialogres; + +function filedialogres: tfiledialogres; +begin + result:= ffiledialogres; +end; + +{ tfiledialogres } + +procedure tfiledialogres.getfileicon(const aimage: filedialogiconty; + var imagelist: timagelist; out imagenr: integer); +begin + if imagelist = nil then begin + imagelist:= images; + end; + imagenr:= ord(aimage); +end; + +initialization + application.lock; //create application instance + try + createmodule(nil,tfiledialogres,ffiledialogres); + finally + application.unlock; + end; +finalization + freeandnil(ffiledialogres); +end. diff --git a/mseide-msegui/lib/common/dialogs/msefiledialogres_mfm.pas b/mseide-msegui/lib/common/dialogs/msefiledialogres_mfm.pas new file mode 100644 index 0000000..f0b5983 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialogres_mfm.pas @@ -0,0 +1,287 @@ +unit msefiledialogres_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefiledialogres; + +const + objdata: record size: integer; data: array[0..5385] of byte end = + (size: 5386; data: ( + 84,80,70,48,14,116,102,105,108,101,100,105,97,108,111,103,114,101,115,13, + 102,105,108,101,100,105,97,108,111,103,114,101,115,9,98,111,117,110,100,115, + 95,99,120,3,235,0,9,98,111,117,110,100,115,95,99,121,2,117,4,108, + 101,102,116,2,93,3,116,111,112,3,140,1,15,109,111,100,117,108,101,99, + 108,97,115,115,110,97,109,101,6,14,116,109,115,101,100,97,116,97,109,111, + 100,117,108,101,0,10,116,105,109,97,103,101,108,105,115,116,6,105,109,97, + 103,101,115,5,99,111,117,110,116,2,16,4,108,101,102,116,2,32,3,116, + 111,112,2,32,5,105,109,97,103,101,10,108,20,0,0,0,0,0,0,2, + 0,0,0,64,0,0,0,64,0,0,0,56,18,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,0,255,163,0,0,0,6,255,0,255,26,127, + 127,127,1,0,0,0,4,127,127,127,1,255,0,255,9,127,127,127,1,0, + 0,0,4,127,127,127,1,255,0,255,11,0,0,0,1,255,255,255,4,0, + 0,0,2,255,0,255,9,127,127,127,1,0,0,0,4,127,127,127,1,255, + 0,255,10,0,0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,9,0,0,0,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255,0,255,11,0, + 0,0,1,255,255,255,4,0,0,0,1,255,255,255,1,0,0,0,1,255, + 0,255,8,0,0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,9,0,0,0,10,255,0,255,5,0, + 0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,3,255,0,255,8,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,2,0,0,0,1,255,0,255,6,0, + 0,0,10,255,0,255,6,0,0,0,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,255,255,255,4,0,0,0,5,255,0,255,5,0, + 0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 0,0,1,255,0,255,5,0,0,0,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0,0,0,10,255, + 0,255,4,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,0,255,255,1,255,255,255,1,0,0,0,1,0,255,255,1,191, + 191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0, + 255,255,1,191,191,191,1,0,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,0,255,255,1,255,255,255,1,0,0,0,5,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,0,0,1,0,255,255,1,191,191,191,1,0, + 255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,191, + 191,191,1,0,255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255, + 255,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,0,0,0,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255, + 0,255,5,0,0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,4,0,0,0,2,0,255,255,1,191, + 191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0, + 255,255,1,191,191,191,1,0,255,255,1,0,0,0,1,255,0,255,6,0, + 0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,0, + 0,0,1,255,0,255,6,0,0,0,10,255,0,255,5,0,0,0,10,255, + 0,255,7,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,10,255,0,255,38,0,0,0,10,128,128,128,1,255, + 0,255,54,128,128,128,10,255,0,255,245,0,0,0,6,255,0,255,26,127, + 127,127,1,0,0,0,4,127,127,127,1,255,0,255,9,127,127,127,1,0, + 0,0,4,127,127,127,1,255,0,255,11,0,0,0,1,123,0,255,4,0, + 0,0,2,255,0,255,9,127,127,127,1,0,0,0,4,127,127,127,1,255, + 0,255,10,0,0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,0,0,0,1,255,0,255,9,0,0,0,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,0,0,0,1,255,0,255,11,0, + 0,0,1,123,0,255,4,0,0,0,1,123,0,255,1,0,0,0,1,255, + 0,255,8,0,0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,0,0,0,1,255,0,255,9,0,0,0,10,255,0,255,5,0, + 0,0,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,255,255,255,1,0,0,0,3,255,0,255,8,0,0,0,1,123, + 0,255,4,0,0,0,1,123,0,255,2,0,0,0,1,255,0,255,6,0, + 0,0,10,255,0,255,6,0,0,0,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,123,0,255,4,0,0,0,5,255,0,255,5,0, + 0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,0, + 0,0,1,255,0,255,5,0,0,0,1,123,0,255,1,255,255,255,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,0,0,0,1,255,0,255,4,0,0,0,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,123,0,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,0,0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,0,0,0,10,255, + 0,255,4,0,0,0,1,123,0,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,0,0,0,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,255,255,255,1,123,0,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,123,0,255,1,255,255,255,1,0,0,0,1,123,0,255,1,191, + 191,191,1,123,0,255,1,191,191,191,1,123,0,255,1,191,191,191,1,123, + 0,255,1,191,191,191,1,123,0,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,123,0,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,123,0,255,1,255,255,255,1,0,0,0,5,255,255,255,1,123, + 0,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,0,0,1,123,0,255,1,191,191,191,1,123, + 0,255,1,191,191,191,1,123,0,255,1,191,191,191,1,123,0,255,1,191, + 191,191,1,123,0,255,1,0,0,0,1,255,0,255,5,0,0,0,1,123, + 0,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0,0,0,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,0,0,0,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,0,0,0,1,255, + 0,255,5,0,0,0,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,0,0,0,1,255,0,255,4,0,0,0,2,123,0,255,1,191, + 191,191,1,123,0,255,1,191,191,191,1,123,0,255,1,191,191,191,1,123, + 0,255,1,191,191,191,1,123,0,255,1,0,0,0,1,255,0,255,6,0, + 0,0,1,123,0,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,0, + 0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,0, + 0,0,1,255,0,255,6,0,0,0,10,255,0,255,5,0,0,0,10,255, + 0,255,7,0,0,0,1,123,0,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,10,255,0,255,38,0,0,0,10,128,128,128,1,255, + 0,255,54,128,128,128,10,255,0,255,245,0,0,0,6,255,0,255,26,127, + 127,127,1,0,0,0,4,127,127,127,1,255,0,255,9,127,127,127,1,0, + 0,0,4,127,127,127,1,255,0,255,11,0,0,0,1,0,255,0,4,0, + 0,0,2,255,0,255,9,127,127,127,1,0,0,0,4,127,127,127,1,255, + 0,255,10,0,0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,0,0,0,1,255,0,255,9,0,0,0,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,0,0,1,255,0,255,11,0, + 0,0,1,0,255,0,4,0,0,0,1,0,255,0,1,0,0,0,1,255, + 0,255,8,0,0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,0,0,0,1,255,0,255,9,0,0,0,10,255,0,255,5,0, + 0,0,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,0,0,3,255,0,255,8,0,0,0,1,0, + 255,0,4,0,0,0,1,0,255,0,2,0,0,0,1,255,0,255,6,0, + 0,0,10,255,0,255,6,0,0,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,0,255,0,4,0,0,0,5,255,0,255,5,0, + 0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 0,0,1,255,0,255,5,0,0,0,1,0,255,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,0,0,0,1,255,0,255,4,0,0,0,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,0,0,0,1,255, + 0,255,7,0,0,0,1,0,255,0,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,0,0,10,255, + 0,255,4,0,0,0,1,0,255,0,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,0,0,0,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,255,0,1,0,0,0,1,255,0,255,4,0, + 0,0,1,0,255,0,1,255,255,255,1,0,0,0,1,0,255,0,1,191, + 191,191,1,0,255,0,1,191,191,191,1,0,255,0,1,191,191,191,1,0, + 255,0,1,191,191,191,1,0,255,0,1,0,0,0,1,255,0,255,4,0, + 0,0,1,0,255,0,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,0,255,0,1,255,255,255,1,0,0,0,5,255,255,255,1,0, + 255,0,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,0,0,1,0,255,0,1,191,191,191,1,0, + 255,0,1,191,191,191,1,0,255,0,1,191,191,191,1,0,255,0,1,191, + 191,191,1,0,255,0,1,0,0,0,1,255,0,255,5,0,0,0,1,0, + 255,0,8,0,0,0,1,128,128,128,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,0,0,0,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,0,0,1,255, + 0,255,5,0,0,0,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,0,0,0,1,255,0,255,4,0,0,0,2,0,255,0,1,191, + 191,191,1,0,255,0,1,191,191,191,1,0,255,0,1,191,191,191,1,0, + 255,0,1,191,191,191,1,0,255,0,1,0,0,0,1,255,0,255,6,0, + 0,0,1,0,255,0,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,0, + 0,0,1,255,0,255,6,0,0,0,10,255,0,255,5,0,0,0,10,255, + 0,255,7,0,0,0,1,0,255,0,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,10,255,0,255,38,0,0,0,10,128,128,128,1,255, + 0,255,54,128,128,128,10,255,0,255,245,0,0,0,6,255,0,255,26,127, + 127,127,1,0,0,0,4,127,127,127,1,255,0,255,9,127,127,127,1,0, + 0,0,4,127,127,127,1,255,0,255,11,0,0,0,1,255,255,255,4,0, + 0,0,2,255,0,255,9,127,127,127,1,0,0,0,4,127,127,127,1,255, + 0,255,10,0,0,0,1,255,255,255,4,0,0,0,1,255,0,255,9,0, + 0,0,1,255,255,255,4,0,0,0,1,255,0,255,11,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,1,0,0,0,1,255,0,255,8,0, + 0,0,1,255,255,255,4,0,0,0,1,255,0,255,9,0,0,0,10,255, + 0,255,5,0,0,0,1,255,255,255,6,0,0,0,3,255,0,255,8,0, + 0,0,1,255,255,255,4,0,0,0,1,255,255,255,2,0,0,0,1,255, + 0,255,6,0,0,0,10,255,0,255,6,0,0,0,1,255,255,255,9,0, + 0,0,1,255,0,255,4,0,0,0,1,255,255,255,9,0,0,0,1,255, + 0,255,7,0,0,0,1,255,255,255,4,0,0,0,5,255,0,255,5,0, + 0,0,1,255,255,255,9,0,0,0,1,255,0,255,5,0,0,0,1,255, + 255,255,9,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9,0, + 0,0,1,255,0,255,7,0,0,0,1,255,255,255,8,0,0,0,1,128, + 128,128,1,255,0,255,4,0,0,0,1,255,255,255,4,0,0,0,1,255, + 255,255,4,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,9,0, + 0,0,1,255,0,255,4,0,0,0,1,255,255,255,3,0,0,0,10,255, + 0,255,4,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,4,0, + 0,0,1,255,0,255,5,0,0,0,1,255,255,255,9,0,0,0,1,255, + 0,255,4,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,191, + 191,191,1,255,255,255,1,191,191,191,1,255,255,255,1,191,191,191,1,255, + 255,255,1,191,191,191,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,255,255,255,2,0,0,0,5,255,255,255,2,0,0,0,1,255, + 0,255,5,0,0,0,1,255,255,255,9,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,191,191,191,1,255, + 255,255,1,191,191,191,1,255,255,255,1,191,191,191,1,255,255,255,1,191, + 191,191,1,255,255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255, + 255,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,4,0,0,0,1,255,0,255,5,0, + 0,0,1,255,255,255,9,0,0,0,1,255,0,255,4,0,0,0,2,255, + 255,255,1,191,191,191,1,255,255,255,1,191,191,191,1,255,255,255,1,191, + 191,191,1,255,255,255,1,191,191,191,1,255,255,255,1,0,0,0,1,255, + 0,255,6,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,4,0, + 0,0,1,255,0,255,6,0,0,0,10,255,0,255,5,0,0,0,10,255, + 0,255,7,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,10,255,0,255,38,0,0,0,10,128,128,128,1,255, + 0,255,54,128,128,128,10,255,0,255,82,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,248,1,0,0,248,1,252,0,248, + 3,248,1,248,1,252,0,248,7,248,1,252,15,254,7,248,15,252,15,252, + 31,254,15,248,31,252,31,252,31,254,15,248,63,252,31,252,31,254,127,248, + 63,252,31,252,31,254,127,248,63,252,31,252,31,254,63,248,63,252,31,252, + 31,254,31,248,63,252,31,248,31,252,15,248,63,248,31,0,0,0,0,248, + 63,0,0,0,0,0,0,240,63,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248, + 1,0,0,248,1,252,0,248,3,248,1,248,1,252,0,248,7,248,1,252, + 15,254,7,248,15,252,15,252,31,254,15,248,31,252,31,252,31,254,15,248, + 63,252,31,252,31,254,127,248,63,252,31,252,31,254,127,248,63,252,31,252, + 31,254,63,248,63,252,31,252,31,254,31,248,63,252,31,248,31,252,15,248, + 63,248,31,0,0,0,0,248,63,0,0,0,0,0,0,240,63,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,248,1,0,0,248,1,252,0,248,3,248,1,248, + 1,252,0,248,7,248,1,252,15,254,7,248,15,252,15,252,31,254,15,248, + 31,252,31,252,31,254,15,248,63,252,31,252,31,254,127,248,63,252,31,252, + 31,254,127,248,63,252,31,252,31,254,63,248,63,252,31,252,31,254,31,248, + 63,252,31,248,31,252,15,248,63,248,31,0,0,0,0,248,63,0,0,0, + 0,0,0,240,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,1,0,0,248, + 1,252,0,248,3,248,1,248,1,252,0,248,7,248,1,252,15,254,7,248, + 15,252,15,252,31,254,15,248,31,252,31,252,31,254,15,248,63,252,31,252, + 31,254,127,248,63,252,31,252,31,254,127,248,63,252,31,252,31,254,63,248, + 63,252,31,252,31,254,31,248,63,252,31,248,31,252,15,248,63,248,31,0, + 0,0,0,248,63,0,0,0,0,0,0,240,63,0,0,0,0,0,0,0, + 0,0,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfiledialogres,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msefontformatdialog.mfm b/mseide-msegui/lib/common/dialogs/msefontformatdialog.mfm new file mode 100644 index 0000000..190bba0 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefontformatdialog.mfm @@ -0,0 +1,232 @@ +object fontformatdialogfo: tfontformatdialogfo + visible = False + bounds_x = 399 + bounds_y = 175 + bounds_cx = 279 + bounds_cy = 160 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 279 + 160 + ) + options = [fo_freeonclose, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Edit Font Format' + moduleclassname = 'tmseform' + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 80 + bounds_y = 133 + bounds_cx = 192 + bounds_cy = 20 + anchors = [an_left, an_right, an_bottom] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 8 + place_maxdist = 8 + place_mode = wam_end + linktop = tlayouter2 + dist_top = 4 + options = [spao_gluebottom] + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 140 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + font.name = 'stf_default' + font.localprops = [] + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 82 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + end + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 279 + bounds_cy = 129 + anchors = [an_top, an_bottom] + object tlayouter3: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 156 + bounds_y = 3 + bounds_cx = 84 + bounds_cy = 126 + anchors = [an_left, an_top, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placey] + place_mindist = 4 + place_maxdist = 4 + object bolded: tbooleanedit + frame.caption = 'B&old' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 30 + 2 + ) + bounds_x = 8 + bounds_y = 0 + bounds_cx = 43 + bounds_cy = 16 + end + object italiced: tbooleanedit + frame.caption = '&Italic' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 32 + 2 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 20 + bounds_cx = 45 + bounds_cy = 16 + end + object underlineed: tbooleanedit + frame.caption = '&Underline' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 63 + 2 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 40 + bounds_cx = 76 + bounds_cy = 16 + end + object strikeouted: tbooleanedit + frame.caption = '&Strikeout' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 60 + 2 + ) + taborder = 3 + bounds_x = 8 + bounds_y = 60 + bounds_cx = 73 + bounds_cy = 16 + end + object blanked: tbooleanedit + frame.caption = 'Bl&ank' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 37 + 2 + ) + taborder = 4 + bounds_x = 8 + bounds_y = 80 + bounds_cx = 50 + bounds_cy = 16 + end + end + object tlayouter4: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 156 + bounds_cy = 129 + anchors = [an_left, an_top, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placey] + place_mindist = 4 + place_maxdist = 4 + linkright = tlayouter3 + object backgroundcolored: tcoloredit + frame.caption = '&Backgroundcolor' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 2 + frame.buttons.items = < + item + end + item + imagenr = 17 + end> + frame.buttonellipse.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 41 + bounds_cx = 148 + bounds_cy = 37 + reffontheight = 14 + end + object fontcolored: tcoloredit + frame.caption = '&Fontcolor' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 2 + frame.buttons.items = < + item + end + item + imagenr = 17 + end> + frame.buttonellipse.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 8 + bounds_y = 0 + bounds_cx = 148 + bounds_cy = 37 + reffontheight = 14 + end + end + end + object tstatfile1: tstatfile + filename = 'fontformatdialog.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 64 + top = 104 + end +end diff --git a/mseide-msegui/lib/common/dialogs/msefontformatdialog.pas b/mseide-msegui/lib/common/dialogs/msefontformatdialog.pas new file mode 100644 index 0000000..40b9205 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefontformatdialog.pas @@ -0,0 +1,90 @@ +{ MSEgui Copyright (c) 2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefontformatdialog; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + mserichstring,msesplitter,msesimplewidgets,msestatfile,mseact,msecolordialog, + msedataedits,mseedit,mseificomp,mseificompglob,mseifiglob,msestream,msestrings, + sysutils,msegraphedits,msescrollbar; +type + tfontformatdialogfo = class(tmseform) + tlayouter1: tlayouter; + tbutton2: tbutton; + tbutton1: tbutton; + tlayouter2: tlayouter; + tstatfile1: tstatfile; + tlayouter3: tlayouter; + bolded: tbooleanedit; + italiced: tbooleanedit; + underlineed: tbooleanedit; + strikeouted: tbooleanedit; + blanked: tbooleanedit; + tlayouter4: tlayouter; + backgroundcolored: tcoloredit; + fontcolored: tcoloredit; + end; + +function editfontformat(const avalue: formatinfoarty; + const start,count: int32): formatinfoarty; + +implementation +uses + msefontformatdialog_mfm; + +function editfontformat(const avalue: formatinfoarty; + const start,count: int32): formatinfoarty; +var + style1: charstylety; +begin + result:= copy(avalue); + with tfontformatdialogfo.create(nil) do begin + style1:= getcharstyle(avalue,start); + fontcolored.value:= charstyletocolor(style1.fontcolor); + backgroundcolored.value:= charstyletocolor(style1.colorbackground); + bolded.value:= fs_bold in style1.fontstyle; + italiced.value:= fs_italic in style1.fontstyle; + underlineed.value:= fs_underline in style1.fontstyle; + strikeouted.value:= fs_strikeout in style1.fontstyle; +// selecteded.value:= fs_selected in style1.fontstyle; + blanked.value:= fs_blank in style1.fontstyle; + if show(ml_application) = mr_ok then begin + style1.fontcolor:= colortocharstyle(fontcolored.value); + style1.colorbackground:= colortocharstyle(backgroundcolored.value); + style1.fontstyle:= style1.fontstyle - [fs_bold,fs_italic,fs_underline, + fs_strikeout{,fs_selected},fs_blank]; + if bolded.value then begin + include(style1.fontstyle,fs_bold); + end; + if italiced.value then begin + include(style1.fontstyle,fs_italic); + end; + if underlineed.value then begin + include(style1.fontstyle,fs_underline); + end; + if strikeouted.value then begin + include(style1.fontstyle,fs_strikeout); + end; + { + if selecteded.value then begin + include(style1.fontstyle,fs_selected); + end; + } + if blanked.value then begin + include(style1.fontstyle,fs_blank); + end; + setcharstyle1(result,start,count,style1); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msefontformatdialog_mfm.pas b/mseide-msegui/lib/common/dialogs/msefontformatdialog_mfm.pas new file mode 100644 index 0000000..953fd65 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefontformatdialog_mfm.pas @@ -0,0 +1,212 @@ +unit msefontformatdialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefontformatdialog; + +const + objdata: record size: integer; data: array[0..3890] of byte end = + (size: 3891; data: ( + 84,80,70,48,19,116,102,111,110,116,102,111,114,109,97,116,100,105,97,108, + 111,103,102,111,18,102,111,110,116,102,111,114,109,97,116,100,105,97,108,111, + 103,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,3,143,1,8,98,111,117,110,100,115,95,121,3,175,0,9,98,111,117, + 110,100,115,95,99,120,3,23,1,9,98,111,117,110,100,115,95,99,121,3, + 160,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,23,1,3,160,0,0,7,111,112,116,105,111,110,115,11,14, + 102,111,95,102,114,101,101,111,110,99,108,111,115,101,13,102,111,95,99,108, + 111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100, + 115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97, + 116,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101, + 122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0, + 8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101, + 49,7,99,97,112,116,105,111,110,6,16,69,100,105,116,32,70,111,110,116, + 32,70,111,114,109,97,116,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,8,116,109,115,101,102,111,114,109,0,9,116,108,97,121,111, + 117,116,101,114,10,116,108,97,121,111,117,116,101,114,49,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99, + 117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,98, + 111,117,110,100,115,95,120,2,80,8,98,111,117,110,100,115,95,121,3,133, + 0,9,98,111,117,110,100,115,95,99,120,3,192,0,9,98,111,117,110,100, + 115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107, + 121,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17, + 111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111, + 112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108, + 97,99,101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105, + 103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112, + 108,97,99,101,95,109,105,110,100,105,115,116,2,8,13,112,108,97,99,101, + 95,109,97,120,100,105,115,116,2,8,10,112,108,97,99,101,95,109,111,100, + 101,7,7,119,97,109,95,101,110,100,7,108,105,110,107,116,111,112,7,10, + 116,108,97,121,111,117,116,101,114,50,8,100,105,115,116,95,116,111,112,2, + 4,7,111,112,116,105,111,110,115,11,15,115,112,97,111,95,103,108,117,101, + 98,111,116,116,111,109,0,0,7,116,98,117,116,116,111,110,8,116,98,117, + 116,116,111,110,50,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95, + 97,117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115,95,120,3, + 140,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,52,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111, + 117,110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112, + 116,105,111,110,6,7,38,67,97,110,99,101,108,9,102,111,110,116,46,110, + 97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,0,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116, + 116,111,110,8,116,98,117,116,116,111,110,49,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,82,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,50,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117,110,100, + 115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11,10,97,115,95, + 100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97, + 117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0, + 7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97,108,114, + 101,115,117,108,116,7,5,109,114,95,111,107,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,9,116,108,97,121,111,117,116,101, + 114,10,116,108,97,121,111,117,116,101,114,50,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17, + 111,119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,23, + 1,9,98,111,117,110,100,115,95,99,121,3,129,0,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116, + 101,114,51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111, + 119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115, + 117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111, + 117,110,100,115,95,120,3,156,0,8,98,111,117,110,100,115,95,121,2,3, + 9,98,111,117,110,100,115,95,99,120,2,84,9,98,111,117,110,100,115,95, + 99,121,2,126,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,12, + 111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120, + 112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,17,111,115, + 99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99,95, + 101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111,112,116,105,111, + 110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,121, + 0,13,112,108,97,99,101,95,109,105,110,100,105,115,116,2,4,13,112,108, + 97,99,101,95,109,97,120,100,105,115,116,2,4,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,6,98,111,108,100,101,100,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,5,66,38,111,108,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,30,2,2, + 0,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,43,9,98,111,117,110, + 100,115,95,99,121,2,16,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,8,105,116,97,108,105,99,101,100,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,7,38,73,116,97,108,105,99,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,32,2,2,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115, + 95,99,120,2,45,9,98,111,117,110,100,115,95,99,121,2,16,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,11,117,110,100,101,114,108,105, + 110,101,101,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10, + 38,85,110,100,101,114,108,105,110,101,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,1,2,63,2,2,0,8,116,97,98, + 111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,8,8,98, + 111,117,110,100,115,95,121,2,40,9,98,111,117,110,100,115,95,99,120,2, + 76,9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,11,115,116,114,105,107,101,111,117,116,101,100, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10,38,83,116,114, + 105,107,101,111,117,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,60,2,2,0,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100, + 115,95,121,2,60,9,98,111,117,110,100,115,95,99,120,2,73,9,98,111, + 117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,7,98,108,97,110,107,101,100,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,6,66,108,38,97,110,107,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,37,2,2,0, + 8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,80,9,98,111,117,110,100,115, + 95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,16,0,0,0, + 9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114, + 52,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,156,0,9, + 98,111,117,110,100,115,95,99,121,3,129,0,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110,95, + 98,111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101, + 11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104, + 114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105, + 110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107, + 121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97, + 111,95,112,108,97,99,101,121,0,13,112,108,97,99,101,95,109,105,110,100, + 105,115,116,2,4,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2, + 4,9,108,105,110,107,114,105,103,104,116,7,10,116,108,97,121,111,117,116, + 101,114,51,0,10,116,99,111,108,111,114,101,100,105,116,17,98,97,99,107, + 103,114,111,117,110,100,99,111,108,111,114,101,100,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,16,38,66,97,99,107,103,114,111,117,110,100, + 99,111,108,111,114,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99, + 111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,105,116,101,109,115,14,1,0,1,7,105,109,97,103,101,110,114,2,17, + 0,0,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112, + 115,101,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,2,41,9,98,111,117,110,100,115,95, + 99,120,3,148,0,9,98,111,117,110,100,115,95,99,121,2,37,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,10,116,99,111,108, + 111,114,101,100,105,116,11,102,111,110,116,99,111,108,111,114,101,100,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,10,38,70,111,110,116,99, + 111,108,111,114,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111, + 117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 105,116,101,109,115,14,1,0,1,7,105,109,97,103,101,110,114,2,17,0, + 0,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115, + 101,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,148,0,9,98,111,117,110,100,115, + 95,99,121,2,37,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97, + 116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,20,102,111,110, + 116,102,111,114,109,97,116,100,105,97,108,111,103,46,115,116,97,7,111,112, + 116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,17,115,102, + 111,95,97,99,116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95, + 97,99,116,105,118,97,116,111,114,119,114,105,116,101,0,4,108,101,102,116, + 2,64,3,116,111,112,2,104,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfontformatdialogfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/mseintegerenter.mfm b/mseide-msegui/lib/common/dialogs/mseintegerenter.mfm new file mode 100644 index 0000000..c3856d6 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseintegerenter.mfm @@ -0,0 +1,58 @@ +object integerenterfo: tintegerenterfo + visible = False + bounds_x = 395 + bounds_y = 323 + bounds_cx = 233 + bounds_cy = 88 + bounds_cymin = 75 + container.bounds = ( + 0 + 0 + 233 + 88 + ) + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat] + moduleclassname = 'tmseform' + object lab: tlabel + optionswidget1 = [ow1_autoheight] + taborder = 3 + bounds_x = 8 + bounds_y = 41 + bounds_cx = 217 + bounds_cy = 14 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'lab' + textflags = [tf_ycentered, tf_wordbreak] + end + object ok: tbutton + taborder = 1 + bounds_x = 120 + bounds_y = 62 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 2 + bounds_x = 176 + bounds_y = 62 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object value: tintegeredit + frame.dummy = 0 + bounds_x = 8 + bounds_y = 62 + anchors = [an_left, an_right, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end +end diff --git a/mseide-msegui/lib/common/dialogs/mseintegerenter.pas b/mseide-msegui/lib/common/dialogs/mseintegerenter.pas new file mode 100644 index 0000000..2d93cf4 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseintegerenter.pas @@ -0,0 +1,62 @@ +{ MSEgui Copyright (c) 1999-2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseintegerenter; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msetypes,mseglob,mseguiglob,msegui, + msedialog,msestrings; + +type + tintegerenterfo = class(tdialogform) + lab: tlabel; + ok: tbutton; + cancel: tbutton; + value: tintegeredit; + end; + +function integerenter(var avalue: integer; const amin,amax: integer; + const text: msestring = ''; const acaption: msestring = ''): modalresultty; +//threadsave +implementation +uses + mseintegerenter_mfm; + +function integerenter(var avalue: integer; const amin,amax: integer; const text: msestring = ''; + const acaption: msestring = ''): modalresultty; +var + fo: tintegerenterfo; +begin + application.lock; + try + fo:= tintegerenterfo.create(nil); + try + with fo do begin + value.value:= avalue; + value.valuemin:= amin; + value.valuemax:= amax; + caption:= acaption; + lab.caption:= text; + result:= fo.show(true,nil); + if result = mr_ok then begin + avalue:= value.value; + end; + end; + finally + fo.Free; + end; + finally + application.unlock; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/mseintegerenter_mfm.pas b/mseide-msegui/lib/common/dialogs/mseintegerenter_mfm.pas new file mode 100644 index 0000000..76c2355 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseintegerenter_mfm.pas @@ -0,0 +1,74 @@ +unit mseintegerenter_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseintegerenter; + +const + objdata: record size: integer; data: array[0..1139] of byte end = + (size: 1140; data: ( + 84,80,70,48,15,116,105,110,116,101,103,101,114,101,110,116,101,114,102,111, + 14,105,110,116,101,103,101,114,101,110,116,101,114,102,111,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,139,1,8,98,111,117, + 110,100,115,95,121,3,67,1,9,98,111,117,110,100,115,95,99,120,3,233, + 0,9,98,111,117,110,100,115,95,99,121,2,88,12,98,111,117,110,100,115, + 95,99,121,109,105,110,2,75,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,233,0,2,88,0,7,111,112,116, + 105,111,110,115,11,17,102,111,95,115,99,114,101,101,110,99,101,110,116,101, + 114,101,100,13,102,111,95,99,108,111,115,101,111,110,101,115,99,17,102,111, + 95,108,111,99,97,108,115,104,111,114,116,99,117,116,115,15,102,111,95,97, + 117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119, + 114,105,116,101,115,116,97,116,0,15,109,111,100,117,108,101,99,108,97,115, + 115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,6,116,108,97, + 98,101,108,3,108,97,98,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,14,111,119,49,95,97,117,116,111,104,101,105,103,104,116,0,8, + 116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,2,41,9,98,111,117,110,100,115,95, + 99,120,3,217,0,9,98,111,117,110,100,115,95,99,121,2,14,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109, + 0,7,99,97,112,116,105,111,110,6,3,108,97,98,9,116,101,120,116,102, + 108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,12,116, + 102,95,119,111,114,100,98,114,101,97,107,0,0,0,7,116,98,117,116,116, + 111,110,2,111,107,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,120,8,98,111,117,110,100,115,95,121,2,62,9,98, + 111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121, + 2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116, + 9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97, + 115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101, + 102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97, + 108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117, + 116,116,111,110,6,99,97,110,99,101,108,8,116,97,98,111,114,100,101,114, + 2,2,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110,100, + 115,95,121,2,62,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111, + 117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97, + 110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11, + 109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99, + 101,108,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,5,118,97, + 108,117,101,11,102,114,97,109,101,46,100,117,109,109,121,2,0,8,98,111, + 117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,62,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tintegerenterfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msememodialog.mfm b/mseide-msegui/lib/common/dialogs/msememodialog.mfm new file mode 100644 index 0000000..7453017 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msememodialog.mfm @@ -0,0 +1,84 @@ +object msememodialogfo: tmsememodialogfo + visible = False + bounds_x = 110 + bounds_y = 237 + bounds_cx = 409 + bounds_cy = 297 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 409 + 297 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + caption = 'Enter Memo Text' + moduleclassname = 'tmseform' + object memo: tmemoedit + frame.localprops = [frl_colorclient] + frame.localprops1 = [] + frame.sbhorz.pagesize = 1 + frame.sbvert.pagesize = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 409 + bounds_cy = 268 + anchors = [an_top, an_bottom] + optionsedit1 = [oe1_multiline, oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_shiftreturn, oe_resetselectonexit, oe_nofirstarrownavig, oe_caretonreadonly] + reffontheight = 14 + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 72 + bounds_y = 272 + bounds_cx = 330 + bounds_cy = 20 + anchors = [an_left, an_right, an_bottom] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 8 + place_maxdist = 8 + place_mode = wam_end + linktop = memo + dist_top = 4 + options = [spao_gluebottom] + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 278 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + font.name = 'stf_default' + font.localprops = [] + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 220 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + end + object tstatfile1: tstatfile + filename = 'memodialog.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 64 + top = 104 + end +end diff --git a/mseide-msegui/lib/common/dialogs/msememodialog.pas b/mseide-msegui/lib/common/dialogs/msememodialog.pas new file mode 100644 index 0000000..723dbe2 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msememodialog.pas @@ -0,0 +1,232 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msememodialog; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msedataedits,mseedit,msestrings, + msetypes,msestatfile,msesimplewidgets,msewidgets,msedialog,classes,mclasses, + msedropdownlist,msesplitter; + +type + tmemodialogcontroller = class(tstringdialogcontroller) + protected + function execute(var avalue: msestring): boolean; override; + end; + + tmemodialogedit = class(tcustomdialogstringed) + protected + function createdialogcontroller: tstringdialogcontroller; override; + public + constructor create(aowner: tcomponent); override; + published + property textflags default defaulttextflagsnoycentered; + property textflagsactive default defaulttextflagsactivenoycentered; + end; + + tmsememodialogfo = class(tmseform) + memo: tmemoedit; + tstatfile1: tstatfile; + tlayouter1: tlayouter; + tbutton2: tbutton; + tbutton1: tbutton; + public + constructor create(const aowner: tcomponent; const readonly: boolean); + reintroduce; + end; + + tdialogdropdownbuttonframe = class(tdropdownmultibuttonframe) + private + function getbuttondialog: tdropdownbutton; + procedure setbuttondialog(const avalue: tdropdownbutton); + public + constructor create(const aintf: icaptionframe; + const buttonintf: ibutton); override; + published + property buttondialog: tdropdownbutton read getbuttondialog + write setbuttondialog; + end; + + tdialoghistorycontroller = class(thistorycontroller) + protected + function getbuttonframeclass: dropdownbuttonframeclassty; override; + end; + + tmemodialoghistoryedit = class(thistoryedit,ibutton) + private +// function getframe: tellipsebuttonframe; +// procedure setframe(const avalue: tellipsebuttonframe); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; +// procedure internalcreateframe; override; +// procedure dokeydown(var info: keyeventinfoty); override; +// procedure mouseevent(var info: mouseeventinfoty); override; +// procedure updatereadonlystate; override; + //ibutton + procedure buttonaction(var action: buttonactionty; + const buttonindex: integer); override; + + procedure internalexecute; + function execute(var avalue: msestring): boolean; virtual; + procedure setexecresult(var avalue: msestring); virtual; +// function iskeyexecute(const info: keyeventinfoty): boolean; virtual; + public + constructor create(aowner: tcomponent); override; +// property frame: tellipsebuttonframe read getframe write setframe; + end; + +function memodialog(var avalue: msestring; const readonly: boolean): modalresultty; + +implementation +uses + msememodialog_mfm,mseeditglob,msekeyboard,msestockobjects; + +function memodialog(var avalue: msestring; const readonly: boolean): modalresultty; +var + dia1: tmsememodialogfo; +begin + dia1:= tmsememodialogfo.create(nil,readonly); + try + dia1.memo.value:= avalue; + result:= dia1.show(true); + if result = mr_ok then begin + avalue:= dia1.memo.value; + end; + finally + dia1.free; + end; +end; + +{ tmemodialogcontroller } + +function tmemodialogcontroller.execute(var avalue: msestring): boolean; +begin + result:= memodialog(avalue,not fowner.editor.canedit) = mr_ok; +end; + +{ tmemodialogedit } + +constructor tmemodialogedit.create(aowner: tcomponent); +begin + inherited; + ftextflags:= defaulttextflagsnoycentered; + ftextflagsactive:= defaulttextflagsactivenoycentered; + updatetextflags(); +end; + +function tmemodialogedit.createdialogcontroller: tstringdialogcontroller; +begin + result:= tmemodialogcontroller.create(self); +end; + + +{ +function tmemodialogedit.execute(var avalue: msestring): boolean; +begin + result:= memodialog(avalue) = mr_ok; +end; +} +{ tmemodialoghistoryedit } + +constructor tmemodialoghistoryedit.create(aowner: tcomponent); +begin + inherited; +// internalcreateframe; +end; + +procedure tmemodialoghistoryedit.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + if buttonindex = 1 then begin + if action = ba_click then begin + if canfocus and not setfocus then begin + exit; + end; + internalexecute; + end; + end + else begin + inherited; + end; +end; +{ +procedure tmemodialoghistoryedit.internalcreateframe; +begin + tellipsebuttonframe.create(iscrollframe(self),ibutton(self)); + updatereadonlystate; +end; +} +function tmemodialoghistoryedit.execute(var avalue: msestring): boolean; +begin + result:= memodialog(avalue,readonly) = mr_ok; +end; + +procedure tmemodialoghistoryedit.setexecresult(var avalue: msestring); +begin + text:= avalue; +end; + +procedure tmemodialoghistoryedit.internalexecute; +var + str1: msestring; +begin + str1:= text; + if execute(str1) then begin + setexecresult(str1); + checkvalue; + end; +end; + +function tmemodialoghistoryedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdialoghistorycontroller.create(idropdownlist(self)); +end; + +{ tdialoghistorycontroller } + +function tdialoghistorycontroller.getbuttonframeclass: dropdownbuttonframeclassty; +begin + result:= tdialogdropdownbuttonframe; +end; + +{ tdialogdropdownbuttonframe } + +constructor tdialogdropdownbuttonframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + inherited; + buttons.count:= 2; + buttons[1].imagenr:= ord(stg_ellipsesmall); +end; + +function tdialogdropdownbuttonframe.getbuttondialog: tdropdownbutton; +begin + result:= tdropdownbutton(buttons[1]); +end; + +procedure tdialogdropdownbuttonframe.setbuttondialog(const avalue: tdropdownbutton); +begin + tdropdownbutton(buttons[1]).assign(avalue); +end; + +{ tmsememodialogfo } + +constructor tmsememodialogfo.create(const aowner: tcomponent; + const readonly: boolean); +begin + inherited create(aowner); + if readonly then begin + caption:= 'Memo text'; + end; + memo.readonly:= readonly; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msememodialog_mfm.pas b/mseide-msegui/lib/common/dialogs/msememodialog_mfm.pas new file mode 100644 index 0000000..06d1a08 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msememodialog_mfm.pas @@ -0,0 +1,113 @@ +unit msememodialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msememodialog; + +const + objdata: record size: integer; data: array[0..1912] of byte end = + (size: 1913; data: ( + 84,80,70,48,16,116,109,115,101,109,101,109,111,100,105,97,108,111,103,102, + 111,15,109,115,101,109,101,109,111,100,105,97,108,111,103,102,111,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,110,8,98,111, + 117,110,100,115,95,121,3,237,0,9,98,111,117,110,100,115,95,99,120,3, + 153,1,9,98,111,117,110,100,115,95,99,121,3,41,1,26,99,111,110,116, + 97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,153,1,3, + 41,1,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101, + 101,110,99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111, + 110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116, + 16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111, + 95,115,97,118,101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116, + 101,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105, + 108,101,49,7,99,97,112,116,105,111,110,6,15,69,110,116,101,114,32,77, + 101,109,111,32,84,101,120,116,15,109,111,100,117,108,101,99,108,97,115,115, + 110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,9,116,109,101,109, + 111,101,100,105,116,4,109,101,109,111,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,21,102,114,97,109,101,46,115,98,104,111,114,122,46,112, + 97,103,101,115,105,122,101,2,1,21,102,114,97,109,101,46,115,98,118,101, + 114,116,46,112,97,103,101,115,105,122,101,2,1,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,153,1,9,98,111,117,110,100,115,95,99,121,3,12, + 1,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110, + 95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,13,111,101,49,95,109,117,108,116,105,108,105,110,101,17,111,101,49, + 95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107, + 101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118,97, + 108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,12,111,101,95,108,105,110,101,98,114,101,97,107,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,20,111,101,95,110,111,102,105,114, + 115,116,97,114,114,111,119,110,97,118,105,103,18,111,101,95,99,97,114,101, + 116,111,110,114,101,97,100,111,110,108,121,0,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,9,116,108,97,121,111,117,116,101,114, + 10,116,108,97,121,111,117,116,101,114,49,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111, + 119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,72,8,98,111,117, + 110,100,115,95,121,3,16,1,9,98,111,117,110,100,115,95,99,120,3,74, + 1,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114, + 115,11,7,97,110,95,108,101,102,116,8,97,110,95,114,105,103,104,116,9, + 97,110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99, + 97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99, + 95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100,115, + 104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114, + 105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105,103, + 110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95, + 115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116,2, + 8,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,8,10,112,108, + 97,99,101,95,109,111,100,101,7,7,119,97,109,95,101,110,100,7,108,105, + 110,107,116,111,112,7,4,109,101,109,111,8,100,105,115,116,95,116,111,112, + 2,4,7,111,112,116,105,111,110,115,11,15,115,112,97,111,95,103,108,117, + 101,98,111,116,116,111,109,0,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,50,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49, + 95,97,117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115,95,120, + 3,22,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,2,52,9,98,111,117,110,100,115,95,99,121,2,20,12,98, + 111,117,110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97, + 112,116,105,111,110,6,7,38,67,97,110,99,101,108,9,102,111,110,116,46, + 110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,0,11,109,111,100,97, + 108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117, + 116,116,111,110,8,116,98,117,116,116,111,110,49,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,220, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117, + 110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11,10,97, + 115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101, + 102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97, + 108,114,101,115,117,108,116,7,5,109,114,95,111,107,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,116,97,116,102, + 105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110, + 97,109,101,6,14,109,101,109,111,100,105,97,108,111,103,46,115,116,97,7, + 111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,17, + 115,102,111,95,97,99,116,105,118,97,116,111,114,114,101,97,100,18,115,102, + 111,95,97,99,116,105,118,97,116,111,114,119,114,105,116,101,0,4,108,101, + 102,116,2,64,3,116,111,112,2,104,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsememodialogfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msepopupcalendar.mfm b/mseide-msegui/lib/common/dialogs/msepopupcalendar.mfm new file mode 100644 index 0000000..7ede7c1 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msepopupcalendar.mfm @@ -0,0 +1,213 @@ +object msepopupcalendarfo: tpopupcalendarfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + frame.framewidth = 1 + frame.colorframe = -1610612734 + frame.localprops = [frl_framewidth, frl_colorframe] + frame.dummy = 0 + visible = False + bounds_x = 341 + bounds_y = 304 + bounds_cx = 233 + bounds_cy = 179 + anchors = [an_left, an_top, an_bottom] + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [frl_framewidth] + container.frame.sbhorz.options = [sbo_thumbtrack, sbo_moveauto] + container.frame.sbvert.options = [sbo_thumbtrack, sbo_moveauto] + container.bounds = ( + 1 + 1 + 231 + 177 + ) + optionswindow = [wo_popup, wo_buttonendmodal] + options = [fo_freeonclose, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + oncreate = formoncreate + moduleclassname = 'tmseform' + object grid: tdrawgrid + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.framewidth = 1 + frame.colorframe = -1610612733 + frame.sbvert.options = [sbo_thumbtrack] + frame.sbhorz.options = [sbo_thumbtrack] + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_colorframe, frl_fileft, frl_fitop, frl_firight, frl_fibottom] + taborder = 6 + bounds_x = 0 + bounds_y = 22 + bounds_cx = 233 + bounds_cy = 156 + anchors = [an_left, an_top, an_right] + datacols.count = 7 + datacols.coloractive = -1879048185 + datacols.width = 32 + datacols.options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + datacols.options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + datacols.items = < + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + linewidth = 0 + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end> + fixrows.count = 1 + fixrows.items = < + item + height = 21 + captions.count = 7 + captions.items = < + item + options = [] + end + item + options = [] + end + item + options = [] + end + item + options = [] + end + item + options = [] + end + item + options = [] + end + item + options = [] + end> + end> + rowcount = 6 + gridframecolor = -2147483645 + datarowheight = 21 + oncellevent = cellevent + reffontheight = 14 + end + object monthdisp: tdatetimedisp + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousewheel, ow_destroywidgets] + color = -1879048186 + taborder = 5 + bounds_x = 83 + bounds_y = 0 + bounds_cx = 137 + bounds_cy = 22 + textflags = [tf_xcentered, tf_right, tf_ycentered] + format = 'mmmm' + value = -Inf + reffontheight = 14 + end + object yeardisp: tdatetimedisp + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousewheel, ow_destroywidgets] + color = -1879048186 + taborder = 4 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 72 + bounds_cy = 22 + textflags = [tf_xcentered, tf_right, tf_ycentered] + format = 'yyyy' + value = -Inf + reffontheight = 14 + end + object tstockglyphbutton1: tstockglyphbutton + optionswidget = [ow_mousewheel, ow_destroywidgets] + taborder = 3 + bounds_x = 220 + bounds_y = 0 + bounds_cx = 11 + bounds_cy = 11 + state = [as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowupsmall + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_nocandefocus] + onexecute = moup + end + object tstockglyphbutton2: tstockglyphbutton + optionswidget = [ow_mousewheel, ow_destroywidgets] + taborder = 1 + bounds_x = 220 + bounds_y = 11 + bounds_cx = 11 + bounds_cy = 11 + state = [as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowdownsmall + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_nocandefocus] + onexecute = modown + end + object buup: tstockglyphbutton + optionswidget = [ow_mousewheel, ow_destroywidgets] + taborder = 2 + bounds_x = 72 + bounds_y = 0 + bounds_cx = 11 + bounds_cy = 11 + state = [as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowupsmall + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_nocandefocus] + onexecute = yearup + end + object budo: tstockglyphbutton + optionswidget = [ow_mousewheel, ow_destroywidgets] + bounds_x = 72 + bounds_y = 11 + bounds_cx = 11 + bounds_cy = 11 + state = [as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowdownsmall + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_nocandefocus] + onexecute = yeardown + end +end diff --git a/mseide-msegui/lib/common/dialogs/msepopupcalendar.pas b/mseide-msegui/lib/common/dialogs/msepopupcalendar.pas new file mode 100644 index 0000000..dfb1296 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msepopupcalendar.pas @@ -0,0 +1,417 @@ +{ MSEgui Copyright (c) 1999-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepopupcalendar; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} +interface +uses + msegui,mseclasses,mseforms,msegraphutils,msegrids,msedispwidgets,classes, + mclasses, + msegraphics,mseeditglob,msetypes,msedropdownlist,msetimer,msesimplewidgets, + mseinplaceedit,mseevent,mseguiglob,msegridsglob,msestrings; + +const + popupcalendarwidth = 233; + +type + idropdowncalendar = interface(idropdownwidget) + end; + + tcalendarcontroller = class(tdropdownwidgetcontroller) + private + ffirstdayofweek: dayofweekty; + freddayofweek: dayofweekty; + protected + procedure dropdownkeydown(var info: keyeventinfoty); + public + constructor create(const intf: idropdowncalendar); + procedure editnotification(var info: editnotificationinfoty); override; + published + property bounds_cx default popupcalendarwidth; + property firstdayofweek: dayofweekty read ffirstdayofweek + write ffirstdayofweek default dw_mon; + property reddayofweek: dayofweekty read freddayofweek + write freddayofweek default dw_sun; + end; + + tpopupcalendarfo = class(tmseform) + grid: tdrawgrid; + monthdisp: tdatetimedisp; + tstockglyphbutton1: tstockglyphbutton; + tstockglyphbutton2: tstockglyphbutton; + buup: tstockglyphbutton; + budo: tstockglyphbutton; + yeardisp: tdatetimedisp; + procedure formoncreate(const sender: TObject); + procedure drawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty); + procedure cellevent(const sender: TObject; var info: celleventinfoty); + procedure moup(const sender: TObject); + procedure modown(const sender: TObject); + procedure yearup(const sender: TObject); + procedure yeardown(const sender: TObject); + private + fvalue: tdatetime; + ffirstdate: tdatetime; + ffirstcol,flastcol,flastrow: integer; + fvalueupdating: integer; + fcontroller: tcalendarcontroller; + fformatedit: msestring; + procedure setvalue(const avalue: tdatetime); + function isinvalidcell(const acell: gridcoordty): boolean; + protected + fdayofweekoffset: integer; +// freddayofweeknum: integer; +// procedure mousewheelevent(var info: mousewheeleventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure mousewheelevent(var info: mousewheeleventinfoty); override; + public + constructor create(const aowner: tcomponent; + const acontroller: tcalendarcontroller); reintroduce; + property value: tdatetime read fvalue write setvalue; + property formatedit: msestring read fformatedit write fformatedit; + end; + +implementation +uses + mseformatstr,msepopupcalendar_mfm,sysutils,msesys, + {$ifndef UNIX} + dateutils, + {$else} + {$ifdef FPC}dateutils,{$endif} + {$endif} //kylix compatibility + msedrawtext, + msekeyboard; + + {$ifdef UNIX} + {$ifndef FPC} //kylix compatibility + //copied from dateutil.inc + +Function DayOf(const AValue: TDateTime): Word; + +Var + Y,M : Word; + +begin + DecodeDate(AValue,Y,M,Result); +end; + +Function DaysBetween(const ANow, AThen: TDateTime): Integer; +begin + Result:=Trunc(Abs(ANow-AThen)); +end; + +Function DaysInMonth(const AValue: TDateTime): Word; + +Var + Y,M,D : Word; + +begin + Decodedate(AValue,Y,M,D); + Result:=MonthDays[IsLeapYear(Y),M]; +end; + +Function IncDay(const AValue: TDateTime; const ANumberOfDays: Integer): TDateTime; +begin + Result:=AValue+ANumberOfDays; //1899 step? +end; + {$endif} +{$endif} + +{ tcalendarcontroller } + +constructor tcalendarcontroller.create(const intf: idropdowncalendar); +begin + ffirstdayofweek:= dw_mon; + freddayofweek:= dw_sun; + inherited create(intf); + include(fstate,dcs_forcecaret); +// fforcecaret:= true; + bounds_cx:= popupcalendarwidth; +end; + +procedure tcalendarcontroller.editnotification(var info: editnotificationinfoty); +var + dt1: tdatetime; +begin + inherited; + if fdropdownwidget <> nil then begin + case info.action of + ea_textedited: begin + if trystringtodate(fintf.geteditor.text,dt1) then begin + tpopupcalendarfo(fdropdownwidget).value:= dt1; + end; + end + end; + end; +end; + +procedure tcalendarcontroller.dropdownkeydown(var info: keyeventinfoty); +var + editor1: tinplaceedit; +begin + editor1:= fintf.geteditor; + editor1.dokeydown(info); +end; + +{ tpopupcalendarfo } + +constructor tpopupcalendarfo.create(const aowner: tcomponent; + const acontroller: tcalendarcontroller); +begin + fcontroller:= acontroller; + fdayofweekoffset:= ord(fcontroller.ffirstdayofweek)+1; +// freddayofweeknum:= ord(fcontroller.freddayofweek)+1; + inherited create(aowner); +end; + +procedure tpopupcalendarfo.formoncreate(const sender: TObject); +var + int1,int2: integer; +begin + with grid.fixrows[-1] do begin + int2:= ord(fcontroller.ffirstdayofweek); + for int1:= 0 to 6 do begin + captions[int1].caption:= + defaultformatsettingsmse.shortdaynames[((int1+int2) mod 7)+1]; + end; + { + for int1:= 2 to 7 do begin + captions[int1-2].caption:= defaultformatsettingsmse.shortdaynames[int1]; + end; + captions[6].caption:= defaultformatsettingsmse.shortdaynames[1]; + } + end; + int2:= ord(fcontroller.freddayofweek) - int2; + if int2 < 0 then begin + int2:= int2 + 7; + end; + with grid.datacols[int2] do begin +// with grid.datacols[(7-int2) mod 7] do begin + createfont; + font.color:= cl_red; + end; + value:= fvalue; +end; + +procedure tpopupcalendarfo.setvalue(const avalue: tdatetime); +var + year,month,day: word; + int1: integer; + dat1: tdatetime; +begin + if fvalueupdating = 0 then begin + inc(fvalueupdating); + fvalue:= avalue; + if yeardisp <> nil then begin + yeardisp.value:= avalue; + end; + if monthdisp <> nil then begin + monthdisp.value:= avalue; + end; + decodedate(avalue,year,month,day); + dat1:= encodedate(year,month,1); + int1:= fdayofweekoffset-dayofweek(dat1); + if int1 > 0 then begin + int1:= int1 - 7; + end; + ffirstdate:= incday(dat1,int1); + ffirstcol:= - int1; + flastcol:= dayofweek(encodedate(year,month,daysinmonth(avalue))- + fdayofweekoffset) mod 7; + flastrow:= (ffirstcol + daysinmonth(avalue) - 1) div 7; + int1:= daysbetween(ffirstdate,avalue); + grid.focuscell(makegridcoord(int1 mod 7,int1 div 7)); + dec(fvalueupdating); + invalidate; + end; +end; + +function tpopupcalendarfo.isinvalidcell(const acell: gridcoordty): boolean; +begin + result:= (acell.row = 0) and (acell.col < ffirstcol) or + (acell.row > flastrow) or + (acell.row >= flastrow) and (acell.col > flastcol); +end; + +procedure tpopupcalendarfo.drawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty); +var + flags1: textflagsty; +begin + with cellinfo do begin + if isinvalidcell(cell) then begin + flags1:= [tf_xcentered,tf_ycentered,tf_grayed]; + end + else begin + flags1:= [tf_xcentered,tf_ycentered]; + end; + drawtext(canvas, + msestring(inttostr(dayof(incday(ffirstdate,cell.row*7+cell.col)))), + rect,flags1); + end; +end; + +procedure tpopupcalendarfo.cellevent(const sender: TObject; + var info: celleventinfoty); + procedure setcellvalue; + begin + if (fvalueupdating = 0) then begin + with grid.focusedcell do begin + value:= incday(ffirstdate,row*7+col); + end; + end; + end; + +begin + if (fcontroller <> nil) and iscellclick(info,[ccr_buttonpress]) then begin + setcellvalue; + options:= options - [fo_freeonclose]; + hide; //do not show error messages above the popup window + if fcontroller.setdropdowntext( + mseformatstr.datetimetostring(fvalue,fformatedit), + true,false,key_none) then begin +// release; + end; + release; + end + else begin + with info do begin + case eventkind of + cek_enter: begin + setcellvalue; + end; + cek_keydown: begin + with keyeventinfopo^ do begin + include(eventstate,es_processed); + case key of + key_pagedown{,key_wheeldown}: begin + if shiftstate = [ss_ctrl] then begin + yearup(nil); + end + else begin + moup(nil); + end; + end; + key_pageup{,key_wheelup}: begin + if shiftstate = [ss_ctrl] then begin + yeardown(nil); + end + else begin + modown(nil); + end; + end; + key_up: begin + if cell.row = 0 then begin + value:= incday(fvalue,-7); + end + else begin + exclude(eventstate,es_processed); + end; + end; + key_down: begin + if cell.row = 5 then begin + value:= incday(fvalue,7); + end + else begin + exclude(eventstate,es_processed); + end; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tpopupcalendarfo.mousewheelevent(var info: mousewheeleventinfoty); + function bigstep: boolean; + begin + with info do begin + result:= (shiftstate = [ss_ctrl]) or + pointinrect(pos,yeardisp.widgetrect) or + pointinrect(pos,buup.widgetrect) or + pointinrect(pos,budo.widgetrect); + end; + end; + +begin + with info do begin + if not (es_processed in eventstate) then begin + include(eventstate,es_processed); + case wheel of + mw_up: begin + if bigstep then begin + yearup(nil); + end + else begin + moup(nil); + end; + end; + mw_down: begin + if bigstep then begin + yeardown(nil); + end + else begin + modown(nil); + end; + end; + end; + end; + end; +end; + +procedure tpopupcalendarfo.moup(const sender: TObject); +begin + value:= incmonth(fvalue,1); +end; + +procedure tpopupcalendarfo.modown(const sender: TObject); +begin + value:= incmonth(fvalue,-1); +end; + +procedure tpopupcalendarfo.yearup(const sender: TObject); +begin + value:= incmonth(fvalue,12); +end; + +procedure tpopupcalendarfo.yeardown(const sender: TObject); +begin + value:= incmonth(fvalue,-12); +end; + +procedure tpopupcalendarfo.dokeydown(var info: keyeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) then begin + fcontroller.dropdownkeydown(info); + end; +end; + +procedure tpopupcalendarfo.doactivate; +begin + inherited; + fcontroller.dropdownactivated; +end; + +procedure tpopupcalendarfo.dodeactivate; +begin + inherited; + fcontroller.dropdowndeactivated; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msepopupcalendar_mfm.pas b/mseide-msegui/lib/common/dialogs/msepopupcalendar_mfm.pas new file mode 100644 index 0000000..d2c7f4b --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msepopupcalendar_mfm.pas @@ -0,0 +1,274 @@ +unit msepopupcalendar_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msepopupcalendar; + +const + objdata: record size: integer; data: array[0..5139] of byte end = + (size: 5140; data: ( + 84,80,70,48,16,116,112,111,112,117,112,99,97,108,101,110,100,97,114,102, + 111,18,109,115,101,112,111,112,117,112,99,97,108,101,110,100,97,114,102,111, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117, + 115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9, + 111,119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,102,114,97, + 109,101,119,105,100,116,104,2,1,16,102,114,97,109,101,46,99,111,108,111, + 114,102,114,97,109,101,4,2,0,0,160,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,14,102,114,108,95,102,114,97,109,101,119, + 105,100,116,104,14,102,114,108,95,99,111,108,111,114,102,114,97,109,101,0, + 11,102,114,97,109,101,46,100,117,109,109,121,2,0,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,85,1,8,98,111,117,110, + 100,115,95,121,3,48,1,9,98,111,117,110,100,115,95,99,120,3,233,0, + 9,98,111,117,110,100,115,95,99,121,3,179,0,7,97,110,99,104,111,114, + 115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110, + 95,98,111,116,116,111,109,0,23,99,111,110,116,97,105,110,101,114,46,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98, + 102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112, + 97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,14,102,114,108,95,102,114,97, + 109,101,119,105,100,116,104,0,30,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,115,98,104,111,114,122,46,111,112,116,105,111,110,115,11, + 14,115,98,111,95,116,104,117,109,98,116,114,97,99,107,12,115,98,111,95, + 109,111,118,101,97,117,116,111,0,30,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,115,98,118,101,114,116,46,111,112,116,105,111,110,115, + 11,14,115,98,111,95,116,104,117,109,98,116,114,97,99,107,12,115,98,111, + 95,109,111,118,101,97,117,116,111,0,16,99,111,110,116,97,105,110,101,114, + 46,98,111,117,110,100,115,1,2,1,2,1,3,231,0,3,177,0,0,13, + 111,112,116,105,111,110,115,119,105,110,100,111,119,11,8,119,111,95,112,111, + 112,117,112,17,119,111,95,98,117,116,116,111,110,101,110,100,109,111,100,97, + 108,0,7,111,112,116,105,111,110,115,11,14,102,111,95,102,114,101,101,111, + 110,99,108,111,115,101,13,102,111,95,99,108,111,115,101,111,110,101,115,99, + 17,102,111,95,108,111,99,97,108,115,104,111,114,116,99,117,116,115,15,102, + 111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117, + 116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112, + 111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,111,110,99, + 114,101,97,116,101,7,12,102,111,114,109,111,110,99,114,101,97,116,101,15, + 109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115, + 101,102,111,114,109,0,9,116,100,114,97,119,103,114,105,100,4,103,114,105, + 100,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,16,102,114,97,109,101,46, + 102,114,97,109,101,119,105,100,116,104,2,1,16,102,114,97,109,101,46,99, + 111,108,111,114,102,114,97,109,101,4,3,0,0,160,20,102,114,97,109,101, + 46,115,98,118,101,114,116,46,111,112,116,105,111,110,115,11,14,115,98,111, + 95,116,104,117,109,98,116,114,97,99,107,0,20,102,114,97,109,101,46,115, + 98,104,111,114,122,46,111,112,116,105,111,110,115,11,14,115,98,111,95,116, + 104,117,109,98,116,114,97,99,107,0,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10, + 102,114,108,95,108,101,118,101,108,105,14,102,114,108,95,102,114,97,109,101, + 119,105,100,116,104,14,102,114,108,95,99,111,108,111,114,102,114,97,109,101, + 10,102,114,108,95,102,105,108,101,102,116,9,102,114,108,95,102,105,116,111, + 112,11,102,114,108,95,102,105,114,105,103,104,116,12,102,114,108,95,102,105, + 98,111,116,116,111,109,0,8,116,97,98,111,114,100,101,114,2,6,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,22, + 9,98,111,117,110,100,115,95,99,120,3,233,0,9,98,111,117,110,100,115, + 95,99,121,3,156,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,7,20,100,97, + 116,97,99,111,108,115,46,99,111,108,111,114,97,99,116,105,118,101,4,7, + 0,0,144,14,100,97,116,97,99,111,108,115,46,119,105,100,116,104,2,32, + 16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111, + 99,117,115,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95, + 115,97,118,101,115,116,97,116,101,0,17,100,97,116,97,99,111,108,115,46, + 111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111,110, + 116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49,95,122, + 101,98,114,97,99,111,108,111,114,19,99,111,49,95,114,111,119,99,111,108, + 111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114,101,97, + 100,111,110,108,121,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109, + 115,14,1,11,99,111,108,111,114,97,99,116,105,118,101,4,7,0,0,144, + 5,119,105,100,116,104,2,32,7,111,112,116,105,111,110,115,11,11,99,111, + 95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99, + 117,115,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,0,8,111,112,116,105,111,110,115,49,11,11, + 99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99, + 111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,19, + 99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15, + 99,111,49,95,114,111,119,114,101,97,100,111,110,108,121,0,13,102,111,99, + 117,115,114,101,99,116,100,105,115,116,2,1,10,111,110,100,114,97,119,99, + 101,108,108,7,8,100,114,97,119,99,101,108,108,0,1,11,99,111,108,111, + 114,97,99,116,105,118,101,4,7,0,0,144,5,119,105,100,116,104,2,32, + 7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108, + 121,12,99,111,95,100,114,97,119,102,111,99,117,115,12,99,111,95,115,97, + 118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102, + 111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49, + 95,122,101,98,114,97,99,111,108,111,114,19,99,111,49,95,114,111,119,99, + 111,108,111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114, + 101,97,100,111,110,108,121,0,13,102,111,99,117,115,114,101,99,116,100,105, + 115,116,2,1,10,111,110,100,114,97,119,99,101,108,108,7,8,100,114,97, + 119,99,101,108,108,0,1,11,99,111,108,111,114,97,99,116,105,118,101,4, + 7,0,0,144,5,119,105,100,116,104,2,32,7,111,112,116,105,111,110,115, + 11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97, + 119,102,111,99,117,115,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,0,8,111,112,116,105,111,110, + 115,49,11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95, + 114,111,119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111, + 108,111,114,19,99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117, + 115,101,100,15,99,111,49,95,114,111,119,114,101,97,100,111,110,108,121,0, + 13,102,111,99,117,115,114,101,99,116,100,105,115,116,2,1,10,111,110,100, + 114,97,119,99,101,108,108,7,8,100,114,97,119,99,101,108,108,0,1,11, + 99,111,108,111,114,97,99,116,105,118,101,4,7,0,0,144,5,119,105,100, + 116,104,2,32,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97, + 100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99,117,115,12,99, + 111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115, + 116,97,116,101,0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95, + 114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114, + 14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,19,99,111,49,95, + 114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15,99,111,49,95, + 114,111,119,114,101,97,100,111,110,108,121,0,13,102,111,99,117,115,114,101, + 99,116,100,105,115,116,2,1,10,111,110,100,114,97,119,99,101,108,108,7, + 8,100,114,97,119,99,101,108,108,0,1,11,99,111,108,111,114,97,99,116, + 105,118,101,4,7,0,0,144,5,119,105,100,116,104,2,32,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111, + 95,100,114,97,119,102,111,99,117,115,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,8,111,112, + 116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111,110,116,12, + 99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49,95,122,101,98, + 114,97,99,111,108,111,114,19,99,111,49,95,114,111,119,99,111,108,111,114, + 102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114,101,97,100,111, + 110,108,121,0,13,102,111,99,117,115,114,101,99,116,100,105,115,116,2,1, + 10,111,110,100,114,97,119,99,101,108,108,7,8,100,114,97,119,99,101,108, + 108,0,1,11,99,111,108,111,114,97,99,116,105,118,101,4,7,0,0,144, + 5,119,105,100,116,104,2,32,7,111,112,116,105,111,110,115,11,11,99,111, + 95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99, + 117,115,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,0,8,111,112,116,105,111,110,115,49,11,11, + 99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99, + 111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,19, + 99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15, + 99,111,49,95,114,111,119,114,101,97,100,111,110,108,121,0,13,102,111,99, + 117,115,114,101,99,116,100,105,115,116,2,1,10,111,110,100,114,97,119,99, + 101,108,108,7,8,100,114,97,119,99,101,108,108,0,1,9,108,105,110,101, + 119,105,100,116,104,2,0,11,99,111,108,111,114,97,99,116,105,118,101,4, + 7,0,0,144,5,119,105,100,116,104,2,32,7,111,112,116,105,111,110,115, + 11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97, + 119,102,111,99,117,115,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,0,8,111,112,116,105,111,110, + 115,49,11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95, + 114,111,119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111, + 108,111,114,19,99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117, + 115,101,100,15,99,111,49,95,114,111,119,114,101,97,100,111,110,108,121,0, + 13,102,111,99,117,115,114,101,99,116,100,105,115,116,2,1,10,111,110,100, + 114,97,119,99,101,108,108,7,8,100,114,97,119,99,101,108,108,0,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,21, + 14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,7,14,99,97, + 112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,111,112,116,105,111, + 110,115,11,0,0,1,7,111,112,116,105,111,110,115,11,0,0,1,7,111, + 112,116,105,111,110,115,11,0,0,1,7,111,112,116,105,111,110,115,11,0, + 0,1,7,111,112,116,105,111,110,115,11,0,0,1,7,111,112,116,105,111, + 110,115,11,0,0,1,7,111,112,116,105,111,110,115,11,0,0,0,0,0, + 8,114,111,119,99,111,117,110,116,2,6,14,103,114,105,100,102,114,97,109, + 101,99,111,108,111,114,4,3,0,0,128,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,21,11,111,110,99,101,108,108,101,118,101,110,116,7, + 9,99,101,108,108,101,118,101,110,116,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,13,116,100,97,116,101,116,105,109,101,100,105, + 115,112,9,109,111,110,116,104,100,105,115,112,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111, + 108,111,114,4,6,0,0,144,8,116,97,98,111,114,100,101,114,2,5,8, + 98,111,117,110,100,115,95,120,2,83,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,137,0,9,98,111,117,110,100, + 115,95,99,121,2,22,9,116,101,120,116,102,108,97,103,115,11,12,116,102, + 95,120,99,101,110,116,101,114,101,100,8,116,102,95,114,105,103,104,116,12, + 116,102,95,121,99,101,110,116,101,114,101,100,0,6,102,111,114,109,97,116, + 6,4,109,109,109,109,5,118,97,108,117,101,5,0,0,0,0,0,0,0, + 128,255,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,100,97,116,101,116,105,109,101,100,105,115,112,8,121,101,97,114, + 100,105,115,112,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,6,0,0,144, + 8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,72,9,98,111,117,110,100,115,95,99,121,2,22,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101, + 100,8,116,102,95,114,105,103,104,116,12,116,102,95,121,99,101,110,116,101, + 114,101,100,0,6,102,111,114,109,97,116,6,4,121,121,121,121,5,118,97, + 108,117,101,5,0,0,0,0,0,0,0,128,255,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,17,116,115,116,111,99,107,103, + 108,121,112,104,98,117,116,116,111,110,18,116,115,116,111,99,107,103,108,121, + 112,104,98,117,116,116,111,110,49,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97, + 98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,3,220,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,11,5,115,116,97,116, + 101,11,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116, + 15,97,115,95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121,112, + 104,7,16,115,116,103,95,97,114,114,111,119,117,112,115,109,97,108,108,7, + 111,112,116,105,111,110,115,11,17,98,111,95,101,120,101,99,117,116,101,111, + 110,99,108,105,99,107,15,98,111,95,101,120,101,99,117,116,101,111,110,107, + 101,121,20,98,111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116, + 99,117,116,27,98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108, + 116,111,110,101,110,116,101,114,107,101,121,15,98,111,95,110,111,99,97,110, + 100,101,102,111,99,117,115,0,9,111,110,101,120,101,99,117,116,101,7,4, + 109,111,117,112,0,0,17,116,115,116,111,99,107,103,108,121,112,104,98,117, + 116,116,111,110,18,116,115,116,111,99,107,103,108,121,112,104,98,117,116,116, + 111,110,50,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,3,220,0,8,98,111,117,110,100, + 115,95,121,2,11,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111, + 117,110,100,115,95,99,121,2,11,5,115,116,97,116,101,11,17,97,115,95, + 108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111, + 99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,5,103,108,121,112,104,7,18,115,116,103, + 95,97,114,114,111,119,100,111,119,110,115,109,97,108,108,7,111,112,116,105, + 111,110,115,11,17,98,111,95,101,120,101,99,117,116,101,111,110,99,108,105, + 99,107,15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98, + 111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27, + 98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101, + 110,116,101,114,107,101,121,15,98,111,95,110,111,99,97,110,100,101,102,111, + 99,117,115,0,9,111,110,101,120,101,99,117,116,101,7,6,109,111,100,111, + 119,110,0,0,17,116,115,116,111,99,107,103,108,121,112,104,98,117,116,116, + 111,110,4,98,117,117,112,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111, + 114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,72,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,11,5,115,116,97,116,101,11,17, + 97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115, + 95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121,112,104,7,16, + 115,116,103,95,97,114,114,111,119,117,112,115,109,97,108,108,7,111,112,116, + 105,111,110,115,11,17,98,111,95,101,120,101,99,117,116,101,111,110,99,108, + 105,99,107,15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20, + 98,111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116, + 27,98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110, + 101,110,116,101,114,107,101,121,15,98,111,95,110,111,99,97,110,100,101,102, + 111,99,117,115,0,9,111,110,101,120,101,99,117,116,101,7,6,121,101,97, + 114,117,112,0,0,17,116,115,116,111,99,107,103,108,121,112,104,98,117,116, + 116,111,110,4,98,117,100,111,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,98,111,117, + 110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,2,11,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,11,5,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103, + 101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,5,103,108,121,112,104,7,18,115,116,103,95,97,114,114,111,119,100, + 111,119,110,115,109,97,108,108,7,111,112,116,105,111,110,115,11,17,98,111, + 95,101,120,101,99,117,116,101,111,110,99,108,105,99,107,15,98,111,95,101, + 120,101,99,117,116,101,111,110,107,101,121,20,98,111,95,101,120,101,99,117, + 116,101,111,110,115,104,111,114,116,99,117,116,27,98,111,95,101,120,101,99, + 117,116,101,100,101,102,97,117,108,116,111,110,101,110,116,101,114,107,101,121, + 15,98,111,95,110,111,99,97,110,100,101,102,111,99,117,115,0,9,111,110, + 101,120,101,99,117,116,101,7,8,121,101,97,114,100,111,119,110,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tpopupcalendarfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/mserealenter.mfm b/mseide-msegui/lib/common/dialogs/mserealenter.mfm new file mode 100644 index 0000000..8b6976e --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mserealenter.mfm @@ -0,0 +1,64 @@ +object realenterfo: trealenterfo + visible = False + bounds_x = 395 + bounds_y = 323 + bounds_cx = 233 + bounds_cy = 88 + bounds_cymin = 75 + container.bounds = ( + 0 + 0 + 233 + 88 + ) + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat] + moduleclassname = 'tmseform' + object lab: tlabel + optionswidget1 = [ow1_autoheight] + taborder = 3 + bounds_x = 8 + bounds_y = 41 + bounds_cx = 217 + bounds_cy = 14 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'lab' + textflags = [tf_ycentered, tf_wordbreak] + end + object value: trealedit + frame.dummy = 0 + bounds_x = 8 + bounds_y = 62 + anchors = [an_left, an_right, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = -Inf + valuedefault = -Inf + valuerange = 0 + valuestart = 0 + min = -Inf + max = 1E+038 + reffontheight = 14 + end + object ok: tbutton + taborder = 1 + bounds_x = 120 + bounds_y = 62 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 2 + bounds_x = 176 + bounds_y = 62 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end +end diff --git a/mseide-msegui/lib/common/dialogs/mserealenter.pas b/mseide-msegui/lib/common/dialogs/mserealenter.pas new file mode 100644 index 0000000..f346fcc --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mserealenter.pas @@ -0,0 +1,62 @@ +{ MSEgui Copyright (c) 1999-2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mserealenter; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseglob,mseforms,msedataedits,msesimplewidgets,msetypes,mseguiglob,msegui,msedialog, + msereal,msestrings; + +type + trealenterfo = class(tdialogform) + value: trealedit; + lab: tlabel; + ok: tbutton; + cancel: tbutton; + end; + +function realenter(var avalue: realty; const amin,amax: realty; const text: msestring = ''; + const acaption: msestring = ''): modalresultty; +//threadsave +implementation +uses + mserealenter_mfm; + +function realenter(var avalue: realty; const amin,amax: realty; const text: msestring = ''; + const acaption: msestring = ''): modalresultty; +var + fo: trealenterfo; +begin + application.lock; + try + fo:= trealenterfo.create(nil); + try + with fo do begin + value.min:= amin; + value.max:= amax; + value.value:= avalue; + caption:= acaption; + lab.caption:= text; + result:= fo.show(true,nil); + if result = mr_ok then begin + avalue:= value.value; + end; + end; + finally + fo.Free; + end; + finally + application.unlock; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/mserealenter_mfm.pas b/mseide-msegui/lib/common/dialogs/mserealenter_mfm.pas new file mode 100644 index 0000000..caefdd9 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mserealenter_mfm.pas @@ -0,0 +1,79 @@ +unit mserealenter_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mserealenter; + +const + objdata: record size: integer; data: array[0..1227] of byte end = + (size: 1228; data: ( + 84,80,70,48,12,116,114,101,97,108,101,110,116,101,114,102,111,11,114,101, + 97,108,101,110,116,101,114,102,111,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,139,1,8,98,111,117,110,100,115,95,121,3, + 67,1,9,98,111,117,110,100,115,95,99,120,3,233,0,9,98,111,117,110, + 100,115,95,99,121,2,88,12,98,111,117,110,100,115,95,99,121,109,105,110, + 2,75,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1, + 2,0,2,0,3,233,0,2,88,0,7,111,112,116,105,111,110,115,11,17, + 102,111,95,115,99,114,101,101,110,99,101,110,116,101,114,101,100,13,102,111, + 95,99,108,111,115,101,111,110,101,115,99,17,102,111,95,108,111,99,97,108, + 115,104,111,114,116,99,117,116,115,15,102,111,95,97,117,116,111,114,101,97, + 100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116, + 97,116,0,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6, + 8,116,109,115,101,102,111,114,109,0,6,116,108,97,98,101,108,3,108,97, + 98,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,14,111,119, + 49,95,97,117,116,111,104,101,105,103,104,116,0,8,116,97,98,111,114,100, + 101,114,2,3,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110, + 100,115,95,121,2,41,9,98,111,117,110,100,115,95,99,120,3,217,0,9, + 98,111,117,110,100,115,95,99,121,2,14,7,97,110,99,104,111,114,115,11, + 7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116, + 105,111,110,6,3,108,97,98,9,116,101,120,116,102,108,97,103,115,11,12, + 116,102,95,121,99,101,110,116,101,114,101,100,12,116,102,95,119,111,114,100, + 98,114,101,97,107,0,0,0,9,116,114,101,97,108,101,100,105,116,5,118, + 97,108,117,101,11,102,114,97,109,101,46,100,117,109,109,121,2,0,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,62, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,13,111,101,49,95,115,97,118,101,118,97, + 108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,5,118,97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,12, + 118,97,108,117,101,100,101,102,97,117,108,116,5,0,0,0,0,0,0,0, + 128,255,255,10,118,97,108,117,101,114,97,110,103,101,2,0,10,118,97,108, + 117,101,115,116,97,114,116,2,0,3,109,105,110,5,0,0,0,0,0,0, + 0,128,255,255,3,109,97,120,5,245,136,13,181,80,153,118,150,125,64,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98, + 117,116,116,111,110,2,111,107,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,120,8,98,111,117,110,100,115,95,121,2, + 62,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105, + 103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101, + 11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109, + 111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7, + 116,98,117,116,116,111,110,6,99,97,110,99,101,108,8,116,97,98,111,114, + 100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111, + 117,110,100,115,95,121,2,62,9,98,111,117,110,100,115,95,99,120,2,50, + 9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115, + 11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109, + 0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99, + 101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99, + 97,110,99,101,108,0,0,0) + ); + +initialization + registerobjectdata(@objdata,trealenterfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/mseshortcutdialog.mfm b/mseide-msegui/lib/common/dialogs/mseshortcutdialog.mfm new file mode 100644 index 0000000..051b959 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseshortcutdialog.mfm @@ -0,0 +1,314 @@ +object mseshortcutdialogfo: tmseshortcutdialogfo + visible = False + bounds_x = 87 + bounds_y = 222 + bounds_cx = 595 + bounds_cy = 340 + container.onlayout = layoutexe + container.bounds = ( + 0 + 0 + 595 + 340 + ) + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + caption = 'Shortcuts' + onlayout = layoutexe + moduleclassname = 'tmseform' + object tsimplewidget1: tsimplewidget + taborder = 4 + visible = True + bounds_x = 71 + bounds_y = 285 + bounds_cx = 403 + bounds_cy = 53 + bounds_cxmin = 200 + anchors = [an_left, an_right, an_bottom] + object sc1ed: tstringedit + Tag = 1 + frame.options = [cfo_fixtop] + frame.levelo = 0 + frame.framewidth = 1 + frame.colorframe = -1610612734 + frame.colorclient = -1879048185 + frame.caption = '&Alternate' + frame.localprops = [frl_levelo, frl_framewidth, frl_colorframe, frl_fileft, frl_colorclient] + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + hint = 'Press the desired key combination.' + onshowhint = keyhint + onactivate = edactivate + ondeactivate = eddeactivate + bounds_x = 208 + bounds_y = 4 + bounds_cx = 189 + bounds_cy = 37 + anchors = [an_left, an_right, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + onkeydown = scdikey + onkeyup = scdikey + reffontheight = 14 + end + object tsplitter1: tsplitter + color = -1879048189 + taborder = 1 + visible = False + bounds_x = 200 + bounds_y = 19 + bounds_cx = 8 + bounds_cy = 20 + anchors = [an_left, an_bottom] + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = sced + linkright = sc1ed + end + object sced: tstringedit + frame.options = [cfo_fixtop] + frame.levelo = 0 + frame.framewidth = 1 + frame.colorframe = -1610612734 + frame.colorclient = -1879048185 + frame.caption = '&Shortcut' + frame.localprops = [frl_levelo, frl_framewidth, frl_colorframe, frl_colorclient] + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + hint = 'Press the desired key combination.' + onshowhint = keyhint + onactivate = edactivate + ondeactivate = eddeactivate + bounds_x = 3 + bounds_y = 4 + bounds_cx = 197 + bounds_cy = 37 + anchors = [an_left, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + onkeydown = scdikey + onkeyup = scdikey + reffontheight = 14 + end + end + object grid: twidgetgrid + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 595 + bounds_cy = 286 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 3 + captions.items = < + item + caption = 'Action' + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + end + item + caption = 'Shortcut' + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + end + item + caption = 'Alternate' + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + end> + end> + datacols.count = 3 + datacols.options = [co_focusselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[sc] + width = 338 + onbeforedrawcell = beforedrawnode + options = [co_readonly, co_drawfocus, co_focusselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'sc' + dataclass = ttreeitemeditlist + end + item[scdi] + width = 125 + onbeforedrawcell = beforedraw + options = [co_readonly, co_nofocus, co_focusselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'scdi' + dataclass = tgridmsestringdatalist + end + item[sc1di] + width = 125 + onbeforedrawcell = beforedraw1 + options = [co_readonly, co_nofocus, co_focusselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'sc1di' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + oncellevent = gridcellevent + reffontheight = 14 + object sc: ttreeitemedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 338 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_locate] + onupdaterowvalues = updaterowvalues + options = [teo_treecolnavig] + reffontheight = 14 + end + object scdi: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.dummy = 0 + taborder = 2 + visible = False + bounds_x = 339 + bounds_y = 0 + bounds_cx = 125 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object sc1di: tstringedit + Tag = 1 + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.dummy = 0 + taborder = 3 + visible = False + bounds_x = 465 + bounds_y = 0 + bounds_cx = 125 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + object okbu: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 482 + bounds_y = 306 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object cancelbu: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 2 + bounds_x = 540 + bounds_y = 306 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object defaultbu: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + color = -2147483645 + taborder = 3 + bounds_x = 8 + bounds_y = 306 + bounds_cx = 55 + bounds_cy = 20 + bounds_cxmin = 50 + anchors = [an_left, an_bottom] + state = [as_localcaption, as_localcolor, as_localonexecute] + caption = '&Default' + onexecute = defaultex + reffontheight = 14 + end + object tspacer2: tspacer + taborder = 5 + bounds_x = 532 + bounds_y = 304 + bounds_cx = 8 + bounds_cy = 20 + anchors = [an_left, an_bottom] + linkleft = okbu + linkright = cancelbu + options = [spao_glueright] + end + object tspacer1: tspacer + taborder = 6 + bounds_x = 474 + bounds_y = 304 + bounds_cx = 8 + bounds_cy = 20 + anchors = [an_left, an_bottom] + linkleft = tsimplewidget1 + linkright = okbu + options = [spao_glueright] + end + object tspacer3: tspacer + taborder = 7 + bounds_x = 63 + bounds_y = 304 + bounds_cx = 8 + bounds_cy = 20 + anchors = [an_left, an_bottom] + linkleft = defaultbu + linkright = tsimplewidget1 + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 2 + menu.submenu.items = < + item + caption = 'Expand all' + state = [as_localcaption, as_localonexecute] + onexecute = expandall + end + item + caption = 'Collapse all' + state = [as_localcaption, as_localonexecute] + onexecute = collapseall + end> + left = 32 + top = 64 + end + object timer: ttimer + interval = 1500000 + options = [to_single] + ontimer = keytimeout + left = 160 + top = 64 + end +end diff --git a/mseide-msegui/lib/common/dialogs/mseshortcutdialog.pas b/mseide-msegui/lib/common/dialogs/mseshortcutdialog.pas new file mode 100644 index 0000000..6dc9bc8 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseshortcutdialog.pas @@ -0,0 +1,697 @@ +{ MSEgui Copyright (c) 2008-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseshortcutdialog; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msedataedits,mseedit,msegrids, + msestrings,msetypes,msewidgetgrid,msedatanodes,mselistbrowser,mseactions, + msesimplewidgets,msewidgets,msegridsglob,msetimer,msesplitter,mseificomp, + mseificompglob,mseifiglob; + +type + tmseshortcutdialogfo = class(tmseform) + grid: twidgetgrid; + sc: ttreeitemedit; + scdi: tstringedit; + sc1di: tstringedit; + okbu: tbutton; + cancelbu: tbutton; + defaultbu: tbutton; + tpopupmenu1: tpopupmenu; + timer: ttimer; + tsimplewidget1: tsimplewidget; + sc1ed: tstringedit; + tsplitter1: tsplitter; + sced: tstringedit; + tspacer2: tspacer; + tspacer1: tspacer; + tspacer3: tspacer; + procedure updaterowvalues(const sender: TObject; const aindex: Integer; + const aitem: tlistitem); + procedure scdikey(const sender: twidget; var info: keyeventinfoty); + procedure gridcellevent(const sender: TObject; var info: celleventinfoty); + procedure edactivate(const sender: TObject); + procedure eddeactivate(const sender: TObject); + procedure defaultex(const sender: TObject); + procedure collapseall(const sender: TObject); + procedure expandall(const sender: TObject); + procedure beforedrawnode(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure beforedraw(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure beforedraw1(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure keyhint(const sender: TObject; var info: hintinfoty); + procedure keytimeout(const sender: TObject); + procedure layoutexe(const sender: TObject); + private +// fkeyentering: boolean; + frootnodes: treelistedititemarty; + procedure updateedits; + procedure checkconflict; + end; + +function shortcutdialog(const acontroller: tshortcutcontroller): modalresultty; + +implementation +uses + mseshortcutdialog_mfm,msekeyboard,msedatalist,msearrayutils,msestockobjects; + +const + errorcolor = cl_ltred; + +type + tshortcutitem = class(ttreelistedititem) + private + fisgroup: boolean; + fshortcut: shortcutarty; + fshortcut1: shortcutarty; + fshortcutdefault: shortcutarty; + fshortcut1default: shortcutarty; + fconflict: boolean; + fconflict1: boolean; + procedure setshortcut(const avalue: shortcutarty); + procedure setshortcut1(const avalue: shortcutarty); + public + constructor create(const aitem: tshortcutaction); overload; + procedure resetconflict; + property shortcut: shortcutarty read fshortcut write setshortcut; + property shortcut1: shortcutarty read fshortcut1 write setshortcut1; + end; + + tsysshortcutitem = class(tshortcutitem) + public + constructor create(const acaption: msestring); overload; + constructor create(const acontroller: tshortcutcontroller; + const aindex: sysshortcutty); overload; + end; + + tassistiveshortcutitem = class(tshortcutitem) + public + constructor create(const acaption: msestring); overload; + constructor create(const acontroller: tshortcutcontroller; + const aindex: assistiveshortcutty); overload; + end; + +function shortcutdialog(const acontroller: tshortcutcontroller): modalresultty; +var + fo1: tmseshortcutdialogfo; + no: tshortcutitem; + no1: tsysshortcutitem; + no2: tassistiveshortcutitem; + item1: tshortcutaction; + int1,int2: integer; + ss1: sysshortcutty; + as1: assistiveshortcutty; +begin + fo1:= tmseshortcutdialogfo.create(nil); + try + no1:= tsysshortcutitem.create(stockobjects.captions[sc_system]); + for ss1:= low(ss1) to high(ss1) do begin + no1.add(tsysshortcutitem.create(acontroller,ss1)); + end; + no2:= tassistiveshortcutitem.create(stockobjects.captions[sc_voiceoutput]); + for as1:= low(as1) to high(as1) do begin + no2.add(tassistiveshortcutitem.create(acontroller,as1)); + end; + no1.add(no2); + fo1.sc.itemlist.add(no1); + additem(pointerarty(fo1.frootnodes),no1); + additem(pointerarty(fo1.frootnodes),no2); + with acontroller.actions do begin + if count > 0 then begin + if items[0].action <> nil then begin + no:= tshortcutitem.create(items[0]); + end + else begin + no:= nil; + end; + for int1:= 0 to count - 1 do begin + item1:= items[int1]; + with item1 do begin + if action = nil then begin + if no <> nil then begin + fo1.sc.itemlist.add(no); + additem(pointerarty(fo1.frootnodes),no); + end; + no:= tshortcutitem.create(item1); + end + else begin + no.add(tshortcutitem.create(item1)); + end; + end; + end; + if no <> nil then begin + fo1.sc.itemlist.add(no); + additem(pointerarty(fo1.frootnodes),no); + end; + end; + end; + fo1.sc.itemlist.expandall; + fo1.checkconflict; + result:= fo1.show(true); + if result = mr_ok then begin + fo1.sc.itemlist.expandall; + acontroller.sysshortcuts.beginupdate; + acontroller.sysshortcuts1.beginupdate; + for ss1:= low(ss1) to high(ss1) do begin + with tsysshortcutitem(no1[ord(ss1)]) do begin + acontroller.sysshortcuts[ss1]:= getsimpleshortcut(fshortcut); + acontroller.sysshortcuts1[ss1]:= getsimpleshortcut(fshortcut1); + end; + end; + acontroller.sysshortcuts.endupdate; + acontroller.sysshortcuts1.endupdate; + + acontroller.assistiveshortcuts.beginupdate(); + acontroller.assistiveshortcuts1.beginupdate(); + for as1:= low(as1) to high(as1) do begin + with tassistiveshortcutitem(no2[ord(as1)]) do begin + acontroller.assistiveshortcuts[as1]:= fshortcut; + acontroller.assistiveshortcuts1[as1]:= fshortcut1; + end; + end; + acontroller.assistiveshortcuts.endupdate(); + acontroller.assistiveshortcuts1.endupdate(); + + int2:= ord(high(ss1))+ord(high(as1)) + 4; + for int1:= int2 to fo1.grid.rowhigh do begin + with tshortcutitem(fo1.sc[int1]) do begin + if not fisgroup then begin + with acontroller.actions[int1-int2].action do begin + shortcuts:= fshortcut; + shortcuts1:= fshortcut1; + end; + end; + end; + end; + acontroller.doafterupdate; + end; + finally + fo1.free; + end; +end; + +{ tshortcutitem } + +constructor tshortcutitem.create(const aitem: tshortcutaction); +begin + inherited create; + with aitem do begin + caption:= aitem.dispname; + fisgroup:= action = nil; + if action <> nil then begin + fshortcut:= action.shortcuts; + fshortcut1:= action.shortcuts1; + fshortcutdefault:= shortcutsdefault; + fshortcut1default:= shortcuts1default; + end; + end; +end; + +procedure tshortcutitem.setshortcut(const avalue: shortcutarty); +begin + fshortcut:= avalue; + change; +end; + +procedure tshortcutitem.setshortcut1(const avalue: shortcutarty); +begin + fshortcut1:= avalue; + change; +end; + +procedure tshortcutitem.resetconflict; +var + int1: integer; +begin + fconflict:= false; + fconflict1:= false; + for int1:= 0 to count - 1 do begin + tshortcutitem(fitems[int1]).resetconflict; + end; +end; + +{ tsysshortcutitem } + +constructor tsysshortcutitem.create(const acaption: msestring); +begin + inherited create(nil,nil); + caption:= acaption; + fisgroup:= true; +end; + +constructor tsysshortcutitem.create(const acontroller: tshortcutcontroller; + const aindex: sysshortcutty); +begin + inherited create(nil,nil); + caption:= getsysshortcutdispname(aindex); + with acontroller do begin + setsimpleshortcut(sysshortcuts[aindex],fshortcut); + setsimpleshortcut(sysshortcuts1[aindex],fshortcut1); + setsimpleshortcut(defaultsysshortcuts[aindex],fshortcutdefault); + setsimpleshortcut(defaultsysshortcuts1[aindex],fshortcut1default); + end; +end; + +{ tassistiveshortcutitem } + +constructor tassistiveshortcutitem.create(const acaption: msestring); +begin + inherited create(nil,nil); + caption:= acaption; + fisgroup:= true; +end; + +constructor tassistiveshortcutitem.create(const acontroller: tshortcutcontroller; + const aindex: assistiveshortcutty); + + procedure setdefault(const source: shortcutconstty; out dest: shortcutarty); + var + i1: int32; + begin + dest:= nil; + for i1:= 0 to high(source) do begin + if source[i1] = 0 then begin + break; + end; + additem(int16arty(dest),int16(source[i1])); + end; + end; //setdefault + +begin + inherited create(nil,nil); + caption:= getassistiveshortcutdispname(aindex); + with acontroller do begin + fshortcut:= assistiveshortcuts[aindex]; + fshortcut1:= assistiveshortcuts1[aindex]; + setdefault(defaultassistiveshortcuts[aindex],fshortcutdefault); + setdefault(defaultassistiveshortcuts1[aindex],fshortcut1default); + end; +end; + + +{ tmseshortcutdialogfo } + +procedure tmseshortcutdialogfo.updaterowvalues(const sender: TObject; + const aindex: Integer; const aitem: tlistitem); +begin + with tshortcutitem(aitem) do begin + if fisgroup then begin + scdi[aindex]:= ''; + sc1di[aindex]:= ''; + end + else begin + scdi[aindex]:= encodeshortcutname(fshortcut); + sc1di[aindex]:= encodeshortcutname(fshortcut1); + end; + end; +end; + +procedure tmseshortcutdialogfo.updateedits; +begin + if sc.item <> nil then begin + with tshortcutitem(sc.item) do begin + if fisgroup and (fconflict or fconflict1) then begin + sc.color:= errorcolor; + end + else begin + sc.color:= cl_default; + end; + end; + end; + sced.value:= scdi.value; + sc1ed.value:= sc1di.value; +end; + +procedure tmseshortcutdialogfo.keytimeout(const sender: TObject); +begin + if sced.focused then begin + sced.editor.selectall; + end + else begin + if sc1ed.focused then begin + sc1ed.editor.selectall; + end; + end; +end; + +procedure tmseshortcutdialogfo.scdikey(const sender: twidget; + var info: keyeventinfoty); + function setkey(const akey: shortcutty; + const existing: shortcutarty): shortcutarty; + begin + result:= nil; + if timer.enabled then begin + result:= existing; + end; + if akey and not modmask <> 0 then begin + setlength(result,high(result)+2); + result[high(result)]:= akey; + end; + end; //setkey + +var + mstr1: msestring; + sc1: shortcutty; + ar1: shortcutarty; +begin + with info do begin + with tshortcutitem(sc.item) do begin + if sender.tag = 0 then begin + ar1:= shortcut; + end + else begin + ar1:= shortcut1; + end; + if eventkind = ek_keypress then begin + sc1:= 0; + if not timer.enabled or (sc.item is tsysshortcutitem) then begin + ar1:= nil; + end; + mstr1:= encodeshortcutname(ar1); + if mstr1 <> '' then begin + mstr1:= mstr1 + ' '; + end; + if ss_shift in shiftstate then begin + mstr1:= mstr1+'Shift+'; + sc1:= sc1 + ord(key_modshift); + end; + if ss_ctrl in shiftstate then begin + mstr1:= mstr1+'Ctrl+'; + sc1:= sc1 + ord(key_modctrl); + end; + if ss_alt in shiftstate then begin + mstr1:= mstr1+'Alt+'; + sc1:= sc1 + ord(key_modalt); + end; + if ss_second in shiftstate then begin + mstr1:= mstr1+'Pad+'; + sc1:= sc1 + ord(key_modpad); + end; + if (keynomod = key_shift) or (keynomod = key_control) or + (keynomod = key_alt) then begin + sc1:= 0; + end; + case key of + key_shift,key_alt,key_control: begin + end + else begin + sc1:= sc1 or (ord(keynomod) and not modmask); + if (high(ar1) >= 0) or isvalidshortcut(sc1) or + (keyty(sc1) = key_delete) then begin + if (high(ar1) < 0) and (keyty(sc1) = key_delete) then begin + sc1:= 0; + tstringedit(sender).value:= ''; + end; + ar1:= setkey(sc1,ar1); + if sender.tag = 0 then begin + shortcut:= ar1; + end + else begin + shortcut1:= ar1; + end; + sc.itemlist.refreshitemvalues(-1,1); //show changes + include(eventstate,es_processed); + if not (sc.item is tsysshortcutitem) then begin + timer.enabled:= true; + timer.interval:= timer.interval; + end; + end; + checkconflict; + end; + end; + if mstr1 <> '' then begin + tstringedit(sender).value:= mstr1; + end; + end + else begin + if eventkind = ek_keyrelease then begin + tstringedit(sender).value:= encodeshortcutname(ar1); + updateedits; + end; + end; + end; + end; + if timer.enabled then begin + tstringedit(sender).editor.clearselection; + end; +end; + +procedure tmseshortcutdialogfo.gridcellevent(const sender: TObject; + var info: celleventinfoty); +var + bo1: boolean; +begin + case info.eventkind of + cek_focusedcellchanged: begin + updateedits; + bo1:= not ((sc.item = nil) or tshortcutitem(sc.item).fisgroup); + sced.enabled:= bo1; + sc1ed.enabled:= bo1; + defaultbu.enabled:= bo1; + end; + cek_buttonrelease: begin + if iscellclick(info) then begin + if info.cell.row >= 0 then begin + if not tshortcutitem(sc.item).fisgroup then begin + case info.cell.col of + 1: begin + sced.setfocus; + end; + 2: begin + sc1ed.setfocus; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tmseshortcutdialogfo.edactivate(const sender: TObject); +begin + with tstringedit(sender) do begin + frame.colorframe:= cl_red; + end; +end; + +procedure tmseshortcutdialogfo.eddeactivate(const sender: TObject); +begin + with tstringedit(sender) do begin + frame.colorframe:= cl_black; + end; +end; + +procedure tmseshortcutdialogfo.defaultex(const sender: TObject); +begin + with tshortcutitem(sc.item) do begin + shortcut:= fshortcutdefault; + shortcut1:= fshortcut1default; + end; + sc.itemlist.refreshitemvalues(grid.row,1); + checkconflict; +end; + +procedure tmseshortcutdialogfo.collapseall(const sender: TObject); +begin + sc.itemlist.collapseall; +end; + +procedure tmseshortcutdialogfo.expandall(const sender: TObject); +begin + sc.itemlist.expandall; +end; + +procedure tmseshortcutdialogfo.checkconflict; +var + int1,int2,int3,int4: integer; + rootnode1: tshortcutitem; + rootnode2: tshortcutitem; + node1: tshortcutitem; + scut,scut1: shortcutarty; + conflict,conflict1: boolean; +begin + conflict:= false; + conflict1:= false; + for int1:= 0 to high(frootnodes) do begin + tshortcutitem(frootnodes[int1]).resetconflict; + end; + for int1:= 0 to high(frootnodes) do begin + rootnode1:= tshortcutitem(frootnodes[int1]); + with rootnode1 do begin + for int2:= 0 to count - 1 do begin + node1:= tshortcutitem(fitems[int2]); + with node1 do begin + scut:= fshortcut; + scut1:= fshortcut1; + for int3:= int2 + 1 to rootnode1.count - 1 do begin + //leafs in current node + with tshortcutitem(rootnode1.fitems[int3]) do begin + if (scut <> nil) then begin + if checkshortcutconflict(fshortcut,scut) then begin + node1.fconflict:= true; + rootnode1.fconflict:= true; + fconflict:= true; + conflict:= true; + end; + if checkshortcutconflict(fshortcut1,scut) then begin + node1.fconflict:= true; + conflict:= true; + rootnode1.fconflict:= true; + fconflict1:= true; + conflict1:= true; + end; + end; + if (scut1 <> nil) then begin + if checkshortcutconflict(fshortcut,scut1) then begin + node1.fconflict1:= true; + conflict1:= true; + rootnode1.fconflict1:= true; + fconflict:= true; + conflict:= true; + end; + if checkshortcutconflict(fshortcut1,scut1) then begin + node1.fconflict1:= true; + conflict1:= true; + rootnode1.fconflict1:= true; + fconflict1:= true; + end; + end; + end; + end; + for int4:= int1+1 to high(frootnodes) do begin + //remaining nodes + rootnode2:= tshortcutitem(frootnodes[int4]); + for int3:= 0 to rootnode2.count - 1 do begin + with tshortcutitem(rootnode2.fitems[int3]) do begin + if (scut <> nil) then begin + if checkshortcutconflict(fshortcut,scut) then begin + node1.fconflict:= true; + conflict:= true; + rootnode1.fconflict:= true; + fconflict:= true; + rootnode2.fconflict:= true; + end; + if checkshortcutconflict(fshortcut1,scut) then begin + node1.fconflict:= true; + conflict:= true; + rootnode1.fconflict:= true; + fconflict1:= true; + conflict1:= true; + rootnode2.fconflict1:= true; + end; + end; + if (scut1 <> nil) then begin + if checkshortcutconflict(fshortcut,scut1) then begin + node1.fconflict1:= true; + conflict1:= true; + rootnode1.fconflict1:= true; + fconflict:= true; + conflict:= true; + rootnode2.fconflict:= true; + end; + if checkshortcutconflict(fshortcut1,scut1) then begin + node1.fconflict1:= true; + conflict1:= true; + rootnode1.fconflict1:= true; + fconflict1:= true; + rootnode2.fconflict1:= true; + end; + end; + end; + end; + end; + end; + end; + end; + end; + with grid.fixrows[-1] do begin + if conflict then begin + captions[1].font.color:= cl_red; + end + else begin + captions[1].font.color:= cl_text; + end; + if conflict1 then begin + captions[2].font.color:= cl_red; + end + else begin + captions[2].font.color:= cl_text; + end; + end; + grid.invalidate; + updateedits; +end; + +procedure tmseshortcutdialogfo.beforedrawnode(const sender: tcol; + const canvas: tcanvas; var cellinfo: cellinfoty; + var processed: Boolean); +begin + with tshortcutitem(cellinfo.datapo^) do begin + if fisgroup and (fconflict or fconflict1) then begin + cellinfo.color:= errorcolor; + end; + end; +end; + +procedure tmseshortcutdialogfo.beforedraw(const sender: tcol; + const canvas: tcanvas; var cellinfo: cellinfoty; + var processed: Boolean); +begin + with tshortcutitem(sc[cellinfo.cell.row]) do begin + if not fisgroup then begin + if fconflict then begin + cellinfo.color:= errorcolor; + end + else begin + if not issameshortcut(fshortcut,fshortcutdefault) then begin + cellinfo.color:= cl_infobackground; + end; + end; + end; + end; +end; + +procedure tmseshortcutdialogfo.beforedraw1(const sender: tcol; + const canvas: tcanvas; var cellinfo: cellinfoty; + var processed: Boolean); +begin + with tshortcutitem(sc[cellinfo.cell.row]) do begin + if not fisgroup then begin + if fconflict1 then begin + cellinfo.color:= errorcolor; + end + else begin + if not issameshortcut(fshortcut1,fshortcut1default) then begin + cellinfo.color:= cl_infobackground; + end; + end; + end; + end; +end; + +procedure tmseshortcutdialogfo.keyhint(const sender: TObject; + var info: hintinfoty); +begin + if not twidget(sender).active then begin + info.caption:= ''; + end; +end; + +procedure tmseshortcutdialogfo.layoutexe(const sender: TObject); +begin + aligny(wam_center,[sced,defaultbu,okbu,cancelbu]); +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/mseshortcutdialog_mfm.pas b/mseide-msegui/lib/common/dialogs/mseshortcutdialog_mfm.pas new file mode 100644 index 0000000..0e58c3b --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseshortcutdialog_mfm.pas @@ -0,0 +1,356 @@ +unit mseshortcutdialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseshortcutdialog; + +const + objdata: record size: integer; data: array[0..6779] of byte end = + (size: 6780; data: ( + 84,80,70,48,20,116,109,115,101,115,104,111,114,116,99,117,116,100,105,97, + 108,111,103,102,111,19,109,115,101,115,104,111,114,116,99,117,116,100,105,97, + 108,111,103,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,87,8,98,111,117,110,100,115,95,121,3,222,0,9,98,111, + 117,110,100,115,95,99,120,3,83,2,9,98,111,117,110,100,115,95,99,121, + 3,84,1,18,99,111,110,116,97,105,110,101,114,46,111,110,108,97,121,111, + 117,116,7,9,108,97,121,111,117,116,101,120,101,16,99,111,110,116,97,105, + 110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,83,2,3,84, + 1,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101,101, + 110,99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111,110, + 101,115,99,17,102,111,95,108,111,99,97,108,115,104,111,114,116,99,117,116, + 115,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111, + 95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97, + 118,101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,7, + 99,97,112,116,105,111,110,6,9,83,104,111,114,116,99,117,116,115,8,111, + 110,108,97,121,111,117,116,7,9,108,97,121,111,117,116,101,120,101,15,109, + 111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101, + 102,111,114,109,0,13,116,115,105,109,112,108,101,119,105,100,103,101,116,14, + 116,115,105,109,112,108,101,119,105,100,103,101,116,49,8,116,97,98,111,114, + 100,101,114,2,4,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100, + 115,95,120,2,71,8,98,111,117,110,100,115,95,121,3,29,1,9,98,111, + 117,110,100,115,95,99,120,3,147,1,9,98,111,117,110,100,115,95,99,121, + 2,53,12,98,111,117,110,100,115,95,99,120,109,105,110,3,200,0,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95,114, + 105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,0,11,116,115,116, + 114,105,110,103,101,100,105,116,5,115,99,49,101,100,3,84,97,103,2,1, + 13,102,114,97,109,101,46,111,112,116,105,111,110,115,11,10,99,102,111,95, + 102,105,120,116,111,112,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,16,102,114,97,109,101,46,102,114,97,109,101,119,105,100,116,104,2, + 1,16,102,114,97,109,101,46,99,111,108,111,114,102,114,97,109,101,4,2, + 0,0,160,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,10,38,65,108,116,101,114,110,97,116,101,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,14,102,114,108,95,102,114,97,109,101,119,105,100,116,104,14,102,114,108, + 95,99,111,108,111,114,102,114,97,109,101,10,102,114,108,95,102,105,108,101, + 102,116,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,11, + 102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 4,104,105,110,116,6,34,80,114,101,115,115,32,116,104,101,32,100,101,115, + 105,114,101,100,32,107,101,121,32,99,111,109,98,105,110,97,116,105,111,110, + 46,10,111,110,115,104,111,119,104,105,110,116,7,7,107,101,121,104,105,110, + 116,10,111,110,97,99,116,105,118,97,116,101,7,10,101,100,97,99,116,105, + 118,97,116,101,12,111,110,100,101,97,99,116,105,118,97,116,101,7,12,101, + 100,100,101,97,99,116,105,118,97,116,101,8,98,111,117,110,100,115,95,120, + 3,208,0,8,98,111,117,110,100,115,95,121,2,4,9,98,111,117,110,100, + 115,95,99,120,3,189,0,9,98,111,117,110,100,115,95,99,121,2,37,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,9,111,110,107,101,121,100,111,119,110,7,7,115,99,100,105,107,101,121, + 7,111,110,107,101,121,117,112,7,7,115,99,100,105,107,101,121,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,112,108, + 105,116,116,101,114,10,116,115,112,108,105,116,116,101,114,49,5,99,111,108, + 111,114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2,1,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,200,0,8, + 98,111,117,110,100,115,95,121,2,19,9,98,111,117,110,100,115,95,99,120, + 2,8,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111, + 109,0,7,111,112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111, + 112,12,115,112,111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100, + 111,99,107,116,111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116, + 14,115,112,111,95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110, + 107,108,101,102,116,7,4,115,99,101,100,9,108,105,110,107,114,105,103,104, + 116,7,5,115,99,49,101,100,0,0,11,116,115,116,114,105,110,103,101,100, + 105,116,4,115,99,101,100,13,102,114,97,109,101,46,111,112,116,105,111,110, + 115,11,10,99,102,111,95,102,105,120,116,111,112,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,16,102,114,97,109,101,46,102,114,97,109, + 101,119,105,100,116,104,2,1,16,102,114,97,109,101,46,99,111,108,111,114, + 102,114,97,109,101,4,2,0,0,160,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,9,38,83,104,111,114,116,99,117,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,14,102,114,108,95,102,114,97,109,101,119,105,100, + 116,104,14,102,114,108,95,99,111,108,111,114,102,114,97,109,101,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,11,102,114,97,109,101, + 46,100,117,109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,2,4,104,105,110,116,6,34,80,114,101,115,115,32,116, + 104,101,32,100,101,115,105,114,101,100,32,107,101,121,32,99,111,109,98,105, + 110,97,116,105,111,110,46,10,111,110,115,104,111,119,104,105,110,116,7,7, + 107,101,121,104,105,110,116,10,111,110,97,99,116,105,118,97,116,101,7,10, + 101,100,97,99,116,105,118,97,116,101,12,111,110,100,101,97,99,116,105,118, + 97,116,101,7,12,101,100,100,101,97,99,116,105,118,97,116,101,8,98,111, + 117,110,100,115,95,120,2,3,8,98,111,117,110,100,115,95,121,2,4,9, + 98,111,117,110,100,115,95,99,120,3,197,0,9,98,111,117,110,100,115,95, + 99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112, + 109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,9,111,110, + 107,101,121,100,111,119,110,7,7,115,99,100,105,107,101,121,7,111,110,107, + 101,121,117,112,7,7,115,99,100,105,107,101,121,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,0,11,116,119,105,100,103,101,116, + 103,114,105,100,4,103,114,105,100,9,112,111,112,117,112,109,101,110,117,7, + 11,116,112,111,112,117,112,109,101,110,117,49,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,83,2,9,98,111,117,110,100,115,95,99,121,3,30,1, + 7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95, + 98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11, + 12,111,103,95,99,111,108,115,105,122,105,110,103,19,111,103,95,102,111,99, + 117,115,99,101,108,108,111,110,101,110,116,101,114,20,111,103,95,99,111,108, + 99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114, + 97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111, + 103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105, + 120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119, + 115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99, + 97,112,116,105,111,110,115,46,99,111,117,110,116,2,3,14,99,97,112,116, + 105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110, + 6,6,65,99,116,105,111,110,9,102,111,110,116,46,110,97,109,101,6,11, + 115,116,102,95,100,101,102,97,117,108,116,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,10,102,111,110,116,46,100,117,109,109,121,2,0,0,1, + 7,99,97,112,116,105,111,110,6,8,83,104,111,114,116,99,117,116,9,102, + 111,110,116,46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108, + 116,11,102,111,110,116,46,120,115,99,97,108,101,2,1,10,102,111,110,116, + 46,100,117,109,109,121,2,0,0,1,7,99,97,112,116,105,111,110,6,9, + 65,108,116,101,114,110,97,116,101,9,102,111,110,116,46,110,97,109,101,6, + 11,115,116,102,95,100,101,102,97,117,108,116,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,10,102,111,110,116,46,100,117,109,109,121,2,0,0, + 0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,3, + 16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115, + 46,105,116,101,109,115,14,7,2,115,99,1,5,119,105,100,116,104,3,82, + 1,16,111,110,98,101,102,111,114,101,100,114,97,119,99,101,108,108,7,14, + 98,101,102,111,114,101,100,114,97,119,110,111,100,101,7,111,112,116,105,111, + 110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95, + 102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101, + 6,2,115,99,9,100,97,116,97,99,108,97,115,115,7,17,116,116,114,101, + 101,105,116,101,109,101,100,105,116,108,105,115,116,0,7,4,115,99,100,105, + 1,5,119,105,100,116,104,2,125,16,111,110,98,101,102,111,114,101,100,114, + 97,119,99,101,108,108,7,10,98,101,102,111,114,101,100,114,97,119,7,111, + 112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,10, + 99,111,95,110,111,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115, + 116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,4,115,99,100,105, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,5,115,99,49, + 100,105,1,5,119,105,100,116,104,2,125,16,111,110,98,101,102,111,114,101, + 100,114,97,119,99,101,108,108,7,11,98,101,102,111,114,101,100,114,97,119, + 49,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110, + 108,121,10,99,111,95,110,111,102,111,99,117,115,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99, + 116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97, + 118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,5,115, + 99,49,100,105,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105, + 100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0, + 13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,11,111,110,99, + 101,108,108,101,118,101,110,116,7,13,103,114,105,100,99,101,108,108,101,118, + 101,110,116,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 13,116,116,114,101,101,105,116,101,109,101,100,105,116,2,115,99,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,82, + 1,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114, + 101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,9,111,101,95,108,111,99,97,116,101,0,17,111,110,117,112, + 100,97,116,101,114,111,119,118,97,108,117,101,115,7,15,117,112,100,97,116, + 101,114,111,119,118,97,108,117,101,115,7,111,112,116,105,111,110,115,11,16, + 116,101,111,95,116,114,101,101,99,111,108,110,97,118,105,103,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,4,115,99,100,105,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0, + 128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108, + 105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,11,102, + 114,97,109,101,46,100,117,109,109,121,2,0,8,116,97,98,111,114,100,101, + 114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,3,83,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,125,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97, + 118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,5,115,99,49,100,105,3,84,97,103,2,1,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114, + 108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,11,102,114,97,109,101,46,100,117,109,109,121,2,0,8, + 116,97,98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,3,209,1,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,125,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,0,7,116,98,117,116,116,111,110,4,111,107,98,117,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116, + 111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104, + 0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,3,226,1,8,98,111,117,110,100,115,95,121,3,50,1,9,98,111,117, + 110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20, + 12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,7,97,110,99,104, + 111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116, + 116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79, + 75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116, + 98,117,116,116,111,110,8,99,97,110,99,101,108,98,117,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0, + 8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120, + 3,28,2,8,98,111,117,110,100,115,95,121,3,50,1,9,98,111,117,110, + 100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99,121,2,20,12, + 98,111,117,110,100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111, + 114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97, + 110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114, + 95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,7,116,98,117,116,116,111,110,9,100,101,102,97,117,108, + 116,98,117,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13, + 111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117, + 116,111,119,105,100,116,104,0,5,99,111,108,111,114,4,3,0,0,128,8, + 116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,3,50,1,9,98,111,117,110,100,115, + 95,99,120,2,55,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111, + 117,110,100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,13,97,115,95,108,111,99,97,108,99,111,108,111,114,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112, + 116,105,111,110,6,8,38,68,101,102,97,117,108,116,9,111,110,101,120,101, + 99,117,116,101,7,9,100,101,102,97,117,108,116,101,120,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,115,112,97,99,101, + 114,8,116,115,112,97,99,101,114,50,8,116,97,98,111,114,100,101,114,2, + 5,8,98,111,117,110,100,115,95,120,3,20,2,8,98,111,117,110,100,115, + 95,121,3,48,1,9,98,111,117,110,100,115,95,99,120,2,8,9,98,111, + 117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,8,108,105, + 110,107,108,101,102,116,7,4,111,107,98,117,9,108,105,110,107,114,105,103, + 104,116,7,8,99,97,110,99,101,108,98,117,7,111,112,116,105,111,110,115, + 11,14,115,112,97,111,95,103,108,117,101,114,105,103,104,116,0,0,0,7, + 116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,49,8,116,97,98, + 111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,218,1,8, + 98,111,117,110,100,115,95,121,3,48,1,9,98,111,117,110,100,115,95,99, + 120,2,8,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104, + 111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116, + 111,109,0,8,108,105,110,107,108,101,102,116,7,14,116,115,105,109,112,108, + 101,119,105,100,103,101,116,49,9,108,105,110,107,114,105,103,104,116,7,4, + 111,107,98,117,7,111,112,116,105,111,110,115,11,14,115,112,97,111,95,103, + 108,117,101,114,105,103,104,116,0,0,0,7,116,115,112,97,99,101,114,8, + 116,115,112,97,99,101,114,51,8,116,97,98,111,114,100,101,114,2,7,8, + 98,111,117,110,100,115,95,120,2,63,8,98,111,117,110,100,115,95,121,3, + 48,1,9,98,111,117,110,100,115,95,99,120,2,8,9,98,111,117,110,100, + 115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,9,97,110,95,98,111,116,116,111,109,0,8,108,105,110,107,108, + 101,102,116,7,9,100,101,102,97,117,108,116,98,117,9,108,105,110,107,114, + 105,103,104,116,7,14,116,115,105,109,112,108,101,119,105,100,103,101,116,49, + 0,0,10,116,112,111,112,117,112,109,101,110,117,11,116,112,111,112,117,112, + 109,101,110,117,49,18,109,101,110,117,46,115,117,98,109,101,110,117,46,99, + 111,117,110,116,2,2,18,109,101,110,117,46,115,117,98,109,101,110,117,46, + 105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,10,69,120,112, + 97,110,100,32,97,108,108,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 9,101,120,112,97,110,100,97,108,108,0,1,7,99,97,112,116,105,111,110, + 6,12,67,111,108,108,97,112,115,101,32,97,108,108,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,11,99,111,108,108,97,112,115,101,97,108,108,0, + 0,4,108,101,102,116,2,32,3,116,111,112,2,64,0,0,6,116,116,105, + 109,101,114,5,116,105,109,101,114,8,105,110,116,101,114,118,97,108,4,96, + 227,22,0,7,111,112,116,105,111,110,115,11,9,116,111,95,115,105,110,103, + 108,101,0,7,111,110,116,105,109,101,114,7,10,107,101,121,116,105,109,101, + 111,117,116,4,108,101,102,116,3,160,0,3,116,111,112,2,64,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmseshortcutdialogfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msestringenter.mfm b/mseide-msegui/lib/common/dialogs/msestringenter.mfm new file mode 100644 index 0000000..d0b2fe3 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msestringenter.mfm @@ -0,0 +1,94 @@ +object stringenterfo: tstringenterfo + optionswidget1 = [ow1_autoscale, ow1_autoheight] + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 340 + bounds_y = 323 + bounds_cx = 398 + bounds_cy = 70 + bounds_cxmin = 200 + bounds_cymin = 70 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.framei_bottom = 10 + container.frame.localprops = [frl_fibottom] + container.frame.localprops1 = [] + container.onlayout = layoutexe + container.bounds = ( + 0 + 0 + 398 + 70 + ) + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat] + windowopacity = -Inf + onlayout = layoutexe + moduleclassname = 'tmseform' + object lab: tlabel + optionswidget1 = [ow1_autoheight] + optionswidget = [ow_mousewheel, ow_destroywidgets] + taborder = 1 + bounds_x = 7 + bounds_y = 12 + bounds_cx = 384 + bounds_cy = 16 + anchors = [an_left, an_top, an_right] + caption = 'lab' + textflags = [tf_ycentered, tf_wordbreak] + end + object tlayouter1: tlayouter + bounds_x = 8 + bounds_y = 36 + bounds_cx = 383 + bounds_cy = 22 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 8 + place_maxdist = 8 + place_options = [plo_endmargin] + linktop = lab + dist_top = 8 + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth, ow1_autosizeanright] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 2 + bounds_x = 333 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 16 + end + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 1 + bounds_x = 275 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 16 + end + object value: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 267 + bounds_cy = 22 + anchors = [an_left, an_top, an_right] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 16 + end + end +end diff --git a/mseide-msegui/lib/common/dialogs/msestringenter.pas b/mseide-msegui/lib/common/dialogs/msestringenter.pas new file mode 100644 index 0000000..55937fd --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msestringenter.pas @@ -0,0 +1,110 @@ +{ MSEgui Copyright (c) 1999-2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestringenter; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msetypes,msegui,mseglob,mseguiglob, + msedialog,msestrings,msestringcontainer,msemenus,msesplitter,msegraphics, + msegraphutils,msewidgets,mseapplication,mseedit,mseificomp,mseificompglob, + mseifiglob,msestat,msestatfile,msestream,sysutils; + +type + tstringenterfo = class(tdialogform) + lab: tlabel; + tlayouter1: tlayouter; + cancel: tbutton; + ok: tbutton; + value: tstringedit; + procedure layoutexe(const sender: TObject); + end; + +//functions below are threadsave +function stringenter(var avalue: msestring; const text: msestring = ''; + const acaption: msestring = ''): modalresultty; + +function checkpassword(const password: msestring): boolean; overload; +function checkpassword(const password: msestring; var modalresult: modalresultty): boolean; overload; + +implementation +uses + msestringenter_mfm,msestockobjects; + +function stringenter(var avalue: msestring; const text: msestring = ''; + const acaption: msestring = ''): modalresultty; +var + fo: tstringenterfo; +begin + application.lock; + try + fo:= tstringenterfo.create(nil); + try + with fo do begin + value.value:= avalue; + caption:= acaption; + lab.caption:= text; + result:= fo.show(true,nil); + if result = mr_ok then begin + avalue:= value.value; + end; + end; + finally + fo.Free; + end; + finally + application.unlock; + end; +end; + +function checkpassword(const password: msestring; var modalresult: modalresultty): boolean; +var + fo: tstringenterfo; +begin + application.lock; + try + fo:= tstringenterfo.create(nil); + try + with fo do begin + caption:= stockobjects.captions[sc_passwordupper]; + lab.caption:= stockobjects.captions[sc_enterpassword]+':'; + value.passwordchar:= '*'; + value.value:= ''; + modalresult:= fo.show(true,nil); + result:= (modalresult = mr_ok) and (password = value.value); + if not result and (modalresult = mr_ok) then begin + showerror(stockobjects.captions[sc_invalidpassword]); + end; + end; + finally + fo.Free; + end; + finally + application.unlock; + end; +end; + +function checkpassword(const password: msestring): boolean; +var + res: modalresultty; +begin + res:= mr_none; + repeat + result:= checkpassword(password,res); + until result or (res <> mr_ok); +end; + +procedure tstringenterfo.layoutexe(const sender: TObject); +begin + optionswidget1:= optionswidget1-[ow1_autoheight]; //only on startup +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msestringenter_mfm.pas b/mseide-msegui/lib/common/dialogs/msestringenter_mfm.pas new file mode 100644 index 0000000..627de83 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msestringenter_mfm.pas @@ -0,0 +1,143 @@ +unit msestringenter_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msestringenter; + +const + objdata: record size: integer; data: array[0..2502] of byte end = + (size: 2503; data: ( + 84,80,70,48,14,116,115,116,114,105,110,103,101,110,116,101,114,102,111,13, + 115,116,114,105,110,103,101,110,116,101,114,102,111,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,14,111,119,49,95,97,117,116,111,104,101,105,103,104,116,0,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111, + 110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,84,1,8,98,111,117,110,100,115,95,121,3,67,1,9,98,111,117,110, + 100,115,95,99,120,3,142,1,9,98,111,117,110,100,115,95,99,121,2,70, + 12,98,111,117,110,100,115,95,99,120,109,105,110,3,200,0,12,98,111,117, + 110,100,115,95,99,121,109,105,110,2,70,23,99,111,110,116,97,105,110,101, + 114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101,110, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 29,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102,114,97, + 109,101,105,95,98,111,116,116,111,109,2,10,26,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 12,102,114,108,95,102,105,98,111,116,116,111,109,0,27,99,111,110,116,97, + 105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,18,99,111,110,116,97,105,110,101,114,46,111,110,108,97,121, + 111,117,116,7,9,108,97,121,111,117,116,101,120,101,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,142,1,2, + 70,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101,101, + 110,99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111,110, + 101,115,99,17,102,111,95,108,111,99,97,108,115,104,111,114,116,99,117,116, + 115,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111, + 95,97,117,116,111,119,114,105,116,101,115,116,97,116,0,13,119,105,110,100, + 111,119,111,112,97,99,105,116,121,5,0,0,0,0,0,0,0,128,255,255, + 8,111,110,108,97,121,111,117,116,7,9,108,97,121,111,117,116,101,120,101, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109, + 115,101,102,111,114,109,0,6,116,108,97,98,101,108,3,108,97,98,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,14,111,119,49,95,97, + 117,116,111,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,7, + 8,98,111,117,110,100,115,95,121,2,12,9,98,111,117,110,100,115,95,99, + 120,3,128,1,9,98,111,117,110,100,115,95,99,121,2,16,7,97,110,99, + 104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112, + 8,97,110,95,114,105,103,104,116,0,7,99,97,112,116,105,111,110,6,3, + 108,97,98,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99, + 101,110,116,101,114,101,100,12,116,102,95,119,111,114,100,98,114,101,97,107, + 0,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117, + 116,101,114,49,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110, + 100,115,95,121,2,36,9,98,111,117,110,100,115,95,99,120,3,127,1,9, + 98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104,111,114,115,11, + 7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11, + 111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105, + 110,107,121,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107, + 120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,121,0, + 13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95, + 112,108,97,99,101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97, + 108,105,103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116, + 13,112,108,97,99,101,95,109,105,110,100,105,115,116,2,8,13,112,108,97, + 99,101,95,109,97,120,100,105,115,116,2,8,13,112,108,97,99,101,95,111, + 112,116,105,111,110,115,11,13,112,108,111,95,101,110,100,109,97,114,103,105, + 110,0,7,108,105,110,107,116,111,112,7,3,108,97,98,8,100,105,115,116, + 95,116,111,112,2,8,0,7,116,98,117,116,116,111,110,6,99,97,110,99, + 101,108,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111, + 119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116, + 111,119,105,100,116,104,19,111,119,49,95,97,117,116,111,115,105,122,101,97, + 110,114,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120, + 3,77,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,12,98, + 111,117,110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97, + 112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,7,116,98,117,116, + 116,111,110,2,111,107,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49, + 95,97,117,116,111,119,105,100,116,104,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,3,19,1,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121, + 2,22,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,5,115,116, + 97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108, + 111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79, + 75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,11,116, + 115,116,114,105,110,103,101,100,105,116,5,118,97,108,117,101,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,11,1,9,98,111, + 117,110,100,115,95,99,121,2,22,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstringenterfo,''); +end. diff --git a/mseide-msegui/lib/common/editwidgets/msecalendardatetimeedit.pas b/mseide-msegui/lib/common/editwidgets/msecalendardatetimeedit.pas new file mode 100644 index 0000000..fb403f6 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msecalendardatetimeedit.pas @@ -0,0 +1,182 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit msecalendardatetimeedit; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +interface +uses + classes,mclasses,msedataedits,msepopupcalendar,msedropdownlist,msetypes, + msegraphutils, + mseguiglob,mseinplaceedit,mseedit,msestrings,msegui,mseevent,msemenus, + mseeditglob,msegraphics; + +type + tcustomcalendardatetimeedit = class(tcustomdatetimeedit,idropdowncalendar) + private + fdropdown: tcalendarcontroller; + procedure setframe(const avalue: tdropdownmultibuttonframe); + function getframe: tdropdownmultibuttonframe; + protected + function getcellframe: framety; override; + //idropdownwidget + procedure buttonaction(var action: buttonactionty; const buttonindex: integer); + procedure dobeforedropdown; + procedure doafterclosedropdown; + procedure createdropdownwidget(const atext: msestring; out awidget: twidget); + function getdropdowntext(const awidget: twidget): msestring; + function getvalueempty: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property dropdown: tcalendarcontroller read fdropdown write fdropdown; + published + property frame: tdropdownmultibuttonframe read getframe write setframe; + end; + + tcalendardatetimeedit = class(tcustomcalendardatetimeedit) + published + property onsetvalue; + property value {stored false}; + property formatedit; + property formatdisp; + property valuemin {stored false}; + property valuemax {stored false}; + property kind; + property options; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + end; + + +implementation +uses + sysutils,mseformatstr,msesys,msedate; + +{ tcustomcalendardatetimeedit } + +constructor tcustomcalendardatetimeedit.create(aowner: tcomponent); +begin + inherited; + fdropdown:= tcalendarcontroller.create(idropdowncalendar(self)); + fcontrollerintf:= idataeditcontroller(fdropdown); +end; + +destructor tcustomcalendardatetimeedit.destroy; +begin + fdropdown.free; + inherited; +end; + +procedure tcustomcalendardatetimeedit.setframe( + const avalue: tdropdownmultibuttonframe); +begin + inherited setframe(avalue); +end; + +function tcustomcalendardatetimeedit.getframe: tdropdownmultibuttonframe; +begin + result:= tdropdownmultibuttonframe(inherited getframe); +end; +{ +procedure tcustomcalendardatetimeedit.internalcreateframe; +begin + fdropdown.createframe; +end; + +procedure tcustomcalendardatetimeedit.dokeydown(var info: keyeventinfoty); +begin + fdropdown.dokeydown(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomcalendardatetimeedit.domousewheelevent( + var info: mousewheeleventinfoty); +begin + fdropdown.domousewheelevent(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomcalendardatetimeedit.mouseevent(var info: mouseeventinfoty); +begin + tcustombuttonframe(fframe).mouseevent(info); + inherited; +end; +} +procedure tcustomcalendardatetimeedit.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + //dummy +end; + +procedure tcustomcalendardatetimeedit.dobeforedropdown; +begin + //dummy +end; + +procedure tcustomcalendardatetimeedit.doafterclosedropdown; +begin + //dummy +end; + +procedure tcustomcalendardatetimeedit.createdropdownwidget( + const atext: msestring; out awidget: twidget); +var + dat1: tdatetime; + mstr1: msestring; + bo1: boolean; +begin + bo1:= true; + mstr1:= atext; + checktext(mstr1,bo1); + if not bo1 then begin + abort; + end; + awidget:= tpopupcalendarfo.create(nil,fdropdown); + dat1:= nowlocal; + if trim(mstr1) <> '' then begin + try + dat1:= stringtodatetime(mstr1,formatedit); + except + end; + end; + with tpopupcalendarfo(awidget) do begin + formatedit:= self.formatedit; + value:= dat1; + end; +end; + +function tcustomcalendardatetimeedit.getdropdowntext( + const awidget: twidget): msestring; +begin + result:= text; +end; + +function tcustomcalendardatetimeedit.getcellframe: framety; +begin + result:= fframe.cellframe; +end; + +function tcustomcalendardatetimeedit.getvalueempty: integer; +begin + result:= -1; //dummy +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msedataedits.pas b/mseide-msegui/lib/common/editwidgets/msedataedits.pas new file mode 100644 index 0000000..e7402bd --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msedataedits.pas @@ -0,0 +1,6755 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedataedits; + +{$ifdef FPC} + {$mode objfpc}{$h+}{$goto on} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegui,mseinplaceedit,mseeditglob,msegraphics,mseedit, + msetypes,msestrings,msedatalist,mseglob,mseguiglob,msedragglob, + mseevent,msegraphutils,msedrawtext,msestat,msestatfile,mseclasses, + msearrayprops,msegrids,msewidgetgrid,msedropdownlist,msedrag,{mseforms,} + mseformatstr,typinfo,msemenus,msebitmap,mseassistiveclient,mserichstring, + msescrollbar,msewidgets,{msepopupcalendar,}msekeyboard,msepointer,msegridsglob + {$ifdef mse_with_ifi} + ,mseificomp,mseifiglob,mseificompglob + {$endif} + ; + +const + emptyinteger = minint; + valuevarname = 'value'; + +type + tcustomdataedit = class; + + checkvalueeventty = procedure(const sender: tcustomdataedit; + const quiet: boolean; var accept: boolean) of object; + + gettexteventty = procedure(const sender: tcustomdataedit; var atext: msestring; + const aedit: boolean) of object; + settexteventty = procedure(const sender: tcustomdataedit; + var atext: msestring; var accept: boolean) of object; + textchangeeventty = procedure(const sender: tcustomdataedit; + const atext: msestring) of object; + + tcustomdataedit = class(tcustomedit,igridwidget,istatfile,idragcontroller, + iassistiveclientgridwidget + {$ifdef mse_with_ifi},iifidatalink{$endif}) + private + fontextchange: textchangeeventty; + fondataentered: notifyeventty; + foncheckvalue: checkvalueeventty; + fnullchecking: integer; + fvaluechecking: integer; + fstatfile: tstatfile; + fstatvarname: msestring; + fongettext: gettexteventty; + fonsettext: settexteventty; + fstatpriority: integer; + + procedure setstatfile(const Value: tstatfile); + function getgridrow: integer; + procedure setgridrow(const avalue: integer); + function getdisptext: msestring; + protected + fgridintf: iwidgetgrid; + fgriddatalink: pointer; + fdatalist: tdatalist; + fcontrollerintf: idataeditcontroller; + fparentintf: igridwidget; +{$ifdef mse_with_ifi} + fifilink: tifivaluelinkcomp; + function getdefaultifilink: iificlient; override; + function getifidatalinkintf: iifidatalink; override; + function getoptionsedit: optionseditty; override; + procedure dochange; override; + //iificlient + function getifidatatype(): listdatatypety override; + //iifidatalink + procedure ifisetvalue(var avalue; var accept: boolean); + procedure getifivalue(var avalue) virtual; + procedure setifivalue(const avalue) virtual; + function getifilinkkind: ptypeinfo; virtual; + procedure setifilink(const avalue: tifilinkcomp); + procedure updateifigriddata(const sender: tobject; + const alist: tdatalist); virtual; + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; +{$endif} +// procedure setisdb; + procedure updatedatalist; virtual; + function geteditstate: dataeditstatesty; + procedure seteditstate(const avalue: dataeditstatesty); +// procedure updateedittext(const force: boolean); + function getgridintf: iwidgetgrid; + procedure checkgrid; + function checkgriddata: tdatalist; overload; + function checkgriddata(var index: integer): tdatalist; overload; + //index -1 -> grid.row, nil if no focused row + procedure internalgetgridvalue(index: integer; var value); + procedure internalsetgridvalue(index: integer; const Value); + procedure internalfillcol(const value); + procedure internalassigncol(const value); + function getinnerframe: framety; override; + procedure valuechanged; virtual; + procedure dotextchange; virtual; + procedure modified; virtual; //for dbedits + function gettext: msestring override; + function getedittext(): msestring override; + procedure checktext(var atext: msestring; var accept: boolean); + procedure texttovalue(var accept: boolean; + const quiet: boolean); virtual; abstract; + procedure texttodata(const atext: msestring; var data); virtual; + //used for clipboard paste in widgetgrid + function datatotext(const data): msestring; + function internaldatatotext(const data): msestring; virtual; abstract; + procedure valuetotext; + procedure setenabled(const avalue: boolean); override; +// procedure updatetextflags; override; + procedure dodefocus; override; + procedure dofocus; override; + procedure formatchanged; override; + procedure loaded; override; + procedure fontchanged; override; + procedure dofontheightdelta(var delta: integer); override; + procedure sizechanged; override; + function geteditfont: tfont; override; + class function classskininfo: skininfoty; override; + + function setdropdowntext(const avalue: msestring; const docheckvalue: boolean; + const canceled: boolean; const akey: keyty): boolean; + procedure initeditfocus; + {$ifdef mse_with_ifi} + procedure setifilink0(const avalue: tifilinkcomp); + {$endif} + + //mirrored to fcontrollerintf + procedure mouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure internalcreateframe; override; + procedure updatereadonlystate; override; + procedure editnotification(var info: editnotificationinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + + //iedit + function locatecount: integer; override; //number of locate values + function locatecurrentindex: integer; override; //index of current row + procedure locatesetcurrentindex(const aindex: integer); override; + function getkeystring(const aindex: integer): msestring; override; //locate text + //igridwidget + procedure setfirstclick(var ainfo: mouseeventinfoty); virtual; + function createdatalist(const sender: twidgetcol): tdatalist; + virtual; abstract; + procedure datalistdestroyed; virtual; + function getdatalistclass: datalistclassty; virtual; abstract; + function getdefaultvalue: pointer; virtual; + function getrowdatapo(const arow: integer): pointer; virtual; + procedure setgridintf(const intf: iwidgetgrid); virtual; + function getcellframe: framety; virtual; + function needscellfocuspaint(): boolean; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; virtual; + procedure updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); virtual; + function getnulltext: msestring; virtual; + function getcelltext(const datapo: pointer; out empty: boolean): msestring; + function getiassistiveclient(): iassistiveclient override; + function getassistivecelltext(const arow: int32): msestring; + //iassistiveclient + function getassistiveflags(): assistiveflagsty override; + function getassistivetext(): msestring; override; + function getassistivecolumncaption(): msestring virtual; + + procedure drawcell(const canvas: tcanvas); virtual; + procedure updateautocellsize(const canvas: tcanvas); virtual; + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure valuetogrid(row: integer); virtual; abstract; + procedure gridtovalue(row: integer); virtual; + procedure setvaluedata(const source); virtual; abstract; + procedure getvaluedata(out dest); virtual; abstract; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); virtual; + function sortfunc(const l,r): integer; virtual; + procedure gridvaluechanged(const index: integer); virtual; + procedure updatecoloptions(const aoptions: coloptionsty); + procedure updatecoloptions1(const aoptions: coloptions1ty); + procedure setoptionsedit(const avalue: optionseditty); override; + procedure setoptionsedit1(const avalue: optionsedit1ty); override; + procedure statdataread; virtual; + procedure griddatasourcechanged; virtual; + {$ifdef mse_with_ifi} + function getifilink: tifilinkcomp; + {$endif} + procedure setparentgridwidget(const intf: igridwidget); + procedure childdataentered(const sender: igridwidget); virtual; + procedure childfocused(const sender: igridwidget); virtual; + + procedure formaterror(const quiet: boolean); + procedure rangeerror(const min,max; const quiet: boolean); + procedure notnullerror(const quiet: boolean); + + procedure doafterpaint(const canvas: tcanvas); override; + function needsfocuspaint: boolean; override; + + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + procedure readstatvalue(const reader: tstatreader); virtual; + procedure readstatstate(const reader: tstatreader); virtual; + procedure readstatoptions(const reader: tstatreader); virtual; + procedure writestatvalue(const writer: tstatwriter); virtual; + procedure writestatstate(const writer: tstatwriter); virtual; + procedure writestatoptions(const writer: tstatwriter); virtual; + + function cangridcopy: boolean; override; + function isempty (const atext: msestring): boolean; virtual; + procedure nullvalueset; + procedure setnullvalue; virtual; //for dbedits + function nullcheckneeded(const newfocus: twidget): boolean; virtual; + function textcellcopy: boolean; virtual; + function getedited: boolean; override; + procedure setedited(const avalue: boolean); virtual; + public + + procedure initnewwidget(const ascale: real); override; + procedure initgridwidget; virtual; + procedure paint(const canvas: tcanvas); override; + procedure synctofontheight; override; + function actualcolor: colorty; override; + function actualcursor(const apos: pointty): cursorshapety; override; + function widgetcol: twidgetcol; + function grid: tcustomwidgetgrid; + property gridrow: integer read getgridrow write setgridrow; + //returns -1 if no grid, setting ignored if no grid + function gridrowhigh: int32; //-1 if no grid + function griddatarowhigh: int32; //-1 if no grid + function gridcol: integer; + function griddata: tdatalist; + property gridintf: iwidgetgrid read fgridintf; + function textclipped(const arow: integer; + out acellrect: rectty): boolean; virtual; + function textclipped(const arow: integer): boolean; + + function checkvalue(const quiet: boolean = false): boolean; virtual; + function canclose(const newfocus: twidget): boolean; override; + property edited: boolean read getedited write setedited; + function emptytext: boolean; + function seteditfocus: boolean; + function isnull: boolean; virtual; + + property disptext: msestring read getdisptext; + property dataeditstate: dataeditstatesty read fstate; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property oncheckvalue: checkvalueeventty read foncheckvalue + write foncheckvalue; + property ondataentered: notifyeventty read fondataentered + write fondataentered; + property ongettext: gettexteventty read fongettext write fongettext; + property onsettext: settexteventty read fonsettext write fonsettext; + property ontextchange: textchangeeventty read fontextchange + write fontextchange; + end; + + dataediteventty = procedure(const sender: tcustomdataedit) of object; + + tdataedit = class(tcustomdataedit) + published + property statfile; + property statvarname; + property statpriority; + property empty_color; + property empty_font; + property empty_fontstyle; + property empty_textflags; + property empty_text; + property empty_options; + property empty_textcolor; + property empty_textcolorbackground; + + property optionsedit1; //before optionsedit! + property optionsedit; + property font; + property textflags; + property textflagsactive; + property caretwidth; + property cursorreadonly; + property onchange; + property ontextchange; + property onkeydown; + property onkeyup; + property onmouseevent; + property onclientmouseevent; + property onmousewheelevent; + property oncopytoclipboard; + property onpastefromclipboard; + + property ontextedited; + property oncheckvalue; + property ondataentered; + property ongettext; + property onsettext; + end; + + tcustomstringedit = class(tdataedit) + private + fonsetvalue: setstringeventty; + procedure setvalue(const Value: msestring); + function getgridvalue(const index: integer): msestring; + procedure setgridvalue(const index: integer; const Value: msestring); + function getgridvalues: msestringarty; + procedure setgridvalues(const Value: msestringarty); + {$ifdef mse_with_ifi} + function getifilink: tifistringlinkcomp; + procedure setifilink(const avalue: tifistringlinkcomp); + {$endif} + protected + fvalue: msestring; + fvaluedefault: msestring; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function getvaluetext: msestring; virtual; + procedure updatedisptext(var avalue: msestring); virtual; + + procedure dosetvalue(var avalue: msestring; var accept: boolean); virtual; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function sortfunc(const l,r): integer; override; + function getdefaultvalue: pointer; override; + + public + function checkvalue(const quiet: boolean = false): boolean; override; + function isnull: boolean; override; + procedure dragevent(var info: draginfoty); override; + procedure fillcol(const value: msestring); + procedure assigncol(const value: tmsestringdatalist); + property onsetvalue: setstringeventty read fonsetvalue write fonsetvalue; + property value: msestring read fvalue write setvalue; + property valuedefault: msestring read fvaluedefault write fvaluedefault; + property gridvalue[const index: integer]: msestring + read getgridvalue write setgridvalue; default; + property gridvalues: msestringarty read getgridvalues write setgridvalues; + function griddata: tgridmsestringdatalist; +{$ifdef mse_with_ifi} + property ifilink: tifistringlinkcomp read getifilink write setifilink; +{$endif} + end; + + tstringedit = class(tcustomstringedit) + published + property passwordchar; + property maxlength; + property value; + property valuedefault; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + +const + defaultmemotextflags = (defaulttextflags - [tf_ycentered]) + [tf_wordbreak]; + defaultmemotextflagsactive = (defaulttextflagsactive - [tf_ycentered]) + + [tf_wordbreak]; + defaultmemooptionsedit = (defaultoptionsedit - + [oe_undoonesc,oe_exitoncursor,oe_shiftreturn, + oe_endonenter,oe_homeonenter, + oe_autoselect,oe_autoselectonfirstclick]) + + [oe_linebreak,oe_nofirstarrownavig]; + defaultmemooptionsedit1 = defaultoptionsedit1 + [oe1_multiline]; + +type + + tcustommemoedit = class(tcustomstringedit,iscrollbar) + private + ftextrectbefore: rectty; + fclientsizebefore: sizety; + fcreated: boolean; + fxpos: integer; + fupdatescrollbarcount: integer; + function getframe: tscrolleditframe; + procedure setframe(const avalue: tscrolleditframe); + procedure updatescrollbars; + protected + procedure setupeditor; override; + procedure editnotification(var info: editnotificationinfoty); override; + procedure internalcreateframe; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + function getnoscroll(): boolean override; + //iscrollbar + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); + public + constructor create(aowner: tcomponent); override; + procedure afterconstruction; override; + property frame: tscrolleditframe read getframe write setframe; + property textflags default defaultmemotextflags; + property textflagsactive default defaultmemotextflagsactive; + published + property optionsedit default defaultmemooptionsedit; + property optionsedit1 default defaultmemooptionsedit1; + property optionswidget default defaultoptionswidgetmousewheel; + end; + + tmemoedit = class(tcustommemoedit) + published + property value; + property valuedefault; + property onsetvalue; + property frame; + property textflags; + property textflagsactive; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + + tcustomrichmemoedit = class(tcustommemoedit,irichstringprop) + private + procedure readrichvalue(reader: treader); + procedure writerichvalue(writer: twriter); + protected + fformat: formatinfoarty; + frichflags: richflagsty; + function getformat: formatinfoarty override; + procedure setformat(const avalue: formatinfoarty); + procedure defineproperties(filer: tfiler) override; + //irichstringprop + function getrichvalue(): richstringty; + procedure setrichvalue(const avalue: richstringty); + public + property value stored false; + property richvalue: richstringty read getrichvalue write setrichvalue; + property formatvalue: formatinfoarty read fformat write setformat; + end; + + trichmemoedit = class(tcustomrichmemoedit) + published + property value; + property valuedefault; + property onsetvalue; + property frame; + property textflags; + property textflagsactive; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + + thexstringedit = class(tdataedit) + private + fonsetvalue: setansistringeventty; + procedure setvalue(const Value: string); + function getgridvalue(const index: integer): ansistring; + procedure setgridvalue(const index: integer; const Value: ansistring); + function getgridvalues: stringarty; + procedure setgridvalues(const Value: stringarty); + protected + fvalue: ansistring; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure dosetvalue(var avalue: ansistring; var accept: boolean); virtual; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function sortfunc(const l,r): integer; override; + public + procedure fillcol(const value: string); + procedure assigncol(const value: tansistringdatalist); + property gridvalue[const index: integer]: ansistring + read getgridvalue write setgridvalue; default; + property gridvalues: stringarty read getgridvalues write setgridvalues; + function griddata: tgridansistringdatalist; + published + property value: ansistring read fvalue write setvalue; + property onsetvalue: setansistringeventty read fonsetvalue write fonsetvalue; + end; + +const + defaultenumdropdownoptions = [deo_selectonly,deo_autodropdown,deo_keydropdown]; + defaultkeystringdropdownoptions = [deo_selectonly,deo_autodropdown,deo_keydropdown]; + +type + + tcustomdropdownedit = class(tcustomstringedit,idropdown + {$ifdef mse_with_ifi},iifidropdownlistdatalink{$endif}) + private + fonbeforedropdown: notifyeventty; + fonafterclosedropdown: notifyeventty; + function getframe: tdropdownmultibuttonframe; + procedure setframe(const avalue: tdropdownmultibuttonframe); + protected + fdropdown: tcustomdropdowncontroller; + function createdropdowncontroller: tcustomdropdowncontroller; virtual; + procedure loaded() override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure dohide; override; + function getassistiveflags(): assistiveflagsty override; +// function getassistivecaption(): msestring override; +// function getassistivetext(): msestring override; + {$ifdef mse_with_ifi} + function getifidatalinkintf: iifidatalink; override; + //iifidropdownlistdatalink + procedure ifidropdownlistchanged(const acols: tifidropdowncols); + {$endif} + //idropdown + procedure buttonaction(var action: buttonactionty; const buttonindex: integer); virtual; + procedure dobeforedropdown; virtual; + procedure doafterclosedropdown; virtual; + function getvalueempty: integer; virtual; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property onbeforedropdown: notifyeventty read fonbeforedropdown write fonbeforedropdown; + property onafterclosedropdown: notifyeventty read fonafterclosedropdown + write fonafterclosedropdown; + published + property frame: tdropdownmultibuttonframe read getframe write setframe; + end; + + tcustomdropdownwidgetedit = class(tcustomdropdownedit,idropdownwidget) + private + function getdropdown: tdropdownwidgetcontroller; + procedure setdropdown(const avalue: tdropdownwidgetcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + //idropdownwidget + procedure createdropdownwidget(const atext: msestring; + out awidget: twidget); virtual; abstract; + function getdropdowntext(const awidget: twidget): msestring; virtual; abstract; + public + property dropdown: tdropdownwidgetcontroller read getdropdown + write setdropdown; + end; + + tdropdownwidgetedit = class(tcustomdropdownwidgetedit) + published + property value; + property valuedefault; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onsetvalue; + property onbeforedropdown; + property onafterclosedropdown; + end; + + tcustomdropdownlistedit = class(tcustomdropdownedit,idropdownlist + {$ifdef mse_with_ifi},iifidropdownlistdatalink{$endif}) + private + procedure setdropdown(const avalue: tdropdownlistcontroller); + function getdropdown: tdropdownlistcontroller; + {$ifdef mse_with_ifi} + function getifilink: tifidropdownlistlinkcomp; + procedure setifilink1(const avalue: tifidropdownlistlinkcomp); + procedure ifidropdownlistchanged(const acols: tifidropdowncols); + {$endif} + protected + //idropdownlist + procedure imagelistchanged; + procedure paintimage(const canvas: tcanvas); override; + procedure dochange; override; + {$ifdef mse_with_ifi} + function getifidatalinkintf: iifidatalink; override; + //iifidatalink + function getifilinkkind: ptypeinfo; override; + {$endif} + //idropdownlist + function getdropdownitems: tdropdowndatacols; virtual; + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure internalsort(const acol: integer; + out sortlist: integerarty); virtual; + function geteditframe: framety; override; + procedure getautopaintsize(var asize: sizety); override; + public + procedure sort(const acol: integer = 0); + property dropdown: tdropdownlistcontroller read getdropdown write setdropdown; +{$ifdef mse_with_ifi} + property ifilink: tifidropdownlistlinkcomp read getifilink write setifilink1; +{$endif} + end; + + tdropdownlistedit = class(tcustomdropdownlistedit) + published + property maxlength; + property value; + property valuedefault; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onbeforedropdown; + property onafterclosedropdown; + end; + +const + defaulthistorymaxcount = 20; + defaulthistoryeditoptions = defaultdropdownoptionsedit + [deo_autosavehistory]; + +type + + thistorycontroller = class(tdropdownlistcontroller) + private + fhistorymaxcount: integer; + procedure sethistorymaxcount(const avalue: integer); + function gethistory: msestringarty; + procedure sethistory(const avalue: msestringarty); + protected + procedure checkmaxcount; + public + constructor create(const intf: idropdownlist); + procedure readstate(const reader: tstatreader); + procedure writestate(const writer: tstatwriter); + procedure savehistoryvalue(const avalue: msestring); + property history: msestringarty read gethistory write sethistory; + published + property dropdownrowcount; //first + property delay; + property historymaxcount: integer read fhistorymaxcount + write sethistorymaxcount default defaulthistorymaxcount; + procedure clearhistory; + property options default defaulthistoryeditoptions; + property width; + property cols; + end; + + tcustomhistoryedit = class(tcustomdropdownlistedit) + private + procedure setdropdown(const avalue: thistorycontroller); + function getdropdown: thistorycontroller; + protected + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure loaded; override; + procedure readstatstate(const reader: tstatreader); override; + procedure writestatstate(const writer: tstatwriter); override; + function createdropdowncontroller: tcustomdropdowncontroller; override; + public + constructor create(aowner: tcomponent); override; + procedure savehistoryvalue; + property dropdown: thistorycontroller read getdropdown write setdropdown; + end; + + thistoryedit = class(tcustomhistoryedit) + published + property maxlength; + property value; + property valuedefault; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onbeforedropdown; + property onafterclosedropdown; + + end; + +const + defaultnumedittextflags = defaulttextflags + [tf_right]; + +type + + tnumedit = class(tdataedit) + public + constructor create(aowner: tcomponent); override; + published + property textflags default defaultnumedittextflags; + end; + + tcustomintegeredit = class(tnumedit) + private + fonsetvalue: setintegereventty; + fvalue: integer; + fbase: numbasety; + fbitcount: integer; + fvaluemin: integer; + fvaluemax: integer; + fvaluedefault: integer; + procedure setvalue(const Value: integer); + procedure setbase(const Value: numbasety); + procedure setbitcount(const Value: integer); + function getgridvalue(const index: integer): integer; + procedure setgridvalue(const index, Value: integer); + function getgridvalues: integerarty; + procedure setgridvalues(const Value: integerarty); + {$ifdef mse_with_ifi} + function getifilink: tifiintegerlinkcomp; + procedure setifilink(const avalue: tifiintegerlinkcomp); + {$endif} + procedure setvaluemin(const avalue: integer); + procedure setvaluemax(const avalue: integer); + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected + fisnull: boolean; //used in tdbintegeredit + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function gettextvalue(var accept: boolean; const quiet: boolean): integer; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure setnullvalue; override; + function getdefaultvalue: pointer; override; + procedure updatedatalist; override; + procedure defineproperties(filer: tfiler) override; + public + constructor create(aowner: tcomponent); override; + procedure fillcol(const value: integer); + procedure assigncol(const value: tintegerdatalist); + property onsetvalue: setintegereventty read fonsetvalue write fonsetvalue; + property value: integer read fvalue write setvalue default 0; + property valuedefault: integer read fvaluedefault + write fvaluedefault default 0; + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + property valuemin: integer read fvaluemin write setvaluemin default 0; + property valuemax: integer read fvaluemax write setvaluemax default maxint; + + property gridvalue[const index: integer]: integer + read getgridvalue write setgridvalue; default; + property gridvalues: integerarty read getgridvalues write setgridvalues; + function griddata: tgridintegerdatalist; +{$ifdef mse_with_ifi} + property ifilink: tifiintegerlinkcomp read getifilink write setifilink; +{$endif} + end; + + tintegeredit = class(tcustomintegeredit) + published + property onsetvalue; + property value; + property valuedefault; + property base; + property bitcount; + property valuemin; + property valuemax; + {$ifdef mse_with_ifi} + property ifilink; + {$endif} + end; + + tcustomint64edit = class(tnumedit) + private + fonsetvalue: setint64eventty; + fvalue: int64; + fbase: numbasety; + fbitcount: integer; + fvaluemin: int64; + fvaluemax: int64; + fvaluedefault: int64; + procedure setvalue(const Value: int64); + procedure setbase(const Value: numbasety); + procedure setbitcount(const Value: integer); + function getgridvalue(const index: integer): int64; + procedure setgridvalue(const index: integer; const Value: int64); + function getgridvalues: int64arty; + procedure setgridvalues(const Value: int64arty); +// procedure setmin(const avalue: int64); +// procedure setmax(const avalue: int64); + {$ifdef mse_with_ifi} + function getifilink: tifiint64linkcomp; + procedure setifilink(const avalue: tifiint64linkcomp); + {$endif} + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected + fisnull: boolean; //used in tdbintegeredit + procedure defineproperties(filer: tfiler) override; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure setnullvalue; override; + function getdefaultvalue: pointer; override; +// procedure updatedatalist; override; + public + constructor create(aowner: tcomponent); override; + procedure fillcol(const value: int64); + procedure assigncol(const value: tint64datalist); + property onsetvalue: setint64eventty read fonsetvalue write fonsetvalue; + property value: int64 read fvalue write setvalue default 0; + property valuedefault: int64 read fvaluedefault write fvaluedefault default 0; + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 64; + property valuemin: int64 read fvaluemin write fvaluemin{setmin} default 0; + property valuemax: int64 read fvaluemax write fvaluemax{setmax}; + // {$ifdef FPC}default maxint64{$endif}; + + property gridvalue[const index: integer]: int64 + read getgridvalue write setgridvalue; default; + property gridvalues: int64arty read getgridvalues write setgridvalues; + function griddata: tgridint64datalist; +{$ifdef mse_with_ifi} + property ifilink: tifiint64linkcomp read getifilink write setifilink; +{$endif} + end; + + tint64edit = class(tcustomint64edit) + published + property onsetvalue; + property value; + property valuedefault; + property base; + property bitcount; + property valuemin; + property valuemax; + {$ifdef mse_with_ifi} + property ifilink; + {$endif} + end; + + tkeystringdropdowncontroller = class(tdropdownlistcontroller) + protected + public + constructor create(const intf: idropdownlist); + function getindex(const akey: msestring): integer; + //todo: non linear search + published + property options default defaultkeystringdropdownoptions; + property valuecol default 1; + end; + + tcustomkeystringedit = class; + keystringediteventty = procedure(const sender: tcustomkeystringedit) of object; + + tcustomkeystringedit = class(tcustomdropdownlistedit) + private +// fvaluedefault: msestring; + foninit: keystringediteventty; + protected + fvalue1: msestring; + procedure setvalue(const avalue: msestring); + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure setnullvalue; override; //for dbedits + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; +// function getdefaultvalue: pointer; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure loaded; override; + public + property value: msestring read fvalue1 write setvalue; +// property valuedefault: msestring read fvaluedefault write fvaluedefault; + property oninit: keystringediteventty read foninit write foninit; + end; + + + tkeystringedit = class(tcustomkeystringedit) + published + property value; + property valuedefault; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onbeforedropdown; + property onafterclosedropdown; + property oninit; + end; + + tnocolsenumdropdowncontroller = class(tnocolsdropdownlistcontroller) + private + procedure readitemindex(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create(const intf: idropdownlist); + published + property options default defaultenumdropdownoptions; + property imagelist; + property imageframe_left; + property imageframe_top; + property imageframe_right; + property imageframe_bottom; +// property valuecol; +// property itemindex; + end; + + tenumdropdowncontroller = class(tnocolsenumdropdowncontroller) + public + constructor create(const intf: idropdownlist); + published + property cols; + property valuecol; //after cols + end; + + tcustomenuedit = class(tcustomdropdownlistedit) + private + fbitcount: integer; + fbase: numbasety; + fvaluemin,fvaluemax: integer; + fvalueoffset: integer; + function getgridvalue(const index: integer): integer; + procedure setgridvalue(const index, aValue: integer); + function getgridvalues: integerarty; + procedure setgridvalues(const avalue: integerarty); + function getindex(avalue: integer): integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + procedure setvalueoffset(avalue: integer); + {$ifdef mse_with_ifi} + function getifilink: tifienumlinkcomp; + procedure setifilink1(const avalue: tifienumlinkcomp); + {$endif} + procedure setvaluemin(const avalue: integer); + procedure setvaluemax(const avalue: integer); + function getdropdown: tenumdropdowncontroller; + procedure setdropdown(const avalue: tenumdropdowncontroller); + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected + fonsetvalue1: setintegereventty; + fvalue1: integer; + fvaluedefault1: integer; + fvalueempty: integer; + procedure setvalue(const avalue: integer); + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure setnullvalue; override; //for dbedits + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + function getdefaultvalue: pointer; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure texttodata(const atext: msestring; var data); override; + function internaldatatotext(const data): msestring; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure internalsort(const acol: integer; + out sortlist: integerarty); override; + function sortfunc(const l,r): integer; override; + + function getvalueempty: integer; override; + function textcellcopy: boolean; override; + procedure updatedatalist; override; + procedure paintimage(const canvas: tcanvas); override; + procedure defineproperties(filer: tfiler) override; + public + enums: integerarty; //nil -> enum = item rowindex + valueoffset + constructor create(aowner: tcomponent); override; + procedure clear; + function enumname(const avalue: integer): msestring; + function addrow(const aitems: array of msestring; + const enum: integer = -1): integer; //returns itemindex + //enum = -1 -> no enum set + procedure fillcol(const avalue: integer); + procedure assigncol(const avalue: tintegerdatalist); + property valueoffset: integer read fvalueoffset write setvalueoffset default 0; + //before value + property value: integer read fvalue1 write setvalue default -1; + property valuedefault: integer read fvaluedefault1 + write fvaluedefault1 default -1; + property valueempty: integer read fvalueempty write fvalueempty default -1; + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + property valuemin: integer read fvaluemin write setvaluemin default -1; + property valuemax: integer read fvaluemax write setvaluemax default maxint; + property gridvalue[const index: integer]: integer + read getgridvalue write setgridvalue; default; + property gridvalues: integerarty read getgridvalues write setgridvalues; + function griddata: tgridenumdatalist; + property dropdown: tenumdropdowncontroller read getdropdown + write setdropdown; + property onsetvalue: setintegereventty read fonsetvalue1 write fonsetvalue1; +{$ifdef mse_with_ifi} + property ifilink: tifienumlinkcomp read getifilink write setifilink1; +{$endif} + end; + + tcustomenumedit = class; + enumediteventty = procedure (const sender: tcustomenumedit) of object; + + tcustomenumedit = class(tcustomenuedit) + private + foninit: enumediteventty; + protected + procedure loaded; override; + public + property oninit: enumediteventty read foninit write foninit; + end; + + tenumedit = class(tcustomenumedit) + published + property dropdown; //first + property valueoffset; //before value + property value; + property valuedefault; + property valueempty; + property base; + property bitcount; + property valuemin; + property valuemax; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property onbeforedropdown; + property onafterclosedropdown; + property oninit; + end; + + tenumtypeedit = class; + enumtypeediteventty = procedure (const sender: tenumtypeedit) of object; + + tenumtypeedit = class(tcustomenumedit) + private + ftypeinfopo: ptypeinfo; + procedure settypeinfopo(const avalue: ptypeinfo); + procedure setoninit(const aValue: enumtypeediteventty); + function getoninit: enumtypeediteventty; + protected + public + property typeinfopo: ptypeinfo read ftypeinfopo write settypeinfopo; + published + property value; + property valuedefault; + property base; + property bitcount; + property valuemin; + property valuemax; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onbeforedropdown; + property onafterclosedropdown; + property oninit: enumtypeediteventty read getoninit write setoninit; + end; + + tcustomselector = class(tcustomenuedit) + private + fdropdownitems: tdropdowndatacols; + fdropdownenums: integerarty; + protected + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure dobeforedropdown; override; + procedure getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); virtual; abstract; + function getdropdownitems: tdropdowndatacols; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + end; + + tselector = class; + selectoreventty = procedure (const sender: tselector) of object; + + tselector = class(tcustomselector) + private + fongetdropdowninfo: selectoreventty; + foninit: selectoreventty; + procedure setdropdownitems(const avalue: tdropdowndatacols); + protected + procedure getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); override; + procedure loaded; override; + public + published + property dropdownitems: tdropdowndatacols read getdropdownitems + write setdropdownitems; + property ongetdropdowninfo: selectoreventty read fongetdropdowninfo + write fongetdropdowninfo; + property oninit: selectoreventty read foninit write foninit; + property valueoffset; //before value + property value; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onbeforedropdown; + property onafterclosedropdown; + end; + + gettypeeventty = procedure(const sender: tobject; var atype: ptypeinfo) of object; + + tcustomrealedit = class(tnumedit) + private + fonsetvalue: setrealeventty; + fonsetintvalue: setintegereventty; + fformatdisp: msestring; + fformatedit: msestring; + fvaluerange: real; + fvaluestart: real; + procedure setvalue(const Value: realty); + procedure setformatdisp(const Value: msestring); + procedure setformatedit(const Value: msestring); + procedure readvalue(reader: treader); + procedure readvaluedefault(reader: treader); + procedure readmin1(reader: treader); + procedure readmax1(reader: treader); + function getgridvalue(const index: integer): realty; + function getgridintvalue(const index: integer): integer; + procedure setgridvalue(const index: integer; const avalue: realty); + procedure setgridintvalue(const index: integer; const avalue: integer); + function getgridvalues: realarty; + function getgridintvalues: integerarty; + procedure setgridvalues(const avalue: realarty); + procedure setgridintvalues(const avalue: integerarty); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + function getasinteger: integer; + procedure setasinteger(const avalue: integer); + function getascurrency: currency; + procedure setascurrency(const avalue: currency); + procedure readvaluescale(reader: treader); + {$ifdef mse_with_ifi} + function getifilink: tifireallinkcomp; + procedure setifilink(const avalue: tifireallinkcomp); + {$endif} + function getasstring: msestring; + procedure setasstring(const avalue: msestring); + function getintvalue: integer; + procedure setintvalue(const avalue: integer); + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected + fvalue: realty; + fvaluedefault: realty; + fvaluemin: realty; + fvaluemax: realty; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure updatedatalist; override; + procedure setvaluemin(const avalue: realty); virtual; + procedure setvaluemax(const avalue: realty); virtual; + function gettextvalue(var accept: boolean; + const quiet: boolean): realty; virtual; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure defineproperties(filer: tfiler); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function getdefaultvalue: pointer; override; + procedure setnullvalue(); override; + procedure updatereadonlystate(); override; + public + constructor create(aowner: tcomponent); override; +// function griddata: trealdatalist; + procedure fillcol(const value: realty); + procedure assigncol(const value: trealdatalist); + function isnull: boolean; override; + property asstring: msestring read getasstring write setasstring; + property asinteger: integer read getasinteger write setasinteger; + //returns minint for empty value + property ascurrency: currency read getascurrency write setascurrency; + property onsetvalue: setrealeventty read fonsetvalue write fonsetvalue; + property onsetintvalue: setintegereventty read fonsetintvalue + write fonsetintvalue; + //overrides onsetvalue + property value: realty read fvalue write setvalue {stored false}; + property intvalue: integer read getintvalue write setintvalue; + property valuedefault: realty read fvaluedefault + write fvaluedefault {stored false}; + property formatedit: msestring read fformatedit write setformatedit; + property formatdisp: msestring read fformatdisp write setformatdisp; + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property valuemin: realty read fvaluemin write setvaluemin; + property valuemax: realty read fvaluemax write setvaluemax; + property gridvalue[const index: integer]: realty + read getgridvalue write setgridvalue; default; + property gridintvalue[const index: integer]: integer + read getgridintvalue write setgridintvalue; + property gridvalues: realarty read getgridvalues write setgridvalues; + property gridintvalues: integerarty read getgridintvalues + write setgridintvalues; + function griddata: tgridrealdatalist; +{$ifdef mse_with_ifi} + property ifilink: tifireallinkcomp read getifilink write setifilink; +{$endif} + published + property optionswidget default defaulteditwidgetoptions + [ow_mousewheel]; //first! + end; + + trealedit = class(tcustomrealedit) + published + property onsetvalue; + property onsetintvalue; + property value; + property valuedefault; + property formatedit; + property formatdisp; + property valuerange; + property valuestart; + property valuemin; + property valuemax; + {$ifdef mse_with_ifi} + property ifilink; + {$endif} + end; + +const + spinstepbuttons = [sk_up,sk_down,sk_first,sk_last]; + +type + tspineditframe = class(tcustomstepframe) + private + procedure setbuttonsvisible(const avalue: stepkindsty); + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: icaptionframe; const stepintf: istepbar); + property buttonsinvisible default []; + published + property options; + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient {default cl_foreground}; + property colorbutton; + property colorglyph; + property framei_left default -1; + property framei_top default -1; + property framei_right default -1; + property framei_bottom default -1; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property caption; + property captionpos; + property font; + property localprops; //before template + property localprops1; //before template + property template; + property buttonface; + property buttonframe; + property buttonsvisible read fforcevisiblebuttons write setbuttonsvisible + default [sk_up,sk_down]; + property buttonsize; + property buttonpos; + property buttonslast; + property buttonsinline; + end; + + tcustomrealspinedit = class(tcustomrealedit,istepbar) + private + fstep: real; + fstepflag: stepkindty; +// fstepfact: integer; + fstepfact: real; + fstepctrlfact: real; + fstepshiftfact: real; + fwheelsensitivity: real; + function getframe: tspineditframe; + procedure setframe(const avalue: tspineditframe); + protected + function gettextvalue(var accept: boolean; + const quiet: boolean): realty; override; + procedure internalcreateframe; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure updatebuttonstate(); + procedure updatereadonlystate; override; + procedure enabledchanged(); override; + //istepbar + function dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; + public + constructor create(aowner: tcomponent); override; + property step: real read fstep write fstep; //default 1 + property stepctrlfact: real read fstepctrlfact write fstepctrlfact; + //default = 0 -> no ctrl step + property stepshiftfact: real read fstepshiftfact write fstepshiftfact; + //default = 0 -> no shift step + property wheelsensitivity: real read fwheelsensitivity + write fwheelsensitivity; + published + property frame: tspineditframe read getframe write setframe; + end; + + trealspinedit = class(tcustomrealspinedit) + published + property onsetvalue; + property onsetintvalue; + property value; + property valuedefault; + property formatedit; + property formatdisp; + property valuerange; + property valuestart; + property valuemin; + property valuemax; + property step; + property stepctrlfact; + property stepshiftfact; + property wheelsensitivity; + end; + + datetimeeditoptionty = (dteo_showlocal,dteo_showutc); + datetimeeditoptionsty = set of datetimeeditoptionty; + + tcustomdatetimeedit = class(tnumedit) + private + fonsetvalue: setdatetimeeventty; + fvalue: tdatetime; + fvaluedefault: tdatetime; + fformatdisp: msestring; + fformatedit: msestring; + fvaluemin: tdatetime; + fvaluemax: tdatetime; + fkind: datetimekindty; + foptions: datetimeeditoptionsty; + fconvert: dateconvertty; + procedure setvalue(const Value: tdatetime); + procedure setformatdisp(const Value: msestring); + procedure setformatedit(const Value: msestring); + function getgridvalue(const index: integer): tdatetime; + procedure setgridvalue(const index: integer; const Value: tdatetime); + function getgridvalues: datetimearty; + procedure setgridvalues(const Value: datetimearty); + function checkkind(const avalue: tdatetime): tdatetime; + procedure setkind(const avalue: datetimekindty); + procedure readvalue(reader: treader); + procedure readvaluedefault(reader: treader); + procedure readmin1(reader: treader); + procedure readmax1(reader: treader); + {$ifdef mse_with_ifi} + function getifilink: tifidatetimelinkcomp; + procedure setifilink(const avalue: tifidatetimelinkcomp); + {$endif} + procedure setoptions(const avalue: datetimeeditoptionsty); + procedure setvaluemin(const avalue: tdatetime); + procedure setvaluemax(const avalue: tdatetime); + function getshowlocal: boolean; + procedure setshowlocal(const avalue: boolean); + function getshowutc: boolean; + procedure setshowutc(const avalue: boolean); + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function gettextvalue(var accept: boolean; const quiet: boolean): tdatetime; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure defineproperties(filer: tfiler); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function isempty (const atext: msestring): boolean; override; + function getdefaultvalue: pointer; override; + procedure setnullvalue(); override; + procedure updatedatalist; override; + procedure updatereadonlystate(); override; + //iassistiveclient + function getassistiveflags: assistiveflagsty; override; + public + constructor create(aowner: tcomponent); override; + procedure fillcol(const value: tdatetime); + procedure assigncol(const value: trealdatalist); + function isnull: boolean; override; + property onsetvalue: setdatetimeeventty read fonsetvalue write fonsetvalue; + property value: tdatetime read fvalue write setvalue {stored false}; + property valuedefault: tdatetime read fvaluedefault + write fvaluedefault {stored false}; + property formatedit: msestring read fformatedit write setformatedit; + property formatdisp: msestring read fformatdisp write setformatdisp; + property valuemin: tdatetime read fvaluemin write setvaluemin; + property valuemax: tdatetime read fvaluemax write setvaluemax; + property kind: datetimekindty read fkind write setkind default dtk_date; + property options: datetimeeditoptionsty read foptions write setoptions + default []; + property showlocal: boolean read getshowlocal write setshowlocal; + property showutc: boolean read getshowutc write setshowutc; + property gridvalue[const index: integer]: tdatetime + read getgridvalue write setgridvalue; default; + property gridvalues: datetimearty read getgridvalues write setgridvalues; + function griddata: tgridrealdatalist; +{$ifdef mse_with_ifi} + property ifilink: tifidatetimelinkcomp read getifilink write setifilink; +{$endif} + end; + + tdatetimeedit = class(tcustomdatetimeedit) + published + property onsetvalue; + property value {stored false}; + property valuedefault {stored false}; + property formatedit; + property formatdisp; + property valuemin {stored false}; + property valuemax {stored false}; + property kind; + property options; + {$ifdef mse_with_ifi} + property ifilink; + {$endif} + end; + +function realtytoint(const avalue: realty): integer; +function inttorealty(const avalue: integer): realty; + +implementation +uses + sysutils,msereal,msebits,msestreaming,msestockobjects,msefloattostr, + mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdatalist1 = class(tdatalist); + twidget1 = class(twidget); + tcustombuttonframe1 = class(tcustombuttonframe); + twidgetcol1 = class(twidgetcol); + tdropdowncols1 = class(tdropdowncols); + tcustomframe1 = class(tcustomframe); + tcustomgrid1 = class(tcustomgrid); + tcustomwidgetgrid1 = class(tcustomwidgetgrid); + tdropdowncontroller1 = class(tdropdowncontroller); + tcustomdropdownlistcontroller1 = class(tcustomdropdownlistcontroller); + tcustomdropdowncontroller1 = class(tcustomdropdowncontroller); + tinplaceedit1 = class(tinplaceedit); +// tdatacol1 = class(tdatacol); + +function realtytoint(const avalue: realty): integer; +begin + if avalue = emptyreal then begin + result:= emptyinteger; + end + else begin + result:= round(avalue); + end; +end; + +function inttorealty(const avalue: integer): realty; +begin + if avalue = emptyinteger then begin + result:= emptyreal; + end + else begin + result:= avalue; + end; +end; + + { teditemptyfont } +{ +class function teditemptyfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomdataedit(owner).fempty_font; +end; +} +{ tcustomdataedit } +{ +constructor tcustomdataedit.create(aowner: tcomponent); +begin + include(fstate,des_isdataedit); + inherited; +end; +} +{ +destructor tcustomdataedit.destroy; +begin + inherited; + fempty_font.free; +end; +} +function tcustomdataedit.checkvalue(const quiet: boolean = false): boolean; +begin + result:= true; + if not ((oe_checkmrcancel in foptionsedit) and + (window.modalresult = mr_cancel)) and (fvaluechecking = 0) then begin + inc(fvaluechecking); + try + if canevent(tmethod(foncheckvalue)) then begin + foncheckvalue(self,quiet,result); + end; + if result then begin + if (oe_notnull in optionsedit) and isempty(text) and + nullcheckneeded(nil) then begin + result:= false; + try + if fgridintf = nil then begin + show; + setfocus; + end; + finally + notnullerror(quiet); + end; + exit; + end; + texttovalue(result,quiet); + if result then begin + exclude(fstate,des_edited); + if fparentintf <> nil then begin + fparentintf.childdataentered(igridwidget(self)); + end; + if not quiet and canevent(tmethod(fondataentered)) then begin + fondataentered(self); + end; + {$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.dataentered(getifidatalinkintf,gridrow); + end; + {$endif} + if (oe1_sendchangeeventbycheckvalue in optionsedit1) then begin + sendchangeevent(); + end; + if focused then begin + initfocus; + end; + if canassistive() and not quiet and + not (des_statreading in fstate) then begin + assistiveserver.dodataentered( + iassistiveclientdata(getiassistiveclient())); + end; + end; + end; + finally + dec(fvaluechecking); + end; + end; +end; + +function tcustomdataedit.canclose(const newfocus: twidget): boolean; +var + widget1: twidget; +begin + result:= true; + if not (csdesigning in componentstate) and + (oe_closequery in foptionsedit) and isenabled then begin + if (oe_notnull in optionsedit) and (fnullchecking = 0) and + nullcheckneeded(newfocus) and isempty(text) and + (not(ow1_nocancloseifhidden in foptionswidget1) or + showing) then begin + widget1:= window.focusedwidget; + result:= checkvalue; + if not result and (widget1 = window.focusedwidget) then begin + inc(fnullchecking); + try + if fgridintf <> nil then begin + with fgridintf.getcol do begin + {$warnings off} + tcustomgrid1(grid).beginnullchecking; + {$warnings on} + try + grid.col:= index; + grid.show; + if not focused then begin + {$warnings off} + tcustomgrid1(grid).beginnonullcheck; + {$warnings on} + try + grid.setfocus; + finally + {$warnings off} + tcustomgrid1(grid).endnonullcheck; + {$warnings on} + end; + end; + finally + {$warnings off} + tcustomgrid1(grid).endnullchecking; + {$warnings on} + end; + end; + end; + finally + dec(fnullchecking); + end; + end; + end + else begin + if focused and (des_edited in fstate) and + ((fgridintf = nil) or not fgridintf.nocheckvalue) then begin + result:= checkvalue; + end; + end; + end; + if result then begin + result:= inherited canclose(newfocus); + end; +end; + +procedure tcustomdataedit.valuetotext; +begin + updateedittext(false); + feditor.initfocus; + exclude(fstate,des_edited); +end; + +procedure tcustomdataedit.gridtovalue(row: integer); +begin + valuetotext; +end; + +procedure tcustomdataedit.dofocus; +begin + if fparentintf <> nil then begin + fparentintf.childfocused(igridwidget(self)); + end; + valuetotext(); + inherited; +end; + +procedure tcustomdataedit.synctofontheight; +begin + inherited; + if (fgridintf <> nil) and not (tf_rotate90 in textflags) then begin + fgridintf.getcol.grid.datarowheight:= bounds_cy; + end; +end; + +function tcustomdataedit.actualcolor: colorty; +begin + if (fgridintf <> nil) and (fcolor = cl_default) and + not (csdestroying in componentstate) then begin + result:= fgridintf.getcol.rowcolor(fgridintf.getrow); + if result = cl_transparent then begin + result:= fgridintf.getcol.actualcolor; + if result = cl_transparent then begin + result:= inherited actualcolor; + end; + end; + end + else begin + result:= inherited actualcolor; + end; +end; + +function tcustomdataedit.getedited: boolean; +begin + result:= des_edited in fstate; +end; + +procedure tcustomdataedit.setedited(const avalue: boolean); +begin + if avalue then begin + include(fstate,des_edited); + end + else begin + exclude(fstate,des_edited); + end; +end; + +function tcustomdataedit.geteditstate: dataeditstatesty; +begin + result:= fstate; +end; + +procedure tcustomdataedit.seteditstate(const avalue: dataeditstatesty); +begin + fstate:= avalue; +end; +{ +procedure tcustomdataedit.setisdb; +begin + include(fstate,des_isdb); +end; +} +function tcustomdataedit.emptytext: boolean; +begin + result:= des_emptytext in fstate; +end; +{ +procedure tcustomdataedit.updatetextflags; +var + aflags: textflagsty; +begin + if not (csloading in componentstate) then begin + if (des_emptytext in fstate) and (fempty_text <> '') then begin + aflags:= fempty_textflags; + end + else begin + aflags:= textflags; + end; + if isenabled or (oe_nogray in foptionsedit) then begin + exclude(fstate,des_grayed); + feditor.textflags:= aflags; + feditor.textflagsactive:= textflagsactive; + end + else begin + include(fstate,des_grayed); + feditor.textflags:= aflags + [tf_grayed]; + feditor.textflagsactive:= textflagsactive + [tf_grayed]; + end; + end; +end; +} + +function tcustomdataedit.gettext: msestring; +begin + result:= inherited gettext(); + if des_emptytext in fstate then begin + result:= ''; + end; +end; + +function tcustomdataedit.getedittext(): msestring; +begin + result:= datatotext(nil^); +end; + +function tcustomdataedit.getdisptext: msestring; +var + mstr1: msestring; +begin + {$ifdef FPC} {$checkpointer off} {$endif} + mstr1:= datatotext(nil^); + {$ifdef FPC} {$checkpointer default} {$endif} + if (not(des_isdb in fstate) and (mstr1 = '') or + (des_dbnull in fstate)) then begin + mstr1:= empty_text; + end; + result:= mstr1; +end; + +procedure tcustomdataedit.dodefocus; +begin + updateedittext(false); + exclude(fstate,des_edited); + inherited; +end; + +function tcustomdataedit.cangridcopy: boolean; +begin + result:= (fgridintf <> nil) and fgridintf.cangridcopy; +end; + +procedure tcustomdataedit.initgridwidget; +begin + defaultinitgridwidget(self,fgridintf); +end; + +function tcustomdataedit.getinnerframe: framety; +begin + if fgridintf <> nil then begin + result:= fgridintf.getcol.innerframe; + end + else begin + result:= inherited getinnerframe; + end; +end; + +procedure tcustomdataedit.formatchanged(); +begin + if not (csloading in componentstate) then begin + if fgridintf <> nil then begin + fgridintf.changed; + end; + if not (des_edited in fstate) then begin + updateedittext(false); //do not touch pending modifications + end; + inherited; + end; +end; + +procedure tcustomdataedit.formaterror(const quiet: boolean); +begin + if not quiet then begin + showmessage(''''+text+''' '+stockobjects.captions[sc_is_invalid]+'.', + stockobjects.captions[sc_Format_error]); + end; +end; + +procedure tcustomdataedit.notnullerror(const quiet: boolean); +begin + if not quiet then begin + showmessage(stockobjects.captions[sc_Value_is_required]+'.', + stockobjects.captions[sc_Error]); + end; +end; + +procedure tcustomdataedit.rangeerror(const min, max; const quiet: boolean); +begin + if not quiet then begin + showmessage(stockobjects.captions[sc_min]+': '+datatotext(min)+' '+ + stockobjects.captions[sc_Max]+': ' + + datatotext(max) + '.',stockobjects.captions[sc_Range_error]); + end; +end; + +procedure tcustomdataedit.loaded; +begin + inherited; + include(fwidgetstate,ws_loadedproc); + try + valuechanged; + formatchanged; + finally + exclude(fwidgetstate,ws_loadedproc); + end; +end; + +procedure tcustomdataedit.fontchanged; +begin + inherited; + if fgridintf <> nil then begin + fgridintf.getcol.changed; + end; +end; + +procedure tcustomdataedit.dofontheightdelta(var delta: integer); +begin + inherited; + gridwidgetfontheightdelta(self,fgridintf,delta); +end; + +function tcustomdataedit.geteditfont: tfont; +begin + if {(fempty_font <> nil) and} (des_emptytext in fstate) then begin + result:= getfontempty1{fempty_font}; + end + else begin + if (fgridintf <> nil) and (ffont = nil) then begin + with fgridintf.getcol do begin + result:= rowfont(grid.row); + end; + end + else begin + result:= inherited geteditfont; + end; + end; +end; + +class function tcustomdataedit.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_dataedit; +end; + +function tcustomdataedit.setdropdowntext(const avalue: msestring; + const docheckvalue: boolean; const canceled: boolean; + const akey: keyty): boolean; +var + bo1: boolean; +begin + result:= true; + if canceled then begin + feditor.undo; + end + else begin + text:= avalue; //setcurrenttext(avalue); + if docheckvalue then begin + result:= checkvalue(); + if not result then begin + feditor.undo; + end + else begin + if akey = key_tab then begin + window.postkeyevent(akey,[],false); + end; + end; + end + else begin + if not canceled then begin + bo1:= true; + texttovalue(bo1,true); + end; + end; + end; +end; + +procedure tcustomdataedit.setgridintf(const intf: iwidgetgrid); +begin + fgridintf:= intf; + if fgridintf <> nil then begin +{$ifdef mse_with_ifi} +{ + if (fifilink <> nil) and (fifilink.controller.datalist <> nil) then begin + updateifigriddata(fifilink.controller.datalist); + end; +} +{$endif} + fdatalist:= fgridintf.getcol.datalist; + if fdatalist <> nil then begin + updatedatalist; + end; + fgriddatalink:= tcustomwidgetgrid1(fgridintf.getgrid).getgriddatalink; + fgridintf.updateeditoptions(foptionsedit,feditor.optionsedit1); + if (ow1_autoscale in foptionswidget1) and + (foptionswidget1 * [ow1_fontglyphheight,ow1_fontlineheight] <> []) then begin + fgridintf.getcol.grid.datarowheight:= bounds_cy; + end; + end + else begin + fdatalist:= nil; + fgriddatalink:= nil; + end; +end; + +function tcustomdataedit.getcellframe: framety; +begin + if fframe <> nil then begin + result:= frame.cellframe; + end + else begin + if fgridintf <> nil then begin + result:= tgridarrayprop(fgridintf.getcol.prop).innerframe; + end + else begin + result:= getinnerframe; + end; + end; +end; + +function tcustomdataedit.needscellfocuspaint(): boolean; +begin + result:= inherited needsfocuspaint(); +end; + +procedure tcustomdataedit.updatecoloptions(const aoptions: coloptionsty); +var + opt1: optionseditty; + opt2: optionsedit1ty; +begin + opt1:= foptionsedit; + opt2:= optionsedit1; + fgridintf.coloptionstoeditoptions(opt1,opt2); + optionsedit:= opt1; + optionsedit1:= opt2; +end; + +procedure tcustomdataedit.setoptionsedit(const avalue: optionseditty); +begin + if foptionsedit <> avalue then begin + inherited; + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,feditor.optionsedit1); + end; + end; +end; + +procedure tcustomdataedit.setoptionsedit1(const avalue: optionsedit1ty); +begin + inherited; + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,feditor.optionsedit1); + end; +end; + +procedure tcustomdataedit.updatecoloptions1(const aoptions: coloptions1ty); +begin + //dummy +end; + +procedure tcustomdataedit.statdataread; +begin + //dummy +end; + +procedure tcustomdataedit.griddatasourcechanged; +begin + //dummy +end; + +procedure tcustomdataedit.modified; +begin + if fgridintf <> nil then begin + fgridintf.edited(); + end; +end; + +procedure tcustomdataedit.valuechanged; +begin + if not (csloading in componentstate) then begin + if not (ws_loadedproc in fwidgetstate) then begin + exclude(fstate,des_dbnull); + end; + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + valuetogrid(fgridintf.getrow); + end; + updateedittext(false); + if focused then begin + feditor.initfocus; + end + else begin + feditor.sellength:= 0; + feditor.curindex:= bigint; + end; + if not (ws_loadedproc in fwidgetstate) then begin + modified; + end; + dochange; + end; +end; + +procedure tcustomdataedit.dotextchange; +begin + if canevent(tmethod(fontextchange)) then begin + fontextchange(self,text); + end; +end; + +procedure tcustomdataedit.checktext(var atext: msestring; var accept: boolean); +begin + if canevent(tmethod(fonsettext)) then begin + fonsettext(self,atext,accept); + end; +end; + +procedure tcustomdataedit.texttodata(const atext: msestring; var data); +begin + //dummy +end; + +procedure tcustomdataedit.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tcustomdataedit.dostatwrite(const writer: tstatwriter); +begin + if not (des_isdb in fstate) and (fgridintf = nil) and + canstatvalue(optionsedit1,writer) then begin + writestatvalue(writer); + end; + if canstatstate(optionsedit1,writer) then begin + writestatstate(writer); + end; + if canstatoptions(optionsedit1,writer) then begin + writestatoptions(writer); + end; +end; + +procedure tcustomdataedit.dostatread(const reader: tstatreader); +begin + exclude(fstate,des_valueread); + if not (des_isdb in fstate) and (fgridintf = nil) + and canstatvalue(optionsedit1,reader) then begin + readstatvalue(reader); + include(fstate,des_valueread); + end; + if canstatstate(optionsedit1,reader) then begin + readstatstate(reader); + end; + if canstatoptions(optionsedit1,reader) then begin + readstatoptions(reader); + end; +end; + +procedure tcustomdataedit.statreading; +begin + //dummy +end; + +procedure tcustomdataedit.statread; +var + bo1: boolean; +begin + if (oe1_checkvalueafterstatread in optionsedit1) and + (des_valueread in fstate) then begin + bo1:= des_statreading in fstate; + include(fstate,des_statreading); + try +// checkvalue(true); + checkvalue(); + finally + if not bo1 then begin + exclude(fstate,des_statreading); + end; + end; + end; +end; + +function tcustomdataedit.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomdataedit.readstatoptions(const reader: tstatreader); +begin + //dummy +end; + +procedure tcustomdataedit.readstatstate(const reader: tstatreader); +begin + //dummy +end; + +procedure tcustomdataedit.readstatvalue(const reader: tstatreader); +begin + //dummy +end; + +procedure tcustomdataedit.writestatoptions(const writer: tstatwriter); +begin + //dummy +end; + +procedure tcustomdataedit.writestatstate(const writer: tstatwriter); +begin + //dummy +end; + +procedure tcustomdataedit.writestatvalue(const writer: tstatwriter); +begin + //dummy +end; + +procedure tcustomdataedit.nullvalueset(); +begin + include(fstate,des_dbnull); + updateedittext(true); //change to textempty +end; + +procedure tcustomdataedit.setnullvalue(); //for dbedits +var + bo1: boolean; +begin + text:= getnulltext; + bo1:= true; + texttovalue(bo1,true); //setvalue call + nullvalueset(); +end; + +procedure tcustomdataedit.setfirstclick(var ainfo: mouseeventinfoty); +begin + feditor.setfirstclick(ainfo); +end; + +function tcustomdataedit.getdefaultvalue: pointer; +begin + result:= nil; +end; + +function tcustomdataedit.getrowdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +function tcustomdataedit.getnulltext: msestring; +begin + result:= ''; +end; + +function tcustomdataedit.getcelltext(const datapo: pointer; + out empty: boolean): msestring; +var + mstr1: msestring; + //avoid refcount 0 because of const param in internaldatatotext() +begin + empty:= false; + if datapo <> nil then begin + mstr1:= internaldatatotext(datapo^); + if passwordchar <> #0 then begin + mstr1:= charstring(passwordchar,length(mstr1)); + end; + if not (des_isdb in fstate) and (mstr1 = '') and + (empty_text <> '') then begin + empty:= true; + mstr1:= empty_text; + end; + end + else begin + empty:= true; + mstr1:= empty_text; + end; + if canevent(tmethod(fongettext)) then begin + fongettext(self,mstr1,false); + end; + result:= mstr1; +end; + +function tcustomdataedit.getiassistiveclient(): iassistiveclient; +begin + result:= iassistiveclientgridwidget(self); +end; + +function tcustomdataedit.getassistivecelltext(const arow: int32): msestring; +var + bo1: boolean; +begin + if fdatalist <> nil then begin + result:= getcelltext(fdatalist.getitempo(arow),bo1); + end + else begin + result:= ''; + end; +end; + +function tcustomdataedit.getassistivetext(): msestring; +begin + result:= feditor.text; +end; + +function tcustomdataedit.getassistivecolumncaption(): msestring; +begin + result:= ''; + if fgridintf <> nil then begin + result:= fgridintf.getcol.defaultcaption(); + end; +end; + +function tcustomdataedit.getassistiveflags: assistiveflagsty; +begin + result:= inherited getassistiveflags; + if fgridintf <> nil then begin + result:= result + [{asf_gridcell,}asf_gridwidget]; + if gs1_scrolllimit in tcustomwidgetgrid1(fgridintf.getgrid).fstate1 then begin + include(result,asf_scrolllimit); + end; + end; + if des_isdb in fstate then begin + include(result,asf_db); + end; +end; + +procedure tcustomdataedit.drawcell(const canvas: tcanvas); +var + mstr1: msestring; + atextflags: textflagsty; + bo1: boolean; + int1: integer; + rect1: rectty; + fra1: framety; + + procedure cellpaint(const rect: rectty; const innerrect: rectty); + begin + if (rect.cx > 0) and (rect.cy > 0) then begin + if bo1 and (empty_color <> cl_none) and + not (des_grayed in fstate) then begin + canvas.fillrect(rect,empty_color); + end; + paintimage(canvas); + if mstr1 <> '' then begin + if bo1 then begin + canvas.font:= getfontempty1{fempty_font}; + atextflags:= empty_textflags; + if empty_textcolor <> cl_none then begin + canvas.font.color:= empty_textcolor; + end; + if empty_textcolorbackground <> cl_none then begin + canvas.font.color:= empty_textcolorbackground; + end; + end; + if des_grayed in fstate then begin + include(atextflags,tf_grayed); + end; + drawtext(canvas,mstr1,deflaterect(innerrect,fra1),deflaterect(rect,fra1), + atextflags); + end; + end; + end; //cellpaint + +var + outer1,inner1: rectty; + pt1: pointty; + +begin + atextflags:= textflags; + with cellinfoty(canvas.drawinfopo^) do begin + mstr1:= getcelltext(datapo,bo1); + if bo1 then begin + if empty_fontstyle <> [] then begin + canvas.font.style:= empty_fontstyle; + end; + end; + fra1:= geteditframe; + if calcautocellsize then begin + rect1:= textrect(canvas,mstr1,deflaterect(innerrect,fra1),atextflags); + int1:= rect1.cx - innerrect.cx + rect.cx; + if int1 > autocellsize.cx then begin + autocellsize.cx:= int1; + end; + int1:= rect1.cy - innerrect.cy + rect.cy; + if int1 > autocellsize.cy then begin + autocellsize.cy:= int1; + end; + end + else begin + if (fgridintf = nil) and (fparentintf <> nil) and + (oe1_nocellpaint in optionsedit1) then begin + if (fwidgetrect.cx > 0) and (fwidgetrect.cy > 0) then begin + paintbackground(canvas,fwidgetrect); + gettextrects(outer1,inner1); + pt1:= paintparentpos; + addpoint1(outer1.pos,pt1); + addpoint1(inner1.pos,pt1); + cellpaint(outer1,inner1); + paintoverlay(canvas,fwidgetrect); + end; + end + else begin + cellpaint(rect,innerrect); + end; + end; + end; +end; + +procedure tcustomdataedit.updateautocellsize(const canvas: tcanvas); +begin + drawcell(canvas); +end; + +procedure tcustomdataedit.doafterpaint(const canvas: tcanvas); +begin + inherited; + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + fgridintf.widgetpainted(canvas); + end; +end; + +function tcustomdataedit.needsfocuspaint: boolean; +begin + result:= (fgridintf = nil) and inherited needsfocuspaint; +end; + +function tcustomdataedit.getgridintf: iwidgetgrid; +begin + result:= fgridintf; +end; + +function tcustomdataedit.checkgriddata: tdatalist; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; +// result:= fgridintf.getcol.datalist; + result:= fdatalist; + if result = nil then begin + raise exception.Create('No datalist.'); + end; +end; + +procedure tcustomdataedit.checkgrid; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; +end; + +function tcustomdataedit.checkgriddata(var index: integer): tdatalist; + //index -1 -> grid.row, nil if no focused row +begin + result:= checkgriddata(); + if index = -1 then begin + index:= fgridintf.getcol.grid.row; + end; + if index < 0 then begin + result:= nil; + end; +end; + +procedure tcustomdataedit.internalgetgridvalue(index: integer; var value); +begin + checkgrid; + fgridintf.getdata(index,value); +end; + +procedure tcustomdataedit.internalsetgridvalue(index: integer; + const Value); +begin + checkgrid; + fgridintf.setdata(index,value); +end; + +procedure tcustomdataedit.internalfillcol(const value); +begin +// checkgrid; +// with tdatalist1(fgridintf.getcol.datalist) do begin + with tdatalist1(checkgriddata) do begin + {tdatalist1(fgridintf.getcol.datalist).}internalfill(count,value); + end; +end; + +procedure tcustomdataedit.internalassigncol(const value); +begin + checkgrid; + with fgridintf.getcol do begin + datalist.Assign(tdatalist(value)); + end; +end; + +function tcustomdataedit.widgetcol: twidgetcol; +begin + if fgridintf = nil then begin + result:= nil; + end + else begin + result:= fgridintf.getcol; + end; +end; + +function tcustomdataedit.grid: tcustomwidgetgrid; +begin + if fgridintf = nil then begin + result:= nil; + end + else begin + result:= fgridintf.getgrid(); + end; +end; + +function tcustomdataedit.getgridrow: integer; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.row; + end; +end; + +function tcustomdataedit.gridrowhigh: int32; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.rowhigh; + end; +end; + +function tcustomdataedit.griddatarowhigh: int32; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.datarowhigh; + end; +end; + +procedure tcustomdataedit.setgridrow(const avalue: integer); +begin + if fgridintf <> nil then begin + fgridintf.getcol.grid.row:= avalue; + end; +end; + +function tcustomdataedit.gridcol: integer; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.index; + end; +end; + +function tcustomdataedit.sortfunc(const l,r): integer; +begin +// result:= tdatalist1(twidgetcol1(fgridintf.getcol).fdata).compare(l,r); + result:= tdatalist1(fdatalist).compare(l,r); +end; + +function tcustomdataedit.griddata: tdatalist; +begin + checkgrid; + result:= fdatalist; +end; + +function tcustomdataedit.textclipped(const arow: integer; + out acellrect: rectty): boolean; +var + rect2: rectty; + canvas1: tcanvas; + cell1: gridcoordty; + grid1: tcustomgrid; + bo1: boolean; +begin + checkgrid; + with twidgetcol1(fgridintf.getcol) do begin + grid1:= grid; + cell1.row:= arow; + cell1.col:= colindex; + result:= grid1.isdatacell(cell1); + if result then begin + acellrect:= grid1.clippedcellrect(cell1,cil_inner); + canvas1:= getcanvas; + rect2:= textrect(canvas1,getcelltext(getdatapo(arow),bo1), + acellrect,feditor.textflags,font); + result:= not rectinrect(rect2,acellrect); + end + else begin + acellrect:= nullrect; + end; + end; +end; + +function tcustomdataedit.textclipped(const arow: integer): boolean; +var + rect1: rectty; +begin + result:= textclipped(arow,rect1); +end; + +procedure tcustomdataedit.docellevent(const ownedcol: boolean; var info: celleventinfoty); + +var + hintinfo: hintinfoty; +begin + if ownedcol then begin + if (info.eventkind = cek_enter) then begin + setupeditor; //setrowfont + feditor.initfocus; + end; + if (oe_hintclippedtext in foptionsedit) and + (info.eventkind = cek_firstmousepark) and application.active and + textclipped(info.cell.row) and + ((info.grid.row <> info.cell.row) or (info.grid.col <> info.cell.col)) and + {$warnings off} + twidget1(info.grid).getshowhint then begin + {$warnings on} + application.inithintinfo(hintinfo,info.grid); + {$warnings off} + hintinfo.caption:= + datatotext(twidgetcol1(fgridintf.getcol).getdatapo(info.cell.row)^); + {$warnings on} + application.showhint(info.grid,hintinfo); + end; + end; +end; + +procedure tcustomdataedit.gridvaluechanged(const index: integer); +begin + //dummy +end; + +function tcustomdataedit.isempty(const atext: msestring): boolean; +begin + result:= trim(atext) = getnulltext; +end; + +function tcustomdataedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= false; + if (newfocus <> self) and not (des_statreading in fstate) and + not ((oe_checkmrcancel in foptionsedit) and + (window.modalresult = mr_cancel)) and + not readonly then begin + if fgridintf = nil then begin + result:= (newfocus = nil) and + (not (des_isdb in fstate) or (des_dbnullcheck in fstate) or + (oe_directdbnullcheck in optionsedit)); + end + else begin + result:= fgridintf.nullcheckneeded(newfocus); + end; + end; +end; + +procedure tcustomdataedit.setenabled(const avalue: boolean); +begin + inherited; + if (fgridintf <> nil) and not (csloading in componentstate) then begin + fgridintf.getcol.enabled:= avalue; + end; +end; + +function tcustomdataedit.seteditfocus: boolean; +begin + if not readonly then begin + if fgridintf = nil then begin + if canfocus then begin + setfocus; + end; + end + else begin + with fgridintf.getcol do begin + grid.col:= index; + if grid.canfocus then begin + if not focused then begin + grid.setfocus; + end; + end; + end; + end; + end; + result:= focused; +end; + +procedure tcustomdataedit.beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); +begin + //dummy +end; + +procedure tcustomdataedit.aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); +begin + //dummy +end; + +procedure tcustomdataedit.initeditfocus; +begin + exclude(fstate,des_edited); + initfocus; +end; + +function tcustomdataedit.datatotext(const data): msestring; +var + mstr1: msestring; + //avoid refcount 0 because of const param in internaldatatotext() +begin + mstr1:= internaldatatotext(data); + if canevent(tmethod(fongettext)) then begin + fongettext(self,mstr1,focused); + end; + result:= mstr1; +end; + +(* +procedure tcustomdataedit.createfontempty; +begin + if fempty_font = nil then begin + fempty_font:= teditemptyfont.create; + fempty_font.onchange:= {$ifdef FPC}@{$endif}fontemptychanged; + end; +end; + +function tcustomdataedit.getempty_font: teditemptyfont; +begin + getoptionalobject(fempty_font,{$ifdef FPC}@{$endif}createfontempty); + result:= fempty_font; + if result = nil then begin + result:= teditemptyfont(getfont1); + end; +end; + +procedure tcustomdataedit.setempty_font(const avalue: teditemptyfont); +begin + if fempty_font <> avalue then begin + setoptionalobject(avalue,fempty_font,{$ifdef FPC}@{$endif}createfontempty); + end; +end; + +function tcustomdataedit.isempty_fontstored: boolean; +begin + result:= fempty_font <> nil; +end; + +procedure tcustomdataedit.fontemptychanged(const sender: tobject); +begin + emptychanged; +end; +*) +function tcustomdataedit.locatecount: integer; +//var +// datalist1: tdatalist; +begin + result:= 0; + if fgridintf <> nil then begin +// datalist1:= fgridintf.getcol.datalist; + if fdatalist <> nil then begin + result:= fdatalist.count; + end; + end; +end; + +function tcustomdataedit.locatecurrentindex: integer; +begin + result:= fgridintf.getcol.grid.row; +end; + +procedure tcustomdataedit.locatesetcurrentindex(const aindex: integer); +begin + fgridintf.getcol.grid.row:= aindex; +end; + +function tcustomdataedit.getkeystring(const aindex: integer): msestring; +begin + with fgridintf.getcol do begin + if grid.rowhidden[aindex] then begin + result:= ''; + end + else begin + result:= datatotext(datalist.getitempo(aindex)^); + end; + end; +end; + +function tcustomdataedit.actualcursor(const apos: pointty): cursorshapety; +var + zone1: cellzonety; + int1: integer; +begin + if (fgridintf <> nil) and not (des_actualcursor in fstate) then begin + include(fstate,des_actualcursor); + try + zone1:= cz_default; + int1:= fgridintf.grid.row; + if int1 >= 0 then begin + updatecellzone(int1,widgetpostoclientpos(apos),zone1); +// result:= getcellcursor(int1,zone1); + result:= getcellcursor(-1,zone1,apos); + exit; + end; + finally + exclude(fstate,des_actualcursor); + end; + end; + result:= inherited actualcursor(apos); +end; + +function tcustomdataedit.getcellcursor(const arow: integer; + const acellzone: cellzonety; const apos: pointty): cursorshapety; +var + bo1: boolean; +begin + bo1:= des_actualcursor in fstate; + include(fstate,des_actualcursor); + result:= actualcursor(nullpoint); + if not bo1 then begin + exclude(fstate,des_actualcursor); + end; +end; + +procedure tcustomdataedit.updatecellzone(const row: integer; + const apos: pointty; var result: cellzonety); +begin + //dummy +end; + +procedure tcustomdataedit.mouseevent(var info: mouseeventinfoty); +begin + if fcontrollerintf <> nil then begin + fcontrollerintf.mouseevent(info); + end; + inherited; +end; + +procedure tcustomdataedit.domousewheelevent(var info: mousewheeleventinfoty); +begin + if fcontrollerintf <> nil then begin + fcontrollerintf.domousewheelevent(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + + +procedure tcustomdataedit.dokeydown(var info: keyeventinfoty); +begin + if fcontrollerintf <> nil then begin + fcontrollerintf.dokeydown(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomdataedit.updatereadonlystate; +begin + inherited; + if fcontrollerintf <> nil then begin + fcontrollerintf.updatereadonlystate; + end; +end; + +procedure tcustomdataedit.internalcreateframe; +begin + if (fframe = nil) and (fcontrollerintf <> nil) then begin + fcontrollerintf.internalcreateframe; + end; + if fframe = nil then begin + inherited; + end; +end; + +procedure tcustomdataedit.editnotification(var info: editnotificationinfoty); +var + bo1: boolean; +begin + if fcontrollerintf <> nil then begin + fcontrollerintf.editnotification(info); + end; + case info.action of + ea_textentered: begin + bo1:= true; + if (des_edited in fstate) or + (oe_forcereturncheckvalue in foptionsedit) then begin + bo1:= checkvalue; + if not bo1 or (oe_eatreturn in foptionsedit) then begin + info.action:= ea_none; + end; + end; + if bo1 then begin + if (fgridintf <> nil) and + (og_colchangeonreturnkey in fgridintf.getcol.grid.optionsgrid)then begin + info.action:= ea_none; + fgridintf.getcol.grid.colstep(fca_focusin,1,true,false,true); + end; + end; + end; + ea_textedited: begin + include(fstate,des_edited); + modified(); + inherited; + end; + ea_resetemptytext: begin + inherited; + end; + ea_undone: begin + updateedittext(true); //restore empty_* setings + end; + ea_textchanged: begin + dotextchange; + end; + ea_undo: begin + exclude(fstate,des_edited); + end; + ea_caretupdating: begin + if (fgridintf <> nil) and focused then begin + fgridintf.showcaretrect(info.caretrect,fframe); + end; + end; + end; +end; + +procedure tcustomdataedit.initnewwidget(const ascale: real); +begin +{ + if fgridintf <> nil then begin + fgridintf.getcol.options:= fgridintf.getcol.grid.datacols.options; + //restore default options + end; +} + inherited; +end; + +function tcustomdataedit.textcellcopy: boolean; +begin + result:= true; +end; + +procedure tcustomdataedit.datalistdestroyed; +begin + fdatalist:= nil; +end; + +{$ifdef mse_with_ifi} +function tcustomdataedit.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure tcustomdataedit.setifilink0(const avalue: tifilinkcomp); +begin + mseificomp.setifilinkcomp(getifidatalinkintf,avalue,tifilinkcomp(fifilink)); +end; + +procedure tcustomdataedit.setifilink(const avalue: tifilinkcomp); +begin + setifilink0(avalue); +end; +{ +function tcustomdataedit.ifigriddata: tdatalist; +begin + result:= fdatalist; +end; +} +procedure tcustomdataedit.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + if fgridintf <> nil then begin + fgridintf.updateifigriddata(alist); + fdatalist:= alist; + end; +end; + +function tcustomdataedit.getgriddata: tdatalist; +begin + result:= fdatalist; +end; + +function tcustomdataedit.getvalueprop: ppropinfo; +begin + result:= getpropinfo(self,'value'); +end; + +function tcustomdataedit.getifidatalinkintf: iifidatalink; +begin + result:= iifidatalink(self); +end; + +function tcustomdataedit.getdefaultifilink: iificlient; +begin + result:= getifidatalinkintf; +end; + +function tcustomdataedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + if fifiserverintf <> nil then begin + fifiserverintf.updateoptionsedit(result); + end; +end; + +procedure tcustomdataedit.ifisetvalue(var avalue; var accept: boolean); +begin + if accept and (fifiserverintf <> nil) then begin + iifidataserver(fifiserverintf).setvalue( + getifidatalinkintf,avalue,accept,gridrow); + end; +end; + +procedure tcustomdataedit.getifivalue(var avalue); +begin + //dummy +end; + +procedure tcustomdataedit.setifivalue(const avalue); +begin + //dummy +end; + +function tcustomdataedit.getifilink: tifilinkcomp; +begin + result:= fifilink; +end; + +procedure tcustomdataedit.dochange; +begin + inherited; + if not (ws_loadedproc in fwidgetstate) then begin + if fifiserverintf <> nil then begin + iifidataserver(fifiserverintf).valuechanged(getifidatalinkintf); + end; + end; +end; + +{$endif mse_with_ifi} + +function tcustomdataedit.getifidatatype(): listdatatypety; +begin + result:= getdatalistclass().datatype(); +end; + +procedure tcustomdataedit.sizechanged; +begin + inherited; + gridwidgetsized(self,fgridintf); +end; + +procedure tcustomdataedit.paint(const canvas: tcanvas); +begin + if (fgridintf = nil) or + not (twidgetcol1(fgridintf.getcol).checkautocolwidth) then begin + inherited; + end; +end; + +procedure tcustomdataedit.updatedatalist; +begin + //dummy +end; + +function tcustomdataedit.isnull: boolean; +begin + result:= false; //dummy +end; + +function tcustomdataedit.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tcustomdataedit.setparentgridwidget(const intf: igridwidget); +begin + fparentintf:= intf; +end; + +procedure tcustomdataedit.childdataentered(const sender: igridwidget); +begin + //dummy +end; + +procedure tcustomdataedit.childfocused(const sender: igridwidget); +begin + //dummy +end; + +{ tcustomstringedit } + +function tcustomstringedit.internaldatatotext(const data): msestring; +begin + if @data = nil then begin + result:= fvalue; + end + else begin + result:= msestring(data); + end; + updatedisptext(result); +end; + +procedure tcustomstringedit.texttodata(const atext: msestring; var data); +begin + msestring(data):= atext; +end; + +function tcustomstringedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridmsestringdatalist.create(sender); +end; + +function tcustomstringedit.getdatalistclass: datalistclassty; +begin + result:= tgridmsestringdatalist; +end; + +procedure tcustomstringedit.setvalue(const Value: msestring); +begin + fvalue:= Value; + valuechanged; +end; + +function tcustomstringedit.getvaluetext: msestring; +begin + result:= text; +end; + +procedure tcustomstringedit.updatedisptext(var avalue: msestring); +begin + updateflagtext(avalue); +end; + +procedure tcustomstringedit.dosetvalue(var avalue: msestring; var accept: boolean); +begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,avalue,accept); + end; +end; + +procedure tcustomstringedit.texttovalue(var accept: boolean; + const quiet: boolean); +var + mstr1: msestring; +begin + mstr1:= getvaluetext; + updateflagtext(mstr1); + checktext(mstr1,accept); + if not accept then begin + exit; + end; + if not quiet then begin + dosetvalue(mstr1,accept); +{$ifdef mse_with_ifi} + ifisetvalue(mstr1,accept); +{$endif} + end; + if accept then begin + value:= mstr1; + end; +end; + +function tcustomstringedit.checkvalue(const quiet: boolean = false): boolean; +//var +// mstr1: msestring; +begin +{ + if optionsedit * + [oe_trimleft,oe_trimright,oe_uppercase,oe_lowercase] <> [] then begin + mstr1:= getvaluetext; + updateflagtext(mstr1); + text:= mstr1; + end; +} + result:= inherited checkvalue(quiet); +end; + +procedure tcustomstringedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomstringedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomstringedit.readstatvalue(const reader: tstatreader); +//var +// ar1: msestringarty; +begin +// ar1:= nil; //compiler warning +// if fgridintf = nil then begin +// ar1:= nil; +// ar1:= reader.readarray(valuevarname+'ar',ar1); +// if high(ar1) >= 0 then begin +// value:= concatstrings(ar1,lineend); +// end +// else begin + value:= reader.readmsestring(valuevarname,value); +// end; +// end; +end; + +procedure tcustomstringedit.writestatvalue(const writer: tstatwriter); +//var +// ar1: msestringarty; +begin +// ar1:= breaklines(value); +// if high(ar1) > 0 then begin +// writer.writearray(valuevarname+'ar',ar1); +// end +// else begin + writer.writemsestring(valuevarname,value); +// end; +end; + +procedure tcustomstringedit.dragevent(var info: draginfoty); +begin + with info do begin + case eventkind of + dek_check: begin + inherited; + accept:= accept or (dragobjectpo^ is tstringdragobject); + end; + dek_drop: begin + if dragobjectpo^ is tstringdragobject then begin + value:= msestring(tstringdragobject(dragobjectpo^).data); + end + else begin + inherited; + end; + end; + else begin + inherited; + end; + end; + end; +end; + +procedure tcustomstringedit.fillcol(const value: msestring); +begin + internalfillcol(value); +end; + +procedure tcustomstringedit.assigncol(const value: tmsestringdatalist); +begin + internalassigncol(value); +end; + +function tcustomstringedit.getgridvalue(const index: integer): msestring; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomstringedit.setgridvalue(const index: integer; + const Value: msestring); +begin + internalsetgridvalue(index,value); +end; + +function tcustomstringedit.sortfunc(const l,r): integer; +begin + if oe_casesensitive in foptionsedit then begin + result:= msecomparestr(msestring(l),msestring(r)); + end + else begin + result:= msecomparetext(msestring(l),msestring(r)); + end; +end; + +function tcustomstringedit.getgridvalues: msestringarty; +begin + result:= tmsestringdatalist(checkgriddata).asarray; +// result:= tmsestringdatalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tcustomstringedit.setgridvalues(const Value: msestringarty); +begin + tmsestringdatalist(checkgriddata).asarray:= value; +// tmsestringdatalist(fgridintf.getcol.datalist).asarray:= value; +end; +{ +function tcustomstringedit.isempty(const atext: msestring): boolean; +begin + if fvaluedefault <> '' then begin + result:= atext = fvaluedefault; + end + else begin + result:= atext = getnulltext; + end; +end; +} + +function tcustomstringedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +{$ifdef mse_with_ifi} +function tcustomstringedit.getifilink: tifistringlinkcomp; +begin + result:= tifistringlinkcomp(fifilink); +end; + +procedure tcustomstringedit.setifilink(const avalue: tifistringlinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +function tcustomstringedit.isnull: boolean; +begin + result:= value = ''; +end; + +function tcustomstringedit.griddata: tgridmsestringdatalist; +begin + result:= tgridmsestringdatalist(inherited griddata); +end; + +procedure tcustomstringedit.setvaluedata(const source); +begin + value:= msestring(source); +end; + +procedure tcustomstringedit.getvaluedata(out dest); +begin + msestring(dest):= value; +end; + +{ tstringedit } + +{ tcustommemoedit } + +constructor tcustommemoedit.create(aowner: tcomponent); +begin + inherited; + internalcreateframe; + foptionswidget:= defaultoptionswidgetmousewheel; + foptionsedit:= defaultmemooptionsedit; + optionsedit1:= defaultmemooptionsedit1; + textflags:= defaultmemotextflags; + textflagsactive:= defaultmemotextflagsactive; +end; + +procedure tcustommemoedit.afterconstruction; +begin + inherited; + fcreated:= true; +end; + +procedure tcustommemoedit.internalcreateframe; +begin + tscrolleditframe.create(iscrollframe(self),iscrollbar(self)); + with frame do begin + sbhorz.pagesize:= 1; + sbvert.pagesize:= 1; + end; +end; + +procedure tcustommemoedit.mouseevent(var info: mouseeventinfoty); +begin + tscrolleditframe(fframe).mouseevent(info); + inherited; +end; + +function tcustommemoedit.getframe: tscrolleditframe; +begin + result:= tscrolleditframe(inherited getframe); +end; + +procedure tcustommemoedit.setframe(const avalue: tscrolleditframe); +begin + inherited setframe(avalue); +end; + +procedure tcustommemoedit.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +var + pagesize: integer; + stepsize: integer; + + procedure init; + begin + if sender = frame.sbvert then begin + stepsize:= feditor.font.lineheight; + if stepsize > 0 then begin + pagesize:= ((innerclientsize.cy - stepsize div 2) div stepsize) * stepsize; + end + else begin + pagesize:= innerclientsize.cy; + end; + end + else begin + stepsize:= innerclientsize.cx div 10; + pagesize:= innerclientsize.cx - stepsize; + end; + if stepsize < 2 then begin + stepsize:= 2; + end; + if pagesize < stepsize then begin + pagesize:= stepsize; + end; + end; + +var + int1: integer; + size1: sizety; + +begin + int1:= 0; + stepsize:= 0; + pagesize:= 0; + case event of + sbe_stepup: begin + init; + int1:= stepsize; + end; + sbe_stepdown: begin + init; + int1:= -stepsize; + end; + sbe_pageup,sbe_wheelup: begin + init; + int1:= pagesize; + end; + sbe_pagedown,sbe_wheeldown: begin + init; + int1:= -pagesize; + end; + sbe_valuechanged: begin + feditor.setscrollvalue(sender.value,sender = frame.sbhorz); + end; + end; + if int1 <> 0 then begin + size1:= feditor.textrect.size; + subsize1(size1,innerclientsize); + if sender = frame.sbvert then begin + if size1.cy > 0 then begin + sender.value:= sender.value + int1 / size1.cy; + end; + end + else begin + if size1.cx > 0 then begin + sender.value:= sender.value + int1 / size1.cx; + end; + end; + end; +end; + +procedure tcustommemoedit.updatescrollbars; +var + rect1: rectty; + size1: sizety; +begin + rect1:= feditor.textrect; + size1:= innerclientsize; + if (ftextrectbefore.cx <> rect1.cx) or + (ftextrectbefore.cy <> rect1.cy) or + (size1.cx <> fclientsizebefore.cx) or + (size1.cy <> fclientsizebefore.cy) then begin + ftextrectbefore:= rect1; + fclientsizebefore:= size1; + with frame do begin + if rect1.cx > 0 then begin + sbhorz.pagesize:= size1.cx / rect1.cx; + end + else begin + sbhorz.pagesize:= 1; + end; + if rect1.cy > 0 then begin + sbvert.pagesize:= size1.cy / rect1.cy; + end + else begin + sbvert.pagesize:= 1; + end; + if fupdatescrollbarcount < 10 then begin //limit recursions + inc(fupdatescrollbarcount); + try + tcustomframe1(fframe).updatestate; + finally + dec(fupdatescrollbarcount); + end; + end; + end; + end; +end; + +procedure tcustommemoedit.editnotification(var info: editnotificationinfoty); +var + rect1: rectty; +begin + inherited; + if fcreated and windowallocated then begin + case info.action of + ea_textchanged: begin + updatescrollbars; + end; + ea_caretupdating: begin + if fframe <> nil then begin + rect1.size:= feditor.textrect.size; + subsize1(rect1.size,feditor.destrect.size); + rect1.pos:= feditor.destrect.pos; + subpoint1(rect1.pos,innerclientpos); + with frame do begin + if rect1.cx > 0 then begin + sbhorz.value:= -rect1.x / rect1.cx; + end + else begin + sbhorz.value:= 0; + end; + if rect1.cy > 0 then begin + sbvert.value:= -rect1.y / rect1.cy; + end + else begin + sbvert.value:= 0; + end; + end; + end; + end; + ea_indexmoved: begin + fxpos:= feditor.caretpos.x; + end; + end; + end; +end; + +procedure tcustommemoedit.dokeydown(var info: keyeventinfoty); +var + int1,int2: integer; + rect1: rectty; + indexbefore: integer; +begin + if not (es_processed in info.eventstate) then begin + if info.shiftstate * shiftstatesmask - [ss_shift] = [] then begin + include(info.eventstate,es_processed); + with feditor do begin + int2:= fxpos; + int1:= 0; + case info.key of + key_pageup: begin + int1:= -(innerpaintrect.cy - self.font.lineheight); + end; + key_pagedown: begin + int1:= (innerpaintrect.cy - self.font.lineheight); + end; + key_up: begin + int1:= - self.font.lineheight; + end; + key_down: begin + int1:= self.font.lineheight; + end; + else begin + exclude(info.eventstate,es_processed); + end; + end; + if int1 <> 0 then begin + int1:= caretpos.y + int1; + rect1:= textrect; + if int1 < rect1.y then begin + int1:= rect1.y; + end; + if int1 >= rect1.y + rect1.cy then begin + int1:= rect1.y + rect1.cy - 1; + end; + indexbefore:= curindex; + moveindex(mousepostotextindex(makepoint(fxpos,int1)), + ss_shift in info.shiftstate); + if ss_shift in info.shiftstate then begin + invalidate; + end; + if fxpos < int2 then begin + fxpos:= int2; + end; + if (oe_exitoncursor in foptionsedit) and (indexbefore = curindex) and + (info.shiftstate = []) and + ((info.key = key_down) or (info.key = key_up)) then begin + exclude(info.eventstate,es_processed); + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +function tcustommemoedit.getnoscroll(): boolean; +begin + result:= inherited getnoscroll() or needsfocuspaintstate() and + (tcustomframe1(fframe).haspaintrectfocus()); + //do not scroll focusrect +end; + +procedure tcustommemoedit.setupeditor; +begin + inherited; + if not (fs_creating in tcustomframe1(fframe).fstate) then begin + updatescrollbars; + end; +end; + +procedure tcustommemoedit.domousewheelevent(var info: mousewheeleventinfoty); +begin + if fframe <> nil then begin + frame.domousewheelevent(info,false); + end; + inherited; +end; + +{ thexstringedit } + +function thexstringedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridansistringdatalist.create(sender); +end; + +function thexstringedit.getdatalistclass: datalistclassty; +begin + result:= tgridansistringdatalist; +end; + +function thexstringedit.getgridvalue(const index: integer): ansistring; +begin + internalgetgridvalue(index,result); +end; + +procedure thexstringedit.setgridvalue(const index: integer; const Value: ansistring); +begin + internalsetgridvalue(index,value); +end; + +function thexstringedit.getgridvalues: stringarty; +begin + result:= tansistringdatalist(checkgriddata).asarray; +// result:= tansistringdatalist(fgridintf.getcol.datalist).asarray; +end; + +procedure thexstringedit.setgridvalues(const Value: stringarty); +begin + tansistringdatalist(checkgriddata).asarray:= value; +// tansistringdatalist(fgridintf.getcol.datalist).asarray:= value; +end; + +procedure thexstringedit.fillcol(const value: string); +begin + internalfillcol(value); +end; + +procedure thexstringedit.assigncol(const value: tansistringdatalist); +begin + internalassigncol(value); +end; + +procedure thexstringedit.dosetvalue(var avalue: ansistring; var accept: boolean); +begin + if accept and canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,avalue,accept); + end; +end; + +procedure thexstringedit.texttovalue(var accept: boolean; const quiet: boolean); +var + mstr1: msestring; + str1: ansistring; +begin + try + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + str1:= strtobytestr(printableascii(ansistring(mstr1))) + except + formaterror(quiet); + accept:= false + end; + if accept then begin + if not quiet then begin + dosetvalue(str1,accept); + end; + if accept then begin + value:= str1; + end; + end; +end; + +function thexstringedit.internaldatatotext(const data): msestring; +var + str1: ansistring; +begin + if @data = nil then begin + str1:= fvalue; + end + else begin + str1:= ansistring(data); + end; + if length(str1) > 256 then begin + result:= msestring(bytestrtostr(copy(str1,1,256),nb_hex,' '))+'...'; + end + else begin + result:= msestring(bytestrtostr(str1,nb_hex,' ')); + end; +end; + +procedure thexstringedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure thexstringedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure thexstringedit.readstatvalue(const reader: tstatreader); +begin +// if fgridintf = nil then begin + value:= reader.readbinarystring(valuevarname,value); +// end; +end; + +procedure thexstringedit.writestatvalue(const writer: tstatwriter); +begin + writer.writebinarystring(valuevarname,value); +end; + +function thexstringedit.sortfunc(const l,r): integer; +begin + result:= stringcomp(ansistring(l),ansistring(r)); +end; + +procedure thexstringedit.setvalue(const Value: string); +begin + fvalue := Value; + valuechanged; +end; + +function thexstringedit.griddata: tgridansistringdatalist; +begin + result:= tgridansistringdatalist(inherited griddata); +end; + +procedure thexstringedit.setvaluedata(const source); +begin + value:= string(source); +end; + +procedure thexstringedit.getvaluedata(out dest); +begin + string(dest):= value; +end; + +{ tcustomdropdownedit } + +constructor tcustomdropdownedit.create(aowner: tcomponent); +begin + inherited; + fdropdown:= createdropdowncontroller; + fcontrollerintf:= idataeditcontroller(fdropdown); +end; + +destructor tcustomdropdownedit.destroy; +begin + inherited; + fdropdown.Free; +end; +{ +procedure tcustomdropdownedit.editnotification(var info: editnotificationinfoty); +begin + if fdropdown <> nil then begin + fdropdown.editnotification(info); + end; + inherited; +end; +} +{ +procedure tcustomdropdownedit.dokeydown(var info: keyeventinfoty); +begin + fdropdown.dokeydown(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +} +{ +procedure tcustomdropdownedit.domousewheelevent(var info: mousewheeleventinfoty); +begin + fdropdown.domousewheelevent(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +} +function tcustomdropdownedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdropdowncontroller.create(idropdown(self)); +end; + +procedure tcustomdropdownedit.loaded(); +begin + inherited; + tcustomdropdowncontroller1(fdropdown).updatereadonlystate(); + //for db dropdowns +end; + +procedure tcustomdropdownedit.dobeforedropdown; +begin + if canevent(tmethod(fonbeforedropdown)) then begin + fonbeforedropdown(self); + end; +end; + +procedure tcustomdropdownedit.doafterclosedropdown; +begin + if canevent(tmethod(fonafterclosedropdown)) then begin + fonafterclosedropdown(self); + end; +end; + +procedure tcustomdropdownedit.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + //dummy +end; +{ +procedure tcustomdropdownedit.mouseevent(var info: mouseeventinfoty); +begin + tcustombuttonframe(fframe).mouseevent(info); + inherited; +end; +} +procedure tcustomdropdownedit.texttovalue(var accept: boolean; + const quiet: boolean); +begin + if (deo_selectonly in fdropdown.options) and + not fdropdown.dataselected then begin + if (text <> '') then begin + if not quiet and not (des_statreading in fstate) and + not (deo_autodropdown in fdropdown.options) then begin + accept:= false; + fdropdown.dropdown; + end + else begin + if feditor.canundo then begin //otherwise no userentry + accept:= false; + feditor.undo; + end; + end + end + else begin + tdropdowncontroller1(fdropdown).resetselection; + inherited; + end; + end + else begin + inherited; + end; +end; +{ +function tcustomdropdownedit.getcellframe: framety; +begin + result:= fframe.cellframe; +end; +} +function tcustomdropdownedit.getframe: tdropdownmultibuttonframe; +begin + result:= tdropdownmultibuttonframe(inherited getframe); +end; + +procedure tcustomdropdownedit.setframe(const avalue: tdropdownmultibuttonframe); +begin + inherited setframe(avalue); +end; +{ +procedure tcustomdropdownedit.internalcreateframe; +begin + fdropdown.createframe; +end; +} +procedure tcustomdropdownedit.dohide; +begin + fdropdown.canceldropdown; + inherited; +end; + +function tcustomdropdownedit.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags(); + if fdropdown.hasdropdown() then begin + include(result,asf_hasdropdown); + end; +end; +{ +function tcustomdropdownedit.getassistivecaption(): msestring; +var + wi1: tcustomgrid; + intf1: iassistiveclientgrid; +begin + if fdropdown.hasdropdown() then begin + wi1:= tcustomgrid(fdropdown.dropdownwidget); + result:= iassistiveclientgrid(wi1).getassistivecellcaption(wi1.focusedcell); + end + else begin + result:= inherited getassistivecaption(); + end; +end; + +function tcustomdropdownedit.getassistivetext(): msestring; +var + wi1: tcustomgrid; + intf1: iassistiveclientgrid; +begin + if fdropdown.hasdropdown() then begin + wi1:= tcustomgrid(fdropdown.dropdownwidget); + result:= iassistiveclientgrid(wi1).getassistivecelltext(wi1.focusedcell); + end + else begin + result:= inherited getassistivetext(); + end; +end; +} +{ +procedure tcustomdropdownedit.updatereadonlystate; +begin + inherited; + if fdropdown <> nil then begin + fdropdown.updatereadonlystate; + end; +end; +} +function tcustomdropdownedit.getvalueempty: integer; +begin + result:= -1; +end; + +procedure tcustomdropdownedit.dostatread(const reader: tstatreader); +begin + inherited; + fdropdown.dostatread(reader); +end; + +procedure tcustomdropdownedit.dostatwrite(const writer: tstatwriter); +begin + inherited; + fdropdown.dostatwrite(writer); +end; + +{$ifdef mse_with_ifi} +function tcustomdropdownedit.getifidatalinkintf: iifidatalink; +begin + result:= iifidropdownlistdatalink(self); +end; + +procedure tcustomdropdownedit.ifidropdownlistchanged(const acols: tifidropdowncols); +begin +end; +{$endif} + +{ +function tcustomdropdownedit.getbutton: tdropdownbutton; +begin + with tdropdownmultibuttonframe(fframe) do begin + result:= tdropdownbutton(buttons[activebutton]); + end; +end; + +procedure tcustomdropdownedit.setbutton(const avalue: tdropdownbutton); +begin + with tdropdownmultibuttonframe(fframe) do begin + tdropdownbutton(buttons[activebutton]).assign(avalue); + end; +end; +} +{ tcustomdropdownwidgetedit } + +function tcustomdropdownwidgetedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdropdownwidgetcontroller.create(idropdownwidget(self)); +end; + +function tcustomdropdownwidgetedit.getdropdown: tdropdownwidgetcontroller; +begin + result:= tdropdownwidgetcontroller(fdropdown); +end; + +procedure tcustomdropdownwidgetedit.setdropdown( + const avalue: tdropdownwidgetcontroller); +begin + fdropdown.Assign(avalue); +end; + +{ tcustomdropdownlistedit } + +function tcustomdropdownlistedit.getdropdownitems: tdropdowndatacols; +begin + result:= nil; +end; + +function tcustomdropdownlistedit.getdropdown: tdropdownlistcontroller; +begin + result:= tdropdownlistcontroller(fdropdown); +end; + +procedure tcustomdropdownlistedit.setdropdown( + const avalue: tdropdownlistcontroller); +begin + fdropdown.Assign(avalue); +end; + +function tcustomdropdownlistedit.createdropdowncontroller: + tcustomdropdowncontroller; +begin + result:= tdropdownlistcontroller.create(idropdownlist(self)); +end; + +procedure tcustomdropdownlistedit.internalsort(const acol: integer; + out sortlist: integerarty); +var + int1: integer; +begin + with tdropdownlistcontroller(fdropdown) do begin + cols.beginupdate; + try + cols[acol].sort(sortlist,false); + for int1:= 0 to cols.count - 1 do begin + cols[int1].rearange(sortlist); + end; + finally + cols.endupdate; + end; + end; +end; + +procedure tcustomdropdownlistedit.sort(const acol: integer); +var + ar1: integerarty; +begin + internalsort(acol,ar1); +end; + +{$ifdef mse_with_ifi} +function tcustomdropdownlistedit.getifilink: tifidropdownlistlinkcomp; +begin + result:= tifidropdownlistlinkcomp(fifilink); +end; + +procedure tcustomdropdownlistedit.setifilink1(const avalue: tifidropdownlistlinkcomp); +begin + setifilink0(avalue); +end; + +function tcustomdropdownlistedit.getifidatalinkintf: iifidatalink; +begin + result:= iifidropdownlistdatalink(self); +end; + +function tcustomdropdownlistedit.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidropdownlistdatalink); +end; + +procedure tcustomdropdownlistedit.ifidropdownlistchanged( + const acols: tifidropdowncols); +begin + dropdown.cols.assign(acols); +end; + +{$endif} + +function tcustomdropdownlistedit.geteditframe: framety; +begin + result:= nullframe; + if (fdropdown <> nil) and not(csdestroying in componentstate) and + (tcustomdropdownlistcontroller(fdropdown).imagelist <> nil) then begin + with tcustomdropdownlistcontroller1(fdropdown)do begin + result.left:= tcustomdropdownlistcontroller(fdropdown).imagelist.width + + fimageframe.left + fimageframe.right; + end; + end; +end; + +procedure tcustomdropdownlistedit.getautopaintsize(var asize: sizety); +var + int1: integer; +begin + inherited; + with tcustomdropdownlistcontroller1(fdropdown)do begin + if fimagelist <> nil then begin + int1:= fimagelist.height + fimageframe.top + fimageframe.bottom; + if int1 > asize.cy then begin + asize.cy:= int1; + end; + end; + end; +end; + +procedure tcustomdropdownlistedit.imagelistchanged; +begin + if componentstate*[csloading,csdestroying] = [] then begin + setupeditor; + formatchanged(); +// checkautosize; + end; +end; + +procedure tcustomdropdownlistedit.paintimage(const canvas: tcanvas); +begin + with tcustomdropdownlistcontroller1(fdropdown) do begin + if imagelist <> nil then begin + imagelist.paint(canvas,itemindex, + deflaterect(clientrect,fimageframe),[al_ycentered]); + end; + end; + inherited; +end; + +procedure tcustomdropdownlistedit.dochange; +begin + if tcustomdropdownlistcontroller(fdropdown).imagelist <> nil then begin + invalidate; + end; + inherited; +end; + +{ thistorycontroller } + +constructor thistorycontroller.create(const intf: idropdownlist); +begin + inherited; + fhistorymaxcount:= defaulthistorymaxcount; + foptions:= defaulthistoryeditoptions; +end; + +procedure thistorycontroller.checkmaxcount; +begin + if valuelist.count > fhistorymaxcount then begin + valuelist.count:= fhistorymaxcount; + end; +end; + +procedure thistorycontroller.sethistorymaxcount(const aValue: integer); +begin + fhistorymaxcount := avalue; + checkmaxcount; +end; + +procedure thistorycontroller.clearhistory; +begin + cols.clear; +end; +{ +function thistorycontroller.gethistory: tmsestringdatalist; +begin + result:= valuelist; +end; +} +procedure thistorycontroller.savehistoryvalue(const avalue: msestring); +var + int1: integer; + list: tmsestringdatalist; +begin + list:= valuelist; + list.insert(0,avalue); + int1:= 1; + while int1 < list.count do begin + if list[int1] = avalue then begin + list.deletedata(int1); + end + else begin + inc(int1); + end; + end; + checkmaxcount; +end; + +procedure thistorycontroller.readstate(const reader: tstatreader); +begin + reader.readdatalist('history',valuelist); +end; + +procedure thistorycontroller.writestate(const writer: tstatwriter); +begin + writer.writedatalist('history',valuelist); +end; + +function thistorycontroller.gethistory: msestringarty; +begin + result:= valuelist.asarray; +end; + +procedure thistorycontroller.sethistory(const avalue: msestringarty); +begin + valuelist.asarray:= copy(avalue,0,fhistorymaxcount); +end; + +{ tcustomhistoryedit } + +constructor tcustomhistoryedit.create(aowner: tcomponent); +begin + inherited; +end; + +procedure tcustomhistoryedit.savehistoryvalue; +begin + thistorycontroller(fdropdown).savehistoryvalue(fvalue); +end; + +procedure tcustomhistoryedit.loaded; +begin + inherited; +// checkmaxcount; +end; + +procedure tcustomhistoryedit.readstatstate(const reader: tstatreader); +begin + inherited; + thistorycontroller(fdropdown).readstate(reader); +end; + +procedure tcustomhistoryedit.writestatstate(const writer: tstatwriter); +begin + inherited; + thistorycontroller(fdropdown).writestate(writer); +end; + +procedure tcustomhistoryedit.setdropdown(const avalue: thistorycontroller); +begin + fdropdown.Assign(avalue); +end; + +function tcustomhistoryedit.getdropdown: thistorycontroller; +begin + result:= thistorycontroller(fdropdown); +end; + +procedure tcustomhistoryedit.texttovalue(var accept: boolean; const quiet: boolean); +begin + inherited; + if not quiet and accept and + (deo_autosavehistory in thistorycontroller(fdropdown).foptions) then begin + savehistoryvalue; + end; +end; + +function tcustomhistoryedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= thistorycontroller.create(idropdownlist(self)); +end; + +{ tnumedit } + +constructor tnumedit.create(aowner: tcomponent); +begin + inherited; + textflags:= defaultnumedittextflags; +end; + +{ tcustomintegeredit } + +constructor tcustomintegeredit.create(aowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + fvaluemax:= maxint; + inherited; +end; + +function tcustomintegeredit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridintegerdatalist.create(sender); +end; + +function tcustomintegeredit.getdatalistclass: datalistclassty; +begin + result:= tgridintegerdatalist; +end; + +procedure tcustomintegeredit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomintegeredit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomintegeredit.setvalue(const Value: integer); +begin + fvalue := Value; + if fvaluechecking = 0 then begin + fisnull:= false; + end; + valuechanged; +end; + +function tcustomintegeredit.gettextvalue(var accept: boolean; + const quiet: boolean): integer; +var + mstr1: msestring; +begin + if fisnull then begin + result:= 0; + end + else begin + try + mstr1:= text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + result:= strtointvalue(mstr1,fbase); + except + formaterror(quiet); + accept:= false + end; + end; +end; + +procedure tcustomintegeredit.texttovalue(var accept: boolean; const quiet: boolean); +var + int1: integer; +// mstr1: msestring; +begin + int1:= gettextvalue(accept,quiet); +{ + if fisnull then begin + int1:= 0; + end + else begin + try + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + int1:= strtointvalue(mstr1,fbase); + except + formaterror(quiet); + accept:= false + end; + end; +} + if accept then begin + if not fisnull then begin + if fvaluemax < fvaluemin then begin //unsigned + if (longword(int1) < longword(fvaluemin)) or + (longword(int1) > longword(fvaluemax)) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end + else begin + if (int1 < fvaluemin) or (int1 > fvaluemax) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end; + end; + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,int1,accept); + end; + {$ifdef mse_with_ifi} + ifisetvalue(int1,accept); + {$endif} + end; + if accept then begin + value:= int1; + end; + end; + end; +end; + +procedure tcustomintegeredit.texttodata(const atext: msestring; var data); +var + int1: integer; +begin + try + int1:= strtointvalue(atext,fbase); + except + int1:= 0; + end; + if int1 < fvaluemin then begin + int1:= fvaluemin; + end; + if int1 > fvaluemax then begin + int1:= fvaluemax; + end; + integer(data):= int1; +end; + +procedure tcustomintegeredit.readstatvalue(const reader: tstatreader); +begin +// if fgridintf <> nil then begin +// with fgridintf.getcol do begin +// with tintegerdatalist(datalist) do begin +// min:= fmin; +// max:= fmax; +// end; +// dostatread(reader); +// end; +// reader.readintegerdatalist(valuevarname, +// tintegerdatalist(fgridintf.getcol.datalist),fmin,fmax); +// end +// else begin + value:= reader.readinteger(valuevarname,value,fvaluemin,fvaluemax); +// end; +end; + +procedure tcustomintegeredit.writestatvalue(const writer: tstatwriter); +begin + writer.writeinteger(valuevarname,value); +end; + +procedure tcustomintegeredit.setnullvalue; +begin + value:= 0; + fisnull:= true; + nullvalueset(); +end; + +procedure tcustomintegeredit.setbase(const Value: numbasety); +begin + if fbase <> value then begin + fbase := Value; + formatchanged; + end; +end; + +procedure tcustomintegeredit.setbitcount(const Value: integer); +begin + if fbitcount <> value then begin + fbitcount := Value; + formatchanged; + end; +end; + +function tcustomintegeredit.internaldatatotext(const data): msestring; +begin + if @data = nil then begin + result:= msestring(intvaluetostr(fvalue,fbase,fbitcount)); + end + else begin + result:= msestring(intvaluetostr(integer(data),fbase,fbitcount)); + end; +end; + +function tcustomintegeredit.getgridvalue(const index: integer): integer; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomintegeredit.setgridvalue(const index, Value: integer); +begin + internalsetgridvalue(index,value); +end; + +function tcustomintegeredit.getgridvalues: integerarty; +begin + result:= tintegerdatalist(checkgriddata).asarray; +// result:= tintegerdatalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tcustomintegeredit.setgridvalues(const Value: integerarty); +begin + tintegerdatalist(checkgriddata).asarray:= value; +// tintegerdatalist(fgridintf.getcol.datalist).asarray:= value; +end; + +procedure tcustomintegeredit.fillcol(const value: integer); +begin + internalfillcol(value); +end; + +procedure tcustomintegeredit.assigncol(const value: tintegerdatalist); +begin + internalassigncol(value); +end; + +{$ifdef mse_with_ifi} +function tcustomintegeredit.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure tcustomintegeredit.setifilink(const avalue: tifiintegerlinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +function tcustomintegeredit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +procedure tcustomintegeredit.setvaluemin(const avalue: integer); +begin + fvaluemin:= avalue; + if fdatalist <> nil then begin + with tgridintegerdatalist(fdatalist) do begin + min:= avalue; + end; + end; +end; + +procedure tcustomintegeredit.setvaluemax(const avalue: integer); +begin + fvaluemax:= avalue; + if fdatalist <> nil then begin + with tgridintegerdatalist(fdatalist) do begin + max:= avalue; + end; + end; +end; + + +procedure tcustomintegeredit.updatedatalist; +begin + with tgridintegerdatalist(fdatalist) do begin + min:= self.valuemin; + max:= self.valuemax; + end; +end; + +procedure tcustomintegeredit.readmin(reader: treader); +begin + valuemin:= reader.readinteger; +end; + +procedure tcustomintegeredit.readmax(reader: treader); +begin + valuemax:= reader.readinteger; +end; + +procedure tcustomintegeredit.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +function tcustomintegeredit.griddata: tgridintegerdatalist; +begin + result:= tgridintegerdatalist(inherited griddata); +end; + +procedure tcustomintegeredit.setvaluedata(const source); +begin + value:= integer(source); +end; + +procedure tcustomintegeredit.getvaluedata(out dest); +begin + integer(dest):= value; +end; + +{ tcustomint64edit } + +constructor tcustomint64edit.create(aowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 64; + fvaluemax:= maxint64; + inherited; +end; + +function tcustomint64edit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridint64datalist.create(sender); +end; + +function tcustomint64edit.getdatalistclass: datalistclassty; +begin + result:= tgridint64datalist; +end; + +procedure tcustomint64edit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomint64edit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomint64edit.setvalue(const Value: int64); +begin + fvalue := Value; + if fvaluechecking = 0 then begin + fisnull:= false; + end; + valuechanged; +end; + +procedure tcustomint64edit.texttovalue(var accept: boolean; const quiet: boolean); +var + int1: int64; + mstr1: msestring; +begin + if fisnull then begin + int1:= 0; + end + else begin + try + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + int1:= strtointvalue64(mstr1,fbase); + except + formaterror(quiet); + accept:= false + end; + end; + if accept then begin + if not fisnull then begin + if fvaluemax < fvaluemin then begin //unsigned + if (uint64(int1) < uint64(fvaluemin)) or + (uint64(int1) > uint64(fvaluemax)) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end + else begin + if (int1 < fvaluemin) or (int1 > fvaluemax) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end; + end; + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,int1,accept); + end; + {$ifdef mse_with_ifi} + ifisetvalue(int1,accept); + {$endif} + end; + if accept then begin + value:= int1; + end; + end; + end; +end; + +procedure tcustomint64edit.texttodata(const atext: msestring; var data); +var + int1: int64; +begin + try + int1:= strtointvalue64(atext,fbase); + except + int1:= 0; + end; + if int1 < fvaluemin then begin + int1:= fvaluemin; + end; + if int1 > fvaluemax then begin + int1:= fvaluemax; + end; + int64(data):= int1; +end; + +procedure tcustomint64edit.readstatvalue(const reader: tstatreader); +begin +// if fgridintf <> nil then begin +// with fgridintf.getcol do begin +// with tint64datalist(datalist) do begin +// min:= fmin; +// max:= fmax; +// end; +// dostatread(reader); +// end; +// reader.readintegerdatalist(valuevarname, +// tintegerdatalist(fgridintf.getcol.datalist),fmin,fmax); +// end +// else begin + value:= reader.readint64(valuevarname,value,fvaluemin,fvaluemax); +// end; +end; + +procedure tcustomint64edit.writestatvalue(const writer: tstatwriter); +begin + writer.writeint64(valuevarname,value); +end; + +procedure tcustomint64edit.setnullvalue; +begin + value:= 0; +// text:= ''; + fisnull:= true; + nullvalueset(); +end; + +procedure tcustomint64edit.setbase(const Value: numbasety); +begin + if fbase <> value then begin + fbase := Value; + formatchanged; + end; +end; + +procedure tcustomint64edit.setbitcount(const Value: integer); +begin + if fbitcount <> value then begin + fbitcount := Value; + formatchanged; + end; +end; + +function tcustomint64edit.internaldatatotext(const data): msestring; +begin + if @data = nil then begin + result:= msestring(intvaluetostr(fvalue,fbase,fbitcount)); + end + else begin + result:= msestring(intvaluetostr(int64(data),fbase,fbitcount)); + end; +end; + +function tcustomint64edit.getgridvalue(const index: integer): int64; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomint64edit.setgridvalue(const index: integer; + const Value: int64); +begin + internalsetgridvalue(index,value); +end; + +function tcustomint64edit.getgridvalues: int64arty; +begin + result:= tint64datalist(checkgriddata).asarray; +// result:= tint64datalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tcustomint64edit.setgridvalues(const Value: int64arty); +begin + tint64datalist(checkgriddata).asarray:= value; +// tint64datalist(fgridintf.getcol.datalist).asarray:= value; +end; + +{$ifdef mse_with_ifi} +function tcustomint64edit.getifilink: tifiint64linkcomp; +begin + result:= tifiint64linkcomp(fifilink); +end; + +procedure tcustomint64edit.setifilink(const avalue: tifiint64linkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tcustomint64edit.readmin(reader: treader); +begin + valuemin:= reader.readint64; +end; + +procedure tcustomint64edit.readmax(reader: treader); +begin + valuemax:= reader.readint64; +end; + +procedure tcustomint64edit.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +{$endif} +procedure tcustomint64edit.fillcol(const value: int64); +begin + internalfillcol(value); +end; + +procedure tcustomint64edit.assigncol(const value: tint64datalist); +begin + internalassigncol(value); +end; + +function tcustomint64edit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +function tcustomint64edit.griddata: tgridint64datalist; +begin + result:= tgridint64datalist(inherited griddata); +end; + +procedure tcustomint64edit.setvaluedata(const source); +begin + value:= int64(source); +end; + +procedure tcustomint64edit.getvaluedata(out dest); +begin + int64(dest):= value; +end; +{ +procedure tcustomint64edit.setmin(const avalue: int64); +begin + fmin:= avalue; + if fdatalist <> nil then begin + with tgridint64datalist(fdatalist) do begin + min:= avalue + end; + end; +end; + +procedure tcustomint64edit.setmax(const avalue: int64); +begin + fmax:= avalue; + if fdatalist <> nil then begin + with tgridint64datalist(fdatalist) do begin + max:= avalue + end; + end; +end; + +procedure tcustomint64edit.updatedatalist; +begin + with tgridint64datalist(fdatalist) do begin + min:= self.min; + max:= self.max; + end; +end; +} + +{ tkeystringdropdowncontroller } + +constructor tkeystringdropdowncontroller.create(const intf: idropdownlist); +begin + inherited; + options:= defaultkeystringdropdownoptions; + cols.count:= 2; + valuecol:= 1; + cols[1].options:= cols[1].options + [co_invisible]; +end; + +function tkeystringdropdowncontroller.getindex(const akey: msestring): integer; + //todo: non linear search +var + int1: integer; + po1: pmsestringaty; +begin + result:= -1; + with cols[valuecol] do begin + po1:= datapo; + for int1:= 0 to count - 1 do begin + if po1^[int1] = akey then begin + result:= int1; + break; + end; + end; + end; +end; + +{ tcustomkeystringedit } + +procedure tcustomkeystringedit.setvalue(const avalue: msestring); +begin + with tkeystringdropdowncontroller(fdropdown) do begin + with tdropdowncols1(cols) do begin + fitemindex:= getindex(avalue); + if fitemindex >= 0 then begin + fkeyvalue:= avalue; + end; + end; + end; + fvalue1:= avalue; + valuechanged; +end; + +procedure tcustomkeystringedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readmsestring(valuevarname,value); +end; + +procedure tcustomkeystringedit.writestatvalue(const writer: tstatwriter); +begin + writer.writemsestring(valuevarname,value); +end; + +function tcustomkeystringedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tkeystringdropdowncontroller.create(idropdownlist(self)); +end; + +procedure tcustomkeystringedit.texttovalue(var accept: boolean; + const quiet: boolean); +var + mstr1: msestring; + int1: integer; +begin + with tdropdownlistcontroller(fdropdown) do begin + int1:= itemindex; + if (int1 >= 0) and (text <> '') then begin +// mstr1:= cols[valuecol][int1]; + mstr1:= tdropdowncols1(cols).fkeyvalue; + end + else begin + mstr1:= ''; + end; + end; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + if not quiet then begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,mstr1,accept); + end; +{$ifdef mse_with_ifi} + ifisetvalue(mstr1,accept); +{$endif} + end; + if accept then begin + value:= mstr1; + end; + if int1 < 0 then begin + text:= ''; //for setnullvalue + end; +end; + +procedure tcustomkeystringedit.setnullvalue; +begin + dropdown.itemindex:= -1; + nullvalueset(); +end; + +function tcustomkeystringedit.internaldatatotext(const data): msestring; +var + int1: integer; +begin + with tkeystringdropdowncontroller(fdropdown) do begin + if @data = nil then begin + int1:= itemindex; + if int1 = -3 then begin + int1:= getindex(fvalue1); + tdropdowncols1(cols).fitemindex:= int1; + end; + end + else begin + int1:= getindex(msestring(data)); + end; + if int1 >= 0 then begin + result:= cols[0][int1]; + end + else begin + result:= ''; + end; + end; +end; + +procedure tcustomkeystringedit.texttodata(const atext: msestring; var data); +begin + //not supported +end; + +//function tcustomkeystringedit.getdefaultvalue: pointer; +//begin +// result:= @fvaluedefault; +//end; + +procedure tcustomkeystringedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue1); +end; + +procedure tcustomkeystringedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue1); + tdropdowncols1(tkeystringdropdowncontroller(fdropdown).cols).fitemindex:= -3; + valuetotext; +end; + +procedure tcustomkeystringedit.loaded; +begin + inherited; + if canevent(tmethod(foninit)) then begin + foninit(self); + end; +end; + +procedure tcustomkeystringedit.setvaluedata(const source); +begin + value:= msestring(source); +end; + +procedure tcustomkeystringedit.getvaluedata(out dest); +begin + msestring(dest):= value; +end; + +{ tcustomenuedit } + +constructor tcustomenuedit.create(aowner: tcomponent); +begin + fvalue1:= -1; + fvaluedefault1:= -1; + fvalueempty:= -1; + fbase:= nb_dec; + fbitcount:= 32; + fvaluemin:= -1; + fvaluemax:= maxint; + inherited; +end; + +function getindex1(const avalue: integer; + const enums: integerarty; const offset: integer): integer; +var + int1: integer; +begin + if enums <> nil then begin + result:= -1; + for int1:= 0 to high(enums) do begin + if avalue = enums[int1] then begin + result:= int1; + break; + end; + end; + end + else begin + result:= avalue - offset; + if result < 0 then begin + result:= -1; + end; + end; +end; + +function tcustomenuedit.getindex(avalue: integer): integer; +begin + if avalue = fvalueempty then begin + result:= -1; + end + else begin + result:= getindex1(avalue,enums,fvalueoffset); + if result < 0 then begin + result:= -1; + end; + end; +end; + +procedure tcustomenuedit.texttodata(const atext: msestring; var data); +begin + //not supported +end; + +function tcustomenuedit.internaldatatotext(const data): msestring; +var + int1,int2: integer; +begin + with tdropdownlistcontroller(fdropdown) do begin + if @data = nil then begin + int1:= fvalue1; + end + else begin + int1:= integer(data); + end; + int2:= getindex(int1); + if (int2 < 0) or (int2 >= valuelist.count) then begin + if not (deo_selectonly in options) and (int1 <> fvalueempty) then begin + result:= msestring(intvaluetostr(int1,fbase,fbitcount)); + end + else begin + result:= ''; + end; + end + else begin + result:= valuelist[int2]; + end; + end; +end; + +function tcustomenuedit.enumname(const avalue: integer): msestring; +begin + result:= datatotext(avalue); +end; + +procedure tcustomenuedit.clear; +begin + enums:= nil; + tdropdownlistcontroller(fdropdown).cols.clear; +end; + +function tcustomenuedit.addrow(const aitems: array of msestring; + const enum: integer = -1): integer; //returns itemindex + //enum = -1 -> no enum set +var + int1,int2: integer; +begin + result:= tdropdownlistcontroller(fdropdown).cols.addrow(aitems); + if enum >= 0 then begin + int1:= length(enums); + if int1 <= result then begin + setlength(enums,result+1); + for int2:= int1 to result-1 do begin + enums[int2]:= -1; + end; + end; + enums[result]:= enum; + end; +end; + +procedure tcustomenuedit.fillcol(const avalue: integer); +begin + internalfillcol(avalue); +end; + +function tcustomenuedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridenumdatalist.create(sender); +end; + +function tcustomenuedit.getdatalistclass: datalistclassty; +begin + result:= tgridenumdatalist; +end; + +procedure tcustomenuedit.setvalue(const avalue: integer); +begin + tdropdowncols1(tcustomdropdownlistcontroller(fdropdown).cols).fitemindex:= + getindex(avalue); + fvalue1:= avalue; + valuechanged; +end; + +function tcustomenuedit.getgridvalue(const index: integer): integer; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomenuedit.setgridvalue(const index, aValue: integer); +begin + internalsetgridvalue(index,avalue); +end; + +function tcustomenuedit.getgridvalues: integerarty; +begin + result:= tintegerdatalist(checkgriddata).asarray; +// result:= tintegerdatalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tcustomenuedit.setgridvalues(const avalue: integerarty); +begin + tintegerdatalist(checkgriddata).asarray:= avalue; +// tintegerdatalist(fgridintf.getcol.datalist).asarray:= avalue; +end; + +function tcustomenuedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault1; +end; + +procedure tcustomenuedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue1); + valuetotext; +end; + +procedure tcustomenuedit.texttovalue(var accept: boolean; const quiet: boolean); +var + int1: integer; + mstr1: msestring; +begin + if (tdropdownlistcontroller(fdropdown).itemindex < 0) and + (trim(text) = '') then begin + int1:= fvalueempty; + end + else begin + int1:= tdropdownlistcontroller(fdropdown).itemindex; + if (int1 >= 0) and (int1 <= high(enums)) then begin + int1:= enums[int1]; + end + else begin + if int1 >= 0 then begin + int1:= int1 + fvalueoffset; + end + else begin + if not (deo_selectonly in fdropdown.options) and + not (des_isdb in fstate) then begin + try + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + int1:= strtointvalue(mstr1,fbase); + except + accept:= false; + formaterror(quiet); + end; + end; + end; + end; + end; + if not ({(des_isdb in fstate) and} (int1 = fvalueempty)) and + (int1 < fvaluemin) or (int1 > fvaluemax) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetvalue1)) then begin + fonsetvalue1(self,int1,accept); + end; + {$ifdef mse_with_ifi} + ifisetvalue(int1,accept); + {$endif} + end; + if accept then begin + value:= int1; + end; + end; +end; + +procedure tcustomenuedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue1); +end; + +procedure tcustomenuedit.readstatvalue(const reader: tstatreader); +var + min1,max1: integer; +begin +// if fgridintf <> nil then begin +// fgridintf.getcol.dostatread(reader); +// end +// else begin + if enums <> nil then begin + min1:= fvaluemin; + max1:= fvaluemax; + end + else begin + if deo_forceselect in fdropdown.options then begin + min1:= 0; + end + else begin + min1:= fvalueempty; + end; + with tenumdropdowncontroller(fdropdown) do begin + max1:= cols[valuecol].count - 1; + end; + end; + value:= reader.readinteger(valuevarname,value,min1,max1); +// end; +end; + +procedure tcustomenuedit.writestatvalue(const writer: tstatwriter); +begin + writer.writeinteger(valuevarname,value); +end; + +function tcustomenuedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tenumdropdowncontroller.create(idropdownlist(self)); +end; + +procedure tcustomenuedit.internalsort(const acol: integer; + out sortlist: integerarty); +var + enum1: integerarty; + int1: integer; +begin + tdropdownlistcontroller(fdropdown).cols.beginupdate; + try + inherited internalsort(acol,sortlist); + if enums <> nil then begin + setlength(enum1,length(sortlist)); + for int1:= 0 to high(enum1) do begin + if sortlist[int1] > high(enums) then begin + enum1[int1]:= -1; + end + else begin + enum1[int1]:= enums[sortlist[int1]]; + end; + end; + enums:= enum1; + end; + finally + tdropdownlistcontroller(fdropdown).cols.endupdate; + end; +end; + +procedure tcustomenuedit.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase:= avalue; + formatchanged; + end; +end; + +procedure tcustomenuedit.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount:= avalue; + formatchanged; + end; +end; + +procedure tcustomenuedit.setvalueoffset(avalue: integer); +begin + if avalue < 0 then begin + avalue:= 0; + end; + if avalue <> fvalueoffset then begin + fvalueoffset:= avalue; + value:= value; //update itemindex + end; +end; + +procedure tcustomenuedit.assigncol(const avalue: tintegerdatalist); +begin + internalassigncol(avalue); +end; + +function tcustomenuedit.getvalueempty: integer; +begin + result:= fvalueempty; +end; + +function tcustomenuedit.textcellcopy: boolean; +begin + result:= false; +end; + +{$ifdef mse_with_ifi} +function tcustomenuedit.getifilink: tifienumlinkcomp; +begin + result:= tifienumlinkcomp(fifilink); +end; + +procedure tcustomenuedit.setifilink1(const avalue: tifienumlinkcomp); +begin + setifilink0(avalue); +end; +{$endif} + +procedure tcustomenuedit.setvaluemin(const avalue: integer); +begin + fvaluemin:= avalue; + if fdatalist <> nil then begin + with tgridenumdatalist(fdatalist) do begin + min:= avalue; + end; + end; +end; + +procedure tcustomenuedit.setvaluemax(const avalue: integer); +begin + fvaluemax:= avalue; + if fdatalist <> nil then begin + with tgridenumdatalist(fdatalist) do begin + max:= avalue; + end; + end; +end; + +procedure tcustomenuedit.updatedatalist; +begin + with tgridenumdatalist(fdatalist) do begin + min:= self.valuemin; + max:= self.valuemax; + end; +end; + +procedure tcustomenuedit.paintimage(const canvas: tcanvas); +var + int1: integer; +begin + with tcustomdropdownlistcontroller1(fdropdown) do begin + if imagelist <> nil then begin + int1:= value; + if canvas.drawinfopo <> nil then begin + with cellinfoty(canvas.drawinfopo^) do begin + int1:= pinteger(datapo)^; + end; + end; + imagelist.paint(canvas,int1, + deflaterect(clientrect,fimageframe),[al_ycentered]); + end; + end; +end; + +procedure tcustomenuedit.readmin(reader: treader); +begin + valuemin:= reader.readinteger; +end; + +procedure tcustomenuedit.readmax(reader: treader); +begin + valuemax:= reader.readinteger; +end; + +procedure tcustomenuedit.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +function tcustomenuedit.getdropdown: tenumdropdowncontroller; +begin + result:= tenumdropdowncontroller(fdropdown); +end; + +procedure tcustomenuedit.setdropdown(const avalue: tenumdropdowncontroller); +begin + fdropdown.assign(avalue); +end; + +function tcustomenuedit.griddata: tgridenumdatalist; +begin + checkgrid(); + result:= tgridenumdatalist(fdatalist); +end; + +procedure tcustomenuedit.setnullvalue; +begin + dropdown.itemindex:= -1; + nullvalueset(); +end; + +function tcustomenuedit.sortfunc(const l; const r): integer; +begin +// result:= tdatalist1(twidgetcol1(fgridintf.getcol).fdata).compare(l,r); + result:= tdatalist1(fdatalist).compare(l,r); +end; + +procedure tcustomenuedit.setvaluedata(const source); +begin + value:= integer(source); +end; + +procedure tcustomenuedit.getvaluedata(out dest); +begin + integer(dest):= value; +end; + +{ tnocolsenumdropdowncontroller } + +constructor tnocolsenumdropdowncontroller.create(const intf: idropdownlist); +begin + inherited; + options:= defaultenumdropdownoptions; +end; + +procedure tnocolsenumdropdowncontroller.readitemindex(reader: treader); +begin + reader.readinteger; //dummy +end; + +procedure tnocolsenumdropdowncontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('itemindex',{$ifdef FPC}@{$endif}readitemindex, + nil,false); +end; + +{ tcustomenumedit } + +procedure tcustomenumedit.loaded; +begin + inherited; + if canevent(tmethod(foninit)) then begin + foninit(self); + end; +end; + +{ tenumtypeedit } + +procedure tenumtypeedit.setoninit(const aValue: enumtypeediteventty); +begin + foninit:= enumediteventty(avalue); +end; + +function tenumtypeedit.getoninit: enumtypeediteventty; +begin + result:= enumtypeediteventty(foninit); +end; + +procedure tenumtypeedit.settypeinfopo(const avalue: ptypeinfo); +begin + if avalue <> ftypeinfopo then begin + if avalue <> nil then begin + dropdown.cols[dropdown.valuecol].asarray:= getenumnames(avalue); + end + else begin + dropdown.cols[dropdown.valuecol].clear; + end; + formatchanged; + end; +end; + +{ tcustomselector } + +constructor tcustomselector.create(aowner: tcomponent); +begin + inherited; + fdropdownitems:= tdropdowndatacols.create( + tcustomdropdownlistcontroller(fdropdown)); +// inherited; +end; + +destructor tcustomselector.destroy; +begin + inherited; + fdropdownitems.Free; +end; + +procedure tcustomselector.dobeforedropdown; +begin + inherited; + fdropdownenums:= copy(enums); + getdropdowninfo(fdropdownenums,fdropdownitems); + tdropdowncols1(dropdown.cols).fitemindex:= + getindex1(fvalue1,fdropdownenums,fvalueoffset); +end; + +function tcustomselector.getdropdownitems: tdropdowndatacols; +begin + result:= fdropdownitems; +end; + +procedure tcustomselector.texttovalue(var accept: boolean; const quiet: boolean); +var + int1: integer; +begin + with tdropdownlistcontroller(fdropdown) do begin + if (trim(text) = '') or (itemindex < 0) or + (itemindex >= length(fdropdownenums)) and (length(fdropdownenums) <> 0) then begin + int1:= -1; + end + else begin + if length(fdropdownenums) = 0 then begin + int1:= itemindex + fvalueoffset; + end + else begin + int1:= fdropdownenums[itemindex]; + end; + end; + fdropdownenums:= nil; + if not quiet then begin + if canevent(tmethod(fonsetvalue1)) then begin + fonsetvalue1(self,int1,accept); + end; + {$ifdef mse_with_ifi} + ifisetvalue(int1,accept); + {$endif} + end; + if accept then begin + value:= int1; + end; + end; +end; + +{ tselector } + +procedure tselector.getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); +begin + if canevent(tmethod(fongetdropdowninfo)) then begin + fongetdropdowninfo(self) + end; +end; + +procedure tselector.loaded; +begin + inherited; + if canevent(tmethod(foninit)) then begin + foninit(self); + end; +end; + +procedure tselector.setdropdownitems(const avalue: tdropdowndatacols); +begin + fdropdownitems.Assign(avalue); +end; + +{ tcustomrealedit } + +constructor tcustomrealedit.create(aowner: tcomponent); +begin + fvalue:= emptyreal; + fvaluedefault:= emptyreal; + fvaluemin:= emptyreal; + fvaluemax:= bigreal; + fvaluerange:= 1; + inherited; + include(foptionswidget,ow_mousewheel); +end; +{ +function tcustomrealedit.griddata: trealdatalist; +begin + checkgrid; + result:= trealdatalist(fdatalist); +end; +} +procedure tcustomrealedit.setformatdisp(const Value: msestring); +begin + fformatdisp := Value; + formatchanged; +end; + +procedure tcustomrealedit.setformatedit(const Value: msestring); +begin + fformatedit := Value; + formatchanged; +end; + +function tcustomrealedit.internaldatatotext(const data): msestring; +var + rea1: real; +begin + if @data = nil then begin + rea1:= fvalue; + end + else begin + rea1:= realty(data); + end; + if (@data = nil) and focused then begin + result:= realtytostrrange(rea1,fformatedit,fvaluerange,fvaluestart); + end + else begin + result:= realtytostrrange(rea1,fformatdisp,fvaluerange,fvaluestart); + end; +end; + +function tcustomrealedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridrealdatalist.create(sender); +end; + +function tcustomrealedit.getdatalistclass: datalistclassty; +begin + result:= tgridrealdatalist; +end; + +procedure tcustomrealedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomrealedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomrealedit.setvalue(const Value: realty); +begin + fvalue := Value; + valuechanged; +end; + +function tcustomrealedit.gettextvalue(var accept: boolean; + const quiet: boolean): realty; +var + mstr1: msestring; +begin + try + if focused then begin + mstr1:= text; + end + else begin + mstr1:= realtytostrrange(fvalue,fformatedit,fvaluerange,fvaluestart) + end; + checktext(mstr1,accept); + if not accept then begin + result:= emptyreal; //compiler warning + exit; + end; + result:= strtorealty(mstr1); + except + formaterror(quiet); + accept:= false + end; +end; + +procedure tcustomrealedit.texttovalue(var accept: boolean; const quiet: boolean); +var + rea1,rea2: realty; + str1: msestring; + int1: integer; +begin + rea1:= gettextvalue(accept,quiet); + if accept then begin + str1:= realtytostring(rea1,fformatedit); + if trystrtorealty(str1,rea2) then begin //round to editformat + rea1:= rea2; + end; +{ + try + rea2:= strtorealty(str1); //round to editformat + rea1:= rea2; + except + end; +} + rea1:= reapplyrange(rea1,fvaluerange,fvaluestart); + if not (((des_isdb in fstate) or (oe_null in foptionsedit)) and + (rea1 = emptyreal)) then begin + if (cmprealty(fvaluemin,rea1) > 0) or + (cmprealty(fvaluemax,rea1) < 0) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end; + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetintvalue)) then begin + int1:= realtytoint(rea1); + fonsetintvalue(self,int1,accept); + rea1:= inttorealty(int1); + end + else begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,rea1,accept); + end; + end; + {$ifdef mse_with_ifi} + ifisetvalue(rea1,accept); + {$endif} + end; + if accept then begin + value:= rea1; + end; + end; + end; +end; + +procedure tcustomrealedit.texttodata(const atext: msestring; var data); +var + rea1: realty; +begin + try + rea1:= reapplyrange(strtorealty(atext),fvaluerange,fvaluestart); + except + rea1:= emptyreal; + end; + if cmprealty(fvaluemin,rea1) > 0 then begin + rea1:= fvaluemin; + end; + if cmprealty(fvaluemax,rea1) < 0 then begin + rea1:= fvaluemax; + end; + realty(data):= rea1; +end; + +procedure tcustomrealedit.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; + +procedure tcustomrealedit.readvaluedefault(reader: treader); +begin + valuedefault:= readrealty(reader); +end; + +procedure tcustomrealedit.readmin1(reader: treader); +begin + fvaluemin:= readrealty(reader); +end; + +procedure tcustomrealedit.readmax1(reader: treader); +begin + fvaluemax:= readrealty(reader); +end; + +procedure tcustomrealedit.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tcustomrealedit.readmin(reader: treader); +begin + valuemin:= reader.readfloat; +end; + +procedure tcustomrealedit.readmax(reader: treader); +begin + valuemax:= reader.readfloat; +end; + +procedure tcustomrealedit.defineproperties(filer: tfiler); +//var +// bo1,bo2{,bo3,bo4}: boolean; +begin + inherited; + + filer.DefineProperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); + filer.DefineProperty('mi',{$ifdef FPC}@{$endif}readmin1,nil,false); + filer.DefineProperty('ma',{$ifdef FPC}@{$endif}readmax1,nil,false); + filer.DefineProperty('def',{$ifdef FPC}@{$endif}readvaluedefault,nil,false); + filer.defineproperty('valuescale',@readvaluescale,nil,false); + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +procedure tcustomrealedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readreal(valuevarname,value,fvaluemin,fvaluemax, + oe_null in foptionsedit); +end; + +procedure tcustomrealedit.writestatvalue(const writer: tstatwriter); +begin + writer.writereal(valuevarname,value); +end; + +function tcustomrealedit.getgridvalue(const index: integer): realty; +begin + internalgetgridvalue(index,result); +end; + +function tcustomrealedit.getgridintvalue(const index: integer): integer; +var + rea1: realty; +begin + internalgetgridvalue(index,rea1); + result:= realtytoint(rea1); +end; + +procedure tcustomrealedit.setgridvalue(const index: integer; + const avalue: realty); +begin + internalsetgridvalue(index,avalue); +end; + +procedure tcustomrealedit.setgridintvalue(const index: integer; + const avalue: integer); +var + rea1: realty; +begin + rea1:= inttorealty(avalue); //avoid FPC crash + internalsetgridvalue(index,rea1); +end; + +function tcustomrealedit.getgridvalues: realarty; +begin + result:= trealdatalist(checkgriddata).asarray; +// result:= trealdatalist(fgridintf.getcol.datalist).asarray; +end; + +function tcustomrealedit.getgridintvalues: integerarty; +var + ar1: realarty; + int1: integer; +begin + ar1:= trealdatalist(checkgriddata).asarray; + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= realtytoint(ar1[int1]); + end; +end; + +procedure tcustomrealedit.setgridvalues(const avalue: realarty); +begin + trealdatalist(checkgriddata).asarray:= avalue; +// trealdatalist(fgridintf.getcol.datalist).asarray:= avalue; +end; + +procedure tcustomrealedit.setgridintvalues(const avalue: integerarty); +var + ar1: realarty; + int1: integer; +begin + setlength(ar1,length(avalue)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= inttorealty(avalue[int1]); + end; + trealdatalist(checkgriddata).asarray:= ar1; +end; + +procedure tcustomrealedit.setvaluerange(const avalue: real); +begin + if fvaluerange <> avalue then begin + fvaluerange:= avalue; + valuetotext; + end; +end; + +procedure tcustomrealedit.setvaluestart(const avalue: real); +begin + if fvaluestart <> avalue then begin + fvaluestart:= avalue; + valuetotext; + end; +end; + +procedure tcustomrealedit.fillcol(const value: realty); +begin + internalfillcol(value); +end; + +procedure tcustomrealedit.assigncol(const value: trealdatalist); +begin + internalassigncol(value); +end; + +function tcustomrealedit.getasinteger: integer; +begin + result:= realtytoint(value); +end; + +procedure tcustomrealedit.setasinteger(const avalue: integer); +begin + value:= inttorealty(avalue); +end; + +function tcustomrealedit.getascurrency: currency; +begin + if isnull then begin + result:= 0; + end + else begin + result:= value; + end; +end; + +procedure tcustomrealedit.setascurrency(const avalue: currency); +begin + value:= avalue; +end; + +function tcustomrealedit.isnull: boolean; +begin + result:= value = emptyreal; +end; + +function tcustomrealedit.getasstring: msestring; +begin + result:= doubletostring(value); +end; + +procedure tcustomrealedit.setasstring(const avalue: msestring); +begin + value:= strtorealtydot(avalue); +end; + +{$ifdef mse_with_ifi} + +function tcustomrealedit.getifilink: tifireallinkcomp; +begin + result:= tifireallinkcomp(fifilink); +end; + +procedure tcustomrealedit.setifilink(const avalue: tifireallinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +function tcustomrealedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +procedure tcustomrealedit.setvaluemin(const avalue: realty); +begin + fvaluemin:= avalue; + if fdatalist <> nil then begin + with tgridrealdatalist(fdatalist) do begin + min:= avalue; + end; + end; +end; + +procedure tcustomrealedit.setvaluemax(const avalue: realty); +begin + fvaluemax:= avalue; + if fdatalist <> nil then begin + with tgridrealdatalist(fdatalist) do begin + max:= avalue; + end; + end; +end; + +procedure tcustomrealedit.updatedatalist; +begin + with tgridrealdatalist(fdatalist) do begin + min:= self.valuemin; + max:= self.valuemax; + updateeditoptions(foptionsedit); + end; +end; + +function tcustomrealedit.getintvalue: integer; +begin + result:= realtytoint(value); +end; + +procedure tcustomrealedit.setintvalue(const avalue: integer); +begin + value:= avalue; +end; + +function tcustomrealedit.griddata: tgridrealdatalist; +begin + result:= tgridrealdatalist(inherited griddata); +end; + +procedure tcustomrealedit.setnullvalue; +begin + value:= emptyreal; + nullvalueset(); +end; + +procedure tcustomrealedit.updatereadonlystate(); +begin + inherited; + if fdatalist <> nil then begin + tgridrealdatalist(fdatalist).updateeditoptions(foptionsedit); + //for acceptempty + end; +end; + +procedure tcustomrealedit.setvaluedata(const source); +begin + value:= realty(source); +end; + +procedure tcustomrealedit.getvaluedata(out dest); +begin + realty(dest):= value; +end; + +{ tspineditframe } + +constructor tspineditframe.create(const aintf: icaptionframe; + const stepintf: istepbar); +begin + include(fstepstate,sfs_spinedit); + inherited; + fi.levelo:= -2; + inflateframe1(fi.innerframe,1); + fforcevisiblebuttons:= [sk_up,sk_down]; + fforceinvisiblebuttons:= []; + internalupdatestate; +end; + +function tspineditframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + +procedure tspineditframe.setbuttonsvisible(const avalue: stepkindsty); +begin + inherited buttonsvisible:= avalue * spinstepbuttons; +end; + +{ tcustomrealspinedit } + +constructor tcustomrealspinedit.create(aowner: tcomponent); +begin + fstep:= 1; + fwheelsensitivity:= 1; + inherited; +end; + +procedure tcustomrealspinedit.internalcreateframe; +begin + tspineditframe.create(iscrollframe(self),istepbar(self)); +end; + +function tcustomrealspinedit.gettextvalue(var accept: boolean; + const quiet: boolean): realty; + function initvalue: realty; + begin + result:= 0; + if result < fvaluemin then begin + result:= fvaluemin; + end; + if result > fvaluemax then begin + result:= fvaluemax; + end; + end; + +label + endlab,endlab1; +begin + case fstepflag of + sk_last: begin + result:= fvaluemax; + end; + sk_first: begin + result:= fvaluemin; + end; + sk_up: begin + result:= fvalue; + if fvalue = emptyreal then begin + result:= initvalue; + goto endlab; + end; + result:= result + fstep*fstepfact; + end; + sk_down: begin + result:= fvalue; + if fvalue = emptyreal then begin + result:= initvalue; + goto endlab; + end; + result:= result - fstep*fstepfact; + end; + else begin + result:= inherited gettextvalue(accept,quiet); + goto endlab1; + end; + end; +endlab: + if result < fvaluemin then begin + result:= fvaluemin; + end; + if result > fvaluemax then begin + result:= fvaluemax; + end; +endlab1: + fstepflag:= stepkindty(-1); +end; + +function tcustomrealspinedit.dostep(const event: stepkindty; + const adelta: real; ashiftstate: shiftstatesty): boolean; +begin + result:= false; + if not (csdesigning in componentstate) then begin + if event in [sk_up,sk_down,sk_first,sk_last] then begin + result:= true; + if edited then begin + if not checkvalue then begin + exit; + end; + end; + fstepflag:= event; + if (adelta = 0) or (application.mousewheeldeltamin <= 0) then begin + fstepfact:= 1; + end + else begin + fstepfact:= round(0.03 * fwheelsensitivity * + abs(adelta/application.mousewheeldeltamin)); + end; + if fstepfact < 1 then begin + fstepfact:= 1; + end; + ashiftstate:= ashiftstate * keyshiftstatesmask; + if (ashiftstate = [ss_ctrl]) and (fstepctrlfact <> 0) then begin + fstepfact:= fstepfact * fstepctrlfact; + end + else begin + if (ashiftstate = [ss_shift]) and (fstepshiftfact <> 0) then begin + fstepfact:= fstepfact * fstepshiftfact; + end; + end; + checkvalue; + end; + end; +end; + +procedure tcustomrealspinedit.mouseevent(var info: mouseeventinfoty); +begin + tspineditframe(fframe).mouseevent(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +function tcustomrealspinedit.getframe: tspineditframe; +begin + result:= tspineditframe(pointer(inherited frame)); +end; + +procedure tcustomrealspinedit.setframe(const avalue: tspineditframe); +begin + inherited frame:= tcaptionframe(pointer(avalue)); +end; + +procedure tcustomrealspinedit.domousewheelevent(var info: mousewheeleventinfoty); +begin + tspineditframe(fframe).domousewheelevent(info); + inherited; +end; + +procedure tcustomrealspinedit.updatebuttonstate(); +begin + if fframe <> nil then begin + if readonly or not isenabled then begin + frame.disabledbuttons:= allstepkinds; + end + else begin + frame.disabledbuttons:= []; + end; + end; +end; + +procedure tcustomrealspinedit.updatereadonlystate; +begin + inherited; + updatebuttonstate(); +end; + +procedure tcustomrealspinedit.enabledchanged; +begin + inherited; + updatebuttonstate(); +end; + +procedure tcustomrealspinedit.dokeydown(var info: keyeventinfoty); +var + shiftstate1: shiftstatesty; +begin + with info do begin + if ((shiftstate * keyshiftstatesmask) - [ss_shift,ss_alt,ss_ctrl] = []) and + (ss_alt in shiftstate) and not readonly and + not (es_processed in eventstate) then begin + include(eventstate,es_processed); + shiftstate1:= shiftstate - [ss_alt]; + case key of + key_up: begin + dostep(sk_up,0,shiftstate1); + end; + key_down: begin + dostep(sk_down,0,shiftstate1); + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +{ tcustomdatetimeedit } + +constructor tcustomdatetimeedit.create(aowner: tcomponent); +begin + fvalue:= emptydatetime; + fvaluedefault:= emptydatetime; + fvaluemin:= emptydatetime; + fvaluemax:= bigdatetime; + inherited; +end; + +procedure tcustomdatetimeedit.setvalue(const Value: tdatetime); +begin + fvalue := Value; + valuechanged; +end; + +procedure tcustomdatetimeedit.setformatdisp(const Value: msestring); +begin + fformatdisp := Value; + formatchanged; +end; + +procedure tcustomdatetimeedit.setformatedit(const Value: msestring); +begin + fformatedit := Value; + formatchanged; +end; + +function tcustomdatetimeedit.getgridvalue(const index: integer): tdatetime; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomdatetimeedit.setgridvalue(const index: integer; const Value: tdatetime); +begin + internalsetgridvalue(index,value); +end; + +function tcustomdatetimeedit.getgridvalues: datetimearty; +begin + result:= datetimearty(trealdatalist(checkgriddata).asarray); +end; + +procedure tcustomdatetimeedit.setgridvalues(const Value: datetimearty); +begin + trealdatalist(checkgriddata).asarray:= realarty(value); +end; + +function tcustomdatetimeedit.checkkind(const avalue: tdatetime): tdatetime; +begin + if avalue = emptydatetime then begin + result:= avalue; + end + else begin + case fkind of + dtk_date: result:= trunc(avalue); + dtk_time: result:= frac(avalue); + else result:= avalue; + end; + end; +end; + +function tcustomdatetimeedit.gettextvalue(var accept: boolean; + const quiet: boolean): tdatetime; +var + mstr1: msestring; + bo1: boolean; +begin + mstr1:= text; + checktext(mstr1,accept); + if not accept then begin + result:= emptydatetime; //compiler warning + exit; + end; + bo1:= false; + case fkind of + dtk_time: begin + bo1:= trystringtotime(mstr1,fformatedit,result); + end; + dtk_date: begin + bo1:= trystringtodate(mstr1,fformatedit,result); + end; + else begin + bo1:= trystringtodatetime(mstr1,fformatedit,result); + end; + end; + if not bo1 then begin + formaterror(quiet); + accept:= false + end + else begin + checkdateconvert(fconvert,result); + end; +end; + +procedure tcustomdatetimeedit.texttovalue(var accept: boolean; + const quiet: boolean); +var + dat1: tdatetime; +// mstr1: msestring; +begin + dat1:= gettextvalue(accept,quiet); + if accept then begin + if not (((des_isdb in fstate) or (oe_null in foptionsedit)) and + (dat1 = emptydatetime)) then begin + if fkind = dtk_time then begin + if (fvaluemax = emptydatetime) and not (dat1 = emptydatetime) or + not (fvaluemin = emptydatetime) and (dat1 < frac(fvaluemin)) or + (dat1 > frac(fvaluemax)) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end + else begin + if (cmprealty(fvaluemin,dat1) > 0) or + (cmprealty(fvaluemax,dat1) < 0) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end; + end; + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,dat1,accept); + end; + {$ifdef mse_with_ifi} + ifisetvalue(dat1,accept); + {$endif} + end; + if accept then begin + value:= dat1; + end; + end; + end; +end; + +procedure tcustomdatetimeedit.texttodata(const atext: msestring; var data); +var + dat1: tdatetime; + bo1: boolean; +begin + if fkind = dtk_time then begin + bo1:= trystringtotime(atext,fformatedit,dat1,fconvert); + end + else begin + bo1:= trystringtodatetime(atext,fformatedit,dat1,fconvert); + end; + if not bo1 then begin + bo1:= trystrtorealty(atext,realty(dat1)); + if not bo1 then begin + dat1:= emptyreal; + end + else begin + checkdateconvert(fconvert,dat1); + end; + end; + if cmprealty(fvaluemin,dat1) > 0 then begin + dat1:= fvaluemin; + end; + if cmprealty(fvaluemax,dat1) < 0 then begin + dat1:= fvaluemax; + end; + tdatetime(data):= dat1; +end; + +function tcustomdatetimeedit.internaldatatotext(const data): msestring; +var + dat1: tdatetime; + mstr1: msestring; +begin + if @data = nil then begin + dat1:= fvalue; + end + else begin + dat1:= tdatetime(data); + end; + checkdatereconvert(fconvert,dat1); + if (@data = nil) and focused then begin + mstr1:= fformatedit; + end + else begin + mstr1:= fformatdisp; + end; + case fkind of + dtk_time: begin + result:= mseformatstr.timetostring(dat1,mstr1); + end; + dtk_date: begin + result:= mseformatstr.datetostring(dat1,mstr1); + end; + else begin + result:= mseformatstr.datetimetostring(dat1,mstr1); + end; + end; +end; + +function tcustomdatetimeedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridrealdatalist.create(sender); +end; + +function tcustomdatetimeedit.getdatalistclass: datalistclassty; +begin + result:= tgridrealdatalist; +end; + +procedure tcustomdatetimeedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomdatetimeedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomdatetimeedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readreal(valuevarname,value,fvaluemin,fvaluemax, + oe_null in foptionsedit); +end; + +procedure tcustomdatetimeedit.writestatvalue(const writer: tstatwriter); +begin + writer.writereal(valuevarname,value); +end; + +procedure tcustomdatetimeedit.fillcol(const value: tdatetime); +begin + internalfillcol(value); +end; + +procedure tcustomdatetimeedit.assigncol(const value: trealdatalist); +begin + internalassigncol(value); +end; + +procedure tcustomdatetimeedit.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +procedure tcustomdatetimeedit.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; + +procedure tcustomdatetimeedit.readvaluedefault(reader: treader); +begin + valuedefault:= readrealty(reader); +end; + +procedure tcustomdatetimeedit.readmin1(reader: treader); +begin + fvaluemin:= readrealty(reader); +end; + +procedure tcustomdatetimeedit.readmax1(reader: treader); +begin + fvaluemax:= readrealty(reader); +end; + +procedure tcustomdatetimeedit.readmin(reader: treader); +begin + valuemin:= reader.readfloat(); +end; + +procedure tcustomdatetimeedit.readmax(reader: treader); +begin + valuemax:= reader.readfloat(); +end; + + +procedure tcustomdatetimeedit.defineproperties(filer: tfiler); +begin + inherited; + + filer.DefineProperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); + filer.DefineProperty('mi',{$ifdef FPC}@{$endif}readmin1,nil,false); + filer.DefineProperty('ma',{$ifdef FPC}@{$endif}readmax1,nil,false); + filer.DefineProperty('def', + {$ifdef FPC}@{$endif}readvaluedefault,nil,false); + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +function tcustomdatetimeedit.isempty(const atext: msestring): boolean; +begin + result:= (atext <> ' ') and inherited isempty(atext); +end; + +function tcustomdatetimeedit.isnull: boolean; +begin + result:= value = emptydatetime; +end; +{ +function tcustomdatetimeedit.griddata: trealdatalist; +begin + result:= trealdatalist(fdatalist); +end; +} +{$ifdef mse_with_ifi} +function tcustomdatetimeedit.getifilink: tifidatetimelinkcomp; +begin + result:= tifidatetimelinkcomp(fifilink); +end; + +procedure tcustomdatetimeedit.setifilink(const avalue: tifidatetimelinkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +function tcustomdatetimeedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +procedure tcustomdatetimeedit.setoptions(const avalue: datetimeeditoptionsty); +{$ifndef FPC} +const + mask1: datetimeeditoptionsty = [dteo_showlocal,dteo_showutc]; +{$endif} +begin + if avalue <> foptions then begin + foptions:= datetimeeditoptionsty( + {$ifdef FPC} + setsinglebit(longword(avalue),longword(foptions), + longword([dteo_showlocal,dteo_showutc]))); + {$else} + setsinglebit(byte(avalue),byte(foptions),byte(mask1))); + {$endif} + fconvert:= dc_none; + if dteo_showutc in foptions then begin + fconvert:= dc_tolocal; + end; + if dteo_showlocal in foptions then begin + fconvert:= dc_toutc; + end; + formatchanged; + end; +end; + +procedure tcustomdatetimeedit.setvaluemin(const avalue: tdatetime); +begin + fvaluemin:= avalue; + if fdatalist <> nil then begin + with tgridrealdatalist(fdatalist) do begin + min:= avalue; + end; + end; +end; + +procedure tcustomdatetimeedit.setvaluemax(const avalue: tdatetime); +begin + fvaluemax:= avalue; + if fdatalist <> nil then begin + with tgridrealdatalist(fdatalist) do begin + max:= avalue; + end; + end; +end; + +procedure tcustomdatetimeedit.updatedatalist; +begin + with tgridrealdatalist(fdatalist) do begin + min:= self.valuemin; + max:= self.valuemax; + updateeditoptions(foptionsedit); + end; +end; + +function tcustomdatetimeedit.getshowlocal: boolean; +begin + result:= dteo_showlocal in foptions; +end; + +procedure tcustomdatetimeedit.setshowlocal(const avalue: boolean); +begin + if avalue then begin + options:= options + [dteo_showlocal]; + end + else begin + options:= options - [dteo_showlocal]; + end; +end; + +function tcustomdatetimeedit.getshowutc: boolean; +begin + result:= dteo_showutc in foptions; +end; + +procedure tcustomdatetimeedit.setshowutc(const avalue: boolean); +begin + if avalue then begin + options:= options + [dteo_showutc]; + end + else begin + options:= options - [dteo_showutc]; + end; +end; + +function tcustomdatetimeedit.griddata: tgridrealdatalist; +begin + result:= tgridrealdatalist(inherited griddata); +end; + +procedure tcustomdatetimeedit.setnullvalue; +begin + value:= emptydatetime; + nullvalueset(); +end; + +procedure tcustomdatetimeedit.updatereadonlystate(); +begin + inherited; + if fdatalist <> nil then begin + tgridrealdatalist(fdatalist).updateeditoptions(foptionsedit); + //for acceptempty + end; +end; + +function tcustomdatetimeedit.getassistiveflags: assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_datetime]; +end; + +procedure tcustomdatetimeedit.setvaluedata(const source); +begin + value:= tdatetime(source); +end; + +procedure tcustomdatetimeedit.getvaluedata(out dest); +begin + tdatetime(dest):= value; +end; + +{ tenumdropdowncontroller } + +constructor tenumdropdowncontroller.create(const intf: idropdownlist); +begin + inherited; + cols.nostreaming:= false; +end; + +{ tcustomrichmemoedit } + +function tcustomrichmemoedit.getformat: formatinfoarty; +begin + result:= fformat; +end; + +procedure tcustomrichmemoedit.setformat(const avalue: formatinfoarty); +begin + fformat:= copy(avalue); + feditor.format:= fformat; +// valuechanged(); +end; + +function tcustomrichmemoedit.getrichvalue(): richstringty; +begin + result.text:= value; + result.format:= fformat; + result.flags:= frichflags; +end; + +procedure tcustomrichmemoedit.setrichvalue(const avalue: richstringty); +begin + fformat:= copy(avalue.format); + frichflags:= avalue.flags; + value:= avalue.text; +end; + +procedure tcustomrichmemoedit.readrichvalue(reader: treader); +begin + richvalue:= readrichstring(reader); +end; + +procedure tcustomrichmemoedit.writerichvalue(writer: twriter); +begin + writerichstring(writer,richvalue); +end; + +procedure tcustomrichmemoedit.defineproperties(filer: tfiler); +var + b1: boolean; +begin + inherited; + if filer.ancestor <> nil then begin + b1:= isequalrichstring(tcustomrichmemoedit(filer.ancestor).richvalue, + richvalue); + end + else begin + b1:= not isemptyrichstring(richvalue); + end; + filer.defineproperty('richvalue',@readrichvalue,@writerichvalue,b1); +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msedataimage.pas b/mseide-msegui/lib/common/editwidgets/msedataimage.pas new file mode 100644 index 0000000..e0c9fc0 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msedataimage.pas @@ -0,0 +1,860 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedataimage; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseguiglob,msegui,mseimage,msewidgetgrid,msegrids,msedatalist, + msegraphutils,msedragglob, + msegraphics,mseclasses,mseeditglob,msebitmap,msemenus,mseevent, + msetypes{msestrings}, + msepointer,msegridsglob{$ifdef mse_with_ifi},mseificomp,mseifiglob{$endif}, + mseglob,msehash; + +type + imagecachedataty = record + data: pointer; + image: maskedimagety; + prev: int32; //offset from fdata + next: int32; //offset from fdata + end; + imagecachehashdataty = record + header: hashheaderty; + data: imagecachedataty; + end; + pimagecachehashdataty = ^imagecachehashdataty; + + timagecache = class(thashdatalist) + private + fmaxsize: int32; + fimagedatasize: int32; + ffirst: int32; //offset from fdata + flast: int32; //offset from fdata + protected + function getrecordsize(): int32 override; +// procedure inititem(const aitem: phashdataty) override; + procedure finalizeitem(const aitem: phashdataty) override; + function hashkey(const akey): hashvaluety override; + function checkkey(const akey; const aitem: phashdataty): boolean override; + public + constructor create(); + procedure clear() override; + function find(const adata: string; out aimage: maskedimagety): boolean; + procedure add(const adata: string; const aimage: maskedimagety); + procedure delete(const adata: string); + property maxsize: int32 read fmaxsize write fmaxsize; + end; + + tcustomdataimage = class(timage,igridwidget) + private + fonchange: notifyeventty; + fformat: string; + fgridsettingx: integer; + procedure checkgrid; + function getgridvalue(index: integer): string; + procedure setgridvalue(index: integer; const avalue: string); + procedure readvalue(stream: tstream); + procedure writevalue(stream: tstream); + function getcachesize: int32; + procedure setcachesize(const avalue: int32); +// function getvalue: string; + protected + fgridintf: iwidgetgrid; + fgriddatalink: pointer; + fvalue: string; //in design mode only + fcurformat: string; + feditstate: dataeditstatesty; + fcache: timagecache; +// procedure setisdb; + function geteditstate: dataeditstatesty; + procedure seteditstate(const avalue: dataeditstatesty); + function getgridintf: iwidgetgrid; + procedure defineproperties(filer: tfiler); override; + procedure setvalue(const avalue: string); virtual; + procedure setformat(const avalue: string); + procedure internaldrawcell(const canvas: tcanvas; const dest: rectty); + + //igridwidget + procedure initgridwidget; virtual; + function getoptionsedit: optionseditty; + procedure setfirstclick(var ainfo: mouseeventinfoty); + procedure setreadonly(const avalue: boolean); + function createdatalist(const sender: twidgetcol): tdatalist; virtual; + procedure datalistdestroyed; + function getdatalistclass: datalistclassty; + function getdefaultvalue: pointer; + function getrowdatapo(const arow: integer): pointer; virtual; + procedure setgridintf(const intf: iwidgetgrid); + function getcellframe: framety; + function needscellfocuspaint(): boolean; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; + procedure updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); + function getnulltext: msestring; + function getassistivecelltext(const arow: int32): msestring; + procedure loadcellbmp(const acanvas: tcanvas; + const abmp: tmaskedbitmap); virtual; + procedure drawcell(const canvas: tcanvas); + procedure updateautocellsize(const canvas: tcanvas); + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure valuetogrid(row: integer); virtual; + procedure gridtovalue(row: integer); virtual; + procedure setvaluedata(const source); virtual; + procedure getvaluedata(out dest); virtual; + procedure docellevent(const ownedcol: boolean; var info: celleventinfoty); virtual; + function sortfunc(const l,r): integer; virtual; + procedure gridvaluechanged(const index: integer); virtual; + procedure updatecoloptions(const aoptions: coloptionsty); + procedure updatecoloptions1(const aoptions: coloptions1ty); + procedure statdataread; virtual; + procedure griddatasourcechanged; virtual; + {$ifdef mse_with_ifi} + function getifilink: tifilinkcomp; + {$endif} + procedure setparentgridwidget(const intf: igridwidget); + procedure childdataentered(const sender: igridwidget); virtual; + procedure childfocused(const sender: igridwidget); virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + function seteditfocus: boolean; + procedure changed; override; + function actualcolor: colorty; override; + function loadfromstream(const astream: tstream): string; //returns format + function loadfromfile(const afilename: filenamety): string; //returns format + procedure storeimage(const aformat: string; const params: array of const); + //writes image data to value property + procedure drawimage(const canvas: tcanvas; const cellinfo: pcellinfoty; + const dest: rectty); + property value: string read fvalue{getvalue} write setvalue stored false; + property gridvalue[index: integer]: string read getgridvalue + write setgridvalue; default; + property format: string read fformat write setformat; + property cachesize: int32 read getcachesize + write setcachesize default 0; + //kibibyte + property onchange: notifyeventty read fonchange write fonchange; + end; + + tdataimage = class(tcustomdataimage) + published + property value; + property format; + property cachesize; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + +implementation +uses + msestream,sysutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsimplebitmap1 = class(tsimplebitmap); + tcustomwidgetgrid1 = class(tcustomwidgetgrid); + +{ timagecache } + +constructor timagecache.create(); +begin + inherited; + fstate:= fstate + [hls_needsfinalize]; +end; + +procedure timagecache.clear(); +begin + inherited; + fimagedatasize:= 0; + ffirst:= 0; + flast:= 0; +end; + +function timagecache.getrecordsize(): int32; +begin + result:= sizeof(imagecachehashdataty); +end; +{ +procedure timagecache.inititem(const aitem: phashdataty); +begin + initialize(pimagecachehashdataty(aitem)^); +end; +} +procedure timagecache.finalizeitem(const aitem: phashdataty); +begin + freeimage(pimagecachehashdataty(aitem)^.data.image); +end; + +function timagecache.hashkey(const akey): hashvaluety; +begin + result:= pointerhash(pointer(akey)); +end; + +function timagecache.checkkey(const akey; const aitem: phashdataty): boolean; +begin + result:= pointer(akey) = pimagecachehashdataty(aitem)^.data.data; +end; + +function timagecache.find(const adata: string; + out aimage: maskedimagety): boolean; +var + p1: pimagecachehashdataty; +begin + result:= false; + if fmaxsize > 0 then begin + p1:= pimagecachehashdataty(internalfind(pointer(adata))); + if p1 <> nil then begin + aimage:= p1^.data.image; + result:= true; + end; + end; +end; + +procedure timagecache.add(const adata: string; const aimage: maskedimagety); +var + i1: int32; + p1: pimagecachehashdataty; +begin + if (fmaxsize > 0) and (adata <> '') then begin + if (fimagedatasize > fmaxsize) and (ffirst <> 0) then begin + p1:= fdata+ffirst; + delete(string(p1^.data.data)); + end; + p1:= pimagecachehashdataty(internaladd(pointer(adata))); + p1^.data.data:= pointer(adata); + p1^.data.image:= aimage; + p1^.data.prev:= flast; + p1^.data.next:= 0; + i1:= pointer(p1)-fdata; + if ffirst = 0 then begin + ffirst:= i1; + end; + if flast <> 0 then begin + pimagecachehashdataty(fdata+flast)^.data.next:= i1; + end; + flast:= i1; + fimagedatasize:= fimagedatasize + (aimage.image.length+aimage.mask.length)*4; + end; +end; + +procedure timagecache.delete(const adata: string); +var + i1: int32; + p1: pimagecachehashdataty; +begin + if (fmaxsize > 0) and (adata <> '') then begin + p1:= pimagecachehashdataty(internalfind(pointer(adata))); + if p1 <> nil then begin + i1:= pointer(p1)-data; + if p1^.data.prev <> 0 then begin + pimagecachehashdataty(fdata+p1^.data.prev)^.data.next:= i1; + end; + if p1^.data.next <> 0 then begin + pimagecachehashdataty(fdata+p1^.data.next)^.data.prev:= i1; + end; + if i1 = ffirst then begin + ffirst:= p1^.data.next; + end; + if i1 = flast then begin + flast:= p1^.data.prev; + end; + fimagedatasize:= fimagedatasize - + (p1^.data.image.image.length+p1^.data.image.mask.length)*4; + internaldeleteitem(phashdataty(p1)); + end; + end; +end; + +{ tcustomdataimage } + +constructor tcustomdataimage.create(aowner: tcomponent); +begin + fcache:= timagecache.create(); + inherited; +{$warnings off} + include(tsimplebitmap1(bitmap).fstate,pms_nosave); +{$warnings on} +end; + +destructor tcustomdataimage.destroy(); +begin + inherited; + fcache.free; +end; + +procedure tcustomdataimage.setvalue(const avalue: string); +var + int1: integer; + str1: string; +begin + if pointer(fvalue) <> pointer(avalue) then begin + { + if pointer(avalue) <> pointer(fvalue) then begin + fcache.delete(fvalue); + end; + } + fvalue:= avalue; + try + fcurformat:= bitmap.loadfromstring(avalue,fformat,[]); + except + fcurformat:= ''; + bitmap.clear; + end; + if (fgridintf <> nil) and not (csdesigning in componentstate) and + (fgridsettingx = 0) then begin + int1:= fgridintf.getrow(); + fgridintf.getdata(int1,str1); + fgridintf.setdata(int1,avalue,false); + if pointer(avalue) <> pointer(str1) then begin + fcache.delete(str1); + end; + end; + end; +// if csdesigning in componentstate then begin +// fvalue:= avalue; +// end; + changed; +end; +{ +procedure tcustomdataimage.setvalue(const avalue: string); +var + int1: integer; + str1: string; +begin + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + inc(fgridsetting); + try + int1:= -1; + fgridintf.getdata(int1,str1); + fgridintf.setdata(int1,avalue); + finally + dec(fgridsetting); + end; + end; + try + fcurformat:= bitmap.loadfromstring(avalue,fformat,[]); + except + fcurformat:= ''; + bitmap.clear; + end; + if csdesigning in componentstate then begin + fvalue:= avalue; + end; + changed; + if pointer(avalue) <> pointer(str1) then begin + fcache.delete(str1); + end; +end; +} +function tcustomdataimage.seteditfocus: boolean; +begin + if fgridintf = nil then begin + if canfocus then begin + setfocus; + end; + end + else begin + with fgridintf.getcol do begin + grid.col:= index; + if grid.canfocus then begin + if not focused then begin + grid.setfocus; + end; + end; + end; + end; + result:= focused; +end; + +procedure tcustomdataimage.changed; +begin + inherited; + if not (ws_loadedproc in fwidgetstate) and + canevent(tmethod(fonchange)) then begin + fonchange(self); + end; +end; + +procedure tcustomdataimage.setfirstclick(var ainfo: mouseeventinfoty); +begin + //dummy +end; + +function tcustomdataimage.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridbinarystringdatalist.create(sender); +end; + +function tcustomdataimage.getdatalistclass: datalistclassty; +begin + result:= tgridbinarystringdatalist; +end; + +function tcustomdataimage.getdefaultvalue: pointer; +begin + result:= nil; +end; + +function tcustomdataimage.getrowdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +procedure tcustomdataimage.setgridintf(const intf: iwidgetgrid); +begin + fgridintf:= intf; + if fgridintf <> nil then begin + fgriddatalink:= tcustomwidgetgrid1(fgridintf.getgrid).getgriddatalink; + end + else begin + fgriddatalink:= nil; + end; +end; + +function tcustomdataimage.getcellframe: framety; +begin + if fframe <> nil then begin + result:= fframe.cellframe; + end + else begin + result:= nullframe; + end; +end; + +function tcustomdataimage.needscellfocuspaint(): boolean; +begin + result:= inherited needsfocuspaint(); +end; + +function tcustomdataimage.getcellcursor(const arow: integer; + const acellzone: cellzonety; + const apos: pointty): cursorshapety; +begin + result:= actualcursor(nullpoint); +end; + +procedure tcustomdataimage.updatecellzone(const row: integer; + const apos: pointty; var result: cellzonety); +begin + //dummy +end; + +function tcustomdataimage.getnulltext: msestring; +begin + result:= ''; +end; + +function tcustomdataimage.getassistivecelltext(const arow: int32): msestring; +begin + result:= ''; +end; + +procedure tcustomdataimage.loadcellbmp(const acanvas: tcanvas; + const abmp: tmaskedbitmap); +var + image1: maskedimagety; +begin + with cellinfoty(acanvas.drawinfopo^) do begin + if fcache.maxsize > 0 then begin + if fcache.find(string(datapo^),image1) then begin + abmp.loadfrommaskedimage(image1); + end + else begin + abmp.loadfromstring(string(datapo^),fformat,[]); + abmp.savetomaskedimage(image1); + fcache.add(string(datapo^),image1); + end; + end + else begin + abmp.loadfromstring(string(datapo^),fformat,[]); + end; + end; +end; + +procedure tcustomdataimage.internaldrawcell(const canvas: tcanvas; + const dest: rectty); +var + bmp: tmaskedbitmap; + int1: integer; +begin + with cellinfoty(canvas.drawinfopo^) do begin + if (datapo <> nil) and (string(datapo^) <> '') then begin + bmp:= tmaskedbitmap.create(bitmap.kind); + try + with bitmap do begin + bmp.alignment:= alignment; + bmp.options:= options; + bmp.opacity:= opacity; + bmp.transparentcolor:= transparentcolor; + end; + loadcellbmp(canvas,bmp); + if calcautocellsize then begin + int1:= bmp.size.cx - innerrect.cx + rect.cx; + if int1 > autocellsize.cx then begin + autocellsize.cx:= int1; + end; + int1:= bmp.size.cy - innerrect.cy + rect.cy; + if int1 > autocellsize.cy then begin + autocellsize.cy:= int1; + end; + end + else begin + paintbmp(canvas,bmp,dest); + end; + except; + end; + bmp.free; + end; + end; +end; + +procedure tcustomdataimage.drawcell(const canvas: tcanvas); +begin + with cellinfoty(canvas.drawinfopo^) do begin + internaldrawcell(canvas,innerrect); + end; +end; + +procedure tcustomdataimage.drawimage(const canvas: tcanvas; + const cellinfo: pcellinfoty; const dest: rectty); +var + p1: pointer; + p2: pcellinfoty; + cellinfo1: cellinfoty; +begin + p2:= canvas.drawinfopo; + if cellinfo = nil then begin + canvas.drawinfopo:= @cellinfo1; + cellinfo1.cell.row:= fgridintf.getgrid.row; + cellinfo1.calcautocellsize:= false; + end + else begin + canvas.drawinfopo:= cellinfo; + end; + with pcellinfoty(canvas.drawinfopo)^ do begin + p1:= datapo; + datapo:= fgridintf.getdatapo(cell.row); + internaldrawcell(canvas,dest); + datapo:= p1; + end; + canvas.drawinfopo:= p2; +end; + +procedure tcustomdataimage.updateautocellsize(const canvas: tcanvas); +begin + drawcell(canvas); +end; + +procedure tcustomdataimage.valuetogrid(row: integer); +begin + //dummy +end; + +procedure tcustomdataimage.gridtovalue(row: integer); +var + str1: string; +begin +// if fgridsetting = 0 then begin +// if row <> -2 then begin //not default value + inc(fgridsettingx); + try + fgridintf.getdata(row,str1); + value:= str1; + finally + dec(fgridsettingx); + end; +// end; +// end; +end; + +procedure tcustomdataimage.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + //dummy +end; + +function tcustomdataimage.sortfunc(const l,r): integer; +begin + result:= 0; +end; + +procedure tcustomdataimage.gridvaluechanged(const index: integer); +begin + //dummy +end; + +procedure tcustomdataimage.updatecoloptions(const aoptions: coloptionsty); +begin + //dummy +end; + +procedure tcustomdataimage.updatecoloptions1(const aoptions: coloptions1ty); +begin + //dummy +end; + +procedure tcustomdataimage.statdataread; +begin + //dummy +end; + +procedure tcustomdataimage.griddatasourcechanged; +begin + //dummy +end; + +{$ifdef mse_with_ifi} +function tcustomdataimage.getifilink: tifilinkcomp; +begin + result:= nil; +end; +{$endif} + +function tcustomdataimage.getoptionsedit: optionseditty; +begin + result:= [oe_readonly]; +end; + +procedure tcustomdataimage.initgridwidget; +begin + defaultinitgridwidget(self,fgridintf); +end; + +procedure tcustomdataimage.setformat(const avalue: string); +begin + fformat:= avalue; +end; + +procedure tcustomdataimage.checkgrid; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; + if fgridintf.getcol = nil then begin + raise exception.Create('No datalist.'); + end; +end; + +function tcustomdataimage.getgridvalue(index: integer): string; +begin + checkgrid; + fgridintf.getdata(index,result); +end; + +function tcustomdataimage.geteditstate: dataeditstatesty; +begin + result:= feditstate; +end; + +procedure tcustomdataimage.seteditstate(const avalue: dataeditstatesty); +begin + feditstate:= avalue; +end; +{ +procedure tcustomdataimage.setisdb; +begin + //dummy +end; +} +procedure tcustomdataimage.setgridvalue(index: integer; + const avalue: string); +var + str1: string; +begin + checkgrid; + fgridintf.getdata(index,str1); + fgridintf.setdata(index,avalue); + fcache.delete(str1); +end; + +function tcustomdataimage.getgridintf: iwidgetgrid; +begin + result:= fgridintf; +end; + +procedure tcustomdataimage.beforecelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; + +procedure tcustomdataimage.aftercelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; + +procedure tcustomdataimage.setreadonly(const avalue: boolean); +begin + //dummy +end; + +procedure tcustomdataimage.readvalue(stream: tstream); +var + str1: string; + int1: integer; +begin + stream.readbuffer(int1,sizeof(integer)); + setlength(str1,int1); + stream.readbuffer(pointer(str1)^,int1); + value:= str1; +end; + +procedure tcustomdataimage.writevalue(stream: tstream); +var + int1: integer; +begin + int1:= length(fvalue); + stream.writebuffer(int1,sizeof(integer)); + stream.writebuffer(pointer(fvalue)^,int1); +end; + +function tcustomdataimage.getcachesize: int32; +begin + result:= fcache.maxsize; +end; + +procedure tcustomdataimage.setcachesize(const avalue: int32); +begin + fcache.maxsize:= avalue; + if avalue = 0 then begin + fcache.clear; + end; +end; +(* +function tcustomdataimage.getvalue: string; +//var +// i1: int32; +begin + result:= fvalue; +{ + result:= ''; + if fgridintf <> nil then begin + i1:= fgridintf.getgrid.row; + if i1 >= 0 then begin + result:= gridvalue[i1]; + end; + end; +} +end; +*) +procedure tcustomdataimage.defineproperties(filer: tfiler); +begin + inherited; + filer.definebinaryproperty('valuedata',{$ifdef FPC}@{$endif}readvalue, + {$ifdef FPC}@{$endif}writevalue, + (filer.ancestor = nil) and (fvalue <> '') or + (filer.ancestor <> nil) and + (tcustomdataimage(filer.ancestor).fvalue <> fvalue)); +end; + +function tcustomdataimage.actualcolor: colorty; +begin + if (fgridintf <> nil) and (fcolor = cl_default) then begin + result:= fgridintf.getcol.rowcolor(fgridintf.getrow); + end + else begin + result:= inherited actualcolor; + end; +end; + +function tcustomdataimage.loadfromstream(const astream: tstream): string; +//var +// str1: string; +begin + fcurformat:= ''; + value:= readstreamdatastring(astream); + result:= fcurformat; +end; + +function tcustomdataimage.loadfromfile(const afilename: filenamety): string; +var + stream1: tmsefilestream; +begin + stream1:= tmsefilestream.create(afilename); + try + result:= loadfromstream(stream1); + finally + stream1.free; + end; +end; + +procedure tcustomdataimage.storeimage(const aformat: string; + const params: array of const); +var + str1: string; +begin + if aformat <> '' then begin + str1:= aformat; + end + else begin + str1:= format; + end; + value:= bitmap.writetostring(str1,params); +end; + +procedure tcustomdataimage.datalistdestroyed; +begin + //dummy +end; + +procedure tcustomdataimage.setvaluedata(const source); +begin + value:= string(source); +end; + +procedure tcustomdataimage.getvaluedata(out dest); +begin + //dummy +end; + +procedure tcustomdataimage.setparentgridwidget(const intf: igridwidget); +begin + //dummy +end; + +procedure tcustomdataimage.childdataentered(const sender: igridwidget); +begin + //dummy +end; + +procedure tcustomdataimage.childfocused(const sender: igridwidget); +begin + //dummy +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msedatanodes.pas b/mseide-msegui/lib/common/editwidgets/msedatanodes.pas new file mode 100644 index 0000000..4d48c14 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msedatanodes.pas @@ -0,0 +1,4019 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedatanodes; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegraphutils,msedrawtext,msegraphics,msedatalist,mseglob, + mseguiglob,msegui,msestockobjects, + msebitmap,mseclasses,mseevent,msegrids,msetypes,msestrings,mseinplaceedit, + msestat,msegridsglob,mselist,msearrayutils,msearrayprops; + +type + + nodestatty = (ns_expanded,ns_selected,ns_readonly,ns_checked, + ns_subitems,ns_drawemptybox,ns_imagenrfix, +// ns_destroying,ns_updating,ns_noowner, + ns_checkbox,ns_showchildchecked,ns_showchildnotchecked, + ns_showparentnotchecked, + ns_nosubnodestat, + ns_casesensitive,ns_sorted,//ns_captionclipped, + ns_drawemptyexpand,ns_res15, + ns_useri0,ns_useri1,ns_useri2,ns_useri3, + //with invalidate and statsave + ns_useri4,ns_useri5,ns_useri6,ns_useri7, + //with invalidate, no statsave + ns_user0,ns_user1,ns_user2,ns_user3, + //without invalidate, with statsave + ns_user4,ns_user5,ns_user6,ns_user7); + //without invalidate, no statsave + + nodestatesty = set of nodestatty; + nodestate1ty = (ns1_statechanged,ns1_rootchange,ns1_candrag, + ns1_destroying,ns1_notbyownerdestroying, + ns1_updating,ns1_noowner,ns1_captionclipped, + ns1_childchecked,ns1_childnotchecked,ns1_parentnotchecked, + ns1_checkboxclicked,ns1_customsort, + ns1_nofreeroot,ns1_top,ns1_fixedcaption,ns1_nodefaultimagelist + // ns1_irecordfield, //implements irecordfield + // ns1_irecordvaluefield //irecordvaluefield + ); + nodestates1ty = set of nodestate1ty; + + nodeoptionty = (no_drawemptybox,no_drawemptyexpand,no_solidline,no_checkbox, + no_updatechildchecked, + //track ns1_childchecked state, slow! + no_updatechildnotchecked, + //track ns1_childnotchecked state, slow! + no_updateparentnotchecked, + //track ns1_parentnotchecked state, slow! + no_cellitemselect, //copy cell select state to item select + no_nofreeitems, //do not free items for removed rows + no_createvalueitems //titemeditlist creates items depending + //on statread type value + ); + nodeoptionsty = set of nodeoptionty; + + treeitemboxty = (tib_none,tib_empty,tib_expand,tib_expanded, + tib_checkbox,tib_checkboxchecked, + tib_checkboxparentnotchecked,tib_checkboxchildchecked, + tib_checkboxchildnotchecked); + itemdrawoptionty = (ido_solidline); + itemdrawoptionsty = set of itemdrawoptionty; + treeitemboxidarty = array[treeitemboxty] of int32; + ptreeitemboxidarty = treeitemboxidarty; + +const + invalidatestates = [ns_expanded,ns_selected,ns_checked, + ns_subitems,ns_drawemptybox,ns_checkbox, + ns_useri0..ns_useri7]; + invalidateallstates = [ns_expanded]; + valuechangestates = [ns_checked]; + statstates: nodestatesty = [ns_expanded,ns_selected,ns_checked,{ns_checkbox,} + ns_useri0..ns_useri3,ns_user0..ns_user3]; + defaultlevelstep = 10; + +type + getnodemodety = (gno_matching,gno_allchildren,gno_nochildren); + + extrainfoty = record + image: sizety; //first because of backward compatibility of extendimageeventty + caption: sizety; + end; + + variablelistiteminfoty = record + extra: extrainfoty; + imageextend: sizety; + treelevelshift: integer; + rowindex: integer; + widgetstate: widgetstatesty; + calcautocellsize: boolean; + colorline: colorty; + colorglyph: colorty; +// boxids: ptreeitemboxidarty; + glyphversion: int32; //for stockglyphs + imageversion: int32; //for imagelist + end; + + listitemlayoutinfoty = record + widget: twidget; //titemedit or tcustomlistview + cellsize: sizety; + minsize: sizety; + captionrect: rectty; + captioninnerrect: rectty; + imagerect: rectty; + imagealignment: alignmentsty; + textflags: textflagsty; + expandboxrect: rectty; + checkboxrect: rectty; + checkboxinnerrect: rectty; +// colorline: colorty; + boxids: treeitemboxidarty; +// drawoptions: itemdrawoptionsty; + variable: variablelistiteminfoty; //variable + end; + plistitemlayoutinfoty = ^listitemlayoutinfoty; + + nodeactionty = (na_none,na_change,na_valuechange,na_checkedchange, + na_expand,na_collapse,na_countchange, + na_destroying,na_aftersort); + nodeactioninfoty = record + case action: nodeactionty of + na_countchange: ( + treeheightbefore: integer; + ); + end; + + tlistitem = class; + + iitemlist = interface(inullinterface) + function getgrid: tcustomgrid; + function getlayoutinfo(const acellinfo: pcellinfoty): plistitemlayoutinfoty; + procedure updatelayout; + procedure itemcountchanged; +// function getcolorglyph: colorty; + procedure updateitemvalues(const index: integer; const count: integer); + function getcomponentstate: tcomponentstate; + end; + + tcustomitemlist = class; + + tlistitem = class(tnullinterfacedobject) + private + procedure setstate(const Value: nodestatesty); + procedure setimagenr(const Value: integer); + function getselected: boolean; + procedure setselected(const Value: boolean); + function getchecked: boolean; + function getimagelist: timagelist; + procedure setimagelist(const Value: timagelist); + procedure setvaluetext1(const avalue: msestring); + function gettop: boolean; + procedure settop(const avalue: boolean); + function getcheckbox: boolean; + procedure setcheckbox(const avalue: boolean); + protected + fstate: nodestatesty; + fstate1: nodestates1ty; + findex: integer; + fimagelist: timagelist; + fimagenr: integer; + fcaption: msestring; + fowner: tcustomitemlist; + procedure setchecked(const avalue: boolean); virtual; + procedure setcaption(const avalue: msestring); virtual; + function checkaction(aaction: nodeactionty): boolean; + procedure actionnotification(var ainfo: nodeactioninfoty); virtual; + function getactimagenr( + const alayoutinfo: listitemlayoutinfoty): integer; virtual; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + procedure setowner(const aowner: tcustomitemlist); virtual; + function compare(const r: tlistitem; + const acasesensitive: boolean): integer; virtual; + function cancaptionedit: boolean; virtual; + function canvalueedit: boolean; virtual; + function getvalueitem: tlistitem; virtual; + procedure setvalueitem(const avalue: tlistitem); virtual; + function getownerintf: iitemlist inline; + public + tag: integer; + tagpo: pointer; + property tagpointer: pointer read tagpo write tagpo; + deprecated 'Use tagpo instead'; + constructor create(const aowner: tcustomitemlist); overload; virtual; + constructor createassign(const aowner: tcustomitemlist; + const asource: tlistitem); overload; + destructor destroy; override; + class procedure calcitemlayout(const asize: sizety; + const ainnerframe: framety; const list: tcustomitemlist; + var info: listitemlayoutinfoty); virtual; + + procedure assign(const source: tlistitem); overload; virtual; + procedure beginupdate; + procedure endupdate; + procedure releaseowner; virtual; + + function empty: boolean; virtual; + procedure change(); virtual; + procedure valuechange(const delta: nodestatesty = []); virtual; + procedure updatecellzone(const pos: pointty; var zone: cellzonety); virtual; + procedure drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty) virtual; + procedure updatecaption(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty; + var ainfo: drawtextinfoty); virtual; + procedure drawcell(const acanvas: tcanvas); virtual; + procedure mouseevent(var info: mouseeventinfoty); virtual; + property index: integer read findex; + procedure focusrow(); //set assigned grid row to index + procedure setupeditor(const editor: tinplaceedit; + const font: tfont; const notext: boolean); virtual; + + procedure dostatupdate(const filer: tstatfiler); + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + + function captionclipped: boolean; + property caption: msestring read fcaption write setcaption; + property state: nodestatesty read fstate write setstate; + property state1: nodestates1ty read fstate1; + property imagelist: timagelist read getimagelist write setimagelist; + //nil -> fowner.imagelist + property imagenr: integer read fimagenr write setimagenr; + property selected: boolean read getselected write setselected; + property checkbox: boolean read getcheckbox write setcheckbox; + property checked: boolean read getchecked write setchecked; + property owner: tcustomitemlist read fowner; + function getvaluetext: msestring; virtual; + procedure setvaluetext(var avalue: msestring); virtual; + property valuetext: msestring read getvaluetext write setvaluetext1; + property valueitem: tlistitem read getvalueitem; + property top: boolean read gettop write settop; + end; + + plistitem = ^tlistitem; + listitemclassty = class of tlistitem; + listitemarty = array of tlistitem; + listitematy = array[0..0] of tlistitem; + plistitematy = ^listitematy; + + ttreelistitem = class; + treelistitemarty = array of ttreelistitem; + treelistitematy = array[0..0] of ttreelistitem; + ptreelistitematy = ^treelistitematy; + + treelistitemclassty = class of ttreelistitem; + checktreelistitemprocty = procedure(const sender: ttreelistitem; + var delete: boolean) of object; + ttreelistitemcomparefuncty = function( + const l,r: ttreelistitem): integer of object; + tlistitemcomparefuncty = function (const r: tlistitem; + const acasesensitive: boolean): integer of object; + +{ + treeitemdrawinfoty = record + boxkind: treeitemboxty; //set by caller + boximageid: int32; + flags: treeitemdrawingflagsty; + end; +} + ttreelistitem = class(tlistitem) + private + function getexpanded: boolean; + function getitems(const aindex: integer): ttreelistitem; + procedure dosetitems(const aindex: integer; const value: ttreelistitem); + procedure setitems(const aindex: integer; const value: ttreelistitem); + procedure unsetitem(const aindex: integer); + procedure internalcheckitems(const checkdelete: checktreelistitemprocty); + procedure setdestroying; + procedure setnotbyownerdestroying; + //destroyed by parentitem with owner = nil + function inccount: integer; //returns itemindex + function getrootexpanded: boolean; + procedure setrootexpanded(const avalue: boolean); + function getsubitems: boolean; + procedure setsubitems(const avalue: boolean); + protected + fparent: ttreelistitem; + fparentindex: integer; + fitems: treelistitemarty; + fcount: integer; + ftreelevel: integer; + procedure setexpanded(const Value: boolean) virtual; + procedure statechanged virtual; + procedure aftermove virtual; + procedure checksort; virtual; + procedure setcaption(const avalue: msestring); override; + procedure setowner(const aowner: tcustomitemlist); override; + procedure setchecked(const avalue: boolean); override; + procedure checkindex(const aindex: integer); + procedure settreelevel(const value: integer); + procedure countchange(const atreeheightbefore: integer; + const notifyowner: boolean); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function createsubnode: ttreelistitem; virtual; + procedure internalswap(const a,b: integer); + procedure internalmove(const source,dest: integer); + procedure statreadsubnode(const reader: tstatreader; + var anode: ttreelistitem); virtual; + procedure internalexpandall; + procedure internalcollapseall; + procedure internalgetnodes(var aresult: treelistitemarty; var acount: integer; + const must: nodestatesty; const mustnot: nodestatesty; + const amode: getnodemodety; const addself: boolean); + function customcompare(const l,r: ttreelistitem): integer; virtual; + + function comparecasesens(const l: ttreelistitem; + const r: ttreelistitem): integer; + function comparecaseinsens(const l: ttreelistitem; + const r: ttreelistitem): integer; + procedure doupdateparentnotcheckedstate(const aset: boolean); +// procedure updatedrawinfo(var ainfo: treeitemdrawinfoty) virtual; + public + constructor create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); reintroduce; virtual; + destructor destroy; override; + class procedure calcitemlayout(const asize: sizety; + const ainnerframe: framety; const list: tcustomitemlist; + var info: listitemlayoutinfoty); override; + + procedure releaseowner; override; + procedure releasechildren(); + + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + + procedure updatechildcheckedstate(); //updates ancestors + procedure updatechildcheckedtree(); //updates self and descendents + procedure updatechildnotcheckedtree(); //updates self and descendents + procedure updatechildnotcheckedstate(); //updates ancestors + procedure updateparentnotcheckedstate(); //updates affected descendents + procedure updateparentnotcheckedtree(); //updates all descendents + property parent: ttreelistitem read fparent; + function parentorself: ttreelistitem; + function parentindex: integer; + property treelevel: integer read ftreelevel; + function levelshift: integer; + function treeheight: integer; //total hight of children + function rowheight: integer; //toatal needed grid rows + function isroot: boolean; + function issinglerootrow: boolean; //keyrowmove can be used + function islastnode: boolean; + property subitems: boolean read getsubitems write setsubitems; + function findsibling(const asibling: ttreelistitem): ttreelistitem; + function nextnode: ttreelistitem; //node of next row + function nextnodeparent: ttreelistitem; + function checkdescendent(node: ttreelistitem): boolean; + //true if node is descendent or self + function checkancestor(node: ttreelistitem): boolean; + //true if node is ancestor or self + function isstatechanged: boolean; + function candrag: boolean; virtual; + function candrop(const source: ttreelistitem): boolean; virtual; + + function finditembycaption(const acaption: msestring; + var dest: ttreelistitem): boolean; overload; + function finditembycaption(const acaption: msestring; + const acasesensitive: boolean = false; + const aexpand: boolean = false): ttreelistitem; overload; + function finditembycaption(const acaption: lmsestringty; + const aexpand: boolean = false): ttreelistitem; overload; + function finditembycaption(const acaptions: msestringarty; + const acasesensitive: boolean = false; + const aexpand: boolean = false; + const apartial: boolean = false): ttreelistitem; overload; + function rootnode: ttreelistitem; + function rootpath: treelistitemarty; + //top-down + function rootcaptions: msestringarty; overload; + function rootcaptions(const aowner: tcustomitemlist): msestringarty; overload; + //stops if not owned by aowner + procedure checkitems(const checkdelete: checktreelistitemprocty); + + procedure updatecellzone(const pos: pointty; var zone: cellzonety); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty) override; + procedure addchildren(const aitem: ttreelistitem); + //transfers children + function add(const aitem: ttreelistitem): integer; overload; + //returns index, nil ignored + procedure add(const aitems: treelistitemarty); overload; + function add(const itemclass: treelistitemclassty = nil): + ttreelistitem; overload; + procedure add(const acount: integer; + const itemclass: treelistitemclassty = nil; + const defaultstate: nodestatesty = []); overload; + procedure insert(aindex: integer; const aitem: ttreelistitem); + procedure insert(const aitem: ttreelistitem; aindex: integer); deprecated; + //use insert(aindex,aitem) above instead + procedure move(const source,dest: integer); + procedure swap(const a,b: integer); + procedure clear; virtual; + + function getnodes(const must: nodestatesty; + const mustnot: nodestatesty; + const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; + function getselectednodes(const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; + function getcheckednodes(const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; + + procedure expandall; + procedure collapseall; + procedure expandtoroot(const afocusrow: boolean = true); + procedure collapsetoroot; + function remove(const aindex: integer): ttreelistitem; + procedure sort(const casesensitive: boolean; + const recursive: boolean = false); overload; + procedure sort(const sortfunc: arraysortcomparety; + const recursive: boolean = false); overload; + property count: integer read fcount; + procedure setupeditor(const editor: tinplaceedit; + const font: tfont; const notext: boolean); override; + property rootexpanded: boolean read getrootexpanded write setrootexpanded; + //stops after toplevel item of itemlist + property expanded: boolean read getexpanded write setexpanded; + function treechecked: boolean; //true if checked and not parentnotchecked + property items[const aindex: integer]: ttreelistitem read getitems; default; + end; + + tfontarrayprop = class(tpersistentarrayprop) + private + procedure setitems(const index: integer; const avalue: tfont); + protected + function getitems(const index: integer): tfont; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(); + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + property items[const index: integer]: tfont read getitems + write setitems; default; + end; + + ptreelistitem = ^ttreelistitem; + + itemliststatety = (ils_destroying,ils_updateitemvalues, + ils_subnodecountinvalid,ils_subnodecountupdating, + ils_subnodedeleting, + ils_freelock); + itemliststatesty = set of itemliststatety; + statreaditemeventty = procedure(const sender: tobject; const reader: tstatreader; + var aitem: tlistitem) of object; + statreadtreeitemeventty = procedure(const sender: tobject; + const reader: tstatreader; + var aitem: ttreelistitem) of object; + statwriteitemeventty = procedure(const sender: tobject; + const writer: tstatwriter; const aitem: tlistitem) of object; + statwritetreeitemeventty = procedure(const sender: tobject; + const writer: tstatwriter; const aitem: ttreelistitem) of object; + + statreaditemlisteventty = procedure(const sender: tcustomitemlist; + const areader: tstatreader; + const aname: msestring) of object; + statwriteitemlisteventty = procedure(const sender: tcustomitemlist; + const areader: tstatwriter; + const aname: msestring) of object; + tcustomitemlist = class(tobjectdatalist,iobjectlink) + private + fonstatreaditem: statreaditemeventty; + fonstatreadtreeitem: statreadtreeitemeventty; + fonstatwriteitem: statwriteitemeventty; + fonstatwritetreeitem: statwritetreeitemeventty; + fonstatwrite: statwriteitemlisteventty; + fonstatread: statreaditemlisteventty; + ffonts: tfontarrayprop; + fimnr_focused: integer; + fimnr_active: integer; + procedure setimnr_base(const Value: integer); + procedure setimnr_expanded(const Value: integer); + procedure setimnr_selected(const Value: integer); + procedure setimnr_readonly(const Value: integer); + procedure setimnr_checked(const Value: integer); + procedure setimnr_subitems(const Value: integer); + procedure setimagelist(const Value: timagelist); + procedure setoptions(const Value: nodeoptionsty); + procedure setcaptionpos(const Value: captionposty); + procedure setlevelstep(const Value: integer); + procedure setimageheight(const Value: integer); + procedure setimagewidth(const Value: integer); + procedure setimagesize(const avalue: sizety); + procedure setimagealignment(const avalue: alignmentsty); + procedure setfonts(const avalue: tfontarrayprop); + procedure setimnr_focused(const avalue: integer); + procedure setimnr_active(const avalue: integer); + protected + fdefaultnodestate: nodestatesty; + fimagelist: timagelist; + fimagesize: sizety; + fimagealignment: alignmentsty; + fimnr_base: integer; + fimnr_expanded,fimnr_selected,fimnr_readonly,fimnr_checked, + fimnr_subitems: integer; + flevelstep: integer; + fintf: iitemlist; + foptions: nodeoptionsty; + fcaptionpos: captionposty; + fitemstate: itemliststatesty; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function getitems1(const index: integer): tlistitem; + procedure setitems(const index: integer; const Value: tlistitem); + procedure setcount(const value: integer); override; + procedure freedata(var data); override; + procedure removeitem(const aindex: integer); //no free item + procedure change(const item: tlistitem); reintroduce; overload; + procedure nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); virtual; + procedure setitemselected(const row: integer; const value: boolean); override; + procedure doitemchange(const index: integer); override; + procedure invalidate; virtual; + procedure updatelayout; virtual; + procedure docreateobject(var instance: tobject); override; + procedure createitem(out item: tlistitem); virtual; + procedure createstatitem(const reader: tstatreader; + out item: tlistitem); virtual; + procedure statreaditem(const reader: tstatreader; + var aitem: tlistitem); virtual; + procedure statreadtreeitem(const reader: tstatreader; + const parent: ttreelistitem; var aitem: ttreelistitem); virtual; + procedure statwriteitem(const writer: tstatwriter; + const aitem: tlistitem); virtual; + procedure statwritetreeitem(const writer: tstatwriter; + const aitem: ttreelistitem); virtual; + + procedure dostatread(const reader: tstatreader; + const name: msestring); virtual; + procedure dostatwrite(const writer: tstatwriter; + const name: msestring); virtual; + procedure writestate(const writer; const name: msestring); override; + procedure readstate(const reader; const acount: integer; + const name: msestring); override; + + public + constructor create; overload; override; + constructor create(const intf: iitemlist); reintroduce; overload; + destructor destroy; override; + procedure registerobject(const aobject: iobjectlink); + //call objectevent method of items + procedure unregisterobject(const aobject: iobjectlink); + function layoutinfopo: plistitemlayoutinfoty; + + function add(const aitem: tlistitem): integer; overload; + function add(const aitem: msestring): integer; overload; + procedure add(const aitems: listitemarty); overload; + procedure add(const aitems: msestringarty); overload; + procedure add(const aitems: array of msestring); overload; + + function empty(const index: integer): boolean; override; + function indexof(const aitem: tlistitem): integer; + function nodezone(const point: pointty): cellzonety; + function getitems(const must: nodestatesty; + const mustnot: nodestatesty): listitemarty; + function getindexes(const must: nodestatesty; + const mustnot: nodestatesty): integerarty; + function getselecteditems: listitemarty; + function getselectedindexes: integerarty; + function getcheckeditems: listitemarty; + function getcheckedindexes: integerarty; + property itemlistintf: iitemlist read fintf; + property items[const index: integer]: tlistitem read getitems1 write setitems; + default; + property imnr_base: integer read fimnr_base write setimnr_base default 0; + property imnr_expanded: integer read fimnr_expanded + write setimnr_expanded default 0; + property imnr_selected: integer read fimnr_selected + write setimnr_selected default 0; + property imnr_readonly: integer read fimnr_readonly + write setimnr_readonly default 0; + property imnr_checked: integer read fimnr_checked + write setimnr_checked default 0; + property imnr_subitems: integer read fimnr_subitems + write setimnr_subitems default 0; + property imnr_focused: integer read fimnr_focused + write setimnr_focused default 0; + property imnr_active: integer read fimnr_active + write setimnr_active default 0; + property imagelist: timagelist read fimagelist write setimagelist; + property imagewidth: integer read fimagesize.cx + write setimagewidth default 0; + property imageheight: integer read fimagesize.cy + write setimageheight default 0; + property imagesize: sizety read fimagesize write setimagesize; + property imagealignment: alignmentsty read fimagealignment + write setimagealignment default [al_xcentered,al_ycentered]; + property options: nodeoptionsty read foptions write setoptions default []; + property captionpos: captionposty read fcaptionpos write setcaptionpos + default cp_right; + property fonts: tfontarrayprop read ffonts write setfonts; + property levelstep: integer read flevelstep write setlevelstep + default defaultlevelstep; + property defaultnodestate: nodestatesty read fdefaultnodestate + write fdefaultnodestate default []; + + property onstatreaditem: statreaditemeventty read fonstatreaditem + write fonstatreaditem; + property onstatreadtreeitem: statreadtreeitemeventty + read fonstatreadtreeitem write fonstatreadtreeitem; + property onstatwriteitem: statwriteitemeventty read fonstatwriteitem + write fonstatwriteitem; + property onstatwritetreeitem: statwritetreeitemeventty + read fonstatwritetreeitem write fonstatwritetreeitem; + + property onstatwrite: statwriteitemlisteventty read fonstatwrite + write fonstatwrite; //called before items + property onstatread: statreaditemlisteventty read fonstatread + write fonstatread; //called before items + end; + + ttreenode = class; + treenodeclassty = class of ttreenode; + treenodearty = array of ttreenode; + nodeeventty = procedure(const sender: ttreenode) of object; + treenodefilterfuncty = function(const sender: ttreenode): boolean of object; + + ttreenode = class + private + procedure setcount(const value: integer); + procedure checkindex(const index: integer); + procedure convertflat(const listitem: ttreelistitem; + const filterfunc: treenodefilterfuncty); + function converttree(const filterfunc: treenodefilterfuncty): ttreelistitem; + protected + fitems: treenodearty; + fcount: integer; + fparent: ttreenode; + function getitems(const index: integer): ttreenode; + procedure setitems(const index: integer; const Value: ttreenode); + function treenodeclass: treenodeclassty; virtual; + function listitemclass: treelistitemclassty; virtual; + procedure nodetoitem(const listitem: ttreelistitem); virtual; + public + destructor destroy; override; + procedure clear; virtual; + function count: integer; + function add(const anode: ttreenode): integer; + procedure iterate(const event: nodeeventty); + function converttotreelistitem(flat: boolean = false; + withrootnode: boolean = false; + filterfunc: treenodefilterfuncty = nil): ttreelistitem; + property items[const index: integer]: ttreenode read getitems + write setitems; default; + property parent: ttreenode read fparent; + end; + + ptreenode = ^ttreenode; + + function copylistitems(const asource: listitemarty): listitemarty; + +implementation +uses + {$ifdef FPCc}rtlconst{$else}rtlconsts{$endif}, + sysutils,msebits,msesysintf; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + imageextendcaptionpos = [cp_right,cp_righttop{,cp_rightcenter},cp_rightbottom]; + +function copylistitems(const asource: listitemarty): listitemarty; +var + int1: integer; +begin + result:= nil; + allocuninitedarray(length(asource),sizeof(pointer),result); + for int1:= 0 to high(result) do begin + result[int1]:= listitemclassty(asource[int1].classtype).create(nil); + result[int1].assign(asource[int1]); + end; +end; + +{ tfontarrayprop } + +constructor tfontarrayprop.create(); +begin + inherited create(tfont); +end; + +procedure tfontarrayprop.setitems(const index: integer; const avalue: tfont); +begin + checkindex(index); + if fitems[index] <> nil then begin + fitems[index].assign(avalue); + end; +end; + +function tfontarrayprop.getitems(const index: integer): tfont; +begin + result:= tfont(inherited getitems(index)); +end; + +procedure tfontarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tfont.create; + item.assign(stockobjects.fonts[stf_default]); +end; + +class function tfontarrayprop.getitemclasstype: persistentclassty; +begin + result:= tfont; +end; + +{ tlistitem } + +constructor tlistitem.create(const aowner: tcustomitemlist); +begin + findex:= -1; + if aowner <> nil then begin + setowner(aowner); + end; + if (fowner <> nil) then begin + fstate:= fowner.fdefaultnodestate; + end; +end; + +constructor tlistitem.createassign(const aowner: tcustomitemlist; + const asource: tlistitem); +begin + create(aowner); + assign(asource); +end; + +destructor tlistitem.destroy; +begin + if not (ns1_destroying in fstate1) then begin + include(fstate1,ns1_destroying); + if (fowner <> nil) then begin + if not(ils_destroying in fowner.fitemstate) then begin + checkaction(na_destroying); + end; + end; + end; + inherited; +end; + +procedure tlistitem.assign(const source: tlistitem); +begin + beginupdate; + tag:= source.tag; + tagpo:= source.tagpo; + caption:= source.fcaption; + state:= source.fstate; + imagelist:= source.fimagelist; + imagenr:= source.fimagenr; + endupdate; +end; + +class procedure tlistitem.calcitemlayout(const asize: sizety; + const ainnerframe: framety; + const list: tcustomitemlist; var info: listitemlayoutinfoty); +var + aimagesize: sizety; +const + checkboxdist = 1; +begin + with list do begin + aimagesize:= fimagesize; + info.imagealignment:= fimagealignment; + end; + with info do begin + cellsize:= asize; + captionrect:= makerect(nullpoint,asize); + imagerect:= captionrect; + if no_checkbox in list.foptions then begin + checkboxrect.size.cx:= checkboxsize + 2*checkboxdist; + checkboxrect.size.cy:= checkboxrect.size.cx; + aimagesize.cx:= aimagesize.cx + checkboxrect.size.cx; + if aimagesize.cy < checkboxsize then begin + aimagesize.cy:= checkboxsize; + end; + end + else begin + checkboxrect.size:= nullsize; + checkboxinnerrect.size:= nullsize; + end; + textflags:= [tf_xcentered,tf_ycentered]; + case list.fcaptionpos of + cp_left,cp_lefttop,cp_leftbottom: begin + dec(captionrect.cx,aimagesize.cx); + imagerect.x:= captionrect.cx; + imagerect.cx:= aimagesize.cx; + case list.fcaptionpos of + cp_lefttop: textflags:= [tf_right]; + cp_leftbottom: textflags:= [tf_ycentered,tf_right]; + else textflags:= [tf_bottom,tf_right]; + end; + end; + cp_right,cp_righttop,cp_rightbottom: begin + captionrect.x:= aimagesize.cx; + dec(captionrect.cx,aimagesize.cx); + imagerect.cx:= aimagesize.cx; + case list.captionpos of + cp_righttop: textflags:= []; + cp_rightbottom: textflags:= [tf_bottom]; + else textflags:= [tf_ycentered]; + end; + end; + cp_top,cp_topleft,cp_topright: begin + dec(captionrect.cy,aimagesize.cy); + imagerect.y:= captionrect.cy; + imagerect.cy:= aimagesize.cy; + case list.captionpos of + cp_topleft: textflags:= [tf_ycentered]; + cp_topright: textflags:= [tf_ycentered,tf_right]; + else textflags:= [tf_ycentered,tf_xcentered]; + end; + end; + cp_bottom,cp_bottomleft,cp_bottomright: begin + captionrect.y:= aimagesize.cy; + dec(captionrect.cy,aimagesize.cy); + imagerect.cy:= aimagesize.cy; + case list.captionpos of + cp_bottomleft: textflags:= [tf_ycentered]; + cp_bottomright: textflags:= [tf_ycentered,tf_right]; + else textflags:= [tf_ycentered,tf_xcentered]; + end; + end; + end; + captioninnerrect:= deflaterect(captionrect,ainnerframe); + checkboxrect.y:= imagerect.y + (imagerect.cy - checkboxrect.cy) div 2; + checkboxrect.x:= imagerect.x; + if no_checkbox in list.foptions then begin + imagerect.x:= imagerect.x + checkboxrect.cx; + imagerect.cx:= imagerect.cx - checkboxrect.cx; + checkboxinnerrect:= inflaterect(checkboxrect,-checkboxdist); + end + else begin + checkboxinnerrect.pos:= checkboxrect.pos; + end; + minsize:= aimagesize; + end; +end; + +procedure tlistitem.drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty); +var + int1: integer; + aimagelist: timagelist; + glyphno: int32; + nopaint: boolean; +begin + aimagelist:= imagelist; + nopaint:= (acanvas = nil) or alayoutinfo.variable.calcautocellsize; + with fowner,alayoutinfo do begin + variable.imageextend:= nullsize; + if not nopaint then begin //acanvas <> nil then begin + if (no_checkbox in foptions) and (ns_checkbox in self.fstate) then begin + glyphno:= boxids[tib_checkbox]; + if ns_checked in self.fstate then begin + glyphno:= boxids[tib_checkboxchecked]; + if (ns_showparentnotchecked in self.fstate) and + (ns1_parentnotchecked in self.fstate1) then begin + glyphno:= boxids[tib_checkboxparentnotchecked]; + end + else begin + if (ns_showchildnotchecked in self.fstate) and + (ns1_childnotchecked in self.fstate1) then begin + glyphno:= boxids[tib_checkboxchildnotchecked]; + end; + end; + end + else begin + if (ns_showchildchecked in self.fstate) and + (ns1_childchecked in self.fstate1) then begin + glyphno:= boxids[tib_checkboxchildchecked]; + end; + end; + stockobjects.glyphs.paint(acanvas,glyphno,checkboxrect, + [al_xcentered,al_ycentered],variable.colorglyph, + cl_default,cl_default,variable.glyphversion); + end; + end; + if aimagelist <> nil then begin + if fowner.captionpos in imageextendcaptionpos then begin + variable.imageextend.cx:= aimagelist.size.cx + variable.extra.image.cx - + imagerect.cx; + end; + if not nopaint then begin //acanvas <> nil then begin + int1:= getactimagenr(alayoutinfo); + if (int1 >= 0) and (int1 < aimagelist.count) then begin + //todo: check imagepos and the like + with imagerect do begin + aimagelist.paint(acanvas,int1,mr(x,y,cx+variable.imageextend.cx,cy), + imagealignment,variable.colorglyph, + cl_default,cl_default,variable.imageversion); + end; + end; + end; + end + else begin + if fowner.captionpos in imageextendcaptionpos then begin + variable.imageextend.cx:= variable.extra.image.cx - imagerect.cx; + end; + end; + end; +end; + +procedure tlistitem.updatecaption(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty; + var ainfo: drawtextinfoty); +var + int1: integer; +begin +//toto: check captionpos and the like + with alayoutinfo do begin + ainfo.dest.cx:= ainfo.dest.cx - variable.treelevelshift; + ainfo.clip.cx:= ainfo.clip.cx - variable.treelevelshift; +// if fimagelist <> nil then begin + if (variable.imageextend.cx <> 0) and + (fowner.captionpos in imageextendcaptionpos) then begin + int1:= variable.imageextend.cx; + with ainfo.dest do begin + x:= x+int1; + cx:= cx-int1; + end; + with ainfo.clip do begin + x:= x+int1; + cx:= cx-int1; + end; + end; +// end; + end; +end; + +procedure tlistitem.drawcell(const acanvas: tcanvas); +var + info: drawtextinfoty; +// pt1: pointty; + po1: pcellinfoty; + layoutinfopo: plistitemlayoutinfoty; + size1: sizety; +begin +// pt1:= acanvas.origin; + po1:= pcellinfoty(acanvas.drawinfopo); + layoutinfopo:= fowner.fintf.getlayoutinfo(po1); + layoutinfopo^.variable.calcautocellsize:= po1^.calcautocellsize; +// if not po1^.calcautocellsize then begin + drawimage(acanvas,layoutinfopo^); //ttreelistitem shifts origin +// end +// else begin +// drawimage(layoutinfopo^,nil); +// end; + with layoutinfopo^ do begin + info.text.text:= fcaption; + info.text.format:= nil; + info.dest:= captioninnerrect; + inc(info.dest.cx,variable.extra.caption.cx); + inc(info.dest.cy,variable.extra.caption.cy); + info.clip:= captionrect; + inc(info.clip.cx,variable.extra.caption.cx); + inc(info.clip.cy,variable.extra.caption.cy); + info.flags:= textflags {- [tf_clipo]}; + info.font:= nil; + info.tabulators:= nil; + updatecaption(acanvas,layoutinfopo^,info); + if po1^.calcautocellsize then begin + textrect(acanvas,info); + size1.cx:= po1^.rect.cx + info.res.cx - info.dest.cx; + if size1.cx < minsize.cx then begin + size1.cx:= minsize.cx; + end; + size1.cy:= po1^.rect.cy + info.res.cy - info.dest.cy; + if size1.cy < minsize.cy then begin + size1.cy:= minsize.cy; + end; + if size1.cx > po1^.autocellsize.cx then begin + po1^.autocellsize.cx:= size1.cx; + end; + if size1.cy > po1^.autocellsize.cy then begin + po1^.autocellsize.cy:= size1.cy; + end; + end + else begin + drawtext(acanvas,info); + if not rectinrect(info.res,info.dest) then begin + include(fstate1,ns1_captionclipped); + end + else begin + exclude(fstate1,ns1_captionclipped); + end; + { + with info.res do begin + x:= x + captioninnerrect.x - info.dest.x; + y:= y + captioninnerrect.y - info.dest.y; + cx:= cx + captioninnerrect.cx - info.dest.cx; + cy:= cy + captioninnerrect.cy - info.dest.cy; + end; + if not rectinrect(info.res, + moverect(captioninnerrect,subpoint(pt1,acanvas.origin))) then begin + include(fstate1,ns1_captionclipped); + end + else begin + exclude(fstate1,ns1_captionclipped); + end; + } + end; + end; +end; + +function tlistitem.captionclipped: boolean; +begin + result:= ns1_captionclipped in fstate1; +end; + +procedure tlistitem.updatecellzone(const pos: pointty; var zone: cellzonety); +begin + with fowner.fintf.getlayoutinfo(nil)^ do begin + if pointinrect(pos,captionrect) then begin + zone:= cz_caption; + end + else begin + if (ns_checkbox in fstate) and pointinrect(pos,checkboxinnerrect) then begin + zone:= cz_checkbox; + end + else begin + if pointinrect(pos,imagerect) then begin + zone:= cz_image; + end; + end; + end; + end; +end; + +procedure tlistitem.setupeditor(const editor: tinplaceedit; const font: tfont; + const notext: boolean); +var + info1: drawtextinfoty; + po1: plistitemlayoutinfoty; +begin + po1:= fowner.fintf.getlayoutinfo(nil); + po1^.variable.calcautocellsize:= true; + drawimage(editor.getfontcanvas(),po1^); //calc image extend + with po1^ do begin + info1.font:= font; + with info1 do begin + tabulators:= nil; + dest:= captioninnerrect; + inc(dest.cx,variable.extra.caption.cx); + inc(dest.cy,variable.extra.caption.cy); + clip:= captionrect; + inc(clip.cx,variable.extra.caption.cx); + inc(clip.cy,variable.extra.caption.cy); + if not notext then begin + text.text:= fcaption; + end + else begin + text.text:= editor.text; + end; + flags:= textflags; + + updatecaption(editor.getfontcanvas(),po1^,info1); + editor.setup(text.text,editor.curindex,false,dest,clip,text.format,nil,font); + end; + end; +end; + +procedure tlistitem.change(); +var + action: nodeactioninfoty; +begin + if fowner <> nil {and (fowner.fnochange = 0)} then begin + action.action:= na_change; + fowner.nodenotification(self,action); + end; +end; + +procedure tlistitem.valuechange(const delta: nodestatesty = []); +var + action: nodeactioninfoty; +begin + if fowner <> nil then begin + if ns_checked in delta then begin + action.action:= na_checkedchange; + end + else begin + action.action:= na_valuechange; + end; + fowner.nodenotification(self,action); + end; +end; + +procedure tlistitem.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + change(); + if not (ns1_fixedcaption in fstate1) then begin + valuechange([]); + end; +end; + +procedure tlistitem.setstate(const Value: nodestatesty); +var + stat1: nodestatesty; +begin + stat1:= nodestatesty(longword(fstate) xor longword(value)); + fstate := Value; + if stat1 * invalidatestates <> [] then begin + change(); + end; + if stat1 * valuechangestates <> [] then begin + valuechange(stat1); + end; +end; + +procedure tlistitem.setimagenr(const Value: integer); +begin + if fimagenr <> value then begin + fimagenr := Value; + change; + end; +end; + +procedure tlistitem.mouseevent(var info: mouseeventinfoty); +//var +// bo1: boolean; +begin + with info do begin + if eventkind in mouseposevents then begin + if pointinrect(pos, + fowner.fintf.getlayoutinfo(nil)^.checkboxinnerrect) then begin + if (eventkind = ek_buttonrelease) then begin + if (shiftstate * keyshiftstatesmask = []) and (button = mb_left) and + (ns1_checkboxclicked in fstate1) then begin + checked:= not checked; + include(eventstate,es_processed); + end; + exclude(fstate1,ns1_checkboxclicked); + end + else begin + if (eventkind = ek_buttonpress) and + (shiftstate * keyshiftstatesmask = []) and + (button = mb_left) then begin + include(fstate1,ns1_checkboxclicked); + end; + end; + end + else begin + exclude(fstate1,ns1_checkboxclicked); + end + end; + if eventkind in [ek_mouseleave,ek_clientmouseleave] then begin + exclude(fstate1,ns1_checkboxclicked); + end; + end; +end; + +procedure tlistitem.focusrow(); +var + grid1: tcustomgrid; +begin + if (fowner <> nil) then begin + grid1:= fowner.fintf.getgrid(); + if grid1 <> nil then begin + grid1.row:= findex; + end; + end; +end; + +function tlistitem.getselected: boolean; +begin + result:= ns_selected in fstate; +end; + +procedure tlistitem.setselected(const Value: boolean); +begin + if value then begin + setstate(fstate + [ns_selected]); + end + else begin + setstate(fstate - [ns_selected]); + end; +end; + +function tlistitem.getchecked: boolean; +begin + result:= ns_checked in fstate; +end; + +procedure tlistitem.setchecked(const avalue: boolean); +begin + if avalue then begin + setstate(fstate + [ns_checked]); + end + else begin + setstate(fstate - [ns_checked]); + end; +end; + +function tlistitem.getcheckbox: boolean; +begin + result:= ns_checkbox in fstate; +end; + +procedure tlistitem.setcheckbox(const avalue: boolean); +begin + if avalue then begin + setstate(fstate + [ns_checkbox]); + end + else begin + setstate(fstate - [ns_checkbox]); + end; +end; + +function tlistitem.checkaction(aaction: nodeactionty): boolean; +var + action: nodeactioninfoty; +begin + action.action:= aaction; + actionnotification(action); + result:= action.action = aaction; +end; + +procedure tlistitem.actionnotification(var ainfo: nodeactioninfoty); +begin + if fowner <> nil then begin + fowner.nodenotification(self,ainfo); + end; +end; + +function tlistitem.getactimagenr( + const alayoutinfo: listitemlayoutinfoty): integer; +begin + result:= fowner.fimnr_base + fimagenr; + if not (ns_imagenrfix in fstate) then begin + if ns_expanded in fstate then begin + inc(result,fowner.fimnr_expanded); + end; + if ns_selected in fstate then begin + inc(result,fowner.fimnr_selected); + end; + if ns_readonly in fstate then begin + inc(result,fowner.fimnr_readonly); + end; + if ns_checked in fstate then begin + inc(result,fowner.fimnr_checked); + end; + if ns_subitems in fstate then begin + inc(result,fowner.fimnr_subitems); + end; + if ws_focused in alayoutinfo.variable.widgetstate then begin + inc(result,fowner.fimnr_focused); + end; + if ws_active in alayoutinfo.variable.widgetstate then begin + inc(result,fowner.fimnr_active); + end; + end; +end; + +procedure tlistitem.setimagelist(const Value: timagelist); +begin + if fimagelist <> value then begin + if fowner <> nil then begin + if (fimagelist <> nil) and (fimagelist <> fowner.imagelist) then begin + fowner.unregisterobject(ievent(fimagelist)); + end; + if (value <> nil) and (value <> fowner.fimagelist) then begin + fowner.registerobject(ievent(value)); + end; + end; + fimagelist:= value; + change; + end; +end; + +function tlistitem.getimagelist: timagelist; +begin + if fimagelist = nil then begin + if (fowner <> nil) and not (ns1_nodefaultimagelist in fstate1) then begin + result:= fowner.fimagelist; + end + else begin + result:= nil; + end; + end + else begin + result:= fimagelist; + end; +end; + +function tlistitem.getvaluetext: msestring; +begin + result:= fcaption; +end; + +procedure tlistitem.setvaluetext(var avalue: msestring); +begin + caption:= avalue; +end; + +procedure tlistitem.setvaluetext1(const avalue: msestring); +var + str1: msestring; +begin + str1:= avalue; + setvaluetext(str1); +end; + +procedure tlistitem.objectevent(const sender: tobject; + const event: objecteventty); +begin + if sender = fimagelist then begin + case event of + oe_destroyed: begin + fimagelist:= nil; + change; + end; + oe_changed: begin + change; + end; + end; + end; +end; + +procedure tlistitem.setowner(const aowner: tcustomitemlist); +begin + if aowner <> fowner then begin + findex:= -1; + if (fowner <> nil) and (fimagelist <> nil) then begin + fowner.unregisterobject(ievent(fimagelist)); + end; + fowner:= aowner; + if (fimagelist <> nil) and (fowner <> nil) then begin + fowner.registerobject(ievent(fimagelist)); + end; + end; +end; + +procedure tlistitem.beginupdate; +begin + if fowner <> nil then begin + fowner.beginupdate; + end; +end; + +procedure tlistitem.endupdate; +begin + if fowner <> nil then begin + fowner.endupdate; + end; +end; + +procedure tlistitem.dostatread(const reader: tstatreader); +var + ca1: longword; +begin + reader.readrecord('a',[@tag,@ca1,@fimagenr,@fcaption], + [tag,longword(fstate),fimagenr,fcaption]); + fstate:= nodestatesty(replacebits(ca1,longword(fstate),longword(statstates))); +end; + +procedure tlistitem.dostatwrite(const writer: tstatwriter); +begin + writer.writerecord('a',[tag,longword(fstate),fimagenr,fcaption]); +end; + +procedure tlistitem.dostatupdate(const filer: tstatfiler); +begin + if filer.iswriter then begin + dostatwrite(tstatwriter(filer)); + end + else begin + dostatread(tstatreader(filer)); + end; +end; + +function tlistitem.empty: boolean; +begin + result:= fcaption = ''; +end; + +procedure tlistitem.releaseowner; +begin + setowner(nil); +end; + +function tlistitem.compare(const r: tlistitem; + const acasesensitive: boolean): integer; +begin + result:= 0; + if ns1_top in fstate1 then begin + dec(result); + end; + if ns1_top in r.fstate1 then begin + inc(result); + end; + if result = 0 then begin + if acasesensitive then begin +// result:= msestringcomp(fcaption,r.fcaption); + result:= msecomparestr(fcaption,r.fcaption); + end + else begin +// result:= msestringicomp(fcaption,r.fcaption); + result:= msecomparetext(fcaption,r.fcaption); + end; + end; +end; + +{ tcustomitemlist } + +constructor tcustomitemlist.create; +begin + fcaptionpos:= cp_right; + fimagealignment:= [al_xcentered,al_ycentered]; + flevelstep:= defaultlevelstep; + ffonts:= tfontarrayprop.create(); + inherited; + fitemclass:= tlistitem; +end; + +constructor tcustomitemlist.create(const intf: iitemlist); +begin + fintf:= intf; + create; +end; + +destructor tcustomitemlist.destroy; +begin + include(fitemstate,ils_destroying); + inherited; + ffonts.free(); + fobjectlinker.free; +end; + +function tcustomitemlist.indexof(const aitem: tlistitem): integer; +var + po1: ppointeraty; + int1: integer; +begin + result:= -1; + normalizering; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if tlistitem(po1^[int1]) = aitem then begin + result:= int1; + break; + end; + end; +end; + +procedure tcustomitemlist.doitemchange(const index: integer); +var + int1: integer; + po1: ^tlistitem; +begin + if index = -1 then begin + po1:= datapo; + for int1:= 0 to count-1 do begin + if po1^ <> nil then begin + po1^.findex:= int1; + end; + inc(po1); + end; + end; + inherited; +end; + +function tcustomitemlist.getitems1(const index: integer): tlistitem; +begin + result:= tlistitem(inherited items[index]); +end; + +procedure tcustomitemlist.setitems(const index: integer; + const Value: tlistitem); +begin + inherited items[index]:= value; +end; +(* +function tcustomitemlist.getobjectlinker: tobjectlinker; +begin + createobjectlinker(self,{$ifdef FPC}@{$endif}objectevent, + fobjectlinker); + result:= fobjectlinker; +end; +*) +procedure tcustomitemlist.objectevent(const sender: tobject; + const event: objecteventty); +var + po1,pe: plistitem; +begin + inherited; + if (event <> oe_connect) then begin + normalizering; + po1:= plistitem(fdatapo); + pe:= po1 + count; + while po1 < pe do begin + po1^.objectevent(sender,event); + inc(po1); + end; + if sender = fimagelist then begin + case event of + // oe_destroyed: imagelist:= nil; + oe_changed: invalidate; + end; + end; + end; +end; + +procedure tcustomitemlist.invalidate; +begin + //dummy +end; + +procedure tcustomitemlist.setimageheight(const Value: integer); +begin + if fimagesize.cy <> value then begin + fimagesize.cy := Value; + updatelayout; +// invalidate; + end; +end; + +procedure tcustomitemlist.setimagewidth(const Value: integer); +begin + if fimagesize.cx <> value then begin + fimagesize.cx := Value; + updatelayout; +// invalidate; + end; +end; + +procedure tcustomitemlist.setimagesize(const avalue: sizety); +begin + if (fimagesize.cx <> avalue.cx) or (fimagesize.cy <> avalue.cy) then begin + fimagesize:= avalue; + updatelayout; + end; +end; + +procedure tcustomitemlist.setimagealignment(const avalue: alignmentsty); +begin + if fimagealignment <> avalue then begin + movealignment(avalue,fimagealignment); + updatelayout; + end; +end; + +procedure tcustomitemlist.setimagelist(const Value: timagelist); +var + imagelistbefore: timagelist; +begin + if fimagelist <> value then begin + imagelistbefore:= fimagelist; + setlinkedcomponent(iobjectlink(self),value,tmsecomponent(fimagelist)); + if (fimagelist <> nil) and + (fintf.getcomponentstate * [csdesigning,csloading] = + [csdesigning]) then begin + if (imagelistbefore = nil) or + (imagelistbefore.width = fimagesize.cx) then begin + fimagesize.cx:= fimagelist.width; + end; + if (imagelistbefore = nil) or + (imagelistbefore.height = fimagesize.cy) then begin + fimagesize.cy:= fimagelist.height; + end; + end; + updatelayout; +// invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_base(const Value: integer); +begin + if fimnr_base <> value then begin + fimnr_base:= Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_expanded(const Value: integer); +begin + if fimnr_expanded <> value then begin + fimnr_expanded:= Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_selected(const Value: integer); +begin + if fimnr_selected <> value then begin + fimnr_selected:= Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_readonly(const Value: integer); +begin + if fimnr_readonly <> value then begin + fimnr_readonly:= Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_checked(const Value: integer); +begin + if fimnr_checked <> value then begin + fimnr_checked := Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_subitems(const Value: integer); +begin + if fimnr_subitems <> value then begin + fimnr_subitems := Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_focused(const avalue: integer); +begin + if fimnr_focused <> avalue then begin + fimnr_focused := avalue; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_active(const avalue: integer); +begin + if fimnr_active <> avalue then begin + fimnr_active := avalue; + invalidate; + end; +end; + +procedure tcustomitemlist.setoptions(const Value: nodeoptionsty); +var + optionsbefore: nodeoptionsty; +begin + if foptions <> value then begin + optionsbefore:= foptions; + foptions:= Value; + if no_nofreeitems in value then begin + exclude(fstate,dls_needsfree); + end + else begin + include(fstate,dls_needsfree); + end; + if nodeoptionsty({$ifdef FPC}longword{$else}byte{$endif}(foptions) xor + {$ifdef FPC}longword{$else}byte{$endif}(optionsbefore)) * + [no_checkbox] <> [] then begin + updatelayout; + end + else begin + invalidate; + end; + end; +end; + +procedure tcustomitemlist.setcaptionpos(const Value: captionposty); +begin + if fcaptionpos <> value then begin + fcaptionpos := Value; + updatelayout; + end; +end; + +procedure tcustomitemlist.updatelayout; +begin + if fintf <> nil then begin + fintf.updatelayout; + invalidate; + end; +end; + +procedure tcustomitemlist.docreateobject(var instance: tobject); +begin + inherited; + if instance = nil then begin + createitem(tlistitem(instance)); + end; +end; + +procedure tcustomitemlist.createitem(out item: tlistitem); +begin + item:= listitemclassty(fitemclass).create(self); +end; + +procedure tcustomitemlist.createstatitem(const reader: tstatreader; + out item: tlistitem); +begin + createitem(item); +end; + +procedure tcustomitemlist.statreaditem(const reader: tstatreader; + var aitem: tlistitem); +begin + if assigned(fonstatreaditem) then begin + fonstatreaditem(self,reader,aitem); + end; + if aitem = nil then begin + createstatitem(reader,aitem); + end; +end; + +procedure tcustomitemlist.statreadtreeitem(const reader: tstatreader; + const parent: ttreelistitem; var aitem: ttreelistitem); +begin + if assigned(fonstatreadtreeitem) then begin + fonstatreadtreeitem(self,reader,aitem); + end; + if aitem = nil then begin + if parent <> nil then begin + aitem:= parent.createsubnode; + end + else begin + createitem(tlistitem(aitem)); + end; + end; +end; + +procedure tcustomitemlist.statwriteitem(const writer: tstatwriter; + const aitem: tlistitem); +begin + if assigned(fonstatwriteitem) then begin + fonstatwriteitem(self,writer,aitem); + end; +end; + +procedure tcustomitemlist.statwritetreeitem(const writer: tstatwriter; + const aitem: ttreelistitem); +begin + if assigned(fonstatwritetreeitem) then begin + fonstatwritetreeitem(self,writer,aitem); + end; +end; + +function tcustomitemlist.nodezone(const point: pointty): cellzonety; +begin + result:= cz_default; + with fintf.getlayoutinfo(nil)^ do begin + if pointinrect(point,captionrect) then begin + result:= cz_caption; + end + else begin + if pointinrect(point,imagerect) then begin + result:= cz_image; + end; + end; + end; +end; + +procedure tcustomitemlist.nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); +begin + if ainfo.action = na_destroying then begin + if not deleting then begin + deletedata(sender.index); + end; + end + else begin + if (ainfo.action = na_change) then begin + change(sender); + end; + end; +end; + +procedure tcustomitemlist.setitemselected(const row: integer; + const value: boolean); +var + po1: plistitematy; + int1: integer; +begin + if (no_cellitemselect in foptions) and + not (dls_selectsetting in fstate) then begin + if row >= 0 then begin + with items[row] do begin + if value then begin + include(fstate,ns_selected); + end + else begin + exclude(fstate,ns_selected); + end; + end; + end + else begin + po1:= datapo; + if value then begin + for int1:= 0 to count - 1 do begin + include(po1^[int1].fstate,ns_selected); + end; + end + else begin + for int1:= 0 to count - 1 do begin + exclude(po1^[int1].fstate,ns_selected); + end; + end; + end; + end; +end; + +procedure tcustomitemlist.freedata(var data); +begin + if not (no_nofreeitems in foptions) and (tlistitem(data) <> nil) and + not (ns1_destroying in tlistitem(data).fstate1) then begin + inherited; + end; +end; + +procedure tcustomitemlist.change(const item: tlistitem); +begin + if item = nil then begin + change(-1); + end + else begin + change(item.findex); + end; +end; + +procedure tcustomitemlist.setlevelstep(const Value: integer); +begin + if flevelstep <> value then begin + flevelstep := Value; + change(-1); + end; +end; + +procedure tcustomitemlist.registerobject(const aobject: iobjectlink); +begin + getobjectlinker.link(iobjectlink(self),aobject); +end; + +procedure tcustomitemlist.unregisterobject(const aobject: iobjectlink); +begin + getobjectlinker.unlink(iobjectlink(self),aobject); +end; + +function tcustomitemlist.add(const aitem: tlistitem): integer; +begin + aitem.setowner(self); + result:= inherited add(aitem); +end; + +procedure tcustomitemlist.add(const aitems: array of msestring); +var + int1,int2: integer; + po1: plistitem; +begin + beginupdate; + try + int1:= count; + count:= count + length(aitems); + po1:= datapo; + inc(po1,int1); + for int2:= 0 to high(aitems) do begin + po1^.caption:= aitems[int2]; + inc(po1); + end; + finally + endupdate; + end; +end; + +procedure tcustomitemlist.add(const aitems: msestringarty); +var + int1,int2: integer; + po1: plistitem; +begin + beginupdate; + try + int1:= count; + count:= count + length(aitems); + po1:= datapo; + inc(po1,int1); + for int2:= 0 to high(aitems) do begin + po1^.caption:= aitems[int2]; + inc(po1); + end; + finally + endupdate; + end; +end; + +function tcustomitemlist.add(const aitem: msestring): integer; +begin + result:= count; + add([aitem]); +end; + +procedure tcustomitemlist.add(const aitems: listitemarty); +var + int1: integer; +begin + beginupdate; + try + for int1:= 0 to high(aitems) do begin + add(aitems[int1]); + end; + finally + endupdate; + end; +end; + +procedure tcustomitemlist.writestate(const writer; const name: msestring); +var + int1: integer; + po1: ppointeraty; + item1: tlistitem; +begin + dostatwrite(tstatwriter(writer),name); + po1:= datapo; + with tstatwriter(writer) do begin + writeinteger(name,count); + for int1:= 0 to count - 1 do begin + beginlist; + item1:= tlistitem(po1^[int1]); + statwriteitem(tstatwriter(writer),item1); + item1.dostatwrite(tstatwriter(writer)); + endlist; + end; + end; +end; + +procedure tcustomitemlist.readstate(const reader; const acount: integer; + const name: msestring); +var + int1: integer; + item1: tlistitem; +begin + dostatread(tstatreader(reader),name); + with tstatreader(reader) do begin + int1:= acount; + if int1 >= 0 then begin + beginupdate; + try + clear; + for int1:= 0 to acount - 1 do begin + beginlist; + item1:= nil; + statreaditem(tstatreader(reader),item1); + if item1 <> nil then begin + add(item1); + item1.dostatread(tstatreader(reader)); + end; + endlist; + end; + finally + endupdate; + end; + end; + end; +end; + +function tcustomitemlist.getitems(const must: nodestatesty; + const mustnot: nodestatesty): listitemarty; +var + int1: integer; + int2: integer; + item1: tlistitem; + po1: ppointeraty; +begin + result:= nil; + int2:= 0; + po1:= datapo; + for int1:= 0 to count - 1 do begin + item1:= tlistitem(po1^[int1]); + with item1 do begin + if (fstate * must = must) and (fstate * mustnot = []) then begin + if int2 > high(result) then begin + setlength(result,10+length(result)*2); + end; + result[int2]:= item1; + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +function tcustomitemlist.getindexes(const must: nodestatesty; + const mustnot: nodestatesty): integerarty; +var + int1: integer; + int2: integer; + item1: tlistitem; + po1: ppointeraty; +begin + result:= nil; + int2:= 0; + po1:= datapo; + for int1:= 0 to count - 1 do begin + item1:= tlistitem(po1^[int1]); + with item1 do begin + if (fstate * must = must) and (fstate * mustnot = []) then begin + if int2 > high(result) then begin + setlength(result,10+length(result)*2); + end; + result[int2]:= int1; + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +function tcustomitemlist.getselecteditems: listitemarty; +begin + result:= getitems([ns_selected],[]); +end; + +function tcustomitemlist.getselectedindexes: integerarty; +begin + result:= getindexes([ns_selected],[]); +end; + +function tcustomitemlist.getcheckeditems: listitemarty; +begin + result:= getitems([ns_checked],[]); +end; + +function tcustomitemlist.getcheckedindexes: integerarty; +begin + result:= getindexes([ns_checked],[]); +end; + +function tcustomitemlist.empty(const index: integer): boolean; +var + item1: tlistitem; +begin + item1:= items[index]; + result:= (item1 = nil) or item1.empty; +end; + +function tcustomitemlist.layoutinfopo: plistitemlayoutinfoty; +begin + result:= fintf.getlayoutinfo(nil); +end; + +procedure tcustomitemlist.dostatread(const reader: tstatreader; + const name: msestring); +begin + if assigned(fonstatread) then begin + fonstatread(self,reader,name); + end; +end; + +procedure tcustomitemlist.dostatwrite(const writer: tstatwriter; + const name: msestring); +begin + if assigned(fonstatwrite) then begin + fonstatwrite(self,writer,name); + end; +end; + +procedure tcustomitemlist.removeitem(const aindex: integer); +var + bo1: boolean; +begin + bo1:= ils_freelock in fitemstate; + include(fitemstate,ils_freelock); + try + deleteitems(aindex,1); + finally + if not bo1 then begin + exclude(fitemstate,ils_freelock); + end; + end; +end; + +procedure tcustomitemlist.setfonts(const avalue: tfontarrayprop); +begin + ffonts.assign(avalue); +end; + +procedure tcustomitemlist.setcount(const value: integer); +begin + if value < fcount then begin + inc(fdeleting); + try + inherited; + finally + dec(fdeleting); + end; + end + else begin + inherited; + end; +end; + +function tlistitem.gettop: boolean; +begin + result:= ns1_top in fstate1; +end; + +procedure tlistitem.settop(const avalue: boolean); +begin + if avalue then begin + include(fstate1,ns1_top); + end + else begin + exclude(fstate1,ns1_top); + end; +end; + +function tlistitem.cancaptionedit: boolean; +begin + result:= not (ns_readonly in fstate) and not (ns1_fixedcaption in fstate1); +end; + +function tlistitem.canvalueedit: boolean; +begin + result:= not (ns_readonly in fstate); +end; + +function tlistitem.getvalueitem: tlistitem; +begin + result:= self; +end; + +procedure tlistitem.setvalueitem(const avalue: tlistitem); +begin + //dummy +end; + +function tlistitem.getownerintf: iitemlist inline; +begin + result:= fowner.fintf; +end; + +{ ttreelistitem } + +constructor ttreelistitem.create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); +begin + if aparent <> nil then begin + if aparent <> fparent then begin + fparent:= aparent; + fparentindex:= -1; + end; + end; + if fparent = nil then begin + fparentindex:= -1; + end; + inherited create(aowner); +end; + +destructor ttreelistitem.destroy; +begin + if not (ns1_destroying in fstate1) then begin + include(fstate1,ns1_destroying); + if (fowner <> nil) and not (ils_destroying in fowner.fitemstate) then begin + checkaction(na_destroying); + end; + end; + if (fparent <> nil) and not (ns1_destroying in fparent.fstate1) then begin + fparent.remove(fparentindex); + end; + clear; + inherited; +end; + +procedure ttreelistitem.countchange(const atreeheightbefore: integer; + const notifyowner: boolean); +var + info1: nodeactioninfoty; +begin + if (fowner <> nil) and notifyowner then begin + info1.action:= na_countchange; + info1.treeheightbefore:= atreeheightbefore; + fowner.nodenotification(self,info1); + end; + if fcount > 0 then begin + state:= fstate + [ns_subitems]; + end + else begin + state:= fstate - [ns_subitems]; + end; +end; + +function ttreelistitem.getitems(const aindex: integer): ttreelistitem; +begin + checkindex(aindex); + result:= fitems[aindex]; +end; + +procedure ttreelistitem.dosetitems(const aindex: integer; + const value: ttreelistitem); +begin + fitems[aindex]:= value; + value.fparentindex:= aindex; + value.fparent:= self; + value.settreelevel(ftreelevel+1); + if (fowner <> nil) and (ns_expanded in fstate) then begin + value.setowner(fowner); + end; +end; + +procedure ttreelistitem.setitems(const aindex: integer; const value: ttreelistitem); + //for internal use +begin + dosetitems(aindex,value); + checksort; +end; + +procedure ttreelistitem.unsetitem(const aindex: integer); +begin + with fitems[aindex] do begin + fparent:= nil; + fparentindex:= -1; + setowner(nil); + settreelevel(0); + end; +end; + +function ttreelistitem.inccount: integer; //returns itemindex +begin + result:= fcount; + if fcount > high(fitems) then begin + setlength(fitems,(fcount*8) div 7 + 16); + end; + inc(fcount) +end; + +function ttreelistitem.add(const aitem: ttreelistitem): integer; +var + int1: integer; +begin + result:= -1; + if aitem <> nil then begin + if aitem = self then begin + raise exception.create('Can not add self.'); + end; + if aitem.parent = self then begin + internalmove(aitem.parentindex,fcount-1); + end + else begin + if aitem.fparent <> nil then begin + aitem.fparent.remove(aitem.fparentindex); + end + else begin + if aitem.fowner <> nil then begin + aitem.fowner.removeitem(aitem.findex); + end; + end; + int1:= treeheight; + dosetitems(inccount,aitem); + countchange(int1,true); + end; + checksort; + result:= aitem.fparentindex; + end; +end; + +procedure ttreelistitem.aftermove; +begin + countchange(fcount,true); //refresh grid + checksort; +end; + +procedure ttreelistitem.insert(aindex: integer; const aitem: ttreelistitem); +var + int1,int2: integer; +begin + if aindex > count then begin + aindex:= count; + end; + if aitem.parent = self then begin + if aindex = count then begin + dec(aindex); + end; + internalmove(aitem.parentindex,aindex); + aftermove; + end + else begin + if aindex <> count then begin + checkindex(aindex); + end; + int2:= treeheight; + if aitem.fparent <> nil then begin + aitem.fparent.remove(aitem.fparentindex); + end; + inccount; + insertitem(pointerarty(fitems),aindex,aitem); + fitems[aindex]:= aitem; + for int1:= aindex to count-1 do begin + fitems[int1].fparentindex:= int1; + end; + dosetitems(aindex,aitem); + countchange(int2,true); + checksort; + end; +end; + +procedure ttreelistitem.insert(const aitem: ttreelistitem; + aindex: integer); +begin + insert(aindex,aitem); +end; + +procedure ttreelistitem.move(const source: integer; const dest: integer); +begin + internalmove(source,dest); + aftermove; +end; + +procedure ttreelistitem.add(const aitems: treelistitemarty); +var + int1,int2: integer; +begin + if length(aitems) > 0 then begin + int2:= treeheight; + if fcount + length(aitems) >= length(fitems) then begin + setlength(fitems,fcount + length(aitems)); + end; + for int1:= 0 to high(aitems) do begin + dosetitems(fcount,aitems[int1]); + inc(fcount); + end; + countchange(int2,true); + checksort; + end; +end; + +procedure ttreelistitem.addchildren(const aitem: ttreelistitem); + //transfers children +begin + setlength(aitem.fitems,aitem.fcount); + add(aitem.fitems); + aitem.fcount:= 0; +end; + +function ttreelistitem.createsubnode: ttreelistitem; +begin + result:= treelistitemclassty(classtype).create(fowner); + //child class = parent class +end; + +procedure ttreelistitem.internalswap(const a,b: integer); +var + item1: ttreelistitem; +begin + checkindex(a); + checkindex(b); + item1:= fitems[a]; + item1.fparentindex:= b; + fitems[a]:= fitems[b]; + fitems[a].fparentindex:= a; + fitems[b]:= item1; +end; + +procedure ttreelistitem.swap(const a,b: integer); +begin + internalswap(a,b); + aftermove(); +end; + +procedure ttreelistitem.internalmove(const source,dest: integer); +var + int1: integer; +begin + checkindex(source); + checkindex(dest); + moveitem(pointerarty(fitems),source,dest); + if source < dest then begin + for int1:= source to dest do begin + fitems[int1].fparentindex:= int1; + end; + end + else begin + for int1:= dest to source do begin + fitems[int1].fparentindex:= int1; + end; + end; +end; + +function ttreelistitem.add(const itemclass: treelistitemclassty = nil): ttreelistitem; +begin + if itemclass <> nil then begin + result:= itemclass.create; + end + else begin + result:= createsubnode; + end; + add(result); +end; + +procedure ttreelistitem.add(const acount: integer; + const itemclass: treelistitemclassty = nil; + const defaultstate: nodestatesty = []); +var + int1,int2: integer; +begin + int2:= treeheight; + if length(fitems) < fcount + acount then begin + setlength(fitems,fcount + acount); + end; + if itemclass <> nil then begin + for int1:= 0 to acount-1 do begin + dosetitems(fcount,itemclass.create); + if defaultstate <> [] then begin + fitems[count].fstate:= defaultstate; + end; + inc(fcount); + end; + end + else begin + for int1:= 0 to acount-1 do begin + dosetitems(fcount,createsubnode); + if defaultstate <> [] then begin + fitems[count].fstate:= defaultstate; + end; + inc(fcount); + end; + end; + countchange(int2,true); + checksort; +end; + +procedure ttreelistitem.setdestroying; +var + int1: integer; +begin + include(fstate1,ns1_destroying); + for int1:= 0 to fcount - 1 do begin + fitems[int1].setdestroying; + end; +end; + +procedure ttreelistitem.setnotbyownerdestroying; +var + int1: integer; +begin + fstate1:= fstate1+[ns1_destroying,ns1_notbyownerdestroying]; + for int1:= 0 to fcount - 1 do begin + fitems[int1].setnotbyownerdestroying; + end; +end; + +procedure ttreelistitem.clear; +var + int1,int2: integer; + acount: integer; + aitems: treelistitemarty; + adestroying: boolean; +begin + aitems:= nil; //compilerwarning + if fcount > 0 then begin + int2:= treeheight; + adestroying:= ns1_destroying in fstate1; + if not (ns1_noowner in fstate1) then begin + if fowner = nil then begin + setnotbyownerdestroying(); + end + else begin + setdestroying(); + end; + end; + aitems:= fitems; + fitems:= nil; + acount:= fcount; + fcount:= 0; + countchange(int2,true); + if not (ns1_noowner in fstate1) then begin + for int1:= 0 to acount-1 do begin + with aitems[int1] do begin + if not adestroying or + (ns1_notbyownerdestroying in fstate1) and (fowner <> nil) then begin + setowner(nil); + end; + Free; + end; + end; + end + else begin + for int1:= 0 to acount-1 do begin + with aitems[int1] do begin + fparent:= nil; + fparentindex:= -1; + end; + end; + end; + if not adestroying then begin + exclude(fstate1,ns1_destroying); + end; + end; + fitems:= nil; //ev. free unused memory + exclude(fstate1,ns1_noowner); +end; + +procedure ttreelistitem.internalgetnodes(var aresult: treelistitemarty; + var acount: integer; + const must: nodestatesty; const mustnot: nodestatesty; + const amode: getnodemodety; const addself: boolean); + + procedure addchi(anode: ttreelistitem); + var + int1: integer; + begin + with anode do begin + for int1:= 0 to fcount - 1 do begin + if acount > high(aresult) then begin + setlength(aresult,10+length(aresult)*2); + end; + aresult[acount]:= fitems[int1]; + inc(acount); + addchi(fitems[int1]); + end; + end; + end; //addchi + +var + first: boolean; + + procedure check(anode: ttreelistitem); + var + int1: integer; + bo1: boolean; + begin + with anode do begin + if not first then begin + bo1:= (fstate * must = must) and (fstate * mustnot = []); + if bo1 then begin + if acount > high(aresult) then begin + setlength(aresult,10+length(aresult)*2); + end; + aresult[acount]:= anode; + inc(acount); + end; + end + else begin + first:= false; + bo1:= false; + end; + case amode of + gno_nochildren: begin + if bo1 then begin + exit; + end; + end; + gno_allchildren: begin + if bo1 then begin + addchi(anode); + exit; + end; + end; + end; + for int1:= 0 to fcount - 1 do begin + check(fitems[int1]); + end; + end; + end; //check + +begin + first:= not addself; + check(self); +end; + +function ttreelistitem.getnodes(const must: nodestatesty; + const mustnot: nodestatesty; + const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; +var + int2: integer; +begin + result:= nil; + int2:= 0; + internalgetnodes(result,int2,must,mustnot,amode,addself); + setlength(result,int2); +end; + +function ttreelistitem.getselectednodes( + const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; +begin + result:= getnodes([ns_selected],[],amode); +end; + +function ttreelistitem.getcheckednodes( + const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; +begin + result:= getnodes([ns_checked],[],amode,addself); +end; + + +procedure ttreelistitem.internalcollapseall; +var + int1: integer; +begin + expanded:= false; + for int1:= 0 to count - 1 do begin + fitems[int1].internalcollapseall; + end; +end; + +procedure ttreelistitem.collapseall; +begin + beginupdate; + try + internalcollapseall; + finally + endupdate; + end; +end; + +procedure ttreelistitem.internalexpandall; +var + int1: integer; +begin + expanded:= true; + for int1:= 0 to count - 1 do begin + fitems[int1].internalexpandall; + end; +end; + +procedure ttreelistitem.expandall; +begin + beginupdate; + try + internalexpandall; + finally + endupdate; + end; +end; + +procedure ttreelistitem.expandtoroot(const afocusrow: boolean = true); +var + item1: ttreelistitem; +begin + item1:= fparent; + while item1 <> nil do begin + item1.expanded:= true; + item1:= item1.fparent; + end; + if afocusrow then begin + focusrow(); + end; +end; + +procedure ttreelistitem.collapsetoroot; +var + item1: ttreelistitem; +begin + item1:= fparent; + while item1 <> nil do begin + item1.expanded:= false; + item1:= item1.fparent; + end; +end; + +procedure ttreelistitem.internalcheckitems( + const checkdelete: checktreelistitemprocty); +var + int1,int2: integer; + bo1,bo2: boolean; + ar1: treelistitemarty; + aitem: ttreelistitem; +begin + bo1:= false; + for int1:= 0 to fcount - 1 do begin + aitem:= fitems[int1]; + aitem.internalcheckitems(checkdelete); + bo2:= false; + checkdelete(aitem,bo2); + if bo2 then begin + aitem.fparent:= nil; + aitem.fowner:= nil; + fitems[int1]:= nil; + aitem.Free; + bo1:= true; + end; + end; + if bo1 then begin + setlength(ar1,fcount); + int2:= 0; + for int1:= 0 to fcount -1 do begin + if fitems[int1] <> nil then begin + ar1[int2]:= fitems[int1]; + ar1[int2].fparentindex:= int2; + inc(int2); + end; + end; + setlength(ar1,int2); + fcount:= int2; + fitems:= ar1; + end; +end; + +procedure ttreelistitem.checkitems(const checkdelete: checktreelistitemprocty); +var + int1: integer; +begin + int1:= treeheight; + internalcheckitems(checkdelete); + countchange(int1,true); +end; + +function ttreelistitem.remove(const aindex: integer): ttreelistitem; +var + int1,int2: integer; +begin + checkindex(aindex); + int2:= treeheight; + result:= fitems[aindex]; + unsetitem(aindex); + int1:= (fcount-aindex-1)*sizeof(pointer); + if int1 > 0 then begin + system.move(fitems[aindex+1],fitems[aindex],int1); + end; + dec(fcount); + for int1:= aindex to fcount-1 do begin + fitems[int1].fparentindex:= int1; + end; + countchange(int2,not (ns1_destroying in result.fstate1)); +end; +{ +function comparetreelistitemcasesensitive(const l,r): integer; +begin + result:= 0; + if ns1_top in ttreelistitem(l).fstate1 then begin + dec(result); + end; + if ns1_top in ttreelistitem(r).fstate1 then begin + inc(result); + end; + if result = 0 then begin + result:= msestringcomp(ttreelistitem(l).caption,ttreelistitem(r).caption); + end; +end; + +function comparetreelistitemcaseinsensitive(const l,r): integer; +begin + result:= 0; + if ns1_top in ttreelistitem(l).fstate1 then begin + dec(result); + end; + if ns1_top in ttreelistitem(r).fstate1 then begin + inc(result); + end; + if result = 0 then begin + result:= msestringicomp(ttreelistitem(l).caption,ttreelistitem(r).caption); + end; +end; +} +function ttreelistitem.customcompare(const l: ttreelistitem; + const r: ttreelistitem): integer; +begin + result:= 0; + if ns1_top in l.fstate1 then begin + dec(result); + end; + if ns1_top in r.fstate1 then begin + inc(result); + end; +end; + +function ttreelistitem.comparecasesens(const l: ttreelistitem; + const r: ttreelistitem): integer; +begin + result:= l.compare(r,true); +end; + +function ttreelistitem.comparecaseinsens(const l: ttreelistitem; + const r: ttreelistitem): integer; +begin + result:= l.compare(r,false); +end; + +procedure ttreelistitem.sort(const casesensitive: boolean; + const recursive: boolean = false); +var + int1: integer; +{$ifndef FPC} + po1: ttreelistitemcomparefuncty; +{$endif} +begin + if ns1_customsort in fstate1 then begin + {$ifdef FPC} + mergesort(pointerarty(fitems),fcount,pointercomparemethodty(@customcompare)); + {$else} + po1:= self.customcompare; + mergesort(pointerarty(fitems),fcount,pointercomparemethodty(po1)); + {$endif} + end + else begin + if casesensitive then begin + {$ifdef FPC} + mergesort(pointerarty(fitems),fcount,pointercomparemethodty( + @comparecasesens)); + {$else} + po1:= self.comparecasesens; + mergesort(pointerarty(fitems),fcount,pointercomparemethodty(po1)); + {$endif} + end + else begin + {$ifdef FPC} + mergesort(pointerarty(fitems),fcount,pointercomparemethodty( + @comparecaseinsens)); + {$else} + po1:= self.comparecaseinsens; + mergesort(pointerarty(fitems),fcount,pointercomparemethodty(po1)); + {$endif} + end; + end; + for int1:= 0 to fcount-1 do begin + fitems[int1].fparentindex:= int1; + end; + if recursive then begin + for int1:= 0 to fcount-1 do begin + fitems[int1].sort(casesensitive,true); + end; + end; + checkaction(na_aftersort); + change; +end; + +procedure ttreelistitem.sort(const sortfunc: arraysortcomparety; + const recursive: boolean = false); +var + int1: integer; +begin + setlength(fitems,fcount); + sortarray(pointerarty(fitems),sortfunc); + for int1:= 0 to high(fitems) do begin + fitems[int1].fparentindex:= int1; + end; + if recursive then begin + for int1:= 0 to high(fitems) do begin + fitems[int1].sort(sortfunc,true); + end; + end; + checkaction(na_aftersort); + change; +end; + +procedure ttreelistitem.checksort; +begin + if ns_sorted in fstate then begin + sort(ns_casesensitive in fstate); + end; +end; + +procedure ttreelistitem.setcaption(const avalue: msestring); +begin + inherited; + if fparent <> nil then begin + fparent.checksort; + end; +end; + +procedure ttreelistitem.setowner(const aowner: tcustomitemlist); +var + int1: integer; +begin + inherited; + if (aowner = nil) or (ns_expanded in fstate) then begin + for int1:= 0 to fcount - 1 do begin + fitems[int1].setowner(aowner); + end; + end; + change(); +end; + +procedure ttreelistitem.updatechildcheckedstate; +var + node1: ttreelistitem; + int1: integer; +begin + node1:= fparent; + if ns_checked in fstate then begin + while (node1 <> nil) and not (ns1_childchecked in node1.fstate1) do begin + include(node1.fstate1,ns1_childchecked); + node1.change; + node1:= node1.fparent; + end; + end + else begin + if not (ns1_childchecked in fstate1) then begin + while (node1 <> nil) and (ns_showchildchecked in node1.fstate) and + (ns1_childchecked in node1.fstate1) do begin + with node1 do begin + for int1:= 0 to fcount-1 do begin + with fitems[int1] do begin + if (ns_checked in fstate) or (ns1_childchecked in fstate1) then begin + exit; + end; + end; + end; + exclude(fstate1,ns1_childchecked); + change; + if ns_checked in fstate then begin + exit; + end; + node1:= fparent; + end; + end; + end; + end; +end; + +procedure ttreelistitem.updatechildnotcheckedstate(); +var + node1: ttreelistitem; + i1: integer; +begin + if not (ns1_childnotchecked in fstate1) then begin + node1:= fparent; + if ns_checked in fstate then begin + while (node1 <> nil) and (ns_showchildnotchecked in node1.fstate) and + (ns1_childnotchecked in node1.fstate1) do begin + with node1 do begin + for i1:= 0 to fcount-1 do begin + with fitems[i1] do begin + if not (ns_checked in fstate) or + (ns1_childnotchecked in fstate1) then begin + exit; + end; + end; + end; + exclude(fstate1,ns1_childnotchecked); + change(); + node1:= fparent; + end; + end; + end + else begin + while (node1 <> nil) and (ns_showchildnotchecked in node1.fstate) and + not (ns1_childnotchecked in node1.fstate1) do begin + with node1 do begin + include(fstate1,ns1_childnotchecked); + change(); + node1:= fparent; + end; + end; + end; + end; +end; + +procedure ttreelistitem.updatechildcheckedtree; +var + int1: integer; +begin + updatechildcheckedstate; + for int1:= 0 to fcount-1 do begin + with fitems[int1] do begin + updatechildcheckedtree; + end; + end; +end; + +procedure ttreelistitem.updatechildnotcheckedtree; +var + int1: integer; +begin + updatechildnotcheckedstate; + for int1:= 0 to fcount-1 do begin + with fitems[int1] do begin + updatechildnotcheckedtree; + end; + end; +end; + +procedure ttreelistitem.doupdateparentnotcheckedstate(const aset: boolean); + + procedure doset(const anode: ttreelistitem); + var + int1: integer; + begin + with anode do begin + if not (ns1_parentnotchecked in fstate1) then begin + include(fstate1,ns1_parentnotchecked); + for int1:= 0 to fcount-1 do begin + doset(fitems[int1]); + end; + change(); + end; + end; + end; + + procedure doclear(const anode: ttreelistitem); + var + int1: integer; + begin + with anode do begin + exclude(fstate1,ns1_parentnotchecked); + for int1:= 0 to fcount-1 do begin + if ns_checked in fstate then begin + doclear(fitems[int1]); + end; + end; + change(); + end; + end; + +var + int1: integer; + +begin + if aset then begin + for int1:= 0 to fcount-1 do begin + doset(fitems[int1]); + end; + end + else begin + for int1:= 0 to fcount-1 do begin + doclear(fitems[int1]); + end; + end; +end; + +procedure ttreelistitem.updateparentnotcheckedstate(); +begin + doupdateparentnotcheckedstate(not (ns_checked in fstate) or + (ns1_parentnotchecked in fstate1)); +end; + +procedure ttreelistitem.updateparentnotcheckedtree(); + + procedure doupdate(const anode: ttreelistitem; avalue: boolean); + var + int1: integer; + begin + with anode do begin + if avalue then begin + include(fstate1,ns1_parentnotchecked); + end + else begin + exclude(fstate1,ns1_parentnotchecked); + end; + avalue:= avalue or not checked; + for int1:= 0 to fcount-1 do begin + doupdate(fitems[int1],avalue); + end; + end; + end; + +var + int1: integer; + bo1: boolean; +begin + bo1:= not (ns_checked in fstate); + for int1:= 0 to fcount-1 do begin + doupdate(fitems[int1],bo1); + end; +end; + + +procedure ttreelistitem.setchecked(const avalue: boolean); +begin + if avalue xor (ns_checked in fstate) then begin + inherited; + if (fowner <> nil) then begin + if (no_updatechildchecked in fowner.foptions) then begin + updatechildcheckedstate(); + end; + if (no_updatechildnotchecked in fowner.foptions) then begin + updatechildnotcheckedstate(); + end; + if (no_updateparentnotchecked in fowner.foptions) then begin + updateparentnotcheckedstate(); + end; + end; + end; +end; +{ +procedure ttreelistitem.updatedrawinfo(var ainfo: treeitemdrawinfoty); +begin + //dummy +end; +} +procedure ttreelistitem.drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty); +var + po1,poend: ptreelistitem; + + function isnotlast(const aitem: ttreelistitem): boolean; + begin + if po1 = nil then begin + result:= aitem.fparentindex <> aitem.fparent.fcount - 1; + end + else begin + result:= po1 = poend; + while pchar(po1) < pchar(poend) do begin + if po1^.treelevel <= aitem.treelevel then begin + result:= po1^.treelevel = aitem.treelevel; + break; + end; + inc(po1); + end; + end; + end; + +var + box: treeitemboxty; + int1: integer; + bo1: boolean; + {$ifdef mswindows} +/// int2: integer; + {$endif} + item1: ttreelistitem; + seg: segmentty; + lines: segmentarty; + cellheight{,boxy}: integer; + nopaint: boolean; +// drawinfo: treeitemdrawinfoty; + +begin + nopaint:= (acanvas = nil) or alayoutinfo.variable.calcautocellsize; + alayoutinfo.variable.treelevelshift:= levelshift; + if not nopaint then begin //acanvas <> nil then begin + if (fcount = 0) and not (ns_subitems in fstate) and + not ((ns_drawemptyexpand in fstate) or + (no_drawemptyexpand in fowner.foptions)) then begin + if (ns_drawemptybox in fstate) or + (no_drawemptybox in fowner.foptions) then begin + box:= tib_empty; + end + else begin + box:= tib_none; + end; + end + else begin + if ns_expanded in fstate then begin + box:= tib_expanded;//integer(stg_boxexpanded); + end + else begin + box:= tib_expand;//integer(stg_boxexpand); + end; + end; + { + with drawinfo do begin + boxkind:= box; + boximageid:= treeitemboxids[box]; + flags:= treeitemdrawingflags; + end; + updatedrawinfo(drawinfo); + } + setlength(lines,ftreelevel+2); //last line can be doubled + horz. line + with fowner,alayoutinfo do begin + acanvas.move(makepoint(variable.treelevelshift,0)); + cellheight:= cellsize.cy; + seg.a.x:= (expandboxrect.x + expandboxrect.cx) div 2; + seg.a.y:= 0; + seg.b.x:= seg.a.x; + seg.b.y:= cellheight-1; + item1:= self; + int1:= 0; + po1:= nil; + if (fowner <> nil) and fowner.frearanged then begin + po1:= ptreelistitem(fowner.datapo); + poend:= @ppointeraty(po1)[fowner.count-1]; + po1:= @ppointeraty(po1)[variable.rowindex + 1]; + end; + bo1:= (fparent = nil) or isnotlast(self); + //bo1 not used if parent = nil + while item1.fparent <> nil do begin + if (int1 = 0) or isnotlast(item1) then begin + lines[int1]:= seg; + inc(int1); + end; + dec(seg.a.x,flevelstep); + seg.b.x:= seg.a.x; + item1:= item1.fparent; + end; + if int1 > 0 then begin + if bo1 then begin +// if fparentindex <> fparent.fcount - 1 then begin + if box <> tib_none then begin + lines[0].b.y:= expandboxrect.y-1; //top of splited vert. + lines[int1]:= lines[0]; + with lines[int1] do begin + a.y:= b.y + expandboxrect.cy; //bottom of splited vert. + b.y:= cellheight-1; + end; + inc(int1); + end; + end + else begin //last vert. + if box <> tib_none then begin + lines[0].b.y:= expandboxrect.y-1; //to top of box + end + else begin + lines[0].b.y:= cellheight div 2; + end; + end; + with lines[int1] do begin + if box <> tib_none then begin + dec(int1); + end + else begin + a.y:= cellheight div 2; + b.y:= a.y; + a.x:= lines[0].a.x + 1; + b.x:= checkboxrect.x - 1; //horizontal line + if b.x < a.x then begin + dec(int1); + end; + end; + end; + setlength(lines,int1+1); + if no_solidline in options then begin + acanvas.drawlinesegments(lines,variable.colorline); + end + else begin + drawdottedlinesegments(acanvas,lines,variable.colorline); + end; + end; + if box <> tib_none then begin + stockobjects.glyphs.paint(acanvas,boxids[box],expandboxrect, + [al_xcentered,al_ycentered],variable.colorglyph, + cl_default,cl_default,variable.glyphversion); + end; + end; + end; + inherited; +end; + +procedure ttreelistitem.setupeditor(const editor: tinplaceedit; + const font: tfont; const notext: boolean); +var +// int1: integer; + info1: drawtextinfoty; + po1: plistitemlayoutinfoty; +begin + if fowner <> nil then begin + po1:= fowner.fintf.getlayoutinfo(nil); + po1^.variable.calcautocellsize:= true; + drawimage(editor.getfontcanvas(),po1^); //calc image extend + with po1^ do begin + info1.font:= font; + with info1 do begin + tabulators:= nil; + dest:= captioninnerrect; + inc(dest.cx,variable.extra.caption.cx); + inc(dest.cy,variable.extra.caption.cy); + clip:= captionrect; + inc(clip.cx,variable.extra.caption.cx); + inc(clip.cy,variable.extra.caption.cy); + if not notext then begin + text.text:= fcaption; + end + else begin + text.text:= editor.text; + end; + flags:= textflags; + inc(dest.x,variable.treelevelshift); + inc(clip.x,variable.treelevelshift); + { + int1:= levelshift; + inc(dest.x,int1); + dec(dest.cx,int1); + inc(clip.x,int1); + dec(clip.cx,int1); + } + updatecaption(editor.getfontcanvas,po1^,info1); + editor.setup(text.text,editor.curindex,false,dest,clip,nil,nil,font); + end; + end; + end; +end; + +class procedure ttreelistitem.calcitemlayout(const asize: sizety; + const ainnerframe: framety; const list: tcustomitemlist; + var info: listitemlayoutinfoty); +var + boxdist: integer; +begin +// info.colorline:= cl_gray; + inherited; + boxdist:= boxsize + 2; + with info.captionrect do begin + inc(x,boxdist); + dec(cx,boxdist); + end; + with info.captioninnerrect do begin + inc(x,boxdist); + dec(cx,boxdist); + end; + with info.checkboxrect do begin + inc(x,boxdist); + end; + with info.checkboxinnerrect do begin + inc(x,boxdist); + end; + inc(info.imagerect.x,boxdist); + with info.expandboxrect do begin + x:= 0; + y:= (asize.cy - boxsize) div 2; + cx:= boxsize; + cy:= boxsize; + end; + info.minsize.cx:= info.minsize.cx + boxdist; + if info.minsize.cy < boxsize then begin + info.minsize.cy:= boxsize; + end; +end; + +procedure ttreelistitem.updatecellzone(const pos: pointty; var zone: cellzonety); +var + po1: pointty; +begin + po1:= pos; + dec(po1.x,levelshift); + inherited updatecellzone(po1,zone); +end; + +procedure ttreelistitem.mouseevent(var info: mouseeventinfoty); +begin + with info do begin + dec(pos.x,levelshift); + try + inherited; + if (eventkind = ek_buttonpress) and + (shiftstate * keyshiftstatesmask = []) and (button = mb_left) and + pointinrect(pos,fowner.fintf.getlayoutinfo(nil)^.expandboxrect) then begin + expanded:= not expanded; + include(eventstate,es_processed); + end; + finally + inc(pos.x,levelshift); + end; + end; +end; + +function ttreelistitem.getexpanded: boolean; +begin + result:= ns_expanded in fstate; +end; + +function ttreelistitem.getrootexpanded: boolean; +begin + result:= fowner <> nil; +end; + +procedure ttreelistitem.setrootexpanded(const avalue: boolean); +var + n1,n2: ttreelistitem; + bo1: boolean; +begin + n1:= self.fparent; + if avalue then begin + bo1:= false; + n2:= self; + while n2 <> nil do begin //check if tree has itemlist + bo1:= n2.fowner <> nil; + if bo1 then begin + break; + end; + n2:= n2.fparent; + end; + while bo1 and (n1 <> nil) do begin + bo1:= n1.fowner = nil; //stop after first expanded + n1.expanded:= true; + n1:= n1.fparent; + end; + end + else begin + while (n1 <> nil) and (n1.fowner <> nil) do begin + n1.expanded:= false; + n1:= n1.fparent; + end; + end; +end; + +function ttreelistitem.getsubitems: boolean; +begin + result:= ns_subitems in fstate; +end; + +procedure ttreelistitem.setsubitems(const avalue: boolean); +begin + if avalue then begin + state:= state + [ns_subitems]; + end + else begin + state:= state - [ns_subitems]; + end; +end; + +procedure ttreelistitem.statechanged; +begin + include(fstate1,ns1_statechanged); + if ns1_rootchange in fstate1 then begin + include(rootnode.fstate1,ns1_statechanged); + end; +end; + +procedure ttreelistitem.setexpanded(const Value: boolean); +begin + if value then begin + if not (ns_expanded in fstate) then begin + if checkaction(na_expand) then begin + include(fstate,ns_expanded); + statechanged; + end; + end; + end + else begin + if ns_expanded in fstate then begin + if checkaction(na_collapse) then begin + exclude(fstate,ns_expanded); + statechanged; + end; + end; + end; +end; + +procedure ttreelistitem.checkindex(const aindex: integer); +begin + if (aIndex < 0) or (aIndex >= FCount) then begin + tlist.Error(SListIndexError, aIndex); + end; +end; + +procedure ttreelistitem.settreelevel(const value: integer); +var + int1: integer; +begin + ftreelevel:= value; + for int1:= 0 to fcount - 1 do begin + fitems[int1].settreelevel(value+1); + end; +end; + +function ttreelistitem.levelshift: integer; +begin + if fowner <> nil then begin + result:= ftreelevel*fowner.flevelstep; + end + else begin + result:= 0; + end; +end; + +function ttreelistitem.treeheight: integer; //total hight of children +var + int1: integer; +begin + result:= 0; + for int1:= 0 to fcount - 1 do begin + inc(result); + with ttreelistitem(fitems[int1]) do begin + if expanded then begin + result:= result + treeheight; + end; + end; + end; +end; + +function ttreelistitem.rowheight: integer; //total needed grid rows +begin + if expanded then begin + result:= treeheight + 1; + end + else begin + result:= 1; + end; +end; + +function ttreelistitem.finditembycaption(const acaption: msestring; + const acasesensitive: boolean = false; + const aexpand: boolean = false): ttreelistitem; +var + int1: integer; + compfunc: function(const a,b: msestring): integer; +begin + result:= nil; + if acasesensitive then begin + compfunc:= {$ifdef FPC}@{$endif}msecomparestr; + end + else begin + compfunc:= {$ifdef FPC}@{$endif}msecomparetext; + end; + for int1:= 0 to fcount - 1 do begin + if compfunc(acaption,fitems[int1].fcaption) = 0 then begin + result:= fitems[int1]; + break; + end; + end; + if aexpand and (result <> nil) then begin + result.rootexpanded:= true; + end; +end; + +function ttreelistitem.finditembycaption(const acaption: msestring; + var dest: ttreelistitem): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to fcount-1 do begin + if fitems[int1].fcaption = acaption then begin + dest:= fitems[int1]; + result:= true; + end; + end; +end; + +function ttreelistitem.finditembycaption(const acaption: lmsestringty; + const aexpand: boolean = false): ttreelistitem; +var + po1,po2: pmsechar; + int1,int2: integer; +label + nextitem; +begin + result:= nil; + for int1:= 0 to fcount - 1 do begin + with fitems[int1] do begin + if length(fcaption) = acaption.len then begin + po1:= pointer(fcaption); + po2:= acaption.po; + for int2:= 0 to acaption.len-1 do begin + if (po1+int2)^ <> (po2+int2)^ then begin + goto nextitem; + end; + end; + result:= self.fitems[int1]; + end; + end; +nextitem: + end; + if aexpand and (result <> nil) then begin + result.rootexpanded:= true; + end; +end; + +function ttreelistitem.finditembycaption(const acaptions: msestringarty; + const acasesensitive: boolean = false; + const aexpand: boolean = false; + const apartial: boolean = false): ttreelistitem; +var + int1: integer; + it1,it2: ttreelistitem; +begin + it1:= self; + it2:= it1; + for int1:= 0 to high(acaptions) do begin + it1:= it1.finditembycaption(acaptions[int1],acasesensitive); + if it1 = nil then begin + if apartial then begin + it1:= it2; + end; + break; + it2:= it1; + end; + end; + if aexpand and (it1 <> nil) then begin + it1.rootexpanded:= true; + end; + result:= it1; +end; + +function ttreelistitem.isroot: boolean; +begin + result:= fparent = nil; +end; + +function ttreelistitem.issinglerootrow: boolean; +begin + result:= (treelevel = 0) and (not expanded or (count = 0)); +end; + +function ttreelistitem.nextnode: ttreelistitem; +var + n1: ttreelistitem; +begin + result:= nil; + n1:= self; + while n1.fparent <> nil do begin + if (n1.fparentindex < n1.fparent.fcount-1) then begin + result:= n1.fparent.fitems[n1.fparentindex+1]; + break; + end; + n1:= n1.fparent; + end; +end; + +function ttreelistitem.nextnodeparent: ttreelistitem; +begin + result:= nextnode; + if result <> nil then begin + result:= result.fparent; + end; +end; + +function ttreelistitem.checkdescendent(node: ttreelistitem): boolean; + //true if node is descendent or self +begin + result:= false; + while node <> nil do begin + if node = self then begin + result:= true; + break; + end; + node:= node.parent; + end; +end; + +function ttreelistitem.checkancestor(node: ttreelistitem): boolean; + //true if node is ancestor or self +begin + result:= (node <> nil) and node.checkdescendent(self); +end; + +function ttreelistitem.parentindex: integer; +begin + if fparent <> nil then begin + result:= fparentindex; + end + else begin + result:= -1; + end; +end; + +function ttreelistitem.rootpath: treelistitemarty; +var + int1: integer; + item: ttreelistitem; +begin + setlength(result,ftreelevel+1); + int1:= ftreelevel; + item:= self; + while int1 >= 0 do begin + result[int1]:= item; + item:= item.fparent; + dec(int1); + end; +end; + +function ttreelistitem.rootnode: ttreelistitem; +begin + result:= self; + while result.fparent <> nil do begin + result:= result.fparent; + end; +end; + +function ttreelistitem.rootcaptions: msestringarty; +var + int1: integer; + item: ttreelistitem; +begin + setlength(result,ftreelevel+1); + item:= self; + for int1:= high(result) downto 0 do begin + result[int1]:= item.fcaption; + item:= item.fparent; + end; +end; + +function ttreelistitem.rootcaptions(const aowner: tcustomitemlist): msestringarty; +var + int1,int2: integer; + item: ttreelistitem; +begin + int2:= ftreelevel+1; + setlength(result,int2); //max + item:= self; + for int1:= high(result) downto 0 do begin + if item.fowner <> aowner then begin + break; + end; + result[int1]:= item.fcaption; + item:= item.fparent; + dec(int2); + end; + if int2 <> 0 then begin + int1:= (length(result)-int2); + system.move(result[int2],result[0],int1*sizeof(pointer)); + setlength(pointerarty(result),int1); + end; +end; + +procedure ttreelistitem.objectevent(const sender: tobject; + const event: objecteventty); +var + int1: integer; +begin + for int1:= 0 to fcount - 1 do begin + fitems[int1].objectevent(sender,event); + end; + inherited; +end; + +procedure ttreelistitem.statreadsubnode(const reader: tstatreader; + var anode: ttreelistitem); +begin + if fowner <> nil then begin + fowner.statreadtreeitem(reader,self,anode); + end + else begin + if anode = nil then begin + anode:= createsubnode; + end; + end; +end; + +procedure ttreelistitem.dostatread(const reader: tstatreader); +var + int1{,int2}: integer; + node1: ttreelistitem; + bo1: boolean; +begin + inherited; + if not (ns_nosubnodestat in fstate) then begin + clear; + int1:= reader.readinteger('c',-1,0,bigint); + if int1 > 0 then begin + bo1:= ns_sorted in fstate; + exclude(fstate,ns_sorted); + for int1:= 0 to int1 - 1 do begin + if not reader.beginlist then begin + break; + end; + node1:= nil; + statreadsubnode(reader,node1); + if node1 <> nil then begin + dosetitems(inccount,node1); + node1.dostatread(reader); + end; + reader.endlist; + end; + if bo1 then begin + include(fstate,ns_sorted); + checksort; + end; + countchange(0,true); + end; + end; + exclude(fstate1,ns1_statechanged); +end; + +procedure ttreelistitem.dostatwrite(const writer: tstatwriter); +var + int1: integer; +begin + inherited; + if (fcount > 0) and not (ns_nosubnodestat in fstate) then begin + writer.writeinteger('c',fcount); + for int1:= 0 to fcount - 1 do begin + writer.beginlist; + fitems[int1].dostatwrite(writer); + writer.endlist; + end; + end; +end; + +function ttreelistitem.isstatechanged: boolean; +begin + result:= ns1_statechanged in fstate1; +end; + +function ttreelistitem.candrag: boolean; +begin + result:= ns1_candrag in fstate1; +end; + +function ttreelistitem.candrop(const source: ttreelistitem): boolean; +begin + result:= false; +end; + +procedure ttreelistitem.releaseowner; +var + int1: integer; +begin + for int1:= 0 to fcount - 1 do begin + fitems[int1].releaseowner; + end; + inherited; +end; + +procedure ttreelistitem.releasechildren(); +begin + include(fstate1,ns1_noowner); + clear(); +end; + +function ttreelistitem.parentorself: ttreelistitem; +begin + result:= fparent; + if fparent = nil then begin + result:= self; + end; +end; + +function ttreelistitem.islastnode: boolean; +begin + result:= (fparent = nil) or (fparentindex = fparent.fcount-1); +end; + +function ttreelistitem.findsibling( + const asibling: ttreelistitem): ttreelistitem; +var + n1: ttreelistitem; +begin + result:= nil; +// if asibling.fparent <> nil then begin + n1:= self; + while n1 <> nil do begin + if n1.fparent = asibling.fparent then begin + result:= n1; + break; + end; + n1:= n1.fparent; + end; +// end; +end; + +function ttreelistitem.treechecked: boolean; +begin + result:= (ns_checked in fstate) and not (ns1_parentnotchecked in fstate1); +end; + +{ ttreenode } + +destructor ttreenode.destroy; +begin + clear; + inherited; +end; + +procedure ttreenode.clear; +var + int1: integer; +begin + for int1:= 0 to fcount - 1 do begin + fitems[int1].Free; + end; + fcount:= 0; + fitems:= nil; +end; + +function ttreenode.add(const anode: ttreenode): integer; +begin + result:= fcount; + setcount(fcount + 1); + items[fcount-1]:= anode; +end; + +procedure ttreenode.setcount(const value: integer); +begin + if high(fitems) <= value then begin + setlength(fitems,(value*8) div 7 + 32); + end; + fcount:= value; +end; + +function ttreenode.getitems(const index: integer): ttreenode; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure ttreenode.setitems(const index: integer; const Value: ttreenode); +begin + checkindex(index); + fitems[index].Free; + fitems[index]:= value; + value.fparent:= self; +end; + +procedure ttreenode.checkindex(const index: integer); +begin + if (index < 0) or (index >= fcount) then begin + tlist.error(slistindexerror,index); + end; +end; + +procedure ttreenode.iterate(const event: nodeeventty); +var + int1: integer; +begin + event(self); + for int1:= 0 to fcount - 1 do begin + fitems[int1].iterate(event); + end; +end; + +procedure ttreenode.convertflat(const listitem: ttreelistitem; + const filterfunc: treenodefilterfuncty); +var + item1: ttreelistitem; + int1: integer; +begin + if assigned(filterfunc) and not filterfunc(self) then begin + exit; + end; + item1:= listitemclass.create; + nodetoitem(item1); + listitem.add(item1); + for int1:= 0 to fcount - 1 do begin + fitems[int1].convertflat(listitem,filterfunc); + end; +end; + +function ttreenode.converttree(const filterfunc: treenodefilterfuncty): ttreelistitem; +var + int1: integer; +begin + if assigned(filterfunc) and not filterfunc(self) then begin + result:= nil; + end + else begin + result:= listitemclass.create; + nodetoitem(result); + for int1:= 0 to fcount - 1 do begin + result.add(fitems[int1].converttree(filterfunc)); + end; + end; +end; + +function ttreenode.converttotreelistitem(flat: boolean = false; withrootnode: boolean = false; + filterfunc: treenodefilterfuncty = nil): ttreelistitem; +var + int1: integer; +begin + result:= listitemclass.create; //container + if withrootnode then begin + if flat then begin + convertflat(result,filterfunc); + end + else begin + result.add(converttree(filterfunc)); + end; + end + else begin + for int1:= 0 to fcount - 1 do begin + if flat then begin + fitems[int1].convertflat(result,filterfunc); + end + else begin + result.add(fitems[int1].converttree(filterfunc)); + end; + end; + end; +end; + +{ +procedure ttreenode.assigntotreelistitem(const listitem: ttreelistitem); +var + int1: integer; + ar1: treelistitemarty; +begin + nodetoitem(listitem); + listitem.clear; + if fcount > 0 then begin + setlength(ar1,fcount); + for int1:= 0 to fcount - 1 do begin + ar1[int1]:= fitems[int1].listitemclass.create; + end; + listitem.add(ar1); + for int1:= 0 to fcount - 1 do begin + fitems[int1].assigntotreelistitem(ar1[int1]); + end; + end; +end; + +procedure ttreenode.assigntreelistitem(const listitem: ttreelistitem); +var + int1: integer; + ar1: treenodearty; +begin + itemtonode(listitem); + clear; + if listitem.count > 0 then begin + setlength(ar1,listitem.count); + for int1:= 0 to listitem.count - 1 do begin + add(treenodeclass.create); + end; + for int1:= 0 to fcount - 1 do begin + fitems[int1].assigntotreelistitem(listitem[int1]); + end; + end; +end; +} +procedure ttreenode.nodetoitem(const listitem: ttreelistitem); +begin + //dummy +end; +{ +procedure ttreenode.itemtonode(const listitem: ttreelistitem); +begin + //dummy +end; +} +function ttreenode.listitemclass: treelistitemclassty; +begin + result:= ttreelistitem; +end; + +function ttreenode.treenodeclass: treenodeclassty; +begin + result:= ttreenode; +end; + +function ttreenode.count: integer; +begin + result:= fcount; +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msedropdownlist.pas b/mseide-msegui/lib/common/editwidgets/msedropdownlist.pas new file mode 100644 index 0000000..f1b0600 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msedropdownlist.pas @@ -0,0 +1,2998 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedropdownlist; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseclasses,mseedit,mseevent,mseglob,mseguiglob,msegrids,msedatalist,msegui, + mseinplaceedit,msearrayprops,classes,mclasses,msegraphics,msedrawtext, + msegraphutils,mseassistiveclient, + msetimer,{mseforms,}msetypes,msestrings,msestockobjects,msescrollbar, + msekeyboard,msegridsglob,mseeditglob,msestat,msebitmap; + +const + defaultdropdowncoloptions = [co_fill,co_readonly,co_focusselect, + co_mousemovefocus,co_rowselect]; + defaultdropdowncoltextflags = defaultcoltextflags + [tf_noselect]; + mouseautoscrollheight = 4; + dropdownitemselectedevent = 345; + +type + + dropdownlistoptionty = (dlo_casesensitive,dlo_posinsensitive,dlo_livefilter); + dropdownlistoptionsty = set of dropdownlistoptionty; + + dropdownliststatety = (dls_firstmousemoved,dls_mousemoved,dls_scrollup); + dropdownliststatesty = set of dropdownliststatety; + + dropdowneditoptionty = (deo_selectonly,deo_forceselect, + deo_autodropdown, + deo_keydropdown,//shift down starts dropdown + deo_modifiedbeforedropdown, + //edit.modified called before dropdown + deo_casesensitive,deo_posinsensitive, + deo_livefilter, + deo_customfilter, //do not hide rows + deo_sorted,deo_disabled,deo_autosavehistory, + deo_cliphint,deo_right,deo_colsizing,deo_savestate); + dropdowneditoptionsty = set of dropdowneditoptionty; + +const + defaultdropdownoptionsedit = [deo_keydropdown]; + defaultautodropdownoptions = defaultdropdownoptionsedit + [deo_autodropdown]; +type + tcustomdropdownlistcontroller = class; + + tdropdowncolfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tdropdowncolfontselect = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tdropdowndata = class(tmsestringdatalist) + end; + + tdropdowndatacols = class(townedpersistentarrayprop) + private + fupdating1: integer; + fonitemchange: indexeventty; + function getitems(const index: integer): tdropdowndata; + protected + function maxrowcount: integer; + function minrowcount: integer; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure itemchanged(const sender: tdatalist; const index: integer); + //sender = nil -> col undefined + procedure checkrowindex(const aindex: integer); + procedure setrowcount(const avalue: integer); + public + constructor create(const aowner: tcustomdropdownlistcontroller); reintroduce; + class function getitemclasstype: persistentclassty; override; + procedure beginupdate; + procedure endupdate; + procedure clear; + function addrow(const aitems: array of msestring): integer; + //returns itemindex + procedure insertrow(const aindex: integer; const aitems: array of msestring); + procedure deleterow(const aindex: integer); + function getrow(const aindex: integer): msestringarty; + property rowcount: integer read maxrowcount write setrowcount; + property items[const index: integer]: tdropdowndata read getitems; default; + end; + + tdropdowncol = class(tdropdowndata) + private + fwidth: integer; + foptions: coloptionsty; + flinewidth: integer; + flinecolor: colorty; + ftextflags: textflagsty; + fcolor: colorty; + fcolorselect: colorty; +// ffontcolorselect: colorty; + fcaption: msestring; + fpasswordchar: msechar; + ffont: tdropdowncolfont; + ffontselect: tdropdowncolfontselect; + fframetemplate: tframecomp; + ffacetemplate: tfacecomp; + procedure setoptions(const avalue: coloptionsty); + function getfont: tdropdowncolfont; + procedure setfont(const avalue: tdropdowncolfont); + function getfontselect: tdropdowncolfontselect; + procedure setfontselect(const avalue: tdropdowncolfontselect); + procedure readfontcolorselect(reader: treader); + procedure setframetemplate(const avalue: tframecomp); + procedure setfacetemplate(const avalue: tfacecomp); + protected + fowner: tobject; +// fdata: tdropdowndata; //for tselector + procedure defineproperties(filer: tfiler); override; + public + constructor create(const aowner: tcustomdropdownlistcontroller); reintroduce; + destructor destroy(); override; + procedure createfont(); + procedure createfontselect(); + published + property width: integer read fwidth write fwidth default griddefaultcolwidth; + property options: coloptionsty read foptions write setoptions + default defaultdropdowncoloptions; + property textflags: textflagsty read ftextflags write ftextflags + default defaultdropdowncoltextflags; + property passwordchar: msechar read fpasswordchar write fpasswordchar + default #0; + property linewidth: integer read flinewidth write flinewidth default 0; + property linecolor: colorty read flinecolor write flinecolor default cl_gray; + property color: colorty read fcolor write fcolor default cl_default; + property colorselect: colorty read fcolorselect write fcolorselect + default cl_default; +// property fontcolorselect: colorty read ffontcolorselect +// write ffontcolorselect default cl_default; + property font: tdropdowncolfont read getfont write setfont; + property fontselect: tdropdowncolfontselect read getfontselect + write setfontselect; + property frametemplate: tframecomp read fframetemplate + write setframetemplate; + property facetemplate: tfacecomp read ffacetemplate + write setfacetemplate; + property caption: msestring read fcaption write fcaption; + end; + + dropdowncolclassty = class of tdropdowncol; + + tdropdownfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tdropdownfontselect = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tdropdowncols = class(tdropdowndatacols) + private + fnostreaming: boolean; +// maxrowcount: integer; + fwidth: integer; + foptions: coloptionsty; + ftextflags: textflagsty; + flinewidth: integer; + flinecolor: colorty; + fcolor: colorty; + fcolorselect: colorty; +// ffontcolorselect: colorty; + ffont: tdropdownfont; + ffontselect: tdropdownfontselect; + fframetemplate: tframecomp; + ffacetemplate: tfacecomp; + function getitems(const index: integer): tdropdowncol; + procedure setnostreaming(const avalue: boolean); + procedure setwidth(const avalue: integer); + procedure setoptions(const avalue: coloptionsty); + procedure settextflags(const avalue: textflagsty); + procedure setlinewidth(const avalue: integer); + procedure setlinecolor(const avalue: colorty); + procedure setcolor(const avalue: colorty); + procedure setcolorselect(const avalue: colorty); +// procedure setfontcolorselect(const avalue: colorty); + function getfont: tdropdownfont; + procedure setfont(const avalue: tdropdownfont); + function getfontselect: tdropdownfontselect; + procedure setfontselect(const avalue: tdropdownfontselect); + procedure readfontcolorselect(reader: treader); + procedure setframetemplate(const avalue: tframecomp); + procedure setfacetemplate(const avalue: tfacecomp); + protected + fdatacols: tdropdowndatacols; //for tselector + fitemindex: integer; + fkeyvalue64: int64; + fkeyvalue: msestring; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure createitem(const index: integer; var item: tpersistent); override; + function getcolclass: dropdowncolclassty; virtual; + procedure defineproperties(filer: tfiler); override; + public + constructor create(const aowner: tcustomdropdownlistcontroller); reintroduce; + destructor destroy(); override; + class function getitemclasstype: persistentclassty; override; + procedure createfont(); + procedure createfontselect(); + property nostreaming: boolean read fnostreaming + write setnostreaming; + property onitemchange: indexeventty read fonitemchange write fonitemchange; + property items[const index: integer]: tdropdowncol read getitems; default; + published + property width: integer read fwidth write setwidth default griddefaultcolwidth; + property options: coloptionsty read foptions write setoptions + default defaultdropdowncoloptions; + property textflags: textflagsty read ftextflags write settextflags + default defaultdropdowncoltextflags; + property linewidth: integer read flinewidth write setlinewidth default 0; + property linecolor: colorty read flinecolor write setlinecolor default cl_gray; + property color: colorty read fcolor write setcolor default cl_default; + property colorselect: colorty read fcolorselect write setcolorselect + default cl_default; +// property fontcolorselect: colorty read ffontcolorselect +// write setfontcolorselect default cl_default; + property font: tdropdownfont read getfont write setfont; + property fontselect: tdropdownfontselect read getfontselect + write setfontselect; + property frametemplate: tframecomp read fframetemplate + write setframetemplate; + property facetemplate: tfacecomp read ffacetemplate + write setfacetemplate; + end; + + dropdowncolsclassty = class of tdropdowncols; + + idropdown = interface(inullinterface) + function getvalueempty: integer; + function getwidget: twidget; + function geteditor: tinplaceedit; + function getedited: boolean; + procedure modified; + procedure dobeforedropdown; + procedure doafterclosedropdown; + function setdropdowntext(const avalue: msestring; const docheckvalue: boolean; + const canceled: boolean; const akey: keyty): boolean; //true if accepted + procedure buttonaction(var action: buttonactionty; const buttonindex: integer); + end; + + idropdownlist = interface(idropdown) + function getdropdownitems: tdropdowndatacols; + //nil -> dropdowncontroller.fdropdownitems + procedure imagelistchanged; + end; + + idropdownwidget = interface(idropdown) + procedure createdropdownwidget(const atext: msestring; out awidget: twidget); + function getdropdowntext(const awidget: twidget): msestring; + end; + + idropdowncontroller = interface(inullinterface) + function getwidget: twidget; + procedure updatedropdownpos(const arect: rectty); + end; + + idropdownlistcontroller = interface(idropdowncontroller) + procedure dropdownactivated; + procedure dropdowndeactivated; + procedure itemselected(const index: integer; const akey: keyty); + procedure dropdownkeydown(var info: keyeventinfoty); + end; + + tdropdownstringcol = class(tstringcol) + protected + function createdatalist: tdatalist; override; + public + destructor destroy; override; + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + end; + + titemselectedevent = class(tcomponentevent) + private + frow: integer; + public + constructor create(const dest: tmsecomponent; const arow: integer); + end; + + tdropdownfixcol = class(tfixcol) + protected + fcontroller: tcustomdropdownlistcontroller; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); reintroduce; virtual; + end; + dropdownfixcolclassty = class of tdropdownfixcol; + +type + tdropdownlist = class(tcustomstringgrid) + private + foptions1: dropdownlistoptionsty; + fdropdownstate: dropdownliststatesty; + ffirstmousepos: pointty; + frepeater: tsimpletimer; + ffiltertext: msestring; + fselectedindex: integer; + fupdatelayoutcount: int32; + procedure canceldropdown; + procedure killrepeater; + procedure startrepeater(up: boolean); + procedure itemselected(const index: integer; const akey: keyty); + protected + fcontroller: tcustomdropdownlistcontroller; + fdropdownrowcount: integer; + function getassistiveflags(): assistiveflagsty override; + procedure setfiltertext(const Value: msestring); virtual; + procedure updatewindowinfo(var info: windowinfoty); override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure docellevent(var info: celleventinfoty); override; + function getkeystring(const aindex: integer): msestring; + function getkeystringnohidden(const aindex: integer): msestring; + function locate(const filter: msestring): boolean; virtual; + function updatevisiblerows(): integer; virtual; + //returns first visible row + procedure dorepeat(const sender: tobject); + procedure initcols(const acols: tdropdowncols); virtual; + procedure updatelayout; override; + function dropdownheight: integer; virtual; + procedure setactiveitem(const aitemindex: integer); virtual; + function getassistiveparent(): iassistiveclient override; + public + constructor create(const acontroller: tcustomdropdownlistcontroller; + const acols: tdropdowncols; + const afixcolclass: dropdownfixcolclassty); reintroduce; + destructor destroy; override; + procedure show(awidth: integer; const arowcount: integer; + var aitemindex: integer; afiltertext: msestring); reintroduce; + property filtertext: msestring read ffiltertext write setfiltertext; + property options: dropdownlistoptionsty read foptions1 write foptions1; + end; + + tdropdownbutton = class(tstockglyphframebutton) + public + constructor create(aowner: tobject); override; + published + property imagenr default ord(stg_arrowdownsmall); + end; + + tcustomdropdownbuttonframe = class(tcustombuttonframe) + private + freadonly: boolean; + procedure setreadonly(const Value: boolean); + protected + procedure updatestate() override; + function getbuttonclass: framebuttonclassty override; + function getbutton: tdropdownbutton; + procedure setbutton(const avalue: tdropdownbutton); + public + constructor create(const aintf: icaptionframe; + const buttonintf: ibutton); override; + procedure updatedropdownoptions(const avalue: dropdowneditoptionsty); + property readonly: boolean read freadonly write setreadonly default false; + property button: tdropdownbutton read getbutton write setbutton; + end; + + dropdownbuttonframeclassty = class of tcustomdropdownbuttonframe; + + tdropdownbuttonframe = class(tcustomdropdownbuttonframe) + published + property button; + end; + + tdropdownmultibuttonframe = class(tdropdownbuttonframe) + published + property buttons; + property activebutton; + end; + + dropdowncontrollerstatety = (dcs_forcecaret,dcs_itemselecting,dcs_isstringkey); + dropdowncontrollerstatesty = set of dropdowncontrollerstatety; + + tcustomdropdowncontroller = class(teventpersistent,ibutton,ievent, + idropdowncontroller,idataeditcontroller) + private + fframetemplate: tframecomp; + ffacetemplate: tfacecomp; + procedure setframetemplate(const avalue: tframecomp); + procedure setfacetemplate(const avalue: tfacecomp); + protected + fowner: twidget; + fdataselected: boolean; + fcolor: colorty; + fcolorclient: colorty; + fdropdowncount: integer; + fselectkey: keyty; + fintf: idropdown; + foptions: dropdowneditoptionsty; + fstate: dropdowncontrollerstatesty; +// fforcecaret: boolean; + procedure applicationactivechanged(const avalue: boolean); virtual; + function getbuttonframeclass: dropdownbuttonframeclassty; virtual; + procedure updatedropdownbounds(var arect: rectty); virtual; + procedure updatedropdownpos(const arect: rectty); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure setoptions(const Value: dropdowneditoptionsty); virtual; + function getdropdownwidget: twidget; virtual; + function getwidget: twidget; + procedure dobeforedropdown; virtual; + procedure doafterclosedropdown; virtual; + procedure internaldropdown; virtual; + function setdropdowntext(const avalue: msestring; + const docheckvalue: boolean; const canceled: boolean; + const akey: keyty): boolean; + //true if selected + function candropdown: boolean; virtual; + procedure selectnone(const akey: keyty); virtual; + function isloading: boolean; + procedure resetselection; virtual; + function componentstate: tcomponentstate; + //ibutton + procedure buttonaction(var action: buttonactionty; + const buttonindex: integer); + + //idataeditcontroller + procedure mouseevent(var info: mouseeventinfoty); + procedure dokeydown(var info: keyeventinfoty); + procedure internalcreateframe; virtual; + procedure updatereadonlystate; + procedure domousewheelevent(var info: mousewheeleventinfoty); + procedure editnotification(var info: editnotificationinfoty); virtual; + public + constructor create(const intf: idropdown); reintroduce; + destructor destroy; override; + function hasdropdown(): boolean; + property dropdownwidget: twidget read getdropdownwidget; + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure dropdown; virtual; + procedure canceldropdown; + procedure dropdownactivated; + procedure dropdowndeactivated; + function dataselected: boolean; + property options: dropdowneditoptionsty read foptions write setoptions + default defaultdropdownoptionsedit; + published + property color: colorty read fcolor write fcolor default cl_default; + property colorclient: colorty read fcolorclient write fcolorclient + default cl_default; + property frametemplate: tframecomp read fframetemplate + write setframetemplate; + property facetemplate: tfacecomp read ffacetemplate + write setfacetemplate; + end; + + tdropdowncontroller = class(tcustomdropdowncontroller) + protected + function getbuttonframeclass: dropdownbuttonframeclassty; override; + published + property options; + end; + dropdownwidgeteventty = procedure(const sender: twidget; + const dropdown: twidget) of object; + tdropdownwidgetcontroller = class(tdropdowncontroller) + private + fondropdown: dropdownwidgeteventty; + protected + fbounds_cy: integer; + fbounds_cx: integer; + fdropdownwidget: twidget; + fdropdownwidth: int32; + procedure internaldropdown; override; + procedure updatedropdownbounds(var arect: rectty); override; + procedure receiveevent(const event: tobjectevent); override; + function getdropdownwidget: twidget; override; + public + constructor create(const intf: idropdownwidget); + procedure editnotification(var info: editnotificationinfoty); override; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + property dropdownwidget: twidget read fdropdownwidget; + published + property bounds_cx: integer read fbounds_cx write fbounds_cx default 0; + //0 -> ownerwidget.bounds_cx + property bounds_cy: integer read fbounds_cy write fbounds_cy default 0; + //0 -> dropdownwidget.bounds_cy + property ondropdown: dropdownwidgeteventty read fondropdown + write fondropdown; + end; + + dropdownlisteventty = procedure(const sender: twidget; + const dropdown: tdropdownlist) of object; + tcustomdropdownlistcontroller = class(tcustomdropdowncontroller, + idropdownlistcontroller) + private + fondropdown: dropdownlisteventty; + procedure setcols(const Value: tdropdowncols); + function getitemindex: integer; + procedure setitemindex(const Value: integer); + procedure setvaluecol(const avalue: integer); + procedure setimagelist(const avalue: timagelist); + procedure imagelistchanged; + procedure setimageframe(const avalue: framety); + procedure setimageframe_left(const avalue: integer); + procedure setimageframe_top(const avalue: integer); + procedure setimageframe_right(const avalue: integer); + procedure setimageframe_bottom(const avalue: integer); + function getdelay: integer; + procedure setdelay(avalue: integer); + protected + ftimer: tsimpletimer; + fimagelist: timagelist; + fimageframe: framety; + fdropdownrowcount: integer; + fwidth: integer; + fvaluecol: integer; + fdatarowlinewidth: integer; + fdatarowlinecolor: colorty; + fbuttonlength: integer; + fbuttonendlength: integer; + fbuttonminlength: integer; +// fdropdownitems: tdropdowncols; + fdropdownlist: tdropdownlist; + fcols: tdropdowncols; + procedure dotimer(const sender: tobject); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure valuecolchanged; virtual; + function getdropdownwidget: twidget; override; + procedure itemchanged(const sender: tdatalist; const index: integer); + function getdropdowncolsclass: dropdowncolsclassty; virtual; + procedure selectnone(const akey: keyty); override; + procedure resetselection; override; //sets fcols.fitemindex to -1, no events + function reloadlist: integer; virtual; + //returns first visible row + function getremoterowcount: integer; virtual; + procedure dobeforedropdown; override; + procedure doafterclosedropdown; override; + + //idropdownlist + procedure itemselected(const index: integer; const akey: keyty); virtual; + //-2 -> no selection, -1 -> cancel + procedure dropdownkeydown(var info: keyeventinfoty); + + function getautowidth: integer; + procedure updatedropdownbounds(var arect: rectty); override; + procedure receiveevent(const event: tobjectevent); override; + function createdropdownlist: tdropdownlist; virtual; + function getfixcolclass: dropdownfixcolclassty; virtual; + procedure internaldropdown; override; + procedure editnotification(var info: editnotificationinfoty); override; + public + constructor create(const intf: idropdownlist); + destructor destroy; override; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + function valuelist: tmsestringdatalist; + property cols: tdropdowncols read fcols write setcols; + property valuecol: integer read fvaluecol write setvaluecol default 0; + property itemindex: integer read getitemindex write setitemindex default -1; + property delay: integer read getdelay write setdelay default 0; + //ms, -1 = idle + property dropdownrowcount: integer read fdropdownrowcount + write fdropdownrowcount default 8; + property width: integer read fwidth write fwidth default 0; + property datarowlinewidth: integer read fdatarowlinewidth + write fdatarowlinewidth default 0; + property datarowlinecolor: colorty read fdatarowlinecolor + write fdatarowlinecolor default defaultdatalinecolor; + property buttonlength: integer read fbuttonlength + write fbuttonlength default 0; + property buttonendlength: integer read fbuttonendlength + write fbuttonendlength default 0; + property buttonminlength: integer read fbuttonminlength + write fbuttonminlength default defaultbuttonminlength; + property imagelist: timagelist read fimagelist write setimagelist; + property imageframe: framety read fimageframe write setimageframe; + property imageframe_left: integer read fimageframe.left + write setimageframe_left default 0; + property imageframe_top: integer read fimageframe.top + write setimageframe_top default 0; + property imageframe_right: integer read fimageframe.right + write setimageframe_right default 0; + property imageframe_bottom: integer read fimageframe.bottom + write setimageframe_bottom default 0; + property ondropdown: dropdownlisteventty read fondropdown + write fondropdown; + end; + + tnocolsdropdownlistcontroller = class(tcustomdropdownlistcontroller) + protected + function getbuttonframeclass: dropdownbuttonframeclassty; override; + public + constructor create(const intf: idropdownlist); + published + property options; + property dropdownrowcount; + property delay; + property width; + property datarowlinewidth; + property datarowlinecolor; + property buttonlength; + property buttonminlength; + property buttonendlength; + property ondropdown; + end; + + tdropdownlistcontroller = class(tnocolsdropdownlistcontroller) + public + constructor create(const intf: idropdownlist); + published + property imagelist; + property imageframe_left; + property imageframe_top; + property imageframe_right; + property imageframe_bottom; + property cols; + property valuecol; + property itemindex; + end; + + dropdownlistcontrollerclassty = class of tcustomdropdownlistcontroller; + + tmbdropdownlistcontroller = class(tdropdownlistcontroller) + protected + function getbuttonframeclass: dropdownbuttonframeclassty; override; + end; + + +implementation +uses + sysutils,msewidgets,mseguiintf,rtlconsts,msebits; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustomframe1= class(tcustomframe); + tdatacols1 = class(tdatacols); + twidget1 = class(twidget); + tcustombuttonframe1 = class(tcustombuttonframe); + tstringcol1 = class(tstringcol); + tframebutton1 = class(tframebutton); + tframebuttons1 = class(tframebuttons); + tinplaceedit1 = class(tinplaceedit); + + timagefixcol = class(tdropdownfixcol) + private + fimagelist: timagelist; + fimageframe: framety; + protected + procedure drawcell(const canvas: tcanvas); override; + public + constructor create(const agrid: tcustomgrid; const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); override; + end; + + +const + defaultdropdowncellinnerframe: framety = + (left: 1; top: 0; right: 1; bottom: 0); + +{ tdropdowncolfont } + +class function tdropdowncolfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tdropdowncol(owner).ffont; +end; + +{ tdropdowncolfontselect } + +class function tdropdowncolfontselect.getinstancepo(owner: tobject): pfont; +begin + result:= @tdropdowncol(owner).ffontselect; +end; + +{ tdropdowncol } + +constructor tdropdowncol.create(const aowner: tcustomdropdownlistcontroller); +begin + fowner:= aowner; + fwidth:= griddefaultcolwidth; + foptions:= defaultdropdowncoloptions; + flinecolor:= cl_gray; + ftextflags:= defaultdropdowncoltextflags; + fcolor:= cl_default; + fcolorselect:= cl_default; +// ffontcolorselect:= cl_default; + inherited create; +end; + +destructor tdropdowncol.destroy; +begin + inherited; + ffont.free(); +end; + +procedure tdropdowncol.setoptions(const avalue: coloptionsty); +begin + foptions:= avalue + [co_focusselect]; +end; + +procedure tdropdowncol.createfont; +begin + if ffont = nil then begin + ffont:= tdropdowncolfont.create(); + end; +end; + +procedure tdropdowncol.createfontselect; +begin + if ffontselect = nil then begin + ffontselect:= tdropdowncolfontselect.create(); + end; +end; + +function tdropdowncol.getfont: tdropdowncolfont; +begin + if fowner <> nil then begin + getoptionalobject(tcustomdropdownlistcontroller(fowner).componentstate, + ffont,@createfont); + end; + result:= ffont; +end; + +procedure tdropdowncol.setfont(const avalue: tdropdowncolfont); +begin + if fowner <> nil then begin + if avalue <> ffont then begin + setoptionalobject(tcustomdropdownlistcontroller(fowner).componentstate,avalue, + ffont,@createfont); + end; + end; +end; + +function tdropdowncol.getfontselect: tdropdowncolfontselect; +begin + if fowner <> nil then begin + getoptionalobject(tcustomdropdownlistcontroller(fowner).componentstate, + ffontselect,@createfontselect); + end; + result:= ffontselect; +end; + +procedure tdropdowncol.setfontselect(const avalue: tdropdowncolfontselect); +begin + if fowner <> nil then begin + if avalue <> ffontselect then begin + setoptionalobject( + tcustomdropdownlistcontroller(fowner).componentstate,avalue, + ffontselect,@createfontselect); + end; + end; +end; + +procedure tdropdowncol.readfontcolorselect(reader: treader); +var + co1: colorty; +begin + co1:= reader.readinteger(); + if co1 <> cl_default then begin + createfontselect(); + ffontselect.color:= co1; + end; +end; + +procedure tdropdowncol.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('fontcolorselect',@readfontcolorselect,nil,false); +end; + +procedure tdropdowncol.setframetemplate(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fframetemplate)); +end; + +procedure tdropdowncol.setfacetemplate(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ffacetemplate)); +end; + +{ tdropdownfont } + +class function tdropdownfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tdropdowncols(owner).ffont; +end; + +{ tdropdownfontselect } + +class function tdropdownfontselect.getinstancepo(owner: tobject): pfont; +begin + result:= @tdropdowncols(owner).ffontselect; +end; + +{ tdropdowndatacols } + +constructor tdropdowndatacols.create( + const aowner: tcustomdropdownlistcontroller); +begin + inherited create(aowner,nil); + count:= 1; +end; + +class function tdropdowndatacols.getitemclasstype: persistentclassty; +begin + result:= tdropdowndata; +end; + +procedure tdropdowndatacols.createitem(const index: integer; + var item: tpersistent); +begin + item:= tdropdowndata.create(); +end; + +function tdropdowndatacols.getitems(const index: integer): tdropdowndata; +begin + result:= tdropdowndata(inherited getitems(index)); +end; + +procedure tdropdowndatacols.checkrowindex(const aindex: integer); +begin + if count = 0 then begin + raise exception.create('No columns.'); + end; + if (aindex < 0) or (aindex >= maxrowcount) then begin + tlist.error(slistindexerror,aindex); + end; +end; + +procedure tdropdowndatacols.setrowcount(const avalue: integer); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tdropdowndata(fitems[int1]).count:= avalue; + end; +end; + +procedure tdropdowndatacols.itemchanged(const sender: tdatalist; + const index: integer); +begin + if (fupdating1 = 0 ) and assigned(fonitemchange) then begin + fonitemchange(sender,index); + end; +end; + +function tdropdowndatacols.maxrowcount: integer; +var + int1,int2: integer; +begin + result:= 0; + for int1:= 0 to count - 1 do begin + int2:= items[int1].count; + if int2 > result then begin + result:= int2; + end; + end; +end; + +function tdropdowndatacols.minrowcount: integer; +var + int1,int2: integer; +begin + if count > 0 then begin + result:= bigint; + for int1:= 0 to count - 1 do begin + int2:= items[int1].count; + if int2 < result then begin + result:= int2; + end; + end; + end + else begin + result:= 0; + end; +end; + +procedure tdropdowndatacols.beginupdate; +begin + inc(fupdating1); +end; + +procedure tdropdowndatacols.endupdate; +begin + dec(fupdating1); + if fupdating1 = 0 then begin + itemchanged(nil,-1); + end; +end; + +procedure tdropdowndatacols.clear; +var + int1: integer; +begin + beginupdate; + try + for int1:= 0 to count - 1 do begin + items[int1].count:= 0; + end; + finally + endupdate; + end; +end; + +function tdropdowndatacols.getrow(const aindex: integer): msestringarty; +var + int1: integer; +begin + if (aindex < 0) or (aindex >= minrowcount) then begin + tlist.error({$ifndef fpc}@{$endif}slistindexerror, aindex); + end; + setlength(result,count); + for int1:= 0 to high(fitems) do begin + result[int1]:= pmsestring(tdropdowndata(fitems[int1]).fdatapo + + aindex * sizeof(msestring))^; + end; +end; + +function tdropdowndatacols.addrow(const aitems: array of msestring): integer; +var + int1: integer; +begin + result:= maxrowcount; + beginupdate; + try + for int1:= 0 to count - 1 do begin + items[int1].count:= result + 1; + if int1 < length(aitems) then begin + items[int1][result]:= aitems[int1]; + end; + end; + finally + endupdate; + end; +end; + +procedure tdropdowndatacols.insertrow(const aindex: integer; + const aitems: array of msestring); +var + int1,int2: integer; +begin + int2:= maxrowcount; + if aindex = int2 then begin + addrow(aitems); + end + else begin + checkrowindex(aindex); + beginupdate; + try + for int1:= 0 to count - 1 do begin + with items[int1] do begin + count:= int2; + if int1 <= high(aitems) then begin + insert(aindex,aitems[int1]); + end + else begin + insert(aindex,''); + end; + end; + end; + finally + endupdate; + end; + end; +end; + +procedure tdropdowndatacols.deleterow(const aindex: integer); +var + int1,int2: integer; +begin + checkrowindex(aindex); + int2:= maxrowcount; + beginupdate; + try + for int1:= 0 to count - 1 do begin + with items[int1] do begin + count:= int2; + deletedata(aindex); + end; + end; + finally + endupdate; + end; +end; + +{ tdropdowncols } + +constructor tdropdowncols.create(const aowner: tcustomdropdownlistcontroller); +begin + fwidth:= griddefaultcolwidth; + foptions:= defaultdropdowncoloptions; + flinecolor:= cl_gray; + ftextflags:= defaultdropdowncoltextflags; + fcolor:= cl_default; + fcolorselect:= cl_default; +// ffontcolorselect:= cl_default; + + inherited create(aowner{,nil}); +// items[0].options:= items[0].options + [co_fill]; +end; + +destructor tdropdowncols.destroy; +begin + inherited; + ffont.free(); + ffontselect.free(); +end; + +class function tdropdowncols.getitemclasstype: persistentclassty; +begin + result:= tdropdowncol; +end; + +function tdropdowncols.getcolclass: dropdowncolclassty; +begin + result:= tdropdowncol; +end; + +procedure tdropdowncols.createitem(const index: integer; var item: tpersistent); +begin + item:= getcolclass.create(tcustomdropdownlistcontroller(fowner)); + with tdropdowncol(item) do begin + onitemchange:= {$ifdef FPC}@{$endif}itemchanged; + if fnostreaming then begin + include(fstate,dls_nostreaming); + end; + fwidth:= self.fwidth; + foptions:= self.foptions; + ftextflags:= self.ftextflags; + flinewidth:= self.flinewidth; + flinecolor:= self.flinecolor; + fcolor:= self.fcolor; + fcolorselect:= self.fcolorselect; +// ffontcolorselect:= self.ffontcolorselect; + end; +end; + +procedure tdropdowncols.createfont(); +begin + if ffont = nil then begin + ffont:= tdropdownfont.create(); + end; +end; + +procedure tdropdowncols.createfontselect(); +begin + if ffontselect = nil then begin + ffontselect:= tdropdownfontselect.create(); + end; +end; + +function tdropdowncols.getfont: tdropdownfont; +begin + if fowner <> nil then begin + getoptionalobject(tcustomdropdownlistcontroller(fowner).componentstate, + ffont,@createfont); + end; + result:= ffont; +end; + +procedure tdropdowncols.setfont(const avalue: tdropdownfont); +begin + if fowner <> nil then begin + if avalue <> ffont then begin + setoptionalobject( + tcustomdropdownlistcontroller(fowner).componentstate,avalue, + ffont,@createfont); + end; + end; +end; + +function tdropdowncols.getfontselect: tdropdownfontselect; +begin + if fowner <> nil then begin + getoptionalobject(tcustomdropdownlistcontroller(fowner).componentstate, + ffontselect,@createfontselect); + end; + result:= ffontselect; +end; + +procedure tdropdowncols.setfontselect(const avalue: tdropdownfontselect); +begin + if fowner <> nil then begin + if avalue <> ffontselect then begin + setoptionalobject( + tcustomdropdownlistcontroller(fowner).componentstate,avalue, + ffontselect,@createfontselect); + end; + end; +end; + +procedure tdropdowncols.setnostreaming(const avalue: boolean); +var + int1: integer; +begin + if fnostreaming <> avalue then begin + fnostreaming:= avalue; + if avalue then begin + for int1:= 0 to count - 1 do begin + include(tdropdowncol(items[int1]).fstate,dls_nostreaming); + end; + end + else begin + for int1:= 0 to count - 1 do begin + exclude(tdropdowncol(items[int1]).fstate,dls_nostreaming); + end; + end; + end; +end; + +function tdropdowncols.getitems(const index: integer): tdropdowncol; +begin + result:= tdropdowncol(inherited getitems(index)); +end; + +procedure tdropdowncols.setcount1(acount: integer; doinit: boolean); +begin + if not (aps_destroying in fstate) and (fowner <> nil) and + (acount <= tcustomdropdownlistcontroller(fowner).fvaluecol) then begin + acount:= tcustomdropdownlistcontroller(fowner).fvaluecol + 1; + end; + inherited; +end; + +procedure tdropdowncols.setwidth(const avalue: integer); +var + int1: integer; +begin + if fwidth <> avalue then begin + fwidth:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).width:= avalue; + end; + end; + end; +end; + +procedure tdropdowncols.setoptions(const avalue: coloptionsty); +var + int1: integer; + mask: longword; +begin + if foptions <> avalue then begin + mask:= longword(avalue) xor longword(foptions); + foptions:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).options:= + coloptionsty(replacebits(longword(foptions), + longword(tdropdowncol(fitems[int1]).options),mask)); + end; + end; + end; +end; + +procedure tdropdowncols.settextflags(const avalue: textflagsty); +var + int1: integer; + mask: longword; +begin + if ftextflags <> avalue then begin + mask:= longword(avalue) xor longword(ftextflags); + ftextflags:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).textflags:= + textflagsty(replacebits(longword(ftextflags), + longword(tdropdowncol(fitems[int1]).textflags),mask)); + end; + end; + end; +end; + +procedure tdropdowncols.setlinewidth(const avalue: integer); +var + int1: integer; +begin + if fwidth <> avalue then begin + flinewidth:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).linewidth:= avalue; + end; + end; + end; +end; + +procedure tdropdowncols.setlinecolor(const avalue: colorty); +var + int1: integer; +begin + if flinecolor <> avalue then begin + flinecolor:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).linecolor:= avalue; + end; + end; + end; +end; + +procedure tdropdowncols.setcolor(const avalue: colorty); +var + int1: integer; +begin + if fcolor <> avalue then begin + fcolor:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).color:= avalue; + end; + end; + end; +end; + +procedure tdropdowncols.setcolorselect(const avalue: colorty); +var + int1: integer; +begin + if fcolorselect <> avalue then begin + fcolorselect:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).colorselect:= avalue; + end; + end; + end; +end; + +procedure tdropdowncols.readfontcolorselect(reader: treader); +var + co1: colorty; +begin + co1:= reader.readinteger(); + if co1 <> cl_default then begin + createfontselect(); + ffontselect.color:= co1; + end; +end; + +procedure tdropdowncols.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('fontcolorselect',@readfontcolorselect,nil,false); +end; + +procedure tdropdowncols.setframetemplate(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fframetemplate)); +end; + +procedure tdropdowncols.setfacetemplate(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ffacetemplate)); +end; + +{ +procedure tdropdowncols.setfontcolorselect(const avalue: colorty); +var + int1: integer; +begin + if ffontcolorselect <> avalue then begin + ffontcolorselect:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).fontcolorselect:= avalue; + end; + end; + end; +end; +} +{ tcustomdropdownbuttonframe } + +constructor tcustomdropdownbuttonframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + inherited; +end; + +procedure tcustomdropdownbuttonframe.setreadonly(const Value: boolean); +begin + if (freadonly <> value) then begin + freadonly:= Value; + updatestate(); + end; +{ + if (freadonly <> value) and (factivebutton < buttons.count) then begin + freadonly:= Value; + buttons[factivebutton].enabled:= not value; + end; +} +end; + +procedure tcustomdropdownbuttonframe.updatestate(); +var + i1: integer; +begin + for i1:= 0 to buttons.count - 1 do begin + tframebutton1(tframebuttons1(buttons).fitems[i1]).freadonly:= freadonly; + end; + inherited; +end; + +function tcustomdropdownbuttonframe.getbuttonclass: framebuttonclassty; +begin + result:= tdropdownbutton; +end; + +procedure tcustomdropdownbuttonframe.updatedropdownoptions( + const avalue: dropdowneditoptionsty); +begin + buttons[factivebutton].visible:= not (deo_disabled in avalue); +end; + +function tcustomdropdownbuttonframe.getbutton: tdropdownbutton; +begin + result:= tdropdownbutton(inherited getbutton); +end; + +procedure tcustomdropdownbuttonframe.setbutton(const avalue: tdropdownbutton); +begin + inherited setbutton(avalue); +end; + +{ tcustomdropdowncontroller } + +constructor tcustomdropdowncontroller.create(const intf: idropdown); +begin + fintf:= intf; + fowner:= intf.getwidget; + foptions:= defaultdropdownoptionsedit; + fcolor:= cl_default; + fcolorclient:= cl_default; + inherited create; + internalcreateframe; +end; + +destructor tcustomdropdowncontroller.destroy; +begin + application.unregisteronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); + getdropdownwidget.Free; + inherited; +end; + +function tcustomdropdowncontroller.hasdropdown(): boolean; +var + wi1: twidget; +begin + wi1:= getdropdownwidget(); + result:= (wi1 <> nil) and not wi1.releasing(); +end; + +procedure tcustomdropdowncontroller.dostatread(const reader: tstatreader); +begin + //dummy +end; + +procedure tcustomdropdowncontroller.dostatwrite(const writer: tstatwriter); +begin + //dummy +end; + +function tcustomdropdowncontroller.getbuttonframeclass: + dropdownbuttonframeclassty; +begin + result:= tcustomdropdownbuttonframe; +end; + +procedure tcustomdropdowncontroller.internalcreateframe; +var + widget: twidget; +begin + widget:= fintf.getwidget; + if twidget1(widget).fframe = nil then begin + getbuttonframeclass.create(iscrollframe(widget),ibutton(self)); + end; + updatereadonlystate(); +end; + +procedure tcustomdropdowncontroller.setoptions( + const Value: dropdowneditoptionsty); +begin + foptions := Value; + tcustomdropdownbuttonframe( + twidget1(fintf.getwidget).fframe).updatedropdownoptions(value); +end; + +procedure tcustomdropdowncontroller.updatereadonlystate; +begin + tcustomdropdownbuttonframe(twidget1(fintf.getwidget).fframe).readonly:= + not fintf.geteditor.canedit or not candropdown; +end; + +function tcustomdropdowncontroller.candropdown: boolean; +begin + result:= fintf.geteditor.canedit; +end; + +procedure tcustomdropdowncontroller.internaldropdown; +begin + //dummy +end; + +procedure tcustomdropdowncontroller.dobeforedropdown; +begin + fintf.dobeforedropdown; + if deo_modifiedbeforedropdown in foptions then begin + fintf.modified; + end; +end; + +procedure tcustomdropdowncontroller.doafterclosedropdown; +begin + fintf.doafterclosedropdown; +end; + +procedure tcustomdropdowncontroller.dropdown; +begin + if not (deo_disabled in foptions) and candropdown and + (fdropdowncount = 0) then begin + dobeforedropdown; + internaldropdown; + application.postevent(tobjectevent.create(ek_dropdown,ievent(self))); + inc(fdropdowncount); + fintf.getwidget.window.registermovenotification(ievent(self)); + end; +end; + +procedure tcustomdropdowncontroller.canceldropdown; +var + widget1: twidget; +begin + widget1:= getdropdownwidget; + if widget1 <> nil then begin + widget1.window.modalresult:= mr_cancel; + end; +end; + +procedure tcustomdropdowncontroller.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + fintf.buttonaction(action,buttonindex); + if buttonindex = tcustomdropdownbuttonframe( + twidget1(fintf.getwidget).fframe).factivebutton then begin + with fintf.getwidget do begin + case action of + ba_buttonpress: begin + if canfocus then begin + setfocus; + end; + end; + ba_click: begin + if focused then begin + dropdown; + end; + end; + end; + end; + end; +end; + +procedure tcustomdropdowncontroller.mouseevent(var info: mouseeventinfoty); +begin + tcustombuttonframe( twidget1(fowner).fframe).mouseevent(info); +end; + +procedure tcustomdropdowncontroller.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if (key = key_down) and (shiftstate = [ss_alt]) and + (deo_keydropdown in foptions) and fintf.geteditor.canedit then begin + exclude(eventstate,es_processed); + dropdown; + include(eventstate,es_processed); + end; + end; +end; + +procedure tcustomdropdowncontroller.domousewheelevent( + var info: mousewheeleventinfoty); +begin + with info do begin + if not (es_processed in info.eventstate) then begin + if (wheel = mw_down) and fintf.getwidget.active then begin + dropdown; + include(info.eventstate,es_processed); + end + else begin + if (wheel = mw_up) and (getdropdownwidget <> nil) then begin + canceldropdown; + include(info.eventstate,es_processed); + end; + end; + end; + end; +end; + +procedure tcustomdropdowncontroller.selectnone(const akey: keyty); +begin + fdataselected:= true; + fintf.setdropdowntext('',true,false,akey); +end; + +procedure tcustomdropdowncontroller.editnotification( + var info: editnotificationinfoty); +begin + case info.action of + ea_textedited: begin + fdataselected:= false; + end; + ea_textentered: begin + if (deo_selectonly in foptions) and not fdataselected and + fintf.getedited then begin + if not (deo_forceselect in foptions) and + (fintf.geteditor.text = '') then begin + info.action:= ea_none; + selectnone(key_return); + end + else begin + if candropdown then begin + info.action:= ea_none; + dropdown; + end; + end; + end; + end; + end; +end; + +procedure tcustomdropdowncontroller.updatedropdownbounds(var arect: rectty); +begin + //dummy +end; + +procedure tcustomdropdowncontroller.updatedropdownpos(const arect: rectty); +var + widget1: twidget; + rect1: rectty; +begin + widget1:= getdropdownwidget; + if widget1 <> nil then begin + rect1:= arect; //widget1.widgetrect; + updatedropdownbounds(rect1); + getdropdownpos(fintf.getwidget,deo_right in foptions,rect1); + widget1.widgetrect:= rect1; + end; +end; + +procedure tcustomdropdowncontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_destroyed) and (sender = getdropdownwidget) then begin + dec(fdropdowncount); + fintf.getwidget.window.unregistermovenotification(ievent(self)); + application.unregisteronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); + end; + inherited; + if (event = oe_changed) and (sender = fintf.getwidget.window) and + (getdropdownwidget <> nil) then begin + updatedropdownpos(getdropdownwidget.widgetrect); + end; +end; + +function tcustomdropdowncontroller.getwidget: twidget; +begin + result:= fintf.getwidget; +end; + +function tcustomdropdowncontroller.getdropdownwidget: twidget; +begin + result:= nil; +end; + +function tcustomdropdowncontroller.dataselected: boolean; +begin + result:= fdataselected; +end; + +function tcustomdropdowncontroller.setdropdowntext(const avalue: msestring; + const docheckvalue: boolean; const canceled: boolean; + const akey: keyty): boolean; +begin + fdataselected:= fdataselected or docheckvalue; + fdataselected:= fintf.setdropdowntext(avalue,docheckvalue,canceled,akey); + result:= fdataselected; +end; + +procedure tcustomdropdowncontroller.applicationactivechanged(const avalue: boolean); +var + widget1: twidget; +begin + if not avalue then begin + widget1:= getdropdownwidget; + if (widget1 <> nil) and not widget1.window.hastransientfor then begin + canceldropdown; + end; +// getdropdownwidget.release; + end; +end; + +procedure tcustomdropdowncontroller.dropdownactivated; +begin + if dcs_forcecaret in fstate then begin + fintf.geteditor.doactivate; + end; +end; + +procedure tcustomdropdowncontroller.dropdowndeactivated; +begin + if dcs_forcecaret in fstate then begin + fintf.geteditor.dodeactivate; + end; +end; + +function tcustomdropdowncontroller.isloading: boolean; +begin + result:= csloading in fintf.getwidget.componentstate; +end; + +procedure tcustomdropdowncontroller.resetselection; +begin + //dummy +end; + +function tcustomdropdowncontroller.componentstate: tcomponentstate; +begin + result:= fintf.getwidget.componentstate; +end; + +procedure tcustomdropdowncontroller.setframetemplate(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fframetemplate)); +end; + +procedure tcustomdropdowncontroller.setfacetemplate(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ffacetemplate)); +end; + +{ tdropdowncontroller } + +function tdropdowncontroller.getbuttonframeclass: dropdownbuttonframeclassty; +begin + result:= tdropdownmultibuttonframe; +end; + +{ tdropdownwidgetcontroller } + +constructor tdropdownwidgetcontroller.create(const intf: idropdownwidget); +begin + inherited create(intf); +end; + +procedure tdropdownwidgetcontroller.internaldropdown; +var + widget1: twidget; +begin + inherited; + if fdropdownwidget = nil then begin + widget1:= nil; + try + idropdownwidget(fintf).createdropdownwidget(fintf.geteditor.text,widget1); + setlinkedvar(widget1,tmsecomponent(fdropdownwidget)); + if (deo_colsizing in options) and (fdropdownwidth > 0) then begin + bounds_cx:= fdropdownwidth; + end; + except + if widget1 <> nil then begin + widget1.release; + end; + raise; + end; + end; + fdropdownwidget.name:= '_dropdownwidget'; //debug purposes +end; + +function tdropdownwidgetcontroller.getdropdownwidget: twidget; +begin + result:= fdropdownwidget; +end; + +procedure tdropdownwidgetcontroller.updatedropdownbounds(var arect: rectty); +begin + if fbounds_cx > 0 then begin + arect.cx:= fbounds_cx; + end + else begin + arect.cx:= fintf.getwidget.framesize.cx; + end; + if fbounds_cy > 0 then begin + arect.cy:= fbounds_cy; + end; +end; + +procedure tdropdownwidgetcontroller.receiveevent(const event: tobjectevent); +begin + inherited; + if event.kind = ek_dropdown then begin + if fdropdownwidget <> nil then begin + updatedropdownpos(fdropdownwidget.widgetrect); + fdropdownwidget.window.winid; //update window.options + if fdropdownwidget.window.ispopup then begin + application.registeronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); + end; + if dcs_forcecaret in fstate then begin + fintf.geteditor.forcecaret:= true; + end; + try + if assigned(fondropdown) then begin + fondropdown(fintf.getwidget,fdropdownwidget); + end; + if fdropdownwidget.show(true,fintf.getwidget.window) = mr_ok then begin + fintf.geteditor.forcecaret:= false; + setdropdowntext(idropdownwidget(fintf).getdropdowntext(fdropdownwidget), + true,false,fselectkey); + end; + finally + fintf.geteditor.forcecaret:= false; + doafterclosedropdown; + end; + if deo_colsizing in foptions then begin + fdropdownwidth:= fdropdownwidget.width; + end; + fdropdownwidget.Free; + fdropdownwidget:= nil; + end; + end; +end; + +procedure tdropdownwidgetcontroller.editnotification( + var info: editnotificationinfoty); +begin + inherited; + case info.action of + ea_textedited: begin + if fdropdownwidget = nil then begin + if (deo_autodropdown in foptions) and + ((fintf.geteditor.text <> '') or (deo_forceselect in foptions)) then begin + dropdown; + end; + end; + end; + end; +end; + +procedure tdropdownwidgetcontroller.dostatread(const reader: tstatreader); +begin + if deo_savestate in foptions then begin + fdropdownwidth:= reader.readinteger('dropdownwidth',0); + end; +end; + +procedure tdropdownwidgetcontroller.dostatwrite(const writer: tstatwriter); +begin + if deo_savestate in foptions then begin + writer.writeinteger('dropdownwidth',fdropdownwidth); + end; +end; + +{ tcustomdropdownlistcontroller } + +constructor tcustomdropdownlistcontroller.create(const intf: idropdownlist); +begin + include(fstate,dcs_forcecaret); + fcols:= getdropdowncolsclass.create(self); + fcols.onitemchange:= {$ifdef FPC}@{$endif}itemchanged; + fcols.fitemindex:= -1; + fdropdownrowcount:= 8; + fdatarowlinecolor:= defaultdatalinecolor; + fbuttonminlength:= defaultbuttonminlength; + inherited create(intf); +end; + +destructor tcustomdropdownlistcontroller.destroy; +begin + freeandnil(ftimer); + inherited; + fcols.Free; +end; + +function tcustomdropdownlistcontroller.getdropdowncolsclass: dropdowncolsclassty; +begin + result:= tdropdowncols; +end; + +procedure tcustomdropdownlistcontroller.dotimer(const sender: tobject); +begin + if fdropdownlist <> nil then begin + if not (dcs_itemselecting in fstate) then begin + fdropdownlist.filtertext:= fintf.geteditor.text; + end; + end + else begin + if (deo_autodropdown in foptions) then begin + if candropdown and ((fintf.geteditor.text <> '') or + (deo_forceselect in foptions)) then begin + dropdown; + end; + end + else begin + fcols.fitemindex:= -1; + end; + end; +end; + +procedure tcustomdropdownlistcontroller.editnotification( + var info: editnotificationinfoty); +begin + inherited; + case info.action of + ea_textedited: begin + if ftimer = nil then begin + dotimer(nil); + end + else begin + ftimer.restart; + end; + end; + end; +end; + +function tcustomdropdownlistcontroller.valuelist: tmsestringdatalist; +begin + result:= fcols[fvaluecol]; +end; + +procedure tcustomdropdownlistcontroller.itemchanged( + const sender: tdatalist; const index: integer); +begin + if (deo_selectonly in foptions) and (index = fcols.fitemindex) and + (index >= 0) then begin + setdropdowntext(valuelist[index],false,false,key_none); + end; +end; + +function tcustomdropdownlistcontroller.createdropdownlist: tdropdownlist; +begin + result:= tdropdownlist.create(self,fcols,getfixcolclass); + result.name:= '_dropdownlist'; //debug purposes +end; + +procedure tcustomdropdownlistcontroller.updatedropdownbounds(var arect: rectty); +begin + if fwidth = 0 then begin + arect.cx:= fintf.getwidget.framesize.cx; + end + else begin + if fwidth = -1 then begin + arect.cx:= getautowidth; + end + else begin + arect.cx:= fwidth; + end; + end; +end; + +function tcustomdropdownlistcontroller.getautowidth: integer; +var + int1: integer; +begin + result:= 0; + if fdropdownlist = nil then begin + for int1:= 0 to high(fcols.fitems) do begin + with tdropdowncol(fcols.fitems[int1]) do begin + if not (co_invisible in foptions) then begin + result:= result+fwidth+flinewidth; + end; + end; + end; + end + else begin + for int1:= 0 to fdropdownlist.datacols.count -1 do begin + with tdatacol(tdatacols1(fdropdownlist.fdatacols).fitems[int1]) do begin + if not (co_invisible in options) then begin + result:= result+width+linewidth; + end; + end; + end; + result:= result + fdropdownlist.framedim.cx; + end; +end; + +procedure tcustomdropdownlistcontroller.receiveevent(const event: tobjectevent); +var + int1,int2{,int3,int4}: integer; +// rect1: rectty; + str1: msestring; + widget1: twidget; + items1: tdropdowndatacols; + bo1: boolean; +begin + inherited; + if event.kind = ek_dropdown then begin + if fdropdownlist = nil then begin + items1:= idropdownlist(fintf).getdropdownitems; + if items1 <> nil then begin //tselector + if fcols.count < items1.count then begin + fcols.count:= items1.count; + end; + fcols.fdatacols:= items1; + end + else begin + fcols.fdatacols:= fcols; + end; + setlinkedcomponent(ievent(self),createdropdownlist, + tmsecomponent(fdropdownlist)); + fdropdownlist.name:= '_dropdownlist'; //debug purpose + fdropdownlist.updateskin; + try + with fdropdownlist.frame.sbvert do begin + buttonminlength:= fbuttonminlength; + buttonlength:= fbuttonlength; + buttonendlength:= fbuttonendlength; + end; + application.registeronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); + fintf.geteditor.forcecaret:= true; + try + widget1:= self.fintf.getwidget; + with fdropdownlist do begin + if deo_casesensitive in self.foptions then begin + options:= options + [dlo_casesensitive]; + end; + if deo_posinsensitive in self.foptions then begin + options:= options + [dlo_posinsensitive]; + end; + if deo_livefilter in self.foptions then begin + options:= options + [dlo_livefilter]; + end; + if deo_sorted in self.foptions then begin + sort; + end; + if fwidth = 0 then begin + int1:= widget1.framesize.cx; + end + else begin + if fwidth = -1 then begin + int1:= getautowidth; + end + else begin + int1:= fwidth; + end; + end; + with self.fintf.geteditor do begin + str1:= text; + bo1:= canundo(); + end; + int2:= fcols.fitemindex; + if (int2 >= 0) and + ((fcols.fdatacols.count = 0) or (int2 >= fcols.fdatacols[0].count) or + (str1 <> fcols.fdatacols[0][int2]) and + (bo1 or (fcols.fdatacols = fcols))) then begin + //no tselector + int2:= -1; + end; + fselectkey:= key_none; + if assigned(fondropdown) then begin + fondropdown(widget1,fdropdownlist); + end; + show(int1,self.fdropdownrowcount,int2,str1); + fintf.geteditor.forcecaret:= false; + include(self.fstate,dcs_itemselecting); + self.itemselected(int2,fselectkey); + end; + finally + exclude(self.fstate,dcs_itemselecting); + fintf.geteditor.forcecaret:= false; + doafterclosedropdown; + end; + if deo_colsizing in options then begin + for int1:= 0 to high(fcols.fitems) do begin + tdropdowncol(fcols.fitems[int1]).width:= + tdatacol(tdatacols1(fdropdownlist.fdatacols).fitems[int1]).width; + end; + end; + finally + fdropdownlist.free; + freeandnil(fdropdownlist); + end; + end; + end; +end; + +function tcustomdropdownlistcontroller.getitemindex: integer; +begin + result:= fcols.fitemindex; +end; + +procedure tcustomdropdownlistcontroller.setitemindex(const Value: integer); +begin + if (value >= valuelist.Count) or (value < 0) then begin + fcols.fitemindex:= -1; + end + else begin + fcols.fitemindex:= Value; + end; + if fcols.fitemindex < 0 then begin + fcols.fkeyvalue:= ''; + setdropdowntext('',false,false,key_none); + end + else begin + fcols.fkeyvalue:= valuelist[fcols.fitemindex]; + fdataselected:= true; + setdropdowntext(fcols.fkeyvalue,false,false,key_none); + end; +end; + +procedure tcustomdropdownlistcontroller.setcols(const Value: tdropdowncols); +begin + fcols.assign(value); +end; + +procedure tcustomdropdownlistcontroller.dropdownkeydown(var info: keyeventinfoty); +var + editor1: tinplaceedit1; + str1: msestring; +begin + editor1:= tinplaceedit1(fintf.geteditor); + editor1.dokeydown(info); + with info do begin + if not (es_processed in eventstate) and (shiftstate*shiftstatesmask = []) then begin + case key of + key_right: begin + with fdropdownlist do begin + if (row >= 0) then begin + str1:= tstringcol1(fdropdownlist[fvaluecol]).getrowtext(row); + if length(str1) > editor1.curindex then begin + editor1.text:= copy(str1,1,editor1.curindex); + editor1.enterchars(copy(str1,editor1.curindex+1,1)); +// editor1.text:= copy(str1,1,editor1.curindex+1); +// editor1.curindex:= editor1.curindex + 1; + include(eventstate,es_processed); + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tcustomdropdownlistcontroller.itemselected(const index: integer; + const akey: keyty); +var + int1: integer; +begin + int1:= index; + if deo_forceselect in foptions then begin + if int1 < 0 then begin + int1:= fcols.fitemindex; + end; + end + else begin + if int1 = -2 then begin //empty row selected + int1:= -1; + fcols.fitemindex:= int1; + if deo_selectonly in foptions then begin +// fcols.fitemindex:= int1; + fcols.fkeyvalue:= ''; + setdropdowntext('',true,false,akey); + end + else begin + setdropdowntext(fintf.geteditor.text,true,false,akey); + end; + end + else begin + if (int1 < 0) and (deo_selectonly in foptions) then begin + setdropdowntext(fintf.geteditor.text,false,true,akey); + //editor.undo + end; + end; + end; + if index <> -1 then begin + fcols.fitemindex:= int1; + end; + if int1 >= 0 then begin + fcols.fkeyvalue:= valuelist[int1]; + setdropdowntext(fcols.fkeyvalue,index <> - 1,index = -1,akey); + end; +end; + +function tcustomdropdownlistcontroller.getdropdownwidget: twidget; +begin + result:= fdropdownlist; +end; + +procedure tcustomdropdownlistcontroller.setvaluecol(const avalue: integer); +begin + if fvaluecol <> avalue then begin + fcols.checkindex(avalue); + fvaluecol:= avalue; + valuecolchanged; + end; +end; + +procedure tcustomdropdownlistcontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = fimagelist) then begin + case event of + oe_destroyed: begin + fimagelist:= nil; + imagelistchanged; + end; + oe_changed: begin + imagelistchanged; + end; + end; + end; +end; + +procedure tcustomdropdownlistcontroller.setimagelist(const avalue: timagelist); +begin + if fimagelist <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + imagelistchanged; + end; +end; + +procedure tcustomdropdownlistcontroller.valuecolchanged; +begin + //dummy +end; + +procedure tcustomdropdownlistcontroller.selectnone(const akey: keyty); +begin + itemselected(-2,akey); +end; + +procedure tcustomdropdownlistcontroller.resetselection; +begin + fcols.fitemindex:= -1; +end; + +function tcustomdropdownlistcontroller.reloadlist: integer; +begin + result:= fdropdownlist.updatevisiblerows(); +end; + +function tcustomdropdownlistcontroller.getremoterowcount: integer; +begin + result:= 0; //dummy +end; + +procedure tcustomdropdownlistcontroller.internaldropdown; +begin + inherited; +end; + +procedure tcustomdropdownlistcontroller.dostatread(const reader: tstatreader); +var + ar1: integerarty; + int1: integer; +begin + if deo_savestate in foptions then begin + ar1:= reader.readarray('dropdowncolwidths',integerarty(nil)); + for int1:= 0 to high(ar1) do begin + if int1 > high(fcols.fitems) then begin + break; + end; + tdropdowncol(fcols.fitems[int1]).fwidth:= ar1[int1]; + end; + end; +end; + +procedure tcustomdropdownlistcontroller.dostatwrite(const writer: tstatwriter); +var + int1: integer; + ar1: integerarty; +begin + if deo_savestate in foptions then begin + setlength(ar1,fcols.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tdropdowncol(fcols.fitems[int1]).fwidth; + end; + writer.writearray('dropdowncolwidths',ar1); + end; +end; + +procedure tcustomdropdownlistcontroller.imagelistchanged; +begin + idropdownlist(fintf).imagelistchanged; +end; + +procedure tcustomdropdownlistcontroller.setimageframe(const avalue: framety); +begin + fimageframe:= avalue; + imagelistchanged; +end; + +procedure tcustomdropdownlistcontroller.setimageframe_left(const avalue: integer); +begin + fimageframe.left:= avalue; + imagelistchanged; +end; + +procedure tcustomdropdownlistcontroller.setimageframe_top(const avalue: integer); +begin + fimageframe.top:= avalue; + imagelistchanged; +end; + +procedure tcustomdropdownlistcontroller.setimageframe_right(const avalue: integer); +begin + fimageframe.right:= avalue; + imagelistchanged; +end; + +procedure tcustomdropdownlistcontroller.setimageframe_bottom(const avalue: integer); +begin + fimageframe.bottom:= avalue; + imagelistchanged; +end; + +function tcustomdropdownlistcontroller.getfixcolclass: dropdownfixcolclassty; +begin + result:= nil; //dummy +end; + +procedure tcustomdropdownlistcontroller.dobeforedropdown; +begin + if deo_livefilter in foptions then begin + with fintf.geteditor do begin + if not canundo then begin + text:= ''; + end; + end; + end; + inherited; +end; + +procedure tcustomdropdownlistcontroller.doafterclosedropdown; +begin + if ftimer <> nil then begin + ftimer.enabled:= false; //cancel pending updates + end; + inherited; +end; + +function tcustomdropdownlistcontroller.getdelay: integer; +begin + result:= 0; + if ftimer <> nil then begin + result:= ftimer.interval div 1000; + if result = 0 then begin + result:= -1; + end; + end; +end; + +procedure tcustomdropdownlistcontroller.setdelay(avalue: integer); +begin + if avalue = 0 then begin + freeandnil(ftimer); + end + else begin + if avalue < 0 then begin + avalue:= 0; + end; + avalue:= avalue * 1000; + if ftimer = nil then begin + ftimer:= tsimpletimer.create(avalue,@dotimer,false,[to_single]); + end; + ftimer.interval:= avalue; + end; +end; + +{ tnocolsdropdownlistcontroller } + +constructor tnocolsdropdownlistcontroller.create(const intf: idropdownlist); +begin + inherited; + cols.nostreaming:= true; +end; + +function tnocolsdropdownlistcontroller.getbuttonframeclass: dropdownbuttonframeclassty; +begin + result:= tdropdownmultibuttonframe; +end; + +{ tdropdownlistcontroller } + +constructor tdropdownlistcontroller.create(const intf: idropdownlist); +begin + inherited; + cols.nostreaming:= false; +end; + +{ tmbdropdownlistcontroller } + +function tmbdropdownlistcontroller.getbuttonframeclass: dropdownbuttonframeclassty; +begin + result:= tdropdownmultibuttonframe; +end; + +{ tdropdownstringcol } + +destructor tdropdownstringcol.destroy; +begin + fdata:= nil; + inherited; +end; + +function tdropdownstringcol.createdatalist: tdatalist; +begin + result:= nil; +end; + +constructor tdropdownstringcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + inherited; + include(foptions,co_readonly); +end; + +{ titemselectedevent } + +constructor titemselectedevent.create(const dest: tmsecomponent; const arow: integer); +begin + frow:= arow; + inherited create(self); +end; + +{ tdropdownlist } + +constructor tdropdownlist.create( + const acontroller: tcustomdropdownlistcontroller; + const acols : tdropdowncols; + const afixcolclass: dropdownfixcolclassty); +var + aparent: twidget; + widget1: twidget; + col1: colorty; + int1: integer; +begin + fcontroller:= acontroller; + aparent:= fcontroller.getwidget; + inherited create(nil); + fdatacols.innerframe:= defaultdropdowncellinnerframe; + visible:= false; + beginupdate; + try + datarowlinewidth:= acontroller.fdatarowlinewidth; + datarowlinecolor:= acontroller.fdatarowlinecolor; + exclude(foptionsgrid,og_focuscellonenter); + ffocusedcell.col:= 0; + if fcontroller.color = cl_default then begin + widget1:= aparent; + repeat + col1:= widget1.parentcolor; + widget1:= widget1.parentwidget; + until (col1 <> cl_transparent) or (widget1 = nil); + if col1 = cl_transparent then begin + col1:= cl_background; + end; + color:= col1; + end + else begin + color:= fcontroller.color; + end; + tcustomframe1(fframe).fi.levelo:= 0; + tcustomframe1(fframe).fi.framewidth:= 1; + tcustomframe1(fframe).fi.colorframe:= cl_black; + if fcontroller.fframetemplate <> nil then begin + fframe.template:= fcontroller.fframetemplate; + end; + if (fcontroller.colorclient <> cl_default) and (fframe <> nil) then begin + fframe.colorclient:= fcontroller.colorclient; + end; + if fcontroller.ffacetemplate <> nil then begin + createface(); + fface.template:= fcontroller.ffacetemplate; + end; + fdatacols.options:= fdatacols.options + [co_focusselect,co_readonly]; + font:= twidget1(aparent).getfont; + initcols(acols); + if afixcolclass <> nil then begin + tcustomframe1(fframe).updatestate(); + synctofontheight(); + ffixcols.add(afixcolclass.create(self,ffixcols,fcontroller)); + end; + tcustomframe1(fframe).updatestate(); + synctofontheight(); + if acontroller.imagelist <> nil then begin + ffixcols.add(timagefixcol.create(self,ffixcols,fcontroller)); + int1:= fcontroller.imagelist.height + fcontroller.fimageframe.top + + fcontroller.fimageframe.bottom; + if datarowheight < int1 then begin + datarowheight:= int1; + end; + end; + finally + endupdate; + end; +end; + +destructor tdropdownlist.destroy; +begin + killrepeater; + inherited; +end; + +procedure tdropdownlist.initcols(const acols: tdropdowncols); +var + int1,int2: integer; + col1: tdropdowncol; + frata1: tframecomp; + fata1: tfacecomp; +begin + if acols.font <> nil then begin + createfont(); + font.assign(acols.font); + end; + if acols.fontselect <> nil then begin + fdatacols.createfontselect(); + datacols.fontselect.assign(acols.fontselect); + end; + if (acols.count > 0) and (acols.fdatacols.count > 0) then begin + if deo_colsizing in fcontroller.options then begin + optionsgrid:= optionsgrid + [og_colsizing]; + end; + int2:= acols.fdatacols.maxrowcount; + rowcount:= int2; + fdatacols.count:= acols.count; + for int1:= 0 to acols.count - 1 do begin + col1:= acols[int1]; + with tstringcol1(fdatacols[int1]) do begin + if acols.fdatacols.count > int1 then begin + fdata:= acols.fdatacols[int1]; + fdata.count:= int2; + end; +// fdata:= col1.fdata; + options:= col1.foptions; + optionsedit:= defaultstringcoleditoptions - [scoe_autoselect,scoe_autoselectonfirstclick]; + width:= col1.fwidth; + linewidth:= col1.flinewidth; + linecolor:= col1.flinecolor; + textflags:= col1.ftextflags; + passwordchar:= col1.passwordchar; + textflagsactive:= col1.ftextflags; + if col1.fcolor <> cl_default then begin + color:= col1.fcolor; + end; + if col1.fcolorselect <> cl_default then begin + colorselect:= col1.fcolorselect; + end; + { + if col1.ffontcolorselect <> cl_default then begin + createfontselect; + fontselect.assign(getfont); + fontselect.color:= col1.ffontcolorselect; + end; + } + if col1.font <> nil then begin + createfont(); + font.assign(col1.font); + end; + if col1.fontselect <> nil then begin + createfontselect(); + fontselect.assign(col1.fontselect); + end; + frata1:= col1.fframetemplate; + if frata1 = nil then begin + frata1:= acols.fframetemplate; + end; + if frata1 <> nil then begin + createframe(); + fframe.template:= frata1; + end; + fata1:= col1.ffacetemplate; + if fata1 = nil then begin + fata1:= acols.ffacetemplate; + end; + if frata1 <> nil then begin + createface(); + fface.template:= fata1; + end; + end; + if col1.caption <> '' then begin + fixrows.count:= 1; + with fixrows[-1] do begin + captions.count:= int1 + 1; + captions[int1].caption:= col1.caption; + end; + end; + end; + end; +end; + +procedure tdropdownlist.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= tdropdownstringcol.create(self,fdatacols); +end; + +procedure tdropdownlist.doactivate; +begin + capturemouse; + inherited; + fcontroller.dropdownactivated; +end; + +procedure tdropdownlist.dodeactivate; +begin + inherited; + fcontroller.dropdowndeactivated; +end; + +procedure tdropdownlist.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if shiftstate*shiftstatesrepeatmask = [] then begin + include(eventstate,es_processed); + case key of + key_return,{key_enter,}key_tab: begin + if ffocusedcell.row < 0 then begin + itemselected(-2,key); //nil selection + end + else begin + itemselected(ffocusedcell.row,key); + end; + end; + key_up,key_down: begin + if (focusedcell.row < 0) and (frowcount > 0) then begin + if key = key_down then begin + row:= 0; + end + else begin + row:= rowcount -1; + end; + end + else begin + exclude(eventstate,es_processed); + end; + end; + key_escape: begin + canceldropdown; + exit; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end; + if not (es_processed in eventstate) then begin + fcontroller.dropdownkeydown(info); + if not (es_processed in eventstate) then begin + inherited; + end; + end; + end; +end; + +procedure tdropdownlist.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if (info.eventkind = ek_buttonpress) and + not pointinrect(translatewidgetpoint(info.pos,self,nil), + fwidgetrect) then begin + canceldropdown; + end; +end; + +procedure tdropdownlist.setactiveitem(const aitemindex: integer); +begin + focuscell(makegridcoord(0,aitemindex)); +end; + +function tdropdownlist.getassistiveparent(): iassistiveclient; +begin + result:= twidget1(fcontroller.fintf.getwidget()).getiassistiveclient(); +end; + +function tdropdownlist.dropdownheight: integer; +var + int1,int2: integer; +begin + int2:= fdatacols.rowstate.visiblerowcount; + if fdropdownrowcount = 0 then begin + int1:= int2; + end + else begin + int1:= fdropdownrowcount; + end; + if (int1 > int2){ and not + (deo_livefilter in fcontroller.foptions)} then begin + int1:= int2; + end; + if int1 = 0 then begin + result:= ystep div 2; + end + else begin + result:= int1 * ystep; + end; + if fixrows.count > 0 then begin + with fixrows[-1] do begin + result:= result+ height + linewidth; + end; + end; + result:= result + fframe.paintframedim.cy; +end; + +procedure tdropdownlist.show(awidth: integer; const arowcount: integer; + var aitemindex: integer; afiltertext: msestring); +var + rect1: rectty; + int1: integer; +begin + fstate:= fstate * [gs_isdb]; + bounds_cx:= awidth; + rect1:= widgetrect; + rect1.cx:= awidth; + fdropdownrowcount:= arowcount; +// rect1.cy:= dropdownheight; +// fcontroller.updatedropdownpos(rect1); + ffiltertext:= afiltertext; + if deo_livefilter in fcontroller.foptions then begin + int1:= updatevisiblerows(); + if afiltertext <> '' then begin + setactiveitem(int1); + end + else begin + setactiveitem(aitemindex); + end; + end + else begin + if (aitemindex = -1) and (ffiltertext <> '') then begin + application.beginnoignorewaitevents; + try + locate(ffiltertext); + finally + application.endnoignorewaitevents; + end; + end + else begin + setactiveitem(aitemindex); + end; + end; + rect1.cy:= dropdownheight; + fcontroller.updatedropdownpos(rect1); + if inherited show(true,fcontroller.getwidget.window) = mr_ok then begin + aitemindex:= fselectedindex; + end + else begin + aitemindex:= -1; + end; +end; + +procedure tdropdownlist.updatewindowinfo(var info: windowinfoty); +begin + inherited; + with info do begin + options:= options + [wo_popup]; + transientfor:= fcontroller.getwidget.window; + end; +end; + +procedure tdropdownlist.itemselected(const index: integer; const akey: keyty); +begin + fselectedindex:= index; + fcontroller.fselectkey:= akey; + window.modalresult:= mr_ok; +end; + +function tdropdownlist.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags(); + if ownswindow then begin + result:= result + [asf_popup]; + end; +end; + +procedure tdropdownlist.docellevent(var info: celleventinfoty); +var + hintinfo: hintinfoty; +begin + with info do begin + if iscellclick(info,[ccr_buttonpress],[],keyshiftstatesmask) then begin + itemselected(cell.row,key_none); + end + else begin + if (deo_cliphint in fcontroller.foptions) and + (eventkind = cek_firstmousepark) and + textclipped(cell) then begin + application.inithintinfo(hintinfo,self); + hintinfo.caption:= tdropdownstringcol(self[cell.col]).getrowtext(cell.row); + application.showhint(self,hintinfo); + include(mouseeventinfopo^.eventstate,es_processed); + end + else begin + inherited; + end; + end; + end; +end; + +procedure tdropdownlist.canceldropdown; +begin + itemselected(-1,key_none); //canceled +end; + +procedure tdropdownlist.clientmouseevent(var info: mouseeventinfoty); +begin + if (info.eventkind = ek_mousemove) and not canassistive() then begin + if dls_mousemoved in fdropdownstate then begin + if fobjectpicker.active then begin + killrepeater(); + end + else begin + with fdatarecty do begin + if (info.pos.y < y + mouseautoscrollheight) and + (info.pos.y >= y) then begin + startrepeater(false); + end + else begin + if info.pos.y >= y + cy - mouseautoscrollheight then begin + startrepeater(true); + end + else begin + killrepeater(); + end; + end; + end; + end; + end + else begin + if not (dls_firstmousemoved in fdropdownstate) then begin + ffirstmousepos:= info.pos; + include(fdropdownstate,dls_firstmousemoved); + end + else begin + if distance(info.pos,ffirstmousepos) > 3 then begin + include(fdropdownstate,dls_mousemoved); + end; + end; + end; + end + else begin + if info.eventkind = ek_clientmouseleave then begin + killrepeater; + end; + end; + inherited; +end; + +function tdropdownlist.getkeystring(const aindex: integer): msestring; +begin + if folded and rowhidden[aindex] then begin + result:= ''; + end + else begin + with tstringcol(fdatacols[0]) do begin + result:= items[aindex]; + end; + end; +end; + +function tdropdownlist.getkeystringnohidden(const aindex: integer): msestring; +begin + with tstringcol(fdatacols[0]) do begin + result:= items[aindex]; + end; +end; + +function tdropdownlist.locate(const filter: msestring): boolean; +var + int1: integer; + opt1: locatestringoptionsty; + co1: gridcoordty; +begin + if (rowcount > 0) and (fdatacols.count > 0) then begin + int1:= focusedcell.row; + opt1:= []; + if dlo_casesensitive in foptions1 then begin + opt1:= [lso_casesensitive]; + end; + if dlo_posinsensitive in foptions1 then begin + include(opt1,lso_posinsensitive); + end; + result:= locatestring(filter,{$ifdef FPC}@{$endif}getkeystring,opt1, + fdatacols[0].datalist.count,int1); + if result then begin + co1:= makegridcoord(ffocusedcell.col,int1); + showcell(co1,cep_top); + focuscell(co1); + end + else begin + focuscell(makegridcoord(ffocusedcell.col,-1)); + end; + end + else begin + result:= false; + end; +end; + +function tdropdownlist.updatevisiblerows(): integer; +var + int1,int2,int3,count1: integer; + opt1: locatestringoptionsty; + bo1: boolean; + s1: msestring; +begin + result:= invalidaxis; + if (rowcount > 0) and (fdatacols.count > 0) then begin + if deo_customfilter in fcontroller.options then begin + result:= 0; + end + else begin + folded:= true; + beginupdate; + int1:= 0; + opt1:= [lso_nodown,lso_noexact]; + if dlo_casesensitive in foptions1 then begin + include(opt1,lso_casesensitive); + s1:= ffiltertext; + end + else begin + include(opt1,lso_filterisuppercase); + s1:= mseuppercase(ffiltertext); + end; + if dlo_posinsensitive in foptions1 then begin + include(opt1,lso_posinsensitive); + end; + count1:= fdatacols[0].datalist.count; + repeat + int2:= int1; + bo1:= locatestring(s1,{$ifdef FPC}@{$endif}getkeystringnohidden, + opt1,count1,int1); + if not bo1 then begin + int1:= fdatacols[0].datalist.count; + end; + for int3:= int2 to int1 - 1 do begin + rowhidden[int3]:= true; + end; + if bo1 then begin + rowhidden[int1]:= false; + if result = invalidaxis then begin + result:= int1; + end; + inc(int1); + end; + until not bo1 or (int1 >= count1); + endupdate; + end; + end; +end; + +procedure tdropdownlist.setfiltertext(const Value: msestring); +var + li1: tdatalist; + rect1: rectty; + int1: integer; +begin + ffiltertext:= Value; + if dlo_livefilter in foptions1 then begin + int1:= fcontroller.reloadlist(); + if (fdatacols.count > 0) then begin + li1:= tdropdownstringcol(fdatacols[0]).fdata; + if li1 <> nil then begin + rowcount:= li1.count; + end; + end; + rect1:= widgetrect; + rect1.cy:= dropdownheight; + fcontroller.updatedropdownpos(rect1); + invalidate; + row:= int1; + setupeditor(ffocusedcell,true); + end + else begin + locate(ffiltertext); + end; +end; + +procedure tdropdownlist.killrepeater; +begin + freeandnil(frepeater); +end; + +procedure tdropdownlist.startrepeater(up: boolean); +begin + if frepeater = nil then begin + frepeater:= tsimpletimer.create(100000,{$ifdef FPC}@{$endif}dorepeat,true,[]); + end; + if up then begin + include(fdropdownstate,dls_scrollup); + end + else begin + exclude(fdropdownstate,dls_scrollup); + end; +end; + +procedure tdropdownlist.dorepeat(const sender: tobject); +begin + if dls_scrollup in fdropdownstate then begin + rowdown(fca_focusin); + end + else begin + rowup(fca_focusin); + end; +end; + +procedure tdropdownlist.updatelayout; +var + int1: integer; +begin + try + inc(fupdatelayoutcount); + if fupdatelayoutcount < 16 then begin + inherited; + if fcontroller.width = -1 then begin + int1:= fcontroller.getautowidth; + if width <> int1 then begin + width:= int1; + updatelayout; + end; + end; + end; + finally + dec(fupdatelayoutcount); + end; +end; + +{ tdropdownbutton } + +constructor tdropdownbutton.create(aowner: tobject); +begin + inherited; + finfo.ca.imagenr:= ord(stg_arrowdownsmall); +end; + +{ tdropdownfixcol } + +constructor tdropdownfixcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); +begin + fcontroller:= acontroller; + inherited create(agrid,aowner); + linewidth:= 0; + color:= acontroller.color; +end; + +{ timagefixcol } + +constructor timagefixcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); +begin + inherited create(agrid,aowner,acontroller); + fimagelist:= acontroller.imagelist; + fimageframe:= acontroller.imageframe; + width:= fimagelist.width + acontroller.fimageframe.left + + acontroller.fimageframe.right; + fcolorselect:= acontroller.cols.colorselect; +end; + +procedure timagefixcol.drawcell(const canvas: tcanvas); +begin + inherited; + with cellinfoty(canvas.drawinfopo^) do begin + fimagelist.paint(canvas,cell.row,deflaterect(rect,fimageframe), + [al_ycentered]); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/mseedit.pas b/mseide-msegui/lib/common/editwidgets/mseedit.pas new file mode 100644 index 0000000..69326ed --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/mseedit.pas @@ -0,0 +1,2437 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseedit; + +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +uses + msegui,mseeditglob,msegraphics,msegraphutils,msedatalist, + mseevent,mseglob,mseguiglob,msestat,msestatfile,mserichstring, + mseinplaceedit,msegrids,msetypes,mseshapes,msewidgets, + msedrawtext,classes,mclasses,msereal,mseclasses,msearrayprops, + msebitmap,msemenus,msetimer,mseactions,msekeyboard, + msesimplewidgets,msepointer,msestrings,msescrollbar,mseassistiveclient + {$ifdef mse_with_ifi},mseifiglob{$endif}; + +const + defaulteditwidgetoptions = defaultoptionswidget + {+[ow_fontglyphheight,ow_autoscale]}; + defaulteditwidgetoptions1 = defaultoptionswidget1+ + [ow1_fontglyphheight,ow1_autoscale]; + defaulteditwidgetwidth = 100; + defaulteditwidgetheight = 20; + defaulttextflags = [tf_ycentered,tf_noselect]; + defaulttextflagsactive = [tf_ycentered]; + defaulttextflagsnoycentered = defaulttextflags - [tf_ycentered]; + defaulttextflagsactivenoycentered = defaulttextflagsactive - [tf_ycentered]; + defaulttextflagsempty = [tf_ycentered,tf_xcentered]; + +type + + teditframe = class(tcustomcaptionframe) + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: icaptionframe); + published + property options; + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property colorclient {default cl_foreground}; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + tscrolleditframe = class(tcustomthumbtrackscrollframe) + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: iscrollframe; const scrollintf: iscrollbar); + published + property options; + property optionsscroll; + property dragbuttons; + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient {default cl_foreground}; + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + property sbhorz; + property sbvert; + end; + + tscrollboxeditframe = class(tcustomscrollboxframe) + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: iscrollframe; const owner: twidget); + published + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + property sbhorz; + property sbvert; + property colorclient {default cl_foreground}; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + buttonactionty = (ba_none,ba_buttonpress,ba_buttonrelease,ba_click); + ibutton = interface(inullinterface) + procedure buttonaction(var action: buttonactionty; const buttonindex: integer); + end; + buttoneventty = procedure(const sender: tobject; var action: buttonactionty; + const buttonindex: integer) of object; + framebuttonoptionty = + (fbo_left,fbo_invisible,fbo_inactiveinvisible, + fbo_disabled,fbo_enabled, //overrides frame readonly state + fbo_executeonclientdblclick, + fbo_flat,fbo_noanim,fbo_nomouseanim,fbo_noclickanim,fbo_nofocusanim); + framebuttonoptionsty = set of framebuttonoptionty; + + tcustombuttonsframe = class; + + tframebutton = class(townedeventpersistent,iframe,iimagelistinfo) + private + fbuttonwidth: integer; + foptions: framebuttonoptionsty; + fonexecute: notifyeventty; + faction: taction; + fshortcut: shortcutty; + procedure setbuttonwidth(const Value: integer); + procedure setoptions(const Value: framebuttonoptionsty); + procedure optionstostate(); + procedure changed; + function getleft: boolean; + procedure setleft(const Value: boolean); + function getvisible: boolean; + procedure setvisible(const Value: boolean); + function getenabled: boolean; + procedure setenabled(const Value: boolean); + procedure setcolor(const avalue: colorty); + procedure setcolorglyph(const avalue: colorty); + procedure setimagelist(const Value: timagelist); + procedure setimagenr(const avalue: imagenrty); + procedure setimagenrdisabled(const avalue: imagenrty); + function getface: tface; + procedure setface(const avalue: tface); + function getframe: tframe; + procedure setframe(const avalue: tframe); + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function getwidgetrect: rectty; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; const org: originty = org_client; + const noclip: boolean = false); + function getwidget: twidget; + function getframestateflags: framestateflagsty; virtual; + function getimagelist: timagelist; + procedure setaction(const avalue: taction); + protected + fframerect: rectty; + finfo: shapeinfoty; + fframe: tframe; + freadonly: boolean; //for checkreadonlystate of tbuttonframe + procedure doexec(); + procedure mouseevent(var info: mouseeventinfoty; + const intf: iframe; const buttonintf: ibutton; + const index: integer); + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure createface; + procedure createframe; + procedure checktemplate(const sender: tobject); + procedure updatewidgetstate(const awidget: twidget); + procedure assign(source: tpersistent); override; + property visible: boolean read getvisible write setvisible default true; + property enabled: boolean read getenabled write setenabled default true; + property left: boolean read getleft write setleft default false; + published + property width: integer read fbuttonwidth write setbuttonwidth default 0; + property color: colorty read finfo.color write setcolor default cl_default; + property colorglyph: colorty read finfo.ca.colorglyph + write setcolorglyph default cl_default; + //cl_default maps to cl_glyph + property face: tface read getface write setface; + property frame: tframe read getframe write setframe; + property imagelist: timagelist read finfo.ca.imagelist write setimagelist; + property imagenr: imagenrty read finfo.ca.imagenr write setimagenr + default -1; + property imagenrdisabled: imagenrty read finfo.imagenrdisabled + write setimagenrdisabled default -2; //grayed + property options: framebuttonoptionsty read foptions write setoptions + default []; + property shortcut: shortcutty read fshortcut write fshortcut + default ord(key_none) ; + property action: taction read faction write setaction; + property onexecute: notifyeventty read fonexecute write fonexecute; + //executed after action execute + end; + + tstockglyphframebutton = class(tframebutton) + private + function isimageliststored: boolean; + procedure setimagelist(const Value: timagelist); + public + constructor create(aowner: tobject); override; + published + property imagelist read finfo.ca.imagelist write setimagelist + stored isimageliststored; + end; + + framebuttonclassty = class of tframebutton; + + tframebuttons = class(townedeventpersistentarrayprop) + private + function getitems1(const index: integer): tframebutton; + protected + procedure dosizechanged; override; + procedure checkcount(var acount: integer); override; + procedure updatestate; + public + constructor create(const aowner: tcustombuttonsframe; + const buttonclass: framebuttonclassty); + class function getitemclasstype: persistentclassty; override; + procedure updatewidgetstate; + function wantmouseevent(const apos: pointty): boolean; + procedure dokeydown(var info: keyeventinfoty); + public + property items[const index: integer]: tframebutton read getitems1; default; + procedure checktemplate(const sender: tobject); + end; + + tcustombuttonsframe = class(teditframe) + private + fbuttons: tframebuttons; + procedure setbuttons(const Value: tframebuttons); + protected + factivebutton: integer; + fbuttonintf: ibutton; + procedure getpaintframe(var aframe: framety); override; + function getbuttonclass: framebuttonclassty; virtual; + procedure updatestate; override; + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) override; + procedure dokeydown(var info: keyeventinfoty) override; + public + constructor create(const aintf: icaptionframe; const buttonintf: ibutton); + reintroduce; virtual; + destructor destroy; override; + procedure checktemplate(const sender: tobject); override; + function buttonframe: framety; + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure updatewidgetstate; override; + procedure mouseevent(var info: mouseeventinfoty); + procedure initgridframe; override; + property buttons: tframebuttons read fbuttons write setbuttons; + end; + + tbuttonsframe = class(tcustombuttonsframe) + published + property buttons; + end; + + tcustombuttonframe = class(tcustombuttonsframe) //has at least one button + private + protected + procedure setactivebutton(avalue: integer); + function getbutton: tframebutton; + procedure setbutton(const avalue: tframebutton); + public + constructor create(const aintf: icaptionframe; const buttonintf: ibutton); + override; + property activebutton: integer read factivebutton write setactivebutton + default 0; + property button: tframebutton read getbutton write setbutton; + end; + + tbuttonframe = class(tcustombuttonframe) + end; + + tmultibuttonframe = class(tcustombuttonframe) + published + property activebutton; + property buttons; + end; + + tcustomedit = class; + texteditedeventty = procedure(const sender: tcustomedit; + var atext: msestring) of object; + + emptyoptionty = (eo_defaulttext, //use text of tfacecontroller + eo_showfocused, //show empty_text if focused + eo_nocolorfocused); //do not show empty_color if focused + emptyoptionsty = set of emptyoptionty; + + tcustomedit = class(tpublishedwidget,iedit) + private + fonchange: notifyeventty; + fontextedited: texteditedeventty; + foncopytoclipboard: updatestringeventty; + fonpastefromclipboard: updatestringeventty; + fcursorreadonly: cursorshapety; + fonpaintimage: painteventty; + fempty_text: msestring; + fempty_textflags: textflagsty; + fempty_textcolor: colorty; + fempty_textcolorbackground: colorty; + fempty_fontstyle: fontstylesty; + fempty_color: colorty; + fempty_options: emptyoptionsty; + function getmaxlength: integer; + function getpasswordchar: msechar; + procedure setpasswordchar(const Value: msechar); + function getoldtext: msestring; + procedure settextflags(const value: textflagsty); + procedure settextflagsactive(const value: textflagsty); + function getcaretwidth: integer; + procedure setcaretwidth(const Value: integer); + procedure setcursorreadonly(const avalue: cursorshapety); + function getoptionsedit1: optionsedit1ty; + procedure setempty_text(const avalue: msestring); + procedure setempty_textflags(const avalue: textflagsty); + procedure setempty_textcolor(const avalue: colorty); + procedure setempty_textcolorbackground(const avalue: colorty); + procedure setempty_fontstyle(const avalue: fontstylesty); + procedure setempty_color(const avalue: colorty); + protected + ftextflags: textflagsty; + ftextflagsactive: textflagsty; + feditor: tinplaceedit; + foptionsedit: optionseditty; + fstate: dataeditstatesty; + function gettext: msestring virtual; + procedure settext(const avalue: msestring) virtual; +// procedure setcurrenttext(const avalue: msestring); + function getreadonly: boolean; virtual; + procedure setreadonly(const avalue: boolean); virtual; + procedure setmaxlength(const avalue: integer); + procedure updatetextflags; virtual; + function getedittext: msestring; virtual; + procedure updateedittext(const force: boolean); + procedure updateemptytext(); + procedure updateflagtext(var avalue: msestring); + function geteditor: tinplaceedit; + function geteditfont: tfont; virtual; + function getinnerframe: framety; virtual; + function geteditframe: framety; virtual; + procedure gettextrects(out outer: rectty; out inner: rectty); + procedure setupeditor; virtual; + function getformat(): formatinfoarty virtual; + procedure internalcreateframe; override; + procedure clientrectchanged; override; + procedure getautopaintsize(var asize: sizety); override; + procedure fontchanged; override; + procedure enabledchanged; override; + procedure dragstarted; override; + function navigrect: rectty; override; + + class function classskininfo: skininfoty; override; + + //interface to inplaceedit + procedure dokeydown(var info: keyeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure dofocus; override; + procedure dodefocus; override; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure dopaintbackground(const canvas: tcanvas); override; + procedure paintimage(const canvas: tcanvas); virtual; + procedure painttext(const canvas: tcanvas); virtual; + function needsfocuspaint: boolean; override; +// procedure doafterpaint(const canvas: tcanvas); override; + procedure rootchanged(const aflags: rootchangeflagsty); override; + function gettextcliprect(): rectty; virtual; + procedure showhint(const aid: int32; var info: hintinfoty); override; + + procedure dochange; virtual; + procedure formatchanged; virtual; + procedure internaltextedited(const aevent: texteditedeventty); + procedure dotextedited; virtual; + procedure emptychanged; + procedure readpwchar(reader: treader); + procedure writepwchar(writer: twriter); + procedure defineproperties(filer: tfiler); override; + function verticalfontheightdelta: boolean; override; + procedure setoptionsedit1(const avalue: optionsedit1ty); virtual; + //iassistiveclient + function getassistivecaretindex(): int32 override; + function getassistiveflags(): assistiveflagsty override; + //iedit + function getoptionsedit: optionseditty; virtual; + function hasselection: boolean; virtual; + function cangridcopy: boolean; virtual; + procedure setoptionsedit(const avalue: optionseditty); virtual; + procedure updatereadonlystate; virtual; + procedure editnotification(var info: editnotificationinfoty); virtual; + procedure updatecopytoclipboard(var atext: msestring); virtual; + procedure updatepastefromclipboard(var atext: msestring); virtual; + function locatecount: integer; virtual; //number of locate values + function locatecurrentindex: integer; virtual; //index of current row + procedure locatesetcurrentindex(const aindex: integer); virtual; + function getkeystring(const aindex: integer): msestring; virtual; //locate text + function getedited: boolean; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure initnewcomponent(const ascale: real); override; + procedure changed; + procedure initfocus; + procedure synctofontheight; override; + function actualcursor(const apos: pointty): cursorshapety; override; + + property editor: tinplaceedit read feditor; + property readonly: boolean read getreadonly write setreadonly; + property optionsedit: optionseditty read getoptionsedit write setoptionsedit + default defaultoptionsedit; + property optionsedit1: optionsedit1ty read getoptionsedit1 + write setoptionsedit1 default defaultoptionsedit1; + property passwordchar: msechar read getpasswordchar + write setpasswordchar stored false default #0; + //FPC and Delphi bug: widechars are not streamed + property cursorreadonly: cursorshapety read fcursorreadonly + write setcursorreadonly default cr_default; + property maxlength: integer read getmaxlength write setmaxlength + default -1; + property text: msestring read gettext write settext; + property oldtext: msestring read getoldtext; + property textflags: textflagsty read ftextflags write settextflags + default defaulttextflags; + property textflagsactive: textflagsty read ftextflagsactive + write settextflagsactive default defaulttextflagsactive; + property font: twidgetfont read getfont write setfont stored isfontstored; + property caretwidth: integer read getcaretwidth write setcaretwidth + default defaultcaretwidth; + + property empty_options: emptyoptionsty read fempty_options + write fempty_options default []; + property empty_color: colorty read fempty_color write setempty_color + default cl_none; + property empty_font: twidgetfontempty read getfontempty write setfontempty + stored isfontemptystored; + property empty_fontstyle: fontstylesty read fempty_fontstyle + write setempty_fontstyle default []; + property empty_textflags: textflagsty read fempty_textflags + write setempty_textflags default defaulttextflagsempty; + property empty_text: msestring read fempty_text write setempty_text; + property empty_textcolor: colorty read fempty_textcolor + write setempty_textcolor default cl_none; + property empty_textcolorbackground: colorty read fempty_textcolorbackground + write setempty_textcolorbackground default cl_none; + + property onchange: notifyeventty read fonchange write fonchange; + property ontextedited: texteditedeventty read fontextedited + write fontextedited; + property oncopytoclipboard: updatestringeventty read foncopytoclipboard + write foncopytoclipboard; + property onpastefromclipboard: updatestringeventty + read fonpastefromclipboard write fonpastefromclipboard; + property onpaintimage: painteventty read fonpaintimage write fonpaintimage; + published + property optionswidget1 default defaulteditwidgetoptions1; //first! + property optionswidget default defaulteditwidgetoptions; //first! + property bounds_cx default defaulteditwidgetwidth; + property bounds_cy default defaulteditwidgetheight; + end; + + tedit = class(tcustomedit,istatfile) + private + ftimer: tsimpletimer; + fontextediteddelayed: texteditedeventty; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: integer; + procedure dotimer(const sender: tobject); virtual; + function getdelay: integer; + procedure setdelay(const avalue: integer); + procedure setstatfile(const avalue: tstatfile); + protected + function gettext: msestring override; + procedure settext(const avalue: msestring) override; + procedure dotextedited; override; + procedure editnotification(var info: editnotificationinfoty); override; + procedure loaded() override; + procedure dofocus() override; + procedure dodefocus() override; + + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property delay: integer read getdelay write setdelay default 0; //ms + property ontextediteddelayed: texteditedeventty read fontextediteddelayed + write fontextediteddelayed; + property optionsedit1; //before optionsedit! + property optionsedit; + property font; + property textflags; + property textflagsactive; + property passwordchar; + + property empty_options; + property empty_color; + property empty_font; + property empty_fontstyle; + property empty_textflags; + property empty_text; + property empty_textcolor; + property empty_textcolorbackground; + + property maxlength; + property caretwidth; + property cursorreadonly; + property text; + property onchange; + property ontextedited; + property onkeydown; + property onkeyup; + property oncopytoclipboard; + property onpastefromclipboard; + end; + +implementation +uses + sysutils,msebits,msedataedits,msestockobjects,mseact, + mseassistiveserver; + +type + twidget1 = class(twidget); + tdatacol1 = class(tdatacol); +// tcustombuttonframe1 = class(tcustombuttonframe); + tinplaceedit1 = class(tinplaceedit); + +{ teditframe } + +constructor teditframe.create(const aintf: icaptionframe); +begin + inherited; + fi.levelo:= -2; + inflateframe1(fi.innerframe,1); + internalupdatestate; +end; + +function teditframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + + +{ tscrolleditframe } + +constructor tscrolleditframe.create(const aintf: iscrollframe; + const scrollintf: iscrollbar); +begin + inherited; + fi.levelo:= -2; + inflateframe1(fi.innerframe,1); + internalupdatestate; +end; + +function tscrolleditframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + +{ tscrollboxeditframe } + +constructor tscrollboxeditframe.create(const aintf: iscrollframe; + const owner: twidget); +begin + inherited; + fi.levelo:= -2; + inflateframe1(fi.innerframe,1); + internalupdatestate; +end; + +function tscrollboxeditframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + +{ tframebutton } + +constructor tframebutton.create(aowner: tobject); +begin + finfo.color:= cl_default; + finfo.ca.colorglyph:= cl_default; + finfo.ca.imagenr:= -1; + finfo.imagenrdisabled:= -2; + fshortcut:= ord(key_none); + include(finfo.state,shs_widgetorg); + inherited; +end; + +destructor tframebutton.destroy; +begin + inherited; + action:= nil; //remove link + finfo.face.free; + fframe.free; +end; + +procedure tframebutton.changed; +begin + if not (csloading in tcustombuttonframe(fowner). + fintf.getwidget.componentstate) then begin + tcustombuttonframe(fowner).updatestate; + end; +end; + +procedure tframebutton.optionstostate(); +begin + updatebit(longword(finfo.state),ord(shs_invisible), + (fbo_invisible in foptions)); + updatebit(longword(finfo.state),ord(shs_disabled),fbo_disabled in foptions); + updatebit(longword(finfo.state),ord(shs_flat),fbo_flat in foptions); + updatebit(longword(finfo.state),ord(shs_noanimation),fbo_noanim in foptions); + updatebit(longword(finfo.state),ord(shs_nomouseanimation), + fbo_nomouseanim in foptions); + updatebit(longword(finfo.state),ord(shs_noclickanimation), + fbo_noclickanim in foptions); + updatebit(longword(finfo.state),ord(shs_nofocusanimation), + fbo_nofocusanim in foptions); +end; + +procedure tframebutton.setoptions(const Value: framebuttonoptionsty); +var + statebefore: shapestatesty; + optionsbefore: framebuttonoptionsty; +begin + statebefore:= finfo.state; + optionsbefore:= foptions; + card32(foptions):= setsinglebit(card32(Value),card32(foptions), + card32([fbo_disabled,fbo_enabled]));; + optionstostate(); + if (statebefore <> finfo.state) or + ((optionsbefore >< foptions) * + [fbo_left,fbo_invisible,fbo_inactiveinvisible] <> []) then begin + changed(); + end; +end; + +function tframebutton.getleft: boolean; +begin + result:= fbo_left in foptions; +end; + +procedure tframebutton.setleft(const Value: boolean); +begin + if value then begin + setoptions(foptions + [fbo_left]); + end + else begin + setoptions(foptions - [fbo_left]); + end; +end; + +function tframebutton.getvisible: boolean; +begin + result:= not (fbo_invisible in foptions); +end; + +procedure tframebutton.setvisible(const Value: boolean); +begin + if value then begin + setoptions(foptions - [fbo_invisible]); + end + else begin + setoptions(foptions + [fbo_invisible]); + end; +end; + +function tframebutton.getenabled: boolean; +begin + result:= not (fbo_disabled in foptions); +end; + +procedure tframebutton.setenabled(const Value: boolean); +begin + if value then begin + setoptions(foptions - [fbo_disabled]); + end + else begin + setoptions(foptions + [fbo_disabled]); + end; +end; + +procedure tframebutton.setbuttonwidth(const Value: integer); +begin + if fbuttonwidth <> value then begin + fbuttonwidth := Value; + changed; + end; +end; + +procedure tframebutton.setcolor(const avalue: colorty); +begin + if finfo.color <> avalue then begin + finfo.color := avalue; + changed; + end; +end; + +procedure tframebutton.setcolorglyph(const avalue: colorty); +begin + if finfo.ca.colorglyph <> avalue then begin + finfo.ca.colorglyph := avalue; + changed; + end; +end; + +procedure tframebutton.doexec(); +begin + if faction <> nil then begin + faction.execute(); + end; + if assigned(fonexecute) then begin + fonexecute(self); + end; +end; //doexe + +procedure tframebutton.mouseevent(var info: mouseeventinfoty; + const intf: iframe; const buttonintf: ibutton; const index: integer); + +var + bo1,bo2: boolean; + action1: buttonactionty; +begin + bo2:= false; + with finfo do begin + bo1:= shs_clicked in state; + if updatemouseshapestate(finfo,info,nil,nil) then begin + invalidate; + end; + if shs_clicked in state then begin + if not bo1 then begin + action1:= ba_buttonpress; + buttonintf.buttonaction(action1,index); + end; + end + else begin + if bo1 then begin + action1:= ba_buttonrelease; + buttonintf.buttonaction(action1,index); + end; + end; + if bo1 and (info.eventkind = ek_buttonrelease) then begin + action1:= ba_click; + buttonintf.buttonaction(action1,index); + if action1 = ba_click then begin + doexec(); + bo2:= true; + end; + end; + end; + if (fbo_executeonclientdblclick in foptions) and not bo2 and + (finfo.state * [shs_disabled,shs_invisible] = []) then begin + with getwidget() do begin + if iswidgetdblclicked(info) then begin + doexec(); + end; + end; + end; +end; + +procedure tframebutton.setimagelist(const Value: timagelist); +begin + setlinkedcomponent(iobjectlink(self),value,tmsecomponent(finfo.ca.imagelist)); + changed; +end; + +procedure tframebutton.setimagenr(const avalue: imagenrty); +begin + if finfo.ca.imagenr <> avalue then begin + finfo.ca.imagenr := avalue; + changed; + end; +end; + +procedure tframebutton.setimagenrdisabled(const avalue: imagenrty); +begin + if finfo.imagenrdisabled <> avalue then begin + finfo.imagenrdisabled := avalue; + changed; + end; +end; + + +procedure tframebutton.createface; +begin + if finfo.face = nil then begin + finfo.face:= tface.create(iface(tcustombuttonframe(fowner).fintf.getwidget)); + end; +end; + +procedure tframebutton.createframe; +begin + if fframe = nil then begin + tframe.create(iframe(self)); + end; +end; + +function tframebutton.getface: tface; +begin + tcustombuttonframe(fowner).fintf.getwidget.getoptionalobject(finfo.face, + {$ifdef FPC}@{$endif}createface); + result:= tface(finfo.face); +end; + +procedure tframebutton.setface(const avalue: tface); +begin + tcustombuttonframe(fowner).fintf.getwidget.setoptionalobject(avalue,finfo.face, + {$ifdef FPC}@{$endif}createface); + tcustombuttonframe(fowner).fintf.getwidget.invalidate; +end; + +function tframebutton.getframe: tframe; +begin + tcustombuttonframe(fowner).fintf.getwidget.getoptionalobject(fframe, + {$ifdef FPC}@{$endif}createframe); + result:= fframe; +end; + +procedure tframebutton.setframe(const avalue: tframe); +begin + tcustombuttonframe(fowner).fintf.getwidget.setoptionalobject(avalue,fframe, + {$ifdef FPC}@{$endif}createframe); +// tcustombuttonframe(fowner).fintf.getwidget.invalidate; + changed(); +end; + +procedure tframebutton.updatewidgetstate(const awidget: twidget); +//var +// invisiblebefore: boolean; +begin +// invisiblebefore:= ss_invisible in finfo.state; + updatewidgetshapestate(finfo,awidget,(fbo_disabled in foptions) or + freadonly and not (fbo_enabled in foptions), + {fbo_invisible in foptions,}fframe); + if (fbo_inactiveinvisible in foptions) and + (awidget.componentstate * [csdesigning,csdestroying] = []) then begin + if awidget.active xor not(shs_invisible in finfo.state) then begin + togglebit1(longword(finfo.state),ord(shs_invisible)); + tcustombuttonframe(fowner).internalupdatestate(); + end; + end; +// updatebit(longword(finfo.state),ord(ss_invisible),invisiblebefore); +end; + +procedure tframebutton.assign(source: tpersistent); +begin + if source is tframebutton then begin + with tframebutton(source) do begin + self.setoptions(foptions); + self.left:= left; + self.color:= color; + self.imagelist:= imagelist; + self.imagenr:= imagenr; + self.onexecute:= onexecute; + self.frame:= frame; + self.face:= face; + end; + end; +end; + +procedure tframebutton.checktemplate(const sender: tobject); +begin + if finfo.face <> nil then begin + finfo.face.checktemplate(sender); + end; + if fframe <> nil then begin + fframe.checktemplate(sender); + end; +end; + +procedure tframebutton.setframeinstance(instance: tcustomframe); +begin + fframe:= tframe(instance); +end; + +procedure tframebutton.setstaticframe(value: boolean); +begin + //dummy +end; + +function tframebutton.getstaticframe: boolean; +begin + result:= false; +end; + +function tframebutton.getwidgetrect: rectty; +begin + result:= nullrect; +end; + +function tframebutton.getcomponentstate: tcomponentstate; +begin + result:= tcustombuttonframe(fowner).fintf.getwidget.componentstate; +end; + +function tframebutton.getmsecomponentstate: msecomponentstatesty; +begin + result:= tcustombuttonframe(fowner).fintf.getwidget.msecomponentstate; +end; + +procedure tframebutton.scrollwidgets(const dist: pointty); +begin + //dummy +end; + +procedure tframebutton.clientrectchanged; +begin + changed; +end; + +procedure tframebutton.invalidate; +begin + tcustombuttonframe(fowner).fintf.getwidget.invalidaterect( + fframerect,org_widget); +end; + +procedure tframebutton.invalidatewidget; +begin + invalidate; +end; + +procedure tframebutton.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + invalidate; +end; + +function tframebutton.getwidget: twidget; +begin + result:= tcustombuttonframe(fowner).fintf.getwidget +end; + +function tframebutton.getframestateflags: framestateflagsty; +begin + with getwidget,finfo do begin + result:= combineframestateflags(shs_disabled in state,focused,active, + shs_mouse in state,shs_clicked in state); + end; +end; + +function tframebutton.getimagelist: timagelist; +begin + result:= finfo.ca.imagelist; +end; + +procedure tframebutton.setaction(const avalue: taction); +begin + twidget1(iframe(tcustombuttonsframe(fowner).fintf).getwidget). + setlinkedvar(avalue,tmsecomponent(faction)); +end; + +{ tstockglyphframebutton} + +constructor tstockglyphframebutton.create(aowner: tobject); +begin + inherited; + finfo.ca.imagelist:= stockobjects.glyphs; +end; + +function tstockglyphframebutton.isimageliststored: boolean; +begin + result:= finfo.ca.imagelist <> stockobjects.glyphs; +end; + +procedure tstockglyphframebutton.setimagelist(const Value: timagelist); +begin + if value = nil then begin + inherited setimagelist(stockobjects.glyphs); + end + else begin + inherited setimagelist(value); + end; +end; + +{ tframebuttons } + +constructor tframebuttons.create(const aowner: tcustombuttonsframe; + const buttonclass: framebuttonclassty); +begin + inherited create(aowner,buttonclass{tframebutton}); +end; + +class function tframebuttons.getitemclasstype: persistentclassty; +begin + result:= tframebutton; +end; + +procedure tframebuttons.dosizechanged; +begin + if not (csloading in + tcustombuttonframe(fowner).fintf.getwidget.componentstate) then begin + tcustombuttonframe(fowner).updatestate; + end; + inherited; +end; + +function tframebuttons.getitems1(const index: integer): tframebutton; +begin + result:= tframebutton(inherited getitems(index)); +end; + +procedure tframebuttons.updatewidgetstate; +var + int1: integer; + widget1: twidget; +begin + widget1:= tcustombuttonsframe(fowner).fintf.getwidget; + for int1:= 0 to high(fitems) do begin +// updatewidgetshapestate(tframebutton(fitems[int1]).finfo,widget1); + tframebutton(fitems[int1]).updatewidgetstate(widget1); + end; +end; + +function tframebuttons.wantmouseevent(const apos: pointty): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(fitems) do begin + with tframebutton(fitems[int1]) do begin + if not (fbo_invisible in foptions) and pointinrect(apos,fframerect) then begin + result:= true; + break; + end; + end; + end; +end; + +procedure tframebuttons.dokeydown(var info: keyeventinfoty); +var + i1: int32; +begin + for i1:= 0 to high(fitems) do begin + with tframebutton(fitems[i1]) do begin + if (finfo.state * [shs_disabled,shs_invisible] = []) and + checkshortcutcode(fshortcut,info) then begin + include(info.eventstate,es_processed); + doexec(); + break; + end; + end; + end; +end; + +procedure tframebuttons.checktemplate(const sender: tobject); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tframebutton(fitems[int1]).checktemplate(sender); + end; +end; + +procedure tframebuttons.updatestate; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tframebutton(fitems[int1]) do begin + frameskinoptionstoshapestate(fframe,finfo); + finfo.state:= finfo.state - [shs_showfocusrect,shs_showdefaultrect]; + if (fframe = nil) then begin + optionstostate(); //restore flat and anim settings + end; + end; + end; + updatewidgetstate(); //restore disabled state +end; + +procedure tframebuttons.checkcount(var acount: integer); +begin + inherited; + if acount <= tcustombuttonsframe(fowner).factivebutton then begin + acount:= tcustombuttonsframe(fowner).factivebutton+1; + end; +end; + +{ tcustombuttonsframe } + +constructor tcustombuttonsframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + factivebutton:= -1; //none + fbuttons:= tframebuttons.create(self,getbuttonclass); + fbuttonintf:= buttonintf; + aintf.setstaticframe(true); + inherited create(aintf); +end; + +destructor tcustombuttonsframe.destroy; +begin + inherited; + fbuttons.free; +end; + +function tcustombuttonsframe.getbuttonclass: framebuttonclassty; +begin + result:= tstockglyphframebutton; +end; + +function tcustombuttonsframe.buttonframe: framety; +var + int1: integer; +begin + result:= nullframe; + for int1:= 0 to fbuttons.count - 1 do begin + with fbuttons[int1],finfo do begin + if not (shs_invisible in state) then begin + if fbo_left in foptions then begin + inc(result.left,fframerect.cx); + end + else begin + inc(result.right,fframerect.cx); + end; + end; + end; + end; +end; + +procedure tcustombuttonsframe.getpaintframe(var aframe: framety); +var + int1: integer; +begin + inherited; + for int1:= 0 to fbuttons.count-1 do begin + with fbuttons[int1],finfo,fframerect do begin + if not (shs_invisible in state) then begin + cy:= fintf.getwidgetrect.cy - frameframedim.cy; + if fbuttonwidth = 0 then begin + cx:= cy; + end + else begin + cx:= fbuttonwidth; + if cx < 0 then begin + cx:= 0; + end; + end; + y:= fouterframe.top + fwidth.top; + if fbo_left in foptions then begin + x:= fouterframe.left + fwidth.left + aframe.left; + inc(aframe.left,cx); + end + else begin + x:= fintf.getwidgetrect.cx - + (fouterframe.right + fwidth.right + cx + aframe.right); + inc(aframe.right,cx); + end; + if (fframe <> nil) and + not (fso_noinnerrect in fframe.optionsskin) then begin + finfo.ca.dim:= deflaterect(fframerect,fframe.paintframe); + deflaterect1(finfo.ca.dim,fframe.frameo); +// finfo.ca.dim:= deflaterect(fframerect,fframe.innerframe); + end + else begin + finfo.ca.dim:= fframerect; + end; + end; + end; + end; +end; + +procedure tcustombuttonsframe.initgridframe; +var + int1: integer; +begin + inherited; + for int1:= 0 to fbuttons.count - 1 do begin + fbuttons.items[int1].finfo.color:= cl_background; + end; +end; + +procedure tcustombuttonsframe.mouseevent(var info: mouseeventinfoty); +var + int1: integer; +begin + if not (csdesigning in fintf.getcomponentstate) then begin + for int1:= 0 to fbuttons.count-1 do begin + fbuttons[int1].mouseevent(info,fintf,fbuttonintf,int1); + end; + end; +end; + +procedure tcustombuttonsframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); +var + int1: integer; + color1,color2: colorty; +begin + color2:= cl_none; + for int1:= 0 to fbuttons.count-1 do begin + with fbuttons[int1] do begin + if not (shs_invisible in finfo.state) + {(fbo_invisible in foptions)} then begin + if fframe <> nil then begin + canvas.save; + fframe.paintbackground(canvas,fframerect,true,false); + end; + if (color = cl_default) or (color = cl_parent) then begin + if color2 = cl_none then begin + color2:= fintf.getwidget.parentcolor; + end; + color1:= finfo.color; + finfo.color:= color2; + drawtoolbutton(canvas,finfo); + finfo.color:= color1; + end + else begin + drawtoolbutton(canvas,finfo); + end; + if fframe <> nil then begin + canvas.restore; + fframe.paintoverlay(canvas,fframerect); + end; + end; + end; + end; + inherited; +end; + +procedure tcustombuttonsframe.dokeydown(var info: keyeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + fbuttons.dokeydown(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +procedure tcustombuttonsframe.setbuttons(const Value: tframebuttons); +begin + fbuttons.Assign(Value); +end; + +procedure tcustombuttonsframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + if fbuttons.wantmouseevent(info.pos) then begin + with twidget1(sender) do begin + fwidgetstate:= fwidgetstate + [ws_wantmousebutton,ws_wantmousemove, + ws_wantmousefocus]; + end; + end; +end; + +procedure tcustombuttonsframe.updatewidgetstate; +begin + inherited; + fbuttons.updatewidgetstate; +end; + +procedure tcustombuttonsframe.checktemplate(const sender: tobject); +begin + inherited; + fbuttons.checktemplate(sender); +end; + +procedure tcustombuttonsframe.updatestate; +begin + fbuttons.updatestate; //set skin options + inherited; +end; + +{ tcutombuttonframe } + +constructor tcustombuttonframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + inherited; + buttons.count:= 1; + setactivebutton(0); +end; + +procedure tcustombuttonframe.setactivebutton(avalue: integer); +begin + if avalue < 0 then begin + avalue:= 0; + end; + if avalue >= fbuttons.count then begin + avalue:= fbuttons.count-1; + end; + factivebutton:= avalue; +end; + +function tcustombuttonframe.getbutton: tframebutton; +begin + result:= buttons[factivebutton]; +end; + +procedure tcustombuttonframe.setbutton(const avalue: tframebutton); +begin + buttons[factivebutton].assign(avalue); +end; + +{ tcustomedit } + +constructor tcustomedit.create(aowner: tcomponent); +begin + inherited; +// cursor:= cr_ibeam; + fcursorreadonly:= cr_default; + foptionsedit:= defaultoptionsedit; + fwidgetrect.cx:= defaulteditwidgetwidth; + fwidgetrect.cy:= defaulteditwidgetheight; + if feditor = nil then begin + feditor:= tinplaceedit.create(self,iedit(self),true); + end; + maxlength:= -1; + foptionswidget:= defaulteditwidgetoptions; + foptionswidget1:= defaulteditwidgetoptions1; + ftextflags:= defaulttextflags; + ftextflagsactive:= defaulttextflagsactive; + fempty_textflags:= defaulttextflagsempty; + fempty_textcolor:= cl_none; + fempty_textcolorbackground:= cl_none; + fempty_color:= cl_none; + updatetextflags; +end; + +destructor tcustomedit.destroy; +begin + inherited; + feditor.free; +end; + +procedure tcustomedit.doactivate; +begin + inherited; + feditor.doactivate; + if (oe_focusrectonreadonly in foptionsedit) and + (oe_readonly in optionsedit) and focused then begin + invalidate; + end; +end; + +procedure tcustomedit.dodeactivate; +begin + inherited; + feditor.dodeactivate; + if (oe_focusrectonreadonly in foptionsedit) and + (oe_readonly in optionsedit) and focused then begin + invalidate; + end; +end; + +procedure tcustomedit.dofocus; +begin + inherited; + initfocus; +end; + +procedure tcustomedit.dodefocus; +begin + if not (csdestroying in componentstate) and (fwindow <> nil) and + fwindow.haswinid + then begin + feditor.dodefocus; + end; + inherited; +end; + +procedure tcustomedit.dokeydown(var info: keyeventinfoty); +begin + doonkeydown(info); + if not (es_processed in info.eventstate) then begin + if not (es_child in info.eventstate) then begin + feditor.dokeydown(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; +{ +procedure tcustomedit.dokeyup(var info: keyeventinfoty); +begin + if canevent(tmethod(fonkeyup)) then begin + fonkeyup(self,info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +} +procedure tcustomedit.clientmouseevent(var info: mouseeventinfoty); +begin + feditor.mouseevent(info); + inherited; +end; + +procedure tcustomedit.painttext(const canvas: tcanvas); +begin + feditor.dopaint(canvas); +end; + +procedure tcustomedit.dopaintforeground(const canvas: tcanvas); +begin + inherited; + paintimage(canvas); + painttext(canvas); +end; + +procedure tcustomedit.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if (fempty_color <> cl_none) and + (fstate * [des_emptytext,des_grayed] = [des_emptytext]) and + (not (eo_nocolorfocused in fempty_options) or not focused)then begin + canvas.fillrect(paintclientrect,fempty_color); + end; +end; + +function tcustomedit.needsfocuspaint: boolean; +begin + result:= inherited needsfocuspaint or + ([oe_focusrectonreadonly,oe_readonly] * optionsedit = + [oe_focusrectonreadonly,oe_readonly]); +end; +{ +procedure tcustomedit.doafterpaint(const canvas: tcanvas); +begin + if ([oe_focusrectonreadonly,oe_readonly] * optionsedit = + [oe_focusrectonreadonly,oe_readonly]) and focused and active then begin + drawfocusrect(canvas,paintrect); + end; + inherited; +end; +} +procedure tcustomedit.editnotification(var info: editnotificationinfoty); +begin + case info.action of + ea_textchanged: begin + dochange; + end; + ea_textedited,ea_undone: begin + dotextedited; + end; + ea_resetemptytext: begin + if des_emptytext in fstate then begin + exclude(fstate,des_emptytext); + updateemptytext(); + end; + end; + end; +end; + +procedure tcustomedit.updatecopytoclipboard(var atext: msestring); +begin + if canevent(tmethod(foncopytoclipboard)) then begin + foncopytoclipboard(self,atext); + end; +end; + +procedure tcustomedit.updatepastefromclipboard(var atext: msestring); +begin + if canevent(tmethod(fonpastefromclipboard)) then begin + fonpastefromclipboard(self,atext); + end; +end; + +function tcustomedit.locatecount: integer; //number of locate values +begin + result:= 0; +end; + +function tcustomedit.locatecurrentindex: integer; //index of current row +begin + result:= -1; +end; + +procedure tcustomedit.locatesetcurrentindex(const aindex: integer); +begin + //dummy +end; + +function tcustomedit.getkeystring(const aindex: integer): msestring; //locate text +begin + result:= ''; +end; + +class function tcustomedit.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_edit; +end; + +function tcustomedit.getoptionsedit: optionseditty; +begin + result:= foptionsedit; +end; + +function tcustomedit.getreadonly: boolean; +begin + result:= oe_readonly in foptionsedit; +end; + +procedure tcustomedit.setreadonly(const avalue: boolean); +begin + if avalue <> (oe_readonly in foptionsedit) then begin + if avalue then begin + optionsedit:= optionsedit + [oe_readonly]; + end + else begin + optionsedit:= optionsedit - [oe_readonly]; + end; + setupeditor; + end; +end; + +procedure tcustomedit.setoptionsedit(const avalue: optionseditty); +var + opt1: optionsedit1ty; + opt: optionseditty; +begin + if foptionsedit <> avalue then begin + opt1:= feditor.optionsedit1; + transferoptionsedit(self,avalue,opt,opt1); + feditor.optionsedit1:= opt1; + foptionsedit:= optionseditty(setsinglebit(card32(opt),card32(foptionsedit), + card32([oe_homeonenter,oe_endonenter]))); + updatereadonlystate; + end; +end; + +function tcustomedit.getoptionsedit1: optionsedit1ty; +begin + result:= feditor.optionsedit1; +end; + +procedure tcustomedit.setempty_text(const avalue: msestring); +begin + fempty_text:= avalue; + formatchanged; +end; + +procedure tcustomedit.setempty_textflags(const avalue: textflagsty); +begin + if avalue <> fempty_textflags then begin + fempty_textflags:= checktextflags(fempty_textflags,avalue); + emptychanged; + end; +end; + +procedure tcustomedit.setempty_textcolor(const avalue: colorty); +begin + if avalue <> fempty_textcolor then begin + fempty_textcolor:= avalue; + emptychanged; + end; +end; + +procedure tcustomedit.setempty_textcolorbackground(const avalue: colorty); +begin + if avalue <> fempty_textcolorbackground then begin + fempty_textcolorbackground:= avalue; + emptychanged; + end; +end; + +procedure tcustomedit.setempty_fontstyle(const avalue: fontstylesty); +begin + if avalue <> fempty_fontstyle then begin + fempty_fontstyle:= avalue; + emptychanged; + end; +end; + +procedure tcustomedit.setempty_color(const avalue: colorty); +begin + if avalue <> fempty_color then begin + fempty_color:= avalue; + invalidate; + end; +end; + +procedure tcustomedit.setoptionsedit1(const avalue: optionsedit1ty); +var + optbefore: optionsedit1ty; +begin + optbefore:= feditor.optionsedit1; + feditor.optionsedit1:= avalue; + if oe1_readonlydialog in optionsedit1ty( + {$ifdef FPC}longword{$else}byte{$endif}(avalue) xor + {$ifdef FPC}longword{$else}byte{$endif}(optbefore)) then begin + updatereadonlystate; + end; +end; + +function tcustomedit.getassistivecaretindex(): int32; +begin + result:= feditor.curindex; +end; + +function tcustomedit.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags + [asf_textedit]; + if not feditor.canedit then begin + include(result,asf_readonly); + end; +end; + +function tcustomedit.geteditfont: tfont; +begin + result:= getfont1; +end; + +function tcustomedit.getinnerframe: framety; +begin + result:= minimalframe; +end; + +function tcustomedit.geteditframe: framety; +begin + result:= nullframe; +end; + +procedure tcustomedit.gettextrects(out outer: rectty; out inner: rectty); +var + fra1: framety; +begin + fra1:= geteditframe; + if fframe = nil then begin + outer:= deflaterect(clientrect,fra1); + inner:= deflaterect(outer,getinnerframe); + end + else begin + outer:= deflaterect(clientsizerect,fra1); + inner:= deflaterect(innerclientrect,fra1); + end; +end; + +procedure tcustomedit.setupeditor; +var + outer1,inner1: rectty; +begin + if not (csloading in componentstate) then begin + gettextrects(outer1,inner1); + with feditor do begin + setup(text,curindex,true,inner1,outer1,getformat(),nil,geteditfont); + end; + end; +end; + +function tcustomedit.getformat(): formatinfoarty; +begin + result:= nil; +end; + +{ +procedure tcustomedit.setupeditor; +var + fra1: framety; +begin + if not (csloading in componentstate) then begin + fra1:= geteditframe; + with feditor do begin + if fframe = nil then begin + setup(text,curindex,true, + deflaterect(clientrect,addframe(fra1,getinnerframe)), + deflaterect(clientrect,fra1),nil,nil,geteditfont); + end + else begin + setup(text,curindex,true,deflaterect(innerclientrect,fra1), + deflaterect(makerect(nullpoint,clientsize),fra1),nil,nil,geteditfont); + end; + end; + end; +end; +} +function tcustomedit.verticalfontheightdelta: boolean; +begin + result:= tf_rotate90 in textflags; +end; + +procedure tcustomedit.synctofontheight; +var +// int1: integer; + fram1: framety; +begin + inherited; + fram1:= getinnerframe; + if tf_rotate90 in ftextflags then begin + syncsinglelinefontheight(false,fram1.left + fram1.right); + end + else begin + syncsinglelinefontheight(false,fram1.top + fram1.bottom); + end; +end; + +procedure tcustomedit.clientrectchanged; +begin + inherited; + setupeditor; +end; + +procedure tcustomedit.getautopaintsize(var asize: sizety); +var + fram1: framety; +begin + if fframe = nil then begin + fram1:= getinnerframe; + end + else begin +// fram1:= fframe.innerframe; + fram1:= fframe.framei; + end; + asize:= feditor.textrect.size; + asize.cx:= asize.cx + fram1.left + fram1.right; + asize.cy:= asize.cy + fram1.top + fram1.bottom; + fram1:= geteditframe; + asize.cx:= asize.cx + fram1.left+fram1.right; + asize.cy:= asize.cy + fram1.top+fram1.bottom; +end; + +procedure tcustomedit.fontchanged; +begin + inherited; + setupeditor; + checkautosize(); +end; + +function tcustomedit.getmaxlength: integer; +begin + result:= feditor.maxlength; +end; + +function tcustomedit.getpasswordchar: msechar; +begin + result:= feditor.passwordchar; +end; + +procedure tcustomedit.setmaxlength(const avalue: integer); +begin + feditor.maxlength:= avalue; +end; + +procedure tcustomedit.setpasswordchar(const Value: msechar); +begin + feditor.passwordchar:= value; +end; + +procedure tcustomedit.internalcreateframe; +begin + teditframe.create(iscrollframe(self)); +end; + +function tcustomedit.gettext: msestring; +begin + result:= feditor.text; +end; + +function tcustomedit.getoldtext: msestring; +begin + result:= feditor.oldtext; +end; + +procedure tcustomedit.settext(const avalue: msestring); +begin + feditor.text:= avalue; + if (avalue = '') and (not focused or + (eo_showfocused in fempty_options)) then begin + if not (des_emptytext in fstate) then begin + include(fstate,des_emptytext); + updateemptytext(); + end; + end + else begin + if des_emptytext in fstate then begin + exclude(fstate,des_emptytext); + updateemptytext(); + end; + end; +end; +{ +procedure tcustomedit.setcurrenttext(const avalue: msestring); +begin + feditor.text:= avalue; + if avalue <> '' then begin + exclude(fstate,des_emptytext); + end; +end; +} +function tcustomedit.getedittext: msestring; +begin + result:= text; +end; + +procedure tcustomedit.updateemptytext(); +begin + if des_emptytext in fstate then begin + include(tinplaceedit1(feditor).fstate,ies_emptytext); + feditor.font:= getfontempty1{fempty_font}; + if fempty_textcolor <> cl_none then begin + feditor.fontcolor:= fempty_textcolor; + end; + if fempty_textcolorbackground <> cl_none then begin + feditor.fontcolorbackground:= fempty_textcolorbackground; + end; + if fempty_fontstyle <> [] then begin + feditor.fontstyle:= fempty_fontstyle; + end; + end + else begin + exclude(tinplaceedit1(feditor).fstate,ies_emptytext); + feditor.font:= geteditfont; + feditor.fontcolor:= cl_none; + feditor.fontcolorbackground:= cl_none; + feditor.fontstyle:= []; + end; + updatetextflags(); +end; + +procedure tcustomedit.updateedittext(const force: boolean); +var + mstr1: msestring; + state1: dataeditstatesty; +begin + state1:= fstate; + mstr1:= getedittext(); + if (not(des_isdb in fstate) and (mstr1 = '') or (des_dbnull in fstate)) and + (not focused or (eo_showfocused in fempty_options)) then begin + mstr1:= fempty_text; + include(fstate,des_emptytext); + end + else begin + exclude(fstate,des_emptytext); + end; + feditor.text:= mstr1; + if force or ((des_emptytext in fstate) xor + (des_emptytext in state1)) then begin + updateemptytext(); + end; + +{ + if not (csloading in componentstate) then begin + if isenabled or (oe_nogray in foptionsedit) then begin + feditor.textflags:= ftextflags; + feditor.textflagsactive:= ftextflagsactive; + end + else begin + feditor.textflags:= ftextflags + [tf_grayed]; + feditor.textflagsactive:= ftextflagsactive + [tf_grayed]; + end; + end; +} +end; + +procedure tcustomedit.updatetextflags; +var + aflags,aflagsactive: textflagsty; +begin + if not (csloading in componentstate) then begin + if (des_emptytext in fstate) {and (fempty_text <> '')} and + (fempty_textflags <> []) then begin + aflags:= fempty_textflags; + aflagsactive:= aflags; + end + else begin + aflags:= textflags; + aflagsactive:= textflagsactive; + end; + if isenabled or (oe_nogray in foptionsedit) then begin + exclude(fstate,des_grayed); + feditor.textflags:= aflags; + feditor.textflagsactive:= aflagsactive; + end + else begin + include(fstate,des_grayed); + feditor.textflags:= aflags + [tf_grayed]; + feditor.textflagsactive:= aflagsactive + [tf_grayed]; + end; + end; +end; + +procedure tcustomedit.enabledchanged; +begin + inherited; + updatetextflags; + if (fempty_color <> cl_none) and (des_emptytext in fstate) then begin + invalidate(); + end; +end; + +procedure tcustomedit.settextflags(const value: textflagsty); +begin + if ftextflags <> value then begin + ftextflags:= checktextflags(ftextflags,value); + updatetextflags; + end; +end; + +procedure tcustomedit.settextflagsactive(const value: textflagsty); +begin + if ftextflagsactive <> value then begin + ftextflagsactive:= checktextflags(ftextflagsactive,value) {- ellipsemask}; + updatetextflags; + end; +end; + +procedure tcustomedit.dochange; +begin + checkautosize(); + if not (ws_loadedproc in fwidgetstate) then begin + if assistiveserver <> nil then begin + assistiveserver.dochange(getiassistiveclient()); + end; + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + (* +{$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.valuechanged(iificlient(self)); + end; +{$endif} + *) + end; +end; + +procedure tcustomedit.formatchanged(); +begin + if not (csloading in componentstate) then begin + invalidate(); + checkautosize(); + end; +end; + +procedure tcustomedit.internaltextedited(const aevent: texteditedeventty); +var + mstr1: msestring; +begin + if canevent(tmethod(aevent)) then begin + mstr1:= text; + aevent(self,mstr1); + if mstr1 <> text then begin + text:= mstr1; + end; +// feditor.oldtext:= mstr1; + end; +end; + +procedure tcustomedit.dotextedited; +begin + internaltextedited(fontextedited); +end; + +procedure tcustomedit.emptychanged; +begin + if not (csloading in componentstate) then begin + updateedittext(true); + end; +end; + +procedure tcustomedit.initnewcomponent(const ascale: real); +begin + createframe; + fframe.scale(ascale); + inherited; +end; + +procedure tcustomedit.initfocus; +begin + feditor.dofocus; +end; + +procedure tcustomedit.rootchanged(const aflags: rootchangeflagsty); +begin + inherited; + feditor.poschanged; +end; + +function tcustomedit.getedited: boolean; +begin + result:= false; +end; + +procedure tcustomedit.changed; +begin + dochange; +end; + +procedure tcustomedit.updateflagtext(var avalue: msestring); +begin + if oe_trimleft in foptionsedit then begin + avalue:= trimleft(avalue); + end; + if oe_trimright in foptionsedit then begin + avalue:= trimright(avalue); + end; + if oe_uppercase in foptionsedit then begin + avalue:= mseuppercase(avalue); + end + else begin + if oe_lowercase in foptionsedit then begin + avalue:= mselowercase(avalue); + end; + end; +end; + +function tcustomedit.geteditor: tinplaceedit; +begin + result:= feditor; +end; + +procedure tcustomedit.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + if oe1_autopopupmenu in feditor.optionsedit1 then begin + feditor.updatepopupmenu(amenu,popupmenu,mouseinfo,hasselection); + end; + inherited; +end; + +function tcustomedit.getcaretwidth: integer; +begin + result:= feditor.caretwidth; +end; + +procedure tcustomedit.setcaretwidth(const Value: integer); +begin + feditor.caretwidth:= value; +end; + +procedure tcustomedit.readpwchar(reader: treader); +begin + passwordchar:= msechar(reader.readinteger); +end; + +procedure tcustomedit.writepwchar(writer: twriter); +begin + writer.writeinteger(ord(passwordchar)); +end; + +procedure tcustomedit.defineproperties(filer: tfiler); +var + bo1: boolean; +begin + inherited; + if filer.ancestor <> nil then begin + bo1:= tcustomedit(filer.ancestor).passwordchar <> passwordchar; + end + else begin + bo1:= passwordchar <> #0; + end; + filer.defineproperty('pwchar',{$ifdef FPC}@{$endif}readpwchar, + {$ifdef FPC}@{$endif}writepwchar,bo1); +end; + +procedure tcustomedit.updatereadonlystate; +begin + if feditor <> nil then begin + feditor.updatecaret; + end; + cursorchanged; + if (oe_focusrectonreadonly in foptionsedit) and focused and active then begin + invalidate; + end; +end; + +function tcustomedit.hasselection: boolean; +begin + result:= false; +end; + +function tcustomedit.cangridcopy: boolean; +begin + result:= false; +end; + +function tcustomedit.gettextcliprect(): rectty; +begin + result:= clippedpaintrect(); + subpoint1(result.pos,paintpos); +end; + +procedure tcustomedit.showhint(const aid: int32; var info: hintinfoty); +begin + if (oe_hintclippedtext in foptionsedit) and + editor.lasttextclipped(gettextcliprect) and getshowhint then begin + info.caption:= text; + end; + inherited; +end; + +procedure tcustomedit.dragstarted; +begin + feditor.dragstarted; + inherited; +end; + +procedure tcustomedit.setcursorreadonly(const avalue: cursorshapety); +begin + if fcursorreadonly <> avalue then begin + fcursorreadonly:= avalue; + cursorchanged; + end; +end; + +function tcustomedit.actualcursor(const apos: pointty): cursorshapety; +begin + if oe_readonly in foptionsedit then begin + result:= fcursorreadonly; + end + else begin + result:= inherited actualcursor(apos); + if result = cr_default then begin + result:= cr_ibeam; + end; + end; +end; + +procedure tcustomedit.paintimage(const canvas: tcanvas); +begin + if canevent(tmethod(fonpaintimage)) then begin + fonpaintimage(self,canvas); + end; +end; + +function tcustomedit.navigrect: rectty; +begin + result:= inherited navigrect(); +// result:= frameinnerrect; +// result:= paintframerect; +end; + +{ tedit } + +constructor tedit.create(aowner: tcomponent); +begin + inherited; + ftimer:= tsimpletimer.create(0,@dotimer,false,[to_single]); +end; + +destructor tedit.destroy; +begin + ftimer.free; + inherited; +end; + +procedure tedit.dotimer(const sender: tobject); +begin + internaltextedited(fontextediteddelayed); +end; + +function tedit.getdelay: integer; +begin + result:= ftimer.interval div 1000; +end; + +procedure tedit.setdelay(const avalue: integer); +begin + ftimer.interval:= avalue * 1000; +end; + +procedure tedit.dotextedited; +begin + inherited; + ftimer.restart; +end; + +procedure tedit.editnotification(var info: editnotificationinfoty); +var + mstr1: msestring; +begin + inherited; + case info.action of + ea_textentered: begin + mstr1:= text; + updateflagtext(mstr1); + text:= mstr1; + ftimer.fireandstop; + initfocus; + end; + ea_undone: begin + updateedittext(false); + end; + end; +end; + +procedure tedit.loaded(); +begin + inherited; + updateedittext(false); +end; + +procedure tedit.dofocus(); +begin + updateedittext(false); + inherited; +end; + +procedure tedit.dodefocus(); +var + info1: editnotificationinfoty; +begin + with tinplaceedit1(feditor) do begin + if ies_edited in fstate then begin + info1:= initactioninfo(ea_textentered); + editnotification(info1); + end + else begin + updateedittext(false); + end; + end; + inherited; +end; + +procedure tedit.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +function tedit.gettext: msestring; +begin + result:= inherited gettext(); + if des_emptytext in fstate then begin + result:= ''; + end; +end; + +procedure tedit.settext(const avalue: msestring); +begin + inherited; + if not (csloading in componentstate) then begin + if avalue <> '' then begin + exclude(fstate,des_emptytext); + end; + updateedittext(true); + end; +end; + +procedure tedit.dostatwrite(const writer: tstatwriter); +begin + writer.writemsestring('text',text); +end; + +procedure tedit.dostatread(const reader: tstatreader); +begin + text:= reader.readmsestring('text',text); +end; + +procedure tedit.statreading; +begin + //dummy +end; + +procedure tedit.statread; +begin + if (oe1_checkvalueafterstatread in optionsedit1) then begin + dotextedited; + end; +end; + +function tedit.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +function tedit.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msefoldedit.pas b/mseide-msegui/lib/common/editwidgets/msefoldedit.pas new file mode 100644 index 0000000..0a27ea8 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msefoldedit.pas @@ -0,0 +1,878 @@ +{ MSEgui Copyright (c) 2009-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefoldedit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,msedataedits,msegraphics,mseguiglob,msegrids, + mseevent,msegui, + msegraphutils,msebitmap,mseeditglob,msedatalist,msewidgetgrid,mseedit, + msedrawtext,msetypes,msestat,msepointer,msemenus,msestrings,msegridsglob; + +const + defaultfoldedittextflags = defaulttextflags + [tf_clipo]; + defaultfoldedittextflagsactive = defaulttextflagsactive + [tf_clipo]; +type + tgridmsestringintdatalist = class(tmsestringintdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + end; + + foldeditoptionty = (feo_menulevel,feo_menuissum); + foldeditoptionsty = set of foldeditoptionty; + + tfoldedit = class(tstringedit) + private + foncellevent: celleventty; + fonclientmouseevent: mouseeventty; + flevelstep: integer; + fimagesize: sizety; + fimnr_base: integer; + fimnr_expanded: integer; + fimnr_selected: integer; + fimnr_readonly: integer; + fimnr_subitems: integer; + fimagelist: timagelist; + fdefault: msestringintty; + + fimnr_value: integer; + fimnr_valuebase: integer; + fimnr_valueexpanded: integer; + fimnr_valueselected: integer; + fimnr_valuereadonly: integer; + fimnr_valuesubitems: integer; + fimagelistvalue: timagelist; + foptions: foldeditoptionsty; + procedure setlevelstep(const avalue: integer); + procedure setimagesize(const avalue: sizety); + procedure setimagewidth(const avalue: integer); + procedure setimageheight(const avalue: integer); + procedure setimnr_base(const avalue: integer); + procedure setimnr_expanded(const avalue: integer); + procedure setimnr_selected(const avalue: integer); + procedure setimnr_readonly(const avalue: integer); + procedure setimnr_subitems(const avalue: integer); + procedure setimagelist(const avalue: timagelist); + function getgridimnr(index: integer): integer; + procedure setgridimnr(index: integer; const avalue: integer); + function getgridimnrs: integerarty; + procedure setgridimnrs(const avalue: integerarty); + procedure setimnr_value(const avalue: integer); + procedure setimnr_valuebase(const avalue: integer); + procedure setimnr_valueexpanded(const avalue: integer); + procedure setimnr_valueselected(const avalue: integer); + procedure setimnr_valuereadonly(const avalue: integer); + procedure setimnr_valuesubitems(const avalue: integer); + procedure setimagelistvalue(const avalue: timagelist); + procedure dolevelup(const sender: tobject); + procedure doleveldown(const sender: tobject); + procedure doissum(const sender: tobject); + protected + procedure updatelayout; + procedure drawimage(const acanvas: tcanvas; + const ainfo: prowfoldinfoty; var arect: rectty; + const isselected,isreadonly: boolean; + const datapo: pmsestringintty); + procedure drawcell(const canvas: tcanvas); override; + procedure clientmouseevent(var ainfo: mouseeventinfoty); override; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + procedure updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); override; + procedure updatelevelcellzone(const alevel: integer; const apos: pointty; + var azone: cellzonety); virtual; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; override; + procedure doonpaint(const acanvas: tcanvas); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdefaultvalue: pointer; override; + function imageshift(arow: integer): integer; + //-1 -> focused row + procedure setupeditor; override; + procedure gridtovalue(arow: integer); override; + procedure valuetogrid(arow: integer); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + public + constructor create(aowner: tcomponent); override; + procedure synctofontheight; override; + property imagesize: sizety read fimagesize write setimagesize; + property gridimnr[index: integer]: integer + read getgridimnr write setgridimnr; + property gridimnrs: integerarty read getgridimnrs write setgridimnrs; + published + property options: foldeditoptionsty read foptions write foptions default []; + property oncellevent: celleventty read foncellevent write foncellevent; + property onclientmouseevent: mouseeventty read fonclientmouseevent + write fonclientmouseevent; + property levelstep: integer read flevelstep write setlevelstep default 10; + + property imnr_base: integer read fimnr_base write setimnr_base default 0; + property imnr_expanded: integer read fimnr_expanded + write setimnr_expanded default 0; + property imnr_selected: integer read fimnr_selected + write setimnr_selected default 0; + property imnr_readonly: integer read fimnr_readonly + write setimnr_readonly default 0; + property imnr_subitems: integer read fimnr_subitems + write setimnr_subitems default 0; + + + property imnr_value: integer read fimnr_value write setimnr_value default -1; + //-1 -> use imagelist, imnr_base, imnr_expanded, imnr_selected + //imnr_readonly, imnr_subitems + //-2 none + // >= 0 use imagelistvalue, imnr_value + imnr_base, imnr_expanded, imnr_selected + //imnr_readonly, imnr_subitems + property imnr_valuebase: integer read fimnr_valuebase + write setimnr_valuebase default 0; + property imnr_valueexpanded: integer read fimnr_valueexpanded + write setimnr_valueexpanded default 0; + property imnr_valueselected: integer read fimnr_valueselected + write setimnr_valueselected default 0; + property imnr_valuereadonly: integer read fimnr_valuereadonly + write setimnr_valuereadonly default 0; + property imnr_valuesubitems: integer read fimnr_valuesubitems + write setimnr_valuesubitems default 0; + + property imagelist: timagelist read fimagelist write setimagelist; + property imagelistvalue: timagelist read fimagelistvalue + write setimagelistvalue; + property imagewidth: integer read fimagesize.cx write setimagewidth default 0; + property imageheight: integer read fimagesize.cy write setimageheight default 0; + property textflags default defaultfoldedittextflags; + property textflagsactive default defaultfoldedittextflagsactive; +// property cursor default cr_default; + end; + +implementation +uses + msestockobjects,msesumlist,mseact; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdatacols1 = class(tdatacols); + twidgetcol1 = class(twidgetcol); + +{ tgridmsestringintdatalist } + +constructor tgridmsestringintdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; +end; + +function tgridmsestringintdatalist.getdefault: pointer; +begin + result:= nil; + with twidgetcol1(fowner) do begin + if fintf <> nil then begin + result:= fintf.getdefaultvalue; + end; + end; +end; + +{ tfoldedit } + +constructor tfoldedit.create(aowner: tcomponent); +begin + flevelstep:= 10; + fdefault.int:= -1; + fimnr_value:= -1; + inherited; +// cursor:= cr_default; + textflags:= defaultfoldedittextflags; + textflagsactive:= defaultfoldedittextflagsactive; +end; + +procedure tfoldedit.drawimage(const acanvas: tcanvas; + const ainfo: prowfoldinfoty; var arect: rectty; + const isselected,isreadonly: boolean; + const datapo: pmsestringintty); +const + boxsize = 11; +var + levelshift: integer; + int1,int2,int3,int4: integer; + glyph1: stockglyphty; + lines: segmentarty; + ycenter,xbefore: integer; + imli1: timagelist; +begin + if ainfo <> nil then begin + with ainfo^ do begin + xbefore:= arect.x; + ycenter:= arect.cy div 2; + levelshift:= flevelstep*foldlevel; + glyph1:= stg_none; + if haschildren then begin + if isopen then begin + glyph1:= stg_boxexpanded; + end + else begin + glyph1:= stg_boxexpand; + end; + end; + inc(arect.x,levelshift); + int3:= flevelstep + flevelstep div 2; + int4:= 0; + setlength(lines,foldlevel+2); + for int2:= 0 to high(nolines) - 1 do begin + with lines[int4] do begin + if not nolines[int2] then begin + a.x:= int3; + b.x:= int3; + a.y:= 0; + b.y:= arect.cy; + inc(int4); + end; + end; + inc(int3,flevelstep); + end; + if foldlevel > 0 then begin + with lines[int4] do begin + a.x:= int3; + b.x:= int3; + a.y:= 0; + if (glyph1 = stg_none) then begin + if nolines[high(nolines)] then begin + b.y:= ycenter; + end + else begin + b.y:= arect.cy; + end; + inc(int4); + with lines[int4] do begin + a.x:= int3; + b.x:= int3 + flevelstep div 2; + a.y:= ycenter; + b.y:= ycenter; + end; + end + else begin + b.y:= ycenter - boxsize div 2; + if not nolines[high(nolines)] then begin + inc(int4); + with lines[int4] do begin + a.x:= int3; + b.x:= int3; + a.y:= ycenter + boxsize div 2; + b.y:= arect.cy; + end; + end; + end; + inc(int4); + end; + end; + if int4 > 0 then begin + setlength(lines,int4); + drawdottedlinesegments(acanvas,lines,cl_shadow); + end; + if glyph1 <> stg_none then begin + int1:= arect.cx; + arect.cx:= flevelstep; + stockobjects.glyphs.paint(acanvas,ord(glyph1),arect, + [al_ycentered,al_xcentered],cl_glyph); + arect.cx:= int1; + end; + inc(arect.x,flevelstep); + imli1:= nil; + if datapo <> nil then begin + int1:= datapo^.int; + end + else begin + int1:= fimnr_value; + end; + if int1 <> -1 then begin + if fimagelistvalue <> nil then begin + imli1:= fimagelistvalue; + inc(int1,fimnr_valuebase); + if isopen then begin + inc(int1,fimnr_valueexpanded); + end; + if isselected then begin + inc(int1,fimnr_valueselected); + end; + if isreadonly then begin + inc(int1,fimnr_valuereadonly); + end; + if isselected then begin + inc(int1,fimnr_valueselected); + end; + if haschildren then begin + inc(int1,fimnr_valuesubitems); + end; + end; + end + else begin + if fimagelist <> nil then begin + imli1:= fimagelist; + int1:= fimnr_base { fimagenr}; + if isopen then begin + inc(int1,fimnr_expanded); + end; + if isselected then begin + inc(int1,fimnr_selected); + end; + if isreadonly then begin + inc(int1,fimnr_readonly); + end; + if isselected then begin + inc(int1,fimnr_selected); + end; + if haschildren then begin + inc(int1,fimnr_subitems); + end; + end; + end; + if (imli1 <> nil) and (int1 >= 0) then begin + int2:= arect.cx; + arect.cx:= fimagesize.cx; + imli1.paint(acanvas,int1,arect,[al_ycentered,al_xcentered]); + inc(arect.x,fimagesize.cx); + arect.cx:= int2; + end; + arect.cx:= arect.cx - (arect.x-xbefore); + end; + end; +end; + +procedure tfoldedit.drawcell(const canvas: tcanvas); +var + rect1: rectty; + int1,int2,int3: integer; +begin + with cellinfoty(canvas.drawinfopo^) do begin + rect1:= rect; + drawimage(canvas,foldinfo,rect,cds_selected in drawstate, + cds_readonly in drawstate,pmsestringintty(datapo)); + int1:= innerrect.x; + int2:= innerrect.cx; + try + int3:= rect.x - rect1.x; //apply adjustments to innerrect + innerrect.x:= innerrect.x + int3; + innerrect.cx:= innerrect.cx - int3; + if innerrect.cx < 0 then begin + innerrect.cx:= 0; + end; + inherited; + finally + innerrect.x:= int1; + innerrect.cx:= int2; + rect:= rect1; + end; + end; +end; + +procedure tfoldedit.doonpaint(const acanvas: tcanvas); +var + rect1: rectty; + int1: integer; +begin + if (fgridintf <> nil) then begin + acanvas.rootbrushorigin:= fgridintf.getbrushorigin; + rect1:= clientrect; + with fgridintf.getcol,grid do begin + int1:= row; + if int1 >= 0 then begin //not csdesigning + drawimage(acanvas,rowfoldinfo,rect1, + datacols.selected[makegridcoord(index,int1)], + rowreadonlystate[int1],nil); + end + else begin + drawimage(acanvas,rowfoldinfo,rect1,false,false,nil); + end; + end; + end; + inherited; +end; + +procedure tfoldedit.clientmouseevent(var ainfo: mouseeventinfoty); +var + isvisible1,haschildren1,isopen1: boolean; + foldlevel1: byte; + zone1: cellzonety; + row1: integer; +begin + if canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,ainfo); + end; + if not (es_processed in ainfo.eventstate) and (fgridintf <> nil) then begin + with ainfo do begin + if isleftbuttondown(ainfo,[]) then begin +{$warnings off} + with fgridintf.getcol.grid,tdatacols1(datacols).frowstate do begin +{$warnings on} + row1:= row; + if row1 >= 0 then begin //no csdesigning + getfoldstate(row1,isvisible1,foldlevel1,haschildren1,isopen1); + zone1:= cz_default; + updatelevelcellzone(foldlevel1,ainfo.pos,zone1); + if (zone1 = cz_default) and + (ainfo.pos.x >= foldlevel1 * flevelstep) then begin + if isopen1 then begin + hidechildren(row1); + end + else begin + showchildren(row1); + end; + end; + end; + end; + end; + end; + if not (es_processed in ainfo.eventstate) then begin + inherited; + end; + end; +end; + +procedure tfoldedit.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + with info do begin + if ownedcol then begin + if (eventkind in mousecellevents) and (info.cell.row >= 0) then begin + updatelevelcellzone(fgridintf.getcol.grid.rowfoldlevel[info.cell.row], + info.mouseeventinfopo^.pos,info.zone); + end + else begin + if eventkind = cek_exit then begin + end; + end; + end; +{ + if (info.eventkind = cek_enter) or + (info.eventkind = cek_exit) then begin + if oe_locate in foptionsedit then begin + editing:= false; + end; + factiverow:= info.newcell.row; + if fvalue <> nil then begin + if info.eventkind = cek_enter then begin + updateitemvalues(info.newcell.row,1); + end + else begin + updateitemvalues(info.cellbefore.row,1); + end; + end; + end; +} + end; + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; + inherited; +end; + +procedure tfoldedit.updatelevelcellzone(const alevel: integer; const apos: pointty; + var azone: cellzonety); +var + int1: integer; +begin + int1:= (alevel+1) * flevelstep; + if apos.x >= int1 + fimagesize.cx then begin + azone:= cz_caption; + end + else begin + if apos.x >= int1 then begin + azone:= cz_image; + end; + end; +end; + +procedure tfoldedit.updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); +begin + if row >= 0 then begin + updatelevelcellzone(fgridintf.getcol.grid.rowfoldlevel[row],apos,result); + end; +end; + +procedure tfoldedit.setlevelstep(const avalue: integer); +begin + if avalue <> flevelstep then begin + flevelstep:= avalue; + updatelayout; + end; +end; + +procedure tfoldedit.setimageheight(const avalue: integer); +begin + if fimagesize.cy <> avalue then begin + fimagesize.cy := avalue; + updatelayout; +// invalidate; + end; +end; + +procedure tfoldedit.setimagewidth(const avalue: integer); +begin + if fimagesize.cx <> avalue then begin + fimagesize.cx := avalue; + updatelayout; +// invalidate; + end; +end; + +procedure tfoldedit.setimagesize(const avalue: sizety); +begin + if (fimagesize.cx <> avalue.cx) or (fimagesize.cy <> avalue.cy) then begin + fimagesize:= avalue; + updatelayout; + end; +end; + +procedure tfoldedit.setimagelist(const avalue: timagelist); +begin + if fimagelist <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + if (fimagelist <> nil) and (csdesigning in componentstate) then begin + fimagesize:= fimagelist.size; + end; + updatelayout; +// invalidate; + end; +end; + +procedure tfoldedit.setimagelistvalue(const avalue: timagelist); +begin + if fimagelistvalue <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelistvalue)); + if (fimagelistvalue <> nil) and (csdesigning in componentstate) then begin + fimagesize:= fimagelistvalue.size; + end; + updatelayout; +// invalidate; + end; +end; + +procedure tfoldedit.setimnr_base(const avalue: integer); +begin + if fimnr_base <> avalue then begin + fimnr_base:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_expanded(const avalue: integer); +begin + if fimnr_expanded <> avalue then begin + fimnr_expanded:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_selected(const avalue: integer); +begin + if fimnr_selected <> avalue then begin + fimnr_selected:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_readonly(const avalue: integer); +begin + if fimnr_readonly <> avalue then begin + fimnr_readonly:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_subitems(const avalue: integer); +begin + if fimnr_subitems <> avalue then begin + fimnr_subitems:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_value(const avalue: integer); +begin + if fimnr_value <> avalue then begin + fimnr_value:= avalue; + valuechanged; + end; +end; + +procedure tfoldedit.setimnr_valuebase(const avalue: integer); +begin + if fimnr_valuebase <> avalue then begin + fimnr_valuebase:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_valueexpanded(const avalue: integer); +begin + if fimnr_valueexpanded <> avalue then begin + fimnr_valueexpanded:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_valueselected(const avalue: integer); +begin + if fimnr_valueselected <> avalue then begin + fimnr_valueselected:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_valuereadonly(const avalue: integer); +begin + if fimnr_valuereadonly <> avalue then begin + fimnr_valuereadonly:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_valuesubitems(const avalue: integer); +begin + if fimnr_valuesubitems <> avalue then begin + fimnr_valuesubitems:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.updatelayout; +begin + formatchanged; +end; + +function tfoldedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridmsestringintdatalist.create(sender); +end; + +function tfoldedit.getdefaultvalue: pointer; +begin + result:= @fdefault; +end; + +function tfoldedit.imageshift(arow: integer): integer; +begin + result:= 0; + if fimagelist <> nil then begin + inc(result,fimagesize.cx); + end; + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + if arow < 0 then begin + arow:= row; + end; + if arow >= 0 then begin + inc(result,(rowfoldlevel[arow]+1)*flevelstep); + end; + end; + end; +end; + +procedure tfoldedit.setupeditor; +var + int1: integer; + rect1,rect2: rectty; +begin + inherited; + int1:= imageshift(-1); + if int1 > 0 then begin + rect1:= feditor.cliprect; + rect2:= feditor.destrect; + inc(rect1.x,int1); + dec(rect1.cx,int1); + if rect1.cx < 0 then begin + rect1.cx:= 0; + end; + inc(rect2.x,int1); + dec(rect2.cx,int1); + if rect2.cx < 0 then begin + rect2.cx:= 0; + end; + feditor.updatepos(rect2,rect1); + end; +end; + +function tfoldedit.getgridimnr(index: integer): integer; +var + list: tdatalist; +begin + list:= checkgriddata(index); + if list <> nil then begin + result:= tmsestringintdatalist(list).itemsb[index]; + end + else begin + result:= -1; + end; +end; + +procedure tfoldedit.setgridimnr(index: integer; const avalue: integer); +var + list: tdatalist; +begin + list:= checkgriddata(index); + if list <> nil then begin + tmsestringintdatalist(list).itemsb[index]:= avalue; + end; +end; + +function tfoldedit.getgridimnrs: integerarty; +begin + checkgrid; + result:= tmsestringintdatalist(fgridintf.getcol.datalist).asarrayb; +end; + +procedure tfoldedit.setgridimnrs(const avalue: integerarty); +begin + checkgrid; + tmsestringintdatalist(fgridintf.getcol.datalist).asarrayb:= avalue; +end; + +procedure tfoldedit.gridtovalue(arow: integer); +var + val1: msestringintty; +begin + fgridintf.getdata(arow,val1); + fvalue:= val1.mstr; + fimnr_value:= val1.int; + valuetotext; +end; + +procedure tfoldedit.valuetogrid(arow: integer); +var + val1: msestringintty; +begin + val1.mstr:= fvalue; + val1.int:= fimnr_value; + fgridintf.setdata(arow,val1); +end; + +procedure tfoldedit.writestatvalue(const writer: tstatwriter); +begin + inherited; + writer.writeinteger(valuevarname+'_imnr',fimnr_value); +end; + +procedure tfoldedit.readstatvalue(const reader: tstatreader); +begin + inherited; + if fgridintf = nil then begin + imnr_value:= reader.readinteger(valuevarname+'_imnr',imnr_value); + end; +end; + +procedure tfoldedit.synctofontheight; +var + size1: sizety; +begin + inherited; + size1:= paintsize; + if size1.cy < fimagesize.cy then begin + size1.cy:= fimagesize.cy; + paintsize:= size1; + if fgridintf <> nil then begin + fgridintf.getcol.grid.datarowheight:= bounds_cy; + end; + end; +end; + +procedure tfoldedit.dolevelup(const sender: tobject); +begin + with fgridintf.getgrid do begin + rowfoldlevel[-1]:= rowfoldlevel[-1] + 1; + end; +end; + +procedure tfoldedit.doleveldown(const sender: tobject); +begin + with fgridintf.getgrid do begin + rowfoldlevel[-1]:= rowfoldlevel[-1] - 1; + end; +end; + +procedure tfoldedit.doissum(const sender: tobject); +begin + with fgridintf.getgrid do begin + rowfoldissum[-1]:= not rowfoldissum[-1]; + end; +end; + +procedure tfoldedit.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +var + state1: actionstatesty; +begin + inherited; + if fgridintf <> nil then begin + if feo_menulevel in foptions then begin + tpopupmenu.additems(amenu,self,mouseinfo,['Levelup','Leveldown'], + [],[],[{$ifdef FPC}@{$endif}dolevelup, + {$ifdef FPC}@{$endif}doleveldown]); + end; + if feo_menuissum in foptions then begin + state1:= []; + if fgridintf.getgrid.rowfoldissum[-1] then begin + state1:= [as_checked]; + end; + tpopupmenu.additems(amenu,self,mouseinfo,['Issum'], + [[mao_checkbox]],[state1],[{$ifdef FPC}@{$endif}doissum],false); + end; + end; +end; + +function tfoldedit.getcellcursor(const arow: integer; + const acellzone: cellzonety; const apos: pointty): cursorshapety; +begin + if acellzone = cz_caption then begin + result:= inherited getcellcursor(arow,acellzone,apos); + end + else begin + result:= cr_arrow; + end; +end; + +{ +function tfoldedit.getinnerframe: framety; +begin + result:= inherited getinnerframe; +// result.left:= result.left + imageshift(-1); +end; +} +function createtgridmsestringintdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridmsestringintdatalist.create(aowner); +end; + +initialization + registergriddatalistclass(tgridmsestringintdatalist.classname, + {$ifdef FPC}@{$endif}createtgridmsestringintdatalist); +end. diff --git a/mseide-msegui/lib/common/editwidgets/msegraphedits.pas b/mseide-msegui/lib/common/editwidgets/msegraphedits.pas new file mode 100644 index 0000000..fcb2015 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msegraphedits.pas @@ -0,0 +1,5180 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegraphedits; +{$ifdef FPC} + {$mode objfpc}{$h+} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msegui, + mseglob,mseguiglob,msescrollbar,msegraphutils,msegraphics,mseevent, + msewidgets,mseeditglob,msestockobjects,msestat,msestatfile,mseassistiveclient, + mseclasses,msesimplewidgets,msemenus,mseact,typinfo,msedragglob, + msegrids,msewidgetgrid,msedatalist,msebitmap,msetypes,msestrings,msearrayprops, + msedrawtext,mseshapes + {$ifdef mse_with_ifi}{,mseifi},mseifiglob,mseificomp,mseificompglob{$endif}, + msepointer,msegridsglob; + +const + defaultsliderwidth = 200; + defaultsliderheight = 20; + defaultboxsize = 13; + defaultsliderscrollbaroptions = defaultscrollbaroptions + + [sbo_valuekeys,sbo_thumbtrack]; + defaultgrapheditframeoptions = defaultcaptionframeoptions + [cfo_captionfocus]; + +type + tgrapheditframe = class(tcustomcaptionframe) + protected +// function getdefaultcolorclient: colorty; virtual; +// function actualcolorclient(): colorty override; + public + constructor create(const aintf: icaptionframe); + published + property options default defaultgrapheditframeoptions; + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property colorclient {default cl_transparent}; + property caption; + property captionpos default cp_right; + property captiondist; + property captionoffset; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + ttogglegrapheditframe = class(tgrapheditframe) + protected + function actualcolorclient: colorty override; + published + property colorclient {default cl_foreground}; + end; + + tgraphdataedit = class(tactionpublishedwidget,igridwidget,istatfile, + iassistiveclientgridwidget + {$ifdef mse_with_ifi},iifidatalink{$endif}) + private + fonchange: notifyeventty; + fondataentered: notifyeventty; + fcolorglyph: colorty; + fstatvarname: msestring; + fstatfile: tstatfile; + foptionsedit: optionseditty; + foptionsedit1: optionsedit1ty; + fedited: boolean; + fvalueread: boolean; + fstatpriority: integer; + procedure setcolorglyph(const Value: colorty); + procedure setstatfile(const Value: tstatfile); + procedure setoptionsedit(const avalue: optionseditty); + function getreadonly: boolean; + procedure setreadonly(const avalue: boolean); + procedure setedited(const avalue: boolean); virtual; + procedure setoptionsedit1(const avalue: optionsedit1ty); + protected + fdatalist: tdatalist; + fgridintf: iwidgetgrid; + fgriddatalink: pointer; + fparentintf: igridwidget; + fstate: dataeditstatesty; +{$ifdef mse_with_ifi} + fifilink: tifivaluelinkcomp; + function getdefaultifilink: iificlient; override; + procedure ifisetvalue(var avalue; var accept: boolean); + procedure getifivalue(var avalue) virtual; + procedure setifivalue(const avalue) virtual; + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifilinkcomp); + function getifilink: tifilinkcomp; + //iificlient + function getifidatatype(): listdatatypety override; +// function ifigriddata: tdatalist; + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + function getiassistiveclient(): iassistiveclient override; + //iassistiveclientgridwidget + function getifidatalinkintf(): iifidatalink; override; + function getassistiveflags: assistiveflagsty; override; + function getassistivecolumncaption(): msestring virtual; +{$endif} + function getedited: boolean; virtual; + function geteditstate: dataeditstatesty; + procedure seteditstate(const avalue: dataeditstatesty); + function getoptionsedit: optionseditty; virtual; + procedure updateoptions; virtual; + procedure loaded; override; + procedure internalcreateframe; override; + procedure enabledchanged() override; + procedure setenabled(const avalue: boolean); override; + procedure dofocus; override; + + function getgridintf: iwidgetgrid; + procedure checkgrid; + function checkgriddata: tdatalist; + procedure internalfillcol(const value); + procedure internalassigncol(const value); + procedure internalgetgridvalue(index: integer; out value); + procedure internalsetgridvalue(index: integer; const avalue); + procedure dochange; virtual; + function docheckvalue(var avalue; const quiet: boolean): boolean; virtual; + procedure valuechanged; virtual; + procedure modified; virtual; //for dbwidgets + procedure formatchanged(); + procedure dopaintforeground(const canvas: tcanvas); override; + function needsfocuspaint: boolean; override; + procedure internalcheckvalue(var avalue; var accept: boolean); + virtual; abstract; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); + virtual; abstract; + procedure dofontheightdelta(var delta: integer); override; + procedure sizechanged; override; + + procedure updatereadonlystate; virtual; + procedure initeditfocus; + procedure updatedatalist; virtual; + + //igridwidget + procedure setfirstclick(var ainfo: mouseeventinfoty); + function createdatalist(const sender: twidgetcol): tdatalist; + virtual; abstract; + procedure datalistdestroyed; virtual; + function getdatalistclass: datalistclassty; virtual; abstract; + function getdefaultvalue: pointer; virtual; + function getrowdatapo(const arow: integer): pointer; virtual; + procedure setgridintf(const intf: iwidgetgrid); virtual; + function getcellframe: framety; virtual; + function needscellfocuspaint(): boolean; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; virtual; + procedure updatecellzone(const arow: integer; const apos: pointty; + var result: cellzonety); virtual; + procedure drawcell(const canvas: tcanvas); + procedure updateautocellsize(const canvas: tcanvas); virtual; + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure valuetogrid(row: integer); virtual; abstract; + procedure gridtovalue(row: integer); virtual; + procedure setvaluedata(const source); virtual; abstract; + procedure getvaluedata(out dest); virtual; abstract; + function getnulltext: msestring; virtual; + function getassistivecelltext(const arow: int32): msestring; virtual; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); virtual; + function sortfunc(const l,r): integer; virtual; + procedure gridvaluechanged(const index: integer); virtual; + procedure updatecoloptions(const aoptions: coloptionsty); + procedure updatecoloptions1(const aoptions: coloptions1ty); + procedure statdataread; virtual; + procedure griddatasourcechanged; virtual; + procedure fontchanged; override; + procedure setparentgridwidget(const intf: igridwidget); + procedure childdataentered(const sender: igridwidget); virtual; + procedure childfocused(const sender: igridwidget); virtual; + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + procedure readstatvalue(const reader: tstatreader); virtual; + procedure writestatvalue(const writer: tstatwriter); virtual; + procedure readstatstate(const reader: tstatreader); virtual; + procedure writestatstate(const writer: tstatwriter); virtual; + procedure readstatoptions(const reader: tstatreader); virtual; + procedure writestatoptions(const writer: tstatwriter); virtual; + + public + constructor create(aowner: tcomponent); override; + procedure initnewcomponent(const ascale: real); override; + procedure initnewwidget(const ascale: real); override; + procedure initgridwidget; virtual; + procedure paint(const canvas: tcanvas); override; + + property edited: boolean read getedited write setedited; + function actualcolor: colorty; override; + function widgetcol: twidgetcol; + function grid: tcustomwidgetgrid; + function gridrow: integer; + function gridrowhigh: int32; //-1 if no grid + function griddatarowhigh: int32; //-1 if no grid + function gridcol: integer; + function griddata: tdatalist; + + function checkvalue(const quiet: boolean = false): boolean virtual abstract; + function seteditfocus: boolean; + + property objectlinker: tobjectlinker read getobjectlinker + {$ifdef msehasimplements}implements istatfile{$endif}; + property colorglyph: colorty read fcolorglyph write setcolorglyph + default cl_default; + //cl_default -> cl_glyph + property readonly: boolean read getreadonly write setreadonly; + published + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property optionsedit: optionseditty read getoptionsedit write setoptionsedit + default defaultoptionsedit; + property optionsedit1: optionsedit1ty read foptionsedit1 + write setoptionsedit1 default defaultoptionsedit1; + property onchange: notifyeventty read fonchange write fonchange; + property ondataentered: notifyeventty read fondataentered + write fondataentered; + end; + + tpointeredit = class; + + paintpointerglypheventty = procedure(const sender: tpointeredit; + const acanvas: tcanvas; const avalue: pointer; + const arow: integer) of object; + + tpointeredit = class(tgraphdataedit) + private + fvalue: pointer; + fonpaintglyph: paintpointerglypheventty; + procedure setvalue(const avalue: pointer); + function getgridvalue(const index: integer): pointer; + procedure setgridvalue(const index: integer; const avalue: pointer); + function getgridvalues: pointerarty; + procedure setgridvalues(const avalue: pointerarty); + protected + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure gridtovalue(arow: integer); override; + procedure valuetogrid(arow: integer); override; + public + procedure initnewcomponent(const ascale: real); override; + property value: pointer read fvalue write setvalue default nil; + property gridvalue[const index: integer]: pointer + read getgridvalue write setgridvalue; default; + property gridvalues: pointerarty read getgridvalues write setgridvalues; + function griddata: tgridpointerdatalist; + published + property visible; + property enabled; + property onpaintglyph: paintpointerglypheventty read fonpaintglyph + write fonpaintglyph; + end; + + tsliderscrollbar = class(tscrollbar,iface) + private + protected + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + destructor destroy; override; + published + property options default defaultsliderscrollbaroptions; + property buttonlength default defaultbuttonminlength; + end; + + tcustomrealgraphdataedit = class; + + paintrealglypheventty = procedure( + const sender: tcustomrealgraphdataedit; + const acanvas: tcanvas; const avalue: real; + const arow: integer) of object; + + tcustomrealgraphdataedit = class(tgraphdataedit) + private + fonsetvalue: setrealeventty; + fdirection: graphicdirectionty; + fonpaintglyph: paintrealglypheventty; + procedure setvalue(const avalue: realty); + function getgridvalue(const index: integer): realty; + procedure setgridvalue(const index: integer; const avalue: realty); + function getgridvalues: realarty; + procedure setgridvalues(const avalue: realarty); + protected + fvalue: realty; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure internalcreateframe; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure setdirection(const avalue: graphicdirectionty); virtual; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure internalcheckvalue(var avalue; var accept: boolean); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure setnullvalue; virtual; //for dbedits + {$ifdef mse_with_ifi} + function getifilink: tifireallinkcomp; + procedure setifilink(const avalue: tifireallinkcomp); + {$endif} + public + constructor create(aowner: tcomponent); override; + procedure fillcol(const value: realty); + procedure assigncol(const avalue: trealdatalist); + function checkvalue(const quiet: boolean = false): boolean override; + function isnull: boolean; + property gridvalue[const index: integer]: realty + read getgridvalue write setgridvalue; default; + property gridvalues: realarty read getgridvalues write setgridvalues; + function griddata: tgridrealdatalist; + property value: realty read fvalue write setvalue; + property direction: graphicdirectionty read fdirection write setdirection + default gd_right; + property onsetvalue: setrealeventty read fonsetvalue write fonsetvalue; + property onpaintglyph: paintrealglypheventty read fonpaintglyph + write fonpaintglyph; + published + property visible; + property enabled; + property bounds_cx default defaultsliderwidth; + property bounds_cy default defaultsliderheight; + {$ifdef mse_with_ifi} + property ifilink: tifireallinkcomp read getifilink write setifilink; + {$endif} + end; + + trealgraphdataedit = class(tcustomrealgraphdataedit) + published + property value; + property onsetvalue; + property direction; + property onpaintglyph; + end; + + tsliderframe = class(tgrapheditframe) + protected + procedure settemplateinfo(const ainfo: frameinfoty); override; + end; + +const + defaultslideroptionswidget = defaultoptionswidget + [ow_mousewheel]; +type + tcustomslider = class(tcustomrealgraphdataedit,iscrollbar) + private + fscrollbar: tsliderscrollbar; + fupdating: integer; + procedure setscrollbar(const avalue: tsliderscrollbar); + protected + procedure beginpaint(); //disable invalidate and updating + procedure endpaint(); + procedure setdirection(const avalue: graphicdirectionty); override; + procedure objectchanged(const sender: tobject); override; + procedure clientrectchanged; override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure doenter; override; + procedure doexit; override; + procedure activechanged; override; + procedure enabledchanged; override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); + + procedure dochange; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + class function classskininfo: skininfoty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure initgridwidget; override; + property scrollbar: tsliderscrollbar read fscrollbar write setscrollbar; + published + property optionswidget default defaultslideroptionswidget; + end; + + tslider = class(tcustomslider) + published + property value; + property scrollbar; + property onsetvalue; + property direction; + property onpaintglyph; + end; + +const + defaultbarcolor = cl_ltblue; + +type + tbarface = class(tface) + public + constructor create(const intf: iface); reintroduce; + end; + + tcustomprogressbar = class; + + tbarframe = class(tframe) + private + fowner: tcustomprogressbar; + public + constructor create(const aowner: tcustomprogressbar); + end; + + tcustomprogressbar = class(tcustomrealgraphdataedit,iface) + private + fbar_face: tbarface; + fbar_frame: tbarframe; + ffacerect: rectty; + fframebarrect: rectty; + ffacebarrect: rectty; + fvaluerange: real; + fvaluestart: real; + fformat: msestring; + ftextflags: textflagsty; + fonfinished: progresseventty; + fonprogress: progresseventty; + fcancel: boolean; + procedure setvalue(const avalue: realty); + procedure setbar_face(const avalue: tbarface); + procedure updatebarrect(const avalue: realty; const arect: rectty; + out facedest,framebardest,facebardest: rectty); + procedure updatebar; + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + procedure setformat(const avalue: msestring); + procedure settextflags(const avalue: textflagsty); + procedure setbar_frame(const avalue: tbarframe); + procedure readformat(reader: treader); + procedure writeformat(writer: twriter); + procedure readvaluescale(reader: treader); + protected + procedure clientrectchanged; override; + procedure dochange; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure internalcreateframe; override; + procedure defineproperties(filer: tfiler); override; + procedure gridtovalue(arow: integer); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure changedirection(const avalue: graphicdirectionty; + var dest: graphicdirectionty); override; + procedure doprogress(const sender: tobject; const avalue: real; + var acancel: boolean); + //threadsave + property cancel: boolean read fcancel write fcancel; + //ored with doprogress.acancel, resetted by value:= 0.0 + property value: realty read fvalue write setvalue; + //thread safe, range 0 .. 1.0 + published + property onsetvalue; + property direction; + + property optionswidget default defaultoptionswidgetnofocus; + property bar_face: tbarface read fbar_face write setbar_face; + property bar_frame: tbarframe read fbar_frame write setbar_frame; + property valuerange: real read fvaluerange write setvaluerange; //default 100 + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat stored false; + //default '0%', '' for no numeric + property textflags: textflagsty read ftextflags write settextflags default + [tf_ycentered,tf_xcentered]; + property font: twidgetfont read getfont write setfont stored isfontstored; + property onprogress: progresseventty read fonprogress write fonprogress; + //called from doprogress + property onfinished: progresseventty read fonfinished write fonfinished; + //called in doprogress if avalue = 1.0 or canceled + end; + + tprogressbar = class(tcustomprogressbar) + published + property value; + property onpaintglyph; + end; + + ttogglegraphdataedit = class(tgraphdataedit) + private + foptions: buttonoptionsty; + function getcheckedrow: integer; + procedure setcheckedrow(const avalue: integer); + function getcheckedtag: integer; + procedure setcheckedtag(const avalue: integer); + protected + fgroup: integer; + fcheckcaption: boolean; + fclickedrow: integer; + fresetting: integer; //for db edits + procedure internalcreateframe; override; + procedure setoptions(const avalue: buttonoptionsty); virtual; + procedure resetradioitems(); + procedure togglevalue(const areadonly: boolean; + const down: boolean) virtual abstract; + procedure docheck() virtual abstract; + procedure douncheck() virtual abstract; + function ischecked(): boolean virtual abstract; + procedure togglegridvalue(const index: integer) virtual abstract; + procedure resetgridvalue(const index: integer) virtual abstract; + procedure checkgridvalue(const index: integer) virtual abstract; + function gridvaluechecked(const aindex: integer): boolean virtual abstract; + procedure mouseevent(var info: mouseeventinfoty) override; + procedure dokeydown(var info: keyeventinfoty) override; + procedure dokeyup(var info: keyeventinfoty) override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget) override; + procedure statechanged; override; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + procedure modified; override; + procedure checkradiorow(aindex: integer); + function internalcheckeditem(out single: boolean): ttogglegraphdataedit; + //nil if none + function navigrect: rectty; override; + public + constructor create(aowner: tcomponent); override; + property group: integer read fgroup write fgroup default 0; + property checkedrow: integer read getcheckedrow write setcheckedrow; + //needs bo_radiotemcol, -1 if none + property checkedtag: integer read getcheckedtag write setcheckedtag; + //-1 if none checked + published + property options: buttonoptionsty read foptions write setoptions + default defaultbuttonoptions; + property colorglyph; + end; + + tcustombooleanedit = class; + booleaneditarty = array of tcustombooleanedit; + + tcustombooleanedit = class(ttogglegraphdataedit) + private + fvalue: longbool; + fvaluedefault: longbool; + fonsetvalue: setbooleaneventty; + procedure setvalue(const Value: boolean); virtual; + function getglyph: stockglyphty; virtual; + function getgridvalue(const index: integer): longbool; + procedure setgridvalue(const index: integer; const Value: longbool); virtual; + function getgridvalues: longboolarty; + procedure setgridvalues(const Value: longboolarty); + function getgridbooleanvalues: booleanarty; + procedure setgridbooleanvalues(const Value: booleanarty); + function getvalue: boolean; + function getvaluedefault: boolean; + procedure setvaluedefault(const Value: boolean); + {$ifdef mse_with_ifi} + function getifilink: tifibooleanlinkcomp; + procedure setifilink(const avalue: tifibooleanlinkcomp); + {$endif} + protected + class function classskininfo: skininfoty; override; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure setnullvalue; + function getdefaultvalue: pointer; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure resetgridvalue(const index: integer); override; + procedure checkgridvalue(const index: integer); override; + function gridvaluechecked(const aindex: integer): boolean; override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure togglevalue(const areadonly: boolean; + const down: boolean); override; + procedure docheck() override; //set value to not valuedefault + procedure douncheck() override; //set value to valuedefault + function ischecked(): boolean; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure internalcheckvalue(var avalue; var accept: boolean); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function getvaluebitmask: longword; + procedure setvaluebitmask(const avalue: longword); + function getgridvaluebitmask(const index: integer): longword; + procedure setgridvaluebitmask(const index: integer; const avalue: longword); + procedure dokeydown(var info: keyeventinfoty); override; + + function getassistivetext(): msestring override; + public + constructor create(aowner: tcomponent); override; + procedure fillcol(const avalue: longbool); + function checkvalue(const quiet: boolean = false): boolean override; + procedure togglegridvalue(const index: integer); override; + + property value: boolean read getvalue write setvalue default false; + property valuedefault: boolean read getvaluedefault + write setvaluedefault default false; + //streaming of longbool does not work on kylix and fpc + property gridvalue[const index: integer]: longbool + read getgridvalue write setgridvalue; default; + function valuetag(const falsevalue: integer): integer; + function valuetagbit: longword; + //if value -> bits[tag] else -> 0 + function gridvaluetagbit(const index: integer): longword; + //if value -> bits[tag] else -> 0 + property valuebitmask: longword read getvaluebitmask write setvaluebitmask; + //ored valuetagbit of all edits in group + property gridvaluebitmask[const index: integer]: longword + read getgridvaluebitmask write setgridvaluebitmask; + //ored valuetagbit of all edits in group + + function gridvaluetag(const index: integer; + const falsevalue: integer): integer; + //if value = true -> tag, falsevalue otherwise + procedure updatetagvalue(const bitset: integer); + //value -> true if bitset and tag <> 0 + procedure gridupdatetagvalue(const index: integer; const bitset: integer); + property gridvalues: longboolarty read getgridvalues write setgridvalues; + property gridbooleanvalues: booleanarty read getgridbooleanvalues + write setgridbooleanvalues; + function griddata: tgridintegerdatalist; + function groupmembers: booleaneditarty; + function tagitem(const atag: integer): tcustombooleanedit; //nil if none + + property bounds_cx default defaultboxsize; + property bounds_cy default defaultboxsize; + property onsetvalue: setbooleaneventty read fonsetvalue write fonsetvalue; +{$ifdef mse_with_ifi} + property ifilink: tifibooleanlinkcomp read getifilink write setifilink; +{$endif} + published + property visible; + property enabled; + end; + + tbooleanedit = class(tcustombooleanedit) + published + property bounds_cx default defaultboxsize; + property bounds_cy default defaultboxsize; + property onsetvalue; + property value; + property valuedefault; + property group; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + + tcustombooleaneditradio = class(tcustombooleanedit) + private + function getglyph: stockglyphty; override; +// procedure reset; + procedure setvalue(const avalue: boolean) override; + procedure setgridvalue(const aindex: integer; + const aValue: longbool) override; + protected + procedure togglevalue(const areadonly: boolean; + const down: boolean) override; + public + procedure togglegridvalue(const index: integer) override; + function checkeditem: tcustombooleaneditradio; //nil if none + end; + + tbooleaneditradio = class(tcustombooleaneditradio) + published + property bounds_cx default defaultboxsize; + property bounds_cy default defaultboxsize; + property onsetvalue; + property value; + property valuedefault; + property group; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + + tcustomintegergraphdataedit = class; + + paintintegerglypheventty = procedure( + const sender: tcustomintegergraphdataedit; + const acanvas: tcanvas; const avalue: integer; + const arow: integer) of object; + + tcustomintegergraphdataedit = class(ttogglegraphdataedit) + private + fvalue: integer; + fvaluedefault: integer; + fonsetvalue: setintegereventty; + fvaluemin: integer; + fvaluemax: integer; +// fdatalist: tintegerdatalist; + fonpaintglyph: paintintegerglypheventty; + procedure setvalue(const avalue: integer); + function getgridvalue(const index: integer): integer; + procedure setgridvalue(const index, Value: integer); + function getgridvalues: integerarty; + procedure setgridvalues(const Value: integerarty); + {$ifdef mse_with_ifi} + function getifilink: tifiintegerlinkcomp; + procedure setifilink(const avalue: tifiintegerlinkcomp); + {$endif} + procedure setvaluemin(const avalue: integer); + procedure setvaluemax(const avalue: integer); + function getdatalist: tintegerdatalist; + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected +// procedure setgridintf(const intf: iwidgetgrid); override; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + function getdefaultvalue: pointer; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure resetgridvalue(const index: integer); override; + procedure checkgridvalue(const index: integer); override; + function gridvaluechecked(const aindex: integer): boolean; override; + procedure internalcheckvalue(var avalue; var accept: boolean); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure togglevalue(const areadonly: boolean; + const down: boolean); override; + function ischecked(): boolean; override; + procedure docheck() override; //set value to valuedefault+1 + procedure douncheck() override; //set value to valuedefault + function doinc(var avalue: integer; const down: boolean): boolean; + //false if no change + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure datalistdestroyed; override; + procedure updatedatalist; override; + procedure defineproperties(filer: tfiler) override; + public + function checkvalue(const quiet: boolean = false): boolean override; + procedure togglegridvalue(const index: integer); override; + procedure fillcol(const avalue: integer); + property gridvalue[const index: integer]: integer + read getgridvalue write setgridvalue; default; + property gridvalues: integerarty read getgridvalues write setgridvalues; + function griddata: tgridintegerdatalist; + property datalist: tintegerdatalist read getdatalist; + property onsetvalue: setintegereventty read fonsetvalue write fonsetvalue; + property value: integer read fvalue write setvalue default 0; + property valuedefault: integer read fvaluedefault + write fvaluedefault default 0; + property valuemin: integer read fvaluemin write setvaluemin default 0; + //checked by togglevalue + property valuemax: integer read fvaluemax write setvaluemax default 0; + //checked by togglevalue + property onpaintglyph: paintintegerglypheventty read fonpaintglyph + write fonpaintglyph; + published + {$ifdef mse_with_ifi} + property ifilink: tifiintegerlinkcomp read getifilink write setifilink; + {$endif} + end; + + tcustomdatabutton = class; + + tvaluefacearrayprop = class(tpersistentarrayprop) + private + fowner: tcustomdatabutton; + protected + function getitems(const index: integer): tface; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tcustomdatabutton); + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tface read getitems; default; + end; + + databuttoneventty = procedure(const sender: tcustomdatabutton) of object; + + tvaluefontarrayprop = class(tpersistentarrayprop) + private + fowner: tcustomdatabutton; + procedure setitems(const index: integer; const avalue: tfont); + protected + function getitems(const index: integer): tfont; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure fontchange(const sender: tobject); + public + constructor create(const aowner: tcustomdatabutton); + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + property items[const index: integer]: tfont read getitems + write setitems; default; + end; + + tcustomdatabutton = class(tcustomintegergraphdataedit,iactionlink,iimagelistinfo) + private +// fonexecute: notifyeventty; + fvaluefaces: tvaluefacearrayprop; + fimageoffset: integer; + fimagenums: tintegerarrayprop; + fimagenr: integer; + fimagenrdisabled: integer; + fimageoffsetdisabled: integer; + fimageoffsetmouse: integer; + fimageoffsetclicked: integer; + fvaluecaptions: tmsestringarrayprop; + fonupdate: databuttoneventty; + fvaluedisabled: integer; + fvaluefonts: tvaluefontarrayprop; + procedure setcolorglyph(const avalue: colorty); + function iscolorglyphstored: boolean; + procedure setvaluefaces(const avalue: tvaluefacearrayprop); + procedure setvaluecaptions(const avalue: tmsestringarrayprop); + procedure setcaption(const avalue: captionty); + function iscaptionstored: boolean; + function getimagelist: timagelist; + procedure setimagelist(const avalue: timagelist); + function isimageliststored: Boolean; + procedure setcaptiondist(const avalue: integer); + procedure setimagepos(const avalue: imageposty); + procedure setimagenr(const avalue: imagenrty); + function isimagenrstored: boolean; + procedure setimageoffset(const avalue: integer); + procedure setimagenums(const avalue: tintegerarrayprop); + procedure setimagenrdisabled(const avalue: imagenrty); + function isimagenrdisabledstored: Boolean; + procedure setimageoffsetdisabled(const avalue: integer); + procedure setimagedist(const avalue: integer); + procedure setimagedist1(const avalue: integer); + procedure setimagedist2(const avalue: integer); + procedure setshortcut(const avalue: shortcutty); + function isshortcutstored: boolean; + function getshortcut: shortcutty; + function getshortcut1: shortcutty; + procedure setshortcut1(const avalue: shortcutty); + function isshortcut1stored: boolean; + procedure setonexecute(const avalue: notifyeventty); + function isonexecutestored: boolean; + procedure setonbeforeexecute(const avalue: accepteventty); + function isonbeforeexecutestored: boolean; + procedure setonafterexecute(const avalue: notifyeventty); + function isonafterexecutestored: boolean; + procedure setstate(const avalue: actionstatesty); + function isstatestored: boolean; + + procedure setaction(const avalue: tcustomaction); + procedure readcaptionpos(reader: treader); + procedure settextflags(const avalue: textflagsty); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + procedure readshortcut(reader: treader); + procedure readshortcut1(reader: treader); + procedure readsc(reader: treader); + procedure writesc(writer: twriter); + procedure readsc1(reader: treader); + procedure writesc1(writer: twriter); + procedure setimageoffsetmouse(const avalue: integer); + procedure setimageoffsetclicked(const avalue: integer); + procedure setvaluedisabled(const avalue: integer); + procedure setvaluefonts(const avalue: tvaluefontarrayprop); + protected + finfo: shapeinfoty; + factioninfo: actioninfoty; + procedure doidle(var again: boolean); + procedure internalexecute; + procedure doasyncevent(var atag: integer); override; + procedure defineproperties(filer: tfiler); override; + procedure loaded; override; + procedure setenabled(const avalue: boolean); override; + procedure setvisible(const avalue: boolean); override; + + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + procedure gridtovalue(arow: integer); override; + + procedure setcolor(const avalue: colorty); override; + procedure objectchanged(const sender: tobject); override; + function getassistiveflags(): assistiveflagsty override; + function getassistivecaption(): msestring override; + + //iactionlink + function getactioninfopo: pactioninfoty; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + procedure actionchanged; + + procedure setnullvalue; + procedure doexecute; virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure togglevalue(const areadonly: boolean; + const down: boolean); override; + procedure statechanged; override; + function valueenabledstate(const avalue: integer): boolean; + procedure checkdisabled(); + procedure valuechanged(); override; + + procedure mouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + procedure clientrectchanged; override; +// function getframestateflags: framestateflagsty; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure internalcreateframe; override; + procedure setgridintf(const intf: iwidgetgrid); override; + function checkfocusshortcut(var info: keyeventinfoty): boolean; override; + procedure setactualimagenr(const avalue: integer); + procedure setoptions(const avalue: buttonoptionsty); override; + function verticalfontheightdelta: boolean; override; + + class function classskininfo: skininfoty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure execute(); + procedure initnewwidget(const ascale: real); override; + procedure updatehotkeys() override; + procedure doupdate; + procedure synctofontheight; override; + procedure initgridwidget; override; + procedure initnewcomponent(const ascale: real); override; + procedure togglegridvalue(const index: integer); override; + function checkeditem: tcustomdatabutton; //nil if none + property valuefaces: tvaluefacearrayprop read fvaluefaces + write setvaluefaces; + property valuecaptions: tmsestringarrayprop read fvaluecaptions + write setvaluecaptions; + property valuefonts: tvaluefontarrayprop read fvaluefonts + write setvaluefonts; + property font: twidgetfont read getfont write setfont stored isfontstored; + property action: tcustomaction read factioninfo.action write setaction; + property caption: captionty read factioninfo.captiontext write setcaption + stored iscaptionstored; + property textflags: textflagsty read finfo.ca.textflags + write settextflags default defaultcaptiontextflags; + property imagepos: imageposty read finfo.ca.imagepos write setimagepos + default ip_center; +// property captionpos: captionposty read finfo.ca.captionpos write setcaptionpos +// default cp_center; + property captiondist: integer read finfo.ca.captiondist write setcaptiondist + default defaultshapecaptiondist; + property imagelist: timagelist read getimagelist write setimagelist + stored isimageliststored; + property imagenr: imagenrty read factioninfo.imagenr write setimagenr + stored isimagenrstored default -1; + property imagenrdisabled: imagenrty read factioninfo.imagenrdisabled + write setimagenrdisabled + stored isimagenrdisabledstored default -2; + //-1 = none, -2 = grayed, -3 = imageoffsetdisabled + property imagedist: integer read finfo.ca.imagedist + write setimagedist default 0; + property imagedist1: integer read finfo.ca.imagedist1 + write setimagedist1 default 0; + property imagedist2: integer read finfo.ca.imagedist2 + write setimagedist2 default 0; + property colorglyph: colorty read factioninfo.colorglyph write setcolorglyph + stored iscolorglyphstored default cl_default; + property shortcut: shortcutty read getshortcut write setshortcut + stored false default 0; + property shortcut1: shortcutty read getshortcut1 write setshortcut1 + stored false default 0; + property shortcuts: shortcutarty read factioninfo.shortcut + write setshortcuts; + property shortcuts1: shortcutarty read factioninfo.shortcut1 + write setshortcuts1; + property onupdate: databuttoneventty read fonupdate write fonupdate; + property onexecute: notifyeventty read factioninfo.onexecute + write setonexecute stored isonexecutestored; + property onbeforeexecute: accepteventty read factioninfo.onbeforeexecute + write setonbeforeexecute stored isonbeforeexecutestored; + property onafterexecute: notifyeventty read factioninfo.onafterexecute + write setonafterexecute stored isonafterexecutestored; + + property imageoffset: integer read fimageoffset + write setimageoffset default 0; + property imageoffsetdisabled: integer read fimageoffsetdisabled + write setimageoffsetdisabled default 0; + property imageoffsetmouse: integer read fimageoffsetmouse + write setimageoffsetmouse default 0; + property imageoffsetclicked: integer read fimageoffsetclicked + write setimageoffsetclicked default 0; + property imagenums: tintegerarrayprop read fimagenums write setimagenums; + + property options; + property focusrectdist: integer read finfo.focusrectdist + write finfo.focusrectdist default defaultshapefocusrectdist; + property onsetvalue; + property value default -1; + property valuedefault default -1; + property valuedisabled: integer read fvaluedisabled + write setvaluedisabled default -2; + //button.enabled:= value <> valuedisabled + //-2 -> not checked + property valuemin default -1; + property valuemax default 0; + property optionswidget default defaultoptionswidget - [ow_mousefocus]; + published + property visible stored false; + property enabled stored false; + property state: actionstatesty read factioninfo.state write setstate + stored isstatestored default []; + end; + + tdatabutton = class(tcustomdatabutton) + published + property optionswidget; + property optionsskin; + property valuefaces; + property valuecaptions; + property valuefonts; + property font; + + property action; + property caption; + property textflags; + property shortcut; + property shortcut1; + property imagepos; + property captiondist; + property imagelist; + property imagenr; + property imagenrdisabled; + property imagedist; + property imagedist1; + property imagedist2; + property colorglyph; + property options; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + property onmouseevent; + property onclientmouseevent; + + property imageoffset; + property imageoffsetdisabled; + property imageoffsetmouse; + property imageoffsetclicked; + property imagenums; + property onsetvalue; + property onpaintglyph; + property group; + property value; + property valuedefault; + property valuemin; + property valuemax; + property valuedisabled; + end; + + tstockglyphdatabutton = class(tcustomdatabutton) + private + fglyph: stockglyphty; + procedure setglyph(const avalue: stockglyphty); + public + constructor create(aowner: tcomponent); override; + published + property action; + + property glyph: stockglyphty read fglyph write setglyph default stg_none; + property imagenums; + property optionswidget; + property optionsskin; + property valuefaces; + property font; + property caption; + property textflags; + property imagepos; + property captiondist; + property options; + property imagedist; + property imagedist1; + property imagedist2; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + property onsetvalue; + property onpaintglyph; + property onmouseevent; + property onclientmouseevent; + property value; + property valuedefault; + property valuemin; + property valuemax; + property valuedisabled; + end; + + tcustomdataicon = class(tcustomintegergraphdataedit) + //if value = -1 then blank else + // if value < 0 then imagenums[0..30] are painted if bit[0..30] is 1 + // else image[value] is painted + private + fimagelist: timagelist; + fimageoffset: integer; + fimagenums: tintegerarrayprop; + procedure setimagelist(const aValue: timagelist); + procedure setimageoffset(const aValue: integer); + procedure imagenumschanged(const sender: tarrayprop; const index: integer); + procedure setimagenums(const avalue: tintegerarrayprop); + protected + procedure setnullvalue; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property imagelist: timagelist read fimagelist write setimagelist; + property imageoffset: integer read fimageoffset write setimageoffset default 0; + property imagenums: tintegerarrayprop read fimagenums write setimagenums; + property valuedefault default -1; + property value default -1; + published + property visible; + property enabled; + end; + + tdataicon = class(tcustomdataicon) + published + property onsetvalue; + property onpaintglyph; + property value default -1; + property valuedefault default -1; + property valuemin; + property valuemax; + property imagelist; + property imageoffset; + property imagenums; + end; + +implementation +uses + SysUtils,msekeyboard,msebits,msereal,msedispwidgets,mseformatstr,mserichstring, + mseactions,msestreaming,mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustomframe1 = class(tcustomframe); + tdatalist1 = class(tdatalist); + twidgetcol1 = class(twidgetcol); + twidget1 = class(twidget); + tarrayprop1 = class(tarrayprop); + tcustomwidgetgrid1 = class(tcustomwidgetgrid); + twidgetdatacol1 = class(twidgetcol); + +const + valuevarname = 'value'; + +{ tgrapheditframe } + +constructor tgrapheditframe.create(const aintf: icaptionframe); +begin + inherited; + options:= defaultgrapheditframeoptions; + fstate:= fstate + [fs_drawfocusrect,fs_captionfocus,fs_captionhint, + fs_paintrectfocus]; + fi.levelo:= -2; + captionpos:= cp_right; + internalupdatestate; +end; +{ +function tgrapheditframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_transparent; + end; +end; +} +{ +function tgrapheditframe.getdefaultcolorclient: colorty; +begin + result:= cl_transparent; +end; +} +{ ttogglegrapheditframe } + +function ttogglegrapheditframe.actualcolorclient: colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; +{ +function ttogglegrapheditframe.getdefaultcolorclient: colorty; +begin + result:= cl_foreground; +end; +} +{ tsliderscrollbar } + +constructor tsliderscrollbar.create(intf: iscrollbar; org: originty; + ondimchanged: proceventty); +begin + inherited; + foptions:= defaultsliderscrollbaroptions; + buttonlength:= defaultbuttonminlength; +// fface:= tface.create(iface(self)); +end; + +destructor tsliderscrollbar.destroy; +begin + inherited; +end; + +{ +function tsliderscrollbar.getwidget: twidget; +begin + result:= fintf.getwidget; +end; +} +{ +function tsliderscrollbar.translatecolor(const acolor: colorty): colorty; +begin + result:= fintf.translatecolor(acolor); +end; + +procedure tsliderscrollbar.paint(const canvas: tcanvas; + const acolor: colorty = cl_none); +begin + if fface <> nil then begin + fface.paint(canvas,fdrawinfo.scrollrect); + end; + inherited; +end; +} +{ +procedure tsliderscrollbar.invalidate; +begin + fintf.getwidget.invalidate; +end; +} +{ +function tsliderscrollbar.getclientrect: rectty; +begin + result:= fintf.getwidget.clientrect; +end; +} +{ +procedure tsliderscrollbar.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + twidget1(fintf.getwidget).setlinkedvar(source,dest,linkintf); +end; +} +{ +function tsliderscrollbar.getcomponentstate: tcomponentstate; +begin + result:= fintf.getwidget.componentstate; +end; +} +{ +procedure tsliderscrollbar.widgetregioninvalid; +begin + twidget1(fintf.getwidget).widgetregioninvalid; +end; +} +{ tcustomrealgraphdataedit } + +constructor tcustomrealgraphdataedit.create(aowner: tcomponent); +begin + inherited; + size:= makesize(defaultsliderwidth,defaultsliderheight); +end; + +procedure tcustomrealgraphdataedit.setvalue(const avalue: realty); +begin + if fvalue <> avalue then begin + if not (des_isdb in fstate) and (avalue = emptyreal) then begin + fvalue:= 0; + end + else begin + fvalue:= avalue; + end; + valuechanged; + end; +end; + +function tcustomrealgraphdataedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridrealdatalist.create(sender); +end; + +function tcustomrealgraphdataedit.getdatalistclass: datalistclassty; +begin + result:= tgridrealdatalist; +end; + +procedure tcustomrealgraphdataedit.internalcheckvalue(var avalue; var accept: boolean); +begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,realty(avalue),accept); + end; +{$ifdef mse_with_ifi} + ifisetvalue(avalue,accept); +{$endif} + if accept then begin + value:= realty(avalue); + end; +end; + +procedure tcustomrealgraphdataedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomrealgraphdataedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomrealgraphdataedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readreal(valuevarname,fvalue); +end; + +procedure tcustomrealgraphdataedit.writestatvalue(const writer: tstatwriter); +begin + writer.writereal(valuevarname,fvalue); +end; + +procedure tcustomrealgraphdataedit.setdirection(const avalue: graphicdirectionty); +begin + if fdirection <> avalue then begin + if not (csreading in componentstate) then begin + changedirection(avalue,fdirection); + end + else begin + fdirection:= avalue; + end; + end; +end; + +function tcustomrealgraphdataedit.getgridvalue(const index: integer): realty; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomrealgraphdataedit.setgridvalue(const index: integer; + const avalue: realty); +begin + internalsetgridvalue(index,avalue); +end; + +function tcustomrealgraphdataedit.getgridvalues: realarty; +begin + result:= trealdatalist(checkgriddata).asarray; +end; + +procedure tcustomrealgraphdataedit.setgridvalues(const avalue: realarty); +begin + trealdatalist(checkgriddata).asarray:= avalue; +end; + +procedure tcustomrealgraphdataedit.fillcol(const value: realty); +begin + internalfillcol(value); +end; + +procedure tcustomrealgraphdataedit.assigncol(const avalue: trealdatalist); +begin + internalassigncol(avalue); +end; + +function tcustomrealgraphdataedit.isnull: boolean; +begin + result:= value = emptyreal; +end; + +procedure tcustomrealgraphdataedit.setnullvalue; +begin + value:= emptyreal; +end; + +function tcustomrealgraphdataedit.checkvalue( + const quiet: boolean = false): boolean; +begin + result:= docheckvalue(fvalue,quiet); +end; + +{$ifdef mse_with_ifi} +function tcustomrealgraphdataedit.getifilink: tifireallinkcomp; +begin + result:= tifireallinkcomp(fifilink); +end; + +procedure tcustomrealgraphdataedit.setifilink(const avalue: tifireallinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +function tcustomrealgraphdataedit.griddata: tgridrealdatalist; +begin + result:= tgridrealdatalist(inherited griddata); +end; + +procedure tcustomrealgraphdataedit.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; const arect: rectty); +var + int1: integer; + val1: real; +begin + if canevent(tmethod(fonpaintglyph)) then begin + if @avalue = nil then begin + val1:= fvalue; + int1:= gridrow; + end + else begin + val1:= real(avalue); + int1:= pcellinfoty(canvas.drawinfopo)^.cell.row; + end; + fonpaintglyph(self,canvas,val1,int1); + end; +end; + +procedure tcustomrealgraphdataedit.internalcreateframe; +begin + tsliderframe.create(iscrollframe(self)); +end; + +procedure tcustomrealgraphdataedit.setvaluedata(const source); +begin + value:= realty(source); +end; + +procedure tcustomrealgraphdataedit.getvaluedata(out dest); +begin + realty(dest):= value; +end; + +{ tcustomslider } + +constructor tcustomslider.create(aowner: tcomponent); +begin + fscrollbar:= tsliderscrollbar.create(iscrollbar(self)); +// fscrollbar.options:= [sbo_moveauto]; + inherited; + optionswidget:= defaultslideroptionswidget; + size:= makesize(defaultsliderwidth,defaultsliderheight); +end; + +destructor tcustomslider.destroy; +begin + fscrollbar.Free; + inherited; +end; + +procedure tcustomslider.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; const arect: rectty); +var + rea1,rea2: realty; + col1: colorty; + bo1: boolean; +begin + bo1:= false; + col1:= cl_none; + if @avalue = nil then begin + rea1:= fvalue; + end + else begin + rea1:= realty(avalue); //cell + if (fgridintf <> nil) then begin + with cellinfoty(canvas.drawinfopo^) do begin + col1:= color; + canvas.move(innerrect.pos); + end; + end + else begin + if fparentintf <> nil then begin + canvas.move(arect.pos); //innerrext? + end; + end; + end; + if rea1 = emptyreal then begin + rea1:= 0; + end; + beginpaint(); + rea2:= fscrollbar.value; + if @avalue <> nil then begin //cell + fscrollbar.value:= rea1; + bo1:= fscrollbar.focused; + fscrollbar.focused:= false; + end + else begin + if not fscrollbar.buttonmoving then begin + fscrollbar.value:= rea1; + rea2:= rea1; + end; + end; + fscrollbar.paint(canvas,col1); + fscrollbar.value:= rea2; + if @avalue <> nil then begin + fscrollbar.focused:= bo1; + if (fgridintf <> nil) then begin + canvas.remove(cellinfoty(canvas.drawinfopo^).innerrect.pos); + end + else begin + canvas.remove(arect.pos); //innerrext? + end; + end; + endpaint(); + inherited; +end; + +procedure tcustomslider.setdirection(const avalue: graphicdirectionty); +begin + fscrollbar.direction:= avalue; + inherited; +end; + +procedure tcustomslider.clientrectchanged; +begin + inherited; + fscrollbar.dim:= innerclientrect; +end; + +procedure tcustomslider.clientmouseevent(var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) and + not (csdesigning in componentstate) and + not (oe_readonly in getoptionsedit) then begin + fscrollbar.mouseevent(info); + end; + inherited; +end; + +procedure tcustomslider.domousewheelevent(var info: mousewheeleventinfoty); +begin + scrollbar.mousewheelevent(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomslider.dokeydown(var info: keyeventinfoty); +begin + if not (es_processed in info.eventstate) and + not (csdesigning in componentstate) and + not (oe_readonly in getoptionsedit) then begin + fscrollbar.keydown(info); + end; + inherited; +end; + +procedure tcustomslider.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +var + rea1: realty; +begin + case event of + sbe_setvalue{valuechanged}: begin + if fupdating = 0 then begin + inc(fupdating); + rea1:= sender.value; + if not docheckvalue(rea1,false) then begin + sender.value:= value; + end + else begin + sender.value:= rea1; + end; + dec(fupdating); + end; + end; + end; +end; + +procedure tcustomslider.doenter; +begin + fscrollbar.enter; + inherited; +end; + +procedure tcustomslider.doexit; +begin + fscrollbar.exit; + inherited; +end; + +procedure tcustomslider.activechanged; +begin + fscrollbar.activechanged(); + inherited; +end; + +procedure tcustomslider.enabledchanged; +begin + fscrollbar.disabled:= not enabled; +end; + +procedure tcustomslider.setscrollbar(const avalue: tsliderscrollbar); +begin + fscrollbar.assign(avalue); +end; + +procedure tcustomslider.beginpaint(); +begin + inc(fupdating); + inc(fnoinvalidate); +end; + +procedure tcustomslider.endpaint(); +begin + dec(fupdating); + dec(fnoinvalidate); +end; + +procedure tcustomslider.dochange; +begin + inc(fupdating); + fscrollbar.value:= fvalue; + dec(fupdating); + inherited; +end; + +procedure tcustomslider.objectchanged(const sender: tobject); +begin + inherited; + fscrollbar.checktemplate(sender); +end; + +procedure tcustomslider.initgridwidget; +begin + inherited; + fscrollbar.options:= fscrollbar.options + + [sbo_noarrowkeys,sbo_nopagekeys,sbo_noreflectedclick]; +// color:= cl_parent; + if fgridintf <> nil then begin + with fgridintf.getcol do begin + if self.color = cl_default then begin + color:= cl_parent; + end + else begin + color:= self.color; + end; + options:= options - [co_drawfocus]; + end; + end; +end; + +class function tcustomslider.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_slider; +end; + +{ tgraphdataedit } + +constructor tgraphdataedit.create(aowner: tcomponent); +begin + foptionsedit:= defaultoptionsedit; + foptionsedit1:= defaultoptionsedit1; + inherited; + fcolorglyph:= cl_default; +end; + +procedure tgraphdataedit.internalcreateframe; +begin + tgrapheditframe.create(iscrollframe(self)); +end; + +procedure tgraphdataedit.enabledchanged(); +begin + inherited; + invalidate(); +end; + +procedure tgraphdataedit.setcolorglyph(const Value: colorty); +begin + if fcolorglyph <> value then begin + fcolorglyph := Value; + invalidate; + end; +end; + +procedure tgraphdataedit.paint(const canvas: tcanvas); +begin + if (fgridintf = nil) or + not (twidgetcol1(fgridintf.getcol).checkautocolwidth) then begin + inherited; + end; +end; + +procedure tgraphdataedit.dopaintforeground(const canvas: tcanvas); +var + col1: colorty; +begin + inherited; + col1:= fcolorglyph; + if col1 = cl_font then begin + if (fgridintf <> nil) and (ffont = nil) then begin + with fgridintf.getcol do begin + col1:= rowfont(grid.row).color; + end; + end + else begin + col1:= getfont1.color; + end; + end; + if (innerclientrect.cx > 0) and (innerclientrect.cy > 0) then begin + paintglyph(canvas,col1,nil^,innerclientrect); + end; + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + fgridintf.widgetpainted(canvas); + end; +end; + +function tgraphdataedit.needsfocuspaint: boolean; +begin + result:= (fgridintf = nil) and inherited needsfocuspaint; +end; + +procedure tgraphdataedit.dofontheightdelta(var delta: integer); +begin + inherited; + gridwidgetfontheightdelta(self,fgridintf,delta); +end; + +procedure tgraphdataedit.sizechanged; +begin + inherited; + gridwidgetsized(self,fgridintf); +end; + +procedure tgraphdataedit.dochange; +begin + if not (ws_loadedproc in fwidgetstate) then begin + if assistiveserver <> nil then begin + assistiveserver.dochange(getiassistiveclient()); + end; + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; +{$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + iifidataserver(fifiserverintf).valuechanged(iifidatalink(self)); + end; +{$endif} + end; + invalidate; +end; + +procedure tgraphdataedit.setgridintf(const intf: iwidgetgrid); +begin + fgridintf:= intf; + if fgridintf <> nil then begin + fdatalist:= fgridintf.getcol.datalist; + if fdatalist <> nil then begin + updatedatalist; + end; + fgriddatalink:= tcustomwidgetgrid1(fgridintf.getgrid).getgriddatalink; + end + else begin + fdatalist:= nil; + fgriddatalink:= nil; + end; + {$ifdef mse_with_ifi} +{ + if fgridintf <> nil then begin + if (fifilink <> nil) and (fifilink.controller.datalist <> nil) then begin + updateifigriddata(fifilink.controller.datalist); + end; + end; +} +{$endif} + +end; + +function tgraphdataedit.getcellframe: framety; +begin + if fframe <> nil then begin + result:= fframe.cellframe; + end + else begin + result:= nullframe; + end; +end; + +function tgraphdataedit.needscellfocuspaint(): boolean; +begin + result:= inherited needsfocuspaint(); +end; + +procedure tgraphdataedit.drawcell(const canvas: tcanvas); +var + col1: colorty; + rect1: rectty; +begin + with cellinfoty(canvas.drawinfopo^) do begin + if datapo <> nil then begin + col1:= fcolorglyph; + if col1 = cl_font then begin + col1:= font.color; + end; + if (fgridintf = nil) and (fparentintf <> nil) and + (oe1_nocellpaint in optionsedit1) then begin + if (fwidgetrect.cx > 0) and (fwidgetrect.cy > 0) then begin + paintbackground(canvas,widgetrect); + rect1:= self.innerparentrect; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + paintglyph(canvas,col1,datapo^,rect1); + end; + paintoverlay(canvas,widgetrect); + end; + end + else begin + if (innerrect.cx > 0) and (innerrect.cy > 0) then begin + paintglyph(canvas,col1,datapo^,innerrect); + end; + end; + end; + end; +end; + +procedure tgraphdataedit.updateautocellsize(const canvas: tcanvas); +begin + //dummy; +end; + +procedure tgraphdataedit.initgridwidget; +begin + defaultinitgridwidget(self,fgridintf); + if fgridintf <> nil then begin + fgridintf.getcol.options:= fgridintf.getcol.options + [co_drawfocus]; + end; +end; + +function tgraphdataedit.docheckvalue(var avalue; const quiet: boolean): boolean; +begin + if fgridintf <> nil then begin + fgridintf.edited(); + end; + result:= true; + internalcheckvalue(avalue,result); + if result then begin + fedited:= false; + if fparentintf <> nil then begin + fparentintf.childdataentered(igridwidget(self)); + end; + if canevent(tmethod(fondataentered)) then begin + fondataentered(self); + end; + {$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.dataentered(iifidatalink(self),gridrow); + end; + {$endif} + if (oe1_sendchangeeventbycheckvalue in optionsedit1) then begin + sendchangeevent(); + end; + if canassistive() and not quiet then begin + assistiveserver.dodataentered(iassistiveclientdata(getiassistiveclient())); + end; + end; +end; + +procedure tgraphdataedit.dofocus; +begin + if fparentintf <> nil then begin + fparentintf.childfocused(igridwidget(self)); + end; + inherited; +end; + +{ +function tgraphdataedit.edited: boolean; +begin + result:= fedited; +end; +} +procedure tgraphdataedit.initeditfocus; +begin + //dummy +end; + +procedure tgraphdataedit.initnewwidget(const ascale: real); +begin + if fgridintf <> nil then begin + fgridintf.getcol.options:= + fgridintf.getcol.grid.datacols.options + [co_drawfocus]; + //restore default options + end; + inherited; +end; + +function tgraphdataedit.actualcolor: colorty; +begin + if (fgridintf <> nil) and (fcolor = cl_default) then begin + result:= fgridintf.getcol.rowcolor(fgridintf.getrow); + end + else begin + result:= inherited actualcolor; + end; +end; + +procedure tgraphdataedit.initnewcomponent(const ascale: real); +begin + inherited; + internalcreateframe; + fframe.scale(ascale); +end; + +function tgraphdataedit.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tgraphdataedit.dostatread(const reader: tstatreader); +begin + fvalueread:= false; + if not (des_isdb in fstate) and (fgridintf = nil) and + canstatvalue(foptionsedit1,reader) then begin + fvalueread:= true; + readstatvalue(reader); + end; + if canstatstate(foptionsedit1,reader) then begin + readstatstate(reader); + end; + if canstatoptions(foptionsedit1,reader) then begin + readstatoptions(reader); + end; +end; + +procedure tgraphdataedit.dostatwrite(const writer: tstatwriter); +begin + if not (des_isdb in fstate) and (fgridintf = nil) and + canstatvalue(foptionsedit1,writer) then begin + writestatvalue(writer); + end; + if canstatstate(foptionsedit1,writer) then begin + writestatstate(writer); + end; + if canstatoptions(foptionsedit1,writer) then begin + writestatoptions(writer); + end; +end; + +procedure tgraphdataedit.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tgraphdataedit.statreading; +begin + //dummy +end; + +procedure tgraphdataedit.statread; +begin + if (oe1_checkvalueafterstatread in foptionsedit1) and fvalueread then begin + checkvalue(true); + end; +end; + +procedure tgraphdataedit.setfirstclick(var ainfo: mouseeventinfoty); +begin + //dummy +end; + +function tgraphdataedit.getdefaultvalue: pointer; +begin + result:= nil; +end; + +function tgraphdataedit.getrowdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +function tgraphdataedit.getgridintf: iwidgetgrid; +begin + result:= fgridintf; +end; + +procedure tgraphdataedit.checkgrid; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; +end; + +function tgraphdataedit.checkgriddata: tdatalist; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; + result:= fdatalist; + if result = nil then begin + raise exception.Create('No datalist.'); + end; +end; + +function tgraphdataedit.seteditfocus: boolean; +begin + if not readonly then begin + if fgridintf = nil then begin + if canfocus then begin + setfocus; + end; + end + else begin + with fgridintf.getcol do begin + grid.col:= index; + if grid.canfocus then begin + if not focused then begin + grid.setfocus; + end; + end; + end; + end; + end; + result:= focused; +end; + +function tgraphdataedit.griddata: tdatalist; +begin + checkgrid; + result:= fdatalist; +end; + +function tgraphdataedit.widgetcol: twidgetcol; +begin + if fgridintf = nil then begin + result:= nil; + end + else begin + result:= fgridintf.getcol; + end; +end; + +function tgraphdataedit.grid: tcustomwidgetgrid; +begin + if fgridintf = nil then begin + result:= nil; + end + else begin + result:= fgridintf.getgrid; + end; +end; + +function tgraphdataedit.gridrow: integer; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.row; + end; +end; + +function tgraphdataedit.gridrowhigh: int32; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.rowhigh; + end; +end; + +function tgraphdataedit.griddatarowhigh: int32; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.datarowhigh; + end; +end; + +function tgraphdataedit.gridcol: integer; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.index; + end; +end; + +procedure tgraphdataedit.gridtovalue(row: integer); +begin + invalidate; + //dochange; +end; + +function tgraphdataedit.getnulltext: msestring; +begin + result:= ''; +end; + +function tgraphdataedit.getassistivecelltext(const arow: int32): msestring; +begin + result:= ''; +end; + +procedure tgraphdataedit.readstatoptions(const reader: tstatreader); +begin + //dummy +end; + +procedure tgraphdataedit.readstatstate(const reader: tstatreader); +begin + //dummy +end; + +procedure tgraphdataedit.readstatvalue(const reader: tstatreader); +begin + //dummy +end; + +procedure tgraphdataedit.writestatoptions(const writer: tstatwriter); +begin + //dummy +end; + +procedure tgraphdataedit.writestatstate(const writer: tstatwriter); +begin + //dummy +end; + +procedure tgraphdataedit.writestatvalue(const writer: tstatwriter); +begin + //dummy +end; + +function tgraphdataedit.geteditstate: dataeditstatesty; +begin + result:= fstate; +end; + +procedure tgraphdataedit.seteditstate(const avalue: dataeditstatesty); +begin + fstate:= avalue; +end; +{ +procedure tgraphdataedit.setisdb; +begin + fisdb:= true; +end; +} +function tgraphdataedit.getoptionsedit: optionseditty; +begin + result:= foptionsedit; +{$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.updateoptionsedit(result); + end; +{$endif} +end; + +procedure tgraphdataedit.updateoptions; +begin + //dummy +end; + +procedure tgraphdataedit.setoptionsedit(const avalue: optionseditty); +begin + if foptionsedit <> avalue then begin + transferoptionsedit(self,avalue,foptionsedit,foptionsedit1); + //move deprecated flags + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,foptionsedit1); + end; + updateoptions; + end; +end; + +procedure tgraphdataedit.setoptionsedit1(const avalue: optionsedit1ty); +begin + if foptionsedit1 <> avalue then begin + foptionsedit1:= avalue; + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,foptionsedit1); + end; + updateoptions; + end; +end; + +function tgraphdataedit.sortfunc(const l, r): integer; +begin + result:= tdatalist1(twidgetcol1(fgridintf.getcol).fdata).compare(l,r); +end; + +procedure tgraphdataedit.internalgetgridvalue(index: integer; + out value); +begin + checkgrid; + fgridintf.getdata(index,value); +end; + +procedure tgraphdataedit.internalsetgridvalue(index: integer; + const avalue); +begin + checkgrid; + fgridintf.setdata(index,avalue); +end; + +procedure tgraphdataedit.docellevent(const ownedcol: boolean; var info: celleventinfoty); +begin + //dummy +end; + +procedure tgraphdataedit.valuechanged(); +begin + if not (csloading in componentstate) then begin + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + valuetogrid(fgridintf.getrow); + end; + if not (ws_loadedproc in fwidgetstate) then begin + modified; + end; + dochange; + end; +end; + +procedure tgraphdataedit.formatchanged(); +begin + if not (csloading in componentstate) then begin + if fgridintf <> nil then begin + fgridintf.changed; + end; + invalidate(); + checkautosize(); + end; +end; + +procedure tgraphdataedit.loaded(); +begin + inherited; + include(fwidgetstate,ws_loadedproc); + try + valuechanged; + formatchanged; + finally + exclude(fwidgetstate,ws_loadedproc); + end; +end; + +procedure tgraphdataedit.gridvaluechanged(const index: integer); +begin + //dummy +end; + +procedure tgraphdataedit.updatecoloptions(const aoptions: coloptionsty); +var + opt1: optionseditty; + opt2: optionsedit1ty; +begin + opt1:= foptionsedit; + opt2:= foptionsedit1; + fgridintf.coloptionstoeditoptions(opt1,opt2); + optionsedit:= opt1; + optionsedit1:= opt2; +end; + +procedure tgraphdataedit.updatecoloptions1(const aoptions: coloptions1ty); +begin + //dummy +end; + +procedure tgraphdataedit.statdataread; +begin + //dummy +end; + +procedure tgraphdataedit.griddatasourcechanged; +begin + //dummy +end; + +procedure tgraphdataedit.updatereadonlystate; +begin + //dummy +end; + +procedure tgraphdataedit.internalfillcol(const value); +begin + with tdatalist1(checkgriddata) do begin + internalfill(count,value); + end; +end; + +procedure tgraphdataedit.internalassigncol(const value); +begin + checkgrid; + with fgridintf.getcol do begin + datalist.Assign(tdatalist(value)); + end; +end; + +procedure tgraphdataedit.setenabled(const avalue: boolean); +begin + inherited; + if (fgridintf <> nil) and not (csloading in componentstate){ and + not (des_noenablesync in fstate)} then begin + fgridintf.getcol.enabled:= avalue; + end; +end; + +function tgraphdataedit.getreadonly: boolean; +begin + result:= oe_readonly in foptionsedit; +end; + +procedure tgraphdataedit.setreadonly(const avalue: boolean); +begin + if avalue then begin + optionsedit:= optionsedit + [oe_readonly]; + end + else begin + optionsedit:= optionsedit - [oe_readonly]; + end; +end; + +procedure tgraphdataedit.beforecelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; + +procedure tgraphdataedit.aftercelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; + +procedure tgraphdataedit.fontchanged; +begin + inherited; + if fcolorglyph = cl_font then begin + invalidate; + end; +end; + +procedure tgraphdataedit.modified; +begin + //dummy +end; + +function tgraphdataedit.getcellcursor(const arow: integer; + const acellzone: cellzonety; const apos: pointty): cursorshapety; +begin + result:= actualcursor(nullpoint); +end; + +procedure tgraphdataedit.updatecellzone(const arow: integer; + const apos: pointty; var result: cellzonety); +begin + //dummy +end; + +procedure tgraphdataedit.datalistdestroyed; +begin + fdatalist:= nil; +end; + +{$ifdef mse_with_ifi} +function tgraphdataedit.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +function tgraphdataedit.getifilink: tifilinkcomp; +begin + result:= fifilink; +end; + +function tgraphdataedit.getifidatatype(): listdatatypety; +begin + result:= getdatalistclass().datatype(); +end; + +procedure tgraphdataedit.setifilink(const avalue: tifilinkcomp); +begin + mseificomp.setifilinkcomp(iifidatalink(self),avalue,tifilinkcomp(fifilink)); +end; + +procedure tgraphdataedit.ifisetvalue(var avalue; var accept: boolean); +begin + if accept and (fifiserverintf <> nil) then begin + iifidataserver(fifiserverintf).setvalue( + iifidatalink(self),avalue,accept,gridrow); + end; +end; + +procedure tgraphdataedit.getifivalue(var avalue); +begin + //dummy +end; + +procedure tgraphdataedit.setifivalue(const avalue); +begin + //dummy +end; +{ +function tgraphdataedit.ifigriddata: tdatalist; +begin + result:= nil; + if fgridintf <> nil then begin + result:= fdatalist; + end; +end; +} +procedure tgraphdataedit.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + if fgridintf <> nil then begin + fgridintf.updateifigriddata(alist); + end; +end; + +function tgraphdataedit.getgriddata: tdatalist; +begin + result:= nil; + if fgridintf <> nil then begin + result:= fdatalist; + end; +end; + +function tgraphdataedit.getvalueprop: ppropinfo; +begin + result:= getpropinfo(self,'value'); +end; + +function tgraphdataedit.getiassistiveclient(): iassistiveclient; +begin + result:= iassistiveclientgridwidget(self); +end; + +function tgraphdataedit.getifidatalinkintf(): iifidatalink; +begin + result:= iifidatalink(self); +end; + +function tgraphdataedit.getassistiveflags: assistiveflagsty; +begin + result:= inherited getassistiveflags; + result:= result + [asf_graphicedit]; + if readonly then begin + include(result,asf_readonly); + end; + if fgridintf <> nil then begin + include(result,asf_gridwidget); + end; +end; + +function tgraphdataedit.getassistivecolumncaption(): msestring; +begin + result:= ''; + if fgridintf <> nil then begin + result:= fgridintf.getcol.defaultcaption(); + end; +end; + +function tgraphdataedit.getdefaultifilink: iificlient; +begin + result:= iifidatalink(self); +end; +{$endif mse_with_ifi} + +function tgraphdataedit.getedited: boolean; +begin + result:= fedited; +end; + +procedure tgraphdataedit.setedited(const avalue: boolean); +begin + fedited:= avalue; +end; + +procedure tgraphdataedit.updatedatalist; +begin + //dummy +end; + +function tgraphdataedit.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tgraphdataedit.setparentgridwidget(const intf: igridwidget); +begin + fparentintf:= intf; +end; + +procedure tgraphdataedit.childdataentered(const sender: igridwidget); +begin + //dummy +end; + +procedure tgraphdataedit.childfocused(const sender: igridwidget); +begin + //dummy +end; + +{ ttogglegraphdataedit} + +constructor ttogglegraphdataedit.create(aowner: tcomponent); +begin + fclickedrow:= -1; + foptions:= defaultbuttonoptions; + inherited; +end; + +procedure ttogglegraphdataedit.internalcreateframe; +begin + ttogglegrapheditframe.create(iscrollframe(self)); +end; + +procedure ttogglegraphdataedit.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if (aso_returntogglevalue in assistiveoptions) and + (shiftstate * keyshiftstatesmask = []) and + (bo_executeonkey in foptions) and (isenterkey(self,key)) then begin + include(eventstate,es_processed); + togglevalue(oe_readonly in getoptionsedit,false); + end; + end; + inherited; +end; + +procedure ttogglegraphdataedit.dokeyup(var info: keyeventinfoty); +begin + with info do begin + if (key = key_space) and (shiftstate*keyshiftstatesmask = []) and + (bo_executeonkey in foptions) then begin + include(eventstate,es_processed); + togglevalue(oe_readonly in getoptionsedit,false); + end; + end; + inherited; +end; + +procedure ttogglegraphdataedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + if (bo_executeonshortcut in foptions) and checkfocusshortcut(info) then begin + include(info.eventstate,es_processed); + togglevalue(oe_readonly in getoptionsedit,false); + if (bo_focusonshortcut in foptions) and canfocus then begin + setfocus; + end; + end; + if not (es_processed in info .eventstate) then begin + inherited; + end; +end; + +procedure ttogglegraphdataedit.mouseevent(var info: mouseeventinfoty); +var + bo1: boolean; +begin + bo1:= not (csdesigning in componentstate) and + iswidgetclick(info,fcheckcaption) and (bo_executeonclick in foptions); + inherited; + if bo1 and not (des_disabled in fstate) then begin + //twidgetgrid needs childmouseevent + togglevalue(oe_readonly in getoptionsedit,false); + end; +end; + +procedure ttogglegraphdataedit.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +var + clickedrowbefore: integer; +begin + inherited; + if (bo_resetcheckedonrowexit in foptions) and isrowchange(info) and + (info.newcell.row <> checkedrow) then begin + checkedrow:= -1; + end; + if ownedcol and (info.eventkind in + [cek_buttonpress,cek_buttonrelease,cek_mouseleave]) then begin + clickedrowbefore:= fclickedrow; + case info.eventkind of + cek_mouseleave: begin + fclickedrow:= -1; + end; + cek_buttonpress: begin + if (bo_executeonclick in foptions) and + (info.mouseeventinfopo^.shiftstate*keyshiftstatesmask = []) and + (info.mouseeventinfopo^.button = mb_left) and + enabled and not (des_disabled in fstate) and not readonly then begin + fclickedrow:= info.cell.row; + end; + end; + cek_buttonrelease: begin + if {not info.processed and} not focused and (fclickedrow >= 0) then begin + togglegridvalue(fclickedrow); + checkradiorow(fclickedrow); + end; + fclickedrow:= -1; + end; + end; + if fclickedrow <> clickedrowbefore then begin + fgridintf.getcol.grid.invalidatecell(info.cell); + end; + end; +end; + +procedure ttogglegraphdataedit.statechanged; +begin + if not enabled then begin + fclickedrow:= -1; + end; + inherited; +end; + +procedure ttogglegraphdataedit.setoptions(const avalue: buttonoptionsty); +begin + foptions:= avalue; +end; + +procedure ttogglegraphdataedit.resetradioitems(); +var + int1: int32; + widget1: twidget; +begin + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget1:= fparentwidget.widgets[int1]; + if (widget1 is self.classtype) and (widget1 <> self) and + (ttogglegraphdataedit(widget1).fgroup = fgroup) then begin + with ttogglegraphdataedit(widget1) do begin + inc(fresetting); + try + douncheck(); + finally + dec(fresetting); + end; + end; + end; + end; + end; +end; + +procedure ttogglegraphdataedit.checkradiorow(aindex: integer); +var + datalist1: tdatalist; + int1: integer; +begin + if (fgridintf <> nil) and (bo_radioitemcol in foptions) then begin + if aindex < 0 then begin + aindex:= fgridintf.grid.row; + end; + datalist1:= fgridintf.getcol.datalist; + int1:= datalist1.checkeditem; + if gridvaluechecked(aindex) then begin + if (int1 >= 0) and (int1 <> aindex) then begin + resetgridvalue(int1); + end; + datalist1.checkeditem:= aindex; + end + else begin + if (int1 >= 0) and (int1 = aindex) then begin + datalist1.checkeditem:= -1; + end; + end; + end; +end; + +function ttogglegraphdataedit.internalcheckeditem( + out single: boolean): ttogglegraphdataedit; //nil if none +var + widget: twidget; + int1,int2: integer; +begin + result:= nil; + int2:= 0; + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget:= fparentwidget.widgets[int1]; + if (widget is self.classtype{tcustombooleaneditradio}) then begin + with ttogglegraphdataedit(widget) do begin + if (fgroup = self.fgroup) and ischecked() then begin + inc(int2); + if result <> nil then begin + break; + end; + result:= ttogglegraphdataedit(widget); + end; + end; + end; + end; + end + else begin + if ischecked() then begin + result:= self; + end; + end; + single:= int2 <= 1; +end; + +procedure ttogglegraphdataedit.modified; +begin + checkradiorow(-1); + inherited; +end; + +function ttogglegraphdataedit.getcheckedrow: integer; +begin + result:= -1; + if (fgridintf <> nil) and (bo_radioitemcol in foptions) then begin + if fdatalist <> nil then begin + result:= fdatalist.checkeditem; + end; + end; +end; + +procedure ttogglegraphdataedit.setcheckedrow(const avalue: integer); +begin + if checkedrow <> avalue then begin + if (fgridintf <> nil) and (bo_radioitemcol in foptions) then begin + if fdatalist <> nil then begin + if avalue < 0 then begin + if fdatalist.checkeditem >= 0 then begin + resetgridvalue(fdatalist.checkeditem); + fdatalist.checkeditem:= -1; + end; + end + else begin + checkgridvalue(avalue); + checkradiorow(avalue); + end; + end; + end; + end; +end; + +function ttogglegraphdataedit.getcheckedtag: integer; +var + item: ttogglegraphdataedit; + bo1: boolean; +begin + item:= internalcheckeditem(bo1); + if item <> nil then begin + result:= item.Tag; + end + else begin + result:= -1; + end; +end; + +procedure ttogglegraphdataedit.setcheckedtag(const avalue: integer); +var + widget: twidget; + item: ttogglegraphdataedit; + int1: integer; + bo1: boolean; +begin + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget:= fparentwidget.widgets[int1]; + if (widget is self.classtype) and + (ttogglegraphdataedit(widget).fgroup = fgroup) and + (widget.tag = avalue) then begin + ttogglegraphdataedit(widget).docheck(); + exit; + end; + end; + item:= internalcheckeditem(bo1); + if item <> nil then begin + item.douncheck(); + end; + end; +end; + +function ttogglegraphdataedit.navigrect: rectty; +var + p1: captionposty; +begin + result:= widgetsizerect; + if (fframe <> nil) then begin + p1:= tcaptionframe(fframe).captionpos; + if p1 in rightcaptionpos then begin + result.x:= paintpos.x; + end; + if p1 in bottomcaptionpos then begin + result.y:= paintpos.y; + end; + end; +end; + +{ tcustombooleanedit } + +procedure tcustombooleanedit.internalcheckvalue(var avalue; var accept: boolean); +var + bo1: boolean; +begin + if canevent(tmethod(fonsetvalue)) then begin + bo1:= longbool(avalue); + fonsetvalue(self,bo1,accept); + longbool(avalue):= bo1; + end; +{$ifdef mse_with_ifi} + ifisetvalue(avalue,accept); +{$endif} + if accept then begin + value:= longbool(avalue); + end; +end; + +procedure tcustombooleanedit.togglevalue(const areadonly: boolean; + const down: boolean); +var + bo1: longbool; +begin + if not areadonly then begin + bo1:= not fvalue; + fedited:= true; + docheckvalue(bo1,false); + end; +end; + +procedure tcustombooleanedit.docheck(); +begin + value:= not valuedefault; +end; + +procedure tcustombooleanedit.douncheck(); +begin + value:= valuedefault; +end; + +function tcustombooleanedit.ischecked(): boolean; +begin + result:= fvalue; +end; + +procedure tcustombooleanedit.togglegridvalue(const index: integer); +begin + gridvalue[index]:= not gridvalue[index]; +end; + +constructor tcustombooleanedit.create(aowner: tcomponent); +begin + fcheckcaption:= true; + inherited; + size:= makesize(defaultboxsize,defaultboxsize); +end; + +function tcustombooleanedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridintegerdatalist.create(sender); +end; + +function tcustombooleanedit.getdatalistclass: datalistclassty; +begin + result:= tgridintegerdatalist; +end; + +function tcustombooleanedit.getglyph: stockglyphty; +begin + result:= stg_checked; +end; + +procedure tcustombooleanedit.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; + const arect: rectty); +var + bo1: boolean; + co1: colorty; +begin + if @avalue = nil then begin + bo1:= fvalue; + end + else begin + bo1:= boolean(avalue); + end; + co1:= acolorglyph; + if co1 = cl_default then begin + co1:= cl_glyph; + end; + if (bo_coloractive in foptions) and active then begin + canvas.fillrect(arect,cl_selectedtextbackground); + co1:= cl_selectedtext; + end; + if bo1 xor (bo_reversed in foptions) then begin + stockobjects.paintglyph(canvas,getglyph,arect,not isenabled,co1); + end; +// inherited; +end; + +procedure tcustombooleanedit.setvalue(const Value: boolean); +begin + fvalue := Value; + valuechanged; +end; + +procedure tcustombooleanedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readboolean(valuevarname,value); +end; + +procedure tcustombooleanedit.writestatvalue(const writer: tstatwriter); +begin + writer.writeboolean(valuevarname,value); +end; + +function tcustombooleanedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +class function tcustombooleanedit.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_booleanedit; +end; + +procedure tcustombooleanedit.setnullvalue; +begin + value:= false; +end; + +procedure tcustombooleanedit.gridtovalue(arow: integer); +var + int1: integer; +begin + int1:= 0; + if fvalue then begin + int1:= 1; + end; + fgridintf.getdata(arow,int1); + fvalue:= int1 <> 0; + inherited; +end; + +procedure tcustombooleanedit.valuetogrid(arow: integer); +var + int1: integer; +begin + int1:= integer(longbool(fvalue)); + fgridintf.setdata(arow,int1); +end; + +procedure tcustombooleanedit.fillcol(const avalue: longbool); +begin + checkgrid; + with tdatalist1(fgridintf.getcol.datalist) do begin + tdatalist1(fgridintf.getcol.datalist).internalfill(count,avalue); + end; + fgridintf.getcol.changed; +end; + +function tcustombooleanedit.checkvalue(const quiet: boolean = false): boolean; +begin + result:= docheckvalue(fvalue,quiet); +end; + +function tcustombooleanedit.getgridvalue(const index: integer): longbool; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustombooleanedit.setgridvalue(const index: integer; + const Value: longbool); +begin + internalsetgridvalue(index,value); +end; + +function tcustombooleanedit.getgridvalues: longboolarty; +begin + result:= longboolarty(tintegerdatalist(fgridintf.getcol.datalist).asarray); +end; + +procedure tcustombooleanedit.setgridvalues(const Value: longboolarty); +begin + tintegerdatalist(fgridintf.getcol.datalist).asarray:= integerarty(value); +end; + +function tcustombooleanedit.getgridbooleanvalues: booleanarty; +begin + result:= tintegerdatalist(fgridintf.getcol.datalist).asbooleanarray; +end; + +procedure tcustombooleanedit.setgridbooleanvalues(const Value: booleanarty); +begin + tintegerdatalist(fgridintf.getcol.datalist).asbooleanarray:= value; +end; + +function tcustombooleanedit.valuetag(const falsevalue: integer): integer; +begin + if fvalue then begin + result:= tag; + end + else begin + result:= falsevalue; + end; +end; + +function tcustombooleanedit.gridvaluetag(const index: integer; + const falsevalue: integer): integer; +begin + if getgridvalue(index) then begin + result:= tag; + end + else begin + result:= falsevalue; + end; +end; + +procedure tcustombooleanedit.updatetagvalue(const bitset: integer); + //value -> true if bitset and tag <> 0 +begin + value:= bitset and tag <> 0; +end; + +procedure tcustombooleanedit.gridupdatetagvalue(const index: integer; const bitset: integer); +begin + setgridvalue(index,bitset and tag <> 0); +end; + +function tcustombooleanedit.valuetagbit: longword; + //if value -> bits[tag] else -> 0 +begin + if fvalue then begin + result:= bits[tag and $1f]; + end + else begin + result:= 0; + end; +end; + +function tcustombooleanedit.gridvaluetagbit(const index: integer): longword; + //if value -> bits[tag] else -> 0 +begin + if gridvalue[index] then begin + result:= bits[tag and $1f]; + end + else begin + result:= 0; + end; +end; + +function tcustombooleanedit.getvaluebitmask: longword; + //ored valuetagbit of all edits in group +var + ar1: booleaneditarty; + int1: integer; +begin + ar1:= groupmembers; + result:= 0; + for int1:= 0 to high(ar1) do begin + result:= result or ar1[int1].valuetagbit; + end; +end; + +procedure tcustombooleanedit.setvaluebitmask(const avalue: longword); +var + ar1: booleaneditarty; + int1: integer; +begin + ar1:= groupmembers; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + value:= avalue and bits[tag and $1f] <> 0; + end; + end; +end; + +function tcustombooleanedit.getgridvaluebitmask(const index: integer): longword; + //ored valuetagbit of all edits in group +var + ar1: booleaneditarty; + int1: integer; +begin + ar1:= groupmembers; + result:= 0; + for int1:= 0 to high(ar1) do begin + result:= result or ar1[int1].gridvaluetagbit(index); + end; +end; + +procedure tcustombooleanedit.setgridvaluebitmask(const index: integer; const avalue: longword); +var + ar1: booleaneditarty; + int1: integer; +begin + ar1:= groupmembers; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + gridvalue[index]:= avalue and bits[tag and $1f] <> 0; + end; + end; +end; + +function tcustombooleanedit.getvalue: boolean; +begin + result:= fvalue; +end; + +function tcustombooleanedit.getvaluedefault: boolean; +begin + result:= fvaluedefault; +end; + +procedure tcustombooleanedit.setvaluedefault(const Value: boolean); +begin + fvaluedefault:= value; +end; + +function tcustombooleanedit.groupmembers: booleaneditarty; +var + int1,int2: integer; + widget1: twidget; +begin + if fparentwidget = nil then begin + setlength(result,1); + result[0]:= self; + end + else begin + setlength(result,fparentwidget.widgetcount); //max + int2:= 0; + for int1:= 0 to high(result) do begin + widget1:= twidget1(fparentwidget).fwidgets[int1]; + if (widget1 is tcustombooleanedit) and + (tcustombooleanedit(widget1).fgroup = self.fgroup) then begin + result[int2]:= tcustombooleanedit(widget1); + inc(int2); + end; + end; + setlength(result,int2); + end; +end; + +function tcustombooleanedit.tagitem(const atag: integer): tcustombooleanedit; //nil if none +var + int1: integer; + widget1: twidget; +begin + result:= nil; + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget1:= twidget1(fparentwidget).fwidgets[int1]; + if (widget1 is tcustombooleanedit) and + (tcustombooleanedit(widget1).fgroup = self.fgroup) and + (widget1.tag = atag) then begin + result:= tbooleanedit(widget1); + break; + end; + end; + end; +end; + +procedure tcustombooleanedit.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if not (es_processed in eventstate) then begin + if ((key = key_0) or (key = key_1) or (key = key_period)) and + (shiftstate = []) and (bo_executeonkey in foptions) then begin + include(eventstate,es_processed); + if ((key = key_1) xor value) or (key = key_period) then begin + togglevalue(oe_readonly in getoptionsedit,false); + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; + end; +end; + +function tcustombooleanedit.getassistivetext(): msestring; +begin + if value then begin + result:= stockobjects.captions[sc_on]; + end + else begin + result:= stockobjects.captions[sc_off]; + end; +end; + +{$ifdef mse_with_ifi} +function tcustombooleanedit.getifilink: tifibooleanlinkcomp; +begin + result:= tifibooleanlinkcomp(fifilink); +end; + +procedure tcustombooleanedit.setifilink(const avalue: tifibooleanlinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +procedure tcustombooleanedit.resetgridvalue(const index: integer); +begin + gridvalue[index]:= false; +end; + +procedure tcustombooleanedit.checkgridvalue(const index: integer); +begin + gridvalue[index]:= true; +end; + +function tcustombooleanedit.gridvaluechecked(const aindex: integer): boolean; +begin + result:= gridvalue[aindex]; +end; + +function tcustombooleanedit.griddata: tgridintegerdatalist; +begin + result:= tgridintegerdatalist(inherited griddata); +end; + +procedure tcustombooleanedit.setvaluedata(const source); +begin + value:= boolean(source); +end; + +procedure tcustombooleanedit.getvaluedata(out dest); +begin + boolean(dest):= value; +end; + +{ tcustombooleaneditradio } + +function tcustombooleaneditradio.getglyph: stockglyphty; +begin + result:= stg_checkedradio; +end; +{ +procedure tcustombooleaneditradio.reset; +begin + if value then begin + inc(fresetting); + try + value:= false + finally + dec(fresetting); + end; + end; +end; +} +procedure tcustombooleaneditradio.setvalue(const avalue: boolean); +begin + if avalue then begin + resetradioitems(); + end; + inherited; +end; + +procedure tcustombooleaneditradio.setgridvalue(const aindex: integer; + const avalue: longbool); +var + widget: twidget; + int1: integer; +begin + if avalue and (fparentwidget <> nil) then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget:= fparentwidget.widgets[int1]; + if (widget is tcustombooleaneditradio) and (widget <> self) and + (tcustombooleaneditradio(widget).fgroup = fgroup) then begin + tcustombooleaneditradio(widget).gridvalue[aindex]:= false; + end; + end; + end; + inherited; +end; + +function tcustombooleaneditradio.checkeditem: tcustombooleaneditradio; + //nil if none +var + bo1: boolean; +begin + result:= tcustombooleaneditradio(internalcheckeditem(bo1)); +end; + +procedure tcustombooleaneditradio.togglevalue(const areadonly: boolean; + const down: boolean); +var + bo1: boolean; + bo2: longbool; +begin + if not areadonly then begin + internalcheckeditem(bo1); + if (bo_cantoggle in foptions) or not fvalue or not bo1 then begin + bo2:= not fvalue; + docheckvalue(bo2,false); + end; + end; +end; + +procedure tcustombooleaneditradio.togglegridvalue(const index: integer); +begin + if not getgridvalue(index) then begin + setgridvalue(index,true); + end; +end; + +{ tcustomintegergraphdataedit } + +procedure tcustomintegergraphdataedit.internalcheckvalue(var avalue; + var accept: boolean); +begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,integer(avalue),accept); + end; +{$ifdef mse_with_ifi} + ifisetvalue(avalue,accept); +{$endif} + if accept then begin + value:= integer(avalue); + end; +end; + +procedure tcustomintegergraphdataedit.setvalue(const avalue: integer); +begin + if (bo_radioitem in foptions) and (avalue <> fvaluedefault) then begin + resetradioitems(); + end; + fvalue := avalue; + valuechanged; +end; + +procedure tcustomintegergraphdataedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readinteger(valuevarname,value); +end; + +procedure tcustomintegergraphdataedit.writestatvalue(const writer: tstatwriter); +begin + writer.writeinteger(valuevarname,value); +end; + +function tcustomintegergraphdataedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +procedure tcustomintegergraphdataedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomintegergraphdataedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +function tcustomintegergraphdataedit.checkvalue( + const quiet: boolean = false): boolean; +begin + result:= docheckvalue(fvalue,quiet); +end; + +function tcustomintegergraphdataedit.doinc(var avalue: integer; + const down: boolean): boolean; +begin + result:= false; + if (foptions * [bo_radioitem,bo_radioitemcol] = []) or + (bo_cantoggle in foptions) or (value = fvaluedefault) then begin + if down then begin + dec(avalue); + if avalue < fvaluemin then begin + avalue:= fvaluemax; + end; + end + else begin + inc(avalue); + if avalue > fvaluemax then begin + avalue:= fvaluemin; + end; + end; + result:= true; + end; +end; + +procedure tcustomintegergraphdataedit.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; + const avalue; const arect: rectty); +var + int1,val1: integer; +begin + if canevent(tmethod(fonpaintglyph)) then begin + if @avalue = nil then begin + val1:= fvalue; + int1:= gridrow; + end + else begin + val1:= integer(avalue); + int1:= pcellinfoty(canvas.drawinfopo)^.cell.row; + end; + fonpaintglyph(self,canvas,val1,int1); + end; +// inherited; +end; + +procedure tcustomintegergraphdataedit.togglevalue(const areadonly: boolean; + const down: boolean); +var + int1: integer; +begin + if not areadonly and (fvaluemin <> fvaluemax) then begin + int1:= fvalue; + if doinc(int1,down) then begin + docheckvalue(int1,false); + end; + end; +end; + +function tcustomintegergraphdataedit.ischecked(): boolean; +begin + result:= fvalue <> fvaluedefault; +end; + +procedure tcustomintegergraphdataedit.docheck(); +begin + value:= valuedefault+1; +end; + +procedure tcustomintegergraphdataedit.douncheck(); +begin + value:= valuedefault; +end; + +procedure tcustomintegergraphdataedit.togglegridvalue(const index: integer); +var + int1: integer; +begin + if fvaluemin <> fvaluemax then begin + int1:= gridvalue[index]; + if doinc(int1,false) then begin + gridvalue[index]:= int1; + end; + end; +end; + +procedure tcustomintegergraphdataedit.fillcol(const avalue: integer); +begin + checkgrid; + tgridintegerdatalist(fdatalist).fill(fdatalist.count,avalue); +end; + +function tcustomintegergraphdataedit.createdatalist( + const sender: twidgetcol): tdatalist; +begin + fdatalist:= tgridintegerdatalist.create(sender); + tgridintegerdatalist(fdatalist).notcheckedvalue:= fvaluedefault; + result:= fdatalist; +end; + +function tcustomintegergraphdataedit.getdatalistclass: datalistclassty; +begin + result:= tgridintegerdatalist; +end; + +function tcustomintegergraphdataedit.getgridvalue(const index: integer): integer; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomintegergraphdataedit.setgridvalue(const index, Value: integer); +begin + internalsetgridvalue(index,value); +end; + +function tcustomintegergraphdataedit.getgridvalues: integerarty; +begin + checkgrid; + result:= tgridintegerdatalist(fdatalist).asarray; +end; + +procedure tcustomintegergraphdataedit.setgridvalues(const Value: integerarty); +begin + checkgrid; + tgridintegerdatalist(fdatalist).asarray:= value; +end; +{ +procedure tcustomintegergraphdataedit.setgridintf(const intf: iwidgetgrid); +begin + if intf <> nil then begin + fdatalist:= tintegerdatalist(intf.getcol.datalist); + end + else begin + fdatalist:= nil; + end; + inherited; +end; +} +procedure tcustomintegergraphdataedit.resetgridvalue(const index: integer); +begin + gridvalue[index]:= valuedefault; +end; + +procedure tcustomintegergraphdataedit.checkgridvalue(const index: integer); +var + int1: integer; +begin + int1:= fvaluedefault + 1; + if int1 > fvaluemax then begin + int1:= int1 -2; + if int1 < fvaluemin then begin + int1:= fvaluemin; + end; + end; + gridvalue[index]:= int1; +end; + +function tcustomintegergraphdataedit.gridvaluechecked( + const aindex: integer): boolean; +begin + result:= gridvalue[aindex] <> valuedefault; +end; + +procedure tcustomintegergraphdataedit.datalistdestroyed; +begin + fdatalist:= nil; +end; + +{$ifdef mse_with_ifi} +function tcustomintegergraphdataedit.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure tcustomintegergraphdataedit.setifilink(const avalue: tifiintegerlinkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +procedure tcustomintegergraphdataedit.setvaluemin(const avalue: integer); +begin + fvaluemin:= avalue; + if fdatalist <> nil then begin + with tgridintegerdatalist(fdatalist) do begin + min:= avalue; + end; + end; +end; + +procedure tcustomintegergraphdataedit.setvaluemax(const avalue: integer); +begin + fvaluemax:= avalue; + if fdatalist <> nil then begin + with tgridintegerdatalist(fdatalist) do begin + max:= avalue; + end; + end; +end; + +procedure tcustomintegergraphdataedit.updatedatalist; +begin + with tgridintegerdatalist(fdatalist) do begin + min:= self.valuemin; + max:= self.valuemax; + notcheckedvalue:= self.valuedefault; + end; +end; + +procedure tcustomintegergraphdataedit.readmin(reader: treader); +begin + valuemin:= reader.readinteger(); +end; + +procedure tcustomintegergraphdataedit.readmax(reader: treader); +begin + valuemax:= reader.readinteger(); +end; + +procedure tcustomintegergraphdataedit.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +function tcustomintegergraphdataedit.getdatalist: tintegerdatalist; +begin + result:= tintegerdatalist(checkgriddata); +end; + +function tcustomintegergraphdataedit.griddata: tgridintegerdatalist; +begin + result:= tgridintegerdatalist(inherited griddata); +end; + +procedure tcustomintegergraphdataedit.setvaluedata(const source); +begin + value:= integer(source); +end; + +procedure tcustomintegergraphdataedit.getvaluedata(out dest); +begin + integer(dest):= value; +end; + + +{ tvaluefacearrayprop } + +constructor tvaluefacearrayprop.create(const aowner: tcustomdatabutton); +begin + fowner:= aowner; + inherited create(nil); +end; + +class function tvaluefacearrayprop.getitemclasstype: persistentclassty; +begin + result:= tface; +end; + +procedure tvaluefacearrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tface.create(iface(fowner)); +end; + +function tvaluefacearrayprop.getitems(const index: integer): tface; +begin + result:= tface(inherited getitems(index)); +end; + +{ tvaluefontarrayprop } + +constructor tvaluefontarrayprop.create(const aowner: tcustomdatabutton); +begin + fowner:= aowner; + inherited create(nil); +end; + +class function tvaluefontarrayprop.getitemclasstype: persistentclassty; +begin + result:= tfont; +end; + +procedure tvaluefontarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tfont.create; + item.assign(fowner.font); + tfont(item).onchange:= @fontchange; +end; + +procedure tvaluefontarrayprop.fontchange(const sender: tobject); +begin + fowner.formatchanged; +end; + +procedure tvaluefontarrayprop.setitems(const index: integer; const avalue: tfont); +begin + checkindex(index); + if fitems[index] <> nil then begin + fitems[index].assign(avalue); + end; +end; + +function tvaluefontarrayprop.getitems(const index: integer): tfont; +begin + result:= tfont(inherited getitems(index)); +end; + +{ tcustomdatabutton } + +constructor tcustomdatabutton.create(aowner: tcomponent); +begin + foptions:= defaultbuttonoptions; + initactioninfo(factioninfo); + fvaluedisabled:= -2; + inherited; + fimagenums:= tintegerarrayprop.create; + fimagenr:= -1; + fimagenrdisabled:= -2; + fvalue:= -1; + fvaluedefault:= -1; + fvaluemin:= -1; + fvaluemax:= 0; + fvaluefaces:= tvaluefacearrayprop.create(self); + fvaluecaptions:= tmsestringarrayprop.create; + fvaluefonts:= tvaluefontarrayprop.create(self); + optionswidget:= defaultoptionswidget - [ow_mousefocus]; + initshapeinfo(finfo); + finfo.ca.imagepos:= ip_center; + finfo.ca.dim:= innerclientrect; + finfo.color:= cl_transparent; + finfo.ca.colorglyph:= cl_black; + finfo.state:= finfo.state + [shs_showfocusrect,shs_showdefaultrect]; + include(fwidgetstate1,ws1_nodesignframe); + size:= makesize(defaultbuttonwidth,defaultbuttonheight); +end; + +destructor tcustomdatabutton.destroy; +begin + if bo_updateonidle in foptions then begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + fvaluefaces.free; + fvaluecaptions.free; + fvaluefonts.free; + fimagenums.free; + inherited; +end; + +procedure tcustomdatabutton.execute(); +begin + if not (shs_disabled in finfo.state) then begin + internalexecute; + end; +end; + +class function tcustomdatabutton.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_databutton; +end; + +function tcustomdatabutton.verticalfontheightdelta: boolean; +begin + result:= tf_rotate90 in textflags; +end; + +procedure tcustomdatabutton.synctofontheight; +begin + inherited; + if tf_rotate90 in textflags then begin + bounds_cx:= font.glyphheight + innerclientframewidth.cx + 6; + end + else begin + bounds_cy:= font.glyphheight + innerclientframewidth.cy + 6; + end; +end; + +procedure tcustomdatabutton.initnewcomponent(const ascale: real); +begin + //dummy +end; + +procedure tcustomdatabutton.clientrectchanged; +begin + inherited; + frameskinoptionstoshapestate(fframe,finfo); + if (fframe = nil) and (fgridintf <> nil) then begin + exclude(finfo.state,shs_showdefaultrect); + end; + if shs_flat in finfo.state then begin + exclude(fwidgetstate1,ws1_nodesignframe); + end + else begin + include(fwidgetstate1,ws1_nodesignframe); + end; + finfo.ca.dim:= clientrect; + if (fframe <> nil) and not(shs_noinnerrect in finfo.state) then begin + //otherwise mouse rect + deflaterect1(finfo.ca.dim,fframe.frameo); + end; + { + if shs_noinnerrect in finfo.state then begin + finfo.ca.dim:= clientrect; + end + else begin + finfo.ca.dim:= innerclientrect; + end; + } +end; +{ +function tcustomdatabutton.getframestateflags: framestateflagsty; +begin + with finfo do begin + result:= combineframestateflags(not isenabled,focused, + not (bo_nodefaultframeactive in foptions) and + (shs_default in finfo.state) or active, + shs_mouse in state,shs_clicked in state); + end; +end; +} +{ +function tcustomdatabutton.getframeclicked: boolean; +begin + result:= ss_clicked in finfo.state; +end; + +function tcustomdatabutton.getframemouse: boolean; +begin + result:= ss_mouse in finfo.state; +end; + +function tcustomdatabutton.getframeactive: boolean; +begin + result:= not (bo_nodefaultframeactive in foptions) and + (ss_default in finfo.state) or active; +end; +} +procedure tcustomdatabutton.doexecute; +begin + if (options * [bo_nocandefocus,bo_candefocuswindow] <> [bo_candefocuswindow]) or + rootwidget.canparentclose then begin + doactionexecute(self,factioninfo,false, + (options * [bo_nocandefocus,bo_candefocuswindow] <> [])); + end; +// doactionexecute(self,factioninfo); +end; + +procedure tcustomdatabutton.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (csdesigning in componentstate) {and + not (es_processed in info.eventstate)} then begin + subpoint1(info.pos,paintpos); + try + updatemouseshapestate(finfo,info,self,fframe,nil, + bo_executeonclick in foptions); + finally + addpoint1(info.pos,paintpos); + end; + end; +end; + +procedure tcustomdatabutton.dokeydown(var info: keyeventinfoty); +begin + inherited; + if (info.shiftstate = []) and (bo_executeonkey in foptions) and + not (des_disabled in fstate) then begin + if (info.key = key_space) then begin + include(finfo.state,shs_clicked); + invalidaterect(finfo.ca.dim); + end + else begin + if isenterkey(self,info.key) then begin + include(info.eventstate,es_processed); + togglevalue(oe_readonly in getoptionsedit,false); + end; + end; + end; +end; + +procedure tcustomdatabutton.dokeyup(var info: keyeventinfoty); +begin + if (info.key = key_space) and (shs_clicked in finfo.state) then begin + exclude(finfo.state,shs_clicked); + invalidaterect(finfo.ca.dim); + end; + inherited; +end; + +procedure tcustomdatabutton.doshortcut(var info: keyeventinfoty; const sender: twidget); +var + bo1,bo2: boolean; +begin + if not (es_processed in info.eventstate) and + not (csdesigning in componentstate) and + not (shs_disabled in finfo.state) then begin + if checkfocusshortcut(info) then begin + setfocus; + end; + bo1:= checkactionshortcut(factioninfo,info); + if not bo1 then begin + if not (es_preview in info.eventstate) then begin + bo2:= es_processed in info.eventstate; + exclude(info.eventstate,es_processed); + bo1:= (bo_executeonshortcut in options) and + msegui.checkshortcut(info,factioninfo.captiontext, + bo_altshortcut in options) or + (finfo.state * [shs_invisible,shs_disabled,shs_default] = [shs_default]) and + (info.key = key_return) and + ((info.shiftstate = []) or + (bo_executedefaultonenterkey in options) and + (info.shiftstate = [ss_second])); + if bo1 then begin + bo2:= true; + togglevalue(oe_readonly in getoptionsedit,false); + // internalexecute; + end; + if bo2 then begin + include(info.eventstate,es_processed); + end; + end; + end + else begin + togglevalue(oe_readonly in getoptionsedit,false); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +procedure tcustomdatabutton.statechanged; +begin + inherited; + updatewidgetshapestate(finfo,self); + if (fgridintf <> nil) and (fvaluedisabled <> -2) then begin + checkdisabled(); + end; +end; + +procedure tcustomdatabutton.setcolorglyph(const avalue: colorty); +begin + setactioncolorglyph(iactionlink(self),avalue); +end; + +function tcustomdatabutton.iscolorglyphstored: boolean; +begin + result:= isactioncolorglyphstored(factioninfo); +end; + +procedure tcustomdatabutton.setactualimagenr(const avalue: integer); +begin + with finfo,ca do begin + if (avalue >= 0) and (avalue < fimagenums.count) then begin + imagenr:= fimagenums[avalue]; + end + else begin + imagenr:= fimagenr; + end; + if shs_disabled in finfo.state then begin + if fimagenrdisabled = -3 then begin + if imagenr >= 0 then begin + imagenrdisabled:= imagenr + fimageoffsetdisabled; + end; + end + else begin + imagenrdisabled:= fimagenrdisabled; + end; + end + else begin + if shs_clicked in state then begin + inc(imagenr,fimageoffsetclicked); + end + else begin + if shs_mouse in state then begin + inc(imagenr,fimageoffsetmouse); + end + end; + if imagenr >= 0 then begin + inc(imagenr,fimageoffset); + end; + end; + end; +end; + +procedure tcustomdatabutton.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; + const arect: rectty); + + function actualcaption(const aindex: integer): richstringty; + begin + if (aindex >= 0) and (aindex < fvaluecaptions.count) then begin + result.text:= fvaluecaptions[aindex]; + result.format:= nil; + end + else begin + result:= factioninfo.caption1; + end; + end; + + function actualface(const aindex: integer): tface; + begin + if (aindex >= 0) and (aindex < fvaluefaces.count) then begin + result:= fvaluefaces[aindex]; + end + else begin + result:= nil; + end; + end; + + function actualfont(const aindex: integer): tfont; + begin + if (aindex >= 0) and (aindex < fvaluefonts.count) then begin + result:= fvaluefonts[aindex]; + end + else begin + result:= font; + end; + end; + +var + statebefore: shapestatesty; + dimbefore: rectty; +begin + finfo.ca.colorglyph:= acolorglyph; + finfo.imagenrdisabled:= fimagenrdisabled; + if (@avalue <> nil) then begin + finfo.ca.caption:= actualcaption(integer(avalue)); + finfo.face:= actualface(integer(avalue)); + finfo.ca.font:= actualfont(int32(avalue)); + statebefore:= finfo.state; + dimbefore:= finfo.ca.dim; + finfo.ca.dim:= arect; + finfo.state:= finfo.state - [shs_focused,shs_clicked,shs_mouse]; + if not valueenabledstate(integer(avalue)) then begin + include(finfo.state,shs_disabled); + end + else begin + exclude(finfo.state,shs_disabled); + end; + with pcellinfoty(canvas.drawinfopo)^ do begin + if (cds_ismousecell in drawstate) and (bo_executeonclick in foptions) and + not(shs_disabled in finfo.state) and not readonly then begin + include(finfo.state,shs_mouse); + end; + if cell.row = fclickedrow then begin + include(finfo.state,shs_clicked); + end; + end; + setactualimagenr(integer(avalue)); + drawbutton(canvas,finfo); + finfo.state:= statebefore; + finfo.ca.dim:= dimbefore; + end + else begin + finfo.ca.caption:= actualcaption(fvalue); + finfo.face:= actualface(fvalue); + finfo.ca.font:= actualfont(fvalue); + setactualimagenr(fvalue); + drawbutton(canvas,finfo); + end; + inherited; +end; + +procedure tcustomdatabutton.internalcreateframe; +begin + tcaptionframe.create(iscrollframe(self)); +end; + +procedure tcustomdatabutton.initgridwidget; +begin + inherited; + if fgridintf <> nil then begin + with fgridintf.getcol do begin + if self.color = cl_default then begin + color:= cl_parent; + end + else begin + color:= self.color; + end; + options:= options - [co_drawfocus]; + end; + end; +end; + +procedure tcustomdatabutton.setvaluefaces(const avalue: tvaluefacearrayprop); +begin + fvaluefaces.assign(avalue); +end; + +procedure tcustomdatabutton.setvaluecaptions(const avalue: tmsestringarrayprop); +begin + fvaluecaptions.assign(avalue); +end; + +procedure tcustomdatabutton.setcaption(const avalue: captionty); +begin + setactioncaption(iactionlink(self),avalue); +// formatchanged; +end; + +procedure tcustomdatabutton.settextflags(const avalue: textflagsty); +begin + if finfo.ca.textflags <> avalue then begin + finfo.ca.textflags:= checktextflags(finfo.ca.textflags,avalue); + invalidate; + checkautosize(); + end; +end; + +function tcustomdatabutton.iscaptionstored: boolean; +begin + result:= isactioncaptionstored(factioninfo); +end; + +procedure tcustomdatabutton.setcaptiondist(const avalue: integer); +begin + if avalue <> finfo.ca.captiondist then begin + finfo.ca.captiondist:= avalue; + formatchanged(); +// checkautosize(); + end; +end; + +procedure tcustomdatabutton.setimagepos(const avalue: imageposty); +begin + if avalue <> finfo.ca.imagepos then begin + finfo.ca.imagepos:= avalue; + formatchanged; +// checkautosize; + end; +end; + +function tcustomdatabutton.getimagelist: timagelist; +begin + result:= timagelist(factioninfo.imagelist); +end; + +procedure tcustomdatabutton.setimagelist(const avalue: timagelist); +begin + setactionimagelist(iactionlink(self),avalue); +end; + +function tcustomdatabutton.isimageliststored: Boolean; +begin + result:= isactionimageliststored(factioninfo); +end; + +procedure tcustomdatabutton.setimagenr(const avalue: imagenrty); +begin + fimagenr:= avalue; + setactionimagenr(iactionlink(self),avalue); +end; + +function tcustomdatabutton.isimagenrstored: Boolean; +begin + result:= isactionimagenrstored(factioninfo); +end; + +procedure tcustomdatabutton.setimagenrdisabled(const avalue: imagenrty); +begin + fimagenrdisabled:= avalue; + setactionimagenrdisabled(iactionlink(self),avalue); +end; + +function tcustomdatabutton.isimagenrdisabledstored: Boolean; +begin + result:= isactionimagenrdisabledstored(factioninfo); +end; + +procedure tcustomdatabutton.setnullvalue; +begin + value:= -1; +end; + +procedure tcustomdatabutton.setgridintf(const intf: iwidgetgrid); +begin + inherited; + exclude(finfo.state,shs_showdefaultrect); +end; + +function tcustomdatabutton.checkfocusshortcut(var info: keyeventinfoty): boolean; +begin + result:= inherited checkfocusshortcut(info) or + msegui.checkshortcut(info,factioninfo.captiontext,true); +end; + +procedure tcustomdatabutton.togglevalue(const areadonly: boolean; + const down: boolean); +begin + if not (des_disabled in fstate) then begin + inherited; + internalexecute; + end; +end; + +procedure tcustomdatabutton.togglegridvalue(const index: integer); +begin + inherited; + internalexecute; +end; + +function tcustomdatabutton.checkeditem: tcustomdatabutton; +var + bo1: boolean; +begin + result:= tcustomdatabutton(internalcheckeditem(bo1)); +end; + +procedure tcustomdatabutton.setimageoffset(const avalue: integer); +begin + if fimageoffset <> avalue then begin + fimageoffset := aValue; + formatchanged; + end; +end; + +procedure tcustomdatabutton.setimageoffsetdisabled(const avalue: integer); +begin + if fimageoffsetdisabled <> avalue then begin + fimageoffsetdisabled := avalue; + formatchanged; + end; +end; + +procedure tcustomdatabutton.setimageoffsetmouse(const avalue: integer); +begin + if fimageoffsetmouse <> avalue then begin + fimageoffsetmouse := avalue; + formatchanged; + end; +end; + +procedure tcustomdatabutton.setimageoffsetclicked(const avalue: integer); +begin + if fimageoffsetclicked <> avalue then begin + fimageoffsetclicked := avalue; + formatchanged; + end; +end; + +procedure tcustomdatabutton.setshortcut(const avalue: shortcutty); +begin + setactionshortcut(iactionlink(self),avalue); +end; + +function tcustomdatabutton.isshortcutstored: boolean; +begin + result:= isactionshortcutstored(factioninfo); +end; + +function tcustomdatabutton.getshortcut: shortcutty; +begin + result:= getsimpleshortcut(factioninfo); +end; + +function tcustomdatabutton.getshortcut1: shortcutty; +begin + result:= getsimpleshortcut1(factioninfo); +end; + +procedure tcustomdatabutton.setshortcut1(const avalue: shortcutty); +begin + setactionshortcut1(iactionlink(self),avalue); +end; + +function tcustomdatabutton.isshortcut1stored: boolean; +begin + result:= isactionshortcut1stored(factioninfo); +end; + +procedure tcustomdatabutton.setonexecute(const avalue: notifyeventty); +begin + setactiononexecute(iactionlink(self),avalue,csloading in componentstate); +end; + +function tcustomdatabutton.isonexecutestored: boolean; +begin + result:= isactiononexecutestored(factioninfo); +end; + +procedure tcustomdatabutton.setonbeforeexecute(const avalue: accepteventty); +begin + setactiononbeforeexecute(iactionlink(self),avalue,csloading in componentstate); +end; + +function tcustomdatabutton.isonbeforeexecutestored: boolean; +begin + result:= isactiononbeforeexecutestored(factioninfo); +end; + +procedure tcustomdatabutton.setonafterexecute(const avalue: notifyeventty); +begin + setactiononafterexecute(iactionlink(self),avalue,csloading in componentstate); +end; + +function tcustomdatabutton.isonafterexecutestored: boolean; +begin + result:= isactiononafterexecutestored(factioninfo); +end; + +procedure tcustomdatabutton.setimagedist(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist then begin + finfo.ca.imagedist:= avalue; + formatchanged; +// checkautosize; + end; +end; + +procedure tcustomdatabutton.setimagedist1(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist1 then begin + finfo.ca.imagedist1:= avalue; + formatchanged; +// checkautosize; + end; +end; + +procedure tcustomdatabutton.setimagedist2(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist2 then begin + finfo.ca.imagedist2:= avalue; + formatchanged; +// checkautosize; + end; +end; + +procedure tcustomdatabutton.setimagenums(const avalue: tintegerarrayprop); +begin + fimagenums.assign(avalue); +end; + +procedure tcustomdatabutton.setoptions(const avalue: buttonoptionsty); +var + delta: buttonoptionsty; +begin + if avalue <> foptions then begin + delta:= buttonoptionsty( + {$ifdef FPC}longword{$else}longword{$endif}(foptions) xor + {$ifdef FPC}longword{$else}longword{$endif}(avalue)); + if bo_updateonidle in delta then begin + if (bo_updateonidle in avalue) and + not (csdesigning in componentstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doidle); + end + else begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + end; + foptions:= avalue; + buttonoptionstoshapestate(foptions,finfo.state); + invalidate; + if bo_shortcutcaption in avalue then begin + setactionoptions(iactionlink(self),factioninfo.options + [mao_shortcutcaption]); + end + else begin + setactionoptions(iactionlink(self),factioninfo.options - [mao_shortcutcaption]); + end; + end; +end; +{ +begin + if foptions <> avalue then begin + foptions:= avalue - [bo_shortcutcaption]; + buttonoptionstoshapestate(foptions,finfo.state); + invalidate; + end; +end; +} +function tcustomdatabutton.getactioninfopo: pactioninfoty; +begin + result:= @factioninfo; +end; + +function tcustomdatabutton.shortcutseparator: msechar; +begin + result:= ' '; +end; + +procedure tcustomdatabutton.calccaptiontext(var ainfo: actioninfoty); +begin + mseactions.calccaptiontext(ainfo,shortcutseparator); +end; + +procedure tcustomdatabutton.updatehotkeys(); +begin + inherited; + calccaptiontext(factioninfo); +end; + +procedure tcustomdatabutton.actionchanged; +begin + finfo.color:= fcolor; + actioninfotoshapeinfo(self,factioninfo,finfo,foptions); + inherited setcolor(finfo.color); + finfo.color:= cl_transparent; +// if csdesigning in componentstate then begin + exclude(finfo.state,shs_invisible); +// end; + formatchanged(); +// checkautosize; +end; + +procedure tcustomdatabutton.setaction(const avalue: tcustomaction); +begin + linktoaction(iactionlink(self),avalue,factioninfo); +end; + +procedure tcustomdatabutton.setstate(const avalue: actionstatesty); +begin + setactionstate(iactionlink(self),avalue); + visible:= not (as_invisible in factioninfo.state); + enabled:= not (as_disabled in factioninfo.state); +end; + +procedure tcustomdatabutton.setenabled(const avalue: boolean); +begin + if avalue then begin + setactionstate(iactionlink(self),state - [as_disabled]); + end + else begin + setactionstate(iactionlink(self),state + [as_disabled]); + end; + inherited; +end; + +procedure tcustomdatabutton.setvisible(const avalue: boolean); +begin + if avalue then begin + setactionstate(iactionlink(self),state - [as_invisible]); + end + else begin + setactionstate(iactionlink(self),state + [as_invisible]); + end; + inherited; +end; + +function tcustomdatabutton.isstatestored: boolean; +begin + result:= isactionstatestored(factioninfo); +end; + +procedure tcustomdatabutton.readcaptionpos(reader: treader); +begin + imagepos:= readcaptiontoimagepos(reader); +end; + +procedure tcustomdatabutton.readshortcut(reader: treader); +begin + shortcut:= translateshortcut(reader.readinteger); +end; + +procedure tcustomdatabutton.readshortcut1(reader: treader); +begin + shortcut1:= translateshortcut(reader.readinteger); +end; + +procedure tcustomdatabutton.readsc(reader: treader); +begin + shortcuts:= readshortcutarty(reader); +end; + +procedure tcustomdatabutton.writesc(writer: twriter); +begin + writeshortcutarty(writer,factioninfo.shortcut); +end; + +procedure tcustomdatabutton.readsc1(reader: treader); +begin + shortcuts1:= readshortcutarty(reader); +end; + +procedure tcustomdatabutton.writesc1(writer: twriter); +begin + writeshortcutarty(writer,factioninfo.shortcut1); +end; + +procedure tcustomdatabutton.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('captionpos',{$ifdef FPC}@{$endif}readcaptionpos,nil,false); + filer.defineproperty('shortcut',{$ifdef FPC}@{$endif}readshortcut,nil,false); + filer.defineproperty('shortcut1',{$ifdef FPC}@{$endif}readshortcut1,nil,false); + filer.defineproperty('sc',{$ifdef FPC}@{$endif}readsc, + {$ifdef FPC}@{$endif}writesc, + isactionshortcutstored(factioninfo) and + ((filer.ancestor = nil) and (factioninfo.shortcut <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(factioninfo.shortcut, + tcustombutton(filer.ancestor).shortcuts)))); + filer.defineproperty('sc1',{$ifdef FPC}@{$endif}readsc1, + {$ifdef FPC}@{$endif}writesc1, + isactionshortcut1stored(factioninfo) and + ((filer.ancestor = nil) and (factioninfo.shortcut1 <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(factioninfo.shortcut, + tcustombutton(filer.ancestor).shortcuts)))); +end; + +procedure tcustomdatabutton.loaded; +begin + inherited; + actionendload(iactionlink(self)); +end; + +procedure tcustomdatabutton.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + inherited; + if ownedcol and (info.eventkind in [cek_mouseenter,cek_mouseleave]) then begin + fgridintf.getcol.grid.invalidatecell(info.cell); + end; +end; + +procedure tcustomdatabutton.setshortcuts(const avalue: shortcutarty); +begin + setactionshortcuts(iactionlink(self),avalue); +end; + +procedure tcustomdatabutton.setshortcuts1(const avalue: shortcutarty); +begin + setactionshortcuts1(iactionlink(self),avalue); +end; + +procedure tcustomdatabutton.internalexecute; +begin + if bo_asyncexecute in foptions then begin + asyncevent; + end + else begin + doexecute; + end; +end; + +procedure tcustomdatabutton.doasyncevent(var atag: integer); +begin + if atag = 0 then begin + doexecute; + end; +end; + +procedure tcustomdatabutton.setcolor(const avalue: colorty); +begin + if csloading in componentstate then begin + inherited; //no actionchanged + end; + setactioncolor(iactionlink(self),avalue); +end; + +procedure tcustomdatabutton.objectchanged(const sender: tobject); +var + i1: int32; +begin + inherited; + for i1:= 0 to high(fvaluefaces.fitems) do begin + tcustomface(fvaluefaces.fitems[i1]).checktemplate(sender); + end; +end; + +function tcustomdatabutton.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_button]; +end; + +function tcustomdatabutton.getassistivecaption(): msestring; +begin + result:= factioninfo.captiontext; + if result = '' then begin + result:= inherited getassistivecaption(); + end; +end; + +procedure tcustomdatabutton.doupdate; +begin + if factioninfo.action <> nil then begin + factioninfo.action.doupdate; + end; + if canevent(tmethod(fonupdate)) then begin + fonupdate(self); + end; +end; + +procedure tcustomdatabutton.doidle(var again: boolean); +begin + doupdate; +end; + +procedure tcustomdatabutton.domousewheelevent(var info: mousewheeleventinfoty); +begin + if not (es_transientfor in info.eventstate) then begin + inherited togglevalue(oe_readonly in getoptionsedit,info.wheel = mw_down); + end + else begin + inherited; + end; +end; + +procedure tcustomdatabutton.setvaluedisabled(const avalue: integer); +begin + if fvaluedisabled <> avalue then begin + fvaluedisabled:= avalue; + { + if fvaluedisabled = -2 then begin + exclude(fstate,des_noenablesync); + end + else begin + include(fstate,des_noenablesync); + checkdisabled(); + end; + } + end; +end; + +procedure tcustomdatabutton.setvaluefonts(const avalue: tvaluefontarrayprop); +begin + fvaluefonts.assign(avalue); +end; + +function tcustomdatabutton.valueenabledstate(const avalue: integer): boolean; +begin + result:= enabled; + if (fvaluedisabled <> -2) then begin + result:= avalue <> fvaluedisabled; + end; +end; + +procedure tcustomdatabutton.checkdisabled(); +begin + if (fgridintf = nil) then begin + //no check if inactive gridrow + enabled:= valueenabledstate(fvalue); + end + else begin + if valueenabledstate(fvalue) then begin + exclude(finfo.state,shs_disabled); + exclude(fstate,des_disabled); + end + else begin + include(finfo.state,shs_disabled); + include(fstate,des_disabled); + end; + end; +end; + +procedure tcustomdatabutton.valuechanged; +begin + checkdisabled(); + inherited; +end; + +procedure tcustomdatabutton.gridtovalue(arow: integer); +begin + inherited; + checkdisabled(); +end; + +procedure tcustomdatabutton.initnewwidget(const ascale: real); +begin + inherited; + if fgridintf <> nil then begin + fgridintf.getcol.options:= + fgridintf.getcol.grid.datacols.options - [co_drawfocus]; + end; +end; + +{ tstockglyphdatabutton } + +constructor tstockglyphdatabutton.create(aowner: tcomponent); +begin + inherited; + imagelist:= stockobjects.glyphs; + glyph:= stg_none; +end; + +procedure tstockglyphdatabutton.setglyph(const avalue: stockglyphty); +begin + fglyph:= avalue; + imagenr:= ord(avalue); +end; + +{ tcustomdataicon } + +constructor tcustomdataicon.create(aowner: tcomponent); +begin + inherited; + fvaluedefault:= -1; + fvalue:= fvaluedefault; + fimagenums:= tintegerarrayprop.create; + fimagenums.onchange:= {$ifdef FPC}@{$endif}imagenumschanged; +end; + +destructor tcustomdataicon.destroy; +begin + fimagenums.free; + inherited; +end; + +procedure tcustomdataicon.setnullvalue; +begin + value:= -1; +end; + +procedure tcustomdataicon.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = fimagelist) and (event = oe_changed) then begin + formatchanged; + end; +end; + +procedure tcustomdataicon.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; + const arect: rectty); +var + int1,int2: integer; + po1: pintegeraty; +begin + if (fimagelist <> nil) then begin + if @avalue = nil then begin + int1:= fvalue + end + else begin + int1:= integer(avalue); + end; + if (int1 >= 0) then begin + int1:= int1 + fimageoffset; + if (int1 < fimagelist.count) and (int1 >= 0) then begin + fimagelist.paint(canvas,int1,arect,[al_ycentered,al_xcentered]); + end; + end + else begin + if (int1 <> -1) and (longword(int1) <> $80000000) then begin + {$warnings off} + po1:= pintegeraty(tarrayprop1(fimagenums).getdatapo^); + {$warnings on} + for int2:= 0 to fimagenums.count-1 do begin + if int1 and bits[int2] <> 0 then begin + fimagelist.paint(canvas,po1^[int2],arect,[al_ycentered,al_xcentered]); + end; + end; + end; + end; + end; + inherited; +end; + +procedure tcustomdataicon.setimagelist(const aValue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + formatchanged; +end; + +procedure tcustomdataicon.setimageoffset(const aValue: integer); +begin + if fimageoffset <> avalue then begin + fimageoffset := aValue; + formatchanged; + end; +end; + +procedure tcustomdataicon.setimagenums(const avalue: tintegerarrayprop); +begin + fimagenums.assign(avalue); +end; + +procedure tcustomdataicon.imagenumschanged(const sender: tarrayprop; const index: integer); +begin + formatchanged; +end; + + +{ tpointeredit } + +function tpointeredit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridpointerdatalist.create(sender); +end; + +function tpointeredit.getdatalistclass: datalistclassty; +begin + result:= tgridpointerdatalist; +end; + +procedure tpointeredit.setvalue(const avalue: pointer); +begin + fvalue:= avalue; + valuechanged; +end; + +function tpointeredit.getgridvalue(const index: integer): pointer; +begin + internalgetgridvalue(index,result); +end; + +procedure tpointeredit.setgridvalue(const index: integer; const avalue: pointer); +begin + internalsetgridvalue(index,avalue); +end; + +function tpointeredit.getgridvalues: pointerarty; +begin + result:= tpointerdatalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tpointeredit.setgridvalues(const avalue: pointerarty); +begin + tpointerdatalist(fgridintf.getcol.datalist).asarray:= avalue; +end; + +procedure tpointeredit.initnewcomponent(const ascale: real); +begin + //do nothing +end; + +procedure tpointeredit.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; + const arect: rectty); +var + po1: pointer; + int1: integer; +begin + if canevent(tmethod(fonpaintglyph)) then begin + if @avalue = nil then begin + po1:= fvalue; + int1:= gridrow; + end + else begin + po1:= pointer(avalue); + int1:= pcellinfoty(canvas.drawinfopo)^.cell.row; + end; + fonpaintglyph(self,canvas,po1,int1); + end; +// inherited; +end; + +procedure tpointeredit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tpointeredit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +function tpointeredit.griddata: tgridpointerdatalist; +begin + result:= tgridpointerdatalist(inherited griddata); +end; + +procedure tpointeredit.setvaluedata(const source); +begin + value:= pointer(source); +end; + +procedure tpointeredit.getvaluedata(out dest); +begin + pointer(dest):= value; +end; + +{ tbarface } + +constructor tbarface.create(const intf: iface); +begin + inherited; + with fade_color do begin + count:= 1; + items[0]:= defaultbarcolor; + end; +end; + +{ tbarframe } + +constructor tbarframe.create(const aowner: tcustomprogressbar); +begin + fowner:= aowner; + fstate:= [fs_nowidget,fs_nosetinstance]; + inherited create(iscrollframe(aowner)); +end; + +{ tcustomprogressbar } + +constructor tcustomprogressbar.create(aowner: tcomponent); +begin + fbar_face:= tbarface.create(iface(self)); + fbar_frame:= tbarframe.create(self); + fformat:= '0%'; + fvaluerange:= 100; + ftextflags:= [tf_ycentered,tf_xcentered]; + inherited; + optionswidget:= defaultoptionswidgetnofocus; +end; + +destructor tcustomprogressbar.destroy; +begin + inherited; + fbar_face.free; + fbar_frame.free; +end; + +procedure tcustomprogressbar.setvalue(const avalue: realty); +begin + if not (csloading in componentstate) then begin + application.lock; + try + if avalue = 0.0 then begin + fcancel:= false; + end; + inherited; + finally + application.unlock; + end; + end + else begin + inherited; + end; +end; + +procedure tcustomprogressbar.setbar_face(const avalue: tbarface); +begin + fbar_face.assign(avalue); +end; + +procedure tcustomprogressbar.updatebarrect(const avalue: realty; const arect: rectty; + out facedest,framebardest,facebardest: rectty); +var + int1,int2,int3: integer; +begin + if avalue = emptyreal then begin + facedest:= nullrect; + framebardest:= nullrect; + facebardest:= nullrect; + end + else begin + with fbar_frame do begin + facedest.x:= arect.x + fi.innerframe.left; //origin = paintpos + facedest.y:= arect.y + fi.innerframe.top; + int2:= (finnerframe.left+finnerframe.right); + int3:= (finnerframe.top+finnerframe.bottom); + facedest.cx:= arect.cx - int2; + facedest.cy:= arect.cy - int3; + end; +// facedest:= deflaterect(arect,fbar_frame.innerframe); +// facedest.pos:= pointty(fbar_frame.fi.innerframe.topleft); + //origin = paintpos + framebardest:= arect; + if fdirection in [gd_right,gd_left] then begin + int1:= round(avalue*facedest.cx) + int2; + if fdirection = gd_left then begin + inc(framebardest.x,framebardest.cx - int1); + end; + framebardest.cx:= int1; + end + else begin + int1:= round(avalue*facedest.cy) + int3; + if fdirection = gd_up then begin + inc(framebardest.y,framebardest.cy - int1); + end; + framebardest.cy:= int1; + end; + facebardest:= deflaterect(framebardest,fbar_frame.innerframe); + subpoint1(facebardest.pos,pointty(fbar_frame.fpaintframe.topleft)); + //origin = paintpos + end; +end; + +procedure tcustomprogressbar.updatebar; +begin + updatebarrect(fvalue,innerclientrect,ffacerect,fframebarrect,ffacebarrect); +end; + +procedure tcustomprogressbar.clientrectchanged; +begin + inherited; + updatebar; +end; + +procedure tcustomprogressbar.dochange; +begin + updatebar; + inherited; +end; + +procedure tcustomprogressbar.changedirection(const avalue: graphicdirectionty; + var dest: graphicdirectionty); +begin + fbar_face.fade_direction:= rotatedirection(fbar_face.fade_direction,avalue,dest); + fbar_frame.changedirection(avalue,dest); + inherited; + updatebar; +end; + +procedure tcustomprogressbar.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; + const arect: rectty); +var + po1,po2,po3: prectty; + rect1,rect2,rect3: rectty; + rea1: realty; +begin + if @avalue = nil then begin + po1:= @ffacerect; + po2:= @fframebarrect; + po3:= @ffacebarrect; + rea1:= fvalue; + end + else begin + po1:= @rect1; + po2:= @rect2; + po3:= @rect3; + rea1:= realty(avalue); + updatebarrect(realty(avalue),arect,rect1,rect2,rect3); + end; + if not (rea1 = emptyreal) then begin + canvas.save; + fbar_frame.paintbackground(canvas,po2^,true,true); + //moves origin to paintrect and sets cliprect + canvas.intersectcliprect(po3^); + fbar_face.paint(canvas,po1^); + canvas.restore; + fbar_frame.paintoverlay(canvas,po2^); + if fformat <> '' then begin + drawtext(canvas,realtytostring(applyrange(rea1,fvaluerange,fvaluestart), + fformat),arect,ftextflags,ffont); + end; + end; + inherited; +end; + +procedure tcustomprogressbar.internalcreateframe; +begin + tdispframe.create(iscrollframe(self)); +end; + +procedure tcustomprogressbar.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tcustomprogressbar.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +procedure tcustomprogressbar.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tcustomprogressbar.settextflags(const avalue: textflagsty); +begin + ftextflags:= avalue; + formatchanged; +end; + +procedure tcustomprogressbar.setbar_frame(const avalue: tbarframe); +begin + fbar_frame.assign(avalue); +end; + +procedure tcustomprogressbar.doprogress(const sender: tobject; const avalue: real; + var acancel: boolean); +begin + application.lock; + try + value:= avalue; + acancel:= acancel or cancel; + if canevent(tmethod(fonprogress)) then begin + fonprogress(sender,avalue,acancel); + end; + if (acancel or (avalue >= 1.0)) and canevent(tmethod(fonfinished)) then begin + fonfinished(sender,avalue,acancel); + end; + finally + application.unlock; + end; +end; + +procedure tcustomprogressbar.readformat(reader: treader); +begin + fformat:= treader_readmsestring(reader); +// {$ifdef mse_unicodestring} +// fformat:= reader.readunicodestring; +// {$else} +// fformat:= reader.readwidestring; +// {$endif} +end; + +procedure tcustomprogressbar.writeformat(writer: twriter); +begin + twriter_writemsestring(writer,fformat); +// {$ifdef mse_unicodestring} +// writer.writeunicodestring(fformat); +// {$else} +// writer.writewidestring(fformat); +// {$endif} +end; + +procedure tcustomprogressbar.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tcustomprogressbar.defineproperties(filer: tfiler); +begin + filer.defineproperty('format',{$ifdef FPC}@{$endif}readformat, + {$ifdef FPC}@{$endif}writeformat,true); + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + +procedure tcustomprogressbar.gridtovalue(arow: integer); +begin + inherited; + updatebar(); +end; + +{ tsliderframe } + +procedure tsliderframe.settemplateinfo(const ainfo: frameinfoty); +begin + inherited; + if not (frl1_colorglyph in flocalprops1) and + (ainfo.ba.colorglyph <> cl_default) then begin + tslider(fintf.getwidget).scrollbar.colorglyph:= ainfo.ba.colorglyph; + end; + if not (frl1_colorpattern in flocalprops1) and + (ainfo.ba.colorpattern <> cl_default) then begin + tslider(fintf.getwidget).scrollbar.colorpattern:= ainfo.ba.colorpattern; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/mselistbrowser.pas b/mseide-msegui/lib/common/editwidgets/mselistbrowser.pas new file mode 100644 index 0000000..ffa86b4 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/mselistbrowser.pas @@ -0,0 +1,7180 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mselistbrowser; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseglob,classes,mclasses,msegrids,msedatanodes,msedatalist,msedragglob, + msegraphics,msegraphutils,msetypes,msestrings,msemenus,msestockobjects, + msebitmap,mseclasses,mseguiglob,msedrawtext,msefileutils,msedataedits, + mseeditglob,msewidgetgrid,msewidgets,mseedit,mseevent,msegui,msedropdownlist, + msesys,msedrag,msestat,mseinplaceedit,msepointer,msegridsglob, + mserichstring,msearrayprops,msevaluenodesglob + {$ifdef mse_with_ifi} + ,mseificomp,mseifiglob,mseificompglob,mseifigui + {$endif} + ; + +const + defaultcellwidth = 50; + defaultcellheight = 50; + defaultcellwidthmin = 10; + defaultitemedittextflags = defaulttextflags + [tf_clipo]; + defaultitemedittextflagsactive = defaulttextflagsactive + [tf_clipo]; + +type + listviewoptionty = ( //matched with coloptionty + lvo_readonly,lvo_mousemoving,lvo_keymoving,lvo_horz, + lvo_drawfocus,lvo_mousemovefocus, + lvo_leftbuttonfocusonly,lvo_middlebuttonfocus, + lvo_noctrlmousefocus, + lvo_focusselect,lvo_mouseselect,lvo_keyselect, + lvo_multiselect,lvo_resetselectonexit,{lvo_noresetselect,} + lvo_fill, + lvo_locate,lvo_casesensitive,lvo_savevalue,lvo_savestate, + lvo_hintclippedtext + ); + listviewoptionsty = set of listviewoptionty; + + filelistviewoptionty = (flvo_maskcasesensitive, //dso_casesensitive, + flvo_maskcaseinsensitive, //dso_caseinsensitive + flvo_nodirselect,flvo_nofileselect,flvo_checksubdir); + //same layout as dirstreamoptionty + filelistviewoptionsty = set of filelistviewoptionty; + +const + defaultlistviewoptionsgrid = defaultoptionsgrid + [og_wraprow,og_mousescrollcol]; + defaultlistviewoptions = [lvo_focusselect,lvo_mouseselect,lvo_drawfocus, + lvo_leftbuttonfocusonly,lvo_locate]; + defaultfilelistviewoptions = [flvo_nodirselect]; + coloptionsmask: listviewoptionsty = + [lvo_readonly,{lvo_mousemoving,lvo_keymoving,lvo_horz,} + lvo_drawfocus,lvo_mousemovefocus,lvo_leftbuttonfocusonly, + lvo_middlebuttonfocus, + lvo_noctrlmousefocus, + lvo_focusselect,lvo_mouseselect,lvo_keyselect, + lvo_multiselect,lvo_resetselectonexit{,lvo_noresetselect}]; +// lvo_coloptions = lvo_drawfocus; + +type + tcustomlistview = class; + + tlistedititem = class(tlistitem) + end; + + listedititemarty = array of tlistitem; + listedititemclassty = class of tlistedititem; + + trichlistedititem = class(tlistedititem) + private + function getrichcaption: richstringty; + procedure setrichcaption(const avalue: richstringty); + procedure setcaptionformat(const avalue: formatinfoarty); + protected + fformat: formatinfoarty; + public + procedure updatecaption(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty; + var ainfo: drawtextinfoty); override; + property richcaption: richstringty read getrichcaption write setrichcaption; + property captionformat: formatinfoarty read fformat write setcaptionformat; + end; + + tlisteditvalueitem = class(tlistitem) + protected + end; + + ttreeitemeditlist = class; + ttreelistedititem = class; + treelistedititemclassty = class of ttreelistedititem; + treelistedititemarty = array of ttreelistedititem; + treelistedititematy = array[0..0] of ttreelistedititem; + ptreelistedititematy = ^treelistedititematy; + + ttreeitemedit = class; + + ttreelistedititem = class(ttreelistitem) + private + factiveindex: integer; + function getactiveindex: integer; + public + constructor create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); override; + procedure assign(source: ttreeitemeditlist); overload; + //source remains owner of items, parent of items is unchanged + function add(const aitem: ttreelistedititem): integer; overload; + //returns index, nil ignored + procedure add(const aitems: treelistedititemarty); overload; + function add(const itemclass: treelistedititemclassty = nil): + ttreelistedititem; overload; + procedure add(const acount: integer; + const itemclass: treelistedititemclassty = nil); overload; + procedure add(const captions: array of msestring; + const itemclass: treelistedititemclassty = nil); overload; + property activeindex: integer read getactiveindex; + function endtreerow: integer; + //returns index of last row of tree + function editwidget: ttreeitemedit; + procedure activate; + end; + ptreelistedititem = ^ttreelistedititem; + + tdirtreenode = class(ttreelistedititem) + protected + procedure checkfiles(var afiles: filenamearty); virtual; + public + procedure loaddirtree(const apath: filenamety); virtual; + function path(const astart: integer = 0): filenamety; + end; + + createlistitemeventty = procedure(const sender: tcustomitemlist; + var item: tlistedititem) of object; + createtreelistitemeventty = procedure(const sender: tcustomitemlist; + var item: ttreelistedititem) of object; + nodenotificationeventty = procedure(const sender: tlistitem; + var action: nodeactionty) of object; + listitemeventty = procedure(const sender: tobject; + const aitem: tlistitem) of object; + + titemviewlist = class; + + paintlistitemeventty = procedure(const sender: titemviewlist; + const canvas: tcanvas; const item: tlistedititem) of object; + +const + defaultboxids: treeitemboxidarty = ( + //tib_none, tib_empty, tib_expand, tib_expanded + -1,ord(stg_box),ord(stg_boxexpand),ord(stg_boxexpanded), + //tib_checkbox, tib_checkboxchecked + ord(stg_checkbox),ord(stg_checkboxchecked), + //tib_checkboxparentnotchecked,tib_checkboxchildchecked + ord(stg_checkboxparentnotchecked),ord(stg_checkboxchildchecked), + //tib_checkboxchildnotchecked + ord(stg_checkboxchildnotchecked) + ); +type + titemviewlist = class(tcustomitemlist,iitemlist) + private + flistview: tcustomlistview; + fonpaintitem: paintlistitemeventty; + function getoncreateitem: createlistitemeventty; + procedure setoncreateitem(const Value: createlistitemeventty); + protected + flayoutinfo: listitemlayoutinfoty; + procedure doitemchange(const index: integer); override; + procedure updatelayout; override; + procedure invalidate; override; + + //iitemlist + function getgrid: tcustomgrid; + function getlayoutinfo(const acellinfo: pcellinfoty): plistitemlayoutinfoty; + procedure itemcountchanged; +// function getcolorglyph: colorty; + procedure updateitemvalues(const index: integer; const acount: integer); + function getcomponentstate: tcomponentstate; + + public + constructor create(const alistview: tcustomlistview); + property listview: tcustomlistview read flistview; + property layoutinfo: listitemlayoutinfoty read flayoutinfo; + published + property oncreateitem: createlistitemeventty read getoncreateitem + write setoncreateitem; + property onpaintitem: paintlistitemeventty read fonpaintitem + write fonpaintitem; + property options; + property captionpos; + property fonts; + property imnr_base; + property imagelist; + property imagewidth; + property imageheight; + property imagealignment; + end; + + + tlistcol = class(tdatacol) + private + function getitems(const aindex: integer): tlistitem; + procedure setitems(const aindex: integer; const Value: tlistitem); + protected + function getselected(const row: integer): boolean; override; + procedure setselected(const row: integer; value: boolean); override; + procedure drawcell(const acanvas: tcanvas); override; + procedure setwidth(const Value: integer); override; + procedure setoptions(const Value: coloptionsty); override; + procedure docellevent(var info: celleventinfoty); override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + procedure updatecellzone(const row: integer; const pos: pointty; + var result: cellzonety); override; + property items[const aindex: integer]: tlistitem read getitems write setitems; + default; + end; + + tlistcols = class(tdatacols) + protected + procedure changeselectedrange(const start,oldend,newend: gridcoordty; + calldoselectcell: boolean); override; + procedure gridrecttoindex(const rect: gridrectty; out start,stop: integer); + procedure dostatread(const reader: tstatreader; + const aorder: boolean); override; + procedure dostatwrite(const writer: tstatwriter; + const aorder: boolean); override; + public + constructor create(aowner: tcustomlistview); + procedure setselectedrange(const start,stop: gridcoordty; + const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); overload; override; + end; + + itemeventty = procedure(const sender: tcustomlistview; const index: integer; + var info: celleventinfoty) of object; + + tlistitemdragobject = class(tobjectdragobject) + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aitem: tlistitem); + function item: tlistitem; + end; + + tlistitemsdragobject = class(tdragobject) + private + fitems: listitemarty; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aitems: array of tlistitem); + property items: listitemarty read fitems; + end; + + listvieweventty = procedure(const sender: tcustomlistview) of object; + + tcustomlistview = class(tcellgrid,iedit) + private + feditor: tinplaceedit; + fonitemevent: itemeventty; + fcellwidthmax: integer; + fcellwidthmin: integer; + foptions: listviewoptionsty; + fcellwidth: integer; + fcolorglyph: colorty; + fcolorglyphactive: colorty; + fediting: boolean; + fonitemsmoved: gridblockmovedeventty; + fcellframe: tcellframe; + foncopytoclipboard: updatestringeventty; + fonpastefromclipboard: updatestringeventty; + fcellcursor: cursorshapety; + fglyphversionactive: int32; + procedure createcellframe; + function getcellframe: tcellframe; + procedure setcellframe(const avalue: tcellframe); + function getitems(const index: integer): tlistitem; + procedure setitems(const index: integer; const Value: tlistitem); + procedure setitemlist(value: titemviewlist); + procedure setcellwidthmax(const Value: integer); + procedure setcellwidthmin(Value: integer); + procedure initdatacol(const item: tdatacol); + procedure updatecoloptions; + procedure setcellwidth(const Value: integer); + function getcolorselect: colorty; + procedure setcolorselect(const Value: colorty); + procedure setcolorglyph(const Value: colorty); + procedure setcolorglyphactive(const Value: colorty); + procedure setediting(const Value: boolean); + function getkeystring(const index: integer): msestring; + function getfocusedindex: integer; + procedure setfocusedindex(const avalue: integer); + procedure setupeditor(const newcell: gridcoordty{; posonly: boolean}); + function getdatacollinecolor: colorty; + function getdatacollinewidth: integer; + procedure setdatacollinecolor(const Value: colorty); + procedure setdatacollinewidth(const Value: integer); + function getcellfocusrectdist: integer; + procedure setcellfocusrectdist(const avalue: integer); + function getonselectionchanged: listvieweventty; + procedure setonselectionchanged(const avalue: listvieweventty); + function getonlayoutchanged: listvieweventty; + procedure setonlayoutchanged(const avalue: listvieweventty); + function getcellheight: integer; + procedure setcellheight(const avalue: integer); + function getonbeforeupdatelayout: listvieweventty; + procedure setonbeforeupdatelayout(const avalue: listvieweventty); + function getcellheightmin: integer; + procedure setcellheightmin(const avalue: integer); + function getcellheightmax: integer; + procedure setcellheightmax(const avalue: integer); + procedure setcellcursor(const avalue: cursorshapety); + function getcellsize: sizety; + procedure setcellsize(const avalue: sizety); + procedure setglyphversionactive(const avalue: int32); + protected + fitemlist: titemviewlist; + class function classskininfo: skininfoty; override; + procedure setframeinstance(instance: tcustomframe); override; + procedure limitcellwidth(var avalue: integer); + + procedure setoptions(const avalue: listviewoptionsty); virtual; + procedure rootchanged(const aflags: rootchangeflagsty); override; + procedure doitemchange(index: integer); + procedure doitemevent(const index: integer; + var info: celleventinfoty); virtual; + procedure docellevent(var info: celleventinfoty); override; + function createdatacols: tdatacols; override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure updatelayout; override; + procedure drawfocusedcell(const acanvas: tcanvas); override; + procedure loaded; override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure scrolled(const dist: pointty); override; + + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + + //iedit + function getoptionsedit: optionseditty; + procedure editnotification(var info: editnotificationinfoty); + function hasselection: boolean; + procedure updatecopytoclipboard(var atext: msestring); virtual; + procedure updatepastefromclipboard(var atext: msestring); virtual; + function locatecount: integer; virtual; //number of locate values + function locatecurrentindex: integer; virtual; //index of current row + procedure locatesetcurrentindex(const aindex: integer); + function getedited: boolean; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure synctofontheight; override; + function internaldragevent(var info: draginfoty): boolean; override; + //true if processed + procedure moveitem(const source,dest: tlistitem; focus: boolean); + function indextocell(const index: integer): gridcoordty; + function celltoindex(const cell: gridcoordty; limit: boolean): integer; + function itematpos(const apos: pointty): tlistitem; + function focuseditem: tlistitem; + property focusedindex: integer read getfocusedindex write setfocusedindex; + function celltoitem(const acell: gridcoordty): tlistitem; + function finditembycaption(const acaption: msestring): tlistitem; + function findcellbycaption(const acaption: msestring; + var cell: gridcoordty): boolean; + function getselecteditems: listitemarty; + function getselectedindexes: integerarty; + + property items[const index: integer]: tlistitem read getitems + write setitems; default; + property editing: boolean read fediting write setediting; + property editor: tinplaceedit read feditor; + + property colorselect: colorty read getcolorselect + write setcolorselect default cl_default; + property colorglyph: colorty read fcolorglyph + write setcolorglyph default cl_glyph; + property colorglyphactive: colorty read fcolorglyphactive + write setcolorglyphactive default cl_glyphactive; + property glyphversionactive: int32 read fglyphversionactive write + setglyphversionactive default 0; + property cellwidth: integer read fcellwidth write setcellwidth + default defaultcellwidth; + property cellheight: integer read getcellheight write setcellheight + default defaultcellheight; + property cellheightmin: integer read getcellheightmin write setcellheightmin + default 1; + property cellheightmax: integer read getcellheightmax write setcellheightmax + default maxint; + property cellwidthmin: integer read fcellwidthmin + write setcellwidthmin default defaultcellwidthmin; + property cellwidthmax: integer read fcellwidthmax + write setcellwidthmax default 0; + property cellsize: sizety read getcellsize write setcellsize; + property cellframe: tcellframe read getcellframe write setcellframe; + property cellcursor: cursorshapety read fcellcursor write setcellcursor + default cr_default; + + property itemlist: titemviewlist read fitemlist write setitemlist; + property options: listviewoptionsty read foptions write setoptions + default defaultlistviewoptions; + property cellfocusrectdist: integer read getcellfocusrectdist + write setcellfocusrectdist default 0; + property datacollinewidth: integer read getdatacollinewidth + write setdatacollinewidth default defaultgridlinewidth; + property datacollinecolor: colorty read getdatacollinecolor + write setdatacollinecolor default defaultdatalinecolor; + property onitemevent: itemeventty read fonitemevent write fonitemevent; + + property onitemsmoved: gridblockmovedeventty read fonitemsmoved + write fonitemsmoved; + property optionsgrid default defaultlistviewoptionsgrid; + property onselectionchanged: listvieweventty read getonselectionchanged + write setonselectionchanged; + property onbeforeupdatelayout: listvieweventty read getonbeforeupdatelayout + write setonbeforeupdatelayout; + property onlayoutchanged: listvieweventty read getonlayoutchanged + write setonlayoutchanged; + property oncopytoclipboard: updatestringeventty read foncopytoclipboard + write foncopytoclipboard; + property onpastefromclipboard: updatestringeventty read fonpastefromclipboard + write fonpastefromclipboard; + end; + + tlistview = class(tcustomlistview) + published + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datacollinewidth; + property datacollinecolor; + property colorselect; + property colorglyph; + property cellwidth; + property cellheight; + property cellframe; + property cellcursor; + property cellfocusrectdist; + property fixcols; + property fixrows; + property optionsgrid; + property optionsgrid1; + property options; + property gridframecolor; + property itemlist; + property cellwidthmin; + property cellwidthmax; + property cellheightmin; + property cellheightmax; + property statvarname; + property statpriority; + property statfile; + property onselectionchanged; + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property onitemevent; + property drag; + property onitemsmoved; + property oncopytoclipboard; + property onpastefromclipboard; + end; + + tcustomitemedit = class; + + tcustomitemeditlist = class(tcustomitemlist,iimagelistinfo) + private + fcolorglyph: colorty; + fcolorglyphactive: colorty; + fcolorline: colorty; + fcolorlineactive: colorty; + fowner: tcustomitemedit; + fonitemnotification: nodenotificationeventty; +// fboxglyph_list: timagelist; +// fboxglyph_listactive: timagelist; + fboxglyph_versionactive: int32; + procedure setcolorglyph(const avalue: colorty); + procedure setcolorglyphactive(const avalue: colorty); + function getboxglyph_checkbox: stockglyphty; + procedure setboxglyph_checkbox(const avalue: stockglyphty); + function getboxglyph_checkboxchecked: stockglyphty; + procedure setboxglyph_checkboxchecked(const avalue: stockglyphty); + function getboxglyph_checkboxparentnotchecked: stockglyphty; + procedure setboxglyph_checkboxparentnotchecked(const avalue: stockglyphty); + function getboxglyph_checkboxchildchecked: stockglyphty; + procedure setboxglyph_checkboxchildchecked(const avalue: stockglyphty); + function getboxglyph_checkboxchildnotchecked: stockglyphty; + procedure setboxglyph_checkboxchildnotchecked(const avalue: stockglyphty); +// procedure setboxglyp_list(const avalue: timagelist); +// procedure setboxglyp_listactive(const avalue: timagelist); + procedure setboxglyph_versionactive(const avalue: int32); + protected + fboxids: treeitemboxidarty; + procedure createstatitem(const reader: tstatreader; + out item: tlistitem); override; + procedure doitemchange(const index: integer); override; + procedure nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); override; + function compare(const l,r): integer; override; + class function defaultitemclass(): listedititemclassty; virtual; + procedure itemclasschanged(); + //iimagelistinfo + function getimagelist: timagelist; + public + constructor create; overload; override; + constructor create(const intf: iitemlist; + const owner: tcustomitemedit); reintroduce; overload; + procedure assign(const aitems: listitemarty); reintroduce; overload; + procedure insert(const aindex: integer; const anode: tlistitem); + procedure add(const anode: tlistitem); + procedure refreshitemvalues(aindex: integer = 0; //-1 = current grid row + acount: integer = -1); //-1 = all + property owner: tcustomitemedit read fowner; + property colorglyph: colorty read fcolorglyph + write setcolorglyph default cl_glyph; + //for monochrome imagelist + property colorglyphactive: colorty read fcolorglyphactive + write setcolorglyphactive default cl_glyphactive; + //for monochrome imagelist +// property boxglyph_list: timagelist read fboxglyph_list write setboxglyp_list; +// property boxglyph_listactive: timagelist read fboxglyph_listactive +// write setboxglyp_listactive; + property boxglyph_versionactive: int32 read fboxglyph_versionactive write + setboxglyph_versionactive default 0; + property boxglyph_checkbox: stockglyphty read getboxglyph_checkbox + write setboxglyph_checkbox default stg_checkbox; + property boxglyph_checkboxchecked: stockglyphty + read getboxglyph_checkboxchecked + write setboxglyph_checkboxchecked default stg_checkboxchecked; + property boxglyph_checkboxparentnotchecked: stockglyphty + read getboxglyph_checkboxparentnotchecked + write setboxglyph_checkboxparentnotchecked + default stg_checkboxparentnotchecked; + property boxglyph_checkboxchildchecked: stockglyphty + read getboxglyph_checkboxchildchecked + write setboxglyph_checkboxchildchecked default stg_checkboxchildchecked; + property boxglyph_checkboxchildnotchecked: stockglyphty + read getboxglyph_checkboxchildnotchecked + write setboxglyph_checkboxchildnotchecked + default stg_checkboxchildnotchecked; + property onitemnotification: nodenotificationeventty + read fonitemnotification write fonitemnotification; + published + end; + + titemeditlist = class(tcustomitemeditlist) + private + procedure setoncreateitem(const value: createlistitemeventty); + function getoncreateitem: createlistitemeventty; + function getitemclass: listedititemclassty; + procedure setitemclass(const avalue: listedititemclassty); + protected + public + property itemclass: listedititemclassty read getitemclass write setitemclass; + published + property colorglyph; + property colorglyphactive; + property boxglyph_versionactive; +// property boxglyph_list; +// property boxglyph_listactive; + property boxglyph_checkbox; + property boxglyph_checkboxchecked; + property boxglyph_checkboxparentnotchecked; + property boxglyph_checkboxchildchecked; + property imnr_base; + property imnr_expanded; + property imnr_selected; + property imnr_readonly; + property imnr_checked; + property imnr_subitems; + property imnr_focused; + property imnr_active; + property imagelist; + property imagewidth; + property imageheight; + property imagealignment; + property defaultnodestate; + property captionpos; + property fonts; + property options; + property onitemnotification; + property oncreateitem: createlistitemeventty read getoncreateitem + write setoncreateitem; + property onstatreaditem; + property onstatwrite; + property onstatread; + end; + + trecordfielditem = class(tlistedititem) + protected + fvalueitem: tlistitem; + function getvalueitem: tlistitem; override; + procedure setvalueitem(const avalue: tlistitem); override; + public + end; + + trecordfielditemeditlist = class(titemeditlist) + protected + class function defaultitemclass(): listedititemclassty; override; + end; + + valueeditinfoty = record + datatype: listdatatypety; + valueindex: int32; + editwidget: twidget; + gridintf: igridwidget; + visible: boolean; + end; + pvalueeditinfoty = ^valueeditinfoty; + + tvalueedititem = class(townedpersistent) + private + finfo: valueeditinfoty; + procedure seteditwidget(const avalue: twidget); + procedure setvalueindex(const avalue: int32); + protected + procedure changed(); + public + destructor destroy(); override; + published + property valueindex: int32 read finfo.valueindex write + setvalueindex default 0; + property editwidget: twidget read finfo.editwidget write seteditwidget; + end; + + tvalueedits = class(townedpersistentarrayprop) + public + constructor create(const aowner: tcustomitemedit); reintroduce; + class function getitemclasstype: persistentclassty; override; + published + end; + + itemindexeventty = procedure(const sender: tobject; const aindex: integer; + const aitem: tlistitem) of object; + itemcanediteventty = procedure(const sender: tobject; + const aitem: tlistitem; var canedit: boolean) of object; + + extendimageeventty = procedure(const sender: twidget; + const cellinfopo: pcellinfoty; //nil for non cell call + var ainfo: extrainfoty) of object; + tcustomitemedit = class(tdataedit,iitemlist,ibutton) + private + fitemlist: tcustomitemeditlist; + fonsetvalue: setstringeventty; + fonclientmouseevent: mouseeventty; + fonbuttonaction: buttoneventty; + fonupdaterowvalues: itemindexeventty; + foncellevent: celleventty; + factiverow: integer; + fcalcsize: sizety; + foncheckcanedit: itemcanediteventty; + fonextendimage: extendimageeventty; + + fvalueedits: tvalueedits; + {$ifdef mse_with_ifi} + fitemifilink: boolean; + {$endif} + function getframe: tbuttonsframe; + procedure setframe(const avalue: tbuttonsframe); + function getitemlist: titemeditlist; + procedure setitemlist(const Value: titemeditlist); + function getitems(const index: integer): tlistitem; + procedure setitems(const index: integer; const Value: tlistitem); + function getediting: boolean; + procedure setediting(const avalue: boolean); + {$ifdef mse_with_ifi} + function getifilink: tifistringlinkcomp; + procedure setifilink(const avalue: tifistringlinkcomp); + function getifilink1: tifilinkcomp; + procedure setifilink1(const avalue: tifilinkcomp); +// function getifiitemlink: tifiitemlinkcomp; +// procedure setifiitemlink(const avalue: tifiitemlinkcomp); + {$endif} + procedure setvalueedits(const avalue: tvalueedits); + protected + factiveinfo: valueeditinfoty; + fvisiblevalueeditcount: int32; + flastzonewidget: twidget; + flayoutinfofocused: listitemlayoutinfoty; + flayoutinfocell: listitemlayoutinfoty; + fentryedge: graphicdirectionty; + fvalue: tlistitem; + + procedure valueeditchanged(); + procedure unregisterchildwidget(const child: twidget); override; + //track removing of field edits + procedure loaded(); override; + procedure dofocus; override; + + function valuecanedit: boolean; + procedure doextendimage(const cellinfopo: pcellinfoty; + var ainfo: extrainfoty); virtual; + procedure getautopaintsize(var asize: sizety); override; + procedure getautocellsize(const acanvas: tcanvas; + var asize: sizety); override; + procedure calclayout(const asize: sizety; + out alayout: listitemlayoutinfoty); + function finddataedits(aitem: tlistitem; out ainfos: recvaluearty): boolean; + function updateeditwidget(): boolean; //true if editwidgetactivated + procedure childdataentered(const sender: igridwidget); override; + procedure childfocused(const sender: igridwidget); override; + + {$ifdef mse_with_ifi} + //iifidatalink + procedure updateifigriddata(const sender: tobject; + const alist: tdatalist); override; + {$endif} + + //iedit + function locatecount: integer; override; //number of locate values + function getkeystring(const index: integer): msestring; override; + + procedure itemchanged(const index: integer); virtual; + procedure createnode(var item: tlistitem); virtual; + + procedure doupdatelayout(const nocolinvalidate: boolean); virtual; + procedure doupdatecelllayout; virtual; + + //iitemlist + function getgrid: tcustomgrid; + function getlayoutinfo(const acellinfo: pcellinfoty): plistitemlayoutinfoty; + procedure itemcountchanged; +// function getcolorglyph: colorty; + + //igridwidget + procedure setfirstclick(var ainfo: mouseeventinfoty); override; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; override; + procedure updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); override; + procedure setgridintf(const intf: iwidgetgrid); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure datalistdestroyed; override; + function getdatalistclass: datalistclassty; override; + procedure drawcell(const canvas: tcanvas); override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + function internaldatatotext(const data): msestring; override; + procedure dosetvalue(var avalue: msestring; var accept: boolean); virtual; + procedure storevalue(var avalue: msestring); virtual; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure clientrectchanged; override; + procedure updatelayout(); + procedure doitembuttonpress(var info: mouseeventinfoty); virtual; + procedure clientmouseevent(var info: mouseeventinfoty); override; + function getitemclass: listitemclassty; virtual; + procedure setupeditor; override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure dokeydown(var info: keyeventinfoty); override; + + procedure getitemvalues; virtual; + procedure internalcreateframe; override; + + //ibuttonaction + procedure buttonaction(var action: buttonactionty; + const buttonindex: integer); virtual; + + procedure mouseevent(var info: mouseeventinfoty); override; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + + function getoptionsedit: optionseditty; override; + property editing: boolean read getediting write setediting; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure insertwidget(const awidget: twidget; + const apos: pointty); override; + function textclipped(const arow: integer; + out acellrect: rectty): boolean; overload; override; + function getvaluetext: msestring; + procedure setvaluetext(var avalue: msestring); + function isnull: boolean; override; + function item: tlistedititem; + property items[const index: integer]: tlistitem read getitems + write setitems; default; + function selecteditems: listedititemarty; + + procedure beginedit; + procedure endedit; + procedure updateitemvalues(const index: integer; + const count: integer); virtual; + procedure updateitemvalues; + //calls updateitemvalues for current grid row + property activerow: integer read factiverow; + published + property itemlist: titemeditlist read getitemlist + write setitemlist stored false; +{$ifdef mse_with_ifi} + property ifilink: tifistringlinkcomp read getifilink write setifilink; +// property ifiitemlink: tifiitemlinkcomp read getifiitemlink +// write setifiitemlink; +{$endif} + property onsetvalue: setstringeventty read fonsetvalue write fonsetvalue; + property onclientmouseevent: mouseeventty read fonclientmouseevent + write fonclientmouseevent; + property optionsedit1; //before optionsedit! + property optionsedit; + property font; + property passwordchar; + property maxlength; + property textflags default defaultitemedittextflags; + property textflagsactive default defaultitemedittextflagsactive; + property frame: tbuttonsframe read getframe write setframe; + property valueedits: tvalueedits read fvalueedits write setvalueedits; + property onchange; +// property onbeforepaint; +// property onpaintbackground; +// property onpaint; + property onpaintimage; + property onextendimage: extendimageeventty read fonextendimage + write fonextendimage; +// property onafterpaint; + property onbuttonaction: buttoneventty read fonbuttonaction + write fonbuttonaction; + property onupdaterowvalues: itemindexeventty read fonupdaterowvalues + write fonupdaterowvalues; + property oncellevent: celleventty read foncellevent write foncellevent; + property oncheckcanedit: itemcanediteventty read foncheckcanedit + write foncheckcanedit; + end; + + titemedit = class; + + titemclientcontroller = class(tvalueclientcontroller) + private + fitemedit: tcustomitemedit; + function getitemlist(): titemeditlist; + function getitemedit: titemedit; + protected + function createdatalist: tdatalist override; + function getlistdatatypes: listdatatypesty override; + function getlistitem(): tlistedititem; + procedure linkset(const alink: iificlient); override; + public + property item: tlistedititem read getlistitem; + property itemlist: titemeditlist read getitemlist; + property itemedit: titemedit read getitemedit; + end; + + tifiitemlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: titemclientcontroller; + procedure setcontroller(const avalue: titemclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: titemclientcontroller read getcontroller + write setcontroller; + published + property controller: titemclientcontroller read getcontroller + write setcontroller; + end; + + titemedit = class(tcustomitemedit) + private + {$ifdef mse_with_ifi} + function getifiitemlink: tifiitemlinkcomp; + procedure setifiitemlink(const avalue: tifiitemlinkcomp); + {$endif} + published +{$ifdef mse_with_ifi} + property ifiitemlink: tifiitemlinkcomp read getifiitemlink + write setifiitemlink; +{$endif} + end; + + tdropdownitemedit = class(titemedit,idropdownlist) + private + fdropdown: tcustomdropdownlistcontroller; + fonbeforedropdown: notifyeventty; + fonafterclosedropdown: notifyeventty; + procedure setdropdown(const Value: tcustomdropdownlistcontroller); + protected + procedure doupdatecelllayout; override; + function getframe: tdropdownmultibuttonframe; + procedure setframe(const avalue: tdropdownmultibuttonframe); + function getdropdowncontrollerclass: dropdownlistcontrollerclassty; virtual; + //idropdown + procedure dobeforedropdown; virtual; + procedure doafterclosedropdown; virtual; + function getdropdownitems: tdropdowndatacols; + function getvalueempty: integer; virtual; + procedure imagelistchanged; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tdropdownmultibuttonframe read getframe write setframe; + property dropdown: tcustomdropdownlistcontroller read fdropdown + write setdropdown; + property onbeforedropdown: notifyeventty read fonbeforedropdown + write fonbeforedropdown; + property onafterclosedropdown: notifyeventty read fonafterclosedropdown + write fonafterclosedropdown; + end; + + tmbdropdownitemedit = class(tdropdownitemedit) + //redundant, all dropdowns are multibutton + private + protected + function getframe: tdropdownmultibuttonframe; + procedure setframe(const Value: tdropdownmultibuttonframe); + function getdropdowncontrollerclass: dropdownlistcontrollerclassty; override; + published + property frame: tdropdownmultibuttonframe read getframe write setframe; + end; + + ttreeeditnode = class(ttreenode) + protected + function listitemclass: treelistitemclassty; override; + public + function converttotreelistitem(flat: boolean = false; + withrootnode: boolean = false; + filterfunc: treenodefilterfuncty = nil): ttreelistedititem; + end; + + ttreeitemdragobject = class(tdragobject) + private + fitem: ttreelistitem; + fdestrow: integer; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aitem: ttreelistitem); + property item: ttreelistitem read fitem; + property destrow: integer read fdestrow; + end; + + treeitemdragbegineventty = procedure(const sender: ttreeitemedit; + const aitem: ttreelistitem; + var candrag: boolean; var dragobject: ttreeitemdragobject; + var processed: boolean) of object; + treeitemdragovereventty = procedure(const sender: ttreeitemedit; + const source,dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var accept: boolean; + var processed: boolean) of object; + treeitemdragdropeventty = procedure(const sender: ttreeitemedit; + const source,dest: ttreelistitem; + var dragobject: ttreeitemdragobject; + var processed: boolean) of object; + + expandedinfoty = record + path: msestringarty; + end; + expandedinfoarty = array of expandedinfoty; + + ttreeitemeditlist = class(tcustomitemeditlist) + private + fchangingnode: ttreelistitem; + finsertcount: integer; + finsertindex: integer; + fondragbegin: treeitemdragbegineventty; + fondragover: treeitemdragovereventty; + fondragdrop: treeitemdragdropeventty; + frootnode: ttreelistedititem; + finsertparent: ttreelistedititem; + finsertparentindex: integer; +// foptionsdraw: itemdrawoptionsty; + procedure setoncreateitem(const value: createtreelistitemeventty); + function getoncreateitem: createtreelistitemeventty; + procedure setcolorline(const value: colorty); + procedure setcolorlineactive(const value: colorty); + function getonstatreaditem: statreadtreeitemeventty; + procedure setonstatreaditem(const avalue: statreadtreeitemeventty); + function getitems1(const index: integer): ttreelistedititem; + procedure setitems(const index: integer; const avalue: ttreelistedititem); + function getitemclass: treelistedititemclassty; + procedure setitemclass(const avalue: treelistedititemclassty); + function getexpandedstate: expandedinfoarty; + procedure setexpandedstate(const avalue: expandedinfoarty); + function getonstatwriteitem: statwritetreeitemeventty; + procedure setonstatwriteitem(const avalue: statwritetreeitemeventty); + procedure setrootnode(const avalue: ttreelistedititem); + function getboxglyph_empty: stockglyphty; + procedure setboxglyph_empty(const avalue: stockglyphty); + function getboxglyph_expand: stockglyphty; + procedure setboxglyph_expand(const avalue: stockglyphty); + function getboxglyph_expanded: stockglyphty; + procedure setboxglyph_expanded(const avalue: stockglyphty); +// procedure setoptionsdraw(const avalue: itemdrawoptionsty); +{ + function getboxglyphactive_empty: stockglyphty; + procedure setboxglyphactive_empty(const avalue: stockglyphty); + function getboxglyphactive_expand: stockglyphty; + procedure setboxglyphactive_expand(const avalue: stockglyphty); + function getboxglyphactive_expanded: stockglyphty; + procedure setboxglyphactive_expanded(const avalue: stockglyphty); +} + protected +// fboxidsactive: treeitemboxidarty; + procedure freedata(var data); override; + procedure docreateobject(var instance: tobject); override; + procedure createitem(out item: tlistitem); override; + procedure nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); override; + function compare(const l,r): integer; override; + procedure statreaditem(const reader: tstatreader; + var aitem: tlistitem); override; + procedure statwriteitem(const writer: tstatwriter; + const aitem: tlistitem); override; + procedure readstate(const reader; const acount: integer; + const aname: msestring); override; + procedure writestate(const writer; const name: msestring); override; + procedure beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); + procedure afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); + public + constructor create; overload; override; + constructor create(const intf: iitemlist; const aowner: ttreeitemedit); + reintroduce; overload; + procedure beginupdate; override; + procedure endupdate; override; + procedure change(const index: integer); override; + procedure deleteitems(index,acount: integer); override; + procedure insertitems(index,acount: integer); override; + + procedure assign(const root: ttreelistedititem; + const freeroot: boolean = true); reintroduce; overload; + procedure assign(const aitems: treelistedititemarty); reintroduce; overload; + procedure add(const anode: ttreelistedititem; + const freeroot: boolean = true); overload; + + //adds toplevel node + procedure add(const anodes: treelistedititemarty); overload; + procedure add(const acount: integer; + aitemclass: treelistedititemclassty = nil); overload; + procedure addchildren(const anode: ttreelistedititem); + //adds children as toplevel nodes + procedure insert(const aindex: integer;const anode: ttreelistedititem; + const freeroot: boolean = true); + //inserts in parent of items[aindex] + procedure delete(const aindex: integer); + procedure readnode(const aname: msestring; const reader: tstatreader; + const anode: ttreelistitem); + procedure writenode(const aname: msestring; const writer: tstatwriter; + const anode: ttreelistitem); + procedure updatenode(const aname: msestring; const filer: tstatfiler; + const anode: ttreelistitem); + + function toplevelnodes: treelistedititemarty; + function getnodes(const must: nodestatesty; const mustnot: nodestatesty; + const amode: getnodemodety = gno_matching): treelistitemarty; + function getselectednodes(const amode: getnodemodety = + gno_matching): treelistitemarty; + function getcheckednodes(const amode: getnodemodety = + gno_matching): treelistitemarty; + procedure updatechildcheckedtree; //slow! + procedure updatechildnotcheckedtree; //slow! + procedure updateparentnotcheckedtree; //slow! + + procedure expandall; + procedure collapseall; + procedure moverow(const source,dest: integer); + //source and dest must belong to the same parent, ignored otherwise + property itemclass: treelistedititemclassty read getitemclass + write setitemclass; + property items[const index: integer]: ttreelistedititem read getitems1 + write setitems; default; + property expandedstate: expandedinfoarty read getexpandedstate + write setexpandedstate; + + property rootnode: ttreelistedititem read frootnode write setrootnode; + //clears list and adds children + property insertparent: ttreelistedititem read finsertparent; + //valid in oncreateitem + property insertparentindex: integer read finsertparentindex; + //valid in oncreateitem + published + property colorglyph; + property colorglyphactive; + property boxglyph_versionactive; +// property boxglyph_list; +// property boxglyph_listactive; + property boxglyph_checkbox; + property boxglyph_checkboxchecked; + property boxglyph_checkboxparentnotchecked; + property boxglyph_checkboxchildchecked; + property imnr_base; + property imnr_expanded; + property imnr_selected; + property imnr_readonly; + property imnr_checked; + property imnr_subitems; + property imnr_focused; + property imnr_active; + property imagelist; + property imagewidth; + property imageheight; + property imagealignment; + property defaultnodestate; + property captionpos; + property fonts; + property options; + property onitemnotification; +// property optionsdraw: itemdrawoptionsty read foptionsdraw +// write setoptionsdraw default []; + property colorline: colorty read fcolorline write setcolorline + default cl_treeline; + property colorlineactive: colorty read fcolorlineactive + write setcolorlineactive default cl_treelineactive; + property boxglyph_empty: stockglyphty read getboxglyph_empty + write setboxglyph_empty default stg_box; + property boxglyph_expand: stockglyphty read getboxglyph_expand + write setboxglyph_expand default stg_boxexpand; + property boxglyph_expanded: stockglyphty read getboxglyph_expanded + write setboxglyph_expanded default stg_boxexpanded; +{ + property boxglyphactive_empty: stockglyphty read getboxglyphactive_empty + write setboxglyphactive_empty default stg_box; + property boxglyphactive_expand: stockglyphty read getboxglyphactive_expand + write setboxglyphactive_expand default stg_boxexpand; + property boxglyphactive_expanded: stockglyphty + read getboxglyphactive_expanded + write setboxglyphactive_expanded default stg_boxexpanded; +} + property oncreateitem: createtreelistitemeventty read getoncreateitem + write setoncreateitem; + property onstatwriteitem: statwritetreeitemeventty read getonstatwriteitem + write setonstatwriteitem; + property onstatreaditem: statreadtreeitemeventty read getonstatreaditem + write setonstatreaditem; + property onstatwrite; + property onstatread; + property ondragbegin: treeitemdragbegineventty read fondragbegin + write fondragbegin; + property ondragover: treeitemdragovereventty read fondragover + write fondragover; + property ondragdrop: treeitemdragdropeventty read fondragdrop + write fondragdrop; + property levelstep; + end; + + treeitemeditoptionty = (teo_treecolnavig,teo_treerownavig,teo_keyrowmoving, + teo_enteronimageclick,teo_enterondoubleclick); + treeitemeditoptionsty = set of treeitemeditoptionty; + + checkmoveeventty = procedure(const curindex,newindex: integer; + var accept: boolean) of object; + + trecordfieldedit = class(tmbdropdownitemedit) + private + fitemedit: ttreeitemedit; + protected + procedure storevalue(var avalue: msestring); override; +// procedure dosetvalue(var avalue: msestring; var accept: boolean); override; + function getoptionsedit: optionseditty; override; + public + constructor create(aowner: tcomponent); override; + end; + + ttreeitemclientcontroller = class(titemclientcontroller) + private + protected + function getlistitem(): ttreelistedititem; + function getitemlist(): ttreeitemeditlist; + function getitemedit(): ttreeitemedit; + public + property item: ttreelistedititem read getlistitem; + property itemlist: ttreeitemeditlist read getitemlist; + property itemedit: ttreeitemedit read getitemedit; + end; + + tifitreeitemlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: ttreeitemclientcontroller; + procedure setcontroller(const avalue: ttreeitemclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: ttreeitemclientcontroller read getcontroller + write setcontroller; + published + property controller: ttreeitemclientcontroller read getcontroller + write setcontroller; + end; + + ttreeitemedit = class(tcustomitemedit,idragcontroller) + private + foptions: treeitemeditoptionsty; + foncheckrowmove: checkmoveeventty; + ffieldedit: trecordfieldedit; + function getitemlist: ttreeitemeditlist; + procedure setitemlist(const Value: ttreeitemeditlist); + function getitems(const index: integer): ttreelistedititem; + procedure setitems(const index: integer; const Value: ttreelistedititem); + procedure expandedchanged(const avalue: boolean); + procedure setfieldedit(const avalue: trecordfieldedit); + private + {$ifdef mse_with_ifi} + function getifiitemlink: tifitreeitemlinkcomp; + procedure setifiitemlink(const avalue: tifitreeitemlinkcomp); + {$endif} + protected + procedure doitembuttonpress(var info: mouseeventinfoty); override; + function locatecount: integer; override; //number of locate values + function locatecurrentindex: integer; override; //index of current row + procedure locatesetcurrentindex(const aindex: integer); override; + function getkeystring(const aindex: integer): msestring; override; + //locate text + procedure doupdatelayout(const nocolinvalidate: boolean); override; +// function getitemclass: listitemclassty; override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + function checkrowmove(const curindex,newindex: integer): boolean; + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); override; + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); override; + function getdatalistclass: datalistclassty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function item: ttreelistedititem; + property items[const index: integer]: ttreelistedititem read getitems + write setitems; default; + function selecteditems: treelistedititemarty; + + function candragsource(const apos: pointty): boolean; + procedure dragdrop(const adragobject: ttreeitemdragobject); + procedure comparerow(const lindex,rindex: integer; var aresult: integer); + procedure updateitemvalues(const index: integer; + const count: integer); override; + procedure updateitemvalues(); + procedure updateparentvalues(const index: integer); + published + property itemlist: ttreeitemeditlist read getitemlist + write setitemlist stored false; + property fieldedit: trecordfieldedit read ffieldedit write setfieldedit; + property options: treeitemeditoptionsty read foptions + write foptions default []; +{$ifdef mse_with_ifi} + property ifiitemlink: tifitreeitemlinkcomp read getifiitemlink + write setifiitemlink; +{$endif} + property oncheckrowmove: checkmoveeventty read foncheckrowmove + write foncheckrowmove; + end; + +implementation +uses + sysutils,msebits,msekeyboard,msearrayutils,msevaluenodes; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdatalist1 = class(tdatalist); + tcustomgrid1 = class(tcustomgrid); + twidgetgrid1 = class(twidgetgrid); + ttreelistitem1 = class(ttreelistitem); + tlistitem1 = class(tlistitem); + tdatacol1 = class(tdatacol); + tframe1 = class(tcustomframe); + twidgetcol1 = class(twidgetcol); + tdatacols1 = class(tdatacols); + twidget1 = class(twidget); + +{ titemviewlist } + +constructor titemviewlist.create(const alistview: tcustomlistview); +begin + flistview:= alistview; + with flayoutinfo do begin + widget:= alistview; + boxids:= defaultboxids; + end; + inherited create(iitemlist(self)); +end; + +function titemviewlist.getlayoutinfo( + const acellinfo: pcellinfoty): plistitemlayoutinfoty; +begin + if acellinfo <> nil then begin + flayoutinfo.variable.glyphversion:= 0; + if cds_usecoloractive in acellinfo^.drawstate then begin + flayoutinfo.variable.colorglyph:= flistview.colorglyph; + if flistview.glyphversionactive < stockobjects.glyphs.versioncount then begin + flayoutinfo.variable.glyphversion:= flistview.glyphversionactive; + end; + end + else begin + flayoutinfo.variable.colorglyph:= flistview.colorglyphactive; + end; + end; + result:= @flayoutinfo; +end; + +procedure titemviewlist.itemcountchanged; +begin + flistview.layoutchanged; +end; + +procedure titemviewlist.doitemchange(const index: integer); +begin + inherited; + flistview.doitemchange(index); +end; + +procedure titemviewlist.invalidate; +begin + flistview.invalidate; +end; + +procedure titemviewlist.updatelayout; +begin + with flistview do begin + if fcellframe = nil then begin + tlistitem.calcitemlayout(makesize(cellwidth,cellheight),minimalframe, + self,flayoutinfo); + end + else begin +{$warnings off} + tlistitem.calcitemlayout(subsize(makesize(cellwidth,cellheight), + fcellframe.paintframedim), + tframe1(fcellframe).fi.innerframe,self,flayoutinfo); +{$warnings on} + end; + layoutchanged; + end; +// invalidate; +end; +{ +function titemviewlist.getcolorglyph: colorty; +begin + result:= flistview.fcolorglyph; +end; +} +procedure titemviewlist.updateitemvalues(const index: integer; + const acount: integer); +begin + //dummy +end; + +function titemviewlist.getcomponentstate: tcomponentstate; +begin + result:= flistview.componentstate; +end; + +function titemviewlist.getoncreateitem: createlistitemeventty; +begin + result:= createlistitemeventty(oncreateobject); +end; + +procedure titemviewlist.setoncreateitem(const value: createlistitemeventty); +begin + oncreateobject:= createobjecteventty(value); +end; + +function titemviewlist.getgrid: tcustomgrid; +begin + result:= flistview; +end; + +{ tlistcol } + +constructor tlistcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + inherited; + fwidth:= tcustomlistview(fcellinfo.grid).cellwidth; + foptions:= (foptions - [co_savestate]) + [co_mousescrollrow]; +end; + +procedure tlistcol.setwidth(const Value: integer); +var + int1: integer; +begin + int1:= value; + tcustomlistview(fcellinfo.grid).limitcellwidth(int1); + inherited setwidth(int1); + tcustomlistview(fcellinfo.grid).cellwidth:= fwidth; +end; + +procedure tlistcol.setoptions(const Value: coloptionsty); +begin + inherited setoptions(value - [co_savevalue]); +end; + +procedure tlistcol.drawcell(const acanvas: tcanvas); +var + item1: tlistitem; +begin + inherited; + with cellinfoty(acanvas.drawinfopo^) do begin + item1:= items[cell.row]; + if item1 <> nil then begin + item1.drawcell(acanvas); + with tcustomlistview(grid),fitemlist do begin + if assigned(fonpaintitem) then begin + fonpaintitem(fitemlist,acanvas,tlistedititem(pointer(item1))); + end; + end; + end; + end; +end; + +function tlistcol.getitems(const aindex: integer): tlistitem; +var + int1: integer; +begin + int1:= tcustomlistview(fcellinfo.grid).celltoindex( + makegridcoord(colindex,aindex),false); + if int1 >= 0 then begin + result:= tcustomlistview(fcellinfo.grid).fitemlist[int1]; + end + else begin + result:= nil; + end; +end; + +procedure tlistcol.setitems(const aindex: integer; const Value: tlistitem); +var + int1: integer; +begin + int1:= tcustomlistview(fcellinfo.grid).celltoindex( + makegridcoord(colindex,aindex),false); + if int1 >= 0 then begin + tcustomlistview(fcellinfo.grid).fitemlist[int1]:= value; + end; +end; + +procedure tlistcol.updatecellzone(const row: integer; const pos: pointty; + var result: cellzonety); +begin + if pointinrect(pos,tcustomlistview( + fcellinfo.grid).fitemlist.flayoutinfo.captionrect) then begin + result:= cz_caption; + end + else begin + if pointinrect(pos, + tcustomlistview(fcellinfo.grid).fitemlist.flayoutinfo.imagerect) then begin + result:= cz_image; + end + else begin + inherited; + end; + end; +end; + +function tlistcol.getselected(const row: integer): boolean; +var + int1: integer; +begin + int1:= tcustomlistview(fcellinfo.grid).celltoindex(makegridcoord(colindex,row), + false); + if int1 >= 0 then begin + result:= tcustomlistview(fcellinfo.grid).fitemlist[int1].selected; + end + else begin + result:= false; + end; +end; + +procedure tlistcol.setselected(const row: integer; value: boolean); + + procedure updateselected(const index: integer); + var + item: tlistitem; + begin + item:= items[index]; + if (item <> nil) and (item.selected <> value) then begin + include(tcustomgrid1(fcellinfo.grid).fstate,gs_selectionchanged); + item.selected:= value; + end; + end; + +var + int1: integer; +begin + if row < 0 then begin + for int1:= 0 to fcellinfo.grid.rowcount-1 do begin + updateselected(int1); + end; + end + else begin + updateselected(row); + end; + inherited; +end; + +procedure tlistcol.docellevent(var info: celleventinfoty); +var + hintinfo: hintinfoty; + item1: tlistitem; +begin + with tcustomlistview(fcellinfo.grid) do begin + if (lvo_hintclippedtext in foptions) and + (info.eventkind = cek_firstmousepark) and application.active and + getshowhint and (info.cell.row >= 0) then begin + item1:= self[info.cell.row]; + if item1 <> nil then begin + with item1 do begin + if captionclipped then begin + application.inithintinfo(hintinfo,fcellinfo.grid); + hintinfo.caption:= caption; + application.showhint(fcellinfo.grid,hintinfo); + end; + end; + end; + end; + end; + inherited; +end; + +{ tlistcols} + +constructor tlistcols.create(aowner: tcustomlistview); +begin + inherited create(aowner,tlistcol); +end; + +procedure tlistcols.gridrecttoindex(const rect: gridrectty; out start,stop: integer); +begin + if (rect.rowcount <= 0) or (rect.colcount <= 0) then begin + start:= -1; + stop:= -2; + end + else begin + with tcustomlistview(fgrid),rect do begin + start:= celltoindex(pos,true); + stop:= celltoindex(makegridcoord(col+colcount-1,row+rowcount-1),true); + if stop < 0 then begin + stop:= fitemlist.count-1; + if start < 0 then begin + stop:= start - 1; + end; + end; + end; + end; +end; + +procedure tlistcols.dostatread(const reader: tstatreader; + const aorder: boolean); +begin + inherited; + with tcustomlistview(fgrid) do begin + if (lvo_savevalue in foptions) and reader.candata then begin + reader.readdatalist('values',fitemlist); + end; + end; +end; + +procedure tlistcols.dostatwrite(const writer: tstatwriter; + const aorder: boolean); +begin + inherited; + with tcustomlistview(fgrid) do begin + if (lvo_savevalue in foptions) and writer.candata then begin + writer.writedatalist('values',fitemlist); + end; + end; +end; + +procedure tlistcols.setselectedrange(const start,stop: gridcoordty; + const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); +var + int1,int2,int3: integer; + sto1: gridcoordty; +begin + sto1:= stop; + if sto1.col < start.col then begin + inc(sto1.col); + end + else begin + if sto1.col = start.col then begin + exit; + end; + dec(sto1.col); + end; + if sto1.row < start.row then begin + inc(sto1.row); + end + else begin + if sto1.row = start.row then begin + exit; + end; + dec(sto1.row); + end; + + if value and checkmultiselect and + not (lvo_multiselect in tcustomlistview(fgrid).foptions) then begin + with tcustomlistview(fgrid) do begin + if calldoselectcell then begin + selectcell(invalidcell,csm_deselect); + selectcell(sto1,csm_select); + end + else begin + selected[invalidcell]:= false; + selected[sto1]:= true; + end; + end; + exit; + end; + + with tcustomlistview(fgrid) do begin + int1:= celltoindex(start,true); + int2:= celltoindex(sto1,true); + if int1 > int2 then begin //swap values + int3:= int1; + int1:= int2; + int2:= int3; + end; + if calldoselectcell and value then begin + for int1:= int1 to int2 do begin + selectcell(indextocell(int1),csm_select); + end; + end + else begin + for int1:= int1 to int2 do begin + selected[indextocell(int1)]:= value; + end; + end; + end; +end; + +procedure tlistcols.changeselectedrange(const start,oldend,newend: gridcoordty; + calldoselectcell: boolean); + + procedure select(start,stop: integer; value: boolean); + var + int1: integer; + mo1: cellselectmodety; + begin + with tcustomlistview(fgrid) do begin + if calldoselectcell then begin + if value then begin + mo1:= csm_select; + end + else begin + mo1:= csm_deselect; + end; + for int1:= start to stop do begin + selectcell(indextocell(int1),mo1{value,false}); + end; + end + else begin + for int1:= start to stop do begin + selected[indextocell(int1)]:= value; + end; + end; + end; + end; + +var + int1,int2,int3,int4,int5: integer; + +begin + with tcustomlistview(fgrid) do begin + if not (lvo_multiselect in options) then begin + if calldoselectcell then begin + selectcell(invalidcell,csm_deselect); + selectcell(newend,csm_select); + end + else begin + selected[invalidcell]:= false; + selected[newend]:= true; + end; + exit; + end; + int1:= celltoindex(start,true); + int2:= celltoindex(oldend,true); + int4:= celltoindex(newend,true); + int3:= int1; + if int2 < int1 then begin + int1:= int2; + int2:= int3; + end; + if int4 < int3 then begin + int5:= int4; + int4:= int3; + int3:= int5; + end; + end; + if (oldend.col >= 0) and (oldend.row >= 0) then begin + if (int1 > int4) or (int3 > int2) then begin + select(int1,int2,false); + select(int3,int4,true); + end + else begin + if int1 < int3 then begin + select(int1,int3-1,false) + end + else begin + if int1 > int3 then begin + select(int3,int1-1,true); + end; + end; + if int4 < int2 then begin + select(int4+1,int2,false) + end + else begin + if int4 > int2 then begin + select(int2+1,int4,true); + end; + end; + end; + end; +end; + +{ tlistitemdragobject } + +constructor tlistitemdragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; const aitem: tlistitem); +begin + inherited create(asender,instance,apickpos,aitem); +end; + +function tlistitemdragobject.item: tlistitem; +begin + result:= tlistitem(fdata); +end; + +{ tlistitemsdragobject } + +constructor tlistitemsdragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aitems: array of tlistitem); +var + i1: int32; +begin + setlength(fitems,length(aitems)); + for i1:= 0 to high(fitems) do begin + fitems[i1]:= aitems[i1]; + end; + inherited create(asender,instance,apickpos); +end; + +{ tcustomlistview } + +constructor tcustomlistview.create(aowner: tcomponent); +begin + foptions:= defaultlistviewoptions; + fcolorglyph:= cl_glyph; + fcolorglyphactive:= cl_glyphactive; + fcellcursor:= cr_default; + if fitemlist = nil then begin + fitemlist:= titemviewlist.create(self); + end; + inherited; + fstate:= fstate + [gs_islist]; + fcellwidthmin:= defaultcellwidthmin; + cellwidth:= defaultcellwidth; + cellheight:= defaultcellheight; + optionsgrid:= defaultlistviewoptionsgrid; + feditor:= tinplaceedit.create(self,iedit(self)); +end; + +destructor tcustomlistview.destroy; +begin + inherited; + feditor.Free; + fitemlist.Free; + fcellframe.free; +end; + +function tcustomlistview.createdatacols: tdatacols; +begin + result:= tlistcols.create(self); +end; + +procedure tcustomlistview.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= tlistcol.create(self,fdatacols); + initdatacol(item); +end; + +procedure tcustomlistview.initdatacol(const item: tdatacol); +var + opt1: coloptionsty; +begin +// item.options:= coloptionsty( +// replacebits( +// {$ifdef FPC}longword{$else}word{$endif}(foptionslist) shl listviewoptionshift, +// {$ifdef FPC}longword{$else}longword{$endif}(item.options), +// {$ifdef FPC}longword{$else}longword{$endif}(bitmask[integer(lvo_coloptions)+1]) +// shl listviewoptionshift)); + opt1:= coloptionsty( + replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(item.options), + {$ifdef FPC}longword{$else}longword{$endif}(coloptionsmask))); +// updatebit(longword(opt1),ord(co_savestate),lvo_savestate in foptions); + item.options:= opt1; + if fcellframe <> nil then begin + item.frame:= fcellframe; + end; +// tdatacol1(item).fcolorselect:= fcolorselect; +end; + +procedure tcustomlistview.updatecoloptions; +var + int1: integer; +begin + if not (csloading in componentstate) then begin + for int1:= 0 to fdatacols.count - 1 do begin + initdatacol(fdatacols[int1]); + end; + invalidate; + end; +end; + +procedure tcustomlistview.setframeinstance(instance: tcustomframe); +begin + if instance is tcellframe then begin + fcellframe:= tcellframe(instance); + end + else begin + inherited; + end; +end; + +procedure tcustomlistview.createcellframe; +begin + tcellframe.create(iscrollframe(self)); +end; + +function tcustomlistview.getcellframe: tcellframe; +begin + getoptionalobject(fcellframe,{$ifdef FPC}@{$endif}createcellframe); + result:= fcellframe; +end; + +procedure tcustomlistview.setcellframe(const avalue: tcellframe); +begin + setoptionalobject(avalue,fcellframe,{$ifdef FPC}@{$endif}createcellframe); +end; + +function tcustomlistview.getitems(const index: integer): tlistitem; +var + cell: gridcoordty; +begin + cell:= indextocell(index); + result:= tlistcol(fdatacols[cell.col])[cell.row]; +end; + +procedure tcustomlistview.setitems(const index: integer; const Value: tlistitem); +var + cell: gridcoordty; +begin + cell:= indextocell(index); + tlistcol(fdatacols[cell.col])[cell.row]:= value; +end; + +function tcustomlistview.celltoindex(const cell: gridcoordty; limit: boolean): integer; +begin + if (cell.row < 0) or (cell.col < 0) then begin + result:= -1; + end + else begin + internalupdatelayout; + if lvo_horz in foptions then begin + result:= cell.row*fdatacols.count + cell.col; + end + else begin + result:= cell.col*frowcount + cell.row; + end; + if result >= fitemlist.count then begin + if limit then begin + result:= fitemlist.count - 1; + end + else begin + result:= -1; + end; + end; + end; +end; + +function tcustomlistview.indextocell(const index: integer): gridcoordty; +begin + internalupdatelayout; + if (frowcount > 0) and (fdatacols.count > 0) then begin + if lvo_horz in foptions then begin + result.row:= index div fdatacols.count; + result.col:= index mod fdatacols.count; + end + else begin + result.col:= index div frowcount; + result.row:= index mod frowcount; + end; + end + else begin + result:= invalidcell; + end; +end; + +function tcustomlistview.itematpos(const apos: pointty): tlistitem; +var + int1: integer; +begin + int1:= celltoindex(cellatpos(apos),false); + if int1 >= 0 then begin + result:= fitemlist[int1]; + end + else begin + result:= nil; + end; +end; + +function tcustomlistview.celltoitem(const acell: gridcoordty): tlistitem; +var + int1: integer; +begin + int1:= celltoindex(acell,false); + if int1 >= 0 then begin + result:= fitemlist[int1]; + end + else begin + result:= nil; + end; +end; + +function tcustomlistview.focuseditem: tlistitem; +begin + result:= celltoitem(ffocusedcell); +end; + +function tcustomlistview.getfocusedindex: integer; +begin + result:= celltoindex(ffocusedcell,true); +end; + +procedure tcustomlistview.setfocusedindex(const avalue: integer); +begin + if (avalue < 0) or (avalue >= fitemlist.count) then begin + focuscell(invalidcell); + end + else begin + focuscell(indextocell(avalue)); + end; +end; + +function tcustomlistview.finditembycaption(const acaption: msestring): tlistitem; +var + int1: integer; + locopt: locatestringoptionsty; +begin + int1:= -1; + if lvo_casesensitive in foptions then begin + locopt:= [lso_exact,lso_casesensitive]; + end + else begin + locopt:= [lso_exact]; + end; + if locatestring(acaption,{$ifdef FPC}@{$endif}getkeystring,locopt, + fitemlist.count,int1) then begin + result:= fitemlist[int1]; + end + else begin + result:= nil; + end; +end; + +function tcustomlistview.findcellbycaption(const acaption: msestring; var cell: gridcoordty): boolean; +var + item1: tlistitem; +begin + item1:= finditembycaption(acaption); + if item1 <> nil then begin + result:= true; + cell:= indextocell(item1.index); + end + else begin + result:= false; + end; +end; + +procedure tcustomlistview.limitcellwidth(var avalue: integer); +begin + if (avalue <> 0) and (fcellwidthmin > avalue) then begin + avalue:= fcellwidthmin; + end; + if (fcellwidthmax <> 0) and (fcellwidthmax < avalue) then begin + avalue:= fcellwidthmax; + end; +end; + +procedure tcustomlistview.updatelayout; +var + int1,int2: integer; + bo1: boolean; + indexbefore: integer; + cell1: gridcoordty; + width1,height1: integer; +begin + indexbefore:= celltoindex(ffocusedcell,true); +// fitemlist.updatelayout; + width1:= fcellwidth; + height1:= datarowheight; + if lvo_fill in foptions then begin + inherited; + if lvo_horz in foptions then begin + width1:= fdatarect.cx - datacollinewidth; + end + else begin + height1:= fdatarect.cy - datarowlinewidth; + end; + end; + limitcellwidth(width1); + datarowheight:= height1; + for int1:= 0 to fdatacols.count-1 do begin + fdatacols[int1].width:= width1; + fdatacols[int1].cursor:= fcellcursor; + end; + fitemlist.updatelayout; + repeat + inherited; + bo1:= false; + if lvo_horz in foptions then begin + int1:= tlistcol.defaultstep(width1); + if int1 = 0 then begin + int1:= 1; + end; + int2:= fdatarect.cx div int1; + if int2 = 0 then begin + int2:= 1; + end; + if fdatacols.count <> int2 then begin + fdatacols.count:= int2; + bo1:= true; + end; + int1:= (fitemlist.count + int2 - 1) div int2; + if int1 <> frowcount then begin + rowcount:= int1; + bo1:= true; + end; + end + else begin + int1:= ystep; + if int1 = 0 then begin + int1:= 1; + end; + int2:= fdatarect.cy div int1; + if int2 = 0 then begin + int2:= 1; + end; + if rowcount <> int2 then begin + rowcount:= int2; + bo1:= true; + end; + int1:= (fitemlist.count + int2 - 1) div int2; + if int1 <> fdatacols.count then begin + fdatacols.count:= int1; + bo1:= true; + end; + end; + until not bo1; + if (indexbefore >= 0) then begin + cell1:= indextocell(indexbefore); + if (cell1.col <> ffocusedcell.col) or (cell1.row <> ffocusedcell.row) then begin + focuscell(cell1); + end; + setupeditor(ffocusedcell{,true}); + end; +end; + +procedure tcustomlistview.setitemlist(value: titemviewlist); +begin + fitemlist.Assign(value); +end; + +procedure tcustomlistview.setcellwidthmax(const Value: integer); +begin + if fcellwidthmax <> value then begin + fcellwidthmax:= Value; + layoutchanged; + end; +end; + +procedure tcustomlistview.setcellwidthmin(Value: integer); +begin + if value < 1 then begin + value:= 1; + end; + if fcellwidthmin <> value then begin + fcellwidthmin := Value; + layoutchanged; + end; +end; + +procedure tcustomlistview.drawfocusedcell(const acanvas: tcanvas); +var + pt1: pointty; + item1: tlistitem1; +begin + if cellinfoty(acanvas.drawinfopo^).calcautocellsize then begin + if focuseditem <> nil then begin + focuseditem.drawcell(acanvas); + end; + end + else begin + acanvas.save; + drawcellbackground(acanvas); + item1:= tlistitem1(focuseditem); + if item1 <> nil then begin + fitemlist.flayoutinfo.variable.calcautocellsize:= false; + item1.drawimage(acanvas,fitemlist.flayoutinfo); + if assigned(fitemlist.fonpaintitem) then begin + fitemlist.fonpaintitem(fitemlist,acanvas,tlistedititem(pointer(item1))); + end; + pt1:= cellrect(ffocusedcell,cil_paint).pos; + acanvas.remove(pt1); + feditor.dopaint(acanvas); + acanvas.move(pt1); + if feditor.lasttextclipped then begin + include(item1.fstate1,ns1_captionclipped); + end + else begin + exclude(item1.fstate1,ns1_captionclipped); + end; + end; + acanvas.restore; + drawcelloverlay(acanvas); + end; +end; + +procedure tcustomlistview.setoptions(const avalue: listviewoptionsty); +const + mask: listviewoptionsty = [lvo_horz,lvo_fill]; +var + optbefore: listviewoptionsty; +begin + if foptions <> avalue then begin + optbefore:= foptions; + foptions:= avalue; + updatecoloptions; + if (longword(foptions) xor longword(optbefore)) and + longword(mask) <> 0 then begin + layoutchanged; + end; + end; +end; + +function tcustomlistview.getcellfocusrectdist: integer; +begin + result:= fdatacols.focusrectdist; +end; + +procedure tcustomlistview.setcellfocusrectdist(const avalue: integer); +begin + fdatacols.focusrectdist:= avalue; +end; + +procedure tcustomlistview.loaded; +begin + inherited; + updatecoloptions; +end; + +function tcustomlistview.locatecount: integer; //number of locate values +begin + result:= fitemlist.count; +end; + +function tcustomlistview.locatecurrentindex: integer; //index of current row +begin + result:= celltoindex(ffocusedcell,false); +end; + +procedure tcustomlistview.locatesetcurrentindex(const aindex: integer); +begin + focuscell(indextocell(aindex)); +end; + +function tcustomlistview.getedited: boolean; +begin + result:= false; +end; + +function tcustomlistview.getkeystring(const index: integer): msestring; +begin + result:= fitemlist[index].caption; +end; + +procedure tcustomlistview.setediting(const Value: boolean); +var + item1: tlistitem; +begin + if fediting <> value then begin + if not (value and (lvo_readonly in foptions)) then begin + fediting := Value; + invalidatefocusedcell; + if not value then begin + if feditor.canundo then begin + item1:= focuseditem; + if item1 <> nil then begin + item1.caption:= feditor.text; + end; + end; + feditor.dodefocus; + end + else begin + feditor.dofocus; + end; + feditor.updatecaret; + end; + end; +end; + +procedure tcustomlistview.setupeditor(const newcell: gridcoordty{; + posonly: boolean}); +var + pt1: pointty; +// rect1,rect2: rectty; + int1: integer; +begin +// rect1:= moverect(fitemlist.flayoutinfo.captionrect,po1); +// rect2:= moverect(fitemlist.flayoutinfo.captioninnerrect,po1); + int1:= celltoindex(newcell,false); + if int1 >= 0 then begin +// if posonly then begin +// feditor.updatepos(rect2,rect1); +// end +// else begin +// feditor.setup(fitemlist[int1].caption,0,false,rect2,rect1,nil,nil,getfont); + + pt1:= cellrect(newcell,cil_paint).pos; + with fitemlist[int1] do begin +// if not posonly then begin + feditor.textflags:= fitemlist.flayoutinfo.textflags + [tf_clipo]; + feditor.textflagsactive:= feditor.textflags; + feditor.text:= caption; +// end; + setupeditor(feditor,getfont,true); + feditor.movepos(pt1); + end; + +// end; + end; +end; + +procedure tcustomlistview.docellevent(var info: celleventinfoty); +var + int1: integer; + +begin + if not (gs_layoutupdating in fstate) then begin + with info do begin + case eventkind of + cek_enter: begin + int1:= celltoindex(newcell,false); + if int1 < 0 then begin + focuscell(indextocell(fitemlist.count - 1),info.selectaction); + exit; + end; + setupeditor(newcell{,false}); + end; + cek_exit: begin + editing:= false; +// filtertext:= ''; + end; + cek_select: begin + if selected and (celltoindex(cell,false) < 0) then begin + accept:= false; + end; + end; + end; + end; + inherited; + int1:= celltoindex(info.cell,false); + if int1 >= 0 then begin + doitemevent(int1,info); + end; + end + else begin + inherited; + end; +end; + +procedure tcustomlistview.doitemevent(const index: integer; var info: celleventinfoty); +var + po1: pointty; +begin + with info do begin + if eventkind in mousecellevents then begin + fitemlist[index].mouseevent(mouseeventinfopo^); + if not (es_processed in mouseeventinfopo^.eventstate) then begin + po1:= mouseeventinfopo^.pos; + mouseeventinfopo^.pos:= gridmousepos; + if editing or (eventkind = cek_buttonrelease) or + (info.mouseeventinfopo^.shiftstate * keyshiftstatesmask = []) then begin + feditor.mouseevent(mouseeventinfopo^); + end; + if isdblclick(mouseeventinfopo^) then begin + editing:= true; + end; + mouseeventinfopo^.pos:= po1; + end; + end; + end; + if canevent(tmethod(fonitemevent)) then begin + fonitemevent(self,index,info); + end; +end; + +procedure tcustomlistview.setcellwidth(const Value: integer); +begin + if fcellwidth <> value then begin + fcellwidth:= Value; + layoutchanged; + end; +end; + +function tcustomlistview.getcellheight: integer; +begin + result:= datarowheight; +end; + +procedure tcustomlistview.setcellheight(const avalue: integer); +begin + datarowheight:= avalue; +{ + if fcellheight <> avalue then begin + fcellheight:= avalue; + layoutchanged; + end; +} +end; + +procedure tcustomlistview.rootchanged(const aflags: rootchangeflagsty); +begin + inherited; + feditor.poschanged; +end; + +procedure tcustomlistview.doitemchange(index: integer); + + procedure itemstatetocellstate(const itemindex: integer; const cell: gridcoordty); + begin + with fitemlist[itemindex] do begin + fdatacols.selected[cell]:= selected; + if (cell.row = ffocusedcell.row) and (cell.col = ffocusedcell.col) then begin + feditor.text:= caption; + end; + end; + end; + +var + cell: gridcoordty; + int1: integer; +begin + if index < 0 then begin + layoutchanged; + updatelayout; + beginupdate; + try + for int1:= fitemlist.count to rowcount * datacols.count - 1 do begin + fdatacols.selected[indextocell(int1)]:= false; //empty cells + end; + if focusedcellvalid() then begin + int1:= celltoindex(ffocusedcell,false); + if int1 >= 0 then begin + if (lvo_focusselect in foptions) then begin + itemlist[int1].selected:= true; + end; + itemstatetocellstate(int1,ffocusedcell); + end; + end; + finally + endupdate; + end; + end + else begin + cell:= indextocell(index); + invalidatecell(cell); + itemstatetocellstate(index,cell); + end; +end; + +function tcustomlistview.getcolorselect: colorty; +begin + result:= fdatacols.colorselect; +end; + +procedure tcustomlistview.setcolorselect(const Value: colorty); +begin + fdatacols.colorselect:= value; +end; + +procedure tcustomlistview.setcolorglyph(const Value: colorty); +begin + if fcolorglyph <> value then begin + fcolorglyph:= Value; + invalidate; + end; +end; + +procedure tcustomlistview.setcolorglyphactive(const Value: colorty); +begin + if fcolorglyphactive <> value then begin + fcolorglyphactive:= Value; + invalidate; + end; +end; + +procedure tcustomlistview.moveitem(const source,dest: tlistitem; focus: boolean); +var + int1: integer; +begin + int1:= source.index; + fitemlist.movedata(int1,dest.index); + if focus then begin + focuscell(indextocell(source.index)); + end; + if canevent(tmethod(fonitemsmoved)) then begin + fonitemsmoved(self,int1,source.index,1); + end; +end; + +procedure tcustomlistview.scrolled(const dist: pointty); +begin + inherited; + if focusedcellvalid then begin + feditor.scroll(dist); + end; +end; + +procedure tcustomlistview.dostatread(const reader: tstatreader); +begin + if lvo_savestate in foptions then begin + cellwidth:= reader.readinteger('cellwidth',cellwidth); + end; + inherited; +end; + +procedure tcustomlistview.dostatwrite(const writer: tstatwriter); +begin + if (lvo_savestate in foptions) and writer.canstate then begin + writer.writeinteger('cellwidth',cellwidth); + end; + inherited; +end; + +function tcustomlistview.getoptionsedit: optionseditty; +begin + result:= [oe_autoselect,oe_resetselectonexit,oe_exitoncursor]; + if lvo_locate in foptions then begin + include(result,oe_locate); + end; + if lvo_casesensitive in foptions then begin + include(result,oe_casesensitive); + end; + if not fediting then begin + include(result,oe_readonly); + end; +end; + +procedure tcustomlistview.editnotification(var info: editnotificationinfoty); +begin + //dummy +end; + +procedure tcustomlistview.synctofontheight; +var + int1: integer; +begin + inherited; + if cellframe = nil then begin + int1:= font.glyphheight + 2; + end + else begin + int1:= font.glyphheight + cellframe.innerframedim.cy; + end; + if (itemlist.imagelist <> nil) then begin + if itemlist.captionpos in [cp_left,cp_center,cp_right] then begin + if itemlist.imagelist.size.cy > int1 then begin + int1:= itemlist.imagelist.size.cy; + end; + end + else begin + int1:= int1 + itemlist.imagelist.size.cy; + end; + end; + cellheight:= int1; +end; + +function tcustomlistview.internaldragevent(var info: draginfoty): boolean; +var + item: tlistitem; +begin + if lvo_mousemoving in foptions then begin + result:= true; + with info do begin + item:= itematpos(pos); + if item <> nil then begin + case eventkind of + dek_begin: begin + tlistitemdragobject.create(self,dragobjectpo^,fdragcontroller.pickpos,item); + end; + dek_check: begin + accept:= (item <> focuseditem) and (info.dragobjectpo <> nil) and + isobjectdrag(info.dragobjectpo^,tlistitem) and + (tlistitem(tobjectdragobject(info.dragobjectpo^).data).owner = + fitemlist); + end; + dek_drop: begin + moveitem(tlistitemdragobject(dragobjectpo^).item,item,true); + end; + end; + end; + end; + end + else begin + result:= inherited internaldragevent(info); + end; +end; +(* +procedure tcustomlistview.setfiltertext(const value: msestring); +var + int1: integer; +begin + if value = '' then begin + ffiltertext:= ''; + end + else begin + int1:= celltoindex(ffocusedcell,false); + fitemlist.datapo; //normalize ring + if locatestring(value,{$ifdef FPC}@{$endif}getkeystring,[],fitemlist.count,int1) then begin + focuscell(indextocell(int1)); + ffiltertext:= value; + end; + end; + if not editing then begin + feditor.selstart:= 0; + feditor.sellength:= length(ffiltertext); + end; +end; +*) +procedure tcustomlistview.dokeydown(var info: keyeventinfoty); +var + item: tlistitem; + int1: integer; +// str1: msestring; + action1: focuscellactionty; +begin + with info do begin + feditor.dokeydown(info); +// if fediting then begin +// if ((key = key_left) or (key = key_right)) and (shiftstate - [ss_shift] = []) then begin +// include(eventstate,es_processed); +// end; +// end +// else begin + { + if (key = key_backspace) and (shiftstate = []) then begin + filtertext:= copy(ffiltertext,1,length(ffiltertext)-1); + end + else begin + if (key = key_home) and (shiftstate = []) then begin + filtertext:= ''; + end + else begin + str1:= mseextractprintchars(info.chars); + if (str1 <> '') and (shiftstate - [ss_shift] = []) then begin + filtertext:= ffiltertext + str1; + include(eventstate,es_processed); + end; + end; + end; + } +// end; + if not (es_processed in eventstate) then begin + if (lvo_keymoving in foptions) and (shiftstate = [ss_ctrl]) + and (focuseditem <> nil) then begin + item:= nil; + case info.key of + key_up: begin + if ffocusedcell.row > 0 then begin + item:= celltoitem(makegridcoord(ffocusedcell.col,ffocusedcell.row - 1)); + end; + end; + key_down: begin + if ffocusedcell.row < frowcount - 1 then begin + item:= celltoitem(makegridcoord(ffocusedcell.col,ffocusedcell.row + 1)); + end; + end; + key_left: begin + if ffocusedcell.col > 0 then begin + item:= celltoitem(makegridcoord(ffocusedcell.col - 1,ffocusedcell.row)); + end; + end; + key_right: begin + if ffocusedcell.col < fdatacols.count - 1 then begin + item:= celltoitem(makegridcoord(ffocusedcell.col + 1,ffocusedcell.row)); + end; + end; + end; + if item <> nil then begin + moveitem(focuseditem,item,true); + include(eventstate,es_processed); + end; + end; + if not (es_processed in info.eventstate) then begin + if (shiftstate = []) and isenterkey(nil,key) then begin + if not editing then begin + editing:= (focuseditem <> nil) and tlistitem1(focuseditem).cancaptionedit(); + if editing then begin + include(eventstate,es_processed); + end; + end + else begin + editing:= false; + include(eventstate,es_processed); + end; + end + else begin + if not editing and (ss_ctrl in shiftstate) and (shiftstate - [ss_ctrl,ss_shift] = []) and + ((key = key_home) or (key = key_end)) and (fitemlist.count > 0) then begin + include(eventstate,es_processed); + if ss_shift in shiftstate then begin + if lvo_keyselect in foptions then begin + action1:= fca_selectend; + end + else begin + action1:= fca_focusinshift; + end; + end + else begin + action1:= fca_focusin; + end; + if key = key_home then begin + focuscell(indextocell(0),action1); + end + else begin + focuscell(indextocell(fitemlist.count - 1),action1); + end; + end; + if not (es_processed in eventstate) and (shiftstate - [ss_shift] = []) and + (og_colchangeontabkey in foptionsgrid) and + (fitemlist.count > 0) then begin + int1:= celltoindex(ffocusedcell,true); + case key of + key_tab: begin + inc(int1); + if int1 = fitemlist.count then begin + int1:= 0; + end; + end; + key_backtab: begin + dec(int1); + if int1 < 0 then begin + int1:= fitemlist.count - 1; + end; + end; + else begin + int1:= -1; + end; + end; + if int1 >= 0 then begin + include(eventstate,es_processed); + focuscell(indextocell(int1)); + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; + end; + end; +end; + +function tcustomlistview.getdatacollinecolor: colorty; +begin + result:= fdatacols.linecolor; +end; + +procedure tcustomlistview.setdatacollinecolor(const Value: colorty); +begin + fdatacols.linecolor:= value; +end; + +function tcustomlistview.getdatacollinewidth: integer; +begin + result:= fdatacols.linewidth; +end; + +procedure tcustomlistview.setdatacollinewidth(const Value: integer); +begin + fdatacols.linewidth:= value; +end; + +procedure tcustomlistview.setcellcursor(const avalue: cursorshapety); +var + int1: integer; +begin + if avalue <> fcellcursor then begin + fcellcursor:= avalue; + with tdatacols1(fdatacols) do begin + cursor:= avalue; + for int1:= 0 to count-1 do begin + tdatacol(fitems[int1]).cursor:= avalue; + end; + end; + end; +end; + +function tcustomlistview.getcellsize: sizety; +begin + result:= ms(cellwidth,cellheight); +end; + +procedure tcustomlistview.setcellsize(const avalue: sizety); +begin + cellwidth:= avalue.cx; + cellheight:= avalue.cy; +end; + +procedure tcustomlistview.setglyphversionactive(const avalue: int32); +begin + if fglyphversionactive <> avalue then begin + fglyphversionactive:= avalue; + if fglyphversionactive < 0 then begin + fglyphversionactive:= 0; + end; + end; +end; + +class function tcustomlistview.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_dataedit; +end; + +function tcustomlistview.getonselectionchanged: listvieweventty; +begin + result:= listvieweventty(inherited onselectionchanged); +end; + +procedure tcustomlistview.setonselectionchanged(const avalue: listvieweventty); +begin + inherited onselectionchanged:= notifyeventty(avalue); +end; + +function tcustomlistview.getselecteditems: listitemarty; +begin + if datacols.hasselection then begin + result:= fitemlist.getselecteditems; + end + else begin + result:= nil; + end; +end; + +function tcustomlistview.getselectedindexes: integerarty; +begin + if datacols.hasselection then begin + result:= fitemlist.getselectedindexes(); + end + else begin + result:= nil; + end; +end; + +function tcustomlistview.hasselection: boolean; +begin + result:= false; +end; + +procedure tcustomlistview.updatecopytoclipboard(var atext: msestring); +begin + if canevent(tmethod(foncopytoclipboard)) then begin + foncopytoclipboard(self,atext); + end; +end; + +procedure tcustomlistview.updatepastefromclipboard(var atext: msestring); +begin + if canevent(tmethod(fonpastefromclipboard)) then begin + fonpastefromclipboard(self,atext); + end; +end; + +function tcustomlistview.getonlayoutchanged: listvieweventty; +begin + result:= listvieweventty(inherited onlayoutchanged); +end; + +procedure tcustomlistview.setonlayoutchanged(const avalue: listvieweventty); +begin + inherited onlayoutchanged:= gridnotifyeventty(avalue); +end; + +function tcustomlistview.getonbeforeupdatelayout: listvieweventty; +begin + result:= listvieweventty(inherited onbeforeupdatelayout); +end; + +procedure tcustomlistview.setonbeforeupdatelayout(const avalue: listvieweventty); +begin + inherited onbeforeupdatelayout:= gridnotifyeventty(avalue); +end; + +function tcustomlistview.getcellheightmin: integer; +begin + result:= datarowheightmin; +end; + +procedure tcustomlistview.setcellheightmin(const avalue: integer); +begin + datarowheightmin:= avalue; +end; + +function tcustomlistview.getcellheightmax: integer; +begin + result:= datarowheightmax; +end; + +procedure tcustomlistview.setcellheightmax(const avalue: integer); +begin + datarowheightmax:= avalue; +end; + +{ tcustomitemeditlist } + +constructor tcustomitemeditlist.create; +begin + fcolorglyph:= cl_glyph; + fcolorglyphactive:= cl_glyphactive; + fboxids:= defaultboxids; + inherited; + fitemclass:= defaultitemclass(); + fstate:= fstate + [dls_nogridstreaming,dls_propertystreaming]; +end; + +constructor tcustomitemeditlist.create(const intf: iitemlist; + const owner: tcustomitemedit); +begin + fowner:= owner; + inherited create(intf); +end; + +class function tcustomitemeditlist.defaultitemclass(): listedititemclassty; +begin + result:= tlistedititem; +end; + +procedure tcustomitemeditlist.itemclasschanged(); +begin + fowner.updatelayout(); +end; + +function tcustomitemeditlist.getimagelist: timagelist; +begin + result:= nil; +// result:= fboxglyph_list; +end; + +procedure tcustomitemeditlist.setcolorglyph(const avalue: colorty); +begin + if fcolorglyph <> avalue then begin + fcolorglyph:= avalue; + fowner.itemchanged(-1); + end; +end; + +procedure tcustomitemeditlist.setcolorglyphactive(const avalue: colorty); +begin + if fcolorglyphactive <> avalue then begin + fcolorglyphactive:= avalue; + fowner.itemchanged(-1); + end; +end; + +function tcustomitemeditlist.getboxglyph_checkbox: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_checkbox]); +end; + +procedure tcustomitemeditlist.setboxglyph_checkbox(const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_checkbox]) <> avalue then begin + stockglyphty(fboxids[tib_checkbox]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function tcustomitemeditlist.getboxglyph_checkboxchecked: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_checkboxchecked]); +end; + +procedure tcustomitemeditlist.setboxglyph_checkboxchecked( + const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_checkboxchecked]) <> avalue then begin + stockglyphty(fboxids[tib_checkboxchecked]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function tcustomitemeditlist.getboxglyph_checkboxparentnotchecked: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_checkboxparentnotchecked]); +end; + +procedure tcustomitemeditlist.setboxglyph_checkboxparentnotchecked( + const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_checkboxparentnotchecked]) <> avalue then begin + stockglyphty(fboxids[tib_checkboxparentnotchecked]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function tcustomitemeditlist.getboxglyph_checkboxchildchecked: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_checkboxchildchecked]); +end; + +procedure tcustomitemeditlist.setboxglyph_checkboxchildchecked( + const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_checkboxchildchecked]) <> avalue then begin + stockglyphty(fboxids[tib_checkboxchildchecked]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function tcustomitemeditlist.getboxglyph_checkboxchildnotchecked: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_checkboxchildnotchecked]); +end; + +procedure tcustomitemeditlist.setboxglyph_checkboxchildnotchecked( + const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_checkboxchildnotchecked]) <> avalue then begin + stockglyphty(fboxids[tib_checkboxchildnotchecked]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; +{ +procedure tcustomitemeditlist.setboxglyp_list(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fboxglyph_list)); +end; + +procedure tcustomitemeditlist.setboxglyp_listactive(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fboxglyph_listactive)); +end; +} +procedure tcustomitemeditlist.setboxglyph_versionactive(const avalue: int32); +begin + if fboxglyph_versionactive <> avalue then begin + fboxglyph_versionactive:= avalue; + if fboxglyph_versionactive < 0 then begin + fboxglyph_versionactive:= 0; + end; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +procedure tcustomitemeditlist.assign(const aitems: listitemarty); +var + po1: plistitem; + int1: integer; +begin + beginupdate; + try + exclude(fitemstate,ils_subnodecountupdating); //free nodes + clear; + include(fitemstate,ils_subnodecountupdating); + capacity:= length(aitems); + fcount:= length(aitems); + if fcount > 0 then begin + move(aitems[0],fdatapo^,length(aitems)*fsize); + end; + po1:= plistitem(fdatapo); + for int1:= 0 to fcount - 1 do begin + tlistitem1(po1^).setowner(self); + inc(po1); + end; + fintf.itemcountchanged; + fintf.updateitemvalues(0,fcount); + finally + endupdate; + end; +end; + +procedure tcustomitemeditlist.add(const anode: tlistitem); +var + int1: integer; +begin + checkitemclass(anode); + beginupdate; + try + int1:= internaladddata(anode,false); + tlistitem1(anode).setowner(self); + tlistitem1(anode).findex:= int1; + fintf.itemcountchanged; + fintf.updateitemvalues(int1,1); + finally + endupdate; + end; +// adddata(anode); +end; + +procedure tcustomitemeditlist.insert(const aindex: integer; + const anode: tlistitem); +begin + checkitemclass(anode); + with fintf.getgrid do begin + insertrow(aindex); + end; + tlistitem1(anode).setowner(self); + tlistitem1(anode).findex:= aindex; + items[aindex]:= anode; + fintf.updateitemvalues(aindex,1); +{ + beginupdate; + try + internalinsertdata(aindex,anode,false); + tlistitem1(anode).setowner(self); + tlistitem1(anode).findex:= aindex; + fintf.itemcountchanged; + fintf.updateitemvalues(aindex,1); + finally + endupdate; + end; +} +end; + +procedure tcustomitemeditlist.refreshitemvalues(aindex: integer = 0; + acount: integer = -1); +begin + beginupdate; + try + if aindex < 0 then begin + aindex:= fowner.gridrow; + end; + if (aindex >= 0) and (aindex < fcount) then begin + if acount < 0 then begin + acount:= fcount; + end; + if acount + aindex > fcount then begin + acount:= fcount - aindex; + end; + fintf.updateitemvalues(aindex,acount); + end; + finally + endupdate; + end; +end; + +procedure tcustomitemeditlist.doitemchange(const index: integer); +begin + if fowner <> nil then begin + fowner.itemchanged(index); + end; + inherited; +end; + +procedure tcustomitemeditlist.nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); +var + grid: tcustomgrid; +begin + if ainfo.action = na_destroying then begin + tlistitem1(sender).setowner(nil); + if not deleting then begin + grid:= fowner.fgridintf.getcol.grid; + if sender.index < grid.rowcount then begin + grid.deleterow(sender.index); + end; + end; + end + else begin + if not (ainfo.action in [na_change,na_valuechange,na_checkedchange]) or + (nochange = 0) then begin + if fowner.canevent(tmethod(fonitemnotification)) then begin + fonitemnotification(sender,ainfo.action); + end; + end; + inherited; + if ainfo.action in [na_expand,na_collapse] then begin + change(sender); + end; + if (nochange = 0) and + (ainfo.action in [na_valuechange,na_checkedchange]) and + not (ils_updateitemvalues in fitemstate) then begin + include(fitemstate,ils_updateitemvalues); + try + fintf.updateitemvalues(sender.index,1); + finally + exclude(fitemstate,ils_updateitemvalues); + end; + end; + end; +end; + +function tcustomitemeditlist.compare(const l,r): integer; +begin + result:= tlistitem1(l).compare(tlistitem(r), + oe_casesensitive in fowner.foptionsedit); +{ + if oe_casesensitive in fowner.foptionsedit then begin + result:= msecomparestr(tlistitem1(l).fcaption,tlistitem1(r).fcaption); + end + else begin + result:= msecomparetext(tlistitem1(l).fcaption,tlistitem1(r).fcaption); + end; +} +end; + +procedure tcustomitemeditlist.createstatitem(const reader: tstatreader; + out item: tlistitem); +var + i1: int32; +begin + if no_createvalueitems in foptions then begin + i1:= reader.readinteger(valuenodetypename); + if (i1 <= 0) or (i1 > ord(high(valuenodeclasses))) then begin + inherited; + end + else begin + item:= valuenodeclasses[listdatatypety(i1)].create(self); + end; + end + else begin + inherited; + end; +end; + +{ titemeditlist} + +function titemeditlist.getitemclass: listedititemclassty; +begin + result:= listedititemclassty(fitemclass); +end; + +procedure titemeditlist.setitemclass(const avalue: listedititemclassty); +begin + fitemclass:= avalue; + itemclasschanged(); +end; + +function titemeditlist.getoncreateitem: createlistitemeventty; +begin + result:= createlistitemeventty(oncreateobject); +end; + +procedure titemeditlist.setoncreateitem(const value: createlistitemeventty); +begin + oncreateobject:= createobjecteventty(value); +end; + +{ tvalueedititem } + +destructor tvalueedititem.destroy; +begin + editwidget:= nil; //remove link, objectlinker of owner is used. + inherited; +end; + +procedure tvalueedititem.changed; +begin + with tcustomitemedit(fowner) do begin + if componentstate * [csloading,csdestroying] = [] then begin + valueeditchanged(); + end; + end; +end; + +procedure tvalueedititem.seteditwidget(const avalue: twidget); +begin + if avalue <> finfo.editwidget then begin + if (avalue <> nil) and (not getcorbainterface(avalue,typeinfo(igridwidget), + finfo.gridintf) or + (avalue.parentwidget <> fowner)) then begin + raise exception.create('Invalid item field edit widget "'+avalue.name+'".'); + end; + if (finfo.editwidget <> nil) and (finfo.gridintf <> nil) then begin + finfo.gridintf.setparentgridwidget(nil); + end; + tcustomitemedit(fowner).setlinkedvar(avalue,tmsecomponent(finfo.editwidget)); + if avalue = nil then begin + finfo.gridintf:= nil; + finfo.datatype:= dl_none; + end + else begin + finfo.gridintf.setparentgridwidget(igridwidget(tcustomitemedit(fowner))); + finfo.datatype:= finfo.gridintf.getdatalistclass().datatype(); + end; + changed(); + end; +end; + +procedure tvalueedititem.setvalueindex(const avalue: int32); +begin + if finfo.valueindex <> avalue then begin + finfo.valueindex:= avalue; + changed(); + end; +end; + +{ tvalueedits } + +constructor tvalueedits.create(const aowner: tcustomitemedit); +begin + inherited create(aowner,tvalueedititem); +end; + +class function tvalueedits.getitemclasstype: persistentclassty; +begin + result:= tvalueedititem; +end; + +{ tcustomitemedit } + +constructor tcustomitemedit.create(aowner: tcomponent); +begin + fentryedge:= gd_none; + fvalueedits:= tvalueedits.create(self); + include(fstate,des_editing); +// fediting:= true; + if fitemlist = nil then begin + fitemlist:= titemeditlist.create(iitemlist(self),self); + end; + flayoutinfofocused.widget:= self; + inherited; + textflags:= defaultitemedittextflags; + textflagsactive:= defaultitemedittextflagsactive; +// createframe; +end; + +destructor tcustomitemedit.destroy; +begin + if fgridintf = nil then begin + freeandnil(fitemlist); + end; + fvalueedits.free(); + inherited; +end; + +function tcustomitemedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= fitemlist; +end; + +function tcustomitemedit.getdatalistclass: datalistclassty; +begin + result:= titemeditlist; +end; + +procedure tcustomitemedit.setgridintf(const intf: iwidgetgrid); +var + li1: tcustomitemeditlist; +begin + inherited; + if intf <> nil then begin + li1:= tcustomitemeditlist(intf.getcol.datalist); + if li1 <> nil then begin + if fitemlist = nil then begin //changed inherited grid col + fitemlist:= tcustomitemeditlist(intf.getcol.datalist); + end + else begin + if fitemlist <> li1 then begin + fitemlist.free; + fitemlist:= li1; + end; + end; + fitemlist.fowner:= self; + fitemlist.fintf:= iitemlist(self); + end; + if fitemlist.count > 0 then begin + itemcountchanged; + end + else begin + fitemlist.count:= intf.getcol.grid.rowcount; + end; + updatelayout; + end; +end; + +procedure tcustomitemedit.createnode(var item: tlistitem); +begin + item:= tlistitem.create(fitemlist); +end; + +function tcustomitemedit.getlayoutinfo( + const acellinfo: pcellinfoty): plistitemlayoutinfoty; +begin + if (ws1_painting in fwidgetstate1) or (des_updatelayout in fstate) then begin + result:= @flayoutinfofocused; //active + with result^.variable do begin + colorglyph:= fitemlist.fcolorglyphactive; + colorline:= fitemlist.fcolorlineactive; + glyphversion:= fitemlist.boxglyph_versionactive; + end; + end + else begin + result:= @flayoutinfocell; + if (acellinfo <> nil) and + ((acellinfo^.rect.cx <> fcalcsize.cx) or + (acellinfo^.rect.cy <> fcalcsize.cy)) then begin + fcalcsize:= acellinfo^.rect.size; + calclayout(fcalcsize,flayoutinfocell); + end; + end; + with result^.variable do begin + if acellinfo <> nil then begin + if cds_usecoloractive in acellinfo^.drawstate then begin + colorglyph:= fitemlist.fcolorglyphactive; + colorline:= fitemlist.fcolorlineactive; + glyphversion:= fitemlist.boxglyph_versionactive; + end + else begin + colorglyph:= fitemlist.fcolorglyph; + colorline:= fitemlist.fcolorline; + glyphversion:= 0; + end; + end; + if stockobjects.glyphs.versioncount <= glyphversion then begin + glyphversion:= 0; + end; + end; +end; + +procedure tcustomitemedit.updateitemvalues(const index: integer; const count: integer); +var + int1,int2: integer; + po1: plistitem; + po2: plistitematy; + col1: tdatacol; +begin + if (no_cellitemselect in fitemlist.options) and (fgridintf <> nil) then begin + col1:= fgridintf.getcol; + po2:= fitemlist.datapo; + for int1:= index to index + count - 1 do begin + col1.selected[int1]:= ns_selected in tlistitem1(po2^[int1]).fstate; + end; + end; + if canevent(tmethod(fonupdaterowvalues)) then begin + if index >= 0 then begin + if count > 1 then begin + fitemlist.beginupdate; + end; + try + po1:= fitemlist.datapo; + inc(po1,index); + int2:= index + count - 1; + if int2 >= fitemlist.fcount then begin + int2:= fitemlist.fcount - 1; + end; + for int1:= index to int2 do begin + fonupdaterowvalues(self,int1,po1^); + inc(po1); + end; + finally + if count > 1 then begin + fitemlist.endupdate; + end; + end; + end; + end; + if (fgridintf <> nil) then begin + {$warnings off} + with tcustomgrid1(fgridintf.getcol.grid) do begin + {$warnings on} +// sortinvalid(invalidaxis,invalidaxis); + rowdatachanged(makegridcoord(invalidaxis,index),count); +// if not fitemlist.updating then begin +// checksort; +// end; + end; + end; +end; + +procedure tcustomitemedit.updateitemvalues(); + //calls updateitemvalues for current grid row +var + int1: integer; +begin + if fgridintf <> nil then begin + int1:= fgridintf.getrow; + if int1 >= 0 then begin + updateitemvalues(int1,1); + end; + end; +end; + +procedure tcustomitemedit.itemcountchanged; +begin + fvalue:= nil; //invalid + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + rowcount:= fitemlist.count; +// rowdatachanged(makegridcoord(invalidaxis,0),fitemlist.count); + end; + end; +end; + +procedure tcustomitemedit.getitemvalues; +begin + if fvalue = nil then begin + text:= ''; + end + else begin + text:= fvalue.caption; + end; + updateeditwidget(); + setupeditor; +end; + +procedure tcustomitemedit.gridtovalue(arow: integer); +var + int1: integer; +begin + int1:= arow; + if int1 = -1 then begin + int1:= fgridintf.getcol.grid.row; + end; + if int1 < 0 then begin + fvalue:= nil; + end + else begin + fvalue:= fitemlist[int1]; + end; + getitemvalues; + inherited; +end; + +procedure tcustomitemedit.valuetogrid(arow: integer); +begin + if arow >= 0 then begin + fitemlist.incupdate; + try + updateitemvalues(arow,1); + finally + fitemlist.decupdate; + end; + end; +end; + +function tcustomitemedit.finddataedits(aitem: tlistitem; + out ainfos: recvaluearty): boolean; +var + i1,i2: int32; + po1: precvaluety; + intf1: irecordvaluefield; +begin + result:= false; + if (fvalueedits.count > 0) and (aitem <> nil) and + mseclasses.getcorbainterface(aitem.valueitem, + typeinfo(irecordvaluefield),intf1) then begin + +// (aitem is trecordlistedititem) then begin +// with irecordvaluefield(trecordlistedititem(aitem)) do begin + with intf1 do begin + getvalueinfo(ainfos); + for i1:= 0 to high(ainfos) do begin + po1:= @ainfos[i1]; + po1^.dummypointer:= nil; + if po1^.datatype <> dl_none then begin + if (po1^.valueindex >= 0) then begin + for i2:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i2]) do begin + if (finfo.datatype = po1^.datatype) and + (finfo.valueindex = po1^.valueindex) then begin + po1^.dummypointer:= @finfo; //check index match + result:= true; + break; + end; + end; + end; + end; + if po1^.dummypointer = nil then begin + for i2:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i2]) do begin + if finfo.datatype = po1^.datatype then begin + po1^.dummypointer:= @finfo; //check any match + result:= true; + break; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tcustomitemedit.updateeditwidget(): boolean; + //true if editwidgetactivated +var + infos1: recvaluearty; + i1: int32; + bo1: boolean; + widget1: twidget; +begin + result:= finddataedits(fvalue,infos1); + if result then begin + for i1:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i1]) do begin + finfo.visible:= false; + end; + end; + bo1:= false; + fvisiblevalueeditcount:= 0; + for i1:= 0 to high(infos1) do begin + with infos1[i1] do begin + if dummypointer <> nil then begin + with pvalueeditinfoty(dummypointer)^ do begin + if gridintf <> nil then begin + visible:= true; + gridintf.setvaluedata(valuead^); + editwidget.visible:= true; + inc(fvisiblevalueeditcount); + if not bo1 then begin + bo1:= true; + factiveinfo:= pvalueeditinfoty(dummypointer)^; +{ + if focused then begin + editwidget.setfocus(); + end; +} + end; + end; + end; + end; + end; + end; + for i1:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i1]) do begin + if not finfo.visible and (finfo.editwidget <> nil) then begin + finfo.editwidget.visible:= false; + end; + end; + end; + if focused then begin + widget1:= getcornerwidget(fentryedge,true); + if widget1 <> nil then begin + widget1.setfocus(); + end + else begin + if factiveinfo.editwidget <> nil then begin + factiveinfo.editwidget.setfocus(); + end; + end; + end; + end + else begin + fillchar(factiveinfo,sizeof(factiveinfo),0); + for i1:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i1]) do begin + finfo.visible:= false; + if finfo.editwidget <> nil then begin + finfo.editwidget.visible:= false; + end; + end; + end; + end; +end; + +procedure tcustomitemedit.drawcell(const canvas: tcanvas); +var + databefore: pointer; + infos1: recvaluearty; + i1: int32; + fra1,fra2: framety; + fs1: widgetstatesty; +begin + with cellinfoty(canvas.drawinfopo^) do begin + fs1:= []; + if focused then begin + include(fs1,ws_focused); + if active then begin + include(fs1,ws_active); + end; + end; + flayoutinfocell.variable.widgetstate:= fs1; + doextendimage(canvas.drawinfopo,flayoutinfocell.variable.extra); + flayoutinfocell.variable.rowindex:= cell.row; + flayoutinfocell.textflags:= textflags; + if finddataedits(tlistitem(datapo^),infos1) then begin + databefore:= datapo; + fra1:= getcellframe; + inflaterect1(innerrect,fra1); + for i1:= 0 to high(infos1) do begin + with infos1[i1] do begin + if dummypointer <> nil then begin + with pvalueeditinfoty(dummypointer)^ do begin + datapo:= valuead; + fra2:= gridintf.getcellframe; + deflaterect1(innerrect,fra2); + gridintf.drawcell(canvas); + inflaterect1(innerrect,fra2); + end; + end; + end; + datapo:= databefore; + deflaterect1(innerrect,fra1); + end; + end + else begin + tlistitem(datapo^).drawcell(canvas); + end; + end; + paintimage(canvas); +end; + +procedure tcustomitemedit.childdataentered(const sender: igridwidget); +var + intf1: irecordvaluefield; +begin + if sender = factiveinfo.gridintf then begin + if (fvalue <> nil) and mseclasses.getcorbainterface(fvalue.valueitem, + typeinfo(irecordvaluefield),intf1) then begin +// if fvalue is trecordlistedititem then begin +// with irecordvaluefield(trecordlistedititem(fvalue)) do begin + with intf1 do begin + setvalue(factiveinfo.datatype,factiveinfo.valueindex,@sender.getvaluedata); + end; + end; + end; +end; + +procedure tcustomitemedit.childfocused(const sender: igridwidget); +var + infos1: recvaluearty; + i1: int32; + widget1: twidget; + intf1: irecordvaluefield; +begin + if mseclasses.getcorbainterface(fvalue, + typeinfo(irecordvaluefield),intf1) then begin +// if fvalue is trecordlistedititem then begin + if finddataedits(tlistitem(fvalue),infos1) then begin + widget1:= sender.getwidget; + for i1:= 0 to high(infos1) do begin + with infos1[i1] do begin + if (dummypointer <> nil) then begin + with pvalueeditinfoty(dummypointer)^ do begin + if editwidget = widget1 then begin + factiveinfo:= pvalueeditinfoty(dummypointer)^; + break; + end; + end; + end; + end; + end; + end; + end; +end; + +function tcustomitemedit.internaldatatotext(const data): msestring; +var + po: plistitem; +begin + if @data = nil then begin + po:= @fvalue; + end + else begin + po:= @data; + end; + if po^ <> nil then begin + result:= po^.caption; + end + else begin + result:= ''; + end; +end; + +procedure tcustomitemedit.dosetvalue(var avalue: msestring; var accept: boolean); +begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,avalue,accept); + end; +end; + +procedure tcustomitemedit.storevalue(var avalue: msestring); +begin + fvalue.caption:= avalue; +end; + +procedure tcustomitemedit.texttovalue(var accept: boolean; const quiet: boolean); +var + mstr1: msestring; +begin + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + if not quiet then begin + dosetvalue(mstr1,accept); + end; + if accept and (fvalue <> nil) then begin + storevalue(mstr1); + end; +end; + +procedure tcustomitemedit.calclayout(const asize: sizety; + out alayout: listitemlayoutinfoty); +begin + if fframe <> nil then begin + getitemclass.calcitemlayout(asize,tframe1(fframe).fi.innerframe, + fitemlist,alayout); + end + else begin + getitemclass.calcitemlayout(asize,minimalframe,fitemlist,alayout); + end; + alayout.textflags:= textflags; +end; + +procedure tcustomitemedit.doupdatelayout(const nocolinvalidate: boolean); +begin + if (fgridintf <> nil) and (fitemlist <> nil) then begin + calclayout(paintrect.size,flayoutinfofocused); + invalidate; + if not fitemlist.updating and not nocolinvalidate then begin + fgridintf.getcol.changed; + end; + end; +end; + +procedure tcustomitemedit.doupdatecelllayout; +begin + flayoutinfocell:= flayoutinfofocused; + fcalcsize:= flayoutinfofocused.cellsize; +end; + +procedure tcustomitemedit.updatelayout; +begin + doupdatelayout(false); + doupdatecelllayout; +end; + +procedure tcustomitemedit.clientrectchanged; +var + bo1: boolean; +begin + doupdatelayout(true); //col invalidated by grid + doupdatecelllayout; + bo1:= des_updatelayout in fstate; + include(fstate,des_updatelayout); //for setupeditor + try + inherited; + finally + if not bo1 then begin + exclude(fstate,des_updatelayout); + end; + end; +end; + +procedure tcustomitemedit.doitembuttonpress(var info: mouseeventinfoty); +begin + //dummy +end; + +procedure tcustomitemedit.clientmouseevent(var info: mouseeventinfoty); +var + po1: pointty; + zone1: cellzonety; +begin + if (fvalue <> nil) and (info.eventkind in mouseposevents) then begin + zone1:= cz_default; + fvalue.updatecellzone(info.pos,zone1); + application.widgetcursorshape:= getcellcursor(-1,zone1,info.pos); + end; + if canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,info); + end; + if not (es_processed in info.eventstate) then begin + if fvalue <> nil then begin + if (info.eventkind = ek_buttonpress) and (fgridintf <> nil) then begin + with fgridintf.getcol.grid,frame do begin + po1:= scrollpos; + fvalue.mouseevent(info); + if not (es_processed in info.eventstate) then begin + doitembuttonpress(info); + end; + po1:= subpoint(scrollpos,po1); + if (po1.x <> 0) or (po1.y <> 0) then begin + self.releasemouse; + addpoint1(info.pos,po1); + end; + end; + end + else begin + fvalue.mouseevent(info); + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +function tcustomitemedit.getitemclass: listitemclassty; +begin +// result:= tlistitem; + result:= listitemclassty(fitemlist.fitemclass); +end; + +procedure tcustomitemedit.setupeditor; +var + bo1: boolean; +begin + if not (csloading in componentstate) then begin + if fvalue = nil then begin + with feditor,flayoutinfofocused do begin + feditor.setup(text,curindex,false,captioninnerrect,captionrect,nil,nil, + geteditfont); + end; + end + else begin + bo1:= des_updatelayout in fstate; + include(fstate,des_updatelayout); + doextendimage(nil,flayoutinfofocused.variable.extra); + fvalue.setupeditor(feditor,geteditfont,true); + if not bo1 then begin + exclude(fstate,des_updatelayout); + end; + end; + end; +end; + +procedure tcustomitemedit.dopaintforeground(const acanvas: tcanvas); +begin + if fvalue <> nil then begin + doextendimage(acanvas.drawinfopo,flayoutinfofocused.variable.extra); + end; + inherited; + if fvalue <> nil then begin + if fgridintf <> nil then begin + acanvas.rootbrushorigin:= fgridintf.getbrushorigin; + flayoutinfofocused.variable.rowindex:= fgridintf.grid.row; + end; + with tlistitem1(fvalue) do begin + flayoutinfofocused.variable.calcautocellsize:= false; + flayoutinfofocused.variable.widgetstate:= widgetstate; + drawimage(acanvas,flayoutinfofocused); + if feditor.lasttextclipped then begin + include(fstate1,ns1_captionclipped); + end + else begin + exclude(fstate1,ns1_captionclipped); + end; + end; + end; +end; + +procedure tcustomitemedit.itemchanged(const index: integer); +begin + if (fgridintf <> nil) then begin + if (factiverow < 0) or (factiverow >= fitemlist.count) then begin + fvalue:= nil; + end; + fgridintf.getcol.cellchanged(index); + end; + changed; +end; + +function tcustomitemedit.getitemlist: titemeditlist; +begin + result:= titemeditlist(fitemlist); +end; + +procedure tcustomitemedit.setitemlist(const Value: titemeditlist); +begin + fitemlist.Assign(Value); +end; + +procedure tcustomitemedit.dokeydown(var info: keyeventinfoty); +var + widget1: twidget; +begin + doonkeydown(info); + with info do begin + if not(es_processed in eventstate) then begin + if not (es_child in info.eventstate) then begin + if (oe_locate in foptionsedit) and isenterkey(nil,key) and + (shiftstate = []) then begin + if not editing then begin + editing:= not (oe_readonly in foptionsedit) and valuecanedit() and + ((fvalue = nil) or tlistitem1(fvalue).cancaptionedit()); + + ; + if editing then begin + include(eventstate,es_processed); + end; + end + else begin + if not editing then begin + include(eventstate,es_processed); //trigger checkvalue otherwise + end; + editing:= false; + end; + end + else begin + if (key = key_space) and + (shiftstate * shiftstatesrepeatmask = []) and + not (es_processed in eventstate) and + (not editing) and valuecanedit() and + (ns_checkbox in fvalue.state) and + (editor.filtertext = '') then begin + fvalue.checked:= not fvalue.checked; + end; + end; + end + else begin + if (fvisiblevalueeditcount > 0) then begin + widget1:= window.focusedwidget; + if checkdescendent(widget1) then begin + twidget1(widget1).handlenavigkeys(info,true); //nowrap + end; + if window.focusedwidget = widget1 then begin + exclude(info.eventstate,es_processed); + end; + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +function tcustomitemedit.getvaluetext: msestring; +begin + if (fvalue <> nil) then begin + result:= fvalue.getvaluetext; + end + else begin + result:= ''; + end; +end; + +procedure tcustomitemedit.setvaluetext(var avalue: msestring); +begin + if (fvalue <> nil) then begin + fvalue.setvaluetext(avalue); + end; +end; + +function tcustomitemedit.item: tlistedititem; +begin + result:= tlistedititem(fvalue); +end; + +procedure tcustomitemedit.internalcreateframe; +begin + tbuttonsframe.create(iscrollframe(self),ibutton(self)); +end; + +{$ifdef mse_with_ifi} +function tcustomitemedit.getifilink: tifistringlinkcomp; +begin + if fitemifilink then begin + result:= nil; + end + else begin + result:= tifistringlinkcomp(fifilink); + end; +end; + +procedure tcustomitemedit.setifilink(const avalue: tifistringlinkcomp); +begin + fitemifilink:= false; + inherited setifilink(avalue); +end; + +function tcustomitemedit.getifilink1: tifilinkcomp; +begin + if not fitemifilink then begin + result:= nil; + end + else begin + result:= fifilink; + end; +end; + +procedure tcustomitemedit.setifilink1(const avalue: tifilinkcomp); +begin + fitemifilink:= true; + inherited setifilink(avalue); +end; + +procedure tcustomitemedit.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy, common datalist not possible +end; + +{$endif} + +function tcustomitemedit.isnull: boolean; +begin + result:= (item = nil) or (item.caption = ''); +end; + +procedure tcustomitemedit.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + if canevent(tmethod(fonbuttonaction)) then begin + fonbuttonaction(self,action,buttonindex); + end; +end; + +procedure tcustomitemedit.mouseevent(var info: mouseeventinfoty); +begin + if fframe <> nil then begin + tcustombuttonframe(fframe).mouseevent(info); + end; + inherited; +end; + +{ +procedure tcustomitemedit.sortfunc(const l, r; var result: integer); +begin + if oe_casesensitive in foptionsedit then begin + result:= msecomparestr(tlistitem1(l).fcaption,tlistitem1(r).fcaption); + end + else begin + result:= msecomparetext(tlistitem1(l).fcaption,tlistitem1(r).fcaption); + end; +end; +} +function tcustomitemedit.getitems(const index: integer): tlistitem; +begin + result:= tlistitem(fitemlist[index]); +end; + +procedure tcustomitemedit.setitems(const index: integer; const Value: tlistitem); +begin + fitemlist[index]:= value; +end; + +function tcustomitemedit.locatecount: integer; //number of locate values +begin + result:= fitemlist.count; +end; + +function tcustomitemedit.getkeystring(const index: integer): msestring; +begin + result:= fitemlist[index].caption; +end; +{ +function tcustomitemedit.islocating: boolean; +begin + result:= not editing and (oe_locate in foptionsedit) +end; +} +(* +procedure tcustomitemedit.setfiltertext(const value: msestring); +var + int1: integer; + opt1: locatestringoptionsty; +begin + if value = '' then begin + ffiltertext:= ''; + end + else begin + int1:= factiverow; + if oe_casesensitive in foptionsedit then begin + opt1:= [lso_casesensitive]; + end + else begin + opt1:= []; + end; + fitemlist.datapo; //normalize ring + if locatestring(value,{$ifdef FPC}@{$endif}getkeystring,opt1, + fitemlist.count,int1) then begin + with tcustomgrid1(fgridintf.getcol.grid) do begin + focuscell(makegridcoord(ffocusedcell.col,int1)); + end; + ffiltertext:= value; + end; + end; + updatefilterselect; +end; +*) +{ +function tcustomitemedit.getcolorglyph: colorty; +begin + result:= fitemlist.fcolorglyph; +end; +} +procedure tcustomitemedit.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + with info do begin + if ownedcol then begin + if eventkind in mousecellevents then begin + if fvalue <> nil then begin + fvalue.updatecellzone(info.mouseeventinfopo^.pos,info.zone); + end; + end; + if (info.eventkind = cek_enter) then begin + if (widgetcount > 1) and (cellbefore.col >= 0) and + (cellbefore.row >= 0) then begin + fentryedge:= gd_none; + if cellbefore.row < cell.row then begin + fentryedge:= gd_up; + end + else begin + if cellbefore.row > cell.row then begin + fentryedge:= gd_down; + end + else begin + if cellbefore.col < cell.col then begin + fentryedge:= gd_left; + end + else begin + if cellbefore.col > cell.col then begin + fentryedge:= gd_right; + end; + end; + end; + end; + end; + end + else begin + if eventkind = cek_exit then begin + fentryedge:= gd_none; + end; + end; + end; + if (info.eventkind = cek_enter) or + (info.eventkind = cek_exit) then begin + if oe_locate in foptionsedit then begin + editing:= false; + end; + factiverow:= info.newcell.row; + end; + end; + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; + inherited; +end; + +function tcustomitemedit.getediting: boolean; +begin + result:= des_editing in fstate; +end; + +procedure tcustomitemedit.setediting(const avalue: boolean); +begin + if editing <> avalue then begin + if avalue or (oe_locate in foptionsedit) then begin + if avalue then begin + include(fstate,des_editing); + end + else begin + exclude(fstate,des_editing); + end; + setupeditor; + if editing then begin + feditor.selectall; + end + else begin + if foptionsedit * [oe_autoselect,oe_locate] = [oe_autoselect] then begin + feditor.selectall; + end; + end; + end + else begin + exclude(fstate,des_editing); + end; +// cursorchanged; + updatereadonlystate; + end; +end; + +function tcustomitemedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + if oe_readonly in result then begin + editing:= false; + end; + if not editing and not (csdesigning in componentstate) then begin + include(result,oe_readonly); + end; +end; + +procedure tcustomitemedit.beginedit; +begin + editing:= true; +end; + +procedure tcustomitemedit.endedit; +begin + editing:= false; +end; + +function tcustomitemedit.valuecanedit: boolean; +begin + result:= (fvalue <> nil) and tlistitem1(fvalue).canvalueedit(); + if (fvalue <> nil) and canevent(tmethod(foncheckcanedit)) then begin + foncheckcanedit(self,fvalue,result); + end; +end; + +procedure tcustomitemedit.doextendimage(const cellinfopo: pcellinfoty; + var ainfo: extrainfoty); +begin + fillchar(ainfo,sizeof(ainfo),#0); + if canevent(tmethod(fonextendimage)) then begin + fonextendimage(self,cellinfopo,ainfo); + end; +end; + +procedure tcustomitemedit.getautopaintsize(var asize: sizety); +begin + inherited; + if (fvalue <> nil) and (fvalue.owner <> nil) then begin + with flayoutinfofocused.variable do begin + calcautocellsize:= true; + fillchar(extra,sizeof(extra),#0); + end; + fvalue.drawimage(editor.getfontcanvas(),flayoutinfofocused); + end; + with flayoutinfofocused do begin + asize.cx:= asize.cx + imagerect.cx + variable.imageextend.cx + + {imageextra.cx +} + variable.treelevelshift; //??? + if asize.cy < minsize.cy then begin + asize.cy:= minsize.cy; + end; + if asize.cx < minsize.cx then begin + asize.cx:= minsize.cx; + end; + end; +end; + +procedure tcustomitemedit.getautocellsize(const acanvas: tcanvas; + var asize: sizety); +begin + if fvalue <> nil then begin + drawcell(acanvas); //called from twidgetcol.drawfocusedcell() + asize:= cellinfoty(acanvas.drawinfopo^).autocellsize; + end + else begin + inherited; + end; +end; + +function tcustomitemedit.getcellcursor(const arow: integer; + const acellzone: cellzonety; const apos: pointty): cursorshapety; +begin + if acellzone = cz_child then begin + if flastzonewidget <> nil then begin + result:= flastzonewidget.actualcursor(apos); + end + else begin + result:= cr_default; + end; + end + else begin + if (acellzone = cz_caption) and + ((foptionsedit * [oe_locate,oe_readonly] = []) or + (arow < 0) and (editing)) then begin + result:= cursor; + if result = cr_default then begin + result:= cr_ibeam; + end; + end + else begin + if (acellzone = cz_caption) and + (foptionsedit * [oe_locate,oe_readonly] <> []) then begin + result:= cursorreadonly; + if result = cr_default then begin + result:= cr_arrow; + end; + end + else begin + result:= cr_arrow; + // result:= cr_default; + end; + end; + end; +end; + +procedure tcustomitemedit.updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); +var + ar1: recvaluearty; + i1: int32; +begin + inherited; + if fitemlist <> nil then begin + flastzonewidget:= nil; + if (fvalueedits.count > 0) and finddataedits(fitemlist[row],ar1) then begin + for i1:= 0 to high(ar1) do begin + with ar1[i1] do begin + if dummypointer <> nil then begin + with pvalueeditinfoty(dummypointer)^ do begin + if (editwidget <> nil) and + pointinrect(apos,editwidget.widgetrect) then begin + result:= cz_child; + flastzonewidget:= editwidget; + end; + end; + end; + end; + end; + end; + if flastzonewidget = nil then begin + fitemlist[row].updatecellzone(apos,result); + end; + end; +end; + +function tcustomitemedit.getgrid: tcustomgrid; +begin + result:= nil; + if fgridintf <> nil then begin + result:= fgridintf.getcol.grid; + end; +end; + +function tcustomitemedit.selecteditems: listedititemarty; +var + int1: integer; + ar1: integerarty; + po1: ppointeraty; +begin + result:= nil; + if fgridintf <> nil then begin + with fgridintf.getcol do begin + if datalist <> nil then begin + ar1:= selectedcells; + setlength(result,length(ar1)); + po1:= datalist.datapo; + for int1:= 0 to high(result) do begin + result[int1]:= tlistitem(po1^[ar1[int1]]); + end; + end; + end; + end; +end; + +procedure tcustomitemedit.datalistdestroyed; +begin + fitemlist:= nil; +end; + +function tcustomitemedit.textclipped(const arow: integer; + out acellrect: rectty): boolean; +var + cell1: gridcoordty; + grid1: tcustomgrid; +// bo1: boolean; +begin + checkgrid; + with twidgetcol1(fgridintf.getcol) do begin + grid1:= grid; + cell1.row:= arow; + cell1.col:= colindex; + result:= grid1.isdatacell(cell1); + if result then begin + acellrect:= grid1.clippedcellrect(cell1,cil_inner); + if focused and (arow = grid1.row) then begin + result:= feditor.lasttextclipped; //todo: check value edit widget + end + else begin + result:= ns1_captionclipped in tlistitem1(fitemlist[arow]).fstate1; + end; + end + else begin + acellrect:= nullrect; + end; + end; +end; + +function tcustomitemedit.getframe(): tbuttonsframe; +begin + result:= tbuttonsframe(inherited getframe()); +end; + +procedure tcustomitemedit.setframe(const avalue: tbuttonsframe); +begin + inherited setframe(avalue); +end; + +procedure tcustomitemedit.insertwidget(const awidget: twidget; const apos: pointty); +var + intf1: igridwidget; +begin + inherited; + if not (csloading in componentstate) then begin + if awidget.getcorbainterface(typeinfo(igridwidget),intf1) then begin + awidget.visible:= false; + intf1.initgridwidget(); + awidget.anchors:= []; + end; + end; +end; + +procedure tcustomitemedit.setvalueedits(const avalue: tvalueedits); +begin + fvalueedits.assign(avalue); +end; + +procedure tcustomitemedit.valueeditchanged(); +begin +end; + +procedure tcustomitemedit.loaded(); +begin + inherited; + valueeditchanged(); +end; + +procedure tcustomitemedit.setfirstclick(var ainfo: mouseeventinfoty); +begin + if (factiveinfo.editwidget <> nil) and + pointinrect(ainfo.pos,factiveinfo.editwidget.paintparentrect) then begin + factiveinfo.gridintf.setfirstclick(ainfo); + end + else begin + inherited; + end; +end; + +procedure tcustomitemedit.dofocus(); +var + widget1: twidget; +begin + widget1:= getcornerwidget(fentryedge,true); + if widget1 <> nil then begin + widget1.setfocus(); + end + else begin + if factiveinfo.editwidget <> nil then begin + factiveinfo.editwidget.setfocus(); + end + else begin + inherited; + end; + end; +end; + +procedure tcustomitemedit.unregisterchildwidget(const child: twidget); +var + i1: int32; +begin + if not (csdestroying in componentstate) then begin + if child = factiveinfo.editwidget then begin + factiveinfo.gridintf.setparentgridwidget(nil); + fillchar(factiveinfo,sizeof(factiveinfo),0); + end; + for i1:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i1]) do begin + if finfo.editwidget = child then begin + editwidget:= nil; + end; + end; + end; + if child = flastzonewidget then begin + flastzonewidget:= nil; + end; + end; + inherited; +end; + +{ +function tcustomitemedit.actualcursor(const apos: pointty): cursorshapety; +var + zone1: cellzonety; + int1: integer; +begin + if fgridintf <> nil then begin + zone1:= cz_default; + int1:= fgridintf.grid.row; + if int1 >= 0 then begin + updatecellzone(int1,widgetpostoclientpos(apos),zone1); + result:= getcellcursor(int1,zone1); + exit; + end; + end; + result:= inherited actualcursor(apos); +end; +} +{ +procedure tcustomitemedit.dostatwrite(const writer: tstatwriter); +begin + fitemlist.statwrite(writer); +end; + +procedure tcustomitemedit.dostatread(const reader: tstatreader); +begin + fitemlist.statread(reader); +end; +} + +{ titemedit } + +function titemedit.getifiitemlink: tifiitemlinkcomp; +begin + result:= tifiitemlinkcomp(getifilink1()); +end; + +procedure titemedit.setifiitemlink(const avalue: tifiitemlinkcomp); +begin + setifilink1(avalue); +// inherited setifilink(avalue); +end; + +{ tdropdownitemedit } + +constructor tdropdownitemedit.create(aowner: tcomponent); +begin + inherited; + fdropdown:= getdropdowncontrollerclass.create(idropdownlist(self)); + fcontrollerintf:= idataeditcontroller(fdropdown); +end; + +destructor tdropdownitemedit.destroy; +begin + inherited; + fdropdown.free; +end; + +function tdropdownitemedit.getdropdowncontrollerclass(): + dropdownlistcontrollerclassty; +begin + result:= tdropdownlistcontroller; +end; +{ +procedure tdropdownitemedit.internalcreateframe; +begin + fdropdown.createframe; +end; +} +function tdropdownitemedit.getframe: tdropdownmultibuttonframe; +begin + result:= tdropdownmultibuttonframe(pointer(inherited getframe)); +end; + +procedure tdropdownitemedit.setframe(const avalue: tdropdownmultibuttonframe); +begin + inherited setframe(tbuttonsframe(pointer(avalue))); +end; +{ +function tdropdownitemedit.getbutton: tdropdownbutton; +begin + with tdropdownmultibuttonframe(fframe) do begin + result:= tdropdownbutton(buttons[activebutton]); + end; +end; + +procedure tdropdownitemedit.setbutton(const avalue: tdropdownbutton); +begin + with tdropdownmultibuttonframe(fframe) do begin + tdropdownbutton(buttons[activebutton]).assign(avalue); + end; +end; +} +procedure tdropdownitemedit.doafterclosedropdown; +begin + if canevent(tmethod(fonafterclosedropdown)) then begin + fonafterclosedropdown(self); + end; +end; +{ +procedure tdropdownitemedit.editnotification(var info: editnotificationinfoty); +begin + if fdropdown <> nil then begin + fdropdown.editnotification(info); + end; + inherited; +end; +} +procedure tdropdownitemedit.dobeforedropdown; +begin + if canevent(tmethod(fonbeforedropdown)) then begin + fonbeforedropdown(self); + end; +end; +{ +procedure tdropdownitemedit.dokeydown(var info: keyeventinfoty); +begin + fdropdown.dokeydown(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +} +function tdropdownitemedit.getdropdownitems: tdropdowndatacols; +begin + result:= nil; +end; + +procedure tdropdownitemedit.setdropdown(const Value: tcustomdropdownlistcontroller); +begin + fdropdown.assign(Value); +end; + +function tdropdownitemedit.getvalueempty: integer; +begin + result:= -1; +end; + +procedure tdropdownitemedit.doupdatecelllayout; +begin + inherited; + if fframe <> nil then begin + with tframe1(fframe) do begin + inflaterect1(flayoutinfocell.captionrect,fpaintframe); //remove buttons + inflaterect1(flayoutinfocell.captioninnerrect,fpaintframe); //remove buttons + end; + end; +end; + +procedure tdropdownitemedit.imagelistchanged; +begin + //dummy +end; +{ +function tdropdownitemedit.setdropdowntext(const value: msestring; + const docheckvalue: boolean;const canceled: boolean): boolean; +begin + result:= true; + if canceled then begin + feditor.undo; + end + else begin + feditor.text:= value; + if docheckvalue then begin + result:= checkvalue; + end; + end; +end; +} +{ tmbdropdownitemedit } + +function tmbdropdownitemedit.getframe: tdropdownmultibuttonframe; +begin + result:= tdropdownmultibuttonframe(inherited getframe); +end; + +procedure tmbdropdownitemedit.setframe(const Value: tdropdownmultibuttonframe); +begin + inherited setframe(value); +end; + +function tmbdropdownitemedit.getdropdowncontrollerclass: + dropdownlistcontrollerclassty; +begin + result:= tmbdropdownlistcontroller; +end; + +{ ttreeeditnode } + +function ttreeeditnode.converttotreelistitem(flat, withrootnode: boolean; + filterfunc: treenodefilterfuncty): ttreelistedititem; +begin + result:= ttreelistedititem(inherited + converttotreelistitem(flat,withrootnode,filterfunc)); +end; + +function ttreeeditnode.listitemclass: treelistitemclassty; +begin + result:= ttreelistedititem; +end; + +{ ttreelistedititem } + +constructor ttreelistedititem.create(const aowner: tcustomitemlist; + const aparent: ttreelistitem); +begin + factiveindex:= -1; + inherited; +end; + +procedure ttreelistedititem.assign(source: ttreeitemeditlist); +var + int1,int2: integer; + po1: ptreelistitem; +begin + clear; + include(fstate1,ns1_noowner); + if source.count > 0 then begin + po1:= source.datapo; + setlength(fitems,source.count); + int2:= 0; + for int1:= 0 to high(fitems) do begin + if ttreelistitem1(po1^).fparent = nil then begin + fitems[int2]:= po1^; + ttreelistitem1(po1^).fparentindex:= int2; + inc(int2); + end; + inc(po1); + end; + setlength(fitems,int2); + fcount:= int2; + end; +end; + +function ttreelistedititem.add(const aitem: ttreelistedititem): integer; +begin + result:= inherited add(aitem); +end; + +function ttreelistedititem.add( + const itemclass: treelistedititemclassty = nil): ttreelistedititem; +begin + result:= ttreelistedititem(inherited add(itemclass)); +end; + +procedure ttreelistedititem.add(const aitems: treelistedititemarty); +begin + inherited add(treelistitemarty(aitems)); +end; + +procedure ttreelistedititem.add(const acount: integer; + const itemclass: treelistedititemclassty = nil); +begin + inherited add(acount,itemclass); +end; + +procedure ttreelistedititem.add(const captions: array of msestring; + const itemclass: treelistedititemclassty = nil); +var + countbefore: integer; + int1: integer; +begin + countbefore:= count; + inherited add(length(captions),itemclass); + for int1:= countbefore to count-1 do begin + ttreelistedititem(fitems[int1]).caption:= captions[int1-countbefore]; + end; +end; + +function ttreelistedititem.getactiveindex: integer; +begin + if factiveindex < fcount then begin + result:= factiveindex; + end + else begin + result:= -1; + end; +end; + +function ttreelistedititem.endtreerow: integer; +begin + result:= findex; + if expanded then begin + result:= result + treeheight; + end; +end; + +function ttreelistedititem.editwidget: ttreeitemedit; +var + node1: ttreelistedititem; +begin + result:= nil; + node1:= self; + repeat + if node1.fowner <> nil then begin + result:= ttreeitemedit(ttreeitemeditlist(node1.fowner).fowner); + break; + end; + node1:= ttreelistedititem(node1.parent); + until not (node1 is ttreelistedititem); +end; + +procedure ttreelistedititem.activate; +var + wi1: ttreeitemedit; +begin + wi1:= editwidget; + if wi1 <> nil then begin + rootexpanded:= true; + with wi1.widgetcol do begin; + grid.focuscell(mgc(index,self.findex)); + grid.activate; + end; +// wi1.activate; + end; +end; + +{ ttreeitemeditlist } + +constructor ttreeitemeditlist.create; +begin + fcolorline:= cl_treeline; + fcolorlineactive:= cl_treelineactive; + inherited; + fitemclass:= ttreelistedititem; +end; + +constructor ttreeitemeditlist.create(const intf: iitemlist; + const aowner: ttreeitemedit); +begin +// inherited; + inherited create(intf,aowner); +end; +{ +procedure ttreeitemeditlist.setoptionsdraw(const avalue: itemdrawoptionsty); +begin + if foptionsdraw <> avalue then begin + foptionsdraw:= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; +} +procedure ttreeitemeditlist.setcolorline(const value: colorty); +begin + if fcolorline <> value then begin + fcolorline:= value; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +procedure ttreeitemeditlist.setcolorlineactive(const value: colorty); +begin + if fcolorlineactive <> value then begin + fcolorlineactive:= value; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function ttreeitemeditlist.getboxglyph_empty: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_empty]); +end; + +procedure ttreeitemeditlist.setboxglyph_empty(const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_empty]) <> avalue then begin + stockglyphty(fboxids[tib_empty]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function ttreeitemeditlist.getboxglyph_expand: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_expand]); +end; + +procedure ttreeitemeditlist.setboxglyph_expand(const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_expand]) <> avalue then begin + stockglyphty(fboxids[tib_expand]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function ttreeitemeditlist.getboxglyph_expanded: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_expanded]); +end; + +procedure ttreeitemeditlist.setboxglyph_expanded(const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_expanded]) <> avalue then begin + stockglyphty(fboxids[tib_expanded]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; +{ +function ttreeitemeditlist.getboxglyphactive_empty: stockglyphty; +begin + result:= stockglyphty(fboxidsactive[tib_empty]); +end; + +procedure ttreeitemeditlist.setboxglyphactive_empty(const avalue: stockglyphty); +begin + if stockglyphty(fboxidsactive[tib_empty]) <> avalue then begin + stockglyphty(fboxidsactive[tib_empty]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function ttreeitemeditlist.getboxglyphactive_expand: stockglyphty; +begin + result:= stockglyphty(fboxidsactive[tib_expand]); +end; + +procedure ttreeitemeditlist.setboxglyphactive_expand( + const avalue: stockglyphty); +begin + if stockglyphty(fboxidsactive[tib_expand]) <> avalue then begin + stockglyphty(fboxids[tib_expand]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function ttreeitemeditlist.getboxglyphactive_expanded: stockglyphty; +begin + result:= stockglyphty(fboxidsactive[tib_expanded]); +end; + +procedure ttreeitemeditlist.setboxglyphactive_expanded( + const avalue: stockglyphty); +begin + if stockglyphty(fboxidsactive[tib_expanded]) <> avalue then begin + stockglyphty(fboxidsactive[tib_expanded]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; +} +function ttreeitemeditlist.getonstatreaditem: statreadtreeitemeventty; +begin + result:= onstatreadtreeitem; +end; + +procedure ttreeitemeditlist.setonstatreaditem(const avalue: statreadtreeitemeventty); +begin + onstatreadtreeitem:= avalue; +end; + +function ttreeitemeditlist.getonstatwriteitem: statwritetreeitemeventty; +begin + result:= onstatwritetreeitem; +end; + +procedure ttreeitemeditlist.setonstatwriteitem(const avalue: statwritetreeitemeventty); +begin + onstatwritetreeitem:= avalue; +end; + +procedure ttreeitemeditlist.createitem(out item: tlistitem); +begin + item:= treelistedititemclassty(fitemclass).create(self); +end; + +procedure ttreeitemeditlist.docreateobject(var instance: tobject); +begin + if fchangingnode = nil then begin + inherited; + if (finsertparent <> nil) and + (ttreelistitem1(instance).parent = finsertparent) then begin + inc(finsertparentindex); + end; + end + else begin + instance:= fchangingnode[finsertindex]; + with ttreelistitem1(instance) do begin + fowner:= self; + findex:= finsertcount; + inc(finsertcount); + if expanded and (fcount > 0) then begin + fchangingnode:= ttreelistitem(instance); + finsertindex:= 0; + end + else begin + inc(finsertindex); + while (fchangingnode <> nil) and + (finsertindex >= ttreelistitem1(fchangingnode).fcount) do begin + finsertindex:= ttreelistitem1(fchangingnode).fparentindex + 1; + fchangingnode:= ttreelistitem1(fchangingnode).fparent; + end; + end; + end; + end; +end; + +procedure ttreeitemeditlist.change(const index: integer); +begin + if (index < 0) and (nochange = 0) and + ((no_updatechildchecked in foptions) or + (no_updatechildnotchecked in foptions) or + (no_updateparentnotchecked in foptions)) then begin + inherited beginupdate; //no ils_subnodecountupdating + try + if (no_updatechildchecked in foptions) then begin + updatechildcheckedtree(); + end; + if (no_updatechildnotchecked in foptions) then begin + updatechildnotcheckedtree(); + end; + if (no_updateparentnotchecked in foptions) then begin + updateparentnotcheckedtree(); + end; + finally + decupdate; + end; + end; + inherited change(index); +end; + +procedure ttreeitemeditlist.freedata(var data); +var + int1,int2: integer; + po1: ptreelistitem; +begin + if not (ils_freelock in fitemstate) then begin + if pointer(data) <> nil then begin + with ttreelistitem1(data) do begin + int2:= findex+1; + if fowner <> nil then begin + setowner(nil); + end; + if not (ils_subnodecountupdating in self.fitemstate) then begin + int1:= int2; + while int1 < self.fcount do begin + po1:= ptreelistitem(getitempo(int1)); + if (po1^ <> nil) and + (ttreelistitem1(po1^).ftreelevel <= ftreelevel) then begin + break; //next same level node + end; + po1^:= nil; + inc(int1); + end; + self.fitemstate:= self.fitemstate + [ils_subnodecountupdating, + ils_subnodedeleting]; + if (fparent <> nil) and + ((ttreelistitem1(fparent).fowner = self) or + (fparent = frootnode)) then begin + if dls_rowdeleting in self.fstate then begin + inherited; //destroy node + end; + end + else begin + { + if not updating and not(ils_destroying in self.fitemstate) then begin + int1:= int1 - int2; + if int1 > 0 then begin + include(self.fitemstate,ils_freelock); + try + self.fowner.fgridintf.getcol.grid.deleterow(int2,int1); + finally + exclude(self.fitemstate,ils_freelock); + end; + end; + end; + } + if not (ns1_nofreeroot in fstate1) then begin + inherited; //free node + end; + end; + self.fitemstate:= self.fitemstate - [ils_subnodecountupdating, + ils_subnodedeleting]; + end; + end; + end; + end + else begin + if pointer(data) <> nil then begin + ttreelistitem1(data).findex:= -1; + end; + end; +end; + +procedure ttreeitemeditlist.writestate(const writer; const name: msestring); +var + int1,int2: integer; + po1: ^ttreelistitem1; +begin + dostatwrite(tstatwriter(writer),name); + with tstatwriter(writer) do begin + po1:= datapo; + int2:= 0; + for int1:= 0 to fcount - 1 do begin + if po1^.ftreelevel = 0 then begin + inc(int2); + end; + inc(po1); + end; + writeinteger(name,int2); + po1:= datapo; + for int1:= 0 to count - 1 do begin + if po1^.ftreelevel = 0 then begin + beginlist; + po1^.dostatwrite(tstatwriter(writer)); + endlist; + end; + inc(po1); + end; + end; +end; + +procedure ttreeitemeditlist.readstate(const reader; const acount: integer; + const aname: msestring); +type + expandedinfoty = record + item: ttreelistitem; + exp: boolean; + end; + +var + int1: integer; + po1: ^ttreelistitem1; + expanded: array of expandedinfoty; +begin + dostatread(tstatreader(reader),aname); + with tstatreader(reader) do begin + int1:= acount; + if int1 >= 0 then begin + beginupdate; + try + exclude(fitemstate,ils_subnodecountupdating); //free nodes + clear; + include(fitemstate,ils_subnodecountupdating); + count:= int1; + setlength(expanded,count); + po1:= datapo; + for int1:= 0 to count - 1 do begin + beginlist; + po1^.dostatread(tstatreader(reader)); + endlist; + if ns_expanded in po1^.fstate then begin + with expanded[int1] do begin + item:= po1^; + exp:= true; + end; + exclude(po1^.fstate,ns_expanded); + end; + inc(po1); + end; + finally + endupdate; + end; + for int1:= 0 to high(expanded) do begin + with expanded[int1] do begin + if exp then begin + item.expanded:= true; + end; + end; + end; + end; + end; +end; + +procedure ttreeitemeditlist.readnode(const aname: msestring; + const reader: tstatreader; const anode: ttreelistitem); +begin + if reader.beginlist(aname) then begin + anode.expanded:= false; //remove existing bindings + beginupdate; + try + anode.dostatread(reader); + reader.endlist; + finally + endupdate; + end; + end; +end; + +procedure ttreeitemeditlist.writenode(const aname: msestring; + const writer: tstatwriter; const anode: ttreelistitem); +begin + writer.beginlist(aname); + anode.dostatwrite(writer); + writer.endlist; +end; + +procedure ttreeitemeditlist.updatenode(const aname: msestring; + const filer: tstatfiler; const anode: ttreelistitem); +begin + if filer.iswriter then begin + writenode(aname,tstatwriter(filer),anode); + end + else begin + readnode(aname,tstatreader(filer),anode); + end; +end; + +procedure ttreeitemeditlist.assign(const root: ttreelistedititem; + const freeroot: boolean = true); +var + ar1: treelistedititemarty; + int1: integer; +begin +{$warnings off} + with ttreelistitem1(root) do begin +{$warnings on} + if fcount > 0 then begin + setlength(ar1,fcount); + for int1:= fcount-1 downto 0 do begin + ar1[int1]:= ttreelistedititem(remove(int1)); + end; + self.assign(ar1); + end + else begin + self.clear; + end; + end; + if freeroot then begin + root.Free; + end; +end; + +procedure ttreeitemeditlist.assign(const aitems: treelistedititemarty); +var + int1,int2: integer; + ar1: listitemarty; + + procedure doadd(const aitem: ttreelistedititem); + var + int1: integer; + begin + additem(pointerarty(ar1),aitem,int2); + if aitem.expanded then begin + for int1:= 0 to aitem.count-1 do begin + doadd(ttreelistedititem(aitem.fitems[int1])); + end; + end; + end; + +begin + int2:= 0; + setlength(ar1,length(aitems)); //min + int2:= 0; + for int1:= 0 to high(aitems) do begin + doadd(aitems[int1]); + end; + setlength(ar1,int2); + inherited assign(listitemarty(ar1)); +end; + +procedure ttreeitemeditlist.add(const anode: ttreelistedititem; + const freeroot: boolean = true); //adds toplevel node +var + bo1: boolean; +begin + if freeroot then begin + exclude(anode.fstate1,ns1_nofreeroot); + end + else begin + include(anode.fstate1,ns1_nofreeroot); + end; + bo1:= anode.expanded; + anode.expanded:= false; + inherited add(anode); + anode.expanded:= bo1; +end; + +procedure ttreeitemeditlist.insert(const aindex: integer; + const anode: ttreelistedititem; + const freeroot: boolean = true); +var + int1: integer; + rowbefore: integer; + n1,n2: ttreelistitem; +// po1: ptreelistitem; + bo1: boolean; + grid1: tcustomgrid; +begin +// beginupdate(); +// try + if freeroot then begin + exclude(anode.fstate1,ns1_nofreeroot); + end + else begin + include(anode.fstate1,ns1_nofreeroot); + end; + int1:= aindex; + n1:= nil; + if int1 >= count then begin + int1:= count; + if int1 > 0 then begin + n1:= items[int1-1]; + int1:= n1.parentindex+1; + end + else begin + int1:= 0; + end; + end + else begin + if int1 < 0 then begin + int1:= 0; + end; + if int1 < count then begin + n1:= items[int1]; + int1:= n1.parentindex; + end; + end; + n2:= nil; + if n1 <> nil then begin + n2:= n1.parent; + end; + if n2 = nil then begin + n2:= frootnode; + end; + bo1:= anode.expanded; + grid1:= nil; + grid1:= fintf.getgrid(); + rowbefore:= -1; + if grid1 <> nil then begin + rowbefore:= grid1.row; + if rowbefore <= aindex then begin + grid1.row:= invalidaxis; + end; + end; + anode.expanded:= false; + if n2 <> nil then begin + n2.insert(int1,anode); + if n2.owner <> self then begin + inherited insert(aindex,anode); //top level node + end; + if ns_showparentnotchecked in anode.fstate then begin + if n2.checked and not (ns1_parentnotchecked in n2.state1) then begin + exclude(anode.fstate1,ns1_parentnotchecked); + anode.doupdateparentnotcheckedstate(false); + end + else begin + include(anode.fstate1,ns1_parentnotchecked); + anode.doupdateparentnotcheckedstate(true); + end; + end; + if ns_showchildchecked in n2.state then begin + anode.updatechildcheckedstate(); + end; + if ns_showchildnotchecked in n2.state then begin + anode.updatechildnotcheckedstate(); + end; + end + else begin + inherited insert(aindex,anode); //top level node + end; + anode.expanded:= bo1; + if grid1 <> nil then begin + if (rowbefore <= aindex) and (rowbefore >= 0) then begin + grid1.row:= rowbefore+anode.rowheight; + end; + end; +// finally +// endupdate(); +// end; +end; + +procedure ttreeitemeditlist.add(const anodes: treelistedititemarty); +var + int1: integer; +begin + beginupdate; + try + for int1:= 0 to high(anodes) do begin + add(anodes[int1]); + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.addchildren(const anode: ttreelistedititem); + //adds children as toplevel nodes +var + int1: integer; + po1: ptreelistedititematy; + n1: ttreelistedititem; +begin + beginupdate; + try + po1:= pointer(anode.fitems); + for int1:= 0 to anode.count-1 do begin + n1:= ttreelistedititem(po1^[int1]); + n1.settreelevel(0); + add(n1); + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.add(const acount: integer; + aitemclass: treelistedititemclassty = nil); +var + int1: integer; +begin + beginupdate; + if aitemclass = nil then begin + aitemclass:= itemclass; //default + end; + try + for int1:= 0 to acount - 1 do begin + add(aitemclass.create); + end; + finally + endupdate; + end; +end; + +function ttreeitemeditlist.getoncreateitem: createtreelistitemeventty; +begin + result:= createtreelistitemeventty(oncreateobject); +end; + +procedure ttreeitemeditlist.nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); + + procedure expand; + var + int1,int2: integer; + grid1: tcustomgrid; + po1: ptreelistedititematy; + begin + with ttreeitemedit(fowner) do begin + if ttreelistitem1(sender).fcount > 0 then begin + fchangingnode:= ttreelistitem(sender); + int2:= sender.index+1; //list row insert position + finsertcount:= int2; //list row insert position counter + finsertindex:= 0; + int1:= ttreelistitem(sender).treeheight; + try + include(fstate,des_updating); + grid1:= fgridintf.getcol.grid; + incupdate; + try + grid1.insertrow(finsertcount,int1); + finally + decupdate; + exclude(fstate,des_updating); + end; + fintf.updateitemvalues(int2,int1); + int1:= int2+int1; + if int2 < fcount then begin + po1:= datapo; + if ils_subnodedeleting in fitemstate then begin + for int1:= int1 to fcount - 1 do begin + if po1^[int1] <> nil then begin + po1^[int1].findex:= int1; + end; + end; + end + else begin + for int1:= int1 to fcount - 1 do begin + po1^[int1].findex:= int1; + end; + end; + end; + finally + exclude(fstate,des_updating); + fchangingnode:= nil; + end; + end; + end; + end; + +var + curnode: ttreelistedititem; + newrow: integer; + ind1: integer; + po1: ptreelistitem; + + procedure scan(const anode: ttreelistedititem); + var + int1: integer; + begin + po1^:= anode; + anode.findex:= ind1; + if anode = curnode then begin + newrow:= ind1; + end; + inc(po1); + inc(ind1); + if ns_expanded in anode.fstate then begin + for int1:= 0 to anode.count-1 do begin + scan(ttreelistedititem(anode.fitems[int1])); + end; + end; + end; + +var + int1,int2: integer; + bo1: boolean; + po2: ptreelistedititematy; + i1: int32; + g1: tcustomgrid; + +begin + if ainfo.action = na_destroying then begin + int2:= sender.index; + tlistitem1(sender).setowner(nil); + if not deleting {and (ttreelistitem(sender).parent = nil)} then begin + with ttreelistitem(sender) do begin + if expanded then begin + int1:= treeheight+1; + end + else begin + int1:= 1; + end; + end; + incupdate; + include(self.fitemstate,ils_freelock); + with fowner.fgridintf.getcol.grid do begin +// if (row >= int1) and (row < int2+int1) then begin +// fowner.fvalue:= nil; //invalid +// end; + deleterow(int2,int1); + po2:= datapo; + for int1:= int2 to fcount-1 do begin + po2^[int1].findex:= int1; + end; + end; + exclude(self.fitemstate,ils_freelock); + decupdate; + end; + end + else begin + if ainfo.action in [na_expand,na_collapse] then begin +{$warnings off} + with tcustomgrid1(self.fowner.fgridintf.getcol.grid) do begin +{$warnings on} + if not(docheckcellvalue and container.canclose) then begin + ainfo.action:= na_none; + exit; + end; + end; + end; + inherited; + case ainfo.action of + na_valuechange: begin + if not updating and (ttreeitemedit(fowner).fieldedit <> nil) then begin + int1:= sender.index; + ttreeitemedit(fowner).ffieldedit[int1].valuetext:= fowner[int1].valuetext; + end; + end; + na_countchange: begin + if not updating then begin + with ttreelistitem1(sender) do begin + if ns_expanded in fstate then begin + g1:= nil; + if self.fowner <> nil then begin + g1:= self.fowner.grid; + end; + if g1 <> nil then begin + i1:= g1.row; + end; + int1:= findex+1; + if (findex < self.fcount-1) then begin + int2:= ainfo.treeheightbefore; + if ils_subnodedeleting in fitemstate then begin + dec(int2); + end; + if int2 > 0 then begin + include(self.fitemstate,ils_freelock); + {$warnings off} + with tcustomgrid1(self.fowner.fgridintf.getcol.grid) do begin + {$warnings on} + try + bo1:= gs1_autoappendlock in fstate1; + include(fstate1,gs1_autoappendlock); + if (g1 <> nil) and + (g1.row >= int1) and (g1.row > int1 + int2) then begin + g1.row:= invalidaxis; + end; + deleterow(int1,int2); + finally + if not bo1 then begin + exclude(fstate1,gs1_autoappendlock); + end; + exclude(self.fitemstate,ils_freelock); + end; + end; + end; + end; + expand; + if g1 <> nil then begin + g1.row:= i1; + end; + end; + end; + end + else begin + include(fitemstate,ils_subnodecountinvalid); + end; + end; + na_expand: begin + if not (ils_subnodecountupdating in fitemstate) then begin + expand; + with ttreeitemedit(fowner) do begin + if fvalue = sender then begin + expandedchanged(true); + end; + end; + end + else begin + include(fitemstate,ils_subnodecountinvalid); + end; + end; + na_collapse: begin + if not (ils_subnodecountupdating in fitemstate) then begin + with ttreeitemedit(fowner) do begin + include(fitemstate,ils_subnodecountupdating); + fgridintf.getcol.grid.deleterow(sender.index+1, + ttreelistitem(sender).treeheight); + exclude(fitemstate,ils_subnodecountupdating); + if fvalue = sender then begin + expandedchanged(false); + end; + end; + end + else begin + include(fitemstate,ils_subnodecountinvalid); + end; + end; + na_aftersort: begin + if not updating and ttreelistedititem(sender).rootexpanded then begin + curnode:= ttreelistedititem(ttreeitemedit(fowner).item); + newrow:= -1; + po1:= datapo; + ind1:= ttreelistedititem(sender).findex; + int2:= ind1+1; + inc(po1,ind1); + scan(ttreelistedititem(sender)); + fintf.updateitemvalues(int2,ind1-int2); + if newrow >= 0 then begin +{$warnings off} + with tcustomgrid1(fowner.fgridintf.getcol.grid) do begin +{$warnings on} + ffocusedcell.row:= newrow; + layoutchanged; + end; + end; + change(-1); + end; + end; + end; + end; +end; + +function ttreeitemeditlist.toplevelnodes: treelistedititemarty; +var + int1,int2: integer; + po1: ptreelistedititematy; +begin + result:= nil; + int2:= 0; + po1:= datapo; + for int1:= 0 to count - 1 do begin + if po1^[int1].ftreelevel = 0 then begin + additem(pointerarty(result),po1^[int1],int2); + end; + end; + setlength(result,int2); +end; + +function ttreeitemeditlist.getnodes(const must: nodestatesty; + const mustnot: nodestatesty; + const amode: getnodemodety = gno_matching): treelistitemarty; +var + int2: integer; + po1,pe: ptreelistitem; +begin + result:= nil; + int2:= 0; + po1:= datapo; + pe:= po1 + count; + while po1 < pe do begin + if (po1^.parent = nil) or (po1^.parent.owner <> self) then begin + ttreelistitem1(po1^).internalgetnodes(result,int2,must, + mustnot,amode,true); + end; + inc(po1); + end; + setlength(result,int2); +end; + +function ttreeitemeditlist.getselectednodes( + const amode: getnodemodety = gno_matching): treelistitemarty; +begin + result:= getnodes([ns_selected],[],amode); +end; + +function ttreeitemeditlist.getcheckednodes( + const amode: getnodemodety = gno_matching): treelistitemarty; +begin + result:= getnodes([ns_checked],[],amode); +end; + +procedure ttreeitemeditlist.updatechildcheckedtree; +var + po1,pe: ptreelistedititem; +begin + beginupdate; + try + po1:= datapo; + pe:= po1 + count; + while po1 < pe do begin + if po1^ <> nil then begin + with po1^ do begin + if ftreelevel = 0 then begin + updatechildcheckedtree; + end; + end; + end; + inc(po1); + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.updatechildnotcheckedtree; +var + po1,pe: ptreelistedititem; +begin + beginupdate; + try + po1:= datapo; + pe:= po1 + count; + while po1 < pe do begin + if po1^ <> nil then begin + with po1^ do begin + if ftreelevel = 0 then begin + updatechildnotcheckedtree; + end; + end; + end; + inc(po1); + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.updateparentnotcheckedtree; +var + int1: integer; + po1: ptreelistedititematy; +begin + beginupdate; + try + po1:= datapo; + for int1:= 0 to count - 1 do begin + with po1^[int1] do begin + if ftreelevel = 0 then begin + updateparentnotcheckedtree; + end; + end; + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.expandall; +var + int1: integer; + po1: ptreelistedititematy; +begin + beginupdate; + try + po1:= datapo; + for int1:= 0 to count - 1 do begin + with po1^[int1] do begin + if ftreelevel = 0 then begin + expandall; + end; + end; + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.collapseall; +var + int1: integer; + po1: ptreelistedititematy; +begin + beginupdate; + try + po1:= datapo; + for int1:= 0 to count - 1 do begin + with po1^[int1] do begin + if ftreelevel = 0 then begin + collapseall; + end; + end; + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.beginupdate; +begin + if nochange = 0 then begin + include(fitemstate,ils_subnodecountupdating); + end; + inherited; +end; + +procedure ttreeitemeditlist.endupdate; +var + ar1: treelistedititemarty; +begin + ar1:= nil; //compilerwarning + if (nochange = 1) then begin + if (ils_subnodecountinvalid in fitemstate) then begin + exclude(fitemstate,ils_subnodecountinvalid); + ar1:= toplevelnodes; + include(fitemstate,ils_subnodecountupdating); + fowner.fgridintf.getcol.grid.rowcount:= 0; + clear; + exclude(fitemstate,ils_subnodecountupdating); + add(ar1); + end + else begin + exclude(fitemstate,ils_subnodecountupdating); + end; + end; + inherited; +end; + +procedure ttreeitemeditlist.setoncreateitem(const value: createtreelistitemeventty); +begin + oncreateobject:= createobjecteventty(value); +end; + +function ttreeitemeditlist.compare(const l,r): integer; +var + pathl,pathr: treelistitemarty; + int1,int2,int3: integer; +begin + pathl:= ttreelistitem(l).rootpath; + pathr:= ttreelistitem(r).rootpath; + int1:= high(pathl); + if int1 > high(pathr) then begin + int1:= high(pathr); + end; + int3:= -1; + for int2:= 0 to int1 do begin + if pathl[int2] <> pathr[int2] then begin + int3:= int2; + break; + end; + end; + if int3 >= 0 then begin + result:= inherited compare(pathl[int3],pathr[int3]); + end + else begin + result:= length(pathl) - length(pathr); + if fgridsortdescend then begin + result:= -result; + end; + end; +end; +{ +function ttreeitemeditlist.compare(const l,r): integer; +var + pathl,pathr: treelistitemarty; + int1,int2,int3: integer; +begin + pathl:= ttreelistitem(l).rootpath; + pathr:= ttreelistitem(r).rootpath; + int1:= length(pathl); + if int1 > length(pathr) then begin + int1:= length(pathr); + end; + int3:= -1; + for int2:= 0 to int1-1 do begin + if pathl[int2] <> pathr[int2] then begin + int3:= int2; + break; + end; + end; + if int3 >= 0 then begin + result:= inherited compare(pathl[int3],pathr[int3]); + end + else begin + result:= length(pathl) - length(pathr); + end; +end; +} +procedure ttreeitemeditlist.statreaditem(const reader: tstatreader; + var aitem: tlistitem); +begin + statreadtreeitem(reader,nil,ttreelistitem(aitem)); +end; + +procedure ttreeitemeditlist.statwriteitem(const writer: tstatwriter; + const aitem: tlistitem); +begin + statwritetreeitem(writer,ttreelistitem(aitem)); +end; + +function istreeitemdrag(const ainfo: draginfoty): boolean; +begin + result:= (ainfo.dragobjectpo <> nil) and + (ainfo.dragobjectpo^ is ttreeitemdragobject); +end; + +procedure ttreeitemeditlist.beforedragevent(var ainfo: draginfoty; + const arow: integer; var processed: boolean); +var + bo1: boolean; + item1: ttreelistitem; + zone1: cellzonety; +// rect1: rectty; +begin + item1:= ttreelistitem(items[arow]); + case ainfo.eventkind of + dek_begin: begin + zone1:= cz_none; + item1.updatecellzone(fowner.fgridintf.getcol.translatetocell(arow, + ainfo.clientpickpos),zone1); + if zone1 = cz_caption then begin + bo1:= item1.candrag; + if assigned(fondragbegin) then begin + fondragbegin(ttreeitemedit(fowner),item1,bo1, + ttreeitemdragobject(ainfo.dragobjectpo^),processed); + end; + if not processed and bo1 then begin + if ainfo.dragobjectpo^ = nil then begin + ttreeitemdragobject.create(ttreeitemedit(fowner),ainfo.dragobjectpo^, + ainfo.pickpos,item1); + processed:= true; + end; + end; +// if ainfo.dragobjectpo^ <> nil then begin +// ttreeitemdragobject(ainfo.dragobjectpo^).fsourcerow:= arow; +// end; + end; + end; + dek_check: begin + if istreeitemdrag(ainfo) then begin + with ttreeitemdragobject(ainfo.dragobjectpo^) do begin + if item <> item1 then begin + bo1:= item1.candrop(item); + if assigned(fondragover) then begin + fdestrow:= arow; + fondragover(ttreeitemedit(fowner),item,item1, + ttreeitemdragobject(ainfo.dragobjectpo^),bo1,processed); + ainfo.accept:= bo1; + end; + end; + end; + end; + end; + dek_drop: begin + if istreeitemdrag(ainfo) then begin + with ttreeitemdragobject(ainfo.dragobjectpo^) do begin + if (item.owner = self) and assigned(fondragdrop) then begin + fdestrow:= arow; + fondragdrop(ttreeitemedit(fowner),item,item1, + ttreeitemdragobject(ainfo.dragobjectpo^),processed); + end; + end; + end; + end; + end; +end; + +procedure ttreeitemeditlist.afterdragevent(var ainfo: draginfoty; + const arow: integer; var processed: boolean); +begin + //dummy +end; + +procedure ttreeitemeditlist.moverow(const source: integer; const dest: integer); +var + so,de,si: ttreelistitem1; + int1,int2,int3: integer; + po1: ppointeraty; + +begin + if source <> dest then begin + {$warnings off} + so:= ttreelistitem1(items[source]); + de:= ttreelistitem1(items[dest]); + si:= ttreelistitem1(de.findsibling(so)); + {$warnings on} + if si <> nil then begin + int1:= source; + if (source < dest) then begin + if si = so then begin + int3:= si.findex+1; + if si.expanded then begin + int3:= int3 + si.treeheight; + end; + if int3 < fcount then begin + {$warnings off} + si:= ttreelistitem1(items[int3]); //next equal or higher level + {$warnings on} + if si.parent <> so.parent then begin + si:= so; //invalid + end; + end; + end; + end; + if si <> so then begin + if si.fparent <> nil then begin + ttreelistitem1(si.parent).internalmove(so.parentindex,si.parentindex); + end; + int2:= si.findex; + int3:= 1; + if so.expanded then begin + int3:= int3 + so.treeheight; + if source < dest then begin + int2:= int2 - so.treeheight; + end; + end; + if si.expanded and (source < dest) then begin + int2:= int2 + si.treeheight; + end; + fowner.fgridintf.getcol.grid.moverow(int1,int2,int3); + po1:= datapo; + dec(int3); + if int2 < int1 then begin + for int1:= int2 to int1 + int3 do begin + ttreelistedititem(po1^[int1]).findex:= int1; + end; + end + else begin + for int1:= int1 to int2 + int3 do begin + ttreelistedititem(po1^[int1]).findex:= int1; + end; + end; + end; + end; + end; +end; + +function ttreeitemeditlist.getitems1(const index: integer): ttreelistedititem; +begin + result:= ttreelistedititem(inherited getitems1(index)); +end; + +procedure ttreeitemeditlist.setitems(const index: integer; + const avalue: ttreelistedititem); +begin + inherited setitems(index,avalue); +end; + +function ttreeitemeditlist.getitemclass: treelistedititemclassty; +begin + result:= treelistedititemclassty(fitemclass); +end; + +procedure ttreeitemeditlist.setitemclass(const avalue: treelistedititemclassty); +begin + fitemclass:= avalue; + itemclasschanged(); +end; + +function ttreeitemeditlist.getexpandedstate: expandedinfoarty; +var + grid: tcustomgrid; + po1: ptreelistitematy; + int1,int2: integer; +begin + result:= nil; + grid:= fintf.getgrid; + if grid <> nil then begin + setlength(result,count+1); //max + po1:= datapo; + if grid.row >= 0 then begin + result[0].path:= po1^[grid.row].rootcaptions(self); //focused row + end; + int2:= 1; + for int1:= 0 to count-1 do begin + if po1^[int1].expanded then begin + result[int2].path:= po1^[int1].rootcaptions(self); + inc(int2); + end; + end; + setlength(result,int2); + end; +end; + +procedure ttreeitemeditlist.setexpandedstate(const avalue: expandedinfoarty); +var + ar1: treelistedititemarty; + + function find(const acaption: msestring): ttreelistedititem; + var + int1: integer; + begin + result:= nil; + for int1:= 0 to high(ar1) do begin + if ar1[int1].caption = acaption then begin + result:= ar1[int1]; + break; + end; + end; + end; //find + +var + grid: tcustomgrid; + n1: ttreelistedititem; + int1,int2: integer; +begin + grid:= fintf.getgrid; + if grid <> nil then begin + grid.row:= invalidaxis; + if avalue <> nil then begin + ar1:= toplevelnodes; + for int1:= 1 to high(avalue) do begin + n1:= find(avalue[int1].path[0]); + if n1 <> nil then begin + n1.expanded:= true; + for int2:= 1 to high(avalue[int1].path) do begin + n1:= ttreelistedititem(n1.finditembycaption(avalue[int1].path[int2])); + if n1 = nil then begin + break; + end; + n1.expanded:= true; + end; + end; + end; + if (ar1 <> nil) and (avalue[0].path <> nil) then begin + n1:= find(avalue[0].path[0]); //restore focused row + if n1 <> nil then begin + int1:= n1.findex; + for int2:= 1 to high(avalue[0].path) do begin + n1:= ttreelistedititem(n1.finditembycaption(avalue[0].path[int2])); + if n1 = nil then begin + break; + end; + int1:= n1.findex; + end; + grid.row:= int1; + end; + end; + end; + end; +end; + +procedure ttreeitemeditlist.setrootnode(const avalue: ttreelistedititem); +begin + beginupdate(); + try + clear(); + frootnode:= avalue; + if frootnode <> nil then begin + frootnode.ftreelevel:= -1; + addchildren(frootnode); + end; + finally + endupdate(); + end; +end; + +procedure ttreeitemeditlist.deleteitems(index: integer; acount: integer); +var + bo1: boolean; +begin + bo1:= dls_rowdeleting in fstate; + include(fstate,dls_rowdeleting); + try + inherited; + finally + if not bo1 then begin + exclude(fstate,dls_rowdeleting); + end; + end; +end; + +procedure ttreeitemeditlist.insertitems(index: integer; acount: integer); +var + int1: integer; +begin + int1:= index; + if int1 >= count then begin + int1:= count - 1; + end; + if int1 >= 0 then begin + with items[int1] do begin + finsertparent:= ttreelistedititem(parent); + finsertparentindex:= parentindex; + end; + end + else begin + finsertparent:= rootnode; + finsertparentindex:= 0; + end; + try + inherited; + finally + finsertparent:= nil; + finsertparentindex:= -1; + end; +end; + +procedure ttreeitemeditlist.delete(const aindex: integer); +begin + ttreelistedititem(items[aindex]).expanded:= false; + fintf.getgrid.deleterow(aindex); +// deleteitems(aindex,1); +end; + +{ trecordfielditem } + +function trecordfielditem.getvalueitem: tlistitem; +begin + if fvalueitem <> nil then begin + result:= fvalueitem; + end + else begin + result:= self; + end; +end; + +procedure trecordfielditem.setvalueitem(const avalue: tlistitem); +begin + fvalueitem:= avalue; +end; + +{ trecordfielditemeditlist } + +class function trecordfielditemeditlist.defaultitemclass: listedititemclassty; +begin + result:= trecordfielditem; +end; + +{ trecordfieldedit } + +constructor trecordfieldedit.create(aowner: tcomponent); +begin + if fitemlist = nil then begin + fitemlist:= trecordfielditemeditlist.create(iitemlist(self),self); + end; + inherited; +end; + +function trecordfieldedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + if not (csdesigning in componentstate) and (fitemedit <> nil) and + not fitemedit.valuecanedit then begin + include(result,oe_readonly); + end; +end; + +procedure trecordfieldedit.storevalue(var avalue: msestring); +begin + inherited; + if fitemedit <> nil then begin + fitemedit.setvaluetext(avalue); + end; +end; + +{ ttreeitemedit } + +constructor ttreeitemedit.create(aowner: tcomponent); +begin +// fdragcontroller:= ttreeitemdragcontroller.create(self); + if fitemlist = nil then begin + fitemlist:= ttreeitemeditlist.create(iitemlist(self),self); + end; + inherited; +// cursor:= cr_default; +end; + +destructor ttreeitemedit.destroy; +begin +// fdragcontroller.free; + inherited; +end; + +function ttreeitemedit.getdatalistclass: datalistclassty; +begin + result:= ttreeitemeditlist; +end; + +function ttreeitemedit.candragsource(const apos: pointty): boolean; +var + zone1: cellzonety; +begin + result:= item <> nil; + if result then begin + zone1:= cz_none; + item.updatecellzone(apos,zone1); + result:= zone1 = cz_caption; + end; +end; +{ +function ttreeitemedit.getitemclass: listitemclassty; +begin + result:= ttreelistedititem; +end; +} +(* +function ttreeitemedit.getkeystring1(const aindex: integer): msestring; +begin +// if (aindex < fitemlist.count) then begin +// result:= true; + with ttreelistitem1(fitemlist[aindex]) do begin + if treelevel = 0 then begin + result:= caption; + end + else begin + result:= ''; + end; + end; +// end +// else begin +// result:= false; +// end; +end; + +function ttreeitemedit.getkeystring2(const aindex: integer): msestring; +begin + with ttreelistitem1(ttreelistitem1(fvalue).fparent) do begin +// if aindex < fcount then begin + result:= fitems[aindex].caption; +// result:= true; +// end +// else begin +// result:= false; +// end; + end; +end; +*) + +function ttreeitemedit.locatecount: integer; //number of locate values +begin + if (fvalue = nil) or (ttreelistitem1(fvalue).treelevel = 0) then begin + result:= fitemlist.count; + end + else begin + result:= ttreelistitem1(ttreelistitem1(fvalue).fparent).count + end; +end; + +function ttreeitemedit.locatecurrentindex: integer; //index of current row +begin + if (fvalue = nil) or (ttreelistitem1(fvalue).treelevel = 0) then begin + result:= factiverow; + end + else begin + result:= ttreelistitem1(fvalue).fparentindex + end; +end; + +procedure ttreeitemedit.locatesetcurrentindex(const aindex: integer); +begin + if (fvalue = nil) or (ttreelistitem1(fvalue).treelevel = 0) then begin + inherited; + end + else begin + fgridintf.getcol.grid.row:= + ttreelistitem1(ttreelistitem1(ttreelistitem1(fvalue).fparent). + fitems[aindex]).findex; + end; +end; + +function ttreeitemedit.getkeystring(const aindex: integer): msestring; //locate text +begin + if (fvalue = nil) or (ttreelistitem1(fvalue).treelevel = 0) then begin + with ttreelistitem1(fitemlist[aindex]) do begin + if treelevel = 0 then begin + result:= caption; + end + else begin + result:= ''; + end; + end; + end + else begin + with ttreelistitem1(ttreelistitem1(fvalue).fparent) do begin + result:= fitems[aindex].caption; + end; + end; +end; + +(* +procedure ttreeitemedit.setfiltertext(const value: msestring); +var + int1: integer; + opt1: locatestringoptionsty; +// func1: getkeystringfuncty; +begin + if value = '' then begin + ffiltertext:= ''; + end + else begin + if oe_casesensitive in foptionsedit then begin + opt1:= [lso_casesensitive]; + end + else begin + opt1:= []; + end; + if (fvalue = nil) or (ttreelistitem1(fvalue).treelevel = 0) then begin + int1:= factiverow; + if locatestring(value,{$ifdef FPC}@{$endif}getkeystring1,opt1, + fitemlist.count,int1) then begin + with tcustomgrid1(fgridintf.getcol.grid) do begin + focuscell(makegridcoord(ffocusedcell.col,int1)); + end; + ffiltertext:= value; + end; + end + else begin + int1:= ttreelistitem1(fvalue).fparentindex; + if locatestring(value,{$ifdef FPC}@{$endif}getkeystring2,opt1, + ttreelistitem1(ttreelistitem1(fvalue).fparent).count,int1) then begin + with tcustomgrid1(fgridintf.getcol.grid) do begin + focuscell(makegridcoord(ffocusedcell.col, + ttreelistitem1(ttreelistitem1(ttreelistitem1(fvalue).fparent). + fitems[int1]).findex)); + end; + ffiltertext:= value; + end; + end; + end; + if islocating then begin + feditor.selstart:= 0; + feditor.sellength:= length(ffiltertext); + end; +end; +*) + +procedure ttreeitemedit.doupdatelayout(const nocolinvalidate: boolean); +begin + inherited; +// flayoutinfofocused.drawoptions:= ttreeitemeditlist(fitemlist).foptionsdraw; +// flayoutinfofocused.colorline:= ttreeitemeditlist(fitemlist).fcolorline; + flayoutinfofocused.boxids:= ttreeitemeditlist(fitemlist).fboxids; +end; + +{ +procedure ttreeitemedit.itemchanged(const index: integer); +var + state1: nodestatesty; + node1: ttreelistitem; +begin + inherited; + if index >= 0 then begin + node1:= ttreelistitem(fitemlist[index]); + with node1 do begin + state1:= changedstates; + if ns_expanded in state1 then begin + if ns_expanded in state then begin + factnode:= node1; + factindex:= 0; + try + fgridintf.getcol.grid.insertrow(index+1,node1.count); + finally + factnode:= nil; + end; + end + else begin + fgridintf.getcol.grid.deleterow(index+1,node1.count); + end; + end; + end; + end; +end; +} +function ttreeitemedit.getitemlist: ttreeitemeditlist; +begin + result:= ttreeitemeditlist(fitemlist); +end; + +procedure ttreeitemedit.setitemlist(const Value: ttreeitemeditlist); +begin + fitemlist.assign(value); +end; + +function ttreeitemedit.item: ttreelistedititem; +begin + result:= ttreelistedititem(fvalue); +end; + +function ttreeitemedit.getitems(const index: integer): ttreelistedititem; +begin + result:= ttreelistedititem(fitemlist[index]); +end; + +procedure ttreeitemedit.setitems(const index: integer; + const Value: ttreelistedititem); +begin + fitemlist[index]:= value; +end; +{ +procedure ttreeitemedit.sortfunc(const l, r; var result: integer); +var + pathl,pathr: treelistitemarty; + int1,int2,int3: integer; +begin + pathl:= ttreelistitem(l).rootpath; + pathr:= ttreelistitem(r).rootpath; + int1:= length(pathl); + if int1 > length(pathr) then begin + int1:= length(pathr); + end; + int3:= -1; + for int2:= 0 to int1-1 do begin + if pathl[int2] <> pathr[int2] then begin + int3:= int2; + break; + end; + end; + if int3 >= 0 then begin + while true do begin + inherited sortfunc(pathl[int3],pathr[int3],result); + if result = 0 then begin + inc(int3); + if int3 >= length(pathl) then begin + if int3 = length(pathr) then begin + break; + end + else begin + result:= -1; + end; + end + else begin + if int3 = length(pathr) then begin + result:= 1; + break; + end; + end; + end + else begin + break; + end; + end; + end; +end; +} +procedure ttreeitemedit.expandedchanged(const avalue: boolean); +var + int1: integer; +begin + with ttreelistitem1(fvalue) do begin + if avalue and (fcount > 0) then begin + int1:= treeheight+1; + with fgridintf.getcol.grid do begin + if int1 > rowsperpage then begin + showcell(makegridcoord(col,index),cep_top); + end + else begin + int1:= index+int1-1; + if rowvisible(int1) > 0 then begin + showcell(makegridcoord(col,int1),cep_bottom); + end; + end; + focuscell(makegridcoord(col,index+1)); + end; + end; + end; +end; + +procedure ttreeitemedit.setfieldedit(const avalue: trecordfieldedit); +begin + setlinkedvar(avalue,tmsecomponent(ffieldedit)); + if avalue <> nil then begin + avalue.setlinkedvar(self,tmsecomponent(avalue.fitemedit)); + end; +end; + +function ttreeitemedit.getifiitemlink: tifitreeitemlinkcomp; +begin + result:= tifitreeitemlinkcomp(getifilink1()); +end; + +procedure ttreeitemedit.setifiitemlink(const avalue: tifitreeitemlinkcomp); +begin + setifilink1(avalue); +end; + +function ttreeitemedit.checkrowmove(const curindex, + newindex: integer): boolean; +begin + if canevent(tmethod(foncheckrowmove)) then begin + result:= false; + foncheckrowmove(curindex,newindex,result); + end + else begin + result:= true; + end; +end; + +procedure ttreeitemedit.updateitemvalues(const index: integer; + const count: integer); +var + int1: integer; + po1: ptreelistedititem; +begin + if ffieldedit <> nil then begin + po1:= fitemlist.getitempo(index); + for int1:= index to index + count - 1 do begin + with tlistitem1(ffieldedit[int1]) do begin + valuetext:= po1^.valuetext; + setvalueitem(po1^); + end; + inc(po1); + end; + end; + inherited; +end; + +procedure ttreeitemedit.updateitemvalues(); +begin + inherited; +end; + +procedure ttreeitemedit.updateparentvalues(const index: integer); +var + n1: ttreelistitem; +begin + n1:= ttreelistitem(fitemlist.items[index]).parent; + while (n1 <> nil) and (n1.owner = fitemlist) do begin + updateitemvalues(n1.index,1); + n1:= n1.parent; + end; +end; + +procedure ttreeitemedit.dokeydown(var info: keyeventinfoty); +var + int1,int2: integer; + equallevelindex,atreelevel: integer; + cellbefore: gridcoordty; + +begin + doonkeydown(info); + with info do begin + if not (es_child in eventstate) and (fgridintf <> nil) and + not (es_processed in eventstate) and (fvalue <> nil) then begin + with twidgetgrid1(fgridintf.getcol.grid),ttreelistitem1(fvalue) do begin + if shiftstate = [] then begin + atreelevel:= treelevel; + equallevelindex:= -1; + cellbefore:= ffocusedcell; + if (teo_treecolnavig in self.foptions) and + not editing then begin + include(eventstate,es_processed); + case key of + key_right: begin + if expanded then begin + if count > 0 then begin + row:= row + 1; + end; + end + else begin + if (fstate * [ns_subitems,ns_drawemptyexpand] <> []) or + (no_drawemptyexpand in fitemlist.foptions) then begin + expanded:= true; + dec(cellbefore.col);//no processed reset + end; + end; + end; + key_left: begin + if ns_expanded in state then begin + expanded:= false; + dec(cellbefore.col);//no processed reset + end + else begin + if (fparent <> nil) and (fparent.owner = fitemlist) then begin + row:= fparent.index; + end; +// int1:= fitemlist.indexof(parent); +// if int1 >= 0 then begin +// row:= int1; +// end; + end; + end; + end; + end; + if teo_treerownavig in self.foptions then begin + include(eventstate,es_processed); + case key of + key_up: begin + for int1:= ffocusedcell.row - 1 downto 0 do begin + int2:= ttreelistitem(fitemlist[int1]).treelevel; + if int2 <= atreelevel then begin + equallevelindex:= int1; + break; + end; + end; + if equallevelindex >= 0 then begin + row:= equallevelindex; + end; + end; + key_down: begin + for int1:= ffocusedcell.row + 1 to frowcount - 1 do begin + int2:= ttreelistitem(fitemlist[int1]).treelevel; + if int2 = atreelevel then begin + equallevelindex:= int1; + break; + end; + if int2 < atreelevel then begin + break; + end; + end; + if equallevelindex >= 0 then begin + row:= equallevelindex; + end; + end; + end; + end; + if (ffocusedcell.row = cellbefore.row) and + (ffocusedcell.col = cellbefore.col) then begin + exclude(eventstate,es_processed); + end; + end + else begin + if (teo_keyrowmoving in foptions) and (shiftstate = [ss_ctrl]) and + ((key = key_up) or (key = key_down)) then begin + include(eventstate,es_processed); + if ((count = 0) or not expanded) then begin + if ftreelevel > 0 then begin + int1:= parentindex; + if key = key_up then begin + if (int1 > 0) and (itemlist[row].parent = itemlist[row-1].parent) and + checkrowmove(row,row-1) then begin + ttreelistitem1(fparent).internalswap(int1,int1-1); + moverow(row,row-1,1); + end; + end + else begin //key_down + if (int1 < fparent.count-1) and + (itemlist[row].parent = itemlist[row+1].parent) and + checkrowmove(row,row+1) then begin + ttreelistitem1(fparent).internalswap(int1,int1+1); + moverow(row,row+1,1); + end; + end; + end + else begin + if key = key_up then begin + if (row > 0) then begin + if ttreelistitem(itemlist[row-1]).issinglerootrow and + checkrowmove(row,row-1) then begin + moverow(row,row-1,1); + end; + end; + end + else begin //key_down + if (row < rowhigh) then begin + if ttreelistitem(itemlist[row+1]).issinglerootrow and + checkrowmove(row,row+1) then begin + moverow(row,row+1,1); + end; + end; + end; + end; + end; + showcell(focusedcell); + end; + end; + end + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +procedure ttreeitemedit.dragdrop(const adragobject: ttreeitemdragobject); +var + bo1: boolean; + de,pa: ttreelistitem; + sourcer: integer; + destr: integer; +begin + if fgridintf <> nil then begin + with adragobject do begin + de:= items[destrow]; + pa:= de.parent; + if pa <> nil then begin + fitemlist.beginupdate; + bo1:= (item.owner = fitemlist) and + not (ils_subnodecountinvalid in fitemlist.fitemstate); + sourcer:= item.index; + pa.insert(de.parentindex,item); + if bo1 then begin + destr:= destrow; + if destr > sourcer then begin + destr:= destr + de.rowheight - 1; + end; + fgridintf.getcol.grid.moverow(sourcer,destr,item.rowheight); + exclude(fitemlist.fitemstate,ils_subnodecountinvalid); + end; + fitemlist.endupdate; + end; + end; + end; +end; + +procedure ttreeitemedit.doitembuttonpress(var info: mouseeventinfoty); +var + cellzone: cellzonety; +begin + if (info.button = mb_left) and (info.shiftstate*keyshiftstatesmask = []) and + ([teo_enteronimageclick,teo_enterondoubleclick]*foptions <> []) then begin + cellzone:= cz_none; + with ttreelistedititem(fvalue) do begin + updatecellzone(info.pos,cellzone); + if (cellzone = cz_image) and (teo_enteronimageclick in foptions) or + (teo_enterondoubleclick in foptions) and + (ss_double in info.shiftstate) then begin + expanded:= not expanded; + include(info.eventstate,es_processed); + end; + end; + end; +end; + +procedure ttreeitemedit.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + inherited; + if fvalue <> nil then begin + with info,ttreelistedititem(fvalue) do begin + if (eventkind = cek_enter) and (fparent <> nil) then begin + ttreelistedititem(fparent).factiveindex:= fparentindex; + end; + end; + end; +end; +{ +procedure ttreeitemedit.setdrag(const avalue: ttreeitemdragcontroller); +begin + fdragcontroller.assign(avalue); +end; +} +(* +procedure ttreeitemedit.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + { + if not (es_processed in info.eventstate) then begin + fdragcontroller.clientmouseevent(info); + end; + } +end; +*) +{ +procedure ttreeitemedit.dragevent(var info: draginfoty); +begin + if not fdragcontroller.beforedragevent(info) then begin + inherited; + end; + fdragcontroller.afterdragevent(info); +end; +} +procedure ttreeitemedit.beforecelldragevent(var ainfo: draginfoty; + const arow: integer; var processed: boolean); +begin + ttreeitemeditlist(fitemlist).beforedragevent(ainfo,arow,processed); +end; + +procedure ttreeitemedit.aftercelldragevent(var ainfo: draginfoty; + const arow: integer; var processed: boolean); +begin + ttreeitemeditlist(fitemlist).afterdragevent(ainfo,arow,processed); +end; + +function ttreeitemedit.selecteditems: treelistedititemarty; +begin + result:= treelistedititemarty(inherited selecteditems); +end; + +procedure ttreeitemedit.comparerow(const lindex: integer; + const rindex: integer; var aresult: integer); +var + pol,por: ptreelistitem; + col1: tdatacol; +begin + if fitemlist <> nil then begin + col1:= fgridintf.getcol; + pol:= fitemlist.datapo; + por:= @ppointeraty(pol)[rindex]; + pol:= @ppointeraty(pol)[lindex]; + if (col1.grid.datacols.sortcol = col1.index) or + (pol^.count = 0) and (por^.count = 0) and + (pol^.parent = por^.parent) then begin + aresult:= col1.grid.datacols.sortfunc(lindex,rindex); + end; + end; +end; +{ +procedure ttreeitemedit.updateitemvalues; +begin + inherited; +end; +} +{ +procedure ttreeitemedit.drawcell(const canvas: tcanvas); +begin + with cellinfoty(canvas.drawinfopo^) do begin + flayoutinfocell.islast:= (cell.row >= grid.rowhigh) or + (fitemlist <> nil) and + (ptreelistitem(datapo)^.treelevel = 0) or + (ptreelistitem(datapo)^.treelevel > + (ptreelistitem(datapo)+1)^.treelevel); + end; + flayoutinfofocused.islast:= flayoutinfocell.islast; + inherited; +end; +} +(* +{ ttreeitemdragcontroller } + +constructor ttreeitemdragcontroller.create(const aowner: ttreeitemedit); +begin + fowner:= aowner; + inherited create(idragcontroller(aowner)); +end; + +function ttreeitemdragcontroller.beforedragevent(var info: draginfoty): boolean; +var + bo1: boolean; + item1: ttreelistitem; +begin + result:= false; + item1:= fowner.item; + case info.eventkind of + dek_begin: begin + bo1:= item1.candrag; + if assigned(fondragbegin) then begin + fondragbegin(fowner,item1,bo1,ttreeitemdragobject(info.dragobjectpo^),result); + end; + if not result and bo1 and (info.dragobjectpo^ = nil) then begin + ttreeitemdragobject.create(fowner,info.dragobjectpo^,info.pickpos,item1); + result:= true; + end; + end; + end; +end; + +function ttreeitemdragcontroller.afterdragevent(var info: draginfoty): boolean; +begin + result:= false; +end; +*) +{ ttreeitemdragobject } + +constructor ttreeitemdragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aitem: ttreelistitem); +begin + fitem:= aitem; +// fsourcerow:= invalidaxis; + fdestrow:= invalidaxis; + inherited create(asender,instance,apickpos); +end; + +{ tdirtreenode } + +procedure tdirtreenode.loaddirtree(const apath: filenamety); + + procedure doload(const anode: tdirtreenode; const apath: filenamety); + var + ar1: filenamearty; + int1: integer; + begin + ar1:= searchfiles('*',apath,[fa_dir]); + if ar1 <> nil then begin + checkfiles(ar1); + end; + with anode do begin + add(length(ar1)); + for int1:= 0 to high(ar1) do begin + fitems[int1].caption:= filename(ar1[int1]); + doload(tdirtreenode(fitems[int1]),ar1[int1]); + end; + end; + end; + +begin + beginupdate; + clear; + try + doload(self,apath); + finally + endupdate; + end; +end; + +procedure tdirtreenode.checkfiles(var afiles: filenamearty); +begin + //dummy +end; + +function tdirtreenode.path(const astart: integer = 0): filenamety; +var + ar1: treelistitemarty; + int1: integer; +begin + result:= ''; + ar1:= rootpath; + if high(ar1) >= astart then begin + result:= ar1[astart].caption; + for int1:= astart+1 to high(ar1) do begin + result:= result+'/'+ar1[int1].caption; + end; + if (result <> '') and (result <> '/') then begin + result:= result + '/'; + end; + end; +end; + +function createtitemeditlist(const aowner: twidgetcol): tdatalist; +begin + result:= titemeditlist.create; +end; + +function createtrecordfielditemeditlist(const aowner: twidgetcol): tdatalist; +begin + result:= trecordfielditemeditlist.create; +end; + +function createttreeitemeditlist(const aowner: twidgetcol): tdatalist; +begin + result:= ttreeitemeditlist.create; +end; + +{ trichlistedititem } + +function trichlistedititem.getrichcaption: richstringty; +begin + result.text:= fcaption; + result.format:= fformat; +end; + +procedure trichlistedititem.setrichcaption(const avalue: richstringty); +begin + fformat:= avalue.format; + caption:= avalue.text; +end; + +procedure trichlistedititem.updatecaption(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty; var ainfo: drawtextinfoty); +begin + inherited; + ainfo.text.format:= fformat; +end; + +procedure trichlistedititem.setcaptionformat(const avalue: formatinfoarty); +begin + fformat:= avalue; + change; +end; + +{ titemclientcontroller } + +function titemclientcontroller.getitemlist(): titemeditlist; +begin + result:= nil; + if fitemedit <> nil then begin + result:= tcustomitemedit(fitemedit).itemlist; + end; +end; + +function titemclientcontroller.getitemedit: titemedit; +begin + pointer(result):= fitemedit; +end; + +function titemclientcontroller.createdatalist: tdatalist; +begin + result:= nil; +end; + +function titemclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= []; +end; + +function titemclientcontroller.getlistitem(): tlistedititem; +begin + result:= nil; + if fitemedit <> nil then begin + result:= tcustomitemedit(fitemedit).item; + end; +end; + +procedure titemclientcontroller.linkset(const alink: iificlient); +var + obj1: tobject; +begin + inherited; + obj1:= alink.getinstance; + if obj1 is tcustomitemedit then begin + setlinkedvar(tcustomitemedit(obj1),tmsecomponent(fitemedit)); + end; +end; + +{ ttreeitemclientcontroller } + +function ttreeitemclientcontroller.getlistitem(): ttreelistedititem; +begin + pointer(result):= inherited getlistitem(); +end; + +function ttreeitemclientcontroller.getitemlist(): ttreeitemeditlist; +begin + pointer(result):= inherited getitemlist(); +end; + +function ttreeitemclientcontroller.getitemedit(): ttreeitemedit; +begin + pointer(result):= fitemedit; +end; + +{ tifiitemlinkcomp } + +function tifiitemlinkcomp.getcontroller: titemclientcontroller; +begin + result:= titemclientcontroller(inherited controller); +end; + +procedure tifiitemlinkcomp.setcontroller(const avalue: titemclientcontroller); +begin + inherited setcontroller(avalue); +end; + +function tifiitemlinkcomp.getcontrollerclass: customificlientcontrollerclassty; +begin + result:= titemclientcontroller; +end; + +{ tifitreeitemlinkcomp } + +function tifitreeitemlinkcomp.getcontroller: ttreeitemclientcontroller; +begin + result:= ttreeitemclientcontroller(inherited controller); +end; + +procedure tifitreeitemlinkcomp.setcontroller( + const avalue: ttreeitemclientcontroller); +begin + inherited setcontroller(avalue); +end; + +function tifitreeitemlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= ttreeitemclientcontroller; +end; + +initialization + registergriddatalistclass(titemeditlist.classname, + @createtitemeditlist); + registergriddatalistclass(trecordfielditemeditlist.classname, + @createtrecordfielditemeditlist); + registergriddatalistclass(ttreeitemeditlist.classname, + @createttreeitemeditlist); +end. diff --git a/mseide-msegui/lib/common/editwidgets/mserealsumedit.pas b/mseide-msegui/lib/common/editwidgets/mserealsumedit.pas new file mode 100644 index 0000000..9ca9284 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/mserealsumedit.pas @@ -0,0 +1,219 @@ +unit mserealsumedit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msesumlist,msedataedits,msewidgetgrid,msedatalist,msestrings,mseeditglob, + msegrids,msegui,msemenus,msetypes,mseevent,mseguiglob,mseedit,msegraphics; + +type + + tgridrealsumlist = class(trealsumlist) + private + fowner: twidgetcol; + protected + procedure setoptions(const avalue: optionssumty); override; + function getdefault: pointer; override; + procedure setsourcevalue(const avalue: string); override; + procedure setsourcelevel(const avalue: string); override; + procedure setsourceissum(const avalue: string); override; + public + constructor create(owner: twidgetcol); reintroduce; + procedure linksource(const source: tdatalist; const atag: integer); override; + published + property sourcevalue; + property sourcelevel; + property sourceissum; + end; + + trealsumedit = class(trealedit) + private + function getsumlevel(index: integer): integer; + procedure setsumlevel(index: integer; const avalue: integer); + protected + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; +// function internaldatatotext(const data): msestring; override; +// procedure valuetogrid(const arow: integer); override; + function getoptionsedit: optionseditty; override; + function internaldatatotext(const data): msestring; override; + public + function griddata: tgridrealsumlist; + property gridsumlevel[index: integer]: integer read getsumlevel + write setsumlevel; + end; + +implementation + +{ tgridrealsumlist } + +constructor tgridrealsumlist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + fstate:= fstate + [dls_nostreaming,dls_propertystreaming]; +end; + +function tgridrealsumlist.getdefault: pointer; +begin + result:= inherited getdefault; +end; + +procedure tgridrealsumlist.setsourcevalue(const avalue: string); +begin + inherited; + fowner.sourcenamechanged(0); +end; + +procedure tgridrealsumlist.setsourcelevel(const avalue: string); +begin + inherited; + fowner.sourcenamechanged(sumleveltag); +end; + +procedure tgridrealsumlist.setsourceissum(const avalue: string); +begin + inherited; + fowner.sourcenamechanged(2); +end; + +procedure tgridrealsumlist.setoptions(const avalue: optionssumty); +var + optionsbefore: optionssumty; +begin + if foptions <> avalue then begin + optionsbefore:= foptions; + inherited; + if osu_foldsum in + optionssumty({$ifdef FPC}longword{$else}byte{$endif}(avalue) xor + {$ifdef FPC}longword{$else}byte{$endif}(optionsbefore)) then begin + fowner.sourcenamechanged(sumleveltag); + end; + change(-1); + end; +end; + +procedure tgridrealsumlist.linksource(const source: tdatalist; + const atag: integer); +begin + if {(source = nil) and} (atag = sumleveltag) and + (osu_foldsum in options) then begin + inherited linksource(fowner.grid.datacols.rowstate,atag); + end + else begin + inherited; + end; +end; + +{ trealsumedit } + +function trealsumedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridrealsumlist.create(sender); +end; + +function trealsumedit.getdatalistclass: datalistclassty; +begin + result:= tgridrealsumlist; +end; + +function trealsumedit.griddata: tgridrealsumlist; +begin + checkgrid(); + result:= tgridrealsumlist(fdatalist); +end; + +function trealsumedit.getoptionsedit: optionseditty; +var + po1: prealsumty; +// datacol1: tdatacol; +// data1: tgridrealsumlist; +// int1: integer; +begin + result:= inherited getoptionsedit; + if fgridintf <> nil then begin + po1:= fgridintf.getrowdatapo; + if (po1 <> nil) then begin + if osu_foldsum in trealsumlist(fdatalist).options then begin + if (po1^.issum) then begin + include(result,oe_readonly); + end; + end + else begin + if (po1^.data.int <> 0) then begin + include(result,oe_readonly); + end; + end; + end; + end; +end; + +function trealsumedit.internaldatatotext(const data): msestring; +var + po1: prealsumty; +begin + if (fdatalist <> nil) and ([osu_sumsonly,osu_valuesonly] * + tgridrealsumlist(fdatalist).options <> []) then begin + po1:= @data; + if (po1 = nil) then begin + po1:= fgridintf.getrowdatapo; + end; + if (po1 <> nil) and ((po1^.data.int = 0) xor + (osu_valuesonly in tgridrealsumlist(fdatalist).options)) then begin + result:= ''; + exit; + end; + end; + result:= inherited internaldatatotext(data); +end; + +function trealsumedit.getsumlevel(index: integer): integer; +var + list: tdatalist; +begin + list:= checkgriddata(index); + if list <> nil then begin + result:= tgridrealsumlist(list).sumlevel[index]; + end + else begin + result:= 0; + end; +end; + +procedure trealsumedit.setsumlevel(index: integer; const avalue: integer); +var + list: tdatalist; +begin + list:= checkgriddata(index); + if list <> nil then begin + tgridrealsumlist(list).sumlevel[index]:= avalue; + fgridintf.datachange(index); + end; +end; + +{ +procedure trealsumedit.valuetogrid(const arow: integer); +begin + griddata.setgriddata(arow,fvalue); +end; +} +{ +function trealsumedit.internaldatatotext(const data): msestring; +begin + if (@data = nil) or (realsumty(data).level = 0) then begin + result:= inherited internaldatatotext(data); + end + else begin + result:= inherited internaldatatotext(realsumty(data).sum); + end; +end; +} +function createtgridrealsumlist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridrealsumlist.create(aowner); +end; + +initialization + registergriddatalistclass(tgridrealsumlist.classname, + {$ifdef FPC}@{$endif}createtgridrealsumlist); + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msestringlistedit.pas b/mseide-msegui/lib/common/editwidgets/msestringlistedit.pas new file mode 100644 index 0000000..2abc6e4 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msestringlistedit.pas @@ -0,0 +1,433 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestringlistedit; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + Classes,msegrids,mseinplaceedit,mseeditglob,mseevent,msegraphics,msegraphutils, + msedatalist,mserichstring,msestring,mseguiglob,msetypes; + +type + editposty = record + col,row: integer; + end; + +const + defaultstringlistcoloptions = []; + invalideditpos: editposty = (col: -1; row: -1); + +type + + tstringlistcol = class(tstringcol,iedit) + private + feditor: tinplaceedit; + feditpos: editposty; + feditcol: integer; + fstartanchor: editposty; + fendanchor: editposty; + fsel1,fsel2: editposty; + function getdata: trichstringdatalist; + procedure selectstart(const pos: editposty); + procedure selectend(const pos: editposty); + procedure clearselection; + procedure extendselection; + procedure updateselection; + protected + function getoptionsedit: optionseditty; //iedit + procedure editnotification(var info: editnotificationinfoty); virtual; + + procedure scrolled(const dist: pointty); override; + procedure fontchanged(const sender: tobject); override; + procedure dofocusedcellchanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const action: focuscellactionty); override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure clientmouseevent(const acell: gridcoordty; var info: mouseeventinfoty); override; + procedure dokeyevent(var info: keyeventinfoty; up: boolean); override; + function createdatalist: tdatalist; override; + procedure drawcell(const canvas: tcanvas); override; + procedure drawfocusedcell(const canvas: tcanvas); override; + procedure itemchanged(sender: tdatalist; index: integer); override; + + public + constructor create(agrid: tcustomgrid; aowner: tgridarrayprop); override; + destructor destroy; override; + function getselection(out start,stop: editposty): boolean; + property data: trichstringdatalist read getdata; + published + property font; + end; + + tstringlistedit = class(tcustomgrid) + private + fstringlistcolindex: integer; + function gettext: trichstringdatalist; + procedure settext(const Value: trichstringdatalist); + function gettextwidth: integer; + procedure settextwidth(const Value: integer); + protected + procedure createdatacol(const index: integer; out item: tdatacol); override; + public + constructor create(aowner: tcomponent); override; + property text: trichstringdatalist read gettext write settext; + published + property textwidth: integer read gettextwidth write settextwidth default 0; + property font; + property rowcount; + end; + +function makeeditpos(col,row: integer): editposty; + +implementation +uses + SysUtils,msegui; + +type + twidget1 = class(twidget); + +function makeeditpos(col,row: integer): editposty; +begin + result.col:= col; + result.row:= row; +end; + +{ tstringlistcol } + +constructor tstringlistcol.create(agrid: tcustomgrid; + aowner: tgridarrayprop); +begin + inherited; + foptions:= defaultstringlistcoloptions; + feditor:= tinplaceedit.create(fgrid,iedit(self)); + fstartanchor:= invalideditpos; + fendanchor:= invalideditpos; + fsel1:= invalideditpos; + fsel2:= invalideditpos; +end; + +destructor tstringlistcol.destroy; +begin + feditor.Free; + ffont.free; + inherited; +end; + +procedure tstringlistcol.fontchanged(const sender: tobject); +begin + inherited; + if (sender = self) or (ffont = nil) then begin + changed; + end; +end; + +procedure tstringlistcol.dofocusedcellchanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const action: focuscellactionty); +var + rect1: rectty; +begin + if enter then begin + rect1:= fgrid.cellrect(newcell); + feditor.setup(items[newcell.row],0,false,inflaterect(rect1,-1), + rect1,data.formats[newcell.row],nil,font); + feditpos.row:= newcell.row; + if action = fca_selectend then begin + extendselection; + end; + // feditor.curindex:= feditcol; + feditor.moveindex(feditcol,action = fca_selectend); + feditor.dofocus; + end + else begin + items[cellbefore.row]:= feditor.text; + if action = fca_selectend then begin + if fstartanchor.row < 0 then begin + fstartanchor:= feditpos; + end; + end + else begin + clearselection; + end; + feditor.dodefocus; + end; + inherited; +end; + +procedure tstringlistcol.clientmouseevent(const acell: gridcoordty; + var info: mouseeventinfoty); +begin + feditor.mouseevent(info); + inherited; +end; + +procedure tstringlistcol.dokeyevent(var info: keyeventinfoty; up: boolean); +begin + if not up then begin + feditor.dokeydown(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +procedure tstringlistcol.dokeyup(var info: keyeventinfoty); +begin + feditor.dokeyup(info); + if not info.processed then begin + inherited; + end; +end; +} +procedure tstringlistcol.editnotification(var info: editnotificationinfoty); +begin + case info.action of + ea_indexmoved: begin + feditpos.col:= feditor.curindex; + feditcol:= feditpos.col; + if not(eas_shift in info.state) then begin + selectstart(feditpos); + end + else begin + selectend(feditpos); + end; + end; + ea_clearselection: clearselection; + ea_textedited: begin + include(fstate,cos_noinvalidate); + data.richitems[feditpos.row]:= feditor.richtext; + exclude(fstate,cos_noinvalidate); + end; + end; +end; + +function tstringlistcol.getoptionsedit: optionseditty; +begin + result:= []; //[oe_noautoselect,oe_noresetselectonexit]; +end; + +procedure tstringlistcol.drawcell(const canvas: tcanvas); +begin + ftextinfo.text.format:= data.formats[cellinfoty(canvas.drawinfopo^).cell.row]; + inherited; +end; + +procedure tstringlistcol.drawfocusedcell(const canvas: tcanvas); +var + po1: pointty; +begin + drawcellbackground(canvas); + po1:= fgrid.cellrect(cellinfoty(canvas.drawinfopo^).cell).pos; + canvas.remove(po1); + feditor.dopaint(canvas); + canvas.move(po1); +end; + +procedure tstringlistcol.scrolled(const dist: pointty); +begin + inherited; + feditor.scroll(dist); + if fgrid.active then begin + application.caret.move(dist); + end; +end; + +function tstringlistcol.createdatalist: tdatalist; +begin + result:= trichstringdatalist.create; +end; + +function tstringlistcol.getdata: trichstringdatalist; +begin + result:= trichstringdatalist(fdata); +end; + +procedure tstringlistcol.selectstart(const pos: editposty); +begin + clearselection; + fstartanchor:= pos; + fendanchor:= invalideditpos; +end; + +procedure tstringlistcol.selectend(const pos: editposty); +begin + fendanchor:= pos; + updateselection; +end; + +procedure tstringlistcol.extendselection; +begin + fendanchor:= feditpos; + updateselection; +end; + +procedure tstringlistcol.clearselection; +var + int1: integer; + po1,po2: editposty; +begin + if getselection(po1,po2) then begin + for int1:= po1.row to po2.row do begin + updatefontstyle(data.getformatpo(int1)^,0,bigint,fs_selected,false); + cellchanged(int1); + end; + end; + fstartanchor:= feditpos; + fendanchor:= invalideditpos; + fsel1:= invalideditpos; + fsel2:= invalideditpos; +end; + +procedure tstringlistcol.updateselection; + + procedure setselected1(const po1,po2: editposty; select: boolean); + var + int1: integer; + begin + int1:= po2.col - po1.col; + if po2.row > po1.row then begin + int1:= bigint; + end; + updatefontstyle(data.getformatpo(po1.row)^,po1.col,int1,fs_selected,select); + cellchanged(po1.row); + for int1:= po1.row + 1 to po2.row-1 do begin + updatefontstyle(data.getformatpo(int1)^,0,bigint,fs_selected,select); + cellchanged(int1); + end; + if po2.row > po1.row then begin + updatefontstyle(data.getformatpo(po2.row)^,0,po2.col,fs_selected,select); + cellchanged(po2.row); + end; + end; + +var + po1,po2: editposty; +begin + if getselection(po1,po2) then begin + if fsel1.row >= 0 then begin + setselected1(fsel1,po1,false); + setselected1(po2,fsel2,false); + setselected1(po1,fsel1,true); + setselected1(fsel2,po2,true); + end + else begin + setselected1(po1,po2,true); + end; + if feditpos.row >= po1.row then begin + if feditpos.row = po1.row then begin + feditor.selstart:= po1.col; + if feditpos.row = po2.row then begin + feditor.sellength:= po2.col - po1.col; + end + else begin + feditor.sellength:= length(feditor.text); + end; + end + else begin + feditor.selstart:= 0; + if feditpos.row = po2.row then begin + feditor.sellength:= po2.col; + end + else begin + feditor.sellength:= length(feditor.text); + end; + end; + end; + fsel1:= po1; + fsel2:= po2; + end; +end; + +function tstringlistcol.getselection(out start, stop: editposty): boolean; +begin + if (fstartanchor.row >= 0) and (fendanchor.row >= 0) then begin + result:= true; + if fendanchor.row < fstartanchor.row then begin + start:= fendanchor; + stop:= fstartanchor; + end + else begin + stop:= fendanchor; + start:= fstartanchor; + if fendanchor.row = fstartanchor.row then begin + if fendanchor.col < fstartanchor.col then begin + start.col:= fendanchor.col; + stop.col:= fstartanchor.col; + end; + end; + end; + end + else begin + result:= false; + end; +end; + +procedure tstringlistcol.doactivate; +begin + feditor.doactivate; + inherited; +end; + +procedure tstringlistcol.dodeactivate; +begin + feditor.dodeactivate; + inherited; +end; + +procedure tstringlistcol.itemchanged(sender: tdatalist; index: integer); +begin + if not (cos_noinvalidate in fstate) and (feditpos.row >= 0) and + ((index < 0) or (index = feditpos.row)) then begin + feditor.richtext:= data.richitems[feditpos.row]; + end; + inherited; +end; + +{ tstringlistedit } + +constructor tstringlistedit.create(aowner: tcomponent); +begin + inherited; + fstringlistcolindex:= 0; + datacols.count:= 1; +end; + +procedure tstringlistedit.createdatacol(const index: integer; + out item: tdatacol); +begin + if index = fstringlistcolindex then begin + item:= tstringlistcol.create(self,fdatacols); + item.options:= item.options + [co_fill]; + end; +end; + +function tstringlistedit.gettext: trichstringdatalist; +begin + result:= tstringlistcol(fdatacols[0]).data; +end; + +procedure tstringlistedit.settextwidth(const Value: integer); +begin + fdatacols[fstringlistcolindex].widthmin:= value; +end; + +function tstringlistedit.gettextwidth: integer; +begin + result:= fdatacols[fstringlistcolindex].widthmin; +end; + +procedure tstringlistedit.settext(const Value: trichstringdatalist); +begin + tstringlistcol(fdatacols[0]).data.assign(value); +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/mseterminal.pas b/mseide-msegui/lib/common/editwidgets/mseterminal.pas new file mode 100644 index 0000000..9e0c254 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/mseterminal.pas @@ -0,0 +1,848 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseterminal; + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} + +interface +uses + msetypes,msegrids,classes,mclasses,msestream,mseclasses,msepipestream,mseevent, + mseinplaceedit,mserichstring, + msetextedit,msestrings,msesys,mseeditglob,msemenus,msegui,mseguiglob, + mseprocess,msegridsglob,mseedit,mseglob,msewidgetgrid,msegraphics; +type + sendtexteventty = procedure(const sender: tobject; + var atext: msestring; var donotsend: boolean) of object; + receivetexteventty = procedure(const sender: tobject; + var atext: ansistring; const errorinput: boolean) of object; + terminaloptionty = (teo_readonly,teo_bufferchunks,teo_stripescsequence, + teo_utf8); + terminaloptionsty = set of terminaloptionty; +const + defaultterminaleditoptions = (defaulttexteditoptions + [oe_caretonreadonly])- + [oe_linebreak]; + defaultterminaloptions = [{teo_tty}]; + defaultoptionsprocess = [pro_output,pro_errorouttoout,pro_input, + pro_winpipewritehandles,pro_inactive,pro_tty,pro_ctrlc]; +type +// terminalstatety = ({ts_running,}ts_listening); +// terminalstatesty = set of terminalstatety; + + + tterminal = class(tcustomtextedit,igridwidget) + private + foninputpipebroken: notifyeventty; + fonerrorpipebroken: notifyeventty; + finputcolindex: integer; + fonsendtext: sendtexteventty; + fonreceivetext: receivetexteventty; + foptions: terminaloptionsty; + fmaxchars: integer; + fupdatingcount: integer; + fonprocfinished: notifyeventty; + fmaxcommandhistory: integer; + fcommandhistory: msestringarty; + fhistoryindex: integer; + fprocess: tcustommseprocess; + function getinputfd: integer; + procedure setinoutfd(const Value: integer); + procedure setoptions(const avalue: terminaloptionsty); + function getoutputfd: integer; + procedure setoutputfd(const avalue: integer); + function geterrorfd: integer; + procedure seterrorfd(const avalue: integer); + function getoptionsprocess: processoptionsty; + procedure setoptionsprocess(const avalue: processoptionsty); + procedure setmaxcommandhistory(const avalue: integer); + function getcommand: msestring; + procedure setcommand(const avalue: msestring); + function getpipewaitus: integer; + procedure setpipewaitus(const avalue: integer); + function getprompt: msestring; + procedure setprompt(const avalue: msestring); + procedure setprocess(const avalue: tcustommseprocess); + protected + finternalprocess: tcustommseprocess; + procedure linkprocess(const aprocess: tcustommseprocess); + procedure unlinkprocess(const aprocess: tcustommseprocess); + function curprocess: tcustommseprocess; + procedure setreadonly1(const avalue: boolean); + procedure igridwidget.setreadonly = setreadonly1; + procedure setreadonly(const avalue: boolean); override; + procedure doinputavailable(const sender: tpipereader); + procedure dopipebroken(const sender: tpipereader); + procedure doprocfinished(const sender: tobject); + function echoisoff: boolean; + function echooff(out aechoisoff: boolean): boolean; + procedure echoon(const avalue: boolean); + procedure dokeydown(var info: keyeventinfoty); override; + procedure editnotification(var info: editnotificationinfoty); override; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + procedure updateeditpos; +// function stripescapesequences(avalue: msestring): msestring; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function prochandle: integer; + function execprog(const acommandline: msestring; + const aworkingdirectory: filenamety = ''; + const aparams: msestringarty = nil; + const aenvvars: msestringarty = nil): integer; + //returns prochandle + procedure terminateprocess; + procedure killprocess; + function waitforprocess: integer; //returns exitcode + function exitcode: integer; + function running: boolean; + procedure addchars(const avalue: msestring); virtual; + procedure addline(const avalue: msestring); //thread safe + procedure writestr(const atext: string); + procedure writestrln(const atext: string); + property inputfd: integer read getinputfd write setinoutfd; + property outputfd: integer read getoutputfd write setoutputfd; + property errorfd: integer read geterrorfd write seterrorfd; + procedure beginupdate; override; + procedure endupdate; override; + property prompt: msestring read getprompt write setprompt; + property command: msestring read getcommand write setcommand; + property commandhistory: msestringarty read fcommandhistory + write fcommandhistory; + property inputcolindex: integer read finputcolindex write finputcolindex; + published + property process: tcustommseprocess read fprocess write setprocess; + //replaces internal process, + //event properties in source will be owerwritten + property optionsedit1; //before optionsedit! + property optionsedit default defaultterminaleditoptions; + property font; + property cursorreadonly; + property maxchars: integer read fmaxchars write fmaxchars default 0; + property maxcommandhistory: integer read fmaxcommandhistory + write setmaxcommandhistory default 0; + property tabulators; + + property caretwidth; + property textflags; + property textflagsactive; + + property marginlinepos; + //offset to innerclientrect.x + property marginlinecolor; + + property onchange; + property ontextedited; + property onkeydown; + property onkeyup; + property oncopytoclipboard; + property onpastefromclipboard; + + property statfile; + property statvarname; + property statpriority; + property encoding; + + property onfontchanged; + property onmodifiedchanged; + property ontextmouseevent; + property oneditnotifcation; + property oncellevent; + property ondrawtext; + property onsetupeditor; + + property oninputpipebroken: notifyeventty read foninputpipebroken + write foninputpipebroken; + property onerrorpipebroken: notifyeventty read fonerrorpipebroken + write fonerrorpipebroken; + property onprocfinished: notifyeventty + read fonprocfinished write fonprocfinished; + + property onsendtext: sendtexteventty read fonsendtext write fonsendtext; + property onreceivetext: receivetexteventty read fonreceivetext + write fonreceivetext; + property options: terminaloptionsty read foptions write setoptions + default defaultterminaloptions; + property optionsprocess: processoptionsty read getoptionsprocess + write setoptionsprocess default defaultoptionsprocess; + property pipewaitus: integer read getpipewaitus write setpipewaitus + default defaultpipewaitus; + end; + +implementation +uses + msesysutils,mseprocutils,msewidgets,mseprocmonitor, + msekeyboard,sysutils,msesysintf,rtlconsts,msegraphutils,msearrayutils, + msesysintf1,msedatalist + {$ifdef unix},mselibc{$endif}; +type + tinplaceedit1 = class(tinplaceedit); + +{ tterminal } + +constructor tterminal.create(aowner: tcomponent); +begin + foptions:= defaultterminaloptions; +// fhistoryindex:= -1; + inherited; + optionsedit:= defaultterminaleditoptions; + finternalprocess:= tcustommseprocess.create(nil); + linkprocess(finternalprocess); + with finternalprocess do begin + output.overloadsleepus:= 50000; + erroroutput.overloadsleepus:= 50000; + options:= defaultoptionsprocess; +// options:= [pro_output,pro_erroroutput,pro_input,pro_tty]; + end +end; + +destructor tterminal.destroy; +begin + process:= nil; //unlink + finternalprocess.free; + inherited; +end; + +procedure tterminal.linkprocess(const aprocess: tcustommseprocess); +begin + if not (csdesigning in componentstate) then begin + with aprocess do begin + output.oninputavailable:= @doinputavailable; + output.onpipebroken:= @dopipebroken; + erroroutput.oninputavailable:= @doinputavailable; + erroroutput.onpipebroken:= @dopipebroken; + onprocfinished:= @doprocfinished; + end; + end; +end; + +procedure tterminal.unlinkprocess(const aprocess: tcustommseprocess); +begin + if not (csdesigning in componentstate) then begin + with aprocess do begin + output.oninputavailable:= nil; + output.onpipebroken:= nil; + erroroutput.oninputavailable:= nil; + erroroutput.onpipebroken:= nil; + onprocfinished:= nil; + end; + end; +end; + +function tterminal.curprocess: tcustommseprocess; +begin + result:= fprocess; + if result = nil then begin + result:= finternalprocess; + end; +end; + +procedure tterminal.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + case info.eventkind of + cek_enter: begin + if (info.newcell.row = fgridintf.getcol.grid.rowhigh) and + not (teo_readonly in foptions) then begin + optionsedit:= optionsedit - [oe_readonly]; + end + else begin + optionsedit:= optionsedit + [oe_readonly]; + end; + end; + end; + inherited; +end; + +function tterminal.getprompt: msestring; +var + int1: integer; +begin + result:= ''; + if fgridintf <> nil then begin + int1:= fgridintf.getcol.grid.rowhigh; + if int1 >= 0 then begin + result:= copy(gridvalue[int1],0,finputcolindex); + end; + end; +end; + +procedure tterminal.setprompt(const avalue: msestring); +//var +// mstr1: msestring; +begin + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + if rowhigh >= 0 then begin + gridvalue[rowhigh]:= avalue + + copy(gridvalue[rowhigh],finputcolindex+1,bigint); + finputcolindex:= length(avalue); + flines.feditcharindex:= finputcolindex; + if row = rowhigh then begin + feditor.curindex:= bigint; + end; + end; + end; + end; +end; + +procedure tterminal.setprocess(const avalue: tcustommseprocess); +begin + if fprocess <> nil then begin + unlinkprocess(fprocess); + end; + fprocess:= avalue; + if fprocess <> nil then begin + linkprocess(fprocess); + end; +end; + +function tterminal.getcommand: msestring; +var + int1: integer; +begin + result:= ''; + if fgridintf <> nil then begin + int1:= fgridintf.getcol.grid.rowhigh; + if int1 >= 0 then begin + result:= copy(gridvalue[int1],finputcolindex+1,bigint); + end; + end; +end; + +procedure tterminal.setcommand(const avalue: msestring); +//var +// int1: integer; +begin + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + if rowhigh >= 0 then begin + gridvalue[rowhigh]:= copy(gridvalue[rowhigh],1,finputcolindex)+avalue; + if row = rowhigh then begin + feditor.curindex:= bigint; + end; + end; + end; + end; +end; + +procedure tterminal.editnotification(var info: editnotificationinfoty); +var + mstr1: msestring; + bo1,bo2,bo3: boolean; + ar1: msestringarty; + int1: integer; +begin + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + case info.action of + ea_textedited: begin + if echoisoff then begin + feditor.format:= updatefontstyle(feditor.format, + finputcolindex,bigint,fs_blank,true); + end; + end; + ea_indexmoved: begin + if editpos.row = datalist.count - 1 then begin + if (editpos.col < finputcolindex) or (teo_readonly in foptions) then begin + optionsedit:= optionsedit + [oe_readonly]; + end + else begin + optionsedit:= optionsedit - [oe_readonly]; + end; + end; + end; + ea_delchar: begin + if (info.dir = gd_left) and (editpos.col <= finputcolindex) then begin + info.action:= ea_none; + end; + end; + ea_textentered: begin + if (row = rowhigh) and not (teo_readonly in foptions) then begin + info.action:= ea_none; + mstr1:= copy(feditor.text,finputcolindex+1,bigint); + if (fmaxcommandhistory > 0) and not running then begin + fhistoryindex:= 0; + if((fcommandhistory = nil) or (fcommandhistory[0] <> mstr1)) then begin + if (fcommandhistory = nil) then begin + setlength(fcommandhistory,1); + end; + fcommandhistory[0]:= mstr1; + insertitem(fcommandhistory,0,''); + if length(fcommandhistory) > fmaxcommandhistory then begin + setlength(fcommandhistory,fmaxcommandhistory); + end; + end; + end; + bo1:= false; + if assigned(fonsendtext) then begin + fonsendtext(self,mstr1,bo1); + end; + if not bo1 then begin + bo2:= echooff(bo3); + try + if teo_utf8 in foptions then begin + curprocess.input.pipewriter.writeln(stringtoutf8ansi(mstr1)); + end + else begin + curprocess.input.pipewriter.writeln(mstr1); + end; + if not bo3 then begin + datalist.add(''); + end; + except + feditor.text:= ''; + gridvalue[row]:= copy(gridvalue[row],1,finputcolindex); + end; + echoon(bo2); + end; +// else begin +// datalist.add(''); +// end; + updateeditpos; + end; + end; + ea_pasteselection: begin + if msewidgets.pastefromclipboard(mstr1,info.bufferkind) then begin + clearselection; + ar1:= breaklines(mstr1); + if high(ar1) >= 0 then begin +// datalist[rowhigh]:= datalist[rowhigh] + ar1[0]; + editor.inserttext(ar1[0],false); + for int1:= 1 to high(ar1) do begin + tinplaceedit1(editor).checkaction(ea_textentered); + datalist[rowhigh]:= ar1[int1]; + end; + if high(ar1) > 0 then begin + editpos:= makegridcoord(length(datalist[rowhigh]),rowhigh); + end; + end; +// editpos:= makegridcoord(length(datalist[rowhigh]),rowhigh); + end; + info.action:= ea_none; + end; + end; + if info.action <> ea_none then begin + inherited; + end; + end; + end; +end; + +function tterminal.echoisoff: boolean; +{$ifdef unix} +var + terminfo: termios; +{$endif} +begin + result:= false; +{$ifdef unix} + if (pro_echo in curprocess.options) and running and + (msetcgetattr(outputfd,terminfo) = 0) then begin + result:= terminfo.c_lflag and echo = 0; + end; +{$endif} +end; + +function tterminal.echooff(out aechoisoff: boolean): boolean; +{$ifdef unix} +var + terminfo: termios; +{$endif} +begin + result:= false; + aechoisoff:= false; +{$ifdef unix} + if (pro_echo in curprocess.options) and running and + (msetcgetattr(outputfd,terminfo) = 0) then begin + result:= terminfo.c_lflag and echo <> 0; + aechoisoff:= not result; + if result then begin + tcdrain(outputfd); + usleep(0); //why is this necessary? no tcdrain without + terminfo.c_lflag:= terminfo.c_lflag and not echo; + msetcsetattr(outputfd,tcsadrain,terminfo); + end; + end; +{$endif} +end; + +procedure tterminal.echoon(const avalue: boolean); +{$ifdef unix} +var + terminfo: termios; +{$endif} +begin +{$ifdef unix} + if avalue and (msetcgetattr(inputfd,terminfo) = 0) then begin + terminfo.c_lflag:= terminfo.c_lflag or echo; + tcdrain(outputfd); + usleep(0); //why is this necessary? no tcdrain without + msetcsetattr(outputfd,tcsadrain,terminfo); + end; +{$endif} +end; + +procedure tterminal.dokeydown(var info: keyeventinfoty); +begin + if fgridintf <> nil then begin + with info do begin + if (key = key_c) and (shiftstate = [ss_ctrl]) and + (pro_ctrlc in optionsprocess) and running then begin + command:= '^C'; + finputcolindex:= finputcolindex + 2; + include(info.eventstate,es_processed); + try + curprocess.terminate; + except + curprocess.kill; + end; + end + else begin + if shiftstate - [ss_shift] = [] then begin + if (chars <> '') and + ((editpos.row < datalist.count - 1) or + (editpos.col < finputcolindex)) then begin + editpos:= makegridcoord(bigint,bigint); + end + else begin + if (key = key_home) and (editpos.row = datalist.count - 1) then begin + editor.moveindex(finputcolindex,ss_shift in shiftstate); + include(eventstate,es_processed); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + if (fmaxcommandhistory > 0) and not running then begin + include(info.eventstate,es_processed); + case key of + key_up,key_down: begin + if fcommandhistory = nil then begin + setlength(fcommandhistory,1); + fhistoryindex:= 0; + end; + fcommandhistory[fhistoryindex]:= command; + if key = key_up then begin + if fhistoryindex < high(fcommandhistory) then begin + inc(fhistoryindex); + end; + end + else begin + if fhistoryindex > 0 then begin + dec(fhistoryindex); + end; + end; + command:= fcommandhistory[fhistoryindex]; + end; + else begin + exclude(info.eventstate,es_processed); + end; + end; + if (es_processed in eventstate) and (fgridintf <> nil) then begin + fgridintf.getcol.grid.row:= bigint; + feditor.curindex:= bigint; + if not (teo_readonly in foptions) then begin + optionsedit:= optionsedit - [oe_readonly]; + end; + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; + end; + end; +end; + +procedure tterminal.updateeditpos; +var + int1: integer; +begin + if (fgridintf <> nil) and (fupdatingcount = 0) then begin + int1:= datalist.count-1; + if int1 >= 0 then begin + finputcolindex:= length(datalist[int1]); + end; + editpos:= makegridcoord(finputcolindex,int1); + end; +end; + +procedure tterminal.doinputavailable(const sender: tpipereader); +var + str1: string; + int1: integer; +begin + try + if teo_bufferchunks in foptions then begin + str1:= sender.readbuffer; + end + else begin + str1:= sender.readdatastring; + end; + if not (csdestroying in componentstate) then begin + if canevent(tmethod(fonreceivetext)) then begin + fonreceivetext(self,str1,sender = curprocess.erroroutput.pipereader); + end; + if teo_utf8 in foptions then begin + addchars(utf8tostringansi(str1)); + end + else begin + addchars(msestring(str1)); + end; + if teo_bufferchunks in foptions then begin + int1:= application.unlockall; + sleepus(0); //sched_yield + application.relockall(int1); + end; + end; + except + end; +end; + +procedure tterminal.addchars(const avalue: msestring); +var + mstr1: msestring; +begin + if fgridintf <> nil then begin + if datalist.count > 0 then begin + mstr1:= datalist[datalist.count-1]; + if length(mstr1) > finputcolindex then begin + datalist[datalist.count-1]:= copy(mstr1,1,finputcolindex); + //remove entered characters + end; + end; + if teo_stripescsequence in foptions then begin + mstr1:= stripescapesequences(avalue); + end + else begin + mstr1:= avalue; + end; + datalist.addchars(mstr1,[aco_processeditchars],fmaxchars); + if window.haswinid then begin //possible deadlock by synchronize() otherwise + updateeditpos; + end; + end; +end; + +procedure tterminal.addline(const avalue: msestring); +begin + if fgridintf <> nil then begin + application.lock; + try + addchars(avalue+lineend); + finally + application.unlock; + end; + end; +end; + +procedure tterminal.dopipebroken(const sender: tpipereader); +begin + if sender = curprocess.output.pipereader then begin + if canevent(tmethod(foninputpipebroken)) then begin + foninputpipebroken(self); + end; + end + else begin + if canevent(tmethod(fonerrorpipebroken)) then begin + fonerrorpipebroken(self); + end; + end; +end; + +procedure tterminal.doprocfinished(const sender: tobject); +begin + if canevent(tmethod(fonprocfinished)) then begin + fonprocfinished(self); + end; +end; + +function tterminal.execprog(const acommandline: msestring; + const aworkingdirectory: filenamety = ''; + const aparams: msestringarty = nil; + const aenvvars: msestringarty = nil): integer; +begin + with curprocess do begin + active:= false; +// if active then begin +// componentexception(self,'Process already active.'); +// end; + commandline:= acommandline; + workingdirectory:= aworkingdirectory; + params.asarray:= aparams; + envvars.asarray:= aenvvars; + active:= true; + result:= lastprochandle; + end; +end; + +function tterminal.getinputfd: integer; +begin + result:= curprocess.output.pipereader.handle; +end; + +function tterminal.prochandle: integer; +begin + result:= curprocess.prochandle; +end; + +procedure tterminal.setinoutfd(const Value: integer); +begin + curprocess.output.pipereader.handle:= value; +end; + +function tterminal.waitforprocess: integer; +begin + result:= curprocess.waitforprocess; +end; + +function tterminal.exitcode: integer; +begin + result:= curprocess.exitcode; +end; + +function tterminal.running: boolean; +begin + result:= curprocess.running; +end; + +procedure tterminal.setoptions(const avalue: terminaloptionsty); +begin + foptions:= avalue; + if (teo_readonly in foptions) then begin + optionsedit:= optionsedit + [oe_readonly]; + end; +end; + +function tterminal.getoutputfd: integer; +begin + result:= curprocess.input.pipewriter.handle; +end; + +procedure tterminal.setoutputfd(const avalue: integer); +begin + curprocess.input.pipewriter.handle:= avalue; +end; + +function tterminal.geterrorfd: integer; +begin + result:= curprocess.erroroutput.pipereader.handle; +end; + +procedure tterminal.seterrorfd(const avalue: integer); +begin + curprocess.erroroutput.pipereader.handle:= avalue; +end; + +procedure tterminal.writestr(const atext: string); +var + bo1,bo2: boolean; +begin + bo1:= echooff(bo2); + try + if sys_write(outputfd,pointer(atext),length(atext)) <> length(atext) then begin + syserror(syelasterror); + end; + finally + echoon(bo1); + end; +end; + +procedure tterminal.writestrln(const atext: string); +begin + writestr(atext+lineend); +end; +{ +function tterminal.getonprocfinished: notifyeventty; +begin + result:= fprocess.onprocfinished; +end; + +procedure tterminal.setonprocfinished(const avalue: notifyeventty); +begin + fprocess.onprocfinished:= avalue; +end; +} +procedure tterminal.terminateprocess; +begin + curprocess.terminate; +end; + +procedure tterminal.killprocess; +begin + curprocess.kill; +end; + +function tterminal.getoptionsprocess: processoptionsty; +begin + result:= finternalprocess.options; +end; + +procedure tterminal.setoptionsprocess(const avalue: processoptionsty); +begin + finternalprocess.options:= avalue; +end; + +procedure tterminal.beginupdate; +begin + inc(fupdatingcount); + inherited; +end; + +procedure tterminal.endupdate; +begin + try + inherited; + finally + dec(fupdatingcount); + if fupdatingcount = 0 then begin + updateeditpos; + end; + end; +end; + +procedure tterminal.setmaxcommandhistory(const avalue: integer); +begin + fmaxcommandhistory:= avalue; + if length(fcommandhistory) > avalue then begin + setlength(fcommandhistory,avalue); + end; + if fhistoryindex > high(fcommandhistory) then begin + fhistoryindex:= high(fcommandhistory); + end; +end; + +function tterminal.getpipewaitus: integer; +begin + result:= finternalprocess.pipewaitus; +end; + +procedure tterminal.setpipewaitus(const avalue: integer); +begin + finternalprocess.pipewaitus:= avalue; +end; + +procedure tterminal.setreadonly(const avalue: boolean); +begin + if avalue then begin + options:= options + [teo_readonly]; + end + else begin + options:= options - [teo_readonly]; + end; + inherited; +end; + +procedure tterminal.setreadonly1(const avalue: boolean); +begin + //dummy for igridwidget +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msetextedit.pas b/mseide-msegui/lib/common/editwidgets/msetextedit.pas new file mode 100644 index 0000000..40fe4d1 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msetextedit.pas @@ -0,0 +1,2834 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msetextedit; + +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +uses + mseeditglob,mseedit,msewidgetgrid,classes,mclasses,msedatalist, + msegraphics,msestream,msedragglob,msesys,mseassistiveclient, + msetypes,mserichstring,msestat,msestatfile,mseclasses,mseinplaceedit,msegrids, + mseevent,mseguiglob,msegui,msegraphutils,msestrings,msedrawtext,msearrayprops, + msemenus,msepointer,msegridsglob{$ifdef mse_with_ifi},mseificomp{$endif}, + mseglob; + +const + + defaulttexteditoptions = (defaultoptionsedit + + [oe_linebreak,oe_nofirstarrownavig]) - + [oe_autoselect,oe_autoselectonfirstclick,oe_endonenter, + oe_resetselectonexit,oe_undoonesc,oe_shiftreturn, + oe_trimleft,oe_trimright,oe_uppercase,oe_lowercase]; + + texteditminimalframe: framety = (left: 1; top: 0; right: 1; bottom: 0); + defaulttexteditwidgetoptions = + (defaulteditwidgetoptions + { - [ow_fontglyphheight]}){ + [ow_fontlineheight]}; + defaulttexteditwidgetoptions1 = + (defaulteditwidgetoptions1 - [ow1_fontglyphheight]) + + [ow1_fontlineheight]; + +type + + textmouseeventinfoty = record + eventkind: celleventkindty; + mouseeventinfopo: pmouseeventinfoty; + pos: gridcoordty; + end; + + tcustomtextedit = class; + textmouseeventty = procedure(const sender: tobject; + var info: textmouseeventinfoty) of object; + textdraweventty = procedure(const sender: tcustomtextedit; + const canvas: tcanvas; const atext: richstringty; + const cellinfo: pcellinfoty; var handled: boolean) of object; + //cellinfo = nil for focused widget + setupeditoreventty = procedure(const sender: tcustomtextedit) of object; + + texteditstatety = (tes_selectinvalid,tes_cellentering,tes_xposinvalid); + texteditstatesty = set of texteditstatety; + + tgridrichstringdatalist = class(trichstringdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + end; + + texteditoptionty = (teeo_bom,teeo_nobom); //[] -> use loaded + texteditoptionsty = set of texteditoptionty; + + tcustomtextedit = class(tcustomedit,igridwidget,istatfile, + iassistiveclientgridwidget) + private + fstatfile: tstatfile; + fstatvarname: msestring; + fselectstart,fselectend: gridcoordty; + fmodified: boolean; + fonmodifiedchanged: booleanchangedeventty; + fontextmouseevent: textmouseeventty; + fmousetextpos: gridcoordty; + foneditnotification: editnotificationeventty; + foncellevent: celleventty; + fonfontchanged: notifyeventty; + fmarginlinecolor: colorty; + fmarginlinepos: integer; + ftabulators: ttabulators; + fencoding: charencodingty; + fxpos: integer; + fstatpriority: integer; + fhasbom: boolean; + foptions: texteditoptionsty; + feolstyle: eolstylety; + fondrawtext: textdraweventty; + fonsetupeditor: setupeditoreventty; + procedure setstatfile(const Value: tstatfile); + function geteditpos: gridcoordty; + procedure seteditpos1(const value: gridcoordty); + function getgridvalue(const index: integer): msestring; + procedure setgridvalue(const index: integer; const Value: msestring); + function getgridvalues: msestringarty; + procedure setgridvalues(const Value: msestringarty); + function getrichlines(const index: integer): richstringty; + procedure setrichlines(const index: integer; const Value: richstringty); + function getrichformats(const index: integer): formatinfoarty; + procedure setrichformats(const index: integer; const avalue: formatinfoarty); + procedure setmodified(const avalue: boolean); + procedure setdatalist(const avalue: tgridrichstringdatalist); + + procedure mousepostotextpos1(const row: integer; const mousepos: pointty; + var textpos: gridcoordty; var result: boolean); + procedure setmarginlinecolor(avalue: colorty); + procedure setmarginlinepos(const avalue: integer); + procedure colchanged; + function gettabulators: ttabulators; + procedure settabulators(const Value: ttabulators); +// procedure setreadonly(const avalue: boolean); + function getrow: integer; + procedure setrow(const avalue: integer); + function getcol: integer; + procedure setcol(const avalue: integer); + procedure setoptions(const avalue: texteditoptionsty); + protected + ftextstate: texteditstatesty; + fgridintf: iwidgetgrid; + fupdating: integer; + fnotificationchangelock: integer; + ffilename: filenamety; + ffilerights: filerightsty; + flines: tgridrichstringdatalist; + ffoundeolstyle: eolstylety; + procedure setoptionsedit(const avalue: optionseditty); override; + procedure setoptionsedit1(const avalue: optionsedit1ty); override; + + function beforechange: boolean; //true if not aborted + procedure fontchanged; override; + procedure tabulatorschanged(const sender: tarrayprop; const index: integer); + procedure painttext(const canvas: tcanvas); override; + procedure dobeforepaintforeground(const canvas: tcanvas); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure getstate(out state: texteditstatety); virtual; + procedure setstate(const state: texteditstatety); virtual; + procedure setfilename(value: filenamety); //no const! + procedure insertlinebreak; virtual; + procedure editnotification(var info: editnotificationinfoty); override; + procedure updateindex(select: boolean); + procedure textinserted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); virtual; + procedure textdeleted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); virtual; + + procedure dotextmouseevent(var info: textmouseeventinfoty); + procedure dosetupeditor(); + procedure setupeditor; override; + procedure dofontheightdelta(var delta: integer); override; + procedure sizechanged; override; + function getinnerframe: framety; override; + function textclipped(const arow: integer; + out acellrect: rectty): boolean; virtual; + function textclipped(const arow: integer): boolean; + + function getiassistiveclient(): iassistiveclient override; + //iassistiveclientgridwidget + function getassistivecolumncaption(): msestring virtual; + //igridwidget + procedure setfirstclick(var ainfo: mouseeventinfoty); + function createdatalist(const sender: twidgetcol): tdatalist; virtual; + procedure datalistdestroyed; + function getdatalistclass: datalistclassty; virtual; + function getinitvalue: pointer; + function getdefaultvalue: pointer; + function getrowdatapo(const arow: integer): pointer; virtual; + procedure setgridintf(const intf: iwidgetgrid); + function getgridintf: iwidgetgrid; + function needscellfocuspaint(): boolean; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; virtual; + procedure updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); virtual; + function getnulltext: msestring; + procedure drawcell(const canvas: tcanvas); + procedure updateautocellsize(const canvas: tcanvas); virtual; + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure initgridwidget; + procedure valuetogrid(row: integer); + procedure gridtovalue(row: integer); + procedure setvaluedata(const source); virtual; + procedure getvaluedata(out dest); virtual; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); virtual; + function sortfunc(const l,r): integer; + procedure gridvaluechanged(const index: integer); virtual; + procedure updatecoloptions(const aoptions: coloptionsty); + procedure updatecoloptions1(const aoptions: coloptions1ty); + procedure statdataread; virtual; + procedure griddatasourcechanged; + {$ifdef mse_with_ifi} + function getifilink: tifilinkcomp; + procedure dochange; override; + {$endif} + procedure setparentgridwidget(const intf: igridwidget); + procedure childdataentered(const sender: igridwidget); virtual; + procedure childfocused(const sender: igridwidget); virtual; + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + procedure checkgrid; + + procedure setedpos(const Value: gridcoordty; const select: boolean; + const donotify: boolean; + const ashowcell: cellpositionty); + procedure internalclearselection; + procedure internaldeletetext(const start, stop: gridcoordty; + const userinput: boolean); + //iassistiveclient + function getassistivetext(): msestring; override; + function getassistiveflags: assistiveflagsty; override; + //iassistiveclientgrid + function getassistivecelltext(const arow: int32): msestring; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure createtabulators; + function actualcolor: colorty; override; + procedure synctofontheight; override; + procedure reloadfile(restorestate: boolean = true); + procedure loadfromstream(const stream: ttextstream; + restorestate: boolean = false); + procedure loadfromfile(afilename: filenamety; //no const! + restorestate: boolean = false); virtual; + procedure savetostream(const stream: ttextstream; + const resetmodified: boolean); + procedure savetofile(const afilename: filenamety = ''); + //afilename = '' -> current filename + property filename: filenamety read ffilename; + property filerights: filerightsty read ffilerights write ffilerights; + + procedure beginupdate; virtual; + procedure endupdate; virtual; + procedure clear; virtual; +// function filename: filenamety; + + procedure seteditpos(const Value: gridcoordty; const select: boolean = false; + const ashowcell: cellpositionty = cep_nearest); + procedure inserttext(const apos: gridcoordty; const atext: msestring; + out aendpos: gridcoordty; + selected: boolean = false; + insertbackwards: boolean = false); overload; + procedure inserttext(const apos: gridcoordty; const atext: msestring; + selected: boolean = false; + insertbackwards: boolean = false); overload; + procedure inserttext(const atext: msestring; + selected: boolean = false); overload; + procedure deletetext(const start,stop: gridcoordty); + function appendrow(const atext: msestring): integer; overload; + function appendrow(const atext: richstringty): integer; overload; + + function hasselection: boolean; override; + function selectedtext: msestring; + function selectedrichtext: richstringty; + procedure getselectedrows(out start,stop: integer); + + property optionsedit default defaulttexteditoptions; + procedure setfontstyle(const start,stop: gridcoordty; + const astyle: fontstylety; const aset: boolean; + const afontcolor: colorty = cl_default; + const acolorbackground: colorty = cl_default); + //astyle = fs_force -> set colors only + property selectstart: gridcoordty read fselectstart; + property selectend: gridcoordty read fselectend; + procedure setselection(const start,stop: gridcoordty; + const aseteditpos: boolean = false; + const ashowcell: cellpositionty = cep_nearest); + procedure clearselection; + procedure copyselection; + procedure cutselection; + function canpaste: boolean; + procedure paste; + procedure deleteselection; + procedure selectall; + + function find(const atext: msestring; options: searchoptionsty; + var textpos: gridcoordty; const endpos: gridcoordty; + selectfound: boolean = false; + const ashowcell: cellpositionty = cep_nearest): boolean; + + function gettext(const start, stop: gridcoordty): msestring + overload reintroduce; + function gettext: msestring overload reintroduce; + procedure settext(const atext: msestring) reintroduce; + function getrichtext(const start, stop: gridcoordty): richstringty; + + function getcellframe: framety; virtual; + + function linecount: integer; + property gridvalue[const index: integer]: msestring + read getgridvalue write setgridvalue; default; + property gridvalues: msestringarty read getgridvalues write setgridvalues; + property richlines[const index: integer]: richstringty + read getrichlines write setrichlines; + property richformats[const index: integer]: formatinfoarty + read getrichformats write setrichformats; + property datalist: tgridrichstringdatalist read flines write setdatalist; + + function mousepostotextpos(const mousepos: pointty; out textpos: gridcoordty; + widgetorg: boolean = false): boolean; + //if widgetorg = false -> org mousepos = topleft of col + // org mousepos = clientpos otherwise + //false if out of text, textpos clamped to textrange + function textpostomousepos(const textpos: gridcoordty; + const screenorg: boolean = false): pointty; + function textpostomouserect(const textpos: gridcoordty; + const screenorg: boolean = false): rectty; + //y:= top of character cell cx = 0 cy = linespacing + property editpos: gridcoordty read geteditpos write seteditpos1; + property row: integer read getrow write setrow; + property col: integer read getcol write setcol; + property modified: boolean read fmodified write setmodified; + + property encoding: charencodingty read fencoding write fencoding + default ce_locale; + property eolstyle: eolstylety read feolstyle write feolstyle + default eol_default; + //applied to write stream if stream.eolstyle = ce_default + //ce_default -> use foundeolstyle of last read stream + //ce_default -> system eol + property options: texteditoptionsty read foptions write setoptions + default []; + property textflags default defaulttextflags - [tf_noselect]; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property tabulators: ttabulators read gettabulators write settabulators; + property marginlinepos: integer read fmarginlinepos + write setmarginlinepos default 0; + //offset to innerclientrect.x + property marginlinecolor: colorty read fmarginlinecolor + write setmarginlinecolor default cl_none; + property onfontchanged: notifyeventty read fonfontchanged + write fonfontchanged; + property onmodifiedchanged: booleanchangedeventty read fonmodifiedchanged + write fonmodifiedchanged; + property ontextmouseevent: textmouseeventty read fontextmouseevent + write fontextmouseevent; + property oneditnotifcation: editnotificationeventty read foneditnotification + write foneditnotification; + property ondrawtext: textdraweventty read fondrawtext write fondrawtext; + property onsetupeditor: setupeditoreventty read fonsetupeditor + write fonsetupeditor; + property oncellevent: celleventty read foncellevent write foncellevent; + published + property optionswidget default defaulttexteditwidgetoptions; + property optionswidget1 default defaulttexteditwidgetoptions1; + end; + + ttextedit = class(tcustomtextedit) + published + property font; + property caretwidth; + property cursorreadonly; + property optionsedit1; //before optionsedit! + property optionsedit; + property textflags; + property textflagsactive; + + property statfile; + property statvarname; + property statpriority; + property encoding; + property options; + property marginlinepos; + //offset to innerclientrect.x + property marginlinecolor; + property tabulators; + + property onchange; + property ontextedited; + property onkeydown; + property onkeyup; + property oncopytoclipboard; + property onpastefromclipboard; + + property onfontchanged; + property onmodifiedchanged; + property ontextmouseevent; + property oneditnotifcation; + property oncellevent; + property ondrawtext; + property onsetupeditor; + end; + + tundotextedit = class(ttextedit,iundo) + private + function getmaxundocount: integer; + procedure setmaxundocount(const Value: integer); + function getmaxundosize: integer; + procedure setmaxundosize(const Value: integer); + protected + procedure textinserted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); override; + procedure textdeleted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); override; + procedure getselectstart(var selectstartpos: gridcoordty); + procedure setselectstart(const selectstartpos: gridcoordty); + protected + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + procedure undo; + procedure redo; + function canundo: boolean; + function canredo: boolean; + procedure lowercase; //selection -> lowercase; + procedure uppercase; //selection -> uppercase + procedure tabtospace; //selection tab -> space + published + property maxundocount: integer read getmaxundocount write + setmaxundocount default defaultundomaxcount; + property maxundosize: integer read getmaxundosize write + setmaxundosize default defaultundobuffermaxsize; + end; + +procedure normalizetextrect(const po1,po2: gridcoordty; + out start,stop: gridcoordty); +function istextdblclick(const ainfo: textmouseeventinfoty): boolean; + +implementation +uses + msefileutils,sysutils,msesysutils,msewidgets,msebits, + msekeyboard,mseactions; + +const + valuevarname = 'value'; +type + tcustomwidgetgrid1 = class(tcustomwidgetgrid); + tinplaceedit1 = class(tinplaceedit); + twidgetcol1 = class(twidgetcol); + tcustomrowstatelist1 = class(tcustomrowstatelist); + twidget1 = class(twidget); + +procedure normalizetextrect(const po1,po2: gridcoordty; out start,stop: gridcoordty); +begin + if po1.row > po2.row then begin + start:= po2; + stop:= po1; + end + else begin + if po1.row < po2.row then begin + start:= po1; + stop:= po2; + end + else begin + if po1.col > po2.col then begin + start:= po2; + stop:= po1; + end + else begin + start:= po1; + stop:= po2; + end; + end; + end; +end; + +function istextdblclick(const ainfo: textmouseeventinfoty): boolean; +begin + result:= (ainfo.eventkind = cek_buttonpress) and + (ss_double in ainfo.mouseeventinfopo^.shiftstate); +end; + +function createtgridrichstringdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridrichstringdatalist.create(aowner); +end; + +{ tgridrichstringdatalist } + +constructor tgridrichstringdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridrichstringdatalist.getdefault: pointer; +begin + if twidgetcol1(fowner).fintf <> nil then begin + result:= twidgetcol1(fowner).fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +{ tcustomtextedit } + +constructor tcustomtextedit.create(aowner: tcomponent); +begin + feolstyle:= eol_default; + ffilerights:= defaultfilerights; + fmousetextpos:= invalidcell; + fmarginlinecolor:= cl_none; + if feditor = nil then begin + feditor:= tinplaceedit.create(self,iedit(self),true); + end; + inherited; + foptionswidget:= defaulttexteditwidgetoptions; + foptionswidget1:= defaulttexteditwidgetoptions1; + optionsedit:= defaulttexteditoptions; + textflags:= defaulttextflags - [tf_noselect]; +end; + +destructor tcustomtextedit.destroy; +begin + inherited; + ftabulators.Free; +end; + +function tcustomtextedit.actualcolor: colorty; +begin + if (fgridintf <> nil) and (fcolor = cl_default) then begin + result:= fgridintf.getcol.rowcolor(fgridintf.getrow); + end + else begin + result:= inherited actualcolor; + end; +end; + +procedure tcustomtextedit.synctofontheight; +begin + inherited; + if (fgridintf <> nil) and not (tf_rotate90 in textflags) then begin + fgridintf.getcol.grid.datarowheight:= bounds_cy - font.glyphheight + font.lineheight; + end; +end; + +procedure tcustomtextedit.dofontheightdelta(var delta: integer); +begin + inherited; + gridwidgetfontheightdelta(self,fgridintf,delta); +{ + inherited; + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + datarowheight:= datarowheight + delta; + end; + end; +} +end; + +procedure tcustomtextedit.sizechanged; +begin + inherited; + gridwidgetsized(self,fgridintf); +end; + +procedure tcustomtextedit.setgridintf(const intf: iwidgetgrid); +begin + fgridintf:= intf; + if (intf <> nil) then begin + flines:= tgridrichstringdatalist(fgridintf.getcol.datalist); + if (ow1_autoscale in foptionswidget1) and + (foptionswidget1 * [ow1_fontglyphheight,ow1_fontlineheight] + <> []) then begin + fgridintf.getcol.grid.datarowheight:= bounds_cy; + end; + end; +end; + +function tcustomtextedit.getcellframe: framety; +begin + if fframe <> nil then begin + result:= frame.cellframe; + end + else begin + if fgridintf <> nil then begin + result:= tgridarrayprop(fgridintf.getcol.prop).innerframe; + end + else begin + result:= getinnerframe; + end; + end; +end; + +function tcustomtextedit.needscellfocuspaint(): boolean; +begin + result:= inherited needsfocuspaint(); +end; + +function tcustomtextedit.getcellcursor(const arow: integer; + const acellzone: cellzonety; + const apos: pointty): cursorshapety; +begin + result:= actualcursor(nullpoint); +end; + +procedure tcustomtextedit.updatecellzone(const row: integer; + const apos: pointty; var result: cellzonety); +begin + //dummy +end; + +function tcustomtextedit.getnulltext: msestring; +begin + result:= ''; +end; + +function tcustomtextedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + flines:= tgridrichstringdatalist.create(sender); + result:= flines; +end; + +function tcustomtextedit.getdatalistclass: datalistclassty; +begin + result:= tgridrichstringdatalist; +end; + +procedure tcustomtextedit.dobeforepaintforeground(const canvas: tcanvas); +var + int1: integer; +begin + if fmarginlinecolor <> cl_none then begin + int1:= innerclientpos.x + fmarginlinepos; + if fframe = nil then begin + inc(int1,texteditminimalframe.left); + end; + canvas.drawline(makepoint(int1,0),makepoint(int1,clientsize.cy), + fmarginlinecolor); + end; +end; + +procedure tcustomtextedit.painttext(const canvas: tcanvas); +var + b1: boolean; +begin + if assigned(fondrawtext) then begin + b1:= false; + fondrawtext(self,canvas,feditor.richtext,nil,b1); + if b1 then begin + exit; + end; + end; + inherited; +end; + +procedure tcustomtextedit.drawcell(const canvas: tcanvas); +var + rect1: rectty; + int1: integer; + b1: boolean; +begin + with cellinfoty(canvas.drawinfopo^) do begin + if assigned(fondrawtext) then begin + b1:= false; + fondrawtext(self,canvas,prichstringty(datapo)^,canvas.drawinfopo,b1); + if b1 then begin + exit; + end; + end; + if calcautocellsize then begin + rect1:= textrect(canvas,prichstringty(datapo)^,innerrect, + feditor.textflags,nil,ftabulators); + int1:= rect.cx + rect1.cx - innerrect.cx; + if int1 > autocellsize.cx then begin + autocellsize.cx:= rect1.cx; + end; + int1:= rect.cy + rect1.cy - innerrect.cy; + if int1 > autocellsize.cy then begin + autocellsize.cy:= int1; + end; + end + else begin + if fmarginlinecolor <> cl_none then begin + int1:= innerrect.x + fmarginlinepos; + canvas.drawline(makepoint(int1,0),makepoint(int1,rect.cy),fmarginlinecolor); + end; + drawtext(canvas,prichstringty(datapo)^,innerrect,feditor.textflags,nil, + ftabulators); + end; + end; +end; + +procedure tcustomtextedit.updateautocellsize(const canvas: tcanvas); +begin + drawcell(canvas); +end; + +function tcustomtextedit.beforechange: boolean; //true if not aborted +begin + result:= feditor.beforechange; +end; + +procedure tcustomtextedit.fontchanged; +begin + inherited; + if fgridintf <> nil then begin + fgridintf.getcol.changed; + end; + if canevent(tmethod(fonfontchanged)) then begin + fonfontchanged(self); + end; +end; + +{ +procedure tcustomtextedit.updatecellzone(const pos: pointty; var result: cellzonety); +begin + //dummy +end; +} +function tcustomtextedit.getdefaultvalue: pointer; +begin + result:= nil; +end; + +function tcustomtextedit.getrowdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +procedure tcustomtextedit.setfirstclick(var ainfo: mouseeventinfoty); +begin + //dummy +end; + +function tcustomtextedit.getinitvalue: pointer; +begin + result:= nil; +end; + +procedure tcustomtextedit.valuetogrid(row: integer); +begin + fgridintf.setdata(row,feditor.richtext); +end; + +procedure tcustomtextedit.gridtovalue(row: integer); +var + text1: richstringty; +begin + if fupdating = 0 then begin + fgridintf.getdata(row,text1); + inc(fupdating); + try + feditor.richtext:= text1; + finally + dec(fupdating); + end; + end; +end; + +procedure tcustomtextedit.initgridwidget; +begin + optionswidget1:= optionswidget1 - [ow1_autoscale]; + frame:= nil; + with fgridintf.grid do begin + optionsgrid:= optionsgrid + [og_autofirstrow]; + end; + optionsskin:= optionsskin + defaultgridskinoptions; +end; + +function tcustomtextedit.sortfunc(const l,r): integer; +begin + result:= 0; +end; + +procedure tcustomtextedit.gridvaluechanged(const index: integer); +begin + modified:= true; +end; + +procedure tcustomtextedit.updatecoloptions(const aoptions: coloptionsty); +var + opt1: optionsedit1ty; +begin + opt1:= feditor.optionsedit1; + fgridintf.coloptionstoeditoptions(foptionsedit,opt1); + feditor.optionsedit1:= opt1; +end; + +procedure tcustomtextedit.updatecoloptions1(const aoptions: coloptions1ty); +begin + //dummy +end; + +procedure tcustomtextedit.statdataread; +begin + modified:= false; +end; + +procedure tcustomtextedit.griddatasourcechanged; +begin + //dummy +end; + +{$ifdef mse_with_ifi} +function tcustomtextedit.getifilink: tifilinkcomp; +begin + result:= nil; +end; + +procedure tcustomtextedit.dochange; +begin + inherited; + { + if not (ws_loadedproc in fwidgetstate) then begin + if fifiserverintf <> nil then begin + fifiserverintf.valuechanged(iificlient(self)); + end; + end; + } +end; +{$endif mse_with_ifi} + +procedure tcustomtextedit.setoptionsedit(const avalue: optionseditty); +var + opt1: optionseditty; +begin + opt1:= avalue - [oe_trimleft,oe_trimright,oe_uppercase,oe_lowercase]; + if foptionsedit <> opt1 then begin + inherited setoptionsedit(opt1); + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,feditor.optionsedit1); + end; + end; +end; + +procedure tcustomtextedit.setoptionsedit1(const avalue: optionsedit1ty); +begin + inherited; + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,feditor.optionsedit1); + end; +end; + +procedure tcustomtextedit.dokeydown(var info: keyeventinfoty); +var + shiftstate1: shiftstatesty; + int1,int2: integer; + indexbefore: integer; + rect1: rectty; + bo1,bo2: boolean; +begin + with info do begin + shiftstate1:= shiftstate * shiftstatesmask; + if (tf_wordbreak in textflagsactive) and + (shiftstate1 - [ss_shift] = []) then begin + include(info.eventstate,es_processed); + with feditor do begin + int2:= fxpos; + int1:= 0; + case key of + key_up: begin + int1:= - self.font.lineheight; + end; + key_down: begin + int1:= self.font.lineheight; + end; + else begin + exclude(info.eventstate,es_processed); + end; + end; + if int1 <> 0 then begin + int1:= caretpos.y + int1; + rect1:= textrect; + if int1 < rect1.y then begin + int1:= rect1.y; + end; + if int1 >= rect1.y + rect1.cy then begin + int1:= rect1.y + rect1.cy - 1; + end; + indexbefore:= curindex; + moveindex(mousepostotextindex(makepoint(fxpos,int1)), + ss_shift in info.shiftstate); + if ss_shift in info.shiftstate then begin + invalidate; + end; +// if fxpos < int2 then begin + fxpos:= int2; //restore +// end; + if {(oe_exitoncursor in foptionsedit) and} (indexbefore = curindex) and + {(info.shiftstate = []) and} + ((info.key = key_down) or (info.key = key_up)) then begin + exclude(info.eventstate,es_processed); + end; + end; + end; + end; + if not (es_processed in eventstate) and (fgridintf <> nil) then begin + if ((shiftstate1 = [ss_shift,ss_ctrl]) or (shiftstate1 = [ss_ctrl])) then begin + if key = key_home then begin + seteditpos(makegridcoord(0,0),ss_shift in shiftstate1); + include(eventstate,es_processed); + end + else begin + if key = key_end then begin + seteditpos(makegridcoord(bigint,bigint),ss_shift in shiftstate1); + include(eventstate,es_processed); + end; + end; + end; + if isenterkey(self,info.key) and (shiftstate1 - [ss_shift] = []) and + (foptionsedit * [oe_readonly,oe_linebreak] = [oe_linebreak]) and + ((ss_shift in shiftstate1) xor not (oe_shiftreturn in foptionsedit)) + then begin + insertlinebreak; + include(eventstate,es_processed); + end; + end; + if flines <> nil then begin + if not (es_processed in eventstate) and + issysshortcut(sho_rowdelete,info) then begin + int1:= col; + feditor.begingroup; + try + if (fgridintf <> nil) and + tcustomwidgetgrid1(fgridintf.getcol.grid). + deleterowconfirmation() then begin + + internaldeletetext(mgc(0,row),mgc(0,row+1),true); + col:= int1; + end; + finally + feditor.endgroup; + end; + include(eventstate,es_processed); + end; + if not (es_processed in eventstate) then begin + bo1:= issysshortcut(sho_rowappend,info); + if bo1 or issysshortcut(sho_rowinsert,info) then begin + feditor.begingroup; + try + bo2:= false; + int1:= col; + clearselection; + if bo1 then begin //append + col:= length(flines[row]); + end + else begin + if row = 0 then begin + bo2:= true; + col:= 0; + end + else begin + editpos:= mgc(length(flines[row-1]),row-1); + end; + end; + insertlinebreak; + if not bo1 then begin //insert + int2:= row; + if not bo2 then begin + inc(int2); + end; + editpos:= mgc(int1,int2); + end; + finally + feditor.endgroup; + end; + include(eventstate,es_processed); + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +procedure tcustomtextedit.reloadfile(restorestate: boolean = true); +begin + inc(fnotificationchangelock); + try + loadfromfile(ffilename,restorestate); + finally + dec(fnotificationchangelock); + end; +end; + +procedure tcustomtextedit.loadfromstream(const stream: ttextstream; + restorestate: boolean = false); +var + statsave: texteditstatety; + po1: pmsestring; +begin + checkgrid; + if restorestate then begin + getstate(statsave); + end; + beginupdate; + try + clear(); + ffilerights:= stream.filerights; + flines.loadfromstream(stream); + ffoundeolstyle:= stream.foundeolstyle(); + fhasbom:= false; + if stream.encoding = ce_utf8 then begin + if (flines.count > 0) then begin + po1:= flines.datapo; + if (po1^ <> '') and (card16(po1^[1]) = $feff) then begin + fhasbom:= true; + po1^:= copy(po1^,2,bigint); + end; + end; + end; + fgridintf.getcol.grid.rowcount:= flines.count; + if restorestate then begin + setstate(statsave); + end; + finally + endupdate; + end; + modified:= false; +end; + +procedure tcustomtextedit.loadfromfile(afilename: filenamety; + restorestate: boolean = false); +var + stream: ttextstream; + +begin + checkgrid; + stream:= ttextstream.Create(afilename,fm_read); + try + stream.encoding:= fencoding; + loadfromstream(stream,restorestate); + setfilename(afilename); + finally + stream.Free; + end; +end; + +procedure tcustomtextedit.savetostream(const stream: ttextstream; + const resetmodified: boolean); +const + bom: array[0..2] of byte = ($ef,$bb,$bf); +begin + stream.encoding:= fencoding; + if stream.eolstyle = eol_default then begin + if feolstyle = eol_default then begin + stream.eolstyle:= ffoundeolstyle; + end + else begin + stream.eolstyle:= feolstyle; + end; + end; +// stream.filerights:= ffilerights; + if (fencoding = ce_utf8) and (fhasbom or (teeo_bom in foptions)) and + not(teeo_nobom in foptions) then begin + stream.writebuffer(bom,length(bom)); + end; + flines.savetostream(stream); + if resetmodified then begin + modified:= false; + end; +end; + +procedure tcustomtextedit.savetofile(const afilename: filenamety = ''); + //afilename = '' -> current filename +var + stream: ttextstream; + str1: filenamety; +begin + if afilename = '' then begin + str1:= ffilename; + end + else begin + str1:= afilename; + end; + stream:= ttextstream.createtransaction(str1,ffilerights); + try + savetostream(stream,true); + setfilename(str1); + finally + stream.Free; + end; +end; + +procedure tcustomtextedit.getstate(out state: texteditstatety); +begin + //dummy +end; + +procedure tcustomtextedit.setstate(const state: texteditstatety); +begin + //dummy +end; + +procedure tcustomtextedit.beginupdate; +begin + feditor.beginupdate; + if flines <> nil then begin + flines.beginupdate; + end; +end; + +procedure tcustomtextedit.endupdate; +begin + if flines <> nil then begin + flines.endupdate; + end; + feditor.endupdate; + if not feditor.updating and (tes_xposinvalid in ftextstate) then begin + fxpos:= feditor.caretpos.x; + exclude(ftextstate,tes_xposinvalid); + end; +end; + +procedure tcustomtextedit.clear; +begin + beforechange; + fselectstart:= nullcoord; + fselectend:= nullcoord; + ffilename:= ''; + ffilerights:= defaultfilerights; + if flines <> nil then begin + flines.clear; +// fgridintf.getcol.grid.rowcount:= 0; + end; + ffoundeolstyle:= eol_default; + modified:= false; +end; + +procedure tcustomtextedit.setfilename(value: filenamety); +begin + ffilename:= filepath(value); +{ + removefilechangenotification; + ffilepath:= expanduncfilename(value); + addfilechangenotification; + if (seo_autosyntax in foptions) and (fsyntaxpainter <> nil) then begin + try + syntaxhandle:= fsyntaxpainter.linkdeffile(fileext(value)); + except + on e: exception do begin + writeexceptionmessage(e); + syntaxhandle:= -1; + end; + end; + end; + } +end; +{ +function tcustomtextedit.filename: filenamety; +begin + result:= ffilename; +end; +} +procedure tcustomtextedit.dostatread(const reader: tstatreader); +begin + if (fgridintf = nil) and canstatvalue(feditor.optionsedit1,reader) then begin +// value:= reader.readmsestring(valuevarname,value); + end; + if canstatstate(feditor.optionsedit1,reader) then begin +// readstatstate(reader); + end; + if canstatoptions(feditor.optionsedit1,reader) then begin +// readstatoptions(reader); + end; +end; + +procedure tcustomtextedit.dostatwrite(const writer: tstatwriter); +begin + if (fgridintf = nil) and canstatvalue(feditor.optionsedit1,writer) then begin +// writestatvalue(writer); + end; + if canstatstate(feditor.optionsedit1,writer) then begin +// writestatstate(writer); + end; + if canstatoptions(feditor.optionsedit1,writer) then begin +// writestatoptions(writer); + end; +end; + +function tcustomtextedit.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomtextedit.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tcustomtextedit.statreading; +begin + //dummy +end; + +procedure tcustomtextedit.statread; +begin + //dummy +end; + +procedure tcustomtextedit.inserttext(const apos: gridcoordty; const atext: msestring; + out aendpos: gridcoordty; + selected: boolean = false; + insertbackwards: boolean = false); +var + ar1: msestringarty; + int1: integer; +begin + beforechange; + beginupdate; + feditor.begingroup; + try + clearselection; + ar1:= breaklines(atext); + with fgridintf.getcol do begin + if ar1 = nil then begin + aendpos.col:= 0; + aendpos.row:= apos.row; + end + else begin + aendpos.col:= length(ar1[high(ar1)]); + aendpos.row:= apos.row + high(ar1); + end; + if length(ar1) > 1 then begin + ar1[high(ar1)]:= ar1[high(ar1)] + copy(flines[apos.row],apos.col + 1,bigint); + if apos.col = 0 then begin + grid.insertrow(apos.row,high(ar1)); + end + else begin + grid.insertrow(apos.row+1,high(ar1)); + end; + for int1:= 1 to high(ar1) do begin + flines.items[apos.row+int1]:= ar1[int1]; + end; + flines[apos.row]:= copy(flines[apos.row],1,apos.col) + ar1[0]; + end + else begin + richinsert(atext,prichstringty(flines.getitempo(apos.row))^,apos.col+1); + aendpos.col:= aendpos.col + apos.col; + end; + end; + int1:= fgridintf.getrow; + if (int1 >= 0) and (int1 < flines.count) then begin + feditor.richtext:= flines.richitems[int1]; + end; + if insertbackwards then begin + seteditpos(aendpos,false); + textinserted(aendpos,atext,selected,apos,true); + seteditpos(apos,false); + if selected then begin + fselectstart:= aendpos; + fselectend:= aendpos; + end; + end + else begin + seteditpos(apos,false); + textinserted(apos,atext,selected,aendpos,false); + seteditpos(aendpos,false); + if selected then begin + fselectstart:= apos; + fselectend:= apos; + end; + end; + updateindex(selected); + finally + feditor.endgroup; + endupdate; + end; +end; + +procedure tcustomtextedit.inserttext(const apos: gridcoordty; + const atext: msestring; selected: boolean = false; + insertbackwards: boolean = false); +var + po1: gridcoordty; +begin + inserttext(apos,atext,po1,selected,insertbackwards); +end; + +procedure tcustomtextedit.internaldeletetext(const start, stop: gridcoordty; + const userinput: boolean); +var + po1,po2: gridcoordty; + bo1: boolean; + grid: tcustomwidgetgrid1; +begin + if (start.col <> stop.col) or (start.row <> stop.row) then begin + beforechange; + normalizetextrect(start,stop,po1,po2); + beginupdate; + feditor.begingroup; + application.caret.remove; + grid:= tcustomwidgetgrid1(fgridintf.getcol.grid); + bo1:= og_appendempty in grid.optionsgrid; + try + include(grid.foptionsgrid,og_appendempty); + clearselection; + seteditpos(stop,false); + textdeleted(stop,gettext(po1,po2),false,po1, + isequalgridcoord(po2,stop)); + seteditpos(po1,false); +// feditor.updatecaret; //locked by beginupdate + if po1.row = po2.row then begin + richdelete(prichstringty(flines.getitempo(po1.row))^,po1.col+1, + po2.col-po1.col); + end + else begin + if po1.col > 0 then begin + richdelete(prichstringty(flines.getitempo(po1.row))^,po1.col+1,bigint); + end; + if po2.col > 0 then begin + richdelete(prichstringty(flines.getitempo(po2.row))^,1,po2.col); + end; + if po1.col > 0 then begin + if po2.row < flines.count then begin + prichstringty(flines.getitempo(po1.row))^:= + richconcat(prichstringty(flines.getitempo(po1.row))^, + prichstringty(flines.getitempo(po2.row))^); + end; + inc(po1.row); + if po1.row < flines.count then begin + grid.deleterow(po1.row,po2.row-po1.row+1,userinput); + end; + end + else begin + grid.deleterow(po1.row,po2.row-po1.row,userinput); + end; +{ + if po2.row < flines.count then begin + prichstringty(flines.getitempo(po1.row))^:= + richconcat(prichstringty(flines.getitempo(po1.row))^, + prichstringty(flines.getitempo(po2.row))^); + end; + if (po1.row+1 < flines.count) then begin + grid.deleterow(po1.row+1,po2.row-po1.row); + end + else begin + if po1.col = 0 then begin + grid.deleterow(po1.row,po2.row-po1.row); + end; + end; +} + end; + if grid.updating then begin + gridtovalue(-1); + end; + finally + application.caret.restore; + feditor.endgroup; + if not bo1 then begin + exclude(grid.foptionsgrid,og_appendempty); + end; + endupdate; + end; + end; +end; + +procedure tcustomtextedit.deletetext(const start, stop: gridcoordty); +begin + internaldeletetext(start,stop,false); +end; + +function tcustomtextedit.appendrow(const atext: richstringty): integer; +begin + checkgrid; + result:= fgridintf.getcol.grid.appendrow; + richlines[result]:= atext; +end; + +function tcustomtextedit.appendrow(const atext: msestring): integer; +var + richstring: richstringty; +begin + richstring.text:= atext; + richstring.format:= nil; + result:= appendrow(richstring); +end; + +function intersecttextrect(const a1,a2,b1,b2: gridcoordty; + out i1,i2: gridcoordty): boolean; + //i = a * b, true if intersection exist, values have to be ordered +begin + if b1.row > a1.row then begin + i1:= b1; + end + else begin + i1:= a1; + if (b1.row = a1.row) and (b1.col > a1.col) then begin + i1.col:= b1.col; + end; + end; + if b2.row < a2.row then begin + i2:= b2; + end + else begin + i2:= a2; + if (b2.row = a2.row) and (b2.col < a2.col) then begin + i2.col:= b2.col; + end; + end; + result:= (i1.row < i2.row) or (i1.row = i2.row) and (i1.col < i2.col); +end; + +function compgridcoord(const a,b: gridcoordty): integer; +begin + result:= a.row-b.row; + if result = 0 then begin + result:= a.col - b.col; + end; +end; + +procedure tcustomtextedit.setselection(const start,stop: gridcoordty; + const aseteditpos: boolean = false; + const ashowcell: cellpositionty = cep_nearest); +var + astart,astop: gridcoordty; + + function checkoverlap(const a1,a2,b1,b2: gridcoordty): boolean; + //true if a <> (a ^ b) + var + int1: integer; + i1,i2: gridcoordty; + begin + if not intersecttextrect(a1,a2,b1,b2,i1,i2) then begin + result:= true; + astart:= a1; + astop:= a2; + exit; //no intersection + end; + result:= (a1.row <> i1.row) or (a1.col <> i1.col) or + (a2.row <> i2.row) or (a2.col <> i2.col); + if result then begin + int1:= compgridcoord(a1,i1); + if int1 < 0 then begin + astart:= a1; + astop:= i1; + end + else begin + astart:= i2; + astop:= a2; + end; + end; + end; + +var + col1: twidgetcol; + grid: twidgetgrid; + cell: gridcoordty; + + procedure updatestyle(value: boolean); + var + int1,int2: integer; + po1: prichstringty; + begin + po1:= prichstringty(flines.getitempo(astart.row)); + for int1:= astart.row to astop.row do begin //deselect old + if int1 = astop.row then begin + int2:= astop.col - astart.col; + end + else begin + int2:= length(po1^.text)-astart.col; + end; + if int2 > 0 then begin + updatefontstyle1(po1^.format, + astart.col,int2,fs_selected,value); + cell.row:= int1; + grid.invalidatecell(cell); + end; + astart.col:= 0; + inc(po1); + end; + end; + +var + new1,new2,old1,old2: gridcoordty; + int1: integer; + +begin + if (start.col < 0) or (start.row < 0) or (stop.col < 0) or + (stop.row < 0) then begin + exit; + end; + if aseteditpos then begin + if ashowcell <> cep_none then begin + seteditpos(start,false); + end; + seteditpos(stop,true,ashowcell); + end + else begin + col1:= fgridintf.getcol; + grid:= twidgetgrid(col1.grid); + cell.col:= col1.colindex; + + normalizetextrect(start,stop,new1,new2); + int1:= grid.row; + if int1 > new1.row then begin + if int1 < new2.row then begin + feditor.selstart:= 0; + feditor.sellength:= bigint; + end + else begin + if int1 = new2.row then begin + if new1.row < int1 then begin + feditor.selstart:= 0; + end + else begin + feditor.selstart:= new1.col; + end; + feditor.sellength:= new2.col-feditor.selstart; + end + else begin + feditor.sellength:= 0; + end; + end; + end + else begin + if int1 = new1.row then begin + feditor.selstart:= new1.col; + if new2.row > int1 then begin + feditor.sellength:= bigint; + end + else begin + feditor.sellength:= new2.col - new1.col; + end; + end + else begin + feditor.sellength:= 0; + end; + end; + normalizetextrect(fselectstart,fselectend,old1,old2); + fselectstart:= start; + fselectend:= stop; + int1:= fgridintf.getcol.grid.rowcount; + if old1.row >= int1 then begin + old1.row:= int1 - 1; + old1.col:= 0; + old2:= old1; + end + else begin + if old2.row >= int1 then begin + old2.row:= int1-1; + old2.col:= bigint; + end; + end; + if tes_selectinvalid in ftextstate then begin + astart:= new1; + astop:= new2; + updatestyle(true); + exclude(ftextstate,tes_selectinvalid); + end + else begin + if checkoverlap(old1,old2,new1,new2) then begin + updatestyle(false); + end; + if checkoverlap(new1,new2,old1,old2) then begin + updatestyle(true); + end; + end; + end; +end; + +procedure tcustomtextedit.selectall; +begin + setselection(makegridcoord(0,0), + makegridcoord(bigint,fgridintf.grid.rowhigh),true); +end; + +procedure tcustomtextedit.setfontstyle(const start,stop: gridcoordty; + const astyle: fontstylety; const aset: boolean; + const afontcolor: colorty = cl_default; + const acolorbackground: colorty = cl_default); +var + a,b: gridcoordty; + int1,int2: integer; + po1: prichstringty; + bo1: boolean; +begin + normalizetextrect(start,stop,a,b); + int2:= bigint; + for int1:= a.row to b.row do begin + po1:= flines.richitemspo[int1]; + if int1 = b.row then begin + int2:= b.col - a.col; + end; + bo1:= (astyle <> fs_force) and + updatefontstyle1(po1^.format,a.col,int2,astyle,aset); + if afontcolor <> cl_default then begin + bo1:= setfontcolor1(po1^.format,a.col,int2,afontcolor) or bo1; + end; + if acolorbackground <> cl_default then begin + bo1:= setcolorbackground1(po1^.format,a.col,int2,acolorbackground) or bo1; + end; + if bo1 then begin + with fgridintf.getcol do begin + invalidatecell(int1); + if int1 = grid.row then begin + tinplaceedit1(feditor).format:= po1^.format; + end; + end; + end; + a.col:= 0; + end; +end; + +procedure tcustomtextedit.updateindex(select: boolean); +var + selectstart1,selectend1: gridcoordty; + +begin + selectstart1:= fselectstart; + selectend1:= fselectend; + if select then begin + selectend1.col:= feditor.curindex; + selectend1.row:= tcustomwidgetgrid1(fgridintf.getcol.grid).row + end + else begin + selectstart1.col:= feditor.curindex; + selectstart1.row:= tcustomwidgetgrid1(fgridintf.getcol.grid).row; + selectend1:= selectstart1; + end; + setselection(selectstart1,selectend1); +end; + +procedure tcustomtextedit.insertlinebreak; +begin + feditor.begingroup; + try + deleteselection; + inserttext(fselectstart,lineend); + finally + feditor.endgroup; + end; +end; + +procedure tcustomtextedit.editnotification(var info: editnotificationinfoty); +var + int1: integer; + str1: msestring; + po1,po2: gridcoordty; + grid: tcustomgrid; + +begin + if canevent(tmethod(foneditnotification)) then begin + foneditnotification(self,info); + end; + if fgridintf <> nil then begin + grid:= fgridintf.getcol.grid; + with info do begin + case action of + ea_clearselection: begin + internalclearselection; + end; + ea_textedited: begin + if not (csdesigning in componentstate) then begin + if fupdating = 0 then begin + inc(fupdating); + try + fgridintf.edited(); + int1:= fgridintf.getrow; + fgridintf.setdata(int1,feditor.richtext,true); + gridvaluechanged(int1); + finally + dec(fupdating); + end; + inherited; + end; + end; + end; + ea_indexmoved: begin + fxpos:= feditor.caretpos.x; + updateindex(eas_shift in state); + end; + ea_textsizechanged: begin + if not (tes_cellentering in ftextstate) then begin + with fgridintf.getcol do begin + if info.sizebefore.cy <> info.newsize.cy then begin + autocellheightchanged(grid.row); + end; + if info.sizebefore.cx <> info.newsize.cx then begin + autocellwidthchanged(grid.row); + end; + end; + end; + end; + ea_delchar: begin + if dir <> gd_left then begin //no backspace + if (fselectstart.col = fselectend.col) and (fselectstart.row = fselectend.row) then begin + if (feditor.curindex = length(feditor.text)) then begin + if fselectstart.row < grid.rowcount - 1 then begin + fselectstart.row:= fselectend.row+1; + fselectstart.col:= 0; + deleteselection; //remove linebreak + action:= ea_none; + end; + end; + end + else begin + deleteselection; + action:= ea_none; + end; + end; + end; + ea_selectall: begin + selectall; + action:= ea_none; + end; + ea_deleteselection: begin + deleteselection; + action:= ea_none; + end; + ea_copyselection: begin +// copyselection; + if hasselection then begin + msewidgets.copytoclipboard(selectedtext,bufferkind); + end; + action:= ea_none; + end; + ea_pasteselection: begin + if msewidgets.pastefromclipboard(str1,bufferkind) then begin + beginupdate; + feditor.begingroup; + try + deleteselection; + po2:= editpos; + inserttext(po2,str1,po1,false); + finally + feditor.endgroup; + endupdate; + end; + end; + action:= ea_none; + end; + ea_exit: begin + action:= ea_none; + if dir = gd_left then begin + if editpos.row > 0 then begin + int1:= length(flines[editpos.row-1]); + if (eas_delete in state) then begin + if hasselection then begin + deleteselection + end + else begin + deletetext(makegridcoord(0,editpos.row),makegridcoord(int1,editpos.row-1)); + end; + end + else begin + seteditpos(makegridcoord(int1,editpos.row - 1),state = [eas_shift]); + end; + end + else begin + if not (eas_shift in state) then begin + internalclearselection; + end; + end; + end + else begin + if dir = gd_right then begin + if editpos.row < linecount - 1 then begin + seteditpos(makegridcoord(0,editpos.row + 1),state = [eas_shift]); + end + else begin + if not (eas_shift in state) then begin + internalclearselection; + end; + end; + end; + end; + end; + ea_caretupdating: begin + if focused and not grid.updating then begin + fgridintf.showcaretrect(info.caretrect,fframe); + end; + end; + end; + end; + end; + inherited; +end; + +procedure tcustomtextedit.mousepostotextpos1( const row: integer; + const mousepos: pointty; + var textpos: gridcoordty; var result: boolean); +var + textinfo: drawtextinfoty; + col1: twidgetcol; +begin + col1:= fgridintf.getcol; + textinfo.text:= flines.richitems[row]; + textinfo.font:= col1.rowfont(row); + textinfo.flags:= feditor.textflags; + if row = col1.grid.row then begin + textinfo.dest:= innerclientrect; + end + else begin + textinfo.dest:= col1.grid.cellrect(mgc(col1.index,row),cil_inner,false,true); + end; + textinfo.tabulators:= ftabulators; + result:= postotextindex(getcanvas,textinfo,mousepos,textpos.col); + textpos.row:= row; +end; + +function tcustomtextedit.mousepostotextpos(const mousepos: pointty; + out textpos: gridcoordty; widgetorg: boolean = false): boolean; + //false if out of text, textpos clamped to textrange +var + grid: tcustomwidgetgrid1; + arow: integer; + {po1,}pt2: pointty; +// int1: integer; +begin + result:= true; + grid:= tcustomwidgetgrid1(fgridintf.getcol.grid); + pt2:= mousepos; + if widgetorg then begin + pt2.y:= pt2.y + grid.rowpos(grid.row); //grid client data origin + end + else begin + subpoint1(pt2,fgridintf.getcol.cellorigin); + end; + arow:= grid.rowatpos(pt2.y); + { + if widgetorg then begin + int1:= fgridintf.getrow * grid.ystep; + end + else begin + int1:= 0; + end; + int1:= (mousepos.y + int1); + arow:= int1 div grid.ystep; + int1:= int1 - arow * grid.ystep; + } + if arow < 0 then begin + result:= false; + arow:= 0; + end + else begin + if arow >= grid.frowcount then begin + result:= false; + arow:= grid.frowcount-1; + end; + end; + pt2.y:= pt2.y - grid.rowpos(arow); + mousepostotextpos1(arow,pt2,textpos,result); + { + if widgetorg then begin + mousepostotextpos1(arow,makepoint(mousepos.x,int1),textpos,result); + end + else begin + po1:= fgridintf.getcol.cellorigin; + mousepostotextpos1(arow,makepoint(mousepos.x - po1.x, + mousepos.y - arow*grid.ystep - po1.y),textpos,result); + end; + } +end; + +function tcustomtextedit.textpostomousepos(const textpos: gridcoordty; + const screenorg: boolean = false): pointty; +var + po1,po2: pointty; + textinfo: drawtextinfoty; +begin + textinfo.text:= flines.richitems[textpos.row]; + textinfo.font:= fgridintf.getcol.rowfont(textpos.row); + textinfo.flags:= feditor.textflags; + textinfo.dest:= innerclientrect; + textinfo.tabulators:= ftabulators; + po1:= textindextopos(getcanvas,textinfo,textpos.col); + po2:= fgridintf.getcol.cellorigin; + result.y:= po1.y + {po2.y +} + tcustomwidgetgrid1(fgridintf.getcol.grid).cellrect(mgc(0,textpos.row)).y; +// textpos.row * tcustomwidgetgrid1(fgridintf.getcol.grid).ystep; + result.x:= po1.x + po2.x; + if screenorg then begin + translateclientpoint1(result,fgridintf.getcol.grid,nil); + end; +end; + +function tcustomtextedit.textpostomouserect(const textpos: gridcoordty; + const screenorg: boolean = false): rectty; + //y:= top of character cell cx = 0 cy = linespacing +begin + result.pos:= textpostomousepos(textpos,screenorg); + result.cx:= 0; + result.cy:= font.lineheight; + dec(result.y,font.ascent); +end; + +procedure tcustomtextedit.dotextmouseevent(var info: textmouseeventinfoty); +begin + if canevent(tmethod(fontextmouseevent)) then begin + fontextmouseevent(self,info); + end; +end; + +function tcustomtextedit.textclipped(const arow: integer; + out acellrect: rectty): boolean; +var + rect2: rectty; + canvas1: tcanvas; + cell1: gridcoordty; + grid1: tcustomgrid; +begin + checkgrid; + with twidgetcol1(fgridintf.getcol) do begin + grid1:= grid; + cell1.row:= arow; + cell1.col:= colindex; + result:= grid1.isdatacell(cell1); + if result then begin + acellrect:= grid1.clippedcellrect(cell1,cil_inner); + canvas1:= getcanvas; + rect2:= textrect(canvas1,richstringty(getdatapo(arow)^), + acellrect,feditor.textflags,font); + result:= not rectinrect(rect2,acellrect); + end + else begin + acellrect:= nullrect; + end; + end; +end; + +function tcustomtextedit.textclipped(const arow: integer): boolean; +var + rect1: rectty; +begin + result:= textclipped(arow,rect1); +end; + +function tcustomtextedit.getiassistiveclient(): iassistiveclient; +begin + result:= iassistiveclientgridwidget(self); +end; + +function tcustomtextedit.getassistivecolumncaption(): msestring; +begin + result:= ''; + if fgridintf <> nil then begin + result:= fgridintf.getcol.defaultcaption(); + end; +end; + +procedure tcustomtextedit.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +var + textinfo: textmouseeventinfoty; + bo1: boolean; + po1: pointty; + int1,int2: integer; + rect1: rectty; + hintinfo: hintinfoty; +begin + if ownedcol then begin + with info do begin + textinfo.eventkind:= eventkind; + if eventkind = cek_enter then begin + tinplaceedit1(feditor).frow:= newcell.row; + end; + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; + case eventkind of + cek_enter: begin + bo1:= tes_cellentering in ftextstate; + include(ftextstate,tes_cellentering); + try + with fgridintf.getcol.grid do begin + if fselectstart.row >= rowcount then begin + fselectstart.row:= rowcount - 1; + fselectstart.col:= length(flines[fselectstart.row]); + //check for removed empty row + end; + end; + if cellbefore.row <> newcell.row then begin + with tinplaceedit1(feditor) do begin + rect1:= textrect; + if cellbefore.row < newcell.row then begin + int1:= mousepostotextindex(makepoint(fxpos,rect1.x)); + end + else begin + int1:= mousepostotextindex(makepoint(fxpos,rect1.y+rect1.cy-1)); + end; + int2:= fxpos; + moveindex(int1, + selectaction in [fca_focusinshift,fca_focusinrepeater],true{false}); + exclude(self.ftextstate,tes_xposinvalid); + fxpos:= int2; //restore + end; + end; + if selectaction = fca_focusinrepeater then begin + fgridintf.getcol.grid.setcellclientclick(self); + end; + dosetupeditor(); + finally + if not bo1 then begin + exclude(ftextstate,tes_cellentering); + end; + end; + end; + cek_mousemove,cek_mousepark,cek_buttonpress,cek_buttonrelease: begin + if cell.row >= 0 then begin + mousepostotextpos1(cell.row,mouseeventinfopo^.pos,textinfo.pos,bo1); + if (eventkind = cek_mousemove) and + (cell.row <> fgridintf.getcol.grid.row) and + (info.mouseeventinfopo^.shiftstate = [ss_left]) and + grid.cellclicked then begin + fxpos:= textpostomousepos(textinfo.pos).x; + + with fgridintf.getcol.grid do begin + focuscell(cell,fca_focusinshift); + setcellclientclick(self); +// setclientclick; + exit; + end; + end; + if not bo1 then begin + textinfo.pos:= invalidcell; + end; + end + else begin + textinfo.pos:= invalidcell; + end; + if not(eventkind in [cek_mousemove]) or (textinfo.pos.col <> fmousetextpos.col) or + (textinfo.pos.row <> fmousetextpos.row) then begin + fmousetextpos:= textinfo.pos; + po1:= subpoint(gridmousepos,mouseeventinfopo^.pos); + mouseeventinfopo^.pos:= gridmousepos; + textinfo.mouseeventinfopo:= mouseeventinfopo; + try + dotextmouseevent(textinfo); + finally + subpoint1(mouseeventinfopo^.pos,po1); + end; + end; + end; + cek_firstmousepark: begin + if (oe_hintclippedtext in foptionsedit) and application.active and + textclipped(info.cell.row) and + ((info.grid.row <> info.cell.row) or + (info.grid.col <> info.cell.col)) and + {$warnings off} + twidget1(info.grid).getshowhint then begin + {$warnings on} + application.inithintinfo(hintinfo,info.grid); + {$warnings off} + hintinfo.caption:= + richstringty( + twidgetcol1(fgridintf.getcol).getdatapo(info.cell.row)^).text; + {$warnings on} + application.showhint(info.grid,hintinfo); + end; + end; + cek_mouseleave: begin + fmousetextpos:= invalidcell; + textinfo.pos:= invalidcell; + textinfo.mouseeventinfopo:= mouseeventinfopo; + dotextmouseevent(textinfo); + end; + end; + end; + end; + inherited; +end; + +procedure tcustomtextedit.internalclearselection; +begin + setselection(editpos,editpos); +end; + +function tcustomtextedit.getassistivetext(): msestring; +begin + result:= feditor.text; +end; + +function tcustomtextedit.getassistiveflags: assistiveflagsty; +begin + result:= inherited getassistiveflags; + if fgridintf <> nil then begin + include(result,asf_gridwidget); + end; +end; + +function tcustomtextedit.getassistivecelltext(const arow: int32): msestring; +begin + if flines <> nil then begin + result:= flines[arow]; + end + else begin + result:= ''; + end; +end; + +procedure tcustomtextedit.clearselection; +begin + seteditpos(editpos,false); +end; + +procedure tcustomtextedit.setedpos(const Value: gridcoordty; + const select: boolean; const donotify: boolean; + const ashowcell: cellpositionty); +var + po1: gridcoordty; +begin + tinplaceedit1(feditor).frow:= value.row; + po1.row:= value.row; + po1.col:= fgridintf.getcol.colindex; + if select then begin + fgridintf.getcol.grid.focuscell(po1,fca_focusinshift,scm_cell,ashowcell); + end + else begin + fgridintf.getcol.grid.focuscell(po1,fca_focusin,scm_cell,ashowcell); + end; + feditor.moveindex(value.col,select,donotify); + if donotify then begin + if feditor.updating then begin + include(ftextstate,tes_xposinvalid);; + end + else begin + fxpos:= feditor.caretpos.x; + end; + end; + updateindex(select); +end; + +procedure tcustomtextedit.seteditpos(const Value: gridcoordty; + const select: boolean = false; + const ashowcell: cellpositionty = cep_nearest); +begin + setedpos(value,select,true,ashowcell); +end; + +procedure tcustomtextedit.seteditpos1(const Value: gridcoordty); +begin + seteditpos(value,false,cep_nearest); +end; + +function tcustomtextedit.geteditpos: gridcoordty; +begin + result:= makegridcoord(feditor.curindex,fgridintf.getrow); +end; + +function tcustomtextedit.getrow: integer; +begin + result:= fgridintf.getrow; +end; + +procedure tcustomtextedit.setrow(const avalue: integer); +begin + editpos:= makegridcoord(col,avalue); +end; + +function tcustomtextedit.getcol: integer; +begin + result:= feditor.curindex; +end; + +procedure tcustomtextedit.setcol(const avalue: integer); +begin + editpos:= makegridcoord(avalue,row); +end; + +procedure tcustomtextedit.getselectedrows(out start,stop: integer); +var + int1: integer; +begin + int1:= fselectend.row - fselectstart.row; + if int1 > 0 then begin + start:= fselectstart.row; + stop:= fselectend.row; + if fselectend.col = 0 then begin + dec(stop); + end; + end + else begin + if int1 <> 0 then begin + start:= fselectend.row; + stop:= fselectstart.row; + if fselectstart.col = 0 then begin + dec(stop); + end; + end + else begin + start:= editpos.row; + stop:= start; + end; + end; +end; + +procedure tcustomtextedit.deleteselection; +begin + if hasselection then begin + deletetext(fselectstart,fselectend); + end; +end; + +procedure tcustomtextedit.copyselection; +begin + if hasselection then begin + msewidgets.copytoclipboard(selectedtext); + end; +end; + +procedure tcustomtextedit.cutselection; +begin + copyselection; + deleteselection; +end; + +function tcustomtextedit.canpaste: boolean; +begin + result:= canpastefromclipboard; +end; + +procedure tcustomtextedit.paste; +var + str1: msestring; +begin + if msewidgets.pastefromclipboard(str1) then begin + feditor.begingroup; + try + deleteselection; + inserttext(editpos,str1,true); + finally + feditor.endgroup; + end; + end; +end; + +function tcustomtextedit.gettext(const start,stop: gridcoordty): msestring; +var + po1,po2: gridcoordty; + int1: integer; +begin + normalizetextrect(start,stop,po1,po2); + if po1.row = po2.row then begin + result:= copy(flines[po1.row],po1.col+1,po2.col-po1.col); + end + else begin + result:= copy(flines[po1.row],po1.col+1,bigint); + for int1:= po1.row + 1 to po2.row - 1 do begin + if flines.noparagraphs[int1] then begin + result:= result + flines[int1]; + end + else begin + result:= result + lineend + flines[int1]; + end; + end; + if po2.row < flines.count then begin + if not flines.noparagraphs[po2.row] then begin + result:= result + lineend; //paragraph + end; + result:= result + copy(flines[po2.row],1,po2.col); + end; + end; +end; + +function tcustomtextedit.getrichtext(const start, + stop: gridcoordty): richstringty; +var + po1,po2: gridcoordty; + int1: integer; +begin + normalizetextrect(start,stop,po1,po2); + if po1.row = po2.row then begin + result:= richcopy(flines.richitems[po1.row],po1.col+1,po2.col-po1.col); + end + else begin + result:= richcopy(flines.richitems[po1.row],po1.col+1,bigint); + for int1:= po1.row + 1 to po2.row - 1 do begin + if flines.noparagraphs[int1] then begin + result:= richconcat(result,flines.richitems[int1]); + end + else begin + result:= richconcat(result,richlineend); + result:= richconcat(result,flines.richitems[int1]); + end; + end; + if po2.row < flines.count then begin + if not flines.noparagraphs[po2.row] then begin + result:= richconcat(result,richlineend); //paragraph + end; + result:= richconcat(result,richcopy(flines.richitems[po2.row],1,po2.col)); + end; + end; +end; + +function tcustomtextedit.gettext: msestring; +begin + result:= flines.gettext; +end; + +procedure tcustomtextedit.settext(const atext: msestring); +begin + flines.settext(atext); +end; + +function tcustomtextedit.hasselection: boolean; +begin + result:= (fselectstart.row <> fselectend.row) or + (fselectstart.col <> fselectend.col); +end; + +function tcustomtextedit.selectedtext: msestring; +begin + if hasselection then begin + result:= gettext(fselectstart,fselectend); + end + else begin + result:= ''; + end; +end; + +function tcustomtextedit.selectedrichtext: richstringty; +begin + if hasselection then begin + result:= getrichtext(fselectstart,fselectend); + end + else begin + result:= emptyrichstring; + end; +end; + +function tcustomtextedit.find(const atext: msestring; options: searchoptionsty; + var textpos: gridcoordty; const endpos: gridcoordty; + selectfound: boolean = false; + const ashowcell: cellpositionty = cep_nearest): boolean; +var + int1,int2: integer; + endrow: integer; + + + function checkresult: boolean; + begin + if (int1 > 0) and ((int2 < endrow) or + (int2 = endrow) and (int1 - 1 + length(atext) <= endpos.col)) then begin + textpos.row:= int2; + textpos.col:= int1-1; + result:= true; + if selectfound then begin + setselection(textpos,makegridcoord(textpos.col + length(atext),textpos.row), + true,ashowcell); + end; + end + else begin + result:= false; + end; + end; + + function checkresultback: boolean; + begin + if (int1 > 0) and ((int2 > endpos.row) or + (int2 = textpos.row) and (int1 <= textpos.col)) then begin + textpos.row:= int2; + textpos.col:= int1-length(atext); + result:= true; + if selectfound then begin + setselection(makegridcoord(textpos.col + length(atext),textpos.row),textpos, + true,ashowcell); + end; + end + else begin + result:= false; + end; + end; + +var + po1: prichstringty; + pos1: gridcoordty; + str1,str2: msestring; + isback: boolean; +begin + result:= false; + if flines.count > 0 then begin + if so_caseinsensitive in options then begin + str1:= mselowercase(atext); + str2:= mseuppercase(atext); + end + else begin + str1:= atext; + str2:= ''; + end; + isback:= so_backward in options; + pos1:= textpos; + endrow:= endpos.row; + if endrow >= flines.count then begin + endrow:= flines.count - 1; + end; + if isback and (endrow < 0) then begin + endrow:= 0; + end; + po1:= flines.datapo; + if pos1.row < 0 then begin + if isback then begin + exit; + end; + pos1.row:= 0; + pos1.col:= 1; + end + else begin + if isback then begin + if pos1.row >= flines.count then begin + pos1.row:= flines.count-1; + end; + end + else begin + if pos1.row <= endrow then begin + inc(pos1.col); + if pos1.col < 1 then begin + pos1.col:= 1; + end; + end; + end; + end; + inc(po1,pos1.row); + int1:= msestringsearch(str1,po1^.text,pos1.col,options,str2); + int2:= pos1.row; + if isback then begin + while true do begin + if checkresultback then begin + result:= true; + exit; + end; + dec(int2); + if int2 < endrow then begin + exit; + end; + dec(po1); + int1:= msestringsearch(str1,po1^.text,bigint,options,str2); + end; + end + else begin + while true do begin + if checkresult then begin + result:= true; + exit; + end; + inc(int2); + if int2 > endrow then begin + exit; + end; + inc(po1); + int1:= msestringsearch(str1,po1^.text,1,options,str2); + end; + end; + end; +end; + +function tcustomtextedit.getgridvalue(const index: integer): msestring; +begin + result:= flines[index]; +end; + +procedure tcustomtextedit.setgridvalue(const index: integer; + const Value: msestring); +begin + flines[index]:= value; +end; + +function tcustomtextedit.linecount: integer; +begin + if flines = nil then begin + result:= 0; + end + else begin + result:= flines.count; + end; +end; + +function tcustomtextedit.getgridvalues: msestringarty; +begin + result:= flines.asmsestringarray; +end; + +procedure tcustomtextedit.setgridvalues(const Value: msestringarty); +begin + flines.asmsestringarray:= value; +end; + +function tcustomtextedit.getrichlines(const index: integer): richstringty; +begin + result:= flines.richitems[index]; +end; + +procedure tcustomtextedit.setrichlines(const index: integer; + const Value: richstringty); +begin + flines.richitems[index]:= value; +end; + +function tcustomtextedit.getrichformats(const index: integer): formatinfoarty; +begin + result:= flines.formats[index]; +end; + +procedure tcustomtextedit.setrichformats(const index: integer; + const avalue: formatinfoarty); +begin + flines.formats[index]:= avalue; +end; + +procedure tcustomtextedit.setmodified(const avalue: boolean); +begin + if fmodified <> avalue then begin + fmodified := avalue; + if canevent(tmethod(fonmodifiedchanged)) then begin + fonmodifiedchanged(self,avalue); + end; + end; +end; + +procedure tcustomtextedit.setdatalist(const avalue: tgridrichstringdatalist); +begin + flines.assign(avalue); +end; + +procedure tcustomtextedit.textinserted (const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); +begin + //dummy +end; + +procedure tcustomtextedit.textdeleted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); +begin + //dummy +end; + +procedure tcustomtextedit.dosetupeditor(); +begin + if canevent(tmethod(fonsetupeditor)) then begin + fonsetupeditor(self); + end; +end; + +procedure tcustomtextedit.setupeditor; +var + rect1: rectty; +begin + if not (csloading in componentstate) then begin + with feditor do begin + //feditor text already set + rect1:= innerclientrect; + if fframe = nil then begin + deflaterect1(rect1,texteditminimalframe); + end; + setup(text,curindex,false,rect1,clientrect,richtext.format,ftabulators,font); + end; + dosetupeditor(); + end; +end; + +procedure tcustomtextedit.checkgrid; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; +end; + +procedure tcustomtextedit.colchanged; +begin + invalidate; + if fgridintf <> nil then begin + fgridintf.getcol.invalidate; + end; +end; + +procedure tcustomtextedit.setmarginlinecolor(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if fmarginlinecolor <> avalue then begin + fmarginlinecolor := avalue; + colchanged; + end; +end; + +procedure tcustomtextedit.setmarginlinepos(const avalue: integer); +begin + if fmarginlinepos <> avalue then begin + fmarginlinepos := avalue; + colchanged; + end; +end; + +procedure tcustomtextedit.createtabulators; +begin + ftabulators:= ttabulators.create; + ftabulators.onchange:= {$ifdef FPC}@{$endif}tabulatorschanged; + tabulatorschanged(nil,-1); +end; + +function tcustomtextedit.gettabulators: ttabulators; +begin + getoptionalobject(ftabulators,{$ifdef FPC}@{$endif}createtabulators); + result:= ftabulators; +end; + +procedure tcustomtextedit.settabulators(const Value: ttabulators); +begin + setoptionalobject(value,ftabulators,{$ifdef FPC}@{$endif}createtabulators); +end; + +procedure tcustomtextedit.tabulatorschanged(const sender: tarrayprop; + const index: integer); +begin + if not (csloading in componentstate) then begin + colchanged; + end; +end; + +procedure tcustomtextedit.inserttext(const atext: msestring; + selected: boolean = false); +begin + inserttext(editpos,atext,selected); +end; + +procedure tcustomtextedit.beforecelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; + +procedure tcustomtextedit.aftercelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; +{ +procedure tcustomtextedit.setreadonly(const avalue: boolean); +begin + if avalue then begin + optionsedit:= optionsedit + [oe_readonly]; + end + else begin + optionsedit:= optionsedit - [oe_readonly]; + end; +end; +} +function tcustomtextedit.getinnerframe: framety; +begin + result:= minimaltextframe; +end; + +function tcustomtextedit.getgridintf: iwidgetgrid; +begin + result:= fgridintf; +end; + +procedure tcustomtextedit.datalistdestroyed; +begin + flines:= nil; +end; + +function tcustomtextedit.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tcustomtextedit.setvaluedata(const source); +begin + text:= msestring(source); +end; + +procedure tcustomtextedit.setparentgridwidget(const intf: igridwidget); +begin + //dummy +end; + +procedure tcustomtextedit.childdataentered(const sender: igridwidget); +begin + //dummy +end; + +procedure tcustomtextedit.childfocused(const sender: igridwidget); +begin + //dummy +end; + +procedure tcustomtextedit.getvaluedata(out dest); +begin + msestring(dest):= text; +end; + +procedure tcustomtextedit.setoptions(const avalue: texteditoptionsty); +begin + if foptions <> avalue then begin + foptions:= texteditoptionsty(setsinglebit(card32(avalue),card32(foptions), + card32([teeo_bom,teeo_nobom]))); + end; +end; + +{ tundotextedit } + +constructor tundotextedit.create(aowner: tcomponent); +begin + feditor:= tundoinplaceedit.create(self,iedit(self),iundo(self),true); + inherited; +end; + +function tundotextedit.canredo: boolean; +begin + result:= tundoinplaceedit(feditor).undolist.canredo; +end; + +function tundotextedit.canundo: boolean; +begin + result:= tundoinplaceedit(feditor).undolist.canundo; +end; + +function tundotextedit.getmaxundocount: integer; +begin + result:= tundoinplaceedit(feditor).undolist.maxcount; +end; + +procedure tundotextedit.setmaxundocount(const Value: integer); +begin + tundoinplaceedit(feditor).undolist.maxcount:= value; +end; + +function tundotextedit.getmaxundosize: integer; +begin + result:= tundoinplaceedit(feditor).undolist.maxsize; +end; + +procedure tundotextedit.setmaxundosize(const Value: integer); +begin + tundoinplaceedit(feditor).undolist.maxsize:= value; +end; + +procedure tundotextedit.undo; +begin + tundoinplaceedit(feditor).undolist.undo; +end; + +procedure tundotextedit.redo; +begin + tundoinplaceedit(feditor).undolist.redo; +end; + +procedure tundotextedit.textinserted(const apos: gridcoordty; const atext: msestring; + const selected: boolean; const endpos: gridcoordty; const backwards: boolean); +begin + tundoinplaceedit(feditor).undolist.inserttext(apos,endpos,atext,selected,backwards); +end; + +procedure tundotextedit.textdeleted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); +begin + tundoinplaceedit(feditor).undolist.deletetext(apos,endpos,atext,selected,backwards) +end; + +procedure tundotextedit.getselectstart(var selectstartpos: gridcoordty); +begin + selectstartpos:= fselectstart; +end; + +procedure tundotextedit.setselectstart(const selectstartpos: gridcoordty); +begin + internalclearselection; + include(ftextstate,tes_selectinvalid); + fselectstart:= selectstartpos; +end; + +procedure tundotextedit.lowercase; +var + mstr1: msestring; +begin + if hasselection then begin + tundoinplaceedit(feditor).begingroup; + try + mstr1:= selectedtext; + deleteselection; + inserttext(mselowercase(mstr1),true); + finally + tundoinplaceedit(feditor).endgroup; + end; + end; +end; + +procedure tundotextedit.uppercase; +var + mstr1: msestring; +begin + if hasselection then begin + tundoinplaceedit(feditor).begingroup; + try + mstr1:= selectedtext; + deleteselection; + inserttext(mseuppercase(mstr1),true); + finally + tundoinplaceedit(feditor).endgroup; + end; + end; +end; + +procedure tundotextedit.tabtospace; +var + mstr1: msestring; +begin + if hasselection then begin + tundoinplaceedit(feditor).begingroup; + try + mstr1:= selectedtext; + replacechar1(mstr1,msechar(c_tab),msechar(' ')); + deleteselection; + inserttext(mstr1,true); + finally + tundoinplaceedit(feditor).endgroup; + end; + end; +end; + +procedure tundotextedit.clear; +begin + tundoinplaceedit(feditor).undolist.clear; + inherited; +end; + +initialization + registergriddatalistclass(tgridrichstringdatalist.classname, + {$ifdef FPC}@{$endif}createtgridrichstringdatalist); +end. diff --git a/mseide-msegui/lib/common/editwidgets/msevaluenodes.pas b/mseide-msegui/lib/common/editwidgets/msevaluenodes.pas new file mode 100644 index 0000000..a688b9a --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msevaluenodes.pas @@ -0,0 +1,777 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msevaluenodes; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseglob,msestrings,msedatalist,msedatanodes,msebitmap,mselistbrowser, + msetypes,msevaluenodesglob,mseinterfaces,msestat; + +const + valuenodetypename = 't'; + valuenodeindexname = 'i'; + valuenodevaluename = 'v'; + +type + irecordfield = interface(inullinterface) [miid_irecordfield] + function getfieldtext(const afieldindex: integer): msestring; + procedure setfieldtext(const afieldindex: integer; var avalue: msestring); + end; + + getvaluemethodty = procedure(out dest) of object; + + irecordvaluefield = interface(irecordfield) [miid_irecordvaluefield] + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + //-1 -> all + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); + end; + + trecordfielditem = class(ttreelistitem) + private + ffieldindex: integer; + fintf: irecordfield; + protected + public + constructor create(const intf: irecordfield; const afieldindex: integer; + const acaption: msestring; + const fixedcaption: boolean = false; + const aimagenr: integer = 0; + const aimagelist: timagelist = nil); reintroduce; + function getvaluetext: msestring; override; + procedure setvaluetext(var avalue: msestring); override; + property fieldindex: integer read ffieldindex; +// property valuetext: msestring read getvaluetext write setvaluetext; + end; + + trecordfieldvalueitem = class(trecordfielditem,irecordvaluefield) + protected + function getfieldtext(const afieldindex: integer): msestring; + procedure setfieldtext(const afieldindex: integer; var avalue: msestring); + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); + public + constructor create(const intf: irecordvaluefield; const afieldindex: integer; + const acaption: msestring; + const fixedcaption: boolean = false; + const aimagenr: integer = 0; + const aimagelist: timagelist = nil); + end; + + fieldinfoty = record + datatype: listdatatypety; + data: pointer; + end; + +// +// hint: irecordvaluefield can be slow +// + trecordlistedititem = class(tlistedititem,irecordvaluefield) + private + protected + //irecordvaluefield + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + virtual; + function getfieldtext(const fieldindex: integer): msestring; virtual; + procedure setfieldtext(const fieldindex: integer; + var avalue: msestring); virtual; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); virtual; + public + end; + + trecordtreelistedititem = class(ttreelistedititem,irecordvaluefield) + //does not statsave subitems + protected + //irecordvaluefield + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + virtual; + function getfieldtext(const fieldindex: integer): msestring; virtual; + procedure setfieldtext(const fieldindex: integer; + var avalue: msestring); virtual; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); virtual; + public + constructor create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); override; + end; + +{ + trecordtreelistedititem = class(tlistedititem,irecordvaluefield) + private + protected + procedure initvalueinfo(out ainfo: recvaluety); + procedure initvalueinfo(const aindex: int32; var avalue: int32; + out ainfo: recvaluety); + procedure initvalueinfo(const aindex: int32; var avalue: longbool; + out ainfo: recvaluety); + procedure initvalueinfo(const aindex: int32; var avalue: realty; + out ainfo: recvaluety); + procedure initvalueinfo(const aindex: int32; var avalue: tdatetime; + out ainfo: recvaluety); + procedure initvalueinfo(const aindex: int32; var avalue: msestring; + out ainfo: recvaluety); + //irecordvaluefield + procedure getvalueinfo(out avalues: recvaluearty); virtual; + function getfieldtext(const fieldindex: integer): msestring; virtual; + procedure setfieldtext(const fieldindex: integer; + var avalue: msestring); virtual; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); virtual; + public + end; +} + trecordvaluelistedititem = class(trecordlistedititem) + private + protected + fvalueindex: int32; + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + override; + function getvaluetype: listdatatypety; virtual; + public + constructor create(const avalueindex: int32 = -1; + const aowner: tcustomitemlist = nil); virtual; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + property valueindex: int32 read fvalueindex write fvalueindex; + //-1 -> any + end; + recordvaluelistedititemty = class of trecordvaluelistedititem; + + tintegervaluelistedititem = class(trecordvaluelistedititem) + private + fvalue: int32; + procedure setvalue(const avalue: int32); + protected + function getvaluetype: listdatatypety; override; + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + override; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); override; + public + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + property value: int32 read fvalue write setvalue; + end; + + tbooleanvaluelistedititem = class(tintegervaluelistedititem) + private + procedure setvalue(const avalue: boolean); reintroduce; + function getvalue: boolean; + protected + public + property value: boolean read getvalue write setvalue; + end; + + trealvaluelistedititem = class(trecordvaluelistedititem) + private + fvalue: realty; + procedure setvalue(const avalue: realty); + protected + function getvaluetype: listdatatypety; override; + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + override; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); override; + public + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + property value: realty read fvalue write setvalue; + end; + + tdatetimevaluelistedititem = class(trealvaluelistedititem) + private +// fvalue: tdatetime; + procedure setvalue(const avalue: tdatetime); reintroduce; + protected +// procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); +// override; +// procedure setvalue(const atype: listdatatypety; +// const aindex: int32; const getvaluemethod: getvaluemethodty); override; + public + property value: tdatetime read fvalue write setvalue; + end; + + tmsestringvaluelistedititem = class(trecordvaluelistedititem) + private + fvalue: msestring; + procedure setvalue(const avalue: msestring); + protected + function getvaluetype: listdatatypety; override; + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + override; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); override; + public + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + property value: msestring read fvalue write setvalue; + end; + +const + valuenodeclasses: array[listdatatypety] of recordvaluelistedititemty = ( +//dl_none, dl_integer, + trecordvaluelistedititem,tintegervaluelistedititem, +//dl_int64, dl_currency, + trecordvaluelistedititem,trecordvaluelistedititem, +//dl_real, dl_realint, dl_realsum, + trealvaluelistedititem,trecordvaluelistedititem,trecordvaluelistedititem, +//dl_datetime, + tdatetimevaluelistedititem, +//dl_pointer + trecordvaluelistedititem, +//dl_ansistring, dl_msestring, + trecordvaluelistedititem,tmsestringvaluelistedititem, +//dl_doublemsestring, dl_msestringint, + trecordvaluelistedititem,trecordvaluelistedititem, +//dl_complex, dl_rowstate, dl_custom + trecordvaluelistedititem,trecordvaluelistedititem,trecordvaluelistedititem + ); + +procedure initvalueinfo(out ainfo: recvaluety); +procedure initvalueinfo(const aindex: int32; var avalue: int32; + out ainfo: recvaluety); +procedure initvalueinfo(const aindex: int32; var avalue: longbool; + out ainfo: recvaluety); +procedure initvalueinfo(const aindex: int32; var avalue: realty; + out ainfo: recvaluety); +procedure initvalueinfo(const aindex: int32; var avalue: tdatetime; + out ainfo: recvaluety); +procedure initvalueinfo(const aindex: int32; var avalue: msestring; + out ainfo: recvaluety); +function valuefield(var avalue: int32): fieldinfoty; +function valuefield(var avalue: longbool): fieldinfoty; +function valuefield(var avalue: real): fieldinfoty; +function valuefield(var avalue: realty): fieldinfoty; +function valuefield(var avalue: tdatetime): fieldinfoty; +function valuefield(var avalue: msestring): fieldinfoty; +function buildvalueinfos(const afields: array of fieldinfoty; + const aindex: int32): recvaluearty; + //-1 -> all + +implementation +uses + msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure initvalueinfo(out ainfo: recvaluety); +begin + ainfo.dummypointer:= nil; +end; + +procedure initvalueinfo(const aindex: int32; + var avalue: int32; out ainfo: recvaluety); +begin + initvalueinfo(ainfo); + ainfo.datatype:= dl_integer; + ainfo.valueindex:= aindex; + ainfo.valuead:= @avalue; +end; + +procedure initvalueinfo(const aindex: int32; + var avalue: longbool; out ainfo: recvaluety); +begin + initvalueinfo(ainfo); + ainfo.datatype:= dl_integer; + ainfo.valueindex:= aindex; + ainfo.valuead:= @avalue; +end; + +procedure initvalueinfo(const aindex: int32; + var avalue: realty; out ainfo: recvaluety); +begin + initvalueinfo(ainfo); + ainfo.datatype:= dl_real; + ainfo.valueindex:= aindex; + ainfo.valuead:= @avalue; +end; + +procedure initvalueinfo(const aindex: int32; + var avalue: tdatetime; out ainfo: recvaluety); +begin + initvalueinfo(ainfo); + ainfo.datatype:= dl_real; + ainfo.valueindex:= aindex; + ainfo.valuead:= @avalue; +end; + +procedure initvalueinfo(const aindex: int32; + var avalue: msestring; out ainfo: recvaluety); +begin + initvalueinfo(ainfo); + ainfo.datatype:= dl_msestring; + ainfo.valueindex:= aindex; + ainfo.valuead:= @avalue; +end; + +function valuefield(var avalue: int32): fieldinfoty; +begin + result.datatype:= dl_integer; + result.data:= @avalue; +end; + +function valuefield(var avalue: longbool): fieldinfoty; +begin + result.datatype:= dl_integer; + result.data:= @avalue; +end; + +function valuefield(var avalue: real): fieldinfoty; +begin + result.datatype:= dl_real; + result.data:= @avalue; +end; + +function valuefield(var avalue: realty): fieldinfoty; +begin + result.datatype:= dl_real; + result.data:= @avalue; +end; + +function valuefield(var avalue: tdatetime): fieldinfoty; +begin + result.datatype:= dl_real; + result.data:= @avalue; +end; + +function valuefield(var avalue: msestring): fieldinfoty; +begin + result.datatype:= dl_msestring; + result.data:= @avalue; +end; + +function buildvalueinfos( + const afields: array of fieldinfoty; + const aindex: int32): recvaluearty; + + procedure setup(const aindex: int32; const source: fieldinfoty; + out dest: recvaluety); + begin + initvalueinfo(dest); + dest.datatype:= source.datatype; + dest.valueindex:= aindex; + dest.valuead:= source.data; + end;//setup + +var + i1: int32; +begin + if aindex < 0 then begin + setlength(result,length(afields)); + for i1:= 0 to high(result) do begin + setup(i1,afields[i1],result[i1]); + end; + end + else begin + if aindex <= high(afields) then begin + setlength(result,1); + setup(aindex,afields[aindex],result[0]); + end + else begin + result:= nil; + end; + end; +end; + +{ trecordfielditem } + +constructor trecordfielditem.create(const intf: irecordfield; + const afieldindex: integer; + const acaption: msestring; const fixedcaption: boolean; + const aimagenr: integer = 0; + const aimagelist: timagelist = nil); +begin + fintf:= intf; + ffieldindex:= afieldindex; + inherited create; + fcaption:= acaption; + fimagenr:= aimagenr; + imagelist:= aimagelist; + if fixedcaption then begin + fstate1:= fstate1 + [ns1_fixedcaption]; + end; +end; + +function trecordfielditem.getvaluetext: msestring; +begin + if fintf <> nil then begin + result:= fintf.getfieldtext(ffieldindex); + end + else begin + result:= inherited getvaluetext; + end; +end; + +procedure trecordfielditem.setvaluetext(var avalue: msestring); +begin + if fintf <> nil then begin + fintf.setfieldtext(ffieldindex,avalue); + end + else begin + if not (ns1_fixedcaption in fstate1) then begin + inherited; + end; + end; +end; + +{ trecordfieldvalueitem } + +constructor trecordfieldvalueitem.create(const intf: irecordvaluefield; + const afieldindex: integer; const acaption: msestring; + const fixedcaption: boolean = false; const aimagenr: integer = 0; + const aimagelist: timagelist = nil); +begin + inherited create(intf,afieldindex,acaption,fixedcaption,aimagenr,aimagelist); +end; + +procedure trecordfieldvalueitem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + irecordvaluefield(fintf).getvalueinfo(avalues,fieldindex); +end; + +procedure trecordfieldvalueitem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +begin + irecordvaluefield(fintf).setvalue(atype,aindex,getvaluemethod); +end; + +function trecordfieldvalueitem.getfieldtext( + const afieldindex: integer): msestring; +begin + result:= ''; +end; + +procedure trecordfieldvalueitem.setfieldtext(const afieldindex: integer; + var avalue: msestring); +begin + //dummy +end; + +{ trecordtreelistedititem } + +constructor trecordtreelistedititem.create(const aowner: tcustomitemlist; + const aparent: ttreelistitem); +begin + inherited; + include(fstate,ns_nosubnodestat); +end; + +function trecordtreelistedititem.getfieldtext( + const fieldindex: integer): msestring; +begin + result:= ''; +end; + +procedure trecordtreelistedititem.setfieldtext(const fieldindex: integer; + var avalue: msestring); +begin + //dummy +end; + +procedure trecordtreelistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +var + values1: recvaluearty; +begin + if aindex >= 0 then begin + getvalueinfo(values1,aindex); + if (values1 <> nil) then begin + with values1[0] do begin + if datatype = atype then begin + getvaluemethod(valuead^); + end; + end; + end; + end; +end; + +procedure trecordtreelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + avalues:= nil; +end; + +{ trecordlistedititem } + +procedure trecordlistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + avalues:= nil; +end; + +function trecordlistedititem.getfieldtext( + const fieldindex: integer): msestring; +begin + result:= ''; +end; + +procedure trecordlistedititem.setfieldtext(const fieldindex: integer; + var avalue: msestring); +begin + //dummy +end; + +procedure trecordlistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +begin + //dummy +end; + +{ trecordvaluelistedititem } + +constructor trecordvaluelistedititem.create(const avalueindex: int32; + const aowner: tcustomitemlist = nil); +begin + fvalueindex:= avalueindex; + create(aowner); +end; + +procedure trecordvaluelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + avalues:= nil; + allocuninitedarray(1,sizeof(recvaluety),avalues); + with avalues[0] do begin + datatype:= dl_none; + valueindex:= fvalueindex; + valuead:= nil; + dummypointer:= nil; + end; +end; + +procedure trecordvaluelistedititem.dostatread(const reader: tstatreader); +begin + inherited; + fvalueindex:= reader.readinteger(valuenodeindexname,fvalueindex); +end; + +procedure trecordvaluelistedititem.dostatwrite(const writer: tstatwriter); +begin + inherited; + writer.writeinteger(valuenodetypename,ord(getvaluetype)); + writer.writeinteger(valuenodeindexname,fvalueindex); +end; + +function trecordvaluelistedititem.getvaluetype: listdatatypety; +begin + result:= dl_none; +end; + +{ tintegervaluelistedititem } + +procedure tintegervaluelistedititem.setvalue(const avalue: int32); +begin + if fvalue <> avalue then begin + fvalue:= avalue; + valuechange([]); + end; +end; + +procedure tintegervaluelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + inherited; + with avalues[0] do begin + datatype:= dl_integer; + valuead:= @fvalue; + end; +end; + +procedure tintegervaluelistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +var + i1: int32; +begin + if (atype = dl_integer) then begin + getvaluemethod(i1); + value:= i1; + end; +end; + +procedure tintegervaluelistedititem.dostatread(const reader: tstatreader); +begin + inherited; + fvalue:= reader.readinteger(valuenodevaluename,fvalue); +end; + +procedure tintegervaluelistedititem.dostatwrite(const writer: tstatwriter); +begin + inherited; + writer.writeinteger(valuenodevaluename,fvalue); +end; + +function tintegervaluelistedititem.getvaluetype: listdatatypety; +begin + result:= dl_integer; +end; + +{ tbooleanvaluelistedititem } + +procedure tbooleanvaluelistedititem.setvalue(const avalue: boolean); +begin + if longbool(fvalue) <> avalue then begin + longbool(fvalue):= avalue; + valuechange([]); + end; +end; + +function tbooleanvaluelistedititem.getvalue: boolean; +begin + result:= longbool(fvalue); +end; + +{ trealvaluelistedititem } + +procedure trealvaluelistedititem.setvalue(const avalue: realty); +begin + if fvalue <> avalue then begin + fvalue:= avalue; + valuechange([]); + end; +end; + +procedure trealvaluelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + inherited; + with avalues[0] do begin + datatype:= dl_real; + valuead:= @fvalue; + end; +end; + +procedure trealvaluelistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +var + rea1: realty; +begin + if (atype = dl_real) then begin + getvaluemethod(rea1); + value:= rea1; + end; +end; + +function trealvaluelistedititem.getvaluetype: listdatatypety; +begin + result:= dl_real; +end; + +procedure trealvaluelistedititem.dostatread(const reader: tstatreader); +begin + inherited; + fvalue:= reader.readreal(valuenodevaluename,fvalue); +end; + +procedure trealvaluelistedititem.dostatwrite(const writer: tstatwriter); +begin + inherited; + writer.writereal(valuenodevaluename,fvalue); +end; + +{ tdatetimevaluelistedititem } + +procedure tdatetimevaluelistedititem.setvalue(const avalue: tdatetime); +begin + inherited setvalue(avalue); +{ + if fvalue <> avalue then begin + fvalue:= avalue; + valuechange(); + end; +} +end; +{ +procedure tdatetimevaluelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + inherited; + with avalues[0] do begin + datatype:= dl_real; + valuead:= @fvalue; + end; +end; + +procedure tdatetimevaluelistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +var + dat1: tdatetime; +begin + if (atype = dl_real) then begin + getvaluemethod(dat1); + value:= dat1; + end; +end; +} +{ tmsestringvaluelistedititem } + +procedure tmsestringvaluelistedititem.setvalue(const avalue: msestring); +begin + if fvalue <> avalue then begin + fvalue:= avalue; + valuechange([]); + end; +end; + +procedure tmsestringvaluelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + inherited; + with avalues[0] do begin + datatype:= dl_msestring; + valuead:= @fvalue; + end; +end; + +procedure tmsestringvaluelistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +var + mstr1: msestring; +begin + if (atype = dl_msestring) then begin + getvaluemethod(mstr1); + value:= mstr1; + end; +end; + +function tmsestringvaluelistedititem.getvaluetype: listdatatypety; +begin + result:= dl_msestring; +end; + +procedure tmsestringvaluelistedititem.dostatread(const reader: tstatreader); +begin + inherited; + fvalue:= reader.readmsestring(valuenodevaluename,fvalue); +end; + +procedure tmsestringvaluelistedititem.dostatwrite(const writer: tstatwriter); +begin + inherited; + writer.writemsestring(valuenodevaluename,fvalue); +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msevaluenodesglob.pas b/mseide-msegui/lib/common/editwidgets/msevaluenodesglob.pas new file mode 100644 index 0000000..c77e6d0 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msevaluenodesglob.pas @@ -0,0 +1,26 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msevaluenodesglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msedatalist,mseglob; +type + recvaluety = record + datatype: listdatatypety; + valueindex: int32; + valuead: pointer; + dummypointer: pointer; //can be used by clients, inited with nil + end; + precvaluety = ^recvaluety; + recvaluearty = array of recvaluety; + +implementation +end. diff --git a/mseide-msegui/lib/common/editwidgets/msewidgetgrid.pas b/mseide-msegui/lib/common/editwidgets/msewidgetgrid.pas new file mode 100644 index 0000000..f83b207 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msewidgetgrid.pas @@ -0,0 +1,4084 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msewidgetgrid; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseclasses,msegrids,msegui,msegraphutils,mseglob,mseguiglob,mseeditglob, + classes,mclasses,msemenus,msearrayutils,msedragglob,mseinterfaces, + msegraphics,mseevent,msedatalist,msetypes,msepointer,msestrings, + mseassistiveclient, + msegridsglob{$ifdef mse_with_ifi},mseificomp{$endif}; + +//todo: simplify handling of changed column widgets in inherited grids + +type + + twidgetcol = class; + tcustomwidgetgrid = class; + + iwidgetgrid = interface(inullinterface) + function getgrid: tcustomwidgetgrid; + function getbrushorigin: pointty; + function getcol: twidgetcol; + function getdatapo(const arow: integer): pointer; + function getrowdatapo: pointer; + procedure getdata(var index: integer; var dest); + procedure setdata(var index: integer; const source; + const noinvalidate: boolean = false); + procedure datachange(const index: integer); + function getrow: integer; + procedure setrow(arow: integer); + procedure changed(); + procedure edited(); + function empty(index: integer): boolean; + function cangridcopy: boolean; + procedure updateeditoptions(var aoptions: optionseditty; + const aoptions1: optionsedit1ty); + procedure coloptionstoeditoptions(var dest: optionseditty; + var dest1: optionsedit1ty); + function showcaretrect(const arect: rectty; + const aframe: tcustomframe): pointty; + procedure widgetpainted(const canvas: tcanvas); + function nullcheckneeded(const newfocus: twidget): boolean; + function nonullcheck: boolean; + function nocheckvalue: boolean; + property grid: tcustomwidgetgrid read getgrid; + {$ifdef mse_with_ifi} + procedure updateifigriddata(const alist: tdatalist); + {$endif} + end; + + igridwidget = interface(inullinterface)[miid_igridwidget] + procedure setfirstclick(var ainfo: mouseeventinfoty); + function getwidget: twidget; + procedure getautocellsize(const acanvas: tcanvas; var asize: sizety); + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); + function getcellframe: framety; + function needscellfocuspaint(): boolean; + function getcellcursor(const arow: integer; //-1 -> widget + const acellzone: cellzonety; const apos: pointty): cursorshapety; + procedure updatecellzone(const arow: integer; //-1 -> widget + const apos: pointty; + var result: cellzonety); + function createdatalist(const sender: twidgetcol): tdatalist; + function getdatalistclass: datalistclassty; + procedure datalistdestroyed; + function getdefaultvalue: pointer; +// function getrowdatapo(const info: cellinfoty): pointer; + function getrowdatapo(const arow: integer): pointer; + function getoptionsedit: optionseditty; + procedure setgridintf(const intf: iwidgetgrid); + function getgridintf: iwidgetgrid; + procedure drawcell(const canvas: tcanvas); + procedure updateautocellsize(const canvas: tcanvas); + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); + procedure initgridwidget; + procedure gridtovalue(row: integer); //row = -1 -> focused row, + // -2 -> default value + procedure valuetogrid(row: integer); //row = -1 -> focused row + function getnulltext: msestring; + function getassistivecelltext(const arow: int32): msestring; + procedure docellevent(const ownedcol: boolean; var info: celleventinfoty); + function sortfunc(const l,r): integer; + procedure gridvaluechanged(const index: integer); //index = -1 -> undefined, all + procedure updatecoloptions(const aoptions: coloptionsty); + procedure updatecoloptions1(const aoptions: coloptions1ty); + procedure statdataread; + procedure griddatasourcechanged; + procedure setreadonly(const avalue: boolean); + {$ifdef mse_with_ifi} + function getifilink: tifilinkcomp; + {$endif} + //for titemedit children + procedure setparentgridwidget(const intf: igridwidget); + procedure setvaluedata(const source); + procedure getvaluedata(out dest); + procedure childdataentered(const sender: igridwidget); + procedure childfocused(const sender: igridwidget); + end; + + twidgetcol = class(tdatacol,iwidgetgrid,idatalistclient) + private + fwidgetname: string; + ffixrowwidgets: widgetarty; + ffixrowwidgetnames: stringarty; + fondrawcell: drawcelleventty; + procedure updatewidgetrect(const updatedata: boolean = false); + procedure readwidgetname(reader: treader); + procedure writewidgetname(writer: twriter); + procedure readfixwidgetnames(reader: treader); + procedure writefixwidgetnames(writer: twriter); + procedure readdataclass(reader: treader); + procedure writedataclass(writer: twriter); + procedure readdatatype(reader: treader); + procedure writedatatype(writer: twriter); + procedure readdata(reader: treader); + procedure writedata(writer: twriter); + procedure readdataprops(reader: treader); + procedure writedataprops(writer: twriter); + function getfixrowwidgets(aindex: integer): twidget; + procedure setfixrowwidgets(aindex: integer; const avalue: twidget); + protected + fintf: igridwidget; + //iwidgetgrid + function getgrid: tcustomwidgetgrid; + procedure edited(); + function getbrushorigin: pointty; + function getcol: twidgetcol; + procedure getdata(var arow: integer; var dest); + procedure setdata(var arow: integer; + const source; const noinvalidate: boolean = false); virtual; + function getrow: integer; + procedure setrow(arow: integer); + function empty(arow: integer): boolean; + function cangridcopy: boolean; + procedure updateeditoptions(var aoptions: optionseditty; + const aoptions1: optionsedit1ty); + function showcaretrect(const arect: rectty; const aframe: tcustomframe): pointty; + procedure widgetpainted(const canvas: tcanvas); + function nullcheckneeded(const newfocus: twidget): boolean; + function nonullcheck: boolean; + function nocheckvalue: boolean; + {$ifdef mse_with_ifi} + procedure updateifigriddata(const alist: tdatalist); + {$endif} + + procedure checkcanclose(var accepted: boolean); + procedure docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); override; + procedure defineproperties(filer: tfiler); override; + function getdatapo(const arow: integer): pointer; override; + procedure drawcell(const canvas: tcanvas); override; + procedure drawfocusedcell(const acanvas: tcanvas); override; + procedure drawfocus(const acanvas: tcanvas); override; + function sortcompare(const index1,index2: integer): integer; override; + procedure itemchanged(const sender: tdatalist; + const aindex: integer); override; + procedure setwidget(const awidget: twidget); virtual; + procedure seteditwidget(const value: twidget); + procedure setfixrowwidget(const awidget: twidget; const rowindex: integer); + function geteditwidget: twidget; + function getinnerframe: framety; override; + procedure setoptions(const avalue: coloptionsty); override; + procedure setoptions1(const avalue: coloptions1ty); override; + function getcursor(const arow: integer; const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; override; + procedure datasourcechanged; + procedure beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); override; + procedure afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); override; + + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + procedure sourcenamechanged(const atag: integer); + procedure updatecellzone(const row: integer; const pos: pointty; + var result: cellzonety); override; + function actualfont: tfont; override; + property editwidget: twidget read geteditwidget write seteditwidget; + property fixrowwidgets[aindex: integer]: twidget read getfixrowwidgets + write setfixrowwidgets; + property grid: tcustomwidgetgrid read getgrid; + published + property datalist stored false; //stored by defineproperties + property ondrawcell: drawcelleventty read fondrawcell write fondrawcell; + end; + widgetcolarty = array of twidgetcol; + twidgetfixrow = class(tfixrow) + end; + + twidgetfixrows = class(tfixrows) + private + fwidgetrectupdating: integer; + procedure unregisterchildwidget(const child: twidget); + function getrows(const aindex: integer): twidgetfixrow; + procedure updatewidgetrect; + protected + procedure countchanged; override; + public + constructor create(const owner: tcustomwidgetgrid); + procedure move(const curindex,newindex: integer); override; + property rows[const index: integer]: twidgetfixrow read getrows; default; + end; + + twidgetcols = class(tdatacols) + private + fcolorder: stringarty; + fcolcount: integer; + function getcols(const index: integer): twidgetcol; + procedure unregisterchildwidget(const child: twidget); + procedure updatecolorder; + procedure writeorder(writer: twriter); + procedure readorder(reader: treader); + protected + procedure updatedatastate(var accepted: boolean); override; + procedure defineproperties(filer: tfiler); override; + function getcollectionname(const aindex: integer): string; override; + procedure setcount1(acount: integer; doinit: boolean); override; + public + constructor create(const aowner: tcustomwidgetgrid); + class function getitemclasstype: persistentclassty; override; + procedure datasourcechanged; override; + property cols[const index: integer]: twidgetcol read getcols; default; + end; + + twidgetfixcol = class(tfixcol) + private + ffixrowwidgets: widgetarty; + ffixrowwidgetnames: stringarty; + procedure readfixwidgetnames(reader: treader); + procedure writefixwidgetnames(writer: twriter); + function getfixrowwidgets(aindex: integer): twidget; + procedure setfixrowwidgets(aindex: integer; const avalue: twidget); + protected + procedure defineproperties(filer: tfiler); override; + procedure setfixrowwidget(const awidget: twidget; const rowindex: integer); + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + property fixrowwidgets[aindex: integer]: twidget read getfixrowwidgets + write setfixrowwidgets; + end; + + twidgetfixcols = class(tfixcols) + private + function getcols(const index: integer): twidgetfixcol; + protected + procedure unregisterchildwidget(const child: twidget); + public + constructor create(const aowner: tcustomwidgetgrid); + property cols[const index: integer]: twidgetfixcol read getcols; default; + end; + + tdummywidget = class(twidget) + protected + function getassistiveflags(): assistiveflagsty override; + public + constructor create(aowner: tcomponent); override; + function setfocus(aactivate: boolean = true): boolean; override; + //unsetsfocus if not focusable + end; + + tcustomwidgetgrid = class(tcustomgrid) + private + fcontainer0: twidget; //nohscroll + fcontainer1: twidget; //top + fcontainer2: twidget; //grid + fcontainer3: twidget; //bottom + flastfocusedfixwidget: twidget; + fwidgetdummy: tdummywidget; + fmouseinfopo: pmouseeventinfoty; + function getdatacols: twidgetcols; + procedure setdatacols(const avalue: twidgetcols); + procedure initcopyars(out dataedits: widgetarty; + out datalists: datalistarty); + procedure dowidgetcellevent(var info: celleventinfoty); + function getfixrows: twidgetfixrows; + procedure setfixrows(const avalue: twidgetfixrows); + function getfixcols: twidgetfixcols; + procedure setfixcols(const avalue: twidgetfixcols); + protected + ffocuslock: integer; + factivewidget: twidget; + function getgriddatalink: pointer; virtual; + procedure setoptionswidget(const avalue: optionswidgetty); override; + procedure setoptionsgrid(const avalue: optionsgridty); override; + function checksubfocus(const aactivate: boolean): boolean; override; + procedure dochildfocused(const sender: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure widgetregionchanged(const sender: twidget); override; + function createdatacols: tdatacols; override; + function createfixrows: tfixrows; override; + function createfixcols: tfixcols; override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure scrolled(const dist: pointty); override; + procedure updatecontainerrect; + procedure updatelayout; override; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; +// procedure dobeginread; override; + procedure doendread; override; + function scrollcaret(const vertical: boolean): boolean; override; + procedure docellevent(var info: celleventinfoty); override; + procedure checkcellvalue(var accept: boolean); override; //store edited value to grid + procedure dofocusedcellposchanged; override; + procedure dorowsmoved(const fromindex,toindex,count: integer); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; var info: mouseeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure doexit; override; + procedure navigrequest(var info: naviginfoty; + const nowrap: boolean); override; + procedure checkrowreadonlystate; override; + procedure updaterowdata; override; + function cellhasfocus: boolean; override; + + function getcontainer: twidget; override; + function getchildwidgets(const index: integer): twidget; override; + procedure removefixwidget(const awidget: twidget); + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + //iassistiveclientgrid + function getassistiveflags(): assistiveflagsty override; + function getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring; override; + function getassistivecaretindex(): int32; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure writestate(writer: twriter); override; + procedure insertwidget(const awidget: twidget; const apos: pointty); override; + function childrencount: integer; override; + function getlogicalchildren: widgetarty; override; + + procedure focuslock; //beginupdate + no cell widget focus/defocus + procedure focusunlock; + + procedure seteditfocus; + procedure setcellclientclick(const awidget: twidget); + function editwidgetatpos(const apos: pointty; out cell: gridcoordty): twidget; + function widgetcell(const awidget: twidget): gridcoordty; + function cellwidget(const acell: gridcoordty): twidget; + function copyselection: boolean; override; + //false if no copy + function pasteselection: boolean; override; + //false if no paste + property datacols: twidgetcols read getdatacols write setdatacols; + property fixcols: twidgetfixcols read getfixcols write setfixcols; + property fixrows: twidgetfixrows read getfixrows write setfixrows; + end; + + twidgetgrid = class(tcustomwidgetgrid) + public + procedure initnewcomponent(const ascale: real); override; + published + property optionsgrid; + property optionsgrid1; + property optionsfold; + property rowstatelist; + property fixcols; + property fixrows; + property rowcount; + property rowcountmax; + property gridframecolor; +// property gridframewidth; + property rowcolors; + property rowfonts; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property datacols; + {$ifdef mse_with_ifi} + property ifilink; + {$endif} + + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datarowheight; + property datarowheightmin; + property datarowheightmax; + + property statfile; + property statvarname; + property statpriority; + + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property oncolmoving; + property oncolmoved; + property onrowcountchanged; + property onrowdatachanged; + property onrowsdatachanged; + property onrowsmoving; + property onrowsmoved; + property onrowsinserting; + property onrowsinserted; + property onrowsdeleting; + property onrowsdeleted; + property onrowsmodified; + property onedited; + property onscrollrows; + property ongetmorerows; + property oncellevent; + property onselectionchanged; + property onsort; + property onsortchanged; + property drag; + end; + + tgridmsestringdatalist = class(tmsestringdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + function empty(const index: integer): boolean; override; //true wenn leer + published + property facultative; + end; + + tgridansistringdatalist = class(tansistringdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + tgridbinarystringdatalist = class(tgridansistringdatalist) + public + constructor create(owner: twidgetcol); + end; + + + tgridpointerdatalist = class(tpointerdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + + tgridintegerdatalist = class(tintegerdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + + tgridint64datalist = class(tint64datalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + + tgridenumdatalist = class(tenumdatalist) + private + fowner: twidgetcol; + protected + function getdefaultenum: integer; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + + tgridenum64datalist = class(tenum64datalist) + private + fowner: twidgetcol; + protected + function getdefaultenum: int64; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + + tgridrealdatalist = class(trealdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + function empty(const index: integer): boolean; override; //true wenn leer + procedure updateeditoptions(const aoptions: optionseditty); + published + property facultative; + end; + +type + creategriddatalistty = function(const aowner: twidgetcol): tdatalist; + +procedure registergriddatalistclass(const tag: ansistring; + const createfunc: creategriddatalistty); + +procedure gridwidgetfontheightdelta(const sender: twidget; + const gridintf: iwidgetgrid; const delta: integer); +procedure gridwidgetsized(const sender: twidget; const gridintf: iwidgetgrid); +procedure defaultinitgridwidget(const awidget: twidget; + const agridintf: iwidgetgrid); + +implementation +uses + sysutils,msebits,msedataedits,msewidgets,mseshapes,msekeyboard,typinfo, + msereal,mseapplication,msehash,msesumlist; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdatalist1 = class(tdatalist); + twidget1 = class(twidget); + tcustomgrid1 = class(tcustomgrid); + tdataedit1 = class(tdataedit); + twriter1 = class(twriter); + treader1 = class(treader); + tdatacol1 = class(tdatacol); + + tcontainer1 = class(twidget) + protected + fgrid: tcustomwidgetgrid; + procedure doexit; override; + procedure doenter; override; + function getiassistiveclient(): iassistiveclient; override; + public + end; + + tfixcontainer = class(tcontainer1) + protected + procedure unregisterchildwidget(const child: twidget); override; + procedure widgetregionchanged(const sender: twidget); override; + procedure dochildfocused(const sender: twidget); override; + procedure doenter; override; + public + constructor create(aowner: tcustomwidgetgrid); reintroduce; + function focusback(const aactivate: boolean = true): boolean; override; + end; + + ttopcontainer = class(tfixcontainer) + end; + + tbottomcontainer = class(tfixcontainer) + end; + + twidgetdummy = class(twidget) + protected + fgrid: tcustomwidgetgrid; + public + constructor create(aowner: tcustomwidgetgrid); reintroduce; + end; + + tgridcontainer = class(tcontainer1) + private + flayoutupdating: integer; + protected + procedure unregisterchildwidget(const child: twidget); override; + procedure doenter; override; + procedure doexit; override; + procedure dofocus; override; + public + constructor create(aowner: tcustomwidgetgrid); reintroduce; + function focusback(const aactivate: boolean = true): boolean; override; + end; + + tscrollgridcontainer = class(tgridcontainer) + protected + procedure widgetregionchanged(const sender: twidget); override; + end; + + tnoscrollgridcontainer = class(tscrollgridcontainer) + public +// constructor create(aowner: tcustomwidgetgrid); + end; + +var + griddatalists: tpointeransistringhashdatalist; + +procedure defaultinitgridwidget(const awidget: twidget; + const agridintf: iwidgetgrid); + +begin + with twidget1(awidget) do begin + optionswidget1:= optionswidget1 - [ow1_autoscale]; + optionsskin:= optionsskin + defaultgridskinoptions; + if (fframe <> nil) then begin + if (ws_staticframe in fwidgetstate) then begin + fframe.initgridframe; + if agridintf <> nil then begin + fframe.framei:= agridintf.getgrid.datacols.innerframe; + end; + end + else begin + freeandnil(fframe); + end; + end; + synctofontheight; + end; +end; + +procedure gridwidgetfontheightdelta(const sender: twidget; const gridintf: iwidgetgrid; + const delta: integer); +var + cell1: gridcoordty; + widget1: twidget; +begin + with twidget1(sender) do begin + if (ow1_autoscale in foptionswidget1) and + not (csdesigning in componentstate) then begin + //in designmode widgetsize -> cellsize + if gridintf <> nil then begin + with gridintf.getcol.grid do begin + datarowheight:= datarowheight + delta; + end; + end + else begin + widget1:= parentofcontainer; + if widget1 is tcustomwidgetgrid then begin + with tcustomwidgetgrid(widget1) do begin + cell1:= widgetcell(sender); + if (cell1.row < 0) and (cell1.row >= -fixrows.count) then begin + fixrows[cell1.row].height:= fixrows[cell1.row].height + delta; + end; + end; + end; + end; + end; + end; +end; + +procedure gridwidgetsized(const sender: twidget; const gridintf: iwidgetgrid); +var + cell1: gridcoordty; + widget1: twidget; +begin + with twidget1(sender) do begin + if (foptionswidget1*[ow1_autowidth,ow1_autoheight] <> []) and + not (csdesigning in componentstate) then begin + //in designmode widgetsize -> cellsize + if gridintf <> nil then begin + with gridintf.getcol do begin + if not (gs1_cellsizesyncing in grid.fstate1) then begin + include(grid.fstate1,gs1_cellsizesyncing); + try + if ow1_autowidth in foptionswidget1 then begin + width:= bounds_cx; + end; + if ow1_autoheight in foptionswidget1 then begin + grid.datarowheight:= bounds_cy; + end; + finally + exclude(grid.fstate1,gs1_cellsizesyncing); + end; + end; + end; + end + else begin + widget1:= parentofcontainer; + if widget1 is tcustomwidgetgrid then begin + with tcustomwidgetgrid(widget1) do begin + if not (gs1_cellsizesyncing in fstate1) then begin + include(fstate1,gs1_cellsizesyncing); + try + cell1:= widgetcell(sender); + if ow1_autowidth in sender.optionswidget1 then begin + if (cell1.col >= 0) then begin + if (cell1.col < datacols.count) then begin + datacols[cell1.col].width:= sender.bounds_cx; + end; + end + else begin + if cell1.col >= -fixcols.count then begin + fixcols[cell1.col].width:= sender.bounds_cx; + end; + end; + end; + if ow1_autoheight in sender.optionswidget1 then begin + if (cell1.row < 0) and (cell1.row >= -fixrows.count) then begin + fixrows[cell1.row].height:= sender.bounds_cy; + end; + end; + finally + exclude(fstate1,gs1_cellsizesyncing); + end; + end; + end; + end; + end; + end; + end; +end; + +{ tgridmsestringdatalist } + +constructor tgridmsestringdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridmsestringdatalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +function tgridmsestringdatalist.empty(const index: integer): boolean; +var + po1: pmsestring; +begin + po1:= nil; + if fowner.fintf <> nil then begin + po1:= fowner.fintf.getdefaultvalue; + end; + if po1 <> nil then begin + result:= msestring(getitempo(index)^) = po1^; + end + else begin + result:= inherited empty(index); + end; +end; + +{ tgridansistringdatalist } + +constructor tgridansistringdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridansistringdatalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +{ tgridpointerdatalist } + +constructor tgridpointerdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridpointerdatalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +{ tgridintegerdatalist } + +constructor tgridintegerdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridintegerdatalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +{ tgridint64datalist } + +constructor tgridint64datalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridint64datalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +{ tgridenumdatalist } + +constructor tgridenumdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create({$ifdef FPC}@{$endif}getdefaultenum); + include(fstate,dls_nostreaming); +end; + +function tgridenumdatalist.getdefaultenum: integer; +begin + if fowner.fintf <> nil then begin + result:= integer(fowner.fintf.getdefaultvalue^); + end + else begin + result:= 0; +// result:= integer(inherited getdefault^); + end; +end; + +{ tgridenum64datalist } + +constructor tgridenum64datalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create({$ifdef FPC}@{$endif}getdefaultenum); + include(fstate,dls_nostreaming); +end; + +function tgridenum64datalist.getdefaultenum: int64; +begin + if fowner.fintf <> nil then begin + result:= int64(fowner.fintf.getdefaultvalue^); + end + else begin +// result:= int64(inherited getdefault^); + result:= 0; + end; +end; + +{ tgridrealdatalist } + +constructor tgridrealdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridrealdatalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= nil; + end; + if result = nil then begin + result:= inherited getdefault; + end; +end; + +function tgridrealdatalist.empty(const index: integer): boolean; +var + po1: prealty; +begin + po1:= nil; + if fowner.fintf <> nil then begin + po1:= fowner.fintf.getdefaultvalue; + end; + if po1 <> nil then begin + result:= realty(getitempo(index)^) = po1^; + end + else begin + result:= inherited empty(index); + end; +end; + +procedure tgridrealdatalist.updateeditoptions(const aoptions: optionseditty); +begin + acceptempty:= oe_null in aoptions; +end; + +{ twidgetfixrow } + + +{ twidgetfixrows } + +constructor twidgetfixrows.create(const owner: tcustomwidgetgrid); +begin + inherited create(owner); + fitemclasstype:= twidgetfixrow; +end; + +procedure twidgetfixrows.unregisterchildwidget(const child: twidget); +var + int1,int2: integer; +begin + if (fwidgetrectupdating = 0) and + not (csdestroying in fgrid.componentstate) then begin + for int1:= 0 to fgrid.datacols.count - 1 do begin + with tcustomwidgetgrid(fgrid).datacols[int1] do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = child then begin + ffixrowwidgets[int2]:= nil; + break; + end; + end; + end; + end; + end; +end; + +function twidgetfixrows.getrows(const aindex: integer): twidgetfixrow; +begin + result:= twidgetfixrow(inherited rows[aindex]); +end; + +procedure twidgetfixrows.updatewidgetrect; +var + rect1: rectty; + int1,int2: integer; + coord1: gridcoordty; +begin + inc(fwidgetrectupdating); + try + for int1:= 0 to fgrid.datacols.count - 1 do begin + with tcustomwidgetgrid(fgrid).datacols[int1] do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] <> nil then begin + with ffixrowwidgets[int2] do begin + if co_nohscroll in foptions then begin + parentwidget:= fgrid; + end + else begin + if int2 >= fgrid.fixrows.count - fgrid.fixrows.oppositecount then begin + parentwidget:= tcustomwidgetgrid(fgrid).fcontainer3; + end + else begin + parentwidget:= tcustomwidgetgrid(fgrid).fcontainer1; + end; + end; + coord1:= makegridcoord(int1,-int2-1); + if fgrid.cellvisible(coord1) or (csdesigning in fgrid.componentstate) then begin + rect1:= fgrid.cellrect(coord1,cil_noline); + rect1.pos:= translatewidgetpoint(addpoint(rect1.pos,fgrid.paintpos), + fgrid,parentwidget); + widgetrect:= rect1; + end + else begin + bounds_y:= -bounds_cy; //shift out of view + end; + end; + end; + end; + end; + end; + for int1:= -fgrid.fixcols.count to -1 do begin + with tcustomwidgetgrid(fgrid).fixcols[int1] do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] <> nil then begin + with ffixrowwidgets[int2] do begin + parentwidget:= fgrid; + coord1:= makegridcoord(int1,-int2-1); + if fgrid.cellvisible(coord1) then begin + rect1:= fgrid.cellrect(coord1,cil_noline); + rect1.pos:= translatewidgetpoint(addpoint(rect1.pos,fgrid.paintpos), + fgrid,parentwidget); + widgetrect:= rect1; + end + else begin + bounds_y:= -bounds_cy; //shift out of view + end; + end; + end; + end; + end; + end; + with tcustomwidgetgrid(fgrid) do begin + if fcontainer1 <> nil then begin //else call from tcustomwidgetgrid.create + if fcontainer1.widgetcount = 0 then begin + exclude(twidget1(fcontainer1).foptionswidget,ow_arrowfocus); + end + else begin + include(twidget1(fcontainer1).foptionswidget,ow_arrowfocus); + end; + if fcontainer3.widgetcount = 0 then begin + exclude(twidget1(fcontainer3).foptionswidget,ow_arrowfocus); + end + else begin + include(twidget1(fcontainer3).foptionswidget,ow_arrowfocus); + end; + end; + end; + finally + dec(fwidgetrectupdating); + end; +end; + +procedure twidgetfixrows.countchanged; +var + int1,int2: integer; + ar1: widgetarty; +begin + if not (csdestroying in fgrid.componentstate) then begin + for int1:= 0 to fgrid.datacols.count - 1 do begin + with tcustomwidgetgrid(fgrid).datacols[int1] do begin + ar1:= ffixrowwidgets; + setlength(ffixrowwidgets,self.count); + for int2:= high(ar1) downto self.count do begin + if ar1[int2] <> nil then begin + freedesigncomponent(ar1[int2]); //inhibit deleting of inherited widget + end; + end; + end; + end; + for int1:= 0 to fgrid.fixcols.count - 1 do begin + with twidgetfixcol(fgrid.fixcols.items[int1]) do begin + ar1:= ffixrowwidgets; + setlength(ffixrowwidgets,self.count); + for int2:= high(ar1) downto self.count do begin + if ar1[int2] <> nil then begin + freedesigncomponent(ar1[int2]); //inhibit deleting of inherited widget + end; + end; + end; + end; + end; + inherited; +end; + +procedure twidgetfixrows.move(const curindex,newindex: integer); +var + int1: integer; +begin + inherited; + for int1:= 0 to fgrid.datacols.count - 1 do begin + with tcustomwidgetgrid(fgrid).datacols[int1] do begin + moveitem(pointerarty(ffixrowwidgets),curindex,newindex); + end; + end; + for int1:= 0 to fgrid.fixcols.count - 1 do begin + with twidgetfixcol(fgrid.fixcols.items[int1]) do begin + moveitem(pointerarty(ffixrowwidgets),curindex,newindex); + end; + end; +end; + +{ twidgetcol } + +constructor twidgetcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + setlength(ffixrowwidgets,agrid.fixrows.count); + inherited; +end; + +destructor twidgetcol.destroy; +var + aintf: igridwidget; + int1: integer; +begin + if not (csdestroying in fcellinfo.grid.componentstate) then begin + if fintf <> nil then begin + aintf:= fintf; + fintf:= nil; + aintf.setgridintf(nil); + if not (csreading in fcellinfo.grid.componentstate) then begin + //refreshancestor otherwise + freedesigncomponent(aintf.getwidget); //inhibit deleting of inherited widget + end; + end; + if not (csreading in fcellinfo.grid.componentstate) then begin + //refreshancestor otherwise + for int1:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int1] <> nil then begin + freedesigncomponent(ffixrowwidgets[int1]); + //inhibit deleting of inherited widget + end; + end; + end; + end; +{$ifndef FPC} + pointer(fintf):= nil; //workaround for com decref +{$endif} + inherited; +end; + +{$ifdef FPC}{$checkpointer off}{$endif} +procedure twidgetcol.updatewidgetrect(const updatedata: boolean = false); +var + rect1: rectty; + widget1: twidget; +begin + with tcustomwidgetgrid(fcellinfo.grid) do begin + if (fintf <> nil) then begin //bug in fixes_2_0 2850 with checkpointer + widget1:= fintf.getwidget; + if co_nohscroll in foptions then begin + widget1.parentwidget:= fcontainer0; + end + else begin + widget1.parentwidget:= fcontainer2; + end; + if (csdesigning in componentstate) or (ffocusedcell.row < 0) then begin + rect1:= cellrect(makegridcoord(colindex,invalidaxis),cil_noline); + rect1.cy:= datarowheight; + if not (csdesigning in componentstate) then begin + if row >= 0 then begin + rect1.cx:= rect1.cx + fdatacols.mergedwidth(index, + fdatacols.rowstate.merged[row]); + end; + end; + if co_nohscroll in self.foptions then begin + rect1.y:= 0; + rect1.x:= rect1.x - fdatarecty.x; + widget1.widgetrect:= rect1; + end + else begin + rect1.y:= 0; + dec(rect1.x,fdatarect.x); + widget1.widgetrect:= rect1; + end; + end + else begin + rect1:= cellrect(makegridcoord(colindex,ffocusedcell.row),cil_noline); + if co_nohscroll in self.foptions then begin + removerect1(rect1,fdatarecty.pos); + end + else begin + removerect1(rect1,fdatarect.pos); + end; + widget1.widgetrect:= rect1; + end; + if updatedata then begin + fintf.gridtovalue(-1); + end; + end; + end; +end; +{$ifdef FPC}{$checkpointer default}{$endif} + +procedure twidgetcol.checkcanclose(var accepted: boolean); +begin + if (fintf <> nil) and fintf.getwidget.focused and + not tcustomgrid1(fcellinfo.grid).nocheckvalue and accepted then begin + accepted:= fintf.getwidget.canclose(nil); + end; +end; + +procedure twidgetcol.docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); +var + widget1: twidget; + activewidgetbefore: twidget; + intf: igridwidget; + focuscount: integer; + bo1: boolean; + +begin + with twidgetgrid(fcellinfo.grid) do begin + if ffocuslock > 0 then begin + if not enter then begin + factivewidget:= nil; + end + else begin + end; + inherited; + exit; + end; + + focuscount:= ffocuscount; + activewidgetbefore:= factivewidget; + if not enter and + ((selectaction <> fca_exitgrid) or (newcell.row < 0)) then begin + factivewidget:= nil; + bo1:= true; + if not (gs1_rowdeleting in twidgetgrid(fcellinfo.grid).fstate1) then begin + checkcanclose(bo1); + end; + if bo1 then begin + if (activewidgetbefore <> nil) and + activewidgetbefore.clicked then begin + with fcellinfo.grid do begin + capturemouse; + fwidgetstate:= fwidgetstate + [ws_clientmousecaptured]; + include(fstate,gs_childmousecaptured); + end; + end; + if (activewidgetbefore <> nil) then begin + if activewidgetbefore.focused then begin + fwidgetdummy.setfocus(active); + end; + activewidgetbefore.visible:= false; + end; + inherited; + end + else begin + focuscell(cellbefore,fca_none); + end; + end + else begin + if (fintf <> nil) then begin + if fcellinfo.grid.canwindow then begin + updatewidgetrect; + end; + inherited; + bo1:= (tcustomwidgetgrid(fcellinfo.grid).fmouseinfopo <> nil) and + tcustomwidgetgrid(fcellinfo.grid).wantmousefocus(fmouseinfopo^); + if fcellinfo.grid.entered or + not (gs_cellexiting in tcustomwidgetgrid(fcellinfo.grid).fstate) and + bo1 then begin + widget1:= fintf.getwidget; + with widget1 do begin + if not visible then begin +// twidgetgrid(fcellinfo.grid).fmouseactivewidget:= nil; + visible:= true; + end; + if (fwindow <> nil) and + canfocus and (tcustomwidgetgrid(fcellinfo.grid).entered or bo1) and + ( + not fcellinfo.grid.checkdescendent(fwindow.focusedwidget) or + (fwindow.focusedwidget = fcellinfo.grid) or + fcontainer2.checkdescendent(fwindow.focusedwidget) or + fcontainer0.checkdescendent(fwindow.focusedwidget)) then begin + bo1:= gs1_focuscellonenterlock in twidgetgrid(fcellinfo.grid).fstate1; + include(twidgetgrid(fcellinfo.grid).fstate1,gs1_focuscellonenterlock); + try + setfocus(fcellinfo.grid.active); + finally + if not bo1 then begin + exclude(twidgetgrid(fcellinfo.grid).fstate1,gs1_focuscellonenterlock); + end; + end; + end; + end; + if ffocuscount = focuscount then begin + factivewidget:= widget1; + end; + end; + end + else begin + if ffocuscount = focuscount then begin + factivewidget:= nil; + end; + end; + if (activewidgetbefore = nil) and (cellbefore.col >= 0) then begin + intf:= twidgetcol(fdatacols[cellbefore.col]).fintf; + if intf <> nil then begin + activewidgetbefore:= intf.getwidget; + end; + end; + if (activewidgetbefore <> nil) and + (activewidgetbefore <> factivewidget) then begin + activewidgetbefore.visible:= false; + end; + end; + end; +end; + +procedure twidgetcol.readfixwidgetnames(reader: treader); +begin + readstringar(reader,ffixrowwidgetnames); +end; + +procedure twidgetcol.writefixwidgetnames(writer: twriter); +begin + writewidgetnames(writer,ffixrowwidgets); +end; + +procedure twidgetcol.readwidgetname(reader: treader); +begin + fwidgetname:= reader.readstring; +end; + +procedure twidgetcol.writewidgetname(writer: twriter); +begin + writer.writestring(fintf.getwidget.name); +end; + +procedure twidgetcol.readdataclass(reader: treader); +var + createproc: creategriddatalistty; + str1: string; +begin + str1:= reader.readident; + if (fdata = nil) or (fdata.classname <> str1) then begin + if fdata <> nil then begin + if fintf <> nil then begin + fintf.datalistdestroyed; + end; + freeandnil(fdata); + end; + if griddatalists.find(str1,pointer({$ifndef FPC}@{$endif}createproc)) then begin + fdata:= createproc(self); + include(fstate,gps_datalistvalid); + end + else begin + raise exception.create('Unknown grid datalist type '+str1+'.'); + end; + end; +end; + +procedure twidgetcol.writedataclass(writer: twriter); +begin + writer.writeident(fdata.classname); +end; + +procedure twidgetcol.readdatatype(reader: treader); +var + str1: string; + int1: integer; + licla: datalistclassty; +begin + str1:= reader.readident; + int1:= getenumvalue(typeinfo(listdatatypety),str1); + if int1 >= 0 then begin + freeandnil(fdata); + licla:= getdatalistclass(listdatatypety(int1)); + if licla <> nil then begin + fdata:= licla.create; + end; + end; +end; + +procedure twidgetcol.writedatatype(writer: twriter); +begin + writer.writeident(getenumname(typeinfo(listdatatypety),integer(fdata.datatype))); +end; + +procedure twidgetcol.readdata(reader: treader); +begin + reader.readlistbegin; + if reader.nextvalue <> valist then begin + readdatatype(reader); + end; + if fdata <> nil then begin + tdatalist1(fdata).readdata(reader); + end + else begin + reader.driver.skipvalue; + end; + reader.readlistend; +end; + +procedure twidgetcol.writedata(writer: twriter); +begin + writer.writelistbegin; +// writedatatype(writer); + tdatalist1(fdata).writedata(writer); + writer.writelistend; +end; + +procedure twidgetcol.readdataprops(reader: treader); +begin + reader.readlistbegin; + while not reader.endoflist do begin + treader1(reader).readproperty(fdata); + end; + reader.readlistend; +end; + +procedure twidgetcol.writedataprops(writer: twriter); +begin + writer.writelistbegin; + twriter1(writer).writeproperties(fdata); + writer.writelistend; +end; + +procedure twidgetcol.defineproperties(filer: tfiler); +var + bo1,bo2: boolean; + col1: twidgetcol; + str1,str2: string; + ancestorbefore: tpersistent; +begin + inherited; + filer.defineproperty('widgetname',{$ifdef FPC}@{$endif}readwidgetname, + {$ifdef FPC}@{$endif}writewidgetname, + (fintf <> nil) and + ((filer.ancestor = nil) or + (twidgetcol(filer.ancestor).fwidgetname <> fwidgetname))); + filer.defineproperty('fixwidgetnames',{$ifdef FPC}@{$endif}readfixwidgetnames, + {$ifdef FPC}@{$endif}writefixwidgetnames, + (filer.ancestor = nil) and needswidgetnamewriting(ffixrowwidgets) or + (filer.ancestor <> nil) and + needswidgetnamewriting(ffixrowwidgets, + twidgetcol(filer.ancestor).ffixrowwidgets)); + bo1:= false; + if (fdata <> nil) and ([dls_nogridstreaming,dls_remote] * + tdatalist1(fdata).fstate = []) then begin + col1:= twidgetcol(filer.ancestor); + if col1 <> nil then begin + bo1:= (col1.fdata = nil) or (fdata.datatype <> col1.fdata.datatype); + filer.ancestor:= col1.fdata; + end; + bo1:= bo1 or fdata.checkwritedata(filer); + filer.ancestor:= col1; + end; + bo2:= (fdata <> nil) and not (dls_remote in fdata.state) and + (not(dls_nogridstreaming in fdata.state) or + (dls_propertystreaming in fdata.state)); + if (filer is twriter) and (twriter(filer).ancestor <> nil) then begin + with twidgetcol(twriter(filer).ancestor) do begin + if (fdata <> nil) and (fdata is self.fdata.classtype) then begin + bo2:= false; + end; + end; + end; + filer.defineproperty('dataclass',{$ifdef FPC}@{$endif}readdataclass, + {$ifdef FPC}@{$endif}writedataclass,bo2); + filer.defineproperty('data',{$ifdef FPC}@{$endif}readdata, + {$ifdef FPC}@{$endif}writedata,bo1); + if (fdata <> nil) and (dls_propertystreaming in + tdatalist1(fdata).fstate) and (filer is twriter) then begin + with twriter1(filer) do begin + str1:= getfproppath(twriter(filer)); + if str1 = '' then begin + str2:= 'datalist.'; + end + else begin + str2:= str1+'.datalist.'; + end; + ancestorbefore:= filer.ancestor; + if ancestorbefore <> nil then begin + filer.ancestor:= twidgetcol(ancestor).fdata; + end; + setfproppath(twriter(filer),str2); + writeproperties(fdata); + setfproppath(twriter(filer),str1); + filer.ancestor:= ancestorbefore; + end; + end; +end; + +procedure twidgetcol.setfixrowwidget(const awidget: twidget; + const rowindex: integer); +begin + tcustomwidgetgrid(fcellinfo.grid).removefixwidget(awidget); + ffixrowwidgets[-rowindex-1]:= awidget; + fcellinfo.grid.layoutchanged; +end; + +procedure twidgetcol.setwidget(const awidget: twidget); +var + po1: pointer; + dl1: tdatalist; +{$ifdef mse_with_ifi} + ifilink1: tifilinkcomp; +{$endif} +begin + dl1:= fdata; + fdata:= nil; +{$ifdef mse_with_ifi} + ifilink1:= nil; +{$endif} + try + if fintf <> nil then begin + if fdata <> nil then begin + fdata.linksource(nil,0); + end; + fintf.setgridintf(nil); + {$ifdef mse_with_ifi} + updateifigriddata(nil); + {$endif} + end; + if awidget <> nil then begin + fwidgetname:= awidget.name; + awidget.visible:= false; + awidget.getcorbainterface(typeinfo(igridwidget),fintf); + if not (gps_datalistvalid in fstate) then begin + fdata:= fintf.createdatalist(self); + end + else begin + if (dl1 <> nil) and not (dl1 is fintf.getdatalistclass) then begin + dl1.destroy(); + dl1:= fintf.createdatalist(self); //fix wrong datalist class + end; + fdata:= dl1; + end; + fintf.setgridintf(iwidgetgrid(self)); + options:= foptions; //call updatecoloptions; + {$ifdef mse_with_ifi} + ifilink1:= fintf.getifilink; + if (ifilink1 <> nil) and not(csloading in ifilink1.componentstate) and + (ifilink1 is tifivaluelinkcomp) and (vco_datalist in + tifivaluelinkcomp(ifilink1).controller.optionsvalue) then begin + if fdata = dl1 then begin + dl1:= nil; //no double free + end; + updateifigriddata(tifivaluelinkcomp(ifilink1).controller.datalist); + end + else begin + {$endif} + po1:= fintf.getdefaultvalue; + if fdata <> nil then begin + if dl1 <> nil then begin //from streaming + if dl1 <> fdata then begin + fdata.assign(dl1); + end + else begin + dl1:= nil; + end; + end + else begin + if po1 <> nil then begin + tdatalist1(fdata).internalfill(fcellinfo.grid.rowcount,po1^); + end + else begin + fdata.count:= fcellinfo.grid.rowcount; + end; + end; + fdata.maxcount:= fcellinfo.grid.rowcountmax; + fdata.onitemchange:= {$ifdef FPC}@{$endif}itemchanged; + end; + {$ifdef mse_with_ifi} + end; + {$endif} + if gs_isdb in tcustomgrid1(fcellinfo.grid).fstate then begin + datasourcechanged; + end; + sourcenamechanged(-1); + tcustomgrid1(fcellinfo.grid).layoutchanged; + end + else begin + fwidgetname:= ''; + fintf:= nil; + if (dl1 <> nil) and (dls_remote in dl1.state) then begin + dl1:= nil; //no free + end; + end; + finally + dl1.free; + end; +end; + +procedure twidgetcol.getdata(var arow: integer; var dest); +var + datatype: listdatatypety; + info: cellinfoty; + po1: pointer; +begin + if arow = -1 then begin + arow:= twidgetgrid(fcellinfo.grid).ffocusedcell.row; + end; + if fdata <> nil then begin + if (arow >= 0) and (arow < fdata.count) then begin + tdatalist1(fdata).getgriddata(arow,dest); + end + else begin + tdatalist1(fdata).getgriddefaultdata(dest); + end; + end + else begin + if fintf <> nil then begin + datatype:= fintf.getdatalistclass.datatype; + if arow >= 0 then begin + info.cell.row:= arow; + po1:= fintf.getrowdatapo(info.cell.row); + end + else begin + po1:= nil; + end; + case datatype of + dl_integer: begin + if po1 = nil then begin + integer(dest):= 0; + end + else begin + integer(dest):= pinteger(po1)^; + end; + end; + dl_real: begin + if po1 = nil then begin + real(dest):= emptyreal; + end + else begin + real(dest):= preal(po1)^; + end; + end; + dl_datetime: begin + if po1 = nil then begin + tdatetime(dest):= emptydatetime; + end + else begin + tdatetime(dest):= pdatetime(po1)^; + end; + end; + dl_msestring: begin + if po1 = nil then begin + msestring(dest):= fintf.getnulltext; + end + else begin + msestring(dest):= pmsestring(po1)^; + end; + end; + dl_ansistring: begin + if po1 = nil then begin + ansistring(dest):= ''; + end + else begin + ansistring(dest):= pansistring(po1)^; + end; + end; + end; + end; + end; +end; + +procedure twidgetcol.setdata(var arow: integer; const source; + const noinvalidate: boolean = false); +begin + if fdata <> nil then begin + if arow = -1 then begin + arow:= twidgetgrid(fcellinfo.grid).ffocusedcell.row; + end; + if arow >= 0 then begin + if noinvalidate then begin + fdata.beginupdate; + end; + tdatalist1(fdata).setgriddata(arow,source); + if (arow = twidgetgrid(fcellinfo.grid).ffocusedcell.row) and + (fintf <> nil) then begin + fintf.gridtovalue(arow); + end; + if noinvalidate then begin + fdata.decupdate; + if (not fdata.updating) and assigned(fonchange) then begin + fonchange(self,arow); + end; + end; + end; + end + else begin + if assigned(fonchange) then begin + fonchange(self,arow); + end; + end; + datachange(arow); +end; + +function twidgetcol.empty(arow: integer): boolean; +begin + result:= true; + if fdata <> nil then begin + if arow = -1 then begin + arow:= twidgetgrid(fcellinfo.grid).ffocusedcell.row; + end; + if arow >= 0 then begin + result:= tdatalist1(fdata).empty(arow); + end; + end; +end; + +function twidgetcol.cangridcopy: boolean; +begin + result:= tcustomwidgetgrid(fcellinfo.grid).datacols.hasselection; +end; + +procedure twidgetcol.updateeditoptions(var aoptions: optionseditty; + const aoptions1: optionsedit1ty); +begin + if not (gps_readonlyupdating in fstate) then begin + updatebit(longword(foptions),ord(co_readonly),oe_readonly in aoptions); + updatebit(longword(foptions),ord(co_savevalue),oe1_savevalue in aoptions1); + end; +end; + +function twidgetcol.showcaretrect(const arect: rectty; + const aframe: tcustomframe): pointty; +begin + result:= grid.showcaretrect(makerect(translateclientpoint(arect.pos, + fintf.getwidget,fcellinfo.grid),arect.size),aframe); +end; + +procedure twidgetcol.widgetpainted(const canvas: tcanvas); +begin + if (co_drawfocus in self.foptions) or fintf.needscellfocuspaint() then begin + with fintf.getwidget() do begin + if active then begin + drawfocusrect(canvas,inflaterect(paintrect,self.ffocusrectdist)); + end; + end; + end; +end; + +function twidgetcol.getdatapo(const arow: integer): pointer; +begin + if (fdata = nil) then begin + result:= nil; + if fintf <> nil then begin + result:= fintf.getrowdatapo(arow); + end; + end + else begin + result:= inherited getdatapo(arow); + end; +end; + +procedure twidgetcol.drawcell(const canvas: tcanvas); +var + face1: tcustomface; +begin + with cellinfoty(canvas.drawinfopo^) do begin + inherited; + if fintf <> nil then begin + if calcautocellsize then begin + fintf.updateautocellsize(canvas); + end + else begin + if (fface = nil) then begin + face1:= fintf.getwidget.face; + if face1 <> nil then begin + face1.paint(canvas,cellinfoty(canvas.drawinfopo^).rect); + end; + end; + fintf.drawcell(canvas); + end; + end; + if assigned(fondrawcell) then begin + fondrawcell(self,canvas,cellinfoty(canvas.drawinfopo^)); + end; + end; +end; + +function twidgetcol.getrow: integer; +begin + result:= twidgetgrid(fcellinfo.grid).factiverow; +end; + +procedure twidgetcol.setrow(arow: integer); +begin + with twidgetgrid(fcellinfo.grid) do begin + focuscell(makegridcoord(colindex,arow)); + end; +end; + +function twidgetcol.getcol: twidgetcol; +begin + result:= self; +end; +{ +procedure twidgetcol.cellchanged(const row: integer); +var + int1: integer; +begin + inherited; + if (fintf <> nil) and (fdata <> nil) then begin + int1:= fgrid.row; + if (int1 >= 0) and ((row = int1) or (row < 0)) and (int1 < fdata.count) and + not (gs_rowremoving in tcustomgrid1(fgrid).fstate) then begin + fintf.gridtovalue(int1); + end; + end; +end; +} +{ +procedure twidgetcol.changed; +begin + inherited; + if (fintf <> nil) and (fgrid.row >= 0) then begin + fintf.gridtovalue(fgrid.row); + end; +end; +} +function twidgetcol.getinnerframe: framety; +begin + if fintf <> nil then begin + result:= fintf.getcellframe; + end + else begin + result:= inherited getinnerframe; + end; +end; + +function twidgetcol.geteditwidget: twidget; +begin + if fintf = nil then begin + result:= nil; + end + else begin + result:= fintf.getwidget; + end; +end; + +procedure twidgetcol.seteditwidget(const value: twidget); +begin + setwidget(value); + if value <> nil then begin + value.parentwidget:= twidgetgrid(fcellinfo.grid).fcontainer2; + end; +end; + +procedure twidgetcol.drawfocusedcell(const acanvas: tcanvas); +var + size1: sizety; +begin + with tcustomwidgetgrid(fcellinfo.grid) do begin + if (factivewidget = nil) or not factivewidget.visible then begin + inherited; + end + else begin + with fcellinfo do begin + if calcautocellsize and (fintf <> nil) then begin + size1:= rect.size; + fintf.getautocellsize(acanvas,size1); + if size1.cx > autocellsize.cx then begin + autocellsize.cx:= size1.cx; + end; + if size1.cy > autocellsize.cy then begin + autocellsize.cy:= size1.cy; + end; + end; + end; + end + end; +end; + +procedure twidgetcol.drawfocus(const acanvas: tcanvas); +begin + with tcustomwidgetgrid(fcellinfo.grid) do begin + if (factivewidget = nil) or not factivewidget.visible then begin + inherited; + end; + end; + //else no paint, done in widgetpainted +end; + +function twidgetcol.sortcompare(const index1,index2: integer): integer; +begin + result:= 0; + if (fintf <> nil) then begin + if fdata <> nil then begin + with tdatalist1(fdata) do begin + result:= fintf.sortfunc((fdatapo+index1*fsize)^,(fdatapo+index2*fsize)^); + end; + end; + end + else begin + result:= inherited sortcompare(index1,index2); + end; +end; + +procedure twidgetcol.itemchanged(const sender: tdatalist; const aindex: integer); +begin + inherited; + if {(tcustomwidgetgrid(fgrid).fupdating = 0) and} (fintf <> nil) and + not (gs_rowremoving in tcustomgrid1(fcellinfo.grid).fstate) and + not (gps_changelock in fstate)then begin + fintf.gridvaluechanged(aindex); + if ((aindex < 0) or (aindex = grid.row)) and (grid.row >= 0) then begin + fintf.gridtovalue(aindex); + end; + end; +end; + +function twidgetcol.actualfont: tfont; +begin + result:= nil; + if fintf <> nil then begin + with twidget1(fintf.getwidget) do begin + result:= ffont; + end; + end; + if result = nil then begin + result:= inherited actualfont; + end; +end; + +procedure twidgetcol.setoptions(const avalue: coloptionsty); +//var +// aoptions: coloptionsty; +begin +// aoptions:= avalue; +// inherited setoptions(aoptions); + inherited; + if fintf <> nil then begin + fintf.updatecoloptions(foptions); + end; +end; + +procedure twidgetcol.setoptions1(const avalue: coloptions1ty); +begin + inherited; + if fintf <> nil then begin + fintf.updatecoloptions1(foptions1); + end; +end; + +function twidgetcol.getcursor(const arow: integer; + const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; +begin + result:= inherited getcursor(arow,actcellzone,amousepos); + if (result = cr_default) and (fintf <> nil){ and + not (co_readonly in foptions)} then begin + result:= fintf.getcellcursor(arow,actcellzone,amousepos); + end; +end; + +procedure twidgetcol.datasourcechanged; +begin + if fintf <> nil then begin + fintf.griddatasourcechanged; + end; +end; + +function twidgetcol.nullcheckneeded(const newfocus: twidget): boolean; +begin + with twidgetgrid(fcellinfo.grid) do begin + result:= not (gs_isdb in fstate) and (fnonullcheck = 0) and ( + not (fcontainer1.checkdescendent(newfocus) or + fcontainer3.checkdescendent(newfocus))) and + (row >= 0) and not (gs_rowremoving in fstate) and + ((gs1_forcenullcheck in fstate1) or + not ((row = rowhigh) and isautoappend or + isinsertempty)); + end; +end; + +function twidgetcol.nonullcheck: boolean; +begin + result:= tcustomgrid1(fcellinfo.grid).fnonullcheck > 0; +end; + +function twidgetcol.nocheckvalue: boolean; +begin + with tcustomgrid1(fcellinfo.grid) do begin + result:= (fnocheckvalue > 0) or (gs_rowremoving in fstate); + end; +end; + +{$ifdef mse_with_ifi} +procedure twidgetcol.updateifigriddata(const alist: tdatalist); +begin + if (fdata <> nil) and not (dls_remote in fdata.state) {and + (alist <> nil)} then begin + freeandnil(fdata); //free internal datalist + end; + if not (csdesigning in fcellinfo.grid.componentstate) then begin + setremotedatalist(idatalistclient(self),alist,fdata); + end; +end; +{$endif} + +function twidgetcol.getgrid: tcustomwidgetgrid; +begin + result:= tcustomwidgetgrid(fcellinfo.grid); +end; + +procedure twidgetcol.edited(); +begin + tcustomwidgetgrid(fcellinfo.grid).doedited(); +end; + +function twidgetcol.getbrushorigin: pointty; +begin + result:= tcustomwidgetgrid(fcellinfo.grid).fbrushorigin; +end; + +procedure twidgetcol.beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + if fintf <> nil then begin + fintf.beforecelldragevent(ainfo,arow,processed); + end; +end; + +procedure twidgetcol.afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + if fintf <> nil then begin + fintf.aftercelldragevent(ainfo,arow,processed); + end; +end; + +procedure twidgetcol.updatecellzone(const row: integer; const pos: pointty; var result: cellzonety); +begin + inherited; + if fintf <> nil then begin + fintf.updatecellzone(row,pos,result); + end; +end; + +procedure twidgetcol.sourcenamechanged(const atag: integer); +var + datalist1: tdatalist; + str1: string; + int1: integer; +begin + if fdata <> nil then begin + if atag >= 0 then begin + str1:= fdata.getsourcename(atag); + datalist1:= nil; + if str1 <> '' then begin + datalist1:= fcellinfo.grid.datacols.datalistbyname(str1); + end; + fdata.linksource(datalist1,atag); + end + else begin + for int1:= 0 to fdata.getsourcecount-1 do begin + str1:= fdata.getsourcename(int1); //link all source lists + datalist1:= nil; + if str1 <> '' then begin + datalist1:= fcellinfo.grid.datacols.datalistbyname(str1); + end; + fdata.linksource(datalist1,int1); + end; + end; + end; +end; + +function twidgetcol.getfixrowwidgets(aindex: integer): twidget; +var + i1: int32; +begin + i1:= -1-aindex; + checkarrayindex(ffixrowwidgets,i1); + result:= ffixrowwidgets[i1]; +end; + +procedure twidgetcol.setfixrowwidgets(aindex: integer; const avalue: twidget); +begin + checkarrayindex(ffixrowwidgets,-1-aindex); + setfixrowwidget(avalue,aindex); +end; + +{ twidgetcols } + +constructor twidgetcols.create(const aowner: tcustomwidgetgrid); +begin + inherited create(aowner,twidgetcol); +end; + +class function twidgetcols.getitemclasstype: persistentclassty; +begin + result:= twidgetcol; +end; + +procedure twidgetcols.datasourcechanged; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + cols[int1].datasourcechanged; + end; +end; + +function twidgetcols.getcols(const index: integer): twidgetcol; +begin + result:= twidgetcol(items[index]); +end; + +procedure twidgetcols.unregisterchildwidget(const child: twidget); +var + int1: integer; +begin + with twidgetgrid(fgrid) do begin + if factivewidget = child then begin + factivewidget:= nil; + end; + end; + int1:= 0; + if not (gs_layoutupdating in tcustomwidgetgrid(fgrid).fstate) then begin + while int1 < count do begin + with cols[int1] do begin + if (fintf <> nil) and (fintf.getwidget = child) then begin + setwidget(nil); + delete(int1); + end + else begin + inc(int1); + end; + end; + end; + end; +end; + +procedure twidgetcols.updatedatastate(var accepted: boolean); +var + int1: integer; +begin + if not (csdestroying in fgrid.componentstate) and + not (gs1_rowdeleting in twidgetgrid(fgrid).fstate1)then begin + for int1:= 0 to count - 1 do begin + if not accepted then begin + break; + end; + cols[int1].checkcanclose(accepted); + end; + end; + inherited; +end; + +procedure twidgetcols.updatecolorder; +var + ar1,ar2: widgetcolarty; + int1,int2: integer; +begin + if (count > 0) and (fcolorder <> nil) then begin //inherited + if length(fcolorder) > count then begin + fcolcount:= length(fcolorder); + inherited setcount1(fcolcount,true); + end; + ar1:= widgetcolarty(copy(fitems)); + setlength(ar2,fcolcount); //new count + setlength(fcolorder,fcolcount); + for int1:= 0 to high(fcolorder) do begin + if fcolorder[int1] <> '' then begin + for int2:= 0 to high(ar1) do begin + if (ar1[int2] <> nil) and + (ar1[int2].fwidgetname = fcolorder[int1]) then begin + ar2[int1]:= ar1[int2]; + ar1[int2]:= nil; + break; + end; + end; + end; + end; + int2:= 0; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] <> nil) and + (ar1[int1].fwidgetname <> '') then begin + //new inherited widget + additem(pointerarty(ar2),ar1[int1]); + ar1[int1]:= nil; + end; + end; + int1:= length(ar2)-fcolcount; + if int1 > 0 then begin + fcolcount:= length(ar2); + int2:= count; + inherited setcount1(int2+int1,true); + setlength(ar1,length(fitems)); + for int1:= int2 to high(fitems) do begin + ar1[int1]:= twidgetcol(fitems[int1]); //new inherited + end; + end; + int2:= 0; + for int1:= 0 to high(ar2) do begin + if ar2[int1] = nil then begin + while ar1[int2] = nil do begin + inc(int2); + end; + ar2[int1]:= ar1[int2]; //new + ar1[int2]:= nil; + end; + end; + for int1:= 0 to high(ar1) do begin + ar1[int1].free; //not used + end; + fitems:= persistentarty(ar2); + fcolorder:= nil; + clearorder; //new order is default + end + else begin + inherited setcount1(fcolcount,true); + end; +end; + +procedure twidgetcols.setcount1(acount: integer; doinit: boolean); +begin + fcolcount:= acount; + if (acount = 0) or + not ((fgrid.componentstate*[csdesigning,csreading] = [csdesigning,csreading]) + and (acount < count)) then begin + inherited; //else delay to updatecolorder, possibly refreshing inherited + end; +end; + +procedure twidgetcols.readorder(reader: treader); +begin + readstringar(reader,fcolorder); + updatecolorder; +end; + +procedure twidgetcols.writeorder(writer: twriter); +var + ar1: stringarty; + int1: integer; +begin + setlength(ar1,count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= twidgetcol(fitems[int1]).fwidgetname; + end; + writestringar(writer,ar1); +end; + +procedure twidgetcols.defineproperties(filer: tfiler); +var + bo1: boolean; + int1: integer; +begin + bo1:= (filer is twriter) and (twriter(filer).ancestor <> nil); + if bo1 then begin + with twidgetcols(twriter(filer).ancestor) do begin + if count = self.count then begin + bo1:= false; + for int1:= 0 to count-1 do begin + if twidgetcol(fitems[int1]).fwidgetname <> + twidgetcol(self.fitems[int1]).fwidgetname then begin + bo1:= true; + break; + end; + end; + end; + end; + end; + filer.defineproperty('colorder',{$ifdef FPC}@{$endif}readorder, + {$ifdef FPC}@{$endif}writeorder,bo1); + inherited; +end; + +function twidgetcols.getcollectionname(const aindex: integer): string; +begin + result:= twidgetcol(fitems[aindex]).fwidgetname; +end; + +{ twidgetfixcol } + +constructor twidgetfixcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + setlength(ffixrowwidgets,agrid.fixrows.count); + inherited; +end; + +destructor twidgetfixcol.destroy; +var + int1: integer; +begin + if not (csdestroying in fcellinfo.grid.componentstate) then begin + for int1:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int1] <> nil then begin + freedesigncomponent(ffixrowwidgets[int1]); + //inhibit deleting of inherited widget + end; + end; + end; + inherited; +end; + +procedure twidgetfixcol.readfixwidgetnames(reader: treader); +begin + readstringar(reader,ffixrowwidgetnames); +end; + +procedure twidgetfixcol.writefixwidgetnames(writer: twriter); +begin + writewidgetnames(writer,ffixrowwidgets); +end; + +procedure twidgetfixcol.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('fixwidgetnames',{$ifdef FPC}@{$endif}readfixwidgetnames, + {$ifdef FPC}@{$endif}writefixwidgetnames, + (filer.ancestor = nil) and needswidgetnamewriting(ffixrowwidgets) or + (filer.ancestor <> nil) and + needswidgetnamewriting(ffixrowwidgets, + twidgetfixcol(filer.ancestor).ffixrowwidgets)); +end; + +procedure twidgetfixcol.setfixrowwidget(const awidget: twidget; const rowindex: integer); +begin + tcustomwidgetgrid(fcellinfo.grid).removefixwidget(awidget); + ffixrowwidgets[-rowindex-1]:= awidget; + fcellinfo.grid.layoutchanged; +end; + +function twidgetfixcol.getfixrowwidgets(aindex: integer): twidget; +var + i1: int32; +begin + i1:= -1-aindex; + checkarrayindex(ffixrowwidgets,i1); + result:= ffixrowwidgets[i1]; +end; + +procedure twidgetfixcol.setfixrowwidgets(aindex: integer; + const avalue: twidget); +begin + checkarrayindex(ffixrowwidgets,-1-aindex); + setfixrowwidget(avalue,aindex); +end; + +{ twidgetfixcols } + +constructor twidgetfixcols.create(const aowner: tcustomwidgetgrid); +begin + inherited create(aowner); + fitemclasstype:= twidgetfixcol; +end; + +function twidgetfixcols.getcols(const index: integer): twidgetfixcol; +begin + result:= twidgetfixcol(inherited cols[index]); +end; + +procedure twidgetfixcols.unregisterchildwidget(const child: twidget); +var + int1,int2: integer; +begin + if not (csdestroying in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + with twidgetfixcol(items[int1]) do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = child then begin + ffixrowwidgets[int2]:= nil; + break; + end; + end; + end; + end; + end; +end; + +{ tdummywidget } + +constructor tdummywidget.create(aowner: tcomponent); +begin + inherited; + foptionswidget:= defaultoptionswidgetnofocus; + exclude(fwidgetstate,ws_iswidget); + size:= nullsize; +end; + +function tdummywidget.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_dummy]; +end; + +function tdummywidget.setfocus(aactivate: boolean = true): boolean; +begin + if canfocus then begin + result:= inherited setfocus(aactivate); + end + else begin + window.nofocus; + result:= false; + end; +end; + +{ tcontainer1 } + +procedure tcontainer1.doexit; +begin +// if fgrid.factivewidget <> nil then begin +// fgrid.factivewidget.visible:= false; +// end; + inherited; +end; + +procedure tcontainer1.doenter; +begin + if fgrid.factivewidget <> nil then begin + fgrid.factivewidget.visible:= true; + end; + inherited; +end; + +function tcontainer1.getiassistiveclient(): iassistiveclient; +begin +// result:= iassistiveclientgrid(fgrid); + result:= fgrid.getiassistiveclient(); +end; + +{ +procedure tcontainer1.registerchildwidget(const child: twidget); +var + int1: integer; +begin + if ws1_oldautoscale in twidget1(child).fwidgetstate1 then begin + foldautoscale:= true; + end; + if foldautoscale then begin + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + if not (ws1_oldautoscale in fwidgetstate1) then begin + exclude(foptionswidget1,ow1_autoscale); + end; + end; + end; + end; + inherited; +end; +} +{ tfixcontainer } + +constructor tfixcontainer.create(aowner: tcustomwidgetgrid); +begin + fgrid:= aowner; + inherited create({nil}aowner); + include(fwidgetstate,ws_nopaint); + exclude(fwidgetstate,ws_opaque); + exclude(fwidgetstate,ws_iswidget); + foptionswidget:= foptionswidget + + [ow_mousetransparent,ow_arrowfocusin,ow_arrowfocusout,ow_subfocus, + ow_focusbackonesc]; + setlockedparentwidget(aowner); +// parentwidget:= aowner; +end; + +procedure tfixcontainer.unregisterchildwidget(const child: twidget); +begin + twidgetfixrows(fgrid.ffixrows).unregisterchildwidget(child); + inherited; +end; + +procedure handlewidgetregionchanged(const self: twidget; + const grid: tcustomwidgetgrid; const sender: twidget); +var + cell1,cell2: gridcoordty; + int1,int2,int3: integer; + pt1: pointty; +begin + with self do begin + if not (gs_layoutupdating in grid.fstate) and (sender <> nil) and + (grid.componentstate * [csdesigning,csdestroying] = [csdesigning]) and + (not (csloading in grid.componentstate) or + (ws1_autoscaling in twidget1(sender).fwidgetstate1)) and + (twidget1(sender).fparentwidget = self) then begin + with grid do begin + cell1:= widgetcell(sender); + if cell1.row <> invalidaxis then begin + if self = grid then begin + pt1:= self.paintpos; + pt1.x:= -pt1.x; + pt1.y:= -pt1.y; + end + else begin + pt1:= self.parentpaintpos; + end; + if (cellatpos(addpoint( + rectcenter(sender.widgetrect),pt1),cell2) in + [ck_fixrow,ck_fixcolrow]) and + ((cell1.col <> cell2.col) or (cell1.row <> cell2.row)) and + (cellwidget(cell2) = nil) then begin + if cell1.col >= 0 then begin + datacols[cell1.col].ffixrowwidgets[-1-cell1.row]:= nil; + end + else begin + fixcols[cell1.col].ffixrowwidgets[-1-cell1.row]:= nil; + end; + if cell2.col >= 0 then begin + datacols[cell2.col].ffixrowwidgets[-1-cell2.row]:= sender; + end + else begin + fixcols[cell2.col].ffixrowwidgets[-1-cell2.row]:= sender; + end; + end + else begin + with ffixrows[cell1.row] do begin + height:= sender.bounds_cy; + int1:= 0; + int3:= 0; + if cell1.col < 0 then begin + int2:= -1-cell1.col; + if (int2 < captionsfix.count) and (int2 >= 0) then begin + with captionsfix[cell1.col] do begin + int1:= mergedcx; + int3:= mergedcy; + end; + end; + ffixcols[cell1.col].width:= sender.bounds_cx - int1; + end + else begin + if cell1.col < captions.count then begin + with captions[cell1.col] do begin + int1:= mergedcx; + int3:= mergedcy; + end; + end; + fdatacols[cell1.col].width:= sender.bounds_cx - int1; + end; + height:= sender.bounds_cy - int3; + end; + end; + layoutchanged; + end; + end; + end; + end; +end; + +procedure tfixcontainer.widgetregionchanged(const sender: twidget); +begin + inherited; + handlewidgetregionchanged(self,fgrid,sender); +end; + +procedure tfixcontainer.dochildfocused(const sender: twidget); +begin + inherited; + fgrid.showcell(fgrid.widgetcell(sender)); +end; + +procedure tfixcontainer.doenter; +begin + fgrid.flastfocusedfixwidget:= self; + inherited; +end; + +function tfixcontainer.focusback(const aactivate: boolean = true): boolean; +begin + if (fgrid.factivewidget <> nil) and + (og_containerfocusbackonesc in fgrid.foptionsgrid) then begin + fgrid.factivewidget.activate; + result:= true; + end + else begin + result:= inherited focusback(aactivate); + end; +end; + +{ twidgetdummy } + +constructor twidgetdummy.create(aowner: tcustomwidgetgrid); +begin + fgrid:= aowner; + inherited create(nil{aowner}); + foptionswidget:= []; + include(fwidgetstate,ws_nopaint); + exclude(fwidgetstate,ws_iswidget); + widgetrect:= nullrect; + parentwidget:= aowner.fcontainer2; +end; + +{ tgridcontainer } + +constructor tgridcontainer.create(aowner: tcustomwidgetgrid); +begin + fgrid:= aowner; + inherited create(nil{aowner}); + include(fwidgetstate,ws_nopaint); + exclude(fwidgetstate,ws_opaque); + exclude(fwidgetstate,ws_iswidget); + foptionswidget:= foptionswidget + [ow_mousetransparent, + ow_subfocus,ow_focusbackonesc]; + foptionswidget:= foptionswidget - [ow_tabfocus]; + setlockedparentwidget(aowner); +// parentwidget:= aowner; +end; + +procedure tgridcontainer.unregisterchildwidget(const child: twidget); +begin + twidgetcols(fgrid.fdatacols).unregisterchildwidget(child); + inherited; +end; + +procedure tgridcontainer.dofocus; +begin + if fgrid.factivewidget = nil then begin + fgrid.setfocus; + end + else begin + fgrid.factivewidget.visible:= true; + inherited; + end; +end; + +function tgridcontainer.focusback(const aactivate: boolean = true): boolean; +begin + if fgrid.flastfocusedfixwidget <> nil then begin + fgrid.flastfocusedfixwidget.setfocus(aactivate); + result:= true; + end + else begin + result:= inherited focusback(aactivate); + end; +end; + +procedure tgridcontainer.doenter; +begin + fgrid.invalidatefocusedcell; + inherited; +end; + +procedure tgridcontainer.doexit; +begin + fgrid.invalidatefocusedcell; + inherited; +end; + +{ tscrollgridcontainer } + +procedure tscrollgridcontainer.widgetregionchanged(const sender: twidget); +var + int1,int2,int3,int4: integer; + po1: pointty; + rect1: rectty; + firstscroll,lastscroll: integer; +begin + if not (csdestroying in fgrid.componentstate) then begin + inherited; + if not (gs_layoutupdating in fgrid.fstate) and (sender <> nil) and + (fgrid.componentstate * [csdesigning,csdestroying] = [csdesigning]) and + (not (csloading in fgrid.componentstate) or + (ws1_autoscaling in twidget1(sender).fwidgetstate1)) and + (flayoutupdating = 0) and + (twidget1(sender).fparentwidget = self) then begin + with fgrid do begin + int3:= -1; + for int1:= 0 to datacols.count-1 do begin + with datacols[int1] do begin + if sender = editwidget then begin + int3:= int1; + break; + end; + end + end; + if int3 >= 0 then begin + int4:= sender.bounds_cy; //updatelayout modifies widgetrect + rect1:= cellrect(makegridcoord(0,0)); + po1:= translatepaintpoint(nullpoint,sender,fgrid); + int2:= datacols.count; + for int1:= 0 to datacols.count-1 do begin + with datacols[int1] do begin + if po1.x < rect1.x + width div 2 then begin + int2:= int1; + break; + end; + inc(rect1.x,step); + end; + end; + if int2 > int3 then begin + dec(int2); + end; + inc(flayoutupdating); + try + sender.bounds_cy:= int4; + datarowheight:= int4; + datacols[int3].width:= sender.bounds_cx; + layoutchanged; + firstscroll:= bigint; + if int2 <> int3 then begin + for int1:= 0 to datacols.count-1 do begin + if tdatacol1(twidgetcols(fdatacols).fitems[int1]).scrollable() then begin + firstscroll:= int1; + break; + end; + end; + lastscroll:= -1; + for int1:= datacols.count-1 downto 0 do begin + if tdatacol1(twidgetcols(fdatacols).fitems[int1]).scrollable() then begin + lastscroll:= int1; + break; + end; + end; + if tdatacol1(twidgetcols(datacols).fitems[int3]).scrollable() then begin + if int2 > int3 then begin //scrollable to right + if int2 > lastscroll then begin + int2:= lastscroll; + end; + end + else begin + if int2 <= firstscroll then begin //scrolable to left + int2:= firstscroll; + end; + end; + end + else begin + if int2 > int3 then begin //fix to right + if int2 >= firstscroll then begin + if int2 < lastscroll then begin + int2:= lastscroll; + end; + end; + end + else begin //fix to left + if int2 <= lastscroll then begin + if int2 > firstscroll then begin + int2:= firstscroll; + end; + end; + end; + end; + if int3 <> int2 then begin + movecol(int3,int2); + end; + end; + finally + dec(flayoutupdating); + end; + end; + internalupdatelayout; + //updatelayout; + end; + end; + end; +end; + +{ tnoscrollgridcontainer } +{ +constructor tnoscrollgridcontainer.create(aowner: tcustomwidgetgrid); +begin + inherited; + optionswidget:= optionswidget - [ow_arrowfocusin]; +end; +} +{ tcustomwidgetgrid } + +constructor tcustomwidgetgrid.create(aowner: tcomponent); +begin +// fmousefocusedcell.col:= -1; + inherited; + fcontainer0:= tnoscrollgridcontainer.create(self); + fcontainer0.name:= '_co0'; //debug purpose + fcontainer1:= ttopcontainer.create(self); + fcontainer1.name:= '_co1'; //debug purpose + fcontainer2:= tscrollgridcontainer.create(self); + fcontainer2.name:= '_co2'; //debug purpose + fcontainer3:= tbottomcontainer.create(self); + fcontainer3.name:= '_co3'; //debug purpose + fwidgetdummy:= tdummywidget.create(self); + include(fstate,gs_layoutupdating); + fwidgetdummy.setlockedparentwidget(fcontainer2); + exclude(fstate,gs_layoutupdating); +// fwidgetdummy.parentwidget:= fcontainer2; + setoptionsgrid(foptionsgrid); //synchronize container +// fcontainer.Name:= 'container'; +end; + +destructor tcustomwidgetgrid.destroy; +begin + flastfocusedfixwidget:= nil; + fwidgetdummy.free; + fcontainer1.free; + freeandnil(fcontainer2); + freeandnil(fcontainer0); + fcontainer3.free; + inherited; +end; + +procedure tcustomwidgetgrid.setoptionsgrid(const avalue: optionsgridty); +begin + if fcontainer2 <> nil then begin + with fcontainer2 do begin + if og_containerfocusbackonesc in avalue then begin + optionswidget:= optionswidget + [ow_focusbackonesc]; + end + else begin + optionswidget:= optionswidget - [ow_focusbackonesc]; + end; + end; + end; + if fcontainer0 <> nil then begin + with fcontainer0 do begin + if og_containerfocusbackonesc in avalue then begin + optionswidget:= optionswidget + [ow_focusbackonesc]; + end + else begin + optionswidget:= optionswidget - [ow_focusbackonesc]; + end; + end; + end; + inherited; +end; + +procedure tcustomwidgetgrid.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= twidgetcol.create(self,fdatacols); +end; + +procedure tcustomwidgetgrid.updatecontainerrect; +var + rect1: rectty; +begin + if fcontainer0 <> nil then begin + rect1:= fdatarecty; + fcontainer0.widgetrect:= moverect(rect1,paintpos); + //for nohscroll widgets + end; + rect1:= fdatarectx; + if fcontainer1 <> nil then begin + rect1.cy:= fdatarect.y - rect1.y; + fcontainer1.widgetrect:= moverect(rect1,paintpos); + end; + if fcontainer3 <> nil then begin + rect1.y:= fdatarect.y + fdatarect.cy; + rect1.cy:= fdatarectx.y + fdatarectx.cy - rect1.y; + fcontainer3.widgetrect:= moverect(rect1,paintpos); + end; + if fcontainer2 <> nil then begin + fcontainer2.widgetrect:= moverect(fdatarect,paintpos); + { + if csdesigning in componentstate then begin + rect1:= fdatarect; +// dec(rect1.x,ffirstnohscroll); +// inc(rect1.cx,ffirstnohscroll); + end + else begin + if noscrollingcol then begin + rect1:= fdatarecty; + end + else begin + rect1:= fdatarect; + end; + end; + fcontainer2.widgetrect:= moverect(rect1,paintpos); + } + end; +end; + +procedure tcustomwidgetgrid.updatelayout; +var + int1: integer; +begin + inherited; + updatecontainerrect; + for int1:= 0 to fdatacols.count - 1 do begin + twidgetcols(fdatacols)[int1].updatewidgetrect + end; + twidgetfixrows(ffixrows).updatewidgetrect; +end; + +procedure tcustomwidgetgrid.dofocusedcellposchanged; +begin + if ffocusedcell.col >= 0 then begin + twidgetcols(fdatacols)[ffocusedcell.col].updatewidgetrect; + end; + inherited; +end; + +procedure tcustomwidgetgrid.dorowsmoved(const fromindex,toindex,count: integer); +var + int1: integer; +begin + if ffocusedcell.col >= 0 then begin + if (focusedcell.row >= toindex) and (focusedcell.row < toindex + count) then begin + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcols(fdatacols)[int1] do begin + if (co_norearange in foptions) and (fintf <> nil) then begin + fintf.gridtovalue(ffocusedcell.row); + end; + end; + end; + end; + end; + inherited; +end; + +function tcustomwidgetgrid.getdatacols: twidgetcols; +begin + result:= twidgetcols(fdatacols); +end; + +procedure tcustomwidgetgrid.setdatacols(const avalue: twidgetcols); +begin + inherited; +end; + +function tcustomwidgetgrid.getfixcols: twidgetfixcols; +begin + result:= twidgetfixcols(ffixcols); +end; + +procedure tcustomwidgetgrid.setfixcols(const avalue: twidgetfixcols); +begin + inherited; +end; + +function tcustomwidgetgrid.getfixrows: twidgetfixrows; +begin + result:= twidgetfixrows(ffixrows); +end; + +procedure tcustomwidgetgrid.setfixrows(const avalue: twidgetfixrows); +begin + inherited; +end; + +procedure tcustomwidgetgrid.insertwidget(const awidget: twidget; + const apos: pointty); +var + po1: pointty; + cell1,cell2: gridcoordty; + intf: igridwidget; + leftnohscroll,rightnohscroll: boolean; +begin + if not (csloading in componentstate) then begin + internalupdatelayout; + po1:= subpoint(apos,paintpos); + cell1:= cellatpos(po1); + if (cell1.row <> invalidaxis) and (cell1.col <> invalidaxis) and + (cell1.row < 0) then begin + if not checkdescendent(awidget) then begin //new insert + exclude(twidget1(awidget).foptionswidget1,ow1_autoscale); + end; + if cell1.col >= 0 then begin + datacols[cell1.col].setfixrowwidget(awidget,cell1.row); + end + else begin + fixcols[cell1.col].setfixrowwidget(awidget,cell1.row); + end; + end + else begin + if (cell1.col >= 0) or (cell1.col = invalidaxis) then begin + if not checkdescendent(awidget) then begin //new insert + if not awidget.getcorbainterface(typeinfo(igridwidget),intf) then begin + error(gre_invalidwidget); + end; + if cell1.col < 0 then begin + cell1.col:= fdatacols.count; + end + else begin + with twidgetcol(fdatacols[cell1.col]) do begin + po1.x:= po1.x + (fend - fstart) div 2; + cell2:= cellatpos(po1); + if cell2.col <> cell1.col then begin + inc(cell1.col); //next col + end; + end; + end; + fdatacols.insertdefault(cell1.col); + leftnohscroll:= false; + rightnohscroll:= false; + if cell1.col > 0 then begin + leftnohscroll:= co_nohscroll in fdatacols[cell1.col-1].options; + end; + if cell1.col < datacols.count-1 then begin + rightnohscroll:= co_nohscroll in fdatacols[cell1.col+1].options; + end; + if cell1.col = 0 then begin + leftnohscroll:= rightnohscroll; + end; + if cell1.col = datacols.count-1 then begin + rightnohscroll:= leftnohscroll; + end; + if leftnohscroll and rightnohscroll then begin + fdatacols[cell1.col].options:= fdatacols[cell1.col].options + + [co_nohscroll]; + end; + awidget.parentwidget:= fcontainer2; + datacols[cell1.col].setwidget(awidget); + intf.initgridwidget; + end; + end + else begin + inherited; + end; + end; + end + else begin + inherited; + end; +end; + +function tcustomwidgetgrid.editwidgetatpos(const apos: pointty; + out cell: gridcoordty): twidget; +begin + if cellatpos(apos,cell) = ck_data then begin + result:= datacols[cell.col].editwidget; + end + else begin + result:= nil; + end; +end; + +function tcustomwidgetgrid.widgetcell(const awidget: twidget): gridcoordty; +var + int1,int2{,int3}: integer; +begin + if awidget <> nil then begin + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcol(fdatacols.items[int1]) do begin + if (fintf <> nil) and (fintf.getwidget = awidget) then begin + result.col:= int1; + result.row:= row; + exit; + end; + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = awidget then begin + result.col:= int1; + result.row:= -int2-1; //int2-ffixrows.count; + exit; + end; + end; + end; + end; + for int1:= 0 to ffixcols.count - 1 do begin + with twidgetfixcol(ffixcols.items[int1]) do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = awidget then begin + result.col:= -int1 - 1; //int1 - fixcols.count; + result.row:= -int2 - 1; //int2 - fixrows.count; + exit; + end; + end; + end; + end; + end; + result:= invalidcell; +end; + +function tcustomwidgetgrid.cellwidget(const acell: gridcoordty): twidget; +var + co1,ro1: integer; +begin + result:= nil; + if acell.col >= 0 then begin + if acell.col < fdatacols.count then begin + if acell.row >= 0 then begin + if acell.row < rowcount then begin + result:= datacols[acell.col].editwidget; + end; + end + else begin + ro1:= -1-acell.row; + with datacols[acell.col] do begin + if ro1 <= high(ffixrowwidgets) then begin + result:= ffixrowwidgets[ro1]; + end; + end; + end; + end; + end + else begin + co1:= -1-acell.col; + if (co1 < fixcols.count) and (acell.row < 0) then begin + ro1:= -1-acell.row; + with twidgetfixcol(twidgetfixcols(ffixcols).fitems[co1]) do begin + if ro1 <= high(ffixrowwidgets) then begin + result:= ffixrowwidgets[ro1]; + end; + end; + end; + end; +end; + +function tcustomwidgetgrid.getcontainer: twidget; +begin + result:= fcontainer2; +end; + +function tcustomwidgetgrid.getchildwidgets(const index: integer): twidget; +var + int1,int2: integer; +begin + int2:= fcontainer2.childrencount; + if index < int2 then begin + result:= fcontainer2.children[index]; + end + else begin + int1:= index - int2; + int2:= fcontainer0.childrencount; + if int1 < int2 then begin + result:= fcontainer0.children[int1]; + end; + int1:= index - int2; + int2:= fcontainer1.childrencount; + if int1 < int2 then begin + result:= fcontainer1.children[int1]; + end + else begin + result:= fcontainer3.children[int1-int2]; + end; + end; +end; + +procedure tcustomwidgetgrid.removefixwidget(const awidget: twidget); +var + int1,int2: integer; +begin + if awidget <> nil then begin + if flastfocusedfixwidget = awidget then begin + flastfocusedfixwidget:= nil; + end; + for int1:= 0 to high(twidgetcols(fdatacols).fitems) do begin + with twidgetcol(twidgetcols(fdatacols).fitems[int1]) do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = awidget then begin + ffixrowwidgets[int2]:= nil; + end; + end; + end; + end; + for int1:= 0 to high(twidgetfixcols(ffixcols).fitems) do begin + with twidgetfixcol(twidgetfixcols(ffixcols).fitems[int1]) do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = awidget then begin + ffixrowwidgets[int2]:= nil; + end; + end; + end; + end; + end; +end; + +function tcustomwidgetgrid.childrencount: integer; +begin + result:= fcontainer0.childrencount + fcontainer2.childrencount + + fcontainer1.childrencount + fcontainer3.childrencount; +end; + +function tcustomwidgetgrid.getlogicalchildren: widgetarty; +begin + result:= inherited getlogicalchildren; + fcontainer1.addlogicalchildren(result); + fcontainer3.addlogicalchildren(result); +end; + +function tcustomwidgetgrid.createdatacols: tdatacols; +begin + result:= twidgetcols.create(self); +end; + +function tcustomwidgetgrid.createfixrows: tfixrows; +begin + result:= twidgetfixrows.create(self); +end; + +function tcustomwidgetgrid.createfixcols: tfixcols; +begin + result:= twidgetfixcols.create(self); +end; + +procedure tcustomwidgetgrid.setoptionswidget(const avalue: optionswidgetty); +begin + inherited setoptionswidget(avalue - [ow_subfocus]); +end; +{ +procedure tcustomwidgetgrid.focusedcellchanged; +begin + inherited; + if col >= 0 then begin + with twidgetcol(twidgetcols(fdatacols).fitems[col]) do begin + updatewidgetrect(true); + end; + end; +end; +} +function tcustomwidgetgrid.checksubfocus(const aactivate: boolean): boolean; +begin + result:= false; + if (factivewidget <> nil) and (factivewidget <> fwidgetdummy) then begin + factivewidget.visible:= true; + if factivewidget.canfocus then begin + factivewidget.setfocus(aactivate); + result:= true; + end; + end; + if not result then begin + result:= inherited checksubfocus(aactivate); + end; +end; +{ +procedure tcustomwidgetgrid.dofocus; +begin + inherited; + if (factivewidget <> nil) and (factivewidget <> fwidgetdummy) then begin + factivewidget.visible:= true; + if factivewidget.canfocus then begin + factivewidget.setfocus(false); + end; + end; +end; +} +procedure tcustomwidgetgrid.unregisterchildwidget(const child: twidget); +begin + twidgetfixrows(ffixrows).unregisterchildwidget(child); + twidgetfixcols(ffixcols).unregisterchildwidget(child); + inherited; +end; + +procedure tcustomwidgetgrid.widgetregionchanged(const sender: twidget); +begin + inherited; + handlewidgetregionchanged(self,self,sender); +end; + +procedure tcustomwidgetgrid.scrolled(const dist: pointty); +var + po1: pointty; + bo1: boolean; +begin + po1:= dist; + if csdesigning in componentstate then begin + po1.y:= 0; + end; + twidget1(fcontainer2).scrollwidgets(po1); + po1.x:= 0; + twidget1(fcontainer0).scrollwidgets(po1); + if dist.x <> 0 then begin + if csdesigning in componentstate then begin + bo1:= gs_layoutupdating in fstate; + include(fstate,gs_layoutupdating); + try + twidgetfixrows(ffixrows).updatewidgetrect; + finally + if not bo1 then begin + exclude(fstate,gs_layoutupdating); + end; + end; + end + else begin + twidgetfixrows(ffixrows).updatewidgetrect; + end; + end; + inherited; +end; + +procedure tcustomwidgetgrid.getchildren(proc: tgetchildproc; root: tcomponent); +begin + inherited; + twidget1(fcontainer2).getchildren(proc,root); + twidget1(fcontainer0).getchildren(proc,root); + twidget1(fcontainer1).getchildren(proc,root); + twidget1(fcontainer3).getchildren(proc,root); +end; +{ +procedure tcustomwidgetgrid.dobeginread; +var + int1: integer; +begin + setlength(fwidgetcolorder,fdatacols.count); + for int1:= 0 to high(fwidgetcolorder) do begin + with fwidgetcolorder[int1], + twidgetcol(twidgetcols(fdatacols).fitems[int1]) do begin + colwidgetname:= fwidgetname; + coldatalist:= fdata; + end; + end; + inherited; +end; +} +procedure tcustomwidgetgrid.doendread; +var + int1,int2,int3: integer; + ar1: widgetarty; +// ar2: array of igridwidget; + str1: string; +// intf1: igridwidget; +begin + twidgetcols(fdatacols).updatecolorder; + inc(tgridcontainer(fcontainer2).flayoutupdating); + include(fstate,gs_layoutupdating); + try + ar1:= copy(fwidgets); + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + for int2:= 0 to high(fwidgets) do begin + additem(pointerarty(ar1),pointer(fwidgets[int2])); + //add children, possibly inherited + end; + end; + end; +{ + if (csdesigning in componentstate) then begin + setlength(ar2,length(ar1)); //init check deleted widgets + for int1:= 0 to high(ar2) do begin + if ar1[int1].getcorbainterface(typeinfo(igridwidget),intf1) and + (intf1.getgridintf <> nil) then begin + ar2[int1]:= intf1; + end; + end; + end; +} + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcols(fdatacols)[int1] do begin + for int2:= 0 to high(ar1) do begin + if ar1[int2] <> nil then begin + str1:= findpastedcomponentname(ar1[int2]); + if str1 = '' then begin + str1:= ar1[int2].name; + end; + if str1 <> '' then begin + if (str1 = fwidgetname) then begin + ar1[int2].parentwidget:= fcontainer2; +// if (csdesigning in componentstate) then begin +// ar2[int2]:= nil; //linked +// end; + fintf:= nil; + //do not remove existing link, inherited order could be changed +{ for int3:= 0 to high(fwidgetcolorder) do begin + with fwidgetcolorder[int3] do begin + if colwidgetname = str1 then begin + fdata:= coldatalist; //repair inherited col order + break; + end; + end; + end; + } + setwidget(ar1[int2]); + ar1[int2]:= nil; + end; + if ar1[int2] <> nil then begin + for int3:= 0 to high(ffixrowwidgetnames) do begin + if str1 = ffixrowwidgetnames[int3] then begin + setfixrowwidget(ar1[int2],-int3-1); + ffixrowwidgetnames[int3]:= ''; + ar1[int2]:= nil; + break; + end; + end; + end; + end; + end; + end; + ffixrowwidgetnames:= nil; + end; + end; +{ + if csdesigning in componentstate then begin //check deleted inherited widgets + for int1:= 0 to high(ar2) do begin + if ar2[int1] <> nil then begin + ar2[int1].setgridintf(nil); + end; + end; + end; +} + for int1:= 0 to fdatacols.count - 1 do begin + twidgetcols(fdatacols)[int1].sourcenamechanged(-1); + end; + for int1:= 0 to ffixcols.count - 1 do begin + with twidgetfixcol(ffixcols.items[int1]) do begin + for int2:= 0 to high(ar1) do begin + if ar1[int2] <> nil then begin + str1:= ar1[int2].name; + if str1 <> '' then begin + for int3:= 0 to high(ffixrowwidgetnames) do begin + if str1 = ffixrowwidgetnames[int3] then begin + setfixrowwidget(ar1[int2],-int3-1); + ffixrowwidgetnames[int3]:= ''; + ar1[int2]:= nil; + break; + end; + end; + end; + end; + end; + end; + end; + finally + exclude(fstate,gs_layoutupdating); + dec(tgridcontainer(fcontainer2).flayoutupdating); + end; + inherited; +end; + +function tcustomwidgetgrid.scrollcaret(const vertical: boolean): boolean; +begin + result:= (factivewidget <> nil) and + ((factivewidget.parentwidget = fcontainer2) or vertical) and + twidget1(factivewidget).hascaret; +end; + +procedure tcustomwidgetgrid.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +var + po1: pointty; +begin + with info do begin + if not (es_reflected in eventstate) then begin + if (eventkind in [ek_mousemove,ek_mousepark, + ek_buttonpress,ek_buttonrelease]) then begin + po1:= translateclientpoint(nullpoint,sender,self); + addpoint1(pos,po1); + if sender.checkancestor(factivewidget) then begin + clientmouseevent(info); + end + else begin + with fobjectpicker do begin + if (sender <> fcontainer2) and (sender <> self) and + ((fpickkind = pok_datacolsize) or + (eventkind <> ek_buttonpress)) then begin + include(fstate,gs_child); + mouseevent(info); + exclude(fstate,gs_child); + if not (fpickkind in [pok_datacolsize,pok_datacol]) then begin + exclude(eventstate,es_processed); + end + else begin + include(eventstate,es_processed); + end; + end; + end; + end; + subpoint1(pos,po1); + end + else begin + if (eventkind = ek_mousecaptureend) and (sender = factivewidget) then begin + clientmouseevent(info); + end; + end; + end + end; + inherited; +end; + +procedure tcustomwidgetgrid.clientmouseevent(var info: mouseeventinfoty); +begin + fmouseinfopo:= @info; + try + inherited; + finally; +// fmouseinfopo:= @info; + fmouseinfopo:= nil; + end; + if (info.eventkind = ek_buttonpress) and + (factivewidget <> nil) and entered then begin + include(info.eventstate,es_nofocus); //do not set focus to grid + end; + if (info.eventkind = ek_buttonrelease) and (info.button = mb_left) and + (gs_childmousecaptured in fstate) then begin + exclude(fstate,gs_childmousecaptured); + releasemouse; + end; +end; + +procedure tcustomwidgetgrid.initcopyars(out dataedits: widgetarty; + out datalists: datalistarty); +var + int1: integer; +begin + setlength(dataedits,datacols.count); + setlength(datalists,length(dataedits)); + for int1:= 0 to high(dataedits) do begin + dataedits[int1]:= datacols[int1].editwidget; + datalists[int1]:= datacols[int1].datalist; + if not (dataedits[int1] is tcustomdataedit) or + not tdataedit1(dataedits[int1]).textcellcopy then begin + dataedits[int1]:= nil; + end; + end; +end; + +function tcustomwidgetgrid.copyselection: boolean; +var + ar2: widgetarty; + ar3: datalistarty; + ar1: gridcoordarty; + wstr1,wstr2: msestring; + int1,int2: integer; + +begin + result:= inherited copyselection; + if result then begin + exit; + end; + ar1:= datacols.selectedcells; + if ar1 <> nil then begin + initcopyars(ar2,ar3); + wstr1:= ''; + int2:= ar1[0].row; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if row <> int2 then begin + removetabterminator(wstr1); + wstr1:= wstr1 + lineend; + int2:= row; + end; + wstr2:= ''; + if co_cancopy in datacols[ar1[int1].col].foptions then begin + if ar2[col] <> nil then begin + with tdataedit1(ar2[col]) do begin + wstr2:= datatotext(ar3[col].getitempo(row)^); + end; + end + else begin + if ar3[col] <> nil then begin + wstr2:= ar3[col].getastext(row); + { + case ar3[col].datatype of + dl_integer: wstr2:= inttostr(tintegerdatalist(ar3[col]).items[row]); + end; + } + end; + end; + wstr1:= wstr1 + wstr2 + c_tab; + end; + end; + end; + removetabterminator(wstr1); + wstr1:= wstr1 + lineend; //terminator + copytoclipboard(wstr1); + result:= true; + end; +end; + +function tcustomwidgetgrid.pasteselection: boolean; +var + ar2: widgetarty; + ar3: datalistarty; + ar1: gridcoordarty; + wstr1: msestring; + int1,int2,int3,int5: integer; + ar4,ar5: msestringarty; + bo1,bo2: boolean; + + procedure setcelltext(const atext: msestring; const acol,arow: integer); + begin + if ar2[acol] <> nil then begin + if ar3[acol] <> nil then begin + tdataedit1(ar2[acol]).texttodata(atext,ar3[acol].getitempo(arow)^); + ar3[acol].change(arow); + end; + end + else begin + if ar3[acol] <> nil then begin + ar3[acol].setastext(arow,atext); + end; + end; + end; //setcelltext + +begin + result:= inherited pasteselection; + if result then begin + exit; + end; + ar1:= nil; //compiler warning + ar4:= nil; + ar5:= nil; + initcopyars(ar2,ar3); +// result:= false; + bo1:= false; + for int1:= 0 to datacols.count - 1 do begin + if co_canpaste in datacols[int1].options then begin + bo1:= true; + end + else begin + ar2[int1]:= nil; + ar3[int1]:= nil; + end; + end; + if bo1 and pastefromclipboard(wstr1) then begin + ar4:= breaklines(wstr1); + bo2:= high(ar4) > 0; + if high(ar4) >= 0 then begin + if ar4[high(ar4)] = '' then begin + setlength(ar4,high(ar4)); //remove terminator + end; + beginupdate; + try + if (og1_pasteinselection in optionsgrid1) and (high(ar4) = 0) and + datacols.hasselection and (findchar(ar4[0],c_tab) = 0) then begin + ar1:= datacols.selectedcells; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + setcelltext(ar4[0],col,row); + end; + end; + end + else begin + if not bo2 then begin + exit; + end; + int5:= row; + if int5 < 0 then begin + int5:= 0; + end; + datacols.clearselection; + // int1:= row; + bo2:= og_rowinserting in optionsgrid; + if bo2 then begin + insertrow(int5,length(ar4)); + end; + if high(ar4) >= rowcount - int5 then begin + setlength(ar4,rowcount-int5); + end; + for int1:= 0 to high(ar4) do begin + if bo2 then begin + datacols.selected[makegridcoord(invalidaxis,int5)]:= true; + end; + ar5:= splitstring(ar4[int1],c_tab); + int3:= 0; + for int2:= 0 to high(ar5) do begin + while (int3 < datacols.count) and + not (co_canpaste in datacols[int3].options) do begin + inc(int3); + end; + if int3 >= datacols.count then begin + break; + end; + if not bo2 then begin + datacols[int3].selected[int5]:= true; + end; + try + setcelltext(ar5[int2],int3,int5); + except + end; + inc(int3); + end; + inc(int5); + end; + end; + finally + try + updaterowdata; + finally + endupdate; + end; + end; + result:= true; + end; + end; +end; + +procedure tcustomwidgetgrid.mouseevent(var info: mouseeventinfoty); +var + bo1: boolean; + fmousefocusedcell: gridcoordty; + fmouseactivewidget: twidget; + fmousefocusedwidget: twidget; + pt1: pointty; + widget1: twidget; +begin + fmousefocusedcell:= ffocusedcell; + fmouseactivewidget:= factivewidget; + fmousefocusedwidget:= window.focusedwidget; + inherited; + if (info.eventstate * [es_processed,es_child] = []) and + not (gs_mousecellredirected in fstate) and + (factivewidget <> nil) and + ((fmouseactivewidget <> factivewidget) or + ((ffocusedcell.row <> fmousefocusedcell.row)) or + (fmousefocusedwidget <> window.focusedwidget)) and + (factivewidget.checkdescendent(mouseeventwidget(info))) then begin + bo1:= gs1_mousecaptureendlock in fstate1; + include(fstate1,gs1_mousecaptureendlock); + try + releasemouse; + finally + if not bo1 then begin + exclude(fstate1,gs1_mousecaptureendlock); + end; + end; + if ffocusedcell.col >= 0 then begin + with twidgetcols(fdatacols)[ffocusedcell.col] do begin + if (fintf <> nil) then begin + widget1:= fintf.getwidget(); + pt1:= info.pos; + try + translatewidgetpoint1(info.pos,self,widget1); + fintf.setfirstclick(info); + finally + info.pos:= pt1; + end; + end; + end; + end; + reflectmouseevent(info); + end; +end; + +procedure tcustomwidgetgrid.dowidgetcellevent(var info: celleventinfoty); +var + int1: integer; +begin + if (info.cell.col >= 0) and (info.cell.col < fdatacols.count) and + (twidgetcols(fdatacols)[info.cell.col].fintf <> nil) then begin + twidgetcols(fdatacols)[info.cell.col].fintf.docellevent(true,info); + //chance to update info.cellzone + end; + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcols(fdatacols)[int1] do begin + if (fintf <> nil) and (info.cell.col <> int1) then begin + fintf.docellevent(false,info); + end; + end; + end; +end; + +procedure tcustomwidgetgrid.docellevent(var info: celleventinfoty); +var + int1: integer; +begin + if (info.cellbefore.row <> info.newcell.row) and + ((info.eventkind = cek_enter) or + (info.eventkind = cek_focusedcellchanged) and + (info.newcell.col = invalidaxis) and + (info.newcell.row >= 0)) then begin + //there was no cek_enter + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcols(fdatacols)[int1] do begin + if fintf <> nil then begin + fintf.gridtovalue(info.newcell.row); + end; + end; + end; + end + else begin + if (info.eventkind = cek_exit) and (info.newcell.row < 0) and + (info.selectaction <> fca_exitgrid) then begin + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcols(fdatacols)[int1] do begin + if fintf <> nil then begin + fintf.gridtovalue(-2); + end; + end; + end; + end; + end; + dowidgetcellevent(info); + inherited; +end; + +procedure tcustomwidgetgrid.checkcellvalue(var accept: boolean); +begin + twidgetcols(fdatacols)[ffocusedcell.col].checkcanclose(accept); +end; + +procedure tcustomwidgetgrid.dokeydown(var info: keyeventinfoty); +begin + if not (es_child in info.eventstate) or + ((factivewidget <> nil) and + factivewidget.checkdescendent(window.focusedwidget)) or + (factivewidget = nil) and + not (fcontainer1.entered or fcontainer3.entered) then begin + inherited; + end + else begin + if (info.key = key_escape) and (info.shiftstate = []) and + (og_containerfocusbackonesc in foptionsgrid) and + (flastfocusedfixwidget <> nil) and (factivewidget <> nil) and + flastfocusedfixwidget.focused then begin + factivewidget.activate; + end; + end; +end; + +function tcustomwidgetgrid.getgriddatalink: pointer; +begin + result:= nil; +end; + +procedure tcustomwidgetgrid.doexit; +begin + if canclose(nil) then begin + flastfocusedfixwidget:= nil; + if factivewidget <> nil then begin + factivewidget.visible:= false; + end; + inherited; + end; +end; + +procedure tcustomwidgetgrid.checkrowreadonlystate; +begin + inherited; + if isdatacell(ffocusedcell) then begin + with datacols[ffocusedcell.col] do begin + if fintf <> nil then begin + include(fstate,gps_readonlyupdating); + fintf.setreadonly(isreadonly); + exclude(fstate,gps_readonlyupdating); + end; + end; + end; +end; + +procedure tcustomwidgetgrid.updaterowdata; +var + int1,int2: integer; +begin + int2:= -2; + if ffocusedcell.row >= 0 then begin + int2:= -1; + end; + for int1:= 0 to datacols.count - 1 do begin + with twidgetcol(fdatacols[int1]) do begin + if fintf <> nil then begin + fintf.gridtovalue(int2); //restore grid value + end; + end; + end; +end; + +procedure tcustomwidgetgrid.focuslock; +begin + beginupdate; + inc(ffocuslock); +end; + +procedure tcustomwidgetgrid.focusunlock; +begin + dec(ffocuslock); + if (ffocuslock = 0) and (col >= 0) then begin + twidgetcol(twidgetcols(fdatacols).fitems[col]).updatewidgetrect; + end; + endupdate; +end; + +procedure tcustomwidgetgrid.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +var + cell1: gridcoordty; + widget1: twidget; +begin + if not (es_child in mouseinfo.eventstate) then begin + cell1:= cellatpos(mouseinfo.pos); + if (cell1.col >= 0) and + ((cell1.row >= 0) {or (cell1.row = invalidaxis)}) then begin + with datacols[cell1.col] do begin + if fintf <> nil then begin + widget1:= fintf.getwidget; + if widget1 <> nil then begin + translateclientpoint1(mouseinfo.pos,self,widget1); + mouseinfo.eventstate:= mouseinfo.eventstate + [es_parent{,es_child}]; + try + fintf.updatepopupmenu(amenu,mouseinfo); + finally + translateclientpoint1(mouseinfo.pos,widget1,self); + mouseinfo.eventstate:= mouseinfo.eventstate - [es_parent{,es_child}]; + end; + end; + end; + end; + end; + end; + inherited; +end; + +function tcustomwidgetgrid.getassistiveflags(): assistiveflagsty; +var + w1: twidget1; +begin + result:= inherited getassistiveflags(); + include(result,asf_widgetgrid); + if focusedcellvalid then begin + w1:= twidget1(datacols[ffocusedcell.col].editwidget); + if (w1 <> nil) and + (asf_gridwidget in w1.getiassistiveclient().getassistiveflags()) then begin + result:= result + [asf_widgetcell]; + end; + end; +end; + +function tcustomwidgetgrid.getassistivecelltext( + const acell: gridcoordty; out aflags: assistiveflagsty): msestring; +var + w1: twidget; +begin + if isdatacell(acell) then begin + with datacols[acell.col] do begin + if fintf <> nil then begin + result:= fintf.getassistivecelltext(acell.row); + w1:= editwidget; + if w1 <> nil then begin + aflags:= twidget1(w1).getassistiveflags(); + end + else begin + inherited getassistivecelltext(acell,aflags); + end; + end + else begin + result:= inherited getassistivecelltext(acell,aflags); +// result:= ''; + end; + end; + end + else begin + result:= inherited getassistivecelltext(acell,aflags); + end; +end; + +function tcustomwidgetgrid.getassistivecaretindex(): int32; +begin + if factivewidget <> nil then begin + result:= twidget1(factivewidget).getassistivecaretindex(); + end + else begin + result:= inherited getassistivecaretindex(); + end; +end; + +procedure tcustomwidgetgrid.seteditfocus; +begin + if factivewidget <> nil then begin + factivewidget.activate; + end + else begin + activate; + end; +end; + +procedure tcustomwidgetgrid.setcellclientclick(const awidget: twidget); +var + bo1: boolean; +begin + if factivewidget = awidget then begin + bo1:= gs1_mousecaptureendlock in fstate1; + try + include(fstate1,gs1_mousecaptureendlock); + twidget1(awidget).setclientclick; + finally + if not bo1 then begin + exclude(fstate1,gs1_mousecaptureendlock); + end; + end; + end; +end; + +procedure tcustomwidgetgrid.navigrequest(var info: naviginfoty; + const nowrap: boolean); +begin + inherited; + if (info.nearest = fcontainer0) or (info.nearest = fcontainer2) then begin + if factivewidget <> nil then begin + factivewidget.show; + info.nearest:= factivewidget; + end; + end; +end; + +procedure tcustomwidgetgrid.dochildfocused(const sender: twidget); +begin + if (sender <> fcontainer2) and (sender <> fcontainer0) then begin + flastfocusedfixwidget:= sender; + end; + inherited; +end; + +function tcustomwidgetgrid.cellhasfocus: boolean; +begin + result:= fcontainer2.entered or fcontainer0.entered or focused; +end; + +procedure tcustomwidgetgrid.writestate(writer: twriter); +var + int1: integer; +begin + for int1:= 0 to fdatacols.count-1 do begin + with twidgetcol(twidgetcols(fdatacols).fitems[int1]) do begin + if fintf = nil then begin + fwidgetname:= ''; + end + else begin + fwidgetname:= fintf.getwidget.name; + end; + end; + end; + inherited; +end; + +procedure registergriddatalistclass(const tag: ansistring; + const createfunc: creategriddatalistty); +begin + griddatalists.addunique(tag,{$ifndef FPC}@{$endif}createfunc); +end; + +function createtgridmsestringdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridmsestringdatalist.create(aowner); +end; + +function createtgridansistringdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridansistringdatalist.create(aowner); +end; + +function createtgridbinarystringdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridbinarystringdatalist.create(aowner); +end; + +function createtgridpointerdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridpointerdatalist.create(aowner); +end; + +function createtgridintegerdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridintegerdatalist.create(aowner); +end; + +function createtgridint64datalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridint64datalist.create(aowner); +end; + +function createtgridenumdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridenumdatalist.create(aowner); +end; + +function createtgridenum64datalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridenum64datalist.create(aowner); +end; + +function createtgridrealdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridrealdatalist.create(aowner); +end; + +{ twidgetgrid } + +procedure twidgetgrid.initnewcomponent(const ascale: real); +begin + inherited; + optionsgrid:= optionsgrid + newcomponentoptionsgridadd; +end; + +{ tgridbinarystringdatalist } + +constructor tgridbinarystringdatalist.create(owner: twidgetcol); +begin + inherited; + include(fstate,dls_binarydata); +end; + +initialization + griddatalists:= tpointeransistringhashdatalist.create; + registergriddatalistclass(tgridmsestringdatalist.classname, + {$ifdef FPC}@{$endif}createtgridmsestringdatalist); + registergriddatalistclass(tgridansistringdatalist.classname, + {$ifdef FPC}@{$endif}createtgridansistringdatalist); + registergriddatalistclass(tgridbinarystringdatalist.classname, + {$ifdef FPC}@{$endif}createtgridbinarystringdatalist); + registergriddatalistclass(tgridpointerdatalist.classname, + {$ifdef FPC}@{$endif}createtgridpointerdatalist); + registergriddatalistclass(tgridintegerdatalist.classname, + {$ifdef FPC}@{$endif}createtgridintegerdatalist); + registergriddatalistclass(tgridint64datalist.classname, + {$ifdef FPC}@{$endif}createtgridint64datalist); + registergriddatalistclass(tgridenumdatalist.classname, + {$ifdef FPC}@{$endif}createtgridenumdatalist); + registergriddatalistclass(tgridenum64datalist.classname, + {$ifdef FPC}@{$endif}createtgridenum64datalist); + registergriddatalistclass(tgridrealdatalist.classname, + {$ifdef FPC}@{$endif}createtgridrealdatalist); +finalization + griddatalists.free; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_avl.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_avl.pas new file mode 100644 index 0000000..294c4f3 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_avl.pas @@ -0,0 +1,435 @@ +unit dbf_avl; + +interface + +{$I dbf_common.inc} + +uses + Dbf_Common; + +type + TBal = -1..1; + + TAvlTree = class; + + TKeyType = Cardinal; + TExtraData = Pointer; + + PData = ^TData; + TData = record + ID: TKeyType; + ExtraData: TExtraData; + end; + + PNode = ^TNode; + TNode = record + Data: TData; + Left: PNode; + Right: PNode; + Bal: TBal; // balance factor: h(Right) - h(Left) + end; + + TAvlTreeEvent = procedure(Sender: TAvlTree; Data: PData) of object; + + TAvlTree = class(TObject) + private + FRoot: PNode; + FCount: Cardinal; + FOnDelete: TAvlTreeEvent; + FHeightChange: Boolean; + + function InternalInsert(X: PNode; var P: PNode): Boolean; + procedure InternalDelete(X: TKeyType; var P: PNode); + + procedure DeleteNode(X: PNode); + procedure TreeDispose(X: PNode); + public + constructor Create; + destructor Destroy; override; + + procedure Clear; + function Find(Key: TKeyType): TExtraData; + function Insert(Key: TKeyType; Extra: TExtraData): Boolean; + procedure Delete(Key: TKeyType); + + function Lowest: PData; + + property Count: Cardinal read FCount; + property OnDelete: TAvlTreeEvent read FOnDelete write FOnDelete; + end; + + +implementation + +uses + Math; + +procedure RotL(var P: PNode); +var + P1: PNode; +begin + P1 := P^.Right; + P^.Right := P1^.Left; + P1^.Left := P; + P := P1; +end; + +procedure RotR(var P: PNode); +var + P1: PNode; +begin + P1 := P^.Left; + P^.Left := P1^.Right; + P1^.Right := P; + P := P1; +end; + +function Height(X: PNode): Integer; +begin + if X = nil then + Result := 0 + else + Result := 1+Max(Height(X^.Left), Height(X^.Right)); +end; + +function CheckTree_T(X: PNode; var H: Integer): Boolean; +var + HR: Integer; +begin + if X = nil then + begin + Result := true; + H := 0; + end else begin + Result := CheckTree_T(X^.Left, H) and CheckTree_T(X^.Right, HR) and + ((X^.Left = nil) or (X^.Left^.Data.ID < X^.Data.ID)) and + ((X^.Right = nil) or (X^.Right^.Data.ID > X^.Data.ID)) and +// ((Height(X^.Right) - Height(X^.Left)) = X^.Bal); + (HR - H = X^.Bal); + H := 1 + Max(H, HR); + end; +end; + +function CheckTree(X: PNode): Boolean; +var + H: Integer; +begin + Result := CheckTree_T(X, H); +end; + +procedure BalanceLeft(var P: PNode; var HeightChange: Boolean); +var + B1, B2: TBal; +{HeightChange = true, left branch has become less high} +begin + case P^.Bal of + -1: begin P^.Bal := 0 end; + 0: begin P^.Bal := 1; HeightChange := false end; + 1: begin {Rebalance} + B1 := P^.Right^.Bal; + if B1 >= 0 + then {single L rotation} + begin + RotL(P); + //adjust balance factors: + if B1 = 0 + then + begin P^.Bal :=-1; P^.Left^.Bal := 1; HeightChange := false end + else + begin P^.Bal := 0; P^.Left^.Bal := 0 end; + end + else {double RL rotation} + begin + B2 := P^.Right^.Left^.Bal; + RotR(P^.Right); + RotL(P); + //adjust balance factors: + if B2=+1 then P^.Left^.Bal := -1 else P^.Left^.Bal := 0; + if B2=-1 then P^.Right^.Bal := 1 else P^.Right^.Bal := 0; + P^.Bal := 0; + end; + end;{1} + end{case} +end;{BalanceLeft} + +procedure BalanceRight(var P: PNode; var HeightChange: Boolean); +var + B1, B2: TBal; +{HeightChange = true, right branch has become less high} +begin + case P^.Bal of + 1: begin P^.Bal := 0 end; + 0: begin P^.Bal := -1; HeightChange := false end; + -1: begin {Rebalance} + B1 := P^.Left^.Bal; + if B1 <= 0 + then {single R rotation} + begin + RotR(P); + //adjust balance factors} + if B1 = 0 + then + begin P^.Bal :=1; P^.Right^.Bal :=-1; HeightChange:= false end + else + begin P^.Bal := 0; P^.Right^.Bal := 0 end; + end + else {double LR rotation} + begin + B2 := P^.Left^.Right^.Bal; + RotL(P^.Left); + RotR(P); + //adjust balance factors + if B2=-1 then P^.Right^.Bal := 1 else P^.Right^.Bal := 0; + if B2= 1 then P^.Left^.Bal := -1 else P^.Left^.Bal := 0; + P^.Bal := 0; + end; + end;{-1} + end{case} +end;{BalanceRight} + +procedure DelRM(var R: PNode; var S: PNode; var HeightChange: Boolean); +// Make S refer to rightmost element of tree with root R; +// Remove that element from the tree +begin + if R^.Right = nil then + begin S := R; R := R^.Left; HeightChange := true end + else + begin + DelRM(R^.Right, S, HeightChange); + if HeightChange then BalanceRight(R, HeightChange) + end +end; + +//--------------------------------------- +//---****--- Class TAvlTree ---*****----- +//--------------------------------------- + +constructor TAvlTree.Create; +begin + inherited; + + FRoot := nil; +end; + +destructor TAvlTree.Destroy; +begin + Clear; + + inherited; +end; + +procedure TAvlTree.Clear; +begin + TreeDispose(FRoot); + FRoot := nil; +end; + +procedure TAvlTree.DeleteNode(X: PNode); +begin + // delete handler installed? + if Assigned(FOnDelete) then + FOnDelete(Self, @X^.Data); + + // dispose of memory + Dispose(X); + Dec(FCount); +end; + +procedure TAvlTree.TreeDispose(X: PNode); +var + P: PNode; +begin + // nothing to dispose of? + if X = nil then + exit; + + // use in-order visiting, maybe someone likes sequential ordering + TreeDispose(X^.Left); + P := X^.Right; + + // free mem + DeleteNode(X); + + // free right child + TreeDispose(P); +end; + +function TAvlTree.Find(Key: TKeyType): TExtraData; +var + H: PNode; +begin + H := FRoot; + while (H <> nil) and (H^.Data.ID <> Key) do // use conditional and + if Key < H^.Data.ID then + H := H^.Left + else + H := H^.Right; + + if H <> nil then + Result := H^.Data.ExtraData + else + Result := nil; +end; + +function TAvlTree.Insert(Key: TKeyType; Extra: TExtraData): boolean; +var + H: PNode; +begin + // make new node + New(H); + with H^ do + begin + Data.ID := Key; + Data.ExtraData := Extra; + Left := nil; + Right := nil; + Bal := 0; + end; + // insert new node + Result := InternalInsert(H, FRoot); + if not Result then + Dispose(H); + // check tree +// assert(CheckTree(FRoot)); +end; + +procedure TAvlTree.Delete(Key: TKeyType); +begin + InternalDelete(Key, FRoot); +// assert(CheckTree(FRoot)); +end; + +function TAvlTree.InternalInsert(X: PNode; var P: PNode): boolean; +begin + if P = nil then + begin + P := X; + Inc(FCount); + FHeightChange := true; + Result := true; + end else begin + if X^.Data.ID < P^.Data.ID then + begin + { less } + Result := InternalInsert(X, P^.Left); + if FHeightChange then {Left branch has grown higher} + case P^.Bal of + 1: begin P^.Bal := 0; FHeightChange := false end; + 0: begin P^.Bal := -1 end; + -1: begin {Rebalance} + if P^.Left^.Bal = -1 + then {single R rotation} + begin + RotR(P); + //adjust balance factor: + P^.Right^.Bal := 0; + end + else {double LR rotation} + begin + RotL(P^.Left); + RotR(P); + //adjust balance factor: + case P^.Bal of + -1: begin P^.Left^.Bal := 0; P^.Right^.Bal := 1 end; + 0: begin P^.Left^.Bal := 0; P^.Right^.Bal := 0 end; + 1: begin P^.Left^.Bal := -1; P^.Right^.Bal := 0 end; + end; + end; + P^.Bal := 0; + FHeightChange := false; +// assert(CheckTree(P)); + end{-1} + end{case} + end else + if X^.Data.ID > P^.Data.ID then + begin + { greater } + Result := InternalInsert(X, P^.Right); + if FHeightChange then {Right branch has grown higher} + case P^.Bal of + -1: begin P^.Bal := 0; FHeightChange := false end; + 0: begin P^.Bal := 1 end; + 1: begin {Rebalance} + if P^.Right^.Bal = 1 + then {single L rotation} + begin + RotL(P); + //adjust balance factor: + P^.Left.Bal := 0; + end + else {double RL rotation} + begin + RotR(P^.Right); + RotL(P); + //adjust balance factor + case P^.Bal of + 1: begin P^.Right^.Bal := 0; P^.Left^.Bal := -1 end; + 0: begin P^.Right^.Bal := 0; P^.Left^.Bal := 0 end; + -1: begin P^.Right^.Bal := 1; P^.Left^.Bal := 0 end; + end; + end; + P^.Bal := 0; + FHeightChange := false; +// assert(CheckTree(P)); + end{1} + end{case} + end {greater} else begin + {X already present; do not insert again} + FHeightChange := false; + Result := false; + end; + end; +// assert(CheckTree(P)); +end;{InternalInsert} + +procedure TAvlTree.InternalDelete(X: TKeyType; var P: PNode); +var + Q: PNode; + H: TData; +begin + if P = nil then + FHeightChange := false + else + if X < P^.Data.ID then + begin + InternalDelete(X, P^.Left); + if FHeightChange then BalanceLeft(P, FHeightChange) + end else + if X > P^.Data.ID then + begin + InternalDelete(X, P^.Right); + if FHeightChange then BalanceRight(P, FHeightChange) + end else begin + if P^.Right = nil then + begin Q := P; P := P^.Left; FHeightChange := true end + else if P^.Left = nil then + begin Q := P; P := P^.Right; FHeightChange := true end + else + begin + DelRM(P^.Left, Q, FHeightChange); + H := P^.Data; + P^.Data := Q^.Data; + Q^.Data := H; + if FHeightChange then BalanceLeft(P, FHeightChange) + end; + DeleteNode(Q) + end;{eq} +end;{InternalDelete} + +function TAvlTree.Lowest: PData; +var + H: PNode; +begin + H := FRoot; + if H = nil then + begin + Result := nil; + exit; + end; + + while H^.Left <> nil do + H := H^.Left; + Result := @H^.Data; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_collate.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_collate.pas new file mode 100644 index 0000000..40fa24c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_collate.pas @@ -0,0 +1,2347 @@ +unit dbf_collate; + +{$i dbf_common.inc} + + +interface + +uses + SysUtils; + + + +type + TCollationTable = array[0..255] of Byte; + PCollationTable = ^TCollationTable; + TCollationBDEName = string[8]; + + TCollationDefinition = record + CollationBDEName :TCollationBDEName; + CollationTable :PCollationTable; + end; + + + +const + BINARY_COLLATION :PCollationTable = PCollationTable($111); + UNKNOWN_COLLATION :PCollationTable = PCollationTable($222); + + + +function GetCollationTable( DbfLangId :integer ) :PCollationTable; +function DbfCompareString( CollationTable :PCollationTable; String1 :PChar; nLength1 :integer; String2 :PChar; nLength2 :integer ) :integer; +function RegisterCollation( DbfLangId :integer; CollationTable :PCollationTable; BDEName :TCollationBDEName ) :Boolean; + + +var + CollationTables :array[0..255] of TCollationDefinition; + + +implementation +uses dbf_lang, math; + + +procedure InitialiseCollationTables; +var + nCnt :integer; +begin + for nCnt := Low(CollationTables) to High(CollationTables) do + begin + CollationTables[nCnt].CollationTable := BINARY_COLLATION; + CollationTables[nCnt].CollationBDEName := ''; + end; +end; + +function GetCollationTable( DbfLangId :integer ) :PCollationTable; +begin + if (DbfLangId < Low(CollationTables)) or (DbfLangId > High(CollationTables)) then + begin + Result := nil; + end + else + begin + Result := CollationTables[DbfLangId].CollationTable; + end; +end; + +function DbfCompareString( CollationTable :PCollationTable; String1 :PChar; nLength1 :integer; String2 :PChar; nLength2 :integer ) :integer; +var + nCnt, nMax, nVal1, nVal2 :integer; +const + ONE_LESS_THAN_TWO = 1; + EQUAL = 2; + TWO_LESS_THAN_ONE = 3; +begin + result := EQUAL; + + if CollationTable = BINARY_COLLATION then + begin + // binary collation + nMax := Min( nLength1, nLength2 ); + for nCnt := 1 to nMax do + begin + if Ord(String1^) < Ord(String2^) then + begin + result := ONE_LESS_THAN_TWO; + break; + end + else if Ord(String1^) > Ord(String2^) then + begin + result := TWO_LESS_THAN_ONE; + break; + end; + + Inc(String1); + Inc(String2); + end; + end + + else + + begin + // collation via collation table + nMax := Min( nLength1, nLength2 ); + for nCnt := 1 to nMax do + begin + nVal1 := CollationTable[Ord(String1^)]; + nVal2 := CollationTable[Ord(String2^)]; + + if nVal1 < nVal2 then + begin + result := ONE_LESS_THAN_TWO; + break; + end + + else if nVal1 > nVal2 then + begin + result := TWO_LESS_THAN_ONE; + break; + end; + + Inc(String1); + Inc(String2); + end; + + end; + + + if result = EQUAL then + begin + // If the two strings are of different lengths, they are compared up to the + // length of the shortest one. If they are equal to that point, then the + // return value will indicate that the longer string is greater. + if nLength1 < nLength2 then + result := ONE_LESS_THAN_TWO + else if nLength1 > nLength2 then + result := TWO_LESS_THAN_ONE; + end; + +end; + + +function RegisterCollation( DbfLangId :integer; CollationTable :PCollationTable; BDEName :TCollationBDEName ) :Boolean; +begin + if (DbfLangId < Low(CollationTables)) or (DbfLangId > High(CollationTables)) then + begin + result := false; + end + else + begin + CollationTables[DbfLangId].CollationTable := CollationTable; + CollationTables[DbfLangId].CollationBDEName := BDEName; + result := true; + end; +end; + + + + +const + + {$IFDEF PARADOX_COLLATIONS} + + // intl 55764 + _intl :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 069, 073, 076, 079, 085, 088, 090, 092, 098, 100, 102, 104, 106, 109, 115, + 119, 121, 123, 125, 128, 133, 137, 139, 141, 144, 146, 149, 150, 151, 152, 153, + 154, 065, 072, 074, 078, 080, 087, 089, 091, 093, 099, 101, 103, 105, 107, 111, + 118, 120, 122, 124, 127, 129, 136, 138, 140, 142, 145, 155, 156, 157, 158, 159, + 035, 035, 035, 165, 035, 035, 035, 035, 035, 035, 125, 035, 115, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 124, 035, 111, 035, 035, 144, + 181, 172, 162, 163, 035, 164, 035, 035, 035, 035, 166, 173, 169, 035, 035, 035, + 178, 176, 180, 035, 035, 175, 035, 179, 035, 035, 167, 174, 171, 170, 035, 168, + 069, 069, 069, 069, 071, 148, 161, 077, 085, 086, 085, 085, 098, 098, 098, 098, + 079, 110, 115, 115, 115, 115, 117, 035, 115, 133, 133, 133, 135, 144, 035, 126, + 067, 066, 068, 065, 070, 147, 160, 075, 083, 082, 084, 081, 096, 095, 097, 094, + 078, 108, 113, 112, 114, 111, 116, 177, 111, 131, 130, 132, 134, 142, 035, 143 + ); + + intl :PCollationTable = @_intl; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // nordan 1610 + + _nordan :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 069, 071, 074, 077, 083, 086, 088, 090, 096, 098, 100, 102, 104, 107, 113, + 115, 117, 119, 121, 123, 128, 130, 132, 134, 138, 141, 152, 153, 154, 155, 156, + 157, 065, 070, 072, 076, 078, 085, 087, 089, 091, 097, 099, 101, 103, 105, 109, + 114, 116, 118, 120, 122, 124, 129, 131, 133, 135, 140, 158, 159, 160, 161, 162, + 035, 035, 035, 164, 035, 035, 035, 035, 035, 035, 121, 035, 113, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 120, 035, 109, 035, 035, 138, + 181, 171, 035, 163, 173, 035, 035, 035, 035, 035, 165, 172, 168, 035, 035, 035, + 178, 176, 180, 035, 035, 175, 035, 179, 035, 035, 166, 035, 170, 169, 035, 167, + 069, 069, 069, 069, 145, 151, 144, 075, 083, 084, 083, 083, 096, 096, 096, 096, + 077, 108, 113, 113, 113, 113, 149, 035, 148, 128, 128, 128, 139, 138, 035, 174, + 067, 066, 068, 065, 143, 150, 142, 073, 081, 080, 082, 079, 094, 093, 095, 092, + 076, 106, 111, 110, 112, 109, 147, 177, 146, 126, 125, 127, 136, 135, 035, 137 + ); + nordan :PCollationTable = @_nordan; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // nordan40 31338 + + _nordan40 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 070, 072, 076, 078, 085, 087, 089, 091, 097, 099, 101, 103, 105, 109, + 114, 116, 118, 120, 122, 124, 129, 131, 133, 135, 140, 152, 153, 154, 155, 156, + 157, 066, 071, 074, 077, 080, 086, 088, 090, 092, 098, 100, 102, 104, 107, 110, + 115, 117, 119, 121, 123, 125, 130, 132, 134, 137, 141, 158, 159, 160, 161, 162, + 035, 035, 035, 164, 035, 035, 035, 035, 035, 035, 120, 035, 109, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 121, 035, 110, 035, 035, 135, + 181, 171, 035, 163, 173, 035, 035, 035, 035, 035, 165, 172, 168, 035, 035, 035, + 178, 176, 180, 035, 035, 175, 035, 179, 035, 035, 166, 035, 170, 169, 035, 167, + 065, 065, 065, 065, 143, 150, 142, 073, 078, 079, 078, 078, 091, 091, 091, 091, + 076, 106, 109, 109, 109, 109, 147, 035, 146, 124, 124, 124, 136, 135, 035, 174, + 068, 067, 069, 066, 145, 151, 144, 075, 083, 082, 084, 081, 095, 094, 096, 093, + 077, 108, 112, 111, 113, 110, 149, 177, 148, 127, 126, 128, 139, 137, 035, 138 + ); + nordan40 :PCollationTable = @_nordan40; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // swedfin 6461 + + _swedfin :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 069, 071, 074, 077, 083, 086, 088, 090, 096, 098, 100, 102, 104, 107, 113, + 115, 117, 119, 121, 123, 128, 130, 132, 134, 137, 139, 150, 151, 152, 153, 154, + 155, 065, 070, 072, 076, 078, 085, 087, 089, 091, 097, 099, 101, 103, 105, 109, + 114, 116, 118, 120, 122, 124, 129, 131, 133, 135, 138, 156, 157, 158, 159, 160, + 035, 035, 035, 164, 035, 035, 035, 035, 035, 035, 121, 035, 113, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 120, 035, 109, 035, 035, 137, + 181, 171, 161, 162, 035, 163, 035, 035, 035, 035, 165, 172, 168, 035, 035, 035, + 178, 176, 180, 035, 035, 175, 035, 179, 035, 035, 166, 173, 170, 169, 035, 167, + 069, 069, 069, 069, 145, 143, 141, 075, 083, 084, 083, 083, 096, 096, 096, 096, + 077, 108, 113, 113, 113, 113, 147, 035, 113, 128, 128, 128, 149, 137, 035, 174, + 067, 066, 068, 065, 144, 142, 140, 073, 081, 080, 082, 079, 094, 093, 095, 092, + 076, 106, 111, 110, 112, 109, 146, 177, 109, 126, 125, 127, 148, 135, 035, 136 + ); + swedfin :PCollationTable = @_swedfin; + + {$ENDIF} + + + + + // DB865DA0 Checksum: 51597 + + _DB865DA0 :TCollationTable = ( + 000, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 001, 118, 130, 124, 125, 110, 123, 132, 099, 100, 111, 108, 113, 109, 112, 119, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 115, 114, 105, 107, 106, 117, + 122, 012, 013, 014, 016, 017, 019, 020, 021, 022, 023, 024, 025, 026, 027, 029, + 030, 031, 032, 033, 034, 035, 037, 038, 039, 040, 041, 101, 120, 102, 133, 135, + 131, 047, 051, 052, 054, 055, 060, 061, 062, 063, 068, 069, 070, 071, 072, 074, + 078, 079, 080, 081, 082, 083, 088, 089, 090, 091, 093, 103, 121, 104, 134, 169, + 015, 087, 056, 050, 095, 049, 098, 053, 058, 059, 057, 067, 066, 065, 043, 046, + 018, 094, 042, 077, 097, 076, 086, 085, 092, 045, 036, 096, 126, 044, 128, 127, + 048, 064, 075, 084, 073, 028, 136, 137, 116, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 129, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB865DA0 :PCollationTable = @_DB865DA0; + + DB865NO0 :PCollationTable = @_DB865DA0; + + + + + // DB437NL0 Checksum: 26538 + + _DB437NL0 :TCollationTable = ( + 000, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 001, 114, 130, 120, 121, 106, 119, 132, 095, 096, 107, 104, 109, 105, 108, 115, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 111, 110, 101, 103, 102, 113, + 118, 012, 015, 016, 018, 019, 021, 022, 023, 024, 025, 026, 027, 028, 029, 031, + 033, 034, 035, 036, 037, 038, 040, 041, 042, 043, 044, 097, 116, 098, 133, 135, + 131, 045, 051, 052, 054, 055, 060, 061, 062, 063, 068, 069, 070, 071, 072, 074, + 079, 080, 081, 082, 083, 084, 089, 090, 091, 092, 094, 099, 117, 100, 134, 169, + 017, 088, 056, 048, 049, 047, 050, 053, 058, 059, 057, 067, 066, 065, 013, 014, + 020, 127, 128, 077, 078, 076, 087, 086, 093, 032, 039, 122, 123, 124, 126, 125, + 046, 064, 075, 085, 073, 030, 136, 137, 112, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 129, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB437NL0 :PCollationTable = @_DB437NL0; + + DB437UK0 :PCollationTable = @_DB437NL0; + + DB437IT0 :PCollationTable = @_DB437NL0; + + DB437FR0 :PCollationTable = @_DB437NL0; + + + + + // DB850NL0 Checksum: 4071 + + _DB850NL0 :TCollationTable = ( + 000, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 001, 176, 189, 213, 206, 214, 212, 006, 192, 193, 210, 215, 173, 005, 181, 180, + 007, 011, 013, 015, 017, 018, 019, 020, 021, 022, 175, 174, 219, 220, 221, 178, + 203, 024, 041, 043, 047, 051, 061, 063, 065, 067, 078, 080, 082, 084, 086, 090, + 105, 107, 109, 111, 114, 118, 128, 130, 132, 134, 139, 194, 211, 195, 184, 003, + 183, 023, 040, 042, 046, 050, 060, 062, 064, 066, 077, 079, 081, 083, 085, 089, + 104, 106, 108, 110, 113, 117, 127, 129, 131, 133, 138, 196, 223, 197, 186, 227, + 045, 125, 052, 030, 034, 028, 032, 044, 056, 058, 054, 074, 072, 070, 035, 033, + 053, 038, 039, 096, 098, 094, 123, 121, 137, 099, 126, 102, 208, 103, 218, 207, + 026, 068, 092, 119, 087, 088, 025, 091, 179, 202, 222, 009, 008, 177, 190, 191, + 230, 231, 232, 243, 239, 027, 031, 029, 201, 250, 254, 247, 253, 205, 209, 236, + 240, 241, 235, 237, 244, 238, 036, 037, 251, 245, 252, 246, 248, 255, 249, 204, + 048, 049, 057, 059, 055, 076, 069, 073, 075, 242, 234, 233, 229, 224, 071, 228, + 093, 112, 097, 095, 100, 101, 226, 115, 116, 120, 124, 122, 135, 136, 171, 182, + 004, 216, 172, 010, 200, 199, 217, 188, 225, 185, 187, 012, 016, 014, 198, 002 + ); + DB850NL0 :PCollationTable = @_DB850NL0; + + DB850FR0 :PCollationTable = @_DB850NL0; + + DB850IT1 :PCollationTable = @_DB850NL0; + + DB850ES0 :PCollationTable = @_DB850NL0; + + DB850UK0 :PCollationTable = @_DB850NL0; + + + + + // DB437FI0 Checksum: 33363 + + _DB437FI0 :TCollationTable = ( + 000, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 001, 118, 130, 124, 125, 110, 123, 132, 099, 100, 111, 108, 113, 109, 112, 119, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 115, 114, 105, 107, 106, 117, + 122, 012, 013, 014, 016, 017, 019, 020, 021, 022, 023, 024, 025, 026, 027, 029, + 030, 031, 032, 033, 034, 035, 037, 038, 039, 040, 041, 101, 120, 102, 133, 135, + 131, 047, 051, 052, 054, 055, 060, 061, 062, 063, 068, 069, 070, 071, 072, 074, + 078, 079, 080, 081, 082, 083, 088, 089, 090, 091, 093, 103, 121, 104, 134, 169, + 015, 087, 056, 050, 095, 049, 094, 053, 058, 059, 057, 067, 066, 065, 043, 042, + 018, 096, 044, 077, 097, 076, 086, 085, 092, 045, 036, 098, 126, 046, 128, 127, + 048, 064, 075, 084, 073, 028, 136, 137, 116, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 129, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB437FI0 :PCollationTable = @_DB437FI0; + + + + + // DB437DE0 Checksum: 51657 + _DB437DE0 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 048, 049, 050, 051, 052, 053, + 054, 168, 172, 173, 175, 176, 178, 179, 180, 181, 182, 183, 184, 185, 186, 188, + 190, 191, 192, 193, 194, 195, 197, 198, 199, 200, 201, 055, 056, 057, 058, 059, + 060, 202, 210, 211, 213, 214, 219, 220, 221, 222, 227, 228, 229, 230, 231, 233, + 239, 240, 241, 242, 244, 245, 250, 251, 252, 253, 255, 061, 062, 063, 064, 065, + 174, 249, 215, 205, 206, 204, 207, 212, 217, 218, 216, 226, 225, 224, 169, 170, + 177, 208, 171, 236, 237, 235, 248, 247, 254, 189, 196, 066, 067, 068, 069, 070, + 203, 223, 234, 246, 232, 187, 209, 238, 071, 072, 073, 074, 075, 076, 077, 078, + 079, 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, + 095, 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 243, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157 + ); + + DB437DE0 :PCollationTable = @_DB437DE0; + + + + + // DB850DE0 Checksum: 60384 + _DB850DE0 :TCollationTable = ( + 000, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, 018, 019, 020, 021, + 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, 032, 033, 034, 035, 036, 037, + 001, 043, 056, 080, 073, 081, 079, 006, 059, 060, 077, 082, 040, 005, 048, 047, + 240, 244, 246, 248, 250, 251, 252, 253, 254, 255, 042, 041, 086, 087, 088, 045, + 070, 124, 141, 143, 147, 151, 161, 163, 165, 167, 178, 180, 182, 184, 186, 190, + 205, 207, 209, 211, 214, 218, 228, 230, 232, 234, 239, 061, 078, 062, 051, 003, + 050, 123, 140, 142, 146, 150, 160, 162, 164, 166, 177, 179, 181, 183, 185, 189, + 204, 206, 208, 210, 213, 217, 227, 229, 231, 233, 238, 063, 090, 064, 053, 094, + 145, 225, 152, 130, 134, 128, 132, 144, 156, 158, 154, 174, 172, 170, 135, 133, + 153, 138, 139, 196, 198, 194, 223, 221, 237, 199, 226, 202, 075, 203, 085, 074, + 126, 168, 192, 219, 187, 188, 125, 191, 046, 069, 089, 242, 241, 044, 057, 058, + 097, 098, 099, 110, 106, 127, 131, 129, 068, 117, 121, 114, 120, 072, 076, 103, + 107, 108, 102, 104, 111, 105, 136, 137, 118, 112, 119, 113, 115, 122, 116, 071, + 148, 149, 157, 159, 155, 176, 169, 173, 175, 109, 101, 100, 096, 091, 171, 095, + 193, 212, 197, 195, 200, 201, 093, 215, 216, 220, 224, 222, 235, 236, 038, 049, + 004, 083, 039, 243, 067, 066, 084, 055, 092, 052, 054, 245, 249, 247, 065, 002 + ); + + DB850DE0 :PCollationTable = @_DB850DE0; + + + + + // DB437SV0 Checksum: 5835 + + _DB437SV0 :TCollationTable = ( + 000, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 001, 117, 130, 123, 124, 109, 122, 132, 098, 099, 110, 107, 112, 108, 111, 118, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 114, 113, 104, 106, 105, 116, + 121, 012, 013, 014, 016, 017, 019, 020, 021, 022, 023, 024, 025, 026, 027, 029, + 030, 031, 032, 033, 034, 035, 037, 038, 039, 040, 041, 100, 119, 101, 133, 135, + 131, 045, 049, 050, 052, 053, 058, 059, 060, 061, 066, 067, 068, 069, 070, 072, + 076, 077, 078, 079, 081, 082, 087, 088, 089, 090, 092, 102, 120, 103, 134, 169, + 015, 086, 054, 048, 094, 047, 093, 051, 056, 057, 055, 065, 064, 063, 043, 042, + 018, 095, 096, 075, 097, 074, 085, 084, 091, 044, 036, 125, 126, 127, 129, 128, + 046, 062, 073, 083, 071, 028, 136, 137, 115, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 080, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB437SV0 :PCollationTable = @_DB437SV0; + + + + + // DB850SV1 Checksum: 15648 + + _DB850SV1 :TCollationTable = ( + 000, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 001, 176, 189, 213, 206, 214, 212, 006, 192, 193, 210, 215, 173, 005, 181, 180, + 007, 011, 013, 015, 017, 018, 019, 020, 021, 022, 175, 174, 219, 220, 221, 178, + 203, 024, 035, 037, 041, 045, 055, 057, 059, 061, 072, 074, 076, 078, 080, 084, + 095, 097, 099, 101, 104, 108, 116, 118, 120, 122, 129, 194, 211, 195, 184, 003, + 183, 023, 034, 036, 040, 044, 054, 056, 058, 060, 071, 073, 075, 077, 079, 083, + 094, 096, 098, 100, 103, 107, 115, 117, 119, 121, 128, 196, 223, 197, 186, 227, + 039, 126, 046, 030, 132, 028, 130, 038, 050, 052, 048, 068, 066, 064, 133, 131, + 047, 134, 135, 090, 136, 088, 113, 111, 125, 137, 127, 138, 208, 139, 218, 207, + 026, 062, 086, 109, 081, 082, 025, 085, 179, 202, 222, 009, 008, 177, 190, 191, + 230, 231, 232, 243, 239, 027, 031, 029, 201, 250, 254, 247, 253, 205, 209, 236, + 240, 241, 235, 237, 244, 238, 032, 033, 251, 245, 252, 246, 248, 255, 249, 204, + 042, 043, 051, 053, 049, 070, 063, 067, 069, 242, 234, 233, 229, 224, 065, 228, + 087, 102, 091, 089, 092, 093, 226, 105, 106, 110, 114, 112, 123, 124, 171, 182, + 004, 216, 172, 010, 200, 199, 217, 188, 225, 185, 187, 012, 016, 014, 198, 002 + ); + DB850SV1 :PCollationTable = @_DB850SV1; + + + + + // DB437ES1 Checksum: 29895 + + _DB437ES1 :TCollationTable = ( + 000, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 001, 114, 131, 121, 122, 107, 120, 133, 096, 097, 108, 105, 002, 106, 109, 116, + 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 111, 110, 102, 104, 103, 113, + 119, 013, 016, 017, 019, 020, 022, 023, 024, 025, 026, 027, 028, 029, 030, 032, + 034, 035, 036, 037, 038, 039, 041, 042, 043, 044, 045, 098, 117, 099, 134, 136, + 132, 046, 052, 053, 055, 056, 061, 062, 063, 064, 069, 070, 071, 072, 073, 075, + 080, 081, 082, 083, 084, 085, 090, 091, 092, 093, 095, 100, 118, 101, 135, 170, + 018, 088, 057, 049, 050, 048, 051, 054, 059, 060, 058, 067, 068, 066, 014, 015, + 021, 128, 129, 078, 079, 077, 089, 087, 094, 033, 040, 123, 124, 125, 126, 127, + 047, 065, 076, 086, 074, 031, 137, 138, 112, 171, 172, 173, 174, 115, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 130, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB437ES1 :PCollationTable = @_DB437ES1 ; + + + + + // DB437US0 Checksum: 43413 + + _DB437US0 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB437US0 :PCollationTable = @_DB437US0; + + + + + // DB863CF1 Checksum: 34446 + + _DB863CF1 :TCollationTable = ( + 000, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 001, 110, 123, 116, 117, 103, 115, 125, 092, 093, 104, 101, 106, 102, 105, 111, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 108, 107, 098, 100, 099, 109, + 114, 012, 015, 016, 018, 019, 024, 025, 026, 027, 030, 031, 032, 033, 034, 035, + 037, 038, 039, 040, 041, 042, 046, 047, 048, 049, 050, 094, 112, 095, 126, 128, + 124, 051, 054, 055, 057, 058, 063, 064, 065, 066, 069, 070, 071, 072, 073, 074, + 077, 078, 079, 080, 081, 082, 087, 088, 089, 090, 091, 096, 113, 097, 127, 163, + 017, 086, 059, 053, 014, 052, 151, 056, 061, 062, 060, 068, 067, 252, 013, 121, + 020, 021, 022, 076, 023, 029, 085, 084, 254, 036, 045, 118, 119, 043, 044, 120, + 250, 251, 075, 083, 253, 249, 129, 130, 028, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 122, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 255 + ); + DB863CF1 :PCollationTable = @_DB863CF1; + + + + + // DB850CF0 Checksum: 4704 + + _DB850CF0 :TCollationTable = ( + 000, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 001, 136, 152, 142, 143, 128, 141, 154, 117, 118, 129, 126, 131, 127, 130, 137, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 133, 132, 123, 125, 124, 135, + 140, 012, 019, 020, 022, 023, 028, 029, 030, 031, 036, 037, 038, 039, 040, 042, + 048, 049, 050, 051, 052, 053, 058, 059, 060, 061, 063, 119, 138, 120, 155, 157, + 153, 064, 071, 072, 074, 075, 080, 081, 082, 083, 088, 089, 090, 091, 092, 094, + 100, 101, 102, 103, 104, 105, 110, 111, 112, 113, 116, 121, 139, 122, 156, 191, + 021, 109, 076, 067, 068, 066, 069, 073, 078, 079, 077, 087, 086, 085, 016, 017, + 024, 149, 150, 097, 098, 096, 108, 107, 115, 046, 057, 144, 145, 146, 148, 147, + 065, 084, 095, 106, 093, 041, 158, 159, 134, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 013, 015, 014, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 070, 018, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 026, 027, 025, 228, 032, 034, 035, 229, 230, 231, 232, 233, 033, 234, + 043, 151, 045, 044, 099, 047, 235, 236, 237, 054, 056, 055, 114, 062, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB850CF0 :PCollationTable = @_DB850CF0; + + + + + // DB852CZ0 Checksum: 35661 + + _DB852CZ0 :TCollationTable = ( + 000, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 172, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 001, 149, 151, 192, 174, 173, 169, 152, 159, 160, 191, 187, 146, 154, 145, 157, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 150, 147, 163, 186, 164, 148, + 170, 003, 015, 017, 025, 031, 041, 043, 045, 047, 053, 055, 057, 065, 067, 073, + 083, 085, 087, 094, 102, 108, 118, 120, 122, 124, 128, 161, 158, 162, 188, 155, + 153, 002, 014, 016, 024, 030, 040, 042, 044, 046, 052, 054, 056, 064, 066, 072, + 082, 084, 086, 093, 101, 107, 117, 119, 121, 123, 127, 165, 156, 166, 193, 222, + 021, 113, 032, 006, 010, 111, 018, 020, 062, 036, 081, 080, 050, 132, 011, 019, + 033, 059, 058, 076, 078, 061, 060, 096, 095, 079, 114, 104, 103, 063, 189, 022, + 004, 048, 074, 109, 013, 012, 134, 133, 039, 038, 255, 131, 023, 097, 167, 168, + 216, 217, 218, 194, 195, 005, 007, 035, 098, 205, 206, 207, 208, 130, 129, 196, + 197, 198, 199, 200, 201, 202, 009, 008, 209, 210, 211, 212, 213, 214, 215, 175, + 028, 029, 027, 037, 026, 071, 049, 051, 034, 203, 204, 219, 220, 106, 112, 221, + 075, 092, 077, 069, 068, 070, 100, 099, 089, 110, 088, 116, 125, 126, 105, 177, + 185, 182, 184, 178, 179, 171, 190, 183, 180, 181, 176, 115, 091, 090, 223, 224 + ); + DB852CZ0 :PCollationTable = @_DB852CZ0; + + + + + // DB867CZ0 Checksum: 9099 + + _DB867CZ0 :TCollationTable = ( + 000, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 001, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 124, 125, 126, 127, 128, 129, + 130, 003, 009, 011, 015, 019, 025, 027, 029, 031, 035, 037, 039, 045, 047, 051, + 059, 061, 063, 070, 074, 078, 086, 088, 090, 092, 096, 131, 132, 133, 134, 135, + 136, 002, 008, 010, 014, 018, 024, 026, 028, 030, 034, 036, 038, 044, 046, 050, + 058, 060, 062, 069, 073, 077, 085, 087, 089, 091, 095, 137, 138, 139, 140, 141, + 013, 083, 020, 016, 006, 017, 076, 012, 022, 023, 041, 033, 042, 040, 007, 005, + 021, 097, 098, 054, 056, 053, 081, 080, 093, 057, 084, 072, 043, 094, 067, 075, + 004, 032, 052, 079, 048, 049, 082, 055, 071, 066, 064, 065, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 068, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224 + ); + DB867CZ0 :PCollationTable = @_DB867CZ0; + + + + + // db852hdc Checksum: 7023 + + _db852hdc :TCollationTable = ( + 000, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 001, 162, 172, 168, 169, 155, 167, 174, 144, 145, 156, 153, 158, 154, 157, 163, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 160, 159, 150, 152, 151, 161, + 166, 012, 018, 019, 023, 026, 031, 032, 033, 034, 038, 039, 040, 044, 045, 048, + 053, 054, 055, 058, 062, 065, 070, 071, 072, 073, 075, 146, 164, 147, 175, 177, + 173, 079, 085, 086, 090, 093, 098, 099, 100, 101, 104, 105, 106, 109, 110, 113, + 118, 119, 120, 123, 127, 130, 135, 136, 137, 138, 140, 148, 165, 149, 176, 209, + 020, 133, 097, 082, 080, 131, 089, 087, 107, 094, 052, 117, 102, 078, 013, 022, + 030, 043, 036, 114, 116, 042, 108, 061, 126, 051, 068, 064, 129, 041, 170, 088, + 084, 103, 115, 132, 014, 081, 077, 142, 028, 095, 210, 143, 021, 124, 211, 212, + 213, 214, 215, 216, 217, 017, 015, 029, 059, 218, 219, 220, 221, 076, 141, 222, + 223, 224, 225, 226, 227, 228, 016, 083, 229, 230, 231, 232, 233, 234, 235, 236, + 091, 024, 025, 027, 092, 047, 037, 035, 096, 237, 238, 239, 240, 063, 066, 241, + 050, 171, 049, 046, 112, 111, 060, 125, 057, 067, 122, 069, 139, 074, 128, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 134, 056, 121, 254, 255 + ); + db852hdc :PCollationTable = @_db852hdc; + + + + + // db852po0 Checksum: 64062 + + _db852po0 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 194, 203, 200, 201, 187, 199, 205, 176, 177, 188, 185, 190, 186, 189, 195, + 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 192, 191, 182, 184, 183, 193, + 198, 044, 056, 058, 066, 072, 082, 084, 086, 088, 094, 096, 098, 106, 108, 114, + 124, 126, 128, 134, 143, 149, 159, 161, 163, 165, 169, 178, 196, 179, 206, 208, + 204, 043, 055, 057, 065, 071, 081, 083, 085, 087, 093, 095, 097, 105, 107, 113, + 123, 125, 127, 133, 142, 148, 158, 160, 162, 164, 168, 180, 197, 181, 207, 209, + 062, 154, 073, 047, 051, 152, 059, 061, 103, 077, 122, 121, 091, 171, 052, 060, + 074, 100, 099, 117, 119, 102, 101, 139, 138, 120, 155, 145, 144, 104, 202, 063, + 045, 089, 115, 150, 053, 054, 175, 174, 080, 079, 210, 170, 064, 135, 211, 212, + 213, 214, 215, 216, 217, 046, 050, 076, 136, 218, 219, 220, 221, 173, 172, 222, + 223, 224, 225, 226, 227, 228, 049, 048, 229, 230, 231, 232, 233, 234, 235, 236, + 069, 070, 068, 078, 067, 112, 090, 092, 075, 237, 238, 239, 240, 147, 153, 241, + 116, 137, 118, 110, 109, 111, 141, 140, 130, 151, 129, 157, 166, 167, 146, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 156, 132, 131, 254, 255 + ); + db852po0 :PCollationTable = @_db852po0; + + + + + // DB860PT0 Checksum: 33927 + + _DB860PT0 :TCollationTable = ( + 000, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, + 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, 032, + 001, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 048, 049, 050, 051, 052, 053, + 054, 168, 178, 180, 184, 186, 194, 196, 198, 200, 206, 208, 210, 212, 214, 218, + 228, 230, 232, 234, 236, 238, 246, 248, 250, 252, 254, 055, 056, 057, 058, 059, + 060, 173, 179, 182, 185, 190, 195, 197, 199, 203, 207, 209, 211, 213, 215, 223, + 229, 231, 233, 235, 237, 242, 247, 249, 251, 253, 255, 061, 062, 063, 064, 065, + 181, 244, 192, 174, 177, 176, 170, 183, 191, 187, 193, 201, 219, 205, 172, 169, + 188, 171, 189, 224, 226, 227, 239, 245, 202, 221, 240, 066, 067, 241, 068, 220, + 175, 204, 225, 243, 217, 216, 069, 070, 071, 222, 072, 073, 074, 075, 076, 077, + 078, 079, 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, + 094, 095, 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157 + ); + DB860PT0 :PCollationTable = @_DB860PT0; + + + + + // DB850PT0 Checksum: 5850 + + _DB850PT0 :TCollationTable = ( + 000, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, + 017, 018, 019, 020, 021, 023, 025, 026, 027, 028, 029, 030, 031, 032, 033, 034, + 001, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, 048, 049, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 050, 051, 052, 053, 054, 055, + 056, 151, 165, 167, 171, 173, 183, 185, 187, 189, 199, 201, 203, 205, 207, 211, + 223, 225, 227, 229, 231, 233, 243, 245, 247, 249, 254, 057, 058, 059, 060, 061, + 062, 158, 166, 169, 172, 178, 184, 186, 188, 194, 200, 202, 204, 206, 208, 217, + 224, 226, 228, 230, 232, 238, 244, 246, 248, 251, 255, 063, 064, 065, 066, 067, + 168, 240, 180, 159, 163, 161, 164, 170, 179, 182, 181, 198, 196, 197, 156, 157, + 176, 068, 069, 218, 222, 221, 242, 241, 253, 216, 235, 070, 071, 072, 073, 074, + 160, 195, 219, 239, 210, 209, 075, 076, 077, 078, 079, 080, 081, 082, 083, 084, + 085, 086, 087, 088, 089, 153, 152, 154, 090, 091, 092, 093, 094, 095, 096, 097, + 098, 099, 100, 101, 102, 103, 162, 155, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 174, 177, 175, 114, 190, 191, 193, 115, 116, 117, 118, 119, 192, 120, + 213, 121, 212, 214, 220, 215, 122, 123, 124, 234, 237, 236, 252, 250, 125, 126, + 127, 128, 129, 130, 022, 024, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140 + ); + DB850PT0 :PCollationTable = @_DB850PT0; + + + + + // db866ru0 Checksum: 43413 + + _db866ru0 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + db866ru0 :PCollationTable = @_db866ru0; + + +{$ifdef USE_BORLAND_COLLATION_TABLES} + + // BLLT1DA0 64770 + + _BLLT1DA0 :TCollationTable = ( + 000, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 020, 020, 020, 020, 020, 020, + 020, 018, 030, 032, 036, 040, 050, 052, 054, 056, 066, 068, 070, 072, 074, 078, + 089, 091, 093, 095, 098, 102, 110, 112, 114, 116, 123, 020, 020, 020, 020, 020, + 020, 019, 031, 033, 037, 041, 051, 053, 055, 057, 067, 069, 071, 073, 075, 079, + 090, 092, 094, 096, 099, 103, 111, 113, 115, 117, 124, 020, 020, 020, 020, 020, + 135, 136, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 137, 138, 139, + 140, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 141, 142, 020, + 001, 020, 020, 020, 020, 020, 020, 020, 020, 020, 021, 020, 020, 020, 020, 020, + 020, 020, 009, 011, 020, 020, 020, 020, 020, 007, 080, 020, 003, 004, 005, 020, + 024, 022, 026, 028, 127, 133, 125, 034, 044, 042, 046, 048, 060, 058, 062, 064, + 038, 076, 083, 081, 085, 087, 131, 020, 129, 106, 104, 108, 121, 118, 100, 097, + 025, 023, 027, 029, 128, 134, 126, 035, 045, 043, 047, 049, 061, 059, 063, 065, + 039, 077, 084, 082, 086, 088, 132, 020, 130, 107, 105, 109, 122, 119, 101, 120 + ); + BLLT1DA0 :PCollationTable = @_BLLT1DA0; + + + + + // BLLT1NL0 30499 + + _BLLT1NL0 :TCollationTable = ( + 000, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 018, 018, 018, 018, 018, 018, + 018, 020, 037, 039, 043, 047, 057, 059, 061, 063, 073, 075, 077, 079, 081, 085, + 100, 102, 104, 106, 109, 113, 123, 125, 127, 129, 134, 018, 018, 018, 018, 018, + 018, 019, 036, 038, 042, 046, 056, 058, 060, 062, 072, 074, 076, 078, 080, 084, + 099, 101, 103, 105, 108, 112, 122, 124, 126, 128, 133, 018, 018, 018, 018, 018, + 135, 136, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 137, 138, 139, + 140, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 141, 142, 018, + 001, 018, 018, 018, 018, 018, 018, 018, 018, 018, 021, 018, 018, 018, 018, 018, + 018, 018, 009, 011, 018, 018, 018, 018, 018, 007, 086, 018, 003, 004, 005, 018, + 025, 023, 027, 033, 031, 029, 035, 041, 051, 049, 053, 055, 067, 065, 069, 071, + 045, 083, 090, 088, 092, 096, 094, 018, 098, 117, 115, 119, 121, 131, 111, 107, + 024, 022, 026, 032, 030, 028, 034, 040, 050, 048, 052, 054, 066, 064, 068, 070, + 044, 082, 089, 087, 091, 095, 093, 018, 097, 116, 114, 118, 120, 130, 110, 132 + ); + BLLT1NL0 :PCollationTable = @_BLLT1NL0; + + BLLT1CA0 :PCollationTable = @_BLLT1NL0; + + BLLT1IT0 :PCollationTable = @_BLLT1NL0; + + BLLT1ES0 :PCollationTable = @_BLLT1NL0; + + BLLT1UK0 :PCollationTable = @_BLLT1NL0; + + BLLT1PT0 :PCollationTable = @_BLLT1NL0; + + + + + // BLLT1FI0 29479 + + _BLLT1FI0 :TCollationTable = ( + 000, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 018, 018, 018, 018, 018, 018, + 018, 020, 031, 033, 037, 041, 051, 053, 055, 057, 067, 069, 071, 073, 075, 079, + 090, 092, 094, 096, 099, 103, 111, 113, 115, 117, 124, 018, 018, 018, 018, 018, + 018, 019, 030, 032, 036, 040, 050, 052, 054, 056, 066, 068, 070, 072, 074, 078, + 089, 091, 093, 095, 098, 102, 110, 112, 114, 116, 123, 018, 018, 018, 018, 018, + 135, 136, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 137, 138, 139, + 140, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 141, 142, 018, + 001, 018, 018, 018, 018, 018, 018, 018, 018, 018, 021, 018, 018, 018, 018, 018, + 018, 018, 009, 011, 018, 018, 018, 018, 018, 007, 080, 018, 003, 004, 005, 018, + 025, 023, 027, 029, 128, 126, 130, 035, 045, 043, 047, 049, 061, 059, 063, 065, + 039, 077, 084, 082, 086, 088, 132, 018, 134, 107, 105, 109, 122, 119, 101, 097, + 024, 022, 026, 028, 127, 125, 129, 034, 044, 042, 046, 048, 060, 058, 062, 064, + 038, 076, 083, 081, 085, 087, 131, 018, 133, 106, 104, 108, 121, 118, 100, 120 + ); + BLLT1FI0 :PCollationTable = @_BLLT1FI0; + + BLLT1SV0 :PCollationTable = @_BLLT1FI0; + + + + + // BLLT1FR0 48778 + + _BLLT1FR0 :TCollationTable = ( + 000, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, 032, + 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, 048, + 049, 057, 071, 093, 087, 094, 092, 070, 074, 075, 090, 095, 054, 053, 062, 061, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 056, 055, 099, 100, 101, 059, + 084, 133, 150, 152, 156, 160, 170, 172, 174, 176, 186, 188, 190, 192, 194, 198, + 213, 215, 217, 219, 222, 226, 236, 238, 240, 242, 247, 076, 091, 077, 065, 050, + 064, 132, 149, 151, 155, 159, 169, 171, 173, 175, 185, 187, 189, 191, 193, 197, + 212, 214, 216, 218, 221, 225, 235, 237, 239, 241, 246, 078, 103, 079, 067, 107, + 248, 249, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 250, 251, 252, + 253, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 254, 255, 131, + 001, 058, 086, 088, 085, 089, 104, 080, 066, 082, 134, 072, 102, 052, 083, 051, + 105, 096, 009, 011, 063, 106, 081, 068, 069, 007, 199, 073, 003, 004, 005, 060, + 138, 136, 140, 146, 144, 142, 148, 154, 164, 162, 166, 168, 180, 178, 182, 184, + 158, 196, 203, 201, 205, 209, 207, 098, 211, 230, 228, 232, 234, 244, 224, 220, + 137, 135, 139, 145, 143, 141, 147, 153, 163, 161, 165, 167, 179, 177, 181, 183, + 157, 195, 202, 200, 204, 208, 206, 097, 210, 229, 227, 231, 233, 243, 223, 245 + ); + BLLT1FR0 :PCollationTable = @_BLLT1FR0; + + BLLT1DE0 :PCollationTable = @_BLLT1FR0; + + + + + // BLLT1IS0 64857 + + _BLLT1IS0 :TCollationTable = ( + 000, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 018, 018, 018, 018, 018, 018, + 018, 020, 035, 037, 041, 045, 055, 057, 059, 061, 071, 073, 075, 077, 079, 083, + 094, 096, 098, 100, 103, 105, 115, 117, 119, 121, 126, 018, 018, 018, 018, 018, + 018, 019, 034, 036, 040, 044, 054, 056, 058, 060, 070, 072, 074, 076, 078, 082, + 093, 095, 097, 099, 102, 104, 114, 116, 118, 120, 125, 018, 018, 018, 018, 018, + 135, 136, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 137, 138, 139, + 140, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 141, 142, 018, + 001, 018, 018, 018, 018, 018, 018, 018, 018, 018, 021, 018, 018, 018, 018, 018, + 018, 018, 009, 011, 018, 018, 018, 018, 018, 007, 084, 018, 003, 004, 005, 018, + 023, 033, 025, 031, 029, 027, 130, 039, 047, 053, 049, 051, 063, 069, 065, 067, + 043, 081, 086, 092, 088, 090, 132, 018, 134, 107, 113, 109, 111, 124, 128, 101, + 022, 032, 024, 030, 028, 026, 129, 038, 046, 052, 048, 050, 062, 068, 064, 066, + 042, 080, 085, 091, 087, 089, 131, 018, 133, 106, 112, 108, 110, 123, 127, 122 + ); + BLLT1IS0 :PCollationTable = @_BLLT1IS0; + + + + + // BLLT1NO0 17250 + + _BLLT1NO0 :TCollationTable = ( + 000, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 020, 020, 020, 020, 020, 020, + 020, 019, 033, 035, 039, 043, 053, 055, 057, 059, 069, 071, 073, 075, 077, 081, + 094, 096, 098, 100, 103, 107, 117, 119, 121, 123, 128, 020, 020, 020, 020, 020, + 020, 018, 032, 034, 038, 042, 052, 054, 056, 058, 068, 070, 072, 074, 076, 080, + 093, 095, 097, 099, 102, 106, 116, 118, 120, 122, 127, 020, 020, 020, 020, 020, + 135, 136, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 137, 138, 139, + 140, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 141, 142, 020, + 001, 020, 020, 020, 020, 020, 020, 020, 020, 020, 021, 020, 020, 020, 020, 020, + 020, 020, 009, 011, 020, 020, 020, 020, 020, 007, 082, 020, 003, 004, 005, 020, + 025, 023, 027, 031, 029, 134, 130, 037, 047, 045, 049, 051, 063, 061, 065, 067, + 041, 079, 086, 084, 088, 092, 090, 020, 132, 111, 109, 113, 115, 125, 105, 101, + 024, 022, 026, 030, 028, 133, 129, 036, 046, 044, 048, 050, 062, 060, 064, 066, + 040, 078, 085, 083, 087, 091, 089, 020, 131, 110, 108, 112, 114, 124, 104, 126 + ); + BLLT1NO0 :PCollationTable = @_BLLT1NO0; + +{$endif} + + + // DB850US0 Checksum: 43413 + + _DB850US0 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB850US0 :PCollationTable = @_DB850US0; + + + + +{$ifdef USE_PARADOX_COLLATIONS} + + // intl850 43039 + + _intl850 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 073, 083, 086, 090, 097, 103, 105, 107, 113, 119, 121, 123, 125, 128, 137, + 146, 148, 150, 152, 155, 162, 169, 171, 173, 177, 180, 181, 182, 183, 184, 185, + 186, 065, 082, 084, 088, 092, 102, 104, 106, 108, 118, 120, 122, 124, 126, 130, + 145, 147, 149, 151, 154, 158, 168, 170, 172, 174, 179, 187, 188, 189, 190, 191, + 035, 035, 035, 194, 035, 035, 035, 035, 035, 035, 152, 035, 137, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 151, 035, 130, 035, 035, 177, + 224, 200, 204, 192, 206, 205, 207, 215, 219, 203, 066, 201, 197, 211, 196, 209, + 218, 212, 223, 222, 210, 208, 214, 220, 217, 221, 131, 202, 199, 198, 213, 195, + 076, 075, 077, 079, 081, 078, 074, 087, 100, 099, 101, 098, 116, 115, 117, 114, + 091, 129, 139, 138, 140, 141, 144, 193, 142, 164, 163, 165, 167, 178, 157, 153, + 069, 068, 070, 072, 080, 071, 067, 085, 095, 094, 096, 093, 111, 110, 112, 109, + 089, 127, 133, 132, 134, 135, 143, 216, 136, 160, 159, 161, 166, 176, 156, 175 + ); + intl850 :PCollationTable = @_intl850; + + + // SPANISH 20109 + + _SPANISH :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, 048, + 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, 064, + 066, 074, 080, 083, 086, 092, 095, 097, 099, 105, 107, 109, 111, 113, 115, 124, + 127, 129, 131, 133, 136, 142, 145, 147, 149, 152, 154, 155, 156, 157, 158, 159, + 160, 067, 079, 081, 085, 087, 094, 096, 098, 100, 106, 108, 110, 112, 114, 118, + 126, 128, 130, 132, 135, 137, 144, 146, 148, 150, 153, 161, 162, 163, 164, 165, + 036, 036, 036, 169, 036, 036, 036, 036, 036, 036, 133, 036, 124, 036, 036, 036, + 036, 036, 036, 036, 036, 036, 036, 036, 036, 036, 132, 036, 118, 036, 036, 152, + 181, 034, 166, 167, 036, 168, 036, 036, 036, 036, 068, 173, 170, 036, 036, 036, + 178, 176, 180, 036, 036, 175, 036, 179, 036, 036, 119, 174, 172, 171, 036, 065, + 074, 074, 074, 074, 075, 076, 078, 084, 092, 093, 092, 092, 105, 105, 105, 105, + 086, 117, 124, 124, 124, 124, 125, 036, 124, 142, 142, 142, 143, 152, 036, 134, + 070, 069, 071, 067, 072, 073, 077, 082, 089, 088, 090, 091, 102, 101, 103, 104, + 085, 116, 121, 120, 122, 118, 123, 177, 118, 139, 138, 140, 141, 150, 036, 151 + ); + SPANISH :PCollationTable = @_SPANISH; + + + + + + + // iceland 23936 + + _iceland :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 070, 076, 079, 082, 089, 093, 095, 097, 099, 103, 105, 107, 109, 111, 114, + 118, 120, 122, 124, 126, 130, 135, 137, 139, 141, 145, 154, 155, 156, 157, 158, + 159, 065, 075, 077, 081, 085, 092, 094, 096, 098, 102, 104, 106, 108, 110, 112, + 117, 119, 121, 123, 125, 127, 134, 136, 138, 140, 144, 160, 161, 162, 163, 035, + 035, 035, 035, 165, 035, 035, 035, 035, 035, 035, 124, 035, 114, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 123, 035, 112, 035, 035, 141, + 180, 170, 035, 164, 035, 035, 035, 035, 035, 035, 035, 171, 167, 035, 035, 035, + 177, 175, 179, 035, 035, 174, 035, 178, 035, 035, 035, 172, 169, 168, 035, 166, + 070, 074, 070, 070, 072, 071, 149, 080, 089, 091, 089, 089, 099, 101, 099, 099, + 084, 111, 114, 116, 114, 114, 152, 035, 153, 130, 133, 130, 131, 143, 147, 173, + 066, 073, 067, 065, 069, 068, 148, 078, 086, 090, 087, 088, 098, 100, 098, 098, + 083, 110, 112, 115, 113, 112, 150, 176, 151, 127, 132, 128, 129, 142, 146, 140 + ); + iceland :PCollationTable = @_iceland; + + + + + + + // ANSIINTL 58462 + + _ANSIINTL :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 070, 078, 081, 085, 092, 098, 100, 102, 108, 114, 116, 118, 120, 123, 131, + 140, 142, 144, 146, 149, 156, 163, 165, 167, 171, 174, 177, 178, 179, 180, 181, + 182, 065, 077, 079, 083, 087, 097, 099, 101, 103, 113, 115, 117, 119, 121, 125, + 139, 141, 143, 145, 148, 152, 162, 164, 166, 168, 173, 183, 184, 185, 186, 187, + 248, 249, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 250, 251, 252, + 253, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 254, 255, 213, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 072, 071, 073, 074, 076, 176, 189, 082, 095, 094, 096, 093, 111, 110, 112, 109, + 086, 124, 133, 132, 134, 135, 138, 246, 136, 158, 157, 159, 161, 172, 151, 147, + 067, 066, 068, 069, 075, 175, 188, 080, 090, 089, 091, 088, 106, 105, 107, 104, + 084, 122, 127, 126, 128, 129, 137, 247, 130, 154, 153, 155, 160, 170, 150, 169 + ); + ANSIINTL :PCollationTable = @_ANSIINTL; + + + + + + + // ANSII850 29000 + + _ANSII850 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 073, 083, 086, 090, 097, 103, 105, 107, 113, 119, 121, 123, 125, 128, 137, + 146, 148, 150, 152, 155, 162, 169, 171, 173, 177, 180, 181, 182, 183, 184, 185, + 186, 065, 082, 084, 088, 092, 102, 104, 106, 108, 118, 120, 122, 124, 126, 130, + 145, 147, 149, 151, 154, 158, 168, 170, 172, 174, 179, 187, 188, 189, 190, 191, + 248, 249, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 250, 251, 252, + 253, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 254, 255, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 066, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 131, 241, 242, 243, 244, 245, + 076, 075, 077, 079, 081, 078, 074, 087, 100, 099, 101, 098, 116, 115, 117, 114, + 091, 129, 139, 138, 140, 141, 144, 246, 142, 164, 163, 165, 167, 178, 157, 153, + 069, 068, 070, 072, 080, 071, 067, 085, 095, 094, 096, 093, 111, 110, 112, 109, + 089, 127, 133, 132, 134, 135, 143, 247, 136, 160, 159, 161, 166, 176, 156, 175 + ); + ANSII850 :PCollationTable = @_ANSII850; + + + + + + + // ANSISPAN 33308 + + _ANSISPAN :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, 048, + 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, 064, + 066, 075, 085, 088, 092, 099, 105, 107, 109, 115, 121, 123, 125, 127, 129, 140, + 148, 150, 152, 154, 158, 165, 171, 173, 175, 179, 182, 183, 184, 185, 186, 187, + 188, 067, 084, 086, 090, 094, 104, 106, 108, 110, 120, 122, 124, 126, 128, 132, + 147, 149, 151, 153, 156, 160, 170, 172, 174, 176, 181, 189, 190, 191, 192, 193, + 248, 249, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 250, 251, 252, + 253, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 254, 255, 217, + 218, 034, 219, 220, 221, 222, 223, 224, 225, 226, 069, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 133, 242, 243, 244, 245, 065, + 077, 076, 078, 079, 080, 081, 083, 089, 102, 101, 103, 100, 118, 117, 119, 116, + 093, 131, 142, 141, 143, 145, 144, 246, 146, 167, 166, 168, 169, 180, 159, 155, + 070, 068, 071, 072, 073, 074, 082, 087, 096, 095, 097, 098, 112, 111, 113, 114, + 091, 130, 135, 134, 136, 138, 137, 247, 139, 162, 161, 163, 164, 177, 157, 178 + ); + ANSISPAN :PCollationTable = @_ANSISPAN; + + + + + + + // ANSISWFN 44782 + + _ANSISWFN :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 070, 076, 079, 083, 090, 096, 098, 100, 106, 112, 114, 116, 118, 121, 128, + 134, 136, 138, 140, 142, 149, 154, 156, 158, 162, 165, 178, 179, 180, 181, 182, + 183, 065, 075, 077, 081, 085, 095, 097, 099, 101, 111, 113, 115, 117, 119, 123, + 133, 135, 137, 139, 141, 145, 153, 155, 157, 159, 164, 184, 185, 186, 187, 188, + 248, 249, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 250, 251, 252, + 253, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 254, 255, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 072, 071, 073, 074, 173, 171, 167, 080, 093, 092, 094, 091, 109, 108, 110, 107, + 084, 122, 130, 129, 131, 132, 175, 245, 169, 151, 150, 152, 177, 163, 144, 246, + 067, 066, 068, 069, 172, 170, 166, 078, 088, 087, 089, 086, 104, 103, 105, 102, + 082, 120, 125, 124, 126, 127, 174, 247, 168, 147, 146, 148, 176, 160, 143, 161 + ); + ANSISWFN :PCollationTable = @_ANSISWFN; + + + + + + + // ANSINOR4 55290 + + _ANSINOR4 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 075, 077, 081, 085, 095, 097, 099, 101, 111, 113, 115, 117, 119, 123, + 133, 135, 137, 139, 141, 145, 153, 155, 157, 159, 166, 178, 179, 180, 181, 182, + 183, 070, 076, 079, 083, 090, 096, 098, 100, 106, 112, 114, 116, 118, 121, 128, + 134, 136, 138, 140, 142, 149, 154, 156, 158, 162, 167, 184, 185, 186, 187, 188, + 248, 249, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 250, 251, 252, + 253, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 254, 255, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 067, 066, 068, 069, 169, 176, 168, 078, 088, 087, 089, 086, 104, 103, 105, 102, + 082, 120, 125, 124, 126, 127, 173, 245, 172, 147, 146, 148, 161, 160, 143, 246, + 072, 071, 073, 074, 171, 177, 170, 080, 093, 092, 094, 091, 109, 108, 110, 107, + 084, 122, 130, 129, 131, 132, 175, 247, 174, 151, 150, 152, 165, 164, 144, 163 + ); + ANSINOR4 :PCollationTable = @_ANSINOR4; + +{$endif} + + + + + // china 54324 + + _china :TCollationTable = ( + 000, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127 + ); + + DB936CN0 :PCollationTable = @_china; + + DB949KO0 :PCollationTable = @_china; + + DB950TW0 :PCollationTable = @_china; + + + + + // thai Checksum: 9864 + + _thai :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 191, + 192, 183, 193, 184, 185, 186, 187, 188, 189, 190, 175, 243, 244, 245, 246, 194, + 247, 248, 249, 250, 251, 195, 196, 176, 177, 178, 179, 180, 181, 182, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 252, 253, 254, 255 + ); + +{$ifdef USE_PARADOX_COLLATIONS} + china :PCollationTable = @_china; + + korea :PCollationTable = @_china; + + taiwan :PCollationTable = @_china; + + thai :PCollationTable = @_thai; +{$endif} + + db874th0 :PCollationTable = @_thai; + + + + + // DB932JP1 Checksum: 8911 + + _DB932JP1 :TCollationTable = ( + 000, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 065, 075, 118, 135, 133, 134, 136, 117, 119, 120, 137, 127, 069, 128, 070, 114, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 072, 073, 130, 129, 131, 074, + 138, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, + 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 121, 132, 122, 078, 111, + 112, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, + 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 123, 116, 124, 115, 110, + 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, + 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, 032, + 066, 068, 125, 126, 067, 071, 254, 201, 203, 205, 207, 209, 242, 244, 246, 223, + 113, 202, 204, 206, 208, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 243, 245, 247, 248, 249, 250, 251, 252, 253, 255, 076, 077, + 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, 048, + 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, 064 + ); + DB932JP1 :PCollationTable = @_DB932JP1; + + + + + // DBWINWE0 5562 + + _DBWINWE0 :TCollationTable = ( + 000, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, + 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, 032, + 001, 041, 055, 077, 071, 078, 076, 054, 058, 059, 074, 079, 038, 037, 046, 045, + 111, 115, 117, 119, 121, 122, 123, 124, 125, 126, 040, 039, 083, 084, 085, 043, + 068, 128, 145, 147, 151, 155, 165, 167, 169, 171, 181, 183, 185, 187, 189, 193, + 210, 212, 214, 216, 221, 225, 235, 237, 239, 241, 247, 060, 075, 061, 049, 034, + 048, 127, 144, 146, 150, 154, 164, 166, 168, 170, 180, 182, 184, 186, 188, 192, + 209, 211, 213, 215, 220, 224, 234, 236, 238, 240, 246, 062, 087, 063, 051, 091, + 248, 249, 092, 093, 094, 095, 096, 097, 098, 099, 218, 100, 208, 250, 251, 252, + 253, 101, 102, 103, 104, 105, 106, 107, 108, 109, 217, 110, 207, 254, 255, 245, + 033, 042, 070, 072, 069, 073, 088, 064, 050, 066, 129, 056, 086, 036, 067, 035, + 089, 080, 118, 120, 047, 090, 065, 052, 053, 116, 194, 057, 112, 113, 114, 044, + 133, 131, 135, 141, 139, 137, 143, 149, 159, 157, 161, 163, 175, 173, 177, 179, + 153, 191, 198, 196, 200, 204, 202, 082, 206, 229, 227, 231, 233, 243, 223, 219, + 132, 130, 134, 140, 138, 136, 142, 148, 158, 156, 160, 162, 174, 172, 176, 178, + 152, 190, 197, 195, 199, 203, 201, 081, 205, 228, 226, 230, 232, 242, 222, 244 + ); + DBWINWE0 :PCollationTable = @_DBWINWE0; + + DBWINES0 :PCollationTable = @_DBWINWE0; + + +{$ifdef USE_ACCESS_COLLATIONS} + + // ACCGEN 19621 + + _ACCGEN :TCollationTable = ( + 000, 001, 001, 001, 001, 001, 001, 001, 001, 002, 001, 001, 001, 001, 001, 001, + 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, + 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, 018, + 072, 073, 074, 075, 076, 077, 078, 079, 080, 081, 019, 020, 021, 022, 023, 024, + 025, 082, 090, 091, 093, 095, 100, 101, 102, 103, 108, 109, 110, 111, 112, 114, + 121, 122, 123, 124, 127, 128, 133, 134, 135, 136, 139, 026, 027, 028, 029, 030, + 031, 082, 090, 091, 093, 095, 100, 101, 102, 103, 108, 109, 110, 111, 112, 114, + 121, 122, 123, 124, 127, 128, 133, 134, 135, 136, 139, 032, 033, 034, 035, 001, + 142, 143, 010, 036, 005, 037, 038, 039, 040, 041, 125, 010, 120, 144, 145, 146, + 147, 010, 010, 005, 005, 042, 016, 016, 043, 044, 125, 010, 120, 148, 149, 138, + 003, 045, 046, 047, 048, 049, 050, 051, 052, 053, 054, 005, 055, 016, 056, 057, + 058, 059, 074, 075, 060, 061, 062, 063, 064, 073, 065, 005, 066, 067, 068, 069, + 083, 084, 085, 087, 086, 088, 089, 092, 096, 097, 098, 099, 104, 105, 106, 107, + 094, 113, 115, 116, 117, 119, 118, 070, 141, 129, 130, 131, 132, 137, 140, 126, + 083, 084, 085, 087, 086, 088, 089, 092, 096, 097, 098, 099, 104, 105, 106, 107, + 094, 113, 115, 116, 117, 119, 118, 071, 141, 129, 130, 131, 132, 137, 140, 138 + ); + ACCGEN :PCollationTable = @_ACCGEN; + + + + + // ACCNRDAN 24816 + + _ACCNRDAN :TCollationTable = ( + 000, 001, 001, 001, 001, 001, 001, 001, 001, 002, 001, 001, 001, 001, 001, 001, + 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, + 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, 018, + 072, 073, 074, 075, 076, 077, 078, 079, 080, 081, 019, 020, 021, 022, 023, 024, + 025, 140, 086, 087, 089, 091, 096, 097, 098, 099, 104, 105, 106, 107, 108, 110, + 116, 117, 118, 119, 122, 124, 128, 129, 130, 131, 135, 026, 027, 028, 029, 030, + 031, 140, 086, 087, 089, 091, 096, 097, 098, 099, 104, 105, 106, 107, 108, 110, + 116, 117, 118, 119, 122, 124, 128, 129, 130, 131, 135, 032, 033, 034, 035, 001, + 142, 143, 010, 036, 005, 037, 038, 039, 040, 041, 120, 010, 115, 144, 145, 146, + 147, 010, 010, 005, 005, 042, 016, 016, 043, 044, 120, 010, 115, 148, 149, 133, + 003, 045, 046, 047, 048, 049, 050, 051, 052, 053, 054, 005, 055, 016, 056, 057, + 058, 059, 074, 075, 060, 061, 062, 063, 064, 073, 065, 005, 066, 067, 068, 069, + 083, 082, 084, 085, 137, 141, 136, 088, 093, 092, 094, 095, 101, 100, 102, 103, + 090, 109, 112, 111, 113, 114, 139, 070, 138, 126, 125, 127, 134, 132, 123, 121, + 083, 082, 084, 085, 137, 141, 136, 088, 093, 092, 094, 095, 101, 100, 102, 103, + 090, 109, 112, 111, 113, 114, 139, 071, 138, 126, 125, 127, 134, 132, 123, 133 + ); + ACCNRDAN :PCollationTable = @_ACCNRDAN; + + + + + // ACCSWFIN 39386 + + _ACCSWFIN :TCollationTable = ( + 000, 001, 001, 001, 001, 001, 001, 001, 001, 002, 001, 001, 001, 001, 001, 001, + 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, + 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, 018, + 072, 073, 074, 075, 076, 077, 078, 079, 080, 081, 019, 020, 021, 022, 023, 024, + 025, 082, 088, 089, 091, 093, 098, 099, 100, 101, 106, 107, 108, 109, 110, 112, + 118, 119, 120, 121, 124, 126, 130, 131, 132, 133, 137, 026, 027, 028, 029, 030, + 031, 082, 088, 089, 091, 093, 098, 099, 100, 101, 106, 107, 108, 109, 110, 112, + 118, 119, 120, 121, 124, 126, 130, 131, 132, 133, 137, 032, 033, 034, 035, 001, + 142, 143, 010, 036, 005, 037, 038, 039, 040, 041, 122, 010, 117, 144, 145, 146, + 147, 010, 010, 005, 005, 042, 016, 016, 043, 044, 122, 010, 117, 148, 149, 135, + 003, 045, 046, 047, 048, 049, 050, 051, 052, 053, 054, 005, 055, 016, 056, 057, + 058, 059, 074, 075, 060, 061, 062, 063, 064, 073, 065, 005, 066, 067, 068, 069, + 084, 083, 085, 086, 139, 138, 087, 090, 095, 094, 096, 097, 103, 102, 104, 105, + 092, 111, 114, 113, 115, 116, 140, 070, 141, 128, 127, 129, 136, 134, 125, 123, + 084, 083, 085, 086, 139, 138, 087, 090, 095, 094, 096, 097, 103, 102, 104, 105, + 092, 111, 114, 113, 115, 116, 140, 071, 141, 128, 127, 129, 136, 134, 125, 135 + ); + ACCSWFIN :PCollationTable = @_ACCSWFIN; + +{$endif} + + + // FOXDE437 Checksum: 21075 + + _FOXDE437 :TCollationTable = ( + 000, 125, 125, 125, 125, 125, 125, 125, 125, 127, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 143, 144, 145, 146, 147, 148, + 149, 171, 182, 184, 188, 190, 197, 199, 201, 203, 209, 211, 213, 215, 217, 221, + 226, 228, 230, 232, 237, 239, 246, 248, 250, 252, 255, 150, 151, 152, 153, 154, + 155, 171, 182, 184, 188, 190, 197, 199, 201, 203, 209, 211, 213, 215, 217, 221, + 226, 228, 230, 232, 237, 239, 246, 248, 250, 252, 255, 156, 157, 158, 159, 125, + 186, 244, 192, 174, 180, 173, 176, 186, 194, 195, 193, 207, 206, 205, 180, 176, + 192, 180, 180, 224, 235, 223, 242, 241, 253, 235, 244, 125, 125, 125, 125, 125, + 172, 204, 222, 240, 219, 219, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 235, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125 + ); + FOXDE437 :PCollationTable = @_FOXDE437; + + + + + // FOXNO437 Checksum: 473 + + _FOXNO437 :TCollationTable = ( + 000, 125, 125, 125, 125, 125, 125, 125, 125, 127, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 143, 144, 145, 146, 147, 148, + 149, 171, 176, 178, 182, 184, 191, 193, 195, 197, 203, 205, 207, 209, 211, 215, + 220, 222, 224, 226, 229, 231, 236, 238, 240, 242, 247, 150, 151, 152, 153, 154, + 155, 171, 176, 178, 182, 184, 191, 193, 195, 197, 203, 205, 207, 209, 211, 215, + 220, 222, 224, 226, 229, 231, 236, 238, 240, 242, 247, 156, 157, 158, 159, 125, + 180, 245, 187, 174, 251, 172, 255, 180, 188, 189, 185, 201, 200, 198, 251, 255, + 187, 249, 249, 218, 253, 216, 234, 232, 245, 253, 245, 125, 125, 125, 125, 125, + 173, 199, 217, 233, 213, 213, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 227, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125 + ); + FOXNO437 :PCollationTable = @_FOXNO437 ; + + + + + // FOXNO850 Checksum: 62 + + _FOXNO850 :TCollationTable = ( + 000, 096, 096, 096, 096, 096, 096, 096, 096, 098, 096, 096, 096, 096, 096, 096, + 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, + 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 114, 115, 116, 117, 118, 119, + 120, 143, 153, 155, 159, 163, 173, 175, 177, 179, 189, 191, 193, 195, 197, 201, + 211, 213, 215, 217, 220, 222, 230, 232, 234, 236, 243, 121, 122, 123, 124, 125, + 126, 143, 153, 155, 159, 163, 173, 175, 177, 179, 189, 191, 193, 195, 197, 201, + 211, 213, 215, 217, 220, 222, 230, 232, 234, 236, 243, 127, 128, 129, 130, 096, + 157, 241, 167, 149, 249, 145, 255, 157, 169, 171, 165, 187, 185, 181, 249, 255, + 167, 247, 247, 207, 253, 203, 228, 224, 241, 253, 241, 251, 096, 251, 096, 096, + 147, 183, 205, 226, 199, 199, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, + 096, 096, 096, 096, 096, 147, 149, 145, 131, 096, 096, 096, 096, 096, 096, 096, + 096, 096, 096, 096, 096, 096, 151, 151, 096, 096, 096, 096, 096, 096, 096, 096, + 161, 161, 169, 171, 165, 096, 183, 185, 187, 096, 096, 096, 096, 096, 181, 096, + 205, 218, 207, 203, 209, 209, 096, 245, 245, 226, 228, 224, 238, 238, 096, 096, + 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096 + ); + FOXNO850 :PCollationTable = @_FOXNO850; + + + + + // FOXDEWIN 44890 + + _FOXDEWIN :TCollationTable = ( + 000, 001, 001, 001, 001, 001, 001, 001, 001, 002, 001, 001, 001, 001, 001, 001, + 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, + 072, 073, 074, 075, 076, 077, 078, 079, 080, 081, 019, 020, 021, 022, 023, 024, + 025, 082, 089, 090, 092, 094, 099, 100, 101, 102, 107, 108, 109, 110, 111, 113, + 119, 120, 121, 122, 125, 127, 132, 133, 134, 135, 138, 026, 027, 028, 029, 030, + 031, 082, 089, 090, 092, 094, 099, 100, 101, 102, 107, 108, 109, 110, 111, 113, + 119, 120, 121, 122, 125, 127, 132, 133, 134, 135, 138, 032, 033, 034, 035, 001, + 140, 141, 009, 036, 004, 037, 038, 039, 040, 041, 123, 009, 118, 142, 143, 144, + 145, 009, 009, 004, 004, 042, 015, 015, 043, 044, 123, 009, 118, 146, 147, 137, + 018, 045, 046, 047, 048, 049, 050, 051, 052, 053, 054, 004, 055, 015, 056, 057, + 058, 059, 074, 075, 060, 061, 062, 063, 064, 073, 065, 004, 066, 067, 068, 069, + 084, 083, 085, 086, 088, 087, 088, 091, 096, 095, 097, 098, 104, 103, 105, 106, + 093, 112, 115, 114, 116, 117, 118, 070, 139, 129, 128, 130, 131, 136, 126, 124, + 084, 083, 085, 086, 088, 087, 088, 091, 096, 095, 097, 098, 104, 103, 105, 106, + 093, 112, 115, 114, 116, 117, 118, 071, 139, 129, 128, 130, 131, 136, 126, 137 + ); + FOXDEWIN :PCollationTable = @_FOXDEWIN; + + + + + // FOXNOWIN Checksum: 58863 + + _FOXNOWIN :TCollationTable = ( + 000, 031, 031, 031, 031, 031, 031, 031, 031, 033, 031, 031, 031, 031, 031, 031, + 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, + 033, 035, 041, 042, 043, 044, 045, 051, 052, 053, 054, 055, 056, 060, 061, 062, + 116, 118, 120, 122, 123, 124, 125, 126, 127, 128, 063, 064, 065, 066, 067, 068, + 069, 130, 140, 142, 146, 150, 160, 162, 164, 166, 176, 178, 180, 182, 184, 188, + 200, 202, 204, 206, 211, 213, 223, 225, 227, 229, 235, 070, 071, 072, 073, 074, + 075, 130, 140, 142, 146, 150, 160, 162, 164, 166, 176, 178, 180, 182, 184, 188, + 200, 202, 204, 206, 211, 213, 223, 225, 227, 229, 235, 076, 077, 078, 079, 031, + 248, 249, 051, 080, 041, 081, 082, 083, 084, 085, 208, 051, 198, 250, 251, 252, + 253, 051, 051, 041, 041, 086, 060, 060, 087, 088, 208, 051, 198, 254, 255, 233, + 034, 089, 090, 091, 092, 093, 094, 095, 096, 097, 098, 041, 099, 060, 100, 101, + 102, 103, 120, 122, 104, 105, 106, 107, 108, 118, 109, 041, 110, 111, 112, 113, + 134, 132, 136, 138, 241, 247, 239, 144, 154, 152, 156, 158, 170, 168, 172, 174, + 148, 186, 192, 190, 194, 196, 245, 114, 243, 217, 215, 219, 221, 231, 237, 209, + 134, 132, 136, 138, 241, 247, 239, 144, 154, 152, 156, 158, 170, 168, 172, 174, + 148, 186, 192, 190, 194, 196, 245, 115, 243, 217, 215, 219, 221, 231, 237, 233 + ); + FOXNOWIN :PCollationTable = @_FOXNOWIN; + + + + +{$ifdef USE_PARADOX_COLLATIONS} + + // czech 30844 + + _czech :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 074, 076, 080, 082, 088, 090, 092, 094, 100, 102, 104, 106, 108, 110, + 118, 120, 122, 124, 129, 131, 137, 139, 141, 143, 147, 148, 149, 150, 151, 152, + 153, 065, 073, 075, 079, 081, 087, 089, 091, 093, 099, 101, 103, 105, 107, 109, + 117, 119, 121, 123, 128, 130, 136, 138, 140, 142, 146, 154, 155, 156, 157, 035, + 035, 035, 035, 087, 035, 035, 035, 035, 035, 035, 127, 035, 110, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 126, 035, 109, 035, 035, 143, + 170, 035, 035, 035, 162, 035, 035, 165, 169, 035, 035, 160, 159, 164, 035, 035, + 168, 035, 035, 035, 163, 035, 035, 035, 167, 035, 035, 161, 035, 035, 035, 035, + 066, 068, 070, 066, 072, 066, 066, 078, 082, 084, 082, 086, 094, 096, 098, 094, + 080, 108, 110, 112, 114, 110, 116, 158, 110, 131, 133, 131, 135, 145, 035, 125, + 065, 067, 069, 065, 071, 065, 065, 077, 081, 083, 081, 085, 093, 095, 097, 093, + 079, 107, 109, 111, 113, 109, 115, 166, 109, 130, 132, 130, 134, 144, 035, 142 + ); + czech :PCollationTable = @_czech; + + + + + // czechw 30844 + + czechw :PCollationTable = @_czech; + + + + + + // il2czw 13611 + + _il2czw :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 074, 076, 080, 082, 088, 090, 092, 094, 100, 102, 104, 106, 108, 110, + 118, 120, 122, 124, 129, 131, 137, 139, 141, 143, 147, 148, 149, 150, 151, 152, + 153, 065, 073, 075, 079, 081, 087, 089, 091, 093, 099, 101, 103, 105, 107, 109, + 117, 119, 121, 123, 128, 130, 136, 138, 140, 142, 146, 154, 155, 156, 157, 035, + 035, 035, 035, 087, 035, 035, 035, 035, 035, 035, 127, 035, 110, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 126, 035, 109, 035, 035, 143, + 158, 035, 035, 035, 159, 035, 035, 160, 161, 035, 035, 035, 035, 162, 035, 035, + 163, 035, 035, 035, 164, 035, 035, 035, 165, 035, 035, 035, 035, 035, 035, 035, + 066, 068, 070, 066, 072, 066, 066, 078, 082, 084, 082, 086, 094, 096, 098, 094, + 080, 108, 110, 112, 114, 110, 116, 166, 110, 131, 133, 131, 135, 145, 035, 125, + 065, 067, 069, 065, 071, 065, 065, 077, 081, 083, 081, 085, 093, 095, 097, 093, + 079, 107, 109, 111, 113, 109, 115, 167, 109, 130, 132, 130, 134, 144, 035, 142 + ); + il2czw :PCollationTable = @_il2czw; + + + + + + // polish 59020 + + _polish :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 074, 076, 080, 082, 088, 090, 092, 094, 100, 102, 104, 106, 108, 110, + 118, 120, 122, 124, 129, 131, 137, 139, 141, 143, 147, 148, 149, 150, 151, 152, + 153, 065, 073, 075, 079, 081, 087, 089, 091, 093, 099, 101, 103, 105, 107, 109, + 117, 119, 121, 123, 128, 130, 136, 138, 140, 142, 146, 154, 155, 156, 157, 035, + 035, 035, 035, 087, 035, 035, 035, 035, 035, 035, 126, 035, 110, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 125, 035, 109, 035, 035, 143, + 170, 035, 035, 035, 162, 035, 035, 165, 169, 035, 035, 160, 159, 164, 035, 035, + 168, 035, 035, 035, 163, 035, 035, 035, 167, 035, 035, 161, 035, 035, 035, 035, + 066, 068, 070, 066, 072, 066, 066, 078, 082, 084, 082, 086, 094, 096, 098, 094, + 080, 108, 110, 112, 114, 110, 116, 158, 110, 131, 133, 131, 135, 145, 035, 127, + 065, 067, 069, 065, 071, 065, 065, 077, 081, 083, 081, 085, 093, 095, 097, 093, + 079, 107, 109, 111, 113, 109, 115, 166, 109, 130, 132, 130, 134, 144, 035, 142 + ); + polish :PCollationTable = @_polish; + + + + + + + // cyrr 20081 + + _cyrr :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 068, 070, 072, 074, 076, 078, 080, 082, 084, 086, 088, 090, 092, 094, + 096, 098, 100, 102, 104, 106, 108, 110, 112, 114, 116, 117, 118, 119, 120, 121, + 122, 065, 067, 069, 071, 073, 075, 077, 079, 081, 083, 085, 087, 089, 091, 093, + 095, 097, 099, 101, 103, 105, 107, 109, 111, 113, 115, 123, 124, 125, 126, 127, + 035, 035, 035, 075, 035, 035, 035, 035, 035, 035, 102, 035, 094, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 101, 035, 093, 035, 035, 114, + 131, 035, 035, 035, 130, 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, + 128, 035, 035, 035, 035, 035, 035, 129, 035, 035, 035, 035, 035, 035, 035, 035, + 066, 066, 066, 066, 066, 066, 066, 070, 074, 074, 074, 074, 082, 082, 082, 082, + 072, 092, 094, 094, 094, 094, 094, 035, 094, 106, 106, 106, 106, 114, 035, 035, + 065, 065, 065, 065, 065, 065, 065, 069, 073, 073, 073, 073, 081, 081, 081, 081, + 071, 091, 093, 093, 093, 093, 093, 035, 093, 105, 105, 105, 105, 113, 035, 113 + ); + cyrr :PCollationTable = @_cyrr; + + + + + + + // hun852dc 62898 + + _hun852dc :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 070, 072, 074, 076, 080, 082, 084, 086, 090, 092, 094, 096, 098, 100, + 107, 109, 111, 113, 115, 117, 123, 125, 127, 129, 131, 132, 133, 134, 135, 136, + 137, 065, 069, 071, 073, 075, 079, 081, 083, 085, 089, 091, 093, 095, 097, 099, + 106, 108, 110, 112, 114, 116, 122, 124, 126, 128, 130, 138, 139, 140, 141, 035, + 035, 035, 035, 079, 035, 035, 035, 035, 035, 035, 159, 035, 100, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 160, 035, 099, 035, 035, 129, + 170, 035, 035, 035, 154, 035, 035, 165, 169, 035, 035, 151, 150, 164, 035, 035, + 168, 035, 035, 035, 163, 035, 035, 035, 167, 035, 035, 152, 035, 035, 035, 035, + 066, 068, 153, 066, 148, 066, 066, 142, 076, 078, 076, 155, 086, 088, 156, 086, + 074, 098, 100, 102, 158, 100, 105, 149, 100, 117, 119, 117, 121, 162, 035, 157, + 065, 067, 143, 065, 144, 065, 065, 145, 075, 077, 075, 146, 085, 087, 147, 085, + 073, 097, 099, 101, 104, 099, 103, 166, 099, 116, 118, 116, 120, 161, 035, 128 + ); + hun852dc :PCollationTable = @_hun852dc; + +{$endif} + + + + + // grcp437 Checksum: 35367 + + _grcp437 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 068, 070, 072, 074, 076, 078, 080, 082, 084, 086, 088, 090, 092, 094, + 096, 098, 100, 102, 104, 106, 108, 110, 112, 114, 116, 182, 183, 184, 185, 186, + 187, 065, 067, 069, 071, 073, 075, 077, 079, 081, 083, 085, 087, 089, 091, 093, + 095, 097, 099, 101, 103, 105, 107, 109, 111, 113, 115, 188, 189, 190, 191, 192, + 117, 119, 120, 121, 122, 124, 125, 127, 128, 130, 131, 132, 133, 134, 135, 137, + 138, 139, 140, 141, 143, 144, 145, 146, 148, 150, 151, 152, 153, 155, 156, 158, + 159, 162, 163, 164, 165, 166, 167, 169, 170, 171, 172, 173, 174, 177, 178, 179, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 180, 149, 154, 157, 160, 161, 168, 176, 175, 181, 118, 123, 126, 129, 136, 142, + 147, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + + db437gr0 :PCollationTable = @_grcp437; + + + + + // dbHebrew Checksum: 43413 + + _dbHebrew :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + dbhebrew :PCollationTable = @_dbhebrew; + + + + + + // slovene Checksum: 48585 + + _slovene :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 071, 078, 081, 089, 098, 104, 106, 108, 112, 116, 118, 123, 128, 132, 140, + 146, 148, 152, 159, 167, 175, 181, 183, 185, 188, 193, 198, 199, 200, 201, 202, + 203, 065, 077, 079, 087, 093, 103, 105, 107, 109, 115, 117, 119, 127, 129, 135, + 145, 147, 149, 155, 164, 170, 180, 182, 184, 186, 190, 204, 205, 206, 207, 208, + 082, 171, 095, 068, 066, 174, 085, 080, 121, 094, 144, 139, 111, 194, 072, 086, + 100, 124, 120, 138, 136, 126, 122, 160, 156, 141, 176, 168, 165, 125, 209, 083, + 067, 110, 137, 172, 076, 070, 197, 196, 102, 097, 210, 191, 084, 157, 211, 212, + 213, 214, 215, 216, 217, 073, 074, 101, 161, 218, 219, 220, 221, 195, 192, 222, + 223, 224, 225, 226, 227, 228, 075, 069, 229, 230, 231, 232, 233, 234, 235, 236, + 091, 092, 090, 099, 088, 134, 113, 114, 096, 237, 238, 239, 240, 169, 179, 241, + 142, 158, 143, 133, 130, 131, 163, 162, 153, 177, 150, 178, 187, 189, 166, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 173, 154, 151, 254, 255 + ); + db852sl0 :PCollationTable = @_slovene; + +{$ifdef USE_PARADOX_COLLATIONS} + grcp437 :PCollationTable = @_grcp437; + + hebrew :PCollationTable = @_dbhebrew; + + slovene :PCollationTable = @_slovene; +{$endif} + + + + {$IFDEF PARADOX_COLLATIONS} + + // turk 8582 + + _turk :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 072, 082, 084, 088, 094, 100, 102, 104, 109, 116, 118, 120, 122, 125, 132, + 140, 142, 144, 146, 149, 154, 161, 163, 165, 168, 170, 171, 172, 173, 174, 175, + 176, 065, 081, 083, 087, 089, 099, 101, 103, 114, 115, 117, 119, 121, 123, 127, + 139, 141, 143, 145, 148, 150, 160, 162, 164, 166, 169, 177, 178, 179, 180, 035, + 035, 035, 035, 099, 035, 035, 035, 035, 035, 035, 146, 035, 132, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 145, 035, 127, 035, 035, 168, + 216, 189, 193, 182, 195, 194, 198, 207, 211, 192, 197, 190, 186, 203, 185, 201, + 210, 204, 215, 214, 202, 199, 206, 212, 209, 213, 196, 191, 188, 187, 205, 184, + 074, 076, 075, 077, 080, 073, 078, 086, 098, 095, 096, 097, 113, 110, 111, 112, + 088, 126, 135, 133, 134, 136, 138, 200, 183, 157, 155, 156, 159, 168, 035, 147, + 067, 069, 068, 070, 079, 066, 071, 085, 093, 090, 091, 092, 108, 107, 106, 105, + 087, 124, 129, 128, 130, 131, 137, 208, 181, 152, 153, 151, 158, 166, 035, 167 + ); + turk :PCollationTable = @_turk; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // anczech 44872 + + _anczech :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 078, 080, 088, 094, 104, 106, 108, 110, 116, 118, 120, 128, 130, 136, + 146, 148, 150, 156, 165, 171, 181, 183, 185, 187, 191, 198, 199, 200, 201, 202, + 203, 065, 077, 079, 087, 093, 103, 105, 107, 109, 115, 117, 119, 127, 129, 135, + 145, 147, 149, 155, 164, 170, 180, 182, 184, 186, 190, 204, 205, 206, 207, 208, + 250, 251, 209, 252, 210, 211, 212, 213, 253, 214, 163, 215, 158, 167, 197, 195, + 254, 216, 217, 218, 219, 220, 221, 222, 255, 223, 162, 224, 157, 166, 196, 194, + 225, 226, 227, 122, 228, 074, 229, 230, 231, 232, 160, 233, 234, 235, 236, 193, + 237, 238, 239, 121, 240, 241, 242, 243, 244, 073, 159, 245, 126, 246, 125, 192, + 152, 068, 070, 072, 076, 124, 082, 084, 086, 096, 100, 102, 098, 112, 114, 092, + 090, 132, 134, 138, 140, 144, 142, 247, 154, 175, 173, 179, 177, 189, 169, 161, + 151, 067, 069, 071, 075, 123, 081, 083, 085, 095, 099, 101, 097, 111, 113, 091, + 089, 131, 133, 137, 139, 143, 141, 248, 153, 174, 172, 178, 176, 188, 168, 249 + ); + anczech :PCollationTable = @_anczech; + + anczechw :PCollationTable = @_anczech; + + anil2czw :PCollationTable = @_anczech; + + {$ENDIF} + + + + {$IFDEF PARADOX_COLLATIONS} + + // cskamenw 40577 + + _cskamenw :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 072, 074, 076, 078, 082, 084, 086, 088, 092, 094, 096, 098, 100, 102, + 110, 112, 114, 116, 120, 122, 128, 130, 132, 134, 138, 139, 140, 141, 142, 143, + 144, 065, 071, 073, 075, 077, 081, 083, 085, 087, 091, 093, 095, 097, 099, 101, + 109, 111, 113, 115, 119, 121, 127, 129, 131, 133, 137, 145, 146, 147, 148, 149, + 035, 035, 035, 081, 035, 035, 035, 035, 035, 035, 118, 035, 102, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 117, 035, 101, 035, 035, 134, + 161, 035, 035, 035, 035, 035, 035, 151, 035, 035, 035, 152, 035, 035, 035, 035, + 158, 156, 160, 035, 035, 155, 035, 159, 035, 035, 035, 153, 150, 035, 035, 035, + 066, 068, 066, 066, 070, 066, 066, 074, 078, 080, 078, 078, 088, 090, 088, 088, + 076, 100, 102, 104, 106, 102, 108, 035, 102, 122, 124, 122, 126, 136, 035, 154, + 065, 067, 065, 065, 069, 065, 065, 073, 077, 079, 077, 077, 087, 089, 087, 087, + 075, 099, 101, 103, 105, 101, 107, 157, 101, 121, 123, 121, 125, 135, 035, 133 + ); + cskamenw :PCollationTable = @_cskamenw; + + cskamen :PCollationTable = @_cskamenw; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // anpolish 44922 + + _anpolish :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 078, 080, 088, 094, 104, 106, 108, 110, 116, 118, 120, 128, 130, 136, + 146, 148, 150, 156, 165, 171, 181, 183, 185, 187, 191, 198, 199, 200, 201, 202, + 203, 065, 077, 079, 087, 093, 103, 105, 107, 109, 115, 117, 119, 127, 129, 135, + 145, 147, 149, 155, 164, 170, 180, 182, 184, 186, 190, 204, 205, 206, 207, 208, + 250, 251, 237, 252, 229, 230, 231, 233, 253, 234, 162, 236, 158, 167, 197, 193, + 254, 217, 222, 223, 224, 225, 226, 227, 255, 232, 161, 249, 157, 166, 196, 192, + 210, 241, 242, 122, 228, 074, 218, 243, 247, 220, 160, 211, 235, 238, 219, 195, + 246, 221, 240, 121, 213, 214, 215, 216, 245, 073, 159, 212, 126, 239, 125, 194, + 152, 068, 070, 072, 076, 124, 082, 084, 086, 096, 100, 102, 098, 112, 114, 092, + 090, 132, 134, 138, 140, 144, 142, 209, 154, 175, 173, 179, 177, 189, 169, 163, + 151, 067, 069, 071, 075, 123, 081, 083, 085, 095, 099, 101, 097, 111, 113, 091, + 089, 131, 133, 137, 139, 143, 141, 244, 153, 174, 172, 178, 176, 188, 168, 248 + ); + anpolish :PCollationTable = @_anpolish; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // ancyrr 15158 + + _ancyrr :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 068, 070, 072, 074, 076, 078, 080, 082, 084, 086, 088, 090, 092, 094, + 096, 098, 100, 102, 104, 106, 108, 110, 112, 114, 116, 183, 184, 185, 186, 187, + 188, 065, 067, 069, 071, 073, 075, 077, 079, 081, 083, 085, 087, 089, 091, 093, + 095, 097, 099, 101, 103, 105, 107, 109, 111, 113, 115, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 254, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 255, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 130, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 129, 247, 248, 249, 250, 251, 252, 253, + 118, 120, 122, 124, 126, 128, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, + 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, + 117, 119, 121, 123, 125, 127, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, + 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181 + ); + ancyrr :PCollationTable = @_ancyrr; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // anhundc 19132 + + _anhundc :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 071, 073, 075, 077, 081, 083, 085, 087, 092, 094, 096, 098, 100, 102, + 113, 115, 117, 119, 121, 123, 134, 136, 138, 140, 142, 143, 144, 145, 146, 147, + 148, 065, 070, 072, 074, 076, 080, 082, 084, 086, 091, 093, 095, 097, 099, 101, + 112, 114, 116, 118, 120, 122, 133, 135, 137, 139, 141, 149, 150, 151, 152, 153, + 250, 251, 154, 252, 155, 156, 157, 158, 253, 159, 160, 161, 126, 162, 163, 090, + 254, 164, 165, 166, 167, 168, 169, 170, 255, 171, 172, 173, 132, 174, 111, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 105, 204, 130, 205, + 206, 068, 207, 208, 209, 210, 069, 211, 212, 079, 213, 214, 215, 089, 216, 217, + 218, 219, 220, 104, 221, 110, 107, 222, 223, 224, 125, 131, 128, 225, 226, 227, + 228, 067, 229, 230, 231, 232, 233, 234, 235, 078, 236, 237, 238, 088, 239, 240, + 241, 242, 243, 103, 109, 108, 106, 244, 245, 246, 124, 129, 127, 247, 248, 249 + ); + anhundc :PCollationTable = @_anhundc; + + {$ENDIF} + + + + {$IFDEF PARADOX_COLLATIONS} + + // angreek1 39126 + + _angreek1 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 068, 070, 072, 074, 076, 078, 080, 082, 084, 086, 088, 090, 092, 094, + 096, 098, 100, 102, 104, 106, 108, 110, 112, 114, 116, 186, 187, 188, 189, 190, + 191, 065, 067, 069, 071, 073, 075, 077, 079, 081, 083, 085, 087, 089, 091, 093, + 095, 097, 099, 101, 103, 105, 107, 109, 111, 113, 115, 192, 193, 194, 195, 196, + 238, 239, 197, 198, 199, 200, 201, 202, 240, 203, 241, 204, 242, 243, 244, 245, + 246, 205, 206, 207, 208, 209, 210, 211, 247, 212, 248, 213, 249, 250, 251, 252, + 214, 215, 120, 216, 217, 218, 219, 220, 221, 222, 253, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 130, 136, 144, 236, 159, 237, 174, 185, + 142, 119, 122, 124, 126, 129, 132, 135, 138, 143, 147, 149, 151, 153, 155, 158, + 161, 163, 254, 166, 168, 173, 177, 179, 181, 184, 145, 175, 118, 128, 134, 140, + 172, 117, 121, 123, 125, 127, 131, 133, 137, 139, 146, 148, 150, 152, 154, 156, + 160, 162, 165, 164, 167, 169, 176, 178, 180, 182, 141, 171, 157, 170, 183, 255 + ); + angreek1 :PCollationTable = @_angreek1; + + ACCGREEK :PCollationTable = @_angreek1; + + {$ENDIF} + + {$IFDEF PARADOX_COLLATIONS} + + // ansislov 61480 + + _ansislov :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 071, 078, 081, 089, 098, 104, 106, 108, 112, 116, 118, 123, 128, 132, 140, + 146, 148, 152, 159, 167, 175, 181, 183, 185, 188, 193, 198, 199, 200, 201, 202, + 203, 065, 077, 079, 087, 093, 103, 105, 107, 109, 115, 117, 119, 127, 129, 135, + 145, 147, 149, 155, 164, 170, 180, 182, 184, 186, 190, 204, 205, 206, 207, 208, + 250, 251, 209, 252, 210, 211, 212, 213, 253, 214, 163, 215, 160, 168, 197, 194, + 254, 216, 217, 218, 219, 220, 221, 222, 255, 223, 162, 224, 156, 165, 196, 191, + 225, 226, 227, 125, 228, 076, 229, 230, 231, 232, 161, 233, 234, 235, 236, 195, + 237, 238, 239, 121, 240, 241, 242, 243, 244, 070, 157, 245, 126, 246, 122, 192, + 153, 073, 074, 075, 072, 124, 086, 082, 084, 100, 102, 099, 101, 113, 114, 090, + 092, 133, 134, 142, 143, 144, 141, 247, 154, 179, 177, 178, 176, 189, 169, 158, + 150, 067, 068, 069, 066, 120, 085, 080, 083, 095, 097, 094, 096, 110, 111, 088, + 091, 130, 131, 137, 138, 139, 136, 248, 151, 174, 172, 173, 171, 187, 166, 249 + ); + ansislov :PCollationTable = @_ansislov; + + {$ENDIF} + + + + {$IFDEF USE_PARADOX_COLLATIONS} + + // ANTURK 24004 + + _ANTURK :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 072, 082, 084, 088, 094, 100, 102, 106, 112, 120, 122, 124, 126, 129, 136, + 144, 146, 148, 150, 155, 160, 167, 169, 171, 174, 176, 177, 178, 179, 180, 181, + 182, 065, 081, 083, 087, 089, 099, 101, 105, 117, 119, 121, 123, 125, 127, 131, + 143, 145, 147, 149, 154, 156, 166, 168, 170, 172, 175, 183, 184, 185, 186, 187, + 248, 249, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 250, 251, 252, + 253, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 254, 255, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 074, 076, 075, 077, 080, 073, 078, 086, 098, 095, 096, 097, 116, 113, 114, 115, + 104, 130, 139, 137, 138, 140, 142, 244, 245, 163, 161, 162, 165, 118, 153, 151, + 067, 069, 068, 070, 079, 066, 071, 085, 093, 090, 091, 092, 111, 110, 109, 108, + 103, 128, 133, 132, 134, 135, 141, 246, 247, 158, 159, 157, 164, 107, 152, 173 + ); + ANTURK :PCollationTable = @_ANTURK; + + {$ENDIF} + + + + // DB857TR0 Checksum: 20238 + + _DB857TR0 :TCollationTable = ( + 000, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 001, 141, 154, 147, 148, 133, 146, 156, 122, 123, 134, 131, 136, 132, 135, 142, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 138, 137, 128, 130, 129, 140, + 145, 012, 020, 021, 023, 024, 029, 030, 032, 033, 039, 040, 041, 042, 043, 045, + 051, 052, 053, 054, 056, 057, 062, 063, 064, 065, 066, 124, 143, 125, 157, 159, + 155, 067, 074, 075, 077, 078, 083, 084, 086, 092, 093, 094, 095, 096, 097, 099, + 105, 106, 107, 108, 110, 111, 116, 117, 118, 119, 121, 126, 144, 127, 158, 191, + 022, 115, 079, 071, 072, 069, 073, 076, 081, 082, 080, 091, 089, 087, 013, 014, + 028, 152, 019, 103, 104, 102, 114, 113, 038, 050, 061, 149, 150, 151, 055, 109, + 068, 088, 100, 112, 098, 044, 031, 085, 139, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 015, 016, 018, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 070, 017, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 025, 026, 027, 253, 034, 035, 037, 228, 229, 230, 231, 232, 036, 233, + 046, 153, 047, 049, 101, 048, 234, 254, 235, 058, 059, 060, 090, 120, 236, 237, + 238, 239, 255, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252 + ); + DB857TR0 :PCollationTable = @_DB857TR0; + + + + + // FOXCZWIN 29353 + + _FOXCZWIN :TCollationTable = ( + 000, 001, 001, 001, 001, 001, 001, 001, 001, 002, 003, 004, 005, 006, 001, 001, + 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, + 016, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, 018, 019, 020, 021, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 022, 023, 024, 025, 026, 027, + 028, 090, 097, 098, 102, 105, 110, 111, 112, 113, 116, 117, 118, 122, 123, 126, + 131, 132, 133, 136, 141, 144, 150, 151, 152, 153, 155, 029, 030, 031, 032, 033, + 034, 090, 097, 098, 102, 105, 110, 111, 112, 113, 116, 117, 118, 122, 123, 126, + 131, 132, 133, 136, 141, 144, 150, 151, 152, 153, 155, 035, 036, 037, 038, 001, + 159, 160, 039, 161, 040, 041, 042, 043, 162, 044, 140, 045, 137, 142, 158, 157, + 163, 046, 047, 048, 049, 050, 051, 052, 164, 053, 140, 054, 137, 142, 158, 157, + 055, 056, 057, 121, 058, 095, 059, 060, 061, 062, 138, 063, 064, 065, 066, 156, + 067, 068, 069, 121, 070, 071, 072, 073, 074, 096, 138, 075, 120, 076, 120, 156, + 134, 092, 093, 094, 091, 119, 099, 100, 101, 107, 109, 106, 108, 114, 115, 103, + 104, 124, 125, 128, 130, 129, 127, 077, 135, 146, 145, 147, 145, 154, 143, 139, + 134, 092, 093, 094, 091, 119, 099, 100, 101, 107, 109, 106, 108, 114, 115, 103, + 104, 124, 125, 128, 130, 129, 127, 078, 135, 147, 146, 148, 149, 154, 143, 079 + ); + FOXCZWIN :PCollationTable = @_FOXCZWIN; + + + + + // FOXCZ895 Checksum: 42384 + + _FOXCZ895 :TCollationTable = ( + 000, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, + 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, + 048, 036, 037, 038, 039, 040, 041, 033, 042, 043, 044, 063, 045, 034, 046, 048, + 131, 133, 134, 136, 137, 138, 139, 140, 141, 142, 049, 050, 065, 066, 067, 051, + 052, 145, 152, 154, 158, 162, 168, 170, 172, 174, 178, 180, 182, 188, 191, 195, + 203, 205, 207, 213, 218, 223, 231, 233, 235, 237, 241, 053, 054, 055, 056, 057, + 058, 145, 152, 154, 158, 162, 168, 170, 172, 174, 178, 180, 182, 188, 191, 195, + 203, 205, 207, 213, 218, 223, 231, 233, 235, 237, 241, 059, 060, 061, 062, 032, + 156, 225, 164, 160, 147, 160, 220, 156, 166, 166, 184, 176, 186, 184, 147, 149, + 164, 243, 243, 201, 197, 199, 229, 227, 239, 197, 225, 216, 186, 239, 211, 220, + 149, 176, 199, 227, 193, 193, 229, 201, 216, 211, 209, 209, 132, 127, 069, 070, + 124, 125, 126, 083, 105, 106, 150, 091, 090, 107, 084, 092, 100, 099, 098, 089, + 093, 112, 108, 101, 081, 116, 102, 103, 096, 088, 115, 111, 104, 082, 119, 113, + 114, 109, 110, 095, 094, 086, 087, 118, 117, 097, 085, 123, 121, 221, 122, 120, + 244, 214, 245, 249, 251, 251, 129, 252, 254, 248, 255, 246, 143, 254, 247, 073, + 075, 068, 077, 076, 078, 079, 071, 074, 128, 064, 130, 072, 191, 135, 080, 035 + ); + FOXCZ895 :PCollationTable = @_FOXCZ895; + + + + {$IFDEF USE_ACCESS_COLLATIONS} + + // BLROM800 28847 + + _BLROM800 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 035, 161, 035, 035, 035, 035, 035, 035, 206, 035, 079, 130, 131, 132, + 133, 035, 035, 035, 035, 035, 035, 217, 035, 035, 207, 035, 111, 134, 135, 209, + 136, 155, 162, 158, 157, 159, 035, 160, 145, 035, 220, 222, 035, 035, 035, 035, + 150, 224, 035, 035, 144, 214, 215, 213, 035, 035, 221, 223, 218, 219, 216, 156, + 137, 195, 138, 196, 187, 179, 182, 151, 139, 191, 140, 141, 201, 200, 142, 143, + 198, 153, 203, 202, 194, 204, 189, 035, 181, 146, 208, 147, 190, 148, 211, 193, + 171, 167, 163, 197, 175, 183, 186, 152, 172, 168, 164, 176, 188, 184, 180, 192, + 199, 154, 173, 169, 165, 205, 177, 035, 185, 174, 170, 166, 178, 149, 212, 210 + ); + BLROM800 :PCollationTable = @_BLROM800; + + {$ENDIF} + + + {$IFDEF USE_ORACLE_COLLATIONS} + + // ORAWE850 31378 + + _ORAWE850 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 048, 049, 050, 051, 052, 053, + 054, 101, 117, 119, 123, 127, 137, 139, 141, 143, 153, 155, 157, 159, 161, 165, + 179, 181, 183, 185, 188, 192, 202, 204, 206, 208, 213, 055, 056, 057, 058, 059, + 060, 102, 118, 120, 124, 128, 138, 140, 142, 144, 154, 156, 158, 160, 162, 166, + 180, 182, 184, 186, 189, 193, 203, 205, 207, 209, 214, 061, 062, 063, 064, 065, + 035, 035, 035, 068, 035, 035, 035, 035, 035, 035, 185, 035, 165, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 186, 035, 166, 035, 035, 208, + 100, 076, 080, 066, 082, 081, 083, 091, 095, 079, 069, 077, 073, 087, 072, 085, + 094, 088, 099, 098, 086, 084, 090, 096, 093, 097, 070, 078, 075, 074, 089, 071, + 105, 103, 107, 111, 109, 113, 115, 121, 131, 129, 133, 135, 147, 145, 149, 151, + 125, 163, 169, 167, 171, 175, 173, 067, 177, 196, 194, 198, 200, 210, 190, 187, + 106, 104, 108, 112, 110, 114, 116, 122, 132, 130, 134, 136, 148, 146, 150, 152, + 126, 164, 170, 168, 172, 176, 174, 092, 178, 197, 195, 199, 201, 211, 191, 212 + ); + ORAWE850 :PCollationTable = @_ORAWE850 ; + + {$ENDIF} + + + + {$IFDEF USE_SYBASE_COLLATIONS} + + // SYDC850 46023 + + _SYDC850 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 048, 049, 050, 051, 052, 053, + 054, 111, 127, 129, 133, 135, 145, 147, 149, 151, 161, 163, 165, 167, 169, 173, + 187, 189, 191, 193, 196, 198, 208, 210, 212, 214, 219, 055, 056, 057, 058, 059, + 060, 112, 128, 130, 134, 136, 146, 148, 150, 152, 162, 164, 166, 168, 170, 174, + 188, 190, 192, 194, 197, 199, 209, 211, 213, 215, 220, 061, 062, 063, 064, 065, + 035, 035, 035, 068, 035, 035, 035, 035, 035, 035, 193, 035, 173, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 194, 035, 174, 035, 035, 214, + 100, 076, 080, 066, 082, 081, 083, 091, 095, 079, 069, 077, 073, 087, 072, 085, + 094, 088, 099, 098, 086, 084, 090, 096, 093, 097, 070, 078, 075, 074, 089, 071, + 113, 115, 117, 119, 121, 123, 125, 131, 137, 139, 141, 143, 153, 155, 157, 159, + 221, 171, 175, 177, 179, 181, 183, 067, 185, 200, 202, 204, 206, 216, 224, 195, + 114, 116, 118, 120, 122, 124, 126, 132, 138, 140, 142, 144, 154, 156, 158, 160, + 222, 172, 176, 178, 180, 182, 184, 092, 186, 201, 203, 205, 207, 217, 223, 218 + ); + SYDC850 :PCollationTable = @_SYDC850; + + + + + // SYDC437 16660 + + _SYDC437 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 048, 049, 050, 051, 052, 053, + 054, 095, 106, 108, 112, 114, 121, 123, 125, 127, 133, 135, 137, 139, 141, 145, + 152, 154, 156, 158, 160, 162, 169, 171, 173, 175, 178, 055, 056, 057, 058, 059, + 060, 096, 107, 109, 113, 115, 122, 124, 126, 128, 134, 136, 138, 140, 142, 146, + 153, 155, 157, 159, 161, 163, 170, 172, 174, 176, 179, 061, 062, 063, 064, 065, + 035, 035, 035, 069, 035, 035, 035, 035, 035, 035, 158, 035, 145, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 159, 035, 146, 035, 035, 175, + 084, 076, 066, 067, 035, 068, 035, 035, 035, 035, 070, 077, 073, 035, 035, 035, + 081, 079, 083, 035, 035, 181, 035, 082, 035, 035, 071, 078, 075, 074, 035, 072, + 095, 095, 095, 095, 100, 102, 104, 110, 114, 117, 114, 114, 127, 127, 127, 127, + 112, 143, 145, 145, 145, 145, 150, 035, 145, 162, 162, 162, 167, 175, 035, 180, + 097, 098, 099, 096, 101, 103, 105, 111, 116, 118, 119, 120, 129, 130, 131, 132, + 113, 144, 147, 148, 149, 146, 151, 080, 146, 164, 165, 166, 168, 176, 035, 177 + ); + SYDC437 :PCollationTable = @_SYDC437; + + {$ENDIF} + + + {$IFDEF USE_DB2_COLLATIONS} + + // db2andeu 8683 + + _db2andeu :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 035, 038, 039, 045, 046, 047, 048, 049, 050, 051, 052, 053, 054, 055, + 056, 057, 058, 059, 060, 061, 062, 063, 064, 065, 066, 067, 068, 069, 070, 071, + 073, 074, 085, 087, 091, 094, 101, 103, 105, 107, 113, 115, 117, 119, 121, 125, + 132, 134, 136, 138, 141, 143, 150, 152, 154, 156, 159, 161, 162, 163, 164, 165, + 166, 075, 086, 088, 092, 095, 102, 104, 106, 108, 114, 116, 118, 120, 122, 126, + 133, 135, 137, 139, 142, 144, 151, 153, 155, 157, 160, 168, 169, 170, 171, 172, + 233, 234, 235, 041, 236, 237, 238, 239, 240, 241, 231, 242, 229, 243, 244, 245, + 246, 167, 211, 226, 227, 247, 248, 249, 250, 251, 230, 252, 228, 253, 254, 232, + 032, 034, 042, 040, 185, 043, 193, 217, 221, 182, 173, 036, 176, 213, 175, 210, + 220, 214, 225, 224, 212, 200, 216, 222, 219, 223, 174, 037, 178, 177, 215, 072, + 181, 179, 180, 184, 080, 081, 083, 089, 189, 100, 187, 188, 194, 190, 191, 192, + 093, 124, 197, 195, 196, 199, 130, 044, 202, 207, 205, 206, 148, 209, 204, 140, + 078, 084, 076, 183, 077, 079, 082, 090, 099, 096, 097, 098, 111, 112, 110, 109, + 186, 123, 129, 131, 127, 198, 128, 218, 201, 147, 149, 146, 145, 208, 203, 158 + ); + db2andeu :PCollationTable = @_db2andeu; + + {$ENDIF} + +initialization + + InitialiseCollationTables; + + RegisterCollation( DbfLangId_Spanish_1252, DBWINES0, 'DBWINES0' ); // 'Spanish' ANSI + RegisterCollation( DbfLangId_Ascii_1252, BINARY_COLLATION, 'DBWINUS0' ); // 'ascii' ANSI + RegisterCollation( DbfLangId_WEurope_1252, DBWINWE0, 'DBWINWE0' ); // 'WEurope' ANSI + + //DbfLangId_BUL_868 = $8E; // is it used? does not exist in BDE + //DbfLangId_FIN_850 = $0C; // is it used? does not exist in BDE + RegisterCollation( DbfLangId_DEU_437, DB437DE0, 'DB437DE0' ); // dBASE DEU cp437 + RegisterCollation( DbfLangId_ESP_437, DB437ES1, 'DB437ES1' ); // dBASE ESP cp437 + RegisterCollation( DbfLangId_FIN_437, DB437FI0, 'DB437FI0' ); // dBASE FIN cp437 + RegisterCollation( DbfLangId_FRA_437, DB437FR0, 'DB437FR0' ); // dBASE FRA cp437 + RegisterCollation( DbfLangId_ELL_437, db437gr0, 'db437gr0' ); // dBASE ELL GR437 + RegisterCollation( DbfLangId_ITA_437, DB437IT0, 'DB437IT0' ); // dBASE ITA cp437 + RegisterCollation( DbfLangId_NLD_437, DB437NL0, 'DB437NL0' ); // dBASE NLD cp437 + RegisterCollation( DbfLangId_SVE_437, DB437SV0, 'DB437SV0' ); // dBASE SVE cp437 + RegisterCollation( DbfLangId_ENG_437, DB437UK0, 'DB437UK0' ); // dBASE ENG cp437 + RegisterCollation( DbfLangId_ENU_437, DB437US0, 'DB437US0' ); // dBASE ENU cp437 + RegisterCollation( DbfLangId_FRC_850, DB850CF0, 'DB850CF0' ); // dBASE FRC cp850 + RegisterCollation( DbfLangId_DEU_850, DB850DE0, 'DB850DE0' ); // dBASE DEU cp850 + RegisterCollation( DbfLangId_ESP_850, DB850ES0, 'DB850ES0' ); // dBASE ESP cp850 + RegisterCollation( DbfLangId_FRA_850, DB850FR0, 'DB850FR0' ); // dBASE FRA cp850 + RegisterCollation( DbfLangId_ITA_850, DB850IT1, 'DB850IT1' ); // dBASE ITA cp850 + RegisterCollation( DbfLangId_NLD_850, DB850NL0, 'DB850NL0' ); // dBASE NLD cp850 + RegisterCollation( DbfLangId_PTB_850, DB850PT0, 'DB850PT0' ); // dBASE PTB cp850 + RegisterCollation( DbfLangId_SVE_850, DB850SV1, 'DB850SV1' ); // dBASE SVE cp850 + RegisterCollation( DbfLangId_ENG_850, DB850UK0, 'DB850UK0' ); // dBASE ENG cp850 + RegisterCollation( DbfLangId_ENU_850, DB850US0, 'DB850US0' ); // dBASE ENU cp850 + RegisterCollation( DbfLangId_CSY_852, DB852CZ0, 'DB852CZ0' ); // dBASE CSY cp852 + RegisterCollation( DbfLangId_HUN_852, db852hdc, 'db852hdc' ); // dBASE HUN cp852 + RegisterCollation( DbfLangId_PLK_852, db852po0, 'db852po0' ); // dBASE PLK cp852 + RegisterCollation( DbfLangId_SLO_852, db852sl0, 'db852sl0' ); // dBASE SLO cp852 + RegisterCollation( DbfLangId_TRK_857, DB857TR0, 'DB857TR0' ); // dBASE TRK cp857 + RegisterCollation( DbfLangId_PTG_860, DB860PT0, 'DB860PT0' ); // dBASE PTG cp860 + RegisterCollation( DbfLangId_FRC_863, DB863CF1, 'DB863CF1' ); // dBASE FRC cp863 + RegisterCollation( DbfLangId_DAN_865, DB865DA0, 'DB865DA0' ); // dBASE DAN cp865 + RegisterCollation( DbfLangId_NOR_865, DB865NO0, 'DB865NO0' ); // dBASE NOR cp865 + RegisterCollation( DbfLangId_RUS_866, db866ru0, 'db866ru0' ); // dBASE RUS cp866 + RegisterCollation( DbfLangId_CSY_867, DB867CZ0, 'DB867CZ0' ); // dBASE CSY cp867 + RegisterCollation( DbfLangId_THA_874, db874th0, 'db874th0' ); // dBASE THA cp874 + RegisterCollation( DbfLangId_JPN_932, BINARY_COLLATION, 'DB932JP0' ); // dBASE JPN cp932 + RegisterCollation( DbfLangId_JPN_DIC_932, DB932JP1, 'DB932JP1' ); // dBASE JPN Dic932 + RegisterCollation( DbfLangId_CHS_936, DB936CN0, 'DB936CN0' ); // dBASE CHS cp936 + RegisterCollation( DbfLangId_KOR_949, DB949KO0, 'DB949KO0' ); // dBASE KOR cp949 + RegisterCollation( DbfLangId_CHT_950, DB950TW0, 'DB950TW0' ); // dBASE CHT cp950 + RegisterCollation( DbfLangId_Hebrew, dbHebrew, 'dbHebrew' ); // Hebrew dBASE + //RegisterCollation( XXXXXXXXXXXX, BLLT1CA0 ); // Borland FRC Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1DA0 ); // Borland DAN Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1DE0 ); // Borland DEU Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1ES0 ); // Borland ESP Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1FI0 ); // Borland FIN Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1FR0 ); // Borland FRA Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1IS0 ); // Borland ISL Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1IT0 ); // Borland ITA Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1NL0 ); // Borland NLD Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1NO0 ); // Borland NOR Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1PT0 ); // Borland PTG Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1SV0 ); // Borland SVE Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1UK0 ); // Borland ENG Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1US0 ); // Borland ENU Latin-1 + +(* + + FoxLangId_ENU_437 = $01; + FoxLangId_Intl_850 = $02; + FoxLangId_Windows_1252 = $03; + FoxLangId_Mac_10000 = $04; + + FoxLangId_EEurope_852 = $64; + FoxLangId_Russia_866 = $65; + FoxLangId_Nordic_865 = $66; + FoxLangId_Iceland_861 = $67; + + DbfLangId_POL_620 = $69; + + FoxLangId_Greek_737 = $6A; + FoxLangId_Turkish_857 = $6B; + + FoxLangId_Taiwan_950 = $78; + FoxLangId_Korean_949 = $79; + FoxLangId_Chinese_936 = $7A; + FoxLangId_Japan_932 = $7B; + FoxLangId_Thai_874 = $7C; + FoxLangId_Hebrew_1255 = $7D; + FoxLangId_Arabic_1256 = $7E; + + FoxLangId_Russia_10007 = $96; + FoxLangId_EEurope_10029 = $97; + FoxLangId_Greek_10006 = $98; + + FoxLangId_Czech_850 = $9C; // DOS + + FoxLangId_EEurope_1250 = $C8; + FoxLangId_Russia_1251 = $C9; + FoxLangId_Turkish_1254 = $CA; + FoxLangId_Greek_1253 = $CB; + +*) + + + RegisterCollation( FoxLangId_Czech_895, FOXCZ895, 'FOXCZ895' ); // FoxPro Czech DOS895 + RegisterCollation( FoxLangId_Czech_1250, FOXCZWIN, 'FOXCZWIN' ); // FoxPro Czech 1250 + RegisterCollation( FoxLangId_German_437, FOXDE437, 'FOXDE437' ); // FoxPro German 437 + RegisterCollation( FoxLangId_German_1252, FOXDEWIN, 'FOXDEWIN' ); // FoxPro German 1252 + RegisterCollation( FoxLangId_Nordic_437, FOXNO437, 'FOXNO437' ); // FoxPro Nordic 437 + RegisterCollation( FoxLangId_Nordic_850, FOXNO850, 'FOXNO850' ); // FoxPro Nordic 850 + RegisterCollation( FoxLangId_Nordic_1252, FOXNOWIN, 'FOXNOWIN' ); // FoxPro Nordic 1252 + + //RegisterCollation( XXXXXXXXXXXX, BLROM800 ); // SQL Link ROMAN8 + //RegisterCollation( XXXXXXXXXXXX, db2andeu ); // DB2 SQL ANSI DEU + //RegisterCollation( XXXXXXXXXXXX, SYDC437 ); // Sybase SQL Dic437 + //RegisterCollation( XXXXXXXXXXXX, SYDC850 ); // Sybase SQL Dic850 + //RegisterCollation( XXXXXXXXXXXX, ORAWE850 ); // Oracle SQL WE850 + + //RegisterCollation( XXXXXXXXXXXX, ACCGEN ); // Access General + //RegisterCollation( XXXXXXXXXXXX, ACCGREEK ); // Access Greece + //RegisterCollation( XXXXXXXXXXXX, ACCJAPAN ); // Access Japanese + //RegisterCollation( XXXXXXXXXXXX, ACCNRDAN ); // Access Nord/Danish + //RegisterCollation( XXXXXXXXXXXX, ACCSWFIN ); // Access Swed/Finnish + + //RegisterCollation( XXXXXXXXXXXX, ancyrr ); // Pdox ANSI Cyrillic + //RegisterCollation( XXXXXXXXXXXX, anczech ); // Pdox ANSI Czech + //RegisterCollation( XXXXXXXXXXXX, anczechw ); // pdx ANSI Czech 'CH' + //RegisterCollation( XXXXXXXXXXXX, angreek1 ); // Pdox ANSI Greek + //RegisterCollation( XXXXXXXXXXXX, ANHEBREW ); // Paradox ANSI HEBREW + //RegisterCollation( XXXXXXXXXXXX, anhundc ); // Pdox ANSI Hun. DC + //RegisterCollation( XXXXXXXXXXXX, anil2czw ); // pdx ANSI ISO L_2 CZ + //RegisterCollation( XXXXXXXXXXXX, anpolish ); // Pdox ANSI Polish + //RegisterCollation( XXXXXXXXXXXX, ANSII850 ); // Pdox ANSI Intl850 + //RegisterCollation( XXXXXXXXXXXX, ANSIINTL ); // Pdox ANSI Intl + //RegisterCollation( XXXXXXXXXXXX, ANSINOR4 ); // Pdox ANSI Nordan4 + //RegisterCollation( XXXXXXXXXXXX, ansislov ); // Pdox ANSI Slovene + //RegisterCollation( XXXXXXXXXXXX, ANSISPAN ); // Pdox ANSI Spanish + //RegisterCollation( XXXXXXXXXXXX, ANSISWFN ); // Pdox ANSI Swedfin + //RegisterCollation( XXXXXXXXXXXX, ANTURK ); // Pdox ANSI Turkish + //RegisterCollation( XXXXXXXXXXXX, china ); // Paradox China 936 + //RegisterCollation( XXXXXXXXXXXX, cskamen ); // Paradox Czech 867 + //RegisterCollation( XXXXXXXXXXXX, cskamenw ); // pdx Czech 867 'CH' + //RegisterCollation( XXXXXXXXXXXX, cyrr ); // Paradox Cyrr 866 + //RegisterCollation( XXXXXXXXXXXX, czech ); // Paradox Czech 852 + //RegisterCollation( XXXXXXXXXXXX, czechw ); // pdx Czech 852 'CH' + //RegisterCollation( XXXXXXXXXXXX, grcp437 ); // Paradox Greek GR437 + //RegisterCollation( XXXXXXXXXXXX, hebrew ); // Paradox 'hebrew' + //RegisterCollation( XXXXXXXXXXXX, hun852dc ); // Paradox Hun 852 DC + //RegisterCollation( XXXXXXXXXXXX, iceland ); // Paradox ISL 861 + //RegisterCollation( XXXXXXXXXXXX, il2czw ); // pdx ISO L_2 Czech + //RegisterCollation( XXXXXXXXXXXX, intl ); // Paradox 'intl' + //RegisterCollation( XXXXXXXXXXXX, intl850 ); // Paradox 'intl' 850 + //RegisterCollation( XXXXXXXXXXXX, japan ); // Paradox 'japan' + //RegisterCollation( XXXXXXXXXXXX, korea ); // Paradox Korea 949 + //RegisterCollation( XXXXXXXXXXXX, nordan ); // Paradox 'nordan' + //RegisterCollation( XXXXXXXXXXXX, nordan40 ); // Paradox 'nordan40' + //RegisterCollation( XXXXXXXXXXXX, polish ); // Paradox Polish 852 + //RegisterCollation( XXXXXXXXXXXX, slovene ); // Paradox Slovene 852 + //RegisterCollation( XXXXXXXXXXXX, SPANISH ); // Paradox ESP 437 + //RegisterCollation( XXXXXXXXXXXX, swedfin ); // Paradox 'swedfin' + //RegisterCollation( XXXXXXXXXXXX, taiwan ); // Paradox Taiwan 950 + //RegisterCollation( XXXXXXXXXXXX, thai ); // Paradox Thai 874 + //RegisterCollation( XXXXXXXXXXXX, turk ); // Paradox 'turk' + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_common.inc b/mseide-msegui/lib/common/fpccompatibility/dbf_common.inc new file mode 100644 index 0000000..ef4e275 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_common.inc @@ -0,0 +1,262 @@ +// define this if you need more SPEEEEEDDDD!!! +// useful if you index dbf files over a network + +{.$define USE_CACHE} + +// define the following if you want support for 65535 length character +// fields for all dbase files (and not only foxpro); if you define this, +// you will not be able to read MS Excel generated .dbf files! + +{.$define USE_LONG_CHAR_FIELDS} + +// modifies unix unit dbf_wtil to use hungarian encodings (hack) + +{.$define HUNGARIAN} + +// enables assembler routines, 486+ only + +{$define USE_ASSEMBLER_486_UP} + +// test compatibility + +{.$define TDBF_UPDATE_FIRSTLAST_NODE} + +// use this directive to suppress math exceptions, +// instead NAN is returned. +// Using this directive is slightly less efficient +// +// used in Dbf_PrsDef +// +// NAN support needs to be rewritten and is currently absent + +{.$define NAN} + +//------------------------------------------------------ +//--- Define all SUPPORT_xxx; undef if not supported --- +//------------------------------------------------------ + + +//------------------------------------------------------ +//--- Delphi versions --- +//------------------------------------------------------ + + +{$ifdef VER80} // Delphi 1.0 + #ERROR tDbf needs Delphi or C++ Builder 3 minimum. +{$endif} + +{$ifdef VER90} // Delphi 2.0 + #ERROR tDbf needs Delphi or C++ Builder 3 minimum. +{$endif} + +{$ifdef VER93} // is BCB++ 1.0 + #ERROR tDbf needs Delphi or C++ Builder 3 minimum. +{$endif} + +{$ifdef VER100} // Delphi 3 + {$define DELPHI_3} +{$endif} + +{$ifdef VER110} // CBuilder 3 + {$define DELPHI_3} +{$endif} + +{$ifdef VER120} // Delphi 4 + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER125} // C++ BUILDER 4 + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER130} // Delphi 5 + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER135} // C++ Builder 5 ?? + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER140} // Delphi 6 + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER145} // C++ Builder 6 + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER150} // Delphi 7 :-) For once I am not late (12/07/2001) + {$define DELPHI_7} + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER155} // C++ Builder 7 + {$define DELPHI_7} + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER160} // Delphi 8 + {$define DELPHI_2005} + {$define DELPHI_8} + {$define DELPHI_7} + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER170} // Delphi 2005 + {$define DELPHI_2005} + {$define DELPHI_8} + {$define DELPHI_7} + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER180} // Delphi 2006 + {$define DELPHI_2006} + {$define DELPHI_2005} + {$define DELPHI_8} + {$define DELPHI_7} + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER185} // Delphi 2007 + {$define DELPHI_2007} + { Delphi 2007 also defines VER180, so other DELPHI defines already done } +{$endif} + +//------------------------------------------------------- +//--- Conclude supported features from delphi version --- +//------------------------------------------------------- + +{$ifdef DELPHI_3} + + {$define SUPPORT_VARIANTS} + {$define WINDOWS} + {$define ENDIAN_LITTLE} + +{$ifdef DELPHI_4} + + {$define SUPPORT_DEFCHANGED} + {$define SUPPORT_DEFAULT_PARAMS} + {$define SUPPORT_OVERLOAD} + {$define SUPPORT_NEW_TRANSLATE} + {$define SUPPORT_INT64} + {$define SUPPORT_REINTRODUCE} + {$define SUPPORT_FIELDDEFS_UPDATED} + {$define SUPPORT_FIELDDEF_ATTRIBUTES} + {$define SUPPORT_FIELDDEF_TPERSISTENT} + {$define SUPPORT_FIELDDEF_INDEX} + {$define SUPPORT_FIELDTYPES_V4} + {$define SUPPORT_UINT32_CARDINAL} + {$define SUPPORT_MATH_UNIT} + +{$ifdef DELPHI_5} + + {$define SUPPORT_BACKWARD_FIELDDATA} + {$define SUPPORT_INITDEFSFROMFIELDS} + {$define SUPPORT_REFRESHEVENTS} + {$define SUPPORT_DEF_DELETE} + {$define SUPPORT_FREEANDNIL} + +{$ifdef DELPHI_6} + + {$define SUPPORT_PATHDELIM} + {$define SUPPORT_SEPARATE_VARIANTS_UNIT} + +{$endif} +{$endif} +{$endif} +{$endif} + +//------------------------------------------------------ +//--- Conclude supported features in FreePascal --- +//------------------------------------------------------ + +{$ifdef FPC_VERSION} + + {$mode delphi} + {$h+} + +{$ifndef CPUI386} + {$undef USE_ASSEMBLER_486_UP} +{$endif} + +{$ifdef USE_ASSEMBLER_486_UP} + {$asmmode intel} +{$endif} + + {$define SUPPORT_INT64} + {$define SUPPORT_DEFAULT_PARAMS} + {$define SUPPORT_OVERLOAD} + {$define SUPPORT_NEW_TRANSLATE} + {$define SUPPORT_FIELDDEF_TPERSISTENT} + {$define SUPPORT_FIELDTYPES_V4} + {$define SUPPORT_UINT32_CARDINAL} + {$define SUPPORT_REINTRODUCE} + {$define SUPPORT_MATH_UNIT} + {$define SUPPORT_VARIANTS} + {$define SUPPORT_SEPARATE_VARIANTS_UNIT} + {$define SUPPORT_REFRESHEVENTS} + + // FPC 2.0.x improvements + {$ifdef VER2} + {$ifndef VER2_0_0} + {$define SUPPORT_BACKWARD_FIELDDATA} + {$endif} + {$endif} + + // FPC 1.0.x exceptions: no 0/0 support + {$ifdef VER1_0} + {$undef NAN} + {$undef SUPPORT_DEFAULT_PARAMS} + {$undef SUPPORT_NEW_TRANSLATE} + + {$message error TDbf needs fpc 1.9 minimum.} + + {$endif} + +{$endif} + +//---------------------------------------------------------- +//--- Conclude supported features in non-Windows platforms --- +//---------------------------------------------------------- + +{$ifndef WINDOWS} + + {$define SUPPORT_PATHDELIM} + {$define SUPPORT_INCLUDETRAILPATHDELIM} + {$define SUPPORT_INCLUDETRAILBACKSLASH} + +{$endif} + +{$ifndef ENDIAN_LITTLE} +{$ifndef ENDIAN_BIG} +{$error Neither ENDIAN_LITTLE nor ENDIAN_BIG defined!} +{$endif} +{$endif} + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_common.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_common.pas new file mode 100644 index 0000000..cb4bd94 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_common.pas @@ -0,0 +1,455 @@ +unit dbf_common; + +// Modified 2013 by Martin Schreiber + +interface + +{$I dbf_common.inc} + +uses + SysUtils, classes,mclasses,mdb +{$ifndef WINDOWS} + , Types, dbf_wtil +{$ifdef KYLIX} + , Libc +{$endif} +{$endif} + ; + + +const + TDBF_MAJOR_VERSION = 6; + TDBF_MINOR_VERSION = 9; + TDBF_SUB_MINOR_VERSION = 2; + + TDBF_TABLELEVEL_FOXPRO = 25; + + JulianDateDelta = 1721425; { number of days between 1.1.4714 BC and "0" } + +type + EDbfError = class (EDatabaseError); + EDbfWriteError = class (EDbfError); + + TDbfFieldType = char; + + TXBaseVersion = (xUnknown, xClipper, xBaseIII, xBaseIV, xBaseV, xFoxPro, xBaseVII); + TSearchKeyType = (stEqual, stGreaterEqual, stGreater); + + TDateTimeHandling = (dtDateTime, dtBDETimeStamp); + +//------------------------------------- + + PDateTime = ^TDateTime; +{$ifndef FPC_VERSION} + PtrInt = Longint; +{$endif} + + PSmallInt = ^SmallInt; + PCardinal = ^Cardinal; + PDouble = ^Double; + PString = ^String; + +{$ifdef DELPHI_3} + dword = cardinal; +{$endif} + +//------------------------------------- + +{$ifndef SUPPORT_FREEANDNIL} +// some procedures for the less lucky who don't have newer versions yet :-) +procedure FreeAndNil(var v); +{$endif} +procedure FreeMemAndNil(var P: Pointer); + +//------------------------------------- + +{$ifndef SUPPORT_PATHDELIM} +const +{$ifdef msWINDOWS} + PathDelim = '\'; +{$else} + PathDelim = '/'; +{$endif} +{$endif} + +{$ifndef SUPPORT_INCLTRAILPATHDELIM} +function IncludeTrailingPathDelimiter(const Path: string): string; +{$endif} + +//------------------------------------- + +function GetCompletePath(const Base, Path: string): string; +function GetCompleteFileName(const Base, FileName: string): string; +function IsFullFilePath(const Path: string): Boolean; // full means not relative +function DateTimeToBDETimeStamp(aDT: TDateTime): double; +function BDETimeStampToDateTime(aBT: double): TDateTime; +procedure FindNextName(BaseName: string; var OutName: string; var Modifier: Integer); +{$ifdef USE_CACHE} +function GetFreeMemory: Integer; +{$endif} + +function SwapWordBE(const Value: word): word; +function SwapWordLE(const Value: word): word; +function SwapIntBE(const Value: dword): dword; +function SwapIntLE(const Value: dword): dword; +{$ifdef SUPPORT_INT64} +procedure SwapInt64BE(Value, Result: Pointer); register; +procedure SwapInt64LE(Value, Result: Pointer); register; +{$endif} + +function TranslateString(FromCP, ToCP: Cardinal; Src, Dest: PChar; Length: Integer): Integer; + +// Returns a pointer to the first occurence of Chr in Str within the first Length characters +// Does not stop at null (#0) terminator! +function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer; + +// Delphi 3 does not have a Min function +{$ifdef DELPHI_3} +{$ifndef DELPHI_4} +function Min(x, y: integer): integer; +function Max(x, y: integer): integer; +{$endif} +{$endif} + +implementation + +{$ifdef msWINDOWS} +uses + Windows; +{$endif} + +//==================================================================== + +function GetCompletePath(const Base, Path: string): string; +begin + if IsFullFilePath(Path) + then begin + Result := Path; + end else begin + if Length(Base) > 0 then + Result := ExpandFileName(IncludeTrailingPathDelimiter(Base) + Path) + else + Result := ExpandFileName(Path); + end; + + // add last backslash if not present + if Length(Result) > 0 then + Result := IncludeTrailingPathDelimiter(Result); +end; + +function IsFullFilePath(const Path: string): Boolean; // full means not relative +begin +{$ifdef msWINDOWS} + Result := Length(Path) > 1; + if Result then + // check for 'x:' or '\\' at start of path + Result := ((Path[2]=':') and (upcase(Path[1]) in ['A'..'Z'])) + or ((Path[1]='\') and (Path[2]='\')); +{$else} // Linux + Result := Length(Path) > 0; + if Result then + Result := Path[1]='/'; + {$endif} +end; + +//==================================================================== + +function GetCompleteFileName(const Base, FileName: string): string; +var + lpath: string; + lfile: string; +begin + lpath := GetCompletePath(Base, ExtractFilePath(FileName)); + lfile := ExtractFileName(FileName); + lpath := lpath + lfile; + result := lpath; +end; + +function DateTimeToBDETimeStamp(aDT: TDateTime): double; +var + aTS: TTimeStamp; +begin + aTS := DateTimeToTimeStamp(aDT); + Result := TimeStampToMSecs(aTS); +end; + +function BDETimeStampToDateTime(aBT: double): TDateTime; +var + aTS: TTimeStamp; +begin + aTS := MSecsToTimeStamp(Round(aBT)); + Result := TimeStampToDateTime(aTS); +end; + +//==================================================================== + +{$ifndef SUPPORT_FREEANDNIL} + +procedure FreeAndNil(var v); +var + Temp: TObject; +begin + Temp := TObject(v); + TObject(v) := nil; + Temp.Free; +end; + +{$endif} + +procedure FreeMemAndNil(var P: Pointer); +var + Temp: Pointer; +begin + Temp := P; + P := nil; + FreeMem(Temp); +end; + +//==================================================================== + +{$ifndef SUPPORT_INCLTRAILPATHDELIM} +{$ifndef SUPPORT_INCLTRAILBACKSLASH} + +function IncludeTrailingPathDelimiter(const Path: string): string; +var + len: Integer; +begin + Result := Path; + len := Length(Result); + if len = 0 then + Result := PathDelim + else + if Result[len] <> PathDelim then + Result := Result + PathDelim; +end; + +{$else} + +function IncludeTrailingPathDelimiter(const Path: string): string; +begin +{$ifdef msWINDOWS} + Result := IncludeTrailingBackslash(Path); +{$else} + Result := IncludeTrailingSlash(Path); +{$endif} +end; + +{$endif} +{$endif} + +{$ifdef USE_CACHE} + +function GetFreeMemory: Integer; +var + MemStatus: TMemoryStatus; +begin + GlobalMemoryStatus(MemStatus); + Result := MemStatus.dwAvailPhys; +end; + +{$endif} + +//==================================================================== +// Utility routines +//==================================================================== + +{$ifdef ENDIAN_LITTLE} +function SwapWordBE(const Value: word): word; +{$else} +function SwapWordLE(const Value: word): word; +{$endif} +begin + Result := ((Value and $FF) shl 8) or ((Value shr 8) and $FF); +end; + +{$ifdef ENDIAN_LITTLE} +function SwapWordLE(const Value: word): word; +{$else} +function SwapWordBE(const Value: word): word; +{$endif} +begin + Result := Value; +end; + +{$ifdef FPC} + +function SwapIntBE(const Value: dword): dword; +begin + Result := BEtoN(Value); +end; + +function SwapIntLE(const Value: dword): dword; +begin + Result := LEtoN(Value); +end; + +procedure SwapInt64BE(Value, Result: Pointer); +begin + PInt64(Result)^ := BEtoN(PInt64(Value)^); +end; + +procedure SwapInt64LE(Value, Result: Pointer); +begin + PInt64(Result)^ := LEtoN(PInt64(Value)^); +end; + +{$else} +{$ifdef USE_ASSEMBLER_486_UP} + +function SwapIntBE(const Value: dword): dword; register; assembler; +asm + BSWAP EAX; +end; + +procedure SwapInt64BE(Value {EAX}, Result {EDX}: Pointer); register; assembler; +asm + MOV ECX, dword ptr [EAX] + MOV EAX, dword ptr [EAX + 4] + BSWAP ECX + BSWAP EAX + MOV dword ptr [EDX+4], ECX + MOV dword ptr [EDX], EAX +end; + +{$else} + +function SwapIntBE(const Value: Cardinal): Cardinal; +begin + PByteArray(@Result)[0] := PByteArray(@Value)[3]; + PByteArray(@Result)[1] := PByteArray(@Value)[2]; + PByteArray(@Result)[2] := PByteArray(@Value)[1]; + PByteArray(@Result)[3] := PByteArray(@Value)[0]; +end; + +procedure SwapInt64BE(Value, Result: Pointer); register; +var + PtrResult: PByteArray; + PtrSource: PByteArray; +begin + // temporary storage is actually not needed, but otherwise compiler crashes (?) + PtrResult := PByteArray(Result); + PtrSource := PByteArray(Value); + PtrResult[0] := PtrSource[7]; + PtrResult[1] := PtrSource[6]; + PtrResult[2] := PtrSource[5]; + PtrResult[3] := PtrSource[4]; + PtrResult[4] := PtrSource[3]; + PtrResult[5] := PtrSource[2]; + PtrResult[6] := PtrSource[1]; + PtrResult[7] := PtrSource[0]; +end; + +{$endif} + +function SwapIntLE(const Value: dword): dword; +begin + Result := Value; +end; + +{$ifdef SUPPORT_INT64} + +procedure SwapInt64LE(Value, Result: Pointer); +begin + PInt64(Result)^ := PInt64(Value)^; +end; + +{$endif} + +{$endif} + +function TranslateString(FromCP, ToCP: Cardinal; Src, Dest: PChar; Length: Integer): Integer; +var + WideCharStr: array[0..1023] of WideChar; + wideBytes: Cardinal; +begin + if Length = -1 then + Length := StrLen(Src); + Result := Length; +{$ifndef WINCE} + if (FromCP = GetOEMCP) and (ToCP = GetACP) then + OemToCharBuff(Src, Dest, Length) + else + if (FromCP = GetACP) and (ToCP = GetOEMCP) then + CharToOemBuff(Src, Dest, Length) + else +{$endif} + if FromCP = ToCP then + begin + if Src <> Dest then + Move(Src^, Dest^, Length); + end else begin + // does this work on Win95/98/ME? + wideBytes := MultiByteToWideChar(FromCP, MB_PRECOMPOSED, Src, Length, LPWSTR(@WideCharStr[0]), 1024); + Result := WideCharToMultiByte(ToCP, 0, LPWSTR(@WideCharStr[0]), wideBytes, Dest, Length, nil, nil); + end; +end; + +procedure FindNextName(BaseName: string; var OutName: string; var Modifier: Integer); +var + Extension: string; +begin + Extension := ExtractFileExt(BaseName); + BaseName := Copy(BaseName, 1, Length(BaseName)-Length(Extension)); + repeat + Inc(Modifier); + OutName := ChangeFileExt(BaseName+'_'+IntToStr(Modifier), Extension); + until not FileExists(OutName); +end; + +{$ifdef FPC} + +function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer; +var + I: Integer; +begin + I := System.IndexByte(Buffer, Length, Chr); + if I = -1 then + Result := nil + else + Result := Buffer+I; +end; + +{$else} + +function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer; +asm + PUSH EDI + MOV EDI,Buffer + MOV AL, Chr + MOV ECX,Length + REPNE SCASB + MOV EAX,0 + JNE @@1 + MOV EAX,EDI + DEC EAX +@@1: POP EDI +end; + +{$endif} + +{$ifdef DELPHI_3} +{$ifndef DELPHI_4} + +function Min(x, y: integer): integer; +begin + if x < y then + result := x + else + result := y; +end; + +function Max(x, y: integer): integer; +begin + if x < y then + result := y + else + result := x; +end; + +{$endif} +{$endif} + +end. + + + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_cursor.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_cursor.pas new file mode 100644 index 0000000..7f106f2 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_cursor.pas @@ -0,0 +1,64 @@ +unit dbf_cursor; + +interface + +{$I dbf_common.inc} + +uses + SysUtils, + classes,mclasses, + dbf_pgfile, + dbf_common; + +type + +//==================================================================== + TVirtualCursor = class(TObject) + private + FFile: TPagedFile; + + protected + function GetPhysicalRecNo: Integer; virtual; abstract; + function GetSequentialRecNo: Integer; virtual; abstract; + function GetSequentialRecordCount: Integer; virtual; abstract; + procedure SetPhysicalRecNo(RecNo: Integer); virtual; abstract; + procedure SetSequentialRecNo(RecNo: Integer); virtual; abstract; + + public + constructor Create(pFile: TPagedFile); + destructor Destroy; override; + + function RecordSize: Integer; + + function Next: Boolean; virtual; abstract; + function Prev: Boolean; virtual; abstract; + procedure First; virtual; abstract; + procedure Last; virtual; abstract; + + property PagedFile: TPagedFile read FFile; + property PhysicalRecNo: Integer read GetPhysicalRecNo write SetPhysicalRecNo; + property SequentialRecNo: Integer read GetSequentialRecNo write SetSequentialRecNo; + property SequentialRecordCount: Integer read GetSequentialRecordCount; + end; + +implementation + +constructor TVirtualCursor.Create(pFile: TPagedFile); +begin + FFile := pFile; +end; + +destructor TVirtualCursor.Destroy; {override;} +begin +end; + +function TVirtualCursor.RecordSize : Integer; +begin + if FFile = nil then + Result := 0 + else + Result := FFile.RecordSize; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_dbffile.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_dbffile.pas new file mode 100644 index 0000000..b90e03b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_dbffile.pas @@ -0,0 +1,2848 @@ +unit dbf_dbffile; + +// Modified 2013 by Martin Schreiber + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$I dbf_common.inc} + +uses + classes,mclasses,SysUtils, +{$ifdef msWINDOWS} + Windows, +{$else} +{$ifdef KYLIX} + Libc, +{$endif} + Types, dbf_wtil, +{$endif} + mdb, + dbf_common, + dbf_cursor, + dbf_pgfile, + dbf_fields, + dbf_memo, + dbf_idxfile; + +//==================================================================== +//=== Dbf support (first part) +//==================================================================== +// TxBaseVersion = (xUnknown,xClipper,xBaseIII,xBaseIV,xBaseV,xFoxPro,xVisualFoxPro); +// TPagedFileMode = (pfOpen,pfCreate); +// TDbfGetMode = (xFirst,xPrev,xCurrent, xNext, xLast); +// TDbfGetResult = (xOK, xBOF, xEOF, xError); + +type + +//==================================================================== + TDbfIndexMissingEvent = procedure(var DeleteLink: Boolean) of object; + TUpdateNullField = (unClear, unSet); + +//==================================================================== + TDbfGlobals = class; +//==================================================================== + + TDbfFile = class(TPagedFile) + protected + FMdxFile: TIndexFile; + FMemoFile: TMemoFile; + FFieldDefs: TDbfFieldDefs; + FIndexNames: TStringList; + FIndexFiles: TList; + FDbfVersion: TXBaseVersion; + FPrevBuffer: TRecordBuffer; + FDefaultBuffer: TRecordBuffer; + FRecordBufferSize: Integer; + FLockUserLen: DWORD; + FFileCodePage: Cardinal; + FUseCodePage: Cardinal; + FFileLangId: Byte; + FCountUse: Integer; + FCurIndex: Integer; + FForceClose: Boolean; + FLockField: TDbfFieldDef; + FNullField: TDbfFieldDef; + FAutoIncPresent: Boolean; + FCopyDateTimeAsString: Boolean; + FDateTimeHandling: TDateTimeHandling; + FOnLocaleError: TDbfLocaleErrorEvent; + FOnIndexMissing: TDbfIndexMissingEvent; + + function HasBlob: Boolean; + function GetMemoExt: string; + + function GetLanguageId: Integer; + function GetLanguageStr: string; + + protected + procedure ConstructFieldDefs; + procedure InitDefaultBuffer; + procedure UpdateNullField(Buffer: Pointer; AFieldDef: TDbfFieldDef; Action: TUpdateNullField); + procedure WriteLockInfo(Buffer: TRecordBuffer); + + public + constructor Create; + destructor Destroy; override; + + procedure Open; + procedure Close; + procedure Zap; + + procedure FinishCreate(AFieldDefs: TDbfFieldDefs; MemoSize: Integer); + function GetIndexByName(AIndexName: string): TIndexFile; + procedure SetRecordSize(NewSize: Integer); override; + + procedure TryExclusive; override; + procedure EndExclusive; override; + procedure OpenIndex(IndexName, IndexField: string; CreateIndex: Boolean; Options: TIndexOptions); + function DeleteIndex(const AIndexName: string): Boolean; + procedure CloseIndex(AIndexName: string); + procedure RepageIndex(AIndexFile: string); + procedure CompactIndex(AIndexFile: string); + function Insert(Buffer: TRecordBuffer): integer; + procedure WriteHeader; override; + procedure ApplyAutoIncToBuffer(DestBuf: TRecordBuffer); // dBase7 support. Writeback last next-autoinc value + procedure FastPackTable; + procedure RestructureTable(DbfFieldDefs: TDbfFieldDefs; Pack: Boolean); + procedure Rename(DestFileName: string; NewIndexFileNames: TStrings; DeleteFiles: boolean); + function GetFieldInfo(FieldName: string): TDbfFieldDef; + function GetFieldData(Column: Integer; DataType: TFieldType; Src,Dst: Pointer; + NativeFormat: boolean): Boolean; + function GetFieldDataFromDef(AFieldDef: TDbfFieldDef; DataType: TFieldType; + Src, Dst: Pointer; NativeFormat: boolean): Boolean; + procedure SetFieldData(Column: Integer; DataType: TFieldType; Src,Dst: Pointer; NativeFormat: boolean); + procedure InitRecord(DestBuf: TRecordBuffer); + procedure PackIndex(lIndexFile: TIndexFile; AIndexName: string); + procedure RegenerateIndexes; + procedure LockRecord(RecNo: Integer; Buffer: TRecordBuffer); + procedure UnlockRecord(RecNo: Integer; Buffer: TRecordBuffer); + procedure RecordDeleted(RecNo: Integer; Buffer: TRecordBuffer); + procedure RecordRecalled(RecNo: Integer; Buffer: TRecordBuffer); + + property MemoFile: TMemoFile read FMemoFile; + property FieldDefs: TDbfFieldDefs read FFieldDefs; + property IndexNames: TStringList read FIndexNames; + property IndexFiles: TList read FIndexFiles; + property MdxFile: TIndexFile read FMdxFile; + property LanguageId: Integer read GetLanguageId; + property LanguageStr: string read GetLanguageStr; + property FileCodePage: Cardinal read FFileCodePage; + property UseCodePage: Cardinal read FUseCodePage write FUseCodePage; + property FileLangId: Byte read FFileLangId write FFileLangId; + property DbfVersion: TXBaseVersion read FDbfVersion write FDbfVersion; + property PrevBuffer: TRecordBuffer read FPrevBuffer; + property ForceClose: Boolean read FForceClose; + property CopyDateTimeAsString: Boolean read FCopyDateTimeAsString write FCopyDateTimeAsString; + property DateTimeHandling: TDateTimeHandling read FDateTimeHandling write FDateTimeHandling; + + property OnIndexMissing: TDbfIndexMissingEvent read FOnIndexMissing write FOnIndexMissing; + property OnLocaleError: TDbfLocaleErrorEvent read FOnLocaleError write FOnLocaleError; + end; + +//==================================================================== + TDbfCursor = class(TVirtualCursor) + protected + FPhysicalRecNo: Integer; + public + constructor Create(DbfFile: TDbfFile); + function Next: Boolean; override; + function Prev: Boolean; override; + procedure First; override; + procedure Last; override; + + function GetPhysicalRecNo: Integer; override; + procedure SetPhysicalRecNo(RecNo: Integer); override; + + function GetSequentialRecordCount: Integer; override; + function GetSequentialRecNo: Integer; override; + procedure SetSequentialRecNo(RecNo: Integer); override; + end; + +//==================================================================== + TDbfGlobals = class + protected + FCodePages: TList; + FCurrencyAsBCD: Boolean; + FDefaultOpenCodePage: Integer; + FDefaultCreateLangId: Byte; + FUserName: string; + FUserNameLen: DWORD; + + function GetDefaultCreateCodePage: Integer; + procedure SetDefaultCreateCodePage(NewCodePage: Integer); + procedure InitUserName; + public + constructor Create; + destructor Destroy; override; + + function CodePageInstalled(ACodePage: Integer): Boolean; + + property CurrencyAsBCD: Boolean read FCurrencyAsBCD write FCurrencyAsBCD; + property DefaultOpenCodePage: Integer read FDefaultOpenCodePage write FDefaultOpenCodePage; + property DefaultCreateCodePage: Integer read GetDefaultCreateCodePage write SetDefaultCreateCodePage; + property DefaultCreateLangId: Byte read FDefaultCreateLangId write FDefaultCreateLangId; + property UserName: string read FUserName; + property UserNameLen: DWORD read FUserNameLen; + end; + +var + DbfGlobals: TDbfGlobals; + +implementation + +uses +{$ifndef WINDOWS} +{$ifndef FPC} + RTLConsts, +{$else} + BaseUnix, +{$endif} +{$endif} +{$ifdef SUPPORT_MATH_UNIT} + Math, +{$endif} + dbf_str, dbf_lang, mdbf_prssupp, mdbf_prsdef; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + sDBF_DEC_SEP = '.'; + +{$I dbf_struct.inc} + +//==================================================================== +// International separator +// thanks to Bruno Depero from Italy +// and Andreas W�nstein from Denmark +//==================================================================== +function DbfStrToFloat(const Src: PChar; const Size: Integer): Extended; +var + iPos: PChar; + eValue: extended; + endChar: Char; +begin + // temp null-term string + endChar := (Src + Size)^; + (Src + Size)^ := #0; + // we only have to convert if decimal separator different +{$warnings off} + if DecimalSeparator <> sDBF_DEC_SEP then +{$warnings on} + begin + // search dec sep + iPos := StrScan(Src, sDBF_DEC_SEP); + // replace + if iPos <> nil then +{$warnings off} + iPos^ := DecimalSeparator; +{$warnings on} + end else + iPos := nil; + // convert to double + if TextToFloat(Src, eValue {$ifndef VER1_0}, fvExtended{$endif}) then + Result := eValue + else + Result := 0; + // restore dec sep + if iPos <> nil then + iPos^ := sDBF_DEC_SEP; + // restore Char of null-term + (Src + Size)^ := endChar; +end; + +procedure FloatToDbfStr(const Val: Extended; const Size, Precision: Integer; const Dest: PChar); +var + Buffer: array [0..24] of Char; + resLen: Integer; + iPos: PChar; +begin + // convert to temporary buffer + resLen := FloatToText(@Buffer[0], Val, {$ifndef FPC_VERSION}fvExtended,{$endif} ffFixed, Size, Precision); + // prevent overflow in destination buffer + if resLen > Size then + resLen := Size; + // null-terminate buffer + Buffer[resLen] := #0; + // we only have to convert if decimal separator different +{$warnings off} + if DecimalSeparator <> sDBF_DEC_SEP then +{$warnings on} + begin +{$warnings off} + iPos := StrScan(@Buffer[0], DecimalSeparator); +{$warnings on} + if iPos <> nil then + iPos^ := sDBF_DEC_SEP; + end; + // fill destination with spaces + FillChar(Dest^, Size, ' '); + // now copy right-aligned to destination + Move(Buffer[0], Dest[Size-resLen], resLen); +end; + +function GetIntFromStrLength(Src: Pointer; Size: Integer; Default: Integer): Integer; +var + endChar: Char; + Code: Integer; +begin + // save Char at pos term. null + endChar := (PChar(Src) + Size)^; + (PChar(Src) + Size)^ := #0; + // convert + Val(PChar(Src), Result, Code); + // check success + if Code <> 0 then + Result := Default; + // restore prev. ending Char + (PChar(Src) + Size)^ := endChar; +end; + +//==================================================================== +// TDbfFile +//==================================================================== +constructor TDbfFile.Create; +begin + // init variables first + FFieldDefs := TDbfFieldDefs.Create(nil); + FIndexNames := TStringList.Create; + FIndexFiles := TList.Create; + + // now initialize inherited + inherited; +end; + +destructor TDbfFile.Destroy; +var + I: Integer; +begin + // close file + Close; + + // free files + for I := 0 to Pred(FIndexFiles.Count) do + TPagedFile(FIndexFiles.Items[I]).Free; + + // free lists + FreeAndNil(FIndexFiles); + FreeAndNil(FIndexNames); + FreeAndNil(FFieldDefs); + + // call ancestor + inherited; +end; + +procedure TDbfFile.Open; +var + lMemoFileName: string; + lMdxFileName: string; + MemoFileClass: TMemoFileClass; + I: Integer; + deleteLink: Boolean; + lModified: boolean; + LangStr: PChar; + version: byte; +begin + // check if not already opened + if not Active then + begin + // open requested file + OpenFile; + + // check if we opened an already existing file + lModified := false; + if not FileCreated then + begin + HeaderSize := sizeof(rDbfHdr); // temporary + // OH 2000-11-15 dBase7 support. I build dBase Tables with different + // BDE dBase Level (1. without Memo, 2. with Memo) + // Header Byte ($1d hex) (29 dec) -> Language driver ID. + // $03,$83 xBaseIII Header Byte $1d=$00, Float -> N($13.$04) DateTime C($1E) + // $03,$8B xBaseIV/V Header Byte $1d=$58, Float -> N($14.$04) + // $04,$8C xBaseVII Header Byte $1d=$00 Float -> O($08) DateTime @($08) + // $03,$F5 FoxPro Level 25 Header Byte $1d=$03, Float -> N($14.$04) + // Access 97 + // $03,$83 dBaseIII Header Byte $1d=$00, Float -> N($13.$05) DateTime D($08) + // $03,$8B dBaseIV/V Header Byte $1d=$00, Float -> N($14.$05) DateTime D($08) + // $03,$F5 FoxPro Level 25 Header Byte $1d=$09, Float -> N($14.$05) DateTime D($08) + + version := PDbfHdr(Header)^.VerDBF; + case (version and $07) of + $03: + if LanguageID = 0 then + FDbfVersion := xBaseIII + else + FDbfVersion := xBaseIV; + $04: + FDbfVersion := xBaseVII; + $02, $05: + FDbfVersion := xFoxPro; + else + // check visual foxpro + if ((version and $FE) = $30) or (version = $F5) or (version = $FB) then + begin + FDbfVersion := xFoxPro; + end else begin + // not a valid DBF file + raise EDbfError.Create(STRING_INVALID_DBF_FILE); + end; + end; + FFieldDefs.DbfVersion := FDbfVersion; + RecordSize := PDbfHdr(Header)^.RecordSize; + HeaderSize := PDbfHdr(Header)^.FullHdrSize; + if (HeaderSize = 0) or (RecordSize = 0) then + begin + HeaderSize := 0; + RecordSize := 0; + RecordCount := 0; + FForceClose := true; + exit; + end; + // check if specified recordcount correct + if PDbfHdr(Header)^.RecordCount <> RecordCount then + begin + // This message was annoying + // and was not understood by most people + // ShowMessage('Invalid Record Count,'+^M+ + // 'RecordCount in Hdr : '+IntToStr(PDbfHdr(Header).RecordCount)+^M+ + // 'expected : '+IntToStr(RecordCount)); + PDbfHdr(Header)^.RecordCount := RecordCount; + lModified := true; + end; + // determine codepage + if FDbfVersion >= xBaseVII then + begin + // cache language str + LangStr := @PAfterHdrVII(PChar(Header) + SizeOf(rDbfHdr))^.LanguageDriverName; + // VdBase 7 Language strings + // 'DBWIN...' -> Charset 1252 (ansi) + // 'DB999...' -> Code page 999, 9 any digit + // 'DBHEBREW' -> Code page 1255 ?? + // 'FOX..999' -> Code page 999, 9 any digit + // 'FOX..WIN' -> Charset 1252 (ansi) + if (LangStr[0] = 'D') and (LangStr[1] = 'B') then + begin + if StrLComp(LangStr+2, 'WIN', 3) = 0 then + FFileCodePage := 1252 + else + if StrLComp(LangStr+2, 'HEBREW', 6) = 0 then + begin + FFileCodePage := 1255; + end else begin + FFileCodePage := GetIntFromStrLength(LangStr+2, 3, 0); + if (Ord(LangStr[5]) >= Ord('0')) and (Ord(LangStr[5]) <= Ord('9')) then + FFileCodePage := FFileCodePage * 10 + Ord(LangStr[5]) - Ord('0'); + end; + end else + if StrLComp(LangStr, 'FOX', 3) = 0 then + begin + if StrLComp(LangStr+5, 'WIN', 3) = 0 then + FFileCodePage := 1252 + else + FFileCodePage := GetIntFromStrLength(LangStr+5, 3, 0) + end else begin + FFileCodePage := 0; + end; + FFileLangId := GetLangId_From_LangName(LanguageStr); + end else begin + // FDbfVersion <= xBaseV + FFileLangId := PDbfHdr(Header)^.Language; + FFileCodePage := LangId_To_CodePage[FFileLangId]; + end; + // determine used codepage, if no codepage, then use default codepage + FUseCodePage := FFileCodePage; + if FUseCodePage = 0 then + FUseCodePage := DbfGlobals.DefaultOpenCodePage; + // get list of fields + ConstructFieldDefs; + // open blob file if present + lMemoFileName := ChangeFileExt(FileName, GetMemoExt); + if HasBlob then + begin + // open blob file + if not FileExists(lMemoFileName) then + MemoFileClass := TNullMemoFile + else if FDbfVersion = xFoxPro then + MemoFileClass := TFoxProMemoFile + else + MemoFileClass := TDbaseMemoFile; + FMemoFile := MemoFileClass.Create(Self); + FMemoFile.FileName := lMemoFileName; + FMemoFile.Mode := Mode; + FMemoFile.AutoCreate := false; + FMemoFile.MemoRecordSize := 0; + FMemoFile.DbfVersion := FDbfVersion; + FMemoFile.Open; + // set header blob flag corresponding to field list + if FDbfVersion <> xFoxPro then + begin + PDbfHdr(Header)^.VerDBF := PDbfHdr(Header)^.VerDBF or $80; + lModified := true; + end; + end else + if FDbfVersion <> xFoxPro then + begin + PDbfHdr(Header)^.VerDBF := PDbfHdr(Header)^.VerDBF and $7F; + lModified := true; + end; + // check if mdx flagged + if (FDbfVersion <> xFoxPro) and (PDbfHdr(Header)^.MDXFlag <> 0) then + begin + // open mdx file if present + lMdxFileName := ChangeFileExt(FileName, '.mdx'); + if FileExists(lMdxFileName) then + begin + // open file + FMdxFile := TIndexFile.Create(Self); + FMdxFile.FileName := lMdxFileName; + FMdxFile.Mode := Mode; + FMdxFile.AutoCreate := false; + FMdxFile.OnLocaleError := FOnLocaleError; + FMdxFile.CodePage := UseCodePage; + FMdxFile.Open; + // is index ready for use? + if not FMdxFile.ForceClose then + begin + FIndexFiles.Add(FMdxFile); + // get index tag names known + FMdxFile.GetIndexNames(FIndexNames); + end else begin + // asked to close! close file + FreeAndNil(FMdxFile); + end; + end else begin + // ask user + deleteLink := true; + if Assigned(FOnIndexMissing) then + FOnIndexMissing(deleteLink); + // correct flag + if deleteLink then + begin + PDbfHdr(Header)^.MDXFlag := 0; + lModified := true; + end else + FForceClose := true; + end; + end; + end; + + // record changes + if lModified then + WriteHeader; + + // open indexes + for I := 0 to FIndexFiles.Count - 1 do + TIndexFile(FIndexFiles.Items[I]).Open; + end; +end; + +procedure TDbfFile.Close; +var + MdxIndex, I: Integer; +begin + if Active then + begin + // close index files first + MdxIndex := -1; + for I := 0 to FIndexFiles.Count - 1 do + begin + TIndexFile(FIndexFiles.Items[I]).Close; + if TIndexFile(FIndexFiles.Items[I]) = FMdxFile then + MdxIndex := I; + end; + // free memo file if any + FreeAndNil(FMemoFile); + + // now we can close physical dbf file + CloseFile; + + // free FMdxFile, remove it from the FIndexFiles and Names lists + if MdxIndex >= 0 then + FIndexFiles.Delete(MdxIndex); + I := 0; + while I < FIndexNames.Count do + begin + if FIndexNames.Objects[I] = FMdxFile then + begin + FIndexNames.Delete(I); + end else begin + Inc(I); + end; + end; + FreeAndNil(FMdxFile); + FreeMemAndNil(Pointer(FPrevBuffer)); + FreeMemAndNil(Pointer(FDefaultBuffer)); + + // reset variables + FFileLangId := 0; + end; +end; + +procedure TDbfFile.FinishCreate(AFieldDefs: TDbfFieldDefs; MemoSize: Integer); +var + lFieldDescIII: rFieldDescIII; + lFieldDescVII: rFieldDescVII; + lFieldDescPtr: Pointer; + lFieldDef: TDbfFieldDef; + lMemoFileName: string; + I, lFieldOffset, lSize, lPrec: Integer; + lHasBlob: Boolean; + lLocaleID: LCID; + +begin + try + // first reset file + RecordCount := 0; + lHasBlob := false; + // determine codepage & locale + if FFileLangId = 0 then + FFileLangId := DbfGlobals.DefaultCreateLangId; + FFileCodePage := LangId_To_CodePage[FFileLangId]; + lLocaleID := LangId_To_Locale[FFileLangId]; + FUseCodePage := FFileCodePage; + // prepare header size + if FDbfVersion = xBaseVII then + begin + // version xBaseVII without memo + HeaderSize := SizeOf(rDbfHdr) + SizeOf(rAfterHdrVII); + RecordSize := SizeOf(rFieldDescVII); + FillChar(Header^, HeaderSize, #0); + PDbfHdr(Header)^.VerDBF := $04; + // write language string + StrPLCopy( + @PAfterHdrVII(PChar(Header)+SizeOf(rDbfHdr))^.LanguageDriverName[32], + ConstructLangName(FFileCodePage, lLocaleID, false), + 63-32); + lFieldDescPtr := @lFieldDescVII; + end else begin + // version xBaseIII/IV/V without memo + HeaderSize := SizeOf(rDbfHdr) + SizeOf(rAfterHdrIII); + RecordSize := SizeOf(rFieldDescIII); + FillChar(Header^, HeaderSize, #0); + if FDbfVersion = xFoxPro then + begin + PDbfHdr(Header)^.VerDBF := $02 + end else + PDbfHdr(Header)^.VerDBF := $03; + // standard language WE, dBase III no language support + if FDbfVersion = xBaseIII then + PDbfHdr(Header)^.Language := 0 + else + PDbfHdr(Header)^.Language := FFileLangId; + // init field ptr + lFieldDescPtr := @lFieldDescIII; + end; + // begin writing fields + FFieldDefs.Clear; + // deleted mark 1 byte + lFieldOffset := 1; + for I := 1 to AFieldDefs.Count do + begin + lFieldDef := AFieldDefs.Items[I-1]; + + // check if datetime conversion + if FCopyDateTimeAsString then + if lFieldDef.FieldType = ftDateTime then + begin + // convert to string + lFieldDef.FieldType := ftString; + lFieldDef.Size := 22; + end; + + // update source + lFieldDef.FieldName := AnsiUpperCase(lFieldDef.FieldName); + lFieldDef.Offset := lFieldOffset; + lHasBlob := lHasBlob or lFieldDef.IsBlob; + + // apply field transformation tricks + lSize := lFieldDef.Size; + lPrec := lFieldDef.Precision; + if (lFieldDef.NativeFieldType = 'C') +{$ifndef USE_LONG_CHAR_FIELDS} + and (FDbfVersion = xFoxPro) +{$endif} + then + begin + lPrec := lSize shr 8; + lSize := lSize and $FF; + end; + + // update temp field props + if FDbfVersion = xBaseVII then + begin + FillChar(lFieldDescVII, SizeOf(lFieldDescVII), #0); + StrPLCopy(lFieldDescVII.FieldName, lFieldDef.FieldName, SizeOf(lFieldDescVII.FieldName)-1); + lFieldDescVII.FieldType := lFieldDef.NativeFieldType; + lFieldDescVII.FieldSize := lSize; + lFieldDescVII.FieldPrecision := lPrec; + lFieldDescVII.NextAutoInc := SwapIntLE(lFieldDef.AutoInc); + //lFieldDescVII.MDXFlag := ??? + end else begin + FillChar(lFieldDescIII, SizeOf(lFieldDescIII), #0); + StrPLCopy(lFieldDescIII.FieldName, lFieldDef.FieldName, SizeOf(lFieldDescIII.FieldName)-1); + lFieldDescIII.FieldType := lFieldDef.NativeFieldType; + lFieldDescIII.FieldSize := lSize; + lFieldDescIII.FieldPrecision := lPrec; + if FDbfVersion = xFoxPro then + lFieldDescIII.FieldOffset := SwapIntLE(lFieldOffset); + if (PDbfHdr(Header)^.VerDBF = $02) and (lFieldDef.NativeFieldType in ['0', 'Y', 'T', 'O', '+']) then + PDbfHdr(Header)^.VerDBF := $30; + if (PDbfHdr(Header)^.VerDBF = $30) and (lFieldDef.NativeFieldType = '+') then + PDbfHdr(Header)^.VerDBF := $31; + end; + + // update our field list + with FFieldDefs.AddFieldDef do + begin + Assign(lFieldDef); + Offset := lFieldOffset; + AutoInc := 0; + end; + + // save field props + WriteRecord(I, lFieldDescPtr); + Inc(lFieldOffset, lFieldDef.Size); + end; + // end of header + WriteChar($0D); + + // write memo bit + if lHasBlob then + begin + if FDbfVersion = xBaseIII then + PDbfHdr(Header)^.VerDBF := PDbfHdr(Header)^.VerDBF or $80 + else + if FDbfVersion = xFoxPro then + begin + if PDbfHdr(Header)^.VerDBF = $02 then + PDbfHdr(Header)^.VerDBF := $F5; + end else + PDbfHdr(Header)^.VerDBF := PDbfHdr(Header)^.VerDBF or $88; + end; + + // update header + PDbfHdr(Header)^.RecordSize := lFieldOffset; + PDbfHdr(Header)^.FullHdrSize := HeaderSize + RecordSize * AFieldDefs.Count + 1; + // add empty "back-link" info, whatever it is: + { A 263-byte range that contains the backlink, which is the relative path of + an associated database (.dbc) file, information. If the first byte is 0x00, + the file is not associated with a database. Therefore, database files always + contain 0x00. } + if FDbfVersion = xFoxPro then + Inc(PDbfHdr(Header)^.FullHdrSize, 263); + + // write dbf header to disk + inherited WriteHeader; + finally + RecordSize := PDbfHdr(Header)^.RecordSize; + HeaderSize := PDbfHdr(Header)^.FullHdrSize; + + // write full header to disk (dbf+fields) + WriteHeader; + end; + + if HasBlob and (FMemoFile=nil) then + begin + lMemoFileName := ChangeFileExt(FileName, GetMemoExt); + if FDbfVersion = xFoxPro then + FMemoFile := TFoxProMemoFile.Create(Self) + else + FMemoFile := TDbaseMemoFile.Create(Self); + FMemoFile.FileName := lMemoFileName; + FMemoFile.Mode := Mode; + FMemoFile.AutoCreate := AutoCreate; + FMemoFile.MemoRecordSize := MemoSize; + FMemoFile.DbfVersion := FDbfVersion; + FMemoFile.Open; + end; +end; + +function TDbfFile.HasBlob: Boolean; +var + I: Integer; +begin + Result := false; + for I := 0 to FFieldDefs.Count-1 do + if FFieldDefs.Items[I].IsBlob then + Result := true; +end; + +function TDbfFile.GetMemoExt: string; +begin + if FDbfVersion = xFoxPro then + Result := '.fpt' + else + Result := '.dbt'; +end; + +procedure TDbfFile.Zap; +begin + // make recordcount zero + RecordCount := 0; + // update recordcount + PDbfHdr(Header)^.RecordCount := RecordCount; + // update disk header + WriteHeader; + // update indexes + RegenerateIndexes; +end; + +procedure TDbfFile.WriteHeader; +var + SystemTime: TSystemTime; + lDataHdr: PDbfHdr; + EofTerminator: Byte; +begin + if (HeaderSize=0) then + exit; + + //FillHeader(0); + lDataHdr := PDbfHdr(Header); + GetLocalTime(SystemTime); + lDataHdr^.Year := SystemTime.wYear - 1900; + lDataHdr^.Month := SystemTime.wMonth; + lDataHdr^.Day := SystemTime.wDay; +// lDataHdr.RecordCount := RecordCount; + inherited WriteHeader; + + EofTerminator := $1A; + WriteBlock(@EofTerminator, 1, CalcPageOffset(RecordCount+1)); +end; + +procedure TDbfFile.ConstructFieldDefs; +var + {lColumnCount,}lHeaderSize,lFieldSize: Integer; + lPropHdrOffset, lFieldOffset: Integer; + lFieldDescIII: rFieldDescIII; + lFieldDescVII: rFieldDescVII; + lFieldPropsHdr: rFieldPropsHdr; + lStdProp: rStdPropEntry; + TempFieldDef: TDbfFieldDef; + lSize,lPrec,I, lColumnCount: Integer; + lAutoInc: Cardinal; + dataPtr: PChar; + lNativeFieldType: Char; + lFieldName: string; + lCanHoldNull: boolean; + lCurrentNullPosition: integer; +begin + FFieldDefs.Clear; + if DbfVersion >= xBaseVII then + begin + lHeaderSize := SizeOf(rAfterHdrVII) + SizeOf(rDbfHdr); + lFieldSize := SizeOf(rFieldDescVII); + end else begin + lHeaderSize := SizeOf(rAfterHdrIII) + SizeOf(rDbfHdr); + lFieldSize := SizeOf(rFieldDescIII); + end; + HeaderSize := lHeaderSize; + RecordSize := lFieldSize; + + FLockField := nil; + FNullField := nil; + FAutoIncPresent := false; + lColumnCount := (PDbfHdr(Header)^.FullHdrSize - lHeaderSize) div lFieldSize; + lFieldOffset := 1; + lAutoInc := 0; + I := 1; + lCurrentNullPosition := 0; + lCanHoldNull := false; + try + // there has to be minimum of one field + repeat + // version field info? + if FDbfVersion >= xBaseVII then + begin + ReadRecord(I, @lFieldDescVII); + lFieldName := AnsiUpperCase(PChar(@lFieldDescVII.FieldName[0])); + lSize := lFieldDescVII.FieldSize; + lPrec := lFieldDescVII.FieldPrecision; + lNativeFieldType := lFieldDescVII.FieldType; + lAutoInc := SwapIntLE(lFieldDescVII.NextAutoInc); + if lNativeFieldType = '+' then + FAutoIncPresent := true; + end else begin + ReadRecord(I, @lFieldDescIII); + lFieldName := AnsiUpperCase(PChar(@lFieldDescIII.FieldName[0])); + lSize := lFieldDescIII.FieldSize; + lPrec := lFieldDescIII.FieldPrecision; + lNativeFieldType := lFieldDescIII.FieldType; + lCanHoldNull := (FDbfVersion = xFoxPro) and + ((lFieldDescIII.FoxProFlags and $2) <> 0) and + (lFieldName <> '_NULLFLAGS'); + end; + + // apply field transformation tricks + if (lNativeFieldType = 'C') +{$ifndef USE_LONG_CHAR_FIELDS} + and (FDbfVersion = xFoxPro) +{$endif} + then + begin + lSize := lSize + lPrec shl 8; + lPrec := 0; + end; + + // add field + TempFieldDef := FFieldDefs.AddFieldDef; + with TempFieldDef do + begin + FieldName := lFieldName; + Offset := lFieldOffset; + Size := lSize; + Precision := lPrec; + AutoInc := lAutoInc; + NativeFieldType := lNativeFieldType; + if lCanHoldNull then + begin + NullPosition := lCurrentNullPosition; + inc(lCurrentNullPosition); + end else + NullPosition := -1; + end; + + // check valid field: + // 1) non-empty field name + // 2) known field type + // {3) no changes have to be made to precision or size} + if (Length(lFieldName) = 0) or (TempFieldDef.FieldType = ftUnknown) then + raise EDbfError.Create(STRING_INVALID_DBF_FILE); + + // determine if lock field present, if present, then store additional info + if lFieldName = '_DBASELOCK' then + begin + FLockField := TempFieldDef; + FLockUserLen := lSize - 8; + if FLockUserLen > DbfGlobals.UserNameLen then + FLockUserLen := DbfGlobals.UserNameLen; + end else + if UpperCase(lFieldName) = '_NULLFLAGS' then + FNullField := TempFieldDef; + + // goto next field + Inc(lFieldOffset, lSize); + Inc(I); + + // continue until header termination character found + // or end of header reached + until (I > lColumnCount) or (ReadChar = $0D); + + // test if not too many fields + if FFieldDefs.Count >= 4096 then + raise EDbfError.CreateFmt(STRING_INVALID_FIELD_COUNT, [FFieldDefs.Count]); + + // do not check FieldOffset = PDbfHdr(Header).RecordSize because additional + // data could be present in record + + // get current position + lPropHdrOffset := Stream.Position; + + // dBase 7 -> read field properties, test if enough space, maybe no header + if (FDbfVersion = xBaseVII) and (lPropHdrOffset + Sizeof(lFieldPropsHdr) < + PDbfHdr(Header)^.FullHdrSize) then + begin + // read in field properties header + ReadBlock(@lFieldPropsHdr, SizeOf(lFieldPropsHdr), lPropHdrOffset); + // read in standard properties + lFieldOffset := lPropHdrOffset + lFieldPropsHdr.StartStdProps; + for I := 0 to lFieldPropsHdr.NumStdProps - 1 do + begin + // read property data + ReadBlock(@lStdProp, SizeOf(lStdProp), lFieldOffset+I*SizeOf(lStdProp)); + // is this a constraint? + if lStdProp.FieldOffset = 0 then + begin + // this is a constraint...not implemented + end else if lStdProp.FieldOffset <= FFieldDefs.Count then begin + // get fielddef for this property + TempFieldDef := FFieldDefs.Items[lStdProp.FieldOffset-1]; + // allocate space to store data + TempFieldDef.AllocBuffers; + // dataPtr = nil -> no data to retrieve + dataPtr := nil; + // store data + case lStdProp.PropType of + FieldPropType_Required: TempFieldDef.Required := true; + FieldPropType_Default: + begin + dataPtr := TempFieldDef.DefaultBuf; + TempFieldDef.HasDefault := true; + end; + FieldPropType_Min: + begin + dataPtr := TempFieldDef.MinBuf; + TempFieldDef.HasMin := true; + end; + FieldPropType_Max: + begin + dataPtr := TempFieldDef.MaxBuf; + TempFieldDef.HasMax := true; + end; + end; + // get data for this property + if dataPtr <> nil then + ReadBlock(dataPtr, lStdProp.DataSize, lPropHdrOffset + lStdProp.DataOffset); + end; + end; + // read custom properties...not implemented + // read RI properties...not implemented + end; + finally + HeaderSize := PDbfHdr(Header)^.FullHdrSize; + RecordSize := PDbfHdr(Header)^.RecordSize; + end; +end; + +function TDbfFile.GetLanguageId: Integer; +begin + Result := PDbfHdr(Header)^.Language; +end; + +function TDbfFile.GetLanguageStr: String; +begin + result:= ''; + if FDbfVersion >= xBaseVII then + Result := PAfterHdrVII(PChar(Header) + SizeOf(rDbfHdr))^.LanguageDriverName; +end; + +{ + I fill the holes with the last records. + now we can do an 'in-place' pack +} +procedure TDbfFile.FastPackTable; +var + iDel,iNormal: Integer; + pDel,pNormal: PChar; + + function FindFirstDel: Boolean; + begin + while iDel<=iNormal do + begin + ReadRecord(iDel, pDel); + if (PChar(pDel)^ <> ' ') then + begin + Result := true; + exit; + end; + Inc(iDel); + end; + Result := false; + end; + + function FindLastNormal: Boolean; + begin + while iNormal>=iDel do + begin + ReadRecord(iNormal, pNormal); + if (PChar(pNormal)^= ' ') then + begin + Result := true; + exit; + end; + dec(iNormal); + end; + Result := false; + end; + +begin + if RecordSize < 1 then Exit; + + GetMem(pNormal, RecordSize); + GetMem(pDel, RecordSize); + try + iDel := 1; + iNormal := RecordCount; + + while FindFirstDel do + begin + // iDel is definitely deleted + if FindLastNormal then + begin + // but is not anymore + WriteRecord(iDel, pNormal); + PChar(pNormal)^ := '*'; + WriteRecord(iNormal, pNormal); + end else begin + // Cannot found a record after iDel so iDel must be deleted + dec(iDel); + break; + end; + end; + // FindFirstDel failed means than iDel is full + RecordCount := iDel; + RegenerateIndexes; + // Pack Memofields + finally + FreeMem(pNormal); + FreeMem(pDel); + end; +end; + +procedure TDbfFile.Rename(DestFileName: string; NewIndexFileNames: TStrings; DeleteFiles: boolean); +var + lIndexFileNames: TStrings; + lIndexFile: TIndexFile; + NewBaseName: string; + I: integer; +begin + // get memory for index file list + lIndexFileNames := TStringList.Create; + try + // save index filenames + for I := 0 to FIndexFiles.Count - 1 do + begin + lIndexFile := TIndexFile(IndexFiles[I]); + lIndexFileNames.Add(lIndexFile.FileName); + // prepare changing the dbf file name, needs changes in index files + lIndexFile.PrepareRename(NewIndexFileNames[I]); + end; + + // close file + Close; + + if DeleteFiles then + begin + SysUtils.DeleteFile(DestFileName); + SysUtils.DeleteFile(ChangeFileExt(DestFileName, GetMemoExt)); + end else begin + I := 0; + FindNextName(DestFileName, NewBaseName, I); + SysUtils.RenameFile(DestFileName, NewBaseName); + SysUtils.RenameFile(ChangeFileExt(DestFileName, GetMemoExt), + ChangeFileExt(NewBaseName, GetMemoExt)); + end; + // delete old index files + for I := 0 to NewIndexFileNames.Count - 1 do + SysUtils.DeleteFile(NewIndexFileNames.Strings[I]); + // rename the new dbf files + SysUtils.RenameFile(FileName, DestFileName); + SysUtils.RenameFile(ChangeFileExt(FileName, GetMemoExt), + ChangeFileExt(DestFileName, GetMemoExt)); + // rename new index files + for I := 0 to NewIndexFileNames.Count - 1 do + SysUtils.RenameFile(lIndexFileNames.Strings[I], NewIndexFileNames.Strings[I]); + finally + lIndexFileNames.Free; + end; +end; + +type + TRestructFieldInfo = record + SourceOffset: Integer; + DestOffset: Integer; + Size: Integer; + end; + + { assume nobody has more than 8192 fields, otherwise possibly range check error } + PRestructFieldInfo = ^TRestructFieldInfoArray; + TRestructFieldInfoArray = array[0..8191] of TRestructFieldInfo; + +procedure TDbfFile.RestructureTable(DbfFieldDefs: TDbfFieldDefs; Pack: Boolean); +var + DestDbfFile: TDbfFile; + TempIndexDef: TDbfIndexDef; + TempIndexFile: TIndexFile; + DestFieldDefs: TDbfFieldDefs; + TempDstDef, TempSrcDef: TDbfFieldDef; + OldIndexFiles: TStrings; + IndexName, NewBaseName: string; + I, lRecNo, lFieldNo, lFieldSize, lBlobPageNo, lWRecNo, srcOffset, dstOffset: Integer; + pBuff, pDestBuff: TRecordBuffer; + RestructFieldInfo: PRestructFieldInfo; + BlobStream: TMemoryStream; +begin + // nothing to do? + if (RecordSize < 1) or ((DbfFieldDefs = nil) and not Pack) then + exit; + + // if no exclusive access, terrible things can happen! + CheckExclusiveAccess; + + // make up some temporary filenames + lRecNo := 0; + FindNextName(FileName, NewBaseName, lRecNo); + + // select final field definition list + if DbfFieldDefs = nil then + begin + DestFieldDefs := FFieldDefs; + end else begin + DestFieldDefs := DbfFieldDefs; + // copy autoinc values + for I := 0 to DbfFieldDefs.Count - 1 do + begin + lFieldNo := DbfFieldDefs.Items[I].CopyFrom; + if (lFieldNo >= 0) and (lFieldNo < FFieldDefs.Count) then + DbfFieldDefs.Items[I].AutoInc := FFieldDefs.Items[lFieldNo].AutoInc; + end; + end; + + // create temporary dbf + DestDbfFile := TDbfFile.Create; + DestDbfFile.FileName := NewBaseName; + DestDbfFile.AutoCreate := true; + DestDbfFile.Mode := pfExclusiveCreate; + DestDbfFile.OnIndexMissing := FOnIndexMissing; + DestDbfFile.OnLocaleError := FOnLocaleError; + DestDbfFile.DbfVersion := FDbfVersion; + DestDbfFile.FileLangId := FileLangId; + DestDbfFile.Open; + // create dbf header + if FMemoFile <> nil then + DestDbfFile.FinishCreate(DestFieldDefs, FMemoFile.RecordSize) + else + DestDbfFile.FinishCreate(DestFieldDefs, 512); + + // adjust size and offsets of fields + GetMem(RestructFieldInfo, sizeof(TRestructFieldInfo)*DestFieldDefs.Count); + for lFieldNo := 0 to DestFieldDefs.Count - 1 do + begin + TempDstDef := DestFieldDefs.Items[lFieldNo]; + if TempDstDef.CopyFrom >= 0 then + begin + TempSrcDef := FFieldDefs.Items[TempDstDef.CopyFrom]; + if TempDstDef.NativeFieldType in ['F', 'N'] then + begin + // get minimum field length + lFieldSize := Min(TempSrcDef.Precision, TempDstDef.Precision) + + Min(TempSrcDef.Size - TempSrcDef.Precision, + TempDstDef.Size - TempDstDef.Precision); + // if one has dec separator, but other not, we lose one digit + if (TempDstDef.Precision > 0) xor + ((TempSrcDef.NativeFieldType in ['F', 'N']) and (TempSrcDef.Precision > 0)) then + Dec(lFieldSize); + // should not happen, but check nevertheless (maybe corrupt data) + if lFieldSize < 0 then + lFieldSize := 0; + srcOffset := TempSrcDef.Size - TempSrcDef.Precision - + (TempDstDef.Size - TempDstDef.Precision); + if srcOffset < 0 then + begin + dstOffset := -srcOffset; + srcOffset := 0; + end else begin + dstOffset := 0; + end; + end else begin + lFieldSize := Min(TempSrcDef.Size, TempDstDef.Size); + srcOffset := 0; + dstOffset := 0; + end; + with RestructFieldInfo[lFieldNo] do + begin + Size := lFieldSize; + SourceOffset := TempSrcDef.Offset + srcOffset; + DestOffset := TempDstDef.Offset + dstOffset; + end; + end; + end; + + // add indexes + TempIndexDef := TDbfIndexDef.Create(nil); + for I := 0 to FIndexNames.Count - 1 do + begin + // get length of extension -> determines MDX or NDX + IndexName := FIndexNames.Strings[I]; + TempIndexFile := TIndexFile(FIndexNames.Objects[I]); + TempIndexFile.GetIndexInfo(IndexName, TempIndexDef); + if Length(ExtractFileExt(IndexName)) > 0 then + begin + // NDX index, get unique file name + lRecNo := 0; + FindNextName(IndexName, IndexName, lRecNo); + end; + // add this index + DestDbfFile.OpenIndex(IndexName, TempIndexDef.SortField, true, TempIndexDef.Options); + end; + TempIndexDef.Free; + + // get memory for record buffers + GetMem(pBuff, RecordSize); + BlobStream := TMemoryStream.Create; + OldIndexFiles := TStringList.Create; + // if restructure, we need memory for dest buffer, otherwise use source + if DbfFieldDefs = nil then + pDestBuff := pBuff + else + GetMem(pDestBuff, DestDbfFile.RecordSize); + + // let the games begin! + try +{$ifdef USE_CACHE} + BufferAhead := true; + DestDbfFile.BufferAhead := true; +{$endif} + lWRecNo := 1; + for lRecNo := 1 to RecordCount do + begin + // read record from original dbf + ReadRecord(lRecNo, pBuff); + // copy record? + if (ansichar(pBuff^) <> '*') or not Pack then + begin + // if restructure, initialize dest + if DbfFieldDefs <> nil then + begin + DestDbfFile.InitRecord(pDestBuff); + // copy deleted mark (the first byte) + pDestBuff^ := pBuff^; + end; + + if (DbfFieldDefs <> nil) or (FMemoFile <> nil) then + begin + // copy fields + for lFieldNo := 0 to DestFieldDefs.Count-1 do + begin + TempDstDef := DestFieldDefs.Items[lFieldNo]; + // handle blob fields differently + // don't try to copy new blob fields! + // DbfFieldDefs = nil -> pack only + // TempDstDef.CopyFrom >= 0 -> copy existing (blob) field + if TempDstDef.IsBlob and ((DbfFieldDefs = nil) or (TempDstDef.CopyFrom >= 0)) then + begin + // get current blob blockno + GetFieldData(lFieldNo, ftInteger, pBuff, @lBlobPageNo, false); + // valid blockno read? + if lBlobPageNo > 0 then + begin + BlobStream.Clear; + FMemoFile.ReadMemo(lBlobPageNo, BlobStream); + BlobStream.Position := 0; + // always append + DestDbfFile.FMemoFile.WriteMemo(lBlobPageNo, 0, BlobStream); + end; + // write new blockno + DestDbfFile.SetFieldData(lFieldNo, ftInteger, @lBlobPageNo, pDestBuff, false); + end else if (DbfFieldDefs <> nil) and (TempDstDef.CopyFrom >= 0) then + begin + // copy content of field + with RestructFieldInfo[lFieldNo] do + Move(pBuff[SourceOffset], pDestBuff[DestOffset], Size); + end; + end; + end; + + // write record + DestDbfFile.WriteRecord(lWRecNo, pDestBuff); + // update indexes + for I := 0 to DestDbfFile.IndexFiles.Count - 1 do + TIndexFile(DestDbfFile.IndexFiles.Items[I]).Insert(lWRecNo, pDestBuff); + + // go to next record + Inc(lWRecNo); + end; + end; + +{$ifdef USE_CACHE} + BufferAhead := false; + DestDbfFile.BufferAhead := false; +{$endif} + + // save index filenames + for I := 0 to FIndexFiles.Count - 1 do + OldIndexFiles.Add(TIndexFile(IndexFiles[I]).FileName); + + // close dbf + Close; + + // if restructure -> rename the old dbf files + // if pack only -> delete the old dbf files + DestDbfFile.Rename(FileName, OldIndexFiles, DbfFieldDefs = nil); + + // we have to reinit fielddefs if restructured + Open; + + // crop deleted records + RecordCount := lWRecNo - 1; + // update date/time stamp, recordcount + PDbfHdr(Header)^.RecordCount := RecordCount; + WriteHeader; + finally + // close temporary file + FreeAndNil(DestDbfFile); + // free mem + FreeAndNil(OldIndexFiles); + FreeMem(pBuff); + FreeAndNil(BlobStream); + FreeMem(RestructFieldInfo); + if DbfFieldDefs <> nil then + FreeMem(pDestBuff); + end; +end; + +procedure TDbfFile.RegenerateIndexes; +var + lIndexNo: Integer; +begin + // recreate every index in every file + for lIndexNo := 0 to FIndexFiles.Count-1 do + begin + PackIndex(TIndexFile(FIndexFiles.Items[lIndexNo]), EmptyStr); + end; +end; + +function TDbfFile.GetFieldInfo(FieldName: string): TDbfFieldDef; +var + I: Integer; + lfi: TDbfFieldDef; +begin + FieldName := AnsiUpperCase(FieldName); + for I := 0 to FFieldDefs.Count-1 do + begin + lfi := TDbfFieldDef(FFieldDefs.Items[I]); + if lfi.fieldName = FieldName then + begin + Result := lfi; + exit; + end; + end; + Result := nil; +end; + +// NOTE: Dst may be nil! +function TDbfFile.GetFieldData(Column: Integer; DataType: TFieldType; + Src, Dst: Pointer; NativeFormat: boolean): Boolean; +var + TempFieldDef: TDbfFieldDef; +begin + TempFieldDef := TDbfFieldDef(FFieldDefs.Items[Column]); + Result := GetFieldDataFromDef(TempFieldDef, DataType, Src, Dst, NativeFormat); +end; + +// NOTE: Dst may be nil! +function TDbfFile.GetFieldDataFromDef(AFieldDef: TDbfFieldDef; DataType: TFieldType; + Src, Dst: Pointer; NativeFormat: boolean): Boolean; +var + FieldOffset, FieldSize: Integer; +// s: string; + ldd, ldm, ldy, lth, ltm, lts: Integer; + date: TDateTime; + timeStamp: TTimeStamp; + asciiContents: boolean; + +{$ifdef SUPPORT_INT64} + function GetInt64FromStrLength(Src: Pointer; Size: Integer; Default: Int64): Int64; + var + endChar: Char; + Code: Integer; + begin + // save Char at pos term. null + endChar := (PChar(Src) + Size)^; + (PChar(Src) + Size)^ := #0; + // convert + Val(PChar(Src), Result, Code); + // check success + if Code <> 0 then Result := Default; + // restore prev. ending Char + (PChar(Src) + Size)^ := endChar; + end; +{$endif} + + procedure CorrectYear(var wYear: Integer); + var wD, wM, wY, CenturyBase: Word; +(* +{$ifndef DELPHI_5} + // Delphi 3 standard-behavior no change possible + const TwoDigitYearCenturyWindow= 0; +{$endif} +*) + begin + if wYear >= 100 then + Exit; + DecodeDate(Date, wY, wm, wD); + // use Delphi-Date-Window + CenturyBase := wY{must be CurrentYear} - TwoDigitYearCenturyWindow; + Inc(wYear, CenturyBase div 100 * 100); + if (TwoDigitYearCenturyWindow > 0) and (wYear < CenturyBase) then + Inc(wYear, 100); + end; + + procedure SaveDateToDst; + begin + if not NativeFormat then + begin + // Delphi 5 requests a TDateTime + PDateTime(Dst)^ := date; + end else begin + // Delphi 3 and 4 request a TDateTimeRec + // date is TTimeStamp.date + // datetime = msecs == BDE timestamp as we implemented it + if DataType = ftDateTime then + begin + PDateTimeRec(Dst)^.DateTime := date; + end else begin + PLongInt(Dst)^ := DateTimeToTimeStamp(date).Date; + end; + end; + end; + +begin + // test if non-nil source (record buffer) + if Src = nil then + begin + Result := false; + exit; + end; + + // check Dst = nil, called with dst = nil to check empty field + if (FNullField <> nil) and (Dst = nil) and (AFieldDef.NullPosition >= 0) then + begin + // go to byte with null flag of this field + Src := PChar(Src) + FNullField.Offset + (AFieldDef.NullPosition shr 3); + Result := (PByte(Src)^ and (1 shl (AFieldDef.NullPosition and $7))) <> 0; + exit; + end; + + FieldOffset := AFieldDef.Offset; + FieldSize := AFieldDef.Size; + Src := PChar(Src) + FieldOffset; + asciiContents := false; + Result := true; + // field types that are binary and of which the fieldsize should not be truncated + case AFieldDef.NativeFieldType of + '+', 'I': + begin + if FDbfVersion <> xFoxPro then + begin + Result := PDWord(Src)^ <> 0; + if Result and (Dst <> nil) then + begin + PDWord(Dst)^ := SwapIntBE(PDWord(Src)^); + if Result then + PInteger(Dst)^ := Integer(PDWord(Dst)^ xor $80000000); + end; + end else begin + Result := true; + if Dst <> nil then + PInteger(Dst)^ := SwapIntLE(PInteger(Src)^); + end; + end; + 'O': + begin +{$ifdef SUPPORT_INT64} + Result := PInt64(Src)^ <> 0; + if Result and (Dst <> nil) then + begin + SwapInt64BE(Src, Dst); + if PInt64(Dst)^ > 0 then + PInt64(Dst)^ := not PInt64(Dst)^ + else + PDouble(Dst)^ := PDouble(Dst)^ * -1; + end; +{$endif} + end; + '@': + begin + Result := (PInteger(Src)^ <> 0) and (PInteger(PChar(Src)+4)^ <> 0); + if Result and (Dst <> nil) then + begin + SwapInt64BE(Src, Dst); + if FDateTimeHandling = dtBDETimeStamp then + date := BDETimeStampToDateTime(PDouble(Dst)^) + else + date := PDateTime(Dst)^; + SaveDateToDst; + end; + end; + 'T': + begin + // all binary zeroes -> empty datetime +{$ifdef SUPPORT_INT64} + Result := PInt64(Src)^ <> 0; +{$else} + Result := (PInteger(Src)^ <> 0) or (PInteger(PChar(Src)+4)^ <> 0); +{$endif} + if Result and (Dst <> nil) then + begin + timeStamp.Date := SwapIntLE(PInteger(Src)^) - JulianDateDelta; + timeStamp.Time := SwapIntLE(PInteger(PChar(Src)+4)^); + date := TimeStampToDateTime(timeStamp); + SaveDateToDst; + end; + end; + 'Y': + begin +{$ifdef SUPPORT_INT64} + Result := true; + if Dst <> nil then + begin + PInt64(Dst)^ := SwapIntLE(PInt64(Src)^); + if DataType = ftCurrency then + PDouble(Dst)^ := PInt64(Dst)^ / 10000.0; + end; +{$endif} + end; + 'B': // foxpro double + begin + if FDbfVersion = xFoxPro then + begin + Result := true; + if Dst <> nil then + PInt64(Dst)^ := SwapIntLE(PInt64(Src)^); + end else + asciiContents := true; + end; + 'M': + begin + if FieldSize = 4 then + begin + Result := PInteger(Src)^ <> 0; + if Dst <> nil then + PInteger(Dst)^ := SwapIntLE(PInteger(Src)^); + end else + asciiContents := true; + end; + else + asciiContents := true; + end; + if asciiContents then + begin + // SetString(s, PChar(Src) + FieldOffset, FieldSize ); + // s := {TrimStr(s)} TrimRight(s); + // truncate spaces at end by shortening fieldsize + while (FieldSize > 0) and ((PChar(Src) + FieldSize - 1)^ = ' ') do + dec(FieldSize); + // if not string field, truncate spaces at beginning too + if DataType <> ftString then + while (FieldSize > 0) and (PChar(Src)^ = ' ') do + begin + inc(PChar(Src)); + dec(FieldSize); + end; + // return if field is empty + Result := FieldSize > 0; + if Result and (Dst <> nil) then // data not needed if Result= false or Dst=nil + case DataType of + ftBoolean: + begin + // in DBase- FileDescription lowercase t is allowed too + // with asking for Result= true s must be longer then 0 + // else it happens an AV, maybe field is NULL + if (PChar(Src)^ = 'T') or (PChar(Src)^ = 't') then + PWord(Dst)^ := 1 + else + PWord(Dst)^ := 0; + end; + ftSmallInt: + PSmallInt(Dst)^ := GetIntFromStrLength(Src, FieldSize, 0); +{$ifdef SUPPORT_INT64} + ftLargeInt: + PLargeInt(Dst)^ := GetInt64FromStrLength(Src, FieldSize, 0); +{$endif} + ftInteger: + PInteger(Dst)^ := GetIntFromStrLength(Src, FieldSize, 0); + ftFloat, ftCurrency: + PDouble(Dst)^ := DbfStrToFloat(Src, FieldSize); + ftDate, ftDateTime: + begin + // get year, month, day + ldy := GetIntFromStrLength(PChar(Src) + 0, 4, 1); + ldm := GetIntFromStrLength(PChar(Src) + 4, 2, 1); + ldd := GetIntFromStrLength(PChar(Src) + 6, 2, 1); + //if (ly<1900) or (ly>2100) then ly := 1900; + //Year from 0001 to 9999 is possible + //everyting else is an error, an empty string too + //Do DateCorrection with Delphis possibillities for one or two digits + if (ldy < 100) and (PChar(Src)[0] = #32) and (PChar(Src)[1] = #32) then + CorrectYear(ldy); + try + date := EncodeDate(ldy, ldm, ldd); + except + date := 0; + end; + + // time stored too? + if (AFieldDef.FieldType = ftDateTime) and (DataType = ftDateTime) then + begin + // get hour, minute, second + lth := GetIntFromStrLength(PChar(Src) + 8, 2, 1); + ltm := GetIntFromStrLength(PChar(Src) + 10, 2, 1); + lts := GetIntFromStrLength(PChar(Src) + 12, 2, 1); + // encode + try + date := date + EncodeTime(lth, ltm, lts, 0); + except + date := 0; + end; + end; + + SaveDateToDst; + end; + ftString: + StrLCopy(Dst, Src, FieldSize); + end else begin + case DataType of + ftString: + if Dst <> nil then + PChar(Dst)[0] := #0; + end; + end; + end; +end; + +procedure TDbfFile.UpdateNullField(Buffer: Pointer; AFieldDef: TDbfFieldDef; + Action: TUpdateNullField); +var + NullDst: pbyte; + Mask: byte; +begin + // this field has null setting capability + NullDst := PByte(PChar(Buffer) + FNullField.Offset + (AFieldDef.NullPosition shr 3)); + Mask := 1 shl (AFieldDef.NullPosition and $7); + if Action = unSet then + begin + // clear the field, set null flag + NullDst^ := NullDst^ or Mask; + end else begin + // set field data, clear null flag + NullDst^ := NullDst^ and not Mask; + end; +end; + +procedure TDbfFile.SetFieldData(Column: Integer; DataType: TFieldType; + Src, Dst: Pointer; NativeFormat: boolean); +const + IsBlobFieldToPadChar: array[Boolean] of Char = (#32, '0'); + SrcNilToUpdateNullField: array[boolean] of TUpdateNullField = (unClear, unSet); +var + FieldSize,FieldPrec: Integer; + TempFieldDef: TDbfFieldDef; + Len: Integer; + IntValue: dword; + year, month, day: Word; + hour, minute, sec, msec: Word; + date: TDateTime; + timeStamp: TTimeStamp; + asciiContents: boolean; + + procedure LoadDateFromSrc; + begin + if not NativeFormat then + begin + // Delphi 5, new format, passes a TDateTime + date := PDateTime(Src)^; + end else begin + // Delphi 3 and 4, old "native" format, pass a TDateTimeRec with a time stamp + // date = integer + // datetime = msecs == BDETimeStampToDateTime as we implemented it + if DataType = ftDateTime then + begin + date := PDouble(Src)^; + end else begin + timeStamp.Time := 0; + timeStamp.Date := PLongInt(Src)^; + date := TimeStampToDateTime(timeStamp); + end; + end; + end; + +begin + date:= 0; + TempFieldDef := TDbfFieldDef(FFieldDefs.Items[Column]); + FieldSize := TempFieldDef.Size; + FieldPrec := TempFieldDef.Precision; + + // if src = nil then write empty field + // symmetry with above + + // foxpro has special _nullfield for flagging fields as `null' + if (FNullField <> nil) and (TempFieldDef.NullPosition >= 0) then + UpdateNullField(Dst, TempFieldDef, SrcNilToUpdateNullField[Src = nil]); + + // copy field data to record buffer + Dst := PChar(Dst) + TempFieldDef.Offset; + asciiContents := false; + case TempFieldDef.NativeFieldType of + '+', 'I': + begin + if FDbfVersion <> xFoxPro then + begin + if Src = nil then + IntValue := 0 + else + IntValue := PDWord(Src)^ xor $80000000; + PDWord(Dst)^ := SwapIntBE(IntValue); + end else begin + if Src = nil then + PDWord(Dst)^ := 0 + else + PDWord(Dst)^ := SwapIntLE(PDWord(Src)^); + end; + end; + 'O': + begin +{$ifdef SUPPORT_INT64} + if Src = nil then + begin + PInt64(Dst)^ := 0; + end else begin + if PDouble(Src)^ < 0 then + PInt64(Dst)^ := not PInt64(Src)^ + else + PDouble(Dst)^ := (PDouble(Src)^) * -1; + SwapInt64BE(Dst, Dst); + end; +{$endif} + end; + '@': + begin + if Src = nil then + begin +{$ifdef SUPPORT_INT64} + PInt64(Dst)^ := 0; +{$else} + PInteger(Dst)^ := 0; + PInteger(PChar(Dst)+4)^ := 0; +{$endif} + end else begin + LoadDateFromSrc; + if FDateTimeHandling = dtBDETimeStamp then + date := DateTimeToBDETimeStamp(date); + SwapInt64BE(@date, Dst); + end; + end; + 'T': + begin + // all binary zeroes -> empty datetime + if Src = nil then + begin +{$ifdef SUPPORT_INT64} + PInt64(Dst)^ := 0; +{$else} + PInteger(Dst)^ := 0; + PInteger(PChar(Dst)+4)^ := 0; +{$endif} + end else begin + LoadDateFromSrc; + timeStamp := DateTimeToTimeStamp(date); + PInteger(Dst)^ := SwapIntLE(timeStamp.Date + JulianDateDelta); + PInteger(PChar(Dst)+4)^ := SwapIntLE(timeStamp.Time); + end; + end; + 'Y': + begin +{$ifdef SUPPORT_INT64} + if Src = nil then + begin + PInt64(Dst)^ := 0; + end else begin + case DataType of + ftCurrency: + PInt64(Dst)^ := Trunc(PDouble(Src)^ * 10000); + ftBCD: + PCurrency(Dst)^ := PCurrency(Src)^; + end; + SwapInt64LE(Dst, Dst); + end; +{$endif} + end; + 'B': + begin + if DbfVersion = xFoxPro then + begin + if Src = nil then + PDouble(Dst)^ := 0 + else + SwapInt64LE(Src, Dst); + end else + asciiContents := true; + end; + 'M': + begin + if FieldSize = 4 then + begin + if Src = nil then + PInteger(Dst)^ := 0 + else + PInteger(Dst)^ := SwapIntLE(PInteger(Src)^); + end else + asciiContents := true; + end; + else + asciiContents := true; + end; + if asciiContents then + begin + if Src = nil then + begin + FillChar(Dst^, FieldSize, ' '); + end else begin + case DataType of + ftBoolean: + begin + if PWord(Src)^ <> 0 then + PChar(Dst)^ := 'T' + else + PChar(Dst)^ := 'F'; + end; + ftSmallInt: + GetStrFromInt_Width(PSmallInt(Src)^, FieldSize, PChar(Dst), #32); +{$ifdef SUPPORT_INT64} + ftLargeInt: + GetStrFromInt64_Width(PLargeInt(Src)^, FieldSize, PChar(Dst), #32); +{$endif} + ftFloat, ftCurrency: + FloatToDbfStr(PDouble(Src)^, FieldSize, FieldPrec, PChar(Dst)); + ftInteger: + GetStrFromInt_Width(PInteger(Src)^, FieldSize, PChar(Dst), + IsBlobFieldToPadChar[TempFieldDef.IsBlob]); + ftDate, ftDateTime: + begin + LoadDateFromSrc; + // decode + DecodeDate(date, year, month, day); + // format is yyyymmdd + GetStrFromInt_Width(year, 4, PChar(Dst), '0'); + GetStrFromInt_Width(month, 2, PChar(Dst)+4, '0'); + GetStrFromInt_Width(day, 2, PChar(Dst)+6, '0'); + // do time too if datetime + if DataType = ftDateTime then + begin + DecodeTime(date, hour, minute, sec, msec); + // format is hhmmss + GetStrFromInt_Width(hour, 2, PChar(Dst)+8, '0'); + GetStrFromInt_Width(minute, 2, PChar(Dst)+10, '0'); + GetStrFromInt_Width(sec, 2, PChar(Dst)+12, '0'); + end; + end; + ftString: + begin + // copy data + Len := StrLen(Src); + if Len > FieldSize then + Len := FieldSize; + Move(Src^, Dst^, Len); + // fill remaining space with spaces + FillChar((PChar(Dst)+Len)^, FieldSize - Len, ' '); + end; + end; // case datatype + end; + end; +end; + +procedure TDbfFile.InitDefaultBuffer; +var + lRecordSize: integer; + TempFieldDef: TDbfFieldDef; + I: Integer; +begin + lRecordSize := PDbfHdr(Header)^.RecordSize; + // clear buffer (assume all string, fix specific fields later) + // note: Self.RecordSize is used for reading fielddefs too + GetMem(FDefaultBuffer, lRecordSize+1); + FillChar(FDefaultBuffer^, lRecordSize, ' '); + + // set nullflags field so that all fields are null + if FNullField <> nil then + FillChar(PChar(FDefaultBuffer+FNullField.Offset)^, FNullField.Size, $FF); + + // check binary and default fields + for I := 0 to FFieldDefs.Count-1 do + begin + TempFieldDef := FFieldDefs.Items[I]; + // binary field? (foxpro memo fields are binary, but dbase not) + if (TempFieldDef.NativeFieldType in ['I', 'O', '@', '+', '0', 'Y']) + or ((TempFieldDef.NativeFieldType = 'M') and (TempFieldDef.Size = 4)) then + FillChar(PChar(FDefaultBuffer+TempFieldDef.Offset)^, TempFieldDef.Size, 0); + // copy default value? + if TempFieldDef.HasDefault then + begin + Move(TempFieldDef.DefaultBuf[0], FDefaultBuffer[TempFieldDef.Offset], TempFieldDef.Size); + // clear the null flag, this field has a value + if FNullField <> nil then + UpdateNullField(FDefaultBuffer, TempFieldDef, unClear); + end; + end; +end; + +procedure TDbfFile.InitRecord(DestBuf: TRecordBuffer); +begin + if FDefaultBuffer = nil then + InitDefaultBuffer; + Move(FDefaultBuffer^, DestBuf^, RecordSize); +end; + +procedure TDbfFile.ApplyAutoIncToBuffer(DestBuf: TRecordBuffer); +var + TempFieldDef: TDbfFieldDef; + I, NextVal, lAutoIncOffset: {LongWord} Cardinal; {Delphi 3 does not know LongWord?} +begin + if FAutoIncPresent then + begin + // if shared, reread header to find new autoinc values + if NeedLocks then + begin + // lock header so nobody else can use this value + LockPage(0, true); + end; + + // find autoinc fields + for I := 0 to FFieldDefs.Count-1 do + begin + TempFieldDef := FFieldDefs.Items[I]; + if (TempFieldDef.NativeFieldType = '+') then + begin + // read current auto inc, from header or field, depending on sharing + lAutoIncOffset := sizeof(rDbfHdr) + sizeof(rAfterHdrVII) + + FieldDescVII_AutoIncOffset + I * sizeof(rFieldDescVII); + if NeedLocks then + begin + ReadBlock(@NextVal, 4, lAutoIncOffset); + NextVal := SwapIntLE(NextVal); + end else + NextVal := TempFieldDef.AutoInc; + // store to buffer, positive = high bit on, so flip it + PCardinal(DestBuf+TempFieldDef.Offset)^ := SwapIntBE(NextVal or $80000000); + // increase + Inc(NextVal); + TempFieldDef.AutoInc := NextVal; + // write new value to header buffer + PCardinal(FHeader+lAutoIncOffset)^ := SwapIntLE(NextVal); + end; + end; + + // write modified header (new autoinc values) to file + WriteHeader; + + // release lock if locked + if NeedLocks then + UnlockPage(0); + end; +end; + +procedure TDbfFile.TryExclusive; +var + I: Integer; +begin + inherited; + + // exclusive succeeded? open index & memo exclusive too + if Mode in [pfMemoryCreate..pfExclusiveOpen] then + begin + // indexes + for I := 0 to FIndexFiles.Count - 1 do + TPagedFile(FIndexFiles[I]).TryExclusive; + // memo + if FMemoFile <> nil then + FMemoFile.TryExclusive; + end; +end; + +procedure TDbfFile.EndExclusive; +var + I: Integer; +begin + // end exclusive on index & memo too + for I := 0 to FIndexFiles.Count - 1 do + TPagedFile(FIndexFiles[I]).EndExclusive; + // memo + if FMemoFile <> nil then + FMemoFile.EndExclusive; + // dbf file + inherited; +end; + +procedure TDbfFile.OpenIndex(IndexName, IndexField: string; CreateIndex: Boolean; Options: TIndexOptions); + // + // assumes IndexName is not empty + // +const + // memcr, memop, excr, exopen, rwcr, rwopen, rdonly + IndexOpenMode: array[boolean, pfMemoryCreate..pfReadOnly] of TPagedFileMode = + ((pfMemoryCreate, pfMemoryCreate, pfExclusiveOpen, pfExclusiveOpen, pfReadWriteOpen, pfReadWriteOpen, + pfReadOnly), + (pfMemoryCreate, pfMemoryCreate, pfExclusiveCreate, pfExclusiveCreate, pfReadWriteCreate, pfReadWriteCreate, + pfReadOnly)); +var + lIndexFile: TIndexFile; + lIndexFileName: string; + createMdxFile: Boolean; + tempExclusive: boolean; + addedIndexFile: Integer; + addedIndexName: Integer; +begin + // init + addedIndexFile := -1; + addedIndexName := -1; + createMdxFile := false; + // index already opened? + lIndexFile := GetIndexByName(IndexName); + if (lIndexFile <> nil) and (lIndexFile = FMdxFile) and CreateIndex then + begin + // index already exists in MDX file + // delete it to save space, this causes a repage + FMdxFile.DeleteIndex(IndexName); + // index no longer exists + lIndexFile := nil; + end; + if (lIndexFile = nil) and (IndexName <> EmptyStr) then + begin + // check if no extension, then create MDX index + if Length(ExtractFileExt(IndexName)) = 0 then + begin + // check if mdx index already opened + if FMdxFile <> nil then + begin + lIndexFileName := EmptyStr; + lIndexFile := FMdxFile; + end else begin + lIndexFileName := ChangeFileExt(FileName, '.mdx'); + createMdxFile := true; + end; + end else begin + lIndexFileName := IndexName; + end; + // do we need to open / create file? + if lIndexFileName <> EmptyStr then + begin + // try to open / create the file + lIndexFile := TIndexFile.Create(Self); + lIndexFile.FileName := lIndexFileName; + lIndexFile.Mode := IndexOpenMode[CreateIndex, Mode]; + lIndexFile.AutoCreate := CreateIndex or (Length(IndexField) > 0); + lIndexFile.CodePage := UseCodePage; + lIndexFile.OnLocaleError := FOnLocaleError; + lIndexFile.Open; + // index file ready for use? + if not lIndexFile.ForceClose then + begin + // if we had to create the index, store that info + CreateIndex := lIndexFile.FileCreated; + // check if trying to create empty index + if CreateIndex and (IndexField = EmptyStr) then + begin + FreeAndNil(lIndexFile); + CreateIndex := false; + createMdxFile := false; + end else begin + // add new index file to list + addedIndexFile := FIndexFiles.Add(lIndexFile); + end; + // created accompanying mdx file? + if createMdxFile then + FMdxFile := lIndexFile; + end else begin + // asked to close! close file + FreeAndNil(lIndexFile); + end; + end; + + // check if file succesfully opened + if lIndexFile <> nil then + begin + // add index to list + addedIndexName := FIndexNames.AddObject(IndexName, lIndexFile); + end; + end; + // create it or open it? + if lIndexFile <> nil then + begin + if not CreateIndex then + if lIndexFile = FMdxFile then + CreateIndex := lIndexFile.IndexOf(IndexName) < 0; + if CreateIndex then + begin + // try get exclusive mode + tempExclusive := IsSharedAccess; + if tempExclusive then TryExclusive; + // always uppercase index expression + IndexField := AnsiUpperCase(IndexField); + try + try + // create index if asked + lIndexFile.CreateIndex(IndexField, IndexName, Options); + // add all records + PackIndex(lIndexFile, IndexName); + // if we wanted to open index readonly, but we created it, then reopen + if Mode = pfReadOnly then + begin + lIndexFile.CloseFile; + lIndexFile.Mode := pfReadOnly; + lIndexFile.OpenFile; + end; + // if mdx file just created, write changes to dbf header + // set MDX flag to true + PDbfHdr(Header)^.MDXFlag := 1; + WriteHeader; + except + on EDbfError do + begin + // :-( need to undo 'damage'.... + // remove index from list(s) if just added + if addedIndexFile >= 0 then + FIndexFiles.Delete(addedIndexFile); + if addedIndexName >= 0 then + FIndexNames.Delete(addedIndexName); + // if no file created, do not destroy! + if addedIndexFile >= 0 then + begin + lIndexFile.Close; + Sysutils.DeleteFile(lIndexFileName); + if FMdxFile = lIndexFile then + FMdxFile := nil; + lIndexFile.Free; + end; + raise; + end; + end; + finally + // return to previous mode + if tempExclusive then EndExclusive; + end; + end; + end; +end; + +procedure TDbfFile.PackIndex(lIndexFile: TIndexFile; AIndexName: string); +var + prevMode: TIndexUpdateMode; + prevIndex: string; + cur, last: Integer; +{$ifdef USE_CACHE} + prevCache: Integer; +{$endif} +begin + // save current mode in case we change it + prevMode := lIndexFile.UpdateMode; + prevIndex := lIndexFile.IndexName; + // check if index specified + if Length(AIndexName) > 0 then + begin + // only pack specified index, not all + lIndexFile.IndexName := AIndexName; + lIndexFile.ClearIndex; + lIndexFile.UpdateMode := umCurrent; + end else begin + lIndexFile.IndexName := EmptyStr; + lIndexFile.Clear; + lIndexFile.UpdateMode := umAll; + end; + // prepare update + cur := 1; + last := RecordCount; +{$ifdef USE_CACHE} + BufferAhead := true; + prevCache := lIndexFile.CacheSize; + lIndexFile.CacheSize := GetFreeMemory; + if lIndexFile.CacheSize < 16384 * 1024 then + lIndexFile.CacheSize := 16384 * 1024; +{$endif} + try + try + while cur <= last do + begin + ReadRecord(cur, FPrevBuffer); + lIndexFile.Insert(cur, FPrevBuffer); + inc(cur); + end; + except + on E: EDbfError do + begin + lIndexFile.DeleteIndex(lIndexFile.IndexName); + raise; + end; + end; + finally + // restore previous mode +{$ifdef USE_CACHE} + BufferAhead := false; + lIndexFile.BufferAhead := true; +{$endif} + lIndexFile.Flush; +{$ifdef USE_CACHE} + lIndexFile.BufferAhead := false; + lIndexFile.CacheSize := prevCache; +{$endif} + lIndexFile.UpdateMode := prevMode; + lIndexFile.IndexName := prevIndex; + end; +end; + +procedure TDbfFile.RepageIndex(AIndexFile: string); +var + lIndexNo: Integer; +begin + // DBF MDX index? + if Length(AIndexFile) = 0 then + begin + if FMdxFile <> nil then + begin + // repage attached mdx + FMdxFile.RepageFile; + end; + end else begin + // search index file + lIndexNo := FIndexNames.IndexOf(AIndexFile); + // index found? + if lIndexNo >= 0 then + TIndexFile(FIndexNames.Objects[lIndexNo]).RepageFile; + end; +end; + +procedure TDbfFile.CompactIndex(AIndexFile: string); +var + lIndexNo: Integer; +begin + // DBF MDX index? + if Length(AIndexFile) = 0 then + begin + if FMdxFile <> nil then + begin + // repage attached mdx + FMdxFile.CompactFile; + end; + end else begin + // search index file + lIndexNo := FIndexNames.IndexOf(AIndexFile); + // index found? + if lIndexNo >= 0 then + TIndexFile(FIndexNames.Objects[lIndexNo]).CompactFile; + end; +end; + +procedure TDbfFile.CloseIndex(AIndexName: string); +var + lIndexNo: Integer; + lIndex: TIndexFile; +begin + // search index file + lIndexNo := FIndexNames.IndexOf(AIndexName); + // don't close mdx file + if (lIndexNo >= 0) then + begin + // get index pointer + lIndex := TIndexFile(FIndexNames.Objects[lIndexNo]); + if (lIndex <> FMdxFile) then + begin + // close file + lIndex.Free; + // remove from lists + FIndexFiles.Remove(lIndex); + FIndexNames.Delete(lIndexNo); + // was this the current index? + if (FCurIndex = lIndexNo) then + begin + FCurIndex := -1; + //FCursor := FDbfCursor; + end; + end; + end; +end; + +function TDbfFile.DeleteIndex(const AIndexName: string): Boolean; +var + lIndexNo: Integer; + lIndex: TIndexFile; + lFileName: string; +begin + // search index file + lIndexNo := FIndexNames.IndexOf(AIndexName); + Result := lIndexNo >= 0; + // found index? + if Result then + begin + // can only delete indexes from MDX files + lIndex := TIndexFile(FIndexNames.Objects[lIndexNo]); + if lIndex = FMdxFile then + begin + lIndex.DeleteIndex(AIndexName); + // remove it from the list + FIndexNames.Delete(lIndexNo); + // no more MDX indexes? + lIndexNo := FIndexNames.IndexOfObject(FMdxFile); + if lIndexNo = -1 then + begin + // no MDX indexes left + lIndexNo := FIndexFiles.IndexOf(FMdxFile); + if lIndexNo >= 0 then + FIndexFiles.Delete(lIndexNo); + lFileName := FMdxFile.FileName; + FreeAndNil(FMdxFile); + // erase file + Sysutils.DeleteFile(lFileName); + // clear mdx flag + PDbfHdr(Header)^.MDXFlag := 0; + WriteHeader; + end; + end else begin + // close index first + CloseIndex(AIndexName); + // delete file from disk + SysUtils.DeleteFile(AIndexName); + end; + end; +end; + +function TDbfFile.Insert(Buffer: TRecordBuffer): integer; +type + TErrorContext = (ecNone, ecInsert, ecWriteIndex, ecWriteDbf); +var + newRecord: Integer; + lIndex: TIndexFile; + + procedure RollBackIndexesAndRaise(Count: Integer; ErrorContext: TErrorContext); + var + errorMsg: string; + I: Integer; + begin + errormsg:= ''; + // rollback committed indexes + for I := 0 to Count-1 do + begin + lIndex := TIndexFile(FIndexFiles.Items[I]); + lIndex.Delete(newRecord, Buffer); + end; + + // reset any dbf file error + ResetError; + + // if part of indexes committed -> always index error msg + // if error while rolling back index -> index error msg + case ErrorContext of + ecInsert: begin TIndexFile(FIndexFiles.Items[Count]).InsertError; exit; end; + ecWriteIndex: errorMsg := STRING_WRITE_INDEX_ERROR; + ecWriteDbf: errorMsg := STRING_WRITE_ERROR; + end; + raise EDbfWriteError.Create(errorMsg); + end; + +var + I: Integer; + error: TErrorContext; +begin + // get new record index + Result := 0; + newRecord := RecordCount+1; + // lock record so we can write data + while not LockPage(newRecord, false) do + Inc(newRecord); + // write autoinc value + ApplyAutoIncToBuffer(Buffer); + error := ecNone; + I := 0; + while I < FIndexFiles.Count do + begin + lIndex := TIndexFile(FIndexFiles.Items[I]); + if not lIndex.Insert(newRecord, Buffer) then + error := ecInsert; + if lIndex.WriteError then + error := ecWriteIndex; + if error <> ecNone then + begin + // if there's an index write error, I shouldn't + // try to write the dbf header and the new record, + // but raise an exception right away + UnlockPage(newRecord); + RollBackIndexesAndRaise(I, ecWriteIndex); + end; + Inc(I); + end; + + // indexes ok -> continue inserting + // update header record count + LockPage(0, true); + // read current header + ReadHeader; + // increase current record count + Inc(PDbfHdr(Header)^.RecordCount); + // write header to disk + WriteHeader; + // done with header + UnlockPage(0); + + if WriteError then + begin + // couldn't write header, so I shouldn't + // even try to write the record. + // + // At this point I should "roll back" + // the already written index records. + // if this fails, I'm in deep trouble! + UnlockPage(newRecord); + RollbackIndexesAndRaise(FIndexFiles.Count, ecWriteDbf); + end; + + // write locking info + if FLockField <> nil then + WriteLockInfo(Buffer); + // write buffer to disk + WriteRecord(newRecord, Buffer); + // done updating, unlock + UnlockPage(newRecord); + // error occurred while writing? + if WriteError then + begin + // -- Tobias -- + // The record couldn't be written, so + // the written index records and the + // change to the header have to be + // rolled back + LockPage(0, true); + ReadHeader; + Dec(PDbfHdr(Header)^.RecordCount); + WriteHeader; + UnlockPage(0); + // roll back indexes too + RollbackIndexesAndRaise(FIndexFiles.Count, ecWriteDbf); + end else + Result := newRecord; +end; + +procedure TDbfFile.WriteLockInfo(Buffer: TRecordBuffer); +// +// *) assumes FHasLockField = true +// +var + year, month, day, hour, minute, sec, msec: Word; + lockoffset: integer; +begin + // increase change count + lockoffset := FLockField.Offset; + Inc(PWord(Buffer+lockoffset)^); + // set time + DecodeDate(Now(), year, month, day); + DecodeTime(Now(), hour, minute, sec, msec); + Buffer[lockoffset+2] := TRecordBufferBaseType(hour); + Buffer[lockoffset+3] := TRecordBufferBaseType(minute); + Buffer[lockoffset+4] := TRecordBufferBaseType(sec); + // set date + Buffer[lockoffset+5] := TRecordBufferBaseType(year - 1900); + Buffer[lockoffset+6] := TRecordBufferBaseType(month); + Buffer[lockoffset+7] := TRecordBufferBaseType(day); + // set name + FillChar(Buffer[lockoffset+8], FLockField.Size-8, ' '); + Move(DbfGlobals.UserName[1], Buffer[lockoffset+8], FLockUserLen); +end; + +procedure TDbfFile.LockRecord(RecNo: Integer; Buffer: TRecordBuffer); +begin + if LockPage(RecNo, false) then + begin + // reread data + ReadRecord(RecNo, Buffer); + // store previous data for updating indexes + Move(Buffer^, FPrevBuffer^, RecordSize); + // lock succeeded, update lock info, if field present + if FLockField <> nil then + begin + // update buffer + WriteLockInfo(Buffer); + // write to disk + WriteRecord(RecNo, Buffer); + end; + end else + raise EDbfError.Create(STRING_RECORD_LOCKED); +end; + +procedure TDbfFile.UnlockRecord(RecNo: Integer; Buffer: TRecordBuffer); +var + I: Integer; + lIndex, lErrorIndex: TIndexFile; +begin + // update indexes, possible key violation + I := 0; + while I < FIndexFiles.Count do + begin + lIndex := TIndexFile(FIndexFiles.Items[I]); + if not lIndex.Update(RecNo, FPrevBuffer, Buffer) then + begin + // error -> rollback + lErrorIndex := lIndex; + while I > 0 do + begin + Dec(I); + lIndex := TIndexFile(FIndexFiles.Items[I]); + lIndex.Update(RecNo, Buffer, FPrevBuffer); + end; + lErrorIndex.InsertError; + end; + Inc(I); + end; + // write new record buffer, all keys ok + WriteRecord(RecNo, Buffer); + // done updating, unlock + UnlockPage(RecNo); +end; + +procedure TDbfFile.RecordDeleted(RecNo: Integer; Buffer: TRecordBuffer); +var + I: Integer; + lIndex: TIndexFile; +begin + // notify indexes: record deleted + for I := 0 to FIndexFiles.Count - 1 do + begin + lIndex := TIndexFile(FIndexFiles.Items[I]); + lIndex.RecordDeleted(RecNo, Buffer); + end; +end; + +procedure TDbfFile.RecordRecalled(RecNo: Integer; Buffer: TRecordBuffer); +var + I: Integer; + lIndex, lErrorIndex: TIndexFile; +begin + // notify indexes: record recalled + I := 0; + while I < FIndexFiles.Count do + begin + lIndex := TIndexFile(FIndexFiles.Items[I]); + if not lIndex.RecordRecalled(RecNo, Buffer) then + begin + lErrorIndex := lIndex; + while I > 0 do + begin + Dec(I); + lIndex.RecordDeleted(RecNo, Buffer); + end; + lErrorIndex.InsertError; + end; + Inc(I); + end; +end; + +procedure TDbfFile.SetRecordSize(NewSize: Integer); +begin + if NewSize <> RecordSize then + begin + if FPrevBuffer <> nil then + FreeMemAndNil(Pointer(FPrevBuffer)); + + if NewSize > 0 then + GetMem(FPrevBuffer, NewSize); + end; + inherited; +end; + +function TDbfFile.GetIndexByName(AIndexName: string): TIndexFile; +var + I: Integer; +begin + I := FIndexNames.IndexOf(AIndexName); + if I >= 0 then + Result := TIndexFile(FIndexNames.Objects[I]) + else + Result := nil; +end; + +//==================================================================== +// TDbfCursor +//==================================================================== +constructor TDbfCursor.Create(DbfFile: TDbfFile); +begin + inherited Create(DbfFile); +end; + +function TDbfCursor.Next: Boolean; +begin + if TDbfFile(PagedFile).IsRecordPresent(FPhysicalRecNo) then + begin + inc(FPhysicalRecNo); + Result := TDbfFile(PagedFile).IsRecordPresent(FPhysicalRecNo); + end else begin + FPhysicalRecNo := TDbfFile(PagedFile).CachedRecordCount + 1; + Result := false; + end; +end; + +function TDbfCursor.Prev: Boolean; +begin + if FPhysicalRecNo > 0 then + dec(FPhysicalRecNo) + else + FPhysicalRecNo := 0; + Result := FPhysicalRecNo > 0; +end; + +procedure TDbfCursor.First; +begin + FPhysicalRecNo := 0; +end; + +procedure TDbfCursor.Last; +var + max: Integer; +begin + max := TDbfFile(PagedFile).RecordCount; + if max = 0 then + FPhysicalRecNo := 0 + else + FPhysicalRecNo := max + 1; +end; + +function TDbfCursor.GetPhysicalRecNo: Integer; +begin + Result := FPhysicalRecNo; +end; + +procedure TDbfCursor.SetPhysicalRecNo(RecNo: Integer); +begin + FPhysicalRecNo := RecNo; +end; + +function TDbfCursor.GetSequentialRecordCount: Integer; +begin + Result := TDbfFile(PagedFile).RecordCount; +end; + +function TDbfCursor.GetSequentialRecNo: Integer; +begin + Result := FPhysicalRecNo; +end; + +procedure TDbfCursor.SetSequentialRecNo(RecNo: Integer); +begin + FPhysicalRecNo := RecNo; +end; + +// codepage enumeration procedure +var + TempCodePageList: TList; + +// LPTSTR = PChar ok? + +function CodePagesProc(CodePageString: PChar): Cardinal; stdcall; +begin + // add codepage to list + TempCodePageList.Add(Pointer(ptrint(GetIntFromStrLength(CodePageString, StrLen(CodePageString), -1)))); + + // continue enumeration + Result := 1; +end; + +//==================================================================== +// TDbfGlobals +//==================================================================== +constructor TDbfGlobals.Create; +begin + FCodePages := TList.Create; + FDefaultOpenCodePage := GetACP; + // the following sets FDefaultCreateLangId + DefaultCreateCodePage := GetACP; + FCurrencyAsBCD := true; + // determine which code pages are installed + TempCodePageList := FCodePages; + EnumSystemCodePages(@CodePagesProc, {CP_SUPPORTED} CP_INSTALLED); + TempCodePageList := nil; + InitUserName; +end; + +procedure TDbfGlobals.InitUserName; +{$ifdef FPC} +{$ifndef msWINDOWS} +var + TempName: UTSName; +{$endif} +{$endif} +begin +{$ifdef msWINDOWS} +{$ifdef wince} + FUserName:='cedevice'; + FUserNameLen:=Length(FUserName); +{$else} + FUserNameLen := MAX_COMPUTERNAME_LENGTH+1; + SetLength(FUserName, FUserNameLen); + Windows.GetComputerName(PChar(FUserName), + {$ifdef DELPHI_3}Windows.DWORD({$endif} + FUserNameLen + {$ifdef DELPHI_3}){$endif} + ); + SetLength(FUserName, FUserNameLen); +{$endif wince} +{$else} +{$ifdef FPC} + FpUname(TempName); + FUserName := TempName.machine; + FUserNameLen := Length(FUserName); +{$endif} +{$endif} +end; + +destructor TDbfGlobals.Destroy; {override;} +begin + FCodePages.Free; +end; + +function TDbfGlobals.GetDefaultCreateCodePage: Integer; +begin + Result := LangId_To_CodePage[FDefaultCreateLangId]; +end; + +procedure TDbfGlobals.SetDefaultCreateCodePage(NewCodePage: Integer); +begin + FDefaultCreateLangId := ConstructLangId(NewCodePage, GetUserDefaultLCID, false); +end; + +function TDbfGlobals.CodePageInstalled(ACodePage: Integer): Boolean; +begin + Result := FCodePages.IndexOf(Pointer(ptrint(ACodePage))) >= 0; +end; + +initialization +finalization + FreeAndNil(DbfGlobals); + + +(* + Stuffs non implemented yet + TFoxCDXHeader = Record + PointerRootNode : Integer; + PointerFreeList : Integer; + Reserved_8_11 : Cardinal; + KeyLength : Word; + IndexOption : Byte; + IndexSignature : Byte; + Reserved_Null : TFoxReservedNull; + SortOrder : Word; + TotalExpressionLen : Word; + ForExpressionLen : Word; + Reserved_506_507 : Word; + KeyExpressionLen : Word; + KeyForExpression : TKeyForExpression; + End; + PFoxCDXHeader = ^TFoxCDXHeader; + + TFoxCDXNodeCommon = Record + NodeAttributes : Word; + NumberOfKeys : Word; + PointerLeftNode : Integer; + PointerRightNode : Integer; + End; + + TFoxCDXNodeNonLeaf = Record + NodeCommon : TFoxCDXNodeCommon; + TempBlock : Array [12..511] of Byte; + End; + PFoxCDXNodeNonLeaf = ^TFoxCDXNodeNonLeaf; + + TFoxCDXNodeLeaf = Packed Record + NodeCommon : TFoxCDXNodeCommon; + BlockFreeSpace : Word; + RecordNumberMask : Integer; + DuplicateCountMask : Byte; + TrailByteCountMask : Byte; + RecNoBytes : Byte; + DuplicateCountBytes : Byte; + TrailByteCountBytes : Byte; + HoldingByteCount : Byte; + DataBlock : TDataBlock; + End; + PFoxCDXNodeLeaf = ^TFoxCDXNodeLeaf; + +*) + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_fields.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_fields.pas new file mode 100644 index 0000000..0e934e8 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_fields.pas @@ -0,0 +1,597 @@ +unit dbf_fields; + +// Modified 2013 by Martin Schreiber + +interface + +{$I dbf_common.inc} + +uses + classes,mclasses, + SysUtils, + mdb, + dbf_common, + dbf_str; + +type + PDbfFieldDef = ^TDbfFieldDef; + + TDbfFieldDef = class(TCollectionItem) + private + FFieldName: string; + FFieldType: TFieldType; + FNativeFieldType: TDbfFieldType; + FDefaultBuf: PChar; + FMinBuf: PChar; + FMaxBuf: PChar; + FSize: Integer; + FPrecision: Integer; + FHasDefault: Boolean; + FHasMin: Boolean; + FHasMax: Boolean; + FAllocSize: Integer; + FCopyFrom: Integer; + FOffset: Integer; + FAutoInc: Cardinal; + FRequired: Boolean; + FIsLockField: Boolean; + FNullPosition: integer; + + function GetDbfVersion: TXBaseVersion; + procedure SetNativeFieldType(lFieldType: TDbfFieldType); + procedure SetFieldType(lFieldType: TFieldType); + procedure SetSize(lSize: Integer); + procedure SetPrecision(lPrecision: Integer); + procedure VCLToNative; + procedure NativeToVCL; + procedure FreeBuffers; + protected + function GetDisplayName: string; override; + procedure AssignTo(Dest: TPersistent); override; + + property DbfVersion: TXBaseVersion read GetDbfVersion; + public + constructor Create(ACollection: TCollection); override; + destructor Destroy; override; + + procedure Assign(Source: TPersistent); override; + procedure AssignDb(DbSource: TFieldDef); + + procedure CheckSizePrecision; + procedure SetDefaultSize; + procedure AllocBuffers; + function IsBlob: Boolean; + + property DefaultBuf: PChar read FDefaultBuf; + property MinBuf: PChar read FMinBuf; + property MaxBuf: PChar read FMaxBuf; + property HasDefault: Boolean read FHasDefault write FHasDefault; + property HasMin: Boolean read FHasMin write FHasMin; + property HasMax: Boolean read FHasMax write FHasMax; + property Offset: Integer read FOffset write FOffset; + property AutoInc: Cardinal read FAutoInc write FAutoInc; + property IsLockField: Boolean read FIsLockField write FIsLockField; + property CopyFrom: Integer read FCopyFrom write FCopyFrom; + published + property FieldName: string read FFieldName write FFieldName; + property FieldType: TFieldType read FFieldType write SetFieldType; + property NativeFieldType: TDbfFieldType read FNativeFieldType write SetNativeFieldType; + property NullPosition: integer read FNullPosition write FNullPosition; + property Size: Integer read FSize write SetSize; + property Precision: Integer read FPrecision write SetPrecision; + property Required: Boolean read FRequired write FRequired; + end; + + TDbfFieldDefs = class(TCollection) + private + FOwner: TPersistent; + FDbfVersion: TXBaseVersion; + + function GetItem(Idx: Integer): TDbfFieldDef; + protected + function GetOwner: TPersistent; override; + public + constructor Create(Owner: TPersistent); + +{$ifdef SUPPORT_DEFAULT_PARAMS} + procedure Add(const Name: string; DataType: TFieldType; Size: Integer = 0; Required: Boolean = False); +{$else} + procedure Add(const Name: string; DataType: TFieldType; Size: Integer; Required: Boolean); +{$endif} + function AddFieldDef: TDbfFieldDef; + + property Items[Idx: Integer]: TDbfFieldDef read GetItem; + property DbfVersion: TXBaseVersion read FDbfVersion write FDbfVersion; + end; + +implementation + +uses + dbf_dbffile; // for dbf header structures + +{$I dbf_struct.inc} + +// I keep changing that fields... +// Last time has been asked by Venelin Georgiev +// Is he going to be the last ? +const +(* +The theory until now was : + ftSmallint 16 bits = -32768 to 32767 + 123456 = 6 digit max theorically + DIGITS_SMALLINT = 6; + ftInteger 32 bits = -2147483648 to 2147483647 + 12345678901 = 11 digits max + DIGITS_INTEGER = 11; + ftLargeInt 64 bits = -9223372036854775808 to 9223372036854775807 + 12345678901234567890 = 20 digits max + DIGITS_LARGEINT = 20; + +But in fact if I accept 6 digits into a ftSmallInt then tDbf will not +being able to handles fields with 999999 (6 digits). + +So I now oversize the field type in order to accept anithing coming from the +database. + ftSmallint 16 bits = -32768 to 32767 + -999 to 9999 + 4 digits max theorically + DIGITS_SMALLINT = 4; + ftInteger 32 bits = -2147483648 to 2147483647 + -99999999 to 999999999 12345678901 = 11 digits max + DIGITS_INTEGER = 9; + ftLargeInt 64 bits = -9223372036854775808 to 9223372036854775807 + -99999999999999999 to 999999999999999999 + DIGITS_LARGEINT = 18; + *) + DIGITS_SMALLINT = 4; + DIGITS_INTEGER = 9; + DIGITS_LARGEINT = 18; + +//==================================================================== +// DbfFieldDefs +//==================================================================== +function TDbfFieldDefs.GetItem(Idx: Integer): TDbfFieldDef; +begin + Result := TDbfFieldDef(inherited GetItem(Idx)); +end; + +constructor TDbfFieldDefs.Create(Owner: TPersistent); +begin + inherited Create(TDbfFieldDef); + FOwner := Owner; +end; + +function TDbfFieldDefs.AddFieldDef: TDbfFieldDef; +begin + Result := TDbfFieldDef(inherited Add); +end; + +function TDbfFieldDefs.GetOwner: TPersistent; {override;} +begin + Result := FOwner; +end; + +procedure TDbfFieldDefs.Add(const Name: string; DataType: TFieldType; Size: Integer; Required: Boolean); +var + FieldDef: TDbfFieldDef; +begin + FieldDef := AddFieldDef; + FieldDef.FieldName := Name; + FieldDef.FieldType := DataType; + if Size <> 0 then + FieldDef.Size := Size; + FieldDef.Required := Required; +end; + +//==================================================================== +// DbfFieldDef +//==================================================================== +constructor TDbfFieldDef.Create(ACollection: TCollection); {virtual} +begin + inherited; + + FDefaultBuf := nil; + FMinBuf := nil; + FMaxBuf := nil; + FAllocSize := 0; + FCopyFrom := -1; + FPrecision := 0; + FHasDefault := false; + FHasMin := false; + FHasMax := false; + FNullPosition := -1; +end; + +destructor TDbfFieldDef.Destroy; {override} +begin + FreeBuffers; + inherited; +end; + +procedure TDbfFieldDef.Assign(Source: TPersistent); +var + DbfSource: TDbfFieldDef; +begin + if Source is TDbfFieldDef then + begin + // copy from another TDbfFieldDef + DbfSource := TDbfFieldDef(Source); + FFieldName := DbfSource.FieldName; + FFieldType := DbfSource.FieldType; + FNativeFieldType := DbfSource.NativeFieldType; + FSize := DbfSource.Size; + FPrecision := DbfSource.Precision; + FRequired := DbfSource.Required; + FCopyFrom := DbfSource.Index; + FIsLockField := DbfSource.IsLockField; + FNullPosition := DbfSource.NullPosition; + // copy default,min,max + AllocBuffers; + if DbfSource.DefaultBuf <> nil then + Move(DbfSource.DefaultBuf^, FDefaultBuf^, FAllocSize*3); + FHasDefault := DbfSource.HasDefault; + FHasMin := DbfSource.HasMin; + FHasMax := DbfSource.HasMax; + // do we need offsets? + FOffset := DbfSource.Offset; + FAutoInc := DbfSource.AutoInc; +{$ifdef SUPPORT_FIELDDEF_TPERSISTENT} + end else if Source is TFieldDef then begin + AssignDb(TFieldDef(Source)); +{$endif} + end else + inherited Assign(Source); +end; + +procedure TDbfFieldDef.AssignDb(DbSource: TFieldDef); +begin + // copy from Db.TFieldDef + FFieldName := DbSource.Name; + FFieldType := DbSource.DataType; + FSize := DbSource.Size; + FPrecision := DbSource.Precision; + FRequired := DbSource.Required; +{$ifdef SUPPORT_FIELDDEF_INDEX} + FCopyFrom := DbSource.Index; +{$endif} + FIsLockField := false; + // convert VCL fieldtypes to native DBF fieldtypes + VCLToNative; + // for integer / float fields try fill in size/precision + if FSize = 0 then + SetDefaultSize + else + CheckSizePrecision; + // VCL does not have default value support + AllocBuffers; + FHasDefault := false; + FHasMin := false; + FHasMax := false; + FOffset := 0; + FAutoInc := 0; +end; + +procedure TDbfFieldDef.AssignTo(Dest: TPersistent); +{$ifdef SUPPORT_FIELDDEF_TPERSISTENT} + {$ifdef SUPPORT_FIELDDEF_ATTRIBUTES} +var + DbDest: TFieldDef; + {$endif} +{$endif} +begin +{$ifdef SUPPORT_FIELDDEF_TPERSISTENT} + // copy to VCL fielddef? + if Dest is TFieldDef then + begin + // VCL TFieldDef does not know how to handle TDbfFieldDef! + // what a shame :-) +{$ifdef SUPPORT_FIELDDEF_ATTRIBUTES} + DbDest := TFieldDef(Dest); + DbDest.Attributes := []; + DbDest.ChildDefs.Clear; + DbDest.DataType := FFieldType; + DbDest.Required := FRequired; + DbDest.Size := FSize; + DbDest.Name := FFieldName; +{$endif} + end else +{$endif} + inherited AssignTo(Dest); +end; + +function TDbfFieldDef.GetDbfVersion: TXBaseVersion; +begin + Result := TDbfFieldDefs(Collection).DbfVersion; +end; + +procedure TDbfFieldDef.SetFieldType(lFieldType: tFieldType); +begin + FFieldType := lFieldType; + VCLToNative; + SetDefaultSize; +end; + +procedure TDbfFieldDef.SetNativeFieldType(lFieldType: tDbfFieldType); +begin + // get uppercase field type + if (lFieldType >= 'a') and (lFieldType <= 'z') then + lFieldType := Chr(Ord(lFieldType)-32); + FNativeFieldType := lFieldType; + NativeToVCL; + CheckSizePrecision; +end; + +procedure TDbfFieldDef.SetSize(lSize: Integer); +begin + FSize := lSize; + CheckSizePrecision; +end; + +procedure TDbfFieldDef.SetPrecision(lPrecision: Integer); +begin + FPrecision := lPrecision; + CheckSizePrecision; +end; + +procedure TDbfFieldDef.NativeToVCL; +begin + case FNativeFieldType of +// OH 2000-11-15 dBase7 support. +// Add the new fieldtypes + '+' : + if DbfVersion = xBaseVII then + FFieldType := ftAutoInc; + 'I' : FFieldType := ftInteger; + 'O' : FFieldType := ftFloat; + '@', 'T': + FFieldType := ftDateTime; + 'C', + #$91 {Russian 'C'} + : FFieldType := ftString; + 'L' : FFieldType := ftBoolean; + 'F', 'N': + begin + if (FPrecision = 0) then + begin + if FSize <= DIGITS_SMALLINT then + FFieldType := ftSmallInt + else + if FSize <= DIGITS_INTEGER then + FFieldType := ftInteger + else +{$ifdef SUPPORT_INT64} + FFieldType := ftLargeInt; +{$else} + FFieldType := ftFloat; +{$endif} + end else begin + FFieldType := ftFloat; + end; + end; + 'D' : FFieldType := ftDate; + 'M' : FFieldType := ftMemo; + 'B' : + if DbfVersion = xFoxPro then + FFieldType := ftFloat + else + FFieldType := ftBlob; + 'G' : FFieldType := ftDBaseOle; + 'Y' : + if DbfGlobals.CurrencyAsBCD then + FFieldType := ftBCD + else + FFieldType := ftCurrency; + '0' : FFieldType := ftBytes; { Visual FoxPro ``_NullFlags'' } + else + FNativeFieldType := #0; + FFieldType := ftUnknown; + end; //case +end; + +procedure TDbfFieldDef.VCLToNative; +begin + FNativeFieldType := #0; + case FFieldType of + ftAutoInc : FNativeFieldType := '+'; + ftDateTime : + if DbfVersion = xBaseVII then + FNativeFieldType := '@' + else + if DbfVersion = xFoxPro then + FNativeFieldType := 'T' + else + FNativeFieldType := 'D'; +{$ifdef SUPPORT_FIELDTYPES_V4} + ftFixedChar, + ftWideString, +{$endif} + ftString : FNativeFieldType := 'C'; + ftBoolean : FNativeFieldType := 'L'; + ftFloat, ftSmallInt, ftWord +{$ifdef SUPPORT_INT64} + , ftLargeInt +{$endif} + : FNativeFieldType := 'N'; + ftDate : FNativeFieldType := 'D'; + ftMemo : FNativeFieldType := 'M'; + ftBlob : FNativeFieldType := 'B'; + ftDBaseOle : FNativeFieldType := 'G'; + ftInteger : + if DbfVersion = xBaseVII then + FNativeFieldType := 'I' + else + FNativeFieldType := 'N'; + ftBCD, ftCurrency: + if DbfVersion = xFoxPro then + FNativeFieldType := 'Y'; + end; + if FNativeFieldType = #0 then + raise EDbfError.CreateFmt(STRING_INVALID_VCL_FIELD_TYPE, [GetDisplayName, Ord(FFieldType)]); +end; + +procedure TDbfFieldDef.SetDefaultSize; +begin + // choose default values for variable size fields + case FFieldType of + ftFloat: + begin + FSize := 18; + FPrecision := 8; + end; + ftCurrency, ftBCD: + begin + FSize := 8; + FPrecision := 4; + end; + ftSmallInt, ftWord: + begin + FSize := DIGITS_SMALLINT; + FPrecision := 0; + end; + ftInteger, ftAutoInc: + begin + if DbfVersion = xBaseVII then + FSize := 4 + else + FSize := DIGITS_INTEGER; + FPrecision := 0; + end; +{$ifdef SUPPORT_INT64} + ftLargeInt: + begin + FSize := DIGITS_LARGEINT; + FPrecision := 0; + end; +{$endif} + ftString {$ifdef SUPPORT_FIELDTYPES_V4}, ftFixedChar, ftWideString{$endif}: + begin + FSize := 30; + FPrecision := 0; + end; + end; // case fieldtype + + // set sizes for fields that are restricted to single size/precision + CheckSizePrecision; +end; + +procedure TDbfFieldDef.CheckSizePrecision; +begin + case FNativeFieldType of + 'C': + begin + if FSize < 0 then + FSize := 0; + if DbfVersion = xFoxPro then + begin + if FSize >= $FFFF then + FSize := $FFFF; + end else begin + if FSize >= $FF then + FSize := $FF; + end; + FPrecision := 0; + end; + 'L': + begin + FSize := 1; + FPrecision := 0; + end; + 'N','F': + begin + // floating point + if FSize < 1 then FSize := 1; + if FSize >= 20 then FSize := 20; + if FPrecision > FSize-2 then FPrecision := FSize-2; + if FPrecision < 0 then FPrecision := 0; + end; + 'D': + begin + FSize := 8; + FPrecision := 0; + end; + 'B': + begin + if DbfVersion <> xFoxPro then + begin + FSize := 10; + FPrecision := 0; + end; + end; + 'M','G': + begin + if DbfVersion = xFoxPro then + begin + if (FSize <> 4) and (FSize <> 10) then + FSize := 4; + end else + FSize := 10; + FPrecision := 0; + end; + '+','I': + begin + FSize := 4; + FPrecision := 0; + end; + '@', 'O': + begin + FSize := 8; + FPrecision := 0; + end; + 'T': + begin + if DbfVersion = xFoxPro then + FSize := 8 + else + FSize := 14; + FPrecision := 0; + end; + 'Y': + begin + FSize := 8; + FPrecision := 4; + end; + else + // Nothing + end; // case +end; + +function TDbfFieldDef.GetDisplayName: string; {override;} +begin + Result := FieldName; +end; + +function TDbfFieldDef.IsBlob: Boolean; {override;} +begin + Result := FNativeFieldType in ['M','G','B']; +end; + +procedure TDbfFieldDef.FreeBuffers; +begin + if FDefaultBuf <> nil then + begin + // one buffer for all + FreeMemAndNil(Pointer(FDefaultBuf)); + FMinBuf := nil; + FMaxBuf := nil; + end; + FAllocSize := 0; +end; + +procedure TDbfFieldDef.AllocBuffers; +begin + // size changed? + if FAllocSize <> FSize then + begin + // free old buffers + FreeBuffers; + // alloc new + GetMem(FDefaultBuf, FSize*3); + FMinBuf := FDefaultBuf + FSize; + FMaxBuf := FMinBuf + FSize; + // store allocated size + FAllocSize := FSize; + end; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_idxcur.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_idxcur.pas new file mode 100644 index 0000000..3b46ae4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_idxcur.pas @@ -0,0 +1,217 @@ +unit dbf_idxcur; + +// Modified 2013 by Martin Schreiber + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$I dbf_common.inc} + +uses + SysUtils, + classes,mclasses, + mdb, + dbf_cursor, + dbf_idxfile, + mdbf_prsdef, +{$ifndef WINDOWS} + dbf_wtil, +{$endif} + dbf_common; + +type + +//==================================================================== +//=== Index support +//==================================================================== + TIndexCursor = class(TVirtualCursor) + private + FIndexFile: TIndexFile; + protected + function GetPhysicalRecNo: Integer; override; + function GetSequentialRecNo: Integer; override; + function GetSequentialRecordCount: Integer; override; + procedure SetPhysicalRecNo(RecNo: Integer); override; + procedure SetSequentialRecNo(RecNo: Integer); override; + + procedure VariantStrToBuffer(Key: Variant; ABuffer: TRecordBuffer); + public + constructor Create(DbfIndexFile: TIndexFile); + destructor Destroy; override; + + function Next: Boolean; override; + function Prev: Boolean; override; + procedure First; override; + procedure Last; override; + + procedure Insert(RecNo: Integer; Buffer: TRecordBuffer); + procedure Update(RecNo: Integer; PrevBuffer, NewBuffer: TRecordBuffer); + +{$ifdef SUPPORT_VARIANTS} + function VariantToBuffer(Key: Variant; ABuffer: TRecordBuffer): TExpressionType; +{$endif} + function CheckUserKey(Key: PChar; StringBuf: PChar): PChar; + + property IndexFile: TIndexFile read FIndexFile; + end; + +//==================================================================== +// TIndexCursor = class; +//==================================================================== + PIndexPosInfo = ^TIndexPage; + +//==================================================================== +implementation + +{$ifdef msWINDOWS} +uses + Windows; +{$endif} +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +//========================================================== +//============ TIndexCursor +//========================================================== +constructor TIndexCursor.Create(DbfIndexFile: TIndexFile); +begin + inherited Create(DbfIndexFile); + + FIndexFile := DbfIndexFile; +end; + +destructor TIndexCursor.Destroy; {override;} +begin + inherited Destroy; +end; + +procedure TIndexCursor.Insert(RecNo: Integer; Buffer: TRecordBuffer); +begin + TIndexFile(PagedFile).Insert(RecNo,Buffer); + // TODO SET RecNo and Key +end; + +procedure TIndexCursor.Update(RecNo: Integer; PrevBuffer, NewBuffer: TRecordBuffer); +begin + TIndexFile(PagedFile).Update(RecNo, PrevBuffer, NewBuffer); +end; + +procedure TIndexCursor.First; +begin + TIndexFile(PagedFile).First; +end; + +procedure TIndexCursor.Last; +begin + TIndexFile(PagedFile).Last; +end; + +function TIndexCursor.Prev: Boolean; +begin + Result := TIndexFile(PagedFile).Prev; +end; + +function TIndexCursor.Next: Boolean; +begin + Result := TIndexFile(PagedFile).Next; +end; + +function TIndexCursor.GetPhysicalRecNo: Integer; +begin + Result := TIndexFile(PagedFile).PhysicalRecNo; +end; + +procedure TIndexCursor.SetPhysicalRecNo(RecNo: Integer); +begin + TIndexFile(PagedFile).PhysicalRecNo := RecNo; +end; + +function TIndexCursor.GetSequentialRecordCount: Integer; +begin + Result := TIndexFile(PagedFile).SequentialRecordCount; +end; + +function TIndexCursor.GetSequentialRecNo: Integer; +begin + Result := TIndexFile(PagedFile).SequentialRecNo; +end; + +procedure TIndexCursor.SetSequentialRecNo(RecNo: Integer); +begin + TIndexFile(PagedFile).SequentialRecNo := RecNo; +end; + +{$ifdef SUPPORT_VARIANTS} + +procedure TIndexCursor.VariantStrToBuffer(Key: Variant; ABuffer: TRecordBuffer); +var + currLen: Integer; + StrKey: string; +begin + StrKey := Key; + currLen := TranslateString(GetACP, FIndexFile.CodePage, PAnsiChar(StrKey), PAnsiChar(ABuffer), -1); + // we have null-terminated string, pad with spaces if string too short + FillChar(ABuffer[currLen], TIndexFile(PagedFile).KeyLen-currLen, ' '); +end; + +function TIndexCursor.VariantToBuffer(Key: Variant; ABuffer: TRecordBuffer): TExpressionType; +// assumes ABuffer is large enough ie. at least max key size +begin + if (TIndexFile(PagedFile).KeyType='N') then + begin + PDouble(ABuffer)^ := Key; + if (TIndexFile(PagedFile).IndexVersion <> xBaseIII) then + begin + // make copy of userbcd to buffer + Move(TIndexFile(PagedFile).PrepareKey(ABuffer, etFloat)[0], ABuffer[0], 11); + end; + Result := etInteger; + end else begin + VariantStrToBuffer(Key, ABuffer); + Result := etString; + end; +end; + +{$endif} + +function TIndexCursor.CheckUserKey(Key: PChar; StringBuf: PChar): PChar; +var + keyLen, userLen: Integer; +begin + // default is to use key + Result := Key; + // if key is double, then no check + if (TIndexFile(PagedFile).KeyType = 'N') then + begin + // nothing needs to be done + end else begin + // check if string long enough then no copying needed + userLen := StrLen(Key); + keyLen := TIndexFile(PagedFile).KeyLen; + if userLen < keyLen then + begin + // copy string + Move(Key^, StringBuf[0], userLen); + // add spaces to searchstring + FillChar(StringBuf[userLen], keyLen - userLen, ' '); + // set buffer to temporary buffer + Result := StringBuf; + end; + end; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_idxfile.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_idxfile.pas new file mode 100644 index 0000000..089cec8 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_idxfile.pas @@ -0,0 +1,4186 @@ +unit dbf_idxfile; + +// Modified 2013 by Martin Schreiber + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$I dbf_common.inc} + +uses +{$ifdef msWINDOWS} + Windows, +{$else} +{$ifdef KYLIX} + Libc, +{$endif} + Types, dbf_wtil, +{$endif} + SysUtils, + classes,mclasses, + mdb, + dbf_pgfile, +{$ifdef USE_CACHE} + dbf_pgcfile, +{$endif} + dbf_parser, + mdbf_prsdef, + dbf_cursor, + dbf_collate, + dbf_common; + +{$ifdef _DEBUG} +{$define TDBF_INDEX_CHECK} +{$endif} +{$ifdef _ASSERTS} +{$define TDBF_INDEX_CHECK} +{$endif} + +const + MaxIndexes = 47; + +type + TIndexPage = class; + TIndexTag = class; + + TIndexUpdateMode = (umAll, umCurrent); + TLocaleError = (leNone, leUnknown, leTableIndexMismatch, leNotAvailable); + TLocaleSolution = (lsNotOpen, lsNoEdit, lsBinary); + TIndexUniqueType = (iuNormal, iuUnique, iuDistinct); + TIndexModifyMode = (mmNormal, mmDeleteRecall); + + TDbfLocaleErrorEvent = procedure(var Error: TLocaleError; var Solution: TLocaleSolution) of object; + TDbfCompareKeysEvent = function(Key1, Key2: PChar): Integer of object; + + PDouble = ^Double; + PInteger = ^Integer; + +//=========================================================================== + TDbfIndexDef = class; + TDbfIndexDef = class(TCollectionItem) + protected + FIndexName: string; + FExpression: string; + FOptions: TIndexOptions; + FTemporary: Boolean; // added at runtime + + procedure SetIndexName(NewName: string); + procedure SetExpression(NewField: string); + public + constructor Create(ACollection: TCollection); override; + destructor Destroy; override; + + procedure Assign(Source: TPersistent); override; + property Temporary: Boolean read FTemporary write FTemporary; + property Name: string read FIndexName write SetIndexName; + property Expression: string read FExpression write SetExpression; + published + property IndexFile: string read FIndexName write SetIndexName; + property SortField: string read FExpression write SetExpression; + property Options: TIndexOptions read FOptions write FOptions; + end; + + TDbfIndexParser = class(TDbfParser) + protected + FResultLen: Integer; + + procedure ValidateExpression(AExpression: string); override; + public + property ResultLen: Integer read FResultLen; + end; +//=========================================================================== + TIndexFile = class; + TIndexPageClass = class of TIndexPage; + + TIndexPage = class(TObject) + protected + FIndexFile: TIndexFile; + FLowerPage: TIndexPage; + FUpperPage: TIndexPage; + FPageBuffer: Pointer; + FEntry: Pointer; + FEntryNo: Integer; + FLockCount: Integer; + FModified: Boolean; + FPageNo: Integer; + FWeight: Integer; + + // bracket props + FLowBracket: Integer; // = FLowIndex if FPageNo = FLowPage + FLowIndex: Integer; + FLowPage: Integer; + FLowPageTemp: Integer; + FHighBracket: Integer; // = FHighIndex if FPageNo = FHighPage + FHighIndex: Integer; + FHighPage: Integer; + FHighPageTemp: Integer; + + procedure LocalInsert(RecNo: Integer; Buffer: PChar; LowerPageNo: Integer); + procedure LocalDelete; + procedure Delete; + + procedure SyncLowerPage; + procedure WritePage; + procedure Split; + procedure LockPage; + procedure UnlockPage; + + function RecurPrev: Boolean; + function RecurNext: Boolean; + procedure RecurFirst; + procedure RecurLast; + + procedure SetEntry(RecNo: Integer; AKey: PChar; LowerPageNo: Integer); + procedure SetEntryNo(value: Integer); + procedure SetPageNo(NewPageNo: Integer); + procedure SetLowPage(NewPage: Integer); + procedure SetHighPage(NewPage: Integer); + procedure SetUpperPage(NewPage: TIndexPage); + procedure UpdateBounds(IsInnerNode: Boolean); + + protected + function GetEntry(AEntryNo: Integer): Pointer; virtual; abstract; + function GetLowerPageNo: Integer; virtual; abstract; + function GetKeyData: PChar; virtual; abstract; + function GetNumEntries: Integer; virtual; abstract; + function GetKeyDataFromEntry(AEntry: Integer): PChar; virtual; abstract; + function GetRecNo: Integer; virtual; abstract; + function GetIsInnerNode: Boolean; virtual; abstract; + procedure IncNumEntries; virtual; abstract; + procedure SetNumEntries(NewNum: Integer); virtual; abstract; + procedure SetRecLowerPageNo(NewRecNo, NewPageNo: Integer); virtual; abstract; + procedure SetRecLowerPageNoOfEntry(AEntry, NewRecNo, NewPageNo: Integer); virtual; abstract; +{$ifdef TDBF_UPDATE_FIRST_LAST_NODE} + procedure SetPrevBlock(NewBlock: Integer); virtual; +{$endif} + + public + constructor Create(Parent: TIndexFile); + destructor Destroy; override; + + function FindNearest(ARecNo: Integer): Integer; + function PhysicalRecNo: Integer; + function MatchKey: Integer; + procedure GotoInsertEntry; + + procedure Clear; + procedure GetNewPage; + procedure Modified; + procedure RecalcWeight; + procedure UpdateWeight; + procedure Flush; + procedure SaveBracket; + procedure RestoreBracket; + + property Key: PChar read GetKeyData; + property Entry: Pointer read FEntry; + property EntryNo: Integer read FEntryNo write SetEntryNo; + property IndexFile: TIndexFile read FIndexFile; + property UpperPage: TIndexPage read FUpperPage write SetUpperPage; + property LowerPage: TIndexPage read FLowerPage; +// property LowerPageNo: Integer read GetLowerPageNo; // never used + property PageBuffer: Pointer read FPageBuffer; + property PageNo: Integer read FPageNo write SetPageNo; + property Weight: Integer read FWeight; + + property NumEntries: Integer read GetNumEntries; + property HighBracket: Integer read FHighBracket write FHighBracket; + property HighIndex: Integer read FHighIndex; + property HighPage: Integer read FHighPage write SetHighPage; + property LowBracket: Integer read FLowBracket write FLowBracket; + property LowIndex: Integer read FLowIndex; + property LowPage: Integer read FLowPage write SetLowPage; + end; +//=========================================================================== + TIndexTag = class(TObject) + private + FTag: Pointer; + protected + function GetHeaderPageNo: Integer; virtual; abstract; + function GetTagName: string; virtual; abstract; + function GetKeyFormat: Byte; virtual; abstract; + function GetForwardTag1: Byte; virtual; abstract; + function GetForwardTag2: Byte; virtual; abstract; + function GetBackwardTag: Byte; virtual; abstract; + function GetReserved: Byte; virtual; abstract; + function GetKeyType: Char; virtual; abstract; + procedure SetHeaderPageNo(NewPageNo: Integer); virtual; abstract; + procedure SetTagName(NewName: string); virtual; abstract; + procedure SetKeyFormat(NewFormat: Byte); virtual; abstract; + procedure SetForwardTag1(NewTag: Byte); virtual; abstract; + procedure SetForwardTag2(NewTag: Byte); virtual; abstract; + procedure SetBackwardTag(NewTag: Byte); virtual; abstract; + procedure SetReserved(NewReserved: Byte); virtual; abstract; + procedure SetKeyType(NewType: Char); virtual; abstract; + public + property HeaderPageNo: Integer read GetHeaderPageNo write SetHeaderPageNo; + property TagName: string read GetTagName write SetTagName; + property KeyFormat: Byte read GetKeyFormat write SetKeyFormat; + property ForwardTag1: Byte read GetForwardTag1 write SetForwardTag1; + property ForwardTag2: Byte read GetForwardTag2 write SetForwardTag2; + property BackwardTag: Byte read GetBackwardTag write SetBackwardTag; + property Reserved: Byte read GetReserved write SetReserved; + property KeyType: Char read GetKeyType write SetKeyType; + property Tag: Pointer read FTag write FTag; + end; +//=========================================================================== +{$ifdef USE_CACHE} + TIndexFile = class(TCachedFile) +{$else} + TIndexFile = class(TPagedFile) +{$endif} + protected + FIndexName: string; + FLastError: string; + FParsers: array[0..MaxIndexes-1] of TDbfIndexParser; + FIndexHeaders: array[0..MaxIndexes-1] of Pointer; + FIndexHeaderModified: array[0..MaxIndexes-1] of Boolean; + FIndexHeader: Pointer; + FIndexVersion: TXBaseVersion; + FRoots: array[0..MaxIndexes-1] of TIndexPage; + FLeaves: array[0..MaxIndexes-1] of TIndexPage; + FCurrentParser: TDbfIndexParser; + FRoot: TIndexPage; + FLeaf: TIndexPage; + FMdxTag: TIndexTag; + FTempMdxTag: TIndexTag; + FEntryHeaderSize: Integer; + FPageHeaderSize: Integer; + FTagSize: Integer; + FTagOffset: Integer; + FHeaderPageNo: Integer; + FSelectedIndex: Integer; + FRangeIndex: Integer; + FIsDescending: Boolean; + FUniqueMode: TIndexUniqueType; + FModifyMode: TIndexModifyMode; + FHeaderLocked: Integer; // used to remember which header page we have locked + FKeyBuffer: array[0..100] of Char; + FLowBuffer: array[0..100] of Char; + FHighBuffer: array[0..100] of Char; + FEntryBof: Pointer; + FEntryEof: Pointer; + FDbfFile: Pointer; + FCanEdit: Boolean; + FOpened: Boolean; + FRangeActive: Boolean; + FUpdateMode: TIndexUpdateMode; + FUserKey: PChar; // find / insert key + FUserRecNo: Integer; // find / insert recno + FUserBCD: array[0..10] of Byte; + FUserNumeric: Double; + FForceClose: Boolean; + FForceReadOnly: Boolean; + FCodePage: Integer; + FCollation: PCollationTable; + FCompareKeys: TDbfCompareKeysEvent; + FOnLocaleError: TDbfLocaleErrorEvent; + + function GetNewPageNo: Integer; + procedure TouchHeader(AHeader: Pointer); + function CreateTempFile(BaseName: string): TPagedFile; + procedure ConstructInsertErrorMsg; + procedure WriteIndexHeader(AIndex: Integer); + procedure SelectIndexVars(AIndex: Integer); + procedure CalcKeyProperties; + procedure UpdateIndexProperties; + procedure ClearRoots; + function CalcTagOffset(AIndex: Integer): Pointer; + + function FindKey(AInsert: boolean): Integer; + function InsertKey(Buffer: TRecordBuffer): Boolean; + procedure DeleteKey(Buffer: TRecordBuffer); + function InsertCurrent: Boolean; + procedure DeleteCurrent; + function UpdateCurrent(PrevBuffer, NewBuffer: TRecordBuffer): Boolean; + function UpdateIndex(Index: Integer; PrevBuffer, NewBuffer: TRecordBuffer): Boolean; + procedure ReadIndexes; + procedure Resync(Relative: boolean); + procedure ResyncRoot; + procedure ResyncTree; + procedure ResyncRange(KeepPosition: boolean); + procedure ResetRange; + procedure SetBracketLow; + procedure SetBracketHigh; + + procedure WalkFirst; + procedure WalkLast; + function WalkPrev: boolean; + function WalkNext: boolean; + + function CompareKeysNumericNDX(Key1, Key2: PChar): Integer; + function CompareKeysNumericMDX(Key1, Key2: PChar): Integer; + function CompareKeysString(Key1, Key2: PChar): Integer; + + // property functions + function GetName: string; + function GetDbfLanguageId: Byte; + function GetKeyLen: Integer; + function GetKeyType: Char; +// function GetIndexCount Integer; + function GetExpression: string; + function GetPhysicalRecNo: Integer; + function GetSequentialRecNo: Integer; + function GetSequentialRecordCount: Integer; + procedure SetSequentialRecNo(RecNo: Integer); + procedure SetPhysicalRecNo(RecNo: Integer); + procedure SetUpdateMode(NewMode: TIndexUpdateMode); + procedure SetIndexName(const AIndexName: string); + + public + constructor Create(ADbfFile: Pointer); + destructor Destroy; override; + + procedure Open; + procedure Close; + + procedure Clear; + procedure Flush; override; + procedure ClearIndex; + procedure AddNewLevel; + procedure UnlockHeader; + procedure InsertError; + function Insert(RecNo: Integer; Buffer:TRecordBuffer ): Boolean; + function Update(RecNo: Integer; PrevBuffer, NewBuffer: TRecordBuffer): Boolean; + procedure Delete(RecNo: Integer; Buffer: TRecordBuffer); + function CheckKeyViolation(Buffer: TRecordBuffer): Boolean; + procedure RecordDeleted(RecNo: Integer; Buffer: TRecordBuffer); + function RecordRecalled(RecNo: Integer; Buffer: TRecordBuffer): Boolean; + procedure DeleteIndex(const AIndexName: string); + procedure RepageFile; + procedure CompactFile; + procedure PrepareRename(NewFileName: string); + + procedure CreateIndex(FieldDesc, TagName: string; Options: TIndexOptions); + function ExtractKeyFromBuffer(Buffer: TRecordBuffer): PChar; + function SearchKey(Key: PChar; SearchType: TSearchKeyType): Boolean; + function Find(RecNo: Integer; Buffer: PChar): Integer; + function IndexOf(const AIndexName: string): Integer; + procedure DisableRange; + procedure EnableRange; + + procedure GetIndexNames(const AList: TStrings); + procedure GetIndexInfo(const AIndexName: string; IndexDef: TDbfIndexDef); + procedure WriteHeader; override; + procedure WriteFileHeader; + + procedure First; + procedure Last; + function Next: Boolean; + function Prev: Boolean; + + procedure SetRange(LowRange, HighRange: PChar); + procedure CancelRange; + function MatchKey(UserKey: PChar): Integer; + function CompareKey(Key: PChar): Integer; + function CompareKeys(Key1, Key2: PChar): Integer; + function PrepareKey(Buffer: TRecordBuffer; ResultType: TExpressionType): PChar; + + property KeyLen: Integer read GetKeyLen; + property IndexVersion: TXBaseVersion read FIndexVersion; + property EntryHeaderSize: Integer read FEntryHeaderSize; + property KeyType: Char read GetKeyType; + + property SequentialRecordCount: Integer read GetSequentialRecordCount; + property SequentialRecNo: Integer read GetSequentialRecNo write SetSequentialRecNo; + property PhysicalRecNo: Integer read GetPhysicalRecNo write SetPhysicalRecNo; + property HeaderPageNo: Integer read FHeaderPageNo; + + property IndexHeader: Pointer read FIndexHeader; + property EntryBof: Pointer read FEntryBof; + property EntryEof: Pointer read FEntryEof; + property UniqueMode: TIndexUniqueType read FUniqueMode; + property IsDescending: Boolean read FIsDescending; + + property UpdateMode: TIndexUpdateMode read FUpdateMode write SetUpdateMode; + property IndexName: string read FIndexName write SetIndexName; + property Expression: string read GetExpression; +// property Count: Integer read GetIndexCount; + + property ForceClose: Boolean read FForceClose; + property ForceReadOnly: Boolean read FForceReadOnly; + property CodePage: Integer read FCodePage write FCodePage; + + property OnLocaleError: TDbfLocaleErrorEvent read FOnLocaleError write FOnLocaleError; + end; + +//------------------------------------------------------------------------------ +implementation + +uses + dbf_dbffile, + dbf_fields, + dbf_str, + mdbf_prssupp, + mdbf_prscore, + dbf_lang; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + RecBOF = 0; + RecEOF = MaxInt; + + lcidBinary = $0A03; + + KeyFormat_Expression = $00; + KeyFormat_Data = $10; + + KeyFormat_Descending = $08; + KeyFormat_String = $10; + KeyFormat_Distinct = $20; + KeyFormat_Unique = $40; + + Unique_None = $00; + Unique_Unique = $01; + Unique_Distinct = $21; + +type + + TLCIDList = class(TList) + public + constructor Create; + + procedure Enumerate; + end; + + PMdxHdr = ^rMdxHdr; + rMdxHdr = record + MdxVersion : Byte; // 0 + Year : Byte; // 1 + Month : Byte; // 2 + Day : Byte; // 3 + FileName : array[0..15] of Char; // 4..19 + BlockSize : Word; // 20..21 + BlockAdder : Word; // 22..23 + ProdFlag : Byte; // 24 + NumTags : Byte; // 25 + TagSize : Byte; // 26 + Dummy1 : Byte; // 27 + TagsUsed : Word; // 28..29 + Dummy2 : Byte; // 30 + Language : Byte; // 31 + NumPages : Integer; // 32..35 + FreePage : Integer; // 36..39 + BlockFree : Integer; // 40..43 + UpdYear : Byte; // 44 + UpdMonth : Byte; // 45 + UpdDay : Byte; // 46 + Reserved : array[0..481] of Byte; // 47..528 + TagFlag : Byte; // 529 // dunno what this means but it ought to be 1 :-) + end; + + // Tags -> I don't know what to with them + // KeyType -> Variable position, db7 different from db4 + + PMdx4Tag = ^rMdx4Tag; + rMdx4Tag = record + HeaderPageNo : Integer; // 0..3 + TagName : array [0..10] of Char; // 4..14 of Byte + KeyFormat : Byte; // 15 00h: Calculated + // 10h: Data Field + ForwardTag1 : Byte; // 16 + ForwardTag2 : Byte; // 17 + BackwardTag : Byte; // 18 + Reserved : Byte; // 19 + KeyType : Char; // 20 C : Character + // N : Numerical + // D : Date + end; + + PMdx7Tag = ^rMdx7Tag; + rMdx7Tag = record + HeaderPageNo : Integer; // 0..3 + TagName : array [0..32] of Char; // 4..36 of Byte + KeyFormat : Byte; // 37 00h: Calculated + // 10h: Data Field + ForwardTag1 : Byte; // 38 + ForwardTag2 : Byte; // 39 + BackwardTag : Byte; // 40 + Reserved : Byte; // 41 + KeyType : Char; // 42 C : Character + // N : Numerical + // D : Date + end; + + PIndexHdr = ^rIndexHdr; + rIndexHdr = record + RootPage : Integer; // 0..3 + NumPages : Integer; // 4..7 + KeyFormat : Byte; // 8 00h: Right, Left, DTOC + // 08h: Descending order + // 10h: String + // 20h: Distinct + // 40h: Unique + KeyType : Char; // 9 C : Character + // N : Numerical + // D : Date + Dummy : Word; // 10..11 + KeyLen : Word; // 12..13 + NumKeys : Word; // 14..15 + sKeyType : Word; // 16..17 00h: DB4: C/N; DB3: C + // 01h: DB4: D ; DB3: N/D + KeyRecLen : Word; // 18..19 Length of key entry in page + Version : Word; // 20..21 + Dummy2 : Byte; // 22 + Unique : Byte; // 23 + KeyDesc : array [0..219] of Char; // 24..243 + Dummy3 : Byte; // 244 + ForExist : Byte; // 245 + KeyExist : Byte; // 246 + FirstNode : Longint; // 248..251 first node that contains data + LastNode : Longint; // 252..255 last node that contains data + // MDX Header has here a 506 byte block reserved + // and then the FILTER expression, which obviously doesn't + // fit in a NDX page, so we'll skip it + end; + + PMdxEntry = ^rMdxEntry; + rMdxEntry = record + RecBlockNo: Longint; // 0..3 either recno or blockno + KeyData : Char; // 4.. first byte of data, context => length + end; + + PMdxPage = ^rMdxPage; + rMdxPage = record + NumEntries : Integer; + PrevBlock : Integer; + FirstEntry : rMdxEntry; + end; + + PNdxEntry = ^rNdxEntry; + rNdxEntry = record + LowerPageNo: Integer; // 0..3 lower page + RecNo : Integer; // 4..7 recno + KeyData : Char; + end; + + PNdxPage = ^rNdxPage; + rNdxPage = record + NumEntries: Integer; // 0..3 + FirstEntry: rNdxEntry; + end; + +//--------------------------------------------------------------------------- + TMdxPage = class(TIndexPage) + protected + function GetEntry(AEntryNo: Integer): Pointer; override; + function GetLowerPageNo: Integer; override; + function GetKeyData: PChar; override; + function GetNumEntries: Integer; override; + function GetKeyDataFromEntry(AEntry: Integer): PChar; override; + function GetRecNo: Integer; override; + function GetIsInnerNode: Boolean; override; + procedure IncNumEntries; override; + procedure SetNumEntries(NewNum: Integer); override; + procedure SetRecLowerPageNo(NewRecNo, NewPageNo: Integer); override; + procedure SetRecLowerPageNoOfEntry(AEntry, NewRecNo, NewPageNo: Integer); override; +{$ifdef TDBF_UPDATE_FIRST_LAST_NODE} + procedure SetPrevBlock(NewBlock: Integer); override; +{$endif} + end; +//--------------------------------------------------------------------------- + TNdxPage = class(TIndexPage) + protected + function GetEntry(AEntryNo: Integer): Pointer; override; + function GetLowerPageNo: Integer; override; + function GetKeyData: PChar; override; + function GetNumEntries: Integer; override; + function GetKeyDataFromEntry(AEntry: Integer): PChar; override; + function GetRecNo: Integer; override; + function GetIsInnerNode: Boolean; override; + procedure IncNumEntries; override; + procedure SetNumEntries(NewNum: Integer); override; + procedure SetRecLowerPageNo(NewRecNo, NewPageNo: Integer); override; + procedure SetRecLowerPageNoOfEntry(AEntry, NewRecNo, NewPageNo: Integer); override; + end; +//--------------------------------------------------------------------------- + TMdx4Tag = class(TIndexTag) + protected + function GetHeaderPageNo: Integer; override; + function GetTagName: string; override; + function GetKeyFormat: Byte; override; + function GetForwardTag1: Byte; override; + function GetForwardTag2: Byte; override; + function GetBackwardTag: Byte; override; + function GetReserved: Byte; override; + function GetKeyType: Char; override; + procedure SetHeaderPageNo(NewPageNo: Integer); override; + procedure SetTagName(NewName: string); override; + procedure SetKeyFormat(NewFormat: Byte); override; + procedure SetForwardTag1(NewTag: Byte); override; + procedure SetForwardTag2(NewTag: Byte); override; + procedure SetBackwardTag(NewTag: Byte); override; + procedure SetReserved(NewReserved: Byte); override; + procedure SetKeyType(NewType: Char); override; + end; +//--------------------------------------------------------------------------- + TMdx7Tag = class(TIndexTag) + function GetHeaderPageNo: Integer; override; + function GetTagName: string; override; + function GetKeyFormat: Byte; override; + function GetForwardTag1: Byte; override; + function GetForwardTag2: Byte; override; + function GetBackwardTag: Byte; override; + function GetReserved: Byte; override; + function GetKeyType: Char; override; + procedure SetHeaderPageNo(NewPageNo: Integer); override; + procedure SetTagName(NewName: string); override; + procedure SetKeyFormat(NewFormat: Byte); override; + procedure SetForwardTag1(NewTag: Byte); override; + procedure SetForwardTag2(NewTag: Byte); override; + procedure SetBackwardTag(NewTag: Byte); override; + procedure SetReserved(NewReserved: Byte); override; + procedure SetKeyType(NewType: Char); override; + end; + +var + Entry_Mdx_BOF: rMdxEntry; //(RecBOF, #0); + Entry_Mdx_EOF: rMdxEntry; //(RecBOF, #0); + Entry_Ndx_BOF: rNdxEntry; //(0, RecBOF, #0); + Entry_Ndx_EOF: rNdxEntry; //(0, RecEOF, #0); + + LCIDList: TLCIDList; + +procedure IncWordLE(var AVariable: Word; Amount: Integer); +begin + AVariable := SwapWordLE(SwapWordLE(AVariable) + Amount); +end; + +procedure IncIntLE(var AVariable: Integer; Amount: Integer); +begin + AVariable := SwapIntLE(DWord(Integer(SwapIntLE(AVariable)) + Amount)); +end; + +//========================================================== +// Locale support for all versions of Delphi/C++Builder + +function LocaleCallBack(LocaleString: PChar): Integer; stdcall; +begin + LCIDList.Add(Pointer(ptrint(StrToInt('$'+LocaleString)))); + Result := 1; +end; + +constructor TLCIDList.Create; +begin + inherited; +end; + +procedure TLCIDList.Enumerate; +begin + Clear; + EnumSystemLocales(@LocaleCallBack, LCID_SUPPORTED); +end; + +{ TIndexPage } + +constructor TIndexPage.Create(Parent: TIndexFile); +begin + FIndexFile := Parent; + GetMem(FPageBuffer, FIndexFile.RecordSize); + FLowerPage := nil; + Clear; +end; + +destructor TIndexPage.Destroy; +begin + // no locks anymore? + assert(FLockCount = 0); + if (FLowerPage<>nil) then + LowerPage.Free; + WritePage; + FreeMemAndNil(FPageBuffer); + inherited Destroy; +end; + +procedure TIndexPage.Clear; +begin + FillChar(PChar(FPageBuffer)^, FIndexFile.RecordSize, 0); + FreeAndNil(FLowerPage); + FUpperPage := nil; + FPageNo := -1; + FEntryNo := -1; + FWeight := 1; + FModified := false; + FEntry := FIndexFile.EntryBof; + FLowPage := 0; + FHighPage := 0; + FLowIndex := 0; + FHighIndex := -1; + FLockCount := 0; +end; + +procedure TIndexPage.GetNewPage; +begin + FPageNo := FIndexFile.GetNewPageNo; +end; + +procedure TIndexPage.Modified; +begin + FModified := true; +end; + +procedure TIndexPage.LockPage; +begin + // already locked? + if FLockCount = 0 then + FIndexFile.LockPage(FPageNo, true); + // increase count + inc(FLockCount); +end; + +procedure TIndexPage.UnlockPage; +begin + // still in domain? + assert(FLockCount > 0); + dec(FLockCount); + // unlock? + if FLockCount = 0 then + begin + if FIndexFile.NeedLocks then + WritePage; + FIndexFile.UnlockPage(FPageNo); + end; +end; + +procedure TIndexPage.LocalInsert(RecNo: Integer; Buffer: PChar; LowerPageNo: Integer); + // *) assumes there is at least one entry free +var + source, dest: Pointer; + size, lNumEntries, numKeysAvail: Integer; +begin + // lock page if needed; wait if not available, anyone else updating? + LockPage; + // check assertions + lNumEntries := GetNumEntries; + // if this is inner node, we can only store one less than max entries + numKeysAvail := SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.NumKeys) - lNumEntries; + if FLowerPage <> nil then + dec(numKeysAvail); + // check if free space + assert(numKeysAvail > 0); + // first free up some space + source := FEntry; + dest := GetEntry(FEntryNo + 1); + size := (lNumEntries - EntryNo) * SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.KeyRecLen); + // if 'rightmost' entry, copy pageno too + if (FLowerPage <> nil) or (numKeysAvail > 1) then + size := size + FIndexFile.EntryHeaderSize; + Move(source^, dest^, size); + // one entry added + Inc(FHighIndex); + IncNumEntries; + // lNumEntries not valid from here + SetEntry(RecNo, Buffer, LowerPageNo); + // done! + UnlockPage; +end; + +procedure TIndexPage.LocalDelete; + + function IsOnlyEntry(Page: TIndexPage): boolean; + begin + Result := true; + repeat + if Page.HighIndex > 0 then + Result := false; + Page := Page.UpperPage; + until not Result or (Page = nil); + end; + +var + source, dest: Pointer; + size, lNumEntries: Integer; +begin + // get num entries + lNumEntries := GetNumEntries; + // is this last entry? if it's not move entries after current one + if EntryNo < FHighIndex then + begin + source := GetEntry(EntryNo + 1); + dest := FEntry; + size := (FHighIndex - EntryNo) * SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.KeyRecLen); + Move(source^, dest^, size); + end else + // no need to update when we're about to remove the only entry + if (UpperPage <> nil) and (FHighIndex > FLowIndex) then + begin + // we are about to remove the last on this page, so update search + // key data of parent + EntryNo := FHighIndex - 1; + UpperPage.SetEntry(0, GetKeyData, FPageNo); + end; + // one entry less now + dec(lNumEntries); + dec(FHighIndex); + SetNumEntries(lNumEntries); + // zero last one out to not get confused about internal or leaf pages + // note: need to decrease lNumEntries and HighIndex first, otherwise + // check on page key consistency will fail + SetRecLowerPageNoOfEntry(FHighIndex+1, 0, 0); + // update bracket indexes + if FHighPage = FPageNo then + dec(FHighBracket); + // check if range violated + if EntryNo > FHighIndex then + EntryNo := FHighIndex; + // check if still entries left, otherwise remove page from parent + if FHighIndex = -1 then + begin + if UpperPage <> nil then + if not IsOnlyEntry(UpperPage) then + UpperPage.LocalDelete; + end; + // go to valid record in lowerpage + if FLowerPage <> nil then + SyncLowerPage; + // flag modified page + FModified := true; + // success! +end; + +function TIndexPage.MatchKey: Integer; + // assumes Buffer <> nil +var + keyData: PChar; +begin + // get key data + keyData := GetKeyData; + // use locale dependant compare + Result := FIndexFile.CompareKey(keyData); +end; + +function TIndexPage.FindNearest(ARecNo: Integer): Integer; + // pre: + // assumes Key <> nil + // assumes FLowIndex <= FHighIndex + 1 + // ARecNo = -2 -> search first key matching Key + // ARecNo = -3 -> search first key greater than Key + // ARecNo > 0 -> search key matching Key and its recno = ARecNo + // post: + // Result < 0 -> key,recno smaller than current entry + // Result = 0 -> key,recno found, FEntryNo = found key entryno + // Result > 0 -> key,recno larger than current entry +var + low, high, current: Integer; +begin + // implement binary search, keys are sorted + low := FLowIndex; + high := GetNumEntries; + // always true: Entry(FEntryNo) = FEntry + // FHighIndex >= 0 because no-entry cases in leaves have been filtered out + // entry HighIndex may not be bigger than rest (in inner node) + // ARecNo = -3 -> search last recno matching key + // need to have: low <= high + // define low - 1 = neg.inf. + // define high = pos.inf + // inv1: (ARecNo<>-3) -> Entry(low-1).Key < Key <= Entry(high).Key + // inv2: (ARecNo =-3) -> Entry(low-1).Key <= Key < Entry(high).Key + // vf: high + 1 - low + while low < high do + begin + current := (low + high) div 2; + FEntry := GetEntry(current); + // calc diff + Result := MatchKey; + // test if we need to go lower or higher + // result < 0 implies key smaller than tested entry + // result = 0 implies key equal to tested entry + // result > 0 implies key greater than tested entry + if (Result < 0) or ((ARecNo<>-3) and (Result=0)) then + high := current + else + low := current+1; + end; + // high will contain first greater-or-equal key + // ARecNo <> -3 -> Entry(high).Key will contain first key that matches -> go to high + // ARecNo = -3 -> Entry(high).Key will contain first key that is greater -> go to high + FEntryNo := -1; + EntryNo := high; + // calc end result: can't inspect high if lowerpage <> nil + // if this is a leaf, we need to find specific recno + if (LowerPage = nil) then + begin + if high > FHighIndex then + begin + Result := 1; + end else begin + Result := MatchKey; + // test if we need to find a specific recno + // result < 0 -> current key greater -> nothing found -> don't search + if (ARecNo > 0) then + begin + // BLS to RecNo + high := FHighIndex + 1; + low := FEntryNo; + // inv: FLowIndex <= FEntryNo <= high <= FHighIndex + 1 /\ + // (Ai: FLowIndex <= i < FEntryNo: Entry(i).RecNo <> ARecNo) + while FEntryNo <> high do + begin + // FEntryNo < high, get new entry + if low <> FEntryNo then + begin + FEntry := GetEntry(FEntryNo); + // check if entry key still ok + Result := MatchKey; + end; + // test if out of range or found recno + if (Result <> 0) or (GetRecNo = ARecNo) then + high := FEntryNo + else begin + // default to EOF + inc(FEntryNo); + Result := 1; + end; + end; + end; + end; + end else begin + // FLowerPage <> nil -> high contains entry, can not have empty range + Result := 0; + end; +end; + +procedure TIndexPage.GotoInsertEntry; + // assures we really can insert here +begin + if FEntry = FIndexFile.EntryEof then + FEntry := GetEntry(FEntryNo); +end; + +procedure TIndexPage.SetEntry(RecNo: Integer; AKey: PChar; LowerPageNo: Integer); +var + keyData: PChar; +{$ifdef TDBF_INDEX_CHECK} + prevKeyData, curKeyData, nextKeyData: PChar; +{$endif} +begin + // get num entries + keyData := GetKeyData; + // check valid entryno: we should be able to insert entries! + assert((EntryNo >= 0) and (EntryNo <= FHighIndex)); + if (UpperPage <> nil) and (FEntryNo = FHighIndex) then + UpperPage.SetEntry(0, AKey, FPageNo); +{ if PIndexHdr(FIndexFile.IndexHeader).KeyType = 'C' then } + if AKey <> nil then + Move(AKey^, keyData^, SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.KeyLen)) + else + PChar(keyData)^ := #0; +{ + else + if AKey <> nil then + PDouble(keyData)^ := PDouble(AKey)^ + else + PDouble(keyData)^ := 0.0; +} + // set entry info + SetRecLowerPageNo(RecNo, LowerPageNo); + // flag we modified the page + FModified := true; + +{$ifdef TDBF_INDEX_CHECK} + + // check sorted entry sequence + prevKeyData := GetKeyDataFromEntry(FEntryNo-1); + curKeyData := GetKeyDataFromEntry(FEntryNo+0); + nextKeyData := GetKeyDataFromEntry(FEntryNo+1); + // check if prior entry not greater, 'rightmost' key does not have to match + if (FEntryNo > 0) and ((FLowerPage = nil) or (FEntryNo < FHighIndex)) then + begin + if FIndexFile.CompareKeys(prevKeyData, curKeyData) > 0 then + assert(false); + end; + // check if next entry not smaller + if ((FLowerPage = nil) and (FEntryNo < FHighIndex)) or + ((FLowerPage <> nil) and (FEntryNo < (FHighIndex - 1))) then + begin + if FIndexFile.CompareKeys(curKeyData, nextKeyData) > 0 then + assert(false); + end; + +{$endif} + +end; + +{$ifdef TDBF_UPDATE_FIRST_LAST_NODE} + +procedure TIndexPage.SetPrevBlock(NewBlock: Integer); +begin +end; + +{$endif} + +procedure TIndexPage.Split; + // *) assumes this page is `nearly' full +var + NewPage: TIndexPage; + source, dest: Pointer; + paKeyData: PChar; + size, oldEntryNo: Integer; + splitRight, lNumEntries, numEntriesNew: Integer; + saveLow, saveHigh: Integer; + newRoot: Boolean; +begin + // assure parent exists, if not -> create & lock, else lock it + newRoot := FUpperPage = nil; + if newRoot then + FIndexFile.AddNewLevel + else + FUpperPage.LockPage; + + // lock this page for updates + LockPage; + + // get num entries + lNumEntries := GetNumEntries; + + // calc split pos: split in half + splitRight := lNumEntries div 2; + if (FLowerPage <> nil) and (lNumEntries mod 2 = 1) then + inc(splitRight); + numEntriesNew := lNumEntries - splitRight; + // check if place to insert has least entries + if (numEntriesNew > splitRight) and (EntryNo > splitRight) then + begin + inc(splitRight); + dec(numEntriesNew); + end else if (numEntriesNew < splitRight) and (EntryNo < splitRight) then + begin + dec(splitRight); + inc(numEntriesNew); + end; + // save current entryno + oldEntryNo := EntryNo; + // check if we need to save high / low bound + if FLowPage = FPageNo then + saveLow := FLowIndex + else + saveLow := -1; + if FHighPage = FPageNo then + saveHigh := FHighIndex + else + saveHigh := -1; + + // create new page + NewPage := TIndexPageClass(ClassType).Create(FIndexFile); + try + // get page + NewPage.GetNewPage; +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + NewPage.SetPrevBlock(NewPage.PageNo - FIndexFile.PagesPerRecord); +{$endif} + + // set modified + FModified := true; + NewPage.FModified := true; + + // compute source, dest + dest := NewPage.GetEntry(0); + source := GetEntry(splitRight); + size := numEntriesNew * SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.KeyRecLen); + // if inner node, copy rightmost entry too + if FLowerPage <> nil then + size := size + FIndexFile.EntryHeaderSize; + // copy bytes + Move(source^, dest^, size); + // if not inner node, clear possible 'rightmost' entry + if (FLowerPage = nil) then + SetRecLowerPageNoOfEntry(splitRight, 0, 0); + + // calc new number of entries of this page + lNumEntries := lNumEntries - numEntriesNew; + // if lower level, then we need adjust for new 'rightmost' node + if FLowerPage <> nil then + begin + // right split, so we need 'new' rightmost node + dec(lNumEntries); + end; + // store new number of nodes + // new page is right page, so update parent to point to new right page + NewPage.SetNumEntries(numEntriesNew); + SetNumEntries(lNumEntries); + // update highindex + FHighIndex := lNumEntries; + if FLowerPage = nil then + dec(FHighIndex); + + // get data of last entry on this page + paKeyData := GetKeyDataFromEntry(splitRight - 1); + + // reinsert ourself into parent +// FUpperPage.RecurInsert(0, paKeyData, FPageNo); + // we can do this via a localinsert now: we know there is at least one entry + // free in this page and higher up + FUpperPage.LocalInsert(0, paKeyData, FPageNo); + + // new page is right page, so update parent to point to new right page + // we can't do this earlier: we will get lost in tree! + FUpperPage.SetRecLowerPageNoOfEntry(FUpperPage.EntryNo+1, 0, NewPage.PageNo); + + // NOTE: UpperPage.LowerPage = Self <= inserted FPageNo, not NewPage.PageNo + finally + NewPage.Free; + end; + + // done updating: unlock page + UnlockPage; + // save changes to parent + FUpperPage.UnlockPage; + + // unlock new root, unlock header too + FIndexFile.UnlockHeader; + + // go to entry we left on + if oldEntryNo >= splitRight then + begin + // sync upperpage with right page + FUpperPage.EntryNo := FUpperPage.EntryNo + 1; + FEntryNo := oldEntryNo - splitRight; + FEntry := GetEntry(FEntryNo); + end else begin + // in left page = this page + EntryNo := oldEntryNo; + end; + + // check if we have to save high / low bound + // seen the fact that FHighPage = FPageNo -> EntryNo <= FHighIndex, it can in + // theory not happen that page is advanced to right page and high bound remains + // on left page, but we won't check for that here + if saveLow >= splitRight then + begin + FLowPage := FPageNo; + FLowIndex := saveLow - splitRight; + end; + if saveHigh >= splitRight then + begin + FHighPage := FPageNo; + FHighIndex := saveHigh - splitRight; + end; +end; + +procedure TIndexPage.Delete; +begin + LocalDelete; +end; + +procedure TIndexPage.WritePage; +begin + // check if we modified current page + if FModified and (FPageNo > 0) then + begin + FIndexFile.WriteRecord(FPageNo, FPageBuffer); + FModified := false; + end; +end; + +procedure TIndexPage.Flush; +begin + WritePage; + if FLowerPage <> nil then + FLowerPage.Flush; +end; + +procedure TIndexPage.RecalcWeight; +begin + if FLowerPage <> nil then + begin + FWeight := FLowerPage.Weight * SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.NumKeys); + end else begin + FWeight := 1; + end; + if FUpperPage <> nil then + FUpperPage.RecalcWeight; +end; + +procedure TIndexPage.UpdateWeight; +begin + if FLowerPage <> nil then + FLowerPage.UpdateWeight + else + RecalcWeight; +end; + +procedure TIndexPage.SetUpperPage(NewPage: TIndexPage); +begin + if FUpperPage <> NewPage then + begin + // root height changed: update weights + FUpperPage := NewPage; + UpdateWeight; + end; +end; + +procedure TIndexPage.SetLowPage(NewPage: Integer); +begin + if FLowPage <> NewPage then + begin + FLowPage := NewPage; + UpdateBounds(FLowerPage <> nil); + end; +end; + +procedure TIndexPage.SetHighPage(NewPage: Integer); +begin + if FHighPage <> NewPage then + begin + FHighPage := NewPage; + UpdateBounds(FLowerPage <> nil); + end; +end; + +procedure TIndexPage.UpdateBounds(IsInnerNode: Boolean); +begin + // update low / high index range + if FPageNo = FLowPage then + FLowIndex := FLowBracket + else + FLowIndex := 0; + if FPageNo = FHighPage then + FHighIndex := FHighBracket + else begin + FHighIndex := GetNumEntries; + if not IsInnerNode then + dec(FHighIndex); + end; +end; + +function TMdxPage.GetIsInnerNode: Boolean; +begin + Result := SwapIntLE(PMdxPage(FPageBuffer)^.NumEntries) < SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.NumKeys); + // if there is still an entry after the last one, this has to be an inner node + if Result then + Result := PMdxEntry(GetEntry(PMdxPage(FPageBuffer)^.NumEntries))^.RecBlockNo <> 0; +end; + +function TNdxPage.GetIsInnerNode: Boolean; +begin + Result := PNdxEntry(GetEntry(0))^.LowerPageNo <> 0; +end; + +procedure TIndexPage.SetPageNo(NewPageNo: Integer); +var + isInnerNode: Boolean; +begin + if (NewPageNo <> FPageNo) or FIndexFile.NeedLocks then + begin + // save changes + WritePage; + // no locks + assert(FLockCount = 0); + + // goto new page + FPageNo := NewPageNo; + // remind ourselves we need to load new entry when page loaded + FEntryNo := -1; + if (NewPageNo > 0) and (NewPageNo <= FIndexFile.RecordCount) then + begin + // read page from disk + FIndexFile.ReadRecord(NewPageNo, FPageBuffer); + + // fixup descending tree + isInnerNode := GetIsInnerNode; + + // update low / high index range + UpdateBounds(isInnerNode); + + // read inner node if any + if isInnerNode then + begin + if FLowerPage = nil then + begin + FLowerPage := TIndexPageClass(ClassType).Create(FIndexFile); + FLowerPage.UpperPage := Self; + end; + // read first entry, don't do this sooner, not created lowerpage yet + // don't recursively resync all lower pages +{$ifdef TDBF_INDEX_CHECK} + end else if FLowerPage <> nil then + begin +// FLowerPage.Free; +// FLowerPage := nil; + assert(false); +{$endif} + end else begin + // we don't have to check autoresync here because we're already at lowest level + EntryNo := FLowIndex; + end; + end; + end; +end; + +procedure TIndexPage.SyncLowerPage; + // *) assumes FLowerPage <> nil! +begin + FLowerPage.PageNo := GetLowerPageNo; +end; + +procedure TIndexPage.SetEntryNo(value: Integer); +begin + // do not bother if no change + if value <> FEntryNo then + begin + // check if out of range + if (value < FLowIndex) then + begin + if FLowerPage = nil then + FEntryNo := FLowIndex - 1; + FEntry := FIndexFile.EntryBof; + end else if value > FHighIndex then begin + FEntryNo := FHighIndex + 1; + FEntry := FIndexFile.EntryEof; + end else begin + FEntryNo := value; + FEntry := GetEntry(value); + // sync lowerpage with entry + if (FLowerPage <> nil) then + SyncLowerPage; + end; + end; +end; + +function TIndexPage.PhysicalRecNo: Integer; +var + entryRec: Integer; +begin + // get num entries + entryRec := GetRecNo; + // check if in range + if (FEntryNo >= FLowIndex) and (FEntryNo <= FHighIndex) then + Result := entryRec + else + Result := -1; +end; + +function TIndexPage.RecurPrev: Boolean; +begin + EntryNo := EntryNo - 1; + Result := Entry <> FIndexFile.EntryBof; + if Result then + begin + if FLowerPage <> nil then + begin + FLowerPage.RecurLast; + end; + end else begin + if FUpperPage<>nil then + begin + Result := FUpperPage.RecurPrev; + end; + end; +end; + +function TIndexPage.RecurNext: Boolean; +begin + EntryNo := EntryNo + 1; + Result := Entry <> FIndexFile.EntryEof; + if Result then + begin + if FLowerPage <> nil then + begin + FLowerPage.RecurFirst; + end; + end else begin + if FUpperPage<>nil then + begin + Result := FUpperPage.RecurNext; + end; + end; +end; + +procedure TIndexPage.RecurFirst; +begin + EntryNo := FLowIndex; + if (FLowerPage<>nil) then + FLowerPage.RecurFirst; +end; + +procedure TIndexPage.RecurLast; +begin + EntryNo := FHighIndex; + if (FLowerPage<>nil) then + FLowerPage.RecurLast; +end; + +procedure TIndexPage.SaveBracket; +begin + FLowPageTemp := FLowPage; + FHighPageTemp := FHighPage; +end; + +procedure TIndexPage.RestoreBracket; +begin + FLowPage := FLowPageTemp; + FHighPage := FHighPageTemp; +end; + +//============================================================================== +//============ Mdx specific access routines +//============================================================================== + +function TMdxPage.GetEntry(AEntryNo: Integer): Pointer; +begin + // get base + offset + Result := PChar(@PMdxPage(PageBuffer)^.FirstEntry) + (SwapWordLE(PIndexHdr( + IndexFile.IndexHeader)^.KeyRecLen) * AEntryNo); +end; + +function TMdxPage.GetLowerPageNo: Integer; + // *) assumes LowerPage <> nil +begin +// if LowerPage = nil then +// Result := 0 +// else + Result := SwapIntLE(PMdxEntry(Entry)^.RecBlockNo); +end; + +function TMdxPage.GetKeyData: PChar; +begin + Result := @PMdxEntry(Entry)^.KeyData; +end; + +function TMdxPage.GetNumEntries: Integer; +begin + Result := SwapWordLE(PMdxPage(PageBuffer)^.NumEntries); +end; + +function TMdxPage.GetKeyDataFromEntry(AEntry: Integer): PChar; +begin + Result := @PMdxEntry(GetEntry(AEntry))^.KeyData; +end; + +function TMdxPage.GetRecNo: Integer; +begin + Result := SwapIntLE(PMdxEntry(Entry)^.RecBlockNo); +end; + +procedure TMdxPage.SetNumEntries(NewNum: Integer); +begin + PMdxPage(PageBuffer)^.NumEntries := SwapIntLE(NewNum); +end; + +procedure TMdxPage.IncNumEntries; +begin + IncIntLE(PMdxPage(PageBuffer)^.NumEntries, 1); +end; + +procedure TMdxPage.SetRecLowerPageNo(NewRecNo, NewPageNo: Integer); +begin + if FLowerPage = nil then + PMdxEntry(Entry)^.RecBlockNo := SwapIntLE(NewRecNo) + else + PMdxEntry(Entry)^.RecBlockNo := SwapIntLE(NewPageNo); +end; + +procedure TMdxPage.SetRecLowerPageNoOfEntry(AEntry, NewRecNo, NewPageNo: Integer); +begin + if FLowerPage = nil then + PMdxEntry(GetEntry(AEntry))^.RecBlockNo := SwapIntLE(NewRecNo) + else + PMdxEntry(GetEntry(AEntry))^.RecBlockNo := SwapIntLE(NewPageNo); +end; + +{$ifdef TDBF_UPDATE_FIRST_LAST_NODE} + +procedure TMdxPage.SetPrevBlock(NewBlock: Integer); +begin + PMdxPage(PageBuffer)^.PrevBlock := SwapIntLE(NewBlock); +end; + +{$endif} + +//============================================================================== +//============ Ndx specific access routines +//============================================================================== + +function TNdxPage.GetEntry(AEntryNo: Integer): Pointer; +begin + // get base + offset + Result := PChar(@PNdxPage(PageBuffer)^.FirstEntry) + + (SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.KeyRecLen) * AEntryNo); +end; + +function TNdxPage.GetLowerPageNo: Integer; + // *) assumes LowerPage <> nil +begin +// if LowerPage = nil then +// Result := 0 +// else + Result := SwapIntLE(PNdxEntry(Entry)^.LowerPageNo) +end; + +function TNdxPage.GetRecNo: Integer; +begin + Result := SwapIntLE(PNdxEntry(Entry)^.RecNo); +end; + +function TNdxPage.GetKeyData: PChar; +begin + Result := @PNdxEntry(Entry)^.KeyData; +end; + +function TNdxPage.GetKeyDataFromEntry(AEntry: Integer): PChar; +begin + Result := @PNdxEntry(GetEntry(AEntry))^.KeyData; +end; + +function TNdxPage.GetNumEntries: Integer; +begin + Result := SwapIntLE(PNdxPage(PageBuffer)^.NumEntries); +end; + +procedure TNdxPage.IncNumEntries; +begin + IncIntLE(PNdxPage(PageBuffer)^.NumEntries, 1); +end; + +procedure TNdxPage.SetNumEntries(NewNum: Integer); +begin + PNdxPage(PageBuffer)^.NumEntries := SwapIntLE(NewNum); +end; + +procedure TNdxPage.SetRecLowerPageNo(NewRecNo, NewPageNo: Integer); +begin + PNdxEntry(Entry)^.RecNo := SwapIntLE(NewRecNo); + PNdxEntry(Entry)^.LowerPageNo := SwapIntLE(NewPageNo); +end; + +procedure TNdxPage.SetRecLowerPageNoOfEntry(AEntry, NewRecNo, NewPageNo: Integer); +begin + PNdxEntry(GetEntry(AEntry))^.RecNo := SwapIntLE(NewRecNo); + PNdxEntry(GetEntry(AEntry))^.LowerPageNo := SwapIntLE(NewPageNo); +end; + +//============================================================================== +//============ MDX version 4 header access routines +//============================================================================== + +function TMdx4Tag.GetHeaderPageNo: Integer; +begin + Result := SwapIntLE(PMdx4Tag(Tag)^.HeaderPageNo); +end; + +function TMdx4Tag.GetTagName: string; +begin + Result := PMdx4Tag(Tag)^.TagName; +end; + +function TMdx4Tag.GetKeyFormat: Byte; +begin + Result := PMdx4Tag(Tag)^.KeyFormat; +end; + +function TMdx4Tag.GetForwardTag1: Byte; +begin + Result := PMdx4Tag(Tag)^.ForwardTag1; +end; + +function TMdx4Tag.GetForwardTag2: Byte; +begin + Result := PMdx4Tag(Tag)^.ForwardTag2; +end; + +function TMdx4Tag.GetBackwardTag: Byte; +begin + Result := PMdx4Tag(Tag)^.BackwardTag; +end; + +function TMdx4Tag.GetReserved: Byte; +begin + Result := PMdx4Tag(Tag)^.Reserved; +end; + +function TMdx4Tag.GetKeyType: Char; +begin + Result := PMdx4Tag(Tag)^.KeyType; +end; + +procedure TMdx4Tag.SetHeaderPageNo(NewPageNo: Integer); +begin + PMdx4Tag(Tag)^.HeaderPageNo := SwapIntLE(NewPageNo); +end; + +procedure TMdx4Tag.SetTagName(NewName: string); +begin + StrPLCopy(PMdx4Tag(Tag)^.TagName, NewName, 10); + PMdx4Tag(Tag)^.TagName[10] := #0; +end; + +procedure TMdx4Tag.SetKeyFormat(NewFormat: Byte); +begin + PMdx4Tag(Tag)^.KeyFormat := NewFormat; +end; + +procedure TMdx4Tag.SetForwardTag1(NewTag: Byte); +begin + PMdx4Tag(Tag)^.ForwardTag1 := NewTag; +end; + +procedure TMdx4Tag.SetForwardTag2(NewTag: Byte); +begin + PMdx4Tag(Tag)^.ForwardTag2 := NewTag; +end; + +procedure TMdx4Tag.SetBackwardTag(NewTag: Byte); +begin + PMdx4Tag(Tag)^.BackwardTag := NewTag; +end; + +procedure TMdx4Tag.SetReserved(NewReserved: Byte); +begin + PMdx4Tag(Tag)^.Reserved := NewReserved; +end; + +procedure TMdx4Tag.SetKeyType(NewType: Char); +begin + PMdx4Tag(Tag)^.KeyType := NewType; +end; + +//============================================================================== +//============ MDX version 7 headertag access routines +//============================================================================== + +function TMdx7Tag.GetHeaderPageNo: Integer; +begin + Result := SwapIntLE(PMdx7Tag(Tag)^.HeaderPageNo); +end; + +function TMdx7Tag.GetTagName: string; +begin + Result := PMdx7Tag(Tag)^.TagName; +end; + +function TMdx7Tag.GetKeyFormat: Byte; +begin + Result := PMdx7Tag(Tag)^.KeyFormat; +end; + +function TMdx7Tag.GetForwardTag1: Byte; +begin + Result := PMdx7Tag(Tag)^.ForwardTag1; +end; + +function TMdx7Tag.GetForwardTag2: Byte; +begin + Result := PMdx7Tag(Tag)^.ForwardTag2; +end; + +function TMdx7Tag.GetBackwardTag: Byte; +begin + Result := PMdx7Tag(Tag)^.BackwardTag; +end; + +function TMdx7Tag.GetReserved: Byte; +begin + Result := PMdx7Tag(Tag)^.Reserved; +end; + +function TMdx7Tag.GetKeyType: Char; +begin + Result := PMdx7Tag(Tag)^.KeyType; +end; + +procedure TMdx7Tag.SetHeaderPageNo(NewPageNo: Integer); +begin + PMdx7Tag(Tag)^.HeaderPageNo := SwapIntLE(NewPageNo); +end; + +procedure TMdx7Tag.SetTagName(NewName: string); +begin + StrPLCopy(PMdx7Tag(Tag)^.TagName, NewName, 32); + PMdx7Tag(Tag)^.TagName[32] := #0; +end; + +procedure TMdx7Tag.SetKeyFormat(NewFormat: Byte); +begin + PMdx7Tag(Tag)^.KeyFormat := NewFormat; +end; + +procedure TMdx7Tag.SetForwardTag1(NewTag: Byte); +begin + PMdx7Tag(Tag)^.ForwardTag1 := NewTag; +end; + +procedure TMdx7Tag.SetForwardTag2(NewTag: Byte); +begin + PMdx7Tag(Tag)^.ForwardTag2 := NewTag; +end; + +procedure TMdx7Tag.SetBackwardTag(NewTag: Byte); +begin + PMdx7Tag(Tag)^.BackwardTag := NewTag; +end; + +procedure TMdx7Tag.SetReserved(NewReserved: Byte); +begin + PMdx7Tag(Tag)^.Reserved := NewReserved; +end; + +procedure TMdx7Tag.SetKeyType(NewType: Char); +begin + PMdx7Tag(Tag)^.KeyType := NewType; +end; + +{ TDbfIndexParser } + +procedure TDbfIndexParser.ValidateExpression(AExpression: string); +const + AnsiStrFuncs: array[0..13] of TExprFunc = (FuncUppercase, FuncLowercase, FuncStrI_EQ, + FuncStrIP_EQ, FuncStrI_NEQ, FuncStrI_LT, FuncStrI_GT, FuncStrI_LTE, FuncStrI_GTE, + FuncStrP_EQ, FuncStr_LT, FuncStr_GT, FuncStr_LTE, FuncStr_GTE); + AnsiFuncsToMode: array[boolean] of TStringFieldMode = (smRaw, smAnsi); +var + TempRec: PExpressionRec; + TempBuffer: TRecordBuffer; + I: integer; + hasAnsiFuncs: boolean; +begin + TempRec := CurrentRec; + hasAnsiFuncs := false; + while not hasAnsiFuncs and (TempRec <> nil) do + begin + for I := Low(AnsiStrFuncs) to High(AnsiStrFuncs) do + if @TempRec^.Oper = @AnsiStrFuncs[I] then + begin + hasAnsiFuncs := true; + break; + end; + TempRec := TempRec^.Next; + end; + + StringFieldMode := AnsiFuncsToMode[hasAnsiFuncs]; + + FResultLen := inherited ResultLen; + + if FResultLen = -1 then + begin + // make empty record + GetMem(TempBuffer, TDbfFile(DbfFile).RecordSize); + try + TDbfFile(DbfFile).InitRecord(TempBuffer); + FResultLen := StrLen(ExtractFromBuffer(TempBuffer)); + finally + FreeMem(TempBuffer); + end; + end; + + // check if expression not too long + if FResultLen > 100 then + raise EDbfError.CreateFmt(STRING_INDEX_EXPRESSION_TOO_LONG, [AExpression, FResultLen]); +end; + +//============================================================================== +//============ TIndexFile +//============================================================================== +constructor TIndexFile.Create(ADbfFile: Pointer); +var + I: Integer; +begin + inherited Create; + + // clear variables + FOpened := false; + FRangeActive := false; + FUpdateMode := umCurrent; + FModifyMode := mmNormal; + FTempMode := TDbfFile(ADbfFile).TempMode; + FRangeIndex := -1; + SelectIndexVars(-1); + for I := 0 to MaxIndexes - 1 do + begin + FParsers[I] := nil; + FRoots[I] := nil; + FLeaves[I] := nil; + FIndexHeaderModified[I] := false; + end; + + // store pointer to `parent' dbf file + FDbfFile := ADbfFile; +end; + +destructor TIndexFile.Destroy; +begin + // close file + Close; + + // call ancestor + inherited Destroy; +end; + +procedure TIndexFile.Open; +var + I: Integer; + ext: string; + localeError: TLocaleError; + localeSolution: TLocaleSolution; + DbfLangId: Byte; +begin + if not FOpened then + begin + // open physical file + OpenFile; + + // page offsets are not related to header length + PageOffsetByHeader := false; + // we need physical page locks + VirtualLocks := false; + + // not selected index expression => can't edit yet + FCanEdit := false; + FUserKey := nil; + FUserRecNo := -1; + FHeaderLocked := -1; + FHeaderPageNo := 0; + FForceClose := false; + FForceReadOnly := false; + FMdxTag := nil; + + // get index type + ext := UpperCase(ExtractFileExt(FileName)); + if (ext = '.MDX') then + begin + FEntryHeaderSize := 4; + FPageHeaderSize := 8; + FEntryBof := @Entry_Mdx_BOF; + FEntryEof := @Entry_Mdx_EOF; + HeaderSize := 2048; + RecordSize := 1024; + PageSize := 512; + if FileCreated then + begin + FIndexVersion := TDbfFile(FDbfFile).DbfVersion; + if FIndexVersion = xBaseIII then + FIndexVersion := xBaseIV; + end else begin + case PMdxHdr(Header)^.MdxVersion of + 3: FIndexVersion := xBaseVII; + else + FIndexVersion := xBaseIV; + end; + end; + case FIndexVersion of + xBaseVII: + begin + FMdxTag := TMdx7Tag.Create; + FTempMdxTag := TMdx7Tag.Create; + end; + else + FMdxTag := TMdx4Tag.Create; + FTempMdxTag := TMdx4Tag.Create; + end; + // get mem for all index headers..we're going to cache these + for I := 0 to MaxIndexes - 1 do + begin + GetMem(FIndexHeaders[I], RecordSize); + FillChar(FIndexHeaders[I]^, RecordSize, 0); + end; + // set pointers to first index + FIndexHeader := FIndexHeaders[0]; + end else begin + // don't waste memory on another header block: we can just use + // the pagedfile one, there is only one index in this file + FIndexVersion := xBaseIII; + FEntryHeaderSize := 8; + FPageHeaderSize := 4; + FEntryBof := @Entry_Ndx_BOF; + FEntryEof := @Entry_Ndx_EOF; + HeaderSize := 512; + RecordSize := 512; + // have to read header first before we can assign following vars + FIndexHeaders[0] := Header; + FIndexHeader := Header; + // create default root + FParsers[0] := TDbfIndexParser.Create(FDbfFile); + FRoots[0] := TNdxPage.Create(Self); + FCurrentParser := FParsers[0]; + FRoot := FRoots[0]; + FSelectedIndex := 0; + // parse index expression + FCurrentParser.ParseExpression(PIndexHdr(FIndexHeader)^.KeyDesc); + // set index locale + FCollation := BINARY_COLLATION; + end; + + // determine how to open file + if FileCreated then + begin + FillChar(Header^, HeaderSize, 0); + Clear; + end else begin + // determine locale type + localeError := leNone; + if (FIndexVersion >= xBaseIV) then + begin + // get parent language id + DbfLangId := GetDbfLanguageId; + // no ID? + if (DbfLangId = 0) { and (TDbfFile(FDbfFile).DbfVersion = xBaseIII)} then + begin + // if dbf is version 3, no language id, if no MDX language, use binary + if PMdxHdr(Header)^.Language = 0 then + FCollation := BINARY_COLLATION + else + FCollation := GetCollationTable(PMdxHdr(Header)^.Language); + end else begin + // check if MDX - DBF language id's match + if (PMdxHdr(Header)^.Language = 0) or (PMdxHdr(Header)^.Language = DbfLangId) then + FCollation := GetCollationTable(DbfLangId) + else + localeError := leTableIndexMismatch; + end; + // don't overwrite previous error + if (FCollation = UNKNOWN_COLLATION) and (localeError = leNone) then + localeError := leUnknown; + end else begin + // dbase III always binary? + FCollation := BINARY_COLLATION; + end; + // check if selected locale is available, binary is always available... + if (localeError <> leNone) and (FCollation <> BINARY_COLLATION) then + begin + if LCIDList.IndexOf(Pointer(FCollation)) < 0 then + localeError := leNotAvailable; + end; + // check if locale error detected + if localeError <> leNone then + begin + // provide solution, well, solution... + localeSolution := lsNotOpen; + // call error handler + if Assigned(FOnLocaleError) then + FOnLocaleError(localeError, localeSolution); + // act to solution + case localeSolution of + lsNotOpen: FForceClose := true; + lsNoEdit: FForceReadOnly := true; + else + { lsBinary } + FCollation := BINARY_COLLATION; + end; + end; + // now read info + if not ForceClose then + ReadIndexes; + end; + // default to update all + UpdateMode := umAll; + // flag open + FOpened := true; + end; +end; + +procedure TIndexFile.Close; +var + I: Integer; +begin + if FOpened then + begin + // save headers + Flush; + + // remove parser reference + FCurrentParser := nil; + + // free roots + if FIndexVersion >= xBaseIV then + begin + for I := 0 to MaxIndexes - 1 do + begin + FreeMemAndNil(FIndexHeaders[I]); + FreeAndNil(FParsers[I]); + FreeAndNil(FRoots[I]); + end; + end else begin + FreeAndNil(FRoot); + end; + + // free mem + FMdxTag.Free; + FTempMdxTag.Free; + + // close physical file + CloseFile; + + // not opened any more + FOpened := false; + end; +end; + +procedure TIndexFile.ClearRoots; + // + // *) assumes FIndexVersion >= xBaseIV + // +var + I, prevIndex: Integer; +begin + prevIndex := FSelectedIndex; + for I := 0 to MaxIndexes - 1 do + begin + SelectIndexVars(I); + if FRoot <> nil then + begin + // clear this entry + ClearIndex; + FLeaves[I] := FRoots[I]; + end; + end; + // reselect previously selected index + SelectIndexVars(prevIndex); + // deselect index +end; + +procedure WriteDBFileName(Header: PMdxHdr; HdrFileName: string); +var + HdrFileExt: string; + lPos, lenFileName: integer; +begin + HdrFileName := ExtractFileName(HdrFileName); + HdrFileExt := ExtractFileExt(HdrFileName); + if Length(HdrFileExt) > 0 then + begin + lPos := System.Pos(HdrFileExt, HdrFileName); + if lPos > 0 then + SetLength(HdrFileName, lPos - 1); + end; + if Length(HdrFileName) > 15 then + SetLength(HdrFileName, 15); + lenFileName := Length(HdrFileName); + Move(PChar(HdrFileName)^, PMdxHdr(Header)^.FileName[0], lenFileName); + FillChar(PMdxHdr(Header)^.FileName[lenFileName], 15-lenFileName, 0); +end; + +procedure TIndexFile.Clear; +var + year, month, day: Word; + pos, prevSelIndex, pageno: Integer; + DbfLangId: Byte; +begin + // flush cache to prevent reading corrupted data + Flush; + // completely erase index + if FIndexVersion >= xBaseIV then + begin + DecodeDate(Now, year, month, day); + if FIndexVersion = xBaseVII then + PMdxHdr(Header)^.MdxVersion := 3 + else + PMdxHdr(Header)^.MdxVersion := 2; + PMdxHdr(Header)^.Year := year - 1900; + PMdxHdr(Header)^.Month := month; + PMdxHdr(Header)^.Day := day; + WriteDBFileName(PMdxHdr(Header), FileName); + PMdxHdr(Header)^.BlockSize := SwapWordLE(2); + PMdxHdr(Header)^.BlockAdder := SwapWordLE(1024); + PMdxHdr(Header)^.ProdFlag := 1; + PMdxHdr(Header)^.NumTags := 48; + PMdxHdr(Header)^.TagSize := 32; + PMdxHdr(Header)^.Dummy2 := 0; + PMdxHdr(Header)^.Language := GetDbfLanguageID; + PMdxHdr(Header)^.NumPages := SwapIntLE(HeaderSize div PageSize); // = 4 + TouchHeader(Header); + PMdxHdr(Header)^.TagFlag := 1; + // use locale id of parent + DbfLangId := GetDbfLanguageId; + if DbfLangId = 0 then + FCollation := BINARY_COLLATION + else + FCollation := GetCollationTable(DbfLangId); + // write index headers + prevSelIndex := FSelectedIndex; + for pos := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + SelectIndexVars(pos); + pageno := GetNewPageNo; + FMdxTag.HeaderPageNo := SwapIntLE(pageno); + WriteRecord(pageno, FIndexHeader); + end; + // reselect previously selected index + SelectIndexVars(prevSelIndex); + // file header done (tags are included in file header) + WriteFileHeader; + // clear roots + ClearRoots; + // init vars + FTagSize := 32; + FTagOffset := 544; + // clear entries + RecordCount := SwapIntLE(PMdxHdr(Header)^.NumPages); + end else begin + // clear single index entry + ClearIndex; + RecordCount := SwapIntLE(PIndexHdr(FIndexHeader)^.NumPages); + end; +end; + +procedure TIndexFile.ClearIndex; +var + prevHeaderLocked: Integer; + needHeaderLock: Boolean; +begin + // flush cache to prevent reading corrupted data + Flush; + // modifying header: lock page + needHeaderLock := FHeaderLocked <> 0; + prevHeaderLocked := FHeaderLocked; + if needHeaderLock then + begin + LockPage(0, true); + FHeaderLocked := 0; + end; + // initially, we have 1 page: header + PIndexHdr(FIndexHeader)^.NumPages := SwapIntLE(HeaderSize div PageSize); + // clear memory of root + FRoot.Clear; + // get new page for root + FRoot.GetNewPage; + // store new root page + PIndexHdr(FIndexHeader)^.RootPage := SwapIntLE(FRoot.PageNo); +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + PIndexHdr(FIndexHeader)^.FirstNode := SwapIntLE(FRoot.PageNo); +{$endif} + // update leaf pointers + FLeaves[FSelectedIndex] := FRoot; + FLeaf := FRoot; + // write new header + WriteHeader; + FRoot.Modified; + FRoot.WritePage; + // done updating: unlock header + if needHeaderLock then + begin + UnlockPage(0); + FHeaderLocked := prevHeaderLocked; + end; +end; + +procedure TIndexFile.CalcKeyProperties; + // given KeyLen, this func calcs KeyRecLen and NumEntries +begin + // now adjust keylen to align on DWORD boundaries + PIndexHdr(FIndexHeader)^.KeyRecLen := SwapWordLE((SwapWordLE( + PIndexHdr(FIndexHeader)^.KeyLen) + FEntryHeaderSize + 3) and not 3); + PIndexHdr(FIndexHeader)^.NumKeys := SwapWordLE((RecordSize - FPageHeaderSize) div + SwapWordLE(PIndexHdr(FIndexHeader)^.KeyRecLen)); +end; + +function TIndexFile.GetName: string; +begin + // get suitable name of index: if tag name defined use that otherwise filename + if FIndexVersion >= xBaseIV then + Result := FIndexName + else + Result := FileName; +end; + +procedure TIndexFile.CreateIndex(FieldDesc, TagName: string; Options: TIndexOptions); +var + tagNo: Integer; + fieldType: Char; + TempParser: TDbfIndexParser; +begin + // check if we have exclusive access to table + TDbfFile(FDbfFile).CheckExclusiveAccess; + // parse index expression; if it cannot be parsed, why bother making index? + TempParser := TDbfIndexParser.Create(FDbfFile); + try + TempParser.ParseExpression(FieldDesc); + // check if result type is correct + fieldType := 'C'; + case TempParser.ResultType of + etString: ; { default set above to suppress delphi warning } + etInteger, etLargeInt, etFloat: fieldType := 'N'; + else + raise EDbfError.Create(STRING_INVALID_INDEX_TYPE); + end; + finally + TempParser.Free; + end; + // select empty index + if FIndexVersion >= xBaseIV then + begin + // get next entry no + tagNo := SwapWordLE(PMdxHdr(Header)^.TagsUsed); + // check if too many indexes + if tagNo = MaxIndexes then + raise EDbfError.Create(STRING_TOO_MANY_INDEXES); + // get memory for root + if FRoots[tagNo] = nil then + begin + FParsers[tagNo] := TDbfIndexParser.Create(FDbfFile); + FRoots[tagNo] := TMdxPage.Create(Self) + end else begin + FreeAndNil(FRoots[tagNo].FLowerPage); + end; + // set leaves pointer + FLeaves[tagNo] := FRoots[tagNo]; + // get pointer to index header + FIndexHeader := FIndexHeaders[tagNo]; + // load root + leaf + FCurrentParser := FParsers[tagNo]; + FRoot := FRoots[tagNo]; + FLeaf := FLeaves[tagNo]; + // create new tag + FTempMdxTag.Tag := CalcTagOffset(tagNo); + FTempMdxTag.TagName := UpperCase(TagName); + // if expression then calculate + FTempMdxTag.KeyFormat := KeyFormat_Data; + if ixExpression in Options then + FTempMdxTag.KeyFormat := KeyFormat_Expression; + // what use have these reference tags? + FTempMdxTag.ForwardTag1 := 0; + FTempMdxTag.ForwardTag2 := 0; + FTempMdxTag.BackwardTag := 0; + FTempMdxTag.Reserved := 2; + FTempMdxTag.KeyType := fieldType; + // save this part of tag, need to save before GetNewPageNo, + // it will reread header + WriteFileHeader; + // store selected index + FSelectedIndex := tagNo; + FIndexName := TagName; + // store new headerno + FHeaderPageNo := GetNewPageNo; + FTempMdxTag.HeaderPageNo := FHeaderPageNo; + // increase number of indexes active + IncWordLE(PMdxHdr(Header)^.TagsUsed, 1); + // update updatemode + UpdateMode := umAll; + // index header updated + WriteFileHeader; + end; + // clear index + ClearIndex; + + // parse expression, we know it's parseable, we've checked that + FCurrentParser.ParseExpression(FieldDesc); + + // looked up index expression: now we can edit +// FIsExpression := ixExpression in Options; + FCanEdit := not FForceReadOnly; + + // init key variables + PIndexHdr(FIndexHeader)^.KeyFormat := 0; + // descending + if ixDescending in Options then + PIndexHdr(FIndexHeader)^.KeyFormat := PIndexHdr(FIndexHeader)^.KeyFormat or KeyFormat_Descending; + // key type + if fieldType = 'C' then + PIndexHdr(FIndexHeader)^.KeyFormat := PIndexHdr(FIndexHeader)^.KeyFormat or KeyFormat_String; + PIndexHdr(FIndexHeader)^.KeyType := fieldType; + // uniqueness + PIndexHdr(FIndexHeader)^.Unique := Unique_None; + if ixPrimary in Options then + begin + PIndexHdr(FIndexHeader)^.KeyFormat := PIndexHdr(FIndexHeader)^.KeyFormat or KeyFormat_Distinct or KeyFormat_Unique; + PIndexHdr(FIndexHeader)^.Unique := Unique_Distinct; + end else if ixUnique in Options then + begin + PIndexHdr(FIndexHeader)^.KeyFormat := PIndexHdr(FIndexHeader)^.KeyFormat or KeyFormat_Unique; + PIndexHdr(FIndexHeader)^.Unique := Unique_Unique; + end; + // keylen is exact length of field + if fieldType = 'C' then + PIndexHdr(FIndexHeader)^.KeyLen := SwapWordLE(FCurrentParser.ResultLen) + else if FIndexVersion >= xBaseIV then + PIndexHdr(FIndexHeader)^.KeyLen := SwapWordLE(12) + else + PIndexHdr(FIndexHeader)^.KeyLen := SwapWordLE(8); + CalcKeyProperties; + // key desc + StrPLCopy(PIndexHdr(FIndexHeader)^.KeyDesc, FieldDesc, 219); + PIndexHdr(FIndexHeader)^.KeyDesc[219] := #0; + + // init various + if FIndexVersion >= xBaseIV then + PIndexHdr(FIndexHeader)^.Dummy := 0 // MDX -> language driver + else + PIndexHdr(FIndexHeader)^.Dummy := SwapWordLE($5800); // NDX -> same ??? + case fieldType of + 'C': + PIndexHdr(FIndexHeader)^.sKeyType := 0; + 'D': + PIndexHdr(FIndexHeader)^.sKeyType := SwapWordLE(1); + 'N', 'F': + if FIndexVersion >= xBaseIV then + PIndexHdr(FIndexHeader)^.sKeyType := 0 + else + PIndexHdr(FIndexHeader)^.sKeyType := SwapWordLE(1); + else + PIndexHdr(FIndexHeader)^.sKeyType := 0; + end; + + PIndexHdr(FIndexHeader)^.Version := SwapWordLE(2); // this is what DB4 writes into file + PIndexHdr(FIndexHeader)^.Dummy2 := 0; + PIndexHdr(FIndexHeader)^.Dummy3 := 0; + PIndexHdr(FIndexHeader)^.ForExist := 0; // false + PIndexHdr(FIndexHeader)^.KeyExist := 1; // true +{$ifndef TDBF_UPDATE_FIRSTLAST_NODE} + // if not defined, init to zero + PIndexHdr(FIndexHeader)^.FirstNode := 0; + PIndexHdr(FIndexHeader)^.LastNode := 0; +{$endif} + WriteHeader; + + // update internal properties + UpdateIndexProperties; + + // for searches / inserts / deletes + FKeyBuffer[SwapWordLE(PIndexHdr(FIndexHeader)^.KeyLen)] := #0; +end; + +procedure TIndexFile.ReadIndexes; +var + I: Integer; + + procedure CheckHeaderIntegrity; + begin + if integer(SwapWordLE(PIndexHdr(FIndexHeader)^.NumKeys) * + SwapWordLE(PIndexHdr(FIndexHeader)^.KeyRecLen)) > RecordSize then + begin + // adjust index header so that integrity is correct + // WARNING: we can't be sure this gives a correct result, but at + // least we won't AV (as easily). user will probably have to regenerate this index + if SwapWordLE(PIndexHdr(FIndexHeader)^.KeyLen) > 100 then + PIndexHdr(FIndexHeader)^.KeyLen := SwapWordLE(100); + CalcKeyProperties; + end; + end; + +begin + // force header reread + inherited ReadHeader; + // examine all indexes + if FIndexVersion >= xBaseIV then + begin + // clear all roots + ClearRoots; + // tags are extended at beginning? tagsize is byte sized + FTagSize := PMdxHdr(Header)^.TagSize; + FTagOffset := 544 + FTagSize - 32; + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + // read page header + FTempMdxTag.Tag := CalcTagOffset(I); + ReadRecord(FTempMdxTag.HeaderPageNo, FIndexHeaders[I]); + // select it + FIndexHeader := FIndexHeaders[I]; + // create root if needed + if FRoots[I] = nil then + begin + FParsers[I] := TDbfIndexParser.Create(FDbfFile); + FRoots[I] := TMdxPage.Create(Self); + end; + // check header integrity + CheckHeaderIntegrity; + // read tree + FRoots[I].PageNo := SwapIntLE(PIndexHdr(FIndexHeader)^.RootPage); + // go to first record + FRoots[I].RecurFirst; + // store leaf + FLeaves[I] := FRoots[I]; + while FLeaves[I].LowerPage <> nil do + FLeaves[I] := FLeaves[I].LowerPage; + // parse expression + FParsers[I].ParseExpression(PIndexHdr(FIndexHeader)^.KeyDesc); + end; + end else begin + // clear root + FRoot.Clear; + // check recordsize constraint + CheckHeaderIntegrity; + // just one index: read tree + FRoot.PageNo := SwapIntLE(PIndexHdr(FIndexHeader)^.RootPage); + // go to first valid record + FRoot.RecurFirst; + // get leaf page + FLeaf := FRoot; + while FLeaf.LowerPage <> nil do + FLeaf := FLeaf.LowerPage; + // write leaf pointer to first index + FLeaves[0] := FLeaf; + // get index properties -> internal props + UpdateIndexProperties; + end; +end; + +procedure TIndexFile.DeleteIndex(const AIndexName: string); +var + I, found, numTags, moveItems: Integer; + tempHeader: Pointer; + tempRoot, tempLeaf: TIndexPage; + tempParser: TDbfIndexParser; +begin + // check if we have exclusive access to table + TDbfFile(FDbfFile).CheckExclusiveAccess; + if FIndexVersion = xBaseIII then + begin + Close; + DeleteFile; + end else if FIndexVersion >= xBaseIV then + begin + // find index + found := IndexOf(AIndexName); + if found >= 0 then + begin + // just remove this tag by copying memory over it + numTags := SwapWordLE(PMdxHdr(Header)^.TagsUsed); + moveItems := numTags - found - 1; + // anything to move? + if moveItems > 0 then + begin + // move entries after found one + Move((Header + FTagOffset + (found+1) * FTagSize)^, + (Header + FTagOffset + found * FTagSize)^, moveItems * FTagSize); + // nullify last entry + FillChar((Header + FTagOffset + numTags * FTagSize)^, FTagSize, 0); + // index headers, roots, leaves + tempHeader := FIndexHeaders[found]; + tempParser := FParsers[found]; + tempRoot := FRoots[found]; + tempLeaf := FLeaves[found]; + for I := 0 to moveItems - 1 do + begin + FIndexHeaders[found + I] := FIndexHeaders[found + I + 1]; + FParsers[found + I] := FParsers[found + I + 1]; + FRoots[found + I] := FRoots[found + I + 1]; + FLeaves[found + I] := FLeaves[found + I + 1]; + FIndexHeaderModified[found + I] := true; + end; + FIndexHeaders[found + moveItems] := tempHeader; + FParsers[found + moveItems] := tempParser; + FRoots[found + moveItems] := tempRoot; + FLeaves[found + moveItems] := tempLeaf; + FIndexHeaderModified[found + moveItems] := false; // non-existant header + end; + // one entry less left + IncWordLE(PMdxHdr(Header)^.TagsUsed, -1); + // ---*** numTags not valid from here ***--- + // file header changed + WriteFileHeader; + // repage index to free space used by deleted index +// RepageFile; + end; + end; +end; + +procedure TIndexFile.TouchHeader(AHeader: Pointer); +var + year, month, day: Word; +begin + DecodeDate(Now, year, month, day); + PMdxHdr(AHeader)^.UpdYear := year - 1900; + PMdxHdr(AHeader)^.UpdMonth := month; + PMdxHdr(AHeader)^.UpdDay := day; +end; + +function TIndexFile.CreateTempFile(BaseName: string): TPagedFile; +var + lModifier: Integer; +begin + // create temporary in-memory index file + lModifier := 0; + FindNextName(BaseName, BaseName, lModifier); + Result := TPagedFile.Create; + Result.FileName := BaseName; + Result.Mode := pfExclusiveCreate; + Result.AutoCreate := true; + Result.OpenFile; + Result.HeaderSize := HeaderSize; + Result.RecordSize := RecordSize; + Result.PageSize := PageSize; + Result.PageOffsetByHeader := false; +end; + +procedure TIndexFile.RepageFile; +var + TempFile: TPagedFile; + TempIdxHeader: PIndexHdr; + I, newPageNo: Integer; + prevIndex: Integer; + + function AllocNewPageNo: Integer; + begin + Result := newPageNo; + Inc(newPageNo, PagesPerRecord); + if FIndexVersion >= xBaseIV then + IncIntLE(PMdxHdr(TempFile.Header)^.NumPages, PagesPerRecord); + IncIntLE(TempIdxHeader^.NumPages, PagesPerRecord); + end; + + function WriteTree(NewPage: TIndexPage): Integer; + var + J: Integer; + begin + // get us a page so that page no's are more logically ordered + Result := AllocNewPageNo; + // use postorder visiting, first do all children + if NewPage.LowerPage <> nil then + begin + for J := 0 to NewPage.HighIndex do + begin + NewPage.EntryNo := J; + WriteTree(NewPage.LowerPage); + end; + end; + // now create new page for ourselves and write + // update page pointer in parent + if NewPage.UpperPage <> nil then + begin + if FIndexVersion >= xBaseIV then + begin + PMdxEntry(NewPage.UpperPage.Entry)^.RecBlockNo := SwapIntLE(Result); +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + // write previous node + if FRoot = NewPage then + PMdxPage(NewPage.PageBuffer)^.PrevBlock := 0 + else + PMdxPage(NewPage.PageBuffer)^.PrevBlock := SwapIntLE(Result - PagesPerRecord); +{$endif} + end else begin + PNdxEntry(NewPage.UpperPage.Entry)^.LowerPageNo := SwapIntLE(Result); + end; + end; + // store page + TempFile.WriteRecord(Result, NewPage.PageBuffer); + end; + + procedure CopySelectedIndex; + var + hdrPageNo: Integer; + begin + // copy current index settings + Move(FIndexHeader^, TempIdxHeader^, RecordSize); + // clear number of pages + TempIdxHeader^.NumPages := PagesPerRecord; + // allocate a page no for header + hdrPageNo := AllocNewPageNo; + // use recursive function to write all pages + TempIdxHeader^.RootPage := SwapIntLE(WriteTree(FRoot)); +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + TempIdxHeader^.FirstNode := TempIdxHeader^.RootPage; +{$endif} + // write index header now we know the root page + TempFile.WriteRecord(hdrPageNo, TempIdxHeader); + if FIndexVersion >= xBaseIV then + begin + // calculate tag offset in tempfile header + FTempMdxTag.Tag := PChar(TempFile.Header) + (PChar(CalcTagOffset(I)) - Header); + FTempMdxTag.HeaderPageNo := hdrPageNo; + end; + end; + +begin + CheckExclusiveAccess; + + prevIndex := FSelectedIndex; + newPageNo := HeaderSize div PageSize; + TempFile := CreateTempFile(FileName); + if FIndexVersion >= xBaseIV then + begin + // copy header + Move(Header^, TempFile.Header^, HeaderSize); + TouchHeader(TempFile.Header); + // reset header + PMdxHdr(TempFile.Header)^.NumPages := SwapIntLE(HeaderSize div PageSize); + TempFile.WriteHeader; + GetMem(TempIdxHeader, RecordSize); + // now recreate indexes to that file + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed - 1) do + begin + // select this index + SelectIndexVars(I); + CopySelectedIndex; + end; + FreeMem(TempIdxHeader); + end else begin + // indexversion = xBaseIII + TempIdxHeader := PIndexHdr(TempFile.Header); + CopySelectedIndex; + end; + TempFile.WriteHeader; + TempFile.CloseFile; + CloseFile; + + // rename temporary file if all went successfull + if not TempFile.WriteError then + begin + SysUtils.DeleteFile(FileName); + SysUtils.RenameFile(TempFile.FileName, FileName); + end; + + TempFile.Free; + DisableForceCreate; + OpenFile; + ReadIndexes; + SelectIndexVars(prevIndex); +end; + +procedure TIndexFile.CompactFile; +var + TempFile: TPagedFile; + TempIdxHeader: PIndexHdr; + I, newPageNo: Integer; + prevIndex: Integer; + + function AllocNewPageNo: Integer; + begin + Result := newPageNo; + Inc(newPageNo, PagesPerRecord); + if FIndexVersion >= xBaseIV then + IncIntLE(PMdxHdr(TempFile.Header)^.NumPages, PagesPerRecord); + IncIntLE(TempIdxHeader^.NumPages, PagesPerRecord); + end; + + function CreateNewPage: TIndexPage; + begin + // create new page + space + if FIndexVersion >= xBaseIV then + Result := TMdxPage.Create(Self) + else + Result := TNdxPage.Create(Self); + Result.FPageNo := AllocNewPageNo; + + // set new page properties + Result.SetNumEntries(0); + end; + + procedure GetNewEntry(APage: TIndexPage); + // makes a new entry available and positions current 'pos' on it + // NOTES: uses TIndexPage *very* carefully + // - may not read from self (tindexfile) + // - page.FLowerPage is assigned -> SyncLowerPage may *not* be called + // - do not set PageNo (= SetPageNo) + // - do not set EntryNo + begin + if APage.HighIndex >= SwapWordLE(PIndexHdr(FIndexHeader)^.NumKeys)-1 then + begin + if APage.UpperPage = nil then + begin + // add new upperlevel to page + APage.FUpperPage := CreateNewPage; + APage.UpperPage.FLowerPage := APage; + APage.UpperPage.FEntryNo := 0; + APage.UpperPage.FEntry := EntryEof; + APage.UpperPage.GotoInsertEntry; + APage.UpperPage.LocalInsert(0, APage.Key, APage.PageNo); + // non-leaf pages need 'rightmost' key; numentries = real# - 1 + APage.UpperPage.SetNumEntries(0); + end; + + // page done, store + TempFile.WriteRecord(APage.FPageNo, APage.PageBuffer); + + // allocate new page + APage.FPageNo := AllocNewPageNo; + // clear + APage.SetNumEntries(0); + APage.FHighIndex := -1; + APage.FLowIndex := 0; + // clear 'right-most' blockno + APage.SetRecLowerPageNoOfEntry(0, 0, 0); + + // get new entry in upper page for current new apage + GetNewEntry(APage.UpperPage); + APage.UpperPage.LocalInsert(0, nil, 0); + // non-leaf pages need 'rightmost' key; numentries = real# - 1 + if APage.UpperPage.EntryNo = 0 then + APage.UpperPage.SetNumEntries(0); + end; + APage.FEntryNo := APage.HighIndex+1; + APage.FEntry := EntryEof; + APage.GotoInsertEntry; + end; + + procedure CopySelectedIndex; + var + APage: TIndexPage; + hdrPageNo: Integer; + begin + // copy current index settings + Move(FIndexHeader^, TempIdxHeader^, RecordSize); + // clear number of pages + TempIdxHeader^.NumPages := SwapIntLE(PagesPerRecord); + // allocate a page no for header + hdrPageNo := AllocNewPageNo; + + // copy all records + APage := CreateNewPage; + FLeaf.RecurFirst; + while not (FRoot.Entry = FEntryEof) do + begin + GetNewEntry(APage); + APage.LocalInsert(FLeaf.PhysicalRecNo, FLeaf.Key, 0); + FLeaf.RecurNext; + end; + + // flush remaining (partially filled) pages + repeat + TempFile.WriteRecord(APage.FPageNo, APage.PageBuffer); + if APage.UpperPage <> nil then + APage := APage.UpperPage + else break; + until false; + + // copy index header + root page + TempIdxHeader^.RootPage := SwapIntLE(APage.PageNo); +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + TempIdxHeader^.FirstNode := SwapIntLE(APage.PageNo); +{$endif} + // write index header now we know the root page + TempFile.WriteRecord(hdrPageNo, TempIdxHeader); + if FIndexVersion >= xBaseIV then + begin + // calculate tag offset in tempfile header + FTempMdxTag.Tag := PChar(TempFile.Header) + (PChar(CalcTagOffset(I)) - Header); + FTempMdxTag.HeaderPageNo := hdrPageNo; + end; + end; + +begin + CheckExclusiveAccess; + + prevIndex := FSelectedIndex; + newPageNo := HeaderSize div PageSize; + TempFile := CreateTempFile(FileName); + if FIndexVersion >= xBaseIV then + begin + // copy header + Move(Header^, TempFile.Header^, HeaderSize); + TouchHeader(TempFile.Header); + // reset header + PMdxHdr(TempFile.Header)^.NumPages := SwapIntLE(HeaderSize div PageSize); + TempFile.WriteHeader; + GetMem(TempIdxHeader, RecordSize); + // now recreate indexes to that file + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + // select this index + SelectIndexVars(I); + CopySelectedIndex; + end; + FreeMem(TempIdxHeader); + end else begin + // indexversion = xBaseIII + TempIdxHeader := PIndexHdr(TempFile.Header); + CopySelectedIndex; + end; + TempFile.WriteHeader; + TempFile.CloseFile; + CloseFile; + + // rename temporary file if all went successfull + if not TempFile.WriteError then + begin + SysUtils.DeleteFile(FileName); + SysUtils.RenameFile(TempFile.FileName, FileName); + end; + + TempFile.Free; + DisableForceCreate; + OpenFile; + ReadIndexes; + SelectIndexVars(prevIndex); +end; + +procedure TIndexFile.PrepareRename(NewFileName: string); +begin + if FIndexVersion >= xBaseIV then + begin + WriteDBFileName(PMdxHdr(Header), NewFileName); + WriteFileHeader; + end; +end; + +function TIndexFile.GetNewPageNo: Integer; +var + needLockHeader: Boolean; +begin + // update header -> lock it if not already locked + needLockHeader := FHeaderLocked <> 0; + if needLockHeader then + begin + // lock header page + LockPage(0, true); + // someone else could be inserting records at the same moment + if NeedLocks then + inherited ReadHeader; + end; + if FIndexVersion >= xBaseIV then + begin + Result := SwapIntLE(PMdxHdr(Header)^.NumPages); + IncIntLE(PMdxHdr(Header)^.NumPages, PagesPerRecord); +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + // adjust high page + PIndexHdr(FIndexHeader)^.LastNode := SwapIntLE(Result); +{$endif} + WriteFileHeader; + end else begin + Result := SwapIntLE(PIndexHdr(FIndexHeader)^.NumPages); + end; + IncIntLE(PIndexHdr(FIndexHeader)^.NumPages, PagesPerRecord); + WriteHeader; + // done updating header -> unlock if locked + if needLockHeader then + UnlockPage(0); +end; + +function TIndexFile.Insert(RecNo: Integer; Buffer: TRecordBuffer): Boolean; {override;} +var + I, curSel, count: Integer; +begin + // check if updating all or only current + FUserRecNo := RecNo; + if (FUpdateMode = umAll) or (FSelectedIndex = -1) then + begin + // remember currently selected index + curSel := FSelectedIndex; + Result := true; + I := 0; + count := SwapWordLE(PMdxHdr(Header)^.TagsUsed); + while I < count do + begin + SelectIndexVars(I); + Result := InsertKey(Buffer); + if not Result then + begin + while I > 0 do + begin + Dec(I); + DeleteKey(Buffer); + end; + break; + end; + Inc(I); + end; + // restore previous selected index + SelectIndexVars(curSel); + end else begin + Result := InsertKey(Buffer); + end; + + // check range, disabled by insert + ResyncRange(true); +end; + +function TIndexFile.CheckKeyViolation(Buffer: TRecordBuffer): Boolean; +var + I, curSel: Integer; +begin + Result := false; + FUserRecNo := -2; + if FIndexVersion = xBaseIV then + begin + curSel := FSelectedIndex; + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + SelectIndexVars(I); + if FUniqueMode = iuDistinct then + begin + FUserKey := ExtractKeyFromBuffer(Buffer); + Result := FindKey(false) = 0; + if Result then + break; + end; + end; + SelectIndexVars(curSel); + end else begin + if FUniqueMode = iuDistinct then + begin + FUserKey := ExtractKeyFromBuffer(Buffer); + Result := FindKey(false) = 0; + end; + end; +end; + +function TIndexFile.PrepareKey(Buffer: TRecordBuffer; ResultType: TExpressionType): PChar; +var + FloatRec: TFloatRec; + I, IntSrc, NumDecimals: Integer; + ExtValue: Extended; + BCDdigit: Byte; +{$ifdef SUPPORT_INT64} + Int64Src: Int64; +{$endif} + +begin + floatrec.exponent:= 0; + // need to convert numeric? + Result := PChar(Buffer); + if PIndexHdr(FIndexHeader)^.KeyType in ['N', 'F'] then + begin + if FIndexVersion = xBaseIII then + begin + // DB3 -> index always 8 byte float, if original integer, convert to double + case ResultType of + etInteger: + begin + FUserNumeric := PInteger(Result)^; + Result := PChar(@FUserNumeric); + end; +{$ifdef SUPPORT_INT64} + etLargeInt: + begin + FUserNumeric := PLargeInt(Result)^; + Result := PChar(@FUserNumeric); + end; +{$endif} + end; + end else begin + // DB4 MDX + NumDecimals := 0; + case ResultType of + etInteger: + begin + IntSrc := PInteger(Result)^; + // handle zero differently: no decimals + if IntSrc <> 0 then + NumDecimals := GetStrFromInt(IntSrc, @FloatRec.Digits[0]) + else + NumDecimals := 0; + FloatRec.Negative := IntSrc < 0; + end; +{$ifdef SUPPORT_INT64} + etLargeInt: + begin + Int64Src := PLargeInt(Result)^; + if Int64Src <> 0 then + NumDecimals := GetStrFromInt64(Int64Src, @FloatRec.Digits[0]) + else + NumDecimals := 0; + FloatRec.Negative := Int64Src < 0; + end; +{$endif} + etFloat: + begin + ExtValue := PDouble(Result)^; + FloatToDecimal(FloatRec, ExtValue, {$ifndef FPC_VERSION}fvExtended,{$endif} 9999, 15); + if ExtValue <> 0.0 then + NumDecimals := StrLen(@FloatRec.Digits[0]) + else + NumDecimals := 0; + // maximum number of decimals possible to encode in BCD is 16 + if NumDecimals > 16 then + NumDecimals := 16; + end; + end; + + case ResultType of + etInteger {$ifdef SUPPORT_INT64}, etLargeInt{$endif}: + begin + FloatRec.Exponent := NumDecimals; + // MDX-BCD does not count ending zeroes as `data' space length + while (NumDecimals > 0) and (FloatRec.Digits[NumDecimals-1] = '0') do + Dec(NumDecimals); + // null-terminate string + FloatRec.Digits[NumDecimals] := #0; + end; + end; + + // write 'header', contains number of digits before decimal separator + FUserBCD[0] := $34 + FloatRec.Exponent; + // clear rest of BCD + FillChar(FUserBCD[1], SizeOf(FUserBCD)-1, 0); + // store number of bytes used (in number of bits + 1) + FUserBCD[1] := (((NumDecimals+1) div 2) * 8) + 1; + // where to store decimal dot position? now implicitly in first byte + // store negative sign + if FloatRec.Negative then + FUserBCD[1] := FUserBCD[1] or $80; + // convert string to BCD + I := 0; + while I < NumDecimals do + begin + // only one byte left? + if FloatRec.Digits[I+1] = #0 then + BCDdigit := 0 + else + BCDdigit := Byte(FloatRec.Digits[I+1]) - Byte('0'); + // pack two bytes into bcd + FUserBCD[2+(I div 2)] := ((Byte(FloatRec.Digits[I]) - Byte('0')) shl 4) or BCDdigit; + // goto next 2 bytes + Inc(I, 2); + end; + + // set result pointer to BCD + Result := PChar(@FUserBCD[0]); + end; + end; +end; + +function TIndexFile.ExtractKeyFromBuffer(Buffer: TRecordBuffer): PChar; +begin + // execute expression to get key + Result := PrepareKey(TRecordBuffer(FCurrentParser.ExtractFromBuffer(Buffer)), FCurrentParser.ResultType); + if FCurrentParser.StringFieldMode <> smRaw then + TranslateString(GetACP, FCodePage, Result, Result, KeyLen); +end; + +function TIndexFile.InsertKey(Buffer: TRecordBuffer): boolean; +begin + Result := true; + // ignore deleted records + if (FModifyMode = mmNormal) and (FUniqueMode = iuDistinct) and (AnsiChar(Buffer^) = '*') then + exit; + // check proper index and modifiability + if FCanEdit and (PIndexHdr(FIndexHeader)^.KeyLen <> 0) then + begin + // get key from buffer + FUserKey := ExtractKeyFromBuffer(Buffer); + // patch through + Result := InsertCurrent; + end; +end; + +function TIndexFile.InsertCurrent: boolean; + // insert in current index + // assumes: FUserKey is an OEM key +begin + // only insert if not recalling or mode = distinct + // modify = mmDeleteRecall /\ unique <> distinct -> key already present + Result := true; + if (FModifyMode <> mmDeleteRecall) or (FUniqueMode = iuDistinct) then + begin + // temporarily remove range to find correct location of key + ResetRange; + // find this record as closely as possible + // if result = 0 then key already exists + // if unique index, then don't insert key if already present + if (FindKey(true) <> 0) or (FUniqueMode = iuNormal) then + begin + // if we found eof, write to pagebuffer + FLeaf.GotoInsertEntry; + // insert requested entry, we know there is an entry available + FLeaf.LocalInsert(FUserRecNo, FUserKey, 0); + end else begin + // key already exists -> test possible key violation + if FUniqueMode = iuDistinct then + begin + // raising -> reset modify mode + FModifyMode := mmNormal; + ConstructInsertErrorMsg; + Result := false; + end; + end; + end; +end; + +procedure TIndexFile.ConstructInsertErrorMsg; +var + InfoKey: string; +begin + if Length(FLastError) > 0 then exit; + InfoKey := FUserKey; + SetLength(InfoKey, KeyLen); + FLastError := Format(STRING_KEY_VIOLATION, [GetName, + PhysicalRecNo, TrimRight(InfoKey)]); +end; + +procedure TIndexFile.InsertError; +var + errorStr: string; +begin + errorStr := FLastError; + FLastError := ''; + raise EDbfError.Create(errorStr); +end; + +procedure TIndexFile.Delete(RecNo: Integer; Buffer: TRecordBuffer); +var + I, curSel: Integer; +begin + // check if updating all or only current + FUserRecNo := RecNo; + if (FUpdateMode = umAll) or (FSelectedIndex = -1) then + begin + // remember currently selected index + curSel := FSelectedIndex; + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + SelectIndexVars(I); + DeleteKey(Buffer); + end; + // restore previous selected index + SelectIndexVars(curSel); + end else begin + DeleteKey(Buffer); + end; + // range may be changed + ResyncRange(true); +end; + +procedure TIndexFile.DeleteKey(Buffer: TRecordBuffer); +begin + if FCanEdit and (PIndexHdr(FIndexHeader)^.KeyLen <> 0) then + begin + // get key from record buffer + FUserKey := ExtractKeyFromBuffer(Buffer); + // call function + DeleteCurrent; + end; +end; + +procedure TIndexFile.DeleteCurrent; + // deletes from current index +begin + // only delete if not delete record or mode = distinct + // modify = mmDeleteRecall /\ unique = distinct -> key needs to be deleted from index + if (FModifyMode <> mmDeleteRecall) or (FUniqueMode = iuDistinct) then + begin + // prevent "confined" view of index while deleting + ResetRange; + // search correct entry to delete + if FLeaf.PhysicalRecNo <> FUserRecNo then + begin + FindKey(false); + end; + // delete selected entry + FLeaf.Delete; + end; +end; + +function TIndexFile.UpdateIndex(Index: Integer; PrevBuffer, NewBuffer: TRecordBuffer): Boolean; +begin + SelectIndexVars(Index); + Result := UpdateCurrent(PrevBuffer, NewBuffer); +end; + +function TIndexFile.Update(RecNo: Integer; PrevBuffer, NewBuffer: TRecordBuffer): Boolean; +var + I, curSel, count: Integer; +begin + // check if updating all or only current + FUserRecNo := RecNo; + if (FUpdateMode = umAll) or (FSelectedIndex = -1) then + begin + // remember currently selected index + curSel := FSelectedIndex; + Result := true; + I := 0; + count := SwapWordLE(PMdxHdr(Header)^.TagsUsed); + while I < count do + begin + Result := UpdateIndex(I, PrevBuffer, NewBuffer); + if not Result then + begin + // rollback updates to previous indexes + while I > 0 do + begin + Dec(I); + UpdateIndex(I, NewBuffer, PrevBuffer); + end; + break; + end; + Inc(I); + end; + // restore previous selected index + SelectIndexVars(curSel); + end else begin + Result := UpdateCurrent(PrevBuffer, NewBuffer); + end; + // check range, disabled by delete/insert + if (FRoot.LowPage = 0) and (FRoot.HighPage = 0) then + ResyncRange(true); +end; + +function TIndexFile.UpdateCurrent(PrevBuffer, NewBuffer: TRecordBuffer): boolean; +var + InsertKey, DeleteKey: PChar; + TempBuffer: array [0..100] of Char; +begin + Result := true; + if FCanEdit and (PIndexHdr(FIndexHeader)^.KeyLen <> 0) then + begin + DeleteKey := ExtractKeyFromBuffer(PrevBuffer); + Move(DeleteKey^, TempBuffer, SwapWordLE(PIndexHdr(FIndexHeader)^.KeyLen)); + DeleteKey := @TempBuffer[0]; + InsertKey := ExtractKeyFromBuffer(NewBuffer); + + // compare to see if anything changed + if CompareKeys(DeleteKey, InsertKey) <> 0 then + begin + FUserKey := DeleteKey; + DeleteCurrent; + FUserKey := InsertKey; + Result := InsertCurrent; + if not Result then + begin + FUserKey := DeleteKey; + InsertCurrent; + FUserKey := InsertKey; + end; + end; + end; +end; + +procedure TIndexFile.AddNewLevel; +var + lNewPage: TIndexPage; + pKeyData: PChar; +begin + // create new page + space + if FIndexVersion >= xBaseIV then + lNewPage := TMdxPage.Create(Self) + else + lNewPage := TNdxPage.Create(Self); + lNewPage.GetNewPage; + + // lock this new page; will be unlocked by caller + lNewPage.LockPage; + // lock index header; will be unlocked by caller + LockPage(FHeaderPageNo, true); + FHeaderLocked := FHeaderPageNo; + + // modify header + PIndexHdr(FIndexHeader)^.RootPage := SwapIntLE(lNewPage.PageNo); + + // set new page properties + lNewPage.SetNumEntries(0); + lNewPage.EntryNo := 0; + lNewPage.GotoInsertEntry; +{$ifdef TDBF_UPDATE_FIRST_LAST_NODE} + lNewPage.SetPrevBlock(lNewPage.PageNo - PagesPerRecord); +{$endif} + pKeyData := FRoot.GetKeyDataFromEntry(0); + lNewPage.FLowerPage := FRoot; + lNewPage.FHighIndex := 0; + lNewPage.SetEntry(0, pKeyData, FRoot.PageNo); + + // update root pointer + FRoot.UpperPage := lNewPage; + FRoots[FSelectedIndex] := lNewPage; + FRoot := lNewPage; + + // write new header + WriteRecord(FHeaderPageNo, FIndexHeader); +end; + +procedure TIndexFile.UnlockHeader; +begin + if FHeaderLocked <> -1 then + begin + UnlockPage(FHeaderLocked); + FHeaderLocked := -1; + end; +end; + +procedure TIndexFile.ResyncRoot; +begin + if FIndexVersion >= xBaseIV then + begin + // read header page + inherited ReadRecord(FHeaderPageNo, FIndexHeader); + end else + inherited ReadHeader; + // reread tree + FRoot.PageNo := SwapIntLE(PIndexHdr(FIndexHeader)^.RootPage); +end; + +function TIndexFile.SearchKey(Key: PChar; SearchType: TSearchKeyType): Boolean; +var + findres, currRecNo: Integer; +begin + // save current position + currRecNo := SequentialRecNo; + // search, these are always from the root: no need for first + findres := Find(-2, Key); + // test result + case SearchType of + stEqual: + Result := findres = 0; + stGreaterEqual: + Result := findres <= 0; + stGreater: + begin + if findres = 0 then + begin + // find next record that is greater + // NOTE: MatchKey assumes key to search for is already specified + // in FUserKey, it is because we have called Find + repeat + Result := WalkNext; + until not Result or (MatchKey(Key) <> 0); + end else + Result := findres < 0; + end; + else + Result := false; + end; + // search failed -> restore previous position + if not Result then + SequentialRecNo := currRecNo; +end; + +function TIndexFile.Find(RecNo: Integer; Buffer: PChar): Integer; +begin + // execute find + FUserRecNo := RecNo; + FUserKey := Buffer; + Result := FindKey(false); +end; + +function TIndexFile.FindKey(AInsert: boolean): Integer; +// +// if you set Insert = true, you need to re-enable range after insert!! +// +var + TempPage, NextPage: TIndexPage; + numEntries, numKeysAvail, done, searchRecNo: Integer; +begin + // reread index header (to discover whether root page changed) + if NeedLocks then + ResyncRoot; + // if distinct or unique index -> every entry only occurs once -> + // does not matter which recno we search -> search recno = -2 -> + // extra info = recno + if (FUniqueMode = iuNormal) then + begin + // if inserting, search last entry matching key + if AInsert then + searchRecNo := -3 + else + searchRecNo := FUserRecNo + end else begin + searchRecNo := -2; + end; + // start from root + TempPage := FRoot; + repeat + // find key + done := 0; + Result := TempPage.FindNearest(searchRecNo); + if TempPage.LowerPage = nil then + begin + // if key greater than last, try next leaf + if (Result > 0) and (searchRecNo > 0) then + begin + // find first parent in tree so we can advance to next item + NextPage := TempPage; + repeat + NextPage := NextPage.UpperPage; + until (NextPage = nil) or (NextPage.EntryNo < NextPage.HighIndex); + // found page? + if NextPage <> nil then + begin + // go to parent + TempPage := NextPage; + TempPage.EntryNo := TempPage.EntryNo + 1; + // resync rest of tree + TempPage.LowerPage.RecurFirst; + // go to lower page to continue search + TempPage := TempPage.LowerPage; + // check if still more lowerpages + if TempPage.LowerPage <> nil then + begin + // flag we need to traverse down further + done := 2; + end else begin + // this is next child, we don't know if found + done := 1; + end; + end; + end; + end else begin + // need to traverse lower down + done := 2; + end; + + // check if we need to split page + // done = 1 -> not found entry on insert path yet + if AInsert and (done <> 1) then + begin + // now we are on our path to destination where entry is to be inserted + // check if this page is full, then split it + numEntries := TempPage.NumEntries; + // if this is inner node, we can only store one less than max entries + numKeysAvail := SwapWordLE(PIndexHdr(FIndexHeader)^.NumKeys) - numEntries; + if TempPage.LowerPage <> nil then + dec(numKeysAvail); + // too few available -> split + if numKeysAvail = 0 then + TempPage.Split; + end; + + // do we need to go lower down? + if done = 2 then + TempPage := TempPage.LowerPage; + until done = 0; +end; + +function TIndexFile.MatchKey(UserKey: PChar): Integer; +begin + // BOF and EOF always false + if FLeaf.Entry = FEntryBof then + Result := 1 + else + if FLeaf.Entry = FEntryEof then + Result := -1 + else begin + FUserKey := UserKey; + Result := FLeaf.MatchKey; + end; +end; + +procedure TIndexFile.SetRange(LowRange, HighRange: PChar); +begin + Move(LowRange^, FLowBuffer[0], KeyLen); + Move(HighRange^, FHighBuffer[0], KeyLen); + FRangeActive := true; + ResyncRange(true); +end; + +procedure TIndexFile.RecordDeleted(RecNo: Integer; Buffer: TRecordBuffer); +begin + // are we distinct -> then delete record from index + FModifyMode := mmDeleteRecall; + Delete(RecNo, Buffer); + FModifyMode := mmNormal; +end; + +function TIndexFile.RecordRecalled(RecNo: Integer; Buffer: TRecordBuffer): Boolean; +begin + // are we distinct -> then reinsert record in index + FModifyMode := mmDeleteRecall; + Result := Insert(RecNo, Buffer); + FModifyMode := mmNormal; +end; + +procedure TIndexFile.SetPhysicalRecNo(RecNo: Integer); +begin + // check if already at specified recno + if FLeaf.PhysicalRecNo = RecNo then + exit; + + // check record actually exists + if TDbfFile(FDbfFile).IsRecordPresent(RecNo) then + begin + // read buffer of this RecNo + TDbfFile(FDbfFile).ReadRecord(RecNo, TDbfFile(FDbfFile).PrevBuffer); + // extract key + FUserKey := ExtractKeyFromBuffer(TDbfFile(FDbfFile).PrevBuffer); + // find this key + FUserRecNo := RecNo; + FindKey(false); + end; +end; + +procedure TIndexFile.SetUpdateMode(NewMode: TIndexUpdateMode); +begin + // if there is only one index, don't waste time and just set single + if (FIndexVersion = xBaseIII) or (SwapWordLE(PMdxHdr(Header)^.TagsUsed) <= 1) then + FUpdateMode := umCurrent + else + FUpdateMode := NewMode; +end; + +procedure TIndexFile.WalkFirst; +begin + // search first node + FRoot.RecurFirst; + // out of index - BOF + FLeaf.EntryNo := FLeaf.EntryNo - 1; +end; + +procedure TIndexFile.WalkLast; +begin + // search last node + FRoot.RecurLast; + // out of index - EOF + // we need to skip two entries to go out-of-bound + FLeaf.EntryNo := FLeaf.EntryNo + 2; +end; + +procedure TIndexFile.First; +begin + // resync tree + Resync(false); + WalkFirst; +end; + +procedure TIndexFile.Last; +begin + // resync tree + Resync(false); + WalkLast; +end; + +procedure TIndexFile.ResyncRange(KeepPosition: boolean); +var + Result: Boolean; + currRecNo: integer; +begin + if not FRangeActive then + exit; + + // disable current range if any + // init to 0 to suppress delphi warning + currRecNo := 0; + if KeepPosition then + currRecNo := SequentialRecNo; + ResetRange; + // search lower bound + Result := SearchKey(FLowBuffer, stGreaterEqual); + if not Result then + begin + // not found? -> make empty range + WalkLast; + end; + // set lower bound + SetBracketLow; + // search upper bound + Result := SearchKey(FHighBuffer, stGreater); + // if result true, then need to get previous item <=> + // last of equal/lower than key + if Result then + begin + Result := WalkPrev; + if not Result then + begin + // cannot go prev -> empty range + WalkFirst; + end; + end else begin + // not found -> EOF found, go EOF, then to last record + WalkLast; + WalkPrev; + end; + // set upper bound + SetBracketHigh; + if KeepPosition then + SequentialRecNo := currRecNo; +end; + +procedure TIndexFile.Resync(Relative: boolean); +begin + if NeedLocks then + begin + if not Relative then + begin + ResyncRoot; + ResyncRange(false); + end else begin + // resyncing tree implies resyncing range + ResyncTree; + end; + end; +end; + +procedure TIndexFile.ResyncTree; +var + action, recno: integer; +begin + // if at BOF or EOF, then we need to resync by first or last + // remember where the cursor was + // init to 0 to suppress delphi warning + recno := 0; + if FLeaf.Entry = FEntryBof then + begin + action := 0; + end else if FLeaf.Entry = FEntryEof then begin + action := 1; + end else begin + // read current key into buffer + Move(FLeaf.Key^, FKeyBuffer, SwapWordLE(PIndexHdr(FIndexHeader)^.KeyLen)); + recno := FLeaf.PhysicalRecNo; + action := 2; + end; + + // we now know cursor position, resync possible range + ResyncRange(false); + + // go to cursor position + case action of + 0: WalkFirst; + 1: WalkLast; + 2: + begin + // search current in-mem key on disk + if (Find(recno, FKeyBuffer) <> 0) then + begin + // houston, we've got a problem! + // our `current' record has gone. we need to find it + // find it by using physical recno + PhysicalRecNo := recno; + end; + end; + end; +end; + +function TIndexFile.WalkPrev: boolean; +var + curRecNo: Integer; +begin + // save current recno, find different next! + curRecNo := FLeaf.PhysicalRecNo; + repeat + // return false if we are at first entry + Result := FLeaf.RecurPrev; + until not Result or (curRecNo <> FLeaf.PhysicalRecNo); +end; + +function TIndexFile.WalkNext: boolean; +var + curRecNo: Integer; +begin + // save current recno, find different prev! + curRecNo := FLeaf.PhysicalRecNo; + repeat + // return false if we are at last entry + Result := FLeaf.RecurNext; + until not Result or (curRecNo <> FLeaf.PhysicalRecNo); +end; + +function TIndexFile.Prev: Boolean; +begin + // resync in-mem tree with tree on disk + Resync(true); + Result := WalkPrev; +end; + +function TIndexFile.Next: Boolean; +begin + // resync in-mem tree with tree on disk + Resync(true); + Result := WalkNext; +end; + +function TIndexFile.GetKeyLen: Integer; +begin + Result := SwapWordLE(PIndexHdr(FIndexHeader)^.KeyLen); +end; + +function TIndexFile.GetKeyType: Char; +begin + Result := PIndexHdr(FIndexHeader)^.KeyType; +end; + +function TIndexFile.GetPhysicalRecNo: Integer; +begin + Result := FLeaf.PhysicalRecNo; +end; + +function TIndexFile.GetSequentialRecordCount: Integer; +begin + Result := FRoot.Weight * (FRoot.HighIndex + 1); +end; + +function TIndexFile.GetSequentialRecNo: Integer; +var + TempPage: TIndexPage; +begin + // check if at BOF or EOF, special values + if FLeaf.EntryNo < FLeaf.LowIndex then begin + Result := RecBOF; + end else if FLeaf.EntryNo > FLeaf.HighIndex then begin + Result := RecEOF; + end else begin + // first record is record 1 + Result := 1; + TempPage := FRoot; + repeat + inc(Result, TempPage.EntryNo * TempPage.Weight); + TempPage := TempPage.LowerPage; + until TempPage = nil; + end; +end; + +procedure TIndexFile.SetSequentialRecNo(RecNo: Integer); +var + TempPage: TIndexPage; + gotoEntry: Integer; +begin + // use our weighting system to quickly go to a seq recno + // recno starts at 1, entries at zero + Dec(RecNo); + TempPage := FRoot; + repeat + // don't div by zero + assert(TempPage.Weight > 0); + gotoEntry := RecNo div TempPage.Weight; + RecNo := RecNo mod TempPage.Weight; + // do we have this much entries? + if (TempPage.HighIndex < gotoEntry) then + begin + // goto next entry in upper page if not + // if recurnext fails, we have come at the end of the index + if (TempPage.UpperPage <> nil) and TempPage.UpperPage.RecurNext then + begin + // lower recno to get because we skipped an entry + TempPage.EntryNo := TempPage.LowIndex; + RecNo := 0; + end else begin + // this can only happen if too big RecNo was entered, go to last + TempPage.RecurLast; + // terminate immediately + TempPage := FLeaf; + end; + end else begin + TempPage.EntryNo := gotoEntry; + end; + // get lower node + TempPage := TempPage.LowerPage; + until TempPage = nil; +end; + +procedure TIndexFile.SetBracketLow; +var + TempPage: TIndexPage; +begin + // set current record as lower bound + TempPage := FRoot; + repeat + TempPage.LowBracket := TempPage.EntryNo; + TempPage.LowPage := TempPage.PageNo; + TempPage := TempPage.LowerPage; + until TempPage = nil; +end; + +procedure TIndexFile.SetBracketHigh; +var + TempPage: TIndexPage; +begin + // set current record as lower bound + TempPage := FRoot; + repeat + TempPage.HighBracket := TempPage.EntryNo; + TempPage.HighPage := TempPage.PageNo; + TempPage := TempPage.LowerPage; + until TempPage = nil; +end; + +procedure TIndexFile.CancelRange; +begin + FRangeActive := false; + ResetRange; +end; + +procedure TIndexFile.ResetRange; +var + TempPage: TIndexPage; +begin + // disable lower + upper bound + TempPage := FRoot; + repeat + // set a page the index should never reach + TempPage.LowPage := 0; + TempPage.HighPage := 0; + TempPage := TempPage.LowerPage; + until TempPage = nil; +end; + +procedure TIndexFile.DisableRange; +var + TempPage: TIndexPage; +begin + TempPage := FRoot; + repeat + TempPage.SaveBracket; + TempPage := TempPage.LowerPage; + until TempPage = nil; + CancelRange; +end; + +procedure TIndexFile.EnableRange; +var + TempPage: TIndexPage; +begin + TempPage := FRoot; + repeat + TempPage.RestoreBracket; + TempPage := TempPage.LowerPage; + until TempPage = nil; + FRangeActive := true; +end; + +function MemComp(P1, P2: Pointer; const Length: Integer): Integer; +var + I: Integer; +begin + for I := 0 to Length - 1 do + begin + // still equal? + if PByte(P1)^ <> PByte(P2)^ then + begin + Result := Integer(PByte(P1)^) - Integer(PByte(P2)^); + exit; + end; + // go to next byte + Inc(PChar(P1)); + Inc(PChar(P2)); + end; + + // memory equal + Result := 0; +end; + +function TIndexFile.CompareKeys(Key1, Key2: PChar): Integer; +begin + // call compare routine + Result := FCompareKeys(Key1, Key2); + + // if descending then reverse order + if FIsDescending then + Result := -Result; +end; + +function TIndexFile.CompareKeysNumericNDX(Key1, Key2: PChar): Integer; +var + v1,v2: Double; +begin + v1 := PDouble(Key1)^; + v2 := PDouble(Key2)^; + if v1 > v2 then Result := 1 + else if v1 < v2 then Result := -1 + else Result := 0; +end; + +function TIndexFile.CompareKeysNumericMDX(Key1, Key2: PChar): Integer; +var + neg1, neg2: Boolean; +begin + // first byte - $34 contains dot position + neg1 := (Byte(Key1[1]) and $80) <> 0; + neg2 := (Byte(Key2[1]) and $80) <> 0; + // check if both negative or both positive + if neg1 = neg2 then + begin + // check alignment + if Key1[0] = Key2[0] then + begin + // no alignment needed -> have same alignment + Result := MemComp(Key1+2, Key2+2, 10-2); + end else begin + // greater 10-power implies bigger number except for zero + if (Byte(Key1[0]) = $01) and (Byte(Key1[1]) = $34) then + Result := -1 + else + if (Byte(Key2[0]) = $01) and (Byte(Key2[1]) = $34) then + Result := 1 + else + Result := Byte(Key1[0]) - Byte(Key2[0]); + end; + // negate result if both negative + if neg1 and neg2 then + Result := -Result; + end else if neg1 {-> not neg2} then + Result := -1 + else { not neg1 and neg2 } + Result := 1; +end; + +function TIndexFile.CompareKeysString(Key1, Key2: PChar): Integer; +begin + Result := DbfCompareString(FCollation, Key1, KeyLen, Key2, KeyLen); + if Result > 0 then + Dec(Result, 2); +end; + +function TIndexFile.CompareKey(Key: PChar): Integer; +begin + Result := CompareKeys(FUserKey, Key); +end; + +function TIndexFile.IndexOf(const AIndexName: string): Integer; + // *) assumes FIndexVersion >= xBaseIV +var + I: Integer; +begin + // get index of this index :-) + Result := -1; + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + FTempMdxTag.Tag := CalcTagOffset(I); + if AnsiCompareText(AIndexName, FTempMdxTag.TagName) = 0 then + begin + Result := I; + break; + end; + end; +end; + +procedure TIndexFile.SetIndexName(const AIndexName: string); +var + found: Integer; +begin + // we can only select a different index if we are MDX + if FIndexVersion >= xBaseIV then + begin + // find index + found := IndexOf(AIndexName); + end else + found := 0; + // if changing index, range is N/A anymore + if FRangeActive and (found <> FSelectedIndex) then + begin + FRangeIndex := FSelectedIndex; + DisableRange; + end; + // we can now select by index + if found >= 0 then + begin + SelectIndexVars(found); + if found = FRangeIndex then + begin + EnableRange; + FRangeIndex := -1; + end; + end; +end; + +function TIndexFile.CalcTagOffset(AIndex: Integer): Pointer; +begin + Result := PChar(Header) + FTagOffset + AIndex * FTagSize; +end; + +procedure TIndexFile.SelectIndexVars(AIndex: Integer); + // *) assumes index is in range +begin + if AIndex >= 0 then + begin + // get pointer to index header + FIndexHeader := FIndexHeaders[AIndex]; + // load root + leaf + FCurrentParser := FParsers[AIndex]; + FRoot := FRoots[AIndex]; + FLeaf := FLeaves[AIndex]; + // if xBaseIV then we need to store where pageno of current header + if FIndexVersion >= xBaseIV then + begin + FMdxTag.Tag := CalcTagOffset(AIndex); + FIndexName := FMdxTag.TagName; + FHeaderPageNo := FMdxTag.HeaderPageNo; + // does dBase actually use this flag? +// FIsExpression := FMdxTag.KeyFormat = KeyFormat_Expression; + end else begin + // how does dBase III store whether it is expression? +// FIsExpression := true; + end; + // retrieve properties + UpdateIndexProperties; + end else begin + // not a valid index + FIndexName := EmptyStr; + end; + // store selected index + FSelectedIndex := AIndex; + FCanEdit := not FForceReadOnly; +end; + +procedure TIndexFile.UpdateIndexProperties; +begin + // get properties + FIsDescending := (PIndexHdr(FIndexHeader)^.KeyFormat and KeyFormat_Descending) <> 0; + FUniqueMode := iuNormal; + if (PIndexHdr(FIndexHeader)^.KeyFormat and KeyFormat_Unique) <> 0 then + FUniqueMode := iuUnique; + if (PIndexHdr(FIndexHeader)^.KeyFormat and KeyFormat_Distinct) <> 0 then + FUniqueMode := iuDistinct; + // select key compare routine + if PIndexHdr(FIndexHeader)^.KeyType = 'C' then + FCompareKeys := CompareKeysString + else + if FIndexVersion >= xBaseIV then + FCompareKeys := CompareKeysNumericMDX + else + FCompareKeys := CompareKeysNumericNDX; +end; + +procedure TIndexFile.Flush; +var + I: Integer; +begin + // save changes to pages + if FIndexVersion >= xBaseIV then + begin + for I := 0 to MaxIndexes - 1 do + begin + if FIndexHeaderModified[I] then + WriteIndexHeader(I); + if FRoots[I] <> nil then + FRoots[I].Flush + end; + end else begin + if FRoot <> nil then + FRoot.Flush; + end; + + // save changes to header + FlushHeader; + + inherited; +end; + +(* + +function TIndexFile.GetIndexCount: Integer; +begin + if FIndexVersion = xBaseIII then + Result := 1 + else + if FIndexVersion = xBaseIV then + Result := PMdxHdr(Header).TagsUsed; + else + Result := 0; +end; + +*) + +procedure TIndexFile.GetIndexNames(const AList: TStrings); +var + I: Integer; +begin + // only applicable to MDX files + if FIndexVersion >= xBaseIV then + begin + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + FTempMdxTag.Tag := CalcTagOffset(I); + AList.AddObject(FTempMdxTag.TagName, Self); + end; + end; +end; + +procedure TIndexFile.GetIndexInfo(const AIndexName: string; IndexDef: TDbfIndexDef); +var + SaveIndexName: string; +begin + // remember current index + SaveIndexName := IndexName; + // select index + IndexName := AIndexName; + // copy properties + IndexDef.IndexFile := AIndexName; + IndexDef.Expression := PIndexHdr(FIndexHeader)^.KeyDesc; + IndexDef.Options := []; + IndexDef.Temporary := true; + if FIsDescending then + IndexDef.Options := IndexDef.Options + [ixDescending]; + IndexDef.Options := IndexDef.Options + [ixExpression]; + case FUniqueMode of + iuUnique: IndexDef.Options := IndexDef.Options + [ixUnique]; + iuDistinct: IndexDef.Options := IndexDef.Options + [ixPrimary]; + end; + // reselect previous index + IndexName := SaveIndexName; +end; + +function TIndexFile.GetExpression: string; +begin + if FCurrentParser <> nil then + Result := FCurrentParser.Expression + else + Result := EmptyStr; +end; + +function TIndexFile.GetDbfLanguageId: Byte; +begin + // check if parent DBF version 7, get language id + if (TDbfFile(FDbfFile).DbfVersion = xBaseVII) then + begin + // get language id of parent dbf + Result := GetLangId_From_LangName(TDbfFile(FDbfFile).LanguageStr); + end else begin + // dBase IV has language id in header + Result := TDbfFile(FDbfFile).LanguageID; + end; +end; + +procedure TIndexFile.WriteHeader; {override;} +begin + // if NDX, then this means file header + if FIndexVersion >= xBaseIV then + if NeedLocks then + WriteIndexHeader(FSelectedIndex) + else + FIndexHeaderModified[FSelectedIndex] := true + else + WriteFileHeader; +end; + +procedure TIndexFile.WriteFileHeader; +begin + inherited WriteHeader; +end; + +procedure TIndexFile.WriteIndexHeader(AIndex: Integer); +begin + FTempMdxTag.Tag := CalcTagOffset(AIndex); + WriteRecord(FTempMdxTag.HeaderPageNo, FIndexHeaders[AIndex]); + FIndexHeaderModified[AIndex] := false; +end; + +//========================================================== +//============ TDbfIndexDef +//========================================================== + +constructor TDbfIndexDef.Create(ACollection: TCollection); {override;} +begin + inherited Create(ACollection); + FTemporary := false; +end; + +destructor TDbfIndexDef.Destroy; {override;} +begin + inherited Destroy; +end; + +procedure TDbfIndexDef.Assign(Source: TPersistent); +begin + // we can't do anything with it if not a TDbfIndexDef + if Source is TDbfIndexDef then + begin + FIndexName := TDbfIndexDef(Source).IndexFile; + FExpression := TDbfIndexDef(Source).Expression; + FOptions := TDbfIndexDef(Source).Options; + end else + inherited; +end; + +procedure TDbfIndexDef.SetIndexName(NewName: string); +begin + FIndexName := AnsiUpperCase(Trim(NewName)); +end; + +procedure TDbfIndexDef.SetExpression(NewField: string); +begin + FExpression := AnsiUpperCase(Trim(NewField)); +end; + +initialization + +{ + Entry_Mdx_BOF.RecBlockNo := RecBOF; + Entry_Mdx_BOF.KeyData := #0; + + Entry_Mdx_EOF.RecBlockNo := RecEOF; + Entry_Mdx_EOF.KeyData := #0; + + Entry_Ndx_BOF.LowerPageNo := 0; + Entry_Ndx_BOF.RecNo := RecBOF; + Entry_Ndx_BOF.KeyData := #0; + + Entry_Ndx_EOF.LowerPageNo := 0; + Entry_Ndx_EOF.RecNo := RecEOF; + Entry_Ndx_EOF.KeyData := #0; +} + + LCIDList := TLCIDList.Create; + LCIDList.Enumerate; + +finalization + + LCIDList.Free; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_lang.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_lang.pas new file mode 100644 index 0000000..83151da --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_lang.pas @@ -0,0 +1,655 @@ +unit dbf_lang; + +{$I dbf_common.inc} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses +{$ifdef msWINDOWS} + Windows; +{$else} +{$ifdef KYLIX} + Libc, +{$endif} + Types, dbf_wtil; +{$endif} + +const + +//*************************************************************************// +// DB3/DB4/FoxPro Lang ID consts, for readable code +//*************************************************************************// + +// ... + FoxLangId_ENU_437 = $01; + FoxLangId_Intl_850 = $02; + FoxLangId_Windows_1252 = $03; + FoxLangId_Mac_10000 = $04; +// ... + DbfLangId_DAN_865 = $08; + DbfLangId_NLD_437 = $09; + DbfLangId_NLD_850 = $0A; + DbfLangId_FIN_437 = $0B; + DbfLangId_FIN_850 = $0C; // is it used? does not exist in BDE + DbfLangId_FRA_437 = $0D; + DbfLangId_FRA_850 = $0E; + DbfLangId_DEU_437 = $0F; + DbfLangId_DEU_850 = $10; + DbfLangId_ITA_437 = $11; + DbfLangId_ITA_850 = $12; + DbfLangId_JPN_932 = $13; + DbfLangId_ESP_850 = $14; + DbfLangId_SVE_437 = $15; + DbfLangId_SVE_850 = $16; + DbfLangId_NOR_865 = $17; + DbfLangId_ESP_437 = $18; + DbfLangId_ENG_437 = $19; + DbfLangId_ENG_850 = $1A; + DbfLangId_ENU_437 = $1B; + DbfLangId_FRC_863 = $1C; + DbfLangId_FRC_850 = $1D; +// ... + DbfLangId_CSY_852 = $1F; + DbfLangId_CSY_867 = $20; +// ... + DbfLangId_HUN_852 = $22; + DbfLangId_PLK_852 = $23; + DbfLangId_PTG_860 = $24; + DbfLangId_PTB_850 = $25; + DbfLangId_RUS_866 = $26; +// ... + DbfLangId_ENU_850 = $37; +// ... + DbfLangId_CHS_936 = $4D; + DbfLangId_KOR_949 = $4E; + DbfLangId_CHT_950 = $4F; + DbfLangId_THA_874 = $50; +// ... + DbfLangId_JPN_DIC_932 = $56; + DbfLangId_Ascii_1252 = $57; + DbfLangId_WEurope_1252 = $58; + DbfLangId_Spanish_1252 = $59; +// ... + FoxLangId_German_437 = $5E; + FoxLangId_Nordic_437 = $5F; + FoxLangId_Nordic_850 = $60; + FoxLangId_German_1252 = $61; + FoxLangId_Nordic_1252 = $62; +// ... + FoxLangId_EEurope_852 = $64; + FoxLangId_Russia_866 = $65; + FoxLangId_Nordic_865 = $66; + FoxLangId_Iceland_861 = $67; + FoxLangId_Czech_895 = $68; +// ... + DbfLangId_POL_620 = $69; +// ... + FoxLangId_Greek_737 = $6A; + FoxLangId_Turkish_857 = $6B; +// ... + FoxLangId_Taiwan_950 = $78; + FoxLangId_Korean_949 = $79; + FoxLangId_Chinese_936 = $7A; + FoxLangId_Japan_932 = $7B; + FoxLangId_Thai_874 = $7C; + FoxLangId_Hebrew_1255 = $7D; + FoxLangId_Arabic_1256 = $7E; +// ... + DbfLangId_Hebrew = $85; + DbfLangId_ELL_437 = $86; // greek, code page 737 (?) + DbfLangId_SLO_852 = $87; + DbfLangId_TRK_857 = $88; +// ... + DbfLangId_BUL_868 = $8E; +// ... + FoxLangId_Russia_10007 = $96; + FoxLangId_EEurope_10029 = $97; + FoxLangId_Greek_10006 = $98; +// ... + FoxLangId_Czech_1250 = $9B; + FoxLangId_Czech_850 = $9C; // DOS +// ... + FoxLangId_EEurope_1250 = $C8; + FoxLangId_Russia_1251 = $C9; + FoxLangId_Turkish_1254 = $CA; + FoxLangId_Greek_1253 = $CB; + + +// special constants + + DbfLocale_NotFound = $010000; + DbfLocale_Bul868 = $020000; + +//*************************************************************************// +// DB3/DB4/FoxPro Language ID to CodePage convert table +//*************************************************************************// + + LangId_To_CodePage: array[Byte] of Word = +// | 0| 1| 2| 3| 4| 5| 6| 7| +// | 8| 9| A| B| C| D| E| F| +// | | | | | | | | | +{00} ( 0, 437, 850, 1252,10000, 0, 0, 0, +{08} 865, 437, 850, 437, 850, 437, 850, 437, +{10} 850, 437, 850, 932, 850, 437, 850, 865, +{18} 437, 437, 850, 437, 863, 850, 0, 852, +{20} 867, 0, 852, 852, 860, 850, 866, 0, +{28} 0, 0, 0, 0, 0, 0, 0, 0, +{30} 0, 0, 0, 0, 0, 0, 0, 850, +{38} 0, 0, 0, 0, 0, 0, 0, 0, +{40} 0, 0, 0, 0, 0, 0, 0, 0, +{48} 0, 0, 0, 0, 0, 936, 949, 950, +{50} 874, 0, 0, 0, 0, 0, 932, 1252, +{58} 1252, 1252, 0, 0, 0, 0, 437, 437, +{60} 850, 1252, 1252, 0, 852, 866, 865, 861, +{68} 895, 620, 737, 857, 0, 0, 0, 0, +{70} 0, 0, 0, 0, 0, 0, 0, 0, +{78} 950, 949, 936, 932, 874, 1255, 1256, 0, +{80} 0, 0, 0, 0, 0, 862, 437, 852, +{88} 857, 0, 0, 0, 0, 0, 868, 0, +{90} 0, 0, 0, 0, 0, 0,10007,10029, +{98} 10006, 0, 0, 1250, 850, 0, 0, 0, +{A0} 0, 0, 0, 0, 0, 0, 0, 0, +{A8} 0, 0, 0, 0, 0, 0, 0, 0, +{B0} 0, 0, 0, 0, 0, 0, 0, 0, +{B8} 0, 0, 0, 0, 0, 0, 0, 0, +{C0} 0, 0, 0, 0, 0, 0, 0, 0, +{C8} 1250, 1251, 1254, 1253, 0, 0, 0, 0, +{D0} 0, 0, 0, 0, 0, 0, 0, 0, +{D8} 0, 0, 0, 0, 0, 0, 0, 0, +{E0} 0, 0, 0, 0, 0, 0, 0, 0, +{E8} 0, 0, 0, 0, 0, 0, 0, 0, +{F0} 0, 0, 0, 0, 0, 0, 0, 0, +{F8} 0, 0, 0, 0, 0, 0, 0, 0); + +{$ifdef FPC_VERSION} +{$ifdef VER1_0} + LANG_ARABIC = $01; + LANG_HEBREW = $0d; + LANG_THAI = $1e; + SUBLANG_KOREAN = $01; { Korean (Extended Wansung) } + SORT_CHINESE_PRC = $2; { PRC Chinese Stroke Count order } +{$endif} +{$endif} + +//*************************************************************************// +// DB3/DB4/FoxPro Language ID to Locale convert table +//*************************************************************************// + +// table + + LangId_To_Locale: array[Byte] of LCID = + ( + DbfLocale_NotFound, +{01} LANG_ENGLISH or (SUBLANG_ENGLISH_US shl 10) or (SORT_DEFAULT shl 16), + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), {international ??} + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), {windows ??} + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), {macintosh ??} + 0,0,0, +{08} LANG_DANISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_DUTCH or (SUBLANG_DUTCH shl 10) or (SORT_DEFAULT shl 16), + LANG_DUTCH or (SUBLANG_DUTCH shl 10) or (SORT_DEFAULT shl 16), + LANG_FINNISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_FINNISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_FRENCH or (SUBLANG_FRENCH shl 10) or (SORT_DEFAULT shl 16), + LANG_FRENCH or (SUBLANG_FRENCH shl 10) or (SORT_DEFAULT shl 16), + LANG_GERMAN or (SUBLANG_GERMAN shl 10) or (SORT_DEFAULT shl 16), + LANG_GERMAN or (SUBLANG_GERMAN shl 10) or (SORT_DEFAULT shl 16), + LANG_ITALIAN or (SUBLANG_ITALIAN shl 10) or (SORT_DEFAULT shl 16), + LANG_ITALIAN or (SUBLANG_ITALIAN shl 10) or (SORT_DEFAULT shl 16), + LANG_JAPANESE or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_SPANISH or (SUBLANG_SPANISH shl 10) or (SORT_DEFAULT shl 16), + LANG_SWEDISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_SWEDISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_SPANISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), + LANG_ENGLISH or (SUBLANG_ENGLISH_US shl 10) or (SORT_DEFAULT shl 16), + LANG_FRENCH or (SUBLANG_FRENCH_CANADIAN shl 10) or (SORT_DEFAULT shl 16), + LANG_FRENCH or (SUBLANG_FRENCH_CANADIAN shl 10) or (SORT_DEFAULT shl 16), +{1E} 0, +{1F} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{21} 0, +{22} LANG_HUNGARIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_POLISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_PORTUGUESE or (SUBLANG_PORTUGUESE_BRAZILIAN shl 10) or (SORT_DEFAULT shl 16), + LANG_PORTUGUESE or (SUBLANG_PORTUGUESE_BRAZILIAN shl 10) or (SORT_DEFAULT shl 16), + LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{27} 0,0,0,0,0,0,0,0,0, +{30} 0,0,0,0,0,0,0, +{37} LANG_ENGLISH or (SUBLANG_ENGLISH_US shl 10) or (SORT_DEFAULT shl 16), +{38} 0,0,0,0,0,0,0,0, +{40} 0,0,0,0,0,0,0,0,0,0,0,0,0, +{4D} LANG_CHINESE or (SUBLANG_CHINESE_SIMPLIFIED shl 10) or (SORT_DEFAULT shl 16), + LANG_KOREAN or (SUBLANG_KOREAN shl 10) or (SORT_DEFAULT shl 16), + LANG_CHINESE or (SUBLANG_CHINESE_TRADITIONAL shl 10) or (SORT_DEFAULT shl 16), + LANG_THAI or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{51} 0,0,0,0,0, +{56} LANG_JAPANESE or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // JPN: Dic932 ?? + 0, // Ascii: Binary + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), // Western Europe ?? + LANG_SPANISH or (SUBLANG_SPANISH shl 10) or (SORT_DEFAULT shl 16), +{5A} 0,0,0,0, +// FoxPro +{5E} LANG_GERMAN or (SUBLANG_GERMAN shl 10) or (SORT_DEFAULT shl 16), + LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_GERMAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{63} 0, +{64} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // Eastern Europe ?? + LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_ICELANDIC or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_POLISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_TURKISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{6C} 0,0,0,0, +{70} 0,0,0,0,0,0,0,0, +{78} LANG_CHINESE or (SUBLANG_CHINESE_HONGKONG shl 10) or (SORT_DEFAULT shl 16), + LANG_KOREAN or (SUBLANG_KOREAN shl 10) or (SORT_DEFAULT shl 16), + LANG_CHINESE or (SUBLANG_CHINESE_SINGAPORE shl 10) or (SORT_CHINESE_PRC shl 16), + LANG_JAPANESE or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // JPN: Dic932 ?? + LANG_THAI or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_HEBREW or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_ARABIC or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + 0, +{80} 0,0,0,0,0, +// dBase +{85} LANG_HEBREW or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_SLOVAK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_TURKISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{89} 0,0,0,0,0, +{8E} LANG_BULGARIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{8F} 0,0,0,0,0,0,0, +{96} LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // Eastern Europe ?? + LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + 0,0, +// FoxPro +{9B} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{9D} 0,0,0, +{A0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{B0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{C0} 0,0,0,0,0,0,0,0, +{C8} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // Eastern Europe ?? + LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_TURKISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{CC} 0,0,0,0, +{D0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{E0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{F0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ); + +//*************************************************************************// +// DB7 LangID Locale substrings +//*************************************************************************// + +// convert table + + LangId_To_LocaleStr: array[Byte] of Cardinal = + ( + DbfLocale_NotFound, +{01} Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16), + Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16), + Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16), + Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16), + 0,0,0, +{08} Ord('D') or (Ord('A') shl 8) or (Ord('0') shl 16), + Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16), + Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16), + Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16), + Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16), + Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16), + Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16), + Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16), + Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16), + Ord('I') or (Ord('T') shl 8) or (Ord('0') shl 16), + Ord('I') or (Ord('T') shl 8) or (Ord('1') shl 16), + Ord('J') or (Ord('P') shl 8) or (Ord('0') shl 16), + Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16), + Ord('S') or (Ord('V') shl 8) or (Ord('0') shl 16), + Ord('S') or (Ord('V') shl 8) or (Ord('1') shl 16), + Ord('N') or (Ord('O') shl 8) or (Ord('0') shl 16), + Ord('E') or (Ord('S') shl 8) or (Ord('1') shl 16), + Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16), + Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16), + Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16), + Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16), + Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16), +{1E} 0, +{1F} Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), + Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), +{21} 0, +{22} Ord('H') or (Ord('D') shl 8) or (Ord('C') shl 16), + Ord('P') or (Ord('O') shl 8) or (Ord('0') shl 16), + Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16), + Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16), + Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16), +{27} 0,0,0,0,0,0,0,0,0, +{30} 0,0,0,0,0,0,0, +{37} Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16), +{38} 0,0,0,0,0,0,0,0, +{40} 0,0,0,0,0,0,0,0,0,0,0,0,0, +{4D} Ord('C') or (Ord('N') shl 8) or (Ord('0') shl 16), + Ord('K') or (Ord('O') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('W') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('H') shl 8) or (Ord('0') shl 16), +{51} 0,0,0,0,0, +{56} Ord('J') or (Ord('P') shl 8) or (Ord('1') shl 16), + Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16), + Ord('W') or (Ord('E') shl 8) or (Ord('0') shl 16), + Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16), +{5A} 0,0,0,0, +// FoxPro +{5E} Ord('D') or (Ord('E') shl 8), + Ord('N') or (Ord('O') shl 8), + Ord('N') or (Ord('O') shl 8), + Ord('D') or (Ord('E') shl 8), + Ord('N') or (Ord('O') shl 8), +{63} 0, +{64} Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), + Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16), + Ord('N') or (Ord('O') shl 8), + Ord('I') or (Ord('C') shl 8) or (Ord('0') shl 16), // made this one up: iceland + Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), +{69} Ord('P') or (Ord('O') shl 8) or (Ord('1') shl 16), + Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16), +{6C} 0,0,0,0, +{70} 0,0,0,0,0,0,0,0, +{78} Ord('C') or (Ord('H') shl 8) or (Ord('0') shl 16), // made this one up: chinese hongkong + Ord('K') or (Ord('O') shl 8) or (Ord('0') shl 16), + Ord('C') or (Ord('S') shl 8) or (Ord('0') shl 16), // made this one up: chinese singapore + Ord('J') or (Ord('P') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('H') shl 8) or (Ord('0') shl 16), + Ord('R') or (Ord('E') shl 8) or (Ord('W') shl 16), + Ord('A') or (Ord('R') shl 8) or (Ord('0') shl 16), // made this one up: arabic (default) +{7F} 0, +{80} 0,0,0,0,0, +// dBase +{85} Ord('R') or (Ord('E') shl 8) or (Ord('W') shl 16), + Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16), + Ord('S') or (Ord('L') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16), +{89} 0,0,0,0,0, +{8E} DbfLocale_Bul868, +{8F} 0,0,0,0,0,0,0, +{96} Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16), + Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), + Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16), +{99} 0,0, +// FoxPro +{9B} 0, //LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + 0, //LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{9D} 0,0,0, +{A0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{B0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{C0} 0,0,0,0,0,0,0,0, +{C8} Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), + Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16), + Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16), +{CC} 0,0,0,0, +{D0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{E0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{F0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ); + +{ + DbfLocaleId_DAN_865 = Ord('D') or (Ord('A') shl 8) or (Ord('0') shl 16); + DbfLocaleId_NLD_437 = Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16); + DbfLocaleId_NLD_850 = Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16); + DbfLocaleId_FIN_437 = Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16); + DbfLocaleId_FIN_850 = Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16); + DbfLocaleId_FRA_437 = Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16); + DbfLocaleId_FRA_850 = Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16); + DbfLocaleId_DEU_437 = Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16); + DbfLocaleId_DEU_850 = Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ITA_437 = Ord('I') or (Ord('T') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ITA_850 = Ord('I') or (Ord('T') shl 8) or (Ord('1') shl 16); + DbfLocaleId_JPN_932 = Ord('J') or (Ord('P') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ESP_850 = Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16); + DbfLocaleId_SVE_437 = Ord('S') or (Ord('V') shl 8) or (Ord('0') shl 16); + DbfLocaleId_SVE_850 = Ord('S') or (Ord('V') shl 8) or (Ord('1') shl 16); + DbfLocaleId_NOR_865 = Ord('N') or (Ord('O') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ESP_437 = Ord('E') or (Ord('S') shl 8) or (Ord('1') shl 16); + DbfLocaleId_ENG_437 = Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ENG_850 = Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ENU_437 = Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16); + DbfLocaleId_FRC_863 = Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16); + DbfLocaleId_FRC_850 = Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16); +// ... + DbfLocaleId_CSY_852 = Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16); + DbfLocaleId_CSY_867 = Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_HUN_852 = Ord('H') or (Ord('D') shl 8) or (Ord('C') shl 16); + DbfLocaleId_PLK_852 = Ord('P') or (Ord('O') shl 8) or (Ord('0') shl 16); + DbfLocaleId_PTG_860 = Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16); + DbfLocaleId_PTB_850 = Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16); + DbfLocaleId_RUS_866 = Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_ENU_850 = Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_CHS_936 = Ord('C') or (Ord('N') shl 8) or (Ord('0') shl 16); + DbfLocaleId_KOR_949 = Ord('K') or (Ord('O') shl 8) or (Ord('0') shl 16); + DbfLocaleId_CHT_950 = Ord('T') or (Ord('W') shl 8) or (Ord('0') shl 16); + DbfLocaleId_THA_874 = Ord('T') or (Ord('H') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_JPN_DIC_932 = Ord('J') or (Ord('P') shl 8) or (Ord('1') shl 16); + DbfLocaleId_Ascii_Ansi = Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16); + DbfLocaleId_WEurope_Ansi = Ord('W') or (Ord('E') shl 8) or (Ord('0') shl 16); + DbfLocaleId_Spanish_Ansi = Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_Hebrew = Ord('R') or (Ord('E') shl 8) or (Ord('W') shl 16); + DbfLocaleId_ELL_437 = Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16); + DbfLocaleId_SLO_852 = Ord('S') or (Ord('L') shl 8) or (Ord('0') shl 16); + DbfLocaleId_TRK_857 = Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_BUL_868 = 'BGDB868'; +} + +// VdBase 7 Language strings +// 'DBWIN...' -> Charset 1252 (ansi) +// 'DB999...' -> Code page 999, 9 any digit +// 'DBHEBREW' -> Code page 1255 ?? +// 'FOX..999' -> Code page 999, 9 any digit +// 'FOX..WIN' -> Charset 1252 (ansi) + +//*************************************************************************// +// reverse convert routines +//*************************************************************************// + +function ConstructLangName(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): string; + +function ConstructLangId(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): Byte; + +function GetLangId_From_LangName(LocaleStr: string): Byte; + +implementation + +uses + SysUtils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + PCardinal = ^Cardinal; + +function ConstructLangName(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): string; +var + SubType: Cardinal; +begin + // ANSI? + SubType := LangId_To_LocaleStr[ConstructLangId(CodePage, Locale, IsFoxPro)]; + // found? + if SubType <> DbfLocale_NotFound then + begin + // foxpro or dbase? + if IsFoxPro then + begin + Result := 'FOX' + PChar(@SubType); + if CodePage = 1252 then + Result := Result + 'WIN' + else + Result := Result + IntToStr(CodePage); + end else begin + if SubType = DbfLocale_Bul868 then + begin + // special case + Result := 'BGDB868'; + end else begin + // start with DB + Result := 'DB'; + // add codepage + if CodePage = 1252 then + Result := Result + 'WIN' + else + Result := Result + IntToStr(CodePage); + // add subtype + Result := Result + PChar(@SubType); + end; + end; + end; +end; + +const + // range of Dbase / FoxPro locale; these are INCLUSIVE + + dBase_RegionCount = 4; + dBase_Regions: array[0..dBase_RegionCount*2-1] of Byte = + ($00, $00, + $05, $5D, + $69, $69, // a lonely dbf entry :-) + $80, $90); + +function FindLangId(CodePage, Info2: Cardinal; Info2Table: PCardinal; IsFoxPro: Boolean): Byte; +var + I, Region, FoxRes, DbfRes: Integer; +begin + Region := 0; + DbfRes := 0; + FoxRes := 0; + // scan + for I := 0 to $FF do + begin + // check if need to advance to next region + if Region + 2 < dBase_RegionCount then + if I >= dBase_Regions[Region + 2] then + Inc(Region, 2); + // it seems delphi does not properly understand pointers? + // what a mess :-( + if ((LangId_To_CodePage[I] = CodePage) or (CodePage = 0)) and (PCardinal(PChar(Info2Table)+(I*4))^ = Info2) then + if I <= dBase_Regions[Region+1] then + DbfRes := Byte(I) + else + FoxRes := Byte(I); + end; + // if we can find langid in other set, use it + if (DbfRes <> 0) and (not IsFoxPro or (FoxRes = 0)) then + Result := DbfRes + else {(DbfRes = 0) or (IsFoxPro and (FoxRes <> 0)} + if (FoxRes <> 0) {and (IsFoxPro or (DbfRes = 0)} then + Result := FoxRes + else + Result := 0; +end; + +{ +function FindLangId(CodePage, Info2: Cardinal; Info2Table: PCardinal; IsFoxPro: Boolean): Byte; +var + I, Region, lEnd: Integer; + EndReached: Boolean; +begin + Region := 0; + Result := 0; + repeat + // determine region to scan + if IsFoxPro then + begin + // foxpro, in between dbase regions + I := dBase_Regions[Region+1] + 1; + lEnd := dBase_Regions[Region+2] - 1; + EndReached := Region = dBase_RegionCount*2-4; + end else begin + // dBase, select regions + I := dBase_Regions[Region]; + lEnd := dBase_Regions[Region+1]; + EndReached := Region = dBase_RegionCount*2-2; + end; + // scan + repeat + // it seems delphi does not properly understand pointers? + // what a mess :-( + if (LangId_To_CodePage[I] = CodePage) and (PCardinal(PChar(Info2Table)+(I*4))^ = Info2) then + Result := Byte(I); + Inc(I); + // lEnd is included in range + until (Result <> 0) or (I > lEnd); + // goto next region + if (Result = 0) then + Inc(Region, 2); + // found or end? + until (Result <> 0) or EndReached; +end; +} + +function ConstructLangId(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): Byte; +begin + // locale: lower 16bits only + Locale := (Locale and $FFFF) or (SORT_DEFAULT shl 16); + Result := FindLangId(CodePage, Locale, @LangId_To_Locale[0], IsFoxPro); + // not found? try any codepage + if Result = 0 then + Result := FindLangId(0, Locale, @LangId_To_Locale[0], IsFoxPro); +end; + +function GetLangId_From_LangName(LocaleStr: string): Byte; +var + CodePage, SubType: Integer; + IsFoxPro: Boolean; + CodePageStr: string; +begin + // determine foxpro/dbase + IsFoxPro := CompareMem(PChar('FOX'), PChar(LocaleStr), 3); + // get codepage/locale subtype + if IsFoxPro then + begin + CodePageStr := Copy(LocaleStr, 6, 3); + SubType := Integer(LocaleStr[4]) or (Integer(LocaleStr[5]) shl 8); + end else begin + CodePageStr := Copy(LocaleStr, 3, 3); + SubType := Integer(LocaleStr[6]) or (Integer(LocaleStr[7]) shl 8) or (Integer(LocaleStr[8]) shl 16); + end; + // convert codepage string to codepage id + if CodePageStr = 'WIN' then + CodePage := 1252 + else if CodePageStr = 'REW' then // hebrew + CodePage := 1255 + else + CodePage := StrToInt(CodePageStr); + // find lang id + Result := FindLangId(CodePage, SubType, @LangId_To_LocaleStr[0], IsFoxPro); +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_memo.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_memo.pas new file mode 100644 index 0000000..ebdae59 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_memo.pas @@ -0,0 +1,556 @@ +unit dbf_memo; + +interface + +{$I dbf_common.inc} + +uses + classes,mclasses, + dbf_pgfile, + dbf_common; + +type + +//==================================================================== + TMemoFile = class(TPagedFile) + protected + FDbfFile: pointer; + FDbfVersion: TXBaseVersion; + FMemoRecordSize: Integer; + FOpened: Boolean; + FBuffer: PChar; + protected + function GetBlockLen: Integer; virtual; abstract; + function GetMemoSize: Integer; virtual; abstract; + function GetNextFreeBlock: Integer; virtual; abstract; + procedure SetNextFreeBlock(BlockNo: Integer); virtual; abstract; + procedure SetBlockLen(BlockLen: Integer); virtual; abstract; + public + constructor Create(ADbfFile: pointer); + destructor Destroy; override; + + procedure Open; + procedure Close; + + procedure ReadMemo(BlockNo: Integer; DestStream: TStream); + procedure WriteMemo(var BlockNo: Integer; ReadSize: Integer; Src: TStream); + + property DbfVersion: TXBaseVersion read FDbfVersion write FDbfVersion; + property MemoRecordSize: Integer read FMemoRecordSize write FMemoRecordSize; + end; + + TFoxProMemoFile = class(TMemoFile) + protected + function GetBlockLen: Integer; override; + function GetMemoSize: Integer; override; + function GetNextFreeBlock: Integer; override; + procedure SetNextFreeBlock(BlockNo: Integer); override; + procedure SetBlockLen(BlockLen: Integer); override; + end; + + TDbaseMemoFile = class(TMemoFile) + protected + function GetBlockLen: Integer; override; + function GetMemoSize: Integer; override; + function GetNextFreeBlock: Integer; override; + procedure SetNextFreeBlock(BlockNo: Integer); override; + procedure SetBlockLen(BlockLen: Integer); override; + end; + + { TNullMemoFile, a kind /dev/null memofile ;-) } + { - inv: FHeaderModified == false!! (otherwise will try to write FStream) } + { - inv: FHeaderSize == 0 } + { - inv: FNeedLocks == false } + { - WriteTo must NOT be used } + { - WriteChar must NOT be used } + + TNullMemoFile = class(TMemoFile) + protected + procedure SetHeaderOffset(NewValue: Integer); override; + procedure SetRecordSize(NewValue: Integer); override; + procedure SetHeaderSize(NewValue: Integer); override; + + function LockSection(const Offset, Length: Cardinal; const Wait: Boolean): Boolean; override; + function UnlockSection(const Offset, Length: Cardinal): Boolean; override; + + function GetBlockLen: Integer; override; + function GetMemoSize: Integer; override; + function GetNextFreeBlock: Integer; override; + procedure SetNextFreeBlock(BlockNo: Integer); override; + procedure SetBlockLen(BlockLen: Integer); override; + + public + constructor Create(ADbfFile: pointer); + + procedure CloseFile; override; + procedure OpenFile; override; + + function ReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; override; + procedure WriteRecord(IntRecNum: Integer; Buffer: Pointer); override; + end; + + PInteger = ^Integer; + TMemoFileClass = class of TMemoFile; + +implementation + +uses + SysUtils, dbf_dbffile; + +//==================================================================== +//=== Memo and binary fields support +//==================================================================== +type + + PDbtHdr = ^rDbtHdr; + rDbtHdr = record + NextBlock : dword; + Dummy : array [4..7] of Byte; + DbfFile : array [0..7] of Byte; // 8..15 + bVer : Byte; // 16 + Dummy2 : array [17..19] of Byte; + BlockLen : Word; // 20..21 + Dummy3 : array [22..511] of Byte; + end; + + PFptHdr = ^rFptHdr; + rFptHdr = record + NextBlock : dword; + Dummy : array [4..5] of Byte; + BlockLen : Word; // 20..21 + Dummy3 : array [8..511] of Byte; + end; + + PBlockHdr = ^rBlockHdr; + rBlockHdr = record + MemoType : Cardinal; + MemoSize : Cardinal; + end; + + +//========================================================== +//============ Dbtfile +//========================================================== +constructor TMemoFile.Create(ADbfFile: pointer); +begin + // init vars + FBuffer := nil; + FOpened := false; + + // call inherited + inherited Create; + + FDbfFile := ADbfFile; + FTempMode := TDbfFile(ADbfFile).TempMode; +end; + +destructor TMemoFile.Destroy; +begin + // close file + Close; + + // call ancestor + inherited; +end; + +procedure TMemoFile.Open; +begin + if not FOpened then + begin + // memo pages count start from begining of file! + PageOffsetByHeader := false; + + // open physical file + OpenFile; + + // read header + HeaderSize := 512; + + // determine version + if FDbfVersion = xBaseIII then + PDbtHdr(Header)^.bVer := 3; + VirtualLocks := false; + + if FileCreated or (HeaderSize = 0) then + begin + if (FMemoRecordSize = 0) or (FMemoRecordSize > HeaderSize) then + SetNextFreeBlock(1) + else + SetNextFreeBlock(HeaderSize div FMemoRecordSize); + SetBlockLen(FMemoRecordSize); + WriteHeader; + end; + + RecordSize := GetBlockLen; + // checking for right blocksize not needed for foxpro? + // mod 128 <> 0 <-> and 0x7F <> 0 + if (RecordSize = 0) and ((FDbfVersion = xFoxPro) or ((RecordSize and $7F) <> 0)) then + begin + SetBlockLen(512); + RecordSize := 512; + WriteHeader; + end; + + // get memory for temporary buffer + GetMem(FBuffer, RecordSize+2); + FBuffer[RecordSize] := #0; + FBuffer[RecordSize+1] := #0; + + // now open + FOpened := true; + end; +end; + +procedure TMemoFile.Close; +begin + if FOpened then + begin + // close physical file + CloseFile; + + // free mem + if FBuffer <> nil then + FreeMemAndNil(Pointer(FBuffer)); + + // now closed + FOpened := false; + end; +end; + +procedure TMemoFile.ReadMemo(BlockNo: Integer; DestStream: TStream); +var + bytesLeft,numBytes,dataStart: Integer; + done: Boolean; + lastc: char; + endMemo: PChar; +begin + // clear dest + DestStream.Position := 0; + DestStream.Size := 0; + // no block to read? + if (BlockNo<=0) or (RecordSize=0) then + exit; + // read first block + numBytes := ReadRecord(BlockNo, @FBuffer[0]); + if numBytes = 0 then + begin + // EOF reached? + exit; + end else + if numBytes < RecordSize then + FillChar(FBuffer[numBytes], RecordSize-numBytes, #0); + + bytesLeft := GetMemoSize; + // bytesLeft <> -1 -> memo size is known (FoxPro, dBase4) + // bytesLeft = -1 -> memo size unknown (dBase3) + if bytesLeft <> -1 then + begin + dataStart := 8; + DestStream.Size := bytesLeft; + while bytesLeft > 0 do + begin + // get number of bytes to be read + numBytes := bytesLeft; + // too much for this block? + if numBytes > RecordSize - dataStart then + numBytes := RecordSize - dataStart; + // read block to stream + DestStream.Write(FBuffer[dataStart], numBytes); + // numBytes done + dec(bytesLeft, numBytes); + // still need to read bytes? + if bytesLeft > 0 then + begin + // read next block + inc(BlockNo); + dataStart := 0; + ReadRecord(BlockNo, @FBuffer[0]); + end; + end; + end else begin + // dbase III memo + done := false; + repeat + // scan for EOF + endMemo := MemScan(FBuffer, $1A, RecordSize); + // EOF found? + if endMemo <> nil then + begin + // really EOF? + if (endMemo-FBuffer < RecordSize - 1) and ((endMemo[1] = #$1A) or (endMemo[1] = #0)) then + begin + // yes, EOF found + done := true; + numBytes := endMemo - FBuffer; + end else begin + // no, fake + numBytes := RecordSize; + end; + end else begin + numBytes := RecordSize; + end; + // write to stream + DestStream.Write(FBuffer[0], numBytes); +{ + for i := 0 to RecordSize-2 do + begin + if (FBuffer[i]=#$1A) and (FBuffer[i+1]=#$1A) then + begin + if i>0 then + DestStream.Write(FBuffer[0], i); + done := true; + break; + end; + end; +} + if not done then + begin +{ + DestStream.Write(FBuffer[0], 512); +} + lastc := FBuffer[RecordSize-1]; + inc(BlockNo); + if ReadRecord(BlockNo, @FBuffer[0]) > 0 then + begin + // check if immediate terminator at begin of block + done := (lastc = #$1A) and ((FBuffer[0] = #$1A) or (FBuffer[0] = #0)); + // if so, written one character too much + if done then + DestStream.Size := DestStream.Size - 1; + end else begin + // error while reading, stop + done := true; + end; + end; + until done; + end; +end; + +procedure TMemoFile.WriteMemo(var BlockNo: Integer; ReadSize: Integer; Src: TStream); +var + bytesBefore: Integer; + bytesAfter: Integer; + totsize: Integer; + readBytes: Integer; + append: Boolean; + tmpRecNo: Integer; +begin + // if no data to write, then don't create new block + if Src.Size = 0 then + begin + BlockNo := 0; + end else begin + if FDbfVersion >= xBaseIV then // dBase4 or FoxPro type + begin + bytesBefore := SizeOf(rBlockHdr); + bytesAfter := 0; + end else begin // dBase3 type + bytesBefore := 0; + bytesAfter := 2; + end; +// if ((bytesBefore + Src.Size + bytesAfter + PDbtHdr(Header).BlockLen-1) div PDbtHdr(Header).BlockLen) +// <= ((ReadSize + PDbtHdr(Header).BlockLen-1) div PDbtHdr(Header).BlockLen) then + if ((bytesBefore + Src.Size + bytesAfter + RecordSize-1) div RecordSize) + <= ((ReadSize + RecordSize-1) div RecordSize) then + begin + append := false; + end else begin + append := true; + // modifying header -> lock memo header + LockPage(0, true); + BlockNo := GetNextFreeBlock; + if BlockNo = 0 then + begin + SetNextFreeBlock(1); + BlockNo := 1; + end; + end; + tmpRecNo := BlockNo; + Src.Position := 0; + FillChar(FBuffer[0], RecordSize, ' '); + if bytesBefore=8 then + begin + totsize := Src.Size + bytesBefore + bytesAfter; + if FDbfVersion <> xFoxPro then + begin + PBlockHdr(FBuffer)^.MemoType := SwapIntLE($0008FFFF); + PBlockHdr(FBuffer)^.MemoSize := SwapIntLE(totsize); + end else begin + PBlockHdr(FBuffer)^.MemoType := SwapIntLE($01000000); + PBlockHdr(FBuffer)^.MemoSize := SwapIntBE(Src.Size); + end; + end; + repeat + // read bytes, don't overwrite header + readBytes := Src.Read(FBuffer[bytesBefore], RecordSize{PDbtHdr(Header).BlockLen}-bytesBefore); + // end of input data reached ? check if need to write block terminators + while (readBytes < RecordSize - bytesBefore) and (bytesAfter > 0) do + begin + FBuffer[readBytes] := #$1A; + Inc(readBytes); + Dec(bytesAfter); + end; + // have we read anything that is to be written? + if readBytes > 0 then + begin + // clear any unused space + FillChar(FBuffer[bytesBefore+readBytes], RecordSize-readBytes-bytesBefore, ' '); + // write to disk + WriteRecord(tmpRecNo, @FBuffer[0]); + Inc(tmpRecNo); + end else break; + // first block read, second block can start at beginning + bytesBefore := 0; + until false; + + if append then + begin + SetNextFreeBlock(tmpRecNo); + WriteHeader; + UnlockPage(0); + end; + end; +end; + +// ------------------------------------------------------------------ +// dBase specific helper routines +// ------------------------------------------------------------------ + +function TDbaseMemoFile.GetBlockLen: Integer; +begin + // Can you tell me why the header of dbase3 memo contains 1024 and is 512 ? + // answer: it is not a valid field in memo db3 header + if FDbfVersion = xBaseIII then + Result := 512 + else + Result := SwapWordLE(PDbtHdr(Header)^.BlockLen); +end; + +function TDbaseMemoFile.GetMemoSize: Integer; +begin + // dBase4 memofiles contain small 'header' + if PInteger(@FBuffer[0])^ = Integer(SwapIntLE($0008FFFF)) then + Result := SwapIntLE(PBlockHdr(FBuffer)^.MemoSize)-8 + else + Result := -1; +end; + +function TDbaseMemoFile.GetNextFreeBlock: Integer; +begin + Result := SwapIntLE(PDbtHdr(Header)^.NextBlock); +end; + +procedure TDbaseMemoFile.SetNextFreeBlock(BlockNo: Integer); +begin + PDbtHdr(Header)^.NextBlock := SwapIntLE(BlockNo); +end; + +procedure TDbaseMemoFile.SetBlockLen(BlockLen: Integer); +begin + PDbtHdr(Header)^.BlockLen := SwapWordLE(BlockLen); +end; + +// ------------------------------------------------------------------ +// FoxPro specific helper routines +// ------------------------------------------------------------------ + +function TFoxProMemoFile.GetBlockLen: Integer; +begin + Result := SwapWordBE(PFptHdr(Header)^.BlockLen); +end; + +function TFoxProMemoFile.GetMemoSize: Integer; +begin + Result := SwapIntBE(PBlockHdr(FBuffer)^.MemoSize); +end; + +function TFoxProMemoFile.GetNextFreeBlock: Integer; +begin + Result := SwapIntBE(PFptHdr(Header)^.NextBlock); +end; + +procedure TFoxProMemoFile.SetNextFreeBlock(BlockNo: Integer); +begin + PFptHdr(Header)^.NextBlock := SwapIntBE(dword(BlockNo)); +end; + +procedure TFoxProMemoFile.SetBlockLen(BlockLen: Integer); +begin + PFptHdr(Header)^.BlockLen := SwapWordBE(dword(BlockLen)); +end; + +// ------------------------------------------------------------------ +// NULL file (no file) specific helper routines +// ------------------------------------------------------------------ + +constructor TNullMemoFile.Create(ADbfFile: pointer); +begin + inherited; +end; + +procedure TNullMemoFile.OpenFile; +begin +end; + +procedure TNullMemoFile.CloseFile; +begin +end; + +procedure TNullMemoFile.SetHeaderOffset(NewValue: Integer); +begin + inherited SetHeaderOffset(0); +end; + +procedure TNullMemoFile.SetRecordSize(NewValue: Integer); +begin + inherited SetRecordSize(0); +end; + +procedure TNullMemoFile.SetHeaderSize(NewValue: Integer); +begin + inherited SetHeaderSize(0); +end; + +function TNullMemoFile.LockSection(const Offset, Length: Cardinal; const Wait: Boolean): Boolean; +begin + Result := true; +end; + +function TNullMemoFile.UnlockSection(const Offset, Length: Cardinal): Boolean; +begin + Result := true; +end; + +function TNullMemoFile.GetBlockLen: Integer; +begin + Result := 0; +end; + +function TNullMemoFile.GetMemoSize: Integer; +begin + Result := 0; +end; + +function TNullMemoFile.GetNextFreeBlock: Integer; +begin + Result := 0; +end; + +procedure TNullMemoFile.SetNextFreeBlock(BlockNo: Integer); +begin +end; + +procedure TNullMemoFile.SetBlockLen(BlockLen: Integer); +begin +end; + +function TNullMemoFile.ReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; +begin + Result := 0; +end; + +procedure TNullMemoFile.WriteRecord(IntRecNum: Integer; Buffer: Pointer); +begin +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_parser.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_parser.pas new file mode 100644 index 0000000..56e9483 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_parser.pas @@ -0,0 +1,604 @@ +unit dbf_parser; + +// Modified 2013 by Martin Schreiber + +interface + +{$I dbf_common.inc} + +uses + SysUtils, + classes,mclasses, +{$ifdef KYLIX} + Libc, +{$endif} +{$ifndef WINDOWS} + dbf_wtil, +{$endif} + mdb, + mdbf_prscore, + dbf_common, + dbf_fields, + mdbf_prsdef, + mdbf_prssupp; + +type + + TStringFieldMode = (smRaw, smAnsi, smAnsiTrim); + + TDbfParser = class(TCustomExpressionParser) + private + FDbfFile: Pointer; + FFieldVarList: TStringList; + FIsExpression: Boolean; // expression or simple field? + FFieldType: TExpressionType; + FCaseInsensitive: Boolean; + FStringFieldMode: TStringFieldMode; + FPartialMatch: boolean; + + protected + FCurrentExpression: string; + + procedure FillExpressList; override; + procedure HandleUnknownVariable(VarName: string); override; + function GetVariableInfo(VarName: string): TDbfFieldDef; + function CurrentExpression: string; override; + procedure ValidateExpression(AExpression: string); virtual; + function GetResultType: TExpressionType; override; + function GetResultLen: Integer; + + procedure SetCaseInsensitive(NewInsensitive: Boolean); + procedure SetStringFieldMode(NewMode: TStringFieldMode); + procedure SetPartialMatch(NewPartialMatch: boolean); + public + constructor Create(ADbfFile: Pointer); + destructor Destroy; override; + + procedure ClearExpressions; override; + + procedure ParseExpression(AExpression: string); virtual; + function ExtractFromBuffer(Buffer: TRecordBuffer): PChar; virtual; + + property DbfFile: Pointer read FDbfFile write FDbfFile; + property Expression: string read FCurrentExpression; + property ResultLen: Integer read GetResultLen; + + property CaseInsensitive: Boolean read FCaseInsensitive write SetCaseInsensitive; + property StringFieldMode: TStringFieldMode read FStringFieldMode write SetStringFieldMode; + property PartialMatch: boolean read FPartialMatch write SetPartialMatch; + end; + +implementation + +uses + mdbf, + dbf_dbffile, + dbf_str +{$ifdef WINDOWS} + ,Windows +{$endif} + ; + +type +// TFieldVar aids in retrieving field values from records +// in their proper type + + TFieldVar = class(TObject) + private + FFieldDef: TDbfFieldDef; + FDbfFile: TDbfFile; + FFieldName: string; + FExprWord: TExprWord; + protected + function GetFieldVal: Pointer; virtual; abstract; + function GetFieldType: TExpressionType; virtual; abstract; + procedure SetExprWord(NewExprWord: TExprWord); virtual; + + property ExprWord: TExprWord read FExprWord write SetExprWord; + public + constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile); + + procedure Refresh(Buffer: TRecordBuffer); virtual; abstract; + + property FieldVal: Pointer read GetFieldVal; + property FieldDef: TDbfFieldDef read FFieldDef; + property FieldType: TExpressionType read GetFieldType; + property DbfFile: TDbfFile read FDbfFile; + property FieldName: string read FFieldName; + end; + + TStringFieldVar = class(TFieldVar) + protected + FFieldVal: PChar; + FMode: TStringFieldMode; + + function GetFieldVal: Pointer; override; + function GetFieldType: TExpressionType; override; + procedure SetExprWord(NewExprWord: TExprWord); override; + procedure SetMode(NewMode: TStringFieldMode); + procedure UpdateExprWord; + public + destructor Destroy; override; + + procedure Refresh(Buffer: TRecordBuffer); override; + + property Mode: TStringFieldMode read FMode write SetMode; + end; + + TFloatFieldVar = class(TFieldVar) + private + FFieldVal: Double; + protected + function GetFieldVal: Pointer; override; + function GetFieldType: TExpressionType; override; + public + procedure Refresh(Buffer: TRecordBuffer); override; + end; + + TIntegerFieldVar = class(TFieldVar) + private + FFieldVal: Integer; + protected + function GetFieldVal: Pointer; override; + function GetFieldType: TExpressionType; override; + public + procedure Refresh(Buffer: TRecordBuffer); override; + end; + +{$ifdef SUPPORT_INT64} + TLargeIntFieldVar = class(TFieldVar) + private + FFieldVal: Int64; + protected + function GetFieldVal: Pointer; override; + function GetFieldType: TExpressionType; override; + public + procedure Refresh(Buffer: TRecordBuffer); override; + end; +{$endif} + + TDateTimeFieldVar = class(TFieldVar) + private + FFieldVal: TDateTimeRec; + protected + function GetFieldType: TExpressionType; override; + function GetFieldVal: Pointer; override; + public + procedure Refresh(Buffer: TRecordBuffer); override; + end; + + TBooleanFieldVar = class(TFieldVar) + private + FFieldVal: boolean; + protected + function GetFieldType: TExpressionType; override; + function GetFieldVal: Pointer; override; + public + procedure Refresh(Buffer: TRecordBuffer); override; + end; + +{ TFieldVar } + +constructor TFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile); +begin + inherited Create; + + // store field + FFieldDef := UseFieldDef; + FDbfFile := ADbfFile; + FFieldName := UseFieldDef.FieldName; +end; + +procedure TFieldVar.SetExprWord(NewExprWord: TExprWord); +begin + FExprWord := NewExprWord; +end; + +{ TStringFieldVar } + +destructor TStringFieldVar.Destroy; +begin + if FMode <> smRaw then + FreeMem(FFieldVal); + + inherited; +end; + +function TStringFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TStringFieldVar.GetFieldType: TExpressionType; +begin + Result := etString; +end; + +procedure TStringFieldVar.Refresh(Buffer: TRecordBuffer); +var + Len: Integer; + Src: TRecordBuffer; +begin + Src := Buffer+FieldDef.Offset; + if FMode <> smRaw then + begin + // copy field data + Len := FieldDef.Size; + if FMode = smAnsiTrim then + while (Len >= 1) and (Src[Len-1] = TRecordbufferbasetype(' ')) do Dec(Len); + // translate to ANSI + Len := TranslateString(DbfFile.UseCodePage, GetACP, pansichar(Src), FFieldVal, Len); + FFieldVal[Len] := #0; + end else + FFieldVal := pansichar(Src); +end; + +procedure TStringFieldVar.SetExprWord(NewExprWord: TExprWord); +begin + inherited; + UpdateExprWord; +end; + +procedure TStringFieldVar.UpdateExprWord; +begin + if FMode <> smAnsiTrim then + FExprWord.FixedLen := FieldDef.Size + else + FExprWord.FixedLen := -1; +end; + +procedure TStringFieldVar.SetMode(NewMode: TStringFieldMode); +begin + if NewMode = FMode then exit; + FMode := NewMode; + if NewMode = smRaw then + begin + FreeMem(FFieldVal); + FFieldVal := nil; + end else + GetMem(FFieldVal, FieldDef.Size*3+1); + UpdateExprWord; +end; + +//--TFloatFieldVar----------------------------------------------------------- +function TFloatFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TFloatFieldVar.GetFieldType: TExpressionType; +begin + Result := etFloat; +end; + +procedure TFloatFieldVar.Refresh(Buffer: TRecordBuffer); +begin + // database width is default 64-bit double + if not FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal, false) then + FFieldVal := 0.0; +end; + +//--TIntegerFieldVar---------------------------------------------------------- +function TIntegerFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TIntegerFieldVar.GetFieldType: TExpressionType; +begin + Result := etInteger; +end; + +procedure TIntegerFieldVar.Refresh(Buffer: TRecordBuffer); +begin + FFieldVal := 0; + FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal, false); +end; + +{$ifdef SUPPORT_INT64} + +//--TLargeIntFieldVar---------------------------------------------------------- +function TLargeIntFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TLargeIntFieldVar.GetFieldType: TExpressionType; +begin + Result := etLargeInt; +end; + +procedure TLargeIntFieldVar.Refresh(Buffer: TRecordBuffer); +begin + if not FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal, false) then + FFieldVal := 0; +end; + +{$endif} + +//--TDateTimeFieldVar--------------------------------------------------------- +function TDateTimeFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TDateTimeFieldVar.GetFieldType: TExpressionType; +begin + Result := etDateTime; +end; + +procedure TDateTimeFieldVar.Refresh(Buffer: TRecordBuffer); +begin + if not FDbfFile.GetFieldDataFromDef(FieldDef, ftDateTime, Buffer, @FFieldVal, false) then + FFieldVal.DateTime := 0.0; +end; + +//--TBooleanFieldVar--------------------------------------------------------- +function TBooleanFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TBooleanFieldVar.GetFieldType: TExpressionType; +begin + Result := etBoolean; +end; + +procedure TBooleanFieldVar.Refresh(Buffer: TRecordBuffer); +var + lFieldVal: word; +begin + if FDbfFile.GetFieldDataFromDef(FieldDef, ftBoolean, Buffer, @lFieldVal, false) then + FFieldVal := lFieldVal <> 0 + else + FFieldVal := false; +end; + +//--TDbfParser--------------------------------------------------------------- + +constructor TDbfParser.Create(ADbfFile: Pointer); +begin + FDbfFile := ADbfFile; + FFieldVarList := TStringList.Create; + FCaseInsensitive := true; + inherited Create; +end; + +destructor TDbfParser.Destroy; +begin + ClearExpressions; + inherited; + FreeAndNil(FFieldVarList); +end; + +function TDbfParser.GetResultType: TExpressionType; +begin + // if not a real expression, return type ourself + if FIsExpression then + Result := inherited GetResultType + else + Result := FFieldType; +end; + +function TDbfParser.GetResultLen: Integer; +begin + // set result len for fixed length expressions / fields + case ResultType of + etBoolean: Result := 1; + etInteger: Result := 4; + etFloat: Result := 8; + etDateTime: Result := 8; + etString: + begin + if not FIsExpression and (TStringFieldVar(FFieldVarList.Objects[0]).Mode <> smAnsiTrim) then + Result := TStringFieldVar(FFieldVarList.Objects[0]).FieldDef.Size + else + Result := -1; + end; + else + Result := -1; + end; +end; + +procedure TDbfParser.SetCaseInsensitive(NewInsensitive: Boolean); +begin + if FCaseInsensitive <> NewInsensitive then + begin + // clear and regenerate functions + FCaseInsensitive := NewInsensitive; + FillExpressList; + end; +end; + +procedure TDbfParser.SetPartialMatch(NewPartialMatch: boolean); +begin + if FPartialMatch <> NewPartialMatch then + begin + // refill function list + FPartialMatch := NewPartialMatch; + FillExpressList; + end; +end; + +procedure TDbfParser.SetStringFieldMode(NewMode: TStringFieldMode); +var + I: integer; +begin + if FStringFieldMode <> NewMode then + begin + // clear and regenerate functions, custom fields will be deleted too + FStringFieldMode := NewMode; + for I := 0 to FFieldVarList.Count - 1 do + if FFieldVarList.Objects[I] is TStringFieldVar then + TStringFieldVar(FFieldVarList.Objects[I]).Mode := NewMode; + end; +end; + +procedure TDbfParser.FillExpressList; +var + lExpression: string; +begin + lExpression := FCurrentExpression; + ClearExpressions; + FWordsList.FreeAll; + FWordsList.AddList(DbfWordsGeneralList, 0, DbfWordsGeneralList.Count - 1); + if FCaseInsensitive then + begin + FWordsList.AddList(DbfWordsInsensGeneralList, 0, DbfWordsInsensGeneralList.Count - 1); + if FPartialMatch then + begin + FWordsList.AddList(DbfWordsInsensPartialList, 0, DbfWordsInsensPartialList.Count - 1); + end else begin + FWordsList.AddList(DbfWordsInsensNoPartialList, 0, DbfWordsInsensNoPartialList.Count - 1); + end; + end else begin + FWordsList.AddList(DbfWordsSensGeneralList, 0, DbfWordsSensGeneralList.Count - 1); + if FPartialMatch then + begin + FWordsList.AddList(DbfWordsSensPartialList, 0, DbfWordsSensPartialList.Count - 1); + end else begin + FWordsList.AddList(DbfWordsSensNoPartialList, 0, DbfWordsSensNoPartialList.Count - 1); + end; + end; + if Length(lExpression) > 0 then + ParseExpression(lExpression); +end; + +function TDbfParser.GetVariableInfo(VarName: string): TDbfFieldDef; +begin + Result := TDbfFile(FDbfFile).GetFieldInfo(VarName); +end; + +procedure TDbfParser.HandleUnknownVariable(VarName: string); +var + FieldInfo: TDbfFieldDef; + TempFieldVar: TFieldVar; +begin + // is this variable a fieldname? + FieldInfo := GetVariableInfo(VarName); + if FieldInfo = nil then + raise EDbfError.CreateFmt(STRING_INDEX_BASED_ON_UNKNOWN_FIELD, [VarName]); + + // define field in parser + case FieldInfo.FieldType of + ftString: + begin + TempFieldVar := TStringFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineStringVariable(VarName, TempFieldVar.FieldVal); + TStringFieldVar(TempFieldVar).Mode := FStringFieldMode; + end; + ftBoolean: + begin + TempFieldVar := TBooleanFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineBooleanVariable(VarName, TempFieldVar.FieldVal); + end; + ftFloat: + begin + TempFieldVar := TFloatFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineFloatVariable(VarName, TempFieldVar.FieldVal); + end; + ftAutoInc, ftInteger, ftSmallInt: + begin + TempFieldVar := TIntegerFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineIntegerVariable(VarName, TempFieldVar.FieldVal); + end; +{$ifdef SUPPORT_INT64} + ftLargeInt: + begin + TempFieldVar := TLargeIntFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineLargeIntVariable(VarName, TempFieldVar.FieldVal); + end; +{$endif} + ftDate, ftDateTime: + begin + TempFieldVar := TDateTimeFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineDateTimeVariable(VarName, TempFieldVar.FieldVal); + end; + else + raise EDbfError.CreateFmt(STRING_INDEX_BASED_ON_INVALID_FIELD, [VarName]); + end; + + // add to our own list + FFieldVarList.AddObject(VarName, TempFieldVar); +end; + +function TDbfParser.CurrentExpression: string; +begin + Result := FCurrentExpression; +end; + +procedure TDbfParser.ClearExpressions; +var + I: Integer; +begin + inherited; + + // test if already freed + if FFieldVarList <> nil then + begin + // free field list + for I := 0 to FFieldVarList.Count - 1 do + begin + // replacing with nil = undefining variable + FWordsList.DoFree(TFieldVar(FFieldVarList.Objects[I]).FExprWord); + TFieldVar(FFieldVarList.Objects[I]).Free; + end; + FFieldVarList.Clear; + end; + + // clear expression + FCurrentExpression := EmptyStr; +end; + +procedure TDbfParser.ValidateExpression(AExpression: string); +begin +end; + +procedure TDbfParser.ParseExpression(AExpression: string); +begin + // clear any current expression + ClearExpressions; + + // is this a simple field or complex expression? + FIsExpression := GetVariableInfo(AExpression) = nil; + if FIsExpression then + begin + // parse requested + CompileExpression(AExpression); + end else begin + // simple field, create field variable for it + HandleUnknownVariable(AExpression); + FFieldType := TFieldVar(FFieldVarList.Objects[0]).FieldType; + end; + + ValidateExpression(AExpression); + + // if no errors, assign current expression + FCurrentExpression := AExpression; +end; + +function TDbfParser.ExtractFromBuffer(Buffer: TRecordBuffer): PChar; +var + I: Integer; +begin + // prepare all field variables + for I := 0 to FFieldVarList.Count - 1 do + TFieldVar(FFieldVarList.Objects[I]).Refresh(Buffer); + + // complex expression? + if FIsExpression then + begin + // execute expression + EvaluateCurrent; + Result := ExpResult; + end else begin + // simple field, get field result + Result := TFieldVar(FFieldVarList.Objects[0]).FieldVal; + // if string then dereference + if FFieldType = etString then + Result := PPChar(Result)^; + end; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_pgcfile.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_pgcfile.pas new file mode 100644 index 0000000..01aa02a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_pgcfile.pas @@ -0,0 +1,232 @@ +unit dbf_pgcfile; + +// paged, cached file + +interface + +{$I dbf_common.inc} + +{$ifdef USE_CACHE} + +uses + classes,mclasses + SysUtils, + dbf_common, + dbf_avl, + dbf_pgfile; + +type + + PPageInfo = ^TPageInfo; + TPageInfo = record + TimeStamp: Cardinal; + Modified: Boolean; + Data: Char; + end; + + TCachedFile = class(TPagedFile) + private + FPageTree: TAvlTree; + FUseTree: TAvlTree; + FTimeStamp: Cardinal; + FPageInfoSize: Integer; + FCacheSize: Integer; + FMaxPages: Cardinal; + + function GetTimeStamp: Cardinal; + procedure UpdateTimeStamp(RecNo: Integer; Data: PPageInfo); + procedure PageDeleted(Sender: TAvlTree; Data: PData); + procedure UpdateMaxPages; + function AddToCache(RecNo: Integer; Buffer: Pointer): PPageInfo; + protected + procedure SetRecordSize(NewValue: Integer); override; + procedure SetCacheSize(NewSize: Integer); + public + constructor Create; + destructor Destroy; override; + + procedure CloseFile; override; + procedure Flush; override; + + function ReadRecord(RecNo: Integer; Buffer: Pointer): Integer; override; + procedure WriteRecord(RecNo: Integer; Buffer: Pointer); override; + + property CacheSize: Integer read FCacheSize write SetCacheSize; + end; + +{$endif} + +implementation + +{$ifdef USE_CACHE} + +constructor TCachedFile.Create; +begin + inherited; + + FPageTree := TAvlTree.Create; + FPageTree.OnDelete := PageDeleted; + FUseTree := TAvlTree.Create; + FPageInfoSize := 0; + FTimeStamp := 0; + FCacheSize := 256 * 1024; +end; + +destructor TCachedFile.Destroy; +begin + Flush; + + FPageTree.Free; + FUseTree.Free; + FPageTree := nil; + FUseTree := nil; + + inherited; +end; + +procedure TCachedFile.Flush; +begin + if FPageTree <> nil then + begin + FPageTree.Clear; + FUseTree.Clear; + end; + FTimeStamp := 0; +end; + +procedure TCachedFile.CloseFile; +begin + // flush modified pages to disk + Flush; + + // now we can safely close + inherited; +end; + +procedure TCachedFile.SetRecordSize(NewValue: Integer); +begin + inherited; + + // first flush all pages, restart caching with new parameters + Flush; + + // calculate size of extra data of pagetree + FPageInfoSize := SizeOf(TPageInfo) - SizeOf(Char) + RecordSize; + UpdateMaxPages; +end; + +procedure TCachedFile.SetCacheSize(NewSize: Integer); +begin + if FCacheSize <> NewSize then + begin + FCacheSize := NewSize; + UpdateMaxPages; + end; +end; + +procedure TCachedFile.UpdateMaxPages; +begin + if RecordSize = 0 then + FMaxPages := 0 + else + FMaxPages := FCacheSize div RecordSize; +end; + +function TCachedFile.GetTimeStamp: Cardinal; +begin + Result := FTimeStamp; + Inc(FTimeStamp); +end; + +procedure TCachedFile.PageDeleted(Sender: TAvlTree; Data: PData); +begin + // data modified? write to disk + if PPageInfo(Data^.ExtraData)^.Modified then + inherited WriteRecord(Data^.ID, @PPageInfo(Data^.ExtraData)^.Data); + + // free cached page mem + FreeMem(Data^.ExtraData); +end; + +function TCachedFile.AddToCache(RecNo: Integer; Buffer: Pointer): PPageInfo; +var + oldData: PData; +begin + // make sure there is a free page in the cache + while FPageTree.Count >= FMaxPages do + begin + // no free space, find oldest page + oldData := FUseTree.Lowest; + // remove from cache + FPageTree.Delete(Integer(oldData^.ExtraData)); + FUseTree.Delete(oldData^.ID); + end; + // add to cache + GetMem(Result, FPageInfoSize); + Result^.TimeStamp := GetTimeStamp; + Result^.Modified := false; + Move(Buffer^, Result^.Data, RecordSize); + FPageTree.Insert(RecNo, Result); + FUseTree.Insert(Result^.TimeStamp, Pointer(RecNo)); +end; + +procedure TCachedFile.UpdateTimeStamp(RecNo: Integer; Data: PPageInfo); +begin + // update time used + FUseTree.Delete(Data^.TimeStamp); + Data^.TimeStamp := GetTimeStamp; + FUseTree.Insert(Data^.TimeStamp, Pointer(RecNo)); +end; + +function TCachedFile.ReadRecord(RecNo: Integer; Buffer: Pointer): Integer; +var + Data: PPageInfo; +begin + // only cache when we do not need locking + if NeedLocks then + begin Result := inherited ReadRecord(RecNo, Buffer) end else begin + // do we have this page in cache? + Data := PPageInfo(FPageTree.Find(RecNo)); + if Data <> nil then + begin + // copy from cache + Move(Data^.Data, Buffer^, RecordSize); + UpdateTimeStamp(RecNo, Data); + Result := RecordSize; + end else begin + // not yet in cache + Result := inherited ReadRecord(RecNo, Buffer); + // add + if Result > 0 then + AddToCache(RecNo, Buffer); + end; + end; +end; + +procedure TCachedFile.WriteRecord(RecNo: Integer; Buffer: Pointer); +var + Data: PPageInfo; +begin + // only cache when we do not need locking + if NeedLocks then + begin inherited end else begin + // do we have this page in cache? + Data := PPageInfo(FPageTree.Find(RecNo)); + if Data <> nil then + begin + // copy to cache + Move(Buffer^, Data^.Data, RecordSize); + UpdateTimeStamp(RecNo, Data); + end else begin + // add + Data := AddToCache(RecNo, Buffer); + // notify we've added a page + UpdateCachedSize(CalcPageOffset(RecNo+PagesPerRecord)); + end; + Data^.Modified := true; + end; +end; + +{$endif} // USE_CACHE + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_pgfile.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_pgfile.pas new file mode 100644 index 0000000..fa0c480 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_pgfile.pas @@ -0,0 +1,927 @@ +unit dbf_pgfile; + +interface + +{$I dbf_common.inc} + +uses + classes,mclasses, + SysUtils, + dbf_common; + +//const +// MaxHeaders = 256; + +type + EPagedFile = Exception; + + TPagedFileMode = (pfNone, pfMemoryCreate, pfMemoryOpen, pfExclusiveCreate, + pfExclusiveOpen, pfReadWriteCreate, pfReadWriteOpen, pfReadOnly); + + // access levels: + // + // - memory create + // - exclusive create/open + // - read/write create/open + // - readonly open + // + // - memory -*-share: N/A -*-locks: disabled -*-indexes: read/write + // - exclusive_create -*-share: deny write -*-locks: disabled -*-indexes: read/write + // - exclusive_open -*-share: deny write -*-locks: disabled -*-indexes: read/write + // - readwrite_create -*-share: deny none -*-locks: enabled -*-indexes: read/write + // - readwrite_open -*-share: deny none -*-locks: enabled -*-indexes: read/write + // - readonly -*-share: deny none -*-locks: disabled -*-indexes: readonly + + TPagedFile = class(TObject) + protected + FStream: TStream; + FHeaderOffset: Integer; + FHeaderSize: Integer; + FRecordSize: Integer; + FPageSize: Integer; { need for MDX, where recordsize <> pagesize } + FRecordCount: Integer; { actually FPageCount, but we want to keep existing code } + FPagesPerRecord: Integer; + FCachedSize: Integer; + FCachedRecordCount: Integer; + FHeader: PChar; + FActive: Boolean; + FNeedRecalc: Boolean; + FHeaderModified: Boolean; + FPageOffsetByHeader: Boolean; { do pages start after header or just at BOF? } + FMode: TPagedFileMode; + FTempMode: TPagedFileMode; + FUserMode: TPagedFileMode; + FAutoCreate: Boolean; + FNeedLocks: Boolean; + FVirtualLocks: Boolean; + FFileLocked: Boolean; + FFileName: string; + FBufferPtr: Pointer; + FBufferAhead: Boolean; + FBufferPage: Integer; + FBufferOffset: Integer; + FBufferSize: Integer; + FBufferReadSize: Integer; + FBufferMaxSize: Integer; + FBufferModified: Boolean; + FWriteError: Boolean; + protected + procedure SetHeaderOffset(NewValue: Integer); virtual; + procedure SetRecordSize(NewValue: Integer); virtual; + procedure SetHeaderSize(NewValue: Integer); virtual; + procedure SetPageSize(NewValue: Integer); + procedure SetPageOffsetByHeader(NewValue: Boolean); virtual; + procedure SetRecordCount(NewValue: Integer); + procedure SetBufferAhead(NewValue: Boolean); + procedure SetFileName(NewName: string); + procedure SetStream(NewStream: TStream); + function LockSection(const Offset, Length: Cardinal; const Wait: Boolean): Boolean; virtual; + function UnlockSection(const Offset, Length: Cardinal): Boolean; virtual; + procedure UpdateBufferSize; + procedure RecalcPagesPerRecord; + procedure ReadHeader; + procedure FlushHeader; + procedure FlushBuffer; + function ReadChar: Byte; + procedure WriteChar(c: Byte); + procedure CheckCachedSize(const APosition: Integer); + procedure SynchronizeBuffer(IntRecNum: Integer); + function Read(Buffer: Pointer; ASize: Integer): Integer; + function ReadBlock(const BlockPtr: Pointer; const ASize, APosition: Integer): Integer; + function SingleReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; + procedure WriteBlock(const BlockPtr: Pointer; const ASize, APosition: Integer); + procedure SingleWriteRecord(IntRecNum: Integer; Buffer: Pointer); + function GetRecordCount: Integer; + procedure UpdateCachedSize(CurrPos: Integer); + + property VirtualLocks: Boolean read FVirtualLocks write FVirtualLocks; + public + constructor Create; + destructor Destroy; override; + + procedure CloseFile; virtual; + procedure OpenFile; virtual; + procedure DeleteFile; + procedure TryExclusive; virtual; + procedure EndExclusive; virtual; + procedure CheckExclusiveAccess; + procedure DisableForceCreate; + function CalcPageOffset(const PageNo: Integer): Integer; + function IsRecordPresent(IntRecNum: Integer): boolean; + function ReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; virtual; + procedure WriteRecord(IntRecNum: Integer; Buffer: Pointer); virtual; + procedure WriteHeader; virtual; + function FileCreated: Boolean; + function IsSharedAccess: Boolean; + procedure ResetError; + + function LockPage(const PageNo: Integer; const Wait: Boolean): Boolean; + function LockAllPages(const Wait: Boolean): Boolean; + procedure UnlockPage(const PageNo: Integer); + procedure UnlockAllPages; + + procedure Flush; virtual; + + property Active: Boolean read FActive; + property AutoCreate: Boolean read FAutoCreate write FAutoCreate; // only write when closed! + property Mode: TPagedFileMode read FMode write FMode; // only write when closed! + property TempMode: TPagedFileMode read FTempMode; + property NeedLocks: Boolean read FNeedLocks; + property HeaderOffset: Integer read FHeaderOffset write SetHeaderOffset; + property HeaderSize: Integer read FHeaderSize write SetHeaderSize; + property RecordSize: Integer read FRecordSize write SetRecordSize; + property PageSize: Integer read FPageSize write SetPageSize; + property PagesPerRecord: Integer read FPagesPerRecord; + property RecordCount: Integer read GetRecordCount write SetRecordCount; + property CachedRecordCount: Integer read FCachedRecordCount; + property PageOffsetByHeader: Boolean read FPageOffsetbyHeader write SetPageOffsetByHeader; + property FileLocked: Boolean read FFileLocked; + property Header: PChar read FHeader; + property FileName: string read FFileName write SetFileName; + property Stream: TStream read FStream write SetStream; + property BufferAhead: Boolean read FBufferAhead write SetBufferAhead; + property WriteError: Boolean read FWriteError; + end; + +implementation + +uses +{$ifdef WINDOWS} + Windows, +{$else} +{$ifdef KYLIX} + Libc, +{$endif} + Types, dbf_wtil, +{$endif} + dbf_str; + +//==================================================================== +// TPagedFile +//==================================================================== +constructor TPagedFile.Create; +begin + FFileName := EmptyStr; + FHeaderOffset := 0; + FHeaderSize := 0; + FRecordSize := 0; + FRecordCount := 0; + FPageSize := 0; + FPagesPerRecord := 0; + FActive := false; + FHeaderModified := false; + FPageOffsetByHeader := true; + FNeedLocks := false; + FMode := pfReadOnly; + FTempMode := pfNone; + FAutoCreate := false; + FVirtualLocks := true; + FFileLocked := false; + FHeader := nil; + FBufferPtr := nil; + FBufferAhead := false; + FBufferModified := false; + FBufferSize := 0; + FBufferMaxSize := 0; + FBufferOffset := 0; + FWriteError := false; + + inherited; +end; + +destructor TPagedFile.Destroy; +begin + // close physical file + if FFileLocked then UnlockAllPages; + CloseFile; + FFileLocked := false; + + // free mem + if FHeader <> nil then + FreeMem(FHeader); + + inherited; +end; + +procedure TPagedFile.OpenFile; +var + fileOpenMode: Word; +begin + if FActive then exit; + + // store user specified mode + FUserMode := FMode; + if not (FMode in [pfMemoryCreate, pfMemoryOpen]) then + begin + // test if file exists + if not FileExists(FFileName) then + begin + // if auto-creating, adjust mode + if FAutoCreate then case FMode of + pfExclusiveOpen: FMode := pfExclusiveCreate; + pfReadWriteOpen, pfReadOnly: FMode := pfReadWriteCreate; + end; + // it seems the VCL cannot share a file that is created? + // create file first, then open it in requested mode + // filecreated means 'to be created' in this context ;-) + if FileCreated then + FileClose(FileCreate(FFileName)) + else + raise EPagedFile.CreateFmt(STRING_FILE_NOT_FOUND,[FFileName]); + end; + // specify open mode + case FMode of + pfExclusiveCreate: fileOpenMode := fmOpenReadWrite or fmShareDenyWrite; + pfExclusiveOpen: fileOpenMode := fmOpenReadWrite or fmShareDenyWrite; + pfReadWriteCreate: fileOpenMode := fmOpenReadWrite or fmShareDenyNone; + pfReadWriteOpen: fileOpenMode := fmOpenReadWrite or fmShareDenyNone; + else // => readonly + fileOpenMode := fmOpenRead or fmShareDenyNone; + end; + // open file + FStream := TFileStream.Create(FFileName, fileOpenMode); + // if creating, then empty file + if FileCreated then + FStream.Size := 0; + end else begin + if FStream = nil then + begin + FMode := pfMemoryCreate; + FStream := TMemoryStream.Create; + end; + end; + // init size var + FCachedSize := Stream.Size; + // update whether we need locking +{$ifdef _DEBUG} + FNeedLocks := true; +{$else} + FNeedLocks := IsSharedAccess; +{$endif} + FActive := true; + // allocate memory for bufferahead + UpdateBufferSize; +end; + +procedure TPagedFile.CloseFile; +begin + if FActive then + begin + FlushHeader; + FlushBuffer; + // don't free the user's stream + if not (FMode in [pfMemoryOpen, pfMemoryCreate]) then + FreeAndNil(FStream); + // free bufferahead buffer + FreeMemAndNil(FBufferPtr); + + // mode possibly overridden in case of auto-created file + FMode := FUserMode; + FActive := false; + FCachedRecordCount := 0; + end; +end; + +procedure TPagedFile.DeleteFile; +begin + // opened -> we can not delete + if not FActive then + SysUtils.DeleteFile(FileName); +end; + +function TPagedFile.FileCreated: Boolean; +const + CreationModes: array [pfNone..pfReadOnly] of Boolean = + (false, true, false, true, false, true, false, false); +// node, memcr, memop, excr, exopn, rwcr, rwopn, rdonly +begin + Result := CreationModes[FMode]; +end; + +function TPagedFile.IsSharedAccess: Boolean; +const + SharedAccessModes: array [pfNone..pfReadOnly] of Boolean = + (false, false, false, false, false, true, true, true); +// node, memcr, memop, excr, exopn, rwcr, rwopn, rdonly +begin + Result := SharedAccessModes[FMode]; +end; + +procedure TPagedFile.CheckExclusiveAccess; +begin + // in-memory => exclusive access! + if IsSharedAccess then + raise EDbfError.Create(STRING_NEED_EXCLUSIVE_ACCESS); +end; + +function TPagedFile.CalcPageOffset(const PageNo: Integer): Integer; +begin + if not FPageOffsetByHeader then + Result := FPageSize * PageNo + else if PageNo = 0 then + Result := 0 + else + Result := FHeaderOffset + FHeaderSize + (FPageSize * (PageNo - 1)) +end; + +procedure TPagedFile.CheckCachedSize(const APosition: Integer); +begin + // file expanded? + if APosition > FCachedSize then + begin + FCachedSize := APosition; + FNeedRecalc := true; + end; +end; + +function TPagedFile.Read(Buffer: Pointer; ASize: Integer): Integer; +begin + // if we cannot read due to a lock, then wait a bit + repeat + Result := FStream.Read(Buffer^, ASize); + if Result = 0 then + begin + // translation to linux??? + if GetLastError = ERROR_LOCK_VIOLATION then + begin + // wait a bit until block becomes available + Sleep(1); + end else begin + // return empty block + exit; + end; + end else + exit; + until false; +end; + +procedure TPagedFile.UpdateCachedSize(CurrPos: Integer); +begin + // have we added a record? + if CurrPos > FCachedSize then + begin + // update cached size, always at end + repeat + Inc(FCachedSize, FRecordSize); + Inc(FRecordCount, PagesPerRecord); + until FCachedSize >= CurrPos; + end; +end; + +procedure TPagedFile.FlushBuffer; +begin + if FBufferAhead and FBufferModified then + begin + WriteBlock(FBufferPtr, FBufferSize, FBufferOffset); + FBufferModified := false; + end; +end; + +function TPagedFile.SingleReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; +begin + Result := ReadBlock(Buffer, RecordSize, CalcPageOffset(IntRecNum)); +end; + +procedure TPagedFile.SingleWriteRecord(IntRecNum: Integer; Buffer: Pointer); +begin + WriteBlock(Buffer, RecordSize, CalcPageOffset(IntRecNum)); +end; + +procedure TPagedFile.SynchronizeBuffer(IntRecNum: Integer); +begin + // record outside buffer, flush previous buffer + FlushBuffer; + // read new set of records + FBufferPage := IntRecNum; + FBufferOffset := CalcPageOffset(IntRecNum); + if FBufferOffset + FBufferMaxSize > FCachedSize then + FBufferReadSize := FCachedSize - FBufferOffset + else + FBufferReadSize := FBufferMaxSize; + FBufferSize := FBufferReadSize; + FBufferReadSize := ReadBlock(FBufferPtr, FBufferReadSize, FBufferOffset); +end; + +function TPagedFile.IsRecordPresent(IntRecNum: Integer): boolean; +begin + // if in shared mode, recordcount can only increase, check if recordno + // in range for cached recordcount + if not IsSharedAccess or (IntRecNum > FCachedRecordCount) then + FCachedRecordCount := RecordCount; + Result := (0 <= IntRecNum) and (IntRecNum <= FCachedRecordCount); +end; + +function TPagedFile.ReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; +var + Offset: Integer; +begin + if FBufferAhead then + begin + Offset := (IntRecNum - FBufferPage) * PageSize; + if (FBufferPage <> -1) and (FBufferPage <= IntRecNum) and + (Offset+RecordSize <= FBufferReadSize) then + begin + // have record in buffer, nothing to do here + end else begin + // need to update buffer + SynchronizeBuffer(IntRecNum); + // check if enough bytes read + if RecordSize > FBufferReadSize then + begin + Result := 0; + exit; + end; + // reset offset into buffer + Offset := 0; + end; + // now we have this record in buffer + Move(PChar(FBufferPtr)[Offset], Buffer^, RecordSize); + // successful + Result := RecordSize; + end else begin + // no buffering + Result := SingleReadRecord(IntRecNum, Buffer); + end; +end; + +procedure TPagedFile.WriteRecord(IntRecNum: Integer; Buffer: Pointer); +var + RecEnd: Integer; +begin + if FBufferAhead then + begin + RecEnd := (IntRecNum - FBufferPage + PagesPerRecord) * PageSize; + if (FBufferPage <> -1) and (FBufferPage <= IntRecNum) and + (RecEnd <= FBufferMaxSize) then + begin + // extend buffer? + if RecEnd > FBufferSize then + FBufferSize := RecEnd; + end else begin + // record outside buffer, need to synchronize first + SynchronizeBuffer(IntRecNum); + RecEnd := PagesPerRecord * PageSize; + end; + // we can write this record to buffer + Move(Buffer^, PChar(FBufferPtr)[RecEnd-RecordSize], RecordSize); + FBufferModified := true; + // update cached size + UpdateCachedSize(FBufferOffset+RecEnd); + end else begin + // no buffering + SingleWriteRecord(IntRecNum, Buffer); + // update cached size + UpdateCachedSize(FStream.Position); + end; +end; + +procedure TPagedFile.SetBufferAhead(NewValue: Boolean); +begin + if FBufferAhead <> NewValue then + begin + FlushBuffer; + FBufferAhead := NewValue; + UpdateBufferSize; + end; +end; + +procedure TPagedFile.SetStream(NewStream: TStream); +begin + if not FActive then + FStream := NewStream; +end; + +procedure TPagedFile.SetFileName(NewName: string); +begin + if not FActive then + FFileName := NewName; +end; + +procedure TPagedFile.UpdateBufferSize; +begin + if FBufferAhead then + begin + FBufferMaxSize := 65536; + if RecordSize <> 0 then + Dec(FBufferMaxSize, FBufferMaxSize mod PageSize); + end else begin + FBufferMaxSize := 0; + end; + + if FBufferPtr <> nil then + FreeMem(FBufferPtr); + if FBufferAhead and (FBufferMaxSize <> 0) then + GetMem(FBufferPtr, FBufferMaxSize) + else + FBufferPtr := nil; + FBufferPage := -1; + FBufferOffset := -1; + FBufferModified := false; +end; + +procedure TPagedFile.WriteHeader; +begin + FHeaderModified := true; + if FNeedLocks then + FlushHeader; +end; + +procedure TPagedFile.FlushHeader; +begin + if FHeaderModified then + begin + FStream.Position := FHeaderOffset; + FWriteError := (FStream.Write(FHeader^, FHeaderSize) = 0) or FWriteError; + // test if written new header + if FStream.Position > FCachedSize then + begin + // new header -> record count unknown + FCachedSize := FStream.Position; + FNeedRecalc := true; + end; + FHeaderModified := false; + end; +end; + +procedure TPagedFile.ReadHeader; + { assumes header is large enough } +var + size: Integer; +begin + // save changes before reading new header + FlushHeader; + // check if header length zero + if FHeaderSize <> 0 then + begin + // get size left in file for header + size := FStream.Size - FHeaderOffset; + // header start before EOF? + if size >= 0 then + begin + // go to header start + FStream.Position := FHeaderOffset; + // whole header in file? + if size >= FHeaderSize then + begin + // read header, nothing to be cleared + Read(FHeader, FHeaderSize); + size := FHeaderSize; + end else begin + // read what we can, clear rest + Read(FHeader, size); + end; + end else begin + // header start before EOF, clear header + size := 0; + end; + FillChar(FHeader[size], FHeaderSize-size, 0); + end; +end; + +procedure TPagedFile.TryExclusive; +const NewTempMode: array[pfReadWriteCreate..pfReadOnly] of TPagedFileMode = + (pfReadWriteOpen, pfReadWriteOpen, pfReadOnly); +begin + // already in temporary exclusive mode? + if (FTempMode = pfNone) and IsSharedAccess then + begin + // save temporary mode, if now creating, then reopen non-create + FTempMode := NewTempMode[FMode]; + // try exclusive mode + CloseFile; + FMode := pfExclusiveOpen; + try + OpenFile; + except + on EFOpenError do + begin + // we failed, reopen normally + EndExclusive; + end; + end; + end; +end; + +procedure TPagedFile.EndExclusive; +begin + // are we in temporary file mode? + if FTempMode <> pfNone then + begin + CloseFile; + FMode := FTempMode; + FTempMode := pfNone; + OpenFile; + end; +end; + +procedure TPagedFile.DisableForceCreate; +begin + case FMode of + pfExclusiveCreate: FMode := pfExclusiveOpen; + pfReadWriteCreate: FMode := pfReadWriteOpen; + end; +end; + +procedure TPagedFile.SetHeaderOffset(NewValue: Integer); +// +// *) assumes is called right before SetHeaderSize +// +begin + if FHeaderOffset <> NewValue then + begin + FlushHeader; + FHeaderOffset := NewValue; + end; +end; + +procedure TPagedFile.SetHeaderSize(NewValue: Integer); +begin + if FHeaderSize <> NewValue then + begin + FlushHeader; + if (FHeader <> nil) and (NewValue <> 0) then + FreeMem(FHeader); + FHeaderSize := NewValue; + if FHeaderSize <> 0 then + GetMem(FHeader, FHeaderSize); + FNeedRecalc := true; + ReadHeader; + end; +end; + +procedure TPagedFile.SetRecordSize(NewValue: Integer); +begin + if FRecordSize <> NewValue then + begin + FRecordSize := NewValue; + FPageSize := NewValue; + FNeedRecalc := true; + RecalcPagesPerRecord; + end; +end; + +procedure TPagedFile.SetPageSize(NewValue: Integer); +begin + if FPageSize <> NewValue then + begin + FPageSize := NewValue; + FNeedRecalc := true; + RecalcPagesPerRecord; + UpdateBufferSize; + end; +end; + +procedure TPagedFile.RecalcPagesPerRecord; +begin + if FPageSize = 0 then + FPagesPerRecord := 0 + else + FPagesPerRecord := FRecordSize div FPageSize; +end; + +function TPagedFile.GetRecordCount: Integer; +var + currSize: Integer; +begin + // file size changed? + if FNeedLocks then + begin + currSize := FStream.Size; + if currSize <> FCachedSize then + begin + FCachedSize := currSize; + FNeedRecalc := true; + end; + end; + + // try to optimize speed + if FNeedRecalc then + begin + // no file? test flags + if (FPageSize = 0) or not FActive then + FRecordCount := 0 + else + if FPageOffsetByHeader then + FRecordCount := (FCachedSize - FHeaderSize - FHeaderOffset) div FPageSize + else + FRecordCount := FCachedSize div FPageSize; + if FRecordCount < 0 then + FRecordCount := 0; + + // count updated + FNeedRecalc := false; + end; + Result := FRecordCount; +end; + +procedure TPagedFile.SetRecordCount(NewValue: Integer); +begin + if RecordCount <> NewValue then + begin + if FPageOffsetByHeader then + FCachedSize := FHeaderSize + FHeaderOffset + FPageSize * NewValue + else + FCachedSize := FPageSize * NewValue; +// FCachedSize := CalcPageOffset(NewValue); + FRecordCount := NewValue; + FStream.Size := FCachedSize; + end; +end; + +procedure TPagedFile.SetPageOffsetByHeader(NewValue: Boolean); +begin + if FPageOffsetByHeader <> NewValue then + begin + FPageOffsetByHeader := NewValue; + FNeedRecalc := true; + end; +end; + +procedure TPagedFile.WriteChar(c: Byte); +begin + FWriteError := (FStream.Write(c, 1) = 0) or FWriteError; +end; + +function TPagedFile.ReadChar: Byte; +begin + Read(@Result, 1); +end; + +procedure TPagedFile.Flush; +begin +end; + +function TPagedFile.ReadBlock(const BlockPtr: Pointer; const ASize, APosition: Integer): Integer; +begin + FStream.Position := APosition; + CheckCachedSize(APosition); + Result := Read(BlockPtr, ASize); +end; + +procedure TPagedFile.WriteBlock(const BlockPtr: Pointer; const ASize, APosition: Integer); + // assumes a lock is held if necessary prior to calling this function +begin + FStream.Position := APosition; + CheckCachedSize(APosition); + FWriteError := (FStream.Write(BlockPtr^, ASize) = 0) or FWriteError; +end; + +procedure TPagedFile.ResetError; +begin + FWriteError := false; +end; + +// BDE compatible lock offset found! +const +{$ifdef WINDOWS} + LockOffset = $EFFFFFFE; // BDE compatible + FileLockSize = 2; +{$else} + LockOffset = $7FFFFFFF; + FileLockSize = 1; +{$endif} + +// dBase supports maximum of a billion records + LockStart = LockOffset - 1000000000; + +function TPagedFile.LockSection(const Offset, Length: Cardinal; const Wait: Boolean): Boolean; +{$ifndef wince} + // assumes FNeedLock = true +var + Failed: Boolean; +{$endif wince} +begin +{$ifdef wince} + Result := True; +{$else} + // FNeedLocks => FStream is of type TFileStream + Failed := false; + repeat + Result := LockFile(TFileStream(FStream).Handle, Offset, 0, Length, 0); + // test if lock violation, then wait a bit and try again + if not Result and Wait then + begin + if (GetLastError = ERROR_LOCK_VIOLATION) then + Sleep(10) + else + Failed := true; + end; + until Result or not Wait or Failed; +{$endif wince} +end; + +function TPagedFile.UnlockSection(const Offset, Length: Cardinal): Boolean; +begin +{$ifdef wince} + Result := True; +{$else} + Result := UnlockFile(TFileStream(FStream).Handle, Offset, 0, Length, 0); +{$endif wince} +end; + +function TPagedFile.LockAllPages(const Wait: Boolean): Boolean; +var + Offset: Cardinal; + Length: Cardinal; +begin + // do we need locking? + if FNeedLocks and not FFileLocked then + begin + if FVirtualLocks then + begin +{$ifdef SUPPORT_UINT32_CARDINAL} + Offset := LockStart; + Length := LockOffset - LockStart + FileLockSize; +{$else} + // delphi 3 has strange types: + // cardinal 0..2 GIG ?? does it produce correct code? + Offset := Cardinal(LockStart); + Length := Cardinal(LockOffset) - Cardinal(LockStart) + FileLockSize; +{$endif} + end else begin + Offset := 0; + Length := $7FFFFFFF; + end; + // lock requested section + Result := LockSection(Offset, Length, Wait); + FFileLocked := Result; + end else + Result := true; +end; + +procedure TPagedFile.UnlockAllPages; +var + Offset: Cardinal; + Length: Cardinal; +begin + // do we need locking? + if FNeedLocks and FFileLocked then + begin + if FVirtualLocks then + begin +{$ifdef SUPPORT_UINT32_CARDINAL} + Offset := LockStart; + Length := LockOffset - LockStart + FileLockSize; +{$else} + // delphi 3 has strange types: + // cardinal 0..2 GIG ?? does it produce correct code? + Offset := Cardinal(LockStart); + Length := Cardinal(LockOffset) - Cardinal(LockStart) + FileLockSize; +{$endif} + end else begin + Offset := 0; + Length := $7FFFFFFF; + end; + // unlock requested section + // FNeedLocks => FStream is of type TFileStream + FFileLocked := not UnlockSection(Offset, Length); + end; +end; + +function TPagedFile.LockPage(const PageNo: Integer; const Wait: Boolean): Boolean; +var + Offset: Cardinal; + Length: Cardinal; +begin + // do we need locking? + if FNeedLocks and not FFileLocked then + begin + if FVirtualLocks then + begin + Offset := LockOffset - Cardinal(PageNo); + Length := 1; + end else begin + Offset := CalcPageOffset(PageNo); + Length := RecordSize; + end; + // lock requested section + Result := LockSection(Offset, Length, Wait); + end else + Result := true; +end; + +procedure TPagedFile.UnlockPage(const PageNo: Integer); +var + Offset: Cardinal; + Length: Cardinal; +begin + // do we need locking? + if FNeedLocks and not FFileLocked then + begin + // calc offset + length + if FVirtualLocks then + begin + Offset := LockOffset - Cardinal(PageNo); + Length := 1; + end else begin + Offset := CalcPageOffset(PageNo); + Length := RecordSize; + end; + // unlock requested section + // FNeedLocks => FStream is of type TFileStream + UnlockSection(Offset, Length); + end; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_reg.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_reg.pas new file mode 100644 index 0000000..f4d6e0a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_reg.pas @@ -0,0 +1,366 @@ +unit dbf_reg; + +{=============================================================================== +|| TDbf Component || http://tdbf.sf.net || +===============================================================================} +(* + tDBF is supplied "AS IS". The author disclaims all warranties, + expressed or implied, including, without limitation, the warranties of + merchantability and or fitness for any purpose. The author assumes no + liability for damages, direct or consequential, which may result from the + use of TDBF. + + TDbf is licensed under the LGPL (lesser general public license). + + You are allowed to use this component in any project free of charge. + You are + - NOT allowed to claim that you have created this component. You are + - NOT allowed to copy this component's code into your own component and + claim that the code is your idea. + +*) + +interface + +{$I dbf_common.inc} + +procedure Register; + +implementation + +{$ifndef FPC} +{$R dbf.dcr} +{$endif} + +uses + SysUtils, + classes,mclasses, +{$ifdef KYLIX} + QGraphics, + QControls, + QForms, + QDialogs, +{$else} + Controls, + Forms, + Dialogs, +{$endif} + dbf, + dbf_dbffile, + dbf_idxfile, + dbf_fields, + dbf_common, + dbf_str +{$ifndef FPC} + ,ExptIntf +{$endif} +{$ifdef DELPHI_6} + ,DesignIntf,DesignEditors +{$else} +{$ifndef FPC} + ,DsgnIntf +{$else} + ,PropEdits + ,LazarusPackageIntf + ,LResources + {,ComponentEditors} +{$endif} +{$endif} + ; + +//========================================================== +//============ DESIGNONLY ================================== +//========================================================== +(* +//========================================================== +//============ TFilePathProperty +//========================================================== +type + TFilePathProperty = class(TStringProperty) + public + function GetValue: string; override; + end; + +function TFilePathProperty.GetValue: string; +begin + Result := inherited GetValue; + if Result = EmptyStr then + begin + SetValue(ExtractFilePath(ToolServices.GetProjectName)); + Result := inherited GetValue; + end; +end; +*) + +//========================================================== +//============ TTableNameProperty +//========================================================== +type + TTableNameProperty = class(TStringProperty) + public + procedure Edit; override; + function GetAttributes: TPropertyAttributes; override; + end; + +procedure TTableNameProperty.Edit; {override;} +var + FileOpen: TOpenDialog; + Dbf: TDbf; +begin + FileOpen := TOpenDialog.Create(Application); + try + with fileopen do begin + Dbf := GetComponent(0) as TDbf; +{$ifndef FPC} + if Dbf.FilePath = EmptyStr then + FileOpen.InitialDir := ExtractFilePath(ToolServices.GetProjectName) + else +{$endif} + FileOpen.InitialDir := Dbf.AbsolutePath; + Filename := GetValue; + Filter := 'Dbf table|*.dbf'; + if Execute then begin + SetValue(Filename); + end; + end; + finally + Fileopen.free; + end; +end; + +function TTableNameProperty.GetAttributes: TPropertyAttributes; {override;} +begin + Result := [paDialog, paRevertable]; +end; + +//========================================================== +//============ TIndexFileNameProperty +//========================================================== + +type + TIndexFileNameProperty = class(TStringProperty) + public + procedure Edit; override; + function GetAttributes: TPropertyAttributes; override; + end; + +procedure TIndexFileNameProperty.Edit; {override;} +var + FileOpen: TOpenDialog; + IndexDef: TDbfIndexDef; + Indexes: TDbfIndexDefs; + Dbf: TDbf; +begin + FileOpen := TOpenDialog.Create(Application); + try + with fileopen do begin + IndexDef := GetComponent(0) as TDbfIndexDef; + Indexes := TDbfIndexDefs(IndexDef.Collection); + Dbf := TDbf(Indexes.FOwner); + FileOpen.InitialDir := Dbf.AbsolutePath; + Filename := GetValue; + Filter := 'Simple index (ndx)|*.ndx'{|Multiple index (mdx)|*.mdx'}; + if Execute then begin + SetValue(ExtractFileName(Filename)); + end; + end; + finally + Fileopen.free; + end; +end; + +function TIndexFileNameProperty.GetAttributes: TPropertyAttributes; {override;} +begin + Result := [paDialog, paRevertable]; +end; + +//========================================================== +//============ TSortFieldProperty +//========================================================== + +type + TSortFieldProperty = class(TStringProperty) + public + function GetAttributes: TPropertyAttributes; override; + procedure GetValues(Proc: TGetStrProc); override; + end; + + +function TSortFieldProperty.GetAttributes: TPropertyAttributes; {override;} +begin + Result := [paValueList, paSortList, paRevertable]; +end; + +procedure TSortFieldProperty.GetValues(Proc: TGetStrProc); +var + IndexDef: TDbfIndexDef; + Indexes: TDbfIndexDefs; + Dbf: TDbf; + I: integer; +begin + IndexDef := GetComponent(0) as TDbfIndexDef; + Indexes := TDbfIndexDefs(IndexDef.Collection); + Dbf := TDbf(Indexes.FOwner); + for I := 0 to Dbf.FieldCount-1 do + begin + Proc(Dbf.Fields[i].FieldName); + end; +end; + +//========================================================== +//============ TIndexNameProperty +//========================================================== + +type + TIndexNameProperty = class(TStringProperty) + public + function GetAttributes: TPropertyAttributes; override; + procedure GetValues(Proc: TGetStrProc); override; + procedure SetValue(const Value: string); override; + function GetValue: string; override; + end; + +function TIndexNameProperty.GetAttributes: TPropertyAttributes; {override;} +begin + Result := [paValueList, paRevertable]; +end; + +procedure TIndexNameProperty.GetValues(Proc: TGetStrProc); +var + Dbf: TDbf; + I: Integer; +begin + Dbf := GetComponent(0) as TDbf; + Dbf.UpdateIndexDefs; + for I := 0 to Dbf.Indexes.Count - 1 do + Proc(Dbf.Indexes[I].IndexFile); +end; + +procedure TIndexNameProperty.SetValue(const Value: string); {override} +var + Dbf: TDbf; +begin + Dbf := GetComponent(0) as TDbf; + Dbf.IndexName := Value; +end; + +function TIndexNameProperty.GetValue: string; {override;} +var + Dbf: TDbf; +begin + Dbf := GetComponent(0) as TDbf; + Result := Dbf.IndexName; +end; + +//========================================================== +//============ TVersionProperty +//========================================================== +type + TVersionProperty = class(TStringProperty) + public + procedure Edit; override; + function GetAttributes: TPropertyAttributes; override; + end; + +procedure TVersionProperty.Edit; {override;} +begin + ShowMessage( + Format(STRING_VERSION,[TDBF_MAJOR_VERSION, TDBF_MINOR_VERSION]) + + ' : a dBase component'+#13+ + 'for Delphi and c++ builder with no BDE.'+#13+ + #13 + + 'To get the latest version, please visit'+#13+ + 'the website: http://www.tdbf.net'+#13+ + 'or SourceForge: http://tdbf.sf.net'); +end; + +function TVersionProperty.GetAttributes: TPropertyAttributes; {override;} +begin + Result := [paDialog, paReadOnly, paRevertable]; +end; + +//========================================================== +//============ TNativeFieldTypeProperty +//========================================================== +type + TNativeFieldTypeProperty = class(TCharProperty) + public + function GetAttributes: TPropertyAttributes; override; + procedure GetValues(Proc: TGetStrProc); override; + procedure SetValue(const Value: string); override; + end; + +procedure TNativeFieldTypeProperty.SetValue(const Value: string); +var + L: Longint; +begin + if Length(Value) = 0 then L := 0 else + if Value[1] = '#' then L := StrToInt(Copy(Value, 2, Maxint)) + else L := Ord(Value[1]); + SetOrdValue(L); +end; + +function TNativeFieldTypeProperty.GetAttributes: TPropertyAttributes; {override;} +begin + result := [paRevertable,paValueList]; +end; + +procedure TNativeFieldTypeProperty.GetValues(Proc: TGetStrProc); +begin + Proc('C Character'); + Proc('N Numeric'); + Proc('D Date'); + Proc('L Logical'); + Proc('M Memo'); + Proc('B Blob'); + Proc('F Float'); + Proc('O Double'); + Proc('I Integer'); + Proc('G Graphic'); + Proc('+ AutoIncrement'); + Proc('@ DateTime'); +end; + +//========================================================== +//============ initialization +//========================================================== +function IDE_DbfDefaultPath:string; +begin +{$ifndef FPC} + if ToolServices<>nil then + Result := ExtractFilePath(ToolServices.GetProjectName) + else +{$endif} + Result := GetCurrentDir +end; + +{$ifdef FPC} +procedure RegisterUnitDbf; +{$else} +procedure Register; +{$endif} +begin + Dbf.DbfBasePath := IDE_DbfDefaultPath; + RegisterComponents('Data Access', [TDbf]); +// RegisterPropertyEditor(TypeInfo(string), TDbf, 'FilePath', TFilePathProperty); + RegisterPropertyEditor(TypeInfo(string), TDbf, 'TableName', TTableNameProperty); + RegisterPropertyEditor(TypeInfo(string), TDbf, 'Version', TVersionProperty); + RegisterPropertyEditor(TypeInfo(string), TDbf, 'IndexName', TIndexNameProperty); + RegisterPropertyEditor(TypeInfo(string), TDbfIndexDef, 'IndexFile', TIndexFileNameProperty); + RegisterPropertyEditor(TypeInfo(string), TDbfIndexDef, 'SortField', TSortFieldProperty); + RegisterPropertyEditor(TypeInfo(char), TDbfFieldDef, 'NativeFieldType', TNativeFieldTypeProperty); +end; + +{$ifdef FPC} +procedure Register; +begin + RegisterUnit('Dbf', @RegisterUnitDbf); +end; +{$endif} + +{$ifdef FPC} +initialization + {$i tdbf.lrs} +{$endif} + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str.inc b/mseide-msegui/lib/common/fpccompatibility/dbf_str.inc new file mode 100644 index 0000000..3dbc719 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str.inc @@ -0,0 +1,24 @@ +var + STRING_FILE_NOT_FOUND: string; + STRING_VERSION: string; + + STRING_RECORD_LOCKED: string; + STRING_WRITE_ERROR: string; + STRING_WRITE_INDEX_ERROR: string; + STRING_KEY_VIOLATION: string; + + STRING_INVALID_DBF_FILE: string; + STRING_FIELD_TOO_LONG: string; + STRING_INVALID_FIELD_COUNT: string; + STRING_INVALID_FIELD_TYPE: string; + STRING_INVALID_VCL_FIELD_TYPE: string; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD: string; + STRING_INDEX_BASED_ON_INVALID_FIELD: string; + STRING_INDEX_EXPRESSION_TOO_LONG: string; + STRING_INVALID_INDEX_TYPE: string; + STRING_CANNOT_OPEN_INDEX: string; + STRING_TOO_MANY_INDEXES: string; + STRING_INDEX_NOT_EXIST: string; + STRING_NEED_EXCLUSIVE_ACCESS: string; + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str.pas new file mode 100644 index 0000000..23fda49 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str.pas @@ -0,0 +1,36 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Open: file not found: "%s".'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Record locked.'; + STRING_WRITE_ERROR := 'Error while writing occurred. (Disk full?)'; + STRING_WRITE_INDEX_ERROR := 'Error while writing occurred; indexes probably corrupted. (Disk full?)'; + STRING_KEY_VIOLATION := 'Key violation. (Key already present in file).'+#13+#10+ + 'Index: %s'+#13+#10+'Record=%d Key=''%s''.'; + + STRING_INVALID_DBF_FILE := 'Invalid DBF file.'; + STRING_FIELD_TOO_LONG := 'Value is too long: %d characters (it can''t be more than %d).'; + STRING_INVALID_FIELD_COUNT := 'Invalid field count: %d (must be between 1 and 4095).'; + STRING_INVALID_FIELD_TYPE := 'Invalid field type ''%s'' for field ''%s''.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Cannot create field "%s", VCL field type %x not supported by DBF.'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Index based on unknown field "%s".'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Field "%s" is an invalid field type to base index on.'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Index result for "%s" too long, >100 characters (%d).'; + STRING_INVALID_INDEX_TYPE := 'Invalid index type: can only be string or float.'; + STRING_CANNOT_OPEN_INDEX := 'Cannot open index: "%s".'; + STRING_TOO_MANY_INDEXES := 'Can not create index: too many indexes in file.'; + STRING_INDEX_NOT_EXIST := 'Index "%s" does not exist.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Exclusive access is required for this operation.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_es.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_es.pas new file mode 100644 index 0000000..63f74eb --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_es.pas @@ -0,0 +1,36 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Apertura: archivo no encontrado: "%s".'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Registro bloqueado.'; + STRING_WRITE_ERROR := 'Error de escritura. (Disco lleno?)'; + STRING_WRITE_INDEX_ERROR := 'Error de escritura; índices probablemente corruptos. (Disco lleno?)'; + STRING_KEY_VIOLATION := 'Violación de clave. (Clave ya presente en archivo).'+#13+#10+ + 'Indice: %s'+#13+#10+'Registro=%d Clave=''%s''.'; + + STRING_INVALID_DBF_FILE := 'Archivo DBF inválido.'; + STRING_FIELD_TOO_LONG := 'Valor demasiado largo: %d caracteres (no puede ser mayor de %d).'; + STRING_INVALID_FIELD_COUNT := 'Cantidad de campos inválida: %d (debe estar entre 1 y 4095).'; + STRING_INVALID_FIELD_TYPE := 'Tipo de campo inválido ''%s'' para el campo ''%s''.'; + STRING_INVALID_VCL_FIELD_TYPE := 'No se puede crear el campo "%s", campo VCL tipo %x no soportado por DBF.'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Indice basado en campo desconocido "%s".'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Campo "%s" inválido para crear un índice.'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Resultado de índice para "%s" demasiado largo, >100 caracteres (%d).'; + STRING_INVALID_INDEX_TYPE := 'Tipo de índice invalido: solo puede ser string o float.'; + STRING_CANNOT_OPEN_INDEX := 'No se puede abrir el índice: "%s".'; + STRING_TOO_MANY_INDEXES := 'No se puede crear el índice: demasiados indices en el archivo.'; + STRING_INDEX_NOT_EXIST := 'Indice "%s" no existe.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Acceso Exclusivo requirido para esta operación.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_fr.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_fr.pas new file mode 100644 index 0000000..51ecb45 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_fr.pas @@ -0,0 +1,54 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} + +var + STRING_FILE_NOT_FOUND: string; + STRING_VERSION: string; + + STRING_RECORD_LOCKED: string; + STRING_KEY_VIOLATION: string; + + STRING_INVALID_DBF_FILE: string; + STRING_FIELD_TOO_LONG: string; + STRING_INVALID_FIELD_COUNT: string; + STRING_INVALID_FIELD_TYPE: string; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD: string; + STRING_INDEX_BASED_ON_INVALID_FIELD: string; + STRING_INDEX_EXPRESSION_TOO_LONG: string; + STRING_INVALID_INDEX_TYPE: string; + STRING_CANNOT_OPEN_INDEX: string; + STRING_TOO_MANY_INDEXES: string; + STRING_INDEX_NOT_EXIST: string; + STRING_NEED_EXCLUSIVE_ACCESS: string; + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Ouverture: fichier non trouvé: "%s"'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Enregistrement verrouillé.'; + STRING_KEY_VIOLATION := 'Violation de clé. (doublon dans un index).'+#13+#10+ + 'Index: %s'+#13+#10+'Enregistrement=%d Cle=''%s'''; + + STRING_INVALID_DBF_FILE := 'Fichier DBF invalide.'; + STRING_FIELD_TOO_LONG := 'Valeur trop longue: %d caractères (ne peut dépasser %d).'; + STRING_INVALID_FIELD_COUNT := 'Nombre de champs non valide: %d (doit être entre 1 et 4095).'; + STRING_INVALID_FIELD_TYPE := 'Type de champ ''%s'' invalide pour le champ %s.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Impossible de créer le champ "%s", champ type %x VCL non supporté par DBF'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Index basé sur un champ inconnu %s'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Impossible de contruire un index sur ce type de champ "%s"'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Résultat d''Index trop long pour "%s", >100 caractères (%d).'; + STRING_INVALID_INDEX_TYPE := 'Type d''index non valide: doit être string ou float'; + STRING_CANNOT_OPEN_INDEX := 'Impossible d''ouvrir l''index: "%s"'; + STRING_TOO_MANY_INDEXES := 'Impossible de créer l''index: trop d''index dans le fichier.'; + STRING_INDEX_NOT_EXIST := 'L''index "%s" n''existe pas.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Access exclusif requis pour cette opération.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_ita.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_ita.pas new file mode 100644 index 0000000..ec4c598 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_ita.pas @@ -0,0 +1,29 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Apertura: file non trovato: "%s"'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Record già in uso.'; + + STRING_INVALID_DBF_FILE := 'File DBF non valido.'; + STRING_FIELD_TOO_LONG := 'Valore troppo elevato: %d caratteri (esso non può essere più di %d).'; + STRING_INVALID_FIELD_COUNT := 'Campo non valido (count): %d (deve essere tra 1 e 4095).'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Indice basato su un campo sconosciuto "%s"'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Campo "%s" è di tipo non valido per un indice'; + STRING_INVALID_INDEX_TYPE := 'Tipo indice non valido: Può essere solo string o float'; + STRING_CANNOT_OPEN_INDEX := 'Non è possibile aprire indice : "%s"'; + STRING_TOO_MANY_INDEXES := 'Non è possibile creare indice: Troppi indici aperti.'; + STRING_INDEX_NOT_EXIST := 'Indice "%s" non esiste.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'L''Accesso in esclusiva è richiesto per questa operazione.'; +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_nl.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_nl.pas new file mode 100644 index 0000000..105564d --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_nl.pas @@ -0,0 +1,35 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Openen: bestand niet gevonden: "%s"'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Record in gebruik.'; + STRING_WRITE_ERROR := 'Error tijdens schrijven. (Disk vol?)'; + STRING_KEY_VIOLATION := 'Indexsleutel bestond al in bestand.'+#13+#10+ + 'Index: %s'+#13+#10+'Record=%d Sleutel=''%s'''; + + STRING_INVALID_DBF_FILE := 'Ongeldig DBF bestand.'; + STRING_FIELD_TOO_LONG := 'Waarde is te lang: %d karakters (maximum is %d).'; + STRING_INVALID_FIELD_COUNT := 'Ongeldig aantal velden: %d (moet tussen 1 en 4095).'; + STRING_INVALID_FIELD_TYPE := 'Veldtype ''%s'' is ongeldig voor veld ''%s''.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Veld "%s": VCL veldtype %x wordt niet ondersteund door DBF.'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Index gebaseerd op onbekend veld "%s".'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Veld "%s" heeft een ongeldig veldtype om index op te baseren.'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Index expressie resultaat "%s" is te lang, >100 karakters (%d).'; + STRING_INVALID_INDEX_TYPE := 'Ongeldig index type: kan alleen karakter of numeriek.'; + STRING_CANNOT_OPEN_INDEX := 'Openen index gefaald: "%s".'; + STRING_TOO_MANY_INDEXES := 'Toevoegen index onmogenlijk: te veel indexen in bestand.'; + STRING_INDEX_NOT_EXIST := 'Index "%s" bestaat niet.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Exclusieve toegang is vereist voor deze actie.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_pl.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_pl.pas new file mode 100644 index 0000000..52e5378 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_pl.pas @@ -0,0 +1,36 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Open: brak pliku: "%s"'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Rekord zablokowany.'; + STRING_WRITE_ERROR := 'Niezapisano(Brak miejsca na dysku?)'; + STRING_KEY_VIOLATION := 'Konflikt klucza. (Klucz obecny w pliku).'+#13+#10+ + 'Indeks: %s'+#13+#10+'Rekord=%d Klucz=''%s'''; + + STRING_INVALID_DBF_FILE := 'Uszkodzony plik bazy.'; + STRING_FIELD_TOO_LONG := 'Dana za d³uga : %d znaków (dopuszczalne do %d).'; + STRING_INVALID_FIELD_COUNT := 'Z³a liczba pól: %d (dozwolone 1 do 4095).'; + STRING_INVALID_FIELD_TYPE := 'B³êdny typ pola ''%c'' dla pola ''%s''.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Nie mogê tworzyæ pola "%s", typ pola VCL %x nie wspierany przez DBF.'; + + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Kluczowe pole indeksu "%s" nie istnieje'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Typ pola "%s" niedozwolony dla indeksów'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Zbyt d³ugi wynik "%s", >100 znaków (%d).'; + STRING_INVALID_INDEX_TYPE := 'Z³y typ indeksu: tylko string lub float'; + STRING_CANNOT_OPEN_INDEX := 'Nie mogê otworzyæ indeksu: "%s"'; + STRING_TOO_MANY_INDEXES := 'Nie mogê stworzyæ indeksu: za du¿o w pliku.'; + STRING_INDEX_NOT_EXIST := 'Brak indeksu "%s".'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Operacja wymaga dostêpu w trybie Exclusive.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_pt.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_pt.pas new file mode 100644 index 0000000..37e9a97 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_pt.pas @@ -0,0 +1,37 @@ +unit dbf_str; + +{ note this is Brazilian Portuguese } + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Abertura: arquivo não encontrado: "%s".'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Registro bloqueado.'; + STRING_WRITE_ERROR := 'Erro de escrita. (Disco cheio?)'; + STRING_WRITE_INDEX_ERROR := 'Erro de escrita; índices provavelmente corrompidos. (Disco cheio?)'; + STRING_KEY_VIOLATION := 'Violação de chave. (Chave já presente no archivo).'+#13+#10+ + 'Índice: %s'+#13+#10+'Registro=%d Chave=''%s''.'; + + STRING_INVALID_DBF_FILE := 'Arquivo DBF inválido.'; + STRING_FIELD_TOO_LONG := 'Valor muito grande: %d caracteres (não pode ser maior que %d).'; + STRING_INVALID_FIELD_COUNT := 'Quantidade de campos inválida: %d (deve estar entre 1 e 4095).'; + STRING_INVALID_FIELD_TYPE := 'Tipo de campo inválido ''%s'' para o campo ''%s''.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Não se pode criar o campo "%s", campo VCL tipo %x não suportado por DBF.'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Índice baseado em campo desconhecido "%s".'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Campo "%s" inválido para criar um índice.'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Resultado de índice para "%s" demasiado grande, >100 caracteres (%d).'; + STRING_INVALID_INDEX_TYPE := 'Tipo de índice inválido: só pode ser string ou float.'; + STRING_CANNOT_OPEN_INDEX := 'Não se pode abrir o índice: "%s".'; + STRING_TOO_MANY_INDEXES := 'Não se pode criar o índice: demasiados índices no archivo.'; + STRING_INDEX_NOT_EXIST := 'Ìndice "%s" não existe.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Acesso Exclusivo requerido para esta operação.'; +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_ru.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_ru.pas new file mode 100644 index 0000000..c7fe929 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_ru.pas @@ -0,0 +1,40 @@ +unit dbf_str_ru; + +// file is encoded in Windows-1251 encoding +// for using with Linux/Kylix must be re-coded to KOI8-R +// for use with DOS & OS/2 (if it will be possible with FreePascal or VirtualPascal) +// file should be recoded to cp866 + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Ôàéë "%s" íå ñóùåñòâóåò. Îòêðûòü íåâîçìîæíî.'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Çàïèñü (ñòðîêà òàáëèöû) çàáëîêèðîâàíà.'; + STRING_WRITE_ERROR := 'Îøèáêà çàïèñè íà äèñê (Äèñê çàïîëíåí?)'; + STRING_KEY_VIOLATION := 'Êëþ÷åâîå çíà÷åíèå íå äîëæíî ïîâòîðÿòüñÿ!.'+#13+#10+ + 'Èíäåêñ: %s'+#13+#10+'Çàïèñü (ñòðîêà)=%d Êëþ÷="%s".'; + + STRING_INVALID_DBF_FILE := 'Ôàéë DBF ïîâðåæäåí èëè åãî ñòðóêòóðà íå DBF.'; + STRING_FIELD_TOO_LONG := 'Äëèíà çíà÷åíèÿ - %d ñèìâîëîâ, ýòî áîëüøå ìàêñèìóìà - %d.'; + STRING_INVALID_FIELD_COUNT := 'Êîëè÷åñòâî ïîëåé â òàáëèöå (%d) íåâîçìîæíî. Äîïóñòèìî îò 1 äî 4095.'; + STRING_INVALID_FIELD_TYPE := 'Òèï çíà÷åíèÿ "%s", çàòðåáîâàííûé ïîëåì "%s" íåâîçìîæåí.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Íåâîçìîæíî ñîçäàòü ïîëå "%s", Òèï äàííûõ VCL[%x] íå ìîæåò áûòü çàïèñàí â DBF.'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Èíäåêñ ññûëàåòñÿ íà íåñóùåñòâóþùåå ïîëå "%s".'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Ïîëå "%s" íå ìîæåò áûòü èíäåêñèðîâàííî. Èíäåêñû íå ïîääåðæèâàþò òàêîé òèï ïîëÿ.'; + STRING_INDEX_EXPRESSION_TOO_LONG := '%s: Ñëèøêîì äëèííîå çíà÷åíèå äëÿ èíäåêñà (%d). Äîëæíî áûòü íå áîëüøå 100 ñèìâîëîâ.'; + STRING_INVALID_INDEX_TYPE := 'Íåâîçìîæíûé òèï èíäåêñà: èíäåêñàöèÿ âîçìîæíî òîëüêî ïî ÷èñëó èëè ñòðîêå'; + STRING_CANNOT_OPEN_INDEX := 'Íåâîçìîæíî îòêðûòü èíäåêñ "%s".'; + STRING_TOO_MANY_INDEXES := 'Íåâîçìîæíî ñîçäàòü åùå îäèí èíäåêñ. Ôàéë ïîëîí.'; + STRING_INDEX_NOT_EXIST := 'Èíäåêñ "%s" íå ñóùåñòâóåò.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Íåâîçìîæíî âûïîëíèòü - ñíà÷àëà íóæíî ïîëó÷èòü ìîíîïîëüíûé äîñòóï.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_struct.inc b/mseide-msegui/lib/common/fpccompatibility/dbf_struct.inc new file mode 100644 index 0000000..68d3ae3 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_struct.inc @@ -0,0 +1,145 @@ + +const + +//==================================================================== + FieldPropType_Required = $01; + FieldPropType_Min = $02; + FieldPropType_Max = $03; + FieldPropType_Default = $04; + FieldPropType_Constraint = $06; + + FieldDescVII_AutoIncOffset = 42; + +//==================================================================== +// File structures +//==================================================================== + +type + + PDbfHdr = ^rDbfHdr; + rDbfHdr = packed record + VerDBF : Byte; // 0 + Year : Byte; // 1 + Month : Byte; // 2 + Day : Byte; // 3 + RecordCount : Integer; // 4-7 + FullHdrSize : Word; // 8-9 + RecordSize : Word; // 10-11 + Dummy1 : Word; // 12-13 + IncTrans : Byte; // 14 + Encrypt : Byte; // 15 + MultiUse : Integer; // 16-19 + LastUserID : Integer; // 20-23 + Dummy2 : array[24..27] of Byte; + MDXFlag : Byte; // 28 + Language : Byte; // 29 + Dummy3 : Word; // 30-31 + end; +//==================================================================== + PAfterHdrIII = ^rAfterHdrIII; + rAfterHdrIII = packed record // Empty + end; +//==================================================================== + PAfterHdrVII = ^rAfterHdrVII; + rAfterHdrVII = packed record + LanguageDriverName : array[32..63] of Char; + Dummy : array[64..67] of Byte; + end; +//==================================================================== + PFieldDescIII = ^rFieldDescIII; + rFieldDescIII = packed record + FieldName : array[0..10] of Char; + FieldType : Char; // 11 + FieldOffset : Integer; // 12..15 only applicable to foxpro databases + FieldSize : Byte; // 16 + FieldPrecision : Byte; // 17 + FoxProFlags : Byte; // 18 + Dummy2 : array[19..31] of Byte; + end; +//==================================================================== +// OH 2000-11-15 dBase7 support. Header Update (add fields like Next AutoInc Value) + rFieldDescVII = packed record + FieldName : array [0..31] of Char; + FieldType : Char; // 32 + FieldSize : Byte; // 33 + FieldPrecision : Byte; // 34 + Reserved1 : Word; // 35-36 + MDXFlag : Byte; // 37 + // NOTE: the docs say Reserved2 is 2 bytes, and Reserved3 is 4 bytes + // but testing shows BDE has them the other way around + // be BDE compatible :S + Reserved2 : Cardinal; // 38-41 + NextAutoInc : Cardinal; // 42-45 + Reserved3 : Word; // 46-47 + end; +//==================================================================== + PFieldPropsHdr = ^rFieldPropsHdr; + rFieldPropsHdr = packed record + NumStdProps : Word; // 0..1 + StartStdProps : Word; // 2..3 + NumCustomProps : Word; // 4..5 + StartCustomProps : Word; // 6..7 + NumRIProps : Word; // 8..9 + StartRIProps : Word; // 10..11 + StartData : Word; // 12..13 ; this points past the Descriptor arrays to data used by the arrays - for example Custom property names are stored here. + Size : Word; // 14..15 ; Actual size of structure, including data + end; +//==================================================================== + PStdPropEntry = ^rStdPropEntry; + rStdPropEntry = packed record + GenNumber : Word; // 0..1 ; Generational number. More than one value may exist for a property. The current value is the value with the highest generational number. + FieldOffset : Word; // 2..3 ; Table field offset - base one. 01 for the first field in the table, 02 for the second field, etc. Note: this will be 0 in the case of a constraint. + PropType : Byte; // 4 ; Which property is described in this record: + // 01 Required + // 02 Min + // 03 Max + // 04 Default + // 06 Database constraint + FieldType : Byte; // 5 ; Field Type: + // 00 No type - constraint + // 01 Char + // 02 Numeric + // 03 Memo + // 04 Logical + // 05 Date + // 06 Float + // 08 OLE + // 09 Binary + // 11 Long + // 12 Timestamp + // 13 Double + // 14 AutoIncrement (not settable from the Inspector) + IsConstraint : Byte; // 6 ; 0x00 if the array element is a constraint, 0x02 otherwise. + Reserved : array[7..10] of Char; + DataOffset : Word; // 11..12 ; Offset from the start of this structure to the data for the property. The Required property has no data associated with it, so it is always 0. + DataSize : Word; // 13..14 ; Width of database field associated with the property, and hence size of the data (includes 0 terminator in the case of a constraint). + end; +//==================================================================== + PCustomPropEntry = ^rCustomPropEntry; + rCustomPropEntry = packed record + GenNumber : Word; // 0..1 ; same as standard + FieldOffset : Word; // 2..3 ; same as standard + FieldType : Byte; // 4 ; same as standard + Reserved : Byte; // 5 + NameOffset : Word; // 6..7 ; Offset from the start of this structure to the Custom property name. + NameLength : Word; // 8..9 ; Length of the Custom property name. + DataOffset : Word; // 10..11 ; Offset from the start of this structure to the Custom property data. + DataLength : Word; // 12..13 ; Length of the Custom property data (does not include null terminator). + end; +//==================================================================== + PRIPropEntry = ^rRIPropEntry; + rRIPropEntry = packed record + RelationType : Byte; // 0 ; 0x07 if Master (parent), 0x08 if Dependent (child). + Number : Word; // 1..2 ; Sequential number, 1 based counting. If this number is 0, this RI rule has been dropped. + NameOffset : Word; // 3..4 ; Offset of the RI rule name - 0 terminated. + NameSize : Word; // 5..6 ; Size of ... + ForeignOffset : Word; // 7..8 ; Offset of the name of the Foreign Table - 0 terminated. + ForeignSize : Word; // 9..10 ; Size of ... + UpdateType : Byte; // 11 ; Update & delete behaviour: Update Cascade=0x10, Delete Cascade=0x01 + NumFieldsKey : Word; // 12..13 ; Number of fields in the linking key. + LocalTagOffset : Word; // 14..15 ; Offset of the Local Table tag name - 0 terminated. + LocalTagSize : Word; // 16..17 ; Size of ... + ForeignTagOffset: Word; // 18..19 ; Offset of the Foreign Table tag name - 0 terminated. + ForeignTagSize : Word; // 20..21 ; Size of ... + end; + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_wtil.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_wtil.pas new file mode 100644 index 0000000..cfe8b31 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_wtil.pas @@ -0,0 +1,670 @@ +unit dbf_wtil; + +{$I dbf_common.inc} + +interface + +{$ifndef WINDOWS} +uses +{$ifdef FPC} + BaseUnix, +{$else} + Libc, +{$endif} + Types, SysUtils, Classes; + +const + LCID_INSTALLED = $00000001; { installed locale ids } + LCID_SUPPORTED = $00000002; { supported locale ids } + CP_INSTALLED = $00000001; { installed code page ids } + CP_SUPPORTED = $00000002; { supported code page ids } +(* + * Language IDs. + * + * The following two combinations of primary language ID and + * sublanguage ID have special semantics: + * + * Primary Language ID Sublanguage ID Result + * ------------------- --------------- ------------------------ + * LANG_NEUTRAL SUBLANG_NEUTRAL Language neutral + * LANG_NEUTRAL SUBLANG_DEFAULT User default language + * LANG_NEUTRAL SUBLANG_SYS_DEFAULT System default language + *) +{ Primary language IDs. } + LANG_NEUTRAL = $00; + LANG_AFRIKAANS = $36; + LANG_ALBANIAN = $1c; + LANG_ARABIC = $01; + LANG_BASQUE = $2d; + LANG_BELARUSIAN = $23; + LANG_BULGARIAN = $02; + LANG_CATALAN = $03; + LANG_CHINESE = $04; + LANG_CROATIAN = $1a; + LANG_CZECH = $05; + LANG_DANISH = $06; + LANG_DUTCH = $13; + LANG_ENGLISH = $09; + LANG_ESTONIAN = $25; + LANG_FAEROESE = $38; + LANG_FARSI = $29; + LANG_FINNISH = $0b; + LANG_FRENCH = $0c; + LANG_GERMAN = $07; + LANG_GREEK = $08; + LANG_HEBREW = $0d; + LANG_HUNGARIAN = $0e; + LANG_ICELANDIC = $0f; + LANG_INDONESIAN = $21; + LANG_ITALIAN = $10; + LANG_JAPANESE = $11; + LANG_KOREAN = $12; + LANG_LATVIAN = $26; + LANG_LITHUANIAN = $27; + LANG_NORWEGIAN = $14; + LANG_POLISH = $15; + LANG_PORTUGUESE = $16; + LANG_ROMANIAN = $18; + LANG_RUSSIAN = $19; + LANG_SERBIAN = $1a; + LANG_SLOVAK = $1b; + LANG_SLOVENIAN = $24; + LANG_SPANISH = $0a; + LANG_SWEDISH = $1d; + LANG_THAI = $1e; + LANG_TURKISH = $1f; + LANG_UKRAINIAN = $22; + LANG_VIETNAMESE = $2a; +{ Sublanguage IDs. } + { The name immediately following SUBLANG_ dictates which primary + language ID that sublanguage ID can be combined with to form a + valid language ID. + } + SUBLANG_NEUTRAL = $00; { language neutral } + SUBLANG_DEFAULT = $01; { user default } + SUBLANG_SYS_DEFAULT = $02; { system default } + SUBLANG_ARABIC_SAUDI_ARABIA = $01; { Arabic (Saudi Arabia) } + SUBLANG_ARABIC_IRAQ = $02; { Arabic (Iraq) } + SUBLANG_ARABIC_EGYPT = $03; { Arabic (Egypt) } + SUBLANG_ARABIC_LIBYA = $04; { Arabic (Libya) } + SUBLANG_ARABIC_ALGERIA = $05; { Arabic (Algeria) } + SUBLANG_ARABIC_MOROCCO = $06; { Arabic (Morocco) } + SUBLANG_ARABIC_TUNISIA = $07; { Arabic (Tunisia) } + SUBLANG_ARABIC_OMAN = $08; { Arabic (Oman) } + SUBLANG_ARABIC_YEMEN = $09; { Arabic (Yemen) } + SUBLANG_ARABIC_SYRIA = $0a; { Arabic (Syria) } + SUBLANG_ARABIC_JORDAN = $0b; { Arabic (Jordan) } + SUBLANG_ARABIC_LEBANON = $0c; { Arabic (Lebanon) } + SUBLANG_ARABIC_KUWAIT = $0d; { Arabic (Kuwait) } + SUBLANG_ARABIC_UAE = $0e; { Arabic (U.A.E) } + SUBLANG_ARABIC_BAHRAIN = $0f; { Arabic (Bahrain) } + SUBLANG_ARABIC_QATAR = $10; { Arabic (Qatar) } + SUBLANG_CHINESE_TRADITIONAL = $01; { Chinese (Taiwan) } + SUBLANG_CHINESE_SIMPLIFIED = $02; { Chinese (PR China) } + SUBLANG_CHINESE_HONGKONG = $03; { Chinese (Hong Kong) } + SUBLANG_CHINESE_SINGAPORE = $04; { Chinese (Singapore) } + SUBLANG_DUTCH = $01; { Dutch } + SUBLANG_DUTCH_BELGIAN = $02; { Dutch (Belgian) } + SUBLANG_ENGLISH_US = $01; { English (USA) } + SUBLANG_ENGLISH_UK = $02; { English (UK) } + SUBLANG_ENGLISH_AUS = $03; { English (Australian) } + SUBLANG_ENGLISH_CAN = $04; { English (Canadian) } + SUBLANG_ENGLISH_NZ = $05; { English (New Zealand) } + SUBLANG_ENGLISH_EIRE = $06; { English (Irish) } + SUBLANG_ENGLISH_SOUTH_AFRICA = $07; { English (South Africa) } + SUBLANG_ENGLISH_JAMAICA = $08; { English (Jamaica) } + SUBLANG_ENGLISH_CARIBBEAN = $09; { English (Caribbean) } + SUBLANG_ENGLISH_BELIZE = $0a; { English (Belize) } + SUBLANG_ENGLISH_TRINIDAD = $0b; { English (Trinidad) } + SUBLANG_FRENCH = $01; { French } + SUBLANG_FRENCH_BELGIAN = $02; { French (Belgian) } + SUBLANG_FRENCH_CANADIAN = $03; { French (Canadian) } + SUBLANG_FRENCH_SWISS = $04; { French (Swiss) } + SUBLANG_FRENCH_LUXEMBOURG = $05; { French (Luxembourg) } + SUBLANG_GERMAN = $01; { German } + SUBLANG_GERMAN_SWISS = $02; { German (Swiss) } + SUBLANG_GERMAN_AUSTRIAN = $03; { German (Austrian) } + SUBLANG_GERMAN_LUXEMBOURG = $04; { German (Luxembourg) } + SUBLANG_GERMAN_LIECHTENSTEIN = $05; { German (Liechtenstein) } + SUBLANG_ITALIAN = $01; { Italian } + SUBLANG_ITALIAN_SWISS = $02; { Italian (Swiss) } + SUBLANG_KOREAN = $01; { Korean (Extended Wansung) } + SUBLANG_KOREAN_JOHAB = $02; { Korean (Johab) } + SUBLANG_NORWEGIAN_BOKMAL = $01; { Norwegian (Bokmal) } + SUBLANG_NORWEGIAN_NYNORSK = $02; { Norwegian (Nynorsk) } + SUBLANG_PORTUGUESE = $02; { Portuguese } + SUBLANG_PORTUGUESE_BRAZILIAN = $01; { Portuguese (Brazilian) } + SUBLANG_SERBIAN_LATIN = $02; { Serbian (Latin) } + SUBLANG_SERBIAN_CYRILLIC = $03; { Serbian (Cyrillic) } + SUBLANG_SPANISH = $01; { Spanish (Castilian) } + SUBLANG_SPANISH_MEXICAN = $02; { Spanish (Mexican) } + SUBLANG_SPANISH_MODERN = $03; { Spanish (Modern) } + SUBLANG_SPANISH_GUATEMALA = $04; { Spanish (Guatemala) } + SUBLANG_SPANISH_COSTA_RICA = $05; { Spanish (Costa Rica) } + SUBLANG_SPANISH_PANAMA = $06; { Spanish (Panama) } + SUBLANG_SPANISH_DOMINICAN_REPUBLIC = $07; { Spanish (Dominican Republic) } + SUBLANG_SPANISH_VENEZUELA = $08; { Spanish (Venezuela) } + SUBLANG_SPANISH_COLOMBIA = $09; { Spanish (Colombia) } + SUBLANG_SPANISH_PERU = $0a; { Spanish (Peru) } + SUBLANG_SPANISH_ARGENTINA = $0b; { Spanish (Argentina) } + SUBLANG_SPANISH_ECUADOR = $0c; { Spanish (Ecuador) } + SUBLANG_SPANISH_CHILE = $0d; { Spanish (Chile) } + SUBLANG_SPANISH_URUGUAY = $0e; { Spanish (Uruguay) } + SUBLANG_SPANISH_PARAGUAY = $0f; { Spanish (Paraguay) } + SUBLANG_SPANISH_BOLIVIA = $10; { Spanish (Bolivia) } + SUBLANG_SPANISH_EL_SALVADOR = $11; { Spanish (El Salvador) } + SUBLANG_SPANISH_HONDURAS = $12; { Spanish (Honduras) } + SUBLANG_SPANISH_NICARAGUA = $13; { Spanish (Nicaragua) } + SUBLANG_SPANISH_PUERTO_RICO = $14; { Spanish (Puerto Rico) } + SUBLANG_SWEDISH = $01; { Swedish } + SUBLANG_SWEDISH_FINLAND = $02; { Swedish (Finland) } +{ Sorting IDs. } + SORT_DEFAULT = $0; { sorting default } + SORT_JAPANESE_XJIS = $0; { Japanese XJIS order } + SORT_JAPANESE_UNICODE = $1; { Japanese Unicode order } + SORT_CHINESE_BIG5 = $0; { Chinese BIG5 order } + SORT_CHINESE_PRCP = $0; { PRC Chinese Phonetic order } + SORT_CHINESE_UNICODE = $1; { Chinese Unicode order } + SORT_CHINESE_PRC = $2; { PRC Chinese Stroke Count order } + SORT_KOREAN_KSC = $0; { Korean KSC order } + SORT_KOREAN_UNICODE = $1; { Korean Unicode order } + SORT_GERMAN_PHONE_BOOK = $1; { German Phone Book order } +(* + * A language ID is a 16 bit value which is the combination of a + * primary language ID and a secondary language ID. The bits are + * allocated as follows: + * + * +-----------------------+-------------------------+ + * | Sublanguage ID | Primary Language ID | + * +-----------------------+-------------------------+ + * 15 10 9 0 bit + * + * + * + * A locale ID is a 32 bit value which is the combination of a + * language ID, a sort ID, and a reserved area. The bits are + * allocated as follows: + * + * +-------------+---------+-------------------------+ + * | Reserved | Sort ID | Language ID | + * +-------------+---------+-------------------------+ + * 31 20 19 16 15 0 bit + * + *) +{ Default System and User IDs for language and locale. } + LANG_SYSTEM_DEFAULT = (SUBLANG_SYS_DEFAULT shl 10) or LANG_NEUTRAL; + LANG_USER_DEFAULT = (SUBLANG_DEFAULT shl 10) or LANG_NEUTRAL; + LOCALE_SYSTEM_DEFAULT = (SORT_DEFAULT shl 16) or LANG_SYSTEM_DEFAULT; + LOCALE_USER_DEFAULT = (SORT_DEFAULT shl 16) or LANG_USER_DEFAULT; + +(* + Error const of File Locking +*) +{$ifdef FPC} + ERROR_LOCK_VIOLATION = ESysEACCES; +{$else} + ERROR_LOCK_VIOLATION = EACCES; +{$endif} + +{ MBCS and Unicode Translation Flags. } + MB_PRECOMPOSED = 1; { use precomposed chars } + MB_COMPOSITE = 2; { use composite chars } + MB_USEGLYPHCHARS = 4; { use glyph chars, not ctrl chars } + +type + LCID = DWORD; + BOOL = LongBool; + PBOOL = ^BOOL; + WCHAR = WideChar; + PWChar = PWideChar; + LPSTR = PAnsiChar; + PLPSTR = ^LPSTR; + LPCSTR = PAnsiChar; + LPCTSTR = PAnsiChar; { should be PWideChar if UNICODE } + LPTSTR = PAnsiChar; { should be PWideChar if UNICODE } + LPWSTR = PWideChar; + PLPWSTR = ^LPWSTR; + LPCWSTR = PWideChar; + + { System time is represented with the following structure: } + PSystemTime = ^TSystemTime; + TSystemTime = record + wYear: Word; + wMonth: Word; + wDayOfWeek: Word; + wDay: Word; + wHour: Word; + wMinute: Word; + wSecond: Word; + wMilliseconds: Word; + end; + + TFarProc = Pointer; + TFNLocaleEnumProc = TFarProc; + TFNCodepageEnumProc = TFarProc; + TFNDateFmtEnumProc = TFarProc; + TFNTimeFmtEnumProc = TFarProc; + TFNCalInfoEnumProc = TFarProc; + +function LockFile(hFile: THandle; dwFileOffsetLow, dwFileOffsetHigh: DWORD; nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh: DWORD): BOOL; +function UnlockFile(hFile: THandle; dwFileOffsetLow, dwFileOffsetHigh: DWORD; nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh: DWORD): BOOL; +procedure GetLocalTime(var lpSystemTime: TSystemTime); +function GetOEMCP: Cardinal; +function GetACP: Cardinal; +function OemToChar(lpszSrc: PChar; lpszDst: PChar): BOOL; +function CharToOem(lpszSrc: PChar; lpszDst: PChar): BOOL; +function OemToCharBuff(lpszSrc: PChar; lpszDst: PChar; cchDstLength: DWORD): BOOL; +function CharToOemBuff(lpszSrc: PChar; lpszDst: PChar; cchDstLength: DWORD): BOOL; +function MultiByteToWideChar(CodePage: DWORD; dwFlags: DWORD; const lpMultiByteStr: LPCSTR; cchMultiByte: Integer; lpWideCharStr: LPWSTR; cchWideChar: Integer): Integer; +function WideCharToMultiByte(CodePage: DWORD; dwFlags: DWORD; lpWideCharStr: LPWSTR; cchWideChar: Integer; lpMultiByteStr: LPSTR; cchMultiByte: Integer; lpDefaultChar: LPCSTR; lpUsedDefaultChar: PBOOL): Integer; +function CompareString(Locale: LCID; dwCmpFlags: DWORD; lpString1: PChar; cchCount1: Integer; lpString2: PChar; cchCount2: Integer): Integer; +function EnumSystemCodePages(lpCodePageEnumProc: TFNCodepageEnumProc; dwFlags: DWORD): BOOL; +function EnumSystemLocales(lpLocaleEnumProc: TFNLocaleEnumProc; dwFlags: DWORD): BOOL; +function GetUserDefaultLCID: LCID; + +{$ifdef FPC} +function GetLastError: Integer; +procedure SetLastError(Value: Integer); +{$endif} +{$endif} + +implementation + +{$ifndef WINDOWS} +{$ifdef FPC} +uses + unix; +{$endif} + +(* +NAME + fcntl - manipulate file descriptor + +SYNOPSIS + #include + #include + + int fcntl(int fd, int cmd); + int fcntl(int fd, int cmd, long arg); + int fcntl(int fd, int cmd, struct flock * lock); + +DESCRIPTION + fcntl performs one of various miscellaneous operations on + fd. The operation in question is determined by cmd: + + F_GETLK, F_SETLK and F_SETLKW are used to manage discreð + tionary file locks. The third argument lock is a pointer + to a struct flock (that may be overwritten by this call). + + F_GETLK + Return the flock structure that prevents us from + obtaining the lock, or set the l_type field of the + lock to F_UNLCK if there is no obstruction. + + F_SETLK + The lock is set (when l_type is F_RDLCK or F_WRLCK) + or cleared (when it is F_UNLCK). If the lock is + held by someone else, this call returns -1 and sets + errno to EACCES or EAGAIN. + + F_SETLKW + Like F_SETLK, but instead of returning an error we + wait for the lock to be released. If a signal that + is to be caught is received while fcntl is waiting, + it is interrupted and (after the signal handler has + returned) returns immediately (with return value -1 + and errno set to EINTR). + + Using these mechanisms, a program can implement fully + asynchronous I/O without using select(2) or poll(2) most + of the time. + + The use of O_ASYNC, F_GETOWN, F_SETOWN is specific to BSD + and Linux. F_GETSIG and F_SETSIG are Linux-specific. + POSIX has asynchronous I/O and the aio_sigevent structure + to achieve similar things; these are also available in + Linux as part of the GNU C Library (Glibc). + +RETURN VALUE + For a successful call, the return value depends on the + operation: + + F_GETFD Value of flag. + + F_GETFL Value of flags. + + F_GETOWN Value of descriptor owner. + + F_GETSIG Value of signal sent when read or write becomes + possible, or zero for traditional SIGIO + behaviour. + + All other commands + Zero. + + On error, -1 is returned, and errno is set appropriately. + +ERRORS + EACCES Operation is prohibited by locks held by other + processes. + + EAGAIN Operation is prohibited because the file has been + memory-mapped by another process. + + EBADF fd is not an open file descriptor. + + EDEADLK It was detected that the specified F_SETLKW comð + mand would cause a deadlock. + + EFAULT lock is outside your accessible address space. + + EINTR For F_SETLKW, the command was interrupted by a + signal. For F_GETLK and F_SETLK, the command was + interrupted by a signal before the lock was + checked or acquired. Most likely when locking a + remote file (e.g. locking over NFS), but can + sometimes happen locally. + + EINVAL For F_DUPFD, arg is negative or is greater than + the maximum allowable value. For F_SETSIG, arg + is not an allowable signal number. + + EMFILE For F_DUPFD, the process already has the maximum + number of file descriptors open. + + ENOLCK Too many segment locks open, lock table is full, + or a remote locking protocol failed (e.g. locking + over NFS). + + EPERM Attempted to clear the O_APPEND flag on a file + that has the append-only attribute set. + +typedef long __kernel_off_t; +typedef int __kernel_pid_t; + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +whence: +-------- +const + SEEK_SET = 0; { Seek from beginning of file. } + SEEK_CUR = 1; { Seek from current position. } + SEEK_END = 2; { Seek from end of file. } + +{ Old BSD names for the same constants; just for compatibility. } + L_SET = SEEK_SET; + L_INCR = SEEK_CUR; + L_XTND = SEEK_END; +*) + + +{$ifdef FPC} +const + F_RDLCK = 0; + F_WRLCK = 1; + F_UNLCK = 2; + F_EXLCK = 4; + F_SHLCK = 8; + + LOCK_SH = 1; + LOCK_EX = 2; + LOCK_NB = 4; + LOCK_UN = 8; + + LOCK_MAND = 32; + LOCK_READ = 64; + LOCK_WRITE = 128; + LOCK_RW = 192; + + EACCES = ESysEACCES; + EAGAIN = ESysEAGAIN; +{$endif} + +function LockFile(hFile: THandle; dwFileOffsetLow, dwFileOffsetHigh: DWORD; nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh: DWORD): BOOL; +var + FLockInfo: {$ifdef FPC}BaseUnix.FLock{$else}TFLock{$endif}; + FLastError: Cardinal; +begin + FLockInfo.l_type := F_WRLCK; + FLockInfo.l_whence := SEEK_SET; + FLockInfo.l_start := dwFileOffsetLow; + FLockInfo.l_len := nNumberOfBytesToLockLow; + FLockInfo.l_pid := {$ifdef FPC}fpgetpid{$else}getpid{$endif}(); + Result := {$ifdef FPC}fpfcntl{$else}fcntl{$endif}(hFile, F_SETLK, FLockInfo) <> -1; + if not Result then + begin + FLastError := GetLastError(); + if (FLastError = EACCES) or (FLastError = EAGAIN) then + SetLastError(ERROR_LOCK_VIOLATION) + else + Result := True; // If errno is ENOLCK or EINVAL + end; +end; + +function UnlockFile(hFile: THandle; dwFileOffsetLow, dwFileOffsetHigh: DWORD; nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh: DWORD): BOOL; +var + FLockInfo: {$ifdef FPC}BaseUnix.FLock{$else}TFLock{$endif}; +begin + FLockInfo.l_type := F_UNLCK; + FLockInfo.l_whence := SEEK_SET; + FLockInfo.l_start := dwFileOffsetLow; + FLockInfo.l_len := nNumberOfBytesToUnLockLow; + FLockInfo.l_pid := {$ifdef FPC}fpgetpid{$else}getpid{$endif}(); + Result := {$ifdef FPC}fpfcntl{$else}fcntl{$endif}(hFile, F_SETLK, FLockInfo) <> -1; +end; + +procedure DateTimeToSystemTime(const DateTime: TDateTime; var SystemTime: TSystemTime); +begin + with SystemTime do + begin + DecodeDateFully(DateTime, wYear, wMonth, wDay, wDayOfWeek); + Dec(wDayOfWeek); + DecodeTime(DateTime, wHour, wMinute, wSecond, wMilliseconds); + end; +end; + +function SystemTimeToDateTime(const SystemTime: TSystemTime): TDateTime; +begin + with SystemTime do + begin + Result := EncodeDate(wYear, wMonth, wDay); + if Result >= 0 then + Result := Result + EncodeTime(wHour, wMinute, wSecond, wMilliSeconds) + else + Result := Result - EncodeTime(wHour, wMinute, wSecond, wMilliSeconds); + end; +end; + +procedure GetLocalTime(var lpSystemTime: TSystemTime); +begin + DateTimeToSystemTime(NOW, lpSystemTime); +end; + +function GetOEMCP: Cardinal; +begin +{$ifdef HUNGARIAN} + Result := 852; +{$else} + Result := $FFFFFFFF; +{$endif} +end; + +function GetACP: Cardinal; +begin +{$ifdef HUNGARIAN} + Result := 1250; +{$else} + Result := 1252; +{$endif} +end; + +{$ifdef HUNGARIAN} + +procedure OemHunHun(AnsiDst: PChar; cchDstLength: DWORD); +var + Count: DWORD; +begin + if Assigned(AnsiDst) and (cchDstLength<>0) then + begin + for Count:=0 to Pred(cchDstLength) do + begin + case AnsiDst^ of + #160: AnsiDst^:= #225; {á} + #143,#181: AnsiDst^:= #193; {Á} + #130: AnsiDst^:= #233; {é} + #144: AnsiDst^:= #201; {É} + #161: AnsiDst^:= #237; {í} + #141,#214: AnsiDst^:= #205; {Í} + #162: AnsiDst^:= #243; {ó} + #149,#224: AnsiDst^:= #211; {Ó} + #148: AnsiDst^:= #246; {ö} + #153: AnsiDst^:= #214; {Ö} + #147,#139: AnsiDst^:= #245; {õ} + #167,#138: AnsiDst^:= #213; {Õ} + #163: AnsiDst^:= #250; {ú} + #151,#233: AnsiDst^:= #218; {Ú} + #129: AnsiDst^:= #252; {ü} + #154: AnsiDst^:= #220; {Ü} + #150,#251: AnsiDst^:= #251; {û} + #152,#235: AnsiDst^:= #219; {Û} + end; + Inc(AnsiDst); + end; + end; +end; + +procedure AnsiHunHun(AnsiDst: PChar; cchDstLength: DWORD); +var + Count: DWORD; +begin + if Assigned(AnsiDst) and (cchDstLength<>0) then + begin + for Count:=0 to Pred(cchDstLength) do + begin + case AnsiDst^ of + #225: AnsiDst^:= #160; {á} + #193: AnsiDst^:= #181; {Á} + #233: AnsiDst^:= #130; {é} + #201: AnsiDst^:= #144; {É} + #237: AnsiDst^:= #161; {í} + #205: AnsiDst^:= #214; {Í} + #243: AnsiDst^:= #162; {ó} + #211: AnsiDst^:= #224; {Ó} + #246: AnsiDst^:= #148; {ö} + #214: AnsiDst^:= #153; {Ö} + #245: AnsiDst^:= #139; {õ} + #213: AnsiDst^:= #138; {Õ} + #250: AnsiDst^:= #163; {ú} + #218: AnsiDst^:= #233; {Ú} + #252: AnsiDst^:= #129; {ü} + #220: AnsiDst^:= #154; {Ü} + #251: AnsiDst^:= #251; {û} + #219: AnsiDst^:= #235; {Û} + end; + Inc(AnsiDst); + end; + end; +end; + +{$endif} + +function OemToChar(lpszSrc: PChar; lpszDst: PChar): BOOL; +begin + if lpszDst <> lpszSrc then + StrCopy(lpszDst, lpszSrc); + Result := true; +end; + +function CharToOem(lpszSrc: PChar; lpszDst: PChar): BOOL; +begin + if lpszDst <> lpszSrc then + StrCopy(lpszDst, lpszSrc); + Result := true; +end; + +function OemToCharBuff(lpszSrc: PChar; lpszDst: PChar; cchDstLength: DWORD): BOOL; +begin + if lpszDst <> lpszSrc then + StrLCopy(lpszDst, lpszSrc, cchDstLength); +{$ifdef HUNGARIAN} + OemHunHun(lpszDst, cchDstLength); +{$endif} + Result := true; +end; + +function CharToOemBuff(lpszSrc: PChar; lpszDst: PChar; cchDstLength: DWORD): BOOL; +begin + if lpszDst <> lpszSrc then + StrLCopy(lpszDst, lpszSrc, cchDstLength); +{$ifdef HUNGARIAN} + AnsiHunHun(lpszDst, cchDstLength); +{$endif} + Result := true; +end; + +function MultiByteToWideChar(CodePage: DWORD; dwFlags: DWORD; const lpMultiByteStr: LPCSTR; cchMultiByte: Integer; lpWideCharStr: LPWSTR; cchWideChar: Integer): Integer; +var + TempA: AnsiString; + TempW: WideString; +begin + TempA := String(lpMultiByteStr^); + TempW := TempA; + Result := Length(TempW); + System.Move(TempW, lpWideCharStr^, Result); +end; + +function WideCharToMultiByte(CodePage: DWORD; dwFlags: DWORD; lpWideCharStr: LPWSTR; cchWideChar: Integer; lpMultiByteStr: LPSTR; cchMultiByte: Integer; lpDefaultChar: LPCSTR; lpUsedDefaultChar: PBOOL): Integer; +var + TempA: AnsiString; + TempW: WideString; +begin + TempW := WideString(lpWideCharStr^); + TempA := TempW; + Result := Length(TempA); + System.Move(TempA, lpMultiByteStr^, Result); +end; + +function CompareString(Locale: LCID; dwCmpFlags: DWORD; lpString1: PChar; cchCount1: Integer; lpString2: PChar; cchCount2: Integer): Integer; +begin + Result := StrLComp(lpString1, lpString2, cchCount1) + 2; + if Result > 2 then Result := 3; + if Result < 2 then Result := 1; +end; + +function EnumSystemCodePages(lpCodePageEnumProc: TFNCodepageEnumProc; dwFlags: DWORD): BOOL; +begin + Result := True; +end; + +function EnumSystemLocales(lpLocaleEnumProc: TFNLocaleEnumProc; dwFlags: DWORD): BOOL; +begin + Result := True; +end; + +function GetUserDefaultLCID: LCID; +begin + Result := LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10); +end; + +{$ifdef FPC} + +function GetLastError: Integer; +begin + Result := FpGetErrno; +end; + +procedure SetLastError(Value: Integer); +begin + FpSetErrno(Value); +end; + +{$endif} +{$endif} + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/formatfunc.pas b/mseide-msegui/lib/common/fpccompatibility/formatfunc.pas new file mode 100644 index 0000000..66ced7a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/formatfunc.pas @@ -0,0 +1,470 @@ +{ + ********************************************************************* + Copyright (C) 1997, 1998 Gertjan Schouten + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + ********************************************************************** + + System Utilities For Free Pascal +} + +unit formatfunc; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseformatstr,msetypes; + +function unicodeformat (const fmt : unicodestring; const args : array of const; + const formatsettings: tformatsettingsmse) : msestring; + +implementation +uses + sysutils,sysconst,msefloattostr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +Const + feInvalidFormat = 1; + feMissingArgument = 2; + feInvalidArgIndex = 3; + +Procedure DoFormatError (ErrCode : Longint;const fmt:ansistring); +Var + S : String; +begin + //!! must be changed to contain format string... + S:=fmt; + Case ErrCode of + feInvalidFormat : raise EConvertError.Createfmt(SInvalidFormat,[s]); + feMissingArgument : raise EConvertError.Createfmt(SArgumentMissing,[s]); + feInvalidArgIndex : raise EConvertError.Createfmt(SInvalidArgIndex,[s]); + end; +end; + +function floattostrf(value: double; format: tfloatformat; + precision, digits: integer; + const formatsettings: tformatsettingsmse): msestring; + //todo: digits, currency format and the like +var + m1: floatstringmodety; + sep1: msechar; +begin + sep1:= #0; + m1:= fsm_default; + case format of + ffExponent: begin + m1:= fsm_sci; + end; + ffFixed: begin + m1:= fsm_fix; + end; + ffNumber,ffCurrency: begin + m1:= fsm_fix; + sep1:= formatsettings.thousandseparator; + end; + end; + result:= doubletostring(value,precision,m1,formatsettings.decimalseparator, + sep1); +end; + +{$macro on} +{$define INWIDEFORMAT} +{$define TFormatString:=unicodestring} +{$define TFormatChar:=unicodechar} + +Function UnicodeFormat (Const Fmt : UnicodeString; const Args : Array of const; + Const FormatSettings: TFormatSettingsmse) : UnicodeString; + +Var ChPos,OldPos,ArgPos,DoArg,Len : SizeInt; + Hs,ToAdd : TFormatString; + Index : SizeInt; + Width,Prec : Longint; + Left : Boolean; + Fchar : char; + vq : qword; + + { + ReadFormat reads the format string. It returns the type character in + uppercase, and sets index, Width, Prec to their correct values, + or -1 if not set. It sets Left to true if left alignment was requested. + In case of an error, DoFormatError is called. + } + + Function ReadFormat : Char; + + Var Value : longint; + + Procedure ReadInteger; + + var + Code: Word; + ArgN: SizeInt; + begin + If Value<>-1 then exit; // Was already read. + OldPos:=ChPos; + While (ChPos<=Len) and + (Fmt[ChPos]<='9') and (Fmt[ChPos]>='0') do inc(ChPos); + If ChPos>len then + DoFormatError(feInvalidFormat,ansistring(Fmt)); + If Fmt[ChPos]='*' then + begin + + if Index=-1 then + ArgN:=Argpos + else + begin + ArgN:=Index; + Inc(Index); + end; + + If (ChPos>OldPos) or (ArgN>High(Args)) then + DoFormatError(feInvalidFormat,ansistring(Fmt)); + + ArgPos:=ArgN+1; + + case Args[ArgN].Vtype of + vtInteger: Value := Args[ArgN].VInteger; + vtInt64: Value := Args[ArgN].VInt64^; + vtQWord: Value := Args[ArgN].VQWord^; + else + DoFormatError(feInvalidFormat,ansistring(Fmt)); + end; + Inc(ChPos); + end + else + begin + If (OldPos0 then DoFormatError (feInvalidFormat,ansistring(Fmt)); + end + else + Value:=-1; + end; + end; + + Procedure ReadIndex; + + begin + If Fmt[ChPos]<>':' then + ReadInteger + else + value:=0; // Delphi undocumented behaviour, assume 0, #11099 + If Fmt[ChPos]=':' then + begin + If Value=-1 then DoFormatError(feMissingArgument,ansistring(Fmt)); + Index:=Value; + Value:=-1; + Inc(ChPos); + end; +{$ifdef fmtdebug} + Log ('Read index'); +{$endif} + end; + + Procedure ReadLeft; + + begin + If Fmt[ChPos]='-' then + begin + left:=True; + Inc(ChPos); + end + else + Left:=False; +{$ifdef fmtdebug} + Log ('Read Left'); +{$endif} + end; + + Procedure ReadWidth; + + begin + ReadInteger; + If Value<>-1 then + begin + Width:=Value; + Value:=-1; + end; +{$ifdef fmtdebug} + Log ('Read width'); +{$endif} + end; + + Procedure ReadPrec; + + begin + If Fmt[ChPos]='.' then + begin + inc(ChPos); + ReadInteger; + If Value=-1 then + Value:=0; + prec:=Value; + end; +{$ifdef fmtdebug} + Log ('Read precision'); +{$endif} + end; + +{$ifdef INWIDEFORMAT} + var + FormatChar : TFormatChar; +{$endif INWIDEFORMAT} + + begin +{$ifdef fmtdebug} + Log ('Start format'); +{$endif} + Index:=-1; + Width:=-1; + Prec:=-1; + Value:=-1; + inc(ChPos); + If Fmt[ChPos]='%' then + begin + Result:='%'; + exit; // VP fix + end; + ReadIndex; + ReadLeft; + ReadWidth; + ReadPrec; +{$ifdef INWIDEFORMAT} + FormatChar:=UpCase(UnicodeChar(Fmt[ChPos])); + if word(FormatChar)>255 then + ReadFormat:=#255 + else + ReadFormat:=FormatChar; +{$else INWIDEFORMAT} + ReadFormat:=Upcase(Fmt[ChPos]); +{$endif INWIDEFORMAT} +{$ifdef fmtdebug} + Log ('End format'); +{$endif} +end; + + +{$ifdef fmtdebug} +Procedure DumpFormat (C : char); +begin + Write ('Fmt : ',fmt:10); + Write (' Index : ',Index:3); + Write (' Left : ',left:5); + Write (' Width : ',Width:3); + Write (' Prec : ',prec:3); + Writeln (' Type : ',C); +end; +{$endif} + + +function Checkarg (AT : SizeInt;err:boolean):boolean; +{ + Check if argument INDEX is of correct type (AT) + If Index=-1, ArgPos is used, and argpos is augmented with 1 + DoArg is set to the argument that must be used. +} +begin + result:=false; + if Index=-1 then + DoArg:=Argpos + else + DoArg:=Index; + ArgPos:=DoArg+1; + If (Doarg>High(Args)) or (Args[Doarg].Vtype<>AT) then + begin + if err then + DoFormatError(feInvalidArgindex,ansistring(Fmt)); + dec(ArgPos); + exit; + end; + result:=true; +end; + +begin + Result:=''; + Len:=Length(Fmt); + ChPos:=1; + OldPos:=1; + ArgPos:=0; + While ChPos<=len do + begin + While (ChPos<=Len) and (Fmt[ChPos]<>'%') do + inc(ChPos); + If ChPos>OldPos Then + Result:=Result+Copy(Fmt,OldPos,ChPos-Oldpos); + If ChPos'-' then + ToAdd:=TFormatString(StringOfChar('0',Index))+ToAdd + else + // + 1 to accomodate for - sign in length !! + Insert(TFormatString(StringOfChar('0',Index+1)),toadd,2); + end; + 'U' : begin + if Checkarg(vtinteger,false) then + Str(cardinal(Args[Doarg].VInteger),ToAdd) + else if CheckArg(vtInt64,false) then + Str(qword(Args[DoArg].VInt64^),toadd) + else if CheckArg(vtQWord,true) then + Str(Args[DoArg].VQWord^,toadd); + Width:=Abs(width); + Index:=Prec-Length(ToAdd); + ToAdd:=TFormatString(StringOfChar('0',Index))+ToAdd + end; +{$ifndef FPUNONE} + 'E' : begin + if CheckArg(vtCurrency,false) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VCurrency^,ffexponent,Prec,3,FormatSettings)) + else if CheckArg(vtExtended,true) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VExtended^,ffexponent,Prec,3,FormatSettings)); + end; + 'F' : begin + if CheckArg(vtCurrency,false) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VCurrency^,ffFixed,9999,Prec,FormatSettings)) + else if CheckArg(vtExtended,true) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VExtended^,ffFixed,9999,Prec,FormatSettings)); + end; + 'G' : begin + if CheckArg(vtCurrency,false) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VCurrency^,ffGeneral,Prec,3,FormatSettings)) + else if CheckArg(vtExtended,true) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VExtended^,ffGeneral,Prec,3,FormatSettings)); + end; + 'N' : begin + if CheckArg(vtCurrency,false) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VCurrency^,ffNumber,9999,Prec,FormatSettings)) + else if CheckArg(vtExtended,true) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VExtended^,ffNumber,9999,Prec,FormatSettings)); + end; + 'M' : begin + if CheckArg(vtExtended,false) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VExtended^,ffCurrency,9999,Prec,FormatSettings)) + else if CheckArg(vtCurrency,true) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VCurrency^,ffCurrency,9999,Prec,FormatSettings)); + end; +{$else} + 'E','F','G','N','M': + RunError(207); +{$endif} + 'S' : begin + if CheckArg(vtString,false) then + hs:=TFormatString(Args[doarg].VString^) + else + if CheckArg(vtChar,false) then + hs:=TFormatString(Args[doarg].VChar) + else + if CheckArg(vtPChar,false) then + hs:=TFormatString(Args[doarg].VPChar) + else + if CheckArg(vtPWideChar,false) then + hs:=TFormatString(WideString(Args[doarg].VPWideChar)) + else + if CheckArg(vtWideChar,false) then + hs:=TFormatString(WideString(Args[doarg].VWideChar)) + else + if CheckArg(vtWidestring,false) then + hs:=TFormatString(WideString(Args[doarg].VWideString)) + else + if CheckArg(vtAnsiString,false) then + hs:=TFormatString(ansistring(Args[doarg].VAnsiString)) + else + if CheckArg(vtUnicodeString,false) then + hs:=TFormatString(UnicodeString(Args[doarg].VUnicodeString)) + else + if CheckArg(vtVariant,true) then + hs:=Args[doarg].VVariant^; + Index:=Length(hs); + If (Prec<>-1) and (Index>Prec) then + Index:=Prec; + ToAdd:=Copy(hs,1,Index); + end; + 'P' : Begin + CheckArg(vtpointer,true); + ToAdd:=TFormatString(HexStr(ptruint(Args[DoArg].VPointer),sizeof(Ptruint)*2)); + // Insert ':'. Is this needed in 32 bit ? No it isn't. + // Insert(':',ToAdd,5); + end; + 'X' : begin + if Checkarg(vtinteger,false) then + begin + vq:=Cardinal(Args[Doarg].VInteger); + index:=16; + end + else + if CheckArg(vtQWord, false) then + begin + vq:=Qword(Args[DoArg].VQWord^); + index:=31; + end + else + begin + CheckArg(vtInt64,true); + vq:=Qword(Args[DoArg].VInt64^); + index:=31; + end; + If Prec>index then + ToAdd:=TFormatString(HexStr(int64(vq),index)) + else + begin + // determine minimum needed number of hex digits. + Index:=1; + While (qWord(1) shl (Index*4)<=vq) and (index<16) do + inc(Index); + If Index>Prec then + Prec:=Index; + ToAdd:=TFormatString(HexStr(int64(vq),Prec)); + end; + end; + '%': ToAdd:='%'; + end; + If Width<>-1 then + If Length(ToAdd) $ffff then + result := $ffff + else + result := temp; +end; + +(* +type + TColorBits = array [0..3] of TColorData; + // 0:alpha, 1:red, 2:green, 3:blue + TShiftBits = array [0..3] of shortint; + +const + ColorBits : array[cfRGB15..cfABGR64] of TColorBits = ( + // alpha red green blue + {cfRGB15} ($00000000, $00007C00, $000003E0, $0000001F), + {cfRGB16} ($00000000, $00007C00, $000003E0, $0000001F), + {cfRGB24} ($00000000, $00FF0000, $0000FF00, $000000FF), + {cfRGB32} ($00000000, $00FF0000, $0000FF00, $000000FF), + {cfRGB48} ($00000000, $FFFF0000, $FFFF0000, $0000FFFF), + // shl 16 + {cfRGBA8} ($00000003, $000000C0, $00000030, $0000000C), + {cfRGBA16}($0000000F, $0000F000, $00000F00, $000000F0), + {cfRGBA32}($000000FF, $FF000000, $00FF0000, $0000FF00), + {cfRGBA64}($0000FFFF, $FFFF0000, $FFFF0000, $FFFF0000), + // shl 32 shl 16 + {cfBGR15} ($00000000, $0000001F, $000003E0, $00007C00), + {cfBGR16} ($00000000, $0000001F, $000003E0, $00007C00), + {cfBGR24} ($00000000, $000000FF, $0000FF00, $00FF0000), + {cfBGR32} ($00000000, $000000FF, $0000FF00, $00FF0000), + {cfBGR48} ($00000000, $0000FFFF, $FFFF0000, $FFFF0000), + // shl 16 + {cfABGR8} ($000000C0, $00000003, $0000000C, $00000030), + {cfABGR16}($0000F000, $0000000F, $000000F0, $00000F00), + {cfABGR32}($FF000000, $000000FF, $0000FF00, $00FF0000), + {cfABGR64}($FFFF0000, $0000FFFF, $FFFF0000, $FFFF0000) + // shl 32 shl 16 + ); + ShiftBits : array[cfRGB15..cfABGR64] of TShiftBits = ( // <0:shl, >0:shr + {cfRGB15} ( 0, -1, -6, -11), + {cfRGB16} ( 0, -1, -6, -11), + {cfRGB24} ( 0, 8, 0, -8), + {cfRGB32} ( 0, 8, 0, -8), + {cfRGB48} ( 0, 32, 16, 0), + {cfRGBA8} (-14, -8, -10, -12), + {cfRGBA16}(-12, 0, -4, -8), + {cfRGBA32}( -8, 16, 8, 0), + {cfRGBA64}( 0, 48, 32, 16), + {cfBGR15} ( 0, -11, -6, -1), + {cfBGR16} ( 0, -11, -6, -1), + {cfBGR24} ( 0, -8, 0, 8), + {cfBGR32} ( 0, -8, 0, 8), + {cfBGR48} ( 0, 0, 16, 32), + {cfBGRA8} ( -8, -14, -12, -10), + {cfBGRA16}( 0, -12, -8, -4), + {cfBGRA32}( 16, -8, 0, 8), + {cfBGRA64}( 48, 0, 16, 32) + ); + Bitdepths : array[cfRGB15..cfABGR64] of byte= + (5,5,8,8,16, 2,4,8,16, 5,5,8,8,16, 2,4,8,16); + +function EnlargeColor (data:TColorData;CFmt:TColorFormat;component:byte):word; +var w : word; + i : TColorData; + s : shortint; +begin + i := data and ColorBits[CFmt,component]; + s := ShiftBits[CFmt,component]; + if s = 0 then + w := i + else if s < 0 then + w := i shl -s + else + w := i shr s; + result := FillOtherBits (w ,BitDepths[CFmt]); +end; + +function ConvertColor (const From : TColorData; FromFmt:TColorFormat) : TFPColor; + function SetGrayScale (value : word) : TFPColor; + begin + with result do + begin + red := Value; + green := value; + blue := Value; + end; + end; + function SetGrayScaleA (value : word) : TFPColor; + begin + result := SetGrayScale (value); + result.alpha := alphaOpaque; + end; +var m : qword; +begin + case FromFmt of + cfMono : result := SetGrayScaleA (ShiftAndFill(From,1)); + cfGray2 : result := SetGrayScaleA (ShiftAndFill(From,2)); + cfGray4 : result := SetGrayScaleA (ShiftAndFill(From,4)); + cfGray8 : result := SetGrayScaleA (ShiftAndFill(From,8)); + cfGray16 : result := SetGrayScaleA (From); + cfGray24 : result := SetGrayScaleA ((From and $00FFFF00) shr 8); + cfGrayA8 : + begin + result := SetGrayScale (FillOtherBits((From and $000000F0) shl 8,4)); + result.alpha := ShiftAndFill((From and $0000000F),4); + end; + cfGrayA16 : + begin + result := SetGrayScale (FillOtherBits((From and $0000FF00),8)); + result.alpha := ShiftAndFill((From and $000000FF),8); + end; + cfGrayA32 : + begin + result := SetGrayScale ((From and $FFFF0000) shr 16); + result.alpha := (From and $0000FFFF); + end; + cfRGB15,cfRGB16,cfRGB24,cfRGB32,cfRGB48, + cfBGR15,cfBGR16,cfBGR24,cfBGR32,cfBGR48 : + begin + result.alpha := AlphaOpaque; + result.red := EnlargeColor(From, FromFmt, 1); + result.green := EnlargeColor(From, FromFmt, 2); + result.blue := EnlargeColor(From, FromFmt, 3); + end; + cfRGBA8,cfRGBA16,cfRGBA32,cfRGBA64, + cfABGR8,cfABGR16,cfABGR32,cfABGR64 : + begin + result.alpha := EnlargeColor(From, FromFmt, 0); + result.red := EnlargeColor(From, FromFmt, 1); + result.green := EnlargeColor(From, FromFmt, 2); + result.blue := EnlargeColor(From, FromFmt, 3); + end; + end; +end; + +function ConvertColor (const From : TDeviceColor) : TFPColor; +begin + result := ConvertColor (From.data, From.Fmt) +end; + +const BitMasks : array[1..32] of longword = + ($8000000, $C000000, $E000000, $F000000, + $F800000, $FC00000, $FE00000, $FF00000, + $FF80000, $FFC0000, $FFE0000, $FFF0000, + $FFF8000, $FFFC000, $FFFE000, $FFFF000, + $FFFF800, $FFFFC00, $FFFFE00, $FFFFF00, + $FFFFF80, $FFFFFC0, $FFFFFE0, $FFFFFF0, + $FFFFFF8, $FFFFFFC, $FFFFFFE, $FFFFFFF, + $FFFFFFF, $FFFFFFF, $FFFFFFF, $FFFFFFF); + +procedure PrepareBitMasks; +{ Putting the correct bits in the array (problem with constants in compiler 1.0)} +var r : integer; +begin + for r := 1 to 32 do + BitMasks[r] := BitMasks[r] shl 4; + inc (BitMasks[29], $8); + inc (BitMasks[30], $C); + inc (BitMasks[31], $E); + inc (BitMasks[32], $F); +end; + +function CalculateGray (const c : TFPcolor; Bits:byte) : TColorData; +var temp : longword; +begin + with GrayConvMatrix do + temp := round(red*c.red + green*c.green + blue*c.blue); + result := temp; + //temp := temp + (result shl 16); + //result := temp and BitMasks[Bits]; + {if not (c = colBlack) then + with c do + //writeln ('red:',red,' - green:',green,' - blue:',blue, ' : result=',result); + writeln (format('red:%4x - green:%4x - blue:%4x => result:%4x',[integer(red), + integer(green),integer(blue),integer(result)]));} +end; + +function CalculateGrayA (const c : TFPcolor; Bits:byte) : TColorData; +var r : longword; + d : byte; +begin + d := bits div 2; + r := CalculateGray (c, d); + result := r shl d; + r := c.alpha shr (16-d); + result := result or r; +end; + +function ConvertColorToData (const From : TFPColor; Fmt : TColorFormat) : TColorData; +var sb : TShiftBits; + cb : TColorBits; + function MakeSample (Value:word; ToShift:shortint; ToUse:TColorData) : TColorData; + var sh : word; + begin + result := Value; + if ToShift >= 0 then + begin + sh := ToShift; // if not converting first to word, there will be a + result := result shl Sh; // color shift + end + else + begin + sh := -ToShift; + result := result shr Sh; + end; + result := result and ToUse; + end; +begin + case Fmt of + cfMono : result := CalculateGray (From,1); + cfGray2 : result := CalculateGray (From,2); + cfGray4 : result := CalculateGray (From,4); + cfGray8 : result := CalculateGray (From,8); + cfGray16 : result := CalculateGray (From,16); + cfGray24 : result := CalculateGray (From,24); + cfGrayA8 : result := CalculateGrayA (From, 8); + cfGrayA16 : result := CalculateGrayA (From, 16); + cfGrayA32 : result := CalculateGrayA (From, 32); + cfRGB15,cfRGB16,cfRGB24,cfRGB32,cfRGB48, + cfBGR15,cfBGR16,cfBGR24,cfBGR32,cfBGR48 : + begin + sb := ShiftBits[Fmt]; + cb := ColorBits[Fmt]; + result := MakeSample(From.blue, sb[3], cb[3]) or + MakeSample(From.red, sb[1], cb[1]) or + MakeSample(From.green, sb[2], cb[2]); + {$ifdef FPC_Debug_Image} + with From do + writeln (red,',',green,',',blue,',',result); + end; + {$endif} + cfRGBA8,cfRGBA16,cfRGBA32,cfRGBA64, + cfABGR8,cfABGR16,cfABGR32,cfABGR64 : + begin + sb := ShiftBits[Fmt]; + cb := ColorBits[Fmt]; + result := MakeSample(From.alpha, sb[0], cb[0]) or + MakeSample(From.red, sb[1], cb[1]) or + MakeSample(From.green, sb[2], cb[2]) or + MakeSample(From.blue, sb[3], cb[3]); + end; + end; +end; + +function ConvertColor (const From : TFPColor; Fmt : TColorFormat) : TDeviceColor; +begin + result.Fmt := Fmt; + result.data := convertColorToData(From, Fmt); +end; + +function ConvertColorToData (const From : TDeviceColor; Fmt : TColorFormat) : TColorData; +var c : TFPColor; +begin + c := ConvertColor (From); + result := ConvertColorToData (c, Fmt); +end; + +function ConvertColor (const From : TDeviceColor; Fmt : TColorFormat) : TDeviceColor; +begin + result.Fmt := Fmt; + result.data := ConvertColorToData (From, Fmt); +end; +*) + +function AlphaBlend(color1, color2: TFPColor): TFPColor; +var + factor: single; +begin + if color2.alpha = $ffff then + Result := color2 + else + begin + factor := (color1.alpha / $ffff) * (1 - color2.alpha / $ffff); + + Result.red := Round(color1.red * factor + color2.red * color2.alpha / $ffff); + Result.green := Round(color1.green * factor + color2.green * color2.alpha / $ffff); + Result.blue := Round(color1.blue * factor + color2.blue * color2.alpha / $ffff); + Result.alpha := Round(factor * $ffff + color2.alpha); + end; +end; + +function CompareColors(const Color1, Color2: TFPColor): integer; +begin + Result:=integer(Color1.Red)-integer(Color2.Red); + if Result<>0 then exit; + Result:=integer(Color1.Green)-integer(Color2.Green); + if Result<>0 then exit; + Result:=integer(Color1.Blue)-integer(Color2.Blue); + if Result<>0 then exit; + Result:=integer(Color1.Alpha)-integer(Color2.Alpha); +end; + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpcolors.inc b/mseide-msegui/lib/common/fpccompatibility/fpcolors.inc new file mode 100644 index 0000000..eb4a1d1 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpcolors.inc @@ -0,0 +1,49 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + Color definitions and functions. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +const + BytesNeeded : array[TColorFormat] of byte = + (1,1,1,1,2,3,1,2,4,2,2,3,4,6,1,2,4,8,2,2,3,4,6,1,2,4,8); + + alphaTransparent = $0000; + alphaOpaque = $FFFF; + colTransparent: TFPColor = (Red: $0000; Green: $0000; Blue: $0000; Alpha: alphaTransparent); + colBlack : TFPColor = (Red: $0000; Green: $0000; Blue: $0000; Alpha: alphaOpaque); + colBlue : TFPColor = (Red: $0000; Green: $0000; Blue: $ffff; Alpha: alphaOpaque); + colGreen : TFPColor = (Red: $0000; Green: $ffff; Blue: $0000; Alpha: alphaOpaque); + colCyan : TFPColor = (Red: $0000; Green: $ffff; Blue: $ffff; Alpha: alphaOpaque); + colRed : TFPColor = (Red: $ffff; Green: $0000; Blue: $0000; Alpha: alphaOpaque); + colMagenta : TFPColor = (Red: $ffff; Green: $0000; Blue: $ffff; Alpha: alphaOpaque); + colYellow : TFPColor = (Red: $ffff; Green: $ffff; Blue: $0000; Alpha: alphaOpaque); + colWhite : TFPColor = (Red: $ffff; Green: $ffff; Blue: $ffff; Alpha: alphaOpaque); + colGray : TFPColor = (Red: $8000; Green: $8000; Blue: $8000; Alpha: alphaOpaque); + colLtGray : TFPColor = (Red: $c000; Green: $c000; Blue: $c000; Alpha: alphaOpaque); + colDkGray : TFPColor = (Red: $4000; Green: $4000; Blue: $4000; Alpha: alphaOpaque); + colDkBlue : TFPColor = (Red: $0000; Green: $0000; Blue: $8000; Alpha: alphaOpaque); + colDkGreen : TFPColor = (Red: $0000; Green: $8000; Blue: $0000; Alpha: alphaOpaque); + colDkCyan : TFPColor = (Red: $0000; Green: $8000; Blue: $8000; Alpha: alphaOpaque); + colDkRed : TFPColor = (Red: $8000; Green: $0000; Blue: $0000; Alpha: alphaOpaque); + colDkMagenta : TFPColor = (Red: $8000; Green: $0000; Blue: $8000; Alpha: alphaOpaque); + colDkYellow : TFPColor = (Red: $8000; Green: $8000; Blue: $0000; Alpha: alphaOpaque); + colMaroon : TFPColor = (Red: $8000; Green: $0000; Blue: $0000; Alpha: alphaOpaque); + colLtGreen : TFPColor = (Red: $0000; Green: $8000; Blue: $0000; Alpha: alphaOpaque); + colOlive : TFPColor = (Red: $8000; Green: $8000; Blue: $0000; Alpha: alphaOpaque); + colNavy : TFPColor = (Red: $0000; Green: $0000; Blue: $8000; Alpha: alphaOpaque); + colPurple : TFPColor = (Red: $8000; Green: $0000; Blue: $8000; Alpha: alphaOpaque); + colTeal : TFPColor = (Red: $0000; Green: $8000; Blue: $8000; Alpha: alphaOpaque); + colSilver : TFPColor = (Red: $c000; Green: $c000; Blue: $c000; Alpha: alphaOpaque); + colLime : TFPColor = (Red: $0000; Green: $ffff; Blue: $0000; Alpha: alphaOpaque); + colFuchsia : TFPColor = (Red: $ffff; Green: $0000; Blue: $ffff; Alpha: alphaOpaque); + colAqua : TFPColor = (Red: $0000; Green: $ffff; Blue: $ffff; Alpha: alphaOpaque); + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpcompactimg.inc b/mseide-msegui/lib/common/fpccompatibility/fpcompactimg.inc new file mode 100644 index 0000000..ec0b81b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpcompactimg.inc @@ -0,0 +1,602 @@ +{%MainUnit fpimage.pp} +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2012 by the Free Pascal development team + + Compact images (images with less than 64-bit depth) support, by Mattias Gaertner + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +//modified 2013 by MArtin Schreiber + +function GetFPCompactImgDesc(Gray: boolean; Depth: word; HasAlpha: boolean + ): TFPCompactImgDesc; +begin + Result.Gray:=Gray; + Result.Depth:=Depth; + Result.HasAlpha:=HasAlpha; +end; + +function GetFPCompactImgClass(const Desc: TFPCompactImgDesc): TFPCompactImgBaseClass; +begin + if Desc.Gray then begin + if Desc.HasAlpha then begin + // gray, alpha + if Desc.Depth<=8 then + Result:=TFPCompactImgGrayAlpha8Bit + else + Result:=TFPCompactImgGrayAlpha16Bit; + end else begin + // gray, no alpha + if Desc.Depth<=8 then + Result:=TFPCompactImgGray8Bit + else + Result:=TFPCompactImgGray16Bit; + end; + end else begin + // RGB + if Desc.HasAlpha then begin + // RGB, alpha + if Desc.Depth<=8 then + Result:=TFPCompactImgRGBA8Bit + else + Result:=TFPCompactImgRGBA16Bit; + end else begin + // RGB, no alpha + if Desc.Depth<=8 then + Result:=TFPCompactImgRGB8Bit + else + Result:=TFPCompactImgRGB16Bit; + end; + end; +end; + +function CreateFPCompactImg(const Desc: TFPCompactImgDesc; Width, Height: integer + ): TFPCustomImage; +var + ImgClass: TFPCompactImgBaseClass; +begin + ImgClass:=GetFPCompactImgClass(Desc); + Result:=ImgClass.Create(Width,Height); +end; + +function CreateCompatibleFPCompactImg(Img: TFPCustomImage; Width, Height: integer + ): TFPCustomImage; +begin + if Img is TFPCompactImgBase then + Result:=CreateFPCompactImg(TFPCompactImgBase(Img).Desc,Width,Height) + else + Result:=CreateFPCompactImg(GetMinimumPTDesc(Img),Width,Height); +end; + +function CreateCompatibleFPCompactImgWithAlpha(Img: TFPCustomImage; Width, + Height: integer): TFPCustomImage; +var + Desc: TFPCompactImgDesc; +begin + if Img is TFPCompactImgBase then + Desc:=TFPCompactImgBase(Img).Desc + else + Desc:=GetMinimumPTDesc(Img); + Desc.HasAlpha:=true; + Result:=CreateFPCompactImg(Desc,Width,Height); +end; + +function GetMinimumPTDesc(Img: TFPCustomImage; FuzzyDepth: word = 4): TFPCompactImgDesc; +var + AllLoEqualsHi, AllLoAre0: Boolean; + FuzzyMaskLoHi: Word; + + procedure Need16Bit(c: word); {$ifdef FPC}inline;{$endif} + var + l: Byte; + begin + c:=c and FuzzyMaskLoHi; + l:=Lo(c); + AllLoAre0:=AllLoAre0 and (l=0); + AllLoEqualsHi:=AllLoEqualsHi and (l=Hi(c)); + end; + +var + TestGray: Boolean; + TestAlpha: Boolean; + Test16Bit: Boolean; + BaseImg: TFPCompactImgBase; + ImgDesc: TFPCompactImgDesc; + y: Integer; + x: Integer; + col: TFPColor; + FuzzyMaskWord: Word; + FuzzyOpaque: Word; +begin + TestGray:=true; + TestAlpha:=true; + Test16Bit:=FuzzyDepth<8; + Result.HasAlpha:=false; + Result.Gray:=true; + Result.Depth:=8; + if Img is TFPCompactImgBase then begin + BaseImg:=TFPCompactImgBase(Img); + ImgDesc:=BaseImg.Desc; + if ImgDesc.Depth<=8 then Test16Bit:=false; + if ImgDesc.Gray then TestGray:=false; + if not ImgDesc.HasAlpha then TestAlpha:=false; + end; + + if (not TestGray) and (not TestAlpha) and (not Test16Bit) then exit; + + FuzzyMaskWord:=Word($ffff) shl FuzzyDepth; + FuzzyOpaque:=alphaOpaque and FuzzyMaskWord; + FuzzyMaskLoHi:=Word(lo(FuzzyMaskWord))+(Word(lo(FuzzyMaskWord)) shl 8); + AllLoAre0:=true; + AllLoEqualsHi:=true; + for y:=0 to Img.Height-1 do begin + for x:=0 to Img.Width-1 do begin + col:=Img.Colors[x,y]; + if TestAlpha and ((col.alpha and FuzzyMaskWord)<>FuzzyOpaque) then begin + TestAlpha:=false; + Result.HasAlpha:=true; + if (not TestGray) and (not Test16Bit) then break; + end; + if TestGray + and ((col.red and FuzzyMaskWord)<>(col.green and FuzzyMaskWord)) + or ((col.red and FuzzyMaskWord)<>(col.blue and FuzzyMaskWord)) then begin + TestGray:=false; + Result.Gray:=false; + if (not TestAlpha) and (not Test16Bit) then break; + end; +{$warnings off} + if Test16Bit then begin + Need16Bit(col.red); + Need16Bit(col.green); + Need16Bit(col.blue); + Need16Bit(col.alpha); + if (not AllLoAre0) and (not AllLoEqualsHi) then begin + Test16Bit:=false; + Result.Depth:=16; + if (not TestAlpha) and (not TestGray) then break; + end; + end; + end; + end; +end; +{$warnings on} + +function GetMinimumFPCompactImg(Img: TFPCustomImage; FreeImg: boolean; + FuzzyDepth: word = 4): TFPCustomImage; +var + Desc: TFPCompactImgDesc; + ImgClass: TFPCompactImgBaseClass; + y: Integer; + x: Integer; +begin + Desc:=GetMinimumPTDesc(Img,FuzzyDepth); + ImgClass:=GetFPCompactImgClass(Desc); + if Img.ClassType=ImgClass then begin + result:= img; + exit; + end; + Result:=CreateFPCompactImg(Desc,Img.Width,Img.Height); + for y:=0 to Img.Height-1 do + for x:=0 to Img.Width-1 do + Result.Colors[x,y]:=Img.Colors[x,y]; + if FreeImg then + Img.Free; +end; + +function ColorRound (c : double) : word; +begin + if c > $FFFF then + result := $FFFF + else if c < 0.0 then + result := 0 + else + result := round(c); +end; + +{ TFPCompactImgGrayAlpha16Bit } + +function TFPCompactImgGrayAlpha16Bit.GetInternalColor(x, y: integer): TFPColor; +var + v: TFPCompactImgGrayAlpha16BitValue; +begin + v:= pFPCompactImgGrayAlpha16BitValueaty(FData)^[x+y*Width]; + Result.red:=v.g; + Result.green:=Result.red; + Result.blue:=Result.red; + Result.alpha:=v.a; +end; + +function TFPCompactImgGrayAlpha16Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgGrayAlpha16Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +var + v: TFPCompactImgGrayAlpha16BitValue; +begin + v.g:=Value.red; + v.a:=Value.alpha; + pFPCompactImgGrayAlpha16BitValueaty(FData)^[x+y*Width]:=v; +end; + +procedure TFPCompactImgGrayAlpha16Bit.SetInternalPixel(x, y: integer; Value: integer + ); +begin + +end; + +constructor TFPCompactImgGrayAlpha16Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(true,16,true); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgGrayAlpha16Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgGrayAlpha16Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPCompactImgGrayAlpha16BitValue)*AWidth*AHeight); + inherited SetSize(AWidth, AHeight); +end; + +{ TFPCompactImgGrayAlpha8Bit } + +function TFPCompactImgGrayAlpha8Bit.GetInternalColor(x, y: integer): TFPColor; +var + v: TFPCompactImgGrayAlpha8BitValue; +begin + v:= pFPCompactImgGrayAlpha8BitValueaty(FData)^[x+y*Width]; + Result.red:=(v.g shl 8)+v.g; + Result.green:=Result.red; + Result.blue:=Result.red; + Result.alpha:=(v.a shl 8)+v.a; +end; + +function TFPCompactImgGrayAlpha8Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgGrayAlpha8Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +var + v: TFPCompactImgGrayAlpha8BitValue; +begin + v.g:=Value.red shr 8; + v.a:=Value.alpha shr 8; + pFPCompactImgGrayAlpha8BitValueaty(FData)^[x+y*Width]:=v; +end; + +procedure TFPCompactImgGrayAlpha8Bit.SetInternalPixel(x, y: integer; Value: integer + ); +begin + +end; + +constructor TFPCompactImgGrayAlpha8Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(true,8,true); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgGrayAlpha8Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgGrayAlpha8Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPCompactImgGrayAlpha8BitValue)*AWidth*AHeight); + inherited SetSize(AWidth, AHeight); +end; + +{ TFPCompactImgGray16Bit } + +function TFPCompactImgGray16Bit.GetInternalColor(x, y: integer): TFPColor; +begin + Result.red:= pwordaty(FData)^[x+y*Width]; + Result.green:=Result.red; + Result.blue:=Result.red; + Result.alpha:=alphaOpaque; +end; + +function TFPCompactImgGray16Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgGray16Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +begin + pwordaty(FData)^[x+y*Width]:=Value.red; +end; + +procedure TFPCompactImgGray16Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgGray16Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(true,16,false); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgGray16Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgGray16Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(Word)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + +{ TFPCompactImgGray8Bit } + +function TFPCompactImgGray8Bit.GetInternalColor(x, y: integer): TFPColor; +begin + Result.red:=pbyteaty(FData)^[x+y*Width]; + Result.red:=(Word(Result.red) shl 8)+Result.red; + Result.green:=Result.red; + Result.blue:=Result.red; + Result.alpha:=alphaOpaque; +end; + +function TFPCompactImgGray8Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgGray8Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +begin + pbyteaty(FData)^[x+y*Width]:=Value.red shr 8; +end; + +procedure TFPCompactImgGray8Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgGray8Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(true,8,false); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgGray8Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgGray8Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(Byte)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + +{ TFPCompactImgRGBA8Bit } + +function TFPCompactImgRGBA8Bit.GetInternalColor(x, y: integer): TFPColor; +var + v: TFPCompactImgRGBA8BitValue; +begin + v:= pFPCompactImgRGBA8BitValueaty(FData)^[x+y*Width]; + Result.red:=(v.r shl 8)+v.r; + Result.green:=(v.g shl 8)+v.g; + Result.blue:=(v.b shl 8)+v.b; + Result.alpha:=(v.a shl 8)+v.a; +end; + +function TFPCompactImgRGBA8Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgRGBA8Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +var + v: TFPCompactImgRGBA8BitValue; +begin + v.r:=Value.red shr 8; + v.g:=Value.green shr 8; + v.b:=Value.blue shr 8; + v.a:=Value.alpha shr 8; + pFPCompactImgRGBA8BitValueaty(FData)^[x+y*Width]:=v; +end; + +procedure TFPCompactImgRGBA8Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgRGBA8Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(false,8,true); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgRGBA8Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgRGBA8Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPCompactImgRGBA8BitValue)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + +{ TFPCompactImgRGB8Bit } + +function TFPCompactImgRGB8Bit.GetInternalColor(x, y: integer): TFPColor; +var + v: TFPCompactImgRGB8BitValue; +begin + v:= pFPCompactImgRGB8BitValueaty(FData)^[x+y*Width]; + Result.red:=(v.r shl 8)+v.r; + Result.green:=(v.g shl 8)+v.g; + Result.blue:=(v.b shl 8)+v.b; + Result.alpha:=alphaOpaque; +end; + +function TFPCompactImgRGB8Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgRGB8Bit.SetInternalColor(x, y: integer; const Value: TFPColor + ); +var + v: TFPCompactImgRGB8BitValue; +begin + v.r:=Value.red shr 8; + v.g:=Value.green shr 8; + v.b:=Value.blue shr 8; + pFPCompactImgRGB8BitValueaty(FData)^[x+y*Width]:=v; +end; + +procedure TFPCompactImgRGB8Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgRGB8Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(false,8,false); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgRGB8Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgRGB8Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPCompactImgRGB8BitValue)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + +{ TFPCompactImgRGB16Bit } + +function TFPCompactImgRGB16Bit.GetInternalColor(x, y: integer): TFPColor; +var + v: TFPCompactImgRGB16BitValue; +begin + v:=pFPCompactImgRGB16BitValueaty(FData)^[x+y*Width]; + Result.red:=v.r; + Result.green:=v.g; + Result.blue:=v.b; + Result.alpha:=alphaOpaque; +end; + +function TFPCompactImgRGB16Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgRGB16Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +var + v: TFPCompactImgRGB16BitValue; +begin + v.r:=Value.red; + v.g:=Value.green; + v.b:=Value.blue; + pFPCompactImgRGB16BitValueaty(FData)^[x+y*Width]:=v; +end; + +procedure TFPCompactImgRGB16Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgRGB16Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(false,16,false); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgRGB16Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgRGB16Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPCompactImgRGB16BitValue)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + +{ TFPCompactImgRGBA16Bit } + +function TFPCompactImgRGBA16Bit.GetInternalColor(x, y: integer): TFPColor; +begin + Result:= pFPColoraty(FData)^[x+y*Width]; +end; + +function TFPCompactImgRGBA16Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgRGBA16Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +begin + pFPColoraty(FData)^[x+y*Width]:=Value; +end; + +procedure TFPCompactImgRGBA16Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgRGBA16Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(false,16,true); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgRGBA16Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgRGBA16Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPColor)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + + diff --git a/mseide-msegui/lib/common/fpccompatibility/fphandler.inc b/mseide-msegui/lib/common/fpccompatibility/fphandler.inc new file mode 100644 index 0000000..5e3a881 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fphandler.inc @@ -0,0 +1,275 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + TImageHandlers implementations + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +{ TImageHandlersManager } + +constructor TImageHandlersManager.Create; +begin + inherited create; + FData := Tlist.Create; +end; + +destructor TImageHandlersManager.Destroy; +var r : integer; +begin + for r := FData.count-1 downto 0 do + TIHData(FData[r]).Free; + FData.Free; + inherited Destroy; +end; + +function CalcDefExt (TheExtentions:string) : string; +var p : integer; +begin + p := pos (';',TheExtentions); + if p = 0 then + result := TheExtentions + else + result := copy(TheExtentions, 1, p-1); +end; + +procedure TImageHandlersManager.RegisterImageHandlers (const ATypeName,TheExtentions:string; + AReader:TFPCustomImageReaderClass; AWriter:TFPCustomImageWriterClass); +var ih : TIHData; +begin + ih := GetData (ATypeName); + if assigned (ih) then + FPImgError (StrTypeAlreadyExist,[ATypeName]); + ih := TIHData.Create; + with ih do + begin + FTypeName := ATypeName; + FExtention := lowercase(TheExtentions); + FDefaultExt := CalcDefExt (TheExtentions); + FReader := AReader; + FWriter := AWriter; + end; + FData.Add (ih); +end; + +procedure TImageHandlersManager.RegisterImageReader (const ATypeName,TheExtentions:string; + AReader:TFPCustomImageReaderClass); +var ih : TIHData; +begin + ih := GetData (ATypeName); + if assigned (ih) then + begin + if assigned (ih.FReader) then + FPImgError (StrTypeReaderAlreadyExist,[ATypeName]) + else + ih.FReader := AReader; + end + else + begin + ih := TIHData.Create; + with ih do + begin + FTypeName := ATypeName; + FExtention := Lowercase(TheExtentions); + FDefaultExt := CalcDefExt (TheExtentions); + FReader := AReader; + FWriter := nil; + end; + FData.Add (ih); + end; +end; + +procedure TImageHandlersManager.RegisterImageWriter (const ATypeName,TheExtentions:string; + AWriter:TFPCustomImageWriterClass); +var ih : TIHData; +begin + ih := GetData (ATypeName); + if assigned (ih) then + begin + if assigned (ih.FWriter) then + FPImgError (StrTypeWriterAlreadyExist,[ATypeName]) + else + ih.FWriter := AWriter; + end + else + begin + ih := TIHData.Create; + with ih do + begin + FTypeName := ATypeName; + FExtention := lowercase(TheExtentions); + FDefaultExt := CalcDefExt (TheExtentions); + FReader := nil; + FWriter := AWriter; + end; + FData.Add (ih); + end; +end; + +function TImageHandlersManager.GetCount : integer; +begin + result := FData.Count; +end; + +function TImageHandlersManager.GetData (const ATypeName:string) : TIHData; +var r : integer; +begin + r := FData.count; + repeat + dec (r); + until (r < 0) or (compareText (TIHData(FData[r]).FTypeName, ATypeName) = 0); + if r >= 0 then + result := TIHData(FData[r]) + else + result := nil; +end; + +function TImageHandlersManager.GetData (index:integer) : TIHData; +begin + if (index >= 0) and (index < FData.count) then + result := TIHData (FData[index]) + else + result := nil; +end; + +function TImageHandlersManager.GetTypeName (index:integer) : string; +var ih : TIHData; +begin + ih := TIHData (FData[index]); + result := ih.FTypeName; +end; + +function TImageHandlersManager.GetReader (const TypeName:string) : TFPCustomImageReaderClass; +var ih : TIHData; +begin + ih := GetData (TypeName); + if assigned(ih) then + result := ih.FReader + else + result := nil; +end; + +function TImageHandlersManager.GetWriter (const TypeName:string) : TFPCustomImageWriterClass; +var ih : TIHData; +begin + ih := GetData (TypeName); + if assigned(ih) then + result := ih.FWriter + else + result := nil; +end; + +function TImageHandlersManager.GetExt (const TypeName:string) : string; +var ih : TIHData; +begin + ih := GetData (TypeName); + if assigned(ih) then + result := ih.FExtention + else + result := ''; +end; + +function TImageHandlersManager.GetDefExt (const TypeName:string) : string; +var ih : TIHData; +begin + ih := GetData (TypeName); + if assigned(ih) then + result := ih.FDefaultExt + else + result := ''; +end; + +{ TFPCustomImageHandler } + +constructor TFPCustomImageHandler.create; +begin + inherited create; +end; + +procedure TFPCustomImageHandler.Progress(Stage: TProgressStage; + PercentDone: Byte; RedrawNow: Boolean; const R: TRect; + const Msg: AnsiString; var Continue: Boolean); + +begin + If Assigned(FOnProgress) then + FOnProgress(Self,Stage,PercentDone,RedrawNow,R,Msg,Continue) + else If Assigned(FImage) then + // It is debatable whether we should pass ourselves or the image ? + FImage.Progress(Self,Stage,PercentDone,RedrawNow,R,Msg,Continue); +end; + +{ TFPCustomImageReader } + +constructor TFPCustomImageReader.Create; +begin + inherited create; + FDefImageClass := TFPMemoryImage; +end; + +function TFPCustomImageReader.ImageRead (Str:TStream; Img:TFPCustomImage) : TFPCustomImage; +begin + try + if not assigned(Str) then + raise FPImageException.Create(ErrorText[StrNoStream]); + FStream := Str; + if not assigned(img) then + result := FDefImageClass.Create(0,0) + else + result := Img; + FImage := result; + if FImage.UsePalette then + FImage.Palette.Clear; + if CheckContents (Str) then + begin + InternalRead (Str, result) + end + else + raise FPImageException.Create ('Wrong image format'); + finally + FStream := nil; + FImage := nil; + end; +end; + +function TFPCustomImageReader.CheckContents (Str:TStream) : boolean; +var InRead : boolean; +begin + InRead := assigned(FStream); + if not assigned(Str) then + raise FPImageException.Create(ErrorText[StrNoStream]); + try + FSTream := Str; + result := InternalCheck (Str); + finally + if not InRead then + FStream := nil; + end; +end; + +{ TFPCustomImageWriter } + +procedure TFPCustomImageWriter.ImageWrite (Str:TStream; Img:TFPCustomImage); +begin + if not assigned(img) then + raise FPImageException.Create(ErrorText[StrNoImageToWrite]); + if not assigned(Str) then + raise FPImageException.Create(ErrorText[StrNoStream]); + try + FStream := str; + FImage := img; + Str.position := 0; + Str.Size := 0; + InternalWrite(Str, Img); + finally + FStream := nil; + FImage := nil; + end; +end; + + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpimage.inc b/mseide-msegui/lib/common/fpccompatibility/fpimage.inc new file mode 100644 index 0000000..ae78e39 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpimage.inc @@ -0,0 +1,558 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + TFPCustomImage implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +{ TFPCustomImage } + +constructor TFPCustomImage.create (AWidth,AHeight:integer); +begin + inherited create; + FExtra := TStringList.Create; + FWidth := 0; + FHeight := 0; + FPalette := nil; + SetSize (AWidth,AHeight); +end; + +destructor TFPCustomImage.destroy; +begin + FExtra.Free; + if assigned (FPalette) then + FPalette.Free; + inherited; +end; + +procedure TFPCustomImage.LoadFromStream (Str:TStream; Handler:TFPCustomImagereader); +begin + Handler.ImageRead (Str, self); +end; + +procedure TFPCustomImage.LoadFromFile (const filename:String; Handler:TFPCustomImageReader); +var + fs : TStream; +begin + if FileExists (filename) then + begin + fs := TFileStream.Create (filename, fmOpenRead); + try + LoadFromStream (fs, handler); + finally + fs.Free; + end; + end + else + FPImgError (StrNoFile, [filename]); +end; + +procedure TFPCustomImage.SaveToStream (Str:TStream; Handler:TFPCustomImageWriter); +begin + Handler.ImageWrite (Str, Self); +end; + +procedure TFPCustomImage.SaveToFile (const filename:String; Handler:TFPCustomImageWriter); +var + fs : TStream; +begin + fs := TFileStream.Create (filename, fmCreate); + try + SaveToStream (fs, handler); + finally + fs.Free; + end +end; + +procedure TFPCustomImage.SaveToFile (const filename:String); + +var e,s : string; + r : integer; +// f : TFileStream; + h : TFPCustomImageWriterClass; + Writer : TFPCustomImageWriter; + d : TIHData; + Msg : string; + +begin + e := lowercase (ExtractFileExt(filename)); + if (e <> '') and (e[1] = '.') then + delete (e,1,1); + with ImageHandlers do + begin + r := count-1; + s := e + ';'; + while (r >= 0) do + begin + d := GetData(r); + if (pos(s,d.Fextention+';') <> 0) then + try + h := d.FWriter; + if assigned (h) then + begin + Writer := h.Create; + try + SaveTofile (filename, Writer); + finally + Writer.Free; + end; + break; + end; + except + on e : exception do + Msg := e.message; + end; + dec (r); + end + end; + if (Msg<>'') then + FPImgError (StrWriteWithError, [Msg]); +end; + + +procedure TFPCustomImage.LoadFromStream (Str:TStream); +var r : integer; + h : TFPCustomImageReaderClass; + reader : TFPCustomImageReader; + msg : string; + d : TIHData; +begin + with ImageHandlers do + try + r := count-1; + while (r >= 0) do + begin + d := GetData(r); + if assigned (d) then + h := d.FReader; + if assigned (h) then + begin + reader := h.Create; + with reader do + try + if CheckContents (str) then + try + FStream := str; + FImage := self; + InternalRead (str, self); + break; + except + on e : exception do + msg := e.message; + end; + finally + Free; + str.seek (soFromBeginning, 0); + end; + end; + dec (r); + end; + except + on e : exception do + FPImgError (StrCantDetermineType, [e.message]); + end; + if r < 0 then + if msg = '' then + FPImgError (StrNoCorrectReaderFound) + else + FPImgError (StrReadWithError, [Msg]); +end; + +procedure TFPCustomImage.LoadFromFile (const filename:String); +var e,s : string; + r : integer; + f : TFileStream; + h : TFPCustomImageReaderClass; + reader : TFPCustomImageReader; + d : TIHData; + Msg : string; +begin + e := lowercase (ExtractFileExt(filename)); + if (e <> '') and (e[1] = '.') then + delete (e,1,1); + with ImageHandlers do + begin + r := count-1; + s := e + ';'; + while (r >= 0) do + begin + d := GetData(r); + if (pos(s,d.Fextention+';') <> 0) then + try + h := d.FReader; + if assigned (h) then + begin + reader := h.Create; + try + loadfromfile (filename, reader); + finally + Reader.Free; + end; + break; + end; + except + on e : exception do + Msg := e.message; + end; + dec (r); + end + end; + if Msg = '' then + begin + if r < 0 then + begin + f := TFileStream.Create (filename, fmOpenRead); + try + LoadFromStream (f); + finally + f.Free; + end; + end; + end + else + FPImgError (StrReadWithError, [Msg]); +end; + +procedure TFPCustomImage.SetHeight (Value : integer); +begin + if Value <> FHeight then + SetSize (FWidth, Value); +end; + +procedure TFPCustomImage.SetWidth (Value : integer); +begin + if Value <> FWidth then + SetSize (Value, FHeight); +end; + +procedure TFPCustomImage.SetSize (AWidth, AHeight : integer); +begin + FWidth := AWidth; + FHeight := AHeight; +end; + +procedure TFPCustomImage.SetExtraValue (index:integer; const AValue:string); +var s : string; + p : integer; +begin + s := FExtra[index]; + p := pos ('=', s); + if p > 0 then + FExtra[index] := copy(s, 1, p) + AValue + else + FPImgError (StrInvalidIndex,[ErrorText[StrImageExtra],index]); +end; + +function TFPCustomImage.GetExtraValue (index:integer) : string; +var s : string; + p : integer; +begin + s := FExtra[index]; + p := pos ('=', s); + if p > 0 then + result := copy(s, p+1, maxint) + else + result := ''; +end; + +procedure TFPCustomImage.SetExtraKey (index:integer; const AValue:string); +var s : string; + p : integer; +begin + s := FExtra[index]; + p := pos('=',s); + if p > 0 then + s := AValue + copy(s,p,maxint) + else + s := AValue; + FExtra[index] := s; +end; + +function TFPCustomImage.GetExtraKey (index:integer) : string; +begin + result := FExtra.Names[index]; +end; + +procedure TFPCustomImage.SetExtra (const key:String; const AValue:string); +begin + FExtra.values[key] := AValue; +end; + +function TFPCustomImage.GetExtra (const key:String) : string; +begin + result := FExtra.values[key]; +end; + +function TFPCustomImage.ExtraCount : integer; +begin + result := FExtra.count; +end; + +procedure TFPCustomImage.RemoveExtra (const key:string); +var p : integer; +begin + p := FExtra.IndexOfName(key); + if p >= 0 then + FExtra.Delete (p); +end; + +procedure TFPCustomImage.SetPixel (x,y:integer; Value:integer); +begin + CheckPaletteIndex (Value); + CheckIndex (x,y); + SetInternalPixel (x,y,Value); +end; + +function TFPCustomImage.GetPixel (x,y:integer) : integer; +begin + CheckIndex (x,y); + result := GetInternalPixel(x,y); +end; + +procedure TFPCustomImage.SetColor (x,y:integer; const Value:TFPColor); +begin + CheckIndex (x,y); + SetInternalColor (x,y,Value); +end; + +function TFPCustomImage.GetColor (x,y:integer) : TFPColor; +begin + CheckIndex (x,y); + result := GetInternalColor(x,y); +end; + +procedure TFPCustomImage.SetInternalColor (x,y:integer; const Value:TFPColor); +var i : integer; +begin + i := FPalette.IndexOf (Value); + SetInternalPixel (x,y,i); +end; + +function TFPCustomImage.GetInternalColor (x,y:integer) : TFPColor; +begin + result := FPalette.Color[GetInternalPixel(x,y)]; +end; + +function TFPCustomImage.GetUsePalette : boolean; +begin + result := assigned(FPalette); +end; + +procedure TFPCustomImage.SetUsePalette(Value:boolean); +begin + if Value <> assigned(FPalette) + then + if Value + then + begin + FPalette := TFPPalette.Create (0); + // FPalette.Add (colTransparent); + end + else + begin + FPalette.Free; + FPalette := nil; + end; +end; + +procedure TFPCustomImage.CheckPaletteIndex (PalIndex:integer); +begin + if UsePalette then + begin + if (PalIndex < -1) or (PalIndex >= FPalette.Count) then + FPImgError (StrInvalidIndex,[ErrorText[StrPalette],PalIndex]); + end + else + FPImgError (StrNoPaletteAvailable); +end; + +procedure TFPCustomImage.CheckIndex (x,y:integer); +begin + if (x < 0) or (x >= FWidth) then + FPImgError (StrInvalidIndex,[ErrorText[StrImageX],x]); + if (y < 0) or (y >= FHeight) then + FPImgError (StrInvalidIndex,[ErrorText[StrImageY],y]); +end; + +Procedure TFPCustomImage.Progress(Sender: TObject; Stage: TProgressStage; + PercentDone: Byte; RedrawNow: Boolean; const R: TRect; + const Msg: AnsiString; var Continue: Boolean); +begin + If Assigned(FOnProgress) then + FonProgress(Sender,Stage,PercentDone,RedrawNow,R,Msg,Continue); +end; + +Procedure TFPCustomImage.Assign(Source: TPersistent); + +Var + Src : TFPCustomImage; + X,Y : Integer; + +begin + If Source is TFPCustomImage then + begin + Src:=TFPCustomImage(Source); + // Copy extra info + FExtra.Assign(Src.Fextra); + // Copy palette if needed. + SetSize(0,0); { avoid side-effects in descendant classes } + UsePalette:=Src.UsePalette; + If UsePalette then + begin + Palette.Count:=0; + Palette.Merge(Src.Palette); + end; + // Copy image. + SetSize(Src.Width,Src.height); + If UsePalette then + For x:=0 to Src.Width-1 do + For y:=0 to src.Height-1 do + pixels[X,Y]:=src.pixels[X,Y] + else + For x:=0 to Src.Width-1 do + For y:=0 to src.Height-1 do + self[X,Y]:=src[X,Y]; + end + else + Inherited Assign(Source); +end; + +{ TFPMemoryImage } + +constructor TFPMemoryImage.Create (AWidth,AHeight:integer); +begin + Fdata := nil; + inherited create (AWidth,AHeight); + SetUsePalette(False); +end; + +destructor TFPMemoryImage.Destroy; +begin + // MG: missing if + if FData<>nil then + FreeMem (FData); + inherited Destroy; +end; + +function TFPMemoryImage.GetInternalColor(x,y:integer):TFPColor; + begin + if Assigned(FPalette) + then + Result:=inherited GetInternalColor(x,y) + else + Result:=PFPColorArray(FData)^[y*FWidth+x]; + end; + +function TFPMemoryImage.GetInternalPixel (x,y:integer) : integer; +begin + result := FData^[y*FWidth+x]; +end; + +procedure TFPMemoryImage.SetInternalColor (x,y:integer; const Value:TFPColor); + begin + if Assigned(FPalette) + then + inherited SetInternalColor(x,y,Value) + else + PFPColorArray(FData)^[y*FWidth+x]:=Value; + end; + +procedure TFPMemoryImage.SetInternalPixel (x,y:integer; Value:integer); +begin + FData^[y*FWidth+x] := Value; +end; + +function Lowest (a,b : integer) : integer; +begin + if a <= b then + result := a + else + result := b; +end; + +procedure TFPMemoryImage.SetSize (AWidth, AHeight : integer); +var w, h, r, old : integer; + NewData : PFPIntegerArray; +begin + if (AWidth <> Width) or (AHeight <> Height) then + begin + old := Height * Width; + r:=AWidth*AHeight; + if Assigned(FPalette) + then + r:=SizeOf(integer)*r + else + r:=SizeOf(TFPColor)*r; + if r = 0 then + NewData := nil + else + begin + GetMem (NewData, r); + {$ifdef FPC} + FillWord (Newdata^[0], r div sizeof(word), 0); + {$else} + Fillchar (Newdata^[0], r, 0); + {$endif} + end; + // MG: missing "and (NewData<>nil)" + if (old <> 0) and assigned(FData) and (NewData<>nil) then + begin + if r <> 0 then + begin + w := Lowest(Width, AWidth); + h := Lowest(Height, AHeight); + for r := 0 to h-1 do + move (FData^[r*Width], NewData^[r*AWidth], w); + end; + end; + if Assigned(FData) then FreeMem(FData); + FData := NewData; + inherited; + end; +end; + +procedure TFPMemoryImage.SetUsePalette(Value:boolean); +var + OldColors:PFPColorArray; + OldPixels:PFPIntegerArray; + r,c:Integer; +begin + if Value<>assigned(FPalette) + then + if Value + then + begin + FPalette:=TFPPalette.Create(0); + //FPalette.Add(colTransparent); + if assigned(FData) then + begin + OldColors:=PFPColorArray(FData); + GetMem(FData,FWidth*FHeight*SizeOf(Integer)); + for r:=0 to FHeight-1 do + for c:=0 to FWidth-1 do + Colors[c,r]:=OldColors^[r*FWidth+c]; + FreeMem(OldColors); + end; + end + else + begin + if Assigned(FData) then + begin + OldPixels:=PFPIntegerArray(FData); + GetMem(FData,FWidth*FHeight*SizeOf(TFPColor)); + for r:=0 to FHeight-1 do + for c:=0 to FWidth-1 do + Colors[c,r]:=FPalette.Color[OldPixels^[r*FWidth+c]]; + FreeMem(OldPixels); + end; + FPalette.Free; + FPalette:=nil; + end; +end; diff --git a/mseide-msegui/lib/common/fpccompatibility/fpimage.pas b/mseide-msegui/lib/common/fpccompatibility/fpimage.pas new file mode 100644 index 0000000..93a76b2 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpimage.pas @@ -0,0 +1,701 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + fpImage base definitions. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +//modified 2013 by Martin Schreiber + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +unit fpimage; + +interface + +uses + sysutils,classes,mclasses,msetypes{$ifndef FPC},classes_del,types{$endif}; + +type + + TFPCustomImageReader = class; + TFPCustomImageWriter = class; + TFPCustomImage = class; + + FPImageException = class (exception); + + TFPColor = record + red,green,blue,alpha : word; + end; + PFPColor = ^TFPColor; + FPColoraty = array[0..0] of TFPColor; + pFPColoraty = ^FPColoraty; + + TColorFormat = (cfMono,cfGray2,cfGray4,cfGray8,cfGray16,cfGray24, + cfGrayA8,cfGrayA16,cfGrayA32, + cfRGB15,cfRGB16,cfRGB24,cfRGB32,cfRGB48, + cfRGBA8,cfRGBA16,cfRGBA32,cfRGBA64, + cfBGR15,cfBGR16,cfBGR24,cfBGR32,cfBGR48, + cfABGR8,cfABGR16,cfABGR32,cfABGR64); + TColorData = qword; + PColorData = ^TColorData; + + TDeviceColor = record + Fmt : TColorFormat; + Data : TColorData; + end; + +{$ifdef CPU68K} + { 1.0 m68k cpu compiler does not allow + types larger than 32k.... + if we remove range checking all should be fine PM } + TFPColorArray = array [0..0] of TFPColor; +{$R-} +{$else not CPU68K} + TFPColorArray = array [0..(maxint-1) div sizeof(TFPColor)-1] of TFPColor; +{$endif CPU68K} + PFPColorArray = ^TFPColorArray; + + TFPImgProgressStage = (psStarting, psRunning, psEnding); + TFPImgProgressEvent = procedure (Sender: TObject; Stage: TFPImgProgressStage; + PercentDone: Byte; RedrawNow: Boolean; const R: TRect; + const Msg: AnsiString; var Continue : Boolean) of object; + // Delphi compatibility + TProgressStage = TFPImgProgressStage; + TProgressEvent = TFPImgProgressEvent; + + TFPPalette = class + protected + FData : PFPColorArray; + FCount, FCapacity : integer; + procedure SetCount (Value:integer); virtual; + function GetCount : integer; + procedure SetColor (index:integer; const Value:TFPColor); virtual; + function GetColor (index:integer) : TFPColor; + procedure SetCapacity (ind : Integer); + procedure CheckIndex (index:integer); virtual; + procedure EnlargeData; virtual; + public + constructor Create (ACount : integer); + destructor Destroy; override; + procedure Build (Img : TFPCustomImage); virtual; + procedure Copy (APalette: TFPPalette); virtual; + procedure Merge (pal : TFPPalette); virtual; + function IndexOf (const AColor: TFPColor) : integer; virtual; + function Add (const Value: TFPColor) : integer; virtual; + procedure Clear; virtual; + property Color [Index : integer] : TFPColor read GetColor write SetColor; default; + property Count : integer read GetCount write SetCount; + property Capacity : integer read FCapacity write SetCapacity; + end; + + TFPCustomImage = class(TPersistent) + private + FOnProgress : TFPImgProgressEvent; + FExtra : TStringlist; + FPalette : TFPPalette; + FHeight, FWidth : integer; + procedure SetHeight (Value : integer); + procedure SetWidth (Value : integer); + procedure SetExtra (const key:String; const AValue:string); + function GetExtra (const key:String) : string; + procedure SetExtraValue (index:integer; const AValue:string); + function GetExtraValue (index:integer) : string; + procedure SetExtraKey (index:integer; const AValue:string); + function GetExtraKey (index:integer) : string; + procedure CheckIndex (x,y:integer); + procedure CheckPaletteIndex (PalIndex:integer); + procedure SetColor (x,y:integer; const Value:TFPColor); + function GetColor (x,y:integer) : TFPColor; + procedure SetPixel (x,y:integer; Value:integer); + function GetPixel (x,y:integer) : integer; + function GetUsePalette : boolean; + protected + // Procedures to store the data. Implemented in descendants + procedure SetInternalColor (x,y:integer; const Value:TFPColor); virtual; + function GetInternalColor (x,y:integer) : TFPColor; virtual; + procedure SetInternalPixel (x,y:integer; Value:integer); virtual; abstract; + function GetInternalPixel (x,y:integer) : integer; virtual; abstract; + procedure SetUsePalette (Value:boolean);virtual; + procedure Progress(Sender: TObject; Stage: TProgressStage; + PercentDone: Byte; RedrawNow: Boolean; const R: TRect; + const Msg: AnsiString; var Continue: Boolean); Virtual; + public + constructor create (AWidth,AHeight:integer); virtual; + destructor destroy; override; + procedure Assign(Source: TPersistent); override; + // Saving and loading + procedure LoadFromStream (Str:TStream; + Handler:TFPCustomImageReader); overload; + procedure LoadFromStream (Str:TStream); overload; + procedure LoadFromFile (const filename:String; + Handler:TFPCustomImageReader); overload; + procedure LoadFromFile (const filename:String); overload; + procedure SaveToStream (Str:TStream; Handler:TFPCustomImageWriter); + procedure SaveToFile (const filename:String; + Handler:TFPCustomImageWriter); overload; + procedure SaveToFile (const filename:String); overload; + // Size and data + procedure SetSize (AWidth, AHeight : integer); virtual; + property Height : integer read FHeight write SetHeight; + property Width : integer read FWidth write SetWidth; + property Colors [x,y:integer] : TFPColor read GetColor write SetColor; default; + // Use of palette for colors + property UsePalette : boolean read GetUsePalette write SetUsePalette; + property Palette : TFPPalette read FPalette; + property Pixels [x,y:integer] : integer read GetPixel write SetPixel; + // Info unrelated with the image representation + property Extra [const key:string] : string read GetExtra write SetExtra; + property ExtraValue [index:integer] : string read GetExtraValue write SetExtraValue; + property ExtraKey [index:integer] : string read GetExtraKey write SetExtraKey; + procedure RemoveExtra (const key:string); + function ExtraCount : integer; + property OnProgress: TFPImgProgressEvent read FOnProgress write FOnProgress; + end; + TFPCustomImageClass = class of TFPCustomImage; + +{$ifdef CPU68K} + { 1.0 m68k cpu compiler does not allow + types larger than 32k.... + if we remove range checking all should be fine PM } + TFPIntegerArray = array [0..0] of integer; +{$R-} +{$else not CPU68K} + TFPIntegerArray = array [0..(maxint-1) div sizeof(integer)-1] of integer; +{$endif CPU68K} + PFPIntegerArray = ^TFPIntegerArray; + + TFPMemoryImage = class (TFPCustomImage) + private + protected + FData : PFPIntegerArray; + function GetInternalColor(x,y:integer):TFPColor;override; + procedure SetInternalColor (x,y:integer; const Value:TFPColor);override; + procedure SetUsePalette (Value:boolean);override; + procedure SetInternalPixel (x,y:integer; Value:integer); override; + function GetInternalPixel (x,y:integer) : integer; override; + public + constructor create (AWidth,AHeight:integer); override; + destructor destroy; override; + procedure SetSize (AWidth, AHeight : integer); override; + end; + + TFPCustomImageHandler = class + private + FOnProgress : TFPImgProgressEvent; + FStream : TStream; + FImage : TFPCustomImage; + protected + procedure Progress(Stage: TProgressStage; PercentDone: Byte; RedrawNow: Boolean; const R: TRect; + const Msg: AnsiString; var Continue: Boolean); Virtual; + property TheStream : TStream read FStream; + property TheImage : TFPCustomImage read FImage; + public + constructor Create; virtual; + Property OnProgress : TFPImgProgressEvent Read FOnProgress Write FOnProgress; + end; + + TFPCustomImageReader = class (TFPCustomImageHandler) + private + FDefImageClass:TFPCustomImageClass; + protected + procedure InternalRead (Str:TStream; Img:TFPCustomImage); virtual; abstract; + function InternalCheck (Str:TStream) : boolean; virtual; abstract; + public + constructor Create; override; + function ImageRead (Str:TStream; Img:TFPCustomImage) : TFPCustomImage; + // reads image + function CheckContents (Str:TStream) : boolean; + // Gives True if contents is readable + property DefaultImageClass : TFPCustomImageClass read FDefImageClass write FDefImageClass; + // Image Class to create when no img is given for reading + end; + TFPCustomImageReaderClass = class of TFPCustomImageReader; + + TFPCustomImageWriter = class (TFPCustomImageHandler) + protected + procedure InternalWrite (Str:TStream; Img:TFPCustomImage); virtual; abstract; + public + procedure ImageWrite (Str:TStream; Img:TFPCustomImage); + // writes given image to stream + end; + TFPCustomImageWriterClass = class of TFPCustomImageWriter; + + TIHData = class + private + FExtention, FTypeName, FDefaultExt : string; + FReader : TFPCustomImageReaderClass; + FWriter : TFPCustomImageWriterClass; + end; + + TImageHandlersManager = class + private + FData : TList; + function GetReader (const TypeName:string) : TFPCustomImageReaderClass; + function GetWriter (const TypeName:string) : TFPCustomImageWriterClass; + function GetExt (const TypeName:string) : string; + function GetDefExt (const TypeName:string) : string; + function GetTypeName (index:integer) : string; + function GetData (const ATypeName:string) : TIHData; overload; + function GetData (index : integer) : TIHData; overload; + function GetCount : integer; + public + constructor Create; + destructor Destroy; override; + procedure RegisterImageHandlers (const ATypeName,TheExtentions:string; + AReader:TFPCustomImageReaderClass; AWriter:TFPCustomImageWriterClass); + procedure RegisterImageReader (const ATypeName,TheExtentions:string; + AReader:TFPCustomImageReaderClass); + procedure RegisterImageWriter (const ATypeName,TheExtentions:string; + AWriter:TFPCustomImageWriterClass); + property Count : integer read GetCount; + property ImageReader [const TypeName:string] : TFPCustomImageReaderClass read GetReader; + property ImageWriter [const TypeName:string] : TFPCustomImageWriterClass read GetWriter; + property Extentions [const TypeName:string] : string read GetExt; + property DefaultExtention [const TypeName:string] : string read GetDefExt; + property TypeNames [index:integer] : string read GetTypeName; + end; + +{function ShiftAndFill (initial:word; CorrectBits:byte):word; +function FillOtherBits (initial:word;CorrectBits:byte):word; +} +function CalculateGray (const From : TFPColor) : word; +(* +function ConvertColor (const From : TDeviceColor) : TFPColor; +function ConvertColor (const From : TColorData; FromFmt:TColorFormat) : TFPColor; +function ConvertColorToData (const From : TFPColor; Fmt : TColorFormat) : TColorData; +function ConvertColorToData (const From : TDeviceColor; Fmt : TColorFormat) : TColorData; +function ConvertColor (const From : TFPColor; Fmt : TColorFormat) : TDeviceColor; +function ConvertColor (const From : TDeviceColor; Fmt : TColorFormat) : TDeviceColor; +*) + +function AlphaBlend(color1, color2: TFPColor): TFPColor; + +function FPColor (r,g,b,a:word) : TFPColor; overload; +function FPColor (r,g,b:word) : TFPColor; overload; +{$ifdef debug}function MakeHex (n:TColordata;nr:byte): string;{$endif} + +{$ifdef FPC} +operator = (const c,d:TFPColor) : boolean; +operator or (const c,d:TFPColor) : TFPColor; +operator and (const c,d:TFPColor) : TFPColor; +operator xor (const c,d:TFPColor) : TFPColor; +{$else} +function col_equ(const c,d:TFPColor) : boolean; +function col_or (const c,d:TFPColor) : TFPColor; +function col_and (const c,d:TFPColor) : TFPColor; +function col_xor (const c,d:TFPColor) : TFPColor; +{$endif} + +function CompareColors(const Color1, Color2: TFPColor): integer; + +var ImageHandlers : TImageHandlersManager; + +type + TErrorTextIndices = ( + StrInvalidIndex, + StrNoImageToWrite, + StrNoFile, + StrNoStream, + StrPalette, + StrImageX, + StrImageY, + StrImageExtra, + StrTypeAlreadyExist, + StrTypeReaderAlreadyExist, + StrTypeWriterAlreadyExist, + StrCantDetermineType, + StrNoCorrectReaderFound, + StrReadWithError, + StrWriteWithError, + StrNoPaletteAvailable + ); + +const + // MG: ToDo: move to implementation and add a function to map to resourcestrings + ErrorText : array[TErrorTextIndices] of string = + ('Invalid %s index %d', + 'No image to write', + 'File "%s" does not exist', + 'No stream to write to', + 'palette', + 'horizontal pixel', + 'vertical pixel', + 'extra', + 'Image type "%s" already exists', + 'Image type "%s" already has a reader class', + 'Image type "%s" already has a writer class', + 'Error while determining image type of stream: %s', + 'Can''t determine image type of stream', + 'Error while reading stream: %s', + 'Error while writing stream: %s', + 'No palette available' + ); + +{$i fpcolors.inc} + +type + TGrayConvMatrix = record + red, green, blue : single; + end; + +var + GrayConvMatrix : TGrayConvMatrix; + +const + GCM_NTSC : TGrayConvMatrix = (red:0.299; green:0.587; blue:0.114); + GCM_JPEG : TGrayConvMatrix = (red:0.299; green:0.587; blue:0.114); + GCM_Mathematical : TGrayConvMatrix = (red:0.334; green:0.333; blue:0.333); + GCM_Photoshop : TGrayConvMatrix = (red:0.213; green:0.715; blue:0.072); + +function CreateBlackAndWhitePalette : TFPPalette; +function CreateWebSafePalette : TFPPalette; +function CreateGrayScalePalette : TFPPalette; +function CreateVGAPalette : TFPPalette; + +Type + TFPCompactImgDesc = record + Gray: boolean; // true = red=green=blue, false: a RGB image + Depth: word; // 8 or 16 bit + HasAlpha: boolean; // has alpha channel + end; + + { TFPCompactImgBase } + + TFPCompactImgBase = class(TFPCustomImage) + private + FDesc: TFPCompactImgDesc; + public + property Desc: TFPCompactImgDesc read FDesc; + end; + TFPCompactImgBaseClass = class of TFPCompactImgBase; + + { TFPCompactImgGray16Bit } + + TFPCompactImgGray16Bit = class(TFPCompactImgBase) + protected + FData: PWord; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + TFPCompactImgGrayAlpha16BitValue = packed record + g,a: word; + end; + PFPCompactImgGrayAlpha16BitValue = ^TFPCompactImgGrayAlpha16BitValue; + FPCompactImgGrayAlpha16BitValueaty = + array[0..0] of TFPCompactImgGrayAlpha16BitValue; + pFPCompactImgGrayAlpha16BitValueaty = ^FPCompactImgGrayAlpha16BitValueaty; + + { TFPCompactImgGrayAlpha16Bit } + + TFPCompactImgGrayAlpha16Bit = class(TFPCompactImgBase) + protected + FData: PFPCompactImgGrayAlpha16BitValue; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + { TFPCompactImgGray8Bit } + + TFPCompactImgGray8Bit = class(TFPCompactImgBase) + protected + FData: PByte; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + TFPCompactImgGrayAlpha8BitValue = packed record + g,a: byte; + end; + PFPCompactImgGrayAlpha8BitValue = ^TFPCompactImgGrayAlpha8BitValue; + FPCompactImgGrayAlpha8BitValueaty = + array[0..0] of TFPCompactImgGrayAlpha8BitValue; + pFPCompactImgGrayAlpha8BitValueaty = ^FPCompactImgGrayAlpha8BitValueaty; + + { TFPCompactImgGrayAlpha8Bit } + + TFPCompactImgGrayAlpha8Bit = class(TFPCompactImgBase) + protected + FData: PFPCompactImgGrayAlpha8BitValue; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + TFPCompactImgRGBA8BitValue = packed record + r,g,b,a: byte; + end; + PFPCompactImgRGBA8BitValue = ^TFPCompactImgRGBA8BitValue; + FPCompactImgRGBA8BitValueaty = array of TFPCompactImgRGBA8BitValue; + pFPCompactImgRGBA8BitValueaty = ^FPCompactImgRGBA8BitValueaty; + + { TFPCompactImgRGBA8Bit } + + TFPCompactImgRGBA8Bit = class(TFPCompactImgBase) + protected + FData: PFPCompactImgRGBA8BitValue; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + TFPCompactImgRGB8BitValue = packed record + r,g,b: byte; + end; + PFPCompactImgRGB8BitValue = ^TFPCompactImgRGB8BitValue; + FPCompactImgRGB8BitValueaty = array[0..0] of TFPCompactImgRGB8BitValue; + pFPCompactImgRGB8BitValueaty = ^FPCompactImgRGB8BitValueaty; + + { TFPCompactImgRGB8Bit } + + TFPCompactImgRGB8Bit = class(TFPCompactImgBase) + protected + FData: PFPCompactImgRGB8BitValue; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + TFPCompactImgRGB16BitValue = packed record + r,g,b: word; + end; + PFPCompactImgRGB16BitValue = ^TFPCompactImgRGB16BitValue; + FPCompactImgRGB16BitValueaty = array[0..0] of TFPCompactImgRGB16BitValue; + pFPCompactImgRGB16BitValueaty = ^FPCompactImgRGB16BitValueaty; + + { TFPCompactImgRGB16Bit } + + TFPCompactImgRGB16Bit = class(TFPCompactImgBase) + protected + FData: PFPCompactImgRGB16BitValue; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + { TFPCompactImgRGBA16Bit } + + TFPCompactImgRGBA16Bit = class(TFPCompactImgBase) + protected + FData: PFPColor; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + +{ Create a descriptor to select a CompactImg class } +function GetFPCompactImgDesc(Gray: boolean; Depth: word; HasAlpha: boolean): TFPCompactImgDesc; + +{ Returns a CompactImg class that fits the descriptor } +function GetFPCompactImgClass(const Desc: TFPCompactImgDesc): TFPCompactImgBaseClass; + +{ Create a CompactImg with the descriptor } +function CreateFPCompactImg(const Desc: TFPCompactImgDesc; Width, Height: integer): TFPCustomImage; + +{ Create a CompactImg with the same features as Img. +If Img is a TFPCompactImgBaseClass it will create that. +Otherwise it returns a CompactImg that fits the Img using GetMinimumPTDesc. } +function CreateCompatibleFPCompactImg(Img: TFPCustomImage; Width, Height: integer +): TFPCustomImage; + +{ As CreateCompatibleFPCompactImg, but the image has always an alpha channel. } +function CreateCompatibleFPCompactImgWithAlpha(Img: TFPCustomImage; +Width, Height: integer): TFPCustomImage; + +{ Returns the smallest descriptor that allows to store the Img. +It returns HasAlpha=false if all pixel are opaque. +It returns Gray=true if all red=green=blue. +It returns Depth=8 if all lo byte equals the hi byte or all lo bytes are 0. +To ignore rounding errors you can pass a FuzzyDepth. For example a FuzzyDepth +of 3 ignores the lower 3 bits when comparing. } +function GetMinimumPTDesc(Img: TFPCustomImage; FuzzyDepth: word = 4): TFPCompactImgDesc; + +{ Create a smaller CompactImg with the same information as Img. +Pass FreeImg=true to call Img.Free } +function GetMinimumFPCompactImg(Img: TFPCustomImage; FreeImg: boolean; +FuzzyDepth: word = 4): TFPCustomImage; + + + +implementation + +procedure FPImgError (Fmt:TErrorTextIndices; data : array of const); overload; +begin + raise FPImageException.CreateFmt (ErrorText[Fmt],data); +end; + +procedure FPImgError (Fmt:TErrorTextIndices); overload; +begin + raise FPImageException.Create (ErrorText[Fmt]); +end; + +{$i fpimage.inc} +{$i fphandler.inc} +{$i fppalette.inc} +{$i fpcolcnv.inc} +{$i fpcompactimg.inc} + +function FPColor (r,g,b:word) : TFPColor; +begin + with result do + begin + red := r; + green := g; + blue := b; + alpha := alphaOpaque; + end; +end; + +function FPColor (r,g,b,a:word) : TFPColor; +begin + with result do + begin + red := r; + green := g; + blue := b; + alpha := a; + end; +end; + +{$ifdef FPC} +operator = (const c,d:TFPColor) : boolean; +begin + result := (c.Red = d.Red) and + (c.Green = d.Green) and + (c.Blue = d.Blue) and + (c.Alpha = d.Alpha); +end; +{$else} +function col_equ(const c,d:TFPColor) : boolean; +begin + result := (c.Red = d.Red) and + (c.Green = d.Green) and + (c.Blue = d.Blue) and + (c.Alpha = d.Alpha); +end; +{$endif} + +function GetFullColorData (color:TFPColor) : TColorData; +begin + result := PColorData(@color)^; +end; + +function SetFullColorData (color:TColorData) : TFPColor; +begin + result := PFPColor (@color)^; +end; + +{$ifdef FPC} +operator or (const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) OR GetFullColorData(d)); +end; + +operator and (const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) AND GetFullColorData(d)); +end; + +operator xor (const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) XOR GetFullColorData(d)); +end; +{$else} +function col_or(const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) OR GetFullColorData(d)); +end; + +function col_and(const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) AND GetFullColorData(d)); +end; +function col_xor(const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) XOR GetFullColorData(d)); +end; +{$endif} + +{$ifdef debug} +function MakeHex (n:TColordata;nr:byte): string; +const hexnums : array[0..15] of char = + ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); +var r : integer; +begin + result := ''; + for r := 0 to nr-1 do + begin + result := hexnums[n and $F] + result; + n := n shr 4; + if ((r+1) mod 4) = 0 then + result := ' ' + result; + end; +end; +{$endif} + +initialization + ImageHandlers := TImageHandlersManager.Create; + GrayConvMatrix := GCM_JPEG; + // Following lines are here because the compiler 1.0 can't work with int64 constants +(* ColorBits [cfRGB48,1] := ColorBits [cfRGB48,1] shl 16; + ColorBits [cfRGBA64,1] := ColorBits [cfRGBA64,1] shl 32; + ColorBits [cfRGBA64,2] := ColorBits [cfRGBA64,2] shl 16; + ColorBits [cfABGR64,0] := ColorBits [cfABGR64,0] shl 32; + ColorBits [cfABGR64,3] := ColorBits [cfABGR64,3] shl 16; + ColorBits [cfBGR48,3] := ColorBits [cfBGR48,3] shl 16; + PrepareBitMasks;*) + +finalization + ImageHandlers.Free; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fppalette.inc b/mseide-msegui/lib/common/fpccompatibility/fppalette.inc new file mode 100644 index 0000000..0ff3608 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fppalette.inc @@ -0,0 +1,265 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + TFPPalette implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +{ TFPPalette } + +constructor TFPPalette.create (ACount : integer); +begin + inherited create; + if aCount > 0 then + getmem (FData, sizeof(TFPColor)*ACount) + else + FData := nil; + FCapacity := ACount; + SetCount (0); +end; + +destructor TFPPalette.destroy; +begin + if FCapacity > 0 then + freemem (FData); + inherited; +end; + +procedure TFPPalette.Build (Img : TFPCustomImage); +var x,y : integer; +begin + if (Img.Palette <> self) then + begin + Count := 0; + for x := 0 to img.width-1 do + for y := 0 to img.height-1 do + IndexOf(img[x,y]); + end; +end; + +procedure TFPPalette.Copy(APalette: TFPPalette); +var + x: integer; +begin + if (APalette <> Self) then + begin + Self.Clear; + for x := 0 to APalette.Count - 1 do + Add(APalette.Color[x]) + end; +end; + +procedure TFPPalette.Merge (pal : TFPPalette); +var r : integer; +begin + for r := 0 to pal.count-1 do + IndexOf (pal[r]); +end; + +procedure TFPPalette.CheckIndex (index:integer); +begin + if (index >= FCount) or (index < 0) then + FPImgError (StrInvalidIndex,[ErrorText[StrPalette],index]); +end; + +function TFPPalette.Add (const Value:TFPColor) : integer; +begin + result := FCount; + inc (FCount); + if FCount > FCapacity then + EnlargeData; + FData^[result] := Value; +end; + +procedure TFPPalette.SetColor (index:integer; const Value:TFPColor); +begin + if index = FCount then + Add (Value) + else + begin + CheckIndex (index); + FData^[index] := Value; + end; +end; + +function TFPPalette.GetColor (index:integer) : TFPColor; +begin + CheckIndex (index); + result := FData^[index]; +end; + +function TFPPalette.GetCount : integer; +begin + result := FCount; +end; + +procedure TFPPalette.EnlargeData; +var old : integer; + NewData : PFPColorArray; +begin + old := FCapacity; + if FCapacity <= 16 then + FCapacity := 32 + else if FCapacity <= 128 then + FCapacity := 256 + else + // MG: changed to exponential growth + inc (FCapacity, FCapacity); + GetMem (NewData, sizeof(TFPColor)*FCapacity); + if old > 0 then + begin + move (FData^[0], NewData^[0], sizeof(TFPColor)*FCount); + FreeMem (FData); + end; + FData := NewData; +end; + +procedure TFPPalette.SetCount (Value:integer); +var + O : integer; +begin + if Value <> FCount then + begin + if Value > FCapacity then + begin + FCapacity := Value+8; + Reallocmem(FData,sizeof(TFPColor)*FCapacity); + end; + for o := FCount to Value-1 do + FData^[o] := colBlack; + FCount := Value; + end; +end; + +procedure TFPPalette.SetCapacity (ind : Integer); +var o : Integer; +begin + if indfcapacity then + begin + fcapacity:=ind; + Reallocmem(FData,sizeof(TFPColor)*FCapacity); + end; + if ind>count then + begin + for o := FCount to ind-1 do + FData^[o] := colBlack; + end; +end; + +function TFPPalette.IndexOf (const AColor:TFPColor) : integer; +begin + result := FCount; + repeat + dec (result); + {$ifdef FPC} + until (result < 0) or (FData^[result]=AColor); + {$else} + until (result < 0) or col_equ(FData^[result],AColor); + {$endif} + if result < 0 then + result := Add (AColor); +end; + +procedure TFPPalette.Clear; +begin + SetCount (0); +end; + + +{ Functions to create standard palettes, by Giulio Bernardi 2005 } + +{ A simple 1 bit black and white palette } +function CreateBlackAndWhitePalette : TFPPalette; +var fppal : TFPPalette; + Col : TFPColor; +begin + fppal:=TFPPalette.Create(2); + Col.Alpha:=AlphaOpaque; + Col.Red:=$FFFF; Col.Green:=$FFFF; Col.Blue:=$FFFF; + fppal.Color[0]:=Col; + Col.Red:=$0000; Col.Green:=$0000; Col.Blue:=$0000; + fppal.Color[1]:=Col; + Result:=fppal; +end; + +{ The "standard" netscape 216-color palette (aka: web safe palette) } +function CreateWebSafePalette : TFPPalette; +var Col : TFPColor; + i : integer; + fppal : TFPPalette; +begin + fppal:=TFPPalette.Create(216); + Col.Alpha:=AlphaOpaque; + i:=0; + Col.Red:=$FFFF; + while true do + begin + Col.Green:=$FFFF; + while true do + begin + Col.Blue:=$FFFF; + while true do + begin + fppal.Color[i]:=Col; + if Col.Blue=0 then break; + dec(Col.Blue,$3333); + end; + if Col.Green=0 then break; + dec(Col.Green,$3333); + end; + if Col.Red=0 then break; + dec(Col.Red,$3333); + end; + Result:=fppal; +end; + +{ A grayscale palette. Not very useful. } +function CreateGrayScalePalette : TFPPalette; +var Col : TFPColor; + i : integer; + fppal : TFPPalette; +begin + fppal:=TFPPalette.Create(256); + Col.Alpha:=AlphaOpaque; + for i:=0 to $FF do + begin + Col.Red:=i; + Col.Red:=(Col.Red shl 8) + Col.Red; + Col.Green:=Col.Red; + Col.Blue:=Col.Red; + fppal.Color[i]:=Col; + end; + Result:=fppal; +end; + +{ Standard VGA 16 color palette. } +function CreateVGAPalette : TFPPalette; +var fppal : TFPPalette; +begin + fppal:=TFPPalette.Create(16); + fppal.Color[0]:=colBlack; + fppal.Color[1]:=colNavy; + fppal.Color[2]:=colBlue; + fppal.Color[3]:=colMaroon; + fppal.Color[4]:=colPurple; + fppal.Color[5]:=colDkGreen; + fppal.Color[6]:=colRed; + fppal.Color[7]:=colTeal; + fppal.Color[8]:=colFuchsia; + fppal.Color[9]:=colOlive; + fppal.Color[10]:=colGray; + fppal.Color[11]:=colLime; + fppal.Color[12]:=colAqua; + fppal.Color[13]:=colSilver; + fppal.Color[14]:=colYellow; + fppal.Color[15]:=colWhite; + Result:=fppal; +end; diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadbmp.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadbmp.pas new file mode 100644 index 0000000..1c05b01 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadbmp.pas @@ -0,0 +1,520 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + BMP reader implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. +} +{*****************************************************************************} +{ 08/2005 by Giulio Bernardi: + - Added support for 16 and 15 bpp bitmaps. + - If we have bpp <= 8 make an indexed image instead of converting it to RGB + - Support for RLE4 and RLE8 decoding + - Support for top-down bitmaps +} +//modified 2013 by Martin Schreiber + +{$mode objfpc} +{$h+} + +unit fpreadbmp; + +interface + +uses fpimage, classes, mclasses, sysutils, bmpcomn; + +type + TFPReaderBMP = class (TFPCustomImageReader) + Private + DeltaX, DeltaY : integer; // Used for the never-used delta option in RLE + TopDown : boolean; // If set, bitmap is stored top down instead of bottom up + continue : boolean; // needed for onprogress event + percent : byte; + percentinterval : longword; + percentacc : longword; + Rect : TRect; + Procedure FreeBufs; // Free (and nil) buffers. + protected + ReadSize : Integer; // Size (in bytes) of 1 scanline. + BFI : TBitMapInfoHeader; // The header as read from the stream. + FPalette : PFPcolor; // Buffer with Palette entries. (useless now) + LineBuf : PByte; // Buffer for 1 scanline. Can be Byte, Word, TColorRGB or TColorRGBA + RedMask, GreenMask, BlueMask : longword; //Used if Compression=bi_bitfields + RedShift, GreenShift, BlueShift : shortint; + // SetupRead will allocate the needed buffers, and read the colormap if needed. + procedure SetupRead(nPalette, nRowBits: Integer; Stream : TStream); virtual; + function CountBits(Value : byte) : shortint; + function ShiftCount(Mask : longword) : shortint; + function ExpandColor(value : longword) : TFPColor; + procedure ExpandRLE8ScanLine(Row : Integer; Stream : TStream); + procedure ExpandRLE4ScanLine(Row : Integer; Stream : TStream); + procedure ReadScanLine(Row : Integer; Stream : TStream); virtual; + procedure WriteScanLine(Row : Integer; Img : TFPCustomImage); virtual; + // required by TFPCustomImageReader + procedure InternalRead (Stream:TStream; Img:TFPCustomImage); override; + function InternalCheck (Stream:TStream) : boolean; override; + public + constructor Create; override; + destructor Destroy; override; + end; + +implementation + + +function RGBAToFPColor(Const RGBA: TColorRGBA) : TFPcolor; + +begin + with Result, RGBA do + begin + Red :=(R shl 8) or R; + Green :=(G shl 8) or G; + Blue :=(B shl 8) or B; + Alpha :=255-A; + Alpha :=(Alpha shl 8) or Alpha + end; +end; + +Function RGBToFPColor(Const RGB : TColorRGB) : TFPColor; + +begin + with Result,RGB do + begin {Use only the high byte to convert the color} + Red := (R shl 8) + R; + Green := (G shl 8) + G; + Blue := (B shl 8) + B; + Alpha := AlphaOpaque; + end; +end; + +Constructor TFPReaderBMP.create; + +begin + inherited create; +end; + +Destructor TFPReaderBMP.Destroy; + +begin + FreeBufs; + inherited destroy; +end; + +Procedure TFPReaderBMP.FreeBufs; + +begin + If (LineBuf<>Nil) then + begin + FreeMem(LineBuf); + LineBuf:=Nil; + end; + If (FPalette<>Nil) then + begin + FreeMem(FPalette); + FPalette:=Nil; + end; +end; + +{ Counts how many bits are set } +function TFPReaderBMP.CountBits(Value : byte) : shortint; +var i,bits : shortint; +begin + bits:=0; + for i:=0 to 7 do + begin + if (value mod 2)<>0 then inc(bits); + value:=value shr 1; + end; + Result:=bits; +end; + +{ If compression is bi_bitfields, there could be arbitrary masks for colors. + Although this is not compatible with windows9x it's better to know how to read these bitmaps + We must determine how to switch the value once masked + Example: 0000 0111 1110 0000, if we shr 5 we have 00XX XXXX for the color, but these bits must be the + highest in the color, so we must shr (5-(8-6))=3, and we have XXXX XX00. + A negative value means "shift left" } +function TFPReaderBMP.ShiftCount(Mask : longword) : shortint; +var tmp : shortint; +begin + tmp:=0; + if Mask=0 then + begin + Result:=0; + exit; + end; + + while (Mask mod 2)=0 do { rightmost bit is 0 } + begin + inc(tmp); + Mask:= Mask shr 1; + end; + tmp:=tmp-(8-CountBits(Mask and $FF)); + Result:=tmp; +end; + +function TFPReaderBMP.ExpandColor(value : longword) : TFPColor; +var tmpr, tmpg, tmpb : longword; + col : TColorRGB; +begin + {$IFDEF ENDIAN_BIG} + value:=swap(value); + {$ENDIF} + tmpr:=value and RedMask; + tmpg:=value and GreenMask; + tmpb:=value and BlueMask; + if RedShift < 0 then col.R:=byte(tmpr shl (-RedShift)) + else col.R:=byte(tmpr shr RedShift); + if GreenShift < 0 then col.G:=byte(tmpg shl (-GreenShift)) + else col.G:=byte(tmpg shr GreenShift); + if BlueShift < 0 then col.B:=byte(tmpb shl (-BlueShift)) + else col.B:=byte(tmpb shr BlueShift); + Result:=RGBToFPColor(col); +end; + +procedure TFPReaderBMP.SetupRead(nPalette, nRowBits: Integer; Stream : TStream); + +var + ColInfo: ARRAY OF TColorRGBA; + i: Integer; + +begin + if ((BFI.Compression=BI_RGB) and (BFI.BitCount=16)) then { 5 bits per channel, fixed mask } + begin + RedMask:=$7C00; RedShift:=7; + GreenMask:=$03E0; GreenShift:=2; + BlueMask:=$001F; BlueShift:=-3; + end + else if ((BFI.Compression=BI_BITFIELDS) and (BFI.BitCount in [16,32])) then { arbitrary mask } + begin + Stream.Read(RedMask,4); + Stream.Read(GreenMask,4); + Stream.Read(BlueMask,4); + {$IFDEF ENDIAN_BIG} + RedMask:=swap(RedMask); + GreenMask:=swap(GreenMask); + BlueMask:=swap(BlueMask); + {$ENDIF} + RedShift:=ShiftCount(RedMask); + GreenShift:=ShiftCount(GreenMask); + BlueShift:=ShiftCount(BlueMask); + end + else if nPalette>0 then + begin + GetMem(FPalette, nPalette*SizeOf(TFPColor)); + SetLength(ColInfo, nPalette); + if BFI.ClrUsed>0 then + Stream.Read(ColInfo[0],BFI.ClrUsed*SizeOf(TColorRGBA)) + else // Seems to me that this is dangerous. + Stream.Read(ColInfo[0],nPalette*SizeOf(TColorRGBA)); + for i := 0 to High(ColInfo) do + FPalette[i] := RGBAToFPColor(ColInfo[i]); + end + else if BFI.ClrUsed>0 then { Skip palette } + Stream.Position := Stream.Position + BFI.ClrUsed*SizeOf(TColorRGBA); + ReadSize:=((nRowBits + 31) div 32) shl 2; + GetMem(LineBuf,ReadSize); +end; + +procedure TFPReaderBMP.InternalRead(Stream:TStream; Img:TFPCustomImage); + +Var + Row, i, pallen : Integer; + BadCompression : boolean; +begin + Rect.Left:=0; Rect.Top:=0; Rect.Right:=0; Rect.Bottom:=0; + continue:=true; + Progress(psStarting,0,false,Rect,'',continue); + if not continue then exit; + Stream.Read(BFI,SizeOf(BFI)); + {$IFDEF ENDIAN_BIG} + SwapBMPInfoHeader(BFI); + {$ENDIF} + { This will move past any junk after the BFI header } + Stream.Position:=Stream.Position-SizeOf(BFI)+BFI.Size; + with BFI do + begin + BadCompression:=false; + if ((Compression=BI_RLE4) and (BitCount<>4)) then BadCompression:=true; + if ((Compression=BI_RLE8) and (BitCount<>8)) then BadCompression:=true; + if ((Compression=BI_BITFIELDS) and (not (BitCount in [16,32]))) then BadCompression:=true; + if not (Compression in [BI_RGB..BI_BITFIELDS]) then BadCompression:=true; + if BadCompression then + raise FPImageException.Create('Bad BMP compression mode'); + TopDown:=(Height<0); + Height:=abs(Height); + if (TopDown and (not (Compression in [BI_RGB,BI_BITFIELDS]))) then + raise FPImageException.Create('Top-down bitmaps cannot be compressed'); + Img.SetSize(0,0); + if BitCount<=8 then + begin + Img.UsePalette:=true; + Img.Palette.Clear; + end + else Img.UsePalette:=false; + Case BFI.BitCount of + 1 : { Monochrome } + SetupRead(2,Width,Stream); + 4 : + SetupRead(16,Width*4,Stream); + 8 : + SetupRead(256,Width*8,Stream); + 16 : + SetupRead(0,Width*8*2,Stream); + 24: + SetupRead(0,Width*8*3,Stream); + 32: + SetupRead(0,Width*8*4,Stream); + end; + end; + Try + { Note: it would be better to Fill the image palette in setupread instead of creating FPalette. + FPalette is indeed useless but we cannot remove it since it's not private :\ } + pallen:=0; + if BFI.BitCount<=8 then + if BFI.ClrUsed>0 then pallen:=BFI.ClrUsed + else pallen:=(1 shl BFI.BitCount); + if pallen>0 then + begin + Img.Palette.Count:=pallen; + for i:=0 to pallen-1 do + Img.Palette.Color[i]:=FPalette[i]; + end; + Img.SetSize(BFI.Width,BFI.Height); + + percent:=0; + percentinterval:=(Img.Height*4) div 100; + if percentinterval=0 then percentinterval:=$FFFFFFFF; + percentacc:=0; + + DeltaX:=-1; DeltaY:=-1; + if TopDown then + for Row:=0 to Img.Height-1 do { A rare case of top-down bitmap! } + begin + ReadScanLine(Row,Stream); // Scanline in LineBuf with Size ReadSize. + WriteScanLine(Row,Img); + if not continue then exit; + end + else + for Row:=Img.Height-1 downto 0 do + begin + ReadScanLine(Row,Stream); // Scanline in LineBuf with Size ReadSize. + WriteScanLine(Row,Img); + if not continue then exit; + end; + Progress(psEnding,100,false,Rect,'',continue); + finally + FreeBufs; + end; +end; + +procedure TFPReaderBMP.ExpandRLE8ScanLine(Row : Integer; Stream : TStream); +var i,j : integer; + b0, b1 : byte; +begin + i:=0; + while true do + begin + { let's see if we must skip pixels because of delta... } + if DeltaY<>-1 then + begin + if Row=DeltaY then j:=DeltaX { If we are on the same line, skip till DeltaX } + else j:=ReadSize; { else skip up to the end of this line } + while (i0 then { number of repetitions } + begin + if b0+i>ReadSize then + raise FPImageException.Create('Bad BMP RLE chunk at row '+inttostr(row)+', col '+inttostr(i)+', file offset $'+inttohex(Stream.Position,16) ); + j:=i+b0; + while (iReadSize then + raise FPImageException.Create('Bad BMP RLE chunk at row '+inttostr(row)+', col '+inttostr(i)+', file offset $'+inttohex(Stream.Position,16) ); + Stream.Read(LineBuf[i],b1); + inc(i,b1); + { aligned on 2 bytes boundary: every group starts on a 2 bytes boundary, but absolute group + could end on odd address if there is a odd number of elements, so we pad it } + if (b1 mod 2)<>0 then Stream.Seek(1,soFromCurrent); + end; + end; + end; +end; + +procedure TFPReaderBMP.ExpandRLE4ScanLine(Row : Integer; Stream : TStream); +var i,j,tmpsize : integer; + b0, b1 : byte; + nibline : pbyte; { temporary array of nibbles } + even : boolean; +begin + tmpsize:=ReadSize*2; { ReadSize is in bytes, while nibline is made of nibbles, so it's 2*readsize long } + getmem(nibline,tmpsize); + if nibline=nil then + raise FPImageException.Create('Out of memory'); + try + i:=0; + while true do + begin + { let's see if we must skip pixels because of delta... } + if DeltaY<>-1 then + begin + if Row=DeltaY then j:=DeltaX { If we are on the same line, skip till DeltaX } + else j:=tmpsize; { else skip up to the end of this line } + while (i0 then { number of repetitions } + begin + if b0+i>tmpsize then + raise FPImageException.Create('Bad BMP RLE chunk at row '+inttostr(row)+', col '+inttostr(i)+', file offset $'+inttohex(Stream.Position,16) ); + even:=true; + j:=i+b0; + while (itmpsize then + raise FPImageException.Create('Bad BMP RLE chunk at row '+inttostr(row)+', col '+inttostr(i)+', file offset $'+inttohex(Stream.Position,16) ); + j:=i+b1; + even:=true; + while (i0 then Stream.Seek(1,soFromCurrent); + end; + end; + end; + { pack the nibline into the linebuf } + for i:=0 to ReadSize-1 do + LineBuf[i]:=(NibLine[i*2] shl 4) or NibLine[i*2+1]; + finally + FreeMem(nibline) + end; +end; + +procedure TFPReaderBMP.ReadScanLine(Row : Integer; Stream : TStream); +begin + if BFI.Compression=BI_RLE8 then ExpandRLE8ScanLine(Row,Stream) + else if BFI.Compression=BI_RLE4 then ExpandRLE4ScanLine(Row,Stream) + else Stream.Read(LineBuf[0],ReadSize); +end; + +procedure TFPReaderBMP.WriteScanLine(Row : Integer; Img : TFPCustomImage); + +Var + Column : Integer; + +begin + Case BFI.BitCount of + 1 : + for Column:=0 to Img.Width-1 do + if ((LineBuf[Column div 8] shr (7-(Column and 7)) ) and 1) <> 0 then + img.Pixels[Column,Row]:=1 + else + img.Pixels[Column,Row]:=0; + 4 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=(LineBuf[Column div 2] shr (((Column+1) and 1)*4)) and $0f; + 8 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=LineBuf[Column]; + 16 : + for Column:=0 to img.Width-1 do + img.colors[Column,Row]:=ExpandColor(PWord(LineBuf)[Column]); + 24 : + for Column:=0 to img.Width-1 do + img.colors[Column,Row]:=RGBToFPColor(PColorRGB(LineBuf)[Column]); + 32 : + for Column:=0 to img.Width-1 do + if BFI.Compression=BI_BITFIELDS then + img.colors[Column,Row]:=ExpandColor(PLongWord(LineBuf)[Column]) + else + img.colors[Column,Row]:=RGBAToFPColor(PColorRGBA(LineBuf)[Column]); + end; + + inc(percentacc,4); + if percentacc>=percentinterval then + begin + percent:=percent+(percentacc div percentinterval); + percentacc:=percentacc mod percentinterval; + Progress(psRunning,percent,false,Rect,'',continue); + end; +end; + +function TFPReaderBMP.InternalCheck (Stream:TStream) : boolean; + +var + BFH:TBitMapFileHeader; +begin + stream.Read(BFH,SizeOf(BFH)); + {$IFDEF ENDIAN_BIG} + SwapBMPFileHeader(BFH); + {$ENDIF} + With BFH do + Result:=(bfType=BMmagic); // Just check magic number +end; + +initialization + ImageHandlers.RegisterImageReader ('BMP Format', 'bmp', TFPReaderBMP); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadgif.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadgif.pas new file mode 100644 index 0000000..0b86789 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadgif.pas @@ -0,0 +1,544 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2008 by the Free Pascal development team + + GIF reader for fpImage. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + ********************************************************************** + + ToDo: read further images +} +unit FPReadGif; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FPimage; + +type + TGifRGB = packed record + Red, Green, Blue : Byte; + end; + + TGIFHeader = packed record + Signature:array[0..2] of Char; //* Header Signature (always "GIF") */ + Version:array[0..2] of Char; //* GIF format version("87a" or "89a") */ + // Logical Screen Descriptor + ScreenWidth:word; //* Width of Display Screen in Pixels */ + ScreenHeight:word; //* Height of Display Screen in Pixels */ + Packedbit, //* Screen and Color Map Information */ + BackgroundColor, //* Background Color Index */ + AspectRatio:byte; //* Pixel Aspect Ratio */ + end; + + TGifImageDescriptor = packed record + Left, //* X position of image on the display */ + Top, //* Y position of image on the display */ + Width, //* Width of the image in pixels */ + Height:word; //* Height of the image in pixels */ + Packedbit:byte; //* Image and Color Table Data Information */ + end; + + TGifGraphicsControlExtension = packed record + BlockSize, //* Size of remaining fields (always 04h) */ + Packedbit:byte; //* Method of graphics disposal to use */ + DelayTime:word; //* Hundredths of seconds to wait */ + ColorIndex, //* Transparent Color Index */ + Terminator:byte; //* Block Terminator (always 0) */ + end; + + TFPReaderGif = class; + + TGifCreateCompatibleImgEvent = procedure(Sender: TFPReaderGif; + var NewImage: TFPCustomImage) of object; + + { TFPReaderGif } + + TFPReaderGif = class(TFPCustomImageReader) + protected + FHeader: TGIFHeader; + FDescriptor: TGifImageDescriptor; + FGraphicsCtrlExt: TGifGraphicsControlExtension; + FTransparent: Boolean; + FGraphCtrlExt: Boolean; + FScanLine: PByte; + FLineSize: Integer; + FPalette: TFPPalette; + FWidth: integer; + FHeight: Integer; + FInterlace: boolean; + FBitsPerPixel: byte; + FBackground: byte; + FResolution: byte; + FOnCreateImage: TGifCreateCompatibleImgEvent; + procedure ReadPalette(Stream: TStream; Size: integer); + function AnalyzeHeader: Boolean; + procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override; + function ReadScanLine(Stream: TStream): boolean; virtual; + function WriteScanLine(Img: TFPCustomImage): Boolean; virtual; + function InternalCheck (Stream: TStream) : boolean; override; + function SkipBlock(Stream: TStream): byte; + public + constructor Create; override; + destructor Destroy; override; + property Header: TGIFHeader read FHeader; + property Descriptor: TGifImageDescriptor read FDescriptor; + property GraphCtrlExt: Boolean read FGraphCtrlExt; + property GraphicsCtrlExt: TGifGraphicsControlExtension read FGraphicsCtrlExt; + property Transparent: Boolean read FTransparent; + property Palette: TFPPalette read FPalette; + property Width: integer read FWidth; + property Height: Integer read FHeight; + property Interlace: boolean read FInterlace; + property BitsPerPixel: byte read FBitsPerPixel; + property Background: byte read FBackground; + property Resolution: byte read FResolution; + property OnCreateImage: TGifCreateCompatibleImgEvent read FOnCreateImage write FOnCreateImage; + end; + +implementation + +{ TFPReaderGif } + +procedure TFPReaderGif.ReadPalette(Stream: TStream; Size: integer); +Var + RGBEntry : TGifRGB; + I : Integer; + c : TFPColor; +begin + FPalette.count := 0; + For I:=0 To Size-1 Do + Begin + Stream.Read(RGBEntry, SizeOf(RGBEntry)); + With c do + begin + Red:=RGBEntry.Red or (RGBEntry.Red shl 8); + Green:=RGBEntry.Green or (RGBEntry.Green shl 8); + Blue:=RGBEntry.Blue or (RGBEntry.Blue shl 8); + Alpha:=alphaOpaque; + end; + FPalette.Add(C); + End; +end; + +function TFPReaderGif.AnalyzeHeader: Boolean; +var + C : TFPColor; +begin + Result:=false; + With FHeader do + begin + if (Signature = 'GIF') and + ((Version = '87a') or + (Version = '89a')) then + else + Raise Exception.Create('Unknown/Unsupported GIF image type'); + + FResolution := Packedbit and $70 shr 5 + 1; + FBitsPerPixel:=Packedbit and 7 + 1; + FBackground := BackgroundColor; + + With FDescriptor do + begin + fWidth:=Width; + fHeight:=Height; + FInterlace := (Packedbit and $40 = $40); + end; + FTransparent:= FBackground <> 0; + if FGraphCtrlExt then + begin + FTransparent:=(FGraphicsCtrlExt.Packedbit and $01)<>0; + If FTransparent then + FBackground:=FGraphicsCtrlExt.ColorIndex; + end; + FLineSize:=FWidth*(FHeight+1); + GetMem(FScanLine,FLineSize); + If FTransparent then + begin + C:=FPalette.Color[FBackground]; + C.alpha:=alphaTransparent; + FPalette.Color[FBackground]:=C; + end; + end; + Result:=true; +end; + +procedure TFPReaderGif.InternalRead(Stream: TStream; Img: TFPCustomImage); +var + Introducer:byte; + ColorTableSize :Integer; + ContProgress: Boolean; +begin + FPalette:=nil; + FScanLine:=nil; + try + ContProgress:=true; + Progress(psStarting, 0, False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + + FPalette := TFPPalette.Create(0); + + Stream.Position:=0; + // header + Stream.Read(FHeader,SizeOf(FHeader)); + Progress(psRunning, trunc(100.0 * (Stream.position / Stream.size)), False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + + // Endian Fix Mantis 8541. Gif is always little endian + {$IFDEF ENDIAN_BIG} + with FHeader do + begin + ScreenWidth := LEtoN(ScreenWidth); + ScreenHeight := LEtoN(ScreenHeight); + end; + {$ENDIF} + // global palette + if (FHeader.Packedbit and $80) <> 0 then + begin + ColorTableSize := FHeader.Packedbit and 7 + 1; + ReadPalette(stream, 1 shl ColorTableSize); + end; + + // skip extensions + Repeat + Introducer:=SkipBlock(Stream); + until (Introducer = $2C) or (Introducer = $3B); + + // descriptor + Stream.Read(FDescriptor, SizeOf(FDescriptor)); + {$IFDEF ENDIAN_BIG} + with FDescriptor do + begin + Left := LEtoN(Left); + Top := LEtoN(Top); + Width := LEtoN(Width); + Height := LEtoN(Height); + end; + {$ENDIF} + // local palette + if (FDescriptor.Packedbit and $80) <> 0 then + begin + ColorTableSize := FDescriptor.Packedbit and 7 + 1; + ReadPalette(stream, 1 shl ColorTableSize); + end; + + // parse header + if not AnalyzeHeader then exit; + + // create image + if Assigned(OnCreateImage) then + OnCreateImage(Self,Img); + Img.SetSize(FWidth,FHeight); + + // read pixels + if not ReadScanLine(Stream) then exit; + if not WriteScanLine(Img) then exit; + + // ToDo: read further images + finally + FreeAndNil(FPalette); + ReAllocMem(FScanLine,0); + end; + Progress(FPimage.psEnding, 100, false, Rect(0,0,FWidth,FHeight), '', ContProgress); +end; + +function TFPReaderGif.ReadScanLine(Stream: TStream): Boolean; +var + OldPos, + UnpackedSize, + PackedSize:longint; + I: Integer; + Data, + Bits, + Code: Cardinal; + SourcePtr: PByte; + InCode: Cardinal; + + CodeSize: Cardinal; + CodeMask: Cardinal; + FreeCode: Cardinal; + OldCode: Cardinal; + Prefix: array[0..4095] of Cardinal; + Suffix, + Stack: array [0..4095] of Byte; + StackPointer: PByte; + DataComp, + Target: PByte; + B, + FInitialCodeSize, + FirstChar: Byte; + ClearCode, + EOICode: Word; + ContProgress: Boolean; + +begin + DataComp:=nil; + ContProgress:=true; + try + // read dictionary size + Stream.read(FInitialCodeSize, 1); + + // search end of compressor table + OldPos:=Stream.Position; + PackedSize := 0; + Repeat + Stream.read(B, 1); + if B > 0 then + begin + inc(PackedSize, B); + Stream.Seek(B, soFromCurrent); + CodeMask := (1 shl CodeSize) - 1; + end; + until B = 0; + + Progress(psRunning, trunc(100.0 * (Stream.position / Stream.size)), + False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit(false); + + Getmem(DataComp, PackedSize); + // read compressor table + SourcePtr:=DataComp; + Stream.Position:=OldPos; + Repeat + Stream.read(B, 1); + if B > 0 then + begin + Stream.ReadBuffer(SourcePtr^, B); + Inc(SourcePtr,B); + end; + until B = 0; + + Progress(psRunning, trunc(100.0 * (Stream.position / Stream.size)), + False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit(false); + + SourcePtr:=DataComp; + Target := FScanLine; + CodeSize := FInitialCodeSize + 1; + ClearCode := 1 shl FInitialCodeSize; + EOICode := ClearCode + 1; + FreeCode := ClearCode + 2; + OldCode := 4096; + CodeMask := (1 shl CodeSize) - 1; + UnpackedSize:=FWidth * FHeight; + for I := 0 to ClearCode - 1 do + begin + Prefix[I] := 4096; + Suffix[I] := I; + end; + StackPointer := @Stack; + FirstChar := 0; + Data := 0; + Bits := 0; + // LZW decompression gif + while (UnpackedSize > 0) and (PackedSize > 0) do + begin + Inc(Data, SourcePtr^ shl Bits); + Inc(Bits, 8); + while Bits >= CodeSize do + begin + Code := Data and CodeMask; + Data := Data shr CodeSize; + Dec(Bits, CodeSize); + if Code = EOICode then Break; + if Code = ClearCode then + begin + CodeSize := FInitialCodeSize + 1; + CodeMask := (1 shl CodeSize) - 1; + FreeCode := ClearCode + 2; + OldCode := 4096; + Continue; + end; + if Code > FreeCode then Break; + if OldCode = 4096 then + begin + FirstChar := Suffix[Code]; + Target^ := FirstChar; + Inc(Target); + Dec(UnpackedSize); + OldCode := Code; + Continue; + end; + InCode := Code; + if Code = FreeCode then + begin + StackPointer^ := FirstChar; + Inc(StackPointer); + Code := OldCode; + end; + while Code > ClearCode do + begin + StackPointer^ := Suffix[Code]; + Inc(StackPointer); + Code := Prefix[Code]; + end; + FirstChar := Suffix[Code]; + StackPointer^ := FirstChar; + Inc(StackPointer); + Prefix[FreeCode] := OldCode; + Suffix[FreeCode] := FirstChar; + if (FreeCode = CodeMask) and + (CodeSize < 12) then + begin + Inc(CodeSize); + CodeMask := (1 shl CodeSize) - 1; + end; + if FreeCode < 4095 then Inc(FreeCode); + OldCode := InCode; + repeat + Dec(StackPointer); + Target^ := StackPointer^; + Inc(Target); + Dec(UnpackedSize); + until StackPointer = @Stack; + end; + Inc(SourcePtr); + Dec(PackedSize); + end; + Progress(psRunning, trunc(100.0 * (Stream.position / Stream.size)), + False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit(false); + finally + if DataComp<>nil then + FreeMem(DataComp); + end; + Result:=true; +end; + +function TFPReaderGif.WriteScanLine(Img: TFPCustomImage): Boolean; +Var + Row, Col : Integer; + Pass, Every : byte; + P : PByte; + function IsMultiple(NumberA, NumberB: Integer): Boolean; + begin + Result := (NumberA >= NumberB) and + (NumberB > 0) and + (NumberA mod NumberB = 0); + end; +begin + Result:=false; + P:=FScanLine; + If FInterlace then + begin + For Pass := 1 to 4 do + begin + Case Pass of + 1 : begin + Row := 0; + Every := 8; + end; + 2 : begin + Row := 4; + Every := 8; + end; + 3 : begin + Row := 2; + Every := 4; + end; + 4 : begin + Row := 1; + Every := 2; + end; + end; + Repeat + for Col:=0 to Img.Width-1 do + begin + Img.Colors[Col,Row]:=FPalette[P^]; + Inc(P); + end; + Inc(Row, Every); + until Row >= Img.Height; + end; + end + else + begin + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + Img.Colors[Col,Row]:=FPalette[P^]; + Inc(P); + end; + end; + Result:=true; +end; + +function TFPReaderGif.InternalCheck(Stream: TStream): boolean; +var + OldPos: Int64; +begin + try + OldPos:=Stream.Position; + Stream.Read(FHeader,SizeOf(FHeader)); + Result:=(FHeader.Signature = 'GIF') and + ((FHeader.Version = '87a') or (FHeader.Version = '89a')); + Stream.Position:=OldPos; + except + Result:=False; + end; +end; + +function TFPReaderGif.SkipBlock(Stream: TStream): byte; +var + Introducer, + Labels, + SkipByte : byte; +begin + Stream.read(Introducer,1); + if Introducer = $21 then + begin + Stream.read(Labels,1); + Case Labels of + $FE, $FF : // Comment Extension block or Application Extension block + while true do + begin + Stream.Read(SkipByte, 1); + if SkipByte = 0 then Break; + Stream.Seek(SkipByte, soFromCurrent); + end; + $F9 : // Graphics Control Extension block + begin + Stream.Read(FGraphicsCtrlExt, SizeOf(FGraphicsCtrlExt)); + FGraphCtrlExt:=True; + end; + $01 : // Plain Text Extension block + begin + Stream.Read(SkipByte, 1); + Stream.Seek(SkipByte, soFromCurrent); + while true do + begin + Stream.Read(SkipByte, 1); + if SkipByte = 0 then Break; + Stream.Seek(SkipByte, soFromCurrent); + end; + end; + end; + end; + Result:=Introducer; +end; + +constructor TFPReaderGif.Create; +begin + inherited Create; + +end; + +destructor TFPReaderGif.Destroy; +begin + + inherited Destroy; +end; + +initialization + ImageHandlers.RegisterImageReader ('GIF Graphics', 'gif', TFPReaderGif); +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadjpeg.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadjpeg.pas new file mode 100644 index 0000000..1948b4c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadjpeg.pas @@ -0,0 +1,482 @@ +{ Copyright (C) 2003 Mattias Gaertner + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This 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 Library General Public License + for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ToDo: + - palette + + Modified 2013 by Martin Schreiber + +} +unit fpreadjpeg; +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses, sysutils,fpimage, +// {$ifdef FPC} +// jpeglib, jdapimin,jdatasrc, jdapistd, jmorecfg +// {$else} + jpeglib_del, jdapimin_del,jdatasrc_del, jdapistd_del, jmorecfg_del +// {$endif}; +; +type + { TFPReaderJPEG } + { This is a FPImage reader for jpeg images. } + + TFPReaderJPEG = class; + + PFPJPEGProgressManager = ^TFPJPEGProgressManager; + TFPJPEGProgressManager = record + pub : jpeg_progress_mgr; + instance: TObject; + last_pass: Integer; + last_pct: Integer; + last_time: Integer; + last_scanline: Integer; + end; + + TJPEGScale = (jsFullSize, jsHalf, jsQuarter, jsEighth); + TJPEGReadPerformance = (jpBestQuality, jpBestSpeed); + + TFPReaderJPEG = class(TFPCustomImageReader) + private + FSmoothing: boolean; + FMinHeight:integer; + FMinWidth:integer; + FWidth: Integer; + FHeight: Integer; + FGrayscale: boolean; + FProgressiveEncoding: boolean; + FError: jpeg_error_mgr; + FProgressMgr: TFPJPEGProgressManager; + FInfo: jpeg_decompress_struct; + FScale: TJPEGScale; + FPerformance: TJPEGReadPerformance; + procedure SetPerformance(const AValue: TJPEGReadPerformance); + procedure SetSmoothing(const AValue: boolean); + protected + procedure InternalRead(Str: TStream; Img: TFPCustomImage); override; + function InternalCheck(Str: TStream): boolean; override; + public + constructor Create; override; + destructor Destroy; override; + property GrayScale: boolean read FGrayscale; + property ProgressiveEncoding: boolean read FProgressiveEncoding; + property Smoothing: boolean read FSmoothing write SetSmoothing; + property Performance: TJPEGReadPerformance read FPerformance write SetPerformance; + property Scale: TJPEGScale read FScale write FScale; + property MinWidth:integer read FMinWidth write FMinWidth; + property MinHeight:integer read FMinHeight write FMinHeight; + end; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure ReadCompleteStreamToStream(SrcStream, DestStream: TStream; + StartSize: integer); +var + NewLength: Integer; + ReadLen: Integer; + Buffer: string; +begin + if (SrcStream is TMemoryStream) or (SrcStream is TFileStream) + or (SrcStream is TStringStream) + then begin + // read as one block + DestStream.CopyFrom(SrcStream,SrcStream.Size-SrcStream.Position); + end else begin + // read exponential + if StartSize<=0 then StartSize:=1024; + SetLength(Buffer,StartSize); + NewLength:=0; + repeat + ReadLen:=SrcStream.Read(Buffer[NewLength+1],length(Buffer)-NewLength); + inc(NewLength,ReadLen); + if NewLength0 then + DestStream.Write(Buffer[1],NewLength); + end; +end; + +procedure JPEGError(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + raise Exception.CreateFmt('JPEG error',[CurInfo^.err^.msg_code]); +end; + +procedure EmitMessage(CurInfo: j_common_ptr; msg_level: Integer); +begin + if CurInfo=nil then exit; + if msg_level=0 then ; +end; + +procedure OutputMessage(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; +end; + +procedure FormatMessage(CurInfo: j_common_ptr; var buffer: string); +begin + if CurInfo=nil then exit; + {$ifdef FPC_Debug_Image} + writeln('FormatMessage ',buffer); + {$endif} +end; + +procedure ResetErrorMgr(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + CurInfo^.err^.num_warnings := 0; + CurInfo^.err^.msg_code := 0; +end; + + +var + jpeg_std_error: jpeg_error_mgr; + +procedure ProgressCallback(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + // ToDo +end; + +{ TFPReaderJPEG } + +procedure TFPReaderJPEG.SetSmoothing(const AValue: boolean); +begin + if FSmoothing=AValue then exit; + FSmoothing:=AValue; +end; + +procedure TFPReaderJPEG.SetPerformance(const AValue: TJPEGReadPerformance); +begin + if FPerformance=AValue then exit; + FPerformance:=AValue; +end; + +procedure TFPReaderJPEG.InternalRead(Str: TStream; Img: TFPCustomImage); +var + MemStream: TMemoryStream; + + procedure SetSource; + begin + MemStream.Position:=0; + jpeg_stdio_src(@FInfo, @MemStream); + end; + + procedure ReadHeader; + begin + jpeg_read_header(@FInfo, TRUE); + FWidth := FInfo.image_width; + FHeight := FInfo.image_height; + FGrayscale := FInfo.jpeg_color_space = JCS_GRAYSCALE; + FProgressiveEncoding := jpeg_has_multiple_scans(@FInfo); + end; + + procedure InitReadingPixels; + var d1,d2:integer; + + function DToScale(inp:integer):TJPEGScale; + begin + if inp>7 then Result:=jsEighth else + if inp>3 then Result:=jsQuarter else + if inp>1 then Result:=jsHalf else + Result:=jsFullSize; + end; + + begin + FInfo.scale_num := 1; + + if (FMinWidth>0) and (FMinHeight>0) then + if (FInfo.image_width>FMinWidth) or (FInfo.image_height>FMinHeight) then + begin + d1:=Round((FInfo.image_width / FMinWidth)-0.5); + d2:=Round((FInfo.image_height / FMinHeight)-0.5); + if d1>d2 then fScale:=DToScale(d2) else fScale:=DtoScale(d1); + end; + + FInfo.scale_denom :=1 shl Byte(FScale); //1 + FInfo.do_block_smoothing := FSmoothing; + + if FGrayscale then FInfo.out_color_space := JCS_GRAYSCALE; + if (FInfo.out_color_space = JCS_GRAYSCALE) then + begin + FInfo.quantize_colors := True; + FInfo.desired_number_of_colors := 236; + end; + + if FPerformance = jpBestSpeed then + begin + FInfo.dct_method := JDCT_IFAST; + FInfo.two_pass_quantize := False; + FInfo.dither_mode := JDITHER_ORDERED; + // FInfo.do_fancy_upsampling := False; can create an AV inside jpeglib + end; + + if FProgressiveEncoding then + begin + FInfo.enable_2pass_quant := FInfo.two_pass_quantize; + FInfo.buffered_image := True; + end; + end; + + function CorrectCMYK(const C: TFPColor): TFPColor; + var + MinColor: word; + begin + if C.red$FF then MinColor:=$FF-C.alpha; + Result.red:=(C.red-MinColor) shl 8; + Result.green:=(C.green-MinColor) shl 8; + Result.blue:=(C.blue-MinColor) shl 8; + Result.alpha:=alphaOpaque; + end; + procedure ReadPixels; + var + Continue: Boolean; + SampArray: JSAMPARRAY; + SampRow: JSAMPROW; + Color: TFPColor; + LinesRead: Cardinal; +// x: Integer; + y: Integer; + c: word; + Status,Scan: integer; + ReturnValue,RestartLoop: Boolean; + procedure OutputScanLines(); + var + x: integer; + begin + Color.Alpha:=alphaOpaque; + y:=0; + while (FInfo.output_scanline < FInfo.output_height) do begin + // read one line per call + LinesRead := jpeg_read_scanlines(@FInfo, SampArray, 1); + if LinesRead<1 then begin + ReturnValue:=false; + break; + end; + if (FInfo.jpeg_color_space = JCS_CMYK) then + for x:=0 to FInfo.output_width-1 do begin + Color.Red:=SampRow^[x*4+0]; + Color.Green:=SampRow^[x*4+1]; + Color.Blue:=SampRow^[x*4+2]; + Color.alpha:=SampRow^[x*4+3]; + Img.Colors[x,y]:=CorrectCMYK(Color); + end + else + if fgrayscale then begin + for x:=0 to FInfo.output_width-1 do begin + c:= SampRow^[x] shl 8; + Color.Red:=c; + Color.Green:=c; + Color.Blue:=c; + Img.Colors[x,y]:=Color; + end; + end + else begin + for x:=0 to FInfo.output_width-1 do begin + Color.Red:=SampRow^[x*3+0] shl 8; + Color.Green:=SampRow^[x*3+1] shl 8; + Color.Blue:=SampRow^[x*3+2] shl 8; + Img.Colors[x,y]:=Color; + end; + end; + inc(y); + end; + end; + begin + InitReadingPixels; + + Continue:=true; + Progress(psStarting, 0, False, Rect(0,0,0,0), '', Continue); + if not Continue then exit; + + jpeg_start_decompress(@FInfo); + + Img.SetSize(FInfo.output_width,FInfo.output_height); + + GetMem(SampArray,SizeOf(JSAMPROW)); + GetMem(SampRow,FInfo.output_width*FInfo.output_components); + SampArray^[0]:=SampRow; + try + case FProgressiveEncoding of + false: + begin + ReturnValue:=true; + OutputScanLines(); + if FInfo.buffered_image then jpeg_finish_output(@FInfo); + end; + true: + begin + while true do begin + (* The RestartLoop variable drops a placeholder for suspension + mode, or partial jpeg decode, return and continue. In case + of support this suspension, the RestartLoop:=True should be + changed by an Exit and in the routine enter detects that it + is being called from a suspended state to not + reinitialize some buffer *) + RestartLoop:=false; + repeat + status := jpeg_consume_input(@FInfo); + until (status=JPEG_SUSPENDED) or (status=JPEG_REACHED_EOI); + ReturnValue:=true; + if FInfo.output_scanline = 0 then begin + Scan := FInfo.input_scan_number; + (* if we haven't displayed anything yet (output_scan_number==0) + and we have enough data for a complete scan, force output + of the last full scan *) + if (FInfo.output_scan_number = 0) and (Scan > 1) and + (status <> JPEG_REACHED_EOI) then Dec(Scan); + + if not jpeg_start_output(@FInfo, Scan) then begin + RestartLoop:=true; (* I/O suspension *) + end; + end; + + if not RestartLoop then begin + if (FInfo.output_scanline = $ffffff) then + FInfo.output_scanline := 0; + + OutputScanLines(); + + if ReturnValue=false then begin + if (FInfo.output_scanline = 0) then begin + (* didn't manage to read any lines - flag so we don't call + jpeg_start_output() multiple times for the same scan *) + FInfo.output_scanline := $ffffff; + end; + RestartLoop:=true; (* I/O suspension *) + end; + + if not RestartLoop then begin + if (FInfo.output_scanline = FInfo.output_height) then begin + if not jpeg_finish_output(@FInfo) then begin + RestartLoop:=true; (* I/O suspension *) + end; + + if not RestartLoop then begin + if (jpeg_input_complete(@FInfo) and + (FInfo.input_scan_number = FInfo.output_scan_number)) then + break; + + FInfo.output_scanline := 0; + end; + end; + end; + end; + if RestartLoop then begin + (* Suspension mode, but as not supported by this implementation + it will simple break the loop to avoid endless looping. *) + break; + end; + end; + end; + end; + finally + FreeMem(SampRow); + FreeMem(SampArray); + end; + + jpeg_finish_decompress(@FInfo); + + Progress(psEnding, 100, false, Rect(0,0,0,0), '', Continue); + end; + +begin + FWidth:=0; + FHeight:=0; + MemStream:=nil; + FillChar(FInfo,SizeOf(FInfo),0); + try + if Str is TMemoryStream then + MemStream:=TMemoryStream(Str) + else begin + MemStream:=TMemoryStream.Create; + ReadCompleteStreamToStream(Str,MemStream,1024); + MemStream.Position:=0; + end; + if MemStream.Size > 0 then begin + FError:=jpeg_std_error; + FInfo.err := @FError; + jpeg_CreateDecompress(@FInfo, JPEG_LIB_VERSION, SizeOf(FInfo)); + try + FProgressMgr.pub.progress_monitor := @ProgressCallback; + FProgressMgr.instance := Self; + FInfo.progress := @FProgressMgr.pub; + SetSource; + ReadHeader; + ReadPixels; + finally + jpeg_Destroy_Decompress(@FInfo); + end; + end; + finally + if (MemStream<>nil) and (MemStream<>Str) then + MemStream.Free; + end; +end; + +function TFPReaderJPEG.InternalCheck(Str: TStream): boolean; +begin + // ToDo: read header and check + Result:=false; + if Str=nil then exit; + Result:=true; +end; + +constructor TFPReaderJPEG.Create; +begin + FScale:=jsFullSize; + FPerformance:=jpBestSpeed; + inherited Create; +end; + +destructor TFPReaderJPEG.Destroy; +begin + inherited Destroy; +end; + +initialization + with jpeg_std_error do begin + error_exit:=@JPEGError; + emit_message:=@EmitMessage; + output_message:=@OutputMessage; + format_message:=@FormatMessage; + reset_error_mgr:=@ResetErrorMgr; + end; + ImageHandlers.RegisterImageReader ('JPEG Graphics', 'jpg;jpeg', TFPReaderJPEG); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadpcx.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadpcx.pas new file mode 100644 index 0000000..f6c5bc1 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadpcx.pas @@ -0,0 +1,310 @@ +{ Copyright (C) 2007 Laurent Jacques + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This 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 Library General Public License + for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Load all format compressed or not +} + +unit FPReadPCX; + +{$mode objfpc}{$H+} + +interface + +uses FPImage, Classes, SysUtils, pcxcomn; + +type + + { TFPReaderPCX } + + TFPReaderPCX = class(TFPCustomImageReader) + private + FCompressed: boolean; + protected + Header: TPCXHeader; + BytesPerPixel: byte; + FScanLine: PByte; + FLineSize: integer; + TotalWrite: longint; + procedure CreateGrayPalette(Img: TFPCustomImage); + procedure CreateBWPalette(Img: TFPCustomImage); + procedure CreatePalette16(Img: TFPCustomImage); + procedure ReadPalette(Stream: TStream; Img: TFPCustomImage); + procedure AnalyzeHeader(Img: TFPCustomImage); + function InternalCheck(Stream: TStream): boolean; override; + procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override; + procedure ReadScanLine(Row: integer; Stream: TStream); virtual; + procedure UpdateProgress(percent: longint); + procedure WriteScanLine(Row: integer; Img: TFPCustomImage); virtual; + public + property Compressed: boolean Read FCompressed; + end; + +implementation + + +procedure TFPReaderPCX.CreatePalette16(Img: TFPCustomImage); +var + I: integer; + c: TFPColor; +begin + Img.UsePalette := True; + Img.Palette.Clear; + for I := 0 to 15 do + begin + with c, header do + begin + Red := ColorMap[I].red shl 8; + Green := ColorMap[I].Green shl 8; + Blue := ColorMap[I].Blue shl 8; + Alpha := alphaOpaque; + end; + Img.Palette.Add(c); + end; +end; + +procedure TFPReaderPCX.CreateGrayPalette(Img: TFPCustomImage); +var + I: integer; + c: TFPColor; +begin + Img.UsePalette := True; + Img.Palette.Clear; + for I := 0 to 255 do + begin + with c do + begin + Red := I * 255; + Green := I * 255; + Blue := I * 255; + Alpha := alphaOpaque; + end; + Img.Palette.Add(c); + end; +end; + +procedure TFPReaderPCX.CreateBWPalette(Img: TFPCustomImage); +begin + Img.UsePalette := True; + Img.Palette.Clear; + Img.Palette.Add(colBlack); + Img.Palette.Add(colWhite); +end; + +procedure TFPReaderPCX.ReadPalette(Stream: TStream; Img: TFPCustomImage); +var + RGBEntry: TRGB; + I: integer; + c: TFPColor; + OldPos: integer; +begin + Img.UsePalette := True; + Img.Palette.Clear; + OldPos := Stream.Position; + Stream.Position := Stream.Size - 768; + for I := 0 to 255 do + begin + Stream.Read(RGBEntry, SizeOf(RGBEntry)); + with c do + begin + Red := RGBEntry.Red shl 8; + Green := RGBEntry.Green shl 8; + Blue := RGBEntry.Blue shl 8; + Alpha := alphaOpaque; + end; + Img.Palette.Add(C); + end; + Stream.Position := OldPos; +end; + +procedure TFPReaderPCX.AnalyzeHeader(Img: TFPCustomImage); +begin + with Header do + begin + if not ((FileID in [$0A, $0C]) and (ColorPlanes in [1, 3, 4]) and + (Version in [0, 2, 3, 5]) and (PaletteType in [1, 2])) then + raise Exception.Create('Unknown/Unsupported PCX image type'); + BytesPerPixel := BitsPerPixel * ColorPlanes; + FCompressed := Encoding = 1; + Img.Width := XMax - XMin + 1; + Img.Height := YMax - YMin + 1; + FLineSize := (BytesPerLine * ColorPlanes); + GetMem(FScanLine, FLineSize); + end; +end; + +procedure TFPReaderPCX.ReadScanLine(Row: integer; Stream: TStream); +var + P: PByte; + B: byte; + bytes, Count: integer; +begin + P := FScanLine; + bytes := FLineSize; + Count := 0; + if Compressed then + begin + while bytes > 0 do + begin + if (Count = 0) then + begin + Stream.ReadBuffer(B, 1); + if (B < $c0) then + Count := 1 + else + begin + Count := B - $c0; + Stream.ReadBuffer(B, 1); + end; + end; + Dec(Count); + P[0] := B; + Inc(P); + Dec(bytes); + end; + end + else + Stream.ReadBuffer(FScanLine^, FLineSize); +end; + +procedure TFPReaderPCX.UpdateProgress(percent: longint); +var + continue: boolean; + Rect: TRect; +begin + Rect.Left := 0; + Rect.Top := 0; + Rect.Right := 0; + Rect.Bottom := 0; + continue := True; + Progress(psRunning, 0, False, Rect, '', continue); +end; + +procedure TFPReaderPCX.InternalRead(Stream: TStream; Img: TFPCustomImage); +var + H, Row: integer; + continue: boolean; + Rect: TRect; +begin + TotalWrite := 0; + Rect.Left := 0; + Rect.Top := 0; + Rect.Right := 0; + Rect.Bottom := 0; + continue := True; + Progress(psStarting, 0, False, Rect, '', continue); + Stream.Read(Header, SizeOf(Header)); + AnalyzeHeader(Img); + case BytesPerPixel of + 1: CreateBWPalette(Img); + 4: CreatePalette16(Img); + 8: ReadPalette(stream, Img); + else + if (Header.PaletteType = 2) then + CreateGrayPalette(Img); + end; + H := Img.Height; + TotalWrite := Img.Height * Img.Width; + for Row := 0 to H - 1 do + begin + ReadScanLine(Row, Stream); + WriteScanLine(Row, Img); + end; + Progress(psEnding, 100, False, Rect, '', continue); + freemem(FScanLine); +end; + +procedure TFPReaderPCX.WriteScanLine(Row: integer; Img: TFPCustomImage); +var + Col: integer; + C: TFPColor; + P, P1, P2, P3: PByte; + Z2: word; + color: byte; +begin + C.Alpha := AlphaOpaque; + P := FScanLine; + Z2 := Header.BytesPerLine; + begin + case BytesPerPixel of + 1: + begin + for Col := 0 to Img.Width - 1 do + begin + if (P[col div 8] and (128 shr (col mod 8))) <> 0 then + Img.Colors[Col, Row] := Img.Palette[1] + else + Img.Colors[Col, Row] := Img.Palette[0]; + UpdateProgress(trunc(100.0 * (Row * Col / TotalWrite))); + end; + end; + 4: + begin + P1 := P; + Inc(P1, Z2); + P2 := P; + Inc(P2, Z2 * 2); + P3 := P; + Inc(P3, Z2 * 3); + for Col := 0 to Img.Width - 1 do + begin + color := 0; + if (P[col div 8] and (128 shr (col mod 8))) <> 0 then + Inc(color, 1); + if (P1[col div 8] and (128 shr (col mod 8))) <> 0 then + Inc(color, 1 shl 1); + if (P2[col div 8] and (128 shr (col mod 8))) <> 0 then + Inc(color, 1 shl 2); + if (P3[col div 8] and (128 shr (col mod 8))) <> 0 then + Inc(color, 1 shl 3); + Img.Colors[Col, Row] := Img.Palette[color]; + UpdateProgress(trunc(100.0 * (Row * Col / TotalWrite))); + end; + end; + 8: + begin + for Col := 0 to Img.Width - 1 do + begin + Img.Colors[Col, Row] := Img.Palette[P[Col]]; + UpdateProgress(trunc(100.0 * (Row * Col / TotalWrite))); + end; + end; + 24: + begin + for Col := 0 to Img.Width - 1 do + begin + with C do + begin + Red := P[col] or (P[col] shl 8); + Blue := P[col + Z2 * 2] or (P[col + Z2 * 2] shl 8); + Green := P[col + Z2] or (P[col + Z2] shl 8); + Alpha := alphaOpaque; + end; + Img[col, row] := C; + UpdateProgress(trunc(100.0 * (Row * Col / TotalWrite))); + end; + end; + end; + end; +end; + +function TFPReaderPCX.InternalCheck(Stream: TStream): boolean; +begin + Result := True; +end; + +initialization + ImageHandlers.RegisterImageReader('PCX Format', 'pcx', TFPReaderPCX); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadpng.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadpng.pas new file mode 100644 index 0000000..b676a55 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadpng.pas @@ -0,0 +1,870 @@ +{ + $Id: fpreadpng.pp,v 1.10 2003/10/19 21:09:51 luk Exp $ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + PNG reader implementation + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +//modified 2013 by Martin Schreiber + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +unit fpreadpng; + +interface + +uses + sysutils,classes,mclasses, fpimage,zstream, + {$ifdef FPC} + fpimgcmn, pngcomn + {$else} + fpimgcmn_del, pngcomn_del + {$endif}; + +Type + + TSetPixelProc = procedure (x,y:integer; CD : TColordata) of object; + TConvertColorProc = function (CD:TColorData) : TFPColor of object; + + TFPReaderPNG = class (TFPCustomImageReader) + private + + FHeader : THeaderChunk; + ZData : TMemoryStream; // holds compressed data until all blocks are read + Decompress : TDeCompressionStream; // decompresses the data + FPltte : boolean; // if palette is used + FCountScanlines : EightLong; //Number of scanlines to process for each pass + FScanLineLength : EightLong; //Length of scanline for each pass + FCurrentPass : byte; + ByteWidth : byte; // number of bytes to read for pixel information + BitsUsed : EightLong; // bitmasks to use to split a byte into smaller parts + BitShift : byte; // shift right to do of the bits extracted with BitsUsed for 1 element + CountBitsUsed : byte; // number of bit groups (1 pixel) per byte (when bytewidth = 1) + //CFmt : TColorFormat; // format of the colors to convert from + StartX,StartY, DeltaX,DeltaY, StartPass,EndPass : integer; // number and format of passes + FSwitchLine, FCurrentLine, FPreviousLine : pByteArray; + FPalette : TFPPalette; + FSetPixel : TSetPixelProc; + FConvertColor : TConvertColorProc; + procedure ReadChunk; + procedure HandleData; + procedure HandleUnknown; + function ColorGray1 (CD:TColorData) : TFPColor; + function ColorGray2 (CD:TColorData) : TFPColor; + function ColorGray4 (CD:TColorData) : TFPColor; + function ColorGray8 (CD:TColorData) : TFPColor; + function ColorGray16 (CD:TColorData) : TFPColor; + function ColorGrayAlpha8 (CD:TColorData) : TFPColor; + function ColorGrayAlpha16 (CD:TColorData) : TFPColor; + function ColorColor8 (CD:TColorData) : TFPColor; + function ColorColor16 (CD:TColorData) : TFPColor; + function ColorColorAlpha8 (CD:TColorData) : TFPColor; + function ColorColorAlpha16 (CD:TColorData) : TFPColor; + protected + Chunk : TChunk; + UseTransparent, EndOfFile : boolean; + TransparentDataValue : TColorData; + UsingBitGroup : byte; + DataIndex : longword; + DataBytes : TColorData; + function CurrentLine(x:longword) : byte; + function PrevSample (x:longword): byte; + function PreviousLine (x:longword) : byte; + function PrevLinePrevSample (x:longword): byte; + procedure HandleChunk; virtual; + procedure HandlePalette; virtual; + procedure HandleAlpha; virtual; + function CalcX (relX:integer) : integer; + function CalcY (relY:integer) : integer; + function CalcColor: TColorData; + procedure HandleScanLine (const y : integer; const ScanLine : PByteArray); virtual; + procedure DoDecompress; virtual; + function DoFilter(LineFilter:byte;index:longword; b:byte) : byte; virtual; + procedure SetPalettePixel (x,y:integer; CD : TColordata); + procedure SetPalColPixel (x,y:integer; CD : TColordata); + procedure SetColorPixel (x,y:integer; CD : TColordata); + procedure SetColorTrPixel (x,y:integer; CD : TColordata); + function DecideSetPixel : TSetPixelProc; virtual; + procedure InternalRead (Str:TStream; Img:TFPCustomImage); override; + function InternalCheck (Str:TStream) : boolean; override; + //property ColorFormat : TColorformat read CFmt; + property ConvertColor : TConvertColorProc read FConvertColor; + property CurrentPass : byte read FCurrentPass; + property Pltte : boolean read FPltte; + property ThePalette : TFPPalette read FPalette; + property Header : THeaderChunk read FHeader; + property CountScanlines : EightLong read FCountScanlines; + property ScanLineLength : EightLong read FScanLineLength; + public + constructor create; override; + destructor destroy; override; + end; + +implementation + + + +const StartPoints : array[0..7, 0..1] of word = + ((0,0),(0,0),(4,0),(0,4),(2,0),(0,2),(1,0),(0,1)); + Delta : array[0..7,0..1] of word = + ((1,1),(8,8),(8,8),(4,8),(4,4),(2,4),(2,2),(1,2)); + BitsUsed1Depth : EightLong = ($80,$40,$20,$10,$08,$04,$02,$01); + BitsUsed2Depth : EightLong = ($C0,$30,$0C,$03,0,0,0,0); + BitsUsed4Depth : EightLong = ($F0,$0F,0,0,0,0,0,0); + +constructor TFPReaderPNG.create; +begin + inherited; + chunk.acapacity := 0; + chunk.data := nil; + UseTransparent := False; +end; + +destructor TFPReaderPNG.destroy; +begin + with chunk do + if acapacity > 0 then + freemem (data); + inherited; +end; + +procedure TFPReaderPNG.ReadChunk; + +var ChunkHeader : TChunkHeader; + readCRC : longword; + l : longword; +begin + TheStream.Read (ChunkHeader,sizeof(ChunkHeader)); + with chunk do + begin + // chunk header + with ChunkHeader do + begin + {$IFDEF ENDIAN_LITTLE} + alength := swap(CLength); + {$ELSE} + alength := CLength; + {$ENDIF} + ReadType := CType; + end; + aType := low(TChunkTypes); + while (aType < high(TChunkTypes)) and (ChunkTypes[aType] <> ReadType) do + inc (aType); + if alength > MaxChunkLength then + raise PNGImageException.Create ('Invalid chunklength'); + if alength > acapacity then + begin + if acapacity > 0 then + freemem (data); + GetMem (data, alength); + acapacity := alength; + end; + l := TheStream.read (data^, alength); + if l <> alength then + raise PNGImageException.Create ('Chunk length exceeds stream length'); + TheStream.Read (readCRC, sizeof(ReadCRC)); + l := CalculateCRC (All1Bits, ReadType, sizeOf(ReadType)); + l := CalculateCRC (l, data^, alength); + {$IFDEF ENDIAN_LITTLE} + l := swap(l xor All1Bits); + {$ELSE} + l := l xor All1Bits; + {$ENDIF} + if ReadCRC <> l then + raise PNGImageException.Create ('CRC check failed'); + end; +end; + +procedure TFPReaderPNG.HandleData; +var OldSize : longword; +begin + OldSize := ZData.size; + ZData.Size := OldSize + Chunk.aLength; + ZData.Write (chunk.Data^, chunk.aLength); +end; + +procedure TFPReaderPNG.HandleAlpha; + procedure PaletteAlpha; + var r : integer; + a : word; + c : TFPColor; + begin + with chunk do + begin + if alength > longword(ThePalette.count) then + raise PNGImageException.create ('To much alpha values for palette'); + for r := 0 to alength-1 do + begin + c := ThePalette[r]; + a := data^[r]; + c.alpha := (a shl 8) + a; + ThePalette[r] := c; + end; + end; + end; + procedure TransparentGray; + var a : word; + begin + move (chunk.data^[0], a, 2); + {$IFDEF ENDIAN_LITTLE} + a := swap (a); + {$ENDIF} + TransparentDataValue := a; + UseTransparent := True; + end; + procedure TransparentColor; + var d : byte; + r,g,b : word; + a : TColorData; + begin + with chunk do + begin + move (data^[0], r, 2); + move (data^[2], g, 2); + move (data^[4], b, 2); + end; + {$IFDEF ENDIAN_LITTLE} + r := swap (r); + g := swap (g); + b := swap (b); + {$ENDIF} + d := header.bitdepth; + a := (TColorData(b) shl d) shl d; + a := a + (TColorData(g) shl d) + r; + TransparentDataValue := a; + UseTransparent := True; + end; +begin + case header.ColorType of + 3 : PaletteAlpha; + 0 : TransparentGray; + 2 : TransparentColor; + end; +end; + +procedure TFPReaderPNG.HandlePalette; +var r : longword; + c : TFPColor; + t : word; +begin + if header.colortype = 3 then + with chunk do + begin + if TheImage.UsePalette then + FPalette := TheImage.Palette + else + FPalette := TFPPalette.Create(0); + c.Alpha := AlphaOpaque; + if (aLength mod 3) > 0 then + raise PNGImageException.Create ('Impossible length for PLTE-chunk'); + r := 0; + ThePalette.count := 0; + while r < alength do + begin + t := data^[r]; + c.red := t + (t shl 8); + inc (r); + t := data^[r]; + c.green := t + (t shl 8); + inc (r); + t := data^[r]; + c.blue := t + (t shl 8); + inc (r); + ThePalette.Add (c); + end; + end; +end; + +procedure TFPReaderPNG.SetPalettePixel (x,y:integer; CD : TColordata); +begin // both PNG and palette have palette + TheImage.Pixels[x,y] := CD; +end; + +procedure TFPReaderPNG.SetPalColPixel (x,y:integer; CD : TColordata); +begin // PNG with palette, Img without + TheImage.Colors[x,y] := ThePalette[CD]; +end; + +procedure TFPReaderPNG.SetColorPixel (x,y:integer; CD : TColordata); +var c : TFPColor; +begin // both PNG and Img work without palette, and no transparency colordata + // c := ConvertColor (CD,CFmt); + c := ConvertColor (CD); + TheImage.Colors[x,y] := c; +end; + +procedure TFPReaderPNG.SetColorTrPixel (x,y:integer; CD : TColordata); +var c : TFPColor; +begin // both PNG and Img work without palette, and there is a transparency colordata + //c := ConvertColor (CD,CFmt); + c := ConvertColor (CD); + if TransparentDataValue = CD then + c.alpha := alphaTransparent; + TheImage.Colors[x,y] := c; +end; + +function TFPReaderPNG.CurrentLine(x:longword):byte; +begin + result := FCurrentLine^[x]; +end; + +function TFPReaderPNG.PrevSample (x:longword): byte; +begin + if x < byteWidth then + result := 0 + else + result := FCurrentLine^[x - bytewidth]; +end; + +function TFPReaderPNG.PreviousLine (x:longword) : byte; +begin + result := FPreviousline^[x]; +end; + +function TFPReaderPNG.PrevLinePrevSample (x:longword): byte; +begin + if x < byteWidth then + result := 0 + else + result := FPreviousLine^[x - bytewidth]; +end; + +function TFPReaderPNG.DoFilter(LineFilter:byte;index:longword; b:byte) : byte; +var diff : byte; + procedure FilterSub; + begin + diff := PrevSample(index); + end; + procedure FilterUp; + begin + diff := PreviousLine(index); + end; + procedure FilterAverage; + var l, p : word; + begin + l := PrevSample(index); + p := PreviousLine(index); + diff := (l + p) div 2; + end; + procedure FilterPaeth; + var dl, dp, dlp : word; // index for previous and distances for: + l, p, lp : byte; // r:predictor, Left, Previous, LeftPrevious + r : integer; + begin + l := PrevSample(index); + lp := PrevLinePrevSample(index); + p := PreviousLine(index); + r := l + p - lp; + dl := abs (r - l); + dlp := abs (r - lp); + dp := abs (r - p); + if (dl <= dp) and (dl <= dlp) then + diff := l + else if dp <= dlp then + diff := p + else + diff := lp; + end; +begin + diff:= 0; + case LineFilter of + 0 : diff := 0; + 1 : FilterSub; + 2 : FilterUp; + 3 : FilterAverage; + 4 : FilterPaeth; + end; + result := (b + diff) mod $100; +end; + +function TFPReaderPNG.DecideSetPixel : TSetPixelProc; +begin + if Pltte then + if TheImage.UsePalette then + result := {$ifdef FPC}@{$endif}SetPalettePixel + else + result := {$ifdef FPC}@{$endif}SetPalColPixel + else + if UseTransparent then + result := {$ifdef FPC}@{$endif}SetColorTrPixel + else + result := {$ifdef FPC}@{$endif}SetColorPixel; +end; + +function TFPReaderPNG.CalcX (relX:integer) : integer; +begin + result := StartX + (relX * deltaX); +end; + +function TFPReaderPNG.CalcY (relY:integer) : integer; +begin + result := StartY + (relY * deltaY); +end; + +function TFPReaderPNG.CalcColor: TColorData; +var cd : longword; + r : word; +// b : byte; + tmp : pbytearray; +begin + if UsingBitGroup = 0 then + begin + Databytes := 0; + if Header.BitDepth = 16 then + begin + getmem(tmp, bytewidth); + fillchar(tmp^, bytewidth, 0); + for r:=0 to bytewidth-2 do + tmp^[r+1]:=FCurrentLine^[Dataindex+r]; + move (tmp^[0], Databytes, bytewidth); + freemem(tmp); + end + else move (FCurrentLine^[DataIndex], Databytes, bytewidth); + {$IFDEF ENDIAN_BIG} + Databytes:=swap(Databytes); + {$ENDIF} + inc (DataIndex,bytewidth); + end; + if bytewidth = 1 then + begin + cd := (Databytes and BitsUsed[UsingBitGroup]); + result := cd shr ((CountBitsUsed-UsingBitGroup-1) * BitShift); + inc (UsingBitgroup); + if UsingBitGroup >= CountBitsUsed then + UsingBitGroup := 0; + end + else + result := Databytes; +end; + +procedure TFPReaderPNG.HandleScanLine (const y : integer; const ScanLine : PByteArray); +var x, rx : integer; + c : TColorData; +begin + UsingBitGroup := 0; + DataIndex := 0; + for rx := 0 to ScanlineLength[CurrentPass]-1 do + begin + X := CalcX(rx); + c := CalcColor; + FSetPixel (x,y,c); + end +end; + +function TFPReaderPNG.ColorGray1 (CD:TColorDAta) : TFPColor; +begin + if CD = 0 then + result := colBlack + else + result := colWhite; +end; + +function TFPReaderPNG.ColorGray2 (CD:TColorDAta) : TFPColor; +var c : word; +begin + c := CD and 3; + c := c + (c shl 2); + c := c + (c shl 4); + c := c + (c shl 8); + with result do + begin + red := c; + green := c; + blue := c; + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorGray4 (CD:TColorDAta) : TFPColor; +var c : word; +begin + c := CD and $F; + c := c + (c shl 4); + c := c + (c shl 8); + with result do + begin + red := c; + green := c; + blue := c; + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorGray8 (CD:TColorDAta) : TFPColor; +var c : word; +begin + c := CD and $FF; + c := c + (c shl 8); + with result do + begin + red := c; + green := c; + blue := c; + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorGray16 (CD:TColorDAta) : TFPColor; +var c : word; +begin + c := CD and $FFFF; + with result do + begin + red := c; + green := c; + blue := c; + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorGrayAlpha8 (CD:TColorData) : TFPColor; +var c : word; +begin + c := CD and $00FF; + c := c + (c shl 8); + with result do + begin + red := c; + green := c; + blue := c; + c := CD and $FF00; + alpha := c + (c shr 8); + end; +end; + +function TFPReaderPNG.ColorGrayAlpha16 (CD:TColorData) : TFPColor; +var c : word; +begin + c := (CD shr 16) and $FFFF; + with result do + begin + red := c; + green := c; + blue := c; + alpha := CD and $FFFF; + end; +end; + +function TFPReaderPNG.ColorColor8 (CD:TColorData) : TFPColor; +var c : word; +begin + with result do + begin + c := CD and $FF; + red := c + (c shl 8); + CD:=CD shr 8; + c := CD and $FF; + green := c + (c shl 8); + CD:=CD shr 8; + c := CD and $FF; + blue := c + (c shl 8); + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorColor16 (CD:TColorData) : TFPColor; +begin + with result do + begin + red := CD and $FFFF; + CD:=CD shr 16; + green := CD and $FFFF; + CD:=CD shr 16; + blue := CD and $FFFF; + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorColorAlpha8 (CD:TColorData) : TFPColor; +var c : word; +begin + with result do + begin + c := CD and $FF; + red := c + (c shl 8); + CD:=CD shr 8; + c := CD and $FF; + green := c + (c shl 8); + CD:=CD shr 8; + c := CD and $FF; + blue := c + (c shl 8); + CD:=CD shr 8; + c := CD and $FF; + alpha := c + (c shl 8); + end; +end; + +function TFPReaderPNG.ColorColorAlpha16 (CD:TColorData) : TFPColor; +begin + with result do + begin + red := CD and $FFFF; + CD:=CD shr 16; + green := CD and $FFFF; + CD:=CD shr 16; + blue := CD and $FFFF; + CD:=CD shr 16; + alpha := CD and $FFFF; + end; +end; + +procedure TFPReaderPNG.DoDecompress; + + procedure initVars; + var r,d : integer; + begin + with Header do + begin + if interlace=0 then + begin + StartPass := 0; + EndPass := 0; + FCountScanlines[0] := Height; + FScanLineLength[0] := Width; + end + else + begin + StartPass := 1; + EndPass := 7; + for r := 1 to 7 do + begin + d := Height div delta[r,1]; + if (height mod delta[r,1]) > startpoints[r,1] then + inc (d); + FCountScanlines[r] := d; + d := width div delta[r,0]; + if (width mod delta[r,0]) > startpoints[r,0] then + inc (d); + FScanLineLength[r] := d; + end; + end; + Fpltte := (ColorType = 3); + case colortype of + 0 : case Bitdepth of + 1 : begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGray1; //CFmt := cfMono; + ByteWidth := 1; + end; + 2 : begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGray2; //CFmt := cfGray2; + ByteWidth := 1; + end; + 4 : begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGray4; //CFmt := cfGray4; + ByteWidth := 1; + end; + 8 : begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGray8; //CFmt := cfGray8; + ByteWidth := 1; + end; + 16 : begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGray16; //CFmt := cfGray16; + ByteWidth := 2; + end; + end; + 2 : if BitDepth = 8 then + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorColor8; //CFmt := cfBGR24 + ByteWidth := 3; + end + else + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorColor16; //CFmt := cfBGR48; + ByteWidth := 6; + end; + 3 : if BitDepth = 16 then + ByteWidth := 2 + else + ByteWidth := 1; + 4 : if BitDepth = 8 then + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGrayAlpha8; //CFmt := cfGrayA16 + ByteWidth := 2; + end + else + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGrayAlpha16; //CFmt := cfGrayA32; + ByteWidth := 4; + end; + 6 : if BitDepth = 8 then + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorColorAlpha8; //CFmt := cfABGR32 + ByteWidth := 4; + end + else + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorColorAlpha16; //CFmt := cfABGR64; + ByteWidth := 8; + end; + end; + //ByteWidth := BytesNeeded[CFmt]; + case BitDepth of + 1 : begin + CountBitsUsed := 8; + BitShift := 1; + BitsUsed := BitsUsed1Depth; + end; + 2 : begin + CountBitsUsed := 4; + BitShift := 2; + BitsUsed := BitsUsed2Depth; + end; + 4 : begin + CountBitsUsed := 2; + BitShift := 4; + BitsUsed := BitsUsed4Depth; + end; + 8 : begin + CountBitsUsed := 1; + BitShift := 0; + BitsUsed[0] := $FF; + end; + end; + end; + end; + + procedure Decode; + var y, rp, ry, rx, l : integer; + lf : byte; + begin + FSetPixel := DecideSetPixel(); + for rp := StartPass to EndPass do + begin + FCurrentPass := rp; + StartX := StartPoints[rp,0]; + StartY := StartPoints[rp,1]; + DeltaX := Delta[rp,0]; + DeltaY := Delta[rp,1]; + if bytewidth = 1 then + begin + l := (ScanLineLength[rp] div CountBitsUsed); + if (ScanLineLength[rp] mod CountBitsUsed) > 0 then + inc (l); + end + else + l := ScanLineLength[rp]*ByteWidth; + if (l>0) then + begin + GetMem (FPreviousLine, l); + GetMem (FCurrentLine, l); + fillchar (FCurrentLine^,l,0); + try + for ry := 0 to CountScanlines[rp]-1 do + begin + FSwitchLine := FCurrentLine; + FCurrentLine := FPreviousLine; + FPreviousLine := FSwitchLine; + Y := CalcY(ry); + Decompress.Read (lf, sizeof(lf)); + Decompress.Read (FCurrentLine^, l); + if lf <> 0 then // Do nothing when there is no filter used + for rx := 0 to l-1 do + FCurrentLine^[rx] := DoFilter (lf, rx, FCurrentLine^[rx]); + HandleScanLine (y, FCurrentLine); + end; + finally + freemem (FPreviousLine); + freemem (FCurrentLine); + end; + end; + end; + end; + +begin + InitVars; + DeCode; +end; + +procedure TFPReaderPNG.HandleChunk; +begin + case chunk.AType of + ctIHDR : raise PNGImageException.Create ('Second IHDR chunk found'); + ctPLTE : HandlePalette; + ctIDAT : HandleData; + ctIEND : EndOfFile := True; + cttRNS : HandleAlpha; + else HandleUnknown; + end; +end; + +procedure TFPReaderPNG.HandleUnknown; +begin + if (chunk.readtype[0] in ['A'..'Z']) then + raise PNGImageException.Create('Critical chunk '+chunk.readtype+' not recognized'); +end; + +procedure TFPReaderPNG.InternalRead (Str:TStream; Img:TFPCustomImage); +begin + {$ifdef FPC_Debug_Image} + if Str<>TheStream then + writeln('WARNING: TFPReaderPNG.InternalRead Str<>TheStream'); + {$endif} + with Header do + Img.SetSize (Width, Height); + ZData := TMemoryStream.Create; + try + EndOfFile := false; + while not EndOfFile do + begin + ReadChunk; + HandleChunk; + end; + ZData.position:=0; + Decompress := TDecompressionStream.Create (ZData); + try + DoDecompress; + finally + Decompress.Free; + end; + finally + ZData.Free; + if not img.UsePalette and assigned(FPalette) then + begin + FPalette.Free; + end; + end; +end; + +function TFPReaderPNG.InternalCheck (Str:TStream) : boolean; +var SigCheck : array[0..7] of byte; + r : integer; +begin + try + // Check Signature + Str.Read(SigCheck, SizeOf(SigCheck)); + for r := 0 to 7 do + begin + If SigCheck[r] <> Signature[r] then begin + result:= false; + exit; + end; +// raise PNGImageException.Create('This is not PNG-data'); + end; + // Check IHDR + ReadChunk; + move (chunk.data^, FHeader, sizeof(Header)); + with header do + begin + {$IFDEF ENDIAN_LITTLE} + Width := swap(width); + height := swap (height); + {$ENDIF} + result := (width > 0) and (height > 0) and (compression = 0) + and (filter = 0) and (Interlace in [0,1]); + end; + except + result := false; + end; +end; + +initialization + ImageHandlers.RegisterImageReader ('Portable Network Graphics', 'png', TFPReaderPNG); +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadpnm.pp b/mseide-msegui/lib/common/fpccompatibility/fpreadpnm.pp new file mode 100644 index 0000000..7e45f79 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadpnm.pp @@ -0,0 +1,350 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + PNM writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. +} +{*****************************************************************************} + +{ +The PNM (Portable aNyMaps) is a generic name for : + PBM : Portable BitMaps, + PGM : Portable GrayMaps, + PPM : Portable PixMaps. +There is normally no file format associated with PNM itself.} + +{$mode objfpc}{$h+} +unit FPReadPNM; + +interface + +uses FPImage, classes,mclasses, sysutils; + +type + TFPReaderPNM=class (TFPCustomImageReader) + private + FBitMapType : Integer; + FWidth : Integer; + FHeight : Integer; + protected + FMaxVal : Cardinal; + FBitPP : Byte; + FScanLineSize : Integer; + FScanLine : PByte; + procedure ReadHeader(Stream : TStream); + function InternalCheck (Stream:TStream):boolean;override; + procedure InternalRead(Stream:TStream;Img:TFPCustomImage);override; + procedure ReadScanLine(Row : Integer; Stream:TStream); + procedure WriteScanLine(Row : Integer; Img : TFPCustomImage); + end; + +implementation + +function TFPReaderPNM.InternalCheck(Stream:TStream):boolean; + +begin + InternalCheck:=True; +end; + +const + WhiteSpaces=[#9,#10,#13,#32]; {Whitespace (TABs, CRs, LFs, blanks) are separators in the PNM Headers} + +function DropWhiteSpaces(Stream : TStream) :Char; + +begin + result:= #0; + with Stream do + begin + repeat + ReadBuffer(DropWhiteSpaces,1); +{If we encounter comment then eate line} + if DropWhiteSpaces='#' then + repeat + ReadBuffer(DropWhiteSpaces,1); + until DropWhiteSpaces=#10; + until not(DropWhiteSpaces in WhiteSpaces); + end; +end; + +function ReadInteger(Stream : TStream) :Integer; + +var + s:String[7]; + +begin + s:=''; + s[1]:=DropWhiteSpaces(Stream); + with Stream do + repeat + Inc(s[0]); + ReadBuffer(s[Length(s)+1],1) + until (s[0]=#7) or (s[Length(s)+1] in WhiteSpaces); + Result:=StrToInt(s); +end; + +procedure TFPReaderPNM.ReadHeader(Stream : TStream); + +Var + C : Char; + +begin + Stream.ReadBuffer(C,1); + If (C<>'P') then + Raise Exception.Create('Not a valid PNM image.'); + Stream.ReadBuffer(C,1); + FBitmapType:=Ord(C)-Ord('0'); + If Not (FBitmapType in [1..6]) then + Raise Exception.CreateFmt('Unknown PNM subtype : %s',[C]); + FWidth:=ReadInteger(Stream); + FHeight:=ReadInteger(Stream); + if FBitMapType in [1,4] + then + FMaxVal:=1 + else + FMaxVal:=ReadInteger(Stream); + If (FWidth<=0) or (FHeight<=0) or (FMaxVal<=0) then + Raise Exception.Create('Invalid PNM header data'); + case FBitMapType of + 1: FBitPP := 1; // 1bit PP (text) + 2: FBitPP := 8 * SizeOf(Word); // Grayscale (text) + 3: FBitPP := 8 * SizeOf(Word)*3; // RGB (text) + 4: FBitPP := 1; // 1bit PP (raw) + 5: If (FMaxval>255) then // Grayscale (raw); + FBitPP:= 8 * 2 + else + FBitPP:= 8; + 6: if (FMaxVal>255) then // RGB (raw) + FBitPP:= 8 * 6 + else + FBitPP:= 8 * 3 + end; +// Writeln(FWidth,'x',Fheight,' Maxval: ',FMaxVal,' BitPP: ',FBitPP); +end; + +procedure TFPReaderPNM.InternalRead(Stream:TStream;Img:TFPCustomImage); + +var + Row:Integer; + +begin + ReadHeader(Stream); + Img.SetSize(FWidth,FHeight); + FScanLineSize:=FBitPP*((FWidth+7)shr 3); + GetMem(FScanLine,FScanLineSize); + try + for Row:=0 to img.Height-1 do + begin + ReadScanLine(Row,Stream); + WriteScanLine(Row,Img); + end; + finally + FreeMem(FScanLine); + end; +end; + +procedure TFPReaderPNM.ReadScanLine(Row : Integer; Stream:TStream); + +Var + P : PWord; + I,j,bitsLeft : Integer; + PB: PByte; + +begin + Case FBitmapType of + 1 : begin + PB:=FScanLine; + For I:=0 to ((FWidth+7)shr 3)-1 do + begin + PB^:=0; + bitsLeft := FWidth-(I shl 3)-1; + if bitsLeft > 7 then bitsLeft := 7; + for j:=0 to bitsLeft do + PB^:=PB^ or (ReadInteger(Stream) shl (7-j)); + Inc(PB); + end; + end; + 2 : begin + P:=PWord(FScanLine); + For I:=0 to FWidth-1 do + begin + P^:=ReadInteger(Stream); + Inc(P); + end; + end; + 3 : begin + P:=PWord(FScanLine); + For I:=0 to FWidth-1 do + begin + P^:=ReadInteger(Stream); // Red + Inc(P); + P^:=ReadInteger(Stream); // Green + Inc(P); + P^:=ReadInteger(Stream); // Blue; + Inc(P) + end; + end; + 4,5,6 : Stream.ReadBuffer(FScanLine^,FScanLineSize); + end; +end; + + +procedure TFPReaderPNM.WriteScanLine(Row : Integer; Img : TFPCustomImage); + +Var + C : TFPColor; + L : Cardinal; + Scale: Cardinal; + + function ScaleByte(B: Byte):Word; + begin + if FMaxVal = 255 then + Result := (B shl 8) or B { As used for reading .BMP files } + else { Mimic the above with multiplications } + Result := (B*(FMaxVal+1) + B) * 65535 div Scale; + end; + + function ScaleWord(W: Word):Word; + begin + if FMaxVal = 65535 then + Result := W + else { Mimic the above with multiplications } + Result := Int64(W*(FMaxVal+1) + W) * 65535 div Scale; + end; + + Procedure ByteBnWScanLine; + + Var + P : PByte; + I,j,x,bitsLeft : Integer; + + begin + P:=PByte(FScanLine); + For I:=0 to ((FWidth+7)shr 3)-1 do + begin + L:=P^; + x := I shl 3; + bitsLeft := FWidth-x-1; + if bitsLeft > 7 then bitsLeft := 7; + for j:=0 to bitsLeft do + begin + if L and $80 <> 0 then + Img.Colors[x,Row]:=colBlack + else + Img.Colors[x,Row]:=colWhite; + L:=L shl 1; + inc(x); + end; + Inc(P); + end; + end; + + Procedure WordGrayScanLine; + + Var + P : PWord; + I : Integer; + + begin + P:=PWord(FScanLine); + For I:=0 to FWidth-1 do + begin + L:=ScaleWord(P^); + C.Red:=L; + C.Green:=L; + C.Blue:=L; + Img.Colors[I,Row]:=C; + Inc(P); + end; + end; + + Procedure WordRGBScanLine; + + Var + P : PWord; + I : Integer; + + begin + P:=PWord(FScanLine); + For I:=0 to FWidth-1 do + begin + C.Red:=ScaleWord(P^); + Inc(P); + C.Green:=ScaleWord(P^); + Inc(P); + C.Blue:=ScaleWord(P^); + Img.Colors[I,Row]:=C; + Inc(P); + end; + end; + + Procedure ByteGrayScanLine; + + Var + P : PByte; + I : Integer; + + begin + P:=PByte(FScanLine); + For I:=0 to FWidth-1 do + begin + L:=ScaleByte(P^); + C.Red:=L; + C.Green:=L; + C.Blue:=L; + Img.Colors[I,Row]:=C; + Inc(P); + end; + end; + + Procedure ByteRGBScanLine; + + Var + P : PByte; + I : Integer; + + begin + P:=PByte(FScanLine); + For I:=0 to FWidth-1 do + begin + C.Red:=ScaleByte(P^); + Inc(P); + C.Green:=ScaleByte(P^); + Inc(P); + C.Blue:=ScaleByte(P^); + Img.Colors[I,Row]:=C; + Inc(P); + end; + end; + +begin + C.Alpha:=AlphaOpaque; + Scale := FMaxVal*(FMaxVal+1) + FMaxVal; + Case FBitmapType of + 1 : ByteBnWScanLine; + 2 : WordGrayScanline; + 3 : WordRGBScanline; + 4 : ByteBnWScanLine; + 5 : If FBitPP=8 then + ByteGrayScanLine + else + WordGrayScanLine; + 6 : If FBitPP=24 then + ByteRGBScanLine + else + WordRGBScanLine; + end; +end; + +initialization + + ImageHandlers.RegisterImageReader ('Netpbm format', 'PNM;PGM;PBM;PPM', TFPReaderPNM); + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadpsd.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadpsd.pas new file mode 100644 index 0000000..42a6e82 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadpsd.pas @@ -0,0 +1,612 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2008 by the Free Pascal development team + + Tiff reader for fpImage. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + ********************************************************************** + + ToDo: read further images +} +unit FPReadPSD; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FPimage; + +type + TRGB = packed record + Red, Green, Blue : Byte; + end; + + TLab = record + L, a, b: byte; + end; + + + TPSDHeader = packed record + Signature : array[0..3] of Char; // File IDs '8BPS' + Version : word; // Version number, always 1 + Reserved : array[0..5] of Byte; // Reserved, must be zeroed + Channels : Word; // Number of color channels (1-24) including alpha channels + Rows : Cardinal; // Height of image in pixels (1-30000) + Columns : Cardinal; // Width of image in pixels (1-30000) + Depth : Word; // Number of bits per channel (1, 8, and 16) + Mode: Word; // Color mode + end; + { + Mode Description + 0 Bitmap (monochrome) + 1 Gray-scale + 2 Indexed color (palette color) + 3 RGB color + 4 CMYK color + 7 Multichannel color + 8 Duotone (halftone) + 9 Lab color + } + + TColorModeDataBlock = packed record + Types : array[0..3] of Char; // Always "8BIM" + ID:word; // (See table below) + Name:byte; // Even-length Pascal-format string, 2 bytes or longer + Size : Cardinal; // Length of resource data following, in bytes + Data:byte; // Resource data, padded to even length + end; + { + ID Data Format Description + 03e8 WORD[5] Channels, rows, columns, depth, and mode + 03e9 Optional Macintosh print manager information + 03eb Indexed color table + 03ed (See below) Resolution information + "TResolutionInfo" + 03ee BYTE[] Alpha channel names (Pascal-format strings) + 03ef (See below) Display information for each channel + "TDisplayInfo" + 03f0 BYTE[] Optional Pascal-format caption string + 03f1 LONG, WORD Fixed-point border width, border units (see below) + 03f2 Background color + 03f3 BYTE[8] Print flags (see below) + 03f4 Gray-scale and halftoning information + 03f5 Color halftoning information + 03f6 Duotone halftoning information + 03f7 Gray-scale and multichannel transfer function + 03f8 Color transfer functions + 03f9 Duotone transfer functions + 03fa Duotone image information + 03fb BYTE[2] Effective black and white value for dot range + 03fc + 03fd EPS options + 03fe WORD, BYTE Quick Mask channel ID, flag for mask initially empty + 03ff + 0400 WORD Index of target layer (0=bottom) + 0401 Working path + 0402 WORD[] Layers group info, group ID for dragging groups + 0403 + 0404 IPTC-NAA record + 0405 Image mode for raw-format files + 0406 JPEG quality (Adobe internal) + 07d0 + 0bb6 Saved path information + 0bb7 Clipping pathname + 2710 (See below) Print flags information + } + TResolutionInfo = record + hRes:Cardinal; // Fixed-point number: pixels per inch + hResUnit:word; // 1=pixels per inch, 2=pixels per centimeter + WidthUnit:word; // 1=in, 2=cm, 3=pt, 4=picas, 5=columns + vRes:Cardinal; // Fixed-point number: pixels per inch + vResUnit:word; // 1=pixels per inch, 2=pixels per centimeter + HeightUnit:word; // 1=in, 2=cm, 3=pt, 4=picas, 5=columns + end; + + TDisplayInfo = record + ColorSpace:word; + Color:array[0..3] of word; + Opacity:word; // 0-100 + Kind:byte; // 0=selected, 1=protected + Padding:byte; // Always zero + end; + + TFPReaderPSD = class; + + TPSDCreateCompatibleImgEvent = procedure(Sender: TFPReaderPSD; + var NewImage: TFPCustomImage) of object; + + { TFPReaderPSD } + + TFPReaderPSD = class(TFPCustomImageReader) + private + FCompressed: boolean; + FOnCreateImage: TPSDCreateCompatibleImgEvent; + protected + FHeader : TPSDHeader; + FColorDataBlock: TColorModeDataBlock; + FBytesPerPixel : Byte; + FScanLine : PByte; + FLineSize : PtrInt; + FPalette : TFPPalette; + FWidth : integer; + FHeight : Integer; + FBlockCount : word; + FChannelCount : word; + FLengthOfLine : array of Word; + FByteRead : PtrInt; + procedure CreateGrayPalette; + procedure CreateBWPalette; + function ReadPalette(Stream: TStream): boolean; + procedure AnalyzeHeader; + procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override; + function ReadScanLine(Stream: TStream): boolean; virtual; + procedure WriteScanLine(Img: TFPCustomImage); virtual; + function InternalCheck(Stream: TStream) : boolean; override; + public + constructor Create; override; + property Compressed: Boolean read FCompressed; + property ThePalette: TFPPalette read FPalette; + property Width: integer read FWidth; + property Height: integer read FHeight; + property BytesPerPixel: Byte read FBytesPerPixel; + property BlockCount: word read FBlockCount; + property ChannelCount: word read FChannelCount; + property Header: TPSDHeader read FHeader; + property OnCreateImage: TPSDCreateCompatibleImgEvent read FOnCreateImage write FOnCreateImage; + end; + +implementation + +function CorrectCMYK(const C : TFPColor): TFPColor; +var + MinColor: word; +begin + if C.red$FFFF then MinColor:=$FFFF-C.alpha; + Result.red:=C.red-MinColor; + Result.green:=C.green-MinColor; + Result.blue:=C.blue-MinColor; + Result.alpha:=C.alpha+MinColor; +end; + +function CMYKtoRGB ( C : TFPColor): TFPColor; +begin + C:=CorrectCMYK(C); + if (C.red + C.Alpha)<$FFFF then + Result.Red:=$FFFF-(C.red+C.Alpha) else Result.Red:=0; + if (C.Green+C.Alpha)<$FFFF then + Result.Green:=$FFFF-(C.Green+C.Alpha) else Result.Green:=0; + if (C.blue+C.Alpha)<$FFFF then + Result.blue:=$FFFF-(C.blue+C.Alpha) else Result.blue:=0; + Result.alpha:=alphaOpaque; +end; + +function XYZToRGB(const X, Y, Z :double):TFPColor; +begin + // ToDo + Result:=colBlack; +end; + +function LabToRGB(const L:TLab):TFPColor; +begin + // ToDo + Result:=colBlack; +end; + +{ TFPReaderPSD } + +procedure TFPReaderPSD.CreateGrayPalette; +Var + I : Integer; + c : TFPColor; +Begin + ThePalette.count := 0; + For I:=0 To 255 Do + Begin + With c do + begin + Red:=I*255; + Green:=I*255; + Blue:=I*255; + Alpha:=alphaOpaque; + end; + ThePalette.Add (c); + End; +end; + +procedure TFPReaderPSD.CreateBWPalette; +begin + ThePalette.count := 0; + ThePalette.Add (colBlack); + ThePalette.Add (colWhite); +end; + +function TFPReaderPSD.ReadPalette(Stream: TStream): boolean; +Var + I : Integer; + c : TFPColor; + OldPos: Integer; + BufSize:Longint; + PalBuf: array[0..767] of Byte; + ContProgress: Boolean; +begin + Result:=false; + ThePalette.count := 0; + OldPos := Stream.Position; + BufSize:=0; + Stream.Read(BufSize, SizeOf(BufSize)); + BufSize:=BEtoN(BufSize); + Stream.Read(PalBuf, BufSize); + ContProgress:=true; + Progress(FPimage.psRunning, trunc(100.0 * (Stream.position / Stream.size)), + False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + For I:=0 To BufSize div 3 Do + Begin + With c do + begin + Red:=PalBuf[I] shl 8; + Green:=PalBuf[I+(BufSize div 3)] shl 8; + Blue:=PalBuf[I+(BufSize div 3)* 2] shl 8; + Alpha:=alphaOpaque; + end; + ThePalette.Add(C); + End; + Stream.Position := OldPos; + Result:=true; +end; + +procedure TFPReaderPSD.AnalyzeHeader; +begin + With FHeader do + begin + Depth:=BEtoN(Depth); + if (Signature <> '8BPS') then + Raise Exception.Create('Unknown/Unsupported PSD image type'); + Channels:=BEtoN(Channels); + if Channels > 4 then + FBytesPerPixel:=Depth*4 + else + FBytesPerPixel:=Depth*Channels; + Mode:=BEtoN(Mode); + FWidth:=BEtoN(Columns); + FHeight:=BEtoN(Rows); + FChannelCount:=Channels; + FLineSize:=PtrInt(FHeight)*FWidth*Depth div 8; + FLineSize:=FLineSize*Channels; + GetMem(FScanLine,FLineSize); + end; +end; + +procedure TFPReaderPSD.InternalRead(Stream: TStream; Img: TFPCustomImage); +var + H: Integer; + BufSize:Cardinal; + Encoding:word; + ContProgress: Boolean; +begin + FScanLine:=nil; + FPalette:=nil; + try + Stream.Position:=0; + ContProgress:=true; + Progress(FPimage.psStarting, 0, False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + // read header + Stream.Read(FHeader, SizeOf(FHeader)); + Progress(FPimage.psRunning, trunc(100.0 * (Stream.position / Stream.size)), False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + AnalyzeHeader; + Case FHeader.Mode of + 0:begin // Bitmap (monochrome) + FPalette := TFPPalette.Create(0); + CreateBWPalette; + end; + 1, 8:begin // Gray-scale + FPalette := TFPPalette.Create(0); + CreateGrayPalette; + end; + 2:begin // Indexed color (palette color) + FPalette := TFPPalette.Create(0); + if not ReadPalette(stream) then exit; + end; + end; + + if Assigned(OnCreateImage) then + OnCreateImage(Self,Img); + Img.SetSize(FWidth,FHeight); + + // color palette + BufSize:=0; + Stream.Read(BufSize, SizeOf(BufSize)); + BufSize:=BEtoN(BufSize); + Stream.Seek(BufSize, soCurrent); + // color data block + Stream.Read(BufSize, SizeOf(BufSize)); + BufSize:=BEtoN(BufSize); + Stream.Read(FColorDataBlock, SizeOf(FColorDataBlock)); + Stream.Seek(BufSize-SizeOf(FColorDataBlock), soCurrent); + // mask + Stream.Read(BufSize, SizeOf(BufSize)); + BufSize:=BEtoN(BufSize); + Stream.Seek(BufSize, soCurrent); + // compression type + Encoding:=0; + Stream.Read(Encoding, SizeOf(Encoding)); + FCompressed:=BEtoN(Encoding) = 1; + if BEtoN(Encoding)>1 then + Raise Exception.Create('Unknown compression type'); + If FCompressed then + begin + SetLength(FLengthOfLine, FHeight * FChannelCount); + Stream.ReadBuffer(FLengthOfLine[0], 2 * Length(FLengthOfLine)); + FByteRead:=0; + Progress(FPimage.psRunning, trunc(100.0 * (Stream.position / Stream.size)), False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + for H := 0 to High(FLengthOfLine) do + Inc(FByteRead, BEtoN(FLengthOfLine[H])); + if not FHeader.Mode in [ 0, 2] then + FByteRead := FByteRead * FHeader.Depth div 8; + end else + FByteRead:= FLineSize; + + ReadScanLine(Stream); + Progress(FPimage.psRunning, trunc(100.0 * (Stream.position / Stream.size)), False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + WriteScanLine(Img); + + {$ifdef FPC_Debug_Image} + WriteLn('TFPReaderPSD.InternalRead AAA1 ',Stream.position,' ',Stream.size); + {$endif} + finally + FreeAndNil(FPalette); + ReAllocMem(FScanLine,0); + end; + Progress(FPimage.psEnding, 100, false, Rect(0,0,FWidth,FHeight), '', ContProgress); +end; + +function TFPReaderPSD.ReadScanLine(Stream: TStream): boolean; +Var + P : PByte; + B : Byte; + I : PtrInt; + J : integer; + N : Shortint; + Count:integer; + ContProgress: Boolean; +begin + Result:=false; + ContProgress:=true; + If Not Compressed then + Stream.ReadBuffer(FScanLine^,FLineSize) + else + begin + P:=FScanLine; + i:=FByteRead; + repeat + Count:=0; + N:=0; + Stream.ReadBuffer(N,1); + Progress(FPimage.psRunning, trunc(100.0 * (Stream.position / Stream.size)), False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + dec(i); + If N = -128 then + else + if N < 0 then + begin + Count:=-N+1; + B:=0; + Stream.ReadBuffer(B,1); + dec(i); + For j := 0 to Count-1 do + begin + P[0]:=B; + inc(p); + end; + end + else + begin + Count:=N+1; + For j := 0 to Count-1 do + begin + Stream.ReadBuffer(B,1); + P[0]:=B; + inc(p); + dec(i); + end; + end; + until (i <= 0); + end; + Result:=true; +end; + +procedure TFPReaderPSD.WriteScanLine(Img: TFPCustomImage); +Var + Col : Integer; + C : TFPColor; + P, P1, P2, P3 : PByte; + Z2 : Longint; + Row : Integer; + Lab : TLab; +begin + C.Alpha:=AlphaOpaque; + P:=FScanLine; + Z2:=FHeader.Depth div 8; + Z2:=Z2 *FHeight*FWidth; + begin + case FBytesPerPixel of + 1 : begin + for Row:=0 to Img.Height-1 do + begin + for Col:=0 to Img.Width-1 do + if (P[col div 8] and (128 shr (col mod 8))) <> 0 then + Img.Colors[Col,Row]:=ThePalette[0] + else + Img.Colors[Col,Row]:=ThePalette[1]; + inc(P, Img.Width div 8); + end; + end; + 8 : begin + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + Img.Colors[Col,Row]:=ThePalette[P[0]]; + inc(p); + end; + end; + 16 : begin + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + Img.Colors[Col,Row]:=ThePalette[BEtoN(PWord(P)^)]; + inc(p,2); + end; + end; + 24 :begin + P1:=P; + inc(P1,Z2); + P2:=P; + inc(P2,Z2*2); + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + if (FHeader.Mode =9) then + begin + Lab.L:=(P[0]); + Lab.a:=(P1[0]); + Lab.b:=(P2[0]); + C:=LabToRGB(Lab); + end + else + With C do + begin + Red:=P[0] or (P[0] shl 8); + green:=P1[0] or (P1[0] shl 8); + blue:=P2[0] or (P2[0] shl 8); + alpha:=alphaOpaque; + end; + Inc(P); + Inc(P1); + Inc(P2); +// if (Header.Mode =9) then C:=XYZtoRGB(C); // Lab color + Img[col, row] := C; + end; + end; + 32 :begin + P1:=P; + inc(P1,Z2); + P2:=P; + inc(P2,Z2*2); + P3:=P; + inc(P3,Z2*3); + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + if (FHeader.Mode =4) then + begin + P^ := 255 - P^; + P1^ := 255 - P1^; + P2^ := 255 - P2^; + P3^ := 255 - P3^; + end; + C.Red:=P[0] or (P[0] shl 8); + C.green:=P1[0] or (P1[0] shl 8); + C.blue:=P2[0] or (P2[0] shl 8); + C.alpha:=P3[0] or (P3[0] shl 8); + if (FHeader.Mode =4) then C:=CMYKtoRGB(C); // CMYK to RGB + Img[col, row] := C; + Inc(P); + Inc(P1); + Inc(P2); + Inc(P3); + end; + end; + 48 :begin + P1:=P; + inc(P1,Z2); + P2:=P; + inc(P2,Z2*2); + C.alpha:=alphaOpaque; + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + With C do + begin + Red:=BEtoN(PWord(P)^); + green:=BEtoN(PWord(P1)^); + blue:=BEtoN(PWord(P2)^); + end; + Inc(P,2); + Inc(P1,2); + Inc(P2,2); + Img[col, row] := C; + end; + end; + 64 :begin + P1:=P; + inc(P1,Z2); + P2:=P; + inc(P2,Z2*2); + P3:=P; + inc(P3,Z2*3); + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + C.Red:=BEtoN(PWord(P)^); + C.green:=BEtoN(PWord(P1)^); + C.blue:=BEtoN(PWord(P2)^); + C.alpha:=BEtoN(PWord(P3)^); + if (FHeader.Mode =4) then + begin + C.red:=$ffff-C.red; + C.green:=$ffff-C.green; + C.blue:=$ffff-C.blue; + C.alpha:=$ffff-C.alpha; + end; + if (FHeader.Mode =4) then C:=CMYKtoRGB(C); // CMYK to RGB + Img[col, row] := C; + Inc(P,2); + Inc(P1,2); + Inc(P2,2); + Inc(P3,2); + end; + end; + end; + end; +end; + +function TFPReaderPSD.InternalCheck(Stream: TStream): boolean; +var + OldPos: Int64; +begin + try + OldPos:=Stream.Position; + Stream.Read(FHeader,SizeOf(FHeader)); + Result:=(FHeader.Signature = '8BPS'); + Stream.Position:=OldPos; + except + Result:=False; + end; +end; + +constructor TFPReaderPSD.Create; +begin + inherited Create; +end; + +initialization + ImageHandlers.RegisterImageReader ('PSD Format', 'PSD', TFPReaderPSD); + ImageHandlers.RegisterImageReader ('PDD Format', 'PDD', TFPReaderPSD); + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadtga.pp b/mseide-msegui/lib/common/fpccompatibility/fpreadtga.pp new file mode 100644 index 0000000..18855a1 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadtga.pp @@ -0,0 +1,345 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + BMP writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. +} +{*****************************************************************************} + +{ - 22/11/2007 Modified by Laurent Jacques for support all format } + +{$mode objfpc} +{$h+} + +unit FPReadTGA; + +interface + +uses FPImage, classes,mclasses, sysutils, targacmn; + +const + TARGA_EMPTY_IMAGE = 0; + TARGA_INDEXED_IMAGE = 1; + TARGA_TRUECOLOR_IMAGE = 2; + TARGA_GRAY_IMAGE = 3; + +type + + { TFPReaderTarga } + + TFPReaderTarga = class (TFPCustomImageReader) + Private + Procedure FreeBuffers; // Free (and nil) buffers. + protected + Header : TTargaHeader; + AlphaBits : Byte; + Identification : ShortString; + Compressed, + BottomUp : Boolean; + BytesPerPixel : Byte; + FPalette : PFPColor; + FScanLine : PByte; + FLineSize : Integer; + FPaletteSize : Integer; + FBlockCount : Integer; + FPixelCount : Integer; + FLastPixel : Packed Array[0..3] of byte; + // AnalyzeHeader will allocate the needed buffers. + Procedure AnalyzeHeader(Img : TFPCustomImage); + procedure CreateGrayPalette; + Procedure ReadPalette(Stream : TStream); + procedure ReadScanLine(Row : Integer; Stream : TStream); virtual; + procedure WriteScanLine(Row : Integer; Img : TFPCustomImage); virtual; + // required by TFPCustomImageReader + procedure InternalRead (Stream:TStream; Img:TFPCustomImage); override; + function InternalCheck (Stream:TStream) : boolean; override; + public + constructor Create; override; + destructor Destroy; override; + end; + +Implementation + +Constructor TFPReaderTarga.Create; + +begin +end; + +Destructor TFPReaderTarga.Destroy; + +begin + FreeBuffers; + Inherited; +end; + +Procedure TFPReaderTarga.FreeBuffers; + +begin + If (FScanLine<>Nil) then + begin + FreeMem(FScanLine); + FScanLine:=Nil; + end; + If (FPalette<>Nil) then + begin + FreeMem(FPalette); + FScanLine:=Nil; + end; +end; + +Procedure TFPReaderTarga.AnalyzeHeader(Img : TFPCustomImage); + +begin + With Header do + begin + if not (ImgType in [1, 2, 3, 9, 10, 11]) and + not (PixelSize in [8, 16, 24, 32]) then + Raise Exception.Create('Unknown/Unsupported Targa image type'); + BottomUp:=(Flags and $20) <>0; + AlphaBits := Flags and $0F; + BytesPerPixel:=PixelSize; + Compressed:=ImgType>8; + If Compressed then + ImgType:=ImgType-8; + FLineSize:=(BytesPerPixel div 8)*ToWord(Width); + GetMem(FScanLine,FLineSize); + + if ImgType = TARGA_GRAY_IMAGE then + FPaletteSize:=SizeOf(TFPColor)*255 + else + FPaletteSize:=SizeOf(TFPColor)*ToWord(MapLength); + GetMem(FPalette,FPaletteSize); + Img.Width:=ToWord(Width); + Img.Height:=ToWord(Height); + end; +end; + +Procedure TFPReaderTarga.CreateGrayPalette; + +Var + I : Integer; + +Begin + For I:=0 To 255 Do + Begin + With FPalette[I] do + begin + Red:=I*255; + Green:=I*255; + Blue:=I*255; + Alpha:=AlphaOpaque; + end; + end; +End; + +Procedure TFPReaderTarga.ReadPalette(Stream : TStream); + +Var + BGREntry : TBGREntry; + BGRAEntry : TBGRAEntry; + I : Integer; + +begin + Case Header.MapEntrySize Of + 16, 24: + For I:=0 to ToWord(Header.MapLength)-1 do + begin + Stream.ReadBuffer(BGREntry, SizeOf(BGREntry)); + With FPalette[I] do + begin + Red:=BGREntry.Red shl 8; + Green:=BGREntry.Green shl 8; + Blue:=BGREntry.Blue shl 8; + Alpha:=alphaOpaque; + end; + end; + 32: + For I:=0 to ToWord(Header.MapLength)-1 do + begin + Stream.ReadBuffer(BGRAEntry,SizeOf(BGRAEntry)); + With FPalette[I] do + begin + Red:=BGRAEntry.Red shl 8; + Green:=BGRAEntry.Green shl 8; + Blue:=BGRAEntry.Blue shl 8; + if alphaBits = 8 then + if (BGRAEntry.Alpha and $80) <> 0 then + Alpha:=alphaTransparent + else + Alpha:=AlphaOpaque; + end; + end; + end; +end; + + +Procedure TFPReaderTarga.InternalRead (Stream:TStream; Img:TFPCustomImage); + +var + H,Row : Integer; + +begin + Stream.Read(Header,SizeOf(Header)); + AnalyzeHeader(Img); + If Header.IdLen>0 then + begin + SetLength(Identification,Header.IDLen); + Stream.Read(Identification[1],Header.Idlen); + If Length(Identification)<>0 then + Img.Extra[KeyIdentification]:=Identification; + end; + + If Header.MapType<>0 then + ReadPalette(Stream); + if Header.ImgType = TARGA_GRAY_IMAGE then + CreateGrayPalette; + + H:=Img.height; + If BottomUp then + For Row:=0 to H-1 do + begin + ReadScanLine(Row,Stream); + WriteScanLine(Row,Img); + end + else + For Row:=H-1 downto 0 do + begin + ReadScanLine(Row,Stream); + WriteScanLine(Row,Img); + end; +end; + +Procedure TFPReaderTarga.ReadScanLine(Row : Integer; Stream : TStream); + +Var + P : PByte; + B : Byte; + I,J : Integer; + +begin + If Not Compressed then + Stream.ReadBuffer(FScanLine^,FLineSize) + else + begin + P:=FScanLine; + For I:=0 to ToWord(Header.Width)-1 do + begin + If (FPixelCount>0) then + Dec(FPixelCount) + else + begin + Dec(FBlockCount); + If (FBlockCount<0) then + begin + Stream.ReadBuffer(B,1); + If (B and $80)<>0 then + begin + FPixelCount:=B and $7F; + FblockCount:=0; + end + else + FBlockCount:=B and $7F + end; + Stream.ReadBuffer(FlastPixel,BytesPerPixel shr 3); + end; + For J:=0 to (BytesPerPixel shr 3)-1 do + begin + P[0]:=FLastPixel[j]; + Inc(P); + end; + end; + end; +end; + +Procedure TFPReaderTarga.WriteScanLine(Row : Integer; Img : TFPCustomImage); + +Var + Col : Integer; + C : TFPColor; + W : Word; + P : PByte; + +begin + C.Alpha:=AlphaOpaque; + P:=FScanLine; + Case Header.ImgType of + TARGA_INDEXED_IMAGE + : for Col:=0 to Img.width-1 do + Img.Colors[Col,Row]:=FPalette[P[Col]]; + TARGA_TRUECOLOR_IMAGE + : for Col:=0 to Img.Width-1 do + begin + // Fill C depending on number of pixels. + case BytesPerPixel of + 8,16 : begin + W:=P[0]; + inc(P); + W:=W or (P[0] shl 8); + With C do + begin + Red:=((W)shr 10) shl 11; + Green:=((w)shr 5) shl 11; + Blue:=((w)) shl 11; + end; + end; + 24,32 : With C do + begin + Blue:=P[0] or (P[0] shl 8); + Inc(P); + Green:=P[0] or (P[0] shl 8); + Inc(P); + Red:=P[0] or (P[0] shl 8); + If bytesPerPixel=32 then + begin + Inc(P); + Alpha:=AlphaOpaque; + if alphaBits = 8 then + if (P[0] and $80) = 0 then + Alpha:=alphaTransparent; + end; + end; + end; // Case BytesPerPixel; + Img[Col,Row]:=C; + Inc(P); + end; + TARGA_GRAY_IMAGE + : case BytesPerPixel of + 8 : for Col:=0 to Img.width-1 do + Img.Colors[Col,Row]:=FPalette[P[Col]]; + 16 : for Col:=0 to Img.width-1 do + begin + With C do + begin + Blue:=FPalette[P^].blue; + Green:=FPalette[P^].green; + Red:=FPalette[P^].red; + Inc(P); + Alpha:=AlphaOpaque; + if alphaBits = 8 then + if (P[0] and $80) = 0 then + Alpha:=alphaTransparent; + Inc(P); + end; + Img[Col,Row]:=C; + end; + end; + end; +end; + +function TFPReaderTarga.InternalCheck (Stream:TStream) : boolean; + +begin + Result:=True; +end; + +initialization + ImageHandlers.RegisterImageReader ('TARGA Format', 'tga', TFPReaderTarga); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadtiff.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadtiff.pas new file mode 100644 index 0000000..c0980c8 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadtiff.pas @@ -0,0 +1,2400 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2012 by the Free Pascal development team + + Tiff reader for fpImage. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + ********************************************************************** + + Working: + Grayscale 8,16bit (optional alpha), + RGB 8,16bit (optional alpha), + Orientation, + skipping Thumbnail to read first image, + compression: packbits, LZW, deflate + endian + multiple images + strips and tiles + + ToDo: + Compression: jpeg, ... + PlanarConfiguration 2 + ColorMap + separate mask + fillorder - not needed by baseline tiff reader + bigtiff 64bit offsets + XMP tag 700 + ICC profile tag 34675 + orientation with rotation +} +//modified 2013 by Martin Schreiber + +unit fpreadtiff; +{$ifdef FPC}{$mode objfpc}{$H+}{$inline on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + math, classes, mclasses, sysutils, msectypes, + {$ifdef FPC}zinflate,zbase,{$else}zinflate_del,zbase_del,classes_del,{$endif} + msetypes, fpimage, fptiffcmn; + +type + TFPReaderTiff = class; + + TTiffCreateCompatibleImgEvent = procedure(Sender: TFPReaderTiff; + ImgFileDir: TTiffIFD) of object; + + TTiffCheckIFDOrder = ( + tcioSmart, + tcioAlways, + tcioNever + ); + + { TFPReaderTiff } + + TFPReaderTiff = class(TFPCustomImageReader) + private + FCheckIFDOrder: TTiffCheckIFDOrder; + FFirstIFDStart: DWord; + FOnCreateImage: TTiffCreateCompatibleImgEvent; + FReverserEndian: boolean; + IFD: TTiffIFD; + {$ifdef FPC_Debug_Image} + FDebug: boolean; + {$endif} + fIFDStarts: TFPList; + FReverseEndian: Boolean; + fStartPos: int64; + s: TStream; + function GetImages(Index: integer): TTiffIFD; + procedure TiffError(Msg: string); + procedure SetStreamPos(p: DWord); + function ReadTiffHeader(QuickTest: boolean; out IFDStart: DWord): boolean; // returns IFD: offset to first IFD + function ReadIFD(Start: DWord): DWord;// Image File Directory + procedure ReadDirectoryEntry(var EntryTag: Word); + function ReadEntryUnsigned: DWord; + function ReadEntrySigned: Cint32; + function ReadEntryRational: TTiffRational; + function ReadEntryString: string; + function ReadByte: Byte; + function ReadWord: Word; + function ReadDWord: DWord; + procedure ReadValues(StreamPos: DWord; + out EntryType: word; out EntryCount: DWord; + out Buffer: Pointer; out ByteCount: PtrUInt); + procedure ReadShortOrLongValues(StreamPos: DWord; + out Buffer: PDWord; out Count: DWord); + procedure ReadShortValues(StreamPos: DWord; + out Buffer: PWord; out Count: DWord); + procedure ReadImageProperties( + out RedBits, GreenBits, BlueBits, GrayBits, AlphaBits: Word; + out ExtraSamples: PWord; out ExtraSampleCnt: DWord; + out SampleBits: PWord; out SampleBitsPerPixel: DWord); + procedure ReadImgValue(BitCount: Word; var Run: Pointer; x: dword; + Predictor: word; var LastValue: word; out Value: Word); + {$ifdef FPC}inline;{$endif} + function FixEndian(w: Word): Word; {$ifdef FPC}inline;{$endif} overload; + function FixEndian(d: DWord): DWord; {$ifdef FPC}inline;{$endif} overload; + procedure SetFPImgExtras(CurImg: TFPCustomImage); + procedure DecodePackBits(var Buffer: Pointer; var Count: PtrInt); + procedure DecodeLZW(var Buffer: Pointer; var Count: PtrInt); + procedure DecodeDeflate(var Buffer: Pointer; var Count: PtrInt; ExpectedCount: PtrInt); + protected + procedure InternalRead(Str: TStream; AnImage: TFPCustomImage); override; + function InternalCheck(Str: TStream): boolean; override; + procedure DoCreateImage(ImgFileDir: TTiffIFD); virtual; + public + ImageList: TFPList; // list of TTiffIFD + constructor Create; override; + destructor Destroy; override; + procedure Clear; + procedure LoadFromStream(aStream: TStream; AutoClear: boolean = true); + procedure LoadHeaderFromStream(aStream: TStream); + procedure LoadIFDsFromStream; // requires LoadHeaderFromStream, creates Images + procedure LoadImageFromStream(Index: integer); // requires LoadIFDsFromStream + {$ifdef FPC_Debug_Image} + property Debug: boolean read FDebug write FDebug; + {$endif} + property StartPos: int64 read fStartPos; + property ReverserEndian: boolean read FReverserEndian; + property TheStream: TStream read s; + property OnCreateImage: TTiffCreateCompatibleImgEvent read FOnCreateImage + write FOnCreateImage; + property CheckIFDOrder: TTiffCheckIFDOrder read FCheckIFDOrder write FCheckIFDOrder; + function FirstImg: TTiffIFD; + function GetBiggestImage: TTiffIFD; + function ImageCount: integer; + property Images[Index: integer]: TTiffIFD read GetImages; default; + property FirstIFDStart: DWord read FFirstIFDStart; + end; + +procedure DecompressPackBits(Buffer: Pointer; Count: PtrInt; + out NewBuffer: Pointer; out NewCount: PtrInt); +procedure DecompressLZW(Buffer: Pointer; Count: PtrInt; + out NewBuffer: PByte; out NewCount: PtrInt); +function DecompressDeflate(Compressed: PByte; CompressedCount: cardinal; + out Decompressed: PByte; var DecompressedCount: cardinal; + ErrorMsg: PAnsiString = nil): boolean; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function CMYKToFPColor(C,M,Y,K: Word): TFPColor; +var R, G, B : LongWord; +begin + R := $ffff - ((LongWord(C)*($ffff-LongWord(K))) shr 16) - LongWord(K) ; + G := $ffff - ((LongWord(M)*($ffff-LongWord(K))) shr 16) - LongWord(K) ; + B := $ffff - ((LongWord(Y)*($ffff-LongWord(K))) shr 16) - LongWord(K) ; + Result := FPColor(R and $ffff,G and $ffff,B and $ffff); +end ; + +procedure TFPReaderTiff.TiffError(Msg: string); +begin + Msg:=Msg+' at position '+IntToStr(s.Position); + if fStartPos>0 then + Msg:=Msg+' (TiffPosition='+IntToStr(fStartPos)+')'; + raise Exception.Create(Msg); +end; + +function TFPReaderTiff.GetImages(Index: integer): TTiffIFD; +begin + Result:=TTiffIFD(ImageList[Index]); +end; + +type + worda4ty = array[0..3] of word; + pworda4ty = ^worda4ty; +{$warnings off} +procedure TFPReaderTiff.ReadImageProperties(out RedBits, GreenBits, BlueBits, + GrayBits, AlphaBits: Word; out ExtraSamples: PWord; out + ExtraSampleCnt: DWord; out SampleBits: PWord; out SampleBitsPerPixel: DWord); +var + BytesPerPixel: Word; + SampleCnt: DWord; + i: Integer; +begin + ReadShortValues(IFD.BitsPerSample, SampleBits, SampleCnt); + if SampleCnt<>IFD.SamplesPerPixel then + TiffError('Samples='+IntToStr(SampleCnt)+' <> SamplesPerPixel='+IntToStr(IFD + .SamplesPerPixel)); + if IFD.ExtraSamples>0 then + ReadShortValues(IFD.ExtraSamples, ExtraSamples, ExtraSampleCnt); + if ExtraSampleCnt>=SampleCnt then + TiffError('Samples='+IntToStr(SampleCnt)+' ExtraSampleCnt='+IntToStr( + ExtraSampleCnt)); + case IFD.PhotoMetricInterpretation of + 0, 1: if SampleCnt-ExtraSampleCnt<>1 then + TiffError('gray images expect one sample per pixel, but found '+IntToStr( + SampleCnt)); + 2: if SampleCnt-ExtraSampleCnt<>3 then + TiffError('rgb images expect three samples per pixel, but found '+IntToStr( + SampleCnt)); + 3: if SampleCnt-ExtraSampleCnt<>1 then + TiffError('palette images expect one sample per pixel, but found '+IntToStr( + SampleCnt)); + 4: if SampleCnt-ExtraSampleCnt<>1 then + TiffError('mask images expect one sample per pixel, but found '+IntToStr( + SampleCnt)); + 5: if SampleCnt-ExtraSampleCnt<>4 then + TiffError('cmyk images expect four samples per pixel, but found '+IntToStr( + SampleCnt)); + end; + + GrayBits:=0; + RedBits:=0; + GreenBits:=0; + BlueBits:=0; + AlphaBits:=0; + BytesPerPixel:=0; + SampleBitsPerPixel:=0; + for i:=0 to SampleCnt-1 do begin + if pwordaty(SampleBits)^[i]>64 then + TiffError('Samples bigger than 64 bit not supported'); + if not (pwordaty(SampleBits)^[i] in [8, 16]) then + TiffError('Only samples of 8 and 16 bit are supported'); + inc(SampleBitsPerPixel, pwordaty(SampleBits)^[i]); + end; + case IFD.PhotoMetricInterpretation of + 0, 1: + begin + GrayBits:=pwordaty(SampleBits)^[0]; + IFD.GrayBits:=GrayBits; + for i:=0 to ExtraSampleCnt-1 do begin + if pwordaty(ExtraSamples)^[i] in [1, 2] then begin + AlphaBits:= pwordaty(SampleBits)^[1+i]; + IFD.AlphaBits:=AlphaBits; + end; + end; + if not (GrayBits in [8, 16]) then + TiffError('gray image only supported with gray BitsPerSample 8 or 16'); + if not (AlphaBits in [0, 8, 16]) then + TiffError('gray image only supported with alpha BitsPerSample 8 or 16'); + end; + 2: + begin + RedBits:= pworda4ty(SampleBits)^[0]; + GreenBits:= pworda4ty(SampleBits)^[1]; + BlueBits:= pworda4ty(SampleBits)^[2]; + IFD.RedBits:=RedBits; + IFD.GreenBits:=GreenBits; + IFD.BlueBits:=BlueBits; + IFD.AlphaBits:=0; + for i:=0 to ExtraSampleCnt-1 do begin + //writeln(' ',i,'/',ExtraSampleCnt,' Type=',ExtraSamples[i],' Count=',SampleBits[3+i]); + if pwordaty(ExtraSamples)^[i] in [1, 2] then begin + AlphaBits:= pwordaty(SampleBits)^[3+i]; + IFD.AlphaBits:=AlphaBits; + end; + end; + if not (RedBits in [8, 16]) then + TiffError('RGB image only supported with red BitsPerSample 8 or 16'); + if not (GreenBits in [8, 16]) then + TiffError('RGB image only supported with green BitsPerSample 8 or 16'); + if not (BlueBits in [8, 16]) then + TiffError('RGB image only supported with blue BitsPerSample 8 or 16'); + if not (AlphaBits in [0, 8, 16]) then + TiffError('RGB image only supported with alpha BitsPerSample 8 or 16'); + end; + 5: + begin + RedBits:= pworda4ty(SampleBits)^[0]; + GreenBits:= pworda4ty(SampleBits)^[1]; + BlueBits:= pworda4ty(SampleBits)^[2]; + GrayBits:= pworda4ty(SampleBits)^[3]; + IFD.RedBits:=RedBits; + IFD.GreenBits:=GreenBits; + IFD.BlueBits:=BlueBits; + IFD.GrayBits:=GrayBits; + IFD.AlphaBits:=0; + for i:=0 to ExtraSampleCnt-1 do begin + if pwordaty(ExtraSamples)^[i] in [1, 2] then begin + AlphaBits:= pwordaty(SampleBits)^[4+i]; + IFD.AlphaBits:=AlphaBits; + end; + end; + if not (RedBits in [8, 16]) then + TiffError('CMYK image only supported with cyan BitsPerSample 8 or 16'); + if not (GreenBits in [8, 16]) then + TiffError('CMYK image only supported with magenta BitsPerSample 8 or 16' + ); + if not (BlueBits in [8, 16]) then + TiffError('CMYK image only supported with yellow BitsPerSample 8 or 16' + ); + if not (GrayBits in [8, 16]) then + TiffError('CMYK image only supported with black BitsPerSample 8 or 16'); + if not (AlphaBits in [0, 8, 16]) then + TiffError('CMYK image only supported with alpha BitsPerSample 8 or 16'); + end; + end; + BytesPerPixel:=(GrayBits+RedBits+GreenBits+BlueBits+AlphaBits) div 8; + IFD.BytesPerPixel:=BytesPerPixel; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('BytesPerPixel=', BytesPerPixel); + {$endif} + + if not (IFD.FillOrder in [0, 1]) then + TiffError('FillOrder unsupported: '+IntToStr(IFD.FillOrder)); +end; +{$warnings on} + +procedure TFPReaderTiff.SetFPImgExtras(CurImg: TFPCustomImage); +begin + ClearTiffExtras(CurImg); + // set Tiff extra attributes + CurImg.Extra[TiffPhotoMetric]:=IntToStr(IFD.PhotoMetricInterpretation); + //writeln('TFPReaderTiff.SetFPImgExtras PhotoMetric=',CurImg.Extra[TiffPhotoMetric]); + if IFD.Artist<>'' then + CurImg.Extra[TiffArtist]:=IFD.Artist; + if IFD.Copyright<>'' then + CurImg.Extra[TiffCopyright]:=IFD.Copyright; + if IFD.DocumentName<>'' then + CurImg.Extra[TiffDocumentName]:=IFD.DocumentName; + if IFD.DateAndTime<>'' then + CurImg.Extra[TiffDateTime]:=IFD.DateAndTime; + if IFD.HostComputer<>'' then + CurImg.Extra[TiffHostComputer]:=IFD.HostComputer; + if IFD.ImageDescription<>'' then + CurImg.Extra[TiffImageDescription]:=IFD.ImageDescription; + if IFD.Make_ScannerManufacturer<>'' then + CurImg.Extra[TiffMake_ScannerManufacturer]:=IFD.Make_ScannerManufacturer; + if IFD.Model_Scanner<>'' then + CurImg.Extra[TiffModel_Scanner]:=IFD.Model_Scanner; + if IFD.Software<>'' then + CurImg.Extra[TiffSoftware]:=IFD.Software; + if not (IFD.Orientation in [1..8]) then + IFD.Orientation:=1; + CurImg.Extra[TiffOrientation]:=IntToStr(IFD.Orientation); + if IFD.ResolutionUnit<>0 then + CurImg.Extra[TiffResolutionUnit]:=IntToStr(IFD.ResolutionUnit); + if (IFD.XResolution.Numerator<>0) or (IFD.XResolution.Denominator<>0) then + CurImg.Extra[TiffXResolution]:=TiffRationalToStr(IFD.XResolution); + if (IFD.YResolution.Numerator<>0) or (IFD.YResolution.Denominator<>0) then + CurImg.Extra[TiffYResolution]:=TiffRationalToStr(IFD.YResolution); + CurImg.Extra[TiffRedBits]:=IntToStr(IFD.RedBits); + CurImg.Extra[TiffGreenBits]:=IntToStr(IFD.GreenBits); + CurImg.Extra[TiffBlueBits]:=IntToStr(IFD.BlueBits); + CurImg.Extra[TiffGrayBits]:=IntToStr(IFD.GrayBits); + CurImg.Extra[TiffAlphaBits]:=IntToStr(IFD.AlphaBits); + if IFD.PageCount>0 then begin + CurImg.Extra[TiffPageNumber]:=IntToStr(IFD.PageNumber); + CurImg.Extra[TiffPageCount]:=IntToStr(IFD.PageCount); + end; + if IFD.PageName<>'' then + CurImg.Extra[TiffPageName]:=IFD.PageName; + if IFD.ImageIsThumbNail then + CurImg.Extra[TiffIsThumbnail]:='1'; + if IFD.ImageIsMask then + CurImg.Extra[TiffIsMask]:='1'; + if IFD.Compression<>TiffCompressionNone then + CurImg.Extra[TiffCompression]:=IntToStr(IFD.Compression); + + {$ifdef FPC_Debug_Image} + if Debug then + WriteTiffExtras('SetFPImgExtras', CurImg); + {$endif} +end; + +procedure TFPReaderTiff.ReadImgValue(BitCount: Word; var Run: Pointer; x: dword; + Predictor: word; var LastValue: word; out Value: Word); + {$ifdef FPC}inline;{$endif} +begin + if BitCount=8 then begin + Value:=PCUInt8(Run)^; + if Predictor=2 then begin + // horizontal difference + if x>0 then + Value:=(Value+LastValue) and $ff; + LastValue:=Value; + end; + Value:=Value shl 8+Value; + inc(pchar(Run)); + end else if BitCount=16 then begin + Value:=FixEndian(PCUInt16(Run)^); + if Predictor=2 then begin + // horizontal difference + if x>0 then + Value:=(Value+LastValue) and $ffff; + LastValue:=Value; + end; + inc(pchar(Run),2); + end; +end; + +procedure TFPReaderTiff.SetStreamPos(p: DWord); +var + NewPosition: int64; +begin + NewPosition:=Int64(p)+fStartPos; + if NewPosition>s.Size then + TiffError('Offset outside of stream'); + s.Position:=NewPosition; +end; + +procedure TFPReaderTiff.LoadFromStream(aStream: TStream; AutoClear: boolean); +var + IFDStart: DWord; + i: Integer; + aContinue: Boolean; +begin + if AutoClear then + Clear; + aContinue:=true; + Progress(psStarting, 0, False, Rect(0,0,0,0), '', aContinue); + if not aContinue then exit; + LoadHeaderFromStream(aStream); + try + IFDStart:=FirstIFDStart; + i:=0; + while IFDStart>0 do begin + if i=ImageCount then + ImageList.Add(TTiffIFD.Create); + IFD:=Images[i]; + IFDStart:=ReadIFD(IFDStart); + LoadImageFromStream(i); + inc(i); + end; + finally + IFD:=nil; + end; + Progress(psEnding, 100, False, Rect(0,0,0,0), '', aContinue); +end; + +procedure TFPReaderTiff.LoadHeaderFromStream(aStream: TStream); +begin + FFirstIFDStart:=0; + s:=aStream; + fStartPos:=s.Position; + ReadTiffHeader(false,FFirstIFDStart); +end; + +procedure TFPReaderTiff.LoadIFDsFromStream; +var + i: Integer; + IFDStart: DWord; +begin + try + IFDStart:=FirstIFDStart; + i:=0; + while IFDStart>0 do begin + if ImageCount=i then + ImageList.Add(TTiffIFD.Create); + IFD:=Images[i]; + IFDStart:=ReadIFD(IFDStart); + inc(i); + end; + finally + IFD:=nil; + end; +end; + +function TFPReaderTiff.FirstImg: TTiffIFD; +begin + Result:=nil; + if (ImageList=nil) or (ImageList.Count=0) then exit; + Result:=TTiffIFD(ImageList[0]); +end; + +function TFPReaderTiff.GetBiggestImage: TTiffIFD; +var + Size: Int64; + Img: TTiffIFD; + CurSize: int64; + i: Integer; +begin + Result:=nil; + Size:=0; + for i:=0 to ImageCount-1 do begin + Img:=Images[i]; + CurSize:=Int64(Img.ImageWidth)*Img.ImageHeight; + if CurSize2 then begin + {$ifdef FPC_Debug_Image} + if Debug then begin + write('TFPReaderTiff.ReadDirectoryEntry Tag 297: PageNumber/Count: '); + for i:=0 to Count-1 do + write(IntToStr(WordBuffer[i]),' '); + writeln; + end; + {$endif} + TiffError('PageNumber Count=2 expected, but found '+IntToStr(Count)); + end; + IFD.PageNumber:= pworda4ty(WordBuffer)^[0]; + IFD.PageCount:= pworda4ty(WordBuffer)^[1]; + if IFD.PageNumber>=IFD.PageCount then begin + // broken order => repair + UValue:=IFD.PageNumber; + IFD.PageNumber:=IFD.PageCount; + IFD.PageCount:=UValue; + end; + finally + ReAllocMem(WordBuffer,0); + end; + {$ifdef FPC_Debug_Image} + if Debug then begin + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 297: PageNumber=',IFD.PageNumber,'/',IFD.PageCount); + end; + {$endif} + end; + 305: + begin + // Software + IFD.Software:=ReadEntryString; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 305: Software="',IFD.Software,'"'); + {$endif} + end; + 306: + begin + // DateAndTime + IFD.DateAndTime:=ReadEntryString; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 306: DateAndTime="',IFD.DateAndTime,'"'); + {$endif} + end; + 315: + begin + // Artist + IFD.Artist:=ReadEntryString; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 315: Artist="',IFD.Artist,'"'); + {$endif} + end; + 316: + begin + // HostComputer + IFD.HostComputer:=ReadEntryString; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 316: HostComputer="',IFD.HostComputer,'"'); + {$endif} + end; + 317: + begin + // Predictor + UValue:=word(ReadEntryUnsigned); + case UValue of + 1: ; + 2: ; + else TiffError('expected Predictor, but found '+IntToStr(UValue)); + end; + IFD.Predictor:=UValue; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 317: Predictor="',IFD.Predictor,'"'); + {$endif} + end; + 320: + begin + // ColorMap: N = 3*2^BitsPerSample + IFD.ColorMap:=GetPos; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 320: skipping ColorMap'); + {$endif} + end; + 322: + begin + // TileWidth + IFD.TileWidth:=ReadEntryUnsigned; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 322: TileWidth=',IFD.TileWidth); + {$endif} + if IFD.TileWidth=0 then + TiffError('TileWidth=0'); + end; + 323: + begin + // TileLength = TileHeight + IFD.TileLength:=ReadEntryUnsigned; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 323: TileLength=',IFD.TileLength); + {$endif} + if IFD.TileLength=0 then + TiffError('TileLength=0'); + end; + 324: + begin + // TileOffsets + IFD.TileOffsets:=GetPos; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 324: TileOffsets=',IFD.TileOffsets); + {$endif} + if IFD.TileOffsets=0 then + TiffError('TileOffsets=0'); + end; + 325: + begin + // TileByteCounts + IFD.TileByteCounts:=GetPos; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 325: TileByteCounts=',IFD.TileByteCounts); + {$endif} + if IFD.TileByteCounts=0 then + TiffError('TileByteCounts=0'); + end; + 338: + begin + // ExtraSamples: if SamplesPerPixel is bigger than PhotometricInterpretation + // then ExtraSamples is an array defining the extra samples + // 0=unspecified + // 1=alpha (premultiplied) + // 2=alpha (unassociated) + IFD.ExtraSamples:=GetPos; + {$ifdef FPC_Debug_Image} + if Debug then begin + ReadShortValues(IFD.ExtraSamples,WordBuffer,Count); + write('TFPReaderTiff.ReadDirectoryEntry Tag 338: ExtraSamples: '); + for i:=0 to Count-1 do + write(IntToStr(WordBuffer[i]),' '); + writeln; + ReAllocMem(WordBuffer,0); + end; + {$endif} + end; + 347: + begin + // ToDo: JPEGTables + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 347: skipping JPEG Tables'); + {$endif} + end; + 512: + begin + // ToDo: JPEGProc + // short + // 1 = baseline sequential + // 14 = lossless process with Huffman encoding + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 512: skipping JPEGProc'); + {$endif} + end; + 513: + begin + // ToDo: JPEGInterchangeFormat + // long + // non zero: start of start of image SOI marker + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 513: skipping JPEGInterchangeFormat'); + {$endif} + end; + 514: + begin + // ToDo: JPEGInterchangeFormatLength + // long + // length in bytes of 513 + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 514: skipping JPEGInterchangeFormatLength'); + {$endif} + end; + 515: + begin + // ToDo: JPEGRestartInterval + // short + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 515: skipping JPEGRestartInterval'); + {$endif} + end; + 517: + begin + // ToDo: JPEGLosslessPredictor + // short + // Count: SamplesPerPixels + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 517: skipping JPEGLosslessPredictor'); + {$endif} + end; + 518: + begin + // ToDo: JPEGPointTransforms + // short + // Count: SamplesPerPixels + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 518: skipping JPEGPointTransforms'); + {$endif} + end; + 519: + begin + // ToDo: JPEGQTables + // long + // Count: SamplesPerPixels + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 519: skipping JPEGQTables'); + {$endif} + end; + 520: + begin + // ToDo: JPEGDCTables + // long + // Count: SamplesPerPixels + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 520: skipping JPEGDCTables'); + {$endif} + end; + 521: + begin + // ToDo: JPEGACTables + // long + // Count: SamplesPerPixels + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 521: skipping JPEGACTables'); + {$endif} + end; + 530: + begin + // ToDo: YCbCrSubSampling alias ChromaSubSampling + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 530: skipping YCbCrSubSampling alias ChromaSubSampling'); + {$endif} + end; + 700: + begin + // ToDo: XMP + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 700: skipping XMP'); + {$endif} + end; + 33432: + begin + // Copyright + IFD.Copyright:=ReadEntryString; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 33432: Copyright="',IFD.Copyright,'"'); + {$endif} + end; + 34675: + begin + // ToDo: ICC Profile + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 34675: skipping ICC profile'); + {$endif} + end; + else + begin + EntryType:=ReadWord; + EntryCount:=ReadDWord; + EntryStart:=ReadDWord; + if (EntryType=0) and (EntryCount=0) and (EntryStart=0) then ; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag=',EntryTag,' Type=',EntryType,' Count=',EntryCount,' ValuesStart=',EntryStart); + {$endif} + end; + end; +end; + +function TFPReaderTiff.ReadEntryUnsigned: DWord; +var + EntryCount: LongWord; + EntryType: Word; +begin + Result:=0; + EntryType:=ReadWord; + EntryCount:=ReadDWord; + if EntryCount<>1 then + TiffError('EntryCount=1 expected, but found '+IntToStr(EntryCount)); + //writeln('TFPReaderTiff.ReadEntryUnsigned Tag=',EntryTag,' Type=',EntryType,' Count=',EntryCount,' ValuesStart=',EntryStart]); + case EntryType of + 1: begin + // byte: 8bit unsigned + Result:=ReadByte; + end; + 3: begin + // short: 16bit unsigned + Result:=ReadWord; + end; + 4: begin + // long: 32bit unsigned long + Result:=ReadDWord; + end; + else + TiffError('expected single unsigned value, but found type='+IntToStr(EntryType)); + end; +end; + +function TFPReaderTiff.ReadEntrySigned: Cint32; +var + EntryCount: LongWord; + EntryType: Word; +begin + Result:=0; + EntryType:=ReadWord; + EntryCount:=ReadDWord; + if EntryCount<>1 then + TiffError('EntryCount+1 expected, but found '+IntToStr(EntryCount)); + //writeln('TFPReaderTiff.ReadEntrySigned Tag=',EntryTag,' Type=',EntryType,' Count=',EntryCount,' ValuesStart=',EntryStart]); + case EntryType of + 1: begin + // byte: 8bit unsigned + Result:=cint8(ReadByte); + end; + 3: begin + // short: 16bit unsigned + Result:=cint16(ReadWord); + end; + 4: begin + // long: 32bit unsigned long + Result:=cint32(ReadDWord); + end; + 6: begin + // sbyte: 8bit signed + Result:=cint8(ReadByte); + end; + 8: begin + // sshort: 16bit signed + Result:=cint16(ReadWord); + end; + 9: begin + // slong: 32bit signed long + Result:=cint32(ReadDWord); + end; + else + TiffError('expected single signed value, but found type='+IntToStr(EntryType)); + end; +end; + +function TFPReaderTiff.ReadEntryRational: TTiffRational; +var + EntryCount: LongWord; + EntryStart: LongWord; + EntryType: Word; +begin + Result:=TiffRational0; + EntryType:=ReadWord; + EntryCount:=ReadDWord; + if EntryCount<>1 then + TiffError('EntryCount+1 expected, but found '+IntToStr(EntryCount)); + //writeln('TFPReaderTiff.ReadEntryUnsigned Tag=',EntryTag,' Type=',EntryType,' Count=',EntryCount,' ValuesStart=',EntryStart]); + case EntryType of + 1: begin + // byte: 8bit unsigned + Result.Numerator:=ReadByte; + end; + 3: begin + // short: 16bit unsigned + Result.Numerator:=ReadWord; + end; + 4: begin + // long: 32bit unsigned long + Result.Numerator:=ReadDWord; + end; + 5: begin + // rational: Two longs: numerator + denominator + // this does not fit into 4 bytes + EntryStart:=ReadDWord; + SetStreamPos(EntryStart); + Result.Numerator:=ReadDWord; + Result.Denominator:=ReadDWord; + end; + else + TiffError('expected rational unsigned value, but found type='+IntToStr(EntryType)); + end; +end; + +function TFPReaderTiff.ReadEntryString: string; +var + EntryType: Word; + EntryCount: LongWord; + EntryStart: LongWord; +begin + Result:=''; + EntryType:=ReadWord; + if EntryType<>2 then + TiffError('asciiz expected, but found '+IntToStr(EntryType)); + EntryCount:=ReadDWord; + EntryStart:=ReadDWord; + SetStreamPos(EntryStart); + SetLength(Result,EntryCount-1); + if EntryCount>1 then + s.Read(Result[1],EntryCount-1); +end; + +function TFPReaderTiff.ReadByte: Byte; +begin + Result:=s.ReadByte; +end; + +function TFPReaderTiff.ReadWord: Word; +begin + Result:=FixEndian(s.ReadWord); +end; + +function TFPReaderTiff.ReadDWord: DWord; +begin + Result:=FixEndian(s.ReadDWord); +end; + +procedure TFPReaderTiff.ReadValues(StreamPos: DWord; + out EntryType: word; out EntryCount: DWord; + out Buffer: Pointer; out ByteCount: PtrUint); +var + EntryStart: DWord; +begin + Buffer:=nil; + ByteCount:=0; + EntryType:=0; + EntryCount:=0; + SetStreamPos(StreamPos); + ReadWord; // skip tag + EntryType:=ReadWord; + EntryCount:=ReadDWord; + if EntryCount=0 then exit; + case EntryType of + 1,6,7: ByteCount:=EntryCount; // byte + 2: ByteCount:=EntryCount; // asciiz + 3,8: ByteCount:=2*EntryCount; // short + 4,9: ByteCount:=4*EntryCount; // long + 5,10: ByteCount:=8*EntryCount; // rational + 11: ByteCount:=4*EntryCount; // single + 12: ByteCount:=8*EntryCount; // double + else + TiffError('invalid EntryType '+IntToStr(EntryType)); + end; + if ByteCount>4 then begin + EntryStart:=ReadDWord; + SetStreamPos(EntryStart); + end; + GetMem(Buffer,ByteCount); + s.Read(Buffer^,ByteCount); +end; + +procedure TFPReaderTiff.ReadShortOrLongValues(StreamPos: DWord; out + Buffer: PDWord; out Count: DWord); +var + p: Pointer; + ByteCount: PtrUInt; + EntryType: word; + i: DWord; +begin + Buffer:=nil; + Count:=0; + p:=nil; + try + ReadValues(StreamPos,EntryType,Count,p,ByteCount); + if Count=0 then exit; + if EntryType=3 then begin + // short + GetMem(Buffer,SizeOf(DWord)*Count); + for i:=0 to Count-1 do + plongwordaty(Buffer)^[i]:=FixEndian(pwordaty(PWord(p))^[i]); + end else if EntryType=4 then begin + // long + Buffer:=p; + p:=nil; + if FReverseEndian then + for i:=0 to Count-1 do + plongwordaty(Buffer)^[i]:= + FixEndian(plongwordaty(PDWord(Buffer))^[i]); + end else + TiffError('only short or long allowed'); + finally + if p<>nil then FreeMem(p); + end; +end; + +procedure TFPReaderTiff.ReadShortValues(StreamPos: DWord; out Buffer: PWord; + out Count: DWord); +var + p: Pointer; + ByteCount: PtrUInt; + EntryType: word; + i: DWord; +begin + Buffer:=nil; + Count:=0; + p:=nil; + try + ReadValues(StreamPos,EntryType,Count,p,ByteCount); + //writeln('ReadShortValues ',FReverseEndian,' ',EntryType,' Count=',Count,' ByteCount=',ByteCount); + if Count=0 then exit; + if EntryType=3 then begin + // short + Buffer:=p; + p:=nil; + if FReverseEndian then + for i:=0 to Count-1 do + pwordaty(Buffer)^[i]:=FixEndian(pwordaty(Buffer)^[i]); + //for i:=0 to Count-1 do writeln(i,' ',Buffer[i]); + end else + TiffError('only short allowed, but found '+IntToStr(EntryType)); + finally + if p<>nil then FreeMem(p); + end; +end; + +procedure TFPReaderTiff.LoadImageFromStream(Index: integer); +var + ChunkOffsets: PDWord; + ChunkByteCounts: PDWord; + Chunk: PByte; + ChunkCount: DWord; + ChunkIndex: Dword; + CurCount: DWord; + CurOffset: DWord; + CurByteCnt: PtrInt; + Run: PByte; + x, y, cx, cy, dx, dy, sx: integer; + SampleBits: PWord; + SampleBitsPerPixel: DWord; + ExtraSamples: PWord; + ExtraSampleCnt: DWord; + GrayBits, GrayValue, LastGrayValue: Word; + RedBits, RedValue, LastRedValue: Word; + GreenBits, GreenValue, LastGreenValue: Word; + BlueBits, BlueValue, LastBlueValue: Word; + AlphaBits, AlphaValue, LastAlphaValue: Word; + Col: TFPColor; + i: Integer; + CurFPImg: TFPCustomImage; + aContinue: Boolean; + ExpectedChunkLength: PtrInt; + ChunkType: TTiffChunkType; + TilesAcross, TilesDown: DWord; + ChunkLeft, ChunkTop, ChunkWidth, ChunkHeight: DWord; + CurImg: TTiffIFD; + ChunkBytesPerLine: DWord; +begin + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.LoadImageFromStream Index=',Index); + {$endif} + IFD:=Images[Index]; + + if IFD.PhotoMetricInterpretation=High(IFD.PhotoMetricInterpretation) then + TiffError('missing PhotometricInterpretation'); + if IFD.BitsPerSample=0 then + TiffError('missing BitsPerSample'); + if IFD.TileWidth>0 then begin + ChunkType:=tctTile; + if IFD.TileLength=0 then + TiffError('missing TileLength'); + if IFD.TileOffsets=0 then + TiffError('missing TileOffsets'); + if IFD.TileByteCounts=0 then + TiffError('missing TileByteCounts'); + end else begin + ChunkType:=tctStrip; + if IFD.RowsPerStrip=0 then + TiffError('missing RowsPerStrip'); + if IFD.StripOffsets=0 then + TiffError('missing StripOffsets'); + if IFD.StripByteCounts=0 then + TiffError('missing StripByteCounts'); + end; + + if (IFD.ImageWidth=0) or (IFD.ImageHeight=0) then + exit; + + if Index=ImageCount then + ImageList.Add(TTiffIFD.Create); + CurImg:=Images[Index]; + + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.LoadImageFromStream reading ...'); + {$endif} + + ChunkOffsets:=nil; + ChunkByteCounts:=nil; + Chunk:=nil; + ExtraSamples:=nil; + SampleBits:=nil; + ExtraSampleCnt:=0; + try + // read chunk starts and sizes + if ChunkType=tctTile then begin + TilesAcross:=(IFD.ImageWidth+IFD.TileWidth-1) div IFD.TileWidth; + TilesDown:=(IFD.ImageHeight+IFD.TileLength-1) div IFD.TileLength; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.LoadImageFromStream TilesAcross=',TilesAcross,' TilesDown=',TilesDown); + {$endif} + ChunkCount := TilesAcross * TilesDown; + ReadShortOrLongValues(IFD.TileOffsets,ChunkOffsets,CurCount); + if CurCount<>ChunkCount then + TiffError('number of TileCounts is wrong'); + ReadShortOrLongValues(IFD.TileByteCounts,ChunkByteCounts,CurCount); + if CurCount<>ChunkCount then + TiffError('number of TileByteCounts is wrong'); + end else begin + ChunkCount:=((IFD.ImageHeight-1) div IFD.RowsPerStrip)+1; + ReadShortOrLongValues(IFD.StripOffsets,ChunkOffsets,CurCount); + if CurCount<>ChunkCount then + TiffError('number of StripCounts is wrong'); + ReadShortOrLongValues(IFD.StripByteCounts,ChunkByteCounts,CurCount); + if CurCount<>ChunkCount then + TiffError('number of StripByteCounts is wrong'); + end; + + // read image structure + ReadImageProperties(RedBits, GreenBits, BlueBits, GrayBits, AlphaBits, + ExtraSamples, ExtraSampleCnt, SampleBits, SampleBitsPerPixel); + CurImg.Assign(IFD); + + // create FPimage + DoCreateImage(CurImg); + CurFPImg:=CurImg.Img; + if CurFPImg=nil then exit; + + SetFPImgExtras(CurFPImg); + + case IFD.Orientation of + 0,1..4: CurFPImg.SetSize(IFD.ImageWidth,IFD.ImageHeight); + 5..8: CurFPImg.SetSize(IFD.ImageHeight,IFD.ImageWidth); + end; + + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.LoadImageFromStream SampleBitsPerPixel=',SampleBitsPerPixel); + {$endif} + + // read chunks + for ChunkIndex:=0 to ChunkCount-1 do begin + CurOffset:= plongwordaty(ChunkOffsets)^[ChunkIndex]; + CurByteCnt:= plongwordaty(ChunkByteCounts)^[ChunkIndex]; + //writeln('TFPReaderTiff.LoadImageFromStream CurOffset=',CurOffset,' CurByteCnt=',CurByteCnt); + if CurByteCnt<=0 then continue; + ReAllocMem(Chunk,CurByteCnt); + SetStreamPos(CurOffset); + s.Read(Chunk^,CurByteCnt); + + // decompress + if ChunkType=tctTile then + ExpectedChunkLength:=(SampleBitsPerPixel*IFD.TileWidth+7) div 8*IFD.TileLength + else + ExpectedChunkLength:=((SampleBitsPerPixel*IFD.ImageWidth+7) div 8)*IFD.RowsPerStrip; + case IFD.Compression of + TiffCompressionNone: ; + TiffCompressionPackBits: DecodePackBits(pointer(Chunk),CurByteCnt); + TiffCompressionLZW: DecodeLZW(pointer(Chunk),CurByteCnt); + TiffCompressionDeflateAdobe, + TiffCompressionDeflateZLib: DecodeDeflate(pointer(Chunk),CurByteCnt,ExpectedChunkLength); + else + TiffError('compression '+TiffCompressionName(IFD.Compression)+' not supported yet'); + end; + if CurByteCnt<=0 then continue; + + // compute current chunk area + if ChunkType=tctTile then begin + ChunkLeft:=(ChunkIndex mod TilesAcross)*IFD.TileWidth; + ChunkTop:=(ChunkIndex div TilesAcross)*IFD.TileLength; + ChunkWidth:=Min(IFD.TileWidth,IFD.ImageWidth-ChunkLeft); + ChunkHeight:=Min(IFD.TileLength,IFD.ImageHeight-ChunkTop); + ChunkBytesPerLine:=(SampleBitsPerPixel*ChunkWidth+7) div 8; + ExpectedChunkLength:=ChunkBytesPerLine*ChunkHeight; + if CurByteCnt=0 then begin + Img:=Images[Best]; + Img.Img:=AnImage; + LoadImageFromStream(Best); + end; + // end + Progress(psEnding, 100, False, Rect(0,0,0,0), '', aContinue); +end; + +function TFPReaderTiff.InternalCheck(Str: TStream): boolean; +var + IFDStart: DWord; +begin + try + s:=Str; + fStartPos:=s.Position; + Result:=ReadTiffHeader(true,IFDStart) and (IFDStart<>0); + s.Position:=fStartPos; + except + Result:=false; + end; +end; + +procedure TFPReaderTiff.DoCreateImage(ImgFileDir: TTiffIFD); +begin + if Assigned(OnCreateImage) then + OnCreateImage(Self,ImgFileDir); +end; + +constructor TFPReaderTiff.Create; +begin + ImageList:=TFPList.Create; +end; + +destructor TFPReaderTiff.Destroy; +begin + Clear; + FreeAndNil(ImageList); + inherited Destroy; +end; + +procedure TFPReaderTiff.Clear; +var + i: Integer; + Img: TTiffIFD; +begin + for i:=ImageCount-1 downto 0 do begin + Img:=Images[i]; + ImageList.Delete(i); + if IFD=Img then IFD:=nil; + Img.Free; + end; + FReverseEndian:=false; + FreeAndNil(fIFDStarts); +end; + +procedure DecompressPackBits(Buffer: Pointer; Count: PtrInt; out + NewBuffer: Pointer; out NewCount: PtrInt); +{ Algorithm: + while not got the expected number of bytes + read one byte n + if n in 0..127 copy the next n+1 bytes + else if n in -127..-1 then copy the next byte 1-n times + else continue + end +} +var + p: Pcint8; + n: cint8; + d: pcint8; + i,j: integer; + EndP: Pcint8; +begin + // compute NewCount + NewCount:=0; + NewBuffer:=nil; + if Count=0 then exit; + p:=Pcint8(Buffer); + EndP:= pointer(pchar(p)+Count); + while pchar(p) < pchar(EndP) do begin + n:=p^; + case n of + 0..127: begin inc(NewCount,n+1); inc(p,n+2); end; // copy the next n+1 bytes + -127..-1: begin inc(NewCount,1-n); inc(p,2); end; // copy the next byte 1-n times + else inc(p); // noop + end; + end; + + // decompress + if NewCount=0 then exit; + GetMem(NewBuffer,NewCount); + p:=Pcint8(Buffer); + d:=Pcint8(NewBuffer); + while pchar(p) < pchar(EndP) do begin + n:=p^; + case n of + 0..127: + begin + // copy the next n+1 bytes + i:=n+1; + inc(NewCount,i); + inc(p); + System.Move(p^,d^,i); + inc(p,i); + inc(d,i); + end; + -127..-1: + begin + // copy the next byte 1-n times + i:=1-n; + inc(NewCount,i); + inc(p); + n:=p^; + for j:=0 to i-1 do + pbyteaty(d)^[j]:=n; + inc(d,i); + inc(p); + end; + else inc(p); // noop + end; + end; +end; + +{$warnings off} + +procedure DecompressLZW(Buffer: Pointer; Count: PtrInt; out NewBuffer: PByte; + out NewCount: PtrInt); +type + TLZWString = packed record + Count: integer; + Data: PByte; + end; + PLZWString = ^TLZWString; +const + ClearCode = 256; // clear table, start with 9bit codes + EoiCode = 257; // end of input +var + NewCapacity: PtrInt; + SrcPos: PtrInt; + SrcPosBit: integer; + CurBitLength: integer; + Code: Word; + Table: PLZWString; + TableCapacity: integer; + TableCount: integer; + OldCode: Word; + + procedure Error(const Msg: string); + begin + raise Exception.Create(Msg); + end; + + function GetNextCode: Word; + var + v: Integer; + begin + Result:=0; + // CurBitLength can be 9 to 12 + //writeln('GetNextCode CurBitLength=',CurBitLength,' SrcPos=',SrcPos,' SrcPosBit=',SrcPosBit,' ',hexstr(PByte(Buffer)[SrcPos],2),' ',hexstr(PByte(Buffer)[SrcPos+1],2),' ',hexstr(PByte(Buffer)[SrcPos+2],2)); + // read two or three bytes + if CurBitLength+SrcPosBit>16 then begin + // read from three bytes + if SrcPos+3>Count then Error('LZW stream overrun'); + v:= pbyteaty(PByte(Buffer))^[SrcPos]; + inc(SrcPos); + v:=(v shl 8)+ pbyteaty(PByte(Buffer))^[SrcPos]; + inc(SrcPos); + v:=(v shl 8)+ pbyteaty(PByte(Buffer))^[SrcPos]; + v:=v shr (24-CurBitLength-SrcPosBit); + end else begin + // read from two bytes + if SrcPos+2>Count then Error('LZW stream overrun'); + v:= pbyteaty(PByte(Buffer))^[SrcPos]; + inc(SrcPos); + v:=(v shl 8)+ pbyteaty(PByte(Buffer))^[SrcPos]; + if CurBitLength+SrcPosBit=16 then + inc(SrcPos); + v:=v shr (16-CurBitLength-SrcPosBit); + end; + Result:=v and ((1 shl CurBitLength)-1); + SrcPosBit:=(SrcPosBit+CurBitLength) and 7; + //writeln('GetNextCode END SrcPos=',SrcPos,' SrcPosBit=',SrcPosBit,' Result=',Result,' Result=',hexstr(Result,4)); + end; + + procedure ClearTable; + var + i: Integer; + begin + for i:=0 to TableCount-1 do + ReAllocMem(plzwstring(ppointeraty(Table)^[i])^.Data,0); + TableCount:=0; + end; + + procedure InitializeTable; + begin + CurBitLength:=9; + ClearTable; + end; + + function IsInTable(Code: word): boolean; + begin + Result:=Code<258+TableCount; + end; + + procedure WriteStringFromCode(Code: integer; AddFirstChar: boolean = false); + var + s: TLZWString; + b: byte; + begin + //WriteLn('WriteStringFromCode Code=',Code,' AddFirstChar=',AddFirstChar,' x=',(NewCount div 4) mod IFD.ImageWidth,' y=',(NewCount div 4) div IFD.ImageWidth,' PixelByte=',NewCount mod 4); + if Code<256 then begin + // write byte + b:=Code; + s.Data:=@b; + s.Count:=1; + end else if Code>=258 then begin + // write string + if Code-258>=TableCount then + Error('LZW code out of bounds'); + s:= plzwstring(ppointeraty(Table)^[Code-258])^; + end else + Error('LZW code out of bounds'); + if NewCount+s.Count+1>NewCapacity then begin + NewCapacity:=NewCapacity*2+8; + ReAllocMem(NewBuffer,NewCapacity); + end; + System.Move(s.Data^,pbyteaty(NewBuffer)^[NewCount],s.Count); + //for i:=0 to s.Count-1 do write(HexStr(NewBuffer[NewCount+i],2)); // debug + inc(NewCount,s.Count); + if AddFirstChar then begin + pbyteaty(NewBuffer)^[NewCount]:= s.Data^; + //write(HexStr(NewBuffer[NewCount],2)); // debug + inc(NewCount); + end; + //writeln(',WriteStringFromCode'); // debug + end; + + procedure AddStringToTable(Code, AddFirstCharFromCode: integer); + // add string from code plus first character of string from code as new string + var + b1, b2: byte; + s1, s2: TLZWString; + p: PByte; + begin + //WriteLn('AddStringToTable Code=',Code,' FCFCode=',AddFirstCharFromCode,' TableCount=',TableCount,' TableCapacity=',TableCapacity); + if TableCount=4096-259 then + Error('LZW too many codes'); + // grow table + if TableCount>=TableCapacity then begin + TableCapacity:=TableCapacity*2+128; + ReAllocMem(Table,TableCapacity*SizeOf(TLZWString)); + end; + // find string 1 + if Code<256 then begin + // string is byte + b1:=Code; + s1.Data:=@b1; + s1.Count:=1; + end else if Code>=258 then begin + // normal string + if Code-258>=TableCount then + Error('LZW code out of bounds'); + s1:= plzwstring(ppointeraty(Table)^[Code-258])^; + end else + Error('LZW code out of bounds'); + // find string 2 + if AddFirstCharFromCode<256 then begin + // string is byte + b2:=AddFirstCharFromCode; + s2.Data:=@b2; + s2.Count:=1; + end else begin + // normal string + if AddFirstCharFromCode-258>=TableCount then + Error('LZW code out of bounds'); + s2:= plzwstring(ppointeraty(Table)^[AddFirstCharFromCode-258])^; + end; + // set new table entry + plzwstring(ppointeraty(Table)^[TableCount])^.Count:= s1.Count+1; + p:=nil; + GetMem(p,s1.Count+1); + plzwstring(ppointeraty(Table)^[TableCount])^.Data:=p; + System.Move(s1.Data^,p^,s1.Count); + // add first character from string 2 + pbyteaty(p)^[s1.Count]:= s2.Data^; + // increase TableCount + inc(TableCount); + case TableCount+259 of + 512,1024,2048: inc(CurBitLength); + end; + end; + +begin + NewBuffer:=nil; + NewCount:=0; + if Count=0 then exit; + //WriteLn('DecompressLZW START Count=',Count); + //for SrcPos:=0 to 19 do + // write(HexStr(PByte(Buffer)[SrcPos],2)); + //writeln(); + + NewCapacity:=Count*2; + ReAllocMem(NewBuffer,NewCapacity); + + SrcPos:=0; + SrcPosBit:=0; + CurBitLength:=9; + Table:=nil; + TableCount:=0; + TableCapacity:=0; + try + repeat + Code:=GetNextCode; + //WriteLn('DecompressLZW Code=',Code); + if Code=EoiCode then break; + if Code=ClearCode then begin + InitializeTable; + Code:=GetNextCode; + //WriteLn('DecompressLZW after clear Code=',Code); + if Code=EoiCode then break; + if Code=ClearCode then + Error('LZW code out of bounds'); + WriteStringFromCode(Code); + OldCode:=Code; + end else begin + if Code Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='inflateInit failed'; + exit; + end; + + // set input = compressed data + stream.avail_in := CompressedCount; + stream.next_in := Compressed; + + // set output = decompressed data + if DecompressedCount=0 then + DecompressedCount:=CompressedCount; + Getmem(Decompressed,DecompressedCount); + stream.avail_out := DecompressedCount; + stream.next_out := Decompressed; + + // Finish the stream + while TRUE do begin + //writeln('run: total_in=',stream.total_in,' avail_in=',stream.avail_in,' total_out=',stream.total_out,' avail_out=',stream.avail_out); + if (stream.avail_out=0) then begin + // need more space + if DecompressedCount<128 then + DecompressedCount:=DecompressedCount+128 + else if DecompressedCount>High(DecompressedCount)-1024 then begin + if ErrorMsg<>nil then + ErrorMsg^:='inflate decompression failed, because not enough space'; + exit; + end else + DecompressedCount:=DecompressedCount*2; + ReAllocMem(Decompressed,DecompressedCount); + stream.next_out:= pointer(pchar(Decompressed)+stream.total_out); + stream.avail_out:= DecompressedCount-stream.total_out; + end; + err := inflate(stream, Z_NO_FLUSH); + if err = Z_STREAM_END then + break; + if err<>Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='inflate finish failed'; + exit; + end; + end; + + //writeln('decompressed: total_in=',stream.total_in,' total_out=',stream.total_out); + DecompressedCount:=stream.total_out; + ReAllocMem(Decompressed,DecompressedCount); + + err := inflateEnd(stream); + if err<>Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='inflateEnd failed'; + exit; + end; + Result:=true; +end; + +initialization + if ImageHandlers.ImageReader[TiffHandlerName]=nil then + ImageHandlers.RegisterImageReader (TiffHandlerName, 'tif;tiff', TFPReaderTiff); +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadxpm.pp b/mseide-msegui/lib/common/fpccompatibility/fpreadxpm.pp new file mode 100644 index 0000000..0acb712 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadxpm.pp @@ -0,0 +1,328 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + XPM reader class. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +{$mode objfpc}{$h+} +unit FPReadXPM; + +interface + +uses FPImage, classes,mclasses, sysutils; + +type + TFPReaderXPM = class (TFPCustomImageReader) + private + width, height, ncols, cpp, xhot, yhot : integer; + xpmext : boolean; + palette : TStringList; + function HexToColor(s : string) : TFPColor; + function NameToColor(s : string) : TFPColor; + function DiminishWhiteSpace (s : string) : string; + protected + procedure InternalRead (Str:TStream; Img:TFPCustomImage); override; + function InternalCheck (Str:TStream) : boolean; override; + public + constructor Create; override; + destructor Destroy; override; + end; + +implementation + +const + WhiteSpace = ' '#8#10#13; + +constructor TFPReaderXPM.create; +begin + inherited create; + palette := TStringList.Create; +end; + +destructor TFPReaderXPM.Destroy; +begin + Palette.Free; + inherited destroy; +end; + +function TFPReaderXPM.HexToColor(s : string) : TFPColor; +var l : integer; + function CharConv (c : char) : longword; + begin + if (c >= 'A') and (c <= 'F') then + result := ord (c) - ord('A') + 10 + else if (c >= '0') and (c <= '9') then + result := ord (c) - ord('0') + else + raise exception.CreateFmt ('Wrong character (%s) in hexadecimal number', [c]); + end; + function convert (n : string) : word; + var t,r: integer; + begin + result := 0; + t := length(n); + if t > 4 then + raise exception.CreateFmt ('Too many bytes for color (%s)',[s]); + for r := 1 to length(n) do + result := (result shl 4) or CharConv(n[r]); + // fill missing bits + case t of + 1: result:=result or (result shl 4) or (result shl 8) or (result shl 12); + 2: result:=result or (result shl 8); + 3: result:=result or (result shl 12); + end; + end; +begin + s := uppercase (s); + l := length(s) div 3; + result.red := (Convert(copy(s,1,l))); + result.green := (Convert(copy(s,l+1,l))); + result.blue := Convert(copy(s,l+l+1,l)); + result.alpha := AlphaOpaque; +end; + +function TFPReaderXPM.NameToColor(s : string) : TFPColor; +begin + s := lowercase (s); + if s = 'transparent' then + result := colTransparent + else if s = 'none' then + result := colTransparent + else if s = 'black' then + result := colBlack + else if s = 'blue' then + result := colBlue + else if s = 'green' then + result := colGreen + else if s = 'cyan' then + result := colCyan + else if s = 'red' then + result := colRed + else if s = 'magenta' then + result := colMagenta + else if s = 'yellow' then + result := colYellow + else if s = 'white' then + result := colWhite + else if s = 'gray' then + result := colGray + else if s = 'ltgray' then + result := colLtGray + else if s = 'dkblue' then + result := colDkBlue + else if s = 'dkgreen' then + result := colDkGreen + else if s = 'dkcyan' then + result := colDkCyan + else if s = 'dkred' then + result := colDkRed + else if s = 'dkmagenta' then + result := colDkMagenta + else if s = 'dkyellow' then + result := colDkYellow + else if s = 'maroon' then + result := colMaroon + else if s = 'ltgreen' then + result := colLtGreen + else if s = 'olive' then + result := colOlive + else if s = 'navy' then + result := colNavy + else if s = 'purple' then + result := colPurple + else if s = 'teal' then + result := colTeal + else if s = 'silver' then + result := colSilver + else if s = 'lime' then + result := colLime + else if s = 'fuchsia' then + result := colFuchsia + else if s = 'aqua' then + result := colAqua + else + result := colTransparent; +end; + +function TFPReaderXPM.DiminishWhiteSpace (s : string) : string; +var r : integer; + Doit : boolean; +begin + Doit := true; + result := ''; + for r := 1 to length(s) do + if pos(s[r],WhiteSpace)>0 then + begin + if DoIt then + result := result + ' '; + DoIt := false; + end + else + begin + DoIt := True; + result := result + s[r]; + end; +end; + +procedure TFPReaderXPM.InternalRead (Str:TStream; Img:TFPCustomImage); +var l : TStringList; + + procedure TakeInteger (var s : string; var i : integer); + var r : integer; + begin + r := pos (' ', s); + if r = 0 then + begin + i := StrToInt(s); + s := ''; + end + else + begin + i := StrToInt(copy(s,1,r-1)); + delete (s, 1, r); + end; + end; + + procedure ParseFirstLine; + var s : string; + begin + s := l[0]; + // diminish all whitespace to 1 blank + s := DiminishWhiteSpace (trim(s)); + Takeinteger (s, width); + Takeinteger (s, height); + Takeinteger (s, ncols); + Takeinteger (s, cpp); + if s <> '' then + begin + Takeinteger (s, xhot); + Takeinteger (s, yhot); + xpmext := (comparetext(s, 'XPMEXT') = 0); + if (s <> '') and not xpmext then + Raise Exception.Create ('Wrong word for XPMEXT tag'); + end; + end; + + procedure AddPalette (const code:string;const Acolor:TFPColor); + var r : integer; + begin + r := Palette.Add(code); + img.palette.Color[r] := Acolor; + end; + + procedure AddToPalette(s : string); + var code : string; + c : TFPColor; + p : integer; + begin + code := copy(s,1,cpp); + s := trim(diminishWhiteSpace (copy(s,cpp+1,maxint))); + // Search for c-key in the color values + if s[1] = 'c' then + delete (s, 1, 2) + else + begin + p := pos (' c ',s); + if p = 0 then + s := '' + else + delete (s, 1, p+2); + end; + // c color value is first word, remove the rest of the line + p := pos(' ', s); + if p > 0 then + delete (s, p, maxint); + // check if exists + if s = '' then + raise exception.Create ('Only c-key is used for colors'); + // convert #hexadecimal value to integer and place in palette + if s[1] = '#' then + c := HexToColor(copy(s,2,maxint)) + else + c := NameToColor(s); + AddPalette(code,c); + end; + + procedure ReadPalette; + var r : integer; + begin + Palette.Clear; + Img.Palette.Count := ncols; + for r := 1 to ncols do + AddToPalette (l[r]); + end; + + procedure ReadLine (const s : string; imgindex : integer); + var color, r, p : integer; + code : string; + begin + p := 1; + for r := 1 to width do + begin + code := copy(s, p, cpp); + inc(p,cpp); + for color := 0 to Palette.Count-1 do + { Can't use indexof, as compare must be case sensitive } + if code = Palette[color] then begin + img.pixels[r-1,imgindex] := color; + Break; + end; + end; + end; + + procedure ReadData; + var r : integer; + begin + for r := 1 to height do + ReadLine (l[ncols+r], r-1); + end; + +var p, r : integer; +begin + l := TStringList.Create; + try + l.LoadFromStream (Str); + for r := l.count-1 downto 0 do + begin + p := pos ('"', l[r]); + if p > 0 then + l[r] := copy(l[r], p+1, lastdelimiter('"',l[r])-p-1) + else + l.delete(r); + end; + ParseFirstLine; + Img.SetSize (width, height); + ReadPalette; + ReadData; + finally + l.Free; + end; +end; + +function TFPReaderXPM.InternalCheck (Str:TStream) : boolean; +var s : string[9]; + l : integer; +begin + try + l := str.Read (s[1],9); + s[0] := char(l); + if l <> 9 then + result := False + else + result := (s = '/* XPM */'); + except + result := false; + end; +end; + +initialization + ImageHandlers.RegisterImageReader ('XPM Format', 'xpm', TFPReaderXPM); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadxwd.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadxwd.pas new file mode 100644 index 0000000..d3b0308 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadxwd.pas @@ -0,0 +1,297 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + BMP reader implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. +} +{*****************************************************************************} +{ 08/2005 by Giulio Bernardi: + - Added support for 16 and 15 bpp bitmaps. + - If we have bpp <= 8 make an indexed image instead of converting it to RGB + - Support for RLE4 and RLE8 decoding + - Support for top-down bitmaps +} + +{$mode objfpc} +{$h+} + +unit FPReadXWD; + +interface + +uses FPImage, classes, sysutils, xwdfile; + +type + TXWDColors = array of TXWDColor; + + { TFPReaderXWD } + + TFPReaderXWD = class (TFPCustomImageReader) + private + continue: boolean; // needed for onprogress event + percent: byte; + percentinterval : longword; + percentacc : longword; + Rect : TRect; + procedure SwapXWDFileHeader(var Header: TXWDFileHeader); + procedure SwapXWDColor(var Color: TXWDColor); + procedure WriteScanLine(Row: Integer; Img: TFPCustomImage); + protected + XWDFileHeader: TXWDFileHeader; // The header, as read from the file + WindowName: array of Char; + XWDColors: TXWDColors; + LineBuf: PByte; // Buffer for 1 line + + // required by TFPCustomImageReader + procedure InternalRead (Stream:TStream; Img:TFPCustomImage); override; + function InternalCheck (Stream:TStream) : boolean; override; + public + constructor Create; override; + destructor Destroy; override; + end; + +implementation + +//============================================================================== +// Endian utils +// +// Copied from LCLProc unit +//============================================================================== +{$R-} +function BEtoN(const AValue: DWord): DWord; +begin + {$IFDEF ENDIAN_BIG} + Result := AValue; + {$ELSE} + Result := (AValue shl 24) + or ((AValue and $0000FF00) shl 8) + or ((AValue and $00FF0000) shr 8) + or (AValue shr 24); + {$ENDIF} +end; +{$R+} + +constructor TFPReaderXWD.create; +begin + inherited create; + +end; + +destructor TFPReaderXWD.Destroy; +begin + If (LineBuf<>Nil) then + begin + FreeMem(LineBuf); + LineBuf:=Nil; + end; + + SetLength(WindowName, 0); + + SetLength(XWDColors, 0); + + inherited destroy; +end; + +procedure TFPReaderXWD.SwapXWDColor(var Color: TXWDColor); +begin + Color.pixel := BEtoN(Color.pixel); + + Color.red := swap(Color.red); + Color.green := swap(Color.green); + Color.blue := swap(Color.blue); +end; + +procedure TFPReaderXWD.SwapXWDFileHeader(var Header: TXWDFileHeader); +begin + Header.header_size := BEtoN(Header.header_size); + Header.file_version := BEtoN(Header.file_version); + Header.pixmap_format := BEtoN(Header.pixmap_format); + Header.pixmap_depth := BEtoN(Header.pixmap_depth); + Header.pixmap_width := BEtoN(Header.pixmap_width); + Header.pixmap_height := BEtoN(Header.pixmap_height); + Header.xoffset := BEtoN(Header.xoffset); + Header.byte_order := BEtoN(Header.byte_order); + Header.bitmap_unit := BEtoN(Header.bitmap_unit); + Header.bitmap_unit := BEtoN(Header.bitmap_bit_order); + Header.bitmap_pad := BEtoN(Header.bitmap_pad); + Header.bits_per_pixel := BEtoN(Header.bits_per_pixel); + Header.bytes_per_line := BEtoN(Header.bytes_per_line); + Header.visual_class := BEtoN(Header.visual_class); + Header.red_mask := BEtoN(Header.red_mask); + Header.green_mask := BEtoN(Header.green_mask); + Header.blue_mask := BEtoN(Header.blue_mask); + Header.bits_per_rgb := BEtoN(Header.bits_per_rgb); + Header.colormap_entries := BEtoN(Header.colormap_entries); + Header.ncolors := BEtoN(Header.ncolors); + Header.window_width := BEtoN(Header.window_width); + Header.window_height := BEtoN(Header.window_height); + Header.window_x := BEtoN(Header.window_x); + Header.window_y := BEtoN(Header.window_y); + Header.window_bdrwidth := BEtoN(Header.window_bdrwidth); +end; + +procedure TFPReaderXWD.WriteScanLine(Row : Integer; Img : TFPCustomImage); +var + Column: Integer; + buffer: Cardinal; + MyColor: TFPColor; +begin + MyColor.alpha := 0; + + case XWDFileHeader.bits_per_pixel of + 1 : + for Column:=0 to Img.Width-1 do + if ((LineBuf[Column div 8] shr (7-(Column and 7)) ) and 1) <> 0 then + img.Pixels[Column,Row]:=1 + else + img.Pixels[Column,Row]:=0; + 4 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=(LineBuf[Column div 2] shr (((Column+1) and 1)*4)) and $0f; + 8 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=LineBuf[Column]; + 16 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=LineBuf[Column]; + 24 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=LineBuf[Column]; + 32 : + for Column:=0 to img.Width-1 do + begin + Move(LineBuf[Column * 4], buffer, 4); +// WriteLn(IntToHex(buffer, 8)); + +{ buffer := buffer mod (256 * 256 * 256); + MyColor.red := Word((buffer div 256 * 256) * 256); + buffer := buffer mod (256 * 256); + MyColor.green := Word((buffer div 256) * 256); + buffer := buffer mod 256; + MyColor.blue := Word((buffer) * 256);} + + buffer := buffer mod (256 * 256 * 256); + MyColor.blue := Word((buffer div 256 * 256) * 256); + buffer := buffer mod (256 * 256); + MyColor.green := Word((buffer div 256) * 256); + buffer := buffer mod 256; + MyColor.red := Word((buffer) * 256); + + img.Colors[Column,Row] := MyColor; + end; + end; + +{ inc(percentacc,4); + if percentacc>=percentinterval then + begin + percent:=percent+(percentacc div percentinterval); + percentacc:=percentacc mod percentinterval; + Progress(psRunning,percent,false,Rect,'',continue); + end;} +end; + +procedure TFPReaderXWD.InternalRead(Stream: TStream; Img: TFPCustomImage); +var + Color: TFPColor; + Size, Row, i, Index: Integer; +begin + {**************************************************************************** + Initialization + ****************************************************************************} + Rect.Left:=0; Rect.Top:=0; Rect.Right:=0; Rect.Bottom:=0; + continue:=true; + Progress(psStarting,0,false,Rect,'',continue); + if not continue then exit; + + Img.UsePalette := True; +// Img.Palette.Clear; + Color.alpha := 0; + + {**************************************************************************** + The file is on big-endian format, so it needs to be swaped on little-endian CPUs + ****************************************************************************} + Stream.Position := 0; //* Causes error if removed, but should be + + Stream.Read(XWDFileHeader, SizeOf(TXWDFileHeader)); + +{$ifdef ENDIAN_LITTLE} + SwapXWDFileHeader(XWDFileHeader); +{$endif} + + {**************************************************************************** + Now reads the window name + ****************************************************************************} + Size := XWDFileHeader.header_size - SizeOf(TXWDFileHeader); + + // Avoids allocating too much space for the string + if Size > 256 then raise Exception.Create('Window name string too big. The file might be corrupted.'); + + SetLength(WindowName, Size); + + Stream.Read(WindowName[0], Size); + + {**************************************************************************** + Fills the palette + ****************************************************************************} + SetLength(XWDColors, XWDFileHeader.ncolors); + + Img.Palette.Count := 256; + + for i := 1 to XWDFileHeader.ncolors do + begin + Stream.Read(XWDColors[i - 1], SizeOf(TXWDColor)); + + {$ifdef ENDIAN_LITTLE} + SwapXWDColor(XWDColors[i - 1]); + {$endif} + + Color.red := XWDColors[i - 1].red; + Color.green := XWDColors[i - 1].green; + Color.blue := XWDColors[i - 1].blue; + + Index := XWDColors[i - 1].pixel mod 256; +// WriteLn(IntToHex(Index, 8)); + Img.Palette.Color[Index] := Color; + end; + + {**************************************************************************** + Reads the matrix of colors + ****************************************************************************} + Img.SetSize(XWDFileHeader.pixmap_width, XWDFileHeader.pixmap_height); + + GetMem(LineBuf, XWDFileHeader.bytes_per_line); + + for Row := 0 to Img.Height - 1 do + begin + Stream.Read(LineBuf[0], XWDFileHeader.bytes_per_line); + WriteScanLine(Row, Img); + if not continue then exit; + end; + + Progress(psEnding,100,false,Rect,'',continue); +end; + +function TFPReaderXWD.InternalCheck (Stream:TStream): boolean; +var + Header: TXWDFileHeader; +begin + stream.Read(Header, SizeOf(Header)); + {$IFDEF ENDIAN_LITTLE} + SwapXWDFileHeader(Header); + {$ENDIF} + Result := Header.file_version = XWD_FILE_VERSION; // Just check magic number +end; + +initialization + + ImageHandlers.RegisterImageReader ('XWD Format', 'xwd', TFPReaderXWD); + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fptiffcmn.pas b/mseide-msegui/lib/common/fpccompatibility/fptiffcmn.pas new file mode 100644 index 0000000..a6dc308 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fptiffcmn.pas @@ -0,0 +1,420 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2012 by the Free Pascal development team + + Common stuff for Tiff image format. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + ********************************************************************** +} +//modified 2013 by Martin Schreiber +unit fptiffcmn; + +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +interface + +uses + classes, sysutils, fpimage,msetypes; + +type + TTiffRational = packed record + Numerator, Denominator: DWord; + end; + +const + TiffHandlerName = 'Tagged Image File Format'; + + TiffRational0: TTiffRational = (Numerator: 0; Denominator: 0); + TiffRational72: TTiffRational = (Numerator: 72; Denominator: 1); + + // TFPCustomImage.Extra properties used by TFPReaderTiff and TFPWriterTiff + TiffExtraPrefix = 'Tiff'; + TiffPhotoMetric = TiffExtraPrefix+'PhotoMetricInterpretation'; + TiffGrayBits = TiffExtraPrefix+'GrayBits'; // CMYK: key plate + TiffRedBits = TiffExtraPrefix+'RedBits'; // CMYK: cyan + TiffGreenBits = TiffExtraPrefix+'GreenBits'; // CMYK: magenta + TiffBlueBits = TiffExtraPrefix+'BlueBits'; // CMYK: yellow + TiffAlphaBits = TiffExtraPrefix+'AlphaBits'; + TiffArtist = TiffExtraPrefix+'Artist'; + TiffCopyright = TiffExtraPrefix+'Copyright'; + TiffDocumentName = TiffExtraPrefix+'DocumentName'; + TiffDateTime = TiffExtraPrefix+'DateTime'; + TiffImageDescription = TiffExtraPrefix+'ImageDescription'; + TiffHostComputer = TiffExtraPrefix+'HostComputer'; + TiffMake_ScannerManufacturer = TiffExtraPrefix+'Make_ScannerManufacturer'; + TiffModel_Scanner = TiffExtraPrefix+'Model_Scanner'; + TiffOrientation = TiffExtraPrefix+'Orientation'; + TiffResolutionUnit = TiffExtraPrefix+'ResolutionUnit'; + TiffSoftware = TiffExtraPrefix+'Software'; + TiffXResolution = TiffExtraPrefix+'XResolution'; + TiffYResolution = TiffExtraPrefix+'YResolution'; + TiffPageNumber = TiffExtraPrefix+'PageNumber'; // starting at 0 + TiffPageCount = TiffExtraPrefix+'PageCount'; // if >0 the image is a page + TiffPageName = TiffExtraPrefix+'PageName'; + TiffIsThumbnail = TiffExtraPrefix+'IsThumbnail'; + TiffIsMask = TiffExtraPrefix+'IsMask'; + TiffTileWidth = TiffExtraPrefix+'TileWidth'; + TiffTileLength = TiffExtraPrefix+'TileLength'; + TiffCompression = TiffExtraPrefix+'Compression'; // number + + TiffCompressionNone = 1; { No Compression, but pack data into bytes as tightly as possible, + leaving no unused bits (except at the end of a row). The component + values are stored as an array of type BYTE. Each scan line (row) + is padded to the next BYTE boundary. } + TiffCompressionCCITTRLE = 2; { CCITT Group 3 1-Dimensional Modified Huffman run length encoding. } + TiffCompressionCCITTFAX3 = 3; { CCITT Group 3 fax encoding } + TiffCompressionCCITTFAX4 = 4; { CCITT Group 4 fax encoding } + TiffCompressionLZW = 5; { LZW } + TiffCompressionOldJPEG = 6; { JPEG old style} + TiffCompressionJPEG = 7; { JPEG new style } + TiffCompressionDeflateAdobe = 8; { Deflate Adobe style } + TiffCompressionJBIGBW = 9; { RFC2301 JBIG black/white } + TiffCompressionJBIGCol = 10; { RFC2301 JBIG color } + TiffCompressionNeXT = 32766; { Next } + TiffCompressionCCITTRLEW = 32771; { CCITTRLEW } + TiffCompressionPackBits = 32773; { PackBits Compression, a simple byte-oriented run length scheme. + See the PackBits section for details. Data Compression applies + only to raster image data. All other TIFF fields are unaffected. } + TiffCompressionThunderScan = 32809; { THUNDERSCAN } + TiffCompressionIT8CTPAD = 32895; { IT8CTPAD } + TiffCompressionIT8LW = 32896; { IT8LW } + TiffCompressionIT8MP = 32897; { IT8MP } + TiffCompressionIT8BL = 32898; { IT8BL } + TiffCompressionPixarFilm = 32908; { PIXARFILM } + TiffCompressionPixarLog = 32909; { PIXARLOG } + TiffCompressionDeflateZLib = 32946; { DeflatePKZip } + TiffCompressionDCS = 32947; { DCS } + TiffCompressionJBIG = 34661; { JBIG } + TiffCompressionSGILog = 34676; { SGILOG } + TiffCompressionSGILog24 = 34677; { SGILOG24 } + TiffCompressionJPEG2000 = 34712; { JP2000 } +type + TTiffChunkType = ( + tctStrip, + tctTile + ); + + { TTiffIFD - Image File Directory } + + TTiffIFD = class + public + IFDStart: DWord; // tiff position + IFDNext: DWord; // tiff position + Artist: String; + BitsPerSample: DWord; // tiff position of entry + BitsPerSampleArray: array of Word; + CellLength: DWord; + CellWidth: DWord; + ColorMap: DWord;// tiff position of entry + Compression: DWord; + Predictor: Word; + Copyright: string; + DateAndTime: string; + DocumentName: string; + ExtraSamples: DWord;// tiff position of entry + FillOrder: DWord; + HostComputer: string; + ImageDescription: string; + ImageHeight: DWord; + ImageIsMask: Boolean; + ImageIsPage: Boolean; + ImageIsThumbNail: Boolean; + ImageWidth: DWord; + Make_ScannerManufacturer: string; + Model_Scanner: string; + Orientation: DWord; + PageNumber: word; // the page number starting at 0, the total number of pages is PageCount + PageCount: word; // see PageNumber + PageName: string; + PhotoMetricInterpretation: DWord; + PlanarConfiguration: DWord; + ResolutionUnit: DWord; + RowsPerStrip: DWord; + SamplesPerPixel: DWord; + Software: string; + StripByteCounts: DWord;// tiff position of entry + StripOffsets: DWord; // tiff position of entry + TileWidth: DWord; + TileLength: DWord; // = Height + TileOffsets: DWord; // tiff position of entry + TileByteCounts: DWord; // tiff position of entry + Tresholding: DWord; + XResolution: TTiffRational; + YResolution: TTiffRational; + // image + Img: TFPCustomImage; + FreeImg: boolean; + RedBits: word; + GreenBits: word; + BlueBits: word; + GrayBits: word; + AlphaBits: word; + BytesPerPixel: Word; + procedure Clear; + procedure Assign(IFD: TTiffIFD); + procedure ReadFPImgExtras(Src: TFPCustomImage); + function ImageLength: DWord; {$ifdef FPC}inline;{$endif} + destructor Destroy; override; + end; + +function TiffRationalToStr(const r: TTiffRational): string; +function StrToTiffRationalDef(const s: string; const Def: TTiffRational): TTiffRational; +procedure ClearTiffExtras(Img: TFPCustomImage); +procedure CopyTiffExtras(SrcImg, DestImg: TFPCustomImage); +procedure WriteTiffExtras(Msg: string; Img: TFPCustomImage); +function TiffCompressionName(c: Word): string; + +implementation + +function TiffRationalToStr(const r: TTiffRational): string; +begin + Result:=IntToStr(r.Numerator)+'/'+IntToStr(r.Denominator); +end; + +function StrToTiffRationalDef(const s: string; const Def: TTiffRational + ): TTiffRational; +var + p: LongInt; +begin + Result:=Def; + p:=System.Pos('/',s); + if p<1 then exit; + Result.Numerator:=StrToIntDef(copy(s,1,p-1),TiffRational0.Numerator); + Result.Denominator:=StrToIntDef(copy(s,p+1,length(s)),TiffRational0.Denominator); +end; + +procedure ClearTiffExtras(Img: TFPCustomImage); +var + i: Integer; +begin + for i:=Img.ExtraCount-1 downto 0 do + if SysUtils.CompareText(copy(Img.ExtraKey[i],1,4),'Tiff')=0 then + Img.RemoveExtra(Img.ExtraKey[i]); +end; + +procedure CopyTiffExtras(SrcImg, DestImg: TFPCustomImage); +var + i: Integer; +begin + ClearTiffExtras(DestImg); + for i:=SrcImg.ExtraCount-1 downto 0 do + if SysUtils.CompareText(copy(SrcImg.ExtraKey[i],1,4),'Tiff')=0 then + DestImg.Extra[SrcImg.ExtraKey[i]]:=SrcImg.ExtraValue[i]; +end; + +procedure WriteTiffExtras(Msg: string; Img: TFPCustomImage); +var + i: Integer; +begin + writeln('WriteTiffExtras ',Msg); + for i:=0 to Img.ExtraCount-1 do + //if SysUtils.CompareText(copy(Img.ExtraKey[i],1,4),'Tiff')=0 then + writeln(' ',i,' ',Img.ExtraKey[i],'=',Img.ExtraValue[i]); +end; + +function TiffCompressionName(c: Word): string; +begin + case c of + 1: Result:='no compression'; + 2: Result:='CCITT Group 3 1-Dimensional Modified Huffman run length encoding'; + 3: Result:='CCITT Group 3 fax encoding'; + 4: Result:='CCITT Group 4 fax encoding'; + 5: Result:='LZW'; + 6: Result:='JPEG old style'; + 7: Result:='JPEG'; + 8: Result:='Deflate Adobe style'; + 9: Result:='RFC2301 JBIG white/black'; + 10: Result:='RFC2301 JBIG color'; + 32766: Result:='NeXT'; + 32771: Result:='CCITTRLEW'; + 32773: Result:='PackBits'; + 32809: Result:='THUNDERSCAN'; + 32895: Result:='IT8CTPAD'; + 32896: Result:='IT8LW'; + 32897: Result:='IT8MP'; + 32898: Result:='IT8BL'; + 32908: Result:='PIXARFILM'; + 32909: Result:='PIXARLOG'; + 32946: Result:='Deflate ZLib'; + 32947: Result:='DCS'; + 34661: Result:='JBIG'; + 34676: Result:='SGILOG'; + 34677: Result:='SGILOG24'; + 34712: Result:='JP2000'; + else Result:='unknown('+IntToStr(c)+')'; + end; +end; + +{ TTiffIFD } + +procedure TTiffIFD.Clear; +begin + IFDStart:=0; + IFDNext:=0; + PhotoMetricInterpretation:=High(PhotoMetricInterpretation); + PlanarConfiguration:=0; + Compression:=TiffCompressionNone; + Predictor:=1; + ImageHeight:=0; + ImageWidth:=0; + ImageIsThumbNail:=false; + ImageIsPage:=false; + ImageIsMask:=false; + BitsPerSample:=0; + SetLength(BitsPerSampleArray,0); + ResolutionUnit:=0; + XResolution:=TiffRational0; + YResolution:=TiffRational0; + RowsPerStrip:=0; + StripOffsets:=0; + StripByteCounts:=0; + SamplesPerPixel:=0; + Artist:=''; + HostComputer:=''; + ImageDescription:=''; + Make_ScannerManufacturer:=''; + Model_Scanner:=''; + Copyright:=''; + DateAndTime:=''; + Software:=''; + CellWidth:=0; + CellLength:=0; + FillOrder:=0; + Orientation:=0; + PageNumber:=0; + PageCount:=0; + PageName:=''; + + // tiles + TileWidth:=0; + TileLength:=0; + TileOffsets:=0; + TileByteCounts:=0; + + Tresholding:=0; + + RedBits:=0; + GreenBits:=0; + BlueBits:=0; + GrayBits:=0; + AlphaBits:=0; + BytesPerPixel:=0; + + if FreeImg then begin + FreeImg:=false; + FreeAndNil(Img); + end; +end; + +procedure TTiffIFD.Assign(IFD: TTiffIFD); +begin + IFDStart:=IFD.IFDStart; + IFDNext:=IFD.IFDNext; + + PhotoMetricInterpretation:=IFD.PhotoMetricInterpretation; + PlanarConfiguration:=IFD.PlanarConfiguration; + Compression:=IFD.Compression; + Predictor:=IFD.Predictor; + ImageHeight:=IFD.ImageHeight; + ImageWidth:=IFD.ImageWidth; + ImageIsThumbNail:=IFD.ImageIsThumbNail; + ImageIsPage:=IFD.ImageIsPage; + ImageIsMask:=IFD.ImageIsMask; + BitsPerSample:=IFD.BitsPerSample; + BitsPerSampleArray:=IFD.BitsPerSampleArray; + ResolutionUnit:=IFD.ResolutionUnit; + XResolution:=IFD.XResolution; + YResolution:=IFD.YResolution; + RowsPerStrip:=IFD.RowsPerStrip; + StripOffsets:=IFD.StripOffsets; + StripByteCounts:=IFD.StripByteCounts; + SamplesPerPixel:=IFD.SamplesPerPixel; + Artist:=IFD.Artist; + HostComputer:=IFD.HostComputer; + ImageDescription:=IFD.ImageDescription; + Make_ScannerManufacturer:=IFD.Make_ScannerManufacturer; + Model_Scanner:=IFD.Model_Scanner; + Copyright:=IFD.Copyright; + DateAndTime:=IFD.DateAndTime; + Software:=IFD.Software; + CellWidth:=IFD.CellWidth; + CellLength:=IFD.CellLength; + FillOrder:=IFD.FillOrder; + Orientation:=IFD.Orientation; + PageNumber:=IFD.PageNumber; + PageCount:=IFD.PageCount; + PageName:=IFD.PageName; + + // tiles + TileWidth:=IFD.TileWidth; + TileLength:=IFD.TileLength; + TileOffsets:=IFD.TileOffsets; + TileByteCounts:=IFD.TileByteCounts; + + Tresholding:=IFD.Tresholding; + + RedBits:=IFD.RedBits; + GreenBits:=IFD.GreenBits; + BlueBits:=IFD.BlueBits; + GrayBits:=IFD.GrayBits; + AlphaBits:=IFD.AlphaBits; + if (Img<>nil) and (IFD.Img<>nil) then + Img.Assign(IFD.Img); +end; + +procedure TTiffIFD.ReadFPImgExtras(Src: TFPCustomImage); +begin + Clear; + PhotoMetricInterpretation:=2; + if Src.Extra[TiffPhotoMetric]<>'' then + PhotoMetricInterpretation:= + StrToInt64Def(Src.Extra[TiffPhotoMetric],High(PhotoMetricInterpretation)); + Artist:=Src.Extra[TiffArtist]; + Copyright:=Src.Extra[TiffCopyright]; + DocumentName:=Src.Extra[TiffDocumentName]; + DateAndTime:=Src.Extra[TiffDateTime]; + HostComputer:=Src.Extra[TiffHostComputer]; + Make_ScannerManufacturer:=Src.Extra[TiffMake_ScannerManufacturer]; + Model_Scanner:=Src.Extra[TiffModel_Scanner]; + ImageDescription:=Src.Extra[TiffImageDescription]; + Software:=Src.Extra[TiffSoftware]; + Orientation:=StrToIntDef(Src.Extra[TiffOrientation],1); + if not (Orientation in [1..8]) then + Orientation:=1; + ResolutionUnit:=StrToIntDef(Src.Extra[TiffResolutionUnit],2); + if not (ResolutionUnit in [1..3]) then + ResolutionUnit:=2; + XResolution:=StrToTiffRationalDef(Src.Extra[TiffXResolution],TiffRational72); + YResolution:=StrToTiffRationalDef(Src.Extra[TiffYResolution],TiffRational72); + PageNumber:=StrToIntDef(Src.Extra[TiffPageNumber],0); + PageCount:=StrToIntDef(Src.Extra[TiffPageCount],0); + PageName:=Src.Extra[TiffPageName]; + ImageIsPage:=PageCount>0; + ImageIsThumbNail:=Src.Extra[TiffIsThumbnail]<>''; + ImageIsMask:=Src.Extra[TiffIsMask]<>''; + TileWidth:=StrToIntDef(Src.Extra[TiffTileWidth],0); + TileLength:=StrToIntDef(Src.Extra[TiffTileLength],0); + Compression:=StrToIntDef(Src.Extra[TiffCompression],TiffCompressionNone); +end; + +function TTiffIFD.ImageLength: DWord; +begin + Result:=ImageHeight; +end; + +destructor TTiffIFD.Destroy; +begin + if FreeImg then + FreeAndNil(Img); + inherited Destroy; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pas b/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pas new file mode 100644 index 0000000..d9eca54 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pas @@ -0,0 +1,732 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + BMP writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. +} +{*****************************************************************************} +{ 08/2005 by Giulio Bernardi: + - Removed FBytesPerPixel, BytesPerPixel property is now deprecated, use BitsPerPixel instead. + - Rewritten a large part of the file, so we can handle all bmp color depths + - Support for RLE4 and RLE8 encoding +} + +{$mode objfpc}{$h+} +unit FPWriteBMP; + +interface + +uses FPImage, classes, sysutils, BMPComn; + +type + + TFPWriterBMP = class (TFPCustomImageWriter) + private + StartPosition : int64; { save start of bitmap in the stream, if we must go back and fix something } + FBpp : byte; + FRLECompress : boolean; + BFH : TBitMapFileHeader; + BFI : TBitMapInfoHeader; + Colinfo : array of TColorRGBA; + procedure SetColorSize (AValue : Byte); + function GetColorSize : byte; + procedure SetBpp (const abpp : byte); + procedure FillColorMap(Img : TFPCustomImage); + procedure Setup16bpp; + function PackWord555(const col : TFPColor) : word; + function PackWord565(const col : TFPColor) : word; + function Pack4bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; + function Pack1bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; + procedure CompressScanLineRLE8(ALine : pbyte; const Row, Width : Integer; Stream : TStream); + procedure CompressScanLineRLE4(ALine : pbyte; const Row, Width : Integer; Stream : TStream); + protected + function SaveHeader(Stream:TStream; Img: TFPCustomImage):boolean; virtual; + procedure InternalWrite (Stream:TStream; Img: TFPCustomImage); override; + public + constructor Create; override; + property BitsPerPixel : byte read FBpp write SetBpp; + property RLECompress : boolean read FRleCompress write FRleCompress; + Property BytesPerPixel : Byte Read GetColorSize Write SetColorSize; deprecated; + end; + + +implementation + +Function FPColorToRGB(Const Color : TFPColor) : TColorRGB; + +begin + With Result,Color do + begin + R:=(Red and $FF00) shr 8; + G:=(Green and $FF00) shr 8; + B:=(Blue and $FF00) shr 8; + end; +end; + +Function FPColorToRGBA(Const Color : TFPColor) : TColorRGBA; + +begin + With Result,Color do + begin + R:=(Red and $FF00) shr 8; + G:=(Green and $FF00) shr 8; + B:=(Blue and $FF00) shr 8; + A:=(Alpha and $FF00) shr 8; + end; +end; + +constructor TFPWriterBMP.create; +begin + inherited create; + FBpp:=24; + FRleCompress:=false; +end; + +{ Only for compatibility, BytesPerPixel should be removed } +{ ******************************************************* } +procedure TFPWriterBMP.SetColorSize (AValue : byte); +begin + SetBpp(AValue*8); +end; + +function TFPWriterBMP.GetColorSize : byte; +begin + if FBpp<>15 then Result:=FBpp div 8 + else Result:=2; +end; +{ ******************************************************* } + +procedure TFPWriterBMP.SetBpp (const abpp : byte); +begin + if not (abpp in [1,4,8,15,16,24,32]) then + raise FPImageException.Create('Invalid color depth'); + FBpp:=abpp; +end; + +procedure TFPWriterBMP.FillColorMap(Img : TFPCustomImage); +var BadPalette : boolean; + i : integer; +begin + BadPalette:=false; + if not Img.UsePalette then BadPalette:=true + else if Img.Palette.Count>(1 shl FBpp) then BadPalette:=true; + if BadPalette then + raise FPImageException.Create('Image palette is too big or absent'); + setlength(ColInfo,Img.Palette.Count); + BFI.ClrUsed:=Img.Palette.Count; + for i:=0 to BFI.ClrUsed-1 do + begin + ColInfo[i]:=FPColorToRGBA(Img.Palette.Color[i]); + ColInfo[i].A:=0; + end; +end; + +{ True 16 bit color is 5 bits red, 6 bits green and 5 bits blue. + Compression must be set to BI_BITFIELDS and we must specify masks for red, green and blue. + 16 bit without compression and masks is 5 bits per channel, so it's 15 bit even if in the header we + must write 16. + It's possible to provide custom masks but this is not compatible with windows9x, so we use 555 for 15 bit + and 565 for 16 bit. + Masks are longwords stored in the palette instead of palette entries (which are 4 bytes long too, with + components stored in following order: B G R A. Since we must write a low-endian longword, B is LSB and A + is the MSB). + We must write first red mask, then green and then blue. + + This sounds terribly confusing, if you don't understand take a look at + http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_1rw2.asp + } +procedure TFPWriterBMP.Setup16bpp; +var col : TColorRGBA; +begin + BFI.Compression:=BI_BITFIELDS; + setlength(ColInfo,3); + { A R G B + r := $0000F800 + g := $000007E0 + b := $0000001F + } + col.A:=0; Col.R:=0; { These are 0 for all the three masks} + { Red Mask } + Col.G:=$F8; Col.B:=0; + ColInfo[0]:=Col; + { Green Mask } + Col.G:=$07; Col.B:=$E0; + ColInfo[1]:=Col; + { Blue Mask } + Col.G:=$00; Col.B:=$1F; + ColInfo[2]:=Col; +end; + +{ 16 bit bpp with 555 packing (that is, 15 bit color) + This is bit dislocation: + 0RRR RRGG GGGB BBBB } + +function TFPWriterBMP.PackWord555(const col : TFPColor) : word; +var tmpcol : TColorRGB; + tmpr, tmpg, tmpb : word; +begin + tmpcol:=FPColorToRGB(col); + tmpb:=tmpcol.b shr 3; + tmpg:=tmpcol.g and $F8; tmpg:= tmpg shl 2; + tmpr:=tmpcol.r and $F8; tmpr:= tmpr shl 7; + tmpb:= tmpr or tmpg or tmpb; + {$IFDEF ENDIAN_BIG} + tmpb:=swap(tmpb); + {$ENDIF} + Result:=tmpb; +end; + +{ 16 bit bpp with 565 packing ) + This is bit dislocation: + RRRR RGGG GGGB BBBB } + +function TFPWriterBMP.PackWord565(const col : TFPColor) : word; +var tmpcol : TColorRGB; + tmpr, tmpg, tmpb : word; +begin + tmpcol:=FPColorToRGB(col); + tmpb:=tmpcol.b shr 3; + tmpg:=tmpcol.g and $FC; tmpg:= tmpg shl 3; + tmpr:=tmpcol.r and $F8; tmpr:= tmpr shl 8; + tmpb:= tmpr or tmpg or tmpb; + {$IFDEF ENDIAN_BIG} + tmpb:=swap(tmpb); + {$ENDIF} + Result:=tmpb; +end; + +{ First pixel in the most significant nibble, second one in LSN. If we are at the end of the line, + pad with zero } +function TFPWriterBMP.Pack4bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; +var b : byte; +begin + b:=(img.Pixels[Col,Row] and $F) shl 4; + if Col=0)) do + begin + if img.Pixels[Col,Row]<>0 then { set this bit } + b:=b+(1 shl sh); + dec(sh); + inc(Col); + end; + Result:=b; +end; + +function TFPWriterBMP.SaveHeader(Stream:TStream; Img : TFPCustomImage):boolean; +begin + Result:=False; + with BFI do + begin + Size:=sizeof(TBitMapInfoHeader); + Width:=Img.Width; + Height:=Img.Height; + Planes:=1; + if FBpp=15 then BitCount:=16 + else BitCount:=FBpp; + XPelsPerMeter:=100; + YPelsPerMeter:=100; + ClrImportant:=0; + end; + with BFH do + begin + bfType:=BMmagic;//'BM' + bfOffset:=sizeof(TBitMapFileHeader)+sizeof(TBitMapInfoHeader)+length(ColInfo)*4; + bfReserved:=0; + bfSize:=bfOffset+BFI.SizeImage; + end; + {$IFDEF ENDIAN_BIG} + SwapBMPFileHeader(BFH); + SwapBMPInfoHeader(BFI); + {$ENDIF} + StartPosition:=Stream.Position; + Stream.Write(bfh,sizeof(TBitMapFileHeader)); + Stream.Write(bfi,sizeof(TBitMapInfoHeader)); + {$IFDEF ENDIAN_BIG} + SwapBMPFileHeader(BFH); + SwapBMPInfoHeader(BFI); + {$ENDIF} + Result:=true; +end; + +{ This code is rather ugly and difficult to read, but compresses better than gimp. + Brief explanation: + A repetition is good if it's made of 3 elements at least: we have 2 bytes instead of 1. Let's call this a + "repetition" or "true repetition". + So we start finding the first repetition from current position. + Once found, we must decide how to handle elements between current position (i) and the repetition position (j) + if j-i = 0 we are on the repetition, so we encode it + if j-i = 1 there is only one pixel. We can't do anything but encode it as a repetition of 1 element. + if j-i = 2 we have two pixels. These can be a couple (a repetition of 2 elements) or 2 singles + (2 repetitions of 1 element) + if j-i > 2 we have two choices. In fact, we must consider that absolute mode is 2 bytes + length of chunk. + A repetition is always 2 bytes, so for 1 element we leak 1 byte, while for 2 elements we don't leak + any byte. + So if we have at most 1 single this means that everything else is made up of couples: it's best to + use repetitions so that we leak 0 to 1 byte. + If we have 2 singles or more it's better to use absolute mode, since we leak 2 bytes always, + without regard to the size of chunk. } + +procedure TFPWriterBMP.CompressScanLineRLE8(ALine : pbyte; const Row, Width : Integer; Stream : TStream); +var i, j, k, couples, singles : integer; + prev,tmp : byte; +begin + i:=0; + while (i=3 } + prev:=Aline[i]; + j:=i+1; + while ((jprev then break; + inc(j); + end; + tmp:=j-i; + Stream.Write(tmp,1); + Stream.Write(prev,1); + end; + 1 : begin { single value: we write a repetition of 1 } + tmp:=1; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + end; + 2 : begin + if couples=1 then { a couple: we write a repetition of 2 } + begin + tmp:=2; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + end + else { two singles: we write two repetitions of 1 each } + begin + tmp:=1; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + Stream.Write(tmp,1); + Stream.Write(Aline[i+1],1); + end; + end; + else { here we have two choices } + begin + if singles>1 then { it's cheaper to use absolute mode } + begin + tmp:=0; Stream.Write(tmp,1); { escape } + tmp:=j-i; Stream.Write(tmp,1); { number of pixels in absolute mode } + Stream.Write(Aline[i],j-i); { write these pixels... } + if ((tmp mod 2)<>0) then { we must end on a 2-byte boundary } + begin + tmp:=0; Stream.Write(tmp,1); { so pad with an additional zero } + end; + end + else { they're nearly all couples, don't use absolute mode } + begin + k:=i; + while (k E + 0316 => 161. + A repetition is good if it's made of five elements at least (2 bytes instead of 3). + In rle4 we consider "single" either a single nibble or 2 (a byte), while a couple is a repetition of 3 or 4 + elements. } + +procedure TFPWriterBMP.CompressScanLineRLE4(ALine : pbyte; const Row, Width : Integer; Stream : TStream); +var i, j, k, couples, singles, lastsingle : integer; + prev1, prev2, prev : word; + tmp : byte; + nibline : pbyte; { temporary array of nibbles } + even : boolean; +begin + getmem(nibline,width); + try + k:=(Width div 2) + (Width mod 2); + i:=0; + while (i(j-1) then + begin + inc(singles); { this is a single if next isn't a couple } + lastsingle:=j; + end; + prev:=nibline[j]; + end; + prev1:=prev2; + prev2:=prev; + even:=not even; + inc(j); + end; + if j>Width then j:=Width; { if j was Width-1 loop was skipped and j is Width+1, so we fix it } + + { ok, now that we know more about byte disposition we write data } + case (j-i) of + 0 : begin { there is a repetition with count>=5 } + even:=true; + prev1:=nibline[i]; + prev2:=nibline[i+1]; + j:=i+2; + while ((jprev1 then break; + if not even then if nibline[j]<>prev2 then break; + even:=not even; + inc(j); + end; + tmp:=j-i; + Stream.Write(tmp,1); + prev:=(prev1 shl 4) + (prev2 and $F); + tmp:=prev; + Stream.Write(tmp,1); + end; + 1 : begin { single value: we write a repetition of 1 } + tmp:=1; + Stream.Write(tmp,1); + tmp:=nibline[i] shl 4; + Stream.Write(tmp,1); + end; + 2 : begin { 2 singles in the same byte: we write a repetition of 2 } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end; + 3 : begin + if couples=1 then { a couple: we write a repetition of 3 } + begin + tmp:=3; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end + else + begin { 2 singles, 2 repetitions of 2 and 1 respectively } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + tmp:=1; + Stream.Write(tmp,1); + tmp:=nibline[i+2] shl 4; + Stream.Write(tmp,1); + end; + end; + 4 : begin + if singles=0 then { a couple: we write a repetition of 4 } + begin + tmp:=4; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end + else + begin { 2 singles, 2 repetitions of 2 each } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i+2] shl 4) + (nibline[i+3] and $F); + Stream.Write(tmp,1); + end; + end; + else { here we have two choices } + begin + if singles>1 then { it's cheaper to use absolute mode } + begin + tmp:=0; Stream.Write(tmp,1); { escape } + tmp:=j-i; Stream.Write(tmp,1); { number of pixels in absolute mode } + k:=i; + while (k0 then { we must end on a 2-byte boundary } + begin + tmp:=0; Stream.Write(tmp,1); { so pad with an additional zero } + end; + end + else { they're nearly all couples, don't use absolute mode } + begin + k:=i; + while (k=j) then tmp:=1 + else if ((k+31 then tmp:=tmp+(nibline[k+1] and $F); + Stream.Write(tmp,1); + inc(k,prev); + end; + end; + end; + end; + i:=j; + end; + tmp:=0; Stream.Write(tmp,1); { escape } + if Row=0 then { last line, end of file } + tmp:=1; + Stream.Write(tmp,1); + finally + FreeMem(nibline); + end; +end; + +procedure TFPWriterBMP.InternalWrite (Stream:TStream; Img:TFPCustomImage); +var + Row,Col,RowSize:Integer; + PadCount : byte; + aLine: PByte; + i : Integer; + tmppos : int64; + continue : boolean; + percent : byte; + percentinterval : longword; + percentacc : longword; + Rect : TRect; +begin + Rect.Left:=0; Rect.Top:=0; Rect.Right:=0; Rect.Bottom:=0; + continue:=true; + percent:=0; + percentinterval:=(Img.Height*4) div 100; + if percentinterval=0 then percentinterval:=$FFFFFFFF; + percentacc:=0; + Progress(psStarting,0,false,Rect,'',continue); + if not continue then exit; + if (FRLECompress and (not (FBpp in [4,8]))) then + raise FPImageException.Create('Can''t use RLE compression with '+IntToStr(FBpp)+' bits per pixel'); + if FRLECompress and (FBpp=4) then BFI.Compression:=BI_RLE4 + else if FRLECompress and (FBpp=8) then BFI.Compression:=BI_RLE8 + else BFI.Compression:=BI_RGB; + BFI.ClrUsed:=0; + try + if FBpp<=8 then FillColorMap(Img); { sets colormap and ClrUsed} + if FBpp=16 then Setup16bpp; { sets colormap with masks and Compression } + RowSize:=0; { just to keep the compiler quiet. } + case FBpp of + 1 : begin + RowSize:=Img.Width div 8; + if (Img.Width mod 8)<>0 then + inc(RowSize); + end; + 4 : begin + RowSize:=Img.Width div 2; + if (Img.Width mod 2)<>0 then + inc(RowSize); + end; + 8 : RowSize:=Img.Width; + 15 : RowSize:=Img.Width*2; + 16 : RowSize:=Img.Width*2; + 24 : RowSize:=Img.Width*3; + 32 : RowSize:=Img.Width*4; + end; + PadCount:=(4-(RowSize mod 4)) mod 4; { every row must end on 4 byte boundary } + inc(RowSize,PadCount); + BFI.SizeImage:=RowSize*Img.Height; + + SaveHeader(Stream,Img); { write the headers } + for i:=0 to length(ColInfo)-1 do { write the palette (or the masks in 16bpp case) } + Stream.Write(ColInfo[i],sizeof(TColorRGBA)); + + GetMem(aLine,RowSize); + try + for Row:=Img.Height-1 downto 0 do + begin + i:=0; Col:=0; + case FBpp of + 1 : while(Col=percentinterval then + begin + percent:=percent+(percentacc div percentinterval); + percentacc:=percentacc mod percentinterval; + Progress(psRunning,percent,false,Rect,'',continue); + if not continue then exit; + end; + end; + { If image is compressed we must fix the headers since we now know the size of the image } + if BFI.Compression in [BI_RLE4,BI_RLE8] then + begin + tmppos:=Stream.Position-StartPosition-BFH.bfOffset; + BFI.SizeImage:=tmppos; { set size of the image } + tmppos:=Stream.Position; { remember where we are } + Stream.Position:=StartPosition; { rewind to the beginning } + SaveHeader(Stream,Img); { rewrite headers (this will update BFH.Size too) } + Stream.Position:=tmppos; { restore our position } + end; + Progress(psEnding,100,false,Rect,'',continue); + finally + FreeMem(aLine); + end; + finally + setlength(ColInfo,0); + end; +end; + +initialization + ImageHandlers.RegisterImageWriter ('BMP Format', 'bmp', TFPWriterBMP); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pp b/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pp new file mode 100644 index 0000000..11ee57c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pp @@ -0,0 +1,734 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + BMP writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. +} +{*****************************************************************************} +{ 08/2005 by Giulio Bernardi: + - Removed FBytesPerPixel, BytesPerPixel property is now deprecated, use BitsPerPixel instead. + - Rewritten a large part of the file, so we can handle all bmp color depths + - Support for RLE4 and RLE8 encoding +} +//modified 2013 by Martin Schreiber + +{$mode objfpc}{$h+} +unit fpwritebmp; + +interface + +uses fpimage, classes, mclasses, sysutils, bmpcomn; + +type + + TFPWriterBMP = class (TFPCustomImageWriter) + private + StartPosition : int64; { save start of bitmap in the stream, if we must go back and fix something } + FBpp : byte; + FRLECompress : boolean; + BFH : TBitMapFileHeader; + BFI : TBitMapInfoHeader; + Colinfo : array of TColorRGBA; + procedure SetColorSize (AValue : Byte); + function GetColorSize : byte; + procedure SetBpp (const abpp : byte); + procedure FillColorMap(Img : TFPCustomImage); + procedure Setup16bpp; + function PackWord555(const col : TFPColor) : word; + function PackWord565(const col : TFPColor) : word; + function Pack4bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; + function Pack1bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; + procedure CompressScanLineRLE8(ALine : pbyte; const Row, Width : Integer; Stream : TStream); + procedure CompressScanLineRLE4(ALine : pbyte; const Row, Width : Integer; Stream : TStream); + protected + function SaveHeader(Stream:TStream; Img: TFPCustomImage):boolean; virtual; + procedure InternalWrite (Stream:TStream; Img: TFPCustomImage); override; + public + constructor Create; override; + property BitsPerPixel : byte read FBpp write SetBpp; + property RLECompress : boolean read FRleCompress write FRleCompress; + Property BytesPerPixel : Byte Read GetColorSize Write SetColorSize; deprecated; + end; + + +implementation + +Function FPColorToRGB(Const Color : TFPColor) : TColorRGB; + +begin + With Result,Color do + begin + R:=(Red and $FF00) shr 8; + G:=(Green and $FF00) shr 8; + B:=(Blue and $FF00) shr 8; + end; +end; + +Function FPColorToRGBA(Const Color : TFPColor) : TColorRGBA; + +begin + With Result,Color do + begin + R:=(Red and $FF00) shr 8; + G:=(Green and $FF00) shr 8; + B:=(Blue and $FF00) shr 8; + A:=(Alpha and $FF00) shr 8; + end; +end; + +constructor TFPWriterBMP.create; +begin + inherited create; + FBpp:=24; + FRleCompress:=false; +end; + +{ Only for compatibility, BytesPerPixel should be removed } +{ ******************************************************* } +procedure TFPWriterBMP.SetColorSize (AValue : byte); +begin + SetBpp(AValue*8); +end; + +function TFPWriterBMP.GetColorSize : byte; +begin + if FBpp<>15 then Result:=FBpp div 8 + else Result:=2; +end; +{ ******************************************************* } + +procedure TFPWriterBMP.SetBpp (const abpp : byte); +begin + if not (abpp in [1,4,8,15,16,24,32]) then + raise FPImageException.Create('Invalid color depth'); + FBpp:=abpp; +end; + +procedure TFPWriterBMP.FillColorMap(Img : TFPCustomImage); +var BadPalette : boolean; + i : integer; +begin + BadPalette:=false; + if not Img.UsePalette then BadPalette:=true + else if Img.Palette.Count>(1 shl FBpp) then BadPalette:=true; + if BadPalette then + raise FPImageException.Create('Image palette is too big or absent'); + setlength(ColInfo,Img.Palette.Count); + BFI.ClrUsed:=Img.Palette.Count; + for i:=0 to BFI.ClrUsed-1 do + begin + ColInfo[i]:=FPColorToRGBA(Img.Palette.Color[i]); + ColInfo[i].A:=0; + end; +end; + +{ True 16 bit color is 5 bits red, 6 bits green and 5 bits blue. + Compression must be set to BI_BITFIELDS and we must specify masks for red, green and blue. + 16 bit without compression and masks is 5 bits per channel, so it's 15 bit even if in the header we + must write 16. + It's possible to provide custom masks but this is not compatible with windows9x, so we use 555 for 15 bit + and 565 for 16 bit. + Masks are longwords stored in the palette instead of palette entries (which are 4 bytes long too, with + components stored in following order: B G R A. Since we must write a low-endian longword, B is LSB and A + is the MSB). + We must write first red mask, then green and then blue. + + This sounds terribly confusing, if you don't understand take a look at + http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_1rw2.asp + } +procedure TFPWriterBMP.Setup16bpp; +var col : TColorRGBA; +begin + BFI.Compression:=BI_BITFIELDS; + setlength(ColInfo,3); + { A R G B + r := $0000F800 + g := $000007E0 + b := $0000001F + } + col.A:=0; Col.R:=0; { These are 0 for all the three masks} + { Red Mask } + Col.G:=$F8; Col.B:=0; + ColInfo[0]:=Col; + { Green Mask } + Col.G:=$07; Col.B:=$E0; + ColInfo[1]:=Col; + { Blue Mask } + Col.G:=$00; Col.B:=$1F; + ColInfo[2]:=Col; +end; + +{ 16 bit bpp with 555 packing (that is, 15 bit color) + This is bit dislocation: + 0RRR RRGG GGGB BBBB } + +function TFPWriterBMP.PackWord555(const col : TFPColor) : word; +var tmpcol : TColorRGB; + tmpr, tmpg, tmpb : word; +begin + tmpcol:=FPColorToRGB(col); + tmpb:=tmpcol.b shr 3; + tmpg:=tmpcol.g and $F8; tmpg:= tmpg shl 2; + tmpr:=tmpcol.r and $F8; tmpr:= tmpr shl 7; + tmpb:= tmpr or tmpg or tmpb; + {$IFDEF ENDIAN_BIG} + tmpb:=swap(tmpb); + {$ENDIF} + Result:=tmpb; +end; + +{ 16 bit bpp with 565 packing ) + This is bit dislocation: + RRRR RGGG GGGB BBBB } + +function TFPWriterBMP.PackWord565(const col : TFPColor) : word; +var tmpcol : TColorRGB; + tmpr, tmpg, tmpb : word; +begin + tmpcol:=FPColorToRGB(col); + tmpb:=tmpcol.b shr 3; + tmpg:=tmpcol.g and $FC; tmpg:= tmpg shl 3; + tmpr:=tmpcol.r and $F8; tmpr:= tmpr shl 8; + tmpb:= tmpr or tmpg or tmpb; + {$IFDEF ENDIAN_BIG} + tmpb:=swap(tmpb); + {$ENDIF} + Result:=tmpb; +end; + +{ First pixel in the most significant nibble, second one in LSN. If we are at the end of the line, + pad with zero } +function TFPWriterBMP.Pack4bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; +var b : byte; +begin + b:=(img.Pixels[Col,Row] and $F) shl 4; + if Col=0)) do + begin + if img.Pixels[Col,Row]<>0 then { set this bit } + b:=b+(1 shl sh); + dec(sh); + inc(Col); + end; + Result:=b; +end; + +function TFPWriterBMP.SaveHeader(Stream:TStream; Img : TFPCustomImage):boolean; +begin + Result:=False; + with BFI do + begin + Size:=sizeof(TBitMapInfoHeader); + Width:=Img.Width; + Height:=Img.Height; + Planes:=1; + if FBpp=15 then BitCount:=16 + else BitCount:=FBpp; + XPelsPerMeter:=100; + YPelsPerMeter:=100; + ClrImportant:=0; + end; + with BFH do + begin + bfType:=BMmagic;//'BM' + bfOffset:=sizeof(TBitMapFileHeader)+sizeof(TBitMapInfoHeader)+length(ColInfo)*4; + bfReserved:=0; + bfSize:=bfOffset+BFI.SizeImage; + end; + {$IFDEF ENDIAN_BIG} + SwapBMPFileHeader(BFH); + SwapBMPInfoHeader(BFI); + {$ENDIF} + StartPosition:=Stream.Position; + Stream.Write(bfh,sizeof(TBitMapFileHeader)); + Stream.Write(bfi,sizeof(TBitMapInfoHeader)); + {$IFDEF ENDIAN_BIG} + SwapBMPFileHeader(BFH); + SwapBMPInfoHeader(BFI); + {$ENDIF} + Result:=true; +end; + +{ This code is rather ugly and difficult to read, but compresses better than gimp. + Brief explanation: + A repetition is good if it's made of 3 elements at least: we have 2 bytes instead of 1. Let's call this a + "repetition" or "true repetition". + So we start finding the first repetition from current position. + Once found, we must decide how to handle elements between current position (i) and the repetition position (j) + if j-i = 0 we are on the repetition, so we encode it + if j-i = 1 there is only one pixel. We can't do anything but encode it as a repetition of 1 element. + if j-i = 2 we have two pixels. These can be a couple (a repetition of 2 elements) or 2 singles + (2 repetitions of 1 element) + if j-i > 2 we have two choices. In fact, we must consider that absolute mode is 2 bytes + length of chunk. + A repetition is always 2 bytes, so for 1 element we leak 1 byte, while for 2 elements we don't leak + any byte. + So if we have at most 1 single this means that everything else is made up of couples: it's best to + use repetitions so that we leak 0 to 1 byte. + If we have 2 singles or more it's better to use absolute mode, since we leak 2 bytes always, + without regard to the size of chunk. } + +procedure TFPWriterBMP.CompressScanLineRLE8(ALine : pbyte; const Row, Width : Integer; Stream : TStream); +var i, j, k, couples, singles : integer; + prev,tmp : byte; +begin + i:=0; + while (i=3 } + prev:=Aline[i]; + j:=i+1; + while ((jprev then break; + inc(j); + end; + tmp:=j-i; + Stream.Write(tmp,1); + Stream.Write(prev,1); + end; + 1 : begin { single value: we write a repetition of 1 } + tmp:=1; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + end; + 2 : begin + if couples=1 then { a couple: we write a repetition of 2 } + begin + tmp:=2; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + end + else { two singles: we write two repetitions of 1 each } + begin + tmp:=1; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + Stream.Write(tmp,1); + Stream.Write(Aline[i+1],1); + end; + end; + else { here we have two choices } + begin + if singles>1 then { it's cheaper to use absolute mode } + begin + tmp:=0; Stream.Write(tmp,1); { escape } + tmp:=j-i; Stream.Write(tmp,1); { number of pixels in absolute mode } + Stream.Write(Aline[i],j-i); { write these pixels... } + if ((tmp mod 2)<>0) then { we must end on a 2-byte boundary } + begin + tmp:=0; Stream.Write(tmp,1); { so pad with an additional zero } + end; + end + else { they're nearly all couples, don't use absolute mode } + begin + k:=i; + while (k E + 0316 => 161. + A repetition is good if it's made of five elements at least (2 bytes instead of 3). + In rle4 we consider "single" either a single nibble or 2 (a byte), while a couple is a repetition of 3 or 4 + elements. } + +procedure TFPWriterBMP.CompressScanLineRLE4(ALine : pbyte; const Row, Width : Integer; Stream : TStream); +var i, j, k, couples, singles, lastsingle : integer; + prev1, prev2, prev : word; + tmp : byte; + nibline : pbyte; { temporary array of nibbles } + even : boolean; +begin + getmem(nibline,width); + try + k:=(Width div 2) + (Width mod 2); + i:=0; + while (i(j-1) then + begin + inc(singles); { this is a single if next isn't a couple } + lastsingle:=j; + end; + prev:=nibline[j]; + end; + prev1:=prev2; + prev2:=prev; + even:=not even; + inc(j); + end; + if j>Width then j:=Width; { if j was Width-1 loop was skipped and j is Width+1, so we fix it } + + { ok, now that we know more about byte disposition we write data } + case (j-i) of + 0 : begin { there is a repetition with count>=5 } + even:=true; + prev1:=nibline[i]; + prev2:=nibline[i+1]; + j:=i+2; + while ((jprev1 then break; + if not even then if nibline[j]<>prev2 then break; + even:=not even; + inc(j); + end; + tmp:=j-i; + Stream.Write(tmp,1); + prev:=(prev1 shl 4) + (prev2 and $F); + tmp:=prev; + Stream.Write(tmp,1); + end; + 1 : begin { single value: we write a repetition of 1 } + tmp:=1; + Stream.Write(tmp,1); + tmp:=nibline[i] shl 4; + Stream.Write(tmp,1); + end; + 2 : begin { 2 singles in the same byte: we write a repetition of 2 } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end; + 3 : begin + if couples=1 then { a couple: we write a repetition of 3 } + begin + tmp:=3; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end + else + begin { 2 singles, 2 repetitions of 2 and 1 respectively } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + tmp:=1; + Stream.Write(tmp,1); + tmp:=nibline[i+2] shl 4; + Stream.Write(tmp,1); + end; + end; + 4 : begin + if singles=0 then { a couple: we write a repetition of 4 } + begin + tmp:=4; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end + else + begin { 2 singles, 2 repetitions of 2 each } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i+2] shl 4) + (nibline[i+3] and $F); + Stream.Write(tmp,1); + end; + end; + else { here we have two choices } + begin + if singles>1 then { it's cheaper to use absolute mode } + begin + tmp:=0; Stream.Write(tmp,1); { escape } + tmp:=j-i; Stream.Write(tmp,1); { number of pixels in absolute mode } + k:=i; + while (k0 then { we must end on a 2-byte boundary } + begin + tmp:=0; Stream.Write(tmp,1); { so pad with an additional zero } + end; + end + else { they're nearly all couples, don't use absolute mode } + begin + k:=i; + while (k=j) then tmp:=1 + else if ((k+31 then tmp:=tmp+(nibline[k+1] and $F); + Stream.Write(tmp,1); + inc(k,prev); + end; + end; + end; + end; + i:=j; + end; + tmp:=0; Stream.Write(tmp,1); { escape } + if Row=0 then { last line, end of file } + tmp:=1; + Stream.Write(tmp,1); + finally + FreeMem(nibline); + end; +end; + +procedure TFPWriterBMP.InternalWrite (Stream:TStream; Img:TFPCustomImage); +var + Row,Col,RowSize:Integer; + PadCount : byte; + aLine: PByte; + i : Integer; + tmppos : int64; + continue : boolean; + percent : byte; + percentinterval : longword; + percentacc : longword; + Rect : TRect; +begin + Rect.Left:=0; Rect.Top:=0; Rect.Right:=0; Rect.Bottom:=0; + continue:=true; + percent:=0; + percentinterval:=(Img.Height*4) div 100; + if percentinterval=0 then percentinterval:=$FFFFFFFF; + percentacc:=0; + Progress(psStarting,0,false,Rect,'',continue); + if not continue then exit; + if (FRLECompress and (not (FBpp in [4,8]))) then + raise FPImageException.Create('Can''t use RLE compression with '+IntToStr(FBpp)+' bits per pixel'); + if FRLECompress and (FBpp=4) then BFI.Compression:=BI_RLE4 + else if FRLECompress and (FBpp=8) then BFI.Compression:=BI_RLE8 + else BFI.Compression:=BI_RGB; + BFI.ClrUsed:=0; + try + if FBpp<=8 then FillColorMap(Img); { sets colormap and ClrUsed} + if FBpp=16 then Setup16bpp; { sets colormap with masks and Compression } + RowSize:=0; { just to keep the compiler quiet. } + case FBpp of + 1 : begin + RowSize:=Img.Width div 8; + if (Img.Width mod 8)<>0 then + inc(RowSize); + end; + 4 : begin + RowSize:=Img.Width div 2; + if (Img.Width mod 2)<>0 then + inc(RowSize); + end; + 8 : RowSize:=Img.Width; + 15 : RowSize:=Img.Width*2; + 16 : RowSize:=Img.Width*2; + 24 : RowSize:=Img.Width*3; + 32 : RowSize:=Img.Width*4; + end; + PadCount:=(4-(RowSize mod 4)) mod 4; { every row must end on 4 byte boundary } + inc(RowSize,PadCount); + BFI.SizeImage:=RowSize*Img.Height; + + SaveHeader(Stream,Img); { write the headers } + for i:=0 to length(ColInfo)-1 do { write the palette (or the masks in 16bpp case) } + Stream.Write(ColInfo[i],sizeof(TColorRGBA)); + + GetMem(aLine,RowSize); + try + for Row:=Img.Height-1 downto 0 do + begin + i:=0; Col:=0; + case FBpp of + 1 : while(Col=percentinterval then + begin + percent:=percent+(percentacc div percentinterval); + percentacc:=percentacc mod percentinterval; + Progress(psRunning,percent,false,Rect,'',continue); + if not continue then exit; + end; + end; + { If image is compressed we must fix the headers since we now know the size of the image } + if BFI.Compression in [BI_RLE4,BI_RLE8] then + begin + tmppos:=Stream.Position-StartPosition-BFH.bfOffset; + BFI.SizeImage:=tmppos; { set size of the image } + tmppos:=Stream.Position; { remember where we are } + Stream.Position:=StartPosition; { rewind to the beginning } + SaveHeader(Stream,Img); { rewrite headers (this will update BFH.Size too) } + Stream.Position:=tmppos; { restore our position } + end; + Progress(psEnding,100,false,Rect,'',continue); + finally + FreeMem(aLine); + end; + finally + setlength(ColInfo,0); + end; +end; + +initialization + ImageHandlers.RegisterImageWriter ('BMP Format', 'bmp', TFPWriterBMP); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritejpeg.pas b/mseide-msegui/lib/common/fpccompatibility/fpwritejpeg.pas new file mode 100644 index 0000000..f09c61d --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritejpeg.pas @@ -0,0 +1,226 @@ +{ Copyright (C) 2003 Mattias Gaertner + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This 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 Library General Public License + for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} + +//modified 2013 by Martin Schreiber + +unit FPWriteJPEG; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, mclasses,SysUtils, FPImage, JPEGLib_del, FPReadJPEG, + JcAPIstd_del, JcAPImin_del, JDataDst_del, JcParam_del, JError_del; + +type + { TFPWriterJPEG } + + TFPJPEGCompressionQuality = 1..100; // 100 = best quality, 25 = pretty awful + + TFPWriterJPEG = class(TFPCustomImageWriter) + private + FGrayscale: boolean; + FInfo: jpeg_compress_struct; + FError: jpeg_error_mgr; + FProgressiveEncoding: boolean; + FQuality: TFPJPEGCompressionQuality; + FProgressMgr: TFPJPEGProgressManager; + protected + procedure InternalWrite(Str: TStream; Img: TFPCustomImage); override; + public + constructor Create; override; + destructor Destroy; override; + property CompressionQuality: TFPJPEGCompressionQuality read FQuality write FQuality; + property ProgressiveEncoding: boolean read FProgressiveEncoding write FProgressiveEncoding; + property GrayScale: boolean read FGrayscale; + end; + +implementation + +procedure JPEGError(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + {$ifdef FPC_Debug_Image} + writeln('JPEGError ',CurInfo^.err^.msg_code,' '); + {$endif} + raise Exception.CreateFmt('JPEG error',[CurInfo^.err^.msg_code]); +end; + +procedure EmitMessage(CurInfo: j_common_ptr; msg_level: Integer); +begin + if CurInfo=nil then exit; + if msg_level=0 then ; +end; + +procedure OutputMessage(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; +end; + +procedure FormatMessage(CurInfo: j_common_ptr; var buffer: string); +begin + if CurInfo=nil then exit; + {$ifdef FPC_Debug_Image} + writeln('FormatMessage ',buffer); + {$endif} +end; + +procedure ResetErrorMgr(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + CurInfo^.err^.num_warnings := 0; + CurInfo^.err^.msg_code := 0; +end; + +var + jpeg_std_error: jpeg_error_mgr; + +procedure ProgressCallback(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + // ToDo +end; + +{ TFPWriterJPEG } + +procedure TFPWriterJPEG.InternalWrite(Str: TStream; Img: TFPCustomImage); +var + MemStream: TMemoryStream; + Continue: Boolean; + + procedure InitWriting; + begin + FillChar(FInfo, sizeof(FInfo), 0); + FError := jpeg_std_error; + FInfo.err := jerror_del.jpeg_std_error(FError); + + jpeg_create_compress(@FInfo); + FProgressMgr.pub.progress_monitor := @ProgressCallback; + FProgressMgr.instance := Self; + FInfo.progress := @FProgressMgr.pub; + end; + + procedure SetDestination; + begin + if Str is TMemoryStream then + MemStream:=TMemoryStream(Str) + else + MemStream := TMemoryStream.Create; + jpeg_stdio_dest(@FInfo, @MemStream); + end; + + procedure WriteHeader; + begin + FInfo.image_width := Img.Width; + FInfo.image_height := Img.Height; + FInfo.input_components := 3; // RGB has 3 components + FInfo.in_color_space := JCS_RGB; + if FGrayscale then + jpeg_set_colorspace(@FInfo, JCS_GRAYSCALE); + + jpeg_set_defaults(@FInfo); + jpeg_set_quality(@FInfo, FQuality, True); + + if ProgressiveEncoding then + jpeg_simple_progression(@FInfo); + end; + + procedure WritePixels; + var + LinesWritten: Cardinal; + SampArray: JSAMPARRAY; + SampRow: JSAMPROW; + Color: TFPColor; + x: Integer; + y: Integer; + begin + Progress(psStarting, 0, False, Rect(0,0,0,0), '', Continue); + if not Continue then exit; + jpeg_start_compress(@FInfo, True); + + // write one line per call + GetMem(SampArray,SizeOf(JSAMPROW)); + GetMem(SampRow,FInfo.image_width*FInfo.input_components); + SampArray^[0]:=SampRow; + try + y:=0; + while (FInfo.next_scanline < FInfo.image_height) do begin + for x:=0 to FInfo.image_width-1 do begin + Color:=Img.Colors[x,y]; + SampRow^[x*3+0]:=Color.Red shr 8; + SampRow^[x*3+1]:=Color.Green shr 8; + SampRow^[x*3+2]:=Color.Blue shr 8; + end; + LinesWritten := jpeg_write_scanlines(@FInfo, SampArray, 1); + if LinesWritten<1 then break; + inc(y); + end; + finally + FreeMem(SampRow); + FreeMem(SampArray); + end; + + jpeg_finish_compress(@FInfo); + Progress(psEnding, 100, False, Rect(0,0,0,0), '', Continue); + end; + + procedure EndWriting; + begin + jpeg_destroy_compress(@FInfo); + end; + +begin + Continue := true; + MemStream:=nil; + try + InitWriting; + SetDestination; + WriteHeader; + WritePixels; + if MemStream<>Str then begin + MemStream.Position:=0; + Str.CopyFrom(MemStream,MemStream.Size); + end; + finally + EndWriting; + if MemStream<>Str then + MemStream.Free; + end; +end; + +constructor TFPWriterJPEG.Create; +begin + inherited Create; + FQuality:=75; +end; + +destructor TFPWriterJPEG.Destroy; +begin + inherited Destroy; +end; + +initialization + with jpeg_std_error do begin + error_exit:=@JPEGError; + emit_message:=@EmitMessage; + output_message:=@OutputMessage; + format_message:=@FormatMessage; + reset_error_mgr:=@ResetErrorMgr; + end; + ImageHandlers.RegisterImageWriter ('JPEG graphics', 'jpg;jpeg', TFPWriterJPEG); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritepcx.pas b/mseide-msegui/lib/common/fpccompatibility/fpwritepcx.pas new file mode 100644 index 0000000..7d8d38b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritepcx.pas @@ -0,0 +1,156 @@ +{ Copyright (C) 2007 Laurent Jacques + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This 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 Library General Public License + for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Save in format 24 bits compressed or not +} + +unit FPWritePCX; + +{$mode objfpc}{$H+} + +interface + +uses FPImage, Classes, SysUtils; + +type + + TFPWriterPCX = class(TFPCustomImageWriter) + private + FCompressed: boolean; + protected + function SaveHeader(Stream: TStream; Img: TFPCustomImage): boolean; virtual; + procedure InternalWrite(Stream: TStream; Img: TFPCustomImage); override; + procedure writeline(Stream: TStream; buffer: PByte; bytes: integer); + public + property Compressed: boolean Read FCompressed Write FCompressed; + end; + +implementation + +uses pcxcomn; + +function TFPWriterPCX.SaveHeader(Stream: TStream; Img: TFPCustomImage): boolean; +var + Header: TPCXHeader; +begin + Result := False; + FillChar(Header, SizeOf(Header), 0); + with Header do + begin + FileID := $0a; + Version := 5; + if Compressed then + Encoding := 1 + else + Encoding := 0; + BitsPerPixel := 8; + XMin := 0; + YMin := 0; + XMax := Img.Width - 1; + YMax := Img.Height - 1; + HRes := 300; + VRes := 300; + ColorPlanes := 3; + BytesPerLine := Img.Width; + PaletteType := 1; + end; + Stream.WriteBuffer(Header, SizeOf(Header)); + Result := True; +end; + +procedure TFPWriterPCX.writeline(Stream: TStream; buffer: PByte; bytes: integer); +var + Value, Count: byte; + tmp: byte; + P: PByte; +begin + P := Buffer; + while bytes > 0 do + begin + Value := P[0]; + Inc(P); + Dec(bytes); + Count := 1; + while (bytes < 0) and (Count < 63) and (P[0] = Value) do + begin + Inc(Count); + Inc(P); + Dec(bytes); + end; + if (Value < $c0) and (Count = 1) then + begin + Stream.Write(Value, 1); + end + else + begin + tmp := $c0 + Count; + Stream.Write(tmp, 1); + Stream.Write(Value, 1); + end; + end; +end; + +procedure TFPWriterPCX.InternalWrite(Stream: TStream; Img: TFPCustomImage); +var + Row, Col, WriteSize: integer; + Aline, P: PByte; + C: TFPColor; + Totalwrite: longint; + continue: boolean; + Rect: TRect; +begin + Rect.Left := 0; + Rect.Top := 0; + Rect.Right := 0; + Rect.Bottom := 0; + continue := True; + TotalWrite := 0; + Progress(psStarting, 0, False, Rect, '', continue); + SaveHeader(Stream, Img); + WriteSize := (Img.Width * 3); + GetMem(aLine, WriteSize); + TotalWrite := Img.Height * Img.Width; + try + for Row := 0 to Img.Height - 1 do + begin + P := ALine; + for Col := 0 to Img.Width - 1 do + begin + C := Img.Colors[Col, Row]; + P[Col + Img.Width * 2] := C.Blue shr 8; + P[Col + Img.Width] := C.Green shr 8; + P[Col] := C.Red shr 8; + Progress(psRunning, trunc(100.0 * (Row * Col / TotalWrite)), + False, Rect, '', continue); + if not continue then + exit; + end; + if Compressed then + writeline(Stream, aLine, WriteSize) + else + Stream.Write(aLine[0], WriteSize); + end; + Progress(psEnding, 100, False, Rect, '', continue); + finally + FreeMem(aLine); + end; +end; + +{ end TFPWriterPCX} + +initialization + ImageHandlers.RegisterImageWriter('PCX Format', 'pcx', TFPWriterPCX); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritepng.pp b/mseide-msegui/lib/common/fpccompatibility/fpwritepng.pp new file mode 100644 index 0000000..58ca209 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritepng.pp @@ -0,0 +1,757 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + XPM writer class. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +{$mode objfpc}{$h+} +unit FPWritePNG; + +interface + +uses sysutils, classes, mclasses, FPImage, FPImgCmn, PNGComn, ZStream; + +type + + TGetPixelFunc = function (x,y : LongWord) : TColorData of object; + + TColorFormatFunction = function (color:TFPColor) : TColorData of object; + + TFPWriterPNG = class (TFPCustomImageWriter) + private + FUsetRNS, FCompressedText, FWordSized, FIndexed, + FUseAlpha, FGrayScale : boolean; + FByteWidth : byte; + FChunk : TChunk; + CFmt : TColorFormat; // format of the colors to convert from + FFmtColor : TColorFormatFunction; + FTransparentColor : TFPColor; + FSwitchLine, FCurrentLine, FPreviousLine : pByteArray; + FPalette : TFPPalette; + OwnsPalette : boolean; + FHeader : THeaderChunk; + FGetPixel : TGetPixelFunc; + FDatalineLength : longword; + ZData : TMemoryStream; // holds uncompressed data until all blocks are written + Compressor : TCompressionStream; // compresses the data + FCompressionLevel : TCompressionLevel; + procedure WriteChunk; + function GetColorPixel (x,y:longword) : TColorData; + function GetPalettePixel (x,y:longword) : TColorData; + function GetColPalPixel (x,y:longword) : TColorData; + procedure InitWriteIDAT; + procedure Gatherdata; + procedure WriteCompressedData; + procedure FinalWriteIDAT; + protected + property Header : THeaderChunk read FHeader; + procedure InternalWrite (Str:TStream; Img:TFPCustomImage); override; + procedure WriteIHDR; virtual; + procedure WritePLTE; virtual; + procedure WritetRNS; virtual; + procedure WriteIDAT; virtual; + procedure WriteTexts; virtual; + procedure WriteIEND; virtual; + function CurrentLine (x:longword) : byte; + function PrevSample (x:longword): byte; + function PreviousLine (x:longword) : byte; + function PrevLinePrevSample (x:longword): byte; + function DoFilter (LineFilter:byte;index:longword; b:byte) : byte; virtual; + procedure SetChunkLength (aValue : longword); + procedure SetChunkType (ct : TChunkTypes); + procedure SetChunkType (ct : TChunkCode); + function DecideGetPixel : TGetPixelFunc; virtual; + procedure DetermineHeader (var AHeader : THeaderChunk); virtual; + function DetermineFilter (Current, Previous:PByteArray; linelength:longword):byte; virtual; + procedure FillScanLine (y : integer; ScanLine : pByteArray); virtual; + function ColorDataGrayB(color:TFPColor) : TColorData; + function ColorDataColorB(color:TFPColor) : TColorData; + function ColorDataGrayW(color:TFPColor) : TColorData; + function ColorDataColorW(color:TFPColor) : TColorData; + function ColorDataGrayAB(color:TFPColor) : TColorData; + function ColorDataColorAB(color:TFPColor) : TColorData; + function ColorDataGrayAW(color:TFPColor) : TColorData; + function ColorDataColorAW(color:TFPColor) : TColorData; + property ChunkDataBuffer : pByteArray read FChunk.data; + property UsetRNS : boolean read FUsetRNS; + property SingleTransparentColor : TFPColor read FTransparentColor; + property ThePalette : TFPPalette read FPalette; + property ColorFormat : TColorformat read CFmt; + property ColorFormatFunc : TColorFormatFunction read FFmtColor; + property byteWidth : byte read FByteWidth; + property DatalineLength : longword read FDatalineLength; + public + constructor create; override; + destructor destroy; override; + property GrayScale : boolean read FGrayscale write FGrayScale; + property Indexed : boolean read FIndexed write FIndexed; + property CompressedText : boolean read FCompressedText write FCompressedText; + property WordSized : boolean read FWordSized write FWordSized; + property UseAlpha : boolean read FUseAlpha write FUseAlpha; + property CompressionLevel : TCompressionLevel read FCompressionLevel write FCompressionLevel; + end; + +implementation + +constructor TFPWriterPNG.create; +begin + inherited; + Fchunk.acapacity := 0; + Fchunk.data := nil; + FGrayScale := False; + FIndexed := False; + FCompressedText := True; + FWordSized := True; + FUseAlpha := False; + FCompressionLevel:=clDefault; +end; + +destructor TFPWriterPNG.destroy; +begin + if OwnsPalette then FreeAndNil(FPalette); + with Fchunk do + if acapacity > 0 then + freemem (data); + inherited; +end; + +procedure TFPWriterPNG.WriteChunk; +var chead : TChunkHeader; + c : longword; +begin + with FChunk do + begin + {$IFDEF ENDIAN_LITTLE} + chead.CLength := swap (alength); + {$ELSE} + chead.CLength := alength; + {$ENDIF} + if (ReadType = '') then + if atype <> ctUnknown then + chead.CType := ChunkTypes[aType] + else + raise PNGImageException.create ('Doesn''t have a chunktype to write') + else + chead.CType := ReadType; + c := CalculateCRC (All1Bits, ReadType, sizeOf(ReadType)); + c := CalculateCRC (c, data^, alength); + {$IFDEF ENDIAN_LITTLE} + crc := swap(c xor All1Bits); + {$ELSE} + crc := c xor All1Bits; + {$ENDIF} + with TheStream do + begin + Write (chead, sizeof(chead)); + Write (data^[0], alength); + Write (crc, sizeof(crc)); + end; + end; +end; + +procedure TFPWriterPNG.SetChunkLength(aValue : longword); +begin + with Fchunk do + begin + alength := aValue; + if aValue > acapacity then + begin + if acapacity > 0 then + freemem (data); + GetMem (data, alength); + acapacity := alength; + end; + end; +end; + +procedure TFPWriterPNG.SetChunkType (ct : TChunkTypes); +begin + with Fchunk do + begin + aType := ct; + ReadType := ChunkTypes[ct]; + end; +end; + +procedure TFPWriterPNG.SetChunkType (ct : TChunkCode); +begin + with FChunk do + begin + ReadType := ct; + aType := low(TChunkTypes); + while (aType < high(TChunkTypes)) and (ChunkTypes[aType] <> ct) do + inc (aType); + end; +end; + +function TFPWriterPNG.CurrentLine(x:longword):byte; +begin + result := FCurrentLine^[x]; +end; + +function TFPWriterPNG.PrevSample (x:longword): byte; +begin + if x < byteWidth then + result := 0 + else + result := FCurrentLine^[x - bytewidth]; +end; + +function TFPWriterPNG.PreviousLine (x:longword) : byte; +begin + result := FPreviousline^[x]; +end; + +function TFPWriterPNG.PrevLinePrevSample (x:longword): byte; +begin + if x < byteWidth then + result := 0 + else + result := FPreviousLine^[x - bytewidth]; +end; + +function TFPWriterPNG.DoFilter(LineFilter:byte;index:longword; b:byte) : byte; +var diff : byte; + procedure FilterSub; + begin + diff := PrevSample(index); + end; + procedure FilterUp; + begin + diff := PreviousLine(index); + end; + procedure FilterAverage; + var l, p : word; + begin + l := PrevSample(index); + p := PreviousLine(index); + Diff := (l + p) div 2; + end; + procedure FilterPaeth; + var dl, dp, dlp : word; // index for previous and distances for: + l, p, lp : byte; // r:predictor, Left, Previous, LeftPrevious + r : integer; + begin + l := PrevSample(index); + lp := PrevLinePrevSample(index); + p := PreviousLine(index); + r := l + p - lp; + dl := abs (r - l); + dlp := abs (r - lp); + dp := abs (r - p); + if (dl <= dp) and (dl <= dlp) then + diff := l + else if dp <= dlp then + diff := p + else + diff := lp; + end; +begin + case LineFilter of + 0 : diff := 0; + 1 : FilterSub; + 2 : FilterUp; + 3 : FilterAverage; + 4 : FilterPaeth; + end; + if diff > b then + result := (b + $100 - diff) + else + result := b - diff; +end; + +procedure TFPWriterPNG.DetermineHeader (var AHeader : THeaderChunk); +var c : integer; + function CountAlphas : integer; + var none, half : boolean; + x,y : longint; // warning, checks on <0 ! + p : integer; + c : TFPColor; + a : word; + begin + half := false; + none := false; + with TheImage do + if UsePalette then + with Palette do + begin + p := count-1; + FTransparentColor.alpha := alphaOpaque; + while (p >= 0) do + begin + c := color[p]; + a := c.Alpha; + if a = alphaTransparent then + begin + none := true; + FTransparentColor := c; + end + else if a <> alphaOpaque then + begin + half := true; + if FtransparentColor.alpha < a then + FtransparentColor := c; + end; + dec (p); + end; + end + else + begin + x := width-1; + y := height-1; + FTransparentColor.alpha := alphaOpaque; + while (y >= 0) and not (half and none) do + begin + c := colors[x,y]; + a := c.Alpha; + if a = alphaTransparent then + begin + none := true; + FTransparentColor := c; + end + else if a <> alphaOpaque then + begin + half := true; + if FtransparentColor.alpha < a then + FtransparentColor := c; + end; + dec (x); + if (x < 0) then + begin + dec (y); + x := width-1; + end; + end; + end; + result := 1; + if none then + inc (result); + if half then + inc (result); + end; + procedure DetermineColorFormat; + begin + with AHeader do + case colortype of + 0 : if FWordSized then + begin + FFmtColor := @ColorDataGrayW; + FByteWidth := 2; + //CFmt := cfGray16 + end + else + begin + FFmtColor := @ColorDataGrayB; + FByteWidth := 1; + //CFmt := cfGray8; + end; + 2 : if FWordSized then + begin + FFmtColor := @ColorDataColorW; + FByteWidth := 6; + //CFmt := cfBGR48 + end + else + begin + FFmtColor := @ColorDataColorB; + FByteWidth := 3; + //CFmt := cfBGR24; + end; + 4 : if FWordSized then + begin + FFmtColor := @ColorDataGrayAW; + FByteWidth := 4; + //CFmt := cfGrayA32 + end + else + begin + FFmtColor := @ColorDataGrayAB; + FByteWidth := 2; + //CFmt := cfGrayA16; + end; + 6 : if FWordSized then + begin + FFmtColor := @ColorDataColorAW; + FByteWidth := 8; + //CFmt := cfABGR64 + end + else + begin + FFmtColor := @ColorDataColorAB; + FByteWidth := 4; + //CFmt := cfABGR32; + end; + end; + end; +begin + with AHeader do + begin + {$IFDEF ENDIAN_LITTLE} + // problem: TheImage has integer width, PNG header longword width. + // Integer Swap can give negative value + Width := swap (longword(TheImage.Width)); + height := swap (longword(TheImage.Height)); + {$ELSE} + Width := TheImage.Width; + height := TheImage.Height; + {$ENDIF} + if FUseAlpha then + c := CountAlphas + else + c := 0; + if FIndexed then + begin + if OwnsPalette then FreeAndNil(FPalette); + OwnsPalette := not TheImage.UsePalette; + if OwnsPalette then + begin + FPalette := TFPPalette.Create (16); + FPalette.Build (TheImage); + end + else + FPalette := TheImage.Palette; + if ThePalette.count > 256 then + raise PNGImageException.Create ('Too many colors to use indexed PNG color type'); + ColorType := 3; + FUsetRNS := C > 1; + BitDepth := 8; + FByteWidth := 1; + end + else + begin + if c = 3 then + ColorType := 4; + FUsetRNS := (c = 2); + if not FGrayScale then + ColorType := ColorType + 2; + if FWordSized then + BitDepth := 16 + else + BitDepth := 8; + DetermineColorFormat; + end; + Compression := 0; + Filter := 0; + Interlace := 0; + end; +end; + +procedure TFPWriterPNG.WriteIHDR; +begin + // signature for PNG + TheStream.writeBuffer(Signature,sizeof(Signature)); + // Determine all settings for filling the header + fillchar(fheader,sizeof(fheader),#0); + DetermineHeader (FHeader); + // write the header chunk + SetChunkLength (13); // (sizeof(FHeader)); gives 14 and is wrong !! + move (FHeader, ChunkDataBuffer^, 13); // sizeof(FHeader)); + SetChunkType (ctIHDR); + WriteChunk; +end; + +{ Color convertions } + +function TFPWriterPNG.ColorDataGrayB(color:TFPColor) : TColorData; +var t : word; +begin + t := CalculateGray (color); + result := hi(t); +end; + +function TFPWriterPNG.ColorDataGrayW(color:TFPColor) : TColorData; +begin + result := CalculateGray (color); +end; + +function TFPWriterPNG.ColorDataGrayAB(color:TFPColor) : TColorData; +begin + result := ColorDataGrayB (color); + result := (result shl 8) and hi(color.Alpha); +end; + +function TFPWriterPNG.ColorDataGrayAW(color:TFPColor) : TColorData; +begin + result := ColorDataGrayW (color); + result := (result shl 16) and color.Alpha; +end; + +function TFPWriterPNG.ColorDataColorB(color:TFPColor) : TColorData; +begin + with color do + result := hi(red) + (green and $FF00) + (hi(blue) shl 16); +end; + +function TFPWriterPNG.ColorDataColorW(color:TFPColor) : TColorData; +begin + with color do + result := red + (green shl 16) + (qword(blue) shl 32); +end; + +function TFPWriterPNG.ColorDataColorAB(color:TFPColor) : TColorData; +begin + with color do + result := hi(red) + (green and $FF00) + (hi(blue) shl 16) + (hi(alpha) shl 24); +end; + +function TFPWriterPNG.ColorDataColorAW(color:TFPColor) : TColorData; +begin + with color do + result := red + (green shl 16) + (qword(blue) shl 32) + (qword(alpha) shl 48); +end; + +{ Data making routines } + +function TFPWriterPNG.GetColorPixel (x,y:longword) : TColorData; +begin + result := FFmtColor (TheImage[x,y]); + //result := ConvertColorToData(TheImage.Colors[x,y],CFmt); +end; + +function TFPWriterPNG.GetPalettePixel (x,y:longword) : TColorData; +begin + result := TheImage.Pixels[x,y]; +end; + +function TFPWriterPNG.GetColPalPixel (x,y:longword) : TColorData; +begin + result := ThePalette.IndexOf (TheImage.Colors[x,y]); +end; + +function TFPWriterPNG.DecideGetPixel : TGetPixelFunc; +begin + case Fheader.colortype of + 3 : if TheImage.UsePalette then + begin + result := @GetPalettePixel; + end + else + begin + result := @GetColPalPixel; + end; + else begin + result := @GetColorPixel; + end + end; +end; + +procedure TFPWriterPNG.WritePLTE; +var r,t : integer; + c : TFPColor; +begin + with ThePalette do + begin + SetChunkLength (count*3); + SetChunkType (ctPLTE); + t := 0; + For r := 0 to count-1 do + begin + c := Color[r]; + ChunkdataBuffer^[t] := c.red div 256; + inc (t); + ChunkdataBuffer^[t] := c.green div 256; + inc (t); + ChunkdataBuffer^[t] := c.blue div 256; + inc (t); + end; + end; + WriteChunk; +end; + +procedure TFPWriterPNG.InitWriteIDAT; +begin + FDatalineLength := TheImage.Width*ByteWidth; + GetMem (FPreviousLine, FDatalineLength); + GetMem (FCurrentLine, FDatalineLength); + fillchar (FCurrentLine^,FDatalineLength,0); + ZData := TMemoryStream.Create; + Compressor := TCompressionStream.Create (FCompressionLevel,ZData); + FGetPixel := DecideGetPixel; +end; + +procedure TFPWriterPNG.FinalWriteIDAT; +begin + ZData.Free; + FreeMem (FPreviousLine); + FreeMem (FCurrentLine); +end; + +function TFPWriterPNG.DetermineFilter (Current, Previous:PByteArray; linelength:longword) : byte; +begin + result := 0; +end; + +procedure TFPWriterPNG.FillScanLine (y : integer; ScanLine : pByteArray); +var r, x : integer; + cd : TColorData; + index : longword; + b : byte; +begin + index := 0; + for x := 0 to pred(TheImage.Width) do + begin + cd := FGetPixel (x,y); + {$IFDEF ENDIAN_BIG} + cd:=swap(cd); + {$ENDIF} + move (cd, ScanLine^[index], FBytewidth); + if WordSized then + begin + r := 1; + while (r < FByteWidth) do + begin + b := Scanline^[index+r]; + Scanline^[index+r] := Scanline^[index+r-1]; + Scanline^[index+r-1] := b; + inc (r,2); + end; + end; + inc (index, FByteWidth); + end; +end; + +procedure TFPWriterPNG.GatherData; +var x,y : integer; + lf : byte; +begin + for y := 0 to pred(TheImage.height) do + begin + FSwitchLine := FCurrentLine; + FCurrentLine := FPreviousLine; + FPreviousLine := FSwitchLine; + FillScanLine (y, FCurrentLine); + lf := DetermineFilter (FCurrentLine, FpreviousLine, FDataLineLength); + for x := 0 to FDatalineLength-1 do + FCurrentLine^[x] := DoFilter (lf, x, FCurrentLine^[x]); + Compressor.Write (lf, sizeof(lf)); + Compressor.Write (FCurrentLine^, FDataLineLength); + end; +end; + +procedure TFPWriterPNG.WriteCompressedData; +var l : longword; +begin + Compressor.Free; // Close compression and finish the writing in ZData + l := ZData.position; + ZData.position := 0; + SetChunkLength(l); + SetChunkType (ctIDAT); + ZData.Read (ChunkdataBuffer^, l); + WriteChunk; +end; + +procedure TFPWriterPNG.WriteIDAT; +begin + InitWriteIDAT; + GatherData; + WriteCompressedData; + FinalWriteIDAT; +end; + +procedure TFPWriterPNG.WritetRNS; + procedure PaletteAlpha; + var r : integer; + begin + with TheImage.palette do + begin + // search last palette entry with transparency + r := count; + repeat + dec (r); + until (r < 0) or (color[r].alpha <> alphaOpaque); + if r >= 0 then // there is at least 1 transparent color + begin + // from this color we go to the first palette entry + SetChunkLength (r+1); + repeat + chunkdatabuffer^[r] := (color[r].alpha shr 8); + dec (r); + until (r < 0); + end; + writechunk; + end; + end; + procedure GrayAlpha; + var g : word; + begin + SetChunkLength(2); + if WordSized then + g := CalculateGray (SingleTransparentColor) + else + g := hi (CalculateGray(SingleTransparentColor)); + {$IFDEF ENDIAN_LITTLE} + g := swap (g); + {$ENDIF} + move (g,ChunkDataBuffer^[0],2); + WriteChunk; + end; + procedure ColorAlpha; + var g : TFPColor; + begin + SetChunkLength(6); + g := SingleTransparentColor; + with g do + if WordSized then + begin + {$IFDEF ENDIAN_LITTLE} + red := swap (red); + green := swap (green); + blue := swap (blue); + {$ENDIF} + move (g, ChunkDatabuffer^[0], 6); + end + else + begin + ChunkDataBuffer^[0] := 0; + ChunkDataBuffer^[1] := red shr 8; + ChunkDataBuffer^[2] := 0; + ChunkDataBuffer^[3] := green shr 8; + ChunkDataBuffer^[4] := 0; + ChunkDataBuffer^[5] := blue shr 8; + end; + WriteChunk; + end; +begin + SetChunkType (cttRNS); + case fheader.colortype of + 6,4 : raise PNGImageException.create ('tRNS chunk forbidden for full alpha channels'); + 3 : PaletteAlpha; + 2 : ColorAlpha; + 0 : GrayAlpha; + end; +end; + +procedure TFPWriterPNG.WriteTexts; +begin +end; + +procedure TFPWriterPNG.WriteIEND; +begin + SetChunkLength(0); + SetChunkType (ctIEND); + WriteChunk; +end; + +procedure TFPWriterPNG.InternalWrite (Str:TStream; Img:TFPCustomImage); +begin + WriteIHDR; + if Fheader.colorType = 3 then + WritePLTE; + if FUsetRNS then + WritetRNS; + WriteIDAT; + WriteTexts; + WriteIEND; +end; + +initialization + ImageHandlers.RegisterImageWriter ('Portable Network Graphics', 'png', TFPWriterPNG); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritepnm.pp b/mseide-msegui/lib/common/fpccompatibility/fpwritepnm.pp new file mode 100644 index 0000000..35137f4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritepnm.pp @@ -0,0 +1,283 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + PNM writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. +} +{*****************************************************************************} +{Support for writing PNM (Portable aNyMap) formats added : + * PBM (P1,P4) : Portable BitMap format : 1 bit per pixel + * PGM (P2,P5) : Portable GrayMap format : 8 bits per pixel + * PPM (P5,P6) : Portable PixelMap foramt : 24 bits per pixel} +{$mode objfpc}{$h+} +unit FPWritePNM; + +interface + +uses FPImage, classes, sysutils; + +type + TPNMColorDepth = (pcdAuto,pcdBlackWhite, pcdGrayscale, pcdRGB); + + { TFPWriterPNM } + + TFPWriterPNM = class(TFPCustomImageWriter) + protected + procedure InternalWrite(Stream:TStream;Img:TFPCustomImage);override; + public + ColorDepth: TPNMColorDepth; + BinaryFormat: boolean; + function GuessColorDepthOfImage(Img: TFPCustomImage): TPNMColorDepth; + function GetColorDepthOfExtension(AExtension: string): TPNMColorDepth; + function GetFileExtension(AColorDepth: TPNMColorDepth): string; + constructor Create; override; + end; + + { TFPWriterPBM } + + TFPWriterPBM = class(TFPWriterPNM) + constructor Create; override; + end; + + { TFPWriterPGM } + + TFPWriterPGM = class(TFPWriterPNM) + constructor Create; override; + end; + + { TFPWriterPPM } + + TFPWriterPPM = class(TFPWriterPNM) + constructor Create; override; + end; + +procedure SaveImageToPNMFile(Img: TFPCustomImage; filename: string; UseBinaryFormat: boolean = true); + +implementation + +procedure SaveImageToPNMFile(Img: TFPCustomImage; filename: string; UseBinaryFormat: boolean = true); +var writer: TFPWriterPNM; + curExt: string; +begin + writer := TFPWriterPNM.Create; + writer.BinaryFormat := UseBinaryFormat; + curExt := Lowercase(ExtractFileExt(filename)); + if (curExt='.pnm') or (curExt='') then + begin + writer.ColorDepth := writer.GuessColorDepthOfImage(Img); + filename := ChangeFileExt(filename,'.'+writer.GetFileExtension(writer.ColorDepth)); + end else + writer.ColorDepth := writer.GetColorDepthOfExtension(curExt); + Img.SaveToFile(filename,writer); + writer.Free; +end; + +{ TFPWriterPPM } + +constructor TFPWriterPPM.Create; +begin + inherited Create; + ColorDepth := pcdRGB; +end; + +{ TFPWriterPGM } + +constructor TFPWriterPGM.Create; +begin + inherited Create; + ColorDepth := pcdGrayscale; +end; + +{ TFPWriterPBM } + +constructor TFPWriterPBM.Create; +begin + inherited Create; + ColorDepth:= pcdBlackWhite; +end; + +{ TFPWriterPNM } + +constructor TFPWriterPNM.Create; +begin + inherited Create; + ColorDepth := pcdAuto; + BinaryFormat := True; +end; + +procedure TFPWriterPNM.InternalWrite(Stream:TStream;Img:TFPCustomImage); +var useBitMapType: integer; + + function SaveHeader(stream:TStream):boolean; + const + MagicWords:Array[1..6]OF String[2]=('P1','P2','P3','P4','P5','P6'); + var + PNMInfo:String; + strWidth,StrHeight:String[15]; + begin + SaveHeader:=false; + with Img do + begin + Str(Img.Width,StrWidth); + Str(Img.Height,StrHeight); + end; + PNMInfo:=Concat(MagicWords[useBitMapType],#10,StrWidth,#32,StrHeight,#10); + if useBitMapType in [2,3,5,6] + then + PNMInfo:=Concat(PNMInfo,'255'#10); + stream.seek(0,soFromBeginning); + stream.Write(PNMInfo[1],Length(PNMInfo)); + SaveHeader := true; + end; + var + Row,Coulumn,nBpLine,i:Integer; + aColor:TFPColor; + aLine:PByte; + strCol:String[3]; + LinuxEndOfLine: char; + UseColorDepth: TPNMColorDepth; + + begin + LinuxEndOfLine := #10; + + //determine color depth + if ColorDepth = pcdAuto then + UseColorDepth := GuessColorDepthOfImage(Img) else + UseColorDepth := ColorDepth; + + //determine file format number (1-6) + case UseColorDepth of + pcdBlackWhite: useBitMapType := 1; + pcdGrayscale: useBitMapType := 2; + pcdRGB: useBitMapType := 3; + end; + if BinaryFormat then inc(useBitMapType,3); + + SaveHeader(Stream); + case useBitMapType of + 1:nBpLine:=Img.Width*2;{p p p} + 2:nBpLine:=Img.Width*4;{lll lll lll} + 3:nBpLine:=Img.Width*3*4;{rrr ggg bbb rrr ggg bbb} + 4:nBpLine:=(Img.Width+7) SHR 3; + 5:nBpLine:=Img.Width; + 6:nBpLine:=Img.Width*3; + end; + GetMem(aLine,nBpLine);//3 extra byte for BMP 4Bytes alignement. + for Row:=0 to img.Height-1 do + begin + FillChar(aLine^,nBpLine,0); + for Coulumn:=0 to img.Width-1 do + begin + aColor:=img.Colors[Coulumn,Row]; + with aColor do + case useBitMapType of + 1:begin + if(Red<=$2F00)or(Green<=$2F00)or(Blue<=$2F00) + then + aLine[2*Coulumn]:=Ord('1') + else + aLine[2*Coulumn]:=Ord('0'); + aLine[2*Coulumn+1]:=32; + end; + 2:begin + Str(Hi(Word(Round(Red*0.299+Green*0.587+Blue*0.114))),strCol); + for i:=0 to Length(StrCol)-1 do + aLine[4*Coulumn+i]:=Ord(StrCol[i+1]); + for i:=Length(StrCol) to 4 do + aLine[4*Coulumn+i]:=32; + end; + 3:begin + Str(Hi(Red),strCol); + for i:=0 to Length(StrCol)-1 do + aLine[4*(3*Coulumn)+i]:=Ord(StrCol[i+1]); + for i:=Length(StrCol) to 4 do + aLine[4*(3*Coulumn)+i]:=32; + Str(Hi(Green),strCol); + for i:=0 to Length(StrCol)-1 do + aLine[4*(3*Coulumn+1)+i]:=Ord(StrCol[i+1]); + for i:=Length(StrCol) to 4 do + aLine[4*(3*Coulumn+1)+i]:=32; + Str(Hi(Blue),strCol); + for i:=0 to Length(StrCol)-1 do + aLine[4*(3*Coulumn+2)+i]:=Ord(StrCol[i+1]); + for i:=Length(StrCol) to 4 do + aLine[4*(3*Coulumn+2)+i]:=32; + end; + 4:if(Red<=$2F00)or(Green<=$2F00)or(Blue<=$2F00) + then + aLine[Coulumn shr 3]:=aLine[Coulumn shr 3] or ($80 shr (Coulumn and $07)); + 5:aLine[Coulumn]:=Hi(Word(Round(Red*0.299+Green*0.587+Blue*0.114))); + 6:begin + aLine[3*Coulumn]:=Hi(Red); + aLine[3*Coulumn+1]:=Hi(Green); + aLine[3*Coulumn+2]:=Hi(Blue); + end; + end; + end; + Stream.Write(aLine^,nBpLine); + if useBitMapType in[1..3] then Stream.Write(LinuxEndOfLine,1); + end; + FreeMem(aLine,nBpLine); + end; + +function TFPWriterPNM.GetColorDepthOfExtension(AExtension: string + ): TPNMColorDepth; +begin + if (length(AExtension) > 0) and (AExtension[1]='.') then + delete(AExtension,1,1); + AExtension := LowerCase(AExtension); + if AExtension='pbm' then result := pcdBlackWhite else + if AExtension='pgm' then result := pcdGrayscale else + if AExtension='ppm' then result := pcdRGB else + result := pcdAuto; +end; + +function TFPWriterPNM.GuessColorDepthOfImage(Img: TFPCustomImage): TPNMColorDepth; +var Row, Col: integer; + aColor: TFPColor; +begin + result := pcdBlackWhite; + for Row:=0 to img.Height-1 do + for Col:=0 to img.Width-1 do + begin + aColor:=img.Colors[Col,Row]; + if (AColor.red >= 256) and (AColor.green >= 256) and (AColor.blue >= 256) and + (AColor.red < $FF00) and (AColor.green < $FF00) and (AColor.blue < $FF00) then + begin + if (AColor.red shr 8 <> AColor.Green shr 8) or + (AColor.blue shr 8 <> AColor.Green shr 8) or + (AColor.red shr 8 <> AColor.blue shr 8) then + begin + result := pcdRGB; + exit; + end else + result := pcdGrayscale; + end; + end; +end; + +function TFPWriterPNM.GetFileExtension(AColorDepth: TPNMColorDepth): string; +begin + case AColorDepth of + pcdBlackWhite: result := 'pbm'; + pcdGrayscale: result := 'pgm'; + pcdRGB: result := 'ppm'; + else + result := 'pnm'; + end; +end; + +initialization + ImageHandlers.RegisterImageWriter ('Netpbm Portable aNyMap', 'pnm', TFPWriterPNM); + ImageHandlers.RegisterImageWriter ('Netpbm Portable BitMap', 'pbm', TFPWriterPBM); + ImageHandlers.RegisterImageWriter ('Netpbm Portable GrayMap', 'pgm', TFPWriterPGM); + ImageHandlers.RegisterImageWriter ('Netpbm Portable PixelMap', 'ppm', TFPWriterPPM); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritetga.pp b/mseide-msegui/lib/common/fpccompatibility/fpwritetga.pp new file mode 100644 index 0000000..5de3f61 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritetga.pp @@ -0,0 +1,101 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Michael Van Canneyt of the Free Pascal development team + + TARGA writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. +} +{*****************************************************************************} +{$mode objfpc}{$h+} +unit FPWriteTGA; + +interface + +uses FPImage, classes, sysutils; + +type + + TFPWriterTarga = class (TFPCustomImageWriter) + protected + function SaveHeader(Stream:TStream; Img: TFPCustomImage):boolean; virtual; + procedure InternalWrite (Stream:TStream; Img: TFPCustomImage); override; + end; + + +implementation + +uses targacmn; + +function TFPWriterTarga.SaveHeader(Stream:TStream; Img : TFPCustomImage):boolean; + +var + Header : TTargaHeader; + ID : ShortString; + +begin + Result:=False; + ID:=Img.Extra[KeyIdentification]; + FillChar(Header,SizeOf(Header),0); + With Header do + begin + IDLen:=Length(ID); + MapType:=0; // No colormap. Uncompressed RGB Only. + ImgType:=2; // Uncompressed RGB + MapStart:=FromWord(0); // No data + MapLength:=FromWord(0); // No colormap yet. + MapEntrySize:=0; // No colormap yet. + OriginX:= FromWord(0); + OriginY:=FromWord(0); + Width:=FromWord(Img.Width); + Height:=FromWord(Img.Height); + PixelSize:=24; // BGR data. + Flags:=$20; // Top-town, non interlaced. + end; + Stream.WriteBuffer(Header,SizeOf(Header)); + If Header.IDlen>0 then + Stream.WriteBuffer(Id[1],Header.IDLen); + Result:=true; +end; + +procedure TFPWriterTarga.InternalWrite (Stream:TStream; Img:TFPCustomImage); + +var + Row,Col,WriteSize:Integer; + Aline,P: PByte; + C : TFPColor; + +begin + SaveHeader(Stream,Img); + WriteSize:=Img.Width*3; + GetMem(aLine,WriteSize); + Try + for Row:=0 to Img.Height-1 do + begin + P:=ALine; + For Col:=0 to Img.width-1 do + begin + C:=Img.Colors[Col,Row]; + P^:=C.Blue shr 8; + Inc(P); + P^:=C.Green shr 8; + Inc(P); + P^:=C.Red shr 8; + Inc(P); + end; + Stream.Write(aLine[0],WriteSize); + end; + Finally + FreeMem(aLine); + end; +end; + +initialization + ImageHandlers.RegisterImageWriter ('TARGA Format', 'tga', TFPWriterTarga); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritetiff.pas b/mseide-msegui/lib/common/fpccompatibility/fpwritetiff.pas new file mode 100644 index 0000000..b85aa09 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritetiff.pas @@ -0,0 +1,903 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2012 by the Free Pascal development team + + Tiff writer for fpImage. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + ********************************************************************** + + Working: + Grayscale 8,16bit (optional alpha), + RGB 8,16bit (optional alpha), + Orientation, + multiple images, pages + thumbnail + Compression: deflate + + ToDo: + Compression: LZW, packbits, jpeg, ... + Planar + ColorMap + separate mask + fillorder - not needed by baseline tiff reader + bigtiff 64bit offsets + endian - currently using system endianess + orientation with rotation +} +//modified 2013 by Martin Schreiber + +unit fpwritetiff; + +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +interface + +uses + math, classes, mclasses, sysutils, fpimage, fptiffcmn,msetypes, + {$ifdef FPC} + zbase, zdeflate + {$else} + zbase_del,zdeflate_del,classes_del + {$endif}; + +type + + { TTiffWriterEntry } + + TTiffWriterEntry = class + public + Tag: Word; + EntryType: Word; + Count: DWord; + Data: Pointer; + DataPos: DWord; + Bytes: DWord; + destructor Destroy; override; + end; + + TTiffWriterChunk = record + Data: Pointer; + Bytes: DWord; + end; + PTiffWriterChunk = ^TTiffWriterChunk; + TiffWriterChunkaty = array[0..0] of TTiffWriterChunk; + pTiffWriterChunkaty = ^TiffWriterChunkaty; + + { TTiffWriterChunkOffsets } + + TTiffWriterChunkOffsets = class(TTiffWriterEntry) + public + Chunks: PTiffWriterChunk; + ChunkByteCounts: TTiffWriterEntry; + constructor Create(ChunkType: TTiffChunkType); + destructor Destroy; override; + procedure SetCount(NewCount: DWord); + end; + + { TFPWriterTiff } + + TFPWriterTiff = class(TFPCustomImageWriter) + private + FSaveCMYKAsRGB: boolean; + fStartPos: Int64; + FEntries: TFPList; // list of TFPList of TTiffWriterEntry + fStream: TStream; + fPosition: DWord; + procedure ClearEntries; + procedure WriteTiff; + procedure WriteHeader; + procedure WriteIFDs; + procedure WriteEntry(Entry: TTiffWriterEntry); + procedure WriteData; + procedure WriteEntryData(Entry: TTiffWriterEntry); + procedure WriteBuf(var Buf; Count: DWord); + procedure WriteWord(w: Word); + procedure WriteDWord(d: DWord); + protected + procedure InternalWrite(Stream: TStream; Img: TFPCustomImage); override; + procedure AddEntryString(Tag: word; const s: string); + procedure AddEntryShort(Tag: word; Value: Word); + procedure AddEntryLong(Tag: word; Value: DWord); + procedure AddEntryShortOrLong(Tag: word; Value: DWord); + procedure AddEntryRational(Tag: word; const Value: TTiffRational); + procedure AddEntry(Tag: Word; EntryType: Word; EntryCount: DWord; + Data: Pointer; Bytes: DWord; + CopyData: boolean = true); overload; + procedure AddEntry(Entry: TTiffWriterEntry); overload; + procedure TiffError(Msg: string); + procedure EncodeDeflate(var Buffer: Pointer; var Count: DWord); + public + constructor Create; override; + destructor Destroy; override; + procedure Clear; + procedure AddImage(Img: TFPCustomImage); + procedure SaveToStream(Stream: TStream); + property SaveCMYKAsRGB: boolean read FSaveCMYKAsRGB write FSaveCMYKAsRGB; + end; + +function CompareTiffWriteEntries(Entry1, Entry2: Pointer): integer; + +function CompressDeflate(InputData: PByte; InputCount: cardinal; + out Compressed: PByte; var CompressedCount: cardinal; + ErrorMsg: PAnsiString = nil): boolean; + +implementation + +function CompareTiffWriteEntries(Entry1, Entry2: Pointer): integer; +begin + Result:=integer(TTiffWriterEntry(Entry1).Tag)-integer(TTiffWriterEntry(Entry2).Tag); +end; + +function CompressDeflate(InputData: PByte; InputCount: cardinal; out + Compressed: PByte; var CompressedCount: cardinal; ErrorMsg: PAnsiString + ): boolean; +var + stream : z_stream; + err : integer; +begin + Result:=false; + //writeln('CompressDeflate START'); + Compressed:=nil; + if InputCount=0 then begin + CompressedCount:=0; + result:= true; + exit; + end; + + err := deflateInit(stream{%H-}, Z_DEFAULT_COMPRESSION); + if err <> Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='deflateInit failed'; + exit; + end; + + // set input = InputData data + stream.avail_in := InputCount; + stream.next_in := InputData; + + // set output = compressed data + if CompressedCount=0 then + CompressedCount:=InputCount; + GetMem(Compressed,CompressedCount); + stream.avail_out := CompressedCount; + stream.next_out := Compressed; + + err := deflate(stream, Z_NO_FLUSH); + if err<>Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='deflate failed'; + exit; + end; + + while TRUE do begin + //writeln('run: total_in=',stream.total_in,' avail_in=',stream.avail_in,' total_out=',stream.total_out,' avail_out=',stream.avail_out); + if (stream.avail_out=0) then begin + // need more space + if CompressedCount<128 then + CompressedCount:=CompressedCount+128 + else if CompressedCount>High(CompressedCount)-1024 then begin + if ErrorMsg<>nil then + ErrorMsg^:='deflate compression failed, because not enough space'; + exit; + end else + CompressedCount:=CompressedCount+1024; + ReAllocMem(Compressed,CompressedCount); + stream.next_out:= pointer(pchar(Compressed)+stream.total_out); + stream.avail_out:= CompressedCount-stream.total_out; + end; + err := deflate(stream, Z_FINISH); + if err = Z_STREAM_END then + break; + if err<>Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='deflate finish failed'; + exit; + end; + end; + + //writeln('compressed: total_in=',stream.total_in,' total_out=',stream.total_out); + CompressedCount:=stream.total_out; + ReAllocMem(Compressed,CompressedCount); + + err := deflateEnd(stream); + if err<>Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='deflateEnd failed'; + exit; + end; + Result:=true; +end; + +{ TFPWriterTiff } + +procedure TFPWriterTiff.WriteWord(w: Word); +begin + if fStream<>nil then + fStream.WriteWord(w); + inc(fPosition,2); +end; + +procedure TFPWriterTiff.WriteDWord(d: DWord); +begin + if fStream<>nil then + fStream.WriteDWord(d); + inc(fPosition,4); +end; + +procedure TFPWriterTiff.ClearEntries; +var + i: Integer; + List: TFPList; + j: Integer; +begin + for i:=FEntries.Count-1 downto 0 do begin + List:=TFPList(FEntries[i]); + for j:=List.Count-1 downto 0 do + TObject(List[j]).Free; + List.Free; + end; + FEntries.Clear; +end; + +procedure TFPWriterTiff.WriteTiff; +begin + {$IFDEF FPC_Debug_Image} + writeln('TFPWriterTiff.WriteTiff fStream=',fStream<>nil); + {$ENDIF} + fPosition:=0; + WriteHeader; + WriteIFDs; + WriteData; +end; + +procedure TFPWriterTiff.WriteHeader; +var + EndianMark: String; +begin + EndianMark:={$IFDEF FPC_BIG_ENDIAN}'MM'{$ELSE}'II'{$ENDIF}; + WriteBuf(EndianMark[1],2); + WriteWord(42); + WriteDWord(8); +end; + +procedure TFPWriterTiff.WriteIFDs; +var + i: Integer; + List: TFPList; + j: Integer; + Entry: TTiffWriterEntry; + NextIFDPos: DWord; +begin + for i:=0 to FEntries.Count-1 do begin + List:=TFPList(FEntries[i]); + // write count + {$IFDEF FPC_Debug_Image} + writeln('TFPWriterTiff.WriteIFDs List=',i,' Count=',List.Count); + {$ENDIF} + WriteWord(List.Count); + // write array of entries + for j:=0 to List.Count-1 do begin + Entry:=TTiffWriterEntry(List[j]); + WriteEntry(Entry); + end; + // write position of next IFD + if i0 then begin + BitsPerSample[SamplesPerPixel]:=AlphaBits; + inc(SamplesPerPixel); + end; + + ImgWidth:=Img.Width; + ImgHeight:=Img.Height; + Compression:=IFD.Compression; + case Compression of + TiffCompressionNone, + TiffCompressionDeflateZLib: ; + else + {$ifdef FPC_DEBUG_IMAGE} + writeln('TFPWriterTiff.AddImage unsupported compression '+TiffCompressionName(Compression)+', using deflate instead.'); + {$endif} + Compression:=TiffCompressionDeflateZLib; + end; + + if IFD.Orientation in [1..4] then begin + OrientedWidth:=ImgWidth; + OrientedHeight:=ImgHeight; + end else begin + // rotated + OrientedWidth:=ImgHeight; + OrientedHeight:=ImgWidth; + end; + + {$IFDEF FPC_Debug_Image} + writeln('TFPWriterTiff.AddImage PhotoMetricInterpretation=',IFD.PhotoMetricInterpretation); + writeln('TFPWriterTiff.AddImage ImageWidth=',ImgWidth,' ImageHeight=',ImgHeight); + writeln('TFPWriterTiff.AddImage Orientation=',IFD.Orientation); + writeln('TFPWriterTiff.AddImage ResolutionUnit=',IFD.ResolutionUnit); + writeln('TFPWriterTiff.AddImage XResolution=',TiffRationalToStr(IFD.XResolution)); + writeln('TFPWriterTiff.AddImage YResolution=',TiffRationalToStr(IFD.YResolution)); + writeln('TFPWriterTiff.AddImage GrayBits=',GrayBits,' RedBits=',RedBits,' GreenBits=',GreenBits,' BlueBits=',BlueBits,' AlphaBits=',AlphaBits); + writeln('TFPWriterTiff.AddImage Compression=',TiffCompressionName(Compression)); + writeln('TFPWriterTiff.AddImage Page=',IFD.PageNumber,'/',IFD.PageCount); + {$ENDIF} + + // required meta entries + AddEntryShortOrLong(256,ImgWidth); + AddEntryShortOrLong(257,ImgHeight); + AddEntryShort(259,Compression); + AddEntryShort(262,IFD.PhotoMetricInterpretation); + AddEntryShort(274,IFD.Orientation); + AddEntryShort(296,IFD.ResolutionUnit); + AddEntryRational(282,IFD.XResolution); + AddEntryRational(283,IFD.YResolution); + if AlphaBits>0 then begin + // ExtraSamples + AddEntryShort(338,2);// 2=unassociated alpha + end; + // BitsPerSample (required) + AddEntry(258,3,SamplesPerPixel,@BitsPerSample[0],SamplesPerPixel*2); + AddEntryShort(277,SamplesPerPixel); + + // BitsPerPixel, BytesPerLine + BitsPerPixel:=0; + for i:=0 to SamplesPerPixel-1 do + inc(BitsPerPixel,BitsPerSample[i]); + BytesPerLine:=(BitsPerPixel*OrientedWidth+7) div 8; + + // optional entries + NewSubFileType:=0; + if IFD.ImageIsThumbNail then inc(NewSubFileType,1); + if IFD.ImageIsPage then inc(NewSubFileType,2); + if IFD.ImageIsMask then inc(NewSubFileType,4); + if NewSubFileType>0 then + AddEntryLong(254,NewSubFileType); + if IFD.DocumentName<>'' then + AddEntryString(269,IFD.DocumentName); + if IFD.ImageDescription<>'' then + AddEntryString(270,IFD.ImageDescription); + if IFD.Make_ScannerManufacturer<>'' then + AddEntryString(271,IFD.Make_ScannerManufacturer); + if IFD.Model_Scanner<>'' then + AddEntryString(272,IFD.Model_Scanner); + if IFD.Software<>'' then + AddEntryString(305,IFD.Software); + if IFD.DateAndTime<>'' then + AddEntryString(306,IFD.DateAndTime); + if IFD.Artist<>'' then + AddEntryString(315,IFD.Artist); + if IFD.HostComputer<>'' then + AddEntryString(316,IFD.HostComputer); + if IFD.PageCount>0 then begin + Shorts[0]:=IFD.PageNumber; + Shorts[1]:=IFD.PageCount; + AddEntry(297,3,2,@Shorts[0],2*SizeOf(Word)); + end; + if IFD.PageName<>'' then + AddEntryString(285,IFD.PageName); + if IFD.Copyright<>'' then + AddEntryString(33432,IFD.Copyright); + + // chunks + ChunkType:=tctStrip; + if IFD.TileWidth>0 then begin + AddEntryShortOrLong(322,IFD.TileWidth); + AddEntryShortOrLong(323,IFD.TileLength); + ChunkType:=tctTile; + end else begin + // RowsPerStrip (required) + if OrientedWidth=0 then + IFD.RowsPerStrip:=8 + else + IFD.RowsPerStrip:=8192 div BytesPerLine; + if IFD.RowsPerStrip<1 then + IFD.RowsPerStrip:=1; + {$IFDEF FPC_Debug_Image} + writeln('TFPWriterTiff.AddImage BitsPerPixel=',BitsPerPixel,' OrientedWidth=',OrientedWidth,' BytesPerLine=',BytesPerLine,' RowsPerStrip=',IFD.RowsPerStrip); + {$ENDIF} + AddEntryShortOrLong(278,IFD.RowsPerStrip); + end; + + // tags for Offsets and ByteCounts + ChunkOffsets:=TTiffWriterChunkOffsets.Create(ChunkType); + AddEntry(ChunkOffsets); + AddEntry(ChunkOffsets.ChunkByteCounts); + if (OrientedHeight>0) and (OrientedWidth>0) then begin + if ChunkType=tctTile then begin + TilesAcross:=(OrientedWidth+IFD.TileWidth{%H-}-1) div IFD.TileWidth; + TilesDown:=(OrientedHeight+IFD.TileLength{%H-}-1) div IFD.TileLength; + ChunkCount:=TilesAcross*TilesDown; + {$IFDEF FPC_Debug_Image} + writeln('TFPWriterTiff.AddImage BitsPerPixel=',BitsPerPixel,' OrientedWidth=',OrientedWidth,' OrientedHeight=',OrientedHeight,' TileWidth=',IFD.TileWidth,' TileLength=',IFD.TileLength,' TilesAcross=',TilesAcross,' TilesDown=',TilesDown,' ChunkCount=',ChunkCount); + {$ENDIF} + end else begin + ChunkCount:=(OrientedHeight+IFD.RowsPerStrip{%H-}-1) div IFD.RowsPerStrip; + end; + ChunkOffsets.SetCount(ChunkCount); + // create chunks + for ChunkIndex:=0 to ChunkCount-1 do begin + if ChunkType=tctTile then begin + ChunkLeft:=(ChunkIndex mod TilesAcross)*IFD.TileWidth; + ChunkTop:=(ChunkIndex div TilesAcross)*IFD.TileLength; + ChunkWidth:=Min(IFD.TileWidth,OrientedWidth-ChunkLeft); + ChunkHeight:=Min(IFD.TileLength,OrientedHeight-ChunkTop); + // boundary tiles are padded to a full tile + // the padding is filled with 0 and compression will get rid of it + ChunkBytesPerLine:=(BitsPerPixel*IFD.TileWidth+7) div 8; + ChunkBytes:=ChunkBytesPerLine*IFD.TileLength; + end else begin + ChunkLeft:=0; + ChunkTop:=IFD.RowsPerStrip*ChunkIndex; + ChunkWidth:=OrientedWidth; + ChunkHeight:=Min(IFD.RowsPerStrip,OrientedHeight-ChunkTop); + ChunkBytesPerLine:=BytesPerLine; + ChunkBytes:=ChunkBytesPerLine*ChunkHeight; + end; + GetMem(Chunk,ChunkBytes); + {$ifdef FPC} + FillByte(Chunk^,ChunkBytes,0); // fill unused bytes with 0 to help compression + {$else} + Fillchar(Chunk^,ChunkBytes,0); // fill unused bytes with 0 to help compression + {$endif} + // Orientation + if IFD.Orientation in [1..4] then begin + x:=ChunkLeft; y:=ChunkTop; + case IFD.Orientation of + 1: begin dx:=1; dy:=1; end;// 0,0 is left, top + 2: begin x:=OrientedWidth-x-1; dx:=-1; dy:=1; end;// 0,0 is right, top + 3: begin x:=OrientedWidth-x-1; dx:=-1; y:=OrientedHeight-y-1; dy:=-1; end;// 0,0 is right, bottom + 4: begin dx:=1; y:=OrientedHeight-y-1; dy:=-1; end;// 0,0 is left, bottom + end; + end else begin + // rotated + x:=ChunkTop; y:=ChunkLeft; + case IFD.Orientation of + 5: begin dx:=1; dy:=1; end;// 0,0 is top, left (rotated) + 6: begin dx:=1; y:=OrientedWidth-y-1; dy:=-1; end;// 0,0 is top, right (rotated) + 7: begin x:=OrientedHeight-x-1; dx:=-1; y:=OrientedWidth-y-1; dy:=-1; end;// 0,0 is bottom, right (rotated) + 8: begin x:=OrientedHeight-x-1; dx:=-1; dy:=1; end;// 0,0 is bottom, left (rotated) + end; + end; + //writeln('TFPWriterTiff.AddImage Chunk=',ChunkIndex,'/',ChunkCount,' ChunkBytes=',ChunkBytes,' ChunkRect=',ChunkLeft,',',ChunkTop,',',ChunkWidth,'x',ChunkHeight,' x=',x,' y=',y,' dx=',dx,' dy=',dy); + sx:=x; // save start x + for cy:=0 to ChunkHeight-1 do begin + x:=sx; + Run:= pointer(pchar(Chunk)+cy*ChunkBytesPerLine); + for cx:=0 to ChunkWidth-1 do begin + Col:=Img.Colors[x,y]; + case IFD.PhotoMetricInterpretation of + 0,1: + begin + // grayscale + Value:=(DWord(Col.red)+Col.green+Col.blue) div 3; + if IFD.PhotoMetricInterpretation=0 then + Value:=$ffff-Value;// 0 is white + if GrayBits=8 then begin + Run^:=Value shr 8; + inc(Run); + end else if GrayBits=16 then begin + PWord(Run)^:=Value; + inc(Run,2); + end; + if AlphaBits=8 then begin + Run^:=Col.alpha shr 8; + inc(Run); + end else if AlphaBits=16 then begin + PWord(Run)^:=Col.alpha; + inc(Run,2); + end; + end; + 2: + begin + // RGB + if RedBits=8 then begin + Run^:=Col.red shr 8; + inc(Run); + end else if RedBits=16 then begin + PWord(Run)^:=Col.red; + inc(Run,2); + end; + if GreenBits=8 then begin + Run^:=Col.green shr 8; + inc(Run); + end else if GreenBits=16 then begin + PWord(Run)^:=Col.green; + inc(Run,2); + end; + if BlueBits=8 then begin + Run^:=Col.blue shr 8; + inc(Run); + end else if BlueBits=16 then begin + PWord(Run)^:=Col.blue; + inc(Run,2); + end; + if AlphaBits=8 then begin + Run^:=Col.alpha shr 8; + inc(Run); + end else if AlphaBits=16 then begin + PWord(Run)^:=Col.alpha; + inc(Run,2); + end; + end; + end; + // next x + inc(x,dx); + end; + // next y + inc(y,dy); + end; + + // compress + case Compression of + TiffCompressionDeflateZLib: EncodeDeflate(pointer(Chunk),ChunkBytes); + end; + + pTiffWriterChunkaty(ChunkOffsets.Chunks)^[ChunkIndex].Data:=Chunk; + pTiffWriterChunkaty(ChunkOffsets.Chunks)^[ChunkIndex].Bytes:=ChunkBytes; + // next chunk + end; + // created chunks + end; + + CurEntries.Sort(@CompareTiffWriteEntries); + finally + IFD.Free; + end; +end; + +procedure TFPWriterTiff.SaveToStream(Stream: TStream); +begin + fStartPos:=Stream.Position; + // simulate write to compute offsets + fStream:=nil; + WriteTiff; + // write to stream + fStream:=Stream; + WriteTiff; + fStream:=nil; +end; + +procedure TFPWriterTiff.InternalWrite(Stream: TStream; Img: TFPCustomImage); +begin + AddImage(Img); + SaveToStream(Stream); +end; + +procedure TFPWriterTiff.AddEntryString(Tag: word; const s: string); +begin + if s<>'' then + AddEntry(Tag,2,length(s)+1,@s[1],length(s)+1) + else + AddEntry(Tag,2,0,nil,0); +end; + +procedure TFPWriterTiff.AddEntryShort(Tag: word; Value: Word); +begin + AddEntry(Tag,3,1,@Value,2); +end; + +procedure TFPWriterTiff.AddEntryLong(Tag: word; Value: DWord); +begin + AddEntry(Tag,4,1,@Value,4); +end; + +procedure TFPWriterTiff.AddEntryShortOrLong(Tag: word; Value: DWord); +begin + if Value<=High(Word) then + AddEntryShort(Tag,Value) + else + AddEntryLong(Tag,Value); +end; + +procedure TFPWriterTiff.AddEntryRational(Tag: word; const Value: TTiffRational + ); +begin + AddEntry(Tag,5,1,@Value,8); +end; + +procedure TFPWriterTiff.AddEntry(Tag: Word; EntryType: Word; EntryCount: DWord; + Data: Pointer; Bytes: DWord; CopyData: boolean); +var + Entry: TTiffWriterEntry; +begin + Entry:=TTiffWriterEntry.Create; + Entry.Tag:=Tag; + Entry.EntryType:=EntryType; + Entry.Count:=EntryCount; + if CopyData then begin + if Bytes>0 then begin + GetMem(Entry.Data,Bytes); + System.Move(Data^,Entry.Data^,Bytes); + end else begin + Entry.Data:=nil; + end; + end else + Entry.Data:=Data; + Entry.Bytes:=Bytes; + AddEntry(Entry); +end; + +procedure TFPWriterTiff.AddEntry(Entry: TTiffWriterEntry); +var + List: TFPList; +begin + List:=TFPList(FEntries[FEntries.Count-1]); + List.Add(Entry); +end; + +procedure TFPWriterTiff.TiffError(Msg: string); +begin + raise Exception.Create('TFPWriterTiff.TiffError: '+Msg); +end; + +procedure TFPWriterTiff.EncodeDeflate(var Buffer: Pointer; var Count: DWord); +var + NewBuffer: PByte; + NewCount: cardinal; + ErrorMsg: String; +begin + ErrorMsg:=''; + NewBuffer:=nil; + try + NewCount:=Count; + if not CompressDeflate(Buffer,Count,NewBuffer,NewCount,@ErrorMsg) then + TiffError(ErrorMsg); + FreeMem(Buffer); + Buffer:=NewBuffer; + Count:=NewCount; + NewBuffer:=nil; + finally + ReAllocMem(NewBuffer,0); + end; +end; + +constructor TFPWriterTiff.Create; +begin + inherited Create; + FEntries:=TFPList.Create; + FSaveCMYKAsRGB:=true; +end; + +destructor TFPWriterTiff.Destroy; +begin + Clear; + FreeAndNil(FEntries); + inherited Destroy; +end; + +procedure TFPWriterTiff.Clear; +begin + ClearEntries; +end; + +{ TTiffWriterEntry } + +destructor TTiffWriterEntry.Destroy; +begin + ReAllocMem(Data,0); + inherited Destroy; +end; + +{ TTiffWriterChunkOffsets } + +constructor TTiffWriterChunkOffsets.Create(ChunkType: TTiffChunkType); +begin + EntryType:=4; // long + ChunkByteCounts:=TTiffWriterEntry.Create; + ChunkByteCounts.EntryType:=4; // long + if ChunkType=tctTile then begin + Tag:=324; // TileOffsets + ChunkByteCounts.Tag:=325; // TileByteCounts + end else begin + Tag:=273; // StripOffsets + ChunkByteCounts.Tag:=279; // StripByteCounts + end; +end; + +destructor TTiffWriterChunkOffsets.Destroy; +var + i: Integer; +begin + if Chunks<>nil then begin + for i:=0 to Count-1 do + ReAllocMem(pTiffWriterChunkaty(Chunks)^[i].Data,0); + ReAllocMem(Chunks,0); + end; + inherited Destroy; +end; + +procedure TTiffWriterChunkOffsets.SetCount(NewCount: DWord); +var + Size: DWord; +begin + {$IFDEF FPC_Debug_Image} + writeln('TTiffWriteStripOffsets.SetCount OldCount=',Count,' NewCount=',NewCount); + {$ENDIF} + Count:=NewCount; + Size:=Count*SizeOf(TTiffWriterChunk); + ReAllocMem(Chunks,Size); + {$ifdef FPC} + if Size>0 then FillByte(Chunks^,Size,0); + {$else} + if Size>0 then Fillchar(Chunks^,Size,0); + {$endif} + Size:=Count*SizeOf(DWord); + // Offsets + ReAllocMem(Data,Size); + {$ifdef FPC} + if Size>0 then FillByte(Data^,Size,0); + {$else} + if Size>0 then Fillchar(Data^,Size,0); + {$endif} + Bytes:=Size; + // ByteCounts + ReAllocMem(ChunkByteCounts.Data,Size); + {$ifdef FPC} + if Size>0 then FillByte(ChunkByteCounts.Data^,Size,0); + {$else} + if Size>0 then Fillchar(ChunkByteCounts.Data^,Size,0); + {$endif} + ChunkByteCounts.Count:=Count; + ChunkByteCounts.Bytes:=Size; +end; + +initialization + if ImageHandlers.ImageWriter[TiffHandlerName]=nil then + ImageHandlers.RegisterImageWriter (TiffHandlerName, 'tif;tiff', TFPWriterTiff); +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritexpm.pp b/mseide-msegui/lib/common/fpccompatibility/fpwritexpm.pp new file mode 100644 index 0000000..2935535 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritexpm.pp @@ -0,0 +1,173 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + XPM writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +{$mode objfpc}{$h+} +unit FPWriteXPM; + +interface + +uses FPImage, classes, sysutils; + +type + + TFPWriterXPM = class (TFPCustomImageWriter) + private + FPalChars : string; + FColorFormat : string; + FColorShift : word; + FColorSize : byte; + procedure SetColorSize (AValue : byte); + function ColorToHex (c:TFPColor) : string; + protected + procedure InternalWrite (Str:TStream; Img:TFPCustomImage); override; + public + constructor Create; override; + property PalChars : string read FPalChars write FPalChars; + property ColorCharSize : byte read FColorSize write SetColorSize; + // number of characters to use for 1 colorcomponent + end; + + +implementation + +const + DefPalChars = '.,-*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#;:=+%$()[]'; + +constructor TFPWriterXPM.create; +begin + inherited create; + PalChars := DefPalChars; + FColorSize := 4; +end; + +procedure TFPWriterXPM.SetColorSize (AValue : byte); +begin + if AValue > 3 then + FColorSize := 4 + else if AValue = 0 then + FColorSize := 1 + else + FColorSize := AValue; +end; + +function TFPWriterXPM.ColorToHex (c:TFPColor) : string; +var r,g,b : word; +begin + with c do + begin + r := red shr FColorShift; + g := green shr FColorShift; + b := blue shr FColorShift; + end; + result := format(FColorFormat,[r,g,b]); +end; + +procedure TFPWriterXPM.InternalWrite (Str:TStream; Img:TFPCustomImage); +var p, l : TStringList; + c, len, r, t : integer; + TmpPalette, Palette: TFPPalette; + procedure BuildPaletteStrings; + var r,c,e : integer; + procedure MakeCodes (const head:string; charplace:integer); + var r : integer; + begin + r := 1; + dec (charplace); + while (r <= e) and (c >= 0) do + begin + if Charplace > 0 then + MakeCodes (head+PalChars[r],charplace) + else begin + p.Add (head+PalChars[r]); + dec(c); + end; + inc (r); + end; + end; + begin + // Calculate length of codes + len := 1; + e := length(PalChars); + r := e; + c := Palette.count; + while (r <= c) do + begin + inc (len); + r := r * e; + end; + MakeCodes ('',len); + end; + procedure InitConsts; + var fmt : string; + begin + fmt := inttostr(FColorSize); + fmt := '%'+fmt+'.'+fmt+'x'; + FColorFormat := fmt+fmt+fmt; + case FColorSize of + 1 : FColorShift := 12; + 2 : FColorShift := 8; + 3 : FColorShift := 4; + else FColorShift := 0; + end; + end; +var s : string; +begin + l := TStringList.Create; + p := TStringList.Create; + TmpPalette := nil; + try + l.Add ('/* XPM */'); + l.Add ('static char *graphic[] = {'); + Palette := img.palette; + if not Assigned(Palette) then begin + TmpPalette := TFPPalette.Create(0); + TmpPalette.Build(Img); + Palette := TmpPalette; + end; + c := Palette.count; + BuildPaletteStrings; + l.add (format('"%d %d %d %d",',[img.width,img.height,c,len])); + InitConsts; + for r := 0 to c-1 do + begin + if Palette[r] <> colTransparent then + l.Add (format('"%s c #%s",',[p[r],ColorToHex(Palette.color[r])])) + else + l.Add (format('"%s c None",',[p[r]])); + end; + for r := 0 to img.Height-1 do + begin + s := ''; + for t := 0 to img.Width-1 do + if Assigned(TmpPalette) then + s := s + p[TmpPalette.IndexOf(img.Colors[t,r])] + else + s := s + p[img.pixels[t,r]]; + s := '"'+s+'"'; + if r < img.Height-1 then + s := s + ','; + l.Add (s); + end; + l.Add ('};'); + finally + TmpPalette.Free; + l.SaveToStream (Str); + p.Free; + l.Free; + end; +end; + +initialization + ImageHandlers.RegisterImageWriter ('XPM Format', 'xpm', TFPWriterXPM); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/getstrfromint.inc b/mseide-msegui/lib/common/fpccompatibility/getstrfromint.inc new file mode 100644 index 0000000..4e3dc79 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/getstrfromint.inc @@ -0,0 +1,38 @@ + if Width <= 0 then + exit; + + NegSign := Val < 0; + Val := Abs(Val); + // we'll have to store characters backwards first + I := 0; + repeat + Temp[I] := Chr((Val mod 10) + Ord('0')); + Val := Val div 10; + Inc(I); + until (Val = 0) or (I = Width); + // add spaces + J := Width - I; + FillChar(Dst^, J, PadChar); + // add sign + if NegSign then + begin + if PadChar = '0' then + begin + Dst[0] := '-'; + end else begin + if J = 0 then + begin + // need one character for sign, shorten + Inc(J); + Dec(I); + end; + Dst[J - 1] := '-'; + end; + end; + // copy value, stored backwards + repeat + Dec(I); + Dst[J] := Temp[I]; + Inc(J); + until I = 0; + // done! diff --git a/mseide-msegui/lib/common/fpccompatibility/jcapimin_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcapimin_del.pas new file mode 100644 index 0000000..9043f2a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcapimin_del.pas @@ -0,0 +1,402 @@ +Unit jcapimin_del; +//{$N+} +{ This file contains application interface code for the compression half + of the JPEG library. These are the "minimum" API routines that may be + needed in either the normal full-compression case or the transcoding-only + case. + + Most of the routines intended to be called directly by an application + are in this file or in jcapistd.c. But also see jcparam.c for + parameter-setup helper routines, jcomapi.c for routines shared by + compression and decompression, and jctrans.c for the transcoding case. } + +{ jcapimin.c ; Copyright (C) 1994-1998, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jcomapi_del, + jmemmgr_del, + jcmarker_del; + +{ Initialization of JPEG compression objects. + Nomssi: This is a macro in the original code. + + jpeg_create_compress() and jpeg_create_decompress() are the exported + names that applications should call. These expand to calls on + jpeg_CreateCompress and jpeg_CreateDecompress with additional information + passed for version mismatch checking. + NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. } + +procedure jpeg_create_compress(cinfo : j_compress_ptr); + + +{ Initialization of a JPEG compression object. + The error manager must already be set up (in case memory manager fails). } + +{GLOBAL} +procedure jpeg_CreateCompress (cinfo : j_compress_ptr; + version : int; + structsize : size_t); + +{ Destruction of a JPEG compression object } + +{GLOBAL} +procedure jpeg_destroy_compress (cinfo : j_compress_ptr); + + +{ Abort processing of a JPEG compression operation, + but don't destroy the object itself. } + +{GLOBAL} +procedure jpeg_abort_compress (cinfo : j_compress_ptr); + + +{ Forcibly suppress or un-suppress all quantization and Huffman tables. + Marks all currently defined tables as already written (if suppress) + or not written (if !suppress). This will control whether they get emitted + by a subsequent jpeg_start_compress call. + + This routine is exported for use by applications that want to produce + abbreviated JPEG datastreams. It logically belongs in jcparam.c, but + since it is called by jpeg_start_compress, we put it here --- otherwise + jcparam.o would be linked whether the application used it or not. } + +{GLOBAL} +procedure jpeg_suppress_tables (cinfo : j_compress_ptr; + suppress : boolean); + + +{ Finish JPEG compression. + + If a multipass operating mode was selected, this may do a great deal of + work including most of the actual output. } + +{GLOBAL} +procedure jpeg_finish_compress (cinfo : j_compress_ptr); + +{ Write a special marker. + This is only recommended for writing COM or APPn markers. + Must be called after jpeg_start_compress() and before + first call to jpeg_write_scanlines() or jpeg_write_raw_data(). } + +{GLOBAL} +procedure jpeg_write_marker (cinfo : j_compress_ptr; + marker : int; + dataptr : JOCTETptr; + datalen : uInt); + +{GLOBAL} +procedure jpeg_write_m_header (cinfo : j_compress_ptr; + marker : int; + datalen : uint); +{GLOBAL} +procedure jpeg_write_m_byte (cinfo : j_compress_ptr; val : int); + +{ Alternate compression function: just write an abbreviated table file. + Before calling this, all parameters and a data destination must be set up. + + To produce a pair of files containing abbreviated tables and abbreviated + image data, one would proceed as follows: + + initialize JPEG object + set JPEG parameters + set destination to table file + jpeg_write_tables(cinfo); + set destination to image file + jpeg_start_compress(cinfo, FALSE); + write data... + jpeg_finish_compress(cinfo); + + jpeg_write_tables has the side effect of marking all tables written + (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress + will not re-emit the tables unless it is passed write_all_tables=TRUE. } + + + +{GLOBAL} +procedure jpeg_write_tables (cinfo : j_compress_ptr); + +implementation + +procedure jpeg_create_compress(cinfo : j_compress_ptr); +begin + jpeg_CreateCompress(cinfo, JPEG_LIB_VERSION, + size_t(sizeof(jpeg_compress_struct))); +end; + +{ Initialization of a JPEG compression object. + The error manager must already be set up (in case memory manager fails). } + +{GLOBAL} +procedure jpeg_CreateCompress (cinfo : j_compress_ptr; + version : int; + structsize : size_t); +var + i : int; +var + err : jpeg_error_mgr_ptr; +// client_data : voidp; +begin + + { Guard against version mismatches between library and caller. } + cinfo^.mem := NIL; { so jpeg_destroy knows mem mgr not called } + if (version <> JPEG_LIB_VERSION) then + ERREXIT2(j_common_ptr(cinfo), JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize <> SIZEOF(jpeg_compress_struct)) then + ERREXIT2(j_common_ptr(cinfo), JERR_BAD_STRUCT_SIZE, + int(SIZEOF(jpeg_compress_struct)), int(structsize)); + + { For debugging purposes, we zero the whole master structure. + But the application has already set the err pointer, and may have set + client_data, so we have to save and restore those fields. + Note: if application hasn't set client_data, tools like Purify may + complain here. } + + err := cinfo^.err; +// client_data := cinfo^.client_data; { ignore Purify complaint here } + MEMZERO(cinfo, SIZEOF(jpeg_compress_struct)); + cinfo^.err := err; + cinfo^.is_decompressor := FALSE; + + { Initialize a memory manager instance for this object } + jinit_memory_mgr(j_common_ptr(cinfo)); + + { Zero out pointers to permanent structures. } + cinfo^.progress := NIL; + cinfo^.dest := NIL; + + cinfo^.comp_info := NIL; + + for i := 0 to pred(NUM_QUANT_TBLS) do + cinfo^.quant_tbl_ptrs[i] := NIL; + + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + cinfo^.dc_huff_tbl_ptrs[i] := NIL; + cinfo^.ac_huff_tbl_ptrs[i] := NIL; + end; + + cinfo^.script_space := NIL; + + cinfo^.input_gamma := 1.0; { in case application forgets } + + { OK, I'm ready } + cinfo^.global_state := CSTATE_START; +end; + + +{ Destruction of a JPEG compression object } + +{GLOBAL} +procedure jpeg_destroy_compress (cinfo : j_compress_ptr); +begin + jpeg_destroy(j_common_ptr(cinfo)); { use common routine } +end; + + +{ Abort processing of a JPEG compression operation, + but don't destroy the object itself. } + +{GLOBAL} +procedure jpeg_abort_compress (cinfo : j_compress_ptr); +begin + jpeg_abort(j_common_ptr(cinfo)); { use common routine } +end; + + +{ Forcibly suppress or un-suppress all quantization and Huffman tables. + Marks all currently defined tables as already written (if suppress) + or not written (if !suppress). This will control whether they get emitted + by a subsequent jpeg_start_compress call. + + This routine is exported for use by applications that want to produce + abbreviated JPEG datastreams. It logically belongs in jcparam.c, but + since it is called by jpeg_start_compress, we put it here --- otherwise + jcparam.o would be linked whether the application used it or not. } + +{GLOBAL} +procedure jpeg_suppress_tables (cinfo : j_compress_ptr; + suppress : boolean); +var + i : int; + qtbl : JQUANT_TBL_PTR; + htbl : JHUFF_TBL_PTR; +begin + for i := 0 to pred(NUM_QUANT_TBLS) do + begin + qtbl := cinfo^.quant_tbl_ptrs[i]; + if (qtbl <> NIL) then + qtbl^.sent_table := suppress; + end; + + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + htbl := cinfo^.dc_huff_tbl_ptrs[i]; + if (htbl <> NIL) then + htbl^.sent_table := suppress; + htbl := cinfo^.ac_huff_tbl_ptrs[i]; + if (htbl <> NIL) then + htbl^.sent_table := suppress; + end; +end; + + +{ Finish JPEG compression. + + If a multipass operating mode was selected, this may do a great deal of + work including most of the actual output. } + +{GLOBAL} +procedure jpeg_finish_compress (cinfo : j_compress_ptr); +var + iMCU_row : JDIMENSION; +begin + if (cinfo^.global_state = CSTATE_SCANNING) or + (cinfo^.global_state = CSTATE_RAW_OK) then + begin + { Terminate first pass } + if (cinfo^.next_scanline < cinfo^.image_height) then + ERREXIT(j_common_ptr(cinfo), JERR_TOO_LITTLE_DATA); + cinfo^.master^.finish_pass (cinfo); + end + else + if (cinfo^.global_state <> CSTATE_WRCOEFS) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + { Perform any remaining passes } + while (not cinfo^.master^.is_last_pass) do + begin + cinfo^.master^.prepare_for_pass (cinfo); + for iMCU_row := 0 to pred(cinfo^.total_iMCU_rows) do + begin + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long (iMCU_row); + cinfo^.progress^.pass_limit := long (cinfo^.total_iMCU_rows); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + { We bypass the main controller and invoke coef controller directly; + all work is being done from the coefficient buffer. } + + if (not cinfo^.coef^.compress_data (cinfo, JSAMPIMAGE(NIL))) then + ERREXIT(j_common_ptr(cinfo), JERR_CANT_SUSPEND); + end; + cinfo^.master^.finish_pass (cinfo); + end; + { Write EOI, do final cleanup } + cinfo^.marker^.write_file_trailer (cinfo); + cinfo^.dest^.term_destination (cinfo); + { We can use jpeg_abort to release memory and reset global_state } + jpeg_abort(j_common_ptr(cinfo)); +end; + + +{ Write a special marker. + This is only recommended for writing COM or APPn markers. + Must be called after jpeg_start_compress() and before + first call to jpeg_write_scanlines() or jpeg_write_raw_data(). } + +{GLOBAL} +procedure jpeg_write_marker (cinfo : j_compress_ptr; + marker : int; + dataptr : JOCTETptr; + datalen : uInt); +var + write_marker_byte : procedure(info : j_compress_ptr; val : int); +begin + if (cinfo^.next_scanline <> 0) or + ((cinfo^.global_state <> CSTATE_SCANNING) and + (cinfo^.global_state <> CSTATE_RAW_OK) and + (cinfo^.global_state <> CSTATE_WRCOEFS)) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + cinfo^.marker^.write_marker_header (cinfo, marker, datalen); + write_marker_byte := cinfo^.marker^.write_marker_byte; { copy for speed } + while (datalen <> 0) do + begin + Dec(datalen); + write_marker_byte (cinfo, dataptr^); + Inc(dataptr); + end; +end; + +{ Same, but piecemeal. } + +{GLOBAL} +procedure jpeg_write_m_header (cinfo : j_compress_ptr; + marker : int; + datalen : uint); +begin + if (cinfo^.next_scanline <> 0) or + ((cinfo^.global_state <> CSTATE_SCANNING) and + (cinfo^.global_state <> CSTATE_RAW_OK) and + (cinfo^.global_state <> CSTATE_WRCOEFS)) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + cinfo^.marker^.write_marker_header (cinfo, marker, datalen); +end; + +{GLOBAL} +procedure jpeg_write_m_byte (cinfo : j_compress_ptr; val : int); +begin + cinfo^.marker^.write_marker_byte (cinfo, val); +end; + + +{ Alternate compression function: just write an abbreviated table file. + Before calling this, all parameters and a data destination must be set up. + + To produce a pair of files containing abbreviated tables and abbreviated + image data, one would proceed as follows: + + initialize JPEG object + set JPEG parameters + set destination to table file + jpeg_write_tables(cinfo); + set destination to image file + jpeg_start_compress(cinfo, FALSE); + write data... + jpeg_finish_compress(cinfo); + + jpeg_write_tables has the side effect of marking all tables written + (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress + will not re-emit the tables unless it is passed write_all_tables=TRUE. } + +{GLOBAL} +procedure jpeg_write_tables (cinfo : j_compress_ptr); +begin + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + { (Re)initialize error mgr and destination modules } + cinfo^.err^.reset_error_mgr (j_common_ptr(cinfo)); + cinfo^.dest^.init_destination (cinfo); + { Initialize the marker writer ... bit of a crock to do it here. } + jinit_marker_writer(cinfo); + { Write them tables! } + cinfo^.marker^.write_tables_only (cinfo); + { And clean up. } + cinfo^.dest^.term_destination (cinfo); + + { In library releases up through v6a, we called jpeg_abort() here to free + any working memory allocated by the destination manager and marker + writer. Some applications had a problem with that: they allocated space + of their own from the library memory manager, and didn't want it to go + away during write_tables. So now we do nothing. This will cause a + memory leak if an app calls write_tables repeatedly without doing a full + compression cycle or otherwise resetting the JPEG object. However, that + seems less bad than unexpectedly freeing memory in the normal case. + An app that prefers the old behavior can call jpeg_abort for itself after + each call to jpeg_write_tables(). } +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcapistd_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcapistd_del.pas new file mode 100644 index 0000000..2b16875 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcapistd_del.pas @@ -0,0 +1,224 @@ +Unit jcapistd_del; + +{ Original : jcapistd.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +{ This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains application interface code for the compression half + of the JPEG library. These are the "standard" API routines that are + used in the normal full-compression case. They are not used by a + transcoding-only application. Note that if an application links in + jpeg_start_compress, it will end up linking in the entire compressor. + We thus must separate this file from jcapimin.c to avoid linking the + whole compression library into a transcoder. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jcapimin_del, jcinit_del; + + + +{ Compression initialization. + Before calling this, all parameters and a data destination must be set up. + + We require a write_all_tables parameter as a failsafe check when writing + multiple datastreams from the same compression object. Since prior runs + will have left all the tables marked sent_table=TRUE, a subsequent run + would emit an abbreviated stream (no tables) by default. This may be what + is wanted, but for safety's sake it should not be the default behavior: + programmers should have to make a deliberate choice to emit abbreviated + images. Therefore the documentation and examples should encourage people + to pass write_all_tables=TRUE; then it will take active thought to do the + wrong thing. } + +{GLOBAL} +procedure jpeg_start_compress (cinfo : j_compress_ptr; + write_all_tables : boolean); + + +{ Write some scanlines of data to the JPEG compressor. + + The return value will be the number of lines actually written. + This should be less than the supplied num_lines only in case that + the data destination module has requested suspension of the compressor, + or if more than image_height scanlines are passed in. + + Note: we warn about excess calls to jpeg_write_scanlines() since + this likely signals an application programmer error. However, + excess scanlines passed in the last valid call are *silently* ignored, + so that the application need not adjust num_lines for end-of-image + when using a multiple-scanline buffer. } + +{GLOBAL} +function jpeg_write_scanlines (cinfo : j_compress_ptr; + scanlines : JSAMPARRAY; + num_lines : JDIMENSION) : JDIMENSION; + +{ Alternate entry point to write raw data. + Processes exactly one iMCU row per call, unless suspended. } + +{GLOBAL} +function jpeg_write_raw_data (cinfo : j_compress_ptr; + data : JSAMPIMAGE; + num_lines : JDIMENSION) : JDIMENSION; + +implementation + +{ Compression initialization. + Before calling this, all parameters and a data destination must be set up. + + We require a write_all_tables parameter as a failsafe check when writing + multiple datastreams from the same compression object. Since prior runs + will have left all the tables marked sent_table=TRUE, a subsequent run + would emit an abbreviated stream (no tables) by default. This may be what + is wanted, but for safety's sake it should not be the default behavior: + programmers should have to make a deliberate choice to emit abbreviated + images. Therefore the documentation and examples should encourage people + to pass write_all_tables=TRUE; then it will take active thought to do the + wrong thing. } + +{GLOBAL} +procedure jpeg_start_compress (cinfo : j_compress_ptr; + write_all_tables : boolean); +begin + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + if (write_all_tables) then + jpeg_suppress_tables(cinfo, FALSE); { mark all tables to be written } + + { (Re)initialize error mgr and destination modules } + cinfo^.err^.reset_error_mgr (j_common_ptr(cinfo)); + cinfo^.dest^.init_destination (cinfo); + { Perform master selection of active modules } + jinit_compress_master(cinfo); + { Set up for the first pass } + cinfo^.master^.prepare_for_pass (cinfo); + { Ready for application to drive first pass through jpeg_write_scanlines + or jpeg_write_raw_data. } + + cinfo^.next_scanline := 0; + if cinfo^.raw_data_in then + cinfo^.global_state := CSTATE_RAW_OK + else + cinfo^.global_state := CSTATE_SCANNING; +end; + + +{ Write some scanlines of data to the JPEG compressor. + + The return value will be the number of lines actually written. + This should be less than the supplied num_lines only in case that + the data destination module has requested suspension of the compressor, + or if more than image_height scanlines are passed in. + + Note: we warn about excess calls to jpeg_write_scanlines() since + this likely signals an application programmer error. However, + excess scanlines passed in the last valid call are *silently* ignored, + so that the application need not adjust num_lines for end-of-image + when using a multiple-scanline buffer. } + +{GLOBAL} +function jpeg_write_scanlines (cinfo : j_compress_ptr; + scanlines : JSAMPARRAY; + num_lines : JDIMENSION) : JDIMENSION; +var + row_ctr, rows_left : JDIMENSION; +begin + if (cinfo^.global_state <> CSTATE_SCANNING) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + if (cinfo^.next_scanline >= cinfo^.image_height) then + WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA); + + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long (cinfo^.next_scanline); + cinfo^.progress^.pass_limit := long (cinfo^.image_height); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + + { Give master control module another chance if this is first call to + jpeg_write_scanlines. This lets output of the frame/scan headers be + delayed so that application can write COM, etc, markers between + jpeg_start_compress and jpeg_write_scanlines. } + if (cinfo^.master^.call_pass_startup) then + cinfo^.master^.pass_startup (cinfo); + + { Ignore any extra scanlines at bottom of image. } + rows_left := cinfo^.image_height - cinfo^.next_scanline; + if (num_lines > rows_left) then + num_lines := rows_left; + + row_ctr := 0; + cinfo^.main^.process_data (cinfo, scanlines, {var}row_ctr, num_lines); + Inc(cinfo^.next_scanline, row_ctr); + jpeg_write_scanlines := row_ctr; +end; + + +{ Alternate entry point to write raw data. + Processes exactly one iMCU row per call, unless suspended. } + +{GLOBAL} +function jpeg_write_raw_data (cinfo : j_compress_ptr; + data : JSAMPIMAGE; + num_lines : JDIMENSION) : JDIMENSION; +var + lines_per_iMCU_row : JDIMENSION; +begin + if (cinfo^.global_state <> CSTATE_RAW_OK) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + if (cinfo^.next_scanline >= cinfo^.image_height) then + begin + WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA); + jpeg_write_raw_data := 0; + exit; + end; + + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long(cinfo^.next_scanline); + cinfo^.progress^.pass_limit := long(cinfo^.image_height); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + + { Give master control module another chance if this is first call to + jpeg_write_raw_data. This lets output of the frame/scan headers be + delayed so that application can write COM, etc, markers between + jpeg_start_compress and jpeg_write_raw_data. } + + if (cinfo^.master^.call_pass_startup) then + cinfo^.master^.pass_startup (cinfo); + + { Verify that at least one iMCU row has been passed. } + lines_per_iMCU_row := cinfo^.max_v_samp_factor * DCTSIZE; + if (num_lines < lines_per_iMCU_row) then + ERREXIT(j_common_ptr(cinfo), JERR_BUFFER_SIZE); + + { Directly compress the row. } + if (not cinfo^.coef^.compress_data (cinfo, data)) then + begin + { If compressor did not consume the whole row, suspend processing. } + jpeg_write_raw_data := 0; + exit; + end; + + { OK, we processed one iMCU row. } + Inc(cinfo^.next_scanline, lines_per_iMCU_row); + jpeg_write_raw_data := lines_per_iMCU_row; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jccoefct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jccoefct_del.pas new file mode 100644 index 0000000..839e7de --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jccoefct_del.pas @@ -0,0 +1,524 @@ +Unit jccoefct_del; + +{ This file contains the coefficient buffer controller for compression. + This controller is the top level of the JPEG compressor proper. + The coefficient buffer lies between forward-DCT and entropy encoding steps.} + +{ Original: jccoefct.c; Copyright (C) 1994-1997, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jerror_del, + jdeferr_del, + jutils_del, + jpeglib_del; + + +{ We use a full-image coefficient buffer when doing Huffman optimization, + and also for writing multiple-scan JPEG files. In all cases, the DCT + step is run during the first pass, and subsequent passes need only read + the buffered coefficients. } +{$ifdef ENTROPY_OPT_SUPPORTED} + {$define FULL_COEF_BUFFER_SUPPORTED} +{$else} + {$ifdef C_MULTISCAN_FILES_SUPPORTED} + {$define FULL_COEF_BUFFER_SUPPORTED} + {$endif} +{$endif} + +{ Initialize coefficient buffer controller. } + +{GLOBAL} +procedure jinit_c_coef_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); + +implementation + +{ Private buffer controller object } + +type + my_coef_ptr = ^my_coef_controller; + my_coef_controller = record + pub : jpeg_c_coef_controller; { public fields } + + iMCU_row_num : JDIMENSION; { iMCU row # within image } + mcu_ctr : JDIMENSION; { counts MCUs processed in current row } + MCU_vert_offset : int; { counts MCU rows within iMCU row } + MCU_rows_per_iMCU_row : int; { number of such rows needed } + + { For single-pass compression, it's sufficient to buffer just one MCU + (although this may prove a bit slow in practice). We allocate a + workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each + MCU constructed and sent. (On 80x86, the workspace is FAR even though + it's not really very big; this is to keep the module interfaces unchanged + when a large coefficient buffer is necessary.) + In multi-pass modes, this array points to the current MCU's blocks + within the virtual arrays. } + + MCU_buffer : array[0..C_MAX_BLOCKS_IN_MCU-1] of JBLOCKROW; + + { In multi-pass modes, we need a virtual block array for each component. } + whole_image : array[0..MAX_COMPONENTS-1] of jvirt_barray_ptr; + end; + + +{ Forward declarations } +{METHODDEF} +function compress_data(cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; forward; +{$ifdef FULL_COEF_BUFFER_SUPPORTED +{METHODDEF} +function compress_first_pass(cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; forward; +{METHODDEF} +function compress_output(cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; forward; +{$endif} + + +{LOCAL} +procedure start_iMCU_row (cinfo : j_compress_ptr); +{ Reset within-iMCU-row counters for a new row } +var + coef : my_coef_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + { In an interleaved scan, an MCU row is the same as an iMCU row. + In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + But at the bottom of the image, process only what's left. } + if (cinfo^.comps_in_scan > 1) then + begin + coef^.MCU_rows_per_iMCU_row := 1; + end + else + begin + if (coef^.iMCU_row_num < (cinfo^.total_iMCU_rows-1)) then + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.v_samp_factor + else + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.last_row_height; + end; + + coef^.mcu_ctr := 0; + coef^.MCU_vert_offset := 0; +end; + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_coef (cinfo : j_compress_ptr; + pass_mode : J_BUF_MODE); +var + coef : my_coef_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + coef^.iMCU_row_num := 0; + start_iMCU_row(cinfo); + + case (pass_mode) of + JBUF_PASS_THRU: + begin + if (coef^.whole_image[0] <> NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + coef^.pub.compress_data := compress_data; + end; +{$ifdef FULL_COEF_BUFFER_SUPPORTED} + JBUF_SAVE_AND_PASS: + begin + if (coef^.whole_image[0] = NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + coef^.pub.compress_data := compress_first_pass; + end; + JBUF_CRANK_DEST: + begin + if (coef^.whole_image[0] = NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + coef^.pub.compress_data := compress_output; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + end; +end; + + +{ Process some data in the single-pass case. + We process the equivalent of one fully interleaved MCU row ("iMCU" row) + per call, ie, v_samp_factor block rows for each component in the image. + Returns TRUE if the iMCU row is completed, FALSE if suspended. + + NB: input_buf contains a plane for each component in image, + which we index according to the component's SOF position. } + + +{METHODDEF} +function compress_data (cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; +var + coef : my_coef_ptr; + MCU_col_num : JDIMENSION; { index of current MCU within row } + last_MCU_col : JDIMENSION; + last_iMCU_row : JDIMENSION; + blkn, bi, ci, yindex, yoffset, blockcnt : int; + ypos, xpos : JDIMENSION; + compptr : jpeg_component_info_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + last_MCU_col := cinfo^.MCUs_per_row - 1; + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + { Loop to write as much as one whole iMCU row } + for yoffset := coef^.MCU_vert_offset to pred(coef^.MCU_rows_per_iMCU_row) do + begin + for MCU_col_num := coef^.mcu_ctr to last_MCU_col do + begin + { Determine where data comes from in input_buf and do the DCT thing. + Each call on forward_DCT processes a horizontal row of DCT blocks + as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks + sequentially. Dummy blocks at the right or bottom edge are filled in + specially. The data in them does not matter for image reconstruction, + so we fill them with values that will encode to the smallest amount of + data, viz: all zeroes in the AC entries, DC entries equal to previous + block's DC value. (Thanks to Thomas Kinsman for this idea.) } + + blkn := 0; + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + if (MCU_col_num < last_MCU_col) then + blockcnt := compptr^.MCU_width + else + blockcnt := compptr^.last_col_width; + xpos := MCU_col_num * compptr^.MCU_sample_width; + ypos := yoffset * DCTSIZE; { ypos = (yoffset+yindex) * DCTSIZE } + for yindex := 0 to pred(compptr^.MCU_height) do + begin + if (coef^.iMCU_row_num < last_iMCU_row) or + (yoffset+yindex < compptr^.last_row_height) then + begin + cinfo^.fdct^.forward_DCT (cinfo, compptr, + input_buf^[compptr^.component_index], + coef^.MCU_buffer[blkn], + ypos, xpos, JDIMENSION (blockcnt)); + + if (blockcnt < compptr^.MCU_width) then + begin + { Create some dummy blocks at the right edge of the image. } + jzero_far({FAR}pointer(coef^.MCU_buffer[blkn + blockcnt]), + (compptr^.MCU_width - blockcnt) * SIZEOF(JBLOCK)); + for bi := blockcnt to pred(compptr^.MCU_width) do + begin + coef^.MCU_buffer[blkn+bi]^[0][0] := coef^.MCU_buffer[blkn+bi-1]^[0][0]; + end; + end; + end + else + begin + { Create a row of dummy blocks at the bottom of the image. } + jzero_far({FAR}pointer(coef^.MCU_buffer[blkn]), + compptr^.MCU_width * SIZEOF(JBLOCK)); + for bi := 0 to pred(compptr^.MCU_width) do + begin + coef^.MCU_buffer[blkn+bi]^[0][0] := coef^.MCU_buffer[blkn-1]^[0][0]; + end; + end; + Inc(blkn, compptr^.MCU_width); + Inc(ypos, DCTSIZE); + end; + end; + { Try to write the MCU. In event of a suspension failure, we will + re-DCT the MCU on restart (a bit inefficient, could be fixed...) } + + if (not cinfo^.entropy^.encode_mcu (cinfo, JBLOCKARRAY(@coef^.MCU_buffer)^)) then + begin + { Suspension forced; update state counters and exit } + coef^.MCU_vert_offset := yoffset; + coef^.mcu_ctr := MCU_col_num; + compress_data := FALSE; + exit; + end; + end; + { Completed an MCU row, but perhaps not an iMCU row } + coef^.mcu_ctr := 0; + end; + { Completed the iMCU row, advance counters for next one } + Inc(coef^.iMCU_row_num); + start_iMCU_row(cinfo); + compress_data := TRUE; +end; + + +{$ifdef FULL_COEF_BUFFER_SUPPORTED} + +{ Process some data in the first pass of a multi-pass case. + We process the equivalent of one fully interleaved MCU row ("iMCU" row) + per call, ie, v_samp_factor block rows for each component in the image. + This amount of data is read from the source buffer, DCT'd and quantized, + and saved into the virtual arrays. We also generate suitable dummy blocks + as needed at the right and lower edges. (The dummy blocks are constructed + in the virtual arrays, which have been padded appropriately.) This makes + it possible for subsequent passes not to worry about real vs. dummy blocks. + + We must also emit the data to the entropy encoder. This is conveniently + done by calling compress_output() after we've loaded the current strip + of the virtual arrays. + + NB: input_buf contains a plane for each component in image. All + components are DCT'd and loaded into the virtual arrays in this pass. + However, it may be that only a subset of the components are emitted to + the entropy encoder during this first pass; be careful about looking + at the scan-dependent variables (MCU dimensions, etc). } + +{METHODDEF} +function compress_first_pass (cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; +var + coef : my_coef_ptr; + last_iMCU_row : JDIMENSION; + blocks_across, MCUs_across, MCUindex : JDIMENSION; + bi, ci, h_samp_factor, block_row, block_rows, ndummy : int; + lastDC : JCOEF; + compptr : jpeg_component_info_ptr; + buffer : JBLOCKARRAY; + thisblockrow, lastblockrow : JBLOCKROW; +begin + coef := my_coef_ptr (cinfo^.coef); + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Align the virtual buffer for this component. } + buffer := cinfo^.mem^.access_virt_barray + (j_common_ptr(cinfo), coef^.whole_image[ci], + coef^.iMCU_row_num * compptr^.v_samp_factor, + JDIMENSION (compptr^.v_samp_factor), TRUE); + { Count non-dummy DCT block rows in this iMCU row. } + if (coef^.iMCU_row_num < last_iMCU_row) then + block_rows := compptr^.v_samp_factor + else + begin + { NB: can't use last_row_height here, since may not be set! } + block_rows := int (compptr^.height_in_blocks mod compptr^.v_samp_factor); + if (block_rows = 0) then + block_rows := compptr^.v_samp_factor; + end; + blocks_across := compptr^.width_in_blocks; + h_samp_factor := compptr^.h_samp_factor; + { Count number of dummy blocks to be added at the right margin. } + ndummy := int (blocks_across mod h_samp_factor); + if (ndummy > 0) then + ndummy := h_samp_factor - ndummy; + { Perform DCT for all non-dummy blocks in this iMCU row. Each call + on forward_DCT processes a complete horizontal row of DCT blocks. } + + for block_row := 0 to pred(block_rows) do + begin + thisblockrow := buffer^[block_row]; + cinfo^.fdct^.forward_DCT (cinfo, compptr, + input_buf^[ci], + thisblockrow, + JDIMENSION (block_row * DCTSIZE), + JDIMENSION (0), + blocks_across); + if (ndummy > 0) then + begin + { Create dummy blocks at the right edge of the image. } + Inc(JBLOCK_PTR(thisblockrow), blocks_across); { => first dummy block } + jzero_far({FAR}pointer(thisblockrow), ndummy * SIZEOF(JBLOCK)); + {lastDC := thisblockrow^[-1][0];} + { work around Range Checking } + Dec(JBLOCK_PTR(thisblockrow)); + lastDC := thisblockrow^[0][0]; + Inc(JBLOCK_PTR(thisblockrow)); + + for bi := 0 to pred(ndummy) do + begin + thisblockrow^[bi][0] := lastDC; + end; + end; + end; + { If at end of image, create dummy block rows as needed. + The tricky part here is that within each MCU, we want the DC values + of the dummy blocks to match the last real block's DC value. + This squeezes a few more bytes out of the resulting file... } + + if (coef^.iMCU_row_num = last_iMCU_row) then + begin + Inc(blocks_across, ndummy); { include lower right corner } + MCUs_across := blocks_across div h_samp_factor; + for block_row := block_rows to pred(compptr^.v_samp_factor) do + begin + thisblockrow := buffer^[block_row]; + lastblockrow := buffer^[block_row-1]; + jzero_far({FAR} pointer(thisblockrow), + size_t(blocks_across * SIZEOF(JBLOCK))); + for MCUindex := 0 to pred(MCUs_across) do + begin + lastDC := lastblockrow^[h_samp_factor-1][0]; + for bi := 0 to pred(h_samp_factor) do + begin + thisblockrow^[bi][0] := lastDC; + end; + Inc(JBLOCK_PTR(thisblockrow), h_samp_factor); { advance to next MCU in row } + Inc(JBLOCK_PTR(lastblockrow), h_samp_factor); + end; + end; + end; + Inc(compptr); + end; + { NB: compress_output will increment iMCU_row_num if successful. + A suspension return will result in redoing all the work above next time.} + + + { Emit data to the entropy encoder, sharing code with subsequent passes } + compress_first_pass := compress_output(cinfo, input_buf); +end; + + +{ Process some data in subsequent passes of a multi-pass case. + We process the equivalent of one fully interleaved MCU row ("iMCU" row) + per call, ie, v_samp_factor block rows for each component in the scan. + The data is obtained from the virtual arrays and fed to the entropy coder. + Returns TRUE if the iMCU row is completed, FALSE if suspended. + + NB: input_buf is ignored; it is likely to be a NIL pointer. } + +{METHODDEF} +function compress_output (cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; +var + coef : my_coef_ptr; + MCU_col_num : JDIMENSION; { index of current MCU within row } + blkn, ci, xindex, yindex, yoffset : int; + start_col : JDIMENSION; + buffer : array[0..MAX_COMPS_IN_SCAN-1] of JBLOCKARRAY; + buffer_ptr : JBLOCKROW; + compptr : jpeg_component_info_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + { Align the virtual buffers for the components used in this scan. + NB: during first pass, this is safe only because the buffers will + already be aligned properly, so jmemmgr.c won't need to do any I/O. } + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + buffer[ci] := cinfo^.mem^.access_virt_barray ( + j_common_ptr(cinfo), coef^.whole_image[compptr^.component_index], + coef^.iMCU_row_num * compptr^.v_samp_factor, + JDIMENSION (compptr^.v_samp_factor), FALSE); + end; + + { Loop to process one whole iMCU row } + for yoffset := coef^.MCU_vert_offset to pred(coef^.MCU_rows_per_iMCU_row) do + begin + for MCU_col_num := coef^.mcu_ctr to pred(cinfo^.MCUs_per_row) do + begin + { Construct list of pointers to DCT blocks belonging to this MCU } + blkn := 0; { index of current DCT block within MCU } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + start_col := MCU_col_num * compptr^.MCU_width; + for yindex := 0 to pred(compptr^.MCU_height) do + begin + buffer_ptr := JBLOCKROW(@ buffer[ci]^[yindex+yoffset]^[start_col]); + for xindex := 0 to pred(compptr^.MCU_width) do + begin + coef^.MCU_buffer[blkn] := buffer_ptr; + Inc(blkn); + Inc(JBLOCK_PTR(buffer_ptr)); + end; + end; + end; + { Try to write the MCU. } + if (not cinfo^.entropy^.encode_mcu (cinfo, coef^.MCU_buffer)) then + begin + { Suspension forced; update state counters and exit } + coef^.MCU_vert_offset := yoffset; + coef^.mcu_ctr := MCU_col_num; + compress_output := FALSE; + exit; + end; + end; + { Completed an MCU row, but perhaps not an iMCU row } + coef^.mcu_ctr := 0; + end; + { Completed the iMCU row, advance counters for next one } + Inc(coef^.iMCU_row_num); + start_iMCU_row(cinfo); + compress_output := TRUE; +end; + +{$endif} { FULL_COEF_BUFFER_SUPPORTED } + + +{ Initialize coefficient buffer controller. } + +{GLOBAL} +procedure jinit_c_coef_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); +var + coef : my_coef_ptr; +var + buffer : JBLOCKROW; + i : int; +var + ci : int; + compptr : jpeg_component_info_ptr; +begin + coef := my_coef_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_coef_controller)) ); + cinfo^.coef := jpeg_c_coef_controller_ptr(coef); + coef^.pub.start_pass := start_pass_coef; + + { Create the coefficient buffer. } + if (need_full_buffer) then + begin +{$ifdef FULL_COEF_BUFFER_SUPPORTED} + { Allocate a full-image virtual array for each component, } + { padded to a multiple of samp_factor DCT blocks in each direction. } + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + coef^.whole_image[ci] := cinfo^.mem^.request_virt_barray + (j_common_ptr(cinfo), JPOOL_IMAGE, FALSE, + JDIMENSION (jround_up( long (compptr^.width_in_blocks), + long (compptr^.h_samp_factor) )), + JDIMENSION (jround_up(long (compptr^.height_in_blocks), + long (compptr^.v_samp_factor))), + JDIMENSION (compptr^.v_samp_factor)); + Inc(compptr); + end; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); +{$endif} + end + else + begin + { We only need a single-MCU buffer. } + buffer := JBLOCKROW ( + cinfo^.mem^.alloc_large (j_common_ptr(cinfo), JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)) ); + for i := 0 to pred(C_MAX_BLOCKS_IN_MCU) do + begin + coef^.MCU_buffer[i] := JBLOCKROW(@ buffer^[i]); + end; + coef^.whole_image[0] := NIL; { flag for no virtual arrays } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jccolor_del.pas b/mseide-msegui/lib/common/fpccompatibility/jccolor_del.pas new file mode 100644 index 0000000..f3f3ebc --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jccolor_del.pas @@ -0,0 +1,531 @@ +Unit jccolor_del; + +{ This file contains input colorspace conversion routines. } + +{ Original : jccolor.c ; Copyright (C) 1991-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del; + +{ Module initialization routine for input colorspace conversion. } + +{GLOBAL} +procedure jinit_color_converter (cinfo : j_compress_ptr); + +implementation + +{ Private subobject } +type + jTInt32 = 0..Pred(MaxInt div SizeOf(INT32)); + INT32_FIELD = array[jTInt32] of INT32; + INT32_FIELD_PTR = ^INT32_FIELD; + +type + my_cconvert_ptr = ^my_color_converter; + my_color_converter = record + pub : jpeg_color_converter; { public fields } + + { Private state for RGB -> YCC conversion } + rgb_ycc_tab : INT32_FIELD_PTR; { => table for RGB to YCbCr conversion } + end; {my_color_converter;} + + +{*************** RGB -> YCbCr conversion: most common case *************} + +{ + YCbCr is defined per CCIR 601-1, except that Cb and Cr are + normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + The conversion equations to be implemented are therefore + Y = 0.29900 * R + 0.58700 * G + 0.11400 * B + Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE + Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE + (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2, + rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and + negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0) + were not represented exactly. Now we sacrifice exact representation of + maximum red and maximum blue in order to get exact grayscales. + + To avoid floating-point arithmetic, we represent the fractional constants + as integers scaled up by 2^16 (about 4 digits precision); we have to divide + the products by 2^16, with appropriate rounding, to get the correct answer. + + For even more speed, we avoid doing any multiplications in the inner loop + by precalculating the constants times R,G,B for all possible values. + For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + for 12-bit samples it is still acceptable. It's not very reasonable for + 16-bit samples, but if you want lossless storage you shouldn't be changing + colorspace anyway. + The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included + in the tables to save adding them separately in the inner loop. } +const + SCALEBITS = 16; { speediest right-shift on some machines } + CBCR_OFFSET = INT32(CENTERJSAMPLE shl SCALEBITS); + ONE_HALF = INT32(1) shl (SCALEBITS-1); + + +{ We allocate one big table and divide it up into eight parts, instead of + doing eight alloc_small requests. This lets us use a single table base + address, which can be held in a register in the inner loops on many + machines (more than can hold all eight addresses, anyway). } + + R_Y_OFF = 0; { offset to R => Y section } + G_Y_OFF = 1*(MAXJSAMPLE+1); { offset to G => Y section } + B_Y_OFF = 2*(MAXJSAMPLE+1); { etc. } + R_CB_OFF = 3*(MAXJSAMPLE+1); + G_CB_OFF = 4*(MAXJSAMPLE+1); + B_CB_OFF = 5*(MAXJSAMPLE+1); + R_CR_OFF = B_CB_OFF; { B=>Cb, R=>Cr are the same } + G_CR_OFF = 6*(MAXJSAMPLE+1); + B_CR_OFF = 7*(MAXJSAMPLE+1); + TABLE_SIZE = 8*(MAXJSAMPLE+1); + + +{ Initialize for RGB->YCC colorspace conversion. } + +{METHODDEF} +procedure rgb_ycc_start (cinfo : j_compress_ptr); +const + FIX_0_29900 = INT32(Round (0.29900 * (1 shl SCALEBITS)) ); + FIX_0_58700 = INT32(Round (0.58700 * (1 shl SCALEBITS)) ); + FIX_0_11400 = INT32(Round (0.11400 * (1 shl SCALEBITS)) ); + FIX_0_16874 = INT32(Round (0.16874 * (1 shl SCALEBITS)) ); + FIX_0_33126 = INT32(Round (0.33126 * (1 shl SCALEBITS)) ); + FIX_0_50000 = INT32(Round (0.50000 * (1 shl SCALEBITS)) ); + FIX_0_41869 = INT32(Round (0.41869 * (1 shl SCALEBITS)) ); + FIX_0_08131 = INT32(Round (0.08131 * (1 shl SCALEBITS)) ); +var + cconvert : my_cconvert_ptr; + rgb_ycc_tab : INT32_FIELD_PTR; + i : INT32; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + + { Allocate and fill in the conversion tables. } + rgb_ycc_tab := INT32_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + (TABLE_SIZE * SIZEOF(INT32))) ); + cconvert^.rgb_ycc_tab := rgb_ycc_tab; + + for i := 0 to MAXJSAMPLE do + begin + rgb_ycc_tab^[i+R_Y_OFF] := FIX_0_29900 * i; + rgb_ycc_tab^[i+G_Y_OFF] := FIX_0_58700 * i; + rgb_ycc_tab^[i+B_Y_OFF] := FIX_0_11400 * i + ONE_HALF; + rgb_ycc_tab^[i+R_CB_OFF] := (-FIX_0_16874) * i; + rgb_ycc_tab^[i+G_CB_OFF] := (-FIX_0_33126) * i; + { We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. + This ensures that the maximum output will round to MAXJSAMPLE + not MAXJSAMPLE+1, and thus that we don't have to range-limit. } + + rgb_ycc_tab^[i+B_CB_OFF] := FIX_0_50000 * i + CBCR_OFFSET + ONE_HALF-1; +{ B=>Cb and R=>Cr tables are the same + rgb_ycc_tab^[i+R_CR_OFF] := FIX_0_50000 * i + CBCR_OFFSET + ONE_HALF-1; +} + rgb_ycc_tab^[i+G_CR_OFF] := (-FIX_0_41869) * i; + rgb_ycc_tab^[i+B_CR_OFF] := (-FIX_0_08131) * i; + end; +end; + + +{ Convert some rows of samples to the JPEG colorspace. + + Note that we change from the application's interleaved-pixel format + to our internal noninterleaved, one-plane-per-component format. + The input buffer is therefore three times as wide as the output buffer. + + A starting row offset is provided only for the output buffer. The caller + can easily adjust the passed input_buf value to accommodate any row + offset required on that side. } + +{METHODDEF} +procedure rgb_ycc_convert (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows : int); +var + cconvert : my_cconvert_ptr; + {register} r, g, b : int; + {register} ctab : INT32_FIELD_PTR; + {register} inptr : JSAMPROW; + {register} outptr0, outptr1, outptr2 : JSAMPROW; + {register} col : JDIMENSION; + num_cols : JDIMENSION; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + ctab := cconvert^.rgb_ycc_tab; + num_cols := cinfo^.image_width; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr := input_buf^[0]; + Inc(JSAMPROW_PTR(input_buf)); + outptr0 := output_buf^[0]^[output_row]; + outptr1 := output_buf^[1]^[output_row]; + outptr2 := output_buf^[2]^[output_row]; + Inc(output_row); + for col := 0 to pred(num_cols) do + begin + r := GETJSAMPLE(inptr^[RGB_RED]); + g := GETJSAMPLE(inptr^[RGB_GREEN]); + b := GETJSAMPLE(inptr^[RGB_BLUE]); + Inc(JSAMPLE_PTR(inptr), RGB_PIXELSIZE); + { If the inputs are 0..MAXJSAMPLE, the outputs of these equations + must be too; we do not need an explicit range-limiting operation. + Hence the value being shifted is never negative, and we don't + need the general RIGHT_SHIFT macro. } + + { Y } + outptr0^[col] := JSAMPLE( + ((ctab^[r+R_Y_OFF] + ctab^[g+G_Y_OFF] + ctab^[b+B_Y_OFF]) + shr SCALEBITS) ); + { Cb } + outptr1^[col] := JSAMPLE( + ((ctab^[r+R_CB_OFF] + ctab^[g+G_CB_OFF] + ctab^[b+B_CB_OFF]) + shr SCALEBITS) ); + { Cr } + outptr2^[col] := JSAMPLE( + ((ctab^[r+R_CR_OFF] + ctab^[g+G_CR_OFF] + ctab^[b+B_CR_OFF]) + shr SCALEBITS) ); + end; + end; +end; + + +{*************** Cases other than RGB -> YCbCr *************} + + +{ Convert some rows of samples to the JPEG colorspace. + This version handles RGB -> grayscale conversion, which is the same + as the RGB -> Y portion of RGB -> YCbCr. + We assume rgb_ycc_start has been called (we only use the Y tables). } + +{METHODDEF} +procedure rgb_gray_convert (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows : int); +var + cconvert : my_cconvert_ptr; + {register} r, g, b : int; + {register} ctab :INT32_FIELD_PTR; + {register} inptr : JSAMPROW; + {register} outptr : JSAMPROW; + {register} col : JDIMENSION; + num_cols : JDIMENSION; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + ctab := cconvert^.rgb_ycc_tab; + num_cols := cinfo^.image_width; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr := input_buf^[0]; + Inc(JSAMPROW_PTR(input_buf)); + outptr := output_buf^[0]^[output_row]; + Inc(output_row); + for col := 0 to pred(num_cols) do + begin + r := GETJSAMPLE(inptr^[RGB_RED]); + g := GETJSAMPLE(inptr^[RGB_GREEN]); + b := GETJSAMPLE(inptr^[RGB_BLUE]); + Inc(JSAMPLE_PTR(inptr), RGB_PIXELSIZE); + { Y } + outptr^[col] := JSAMPLE ( + ((ctab^[r+R_Y_OFF] + ctab^[g+G_Y_OFF] + ctab^[b+B_Y_OFF]) + shr SCALEBITS) ); + end; + end; +end; + + +{ Convert some rows of samples to the JPEG colorspace. + This version handles Adobe-style CMYK -> YCCK conversion, + where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same + conversion as above, while passing K (black) unchanged. + We assume rgb_ycc_start has been called. } + +{METHODDEF} +procedure cmyk_ycck_convert (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows : int); +var + cconvert : my_cconvert_ptr; + {register} r, g, b : int; + {register} ctab : INT32_FIELD_PTR; + {register} inptr : JSAMPROW; + {register} outptr0, outptr1, outptr2, outptr3 : JSAMPROW; + {register} col : JDIMENSION; + num_cols : JDIMENSION; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + ctab := cconvert^.rgb_ycc_tab; + num_cols := cinfo^.image_width; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr := input_buf^[0]; + Inc(JSAMPROW_PTR(input_buf)); + outptr0 := output_buf^[0]^[output_row]; + outptr1 := output_buf^[1]^[output_row]; + outptr2 := output_buf^[2]^[output_row]; + outptr3 := output_buf^[3]^[output_row]; + Inc(output_row); + for col := 0 to pred(num_cols) do + begin + r := MAXJSAMPLE - GETJSAMPLE(inptr^[0]); + g := MAXJSAMPLE - GETJSAMPLE(inptr^[1]); + b := MAXJSAMPLE - GETJSAMPLE(inptr^[2]); + { K passes through as-is } + outptr3^[col] := inptr^[3]; { don't need GETJSAMPLE here } + Inc(JSAMPLE_PTR(inptr), 4); + { If the inputs are 0..MAXJSAMPLE, the outputs of these equations + must be too; we do not need an explicit range-limiting operation. + Hence the value being shifted is never negative, and we don't + need the general RIGHT_SHIFT macro. } + + { Y } + outptr0^[col] := JSAMPLE ( + ((ctab^[r+R_Y_OFF] + ctab^[g+G_Y_OFF] + ctab^[b+B_Y_OFF]) + shr SCALEBITS) ); + { Cb } + outptr1^[col] := JSAMPLE( + ((ctab^[r+R_CB_OFF] + ctab^[g+G_CB_OFF] + ctab^[b+B_CB_OFF]) + shr SCALEBITS) ); + { Cr } + outptr2^[col] := JSAMPLE ( + ((ctab^[r+R_CR_OFF] + ctab^[g+G_CR_OFF] + ctab^[b+B_CR_OFF]) + shr SCALEBITS) ); + end; + end; +end; + + +{ Convert some rows of samples to the JPEG colorspace. + This version handles grayscale output with no conversion. + The source can be either plain grayscale or YCbCr (since Y = gray). } + +{METHODDEF} +procedure grayscale_convert (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows: int); +var + {register} inptr : JSAMPROW; + {register} outptr : JSAMPROW; + {register} col : JDIMENSION; + num_cols :JDIMENSION; + instride : int; +begin + num_cols := cinfo^.image_width; + instride := cinfo^.input_components; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr := input_buf^[0]; + Inc(JSAMPROW_PTR(input_buf)); + outptr := output_buf^[0]^[output_row]; + Inc(output_row); + for col := 0 to pred(num_cols) do + begin + outptr^[col] := inptr^[0]; { don't need GETJSAMPLE() here } + Inc(JSAMPLE_PTR(inptr), instride); + end; + end; +end; + + +{ Convert some rows of samples to the JPEG colorspace. + This version handles multi-component colorspaces without conversion. + We assume input_components = num_components. } + +{METHODDEF} +procedure null_convert (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows : int); +var + {register} inptr : JSAMPROW; + {register} outptr : JSAMPROW; + {register} col : JDIMENSION; + {register} ci : int; + nc : int; + num_cols : JDIMENSION; +begin + nc := cinfo^.num_components; + num_cols := cinfo^.image_width; + + while (num_rows > 0) do + begin + Dec(num_rows); + { It seems fastest to make a separate pass for each component. } + for ci := 0 to pred(nc) do + begin + inptr := input_buf^[0]; + outptr := output_buf^[ci]^[output_row]; + for col := 0 to pred(num_cols) do + begin + outptr^[col] := inptr^[ci]; { don't need GETJSAMPLE() here } + Inc(JSAMPLE_PTR(inptr), nc); + end; + end; + Inc(JSAMPROW_PTR(input_buf)); + Inc(output_row); + end; +end; + + +{ Empty method for start_pass. } + +{METHODDEF} +procedure null_method (cinfo : j_compress_ptr); +begin + { no work needed } +end; + + +{ Module initialization routine for input colorspace conversion. } + +{GLOBAL} +procedure jinit_color_converter (cinfo : j_compress_ptr); +var + cconvert : my_cconvert_ptr; +begin + cconvert := my_cconvert_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_color_converter)) ); + cinfo^.cconvert := jpeg_color_converter_ptr(cconvert); + { set start_pass to null method until we find out differently } + cconvert^.pub.start_pass := null_method; + + { Make sure input_components agrees with in_color_space } + case (cinfo^.in_color_space) of + JCS_GRAYSCALE: + if (cinfo^.input_components <> 1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); + +{$ifdef RGB_PIXELSIZE <> 3} + JCS_RGB: + if (cinfo^.input_components <> RGB_PIXELSIZE) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); +{$else} { share code with YCbCr } + JCS_RGB, +{$endif} + JCS_YCbCr: + if (cinfo^.input_components <> 3) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); + + JCS_CMYK, + JCS_YCCK: + if (cinfo^.input_components <> 4) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); + + else { JCS_UNKNOWN can be anything } + if (cinfo^.input_components < 1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); + end; + + { Check num_components, set conversion method based on requested space } + case (cinfo^.jpeg_color_space) of + JCS_GRAYSCALE: + begin + if (cinfo^.num_components <> 1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + if (cinfo^.in_color_space = JCS_GRAYSCALE) then + cconvert^.pub.color_convert := grayscale_convert + else + if (cinfo^.in_color_space = JCS_RGB) then + begin + cconvert^.pub.start_pass := rgb_ycc_start; + cconvert^.pub.color_convert := rgb_gray_convert; + end + else + if (cinfo^.in_color_space = JCS_YCbCr) then + cconvert^.pub.color_convert := grayscale_convert + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_RGB: + begin + if (cinfo^.num_components <> 3) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + if (cinfo^.in_color_space = JCS_RGB) and (RGB_PIXELSIZE = 3) then + cconvert^.pub.color_convert := null_convert + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_YCbCr: + begin + if (cinfo^.num_components <> 3) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + if (cinfo^.in_color_space = JCS_RGB) then + begin + cconvert^.pub.start_pass := rgb_ycc_start; + cconvert^.pub.color_convert := rgb_ycc_convert; + end + else + if (cinfo^.in_color_space = JCS_YCbCr) then + cconvert^.pub.color_convert := null_convert + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_CMYK: + begin + if (cinfo^.num_components <> 4) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + if (cinfo^.in_color_space = JCS_CMYK) then + cconvert^.pub.color_convert := null_convert + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_YCCK: + begin + if (cinfo^.num_components <> 4) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + if (cinfo^.in_color_space = JCS_CMYK) then + begin + cconvert^.pub.start_pass := rgb_ycc_start; + cconvert^.pub.color_convert := cmyk_ycck_convert; + end + else + if (cinfo^.in_color_space = JCS_YCCK) then + cconvert^.pub.color_convert := null_convert + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + else { allow null conversion of JCS_UNKNOWN } + begin + if (cinfo^.jpeg_color_space <> cinfo^.in_color_space) or + (cinfo^.num_components <> cinfo^.input_components) then + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + cconvert^.pub.color_convert := null_convert; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcdctmgr_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcdctmgr_del.pas new file mode 100644 index 0000000..7305a6e --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcdctmgr_del.pas @@ -0,0 +1,516 @@ +Unit jcdctmgr_del; + +{ Original : jcdctmgr.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +{ This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains the forward-DCT management logic. + This code selects a particular DCT implementation to be used, + and it performs related housekeeping chores including coefficient + quantization. } + +//modified 2013 by Martin Schreiber + +interface + +//{$N+} +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jdct_del, { Private declarations for DCT subsystem } + jfdctint_del, jfdctfst_del, jfdctflt_del; + +{ Initialize FDCT manager. } + +{GLOBAL} +procedure jinit_forward_dct (cinfo : j_compress_ptr); + +implementation + + +{ Private subobject for this module } + +type + my_fdct_ptr = ^my_fdct_controller; + my_fdct_controller = record + pub : jpeg_forward_dct; { public fields } + + { Pointer to the DCT routine actually in use } + do_dct : forward_DCT_method_ptr; + + { The actual post-DCT divisors --- not identical to the quant table + entries, because of scaling (especially for an unnormalized DCT). + Each table is given in normal array order. } + + divisors : array[0..NUM_QUANT_TBLS-1] of DCTELEM_FIELD_PTR; + + {$ifdef DCT_FLOAT_SUPPORTED} + { Same as above for the floating-point case. } + do_float_dct : float_DCT_method_ptr; + float_divisors : array[0..NUM_QUANT_TBLS-1] of FAST_FLOAT_FIELD_PTR; + {$endif} + end; + + +{ Initialize for a processing pass. + Verify that all referenced Q-tables are present, and set up + the divisor table for each one. + In the current implementation, DCT of all components is done during + the first pass, even if only some components will be output in the + first scan. Hence all components should be examined here. } + +{METHODDEF} +procedure start_pass_fdctmgr (cinfo : j_compress_ptr); +var + fdct : my_fdct_ptr; + ci, qtblno, i : int; + compptr : jpeg_component_info_ptr; + qtbl : JQUANT_TBL_PTR; + dtbl : DCTELEM_FIELD_PTR; +{$ifdef DCT_IFAST_SUPPORTED} +const + CONST_BITS = 14; + aanscales : array[0..DCTSIZE2-1] of INT16 = + ({ precomputed values scaled up by 14 bits } + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247); + {SHIFT_TEMPS} + + { Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + + function DESCALE(x : INT32; n : int) : INT32; + var + shift_temp : INT32; + begin + shift_temp := x + (INT32(1) shl (n-1)); + {$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + {$endif} + Descale := (shift_temp shr n); + end; + +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} +var + fdtbl : FAST_FLOAT_FIELD_PTR; + row, col : int; +const + aanscalefactor : array[0..DCTSIZE-1] of double = + (1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379); +{$endif} +begin + fdct := my_fdct_ptr (cinfo^.fdct); + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + qtblno := compptr^.quant_tbl_no; + { Make sure specified quantization table is present } + if (qtblno < 0) or (qtblno >= NUM_QUANT_TBLS) or + (cinfo^.quant_tbl_ptrs[qtblno] = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_QUANT_TABLE, qtblno); + qtbl := cinfo^.quant_tbl_ptrs[qtblno]; + { Compute divisors for this quant table } + { We may do this more than once for same table, but it's not a big deal } + case (cinfo^.dct_method) of +{$ifdef DCT_ISLOW_SUPPORTED} + JDCT_ISLOW: + begin + { For LL&M IDCT method, divisors are equal to raw quantization + coefficients multiplied by 8 (to counteract scaling). } + + if (fdct^.divisors[qtblno] = NIL) then + begin + fdct^.divisors[qtblno] := DCTELEM_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)) ); + end; + dtbl := fdct^.divisors[qtblno]; + for i := 0 to pred(DCTSIZE2) do + begin + dtbl^[i] := (DCTELEM(qtbl^.quantval[i])) shl 3; + end; + end; +{$endif} +{$ifdef DCT_IFAST_SUPPORTED} + JDCT_IFAST: + begin + { For AA&N IDCT method, divisors are equal to quantization + coefficients scaled by scalefactor[row]*scalefactor[col], where + scalefactor[0] := 1 + scalefactor[k] := cos(k*PI/16) * sqrt(2) for k=1..7 + We apply a further scale factor of 8. } + + + if (fdct^.divisors[qtblno] = NIL) then + begin + fdct^.divisors[qtblno] := DCTELEM_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)) ); + end; + dtbl := fdct^.divisors[qtblno]; + for i := 0 to pred(DCTSIZE2) do + begin + dtbl^[i] := DCTELEM( + {MULTIPLY16V16} + DESCALE( INT32(qtbl^.quantval[i]) * INT32 (aanscales[i]), + CONST_BITS-3) ); + end; + end; +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} + + JDCT_FLOAT: + begin + { For float AA&N IDCT method, divisors are equal to quantization + coefficients scaled by scalefactor[row]*scalefactor[col], where + scalefactor[0] := 1 + scalefactor[k] := cos(k*PI/16) * sqrt(2) for k=1..7 + We apply a further scale factor of 8. + What's actually stored is 1/divisor so that the inner loop can + use a multiplication rather than a division. } + + if (fdct^.float_divisors[qtblno] = NIL) then + begin + fdct^.float_divisors[qtblno] := FAST_FLOAT_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(FAST_FLOAT)) ); + end; + fdtbl := fdct^.float_divisors[qtblno]; + i := 0; + for row := 0 to pred(DCTSIZE) do + begin + for col := 0 to pred(DCTSIZE) do + begin + fdtbl^[i] := {FAST_FLOAT} + (1.0 / (( {double}(qtbl^.quantval[i]) * + aanscalefactor[row] * aanscalefactor[col] * 8.0))); + Inc(i); + end; + end; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + end; + Inc(compptr); + end; +end; + + +{ Perform forward DCT on one or more blocks of a component. + + The input samples are taken from the sample_data[] array starting at + position start_row/start_col, and moving to the right for any additional + blocks. The quantized coefficients are returned in coef_blocks[]. } + +{METHODDEF} +procedure forward_DCT (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + sample_data : JSAMPARRAY; + coef_blocks : JBLOCKROW; + start_row : JDIMENSION; + start_col : JDIMENSION; + num_blocks : JDIMENSION); +{ This version is used for integer DCT implementations. } +var + { This routine is heavily used, so it's worth coding it tightly. } + fdct : my_fdct_ptr; + do_dct : forward_DCT_method_ptr; + divisors : DCTELEM_FIELD_PTR; + workspace : array[0..DCTSIZE2-1] of DCTELEM; { work area for FDCT subroutine } + bi : JDIMENSION; +var + {register} workspaceptr : DCTELEMPTR; + {register} elemptr : JSAMPLE_PTR; + {register} elemr : int; +{$ifndef DCTSIZE_IS_8} +var + {register} elemc : int; +{$endif} +var + {register} temp, qval : DCTELEM; + {register} i : int; + {register} output_ptr : JCOEFPTR; +begin + fdct := my_fdct_ptr (cinfo^.fdct); + do_dct := fdct^.do_dct; + divisors := fdct^.divisors[compptr^.quant_tbl_no]; + + Inc(JSAMPROW_PTR(sample_data), start_row); { fold in the vertical offset once } + + for bi := 0 to pred(num_blocks) do + begin + + { Load data into workspace, applying unsigned->signed conversion } + + workspaceptr := @workspace[0]; + for elemr := 0 to pred(DCTSIZE) do + begin + elemptr := @sample_data^[elemr]^[start_col]; +{$ifdef DCTSIZE_IS_8} { unroll the inner loop } + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + {Inc(elemptr); - Value never used } +{$else} + for elemc := pred(DCTSIZE) downto 0 do + begin + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + end; +{$endif} + end; + + { Perform the DCT } + do_dct (workspace); + + { Quantize/descale the coefficients, and store into coef_blocks[] } + + output_ptr := JCOEFPTR(@coef_blocks^[bi]); + for i := 0 to pred(DCTSIZE2) do + begin + qval := divisors^[i]; + temp := workspace[i]; + { Divide the coefficient value by qval, ensuring proper rounding. + Since C does not specify the direction of rounding for negative + quotients, we have to force the dividend positive for portability. + + In most files, at least half of the output values will be zero + (at default quantization settings, more like three-quarters...) + so we should ensure that this case is fast. On many machines, + a comparison is enough cheaper than a divide to make a special test + a win. Since both inputs will be nonnegative, we need only test + for a < b to discover whether a/b is 0. + If your machine's division is fast enough, define FAST_DIVIDE. } + + if (temp < 0) then + begin + temp := -temp; + Inc(temp, qval shr 1); { for rounding } + {DIVIDE_BY(temp, qval);} + {$ifdef FAST_DIVIDE} + temp := temp div qval; + {$else} + if (temp >= qval) then + temp := temp div qval + else + temp := 0; + {$endif} + temp := -temp; + end + else + begin + Inc(temp, qval shr 1); { for rounding } + {DIVIDE_BY(temp, qval);} + {$ifdef FAST_DIVIDE} + temp := temp div qval; + {$else} + if (temp >= qval) then + temp := temp div qval + else + temp := 0; + {$endif} + end; + output_ptr^[i] := JCOEF (temp); + end; + Inc(start_col, DCTSIZE); + end; +end; + + +{$ifdef DCT_FLOAT_SUPPORTED} + +{METHODDEF} +procedure forward_DCT_float (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + sample_data : JSAMPARRAY; + coef_blocks : JBLOCKROW; + start_row : JDIMENSION; + start_col : JDIMENSION; + num_blocks : JDIMENSION); +{ This version is used for floating-point DCT implementations. } +var + { This routine is heavily used, so it's worth coding it tightly. } + fdct : my_fdct_ptr; + do_dct : float_DCT_method_ptr; + divisors : FAST_FLOAT_FIELD_PTR; + workspace : array[0..DCTSIZE2-1] of FAST_FLOAT; { work area for FDCT subroutine } + bi : JDIMENSION; +var + {register} workspaceptr : FAST_FLOAT_PTR; + {register} elemptr : JSAMPLE_PTR; + {register} elemr : int; +{$ifndef DCTSIZE_IS_8} +var + {register} elemc : int; +{$endif} +var + {register} temp : FAST_FLOAT; + {register} i : int; + {register} output_ptr : JCOEFPTR; +begin + fdct := my_fdct_ptr (cinfo^.fdct); + do_dct := fdct^.do_float_dct; + divisors := fdct^.float_divisors[compptr^.quant_tbl_no]; + + Inc(JSAMPROW_PTR(sample_data), start_row); { fold in the vertical offset once } + + for bi := 0 to pred(num_blocks) do + begin + { Load data into workspace, applying unsigned->signed conversion } + + workspaceptr := @workspace[0]; + for elemr := 0 to pred(DCTSIZE) do + begin + elemptr := @(sample_data^[elemr]^[start_col]); +{$ifdef DCTSIZE_IS_8} { unroll the inner loop } + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + {Inc(elemptr); - value never used } +{$else} + for elemc := pred(DCTSIZE) downto 0 do + begin + workspaceptr^ := {FAST_FLOAT}( + (GETJSAMPLE(elemptr^) - CENTERJSAMPLE) ); + Inc(workspaceptr); + Inc(elemptr); + end; +{$endif} + end; + + + { Perform the DCT } + do_dct (workspace); + + { Quantize/descale the coefficients, and store into coef_blocks[] } + + output_ptr := JCOEFPTR(@(coef_blocks^[bi])); + + for i := 0 to pred(DCTSIZE2) do + begin + { Apply the quantization and scaling factor } + temp := workspace[i] * divisors^[i]; + { Round to nearest integer. + Since C does not specify the direction of rounding for negative + quotients, we have to force the dividend positive for portability. + The maximum coefficient size is +-16K (for 12-bit data), so this + code should work for either 16-bit or 32-bit ints. } + output_ptr^[i] := JCOEF ( int(Trunc (temp + {FAST_FLOAT}(16384.5))) - 16384); + end; + Inc(start_col, DCTSIZE); + end; +end; + +{$endif} { DCT_FLOAT_SUPPORTED } + + +{ Initialize FDCT manager. } + +{GLOBAL} +procedure jinit_forward_dct (cinfo : j_compress_ptr); +var + fdct : my_fdct_ptr; + i : int; +begin + fdct := my_fdct_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_fdct_controller)) ); + cinfo^.fdct := jpeg_forward_dct_ptr (fdct); + fdct^.pub.start_pass := start_pass_fdctmgr; + + case (cinfo^.dct_method) of +{$ifdef DCT_ISLOW_SUPPORTED} + JDCT_ISLOW: + begin + fdct^.pub.forward_DCT := forward_DCT; + fdct^.do_dct := jpeg_fdct_islow; + end; +{$endif} +{$ifdef DCT_IFAST_SUPPORTED} + JDCT_IFAST: + begin + fdct^.pub.forward_DCT := forward_DCT; + fdct^.do_dct := jpeg_fdct_ifast; + end; +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} + JDCT_FLOAT: + begin + fdct^.pub.forward_DCT := forward_DCT_float; + fdct^.do_float_dct := jpeg_fdct_float; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + end; + + { Mark divisor tables unallocated } + for i := 0 to pred(NUM_QUANT_TBLS) do + begin + fdct^.divisors[i] := NIL; +{$ifdef DCT_FLOAT_SUPPORTED} + fdct^.float_divisors[i] := NIL; +{$endif} + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jchuff_del.pas b/mseide-msegui/lib/common/fpccompatibility/jchuff_del.pas new file mode 100644 index 0000000..163dd14 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jchuff_del.pas @@ -0,0 +1,1118 @@ +Unit jchuff_del; + +{ This file contains Huffman entropy encoding routines. + + Much of the complexity here has to do with supporting output suspension. + If the data destination module demands suspension, we want to be able to + back up to the start of the current MCU. To do this, we copy state + variables into local working storage, and update them back to the + permanent JPEG objects only upon successful completion of an MCU. } + +{ Original: jchuff.c; Copyright (C) 1991-1997, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, { longptr definition missing } + jpeglib_del, + jdeferr_del, + jerror_del, + jutils_del, + jinclude_del, + jcomapi_del; + +{ The legal range of a DCT coefficient is + -1024 .. +1023 for 8-bit data; + -16384 .. +16383 for 12-bit data. + Hence the magnitude should always fit in 10 or 14 bits respectively. } + + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + MAX_COEF_BITS = 10; +{$else} +const + MAX_COEF_BITS = 14; +{$endif} + +{ Derived data constructed for each Huffman table } +{ Declarations shared with jcphuff.c } +type + c_derived_tbl_ptr = ^c_derived_tbl; + c_derived_tbl = record + ehufco : array[0..256-1] of uInt; { code for each symbol } + ehufsi : array[0..256-1] of byte; { length of code for each symbol } + { If no code has been allocated for a symbol S, ehufsi[S] contains 0 } + end; +{ for JCHUFF und JCPHUFF } +type + TLongTable = array[0..256] of long; + TLongTablePtr = ^TLongTable; + +{ Compute the derived values for a Huffman table. + Note this is also used by jcphuff.c. } + +{GLOBAL} +procedure jpeg_make_c_derived_tbl (cinfo : j_compress_ptr; + isDC : boolean; + tblno : int; + var pdtbl : c_derived_tbl_ptr); + +{ Generate the optimal coding for the given counts, fill htbl. + Note this is also used by jcphuff.c. } + +{GLOBAL} +procedure jpeg_gen_optimal_table (cinfo : j_compress_ptr; + htbl : JHUFF_TBL_PTR; + var freq : TLongTable); { Nomssi } + +{ Module initialization routine for Huffman entropy encoding. } + +{GLOBAL} +procedure jinit_huff_encoder (cinfo : j_compress_ptr); + +implementation + +{ Expanded entropy encoder object for Huffman encoding. + + The savable_state subrecord contains fields that change within an MCU, + but must not be updated permanently until we complete the MCU. } + +type + savable_state = record + put_buffer : INT32; { current bit-accumulation buffer } + put_bits : int; { # of bits now in it } + last_dc_val : array[0..MAX_COMPS_IN_SCAN-1] of int; + { last DC coef for each component } + end; + + +type + huff_entropy_ptr = ^huff_entropy_encoder; + huff_entropy_encoder = record + pub : jpeg_entropy_encoder; { public fields } + + saved : savable_state; { Bit buffer & DC state at start of MCU } + + { These fields are NOT loaded into local working state. } + restarts_to_go : uInt; { MCUs left in this restart interval } + next_restart_num : int; { next restart number to write (0-7) } + + { Pointers to derived tables (these workspaces have image lifespan) } + dc_derived_tbls : array[0..NUM_HUFF_TBLS-1] of c_derived_tbl_ptr; + ac_derived_tbls : array[0..NUM_HUFF_TBLS-1] of c_derived_tbl_ptr; + + {$ifdef ENTROPY_OPT_SUPPORTED} { Statistics tables for optimization } + dc_count_ptrs : array[0..NUM_HUFF_TBLS-1] of TLongTablePtr; + ac_count_ptrs : array[0..NUM_HUFF_TBLS-1] of TLongTablePtr; + {$endif} + end; + + + +{ Working state while writing an MCU. + This struct contains all the fields that are needed by subroutines. } + +type + working_state = record + next_output_byte : JOCTETptr; { => next byte to write in buffer } + free_in_buffer : size_t; { # of byte spaces remaining in buffer } + cur : savable_state; { Current bit buffer & DC state } + cinfo : j_compress_ptr; { dump_buffer needs access to this } + end; + + +{ Forward declarations } +{METHODDEF} +function encode_mcu_huff (cinfo : j_compress_ptr; + const MCU_data : array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +procedure finish_pass_huff (cinfo : j_compress_ptr); forward; +{$ifdef ENTROPY_OPT_SUPPORTED} +{METHODDEF} +function encode_mcu_gather (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + forward; + +{METHODDEF} +procedure finish_pass_gather (cinfo : j_compress_ptr); forward; +{$endif} + + +{ Initialize for a Huffman-compressed scan. + If gather_statistics is TRUE, we do not output anything during the scan, + just count the Huffman symbols used and generate Huffman code tables. } + +{METHODDEF} +procedure start_pass_huff (cinfo : j_compress_ptr; + gather_statistics : boolean); +var + entropy : huff_entropy_ptr; + ci, dctbl, actbl : int; + compptr : jpeg_component_info_ptr; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + if (gather_statistics) then + begin +{$ifdef ENTROPY_OPT_SUPPORTED} + entropy^.pub.encode_mcu := encode_mcu_gather; + entropy^.pub.finish_pass := finish_pass_gather; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + entropy^.pub.encode_mcu := encode_mcu_huff; + entropy^.pub.finish_pass := finish_pass_huff; + end; + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + dctbl := compptr^.dc_tbl_no; + actbl := compptr^.ac_tbl_no; + if (gather_statistics) then + begin +{$ifdef ENTROPY_OPT_SUPPORTED} + { Check for invalid table indexes } + { (make_c_derived_tbl does this in the other path) } + if (dctbl < 0) or (dctbl >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, dctbl); + if (actbl < 0) or (actbl >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, actbl); + { Allocate and zero the statistics tables } + { Note that jpeg_gen_optimal_table expects 257 entries in each table! } + if (entropy^.dc_count_ptrs[dctbl] = NIL) then + entropy^.dc_count_ptrs[dctbl] := TLongTablePtr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + 257 * SIZEOF(long)) ); + MEMZERO(entropy^.dc_count_ptrs[dctbl], 257 * SIZEOF(long)); + if (entropy^.ac_count_ptrs[actbl] = NIL) then + entropy^.ac_count_ptrs[actbl] := TLongTablePtr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + 257 * SIZEOF(long)) ); + MEMZERO(entropy^.ac_count_ptrs[actbl], 257 * SIZEOF(long)); +{$endif} + end + else + begin + { Compute derived values for Huffman tables } + { We may do this more than once for a table, but it's not expensive } + jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl, + entropy^.dc_derived_tbls[dctbl]); + jpeg_make_c_derived_tbl(cinfo, FALSE, actbl, + entropy^.ac_derived_tbls[actbl]); + end; + { Initialize DC predictions to 0 } + entropy^.saved.last_dc_val[ci] := 0; + end; + + { Initialize bit buffer to empty } + entropy^.saved.put_buffer := 0; + entropy^.saved.put_bits := 0; + + { Initialize restart stuff } + entropy^.restarts_to_go := cinfo^.restart_interval; + entropy^.next_restart_num := 0; +end; + + +{ Compute the derived values for a Huffman table. + This routine also performs some validation checks on the table. + + Note this is also used by jcphuff.c. } + +{GLOBAL} +procedure jpeg_make_c_derived_tbl (cinfo : j_compress_ptr; + isDC : boolean; + tblno : int; + var pdtbl : c_derived_tbl_ptr); +var + htbl : JHUFF_TBL_PTR; + dtbl : c_derived_tbl_ptr; + p, i, l, lastp, si, maxsymbol : int; + huffsize : array[0..257-1] of byte; + huffcode : array[0..257-1] of uInt; + code : uInt; +begin + { Note that huffsize[] and huffcode[] are filled in code-length order, + paralleling the order of the symbols themselves in htbl->huffval[]. } + + { Find the input Huffman table } + if (tblno < 0) or (tblno >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, tblno); + if isDC then + htbl := cinfo^.dc_huff_tbl_ptrs[tblno] + else + htbl := cinfo^.ac_huff_tbl_ptrs[tblno]; + if (htbl = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, tblno); + + { Allocate a workspace if we haven't already done so. } + if (pdtbl = NIL) then + pdtbl := c_derived_tbl_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(c_derived_tbl)) ); + dtbl := pdtbl; + + { Figure C.1: make table of Huffman code length for each symbol } + + p := 0; + for l := 1 to 16 do + begin + i := int(htbl^.bits[l]); + if (i < 0) and (p + i > 256) then { protect against table overrun } + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + while (i > 0) do + begin + huffsize[p] := byte(l); + Inc(p); + Dec(i); + end; + end; + huffsize[p] := 0; + lastp := p; + + { Figure C.2: generate the codes themselves } + { We also validate that the counts represent a legal Huffman code tree. } + + code := 0; + si := huffsize[0]; + p := 0; + while (huffsize[p] <> 0) do + begin + while (( int(huffsize[p]) ) = si) do + begin + huffcode[p] := code; + Inc(p); + Inc(code); + end; + { code is now 1 more than the last code used for codelength si; but + it must still fit in si bits, since no code is allowed to be all ones. } + + if (INT32(code) >= (INT32(1) shl si)) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + code := code shl 1; + Inc(si); + end; + + { Figure C.3: generate encoding tables } + { These are code and size indexed by symbol value } + + { Set all codeless symbols to have code length 0; + this lets us detect duplicate VAL entries here, and later + allows emit_bits to detect any attempt to emit such symbols. } + + MEMZERO(@dtbl^.ehufsi, SIZEOF(dtbl^.ehufsi)); + + { This is also a convenient place to check for out-of-range + and duplicated VAL entries. We allow 0..255 for AC symbols + but only 0..15 for DC. (We could constrain them further + based on data depth and mode, but this seems enough.) } + + if isDC then + maxsymbol := 15 + else + maxsymbol := 255; + + for p := 0 to pred(lastp) do + begin + i := htbl^.huffval[p]; + if (i < 0) or (i > maxsymbol) or (dtbl^.ehufsi[i] <> 0) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + dtbl^.ehufco[i] := huffcode[p]; + dtbl^.ehufsi[i] := huffsize[p]; + end; +end; + + +{ Outputting bytes to the file } + + +{LOCAL} +function dump_buffer (var state : working_state) : boolean; +{ Empty the output buffer; return TRUE if successful, FALSE if must suspend } +var + dest : jpeg_destination_mgr_ptr; +begin + dest := state.cinfo^.dest; + + if (not dest^.empty_output_buffer (state.cinfo)) then + begin + dump_buffer := FALSE; + exit; + end; + { After a successful buffer dump, must reset buffer pointers } + state.next_output_byte := dest^.next_output_byte; + state.free_in_buffer := dest^.free_in_buffer; + dump_buffer := TRUE; +end; + + +{ Outputting bits to the file } + +{ Only the right 24 bits of put_buffer are used; the valid bits are + left-justified in this part. At most 16 bits can be passed to emit_bits + in one call, and we never retain more than 7 bits in put_buffer + between calls, so 24 bits are sufficient. } + + +{LOCAL} +function emit_bits (var state : working_state; + code : uInt; + size : int) : boolean; {INLINE} +{ Emit some bits; return TRUE if successful, FALSE if must suspend } +var + { This routine is heavily used, so it's worth coding tightly. } + {register} put_buffer : INT32; + {register} put_bits : int; +var + c : int; +begin + put_buffer := INT32 (code); + put_bits := state.cur.put_bits; + + { if size is 0, caller used an invalid Huffman table entry } + if (size = 0) then + ERREXIT(j_common_ptr(state.cinfo), JERR_HUFF_MISSING_CODE); + + put_buffer := put_buffer and pred(INT32(1) shl size); + { mask off any extra bits in code } + + Inc(put_bits, size); { new number of bits in buffer } + + put_buffer := put_buffer shl (24 - put_bits); + { align incoming bits } + put_buffer := put_buffer or state.cur.put_buffer; + { and merge with old buffer contents } + while (put_bits >= 8) do + begin + c := int ((put_buffer shr 16) and $FF); + + {emit_byte(state, c, return FALSE);} + { Emit a byte, return FALSE if must suspend. } + state.next_output_byte^ := JOCTET (c); + Inc(state.next_output_byte); + Dec(state.free_in_buffer); + if (state.free_in_buffer = 0) then + if not dump_buffer(state) then + begin + emit_bits := FALSE; + exit; + end; + + if (c = $FF) then { need to stuff a zero byte? } + begin + {emit_byte(state, 0, return FALSE);} + state.next_output_byte^ := JOCTET (0); + Inc(state.next_output_byte); + Dec(state.free_in_buffer); + if (state.free_in_buffer = 0) then + if not dump_buffer(state) then + begin + emit_bits := FALSE; + exit; + end; + + end; + put_buffer := put_buffer shl 8; + Dec(put_bits, 8); + end; + + state.cur.put_buffer := put_buffer; { update state variables } + state.cur.put_bits := put_bits; + + emit_bits := TRUE; +end; + + +{LOCAL} +function flush_bits (var state : working_state) : boolean; +begin + if (not emit_bits(state, $7F, 7)) then { fill any partial byte with ones } + begin + flush_bits := FALSE; + exit; + end; + state.cur.put_buffer := 0; { and reset bit-buffer to empty } + state.cur.put_bits := 0; + flush_bits := TRUE; +end; + + +{ Encode a single block's worth of coefficients } + +{LOCAL} +function encode_one_block (var state : working_state; + const block : JBLOCK; + last_dc_val : int; + dctbl : c_derived_tbl_ptr; + actbl : c_derived_tbl_ptr) : boolean; +var + {register} temp, temp2 : int; + {register} nbits : int; + {register} k, r, i : int; +begin + { Encode the DC coefficient difference per section F.1.2.1 } + + temp2 := block[0] - last_dc_val; + temp := temp2; + + if (temp < 0) then + begin + temp := -temp; { temp is abs value of input } + { For a negative input, want temp2 := bitwise complement of abs(input) } + { This code assumes we are on a two's complement machine } + Dec(temp2); + end; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; + while (temp <> 0) do + begin + Inc(nbits); + temp := temp shr 1; + end; + + { Check for out-of-range coefficient values. + Since we're encoding a difference, the range limit is twice as much. } + + if (nbits > MAX_COEF_BITS+1) then + ERREXIT(j_common_ptr(state.cinfo), JERR_BAD_DCT_COEF); + + { Emit the Huffman-coded symbol for the number of bits } + if not emit_bits(state, dctbl^.ehufco[nbits], dctbl^.ehufsi[nbits]) then + begin + encode_one_block := FALSE; + exit; + end; + + { Emit that number of bits of the value, if positive, } + { or the complement of its magnitude, if negative. } + if (nbits <> 0) then { emit_bits rejects calls with size 0 } + if not emit_bits(state, uInt(temp2), nbits) then + begin + encode_one_block := FALSE; + exit; + end; + + { Encode the AC coefficients per section F.1.2.2 } + + r := 0; { r := run length of zeros } + + for k := 1 to pred(DCTSIZE2) do + begin + temp := block[jpeg_natural_order[k]]; + if (temp = 0) then + begin + Inc(r); + end + else + begin + { if run length > 15, must emit special run-length-16 codes ($F0) } + while (r > 15) do + begin + if not emit_bits(state, actbl^.ehufco[$F0], actbl^.ehufsi[$F0]) then + begin + encode_one_block := FALSE; + exit; + end; + Dec(r, 16); + end; + + temp2 := temp; + if (temp < 0) then + begin + temp := -temp; { temp is abs value of input } + { This code assumes we are on a two's complement machine } + Dec(temp2); + end; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; { there must be at least one 1 bit } + repeat + Inc(nbits); + temp := temp shr 1; + until (temp = 0); + + { Check for out-of-range coefficient values } + if (nbits > MAX_COEF_BITS) then + ERREXIT(j_common_ptr(state.cinfo), JERR_BAD_DCT_COEF); + + { Emit Huffman symbol for run length / number of bits } + i := (r shl 4) + nbits; + if not emit_bits(state, actbl^.ehufco[i], actbl^.ehufsi[i]) then + begin + encode_one_block := FALSE; + exit; + end; + + { Emit that number of bits of the value, if positive, } + { or the complement of its magnitude, if negative. } + if not emit_bits(state, uInt(temp2), nbits) then + begin + encode_one_block := FALSE; + exit; + end; + + r := 0; + end; + end; + + { If the last coef(s) were zero, emit an end-of-block code } + if (r > 0) then + if not emit_bits(state, actbl^.ehufco[0], actbl^.ehufsi[0]) then + begin + encode_one_block := FALSE; + exit; + end; + + encode_one_block := TRUE; +end; + + +{ Emit a restart marker & resynchronize predictions. } + +{LOCAL} +function emit_restart (var state : working_state; + restart_num : int) : boolean; +var + ci : int; +begin + if (not flush_bits(state)) then + begin + emit_restart := FALSE; + exit; + end; + + {emit_byte(state, $FF, return FALSE);} + { Emit a byte, return FALSE if must suspend. } + state.next_output_byte^ := JOCTET ($FF); + Inc(state.next_output_byte); + Dec(state.free_in_buffer); + if (state.free_in_buffer = 0) then + if not dump_buffer(state) then + begin + emit_restart := FALSE; + exit; + end; + + {emit_byte(state, JPEG_RST0 + restart_num, return FALSE);} + { Emit a byte, return FALSE if must suspend. } + state.next_output_byte^ := JOCTET (JPEG_RST0 + restart_num); + Inc(state.next_output_byte); + Dec(state.free_in_buffer); + if (state.free_in_buffer = 0) then + if not dump_buffer(state) then + begin + emit_restart := FALSE; + exit; + end; + + { Re-initialize DC predictions to 0 } + for ci := 0 to pred(state.cinfo^.comps_in_scan) do + state.cur.last_dc_val[ci] := 0; + + { The restart counter is not updated until we successfully write the MCU. } + + emit_restart := TRUE; +end; + + +{ Encode and output one MCU's worth of Huffman-compressed coefficients. } + +{METHODDEF} +function encode_mcu_huff (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; +var + entropy : huff_entropy_ptr; + state : working_state; + blkn, ci : int; + compptr : jpeg_component_info_ptr; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + { Load up working state } + state.next_output_byte := cinfo^.dest^.next_output_byte; + state.free_in_buffer := cinfo^.dest^.free_in_buffer; + {ASSIGN_STATE(state.cur, entropy^.saved);} + state.cur := entropy^.saved; + state.cinfo := cinfo; + + { Emit restart marker if needed } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if not emit_restart(state, entropy^.next_restart_num) then + begin + encode_mcu_huff := FALSE; + exit; + end; + end; + + { Encode the MCU data blocks } + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + ci := cinfo^.MCU_membership[blkn]; + compptr := cinfo^.cur_comp_info[ci]; + if not encode_one_block(state, + MCU_data[blkn]^[0], + state.cur.last_dc_val[ci], + entropy^.dc_derived_tbls[compptr^.dc_tbl_no], + entropy^.ac_derived_tbls[compptr^.ac_tbl_no]) then + begin + encode_mcu_huff := FALSE; + exit; + end; + { Update last_dc_val } + state.cur.last_dc_val[ci] := MCU_data[blkn]^[0][0]; + end; + + { Completed MCU, so update state } + cinfo^.dest^.next_output_byte := state.next_output_byte; + cinfo^.dest^.free_in_buffer := state.free_in_buffer; + {ASSIGN_STATE(entropy^.saved, state.cur);} + entropy^.saved := state.cur; + + { Update restart-interval state too } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + entropy^.restarts_to_go := cinfo^.restart_interval; + Inc(entropy^.next_restart_num); + with entropy^ do + next_restart_num := next_restart_num and 7; + end; + Dec(entropy^.restarts_to_go); + end; + + encode_mcu_huff := TRUE; +end; + + +{ Finish up at the end of a Huffman-compressed scan. } + +{METHODDEF} +procedure finish_pass_huff (cinfo : j_compress_ptr); +var + entropy : huff_entropy_ptr; + state : working_state; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + { Load up working state ... flush_bits needs it } + state.next_output_byte := cinfo^.dest^.next_output_byte; + state.free_in_buffer := cinfo^.dest^.free_in_buffer; + {ASSIGN_STATE(state.cur, entropy^.saved);} + state.cur := entropy^.saved; + state.cinfo := cinfo; + + { Flush out the last data } + if not flush_bits(state) then + ERREXIT(j_common_ptr(cinfo), JERR_CANT_SUSPEND); + + { Update state } + cinfo^.dest^.next_output_byte := state.next_output_byte; + cinfo^.dest^.free_in_buffer := state.free_in_buffer; + {ASSIGN_STATE(entropy^.saved, state.cur);} + entropy^.saved := state.cur; +end; + + +{ Huffman coding optimization. + + We first scan the supplied data and count the number of uses of each symbol + that is to be Huffman-coded. (This process MUST agree with the code above.) + Then we build a Huffman coding tree for the observed counts. + Symbols which are not needed at all for the particular image are not + assigned any code, which saves space in the DHT marker as well as in + the compressed data. } + +{$ifdef ENTROPY_OPT_SUPPORTED} + + +{ Process a single block's worth of coefficients } + +{LOCAL} +procedure htest_one_block (cinfo : j_compress_ptr; + const block : JBLOCK; + last_dc_val : int; + dc_counts : TLongTablePtr; + ac_counts : TLongTablePtr); + +var + {register} temp : int; + {register} nbits : int; + {register} k, r : int; +begin + { Encode the DC coefficient difference per section F.1.2.1 } + temp := block[0] - last_dc_val; + if (temp < 0) then + temp := -temp; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; + while (temp <> 0) do + begin + Inc(nbits); + temp := temp shr 1; + end; + + { Check for out-of-range coefficient values. + Since we're encoding a difference, the range limit is twice as much. } + + if (nbits > MAX_COEF_BITS+1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_DCT_COEF); + + { Count the Huffman symbol for the number of bits } + Inc(dc_counts^[nbits]); + + { Encode the AC coefficients per section F.1.2.2 } + + r := 0; { r := run length of zeros } + + for k := 1 to pred(DCTSIZE2) do + begin + temp := block[jpeg_natural_order[k]]; + if (temp = 0) then + begin + Inc(r); + end + else + begin + { if run length > 15, must emit special run-length-16 codes ($F0) } + while (r > 15) do + begin + Inc(ac_counts^[$F0]); + Dec(r, 16); + end; + + { Find the number of bits needed for the magnitude of the coefficient } + if (temp < 0) then + temp := -temp; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; { there must be at least one 1 bit } + repeat + Inc(nbits); + temp := temp shr 1; + until (temp = 0); + + + { Count Huffman symbol for run length / number of bits } + Inc(ac_counts^[(r shl 4) + nbits]); + + r := 0; + end; + end; + + { If the last coef(s) were zero, emit an end-of-block code } + if (r > 0) then + Inc(ac_counts^[0]); +end; + + +{ Trial-encode one MCU's worth of Huffman-compressed coefficients. + No data is actually output, so no suspension return is possible. } + +{METHODDEF} +function encode_mcu_gather (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; +var + entropy : huff_entropy_ptr; + blkn, ci : int; + compptr : jpeg_component_info_ptr; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + { Take care of restart intervals if needed } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + { Re-initialize DC predictions to 0 } + for ci := 0 to pred(cinfo^.comps_in_scan) do + entropy^.saved.last_dc_val[ci] := 0; + { Update restart state } + entropy^.restarts_to_go := cinfo^.restart_interval; + end; + Dec(entropy^.restarts_to_go); + end; + + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + ci := cinfo^.MCU_membership[blkn]; + compptr := cinfo^.cur_comp_info[ci]; + htest_one_block(cinfo, MCU_data[blkn]^[0], + entropy^.saved.last_dc_val[ci], + entropy^.dc_count_ptrs[compptr^.dc_tbl_no], + entropy^.ac_count_ptrs[compptr^.ac_tbl_no]); + entropy^.saved.last_dc_val[ci] := MCU_data[blkn]^[0][0]; + end; + + encode_mcu_gather := TRUE; +end; + + +{ Generate the best Huffman code table for the given counts, fill htbl. + Note this is also used by jcphuff.c. + + The JPEG standard requires that no symbol be assigned a codeword of all + one bits (so that padding bits added at the end of a compressed segment + can't look like a valid code). Because of the canonical ordering of + codewords, this just means that there must be an unused slot in the + longest codeword length category. Section K.2 of the JPEG spec suggests + reserving such a slot by pretending that symbol 256 is a valid symbol + with count 1. In theory that's not optimal; giving it count zero but + including it in the symbol set anyway should give a better Huffman code. + But the theoretically better code actually seems to come out worse in + practice, because it produces more all-ones bytes (which incur stuffed + zero bytes in the final file). In any case the difference is tiny. + + The JPEG standard requires Huffman codes to be no more than 16 bits long. + If some symbols have a very small but nonzero probability, the Huffman tree + must be adjusted to meet the code length restriction. We currently use + the adjustment method suggested in JPEG section K.2. This method is *not* + optimal; it may not choose the best possible limited-length code. But + typically only very-low-frequency symbols will be given less-than-optimal + lengths, so the code is almost optimal. Experimental comparisons against + an optimal limited-length-code algorithm indicate that the difference is + microscopic --- usually less than a hundredth of a percent of total size. + So the extra complexity of an optimal algorithm doesn't seem worthwhile. } + + +{GLOBAL} +procedure jpeg_gen_optimal_table (cinfo : j_compress_ptr; + htbl : JHUFF_TBL_PTR; + var freq : TLongTable); +const + MAX_CLEN = 32; { assumed maximum initial code length } +var + bits : array[0..MAX_CLEN+1-1] of UINT8; { bits[k] := # of symbols with code length k } + codesize : array[0..257-1] of int; { codesize[k] := code length of symbol k } + others : array[0..257-1] of int; { next symbol in current branch of tree } + c1, c2 : int; + p, i, j : int; + v : long; +begin + { This algorithm is explained in section K.2 of the JPEG standard } + + MEMZERO(@bits, SIZEOF(bits)); + MEMZERO(@codesize, SIZEOF(codesize)); + for i := 0 to 256 do + others[i] := -1; { init links to empty } + + freq[256] := 1; { make sure 256 has a nonzero count } + { Including the pseudo-symbol 256 in the Huffman procedure guarantees + that no real symbol is given code-value of all ones, because 256 + will be placed last in the largest codeword category. } + + { Huffman's basic algorithm to assign optimal code lengths to symbols } + + while TRUE do + begin + { Find the smallest nonzero frequency, set c1 := its symbol } + { In case of ties, take the larger symbol number } + c1 := -1; + v := long(1000000000); + for i := 0 to 256 do + begin + if (freq[i] <> 0) and (freq[i] <= v) then + begin + v := freq[i]; + c1 := i; + end; + end; + + { Find the next smallest nonzero frequency, set c2 := its symbol } + { In case of ties, take the larger symbol number } + c2 := -1; + v := long(1000000000); + for i := 0 to 256 do + begin + if (freq[i] <> 0) and (freq[i] <= v) and (i <> c1) then + begin + v := freq[i]; + c2 := i; + end; + end; + + { Done if we've merged everything into one frequency } + if (c2 < 0) then + break; + + { Else merge the two counts/trees } + Inc(freq[c1], freq[c2]); + freq[c2] := 0; + + { Increment the codesize of everything in c1's tree branch } + Inc(codesize[c1]); + while (others[c1] >= 0) do + begin + c1 := others[c1]; + Inc(codesize[c1]); + end; + + others[c1] := c2; { chain c2 onto c1's tree branch } + + { Increment the codesize of everything in c2's tree branch } + Inc(codesize[c2]); + while (others[c2] >= 0) do + begin + c2 := others[c2]; + Inc(codesize[c2]); + end; + end; + + { Now count the number of symbols of each code length } + for i := 0 to 256 do + begin + if (codesize[i]<>0) then + begin + { The JPEG standard seems to think that this can't happen, } + { but I'm paranoid... } + if (codesize[i] > MAX_CLEN) then + ERREXIT(j_common_ptr(cinfo), JERR_HUFF_CLEN_OVERFLOW); + + Inc(bits[codesize[i]]); + end; + end; + + { JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure + Huffman procedure assigned any such lengths, we must adjust the coding. + Here is what the JPEG spec says about how this next bit works: + Since symbols are paired for the longest Huffman code, the symbols are + removed from this length category two at a time. The prefix for the pair + (which is one bit shorter) is allocated to one of the pair; then, + skipping the BITS entry for that prefix length, a code word from the next + shortest nonzero BITS entry is converted into a prefix for two code words + one bit longer. } + + for i := MAX_CLEN downto 17 do + begin + while (bits[i] > 0) do + begin + j := i - 2; { find length of new prefix to be used } + while (bits[j] = 0) do + Dec(j); + + Dec(bits[i], 2); { remove two symbols } + Inc(bits[i-1]); { one goes in this length } + Inc(bits[j+1], 2); { two new symbols in this length } + Dec(bits[j]); { symbol of this length is now a prefix } + end; + end; + + { Delphi 2: FOR-loop variable 'i' may be undefined after loop } + i := 16; { Nomssi: work around } + + { Remove the count for the pseudo-symbol 256 from the largest codelength } + while (bits[i] = 0) do { find largest codelength still in use } + Dec(i); + Dec(bits[i]); + + { Return final symbol counts (only for lengths 0..16) } + MEMCOPY(@htbl^.bits, @bits, SIZEOF(htbl^.bits)); + + { Return a list of the symbols sorted by code length } + { It's not real clear to me why we don't need to consider the codelength + changes made above, but the JPEG spec seems to think this works. } + + p := 0; + for i := 1 to MAX_CLEN do + begin + for j := 0 to 255 do + begin + if (codesize[j] = i) then + begin + htbl^.huffval[p] := UINT8 (j); + Inc(p); + end; + end; + end; + + { Set sent_table FALSE so updated table will be written to JPEG file. } + htbl^.sent_table := FALSE; +end; + + +{ Finish up a statistics-gathering pass and create the new Huffman tables. } + +{METHODDEF} +procedure finish_pass_gather (cinfo : j_compress_ptr); +var + entropy : huff_entropy_ptr; + ci, dctbl, actbl : int; + compptr : jpeg_component_info_ptr; + htblptr : ^JHUFF_TBL_PTR; + did_dc : array[0..NUM_HUFF_TBLS-1] of boolean; + did_ac : array[0..NUM_HUFF_TBLS-1] of boolean; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + { It's important not to apply jpeg_gen_optimal_table more than once + per table, because it clobbers the input frequency counts! } + + MEMZERO(@did_dc, SIZEOF(did_dc)); + MEMZERO(@did_ac, SIZEOF(did_ac)); + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + dctbl := compptr^.dc_tbl_no; + actbl := compptr^.ac_tbl_no; + if (not did_dc[dctbl]) then + begin + htblptr := @(cinfo^.dc_huff_tbl_ptrs[dctbl]); + if ( htblptr^ = NIL) then + htblptr^ := jpeg_alloc_huff_table(j_common_ptr(cinfo)); + jpeg_gen_optimal_table(cinfo, htblptr^, entropy^.dc_count_ptrs[dctbl]^); + did_dc[dctbl] := TRUE; + end; + if (not did_ac[actbl]) then + begin + htblptr := @(cinfo^.ac_huff_tbl_ptrs[actbl]); + if ( htblptr^ = NIL) then + htblptr^ := jpeg_alloc_huff_table(j_common_ptr(cinfo)); + jpeg_gen_optimal_table(cinfo, htblptr^, entropy^.ac_count_ptrs[actbl]^); + did_ac[actbl] := TRUE; + end; + end; +end; + +{$endif} { ENTROPY_OPT_SUPPORTED } + + +{ Module initialization routine for Huffman entropy encoding. } + +{GLOBAL} +procedure jinit_huff_encoder (cinfo : j_compress_ptr); +var + entropy : huff_entropy_ptr; + i : int; +begin + entropy := huff_entropy_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(huff_entropy_encoder)) ); + cinfo^.entropy := jpeg_entropy_encoder_ptr (entropy); + entropy^.pub.start_pass := start_pass_huff; + + { Mark tables unallocated } + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + entropy^.ac_derived_tbls[i] := NIL; + entropy^.dc_derived_tbls[i] := NIL; +{$ifdef ENTROPY_OPT_SUPPORTED} + entropy^.ac_count_ptrs[i] := NIL; + entropy^.dc_count_ptrs[i] := NIL; +{$endif} + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcinit_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcinit_del.pas new file mode 100644 index 0000000..a3f2673 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcinit_del.pas @@ -0,0 +1,97 @@ +Unit jcinit_del; + +{ Original: jcinit.c ; Copyright (C) 1991-1997, Thomas G. Lane. } + +{ This file contains initialization logic for the JPEG compressor. + This routine is in charge of selecting the modules to be executed and + making an initialization call to each one. + + Logically, this code belongs in jcmaster.c. It's split out because + linking this routine implies linking the entire compression library. + For a transcoding-only application, we want to be able to use jcmaster.c + without linking in the whole library. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, +{$ifdef C_PROGRESSIVE_SUPPORTED} + jcphuff_del, +{$endif} + JcHuff_del, JcMaster_del, JcColor_del, JcSample_del, JcPrepCt_del, + JcDCTMgr_del, JcCoefCT_del, JcMainCT_del, JcMarker_del; + +{ Master selection of compression modules. + This is done once at the start of processing an image. We determine + which modules will be used and give them appropriate initialization calls. } + +{GLOBAL} +procedure jinit_compress_master (cinfo : j_compress_ptr); + +implementation + + + +{ Master selection of compression modules. + This is done once at the start of processing an image. We determine + which modules will be used and give them appropriate initialization calls. } + +{GLOBAL} +procedure jinit_compress_master (cinfo : j_compress_ptr); +begin + { Initialize master control (includes parameter checking/processing) } + jinit_c_master_control(cinfo, FALSE { full compression }); + + { Preprocessing } + if (not cinfo^.raw_data_in) then + begin + jinit_color_converter(cinfo); + jinit_downsampler(cinfo); + jinit_c_prep_controller(cinfo, FALSE { never need full buffer here }); + end; + { Forward DCT } + jinit_forward_dct(cinfo); + { Entropy encoding: either Huffman or arithmetic coding. } + if (cinfo^.arith_code) then + begin + ERREXIT(j_common_ptr(cinfo), JERR_ARITH_NOTIMPL); + end + else + begin + if (cinfo^.progressive_mode) then + begin +{$ifdef C_PROGRESSIVE_SUPPORTED} + jinit_phuff_encoder(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + jinit_huff_encoder(cinfo); + end; + + { Need a full-image coefficient buffer in any multi-pass mode. } + jinit_c_coef_controller(cinfo, + (cinfo^.num_scans > 1) or (cinfo^.optimize_coding)); + jinit_c_main_controller(cinfo, FALSE { never need full buffer here }); + + jinit_marker_writer(cinfo); + + { We can now tell the memory manager to allocate virtual arrays. } + cinfo^.mem^.realize_virt_arrays (j_common_ptr(cinfo)); + + { Write the datastream header (SOI) immediately. + Frame and scan headers are postponed till later. + This lets application insert special markers after the SOI. } + + cinfo^.marker^.write_file_header (cinfo); +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcmainct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcmainct_del.pas new file mode 100644 index 0000000..405156d --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcmainct_del.pas @@ -0,0 +1,345 @@ +Unit jcmainct_del; + +{ This file contains the main buffer controller for compression. + The main buffer lies between the pre-processor and the JPEG + compressor proper; it holds downsampled data in the JPEG colorspace. } + +{ Original : jcmainct.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ Note: currently, there is no operating mode in which a full-image buffer + is needed at this step. If there were, that mode could not be used with + "raw data" input, since this module is bypassed in that case. However, + we've left the code here for possible use in special applications. } + +{$undef FULL_MAIN_BUFFER_SUPPORTED} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + jutils_del, +{$endif} + jpeglib_del; + +{ Initialize main buffer controller. } + +{GLOBAL} +procedure jinit_c_main_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); + +implementation + + +{ Private buffer controller object } + +type + my_main_ptr = ^my_main_controller; + my_main_controller = record + pub : jpeg_c_main_controller; { public fields } + + cur_iMCU_row : JDIMENSION; { number of current iMCU row } + rowgroup_ctr : JDIMENSION; { counts row groups received in iMCU row } + suspended : boolean; { remember if we suspended output } + pass_mode : J_BUF_MODE; { current operating mode } + + { If using just a strip buffer, this points to the entire set of buffers + (we allocate one for each component). In the full-image case, this + points to the currently accessible strips of the virtual arrays. } + + buffer : array[0..MAX_COMPONENTS-1] of JSAMPARRAY; + + {$ifdef FULL_MAIN_BUFFER_SUPPORTED} + { If using full-image storage, this array holds pointers to virtual-array + control blocks for each component. Unused if not full-image storage. } + + whole_image : array[0..MAX_COMPONENTS-1] of jvirt_sarray_ptr; + {$endif} + end; {my_main_controller} + + +{ Forward declarations } +{METHODDEF} +procedure process_data_simple_main(cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr: JDIMENSION; + in_rows_avail : JDIMENSION); forward; + +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} +{METHODDEF} +procedure process_data_buffer_main(cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION); forward; +{$endif} + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_main (cinfo : j_compress_ptr; + pass_mode : J_BUF_MODE); +var + main : my_main_ptr; +begin + main := my_main_ptr (cinfo^.main); + + { Do nothing in raw-data mode. } + if (cinfo^.raw_data_in) then + exit; + + main^.cur_iMCU_row := 0; { initialize counters } + main^.rowgroup_ctr := 0; + main^.suspended := FALSE; + main^.pass_mode := pass_mode; { save mode for use by process_data } + + case (pass_mode) of + JBUF_PASS_THRU: + begin +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + if (main^.whole_image[0] <> NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); +{$endif} + main^.pub.process_data := process_data_simple_main; + end; +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + JBUF_SAVE_SOURCE, + JBUF_CRANK_DEST, + JBUF_SAVE_AND_PASS: + begin + if (main^.whole_image[0] = NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + main^.pub.process_data := process_data_buffer_main; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + end; +end; + + +{ Process some data. + This routine handles the simple pass-through mode, + where we have only a strip buffer. } + +{METHODDEF} +procedure process_data_simple_main (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION); +var + main : my_main_ptr; +begin + main := my_main_ptr (cinfo^.main); + + while (main^.cur_iMCU_row < cinfo^.total_iMCU_rows) do + begin + { Read input data if we haven't filled the main buffer yet } + if (main^.rowgroup_ctr < DCTSIZE) then + cinfo^.prep^.pre_process_data (cinfo, + input_buf, + in_row_ctr, + in_rows_avail, + JSAMPIMAGE(@main^.buffer), + main^.rowgroup_ctr, + JDIMENSION(DCTSIZE)); + + { If we don't have a full iMCU row buffered, return to application for + more data. Note that preprocessor will always pad to fill the iMCU row + at the bottom of the image. } + if (main^.rowgroup_ctr <> DCTSIZE) then + exit; + + { Send the completed row to the compressor } + if (not cinfo^.coef^.compress_data (cinfo, JSAMPIMAGE(@main^.buffer))) then + begin + { If compressor did not consume the whole row, then we must need to + suspend processing and return to the application. In this situation + we pretend we didn't yet consume the last input row; otherwise, if + it happened to be the last row of the image, the application would + think we were done. } + + if (not main^.suspended) then + begin + Dec(in_row_ctr); + main^.suspended := TRUE; + end; + exit; + end; + { We did finish the row. Undo our little suspension hack if a previous + call suspended; then mark the main buffer empty. } + + if (main^.suspended) then + begin + Inc(in_row_ctr); + main^.suspended := FALSE; + end; + main^.rowgroup_ctr := 0; + Inc(main^.cur_iMCU_row); + end; +end; + + +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + +{ Process some data. + This routine handles all of the modes that use a full-size buffer. } + +{METHODDEF} +procedure process_data_buffer_main (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION); +var + main : my_main_ptr; + ci : int; + compptr : jpeg_component_info_ptr; + writing : boolean; +begin + main := my_main_ptr (cinfo^.main); + writing := (main^.pass_mode <> JBUF_CRANK_DEST); + + while (main^.cur_iMCU_row < cinfo^.total_iMCU_rows) do + begin + { Realign the virtual buffers if at the start of an iMCU row. } + if (main^.rowgroup_ctr = 0) then + begin + compptr := cinfo^.comp_info; + for ci := 0 to pred(cinfo^.num_components) do + begin + main^.buffer[ci] := cinfo^.mem^.access_virt_sarray + (j_common_ptr (cinfo), main^.whole_image[ci], + main^.cur_iMCU_row * (compptr^.v_samp_factor * DCTSIZE), + JDIMENSION (compptr^.v_samp_factor * DCTSIZE), writing); + Inc(compptr); + end; + { In a read pass, pretend we just read some source data. } + if (not writing) then + begin + Inc(in_row_ctr, cinfo^.max_v_samp_factor * DCTSIZE); + main^.rowgroup_ctr := DCTSIZE; + end; + end; + + { If a write pass, read input data until the current iMCU row is full. } + { Note: preprocessor will pad if necessary to fill the last iMCU row. } + if (writing) then + begin + cinfo^.prep^.pre_process_data (cinfo, + input_buf, in_row_ctr, in_rows_avail, + JSAMPIMAGE(@main^.buffer), + main^.rowgroup_ctr, + JDIMENSION (DCTSIZE)); + + { Return to application if we need more data to fill the iMCU row. } + if (main^.rowgroup_ctr < DCTSIZE) then + exit; + end; + + { Emit data, unless this is a sink-only pass. } + if (main^.pass_mode <> JBUF_SAVE_SOURCE) then + begin + if (not cinfo^.coef^.compress_data (cinfo, + JSAMPIMAGE(@main^.buffer))) then + begin + { If compressor did not consume the whole row, then we must need to + suspend processing and return to the application. In this situation + we pretend we didn't yet consume the last input row; otherwise, if + it happened to be the last row of the image, the application would + think we were done. } + + if (not main^.suspended) then + begin + Dec(in_row_ctr); + main^.suspended := TRUE; + end; + exit; + end; + { We did finish the row. Undo our little suspension hack if a previous + call suspended; then mark the main buffer empty. } + + if (main^.suspended) then + begin + Inc(in_row_ctr); + main^.suspended := FALSE; + end; + end; + + { If get here, we are done with this iMCU row. Mark buffer empty. } + main^.rowgroup_ctr := 0; + Inc(main^.cur_iMCU_row); + end; +end; + +{$endif} { FULL_MAIN_BUFFER_SUPPORTED } + + +{ Initialize main buffer controller. } + +{GLOBAL} +procedure jinit_c_main_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); +var + main : my_main_ptr; + ci : int; + compptr : jpeg_component_info_ptr; +begin + main := my_main_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_main_controller)) ); + cinfo^.main := jpeg_c_main_controller_ptr(main); + main^.pub.start_pass := start_pass_main; + + { We don't need to create a buffer in raw-data mode. } + if (cinfo^.raw_data_in) then + exit; + + { Create the buffer. It holds downsampled data, so each component + may be of a different size. } + + if (need_full_buffer) then + begin +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + { Allocate a full-image virtual array for each component } + { Note we pad the bottom to a multiple of the iMCU height } + compptr := cinfo^.comp_info; + for ci := 0 to pred(cinfo^.num_components) do + begin + main^.whole_image[ci] := cinfo^.mem^.request_virt_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, FALSE, + compptr^.width_in_blocks * DCTSIZE, + JDIMENSION (jround_up( long (compptr^.height_in_blocks), + long (compptr^.v_samp_factor)) * DCTSIZE), + JDIMENSION (compptr^.v_samp_factor * DCTSIZE)); + Inc(compptr); + end; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); +{$endif} + end + else + begin +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + main^.whole_image[0] := NIL; { flag for no virtual arrays } +{$endif} + { Allocate a strip buffer for each component } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + main^.buffer[ci] := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + compptr^.width_in_blocks * DCTSIZE, + JDIMENSION (compptr^.v_samp_factor * DCTSIZE)); + Inc(compptr); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcmarker_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcmarker_del.pas new file mode 100644 index 0000000..ae80025 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcmarker_del.pas @@ -0,0 +1,726 @@ +Unit jcmarker_del; + +{ This file contains routines to write JPEG datastream markers. } + +{ Original: jcmarker.c; Copyright (C) 1991-1998, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jinclude_del, jmorecfg_del, jerror_del, + jdeferr_del, jpeglib_del, jutils_del; + + +const + { JPEG marker codes } + M_SOF0 = $c0; + M_SOF1 = $c1; + M_SOF2 = $c2; + M_SOF3 = $c3; + + M_SOF5 = $c5; + M_SOF6 = $c6; + M_SOF7 = $c7; + + M_JPG = $c8; + M_SOF9 = $c9; + M_SOF10 = $ca; + M_SOF11 = $cb; + + M_SOF13 = $cd; + M_SOF14 = $ce; + M_SOF15 = $cf; + + M_DHT = $c4; + + M_DAC = $cc; + + M_RST0 = $d0; + M_RST1 = $d1; + M_RST2 = $d2; + M_RST3 = $d3; + M_RST4 = $d4; + M_RST5 = $d5; + M_RST6 = $d6; + M_RST7 = $d7; + + M_SOI = $d8; + M_EOI = $d9; + M_SOS = $da; + M_DQT = $db; + M_DNL = $dc; + M_DRI = $dd; + M_DHP = $de; + M_EXP = $df; + + M_APP0 = $e0; + M_APP1 = $e1; + M_APP2 = $e2; + M_APP3 = $e3; + M_APP4 = $e4; + M_APP5 = $e5; + M_APP6 = $e6; + M_APP7 = $e7; + M_APP8 = $e8; + M_APP9 = $e9; + M_APP10 = $ea; + M_APP11 = $eb; + M_APP12 = $ec; + M_APP13 = $ed; + M_APP14 = $ee; + M_APP15 = $ef; + + M_JPG0 = $f0; + M_JPG13 = $fd; + M_COM = $fe; + + M_TEM = $01; + + M_ERROR = $100; + +type + JPEG_MARKER = Word; + +{ Private state } + +type + my_marker_ptr = ^my_marker_writer; + my_marker_writer = record + pub : jpeg_marker_writer; { public fields } + + last_restart_interval : uint; { last DRI value emitted; 0 after SOI } + end; + + + + +{GLOBAL} +procedure jinit_marker_writer (cinfo : j_compress_ptr); + +implementation + +{ Basic output routines. + + Note that we do not support suspension while writing a marker. + Therefore, an application using suspension must ensure that there is + enough buffer space for the initial markers (typ. 600-700 bytes) before + calling jpeg_start_compress, and enough space to write the trailing EOI + (a few bytes) before calling jpeg_finish_compress. Multipass compression + modes are not supported at all with suspension, so those two are the only + points where markers will be written. } + + +{LOCAL} +procedure emit_byte (cinfo : j_compress_ptr; val : int); +{ Emit a byte } +var + dest : jpeg_destination_mgr_ptr; +begin + dest := cinfo^.dest; + + dest^.next_output_byte^ := JOCTET(val); + Inc(dest^.next_output_byte); + + Dec(dest^.free_in_buffer); + if (dest^.free_in_buffer = 0) then + begin + if not dest^.empty_output_buffer(cinfo) then + ERREXIT(j_common_ptr(cinfo), JERR_CANT_SUSPEND); + end; +end; + + +{LOCAL} +procedure emit_marker(cinfo : j_compress_ptr; mark : JPEG_MARKER); +{ Emit a marker code } +begin + emit_byte(cinfo, $FF); + emit_byte(cinfo, int(mark)); +end; + + +{LOCAL} +procedure emit_2bytes (cinfo : j_compress_ptr; value : int); +{ Emit a 2-byte integer; these are always MSB first in JPEG files } +begin + emit_byte(cinfo, (value shr 8) and $FF); + emit_byte(cinfo, value and $FF); +end; + + +{ Routines to write specific marker types. } + +{LOCAL} +function emit_dqt (cinfo : j_compress_ptr; index : int) : int; +{ Emit a DQT marker } +{ Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking } +var + qtbl : JQUANT_TBL_PTR; + prec : int; + i : int; +var + qval : uint; +begin + qtbl := cinfo^.quant_tbl_ptrs[index]; + if (qtbl = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_QUANT_TABLE, index); + + prec := 0; + for i := 0 to Pred(DCTSIZE2) do + begin + if (qtbl^.quantval[i] > 255) then + prec := 1; + end; + + if not qtbl^.sent_table then + begin + emit_marker(cinfo, M_DQT); + + if (prec <> 0) then + emit_2bytes(cinfo, DCTSIZE2*2 + 1 + 2) + else + emit_2bytes(cinfo, DCTSIZE2 + 1 + 2); + + emit_byte(cinfo, index + (prec shl 4)); + + for i := 0 to Pred(DCTSIZE2) do + begin + { The table entries must be emitted in zigzag order. } + qval := qtbl^.quantval[jpeg_natural_order[i]]; + if (prec <> 0) then + emit_byte(cinfo, int(qval shr 8)); + emit_byte(cinfo, int(qval and $FF)); + end; + + qtbl^.sent_table := TRUE; + end; + + emit_dqt := prec; +end; + + +{LOCAL} +procedure emit_dht (cinfo : j_compress_ptr; index : int; is_ac : boolean); +{ Emit a DHT marker } +var + htbl : JHUFF_TBL_PTR; + length, i : int; +begin + if (is_ac) then + begin + htbl := cinfo^.ac_huff_tbl_ptrs[index]; + index := index + $10; { output index has AC bit set } + end + else + begin + htbl := cinfo^.dc_huff_tbl_ptrs[index]; + end; + + if (htbl = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, index); + + if not htbl^.sent_table then + begin + emit_marker(cinfo, M_DHT); + + length := 0; + for i := 1 to 16 do + length := length + htbl^.bits[i]; + + emit_2bytes(cinfo, length + 2 + 1 + 16); + emit_byte(cinfo, index); + + for i := 1 to 16 do + emit_byte(cinfo, htbl^.bits[i]); + + for i := 0 to Pred(length) do + emit_byte(cinfo, htbl^.huffval[i]); + + htbl^.sent_table := TRUE; + end; +end; + + +{LOCAL} +procedure emit_dac (cinfo : j_compress_ptr); +{ Emit a DAC marker } +{ Since the useful info is so small, we want to emit all the tables in } +{ one DAC marker. Therefore this routine does its own scan of the table. } +{$ifdef C_ARITH_CODING_SUPPORTED} +var + dc_in_use : array[0..NUM_ARITH_TBLS] of byte; + ac_in_use : array[0..NUM_ARITH_TBLS] of byte; + length, i : int; + compptr : jpeg_component_info_ptr; +begin + for i := 0 to pred(NUM_ARITH_TBLS) do + begin + dc_in_use[i] := 0; + ac_in_use[i] := 0; + end; + + for i := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[i]; + dc_in_use[compptr^.dc_tbl_no] := 1; + ac_in_use[compptr^.ac_tbl_no] := 1; + end; + + length := 0; + for i := 0 to pred(NUM_ARITH_TBLS) do + Inc(length, dc_in_use[i] + ac_in_use[i]); + + emit_marker(cinfo, M_DAC); + + emit_2bytes(cinfo, length*2 + 2); + + for i := 0 to pred(NUM_ARITH_TBLS) do + begin + if (dc_in_use[i] <> 0) then + begin + emit_byte(cinfo, i); + emit_byte(cinfo, cinfo^.arith_dc_L[i] + (cinfo^.arith_dc_U[i] shl 4)); + end; + if (ac_in_use[i] <> 0) then + begin + emit_byte(cinfo, i + $10); + emit_byte(cinfo, cinfo^.arith_ac_K[i]); + end; + end; +end; +{$else} +begin +end; +{$endif} {C_ARITH_CODING_SUPPORTED} + + +{LOCAL} +procedure emit_dri (cinfo : j_compress_ptr); +{ Emit a DRI marker } +begin + emit_marker(cinfo, M_DRI); + + emit_2bytes(cinfo, 4); { fixed length } + + emit_2bytes(cinfo, int(cinfo^.restart_interval)); +end; + + +{LOCAL} +procedure emit_sof (cinfo : j_compress_ptr; code : JPEG_MARKER); +{ Emit a SOF marker } +var + ci : int; + compptr : jpeg_component_info_ptr; +begin + emit_marker(cinfo, code); + + emit_2bytes(cinfo, 3 * cinfo^.num_components + 2 + 5 + 1); { length } + + { Make sure image isn't bigger than SOF field can handle } + if (long(cinfo^.image_height) > long(65535)) or + (long(cinfo^.image_width) > long(65535)) then + ERREXIT1(j_common_ptr(cinfo), JERR_IMAGE_TOO_BIG, uInt(65535)); + + emit_byte(cinfo, cinfo^.data_precision); + emit_2bytes(cinfo, int(cinfo^.image_height)); + emit_2bytes(cinfo, int(cinfo^.image_width)); + + emit_byte(cinfo, cinfo^.num_components); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to Pred(cinfo^.num_components) do + begin + emit_byte(cinfo, compptr^.component_id); + emit_byte(cinfo, (compptr^.h_samp_factor shl 4) + compptr^.v_samp_factor); + emit_byte(cinfo, compptr^.quant_tbl_no); + Inc(compptr); + end; +end; + + +{LOCAL} +procedure emit_sos (cinfo : j_compress_ptr); +{ Emit a SOS marker } +var + i, td, ta : int; + compptr : jpeg_component_info_ptr; +begin + emit_marker(cinfo, M_SOS); + + emit_2bytes(cinfo, 2 * cinfo^.comps_in_scan + 2 + 1 + 3); { length } + + emit_byte(cinfo, cinfo^.comps_in_scan); + + for i := 0 to Pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[i]; + emit_byte(cinfo, compptr^.component_id); + td := compptr^.dc_tbl_no; + ta := compptr^.ac_tbl_no; + if (cinfo^.progressive_mode) then + begin + { Progressive mode: only DC or only AC tables are used in one scan; + furthermore, Huffman coding of DC refinement uses no table at all. + We emit 0 for unused field(s); this is recommended by the P&M text + but does not seem to be specified in the standard. } + + if (cinfo^.Ss = 0) then + begin + ta := 0; { DC scan } + if (cinfo^.Ah <> 0) and not cinfo^.arith_code then + td := 0; { no DC table either } + end + else + begin + td := 0; { AC scan } + end; + end; + emit_byte(cinfo, (td shl 4) + ta); + end; + + emit_byte(cinfo, cinfo^.Ss); + emit_byte(cinfo, cinfo^.Se); + emit_byte(cinfo, (cinfo^.Ah shl 4) + cinfo^.Al); +end; + + +{LOCAL} +procedure emit_jfif_app0 (cinfo : j_compress_ptr); +{ Emit a JFIF-compliant APP0 marker } +{ + Length of APP0 block (2 bytes) + Block ID (4 bytes - ASCII "JFIF") + Zero byte (1 byte to terminate the ID string) + Version Major, Minor (2 bytes - major first) + Units (1 byte - $00 = none, $01 = inch, $02 = cm) + Xdpu (2 bytes - dots per unit horizontal) + Ydpu (2 bytes - dots per unit vertical) + Thumbnail X size (1 byte) + Thumbnail Y size (1 byte) +} +begin + emit_marker(cinfo, M_APP0); + + emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); { length } + + emit_byte(cinfo, $4A); { Identifier: ASCII "JFIF" } + emit_byte(cinfo, $46); + emit_byte(cinfo, $49); + emit_byte(cinfo, $46); + emit_byte(cinfo, 0); + emit_byte(cinfo, cinfo^.JFIF_major_version); { Version fields } + emit_byte(cinfo, cinfo^.JFIF_minor_version); + emit_byte(cinfo, cinfo^.density_unit); { Pixel size information } + emit_2bytes(cinfo, int(cinfo^.X_density)); + emit_2bytes(cinfo, int(cinfo^.Y_density)); + emit_byte(cinfo, 0); { No thumbnail image } + emit_byte(cinfo, 0); +end; + + +{LOCAL} +procedure emit_adobe_app14 (cinfo : j_compress_ptr); +{ Emit an Adobe APP14 marker } +{ + Length of APP14 block (2 bytes) + Block ID (5 bytes - ASCII "Adobe") + Version Number (2 bytes - currently 100) + Flags0 (2 bytes - currently 0) + Flags1 (2 bytes - currently 0) + Color transform (1 byte) + + Although Adobe TN 5116 mentions Version = 101, all the Adobe files + now in circulation seem to use Version = 100, so that's what we write. + + We write the color transform byte as 1 if the JPEG color space is + YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with + whether the encoder performed a transformation, which is pretty useless. +} +begin + emit_marker(cinfo, M_APP14); + + emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); { length } + + emit_byte(cinfo, $41); { Identifier: ASCII "Adobe" } + emit_byte(cinfo, $64); + emit_byte(cinfo, $6F); + emit_byte(cinfo, $62); + emit_byte(cinfo, $65); + emit_2bytes(cinfo, 100); { Version } + emit_2bytes(cinfo, 0); { Flags0 } + emit_2bytes(cinfo, 0); { Flags1 } + case (cinfo^.jpeg_color_space) of + JCS_YCbCr: + emit_byte(cinfo, 1); { Color transform = 1 } + JCS_YCCK: + emit_byte(cinfo, 2); { Color transform = 2 } + else + emit_byte(cinfo, 0); { Color transform = 0 } + end; +end; + + +{ These routines allow writing an arbitrary marker with parameters. + The only intended use is to emit COM or APPn markers after calling + write_file_header and before calling write_frame_header. + Other uses are not guaranteed to produce desirable results. + Counting the parameter bytes properly is the caller's responsibility. } + +{METHODDEF} +procedure write_marker_header (cinfo : j_compress_ptr; + marker : int; + datalen : uint); +{ Emit an arbitrary marker header } +begin + if (datalen > uint(65533)) then { safety check } + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + emit_marker(cinfo, JPEG_MARKER(marker)); + + emit_2bytes(cinfo, int(datalen + 2)); { total length } +end; + +{METHODDEF} +procedure write_marker_byte (cinfo : j_compress_ptr; val : int); +{ Emit one byte of marker parameters following write_marker_header } +begin + emit_byte(cinfo, val); +end; + +{ Write datastream header. + This consists of an SOI and optional APPn markers. + We recommend use of the JFIF marker, but not the Adobe marker, + when using YCbCr or grayscale data. The JFIF marker should NOT + be used for any other JPEG colorspace. The Adobe marker is helpful + to distinguish RGB, CMYK, and YCCK colorspaces. + Note that an application can write additional header markers after + jpeg_start_compress returns. } + + +{METHODDEF} +procedure write_file_header (cinfo : j_compress_ptr); +var + marker : my_marker_ptr; +begin + marker := my_marker_ptr(cinfo^.marker); + + emit_marker(cinfo, M_SOI); { first the SOI } + + { SOI is defined to reset restart interval to 0 } + marker^.last_restart_interval := 0; + + if (cinfo^.write_JFIF_header) then { next an optional JFIF APP0 } + emit_jfif_app0(cinfo); + if (cinfo^.write_Adobe_marker) then { next an optional Adobe APP14 } + emit_adobe_app14(cinfo); +end; + + +{ Write frame header. + This consists of DQT and SOFn markers. + Note that we do not emit the SOF until we have emitted the DQT(s). + This avoids compatibility problems with incorrect implementations that + try to error-check the quant table numbers as soon as they see the SOF. } + + +{METHODDEF} +procedure write_frame_header (cinfo : j_compress_ptr); +var + ci, prec : int; + is_baseline : boolean; + compptr : jpeg_component_info_ptr; +begin + { Emit DQT for each quantization table. + Note that emit_dqt() suppresses any duplicate tables. } + + prec := 0; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to Pred(cinfo^.num_components) do + begin + prec := prec + emit_dqt(cinfo, compptr^.quant_tbl_no); + Inc(compptr); + end; + { now prec is nonzero iff there are any 16-bit quant tables. } + + { Check for a non-baseline specification. + Note we assume that Huffman table numbers won't be changed later. } + + if (cinfo^.arith_code) or (cinfo^.progressive_mode) + or (cinfo^.data_precision <> 8) then + begin + is_baseline := FALSE; + end + else + begin + is_baseline := TRUE; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to Pred(cinfo^.num_components) do + begin + if (compptr^.dc_tbl_no > 1) or (compptr^.ac_tbl_no > 1) then + is_baseline := FALSE; + Inc(compptr); + end; + if (prec <> 0) and (is_baseline) then + begin + is_baseline := FALSE; + { If it's baseline except for quantizer size, warn the user } + {$IFDEF DEBUG} + TRACEMS(j_common_ptr(cinfo), 0, JTRC_16BIT_TABLES); + {$ENDIF} + end; + end; + + { Emit the proper SOF marker } + if (cinfo^.arith_code) then + begin + emit_sof(cinfo, M_SOF9); { SOF code for arithmetic coding } + end + else + begin + if (cinfo^.progressive_mode) then + emit_sof(cinfo, M_SOF2) { SOF code for progressive Huffman } + else if (is_baseline) then + emit_sof(cinfo, M_SOF0) { SOF code for baseline implementation } + else + emit_sof(cinfo, M_SOF1); { SOF code for non-baseline Huffman file } + end; +end; + + +{ Write scan header. + This consists of DHT or DAC markers, optional DRI, and SOS. + Compressed data will be written following the SOS. } + +{METHODDEF} +procedure write_scan_header (cinfo : j_compress_ptr); +var + marker : my_marker_ptr; + i : int; + compptr : jpeg_component_info_ptr; +begin + marker := my_marker_ptr(cinfo^.marker); + if (cinfo^.arith_code) then + begin + { Emit arith conditioning info. We may have some duplication + if the file has multiple scans, but it's so small it's hardly + worth worrying about. } + emit_dac(cinfo); + end + else + begin + { Emit Huffman tables. + Note that emit_dht() suppresses any duplicate tables. } + for i := 0 to Pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[i]; + if (cinfo^.progressive_mode) then + begin + { Progressive mode: only DC or only AC tables are used in one scan } + if (cinfo^.Ss = 0) then + begin + if (cinfo^.Ah = 0) then { DC needs no table for refinement scan } + emit_dht(cinfo, compptr^.dc_tbl_no, FALSE); + end + else + begin + emit_dht(cinfo, compptr^.ac_tbl_no, TRUE); + end; + end + else + begin + { Sequential mode: need both DC and AC tables } + emit_dht(cinfo, compptr^.dc_tbl_no, FALSE); + emit_dht(cinfo, compptr^.ac_tbl_no, TRUE); + end; + end; + end; + + { Emit DRI if required --- note that DRI value could change for each scan. + We avoid wasting space with unnecessary DRIs, however. } + + if (cinfo^.restart_interval <> marker^.last_restart_interval) then + begin + emit_dri(cinfo); + marker^.last_restart_interval := cinfo^.restart_interval; + end; + + emit_sos(cinfo); +end; + + + +{ Write datastream trailer. } + + +{METHODDEF} +procedure write_file_trailer (cinfo : j_compress_ptr); +begin + emit_marker(cinfo, M_EOI); +end; + + +{ Write an abbreviated table-specification datastream. + This consists of SOI, DQT and DHT tables, and EOI. + Any table that is defined and not marked sent_table = TRUE will be + emitted. Note that all tables will be marked sent_table = TRUE at exit. } + + +{METHODDEF} +procedure write_tables_only (cinfo : j_compress_ptr); +var + i : int; +begin + emit_marker(cinfo, M_SOI); + + for i := 0 to Pred(NUM_QUANT_TBLS) do + begin + if (cinfo^.quant_tbl_ptrs[i] <> NIL) then + emit_dqt(cinfo, i); { dummy := ... } + end; + + if (not cinfo^.arith_code) then + begin + for i := 0 to Pred(NUM_HUFF_TBLS) do + begin + if (cinfo^.dc_huff_tbl_ptrs[i] <> NIL) then + emit_dht(cinfo, i, FALSE); + if (cinfo^.ac_huff_tbl_ptrs[i] <> NIL) then + emit_dht(cinfo, i, TRUE); + end; + end; + + emit_marker(cinfo, M_EOI); +end; + + +{ Initialize the marker writer module. } + +{GLOBAL} +procedure jinit_marker_writer (cinfo : j_compress_ptr); +var + marker : my_marker_ptr; +begin + { Create the subobject } + marker := my_marker_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_marker_writer)) ); + cinfo^.marker := jpeg_marker_writer_ptr(marker); + { Initialize method pointers } + marker^.pub.write_file_header := write_file_header; + marker^.pub.write_frame_header := write_frame_header; + marker^.pub.write_scan_header := write_scan_header; + marker^.pub.write_file_trailer := write_file_trailer; + marker^.pub.write_tables_only := write_tables_only; + marker^.pub.write_marker_header := write_marker_header; + marker^.pub.write_marker_byte := write_marker_byte; + { Initialize private state } + marker^.last_restart_interval := 0; +end; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcmaster_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcmaster_del.pas new file mode 100644 index 0000000..8ec37fe --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcmaster_del.pas @@ -0,0 +1,704 @@ +Unit jcmaster_del; + +{ This file contains master control logic for the JPEG compressor. + These routines are concerned with parameter validation, initial setup, + and inter-pass control (determining the number of passes and the work + to be done in each pass). } + +{ Original: jcmaster.c ; Copyright (C) 1991-1997, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jutils_del, + jpeglib_del; + + +{ Initialize master compression control. } + +{GLOBAL} +procedure jinit_c_master_control (cinfo : j_compress_ptr; + transcode_only : boolean); + +implementation + +{ Private state } + +type + c_pass_type = ( + main_pass, { input data, also do first output step } + huff_opt_pass, { Huffman code optimization pass } + output_pass { data output pass } + ); + +type + my_master_ptr = ^my_comp_master; + my_comp_master = record + pub : jpeg_comp_master; { public fields } + + pass_type : c_pass_type; { the type of the current pass } + + pass_number : int; { # of passes completed } + total_passes : int; { total # of passes needed } + + scan_number : int; { current index in scan_info[] } + end; + + +{ Support routines that do various essential calculations. } + +{LOCAL} +procedure initial_setup (cinfo : j_compress_ptr); +{ Do computations that are needed before master selection phase } +var + ci : int; + compptr : jpeg_component_info_ptr; + samplesperrow : long; + jd_samplesperrow : JDIMENSION; +begin + + { Sanity check on image dimensions } + if (cinfo^.image_height <= 0) or (cinfo^.image_width <= 0) or + (cinfo^.num_components <= 0) or (cinfo^.input_components <= 0) then + ERREXIT(j_common_ptr(cinfo), JERR_EMPTY_IMAGE); + + { Make sure image isn't bigger than I can handle } + if ( long(cinfo^.image_height) > long(JPEG_MAX_DIMENSION)) or + ( long(cinfo^.image_width) > long(JPEG_MAX_DIMENSION)) then + ERREXIT1(j_common_ptr(cinfo), JERR_IMAGE_TOO_BIG, + uInt(JPEG_MAX_DIMENSION)); + + { Width of an input scanline must be representable as JDIMENSION. } + samplesperrow := long (cinfo^.image_width) * long (cinfo^.input_components); + jd_samplesperrow := JDIMENSION (samplesperrow); + if ( long(jd_samplesperrow) <> samplesperrow) then + ERREXIT(j_common_ptr(cinfo), JERR_WIDTH_OVERFLOW); + + { For now, precision must match compiled-in value... } + if (cinfo^.data_precision <> BITS_IN_JSAMPLE) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PRECISION, cinfo^.data_precision); + + { Check that number of components won't exceed internal array sizes } + if (cinfo^.num_components > MAX_COMPONENTS) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.num_components, + MAX_COMPONENTS); + + { Compute maximum sampling factors; check factor validity } + cinfo^.max_h_samp_factor := 1; + cinfo^.max_v_samp_factor := 1; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + if (compptr^.h_samp_factor<=0) or (compptr^.h_samp_factor>MAX_SAMP_FACTOR) + or (compptr^.v_samp_factor<=0) or (compptr^.v_samp_factor>MAX_SAMP_FACTOR) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_SAMPLING); + { MAX } + if cinfo^.max_h_samp_factor > compptr^.h_samp_factor then + cinfo^.max_h_samp_factor := cinfo^.max_h_samp_factor + else + cinfo^.max_h_samp_factor := compptr^.h_samp_factor; + { MAX } + if cinfo^.max_v_samp_factor > compptr^.v_samp_factor then + cinfo^.max_v_samp_factor := cinfo^.max_v_samp_factor + else + cinfo^.max_v_samp_factor := compptr^.v_samp_factor; + Inc(compptr); + end; + + { Compute dimensions of components } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Fill in the correct component_index value; don't rely on application } + compptr^.component_index := ci; + { For compression, we never do DCT scaling. } + compptr^.DCT_scaled_size := DCTSIZE; + { Size in DCT blocks } + compptr^.width_in_blocks := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_width) * long (compptr^.h_samp_factor), + long (cinfo^.max_h_samp_factor * DCTSIZE)) ); + compptr^.height_in_blocks := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height) * long (compptr^.v_samp_factor), + long (cinfo^.max_v_samp_factor * DCTSIZE)) ); + { Size in samples } + compptr^.downsampled_width := JDIMENSION ( + jdiv_round_up(long(cinfo^.image_width) * long(compptr^.h_samp_factor), + long(cinfo^.max_h_samp_factor)) ); + compptr^.downsampled_height := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height) * long(compptr^.v_samp_factor), + long (cinfo^.max_v_samp_factor)) ); + { Mark component needed (this flag isn't actually used for compression) } + compptr^.component_needed := TRUE; + Inc(compptr); + end; + + { Compute number of fully interleaved MCU rows (number of times that + main controller will call coefficient controller). } + + cinfo^.total_iMCU_rows := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height), + long (cinfo^.max_v_samp_factor*DCTSIZE)) ); +end; + + +{$ifdef C_MULTISCAN_FILES_SUPPORTED} + +{LOCAL} +procedure validate_script (cinfo : j_compress_ptr); +{ Verify that the scan script in cinfo^.scan_info[] is valid; also + determine whether it uses progressive JPEG, and set cinfo^.progressive_mode. } +type + IntRow = array[0..DCTSIZE2-1] of int; + introw_ptr = ^IntRow; +var + {const}scanptr : jpeg_scan_info_ptr; + scanno, ncomps, ci, coefi, thisi : int; + Ss, Se, Ah, Al : int; + component_sent : array[0..MAX_COMPONENTS-1] of boolean; +{$ifdef C_PROGRESSIVE_SUPPORTED} + last_bitpos_int_ptr : int_ptr; + last_bitpos_ptr : introw_ptr; + last_bitpos : array[0..MAX_COMPONENTS-1] of IntRow; + { -1 until that coefficient has been seen; then last Al for it } + { The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that + seems wrong: the upper bound ought to depend on data precision. + Perhaps they really meant 0..N+1 for N-bit precision. + Here we allow 0..10 for 8-bit data; Al larger than 10 results in + out-of-range reconstructed DC values during the first DC scan, + which might cause problems for some decoders. } +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + MAX_AH_AL = 10; +{$else} +const + MAX_AH_AL = 13; +{$endif} +{$endif} +begin + + if (cinfo^.num_scans <= 0) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, 0); + + { For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1; + for progressive JPEG, no scan can have this. } + + scanptr := cinfo^.scan_info; + if (scanptr^.Ss <> 0) or (scanptr^.Se <> DCTSIZE2-1) then + begin +{$ifdef C_PROGRESSIVE_SUPPORTED} + cinfo^.progressive_mode := TRUE; + last_bitpos_int_ptr := @(last_bitpos[0][0]); + for ci := 0 to pred(cinfo^.num_components) do + for coefi := 0 to pred(DCTSIZE2) do + begin + last_bitpos_int_ptr^ := -1; + Inc(last_bitpos_int_ptr); + end; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + cinfo^.progressive_mode := FALSE; + for ci := 0 to pred(cinfo^.num_components) do + component_sent[ci] := FALSE; + end; + + for scanno := 1 to cinfo^.num_scans do + begin + { Validate component indexes } + ncomps := scanptr^.comps_in_scan; + if (ncomps <= 0) or (ncomps > MAX_COMPS_IN_SCAN) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN); + for ci := 0 to pred(ncomps) do + begin + thisi := scanptr^.component_index[ci]; + if (thisi < 0) or (thisi >= cinfo^.num_components) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, scanno); + { Components must appear in SOF order within each scan } + if (ci > 0) and (thisi <= scanptr^.component_index[ci-1]) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, scanno); + end; + { Validate progression parameters } + Ss := scanptr^.Ss; + Se := scanptr^.Se; + Ah := scanptr^.Ah; + Al := scanptr^.Al; + if (cinfo^.progressive_mode) then + begin +{$ifdef C_PROGRESSIVE_SUPPORTED} + if (Ss < 0) or (Ss >= DCTSIZE2) or (Se < Ss) or (Se >= DCTSIZE2) or + (Ah < 0) or (Ah > MAX_AH_AL) or (Al < 0) or (Al > MAX_AH_AL) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + + if (Ss < 0) or (Ss >= DCTSIZE2) or (Se < Ss) or (Se >= DCTSIZE2) + or (Ah < 0) or (Ah > MAX_AH_AL) or (Al < 0) or (Al > MAX_AH_AL) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + if (Ss = 0) then + begin + if (Se <> 0) then { DC and AC together not OK } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + end + else + begin + if (ncomps <> 1) then { AC scans must be for only one component } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + end; + for ci := 0 to pred(ncomps) do + begin + last_bitpos_ptr := @( last_bitpos[scanptr^.component_index[ci]]); + if (Ss <> 0) and (last_bitpos_ptr^[0] < 0) then { AC without prior DC scan } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + for coefi := Ss to Se do + begin + if (last_bitpos_ptr^[coefi] < 0) then + begin + { first scan of this coefficient } + if (Ah <> 0) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + end + else + begin + { not first scan } + if (Ah <> last_bitpos_ptr^[coefi]) or (Al <> Ah-1) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + end; + last_bitpos_ptr^[coefi] := Al; + end; + end; +{$endif} + end + else + begin + { For sequential JPEG, all progression parameters must be these: } + if (Ss <> 0) or (Se <> DCTSIZE2-1) or (Ah <> 0) or (Al <> 0) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + { Make sure components are not sent twice } + for ci := 0 to pred(ncomps) do + begin + thisi := scanptr^.component_index[ci]; + if (component_sent[thisi]) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, scanno); + component_sent[thisi] := TRUE; + end; + end; + Inc(scanptr); + end; + + { Now verify that everything got sent. } + if (cinfo^.progressive_mode) then + begin +{$ifdef C_PROGRESSIVE_SUPPORTED + { For progressive mode, we only check that at least some DC data + got sent for each component; the spec does not require that all bits + of all coefficients be transmitted. Would it be wiser to enforce + transmission of all coefficient bits?? } + + for ci := 0 to pred(cinfo^.num_components) do + begin + if (last_bitpos[ci][0] < 0) then + ERREXIT(j_common_ptr(cinfo), JERR_MISSING_DATA); + end; +{$endif} + end + else + begin + for ci := 0 to pred(cinfo^.num_components) do + begin + if (not component_sent[ci]) then + ERREXIT(j_common_ptr(cinfo), JERR_MISSING_DATA); + end; + end; +end; + +{$endif} { C_MULTISCAN_FILES_SUPPORTED } + + +{LOCAL} +procedure select_scan_parameters (cinfo : j_compress_ptr); +{ Set up the scan parameters for the current scan } +var + master : my_master_ptr; + {const} scanptr : jpeg_scan_info_ptr; + ci : int; +var + comp_infos : jpeg_component_info_list_ptr; +begin +{$ifdef C_MULTISCAN_FILES_SUPPORTED} + if (cinfo^.scan_info <> NIL) then + begin + { Prepare for current scan --- the script is already validated } + master := my_master_ptr (cinfo^.master); + scanptr := cinfo^.scan_info; + Inc(scanptr, master^.scan_number); + + cinfo^.comps_in_scan := scanptr^.comps_in_scan; + comp_infos := cinfo^.comp_info; + for ci := 0 to pred(scanptr^.comps_in_scan) do + begin + cinfo^.cur_comp_info[ci] := + @(comp_infos^[scanptr^.component_index[ci]]); + end; + cinfo^.Ss := scanptr^.Ss; + cinfo^.Se := scanptr^.Se; + cinfo^.Ah := scanptr^.Ah; + cinfo^.Al := scanptr^.Al; + end + else +{$endif} + begin + { Prepare for single sequential-JPEG scan containing all components } + if (cinfo^.num_components > MAX_COMPS_IN_SCAN) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.num_components, + MAX_COMPS_IN_SCAN); + cinfo^.comps_in_scan := cinfo^.num_components; + comp_infos := cinfo^.comp_info; + for ci := 0 to pred(cinfo^.num_components) do + begin + cinfo^.cur_comp_info[ci] := @(comp_infos^[ci]); + end; + cinfo^.Ss := 0; + cinfo^.Se := DCTSIZE2-1; + cinfo^.Ah := 0; + cinfo^.Al := 0; + end; +end; + + +{LOCAL} +procedure per_scan_setup (cinfo : j_compress_ptr); +{ Do computations that are needed before processing a JPEG scan } +{ cinfo^.comps_in_scan and cinfo^.cur_comp_info[] are already set } +var + ci, mcublks, tmp : int; + compptr : jpeg_component_info_ptr; + nominal : long; +begin + if (cinfo^.comps_in_scan = 1) then + begin + + { Noninterleaved (single-component) scan } + compptr := cinfo^.cur_comp_info[0]; + + { Overall image size in MCUs } + cinfo^.MCUs_per_row := compptr^.width_in_blocks; + cinfo^.MCU_rows_in_scan := compptr^.height_in_blocks; + + { For noninterleaved scan, always one block per MCU } + compptr^.MCU_width := 1; + compptr^.MCU_height := 1; + compptr^.MCU_blocks := 1; + compptr^.MCU_sample_width := DCTSIZE; + compptr^.last_col_width := 1; + { For noninterleaved scans, it is convenient to define last_row_height + as the number of block rows present in the last iMCU row. } + + tmp := int (compptr^.height_in_blocks mod compptr^.v_samp_factor); + if (tmp = 0) then + tmp := compptr^.v_samp_factor; + compptr^.last_row_height := tmp; + + { Prepare array describing MCU composition } + cinfo^.blocks_in_MCU := 1; + cinfo^.MCU_membership[0] := 0; + + end + else + begin + + { Interleaved (multi-component) scan } + if (cinfo^.comps_in_scan <= 0) or + (cinfo^.comps_in_scan > MAX_COMPS_IN_SCAN) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, + cinfo^.comps_in_scan, MAX_COMPS_IN_SCAN); + + { Overall image size in MCUs } + cinfo^.MCUs_per_row := JDIMENSION ( + jdiv_round_up( long (cinfo^.image_width), + long (cinfo^.max_h_samp_factor*DCTSIZE)) ); + cinfo^.MCU_rows_in_scan := JDIMENSION ( + jdiv_round_up( long (cinfo^.image_height), + long (cinfo^.max_v_samp_factor*DCTSIZE)) ); + + cinfo^.blocks_in_MCU := 0; + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { Sampling factors give # of blocks of component in each MCU } + compptr^.MCU_width := compptr^.h_samp_factor; + compptr^.MCU_height := compptr^.v_samp_factor; + compptr^.MCU_blocks := compptr^.MCU_width * compptr^.MCU_height; + compptr^.MCU_sample_width := compptr^.MCU_width * DCTSIZE; + { Figure number of non-dummy blocks in last MCU column & row } + tmp := int (compptr^.width_in_blocks mod compptr^.MCU_width); + if (tmp = 0) then + tmp := compptr^.MCU_width; + compptr^.last_col_width := tmp; + tmp := int (compptr^.height_in_blocks mod compptr^.MCU_height); + if (tmp = 0) then + tmp := compptr^.MCU_height; + compptr^.last_row_height := tmp; + { Prepare array describing MCU composition } + mcublks := compptr^.MCU_blocks; + if (cinfo^.blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_MCU_SIZE); + while (mcublks > 0) do + begin + Dec(mcublks); + cinfo^.MCU_membership[cinfo^.blocks_in_MCU] := ci; + Inc(cinfo^.blocks_in_MCU); + end; + end; + + end; + + { Convert restart specified in rows to actual MCU count. } + { Note that count must fit in 16 bits, so we provide limiting. } + if (cinfo^.restart_in_rows > 0) then + begin + nominal := long(cinfo^.restart_in_rows) * long(cinfo^.MCUs_per_row); + if nominal < long(65535) then + cinfo^.restart_interval := uInt (nominal) + else + cinfo^.restart_interval := long(65535); + end; +end; + + +{ Per-pass setup. + This is called at the beginning of each pass. We determine which modules + will be active during this pass and give them appropriate start_pass calls. + We also set is_last_pass to indicate whether any more passes will be + required. } + +{METHODDEF} +procedure prepare_for_pass (cinfo : j_compress_ptr); +var + master : my_master_ptr; +var + fallthrough : boolean; +begin + master := my_master_ptr (cinfo^.master); + fallthrough := true; + + case (master^.pass_type) of + main_pass: + begin + { Initial pass: will collect input data, and do either Huffman + optimization or data output for the first scan. } + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (not cinfo^.raw_data_in) then + begin + cinfo^.cconvert^.start_pass (cinfo); + cinfo^.downsample^.start_pass (cinfo); + cinfo^.prep^.start_pass (cinfo, JBUF_PASS_THRU); + end; + cinfo^.fdct^.start_pass (cinfo); + cinfo^.entropy^.start_pass (cinfo, cinfo^.optimize_coding); + if master^.total_passes > 1 then + cinfo^.coef^.start_pass (cinfo, JBUF_SAVE_AND_PASS) + else + cinfo^.coef^.start_pass (cinfo, JBUF_PASS_THRU); + cinfo^.main^.start_pass (cinfo, JBUF_PASS_THRU); + if (cinfo^.optimize_coding) then + begin + { No immediate data output; postpone writing frame/scan headers } + master^.pub.call_pass_startup := FALSE; + end + else + begin + { Will write frame/scan headers at first jpeg_write_scanlines call } + master^.pub.call_pass_startup := TRUE; + end; + end; +{$ifdef ENTROPY_OPT_SUPPORTED} + huff_opt_pass, + output_pass: + begin + if (master^.pass_type = huff_opt_pass) then + begin + { Do Huffman optimization for a scan after the first one. } + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (cinfo^.Ss <> 0) or (cinfo^.Ah = 0) or (cinfo^.arith_code) then + begin + cinfo^.entropy^.start_pass (cinfo, TRUE); + cinfo^.coef^.start_pass (cinfo, JBUF_CRANK_DEST); + master^.pub.call_pass_startup := FALSE; + fallthrough := false; + end; + { Special case: Huffman DC refinement scans need no Huffman table + and therefore we can skip the optimization pass for them. } + if fallthrough then + begin + master^.pass_type := output_pass; + Inc(master^.pass_number); + {FALLTHROUGH} + end; + end; +{$else} + output_pass: + begin +{$endif} + if fallthrough then + begin + { Do a data-output pass. } + { We need not repeat per-scan setup if prior optimization pass did it. } + if (not cinfo^.optimize_coding) then + begin + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + end; + cinfo^.entropy^.start_pass (cinfo, FALSE); + cinfo^.coef^.start_pass (cinfo, JBUF_CRANK_DEST); + { We emit frame/scan headers now } + if (master^.scan_number = 0) then + cinfo^.marker^.write_frame_header (cinfo); + cinfo^.marker^.write_scan_header (cinfo); + master^.pub.call_pass_startup := FALSE; + end; + end; + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + end; + + master^.pub.is_last_pass := (master^.pass_number = master^.total_passes-1); + + { Set up progress monitor's pass info if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.completed_passes := master^.pass_number; + cinfo^.progress^.total_passes := master^.total_passes; + end; +end; + + +{ Special start-of-pass hook. + This is called by jpeg_write_scanlines if call_pass_startup is TRUE. + In single-pass processing, we need this hook because we don't want to + write frame/scan headers during jpeg_start_compress; we want to let the + application write COM markers etc. between jpeg_start_compress and the + jpeg_write_scanlines loop. + In multi-pass processing, this routine is not used. } + +{METHODDEF} +procedure pass_startup (cinfo : j_compress_ptr); +begin + cinfo^.master^.call_pass_startup := FALSE; { reset flag so call only once } + + cinfo^.marker^.write_frame_header (cinfo); + cinfo^.marker^.write_scan_header (cinfo); +end; + + +{ Finish up at end of pass. } + +{METHODDEF} +procedure finish_pass_master (cinfo : j_compress_ptr); +var + master : my_master_ptr; +begin + master := my_master_ptr (cinfo^.master); + + { The entropy coder always needs an end-of-pass call, + either to analyze statistics or to flush its output buffer. } + cinfo^.entropy^.finish_pass (cinfo); + + { Update state for next pass } + case (master^.pass_type) of + main_pass: + begin + { next pass is either output of scan 0 (after optimization) + or output of scan 1 (if no optimization). } + + master^.pass_type := output_pass; + if (not cinfo^.optimize_coding) then + Inc(master^.scan_number); + end; + huff_opt_pass: + { next pass is always output of current scan } + master^.pass_type := output_pass; + output_pass: + begin + { next pass is either optimization or output of next scan } + if (cinfo^.optimize_coding) then + master^.pass_type := huff_opt_pass; + Inc(master^.scan_number); + end; + end; + + Inc(master^.pass_number); +end; + + +{ Initialize master compression control. } + +{GLOBAL} +procedure jinit_c_master_control (cinfo : j_compress_ptr; + transcode_only : boolean); +var + master : my_master_ptr; +begin + master := my_master_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_comp_master)) ); + cinfo^.master := jpeg_comp_master_ptr(master); + master^.pub.prepare_for_pass := prepare_for_pass; + master^.pub.pass_startup := pass_startup; + master^.pub.finish_pass := finish_pass_master; + master^.pub.is_last_pass := FALSE; + + { Validate parameters, determine derived values } + initial_setup(cinfo); + + if (cinfo^.scan_info <> NIL) then + begin +{$ifdef C_MULTISCAN_FILES_SUPPORTED} + validate_script(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + cinfo^.progressive_mode := FALSE; + cinfo^.num_scans := 1; + end; + + if (cinfo^.progressive_mode) then { TEMPORARY HACK ??? } + cinfo^.optimize_coding := TRUE; { assume default tables no good for progressive mode } + + { Initialize my private state } + if (transcode_only) then + begin + { no main pass in transcoding } + if (cinfo^.optimize_coding) then + master^.pass_type := huff_opt_pass + else + master^.pass_type := output_pass; + end + else + begin + { for normal compression, first pass is always this type: } + master^.pass_type := main_pass; + end; + master^.scan_number := 0; + master^.pass_number := 0; + if (cinfo^.optimize_coding) then + master^.total_passes := cinfo^.num_scans * 2 + else + master^.total_passes := cinfo^.num_scans; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcomapi_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcomapi_del.pas new file mode 100644 index 0000000..ce4ce52 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcomapi_del.pas @@ -0,0 +1,131 @@ +unit jcomapi_del; + +{ This file contains application interface routines that are used for both + compression and decompression. } + +{ Original: jcomapi.c; Copyright (C) 1994-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del; + +{ Abort processing of a JPEG compression or decompression operation, + but don't destroy the object itself. } + +{GLOBAL} +procedure jpeg_abort (cinfo : j_common_ptr); + + +{ Destruction of a JPEG object. } + +{GLOBAL} +procedure jpeg_destroy (cinfo : j_common_ptr); + +{GLOBAL} +function jpeg_alloc_quant_table (cinfo : j_common_ptr) : JQUANT_TBL_PTR; + +{GLOBAL} +function jpeg_alloc_huff_table (cinfo : j_common_ptr) : JHUFF_TBL_PTR; + +implementation + +{ Abort processing of a JPEG compression or decompression operation, + but don't destroy the object itself. + + For this, we merely clean up all the nonpermanent memory pools. + Note that temp files (virtual arrays) are not allowed to belong to + the permanent pool, so we will be able to close all temp files here. + Closing a data source or destination, if necessary, is the application's + responsibility. } + + +{GLOBAL} +procedure jpeg_abort (cinfo : j_common_ptr); +var + pool : int; +begin + { Do nothing if called on a not-initialized or destroyed JPEG object. } + if (cinfo^.mem = NIL) then + exit; + + { Releasing pools in reverse order might help avoid fragmentation + with some (brain-damaged) malloc libraries. } + + for pool := JPOOL_NUMPOOLS-1 downto JPOOL_PERMANENT+1 do + begin + cinfo^.mem^.free_pool (cinfo, pool); + end; + + { Reset overall state for possible reuse of object } + if (cinfo^.is_decompressor) then + begin + cinfo^.global_state := DSTATE_START; + { Try to keep application from accessing now-deleted marker list. + A bit kludgy to do it here, but this is the most central place. } + j_decompress_ptr(cinfo)^.marker_list := NIL; + end + else + begin + cinfo^.global_state := CSTATE_START; + end; +end; + + +{ Destruction of a JPEG object. + + Everything gets deallocated except the master jpeg_compress_struct itself + and the error manager struct. Both of these are supplied by the application + and must be freed, if necessary, by the application. (Often they are on + the stack and so don't need to be freed anyway.) + Closing a data source or destination, if necessary, is the application's + responsibility. } + + +{GLOBAL} +procedure jpeg_destroy (cinfo : j_common_ptr); +begin + { We need only tell the memory manager to release everything. } + { NB: mem pointer is NIL if memory mgr failed to initialize. } + if (cinfo^.mem <> NIL) then + cinfo^.mem^.self_destruct (cinfo); + cinfo^.mem := NIL; { be safe if jpeg_destroy is called twice } + cinfo^.global_state := 0; { mark it destroyed } +end; + + +{ Convenience routines for allocating quantization and Huffman tables. + (Would jutils.c be a more reasonable place to put these?) } + + +{GLOBAL} +function jpeg_alloc_quant_table (cinfo : j_common_ptr) : JQUANT_TBL_PTR; +var + tbl : JQUANT_TBL_PTR; +begin + tbl := JQUANT_TBL_PTR( + cinfo^.mem^.alloc_small (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL)) + ); + tbl^.sent_table := FALSE; { make sure this is false in any new table } + jpeg_alloc_quant_table := tbl; +end; + + +{GLOBAL} +function jpeg_alloc_huff_table (cinfo : j_common_ptr) : JHUFF_TBL_PTR; +var + tbl : JHUFF_TBL_PTR; +begin + tbl := JHUFF_TBL_PTR( + cinfo^.mem^.alloc_small (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL)) + ); + tbl^.sent_table := FALSE; { make sure this is false in any new table } + jpeg_alloc_huff_table := tbl; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jconfig_del.inc b/mseide-msegui/lib/common/fpccompatibility/jconfig_del.inc new file mode 100644 index 0000000..3d10c93 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jconfig_del.inc @@ -0,0 +1,118 @@ +{ ----------------------- JPEG_INTERNAL_OPTIONS ---------------------- } + + +{ These defines indicate whether to include various optional functions. + Undefining some of these symbols will produce a smaller but less capable + library. Note that you can leave certain source files out of the + compilation/linking process if you've #undef'd the corresponding symbols. + (You may HAVE to do that if your compiler doesn't like null source files.)} + + +{ Arithmetic coding is unsupported for legal reasons. Complaints to IBM. } + +{ Capability options common to encoder and decoder: } + +{$define DCT_ISLOW_SUPPORTED} { slow but accurate integer algorithm } +{$define DCT_IFAST_SUPPORTED} { faster, less accurate integer method } +{$define DCT_FLOAT_SUPPORTED} { floating-point: accurate, fast on fast HW } + +{ Encoder capability options: } + +{$undef C_ARITH_CODING_SUPPORTED} { Arithmetic coding back end? } +{$define C_MULTISCAN_FILES_SUPPORTED} { Multiple-scan JPEG files? } +{$define C_PROGRESSIVE_SUPPORTED} { Progressive JPEG? (Requires MULTISCAN)} +{$define ENTROPY_OPT_SUPPORTED} { Optimization of entropy coding parms? } +{ Note: if you selected 12-bit data precision, it is dangerous to turn off + ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + precision, so jchuff.c normally uses entropy optimization to compute + usable tables for higher precision. If you don't want to do optimization, + you'll have to supply different default Huffman tables. + The exact same statements apply for progressive JPEG: the default tables + don't work for progressive mode. (This may get fixed, however.) } + +{$define INPUT_SMOOTHING_SUPPORTED} { Input image smoothing option? } + +{ Decoder capability options: } + +{$undef D_ARITH_CODING_SUPPORTED} { Arithmetic coding back end? } +{$define D_MULTISCAN_FILES_SUPPORTED} { Multiple-scan JPEG files? } +{$define D_PROGRESSIVE_SUPPORTED} { Progressive JPEG? (Requires MULTISCAN)} +{$define SAVE_MARKERS_SUPPORTED} { jpeg_save_markers() needed? } +{$define BLOCK_SMOOTHING_SUPPORTED} { Block smoothing? (Progressive only) } +{$define IDCT_SCALING_SUPPORTED} { Output rescaling via IDCT? } +{$undef UPSAMPLE_SCALING_SUPPORTED} { Output rescaling at upsample stage? } +{$define UPSAMPLE_MERGING_SUPPORTED} { Fast path for sloppy upsampling? } +{$define QUANT_1PASS_SUPPORTED} { 1-pass color quantization? } +{$define QUANT_2PASS_SUPPORTED} { 2-pass color quantization? } + +{ If you happen not to want the image transform support, disable it here } +{$define TRANSFORMS_SUPPORTED} + +{ more capability options later, no doubt } + +{$ifopt I+} {$define IOcheck} {$endif} + +{ ------------------------------------------------------------------------ } + +{$define USE_FMEM} { Borland has _fmemcpy() and _fmemset() } + +{$define FMEMCOPY} +{$define FMEMZERO} + +{$define DCTSIZE_IS_8} { e.g. unroll the inner loop } +{$define RIGHT_SHIFT_IS_UNSIGNED} +{$undef AVOID_TABLES} +{$undef FAST_DIVIDE} + +{$define BITS_IN_JSAMPLE_IS_8} + +{----------------------------------------------------------------} +{ for test of 12 bit JPEG code only. !! } +{-- $undef BITS_IN_JSAMPLE_IS_8} +{----------------------------------------------------------------} + +{$define RGB_PIXELSIZE_IS_3} +{$define SLOW_SHIFT_32} +{$define RGB_RED_IS_0} { RGB byte order in JQUANT2 } + +{$undef NO_ZERO_ROW_TEST} + +{$define USE_MSDOS_MEMMGR} { Define this if you use jmemdos.c } +{$define XMS_SUPPORTED} +{$define EMS_SUPPORTED} + +{$undef MEM_STATS} { Write out memory usage } +{$define AM_MEMORY_MANAGER} { we define jvirt_Xarray_control structs } + +{$undef FULL_MAIN_BUFFER_SUPPORTED} + +{$define PROGRESS_REPORT} +{$define TWO_FILE_COMMANDLINE} +{$define BMP_SUPPORTED} +{$define PPM_SUPPORTED} +{$undef GIF_SUPPORTED} +{$undef RLE_SUPPORTED} +{$define TARGA_SUPPORTED} +{$define EXT_SWITCH} + +{$ifndef BITS_IN_JSAMPLE_IS_8} { for 12 bit samples } +{$undef BMP_SUPPORTED} +{$undef RLE_SUPPORTED} +{$undef TARGA_SUPPORTED} +{$endif} + +{$undef BASM16} { for TP7 - use BASM for fast multiply } +{$ifdef Win32} + {$ifndef FPC} + {$define BASM} { jidctint with BASM for Delphi 2/3 } + {$undef RGB_RED_IS_0} { BGR byte order in JQUANT2 } + {$endif} +{$endif} + +{$IFDEF FPC} +{$MODE DELPHI} +{$GOTO ON} +{$DEFINE DELPHI_STREAM} +{$else} +{$DEFINE DELPHI_STREAM} +{$ENDIF} diff --git a/mseide-msegui/lib/common/fpccompatibility/jconsts_del.pas b/mseide-msegui/lib/common/fpccompatibility/jconsts_del.pas new file mode 100644 index 0000000..b7339e4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jconsts_del.pas @@ -0,0 +1,11 @@ +unit jconsts; + +interface + +resourcestring + sChangeJPGSize = 'Cannot change the size of a JPEG image'; + sJPEGError = 'JPEG error #%d'; + +implementation + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcparam_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcparam_del.pas new file mode 100644 index 0000000..a59c0a2 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcparam_del.pas @@ -0,0 +1,700 @@ +Unit JcParam_del; + +{ This file contains optional default-setting code for the JPEG compressor. + Applications do not have to use this file, but those that don't use it + must know a lot more about the innards of the JPEG code. } + +{ Original: jcparam.c ; Copyright (C) 1991-1998, Thomas G. Lane. } + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jcomapi_del, + jpeglib_del; + +{ Quantization table setup routines } + +{GLOBAL} +procedure jpeg_add_quant_table (cinfo : j_compress_ptr; + which_tbl : int; + const basic_table : array of uInt; + scale_factor : int; + force_baseline : boolean); + +{GLOBAL} +procedure jpeg_set_linear_quality (cinfo : j_compress_ptr; + scale_factor : int; + force_baseline : boolean); +{ Set or change the 'quality' (quantization) setting, using default tables + and a straight percentage-scaling quality scale. In most cases it's better + to use jpeg_set_quality (below); this entry point is provided for + applications that insist on a linear percentage scaling. } + +{GLOBAL} +function jpeg_quality_scaling (quality : int) : int; +{ Convert a user-specified quality rating to a percentage scaling factor + for an underlying quantization table, using our recommended scaling curve. + The input 'quality' factor should be 0 (terrible) to 100 (very good). } + +{GLOBAL} +procedure jpeg_set_quality (cinfo : j_compress_ptr; + quality : int; + force_baseline : boolean); +{ Set or change the 'quality' (quantization) setting, using default tables. + This is the standard quality-adjusting entry point for typical user + interfaces; only those who want detailed control over quantization tables + would use the preceding three routines directly. } + +{GLOBAL} +procedure jpeg_set_defaults (cinfo : j_compress_ptr); + +{ Create a recommended progressive-JPEG script. + cinfo^.num_components and cinfo^.jpeg_color_space must be correct. } + +{ Set the JPEG colorspace, and choose colorspace-dependent default values. } + +{GLOBAL} +procedure jpeg_set_colorspace (cinfo : j_compress_ptr; + colorspace : J_COLOR_SPACE); + +{ Select an appropriate JPEG colorspace for in_color_space. } + +{GLOBAL} +procedure jpeg_default_colorspace (cinfo : j_compress_ptr); + +{GLOBAL} +procedure jpeg_simple_progression (cinfo : j_compress_ptr); + + +implementation + +{ Quantization table setup routines } + +{GLOBAL} +procedure jpeg_add_quant_table (cinfo : j_compress_ptr; + which_tbl : int; + const basic_table : array of uInt; + scale_factor : int; + force_baseline : boolean); +{ Define a quantization table equal to the basic_table times + a scale factor (given as a percentage). + If force_baseline is TRUE, the computed quantization table entries + are limited to 1..255 for JPEG baseline compatibility. } +var + qtblptr :^JQUANT_TBL_PTR; + i : int; + temp : long; +begin + { Safety check to ensure start_compress not called yet. } + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + if (which_tbl < 0) or (which_tbl >= NUM_QUANT_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_DQT_INDEX, which_tbl); + + qtblptr := @(cinfo^.quant_tbl_ptrs[which_tbl]); + + if (qtblptr^ = NIL) then + qtblptr^ := jpeg_alloc_quant_table(j_common_ptr(cinfo)); + + for i := 0 to pred(DCTSIZE2) do + begin + temp := (long(basic_table[i] * scale_factor) + long(50)) div long(100); + { limit the values to the valid range } + if (temp <= long(0)) then + temp := long(1); + if (temp > long(32767)) then + temp := long(32767); { max quantizer needed for 12 bits } + if (force_baseline) and (temp > long(255)) then + temp := long(255); { limit to baseline range if requested } + (qtblptr^)^.quantval[i] := UINT16 (temp); + end; + + { Initialize sent_table FALSE so table will be written to JPEG file. } + (qtblptr^)^.sent_table := FALSE; +end; + + +{GLOBAL} +procedure jpeg_set_linear_quality (cinfo : j_compress_ptr; + scale_factor : int; + force_baseline : boolean); +{ Set or change the 'quality' (quantization) setting, using default tables + and a straight percentage-scaling quality scale. In most cases it's better + to use jpeg_set_quality (below); this entry point is provided for + applications that insist on a linear percentage scaling. } + +{ These are the sample quantization tables given in JPEG spec section K.1. + The spec says that the values given produce "good" quality, and + when divided by 2, "very good" quality. } + +const + std_luminance_quant_tbl : array[0..DCTSIZE2-1] of uInt = + (16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99); + +const + std_chrominance_quant_tbl : array[0..DCTSIZE2-1] of uInt = + (17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99); +begin + { Set up two quantization tables using the specified scaling } + jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, + scale_factor, force_baseline); + jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl, + scale_factor, force_baseline); +end; + + +{GLOBAL} +function jpeg_quality_scaling (quality : int) : int; +{ Convert a user-specified quality rating to a percentage scaling factor + for an underlying quantization table, using our recommended scaling curve. + The input 'quality' factor should be 0 (terrible) to 100 (very good). } +begin + { Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. } + if (quality <= 0) then + quality := 1; + if (quality > 100) then + quality := 100; + + { The basic table is used as-is (scaling 100) for a quality of 50. + Qualities 50..100 are converted to scaling percentage 200 - 2*Q; + note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table + to make all the table entries 1 (hence, minimum quantization loss). + Qualities 1..50 are converted to scaling percentage 5000/Q. } + if (quality < 50) then + quality := 5000 div quality + else + quality := 200 - quality*2; + + jpeg_quality_scaling := quality; +end; + + +{GLOBAL} +procedure jpeg_set_quality (cinfo : j_compress_ptr; + quality : int; + force_baseline : boolean); +{ Set or change the 'quality' (quantization) setting, using default tables. + This is the standard quality-adjusting entry point for typical user + interfaces; only those who want detailed control over quantization tables + would use the preceding three routines directly. } +begin + { Convert user 0-100 rating to percentage scaling } + quality := jpeg_quality_scaling(quality); + + { Set up standard quality tables } + jpeg_set_linear_quality(cinfo, quality, force_baseline); +end; + + +{ Huffman table setup routines } + +{LOCAL} +procedure add_huff_table (cinfo : j_compress_ptr; + var htblptr : JHUFF_TBL_PTR; + var bits : array of UINT8; + var val : array of UINT8); +{ Define a Huffman table } +var + nsymbols, len : int; +begin + if (htblptr = NIL) then + htblptr := jpeg_alloc_huff_table(j_common_ptr(cinfo)); + + { Copy the number-of-symbols-of-each-code-length counts } + MEMCOPY(@htblptr^.bits, @bits, SIZEOF(htblptr^.bits)); + + + { Validate the counts. We do this here mainly so we can copy the right + number of symbols from the val[] array, without risking marching off + the end of memory. jchuff.c will do a more thorough test later. } + + nsymbols := 0; + for len := 1 to 16 do + Inc(nsymbols, bits[len]); + if (nsymbols < 1) or (nsymbols > 256) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + + MEMCOPY(@htblptr^.huffval, @val, nsymbols * SIZEOF(UINT8)); + + { Initialize sent_table FALSE so table will be written to JPEG file. } + (htblptr)^.sent_table := FALSE; +end; + + +{LOCAL} +procedure std_huff_tables (cinfo : j_compress_ptr); +{ Set up the standard Huffman tables (cf. JPEG standard section K.3) } +{ IMPORTANT: these are only valid for 8-bit data precision! } + const bits_dc_luminance : array[0..17-1] of UINT8 = + ({ 0-base } 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0); + const val_dc_luminance : array[0..11] of UINT8 = + (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); + + const bits_dc_chrominance : array[0..17-1] of UINT8 = + ( { 0-base } 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + const val_dc_chrominance : array[0..11] of UINT8 = + ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ); + + const bits_ac_luminance : array[0..17-1] of UINT8 = + ( { 0-base } 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, $7d ); + const val_ac_luminance : array[0..161] of UINT8 = + ( $01, $02, $03, $00, $04, $11, $05, $12, + $21, $31, $41, $06, $13, $51, $61, $07, + $22, $71, $14, $32, $81, $91, $a1, $08, + $23, $42, $b1, $c1, $15, $52, $d1, $f0, + $24, $33, $62, $72, $82, $09, $0a, $16, + $17, $18, $19, $1a, $25, $26, $27, $28, + $29, $2a, $34, $35, $36, $37, $38, $39, + $3a, $43, $44, $45, $46, $47, $48, $49, + $4a, $53, $54, $55, $56, $57, $58, $59, + $5a, $63, $64, $65, $66, $67, $68, $69, + $6a, $73, $74, $75, $76, $77, $78, $79, + $7a, $83, $84, $85, $86, $87, $88, $89, + $8a, $92, $93, $94, $95, $96, $97, $98, + $99, $9a, $a2, $a3, $a4, $a5, $a6, $a7, + $a8, $a9, $aa, $b2, $b3, $b4, $b5, $b6, + $b7, $b8, $b9, $ba, $c2, $c3, $c4, $c5, + $c6, $c7, $c8, $c9, $ca, $d2, $d3, $d4, + $d5, $d6, $d7, $d8, $d9, $da, $e1, $e2, + $e3, $e4, $e5, $e6, $e7, $e8, $e9, $ea, + $f1, $f2, $f3, $f4, $f5, $f6, $f7, $f8, + $f9, $fa ); + + const bits_ac_chrominance : array[0..17-1] of UINT8 = + ( { 0-base } 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, $77 ); + const val_ac_chrominance : array[0..161] of UINT8 = + ( $00, $01, $02, $03, $11, $04, $05, $21, + $31, $06, $12, $41, $51, $07, $61, $71, + $13, $22, $32, $81, $08, $14, $42, $91, + $a1, $b1, $c1, $09, $23, $33, $52, $f0, + $15, $62, $72, $d1, $0a, $16, $24, $34, + $e1, $25, $f1, $17, $18, $19, $1a, $26, + $27, $28, $29, $2a, $35, $36, $37, $38, + $39, $3a, $43, $44, $45, $46, $47, $48, + $49, $4a, $53, $54, $55, $56, $57, $58, + $59, $5a, $63, $64, $65, $66, $67, $68, + $69, $6a, $73, $74, $75, $76, $77, $78, + $79, $7a, $82, $83, $84, $85, $86, $87, + $88, $89, $8a, $92, $93, $94, $95, $96, + $97, $98, $99, $9a, $a2, $a3, $a4, $a5, + $a6, $a7, $a8, $a9, $aa, $b2, $b3, $b4, + $b5, $b6, $b7, $b8, $b9, $ba, $c2, $c3, + $c4, $c5, $c6, $c7, $c8, $c9, $ca, $d2, + $d3, $d4, $d5, $d6, $d7, $d8, $d9, $da, + $e2, $e3, $e4, $e5, $e6, $e7, $e8, $e9, + $ea, $f2, $f3, $f4, $f5, $f6, $f7, $f8, + $f9, $fa ); +begin + add_huff_table(cinfo, cinfo^.dc_huff_tbl_ptrs[0], + bits_dc_luminance, val_dc_luminance); + add_huff_table(cinfo, cinfo^.ac_huff_tbl_ptrs[0], + bits_ac_luminance, val_ac_luminance); + add_huff_table(cinfo, cinfo^.dc_huff_tbl_ptrs[1], + bits_dc_chrominance, val_dc_chrominance); + add_huff_table(cinfo, cinfo^.ac_huff_tbl_ptrs[1], + bits_ac_chrominance, val_ac_chrominance); +end; + + +{ Default parameter setup for compression. + + Applications that don't choose to use this routine must do their + own setup of all these parameters. Alternately, you can call this + to establish defaults and then alter parameters selectively. This + is the recommended approach since, if we add any new parameters, + your code will still work (they'll be set to reasonable defaults). } + +{GLOBAL} +procedure jpeg_set_defaults (cinfo : j_compress_ptr); +var + i : int; +begin + { Safety check to ensure start_compress not called yet. } + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(J_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + { Allocate comp_info array large enough for maximum component count. + Array is made permanent in case application wants to compress + multiple images at same param settings. } + + if (cinfo^.comp_info = NIL) then + cinfo^.comp_info := jpeg_component_info_list_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + MAX_COMPONENTS * SIZEOF(jpeg_component_info)) ); + + { Initialize everything not dependent on the color space } + + cinfo^.data_precision := BITS_IN_JSAMPLE; + { Set up two quantization tables using default quality of 75 } + jpeg_set_quality(cinfo, 75, TRUE); + { Set up two Huffman tables } + std_huff_tables(cinfo); + + { Initialize default arithmetic coding conditioning } + for i := 0 to pred(NUM_ARITH_TBLS) do + begin + cinfo^.arith_dc_L[i] := 0; + cinfo^.arith_dc_U[i] := 1; + cinfo^.arith_ac_K[i] := 5; + end; + + { Default is no multiple-scan output } + cinfo^.scan_info := NIL; + cinfo^.num_scans := 0; + + { Expect normal source image, not raw downsampled data } + cinfo^.raw_data_in := FALSE; + + { Use Huffman coding, not arithmetic coding, by default } + cinfo^.arith_code := FALSE; + + { By default, don't do extra passes to optimize entropy coding } + cinfo^.optimize_coding := FALSE; + { The standard Huffman tables are only valid for 8-bit data precision. + If the precision is higher, force optimization on so that usable + tables will be computed. This test can be removed if default tables + are supplied that are valid for the desired precision. } + + if (cinfo^.data_precision > 8) then + cinfo^.optimize_coding := TRUE; + + { By default, use the simpler non-cosited sampling alignment } + cinfo^.CCIR601_sampling := FALSE; + + { No input smoothing } + cinfo^.smoothing_factor := 0; + + { DCT algorithm preference } + cinfo^.dct_method := JDCT_DEFAULT; + + { No restart markers } + cinfo^.restart_interval := 0; + cinfo^.restart_in_rows := 0; + + { Fill in default JFIF marker parameters. Note that whether the marker + will actually be written is determined by jpeg_set_colorspace. + + By default, the library emits JFIF version code 1.01. + An application that wants to emit JFIF 1.02 extension markers should set + JFIF_minor_version to 2. We could probably get away with just defaulting + to 1.02, but there may still be some decoders in use that will complain + about that; saying 1.01 should minimize compatibility problems. } + + cinfo^.JFIF_major_version := 1; { Default JFIF version = 1.01 } + cinfo^.JFIF_minor_version := 1; + cinfo^.density_unit := 0; { Pixel size is unknown by default } + cinfo^.X_density := 1; { Pixel aspect ratio is square by default } + cinfo^.Y_density := 1; + + { Choose JPEG colorspace based on input space, set defaults accordingly } + + jpeg_default_colorspace(cinfo); +end; + + +{ Select an appropriate JPEG colorspace for in_color_space. } + +{GLOBAL} +procedure jpeg_default_colorspace (cinfo : j_compress_ptr); +begin + case (cinfo^.in_color_space) of + JCS_GRAYSCALE: + jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); + JCS_RGB: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + JCS_YCbCr: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + JCS_CMYK: + jpeg_set_colorspace(cinfo, JCS_CMYK); { By default, no translation } + JCS_YCCK: + jpeg_set_colorspace(cinfo, JCS_YCCK); + JCS_UNKNOWN: + jpeg_set_colorspace(cinfo, JCS_UNKNOWN); + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); + end; +end; + + +{ Set the JPEG colorspace, and choose colorspace-dependent default values. } + +{GLOBAL} +procedure jpeg_set_colorspace (cinfo : j_compress_ptr; + colorspace : J_COLOR_SPACE); + { macro } + procedure SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl : int); + begin + with cinfo^.comp_info^[index] do + begin + component_id := (id); + h_samp_factor := (hsamp); + v_samp_factor := (vsamp); + quant_tbl_no := (quant); + dc_tbl_no := (dctbl); + ac_tbl_no := (actbl); + end; + end; + +var + ci : int; +begin + { Safety check to ensure start_compress not called yet. } + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + { For all colorspaces, we use Q and Huff tables 0 for luminance components, + tables 1 for chrominance components. } + + cinfo^.jpeg_color_space := colorspace; + + cinfo^.write_JFIF_header := FALSE; { No marker for non-JFIF colorspaces } + cinfo^.write_Adobe_marker := FALSE; { write no Adobe marker by default } + + case (colorspace) of + JCS_GRAYSCALE: + begin + cinfo^.write_JFIF_header := TRUE; { Write a JFIF marker } + cinfo^.num_components := 1; + { JFIF specifies component ID 1 } + SET_COMP(0, 1, 1,1, 0, 0,0); + end; + JCS_RGB: + begin + cinfo^.write_Adobe_marker := TRUE; { write Adobe marker to flag RGB } + cinfo^.num_components := 3; + SET_COMP(0, $52 { 'R' }, 1,1, 0, 0,0); + SET_COMP(1, $47 { 'G' }, 1,1, 0, 0,0); + SET_COMP(2, $42 { 'B' }, 1,1, 0, 0,0); + end; + JCS_YCbCr: + begin + cinfo^.write_JFIF_header := TRUE; { Write a JFIF marker } + cinfo^.num_components := 3; + { JFIF specifies component IDs 1,2,3 } + { We default to 2x2 subsamples of chrominance } + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + end; + JCS_CMYK: + begin + cinfo^.write_Adobe_marker := TRUE; { write Adobe marker to flag CMYK } + cinfo^.num_components := 4; + SET_COMP(0, $43 { 'C' }, 1,1, 0, 0,0); + SET_COMP(1, $4D { 'M' }, 1,1, 0, 0,0); + SET_COMP(2, $59 { 'Y' }, 1,1, 0, 0,0); + SET_COMP(3, $4B { 'K' }, 1,1, 0, 0,0); + end; + JCS_YCCK: + begin + cinfo^.write_Adobe_marker := TRUE; { write Adobe marker to flag YCCK } + cinfo^.num_components := 4; + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + SET_COMP(3, 4, 2,2, 0, 0,0); + end; + JCS_UNKNOWN: + begin + cinfo^.num_components := cinfo^.input_components; + if (cinfo^.num_components < 1) + or (cinfo^.num_components > MAX_COMPONENTS) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, + cinfo^.num_components, MAX_COMPONENTS); + for ci := 0 to pred(cinfo^.num_components) do + begin + SET_COMP(ci, ci, 1,1, 0, 0,0); + end; + end; + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + end; +end; + + +{$ifdef C_PROGRESSIVE_SUPPORTED} + +{LOCAL} +function fill_a_scan (scanptr : jpeg_scan_info_ptr; + ci : int; Ss : int; + Se : int; Ah : int; + Al : int) : jpeg_scan_info_ptr; +{ Support routine: generate one scan for specified component } +begin + scanptr^.comps_in_scan := 1; + scanptr^.component_index[0] := ci; + scanptr^.Ss := Ss; + scanptr^.Se := Se; + scanptr^.Ah := Ah; + scanptr^.Al := Al; + Inc(scanptr); + fill_a_scan := scanptr; +end; + +{LOCAL} +function fill_scans (scanptr : jpeg_scan_info_ptr; + ncomps : int; + Ss : int; Se : int; + Ah : int; Al : int) : jpeg_scan_info_ptr; +{ Support routine: generate one scan for each component } +var + ci : int; +begin + + for ci := 0 to pred(ncomps) do + begin + scanptr^.comps_in_scan := 1; + scanptr^.component_index[0] := ci; + scanptr^.Ss := Ss; + scanptr^.Se := Se; + scanptr^.Ah := Ah; + scanptr^.Al := Al; + Inc(scanptr); + end; + fill_scans := scanptr; +end; + +{LOCAL} +function fill_dc_scans (scanptr : jpeg_scan_info_ptr; + ncomps : int; + Ah : int; Al : int) : jpeg_scan_info_ptr; +{ Support routine: generate interleaved DC scan if possible, else N scans } +var + ci : int; +begin + + if (ncomps <= MAX_COMPS_IN_SCAN) then + begin + { Single interleaved DC scan } + scanptr^.comps_in_scan := ncomps; + for ci := 0 to pred(ncomps) do + scanptr^.component_index[ci] := ci; + scanptr^.Ss := 0; + scanptr^.Se := 0; + scanptr^.Ah := Ah; + scanptr^.Al := Al; + Inc(scanptr); + end + else + begin + { Noninterleaved DC scan for each component } + scanptr := fill_scans(scanptr, ncomps, 0, 0, Ah, Al); + end; + fill_dc_scans := scanptr; +end; + + +{ Create a recommended progressive-JPEG script. + cinfo^.num_components and cinfo^.jpeg_color_space must be correct. } + +{GLOBAL} +procedure jpeg_simple_progression (cinfo : j_compress_ptr); +var + ncomps : int; + nscans : int; + scanptr : jpeg_scan_info_ptr; +begin + ncomps := cinfo^.num_components; + + { Safety check to ensure start_compress not called yet. } + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + { Figure space needed for script. Calculation must match code below! } + if (ncomps = 3) and (cinfo^.jpeg_color_space = JCS_YCbCr) then + begin + { Custom script for YCbCr color images. } + nscans := 10; + end + else + begin + { All-purpose script for other color spaces. } + if (ncomps > MAX_COMPS_IN_SCAN) then + nscans := 6 * ncomps { 2 DC + 4 AC scans per component } + else + nscans := 2 + 4 * ncomps; { 2 DC scans; 4 AC scans per component } + end; + + { Allocate space for script. + We need to put it in the permanent pool in case the application performs + multiple compressions without changing the settings. To avoid a memory + leak if jpeg_simple_progression is called repeatedly for the same JPEG + object, we try to re-use previously allocated space, and we allocate + enough space to handle YCbCr even if initially asked for grayscale. } + + if (cinfo^.script_space = NIL) or (cinfo^.script_space_size < nscans) then + begin + if nscans > 10 then + cinfo^.script_space_size := nscans + else + cinfo^.script_space_size := 10; + + cinfo^.script_space := jpeg_scan_info_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + cinfo^.script_space_size * SIZEOF(jpeg_scan_info)) ); + end; + scanptr := cinfo^.script_space; + + cinfo^.scan_info := scanptr; + cinfo^.num_scans := nscans; + + if (ncomps = 3) and (cinfo^.jpeg_color_space = JCS_YCbCr) then + begin + { Custom script for YCbCr color images. } + { Initial DC scan } + scanptr := fill_dc_scans(scanptr, ncomps, 0, 1); + { Initial AC scan: get some luma data out in a hurry } + scanptr := fill_a_scan(scanptr, 0, 1, 5, 0, 2); + { Chroma data is too small to be worth expending many scans on } + scanptr := fill_a_scan(scanptr, 2, 1, 63, 0, 1); + scanptr := fill_a_scan(scanptr, 1, 1, 63, 0, 1); + { Complete spectral selection for luma AC } + scanptr := fill_a_scan(scanptr, 0, 6, 63, 0, 2); + { Refine next bit of luma AC } + scanptr := fill_a_scan(scanptr, 0, 1, 63, 2, 1); + { Finish DC successive approximation } + scanptr := fill_dc_scans(scanptr, ncomps, 1, 0); + { Finish AC successive approximation } + scanptr := fill_a_scan(scanptr, 2, 1, 63, 1, 0); + scanptr := fill_a_scan(scanptr, 1, 1, 63, 1, 0); + { Luma bottom bit comes last since it's usually largest scan } + scanptr := fill_a_scan(scanptr, 0, 1, 63, 1, 0); + end + else + begin + { All-purpose script for other color spaces. } + { Successive approximation first pass } + scanptr := fill_dc_scans(scanptr, ncomps, 0, 1); + scanptr := fill_scans(scanptr, ncomps, 1, 5, 0, 2); + scanptr := fill_scans(scanptr, ncomps, 6, 63, 0, 2); + { Successive approximation second pass } + scanptr := fill_scans(scanptr, ncomps, 1, 63, 2, 1); + { Successive approximation final pass } + scanptr := fill_dc_scans(scanptr, ncomps, 1, 0); + scanptr := fill_scans(scanptr, ncomps, 1, 63, 1, 0); + end; +end; + +{$endif} +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcphuff_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcphuff_del.pas new file mode 100644 index 0000000..f816608 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcphuff_del.pas @@ -0,0 +1,962 @@ +Unit jcphuff_del; + +{ This file contains Huffman entropy encoding routines for progressive JPEG. + + We do not support output suspension in this module, since the library + currently does not allow multiple-scan files to be written with output + suspension. } + +{ Original: jcphuff.c; Copyright (C) 1995-1997, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdeferr_del, + jerror_del, + jutils_del, + jcomapi_del, + jchuff_del; { Declarations shared with jchuff.c } + + +{ Module initialization routine for progressive Huffman entropy encoding. } + +{GLOBAL} +procedure jinit_phuff_encoder (cinfo : j_compress_ptr); + +implementation + +{ Expanded entropy encoder object for progressive Huffman encoding. } +type + phuff_entropy_ptr = ^phuff_entropy_encoder; + phuff_entropy_encoder = record + pub : jpeg_entropy_encoder; { public fields } + + { Mode flag: TRUE for optimization, FALSE for actual data output } + gather_statistics : boolean; + + { Bit-level coding status. + next_output_byte/free_in_buffer are local copies of cinfo^.dest fields.} + + next_output_byte : JOCTETptr; { => next byte to write in buffer } + free_in_buffer : size_t; { # of byte spaces remaining in buffer } + put_buffer : INT32; { current bit-accumulation buffer } + put_bits : int; { # of bits now in it } + cinfo : j_compress_ptr; { link to cinfo (needed for dump_buffer) } + + { Coding status for DC components } + last_dc_val : array[0..MAX_COMPS_IN_SCAN-1] of int; + { last DC coef for each component } + + { Coding status for AC components } + ac_tbl_no : int; { the table number of the single component } + EOBRUN : uInt; { run length of EOBs } + BE : uInt; { # of buffered correction bits before MCU } + bit_buffer : JBytePtr; { buffer for correction bits (1 per char) } + { packing correction bits tightly would save some space but cost time... } + + restarts_to_go : uInt; { MCUs left in this restart interval } + next_restart_num : int; { next restart number to write (0-7) } + + { Pointers to derived tables (these workspaces have image lifespan). + Since any one scan codes only DC or only AC, we only need one set + of tables, not one for DC and one for AC. } + + derived_tbls : array[0..NUM_HUFF_TBLS-1] of c_derived_tbl_ptr; + + { Statistics tables for optimization; again, one set is enough } + count_ptrs : array[0..NUM_HUFF_TBLS-1] of TLongTablePtr; + end; + + +{ MAX_CORR_BITS is the number of bits the AC refinement correction-bit + buffer can hold. Larger sizes may slightly improve compression, but + 1000 is already well into the realm of overkill. + The minimum safe size is 64 bits. } + +const + MAX_CORR_BITS = 1000; { Max # of correction bits I can buffer } + + +{ Forward declarations } +{METHODDEF} +function encode_mcu_DC_first (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function encode_mcu_AC_first (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function encode_mcu_DC_refine (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function encode_mcu_AC_refine (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + forward; + +{METHODDEF} +procedure finish_pass_phuff (cinfo : j_compress_ptr); forward; + +{METHODDEF} +procedure finish_pass_gather_phuff (cinfo : j_compress_ptr); forward; + + +{ Initialize for a Huffman-compressed scan using progressive JPEG. } + +{METHODDEF} +procedure start_pass_phuff (cinfo : j_compress_ptr; + gather_statistics : boolean); +var + entropy : phuff_entropy_ptr; + is_DC_band : boolean; + ci, tbl : int; + compptr : jpeg_component_info_ptr; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + + entropy^.cinfo := cinfo; + entropy^.gather_statistics := gather_statistics; + + is_DC_band := (cinfo^.Ss = 0); + + { We assume jcmaster.c already validated the scan parameters. } + + { Select execution routines } + if (cinfo^.Ah = 0) then + begin + if (is_DC_band) then + entropy^.pub.encode_mcu := encode_mcu_DC_first + else + entropy^.pub.encode_mcu := encode_mcu_AC_first; + end + else + begin + if (is_DC_band) then + entropy^.pub.encode_mcu := encode_mcu_DC_refine + else + begin + entropy^.pub.encode_mcu := encode_mcu_AC_refine; + { AC refinement needs a correction bit buffer } + if (entropy^.bit_buffer = NIL) then + entropy^.bit_buffer := JBytePtr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + MAX_CORR_BITS * SIZEOF(byte)) ); + end; + end; + if (gather_statistics) then + entropy^.pub.finish_pass := finish_pass_gather_phuff + else + entropy^.pub.finish_pass := finish_pass_phuff; + + { Only DC coefficients may be interleaved, so cinfo^.comps_in_scan = 1 + for AC coefficients. } + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { Initialize DC predictions to 0 } + entropy^.last_dc_val[ci] := 0; + { Get table index } + if (is_DC_band) then + begin + if (cinfo^.Ah <> 0) then { DC refinement needs no table } + continue; + tbl := compptr^.dc_tbl_no; + end + else + begin + tbl := compptr^.ac_tbl_no; + entropy^.ac_tbl_no := tbl; + end; + if (gather_statistics) then + begin + { Check for invalid table index } + { (make_c_derived_tbl does this in the other path) } + if (tbl < 0) or (tbl >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, tbl); + { Allocate and zero the statistics tables } + { Note that jpeg_gen_optimal_table expects 257 entries in each table! } + if (entropy^.count_ptrs[tbl] = NIL) then + entropy^.count_ptrs[tbl] := TLongTablePtr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + 257 * SIZEOF(long)) ); + MEMZERO(entropy^.count_ptrs[tbl], 257 * SIZEOF(long)); + end else + begin + { Compute derived values for Huffman table } + { We may do this more than once for a table, but it's not expensive } + jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl, + entropy^.derived_tbls[tbl]); + end; + end; + + { Initialize AC stuff } + entropy^.EOBRUN := 0; + entropy^.BE := 0; + + { Initialize bit buffer to empty } + entropy^.put_buffer := 0; + entropy^.put_bits := 0; + + { Initialize restart stuff } + entropy^.restarts_to_go := cinfo^.restart_interval; + entropy^.next_restart_num := 0; +end; + + + + +{LOCAL} +procedure dump_buffer (entropy : phuff_entropy_ptr); +{ Empty the output buffer; we do not support suspension in this module. } +var + dest : jpeg_destination_mgr_ptr; +begin + dest := entropy^.cinfo^.dest; + + if (not dest^.empty_output_buffer (entropy^.cinfo)) then + ERREXIT(j_common_ptr(entropy^.cinfo), JERR_CANT_SUSPEND); + { After a successful buffer dump, must reset buffer pointers } + entropy^.next_output_byte := dest^.next_output_byte; + entropy^.free_in_buffer := dest^.free_in_buffer; +end; + + +{ Outputting bits to the file } + +{ Only the right 24 bits of put_buffer are used; the valid bits are + left-justified in this part. At most 16 bits can be passed to emit_bits + in one call, and we never retain more than 7 bits in put_buffer + between calls, so 24 bits are sufficient. } + + +{LOCAL} +procedure emit_bits (entropy : phuff_entropy_ptr; + code : uInt; + size : int); {INLINE} +{ Emit some bits, unless we are in gather mode } +var + {register} put_buffer : INT32; + {register} put_bits : int; +var + c : int; +begin + { This routine is heavily used, so it's worth coding tightly. } + put_buffer := INT32 (code); + put_bits := entropy^.put_bits; + + { if size is 0, caller used an invalid Huffman table entry } + if (size = 0) then + ERREXIT(j_common_ptr(entropy^.cinfo), JERR_HUFF_MISSING_CODE); + + if (entropy^.gather_statistics) then + exit; { do nothing if we're only getting stats } + + put_buffer := put_buffer and ((INT32(1) shl size) - 1); + { mask off any extra bits in code } + + Inc(put_bits, size); { new number of bits in buffer } + + put_buffer := put_buffer shl (24 - put_bits); { align incoming bits } + + put_buffer := put_buffer or entropy^.put_buffer; + { and merge with old buffer contents } + + while (put_bits >= 8) do + begin + c := int ((put_buffer shr 16) and $FF); + + {emit_byte(entropy, c);} + { Outputting bytes to the file. + NB: these must be called only when actually outputting, + that is, entropy^.gather_statistics = FALSE. } + { Emit a byte } + entropy^.next_output_byte^ := JOCTET(c); + Inc(entropy^.next_output_byte); + Dec(entropy^.free_in_buffer); + if (entropy^.free_in_buffer = 0) then + dump_buffer(entropy); + + if (c = $FF) then + begin { need to stuff a zero byte? } + {emit_byte(entropy, 0);} + entropy^.next_output_byte^ := JOCTET(0); + Inc(entropy^.next_output_byte); + Dec(entropy^.free_in_buffer); + if (entropy^.free_in_buffer = 0) then + dump_buffer(entropy); + end; + put_buffer := put_buffer shl 8; + Dec(put_bits, 8); + end; + + entropy^.put_buffer := put_buffer; { update variables } + entropy^.put_bits := put_bits; +end; + + +{LOCAL} +procedure flush_bits (entropy : phuff_entropy_ptr); +begin + emit_bits(entropy, $7F, 7); { fill any partial byte with ones } + entropy^.put_buffer := 0; { and reset bit-buffer to empty } + entropy^.put_bits := 0; +end; + +{ Emit (or just count) a Huffman symbol. } + + +{LOCAL} +procedure emit_symbol (entropy : phuff_entropy_ptr; + tbl_no : int; + symbol : int); {INLINE} +var + tbl : c_derived_tbl_ptr; +begin + if (entropy^.gather_statistics) then + Inc(entropy^.count_ptrs[tbl_no]^[symbol]) + else + begin + tbl := entropy^.derived_tbls[tbl_no]; + emit_bits(entropy, tbl^.ehufco[symbol], tbl^.ehufsi[symbol]); + end; +end; + + +{ Emit bits from a correction bit buffer. } + +{LOCAL} +procedure emit_buffered_bits (entropy : phuff_entropy_ptr; + bufstart : JBytePtr; + nbits : uInt); +var + bufptr : byteptr; +begin + if (entropy^.gather_statistics) then + exit; { no real work } + + bufptr := byteptr(bufstart); + while (nbits > 0) do + begin + emit_bits(entropy, uInt(bufptr^), 1); + Inc(bufptr); + Dec(nbits); + end; +end; + + +{ Emit any pending EOBRUN symbol. } + +{LOCAL} +procedure emit_eobrun (entropy : phuff_entropy_ptr); +var + {register} temp, nbits : int; +begin + if (entropy^.EOBRUN > 0) then + begin { if there is any pending EOBRUN } + temp := entropy^.EOBRUN; + nbits := 0; + temp := temp shr 1; + while (temp <> 0) do + begin + Inc(nbits); + temp := temp shr 1; + end; + + { safety check: shouldn't happen given limited correction-bit buffer } + if (nbits > 14) then + ERREXIT(j_common_ptr(entropy^.cinfo), JERR_HUFF_MISSING_CODE); + + emit_symbol(entropy, entropy^.ac_tbl_no, nbits shl 4); + if (nbits <> 0) then + emit_bits(entropy, entropy^.EOBRUN, nbits); + + entropy^.EOBRUN := 0; + + { Emit any buffered correction bits } + emit_buffered_bits(entropy, entropy^.bit_buffer, entropy^.BE); + entropy^.BE := 0; + end; +end; + + +{ Emit a restart marker & resynchronize predictions. } + +{LOCAL} +procedure emit_restart (entropy : phuff_entropy_ptr; + restart_num : int); +var + ci : int; +begin + emit_eobrun(entropy); + + if (not entropy^.gather_statistics) then + begin + flush_bits(entropy); + {emit_byte(entropy, $FF);} + { Outputting bytes to the file. + NB: these must be called only when actually outputting, + that is, entropy^.gather_statistics = FALSE. } + + entropy^.next_output_byte^ := JOCTET($FF); + Inc(entropy^.next_output_byte); + Dec(entropy^.free_in_buffer); + if (entropy^.free_in_buffer = 0) then + dump_buffer(entropy); + + {emit_byte(entropy, JPEG_RST0 + restart_num);} + entropy^.next_output_byte^ := JOCTET(JPEG_RST0 + restart_num); + Inc(entropy^.next_output_byte); + Dec(entropy^.free_in_buffer); + if (entropy^.free_in_buffer = 0) then + dump_buffer(entropy); + end; + + if (entropy^.cinfo^.Ss = 0) then + begin + { Re-initialize DC predictions to 0 } + for ci := 0 to pred(entropy^.cinfo^.comps_in_scan) do + entropy^.last_dc_val[ci] := 0; + end + else + begin + { Re-initialize all AC-related fields to 0 } + entropy^.EOBRUN := 0; + entropy^.BE := 0; + end; +end; + + +{ MCU encoding for DC initial scan (either spectral selection, + or first pass of successive approximation). } + +{METHODDEF} +function encode_mcu_DC_first (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; +var + entropy : phuff_entropy_ptr; + {register} temp, temp2 : int; + {register} nbits : int; + blkn, ci : int; + Al : int; + block : JBLOCK_PTR; + compptr : jpeg_component_info_ptr; + ishift_temp : int; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Al := cinfo^.Al; + + entropy^.next_output_byte := cinfo^.dest^.next_output_byte; + entropy^.free_in_buffer := cinfo^.dest^.free_in_buffer; + + { Emit restart marker if needed } + if (cinfo^.restart_interval <> 0) then + if (entropy^.restarts_to_go = 0) then + emit_restart(entropy, entropy^.next_restart_num); + + { Encode the MCU data blocks } + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + block := JBLOCK_PTR(MCU_data[blkn]); + ci := cinfo^.MCU_membership[blkn]; + compptr := cinfo^.cur_comp_info[ci]; + + { Compute the DC value after the required point transform by Al. + This is simply an arithmetic right shift. } + + {temp2 := IRIGHT_SHIFT( int(block^[0]), Al);} + {IRIGHT_SHIFT_IS_UNSIGNED} + ishift_temp := int(block^[0]); + if ishift_temp < 0 then + temp2 := (ishift_temp shr Al) or ((not 0) shl (16-Al)) + else + temp2 := ishift_temp shr Al; + + + { DC differences are figured on the point-transformed values. } + temp := temp2 - entropy^.last_dc_val[ci]; + entropy^.last_dc_val[ci] := temp2; + + { Encode the DC coefficient difference per section G.1.2.1 } + temp2 := temp; + if (temp < 0) then + begin + temp := -temp; { temp is abs value of input } + { For a negative input, want temp2 := bitwise complement of abs(input) } + { This code assumes we are on a two's complement machine } + Dec(temp2); + end; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; + while (temp <> 0) do + begin + Inc(nbits); + temp := temp shr 1; + end; + + { Check for out-of-range coefficient values. + Since we're encoding a difference, the range limit is twice as much. } + + if (nbits > MAX_COEF_BITS+1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_DCT_COEF); + + { Count/emit the Huffman-coded symbol for the number of bits } + emit_symbol(entropy, compptr^.dc_tbl_no, nbits); + + { Emit that number of bits of the value, if positive, } + { or the complement of its magnitude, if negative. } + if (nbits <> 0) then { emit_bits rejects calls with size 0 } + emit_bits(entropy, uInt(temp2), nbits); + end; + + cinfo^.dest^.next_output_byte := entropy^.next_output_byte; + cinfo^.dest^.free_in_buffer := entropy^.free_in_buffer; + + { Update restart-interval state too } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + entropy^.restarts_to_go := cinfo^.restart_interval; + Inc(entropy^.next_restart_num); + with entropy^ do + next_restart_num := next_restart_num and 7; + end; + Dec(entropy^.restarts_to_go); + end; + + encode_mcu_DC_first := TRUE; +end; + + +{ MCU encoding for AC initial scan (either spectral selection, + or first pass of successive approximation). } + +{METHODDEF} +function encode_mcu_AC_first (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; +var + entropy : phuff_entropy_ptr; + {register} temp, temp2 : int; + {register} nbits : int; + {register} r, k : int; + Se : int; + Al : int; + block : JBLOCK_PTR; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Se := cinfo^.Se; + Al := cinfo^.Al; + + entropy^.next_output_byte := cinfo^.dest^.next_output_byte; + entropy^.free_in_buffer := cinfo^.dest^.free_in_buffer; + + { Emit restart marker if needed } + if (cinfo^.restart_interval <> 0) then + if (entropy^.restarts_to_go = 0) then + emit_restart(entropy, entropy^.next_restart_num); + + { Encode the MCU data block } + block := JBLOCK_PTR(MCU_data[0]); + + { Encode the AC coefficients per section G.1.2.2, fig. G.3 } + + r := 0; { r := run length of zeros } + + for k := cinfo^.Ss to Se do + begin + temp := (block^[jpeg_natural_order[k]]); + if (temp = 0) then + begin + Inc(r); + continue; + end; + { We must apply the point transform by Al. For AC coefficients this + is an integer division with rounding towards 0. To do this portably + in C, we shift after obtaining the absolute value; so the code is + interwoven with finding the abs value (temp) and output bits (temp2). } + + if (temp < 0) then + begin + temp := -temp; { temp is abs value of input } + temp := temp shr Al; { apply the point transform } + { For a negative coef, want temp2 := bitwise complement of abs(coef) } + temp2 := not temp; + end + else + begin + temp := temp shr Al; { apply the point transform } + temp2 := temp; + end; + { Watch out for case that nonzero coef is zero after point transform } + if (temp = 0) then + begin + Inc(r); + continue; + end; + + { Emit any pending EOBRUN } + if (entropy^.EOBRUN > 0) then + emit_eobrun(entropy); + { if run length > 15, must emit special run-length-16 codes ($F0) } + while (r > 15) do + begin + emit_symbol(entropy, entropy^.ac_tbl_no, $F0); + Dec(r, 16); + end; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; { there must be at least one 1 bit } + repeat + Inc(nbits); + temp := temp shr 1; + until (temp = 0); + + { Check for out-of-range coefficient values } + if (nbits > MAX_COEF_BITS) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_DCT_COEF); + + { Count/emit Huffman symbol for run length / number of bits } + emit_symbol(entropy, entropy^.ac_tbl_no, (r shl 4) + nbits); + + { Emit that number of bits of the value, if positive, } + { or the complement of its magnitude, if negative. } + emit_bits(entropy, uInt(temp2), nbits); + + r := 0; { reset zero run length } + end; + + if (r > 0) then + begin { If there are trailing zeroes, } + Inc(entropy^.EOBRUN); { count an EOB } + if (entropy^.EOBRUN = $7FFF) then + emit_eobrun(entropy); { force it out to avoid overflow } + end; + + cinfo^.dest^.next_output_byte := entropy^.next_output_byte; + cinfo^.dest^.free_in_buffer := entropy^.free_in_buffer; + + { Update restart-interval state too } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + entropy^.restarts_to_go := cinfo^.restart_interval; + Inc(entropy^.next_restart_num); + with entropy^ do + next_restart_num := next_restart_num and 7; + end; + Dec(entropy^.restarts_to_go); + end; + + encode_mcu_AC_first := TRUE; +end; + + +{ MCU encoding for DC successive approximation refinement scan. + Note: we assume such scans can be multi-component, although the spec + is not very clear on the point. } + +{METHODDEF} +function encode_mcu_DC_refine (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; +var + entropy : phuff_entropy_ptr; + {register} temp : int; + blkn : int; + Al : int; + block : JBLOCK_PTR; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Al := cinfo^.Al; + + entropy^.next_output_byte := cinfo^.dest^.next_output_byte; + entropy^.free_in_buffer := cinfo^.dest^.free_in_buffer; + + { Emit restart marker if needed } + if (cinfo^.restart_interval <> 0) then + if (entropy^.restarts_to_go = 0) then + emit_restart(entropy, entropy^.next_restart_num); + + { Encode the MCU data blocks } + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + block := JBLOCK_PTR(MCU_data[blkn]); + + { We simply emit the Al'th bit of the DC coefficient value. } + temp := block^[0]; + emit_bits(entropy, uInt(temp shr Al), 1); + end; + + cinfo^.dest^.next_output_byte := entropy^.next_output_byte; + cinfo^.dest^.free_in_buffer := entropy^.free_in_buffer; + + { Update restart-interval state too } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + entropy^.restarts_to_go := cinfo^.restart_interval; + Inc(entropy^.next_restart_num); + with entropy^ do + next_restart_num := next_restart_num and 7; + end; + Dec(entropy^.restarts_to_go); + end; + + encode_mcu_DC_refine := TRUE; +end; + + +{ MCU encoding for AC successive approximation refinement scan. } + +{METHODDEF} +function encode_mcu_AC_refine (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + +var + entropy : phuff_entropy_ptr; + {register} temp : int; + {register} r, k : int; + EOB : int; + BR_buffer : JBytePtr; + BR : uInt; + Se : int; + Al : int; + block : JBLOCK_PTR; + absvalues : array[0..DCTSIZE2-1] of int; +begin + entropy := phuff_entropy_ptr(cinfo^.entropy); + Se := cinfo^.Se; + Al := cinfo^.Al; + + entropy^.next_output_byte := cinfo^.dest^.next_output_byte; + entropy^.free_in_buffer := cinfo^.dest^.free_in_buffer; + + { Emit restart marker if needed } + if (cinfo^.restart_interval <> 0) then + if (entropy^.restarts_to_go = 0) then + emit_restart(entropy, entropy^.next_restart_num); + + { Encode the MCU data block } + block := JBLOCK_PTR(MCU_data[0]); + + { It is convenient to make a pre-pass to determine the transformed + coefficients' absolute values and the EOB position. } + + EOB := 0; + for k := cinfo^.Ss to Se do + begin + temp := block^[jpeg_natural_order[k]]; + { We must apply the point transform by Al. For AC coefficients this + is an integer division with rounding towards 0. To do this portably + in C, we shift after obtaining the absolute value. } + + if (temp < 0) then + temp := -temp; { temp is abs value of input } + temp := temp shr Al; { apply the point transform } + absvalues[k] := temp; { save abs value for main pass } + if (temp = 1) then + EOB := k; { EOB := index of last newly-nonzero coef } + end; + + { Encode the AC coefficients per section G.1.2.3, fig. G.7 } + + r := 0; { r := run length of zeros } + BR := 0; { BR := count of buffered bits added now } + BR_buffer := JBytePtr(@(entropy^.bit_buffer^[entropy^.BE])); + { Append bits to buffer } + + for k := cinfo^.Ss to Se do + begin + temp := absvalues[k]; + if (temp = 0) then + begin + Inc(r); + continue; + end; + + { Emit any required ZRLs, but not if they can be folded into EOB } + while (r > 15) and (k <= EOB) do + begin + { emit any pending EOBRUN and the BE correction bits } + emit_eobrun(entropy); + { Emit ZRL } + emit_symbol(entropy, entropy^.ac_tbl_no, $F0); + Dec(r, 16); + { Emit buffered correction bits that must be associated with ZRL } + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer := entropy^.bit_buffer; { BE bits are gone now } + BR := 0; + end; + + { If the coef was previously nonzero, it only needs a correction bit. + NOTE: a straight translation of the spec's figure G.7 would suggest + that we also need to test r > 15. But if r > 15, we can only get here + if k > EOB, which implies that this coefficient is not 1. } + if (temp > 1) then + begin + { The correction bit is the next bit of the absolute value. } + BR_buffer^[BR] := byte (temp and 1); + Inc(BR); + continue; + end; + + { Emit any pending EOBRUN and the BE correction bits } + emit_eobrun(entropy); + + { Count/emit Huffman symbol for run length / number of bits } + emit_symbol(entropy, entropy^.ac_tbl_no, (r shl 4) + 1); + + { Emit output bit for newly-nonzero coef } + if (block^[jpeg_natural_order[k]] < 0) then + temp := 0 + else + temp := 1; + emit_bits(entropy, uInt(temp), 1); + + { Emit buffered correction bits that must be associated with this code } + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer := entropy^.bit_buffer; { BE bits are gone now } + BR := 0; + r := 0; { reset zero run length } + end; + + if (r > 0) or (BR > 0) then + begin { If there are trailing zeroes, } + Inc(entropy^.EOBRUN); { count an EOB } + Inc(entropy^.BE, BR); { concat my correction bits to older ones } + { We force out the EOB if we risk either: + 1. overflow of the EOB counter; + 2. overflow of the correction bit buffer during the next MCU. } + + if (entropy^.EOBRUN = $7FFF) or + (entropy^.BE > (MAX_CORR_BITS-DCTSIZE2+1)) then + emit_eobrun(entropy); + end; + + cinfo^.dest^.next_output_byte := entropy^.next_output_byte; + cinfo^.dest^.free_in_buffer := entropy^.free_in_buffer; + + { Update restart-interval state too } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + entropy^.restarts_to_go := cinfo^.restart_interval; + Inc(entropy^.next_restart_num); + with entropy^ do + next_restart_num := next_restart_num and 7; + end; + Dec(entropy^.restarts_to_go); + end; + + encode_mcu_AC_refine := TRUE; +end; + + +{ Finish up at the end of a Huffman-compressed progressive scan. } + +{METHODDEF} +procedure finish_pass_phuff (cinfo : j_compress_ptr); +var + entropy : phuff_entropy_ptr; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + + entropy^.next_output_byte := cinfo^.dest^.next_output_byte; + entropy^.free_in_buffer := cinfo^.dest^.free_in_buffer; + + { Flush out any buffered data } + emit_eobrun(entropy); + flush_bits(entropy); + + cinfo^.dest^.next_output_byte := entropy^.next_output_byte; + cinfo^.dest^.free_in_buffer := entropy^.free_in_buffer; +end; + + +{ Finish up a statistics-gathering pass and create the new Huffman tables. } + +{METHODDEF} +procedure finish_pass_gather_phuff (cinfo : j_compress_ptr); +var + entropy : phuff_entropy_ptr; + is_DC_band : boolean; + ci, tbl : int; + compptr : jpeg_component_info_ptr; + htblptr : ^JHUFF_TBL_PTR; + did : array[0..NUM_HUFF_TBLS-1] of boolean; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + + { Flush out buffered data (all we care about is counting the EOB symbol) } + emit_eobrun(entropy); + + is_DC_band := (cinfo^.Ss = 0); + + { It's important not to apply jpeg_gen_optimal_table more than once + per table, because it clobbers the input frequency counts! } + + MEMZERO(@did, SIZEOF(did)); + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + if (is_DC_band) then + begin + if (cinfo^.Ah <> 0) then { DC refinement needs no table } + continue; + tbl := compptr^.dc_tbl_no; + end + else + begin + tbl := compptr^.ac_tbl_no; + end; + if (not did[tbl]) then + begin + if (is_DC_band) then + htblptr := @(cinfo^.dc_huff_tbl_ptrs[tbl]) + else + htblptr := @(cinfo^.ac_huff_tbl_ptrs[tbl]); + if (htblptr^ = NIL) then + htblptr^ := jpeg_alloc_huff_table(j_common_ptr(cinfo)); + jpeg_gen_optimal_table(cinfo, htblptr^, entropy^.count_ptrs[tbl]^); + did[tbl] := TRUE; + end; + end; +end; + + +{ Module initialization routine for progressive Huffman entropy encoding. } + +{GLOBAL} +procedure jinit_phuff_encoder (cinfo : j_compress_ptr); +var + entropy : phuff_entropy_ptr; + i : int; +begin + entropy := phuff_entropy_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(phuff_entropy_encoder)) ); + cinfo^.entropy := jpeg_entropy_encoder_ptr(entropy); + entropy^.pub.start_pass := start_pass_phuff; + + { Mark tables unallocated } + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + entropy^.derived_tbls[i] := NIL; + entropy^.count_ptrs[i] := NIL; + end; + entropy^.bit_buffer := NIL; { needed only in AC refinement scan } +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcprepct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcprepct_del.pas new file mode 100644 index 0000000..67ec625 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcprepct_del.pas @@ -0,0 +1,408 @@ +Unit jcprepct_del; + +{ Original : jcprepct.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +{ This file contains the compression preprocessing controller. + This controller manages the color conversion, downsampling, + and edge expansion steps. + + Most of the complexity here is associated with buffering input rows + as required by the downsampler. See the comments at the head of + jcsample.c for the downsampler's needs. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jpeglib_del, + jdeferr_del, + jerror_del, + jinclude_del, + jutils_del; + +{GLOBAL} +procedure jinit_c_prep_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); + +implementation + + +{ At present, jcsample.c can request context rows only for smoothing. + In the future, we might also need context rows for CCIR601 sampling + or other more-complex downsampling procedures. The code to support + context rows should be compiled only if needed. } + +{$ifdef INPUT_SMOOTHING_SUPPORTED} + {$define CONTEXT_ROWS_SUPPORTED} +{$endif} + + +{ For the simple (no-context-row) case, we just need to buffer one + row group's worth of pixels for the downsampling step. At the bottom of + the image, we pad to a full row group by replicating the last pixel row. + The downsampler's last output row is then replicated if needed to pad + out to a full iMCU row. + + When providing context rows, we must buffer three row groups' worth of + pixels. Three row groups are physically allocated, but the row pointer + arrays are made five row groups high, with the extra pointers above and + below "wrapping around" to point to the last and first real row groups. + This allows the downsampler to access the proper context rows. + At the top and bottom of the image, we create dummy context rows by + copying the first or last real pixel row. This copying could be avoided + by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the + trouble on the compression side. } + + +{ Private buffer controller object } + +type + my_prep_ptr = ^my_prep_controller; + my_prep_controller = record + pub : jpeg_c_prep_controller; { public fields } + + { Downsampling input buffer. This buffer holds color-converted data + until we have enough to do a downsample step. } + + color_buf : array[0..MAX_COMPONENTS-1] of JSAMPARRAY; + + rows_to_go : JDIMENSION; { counts rows remaining in source image } + next_buf_row : int; { index of next row to store in color_buf } + + {$ifdef CONTEXT_ROWS_SUPPORTED} { only needed for context case } + this_row_group : int; { starting row index of group to process } + next_buf_stop : int; { downsample when we reach this index } + {$endif} + end; {my_prep_controller;} + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_prep (cinfo : j_compress_ptr; + pass_mode : J_BUF_MODE ); +var + prep : my_prep_ptr; +begin + prep := my_prep_ptr (cinfo^.prep); + + if (pass_mode <> JBUF_PASS_THRU) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + + { Initialize total-height counter for detecting bottom of image } + prep^.rows_to_go := cinfo^.image_height; + { Mark the conversion buffer empty } + prep^.next_buf_row := 0; +{$ifdef CONTEXT_ROWS_SUPPORTED} + { Preset additional state variables for context mode. + These aren't used in non-context mode, so we needn't test which mode. } + prep^.this_row_group := 0; + { Set next_buf_stop to stop after two row groups have been read in. } + prep^.next_buf_stop := 2 * cinfo^.max_v_samp_factor; +{$endif} +end; + + +{ Expand an image vertically from height input_rows to height output_rows, + by duplicating the bottom row. } + +{LOCAL} +procedure expand_bottom_edge (image_data : JSAMPARRAY; + num_cols : JDIMENSION; + input_rows : int; + output_rows : int); +var + {register} row : int; +begin + for row := input_rows to pred(output_rows) do + begin + jcopy_sample_rows(image_data, input_rows-1, image_data, row, + 1, num_cols); + end; +end; + + +{ Process some data in the simple no-context case. + + Preprocessor output data is counted in "row groups". A row group + is defined to be v_samp_factor sample rows of each component. + Downsampling will produce this much data from each max_v_samp_factor + input rows. } + +{METHODDEF} +procedure pre_process_data (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION; + output_buf : JSAMPIMAGE; + var out_row_group_ctr : JDIMENSION; + out_row_groups_avail : JDIMENSION); +var + prep : my_prep_ptr; + numrows, ci : int; + inrows : JDIMENSION; + compptr : jpeg_component_info_ptr; +var + local_input_buf : JSAMPARRAY; +begin + prep := my_prep_ptr (cinfo^.prep); + + while (in_row_ctr < in_rows_avail) and + (out_row_group_ctr < out_row_groups_avail) do + begin + { Do color conversion to fill the conversion buffer. } + inrows := in_rows_avail - in_row_ctr; + numrows := cinfo^.max_v_samp_factor - prep^.next_buf_row; + {numrows := int( MIN(JDIMENSION(numrows), inrows) );} + if inrows < JDIMENSION(numrows) then + numrows := int(inrows); + local_input_buf := JSAMPARRAY(@(input_buf^[in_row_ctr])); + cinfo^.cconvert^.color_convert (cinfo, local_input_buf, + JSAMPIMAGE(@prep^.color_buf), + JDIMENSION(prep^.next_buf_row), + numrows); + Inc(in_row_ctr, numrows); + Inc(prep^.next_buf_row, numrows); + Dec(prep^.rows_to_go, numrows); + { If at bottom of image, pad to fill the conversion buffer. } + if (prep^.rows_to_go = 0) and + (prep^.next_buf_row < cinfo^.max_v_samp_factor) then + begin + for ci := 0 to pred(cinfo^.num_components) do + begin + expand_bottom_edge(prep^.color_buf[ci], cinfo^.image_width, + prep^.next_buf_row, cinfo^.max_v_samp_factor); + end; + prep^.next_buf_row := cinfo^.max_v_samp_factor; + end; + { If we've filled the conversion buffer, empty it. } + if (prep^.next_buf_row = cinfo^.max_v_samp_factor) then + begin + cinfo^.downsample^.downsample (cinfo, + JSAMPIMAGE(@prep^.color_buf), + JDIMENSION (0), + output_buf, + out_row_group_ctr); + prep^.next_buf_row := 0; + Inc(out_row_group_ctr);; + end; + { If at bottom of image, pad the output to a full iMCU height. + Note we assume the caller is providing a one-iMCU-height output buffer! } + if (prep^.rows_to_go = 0) and + (out_row_group_ctr < out_row_groups_avail) then + begin + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + expand_bottom_edge(output_buf^[ci], + compptr^.width_in_blocks * DCTSIZE, + int (out_row_group_ctr * compptr^.v_samp_factor), + int (out_row_groups_avail * compptr^.v_samp_factor)); + Inc(compptr); + end; + out_row_group_ctr := out_row_groups_avail; + break; { can exit outer loop without test } + end; + end; +end; + + +{$ifdef CONTEXT_ROWS_SUPPORTED} + +{ Process some data in the context case. } + +{METHODDEF} +procedure pre_process_context (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION; + output_buf : JSAMPIMAGE; + var out_row_group_ctr : JDIMENSION; + out_row_groups_avail : JDIMENSION); +var + prep : my_prep_ptr; + numrows, ci : int; + buf_height : int; + inrows : JDIMENSION; +var + row : int; + +begin + prep := my_prep_ptr (cinfo^.prep); + buf_height := cinfo^.max_v_samp_factor * 3; + + while (out_row_group_ctr < out_row_groups_avail) do + begin + if (in_row_ctr < in_rows_avail) then + begin + { Do color conversion to fill the conversion buffer. } + inrows := in_rows_avail - in_row_ctr; + numrows := prep^.next_buf_stop - prep^.next_buf_row; + {numrows := int ( MIN( JDIMENSION(numrows), inrows) );} + if inrows < JDIMENSION(numrows) then + numrows := int(inrows); + cinfo^.cconvert^.color_convert (cinfo, + JSAMPARRAY(@input_buf^[in_row_ctr]), + JSAMPIMAGE(@prep^.color_buf), + JDIMENSION (prep^.next_buf_row), + numrows); + { Pad at top of image, if first time through } + if (prep^.rows_to_go = cinfo^.image_height) then + begin + for ci := 0 to pred(cinfo^.num_components) do + begin + for row := 1 to cinfo^.max_v_samp_factor do + begin + jcopy_sample_rows(prep^.color_buf[ci], 0, + prep^.color_buf[ci], -row, + 1, cinfo^.image_width); + end; + end; + end; + Inc(in_row_ctr, numrows); + Inc(prep^.next_buf_row, numrows); + Dec(prep^.rows_to_go, numrows); + end + else + begin + { Return for more data, unless we are at the bottom of the image. } + if (prep^.rows_to_go <> 0) then + break; + { When at bottom of image, pad to fill the conversion buffer. } + if (prep^.next_buf_row < prep^.next_buf_stop) then + begin + for ci := 0 to pred(cinfo^.num_components) do + begin + expand_bottom_edge(prep^.color_buf[ci], cinfo^.image_width, + prep^.next_buf_row, prep^.next_buf_stop); + end; + prep^.next_buf_row := prep^.next_buf_stop; + end; + end; + { If we've gotten enough data, downsample a row group. } + if (prep^.next_buf_row = prep^.next_buf_stop) then + begin + cinfo^.downsample^.downsample (cinfo, + JSAMPIMAGE(@prep^.color_buf), + JDIMENSION(prep^.this_row_group), + output_buf, + out_row_group_ctr); + Inc(out_row_group_ctr); + { Advance pointers with wraparound as necessary. } + Inc(prep^.this_row_group, cinfo^.max_v_samp_factor); + if (prep^.this_row_group >= buf_height) then + prep^.this_row_group := 0; + if (prep^.next_buf_row >= buf_height) then + prep^.next_buf_row := 0; + prep^.next_buf_stop := prep^.next_buf_row + cinfo^.max_v_samp_factor; + end; + end; +end; + + +{ Create the wrapped-around downsampling input buffer needed for context mode. } + +{LOCAL} +procedure create_context_buffer (cinfo : j_compress_ptr); +var + prep : my_prep_ptr; + rgroup_height : int; + ci, i : int; + compptr : jpeg_component_info_ptr; + true_buffer, fake_buffer : JSAMPARRAY; +begin + prep := my_prep_ptr (cinfo^.prep); + rgroup_height := cinfo^.max_v_samp_factor; + { Grab enough space for fake row pointers for all the components; + we need five row groups' worth of pointers for each component. } + + fake_buffer := JSAMPARRAY( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + (cinfo^.num_components * 5 * rgroup_height) * + SIZEOF(JSAMPROW)) ); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Allocate the actual buffer space (3 row groups) for this component. + We make the buffer wide enough to allow the downsampler to edge-expand + horizontally within the buffer, if it so chooses. } + true_buffer := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + JDIMENSION (( long(compptr^.width_in_blocks) * DCTSIZE * + cinfo^.max_h_samp_factor) div compptr^.h_samp_factor), + JDIMENSION (3 * rgroup_height)); + { Copy true buffer row pointers into the middle of the fake row array } + MEMCOPY(JSAMPARRAY(@ fake_buffer^[rgroup_height]), true_buffer, + 3 * rgroup_height * SIZEOF(JSAMPROW)); + { Fill in the above and below wraparound pointers } + for i := 0 to pred(rgroup_height) do + begin + fake_buffer^[i] := true_buffer^[2 * rgroup_height + i]; + fake_buffer^[4 * rgroup_height + i] := true_buffer^[i]; + end; + prep^.color_buf[ci] := JSAMPARRAY(@ fake_buffer^[rgroup_height]); + Inc(JSAMPROW_PTR(fake_buffer), 5 * rgroup_height); { point to space for next component } + Inc(compptr); + end; +end; + +{$endif} { CONTEXT_ROWS_SUPPORTED } + + +{ Initialize preprocessing controller. } + +{GLOBAL} +procedure jinit_c_prep_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); +var + prep : my_prep_ptr; + ci : int; + compptr : jpeg_component_info_ptr; +begin + + if (need_full_buffer) then { safety check } + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + + prep := my_prep_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_prep_controller)) ); + cinfo^.prep := jpeg_c_prep_controller_ptr(prep); + prep^.pub.start_pass := start_pass_prep; + + { Allocate the color conversion buffer. + We make the buffer wide enough to allow the downsampler to edge-expand + horizontally within the buffer, if it so chooses. } + + if (cinfo^.downsample^.need_context_rows) then + begin + { Set up to provide context rows } +{$ifdef CONTEXT_ROWS_SUPPORTED} + prep^.pub.pre_process_data := pre_process_context; + create_context_buffer(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + { No context, just make it tall enough for one row group } + prep^.pub.pre_process_data := pre_process_data; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + prep^.color_buf[ci] := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + JDIMENSION (( long(compptr^.width_in_blocks) * DCTSIZE * + cinfo^.max_h_samp_factor) div compptr^.h_samp_factor), + JDIMENSION(cinfo^.max_v_samp_factor) ); + Inc(compptr); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcsample_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcsample_del.pas new file mode 100644 index 0000000..1ae9b6c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcsample_del.pas @@ -0,0 +1,632 @@ +Unit jcsample_del; + +{ This file contains downsampling routines. + + Downsampling input data is counted in "row groups". A row group + is defined to be max_v_samp_factor pixel rows of each component, + from which the downsampler produces v_samp_factor sample rows. + A single row group is processed in each call to the downsampler module. + + The downsampler is responsible for edge-expansion of its output data + to fill an integral number of DCT blocks horizontally. The source buffer + may be modified if it is helpful for this purpose (the source buffer is + allocated wide enough to correspond to the desired output width). + The caller (the prep controller) is responsible for vertical padding. + + The downsampler may request "context rows" by setting need_context_rows + during startup. In this case, the input arrays will contain at least + one row group's worth of pixels above and below the passed-in data; + the caller will create dummy rows at image top and bottom by replicating + the first or last real pixel row. + + An excellent reference for image resampling is + Digital Image Warping, George Wolberg, 1990. + Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + + The downsampling algorithm used here is a simple average of the source + pixels covered by the output pixel. The hi-falutin sampling literature + refers to this as a "box filter". In general the characteristics of a box + filter are not very good, but for the specific cases we normally use (1:1 + and 2:1 ratios) the box is equivalent to a "triangle filter" which is not + nearly so bad. If you intend to use other sampling ratios, you'd be well + advised to improve this code. + + A simple input-smoothing capability is provided. This is mainly intended + for cleaning up color-dithered GIF input files (if you find it inadequate, + we suggest using an external filtering program such as pnmconvol). When + enabled, each input pixel P is replaced by a weighted sum of itself and its + eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF, + where SF := (smoothing_factor / 1024). + Currently, smoothing is only supported for 2h2v sampling factors. } + +{ Original: jcsample.c ; Copyright (C) 1991-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jutils_del, + jdeferr_del, + jerror_del, + jpeglib_del; + + +{ Module initialization routine for downsampling. + Note that we must select a routine for each component. } + +{GLOBAL} +procedure jinit_downsampler (cinfo : j_compress_ptr); + +implementation + +{ Pointer to routine to downsample a single component } +type + downsample1_ptr = procedure(cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); + +{ Private subobject } + +type + my_downsample_ptr = ^my_downsampler; + my_downsampler = record + pub : jpeg_downsampler; { public fields } + + { Downsampling method pointers, one per component } + methods : array[0..MAX_COMPONENTS-1] of downsample1_ptr; + end; + +{ Initialize for a downsampling pass. } + +{METHODDEF} +procedure start_pass_downsample (cinfo : j_compress_ptr); +begin + { no work for now } +end; + + +{ Expand a component horizontally from width input_cols to width output_cols, + by duplicating the rightmost samples. } + +{LOCAL} +procedure expand_right_edge (image_data : JSAMPARRAY; + num_rows : int; + input_cols : JDIMENSION; + output_cols : JDIMENSION); +var + {register} ptr : JSAMPLE_PTR; + {register} pixval : JSAMPLE; + {register} count : int; + row : int; + numcols : int; +begin + numcols := int (output_cols - input_cols); + + if (numcols > 0) then + begin + for row := 0 to pred(num_rows) do + begin + ptr := JSAMPLE_PTR(@(image_data^[row]^[input_cols-1])); + pixval := ptr^; { don't need GETJSAMPLE() here } + for count := pred(numcols) downto 0 do + begin + Inc(ptr); + ptr^ := pixval; + end; + end; + end; +end; + + +{ Do downsampling for a whole row group (all components). + + In this version we simply downsample each component independently. } + +{METHODDEF} +procedure sep_downsample (cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE; + in_row_index : JDIMENSION; + output_buf : JSAMPIMAGE; + out_row_group_index : JDIMENSION); +var + downsample : my_downsample_ptr; + ci : int; + compptr : jpeg_component_info_ptr; + in_ptr, out_ptr : JSAMPARRAY; +begin + downsample := my_downsample_ptr (cinfo^.downsample); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + in_ptr := JSAMPARRAY(@ input_buf^[ci]^[in_row_index]); + out_ptr := JSAMPARRAY(@ output_buf^[ci]^ + [out_row_group_index * compptr^.v_samp_factor]); + downsample^.methods[ci] (cinfo, compptr, in_ptr, out_ptr); + Inc(compptr); + end; +end; + + +{ Downsample pixel values of a single component. + One row group is processed per call. + This version handles arbitrary integral sampling ratios, without smoothing. + Note that this version is not actually used for customary sampling ratios. } + +{METHODDEF} +procedure int_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +var + inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v : int; + outcol, outcol_h : JDIMENSION; { outcol_h = outcol*h_expand } + output_cols : JDIMENSION; + inptr, + outptr : JSAMPLE_PTR; + outvalue : INT32; +begin + output_cols := compptr^.width_in_blocks * DCTSIZE; + + h_expand := cinfo^.max_h_samp_factor div compptr^.h_samp_factor; + v_expand := cinfo^.max_v_samp_factor div compptr^.v_samp_factor; + numpix := h_expand * v_expand; + numpix2 := numpix div 2; + + { Expand input data enough to let all the output samples be generated + by the standard loop. Special-casing padded output would be more + efficient. } + + expand_right_edge(input_data, cinfo^.max_v_samp_factor, + cinfo^.image_width, output_cols * h_expand); + + inrow := 0; + for outrow := 0 to pred(compptr^.v_samp_factor) do + begin + outptr := JSAMPLE_PTR(output_data^[outrow]); + outcol_h := 0; + for outcol := 0 to pred(output_cols) do + begin + outvalue := 0; + for v := 0 to pred(v_expand) do + begin + inptr := @(input_data^[inrow+v]^[outcol_h]); + for h := 0 to pred(h_expand) do + begin + Inc(outvalue, INT32 (GETJSAMPLE(inptr^)) ); + Inc(inptr); + end; + end; + outptr^ := JSAMPLE ((outvalue + numpix2) div numpix); + Inc(outptr); + Inc(outcol_h, h_expand); + end; + Inc(inrow, v_expand); + end; +end; + + +{ Downsample pixel values of a single component. + This version handles the special case of a full-size component, + without smoothing. } + +{METHODDEF} +procedure fullsize_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +begin + { Copy the data } + jcopy_sample_rows(input_data, 0, output_data, 0, + cinfo^.max_v_samp_factor, cinfo^.image_width); + { Edge-expand } + expand_right_edge(output_data, cinfo^.max_v_samp_factor, + cinfo^.image_width, compptr^.width_in_blocks * DCTSIZE); +end; + + +{ Downsample pixel values of a single component. + This version handles the common case of 2:1 horizontal and 1:1 vertical, + without smoothing. + + A note about the "bias" calculations: when rounding fractional values to + integer, we do not want to always round 0.5 up to the next integer. + If we did that, we'd introduce a noticeable bias towards larger values. + Instead, this code is arranged so that 0.5 will be rounded up or down at + alternate pixel locations (a simple ordered dither pattern). } + +{METHODDEF} +procedure h2v1_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +var + outrow : int; + outcol : JDIMENSION; + output_cols : JDIMENSION; + {register} inptr, outptr : JSAMPLE_PTR; + {register} bias : int; +begin + output_cols := compptr^.width_in_blocks * DCTSIZE; + + { Expand input data enough to let all the output samples be generated + by the standard loop. Special-casing padded output would be more + efficient. } + + expand_right_edge(input_data, cinfo^.max_v_samp_factor, + cinfo^.image_width, output_cols * 2); + + for outrow := 0 to pred(compptr^.v_samp_factor) do + begin + outptr := JSAMPLE_PTR(output_data^[outrow]); + inptr := JSAMPLE_PTR(input_data^[outrow]); + bias := 0; { bias := 0,1,0,1,... for successive samples } + for outcol := 0 to pred(output_cols) do + begin + outptr^ := JSAMPLE ((GETJSAMPLE(inptr^) + + GETJSAMPLE(JSAMPROW(inptr)^[1]) + bias) shr 1); + Inc(outptr); + bias := bias xor 1; { 0=>1, 1=>0 } + Inc(inptr, 2); + end; + end; +end; + + +{ Downsample pixel values of a single component. + This version handles the standard case of 2:1 horizontal and 2:1 vertical, + without smoothing. } + +{METHODDEF} +procedure h2v2_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +var + inrow, outrow : int; + outcol : JDIMENSION; + output_cols : JDIMENSION; + {register} inptr0, inptr1, outptr : JSAMPLE_PTR; + {register} bias : int; +begin + output_cols := compptr^.width_in_blocks * DCTSIZE; + + { Expand input data enough to let all the output samples be generated + by the standard loop. Special-casing padded output would be more + efficient. } + + expand_right_edge(input_data, cinfo^.max_v_samp_factor, + cinfo^.image_width, output_cols * 2); + + inrow := 0; + for outrow := 0 to pred(compptr^.v_samp_factor) do + begin + outptr := JSAMPLE_PTR(output_data^[outrow]); + inptr0 := JSAMPLE_PTR(input_data^[inrow]); + inptr1 := JSAMPLE_PTR(input_data^[inrow+1]); + bias := 1; { bias := 1,2,1,2,... for successive samples } + for outcol := 0 to pred(output_cols) do + begin + outptr^ := JSAMPLE ((GETJSAMPLE(inptr0^) + + GETJSAMPLE(JSAMPROW(inptr0)^[1]) + + GETJSAMPLE(inptr1^) + + GETJSAMPLE(JSAMPROW(inptr1)^[1]) + bias) shr 2); + Inc(outptr); + bias := bias xor 3; { 1=>2, 2=>1 } + Inc(inptr0, 2); + Inc(inptr1, 2); + end; + Inc(inrow, 2); + end; +end; + + +{$ifdef INPUT_SMOOTHING_SUPPORTED} + +{ Downsample pixel values of a single component. + This version handles the standard case of 2:1 horizontal and 2:1 vertical, + with smoothing. One row of context is required. } + +{METHODDEF} +procedure h2v2_smooth_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +var + inrow, outrow : int; + colctr : JDIMENSION; + output_cols : JDIMENSION; + {register} inptr0, inptr1, above_ptr, below_ptr, outptr : JSAMPLE_PTR; + membersum, neighsum, memberscale, neighscale : INT32; +var + prev_input_data : JSAMPARRAY; + prev_inptr0, prev_inptr1, prev_above_ptr, prev_below_ptr : JSAMPLE_PTR; +begin + output_cols := compptr^.width_in_blocks * DCTSIZE; + + { Expand input data enough to let all the output samples be generated + by the standard loop. Special-casing padded output would be more + efficient. } + + prev_input_data := input_data; + Dec(JSAMPROW_PTR(prev_input_data)); + expand_right_edge(prev_input_data, cinfo^.max_v_samp_factor + 2, + cinfo^.image_width, output_cols * 2); + + { We don't bother to form the individual "smoothed" input pixel values; + we can directly compute the output which is the average of the four + smoothed values. Each of the four member pixels contributes a fraction + (1-8*SF) to its own smoothed image and a fraction SF to each of the three + other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final + output. The four corner-adjacent neighbor pixels contribute a fraction + SF to just one smoothed pixel, or SF/4 to the final output; while the + eight edge-adjacent neighbors contribute SF to each of two smoothed + pixels, or SF/2 overall. In order to use integer arithmetic, these + factors are scaled by 2^16 := 65536. + Also recall that SF := smoothing_factor / 1024. } + + memberscale := 16384 - cinfo^.smoothing_factor * 80; { scaled (1-5*SF)/4 } + neighscale := cinfo^.smoothing_factor * 16; { scaled SF/4 } + + inrow := 0; + for outrow := 0 to pred(compptr^.v_samp_factor) do + begin + outptr := JSAMPLE_PTR(output_data^[outrow]); + inptr0 := JSAMPLE_PTR(input_data^[inrow]); + inptr1 := JSAMPLE_PTR(input_data^[inrow+1]); + above_ptr := JSAMPLE_PTR(input_data^[inrow-1]); + below_ptr := JSAMPLE_PTR(input_data^[inrow+2]); + + { Special case for first column: pretend column -1 is same as column 0 } + membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) + + GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]); + neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) + + GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) + + GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[2]) + + GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[2]); + Inc(neighsum, neighsum); + Inc(neighsum, GETJSAMPLE(above_ptr^) + + GETJSAMPLE(JSAMPROW(above_ptr)^[2]) + + GETJSAMPLE(below_ptr^) + + GETJSAMPLE(JSAMPROW(below_ptr)^[2]) ); + membersum := membersum * memberscale + neighsum * neighscale; + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + Inc(outptr); + prev_inptr0 := inptr0; + prev_inptr1 := inptr1; + Inc(prev_inptr0); + Inc(prev_inptr1); + Inc(inptr0, 2); + Inc(inptr1, 2); + prev_above_ptr := above_ptr; + prev_below_ptr := below_ptr; + Inc(above_ptr, 2); + Inc(below_ptr, 2); + Inc(prev_above_ptr, 1); + Inc(prev_below_ptr, 1); + + for colctr := pred(output_cols - 2) downto 0 do + begin + { sum of pixels directly mapped to this output element } + membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) + + GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]); + { sum of edge-neighbor pixels } + neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) + + GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) + + GETJSAMPLE(prev_inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[2]) + + GETJSAMPLE(prev_inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[2]); + { The edge-neighbors count twice as much as corner-neighbors } + Inc(neighsum, neighsum); + { Add in the corner-neighbors } + Inc(neighsum, GETJSAMPLE(prev_above_ptr^) + + GETJSAMPLE(JSAMPROW(above_ptr)^[2]) + + GETJSAMPLE(prev_below_ptr^) + + GETJSAMPLE(JSAMPROW(below_ptr)^[2]) ); + { form final output scaled up by 2^16 } + membersum := membersum * memberscale + neighsum * neighscale; + { round, descale and output it } + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + Inc(outptr); + Inc(inptr0, 2); + Inc(inptr1, 2); + Inc(prev_inptr0, 2); + Inc(prev_inptr1, 2); + Inc(above_ptr, 2); + Inc(below_ptr, 2); + Inc(prev_above_ptr, 2); + Inc(prev_below_ptr, 2); + end; + + { Special case for last column } + membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) + + GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]); + neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) + + GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) + + GETJSAMPLE(prev_inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) + + GETJSAMPLE(prev_inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]); + Inc(neighsum, neighsum); + Inc(neighsum, GETJSAMPLE(prev_above_ptr^) + + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) + + GETJSAMPLE(prev_below_ptr^) + + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) ); + membersum := membersum * memberscale + neighsum * neighscale; + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + + Inc(inrow, 2); + end; +end; + + +{ Downsample pixel values of a single component. + This version handles the special case of a full-size component, + with smoothing. One row of context is required. } + +{METHODDEF} +procedure fullsize_smooth_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +var + outrow : int; + colctr : JDIMENSION; + output_cols : JDIMENSION; + {register} inptr, above_ptr, below_ptr, outptr : JSAMPLE_PTR; + membersum, neighsum, memberscale, neighscale : INT32; + colsum, lastcolsum, nextcolsum : int; +var + prev_input_data : JSAMPARRAY; +begin + output_cols := compptr^.width_in_blocks * DCTSIZE; + + { Expand input data enough to let all the output samples be generated + by the standard loop. Special-casing padded output would be more + efficient. } + + prev_input_data := input_data; + Dec(JSAMPROW_PTR(prev_input_data)); + expand_right_edge(prev_input_data, cinfo^.max_v_samp_factor + 2, + cinfo^.image_width, output_cols); + + { Each of the eight neighbor pixels contributes a fraction SF to the + smoothed pixel, while the main pixel contributes (1-8*SF). In order + to use integer arithmetic, these factors are multiplied by 2^16 := 65536. + Also recall that SF := smoothing_factor / 1024. } + + memberscale := long(65536) - cinfo^.smoothing_factor * long(512); { scaled 1-8*SF } + neighscale := cinfo^.smoothing_factor * 64; { scaled SF } + + for outrow := 0 to pred(compptr^.v_samp_factor) do + begin + outptr := JSAMPLE_PTR(output_data^[outrow]); + inptr := JSAMPLE_PTR(input_data^[outrow]); + above_ptr := JSAMPLE_PTR(input_data^[outrow-1]); + below_ptr := JSAMPLE_PTR(input_data^[outrow+1]); + + { Special case for first column } + colsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) + + GETJSAMPLE(inptr^); + Inc(above_ptr); + Inc(below_ptr); + membersum := GETJSAMPLE(inptr^); + Inc(inptr); + nextcolsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) + + GETJSAMPLE(inptr^); + neighsum := colsum + (colsum - membersum) + nextcolsum; + membersum := membersum * memberscale + neighsum * neighscale; + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + Inc(outptr); + lastcolsum := colsum; colsum := nextcolsum; + + for colctr := pred(output_cols - 2) downto 0 do + begin + membersum := GETJSAMPLE(inptr^); + Inc(inptr); + Inc(above_ptr); + Inc(below_ptr); + nextcolsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) + + GETJSAMPLE(inptr^); + neighsum := lastcolsum + (colsum - membersum) + nextcolsum; + membersum := membersum * memberscale + neighsum * neighscale; + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + Inc(outptr); + lastcolsum := colsum; colsum := nextcolsum; + end; + + { Special case for last column } + membersum := GETJSAMPLE(inptr^); + neighsum := lastcolsum + (colsum - membersum) + colsum; + membersum := membersum * memberscale + neighsum * neighscale; + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + end; +end; + +{$endif} { INPUT_SMOOTHING_SUPPORTED } + + +{ Module initialization routine for downsampling. + Note that we must select a routine for each component. } + +{GLOBAL} +procedure jinit_downsampler (cinfo : j_compress_ptr); +var + downsample : my_downsample_ptr; + ci : int; + compptr : jpeg_component_info_ptr; + smoothok : boolean; +begin + smoothok := TRUE; + + downsample := my_downsample_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_downsampler)) ); + cinfo^.downsample := jpeg_downsampler_ptr (downsample); + downsample^.pub.start_pass := start_pass_downsample; + downsample^.pub.downsample := sep_downsample; + downsample^.pub.need_context_rows := FALSE; + + if (cinfo^.CCIR601_sampling) then + ERREXIT(j_common_ptr(cinfo), JERR_CCIR601_NOTIMPL); + + { Verify we can handle the sampling factors, and set up method pointers } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + if (compptr^.h_samp_factor = cinfo^.max_h_samp_factor) and + (compptr^.v_samp_factor = cinfo^.max_v_samp_factor) then + begin +{$ifdef INPUT_SMOOTHING_SUPPORTED} + if (cinfo^.smoothing_factor <> 0) then + begin + downsample^.methods[ci] := fullsize_smooth_downsample; + downsample^.pub.need_context_rows := TRUE; + end + else +{$endif} + downsample^.methods[ci] := fullsize_downsample; + end + else + if (compptr^.h_samp_factor * 2 = cinfo^.max_h_samp_factor) and + (compptr^.v_samp_factor = cinfo^.max_v_samp_factor) then + begin + smoothok := FALSE; + downsample^.methods[ci] := h2v1_downsample; + end + else + if (compptr^.h_samp_factor * 2 = cinfo^.max_h_samp_factor) and + (compptr^.v_samp_factor * 2 = cinfo^.max_v_samp_factor) then + begin + {$ifdef INPUT_SMOOTHING_SUPPORTED} + if (cinfo^.smoothing_factor <> 0) then + begin + downsample^.methods[ci] := h2v2_smooth_downsample; + downsample^.pub.need_context_rows := TRUE; + end + else + {$endif} + downsample^.methods[ci] := h2v2_downsample; + end + else + if ((cinfo^.max_h_samp_factor mod compptr^.h_samp_factor) = 0) and + ((cinfo^.max_v_samp_factor mod compptr^.v_samp_factor) = 0) then + begin + smoothok := FALSE; + downsample^.methods[ci] := int_downsample; + end + else + ERREXIT(j_common_ptr(cinfo), JERR_FRACT_SAMPLE_NOTIMPL); + Inc(compptr); + end; + +{$ifdef INPUT_SMOOTHING_SUPPORTED} + if (cinfo^.smoothing_factor <> 0) and (not smoothok) then + TRACEMS(j_common_ptr(cinfo), 0, JTRC_SMOOTH_NOTIMPL); +{$endif} +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jctrans_del.pas b/mseide-msegui/lib/common/fpccompatibility/jctrans_del.pas new file mode 100644 index 0000000..217649f --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jctrans_del.pas @@ -0,0 +1,459 @@ +Unit JcTrans; + +{ This file contains library routines for transcoding compression, + that is, writing raw DCT coefficient arrays to an output JPEG file. + The routines in jcapimin.c will also be needed by a transcoder. } + +{ Original : jctrans.c - Copyright (C) 1995-1998, Thomas G. Lane. } + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg, + jinclude, + jdeferr, + jerror, + jutils, + jpeglib, + jcapimin, jcparam, jcomapi, jcmaster, jchuff, jcphuff, jcmarker; + +{ Compression initialization for writing raw-coefficient data. + Before calling this, all parameters and a data destination must be set up. + Call jpeg_finish_compress() to actually write the data. + + The number of passed virtual arrays must match cinfo^.num_components. + Note that the virtual arrays need not be filled or even realized at + the time write_coefficients is called; indeed, if the virtual arrays + were requested from this compression object's memory manager, they + typically will be realized during this routine and filled afterwards. } + +{GLOBAL} +procedure jpeg_write_coefficients (cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); + +{ Initialize the compression object with default parameters, + then copy from the source object all parameters needed for lossless + transcoding. Parameters that can be varied without loss (such as + scan script and Huffman optimization) are left in their default states. } + +{GLOBAL} +procedure jpeg_copy_critical_parameters (srcinfo : j_decompress_ptr; + dstinfo : j_compress_ptr); + + +implementation + +{ Forward declarations } +{LOCAL} +procedure transencode_master_selection(cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); + forward; +{LOCAL} +procedure transencode_coef_controller(cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); + forward; + + +{ Compression initialization for writing raw-coefficient data. + Before calling this, all parameters and a data destination must be set up. + Call jpeg_finish_compress() to actually write the data. + + The number of passed virtual arrays must match cinfo^.num_components. + Note that the virtual arrays need not be filled or even realized at + the time write_coefficients is called; indeed, if the virtual arrays + were requested from this compression object's memory manager, they + typically will be realized during this routine and filled afterwards. } + +{GLOBAL} +procedure jpeg_write_coefficients (cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); +begin + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + { Mark all tables to be written } + jpeg_suppress_tables(cinfo, FALSE); + { (Re)initialize error mgr and destination modules } + cinfo^.err^.reset_error_mgr (j_common_ptr(cinfo)); + cinfo^.dest^.init_destination (cinfo); + { Perform master selection of active modules } + transencode_master_selection(cinfo, coef_arrays); + { Wait for jpeg_finish_compress() call } + cinfo^.next_scanline := 0; { so jpeg_write_marker works } + cinfo^.global_state := CSTATE_WRCOEFS; +end; + + +{ Initialize the compression object with default parameters, + then copy from the source object all parameters needed for lossless + transcoding. Parameters that can be varied without loss (such as + scan script and Huffman optimization) are left in their default states. } + +{GLOBAL} +procedure jpeg_copy_critical_parameters (srcinfo : j_decompress_ptr; + dstinfo : j_compress_ptr); +var + qtblptr : ^JQUANT_TBL_PTR; + incomp, outcomp : jpeg_component_info_ptr; + c_quant, slot_quant : JQUANT_TBL_PTR; + tblno, ci, coefi : int; +begin + + { Safety check to ensure start_compress not called yet. } + if (dstinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(dstinfo), JERR_BAD_STATE, dstinfo^.global_state); + { Copy fundamental image dimensions } + dstinfo^.image_width := srcinfo^.image_width; + dstinfo^.image_height := srcinfo^.image_height; + dstinfo^.input_components := srcinfo^.num_components; + dstinfo^.in_color_space := srcinfo^.jpeg_color_space; + { Initialize all parameters to default values } + jpeg_set_defaults(dstinfo); + { jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB. + Fix it to get the right header markers for the image colorspace. } + + jpeg_set_colorspace(dstinfo, srcinfo^.jpeg_color_space); + dstinfo^.data_precision := srcinfo^.data_precision; + dstinfo^.CCIR601_sampling := srcinfo^.CCIR601_sampling; + { Copy the source's quantization tables. } + for tblno := 0 to pred(NUM_QUANT_TBLS) do + begin + if (srcinfo^.quant_tbl_ptrs[tblno] <> NIL) then + begin + qtblptr := @dstinfo^.quant_tbl_ptrs[tblno]; + if (qtblptr^ = NIL) then + qtblptr^ := jpeg_alloc_quant_table(j_common_ptr(dstinfo)); + MEMCOPY(@(qtblptr^)^.quantval, + @srcinfo^.quant_tbl_ptrs[tblno]^.quantval, + SIZEOF((qtblptr^)^.quantval)); + (qtblptr^)^.sent_table := FALSE; + end; + end; + { Copy the source's per-component info. + Note we assume jpeg_set_defaults has allocated the dest comp_info array. } + + dstinfo^.num_components := srcinfo^.num_components; + if (dstinfo^.num_components < 1) or + (dstinfo^.num_components > MAX_COMPONENTS) then + ERREXIT2(j_common_ptr(dstinfo), JERR_COMPONENT_COUNT, + dstinfo^.num_components, MAX_COMPONENTS); + incomp := jpeg_component_info_ptr(srcinfo^.comp_info); + outcomp := jpeg_component_info_ptr(dstinfo^.comp_info); + for ci := 0 to pred(dstinfo^.num_components) do + begin + + outcomp^.component_id := incomp^.component_id; + outcomp^.h_samp_factor := incomp^.h_samp_factor; + outcomp^.v_samp_factor := incomp^.v_samp_factor; + outcomp^.quant_tbl_no := incomp^.quant_tbl_no; + { Make sure saved quantization table for component matches the qtable + slot. If not, the input file re-used this qtable slot. + IJG encoder currently cannot duplicate this. } + + tblno := outcomp^.quant_tbl_no; + if (tblno < 0) or (tblno >= NUM_QUANT_TBLS) or + (srcinfo^.quant_tbl_ptrs[tblno] = NIL) then + ERREXIT1(j_common_ptr(dstinfo), JERR_NO_QUANT_TABLE, tblno); + slot_quant := srcinfo^.quant_tbl_ptrs[tblno]; + c_quant := incomp^.quant_table; + if (c_quant <> NIL) then + begin + for coefi := 0 to pred(DCTSIZE2) do + begin + if (c_quant^.quantval[coefi] <> slot_quant^.quantval[coefi]) then + ERREXIT1(j_common_ptr(dstinfo), JERR_MISMATCHED_QUANT_TABLE, tblno); + end; + end; + { Note: we do not copy the source's Huffman table assignments; + instead we rely on jpeg_set_colorspace to have made a suitable choice. } + Inc(incomp); + Inc(outcomp); + end; + { Also copy JFIF version and resolution information, if available. + Strictly speaking this isn't "critical" info, but it's nearly + always appropriate to copy it if available. In particular, + if the application chooses to copy JFIF 1.02 extension markers from + the source file, we need to copy the version to make sure we don't + emit a file that has 1.02 extensions but a claimed version of 1.01. + We will *not*, however, copy version info from mislabeled "2.01" files. } + + if (srcinfo^.saw_JFIF_marker) then + begin + if (srcinfo^.JFIF_major_version = 1) then + begin + dstinfo^.JFIF_major_version := srcinfo^.JFIF_major_version; + dstinfo^.JFIF_minor_version := srcinfo^.JFIF_minor_version; + end; + dstinfo^.density_unit := srcinfo^.density_unit; + dstinfo^.X_density := srcinfo^.X_density; + dstinfo^.Y_density := srcinfo^.Y_density; + end; +end; + + +{ Master selection of compression modules for transcoding. + This substitutes for jcinit.c's initialization of the full compressor. } + +{LOCAL} +procedure transencode_master_selection (cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); +begin + { Although we don't actually use input_components for transcoding, + jcmaster.c's initial_setup will complain if input_components is 0. } + + cinfo^.input_components := 1; + { Initialize master control (includes parameter checking/processing) } + jinit_c_master_control(cinfo, TRUE { transcode only }); + + { Entropy encoding: either Huffman or arithmetic coding. } + if (cinfo^.arith_code) then + begin + ERREXIT(j_common_ptr(cinfo), JERR_ARITH_NOTIMPL); + end + else + begin + if (cinfo^.progressive_mode) then + begin +{$ifdef C_PROGRESSIVE_SUPPORTED} + jinit_phuff_encoder(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + jinit_huff_encoder(cinfo); + end; + + { We need a special coefficient buffer controller. } + transencode_coef_controller(cinfo, coef_arrays); + + jinit_marker_writer(cinfo); + + { We can now tell the memory manager to allocate virtual arrays. } + cinfo^.mem^.realize_virt_arrays (j_common_ptr(cinfo)); + + { Write the datastream header (SOI, JFIF) immediately. + Frame and scan headers are postponed till later. + This lets application insert special markers after the SOI. } + + cinfo^.marker^.write_file_header (cinfo); +end; + + +{ The rest of this file is a special implementation of the coefficient + buffer controller. This is similar to jccoefct.c, but it handles only + output from presupplied virtual arrays. Furthermore, we generate any + dummy padding blocks on-the-fly rather than expecting them to be present + in the arrays. } + +{ Private buffer controller object } + +type + my_coef_ptr = ^my_coef_controller; + my_coef_controller = record + pub : jpeg_c_coef_controller; { public fields } + + iMCU_row_num : JDIMENSION; { iMCU row # within image } + mcu_ctr : JDIMENSION; { counts MCUs processed in current row } + MCU_vert_offset : int; { counts MCU rows within iMCU row } + MCU_rows_per_iMCU_row : int; { number of such rows needed } + + { Virtual block array for each component. } + whole_image : jvirt_barray_tbl_ptr; + + { Workspace for constructing dummy blocks at right/bottom edges. } + dummy_buffer : array[0..C_MAX_BLOCKS_IN_MCU-1] of JBLOCKROW; + end; {my_coef_controller;} + + +{LOCAL} +procedure start_iMCU_row (cinfo : j_compress_ptr); +{ Reset within-iMCU-row counters for a new row } +var + coef : my_coef_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + { In an interleaved scan, an MCU row is the same as an iMCU row. + In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + But at the bottom of the image, process only what's left. } + + if (cinfo^.comps_in_scan > 1) then + begin + coef^.MCU_rows_per_iMCU_row := 1; + end + else + begin + if (coef^.iMCU_row_num < (cinfo^.total_iMCU_rows-1)) then + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.v_samp_factor + else + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.last_row_height; + end; + + coef^.mcu_ctr := 0; + coef^.MCU_vert_offset := 0; +end; + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_coef (cinfo : j_compress_ptr; + pass_mode : J_BUF_MODE); +var + coef : my_coef_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + if (pass_mode <> JBUF_CRANK_DEST) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + + coef^.iMCU_row_num := 0; + start_iMCU_row(cinfo); +end; + + +{ Process some data. + We process the equivalent of one fully interleaved MCU row ("iMCU" row) + per call, ie, v_samp_factor block rows for each component in the scan. + The data is obtained from the virtual arrays and fed to the entropy coder. + Returns TRUE if the iMCU row is completed, FALSE if suspended. + + NB: input_buf is ignored; it is likely to be a NIL pointer. } + +{METHODDEF} +function compress_output (cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; +var + coef : my_coef_ptr; + MCU_col_num : JDIMENSION; { index of current MCU within row } + last_MCU_col : JDIMENSION; + last_iMCU_row : JDIMENSION; + blkn, ci, xindex, yindex, yoffset, blockcnt : int; + start_col : JDIMENSION; + buffer : array[0..MAX_COMPS_IN_SCAN-1] of JBLOCKARRAY; + MCU_buffer : array[0..C_MAX_BLOCKS_IN_MCU-1] of JBLOCKROW; + buffer_ptr : JBLOCKROW; + compptr : jpeg_component_info_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + last_MCU_col := cinfo^.MCUs_per_row - 1; + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + { Align the virtual buffers for the components used in this scan. } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + buffer[ci] := cinfo^.mem^.access_virt_barray + (j_common_ptr(cinfo), coef^.whole_image^[compptr^.component_index], + coef^.iMCU_row_num * compptr^.v_samp_factor, + JDIMENSION(compptr^.v_samp_factor), FALSE); + end; + + { Loop to process one whole iMCU row } + for yoffset := coef^.MCU_vert_offset to pred(coef^.MCU_rows_per_iMCU_row) do + begin + for MCU_col_num := coef^.mcu_ctr to pred(cinfo^.MCUs_per_row) do + begin + { Construct list of pointers to DCT blocks belonging to this MCU } + blkn := 0; { index of current DCT block within MCU } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + start_col := MCU_col_num * compptr^.MCU_width; + if (MCU_col_num < last_MCU_col) then + blockcnt := compptr^.MCU_width + else + blockcnt := compptr^.last_col_width; + for yindex := 0 to pred(compptr^.MCU_height) do + begin + if (coef^.iMCU_row_num < last_iMCU_row) or + (yindex+yoffset < compptr^.last_row_height) then + begin + { Fill in pointers to real blocks in this row } + buffer_ptr := JBLOCKROW(@ buffer[ci]^[yindex+yoffset]^[start_col]); + for xindex := 0 to pred(blockcnt) do + begin + MCU_buffer[blkn] := buffer_ptr; + Inc(blkn); + Inc(JBLOCK_PTR(buffer_ptr)); + end; + xindex := blockcnt; + end + else + begin + { At bottom of image, need a whole row of dummy blocks } + xindex := 0; + end; + { Fill in any dummy blocks needed in this row. + Dummy blocks are filled in the same way as in jccoefct.c: + all zeroes in the AC entries, DC entries equal to previous + block's DC value. The init routine has already zeroed the + AC entries, so we need only set the DC entries correctly. } + + while (xindex < compptr^.MCU_width) do + begin + MCU_buffer[blkn] := coef^.dummy_buffer[blkn]; + MCU_buffer[blkn]^[0][0] := MCU_buffer[blkn-1]^[0][0]; + Inc(xindex); + Inc(blkn); + end; + end; + end; + { Try to write the MCU. } + if (not cinfo^.entropy^.encode_mcu (cinfo, MCU_buffer)) then + begin + { Suspension forced; update state counters and exit } + coef^.MCU_vert_offset := yoffset; + coef^.mcu_ctr := MCU_col_num; + compress_output := FALSE; + exit; + end; + end; + { Completed an MCU row, but perhaps not an iMCU row } + coef^.mcu_ctr := 0; + end; + { Completed the iMCU row, advance counters for next one } + Inc(coef^.iMCU_row_num); + start_iMCU_row(cinfo); + compress_output := TRUE; +end; + + +{ Initialize coefficient buffer controller. + + Each passed coefficient array must be the right size for that + coefficient: width_in_blocks wide and height_in_blocks high, + with unitheight at least v_samp_factor. } + +{LOCAL} +procedure transencode_coef_controller (cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); +var + coef : my_coef_ptr; + buffer : JBLOCKROW; + i : int; +begin + coef := my_coef_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_coef_controller))); + cinfo^.coef := jpeg_c_coef_controller_ptr (coef); + coef^.pub.start_pass := start_pass_coef; + coef^.pub.compress_data := compress_output; + + { Save pointer to virtual arrays } + coef^.whole_image := coef_arrays; + + { Allocate and pre-zero space for dummy DCT blocks. } + buffer := JBLOCKROW( + cinfo^.mem^.alloc_large (j_common_ptr(cinfo), JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)) ); + jzero_far({FAR} voidp(buffer), C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for i := 0 to pred(C_MAX_BLOCKS_IN_MCU) do + begin + coef^.dummy_buffer[i] := JBLOCKROW(@ buffer^[i]); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdapimin_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdapimin_del.pas new file mode 100644 index 0000000..42d907b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdapimin_del.pas @@ -0,0 +1,506 @@ +unit jdapimin_del; + +//{$N+} { Nomssi: cinfo^.output_gamma } + +{ This file contains application interface code for the decompression half + of the JPEG library. These are the "minimum" API routines that may be + needed in either the normal full-decompression case or the + transcoding-only case. + + Most of the routines intended to be called directly by an application + are in this file or in jdapistd.c. But also see jcomapi.c for routines + shared by compression and decompression, and jdtrans.c for the transcoding + case. } + +{ Original : jdapimin.c ; Copyright (C) 1994-1998, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jmemmgr_del, jdmarker_del, jdinput_del, jcomapi_del; + +{ Nomssi } +procedure jpeg_create_decompress(cinfo : j_decompress_ptr); + +{ Initialization of a JPEG decompression object. + The error manager must already be set up (in case memory manager fails). } + +{GLOBAL} +procedure jpeg_CreateDecompress (cinfo : j_decompress_ptr; + version : int; + structsize : size_t); + +{ Destruction of a JPEG decompression object } + +{GLOBAL} +procedure jpeg_destroy_decompress (cinfo : j_decompress_ptr); + + +{ Decompression startup: read start of JPEG datastream to see what's there. + Need only initialize JPEG object and supply a data source before calling. + + This routine will read as far as the first SOS marker (ie, actual start of + compressed data), and will save all tables and parameters in the JPEG + object. It will also initialize the decompression parameters to default + values, and finally return JPEG_HEADER_OK. On return, the application may + adjust the decompression parameters and then call jpeg_start_decompress. + (Or, if the application only wanted to determine the image parameters, + the data need not be decompressed. In that case, call jpeg_abort or + jpeg_destroy to release any temporary space.) + If an abbreviated (tables only) datastream is presented, the routine will + return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then + re-use the JPEG object to read the abbreviated image datastream(s). + It is unnecessary (but OK) to call jpeg_abort in this case. + The JPEG_SUSPENDED return code only occurs if the data source module + requests suspension of the decompressor. In this case the application + should load more source data and then re-call jpeg_read_header to resume + processing. + If a non-suspending data source is used and require_image is TRUE, then the + return code need not be inspected since only JPEG_HEADER_OK is possible. + + This routine is now just a front end to jpeg_consume_input, with some + extra error checking. } + +{GLOBAL} +function jpeg_read_header (cinfo : j_decompress_ptr; + require_image : boolean) : int; + +{ Consume data in advance of what the decompressor requires. + This can be called at any time once the decompressor object has + been created and a data source has been set up. + + This routine is essentially a state machine that handles a couple + of critical state-transition actions, namely initial setup and + transition from header scanning to ready-for-start_decompress. + All the actual input is done via the input controller's consume_input + method. } + +{GLOBAL} +function jpeg_consume_input (cinfo : j_decompress_ptr) : int; + +{ Have we finished reading the input file? } + +{GLOBAL} +function jpeg_input_complete (cinfo : j_decompress_ptr) : boolean; + +{ Is there more than one scan? } + +{GLOBAL} +function jpeg_has_multiple_scans (cinfo : j_decompress_ptr) : boolean; + + +{ Finish JPEG decompression. + + This will normally just verify the file trailer and release temp storage. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_finish_decompress (cinfo : j_decompress_ptr) : boolean; + +implementation + +procedure jpeg_create_decompress(cinfo : j_decompress_ptr); +begin + jpeg_CreateDecompress(cinfo, JPEG_LIB_VERSION, + size_t(sizeof(jpeg_decompress_struct))); +end; + +{ Initialization of a JPEG decompression object. + The error manager must already be set up (in case memory manager fails). } + +{GLOBAL} +procedure jpeg_CreateDecompress (cinfo : j_decompress_ptr; + version : int; + structsize : size_t); +var + i : int; +var + err : jpeg_error_mgr_ptr; + client_data : voidp; +begin + { Guard against version mismatches between library and caller. } + cinfo^.mem := NIL; { so jpeg_destroy knows mem mgr not called } + if (version <> JPEG_LIB_VERSION) then + ERREXIT2(j_common_ptr(cinfo), JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize <> SIZEOF(jpeg_decompress_struct)) then + ERREXIT2(j_common_ptr(cinfo), JERR_BAD_STRUCT_SIZE, + int(SIZEOF(jpeg_decompress_struct)), int(structsize)); + + { For debugging purposes, we zero the whole master structure. + But the application has already set the err pointer, and may have set + client_data, so we have to save and restore those fields. + Note: if application hasn't set client_data, tools like Purify may + complain here. } + begin + err := cinfo^.err; + client_data := cinfo^.client_data; { ignore Purify complaint here } + MEMZERO(j_common_ptr(cinfo), SIZEOF(jpeg_decompress_struct)); + cinfo^.err := err; + cinfo^.client_data := client_data; + end; + cinfo^.is_decompressor := TRUE; + + { Initialize a memory manager instance for this object } + jinit_memory_mgr(j_common_ptr(cinfo)); + + { Zero out pointers to permanent structures. } + cinfo^.progress := NIL; + cinfo^.src := NIL; + + for i := 0 to pred(NUM_QUANT_TBLS) do + cinfo^.quant_tbl_ptrs[i] := NIL; + + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + cinfo^.dc_huff_tbl_ptrs[i] := NIL; + cinfo^.ac_huff_tbl_ptrs[i] := NIL; + end; + + { Initialize marker processor so application can override methods + for COM, APPn markers before calling jpeg_read_header. } + cinfo^.marker_list := NIL; + jinit_marker_reader(cinfo); + + { And initialize the overall input controller. } + jinit_input_controller(cinfo); + + { OK, I'm ready } + cinfo^.global_state := DSTATE_START; +end; + + +{ Destruction of a JPEG decompression object } + +{GLOBAL} +procedure jpeg_destroy_decompress (cinfo : j_decompress_ptr); +begin + jpeg_destroy(j_common_ptr(cinfo)); { use common routine } +end; + + +{ Abort processing of a JPEG decompression operation, + but don't destroy the object itself. } + +{GLOBAL} +procedure jpeg_abort_decompress (cinfo : j_decompress_ptr); +begin + jpeg_abort(j_common_ptr(cinfo)); { use common routine } +end; + + +{ Set default decompression parameters. } + +{LOCAL} +procedure default_decompress_parms (cinfo : j_decompress_ptr); +var + cid0 : int; + cid1 : int; + cid2 : int; +begin + { Guess the input colorspace, and set output colorspace accordingly. } + { (Wish JPEG committee had provided a real way to specify this...) } + { Note application may override our guesses. } + case (cinfo^.num_components) of + 1: begin + cinfo^.jpeg_color_space := JCS_GRAYSCALE; + cinfo^.out_color_space := JCS_GRAYSCALE; + end; + + 3: begin + if (cinfo^.saw_JFIF_marker) then + begin + cinfo^.jpeg_color_space := JCS_YCbCr; { JFIF implies YCbCr } + end + else + if (cinfo^.saw_Adobe_marker) then + begin + case (cinfo^.Adobe_transform) of + 0: cinfo^.jpeg_color_space := JCS_RGB; + 1: cinfo^.jpeg_color_space := JCS_YCbCr; + else + begin + WARNMS1(j_common_ptr(cinfo), JWRN_ADOBE_XFORM, cinfo^.Adobe_transform); + cinfo^.jpeg_color_space := JCS_YCbCr; { assume it's YCbCr } + end; + end; + end + else + begin + { Saw no special markers, try to guess from the component IDs } + cid0 := cinfo^.comp_info^[0].component_id; + cid1 := cinfo^.comp_info^[1].component_id; + cid2 := cinfo^.comp_info^[2].component_id; + + if (cid0 = 1) and (cid1 = 2) and (cid2 = 3) then + cinfo^.jpeg_color_space := JCS_YCbCr { assume JFIF w/out marker } + else + if (cid0 = 82) and (cid1 = 71) and (cid2 = 66) then + cinfo^.jpeg_color_space := JCS_RGB { ASCII 'R', 'G', 'B' } + else + begin + {$IFDEF DEBUG} + TRACEMS3(j_common_ptr(cinfo), 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); + {$ENDIF} + cinfo^.jpeg_color_space := JCS_YCbCr; { assume it's YCbCr } + end; + end; + { Always guess RGB is proper output colorspace. } + cinfo^.out_color_space := JCS_RGB; + end; + + 4: begin + if (cinfo^.saw_Adobe_marker) then + begin + case (cinfo^.Adobe_transform) of + 0: cinfo^.jpeg_color_space := JCS_CMYK; + 2: cinfo^.jpeg_color_space := JCS_YCCK; + else + begin + WARNMS1(j_common_ptr(cinfo), JWRN_ADOBE_XFORM, cinfo^.Adobe_transform); + cinfo^.jpeg_color_space := JCS_YCCK; { assume it's YCCK } + end; + end; + end + else + begin + { No special markers, assume straight CMYK. } + cinfo^.jpeg_color_space := JCS_CMYK; + end; + cinfo^.out_color_space := JCS_CMYK; + end; + + else + begin + cinfo^.jpeg_color_space := JCS_UNKNOWN; + cinfo^.out_color_space := JCS_UNKNOWN; + end; + end; + + { Set defaults for other decompression parameters. } + cinfo^.scale_num := 1; { 1:1 scaling } + cinfo^.scale_denom := 1; + cinfo^.output_gamma := 1.0; + cinfo^.buffered_image := FALSE; + cinfo^.raw_data_out := FALSE; + cinfo^.dct_method := JDCT_DEFAULT; + cinfo^.do_fancy_upsampling := TRUE; + cinfo^.do_block_smoothing := TRUE; + cinfo^.quantize_colors := FALSE; + { We set these in case application only sets quantize_colors. } + cinfo^.dither_mode := JDITHER_FS; +{$ifdef QUANT_2PASS_SUPPORTED} + cinfo^.two_pass_quantize := TRUE; +{$else} + cinfo^.two_pass_quantize := FALSE; +{$endif} + cinfo^.desired_number_of_colors := 256; + cinfo^.colormap := NIL; + { Initialize for no mode change in buffered-image mode. } + cinfo^.enable_1pass_quant := FALSE; + cinfo^.enable_external_quant := FALSE; + cinfo^.enable_2pass_quant := FALSE; +end; + + +{ Decompression startup: read start of JPEG datastream to see what's there. + Need only initialize JPEG object and supply a data source before calling. + + This routine will read as far as the first SOS marker (ie, actual start of + compressed data), and will save all tables and parameters in the JPEG + object. It will also initialize the decompression parameters to default + values, and finally return JPEG_HEADER_OK. On return, the application may + adjust the decompression parameters and then call jpeg_start_decompress. + (Or, if the application only wanted to determine the image parameters, + the data need not be decompressed. In that case, call jpeg_abort or + jpeg_destroy to release any temporary space.) + If an abbreviated (tables only) datastream is presented, the routine will + return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then + re-use the JPEG object to read the abbreviated image datastream(s). + It is unnecessary (but OK) to call jpeg_abort in this case. + The JPEG_SUSPENDED return code only occurs if the data source module + requests suspension of the decompressor. In this case the application + should load more source data and then re-call jpeg_read_header to resume + processing. + If a non-suspending data source is used and require_image is TRUE, then the + return code need not be inspected since only JPEG_HEADER_OK is possible. + + This routine is now just a front end to jpeg_consume_input, with some + extra error checking. } + +{GLOBAL} +function jpeg_read_header (cinfo : j_decompress_ptr; + require_image : boolean) : int; +var + retcode : int; +begin + if (cinfo^.global_state <> DSTATE_START) and + (cinfo^.global_state <> DSTATE_INHEADER) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + retcode := jpeg_consume_input(cinfo); + + case (retcode) of + JPEG_REACHED_SOS: + retcode := JPEG_HEADER_OK; + JPEG_REACHED_EOI: + begin + if (require_image) then { Complain if application wanted an image } + ERREXIT(j_common_ptr(cinfo), JERR_NO_IMAGE); + { Reset to start state; it would be safer to require the application to + call jpeg_abort, but we can't change it now for compatibility reasons. + A side effect is to free any temporary memory (there shouldn't be any). } + + jpeg_abort(j_common_ptr(cinfo)); { sets state := DSTATE_START } + retcode := JPEG_HEADER_TABLES_ONLY; + end; + JPEG_SUSPENDED: ; { no work } + end; + + jpeg_read_header := retcode; +end; + + +{ Consume data in advance of what the decompressor requires. + This can be called at any time once the decompressor object has + been created and a data source has been set up. + + This routine is essentially a state machine that handles a couple + of critical state-transition actions, namely initial setup and + transition from header scanning to ready-for-start_decompress. + All the actual input is done via the input controller's consume_input + method. } + +{GLOBAL} +function jpeg_consume_input (cinfo : j_decompress_ptr) : int; +var + retcode : int; +begin + retcode := JPEG_SUSPENDED; + + { NB: every possible DSTATE value should be listed in this switch } + + if (cinfo^.global_state) = DSTATE_START then + begin {work around the FALLTHROUGH} + { Start-of-datastream actions: reset appropriate modules } + cinfo^.inputctl^.reset_input_controller (cinfo); + { Initialize application's data source module } + cinfo^.src^.init_source (cinfo); + cinfo^.global_state := DSTATE_INHEADER; + end; + + case (cinfo^.global_state) of + DSTATE_START, + DSTATE_INHEADER: + begin + retcode := cinfo^.inputctl^.consume_input (cinfo); + if (retcode = JPEG_REACHED_SOS) then + begin { Found SOS, prepare to decompress } + { Set up default parameters based on header data } + default_decompress_parms(cinfo); + { Set global state: ready for start_decompress } + cinfo^.global_state := DSTATE_READY; + end; + end; + DSTATE_READY: + { Can't advance past first SOS until start_decompress is called } + retcode := JPEG_REACHED_SOS; + + DSTATE_PRELOAD, + DSTATE_PRESCAN, + DSTATE_SCANNING, + DSTATE_RAW_OK, + DSTATE_BUFIMAGE, + DSTATE_BUFPOST, + DSTATE_STOPPING: + retcode := cinfo^.inputctl^.consume_input (cinfo); + else + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + end; + jpeg_consume_input := retcode; +end; + + +{ Have we finished reading the input file? } + +{GLOBAL} +function jpeg_input_complete (cinfo : j_decompress_ptr) : boolean; +begin + { Check for valid jpeg object } + if (cinfo^.global_state < DSTATE_START) or + (cinfo^.global_state > DSTATE_STOPPING) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + jpeg_input_complete := cinfo^.inputctl^.eoi_reached; +end; + + +{ Is there more than one scan? } + +{GLOBAL} +function jpeg_has_multiple_scans (cinfo : j_decompress_ptr) : boolean; +begin + { Only valid after jpeg_read_header completes } + if (cinfo^.global_state < DSTATE_READY) or + (cinfo^.global_state > DSTATE_STOPPING) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + jpeg_has_multiple_scans := cinfo^.inputctl^.has_multiple_scans; +end; + + +{ Finish JPEG decompression. + + This will normally just verify the file trailer and release temp storage. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_finish_decompress (cinfo : j_decompress_ptr) : boolean; +begin + if ((cinfo^.global_state = DSTATE_SCANNING) or + (cinfo^.global_state = DSTATE_RAW_OK) and (not cinfo^.buffered_image)) then + begin + { Terminate final pass of non-buffered mode } + if (cinfo^.output_scanline < cinfo^.output_height) then + ERREXIT(j_common_ptr(cinfo), JERR_TOO_LITTLE_DATA); + cinfo^.master^.finish_output_pass (cinfo); + cinfo^.global_state := DSTATE_STOPPING; + end + else + if (cinfo^.global_state = DSTATE_BUFIMAGE) then + begin + { Finishing after a buffered-image operation } + cinfo^.global_state := DSTATE_STOPPING; + end + else + if (cinfo^.global_state <> DSTATE_STOPPING) then + begin + { STOPPING := repeat call after a suspension, anything else is error } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + end; + { Read until EOI } + while (not cinfo^.inputctl^.eoi_reached) do + begin + if (cinfo^.inputctl^.consume_input (cinfo) = JPEG_SUSPENDED) then + begin + jpeg_finish_decompress := FALSE; { Suspend, come back later } + exit; + end; + end; + { Do final cleanup } + cinfo^.src^.term_source (cinfo); + { We can use jpeg_abort to release memory and reset global_state } + jpeg_abort(j_common_ptr(cinfo)); + jpeg_finish_decompress := TRUE; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdapistd_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdapistd_del.pas new file mode 100644 index 0000000..2d291b4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdapistd_del.pas @@ -0,0 +1,377 @@ +unit jdapistd_del; + +{ Original : jdapistd.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +{ This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains application interface code for the decompression half + of the JPEG library. These are the "standard" API routines that are + used in the normal full-decompression case. They are not used by a + transcoding-only application. Note that if an application links in + jpeg_start_decompress, it will end up linking in the entire decompressor. + We thus must separate this file from jdapimin.c to avoid linking the + whole decompression library into a transcoder. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jdmaster_del; + +{ Read some scanlines of data from the JPEG decompressor. + + The return value will be the number of lines actually read. + This may be less than the number requested in several cases, + including bottom of image, data source suspension, and operating + modes that emit multiple scanlines at a time. + + Note: we warn about excess calls to jpeg_read_scanlines() since + this likely signals an application programmer error. However, + an oversize buffer (max_lines > scanlines remaining) is not an error. } + +{GLOBAL} +function jpeg_read_scanlines (cinfo : j_decompress_ptr; + scanlines : JSAMPARRAY; + max_lines : JDIMENSION) : JDIMENSION; + + +{ Alternate entry point to read raw data. + Processes exactly one iMCU row per call, unless suspended. } + +{GLOBAL} +function jpeg_read_raw_data (cinfo : j_decompress_ptr; + data : JSAMPIMAGE; + max_lines : JDIMENSION) : JDIMENSION; + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + +{ Initialize for an output pass in buffered-image mode. } + +{GLOBAL} +function jpeg_start_output (cinfo : j_decompress_ptr; + scan_number : int) : boolean; + +{ Finish up after an output pass in buffered-image mode. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_finish_output (cinfo : j_decompress_ptr) : boolean; + +{$endif} { D_MULTISCAN_FILES_SUPPORTED } + +{ Decompression initialization. + jpeg_read_header must be completed before calling this. + + If a multipass operating mode was selected, this will do all but the + last pass, and thus may take a great deal of time. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_start_decompress (cinfo : j_decompress_ptr) : boolean; + + +implementation + +{ Forward declarations } +{LOCAL} +function output_pass_setup (cinfo : j_decompress_ptr) : boolean; forward; + +{ Decompression initialization. + jpeg_read_header must be completed before calling this. + + If a multipass operating mode was selected, this will do all but the + last pass, and thus may take a great deal of time. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_start_decompress (cinfo : j_decompress_ptr) : boolean; +var + retcode : int; +begin + if (cinfo^.global_state = DSTATE_READY) then + begin + { First call: initialize master control, select active modules } + jinit_master_decompress(cinfo); + if (cinfo^.buffered_image) then + begin + { No more work here; expecting jpeg_start_output next } + cinfo^.global_state := DSTATE_BUFIMAGE; + jpeg_start_decompress := TRUE; + exit; + end; + cinfo^.global_state := DSTATE_PRELOAD; + end; + if (cinfo^.global_state = DSTATE_PRELOAD) then + begin + { If file has multiple scans, absorb them all into the coef buffer } + if (cinfo^.inputctl^.has_multiple_scans) then + begin +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + while TRUE do + begin + + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + { Absorb some more input } + retcode := cinfo^.inputctl^.consume_input (cinfo); + if (retcode = JPEG_SUSPENDED) then + begin + jpeg_start_decompress := FALSE; + exit; + end; + if (retcode = JPEG_REACHED_EOI) then + break; + { Advance progress counter if appropriate } + if (cinfo^.progress <> NIL) and + ((retcode = JPEG_ROW_COMPLETED) or (retcode = JPEG_REACHED_SOS)) then + begin + Inc(cinfo^.progress^.pass_counter); + if (cinfo^.progress^.pass_counter >= cinfo^.progress^.pass_limit) then + begin + { jdmaster underestimated number of scans; ratchet up one scan } + Inc(cinfo^.progress^.pass_limit, long(cinfo^.total_iMCU_rows)); + end; + end; + end; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} { D_MULTISCAN_FILES_SUPPORTED } + end; + cinfo^.output_scan_number := cinfo^.input_scan_number; + end + else + if (cinfo^.global_state <> DSTATE_PRESCAN) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + { Perform any dummy output passes, and set up for the final pass } + jpeg_start_decompress := output_pass_setup(cinfo); +end; + + +{ Set up for an output pass, and perform any dummy pass(es) needed. + Common subroutine for jpeg_start_decompress and jpeg_start_output. + Entry: global_state := DSTATE_PRESCAN only if previously suspended. + Exit: If done, returns TRUE and sets global_state for proper output mode. + If suspended, returns FALSE and sets global_state := DSTATE_PRESCAN. } + +{LOCAL} +function output_pass_setup (cinfo : j_decompress_ptr) : boolean; +var + last_scanline : JDIMENSION; +begin + if (cinfo^.global_state <> DSTATE_PRESCAN) then + begin + { First call: do pass setup } + cinfo^.master^.prepare_for_output_pass (cinfo); + cinfo^.output_scanline := 0; + cinfo^.global_state := DSTATE_PRESCAN; + end; + { Loop over any required dummy passes } + while (cinfo^.master^.is_dummy_pass) do + begin +{$ifdef QUANT_2PASS_SUPPORTED} + { Crank through the dummy pass } + while (cinfo^.output_scanline < cinfo^.output_height) do + begin + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long (cinfo^.output_scanline); + cinfo^.progress^.pass_limit := long (cinfo^.output_height); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + { Process some data } + last_scanline := cinfo^.output_scanline; + cinfo^.main^.process_data (cinfo, JSAMPARRAY(NIL), + cinfo^.output_scanline, {var} + JDIMENSION(0)); + if (cinfo^.output_scanline = last_scanline) then + begin + output_pass_setup := FALSE; { No progress made, must suspend } + exit; + end; + end; + { Finish up dummy pass, and set up for another one } + cinfo^.master^.finish_output_pass (cinfo); + cinfo^.master^.prepare_for_output_pass (cinfo); + cinfo^.output_scanline := 0; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} { QUANT_2PASS_SUPPORTED } + end; + { Ready for application to drive output pass through + jpeg_read_scanlines or jpeg_read_raw_data. } + if cinfo^.raw_data_out then + cinfo^.global_state := DSTATE_RAW_OK + else + cinfo^.global_state := DSTATE_SCANNING; + output_pass_setup := TRUE; +end; + + +{ Read some scanlines of data from the JPEG decompressor. + + The return value will be the number of lines actually read. + This may be less than the number requested in several cases, + including bottom of image, data source suspension, and operating + modes that emit multiple scanlines at a time. + + Note: we warn about excess calls to jpeg_read_scanlines() since + this likely signals an application programmer error. However, + an oversize buffer (max_lines > scanlines remaining) is not an error. } + +{GLOBAL} +function jpeg_read_scanlines (cinfo : j_decompress_ptr; + scanlines : JSAMPARRAY; + max_lines : JDIMENSION) : JDIMENSION; +var + row_ctr : JDIMENSION; +begin + if (cinfo^.global_state <> DSTATE_SCANNING) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + if (cinfo^.output_scanline >= cinfo^.output_height) then + begin + WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA); + jpeg_read_scanlines := 0; + exit; + end; + + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long (cinfo^.output_scanline); + cinfo^.progress^.pass_limit := long (cinfo^.output_height); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + + { Process some data } + row_ctr := 0; + cinfo^.main^.process_data (cinfo, scanlines, {var}row_ctr, max_lines); + Inc(cinfo^.output_scanline, row_ctr); + jpeg_read_scanlines := row_ctr; +end; + + +{ Alternate entry point to read raw data. + Processes exactly one iMCU row per call, unless suspended. } + +{GLOBAL} +function jpeg_read_raw_data (cinfo : j_decompress_ptr; + data : JSAMPIMAGE; + max_lines : JDIMENSION) : JDIMENSION; +var + lines_per_iMCU_row : JDIMENSION; +begin + if (cinfo^.global_state <> DSTATE_RAW_OK) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + if (cinfo^.output_scanline >= cinfo^.output_height) then + begin + WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA); + jpeg_read_raw_data := 0; + exit; + end; + + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long (cinfo^.output_scanline); + cinfo^.progress^.pass_limit := long (cinfo^.output_height); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + + { Verify that at least one iMCU row can be returned. } + lines_per_iMCU_row := cinfo^.max_v_samp_factor * cinfo^.min_DCT_scaled_size; + if (max_lines < lines_per_iMCU_row) then + ERREXIT(j_common_ptr(cinfo), JERR_BUFFER_SIZE); + + { Decompress directly into user's buffer. } + if (cinfo^.coef^.decompress_data (cinfo, data) = 0) then + begin + jpeg_read_raw_data := 0; { suspension forced, can do nothing more } + exit; + end; + + { OK, we processed one iMCU row. } + Inc(cinfo^.output_scanline, lines_per_iMCU_row); + jpeg_read_raw_data := lines_per_iMCU_row; +end; + + +{ Additional entry points for buffered-image mode. } + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + +{ Initialize for an output pass in buffered-image mode. } + +{GLOBAL} +function jpeg_start_output (cinfo : j_decompress_ptr; + scan_number : int) : boolean; +begin + if (cinfo^.global_state <> DSTATE_BUFIMAGE) and + (cinfo^.global_state <> DSTATE_PRESCAN) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + { Limit scan number to valid range } + if (scan_number <= 0) then + scan_number := 1; + if (cinfo^.inputctl^.eoi_reached) and + (scan_number > cinfo^.input_scan_number) then + scan_number := cinfo^.input_scan_number; + cinfo^.output_scan_number := scan_number; + { Perform any dummy output passes, and set up for the real pass } + jpeg_start_output := output_pass_setup(cinfo); +end; + + +{ Finish up after an output pass in buffered-image mode. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_finish_output (cinfo : j_decompress_ptr) : boolean; +begin + if ((cinfo^.global_state = DSTATE_SCANNING) or + (cinfo^.global_state = DSTATE_RAW_OK) and cinfo^.buffered_image) then + begin + { Terminate this pass. } + { We do not require the whole pass to have been completed. } + cinfo^.master^.finish_output_pass (cinfo); + cinfo^.global_state := DSTATE_BUFPOST; + end + else + if (cinfo^.global_state <> DSTATE_BUFPOST) then + begin + { BUFPOST := repeat call after a suspension, anything else is error } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + end; + { Read markers looking for SOS or EOI } + while (cinfo^.input_scan_number <= cinfo^.output_scan_number) and + (not cinfo^.inputctl^.eoi_reached) do + begin + if (cinfo^.inputctl^.consume_input (cinfo) = JPEG_SUSPENDED) then + begin + jpeg_finish_output := FALSE; { Suspend, come back later } + exit; + end; + end; + cinfo^.global_state := DSTATE_BUFIMAGE; + jpeg_finish_output := TRUE; +end; + +{$endif} { D_MULTISCAN_FILES_SUPPORTED } + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdatadst_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdatadst_del.pas new file mode 100644 index 0000000..ba10154 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdatadst_del.pas @@ -0,0 +1,172 @@ +Unit jdatadst_del; + +{ This file contains compression data destination routines for the case of + emitting JPEG data to a file (or any stdio stream). While these routines + are sufficient for most applications, some will want to use a different + destination manager. + IMPORTANT: we assume that fwrite() will correctly transcribe an array of + JOCTETs into 8-bit-wide elements on external storage. If char is wider + than 8 bits on your machine, you may need to do some tweaking. } + +{ Original : jdatadst.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ this is not a core library module, so it doesn't define JPEG_INTERNALS } +uses + jmorecfg_del, + jpeglib_del, + jinclude_del, + jdeferr_del, + jerror_del; + +{ Prepare for output to a stdio stream. + The caller must have already opened the stream, and is responsible + for closing it after finishing compression. } + +{GLOBAL} +procedure jpeg_stdio_dest (cinfo : j_compress_ptr; outfile : FILEptr); + +implementation + +{ Expanded data destination object for stdio output } + +type + my_dest_ptr = ^my_destination_mgr; + my_destination_mgr = record + pub : jpeg_destination_mgr; { public fields } + + outfile : FILEPTR; { target stream } + buffer : JOCTET_FIELD_PTR; { start of buffer } + end; {my_destination_mgr;} + + +const + OUTPUT_BUF_SIZE = 4096; { choose an efficiently fwrite'able size } + + +{ Initialize destination --- called by jpeg_start_compress + before any data is actually written. } + +{METHODDEF} +procedure init_destination (cinfo : j_compress_ptr); +var + dest : my_dest_ptr; +begin + dest := my_dest_ptr(cinfo^.dest); + + { Allocate the output buffer --- it will be released when done with image } + dest^.buffer := JOCTET_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + OUTPUT_BUF_SIZE * SIZEOF(JOCTET)) ); + + dest^.pub.next_output_byte := JOCTETptr(dest^.buffer); + dest^.pub.free_in_buffer := OUTPUT_BUF_SIZE; +end; + + +{ Empty the output buffer --- called whenever buffer fills up. + + In typical applications, this should write the entire output buffer + (ignoring the current state of next_output_byte & free_in_buffer), + reset the pointer & count to the start of the buffer, and return TRUE + indicating that the buffer has been dumped. + + In applications that need to be able to suspend compression due to output + overrun, a FALSE return indicates that the buffer cannot be emptied now. + In this situation, the compressor will return to its caller (possibly with + an indication that it has not accepted all the supplied scanlines). The + application should resume compression after it has made more room in the + output buffer. Note that there are substantial restrictions on the use of + suspension --- see the documentation. + + When suspending, the compressor will back up to a convenient restart point + (typically the start of the current MCU). next_output_byte & free_in_buffer + indicate where the restart point will be if the current call returns FALSE. + Data beyond this point will be regenerated after resumption, so do not + write it out when emptying the buffer externally. } + +{METHODDEF} +function empty_output_buffer (cinfo : j_compress_ptr) : boolean; +var + dest : my_dest_ptr; +begin + dest := my_dest_ptr(cinfo^.dest); + + if (JFWRITE(dest^.outfile, dest^.buffer, OUTPUT_BUF_SIZE) <> + size_t(OUTPUT_BUF_SIZE)) then + ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE); + + dest^.pub.next_output_byte := JOCTETptr(dest^.buffer); + dest^.pub.free_in_buffer := OUTPUT_BUF_SIZE; + + empty_output_buffer := TRUE; +end; + + +{ Terminate destination --- called by jpeg_finish_compress + after all data has been written. Usually needs to flush buffer. + + NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + application must deal with any cleanup that should happen even + for error exit. } + +{METHODDEF} +procedure term_destination (cinfo : j_compress_ptr); +var + dest : my_dest_ptr; + datacount : size_t; +begin + dest := my_dest_ptr (cinfo^.dest); + datacount := OUTPUT_BUF_SIZE - dest^.pub.free_in_buffer; + + { Write any data remaining in the buffer } + if (datacount > 0) then + begin + if (JFWRITE(dest^.outfile, dest^.buffer, datacount) <> datacount) then + ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE); + end; + {fflush(dest^.outfile^);} + + { Make sure we wrote the output file OK } + {if (ferror(dest^.outfile)) + ERREXIT(cinfo, JERR_FILE_WRITE);} + if IOresult <> 0 then + ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE); +end; + + +{ Prepare for output to a stdio stream. + The caller must have already opened the stream, and is responsible + for closing it after finishing compression. } + +{GLOBAL} +procedure jpeg_stdio_dest (cinfo : j_compress_ptr; outfile : FILEptr); +var + dest : my_dest_ptr; +begin + { The destination object is made permanent so that multiple JPEG images + can be written to the same file without re-executing jpeg_stdio_dest. + This makes it dangerous to use this manager and a different destination + manager serially with the same JPEG object, because their private object + sizes may be different. Caveat programmer. } + + if (cinfo^.dest = NIL) then + begin { first time for this JPEG object? } + cinfo^.dest := jpeg_destination_mgr_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + SIZEOF(my_destination_mgr)) ); + end; + + dest := my_dest_ptr (cinfo^.dest); + dest^.pub.init_destination := init_destination; + dest^.pub.empty_output_buffer := empty_output_buffer; + dest^.pub.term_destination := term_destination; + dest^.outfile := outfile; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdatasrc_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdatasrc_del.pas new file mode 100644 index 0000000..fe41bea --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdatasrc_del.pas @@ -0,0 +1,225 @@ +unit jdatasrc_del; + +{ This file contains decompression data source routines for the case of + reading JPEG data from a file (or any stdio stream). While these routines + are sufficient for most applications, some will want to use a different + source manager. + IMPORTANT: we assume that fread() will correctly transcribe an array of + JOCTETs from 8-bit-wide elements on external storage. If char is wider + than 8 bits on your machine, you may need to do some tweaking. } + +{ jdatasrc.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ this is not a core library module, so it doesn't define JPEG_INTERNALS } +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdmarker_del, + jdeferr_del, + jerror_del; + + +{ Prepare for input from a stdio stream. + The caller must have already opened the stream, and is responsible + for closing it after finishing decompression. } + +{GLOBAL} +procedure jpeg_stdio_src (cinfo : j_decompress_ptr; infile : FILEptr); + +implementation + +{ Expanded data source object for stdio input } + +type + my_src_ptr = ^my_source_mgr; + my_source_mgr = record + pub : jpeg_source_mgr; { public fields } + + infile : FILEPTR; { source stream } + buffer : JOCTET_FIELD_PTR; { start of buffer } + start_of_file : boolean; { have we gotten any data yet? } + end; {my_source_mgr;} + +const + INPUT_BUF_SIZE = 4096; { choose an efficiently fread'able size } + + +{ Initialize source --- called by jpeg_read_header + before any data is actually read. } + +{METHODDEF} +procedure init_source (cinfo : j_decompress_ptr); +var + src : my_src_ptr; +begin + src := my_src_ptr (cinfo^.src); + + { We reset the empty-input-file flag for each image, + but we don't clear the input buffer. + This is correct behavior for reading a series of images from one source. } + src^.start_of_file := TRUE; +end; + + +{ Fill the input buffer --- called whenever buffer is emptied. + + In typical applications, this should read fresh data into the buffer + (ignoring the current state of next_input_byte & bytes_in_buffer), + reset the pointer & count to the start of the buffer, and return TRUE + indicating that the buffer has been reloaded. It is not necessary to + fill the buffer entirely, only to obtain at least one more byte. + + There is no such thing as an EOF return. If the end of the file has been + reached, the routine has a choice of ERREXIT() or inserting fake data into + the buffer. In most cases, generating a warning message and inserting a + fake EOI marker is the best course of action --- this will allow the + decompressor to output however much of the image is there. However, + the resulting error message is misleading if the real problem is an empty + input file, so we handle that case specially. + + In applications that need to be able to suspend compression due to input + not being available yet, a FALSE return indicates that no more data can be + obtained right now, but more may be forthcoming later. In this situation, + the decompressor will return to its caller (with an indication of the + number of scanlines it has read, if any). The application should resume + decompression after it has loaded more data into the input buffer. Note + that there are substantial restrictions on the use of suspension --- see + the documentation. + + When suspending, the decompressor will back up to a convenient restart point + (typically the start of the current MCU). next_input_byte & bytes_in_buffer + indicate where the restart point will be if the current call returns FALSE. + Data beyond this point must be rescanned after resumption, so move it to + the front of the buffer rather than discarding it. } + +{METHODDEF} +function fill_input_buffer (cinfo : j_decompress_ptr) : boolean; +var + src : my_src_ptr; + nbytes : size_t; +begin + src := my_src_ptr(cinfo^.src); + nbytes := JFREAD(src^.infile, src^.buffer, INPUT_BUF_SIZE); + + if (nbytes <= 0) then + begin + if (src^.start_of_file) then { Treat empty input file as fatal error } + ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EMPTY); + WARNMS(j_common_ptr(cinfo), JWRN_JPEG_EOF); + { Insert a fake EOI marker } + src^.buffer^[0] := JOCTET ($FF); + src^.buffer^[1] := JOCTET (JPEG_EOI); + nbytes := 2; + end; + + src^.pub.next_input_byte := JOCTETptr(src^.buffer); + src^.pub.bytes_in_buffer := nbytes; + src^.start_of_file := FALSE; + + fill_input_buffer := TRUE; +end; + + +{ Skip data --- used to skip over a potentially large amount of + uninteresting data (such as an APPn marker). + + Writers of suspendable-input applications must note that skip_input_data + is not granted the right to give a suspension return. If the skip extends + beyond the data currently in the buffer, the buffer can be marked empty so + that the next read will cause a fill_input_buffer call that can suspend. + Arranging for additional bytes to be discarded before reloading the input + buffer is the application writer's problem. } + +{METHODDEF} +procedure skip_input_data (cinfo : j_decompress_ptr; + num_bytes : long); +var + src : my_src_ptr; +begin + src := my_src_ptr (cinfo^.src); + + { Just a dumb implementation for now. Could use fseek() except + it doesn't work on pipes. Not clear that being smart is worth + any trouble anyway --- large skips are infrequent. } + + if (num_bytes > 0) then + begin + while (num_bytes > long(src^.pub.bytes_in_buffer)) do + begin + Dec(num_bytes, long(src^.pub.bytes_in_buffer)); + {void} fill_input_buffer(cinfo); + { note we assume that fill_input_buffer will never return FALSE, + so suspension need not be handled. } + end; + Inc( src^.pub.next_input_byte, size_t(num_bytes) ); + Dec( src^.pub.bytes_in_buffer, size_t(num_bytes) ); + end; +end; + + +{ An additional method that can be provided by data source modules is the + resync_to_restart method for error recovery in the presence of RST markers. + For the moment, this source module just uses the default resync method + provided by the JPEG library. That method assumes that no backtracking + is possible. } + + +{ Terminate source --- called by jpeg_finish_decompress + after all data has been read. Often a no-op. + + NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + application must deal with any cleanup that should happen even + for error exit. } + +{METHODDEF} +procedure term_source (cinfo : j_decompress_ptr); +begin + { no work necessary here } +end; + + +{ Prepare for input from a stdio stream. + The caller must have already opened the stream, and is responsible + for closing it after finishing decompression. } + +{GLOBAL} +procedure jpeg_stdio_src (cinfo : j_decompress_ptr; infile : FILEptr); +var + src : my_src_ptr; +begin + { The source object and input buffer are made permanent so that a series + of JPEG images can be read from the same file by calling jpeg_stdio_src + only before the first one. (If we discarded the buffer at the end of + one image, we'd likely lose the start of the next one.) + This makes it unsafe to use this manager and a different source + manager serially with the same JPEG object. Caveat programmer. } + + if (cinfo^.src = NIL) then + begin { first time for this JPEG object? } + cinfo^.src := jpeg_source_mgr_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + SIZEOF(my_source_mgr)) ); + src := my_src_ptr (cinfo^.src); + src^.buffer := JOCTET_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + INPUT_BUF_SIZE * SIZEOF(JOCTET)) ); + end; + + src := my_src_ptr (cinfo^.src); + src^.pub.init_source := init_source; + src^.pub.fill_input_buffer := fill_input_buffer; + src^.pub.skip_input_data := skip_input_data; + src^.pub.resync_to_restart := jpeg_resync_to_restart; { use default method } + src^.pub.term_source := term_source; + src^.infile := infile; + src^.pub.bytes_in_buffer := 0; { forces fill_input_buffer on first read } + src^.pub.next_input_byte := NIL; { until buffer loaded } +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdcoefct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdcoefct_del.pas new file mode 100644 index 0000000..e8acba3 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdcoefct_del.pas @@ -0,0 +1,898 @@ +unit jdcoefct_del; + +{ This file contains the coefficient buffer controller for decompression. + This controller is the top level of the JPEG decompressor proper. + The coefficient buffer lies between entropy decoding and inverse-DCT steps. + + In buffered-image mode, this controller is the interface between + input-oriented processing and output-oriented processing. + Also, the input side (only) is used when reading a file for transcoding. } + +{ Original: jdcoefct.c ; Copyright (C) 1994-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +{$I jconfig_del.inc} + +interface + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jutils_del, + jpeglib_del; + + +{GLOBAL} +procedure jinit_d_coef_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); + + +implementation + + +{ Block smoothing is only applicable for progressive JPEG, so: } +{$ifndef D_PROGRESSIVE_SUPPORTED} +{$undef BLOCK_SMOOTHING_SUPPORTED} +{$endif} + +{ Private buffer controller object } + +{$ifdef BLOCK_SMOOTHING_SUPPORTED} +const + SAVED_COEFS = 6; { we save coef_bits[0..5] } +type + Latch = array[0..SAVED_COEFS-1] of int; + Latch_ptr = ^Latch; +{$endif} + +type + my_coef_ptr = ^my_coef_controller; + my_coef_controller = record + pub : jpeg_d_coef_controller; { public fields } + + { These variables keep track of the current location of the input side. } + { cinfo^.input_iMCU_row is also used for this. } + MCU_ctr : JDIMENSION; { counts MCUs processed in current row } + MCU_vert_offset : int; { counts MCU rows within iMCU row } + MCU_rows_per_iMCU_row : int; { number of such rows needed } + + { The output side's location is represented by cinfo^.output_iMCU_row. } + + { In single-pass modes, it's sufficient to buffer just one MCU. + We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, + and let the entropy decoder write into that workspace each time. + (On 80x86, the workspace is FAR even though it's not really very big; + this is to keep the module interfaces unchanged when a large coefficient + buffer is necessary.) + In multi-pass modes, this array points to the current MCU's blocks + within the virtual arrays; it is used only by the input side. } + + MCU_buffer : array[0..D_MAX_BLOCKS_IN_MCU-1] of JBLOCKROW; + + {$ifdef D_MULTISCAN_FILES_SUPPORTED} + { In multi-pass modes, we need a virtual block array for each component. } + whole_image : jvirt_barray_tbl; + {$endif} + + {$ifdef BLOCK_SMOOTHING_SUPPORTED} + { When doing block smoothing, we latch coefficient Al values here } + coef_bits_latch : Latch_Ptr; + {$endif} + end; + +{ Forward declarations } +{METHODDEF} +function decompress_onepass (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; forward; +{$ifdef D_MULTISCAN_FILES_SUPPORTED} +{METHODDEF} +function decompress_data (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; forward; +{$endif} +{$ifdef BLOCK_SMOOTHING_SUPPORTED} +{LOCAL} +function smoothing_ok (cinfo : j_decompress_ptr) : boolean; forward; + +{METHODDEF} +function decompress_smooth_data (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; forward; +{$endif} + + +{LOCAL} +procedure start_iMCU_row (cinfo : j_decompress_ptr); +{ Reset within-iMCU-row counters for a new row (input side) } +var + coef : my_coef_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + { In an interleaved scan, an MCU row is the same as an iMCU row. + In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + But at the bottom of the image, process only what's left. } + + if (cinfo^.comps_in_scan > 1) then + begin + coef^.MCU_rows_per_iMCU_row := 1; + end + else + begin + if (cinfo^.input_iMCU_row < (cinfo^.total_iMCU_rows-1)) then + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.v_samp_factor + else + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.last_row_height; + end; + + coef^.MCU_ctr := 0; + coef^.MCU_vert_offset := 0; +end; + + +{ Initialize for an input processing pass. } + +{METHODDEF} +procedure start_input_pass (cinfo : j_decompress_ptr); +begin + cinfo^.input_iMCU_row := 0; + start_iMCU_row(cinfo); +end; + + +{ Initialize for an output processing pass. } + +{METHODDEF} +procedure start_output_pass (cinfo : j_decompress_ptr); +var + coef : my_coef_ptr; +begin +{$ifdef BLOCK_SMOOTHING_SUPPORTED} + coef := my_coef_ptr (cinfo^.coef); + + { If multipass, check to see whether to use block smoothing on this pass } + if (coef^.pub.coef_arrays <> NIL) then + begin + if (cinfo^.do_block_smoothing) and smoothing_ok(cinfo) then + coef^.pub.decompress_data := decompress_smooth_data + else + coef^.pub.decompress_data := decompress_data; + end; +{$endif} + cinfo^.output_iMCU_row := 0; +end; + + +{ Decompress and return some data in the single-pass case. + Always attempts to emit one fully interleaved MCU row ("iMCU" row). + Input and output must run in lockstep since we have only a one-MCU buffer. + Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + + NB: output_buf contains a plane for each component in image, + which we index according to the component's SOF position.} + +{METHODDEF} +function decompress_onepass (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; +var + coef : my_coef_ptr; + MCU_col_num : JDIMENSION; { index of current MCU within row } + last_MCU_col : JDIMENSION; + last_iMCU_row : JDIMENSION; + blkn, ci, xindex, yindex, yoffset, useful_width : int; + output_ptr : JSAMPARRAY; + start_col, output_col : JDIMENSION; + compptr : jpeg_component_info_ptr; + inverse_DCT : inverse_DCT_method_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + last_MCU_col := cinfo^.MCUs_per_row - 1; + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + { Loop to process as much as one whole iMCU row } + for yoffset := coef^.MCU_vert_offset to pred(coef^.MCU_rows_per_iMCU_row) do + begin + for MCU_col_num := coef^.MCU_ctr to last_MCU_col do + begin + { Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. } + jzero_far( coef^.MCU_buffer[0], + size_t (cinfo^.blocks_in_MCU * SIZEOF(JBLOCK))); + if (not cinfo^.entropy^.decode_mcu (cinfo, coef^.MCU_buffer)) then + begin + { Suspension forced; update state counters and exit } + coef^.MCU_vert_offset := yoffset; + coef^.MCU_ctr := MCU_col_num; + decompress_onepass := JPEG_SUSPENDED; + exit; + end; + { Determine where data should go in output_buf and do the IDCT thing. + We skip dummy blocks at the right and bottom edges (but blkn gets + incremented past them!). Note the inner loop relies on having + allocated the MCU_buffer[] blocks sequentially. } + + blkn := 0; { index of current DCT block within MCU } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { Don't bother to IDCT an uninteresting component. } + if (not compptr^.component_needed) then + begin + Inc(blkn, compptr^.MCU_blocks); + continue; + end; + inverse_DCT := cinfo^.idct^.inverse_DCT[compptr^.component_index]; + if (MCU_col_num < last_MCU_col) then + useful_width := compptr^.MCU_width + else + useful_width := compptr^.last_col_width; + + output_ptr := JSAMPARRAY(@ output_buf^[compptr^.component_index]^ + [yoffset * compptr^.DCT_scaled_size]); + start_col := MCU_col_num * compptr^.MCU_sample_width; + for yindex := 0 to pred(compptr^.MCU_height) do + begin + if (cinfo^.input_iMCU_row < last_iMCU_row) or + (yoffset+yindex < compptr^.last_row_height) then + begin + output_col := start_col; + for xindex := 0 to pred(useful_width) do + begin + inverse_DCT (cinfo, compptr, + JCOEFPTR(coef^.MCU_buffer[blkn+xindex]), + output_ptr, output_col); + Inc(output_col, compptr^.DCT_scaled_size); + end; + end; + Inc(blkn, compptr^.MCU_width); + Inc(JSAMPROW_PTR(output_ptr), compptr^.DCT_scaled_size); + end; + end; + end; + { Completed an MCU row, but perhaps not an iMCU row } + coef^.MCU_ctr := 0; + end; + { Completed the iMCU row, advance counters for next one } + Inc(cinfo^.output_iMCU_row); + + Inc(cinfo^.input_iMCU_row); + if (cinfo^.input_iMCU_row < cinfo^.total_iMCU_rows) then + begin + start_iMCU_row(cinfo); + decompress_onepass := JPEG_ROW_COMPLETED; + exit; + end; + { Completed the scan } + cinfo^.inputctl^.finish_input_pass (cinfo); + decompress_onepass := JPEG_SCAN_COMPLETED; +end; + +{ Dummy consume-input routine for single-pass operation. } + +{METHODDEF} +function dummy_consume_data (cinfo : j_decompress_ptr) : int; +begin + dummy_consume_data := JPEG_SUSPENDED; { Always indicate nothing was done } +end; + + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + +{ Consume input data and store it in the full-image coefficient buffer. + We read as much as one fully interleaved MCU row ("iMCU" row) per call, + ie, v_samp_factor block rows for each component in the scan. + Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.} + +{METHODDEF} +function consume_data (cinfo : j_decompress_ptr) : int; +var + coef : my_coef_ptr; + MCU_col_num : JDIMENSION; { index of current MCU within row } + blkn, ci, xindex, yindex, yoffset : int; + start_col : JDIMENSION; + buffer : array[0..MAX_COMPS_IN_SCAN-1] of JBLOCKARRAY; + buffer_ptr : JBLOCKROW; + compptr : jpeg_component_info_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + { Align the virtual buffers for the components used in this scan. } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + buffer[ci] := cinfo^.mem^.access_virt_barray + (j_common_ptr (cinfo), coef^.whole_image[compptr^.component_index], + cinfo^.input_iMCU_row * compptr^.v_samp_factor, + JDIMENSION (compptr^.v_samp_factor), TRUE); + { Note: entropy decoder expects buffer to be zeroed, + but this is handled automatically by the memory manager + because we requested a pre-zeroed array. } + + end; + + { Loop to process one whole iMCU row } + for yoffset := coef^.MCU_vert_offset to pred(coef^.MCU_rows_per_iMCU_row) do + begin + for MCU_col_num := coef^.MCU_ctr to pred(cinfo^.MCUs_per_row) do + begin + { Construct list of pointers to DCT blocks belonging to this MCU } + blkn := 0; { index of current DCT block within MCU } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + start_col := MCU_col_num * compptr^.MCU_width; + for yindex := 0 to pred(compptr^.MCU_height) do + begin +{$warnings off} + buffer_ptr := JBLOCKROW(@ buffer[ci]^[yindex+yoffset]^[start_col]); + for xindex := 0 to pred(compptr^.MCU_width) do + begin + coef^.MCU_buffer[blkn] := buffer_ptr; + Inc(blkn); + Inc(JBLOCK_PTR(buffer_ptr)); + end; + end; + end; + { Try to fetch the MCU. } + if (not cinfo^.entropy^.decode_mcu (cinfo, coef^.MCU_buffer)) then + begin + { Suspension forced; update state counters and exit } + coef^.MCU_vert_offset := yoffset; + coef^.MCU_ctr := MCU_col_num; + consume_data := JPEG_SUSPENDED; + exit; + end; + end; + { Completed an MCU row, but perhaps not an iMCU row } + coef^.MCU_ctr := 0; + end; + { Completed the iMCU row, advance counters for next one } + Inc(cinfo^.input_iMCU_row); + if (cinfo^.input_iMCU_row < cinfo^.total_iMCU_rows) then + begin + start_iMCU_row(cinfo); + consume_data := JPEG_ROW_COMPLETED; + exit; + end; + { Completed the scan } + cinfo^.inputctl^.finish_input_pass (cinfo); + consume_data := JPEG_SCAN_COMPLETED; +end; +{$warnings on} + +{ Decompress and return some data in the multi-pass case. + Always attempts to emit one fully interleaved MCU row ("iMCU" row). + Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + + NB: output_buf contains a plane for each component in image. } + +{METHODDEF} +function decompress_data (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; +var + coef : my_coef_ptr; + last_iMCU_row : JDIMENSION; + block_num : JDIMENSION; + ci, block_row, block_rows : int; + buffer : JBLOCKARRAY; + buffer_ptr : JBLOCKROW; + output_ptr : JSAMPARRAY; + output_col : JDIMENSION; + compptr : jpeg_component_info_ptr; + inverse_DCT : inverse_DCT_method_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + { Force some input to be done if we are getting ahead of the input. } + while (cinfo^.input_scan_number < cinfo^.output_scan_number) or + ((cinfo^.input_scan_number = cinfo^.output_scan_number) and + (cinfo^.input_iMCU_row <= cinfo^.output_iMCU_row)) do + begin + if (cinfo^.inputctl^.consume_input(cinfo) = JPEG_SUSPENDED) then + begin + decompress_data := JPEG_SUSPENDED; + exit; + end; + end; + + { OK, output from the virtual arrays. } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Don't bother to IDCT an uninteresting component. } + if (not compptr^.component_needed) then + continue; + { Align the virtual buffer for this component. } + buffer := cinfo^.mem^.access_virt_barray + (j_common_ptr (cinfo), coef^.whole_image[ci], + cinfo^.output_iMCU_row * compptr^.v_samp_factor, + JDIMENSION (compptr^.v_samp_factor), FALSE); + { Count non-dummy DCT block rows in this iMCU row. } + if (cinfo^.output_iMCU_row < last_iMCU_row) then + block_rows := compptr^.v_samp_factor + else + begin + { NB: can't use last_row_height here; it is input-side-dependent! } + block_rows := int(compptr^.height_in_blocks mod compptr^.v_samp_factor); + if (block_rows = 0) then + block_rows := compptr^.v_samp_factor; + end; + inverse_DCT := cinfo^.idct^.inverse_DCT[ci]; + output_ptr := output_buf^[ci]; + { Loop over all DCT blocks to be processed. } + for block_row := 0 to pred(block_rows) do + begin + buffer_ptr := buffer^[block_row]; + output_col := 0; + for block_num := 0 to pred(compptr^.width_in_blocks) do + begin + inverse_DCT (cinfo, compptr, JCOEFPTR (buffer_ptr), + output_ptr, output_col); + Inc(JBLOCK_PTR(buffer_ptr)); + Inc(output_col, compptr^.DCT_scaled_size); + end; + Inc(JSAMPROW_PTR(output_ptr), compptr^.DCT_scaled_size); + end; + Inc(compptr); + end; + + Inc(cinfo^.output_iMCU_row); + if (cinfo^.output_iMCU_row < cinfo^.total_iMCU_rows) then + begin + decompress_data := JPEG_ROW_COMPLETED; + exit; + end; + decompress_data := JPEG_SCAN_COMPLETED; +end; + +{$endif} { D_MULTISCAN_FILES_SUPPORTED } + + +{$ifdef BLOCK_SMOOTHING_SUPPORTED} + +{ This code applies interblock smoothing as described by section K.8 + of the JPEG standard: the first 5 AC coefficients are estimated from + the DC values of a DCT block and its 8 neighboring blocks. + We apply smoothing only for progressive JPEG decoding, and only if + the coefficients it can estimate are not yet known to full precision. } + +{ Natural-order array positions of the first 5 zigzag-order coefficients } +const + Q01_POS = 1; + Q10_POS = 8; + Q20_POS = 16; + Q11_POS = 9; + Q02_POS = 2; + +{ Determine whether block smoothing is applicable and safe. + We also latch the current states of the coef_bits[] entries for the + AC coefficients; otherwise, if the input side of the decompressor + advances into a new scan, we might think the coefficients are known + more accurately than they really are. } + +{LOCAL} +function smoothing_ok (cinfo : j_decompress_ptr) : boolean; +var + coef : my_coef_ptr; + smoothing_useful : boolean; + ci, coefi : int; + compptr : jpeg_component_info_ptr; + qtable : JQUANT_TBL_PTR; + coef_bits : coef_bits_ptr; + coef_bits_latch : Latch_Ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + smoothing_useful := FALSE; + + if (not cinfo^.progressive_mode) or (cinfo^.coef_bits = NIL) then + begin + smoothing_ok := FALSE; + exit; + end; + + { Allocate latch area if not already done } + if (coef^.coef_bits_latch = NIL) then + coef^.coef_bits_latch := Latch_Ptr( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + cinfo^.num_components * + (SAVED_COEFS * SIZEOF(int))) ); + coef_bits_latch := (coef^.coef_bits_latch); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { All components' quantization values must already be latched. } + qtable := compptr^.quant_table; + if (qtable = NIL) then + begin + smoothing_ok := FALSE; + exit; + end; + { Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. } + if (qtable^.quantval[0] = 0) or + (qtable^.quantval[Q01_POS] = 0) or + (qtable^.quantval[Q10_POS] = 0) or + (qtable^.quantval[Q20_POS] = 0) or + (qtable^.quantval[Q11_POS] = 0) or + (qtable^.quantval[Q02_POS] = 0) then + begin + smoothing_ok := FALSE; + exit; + end; + { DC values must be at least partly known for all components. } + coef_bits := @cinfo^.coef_bits^[ci]; { Nomssi } + if (coef_bits^[0] < 0) then + begin + smoothing_ok := FALSE; + exit; + end; + { Block smoothing is helpful if some AC coefficients remain inaccurate. } + for coefi := 1 to 5 do + begin + coef_bits_latch^[coefi] := coef_bits^[coefi]; + if (coef_bits^[coefi] <> 0) then + smoothing_useful := TRUE; + end; + Inc(coef_bits_latch {SAVED_COEFS}); + Inc(compptr); + end; + + smoothing_ok := smoothing_useful; +end; + + +{ Variant of decompress_data for use when doing block smoothing. } + +{METHODDEF} +function decompress_smooth_data (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; +var + coef : my_coef_ptr; + last_iMCU_row : JDIMENSION; + block_num, last_block_column : JDIMENSION; + ci, block_row, block_rows, access_rows : int; + buffer : JBLOCKARRAY; + buffer_ptr, prev_block_row, next_block_row : JBLOCKROW; + output_ptr : JSAMPARRAY; + output_col : JDIMENSION; + compptr : jpeg_component_info_ptr; + inverse_DCT : inverse_DCT_method_ptr; + first_row, last_row : boolean; + workspace : JBLOCK; + coef_bits : Latch_Ptr; { coef_bits_ptr; } + quanttbl : JQUANT_TBL_PTR; + Q00,Q01,Q02,Q10,Q11,Q20, num : INT32; + DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9 : int; + Al, pred : int; +var + delta : JDIMENSION; +begin + coef := my_coef_ptr (cinfo^.coef); + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + { Force some input to be done if we are getting ahead of the input. } + while (cinfo^.input_scan_number <= cinfo^.output_scan_number) and + (not cinfo^.inputctl^.eoi_reached) do + begin + if (cinfo^.input_scan_number = cinfo^.output_scan_number) then + begin + { If input is working on current scan, we ordinarily want it to + have completed the current row. But if input scan is DC, + we want it to keep one row ahead so that next block row's DC + values are up to date. } + + if (cinfo^.Ss = 0) then + delta := 1 + else + delta := 0; + if (cinfo^.input_iMCU_row > cinfo^.output_iMCU_row+delta) then + break; + end; + if (cinfo^.inputctl^.consume_input(cinfo) = JPEG_SUSPENDED) then + begin + decompress_smooth_data := JPEG_SUSPENDED; + exit; + end; + end; + + { OK, output from the virtual arrays. } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to (cinfo^.num_components-1) do + begin + { Don't bother to IDCT an uninteresting component. } + if (not compptr^.component_needed) then + continue; + { Count non-dummy DCT block rows in this iMCU row. } + if (cinfo^.output_iMCU_row < last_iMCU_row) then + begin + block_rows := compptr^.v_samp_factor; + access_rows := block_rows * 2; { this and next iMCU row } + last_row := FALSE; + end + else + begin + { NB: can't use last_row_height here; it is input-side-dependent! } + block_rows := int (compptr^.height_in_blocks mod compptr^.v_samp_factor); + if (block_rows = 0) then + block_rows := compptr^.v_samp_factor; + access_rows := block_rows; { this iMCU row only } + last_row := TRUE; + end; + { Align the virtual buffer for this component. } + if (cinfo^.output_iMCU_row > 0) then + begin + Inc(access_rows, compptr^.v_samp_factor); { prior iMCU row too } + buffer := cinfo^.mem^.access_virt_barray + (j_common_ptr (cinfo), coef^.whole_image[ci], + (cinfo^.output_iMCU_row - 1) * compptr^.v_samp_factor, + JDIMENSION (access_rows), FALSE); + Inc(JBLOCKROW_PTR(buffer), compptr^.v_samp_factor); { point to current iMCU row } + first_row := FALSE; + end + else + begin + buffer := cinfo^.mem^.access_virt_barray + (j_common_ptr (cinfo), coef^.whole_image[ci], + JDIMENSION (0), JDIMENSION (access_rows), FALSE); + first_row := TRUE; + end; + { Fetch component-dependent info } + coef_bits := coef^.coef_bits_latch; + Inc(coef_bits, ci); { ci * SAVED_COEFS} + quanttbl := compptr^.quant_table; + Q00 := quanttbl^.quantval[0]; + Q01 := quanttbl^.quantval[Q01_POS]; + Q10 := quanttbl^.quantval[Q10_POS]; + Q20 := quanttbl^.quantval[Q20_POS]; + Q11 := quanttbl^.quantval[Q11_POS]; + Q02 := quanttbl^.quantval[Q02_POS]; + inverse_DCT := cinfo^.idct^.inverse_DCT[ci]; + output_ptr := output_buf^[ci]; + { Loop over all DCT blocks to be processed. } + for block_row := 0 to (block_rows-1) do + begin + buffer_ptr := buffer^[block_row]; + if (first_row) and (block_row = 0) then + prev_block_row := buffer_ptr + else + prev_block_row := buffer^[block_row-1]; + if (last_row) and (block_row = block_rows-1) then + next_block_row := buffer_ptr + else + next_block_row := buffer^[block_row+1]; + { We fetch the surrounding DC values using a sliding-register approach. + Initialize all nine here so as to do the right thing on narrow pics.} + + DC3 := int(prev_block_row^[0][0]); + DC2 := DC3; + DC1 := DC2; + DC6 := int(buffer_ptr^[0][0]); + DC5 := DC6; + DC4 := DC5; + DC9 := int(next_block_row^[0][0]); + DC8 := DC9; + DC7 := DC8 ; + output_col := 0; + last_block_column := compptr^.width_in_blocks - 1; + for block_num := 0 to last_block_column do + begin + { Fetch current DCT block into workspace so we can modify it. } + jcopy_block_row(buffer_ptr, JBLOCKROW (@workspace), JDIMENSION(1)); + { Update DC values } + if (block_num < last_block_column) then + begin + DC3 := int (prev_block_row^[1][0]); + DC6 := int (buffer_ptr^[1][0]); + DC9 := int (next_block_row^[1][0]); + end; + { Compute coefficient estimates per K.8. + An estimate is applied only if coefficient is still zero, + and is not known to be fully accurate. } + + { AC01 } + Al := coef_bits^[1]; + if (Al <> 0) and (workspace[1] = 0) then + begin + num := 36 * Q00 * (DC4 - DC6); + if (num >= 0) then + begin + pred := int (((Q01 shl 7) + num) div (Q01 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + end + else + begin + pred := int (((Q01 shl 7) - num) div (Q01 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + pred := -pred; + end; + workspace[1] := JCOEF (pred); + end; + { AC10 } + Al := coef_bits^[2]; + if (Al <> 0) and (workspace[8] = 0) then + begin + num := 36 * Q00 * (DC2 - DC8); + if (num >= 0) then + begin + pred := int (((Q10 shl 7) + num) div (Q10 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + end + else + begin + pred := int (((Q10 shl 7) - num) div (Q10 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + pred := -pred; + end; + workspace[8] := JCOEF (pred); + end; + { AC20 } + Al := coef_bits^[3]; + if (Al <> 0) and (workspace[16] = 0) then + begin + num := 9 * Q00 * (DC2 + DC8 - 2*DC5); + if (num >= 0) then + begin + pred := int (((Q20 shl 7) + num) div (Q20 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + end + else + begin + pred := int (((Q20 shl 7) - num) div (Q20 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + pred := -pred; + end; + workspace[16] := JCOEF (pred); + end; + { AC11 } + Al := coef_bits^[4]; + if (Al <> 0) and (workspace[9] = 0) then + begin + num := 5 * Q00 * (DC1 - DC3 - DC7 + DC9); + if (num >= 0) then + begin + pred := int (((Q11 shl 7) + num) div (Q11 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + end + else + begin + pred := int (((Q11 shl 7) - num) div (Q11 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + pred := -pred; + end; + workspace[9] := JCOEF (pred); + end; + { AC02 } + Al := coef_bits^[5]; + if (Al <> 0) and (workspace[2] = 0) then + begin + num := 9 * Q00 * (DC4 + DC6 - 2*DC5); + if (num >= 0) then + begin + pred := int (((Q02 shl 7) + num) div (Q02 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + end + else + begin + pred := int (((Q02 shl 7) - num) div (Q02 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + pred := -pred; + end; + workspace[2] := JCOEF (pred); + end; + { OK, do the IDCT } + inverse_DCT (cinfo, compptr, JCOEFPTR (@workspace), + output_ptr, output_col); + { Advance for next column } + DC1 := DC2; DC2 := DC3; + DC4 := DC5; DC5 := DC6; + DC7 := DC8; DC8 := DC9; + Inc(JBLOCK_PTR(buffer_ptr)); + Inc(JBLOCK_PTR(prev_block_row)); + Inc(JBLOCK_PTR(next_block_row)); + Inc(output_col, compptr^.DCT_scaled_size); + end; + Inc(JSAMPROW_PTR(output_ptr), compptr^.DCT_scaled_size); + end; + Inc(compptr); + end; + + Inc(cinfo^.output_iMCU_row); + if (cinfo^.output_iMCU_row < cinfo^.total_iMCU_rows) then + begin + decompress_smooth_data := JPEG_ROW_COMPLETED; + exit; + end; + decompress_smooth_data := JPEG_SCAN_COMPLETED; +end; + +{$endif} { BLOCK_SMOOTHING_SUPPORTED } + + +{ Initialize coefficient buffer controller. } + +{GLOBAL} +procedure jinit_d_coef_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); +var + coef : my_coef_ptr; +{$ifdef D_MULTISCAN_FILES_SUPPORTED} +var + ci, access_rows : int; + compptr : jpeg_component_info_ptr; +{$endif} +var + buffer : JBLOCK_PTR; + i : int; +begin + coef := my_coef_ptr( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + SIZEOF(my_coef_controller)) ); + cinfo^.coef := jpeg_d_coef_controller_ptr(coef); + coef^.pub.start_input_pass := start_input_pass; + coef^.pub.start_output_pass := start_output_pass; +{$ifdef BLOCK_SMOOTHING_SUPPORTED} + coef^.coef_bits_latch := NIL; +{$endif} + + { Create the coefficient buffer. } + if (need_full_buffer) then + begin +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + { Allocate a full-image virtual array for each component, } + { padded to a multiple of samp_factor DCT blocks in each direction. } + { Note we ask for a pre-zeroed array. } + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + access_rows := compptr^.v_samp_factor; +{$ifdef BLOCK_SMOOTHING_SUPPORTED} + { If block smoothing could be used, need a bigger window } + if (cinfo^.progressive_mode) then + access_rows := access_rows * 3; +{$endif} + coef^.whole_image[ci] := cinfo^.mem^.request_virt_barray + (j_common_ptr (cinfo), JPOOL_IMAGE, TRUE, + JDIMENSION (jround_up( long(compptr^.width_in_blocks), + long(compptr^.h_samp_factor) )), + JDIMENSION (jround_up( long(compptr^.height_in_blocks), + long(compptr^.v_samp_factor) )), + JDIMENSION (access_rows)); + Inc(compptr); + end; + coef^.pub.consume_data := consume_data; + coef^.pub.decompress_data := decompress_data; + coef^.pub.coef_arrays := @(coef^.whole_image); + { link to virtual arrays } +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + { We only need a single-MCU buffer. } + buffer := JBLOCK_PTR ( + cinfo^.mem^.alloc_large (j_common_ptr (cinfo), JPOOL_IMAGE, + D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)) ); + for i := 0 to pred(D_MAX_BLOCKS_IN_MCU) do + begin + coef^.MCU_buffer[i] := JBLOCKROW(buffer); + Inc(buffer); + end; + coef^.pub.consume_data := dummy_consume_data; + coef^.pub.decompress_data := decompress_onepass; + coef^.pub.coef_arrays := NIL; { flag for no virtual arrays } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdcolor_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdcolor_del.pas new file mode 100644 index 0000000..6896f90 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdcolor_del.pas @@ -0,0 +1,502 @@ +unit jdcolor_del; + +{ This file contains output colorspace conversion routines. } + +{ Original: jdcolor.c ; Copyright (C) 1991-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jutils_del, + jdeferr_del, + jerror_del, + jpeglib_del; + +{ Module initialization routine for output colorspace conversion. } + +{GLOBAL} +procedure jinit_color_deconverter (cinfo : j_decompress_ptr); + +implementation + +{ Private subobject } +type + int_Color_Table = array[0..MAXJSAMPLE+1-1] of int; + int_table_ptr = ^int_Color_Table; + INT32_Color_Table = array[0..MAXJSAMPLE+1-1] of INT32; + INT32_table_ptr = ^INT32_Color_Table; +type + my_cconvert_ptr = ^my_color_deconverter; + my_color_deconverter = record + pub : jpeg_color_deconverter; { public fields } + + { Private state for YCC^.RGB conversion } + Cr_r_tab : int_table_ptr; { => table for Cr to R conversion } + Cb_b_tab : int_table_ptr; { => table for Cb to B conversion } + Cr_g_tab : INT32_table_ptr; { => table for Cr to G conversion } + Cb_g_tab : INT32_table_ptr; { => table for Cb to G conversion } + end; + + + + +{*************** YCbCr ^. RGB conversion: most common case *************} + +{ YCbCr is defined per CCIR 601-1, except that Cb and Cr are + normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + The conversion equations to be implemented are therefore + R = Y + 1.40200 * Cr + G = Y - 0.34414 * Cb - 0.71414 * Cr + B = Y + 1.77200 * Cb + where Cb and Cr represent the incoming values less CENTERJSAMPLE. + (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + + To avoid floating-point arithmetic, we represent the fractional constants + as integers scaled up by 2^16 (about 4 digits precision); we have to divide + the products by 2^16, with appropriate rounding, to get the correct answer. + Notice that Y, being an integral input, does not contribute any fraction + so it need not participate in the rounding. + + For even more speed, we avoid doing any multiplications in the inner loop + by precalculating the constants times Cb and Cr for all possible values. + For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + for 12-bit samples it is still acceptable. It's not very reasonable for + 16-bit samples, but if you want lossless storage you shouldn't be changing + colorspace anyway. + The Cr=>R and Cb=>B values can be rounded to integers in advance; the + values for the G calculation are left scaled up, since we must add them + together before rounding. } + +const + SCALEBITS = 16; { speediest right-shift on some machines } + ONE_HALF = (INT32(1) shl (SCALEBITS-1)); + + +{ Initialize tables for YCC->RGB colorspace conversion. } + +{LOCAL} +procedure build_ycc_rgb_table (cinfo : j_decompress_ptr); +const + FIX_1_40200 = INT32(Round( 1.40200 * (1 shl SCALEBITS))); + FIX_1_77200 = INT32(Round( 1.77200 * (1 shl SCALEBITS))); + FIX_0_71414 = INT32(Round( 0.71414 * (1 shl SCALEBITS))); + FIX_0_34414 = INT32(Round( 0.34414 * (1 shl SCALEBITS))); + +var + cconvert : my_cconvert_ptr; + i : int; + x : INT32; +var + shift_temp : INT32; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + + + cconvert^.Cr_r_tab := int_table_ptr( + cinfo^.mem^.alloc_small ( j_common_ptr(cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)) ); + cconvert^.Cb_b_tab := int_table_ptr ( + cinfo^.mem^.alloc_small ( j_common_ptr(cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)) ); + cconvert^.Cr_g_tab := INT32_table_ptr ( + cinfo^.mem^.alloc_small ( j_common_ptr(cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)) ); + cconvert^.Cb_g_tab := INT32_table_ptr ( + cinfo^.mem^.alloc_small ( j_common_ptr(cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)) ); + + + x := -CENTERJSAMPLE; + for i := 0 to MAXJSAMPLE do + begin + { i is the actual input pixel value, in the range 0..MAXJSAMPLE } + { The Cb or Cr value we are thinking of is x := i - CENTERJSAMPLE } + { Cr=>R value is nearest int to 1.40200 * x } + + shift_temp := FIX_1_40200 * x + ONE_HALF; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cconvert^.Cr_r_tab^[i] := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cconvert^.Cr_r_tab^[i] := int(shift_temp shr SCALEBITS); + + { Cb=>B value is nearest int to 1.77200 * x } + shift_temp := FIX_1_77200 * x + ONE_HALF; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cconvert^.Cb_b_tab^[i] := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cconvert^.Cb_b_tab^[i] := int(shift_temp shr SCALEBITS); + + { Cr=>G value is scaled-up -0.71414 * x } + cconvert^.Cr_g_tab^[i] := (- FIX_0_71414 ) * x; + { Cb=>G value is scaled-up -0.34414 * x } + { We also add in ONE_HALF so that need not do it in inner loop } + cconvert^.Cb_g_tab^[i] := (- FIX_0_34414 ) * x + ONE_HALF; + Inc(x); + end; +end; + + +{ Convert some rows of samples to the output colorspace. + + Note that we change from noninterleaved, one-plane-per-component format + to interleaved-pixel format. The output buffer is therefore three times + as wide as the input buffer. + A starting row offset is provided only for the input buffer. The caller + can easily adjust the passed output_buf value to accommodate any row + offset required on that side. } + +{METHODDEF} +procedure ycc_rgb_convert (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); +var + cconvert : my_cconvert_ptr; + {register} y, cb, cr : int; + {register} outptr : JSAMPROW; + {register} inptr0, inptr1, inptr2 : JSAMPROW; + {register} col : JDIMENSION; + num_cols : JDIMENSION; + { copy these pointers into registers if possible } + {register} range_limit : range_limit_table_ptr; + {register} Crrtab : int_table_ptr; + {register} Cbbtab : int_table_ptr; + {register} Crgtab : INT32_table_ptr; + {register} Cbgtab : INT32_table_ptr; +var + shift_temp : INT32; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + num_cols := cinfo^.output_width; + range_limit := cinfo^.sample_range_limit; + Crrtab := cconvert^.Cr_r_tab; + Cbbtab := cconvert^.Cb_b_tab; + Crgtab := cconvert^.Cr_g_tab; + Cbgtab := cconvert^.Cb_g_tab; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr0 := input_buf^[0]^[input_row]; + inptr1 := input_buf^[1]^[input_row]; + inptr2 := input_buf^[2]^[input_row]; + Inc(input_row); + outptr := output_buf^[0]; + Inc(JSAMPROW_PTR(output_buf)); + for col := 0 to pred(num_cols) do + begin + y := GETJSAMPLE(inptr0^[col]); + cb := GETJSAMPLE(inptr1^[col]); + cr := GETJSAMPLE(inptr2^[col]); + { Range-limiting is essential due to noise introduced by DCT losses. } + outptr^[RGB_RED] := range_limit^[y + Crrtab^[cr]]; + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + outptr^[RGB_GREEN] := range_limit^[y + int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS)))] + else + outptr^[RGB_GREEN] := range_limit^[y + int(shift_temp shr SCALEBITS)]; + + outptr^[RGB_BLUE] := range_limit^[y + Cbbtab^[cb]]; + Inc(JSAMPLE_PTR(outptr), RGB_PIXELSIZE); + end; + end; +end; + + +{*************** Cases other than YCbCr -> RGB *************} + + +{ Color conversion for no colorspace change: just copy the data, + converting from separate-planes to interleaved representation. } + +{METHODDEF} +procedure null_convert (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); +var + {register} inptr, + outptr : JSAMPLE_PTR; + {register} count : JDIMENSION; + {register} num_components : int; + num_cols : JDIMENSION; + ci : int; +begin + num_components := cinfo^.num_components; + num_cols := cinfo^.output_width; + + while (num_rows > 0) do + begin + Dec(num_rows); + for ci := 0 to pred(num_components) do + begin + inptr := JSAMPLE_PTR(input_buf^[ci]^[input_row]); + outptr := JSAMPLE_PTR(@(output_buf^[0]^[ci])); + + for count := pred(num_cols) downto 0 do + begin + outptr^ := inptr^; { needn't bother with GETJSAMPLE() here } + Inc(inptr); + Inc(outptr, num_components); + end; + end; + Inc(input_row); + Inc(JSAMPROW_PTR(output_buf)); + end; +end; + + +{ Color conversion for grayscale: just copy the data. + This also works for YCbCr -> grayscale conversion, in which + we just copy the Y (luminance) component and ignore chrominance. } + +{METHODDEF} +procedure grayscale_convert (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); +begin + jcopy_sample_rows(input_buf^[0], int(input_row), output_buf, 0, + num_rows, cinfo^.output_width); +end; + +{ Convert grayscale to RGB: just duplicate the graylevel three times. + This is provided to support applications that don't want to cope + with grayscale as a separate case. } + +{METHODDEF} +procedure gray_rgb_convert (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); +var + {register} inptr, outptr : JSAMPLE_PTR; + {register} col : JDIMENSION; + num_cols : JDIMENSION; +begin + num_cols := cinfo^.output_width; + while (num_rows > 0) do + begin + inptr := JSAMPLE_PTR(input_buf^[0]^[input_row]); + Inc(input_row); + outptr := JSAMPLE_PTR(@output_buf^[0]); + Inc(JSAMPROW_PTR(output_buf)); + for col := 0 to pred(num_cols) do + begin + { We can dispense with GETJSAMPLE() here } + JSAMPROW(outptr)^[RGB_RED] := inptr^; + JSAMPROW(outptr)^[RGB_GREEN] := inptr^; + JSAMPROW(outptr)^[RGB_BLUE] := inptr^; + Inc(inptr); + Inc(outptr, RGB_PIXELSIZE); + end; + Dec(num_rows); + end; +end; + + +{ Adobe-style YCCK -> CMYK conversion. + We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same + conversion as above, while passing K (black) unchanged. + We assume build_ycc_rgb_table has been called. } + +{METHODDEF} +procedure ycck_cmyk_convert (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); +var + cconvert : my_cconvert_ptr; + {register} y, cb, cr : int; + {register} outptr : JSAMPROW; + {register} inptr0, inptr1, inptr2, inptr3 : JSAMPROW; + {register} col : JDIMENSION; + num_cols : JDIMENSION; + { copy these pointers into registers if possible } + {register} range_limit : range_limit_table_ptr; + {register} Crrtab : int_table_ptr; + {register} Cbbtab : int_table_ptr; + {register} Crgtab : INT32_table_ptr; + {register} Cbgtab : INT32_table_ptr; +var + shift_temp : INT32; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + num_cols := cinfo^.output_width; + { copy these pointers into registers if possible } + range_limit := cinfo^.sample_range_limit; + Crrtab := cconvert^.Cr_r_tab; + Cbbtab := cconvert^.Cb_b_tab; + Crgtab := cconvert^.Cr_g_tab; + Cbgtab := cconvert^.Cb_g_tab; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr0 := input_buf^[0]^[input_row]; + inptr1 := input_buf^[1]^[input_row]; + inptr2 := input_buf^[2]^[input_row]; + inptr3 := input_buf^[3]^[input_row]; + Inc(input_row); + outptr := output_buf^[0]; + Inc(JSAMPROW_PTR(output_buf)); + for col := 0 to pred(num_cols) do + begin + y := GETJSAMPLE(inptr0^[col]); + cb := GETJSAMPLE(inptr1^[col]); + cr := GETJSAMPLE(inptr2^[col]); + { Range-limiting is essential due to noise introduced by DCT losses. } + outptr^[0] := range_limit^[MAXJSAMPLE - (y + Crrtab^[cr])]; { red } + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then + outptr^[1] := range_limit^[MAXJSAMPLE - (y + int( + (shift_temp shr SCALEBITS) or ((not INT32(0)) shl (32-SCALEBITS)) + ) )] + else + outptr^[1] := range_limit^[MAXJSAMPLE - { green } + (y + int(shift_temp shr SCALEBITS) )]; + outptr^[2] := range_limit^[MAXJSAMPLE - (y + Cbbtab^[cb])]; { blue } + { K passes through unchanged } + outptr^[3] := inptr3^[col]; { don't need GETJSAMPLE here } + Inc(JSAMPLE_PTR(outptr), 4); + end; + end; +end; + + +{ Empty method for start_pass. } + +{METHODDEF} +procedure start_pass_dcolor (cinfo : j_decompress_ptr); +begin + { no work needed } +end; + + +{ Module initialization routine for output colorspace conversion. } + +{GLOBAL} +procedure jinit_color_deconverter (cinfo : j_decompress_ptr); +var + cconvert : my_cconvert_ptr; + ci : int; +begin + cconvert := my_cconvert_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_color_deconverter)) ); + cinfo^.cconvert := jpeg_color_deconverter_ptr (cconvert); + cconvert^.pub.start_pass := start_pass_dcolor; + + { Make sure num_components agrees with jpeg_color_space } + case (cinfo^.jpeg_color_space) of + JCS_GRAYSCALE: + if (cinfo^.num_components <> 1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + + JCS_RGB, + JCS_YCbCr: + if (cinfo^.num_components <> 3) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + + JCS_CMYK, + JCS_YCCK: + if (cinfo^.num_components <> 4) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + + else { JCS_UNKNOWN can be anything } + if (cinfo^.num_components < 1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + end; + + { Set out_color_components and conversion method based on requested space. + Also clear the component_needed flags for any unused components, + so that earlier pipeline stages can avoid useless computation. } + + case (cinfo^.out_color_space) of + JCS_GRAYSCALE: + begin + cinfo^.out_color_components := 1; + if (cinfo^.jpeg_color_space = JCS_GRAYSCALE) + or (cinfo^.jpeg_color_space = JCS_YCbCr) then + begin + cconvert^.pub.color_convert := grayscale_convert; + { For color -> grayscale conversion, only the + Y (0) component is needed } + for ci := 1 to pred(cinfo^.num_components) do + cinfo^.comp_info^[ci].component_needed := FALSE; + end + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_RGB: + begin + cinfo^.out_color_components := RGB_PIXELSIZE; + if (cinfo^.jpeg_color_space = JCS_YCbCr) then + begin + cconvert^.pub.color_convert := ycc_rgb_convert; + build_ycc_rgb_table(cinfo); + end + else + if (cinfo^.jpeg_color_space = JCS_GRAYSCALE) then + begin + cconvert^.pub.color_convert := gray_rgb_convert; + end + else + if (cinfo^.jpeg_color_space = JCS_RGB) and (RGB_PIXELSIZE = 3) then + begin + cconvert^.pub.color_convert := null_convert; + end + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_CMYK: + begin + cinfo^.out_color_components := 4; + if (cinfo^.jpeg_color_space = JCS_YCCK) then + begin + cconvert^.pub.color_convert := ycck_cmyk_convert; + build_ycc_rgb_table(cinfo); + end + else + if (cinfo^.jpeg_color_space = JCS_CMYK) then + begin + cconvert^.pub.color_convert := null_convert; + end + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + else + begin { Permit null conversion to same output space } + if (cinfo^.out_color_space = cinfo^.jpeg_color_space) then + begin + cinfo^.out_color_components := cinfo^.num_components; + cconvert^.pub.color_convert := null_convert; + end + else { unsupported non-null conversion } + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + end; + + if (cinfo^.quantize_colors) then + cinfo^.output_components := 1 { single colormapped output component } + else + cinfo^.output_components := cinfo^.out_color_components; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdct_del.pas new file mode 100644 index 0000000..04e92b8 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdct_del.pas @@ -0,0 +1,110 @@ +unit jdct_del; + +{ Orignal: jdct.h; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +{ This include file contains common declarations for the forward and + inverse DCT modules. These declarations are private to the DCT managers + (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms. + The individual DCT algorithms are kept in separate files to ease + machine-dependent tuning (e.g., assembly coding). } + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del; + + +{ A forward DCT routine is given a pointer to a work area of type DCTELEM[]; + the DCT is to be performed in-place in that buffer. Type DCTELEM is int + for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT + implementations use an array of type FAST_FLOAT, instead.) + The DCT inputs are expected to be signed (range +-CENTERJSAMPLE). + The DCT outputs are returned scaled up by a factor of 8; they therefore + have a range of +-8K for 8-bit data, +-128K for 12-bit data. This + convention improves accuracy in integer implementations and saves some + work in floating-point ones. + Quantization of the output coefficients is done by jcdctmgr.c. } + + +{$ifdef BITS_IN_JSAMPLE_IS_8} +type + DCTELEM = int; { 16 or 32 bits is fine } +{$else} +type { must have 32 bits } + DCTELEM = INT32; +{$endif} +type + jTDctElem = 0..(MaxInt div SizeOf(DCTELEM))-1; + DCTELEM_FIELD = array[jTDctElem] of DCTELEM; + DCTELEM_FIELD_PTR = ^DCTELEM_FIELD; + DCTELEMPTR = ^DCTELEM; + +type + forward_DCT_method_ptr = procedure(var data : array of DCTELEM); + float_DCT_method_ptr = procedure(var data : array of FAST_FLOAT); + + +{ An inverse DCT routine is given a pointer to the input JBLOCK and a pointer + to an output sample array. The routine must dequantize the input data as + well as perform the IDCT; for dequantization, it uses the multiplier table + pointed to by compptr->dct_table. The output data is to be placed into the + sample array starting at a specified column. (Any row offset needed will + be applied to the array pointer before it is passed to the IDCT code.) + Note that the number of samples emitted by the IDCT routine is + DCT_scaled_size * DCT_scaled_size. } + + +{ typedef inverse_DCT_method_ptr is declared in jpegint.h } + + +{ Each IDCT routine has its own ideas about the best dct_table element type. } + + +type + ISLOW_MULT_TYPE = MULTIPLIER; { short or int, whichever is faster } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +type + IFAST_MULT_TYPE = MULTIPLIER; { 16 bits is OK, use short if faster } +const + IFAST_SCALE_BITS = 2; { fractional bits in scale factors } +{$else} +type + IFAST_MULT_TYPE = INT32; { need 32 bits for scaled quantizers } +const + IFAST_SCALE_BITS = 13; { fractional bits in scale factors } +{$endif} +type + FLOAT_MULT_TYPE = FAST_FLOAT; { preferred floating type } + +const + RANGE_MASK = (MAXJSAMPLE * 4 + 3); { 2 bits wider than legal samples } + +type + jTMultType = 0..(MaxInt div SizeOf(ISLOW_MULT_TYPE))-1; + ISLOW_MULT_TYPE_FIELD = array[jTMultType] of ISLOW_MULT_TYPE; + ISLOW_MULT_TYPE_FIELD_PTR = ^ISLOW_MULT_TYPE_FIELD; + ISLOW_MULT_TYPE_PTR = ^ISLOW_MULT_TYPE; + + jTFloatType = 0..(MaxInt div SizeOf(FLOAT_MULT_TYPE))-1; + FLOAT_MULT_TYPE_FIELD = array[jTFloatType] of FLOAT_MULT_TYPE; + FLOAT_MULT_TYPE_FIELD_PTR = ^FLOAT_MULT_TYPE_FIELD; + FLOAT_MULT_TYPE_PTR = ^FLOAT_MULT_TYPE; + + jTFastType = 0..(MaxInt div SizeOf(IFAST_MULT_TYPE))-1; + IFAST_MULT_TYPE_FIELD = array[jTFastType] of IFAST_MULT_TYPE; + IFAST_MULT_TYPE_FIELD_PTR = ^IFAST_MULT_TYPE_FIELD; + IFAST_MULT_TYPE_PTR = ^IFAST_MULT_TYPE; + +type + jTFastFloat = 0..(MaxInt div SizeOf(FAST_FLOAT))-1; + FAST_FLOAT_FIELD = array[jTFastFloat] of FAST_FLOAT; + FAST_FLOAT_FIELD_PTR = ^FAST_FLOAT_FIELD; + FAST_FLOAT_PTR = ^FAST_FLOAT; + +implementation + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jddctmgr_del.pas b/mseide-msegui/lib/common/fpccompatibility/jddctmgr_del.pas new file mode 100644 index 0000000..0535cbf --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jddctmgr_del.pas @@ -0,0 +1,330 @@ +unit jddctmgr_del; + +{ Original : jddctmgr.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +{ This file contains the inverse-DCT management logic. + This code selects a particular IDCT implementation to be used, + and it performs related housekeeping chores. No code in this file + is executed per IDCT step, only during output pass setup. + + Note that the IDCT routines are responsible for performing coefficient + dequantization as well as the IDCT proper. This module sets up the + dequantization multiplier table needed by the IDCT routine. } + +interface + +{$I jconfig_del.inc} + +//{$N+} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jdct_del, { Private declarations for DCT subsystem } + jidctfst_del, + {$IFDEF BASM} + jidctasm_del, + {$ELSE} + jidctint_del, + {$ENDIF} + jidctflt_del, jidctred_del; + + + +{ Initialize IDCT manager. } + +{GLOBAL} +procedure jinit_inverse_dct (cinfo : j_decompress_ptr); + + +implementation + +{ The decompressor input side (jdinput.c) saves away the appropriate + quantization table for each component at the start of the first scan + involving that component. (This is necessary in order to correctly + decode files that reuse Q-table slots.) + When we are ready to make an output pass, the saved Q-table is converted + to a multiplier table that will actually be used by the IDCT routine. + The multiplier table contents are IDCT-method-dependent. To support + application changes in IDCT method between scans, we can remake the + multiplier tables if necessary. + In buffered-image mode, the first output pass may occur before any data + has been seen for some components, and thus before their Q-tables have + been saved away. To handle this case, multiplier tables are preset + to zeroes; the result of the IDCT will be a neutral gray level. } + + +{ Private subobject for this module } + +type + my_idct_ptr = ^my_idct_controller; + my_idct_controller = record + pub : jpeg_inverse_dct; { public fields } + + { This array contains the IDCT method code that each multiplier table + is currently set up for, or -1 if it's not yet set up. + The actual multiplier tables are pointed to by dct_table in the + per-component comp_info structures. } + + cur_method : array[0..MAX_COMPONENTS-1] of int; + end; {my_idct_controller;} + + +{ Allocated multiplier tables: big enough for any supported variant } + +type + multiplier_table = record + case byte of + 0:(islow_array : array[0..DCTSIZE2-1] of ISLOW_MULT_TYPE); + {$ifdef DCT_IFAST_SUPPORTED} + 1:(ifast_array : array[0..DCTSIZE2-1] of IFAST_MULT_TYPE); + {$endif} + {$ifdef DCT_FLOAT_SUPPORTED} + 2:(float_array : array[0..DCTSIZE2-1] of FLOAT_MULT_TYPE); + {$endif} + end; + + +{ The current scaled-IDCT routines require ISLOW-style multiplier tables, + so be sure to compile that code if either ISLOW or SCALING is requested. } + +{$ifdef DCT_ISLOW_SUPPORTED} + {$define PROVIDE_ISLOW_TABLES} +{$else} + {$ifdef IDCT_SCALING_SUPPORTED} + {$define PROVIDE_ISLOW_TABLES} + {$endif} +{$endif} + + +{ Prepare for an output pass. + Here we select the proper IDCT routine for each component and build + a matching multiplier table. } + +{METHODDEF} +procedure start_pass (cinfo : j_decompress_ptr); +var + idct : my_idct_ptr; + ci, i : int; + compptr : jpeg_component_info_ptr; + method : J_DCT_METHOD; + method_ptr : inverse_DCT_method_ptr; + qtbl : JQUANT_TBL_PTR; +{$ifdef PROVIDE_ISLOW_TABLES} +var + ismtbl : ISLOW_MULT_TYPE_FIELD_PTR; +{$endif} +{$ifdef DCT_IFAST_SUPPORTED} +const + CONST_BITS = 14; +const + aanscales : array[0..DCTSIZE2-1] of INT16 = + ({ precomputed values scaled up by 14 bits } + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247); +var + ifmtbl : IFAST_MULT_TYPE_FIELD_PTR; + {SHIFT_TEMPS} + + { Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + + function DESCALE(x : INT32; n : int) : INT32; + var + shift_temp : INT32; + begin + {$ifdef RIGHT_SHIFT_IS_UNSIGNED} + shift_temp := x + (INT32(1) shl (n-1)); + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + Descale := (shift_temp shr n); + {$else} + Descale := (x + (INT32(1) shl (n-1)) shr n; + {$endif} + end; + +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} +const + aanscalefactor : array[0..DCTSIZE-1] of double = + (1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379); +var + fmtbl : FLOAT_MULT_TYPE_FIELD_PTR; + row, col : int; +{$endif} +begin + idct := my_idct_ptr (cinfo^.idct); + method := J_DCT_METHOD(0); + method_ptr := NIL; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + + for ci := 0 to pred(cinfo^.num_components) do + begin + { Select the proper IDCT routine for this component's scaling } + case (compptr^.DCT_scaled_size) of +{$ifdef IDCT_SCALING_SUPPORTED} + 1:begin + method_ptr := jpeg_idct_1x1; + method := JDCT_ISLOW; { jidctred uses islow-style table } + end; + 2:begin + method_ptr := jpeg_idct_2x2; + method := JDCT_ISLOW; { jidctred uses islow-style table } + end; + 4:begin + method_ptr := jpeg_idct_4x4; + method := JDCT_ISLOW; { jidctred uses islow-style table } + end; +{$endif} + DCTSIZE: + case (cinfo^.dct_method) of +{$ifdef DCT_ISLOW_SUPPORTED} + JDCT_ISLOW: + begin + method_ptr := jpeg_idct_islow; + method := JDCT_ISLOW; + end; +{$endif} +{$ifdef DCT_IFAST_SUPPORTED} + JDCT_IFAST: + begin + method_ptr := jpeg_idct_ifast; + method := JDCT_IFAST; + end; +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} + JDCT_FLOAT: + begin + method_ptr := jpeg_idct_float; + method := JDCT_FLOAT; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + end; + else + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_DCTSIZE, compptr^.DCT_scaled_size); + end; + idct^.pub.inverse_DCT[ci] := method_ptr; + { Create multiplier table from quant table. + However, we can skip this if the component is uninteresting + or if we already built the table. Also, if no quant table + has yet been saved for the component, we leave the + multiplier table all-zero; we'll be reading zeroes from the + coefficient controller's buffer anyway. } + + if (not compptr^.component_needed) or (idct^.cur_method[ci] = int(method)) then + continue; + qtbl := compptr^.quant_table; + if (qtbl = NIL) then { happens if no data yet for component } + continue; + idct^.cur_method[ci] := int(method); + case (method) of +{$ifdef PROVIDE_ISLOW_TABLES} + JDCT_ISLOW: + begin + { For LL&M IDCT method, multipliers are equal to raw quantization + coefficients, but are stored as ints to ensure access efficiency. } + + ismtbl := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + for i := 0 to pred(DCTSIZE2) do + begin + ismtbl^[i] := ISLOW_MULT_TYPE (qtbl^.quantval[i]); + end; + end; +{$endif} +{$ifdef DCT_IFAST_SUPPORTED} + JDCT_IFAST: + begin + { For AA&N IDCT method, multipliers are equal to quantization + coefficients scaled by scalefactor[row]*scalefactor[col], where + scalefactor[0] := 1 + scalefactor[k] := cos(k*PI/16) * sqrt(2) for k=1..7 + For integer operation, the multiplier table is to be scaled by + IFAST_SCALE_BITS. } + + ifmtbl := IFAST_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + + for i := 0 to pred(DCTSIZE2) do + begin + ifmtbl^[i] := IFAST_MULT_TYPE( + DESCALE( INT32 (qtbl^.quantval[i]) * INT32 (aanscales[i]), + CONST_BITS-IFAST_SCALE_BITS) ); + end; + end; +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} + JDCT_FLOAT: + begin + { For float AA&N IDCT method, multipliers are equal to quantization + coefficients scaled by scalefactor[row]*scalefactor[col], where + scalefactor[0] := 1 + scalefactor[k] := cos(k*PI/16) * sqrt(2) for k=1..7 } + + fmtbl := FLOAT_MULT_TYPE_FIELD_PTR(compptr^.dct_table); + + i := 0; + for row := 0 to pred(DCTSIZE) do + begin + for col := 0 to pred(DCTSIZE) do + begin + fmtbl^[i] := {FLOAT_MULT_TYPE} ( + {double} qtbl^.quantval[i] * + aanscalefactor[row] * aanscalefactor[col] ); + Inc(i); + end; + end; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + break; + end; + Inc(compptr); + end; +end; + + +{ Initialize IDCT manager. } + +{GLOBAL} +procedure jinit_inverse_dct (cinfo : j_decompress_ptr); +var + idct : my_idct_ptr; + ci : int; + compptr : jpeg_component_info_ptr; +begin + idct := my_idct_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_idct_controller)) ); + cinfo^.idct := jpeg_inverse_dct_ptr (idct); + idct^.pub.start_pass := start_pass; + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Allocate and pre-zero a multiplier table for each component } + compptr^.dct_table := + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(multiplier_table)); + MEMZERO(compptr^.dct_table, SIZEOF(multiplier_table)); + { Mark multiplier table not yet set up for any method } + idct^.cur_method[ci] := -1; + Inc(compptr); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdeferr_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdeferr_del.pas new file mode 100644 index 0000000..02dfa91 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdeferr_del.pas @@ -0,0 +1,498 @@ +unit jdeferr_del; + +{ This file defines the error and message codes for the cjpeg/djpeg + applications. These strings are not needed as part of the JPEG library + proper. + Edit this file to add new codes, or to translate the message strings to + some other language. } + +{ Original cderror.h ; Copyright (C) 1994, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ To define the enum list of message codes, include this file without + defining macro JMESSAGE. To create a message string table, include it + again with a suitable JMESSAGE definition (see jerror.c for an example). } + + +{ Original: jversion.h ; Copyright (C) 1991-1996, Thomas G. Lane. } +{ This file contains software version identification. } + +const + JVERSION = '6a 7-Feb-96'; + + JCOPYRIGHT = 'Copyright (C) 1996, Thomas G. Lane'; + + JNOTICE = 'Pascal Translation, Copyright (C) 1996, Jacques Nomssi Nzali'; + +{ Create the message string table. + We do this from the master message list in jerror.h by re-reading + jerror.h with a suitable definition for macro JMESSAGE. + The message table is made an external symbol just in case any applications + want to refer to it directly. } + +type + J_MESSAGE_CODE =( + JMSG_NOMESSAGE, + JERR_ARITH_NOTIMPL, + JERR_BAD_ALIGN_TYPE, + JERR_BAD_ALLOC_CHUNK, + JERR_BAD_BUFFER_MODE, + JERR_BAD_COMPONENT_ID, + JERR_BAD_DCT_COEF, + JERR_BAD_DCTSIZE, + JERR_BAD_HUFF_TABLE, + JERR_BAD_IN_COLORSPACE, + JERR_BAD_J_COLORSPACE, + JERR_BAD_LENGTH, + JERR_BAD_LIB_VERSION, + JERR_BAD_MCU_SIZE, + JERR_BAD_POOL_ID, + JERR_BAD_PRECISION, + JERR_BAD_PROGRESSION, + JERR_BAD_PROG_SCRIPT, + JERR_BAD_SAMPLING, + JERR_BAD_SCAN_SCRIPT, + JERR_BAD_STATE, + JERR_BAD_STRUCT_SIZE, + JERR_BAD_VIRTUAL_ACCESS, + JERR_BUFFER_SIZE, + JERR_CANT_SUSPEND, + JERR_CCIR601_NOTIMPL, + JERR_COMPONENT_COUNT, + JERR_CONVERSION_NOTIMPL, + JERR_DAC_INDEX, + JERR_DAC_VALUE, + JERR_DHT_COUNTS, + JERR_DHT_INDEX, + JERR_DQT_INDEX, + JERR_EMPTY_IMAGE, + JERR_EMS_READ, + JERR_EMS_WRITE, + JERR_EOI_EXPECTED, + JERR_FILE_READ, + JERR_FILE_WRITE, + JERR_FRACT_SAMPLE_NOTIMPL, + JERR_HUFF_CLEN_OVERFLOW, + JERR_HUFF_MISSING_CODE, + JERR_IMAGE_TOO_BIG, + JERR_INPUT_EMPTY, + JERR_INPUT_EOF, + JERR_MISMATCHED_QUANT_TABLE, + JERR_MISSING_DATA, + JERR_MODE_CHANGE, + JERR_NOTIMPL, + JERR_NOT_COMPILED, + JERR_NO_BACKING_STORE, + JERR_NO_HUFF_TABLE, + JERR_NO_IMAGE, + JERR_NO_QUANT_TABLE, + JERR_NO_SOI, + JERR_OUT_OF_MEMORY, + JERR_QUANT_COMPONENTS, + JERR_QUANT_FEW_COLORS, + JERR_QUANT_MANY_COLORS, + JERR_SOF_DUPLICATE, + JERR_SOF_NO_SOS, + JERR_SOF_UNSUPPORTED, + JERR_SOI_DUPLICATE, + JERR_SOS_NO_SOF, + JERR_TFILE_CREATE, + JERR_TFILE_READ, + JERR_TFILE_SEEK, + JERR_TFILE_WRITE, + JERR_TOO_LITTLE_DATA, + JERR_UNKNOWN_MARKER, + JERR_VIRTUAL_BUG, + JERR_WIDTH_OVERFLOW, + JERR_XMS_READ, + JERR_XMS_WRITE, + JMSG_COPYRIGHT, + JMSG_VERSION, + JTRC_16BIT_TABLES, + JTRC_ADOBE, + JTRC_APP0, + JTRC_APP14, + JTRC_DAC, + JTRC_DHT, + JTRC_DQT, + JTRC_DRI, + JTRC_EMS_CLOSE, + JTRC_EMS_OPEN, + JTRC_EOI, + JTRC_HUFFBITS, + JTRC_JFIF, + JTRC_JFIF_BADTHUMBNAILSIZE, + JTRC_JFIF_EXTENSION, + JTRC_JFIF_THUMBNAIL, + JTRC_MISC_MARKER, + JTRC_PARMLESS_MARKER, + JTRC_QUANTVALS, + JTRC_QUANT_3_NCOLORS, + JTRC_QUANT_NCOLORS, + JTRC_QUANT_SELECTED, + JTRC_RECOVERY_ACTION, + JTRC_RST, + JTRC_SMOOTH_NOTIMPL, + JTRC_SOF, + JTRC_SOF_COMPONENT, + JTRC_SOI, + JTRC_SOS, + JTRC_SOS_COMPONENT, + JTRC_SOS_PARAMS, + JTRC_TFILE_CLOSE, + JTRC_TFILE_OPEN, + JTRC_THUMB_JPEG, + JTRC_THUMB_PALETTE, + JTRC_THUMB_RGB, + JTRC_UNKNOWN_IDS, + JTRC_XMS_CLOSE, + JTRC_XMS_OPEN, + JWRN_ADOBE_XFORM, + JWRN_BOGUS_PROGRESSION, + JWRN_EXTRANEOUS_DATA, + JWRN_HIT_MARKER, + JWRN_HUFF_BAD_CODE, + JWRN_JFIF_MAJOR, + JWRN_JPEG_EOF, + JWRN_MUST_RESYNC, + JWRN_NOT_SEQUENTIAL, + JWRN_TOO_MUCH_DATA, + + + JMSG_FIRSTADDONCODE, { Must be first entry! } + + {$ifdef BMP_SUPPORTED} + JERR_BMP_BADCMAP, { Unsupported BMP colormap format } + JERR_BMP_BADDEPTH, { Only 8- and 24-bit BMP files are supported } + JERR_BMP_BADHEADER, { Invalid BMP file: bad header length } + JERR_BMP_BADPLANES, { Invalid BMP file: biPlanes not equal to 1 } + JERR_BMP_COLORSPACE, { BMP output must be grayscale or RGB } + JERR_BMP_COMPRESSED, { Sorry, compressed BMPs not yet supported } + JERR_BMP_NOT, { Not a BMP file - does not start with BM } + JTRC_BMP, { %dx%d 24-bit BMP image } + JTRC_BMP_MAPPED, { %dx%d 8-bit colormapped BMP image } + JTRC_BMP_OS2, { %dx%d 24-bit OS2 BMP image } + JTRC_BMP_OS2_MAPPED, { %dx%d 8-bit colormapped OS2 BMP image } + {$endif} { BMP_SUPPORTED } + + {$ifdef GIF_SUPPORTED} + JERR_GIF_BUG, { GIF output got confused } + JERR_GIF_CODESIZE, { Bogus GIF codesize %d } + JERR_GIF_COLORSPACE, { GIF output must be grayscale or RGB } + JERR_GIF_IMAGENOTFOUND, { Too few images in GIF file } + JERR_GIF_NOT, { Not a GIF file } + JTRC_GIF, { %dx%dx%d GIF image } + JTRC_GIF_BADVERSION, + { Warning: unexpected GIF version number '%c%c%c' } + JTRC_GIF_EXTENSION, { Ignoring GIF extension block of type 0x%02x } + JTRC_GIF_NONSQUARE, { Caution: nonsquare pixels in input } + JWRN_GIF_BADDATA, { Corrupt data in GIF file } + JWRN_GIF_CHAR, { Bogus char 0x%02x in GIF file, ignoring } + JWRN_GIF_ENDCODE, { Premature end of GIF image } + JWRN_GIF_NOMOREDATA, { Ran out of GIF bits } + {$endif} { GIF_SUPPORTED } + + {$ifdef PPM_SUPPORTED} + JERR_PPM_COLORSPACE, { PPM output must be grayscale or RGB } + JERR_PPM_NONNUMERIC, { Nonnumeric data in PPM file } + JERR_PPM_NOT, { Not a PPM file } + JTRC_PGM, { %dx%d PGM image } + JTRC_PGM_TEXT, { %dx%d text PGM image } + JTRC_PPM, { %dx%d PPM image } + JTRC_PPM_TEXT, { %dx%d text PPM image } + {$endif} { PPM_SUPPORTED } + + {$ifdef RLE_SUPPORTED} + JERR_RLE_BADERROR, { Bogus error code from RLE library } + JERR_RLE_COLORSPACE, { RLE output must be grayscale or RGB } + JERR_RLE_DIMENSIONS, { Image dimensions (%dx%d) too large for RLE } + JERR_RLE_EMPTY, { Empty RLE file } + JERR_RLE_EOF, { Premature EOF in RLE header } + JERR_RLE_MEM, { Insufficient memory for RLE header } + JERR_RLE_NOT, { Not an RLE file } + JERR_RLE_TOOMANYCHANNELS, { Cannot handle %d output channels for RLE } + JERR_RLE_UNSUPPORTED, { Cannot handle this RLE setup } + JTRC_RLE, { %dx%d full-color RLE file } + JTRC_RLE_FULLMAP, { %dx%d full-color RLE file with map of length %d } + JTRC_RLE_GRAY, { %dx%d grayscale RLE file } + JTRC_RLE_MAPGRAY, { %dx%d grayscale RLE file with map of length %d } + JTRC_RLE_MAPPED, { %dx%d colormapped RLE file with map of length %d } + {$endif} { RLE_SUPPORTED } + + {$ifdef TARGA_SUPPORTED} + JERR_TGA_BADCMAP, { Unsupported Targa colormap format } + JERR_TGA_BADPARMS, { Invalid or unsupported Targa file } + JERR_TGA_COLORSPACE, { Targa output must be grayscale or RGB } + JTRC_TGA, { %dx%d RGB Targa image } + JTRC_TGA_GRAY, { %dx%d grayscale Targa image } + JTRC_TGA_MAPPED, { %dx%d colormapped Targa image } + {$else} + JERR_TGA_NOTCOMP, { Targa support was not compiled } + {$endif} { TARGA_SUPPORTED } + + JERR_BAD_CMAP_FILE, + { Color map file is invalid or of unsupported format } + JERR_TOO_MANY_COLORS, + { Output file format cannot handle %d colormap entries } + JERR_UNGETC_FAILED, { ungetc failed } + {$ifdef TARGA_SUPPORTED} + JERR_UNKNOWN_FORMAT, + { Unrecognized input file format --- perhaps you need -targa } + {$else} + JERR_UNKNOWN_FORMAT, { Unrecognized input file format } + {$endif} + JERR_UNSUPPORTED_FORMAT, { Unsupported output file format } + + JMSG_LASTADDONCODE + ); + + +const + JMSG_LASTMSGCODE : J_MESSAGE_CODE = JMSG_LASTADDONCODE; + +type + msg_table = Array[J_MESSAGE_CODE] of string[80]; +const + jpeg_std_message_table : msg_table = ( + + { JMSG_NOMESSAGE } 'Bogus message code %d', { Must be first entry! } + +{ For maintenance convenience, list is alphabetical by message code name } + { JERR_ARITH_NOTIMPL } + 'Sorry, there are legal restrictions on arithmetic coding', + { JERR_BAD_ALIGN_TYPE } 'ALIGN_TYPE is wrong, please fix', + { JERR_BAD_ALLOC_CHUNK } 'MAX_ALLOC_CHUNK is wrong, please fix', + { JERR_BAD_BUFFER_MODE } 'Bogus buffer control mode', + { JERR_BAD_COMPONENT_ID } 'Invalid component ID %d in SOS', + { JERR_BAD_DCT_COEF } 'DCT coefficient out of range', + { JERR_BAD_DCTSIZE } 'IDCT output block size %d not supported', + { JERR_BAD_HUFF_TABLE } 'Bogus Huffman table definition', + { JERR_BAD_IN_COLORSPACE } 'Bogus input colorspace', + { JERR_BAD_J_COLORSPACE } 'Bogus JPEG colorspace', + { JERR_BAD_LENGTH } 'Bogus marker length', + { JERR_BAD_LIB_VERSION } + 'Wrong JPEG library version: library is %d, caller expects %d', + { JERR_BAD_MCU_SIZE } 'Sampling factors too large for interleaved scan', + { JERR_BAD_POOL_ID } 'Invalid memory pool code %d', + { JERR_BAD_PRECISION } 'Unsupported JPEG data precision %d', + { JERR_BAD_PROGRESSION } + 'Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d', + { JERR_BAD_PROG_SCRIPT } + 'Invalid progressive parameters at scan script entry %d', + { JERR_BAD_SAMPLING } 'Bogus sampling factors', + { JERR_BAD_SCAN_SCRIPT } 'Invalid scan script at entry %d', + { JERR_BAD_STATE } 'Improper call to JPEG library in state %d', + { JERR_BAD_STRUCT_SIZE } + 'JPEG parameter struct mismatch: library thinks size is %d, caller expects %d', + { JERR_BAD_VIRTUAL_ACCESS } 'Bogus virtual array access', + { JERR_BUFFER_SIZE } 'Buffer passed to JPEG library is too small', + { JERR_CANT_SUSPEND } 'Suspension not allowed here', + { JERR_CCIR601_NOTIMPL } 'CCIR601 sampling not implemented yet', + { JERR_COMPONENT_COUNT } 'Too many color components: %d, max %d', + { JERR_CONVERSION_NOTIMPL } 'Unsupported color conversion request', + { JERR_DAC_INDEX } 'Bogus DAC index %d', + { JERR_DAC_VALUE } 'Bogus DAC value $%x', + { JERR_DHT_COUNTS } 'Bogus DHT counts', + { JERR_DHT_INDEX } 'Bogus DHT index %d', + { JERR_DQT_INDEX } 'Bogus DQT index %d', + { JERR_EMPTY_IMAGE } 'Empty JPEG image (DNL not supported)', + { JERR_EMS_READ } 'Read from EMS failed', + { JERR_EMS_WRITE } 'Write to EMS failed', + { JERR_EOI_EXPECTED } 'Didn''t expect more than one scan', + { JERR_FILE_READ } 'Input file read error', + { JERR_FILE_WRITE } 'Output file write error --- out of disk space?', + { JERR_FRACT_SAMPLE_NOTIMPL } 'Fractional sampling not implemented yet', + { JERR_HUFF_CLEN_OVERFLOW } 'Huffman code size table overflow', + { JERR_HUFF_MISSING_CODE } 'Missing Huffman code table entry', + { JERR_IMAGE_TOO_BIG } 'Maximum supported image dimension is %d pixels', + { JERR_INPUT_EMPTY } 'Empty input file', + { JERR_INPUT_EOF } 'Premature end of input file', + { JERR_MISMATCHED_QUANT_TABLE } + 'Cannot transcode due to multiple use of quantization table %d', + { JERR_MISSING_DATA } 'Scan script does not transmit all data', + { JERR_MODE_CHANGE } 'Invalid color quantization mode change', + { JERR_NOTIMPL } 'Not implemented yet', + { JERR_NOT_COMPILED } 'Requested feature was omitted at compile time', + { JERR_NO_BACKING_STORE } 'Backing store not supported', + { JERR_NO_HUFF_TABLE } 'Huffman table $%02x was not defined', + { JERR_NO_IMAGE } 'JPEG datastream contains no image', + { JERR_NO_QUANT_TABLE } 'Quantization table $%02x was not defined', + { JERR_NO_SOI } 'Not a JPEG file: starts with $%02x $%02x', + { JERR_OUT_OF_MEMORY } 'Insufficient memory (case %d)', + { JERR_QUANT_COMPONENTS } + 'Cannot quantize more than %d color components', + { JERR_QUANT_FEW_COLORS } 'Cannot quantize to fewer than %d colors', + { JERR_QUANT_MANY_COLORS } 'Cannot quantize to more than %d colors', + { JERR_SOF_DUPLICATE } 'Invalid JPEG file structure: two SOF markers', + { JERR_SOF_NO_SOS } 'Invalid JPEG file structure: missing SOS marker', + { JERR_SOF_UNSUPPORTED } 'Unsupported JPEG process: SOF type $%02x', + { JERR_SOI_DUPLICATE } 'Invalid JPEG file structure: two SOI markers', + { JERR_SOS_NO_SOF } 'Invalid JPEG file structure: SOS before SOF', + { JERR_TFILE_CREATE } 'Failed to create temporary file %s', + { JERR_TFILE_READ } 'Read failed on temporary file', + { JERR_TFILE_SEEK } 'Seek failed on temporary file', + { JERR_TFILE_WRITE } + 'Write failed on temporary file --- out of disk space?', + { JERR_TOO_LITTLE_DATA } 'Application transferred too few scanlines', + { JERR_UNKNOWN_MARKER } 'Unsupported marker type $%02x', + { JERR_VIRTUAL_BUG } 'Virtual array controller messed up', + { JERR_WIDTH_OVERFLOW } 'Image too wide for this implementation', + { JERR_XMS_READ } 'Read from XMS failed', + { JERR_XMS_WRITE } 'Write to XMS failed', + { JMSG_COPYRIGHT } JCOPYRIGHT, + { JMSG_VERSION } JVERSION, + { JTRC_16BIT_TABLES } + 'Caution: quantization tables are too coarse for baseline JPEG', + { JTRC_ADOBE } + 'Adobe APP14 marker: version %d, flags $%04x $%04x, transform %d', + { JTRC_APP0 } 'Unknown APP0 marker (not JFIF), length %d', + { JTRC_APP14 } 'Unknown APP14 marker (not Adobe), length %d', + { JTRC_DAC } 'Define Arithmetic Table $%02x: $%02x', + { JTRC_DHT } 'Define Huffman Table $%02x', + { JTRC_DQT } 'Define Quantization Table %d precision %d', + { JTRC_DRI } 'Define Restart Interval %d', + { JTRC_EMS_CLOSE } 'Freed EMS handle %d', + { JTRC_EMS_OPEN } 'Obtained EMS handle %d', + { JTRC_EOI } 'End Of Image', + { JTRC_HUFFBITS } ' %3d %3d %3d %3d %3d %3d %3d %3d', + { JTRC_JFIF } 'JFIF APP0 marker, density %dx%d %d', + { JTRC_JFIF_BADTHUMBNAILSIZE } + 'Warning: thumbnail image size does not match data length %d', + { JTRC_JFIF_EXTENSION } 'JFIF extension marker: type 0x%02x, length %u', + { JTRC_JFIF_THUMBNAIL } ' with %d x %d thumbnail image', + { JTRC_MISC_MARKER } 'Skipping marker $%02x, length %d', + { JTRC_PARMLESS_MARKER } 'Unexpected marker $%02x', + { JTRC_QUANTVALS } ' %4d %4d %4d %4d %4d %4d %4d %4d', + { JTRC_QUANT_3_NCOLORS } 'Quantizing to %d = %d*%d*%d colors', + { JTRC_QUANT_NCOLORS } 'Quantizing to %d colors', + { JTRC_QUANT_SELECTED } 'Selected %d colors for quantization', + { JTRC_RECOVERY_ACTION } 'At marker $%02x, recovery action %d', + { JTRC_RST } 'RST%d', + { JTRC_SMOOTH_NOTIMPL } + 'Smoothing not supported with nonstandard sampling ratios', + { JTRC_SOF } 'Start Of Frame $%02x: width=%d, height=%d, components=%d', + { JTRC_SOF_COMPONENT } ' Component %d: %dhx%dv q=%d', + { JTRC_SOI } 'Start of Image', + { JTRC_SOS } 'Start Of Scan: %d components', + { JTRC_SOS_COMPONENT } ' Component %d: dc=%d ac=%d', + { JTRC_SOS_PARAMS } ' Ss=%d, Se=%d, Ah=%d, Al=%d', + { JTRC_TFILE_CLOSE } 'Closed temporary file %s', + { JTRC_TFILE_OPEN } 'Opened temporary file %s', + { JTRC_THUMB_JPEG } + 'JFIF extension marker: JPEG-compressed thumbnail image, length %u', + { JMESSAGE(JTRC_THUMB_PALETTE } + 'JFIF extension marker: palette thumbnail image, length %u', + { JMESSAGE(JTRC_THUMB_RGB } + 'JFIF extension marker: RGB thumbnail image, length %u', + { JTRC_UNKNOWN_IDS } + 'Unrecognized component IDs %d %d %d, assuming YCbCr', + { JTRC_XMS_CLOSE } 'Freed XMS handle %d', + { JTRC_XMS_OPEN } 'Obtained XMS handle %d', + { JWRN_ADOBE_XFORM } 'Unknown Adobe color transform code %d', + { JWRN_BOGUS_PROGRESSION } + 'Inconsistent progression sequence for component %d coefficient %d', + { JWRN_EXTRANEOUS_DATA } + 'Corrupt JPEG data: %d extraneous bytes before marker $%02x', + { JWRN_HIT_MARKER } 'Corrupt JPEG data: premature end of data segment', + { JWRN_HUFF_BAD_CODE } 'Corrupt JPEG data: bad Huffman code', + { JWRN_JFIF_MAJOR } 'Warning: unknown JFIF revision number %d.%02d', + { JWRN_JPEG_EOF } 'Premature end of JPEG file', + { JWRN_MUST_RESYNC } + 'Corrupt JPEG data: found marker $%02x instead of RST%d', + { JWRN_NOT_SEQUENTIAL } 'Invalid SOS parameters for sequential JPEG', + { JWRN_TOO_MUCH_DATA } 'Application transferred too many scanlines', + + { JMSG_FIRSTADDONCODE } '', { Must be first entry! } + +{$ifdef BMP_SUPPORTED} + { JERR_BMP_BADCMAP } 'Unsupported BMP colormap format', + { JERR_BMP_BADDEPTH } 'Only 8- and 24-bit BMP files are supported', + { JERR_BMP_BADHEADER } 'Invalid BMP file: bad header length', + { JERR_BMP_BADPLANES } 'Invalid BMP file: biPlanes not equal to 1', + { JERR_BMP_COLORSPACE } 'BMP output must be grayscale or RGB', + { JERR_BMP_COMPRESSED } 'Sorry, compressed BMPs not yet supported', + { JERR_BMP_NOT } 'Not a BMP file - does not start with BM', + { JTRC_BMP } '%dx%d 24-bit BMP image', + { JTRC_BMP_MAPPED } '%dx%d 8-bit colormapped BMP image', + { JTRC_BMP_OS2 } '%dx%d 24-bit OS2 BMP image', + { JTRC_BMP_OS2_MAPPED } '%dx%d 8-bit colormapped OS2 BMP image', +{$endif} { BMP_SUPPORTED } + +{$ifdef GIF_SUPPORTED} + { JERR_GIF_BUG } 'GIF output got confused', + { JERR_GIF_CODESIZE } 'Bogus GIF codesize %d', + { JERR_GIF_COLORSPACE } 'GIF output must be grayscale or RGB', + { JERR_GIF_IMAGENOTFOUND } 'Too few images in GIF file', + { JERR_GIF_NOT } 'Not a GIF file', + { JTRC_GIF } '%dx%dx%d GIF image', + { JTRC_GIF_BADVERSION } + 'Warning: unexpected GIF version number "%c%c%c"', + { JTRC_GIF_EXTENSION } 'Ignoring GIF extension block of type 0x%02x', + { JTRC_GIF_NONSQUARE } 'Caution: nonsquare pixels in input', + { JWRN_GIF_BADDATA } 'Corrupt data in GIF file', + { JWRN_GIF_CHAR } 'Bogus char 0x%02x in GIF file, ignoring', + { JWRN_GIF_ENDCODE } 'Premature end of GIF image', + { JWRN_GIF_NOMOREDATA } 'Ran out of GIF bits', +{$endif} { GIF_SUPPORTED } + +{$ifdef PPM_SUPPORTED} + { JERR_PPM_COLORSPACE } 'PPM output must be grayscale or RGB', + { JERR_PPM_NONNUMERIC } 'Nonnumeric data in PPM file', + { JERR_PPM_NOT } 'Not a PPM file', + { JTRC_PGM } '%dx%d PGM image', + { JTRC_PGM_TEXT } '%dx%d text PGM image', + { JTRC_PPM } '%dx%d PPM image', + { JTRC_PPM_TEXT } '%dx%d text PPM image', +{$endif} { PPM_SUPPORTED } + +{$ifdef RLE_SUPPORTED} + { JERR_RLE_BADERROR } 'Bogus error code from RLE library', + { JERR_RLE_COLORSPACE } 'RLE output must be grayscale or RGB', + { JERR_RLE_DIMENSIONS } 'Image dimensions (%dx%d) too large for RLE', + { JERR_RLE_EMPTY } 'Empty RLE file', + { JERR_RLE_EOF } 'Premature EOF in RLE header', + { JERR_RLE_MEM } 'Insufficient memory for RLE header', + { JERR_RLE_NOT } 'Not an RLE file', + { JERR_RLE_TOOMANYCHANNELS } 'Cannot handle %d output channels for RLE', + { JERR_RLE_UNSUPPORTED } 'Cannot handle this RLE setup', + { JTRC_RLE } '%dx%d full-color RLE file', + { JTRC_RLE_FULLMAP } '%dx%d full-color RLE file with map of length %d', + { JTRC_RLE_GRAY } '%dx%d grayscale RLE file', + { JTRC_RLE_MAPGRAY } '%dx%d grayscale RLE file with map of length %d', + { JTRC_RLE_MAPPED } '%dx%d colormapped RLE file with map of length %d', +{$endif} { RLE_SUPPORTED } + +{$ifdef TARGA_SUPPORTED} + { JERR_TGA_BADCMAP } 'Unsupported Targa colormap format', + { JERR_TGA_BADPARMS } 'Invalid or unsupported Targa file', + { JERR_TGA_COLORSPACE } 'Targa output must be grayscale or RGB', + { JTRC_TGA } '%dx%d RGB Targa image', + { JTRC_TGA_GRAY } '%dx%d grayscale Targa image', + { JTRC_TGA_MAPPED } '%dx%d colormapped Targa image', +{$else} + { JERR_TGA_NOTCOMP } 'Targa support was not compiled', +{$endif} { TARGA_SUPPORTED } + + { JERR_BAD_CMAP_FILE } + 'Color map file is invalid or of unsupported format', + { JERR_TOO_MANY_COLORS } + 'Output file format cannot handle %d colormap entries', + { JERR_UNGETC_FAILED } 'ungetc failed', +{$ifdef TARGA_SUPPORTED} + { JERR_UNKNOWN_FORMAT } + 'Unrecognized input file format --- perhaps you need -targa', +{$else} + { JERR_UNKNOWN_FORMAT } 'Unrecognized input file format', +{$endif} + { JERR_UNSUPPORTED_FORMAT } 'Unsupported output file format', + + + { JMSG_LASTADDONCODE } ''); + +implementation + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdhuff_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdhuff_del.pas new file mode 100644 index 0000000..05b0425 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdhuff_del.pas @@ -0,0 +1,1205 @@ +unit jdhuff_del; + +{ This file contains declarations for Huffman entropy decoding routines + that are shared between the sequential decoder (jdhuff.c) and the + progressive decoder (jdphuff.c). No other modules need to see these. } + +{ This file contains Huffman entropy decoding routines. + + Much of the complexity here has to do with supporting input suspension. + If the data source module demands suspension, we want to be able to back + up to the start of the current MCU. To do this, we copy state variables + into local working storage, and update them back to the permanent + storage only upon successful completion of an MCU. } + +{ Original: jdhuff.h+jdhuff.c; Copyright (C) 1991-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jutils_del, + jpeglib_del; + + +{ Declarations shared with jdphuff.c } + + + +{ Derived data constructed for each Huffman table } + +const + HUFF_LOOKAHEAD = 8; { # of bits of lookahead } + +type + d_derived_tbl_ptr = ^d_derived_tbl; + d_derived_tbl = record + { Basic tables: (element [0] of each array is unused) } + maxcode : array[0..18-1] of INT32; { largest code of length k (-1 if none) } + { (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) } + valoffset : array[0..17-1] of INT32; { huffval[] offset for codes of length k } + { valoffset[k] = huffval[] index of 1st symbol of code length k, less + the smallest code of length k; so given a code of length k, the + corresponding symbol is huffval[code + valoffset[k]] } + + { Link to public Huffman table (needed only in jpeg_huff_decode) } + pub : JHUFF_TBL_PTR; + + { Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of + the input data stream. If the next Huffman code is no more + than HUFF_LOOKAHEAD bits long, we can obtain its length and + the corresponding symbol directly from these tables. } + + look_nbits : array[0..(1 shl HUFF_LOOKAHEAD)-1] of int; + { # bits, or 0 if too long } + look_sym : array[0..(1 shl HUFF_LOOKAHEAD)-1] of UINT8; + { symbol, or unused } + end; + +{ Fetching the next N bits from the input stream is a time-critical operation + for the Huffman decoders. We implement it with a combination of inline + macros and out-of-line subroutines. Note that N (the number of bits + demanded at one time) never exceeds 15 for JPEG use. + + We read source bytes into get_buffer and dole out bits as needed. + If get_buffer already contains enough bits, they are fetched in-line + by the macros CHECK_BIT_BUFFER and GET_BITS. When there aren't enough + bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer + as full as possible (not just to the number of bits needed; this + prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer). + Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension. + On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains + at least the requested number of bits --- dummy zeroes are inserted if + necessary. } + + +type + bit_buf_type = INT32 ; { type of bit-extraction buffer } +const + BIT_BUF_SIZE = 32; { size of buffer in bits } + +{ If long is > 32 bits on your machine, and shifting/masking longs is + reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE + appropriately should be a win. Unfortunately we can't define the size + with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) + because not all machines measure sizeof in 8-bit bytes. } + +type + bitread_perm_state = record { Bitreading state saved across MCUs } + get_buffer : bit_buf_type; { current bit-extraction buffer } + bits_left : int; { # of unused bits in it } + end; + +type + bitread_working_state = record + { Bitreading working state within an MCU } + { current data source location } + { We need a copy, rather than munging the original, in case of suspension } + next_input_byte : JOCTETptr; { => next byte to read from source } + bytes_in_buffer : size_t; { # of bytes remaining in source buffer } + { Bit input buffer --- note these values are kept in register variables, + not in this struct, inside the inner loops. } + + get_buffer : bit_buf_type; { current bit-extraction buffer } + bits_left : int; { # of unused bits in it } + { Pointer needed by jpeg_fill_bit_buffer } + cinfo : j_decompress_ptr; { back link to decompress master record } + end; + +{ Module initialization routine for Huffman entropy decoding. } + +{GLOBAL} +procedure jinit_huff_decoder (cinfo : j_decompress_ptr); + +{GLOBAL} +function jpeg_huff_decode(var state : bitread_working_state; + get_buffer : bit_buf_type; {register} + bits_left : int; {register} + htbl : d_derived_tbl_ptr; + min_bits : int) : int; + +{ Compute the derived values for a Huffman table. + Note this is also used by jdphuff.c. } + +{GLOBAL} +procedure jpeg_make_d_derived_tbl (cinfo : j_decompress_ptr; + isDC : boolean; + tblno : int; + var pdtbl : d_derived_tbl_ptr); + +{ Load up the bit buffer to a depth of at least nbits } + +function jpeg_fill_bit_buffer (var state : bitread_working_state; + get_buffer : bit_buf_type; {register} + bits_left : int; {register} + nbits : int) : boolean; + +implementation + +{$IFDEF MACRO} + +{ Macros to declare and load/save bitread local variables. } +{$define BITREAD_STATE_VARS} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; + +{$define BITREAD_LOAD_STATE(cinfop,permstate)} + br_state.cinfo := cinfop; + br_state.next_input_byte := cinfop^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfop^.src^.bytes_in_buffer; + get_buffer := permstate.get_buffer; + bits_left := permstate.bits_left; + +{$define BITREAD_SAVE_STATE(cinfop,permstate) } + cinfop^.src^.next_input_byte := br_state.next_input_byte; + cinfop^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + permstate.get_buffer := get_buffer; + permstate.bits_left := bits_left; + + +{ These macros provide the in-line portion of bit fetching. + Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer + before using GET_BITS, PEEK_BITS, or DROP_BITS. + The variables get_buffer and bits_left are assumed to be locals, + but the state struct might not be (jpeg_huff_decode needs this). + CHECK_BIT_BUFFER(state,n,action); + Ensure there are N bits in get_buffer; if suspend, take action. + val = GET_BITS(n); + Fetch next N bits. + val = PEEK_BITS(n); + Fetch next N bits without removing them from the buffer. + DROP_BITS(n); + Discard next N bits. + The value N should be a simple variable, not an expression, because it + is evaluated multiple times. } + + +{$define CHECK_BIT_BUFFER(state,nbits,action)} + if (bits_left < (nbits)) then + begin + if (not jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) then + begin + action; + exit; + end; + get_buffer := state.get_buffer; + bits_left := state.bits_left; + end; + + +{$define GET_BITS(nbits)} + Dec(bits_left, (nbits)); + ( (int(get_buffer shr bits_left)) and ( pred(1 shl (nbits)) ) ) + +{$define PEEK_BITS(nbits)} + int(get_buffer shr (bits_left - (nbits))) and pred(1 shl (nbits)) + +{$define DROP_BITS(nbits)} + Dec(bits_left, nbits); + + + + +{ Code for extracting next Huffman-coded symbol from input bit stream. + Again, this is time-critical and we make the main paths be macros. + + We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits + without looping. Usually, more than 95% of the Huffman codes will be 8 + or fewer bits long. The few overlength codes are handled with a loop, + which need not be inline code. + + Notes about the HUFF_DECODE macro: + 1. Near the end of the data segment, we may fail to get enough bits + for a lookahead. In that case, we do it the hard way. + 2. If the lookahead table contains no entry, the next code must be + more than HUFF_LOOKAHEAD bits long. + 3. jpeg_huff_decode returns -1 if forced to suspend. } + + + + +macro HUFF_DECODE(s,br_state,htbl,return FALSE,slowlabel); +label showlabel; +var + nb, look : int; {register} +begin + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto slowlabel; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := htbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := htbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; +slowlabel: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,htbl,nb)); + if (s < 0) then + begin + result := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; +end; + + +{$ENDIF} {MACRO} + +{ Expanded entropy decoder object for Huffman decoding. + + The savable_state subrecord contains fields that change within an MCU, + but must not be updated permanently until we complete the MCU. } + +type + savable_state = record + last_dc_val : array[0..MAX_COMPS_IN_SCAN-1] of int; { last DC coef for each component } + end; + + +type + huff_entropy_ptr = ^huff_entropy_decoder; + huff_entropy_decoder = record + pub : jpeg_entropy_decoder; { public fields } + + { These fields are loaded into local variables at start of each MCU. + In case of suspension, we exit WITHOUT updating them. } + + bitstate : bitread_perm_state; { Bit buffer at start of MCU } + saved : savable_state; { Other state at start of MCU } + + { These fields are NOT loaded into local working state. } + restarts_to_go : uInt; { MCUs left in this restart interval } + + { Pointers to derived tables (these workspaces have image lifespan) } + dc_derived_tbls : array[0..NUM_HUFF_TBLS] of d_derived_tbl_ptr; + ac_derived_tbls : array[0..NUM_HUFF_TBLS] of d_derived_tbl_ptr; + + { Precalculated info set up by start_pass for use in decode_mcu: } + + { Pointers to derived tables to be used for each block within an MCU } + dc_cur_tbls : array[0..D_MAX_BLOCKS_IN_MCU-1] of d_derived_tbl_ptr; + ac_cur_tbls : array[0..D_MAX_BLOCKS_IN_MCU-1] of d_derived_tbl_ptr; + { Whether we care about the DC and AC coefficient values for each block } + dc_needed : array[0..D_MAX_BLOCKS_IN_MCU-1] of boolean; + ac_needed : array[0..D_MAX_BLOCKS_IN_MCU-1] of boolean; + end; + + + +{ Initialize for a Huffman-compressed scan. } + +{METHODDEF} +procedure start_pass_huff_decoder (cinfo : j_decompress_ptr); +var + entropy : huff_entropy_ptr; + ci, blkn, dctbl, actbl : int; + compptr : jpeg_component_info_ptr; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + { Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. + This ought to be an error condition, but we make it a warning because + there are some baseline files out there with all zeroes in these bytes. } + + if (cinfo^.Ss <> 0) or (cinfo^.Se <> DCTSIZE2-1) or + (cinfo^.Ah <> 0) or (cinfo^.Al <> 0) then + WARNMS(j_common_ptr(cinfo), JWRN_NOT_SEQUENTIAL); + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + dctbl := compptr^.dc_tbl_no; + actbl := compptr^.ac_tbl_no; + { Compute derived values for Huffman tables } + { We may do this more than once for a table, but it's not expensive } + jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, + entropy^.dc_derived_tbls[dctbl]); + jpeg_make_d_derived_tbl(cinfo, FALSE, actbl, + entropy^.ac_derived_tbls[actbl]); + { Initialize DC predictions to 0 } + entropy^.saved.last_dc_val[ci] := 0; + end; + + { Precalculate decoding info for each block in an MCU of this scan } + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + ci := cinfo^.MCU_membership[blkn]; + compptr := cinfo^.cur_comp_info[ci]; + { Precalculate which table to use for each block } + entropy^.dc_cur_tbls[blkn] := entropy^.dc_derived_tbls[compptr^.dc_tbl_no]; + entropy^.ac_cur_tbls[blkn] := entropy^.ac_derived_tbls[compptr^.ac_tbl_no]; + { Decide whether we really care about the coefficient values } + if (compptr^.component_needed) then + begin + entropy^.dc_needed[blkn] := TRUE; + { we don't need the ACs if producing a 1/8th-size image } + entropy^.ac_needed[blkn] := (compptr^.DCT_scaled_size > 1); + end + else + begin + entropy^.ac_needed[blkn] := FALSE; + entropy^.dc_needed[blkn] := FALSE; + end; + end; + + { Initialize bitread state variables } + entropy^.bitstate.bits_left := 0; + entropy^.bitstate.get_buffer := 0; { unnecessary, but keeps Purify quiet } + entropy^.pub.insufficient_data := FALSE; + + { Initialize restart counter } + entropy^.restarts_to_go := cinfo^.restart_interval; +end; + + +{ Compute the derived values for a Huffman table. + This routine also performs some validation checks on the table. + + Note this is also used by jdphuff.c. } + +{GLOBAL} +procedure jpeg_make_d_derived_tbl (cinfo : j_decompress_ptr; + isDC : boolean; + tblno : int; + var pdtbl : d_derived_tbl_ptr); +var + htbl : JHUFF_TBL_PTR; + dtbl : d_derived_tbl_ptr; + p, i, l, si, numsymbols : int; + lookbits, ctr : int; + huffsize : array[0..257-1] of byte; + huffcode : array[0..257-1] of uInt; + code : uInt; +var + sym : int; +begin + { Note that huffsize[] and huffcode[] are filled in code-length order, + paralleling the order of the symbols themselves in htbl^.huffval[]. } + + { Find the input Huffman table } + if (tblno < 0) or (tblno >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, tblno); + if isDC then + htbl := cinfo^.dc_huff_tbl_ptrs[tblno] + else + htbl := cinfo^.ac_huff_tbl_ptrs[tblno]; + if (htbl = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, tblno); + + { Allocate a workspace if we haven't already done so. } + if (pdtbl = NIL) then + pdtbl := d_derived_tbl_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(d_derived_tbl)) ); + dtbl := pdtbl; + dtbl^.pub := htbl; { fill in back link } + + { Figure C.1: make table of Huffman code length for each symbol } + + p := 0; + for l := 1 to 16 do + begin + i := int(htbl^.bits[l]); + if (i < 0) or (p + i > 256) then { protect against table overrun } + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + while (i > 0) do + begin + huffsize[p] := byte(l); + Inc(p); + Dec(i); + end; + end; + huffsize[p] := 0; + numsymbols := p; + + { Figure C.2: generate the codes themselves } + { We also validate that the counts represent a legal Huffman code tree. } + + code := 0; + si := huffsize[0]; + p := 0; + while (huffsize[p] <> 0) do + begin + while (( int (huffsize[p]) ) = si) do + begin + huffcode[p] := code; + Inc(p); + Inc(code); + end; + { code is now 1 more than the last code used for codelength si; but + it must still fit in si bits, since no code is allowed to be all ones. } + + if (INT32(code) >= (INT32(1) shl si)) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + + code := code shl 1; + Inc(si); + end; + + { Figure F.15: generate decoding tables for bit-sequential decoding } + + p := 0; + for l := 1 to 16 do + begin + if (htbl^.bits[l] <> 0) then + begin + { valoffset[l] = huffval[] index of 1st symbol of code length l, + minus the minimum code of length l } + + dtbl^.valoffset[l] := INT32(p) - INT32(huffcode[p]); + Inc(p, htbl^.bits[l]); + dtbl^.maxcode[l] := huffcode[p-1]; { maximum code of length l } + end + else + begin + dtbl^.maxcode[l] := -1; { -1 if no codes of this length } + end; + end; + dtbl^.maxcode[17] := long($FFFFF); { ensures jpeg_huff_decode terminates } + + { Compute lookahead tables to speed up decoding. + First we set all the table entries to 0, indicating "too long"; + then we iterate through the Huffman codes that are short enough and + fill in all the entries that correspond to bit sequences starting + with that code. } + + MEMZERO(@dtbl^.look_nbits, SIZEOF(dtbl^.look_nbits)); + + p := 0; + for l := 1 to HUFF_LOOKAHEAD do + begin + for i := 1 to int (htbl^.bits[l]) do + begin + { l := current code's length, p := its index in huffcode[] & huffval[]. } + { Generate left-justified code followed by all possible bit sequences } + lookbits := huffcode[p] shl (HUFF_LOOKAHEAD-l); + for ctr := pred(1 shl (HUFF_LOOKAHEAD-l)) downto 0 do + begin + dtbl^.look_nbits[lookbits] := l; + dtbl^.look_sym[lookbits] := htbl^.huffval[p]; + Inc(lookbits); + end; + Inc(p); + end; + end; + + { Validate symbols as being reasonable. + For AC tables, we make no check, but accept all byte values 0..255. + For DC tables, we require the symbols to be in range 0..15. + (Tighter bounds could be applied depending on the data depth and mode, + but this is sufficient to ensure safe decoding.) } + + if (isDC) then + begin + for i := 0 to pred(numsymbols) do + begin + sym := htbl^.huffval[i]; + if (sym < 0) or (sym > 15) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + end; + end; +end; + + +{ Out-of-line code for bit fetching (shared with jdphuff.c). + See jdhuff.h for info about usage. + Note: current values of get_buffer and bits_left are passed as parameters, + but are returned in the corresponding fields of the state struct. + + On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width + of get_buffer to be used. (On machines with wider words, an even larger + buffer could be used.) However, on some machines 32-bit shifts are + quite slow and take time proportional to the number of places shifted. + (This is true with most PC compilers, for instance.) In this case it may + be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the + average shift distance at the cost of more calls to jpeg_fill_bit_buffer. } + +{$ifdef SLOW_SHIFT_32} +const + MIN_GET_BITS = 15; { minimum allowable value } +{$else} +const + MIN_GET_BITS = (BIT_BUF_SIZE-7); +{$endif} + + +{GLOBAL} +function jpeg_fill_bit_buffer (var state : bitread_working_state; + {register} get_buffer : bit_buf_type; + {register} bits_left : int; + nbits : int) : boolean; +label + no_more_bytes; +{ Load up the bit buffer to a depth of at least nbits } +var + { Copy heavily used state fields into locals (hopefully registers) } + {register} next_input_byte : {const} JOCTETptr; + {register} bytes_in_buffer : size_t; +var + {register} c : int; +var + cinfo : j_decompress_ptr; +begin + next_input_byte := state.next_input_byte; + bytes_in_buffer := state.bytes_in_buffer; + cinfo := state.cinfo; + + { Attempt to load at least MIN_GET_BITS bits into get_buffer. } + { (It is assumed that no request will be for more than that many bits.) } + { We fail to do so only if we hit a marker or are forced to suspend. } + + if (cinfo^.unread_marker = 0) then { cannot advance past a marker } + begin + while (bits_left < MIN_GET_BITS) do + begin + { Attempt to read a byte } + if (bytes_in_buffer = 0) then + begin + if not cinfo^.src^.fill_input_buffer(cinfo) then + begin + jpeg_fill_bit_buffer := FALSE; + exit; + end; + next_input_byte := cinfo^.src^.next_input_byte; + bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + end; + Dec(bytes_in_buffer); + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + + { If it's $FF, check and discard stuffed zero byte } + if (c = $FF) then + begin + { Loop here to discard any padding FF's on terminating marker, + so that we can save a valid unread_marker value. NOTE: we will + accept multiple FF's followed by a 0 as meaning a single FF data + byte. This data pattern is not valid according to the standard. } + + repeat + if (bytes_in_buffer = 0) then + begin + if (not state.cinfo^.src^.fill_input_buffer (state.cinfo)) then + begin + jpeg_fill_bit_buffer := FALSE; + exit; + end; + next_input_byte := state.cinfo^.src^.next_input_byte; + bytes_in_buffer := state.cinfo^.src^.bytes_in_buffer; + end; + Dec(bytes_in_buffer); + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + Until (c <> $FF); + + if (c = 0) then + begin + { Found FF/00, which represents an FF data byte } + c := $FF; + end + else + begin + { Oops, it's actually a marker indicating end of compressed data. + Save the marker code for later use. + Fine point: it might appear that we should save the marker into + bitread working state, not straight into permanent state. But + once we have hit a marker, we cannot need to suspend within the + current MCU, because we will read no more bytes from the data + source. So it is OK to update permanent state right away. } + + cinfo^.unread_marker := c; + { See if we need to insert some fake zero bits. } + goto no_more_bytes; + end; + end; + + { OK, load c into get_buffer } + get_buffer := (get_buffer shl 8) or c; + Inc(bits_left, 8); + end { end while } + end + else + begin + no_more_bytes: + { We get here if we've read the marker that terminates the compressed + data segment. There should be enough bits in the buffer register + to satisfy the request; if so, no problem. } + + if (nbits > bits_left) then + begin + { Uh-oh. Report corrupted data to user and stuff zeroes into + the data stream, so that we can produce some kind of image. + We use a nonvolatile flag to ensure that only one warning message + appears per data segment. } + + if not cinfo^.entropy^.insufficient_data then + begin + WARNMS(j_common_ptr(cinfo), JWRN_HIT_MARKER); + cinfo^.entropy^.insufficient_data := TRUE; + end; + { Fill the buffer with zero bits } + get_buffer := get_buffer shl (MIN_GET_BITS - bits_left); + bits_left := MIN_GET_BITS; + end; + end; + + { Unload the local registers } + state.next_input_byte := next_input_byte; + state.bytes_in_buffer := bytes_in_buffer; + state.get_buffer := get_buffer; + state.bits_left := bits_left; + + jpeg_fill_bit_buffer := TRUE; +end; + + +{ Out-of-line code for Huffman code decoding. + See jdhuff.h for info about usage. } + +{GLOBAL} +function jpeg_huff_decode (var state : bitread_working_state; + {register} get_buffer : bit_buf_type; + {register} bits_left : int; + htbl : d_derived_tbl_ptr; + min_bits : int) : int; +var + {register} l : int; + {register} code : INT32; +begin + l := min_bits; + + { HUFF_DECODE has determined that the code is at least min_bits } + { bits long, so fetch that many bits in one swoop. } + + {CHECK_BIT_BUFFER(state, l, return -1);} + if (bits_left < l) then + begin + if (not jpeg_fill_bit_buffer(state, get_buffer, bits_left, l)) then + begin + jpeg_huff_decode := -1; + exit; + end; + get_buffer := state.get_buffer; + bits_left := state.bits_left; + end; + + {code := GET_BITS(l);} + Dec(bits_left, l); + code := (int(get_buffer shr bits_left)) and ( pred(1 shl l) ); + + { Collect the rest of the Huffman code one bit at a time. } + { This is per Figure F.16 in the JPEG spec. } + + while (code > htbl^.maxcode[l]) do + begin + code := code shl 1; + {CHECK_BIT_BUFFER(state, 1, return -1);} + if (bits_left < 1) then + begin + if (not jpeg_fill_bit_buffer(state, get_buffer, bits_left, 1)) then + begin + jpeg_huff_decode := -1; + exit; + end; + get_buffer := state.get_buffer; + bits_left := state.bits_left; + end; + + {code := code or GET_BITS(1);} + Dec(bits_left); + code := code or ( (int(get_buffer shr bits_left)) and pred(1 shl 1) ); + + Inc(l); + end; + + { Unload the local registers } + state.get_buffer := get_buffer; + state.bits_left := bits_left; + + { With garbage input we may reach the sentinel value l := 17. } + + if (l > 16) then + begin + WARNMS(j_common_ptr(state.cinfo), JWRN_HUFF_BAD_CODE); + jpeg_huff_decode := 0; { fake a zero as the safest result } + exit; + end; + + jpeg_huff_decode := htbl^.pub^.huffval[ int (code + htbl^.valoffset[l]) ]; +end; + + +{ Figure F.12: extend sign bit. + On some machines, a shift and add will be faster than a table lookup. } + +{$ifdef AVOID_TABLES} + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +{$else} + +{$define HUFF_EXTEND(x,s) + if (x < extend_test[s]) then + := x + extend_offset[s] + else + x;} + +const + extend_test : array[0..16-1] of int = { entry n is 2**(n-1) } + ($0000, $0001, $0002, $0004, $0008, $0010, $0020, $0040, + $0080, $0100, $0200, $0400, $0800, $1000, $2000, $4000); + +const + extend_offset : array[0..16-1] of int = { entry n is (-1 << n) + 1 } +(0, ((-1) shl 1) + 1, ((-1) shl 2) + 1, ((-1) shl 3) + 1, ((-1) shl 4) + 1, + ((-1) shl 5) + 1, ((-1) shl 6) + 1, ((-1) shl 7) + 1, ((-1) shl 8) + 1, + ((-1) shl 9) + 1, ((-1) shl 10) + 1, ((-1) shl 11) + 1,((-1) shl 12) + 1, + ((-1) shl 13) + 1, ((-1) shl 14) + 1, ((-1) shl 15) + 1); + +{$endif} { AVOID_TABLES } + + +{ Check for a restart marker & resynchronize decoder. + Returns FALSE if must suspend. } + +{LOCAL} +function process_restart (cinfo : j_decompress_ptr) : boolean; +var + entropy : huff_entropy_ptr; + ci : int; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + { Throw away any unused bits remaining in bit buffer; } + { include any full bytes in next_marker's count of discarded bytes } + Inc(cinfo^.marker^.discarded_bytes, entropy^.bitstate.bits_left div 8); + entropy^.bitstate.bits_left := 0; + + { Advance past the RSTn marker } + if (not cinfo^.marker^.read_restart_marker (cinfo)) then + begin + process_restart := FALSE; + exit; + end; + + { Re-initialize DC predictions to 0 } + for ci := 0 to pred(cinfo^.comps_in_scan) do + entropy^.saved.last_dc_val[ci] := 0; + + { Reset restart counter } + entropy^.restarts_to_go := cinfo^.restart_interval; + + { Reset out-of-data flag, unless read_restart_marker left us smack up + against a marker. In that case we will end up treating the next data + segment as empty, and we can avoid producing bogus output pixels by + leaving the flag set. } + + if (cinfo^.unread_marker = 0) then + entropy^.pub.insufficient_data := FALSE; + + process_restart := TRUE; +end; + + +{ Decode and return one MCU's worth of Huffman-compressed coefficients. + The coefficients are reordered from zigzag order into natural array order, + but are not dequantized. + + The i'th block of the MCU is stored into the block pointed to by + MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. + (Wholesale zeroing is usually a little faster than retail...) + + Returns FALSE if data source requested suspension. In that case no + changes have been made to permanent state. (Exception: some output + coefficients may already have been assigned. This is harmless for + this module, since we'll just re-assign them on the next call.) } + +{METHODDEF} +function decode_mcu (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; +label + label1, label2, label3; +var + entropy : huff_entropy_ptr; + {register} s, k, r : int; + blkn, ci : int; + block : JBLOCK_PTR; + {BITREAD_STATE_VARS} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; + + state : savable_state; + dctbl : d_derived_tbl_ptr; + actbl : d_derived_tbl_ptr; +var + nb, look : int; {register} +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + { Process restart marker if needed; may have to suspend } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if (not process_restart(cinfo)) then + begin + decode_mcu := FALSE; + exit; + end; + end; + + { If we've run out of data, just leave the MCU set to zeroes. + This way, we return uniform gray for the remainder of the segment. } + + if not entropy^.pub.insufficient_data then + begin + + { Load up working state } + {BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);} + br_state.cinfo := cinfo; + br_state.next_input_byte := cinfo^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + get_buffer := entropy^.bitstate.get_buffer; + bits_left := entropy^.bitstate.bits_left; + + {ASSIGN_STATE(state, entropy^.saved);} + state := entropy^.saved; + + { Outer loop handles each block in the MCU } + + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + block := JBLOCK_PTR(MCU_data[blkn]); + dctbl := entropy^.dc_cur_tbls[blkn]; + actbl := entropy^.ac_cur_tbls[blkn]; + + { Decode a single block's worth of coefficients } + + { Section F.2.2.1: decode the DC coefficient difference } + {HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu := False; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label1; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := dctbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := dctbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label1: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,dctbl,nb); + if (s < 0) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + if (s <> 0) then + begin + {CHECK_BIT_BUFFER(br_state, s, return FALSE);} + if (bits_left < s) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(s);} + Dec(bits_left, s); + r := ( int(get_buffer shr bits_left)) and ( pred(1 shl s) ); + + {s := HUFF_EXTEND(r, s);} + if (r < extend_test[s]) then + s := r + extend_offset[s] + else + s := r; + end; + + if (entropy^.dc_needed[blkn]) then + begin + { Convert DC difference to actual value, update last_dc_val } + ci := cinfo^.MCU_membership[blkn]; + Inc(s, state.last_dc_val[ci]); + state.last_dc_val[ci] := s; + { Output the DC coefficient (assumes jpeg_natural_order[0] := 0) } + block^[0] := JCOEF (s); + end; + + if (entropy^.ac_needed[blkn]) then + begin + + { Section F.2.2.2: decode the AC coefficients } + { Since zeroes are skipped, output area must be cleared beforehand } + k := 1; + while (k < DCTSIZE2) do { Nomssi: k is incr. in the loop } + begin + {HUFF_DECODE(s, br_state, actbl, return FALSE, label2);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu := False; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label2; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := actbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := actbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label2: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,actbl,nb); + if (s < 0) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + r := s shr 4; + s := s and 15; + + if (s <> 0) then + begin + Inc(k, r); + {CHECK_BIT_BUFFER(br_state, s, return FALSE);} + if (bits_left < s) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(s);} + Dec(bits_left, s); + r := (int(get_buffer shr bits_left)) and ( pred(1 shl s) ); + + {s := HUFF_EXTEND(r, s);} + if (r < extend_test[s]) then + s := r + extend_offset[s] + else + s := r; + { Output coefficient in natural (dezigzagged) order. + Note: the extra entries in jpeg_natural_order[] will save us + if k >= DCTSIZE2, which could happen if the data is corrupted. } + + block^[jpeg_natural_order[k]] := JCOEF (s); + end + else + begin + if (r <> 15) then + break; + Inc(k, 15); + end; + Inc(k); + end; + end + else + begin + + { Section F.2.2.2: decode the AC coefficients } + { In this path we just discard the values } + k := 1; + while (k < DCTSIZE2) do + begin + {HUFF_DECODE(s, br_state, actbl, return FALSE, label3);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu := False; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label3; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := actbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := actbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label3: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,actbl,nb); + if (s < 0) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + r := s shr 4; + s := s and 15; + + if (s <> 0) then + begin + Inc(k, r); + {CHECK_BIT_BUFFER(br_state, s, return FALSE);} + if (bits_left < s) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {DROP_BITS(s);} + Dec(bits_left, s); + end + else + begin + if (r <> 15) then + break; + Inc(k, 15); + end; + Inc(k); + end; + + end; + end; + + { Completed MCU, so update state } + {BITREAD_SAVE_STATE(cinfo,entropy^.bitstate);} + cinfo^.src^.next_input_byte := br_state.next_input_byte; + cinfo^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + entropy^.bitstate.get_buffer := get_buffer; + entropy^.bitstate.bits_left := bits_left; + + {ASSIGN_STATE(entropy^.saved, state);} + entropy^.saved := state; + + end; + + { Account for restart interval (no-op if not using restarts) } + Dec(entropy^.restarts_to_go); + + decode_mcu := TRUE; +end; + + +{ Module initialization routine for Huffman entropy decoding. } + +{GLOBAL} +procedure jinit_huff_decoder (cinfo : j_decompress_ptr); +var + entropy : huff_entropy_ptr; + i : int; +begin + entropy := huff_entropy_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(huff_entropy_decoder)) ); + cinfo^.entropy := jpeg_entropy_decoder_ptr (entropy); + entropy^.pub.start_pass := start_pass_huff_decoder; + entropy^.pub.decode_mcu := decode_mcu; + + { Mark tables unallocated } + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + entropy^.dc_derived_tbls[i] := NIL; + entropy^.ac_derived_tbls[i] := NIL; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdinput_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdinput_del.pas new file mode 100644 index 0000000..304379a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdinput_del.pas @@ -0,0 +1,417 @@ +unit jdinput_del; + +{ Original: jdinput.c ; Copyright (C) 1991-1997, Thomas G. Lane. } + +{ This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains input control logic for the JPEG decompressor. + These routines are concerned with controlling the decompressor's input + processing (marker reading and coefficient decoding). The actual input + reading is done in jdmarker.c, jdhuff.c, and jdphuff.c. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jpeglib_del, + jdeferr_del, + jerror_del, + jinclude_del, jutils_del; + +{ Initialize the input controller module. + This is called only once, when the decompression object is created. } + +{GLOBAL} +procedure jinit_input_controller (cinfo : j_decompress_ptr); + +implementation + +{ Private state } + +type + my_inputctl_ptr = ^my_input_controller; + my_input_controller = record + pub : jpeg_input_controller; { public fields } + + inheaders : boolean; { TRUE until first SOS is reached } + end; {my_input_controller;} + + + +{ Forward declarations } +{METHODDEF} +function consume_markers (cinfo : j_decompress_ptr) : int; forward; + + +{ Routines to calculate various quantities related to the size of the image. } + +{LOCAL} +procedure initial_setup (cinfo : j_decompress_ptr); +{ Called once, when first SOS marker is reached } +var + ci : int; + compptr : jpeg_component_info_ptr; +begin + { Make sure image isn't bigger than I can handle } + if (long(cinfo^.image_height) > long (JPEG_MAX_DIMENSION)) or + (long(cinfo^.image_width) > long(JPEG_MAX_DIMENSION)) then + ERREXIT1(j_common_ptr(cinfo), JERR_IMAGE_TOO_BIG, uInt(JPEG_MAX_DIMENSION)); + + { For now, precision must match compiled-in value... } + if (cinfo^.data_precision <> BITS_IN_JSAMPLE) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PRECISION, cinfo^.data_precision); + + { Check that number of components won't exceed internal array sizes } + if (cinfo^.num_components > MAX_COMPONENTS) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.num_components, + MAX_COMPONENTS); + + { Compute maximum sampling factors; check factor validity } + cinfo^.max_h_samp_factor := 1; + cinfo^.max_v_samp_factor := 1; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + if (compptr^.h_samp_factor<=0) or (compptr^.h_samp_factor>MAX_SAMP_FACTOR) or + (compptr^.v_samp_factor<=0) or (compptr^.v_samp_factor>MAX_SAMP_FACTOR) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_SAMPLING); + {cinfo^.max_h_samp_factor := MAX(cinfo^.max_h_samp_factor, + compptr^.h_samp_factor); + cinfo^.max_v_samp_factor := MAX(cinfo^.max_v_samp_factor, + compptr^.v_samp_factor);} + if cinfo^.max_h_samp_factor < compptr^.h_samp_factor then + cinfo^.max_h_samp_factor := compptr^.h_samp_factor; + if cinfo^.max_v_samp_factor < compptr^.v_samp_factor then + cinfo^.max_v_samp_factor := compptr^.v_samp_factor; + Inc(compptr); + end; + + { We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE. + In the full decompressor, this will be overridden by jdmaster.c; + but in the transcoder, jdmaster.c is not used, so we must do it here. } + + cinfo^.min_DCT_scaled_size := DCTSIZE; + + { Compute dimensions of components } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + compptr^.DCT_scaled_size := DCTSIZE; + { Size in DCT blocks } + compptr^.width_in_blocks := JDIMENSION( + jdiv_round_up( long(cinfo^.image_width) * long(compptr^.h_samp_factor), + long(cinfo^.max_h_samp_factor * DCTSIZE)) ); + compptr^.height_in_blocks := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height) * long(compptr^.v_samp_factor), + long (cinfo^.max_v_samp_factor * DCTSIZE)) ); + { downsampled_width and downsampled_height will also be overridden by + jdmaster.c if we are doing full decompression. The transcoder library + doesn't use these values, but the calling application might. } + + { Size in samples } + compptr^.downsampled_width := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_width) * long(compptr^.h_samp_factor), + long (cinfo^.max_h_samp_factor)) ); + compptr^.downsampled_height := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height) * long(compptr^.v_samp_factor), + long (cinfo^.max_v_samp_factor)) ); + { Mark component needed, until color conversion says otherwise } + compptr^.component_needed := TRUE; + { Mark no quantization table yet saved for component } + compptr^.quant_table := NIL; + Inc(compptr); + end; + + { Compute number of fully interleaved MCU rows. } + cinfo^.total_iMCU_rows := JDIMENSION( + jdiv_round_up(long(cinfo^.image_height), + long(cinfo^.max_v_samp_factor*DCTSIZE)) ); + + { Decide whether file contains multiple scans } + if (cinfo^.comps_in_scan < cinfo^.num_components) or + (cinfo^.progressive_mode) then + cinfo^.inputctl^.has_multiple_scans := TRUE + else + cinfo^.inputctl^.has_multiple_scans := FALSE; +end; + + +{LOCAL} +procedure per_scan_setup (cinfo : j_decompress_ptr); +{ Do computations that are needed before processing a JPEG scan } +{ cinfo^.comps_in_scan and cinfo^.cur_comp_info[] were set from SOS marker } +var + ci, mcublks, tmp : int; + compptr : jpeg_component_info_ptr; +begin + if (cinfo^.comps_in_scan = 1) then + begin + { Noninterleaved (single-component) scan } + compptr := cinfo^.cur_comp_info[0]; + + { Overall image size in MCUs } + cinfo^.MCUs_per_row := compptr^.width_in_blocks; + cinfo^.MCU_rows_in_scan := compptr^.height_in_blocks; + + { For noninterleaved scan, always one block per MCU } + compptr^.MCU_width := 1; + compptr^.MCU_height := 1; + compptr^.MCU_blocks := 1; + compptr^.MCU_sample_width := compptr^.DCT_scaled_size; + compptr^.last_col_width := 1; + { For noninterleaved scans, it is convenient to define last_row_height + as the number of block rows present in the last iMCU row. } + + tmp := int (compptr^.height_in_blocks mod compptr^.v_samp_factor); + if (tmp = 0) then + tmp := compptr^.v_samp_factor; + compptr^.last_row_height := tmp; + + { Prepare array describing MCU composition } + cinfo^.blocks_in_MCU := 1; + cinfo^.MCU_membership[0] := 0; + + end + else + begin + + { Interleaved (multi-component) scan } + if (cinfo^.comps_in_scan <= 0) or (cinfo^.comps_in_scan > MAX_COMPS_IN_SCAN) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.comps_in_scan, + MAX_COMPS_IN_SCAN); + + { Overall image size in MCUs } + cinfo^.MCUs_per_row := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_width), + long (cinfo^.max_h_samp_factor*DCTSIZE)) ); + cinfo^.MCU_rows_in_scan := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height), + long (cinfo^.max_v_samp_factor*DCTSIZE)) ); + + cinfo^.blocks_in_MCU := 0; + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { Sampling factors give # of blocks of component in each MCU } + compptr^.MCU_width := compptr^.h_samp_factor; + compptr^.MCU_height := compptr^.v_samp_factor; + compptr^.MCU_blocks := compptr^.MCU_width * compptr^.MCU_height; + compptr^.MCU_sample_width := compptr^.MCU_width * compptr^.DCT_scaled_size; + { Figure number of non-dummy blocks in last MCU column & row } + tmp := int (compptr^.width_in_blocks mod compptr^.MCU_width); + if (tmp = 0) then + tmp := compptr^.MCU_width; + compptr^.last_col_width := tmp; + tmp := int (compptr^.height_in_blocks mod compptr^.MCU_height); + if (tmp = 0) then + tmp := compptr^.MCU_height; + compptr^.last_row_height := tmp; + { Prepare array describing MCU composition } + mcublks := compptr^.MCU_blocks; + if (cinfo^.blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_MCU_SIZE); + while (mcublks > 0) do + begin + Dec(mcublks); + cinfo^.MCU_membership[cinfo^.blocks_in_MCU] := ci; + Inc(cinfo^.blocks_in_MCU); + end; + end; + + end; +end; + + +{ Save away a copy of the Q-table referenced by each component present + in the current scan, unless already saved during a prior scan. + + In a multiple-scan JPEG file, the encoder could assign different components + the same Q-table slot number, but change table definitions between scans + so that each component uses a different Q-table. (The IJG encoder is not + currently capable of doing this, but other encoders might.) Since we want + to be able to dequantize all the components at the end of the file, this + means that we have to save away the table actually used for each component. + We do this by copying the table at the start of the first scan containing + the component. + The JPEG spec prohibits the encoder from changing the contents of a Q-table + slot between scans of a component using that slot. If the encoder does so + anyway, this decoder will simply use the Q-table values that were current + at the start of the first scan for the component. + + The decompressor output side looks only at the saved quant tables, + not at the current Q-table slots. } + +{LOCAL} +procedure latch_quant_tables (cinfo : j_decompress_ptr); +var + ci, qtblno : int; + compptr : jpeg_component_info_ptr; + qtbl : JQUANT_TBL_PTR; +begin + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { No work if we already saved Q-table for this component } + if (compptr^.quant_table <> NIL) then + continue; + { Make sure specified quantization table is present } + qtblno := compptr^.quant_tbl_no; + if (qtblno < 0) or (qtblno >= NUM_QUANT_TBLS) or + (cinfo^.quant_tbl_ptrs[qtblno] = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_QUANT_TABLE, qtblno); + { OK, save away the quantization table } + qtbl := JQUANT_TBL_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(JQUANT_TBL)) ); + MEMCOPY(qtbl, cinfo^.quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); + compptr^.quant_table := qtbl; + end; +end; + + +{ Initialize the input modules to read a scan of compressed data. + The first call to this is done by jdmaster.c after initializing + the entire decompressor (during jpeg_start_decompress). + Subsequent calls come from consume_markers, below. } + +{METHODDEF} +procedure start_input_pass (cinfo : j_decompress_ptr); +begin + per_scan_setup(cinfo); + latch_quant_tables(cinfo); + cinfo^.entropy^.start_pass (cinfo); + cinfo^.coef^.start_input_pass (cinfo); + cinfo^.inputctl^.consume_input := cinfo^.coef^.consume_data; +end; + + +{ Finish up after inputting a compressed-data scan. + This is called by the coefficient controller after it's read all + the expected data of the scan. } + +{METHODDEF} +procedure finish_input_pass (cinfo : j_decompress_ptr); +begin + cinfo^.inputctl^.consume_input := consume_markers; +end; + + +{ Read JPEG markers before, between, or after compressed-data scans. + Change state as necessary when a new scan is reached. + Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + + The consume_input method pointer points either here or to the + coefficient controller's consume_data routine, depending on whether + we are reading a compressed data segment or inter-segment markers. } + +{METHODDEF} +function consume_markers (cinfo : j_decompress_ptr) : int; +var + val : int; + inputctl : my_inputctl_ptr; +begin + inputctl := my_inputctl_ptr (cinfo^.inputctl); + + if (inputctl^.pub.eoi_reached) then { After hitting EOI, read no further } + begin + consume_markers := JPEG_REACHED_EOI; + exit; + end; + + val := cinfo^.marker^.read_markers (cinfo); + + case (val) of + JPEG_REACHED_SOS: { Found SOS } + begin + if (inputctl^.inheaders) then + begin { 1st SOS } + initial_setup(cinfo); + inputctl^.inheaders := FALSE; + { Note: start_input_pass must be called by jdmaster.c + before any more input can be consumed. jdapimin.c is + responsible for enforcing this sequencing. } + end + else + begin { 2nd or later SOS marker } + if (not inputctl^.pub.has_multiple_scans) then + ERREXIT(j_common_ptr(cinfo), JERR_EOI_EXPECTED); { Oops, I wasn't expecting this! } + start_input_pass(cinfo); + end; + end; + JPEG_REACHED_EOI: { Found EOI } + begin + inputctl^.pub.eoi_reached := TRUE; + if (inputctl^.inheaders) then + begin { Tables-only datastream, apparently } + if (cinfo^.marker^.saw_SOF) then + ERREXIT(j_common_ptr(cinfo), JERR_SOF_NO_SOS); + end + else + begin + { Prevent infinite loop in coef ctlr's decompress_data routine + if user set output_scan_number larger than number of scans. } + + if (cinfo^.output_scan_number > cinfo^.input_scan_number) then + cinfo^.output_scan_number := cinfo^.input_scan_number; + end; + end; + JPEG_SUSPENDED:; + end; + + consume_markers := val; +end; + + +{ Reset state to begin a fresh datastream. } + +{METHODDEF} +procedure reset_input_controller (cinfo : j_decompress_ptr); +var + inputctl : my_inputctl_ptr; +begin + inputctl := my_inputctl_ptr (cinfo^.inputctl); + + inputctl^.pub.consume_input := consume_markers; + inputctl^.pub.has_multiple_scans := FALSE; { "unknown" would be better } + inputctl^.pub.eoi_reached := FALSE; + inputctl^.inheaders := TRUE; + { Reset other modules } + cinfo^.err^.reset_error_mgr (j_common_ptr(cinfo)); + cinfo^.marker^.reset_marker_reader (cinfo); + { Reset progression state -- would be cleaner if entropy decoder did this } + cinfo^.coef_bits := NIL; +end; + + +{ Initialize the input controller module. + This is called only once, when the decompression object is created. } + +{GLOBAL} +procedure jinit_input_controller (cinfo : j_decompress_ptr); +var + inputctl : my_inputctl_ptr; +begin + { Create subobject in permanent pool } + inputctl := my_inputctl_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + SIZEOF(my_input_controller)) ); + cinfo^.inputctl := jpeg_input_controller_ptr(inputctl); + { Initialize method pointers } + inputctl^.pub.consume_input := consume_markers; + inputctl^.pub.reset_input_controller := reset_input_controller; + inputctl^.pub.start_input_pass := start_input_pass; + inputctl^.pub.finish_input_pass := finish_input_pass; + { Initialize state: can't use reset_input_controller since we don't + want to try to reset other modules yet. } + + inputctl^.pub.has_multiple_scans := FALSE; { "unknown" would be better } + inputctl^.pub.eoi_reached := FALSE; + inputctl^.inheaders := TRUE; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdmainct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdmainct_del.pas new file mode 100644 index 0000000..3a0f65c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdmainct_del.pas @@ -0,0 +1,611 @@ +unit jdmainct_del; + + +{ This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains the main buffer controller for decompression. + The main buffer lies between the JPEG decompressor proper and the + post-processor; it holds downsampled data in the JPEG colorspace. + + Note that this code is bypassed in raw-data mode, since the application + supplies the equivalent of the main buffer in that case. } + +{ Original: jdmainct.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + + +{ In the current system design, the main buffer need never be a full-image + buffer; any full-height buffers will be found inside the coefficient or + postprocessing controllers. Nonetheless, the main controller is not + trivial. Its responsibility is to provide context rows for upsampling/ + rescaling, and doing this in an efficient fashion is a bit tricky. + + Postprocessor input data is counted in "row groups". A row group + is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + sample rows of each component. (We require DCT_scaled_size values to be + chosen such that these numbers are integers. In practice DCT_scaled_size + values will likely be powers of two, so we actually have the stronger + condition that DCT_scaled_size / min_DCT_scaled_size is an integer.) + Upsampling will typically produce max_v_samp_factor pixel rows from each + row group (times any additional scale factor that the upsampler is + applying). + + The coefficient controller will deliver data to us one iMCU row at a time; + each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or + exactly min_DCT_scaled_size row groups. (This amount of data corresponds + to one row of MCUs when the image is fully interleaved.) Note that the + number of sample rows varies across components, but the number of row + groups does not. Some garbage sample rows may be included in the last iMCU + row at the bottom of the image. + + Depending on the vertical scaling algorithm used, the upsampler may need + access to the sample row(s) above and below its current input row group. + The upsampler is required to set need_context_rows TRUE at global + selection + time if so. When need_context_rows is FALSE, this controller can simply + obtain one iMCU row at a time from the coefficient controller and dole it + out as row groups to the postprocessor. + + When need_context_rows is TRUE, this controller guarantees that the buffer + passed to postprocessing contains at least one row group's worth of samples + above and below the row group(s) being processed. Note that the context + rows "above" the first passed row group appear at negative row offsets in + the passed buffer. At the top and bottom of the image, the required + context rows are manufactured by duplicating the first or last real sample + row; this avoids having special cases in the upsampling inner loops. + + The amount of context is fixed at one row group just because that's a + convenient number for this controller to work with. The existing + upsamplers really only need one sample row of context. An upsampler + supporting arbitrary output rescaling might wish for more than one row + group of context when shrinking the image; tough, we don't handle that. + (This is justified by the assumption that downsizing will be handled mostly + by adjusting the DCT_scaled_size values, so that the actual scale factor at + the upsample step needn't be much less than one.) + + To provide the desired context, we have to retain the last two row groups + of one iMCU row while reading in the next iMCU row. (The last row group + can't be processed until we have another row group for its below-context, + and so we have to save the next-to-last group too for its above-context.) + We could do this most simply by copying data around in our buffer, but + that'd be very slow. We can avoid copying any data by creating a rather + strange pointer structure. Here's how it works. We allocate a workspace + consisting of M+2 row groups (where M = min_DCT_scaled_size is the number + of row groups per iMCU row). We create two sets of redundant pointers to + the workspace. Labeling the physical row groups 0 to M+1, the synthesized + pointer lists look like this: + M+1 M-1 + master pointer --> 0 master pointer --> 0 + 1 1 + ... ... + M-3 M-3 + M-2 M + M-1 M+1 + M M-2 + M+1 M-1 + 0 0 + We read alternate iMCU rows using each master pointer; thus the last two + row groups of the previous iMCU row remain un-overwritten in the workspace. + The pointer lists are set up so that the required context rows appear to + be adjacent to the proper places when we pass the pointer lists to the + upsampler. + + The above pictures describe the normal state of the pointer lists. + At top and bottom of the image, we diddle the pointer lists to duplicate + the first or last sample row as necessary (this is cheaper than copying + sample rows around). + + This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that + situation each iMCU row provides only one row group so the buffering logic + must be different (eg, we must read two iMCU rows before we can emit the + first row group). For now, we simply do not support providing context + rows when min_DCT_scaled_size is 1. That combination seems unlikely to + be worth providing --- if someone wants a 1/8th-size preview, they probably + want it quick and dirty, so a context-free upsampler is sufficient. } + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, +{$ifdef QUANT_2PASS_SUPPORTED} + jquant2_del, +{$endif} + jdeferr_del, + jerror_del, + jpeglib_del; + + +{GLOBAL} +procedure jinit_d_main_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); + + +implementation + +{ Private buffer controller object } + +type + my_main_ptr = ^my_main_controller; + my_main_controller = record + pub : jpeg_d_main_controller; { public fields } + + { Pointer to allocated workspace (M or M+2 row groups). } + buffer : array[0..MAX_COMPONENTS-1] of JSAMPARRAY; + + buffer_full : boolean; { Have we gotten an iMCU row from decoder? } + rowgroup_ctr : JDIMENSION ; { counts row groups output to postprocessor } + + { Remaining fields are only used in the context case. } + + { These are the master pointers to the funny-order pointer lists. } + xbuffer : array[0..2-1] of JSAMPIMAGE; { pointers to weird pointer lists } + + whichptr : int; { indicates which pointer set is now in use } + context_state : int; { process_data state machine status } + rowgroups_avail : JDIMENSION; { row groups available to postprocessor } + iMCU_row_ctr : JDIMENSION; { counts iMCU rows to detect image top/bot } + end; { my_main_controller; } + + +{ context_state values: } +const + CTX_PREPARE_FOR_IMCU = 0; { need to prepare for MCU row } + CTX_PROCESS_IMCU = 1; { feeding iMCU to postprocessor } + CTX_POSTPONED_ROW = 2; { feeding postponed row group } + + +{ Forward declarations } +{METHODDEF} +procedure process_data_simple_main(cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; +{METHODDEF} +procedure process_data_context_main (cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; + +{$ifdef QUANT_2PASS_SUPPORTED} +{METHODDEF} +procedure process_data_crank_post (cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; +{$endif} + + +{LOCAL} +procedure alloc_funny_pointers (cinfo : j_decompress_ptr); +{ Allocate space for the funny pointer lists. + This is done only once, not once per pass. } +var + main : my_main_ptr; + ci, rgroup : int; + M : int; + compptr : jpeg_component_info_ptr; + xbuf : JSAMPARRAY; +begin + main := my_main_ptr (cinfo^.main); + M := cinfo^.min_DCT_scaled_size; + + { Get top-level space for component array pointers. + We alloc both arrays with one call to save a few cycles. } + + main^.xbuffer[0] := JSAMPIMAGE ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + cinfo^.num_components * 2 * SIZEOF(JSAMPARRAY)) ); + main^.xbuffer[1] := JSAMPIMAGE(@( main^.xbuffer[0]^[cinfo^.num_components] )); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; { height of a row group of component } + { Get space for pointer lists --- M+4 row groups in each list. + We alloc both pointer lists with one call to save a few cycles. } + + xbuf := JSAMPARRAY ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)) ); + Inc(JSAMPROW_PTR(xbuf), rgroup); { want one row group at negative offsets } + main^.xbuffer[0]^[ci] := xbuf; + Inc(JSAMPROW_PTR(xbuf), rgroup * (M + 4)); + main^.xbuffer[1]^[ci] := xbuf; + Inc(compptr); + end; +end; + +{LOCAL} +procedure make_funny_pointers (cinfo : j_decompress_ptr); +{ Create the funny pointer lists discussed in the comments above. + The actual workspace is already allocated (in main^.buffer), + and the space for the pointer lists is allocated too. + This routine just fills in the curiously ordered lists. + This will be repeated at the beginning of each pass. } +var + main : my_main_ptr; + ci, i, rgroup : int; + M : int; + compptr : jpeg_component_info_ptr; + buf, xbuf0, xbuf1 : JSAMPARRAY; +var + help_xbuf0 : JSAMPARRAY; { work around negative offsets } +begin + main := my_main_ptr (cinfo^.main); + M := cinfo^.min_DCT_scaled_size; + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; { height of a row group of component } + xbuf0 := main^.xbuffer[0]^[ci]; + xbuf1 := main^.xbuffer[1]^[ci]; + { First copy the workspace pointers as-is } + buf := main^.buffer[ci]; + for i := 0 to pred(rgroup * (M + 2)) do + begin + xbuf0^[i] := buf^[i]; + xbuf1^[i] := buf^[i]; + end; + { In the second list, put the last four row groups in swapped order } + for i := 0 to pred(rgroup * 2) do + begin + xbuf1^[rgroup*(M-2) + i] := buf^[rgroup*M + i]; + xbuf1^[rgroup*M + i] := buf^[rgroup*(M-2) + i]; + end; + { The wraparound pointers at top and bottom will be filled later + (see set_wraparound_pointers, below). Initially we want the "above" + pointers to duplicate the first actual data line. This only needs + to happen in xbuffer[0]. } + + help_xbuf0 := xbuf0; + Dec(JSAMPROW_PTR(help_xbuf0), rgroup); + + for i := 0 to pred(rgroup) do + begin + {xbuf0^[i - rgroup] := xbuf0^[0];} + help_xbuf0^[i] := xbuf0^[0]; + end; + Inc(compptr); + end; +end; + + +{LOCAL} +procedure set_wraparound_pointers (cinfo : j_decompress_ptr); +{ Set up the "wraparound" pointers at top and bottom of the pointer lists. + This changes the pointer list state from top-of-image to the normal state. } +var + main : my_main_ptr; + ci, i, rgroup : int; + M : int; + compptr : jpeg_component_info_ptr; + xbuf0, xbuf1 : JSAMPARRAY; +var + help_xbuf0, + help_xbuf1 : JSAMPARRAY; { work around negative offsets } +begin + main := my_main_ptr (cinfo^.main); + M := cinfo^.min_DCT_scaled_size; + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; { height of a row group of component } + xbuf0 := main^.xbuffer[0]^[ci]; + xbuf1 := main^.xbuffer[1]^[ci]; + + help_xbuf0 := xbuf0; + Dec(JSAMPROW_PTR(help_xbuf0), rgroup); + help_xbuf1 := xbuf1; + Dec(JSAMPROW_PTR(help_xbuf1), rgroup); + + for i := 0 to pred(rgroup) do + begin + {xbuf0^[i - rgroup] := xbuf0^[rgroup*(M+1) + i]; + xbuf1^[i - rgroup] := xbuf1^[rgroup*(M+1) + i];} + + help_xbuf0^[i] := xbuf0^[rgroup*(M+1) + i]; + help_xbuf1^[i] := xbuf1^[rgroup*(M+1) + i]; + + xbuf0^[rgroup*(M+2) + i] := xbuf0^[i]; + xbuf1^[rgroup*(M+2) + i] := xbuf1^[i]; + end; + Inc(compptr); + end; +end; + + +{LOCAL} +procedure set_bottom_pointers (cinfo : j_decompress_ptr); +{ Change the pointer lists to duplicate the last sample row at the bottom + of the image. whichptr indicates which xbuffer holds the final iMCU row. + Also sets rowgroups_avail to indicate number of nondummy row groups in row. } +var + main : my_main_ptr; + ci, i, rgroup, iMCUheight, rows_left : int; + compptr : jpeg_component_info_ptr; + xbuf : JSAMPARRAY; +begin + main := my_main_ptr (cinfo^.main); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Count sample rows in one iMCU row and in one row group } + iMCUheight := compptr^.v_samp_factor * compptr^.DCT_scaled_size; + rgroup := iMCUheight div cinfo^.min_DCT_scaled_size; + { Count nondummy sample rows remaining for this component } + rows_left := int (compptr^.downsampled_height mod JDIMENSION (iMCUheight)); + if (rows_left = 0) then + rows_left := iMCUheight; + { Count nondummy row groups. Should get same answer for each component, + so we need only do it once. } + if (ci = 0) then + begin + main^.rowgroups_avail := JDIMENSION ((rows_left-1) div rgroup + 1); + end; + { Duplicate the last real sample row rgroup*2 times; this pads out the + last partial rowgroup and ensures at least one full rowgroup of context. } + + xbuf := main^.xbuffer[main^.whichptr]^[ci]; + for i := 0 to pred(rgroup * 2) do + begin + xbuf^[rows_left + i] := xbuf^[rows_left-1]; + end; + Inc(compptr); + end; +end; + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_main (cinfo : j_decompress_ptr; + pass_mode : J_BUF_MODE); +var + main : my_main_ptr; +begin + main := my_main_ptr (cinfo^.main); + + case (pass_mode) of + JBUF_PASS_THRU: + begin + if (cinfo^.upsample^.need_context_rows) then + begin + main^.pub.process_data := process_data_context_main; + make_funny_pointers(cinfo); { Create the xbuffer[] lists } + main^.whichptr := 0; { Read first iMCU row into xbuffer[0] } + main^.context_state := CTX_PREPARE_FOR_IMCU; + main^.iMCU_row_ctr := 0; + end + else + begin + { Simple case with no context needed } + main^.pub.process_data := process_data_simple_main; + end; + main^.buffer_full := FALSE; { Mark buffer empty } + main^.rowgroup_ctr := 0; + end; +{$ifdef QUANT_2PASS_SUPPORTED} + JBUF_CRANK_DEST: + { For last pass of 2-pass quantization, just crank the postprocessor } + main^.pub.process_data := process_data_crank_post; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + end; +end; + + +{ Process some data. + This handles the simple case where no context is required. } + +{METHODDEF} +procedure process_data_simple_main (cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + main : my_main_ptr; + rowgroups_avail : JDIMENSION; +var + main_buffer_ptr : JSAMPIMAGE; +begin + main := my_main_ptr (cinfo^.main); + main_buffer_ptr := JSAMPIMAGE(@(main^.buffer)); + + { Read input data if we haven't filled the main buffer yet } + if (not main^.buffer_full) then + begin + if (cinfo^.coef^.decompress_data (cinfo, main_buffer_ptr)=0) then + exit; { suspension forced, can do nothing more } + main^.buffer_full := TRUE; { OK, we have an iMCU row to work with } + end; + + { There are always min_DCT_scaled_size row groups in an iMCU row. } + rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size); + { Note: at the bottom of the image, we may pass extra garbage row groups + to the postprocessor. The postprocessor has to check for bottom + of image anyway (at row resolution), so no point in us doing it too. } + + { Feed the postprocessor } + cinfo^.post^.post_process_data (cinfo, main_buffer_ptr, + main^.rowgroup_ctr, rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + + { Has postprocessor consumed all the data yet? If so, mark buffer empty } + if (main^.rowgroup_ctr >= rowgroups_avail) then + begin + main^.buffer_full := FALSE; + main^.rowgroup_ctr := 0; + end; +end; + + +{ Process some data. + This handles the case where context rows must be provided. } + +{METHODDEF} +procedure process_data_context_main (cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + main : my_main_ptr; +begin + main := my_main_ptr (cinfo^.main); + + { Read input data if we haven't filled the main buffer yet } + if (not main^.buffer_full) then + begin + if (cinfo^.coef^.decompress_data (cinfo, + main^.xbuffer[main^.whichptr])=0) then + exit; { suspension forced, can do nothing more } + main^.buffer_full := TRUE; { OK, we have an iMCU row to work with } + Inc(main^.iMCU_row_ctr); { count rows received } + end; + + { Postprocessor typically will not swallow all the input data it is handed + in one call (due to filling the output buffer first). Must be prepared + to exit and restart. This switch lets us keep track of how far we got. + Note that each case falls through to the next on successful completion. } + + case (main^.context_state) of + CTX_POSTPONED_ROW: + begin + { Call postprocessor using previously set pointers for postponed row } + cinfo^.post^.post_process_data (cinfo, main^.xbuffer[main^.whichptr], + main^.rowgroup_ctr, main^.rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main^.rowgroup_ctr < main^.rowgroups_avail) then + exit; { Need to suspend } + main^.context_state := CTX_PREPARE_FOR_IMCU; + if (out_row_ctr >= out_rows_avail) then + exit; { Postprocessor exactly filled output buf } + end; + end; + case (main^.context_state) of + CTX_POSTPONED_ROW, + CTX_PREPARE_FOR_IMCU: {FALLTHROUGH} + begin + { Prepare to process first M-1 row groups of this iMCU row } + main^.rowgroup_ctr := 0; + main^.rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size - 1); + { Check for bottom of image: if so, tweak pointers to "duplicate" + the last sample row, and adjust rowgroups_avail to ignore padding rows. } + + if (main^.iMCU_row_ctr = cinfo^.total_iMCU_rows) then + set_bottom_pointers(cinfo); + main^.context_state := CTX_PROCESS_IMCU; + + end; + end; + case (main^.context_state) of + CTX_POSTPONED_ROW, + CTX_PREPARE_FOR_IMCU, {FALLTHROUGH} + CTX_PROCESS_IMCU: + begin + { Call postprocessor using previously set pointers } + cinfo^.post^.post_process_data (cinfo, main^.xbuffer[main^.whichptr], + main^.rowgroup_ctr, main^.rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main^.rowgroup_ctr < main^.rowgroups_avail) then + exit; { Need to suspend } + { After the first iMCU, change wraparound pointers to normal state } + if (main^.iMCU_row_ctr = 1) then + set_wraparound_pointers(cinfo); + { Prepare to load new iMCU row using other xbuffer list } + main^.whichptr := main^.whichptr xor 1; { 0=>1 or 1=>0 } + main^.buffer_full := FALSE; + { Still need to process last row group of this iMCU row, } + { which is saved at index M+1 of the other xbuffer } + main^.rowgroup_ctr := JDIMENSION (cinfo^.min_DCT_scaled_size + 1); + main^.rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size + 2); + main^.context_state := CTX_POSTPONED_ROW; + end; + end; +end; + + +{ Process some data. + Final pass of two-pass quantization: just call the postprocessor. + Source data will be the postprocessor controller's internal buffer. } + +{$ifdef QUANT_2PASS_SUPPORTED} + +{METHODDEF} +procedure process_data_crank_post (cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + in_row_group_ctr : JDIMENSION; +begin + in_row_group_ctr := 0; + cinfo^.post^.post_process_data (cinfo, JSAMPIMAGE (NIL), + in_row_group_ctr, + JDIMENSION(0), + output_buf, + out_row_ctr, + out_rows_avail); +end; + +{$endif} { QUANT_2PASS_SUPPORTED } + + +{ Initialize main buffer controller. } + +{GLOBAL} +procedure jinit_d_main_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); +var + main : my_main_ptr; + ci, rgroup, ngroups : int; + compptr : jpeg_component_info_ptr; +begin + main := my_main_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_main_controller)) ); + cinfo^.main := jpeg_d_main_controller_ptr(main); + main^.pub.start_pass := start_pass_main; + + if (need_full_buffer) then { shouldn't happen } + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + + { Allocate the workspace. + ngroups is the number of row groups we need.} + + if (cinfo^.upsample^.need_context_rows) then + begin + if (cinfo^.min_DCT_scaled_size < 2) then { unsupported, see comments above } + ERREXIT(j_common_ptr(cinfo), JERR_NOTIMPL); + alloc_funny_pointers(cinfo); { Alloc space for xbuffer[] lists } + ngroups := cinfo^.min_DCT_scaled_size + 2; + end + else + begin + ngroups := cinfo^.min_DCT_scaled_size; + end; + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; { height of a row group of component } + main^.buffer[ci] := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + compptr^.width_in_blocks * compptr^.DCT_scaled_size, + JDIMENSION (rgroup * ngroups)); + Inc(compptr); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdmarker_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdmarker_del.pas new file mode 100644 index 0000000..f8930db --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdmarker_del.pas @@ -0,0 +1,2658 @@ +unit jdmarker_del; + +{ This file contains routines to decode JPEG datastream markers. + Most of the complexity arises from our desire to support input + suspension: if not all of the data for a marker is available; + we must exit back to the application. On resumption; we reprocess + the marker. } + +{ Original: jdmarker.c; Copyright (C) 1991-1998; Thomas G. Lane. } +{ History + 9.7.96 Conversion to pascal started jnn + 22.3.98 updated to 6b jnn } +//modified 2013 by Martin Schreiber + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jcomapi_del, + jpeglib_del; + +const { JPEG marker codes } + M_SOF0 = $c0; + M_SOF1 = $c1; + M_SOF2 = $c2; + M_SOF3 = $c3; + + M_SOF5 = $c5; + M_SOF6 = $c6; + M_SOF7 = $c7; + + M_JPG = $c8; + M_SOF9 = $c9; + M_SOF10 = $ca; + M_SOF11 = $cb; + + M_SOF13 = $cd; + M_SOF14 = $ce; + M_SOF15 = $cf; + + M_DHT = $c4; + + M_DAC = $cc; + + M_RST0 = $d0; + M_RST1 = $d1; + M_RST2 = $d2; + M_RST3 = $d3; + M_RST4 = $d4; + M_RST5 = $d5; + M_RST6 = $d6; + M_RST7 = $d7; + + M_SOI = $d8; + M_EOI = $d9; + M_SOS = $da; + M_DQT = $db; + M_DNL = $dc; + M_DRI = $dd; + M_DHP = $de; + M_EXP = $df; + + M_APP0 = $e0; + M_APP1 = $e1; + M_APP2 = $e2; + M_APP3 = $e3; + M_APP4 = $e4; + M_APP5 = $e5; + M_APP6 = $e6; + M_APP7 = $e7; + M_APP8 = $e8; + M_APP9 = $e9; + M_APP10 = $ea; + M_APP11 = $eb; + M_APP12 = $ec; + M_APP13 = $ed; + M_APP14 = $ee; + M_APP15 = $ef; + + M_JPG0 = $f0; + M_JPG13 = $fd; + M_COM = $fe; + + M_TEM = $01; + + M_ERROR = $100; + +type + JPEG_MARKER = uint; { JPEG marker codes } + +{ Private state } + +type + my_marker_ptr = ^my_marker_reader; + my_marker_reader = record + pub : jpeg_marker_reader; { public fields } + + { Application-overridable marker processing methods } + process_COM : jpeg_marker_parser_method; + process_APPn : array[0..16-1] of jpeg_marker_parser_method; + + { Limit on marker data length to save for each marker type } + length_limit_COM : uint; + length_limit_APPn : array[0..16-1] of uint; + + { Status of COM/APPn marker saving } + cur_marker : jpeg_saved_marker_ptr; { NIL if not processing a marker } + bytes_read : uint; { data bytes read so far in marker } + { Note: cur_marker is not linked into marker_list until it's all read. } + end; + +{GLOBAL} +function jpeg_resync_to_restart(cinfo : j_decompress_ptr; + desired : int) : boolean; +{GLOBAL} +procedure jinit_marker_reader (cinfo : j_decompress_ptr); + +{$ifdef SAVE_MARKERS_SUPPORTED} + +{GLOBAL} +procedure jpeg_save_markers (cinfo : j_decompress_ptr; + marker_code : int; + length_limit : uint); +{$ENDIF} + +{GLOBAL} +procedure jpeg_set_marker_processor (cinfo : j_decompress_ptr; + marker_code : int; + routine : jpeg_marker_parser_method); +Var + on_unknown_marker : function (cinfo : j_decompress_ptr) : int; + +implementation + +uses + jutils_del; + +{ At all times, cinfo1.src.next_input_byte and .bytes_in_buffer reflect + the current restart point; we update them only when we have reached a + suitable place to restart if a suspension occurs. } + + +{ Routines to process JPEG markers. + + Entry condition: JPEG marker itself has been read and its code saved + in cinfo^.unread_marker; input restart point is just after the marker. + + Exit: if return TRUE, have read and processed any parameters, and have + updated the restart point to point after the parameters. + If return FALSE, was forced to suspend before reaching end of + marker parameters; restart point has not been moved. Same routine + will be called again after application supplies more input data. + + This approach to suspension assumes that all of a marker's parameters + can fit into a single input bufferload. This should hold for "normal" + markers. Some COM/APPn markers might have large parameter segments + that might not fit. If we are simply dropping such a marker, we use + skip_input_data to get past it, and thereby put the problem on the + source manager's shoulders. If we are saving the marker's contents + into memory, we use a slightly different convention: when forced to + suspend, the marker processor updates the restart point to the end of + what it's consumed (ie, the end of the buffer) before returning FALSE. + On resumption, cinfo->unread_marker still contains the marker code, + but the data source will point to the next chunk of marker data. + The marker processor must retain internal state to deal with this. + + Note that we don't bother to avoid duplicate trace messages if a + suspension occurs within marker parameters. Other side effects + require more care. } + +{LOCAL} +function get_soi (cinfo : j_decompress_ptr) : boolean; +{ Process an SOI marker } +var + i : int; +begin + {$IFDEF DEBUG} + TRACEMS(j_common_ptr(cinfo), 1, JTRC_SOI); + {$ENDIF} + + if (cinfo^.marker^.saw_SOI) then + ERREXIT(j_common_ptr(cinfo), JERR_SOI_DUPLICATE); + + { Reset all parameters that are defined to be reset by SOI } + + for i := 0 to Pred(NUM_ARITH_TBLS) do + with cinfo^ do + begin + arith_dc_L[i] := 0; + arith_dc_U[i] := 1; + arith_ac_K[i] := 5; + end; + cinfo^.restart_interval := 0; + + { Set initial assumptions for colorspace etc } + + with cinfo^ do + begin + jpeg_color_space := JCS_UNKNOWN; + CCIR601_sampling := FALSE; { Assume non-CCIR sampling??? } + + saw_JFIF_marker := FALSE; + JFIF_major_version := 1; { set default JFIF APP0 values } + JFIF_minor_version := 1; + density_unit := 0; + X_density := 1; + Y_density := 1; + saw_Adobe_marker := FALSE; + Adobe_transform := 0; + + marker^.saw_SOI := TRUE; + end; + get_soi := TRUE; +end; { get_soi } + + +{LOCAL} +function get_sof(cinfo : j_decompress_ptr; + is_prog : boolean; + is_arith : boolean) : boolean; +{ Process a SOFn marker } +var + length : INT32; + c, ci : int; + compptr : jpeg_component_info_ptr; +{ Declare and initialize local copies of input pointer/count } +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; +{} + cinfo^.progressive_mode := is_prog; + cinfo^.arith_code := is_arith; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + + { Read a byte into variable cinfo^.data_precision. + If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + cinfo^.data_precision := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + +{ Read two bytes interpreted as an unsigned 16-bit integer. + cinfo^.image_height should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + cinfo^.image_height := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( cinfo^.image_height, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + +{ Read two bytes interpreted as an unsigned 16-bit integer. + cinfo^.image_width should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + cinfo^.image_width := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( cinfo^.image_width, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + { Read a byte into variable cinfo^.num_components. + If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + cinfo^.num_components := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + Dec(length, 8); + + {$IFDEF DEBUG} + TRACEMS4(j_common_ptr(cinfo), 1, JTRC_SOF, cinfo^.unread_marker, + int(cinfo^.image_width), int(cinfo^.image_height), + cinfo^.num_components); + {$ENDIF} + + if (cinfo^.marker^.saw_SOF) then + ERREXIT(j_common_ptr(cinfo), JERR_SOF_DUPLICATE); + + { We don't support files in which the image height is initially specified } + { as 0 and is later redefined by DNL. As long as we have to check that, } + { might as well have a general sanity check. } + if (cinfo^.image_height <= 0) or (cinfo^.image_width <= 0) + or (cinfo^.num_components <= 0) then + ERREXIT(j_common_ptr(cinfo), JERR_EMPTY_IMAGE); + + if (length <> (cinfo^.num_components * 3)) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + if (cinfo^.comp_info = NIL) then { do only once, even if suspend } + cinfo^.comp_info := jpeg_component_info_list_ptr( + cinfo^.mem^.alloc_small(j_common_ptr(cinfo), JPOOL_IMAGE, + cinfo^.num_components * SIZEOF(jpeg_component_info))); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + compptr^.component_index := ci; + + { Read a byte into variable compptr^.component_id. + If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + compptr^.component_id := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + compptr^.h_samp_factor := (c shr 4) and 15; + compptr^.v_samp_factor := (c ) and 15; + + { Read a byte into variable compptr^.quant_tbl_no. + If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + compptr^.quant_tbl_no := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + {$IFDEF DEBUG} + TRACEMS4(j_common_ptr(cinfo), 1, JTRC_SOF_COMPONENT, + compptr^.component_id, compptr^.h_samp_factor, + compptr^.v_samp_factor, compptr^.quant_tbl_no); + {$ENDIF} + + Inc(compptr); + end; + + cinfo^.marker^.saw_SOF := TRUE; + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_sof := TRUE; +end; { get_sof } + + +{LOCAL} +function get_sos (cinfo : j_decompress_ptr) : boolean; +{ Process a SOS marker } +label + id_found; +var + length : INT32; + i, ci, n, c, cc : int; + compptr : jpeg_component_info_ptr; +{ Declare and initialize local copies of input pointer/count } +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; { Array[] of JOCTET; } + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{} + + if not cinfo^.marker^.saw_SOF then + ERREXIT(j_common_ptr(cinfo), JERR_SOS_NO_SOF); + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + + { Read a byte into variable n (Number of components). + If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + n := GETJOCTET(next_input_byte^); { Number of components } + Inc(next_input_byte); + + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_SOS, n); + {$ENDIF} + + if ((length <> (n * 2 + 6)) or (n < 1) or (n > MAX_COMPS_IN_SCAN)) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + cinfo^.comps_in_scan := n; + + { Collect the component-spec parameters } + + for i := 0 to Pred(n) do + begin + { Read a byte into variable cc. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + cc := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to Pred(cinfo^.num_components) do + begin + if (cc = compptr^.component_id) then + goto id_found; + Inc(compptr); + end; + + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_COMPONENT_ID, cc); + + id_found: + + cinfo^.cur_comp_info[i] := compptr; + compptr^.dc_tbl_no := (c shr 4) and 15; + compptr^.ac_tbl_no := (c ) and 15; + + {$IFDEF DEBUG} + TRACEMS3(j_common_ptr(cinfo), 1, JTRC_SOS_COMPONENT, cc, + compptr^.dc_tbl_no, compptr^.ac_tbl_no); + {$ENDIF} + end; + + { Collect the additional scan parameters Ss, Se, Ah/Al. } + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + cinfo^.Ss := c; + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + cinfo^.Se := c; + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + cinfo^.Ah := (c shr 4) and 15; + cinfo^.Al := (c ) and 15; + + {$IFDEF DEBUG} + TRACEMS4(j_common_ptr(cinfo), 1, JTRC_SOS_PARAMS, cinfo^.Ss, cinfo^.Se, + cinfo^.Ah, cinfo^.Al); + {$ENDIF} + + { Prepare to scan data & restart markers } + cinfo^.marker^.next_restart_num := 0; + + { Count another SOS marker } + Inc( cinfo^.input_scan_number ); + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_sos := TRUE; +end; { get_sos } + + +{METHODDEF} +function skip_variable (cinfo : j_decompress_ptr) : boolean; +{ Skip over an unknown or uninteresting variable-length marker } +var + length : INT32; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; { Array[] of JOCTET; } + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + skip_variable := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := uint(GETJOCTET(next_input_byte^)) shl 8; + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + skip_variable := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET(next_input_byte^)); + Inc( next_input_byte ); + + Dec(length, 2); + + {$IFDEF DEBUG} + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_MISC_MARKER, + cinfo^.unread_marker, int(length)); + {$ENDIF} + + { Unload the local copies --- do this only at a restart boundary } + { do before skip_input_data } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + if (length > 0) then + cinfo^.src^.skip_input_data(cinfo, long(length)); + + skip_variable := TRUE; +end; { skip_variable } + + +{$IFDEF D_ARITH_CODING_SUPPORTED} + +{LOCAL} +function get_dac (cinfo : j_decompress_ptr) : boolean; +{ Process a DAC marker } +var + length : INT32; + index, val : int; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dac := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dac := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + Dec(length, 2); + + while (length > 0) do + begin + { Read a byte into variable index. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dac := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + index := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + { Read a byte into variable val. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dac := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + val := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + Dec( length, 2); + + {$IFDEF DEBUG} + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_DAC, index, val); + {$ENDIF} + + if (index < 0) or (index >= (2*NUM_ARITH_TBLS)) then + ERREXIT1(j_common_ptr(cinfo) , JERR_DAC_INDEX, index); + + if (index >= NUM_ARITH_TBLS) then + begin { define AC table } + cinfo^.arith_ac_K[index-NUM_ARITH_TBLS] := UINT8(val); + end + else + begin { define DC table } + cinfo^.arith_dc_L[index] := UINT8(val and $0F); + cinfo^.arith_dc_U[index] := UINT8(val shr 4); + if (cinfo^.arith_dc_L[index] > cinfo^.arith_dc_U[index]) then + ERREXIT1(j_common_ptr(cinfo) , JERR_DAC_VALUE, val); + end; + end; + + if (length <> 0) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_dac := TRUE; +end; { get_dac } + +{$ELSE} + +{LOCAL} +function get_dac (cinfo : j_decompress_ptr) : boolean; +begin + get_dac := skip_variable(cinfo); +end; + +{$ENDIF} + +{LOCAL} +function get_dht (cinfo : j_decompress_ptr) : boolean; +{ Process a DHT marker } +var + length : INT32; + bits : Array[0..17-1] of UINT8; + huffval : Array[0..256-1] of UINT8; + i, index, count : int; + htblptr : ^JHUFF_TBL_PTR; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dht := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dht := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + Dec(length, 2); + + while (length > 16) do + begin + { Read a byte into variable index. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dht := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + index := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_DHT, index); + {$ENDIF} + + bits[0] := 0; + count := 0; + for i := 1 to 16 do + begin + { Read a byte into variable bits[i]. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dht := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + bits[i] := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + Inc( count, bits[i] ); + end; + + Dec( length, (1 + 16) ); + + {$IFDEF DEBUG} + TRACEMS8(j_common_ptr(cinfo), 2, JTRC_HUFFBITS, + bits[1], bits[2], bits[3], bits[4], + bits[5], bits[6], bits[7], bits[8]); + TRACEMS8(j_common_ptr(cinfo), 2, JTRC_HUFFBITS, + bits[9], bits[10], bits[11], bits[12], + bits[13], bits[14], bits[15], bits[16]); + {$ENDIF} + + { Here we just do minimal validation of the counts to avoid walking + off the end of our table space. jdhuff.c will check more carefully. } + + if (count > 256) or (INT32(count) > length) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + + for i := 0 to Pred(count) do + begin + { Read a byte into variable huffval[i]. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dht := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + huffval[i] := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + end; + + Dec( length, count ); + + if (index and $10)<>0 then + begin { AC table definition } + Dec( index, $10 ); + htblptr := @cinfo^.ac_huff_tbl_ptrs[index]; + end + else + begin { DC table definition } + htblptr := @cinfo^.dc_huff_tbl_ptrs[index]; + end; + + if (index < 0) or (index >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_DHT_INDEX, index); + + if (htblptr^ = NIL) then + htblptr^ := jpeg_alloc_huff_table(j_common_ptr(cinfo)); + + MEMCOPY(@(htblptr^)^.bits, @bits, SIZEOF((htblptr^)^.bits)); + MEMCOPY(@(htblptr^)^.huffval, @huffval, SIZEOF((htblptr^)^.huffval)); + end; + + if (length <> 0) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_dht := TRUE; +end; { get_dht } + + +{LOCAL} +function get_dqt (cinfo : j_decompress_ptr) : boolean; +{ Process a DQT marker } +var + length : INT32; + n, i, prec : int; + tmp : uint; + quant_ptr : JQUANT_TBL_PTR; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + Dec( length, 2 ); + + while (length > 0) do + begin + { Read a byte into variable n. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + n := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + prec := n shr 4; + n := n and $0F; + + {$IFDEF DEBUG} + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_DQT, n, prec); + {$ENDIF} + + if (n >= NUM_QUANT_TBLS) then + ERREXIT1(j_common_ptr(cinfo) , JERR_DQT_INDEX, n); + + if (cinfo^.quant_tbl_ptrs[n] = NIL) then + cinfo^.quant_tbl_ptrs[n] := jpeg_alloc_quant_table(j_common_ptr(cinfo)); + quant_ptr := cinfo^.quant_tbl_ptrs[n]; + + for i := 0 to Pred(DCTSIZE2) do + begin + if (prec <> 0) then + begin + { Read two bytes interpreted as an unsigned 16-bit integer. + tmp should be declared unsigned int or perhaps INT32. } + + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + tmp := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( tmp, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + end + else + begin + { Read a byte into variable tmp. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + tmp := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + end; + + { We convert the zigzag-order table to natural array order. } + quant_ptr^.quantval[jpeg_natural_order[i]] := UINT16(tmp); + end; + + if (cinfo^.err^.trace_level >= 2) then + begin + i := 0; + while i < Pred(DCTSIZE2) do + begin + {$IFDEF DEBUG} + TRACEMS8(j_common_ptr(cinfo), 2, JTRC_QUANTVALS, + quant_ptr^.quantval[i], quant_ptr^.quantval[i+1], + quant_ptr^.quantval[i+2], quant_ptr^.quantval[i+3], + quant_ptr^.quantval[i+4], quant_ptr^.quantval[i+5], + quant_ptr^.quantval[i+6], quant_ptr^.quantval[i+7]); + {$ENDIF} + Inc(i, 8); + end; + end; + + Dec( length, DCTSIZE2+1 ); + if (prec <> 0) then + Dec( length, DCTSIZE2 ); + end; + + if (length <> 0) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_dqt := TRUE; +end; { get_dqt } + + +{LOCAL} +function get_dri (cinfo : j_decompress_ptr) : boolean; +{ Process a DRI marker } +var + length : INT32; + tmp : uint; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dri := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dri := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + if (length <> 4) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + +{ Read two bytes interpreted as an unsigned 16-bit integer. + tmp should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dri := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + tmp := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dri := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( tmp, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_DRI, tmp); + {$ENDIF} + + cinfo^.restart_interval := tmp; + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_dri := TRUE; +end; { get_dri } + + +{ Routines for processing APPn and COM markers. + These are either saved in memory or discarded, per application request. + APP0 and APP14 are specially checked to see if they are + JFIF and Adobe markers, respectively. } + +const + APP0_DATA_LEN = 14; { Length of interesting data in APP0 } + APP14_DATA_LEN = 12; { Length of interesting data in APP14 } + APPN_DATA_LEN = 14; { Must be the largest of the above!! } + + +{LOCAL} +procedure examine_app0 (cinfo : j_decompress_ptr; + var data : array of JOCTET; + datalen : uint; + remaining : INT32); + +{ Examine first few bytes from an APP0. + Take appropriate action if it is a JFIF marker. + datalen is # of bytes at data[], remaining is length of rest of marker data. +} +{$IFDEF DEBUG} +var + totallen : INT32; +{$ENDIF} +begin + {$IFDEF DEBUG} + totallen := INT32(datalen) + remaining; + {$ENDIF} + if (datalen >= APP0_DATA_LEN) and + (GETJOCTET(data[0]) = $4A) and + (GETJOCTET(data[1]) = $46) and + (GETJOCTET(data[2]) = $49) and + (GETJOCTET(data[3]) = $46) and + (GETJOCTET(data[4]) = 0) then + begin + { Found JFIF APP0 marker: save info } + cinfo^.saw_JFIF_marker := TRUE; + cinfo^.JFIF_major_version := GETJOCTET(data[5]); + cinfo^.JFIF_minor_version := GETJOCTET(data[6]); + cinfo^.density_unit := GETJOCTET(data[7]); + cinfo^.X_density := (GETJOCTET(data[8]) shl 8) + GETJOCTET(data[9]); + cinfo^.Y_density := (GETJOCTET(data[10]) shl 8) + GETJOCTET(data[11]); + { Check version. + Major version must be 1, anything else signals an incompatible change. + (We used to treat this as an error, but now it's a nonfatal warning, + because some bozo at Hijaak couldn't read the spec.) + Minor version should be 0..2, but process anyway if newer. } + + if (cinfo^.JFIF_major_version <> 1) then + WARNMS2(j_common_ptr(cinfo), JWRN_JFIF_MAJOR, + cinfo^.JFIF_major_version, cinfo^.JFIF_minor_version); + { Generate trace messages } + {$IFDEF DEBUG} + TRACEMS5(j_common_ptr(cinfo), 1, JTRC_JFIF, + cinfo^.JFIF_major_version, cinfo^.JFIF_minor_version, + cinfo^.X_density, cinfo^.Y_density, cinfo^.density_unit); + { Validate thumbnail dimensions and issue appropriate messages } + if (GETJOCTET(data[12]) or GETJOCTET(data[13])) <> 0 then + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_JFIF_THUMBNAIL, + GETJOCTET(data[12]), GETJOCTET(data[13])); + Dec(totallen, APP0_DATA_LEN); + if (totallen <> + ( INT32(GETJOCTET(data[12])) * INT32(GETJOCTET(data[13])) * INT32(3) )) then + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_JFIF_BADTHUMBNAILSIZE, int(totallen)); + {$ENDIF} + end + else + if (datalen >= 6) and + (GETJOCTET(data[0]) = $4A) and + (GETJOCTET(data[1]) = $46) and + (GETJOCTET(data[2]) = $58) and + (GETJOCTET(data[3]) = $58) and + (GETJOCTET(data[4]) = 0) then + begin + { Found JFIF "JFXX" extension APP0 marker } + { The library doesn't actually do anything with these, + but we try to produce a helpful trace message. } + {$IFDEF DEBUG} + case (GETJOCTET(data[5])) of + $10: + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_JPEG, int(totallen)); + $11: + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_PALETTE, int(totallen)); + $13: + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_RGB, int(totallen)); + else + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_JFIF_EXTENSION, + GETJOCTET(data[5]), int(totallen)); + end; + {$ENDIF} + end + else + begin + { Start of APP0 does not match "JFIF" or "JFXX", or too short } + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_APP0, int(totallen)); + {$ENDIF} + end; +end; + + +{LOCAL} +procedure examine_app14 (cinfo : j_decompress_ptr; + var data : array of JOCTET; + datalen : uint; + remaining : INT32); +{ Examine first few bytes from an APP14. + Take appropriate action if it is an Adobe marker. + datalen is # of bytes at data[], remaining is length of rest of marker data. + } +var + {$IFDEF DEBUG} + version, flags0, flags1, + {$ENDIF} + transform : uint; +begin + if (datalen >= APP14_DATA_LEN) and + (GETJOCTET(data[0]) = $41) and + (GETJOCTET(data[1]) = $64) and + (GETJOCTET(data[2]) = $6F) and + (GETJOCTET(data[3]) = $62) and + (GETJOCTET(data[4]) = $65) then + begin + { Found Adobe APP14 marker } + {$IFDEF DEBUG} + version := (GETJOCTET(data[5]) shl 8) + GETJOCTET(data[6]); + flags0 := (GETJOCTET(data[7]) shl 8) + GETJOCTET(data[8]); + flags1 := (GETJOCTET(data[9]) shl 8) + GETJOCTET(data[10]); + {$ENDIF} + transform := GETJOCTET(data[11]); + {$IFDEF DEBUG} + TRACEMS4(j_common_ptr(cinfo), 1, JTRC_ADOBE, version, flags0, flags1, transform); + {$ENDIF} + cinfo^.saw_Adobe_marker := TRUE; + cinfo^.Adobe_transform := UINT8 (transform); + end + else + begin + { Start of APP14 does not match "Adobe", or too short } + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_APP14, int (datalen + remaining)); + {$ENDIF} + end; +end; + + +{METHODDEF} +function get_interesting_appn (cinfo : j_decompress_ptr) : boolean; +{ Process an APP0 or APP14 marker without saving it } +var + length : INT32; + b : array[0..APPN_DATA_LEN-1] of JOCTET; + i, numtoread : uint; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_interesting_appn := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_interesting_appn := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET(next_input_byte^)); + Inc( next_input_byte ); + + Dec(length, 2); + + { get the interesting part of the marker data } + if (length >= APPN_DATA_LEN) then + numtoread := APPN_DATA_LEN + else + if (length > 0) then + numtoread := uint(length) + else + numtoread := 0; + + if numtoread > 0 then + begin + for i := 0 to numtoread-1 do + begin + { Read a byte into b[i]. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_interesting_appn := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + b[i] := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + end; + end; + + Dec(length, numtoread); + + { process it } + case (cinfo^.unread_marker) of + M_APP0: + examine_app0(cinfo, b, numtoread, length); + M_APP14: + examine_app14(cinfo, b, numtoread, length); + else + { can't get here unless jpeg_save_markers chooses wrong processor } + ERREXIT1(j_common_ptr(cinfo), JERR_UNKNOWN_MARKER, cinfo^.unread_marker); + end; + + { skip any remaining data -- could be lots } + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + if (length > 0) then + cinfo^.src^.skip_input_data(cinfo, long(length)); + + get_interesting_appn := TRUE; +end; + +{$ifdef SAVE_MARKERS_SUPPORTED} + +{METHODDEF} +function save_marker (cinfo : j_decompress_ptr) : boolean; +{ Save an APPn or COM marker into the marker list } +var + marker : my_marker_ptr; + cur_marker : jpeg_saved_marker_ptr; + bytes_read, data_length : uint; + data : JOCTET_FIELD_PTR; + length : INT32; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +var + limit : uint; +var + prev : jpeg_saved_marker_ptr; +begin + { local copies of input pointer/count } + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + + marker := my_marker_ptr(cinfo^.marker); + cur_marker := marker^.cur_marker; + length := 0; + + if (cur_marker = NIL) then + begin + { begin reading a marker } + { Read two bytes interpreted as an unsigned 16-bit integer. } + + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + save_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + save_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET(next_input_byte^)); + Inc( next_input_byte ); + + Dec(length, 2); + if (length >= 0) then + begin { watch out for bogus length word } + { figure out how much we want to save } + + if (cinfo^.unread_marker = int(M_COM)) then + limit := marker^.length_limit_COM + else + limit := marker^.length_limit_APPn[cinfo^.unread_marker - int(M_APP0)]; + if (uint(length) < limit) then + limit := uint(length); + { allocate and initialize the marker item } + cur_marker := jpeg_saved_marker_ptr( + cinfo^.mem^.alloc_large (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(jpeg_marker_struct) + limit) ); + cur_marker^.next := NIL; + cur_marker^.marker := UINT8 (cinfo^.unread_marker); + cur_marker^.original_length := uint(length); + cur_marker^.data_length := limit; + { data area is just beyond the jpeg_marker_struct } + cur_marker^.data := JOCTET_FIELD_PTR(cur_marker); + Inc(jpeg_saved_marker_ptr(cur_marker^.data)); + data := cur_marker^.data; + + marker^.cur_marker := cur_marker; + marker^.bytes_read := 0; + bytes_read := 0; + data_length := limit; + end + else + begin + { deal with bogus length word } + data_length := 0; + bytes_read := 0; + data := NIL; + end + end + else + begin + { resume reading a marker } + bytes_read := marker^.bytes_read; + data_length := cur_marker^.data_length; + data := cur_marker^.data; + Inc(data, bytes_read); + end; + + while (bytes_read < data_length) do + begin + { move the restart point to here } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + marker^.bytes_read := bytes_read; + { If there's not at least one byte in buffer, suspend } + if (bytes_in_buffer = 0) then + begin + if not datasrc^.fill_input_buffer (cinfo) then + begin + save_marker := FALSE; + exit; + end; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + + { Copy bytes with reasonable rapidity } + while (bytes_read < data_length) and (bytes_in_buffer > 0) do + begin + JOCTETPTR(data)^ := next_input_byte^; + Inc(JOCTETPTR(data)); + Inc(next_input_byte); + Dec(bytes_in_buffer); + Inc(bytes_read); + end; + end; + + { Done reading what we want to read } + if (cur_marker <> NIL) then + begin { will be NIL if bogus length word } + { Add new marker to end of list } + if (cinfo^.marker_list = NIL) then + begin + cinfo^.marker_list := cur_marker + end + else + begin + prev := cinfo^.marker_list; + while (prev^.next <> NIL) do + prev := prev^.next; + prev^.next := cur_marker; + end; + { Reset pointer & calc remaining data length } + data := cur_marker^.data; + length := cur_marker^.original_length - data_length; + end; + { Reset to initial state for next marker } + marker^.cur_marker := NIL; + + { Process the marker if interesting; else just make a generic trace msg } + case (cinfo^.unread_marker) of + M_APP0: + examine_app0(cinfo, data^, data_length, length); + M_APP14: + examine_app14(cinfo, data^, data_length, length); + else + {$IFDEF DEBUG} + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_MISC_MARKER, cinfo^.unread_marker, + int(data_length + length)); + {$ENDIF} + end; + + { skip any remaining data -- could be lots } + { do before skip_input_data } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + if (length > 0) then + cinfo^.src^.skip_input_data (cinfo, long(length) ); + + save_marker := TRUE; +end; + +{$endif} { SAVE_MARKERS_SUPPORTED } + + +{ Find the next JPEG marker, save it in cinfo^.unread_marker. + Returns FALSE if had to suspend before reaching a marker; + in that case cinfo^.unread_marker is unchanged. + + Note that the result might not be a valid marker code, + but it will never be 0 or FF. } + +{LOCAL} +function next_marker (cinfo : j_decompress_ptr) : boolean; +var + c : int; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + + {while TRUE do} + repeat + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + next_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + { Skip any non-FF bytes. + This may look a bit inefficient, but it will not occur in a valid file. + We sync after each discarded byte so that a suspending data source + can discard the byte from its buffer. } + + while (c <> $FF) do + begin + Inc(cinfo^.marker^.discarded_bytes); + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + next_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + end; + { This loop swallows any duplicate FF bytes. Extra FFs are legal as + pad bytes, so don't count them in discarded_bytes. We assume there + will not be so many consecutive FF bytes as to overflow a suspending + data source's input buffer. } + + repeat + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + next_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + Until (c <> $FF); + if (c <> 0) then + break; { found a valid marker, exit loop } + { Reach here if we found a stuffed-zero data sequence (FF/00). + Discard it and loop back to try again. } + + Inc(cinfo^.marker^.discarded_bytes, 2); + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + Until False; + + if (cinfo^.marker^.discarded_bytes <> 0) then + begin + WARNMS2(j_common_ptr(cinfo), JWRN_EXTRANEOUS_DATA, + cinfo^.marker^.discarded_bytes, c); + cinfo^.marker^.discarded_bytes := 0; + end; + + cinfo^.unread_marker := c; + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + next_marker := TRUE; +end; { next_marker } + + +{LOCAL} +function first_marker (cinfo : j_decompress_ptr) : boolean; +{ Like next_marker, but used to obtain the initial SOI marker. } +{ For this marker, we do not allow preceding garbage or fill; otherwise, + we might well scan an entire input file before realizing it ain't JPEG. + If an application wants to process non-JFIF files, it must seek to the + SOI before calling the JPEG library. } +var + c, c2 : int; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + first_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + { Read a byte into variable c2. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + first_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c2 := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + if (c <> $FF) or (c2 <> int(M_SOI)) then + ERREXIT2(j_common_ptr(cinfo), JERR_NO_SOI, c, c2); + + cinfo^.unread_marker := c2; + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + first_marker := TRUE; +end; { first_marker } + + +{ Read markers until SOS or EOI. + + Returns same codes as are defined for jpeg_consume_input: + JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. } + +{METHODDEF} +function read_markers (cinfo : j_decompress_ptr) : int; +begin + { Outer loop repeats once for each marker. } + repeat + { Collect the marker proper, unless we already did. } + { NB: first_marker() enforces the requirement that SOI appear first. } + if (cinfo^.unread_marker = 0) then + begin + if not cinfo^.marker^.saw_SOI then + begin + if not first_marker(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + end + else + begin + if not next_marker(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + end; + end; + { At this point cinfo^.unread_marker contains the marker code and the + input point is just past the marker proper, but before any parameters. + A suspension will cause us to return with this state still true. } + + case (cinfo^.unread_marker) of + M_SOI: + if not get_soi(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_SOF0, { Baseline } + M_SOF1: { Extended sequential, Huffman } + if not get_sof(cinfo, FALSE, FALSE) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + M_SOF2: { Progressive, Huffman } + if not get_sof(cinfo, TRUE, FALSE) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_SOF9: { Extended sequential, arithmetic } + if not get_sof(cinfo, FALSE, TRUE) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_SOF10: { Progressive, arithmetic } + if not get_sof(cinfo, TRUE, TRUE) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + { Currently unsupported SOFn types } + M_SOF3, { Lossless, Huffman } + M_SOF5, { Differential sequential, Huffman } + M_SOF6, { Differential progressive, Huffman } + M_SOF7, { Differential lossless, Huffman } + M_JPG, { Reserved for JPEG extensions } + M_SOF11, { Lossless, arithmetic } + M_SOF13, { Differential sequential, arithmetic } + M_SOF14, { Differential progressive, arithmetic } + M_SOF15: { Differential lossless, arithmetic } + ERREXIT1(j_common_ptr(cinfo), JERR_SOF_UNSUPPORTED, cinfo^.unread_marker); + + M_SOS: + begin + if not get_sos(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + cinfo^.unread_marker := 0; { processed the marker } + read_markers := JPEG_REACHED_SOS; + exit; + end; + + M_EOI: + begin + {$IFDEF DEBUG} + TRACEMS(j_common_ptr(cinfo), 1, JTRC_EOI); + {$ENDIF} + cinfo^.unread_marker := 0; { processed the marker } + read_markers := JPEG_REACHED_EOI; + exit; + end; + + M_DAC: + if not get_dac(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_DHT: + if not get_dht(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_DQT: + if not get_dqt(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_DRI: + if not get_dri(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_APP0, + M_APP1, + M_APP2, + M_APP3, + M_APP4, + M_APP5, + M_APP6, + M_APP7, + M_APP8, + M_APP9, + M_APP10, + M_APP11, + M_APP12, + M_APP13, + M_APP14, + M_APP15: + if not my_marker_ptr(cinfo^.marker)^. + process_APPn[cinfo^.unread_marker - int(M_APP0)](cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_COM: + if not my_marker_ptr(cinfo^.marker)^.process_COM (cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_RST0, { these are all parameterless } + M_RST1, + M_RST2, + M_RST3, + M_RST4, + M_RST5, + M_RST6, + M_RST7, + M_TEM: + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_PARMLESS_MARKER, + cinfo^.unread_marker) + {$ENDIF} + ; + + M_DNL: { Ignore DNL ... perhaps the wrong thing } + if not skip_variable(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + else { must be DHP, EXP, JPGn, or RESn } + if (@on_unknown_marker<>nil) then + begin + read_markers:=on_unknown_marker(cinfo); + exit; + end + else if not skip_variable(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + { // This is the previous code. + ERREXIT1(j_common_ptr(cinfo) , JERR_UNKNOWN_MARKER,cinfo^.unread_marker); + } + end; { end of case } + { Successfully processed marker, so reset state variable } + cinfo^.unread_marker := 0; + Until false; +end; { read_markers } + + +{ Read a restart marker, which is expected to appear next in the datastream; + if the marker is not there, take appropriate recovery action. + Returns FALSE if suspension is required. + + This is called by the entropy decoder after it has read an appropriate + number of MCUs. cinfo^.unread_marker may be nonzero if the entropy decoder + has already read a marker from the data source. Under normal conditions + cinfo^.unread_marker will be reset to 0 before returning; if not reset, + it holds a marker which the decoder will be unable to read past. } + +{METHODDEF} +function read_restart_marker (cinfo : j_decompress_ptr) :boolean; +begin + { Obtain a marker unless we already did. } + { Note that next_marker will complain if it skips any data. } + if (cinfo^.unread_marker = 0) then + begin + if not next_marker(cinfo) then + begin + read_restart_marker := FALSE; + exit; + end; + end; + + if (cinfo^.unread_marker = (int(M_RST0) + cinfo^.marker^.next_restart_num)) then + begin + { Normal case --- swallow the marker and let entropy decoder continue } + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 3, JTRC_RST, + cinfo^.marker^.next_restart_num); + {$ENDIF} + cinfo^.unread_marker := 0; + end + else + begin + { Uh-oh, the restart markers have been messed up. } + { Let the data source manager determine how to resync. } + if not cinfo^.src^.resync_to_restart(cinfo, + cinfo^.marker^.next_restart_num) then + begin + read_restart_marker := FALSE; + exit; + end; + end; + + { Update next-restart state } + with cinfo^.marker^ do + next_restart_num := (next_restart_num + 1) and 7; + + read_restart_marker := TRUE; +end; { read_restart_marker } + + +{ This is the default resync_to_restart method for data source managers + to use if they don't have any better approach. Some data source managers + may be able to back up, or may have additional knowledge about the data + which permits a more intelligent recovery strategy; such managers would + presumably supply their own resync method. + + read_restart_marker calls resync_to_restart if it finds a marker other than + the restart marker it was expecting. (This code is *not* used unless + a nonzero restart interval has been declared.) cinfo^.unread_marker is + the marker code actually found (might be anything, except 0 or FF). + The desired restart marker number (0..7) is passed as a parameter. + This routine is supposed to apply whatever error recovery strategy seems + appropriate in order to position the input stream to the next data segment. + Note that cinfo^.unread_marker is treated as a marker appearing before + the current data-source input point; usually it should be reset to zero + before returning. + Returns FALSE if suspension is required. + + This implementation is substantially constrained by wanting to treat the + input as a data stream; this means we can't back up. Therefore, we have + only the following actions to work with: + 1. Simply discard the marker and let the entropy decoder resume at next + byte of file. + 2. Read forward until we find another marker, discarding intervening + data. (In theory we could look ahead within the current bufferload, + without having to discard data if we don't find the desired marker. + This idea is not implemented here, in part because it makes behavior + dependent on buffer size and chance buffer-boundary positions.) + 3. Leave the marker unread (by failing to zero cinfo^.unread_marker). + This will cause the entropy decoder to process an empty data segment, + inserting dummy zeroes, and then we will reprocess the marker. + + #2 is appropriate if we think the desired marker lies ahead, while #3 is + appropriate if the found marker is a future restart marker (indicating + that we have missed the desired restart marker, probably because it got + corrupted). + We apply #2 or #3 if the found marker is a restart marker no more than + two counts behind or ahead of the expected one. We also apply #2 if the + found marker is not a legal JPEG marker code (it's certainly bogus data). + If the found marker is a restart marker more than 2 counts away, we do #1 + (too much risk that the marker is erroneous; with luck we will be able to + resync at some future point). + For any valid non-restart JPEG marker, we apply #3. This keeps us from + overrunning the end of a scan. An implementation limited to single-scan + files might find it better to apply #2 for markers other than EOI, since + any other marker would have to be bogus data in that case. } + + +{GLOBAL} +function jpeg_resync_to_restart(cinfo : j_decompress_ptr; + desired : int) : boolean; +var + marker : int; + action : int; +begin + marker := cinfo^.unread_marker; + action := 1; { never used } + { Always put up a warning. } + WARNMS2(j_common_ptr(cinfo), JWRN_MUST_RESYNC, marker, desired); + + { Outer loop handles repeated decision after scanning forward. } + repeat + if (marker < int(M_SOF0)) then + action := 2 { invalid marker } + else + if (marker < int(M_RST0)) or (marker > int(M_RST7)) then + action := 3 { valid non-restart marker } + else + begin + if (marker = (int(M_RST0) + ((desired+1) and 7))) or + (marker = (int(M_RST0) + ((desired+2) and 7))) then + action := 3 { one of the next two expected restarts } + else + if (marker = (int(M_RST0) + ((desired-1) and 7))) or + (marker = (int(M_RST0) + ((desired-2) and 7))) then + action := 2 { a prior restart, so advance } + else + action := 1; { desired restart or too far away } + end; + + {$IFDEF DEBUG} + TRACEMS2(j_common_ptr(cinfo), 4, JTRC_RECOVERY_ACTION, marker, action); + {$ENDIF} + case action of + 1: + { Discard marker and let entropy decoder resume processing. } + begin + cinfo^.unread_marker := 0; + jpeg_resync_to_restart := TRUE; + exit; + end; + 2: + { Scan to the next marker, and repeat the decision loop. } + begin + if not next_marker(cinfo) then + begin + jpeg_resync_to_restart := FALSE; + exit; + end; + marker := cinfo^.unread_marker; + end; + 3: + { Return without advancing past this marker. } + { Entropy decoder will be forced to process an empty segment. } + begin + jpeg_resync_to_restart := TRUE; + exit; + end; + end; { case } + Until false; { end loop } +end; { jpeg_resync_to_restart } + + +{ Reset marker processing state to begin a fresh datastream. } + +{METHODDEF} +procedure reset_marker_reader (cinfo : j_decompress_ptr); +var + marker : my_marker_ptr; +begin + marker := my_marker_ptr (cinfo^.marker); + with cinfo^ do + begin + comp_info := NIL; { until allocated by get_sof } + input_scan_number := 0; { no SOS seen yet } + unread_marker := 0; { no pending marker } + end; + marker^.pub.saw_SOI := FALSE; { set internal state too } + marker^.pub.saw_SOF := FALSE; + marker^.pub.discarded_bytes := 0; + marker^.cur_marker := NIL; +end; { reset_marker_reader } + + +{ Initialize the marker reader module. + This is called only once, when the decompression object is created. } + +{GLOBAL} +procedure jinit_marker_reader (cinfo : j_decompress_ptr); +var + marker : my_marker_ptr; + i : int; +begin + { Create subobject in permanent pool } + marker := my_marker_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + SIZEOF(my_marker_reader)) + ); + cinfo^.marker := jpeg_marker_reader_ptr(marker); + { Initialize method pointers } + marker^.pub.reset_marker_reader := reset_marker_reader; + marker^.pub.read_markers := read_markers; + marker^.pub.read_restart_marker := read_restart_marker; + { Initialize COM/APPn processing. + By default, we examine and then discard APP0 and APP14, + but simply discard COM and all other APPn. } + + marker^.process_COM := skip_variable; + marker^.length_limit_COM := 0; + for i := 0 to 16-1 do + begin + marker^.process_APPn[i] := skip_variable; + marker^.length_limit_APPn[i] := 0; + end; + marker^.process_APPn[0] := get_interesting_appn; + marker^.process_APPn[14] := get_interesting_appn; + { Reset marker processing state } + reset_marker_reader(cinfo); +end; { jinit_marker_reader } + + +{ Control saving of COM and APPn markers into marker_list. } + + +{$ifdef SAVE_MARKERS_SUPPORTED} + +{GLOBAL} +procedure jpeg_save_markers (cinfo : j_decompress_ptr; + marker_code : int; + length_limit : uint); +var + marker : my_marker_ptr; + maxlength : long; + processor : jpeg_marker_parser_method; +begin + marker := my_marker_ptr (cinfo^.marker); + + { Length limit mustn't be larger than what we can allocate + (should only be a concern in a 16-bit environment). } + + maxlength := cinfo^.mem^.max_alloc_chunk - SIZEOF(jpeg_marker_struct); + if (long(length_limit) > maxlength) then + length_limit := uint(maxlength); + + { Choose processor routine to use. + APP0/APP14 have special requirements. } + + if (length_limit <> 0) then + begin + processor := save_marker; + { If saving APP0/APP14, save at least enough for our internal use. } + if (marker_code = int(M_APP0)) and (length_limit < APP0_DATA_LEN) then + length_limit := APP0_DATA_LEN + else + if (marker_code = int(M_APP14)) and (length_limit < APP14_DATA_LEN) then + length_limit := APP14_DATA_LEN; + end + else + begin + processor := skip_variable; + { If discarding APP0/APP14, use our regular on-the-fly processor. } + if (marker_code = int(M_APP0)) or (marker_code = int(M_APP14)) then + processor := get_interesting_appn; + end; + + if (marker_code = int(M_COM)) then + begin + marker^.process_COM := processor; + marker^.length_limit_COM := length_limit; + end + else + if (marker_code >= int(M_APP0)) and (marker_code <= int(M_APP15)) then + begin + marker^.process_APPn[marker_code - int(M_APP0)] := processor; + marker^.length_limit_APPn[marker_code - int(M_APP0)] := length_limit; + end + else + ERREXIT1(j_common_ptr(cinfo), JERR_UNKNOWN_MARKER, marker_code); +end; + +{$endif} { SAVE_MARKERS_SUPPORTED } + +{ Install a special processing method for COM or APPn markers. } + +{GLOBAL} + +procedure jpeg_set_marker_processor (cinfo : j_decompress_ptr; + marker_code : int; + routine : jpeg_marker_parser_method); +var + marker : my_marker_ptr; +begin + marker := my_marker_ptr (cinfo^.marker); + if (marker_code = int(M_COM)) then + marker^.process_COM := routine + else + if (marker_code >= int(M_APP0)) and (marker_code <= int(M_APP15)) then + marker^.process_APPn[marker_code - int(M_APP0)] := routine + else + ERREXIT1(j_common_ptr(cinfo), JERR_UNKNOWN_MARKER, marker_code); +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdmaster_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdmaster_del.pas new file mode 100644 index 0000000..248a976 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdmaster_del.pas @@ -0,0 +1,680 @@ +unit jdmaster_del; + +{ This file contains master control logic for the JPEG decompressor. + These routines are concerned with selecting the modules to be executed + and with determining the number of passes and the work to be done in each + pass. } + +{ Original: jdmaster.c ; Copyright (C) 1991-1998, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jutils_del, + jerror_del, + jdeferr_del, + jdcolor_del, jdsample_del, jdpostct_del, jddctmgr_del, jdphuff_del, + jdhuff_del, jdcoefct_del, jdmainct_del, +{$ifdef QUANT_1PASS_SUPPORTED} + jquant1_del, +{$endif} +{$ifdef QUANT_2PASS_SUPPORTED} + jquant2_del, +{$endif} +{$ifdef UPSAMPLE_MERGING_SUPPORTED} + jdmerge_del, +{$endif} + jpeglib_del; + + +{ Compute output image dimensions and related values. + NOTE: this is exported for possible use by application. + Hence it mustn't do anything that can't be done twice. + Also note that it may be called before the master module is initialized! } + +{GLOBAL} +procedure jpeg_calc_output_dimensions (cinfo : j_decompress_ptr); +{ Do computations that are needed before master selection phase } + + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + +{GLOBAL} +procedure jpeg_new_colormap (cinfo : j_decompress_ptr); + +{$endif} + +{ Initialize master decompression control and select active modules. + This is performed at the start of jpeg_start_decompress. } + +{GLOBAL} +procedure jinit_master_decompress (cinfo : j_decompress_ptr); + +implementation + +{ Private state } + +type + my_master_ptr = ^my_decomp_master; + my_decomp_master = record + pub : jpeg_decomp_master; { public fields } + + pass_number : int; { # of passes completed } + + using_merged_upsample : boolean; { TRUE if using merged upsample/cconvert } + + { Saved references to initialized quantizer modules, + in case we need to switch modes. } + + quantizer_1pass : jpeg_color_quantizer_ptr; + quantizer_2pass : jpeg_color_quantizer_ptr; + end; + +{ Determine whether merged upsample/color conversion should be used. + CRUCIAL: this must match the actual capabilities of jdmerge.c! } + +{LOCAL} +function use_merged_upsample (cinfo : j_decompress_ptr) : boolean; +var + compptr : jpeg_component_info_list_ptr; +begin + compptr := cinfo^.comp_info; + +{$ifdef UPSAMPLE_MERGING_SUPPORTED} + { Merging is the equivalent of plain box-filter upsampling } + if (cinfo^.do_fancy_upsampling) or (cinfo^.CCIR601_sampling) then + begin + use_merged_upsample := FALSE; + exit; + end; + { jdmerge.c only supports YCC=>RGB color conversion } + if (cinfo^.jpeg_color_space <> JCS_YCbCr) or (cinfo^.num_components <> 3) + or (cinfo^.out_color_space <> JCS_RGB) + or (cinfo^.out_color_components <> RGB_PIXELSIZE) then + begin + use_merged_upsample := FALSE; + exit; + end; + + { and it only handles 2h1v or 2h2v sampling ratios } + if (compptr^[0].h_samp_factor <> 2) or + (compptr^[1].h_samp_factor <> 1) or + (compptr^[2].h_samp_factor <> 1) or + (compptr^[0].v_samp_factor > 2) or + (compptr^[1].v_samp_factor <> 1) or + (compptr^[2].v_samp_factor <> 1) then + begin + use_merged_upsample := FALSE; + exit; + end; + { furthermore, it doesn't work if we've scaled the IDCTs differently } + if (compptr^[0].DCT_scaled_size <> cinfo^.min_DCT_scaled_size) or + (compptr^[1].DCT_scaled_size <> cinfo^.min_DCT_scaled_size) or + (compptr^[2].DCT_scaled_size <> cinfo^.min_DCT_scaled_size) then + begin + use_merged_upsample := FALSE; + exit; + end; + { ??? also need to test for upsample-time rescaling, when & if supported } + use_merged_upsample := TRUE; { by golly, it'll work... } +{$else} + use_merged_upsample := FALSE; +{$endif} +end; + + +{ Compute output image dimensions and related values. + NOTE: this is exported for possible use by application. + Hence it mustn't do anything that can't be done twice. + Also note that it may be called before the master module is initialized! } + +{GLOBAL} +procedure jpeg_calc_output_dimensions (cinfo : j_decompress_ptr); +{ Do computations that are needed before master selection phase } +{$ifdef IDCT_SCALING_SUPPORTED} +var + ci : int; + compptr : jpeg_component_info_ptr; +{$endif} +var + ssize : int; +begin + { Prevent application from calling me at wrong times } + if (cinfo^.global_state <> DSTATE_READY) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + +{$ifdef IDCT_SCALING_SUPPORTED} + + { Compute actual output image dimensions and DCT scaling choices. } + if (cinfo^.scale_num * 8 <= cinfo^.scale_denom) then + begin + { Provide 1/8 scaling } + cinfo^.output_width := JDIMENSION ( + jdiv_round_up( long(cinfo^.image_width), long(8)) ); + cinfo^.output_height := JDIMENSION ( + jdiv_round_up( long(cinfo^.image_height), long(8)) ); + cinfo^.min_DCT_scaled_size := 1; + end + else + if (cinfo^.scale_num * 4 <= cinfo^.scale_denom) then + begin + { Provide 1/4 scaling } + cinfo^.output_width := JDIMENSION ( + jdiv_round_up( long (cinfo^.image_width), long(4)) ); + cinfo^.output_height := JDIMENSION ( + jdiv_round_up( long (cinfo^.image_height), long(4)) ); + cinfo^.min_DCT_scaled_size := 2; + end + else + if (cinfo^.scale_num * 2 <= cinfo^.scale_denom) then + begin + { Provide 1/2 scaling } + cinfo^.output_width := JDIMENSION ( + jdiv_round_up( long(cinfo^.image_width), long(2)) ); + cinfo^.output_height := JDIMENSION ( + jdiv_round_up( long(cinfo^.image_height), long(2)) ); + cinfo^.min_DCT_scaled_size := 4; + end + else + begin + { Provide 1/1 scaling } + cinfo^.output_width := cinfo^.image_width; + cinfo^.output_height := cinfo^.image_height; + cinfo^.min_DCT_scaled_size := DCTSIZE; + end; + { In selecting the actual DCT scaling for each component, we try to + scale up the chroma components via IDCT scaling rather than upsampling. + This saves time if the upsampler gets to use 1:1 scaling. + Note this code assumes that the supported DCT scalings are powers of 2. } + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + ssize := cinfo^.min_DCT_scaled_size; + while (ssize < DCTSIZE) and + ((compptr^.h_samp_factor * ssize * 2 <= + cinfo^.max_h_samp_factor * cinfo^.min_DCT_scaled_size) and + (compptr^.v_samp_factor * ssize * 2 <= + cinfo^.max_v_samp_factor * cinfo^.min_DCT_scaled_size)) do + begin + ssize := ssize * 2; + end; + compptr^.DCT_scaled_size := ssize; + Inc(compptr); + end; + + { Recompute downsampled dimensions of components; + application needs to know these if using raw downsampled data. } + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Size in samples, after IDCT scaling } + compptr^.downsampled_width := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_width) * + long (compptr^.h_samp_factor * compptr^.DCT_scaled_size), + long (cinfo^.max_h_samp_factor * DCTSIZE)) ); + compptr^.downsampled_height := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height) * + long (compptr^.v_samp_factor * compptr^.DCT_scaled_size), + long (cinfo^.max_v_samp_factor * DCTSIZE)) ); + Inc(compptr); + end; + +{$else} { !IDCT_SCALING_SUPPORTED } + + { Hardwire it to "no scaling" } + cinfo^.output_width := cinfo^.image_width; + cinfo^.output_height := cinfo^.image_height; + { jdinput.c has already initialized DCT_scaled_size to DCTSIZE, + and has computed unscaled downsampled_width and downsampled_height. } + +{$endif} { IDCT_SCALING_SUPPORTED } + + { Report number of components in selected colorspace. } + { Probably this should be in the color conversion module... } + case (cinfo^.out_color_space) of + JCS_GRAYSCALE: + cinfo^.out_color_components := 1; +{$ifndef RGB_PIXELSIZE_IS_3} + JCS_RGB: + cinfo^.out_color_components := RGB_PIXELSIZE; +{$else} + JCS_RGB, +{$endif} { else share code with YCbCr } + JCS_YCbCr: + cinfo^.out_color_components := 3; + JCS_CMYK, + JCS_YCCK: + cinfo^.out_color_components := 4; + else { else must be same colorspace as in file } + cinfo^.out_color_components := cinfo^.num_components; + end; + if (cinfo^.quantize_colors) then + cinfo^.output_components := 1 + else + cinfo^.output_components := cinfo^.out_color_components; + + { See if upsampler will want to emit more than one row at a time } + if (use_merged_upsample(cinfo)) then + cinfo^.rec_outbuf_height := cinfo^.max_v_samp_factor + else + cinfo^.rec_outbuf_height := 1; +end; + + +{ Several decompression processes need to range-limit values to the range + 0..MAXJSAMPLE; the input value may fall somewhat outside this range + due to noise introduced by quantization, roundoff error, etc. These + processes are inner loops and need to be as fast as possible. On most + machines, particularly CPUs with pipelines or instruction prefetch, + a (subscript-check-less) C table lookup + x := sample_range_limit[x]; + is faster than explicit tests + if (x < 0) x := 0; + else if (x > MAXJSAMPLE) x := MAXJSAMPLE; + These processes all use a common table prepared by the routine below. + + For most steps we can mathematically guarantee that the initial value + of x is within MAXJSAMPLE+1 of the legal range, so a table running from + -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial + limiting step (just after the IDCT), a wildly out-of-range value is + possible if the input data is corrupt. To avoid any chance of indexing + off the end of memory and getting a bad-pointer trap, we perform the + post-IDCT limiting thus: + x := range_limit[x & MASK]; + where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit + samples. Under normal circumstances this is more than enough range and + a correct output will be generated; with bogus input data the mask will + cause wraparound, and we will safely generate a bogus-but-in-range output. + For the post-IDCT step, we want to convert the data from signed to unsigned + representation by adding CENTERJSAMPLE at the same time that we limit it. + So the post-IDCT limiting table ends up looking like this: + CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE, + MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + 0,1,...,CENTERJSAMPLE-1 + Negative inputs select values from the upper half of the table after + masking. + + We can save some space by overlapping the start of the post-IDCT table + with the simpler range limiting table. The post-IDCT table begins at + sample_range_limit + CENTERJSAMPLE. + + Note that the table is allocated in near data space on PCs; it's small + enough and used often enough to justify this. } + +{LOCAL} +procedure prepare_range_limit_table (cinfo : j_decompress_ptr); +{ Allocate and fill in the sample_range_limit table } +var + table : range_limit_table_ptr; + idct_table : JSAMPROW; + i : int; +begin + table := range_limit_table_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)) ); + + { First segment of "simple" table: limit[x] := 0 for x < 0 } + MEMZERO(table, (MAXJSAMPLE+1) * SIZEOF(JSAMPLE)); + + cinfo^.sample_range_limit := (table); + { allow negative subscripts of simple table } + { is noop, handled via type definition (Nomssi) } + { Main part of "simple" table: limit[x] := x } + for i := 0 to MAXJSAMPLE do + table^[i] := JSAMPLE (i); + idct_table := JSAMPROW(@ table^[CENTERJSAMPLE]); + { Point to where post-IDCT table starts } + { End of simple table, rest of first half of post-IDCT table } + for i := CENTERJSAMPLE to pred(2*(MAXJSAMPLE+1)) do + idct_table^[i] := MAXJSAMPLE; + { Second half of post-IDCT table } + MEMZERO(@(idct_table^[2 * (MAXJSAMPLE+1)]), + (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + MEMCOPY(@(idct_table^[(4 * (MAXJSAMPLE+1) - CENTERJSAMPLE)]), + @cinfo^.sample_range_limit^[0], CENTERJSAMPLE * SIZEOF(JSAMPLE)); + +end; + + +{ Master selection of decompression modules. + This is done once at jpeg_start_decompress time. We determine + which modules will be used and give them appropriate initialization calls. + We also initialize the decompressor input side to begin consuming data. + + Since jpeg_read_header has finished, we know what is in the SOF + and (first) SOS markers. We also have all the application parameter + settings. } + +{LOCAL} +procedure master_selection (cinfo : j_decompress_ptr); +var + master : my_master_ptr; + use_c_buffer : boolean; + samplesperrow : long; + jd_samplesperrow : JDIMENSION; +var + nscans : int; +begin + master := my_master_ptr (cinfo^.master); + + { Initialize dimensions and other stuff } + jpeg_calc_output_dimensions(cinfo); + prepare_range_limit_table(cinfo); + + { Width of an output scanline must be representable as JDIMENSION. } + samplesperrow := long(cinfo^.output_width) * long (cinfo^.out_color_components); + jd_samplesperrow := JDIMENSION (samplesperrow); + if (long(jd_samplesperrow) <> samplesperrow) then + ERREXIT(j_common_ptr(cinfo), JERR_WIDTH_OVERFLOW); + + { Initialize my private state } + master^.pass_number := 0; + master^.using_merged_upsample := use_merged_upsample(cinfo); + + { Color quantizer selection } + master^.quantizer_1pass := NIL; + master^.quantizer_2pass := NIL; + { No mode changes if not using buffered-image mode. } + if (not cinfo^.quantize_colors) or (not cinfo^.buffered_image) then + begin + cinfo^.enable_1pass_quant := FALSE; + cinfo^.enable_external_quant := FALSE; + cinfo^.enable_2pass_quant := FALSE; + end; + if (cinfo^.quantize_colors) then + begin + if (cinfo^.raw_data_out) then + ERREXIT(j_common_ptr(cinfo), JERR_NOTIMPL); + { 2-pass quantizer only works in 3-component color space. } + if (cinfo^.out_color_components <> 3) then + begin + cinfo^.enable_1pass_quant := TRUE; + cinfo^.enable_external_quant := FALSE; + cinfo^.enable_2pass_quant := FALSE; + cinfo^.colormap := NIL; + end + else + if (cinfo^.colormap <> NIL) then + begin + cinfo^.enable_external_quant := TRUE; + end + else + if (cinfo^.two_pass_quantize) then + begin + cinfo^.enable_2pass_quant := TRUE; + end + else + begin + cinfo^.enable_1pass_quant := TRUE; + end; + + if (cinfo^.enable_1pass_quant) then + begin +{$ifdef QUANT_1PASS_SUPPORTED} + jinit_1pass_quantizer(cinfo); + master^.quantizer_1pass := cinfo^.cquantize; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end; + + { We use the 2-pass code to map to external colormaps. } + if (cinfo^.enable_2pass_quant) or (cinfo^.enable_external_quant) then + begin +{$ifdef QUANT_2PASS_SUPPORTED} + jinit_2pass_quantizer(cinfo); + master^.quantizer_2pass := cinfo^.cquantize; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end; + { If both quantizers are initialized, the 2-pass one is left active; + this is necessary for starting with quantization to an external map. } + end; + + { Post-processing: in particular, color conversion first } + if (not cinfo^.raw_data_out) then + begin + if (master^.using_merged_upsample) then + begin +{$ifdef UPSAMPLE_MERGING_SUPPORTED} + jinit_merged_upsampler(cinfo); { does color conversion too } +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + jinit_color_deconverter(cinfo); + jinit_upsampler(cinfo); + end; + jinit_d_post_controller(cinfo, cinfo^.enable_2pass_quant); + end; + { Inverse DCT } + jinit_inverse_dct(cinfo); + { Entropy decoding: either Huffman or arithmetic coding. } + if (cinfo^.arith_code) then + begin + ERREXIT(j_common_ptr(cinfo), JERR_ARITH_NOTIMPL); + end + else + begin + if (cinfo^.progressive_mode) then + begin +{$ifdef D_PROGRESSIVE_SUPPORTED} + jinit_phuff_decoder(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + jinit_huff_decoder(cinfo); + end; + + { Initialize principal buffer controllers. } + use_c_buffer := cinfo^.inputctl^.has_multiple_scans or cinfo^.buffered_image; + jinit_d_coef_controller(cinfo, use_c_buffer); + + if (not cinfo^.raw_data_out) then + jinit_d_main_controller(cinfo, FALSE { never need full buffer here }); + + { We can now tell the memory manager to allocate virtual arrays. } + cinfo^.mem^.realize_virt_arrays (j_common_ptr(cinfo)); + + { Initialize input side of decompressor to consume first scan. } + cinfo^.inputctl^.start_input_pass (cinfo); + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + { If jpeg_start_decompress will read the whole file, initialize + progress monitoring appropriately. The input step is counted + as one pass. } + + if (cinfo^.progress <> NIL) and (not cinfo^.buffered_image) and + (cinfo^.inputctl^.has_multiple_scans) then + begin + + { Estimate number of scans to set pass_limit. } + if (cinfo^.progressive_mode) then + begin + { Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. } + nscans := 2 + 3 * cinfo^.num_components; + end + else + begin + { For a nonprogressive multiscan file, estimate 1 scan per component. } + nscans := cinfo^.num_components; + end; + cinfo^.progress^.pass_counter := Long(0); + cinfo^.progress^.pass_limit := long (cinfo^.total_iMCU_rows) * nscans; + cinfo^.progress^.completed_passes := 0; + if cinfo^.enable_2pass_quant then + cinfo^.progress^.total_passes := 3 + else + cinfo^.progress^.total_passes := 2; + { Count the input pass as done } + Inc(master^.pass_number); + end; +{$endif} { D_MULTISCAN_FILES_SUPPORTED } +end; + + +{ Per-pass setup. + This is called at the beginning of each output pass. We determine which + modules will be active during this pass and give them appropriate + start_pass calls. We also set is_dummy_pass to indicate whether this + is a "real" output pass or a dummy pass for color quantization. + (In the latter case, jdapistd.c will crank the pass to completion.) } + +{METHODDEF} +procedure prepare_for_output_pass (cinfo : j_decompress_ptr); +var + master : my_master_ptr; +begin + master := my_master_ptr (cinfo^.master); + + if (master^.pub.is_dummy_pass) then + begin +{$ifdef QUANT_2PASS_SUPPORTED} + { Final pass of 2-pass quantization } + master^.pub.is_dummy_pass := FALSE; + cinfo^.cquantize^.start_pass (cinfo, FALSE); + cinfo^.post^.start_pass (cinfo, JBUF_CRANK_DEST); + cinfo^.main^.start_pass (cinfo, JBUF_CRANK_DEST); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} { QUANT_2PASS_SUPPORTED } + end + else + begin + if (cinfo^.quantize_colors) and (cinfo^.colormap = NIL) then + begin + { Select new quantization method } + if (cinfo^.two_pass_quantize) and (cinfo^.enable_2pass_quant) then + begin + cinfo^.cquantize := master^.quantizer_2pass; + master^.pub.is_dummy_pass := TRUE; + end + else + if (cinfo^.enable_1pass_quant) then + begin + cinfo^.cquantize := master^.quantizer_1pass; + end + else + begin + ERREXIT(j_common_ptr(cinfo), JERR_MODE_CHANGE); + end; + end; + cinfo^.idct^.start_pass (cinfo); + cinfo^.coef^.start_output_pass (cinfo); + if (not cinfo^.raw_data_out) then + begin + if (not master^.using_merged_upsample) then + cinfo^.cconvert^.start_pass (cinfo); + cinfo^.upsample^.start_pass (cinfo); + if (cinfo^.quantize_colors) then + cinfo^.cquantize^.start_pass (cinfo, master^.pub.is_dummy_pass); + if master^.pub.is_dummy_pass then + cinfo^.post^.start_pass (cinfo, JBUF_SAVE_AND_PASS) + else + cinfo^.post^.start_pass (cinfo, JBUF_PASS_THRU); + cinfo^.main^.start_pass (cinfo, JBUF_PASS_THRU); + end; + end; + + { Set up progress monitor's pass info if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.completed_passes := master^.pass_number; + if master^.pub.is_dummy_pass then + cinfo^.progress^.total_passes := master^.pass_number + 2 + else + cinfo^.progress^.total_passes := master^.pass_number + 1; + { In buffered-image mode, we assume one more output pass if EOI not + yet reached, but no more passes if EOI has been reached. } + + if (cinfo^.buffered_image) and (not cinfo^.inputctl^.eoi_reached) then + begin + if cinfo^.enable_2pass_quant then + Inc(cinfo^.progress^.total_passes, 2) + else + Inc(cinfo^.progress^.total_passes, 1); + end; + end; +end; + + +{ Finish up at end of an output pass. } + +{METHODDEF} +procedure finish_output_pass (cinfo : j_decompress_ptr); +var + master : my_master_ptr; +begin + master := my_master_ptr (cinfo^.master); + + if (cinfo^.quantize_colors) then + cinfo^.cquantize^.finish_pass (cinfo); + Inc(master^.pass_number); +end; + + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + +{ Switch to a new external colormap between output passes. } + +{GLOBAL} +procedure jpeg_new_colormap (cinfo : j_decompress_ptr); +var + master : my_master_ptr; +begin + master := my_master_ptr (cinfo^.master); + + { Prevent application from calling me at wrong times } + if (cinfo^.global_state <> DSTATE_BUFIMAGE) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + if (cinfo^.quantize_colors) and (cinfo^.enable_external_quant) and + (cinfo^.colormap <> NIL) then + begin + { Select 2-pass quantizer for external colormap use } + cinfo^.cquantize := master^.quantizer_2pass; + { Notify quantizer of colormap change } + cinfo^.cquantize^.new_color_map (cinfo); + master^.pub.is_dummy_pass := FALSE; { just in case } + end + else + ERREXIT(j_common_ptr(cinfo), JERR_MODE_CHANGE); +end; + +{$endif} { D_MULTISCAN_FILES_SUPPORTED } + + +{ Initialize master decompression control and select active modules. + This is performed at the start of jpeg_start_decompress. } + +{GLOBAL} +procedure jinit_master_decompress (cinfo : j_decompress_ptr); +var + master : my_master_ptr; +begin + master := my_master_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_decomp_master)) ); + cinfo^.master := jpeg_decomp_master_ptr(master); + master^.pub.prepare_for_output_pass := prepare_for_output_pass; + master^.pub.finish_output_pass := finish_output_pass; + + master^.pub.is_dummy_pass := FALSE; + + master_selection(cinfo); +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdmerge_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdmerge_del.pas new file mode 100644 index 0000000..0c9cd5a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdmerge_del.pas @@ -0,0 +1,515 @@ +unit jdmerge_del; + +{ This file contains code for merged upsampling/color conversion. + + This file combines functions from jdsample.c and jdcolor.c; + read those files first to understand what's going on. + + When the chroma components are to be upsampled by simple replication + (ie, box filtering), we can save some work in color conversion by + calculating all the output pixels corresponding to a pair of chroma + samples at one time. In the conversion equations + R := Y + K1 * Cr + G := Y + K2 * Cb + K3 * Cr + B := Y + K4 * Cb + only the Y term varies among the group of pixels corresponding to a pair + of chroma samples, so the rest of the terms can be calculated just once. + At typical sampling ratios, this eliminates half or three-quarters of the + multiplications needed for color conversion. + + This file currently provides implementations for the following cases: + YCbCr => RGB color conversion only. + Sampling ratios of 2h1v or 2h2v. + No scaling needed at upsample time. + Corner-aligned (non-CCIR601) sampling alignment. + Other special cases could be added, but in most applications these are + the only common cases. (For uncommon cases we fall back on the more + general code in jdsample.c and jdcolor.c.) } + +{ Original: jdmerge.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jutils_del; + +{ Module initialization routine for merged upsampling/color conversion. + + NB: this is called under the conditions determined by use_merged_upsample() + in jdmaster.c. That routine MUST correspond to the actual capabilities + of this module; no safety checks are made here. } + +{GLOBAL} +procedure jinit_merged_upsampler (cinfo : j_decompress_ptr); + +implementation + + +{ Private subobject } + +type { the same definition as in JdColor } + int_Color_Table = array[0..MAXJSAMPLE+1-1] of int; + int_CConvertPtr = ^int_Color_Table; + INT32_Color_Table = array[0..MAXJSAMPLE+1-1] of INT32; + INT32_CConvertPtr = ^INT32_Color_Table; + +type + my_upsample_ptr = ^my_upsampler; + my_upsampler = record + pub : jpeg_upsampler; { public fields } + + { Pointer to routine to do actual upsampling/conversion of one row group } + upmethod : procedure (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + in_row_group_ctr : JDIMENSION; + output_buf : JSAMPARRAY); + + { Private state for YCC->RGB conversion } + Cr_r_tab : int_CConvertPtr; { => table for Cr to R conversion } + Cb_b_tab : int_CConvertPtr; { => table for Cb to B conversion } + Cr_g_tab : INT32_CConvertPtr; { => table for Cr to G conversion } + Cb_g_tab : INT32_CConvertPtr; { => table for Cb to G conversion } + + { For 2:1 vertical sampling, we produce two output rows at a time. + We need a "spare" row buffer to hold the second output row if the + application provides just a one-row buffer; we also use the spare + to discard the dummy last row if the image height is odd. } + + spare_row : JSAMPROW; + spare_full : boolean; { TRUE if spare buffer is occupied } + + out_row_width : JDIMENSION; { samples per output row } + rows_to_go : JDIMENSION; { counts rows remaining in image } + end; {my_upsampler;} + + +const + SCALEBITS = 16; { speediest right-shift on some machines } + ONE_HALF = (INT32(1) shl (SCALEBITS-1)); + + +{ Initialize tables for YCC->RGB colorspace conversion. + This is taken directly from jdcolor.c; see that file for more info. } + +{LOCAL} +procedure build_ycc_rgb_table (cinfo : j_decompress_ptr); +const + FIX_1_40200 = INT32( Round(1.40200 * (INT32(1) shl SCALEBITS)) ); + FIX_1_77200 = INT32( Round(1.77200 * (INT32(1) shl SCALEBITS)) ); + FIX_0_71414 = INT32( Round(0.71414 * (INT32(1) shl SCALEBITS)) ); + FIX_0_34414 = INT32( Round(0.34414 * (INT32(1) shl SCALEBITS)) ); +var + upsample : my_upsample_ptr; + i : int; + x : INT32; +var + shift_temp : INT32; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + upsample^.Cr_r_tab := int_CConvertPtr ( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)) ); + upsample^.Cb_b_tab := int_CConvertPtr ( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)) ); + upsample^.Cr_g_tab := INT32_CConvertPtr ( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)) ); + upsample^.Cb_g_tab := INT32_CConvertPtr ( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)) ); + + x := -CENTERJSAMPLE; + for i := 0 to pred(MAXJSAMPLE) do + begin + { i is the actual input pixel value, in the range 0..MAXJSAMPLE } + { The Cb or Cr value we are thinking of is x := i - CENTERJSAMPLE } + { Cr=>R value is nearest int to 1.40200 * x } + {upsample^.Cr_r_tab^[i] := int( + RIGHT_SHIFT(FIX_1_40200 * x + ONE_HALF, SCALEBITS) );} + shift_temp := FIX_1_40200 * x + ONE_HALF; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + upsample^.Cr_r_tab^[i] := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + upsample^.Cr_r_tab^[i] := int(shift_temp shr SCALEBITS); + + + { Cb=>B value is nearest int to 1.77200 * x } + {upsample^.Cb_b_tab^[i] := int( + RIGHT_SHIFT(FIX_1_77200 * x + ONE_HALF, SCALEBITS) );} + shift_temp := FIX_1_77200 * x + ONE_HALF; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + upsample^.Cb_b_tab^[i] := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + upsample^.Cb_b_tab^[i] := int(shift_temp shr SCALEBITS); + + { Cr=>G value is scaled-up -0.71414 * x } + upsample^.Cr_g_tab^[i] := (- FIX_0_71414) * x; + { Cb=>G value is scaled-up -0.34414 * x } + { We also add in ONE_HALF so that need not do it in inner loop } + upsample^.Cb_g_tab^[i] := (- FIX_0_34414) * x + ONE_HALF; + Inc(x); + end; +end; + + +{ Initialize for an upsampling pass. } + +{METHODDEF} +procedure start_pass_merged_upsample (cinfo : j_decompress_ptr); +var + upsample : my_upsample_ptr; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + { Mark the spare buffer empty } + upsample^.spare_full := FALSE; + { Initialize total-height counter for detecting bottom of image } + upsample^.rows_to_go := cinfo^.output_height; +end; + + +{ Control routine to do upsampling (and color conversion). + + The control routine just handles the row buffering considerations. } + +{METHODDEF} +procedure merged_2v_upsample (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +{ 2:1 vertical sampling case: may need a spare row. } +var + upsample : my_upsample_ptr; + work_ptrs : array[0..2-1] of JSAMPROW; + num_rows : JDIMENSION; { number of rows returned to caller } +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + if (upsample^.spare_full) then + begin + { If we have a spare row saved from a previous cycle, just return it. } + jcopy_sample_rows(JSAMPARRAY(@upsample^.spare_row), + 0, + JSAMPARRAY(@ output_buf^[out_row_ctr]), + 0, 1, upsample^.out_row_width); + num_rows := 1; + upsample^.spare_full := FALSE; + end + else + begin + { Figure number of rows to return to caller. } + num_rows := 2; + { Not more than the distance to the end of the image. } + if (num_rows > upsample^.rows_to_go) then + num_rows := upsample^.rows_to_go; + { And not more than what the client can accept: } + Dec(out_rows_avail, {var} out_row_ctr); + if (num_rows > out_rows_avail) then + num_rows := out_rows_avail; + { Create output pointer array for upsampler. } + work_ptrs[0] := output_buf^[out_row_ctr]; + if (num_rows > 1) then + begin + work_ptrs[1] := output_buf^[out_row_ctr + 1]; + end + else + begin + work_ptrs[1] := upsample^.spare_row; + upsample^.spare_full := TRUE; + end; + { Now do the upsampling. } + upsample^.upmethod (cinfo, input_buf, {var}in_row_group_ctr, + JSAMPARRAY(@work_ptrs)); + end; + + { Adjust counts } + Inc(out_row_ctr, num_rows); + Dec(upsample^.rows_to_go, num_rows); + { When the buffer is emptied, declare this input row group consumed } + if (not upsample^.spare_full) then + Inc(in_row_group_ctr); +end; + + +{METHODDEF} +procedure merged_1v_upsample (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +{ 1:1 vertical sampling case: much easier, never need a spare row. } +var + upsample : my_upsample_ptr; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + { Just do the upsampling. } + upsample^.upmethod (cinfo, input_buf, in_row_group_ctr, + JSAMPARRAY(@ output_buf^[out_row_ctr])); + { Adjust counts } + Inc(out_row_ctr); + Inc(in_row_group_ctr); +end; + + +{ These are the routines invoked by the control routines to do + the actual upsampling/conversion. One row group is processed per call. + + Note: since we may be writing directly into application-supplied buffers, + we have to be honest about the output width; we can't assume the buffer + has been rounded up to an even width. } + + +{ Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. } + +{METHODDEF} +procedure h2v1_merged_upsample (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + in_row_group_ctr : JDIMENSION; + output_buf : JSAMPARRAY); +var + upsample : my_upsample_ptr; + {register} y, cred, cgreen, cblue : int; + cb, cr : int; + {register} outptr : JSAMPROW; + inptr0, inptr1, inptr2 : JSAMPLE_PTR; + col : JDIMENSION; + { copy these pointers into registers if possible } + {register} range_limit : range_limit_table_ptr; + Crrtab : int_CConvertPtr; + Cbbtab : int_CConvertPtr; + Crgtab : INT32_CConvertPtr; + Cbgtab : INT32_CConvertPtr; +var + shift_temp : INT32; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + range_limit := cinfo^.sample_range_limit; + Crrtab := upsample^.Cr_r_tab; + Cbbtab := upsample^.Cb_b_tab; + Crgtab := upsample^.Cr_g_tab; + Cbgtab := upsample^.Cb_g_tab; + + inptr0 := JSAMPLE_PTR(input_buf^[0]^[in_row_group_ctr]); + inptr1 := JSAMPLE_PTR(input_buf^[1]^[in_row_group_ctr]); + inptr2 := JSAMPLE_PTR(input_buf^[2]^[in_row_group_ctr]); + outptr := output_buf^[0]; + { Loop for each pair of output pixels } + for col := pred(cinfo^.output_width shr 1) downto 0 do + begin + { Do the chroma part of the calculation } + cb := GETJSAMPLE(inptr1^); + Inc(inptr1); + cr := GETJSAMPLE(inptr2^); + Inc(inptr2); + cred := Crrtab^[cr]; + {cgreen := int( RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS) );} + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cgreen := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cgreen := int(shift_temp shr SCALEBITS); + + cblue := Cbbtab^[cb]; + { Fetch 2 Y values and emit 2 pixels } + y := GETJSAMPLE(inptr0^); + Inc(inptr0); + outptr^[RGB_RED] := range_limit^[y + cred]; + outptr^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr), RGB_PIXELSIZE); + y := GETJSAMPLE(inptr0^); + Inc(inptr0); + outptr^[RGB_RED] := range_limit^[y + cred]; + outptr^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr), RGB_PIXELSIZE); + end; + { If image width is odd, do the last output column separately } + if Odd(cinfo^.output_width) then + begin + cb := GETJSAMPLE(inptr1^); + cr := GETJSAMPLE(inptr2^); + cred := Crrtab^[cr]; + {cgreen := int ( RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS) );} + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cgreen := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cgreen := int(shift_temp shr SCALEBITS); + + cblue := Cbbtab^[cb]; + y := GETJSAMPLE(inptr0^); + outptr^[RGB_RED] := range_limit^[y + cred]; + outptr^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr^[RGB_BLUE] := range_limit^[y + cblue]; + end; +end; + + +{ Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. } + +{METHODDEF} +procedure h2v2_merged_upsample (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + in_row_group_ctr : JDIMENSION; + output_buf : JSAMPARRAY); +var + upsample : my_upsample_ptr; + {register} y, cred, cgreen, cblue : int; + cb, cr : int; + {register} outptr0, outptr1 : JSAMPROW; + inptr00, inptr01, inptr1, inptr2 : JSAMPLE_PTR; + col : JDIMENSION; + { copy these pointers into registers if possible } + {register} range_limit : range_limit_table_ptr; + Crrtab : int_CConvertPtr; + Cbbtab : int_CConvertPtr; + Crgtab : INT32_CConvertPtr; + Cbgtab : INT32_CConvertPtr; +var + shift_temp : INT32; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + range_limit := cinfo^.sample_range_limit; + Crrtab := upsample^.Cr_r_tab; + Cbbtab := upsample^.Cb_b_tab; + Crgtab := upsample^.Cr_g_tab; + Cbgtab := upsample^.Cb_g_tab; + + inptr00 := JSAMPLE_PTR(input_buf^[0]^[in_row_group_ctr*2]); + inptr01 := JSAMPLE_PTR(input_buf^[0]^[in_row_group_ctr*2 + 1]); + inptr1 := JSAMPLE_PTR(input_buf^[1]^[in_row_group_ctr]); + inptr2 := JSAMPLE_PTR(input_buf^[2]^[in_row_group_ctr]); + outptr0 := output_buf^[0]; + outptr1 := output_buf^[1]; + { Loop for each group of output pixels } + for col := pred(cinfo^.output_width shr 1) downto 0 do + begin + { Do the chroma part of the calculation } + cb := GETJSAMPLE(inptr1^); + Inc(inptr1); + cr := GETJSAMPLE(inptr2^); + Inc(inptr2); + cred := Crrtab^[cr]; + {cgreen := int( RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS) );} + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cgreen := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cgreen := int(shift_temp shr SCALEBITS); + + cblue := Cbbtab^[cb]; + { Fetch 4 Y values and emit 4 pixels } + y := GETJSAMPLE(inptr00^); + Inc(inptr00); + outptr0^[RGB_RED] := range_limit^[y + cred]; + outptr0^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr0^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr0), RGB_PIXELSIZE); + y := GETJSAMPLE(inptr00^); + Inc(inptr00); + outptr0^[RGB_RED] := range_limit^[y + cred]; + outptr0^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr0^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr0), RGB_PIXELSIZE); + y := GETJSAMPLE(inptr01^); + Inc(inptr01); + outptr1^[RGB_RED] := range_limit^[y + cred]; + outptr1^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr1^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr1), RGB_PIXELSIZE); + y := GETJSAMPLE(inptr01^); + Inc(inptr01); + outptr1^[RGB_RED] := range_limit^[y + cred]; + outptr1^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr1^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr1), RGB_PIXELSIZE); + end; + { If image width is odd, do the last output column separately } + if Odd(cinfo^.output_width) then + begin + cb := GETJSAMPLE(inptr1^); + cr := GETJSAMPLE(inptr2^); + cred := Crrtab^[cr]; + {cgreen := int (RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS));} + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cgreen := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cgreen := int(shift_temp shr SCALEBITS); + + cblue := Cbbtab^[cb]; + y := GETJSAMPLE(inptr00^); + outptr0^[RGB_RED] := range_limit^[y + cred]; + outptr0^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr0^[RGB_BLUE] := range_limit^[y + cblue]; + y := GETJSAMPLE(inptr01^); + outptr1^[RGB_RED] := range_limit^[y + cred]; + outptr1^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr1^[RGB_BLUE] := range_limit^[y + cblue]; + end; +end; + + +{ Module initialization routine for merged upsampling/color conversion. + + NB: this is called under the conditions determined by use_merged_upsample() + in jdmaster.c. That routine MUST correspond to the actual capabilities + of this module; no safety checks are made here. } + + +{GLOBAL} +procedure jinit_merged_upsampler (cinfo : j_decompress_ptr); +var + upsample : my_upsample_ptr; +begin + upsample := my_upsample_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_upsampler)) ); + cinfo^.upsample := jpeg_upsampler_ptr (upsample); + upsample^.pub.start_pass := start_pass_merged_upsample; + upsample^.pub.need_context_rows := FALSE; + + upsample^.out_row_width := cinfo^.output_width * cinfo^.out_color_components; + + if (cinfo^.max_v_samp_factor = 2) then + begin + upsample^.pub.upsample := merged_2v_upsample; + upsample^.upmethod := h2v2_merged_upsample; + { Allocate a spare row buffer } + upsample^.spare_row := JSAMPROW( + cinfo^.mem^.alloc_large ( j_common_ptr(cinfo), JPOOL_IMAGE, + size_t (upsample^.out_row_width * SIZEOF(JSAMPLE))) ); + end + else + begin + upsample^.pub.upsample := merged_1v_upsample; + upsample^.upmethod := h2v1_merged_upsample; + { No spare row needed } + upsample^.spare_row := NIL; + end; + + build_ycc_rgb_table(cinfo); +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdphuff_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdphuff_del.pas new file mode 100644 index 0000000..97446d7 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdphuff_del.pas @@ -0,0 +1,1060 @@ +unit jdphuff_del; + +{ This file contains Huffman entropy decoding routines for progressive JPEG. + + Much of the complexity here has to do with supporting input suspension. + If the data source module demands suspension, we want to be able to back + up to the start of the current MCU. To do this, we copy state variables + into local working storage, and update them back to the permanent + storage only upon successful completion of an MCU. } + +{ Original: jdphuff.c ; Copyright (C) 1995-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdeferr_del, + jerror_del, + jutils_del, + jdhuff_del; { Declarations shared with jdhuff.c } + + +{GLOBAL} +procedure jinit_phuff_decoder (cinfo : j_decompress_ptr); + +implementation + +{ Expanded entropy decoder object for progressive Huffman decoding. + + The savable_state subrecord contains fields that change within an MCU, + but must not be updated permanently until we complete the MCU. } + +type + savable_state = record + EOBRUN : uInt; { remaining EOBs in EOBRUN } + last_dc_val : array[00..MAX_COMPS_IN_SCAN-1] of int; + { last DC coef for each component } + end; + + +type + phuff_entropy_ptr = ^phuff_entropy_decoder; + phuff_entropy_decoder = record + pub : jpeg_entropy_decoder; { public fields } + + { These fields are loaded into local variables at start of each MCU. + In case of suspension, we exit WITHOUT updating them. } + + bitstate : bitread_perm_state; { Bit buffer at start of MCU } + saved : savable_state; { Other state at start of MCU } + + { These fields are NOT loaded into local working state. } + restarts_to_go : uInt; { MCUs left in this restart interval } + + { Pointers to derived tables (these workspaces have image lifespan) } + derived_tbls : array[0..NUM_HUFF_TBLS-1] of d_derived_tbl_ptr; + + ac_derived_tbl : d_derived_tbl_ptr; { active table during an AC scan } + end; + + + +{ Forward declarations } +{METHODDEF} +function decode_mcu_DC_first (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function decode_mcu_AC_first (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function decode_mcu_DC_refine (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function decode_mcu_AC_refine (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + forward; + +{ Initialize for a Huffman-compressed scan. } + +{METHODDEF} +procedure start_pass_phuff_decoder (cinfo : j_decompress_ptr); +var + entropy : phuff_entropy_ptr; + is_DC_band, bad : boolean; + ci, coefi, tbl : int; + coef_bit_ptr : coef_bits_ptr; + compptr : jpeg_component_info_ptr; +var + cindex : int; + expected : int; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + + is_DC_band := (cinfo^.Ss = 0); + + { Validate scan parameters } + bad := FALSE; + if (is_DC_band) then + begin + if (cinfo^.Se <> 0) then + bad := TRUE; + end + else + begin + { need not check Ss/Se < 0 since they came from unsigned bytes } + if (cinfo^.Ss > cinfo^.Se) or (cinfo^.Se >= DCTSIZE2) then + bad := TRUE; + { AC scans may have only one component } + if (cinfo^.comps_in_scan <> 1) then + bad := TRUE; + end; + if (cinfo^.Ah <> 0) then + begin + { Successive approximation refinement scan: must have Al = Ah-1. } + if (cinfo^.Al <> cinfo^.Ah-1) then + bad := TRUE; + end; + if (cinfo^.Al > 13) then { need not check for < 0 } + bad := TRUE; + { Arguably the maximum Al value should be less than 13 for 8-bit precision, + but the spec doesn't say so, and we try to be liberal about what we + accept. Note: large Al values could result in out-of-range DC + coefficients during early scans, leading to bizarre displays due to + overflows in the IDCT math. But we won't crash. } + + if (bad) then + ERREXIT4(j_common_ptr(cinfo), JERR_BAD_PROGRESSION, + cinfo^.Ss, cinfo^.Se, cinfo^.Ah, cinfo^.Al); + { Update progression status, and verify that scan order is legal. + Note that inter-scan inconsistencies are treated as warnings + not fatal errors ... not clear if this is right way to behave. } + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + cindex := cinfo^.cur_comp_info[ci]^.component_index; + coef_bit_ptr := coef_bits_ptr(@(cinfo^.coef_bits^[cindex])); {^[0] ??? + Nomssi } + if (not is_DC_band) and (coef_bit_ptr^[0] < 0) then + { AC without prior DC scan } + WARNMS2(j_common_ptr(cinfo), JWRN_BOGUS_PROGRESSION, cindex, 0); + for coefi := cinfo^.Ss to cinfo^.Se do + begin + if (coef_bit_ptr^[coefi] < 0) then + expected := 0 + else + expected := coef_bit_ptr^[coefi]; + if (cinfo^.Ah <> expected) then + WARNMS2(j_common_ptr(cinfo), JWRN_BOGUS_PROGRESSION, cindex, coefi); + coef_bit_ptr^[coefi] := cinfo^.Al; + end; + end; + + { Select MCU decoding routine } + if (cinfo^.Ah = 0) then + begin + if (is_DC_band) then + entropy^.pub.decode_mcu := decode_mcu_DC_first + else + entropy^.pub.decode_mcu := decode_mcu_AC_first; + end + else + begin + if (is_DC_band) then + entropy^.pub.decode_mcu := decode_mcu_DC_refine + else + entropy^.pub.decode_mcu := decode_mcu_AC_refine; + end; + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { Make sure requested tables are present, and compute derived tables. + We may build same derived table more than once, but it's not expensive. } + + if (is_DC_band) then + begin + if (cinfo^.Ah = 0) then + begin { DC refinement needs no table } + tbl := compptr^.dc_tbl_no; + jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, + entropy^.derived_tbls[tbl]); + end; + end + else + begin + tbl := compptr^.ac_tbl_no; + jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, + entropy^.derived_tbls[tbl]); + { remember the single active table } + entropy^.ac_derived_tbl := entropy^.derived_tbls[tbl]; + end; + { Initialize DC predictions to 0 } + entropy^.saved.last_dc_val[ci] := 0; + end; + + { Initialize bitread state variables } + entropy^.bitstate.bits_left := 0; + entropy^.bitstate.get_buffer := 0; { unnecessary, but keeps Purify quiet } + entropy^.pub.insufficient_data := FALSE; + + { Initialize private state variables } + entropy^.saved.EOBRUN := 0; + + { Initialize restart counter } + entropy^.restarts_to_go := cinfo^.restart_interval; +end; + + +{ Figure F.12: extend sign bit. + On some machines, a shift and add will be faster than a table lookup. } + +{$ifdef AVOID_TABLES} + +#define HUFF_EXTEND(x,s) + ((x) < (1shl((s)-1)) ? (x) + (((-1)shl(s)) + 1) : (x)) + +{$else} + +{ #define HUFF_EXTEND(x,s) + if (x) < extend_test[s] then + (x) + extend_offset[s] + else + (x)} + +const + extend_test : Array[0..16-1] of int = { entry n is 2**(n-1) } + ($0000, $0001, $0002, $0004, $0008, $0010, $0020, $0040, + $0080, $0100, $0200, $0400, $0800, $1000, $2000, $4000); + +const + extend_offset : array[0..16-1] of int = { entry n is (-1 shl n) + 1 } + ( 0, ((-1) shl 1) + 1, ((-1) shl 2) + 1, ((-1) shl 3) + 1, ((-1) shl 4) + 1, + ((-1) shl 5) + 1, ((-1) shl 6) + 1, ((-1) shl 7) + 1, ((-1) shl 8) + 1, + ((-1) shl 9) + 1, ((-1) shl 10) + 1, ((-1) shl 11) + 1, ((-1) shl 12) + 1, + ((-1) shl 13) + 1, ((-1) shl 14) + 1, ((-1) shl 15) + 1 ); + +{$endif} { AVOID_TABLES } + + +{ Check for a restart marker & resynchronize decoder. + return:=s FALSE if must suspend. } + +{LOCAL} +function process_restart (cinfo : j_decompress_ptr) : boolean; +var + entropy : phuff_entropy_ptr; + ci : int; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + + { Throw away any unused bits remaining in bit buffer; } + { include any full bytes in next_marker's count of discarded bytes } + Inc(cinfo^.marker^.discarded_bytes, entropy^.bitstate.bits_left div 8); + entropy^.bitstate.bits_left := 0; + + { Advance past the RSTn marker } + if (not cinfo^.marker^.read_restart_marker (cinfo)) then + begin + process_restart := FALSE; + exit; + end; + + { Re-initialize DC predictions to 0 } + for ci := 0 to pred(cinfo^.comps_in_scan) do + entropy^.saved.last_dc_val[ci] := 0; + { Re-init EOB run count, too } + entropy^.saved.EOBRUN := 0; + + { Reset restart counter } + entropy^.restarts_to_go := cinfo^.restart_interval; + + { Reset out-of-data flag, unless read_restart_marker left us smack up + against a marker. In that case we will end up treating the next data + segment as empty, and we can avoid producing bogus output pixels by + leaving the flag set. } + if (cinfo^.unread_marker = 0) then + entropy^.pub.insufficient_data := FALSE; + + process_restart := TRUE; +end; + + +{ Huffman MCU decoding. + Each of these routines decodes and returns one MCU's worth of + Huffman-compressed coefficients. + The coefficients are reordered from zigzag order into natural array order, + but are not dequantized. + + The i'th block of the MCU is stored into the block pointed to by + MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER. + + We return FALSE if data source requested suspension. In that case no + changes have been made to permanent state. (Exception: some output + coefficients may already have been assigned. This is harmless for + spectral selection, since we'll just re-assign them on the next call. + Successive approximation AC refinement has to be more careful, however.) } + + +{ MCU decoding for DC initial scan (either spectral selection, + or first pass of successive approximation). } + +{METHODDEF} +function decode_mcu_DC_first (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; +label + label1; +var + entropy : phuff_entropy_ptr; + Al : int; + {register} s, r : int; + blkn, ci : int; + block : JBLOCK_PTR; + {BITREAD_STATE_VARS;} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; + + state : savable_state; + tbl : d_derived_tbl_ptr; + compptr : jpeg_component_info_ptr; +var + nb, look : int; {register} +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Al := cinfo^.Al; + + { Process restart marker if needed; may have to suspend } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if (not process_restart(cinfo)) then + begin + decode_mcu_DC_first := FALSE; + exit; + end; + end; + + { If we've run out of data, just leave the MCU set to zeroes. + This way, we return uniform gray for the remainder of the segment. } + + if not entropy^.pub.insufficient_data then + begin + + { Load up working state } + {BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);} + br_state.cinfo := cinfo; + br_state.next_input_byte := cinfo^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + get_buffer := entropy^.bitstate.get_buffer; + bits_left := entropy^.bitstate.bits_left; + + {ASSIGN_STATE(state, entropy^.saved);} + state := entropy^.saved; + + { Outer loop handles each block in the MCU } + + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + block := JBLOCK_PTR(MCU_data[blkn]); + ci := cinfo^.MCU_membership[blkn]; + compptr := cinfo^.cur_comp_info[ci]; + tbl := entropy^.derived_tbls[compptr^.dc_tbl_no]; + + { Decode a single block's worth of coefficients } + + { Section F.2.2.1: decode the DC coefficient difference } + {HUFF_DECODE(s, br_state, tbl, return FALSE, label1);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu_DC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label1; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := tbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := tbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label1: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,tbl,nb); + if (s < 0) then + begin + decode_mcu_DC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + if (s <> 0) then + begin + {CHECK_BIT_BUFFER(br_state, s, return FALSE);} + if (bits_left < s) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then + begin + decode_mcu_DC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(s);} + Dec(bits_left, s); + r := (int(get_buffer shr bits_left)) and ( pred(1 shl s) ); + + {s := HUFF_EXTEND(r, s);} + if (r < extend_test[s]) then + s := r + extend_offset[s] + else + s := r; + end; + + { Convert DC difference to actual value, update last_dc_val } + Inc(s, state.last_dc_val[ci]); + state.last_dc_val[ci] := s; + { Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) } + block^[0] := JCOEF (s shl Al); + end; + + { Completed MCU, so update state } + {BITREAD_SAVE_STATE(cinfo,entropy^.bitstate);} + cinfo^.src^.next_input_byte := br_state.next_input_byte; + cinfo^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + entropy^.bitstate.get_buffer := get_buffer; + entropy^.bitstate.bits_left := bits_left; + + {ASSIGN_STATE(entropy^.saved, state);} + entropy^.saved := state; + end; + + { Account for restart interval (no-op if not using restarts) } + Dec(entropy^.restarts_to_go); + + decode_mcu_DC_first := TRUE; +end; + + +{ MCU decoding for AC initial scan (either spectral selection, + or first pass of successive approximation). } + +{METHODDEF} +function decode_mcu_AC_first (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; +label + label2; +var + entropy : phuff_entropy_ptr; + Se : int; + Al : int; + {register} s, k, r : int; + EOBRUN : uInt; + block : JBLOCK_PTR; + {BITREAD_STATE_VARS;} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; + + tbl : d_derived_tbl_ptr; +var + nb, look : int; {register} +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Se := cinfo^.Se; + Al := cinfo^.Al; + + { Process restart marker if needed; may have to suspend } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if (not process_restart(cinfo)) then + begin + decode_mcu_AC_first := FALSE; + exit; + end; + end; + + { If we've run out of data, just leave the MCU set to zeroes. + This way, we return uniform gray for the remainder of the segment. } + if not entropy^.pub.insufficient_data then + begin + + { Load up working state. + We can avoid loading/saving bitread state if in an EOB run. } + + EOBRUN := entropy^.saved.EOBRUN; { only part of saved state we care about } + + { There is always only one block per MCU } + + if (EOBRUN > 0) then { if it's a band of zeroes... } + Dec(EOBRUN) { ...process it now (we do nothing) } + else + begin + {BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);} + br_state.cinfo := cinfo; + br_state.next_input_byte := cinfo^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + get_buffer := entropy^.bitstate.get_buffer; + bits_left := entropy^.bitstate.bits_left; + + block := JBLOCK_PTR(MCU_data[0]); + tbl := entropy^.ac_derived_tbl; + + k := cinfo^.Ss; + while (k <= Se) do + begin + {HUFF_DECODE(s, br_state, tbl, return FALSE, label2);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu_AC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label2; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := tbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := tbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label2: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,tbl,nb); + if (s < 0) then + begin + decode_mcu_AC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + r := s shr 4; + s := s and 15; + if (s <> 0) then + begin + Inc(k, r); + {CHECK_BIT_BUFFER(br_state, s, return FALSE);} + if (bits_left < s) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then + begin + decode_mcu_AC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(s);} + Dec(bits_left, s); + r := (int(get_buffer shr bits_left)) and ( pred(1 shl s) ); + + {s := HUFF_EXTEND(r, s);} + if (r < extend_test[s]) then + s := r + extend_offset[s] + else + s := r; + + { Scale and output coefficient in natural (dezigzagged) order } + block^[jpeg_natural_order[k]] := JCOEF (s shl Al); + end + else + begin + if (r = 15) then + begin { ZRL } + Inc(k, 15); { skip 15 zeroes in band } + end + else + begin { EOBr, run length is 2^r + appended bits } + EOBRUN := 1 shl r; + if (r <> 0) then + begin { EOBr, r > 0 } + {CHECK_BIT_BUFFER(br_state, r, return FALSE);} + if (bits_left < r) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,r)) then + begin + decode_mcu_AC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(r);} + Dec(bits_left, r); + r := (int(get_buffer shr bits_left)) and ( pred(1 shl r) ); + + Inc(EOBRUN, r); + end; + Dec(EOBRUN); { this band is processed at this moment } + break; { force end-of-band } + end; + end; + Inc(k); + end; + + {BITREAD_SAVE_STATE(cinfo,entropy^.bitstate);} + cinfo^.src^.next_input_byte := br_state.next_input_byte; + cinfo^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + entropy^.bitstate.get_buffer := get_buffer; + entropy^.bitstate.bits_left := bits_left; + end; + + { Completed MCU, so update state } + entropy^.saved.EOBRUN := EOBRUN; { only part of saved state we care about } + end; + + { Account for restart interval (no-op if not using restarts) } + Dec(entropy^.restarts_to_go); + + decode_mcu_AC_first := TRUE; +end; + + +{ MCU decoding for DC successive approximation refinement scan. + Note: we assume such scans can be multi-component, although the spec + is not very clear on the point. } + +{METHODDEF} +function decode_mcu_DC_refine (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + +var + entropy : phuff_entropy_ptr; + p1 : int; { 1 in the bit position being coded } + blkn : int; + block : JBLOCK_PTR; + {BITREAD_STATE_VARS;} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + p1 := 1 shl cinfo^.Al; + + { Process restart marker if needed; may have to suspend } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if (not process_restart(cinfo)) then + begin + decode_mcu_DC_refine := FALSE; + exit; + end; + end; + + { Not worth the cycles to check insufficient_data here, + since we will not change the data anyway if we read zeroes. } + + { Load up working state } + {BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);} + br_state.cinfo := cinfo; + br_state.next_input_byte := cinfo^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + get_buffer := entropy^.bitstate.get_buffer; + bits_left := entropy^.bitstate.bits_left; + + { Outer loop handles each block in the MCU } + + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + block := JBLOCK_PTR(MCU_data[blkn]); + + { Encoded data is simply the next bit of the two's-complement DC value } + {CHECK_BIT_BUFFER(br_state, 1, return FALSE);} + if (bits_left < 1) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then + begin + decode_mcu_DC_refine := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {if (GET_BITS(1)) then} + Dec(bits_left); + if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) ) <> 0 then + block^[0] := block^[0] or p1; + { Note: since we use OR, repeating the assignment later is safe } + end; + + { Completed MCU, so update state } + {BITREAD_SAVE_STATE(cinfo,entropy^.bitstate);} + cinfo^.src^.next_input_byte := br_state.next_input_byte; + cinfo^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + entropy^.bitstate.get_buffer := get_buffer; + entropy^.bitstate.bits_left := bits_left; + + { Account for restart interval (no-op if not using restarts) } + Dec(entropy^.restarts_to_go); + + decode_mcu_DC_refine := TRUE; +end; + + +{ MCU decoding for AC successive approximation refinement scan. } + +{METHODDEF} +function decode_mcu_AC_refine (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; +label + undoit, label3; +var + entropy : phuff_entropy_ptr; + Se : int; + p1 : int; { 1 in the bit position being coded } + m1 : int; { -1 in the bit position being coded } + {register} s, k, r : int; + EOBRUN : uInt; + block : JBLOCK_PTR; + thiscoef : JCOEF_PTR; + {BITREAD_STATE_VARS;} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; + + tbl : d_derived_tbl_ptr; + num_newnz : int; + newnz_pos : array[0..DCTSIZE2-1] of int; +var + pos : int; +var + nb, look : int; {register} +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Se := cinfo^.Se; + p1 := 1 shl cinfo^.Al; { 1 in the bit position being coded } + m1 := (-1) shl cinfo^.Al; { -1 in the bit position being coded } + + { Process restart marker if needed; may have to suspend } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if (not process_restart(cinfo)) then + begin + decode_mcu_AC_refine := FALSE; + exit; + end; + end; + + { If we've run out of data, don't modify the MCU. } + if not entropy^.pub.insufficient_data then + begin + + { Load up working state } + {BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);} + br_state.cinfo := cinfo; + br_state.next_input_byte := cinfo^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + get_buffer := entropy^.bitstate.get_buffer; + bits_left := entropy^.bitstate.bits_left; + + EOBRUN := entropy^.saved.EOBRUN; { only part of saved state we care about } + + { There is always only one block per MCU } + block := JBLOCK_PTR(MCU_data[0]); + tbl := entropy^.ac_derived_tbl; + + { If we are forced to suspend, we must undo the assignments to any newly + nonzero coefficients in the block, because otherwise we'd get confused + next time about which coefficients were already nonzero. + But we need not undo addition of bits to already-nonzero coefficients; + instead, we can test the current bit position to see if we already did it.} + + num_newnz := 0; + + { initialize coefficient loop counter to start of band } + k := cinfo^.Ss; + + if (EOBRUN = 0) then + begin + while (k <= Se) do + begin + {HUFF_DECODE(s, br_state, tbl, goto undoit, label3);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label3; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := tbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := tbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label3: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,tbl,nb); + if (s < 0) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + r := s shr 4; + s := s and 15; + if (s <> 0) then + begin + if (s <> 1) then { size of new coef should always be 1 } + WARNMS(j_common_ptr(cinfo), JWRN_HUFF_BAD_CODE); + {CHECK_BIT_BUFFER(br_state, 1, goto undoit);} + if (bits_left < 1) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {if (GET_BITS(1)) then} + Dec(bits_left); + if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) )<>0 then + s := p1 { newly nonzero coef is positive } + else + s := m1; { newly nonzero coef is negative } + end + else + begin + if (r <> 15) then + begin + EOBRUN := 1 shl r; { EOBr, run length is 2^r + appended bits } + if (r <> 0) then + begin + {CHECK_BIT_BUFFER(br_state, r, goto undoit);} + if (bits_left < r) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,r)) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(r);} + Dec(bits_left, r); + r := (int(get_buffer shr bits_left)) and ( pred(1 shl r) ); + + Inc(EOBRUN, r); + end; + break; { rest of block is handled by EOB logic } + end; + { note s := 0 for processing ZRL } + end; + { Advance over already-nonzero coefs and r still-zero coefs, + appending correction bits to the nonzeroes. A correction bit is 1 + if the absolute value of the coefficient must be increased. } + + repeat + thiscoef :=@(block^[jpeg_natural_order[k]]); + if (thiscoef^ <> 0) then + begin + {CHECK_BIT_BUFFER(br_state, 1, goto undoit);} + if (bits_left < 1) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {if (GET_BITS(1)) then} + Dec(bits_left); + if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) )<>0 then + begin + if ((thiscoef^ and p1) = 0) then + begin { do nothing if already set it } + if (thiscoef^ >= 0) then + Inc(thiscoef^, p1) + else + Inc(thiscoef^, m1); + end; + end; + end + else + begin + Dec(r); + if (r < 0) then + break; { reached target zero coefficient } + end; + Inc(k); + until (k > Se); + if (s <> 0) then + begin + pos := jpeg_natural_order[k]; + { Output newly nonzero coefficient } + block^[pos] := JCOEF (s); + { Remember its position in case we have to suspend } + newnz_pos[num_newnz] := pos; + Inc(num_newnz); + end; + Inc(k); + end; + end; + + if (EOBRUN > 0) then + begin + { Scan any remaining coefficient positions after the end-of-band + (the last newly nonzero coefficient, if any). Append a correction + bit to each already-nonzero coefficient. A correction bit is 1 + if the absolute value of the coefficient must be increased. } + + while (k <= Se) do + begin + thiscoef := @(block^[jpeg_natural_order[k]]); + if (thiscoef^ <> 0) then + begin + {CHECK_BIT_BUFFER(br_state, 1, goto undoit);} + if (bits_left < 1) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {if (GET_BITS(1)) then} + Dec(bits_left); + if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) )<>0 then + begin + if ((thiscoef^ and p1) = 0) then + begin { do nothing if already changed it } + if (thiscoef^ >= 0) then + Inc(thiscoef^, p1) + else + Inc(thiscoef^, m1); + end; + end; + end; + Inc(k); + end; + { Count one block completed in EOB run } + Dec(EOBRUN); + end; + + { Completed MCU, so update state } + {BITREAD_SAVE_STATE(cinfo,entropy^.bitstate);} + cinfo^.src^.next_input_byte := br_state.next_input_byte; + cinfo^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + entropy^.bitstate.get_buffer := get_buffer; + entropy^.bitstate.bits_left := bits_left; + + entropy^.saved.EOBRUN := EOBRUN; { only part of saved state we care about } + end; + + { Account for restart interval (no-op if not using restarts) } + Dec(entropy^.restarts_to_go); + + decode_mcu_AC_refine := TRUE; + exit; + +undoit: + { Re-zero any output coefficients that we made newly nonzero } + while (num_newnz > 0) do + begin + Dec(num_newnz); +{$warnings off} + block^[newnz_pos[num_newnz]] := 0; + end; + + decode_mcu_AC_refine := FALSE; +end; +{$warnings on} + +{ Module initialization routine for progressive Huffman entropy decoding. } + +{GLOBAL} +procedure jinit_phuff_decoder (cinfo : j_decompress_ptr); +var + entropy : phuff_entropy_ptr; + coef_bit_ptr : int_ptr; + ci, i : int; +begin + entropy := phuff_entropy_ptr( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + SIZEOF(phuff_entropy_decoder)) ); + cinfo^.entropy := jpeg_entropy_decoder_ptr (entropy); + entropy^.pub.start_pass := start_pass_phuff_decoder; + + { Mark derived tables unallocated } + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + entropy^.derived_tbls[i] := NIL; + end; + + { Create progression status table } + cinfo^.coef_bits := coef_bits_ptrrow ( + cinfo^.mem^.alloc_small ( j_common_ptr (cinfo), JPOOL_IMAGE, + cinfo^.num_components*DCTSIZE2*SIZEOF(int)) ); + coef_bit_ptr := @cinfo^.coef_bits^[0][0]; + for ci := 0 to pred(cinfo^.num_components) do + for i := 0 to pred(DCTSIZE2) do + begin + coef_bit_ptr^ := -1; + Inc(coef_bit_ptr); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdpostct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdpostct_del.pas new file mode 100644 index 0000000..338479c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdpostct_del.pas @@ -0,0 +1,343 @@ +unit jdpostct_del; + +{ Original: jdpostct.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +{ This file contains the decompression postprocessing controller. + This controller manages the upsampling, color conversion, and color + quantization/reduction steps; specifically, it controls the buffering + between upsample/color conversion and color quantization/reduction. + + If no color quantization/reduction is required, then this module has no + work to do, and it just hands off to the upsample/color conversion code. + An integrated upsample/convert/quantize process would replace this module + entirely. } + +{$I jconfig_del.inc} + +interface + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jutils_del, + jpeglib_del; + + +{ Initialize postprocessing controller. } + +{GLOBAL} +procedure jinit_d_post_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); +implementation + + +{ Private buffer controller object } + +type + my_post_ptr = ^my_post_controller; + my_post_controller = record + pub : jpeg_d_post_controller; { public fields } + + { Color quantization source buffer: this holds output data from + the upsample/color conversion step to be passed to the quantizer. + For two-pass color quantization, we need a full-image buffer; + for one-pass operation, a strip buffer is sufficient. } + + whole_image : jvirt_sarray_ptr; { virtual array, or NIL if one-pass } + buffer : JSAMPARRAY; { strip buffer, or current strip of virtual } + strip_height : JDIMENSION; { buffer size in rows } + { for two-pass mode only: } + starting_row : JDIMENSION; { row # of first row in current strip } + next_row : JDIMENSION; { index of next row to fill/empty in strip } + end; + +{ Forward declarations } +{METHODDEF} +procedure post_process_1pass(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; +{$ifdef QUANT_2PASS_SUPPORTED} +{METHODDEF} +procedure post_process_prepass(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; +{METHODDEF} +procedure post_process_2pass(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; +{$endif} + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_dpost (cinfo : j_decompress_ptr; + pass_mode : J_BUF_MODE); +var + post : my_post_ptr; +begin + post := my_post_ptr(cinfo^.post); + + case (pass_mode) of + JBUF_PASS_THRU: + if (cinfo^.quantize_colors) then + begin + { Single-pass processing with color quantization. } + post^.pub.post_process_data := post_process_1pass; + { We could be doing buffered-image output before starting a 2-pass + color quantization; in that case, jinit_d_post_controller did not + allocate a strip buffer. Use the virtual-array buffer as workspace. } + if (post^.buffer = NIL) then + begin + post^.buffer := cinfo^.mem^.access_virt_sarray + (j_common_ptr(cinfo), post^.whole_image, + JDIMENSION(0), post^.strip_height, TRUE); + end; + end + else + begin + { For single-pass processing without color quantization, + I have no work to do; just call the upsampler directly. } + + post^.pub.post_process_data := cinfo^.upsample^.upsample; + end; + +{$ifdef QUANT_2PASS_SUPPORTED} + JBUF_SAVE_AND_PASS: + begin + { First pass of 2-pass quantization } + if (post^.whole_image = NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + post^.pub.post_process_data := post_process_prepass; + end; + JBUF_CRANK_DEST: + begin + { Second pass of 2-pass quantization } + if (post^.whole_image = NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + post^.pub.post_process_data := post_process_2pass; + end; +{$endif} { QUANT_2PASS_SUPPORTED } + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + end; + post^.next_row := 0; + post^.starting_row := 0; +end; + + +{ Process some data in the one-pass (strip buffer) case. + This is used for color precision reduction as well as one-pass quantization. } + +{METHODDEF} +procedure post_process_1pass (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + post : my_post_ptr; + num_rows, max_rows : JDIMENSION; +begin + post := my_post_ptr (cinfo^.post); + + { Fill the buffer, but not more than what we can dump out in one go. } + { Note we rely on the upsampler to detect bottom of image. } + max_rows := out_rows_avail - out_row_ctr; + if (max_rows > post^.strip_height) then + max_rows := post^.strip_height; + num_rows := 0; + cinfo^.upsample^.upsample (cinfo, + input_buf, + in_row_group_ctr, + in_row_groups_avail, + post^.buffer, + num_rows, { var } + max_rows); + { Quantize and emit data. } + + cinfo^.cquantize^.color_quantize (cinfo, + post^.buffer, + JSAMPARRAY(@ output_buf^[out_row_ctr]), + int(num_rows)); + + Inc(out_row_ctr, num_rows); +end; + + +{$ifdef QUANT_2PASS_SUPPORTED} + +{ Process some data in the first pass of 2-pass quantization. } + +{METHODDEF} +procedure post_process_prepass (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail:JDIMENSION); +var + post : my_post_ptr; + old_next_row, num_rows : JDIMENSION; +begin + post := my_post_ptr(cinfo^.post); + + { Reposition virtual buffer if at start of strip. } + if (post^.next_row = 0) then + begin + post^.buffer := cinfo^.mem^.access_virt_sarray + (j_common_ptr(cinfo), post^.whole_image, + post^.starting_row, post^.strip_height, TRUE); + end; + + { Upsample some data (up to a strip height's worth). } + old_next_row := post^.next_row; + cinfo^.upsample^.upsample (cinfo, + input_buf, in_row_group_ctr, in_row_groups_avail, + post^.buffer, post^.next_row, post^.strip_height); + + { Allow quantizer to scan new data. No data is emitted, } + { but we advance out_row_ctr so outer loop can tell when we're done. } + if (post^.next_row > old_next_row) then + begin + num_rows := post^.next_row - old_next_row; + + + cinfo^.cquantize^.color_quantize (cinfo, + JSAMPARRAY(@ post^.buffer^[old_next_row]), + JSAMPARRAY(NIL), + int(num_rows)); + Inc(out_row_ctr, num_rows); + end; + + { Advance if we filled the strip. } + if (post^.next_row >= post^.strip_height) then + begin + Inc(post^.starting_row, post^.strip_height); + post^.next_row := 0; + end; +end; + + +{ Process some data in the second pass of 2-pass quantization. } + +{METHODDEF} +procedure post_process_2pass (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + post : my_post_ptr; + num_rows, max_rows : JDIMENSION; +begin + post := my_post_ptr(cinfo^.post); + + { Reposition virtual buffer if at start of strip. } + if (post^.next_row = 0) then + begin + post^.buffer := cinfo^.mem^.access_virt_sarray + (j_common_ptr(cinfo), post^.whole_image, + post^.starting_row, post^.strip_height, FALSE); + end; + + { Determine number of rows to emit. } + num_rows := post^.strip_height - post^.next_row; { available in strip } + max_rows := out_rows_avail - out_row_ctr; { available in output area } + if (num_rows > max_rows) then + num_rows := max_rows; + { We have to check bottom of image here, can't depend on upsampler. } + max_rows := cinfo^.output_height - post^.starting_row; + if (num_rows > max_rows) then + num_rows := max_rows; + + { Quantize and emit data. } + cinfo^.cquantize^.color_quantize (cinfo, + JSAMPARRAY(@ post^.buffer^[post^.next_row]), + JSAMPARRAY(@ output_buf^[out_row_ctr]), + int(num_rows)); + Inc(out_row_ctr, num_rows); + + { Advance if we filled the strip. } + Inc(post^.next_row, num_rows); + if (post^.next_row >= post^.strip_height) then + begin + Inc(post^.starting_row, post^.strip_height); + post^.next_row := 0; + end; +end; + +{$endif} { QUANT_2PASS_SUPPORTED } + + +{ Initialize postprocessing controller. } + +{GLOBAL} +procedure jinit_d_post_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); +var + post : my_post_ptr; +begin + post := my_post_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_post_controller)) ); + cinfo^.post := jpeg_d_post_controller_ptr (post); + post^.pub.start_pass := start_pass_dpost; + post^.whole_image := NIL; { flag for no virtual arrays } + post^.buffer := NIL; { flag for no strip buffer } + + { Create the quantization buffer, if needed } + if (cinfo^.quantize_colors) then + begin + { The buffer strip height is max_v_samp_factor, which is typically + an efficient number of rows for upsampling to return. + (In the presence of output rescaling, we might want to be smarter?) } + + post^.strip_height := JDIMENSION (cinfo^.max_v_samp_factor); + if (need_full_buffer) then + begin + { Two-pass color quantization: need full-image storage. } + { We round up the number of rows to a multiple of the strip height. } +{$ifdef QUANT_2PASS_SUPPORTED} + post^.whole_image := cinfo^.mem^.request_virt_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, FALSE, + cinfo^.output_width * cinfo^.out_color_components, + JDIMENSION (jround_up( long(cinfo^.output_height), + long(post^.strip_height)) ), + post^.strip_height); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); +{$endif} { QUANT_2PASS_SUPPORTED } + end + else + begin + { One-pass color quantization: just make a strip buffer. } + post^.buffer := cinfo^.mem^.alloc_sarray + (j_common_ptr (cinfo), JPOOL_IMAGE, + cinfo^.output_width * cinfo^.out_color_components, + post^.strip_height); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdsample_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdsample_del.pas new file mode 100644 index 0000000..f6bbc6b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdsample_del.pas @@ -0,0 +1,593 @@ +unit jdsample_del; + +{ Original: jdsample.c; Copyright (C) 1991-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +{ This file contains upsampling routines. + + Upsampling input data is counted in "row groups". A row group + is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + sample rows of each component. Upsampling will normally produce + max_v_samp_factor pixel rows from each row group (but this could vary + if the upsampler is applying a scale factor of its own). + + An excellent reference for image resampling is + Digital Image Warping, George Wolberg, 1990. + Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.} + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jutils_del, + jpeglib_del, + jdeferr_del, + jerror_del; + + +{ Pointer to routine to upsample a single component } +type + upsample1_ptr = procedure (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); + +{ Module initialization routine for upsampling. } + +{GLOBAL} +procedure jinit_upsampler (cinfo : j_decompress_ptr); + +implementation + +{ Private subobject } + +type + my_upsample_ptr = ^my_upsampler; + my_upsampler = record + pub : jpeg_upsampler; { public fields } + + { Color conversion buffer. When using separate upsampling and color + conversion steps, this buffer holds one upsampled row group until it + has been color converted and output. + Note: we do not allocate any storage for component(s) which are full-size, + ie do not need rescaling. The corresponding entry of color_buf[] is + simply set to point to the input data array, thereby avoiding copying.} + + color_buf : array[0..MAX_COMPONENTS-1] of JSAMPARRAY; + + { Per-component upsampling method pointers } + methods : array[0..MAX_COMPONENTS-1] of upsample1_ptr; + + next_row_out : int; { counts rows emitted from color_buf } + rows_to_go : JDIMENSION; { counts rows remaining in image } + + { Height of an input row group for each component. } + rowgroup_height : array[0..MAX_COMPONENTS-1] of int; + + { These arrays save pixel expansion factors so that int_expand need not + recompute them each time. They are unused for other upsampling methods.} + h_expand : array[0..MAX_COMPONENTS-1] of UINT8 ; + v_expand : array[0..MAX_COMPONENTS-1] of UINT8 ; + end; + + +{ Initialize for an upsampling pass. } + +{METHODDEF} +procedure start_pass_upsample (cinfo : j_decompress_ptr); +var + upsample : my_upsample_ptr; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + { Mark the conversion buffer empty } + upsample^.next_row_out := cinfo^.max_v_samp_factor; + { Initialize total-height counter for detecting bottom of image } + upsample^.rows_to_go := cinfo^.output_height; +end; + + +{ Control routine to do upsampling (and color conversion). + + In this version we upsample each component independently. + We upsample one row group into the conversion buffer, then apply + color conversion a row at a time. } + +{METHODDEF} +procedure sep_upsample (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + upsample : my_upsample_ptr; + ci : int; + compptr : jpeg_component_info_ptr; + num_rows : JDIMENSION; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + { Fill the conversion buffer, if it's empty } + if (upsample^.next_row_out >= cinfo^.max_v_samp_factor) then + begin + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Invoke per-component upsample method. Notice we pass a POINTER + to color_buf[ci], so that fullsize_upsample can change it. } + + upsample^.methods[ci] (cinfo, compptr, + JSAMPARRAY(@ input_buf^[ci]^ + [in_row_group_ctr * upsample^.rowgroup_height[ci]]), + upsample^.color_buf[ci]); + + Inc(compptr); + end; + upsample^.next_row_out := 0; + end; + + { Color-convert and emit rows } + + { How many we have in the buffer: } + num_rows := JDIMENSION (cinfo^.max_v_samp_factor - upsample^.next_row_out); + { Not more than the distance to the end of the image. Need this test + in case the image height is not a multiple of max_v_samp_factor: } + + if (num_rows > upsample^.rows_to_go) then + num_rows := upsample^.rows_to_go; + { And not more than what the client can accept: } + Dec(out_rows_avail, out_row_ctr); + if (num_rows > out_rows_avail) then + num_rows := out_rows_avail; + + cinfo^.cconvert^.color_convert (cinfo, + JSAMPIMAGE(@(upsample^.color_buf)), + JDIMENSION (upsample^.next_row_out), + JSAMPARRAY(@(output_buf^[out_row_ctr])), + int (num_rows)); + + { Adjust counts } + Inc(out_row_ctr, num_rows); + Dec(upsample^.rows_to_go, num_rows); + Inc(upsample^.next_row_out, num_rows); + { When the buffer is emptied, declare this input row group consumed } + if (upsample^.next_row_out >= cinfo^.max_v_samp_factor) then + Inc(in_row_group_ctr); +end; + + +{ These are the routines invoked by sep_upsample to upsample pixel values + of a single component. One row group is processed per call. } + + +{ For full-size components, we just make color_buf[ci] point at the + input buffer, and thus avoid copying any data. Note that this is + safe only because sep_upsample doesn't declare the input row group + "consumed" until we are done color converting and emitting it. } + +{METHODDEF} +procedure fullsize_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +begin + output_data_ptr := input_data; +end; + + +{ This is a no-op version used for "uninteresting" components. + These components will not be referenced by color conversion. } + +{METHODDEF} +procedure noop_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +begin + output_data_ptr := NIL; { safety check } +end; + + +{ This version handles any integral sampling ratios. + This is not used for typical JPEG files, so it need not be fast. + Nor, for that matter, is it particularly accurate: the algorithm is + simple replication of the input pixel onto the corresponding output + pixels. The hi-falutin sampling literature refers to this as a + "box filter". A box filter tends to introduce visible artifacts, + so if you are actually going to use 3:1 or 4:1 sampling ratios + you would be well advised to improve this code. } + +{METHODDEF} +procedure int_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +var + upsample : my_upsample_ptr; + output_data : JSAMPARRAY; + {register} inptr, outptr : JSAMPLE_PTR; + {register} invalue : JSAMPLE; + {register} h : int; + {outend} + h_expand, v_expand : int; + inrow, outrow : int; +var + outcount : int; { Nomssi: avoid pointer arithmetic } +begin + upsample := my_upsample_ptr (cinfo^.upsample); + output_data := output_data_ptr; + + h_expand := upsample^.h_expand[compptr^.component_index]; + v_expand := upsample^.v_expand[compptr^.component_index]; + + inrow := 0; + outrow := 0; + while (outrow < cinfo^.max_v_samp_factor) do + begin + { Generate one output row with proper horizontal expansion } + inptr := JSAMPLE_PTR(input_data^[inrow]); + outptr := JSAMPLE_PTR(output_data^[outrow]); + outcount := cinfo^.output_width; + while (outcount > 0) do { Nomssi } + begin + invalue := inptr^; { don't need GETJSAMPLE() here } + Inc(inptr); + for h := pred(h_expand) downto 0 do + begin + outptr^ := invalue; + inc(outptr); { <-- fix: this was left out in PasJpeg 1.0 } + Dec(outcount); { thanks to Jannie Gerber for the report } + end; + end; + + { Generate any additional output rows by duplicating the first one } + if (v_expand > 1) then + begin + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + v_expand-1, cinfo^.output_width); + end; + Inc(inrow); + Inc(outrow, v_expand); + end; +end; + + +{ Fast processing for the common case of 2:1 horizontal and 1:1 vertical. + It's still a box filter. } + +{METHODDEF} +procedure h2v1_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +var + output_data : JSAMPARRAY; + {register} inptr, outptr : JSAMPLE_PTR; + {register} invalue : JSAMPLE; + {outend : JSAMPROW;} + outcount : int; + inrow : int; +begin + output_data := output_data_ptr; + + for inrow := 0 to pred(cinfo^.max_v_samp_factor) do + begin + inptr := JSAMPLE_PTR(input_data^[inrow]); + outptr := JSAMPLE_PTR(output_data^[inrow]); + {outend := outptr + cinfo^.output_width;} + outcount := cinfo^.output_width; + while (outcount > 0) do + begin + invalue := inptr^; { don't need GETJSAMPLE() here } + Inc(inptr); + outptr^ := invalue; + Inc(outptr); + outptr^ := invalue; + Inc(outptr); + Dec(outcount, 2); { Nomssi: to avoid pointer arithmetic } + end; + end; +end; + + +{ Fast processing for the common case of 2:1 horizontal and 2:1 vertical. + It's still a box filter. } + +{METHODDEF} +procedure h2v2_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +var + output_data : JSAMPARRAY; + {register} inptr, outptr : JSAMPLE_PTR; + {register} invalue : JSAMPLE; + {outend : JSAMPROW;} + outcount : int; + inrow, outrow : int; +begin + output_data := output_data_ptr; + + inrow := 0; + outrow := 0; + while (outrow < cinfo^.max_v_samp_factor) do + begin + inptr := JSAMPLE_PTR(input_data^[inrow]); + outptr := JSAMPLE_PTR(output_data^[outrow]); + {outend := outptr + cinfo^.output_width;} + outcount := cinfo^.output_width; + while (outcount > 0) do + begin + invalue := inptr^; { don't need GETJSAMPLE() here } + Inc(inptr); + outptr^ := invalue; + Inc(outptr); + outptr^ := invalue; + Inc(outptr); + Dec(outcount, 2); + end; + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + 1, cinfo^.output_width); + Inc(inrow); + Inc(outrow, 2); + end; +end; + + +{ Fancy processing for the common case of 2:1 horizontal and 1:1 vertical. + + The upsampling algorithm is linear interpolation between pixel centers, + also known as a "triangle filter". This is a good compromise between + speed and visual quality. The centers of the output pixels are 1/4 and 3/4 + of the way between input pixel centers. + + A note about the "bias" calculations: when rounding fractional values to + integer, we do not want to always round 0.5 up to the next integer. + If we did that, we'd introduce a noticeable bias towards larger values. + Instead, this code is arranged so that 0.5 will be rounded up or down at + alternate pixel locations (a simple ordered dither pattern). } + +{METHODDEF} +procedure h2v1_fancy_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +var + output_data : JSAMPARRAY; + {register} pre_inptr, inptr, outptr : JSAMPLE_PTR; + {register} invalue : int; + {register} colctr : JDIMENSION; + inrow : int; +begin + output_data := output_data_ptr; + + for inrow := 0 to pred(cinfo^.max_v_samp_factor) do + begin + inptr := JSAMPLE_PTR(input_data^[inrow]); + outptr := JSAMPLE_PTR(output_data^[inrow]); + { Special case for first column } + pre_inptr := inptr; + invalue := GETJSAMPLE(inptr^); + Inc(inptr); + outptr^ := JSAMPLE (invalue); + Inc(outptr); + outptr^ := JSAMPLE ((invalue * 3 + GETJSAMPLE(inptr^) + 2) shr 2); + Inc(outptr); + + for colctr := pred(compptr^.downsampled_width - 2) downto 0 do + begin + { General case: 3/4 * nearer pixel + 1/4 * further pixel } + invalue := GETJSAMPLE(inptr^) * 3; + Inc(inptr); + outptr^ := JSAMPLE ((invalue + GETJSAMPLE(pre_inptr^) + 1) shr 2); + Inc(pre_inptr); + Inc(outptr); + outptr^ := JSAMPLE ((invalue + GETJSAMPLE(inptr^) + 2) shr 2); + Inc(outptr); + end; + + { Special case for last column } + invalue := GETJSAMPLE(inptr^); + outptr^ := JSAMPLE ((invalue * 3 + GETJSAMPLE(pre_inptr^) + 1) shr 2); + Inc(outptr); + outptr^ := JSAMPLE (invalue); + {Inc(outptr); - value never used } + end; +end; + + +{ Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. + Again a triangle filter; see comments for h2v1 case, above. + + It is OK for us to reference the adjacent input rows because we demanded + context from the main buffer controller (see initialization code). } + +{METHODDEF} +procedure h2v2_fancy_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +var + output_data : JSAMPARRAY; + {register} inptr0, inptr1, outptr : JSAMPLE_PTR; +{$ifdef BITS_IN_JSAMPLE_IS_8} + {register} thiscolsum, lastcolsum, nextcolsum : int; +{$else} + {register} thiscolsum, lastcolsum, nextcolsum : INT32; +{$endif} + {register} colctr : JDIMENSION; + inrow, outrow, v : int; +var + prev_input_data : JSAMPARRAY; { Nomssi work around } +begin + output_data := output_data_ptr; + + outrow := 0; + inrow := 0; + while (outrow < cinfo^.max_v_samp_factor) do + begin + for v := 0 to pred(2) do + begin + { inptr0 points to nearest input row, inptr1 points to next nearest } + inptr0 := JSAMPLE_PTR(input_data^[inrow]); + if (v = 0) then { next nearest is row above } + begin + {inptr1 := JSAMPLE_PTR(input_data^[inrow-1]);} + prev_input_data := input_data; { work around } + Dec(JSAMPROW_PTR(prev_input_data)); { negative offsets } + inptr1 := JSAMPLE_PTR(prev_input_data^[inrow]); + end + else { next nearest is row below } + inptr1 := JSAMPLE_PTR(input_data^[inrow+1]); + outptr := JSAMPLE_PTR(output_data^[outrow]); + Inc(outrow); + + { Special case for first column } + thiscolsum := GETJSAMPLE(inptr0^) * 3 + GETJSAMPLE(inptr1^); + Inc(inptr0); + Inc(inptr1); + nextcolsum := GETJSAMPLE(inptr0^) * 3 + GETJSAMPLE(inptr1^); + Inc(inptr0); + Inc(inptr1); + + outptr^ := JSAMPLE ((thiscolsum * 4 + 8) shr 4); + Inc(outptr); + outptr^ := JSAMPLE ((thiscolsum * 3 + nextcolsum + 7) shr 4); + Inc(outptr); + lastcolsum := thiscolsum; thiscolsum := nextcolsum; + + for colctr := pred(compptr^.downsampled_width - 2) downto 0 do + begin + { General case: 3/4 * nearer pixel + 1/4 * further pixel in each } + { dimension, thus 9/16, 3/16, 3/16, 1/16 overall } + nextcolsum := GETJSAMPLE(inptr0^) * 3 + GETJSAMPLE(inptr1^); + Inc(inptr0); + Inc(inptr1); + outptr^ := JSAMPLE ((thiscolsum * 3 + lastcolsum + 8) shr 4); + Inc(outptr); + outptr^ := JSAMPLE ((thiscolsum * 3 + nextcolsum + 7) shr 4); + Inc(outptr); + lastcolsum := thiscolsum; + thiscolsum := nextcolsum; + end; + + { Special case for last column } + outptr^ := JSAMPLE ((thiscolsum * 3 + lastcolsum + 8) shr 4); + Inc(outptr); + outptr^ := JSAMPLE ((thiscolsum * 4 + 7) shr 4); + {Inc(outptr); - value never used } + end; + Inc(inrow); + end; +end; + + +{ Module initialization routine for upsampling. } + +{GLOBAL} +procedure jinit_upsampler (cinfo : j_decompress_ptr); +var + upsample : my_upsample_ptr; + ci : int; + compptr : jpeg_component_info_ptr; + need_buffer, do_fancy : boolean; + h_in_group, v_in_group, h_out_group, v_out_group : int; +begin + upsample := my_upsample_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_upsampler)) ); + cinfo^.upsample := jpeg_upsampler_ptr (upsample); + upsample^.pub.start_pass := start_pass_upsample; + upsample^.pub.upsample := sep_upsample; + upsample^.pub.need_context_rows := FALSE; { until we find out differently } + + if (cinfo^.CCIR601_sampling) then { this isn't supported } + ERREXIT(j_common_ptr(cinfo), JERR_CCIR601_NOTIMPL); + + { jdmainct.c doesn't support context rows when min_DCT_scaled_size := 1, + so don't ask for it. } + + do_fancy := cinfo^.do_fancy_upsampling and (cinfo^.min_DCT_scaled_size > 1); + + { Verify we can handle the sampling factors, select per-component methods, + and create storage as needed. } + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Compute size of an "input group" after IDCT scaling. This many samples + are to be converted to max_h_samp_factor * max_v_samp_factor pixels. } + + h_in_group := (compptr^.h_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; + v_in_group := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; + h_out_group := cinfo^.max_h_samp_factor; + v_out_group := cinfo^.max_v_samp_factor; + upsample^.rowgroup_height[ci] := v_in_group; { save for use later } + need_buffer := TRUE; + if (not compptr^.component_needed) then + begin + { Don't bother to upsample an uninteresting component. } + upsample^.methods[ci] := noop_upsample; + need_buffer := FALSE; + end + else + if (h_in_group = h_out_group) and (v_in_group = v_out_group) then + begin + { Fullsize components can be processed without any work. } + upsample^.methods[ci] := fullsize_upsample; + need_buffer := FALSE; + end + else + if (h_in_group * 2 = h_out_group) and + (v_in_group = v_out_group) then + begin + { Special cases for 2h1v upsampling } + if (do_fancy) and (compptr^.downsampled_width > 2) then + upsample^.methods[ci] := h2v1_fancy_upsample + else + upsample^.methods[ci] := h2v1_upsample; + end + else + if (h_in_group * 2 = h_out_group) and + (v_in_group * 2 = v_out_group) then + begin + { Special cases for 2h2v upsampling } + if (do_fancy) and (compptr^.downsampled_width > 2) then + begin + upsample^.methods[ci] := h2v2_fancy_upsample; + upsample^.pub.need_context_rows := TRUE; + end + else + upsample^.methods[ci] := h2v2_upsample; + end + else + if ((h_out_group mod h_in_group) = 0) and + ((v_out_group mod v_in_group) = 0) then + begin + { Generic integral-factors upsampling method } + upsample^.methods[ci] := int_upsample; + upsample^.h_expand[ci] := UINT8 (h_out_group div h_in_group); + upsample^.v_expand[ci] := UINT8 (v_out_group div v_in_group); + end + else + ERREXIT(j_common_ptr(cinfo), JERR_FRACT_SAMPLE_NOTIMPL); + if (need_buffer) then + begin + upsample^.color_buf[ci] := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + JDIMENSION (jround_up( long (cinfo^.output_width), + long (cinfo^.max_h_samp_factor))), + JDIMENSION (cinfo^.max_v_samp_factor)); + end; + Inc(compptr); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdtrans_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdtrans_del.pas new file mode 100644 index 0000000..a265257 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdtrans_del.pas @@ -0,0 +1,192 @@ +Unit JdTrans; + +{ This file contains library routines for transcoding decompression, + that is, reading raw DCT coefficient arrays from an input JPEG file. + The routines in jdapimin.c will also be needed by a transcoder. } + +{ Original : jdtrans.c ; Copyright (C) 1995-1997, Thomas G. Lane. } + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg, + jinclude, + jdeferr, + jerror, + jpeglib, + jdhuff, jdphuff, jdcoefct; + +{ Read the coefficient arrays from a JPEG file. + jpeg_read_header must be completed before calling this. + + The entire image is read into a set of virtual coefficient-block arrays, + one per component. The return value is a pointer to the array of + virtual-array descriptors. These can be manipulated directly via the + JPEG memory manager, or handed off to jpeg_write_coefficients(). + To release the memory occupied by the virtual arrays, call + jpeg_finish_decompress() when done with the data. + + An alternative usage is to simply obtain access to the coefficient arrays + during a buffered-image-mode decompression operation. This is allowed + after any jpeg_finish_output() call. The arrays can be accessed until + jpeg_finish_decompress() is called. (Note that any call to the library + may reposition the arrays, so don't rely on access_virt_barray() results + to stay valid across library calls.) + + Returns NIL if suspended. This case need be checked only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_read_coefficients + (cinfo : j_decompress_ptr) : jvirt_barray_tbl_ptr; + +implementation + + +{ Forward declarations } +{LOCAL} +procedure transdecode_master_selection (cinfo : j_decompress_ptr); forward; + + +{ Read the coefficient arrays from a JPEG file. + jpeg_read_header must be completed before calling this. + + The entire image is read into a set of virtual coefficient-block arrays, + one per component. The return value is a pointer to the array of + virtual-array descriptors. These can be manipulated directly via the + JPEG memory manager, or handed off to jpeg_write_coefficients(). + To release the memory occupied by the virtual arrays, call + jpeg_finish_decompress() when done with the data. + + Returns NIL if suspended. This case need be checked only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_read_coefficients + (cinfo : j_decompress_ptr) : jvirt_barray_tbl_ptr; +var + retcode : int; +begin + if (cinfo^.global_state = DSTATE_READY) then + begin + { First call: initialize active modules } + transdecode_master_selection(cinfo); + cinfo^.global_state := DSTATE_RDCOEFS; + end; + + if (cinfo^.global_state = DSTATE_RDCOEFS) then + begin + { Absorb whole file into the coef buffer } + while TRUE do + begin + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + { Absorb some more input } + retcode := cinfo^.inputctl^.consume_input (cinfo); + if (retcode = JPEG_SUSPENDED) then + begin + jpeg_read_coefficients := NIL; + exit; + end; + if (retcode = JPEG_REACHED_EOI) then + break; + { Advance progress counter if appropriate } + if (cinfo^.progress <> NIL) and + ((retcode = JPEG_ROW_COMPLETED) or (retcode = JPEG_REACHED_SOS)) then + begin + Inc(cinfo^.progress^.pass_counter); + if (cinfo^.progress^.pass_counter >= cinfo^.progress^.pass_limit) then + begin + { startup underestimated number of scans; ratchet up one scan } + Inc(cinfo^.progress^.pass_limit, long(cinfo^.total_iMCU_rows)); + end; + end; + end; + { Set state so that jpeg_finish_decompress does the right thing } + cinfo^.global_state := DSTATE_STOPPING; + end; + { At this point we should be in state DSTATE_STOPPING if being used + standalone, or in state DSTATE_BUFIMAGE if being invoked to get access + to the coefficients during a full buffered-image-mode decompression. } + + if ((cinfo^.global_state = DSTATE_STOPPING) or + (cinfo^.global_state = DSTATE_BUFIMAGE)) and (cinfo^.buffered_image) then + begin + jpeg_read_coefficients := cinfo^.coef^.coef_arrays; + exit; + end; + { Oops, improper usage } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + jpeg_read_coefficients := NIL; { keep compiler happy } +end; + + +{ Master selection of decompression modules for transcoding. + This substitutes for jdmaster.c's initialization of the full decompressor. } + +{LOCAL} +procedure transdecode_master_selection (cinfo : j_decompress_ptr); +var + nscans : int; +begin + { This is effectively a buffered-image operation. } + cinfo^.buffered_image := TRUE; + + { Entropy decoding: either Huffman or arithmetic coding. } + if (cinfo^.arith_code) then + begin + ERREXIT(j_common_ptr(cinfo), JERR_ARITH_NOTIMPL); + end + else + begin + if (cinfo^.progressive_mode) then + begin +{$ifdef D_PROGRESSIVE_SUPPORTED} + jinit_phuff_decoder(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + jinit_huff_decoder(cinfo); + end; + + { Always get a full-image coefficient buffer. } + jinit_d_coef_controller(cinfo, TRUE); + + { We can now tell the memory manager to allocate virtual arrays. } + cinfo^.mem^.realize_virt_arrays (j_common_ptr(cinfo)); + + { Initialize input side of decompressor to consume first scan. } + cinfo^.inputctl^.start_input_pass (cinfo); + + { Initialize progress monitoring. } + if (cinfo^.progress <> NIL) then + begin + { Estimate number of scans to set pass_limit. } + if (cinfo^.progressive_mode) then + begin + { Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. } + nscans := 2 + 3 * cinfo^.num_components; + end + else + if (cinfo^.inputctl^.has_multiple_scans) then + begin + { For a nonprogressive multiscan file, estimate 1 scan per component. } + nscans := cinfo^.num_components; + end + else + begin + nscans := 1; + end; + cinfo^.progress^.pass_counter := long(0); + cinfo^.progress^.pass_limit := long(cinfo^.total_iMCU_rows * nscans); + cinfo^.progress^.completed_passes := 0; + cinfo^.progress^.total_passes := 1; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jerror_del.pas b/mseide-msegui/lib/common/fpccompatibility/jerror_del.pas new file mode 100644 index 0000000..4715ea4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jerror_del.pas @@ -0,0 +1,463 @@ +unit jerror_del; + +{ This file contains simple error-reporting and trace-message routines. + These are suitable for Unix-like systems and others where writing to + stderr is the right thing to do. Many applications will want to replace + some or all of these routines. + + These routines are used by both the compression and decompression code. } + +{ Source: jerror.c; Copyright (C) 1991-1996, Thomas G. Lane. } +{ note: format_message still contains a hack } +//modified 2013 by Martin Schreiber + +{$i jconfig_del.inc} +interface + +uses + jmorecfg_del, + jdeferr_del, + jpeglib_del; +{ + jversion; +} + +const + EXIT_FAILURE = 1; { define halt() codes if not provided } + +{GLOBAL} +function jpeg_std_error (var err : jpeg_error_mgr) : jpeg_error_mgr_ptr; + + + +procedure ERREXIT(cinfo : j_common_ptr; code : J_MESSAGE_CODE); + +procedure ERREXIT1(cinfo : j_common_ptr; code : J_MESSAGE_CODE; p1 : uInt); + +procedure ERREXIT2(cinfo : j_common_ptr; code : J_MESSAGE_CODE; p1 : int; p2 : int); + +procedure ERREXIT3(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int); + +procedure ERREXIT4(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int); + +procedure ERREXITS(cinfo : j_common_ptr;code : J_MESSAGE_CODE; + str : string); +{ Nonfatal errors (we can keep going, but the data is probably corrupt) } + +procedure WARNMS(cinfo : j_common_ptr; code : J_MESSAGE_CODE); + +procedure WARNMS1(cinfo : j_common_ptr;code : J_MESSAGE_CODE; p1 : int); + +procedure WARNMS2(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int); + +{ Informational/debugging messages } +procedure TRACEMS(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE); + +procedure TRACEMS1(cinfo : j_common_ptr; lvl : int; + code : J_MESSAGE_CODE; p1 : long); + +procedure TRACEMS2(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; + p2 : int); + +procedure TRACEMS3(cinfo : j_common_ptr; + lvl : int; + code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int); + +procedure TRACEMS4(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int); + +procedure TRACEMS5(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int; p5 : int); + +procedure TRACEMS8(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int; + p5 : int; p6 : int; p7 : int; p8 : int); + +procedure TRACEMSS(cinfo : j_common_ptr; lvl : int; + code : J_MESSAGE_CODE; str : string); + +implementation + + +{ How to format a message string, in format_message() ? } + +{$IFDEF OS2} + {$DEFINE NO_FORMAT} +{$ENDIF} +{$IFDEF FPC} + {.$DEFINE NO_FORMAT} +{$ENDIF} + +uses +{$IFNDEF NO_FORMAT} + {$IFDEF VER70} + drivers, { Turbo Vision unit with FormatStr } + {$ELSE} + sysutils, { Delphi Unit with Format() } + {$ENDIF} +{$ENDIF} + jcomapi_del; + +{ Error exit handler: must not return to caller. + + Applications may override this if they want to get control back after + an error. Typically one would longjmp somewhere instead of exiting. + The setjmp buffer can be made a private field within an expanded error + handler object. Note that the info needed to generate an error message + is stored in the error object, so you can generate the message now or + later, at your convenience. + You should make sure that the JPEG object is cleaned up (with jpeg_abort + or jpeg_destroy) at some point. } + + +{METHODDEF} +procedure error_exit (cinfo : j_common_ptr); +begin + { Always display the message } + cinfo^.err^.output_message(cinfo); + + { Let the memory manager delete any temp files before we die } + jpeg_destroy(cinfo); + + halt(EXIT_FAILURE); +end; + + +{ Actual output of an error or trace message. + Applications may override this method to send JPEG messages somewhere + other than stderr. } + +{ Macros to simplify using the error and trace message stuff } +{ The first parameter is either type of cinfo pointer } + +{ Fatal errors (print message and exit) } +procedure ERREXIT(cinfo : j_common_ptr; code : J_MESSAGE_CODE); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.error_exit(cinfo); +end; + +procedure ERREXIT1(cinfo : j_common_ptr; code : J_MESSAGE_CODE; p1 : uInt); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.error_exit (cinfo); +end; + +procedure ERREXIT2(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.msg_parm.i[1] := p2; + cinfo^.err^.error_exit (cinfo); +end; + +procedure ERREXIT3(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.msg_parm.i[1] := p2; + cinfo^.err^.msg_parm.i[2] := p3; + cinfo^.err^.error_exit (cinfo); +end; + +procedure ERREXIT4(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.msg_parm.i[1] := p2; + cinfo^.err^.msg_parm.i[2] := p3; + cinfo^.err^.msg_parm.i[3] := p4; + cinfo^.err^.error_exit (cinfo); +end; + +procedure ERREXITS(cinfo : j_common_ptr;code : J_MESSAGE_CODE; + str : string); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.s := str; { string[JMSG_STR_PARM_MAX] } + cinfo^.err^.error_exit (cinfo); +end; + +{ Nonfatal errors (we can keep going, but the data is probably corrupt) } + +procedure WARNMS(cinfo : j_common_ptr; code : J_MESSAGE_CODE); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message(cinfo, -1); +end; + +procedure WARNMS1(cinfo : j_common_ptr;code : J_MESSAGE_CODE; p1 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.emit_message (cinfo, -1); +end; + +procedure WARNMS2(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.msg_parm.i[1] := p2; + cinfo^.err^.emit_message (cinfo, -1); +end; + +{ Informational/debugging messages } +procedure TRACEMS(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message(cinfo, lvl); +end; + +procedure TRACEMS1(cinfo : j_common_ptr; lvl : int; + code : J_MESSAGE_CODE; p1 : long); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.emit_message (cinfo, lvl); +end; + +procedure TRACEMS2(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; + p2 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.msg_parm.i[1] := p2; + cinfo^.err^.emit_message (cinfo, lvl); +end; + +procedure TRACEMS3(cinfo : j_common_ptr; + lvl : int; + code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int); +var + _mp : int8array; +begin + _mp[0] := p1; _mp[1] := p2; _mp[2] := p3; + cinfo^.err^.msg_parm.i := _mp; + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message (cinfo, lvl); +end; + + +procedure TRACEMS4(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int); +var + _mp : int8array; +begin + _mp[0] := p1; _mp[1] := p2; _mp[2] := p3; _mp[3] := p4; + cinfo^.err^.msg_parm.i := _mp; + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message (cinfo, lvl); +end; + +procedure TRACEMS5(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int; p5 : int); +var + _mp : ^int8array; +begin + _mp := @cinfo^.err^.msg_parm.i; + _mp^[0] := p1; _mp^[1] := p2; _mp^[2] := p3; + _mp^[3] := p4; _mp^[5] := p5; + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message (cinfo, lvl); +end; + +procedure TRACEMS8(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int; + p5 : int; p6 : int; p7 : int; p8 : int); +var + _mp : int8array; +begin + _mp[0] := p1; _mp[1] := p2; _mp[2] := p3; _mp[3] := p4; + _mp[4] := p5; _mp[5] := p6; _mp[6] := p7; _mp[7] := p8; + cinfo^.err^.msg_parm.i := _mp; + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message (cinfo, lvl); +end; + +procedure TRACEMSS(cinfo : j_common_ptr; lvl : int; + code : J_MESSAGE_CODE; str : string); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.s := str; { string JMSG_STR_PARM_MAX } + cinfo^.err^.emit_message (cinfo, lvl); +end; + +{METHODDEF} +procedure output_message (cinfo : j_common_ptr); +var + buffer : string; {[JMSG_LENGTH_MAX];} +begin + { Create the message } + cinfo^.err^.format_message (cinfo, buffer); + + { Send it to stderr, adding a newline } + WriteLn(output, buffer); +end; + + + +{ Decide whether to emit a trace or warning message. + msg_level is one of: + -1: recoverable corrupt-data warning, may want to abort. + 0: important advisory messages (always display to user). + 1: first level of tracing detail. + 2,3,...: successively more detailed tracing messages. + An application might override this method if it wanted to abort on warnings + or change the policy about which messages to display. } + + +{METHODDEF} +procedure emit_message (cinfo : j_common_ptr; msg_level : int); +var + err : jpeg_error_mgr_ptr; +begin + err := cinfo^.err; + if (msg_level < 0) then + begin + { It's a warning message. Since corrupt files may generate many warnings, + the policy implemented here is to show only the first warning, + unless trace_level >= 3. } + + if (err^.num_warnings = 0) or (err^.trace_level >= 3) then + err^.output_message(cinfo); + { Always count warnings in num_warnings. } + Inc( err^.num_warnings ); + end + else + begin + { It's a trace message. Show it if trace_level >= msg_level. } + if (err^.trace_level >= msg_level) then + err^.output_message (cinfo); + end; +end; + + +{ Format a message string for the most recent JPEG error or message. + The message is stored into buffer, which should be at least JMSG_LENGTH_MAX + characters. Note that no '\n' character is added to the string. + Few applications should need to override this method. } + + +{METHODDEF} +procedure format_message (cinfo : j_common_ptr; var buffer : string); +var + err : jpeg_error_mgr_ptr; + msg_code : J_MESSAGE_CODE; + msgtext : string; + isstring : boolean; +begin + err := cinfo^.err; + msg_code := J_MESSAGE_CODE(err^.msg_code); + msgtext := ''; + + { Look up message string in proper table } + if (msg_code > JMSG_NOMESSAGE) + and (msg_code <= J_MESSAGE_CODE(err^.last_jpeg_message)) then + begin + msgtext := err^.jpeg_message_table^[msg_code]; + end + else + if (err^.addon_message_table <> NIL) and + (msg_code >= err^.first_addon_message) and + (msg_code <= err^.last_addon_message) then + begin + msgtext := err^.addon_message_table^[J_MESSAGE_CODE + (ord(msg_code) - ord(err^.first_addon_message))]; + end; + + { Defend against bogus message number } + if (msgtext = '') then + begin + err^.msg_parm.i[0] := int(msg_code); + msgtext := err^.jpeg_message_table^[JMSG_NOMESSAGE]; + end; + + { Check for string parameter, as indicated by %s in the message text } + isstring := Pos('%s', msgtext) > 0; + + { Format the message into the passed buffer } + if (isstring) then + buffer := Concat(msgtext, err^.msg_parm.s) + else + begin + {$IFDEF VER70} + FormatStr(buffer, msgtext, err^.msg_parm.i); + {$ELSE} + {$IFDEF NO_FORMAT} + buffer := msgtext; + {$ELSE} + buffer := Format(msgtext, [ + err^.msg_parm.i[0], err^.msg_parm.i[1], + err^.msg_parm.i[2], err^.msg_parm.i[3], + err^.msg_parm.i[4], err^.msg_parm.i[5], + err^.msg_parm.i[6], err^.msg_parm.i[7] ]); + {$ENDIF} + {$ENDIF} + end; +end; + + + +{ Reset error state variables at start of a new image. + This is called during compression startup to reset trace/error + processing to default state, without losing any application-specific + method pointers. An application might possibly want to override + this method if it has additional error processing state. } + + +{METHODDEF} +procedure reset_error_mgr (cinfo : j_common_ptr); +begin + cinfo^.err^.num_warnings := 0; + { trace_level is not reset since it is an application-supplied parameter } + cinfo^.err^.msg_code := 0; { may be useful as a flag for "no error" } +end; + + +{ Fill in the standard error-handling methods in a jpeg_error_mgr object. + Typical call is: + cinfo : jpeg_compress_struct; + err : jpeg_error_mgr; + + cinfo.err := jpeg_std_error(@err); + after which the application may override some of the methods. } + + +{GLOBAL} +function jpeg_std_error (var err : jpeg_error_mgr) : jpeg_error_mgr_ptr; +begin + err.error_exit := error_exit; + err.emit_message := emit_message; + err.output_message := output_message; + err.format_message := format_message; + err.reset_error_mgr := reset_error_mgr; + + err.trace_level := 0; { default := no tracing } + err.num_warnings := 0; { no warnings emitted yet } + err.msg_code := 0; { may be useful as a flag for "no error" } + + { Initialize message table pointers } + err.jpeg_message_table := @jpeg_std_message_table; + err.last_jpeg_message := pred(JMSG_LASTMSGCODE); + + err.addon_message_table := NIL; + err.first_addon_message := JMSG_NOMESSAGE; { for safety } + err.last_addon_message := JMSG_NOMESSAGE; + + jpeg_std_error := @err; +end; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jfdctflt_del.pas b/mseide-msegui/lib/common/fpccompatibility/jfdctflt_del.pas new file mode 100644 index 0000000..c1728b4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jfdctflt_del.pas @@ -0,0 +1,178 @@ +Unit jfdctflt_del; + +//{$N+} +{ This file contains a floating-point implementation of the + forward DCT (Discrete Cosine Transform). + + This implementation should be more accurate than either of the integer + DCT implementations. However, it may not give the same results on all + machines because of differences in roundoff behavior. Speed will depend + on the hardware's floating point capacity. + + A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + on each column. Direct algorithms are also available, but they are + much more complex and seem not to be any faster when reduced to code. + + This implementation is based on Arai, Agui, and Nakajima's algorithm for + scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + Japanese, but the algorithm is described in the Pennebaker & Mitchell + JPEG textbook (see REFERENCES section in file README). The following code + is based directly on figure 4-8 in P&M. + While an 8-point DCT cannot be done in less than 11 multiplies, it is + possible to arrange the computation so that many of the multiplies are + simple scalings of the final outputs. These multiplies can then be + folded into the multiplications or divisions by the JPEG quantization + table entries. The AA&N method leaves only 5 multiplies and 29 adds + to be done in the DCT itself. + The primary disadvantage of this method is that with a fixed-point + implementation, accuracy is lost due to imprecise representation of the + scaled quantization values. However, that problem does not arise if + we use floating point arithmetic. } + +{ Original : jfdctflt.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + + +{ Perform the forward DCT on one block of samples.} + +{GLOBAL} +procedure jpeg_fdct_float (var data : array of FAST_FLOAT); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + + +{ Perform the forward DCT on one block of samples.} + +{GLOBAL} +procedure jpeg_fdct_float (var data : array of FAST_FLOAT); +type + PWorkspace = ^TWorkspace; + TWorkspace = array [0..DCTSIZE2-1] of FAST_FLOAT; +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : FAST_FLOAT; + tmp10, tmp11, tmp12, tmp13 : FAST_FLOAT; + z1, z2, z3, z4, z5, z11, z13 : FAST_FLOAT; + dataptr : PWorkspace; + ctr : int; +begin + { Pass 1: process rows. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[0] + dataptr^[7]; + tmp7 := dataptr^[0] - dataptr^[7]; + tmp1 := dataptr^[1] + dataptr^[6]; + tmp6 := dataptr^[1] - dataptr^[6]; + tmp2 := dataptr^[2] + dataptr^[5]; + tmp5 := dataptr^[2] - dataptr^[5]; + tmp3 := dataptr^[3] + dataptr^[4]; + tmp4 := dataptr^[3] - dataptr^[4]; + + { Even part } + + tmp10 := tmp0 + tmp3; { phase 2 } + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[0] := tmp10 + tmp11; { phase 3 } + dataptr^[4] := tmp10 - tmp11; + + z1 := (tmp12 + tmp13) * ({FAST_FLOAT}(0.707106781)); { c4 } + dataptr^[2] := tmp13 + z1; { phase 5 } + dataptr^[6] := tmp13 - z1; + + { Odd part } + + tmp10 := tmp4 + tmp5; { phase 2 } + tmp11 := tmp5 + tmp6; + tmp12 := tmp6 + tmp7; + + { The rotator is modified from fig 4-8 to avoid extra negations. } + z5 := (tmp10 - tmp12) * ( {FAST_FLOAT}(0.382683433)); { c6 } + z2 := {FAST_FLOAT}(0.541196100) * tmp10 + z5; { c2-c6 } + z4 := {FAST_FLOAT}(1.306562965) * tmp12 + z5; { c2+c6 } + z3 := tmp11 * {FAST_FLOAT} (0.707106781); { c4 } + + z11 := tmp7 + z3; { phase 5 } + z13 := tmp7 - z3; + + dataptr^[5] := z13 + z2; { phase 6 } + dataptr^[3] := z13 - z2; + dataptr^[1] := z11 + z4; + dataptr^[7] := z11 - z4; + + Inc(FAST_FLOAT_PTR(dataptr), DCTSIZE); { advance pointer to next row } + end; + + { Pass 2: process columns. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[DCTSIZE*0] + dataptr^[DCTSIZE*7]; + tmp7 := dataptr^[DCTSIZE*0] - dataptr^[DCTSIZE*7]; + tmp1 := dataptr^[DCTSIZE*1] + dataptr^[DCTSIZE*6]; + tmp6 := dataptr^[DCTSIZE*1] - dataptr^[DCTSIZE*6]; + tmp2 := dataptr^[DCTSIZE*2] + dataptr^[DCTSIZE*5]; + tmp5 := dataptr^[DCTSIZE*2] - dataptr^[DCTSIZE*5]; + tmp3 := dataptr^[DCTSIZE*3] + dataptr^[DCTSIZE*4]; + tmp4 := dataptr^[DCTSIZE*3] - dataptr^[DCTSIZE*4]; + + { Even part } + + tmp10 := tmp0 + tmp3; { phase 2 } + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[DCTSIZE*0] := tmp10 + tmp11; { phase 3 } + dataptr^[DCTSIZE*4] := tmp10 - tmp11; + + z1 := (tmp12 + tmp13) * {FAST_FLOAT} (0.707106781); { c4 } + dataptr^[DCTSIZE*2] := tmp13 + z1; { phase 5 } + dataptr^[DCTSIZE*6] := tmp13 - z1; + + { Odd part } + + tmp10 := tmp4 + tmp5; { phase 2 } + tmp11 := tmp5 + tmp6; + tmp12 := tmp6 + tmp7; + + { The rotator is modified from fig 4-8 to avoid extra negations. } + z5 := (tmp10 - tmp12) * {FAST_FLOAT} (0.382683433); { c6 } + z2 := {FAST_FLOAT} (0.541196100) * tmp10 + z5; { c2-c6 } + z4 := {FAST_FLOAT} (1.306562965) * tmp12 + z5; { c2+c6 } + z3 := tmp11 * {FAST_FLOAT} (0.707106781); { c4 } + + z11 := tmp7 + z3; { phase 5 } + z13 := tmp7 - z3; + + dataptr^[DCTSIZE*5] := z13 + z2; { phase 6 } + dataptr^[DCTSIZE*3] := z13 - z2; + dataptr^[DCTSIZE*1] := z11 + z4; + dataptr^[DCTSIZE*7] := z11 - z4; + + Inc(FAST_FLOAT_PTR(dataptr)); { advance pointer to next column } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jfdctfst_del.pas b/mseide-msegui/lib/common/fpccompatibility/jfdctfst_del.pas new file mode 100644 index 0000000..d74e32a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jfdctfst_del.pas @@ -0,0 +1,239 @@ +Unit jfdctfst_del; + +{ This file contains a fast, not so accurate integer implementation of the + forward DCT (Discrete Cosine Transform). + + A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + on each column. Direct algorithms are also available, but they are + much more complex and seem not to be any faster when reduced to code. + + This implementation is based on Arai, Agui, and Nakajima's algorithm for + scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + Japanese, but the algorithm is described in the Pennebaker & Mitchell + JPEG textbook (see REFERENCES section in file README). The following code + is based directly on figure 4-8 in P&M. + While an 8-point DCT cannot be done in less than 11 multiplies, it is + possible to arrange the computation so that many of the multiplies are + simple scalings of the final outputs. These multiplies can then be + folded into the multiplications or divisions by the JPEG quantization + table entries. The AA&N method leaves only 5 multiplies and 29 adds + to be done in the DCT itself. + The primary disadvantage of this method is that with fixed-point math, + accuracy is lost due to imprecise representation of the scaled + quantization values. The smaller the quantization table entry, the less + precise the scaled value, so this implementation does worse with high- + quality-setting files than with low-quality ones. } + +{ Original: jfdctfst.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + + +{ Perform the forward DCT on one block of samples. } + +{GLOBAL} +procedure jpeg_fdct_ifast (var data : array of DCTELEM); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + + +{ Scaling decisions are generally the same as in the LL&M algorithm; + see jfdctint.c for more details. However, we choose to descale + (right shift) multiplication products as soon as they are formed, + rather than carrying additional fractional bits into subsequent additions. + This compromises accuracy slightly, but it lets us save a few shifts. + More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + everywhere except in the multiplications proper; this saves a good deal + of work on 16-bit-int machines. + + Again to save a few shifts, the intermediate results between pass 1 and + pass 2 are not upscaled, but are represented only to integral precision. + + A final compromise is to represent the multiplicative constants to only + 8 fractional bits, rather than 13. This saves some shifting work on some + machines, and may also reduce the cost of multiplication (since there + are fewer one-bits in the constants). } + +//modified 2013 by Martin Schreiber + +const + CONST_BITS = 8; +const + CONST_SCALE = (INT32(1) shl CONST_BITS); + + +const + FIX_0_382683433 = INT32(Round(CONST_SCALE * 0.382683433)); {98} + FIX_0_541196100 = INT32(Round(CONST_SCALE * 0.541196100)); {139} + FIX_0_707106781 = INT32(Round(CONST_SCALE * 0.707106781)); {181} + FIX_1_306562965 = INT32(Round(CONST_SCALE * 1.306562965)); {334} + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{ We can gain a little more speed, with a further compromise in accuracy, + by omitting the addition in a descaling shift. This yields an incorrectly + rounded result half the time... } +{$ifndef USE_ACCURATE_ROUNDING} + shift_temp := x; +{$else} + shift_temp := x + (INT32(1) shl (n-1)); +{$endif} + +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else +{$endif} + Descale := (shift_temp shr n); +end; + +{ Multiply a DCTELEM variable by an INT32 constant, and immediately + descale to yield a DCTELEM result. } + + + function MULTIPLY(X : DCTELEM; Y: INT32): DCTELEM; + begin + Multiply := DeScale((X) * (Y), CONST_BITS); + end; + + +{ Perform the forward DCT on one block of samples. } + +{GLOBAL} +procedure jpeg_fdct_ifast (var data : array of DCTELEM); +type + PWorkspace = ^TWorkspace; + TWorkspace = array [0..DCTSIZE2-1] of DCTELEM; +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : DCTELEM; + tmp10, tmp11, tmp12, tmp13 : DCTELEM; + z1, z2, z3, z4, z5, z11, z13 : DCTELEM; + dataptr : PWorkspace; + ctr : int; + {SHIFT_TEMPS} +begin + { Pass 1: process rows. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[0] + dataptr^[7]; + tmp7 := dataptr^[0] - dataptr^[7]; + tmp1 := dataptr^[1] + dataptr^[6]; + tmp6 := dataptr^[1] - dataptr^[6]; + tmp2 := dataptr^[2] + dataptr^[5]; + tmp5 := dataptr^[2] - dataptr^[5]; + tmp3 := dataptr^[3] + dataptr^[4]; + tmp4 := dataptr^[3] - dataptr^[4]; + + { Even part } + + tmp10 := tmp0 + tmp3; { phase 2 } + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[0] := tmp10 + tmp11; { phase 3 } + dataptr^[4] := tmp10 - tmp11; + + z1 := MULTIPLY(tmp12 + tmp13, FIX_0_707106781); { c4 } + dataptr^[2] := tmp13 + z1; { phase 5 } + dataptr^[6] := tmp13 - z1; + + { Odd part } + + tmp10 := tmp4 + tmp5; { phase 2 } + tmp11 := tmp5 + tmp6; + tmp12 := tmp6 + tmp7; + + { The rotator is modified from fig 4-8 to avoid extra negations. } + z5 := MULTIPLY(tmp10 - tmp12, FIX_0_382683433); { c6 } + z2 := MULTIPLY(tmp10, FIX_0_541196100) + z5; { c2-c6 } + z4 := MULTIPLY(tmp12, FIX_1_306562965) + z5; { c2+c6 } + z3 := MULTIPLY(tmp11, FIX_0_707106781); { c4 } + + z11 := tmp7 + z3; { phase 5 } + z13 := tmp7 - z3; + + dataptr^[5] := z13 + z2; { phase 6 } + dataptr^[3] := z13 - z2; + dataptr^[1] := z11 + z4; + dataptr^[7] := z11 - z4; + + Inc(DCTELEMPTR(dataptr), DCTSIZE); { advance pointer to next row } + end; + + { Pass 2: process columns. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[DCTSIZE*0] + dataptr^[DCTSIZE*7]; + tmp7 := dataptr^[DCTSIZE*0] - dataptr^[DCTSIZE*7]; + tmp1 := dataptr^[DCTSIZE*1] + dataptr^[DCTSIZE*6]; + tmp6 := dataptr^[DCTSIZE*1] - dataptr^[DCTSIZE*6]; + tmp2 := dataptr^[DCTSIZE*2] + dataptr^[DCTSIZE*5]; + tmp5 := dataptr^[DCTSIZE*2] - dataptr^[DCTSIZE*5]; + tmp3 := dataptr^[DCTSIZE*3] + dataptr^[DCTSIZE*4]; + tmp4 := dataptr^[DCTSIZE*3] - dataptr^[DCTSIZE*4]; + + { Even part } + + tmp10 := tmp0 + tmp3; { phase 2 } + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[DCTSIZE*0] := tmp10 + tmp11; { phase 3 } + dataptr^[DCTSIZE*4] := tmp10 - tmp11; + + z1 := MULTIPLY(tmp12 + tmp13, FIX_0_707106781); { c4 } + dataptr^[DCTSIZE*2] := tmp13 + z1; { phase 5 } + dataptr^[DCTSIZE*6] := tmp13 - z1; + + { Odd part } + + tmp10 := tmp4 + tmp5; { phase 2 } + tmp11 := tmp5 + tmp6; + tmp12 := tmp6 + tmp7; + + { The rotator is modified from fig 4-8 to avoid extra negations. } + z5 := MULTIPLY(tmp10 - tmp12, FIX_0_382683433); { c6 } + z2 := MULTIPLY(tmp10, FIX_0_541196100) + z5; { c2-c6 } + z4 := MULTIPLY(tmp12, FIX_1_306562965) + z5; { c2+c6 } + z3 := MULTIPLY(tmp11, FIX_0_707106781); { c4 } + + z11 := tmp7 + z3; { phase 5 } + z13 := tmp7 - z3; + + dataptr^[DCTSIZE*5] := z13 + z2; { phase 6 } + dataptr^[DCTSIZE*3] := z13 - z2; + dataptr^[DCTSIZE*1] := z11 + z4; + dataptr^[DCTSIZE*7] := z11 - z4; + + Inc(DCTELEMPTR(dataptr)); { advance pointer to next column } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jfdctint_del.pas b/mseide-msegui/lib/common/fpccompatibility/jfdctint_del.pas new file mode 100644 index 0000000..f2ad5db --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jfdctint_del.pas @@ -0,0 +1,299 @@ +Unit jfdctint_del; + + +{ This file contains a slow-but-accurate integer implementation of the + forward DCT (Discrete Cosine Transform). + + A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + on each column. Direct algorithms are also available, but they are + much more complex and seem not to be any faster when reduced to code. + + This implementation is based on an algorithm described in + C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + The primary algorithm described there uses 11 multiplies and 29 adds. + We use their alternate method with 12 multiplies and 32 adds. + The advantage of this method is that no data path contains more than one + multiplication; this allows a very simple and accurate implementation in + scaled fixed-point arithmetic, with a minimal number of shifts. } + +{ Original : jfdctint.c ; Copyright (C) 1991-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jutils_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + + +{ Perform the forward DCT on one block of samples. } + +{GLOBAL} +procedure jpeg_fdct_islow (var data : array of DCTELEM); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + + +{ The poop on this scaling stuff is as follows: + + Each 1-D DCT step produces outputs which are a factor of sqrt(N) + larger than the true DCT outputs. The final outputs are therefore + a factor of N larger than desired; since N=8 this can be cured by + a simple right shift at the end of the algorithm. The advantage of + this arrangement is that we save two multiplications per 1-D DCT, + because the y0 and y4 outputs need not be divided by sqrt(N). + In the IJG code, this factor of 8 is removed by the quantization step + (in jcdctmgr.c), NOT in this module. + + We have to do addition and subtraction of the integer inputs, which + is no problem, and multiplication by fractional constants, which is + a problem to do in integer arithmetic. We multiply all the constants + by CONST_SCALE and convert them to integer constants (thus retaining + CONST_BITS bits of precision in the constants). After doing a + multiplication we have to divide the product by CONST_SCALE, with proper + rounding, to produce the correct output. This division can be done + cheaply as a right shift of CONST_BITS bits. We postpone shifting + as long as possible so that partial sums can be added together with + full fractional precision. + + The outputs of the first pass are scaled up by PASS1_BITS bits so that + they are represented to better-than-integral precision. These outputs + require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + with the recommended scaling. (For 12-bit sample data, the intermediate + array is INT32 anyway.) + + To avoid overflow of the 32-bit intermediate results in pass 2, we must + have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + shows that the values given below are the most effective. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + CONST_BITS = 13; + PASS1_BITS = 2; +{$else} +const + CONST_BITS = 13; + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + +const + CONST_SCALE = (INT32(1) shl CONST_BITS); + +const + FIX_0_298631336 = INT32(Round(CONST_SCALE * 0.298631336)); {2446} + FIX_0_390180644 = INT32(Round(CONST_SCALE * 0.390180644)); {3196} + FIX_0_541196100 = INT32(Round(CONST_SCALE * 0.541196100)); {4433} + FIX_0_765366865 = INT32(Round(CONST_SCALE * 0.765366865)); {6270} + FIX_0_899976223 = INT32(Round(CONST_SCALE * 0.899976223)); {7373} + FIX_1_175875602 = INT32(Round(CONST_SCALE * 1.175875602)); {9633} + FIX_1_501321110 = INT32(Round(CONST_SCALE * 1.501321110)); {12299} + FIX_1_847759065 = INT32(Round(CONST_SCALE * 1.847759065)); {15137} + FIX_1_961570560 = INT32(Round(CONST_SCALE * 1.961570560)); {16069} + FIX_2_053119869 = INT32(Round(CONST_SCALE * 2.053119869)); {16819} + FIX_2_562915447 = INT32(Round(CONST_SCALE * 2.562915447)); {20995} + FIX_3_072711026 = INT32(Round(CONST_SCALE * 3.072711026)); {25172} + + +{ Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + For 8-bit samples with the recommended scaling, all the variable + and constant values involved are no more than 16 bits wide, so a + 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + For 12-bit samples, a full 32-bit multiplication will be needed. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} + + {MULTIPLY16C16(var,const)} + function Multiply(X, Y: int): INT32; + begin + Multiply := int(X) * INT32(Y); + end; + +{$else} + function Multiply(X, Y: INT32): INT32; + begin + Multiply := X * Y; + end; +{$endif} + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + shift_temp := x + (INT32(1) shl (n-1)); + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + Descale := (shift_temp shr n); +{$else} + Descale := (x + (INT32(1) shl (n-1)) shr n; +{$endif} +end; + + +{ Perform the forward DCT on one block of samples. } + +{GLOBAL} +procedure jpeg_fdct_islow (var data : array of DCTELEM); +type + PWorkspace = ^TWorkspace; + TWorkspace = array [0..DCTSIZE2-1] of DCTELEM; +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : INT32; + tmp10, tmp11, tmp12, tmp13 : INT32; + z1, z2, z3, z4, z5 : INT32; + dataptr : PWorkspace; + ctr : int; + {SHIFT_TEMPS} +begin + + { Pass 1: process rows. } + { Note results are scaled up by sqrt(8) compared to a true DCT; } + { furthermore, we scale the results by 2**PASS1_BITS. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[0] + dataptr^[7]; + tmp7 := dataptr^[0] - dataptr^[7]; + tmp1 := dataptr^[1] + dataptr^[6]; + tmp6 := dataptr^[1] - dataptr^[6]; + tmp2 := dataptr^[2] + dataptr^[5]; + tmp5 := dataptr^[2] - dataptr^[5]; + tmp3 := dataptr^[3] + dataptr^[4]; + tmp4 := dataptr^[3] - dataptr^[4]; + + { Even part per LL&M figure 1 --- note that published figure is faulty; + rotator "sqrt(2)*c1" should be "sqrt(2)*c6". } + + tmp10 := tmp0 + tmp3; + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[0] := DCTELEM ((tmp10 + tmp11) shl PASS1_BITS); + dataptr^[4] := DCTELEM ((tmp10 - tmp11) shl PASS1_BITS); + + z1 := MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr^[2] := DCTELEM (DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS-PASS1_BITS)); + dataptr^[6] := DCTELEM (DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS-PASS1_BITS)); + + { Odd part per figure 8 --- note paper omits factor of sqrt(2). + cK represents cos(K*pi/16). + i0..i3 in the paper are tmp4..tmp7 here. } + + z1 := tmp4 + tmp7; + z2 := tmp5 + tmp6; + z3 := tmp4 + tmp6; + z4 := tmp5 + tmp7; + z5 := MULTIPLY(z3 + z4, FIX_1_175875602); { sqrt(2) * c3 } + + tmp4 := MULTIPLY(tmp4, FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + tmp5 := MULTIPLY(tmp5, FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + tmp6 := MULTIPLY(tmp6, FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + tmp7 := MULTIPLY(tmp7, FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + z1 := MULTIPLY(z1, - FIX_0_899976223); { sqrt(2) * (c7-c3) } + z2 := MULTIPLY(z2, - FIX_2_562915447); { sqrt(2) * (-c1-c3) } + z3 := MULTIPLY(z3, - FIX_1_961570560); { sqrt(2) * (-c3-c5) } + z4 := MULTIPLY(z4, - FIX_0_390180644); { sqrt(2) * (c5-c3) } + + Inc(z3, z5); + Inc(z4, z5); + + dataptr^[7] := DCTELEM(DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS)); + dataptr^[5] := DCTELEM(DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS)); + dataptr^[3] := DCTELEM(DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS)); + dataptr^[1] := DCTELEM(DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS)); + + Inc(DCTELEMPTR(dataptr), DCTSIZE); { advance pointer to next row } + end; + + { Pass 2: process columns. + We remove the PASS1_BITS scaling, but leave the results scaled up + by an overall factor of 8. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[DCTSIZE*0] + dataptr^[DCTSIZE*7]; + tmp7 := dataptr^[DCTSIZE*0] - dataptr^[DCTSIZE*7]; + tmp1 := dataptr^[DCTSIZE*1] + dataptr^[DCTSIZE*6]; + tmp6 := dataptr^[DCTSIZE*1] - dataptr^[DCTSIZE*6]; + tmp2 := dataptr^[DCTSIZE*2] + dataptr^[DCTSIZE*5]; + tmp5 := dataptr^[DCTSIZE*2] - dataptr^[DCTSIZE*5]; + tmp3 := dataptr^[DCTSIZE*3] + dataptr^[DCTSIZE*4]; + tmp4 := dataptr^[DCTSIZE*3] - dataptr^[DCTSIZE*4]; + + { Even part per LL&M figure 1 --- note that published figure is faulty; + rotator "sqrt(2)*c1" should be "sqrt(2)*c6". } + + tmp10 := tmp0 + tmp3; + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[DCTSIZE*0] := DCTELEM (DESCALE(tmp10 + tmp11, PASS1_BITS)); + dataptr^[DCTSIZE*4] := DCTELEM (DESCALE(tmp10 - tmp11, PASS1_BITS)); + + z1 := MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr^[DCTSIZE*2] := DCTELEM (DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS+PASS1_BITS)); + dataptr^[DCTSIZE*6] := DCTELEM (DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS+PASS1_BITS)); + + { Odd part per figure 8 --- note paper omits factor of sqrt(2). + cK represents cos(K*pi/16). + i0..i3 in the paper are tmp4..tmp7 here. } + + z1 := tmp4 + tmp7; + z2 := tmp5 + tmp6; + z3 := tmp4 + tmp6; + z4 := tmp5 + tmp7; + z5 := MULTIPLY(z3 + z4, FIX_1_175875602); { sqrt(2) * c3 } + + tmp4 := MULTIPLY(tmp4, FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + tmp5 := MULTIPLY(tmp5, FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + tmp6 := MULTIPLY(tmp6, FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + tmp7 := MULTIPLY(tmp7, FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + z1 := MULTIPLY(z1, - FIX_0_899976223); { sqrt(2) * (c7-c3) } + z2 := MULTIPLY(z2, - FIX_2_562915447); { sqrt(2) * (-c1-c3) } + z3 := MULTIPLY(z3, - FIX_1_961570560); { sqrt(2) * (-c3-c5) } + z4 := MULTIPLY(z4, - FIX_0_390180644); { sqrt(2) * (c5-c3) } + + Inc(z3, z5); + Inc(z4, z5); + + dataptr^[DCTSIZE*7] := DCTELEM (DESCALE(tmp4 + z1 + z3, + CONST_BITS+PASS1_BITS)); + dataptr^[DCTSIZE*5] := DCTELEM (DESCALE(tmp5 + z2 + z4, + CONST_BITS+PASS1_BITS)); + dataptr^[DCTSIZE*3] := DCTELEM (DESCALE(tmp6 + z2 + z3, + CONST_BITS+PASS1_BITS)); + dataptr^[DCTSIZE*1] := DCTELEM (DESCALE(tmp7 + z1 + z4, + CONST_BITS+PASS1_BITS)); + + Inc(DCTELEMPTR(dataptr)); { advance pointer to next column } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jidct2d_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidct2d_del.pas new file mode 100644 index 0000000..68933f3 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidct2d_del.pas @@ -0,0 +1,1048 @@ +Unit JIDct2D; + +{ This file contains a fast, not so accurate integer implementation of the + inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + must also perform dequantization of the input coefficients. + + + A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + on each row (or vice versa, but it's more convenient to emit a row at + a time). Direct algorithms are also available, but they are much more + complex and seem not to be any faster when reduced to code. + + The Feig direct 2D scaled Discrete Cosine Transform extends Arai, Agui + and Nakajima fast scaled DCT to 2D (464 adds and 80 mult.) with further + computational saving (462 adds, 54 mults and 6 shits). + + The forward DCT is described with flow diagrams from the Pennebaker& + Mitchell JPEG book. The inverse DCT flow diagrams are obtained + from the inverse matrices. Scaling must be done accordingly. + + Jacques NOMSSI NZALI, May 16th 1995 } + + +interface + +uses + jmorecfg, + jinclude, + jpeglib, + jdct; { Private declarations for DCT subsystem } + +{$I jconfig_del.inc} + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_i2d (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + +{ Scaling decisions are generally the same as in the LL&M algorithm; + see jidctint.c for more details. However, we choose to descale + (right shift) multiplication products as soon as they are formed, + rather than carrying additional fractional bits into subsequent additions. + This compromises accuracy slightly, but it lets us save a few shifts. + More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + everywhere except in the multiplications proper; this saves a good deal + of work on 16-bit-int machines. + + The dequantized coefficients are not integers because the AA&N scaling + factors have been incorporated. We represent them scaled up by PASS1_BITS, + so that the first and second IDCT rounds have the same input scaling. + For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to + avoid a descaling shift; this compromises accuracy rather drastically + for small quantization table entries, but it saves a lot of shifts. + For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway, + so we use a much larger scaling factor to preserve accuracy. + + A final compromise is to represent the multiplicative constants to only + 8 fractional bits, rather than 13. This saves some shifting work on some + machines, and may also reduce the cost of multiplication (since there + are fewer one-bits in the constants). } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + CONST_BITS = 8; + PASS1_BITS = 2; +{$else} + CONST_BITS = 8; + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + + +{ Convert a positive real constant to an integer scaled by CONST_SCALE. } +const + CONST_SCALE = (INT32(1) shl CONST_BITS); +const + FIX_1_082392200 = INT32(Round(CONST_SCALE*1.082392200)); {277} + FIX_1_414213562 = INT32(Round(CONST_SCALE*1.414213562)); {362} + FIX_1_847759065 = INT32(Round(CONST_SCALE*1.847759065)); {473} + FIX_2_613125930 = INT32(Round(CONST_SCALE*2.613125930)); {669} + + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef USE_ACCURATE_ROUNDING} + shift_temp := x + (INT32(1) shl (n-1)); +{$else} +{ We can gain a little more speed, with a further compromise in accuracy, + by omitting the addition in a descaling shift. This yields an incorrectly + rounded result half the time... } + shift_temp := x; +{$endif} + +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else +{$endif} + Descale := (shift_temp shr n); + +end; + + +{ Multiply a DCTELEM variable by an INT32 constant, and immediately + descale to yield a DCTELEM result. } + + {(DCTELEM( DESCALE((var) * (const), CONST_BITS))} + function Multiply(Avar, Aconst: Integer): DCTELEM; + begin + Multiply := DCTELEM( Avar*INT32(Aconst) div CONST_SCALE); + end; + + + +{ Dequantize a coefficient by multiplying it by the multiplier-table + entry; produce a DCTELEM result. For 8-bit data a 16x16->16 + multiplication will do. For 12-bit data, the multiplier table is + declared INT32, so a 32-bit multiply will be used. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} + function DEQUANTIZE(coef,quantval : int) : int; + begin + Dequantize := ( IFAST_MULT_TYPE(coef) * quantval); + end; + +{$else} +#define DEQUANTIZE(coef,quantval) \ + DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS) +{$endif} + + +{ Like DESCALE, but applies to a DCTELEM and produces an int. + We assume that int right shift is unsigned if INT32 right shift is. } + +function IDESCALE(x : DCTELEM; n : int) : int; +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + DCTELEMBITS = 16; { DCTELEM may be 16 or 32 bits } +{$else} +const + DCTELEMBITS = 32; { DCTELEM must be 32 bits } +{$endif} +var + ishift_temp : DCTELEM; +begin +{$ifndef USE_ACCURATE_ROUNDING} + ishift_temp := x + (INT32(1) shl (n-1)); +{$else} +{ We can gain a little more speed, with a further compromise in accuracy, + by omitting the addition in a descaling shift. This yields an incorrectly + rounded result half the time... } + ishift_temp := x; +{$endif} + +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if ishift_temp < 0 then + IDescale := (ishift_temp shr n) + or ((not DCTELEM(0)) shl (DCTELEMBITS-n)) + else +{$endif} + IDescale := (ishift_temp shr n); +end; + + + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_i2d (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +Const + CONST_IC4 = 1.414213562; { 1/0.707106781; } + FP_IC4 = FIX_1_414213562; + FP_I_C4_2 = FP_IC4; + +type + PWorkspace = ^TWorkspace; + TWorkspace = coef_bits_field; { buffers data between passes } + + Procedure N1(var x, y : integer); { rotator 1 } + Const + FP_a5 = FIX_1_847759065; + FP_a4 = FIX_2_613125930; + FP_a2 = FIX_1_082392200; + var + z5, tmp : integer; + begin + tmp := x; + + z5 := Multiply(tmp + y, FP_a5); { c6 } + x := Multiply(y, FP_a2) - z5; { c2-c6 } + y := Multiply(tmp, -FP_a4) + z5; { c2+c6 } + end; + + Procedure N2(var x, y : integer); { N1 scaled by c4 } + Const + FP_b5 = Integer(Round(CONST_SCALE*1.847759065*CONST_IC4)); + FP_b4 = Integer(Round(CONST_SCALE*2.613125930*CONST_IC4)); + FP_b2 = Integer(Round(CONST_SCALE*1.082392200*CONST_IC4)); + var + z5, tmp : integer; + begin + tmp := x; + + z5 := Multiply(tmp + y, FP_b5); + x := Multiply(y, FP_b2) - z5; + y := Multiply(tmp,-FP_b4) + z5; + end; + +var + column, row : byte; + +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : DCTELEM; + tmp10, tmp11, tmp12, tmp13 : DCTELEM; + z10, z11, z12, z13 : DCTELEM; + inptr : JCOEFPTR; + + quantptr : IFAST_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS { for DESCALE } + {ISHIFT_TEMPS { for IDESCALE } +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := IFAST_MULT_TYPE_FIELD_PTR(compptr^.dct_table); + wsptr := @workspace; + for ctr := pred(DCTSIZE) downto 0 do + begin + { short-circuiting is not easily done here } + // bbo := @outptr; + for num := 0 to Pred(count) do + begin + { R1 x R1 } + for column := 7 downto 0 do + BEGIN + tmp5 := inptr^[1*RowSize + column]; + + inptr^[1*RowSize + column] := inptr^[4*RowSize + column]; + + tmp7 := inptr^[3*RowSize + column]; + + a := inptr^[2*RowSize + column]; + b := inptr^[6*RowSize + column]; + inptr^[2*RowSize + column] := a - b; + inptr^[3*RowSize + column] := a + b; + + a := inptr^[5*RowSize + column]; + inptr^[4*RowSize + column] := a - tmp7; + z13 := a + tmp7; + + b := inptr^[7*RowSize + column]; + inptr^[6*RowSize + column] := tmp5 - b; + z11 := tmp5 + b; + + inptr^[5*RowSize + column] := z11 - z13; + inptr^[7*RowSize + column] := z11 + z13; + END; + + { Even part } + + tmp0 := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]); + tmp1 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]); + tmp2 := DEQUANTIZE(inptr^[DCTSIZE*4], quantptr^[DCTSIZE*4]); + tmp3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]); + + tmp10 := tmp0 + tmp2; { phase 3 } + tmp11 := tmp0 - tmp2; + + tmp13 := tmp1 + tmp3; { phases 5-3 } + tmp12 := MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; { 2*c4 } + + tmp0 := tmp10 + tmp13; { phase 2 } + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + tmp4 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]); + tmp5 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]); + tmp6 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]); + tmp7 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]); + + z13 := tmp6 + tmp5; { phase 6 } + z10 := tmp6 - tmp5; + z11 := tmp4 + tmp7; + z12 := tmp4 - tmp7; + + tmp7 := z11 + z13; { phase 5 } + tmp11 := MULTIPLY(z11 - z13, FIX_1_414213562); { 2*c4 } + + z5 := MULTIPLY(z10 + z12, FIX_1_847759065); { 2*c2 } + tmp10 := MULTIPLY(z12, FIX_1_082392200) - z5; { 2*(c2-c6) } + tmp12 := MULTIPLY(z10, - FIX_2_613125930) + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; { phase 2 } + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + wsptr^[DCTSIZE*0] := int (tmp0 + tmp7); + wsptr^[DCTSIZE*7] := int (tmp0 - tmp7); + wsptr^[DCTSIZE*1] := int (tmp1 + tmp6); + wsptr^[DCTSIZE*6] := int (tmp1 - tmp6); + wsptr^[DCTSIZE*2] := int (tmp2 + tmp5); + wsptr^[DCTSIZE*5] := int (tmp2 - tmp5); + wsptr^[DCTSIZE*4] := int (tmp3 + tmp4); + wsptr^[DCTSIZE*3] := int (tmp3 - tmp4); + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(IFAST_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + end; + + { Pass 2: process rows from work array, store into output array. } + { Note that we must descale the results by a factor of 8 == 2**3, } + { and also undo the PASS1_BITS scaling. } + + wsptr := @workspace; + for ctr := 0 to pred(DCTSIZE) do + begin + outptr := JSAMPROW(@output_buf^[ctr]^[output_col]); + { Rows of zeroes can be exploited in the same way as we did with columns. + However, the column calculation has created many nonzero AC terms, so + the simplification applies less often (typically 5% to 10% of the time). + On machines with very fast multiplication, it's possible that the + test takes more time than it's worth. In that case this section + may be commented out. } + +{$ifndef NO_ZERO_ROW_TEST} + if ((wsptr^[1]) or (wsptr^[2]) or (wsptr^[3]) or (wsptr^[4]) or (wsptr^[5]) or + (wsptr^[6]) or (wsptr^[7]) = 0) then + begin + { AC terms all zero } + JSAMPLE(dcval_) := range_limit^[IDESCALE(wsptr^[0], PASS1_BITS+3) + and RANGE_MASK]; + + outptr^[0] := dcval_; + outptr^[1] := dcval_; + outptr^[2] := dcval_; + outptr^[3] := dcval_; + outptr^[4] := dcval_; + outptr^[5] := dcval_; + outptr^[6] := dcval_; + outptr^[7] := dcval_; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + continue; + end; +{$endif} + + { Even part } + + tmp10 := (DCTELEM(wsptr^[0]) + DCTELEM(wsptr^[4])); + tmp11 := (DCTELEM(wsptr^[0]) - DCTELEM(wsptr^[4])); + + tmp13 := (DCTELEM(wsptr^[2]) + DCTELEM(wsptr^[6])); + tmp12 := MULTIPLY(DCTELEM(wsptr^[2]) - DCTELEM(wsptr^[6]), FIX_1_414213562) + - tmp13; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + z13 := DCTELEM(wsptr^[5]) + DCTELEM(wsptr^[3]); + z10 := DCTELEM(wsptr^[5]) - DCTELEM(wsptr^[3]); + z11 := DCTELEM(wsptr^[1]) + DCTELEM(wsptr^[7]); + z12 := DCTELEM(wsptr^[1]) - DCTELEM(wsptr^[7]); + + tmp7 := z11 + z13; { phase 5 } + tmp11 := MULTIPLY(z11 - z13, FIX_1_414213562); { 2*c4 } + + z5 := MULTIPLY(z10 + z12, FIX_1_847759065); { 2*c2 } + tmp10 := MULTIPLY(z12, FIX_1_082392200) - z5; { 2*(c2-c6) } + tmp12 := MULTIPLY(z10, - FIX_2_613125930) + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; { phase 2 } + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + { Final output stage: scale down by a factor of 8 and range-limit } + + outptr^[0] := range_limit^[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[7] := range_limit^[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[1] := range_limit^[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[6] := range_limit^[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[2] := range_limit^[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[5] := range_limit^[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[4] := range_limit^[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[3] := range_limit^[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + and RANGE_MASK]; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + +end. +---------------------------------------------------------- +type + matasm = array[0..DCTSIZE2-1] of integer; + bmatrix = array[0..DCTSIZE2-1] of byte; + bmatrixptr = ^bmatrix; +procedure ANN_IDCT(var coef_block :matasm; + var outptr :bmatrix); + + var coeffs :matasm; = coef_block + var outptr :bmatrix); output_buf + +Const + CONST_IC4 = 1.414213562; { 1/0.707106781; } + FP_IC4 = FIX_1_414213562; + FP_I_C4_2 = FP_IC4; + + Function Descale(x : integer):byte; + var y : integer; + begin + y := (x + (1 shl (16-1))+ (4 shl PASS_BITS)) div (8 shl PASS_BITS); + { DeScale := x sar (3 + PASS_BITS); + Borland Pascal SHR is unsigned } + if y < 0 then + descale := 0 + else + if y > $ff then + descale := $ff + else + descale := y; + end; + + function Multiply(X, Y: Integer): integer; assembler; + asm + mov ax, X + imul Y + mov al, ah + mov ah, dl + end; + + +Const + RowSize = 8; +var + a, b : integer; + + inptr : JCOEFPTR; + + outptr : bmatrixptr; + + num : integer; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + inptr := @coef_block; + ctr*RowSize + quantptr := IFAST_MULT_TYPE_FIELD_PTR(compptr^.dct_table); + + for ctr := pred(DCTSIZE) downto 0 do + BEGIN + tmp5 := inptr^[1]; + + inptr^[1] := inptr^[4]; + + tmp7 := inptr^[3]; + + a := inptr^[2]; + b := inptr^[6]; + inptr^[2] := a - b; + inptr^[3] := a + b; + + a := inptr^[5]; + inptr^[+ 4] := a - tmp7; + z13 := a + tmp7; + + b := inptr^[7]; + inptr^[6] := tmp5 - b; + z11 := tmp5 + b; + + inptr^[5] := z11 - z13; + inptr^[7] := z11 + z13; + END; + + { M x M tensor } + for row := 0 to 7 do + Case row of + 0,1,3,7: { M1 } + begin + inptr^[row*RowSize + 2] := Multiply(inptr^[row*RowSize + 2], FP_IC4); { 2/c4 } + inptr^[row*RowSize + 5] := Multiply(inptr^[row*RowSize + 5], FP_IC4); { 2/c4 } + + N1(inptr^[row*RowSize + 4], inptr^[row*RowSize + 6]); + end; + 2,5: { M2 } + begin + inptr^[row*RowSize + 0] := Multiply(inptr^[row*RowSize + 0], FP_IC4); + inptr^[row*RowSize + 1] := Multiply(inptr^[row*RowSize + 1], FP_IC4); + inptr^[row*RowSize + 3] := Multiply(inptr^[row*RowSize + 3], FP_IC4); + inptr^[row*RowSize + 7] := Multiply(inptr^[row*RowSize + 7], FP_IC4); + + inptr^[row*RowSize + 2] := inptr^[row*RowSize + 2] * 2; { shift } + inptr^[row*RowSize + 5] := inptr^[row*RowSize + 5] * 2; + + N2(inptr^[row*RowSize + 4], inptr^[row*RowSize + 6]); + end; + end; { Case } + + { M x N tensor } + { rows 4,6 } + begin + N1(inptr^[4*RowSize + 0], inptr^[6*RowSize + 0]); + N1(inptr^[4*RowSize + 1], inptr^[6*RowSize + 1]); + N1(inptr^[4*RowSize + 3], inptr^[6*RowSize + 3]); + N1(inptr^[4*RowSize + 7], inptr^[6*RowSize + 7]); + + N2(inptr^[4*RowSize + 2], inptr^[6*RowSize + 2]); + N2(inptr^[4*RowSize + 5], inptr^[6*RowSize + 5]); + + { N3 } + { two inverse matrices => same as FDCT } + tmp0 := inptr^[4*RowSize + 4]; + tmp3 := inptr^[6*RowSize + 6]; + tmp12 := (tmp0 + tmp3) * 2; + z10 := tmp0 - tmp3; + + tmp1 := inptr^[6*RowSize + 4]; + tmp2 := inptr^[4*RowSize + 6]; + tmp13 :=-(tmp1 - tmp2)*2; + z11 := tmp1 + tmp2; + + tmp0 := Multiply(z10 + z11, FP_I_C4_2); + tmp1 := Multiply(z10 - z11, FP_I_C4_2); + + + inptr^[4*RowSize + 4] := tmp12 + tmp0; + inptr^[6*RowSize + 4] := tmp1 + tmp13; + + inptr^[4*RowSize + 6] := tmp1 - tmp13; + inptr^[6*RowSize + 6] := tmp12 - tmp0; + end; + + { R2 x R2 } + + for row := 0 to 7 do + BEGIN + { Odd part } + tmp7 := inptr^[row*RowSize + 7]; + tmp6 := inptr^[row*RowSize + 6] - tmp7; + tmp5 := inptr^[row*RowSize + 5] - tmp6; + tmp4 :=-inptr^[row*RowSize + 4] - tmp5; + + { even part } + tmp0 := inptr^[row*RowSize + 0]; + tmp1 := inptr^[row*RowSize + 1]; + tmp10 := tmp0 + tmp1; + tmp11 := tmp0 - tmp1; + + tmp2 := inptr^[row*RowSize + 2]; + tmp13 := inptr^[row*RowSize + 3]; + tmp12 := tmp2 - tmp13; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + inptr^[row*RowSize + 0] := (tmp0 + tmp7); + inptr^[row*RowSize + 7] := (tmp0 - tmp7); + + inptr^[row*RowSize + 3] := (tmp3 + tmp4); + inptr^[row*RowSize + 4] := (tmp3 - tmp4); + + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + inptr^[row*RowSize + 1] := (tmp1 + tmp6); + inptr^[row*RowSize + 6] := (tmp1 - tmp6); + + inptr^[row*RowSize + 2] := (tmp2 + tmp5); + inptr^[row*RowSize + 5] := (tmp2 - tmp5); + END; + + for ctr := 0 to pred(DCTSIZE) do + BEGIN + outptr := JSAMPROW(@output_buf^[ctr]^[output_col]); + { even part } + tmp0 := inptr^[0*RowSize + ctr]; + tmp1 := inptr^[1*RowSize + ctr]; + tmp2 := inptr^[2*RowSize + ctr]; + tmp3 := inptr^[3*RowSize + ctr]; + + tmp10 := tmp0 + tmp1; + tmp11 := tmp0 - tmp1; + + tmp13 := tmp3; + tmp12 := tmp2 - tmp3; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + tmp4 := inptr^[4*RowSize + ctr]; + tmp5 := inptr^[5*RowSize + ctr]; + tmp6 := inptr^[6*RowSize + ctr]; + tmp7 := inptr^[7*RowSize + ctr]; + + tmp6 := tmp6 - tmp7; + tmp5 := tmp5 - tmp6; + tmp4 :=-tmp4 - tmp5; + + outptr^[0*RowSize + ctr] := DeScale(tmp0 + tmp7); + outptr^[7*RowSize + ctr] := DeScale(tmp0 - tmp7); + + outptr^[1*RowSize + ctr] := DeScale(tmp1 + tmp6); + outptr^[6*RowSize + ctr] := DeScale(tmp1 - tmp6); + + outptr^[2*RowSize + ctr] := DeScale(tmp2 + tmp5); + outptr^[5*RowSize + ctr] := DeScale(tmp2 - tmp5); + + outptr^[3*RowSize + ctr] := DeScale(tmp3 + tmp4); + outptr^[4*RowSize + ctr] := DeScale(tmp3 - tmp4); + + + { Final output stage: scale down by a factor of 8 and range-limit } + + outptr^[0] := range_limit^[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[7] := range_limit^[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[1] := range_limit^[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[6] := range_limit^[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[2] := range_limit^[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[5] := range_limit^[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[4] := range_limit^[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[3] := range_limit^[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + and RANGE_MASK]; + END; + + Inc(bbo); + Inc(inptr); + End; +End; {----------------------------------------} + + +{GLOBAL} +procedure jpeg_idct_i2d (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +procedure Feig_2D_IDCT(coef_block :imatrix; + output_buf : JSAMPARRAY); +Const + CONST_IC4 = 1.414213562; { 1/0.707106781; } + FP_IC4 = Integer(Round(IFX_CONST*CONST_IC4)); + FP_I_C4_2 = FP_IC4; + + Function Descale(x : integer):integer; + begin + DeScale := (x+ (4 shl PASS_BITS)) div (8 shl PASS_BITS); + { DeScale := x sar (3 + PASS_BITS); + Borland Pascal SHR is unsigned } + end; + { + function Multiply(X, Y: Integer): integer; + begin + Multiply := Integer( X*LongInt(Y) div IFX_CONST); + end; + } + function Multiply(X, Y: Integer): integer; assembler; + asm + mov ax, X + imul Y + mov al, ah + mov ah, dl + end; + + +var + z10, z11, z12, z13, + tmp0,tmp1,tmp2,tmp3, + tmp4,tmp5,tmp6,tmp7, + tmp10,tmp11, + tmp12,tmp13 : integer; + column, row : byte; + + Procedure N1(var x, y : integer); { rotator 1 } + Const + FP_a5 = Integer(Round(IFX_CONST*1.847759065)); + FP_a4 = Integer(Round(IFX_CONST*2.613125930)); + FP_a2 = Integer(Round(IFX_CONST*1.082392200)); + var + z5, tmp : integer; + begin + tmp := x; + + z5 := Multiply(tmp + y, FP_a5); { c6 } + x := Multiply(y, FP_a2) - z5; { c2-c6 } + y := Multiply(tmp, -FP_a4) + z5; { c2+c6 } + end; + + Procedure N2(var x, y : integer); { N1 scaled by c4 } + Const + FP_b5 = Integer(Round(IFX_CONST*1.847759065*CONST_IC4)); + FP_b4 = Integer(Round(IFX_CONST*2.613125930*CONST_IC4)); + FP_b2 = Integer(Round(IFX_CONST*1.082392200*CONST_IC4)); + var + z5, tmp : integer; + begin + tmp := x; + + z5 := Multiply(tmp + y, FP_b5); + x := Multiply(y, FP_b2) - z5; + y := Multiply(tmp,-FP_b4) + z5; + end; + +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : DCTELEM; + tmp10, tmp11, tmp12, tmp13 : DCTELEM; + z10, z11, z12, z13 : DCTELEM; + inptr : JCOEFPTR; + + quantptr : IFAST_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS { for DESCALE } + {ISHIFT_TEMPS { for IDESCALE } +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := IFAST_MULT_TYPE_FIELD_PTR(compptr^.dct_table); + wsptr := @workspace; + + { R1 x R1 } + for ctr := pred(DCTSIZE) downto 0 do + BEGIN + { even part } + tmp1 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]); + tmp3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]); + + wsptr^[DCTSIZE*0] := int (DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0])); + wsptr^[DCTSIZE*1] := int (DEQUANTIZE(inptr^[DCTSIZE*4], quantptr^[DCTSIZE*4]); + + { Odd part } + + tmp6 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]); + tmp4 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]); + tmp7 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]); + tmp5 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]); + + + z13 := tmp6 + tmp5; + wsptr^[DCTSIZE*4] := int (tmp6 - tmp5); + + z11 := tmp4 + tmp7; + wsptr^[DCTSIZE*6] := int (tmp4 - tmp7); + + wsptr^[DCTSIZE*7] := int (z11 + z13); + wsptr^[DCTSIZE*5] := int (z11 - z13); + + wsptr^[DCTSIZE*3] := int (tmp1 + tmp3); + wsptr^[DCTSIZE*2] := int (tmp1 - tmp3); + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(IFAST_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + END; + + wsptr := @workspace[DCTSIZE*pred(DCTSIZE)]; + for row := pred(DCTSIZE) downto 0 do + BEGIN + { Odd part } + tmp5 := DCTELEM(wsptr^[1]); + tmp7 := DCTELEM(wsptr^[3]); + + { even part } + + {noop: + tmp0 := DCTELEM(wsptr^[0]); + wsptr^[0] := DCTELEM(tmp0);} + + {tmp2 := DCTELEM(wsptr^[4]);} + wsptr^[1] := wsptr^[4]; + + tmp1 := DCTELEM(wsptr^[2]); + tmp3 := DCTELEM(wsptr^[6]); + + wsptr^[2] := DCTELEM(tmp1 - tmp3); + wsptr^[3] := DCTELEM(tmp1 + tmp3); + + { Odd part } + tmp4 := DCTELEM(wsptr^[5]); + tmp6 := DCTELEM(wsptr^[7]); + + z13 := tmp4 + tmp7; + wsptr^[4] := DCTELEM(tmp4 - tmp7); + + z11 := tmp5 + tmp6; + wsptr^[6] := DCTELEM(tmp5 - tmp6); + + wsptr^[7] := DCTELEM(z11 + z13); + wsptr^[5] := DCTELEM(z11 - z13); + Dec(int_ptr(wsptr), DCTSIZE); { advance pointer to previous row } + END; + + { M x M tensor } + wsptr := @workspace[DCTSIZE*0]; + for row := 0 to pred(DCTSIZE) do + begin + Case row of + 0,1,3,7: { M1 } + begin + wsptr^[2] := Multiply(wsptr^[2], FP_IC4); { 2/c4 } + wsptr^[5] := Multiply(wsptr^[5], FP_IC4); { 2/c4 } + + N1(wsptr^[ 4], wsptr^[ 6]); + end; + 2,5: { M2 } + begin + wsptr^[0] := Multiply(wsptr^[0], FP_IC4); + wsptr^[1] := Multiply(wsptr^[1], FP_IC4); + wsptr^[3] := Multiply(wsptr^[3], FP_IC4); + wsptr^[7] := Multiply(wsptr^[7], FP_IC4); + + wsptr^[2] := wsptr^[2] * 2; { shift } + wsptr^[5] := wsptr^[5] * 2; + + N2(wsptr^[4], wsptr^[6]); + end; + end; { Case } + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; + + { M x N tensor } + { rows 4,6 } + begin + N1(workspace[DCTSIZE*4+0], workspace[DCTSIZE*6+0]); + N1(workspace[DCTSIZE*4+1], workspace[DCTSIZE*6+1]); + N1(workspace[DCTSIZE*4+3], workspace[DCTSIZE*6+3]); + N1(workspace[DCTSIZE*4+7], workspace[DCTSIZE*6+7]); + + N2(workspace[DCTSIZE*4+2], workspace[DCTSIZE*6+2]); + N2(workspace[DCTSIZE*4+5], workspace[DCTSIZE*6+5]); + + { N3 } + tmp0 := workspace[DCTSIZE*4,4]; + tmp1 := workspace[DCTSIZE*6,4]; + tmp2 := workspace[DCTSIZE*4,6]; + tmp3 := workspace[DCTSIZE*6,6]; + + { two inverse matrices => same as FDCT } + z10 := tmp0 - tmp3; + z11 := tmp1 + tmp2; + + z12 := tmp0 + tmp3; + z13 := tmp1 - tmp2; + + tmp0 := Multiply(z10 + z11, FP_I_C4_2); + tmp1 := Multiply(z10 - z11, FP_I_C4_2); + + tmp2 := z12 * 2; { shifts } + tmp3 := z13 * (-2); + + + workspace[DCTSIZE*4,4] := tmp2 + tmp0; + workspace[DCTSIZE*6,4] := tmp1 + tmp3; + + workspace[DCTSIZE*4,6] := tmp1 - tmp3; + workspace[DCTSIZE*6,6] := tmp2 - tmp0; + end; + + { R2 x R2 } + + wsptr := @workspace; + for row := 0 to pred(DCTSIZE) do + BEGIN + { even part } + tmp0 := wsptr^[0]; + tmp2 := wsptr^[1]; + tmp1 := wsptr^[2]; + tmp3 := wsptr^[3]; + + tmp10 := tmp0 + tmp2; + tmp11 := tmp0 - tmp2; + + tmp12 := tmp1 - tmp3; + tmp13 := tmp3; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + + tmp2 := tmp11 + tmp12; + tmp1 := tmp11 - tmp12; + + { Odd part } + tmp4 := wsptr^[4]; + tmp5 := wsptr^[5]; + tmp6 := wsptr^[6]; + tmp7 := wsptr^[7]; + + tmp6 := tmp6 - tmp7; + tmp5 := tmp5 - tmp6; + tmp4 :=-tmp4 - tmp5; + + wsptr^[0] := (tmp0 + tmp7); + wsptr^[7] := (tmp0 - tmp7); + + wsptr^[1] := (tmp2 + tmp6); + wsptr^[6] := (tmp2 - tmp6); + + wsptr^[2] := (tmp1 + tmp5); + wsptr^[5] := (tmp1 - tmp5); + + wsptr^[3] := (tmp3 + tmp4); + wsptr^[4] := (tmp3 - tmp4); + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + END; + + wsptr := @workspace; + for ctr := 0 to pred(DCTSIZE) do + BEGIN + outptr := JSAMPROW(@output_buf^[ctr]^[output_col]); + { even part } + tmp0 := wsptr[0]; + tmp1 := wsptr[1]; + tmp2 := wsptr[2]; + tmp3 := wsptr[3]; + + tmp10 := tmp0 + tmp1; + tmp11 := tmp0 - tmp1; + + tmp13 := tmp3; + tmp12 := tmp2 - tmp3; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + tmp4 := wsptr[4]; + tmp5 := wsptr[5]; + tmp6 := wsptr[6]; + tmp7 := wsptr[7]; + + tmp6 := tmp6 - tmp7; + tmp5 := tmp5 - tmp6; + tmp4 :=-tmp4 - tmp5; + + { Final output stage: scale down by a factor of 8 and range-limit } + + outptr^[0] := range_limit^[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[7] := range_limit^[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[1] := range_limit^[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[6] := range_limit^[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[2] := range_limit^[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[5] := range_limit^[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[4] := range_limit^[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[3] := range_limit^[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + and RANGE_MASK]; + Inc(int_ptr(wsptr)); + END; +End; {----------------------------------------} + + +{----------------------------------------------------------------------} + diff --git a/mseide-msegui/lib/common/fpccompatibility/jidctasm_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidctasm_del.pas new file mode 100644 index 0000000..a88e08f --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidctasm_del.pas @@ -0,0 +1,793 @@ +Unit JIDctAsm; + +{ This file contains a slow-but-accurate integer implementation of the + inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + must also perform dequantization of the input coefficients. + + A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + on each row (or vice versa, but it's more convenient to emit a row at + a time). Direct algorithms are also available, but they are much more + complex and seem not to be any faster when reduced to code. + + This implementation is based on an algorithm described in + C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + The primary algorithm described there uses 11 multiplies and 29 adds. + We use their alternate method with 12 multiplies and 32 adds. + The advantage of this method is that no data path contains more than one + multiplication; this allows a very simple and accurate implementation in + scaled fixed-point arithmetic, with a minimal number of shifts. } + +{ Original : jidctint.c ; Copyright (C) 1991-1996, Thomas G. Lane. } +{ ;------------------------------------------------------------------------- + ; JIDCTINT.ASM + ; 80386 protected mode assembly translation of JIDCTINT.C + ; **** Optimized to all hell by Jason M. Felice (jasonf@apk.net) **** + ; **** E-mail welcome **** + ; + ; ** This code does not make O/S calls -- use it for OS/2, Win95, WinNT, + ; ** DOS prot. mode., Linux, whatever... have fun. + ; + ; ** Note, this code is dependant on the structure member order in the .h + ; ** files for the following structures: + ; -- amazingly NOT j_decompress_struct... cool. + ; -- jpeg_component_info (dependant on position of dct_table element) + ; + ; Originally created with the /Fa option of MSVC 4.0 (why work when you + ; don't have to?) + ; + ; (this code, when compiled is 1K bytes smaller than the optimized MSVC + ; release build, not to mention 120-130 ms faster in my profile test with 1 + ; small color and and 1 medium black-and-white jpeg: stats using TASM 4.0 + ; and MSVC 4.0 to create a non-console app; jpeg_idct_islow accumulated + ; 5,760 hits on all trials) + ; + ; TASM -t -ml -os jidctint.asm, jidctint.obj + ;------------------------------------------------------------------------- + Converted to Delphi 2.0 BASM for PasJPEG + by Jacques NOMSSI NZALI + October 13th 1996 + * assumes Delphi "register" calling convention + first 3 parameter are in EAX,EDX,ECX + * register allocation revised +} + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg, + jinclude, + jpeglib, + jdct; { Private declarations for DCT subsystem } + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_islow (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + +{ The poop on this scaling stuff is as follows: + + Each 1-D IDCT step produces outputs which are a factor of sqrt(N) + larger than the true IDCT outputs. The final outputs are therefore + a factor of N larger than desired; since N=8 this can be cured by + a simple right shift at the end of the algorithm. The advantage of + this arrangement is that we save two multiplications per 1-D IDCT, + because the y0 and y4 inputs need not be divided by sqrt(N). + + We have to do addition and subtraction of the integer inputs, which + is no problem, and multiplication by fractional constants, which is + a problem to do in integer arithmetic. We multiply all the constants + by CONST_SCALE and convert them to integer constants (thus retaining + CONST_BITS bits of precision in the constants). After doing a + multiplication we have to divide the product by CONST_SCALE, with proper + rounding, to produce the correct output. This division can be done + cheaply as a right shift of CONST_BITS bits. We postpone shifting + as long as possible so that partial sums can be added together with + full fractional precision. + + The outputs of the first pass are scaled up by PASS1_BITS bits so that + they are represented to better-than-integral precision. These outputs + require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + with the recommended scaling. (To scale up 12-bit sample data further, an + intermediate INT32 array would be needed.) + + To avoid overflow of the 32-bit intermediate results in pass 2, we must + have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + shows that the values given below are the most effective. } + +const + CONST_BITS = 13; + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + PASS1_BITS = 2; +{$else} +const + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + +const + CONST_SCALE = (INT32(1) shl CONST_BITS); + +const + FIX_0_298631336 = INT32(Round(CONST_SCALE * 0.298631336)); {2446} + FIX_0_390180644 = INT32(Round(CONST_SCALE * 0.390180644)); {3196} + FIX_0_541196100 = INT32(Round(CONST_SCALE * 0.541196100)); {4433} + FIX_0_765366865 = INT32(Round(CONST_SCALE * 0.765366865)); {6270} + FIX_0_899976223 = INT32(Round(CONST_SCALE * 0.899976223)); {7373} + FIX_1_175875602 = INT32(Round(CONST_SCALE * 1.175875602)); {9633} + FIX_1_501321110 = INT32(Round(CONST_SCALE * 1.501321110)); {12299} + FIX_1_847759065 = INT32(Round(CONST_SCALE * 1.847759065)); {15137} + FIX_1_961570560 = INT32(Round(CONST_SCALE * 1.961570560)); {16069} + FIX_2_053119869 = INT32(Round(CONST_SCALE * 2.053119869)); {16819} + FIX_2_562915447 = INT32(Round(CONST_SCALE * 2.562915447)); {20995} + FIX_3_072711026 = INT32(Round(CONST_SCALE * 3.072711026)); {25172} + + +{ for DESCALE } +const + ROUND_CONST = (INT32(1) shl (CONST_BITS-PASS1_BITS-1)); +const + ROUND_CONST_2 = (INT32(1) shl (CONST_BITS+PASS1_BITS+3-1)); + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_islow (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = coef_bits_field; { buffers data between passes } +const + coefDCTSIZE = DCTSIZE*SizeOf(JCOEF); + wrkDCTSIZE = DCTSIZE*SizeOf(int); +var + tmp0, tmp1, tmp2, tmp3 : INT32; + tmp10, tmp11, tmp12, tmp13 : INT32; + z1, z2, z3, z4, z5 : INT32; +var + inptr : JCOEFPTR; + quantptr : ISLOW_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; +var + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; +var + dcval : int; +var + dcval_ : JSAMPLE; +asm + push edi + push esi + push ebx + + cld { The only direction we use, might as well set it now, as opposed } + { to inside 2 loops. } + +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + {range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE]));} + mov eax, [eax].jpeg_decompress_struct.sample_range_limit {eax=cinfo} + add eax, (MAXJSAMPLE+1 + CENTERJSAMPLE)*(Type JSAMPLE) + mov range_limit, eax + + { Pass 1: process columns from input, store into work array. } + { Note results are scaled up by sqrt(8) compared to a true IDCT; } + { furthermore, we scale the results by 2**PASS1_BITS. } + + {inptr := coef_block;} + mov esi, ecx { ecx=coef_block } + {quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table);} + mov edi, [edx].jpeg_component_info.dct_table { edx=compptr } + + {wsptr := PWorkspace(@workspace);} + lea ecx, workspace + + {for ctr := pred(DCTSIZE) downto 0 do + begin} + mov ctr, DCTSIZE +@loop518: + { Due to quantization, we will usually find that many of the input + coefficients are zero, especially the AC terms. We can exploit this + by short-circuiting the IDCT calculation for any column in which all + the AC terms are zero. In that case each output is equal to the + DC coefficient (with scale factor as needed). + With typical images and quantization tables, half or more of the + column DCT calculations can be simplified this way. } + + {if ((inptr^[DCTSIZE*1]) or (inptr^[DCTSIZE*2]) or (inptr^[DCTSIZE*3]) or + (inptr^[DCTSIZE*4]) or (inptr^[DCTSIZE*5]) or (inptr^[DCTSIZE*6]) or + (inptr^[DCTSIZE*7]) = 0) then + begin} + mov eax, DWORD PTR [esi+coefDCTSIZE*1] + or eax, DWORD PTR [esi+coefDCTSIZE*2] + or eax, DWORD PTR [esi+coefDCTSIZE*3] + mov edx, DWORD PTR [esi+coefDCTSIZE*4] + or eax, edx + or eax, DWORD PTR [esi+coefDCTSIZE*5] + or eax, DWORD PTR [esi+coefDCTSIZE*6] + or eax, DWORD PTR [esi+coefDCTSIZE*7] + jne @loop520 + + { AC terms all zero } + {dcval := ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * + (quantptr^[DCTSIZE*0]) shl PASS1_BITS;} + mov eax, DWORD PTR [esi+coefDCTSIZE*0] + imul eax, DWORD PTR [edi+wrkDCTSIZE*0] + shl eax, PASS1_BITS + + {wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + wsptr^[DCTSIZE*2] := dcval; + wsptr^[DCTSIZE*3] := dcval; + wsptr^[DCTSIZE*4] := dcval; + wsptr^[DCTSIZE*5] := dcval; + wsptr^[DCTSIZE*6] := dcval; + wsptr^[DCTSIZE*7] := dcval;} + + mov DWORD PTR [ecx+ wrkDCTSIZE*0], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*1], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*2], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*3], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*4], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*5], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*6], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*7], eax + + {Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + {Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + continue;} + dec ctr + je @loop519 + + add esi, Type JCOEF + add edi, Type ISLOW_MULT_TYPE + add ecx, Type int { int_ptr } + jmp @loop518 + +@loop520: + + {end;} + + { Even part: reverse the even part of the forward DCT. } + { The rotator is sqrt(2)*c(-6). } + + {z2 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*2]) * quantptr^[DCTSIZE*2]; + z3 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*6]) * quantptr^[DCTSIZE*6]; + + z1 := (z2 + z3) * INT32(FIX_0_541196100); + tmp2 := z1 + INT32(z3) * INT32(- FIX_1_847759065); + tmp3 := z1 + INT32(z2) * INT32(FIX_0_765366865);} + + mov edx, DWORD PTR [esi+coefDCTSIZE*2] + imul edx, DWORD PTR [edi+wrkDCTSIZE*2] {z2} + + mov eax, DWORD PTR [esi+coefDCTSIZE*6] + imul eax, DWORD PTR [edi+wrkDCTSIZE*6] {z3} + + lea ebx, [eax+edx] + imul ebx, FIX_0_541196100 {z1} + + imul eax, (-FIX_1_847759065) + add eax, ebx + mov tmp2, eax + + imul edx, FIX_0_765366865 + add edx, ebx + mov tmp3, edx + + {z2 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * quantptr^[DCTSIZE*0]; + z3 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*4]) * quantptr^[DCTSIZE*4];} + + mov edx, DWORD PTR [esi+coefDCTSIZE*4] + imul edx, DWORD PTR [edi+wrkDCTSIZE*4] { z3 = edx } + + mov eax, DWORD PTR [esi+coefDCTSIZE*0] + imul eax, DWORD PTR [edi+wrkDCTSIZE*0] { z2 = eax } + + {tmp0 := (z2 + z3) shl CONST_BITS; + tmp1 := (z2 - z3) shl CONST_BITS;} + lea ebx,[eax+edx] + sub eax, edx + shl ebx, CONST_BITS { tmp0 = ebx } + shl eax, CONST_BITS { tmp1 = eax } + + {tmp10 := tmp0 + tmp3; + tmp13 := tmp0 - tmp3;} + mov edx, tmp3 + sub ebx, edx + mov tmp13, ebx + add edx, edx + add ebx, edx + mov tmp10, ebx + + {tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2;} + mov ebx, tmp2 + sub eax, ebx + mov tmp12, eax + add ebx, ebx + add eax, ebx + mov tmp11, eax + + { Odd part per figure 8; the matrix is unitary and hence its + transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. } + + {tmp0 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*7]) * quantptr^[DCTSIZE*7];} + mov eax, DWORD PTR [esi+coefDCTSIZE*7] + imul eax, DWORD PTR [edi+wrkDCTSIZE*7] + mov edx, eax { edx = tmp0 } + {tmp0 := (tmp0) * INT32(FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + imul eax, FIX_0_298631336 + mov tmp0, eax + + {tmp3 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*1]) * quantptr^[DCTSIZE*1];} + mov eax, DWORD PTR [esi+coefDCTSIZE*1] + imul eax, DWORD PTR [edi+wrkDCTSIZE*1] + mov tmp3, eax + + {z1 := tmp0 + tmp3;} + {z1 := (z1) * INT32(- FIX_0_899976223); { sqrt(2) * (c7-c3) } + add eax, edx + imul eax, (-FIX_0_899976223) + mov z1, eax + + {tmp1 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*5]) * quantptr^[DCTSIZE*5];} + mov eax, DWORD PTR [esi+coefDCTSIZE*5] + imul eax, DWORD PTR [edi+wrkDCTSIZE*5] + mov ebx, eax { ebx = tmp1 } + {tmp1 := (tmp1) * INT32(FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + imul eax, FIX_2_053119869 + mov tmp1, eax + + {tmp2 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*3]) * quantptr^[DCTSIZE*3];} + mov eax, DWORD PTR [esi+coefDCTSIZE*3] + imul eax, DWORD PTR [edi+wrkDCTSIZE*3] + mov tmp2, eax + + {z3 := tmp0 + tmp2;} + add edx, eax { edx = z3 } + + {z2 := tmp1 + tmp2;} + {z2 := (z2) * INT32(- FIX_2_562915447); { sqrt(2) * (-c1-c3) } + add eax, ebx + imul eax, (-FIX_2_562915447) + mov z2, eax + + {z4 := tmp1 + tmp3;} + add ebx, tmp3 { ebx = z4 } + + {z5 := INT32(z3 + z4) * INT32(FIX_1_175875602); { sqrt(2) * c3 } + lea eax, [edx+ebx] + imul eax, FIX_1_175875602 { eax = z5 } + + {z4 := (z4) * INT32(- FIX_0_390180644); { sqrt(2) * (c5-c3) } + {Inc(z4, z5);} + imul ebx, (-FIX_0_390180644) + add ebx, eax + mov z4, ebx + + {z3 := (z3) * INT32(- FIX_1_961570560); { sqrt(2) * (-c3-c5) } + {Inc(z3, z5);} + imul edx, (-FIX_1_961570560) + add eax, edx { z3 = eax } + + {Inc(tmp0, z1 + z3);} + mov ebx, z1 + add ebx, eax + add tmp0, ebx + + {tmp2 := (tmp2) * INT32(FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + {Inc(tmp2, z2 + z3);} + mov ebx, tmp2 + imul ebx, FIX_3_072711026 + mov edx, z2 { z2 = edx } + add ebx, edx + add eax, ebx + mov tmp2, eax + + {Inc(tmp1, z2 + z4);} + mov eax, z4 { z4 = eax } + add edx, eax + add tmp1, edx + + {tmp3 := (tmp3) * INT32(FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + {Inc(tmp3, z1 + z4);} + mov edx, tmp3 + imul edx, FIX_1_501321110 + + add edx, eax + add edx, z1 { tmp3 = edx } + + { Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 } + + {wsptr^[DCTSIZE*0] := int (DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS));} + {wsptr^[DCTSIZE*7] := int (DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS));} + mov eax, tmp10 + add eax, ROUND_CONST + lea ebx, [eax+edx] + sar ebx, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*0], ebx + + sub eax, edx + sar eax, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*7], eax + + {wsptr^[DCTSIZE*1] := int (DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS));} + {wsptr^[DCTSIZE*6] := int (DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS));} + mov eax, tmp11 + add eax, ROUND_CONST + mov edx, tmp2 + lea ebx, [eax+edx] + sar ebx, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*1], ebx + + sub eax, edx + sar eax, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*6], eax + + {wsptr^[DCTSIZE*2] := int (DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS));} + {wsptr^[DCTSIZE*5] := int (DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS));} + mov eax, tmp12 + add eax, ROUND_CONST + mov edx, tmp1 + lea ebx, [eax+edx] + sar ebx, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*2], ebx + + sub eax, edx + sar eax, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*5], eax + + {wsptr^[DCTSIZE*3] := int (DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS));} + {wsptr^[DCTSIZE*4] := int (DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS));} + mov eax, tmp13 + add eax, ROUND_CONST + mov edx, tmp0 + lea ebx, [eax+edx] + sar ebx, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*3], ebx + + sub eax, edx + sar eax, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*4], eax + + {Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + {Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr));} + dec ctr + je @loop519 + + add esi, Type JCOEF + add edi, Type ISLOW_MULT_TYPE + add ecx, Type int { int_ptr } + {end;} + jmp @loop518 +@loop519: + { Save to memory what we've registerized for the preceding loop. } + + { Pass 2: process rows from work array, store into output array. } + { Note that we must descale the results by a factor of 8 == 2**3, } + { and also undo the PASS1_BITS scaling. } + + {wsptr := @workspace;} + lea esi, workspace + + {for ctr := 0 to pred(DCTSIZE) do + begin} + mov ctr, 0 +@loop523: + + {outptr := output_buf^[ctr];} + mov eax, ctr + mov ebx, output_buf + mov edi, DWORD PTR [ebx+eax*4] { 4 = SizeOf(pointer) } + + {Inc(JSAMPLE_PTR(outptr), output_col);} + add edi, output_col + + { Rows of zeroes can be exploited in the same way as we did with columns. + However, the column calculation has created many nonzero AC terms, so + the simplification applies less often (typically 5% to 10% of the time). + On machines with very fast multiplication, it's possible that the + test takes more time than it's worth. In that case this section + may be commented out. } + +{$ifndef NO_ZERO_ROW_TEST} + {if ((wsptr^[1]) or (wsptr^[2]) or (wsptr^[3]) or (wsptr^[4]) or + (wsptr^[5]) or (wsptr^[6]) or (wsptr^[7]) = 0) then + begin} + mov eax, DWORD PTR [esi+4*1] + or eax, DWORD PTR [esi+4*2] + or eax, DWORD PTR [esi+4*3] + jne @loop525 { Nomssi: early exit path may help } + or eax, DWORD PTR [esi+4*4] + or eax, DWORD PTR [esi+4*5] + or eax, DWORD PTR [esi+4*6] + or eax, DWORD PTR [esi+4*7] + jne @loop525 + + { AC terms all zero } + {JSAMPLE(dcval_) := range_limit^[int(DESCALE(INT32(wsptr^[0]), + PASS1_BITS+3)) and RANGE_MASK];} + mov eax, DWORD PTR [esi+4*0] + add eax, (INT32(1) shl (PASS1_BITS+3-1)) + sar eax, PASS1_BITS+3 + and eax, RANGE_MASK + mov ebx, range_limit + mov al, BYTE PTR [ebx+eax] + mov ah, al + + {outptr^[0] := dcval_; + outptr^[1] := dcval_; + outptr^[2] := dcval_; + outptr^[3] := dcval_; + outptr^[4] := dcval_; + outptr^[5] := dcval_; + outptr^[6] := dcval_; + outptr^[7] := dcval_;} + + stosw + stosw + stosw + stosw + + {Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + {continue;} + add esi, wrkDCTSIZE + inc ctr + cmp ctr, DCTSIZE + jl @loop523 + jmp @loop524 + {end;} +@loop525: +{$endif} + + + { Even part: reverse the even part of the forward DCT. } + { The rotator is sqrt(2)*c(-6). } + + {z2 := INT32 (wsptr^[2]);} + mov edx, DWORD PTR [esi+4*2] { z2 = edx } + + {z3 := INT32 (wsptr^[6]);} + mov ecx, DWORD PTR [esi+4*6] { z3 = ecx } + + {z1 := (z2 + z3) * INT32(FIX_0_541196100);} + lea eax, [edx+ecx] + imul eax, FIX_0_541196100 + mov ebx, eax { z1 = ebx } + + {tmp2 := z1 + (z3) * INT32(- FIX_1_847759065);} + imul ecx, (-FIX_1_847759065) + add ecx, ebx { tmp2 = ecx } + + {tmp3 := z1 + (z2) * INT32(FIX_0_765366865);} + imul edx, FIX_0_765366865 + add ebx, edx { tmp3 = ebx } + + {tmp0 := (INT32(wsptr^[0]) + INT32(wsptr^[4])) shl CONST_BITS;} + {tmp1 := (INT32(wsptr^[0]) - INT32(wsptr^[4])) shl CONST_BITS;} + mov edx, DWORD PTR [esi+4*4] + mov eax, DWORD PTR [esi+4*0] + sub eax, edx + add edx, edx + add edx, eax + shl edx, CONST_BITS { tmp0 = edx } + shl eax, CONST_BITS { tmp1 = eax } + + {tmp10 := tmp0 + tmp3;} + {tmp13 := tmp0 - tmp3;} + sub edx, ebx + mov tmp13, edx + add ebx, ebx + add edx, ebx + mov tmp10, edx + + {tmp11 := tmp1 + tmp2;} + {tmp12 := tmp1 - tmp2;} + lea ebx, [ecx+eax] + mov tmp11, ebx + sub eax, ecx + mov tmp12, eax + + { Odd part per figure 8; the matrix is unitary and hence its + transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. } + +{ The following lines no longer produce code, since wsptr has been + optimized to esi, it is more efficient to access these values + directly. + tmp0 := INT32(wsptr^[7]); + tmp1 := INT32(wsptr^[5]); + tmp2 := INT32(wsptr^[3]); + tmp3 := INT32(wsptr^[1]); } + + {z2 := tmp1 + tmp2;} + {z2 := (z2) * INT32(- FIX_2_562915447); { sqrt(2) * (-c1-c3) } + mov ebx, DWORD PTR [esi+4*3] { tmp2 } + mov ecx, DWORD PTR [esi+4*5] { tmp1 } + lea eax, [ebx+ecx] + imul eax, (-FIX_2_562915447) + mov z2, eax + + {z3 := tmp0 + tmp2;} + mov edx, DWORD PTR [esi+4*7] { tmp0 } + add ebx, edx { old z3 = ebx } + mov eax, ebx + {z3 := (z3) * INT32(- FIX_1_961570560); { sqrt(2) * (-c3-c5) } + imul eax, (-FIX_1_961570560) + mov z3, eax + + {z1 := tmp0 + tmp3;} + {z1 := (z1) * INT32(- FIX_0_899976223); { sqrt(2) * (c7-c3) } + mov eax, DWORD PTR [esi+4*1] { tmp3 } + add edx, eax + imul edx, (-FIX_0_899976223) { z1 = edx } + + {z4 := tmp1 + tmp3;} + add eax, ecx { +tmp1 } + add ebx, eax { z3 + z4 = ebx } + {z4 := (z4) * INT32(- FIX_0_390180644); { sqrt(2) * (c5-c3) } + imul eax, (-FIX_0_390180644) { z4 = eax } + + {z5 := (z3 + z4) * INT32(FIX_1_175875602); { sqrt(2) * c3 } + {Inc(z3, z5);} + imul ebx, FIX_1_175875602 + mov ecx, z3 + add ecx, ebx { ecx = z3 } + + {Inc(z4, z5);} + add ebx, eax { z4 = ebx } + + {tmp0 := (tmp0) * INT32(FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + {Inc(tmp0, z1 + z3);} + mov eax, DWORD PTR [esi+4*7] + imul eax, FIX_0_298631336 + add eax, edx + add eax, ecx + mov tmp0, eax + + {tmp1 := (tmp1) * INT32(FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + {Inc(tmp1, z2 + z4);} + mov eax, DWORD PTR [esi+4*5] + imul eax, FIX_2_053119869 + add eax, z2 + add eax, ebx + mov tmp1, eax + + {tmp2 := (tmp2) * INT32(FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + {Inc(tmp2, z2 + z3);} + mov eax, DWORD PTR [esi+4*3] + imul eax, FIX_3_072711026 + add eax, z2 + add ecx, eax { ecx = tmp2 } + + {tmp3 := (tmp3) * INT32(FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + {Inc(tmp3, z1 + z4);} + mov eax, DWORD PTR [esi+4*1] + imul eax, FIX_1_501321110 + add eax, edx + add ebx, eax { ebx = tmp3 } + + { Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 } + + {outptr^[0] := range_limit^[ int(DESCALE(tmp10 + tmp3, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK]; } + {outptr^[7] := range_limit^[ int(DESCALE(tmp10 - tmp3, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + + mov edx, tmp10 + add edx, ROUND_CONST_2 + lea eax, [ebx+edx] + sub edx, ebx + + shr eax, CONST_BITS+PASS1_BITS+3 + and eax, RANGE_MASK + mov ebx, range_limit { once for all } + mov al, BYTE PTR [ebx+eax] + mov [edi+0], al + + shr edx, CONST_BITS+PASS1_BITS+3 + and edx, RANGE_MASK + mov al, BYTE PTR [ebx+edx] + mov [edi+7], al + + {outptr^[1] := range_limit^[ int(DESCALE(tmp11 + tmp2, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + mov eax, tmp11 + add eax, ROUND_CONST_2 + lea edx, [eax+ecx] + shr edx, CONST_BITS+PASS1_BITS+3 + and edx, RANGE_MASK + mov dl, BYTE PTR [ebx+edx] + mov [edi+1], dl + + {outptr^[6] := range_limit^[ int(DESCALE(tmp11 - tmp2, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + sub eax, ecx + shr eax, CONST_BITS+PASS1_BITS+3 + and eax, RANGE_MASK + mov al, BYTE PTR [ebx+eax] + mov [edi+6], al + + {outptr^[2] := range_limit^[ int(DESCALE(tmp12 + tmp1, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + mov eax, tmp12 + add eax, ROUND_CONST_2 + mov ecx, tmp1 + lea edx, [eax+ecx] + shr edx, CONST_BITS+PASS1_BITS+3 + and edx, RANGE_MASK + mov dl, BYTE PTR [ebx+edx] + mov [edi+2], dl + + {outptr^[5] := range_limit^[ int(DESCALE(tmp12 - tmp1, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + sub eax, ecx + shr eax, CONST_BITS+PASS1_BITS+3 + and eax, RANGE_MASK + mov al, BYTE PTR [ebx+eax] + mov [edi+5], al + + {outptr^[3] := range_limit^[ int(DESCALE(tmp13 + tmp0, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + mov eax, tmp13 + add eax, ROUND_CONST_2 + mov ecx, tmp0 + lea edx, [eax+ecx] + shr edx, CONST_BITS+PASS1_BITS+3 + and edx, RANGE_MASK + mov dl, BYTE PTR [ebx+edx] + mov [edi+3], dl + + {outptr^[4] := range_limit^[ int(DESCALE(tmp13 - tmp0, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + sub eax, ecx + shr eax, CONST_BITS+PASS1_BITS+3 + and eax, RANGE_MASK + mov al, BYTE PTR [ebx+eax] + mov [edi+4], al + + {Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + add esi, wrkDCTSIZE + add edi, DCTSIZE + + {end;} + inc ctr + cmp ctr, DCTSIZE + jl @loop523 + +@loop524: +@loop496: + pop ebx + pop esi + pop edi +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jidctflt_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidctflt_del.pas new file mode 100644 index 0000000..8c8ca3c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidctflt_del.pas @@ -0,0 +1,287 @@ +unit jidctflt_del; + +//{$N+} +{ This file contains a floating-point implementation of the + inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + must also perform dequantization of the input coefficients. + + This implementation should be more accurate than either of the integer + IDCT implementations. However, it may not give the same results on all + machines because of differences in roundoff behavior. Speed will depend + on the hardware's floating point capacity. + + A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + on each row (or vice versa, but it's more convenient to emit a row at + a time). Direct algorithms are also available, but they are much more + complex and seem not to be any faster when reduced to code. + + This implementation is based on Arai, Agui, and Nakajima's algorithm for + scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + Japanese, but the algorithm is described in the Pennebaker & Mitchell + JPEG textbook (see REFERENCES section in file README). The following code + is based directly on figure 4-8 in P&M. + While an 8-point DCT cannot be done in less than 11 multiplies, it is + possible to arrange the computation so that many of the multiplies are + simple scalings of the final outputs. These multiplies can then be + folded into the multiplications or divisions by the JPEG quantization + table entries. The AA&N method leaves only 5 multiplies and 29 adds + to be done in the DCT itself. + The primary disadvantage of this method is that with a fixed-point + implementation, accuracy is lost due to imprecise representation of the + scaled quantization values. However, that problem does not arise if + we use floating point arithmetic. } + +{ Original: jidctflt.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_float (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + + +{ Dequantize a coefficient by multiplying it by the multiplier-table + entry; produce a float result. } + +function DEQUANTIZE(coef : int; quantval : FAST_FLOAT) : FAST_FLOAT; +begin + Dequantize := ( (coef) * quantval); +end; + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + shift_temp := x + (INT32(1) shl (n-1)); + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + Descale := (shift_temp shr n); +{$else} + Descale := (x + (INT32(1) shl (n-1)) shr n; +{$endif} +end; + + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_float (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = array[0..DCTSIZE2-1] of FAST_FLOAT; +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : FAST_FLOAT; + tmp10, tmp11, tmp12, tmp13 : FAST_FLOAT; + z5, z10, z11, z12, z13 : FAST_FLOAT; + inptr : JCOEFPTR; + quantptr : FLOAT_MULT_TYPE_FIELD_PTR; + wsptr : PWorkSpace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS} +var + dcval : FAST_FLOAT; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := FLOAT_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + wsptr := @workspace; + for ctr := pred(DCTSIZE) downto 0 do + begin + { Due to quantization, we will usually find that many of the input + coefficients are zero, especially the AC terms. We can exploit this + by short-circuiting the IDCT calculation for any column in which all + the AC terms are zero. In that case each output is equal to the + DC coefficient (with scale factor as needed). + With typical images and quantization tables, half or more of the + column DCT calculations can be simplified this way. } + + if (inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*2]=0) and + (inptr^[DCTSIZE*3]=0) and (inptr^[DCTSIZE*4]=0) and + (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*6]=0) and + (inptr^[DCTSIZE*7]=0) then + begin + { AC terms all zero } + FAST_FLOAT(dcval) := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]); + + wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + wsptr^[DCTSIZE*2] := dcval; + wsptr^[DCTSIZE*3] := dcval; + wsptr^[DCTSIZE*4] := dcval; + wsptr^[DCTSIZE*5] := dcval; + wsptr^[DCTSIZE*6] := dcval; + wsptr^[DCTSIZE*7] := dcval; + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(FLOAT_MULT_TYPE_PTR(quantptr)); + Inc(FAST_FLOAT_PTR(wsptr)); + continue; + end; + + { Even part } + + tmp0 := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]); + tmp1 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]); + tmp2 := DEQUANTIZE(inptr^[DCTSIZE*4], quantptr^[DCTSIZE*4]); + tmp3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]); + + tmp10 := tmp0 + tmp2; { phase 3 } + tmp11 := tmp0 - tmp2; + + tmp13 := tmp1 + tmp3; { phases 5-3 } + tmp12 := (tmp1 - tmp3) * ({FAST_FLOAT}(1.414213562)) - tmp13; { 2*c4 } + + tmp0 := tmp10 + tmp13; { phase 2 } + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + tmp4 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]); + tmp5 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]); + tmp6 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]); + tmp7 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]); + + z13 := tmp6 + tmp5; { phase 6 } + z10 := tmp6 - tmp5; + z11 := tmp4 + tmp7; + z12 := tmp4 - tmp7; + + tmp7 := z11 + z13; { phase 5 } + tmp11 := (z11 - z13) * ({FAST_FLOAT}(1.414213562)); { 2*c4 } + + z5 := (z10 + z12) * ({FAST_FLOAT}(1.847759065)); { 2*c2 } + tmp10 := ({FAST_FLOAT}(1.082392200)) * z12 - z5; { 2*(c2-c6) } + tmp12 := ({FAST_FLOAT}(-2.613125930)) * z10 + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; { phase 2 } + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + wsptr^[DCTSIZE*0] := tmp0 + tmp7; + wsptr^[DCTSIZE*7] := tmp0 - tmp7; + wsptr^[DCTSIZE*1] := tmp1 + tmp6; + wsptr^[DCTSIZE*6] := tmp1 - tmp6; + wsptr^[DCTSIZE*2] := tmp2 + tmp5; + wsptr^[DCTSIZE*5] := tmp2 - tmp5; + wsptr^[DCTSIZE*4] := tmp3 + tmp4; + wsptr^[DCTSIZE*3] := tmp3 - tmp4; + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(FLOAT_MULT_TYPE_PTR(quantptr)); + Inc(FAST_FLOAT_PTR(wsptr)); + end; + + { Pass 2: process rows from work array, store into output array. } + { Note that we must descale the results by a factor of 8 = 2**3. } + + wsptr := @workspace; + for ctr := 0 to pred(DCTSIZE) do + begin + outptr := JSAMPROW(@(output_buf^[ctr]^[output_col])); + { Rows of zeroes can be exploited in the same way as we did with columns. + However, the column calculation has created many nonzero AC terms, so + the simplification applies less often (typically 5% to 10% of the time). + And testing floats for zero is relatively expensive, so we don't bother. } + + { Even part } + + tmp10 := wsptr^[0] + wsptr^[4]; + tmp11 := wsptr^[0] - wsptr^[4]; + + tmp13 := wsptr^[2] + wsptr^[6]; + tmp12 := (wsptr^[2] - wsptr^[6]) * ({FAST_FLOAT}(1.414213562)) - tmp13; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + z13 := wsptr^[5] + wsptr^[3]; + z10 := wsptr^[5] - wsptr^[3]; + z11 := wsptr^[1] + wsptr^[7]; + z12 := wsptr^[1] - wsptr^[7]; + + tmp7 := z11 + z13; + tmp11 := (z11 - z13) * ({FAST_FLOAT}(1.414213562)); + + z5 := (z10 + z12) * ({FAST_FLOAT}(1.847759065)); { 2*c2 } + tmp10 := ({FAST_FLOAT}(1.082392200)) * z12 - z5; { 2*(c2-c6) } + tmp12 := ({FAST_FLOAT}(-2.613125930)) * z10 + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + { Final output stage: scale down by a factor of 8 and range-limit } + + outptr^[0] := range_limit^[ int(DESCALE( INT32(Round((tmp0 + tmp7))), 3)) + and RANGE_MASK]; + outptr^[7] := range_limit^[ int(DESCALE( INT32(Round((tmp0 - tmp7))), 3)) + and RANGE_MASK]; + outptr^[1] := range_limit^[ int(DESCALE( INT32(Round((tmp1 + tmp6))), 3)) + and RANGE_MASK]; + outptr^[6] := range_limit^[ int(DESCALE( INT32(Round((tmp1 - tmp6))), 3)) + and RANGE_MASK]; + outptr^[2] := range_limit^[ int(DESCALE( INT32(Round((tmp2 + tmp5))), 3)) + and RANGE_MASK]; + outptr^[5] := range_limit^[ int(DESCALE( INT32(Round((tmp2 - tmp5))), 3)) + and RANGE_MASK]; + outptr^[4] := range_limit^[ int(DESCALE( INT32(Round((tmp3 + tmp4))), 3)) + and RANGE_MASK]; + outptr^[3] := range_limit^[ int(DESCALE( INT32(Round((tmp3 - tmp4))), 3)) + and RANGE_MASK]; + + Inc(FAST_FLOAT_PTR(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jidctfst_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidctfst_del.pas new file mode 100644 index 0000000..9b3d390 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidctfst_del.pas @@ -0,0 +1,411 @@ +unit jidctfst_del; + +{ This file contains a fast, not so accurate integer implementation of the + inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + must also perform dequantization of the input coefficients. + + A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + on each row (or vice versa, but it's more convenient to emit a row at + a time). Direct algorithms are also available, but they are much more + complex and seem not to be any faster when reduced to code. + + This implementation is based on Arai, Agui, and Nakajima's algorithm for + scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + Japanese, but the algorithm is described in the Pennebaker & Mitchell + JPEG textbook (see REFERENCES section in file README). The following code + is based directly on figure 4-8 in P&M. + While an 8-point DCT cannot be done in less than 11 multiplies, it is + possible to arrange the computation so that many of the multiplies are + simple scalings of the final outputs. These multiplies can then be + folded into the multiplications or divisions by the JPEG quantization + table entries. The AA&N method leaves only 5 multiplies and 29 adds + to be done in the DCT itself. + The primary disadvantage of this method is that with fixed-point math, + accuracy is lost due to imprecise representation of the scaled + quantization values. The smaller the quantization table entry, the less + precise the scaled value, so this implementation does worse with high- + quality-setting files than with low-quality ones. } + +{ Original : jidctfst.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_ifast (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + +{ Scaling decisions are generally the same as in the LL&M algorithm; + see jidctint.c for more details. However, we choose to descale + (right shift) multiplication products as soon as they are formed, + rather than carrying additional fractional bits into subsequent additions. + This compromises accuracy slightly, but it lets us save a few shifts. + More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + everywhere except in the multiplications proper; this saves a good deal + of work on 16-bit-int machines. + + The dequantized coefficients are not integers because the AA&N scaling + factors have been incorporated. We represent them scaled up by PASS1_BITS, + so that the first and second IDCT rounds have the same input scaling. + For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to + avoid a descaling shift; this compromises accuracy rather drastically + for small quantization table entries, but it saves a lot of shifts. + For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway, + so we use a much larger scaling factor to preserve accuracy. + + A final compromise is to represent the multiplicative constants to only + 8 fractional bits, rather than 13. This saves some shifting work on some + machines, and may also reduce the cost of multiplication (since there + are fewer one-bits in the constants). } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + CONST_BITS = 8; + PASS1_BITS = 2; +{$else} +const + CONST_BITS = 8; + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + + +const + FIX_1_082392200 = INT32(Round((INT32(1) shl CONST_BITS)*1.082392200)); {277} + FIX_1_414213562 = INT32(Round((INT32(1) shl CONST_BITS)*1.414213562)); {362} + FIX_1_847759065 = INT32(Round((INT32(1) shl CONST_BITS)*1.847759065)); {473} + FIX_2_613125930 = INT32(Round((INT32(1) shl CONST_BITS)*2.613125930)); {669} + + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef USE_ACCURATE_ROUNDING} + shift_temp := x + (INT32(1) shl (n-1)); +{$else} +{ We can gain a little more speed, with a further compromise in accuracy, + by omitting the addition in a descaling shift. This yields an incorrectly + rounded result half the time... } + shift_temp := x; +{$endif} + +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else +{$endif} + Descale := (shift_temp shr n); +end; + + +{ Multiply a DCTELEM variable by an INT32 constant, and immediately + descale to yield a DCTELEM result. } + + {(DCTELEM( DESCALE((var) * (const), CONST_BITS))} + function Multiply(Avar, Aconst: Integer): DCTELEM; + begin + Multiply := DCTELEM( Avar*INT32(Aconst) div (INT32(1) shl CONST_BITS)); + end; + + +{ Dequantize a coefficient by multiplying it by the multiplier-table + entry; produce a DCTELEM result. For 8-bit data a 16x16->16 + multiplication will do. For 12-bit data, the multiplier table is + declared INT32, so a 32-bit multiply will be used. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} + function DEQUANTIZE(coef,quantval : int) : int; + begin + Dequantize := ( IFAST_MULT_TYPE(coef) * quantval); + end; +{$else} + function DEQUANTIZE(coef,quantval : INT32) : int; + begin + Dequantize := DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS); + end; +{$endif} + + +{ Like DESCALE, but applies to a DCTELEM and produces an int. + We assume that int right shift is unsigned if INT32 right shift is. } + +function IDESCALE(x : DCTELEM; n : int) : int; +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + DCTELEMBITS = 16; { DCTELEM may be 16 or 32 bits } +{$else} +const + DCTELEMBITS = 32; { DCTELEM must be 32 bits } +{$endif} +var + ishift_temp : DCTELEM; +begin +{$ifndef USE_ACCURATE_ROUNDING} + ishift_temp := x + (INT32(1) shl (n-1)); +{$else} +{ We can gain a little more speed, with a further compromise in accuracy, + by omitting the addition in a descaling shift. This yields an incorrectly + rounded result half the time... } + ishift_temp := x; +{$endif} + +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if ishift_temp < 0 then + IDescale := (ishift_temp shr n) + or ((not DCTELEM(0)) shl (DCTELEMBITS-n)) + else +{$endif} + IDescale := (ishift_temp shr n); +end; + + + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_ifast (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = coef_bits_field; { buffers data between passes } +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : DCTELEM; + tmp10, tmp11, tmp12, tmp13 : DCTELEM; + z5, z10, z11, z12, z13 : DCTELEM; + inptr : JCOEFPTR; + quantptr : IFAST_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS} { for DESCALE } + {ISHIFT_TEMPS} { for IDESCALE } +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := IFAST_MULT_TYPE_FIELD_PTR(compptr^.dct_table); + wsptr := @workspace; + for ctr := pred(DCTSIZE) downto 0 do + begin + { Due to quantization, we will usually find that many of the input + coefficients are zero, especially the AC terms. We can exploit this + by short-circuiting the IDCT calculation for any column in which all + the AC terms are zero. In that case each output is equal to the + DC coefficient (with scale factor as needed). + With typical images and quantization tables, half or more of the + column DCT calculations can be simplified this way. } + + if (inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*2]=0) and (inptr^[DCTSIZE*3]=0) and + (inptr^[DCTSIZE*4]=0) and (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*6]=0) and + (inptr^[DCTSIZE*7]=0) then + begin + { AC terms all zero } + dcval := int(DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0])); + + wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + wsptr^[DCTSIZE*2] := dcval; + wsptr^[DCTSIZE*3] := dcval; + wsptr^[DCTSIZE*4] := dcval; + wsptr^[DCTSIZE*5] := dcval; + wsptr^[DCTSIZE*6] := dcval; + wsptr^[DCTSIZE*7] := dcval; + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(IFAST_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + continue; + end; + + { Even part } + + tmp0 := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]); + tmp1 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]); + tmp2 := DEQUANTIZE(inptr^[DCTSIZE*4], quantptr^[DCTSIZE*4]); + tmp3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]); + + tmp10 := tmp0 + tmp2; { phase 3 } + tmp11 := tmp0 - tmp2; + + tmp13 := tmp1 + tmp3; { phases 5-3 } + tmp12 := MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; { 2*c4 } + + tmp0 := tmp10 + tmp13; { phase 2 } + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + tmp4 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]); + tmp5 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]); + tmp6 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]); + tmp7 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]); + + z13 := tmp6 + tmp5; { phase 6 } + z10 := tmp6 - tmp5; + z11 := tmp4 + tmp7; + z12 := tmp4 - tmp7; + + tmp7 := z11 + z13; { phase 5 } + tmp11 := MULTIPLY(z11 - z13, FIX_1_414213562); { 2*c4 } + + z5 := MULTIPLY(z10 + z12, FIX_1_847759065); { 2*c2 } + tmp10 := MULTIPLY(z12, FIX_1_082392200) - z5; { 2*(c2-c6) } + tmp12 := MULTIPLY(z10, - FIX_2_613125930) + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; { phase 2 } + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + wsptr^[DCTSIZE*0] := int (tmp0 + tmp7); + wsptr^[DCTSIZE*7] := int (tmp0 - tmp7); + wsptr^[DCTSIZE*1] := int (tmp1 + tmp6); + wsptr^[DCTSIZE*6] := int (tmp1 - tmp6); + wsptr^[DCTSIZE*2] := int (tmp2 + tmp5); + wsptr^[DCTSIZE*5] := int (tmp2 - tmp5); + wsptr^[DCTSIZE*4] := int (tmp3 + tmp4); + wsptr^[DCTSIZE*3] := int (tmp3 - tmp4); + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(IFAST_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + end; + + { Pass 2: process rows from work array, store into output array. } + { Note that we must descale the results by a factor of 8 == 2**3, } + { and also undo the PASS1_BITS scaling. } + + wsptr := @workspace; + for ctr := 0 to pred(DCTSIZE) do + begin + outptr := JSAMPROW(@output_buf^[ctr]^[output_col]); + { Rows of zeroes can be exploited in the same way as we did with columns. + However, the column calculation has created many nonzero AC terms, so + the simplification applies less often (typically 5% to 10% of the time). + On machines with very fast multiplication, it's possible that the + test takes more time than it's worth. In that case this section + may be commented out. } + +{$ifndef NO_ZERO_ROW_TEST} + if (wsptr^[1]=0) and (wsptr^[2]=0) and (wsptr^[3]=0) and (wsptr^[4]=0) and + (wsptr^[5]=0) and (wsptr^[6]=0) and (wsptr^[7]=0) then + begin + { AC terms all zero } + dcval_ := range_limit^[IDESCALE(wsptr^[0], PASS1_BITS+3) + and RANGE_MASK]; + + outptr^[0] := dcval_; + outptr^[1] := dcval_; + outptr^[2] := dcval_; + outptr^[3] := dcval_; + outptr^[4] := dcval_; + outptr^[5] := dcval_; + outptr^[6] := dcval_; + outptr^[7] := dcval_; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + continue; + end; +{$endif} + + { Even part } + + tmp10 := (DCTELEM(wsptr^[0]) + DCTELEM(wsptr^[4])); + tmp11 := (DCTELEM(wsptr^[0]) - DCTELEM(wsptr^[4])); + + tmp13 := (DCTELEM(wsptr^[2]) + DCTELEM(wsptr^[6])); + tmp12 := MULTIPLY(DCTELEM(wsptr^[2]) - DCTELEM(wsptr^[6]), FIX_1_414213562) + - tmp13; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + z13 := DCTELEM(wsptr^[5]) + DCTELEM(wsptr^[3]); + z10 := DCTELEM(wsptr^[5]) - DCTELEM(wsptr^[3]); + z11 := DCTELEM(wsptr^[1]) + DCTELEM(wsptr^[7]); + z12 := DCTELEM(wsptr^[1]) - DCTELEM(wsptr^[7]); + + tmp7 := z11 + z13; { phase 5 } + tmp11 := MULTIPLY(z11 - z13, FIX_1_414213562); { 2*c4 } + + z5 := MULTIPLY(z10 + z12, FIX_1_847759065); { 2*c2 } + tmp10 := MULTIPLY(z12, FIX_1_082392200) - z5; { 2*(c2-c6) } + tmp12 := MULTIPLY(z10, - FIX_2_613125930) + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; { phase 2 } + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + { Final output stage: scale down by a factor of 8 and range-limit } + + outptr^[0] := range_limit^[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[7] := range_limit^[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[1] := range_limit^[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[6] := range_limit^[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[2] := range_limit^[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[5] := range_limit^[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[4] := range_limit^[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[3] := range_limit^[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + and RANGE_MASK]; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jidctint_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidctint_del.pas new file mode 100644 index 0000000..a019540 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidctint_del.pas @@ -0,0 +1,441 @@ +unit jidctint_del; +{$Q+} + +{ This file contains a slow-but-accurate integer implementation of the + inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + must also perform dequantization of the input coefficients. + + A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + on each row (or vice versa, but it's more convenient to emit a row at + a time). Direct algorithms are also available, but they are much more + complex and seem not to be any faster when reduced to code. + + This implementation is based on an algorithm described in + C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + The primary algorithm described there uses 11 multiplies and 29 adds. + We use their alternate method with 12 multiplies and 32 adds. + The advantage of this method is that no data path contains more than one + multiplication; this allows a very simple and accurate implementation in + scaled fixed-point arithmetic, with a minimal number of shifts. } + +{ Original : jidctint.c ; Copyright (C) 1991-1998, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_islow (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + +{ The poop on this scaling stuff is as follows: + + Each 1-D IDCT step produces outputs which are a factor of sqrt(N) + larger than the true IDCT outputs. The final outputs are therefore + a factor of N larger than desired; since N=8 this can be cured by + a simple right shift at the end of the algorithm. The advantage of + this arrangement is that we save two multiplications per 1-D IDCT, + because the y0 and y4 inputs need not be divided by sqrt(N). + + We have to do addition and subtraction of the integer inputs, which + is no problem, and multiplication by fractional constants, which is + a problem to do in integer arithmetic. We multiply all the constants + by CONST_SCALE and convert them to integer constants (thus retaining + CONST_BITS bits of precision in the constants). After doing a + multiplication we have to divide the product by CONST_SCALE, with proper + rounding, to produce the correct output. This division can be done + cheaply as a right shift of CONST_BITS bits. We postpone shifting + as long as possible so that partial sums can be added together with + full fractional precision. + + The outputs of the first pass are scaled up by PASS1_BITS bits so that + they are represented to better-than-integral precision. These outputs + require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + with the recommended scaling. (To scale up 12-bit sample data further, an + intermediate INT32 array would be needed.) + + To avoid overflow of the 32-bit intermediate results in pass 2, we must + have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + shows that the values given below are the most effective. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + CONST_BITS = 13; + PASS1_BITS = 2; +{$else} +const + CONST_BITS = 13; + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + +const + CONST_SCALE = (INT32(1) shl CONST_BITS); + +const + FIX_0_298631336 = INT32(Round(CONST_SCALE * 0.298631336)); {2446} + FIX_0_390180644 = INT32(Round(CONST_SCALE * 0.390180644)); {3196} + FIX_0_541196100 = INT32(Round(CONST_SCALE * 0.541196100)); {4433} + FIX_0_765366865 = INT32(Round(CONST_SCALE * 0.765366865)); {6270} + FIX_0_899976223 = INT32(Round(CONST_SCALE * 0.899976223)); {7373} + FIX_1_175875602 = INT32(Round(CONST_SCALE * 1.175875602)); {9633} + FIX_1_501321110 = INT32(Round(CONST_SCALE * 1.501321110)); {12299} + FIX_1_847759065 = INT32(Round(CONST_SCALE * 1.847759065)); {15137} + FIX_1_961570560 = INT32(Round(CONST_SCALE * 1.961570560)); {16069} + FIX_2_053119869 = INT32(Round(CONST_SCALE * 2.053119869)); {16819} + FIX_2_562915447 = INT32(Round(CONST_SCALE * 2.562915447)); {20995} + FIX_3_072711026 = INT32(Round(CONST_SCALE * 3.072711026)); {25172} + + + +{ Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + For 8-bit samples with the recommended scaling, all the variable + and constant values involved are no more than 16 bits wide, so a + 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + For 12-bit samples, a full 32-bit multiplication will be needed. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} + + {$IFDEF BASM16} + {$IFNDEF WIN32} + {MULTIPLY16C16(var,const)} + function Multiply(X, Y: Integer): integer; assembler; + asm + mov ax, X + imul Y + mov al, ah + mov ah, dl + end; + {$ENDIF} + {$ENDIF} + + function Multiply(X, Y: INT32): INT32; + begin + Multiply := INT32(X) * INT32(Y); + end; + + +{$else} + {#define MULTIPLY(var,const) ((var) * (const))} + function Multiply(X, Y: INT32): INT32; + begin + Multiply := INT32(X) * INT32(Y); + end; +{$endif} + + +{ Dequantize a coefficient by multiplying it by the multiplier-table + entry; produce an int result. In this module, both inputs and result + are 16 bits or less, so either int or short multiply will work. } + +function DEQUANTIZE(coef,quantval : int) : int; +begin + Dequantize := ( ISLOW_MULT_TYPE(coef) * quantval); +end; + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + shift_temp := x + (INT32(1) shl (n-1)); + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + Descale := (shift_temp shr n); +{$else} + Descale := (x + (INT32(1) shl (n-1)) shr n; +{$endif} +end; + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_islow (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = coef_bits_field; { buffers data between passes } +var + tmp0, tmp1, tmp2, tmp3 : INT32; + tmp10, tmp11, tmp12, tmp13 : INT32; + z1, z2, z3, z4, z5 : INT32; + inptr : JCOEFPTR; + quantptr : ISLOW_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; + {SHIFT_TEMPS} +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + + + { Pass 1: process columns from input, store into work array. } + { Note results are scaled up by sqrt(8) compared to a true IDCT; } + { furthermore, we scale the results by 2**PASS1_BITS. } + + inptr := coef_block; + quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + wsptr := PWorkspace(@workspace); + for ctr := pred(DCTSIZE) downto 0 do + begin + { Due to quantization, we will usually find that many of the input + coefficients are zero, especially the AC terms. We can exploit this + by short-circuiting the IDCT calculation for any column in which all + the AC terms are zero. In that case each output is equal to the + DC coefficient (with scale factor as needed). + With typical images and quantization tables, half or more of the + column DCT calculations can be simplified this way. } + + if ((inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*2]=0) and + (inptr^[DCTSIZE*3]=0) and (inptr^[DCTSIZE*4]=0) and + (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*6]=0) and + (inptr^[DCTSIZE*7]=0)) then + begin + { AC terms all zero } + dcval := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]) shl PASS1_BITS; + + wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + wsptr^[DCTSIZE*2] := dcval; + wsptr^[DCTSIZE*3] := dcval; + wsptr^[DCTSIZE*4] := dcval; + wsptr^[DCTSIZE*5] := dcval; + wsptr^[DCTSIZE*6] := dcval; + wsptr^[DCTSIZE*7] := dcval; + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + continue; + end; + + { Even part: reverse the even part of the forward DCT. } + { The rotator is sqrt(2)*c(-6). } + + z2 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]); + z3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]); + + z1 := MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 := z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 := z1 + MULTIPLY(z2, FIX_0_765366865); + + z2 := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]); + z3 := DEQUANTIZE(inptr^[DCTSIZE*4], quantptr^[DCTSIZE*4]); + + tmp0 := (z2 + z3) shl CONST_BITS; + tmp1 := (z2 - z3) shl CONST_BITS; + + tmp10 := tmp0 + tmp3; + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + { Odd part per figure 8; the matrix is unitary and hence its + transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. } + + tmp0 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]); + tmp1 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]); + tmp2 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]); + tmp3 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]); + + z1 := tmp0 + tmp3; + z2 := tmp1 + tmp2; + z3 := tmp0 + tmp2; + z4 := tmp1 + tmp3; + z5 := MULTIPLY(z3 + z4, FIX_1_175875602); { sqrt(2) * c3 } + + tmp0 := MULTIPLY(tmp0, FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + tmp1 := MULTIPLY(tmp1, FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + tmp2 := MULTIPLY(tmp2, FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + tmp3 := MULTIPLY(tmp3, FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + z1 := MULTIPLY(z1, - FIX_0_899976223); { sqrt(2) * (c7-c3) } + z2 := MULTIPLY(z2, - FIX_2_562915447); { sqrt(2) * (-c1-c3) } + z3 := MULTIPLY(z3, - FIX_1_961570560); { sqrt(2) * (-c3-c5) } + z4 := MULTIPLY(z4, - FIX_0_390180644); { sqrt(2) * (c5-c3) } + + Inc(z3, z5); + Inc(z4, z5); + + Inc(tmp0, z1 + z3); + Inc(tmp1, z2 + z4); + Inc(tmp2, z2 + z3); + Inc(tmp3, z1 + z4); + + { Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 } + + wsptr^[DCTSIZE*0] := int (DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*7] := int (DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*1] := int (DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*6] := int (DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*2] := int (DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*5] := int (DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*3] := int (DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*4] := int (DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS)); + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + end; + + { Pass 2: process rows from work array, store into output array. } + { Note that we must descale the results by a factor of 8 == 2**3, } + { and also undo the PASS1_BITS scaling. } + + wsptr := @workspace; + for ctr := 0 to pred(DCTSIZE) do + begin + outptr := output_buf^[ctr]; + Inc(JSAMPLE_PTR(outptr), output_col); + { Rows of zeroes can be exploited in the same way as we did with columns. + However, the column calculation has created many nonzero AC terms, so + the simplification applies less often (typically 5% to 10% of the time). + On machines with very fast multiplication, it's possible that the + test takes more time than it's worth. In that case this section + may be commented out. } + +{$ifndef NO_ZERO_ROW_TEST} + if ((wsptr^[1]=0) and (wsptr^[2]=0) and (wsptr^[3]=0) and (wsptr^[4]=0) + and (wsptr^[5]=0) and (wsptr^[6]=0) and (wsptr^[7]=0)) then + begin + { AC terms all zero } + JSAMPLE(dcval_) := range_limit^[int(DESCALE(INT32(wsptr^[0]), + PASS1_BITS+3)) and RANGE_MASK]; + + outptr^[0] := dcval_; + outptr^[1] := dcval_; + outptr^[2] := dcval_; + outptr^[3] := dcval_; + outptr^[4] := dcval_; + outptr^[5] := dcval_; + outptr^[6] := dcval_; + outptr^[7] := dcval_; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + continue; + end; +{$endif} + + { Even part: reverse the even part of the forward DCT. } + { The rotator is sqrt(2)*c(-6). } + + z2 := INT32 (wsptr^[2]); + z3 := INT32 (wsptr^[6]); + + z1 := MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 := z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 := z1 + MULTIPLY(z2, FIX_0_765366865); + + tmp0 := (INT32(wsptr^[0]) + INT32(wsptr^[4])) shl CONST_BITS; + tmp1 := (INT32(wsptr^[0]) - INT32(wsptr^[4])) shl CONST_BITS; + + tmp10 := tmp0 + tmp3; + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + { Odd part per figure 8; the matrix is unitary and hence its + transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. } + + tmp0 := INT32(wsptr^[7]); + tmp1 := INT32(wsptr^[5]); + tmp2 := INT32(wsptr^[3]); + tmp3 := INT32(wsptr^[1]); + + z1 := tmp0 + tmp3; + z2 := tmp1 + tmp2; + z3 := tmp0 + tmp2; + z4 := tmp1 + tmp3; + z5 := MULTIPLY(z3 + z4, FIX_1_175875602); { sqrt(2) * c3 } + + tmp0 := MULTIPLY(tmp0, FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + tmp1 := MULTIPLY(tmp1, FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + tmp2 := MULTIPLY(tmp2, FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + tmp3 := MULTIPLY(tmp3, FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + z1 := MULTIPLY(z1, - FIX_0_899976223); { sqrt(2) * (c7-c3) } + z2 := MULTIPLY(z2, - FIX_2_562915447); { sqrt(2) * (-c1-c3) } + z3 := MULTIPLY(z3, - FIX_1_961570560); { sqrt(2) * (-c3-c5) } + z4 := MULTIPLY(z4, - FIX_0_390180644); { sqrt(2) * (c5-c3) } + + Inc(z3, z5); + Inc(z4, z5); + + Inc(tmp0, z1 + z3); + Inc(tmp1, z2 + z4); + Inc(tmp2, z2 + z3); + Inc(tmp3, z1 + z4); + + { Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 } + + outptr^[0] := range_limit^[ int(DESCALE(tmp10 + tmp3, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[7] := range_limit^[ int(DESCALE(tmp10 - tmp3, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[1] := range_limit^[ int(DESCALE(tmp11 + tmp2, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[6] := range_limit^[ int(DESCALE(tmp11 - tmp2, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[2] := range_limit^[ int(DESCALE(tmp12 + tmp1, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[5] := range_limit^[ int(DESCALE(tmp12 - tmp1, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[3] := range_limit^[ int(DESCALE(tmp13 + tmp0, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[4] := range_limit^[ int(DESCALE(tmp13 - tmp0, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jidctred_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidctred_del.pas new file mode 100644 index 0000000..612ce51 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidctred_del.pas @@ -0,0 +1,526 @@ +unit jidctred_del; + + +{ This file contains inverse-DCT routines that produce reduced-size output: + either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block. + + The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M) + algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step + with an 8-to-4 step that produces the four averages of two adjacent outputs + (or an 8-to-2 step producing two averages of four outputs, for 2x2 output). + These steps were derived by computing the corresponding values at the end + of the normal LL&M code, then simplifying as much as possible. + + 1x1 is trivial: just take the DC coefficient divided by 8. + + See jidctint.c for additional comments. } + + +{ Original : jidctred.c ; Copyright (C) 1994-1998, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 1x1 output block. } + +{GLOBAL} +procedure jpeg_idct_1x1 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 2x2 output block. } + +{GLOBAL} +procedure jpeg_idct_2x2 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 4x4 output block. } + +{GLOBAL} +procedure jpeg_idct_4x4 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + + +{ Scaling is the same as in jidctint.c. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + CONST_BITS = 13; + PASS1_BITS = 2; +{$else} +const + CONST_BITS = 13; + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + +const + FIX_0_211164243 = INT32(Round((INT32(1) shl CONST_BITS) * 0.211164243)); {1730} + FIX_0_509795579 = INT32(Round((INT32(1) shl CONST_BITS) * 0.509795579)); {4176} + FIX_0_601344887 = INT32(Round((INT32(1) shl CONST_BITS) * 0.601344887)); {4926} + FIX_0_720959822 = INT32(Round((INT32(1) shl CONST_BITS) * 0.720959822)); {5906} + FIX_0_765366865 = INT32(Round((INT32(1) shl CONST_BITS) * 0.765366865)); {6270} + FIX_0_850430095 = INT32(Round((INT32(1) shl CONST_BITS) * 0.850430095)); {6967} + FIX_0_899976223 = INT32(Round((INT32(1) shl CONST_BITS) * 0.899976223)); {7373} + FIX_1_061594337 = INT32(Round((INT32(1) shl CONST_BITS) * 1.061594337)); {8697} + FIX_1_272758580 = INT32(Round((INT32(1) shl CONST_BITS) * 1.272758580)); {10426} + FIX_1_451774981 = INT32(Round((INT32(1) shl CONST_BITS) * 1.451774981)); {11893} + FIX_1_847759065 = INT32(Round((INT32(1) shl CONST_BITS) * 1.847759065)); {15137} + FIX_2_172734803 = INT32(Round((INT32(1) shl CONST_BITS) * 2.172734803)); {17799} + FIX_2_562915447 = INT32(Round((INT32(1) shl CONST_BITS) * 2.562915447)); {20995} + FIX_3_624509785 = INT32(Round((INT32(1) shl CONST_BITS) * 3.624509785)); {29692} + + +{ Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + For 8-bit samples with the recommended scaling, all the variable + and constant values involved are no more than 16 bits wide, so a + 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + For 12-bit samples, a full 32-bit multiplication will be needed. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} + + {function Multiply(X, Y: Integer): integer; assembler; + asm + mov ax, X + imul Y + mov al, ah + mov ah, dl + end;} + + {MULTIPLY16C16(var,const)} + function Multiply(X, Y: Integer): INT32; + begin + Multiply := X*INT32(Y); + end; + + +{$else} + function Multiply(X, Y: INT32): INT32; + begin + Multiply := X*Y; + end; +{$endif} + + +{ Dequantize a coefficient by multiplying it by the multiplier-table + entry; produce an int result. In this module, both inputs and result + are 16 bits or less, so either int or short multiply will work. } + +function DEQUANTIZE(coef,quantval : int) : int; +begin + Dequantize := ( ISLOW_MULT_TYPE(coef) * quantval); +end; + + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + shift_temp := x + (INT32(1) shl (n-1)); + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + Descale := (shift_temp shr n); +{$else} + Descale := (x + (INT32(1) shl (n-1)) shr n; +{$endif} +end; + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 4x4 output block. } + +{GLOBAL} +procedure jpeg_idct_4x4 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = array[0..(DCTSIZE*4)-1] of int; { buffers data between passes } +var + tmp0, tmp2, tmp10, tmp12 : INT32; + z1, z2, z3, z4 : INT32; + inptr : JCOEFPTR; + quantptr : ISLOW_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS} +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + wsptr := @workspace; + for ctr := DCTSIZE downto 1 do + begin + { Don't bother to process column 4, because second pass won't use it } + if (ctr = DCTSIZE-4) then + begin + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + + continue; + end; + if (inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*2]=0) and (inptr^[DCTSIZE*3]=0) and + (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*6]=0) and (inptr^[DCTSIZE*7]=0) then + begin + { AC terms all zero; we need not examine term 4 for 4x4 output } + dcval := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * + quantptr^[DCTSIZE*0]) shl PASS1_BITS; + + wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + wsptr^[DCTSIZE*2] := dcval; + wsptr^[DCTSIZE*3] := dcval; + + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + + continue; + end; + + { Even part } + + tmp0 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * quantptr^[DCTSIZE*0]); + + tmp0 := tmp0 shl (CONST_BITS+1); + + z2 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*2]) * quantptr^[DCTSIZE*2]); + z3 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*6]) * quantptr^[DCTSIZE*6]); + + tmp2 := MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865); + + tmp10 := tmp0 + tmp2; + tmp12 := tmp0 - tmp2; + + { Odd part } + + z1 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*7]) * quantptr^[DCTSIZE*7]; + z2 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*5]) * quantptr^[DCTSIZE*5]; + z3 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*3]) * quantptr^[DCTSIZE*3]; + z4 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*1]) * quantptr^[DCTSIZE*1]; + + tmp0 := MULTIPLY(z1, - FIX_0_211164243) { sqrt(2) * (c3-c1) } + + MULTIPLY(z2, FIX_1_451774981) { sqrt(2) * (c3+c7) } + + MULTIPLY(z3, - FIX_2_172734803) { sqrt(2) * (-c1-c5) } + + MULTIPLY(z4, FIX_1_061594337); { sqrt(2) * (c5+c7) } + + tmp2 := MULTIPLY(z1, - FIX_0_509795579) { sqrt(2) * (c7-c5) } + + MULTIPLY(z2, - FIX_0_601344887) { sqrt(2) * (c5-c1) } + + MULTIPLY(z3, FIX_0_899976223) { sqrt(2) * (c3-c7) } + + MULTIPLY(z4, FIX_2_562915447); { sqrt(2) * (c1+c3) } + + { Final output stage } + + wsptr^[DCTSIZE*0] := int(DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1)); + wsptr^[DCTSIZE*3] := int(DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1)); + wsptr^[DCTSIZE*1] := int(DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1)); + wsptr^[DCTSIZE*2] := int(DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1)); + + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + end; + + { Pass 2: process 4 rows from work array, store into output array. } + + wsptr := @workspace; + for ctr := 0 to pred(4) do + begin + outptr := JSAMPROW(@ output_buf^[ctr]^[output_col]); + { It's not clear whether a zero row test is worthwhile here ... } + +{$ifndef NO_ZERO_ROW_TEST} + if (wsptr^[1]=0) and (wsptr^[2]=0) and (wsptr^[3]=0) and + (wsptr^[5]=0) and (wsptr^[6]=0) and (wsptr^[7]=0) then + begin + { AC terms all zero } + dcval_ := range_limit^[int(DESCALE(INT32(wsptr^[0]), PASS1_BITS+3)) + and RANGE_MASK]; + + outptr^[0] := dcval_; + outptr^[1] := dcval_; + outptr^[2] := dcval_; + outptr^[3] := dcval_; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + continue; + end; +{$endif} + + { Even part } + + tmp0 := (INT32(wsptr^[0])) shl (CONST_BITS+1); + + tmp2 := MULTIPLY(INT32(wsptr^[2]), FIX_1_847759065) + + MULTIPLY(INT32(wsptr^[6]), - FIX_0_765366865); + + tmp10 := tmp0 + tmp2; + tmp12 := tmp0 - tmp2; + + { Odd part } + + z1 := INT32(wsptr^[7]); + z2 := INT32(wsptr^[5]); + z3 := INT32(wsptr^[3]); + z4 := INT32(wsptr^[1]); + + tmp0 := MULTIPLY(z1, - FIX_0_211164243) { sqrt(2) * (c3-c1) } + + MULTIPLY(z2, FIX_1_451774981) { sqrt(2) * (c3+c7) } + + MULTIPLY(z3, - FIX_2_172734803) { sqrt(2) * (-c1-c5) } + + MULTIPLY(z4, FIX_1_061594337); { sqrt(2) * (c5+c7) } + + tmp2 := MULTIPLY(z1, - FIX_0_509795579) { sqrt(2) * (c7-c5) } + + MULTIPLY(z2, - FIX_0_601344887) { sqrt(2) * (c5-c1) } + + MULTIPLY(z3, FIX_0_899976223) { sqrt(2) * (c3-c7) } + + MULTIPLY(z4, FIX_2_562915447); { sqrt(2) * (c1+c3) } + + { Final output stage } + + outptr^[0] := range_limit^[ int(DESCALE(tmp10 + tmp2, + CONST_BITS+PASS1_BITS+3+1)) + and RANGE_MASK]; + outptr^[3] := range_limit^[ int(DESCALE(tmp10 - tmp2, + CONST_BITS+PASS1_BITS+3+1)) + and RANGE_MASK]; + outptr^[1] := range_limit^[ int(DESCALE(tmp12 + tmp0, + CONST_BITS+PASS1_BITS+3+1)) + and RANGE_MASK]; + outptr^[2] := range_limit^[ int(DESCALE(tmp12 - tmp0, + CONST_BITS+PASS1_BITS+3+1)) + and RANGE_MASK]; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 2x2 output block. } + +{GLOBAL} +procedure jpeg_idct_2x2 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = array[0..(DCTSIZE*2)-1] of int; { buffers data between passes } +var + tmp0, tmp10, z1 : INT32; + inptr : JCOEFPTR; + quantptr : ISLOW_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS} +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + wsptr := @workspace; + for ctr := DCTSIZE downto 1 do + begin + { Don't bother to process columns 2,4,6 } + if (ctr = DCTSIZE-2) or (ctr = DCTSIZE-4) or (ctr = DCTSIZE-6) then + begin + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + + continue; + end; + if (inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*3]=0) and + (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*7]=0) then + begin + { AC terms all zero; we need not examine terms 2,4,6 for 2x2 output } + dcval := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * + quantptr^[DCTSIZE*0]) shl PASS1_BITS; + + wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + + continue; + end; + + { Even part } + + z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * quantptr^[DCTSIZE*0]); + + tmp10 := z1 shl (CONST_BITS+2); + + { Odd part } + + z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*7]) * quantptr^[DCTSIZE*7]); + tmp0 := MULTIPLY(z1, - FIX_0_720959822); { sqrt(2) * (c7-c5+c3-c1) } + z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*5]) * quantptr^[DCTSIZE*5]); + Inc(tmp0, MULTIPLY(z1, FIX_0_850430095)); { sqrt(2) * (-c1+c3+c5+c7) } + z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*3]) * quantptr^[DCTSIZE*3]); + Inc(tmp0, MULTIPLY(z1, - FIX_1_272758580)); { sqrt(2) * (-c1+c3-c5-c7) } + z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*1]) * quantptr^[DCTSIZE*1]); + Inc(tmp0, MULTIPLY(z1, FIX_3_624509785)); { sqrt(2) * (c1+c3+c5+c7) } + + { Final output stage } + + wsptr^[DCTSIZE*0] := int (DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2)); + wsptr^[DCTSIZE*1] := int (DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2)); + + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + end; + + { Pass 2: process 2 rows from work array, store into output array. } + + wsptr := @workspace; + for ctr := 0 to pred(2) do + begin + outptr := JSAMPROW(@ output_buf^[ctr]^[output_col]); + { It's not clear whether a zero row test is worthwhile here ... } + +{$ifndef NO_ZERO_ROW_TEST} + if (wsptr^[1]=0) and (wsptr^[3]=0) and (wsptr^[5]=0) and (wsptr^[7]= 0) then + begin + { AC terms all zero } + dcval_ := range_limit^[ int(DESCALE(INT32(wsptr^[0]), PASS1_BITS+3)) + and RANGE_MASK]; + + outptr^[0] := dcval_; + outptr^[1] := dcval_; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + continue; + end; +{$endif} + + { Even part } + + tmp10 := (INT32 (wsptr^[0])) shl (CONST_BITS+2); + + { Odd part } + + tmp0 := MULTIPLY( INT32(wsptr^[7]), - FIX_0_720959822) { sqrt(2) * (c7-c5+c3-c1) } + + MULTIPLY( INT32(wsptr^[5]), FIX_0_850430095) { sqrt(2) * (-c1+c3+c5+c7) } + + MULTIPLY( INT32(wsptr^[3]), - FIX_1_272758580) { sqrt(2) * (-c1+c3-c5-c7) } + + MULTIPLY( INT32(wsptr^[1]), FIX_3_624509785); { sqrt(2) * (c1+c3+c5+c7) } + + { Final output stage } + + outptr^[0] := range_limit^[ int(DESCALE(tmp10 + tmp0, + CONST_BITS+PASS1_BITS+3+2)) + and RANGE_MASK]; + outptr^[1] := range_limit^[ int(DESCALE(tmp10 - tmp0, + CONST_BITS+PASS1_BITS+3+2)) + and RANGE_MASK]; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 1x1 output block. } + +{GLOBAL} +procedure jpeg_idct_1x1 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +var + dcval : int; + quantptr : ISLOW_MULT_TYPE_FIELD_PTR; + range_limit : JSAMPROW; + {SHIFT_TEMPS} +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + { We hardly need an inverse DCT routine for this: just take the + average pixel value, which is one-eighth of the DC coefficient. } + + quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + dcval := (ISLOW_MULT_TYPE(coef_block^[0]) * quantptr^[0]); + dcval := int (DESCALE( INT32(dcval), 3)); + + output_buf^[0]^[output_col] := range_limit^[dcval and RANGE_MASK]; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jinclude_del.pas b/mseide-msegui/lib/common/fpccompatibility/jinclude_del.pas new file mode 100644 index 0000000..1a88663 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jinclude_del.pas @@ -0,0 +1,127 @@ +Unit jinclude_del; + +{ This file exists to provide a single place to fix any problems with + including the wrong system include files. (Common problems are taken + care of by the standard jconfig symbols, but on really weird systems + you may have to edit this file.) + + NOTE: this file is NOT intended to be included by applications using the + JPEG library. Most applications need only include jpeglib.h. } + +{ Original: jinclude.h Copyright (C) 1991-1994, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ Include auto-config file to find out which system include files we need. } + +uses +{$ifdef Delphi_Stream} + classes, mclasses, +{$endif} + jmorecfg_del; + +{ Nomssi: + To write a dest/source manager that handle streams rather than files, + you can edit the FILEptr definition and the JFREAD() and JFWRITE() + functions in this unit, you don't need to change the default managers + JDATASRC and JDATADST. } + +{$ifdef Delphi_Stream} +type + FILEptr = ^TStream; +{$else} + {$ifdef Delphi_Jpeg} + type + FILEptr = TCustomMemoryStream; + {$else} + type + FILEptr = ^File; + {$endif} +{$endif} + +{ We need the NULL macro and size_t typedef. + On an ANSI-conforming system it is sufficient to include . + Otherwise, we get them from or ; we may have to + pull in as well. + Note that the core JPEG library does not require ; + only the default error handler and data source/destination modules do. + But we must pull it in because of the references to FILE in jpeglib.h. + You can remove those references if you want to compile without .} + + + +{ We need memory copying and zeroing functions, plus strncpy(). + ANSI and System V implementations declare these in . + BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). + Some systems may declare memset and memcpy in . + + NOTE: we assume the size parameters to these functions are of type size_t. + Change the casts in these macros if not! } + +procedure MEMZERO(target : pointer; size : size_t); + +procedure MEMCOPY(dest, src : pointer; size : size_t); + +{function SIZEOF(object) : size_t;} + +function JFREAD(fp : FILEptr; buf : pointer; sizeofbuf : size_t) : size_t; + +function JFWRITE(fp : FILEptr; buf : pointer; sizeofbuf : size_t) : size_t; + +implementation + +procedure MEMZERO(target : pointer; size : size_t); +begin + FillChar(target^, size, 0); +end; + +procedure MEMCOPY(dest, src : pointer; size : size_t); +begin + Move(src^, dest^, size); +end; + +{ In ANSI C, and indeed any rational implementation, size_t is also the + type returned by sizeof(). However, it seems there are some irrational + implementations out there, in which sizeof() returns an int even though + size_t is defined as long or unsigned long. To ensure consistent results + we always use this SIZEOF() macro in place of using sizeof() directly. } + + +{#define + SIZEOF(object) (size_t(sizeof(object))} + + +{ The modules that use fread() and fwrite() always invoke them through + these macros. On some systems you may need to twiddle the argument casts. + CAUTION: argument order is different from underlying functions! } + + +function JFREAD(fp : FILEptr; buf : pointer; sizeofbuf : size_t) : size_t; +var + count : uint; +begin + {$ifdef Delphi_Stream} + count := fp^.Read(buf^, sizeofbuf); + {$else} + blockread(fp^, buf^, sizeofbuf, count); + {$endif} + JFREAD := size_t(count); +end; + +function JFWRITE(fp : FILEptr; buf : pointer; sizeofbuf : size_t) : size_t; +var + count : uint; +begin + {$ifdef Delphi_Stream} + count := fp^.Write(buf^, sizeofbuf); + {$else} + blockwrite(fp^, buf^, sizeofbuf, count); + {$endif} + JFWRITE := size_t(count); +end; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmemdos_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmemdos_del.pas new file mode 100644 index 0000000..f48835d --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmemdos_del.pas @@ -0,0 +1,780 @@ +Unit JmemDos; + + +{ This file provides an MS-DOS-compatible implementation of the system- + dependent portion of the JPEG memory manager. Temporary data can be + stored in extended or expanded memory as well as in regular DOS files. + + If you use this file, you must be sure that NEED_FAR_POINTERS is defined + if you compile in a small-data memory model; it should NOT be defined if + you use a large-data memory model. This file is not recommended if you + are using a flat-memory-space 386 environment such as DJGCC or Watcom C. + Also, this code will NOT work if struct fields are aligned on greater than + 2-byte boundaries. + + Based on code contributed by Ge' Weijers. } + +{ Original: jmemdos.c; Copyright (C) 1992-1996, Thomas G. Lane. } + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg, + jpeglib; + +{ If you have both extended and expanded memory, you may want to change the + order in which they are tried in jopen_backing_store. On a 286 machine + expanded memory is usually faster, since extended memory access involves + an expensive protected-mode-and-back switch. On 386 and better, extended + memory is usually faster. As distributed, the code tries extended memory + first (what? not everyone has a 386? :-). + + You can disable use of extended/expanded memory entirely by altering these + definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0).} + +{GLOBAL} +procedure jpeg_open_backing_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long); + +{ These routines take care of any system-dependent initialization and + cleanup required. } + +{GLOBAL} +function jpeg_mem_init (cinfo : j_common_ptr) : long; + +{GLOBAL} +procedure jpeg_mem_term (cinfo : j_common_ptr); + +{ These two functions are used to allocate and release small chunks of + memory. (Typically the total amount requested through jpeg_get_small is + no more than 20K or so; this will be requested in chunks of a few K each.) + Behavior should be the same as for the standard library functions malloc + and free; in particular, jpeg_get_small must return NIL on failure. + On most systems, these ARE malloc and free. jpeg_free_small is passed the + size of the object being freed, just in case it's needed. + On an 80x86 machine using small-data memory model, these manage near heap. } + + +{ Near-memory allocation and freeing are controlled by the regular library + routines malloc() and free(). } + +{GLOBAL} +function jpeg_get_small (cinfo : j_common_ptr; + sizeofobject : size_t) : pointer; + +{GLOBAL} +{object is a reserved word in Borland Pascal } +procedure jpeg_free_small (cinfo : j_common_ptr; + an_object : pointer; + sizeofobject : size_t); + +{ These two functions are used to allocate and release large chunks of + memory (up to the total free space designated by jpeg_mem_available). + The interface is the same as above, except that on an 80x86 machine, + far pointers are used. On most other machines these are identical to + the jpeg_get/free_small routines; but we keep them separate anyway, + in case a different allocation strategy is desirable for large chunks. } + + +{ "Large" objects are allocated in far memory, if possible } + + +{GLOBAL} +function jpeg_get_large (cinfo : j_common_ptr; + sizeofobject : size_t) : voidp; {far} + +{GLOBAL} +procedure jpeg_free_large (cinfo : j_common_ptr; + {var?} an_object : voidp; {FAR} + sizeofobject : size_t); + +{ This routine computes the total memory space available for allocation. + It's impossible to do this in a portable way; our current solution is + to make the user tell us (with a default value set at compile time). + If you can actually get the available space, it's a good idea to subtract + a slop factor of 5% or so. } + +{GLOBAL} +function jpeg_mem_available (cinfo : j_common_ptr; + min_bytes_needed : long; + max_bytes_needed : long; + already_allocated : long) : long; + + +{ The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + be requested in a single call to jpeg_get_large (and jpeg_get_small for that + matter, but that case should never come into play). This macro is needed + to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + On those machines, we expect that jconfig.h will provide a proper value. + On machines with 32-bit flat address spaces, any large constant may be used. + + NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + size_t and will be a multiple of sizeof(align_type). } + + +{$ifdef USE_MSDOS_MEMMGR} { Define this if you use jmemdos.c } +const + MAX_ALLOC_CHUNK = long(32752); {65520} { Maximum request to malloc() } + { MAX_ALLOC_CHUNK should be less than 64K. } +{$else} +const + MAX_ALLOC_CHUNK = long(1000000000); +{$endif} + +implementation + +uses + dos, + jmemdosa, + jdeferr, + jerror; + + + +{ Selection of a file name for a temporary file. + This is highly system-dependent, and you may want to customize it. } + +var + next_file_num : int; { to distinguish among several temp files } + +{LOCAL} +procedure select_file_name (var fname : TEMP_STRING); +var + env : string; + suffix, + prefix : TEMP_STRING; + tfile : FILE; + l : byte; +begin + { Keep generating file names till we find one that's not in use } + while TRUE do + begin + { Get temp directory name from environment TMP or TEMP variable; + if none, use "." } + env := getenv('TMP'); + if (env = '') then + begin + env := getenv('TEMP'); + if (env = '') then { null string means "." } + env := '.'; + end; + prefix := env; { copy name to fname } + { length(fname) > 0 !! } + if (prefix[length(prefix)] <> '\') + and (prefix[length(prefix)] <> '/') then + prefix := prefix + '\'; { append backslash if not in env variable } + { Append a suitable file name } + Inc(next_file_num); { advance counter } + + Str(next_file_num, suffix); + for l := Length(suffix)+1 to 3 do + suffix := '0' + suffix; + fname := prefix + 'JPG' + suffix + '.TMP'; + { Probe to see if file name is already in use } + system.assign(tfile, fname); + {$ifdef IoCheck} {$I-} {$endif} + system.reset(tfile, 1); + {$ifdef IoCheck} {$I+} {$endif} + if (IOresult <> 0) then + begin + fname := fname + #0; + break; + end; + system.close(tfile); { oops, it's there; close tfile & try again } + end; +end; + +{ These two functions are used to allocate and release small chunks of + memory. (Typically the total amount requested through jpeg_get_small is + no more than 20K or so; this will be requested in chunks of a few K each.) + Behavior should be the same as for the standard library functions malloc + and free; in particular, jpeg_get_small must return NIL on failure. + On most systems, these ARE malloc and free. jpeg_free_small is passed the + size of the object being freed, just in case it's needed. + On an 80x86 machine using small-data memory model, these manage near heap. } + + +{ Near-memory allocation and freeing are controlled by the regular library + routines malloc() and free(). } + +{GLOBAL} +function jpeg_get_small (cinfo : j_common_ptr; + sizeofobject : size_t) : pointer; +var + p : pointer; +begin + getmem(p, sizeofobject); + jpeg_get_small := p; +end; + +{GLOBAL} +{object is a reserved word in Borland Pascal } +procedure jpeg_free_small (cinfo : j_common_ptr; + an_object : pointer; + sizeofobject : size_t); +begin + freemem(an_object, sizeofobject); +end; + +{ These two functions are used to allocate and release large chunks of + memory (up to the total free space designated by jpeg_mem_available). + The interface is the same as above, except that on an 80x86 machine, + far pointers are used. On most other machines these are identical to + the jpeg_get/free_small routines; but we keep them separate anyway, + in case a different allocation strategy is desirable for large chunks. } + + +{GLOBAL} +function jpeg_get_large (cinfo : j_common_ptr; + sizeofobject : size_t) : voidp; {far} +var + p : voidp; {FAR} +begin + {far_malloc;} + getmem(p, sizeofobject); + jpeg_get_large := p; +end; + +{GLOBAL} +procedure jpeg_free_large (cinfo : j_common_ptr; + {var?} an_object : voidp; {FAR} + sizeofobject : size_t); +begin + {far_free(an_object);} + FreeMem(an_object, sizeofobject); +end; + +{ This routine computes the total space still available for allocation by + jpeg_get_large. If more space than this is needed, backing store will be + used. NOTE: any memory already allocated must not be counted. + + There is a minimum space requirement, corresponding to the minimum + feasible buffer sizes; jmemmgr.c will request that much space even if + jpeg_mem_available returns zero. The maximum space needed, enough to hold + all working storage in memory, is also passed in case it is useful. + Finally, the total space already allocated is passed. If no better + method is available, cinfo->mem->max_memory_to_use - already_allocated + is often a suitable calculation. + + It is OK for jpeg_mem_available to underestimate the space available + (that'll just lead to more backing-store access than is really necessary). + However, an overestimate will lead to failure. Hence it's wise to subtract + a slop factor from the true available space. 5% should be enough. + + On machines with lots of virtual memory, any large constant may be returned. + Conversely, zero may be returned to always use the minimum amount of memory.} + + + +{ This routine computes the total memory space available for allocation. + It's impossible to do this in a portable way; our current solution is + to make the user tell us (with a default value set at compile time). + If you can actually get the available space, it's a good idea to subtract + a slop factor of 5% or so. } + +const + DEFAULT_MAX_MEM = long(300000); { for total usage about 450K } + +{GLOBAL} +function jpeg_mem_available (cinfo : j_common_ptr; + min_bytes_needed : long; + max_bytes_needed : long; + already_allocated : long) : long; +begin + {jpeg_mem_available := cinfo^.mem^.max_memory_to_use - already_allocated;} + jpeg_mem_available := MaxAvail*95 div 100; { 95% } + + { Nomssi: limit the available memory for test purpose } + {jpeg_mem_available := 30000;} +end; + + +{ Backing store (temporary file) management. + Backing store objects are only used when the value returned by + jpeg_mem_available is less than the total space needed. You can dispense + with these routines if you have plenty of virtual memory; see jmemnobs.c. } + + +{ For MS-DOS we support three types of backing storage: + 1. Conventional DOS files. We access these by direct DOS calls rather + than via the stdio package. This provides a bit better performance, + but the real reason is that the buffers to be read or written are FAR. + The stdio library for small-data memory models can't cope with that. + 2. Extended memory, accessed per the XMS V2.0 specification. + 3. Expanded memory, accessed per the LIM/EMS 4.0 specification. + You'll need copies of those specs to make sense of the related code. + The specs are available by Internet FTP from the SIMTEL archives + (oak.oakland.edu and its various mirror sites). See files + pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip. } + + + +{ Access methods for a DOS file. } + + +{METHODDEF} +procedure read_file_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +begin + if jdos_seek(info^.handle.file_handle, file_offset) <> 0 then + ERREXIT(cinfo, JERR_TFILE_SEEK); + { Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. } + if (byte_count > long(65535)) then { safety check } + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + if jdos_read(info^.handle.file_handle, buffer_address, + ushort(byte_count)) <> 0 then + ERREXIT(cinfo, JERR_TFILE_READ); +end; + + +{METHODDEF} +procedure write_file_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +begin + if (jdos_seek(info^.handle.file_handle, file_offset)) <> 0 then + ERREXIT(cinfo, JERR_TFILE_SEEK); + { Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. } + if (byte_count > long(65535)) then { safety check } + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + if jdos_write(info^.handle.file_handle, buffer_address, + ushort(byte_count)) <> 0 then + ERREXIT(cinfo, JERR_TFILE_WRITE); +end; + + +{METHODDEF} +procedure close_file_store (cinfo : j_common_ptr; + info : backing_store_ptr); +var + f : FILE; +begin + jdos_close(info^.handle.file_handle); { close the file } + + system.assign(f, info^.temp_name); + system.erase(f); { delete the file } +{ If your system doesn't have remove(), try unlink() instead. + remove() is the ANSI-standard name for this function, but + unlink() was more common in pre-ANSI systems. } + + TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info^.temp_name); +end; + + +{LOCAL} +function open_file_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long): boolean; +var + handle : short; +begin + select_file_name(info^.temp_name); + if jdos_open(handle, info^.temp_name[1]) <> 0 then + begin + { might as well exit since jpeg_open_backing_store will fail anyway } + ERREXITS(cinfo, JERR_TFILE_CREATE, info^.temp_name); + open_file_store := FALSE; + exit; + end; + info^.handle.file_handle := handle; + info^.read_backing_store := read_file_store; + info^.write_backing_store := write_file_store; + info^.close_backing_store := close_file_store; + TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info^.temp_name); + open_file_store := TRUE; { succeeded } +end; + + +{ Access methods for extended memory. } + +{$ifdef XMS_SUPPORTED} + +var + xms_driver : XMSDRIVER; { saved address of XMS driver } + +type + XMSPTR = record { either long offset or real-mode pointer } + case byte of + 0:(offset : long); + 1:(ptr : pointer {FAR}); + end; + +type + XMSspec = record { XMS move specification structure } + length : long; + src_handle : XMSH; + src : XMSPTR; + dst_handle : XMSH; + dst : XMSPTR; + end; +type + TByteArray = Array[0..MAX_ALLOC_CHUNK-1] of byte; + +{METHODDEF} +procedure read_xms_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +var + ctx : XMScontext; + spec : XMSspec; + endbuffer : packed array[0..1] of byte; +begin + { The XMS driver can't cope with an odd length, so handle the last byte + specially if byte_count is odd. We don't expect this to be common. } + + + spec.length := byte_count and (not long(1)); + spec.src_handle := info^.handle.xms_handle; + spec.src.offset := file_offset; + spec.dst_handle := 0; + spec.dst.ptr := buffer_address; + + ctx.ds_si := addr(spec); + ctx.ax := $0b00; { EMB move } + jxms_calldriver(xms_driver, ctx); + if (ctx.ax <> 1) then + ERREXIT(cinfo, JERR_XMS_READ); + + if odd(byte_count) then + begin + read_xms_store(cinfo, info, pointer(@endbuffer) {FAR}, + file_offset + byte_count - long(1), long(2)); + TByteArray(buffer_address^)[byte_count - long(1)] := endbuffer[0]; + end; +end; + + +{METHODDEF} +procedure write_xms_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +var + ctx : XMScontext; + spec : XMSspec; + endbuffer : packed array[0..1] of byte; +begin + { The XMS driver can't cope with an odd length, so handle the last byte + specially if byte_count is odd. We don't expect this to be common. } + + spec.length := byte_count and (not long(1)); + spec.src_handle := 0; + spec.src.ptr := buffer_address; + spec.dst_handle := info^.handle.xms_handle; + spec.dst.offset := file_offset; + + ctx.ds_si := addr(spec); + ctx.ax := $0b00; { EMB move } + jxms_calldriver(xms_driver, ctx); + if (ctx.ax <> 1) then + ERREXIT(cinfo, JERR_XMS_WRITE); + + if odd(byte_count) then + begin + read_xms_store(cinfo, info, pointer(@endbuffer) {FAR}, + file_offset + byte_count - long(1), long(2)); + endbuffer[0] := TByteArray(buffer_address^)[byte_count - long(1)]; + write_xms_store(cinfo, info, pointer(@endbuffer) {FAR}, + file_offset + byte_count - long(1), long(2)); + end; +end; + + +{METHODDEF} +procedure close_xms_store (cinfo : j_common_ptr; + info : backing_store_ptr); +var + ctx : XMScontext; +begin + ctx.dx := info^.handle.xms_handle; + ctx.ax := $0a00; + jxms_calldriver(xms_driver, ctx); + TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info^.handle.xms_handle); + { we ignore any error return from the driver } +end; + + +{LOCAL} +function open_xms_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long) : boolean; +var + ctx : XMScontext; +begin + { Get address of XMS driver } + jxms_getdriver(xms_driver); + if (xms_driver = NIL) then + begin + open_xms_store := FALSE; { no driver to be had } + exit; + end; + + { Get version number, must be >= 2.00 } + ctx.ax := $0000; + jxms_calldriver(xms_driver, ctx); + if (ctx.ax < ushort($0200)) then + begin + open_xms_store := FALSE; + exit; + end; + + { Try to get space (expressed in kilobytes) } + ctx.dx := ushort ((total_bytes_needed + long(1023)) shr 10); + ctx.ax := $0900; + jxms_calldriver(xms_driver, ctx); + if (ctx.ax <> 1) then + begin + open_xms_store := FALSE; + exit; + end; + + { Succeeded, save the handle and away we go } + info^.handle.xms_handle := ctx.dx; + info^.read_backing_store := read_xms_store; + info^.write_backing_store := write_xms_store; + info^.close_backing_store := close_xms_store; + TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx); + open_xms_store := TRUE; { succeeded } +end; + +{$endif} { XMS_SUPPORTED } + + +{ Access methods for expanded memory. } + +{$ifdef EMS_SUPPORTED} + +{ The EMS move specification structure requires word and long fields aligned + at odd byte boundaries. Some compilers will align struct fields at even + byte boundaries. While it's usually possible to force byte alignment, + that causes an overall performance penalty and may pose problems in merging + JPEG into a larger application. Instead we accept some rather dirty code + here. Note this code would fail if the hardware did not allow odd-byte + word & long accesses, but all 80x86 CPUs do. } + + +type + EMSPTR = pointer; {FAR} + + +{ types for accessing misaligned fields } +type + EMSAddrStruct = packed record {Size } + MemType : byte; { emsConventional, emsExpanded } { 1 } + Handle : word; { TEMSHandle; } { 2 } + case integer of {union} + 0 : (Offs : word; { 2 } + Page : word); { 2 } + 1 : (Ptr : pointer); {or 4 } + end; + { EMS move specification structure } + EMSspec = packed record + length : longint; { 4 } + src : EMSAddrStruct; { 7 } + dst : EMSAddrStruct; { 7 } + end; + + +const + EMSPAGESIZE = long(16384); { gospel, see the EMS specs } + + +{METHODDEF} +procedure read_ems_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +var + ctx : EMScontext; + spec : EMSspec; +begin + spec.length := byte_count; + spec.src.memtype := 1; + spec.src.handle := info^.handle.ems_handle; + spec.src.page := ushort (file_offset div EMSPAGESIZE); + spec.src.offs := ushort (file_offset mod EMSPAGESIZE); + spec.dst.memtype := 0; + spec.dst.handle := 0; + spec.dst.ptr := buffer_address; + + ctx.ds_si := addr(spec); + ctx.ax := $5700; { move memory region } + jems_calldriver(ctx); + if (hi(ctx.ax) <> 0) then + ERREXIT(cinfo, JERR_EMS_READ); +end; + + +{METHODDEF} +procedure write_ems_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +var + ctx : EMScontext; + spec : EMSspec; +begin + spec.length := byte_count; + spec.src.memtype := 0; + spec.src.handle := 0; + spec.src.ptr := buffer_address; + spec.dst.memtype := 1; + spec.dst.handle := info^.handle.ems_handle; + spec.dst.page := ushort (file_offset div EMSPAGESIZE); + spec.dst.offs := ushort (file_offset mod EMSPAGESIZE); + + ctx.ds_si := addr(spec); + ctx.ax := $5700; { move memory region } + jems_calldriver(ctx); + if (hi(ctx.ax) <> 0) then + ERREXIT(cinfo, JERR_EMS_WRITE); +end; + + +{METHODDEF} +procedure close_ems_store (cinfo : j_common_ptr; + info : backing_store_ptr); +var + ctx : EMScontext; +begin + ctx.ax := $4500; + ctx.dx := info^.handle.ems_handle; + jems_calldriver(ctx); + TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info^.handle.ems_handle); + { we ignore any error return from the driver } +end; + + +{LOCAL} +function open_ems_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long) : boolean; +var + ctx : EMScontext; +begin + { Is EMS driver there? } + if (jems_available = 0) then + begin + open_ems_store := FALSE; + exit; + end; + + { Get status, make sure EMS is OK } + ctx.ax := $4000; + jems_calldriver(ctx); + if (hi(ctx.ax) <> 0) then + begin + open_ems_store := FALSE; + exit; + end; + + { Get version, must be >= 4.0 } + ctx.ax := $4600; + jems_calldriver(ctx); + if (hi(ctx.ax) <> 0) or (lo(ctx.ax) < $40) then + begin + open_ems_store := FALSE; + exit; + end; + + { Try to allocate requested space } + ctx.ax := $4300; + ctx.bx := ushort ((total_bytes_needed + + EMSPAGESIZE-long(1)) div EMSPAGESIZE); + jems_calldriver(ctx); + if (hi(ctx.ax) <> 0) then + begin + open_ems_store := FALSE; + exit; + end; + + { Succeeded, save the handle and away we go } + info^.handle.ems_handle := ctx.dx; + info^.read_backing_store := read_ems_store; + info^.write_backing_store := write_ems_store; + info^.close_backing_store := close_ems_store; + TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx); + open_ems_store := TRUE; { succeeded } +end; + +{$endif} { EMS_SUPPORTED } + +{ Initial opening of a backing-store object. This must fill in the + read/write/close pointers in the object. The read/write routines + may take an error exit if the specified maximum file size is exceeded. + (If jpeg_mem_available always returns a large value, this routine can + just take an error exit.) } + + + + +{ Initial opening of a backing-store object. } + +{GLOBAL} +procedure jpeg_open_backing_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long); +begin + { Try extended memory, then expanded memory, then regular file. } +{$ifdef XMS_SUPPORTED} + if (open_xms_store(cinfo, info, total_bytes_needed)) then + exit; +{$endif} +{$ifdef EMS_SUPPORTED} + if (open_ems_store(cinfo, info, total_bytes_needed)) then + exit; +{$endif} + if (open_file_store(cinfo, info, total_bytes_needed)) then + exit; + ERREXITS(cinfo, JERR_TFILE_CREATE, ''); +end; + +{ These routines take care of any system-dependent initialization and + cleanup required. jpeg_mem_init will be called before anything is + allocated (and, therefore, nothing in cinfo is of use except the error + manager pointer). It should return a suitable default value for + max_memory_to_use; this may subsequently be overridden by the surrounding + application. (Note that max_memory_to_use is only important if + jpeg_mem_available chooses to consult it ... no one else will.) + jpeg_mem_term may assume that all requested memory has been freed and that + all opened backing-store objects have been closed. } + + +{ These routines take care of any system-dependent initialization and + cleanup required. } + + +{GLOBAL} +function jpeg_mem_init (cinfo : j_common_ptr) : long; +begin + next_file_num := 0; { initialize temp file name generator } + jpeg_mem_init := DEFAULT_MAX_MEM; { default for max_memory_to_use } +end; + +{GLOBAL} +procedure jpeg_mem_term (cinfo : j_common_ptr); +begin + { Microsoft C, at least in v6.00A, will not successfully reclaim freed + blocks of size > 32Kbytes unless we give it a kick in the rear, + like so: } + +{$ifdef NEED_FHEAPMIN} + _fheapmin(); +{$endif} +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmemdosa_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmemdosa_del.pas new file mode 100644 index 0000000..593d409 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmemdosa_del.pas @@ -0,0 +1,365 @@ +Unit jmemdosa; + +{$G+} {enable 286/287 instructions } + +{ Original: jmemdosa.asm ; Copyright (C) 1992, Thomas G. Lane. + Based on code contributed by Ge' Weijers. } + +{ This file contains low-level interface routines to support the MS-DOS + backing store manager (jmemdos.c). Routines are provided to access disk + files through direct DOS calls, and to access XMS and EMS drivers. } + +interface + +uses + jmorecfg; + +type + XMSDRIVER = pointer; {far} { actually a pointer to code } +type + XMScontext = packed record { registers for calling XMS driver } + ax, dx, bx : ushort; + ds_si : pointer; {far} + end; +type + EMScontext = packed record { registers for calling EMS driver } + ax, dx, bx : ushort; + ds_si : pointer; {far} + end; +{ offset is a reserved word in BASM } + +function jdos_open (var handle : short {far}; const filename {: PChar}) : short; + +function jdos_close (handle : short) : short; + +function jdos_seek (handle : short; offs : long) : short; + +function jdos_read (handle : short; buffer : pointer; {FAR} + count : ushort) : short; +function jdos_write (handle : short; buffer : pointer; {FAR} + count : ushort) : short; + +procedure jxms_getdriver (var driver : XMSDRIVER); + +procedure jxms_calldriver (driver : XMSDRIVER; + var ctx : XMScontext); +function jems_available : short; + +procedure jems_calldriver (var ctx : EMScontext); + + +implementation + + +function jdos_open (var handle : short {far}; + const filename {: PChar}) : short; assembler; +{ Create and open a temporary file } +label + open_err; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov cx,0 { normal file attributes } + lds dx, filename { get filename pointer } + mov ah,3ch { create file } + int 21h + jc open_err { if failed, return error code } + lds bx, handle { get handle pointer } + mov word ptr [bx],ax { save the handle } + xor ax,ax { return zero for OK } +open_err: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jdos_open } + + +function jdos_close (handle : short) : short; assembler; +{ Close the file handle } +label + close_err; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov bx, handle { file handle } + mov ah,3eh { close file } + int 21h + jc close_err { if failed, return error code } + xor ax,ax { return zero for OK } +close_err: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jdos_close } + + + +function jdos_seek (handle : short; offs : long) : short; assembler; +{ Set file position } +label + seek_err; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov bx, handle { file handle } + mov dx, offs.word { LS offset } + mov cx, offs.word[2] { MS offset } + mov ax,4200h { absolute seek } + int 21h + jc seek_err { if failed, return error code } + xor ax,ax { return zero for OK } +seek_err: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jdos_seek } + + +function jdos_read (handle : short; buffer : pointer; {FAR} + count : ushort) : short; assembler; +{ Read from file } +label + read_ok, read_err; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov bx, handle { file handle } + lds dx, buffer { buffer address } + mov cx, count { number of bytes } + mov ah,3fh { read file } + int 21h + jc read_err { if failed, return error code } + cmp ax, count { make sure all bytes were read } + je read_ok + mov ax,1 { else return 1 for not OK } + jmp read_err +read_ok: + xor ax,ax { return zero for OK } +read_err: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jdos_read } + + + +function jdos_write (handle : short; buffer : pointer; {FAR} + count : ushort) : short; assembler; +{ Write to file } +label + write_ok, write_err; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov bx, handle { file handle } + lds dx, buffer { buffer address } + mov cx, count { number of bytes } + mov ah,40h { write file } + int 21h + jc write_err { if failed, return error code } + cmp ax, count { make sure all bytes written } + je write_ok + mov ax,1 { else return 1 for not OK } + jmp write_err +write_ok: + xor ax,ax { return zero for OK } +write_err: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jdos_write } + + + +procedure jxms_getdriver (var driver : XMSDRIVER); assembler; +{ Get the address of the XMS driver, or NIL if not available } +label + xmsavail, xmsavail_done; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov ax,4300h { call multiplex interrupt with } + int 2fh { a magic cookie, hex 4300 } + cmp al,80h { AL should contain hex 80 } + je xmsavail + xor dx,dx { no XMS driver available } + xor ax,ax { return a nil pointer } + jmp xmsavail_done +xmsavail: + mov ax,4310h { fetch driver address with } + int 2fh { another magic cookie } + mov dx,es { copy address to dx:ax } + mov ax,bx +xmsavail_done: + les bx,dword ptr [bp+6] { get pointer to return value } + mov word ptr es:[bx],ax + mov word ptr es:[bx+2],dx + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jxms_getdriver } + +procedure jxms_calldriver (driver : XMSDRIVER; + var ctx : XMScontext); assembler; +{ The XMScontext structure contains values for the AX,DX,BX,SI,DS registers.} +{ These are loaded, the XMS call is performed, and the new values of the } +{ AX,DX,BX registers are written back to the context structure. } +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + les bx, ctx { get XMScontext pointer } + mov ax,word ptr es:[bx] { load registers } + mov dx,word ptr es:[bx+2] + mov si,word ptr es:[bx+6] + mov ds,word ptr es:[bx+8] + mov bx,word ptr es:[bx+4] + call dword ptr driver { call the driver } + mov cx,bx { save returned BX for a sec } + les bx, ctx { get XMScontext pointer } + mov word ptr es:[bx],ax { put back ax,dx,bx } + mov word ptr es:[bx+2],dx + mov word ptr es:[bx+4],cx + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jxms_calldriver } + + + +function jems_available : short; assembler; +{ Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)} +label + no_ems, avail_done; +const + ASCII_device_name : packed array[0..7] of char = 'EMMXXXX0'; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov ax,3567h { get interrupt vector 67h } + int 21h + push cs + pop ds + mov di,000ah { check offs 10 in returned seg } + lea si, ASCII_device_name { against literal string } + mov cx,8 + cld + repe cmpsb + jne no_ems + mov ax,1 { match, it's there } + jmp avail_done +no_ems: xor ax,ax { it's not there } +avail_done: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jems_available } + + +procedure jems_calldriver (var ctx : EMScontext); assembler; +{ The EMScontext structure contains values for the AX,DX,BX,SI,DS registers. } +{ These are loaded, the EMS trap is performed, and the new values of the } +{ AX,DX,BX registers are written back to the context structure. } +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + + les bx, ctx { get EMScontext pointer } + mov ax, es:[bx].EMScontext.&ax { load registers } + mov dx, es:[bx].EMScontext.&dx + mov si, es:[bx].EMScontext.&ds_si.word + mov ds, es:[bx].EMScontext.&ds_si.word[2] + mov bx, es:[bx].EMScontext.&bx + int 67h { call the EMS driver } + mov cx,bx { save returned BX for a sec } + les bx, ctx { get EMScontext pointer } + mov es:[bx].EMScontext.&ax, ax { put back ax,dx,bx } + mov es:[bx].EMScontext.&dx, dx + mov es:[bx].EMScontext.&bx, cx + + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jems_calldriver } + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmemmgr_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmemmgr_del.pas new file mode 100644 index 0000000..78039a7 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmemmgr_del.pas @@ -0,0 +1,1285 @@ +unit jmemmgr_del; + +{ This file contains the JPEG system-independent memory management + routines. This code is usable across a wide variety of machines; most + of the system dependencies have been isolated in a separate file. + The major functions provided here are: + * pool-based allocation and freeing of memory; + * policy decisions about how to divide available memory among the + virtual arrays; + * control logic for swapping virtual arrays between main memory and + backing storage. + The separate system-dependent file provides the actual backing-storage + access code, and it contains the policy decision about how much total + main memory to use. + This file is system-dependent in the sense that some of its functions + are unnecessary in some systems. For example, if there is enough virtual + memory so that backing storage will never be used, much of the virtual + array control logic could be removed. (Of course, if you have that much + memory then you shouldn't care about a little bit of unused code...) } + +{ Original : jmemmgr.c ; Copyright (C) 1991-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jutils_del, +{$IFDEF VER70} +{$ifndef NO_GETENV} + Dos, { DOS unit should declare getenv() } + { function GetEnv(name : string) : string; } +{$endif} + jmemdos; { import the system-dependent declarations } +{$ELSE} + jmemnobs_del; + {$DEFINE NO_GETENV} +{$ENDIF} + +{ Memory manager initialization. + When this is called, only the error manager pointer is valid in cinfo! } + +{GLOBAL} +procedure jinit_memory_mgr (cinfo : j_common_ptr); + +implementation + + +{ Some important notes: + The allocation routines provided here must never return NIL. + They should exit to error_exit if unsuccessful. + + It's not a good idea to try to merge the sarray and barray routines, + even though they are textually almost the same, because samples are + usually stored as bytes while coefficients are shorts or ints. Thus, + in machines where byte pointers have a different representation from + word pointers, the resulting machine code could not be the same. } + + +{ Many machines require storage alignment: longs must start on 4-byte + boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc() + always returns pointers that are multiples of the worst-case alignment + requirement, and we had better do so too. + There isn't any really portable way to determine the worst-case alignment + requirement. This module assumes that the alignment requirement is + multiples of sizeof(ALIGN_TYPE). + By default, we define ALIGN_TYPE as double. This is necessary on some + workstations (where doubles really do need 8-byte alignment) and will work + fine on nearly everything. If your machine has lesser alignment needs, + you can save a few bytes by making ALIGN_TYPE smaller. + The only place I know of where this will NOT work is certain Macintosh + 680x0 compilers that define double as a 10-byte IEEE extended float. + Doing 10-byte alignment is counterproductive because longwords won't be + aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have + such a compiler. } + +{$ifndef ALIGN_TYPE} { so can override from jconfig.h } +type + ALIGN_TYPE = double; +{$endif} + + +{ We allocate objects from "pools", where each pool is gotten with a single + request to jpeg_get_small() or jpeg_get_large(). There is no per-object + overhead within a pool, except for alignment padding. Each pool has a + header with a link to the next pool of the same class. + Small and large pool headers are identical except that the latter's + link pointer must be FAR on 80x86 machines. + Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE + field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple + of the alignment requirement of ALIGN_TYPE. } + +type + small_pool_ptr = ^small_pool_hdr; + small_pool_hdr = record + case byte of + 0:(hdr : record + next : small_pool_ptr; { next in list of pools } + bytes_used : size_t; { how many bytes already used within pool } + bytes_left : size_t; { bytes still available in this pool } + end); + 1:(dummy : ALIGN_TYPE); { included in union to ensure alignment } + end; {small_pool_hdr;} + +type + large_pool_ptr = ^large_pool_hdr; {FAR} + large_pool_hdr = record + case byte of + 0:(hdr : record + next : large_pool_ptr; { next in list of pools } + bytes_used : size_t; { how many bytes already used within pool } + bytes_left : size_t; { bytes still available in this pool } + end); + 1:(dummy : ALIGN_TYPE); { included in union to ensure alignment } + end; {large_pool_hdr;} + + +{ Here is the full definition of a memory manager object. } + +type + my_mem_ptr = ^my_memory_mgr; + my_memory_mgr = record + pub : jpeg_memory_mgr; { public fields } + + { Each pool identifier (lifetime class) names a linked list of pools. } + small_list : array[0..JPOOL_NUMPOOLS-1] of small_pool_ptr ; + large_list : array[0..JPOOL_NUMPOOLS-1] of large_pool_ptr ; + + { Since we only have one lifetime class of virtual arrays, only one + linked list is necessary (for each datatype). Note that the virtual + array control blocks being linked together are actually stored somewhere + in the small-pool list. } + + virt_sarray_list : jvirt_sarray_ptr; + virt_barray_list : jvirt_barray_ptr; + + { This counts total space obtained from jpeg_get_small/large } + total_space_allocated : long; + + { alloc_sarray and alloc_barray set this value for use by virtual + array routines. } + + last_rowsperchunk : JDIMENSION; { from most recent alloc_sarray/barray } + end; {my_memory_mgr;} + + {$ifndef AM_MEMORY_MANAGER} { only jmemmgr.c defines these } + +{ The control blocks for virtual arrays. + Note that these blocks are allocated in the "small" pool area. + System-dependent info for the associated backing store (if any) is hidden + inside the backing_store_info struct. } +type + jvirt_sarray_control = record + mem_buffer : JSAMPARRAY; { => the in-memory buffer } + rows_in_array : JDIMENSION; { total virtual array height } + samplesperrow : JDIMENSION; { width of array (and of memory buffer) } + maxaccess : JDIMENSION; { max rows accessed by access_virt_sarray } + rows_in_mem : JDIMENSION; { height of memory buffer } + rowsperchunk : JDIMENSION; { allocation chunk size in mem_buffer } + cur_start_row : JDIMENSION; { first logical row # in the buffer } + first_undef_row : JDIMENSION; { row # of first uninitialized row } + pre_zero : boolean; { pre-zero mode requested? } + dirty : boolean; { do current buffer contents need written? } + b_s_open : boolean; { is backing-store data valid? } + next : jvirt_sarray_ptr; { link to next virtual sarray control block } + b_s_info : backing_store_info; { System-dependent control info } + end; + + jvirt_barray_control = record + mem_buffer : JBLOCKARRAY; { => the in-memory buffer } + rows_in_array : JDIMENSION; { total virtual array height } + blocksperrow : JDIMENSION; { width of array (and of memory buffer) } + maxaccess : JDIMENSION; { max rows accessed by access_virt_barray } + rows_in_mem : JDIMENSION; { height of memory buffer } + rowsperchunk : JDIMENSION; { allocation chunk size in mem_buffer } + cur_start_row : JDIMENSION; { first logical row # in the buffer } + first_undef_row : JDIMENSION; { row # of first uninitialized row } + pre_zero : boolean; { pre-zero mode requested? } + dirty : boolean; { do current buffer contents need written? } + b_s_open : boolean; { is backing-store data valid? } + next : jvirt_barray_ptr; { link to next virtual barray control block } + b_s_info : backing_store_info; { System-dependent control info } + end; + {$endif} { AM_MEMORY_MANAGER} + +{$ifdef MEM_STATS} { optional extra stuff for statistics } + +{LOCAL} +procedure print_mem_stats (cinfo : j_common_ptr; pool_id : int); +var + mem : my_mem_ptr; + shdr_ptr : small_pool_ptr; + lhdr_ptr : large_pool_ptr; +begin + mem := my_mem_ptr (cinfo^.mem); + + { Since this is only a debugging stub, we can cheat a little by using + fprintf directly rather than going through the trace message code. + This is helpful because message parm array can't handle longs. } + + WriteLn(output, 'Freeing pool ', pool_id,', total space := ', + mem^.total_space_allocated); + + lhdr_ptr := mem^.large_list[pool_id]; + while (lhdr_ptr <> NIL) do + begin + WriteLn(output, ' Large chunk used ', + long (lhdr_ptr^.hdr.bytes_used)); + lhdr_ptr := lhdr_ptr^.hdr.next; + end; + + shdr_ptr := mem^.small_list[pool_id]; + + while (shdr_ptr <> NIL) do + begin + WriteLn(output, ' Small chunk used ', + long (shdr_ptr^.hdr.bytes_used), ' free ', + long (shdr_ptr^.hdr.bytes_left) ); + shdr_ptr := shdr_ptr^.hdr.next; + end; +end; + +{$endif} { MEM_STATS } + + +{LOCAL} +procedure out_of_memory (cinfo : j_common_ptr; which : int); +{ Report an out-of-memory error and stop execution } +{ If we compiled MEM_STATS support, report alloc requests before dying } +begin +{$ifdef MEM_STATS} + cinfo^.err^.trace_level := 2; { force self_destruct to report stats } +{$endif} + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which); +end; + + +{ Allocation of "small" objects. + + For these, we use pooled storage. When a new pool must be created, + we try to get enough space for the current request plus a "slop" factor, + where the slop will be the amount of leftover space in the new pool. + The speed vs. space tradeoff is largely determined by the slop values. + A different slop value is provided for each pool class (lifetime), + and we also distinguish the first pool of a class from later ones. + NOTE: the values given work fairly well on both 16- and 32-bit-int + machines, but may be too small if longs are 64 bits or more. } + +const + first_pool_slop : array[0..JPOOL_NUMPOOLS-1] of size_t = + (1600, { first PERMANENT pool } + 16000); { first IMAGE pool } + +const + extra_pool_slop : array[0..JPOOL_NUMPOOLS-1] of size_t = + (0, { additional PERMANENT pools } + 5000); { additional IMAGE pools } + +const + MIN_SLOP = 50; { greater than 0 to avoid futile looping } + + +{METHODDEF} +function alloc_small (cinfo : j_common_ptr; + pool_id : int; + sizeofobject : size_t) : pointer; +type + byteptr = ^byte; +{ Allocate a "small" object } +var + mem : my_mem_ptr; + hdr_ptr, prev_hdr_ptr : small_pool_ptr; + data_ptr : byteptr; + odd_bytes, min_request, slop : size_t; +begin + mem := my_mem_ptr (cinfo^.mem); + + { Check for unsatisfiable request (do now to ensure no overflow below) } + if (sizeofobject > size_t(MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr))) then + out_of_memory(cinfo, 1); { request exceeds malloc's ability } + + { Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) } + odd_bytes := sizeofobject mod SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) then + Inc(sizeofobject, SIZEOF(ALIGN_TYPE) - odd_bytes); + + { See if space is available in any existing pool } + if (pool_id < 0) or (pool_id >= JPOOL_NUMPOOLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_POOL_ID, pool_id); { safety check } + prev_hdr_ptr := NIL; + hdr_ptr := mem^.small_list[pool_id]; + while (hdr_ptr <> NIL) do + begin + if (hdr_ptr^.hdr.bytes_left >= sizeofobject) then + break; { found pool with enough space } + prev_hdr_ptr := hdr_ptr; + hdr_ptr := hdr_ptr^.hdr.next; + end; + + { Time to make a new pool? } + if (hdr_ptr = NIL) then + begin + { min_request is what we need now, slop is what will be leftover } + min_request := sizeofobject + SIZEOF(small_pool_hdr); + if (prev_hdr_ptr = NIL) then { first pool in class? } + slop := first_pool_slop[pool_id] + else + slop := extra_pool_slop[pool_id]; + { Don't ask for more than MAX_ALLOC_CHUNK } + if (slop > size_t (MAX_ALLOC_CHUNK-min_request)) then + slop := size_t (MAX_ALLOC_CHUNK-min_request); + { Try to get space, if fail reduce slop and try again } + while TRUE do + begin + hdr_ptr := small_pool_ptr(jpeg_get_small(cinfo, min_request + slop)); + if (hdr_ptr <> NIL) then + break; + slop := slop div 2; + if (slop < MIN_SLOP) then { give up when it gets real small } + out_of_memory(cinfo, 2); { jpeg_get_small failed } + end; + Inc(mem^.total_space_allocated, min_request + slop); + { Success, initialize the new pool header and add to end of list } + hdr_ptr^.hdr.next := NIL; + hdr_ptr^.hdr.bytes_used := 0; + hdr_ptr^.hdr.bytes_left := sizeofobject + slop; + if (prev_hdr_ptr = NIL) then { first pool in class? } + mem^.small_list[pool_id] := hdr_ptr + else + prev_hdr_ptr^.hdr.next := hdr_ptr; + end; + + { OK, allocate the object from the current pool } + data_ptr := byteptr (hdr_ptr); + Inc(small_pool_ptr(data_ptr)); { point to first data byte in pool } + Inc(data_ptr, hdr_ptr^.hdr.bytes_used); { point to place for object } + Inc(hdr_ptr^.hdr.bytes_used, sizeofobject); + Dec(hdr_ptr^.hdr.bytes_left, sizeofobject); + + alloc_small := pointer(data_ptr); +end; + + +{ Allocation of "large" objects. + + The external semantics of these are the same as "small" objects, + except that FAR pointers are used on 80x86. However the pool + management heuristics are quite different. We assume that each + request is large enough that it may as well be passed directly to + jpeg_get_large; the pool management just links everything together + so that we can free it all on demand. + Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY + structures. The routines that create these structures (see below) + deliberately bunch rows together to ensure a large request size. } + +{METHODDEF} +function alloc_large (cinfo : j_common_ptr; + pool_id : int; + sizeofobject : size_t) : pointer; +{ Allocate a "large" object } +var + mem : my_mem_ptr; + hdr_ptr : large_pool_ptr; + odd_bytes : size_t; +var + dest_ptr : large_pool_ptr; +begin + mem := my_mem_ptr (cinfo^.mem); + + { Check for unsatisfiable request (do now to ensure no overflow below) } + if (sizeofobject > size_t (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr))) then + out_of_memory(cinfo, 3); { request exceeds malloc's ability } + + { Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) } + odd_bytes := sizeofobject mod SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) then + Inc(sizeofobject, SIZEOF(ALIGN_TYPE) - odd_bytes); + + { Always make a new pool } + if (pool_id < 0) or (pool_id >= JPOOL_NUMPOOLS) then + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); { safety check } + + hdr_ptr := large_pool_ptr (jpeg_get_large(cinfo, sizeofobject + + SIZEOF(large_pool_hdr))); + if (hdr_ptr = NIL) then + out_of_memory(cinfo, 4); { jpeg_get_large failed } + Inc(mem^.total_space_allocated, sizeofobject + SIZEOF(large_pool_hdr)); + + { Success, initialize the new pool header and add to list } + hdr_ptr^.hdr.next := mem^.large_list[pool_id]; + { We maintain space counts in each pool header for statistical purposes, + even though they are not needed for allocation. } + + hdr_ptr^.hdr.bytes_used := sizeofobject; + hdr_ptr^.hdr.bytes_left := 0; + mem^.large_list[pool_id] := hdr_ptr; + + {alloc_large := pointerFAR (hdr_ptr + 1); - point to first data byte in pool } + dest_ptr := hdr_ptr; + Inc(large_pool_ptr(dest_ptr)); + alloc_large := dest_ptr; +end; + + +{ Creation of 2-D sample arrays. + The pointers are in near heap, the samples themselves in FAR heap. + + To minimize allocation overhead and to allow I/O of large contiguous + blocks, we allocate the sample rows in groups of as many rows as possible + without exceeding MAX_ALLOC_CHUNK total bytes per allocation request. + NB: the virtual array control routines, later in this file, know about + this chunking of rows. The rowsperchunk value is left in the mem manager + object so that it can be saved away if this sarray is the workspace for + a virtual array. } + +{METHODDEF} +function alloc_sarray (cinfo : j_common_ptr; + pool_id : int; + samplesperrow : JDIMENSION; + numrows : JDIMENSION) : JSAMPARRAY; +{ Allocate a 2-D sample array } +var + mem : my_mem_ptr; + the_result : JSAMPARRAY; + workspace : JSAMPROW; + rowsperchunk, currow, i : JDIMENSION; + ltemp : long; +begin + mem := my_mem_ptr(cinfo^.mem); + + { Calculate max # of rows allowed in one allocation chunk } + ltemp := (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) div + (long(samplesperrow) * SIZEOF(JSAMPLE)); + if (ltemp <= 0) then + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < long(numrows)) then + rowsperchunk := JDIMENSION (ltemp) + else + rowsperchunk := numrows; + mem^.last_rowsperchunk := rowsperchunk; + + { Get space for row pointers (small object) } + the_result := JSAMPARRAY (alloc_small(cinfo, pool_id, + size_t (numrows * SIZEOF(JSAMPROW)))); + + { Get the rows themselves (large objects) } + currow := 0; + while (currow < numrows) do + begin + {rowsperchunk := MIN(rowsperchunk, numrows - currow);} + if rowsperchunk > numrows - currow then + rowsperchunk := numrows - currow; + + workspace := JSAMPROW (alloc_large(cinfo, pool_id, + size_t (size_t(rowsperchunk) * size_t(samplesperrow) + * SIZEOF(JSAMPLE))) ); + for i := pred(rowsperchunk) downto 0 do + begin + the_result^[currow] := workspace; + Inc(currow); + Inc(JSAMPLE_PTR(workspace), samplesperrow); + end; + end; + + alloc_sarray := the_result; +end; + + +{ Creation of 2-D coefficient-block arrays. + This is essentially the same as the code for sample arrays, above. } + +{METHODDEF} +function alloc_barray (cinfo : j_common_ptr; + pool_id : int; + blocksperrow : JDIMENSION; + numrows : JDIMENSION) : JBLOCKARRAY; +{ Allocate a 2-D coefficient-block array } +var + mem : my_mem_ptr; + the_result : JBLOCKARRAY; + workspace : JBLOCKROW; + rowsperchunk, currow, i : JDIMENSION; + ltemp : long; +begin + mem := my_mem_ptr(cinfo^.mem); + + { Calculate max # of rows allowed in one allocation chunk } + ltemp := (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) div + (long(blocksperrow) * SIZEOF(JBLOCK)); + if (ltemp <= 0) then + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < long(numrows)) then + rowsperchunk := JDIMENSION (ltemp) + else + rowsperchunk := numrows; + mem^.last_rowsperchunk := rowsperchunk; + + { Get space for row pointers (small object) } + the_result := JBLOCKARRAY (alloc_small(cinfo, pool_id, + size_t (numrows * SIZEOF(JBLOCKROW))) ); + + { Get the rows themselves (large objects) } + currow := 0; + while (currow < numrows) do + begin + {rowsperchunk := MIN(rowsperchunk, numrows - currow);} + if rowsperchunk > numrows - currow then + rowsperchunk := numrows - currow; + + workspace := JBLOCKROW (alloc_large(cinfo, pool_id, + size_t (size_t(rowsperchunk) * size_t(blocksperrow) + * SIZEOF(JBLOCK))) ); + for i := rowsperchunk downto 1 do + begin + the_result^[currow] := workspace; + Inc(currow); + Inc(JBLOCK_PTR(workspace), blocksperrow); + end; + end; + + alloc_barray := the_result; +end; + + +{ About virtual array management: + + The above "normal" array routines are only used to allocate strip buffers + (as wide as the image, but just a few rows high). Full-image-sized buffers + are handled as "virtual" arrays. The array is still accessed a strip at a + time, but the memory manager must save the whole array for repeated + accesses. The intended implementation is that there is a strip buffer in + memory (as high as is possible given the desired memory limit), plus a + backing file that holds the rest of the array. + + The request_virt_array routines are told the total size of the image and + the maximum number of rows that will be accessed at once. The in-memory + buffer must be at least as large as the maxaccess value. + + The request routines create control blocks but not the in-memory buffers. + That is postponed until realize_virt_arrays is called. At that time the + total amount of space needed is known (approximately, anyway), so free + memory can be divided up fairly. + + The access_virt_array routines are responsible for making a specific strip + area accessible (after reading or writing the backing file, if necessary). + Note that the access routines are told whether the caller intends to modify + the accessed strip; during a read-only pass this saves having to rewrite + data to disk. The access routines are also responsible for pre-zeroing + any newly accessed rows, if pre-zeroing was requested. + + In current usage, the access requests are usually for nonoverlapping + strips; that is, successive access start_row numbers differ by exactly + num_rows := maxaccess. This means we can get good performance with simple + buffer dump/reload logic, by making the in-memory buffer be a multiple + of the access height; then there will never be accesses across bufferload + boundaries. The code will still work with overlapping access requests, + but it doesn't handle bufferload overlaps very efficiently. } + + +{METHODDEF} +function request_virt_sarray (cinfo : j_common_ptr; + pool_id : int; + pre_zero : boolean; + samplesperrow : JDIMENSION; + numrows : JDIMENSION; + maxaccess : JDIMENSION) : jvirt_sarray_ptr; +{ Request a virtual 2-D sample array } +var + mem : my_mem_ptr; + the_result : jvirt_sarray_ptr; +begin + mem := my_mem_ptr (cinfo^.mem); + + { Only IMAGE-lifetime virtual arrays are currently supported } + if (pool_id <> JPOOL_IMAGE) then + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); { safety check } + + { get control block } + the_result := jvirt_sarray_ptr (alloc_small(cinfo, pool_id, + SIZEOF(jvirt_sarray_control)) ); + + the_result^.mem_buffer := NIL; { marks array not yet realized } + the_result^.rows_in_array := numrows; + the_result^.samplesperrow := samplesperrow; + the_result^.maxaccess := maxaccess; + the_result^.pre_zero := pre_zero; + the_result^.b_s_open := FALSE; { no associated backing-store object } + the_result^.next := mem^.virt_sarray_list; { add to list of virtual arrays } + mem^.virt_sarray_list := the_result; + + request_virt_sarray := the_result; +end; + + +{METHODDEF} +function request_virt_barray (cinfo : j_common_ptr; + pool_id : int; + pre_zero : boolean; + blocksperrow : JDIMENSION; + numrows : JDIMENSION; + maxaccess : JDIMENSION) : jvirt_barray_ptr; +{ Request a virtual 2-D coefficient-block array } +var + mem : my_mem_ptr; + the_result : jvirt_barray_ptr; +begin + mem := my_mem_ptr(cinfo^.mem); + + { Only IMAGE-lifetime virtual arrays are currently supported } + if (pool_id <> JPOOL_IMAGE) then + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); { safety check } + + { get control block } + the_result := jvirt_barray_ptr(alloc_small(cinfo, pool_id, + SIZEOF(jvirt_barray_control)) ); + + the_result^.mem_buffer := NIL; { marks array not yet realized } + the_result^.rows_in_array := numrows; + the_result^.blocksperrow := blocksperrow; + the_result^.maxaccess := maxaccess; + the_result^.pre_zero := pre_zero; + the_result^.b_s_open := FALSE; { no associated backing-store object } + the_result^.next := mem^.virt_barray_list; { add to list of virtual arrays } + mem^.virt_barray_list := the_result; + + request_virt_barray := the_result; +end; + + +{METHODDEF} +procedure realize_virt_arrays (cinfo : j_common_ptr); +{ Allocate the in-memory buffers for any unrealized virtual arrays } +var + mem : my_mem_ptr; + space_per_minheight, maximum_space, avail_mem : long; + minheights, max_minheights : long; + sptr : jvirt_sarray_ptr; + bptr : jvirt_barray_ptr; +begin + mem := my_mem_ptr (cinfo^.mem); + { Compute the minimum space needed (maxaccess rows in each buffer) + and the maximum space needed (full image height in each buffer). + These may be of use to the system-dependent jpeg_mem_available routine. } + + space_per_minheight := 0; + maximum_space := 0; + sptr := mem^.virt_sarray_list; + while (sptr <> NIL) do + begin + if (sptr^.mem_buffer = NIL) then + begin { if not realized yet } + Inc(space_per_minheight, long(sptr^.maxaccess) * + long(sptr^.samplesperrow) * SIZEOF(JSAMPLE)); + Inc(maximum_space, long(sptr^.rows_in_array) * + long(sptr^.samplesperrow) * SIZEOF(JSAMPLE)); + end; + sptr := sptr^.next; + end; + bptr := mem^.virt_barray_list; + while (bptr <> NIL) do + begin + if (bptr^.mem_buffer = NIL) then + begin { if not realized yet } + Inc(space_per_minheight, long(bptr^.maxaccess) * + long(bptr^.blocksperrow) * SIZEOF(JBLOCK)); + Inc(maximum_space, long(bptr^.rows_in_array) * + long(bptr^.blocksperrow) * SIZEOF(JBLOCK)); + end; + bptr := bptr^.next; + end; + + if (space_per_minheight <= 0) then + exit; { no unrealized arrays, no work } + + { Determine amount of memory to actually use; this is system-dependent. } + avail_mem := jpeg_mem_available(cinfo, space_per_minheight, maximum_space, + mem^.total_space_allocated); + + { If the maximum space needed is available, make all the buffers full + height; otherwise parcel it out with the same number of minheights + in each buffer. } + + if (avail_mem >= maximum_space) then + max_minheights := long(1000000000) + else + begin + max_minheights := avail_mem div space_per_minheight; + { If there doesn't seem to be enough space, try to get the minimum + anyway. This allows a "stub" implementation of jpeg_mem_available(). } + if (max_minheights <= 0) then + max_minheights := 1; + end; + + { Allocate the in-memory buffers and initialize backing store as needed. } + + sptr := mem^.virt_sarray_list; + while (sptr <> NIL) do + begin + if (sptr^.mem_buffer = NIL) then + begin { if not realized yet } + minheights := (long(sptr^.rows_in_array) - long(1)) div sptr^.maxaccess + long(1); + if (minheights <= max_minheights) then + begin + { This buffer fits in memory } + sptr^.rows_in_mem := sptr^.rows_in_array; + end + else + begin + { It doesn't fit in memory, create backing store. } + sptr^.rows_in_mem := JDIMENSION (max_minheights * sptr^.maxaccess); + jpeg_open_backing_store(cinfo, + @sptr^.b_s_info, + long(sptr^.rows_in_array) * + long(sptr^.samplesperrow) * + long(SIZEOF(JSAMPLE))); + sptr^.b_s_open := TRUE; + end; + sptr^.mem_buffer := alloc_sarray(cinfo, JPOOL_IMAGE, + sptr^.samplesperrow, sptr^.rows_in_mem); + sptr^.rowsperchunk := mem^.last_rowsperchunk; + sptr^.cur_start_row := 0; + sptr^.first_undef_row := 0; + sptr^.dirty := FALSE; + end; + sptr := sptr^.next; + end; + + bptr := mem^.virt_barray_list; + while (bptr <> NIL) do + begin + if (bptr^.mem_buffer = NIL) then + begin { if not realized yet } + minheights := (long(bptr^.rows_in_array) - long(1)) div bptr^.maxaccess + long(1); + if (minheights <= max_minheights) then + begin + { This buffer fits in memory } + bptr^.rows_in_mem := bptr^.rows_in_array; + end + else + begin + { It doesn't fit in memory, create backing store. } + bptr^.rows_in_mem := JDIMENSION (max_minheights * bptr^.maxaccess); + jpeg_open_backing_store(cinfo, + @bptr^.b_s_info, + long(bptr^.rows_in_array) * + long(bptr^.blocksperrow) * + long(SIZEOF(JBLOCK))); + bptr^.b_s_open := TRUE; + end; + bptr^.mem_buffer := alloc_barray(cinfo, JPOOL_IMAGE, + bptr^.blocksperrow, bptr^.rows_in_mem); + bptr^.rowsperchunk := mem^.last_rowsperchunk; + bptr^.cur_start_row := 0; + bptr^.first_undef_row := 0; + bptr^.dirty := FALSE; + end; + bptr := bptr^.next; + end; +end; + + +{LOCAL} +procedure do_sarray_io (cinfo : j_common_ptr; + ptr : jvirt_sarray_ptr; + writing : boolean); +{ Do backing store read or write of a virtual sample array } +var + bytesperrow, file_offset, byte_count, rows, thisrow, i : long; +begin + + bytesperrow := long(ptr^.samplesperrow * SIZEOF(JSAMPLE)); + file_offset := ptr^.cur_start_row * bytesperrow; + { Loop to read or write each allocation chunk in mem_buffer } + i := 0; + while i < long(ptr^.rows_in_mem) do + begin + + { One chunk, but check for short chunk at end of buffer } + {rows := MIN(long(ptr^.rowsperchunk), long(ptr^.rows_in_mem - i));} + rows := long(ptr^.rowsperchunk); + if rows > long(ptr^.rows_in_mem - i) then + rows := long(ptr^.rows_in_mem - i); + { Transfer no more than is currently defined } + thisrow := long (ptr^.cur_start_row) + i; + {rows := MIN(rows, long(ptr^.first_undef_row) - thisrow);} + if (rows > long(ptr^.first_undef_row) - thisrow) then + rows := long(ptr^.first_undef_row) - thisrow; + { Transfer no more than fits in file } + {rows := MIN(rows, long(ptr^.rows_in_array) - thisrow);} + if (rows > long(ptr^.rows_in_array) - thisrow) then + rows := long(ptr^.rows_in_array) - thisrow; + + if (rows <= 0) then { this chunk might be past end of file! } + break; + byte_count := rows * bytesperrow; + if (writing) then + ptr^.b_s_info.write_backing_store (cinfo, + @ptr^.b_s_info, + pointer {FAR} (ptr^.mem_buffer^[i]), + file_offset, byte_count) + else + ptr^.b_s_info.read_backing_store (cinfo, + @ptr^.b_s_info, + pointer {FAR} (ptr^.mem_buffer^[i]), + file_offset, byte_count); + Inc(file_offset, byte_count); + Inc(i, ptr^.rowsperchunk); + end; +end; + + +{LOCAL} +procedure do_barray_io (cinfo : j_common_ptr; + ptr : jvirt_barray_ptr; + writing : boolean); +{ Do backing store read or write of a virtual coefficient-block array } +var + bytesperrow, file_offset, byte_count, rows, thisrow, i : long; +begin + bytesperrow := long (ptr^.blocksperrow) * SIZEOF(JBLOCK); + file_offset := ptr^.cur_start_row * bytesperrow; + { Loop to read or write each allocation chunk in mem_buffer } + i := 0; + while (i < long(ptr^.rows_in_mem)) do + begin + { One chunk, but check for short chunk at end of buffer } + {rows := MIN(long(ptr^.rowsperchunk), long(ptr^.rows_in_mem - i));} + rows := long(ptr^.rowsperchunk); + if rows >long(ptr^.rows_in_mem - i) then + rows := long(ptr^.rows_in_mem - i); + { Transfer no more than is currently defined } + thisrow := long (ptr^.cur_start_row) + i; + {rows := MIN(rows, long(ptr^.first_undef_row - thisrow));} + if rows > long(ptr^.first_undef_row - thisrow) then + rows := long(ptr^.first_undef_row - thisrow); + { Transfer no more than fits in file } + {rows := MIN(rows, long (ptr^.rows_in_array - thisrow));} + if (rows > long (ptr^.rows_in_array - thisrow)) then + rows := long (ptr^.rows_in_array - thisrow); + + if (rows <= 0) then { this chunk might be past end of file! } + break; + byte_count := rows * bytesperrow; + if (writing) then + ptr^.b_s_info.write_backing_store (cinfo, + @ptr^.b_s_info, + {FAR} pointer(ptr^.mem_buffer^[i]), + file_offset, byte_count) + else + ptr^.b_s_info.read_backing_store (cinfo, + @ptr^.b_s_info, + {FAR} pointer(ptr^.mem_buffer^[i]), + file_offset, byte_count); + Inc(file_offset, byte_count); + Inc(i, ptr^.rowsperchunk); + end; +end; + + +{METHODDEF} +function access_virt_sarray (cinfo : j_common_ptr; + ptr : jvirt_sarray_ptr; + start_row : JDIMENSION; + num_rows : JDIMENSION; + writable : boolean ) : JSAMPARRAY; +{ Access the part of a virtual sample array starting at start_row } +{ and extending for num_rows rows. writable is true if } +{ caller intends to modify the accessed area. } +var + end_row : JDIMENSION; + undef_row : JDIMENSION; +var + bytesperrow : size_t; +var + ltemp : long; +begin + end_row := start_row + num_rows; + { debugging check } + if (end_row > ptr^.rows_in_array) or (num_rows > ptr^.maxaccess) or + (ptr^.mem_buffer = NIL) then + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + { Make the desired part of the virtual array accessible } + if (start_row < ptr^.cur_start_row) or + (end_row > ptr^.cur_start_row+ptr^.rows_in_mem) then + begin + if (not ptr^.b_s_open) then + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + { Flush old buffer contents if necessary } + if (ptr^.dirty) then + begin + do_sarray_io(cinfo, ptr, TRUE); + ptr^.dirty := FALSE; + end; + { Decide what part of virtual array to access. + Algorithm: if target address > current window, assume forward scan, + load starting at target address. If target address < current window, + assume backward scan, load so that target area is top of window. + Note that when switching from forward write to forward read, will have + start_row := 0, so the limiting case applies and we load from 0 anyway. } + if (start_row > ptr^.cur_start_row) then + begin + ptr^.cur_start_row := start_row; + end + else + begin + { use long arithmetic here to avoid overflow & unsigned problems } + + + ltemp := long(end_row) - long(ptr^.rows_in_mem); + if (ltemp < 0) then + ltemp := 0; { don't fall off front end of file } + ptr^.cur_start_row := JDIMENSION(ltemp); + end; + { Read in the selected part of the array. + During the initial write pass, we will do no actual read + because the selected part is all undefined. } + + do_sarray_io(cinfo, ptr, FALSE); + end; + { Ensure the accessed part of the array is defined; prezero if needed. + To improve locality of access, we only prezero the part of the array + that the caller is about to access, not the entire in-memory array. } + if (ptr^.first_undef_row < end_row) then + begin + if (ptr^.first_undef_row < start_row) then + begin + if (writable) then { writer skipped over a section of array } + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row := start_row; { but reader is allowed to read ahead } + end + else + begin + undef_row := ptr^.first_undef_row; + end; + if (writable) then + ptr^.first_undef_row := end_row; + if (ptr^.pre_zero) then + begin + bytesperrow := size_t(ptr^.samplesperrow) * SIZEOF(JSAMPLE); + Dec(undef_row, ptr^.cur_start_row); { make indexes relative to buffer } + Dec(end_row, ptr^.cur_start_row); + while (undef_row < end_row) do + begin + jzero_far({FAR} pointer(ptr^.mem_buffer^[undef_row]), bytesperrow); + Inc(undef_row); + end; + end + else + begin + if (not writable) then { reader looking at undefined data } + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + end; + end; + { Flag the buffer dirty if caller will write in it } + if (writable) then + ptr^.dirty := TRUE; + { Return address of proper part of the buffer } + access_virt_sarray := JSAMPARRAY(@ ptr^.mem_buffer^[start_row - ptr^.cur_start_row]); +end; + + +{METHODDEF} +function access_virt_barray (cinfo : j_common_ptr; + ptr : jvirt_barray_ptr; + start_row : JDIMENSION; + num_rows : JDIMENSION; + writable : boolean) : JBLOCKARRAY; +{ Access the part of a virtual block array starting at start_row } +{ and extending for num_rows rows. writable is true if } +{ caller intends to modify the accessed area. } +var + end_row : JDIMENSION; + undef_row : JDIMENSION; + ltemp : long; +var + bytesperrow : size_t; +begin + end_row := start_row + num_rows; + + { debugging check } + if (end_row > ptr^.rows_in_array) or (num_rows > ptr^.maxaccess) or + (ptr^.mem_buffer = NIL) then + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + { Make the desired part of the virtual array accessible } + if (start_row < ptr^.cur_start_row) or + (end_row > ptr^.cur_start_row+ptr^.rows_in_mem) then + begin + if (not ptr^.b_s_open) then + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + { Flush old buffer contents if necessary } + if (ptr^.dirty) then + begin + do_barray_io(cinfo, ptr, TRUE); + ptr^.dirty := FALSE; + end; + { Decide what part of virtual array to access. + Algorithm: if target address > current window, assume forward scan, + load starting at target address. If target address < current window, + assume backward scan, load so that target area is top of window. + Note that when switching from forward write to forward read, will have + start_row := 0, so the limiting case applies and we load from 0 anyway. } + + if (start_row > ptr^.cur_start_row) then + begin + ptr^.cur_start_row := start_row; + end + else + begin + { use long arithmetic here to avoid overflow & unsigned problems } + + ltemp := long(end_row) - long(ptr^.rows_in_mem); + if (ltemp < 0) then + ltemp := 0; { don't fall off front end of file } + ptr^.cur_start_row := JDIMENSION (ltemp); + end; + { Read in the selected part of the array. + During the initial write pass, we will do no actual read + because the selected part is all undefined. } + + do_barray_io(cinfo, ptr, FALSE); + end; + { Ensure the accessed part of the array is defined; prezero if needed. + To improve locality of access, we only prezero the part of the array + that the caller is about to access, not the entire in-memory array. } + + if (ptr^.first_undef_row < end_row) then + begin + if (ptr^.first_undef_row < start_row) then + begin + if (writable) then { writer skipped over a section of array } + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row := start_row; { but reader is allowed to read ahead } + end + else + begin + undef_row := ptr^.first_undef_row; + end; + if (writable) then + ptr^.first_undef_row := end_row; + if (ptr^.pre_zero) then + begin + bytesperrow := size_t (ptr^.blocksperrow) * SIZEOF(JBLOCK); + Dec(undef_row, ptr^.cur_start_row); { make indexes relative to buffer } + Dec(end_row, ptr^.cur_start_row); + while (undef_row < end_row) do + begin + jzero_far({FAR}pointer(ptr^.mem_buffer^[undef_row]), bytesperrow); + Inc(undef_row); + end; + end + else + begin + if (not writable) then { reader looking at undefined data } + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + end; + end; + { Flag the buffer dirty if caller will write in it } + if (writable) then + ptr^.dirty := TRUE; + { Return address of proper part of the buffer } + access_virt_barray := JBLOCKARRAY(@ ptr^.mem_buffer^[start_row - ptr^.cur_start_row]); +end; + + +{ Release all objects belonging to a specified pool. } + +{METHODDEF} +procedure free_pool (cinfo : j_common_ptr; pool_id : int); +var + mem : my_mem_ptr; + shdr_ptr : small_pool_ptr; + lhdr_ptr : large_pool_ptr; + space_freed : size_t; +var + sptr : jvirt_sarray_ptr; + bptr : jvirt_barray_ptr; +var + next_lhdr_ptr : large_pool_ptr; + next_shdr_ptr : small_pool_ptr; +begin + mem := my_mem_ptr(cinfo^.mem); + + if (pool_id < 0) or (pool_id >= JPOOL_NUMPOOLS) then + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); { safety check } + +{$ifdef MEM_STATS} + if (cinfo^.err^.trace_level > 1) then + print_mem_stats(cinfo, pool_id); { print pool's memory usage statistics } +{$endif} + + { If freeing IMAGE pool, close any virtual arrays first } + if (pool_id = JPOOL_IMAGE) then + begin + sptr := mem^.virt_sarray_list; + while (sptr <> NIL) do + begin + if (sptr^.b_s_open) then + begin { there may be no backing store } + sptr^.b_s_open := FALSE; { prevent recursive close if error } + sptr^.b_s_info.close_backing_store (cinfo, @sptr^.b_s_info); + end; + sptr := sptr^.next; + end; + mem^.virt_sarray_list := NIL; + bptr := mem^.virt_barray_list; + while (bptr <> NIL) do + begin + if (bptr^.b_s_open) then + begin { there may be no backing store } + bptr^.b_s_open := FALSE; { prevent recursive close if error } + bptr^.b_s_info.close_backing_store (cinfo, @bptr^.b_s_info); + end; + bptr := bptr^.next; + end; + mem^.virt_barray_list := NIL; + end; + + { Release large objects } + lhdr_ptr := mem^.large_list[pool_id]; + mem^.large_list[pool_id] := NIL; + + while (lhdr_ptr <> NIL) do + begin + next_lhdr_ptr := lhdr_ptr^.hdr.next; + space_freed := lhdr_ptr^.hdr.bytes_used + + lhdr_ptr^.hdr.bytes_left + + SIZEOF(large_pool_hdr); + jpeg_free_large(cinfo, {FAR} pointer(lhdr_ptr), space_freed); + Dec(mem^.total_space_allocated, space_freed); + lhdr_ptr := next_lhdr_ptr; + end; + + { Release small objects } + shdr_ptr := mem^.small_list[pool_id]; + mem^.small_list[pool_id] := NIL; + + while (shdr_ptr <> NIL) do + begin + next_shdr_ptr := shdr_ptr^.hdr.next; + space_freed := shdr_ptr^.hdr.bytes_used + + shdr_ptr^.hdr.bytes_left + + SIZEOF(small_pool_hdr); + jpeg_free_small(cinfo, pointer(shdr_ptr), space_freed); + Dec(mem^.total_space_allocated, space_freed); + shdr_ptr := next_shdr_ptr; + end; +end; + + +{ Close up shop entirely. + Note that this cannot be called unless cinfo^.mem is non-NIL. } + +{METHODDEF} +procedure self_destruct (cinfo : j_common_ptr); +var + pool : int; +begin + { Close all backing store, release all memory. + Releasing pools in reverse order might help avoid fragmentation + with some (brain-damaged) malloc libraries. } + + for pool := JPOOL_NUMPOOLS-1 downto JPOOL_PERMANENT do + begin + free_pool(cinfo, pool); + end; + + { Release the memory manager control block too. } + jpeg_free_small(cinfo, pointer(cinfo^.mem), SIZEOF(my_memory_mgr)); + cinfo^.mem := NIL; { ensures I will be called only once } + + jpeg_mem_term(cinfo); { system-dependent cleanup } +end; + + +{ Memory manager initialization. + When this is called, only the error manager pointer is valid in cinfo! } + +{GLOBAL} +procedure jinit_memory_mgr (cinfo : j_common_ptr); +var + mem : my_mem_ptr; + max_to_use : long; + pool : int; + test_mac : size_t; +{$ifndef NO_GETENV} +var + memenv : string; + code : integer; +{$endif} +begin + cinfo^.mem := NIL; { for safety if init fails } + + { Check for configuration errors. + SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably + doesn't reflect any real hardware alignment requirement. + The test is a little tricky: for X>0, X and X-1 have no one-bits + in common if and only if X is a power of 2, ie has only one one-bit. + Some compilers may give an "unreachable code" warning here; ignore it. } + {$push}{$warnings off} + if ((SIZEOF(ALIGN_TYPE) and (SIZEOF(ALIGN_TYPE)-1)) <> 0) then + ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE); + {$pop} + { MAX_ALLOC_CHUNK must be representable as type size_t, and must be + a multiple of SIZEOF(ALIGN_TYPE). + Again, an "unreachable code" warning may be ignored here. + But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. } + + test_mac := size_t (MAX_ALLOC_CHUNK); + if (long (test_mac) <> MAX_ALLOC_CHUNK) or + ((MAX_ALLOC_CHUNK mod SIZEOF(ALIGN_TYPE)) <> 0) then + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + + max_to_use := jpeg_mem_init(cinfo); { system-dependent initialization } + + { Attempt to allocate memory manager's control block } + mem := my_mem_ptr (jpeg_get_small(cinfo, SIZEOF(my_memory_mgr))); + + if (mem = NIL) then + begin + jpeg_mem_term(cinfo); { system-dependent cleanup } + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); + end; + + { OK, fill in the method pointers } + mem^.pub.alloc_small := alloc_small; + mem^.pub.alloc_large := alloc_large; + mem^.pub.alloc_sarray := alloc_sarray; + mem^.pub.alloc_barray := alloc_barray; + mem^.pub.request_virt_sarray := request_virt_sarray; + mem^.pub.request_virt_barray := request_virt_barray; + mem^.pub.realize_virt_arrays := realize_virt_arrays; + mem^.pub.access_virt_sarray := access_virt_sarray; + mem^.pub.access_virt_barray := access_virt_barray; + mem^.pub.free_pool := free_pool; + mem^.pub.self_destruct := self_destruct; + + { Make MAX_ALLOC_CHUNK accessible to other modules } + mem^.pub.max_alloc_chunk := MAX_ALLOC_CHUNK; + + { Initialize working state } + mem^.pub.max_memory_to_use := max_to_use; + + for pool := JPOOL_NUMPOOLS-1 downto JPOOL_PERMANENT do + begin + mem^.small_list[pool] := NIL; + mem^.large_list[pool] := NIL; + end; + mem^.virt_sarray_list := NIL; + mem^.virt_barray_list := NIL; + + mem^.total_space_allocated := SIZEOF(my_memory_mgr); + + { Declare ourselves open for business } + cinfo^.mem := @mem^.pub; + + { Check for an environment variable JPEGMEM; if found, override the + default max_memory setting from jpeg_mem_init. Note that the + surrounding application may again override this value. + If your system doesn't support getenv(), define NO_GETENV to disable + this feature. } + +{$ifndef NO_GETENV} + memenv := getenv('JPEGMEM'); + if (memenv <> '') then + begin + Val(memenv, max_to_use, code); + if (Code = 0) then + begin + max_to_use := max_to_use * long(1000); + mem^.pub.max_memory_to_use := max_to_use * long(1000); + end; + end; +{$endif} + +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmemnobs_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmemnobs_del.pas new file mode 100644 index 0000000..6d8279d --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmemnobs_del.pas @@ -0,0 +1,265 @@ +Unit jmemnobs_del; +{ Delphi3 -- > jmemnobs from jmemwin } +{ This file provides an Win32-compatible implementation of the system- + dependent portion of the JPEG memory manager. } + +{ Check jmemnobs.c } +{ Copyright (C) 1996, Jacques Nomssi Nzali } +//modified 2013 by Martin Schreiber + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jdeferr_del, + jerror_del, + jpeglib_del; + +{ The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + be requested in a single call to jpeg_get_large (and jpeg_get_small for that + matter, but that case should never come into play). This macro is needed + to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + On those machines, we expect that jconfig.h will provide a proper value. + On machines with 32-bit flat address spaces, any large constant may be used. + + NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + size_t and will be a multiple of sizeof(align_type). } + +{$IFDEF CPU16} +const + MAX_ALLOC_CHUNK = long(32752); +{$ELSE} +const + MAX_ALLOC_CHUNK = long(1000000000); +{$ENDIF} + +{GLOBAL} +procedure jpeg_open_backing_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long); + +{ These routines take care of any system-dependent initialization and + cleanup required. } + +{GLOBAL} +function jpeg_mem_init (cinfo : j_common_ptr) : long; + +{GLOBAL} +procedure jpeg_mem_term (cinfo : j_common_ptr); + +{ These two functions are used to allocate and release small chunks of + memory. (Typically the total amount requested through jpeg_get_small is + no more than 20K or so; this will be requested in chunks of a few K each.) + Behavior should be the same as for the standard library functions malloc + and free; in particular, jpeg_get_small must return NIL on failure. + On most systems, these ARE malloc and free. jpeg_free_small is passed the + size of the object being freed, just in case it's needed. + On an 80x86 machine using small-data memory model, these manage near heap. } + + +{ Near-memory allocation and freeing are controlled by the regular library + routines malloc() and free(). } + +{GLOBAL} +function jpeg_get_small (cinfo : j_common_ptr; + sizeofobject : size_t) : pointer; + +{GLOBAL} +{object is a reserved word in Borland Pascal } +procedure jpeg_free_small (cinfo : j_common_ptr; + an_object : pointer; + sizeofobject : size_t); + +{ These two functions are used to allocate and release large chunks of + memory (up to the total free space designated by jpeg_mem_available). + The interface is the same as above, except that on an 80x86 machine, + far pointers are used. On most other machines these are identical to + the jpeg_get/free_small routines; but we keep them separate anyway, + in case a different allocation strategy is desirable for large chunks. } + + +{ "Large" objects are allocated in far memory, if possible } + + +{GLOBAL} +function jpeg_get_large (cinfo : j_common_ptr; + sizeofobject : size_t) : voidp; {far} + +{GLOBAL} +procedure jpeg_free_large (cinfo : j_common_ptr; + {var?} an_object : voidp; {FAR} + sizeofobject : size_t); + +{ This routine computes the total memory space available for allocation. + It's impossible to do this in a portable way; our current solution is + to make the user tell us (with a default value set at compile time). + If you can actually get the available space, it's a good idea to subtract + a slop factor of 5% or so. } + +{GLOBAL} +function jpeg_mem_available (cinfo : j_common_ptr; + min_bytes_needed : long; + max_bytes_needed : long; + already_allocated : long) : long; + + +implementation + +{ This structure holds whatever state is needed to access a single + backing-store object. The read/write/close method pointers are called + by jmemmgr.c to manipulate the backing-store object; all other fields + are private to the system-dependent backing store routines. } + + + +{ These two functions are used to allocate and release small chunks of + memory. (Typically the total amount requested through jpeg_get_small is + no more than 20K or so; this will be requested in chunks of a few K each.) + Behavior should be the same as for the standard library functions malloc + and free; in particular, jpeg_get_small must return NIL on failure. + On most systems, these ARE malloc and free. jpeg_free_small is passed the + size of the object being freed, just in case it's needed. + On an 80x86 machine using small-data memory model, these manage near heap. } + + +{ Near-memory allocation and freeing are controlled by the regular library + routines malloc() and free(). } + +{GLOBAL} +function jpeg_get_small (cinfo : j_common_ptr; + sizeofobject : size_t) : pointer; +var + p : pointer; +begin + GetMem(p, sizeofobject); + jpeg_get_small := p; +end; + +{GLOBAL} +{object is a reserved word in Object Pascal } +procedure jpeg_free_small (cinfo : j_common_ptr; + an_object : pointer; + sizeofobject : size_t); +begin + FreeMem(an_object, sizeofobject); +end; + +{ These two functions are used to allocate and release large chunks of + memory (up to the total free space designated by jpeg_mem_available). + The interface is the same as above, except that on an 80x86 machine, + far pointers are used. On most other machines these are identical to + the jpeg_get/free_small routines; but we keep them separate anyway, + in case a different allocation strategy is desirable for large chunks. } + + + +{GLOBAL} +function jpeg_get_large (cinfo : j_common_ptr; + sizeofobject : size_t) : voidp; {far} +var + p : pointer; +begin + GetMem(p, sizeofobject); + jpeg_get_large := p; +end; + +{GLOBAL} +procedure jpeg_free_large (cinfo : j_common_ptr; + {var?} an_object : voidp; {FAR} + sizeofobject : size_t); +begin + Freemem(an_object, sizeofobject); +end; + +{ This routine computes the total space still available for allocation by + jpeg_get_large. If more space than this is needed, backing store will be + used. NOTE: any memory already allocated must not be counted. + + There is a minimum space requirement, corresponding to the minimum + feasible buffer sizes; jmemmgr.c will request that much space even if + jpeg_mem_available returns zero. The maximum space needed, enough to hold + all working storage in memory, is also passed in case it is useful. + Finally, the total space already allocated is passed. If no better + method is available, cinfo^.mem^.max_memory_to_use - already_allocated + is often a suitable calculation. + + It is OK for jpeg_mem_available to underestimate the space available + (that'll just lead to more backing-store access than is really necessary). + However, an overestimate will lead to failure. Hence it's wise to subtract + a slop factor from the true available space. 5% should be enough. + + On machines with lots of virtual memory, any large constant may be returned. + Conversely, zero may be returned to always use the minimum amount of memory.} + + + +{ This routine computes the total memory space available for allocation. + It's impossible to do this in a portable way; our current solution is + to make the user tell us (with a default value set at compile time). + If you can actually get the available space, it's a good idea to subtract + a slop factor of 5% or so. } + +const + DEFAULT_MAX_MEM = long(300000); { for total usage about 450K } + +{GLOBAL} +function jpeg_mem_available (cinfo : j_common_ptr; + min_bytes_needed : long; + max_bytes_needed : long; + already_allocated : long) : long; +begin + {jpeg_mem_available := cinfo^.mem^.max_memory_to_use - already_allocated;} + jpeg_mem_available := max_bytes_needed; +end; + + +{ Initial opening of a backing-store object. This must fill in the + read/write/close pointers in the object. The read/write routines + may take an error exit if the specified maximum file size is exceeded. + (If jpeg_mem_available always returns a large value, this routine can + just take an error exit.) } + + + +{ Initial opening of a backing-store object. } + +{GLOBAL} +procedure jpeg_open_backing_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long); +begin + ERREXIT(cinfo, JERR_NO_BACKING_STORE); +end; + +{ These routines take care of any system-dependent initialization and + cleanup required. jpeg_mem_init will be called before anything is + allocated (and, therefore, nothing in cinfo is of use except the error + manager pointer). It should return a suitable default value for + max_memory_to_use; this may subsequently be overridden by the surrounding + application. (Note that max_memory_to_use is only important if + jpeg_mem_available chooses to consult it ... no one else will.) + jpeg_mem_term may assume that all requested memory has been freed and that + all opened backing-store objects have been closed. } + + +{ These routines take care of any system-dependent initialization and + cleanup required. } + + +{GLOBAL} +function jpeg_mem_init (cinfo : j_common_ptr) : long; +begin + jpeg_mem_init := DEFAULT_MAX_MEM; { default for max_memory_to_use } +end; + +{GLOBAL} +procedure jpeg_mem_term (cinfo : j_common_ptr); +begin + +end; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmemsys_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmemsys_del.pas new file mode 100644 index 0000000..1218561 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmemsys_del.pas @@ -0,0 +1,177 @@ +Unit jmemsys; + +{ This is a skeleton you need to create a working system-dependent + JPEG memory manager. + No other modules need include it. (The system-independent portion is + jmemmgr.c; there are several different versions of the system-dependent + portion.) + + This code will not compile - Check JMEMDOS.PAS for an example } + +{ Original: jmemsys.h; Copyright (C) 1992-1996, Thomas G. Lane. } + +interface + +uses + jmorecfg, + jpeglib; + +{ The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + be requested in a single call to jpeg_get_large (and jpeg_get_small for that + matter, but that case should never come into play). This macro is needed + to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + On those machines, we expect that jconfig.h will provide a proper value. + On machines with 32-bit flat address spaces, any large constant may be used. + + NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + size_t and will be a multiple of sizeof(align_type). } + +{$ifdef USE_MSDOS_MEMMGR} { Define this if you use jmemdos.c } +const + MAX_ALLOC_CHUNK = long(65520); { Maximum request to malloc() } +{$else} +const + MAX_ALLOC_CHUNK = long(1000000000); +{$endif} + + + +{ Initial opening of a backing-store object. This must fill in the + read/write/close pointers in the object. The read/write routines + may take an error exit if the specified maximum file size is exceeded. + (If jpeg_mem_available always returns a large value, this routine can + just take an error exit.) } + + +EXTERN procedure jpeg_open_backing_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long); + + +{ These routines take care of any system-dependent initialization and + cleanup required. jpeg_mem_init will be called before anything is + allocated (and, therefore, nothing in cinfo is of use except the error + manager pointer). It should return a suitable default value for + max_memory_to_use; this may subsequently be overridden by the surrounding + application. (Note that max_memory_to_use is only important if + jpeg_mem_available chooses to consult it ... no one else will.) + jpeg_mem_term may assume that all requested memory has been freed and that + all opened backing-store objects have been closed. } + + +EXTERN function jpeg_mem_init (cinfo : j_common_ptr) : long; +EXTERN procedure jpeg_mem_term (cinfo : j_common_ptr); + + +implementation + +{ This structure holds whatever state is needed to access a single + backing-store object. The read/write/close method pointers are called + by jmemmgr.c to manipulate the backing-store object; all other fields + are private to the system-dependent backing store routines. } + + +const + TEMP_NAME_LENGTH = 64; { max length of a temporary file's name } + +{$ifdef USE_MSDOS_MEMMGR} { DOS-specific junk } +type + XMSH = ushort; { type of extended-memory handles } + EMSH = ushort; { type of expanded-memory handles } + + handle_union = record + case byte of + 0:(file_handle : short); { DOS file handle if it's a temp file } + 1:(xms_handle : XMSH); { handle if it's a chunk of XMS } + 2:(ems_handle : EMSH); { handle if it's a chunk of EMS } + end; +{$endif - USE_MSDOS_MEMMGR } + +type + backing_store_ptr = ^backing_store_info; + backing_store_info = record + { Methods for reading/writing/closing this backing-store object } + read_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {far} + file_offset : long; + byte_count : long); + write_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {far} + file_offset : long; + byte_count : long); + + close_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr); + + { Private fields for system-dependent backing-store management } + {$ifdef USE_MSDOS_MEMMGR} + { For the MS-DOS manager (jmemdos.c), we need: } + handle : handle_union; { reference to backing-store storage object } + temp_name : string[TEMP_NAME_LENGTH]; { name if it's a file } + {$else} + { For a typical implementation with temp files, we need: } + temp_file : FILE; { stdio reference to temp file } + temp_name : string[TEMP_NAME_LENGTH]; { name of temp file } + {$endif} + end; + +{ These two functions are used to allocate and release small chunks of + memory. (Typically the total amount requested through jpeg_get_small is + no more than 20K or so; this will be requested in chunks of a few K each.) + Behavior should be the same as for the standard library functions malloc + and free; in particular, jpeg_get_small must return NIL on failure. + On most systems, these ARE malloc and free. jpeg_free_small is passed the + size of the object being freed, just in case it's needed. + On an 80x86 machine using small-data memory model, these manage near heap. } + +EXTERN function jpeg_get_small (cinfo : j_common_ptr; + sizeofobject : size_t) : pointer; +EXTERN procedure jpeg_free_small (cinfo : j_common_ptr; + object : pointer; + sizeofobject : size_t); + +{ These two functions are used to allocate and release large chunks of + memory (up to the total free space designated by jpeg_mem_available). + The interface is the same as above, except that on an 80x86 machine, + far pointers are used. On most other machines these are identical to + the jpeg_get/free_small routines; but we keep them separate anyway, + in case a different allocation strategy is desirable for large chunks. } + +EXTERN function jpeg_get_large (cinfo : j_common_ptr cinfo; + sizeofobject : size_t) : pointer; {far} + +EXTERN procedure jpeg_free_large (cinfo : j_common_ptr; + object : pointer; {far} + sizeofobject : size_t); + + +{ This routine computes the total space still available for allocation by + jpeg_get_large. If more space than this is needed, backing store will be + used. NOTE: any memory already allocated must not be counted. + + There is a minimum space requirement, corresponding to the minimum + feasible buffer sizes; jmemmgr.c will request that much space even if + jpeg_mem_available returns zero. The maximum space needed, enough to hold + all working storage in memory, is also passed in case it is useful. + Finally, the total space already allocated is passed. If no better + method is available, cinfo->mem->max_memory_to_use - already_allocated + is often a suitable calculation. + + It is OK for jpeg_mem_available to underestimate the space available + (that'll just lead to more backing-store access than is really necessary). + However, an overestimate will lead to failure. Hence it's wise to subtract + a slop factor from the true available space. 5% should be enough. + + On machines with lots of virtual memory, any large constant may be returned. + Conversely, zero may be returned to always use the minimum amount of memory.} + + +EXTERN function jpeg_mem_available (cinfo : j_common_ptr; + min_bytes_needed : long; + max_bytes_needed : long; + already_allocated : long) : long; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmorecfg_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmorecfg_del.pas new file mode 100644 index 0000000..b611f3a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmorecfg_del.pas @@ -0,0 +1,250 @@ +unit jmorecfg_del; + +{ This file contains additional configuration options that customize the + JPEG software for special applications or support machine-dependent + optimizations. Most users will not need to touch this file. } + +{ Source: jmorecfg.h; Copyright (C) 1991-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +//{$IFDEF FPC} { Free Pascal Compiler } + type + int = longint; + uInt = Cardinal; { unsigned int } + short = Integer; + ushort = Word; + long = longint; +(* +{$ELSE} +{$IFDEF WIN32} + { Delphi 2.0 } + type + int = Integer; + uInt = Cardinal; + short = SmallInt; + ushort = Word; + long = longint; + {$ELSE} + {$IFDEF VIRTUALPASCAL} + type + int = longint; + uInt = longint; { unsigned int } + short = system.Integer; + ushort = system.Word; + long = longint; + {$ELSE} + type + int = Integer; + uInt = Word; { unsigned int } + short = Integer; + ushort = Word; + long = longint; + {$ENDIF} +{$ENDIF} +{$ENDIF} +*) +type + voidp = pointer; + +type + int_ptr = ^int; + size_t = int; + +{ Define BITS_IN_JSAMPLE as either + 8 for 8-bit sample values (the usual setting) + 12 for 12-bit sample values + Only 8 and 12 are legal data precisions for lossy JPEG according to the + JPEG standard, and the IJG code does not support anything else! + We do not support run-time selection of data precision, sorry. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} { use 8 or 12 } +const + BITS_IN_JSAMPLE = 8; +{$else} +const + BITS_IN_JSAMPLE = 12; +{$endif} + + + + +{ Maximum number of components (color channels) allowed in JPEG image. + To meet the letter of the JPEG spec, set this to 255. However, darn + few applications need more than 4 channels (maybe 5 for CMYK + alpha + mask). We recommend 10 as a reasonable compromise; use 4 if you are + really short on memory. (Each allowed component costs a hundred or so + bytes of storage, whether actually used in an image or not.) } + + +const + MAX_COMPONENTS = 10; { maximum number of image components } + + +{ Basic data types. + You may need to change these if you have a machine with unusual data + type sizes; for example, "char" not 8 bits, "short" not 16 bits, + or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + but it had better be at least 16. } + + +{ Representation of a single sample (pixel element value). + We frequently allocate large arrays of these, so it's important to keep + them small. But if you have memory to burn and access to char or short + arrays is very slow on your hardware, you might want to change these. } + + +{$ifdef BITS_IN_JSAMPLE_IS_8} +{ JSAMPLE should be the smallest type that will hold the values 0..255. + You can use a signed char by having GETJSAMPLE mask it with $FF. } + +{ CHAR_IS_UNSIGNED } +type + JSAMPLE = byte; { Pascal unsigned char } + GETJSAMPLE = int; + +const + MAXJSAMPLE = 255; + CENTERJSAMPLE = 128; + +{$endif} + +{$ifndef BITS_IN_JSAMPLE_IS_8} +{ JSAMPLE should be the smallest type that will hold the values 0..4095. + On nearly all machines "short" will do nicely. } + +type + JSAMPLE = short; + GETJSAMPLE = int; + +const + MAXJSAMPLE = 4095; + CENTERJSAMPLE = 2048; + +{$endif} { BITS_IN_JSAMPLE = 12 } + + +{ Representation of a DCT frequency coefficient. + This should be a signed value of at least 16 bits; "short" is usually OK. + Again, we allocate large arrays of these, but you can change to int + if you have memory to burn and "short" is really slow. } +type + JCOEF = int; + JCOEF_PTR = ^JCOEF; + + +{ Compressed datastreams are represented as arrays of JOCTET. + These must be EXACTLY 8 bits wide, at least once they are written to + external storage. Note that when using the stdio data source/destination + managers, this is also the data type passed to fread/fwrite. } + + +type + JOCTET = Byte; + jTOctet = 0..(MaxInt div SizeOf(JOCTET))-1; + JOCTET_FIELD = array[jTOctet] of JOCTET; + JOCTET_FIELD_PTR = ^JOCTET_FIELD; + JOCTETPTR = ^JOCTET; + + GETJOCTET = JOCTET; { A work around } + + +{ These typedefs are used for various table entries and so forth. + They must be at least as wide as specified; but making them too big + won't cost a huge amount of memory, so we don't provide special + extraction code like we did for JSAMPLE. (In other words, these + typedefs live at a different point on the speed/space tradeoff curve.) } + + +{ UINT8 must hold at least the values 0..255. } + +type + UINT8 = byte; + +{ UINT16 must hold at least the values 0..65535. } + + UINT16 = Word; + +{ INT16 must hold at least the values -32768..32767. } + + INT16 = int; + +{ INT32 must hold at least signed 32-bit values. } + + INT32 = longint; +type + INT32PTR = ^INT32; + +{ Datatype used for image dimensions. The JPEG standard only supports + images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + "unsigned int" is sufficient on all machines. However, if you need to + handle larger images and you don't mind deviating from the spec, you + can change this datatype. } + +type + JDIMENSION = uInt; + +const + JPEG_MAX_DIMENSION = 65500; { a tad under 64K to prevent overflows } + + +{ Ordering of RGB data in scanlines passed to or from the application. + If your application wants to deal with data in the order B,G,R, just + change these macros. You can also deal with formats such as R,G,B,X + (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + the offsets will also change the order in which colormap data is organized. + RESTRICTIONS: + 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + useful if you are using JPEG color spaces other than YCbCr or grayscale. + 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + is not 3 (they don't understand about dummy color components!). So you + can't use color quantization if you change that value. } + +{$ifdef RGB_RED_IS_0} +const + RGB_RED = 0; { Offset of Red in an RGB scanline element } + RGB_GREEN = 1; { Offset of Green } + RGB_BLUE = 2; { Offset of Blue } +{$else} +const + RGB_RED = 2; { Offset of Red in an RGB scanline element } + RGB_GREEN = 1; { Offset of Green } + RGB_BLUE = 0; { Offset of Blue } +{$endif} + +{$ifdef RGB_PIXELSIZE_IS_3} +const + RGB_PIXELSIZE = 3; { JSAMPLEs per RGB scanline element } +{$else} +const + RGB_PIXELSIZE = ??; { Nomssi: deliberate syntax error. Set this value } +{$endif} + +{ Definitions for speed-related optimizations. } + +{ On some machines (notably 68000 series) "int" is 32 bits, but multiplying + two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + as short on such a machine. MULTIPLIER must be at least 16 bits wide. } +type + MULTIPLIER = int; { type for fastest integer multiply } + + +{ FAST_FLOAT should be either float or double, whichever is done faster + by your compiler. (Note that this type is only used in the floating point + DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + Typically, float is faster in ANSI C compilers, while double is faster in + pre-ANSI compilers (because they insist on converting to double anyway). + The code below therefore chooses float if we have ANSI-style prototypes. } + +type + FAST_FLOAT = double; {float} + + +implementation + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jpeglib_del.pas b/mseide-msegui/lib/common/fpccompatibility/jpeglib_del.pas new file mode 100644 index 0000000..e7b17aa --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jpeglib_del.pas @@ -0,0 +1,1301 @@ +unit jpeglib_del; + +{ This file defines the application interface for the JPEG library. + Most applications using the library need only include this file, + and perhaps jerror.h if they want to know the exact error codes. } + +{ Source:jpeglib.h+jpegint.h; Copyright (C) 1991-1998, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ First we include the configuration files that record how this + installation of the JPEG library is set up. jconfig.h can be + generated automatically for many systems. jmorecfg.h contains + manual configuration options that most people need not worry about. } + +uses + jdeferr_del, + jmorecfg_del; { seldom changed options } + +{ Version ID for the JPEG library. + Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". } + + +Const + JPEG_LIB_VERSION = 62; { Version 6b } + + +{ These marker codes are exported since applications and data source modules + are likely to want to use them. } + +const + JPEG_RST0 = $D0; { RST0 marker code } + JPEG_EOI = $D9; { EOI marker code } + JPEG_APP0 = $E0; { APP0 marker code } + JPEG_COM = $FE; { COM marker code } + + +{ Various constants determining the sizes of things. + All of these are specified by the JPEG standard, so don't change them + if you want to be compatible. } + +const + DCTSIZE = 8; { The basic DCT block is 8x8 samples } + DCTSIZE2 = 64; { DCTSIZE squared; # of elements in a block } + NUM_QUANT_TBLS = 4; { Quantization tables are numbered 0..3 } + NUM_HUFF_TBLS = 4; { Huffman tables are numbered 0..3 } + NUM_ARITH_TBLS = 16; { Arith-coding tables are numbered 0..15 } + MAX_COMPS_IN_SCAN = 4; { JPEG limit on # of components in one scan } + MAX_SAMP_FACTOR = 4; { JPEG limit on sampling factors } +{ Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + to handle it. We even let you do this from the jconfig.h file. However, + we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + sometimes emits noncompliant files doesn't mean you should too. } + C_MAX_BLOCKS_IN_MCU = 10; { compressor's limit on blocks per MCU } + D_MAX_BLOCKS_IN_MCU = 10; { decompressor's limit on blocks per MCU } + + +{ Data structures for images (arrays of samples and of DCT coefficients). + On 80x86 machines, the image arrays are too big for near pointers, + but the pointer arrays can fit in near memory. } + +type +{ for typecasting } + JSAMPLE_PTR = ^JSAMPLE; + JSAMPROW_PTR = ^JSAMPROW; + JBLOCKROW_PTR = ^JBLOCKROW; + + jTSample = 0..(MaxInt div SIZEOF(JSAMPLE))-1; + JSAMPLE_ARRAY = Array[jTSample] of JSAMPLE; {far} + JSAMPROW = ^JSAMPLE_ARRAY; { ptr to one image row of pixel samples. } + + jTRow = 0..(MaxInt div SIZEOF(JSAMPROW))-1; + JSAMPROW_ARRAY = Array[jTRow] of JSAMPROW; + JSAMPARRAY = ^JSAMPROW_ARRAY; { ptr to some rows (a 2-D sample array) } + + jTArray = 0..(MaxInt div SIZEOF(JSAMPARRAY))-1; + JSAMP_ARRAY = Array[jTArray] of JSAMPARRAY; + JSAMPIMAGE = ^JSAMP_ARRAY; { a 3-D sample array: top index is color } + + JBLOCK = Array[0..DCTSIZE2-1] of JCOEF; { one block of coefficients } + JBLOCK_PTR = ^JBLOCK; + + jTBlockRow = 0..(MaxInt div SIZEOF(JBLOCK))-1; + JBLOCK_ROWS = Array[jTBlockRow] of JBLOCK; + JBLOCKROW = ^JBLOCK_ROWS; {far} { pointer to one row of coefficient blocks } + + + jTBlockArray = 0..(MaxInt div SIZEOF(JBLOCKROW))-1; + JBLOCK_ARRAY = Array[jTBlockArray] of JBLOCKROW; + JBLOCKARRAY = ^JBLOCK_ARRAY; { a 2-D array of coefficient blocks } + + jTBlockImage = 0..(MaxInt div SIZEOF(JBLOCKARRAY))-1; + JBLOCK_IMAGE = Array[jTBlockImage] of JBLOCKARRAY; + JBLOCKIMAGE = ^JBLOCK_IMAGE; { a 3-D array of coefficient blocks } + + jTCoef = 0..(MaxInt div SIZEOF(JCOEF))-1; + JCOEF_ROW = Array[jTCoef] of JCOEF; + JCOEFPTR = ^JCOEF_ROW; {far} { useful in a couple of places } + + +type + jTByte = 0..(MaxInt div SIZEOF(byte))-1; + JByteArray = Array[jTByte] of byte; + JBytePtr = ^JByteArray; +type + byteptr = ^byte; + +{ Types for JPEG compression parameters and working tables. } + + +{ DCT coefficient quantization tables. } + +type + JQUANT_TBL_PTR = ^JQUANT_TBL; + JQUANT_TBL = record + { This array gives the coefficient quantizers in natural array order + (not the zigzag order in which they are stored in a JPEG DQT marker). + CAUTION: IJG versions prior to v6a kept this array in zigzag order. } + quantval : Array[0..DCTSIZE2-1] of UINT16; + { quantization step for each coefficient } + { This field is used only during compression. It's initialized FALSE when + the table is created, and set TRUE when it's been output to the file. + You could suppress output of a table by setting this to TRUE. + (See jpeg_suppress_tables for an example.) } + sent_table : boolean; { TRUE when table has been output } + end; + JQUANT_TBL_FIELD = Array[0..(MaxInt div SizeOf(JQUANT_TBL))-1] of JQUANT_TBL; + +{ Huffman coding tables. } + +type + JHUFF_TBL_PTR = ^JHUFF_TBL; + JHUFF_TBL = record + { These two fields directly represent the contents of a JPEG DHT marker } + bits : Array[0..17-1] of UINT8; { bits[k] = # of symbols with codes of } + { length k bits; bits[0] is unused } + huffval : Array[0..256-1] of UINT8; + { The symbols, in order of incr code length } + { This field is used only during compression. It's initialized FALSE when + the table is created, and set TRUE when it's been output to the file. + You could suppress output of a table by setting this to TRUE. + (See jpeg_suppress_tables for an example.) } + sent_table : boolean; { TRUE when table has been output } + end; + JHUFF_TBL_FIELD = Array[0..(MaxInt div SizeOf(JHUFF_TBL))-1] of JHUFF_TBL; + +{ Declarations for both compression & decompression } + +type + J_BUF_MODE = ( { Operating modes for buffer controllers } + JBUF_PASS_THRU, { Plain stripwise operation } + { Remaining modes require a full-image buffer to have been created } + JBUF_SAVE_SOURCE, { Run source subobject only, save output } + JBUF_CRANK_DEST, { Run dest subobject only, using saved data } + JBUF_SAVE_AND_PASS { Run both subobjects, save output } + ); + +{ Values of global_state field (jdapi.c has some dependencies on ordering!) } +const + CSTATE_START = 100; { after create_compress } + CSTATE_SCANNING = 101; { start_compress done, write_scanlines OK } + CSTATE_RAW_OK = 102; { start_compress done, write_raw_data OK } + CSTATE_WRCOEFS = 103; { jpeg_write_coefficients done } + DSTATE_START = 200; { after create_decompress } + DSTATE_INHEADER = 201; { reading header markers, no SOS yet } + DSTATE_READY = 202; { found SOS, ready for start_decompress } + DSTATE_PRELOAD = 203; { reading multiscan file in start_decompress} + DSTATE_PRESCAN = 204; { performing dummy pass for 2-pass quant } + DSTATE_SCANNING = 205; { start_decompress done, read_scanlines OK } + DSTATE_RAW_OK = 206; { start_decompress done, read_raw_data OK } + DSTATE_BUFIMAGE = 207; { expecting jpeg_start_output } + DSTATE_BUFPOST = 208; { looking for SOS/EOI in jpeg_finish_output } + DSTATE_RDCOEFS = 209; { reading file in jpeg_read_coefficients } + DSTATE_STOPPING = 210; { looking for EOI in jpeg_finish_decompress } + + + +{ Basic info about one component (color channel). } + +type + jpeg_component_info_ptr = ^jpeg_component_info; + jpeg_component_info = record + { These values are fixed over the whole image. } + { For compression, they must be supplied by parameter setup; } + { for decompression, they are read from the SOF marker. } + component_id : int; { identifier for this component (0..255) } + component_index : int; { its index in SOF or cinfo^.comp_info[] } + h_samp_factor : int; { horizontal sampling factor (1..4) } + v_samp_factor : int; { vertical sampling factor (1..4) } + quant_tbl_no : int; { quantization table selector (0..3) } + { These values may vary between scans. } + { For compression, they must be supplied by parameter setup; } + { for decompression, they are read from the SOS marker. } + { The decompressor output side may not use these variables. } + dc_tbl_no : int; { DC entropy table selector (0..3) } + ac_tbl_no : int; { AC entropy table selector (0..3) } + + { Remaining fields should be treated as private by applications. } + + { These values are computed during compression or decompression startup: } + { Component's size in DCT blocks. + Any dummy blocks added to complete an MCU are not counted; therefore + these values do not depend on whether a scan is interleaved or not. } + width_in_blocks : JDIMENSION; + height_in_blocks : JDIMENSION; + { Size of a DCT block in samples. Always DCTSIZE for compression. + For decompression this is the size of the output from one DCT block, + reflecting any scaling we choose to apply during the IDCT step. + Values of 1,2,4,8 are likely to be supported. Note that different + components may receive different IDCT scalings. } + + DCT_scaled_size : int; + { The downsampled dimensions are the component's actual, unpadded number + of samples at the main buffer (preprocessing/compression interface), thus + downsampled_width = ceil(image_width * Hi/Hmax) + and similarly for height. For decompression, IDCT scaling is included, so + downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)} + + downsampled_width : JDIMENSION; { actual width in samples } + downsampled_height : JDIMENSION; { actual height in samples } + { This flag is used only for decompression. In cases where some of the + components will be ignored (eg grayscale output from YCbCr image), + we can skip most computations for the unused components. } + + component_needed : boolean; { do we need the value of this component? } + + { These values are computed before starting a scan of the component. } + { The decompressor output side may not use these variables. } + MCU_width : int; { number of blocks per MCU, horizontally } + MCU_height : int; { number of blocks per MCU, vertically } + MCU_blocks : int; { MCU_width * MCU_height } + MCU_sample_width : int; { MCU width in samples, MCU_width*DCT_scaled_size } + last_col_width : int; { # of non-dummy blocks across in last MCU } + last_row_height : int; { # of non-dummy blocks down in last MCU } + + { Saved quantization table for component; NIL if none yet saved. + See jdinput.c comments about the need for this information. + This field is currently used only for decompression. } + + quant_table : JQUANT_TBL_PTR; + + { Private per-component storage for DCT or IDCT subsystem. } + dct_table : pointer; + end; { record jpeg_component_info } + + jTCinfo = 0..(MaxInt div SizeOf(jpeg_component_info))-1; + jpeg_component_info_array = array[jTCinfo] of jpeg_component_info; + jpeg_component_info_list_ptr = ^jpeg_component_info_array; + + +{ The script for encoding a multiple-scan file is an array of these: } + +type + jpeg_scan_info_ptr = ^jpeg_scan_info; + jpeg_scan_info = record + comps_in_scan : int; { number of components encoded in this scan } + component_index : Array[0..MAX_COMPS_IN_SCAN-1] of int; + { their SOF/comp_info[] indexes } + Ss, Se : int; { progressive JPEG spectral selection parms } + Ah, Al : int; { progressive JPEG successive approx. parms } + end; + +{ The decompressor can save APPn and COM markers in a list of these: } + +type + jpeg_saved_marker_ptr = ^jpeg_marker_struct; + jpeg_marker_struct = record + next : jpeg_saved_marker_ptr; { next in list, or NULL } + marker : UINT8; { marker code: JPEG_COM, or JPEG_APP0+n } + original_length : uint; { # bytes of data in the file } + data_length : uint; { # bytes of data saved at data[] } + data : JOCTET_FIELD_PTR; { the data contained in the marker } + { the marker length word is not counted in data_length or original_length } + end; + +{ Known color spaces. } + +type + J_COLOR_SPACE = ( + JCS_UNKNOWN, { error/unspecified } + JCS_GRAYSCALE, { monochrome } + JCS_RGB, { red/green/blue } + JCS_YCbCr, { Y/Cb/Cr (also known as YUV) } + JCS_CMYK, { C/M/Y/K } + JCS_YCCK { Y/Cb/Cr/K } + ); + +{ DCT/IDCT algorithm options. } + +type + J_DCT_METHOD = ( + JDCT_ISLOW, { slow but accurate integer algorithm } + JDCT_IFAST, { faster, less accurate integer method } + JDCT_FLOAT { floating-point: accurate, fast on fast HW } + ); + +const + JDCT_DEFAULT = JDCT_ISLOW; + JDCT_FASTEST = JDCT_IFAST; + +{ Dithering options for decompression. } + +type + J_DITHER_MODE = ( + JDITHER_NONE, { no dithering } + JDITHER_ORDERED, { simple ordered dither } + JDITHER_FS { Floyd-Steinberg error diffusion dither } + ); + + +const + JPOOL_PERMANENT = 0; { lasts until master record is destroyed } + JPOOL_IMAGE = 1; { lasts until done with image/datastream } + JPOOL_NUMPOOLS = 2; + + +{ "Object" declarations for JPEG modules that may be supplied or called + directly by the surrounding application. + As with all objects in the JPEG library, these structs only define the + publicly visible methods and state variables of a module. Additional + private fields may exist after the public ones. } + + +{ Error handler object } + +const + JMSG_LENGTH_MAX = 200; { recommended size of format_message buffer } + JMSG_STR_PARM_MAX = 80; + +const + TEMP_NAME_LENGTH = 64; { max length of a temporary file's name } +type + TEMP_STRING = string[TEMP_NAME_LENGTH]; + +{$ifdef USE_MSDOS_MEMMGR} { DOS-specific junk } +type + XMSH = ushort; { type of extended-memory handles } + EMSH = ushort; { type of expanded-memory handles } + + handle_union = record + case byte of + 0:(file_handle : short); { DOS file handle if it's a temp file } + 1:(xms_handle : XMSH); { handle if it's a chunk of XMS } + 2:(ems_handle : EMSH); { handle if it's a chunk of EMS } + end; +{$endif} { USE_MSDOS_MEMMGR } + +type + jpeg_error_mgr_ptr = ^jpeg_error_mgr; + jpeg_memory_mgr_ptr = ^jpeg_memory_mgr; + jpeg_progress_mgr_ptr = ^jpeg_progress_mgr; + + +{$ifdef common} +{ Common fields between JPEG compression and decompression master structs. } + err : jpeg_error_mgr_ptr; { Error handler module } + mem : jpeg_memory_mgr_ptr; { Memory manager module } + progress : jpeg_progress_mgr_ptr; { Progress monitor, or NIL if none } + client_data : voidp; { Available for use by application } + is_decompressor : boolean; { so common code can tell which is which } + global_state : int; { for checking call sequence validity } +{$endif} + + j_common_ptr = ^jpeg_common_struct; + j_compress_ptr = ^jpeg_compress_struct; + j_decompress_ptr = ^jpeg_decompress_struct; + + {$ifdef AM_MEMORY_MANAGER} { only jmemmgr.c defines these } + +{ This structure holds whatever state is needed to access a single + backing-store object. The read/write/close method pointers are called + by jmemmgr.c to manipulate the backing-store object; all other fields + are private to the system-dependent backing store routines. } + + + backing_store_ptr = ^backing_store_info; + backing_store_info = record + { Methods for reading/writing/closing this backing-store object } + read_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {far} + file_offset : long; + byte_count : long); + write_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {far} + file_offset : long; + byte_count : long); + + close_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr); + + { Private fields for system-dependent backing-store management } + {$ifdef USE_MSDOS_MEMMGR} + { For the MS-DOS manager (jmemdos.c), we need: } + handle : handle_union; { reference to backing-store storage object } + temp_name : TEMP_STRING; { name if it's a file } + {$else} + { For a typical implementation with temp files, we need: } + temp_file : file; { stdio reference to temp file } + temp_name : TEMP_STRING; { name of temp file } + {$endif} + end; + + +{ The control blocks for virtual arrays. + Note that these blocks are allocated in the "small" pool area. + System-dependent info for the associated backing store (if any) is hidden + inside the backing_store_info struct. } + + jvirt_sarray_ptr = ^jvirt_sarray_control; + jvirt_sarray_control = record + mem_buffer : JSAMPARRAY; { => the in-memory buffer } + rows_in_array : JDIMENSION; { total virtual array height } + samplesperrow : JDIMENSION; { width of array (and of memory buffer) } + maxaccess : JDIMENSION; { max rows accessed by access_virt_sarray } + rows_in_mem : JDIMENSION; { height of memory buffer } + rowsperchunk : JDIMENSION; { allocation chunk size in mem_buffer } + cur_start_row : JDIMENSION; { first logical row # in the buffer } + first_undef_row : JDIMENSION; { row # of first uninitialized row } + pre_zero : boolean; { pre-zero mode requested? } + dirty : boolean; { do current buffer contents need written? } + b_s_open : boolean; { is backing-store data valid? } + next : jvirt_sarray_ptr; { link to next virtual sarray control block } + b_s_info : backing_store_info; { System-dependent control info } + end; + + jvirt_barray_ptr = ^jvirt_barray_control; + jvirt_barray_control = record + mem_buffer : JBLOCKARRAY; { => the in-memory buffer } + rows_in_array : JDIMENSION; { total virtual array height } + blocksperrow : JDIMENSION; { width of array (and of memory buffer) } + maxaccess : JDIMENSION; { max rows accessed by access_virt_barray } + rows_in_mem : JDIMENSION; { height of memory buffer } + rowsperchunk : JDIMENSION; { allocation chunk size in mem_buffer } + cur_start_row : JDIMENSION; { first logical row # in the buffer } + first_undef_row : JDIMENSION; { row # of first uninitialized row } + pre_zero : boolean; { pre-zero mode requested? } + dirty : boolean; { do current buffer contents need written? } + b_s_open : boolean; { is backing-store data valid? } + next : jvirt_barray_ptr; { link to next virtual barray control block } + b_s_info : backing_store_info; { System-dependent control info } + end; + + {$endif} { AM_MEMORY_MANAGER } + +{ Declarations for compression modules } + +{ Master control module } + jpeg_comp_master_ptr = ^jpeg_comp_master; + jpeg_comp_master = record + prepare_for_pass : procedure(cinfo : j_compress_ptr); + pass_startup : procedure(cinfo : j_compress_ptr); + finish_pass : procedure(cinfo : j_compress_ptr); + + { State variables made visible to other modules } + call_pass_startup : Boolean; { True if pass_startup must be called } + is_last_pass : Boolean; { True during last pass } + end; + +{ Main buffer control (downsampled-data buffer) } + jpeg_c_main_controller_ptr = ^jpeg_c_main_controller; + jpeg_c_main_controller = record + start_pass : procedure(cinfo : j_compress_ptr; pass_mode : J_BUF_MODE); + process_data : procedure(cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION); + end; + +{ Compression preprocessing (downsampling input buffer control) } + jpeg_c_prep_controller_ptr = ^jpeg_c_prep_controller; + jpeg_c_prep_controller = record + start_pass : procedure(cinfo : j_compress_ptr; pass_mode : J_BUF_MODE); + pre_process_data : procedure(cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION; + output_buf : JSAMPIMAGE; + var out_row_group_ctr : JDIMENSION; + out_row_groups_avail : JDIMENSION); + end; + +{ Coefficient buffer control } + jpeg_c_coef_controller_ptr = ^jpeg_c_coef_controller; + jpeg_c_coef_controller = record + start_pass : procedure(cinfo : j_compress_ptr; pass_mode : J_BUF_MODE); + compress_data : function(cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; + end; + +{ Colorspace conversion } + jpeg_color_converter_ptr = ^jpeg_color_converter; + jpeg_color_converter = record + start_pass : procedure(cinfo : j_compress_ptr); + color_convert : procedure(cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows : int); + end; + +{ Downsampling } + jpeg_downsampler_ptr = ^jpeg_downsampler; + jpeg_downsampler = record + start_pass : procedure(cinfo : j_compress_ptr); + downsample : procedure(cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE; + in_row_index : JDIMENSION; + output_buf : JSAMPIMAGE; + out_row_group_index: JDIMENSION); + need_context_rows : Boolean; { TRUE if need rows above & below } + end; + +{ Forward DCT (also controls coefficient quantization) } + jpeg_forward_dct_ptr = ^jpeg_forward_dct; + jpeg_forward_dct = record + start_pass : procedure(cinfo : j_compress_ptr); + { perhaps this should be an array??? } + forward_DCT : procedure(cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + sample_data : JSAMPARRAY; + coef_blocks : JBLOCKROW; + start_row : JDIMENSION; + start_col : JDIMENSION; + num_blocks : JDIMENSION); + end; + +{ Entropy encoding } + + jpeg_entropy_encoder_ptr = ^jpeg_entropy_encoder; + jpeg_entropy_encoder = record + start_pass : procedure(cinfo : j_compress_ptr; gather_statistics : boolean); + encode_mcu : function(cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + finish_pass : procedure(cinfo : j_compress_ptr); + end; + +{ Marker writing } + jpeg_marker_writer_ptr = ^jpeg_marker_writer; + jpeg_marker_writer = record + write_file_header : procedure(cinfo : j_compress_ptr); + write_frame_header : procedure(cinfo : j_compress_ptr); + write_scan_header : procedure(cinfo : j_compress_ptr); + write_file_trailer : procedure(cinfo : j_compress_ptr); + write_tables_only : procedure(cinfo : j_compress_ptr); + { These routines are exported to allow insertion of extra markers } + { Probably only COM and APPn markers should be written this way } + write_marker_header : procedure (cinfo : j_compress_ptr; + marker : int; + datalen : uint); + write_marker_byte : procedure (cinfo : j_compress_ptr; val : int); + end; + +{ Declarations for decompression modules } + +{ Master control module } + jpeg_decomp_master_ptr = ^jpeg_decomp_master; + jpeg_decomp_master = record + prepare_for_output_pass : procedure( cinfo : j_decompress_ptr); + finish_output_pass : procedure(cinfo : j_decompress_ptr); + + { State variables made visible to other modules } + is_dummy_pass : Boolean; { True during 1st pass for 2-pass quant } + end; + +{ Input control module } + jpeg_input_controller_ptr = ^jpeg_input_controller; + jpeg_input_controller = record + consume_input : function (cinfo : j_decompress_ptr) : int; + reset_input_controller : procedure(cinfo : j_decompress_ptr); + start_input_pass : procedure(cinfo : j_decompress_ptr); + finish_input_pass : procedure(cinfo : j_decompress_ptr); + + { State variables made visible to other modules } + has_multiple_scans : Boolean; { True if file has multiple scans } + eoi_reached : Boolean; { True when EOI has been consumed } + end; + +{ Main buffer control (downsampled-data buffer) } + + jpeg_d_main_controller_ptr = ^jpeg_d_main_controller; + jpeg_d_main_controller = record + start_pass : procedure(cinfo : j_decompress_ptr; pass_mode : J_BUF_MODE); + process_data : procedure(cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); + end; + +{ Coefficient buffer control } + jvirt_barray_tbl = array[0..MAX_COMPONENTS-1] of jvirt_barray_ptr; + jvirt_barray_tbl_ptr = ^jvirt_barray_tbl; + jpeg_d_coef_controller_ptr = ^jpeg_d_coef_controller; + jpeg_d_coef_controller = record + start_input_pass : procedure(cinfo : j_decompress_ptr); + consume_data : function (cinfo : j_decompress_ptr) : int; + start_output_pass : procedure(cinfo : j_decompress_ptr); + decompress_data : function (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; + { Pointer to array of coefficient virtual arrays, or NIL if none } + coef_arrays : jvirt_barray_tbl_ptr; + end; + +{ Decompression postprocessing (color quantization buffer control) } + jpeg_d_post_controller_ptr = ^jpeg_d_post_controller; + jpeg_d_post_controller = record + start_pass : procedure(cinfo : j_decompress_ptr; + pass_mode : J_BUF_MODE); + post_process_data : procedure(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); + end; + + +{ Routine signature for application-supplied marker processing methods. + Need not pass marker code since it is stored in cinfo^.unread_marker. } + + jpeg_marker_parser_method = function(cinfo : j_decompress_ptr) : boolean; + +{ Marker reading & parsing } + jpeg_marker_reader_ptr = ^jpeg_marker_reader; + jpeg_marker_reader = record + reset_marker_reader : procedure(cinfo : j_decompress_ptr); + { Read markers until SOS or EOI. + Returns same codes as are defined for jpeg_consume_input: + JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. } + + read_markers : function (cinfo : j_decompress_ptr) : int; + { Read a restart marker --- exported for use by entropy decoder only } + read_restart_marker : jpeg_marker_parser_method; + + { State of marker reader --- nominally internal, but applications + supplying COM or APPn handlers might like to know the state. } + + saw_SOI : boolean; { found SOI? } + saw_SOF : boolean; { found SOF? } + next_restart_num : int; { next restart number expected (0-7) } + discarded_bytes : uint; { # of bytes skipped looking for a marker } + end; + +{ Entropy decoding } + jpeg_entropy_decoder_ptr = ^jpeg_entropy_decoder; + jpeg_entropy_decoder = record + start_pass : procedure(cinfo : j_decompress_ptr); + decode_mcu : function(cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + { This is here to share code between baseline and progressive decoders; } + { other modules probably should not use it } + insufficient_data : BOOLEAN; { set TRUE after emitting warning } + end; + +{ Inverse DCT (also performs dequantization) } + inverse_DCT_method_ptr = procedure(cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; output_col : JDIMENSION); + + jpeg_inverse_dct_ptr = ^jpeg_inverse_dct; + jpeg_inverse_dct = record + start_pass : procedure(cinfo : j_decompress_ptr); + { It is useful to allow each component to have a separate IDCT method. } + inverse_DCT : Array[0..MAX_COMPONENTS-1] of inverse_DCT_method_ptr; + end; + +{ Upsampling (note that upsampler must also call color converter) } + jpeg_upsampler_ptr = ^jpeg_upsampler; + jpeg_upsampler = record + start_pass : procedure(cinfo : j_decompress_ptr); + upsample : procedure(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; { array of } + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); + + need_context_rows : boolean; { TRUE if need rows above & below } + end; + +{ Colorspace conversion } + jpeg_color_deconverter_ptr = ^jpeg_color_deconverter; + jpeg_color_deconverter = record + start_pass : procedure(cinfo: j_decompress_ptr); + color_convert : procedure(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); + end; + +{ Color quantization or color precision reduction } + jpeg_color_quantizer_ptr = ^jpeg_color_quantizer; + jpeg_color_quantizer = record + start_pass : procedure(cinfo : j_decompress_ptr; is_pre_scan : boolean); + color_quantize : procedure(cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); + + finish_pass : procedure(cinfo : j_decompress_ptr); + new_color_map : procedure(cinfo : j_decompress_ptr); + end; + + {int8array = Array[0..8-1] of int;} + int8array = Array[0..8-1] of longint; { for TP FormatStr } + + jpeg_error_mgr = record + { Error exit handler: does not return to caller } + error_exit : procedure (cinfo : j_common_ptr); + { Conditionally emit a trace or warning message } + emit_message : procedure (cinfo : j_common_ptr; msg_level : int); + { Routine that actually outputs a trace or error message } + output_message : procedure (cinfo : j_common_ptr); + { Format a message string for the most recent JPEG error or message } + format_message : procedure (cinfo : j_common_ptr; var buffer : string); + + { Reset error state variables at start of a new image } + reset_error_mgr : procedure (cinfo : j_common_ptr); + + { The message ID code and any parameters are saved here. + A message can have one string parameter or up to 8 int parameters. } + + msg_code : int; + + msg_parm : record + case byte of + 0:(i : int8array); + 1:(s : string[JMSG_STR_PARM_MAX]); + end; + + { Standard state variables for error facility } + + trace_level : int; { max msg_level that will be displayed } + + { For recoverable corrupt-data errors, we emit a warning message, + but keep going unless emit_message chooses to abort. emit_message + should count warnings in num_warnings. The surrounding application + can check for bad data by seeing if num_warnings is nonzero at the + end of processing. } + + num_warnings : long; { number of corrupt-data warnings } + + { These fields point to the table(s) of error message strings. + An application can change the table pointer to switch to a different + message list (typically, to change the language in which errors are + reported). Some applications may wish to add additional error codes + that will be handled by the JPEG library error mechanism; the second + table pointer is used for this purpose. + + First table includes all errors generated by JPEG library itself. + Error code 0 is reserved for a "no such error string" message. } + + {const char * const * jpeg_message_table; } + jpeg_message_table : ^msg_table; { Library errors } + + last_jpeg_message : J_MESSAGE_CODE; + { Table contains strings 0..last_jpeg_message } + { Second table can be added by application (see cjpeg/djpeg for example). + It contains strings numbered first_addon_message..last_addon_message. } + + {const char * const * addon_message_table; } + addon_message_table : ^msg_table; { Non-library errors } + + first_addon_message : J_MESSAGE_CODE; { code for first string in addon table } + last_addon_message : J_MESSAGE_CODE; { code for last string in addon table } + end; + + +{ Progress monitor object } + + jpeg_progress_mgr = record + progress_monitor : procedure(cinfo : j_common_ptr); + + pass_counter : long; { work units completed in this pass } + pass_limit : long; { total number of work units in this pass } + completed_passes : int; { passes completed so far } + total_passes : int; { total number of passes expected } + end; + + +{ Data destination object for compression } + jpeg_destination_mgr_ptr = ^jpeg_destination_mgr; + jpeg_destination_mgr = record + next_output_byte : JOCTETptr; { => next byte to write in buffer } + free_in_buffer : size_t; { # of byte spaces remaining in buffer } + + init_destination : procedure (cinfo : j_compress_ptr); + empty_output_buffer : function (cinfo : j_compress_ptr) : boolean; + term_destination : procedure (cinfo : j_compress_ptr); + end; + + +{ Data source object for decompression } + + jpeg_source_mgr_ptr = ^jpeg_source_mgr; + jpeg_source_mgr = record + {const JOCTET * next_input_byte;} + next_input_byte : JOCTETptr; { => next byte to read from buffer } + bytes_in_buffer : size_t; { # of bytes remaining in buffer } + + init_source : procedure (cinfo : j_decompress_ptr); + fill_input_buffer : function (cinfo : j_decompress_ptr) : boolean; + skip_input_data : procedure (cinfo : j_decompress_ptr; num_bytes : long); + resync_to_restart : function (cinfo : j_decompress_ptr; + desired : int) : boolean; + term_source : procedure (cinfo : j_decompress_ptr); + end; + + +{ Memory manager object. + Allocates "small" objects (a few K total), "large" objects (tens of K), + and "really big" objects (virtual arrays with backing store if needed). + The memory manager does not allow individual objects to be freed; rather, + each created object is assigned to a pool, and whole pools can be freed + at once. This is faster and more convenient than remembering exactly what + to free, especially where malloc()/free() are not too speedy. + NB: alloc routines never return NIL. They exit to error_exit if not + successful. } + + + jpeg_memory_mgr = record + { Method pointers } + alloc_small : function (cinfo : j_common_ptr; pool_id : int; + sizeofobject : size_t) : pointer; + alloc_large : function (cinfo : j_common_ptr; pool_id : int; + sizeofobject : size_t) : pointer; {far} + alloc_sarray : function (cinfo : j_common_ptr; pool_id : int; + samplesperrow : JDIMENSION; + numrows : JDIMENSION) : JSAMPARRAY; + + alloc_barray : function (cinfo : j_common_ptr; pool_id : int; + blocksperrow : JDIMENSION; + numrows : JDIMENSION) : JBLOCKARRAY; + + request_virt_sarray : function(cinfo : j_common_ptr; + pool_id : int; + pre_zero : boolean; + samplesperrow : JDIMENSION; + numrows : JDIMENSION; + maxaccess : JDIMENSION) : jvirt_sarray_ptr; + + request_virt_barray : function(cinfo : j_common_ptr; + pool_id : int; + pre_zero : boolean; + blocksperrow : JDIMENSION; + numrows : JDIMENSION; + maxaccess : JDIMENSION) : jvirt_barray_ptr; + + realize_virt_arrays : procedure (cinfo : j_common_ptr); + + access_virt_sarray : function (cinfo : j_common_ptr; + ptr : jvirt_sarray_ptr; + start_row : JDIMENSION; + num_rows : JDIMENSION; + writable : boolean) : JSAMPARRAY; + + access_virt_barray : function (cinfo : j_common_ptr; + ptr : jvirt_barray_ptr; + start_row : JDIMENSION; + num_rows : JDIMENSION; + writable : boolean) : JBLOCKARRAY; + + free_pool : procedure (cinfo : j_common_ptr; pool_id : int); + self_destruct : procedure (cinfo : j_common_ptr); + + { Limit on memory allocation for this JPEG object. (Note that this is + merely advisory, not a guaranteed maximum; it only affects the space + used for virtual-array buffers.) May be changed by outer application + after creating the JPEG object. } + max_memory_to_use : long; + + { Maximum allocation request accepted by alloc_large. } + max_alloc_chunk : long; + end; + +{ Routines that are to be used by both halves of the library are declared + to receive a pointer to this structure. There are no actual instances of + jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.} + jpeg_common_struct = record + { Fields common to both master struct types } + err : jpeg_error_mgr_ptr; { Error handler module } + mem : jpeg_memory_mgr_ptr; { Memory manager module } + progress : jpeg_progress_mgr_ptr; { Progress monitor, or NIL if none } + client_data : voidp; { Available for use by application } + is_decompressor : boolean; { so common code can tell which is which } + global_state : int; { for checking call sequence validity } + + { Additional fields follow in an actual jpeg_compress_struct or + jpeg_decompress_struct. All three structs must agree on these + initial fields! (This would be a lot cleaner in C++.) } + end; + + +{ Master record for a compression instance } + + jpeg_compress_struct = record + { Fields shared with jpeg_decompress_struct } + err : jpeg_error_mgr_ptr; { Error handler module } + mem : jpeg_memory_mgr_ptr; { Memory manager module } + progress : jpeg_progress_mgr_ptr; { Progress monitor, or NIL if none } + client_data : voidp; { Available for use by application } + is_decompressor : boolean; { so common code can tell which is which } + global_state : int; { for checking call sequence validity } + + { Destination for compressed data } + dest : jpeg_destination_mgr_ptr; + + { Description of source image --- these fields must be filled in by + outer application before starting compression. in_color_space must + be correct before you can even call jpeg_set_defaults(). } + + + image_width : JDIMENSION; { input image width } + image_height : JDIMENSION; { input image height } + input_components : int; { # of color components in input image } + in_color_space : J_COLOR_SPACE; { colorspace of input image } + + input_gamma : double; { image gamma of input image } + + { Compression parameters --- these fields must be set before calling + jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + initialize everything to reasonable defaults, then changing anything + the application specifically wants to change. That way you won't get + burnt when new parameters are added. Also note that there are several + helper routines to simplify changing parameters. } + + data_precision : int; { bits of precision in image data } + + num_components : int; { # of color components in JPEG image } + jpeg_color_space : J_COLOR_SPACE; { colorspace of JPEG image } + + comp_info : jpeg_component_info_list_ptr; + { comp_info^[i] describes component that appears i'th in SOF } + + quant_tbl_ptrs: Array[0..NUM_QUANT_TBLS-1] of JQUANT_TBL_PTR; + { ptrs to coefficient quantization tables, or NIL if not defined } + + dc_huff_tbl_ptrs : Array[0..NUM_HUFF_TBLS-1] of JHUFF_TBL_PTR; + ac_huff_tbl_ptrs : Array[0..NUM_HUFF_TBLS-1] of JHUFF_TBL_PTR; + { ptrs to Huffman coding tables, or NIL if not defined } + + arith_dc_L : Array[0..NUM_ARITH_TBLS-1] of UINT8; { L values for DC arith-coding tables } + arith_dc_U : Array[0..NUM_ARITH_TBLS-1] of UINT8; { U values for DC arith-coding tables } + arith_ac_K : Array[0..NUM_ARITH_TBLS-1] of UINT8; { Kx values for AC arith-coding tables } + + num_scans : int; { # of entries in scan_info array } + scan_info : jpeg_scan_info_ptr; { script for multi-scan file, or NIL } + { The default value of scan_info is NIL, which causes a single-scan + sequential JPEG file to be emitted. To create a multi-scan file, + set num_scans and scan_info to point to an array of scan definitions. } + + raw_data_in : boolean; { TRUE=caller supplies downsampled data } + arith_code : boolean; { TRUE=arithmetic coding, FALSE=Huffman } + optimize_coding : boolean; { TRUE=optimize entropy encoding parms } + CCIR601_sampling : boolean; { TRUE=first samples are cosited } + smoothing_factor : int; { 1..100, or 0 for no input smoothing } + dct_method : J_DCT_METHOD; { DCT algorithm selector } + + { The restart interval can be specified in absolute MCUs by setting + restart_interval, or in MCU rows by setting restart_in_rows + (in which case the correct restart_interval will be figured + for each scan). } + + restart_interval : uint; { MCUs per restart, or 0 for no restart } + restart_in_rows : int; { if > 0, MCU rows per restart interval } + + { Parameters controlling emission of special markers. } + + write_JFIF_header : boolean; { should a JFIF marker be written? } + JFIF_major_version : UINT8; { What to write for the JFIF version number } + JFIF_minor_version : UINT8; + { These three values are not used by the JPEG code, merely copied } + { into the JFIF APP0 marker. density_unit can be 0 for unknown, } + { 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect } + { ratio is defined by X_density/Y_density even when density_unit=0. } + density_unit : UINT8; { JFIF code for pixel size units } + X_density : UINT16; { Horizontal pixel density } + Y_density : UINT16; { Vertical pixel density } + write_Adobe_marker : boolean; { should an Adobe marker be written? } + + { State variable: index of next scanline to be written to + jpeg_write_scanlines(). Application may use this to control its + processing loop, e.g., "while (next_scanline < image_height)". } + + next_scanline : JDIMENSION; { 0 .. image_height-1 } + + { Remaining fields are known throughout compressor, but generally + should not be touched by a surrounding application. } + + { These fields are computed during compression startup } + progressive_mode : boolean; { TRUE if scan script uses progressive mode } + max_h_samp_factor : int; { largest h_samp_factor } + max_v_samp_factor : int; { largest v_samp_factor } + + total_iMCU_rows : JDIMENSION; { # of iMCU rows to be input to coef ctlr } + { The coefficient controller receives data in units of MCU rows as defined + for fully interleaved scans (whether the JPEG file is interleaved or not). + There are v_samp_factor * DCTSIZE sample rows of each component in an + "iMCU" (interleaved MCU) row. } + + { These fields are valid during any one scan. + They describe the components and MCUs actually appearing in the scan. } + + comps_in_scan : int; { # of JPEG components in this scan } + cur_comp_info : Array[0..MAX_COMPS_IN_SCAN-1] of jpeg_component_info_ptr; + { cur_comp_info[i]^ describes component that appears i'th in SOS } + + MCUs_per_row : JDIMENSION; { # of MCUs across the image } + MCU_rows_in_scan : JDIMENSION;{ # of MCU rows in the image } + + blocks_in_MCU : int; { # of DCT blocks per MCU } + MCU_membership : Array[0..C_MAX_BLOCKS_IN_MCU-1] of int; + { MCU_membership[i] is index in cur_comp_info of component owning } + { i'th block in an MCU } + + Ss, Se, Ah, Al : int; { progressive JPEG parameters for scan } + + { Links to compression subobjects (methods and private variables of modules) } + master : jpeg_comp_master_ptr; + main : jpeg_c_main_controller_ptr; + prep : jpeg_c_prep_controller_ptr; + coef : jpeg_c_coef_controller_ptr; + marker : jpeg_marker_writer_ptr; + cconvert : jpeg_color_converter_ptr; + downsample : jpeg_downsampler_ptr; + fdct : jpeg_forward_dct_ptr; + entropy : jpeg_entropy_encoder_ptr; + script_space : jpeg_scan_info_ptr; { workspace for jpeg_simple_progression } + script_space_size : int; + end; + + +{ Master record for a decompression instance } + + coef_bits_field = Array[0..DCTSIZE2-1] of int; + coef_bits_ptr = ^coef_bits_field; + coef_bits_ptrfield = Array[0..MAX_COMPS_IN_SCAN-1] of coef_bits_field; + coef_bits_ptrrow = ^coef_bits_ptrfield; + + range_limit_table = array[-(MAXJSAMPLE+1)..4*(MAXJSAMPLE+1) + + CENTERJSAMPLE -1] of JSAMPLE; + range_limit_table_ptr = ^range_limit_table; + + jpeg_decompress_struct = record + { Fields shared with jpeg_compress_struct } + err : jpeg_error_mgr_ptr; { Error handler module } + mem : jpeg_memory_mgr_ptr; { Memory manager module } + progress : jpeg_progress_mgr_ptr; { Progress monitor, or NIL if none } + client_data : voidp; { Available for use by application } + is_decompressor : boolean; { so common code can tell which is which } + global_state : int; { for checking call sequence validity } + + { Source of compressed data } + src : jpeg_source_mgr_ptr; + + { Basic description of image --- filled in by jpeg_read_header(). } + { Application may inspect these values to decide how to process image. } + + image_width : JDIMENSION; { nominal image width (from SOF marker) } + image_height : JDIMENSION; { nominal image height } + num_components : int; { # of color components in JPEG image } + jpeg_color_space : J_COLOR_SPACE; { colorspace of JPEG image } + + { Decompression processing parameters --- these fields must be set before + calling jpeg_start_decompress(). Note that jpeg_read_header() + initializes them to default values. } + + out_color_space : J_COLOR_SPACE; { colorspace for output } + + scale_num, scale_denom : uint ; { fraction by which to scale image } + + output_gamma : double; { image gamma wanted in output } + + buffered_image : boolean; { TRUE=multiple output passes } + raw_data_out : boolean; { TRUE=downsampled data wanted } + + dct_method : J_DCT_METHOD; { IDCT algorithm selector } + do_fancy_upsampling : boolean; { TRUE=apply fancy upsampling } + do_block_smoothing : boolean; { TRUE=apply interblock smoothing } + + quantize_colors : boolean; { TRUE=colormapped output wanted } + { the following are ignored if not quantize_colors: } + dither_mode : J_DITHER_MODE; { type of color dithering to use } + two_pass_quantize : boolean; { TRUE=use two-pass color quantization } + desired_number_of_colors : int; { max # colors to use in created colormap } + { these are significant only in buffered-image mode: } + enable_1pass_quant : boolean; { enable future use of 1-pass quantizer } + enable_external_quant : boolean; { enable future use of external colormap } + enable_2pass_quant : boolean; { enable future use of 2-pass quantizer } + + { Description of actual output image that will be returned to application. + These fields are computed by jpeg_start_decompress(). + You can also use jpeg_calc_output_dimensions() to determine these values + in advance of calling jpeg_start_decompress(). } + + output_width : JDIMENSION; { scaled image width } + output_height: JDIMENSION; { scaled image height } + out_color_components : int; { # of color components in out_color_space } + output_components : int; { # of color components returned } + { output_components is 1 (a colormap index) when quantizing colors; + otherwise it equals out_color_components. } + + rec_outbuf_height : int; { min recommended height of scanline buffer } + { If the buffer passed to jpeg_read_scanlines() is less than this many + rows high, space and time will be wasted due to unnecessary data + copying. Usually rec_outbuf_height will be 1 or 2, at most 4. } + + { When quantizing colors, the output colormap is described by these + fields. The application can supply a colormap by setting colormap + non-NIL before calling jpeg_start_decompress; otherwise a colormap + is created during jpeg_start_decompress or jpeg_start_output. The map + has out_color_components rows and actual_number_of_colors columns. } + + actual_number_of_colors : int; { number of entries in use } + colormap : JSAMPARRAY; { The color map as a 2-D pixel array } + + { State variables: these variables indicate the progress of decompression. + The application may examine these but must not modify them. } + + { Row index of next scanline to be read from jpeg_read_scanlines(). + Application may use this to control its processing loop, e.g., + "while (output_scanline < output_height)". } + + output_scanline : JDIMENSION; { 0 .. output_height-1 } + + { Current input scan number and number of iMCU rows completed in scan. + These indicate the progress of the decompressor input side. } + + input_scan_number : int; { Number of SOS markers seen so far } + input_iMCU_row : JDIMENSION; { Number of iMCU rows completed } + + { The "output scan number" is the notional scan being displayed by the + output side. The decompressor will not allow output scan/row number + to get ahead of input scan/row, but it can fall arbitrarily far behind.} + + output_scan_number : int; { Nominal scan number being displayed } + output_iMCU_row : int; { Number of iMCU rows read } + + { Current progression status. coef_bits[c][i] indicates the precision + with which component c's DCT coefficient i (in zigzag order) is known. + It is -1 when no data has yet been received, otherwise it is the point + transform (shift) value for the most recent scan of the coefficient + (thus, 0 at completion of the progression). + This pointer is NIL when reading a non-progressive file. } + + coef_bits : coef_bits_ptrrow; + { -1 or current Al value for each coef } + + { Internal JPEG parameters --- the application usually need not look at + these fields. Note that the decompressor output side may not use + any parameters that can change between scans. } + + { Quantization and Huffman tables are carried forward across input + datastreams when processing abbreviated JPEG datastreams. } + + quant_tbl_ptrs : Array[0..NUM_QUANT_TBLS-1] of JQUANT_TBL_PTR; + { ptrs to coefficient quantization tables, or NIL if not defined } + + dc_huff_tbl_ptrs : Array[0..NUM_HUFF_TBLS-1] of JHUFF_TBL_PTR; + ac_huff_tbl_ptrs : Array[0..NUM_HUFF_TBLS-1] of JHUFF_TBL_PTR; + { ptrs to Huffman coding tables, or NIL if not defined } + + { These parameters are never carried across datastreams, since they + are given in SOF/SOS markers or defined to be reset by SOI. } + + data_precision : int; { bits of precision in image data } + + comp_info : jpeg_component_info_list_ptr; + { comp_info^[i] describes component that appears i'th in SOF } + + progressive_mode : boolean; { TRUE if SOFn specifies progressive mode } + arith_code : boolean; { TRUE=arithmetic coding, FALSE=Huffman } + + arith_dc_L : Array[0..NUM_ARITH_TBLS-1] of UINT8; { L values for DC arith-coding tables } + arith_dc_U : Array[0..NUM_ARITH_TBLS-1] of UINT8; { U values for DC arith-coding tables } + arith_ac_K : Array[0..NUM_ARITH_TBLS-1] of UINT8; { Kx values for AC arith-coding tables } + + restart_interval : uint; { MCUs per restart interval, or 0 for no restart } + + { These fields record data obtained from optional markers recognized by + the JPEG library. } + + saw_JFIF_marker : boolean; { TRUE iff a JFIF APP0 marker was found } + { Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: } + JFIF_major_version : UINT8; { JFIF version number } + JFIF_minor_version : UINT8; + density_unit : UINT8; { JFIF code for pixel size units } + X_density : UINT16; { Horizontal pixel density } + Y_density : UINT16; { Vertical pixel density } + saw_Adobe_marker : boolean; { TRUE iff an Adobe APP14 marker was found } + Adobe_transform : UINT8; { Color transform code from Adobe marker } + + CCIR601_sampling : boolean; { TRUE=first samples are cosited } + + { Aside from the specific data retained from APPn markers known to the + library, the uninterpreted contents of any or all APPn and COM markers + can be saved in a list for examination by the application. } + + marker_list : jpeg_saved_marker_ptr; { Head of list of saved markers } + + { Remaining fields are known throughout decompressor, but generally + should not be touched by a surrounding application. } + + + { These fields are computed during decompression startup } + + max_h_samp_factor : int; { largest h_samp_factor } + max_v_samp_factor : int; { largest v_samp_factor } + + min_DCT_scaled_size : int; { smallest DCT_scaled_size of any component } + + total_iMCU_rows : JDIMENSION; { # of iMCU rows in image } + { The coefficient controller's input and output progress is measured in + units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + in fully interleaved JPEG scans, but are used whether the scan is + interleaved or not. We define an iMCU row as v_samp_factor DCT block + rows of each component. Therefore, the IDCT output contains + v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row.} + + sample_range_limit : range_limit_table_ptr; { table for fast range-limiting } + + + { These fields are valid during any one scan. + They describe the components and MCUs actually appearing in the scan. + Note that the decompressor output side must not use these fields. } + + comps_in_scan : int; { # of JPEG components in this scan } + cur_comp_info : Array[0..MAX_COMPS_IN_SCAN-1] of jpeg_component_info_ptr; + { cur_comp_info[i]^ describes component that appears i'th in SOS } + + MCUs_per_row : JDIMENSION; { # of MCUs across the image } + MCU_rows_in_scan : JDIMENSION; { # of MCU rows in the image } + + blocks_in_MCU : JDIMENSION; { # of DCT blocks per MCU } + MCU_membership : Array[0..D_MAX_BLOCKS_IN_MCU-1] of int; + { MCU_membership[i] is index in cur_comp_info of component owning } + { i'th block in an MCU } + + Ss, Se, Ah, Al : int; { progressive JPEG parameters for scan } + + { This field is shared between entropy decoder and marker parser. + It is either zero or the code of a JPEG marker that has been + read from the data source, but has not yet been processed. } + + unread_marker : int; + + { Links to decompression subobjects + (methods, private variables of modules) } + + master : jpeg_decomp_master_ptr; + main : jpeg_d_main_controller_ptr; + coef : jpeg_d_coef_controller_ptr; + post : jpeg_d_post_controller_ptr; + inputctl : jpeg_input_controller_ptr; + marker : jpeg_marker_reader_ptr; + entropy : jpeg_entropy_decoder_ptr; + idct : jpeg_inverse_dct_ptr; + upsample : jpeg_upsampler_ptr; + cconvert : jpeg_color_deconverter_ptr; + cquantize : jpeg_color_quantizer_ptr; + end; + +{ Decompression startup: read start of JPEG datastream to see what's there + function jpeg_read_header (cinfo : j_decompress_ptr; + require_image : boolean) : int; + Return value is one of: } +const + JPEG_SUSPENDED = 0; { Suspended due to lack of input data } + JPEG_HEADER_OK = 1; { Found valid image datastream } + JPEG_HEADER_TABLES_ONLY = 2; { Found valid table-specs-only datastream } +{ If you pass require_image = TRUE (normal case), you need not check for + a TABLES_ONLY return code; an abbreviated file will cause an error exit. + JPEG_SUSPENDED is only possible if you use a data source module that can + give a suspension return (the stdio source module doesn't). } + + +{ function jpeg_consume_input (cinfo : j_decompress_ptr) : int; + Return value is one of: } + + JPEG_REACHED_SOS = 1; { Reached start of new scan } + JPEG_REACHED_EOI = 2; { Reached end of image } + JPEG_ROW_COMPLETED = 3; { Completed one iMCU row } + JPEG_SCAN_COMPLETED = 4; { Completed last iMCU row of a scan } + + + + +implementation + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jquant1_del.pas b/mseide-msegui/lib/common/fpccompatibility/jquant1_del.pas new file mode 100644 index 0000000..bd5db7f --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jquant1_del.pas @@ -0,0 +1,1011 @@ +unit jquant1_del; + +{ This file contains 1-pass color quantization (color mapping) routines. + These routines provide mapping to a fixed color map using equally spaced + color values. Optional Floyd-Steinberg or ordered dithering is available. } + +{ Original: jquant1.c; Copyright (C) 1991-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jpeglib_del; + + +{GLOBAL} +procedure jinit_1pass_quantizer (cinfo : j_decompress_ptr); + +implementation + +uses + jmorecfg_del, + jdeferr_del, + jerror_del, + jutils_del; + +{ The main purpose of 1-pass quantization is to provide a fast, if not very + high quality, colormapped output capability. A 2-pass quantizer usually + gives better visual quality; however, for quantized grayscale output this + quantizer is perfectly adequate. Dithering is highly recommended with this + quantizer, though you can turn it off if you really want to. + + In 1-pass quantization the colormap must be chosen in advance of seeing the + image. We use a map consisting of all combinations of Ncolors[i] color + values for the i'th component. The Ncolors[] values are chosen so that + their product, the total number of colors, is no more than that requested. + (In most cases, the product will be somewhat less.) + + Since the colormap is orthogonal, the representative value for each color + component can be determined without considering the other components; + then these indexes can be combined into a colormap index by a standard + N-dimensional-array-subscript calculation. Most of the arithmetic involved + can be precalculated and stored in the lookup table colorindex[]. + colorindex[i][j] maps pixel value j in component i to the nearest + representative value (grid plane) for that component; this index is + multiplied by the array stride for component i, so that the + index of the colormap entry closest to a given pixel value is just + sum( colorindex[component-number][pixel-component-value] ) + Aside from being fast, this scheme allows for variable spacing between + representative values with no additional lookup cost. + + If gamma correction has been applied in color conversion, it might be wise + to adjust the color grid spacing so that the representative colors are + equidistant in linear space. At this writing, gamma correction is not + implemented by jdcolor, so nothing is done here. } + + +{ Declarations for ordered dithering. + + We use a standard 16x16 ordered dither array. The basic concept of ordered + dithering is described in many references, for instance Dale Schumacher's + chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). + In place of Schumacher's comparisons against a "threshold" value, we add a + "dither" value to the input pixel and then round the result to the nearest + output value. The dither value is equivalent to (0.5 - threshold) times + the distance between output values. For ordered dithering, we assume that + the output colors are equally spaced; if not, results will probably be + worse, since the dither may be too much or too little at a given point. + + The normal calculation would be to form pixel value + dither, range-limit + this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. + We can skip the separate range-limiting step by extending the colorindex + table in both directions. } + + +const + ODITHER_SIZE = 16; { dimension of dither matrix } +{ NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break } + ODITHER_CELLS = (ODITHER_SIZE*ODITHER_SIZE); { # cells in matrix } + ODITHER_MASK = (ODITHER_SIZE-1); { mask for wrapping around counters } + +type + ODITHER_vector = Array[0..ODITHER_SIZE-1] of int; + ODITHER_MATRIX = Array[0..ODITHER_SIZE-1] of ODITHER_vector; + {ODITHER_MATRIX_PTR = ^array[0..ODITHER_SIZE-1] of int;} + ODITHER_MATRIX_PTR = ^ODITHER_MATRIX; + +const + base_dither_matrix : Array[0..ODITHER_SIZE-1,0..ODITHER_SIZE-1] of UINT8 + = ( + { Bayer's order-4 dither array. Generated by the code given in + Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. + The values in this array must range from 0 to ODITHER_CELLS-1. } + + ( 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 ), + ( 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 ), + ( 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 ), + ( 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 ), + ( 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 ), + ( 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 ), + ( 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 ), + ( 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 ), + ( 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 ), + ( 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 ), + ( 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 ), + ( 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 ), + ( 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 ), + ( 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 ), + ( 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 ), + ( 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 ) + ); + + +{ Declarations for Floyd-Steinberg dithering. + + Errors are accumulated into the array fserrors[], at a resolution of + 1/16th of a pixel count. The error at a given pixel is propagated + to its not-yet-processed neighbors using the standard F-S fractions, + ... (here) 7/16 + 3/16 5/16 1/16 + We work left-to-right on even rows, right-to-left on odd rows. + + We can get away with a single array (holding one row's worth of errors) + by using it to store the current row's errors at pixel columns not yet + processed, but the next row's errors at columns already processed. We + need only a few extra variables to hold the errors immediately around the + current column. (If we are lucky, those variables are in registers, but + even if not, they're probably cheaper to access than array elements are.) + + The fserrors[] array is indexed [component#][position]. + We provide (#columns + 2) entries per component; the extra entry at each + end saves us from special-casing the first and last pixels. + + Note: on a wide image, we might not have enough room in a PC's near data + segment to hold the error array; so it is allocated with alloc_large. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +type + FSERROR = INT16; { 16 bits should be enough } + LOCFSERROR = int; { use 'int' for calculation temps } +{$else} +type + FSERROR = INT32; { may need more than 16 bits } + LOCFSERROR = INT32; { be sure calculation temps are big enough } +{$endif} + +type + jFSError = 0..(MaxInt div SIZEOF(FSERROR))-1; + FS_ERROR_FIELD = array[jFSError] of FSERROR; + FS_ERROR_FIELD_PTR = ^FS_ERROR_FIELD;{far} + { pointer to error array (in FAR storage!) } + FSERRORPTR = ^FSERROR; + + +{ Private subobject } + +const + MAX_Q_COMPS = 4; { max components I can handle } + +type + my_cquantize_ptr = ^my_cquantizer; + my_cquantizer = record + pub : jpeg_color_quantizer; { public fields } + + { Initially allocated colormap is saved here } + sv_colormap : JSAMPARRAY; { The color map as a 2-D pixel array } + sv_actual : int; { number of entries in use } + + colorindex : JSAMPARRAY; { Precomputed mapping for speed } + { colorindex[i][j] = index of color closest to pixel value j in component i, + premultiplied as described above. Since colormap indexes must fit into + JSAMPLEs, the entries of this array will too. } + + is_padded : boolean; { is the colorindex padded for odither? } + + Ncolors : array[0..MAX_Q_COMPS-1] of int; + { # of values alloced to each component } + + { Variables for ordered dithering } + row_index : int; { cur row's vertical index in dither matrix } + odither : array[0..MAX_Q_COMPS-1] of ODITHER_MATRIX_PTR; + { one dither array per component } + { Variables for Floyd-Steinberg dithering } + fserrors : array[0..MAX_Q_COMPS-1] of FS_ERROR_FIELD_PTR; + { accumulated errors } + on_odd_row : boolean; { flag to remember which row we are on } + end; + + +{ Policy-making subroutines for create_colormap and create_colorindex. + These routines determine the colormap to be used. The rest of the module + only assumes that the colormap is orthogonal. + + * select_ncolors decides how to divvy up the available colors + among the components. + * output_value defines the set of representative values for a component. + * largest_input_value defines the mapping from input values to + representative values for a component. + Note that the latter two routines may impose different policies for + different components, though this is not currently done. } + + + +{LOCAL} +function select_ncolors (cinfo : j_decompress_ptr; + var Ncolors : array of int) : int; +{ Determine allocation of desired colors to components, } +{ and fill in Ncolors[] array to indicate choice. } +{ Return value is total number of colors (product of Ncolors[] values). } +var + nc : int; + max_colors : int; + total_colors, iroot, i, j : int; + changed : boolean; + temp : long; +const + RGB_order:array[0..2] of int = (RGB_GREEN, RGB_RED, RGB_BLUE); +begin + nc := cinfo^.out_color_components; { number of color components } + max_colors := cinfo^.desired_number_of_colors; + + { We can allocate at least the nc'th root of max_colors per component. } + { Compute floor(nc'th root of max_colors). } + iroot := 1; + repeat + Inc(iroot); + temp := iroot; { set temp = iroot ** nc } + for i := 1 to pred(nc) do + temp := temp * iroot; + until (temp > long(max_colors)); { repeat till iroot exceeds root } + Dec(iroot); { now iroot = floor(root) } + + { Must have at least 2 color values per component } + if (iroot < 2) then + ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_FEW_COLORS, int(temp)); + + { Initialize to iroot color values for each component } + total_colors := 1; + for i := 0 to pred(nc) do + begin + Ncolors[i] := iroot; + total_colors := total_colors * iroot; + end; + + { We may be able to increment the count for one or more components without + exceeding max_colors, though we know not all can be incremented. + Sometimes, the first component can be incremented more than once! + (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) + In RGB colorspace, try to increment G first, then R, then B. } + + repeat + changed := FALSE; + for i := 0 to pred(nc) do + begin + if cinfo^.out_color_space = JCS_RGB then + j := RGB_order[i] + else + j := i; + { calculate new total_colors if Ncolors[j] is incremented } + temp := total_colors div Ncolors[j]; + temp := temp * (Ncolors[j]+1); { done in long arith to avoid oflo } + if (temp > long(max_colors)) then + break; { won't fit, done with this pass } + Inc(Ncolors[j]); { OK, apply the increment } + total_colors := int(temp); + changed := TRUE; + end; + until not changed; + + select_ncolors := total_colors; +end; + + +{LOCAL} +function output_value (cinfo : j_decompress_ptr; + ci : int; j : int; maxj : int) : int; +{ Return j'th output value, where j will range from 0 to maxj } +{ The output values must fall in 0..MAXJSAMPLE in increasing order } +begin + { We always provide values 0 and MAXJSAMPLE for each component; + any additional values are equally spaced between these limits. + (Forcing the upper and lower values to the limits ensures that + dithering can't produce a color outside the selected gamut.) } + + output_value := int (( INT32(j) * MAXJSAMPLE + maxj div 2) div maxj); +end; + + +{LOCAL} +function largest_input_value (cinfo : j_decompress_ptr; + ci : int; j : int; maxj : int) : int; +{ Return largest input value that should map to j'th output value } +{ Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE } +begin + { Breakpoints are halfway between values returned by output_value } + largest_input_value := int (( INT32(2*j + 1) * MAXJSAMPLE + + maxj) div (2*maxj)); +end; + + +{ Create the colormap. } + +{LOCAL} +procedure create_colormap (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; + colormap : JSAMPARRAY; { Created colormap } + + total_colors : int; { Number of distinct output colors } + i,j,k, nci, blksize, blkdist, ptr, val : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + + { Select number of colors for each component } + total_colors := select_ncolors(cinfo, cquantize^.Ncolors); + + { Report selected color counts } + {$IFDEF DEBUG} + if (cinfo^.out_color_components = 3) then + TRACEMS4(j_common_ptr(cinfo), 1, JTRC_QUANT_3_NCOLORS, + total_colors, cquantize^.Ncolors[0], + cquantize^.Ncolors[1], cquantize^.Ncolors[2]) + else + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_QUANT_NCOLORS, total_colors); + {$ENDIF} + + { Allocate and fill in the colormap. } + { The colors are ordered in the map in standard row-major order, } + { i.e. rightmost (highest-indexed) color changes most rapidly. } + + colormap := cinfo^.mem^.alloc_sarray( + j_common_ptr(cinfo), JPOOL_IMAGE, + JDIMENSION(total_colors), JDIMENSION(cinfo^.out_color_components)); + + { blksize is number of adjacent repeated entries for a component } + { blkdist is distance between groups of identical entries for a component } + blkdist := total_colors; + + for i := 0 to pred(cinfo^.out_color_components) do + begin + { fill in colormap entries for i'th color component } + nci := cquantize^.Ncolors[i]; { # of distinct values for this color } + blksize := blkdist div nci; + for j := 0 to pred(nci) do + begin + { Compute j'th output value (out of nci) for component } + val := output_value(cinfo, i, j, nci-1); + { Fill in all colormap entries that have this value of this component } + ptr := j * blksize; + while (ptr < total_colors) do + begin + { fill in blksize entries beginning at ptr } + for k := 0 to pred(blksize) do + colormap^[i]^[ptr+k] := JSAMPLE(val); + + Inc(ptr, blkdist); + end; + end; + blkdist := blksize; { blksize of this color is blkdist of next } + end; + + { Save the colormap in private storage, + where it will survive color quantization mode changes. } + + cquantize^.sv_colormap := colormap; + cquantize^.sv_actual := total_colors; +end; + +{ Create the color index table. } + +{LOCAL} +procedure create_colorindex (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; + indexptr, + help_indexptr : JSAMPROW; { for negative offsets } + i,j,k, nci, blksize, val, pad : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + { For ordered dither, we pad the color index tables by MAXJSAMPLE in + each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE). + This is not necessary in the other dithering modes. However, we + flag whether it was done in case user changes dithering mode. } + + if (cinfo^.dither_mode = JDITHER_ORDERED) then + begin + pad := MAXJSAMPLE*2; + cquantize^.is_padded := TRUE; + end + else + begin + pad := 0; + cquantize^.is_padded := FALSE; + end; + + cquantize^.colorindex := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + JDIMENSION(MAXJSAMPLE+1 + pad), + JDIMENSION(cinfo^.out_color_components)); + + { blksize is number of adjacent repeated entries for a component } + blksize := cquantize^.sv_actual; + + for i := 0 to pred(cinfo^.out_color_components) do + begin + { fill in colorindex entries for i'th color component } + nci := cquantize^.Ncolors[i]; { # of distinct values for this color } + blksize := blksize div nci; + + { adjust colorindex pointers to provide padding at negative indexes. } + if (pad <> 0) then + Inc(JSAMPLE_PTR(cquantize^.colorindex^[i]), MAXJSAMPLE); + + { in loop, val = index of current output value, } + { and k = largest j that maps to current val } + indexptr := cquantize^.colorindex^[i]; + val := 0; + k := largest_input_value(cinfo, i, 0, nci-1); + for j := 0 to MAXJSAMPLE do + begin + while (j > k) do { advance val if past boundary } + begin + Inc(val); + k := largest_input_value(cinfo, i, val, nci-1); + end; + { premultiply so that no multiplication needed in main processing } + indexptr^[j] := JSAMPLE (val * blksize); + end; + { Pad at both ends if necessary } + if (pad <> 0) then + begin + help_indexptr := indexptr; + { adjust the help pointer to avoid negative offsets } + Dec(JSAMPLE_PTR(help_indexptr), MAXJSAMPLE); + + for j := 1 to MAXJSAMPLE do + begin + {indexptr^[-j] := indexptr^[0];} + help_indexptr^[MAXJSAMPLE-j] := indexptr^[0]; + indexptr^[MAXJSAMPLE+j] := indexptr^[MAXJSAMPLE]; + end; + end; + end; +end; + + +{ Create an ordered-dither array for a component having ncolors + distinct output values. } + +{LOCAL} +function make_odither_array (cinfo : j_decompress_ptr; + ncolors : int) : ODITHER_MATRIX_PTR; +var + odither : ODITHER_MATRIX_PTR; + j, k : int; + num, den : INT32; +begin + odither := ODITHER_MATRIX_PTR ( + cinfo^.mem^.alloc_small(j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(ODITHER_MATRIX))); + { The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). + Hence the dither value for the matrix cell with fill order f + (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). + On 16-bit-int machine, be careful to avoid overflow. } + + den := 2 * ODITHER_CELLS * ( INT32(ncolors - 1)); + for j := 0 to pred(ODITHER_SIZE) do + begin + for k := 0 to pred(ODITHER_SIZE) do + begin + num := ( INT32(ODITHER_CELLS-1 - 2*( int(base_dither_matrix[j][k])))) + * MAXJSAMPLE; + { Ensure round towards zero despite C's lack of consistency + about rounding negative values in integer division... } + + if num<0 then + odither^[j][k] := int (-((-num) div den)) + else + odither^[j][k] := int (num div den); + end; + end; + make_odither_array := odither; +end; + + +{ Create the ordered-dither tables. + Components having the same number of representative colors may + share a dither table. } + +{LOCAL} +procedure create_odither_tables (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; + odither : ODITHER_MATRIX_PTR; + i, j, nci : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + + for i := 0 to pred(cinfo^.out_color_components) do + begin + nci := cquantize^.Ncolors[i]; { # of distinct values for this color } + odither := NIL; { search for matching prior component } + for j := 0 to pred(i) do + begin + if (nci = cquantize^.Ncolors[j]) then + begin + odither := cquantize^.odither[j]; + break; + end; + end; + if (odither = NIL) then { need a new table? } + odither := make_odither_array(cinfo, nci); + cquantize^.odither[i] := odither; + end; +end; + + +{ Map some rows of pixels to the output colormapped representation. } + +{METHODDEF} +procedure color_quantize (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ General case, no dithering } +var + cquantize : my_cquantize_ptr; + colorindex : JSAMPARRAY; + pixcode, ci : int; {register} + ptrin, ptrout : JSAMPLE_PTR; {register} + row : int; + col : JDIMENSION; + width : JDIMENSION; + nc : int; {register} +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + colorindex := cquantize^.colorindex; + width := cinfo^.output_width; + nc := cinfo^.out_color_components; + + for row := 0 to pred(num_rows) do + begin + ptrin := JSAMPLE_PTR(input_buf^[row]); + ptrout := JSAMPLE_PTR(output_buf^[row]); + for col := pred(width) downto 0 do + begin + pixcode := 0; + for ci := 0 to pred(nc) do + begin + Inc(pixcode, GETJSAMPLE(colorindex^[ci]^[GETJSAMPLE(ptrin^)]) ); + Inc(ptrin); + end; + ptrout^ := JSAMPLE (pixcode); + Inc(ptrout); + end; + end; +end; + + +{METHODDEF} +procedure color_quantize3 (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ Fast path for out_color_components=3, no dithering } +var + cquantize : my_cquantize_ptr; + pixcode : int; {register} + ptrin, ptrout : JSAMPLE_PTR; {register} + colorindex0 : JSAMPROW; + colorindex1 : JSAMPROW; + colorindex2 : JSAMPROW; + row : int; + col : JDIMENSION; + width : JDIMENSION; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + colorindex0 := (cquantize^.colorindex)^[0]; + colorindex1 := (cquantize^.colorindex)^[1]; + colorindex2 := (cquantize^.colorindex)^[2]; + width := cinfo^.output_width; + + for row := 0 to pred(num_rows) do + begin + ptrin := JSAMPLE_PTR(input_buf^[row]); + ptrout := JSAMPLE_PTR(output_buf^[row]); + for col := pred(width) downto 0 do + begin + pixcode := GETJSAMPLE((colorindex0)^[GETJSAMPLE(ptrin^)]); + Inc(ptrin); + Inc( pixcode, GETJSAMPLE((colorindex1)^[GETJSAMPLE(ptrin^)]) ); + Inc(ptrin); + Inc( pixcode, GETJSAMPLE((colorindex2)^[GETJSAMPLE(ptrin^)]) ); + Inc(ptrin); + ptrout^ := JSAMPLE (pixcode); + Inc(ptrout); + end; + end; +end; + + +{METHODDEF} +procedure quantize_ord_dither (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ General case, with ordered dithering } +var + cquantize : my_cquantize_ptr; + input_ptr, {register} + output_ptr : JSAMPLE_PTR; {register} + colorindex_ci : JSAMPROW; + dither : ^ODITHER_vector; { points to active row of dither matrix } + row_index, col_index : int; { current indexes into dither matrix } + nc : int; + ci : int; + row : int; + col : JDIMENSION; + width : JDIMENSION; +var + pad_offset : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + nc := cinfo^.out_color_components; + width := cinfo^.output_width; + + { Nomssi: work around negative offset } + if my_cquantize_ptr (cinfo^.cquantize)^.is_padded then + pad_offset := MAXJSAMPLE + else + pad_offset := 0; + + for row := 0 to pred(num_rows) do + begin + { Initialize output values to 0 so can process components separately } + jzero_far( {far} pointer(output_buf^[row]), + size_t(width * SIZEOF(JSAMPLE))); + row_index := cquantize^.row_index; + for ci := 0 to pred(nc) do + begin + input_ptr := JSAMPLE_PTR(@ input_buf^[row]^[ci]); + output_ptr := JSAMPLE_PTR(output_buf^[row]); + colorindex_ci := cquantize^.colorindex^[ci]; + { Nomssi } + Dec(JSAMPLE_PTR(colorindex_ci), pad_offset); + + dither := @(cquantize^.odither[ci]^[row_index]); + col_index := 0; + + for col := pred(width) downto 0 do + begin + { Form pixel value + dither, range-limit to 0..MAXJSAMPLE, + select output value, accumulate into output code for this pixel. + Range-limiting need not be done explicitly, as we have extended + the colorindex table to produce the right answers for out-of-range + inputs. The maximum dither is +- MAXJSAMPLE; this sets the + required amount of padding. } + + Inc(output_ptr^, + colorindex_ci^[GETJSAMPLE(input_ptr^)+ pad_offset + + dither^[col_index]]); + Inc(output_ptr); + Inc(input_ptr, nc); + col_index := (col_index + 1) and ODITHER_MASK; + end; + end; + { Advance row index for next row } + row_index := (row_index + 1) and ODITHER_MASK; + cquantize^.row_index := row_index; + end; +end; + +{METHODDEF} +procedure quantize3_ord_dither (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ Fast path for out_color_components=3, with ordered dithering } +var + cquantize : my_cquantize_ptr; + pixcode : int; {register} + input_ptr : JSAMPLE_PTR; {register} + output_ptr : JSAMPLE_PTR; {register} + colorindex0 : JSAMPROW; + colorindex1 : JSAMPROW; + colorindex2 : JSAMPROW; + dither0 : ^ODITHER_vector; { points to active row of dither matrix } + dither1 : ^ODITHER_vector; + dither2 : ^ODITHER_vector; + row_index, col_index : int; { current indexes into dither matrix } + row : int; + col : JDIMENSION; + width : JDIMENSION; +var + pad_offset : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + colorindex0 := (cquantize^.colorindex)^[0]; + colorindex1 := (cquantize^.colorindex)^[1]; + colorindex2 := (cquantize^.colorindex)^[2]; + width := cinfo^.output_width; + + { Nomssi: work around negative offset } + if my_cquantize_ptr (cinfo^.cquantize)^.is_padded then + pad_offset := MAXJSAMPLE + else + pad_offset := 0; + + Dec(JSAMPLE_PTR(colorindex0), pad_offset); + Dec(JSAMPLE_PTR(colorindex1), pad_offset); + Dec(JSAMPLE_PTR(colorindex2), pad_offset); + + for row := 0 to pred(num_rows) do + begin + row_index := cquantize^.row_index; + input_ptr := JSAMPLE_PTR(input_buf^[row]); + output_ptr := JSAMPLE_PTR(output_buf^[row]); + dither0 := @(cquantize^.odither[0]^[row_index]); + dither1 := @(cquantize^.odither[1]^[row_index]); + dither2 := @(cquantize^.odither[2]^[row_index]); + col_index := 0; + + + for col := pred(width) downto 0 do + begin + pixcode := GETJSAMPLE(colorindex0^[GETJSAMPLE(input_ptr^) + pad_offset + + dither0^[col_index]]); + Inc(input_ptr); + Inc(pixcode, GETJSAMPLE(colorindex1^[GETJSAMPLE(input_ptr^) + pad_offset + + dither1^[col_index]])); + Inc(input_ptr); + Inc(pixcode, GETJSAMPLE(colorindex2^[GETJSAMPLE(input_ptr^) + pad_offset + + dither2^[col_index]])); + Inc(input_ptr); + output_ptr^ := JSAMPLE (pixcode); + Inc(output_ptr); + col_index := (col_index + 1) and ODITHER_MASK; + end; + row_index := (row_index + 1) and ODITHER_MASK; + cquantize^.row_index := row_index; + end; +end; + + +{METHODDEF} +procedure quantize_fs_dither (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ General case, with Floyd-Steinberg dithering } +var + cquantize : my_cquantize_ptr; + cur : LOCFSERROR; {register} { current error or pixel value } + belowerr : LOCFSERROR; { error for pixel below cur } + bpreverr : LOCFSERROR; { error for below/prev col } + bnexterr : LOCFSERROR; { error for below/next col } + delta : LOCFSERROR; + prev_errorptr, + errorptr : FSERRORPTR; {register} { => fserrors[] at column before current } + input_ptr, {register} + output_ptr : JSAMPLE_PTR; {register} + colorindex_ci : JSAMPROW; + colormap_ci : JSAMPROW; + pixcode : int; + nc : int; + dir : int; { 1 for left-to-right, -1 for right-to-left } + dirnc : int; { dir * nc } + ci : int; + row : int; + col : JDIMENSION; + width : JDIMENSION; + range_limit : range_limit_table_ptr; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + nc := cinfo^.out_color_components; + width := cinfo^.output_width; + range_limit := cinfo^.sample_range_limit; + + for row := 0 to pred(num_rows) do + begin + { Initialize output values to 0 so can process components separately } + jzero_far( (output_buf)^[row], + size_t(width * SIZEOF(JSAMPLE))); + for ci := 0 to pred(nc) do + begin + input_ptr := JSAMPLE_PTR(@ input_buf^[row]^[ci]); + output_ptr := JSAMPLE_PTR(output_buf^[row]); + errorptr := FSERRORPTR(cquantize^.fserrors[ci]); { => entry before first column } + if (cquantize^.on_odd_row) then + begin + { work right to left in this row } + Inc(input_ptr, (width-1) * nc); { so point to rightmost pixel } + Inc(output_ptr, width-1); + dir := -1; + dirnc := -nc; + Inc(errorptr, (width+1)); { => entry after last column } + end + else + begin + { work left to right in this row } + dir := 1; + dirnc := nc; + {errorptr := cquantize^.fserrors[ci];} + end; + + colorindex_ci := cquantize^.colorindex^[ci]; + + colormap_ci := (cquantize^.sv_colormap)^[ci]; + { Preset error values: no error propagated to first pixel from left } + cur := 0; + { and no error propagated to row below yet } + belowerr := 0; + bpreverr := 0; + + for col := pred(width) downto 0 do + begin + prev_errorptr := errorptr; + Inc(errorptr, dir); { advance errorptr to current column } + + { cur holds the error propagated from the previous pixel on the + current line. Add the error propagated from the previous line + to form the complete error correction term for this pixel, and + round the error term (which is expressed * 16) to an integer. + RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + for either sign of the error value. + Note: errorptr points to *previous* column's array entry. } + + cur := (cur + errorptr^ + 8) div 16; + + { Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + The maximum error is +- MAXJSAMPLE; this sets the required size + of the range_limit array. } + + Inc( cur, GETJSAMPLE(input_ptr^)); + cur := GETJSAMPLE(range_limit^[cur]); + { Select output value, accumulate into output code for this pixel } + pixcode := GETJSAMPLE(colorindex_ci^[cur]); + Inc(output_ptr^, JSAMPLE (pixcode)); + { Compute actual representation error at this pixel } + { Note: we can do this even though we don't have the final } + { pixel code, because the colormap is orthogonal. } + Dec(cur, GETJSAMPLE(colormap_ci^[pixcode])); + { Compute error fractions to be propagated to adjacent pixels. + Add these into the running sums, and simultaneously shift the + next-line error sums left by 1 column. } + + bnexterr := cur; + delta := cur * 2; + Inc(cur, delta); { form error * 3 } + prev_errorptr^ := FSERROR (bpreverr + cur); + Inc(cur, delta); { form error * 5 } + bpreverr := belowerr + cur; + belowerr := bnexterr; + Inc(cur, delta); { form error * 7 } + { At this point cur contains the 7/16 error value to be propagated + to the next pixel on the current line, and all the errors for the + next line have been shifted over. We are therefore ready to move on. } + + Inc(input_ptr, dirnc); { advance input ptr to next column } + Inc(output_ptr, dir); { advance output ptr to next column } + + end; + { Post-loop cleanup: we must unload the final error value into the + final fserrors[] entry. Note we need not unload belowerr because + it is for the dummy column before or after the actual array. } + + errorptr^ := FSERROR (bpreverr); { unload prev err into array } + { Nomssi : ?? } + end; + cquantize^.on_odd_row := not cquantize^.on_odd_row; + end; +end; + + +{ Allocate workspace for Floyd-Steinberg errors. } + +{LOCAL} +procedure alloc_fs_workspace (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; + arraysize : size_t; + i : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + arraysize := size_t ((cinfo^.output_width + 2) * SIZEOF(FSERROR)); + for i := 0 to pred(cinfo^.out_color_components) do + begin + cquantize^.fserrors[i] := FS_ERROR_FIELD_PTR( + cinfo^.mem^.alloc_large(j_common_ptr(cinfo), JPOOL_IMAGE, arraysize)); + end; +end; + + +{ Initialize for one-pass color quantization. } + +{METHODDEF} +procedure start_pass_1_quant (cinfo : j_decompress_ptr; + is_pre_scan : boolean); +var + cquantize : my_cquantize_ptr; + arraysize : size_t; + i : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + { Install my colormap. } + cinfo^.colormap := cquantize^.sv_colormap; + cinfo^.actual_number_of_colors := cquantize^.sv_actual; + + { Initialize for desired dithering mode. } + case (cinfo^.dither_mode) of + JDITHER_NONE: + if (cinfo^.out_color_components = 3) then + cquantize^.pub.color_quantize := color_quantize3 + else + cquantize^.pub.color_quantize := color_quantize; + JDITHER_ORDERED: + begin + if (cinfo^.out_color_components = 3) then + cquantize^.pub.color_quantize := quantize3_ord_dither + else + cquantize^.pub.color_quantize := quantize_ord_dither; + cquantize^.row_index := 0; { initialize state for ordered dither } + { If user changed to ordered dither from another mode, + we must recreate the color index table with padding. + This will cost extra space, but probably isn't very likely. } + + if (not cquantize^.is_padded) then + create_colorindex(cinfo); + { Create ordered-dither tables if we didn't already. } + if (cquantize^.odither[0] = NIL) then + create_odither_tables(cinfo); + end; + JDITHER_FS: + begin + cquantize^.pub.color_quantize := quantize_fs_dither; + cquantize^.on_odd_row := FALSE; { initialize state for F-S dither } + { Allocate Floyd-Steinberg workspace if didn't already. } + if (cquantize^.fserrors[0] = NIL) then + alloc_fs_workspace(cinfo); + { Initialize the propagated errors to zero. } + arraysize := size_t ((cinfo^.output_width + 2) * SIZEOF(FSERROR)); + for i := 0 to pred(cinfo^.out_color_components) do + jzero_far({far} pointer( cquantize^.fserrors[i] ), arraysize); + end; + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + end; +end; + + +{ Finish up at the end of the pass. } + +{METHODDEF} +procedure finish_pass_1_quant (cinfo : j_decompress_ptr); +begin + { no work in 1-pass case } +end; + + +{ Switch to a new external colormap between output passes. + Shouldn't get to this module! } + +{METHODDEF} +procedure new_color_map_1_quant (cinfo : j_decompress_ptr); +begin + ERREXIT(j_common_ptr(cinfo), JERR_MODE_CHANGE); +end; + + +{ Module initialization routine for 1-pass color quantization. } + +{GLOBAL} +procedure jinit_1pass_quantizer (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; +begin + cquantize := my_cquantize_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_cquantizer))); + cinfo^.cquantize := jpeg_color_quantizer_ptr(cquantize); + cquantize^.pub.start_pass := start_pass_1_quant; + cquantize^.pub.finish_pass := finish_pass_1_quant; + cquantize^.pub.new_color_map := new_color_map_1_quant; + cquantize^.fserrors[0] := NIL; { Flag FS workspace not allocated } + cquantize^.odither[0] := NIL; { Also flag odither arrays not allocated } + + { Make sure my internal arrays won't overflow } + if (cinfo^.out_color_components > MAX_Q_COMPS) then + ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_COMPONENTS, MAX_Q_COMPS); + { Make sure colormap indexes can be represented by JSAMPLEs } + if (cinfo^.desired_number_of_colors > (MAXJSAMPLE+1)) then + ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); + + { Create the colormap and color index table. } + create_colormap(cinfo); + create_colorindex(cinfo); + + { Allocate Floyd-Steinberg workspace now if requested. + We do this now since it is FAR storage and may affect the memory + manager's space calculations. If the user changes to FS dither + mode in a later pass, we will allocate the space then, and will + possibly overrun the max_memory_to_use setting. } + + if (cinfo^.dither_mode = JDITHER_FS) then + alloc_fs_workspace(cinfo); +end; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jquant2_del.pas b/mseide-msegui/lib/common/fpccompatibility/jquant2_del.pas new file mode 100644 index 0000000..099d805 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jquant2_del.pas @@ -0,0 +1,1553 @@ +unit jquant2_del; + + +{ This file contains 2-pass color quantization (color mapping) routines. + These routines provide selection of a custom color map for an image, + followed by mapping of the image to that color map, with optional + Floyd-Steinberg dithering. + It is also possible to use just the second pass to map to an arbitrary + externally-given color map. + + Note: ordered dithering is not supported, since there isn't any fast + way to compute intercolor distances; it's unclear that ordered dither's + fundamental assumptions even hold with an irregularly spaced color map. } + +{ Original: jquant2.c; Copyright (C) 1991-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jdeferr_del, + jerror_del, + jutils_del, + jpeglib_del; + +{ Module initialization routine for 2-pass color quantization. } + + +{GLOBAL} +procedure jinit_2pass_quantizer (cinfo : j_decompress_ptr); + +implementation + +{ This module implements the well-known Heckbert paradigm for color + quantization. Most of the ideas used here can be traced back to + Heckbert's seminal paper + Heckbert, Paul. "Color Image Quantization for Frame Buffer Display", + Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304. + + In the first pass over the image, we accumulate a histogram showing the + usage count of each possible color. To keep the histogram to a reasonable + size, we reduce the precision of the input; typical practice is to retain + 5 or 6 bits per color, so that 8 or 4 different input values are counted + in the same histogram cell. + + Next, the color-selection step begins with a box representing the whole + color space, and repeatedly splits the "largest" remaining box until we + have as many boxes as desired colors. Then the mean color in each + remaining box becomes one of the possible output colors. + + The second pass over the image maps each input pixel to the closest output + color (optionally after applying a Floyd-Steinberg dithering correction). + This mapping is logically trivial, but making it go fast enough requires + considerable care. + + Heckbert-style quantizers vary a good deal in their policies for choosing + the "largest" box and deciding where to cut it. The particular policies + used here have proved out well in experimental comparisons, but better ones + may yet be found. + + In earlier versions of the IJG code, this module quantized in YCbCr color + space, processing the raw upsampled data without a color conversion step. + This allowed the color conversion math to be done only once per colormap + entry, not once per pixel. However, that optimization precluded other + useful optimizations (such as merging color conversion with upsampling) + and it also interfered with desired capabilities such as quantizing to an + externally-supplied colormap. We have therefore abandoned that approach. + The present code works in the post-conversion color space, typically RGB. + + To improve the visual quality of the results, we actually work in scaled + RGB space, giving G distances more weight than R, and R in turn more than + B. To do everything in integer math, we must use integer scale factors. + The 2/3/1 scale factors used here correspond loosely to the relative + weights of the colors in the NTSC grayscale equation. + If you want to use this code to quantize a non-RGB color space, you'll + probably need to change these scale factors. } + +const + R_SCALE = 2; { scale R distances by this much } + G_SCALE = 3; { scale G distances by this much } + B_SCALE = 1; { and B by this much } + +{ Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined + in jmorecfg.h. As the code stands, it will do the right thing for R,G,B + and B,G,R orders. If you define some other weird order in jmorecfg.h, + you'll get compile errors until you extend this logic. In that case + you'll probably want to tweak the histogram sizes too. } + +{$ifdef RGB_RED_IS_0} +const + C0_SCALE = R_SCALE; + C1_SCALE = G_SCALE; + C2_SCALE = B_SCALE; +{$else} +const + C0_SCALE = B_SCALE; + C1_SCALE = G_SCALE; + C2_SCALE = R_SCALE; +{$endif} + + +{ First we have the histogram data structure and routines for creating it. + + The number of bits of precision can be adjusted by changing these symbols. + We recommend keeping 6 bits for G and 5 each for R and B. + If you have plenty of memory and cycles, 6 bits all around gives marginally + better results; if you are short of memory, 5 bits all around will save + some space but degrade the results. + To maintain a fully accurate histogram, we'd need to allocate a "long" + (preferably unsigned long) for each cell. In practice this is overkill; + we can get by with 16 bits per cell. Few of the cell counts will overflow, + and clamping those that do overflow to the maximum value will give close- + enough results. This reduces the recommended histogram size from 256Kb + to 128Kb, which is a useful savings on PC-class machines. + (In the second pass the histogram space is re-used for pixel mapping data; + in that capacity, each cell must be able to store zero to the number of + desired colors. 16 bits/cell is plenty for that too.) + Since the JPEG code is intended to run in small memory model on 80x86 + machines, we can't just allocate the histogram in one chunk. Instead + of a true 3-D array, we use a row of pointers to 2-D arrays. Each + pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and + each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that + on 80x86 machines, the pointer row is in near memory but the actual + arrays are in far memory (same arrangement as we use for image arrays). } + + +const + MAXNUMCOLORS = (MAXJSAMPLE+1); { maximum size of colormap } + +{ These will do the right thing for either R,G,B or B,G,R color order, + but you may not like the results for other color orders. } + +const + HIST_C0_BITS = 5; { bits of precision in R/B histogram } + HIST_C1_BITS = 6; { bits of precision in G histogram } + HIST_C2_BITS = 5; { bits of precision in B/R histogram } + +{ Number of elements along histogram axes. } +const + HIST_C0_ELEMS = (1 shl HIST_C0_BITS); + HIST_C1_ELEMS = (1 shl HIST_C1_BITS); + HIST_C2_ELEMS = (1 shl HIST_C2_BITS); + +{ These are the amounts to shift an input value to get a histogram index. } +const + C0_SHIFT = (BITS_IN_JSAMPLE-HIST_C0_BITS); + C1_SHIFT = (BITS_IN_JSAMPLE-HIST_C1_BITS); + C2_SHIFT = (BITS_IN_JSAMPLE-HIST_C2_BITS); + + +type { Nomssi } + RGBptr = ^RGBtype; + RGBtype = packed record + r,g,b : JSAMPLE; + end; +type + histcell = UINT16; { histogram cell; prefer an unsigned type } + +type + histptr = ^histcell {FAR}; { for pointers to histogram cells } + +type + hist1d = array[0..HIST_C2_ELEMS-1] of histcell; { typedefs for the array } + {hist1d_ptr = ^hist1d;} + hist1d_field = array[0..HIST_C1_ELEMS-1] of hist1d; + { type for the 2nd-level pointers } + hist2d = ^hist1d_field; + hist2d_field = array[0..HIST_C0_ELEMS-1] of hist2d; + hist3d = ^hist2d_field; { type for top-level pointer } + + +{ Declarations for Floyd-Steinberg dithering. + + Errors are accumulated into the array fserrors[], at a resolution of + 1/16th of a pixel count. The error at a given pixel is propagated + to its not-yet-processed neighbors using the standard F-S fractions, + ... (here) 7/16 + 3/16 5/16 1/16 + We work left-to-right on even rows, right-to-left on odd rows. + + We can get away with a single array (holding one row's worth of errors) + by using it to store the current row's errors at pixel columns not yet + processed, but the next row's errors at columns already processed. We + need only a few extra variables to hold the errors immediately around the + current column. (If we are lucky, those variables are in registers, but + even if not, they're probably cheaper to access than array elements are.) + + The fserrors[] array has (#columns + 2) entries; the extra entry at + each end saves us from special-casing the first and last pixels. + Each entry is three values long, one value for each color component. + + Note: on a wide image, we might not have enough room in a PC's near data + segment to hold the error array; so it is allocated with alloc_large. } + + +{$ifdef BITS_IN_JSAMPLE_IS_8} +type + FSERROR = INT16; { 16 bits should be enough } + LOCFSERROR = int; { use 'int' for calculation temps } +{$else} +type + FSERROR = INT32; { may need more than 16 bits } + LOCFSERROR = INT32; { be sure calculation temps are big enough } +{$endif} +type { Nomssi } + RGB_FSERROR_PTR = ^RGB_FSERROR; + RGB_FSERROR = packed record + r,g,b : FSERROR; + end; + LOCRGB_FSERROR = packed record + r,g,b : LOCFSERROR; + end; + +type + FSERROR_PTR = ^FSERROR; + jFSError = 0..(MaxInt div SIZEOF(RGB_FSERROR))-1; + FS_ERROR_FIELD = array[jFSError] of RGB_FSERROR; + FS_ERROR_FIELD_PTR = ^FS_ERROR_FIELD;{far} + { pointer to error array (in FAR storage!) } + +type + error_limit_array = array[-MAXJSAMPLE..MAXJSAMPLE] of int; + { table for clamping the applied error } + error_limit_ptr = ^error_limit_array; + +{ Private subobject } +type + my_cquantize_ptr = ^my_cquantizer; + my_cquantizer = record + pub : jpeg_color_quantizer; { public fields } + + { Space for the eventually created colormap is stashed here } + sv_colormap : JSAMPARRAY; { colormap allocated at init time } + desired : int; { desired # of colors = size of colormap } + + { Variables for accumulating image statistics } + histogram : hist3d; { pointer to the histogram } + + needs_zeroed : boolean; { TRUE if next pass must zero histogram } + + { Variables for Floyd-Steinberg dithering } + fserrors : FS_ERROR_FIELD_PTR; { accumulated errors } + on_odd_row : boolean; { flag to remember which row we are on } + error_limiter : error_limit_ptr; { table for clamping the applied error } + end; + + + +{ Prescan some rows of pixels. + In this module the prescan simply updates the histogram, which has been + initialized to zeroes by start_pass. + An output_buf parameter is required by the method signature, but no data + is actually output (in fact the buffer controller is probably passing a + NIL pointer). } + +{METHODDEF} +procedure prescan_quantize (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +var + cquantize : my_cquantize_ptr; + {register} ptr : RGBptr; + {register} histp : histptr; + {register} histogram : hist3d; + row : int; + col : JDIMENSION; + width : JDIMENSION; +begin + cquantize := my_cquantize_ptr(cinfo^.cquantize); + histogram := cquantize^.histogram; + width := cinfo^.output_width; + + for row := 0 to pred(num_rows) do + begin + ptr := RGBptr(input_buf^[row]); + for col := pred(width) downto 0 do + begin + { get pixel value and index into the histogram } + histp := @(histogram^[GETJSAMPLE(ptr^.r) shr C0_SHIFT]^ + [GETJSAMPLE(ptr^.g) shr C1_SHIFT] + [GETJSAMPLE(ptr^.b) shr C2_SHIFT]); + { increment, check for overflow and undo increment if so. } + Inc(histp^); + if (histp^ <= 0) then + Dec(histp^); + Inc(ptr); + end; + end; +end; + +{ Next we have the really interesting routines: selection of a colormap + given the completed histogram. + These routines work with a list of "boxes", each representing a rectangular + subset of the input color space (to histogram precision). } + +type + box = record + { The bounds of the box (inclusive); expressed as histogram indexes } + c0min, c0max : int; + c1min, c1max : int; + c2min, c2max : int; + { The volume (actually 2-norm) of the box } + volume : INT32; + { The number of nonzero histogram cells within this box } + colorcount : long; + end; + +type + jBoxList = 0..(MaxInt div SizeOf(box))-1; + box_field = array[jBoxlist] of box; + boxlistptr = ^box_field; + boxptr = ^box; + +{LOCAL} +function find_biggest_color_pop (boxlist : boxlistptr; numboxes : int) : boxptr; +{ Find the splittable box with the largest color population } +{ Returns NIL if no splittable boxes remain } +var + boxp : boxptr ; {register} + i : int; {register} + maxc : long; {register} + which : boxptr; +begin + which := NIL; + boxp := @(boxlist^[0]); + maxc := 0; + for i := 0 to pred(numboxes) do + begin + if (boxp^.colorcount > maxc) and (boxp^.volume > 0) then + begin + which := boxp; + maxc := boxp^.colorcount; + end; + Inc(boxp); + end; + find_biggest_color_pop := which; +end; + + +{LOCAL} +function find_biggest_volume (boxlist : boxlistptr; numboxes : int) : boxptr; +{ Find the splittable box with the largest (scaled) volume } +{ Returns NULL if no splittable boxes remain } +var + {register} boxp : boxptr; + {register} i : int; + {register} maxv : INT32; + which : boxptr; +begin + maxv := 0; + which := NIL; + boxp := @(boxlist^[0]); + for i := 0 to pred(numboxes) do + begin + if (boxp^.volume > maxv) then + begin + which := boxp; + maxv := boxp^.volume; + end; + Inc(boxp); + end; + find_biggest_volume := which; +end; + + +{LOCAL} +procedure update_box (cinfo : j_decompress_ptr; var boxp : box); +label + have_c0min, have_c0max, + have_c1min, have_c1max, + have_c2min, have_c2max; +{ Shrink the min/max bounds of a box to enclose only nonzero elements, } +{ and recompute its volume and population } +var + cquantize : my_cquantize_ptr; + histogram : hist3d; + histp : histptr; + c0,c1,c2 : int; + c0min,c0max,c1min,c1max,c2min,c2max : int; + dist0,dist1,dist2 : INT32; + ccount : long; +begin + cquantize := my_cquantize_ptr(cinfo^.cquantize); + histogram := cquantize^.histogram; + + c0min := boxp.c0min; c0max := boxp.c0max; + c1min := boxp.c1min; c1max := boxp.c1max; + c2min := boxp.c2min; c2max := boxp.c2max; + + if (c0max > c0min) then + for c0 := c0min to c0max do + for c1 := c1min to c1max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + if (histp^ <> 0) then + begin + c0min := c0; + boxp.c0min := c0min; + goto have_c0min; + end; + Inc(histp); + end; + end; + have_c0min: + if (c0max > c0min) then + for c0 := c0max downto c0min do + for c1 := c1min to c1max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + if ( histp^ <> 0) then + begin + c0max := c0; + boxp.c0max := c0; + goto have_c0max; + end; + Inc(histp); + end; + end; + have_c0max: + if (c1max > c1min) then + for c1 := c1min to c1max do + for c0 := c0min to c0max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + if (histp^ <> 0) then + begin + c1min := c1; + boxp.c1min := c1; + goto have_c1min; + end; + Inc(histp); + end; + end; + have_c1min: + if (c1max > c1min) then + for c1 := c1max downto c1min do + for c0 := c0min to c0max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + if (histp^ <> 0) then + begin + c1max := c1; + boxp.c1max := c1; + goto have_c1max; + end; + Inc(histp); + end; + end; + have_c1max: + if (c2max > c2min) then + for c2 := c2min to c2max do + for c0 := c0min to c0max do + begin + histp := @(histogram^[c0]^[c1min][c2]); + for c1 := c1min to c1max do + begin + if (histp^ <> 0) then + begin + c2min := c2; + boxp.c2min := c2min; + goto have_c2min; + end; + Inc(histp, HIST_C2_ELEMS); + end; + end; + have_c2min: + if (c2max > c2min) then + for c2 := c2max downto c2min do + for c0 := c0min to c0max do + begin + histp := @(histogram^[c0]^[c1min][c2]); + for c1 := c1min to c1max do + begin + if (histp^ <> 0) then + begin + c2max := c2; + boxp.c2max := c2max; + goto have_c2max; + end; + Inc(histp, HIST_C2_ELEMS); + end; + end; + have_c2max: + + { Update box volume. + We use 2-norm rather than real volume here; this biases the method + against making long narrow boxes, and it has the side benefit that + a box is splittable iff norm > 0. + Since the differences are expressed in histogram-cell units, + we have to shift back to JSAMPLE units to get consistent distances; + after which, we scale according to the selected distance scale factors.} + + dist0 := ((c0max - c0min) shl C0_SHIFT) * C0_SCALE; + dist1 := ((c1max - c1min) shl C1_SHIFT) * C1_SCALE; + dist2 := ((c2max - c2min) shl C2_SHIFT) * C2_SCALE; + boxp.volume := dist0*dist0 + dist1*dist1 + dist2*dist2; + + { Now scan remaining volume of box and compute population } + ccount := 0; + for c0 := c0min to c0max do + for c1 := c1min to c1max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + if (histp^ <> 0) then + Inc(ccount); + Inc(histp); + end; + end; + boxp.colorcount := ccount; +end; + + +{LOCAL} +function median_cut (cinfo : j_decompress_ptr; boxlist : boxlistptr; + numboxes : int; desired_colors : int) : int; +{ Repeatedly select and split the largest box until we have enough boxes } +var + n,lb : int; + c0,c1,c2,cmax : int; + {register} b1,b2 : boxptr; +begin + while (numboxes < desired_colors) do + begin + { Select box to split. + Current algorithm: by population for first half, then by volume. } + + if (numboxes*2 <= desired_colors) then + b1 := find_biggest_color_pop(boxlist, numboxes) + else + b1 := find_biggest_volume(boxlist, numboxes); + + if (b1 = NIL) then { no splittable boxes left! } + break; + b2 := @(boxlist^[numboxes]); { where new box will go } + { Copy the color bounds to the new box. } + b2^.c0max := b1^.c0max; b2^.c1max := b1^.c1max; b2^.c2max := b1^.c2max; + b2^.c0min := b1^.c0min; b2^.c1min := b1^.c1min; b2^.c2min := b1^.c2min; + { Choose which axis to split the box on. + Current algorithm: longest scaled axis. + See notes in update_box about scaling distances. } + + c0 := ((b1^.c0max - b1^.c0min) shl C0_SHIFT) * C0_SCALE; + c1 := ((b1^.c1max - b1^.c1min) shl C1_SHIFT) * C1_SCALE; + c2 := ((b1^.c2max - b1^.c2min) shl C2_SHIFT) * C2_SCALE; + { We want to break any ties in favor of green, then red, blue last. + This code does the right thing for R,G,B or B,G,R color orders only. } + +{$ifdef RGB_RED_IS_0} + cmax := c1; n := 1; + if (c0 > cmax) then + begin + cmax := c0; + n := 0; + end; + if (c2 > cmax) then + n := 2; +{$else} + cmax := c1; + n := 1; + if (c2 > cmax) then + begin + cmax := c2; + n := 2; + end; + if (c0 > cmax) then + n := 0; +{$endif} + { Choose split point along selected axis, and update box bounds. + Current algorithm: split at halfway point. + (Since the box has been shrunk to minimum volume, + any split will produce two nonempty subboxes.) + Note that lb value is max for lower box, so must be < old max. } + + case n of + 0:begin + lb := (b1^.c0max + b1^.c0min) div 2; + b1^.c0max := lb; + b2^.c0min := lb+1; + end; + 1:begin + lb := (b1^.c1max + b1^.c1min) div 2; + b1^.c1max := lb; + b2^.c1min := lb+1; + end; + 2:begin + lb := (b1^.c2max + b1^.c2min) div 2; + b1^.c2max := lb; + b2^.c2min := lb+1; + end; + end; + { Update stats for boxes } + update_box(cinfo, b1^); + update_box(cinfo, b2^); + Inc(numboxes); + end; + median_cut := numboxes; +end; + + +{LOCAL} +procedure compute_color (cinfo : j_decompress_ptr; + const boxp : box; icolor : int); +{ Compute representative color for a box, put it in colormap[icolor] } +var + { Current algorithm: mean weighted by pixels (not colors) } + { Note it is important to get the rounding correct! } + cquantize : my_cquantize_ptr; + histogram : hist3d; + histp : histptr; + c0,c1,c2 : int; + c0min,c0max,c1min,c1max,c2min,c2max : int; + count : long; + total : long; + c0total : long; + c1total : long; + c2total : long; +begin + cquantize := my_cquantize_ptr(cinfo^.cquantize); + histogram := cquantize^.histogram; + total := 0; + c0total := 0; + c1total := 0; + c2total := 0; + + c0min := boxp.c0min; c0max := boxp.c0max; + c1min := boxp.c1min; c1max := boxp.c1max; + c2min := boxp.c2min; c2max := boxp.c2max; + + for c0 := c0min to c0max do + for c1 := c1min to c1max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + count := histp^; + Inc(histp); + if (count <> 0) then + begin + Inc(total, count); + Inc(c0total, ((c0 shl C0_SHIFT) + ((1 shl C0_SHIFT) shr 1)) * count); + Inc(c1total, ((c1 shl C1_SHIFT) + ((1 shl C1_SHIFT) shr 1)) * count); + Inc(c2total, ((c2 shl C2_SHIFT) + ((1 shl C2_SHIFT) shr 1)) * count); + end; + end; + end; + + cinfo^.colormap^[0]^[icolor] := JSAMPLE ((c0total + (total shr 1)) div total); + cinfo^.colormap^[1]^[icolor] := JSAMPLE ((c1total + (total shr 1)) div total); + cinfo^.colormap^[2]^[icolor] := JSAMPLE ((c2total + (total shr 1)) div total); +end; + + +{LOCAL} +procedure select_colors (cinfo : j_decompress_ptr; desired_colors : int); +{ Master routine for color selection } +var + boxlist : boxlistptr; + numboxes : int; + i : int; +begin + { Allocate workspace for box list } + boxlist := boxlistptr(cinfo^.mem^.alloc_small( + j_common_ptr(cinfo), JPOOL_IMAGE, desired_colors * SIZEOF(box))); + { Initialize one box containing whole space } + numboxes := 1; + boxlist^[0].c0min := 0; + boxlist^[0].c0max := MAXJSAMPLE shr C0_SHIFT; + boxlist^[0].c1min := 0; + boxlist^[0].c1max := MAXJSAMPLE shr C1_SHIFT; + boxlist^[0].c2min := 0; + boxlist^[0].c2max := MAXJSAMPLE shr C2_SHIFT; + { Shrink it to actually-used volume and set its statistics } + update_box(cinfo, boxlist^[0]); + { Perform median-cut to produce final box list } + numboxes := median_cut(cinfo, boxlist, numboxes, desired_colors); + { Compute the representative color for each box, fill colormap } + for i := 0 to pred(numboxes) do + compute_color(cinfo, boxlist^[i], i); + cinfo^.actual_number_of_colors := numboxes; + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_QUANT_SELECTED, numboxes); + {$ENDIF} +end; + + +{ These routines are concerned with the time-critical task of mapping input + colors to the nearest color in the selected colormap. + + We re-use the histogram space as an "inverse color map", essentially a + cache for the results of nearest-color searches. All colors within a + histogram cell will be mapped to the same colormap entry, namely the one + closest to the cell's center. This may not be quite the closest entry to + the actual input color, but it's almost as good. A zero in the cache + indicates we haven't found the nearest color for that cell yet; the array + is cleared to zeroes before starting the mapping pass. When we find the + nearest color for a cell, its colormap index plus one is recorded in the + cache for future use. The pass2 scanning routines call fill_inverse_cmap + when they need to use an unfilled entry in the cache. + + Our method of efficiently finding nearest colors is based on the "locally + sorted search" idea described by Heckbert and on the incremental distance + calculation described by Spencer W. Thomas in chapter III.1 of Graphics + Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that + the distances from a given colormap entry to each cell of the histogram can + be computed quickly using an incremental method: the differences between + distances to adjacent cells themselves differ by a constant. This allows a + fairly fast implementation of the "brute force" approach of computing the + distance from every colormap entry to every histogram cell. Unfortunately, + it needs a work array to hold the best-distance-so-far for each histogram + cell (because the inner loop has to be over cells, not colormap entries). + The work array elements have to be INT32s, so the work array would need + 256Kb at our recommended precision. This is not feasible in DOS machines. + + To get around these problems, we apply Thomas' method to compute the + nearest colors for only the cells within a small subbox of the histogram. + The work array need be only as big as the subbox, so the memory usage + problem is solved. Furthermore, we need not fill subboxes that are never + referenced in pass2; many images use only part of the color gamut, so a + fair amount of work is saved. An additional advantage of this + approach is that we can apply Heckbert's locality criterion to quickly + eliminate colormap entries that are far away from the subbox; typically + three-fourths of the colormap entries are rejected by Heckbert's criterion, + and we need not compute their distances to individual cells in the subbox. + The speed of this approach is heavily influenced by the subbox size: too + small means too much overhead, too big loses because Heckbert's criterion + can't eliminate as many colormap entries. Empirically the best subbox + size seems to be about 1/512th of the histogram (1/8th in each direction). + + Thomas' article also describes a refined method which is asymptotically + faster than the brute-force method, but it is also far more complex and + cannot efficiently be applied to small subboxes. It is therefore not + useful for programs intended to be portable to DOS machines. On machines + with plenty of memory, filling the whole histogram in one shot with Thomas' + refined method might be faster than the present code --- but then again, + it might not be any faster, and it's certainly more complicated. } + + + +{ log2(histogram cells in update box) for each axis; this can be adjusted } +const + BOX_C0_LOG = (HIST_C0_BITS-3); + BOX_C1_LOG = (HIST_C1_BITS-3); + BOX_C2_LOG = (HIST_C2_BITS-3); + + BOX_C0_ELEMS = (1 shl BOX_C0_LOG); { # of hist cells in update box } + BOX_C1_ELEMS = (1 shl BOX_C1_LOG); + BOX_C2_ELEMS = (1 shl BOX_C2_LOG); + + BOX_C0_SHIFT = (C0_SHIFT + BOX_C0_LOG); + BOX_C1_SHIFT = (C1_SHIFT + BOX_C1_LOG); + BOX_C2_SHIFT = (C2_SHIFT + BOX_C2_LOG); + + +{ The next three routines implement inverse colormap filling. They could + all be folded into one big routine, but splitting them up this way saves + some stack space (the mindist[] and bestdist[] arrays need not coexist) + and may allow some compilers to produce better code by registerizing more + inner-loop variables. } + +{LOCAL} +function find_nearby_colors (cinfo : j_decompress_ptr; + minc0 : int; minc1 : int; minc2 : int; + var colorlist : array of JSAMPLE) : int; +{ Locate the colormap entries close enough to an update box to be candidates + for the nearest entry to some cell(s) in the update box. The update box + is specified by the center coordinates of its first cell. The number of + candidate colormap entries is returned, and their colormap indexes are + placed in colorlist[]. + This routine uses Heckbert's "locally sorted search" criterion to select + the colors that need further consideration. } + +var + numcolors : int; + maxc0, maxc1, maxc2 : int; + centerc0, centerc1, centerc2 : int; + i, x, ncolors : int; + minmaxdist, min_dist, max_dist, tdist : INT32; + mindist : array[0..MAXNUMCOLORS-1] of INT32; + { min distance to colormap entry i } +begin + numcolors := cinfo^.actual_number_of_colors; + + { Compute true coordinates of update box's upper corner and center. + Actually we compute the coordinates of the center of the upper-corner + histogram cell, which are the upper bounds of the volume we care about. + Note that since ">>" rounds down, the "center" values may be closer to + min than to max; hence comparisons to them must be "<=", not "<". } + + maxc0 := minc0 + ((1 shl BOX_C0_SHIFT) - (1 shl C0_SHIFT)); + centerc0 := (minc0 + maxc0) shr 1; + maxc1 := minc1 + ((1 shl BOX_C1_SHIFT) - (1 shl C1_SHIFT)); + centerc1 := (minc1 + maxc1) shr 1; + maxc2 := minc2 + ((1 shl BOX_C2_SHIFT) - (1 shl C2_SHIFT)); + centerc2 := (minc2 + maxc2) shr 1; + + { For each color in colormap, find: + 1. its minimum squared-distance to any point in the update box + (zero if color is within update box); + 2. its maximum squared-distance to any point in the update box. + Both of these can be found by considering only the corners of the box. + We save the minimum distance for each color in mindist[]; + only the smallest maximum distance is of interest. } + + minmaxdist := long($7FFFFFFF); + + for i := 0 to pred(numcolors) do + begin + { We compute the squared-c0-distance term, then add in the other two. } + x := GETJSAMPLE(cinfo^.colormap^[0]^[i]); + if (x < minc0) then + begin + tdist := (x - minc0) * C0_SCALE; + min_dist := tdist*tdist; + tdist := (x - maxc0) * C0_SCALE; + max_dist := tdist*tdist; + end + else + if (x > maxc0) then + begin + tdist := (x - maxc0) * C0_SCALE; + min_dist := tdist*tdist; + tdist := (x - minc0) * C0_SCALE; + max_dist := tdist*tdist; + end + else + begin + { within cell range so no contribution to min_dist } + min_dist := 0; + if (x <= centerc0) then + begin + tdist := (x - maxc0) * C0_SCALE; + max_dist := tdist*tdist; + end + else + begin + tdist := (x - minc0) * C0_SCALE; + max_dist := tdist*tdist; + end; + end; + + x := GETJSAMPLE(cinfo^.colormap^[1]^[i]); + if (x < minc1) then + begin + tdist := (x - minc1) * C1_SCALE; + Inc(min_dist, tdist*tdist); + tdist := (x - maxc1) * C1_SCALE; + Inc(max_dist, tdist*tdist); + end + else + if (x > maxc1) then + begin + tdist := (x - maxc1) * C1_SCALE; + Inc(min_dist, tdist*tdist); + tdist := (x - minc1) * C1_SCALE; + Inc(max_dist, tdist*tdist); + end + else + begin + { within cell range so no contribution to min_dist } + if (x <= centerc1) then + begin + tdist := (x - maxc1) * C1_SCALE; + Inc(max_dist, tdist*tdist); + end + else + begin + tdist := (x - minc1) * C1_SCALE; + Inc(max_dist, tdist*tdist); + end + end; + + x := GETJSAMPLE(cinfo^.colormap^[2]^[i]); + if (x < minc2) then + begin + tdist := (x - minc2) * C2_SCALE; + Inc(min_dist, tdist*tdist); + tdist := (x - maxc2) * C2_SCALE; + Inc(max_dist, tdist*tdist); + end + else + if (x > maxc2) then + begin + tdist := (x - maxc2) * C2_SCALE; + Inc(min_dist, tdist*tdist); + tdist := (x - minc2) * C2_SCALE; + Inc(max_dist, tdist*tdist); + end + else + begin + { within cell range so no contribution to min_dist } + if (x <= centerc2) then + begin + tdist := (x - maxc2) * C2_SCALE; + Inc(max_dist, tdist*tdist); + end + else + begin + tdist := (x - minc2) * C2_SCALE; + Inc(max_dist, tdist*tdist); + end; + end; + + mindist[i] := min_dist; { save away the results } + if (max_dist < minmaxdist) then + minmaxdist := max_dist; + end; + + { Now we know that no cell in the update box is more than minmaxdist + away from some colormap entry. Therefore, only colors that are + within minmaxdist of some part of the box need be considered. } + + ncolors := 0; + for i := 0 to pred(numcolors) do + begin +{$warnings off} + if (mindist[i] <= minmaxdist) then + begin + colorlist[ncolors] := JSAMPLE(i); + Inc(ncolors); + end; + end; + find_nearby_colors := ncolors; +end; +{$warnings on} + +{LOCAL} +procedure find_best_colors (cinfo : j_decompress_ptr; + minc0 : int; minc1 : int; minc2 : int; + numcolors : int; + var colorlist : array of JSAMPLE; + var bestcolor : array of JSAMPLE); +{ Find the closest colormap entry for each cell in the update box, + given the list of candidate colors prepared by find_nearby_colors. + Return the indexes of the closest entries in the bestcolor[] array. + This routine uses Thomas' incremental distance calculation method to + find the distance from a colormap entry to successive cells in the box. } +const + { Nominal steps between cell centers ("x" in Thomas article) } + STEP_C0 = ((1 shl C0_SHIFT) * C0_SCALE); + STEP_C1 = ((1 shl C1_SHIFT) * C1_SCALE); + STEP_C2 = ((1 shl C2_SHIFT) * C2_SCALE); +var + ic0, ic1, ic2 : int; + i, icolor : int; + {register} bptr : INT32PTR; { pointer into bestdist[] array } + cptr : JSAMPLE_PTR; { pointer into bestcolor[] array } + dist0, dist1 : INT32; { initial distance values } + {register} dist2 : INT32; { current distance in inner loop } + xx0, xx1 : INT32; { distance increments } + {register} xx2 : INT32; + inc0, inc1, inc2 : INT32; { initial values for increments } + { This array holds the distance to the nearest-so-far color for each cell } + bestdist : array[0..BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS-1] of INT32; +begin + { Initialize best-distance for each cell of the update box } + for i := BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1 downto 0 do + bestdist[i] := $7FFFFFFF; + + { For each color selected by find_nearby_colors, + compute its distance to the center of each cell in the box. + If that's less than best-so-far, update best distance and color number. } + + + + for i := 0 to pred(numcolors) do + begin + icolor := GETJSAMPLE(colorlist[i]); + { Compute (square of) distance from minc0/c1/c2 to this color } + inc0 := (minc0 - GETJSAMPLE(cinfo^.colormap^[0]^[icolor])) * C0_SCALE; + dist0 := inc0*inc0; + inc1 := (minc1 - GETJSAMPLE(cinfo^.colormap^[1]^[icolor])) * C1_SCALE; + Inc(dist0, inc1*inc1); + inc2 := (minc2 - GETJSAMPLE(cinfo^.colormap^[2]^[icolor])) * C2_SCALE; + Inc(dist0, inc2*inc2); + { Form the initial difference increments } + inc0 := inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; + inc1 := inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; + inc2 := inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; + { Now loop over all cells in box, updating distance per Thomas method } + bptr := @bestdist[0]; + cptr := @bestcolor[0]; + xx0 := inc0; + for ic0 := BOX_C0_ELEMS-1 downto 0 do + begin + dist1 := dist0; + xx1 := inc1; + for ic1 := BOX_C1_ELEMS-1 downto 0 do + begin + dist2 := dist1; + xx2 := inc2; + for ic2 := BOX_C2_ELEMS-1 downto 0 do + begin + if (dist2 < bptr^) then + begin + bptr^ := dist2; + cptr^ := JSAMPLE (icolor); + end; + Inc(dist2, xx2); + Inc(xx2, 2 * STEP_C2 * STEP_C2); + Inc(bptr); + Inc(cptr); + end; + Inc(dist1, xx1); + Inc(xx1, 2 * STEP_C1 * STEP_C1); + end; + Inc(dist0, xx0); + Inc(xx0, 2 * STEP_C0 * STEP_C0); + end; + end; +end; + + +{LOCAL} +procedure fill_inverse_cmap (cinfo : j_decompress_ptr; + c0 : int; c1 : int; c2 : int); +{ Fill the inverse-colormap entries in the update box that contains } +{ histogram cell c0/c1/c2. (Only that one cell MUST be filled, but } +{ we can fill as many others as we wish.) } +var + cquantize : my_cquantize_ptr; + histogram : hist3d; + minc0, minc1, minc2 : int; { lower left corner of update box } + ic0, ic1, ic2 : int; + {register} cptr : JSAMPLE_PTR; { pointer into bestcolor[] array } + {register} cachep : histptr; { pointer into main cache array } + { This array lists the candidate colormap indexes. } + colorlist : array[0..MAXNUMCOLORS-1] of JSAMPLE; + numcolors : int; { number of candidate colors } + { This array holds the actually closest colormap index for each cell. } + bestcolor : array[0..BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS-1] of JSAMPLE; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + histogram := cquantize^.histogram; + + { Convert cell coordinates to update box ID } + c0 := c0 shr BOX_C0_LOG; + c1 := c1 shr BOX_C1_LOG; + c2 := c2 shr BOX_C2_LOG; + + { Compute true coordinates of update box's origin corner. + Actually we compute the coordinates of the center of the corner + histogram cell, which are the lower bounds of the volume we care about.} + + minc0 := (c0 shl BOX_C0_SHIFT) + ((1 shl C0_SHIFT) shr 1); + minc1 := (c1 shl BOX_C1_SHIFT) + ((1 shl C1_SHIFT) shr 1); + minc2 := (c2 shl BOX_C2_SHIFT) + ((1 shl C2_SHIFT) shr 1); + + { Determine which colormap entries are close enough to be candidates + for the nearest entry to some cell in the update box. } + + numcolors := find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist); + + { Determine the actually nearest colors. } + find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, + bestcolor); + + { Save the best color numbers (plus 1) in the main cache array } + c0 := c0 shl BOX_C0_LOG; { convert ID back to base cell indexes } + c1 := c1 shl BOX_C1_LOG; + c2 := c2 shl BOX_C2_LOG; + cptr := @(bestcolor[0]); + for ic0 := 0 to pred(BOX_C0_ELEMS) do + for ic1 := 0 to pred(BOX_C1_ELEMS) do + begin + cachep := @(histogram^[c0+ic0]^[c1+ic1][c2]); + for ic2 := 0 to pred(BOX_C2_ELEMS) do + begin + cachep^ := histcell (GETJSAMPLE(cptr^) + 1); + Inc(cachep); + Inc(cptr); + end; + end; +end; + + +{ Map some rows of pixels to the output colormapped representation. } + +{METHODDEF} +procedure pass2_no_dither (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ This version performs no dithering } +var + cquantize : my_cquantize_ptr; + histogram : hist3d; + {register} inptr : RGBptr; + outptr : JSAMPLE_PTR; + {register} cachep : histptr; + {register} c0, c1, c2 : int; + row : int; + col : JDIMENSION; + width : JDIMENSION; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + histogram := cquantize^.histogram; + width := cinfo^.output_width; + + for row := 0 to pred(num_rows) do + begin + inptr := RGBptr(input_buf^[row]); + outptr := JSAMPLE_PTR(output_buf^[row]); + for col := pred(width) downto 0 do + begin + { get pixel value and index into the cache } + c0 := GETJSAMPLE(inptr^.r) shr C0_SHIFT; + c1 := GETJSAMPLE(inptr^.g) shr C1_SHIFT; + c2 := GETJSAMPLE(inptr^.b) shr C2_SHIFT; + Inc(inptr); + cachep := @(histogram^[c0]^[c1][c2]); + { If we have not seen this color before, find nearest colormap entry } + { and update the cache } + if (cachep^ = 0) then + fill_inverse_cmap(cinfo, c0,c1,c2); + { Now emit the colormap index for this cell } + outptr^ := JSAMPLE (cachep^ - 1); + Inc(outptr); + end; + end; +end; + + +{METHODDEF} +procedure pass2_fs_dither (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ This version performs Floyd-Steinberg dithering } +var + cquantize : my_cquantize_ptr; + histogram : hist3d; + {register} cur : LOCRGB_FSERROR; { current error or pixel value } + belowerr : LOCRGB_FSERROR; { error for pixel below cur } + bpreverr : LOCRGB_FSERROR; { error for below/prev col } + prev_errorptr, + {register} errorptr : RGB_FSERROR_PTR; { => fserrors[] at column before current } + inptr : RGBptr; { => current input pixel } + outptr : JSAMPLE_PTR; { => current output pixel } + cachep : histptr; + dir : int; { +1 or -1 depending on direction } + row : int; + col : JDIMENSION; + width : JDIMENSION; + range_limit : range_limit_table_ptr; + error_limit : error_limit_ptr; + colormap0 : JSAMPROW; + colormap1 : JSAMPROW; + colormap2 : JSAMPROW; + {register} pixcode : int; + {register} bnexterr, delta : LOCFSERROR; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + histogram := cquantize^.histogram; + width := cinfo^.output_width; + range_limit := cinfo^.sample_range_limit; + error_limit := cquantize^.error_limiter; + colormap0 := cinfo^.colormap^[0]; + colormap1 := cinfo^.colormap^[1]; + colormap2 := cinfo^.colormap^[2]; + + for row := 0 to pred(num_rows) do + begin + inptr := RGBptr(input_buf^[row]); + outptr := JSAMPLE_PTR(output_buf^[row]); + errorptr := RGB_FSERROR_PTR(cquantize^.fserrors); { => entry before first real column } + if (cquantize^.on_odd_row) then + begin + { work right to left in this row } + Inc(inptr, (width-1)); { so point to rightmost pixel } + Inc(outptr, width-1); + dir := -1; + Inc(errorptr, (width+1)); { => entry after last column } + cquantize^.on_odd_row := FALSE; { flip for next time } + end + else + begin + { work left to right in this row } + dir := 1; + cquantize^.on_odd_row := TRUE; { flip for next time } + end; + + { Preset error values: no error propagated to first pixel from left } + cur.r := 0; + cur.g := 0; + cur.b := 0; + { and no error propagated to row below yet } + belowerr.r := 0; + belowerr.g := 0; + belowerr.b := 0; + bpreverr.r := 0; + bpreverr.g := 0; + bpreverr.b := 0; + + for col := pred(width) downto 0 do + begin + prev_errorptr := errorptr; + Inc(errorptr, dir); { advance errorptr to current column } + + { curN holds the error propagated from the previous pixel on the + current line. Add the error propagated from the previous line + to form the complete error correction term for this pixel, and + round the error term (which is expressed * 16) to an integer. + RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + for either sign of the error value. + Note: prev_errorptr points to *previous* column's array entry. } + + { Nomssi Note: Borland Pascal SHR is unsigned } + cur.r := (cur.r + errorptr^.r + 8) div 16; + cur.g := (cur.g + errorptr^.g + 8) div 16; + cur.b := (cur.b + errorptr^.b + 8) div 16; + { Limit the error using transfer function set by init_error_limit. + See comments with init_error_limit for rationale. } + + cur.r := error_limit^[cur.r]; + cur.g := error_limit^[cur.g]; + cur.b := error_limit^[cur.b]; + { Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + The maximum error is +- MAXJSAMPLE (or less with error limiting); + this sets the required size of the range_limit array. } + + Inc(cur.r, GETJSAMPLE(inptr^.r)); + Inc(cur.g, GETJSAMPLE(inptr^.g)); + Inc(cur.b, GETJSAMPLE(inptr^.b)); + + cur.r := GETJSAMPLE(range_limit^[cur.r]); + cur.g := GETJSAMPLE(range_limit^[cur.g]); + cur.b := GETJSAMPLE(range_limit^[cur.b]); + { Index into the cache with adjusted pixel value } + cachep := @(histogram^[cur.r shr C0_SHIFT]^ + [cur.g shr C1_SHIFT][cur.b shr C2_SHIFT]); + { If we have not seen this color before, find nearest colormap } + { entry and update the cache } + if (cachep^ = 0) then + fill_inverse_cmap(cinfo, cur.r shr C0_SHIFT, + cur.g shr C1_SHIFT, + cur.b shr C2_SHIFT); + { Now emit the colormap index for this cell } + + pixcode := cachep^ - 1; + outptr^ := JSAMPLE (pixcode); + + { Compute representation error for this pixel } + Dec(cur.r, GETJSAMPLE(colormap0^[pixcode])); + Dec(cur.g, GETJSAMPLE(colormap1^[pixcode])); + Dec(cur.b, GETJSAMPLE(colormap2^[pixcode])); + + { Compute error fractions to be propagated to adjacent pixels. + Add these into the running sums, and simultaneously shift the + next-line error sums left by 1 column. } + + bnexterr := cur.r; { Process component 0 } + delta := cur.r * 2; + Inc(cur.r, delta); { form error * 3 } + prev_errorptr^.r := FSERROR (bpreverr.r + cur.r); + Inc(cur.r, delta); { form error * 5 } + bpreverr.r := belowerr.r + cur.r; + belowerr.r := bnexterr; + Inc(cur.r, delta); { form error * 7 } + bnexterr := cur.g; { Process component 1 } + delta := cur.g * 2; + Inc(cur.g, delta); { form error * 3 } + prev_errorptr^.g := FSERROR (bpreverr.g + cur.g); + Inc(cur.g, delta); { form error * 5 } + bpreverr.g := belowerr.g + cur.g; + belowerr.g := bnexterr; + Inc(cur.g, delta); { form error * 7 } + bnexterr := cur.b; { Process component 2 } + delta := cur.b * 2; + Inc(cur.b, delta); { form error * 3 } + prev_errorptr^.b := FSERROR (bpreverr.b + cur.b); + Inc(cur.b, delta); { form error * 5 } + bpreverr.b := belowerr.b + cur.b; + belowerr.b := bnexterr; + Inc(cur.b, delta); { form error * 7 } + + { At this point curN contains the 7/16 error value to be propagated + to the next pixel on the current line, and all the errors for the + next line have been shifted over. We are therefore ready to move on.} + + Inc(inptr, dir); { Advance pixel pointers to next column } + Inc(outptr, dir); + end; + { Post-loop cleanup: we must unload the final error values into the + final fserrors[] entry. Note we need not unload belowerrN because + it is for the dummy column before or after the actual array. } + + errorptr^.r := FSERROR (bpreverr.r); { unload prev errs into array } + errorptr^.g := FSERROR (bpreverr.g); + errorptr^.b := FSERROR (bpreverr.b); + end; +end; + + +{ Initialize the error-limiting transfer function (lookup table). + The raw F-S error computation can potentially compute error values of up to + +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be + much less, otherwise obviously wrong pixels will be created. (Typical + effects include weird fringes at color-area boundaries, isolated bright + pixels in a dark area, etc.) The standard advice for avoiding this problem + is to ensure that the "corners" of the color cube are allocated as output + colors; then repeated errors in the same direction cannot cause cascading + error buildup. However, that only prevents the error from getting + completely out of hand; Aaron Giles reports that error limiting improves + the results even with corner colors allocated. + A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty + well, but the smoother transfer function used below is even better. Thanks + to Aaron Giles for this idea. } + +{LOCAL} +procedure init_error_limit (cinfo : j_decompress_ptr); +const + STEPSIZE = ((MAXJSAMPLE+1) div 16); +{ Allocate and fill in the error_limiter table } +var + cquantize : my_cquantize_ptr; + table : error_limit_ptr; + inp, out : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + table := error_limit_ptr (cinfo^.mem^.alloc_small + (j_common_ptr (cinfo), JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int))); + { not needed: Inc(table, MAXJSAMPLE); + so can index -MAXJSAMPLE .. +MAXJSAMPLE } + cquantize^.error_limiter := table; + { Map errors 1:1 up to +- MAXJSAMPLE/16 } + out := 0; + for inp := 0 to pred(STEPSIZE) do + begin + table^[inp] := out; + table^[-inp] := -out; + Inc(out); + end; + { Map errors 1:2 up to +- 3*MAXJSAMPLE/16 } + inp := STEPSIZE; { Nomssi: avoid problems with Delphi2 optimizer } + while (inp < STEPSIZE*3) do + begin + table^[inp] := out; + table^[-inp] := -out; + Inc(inp); + if Odd(inp) then + Inc(out); + end; + { Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) } + inp := STEPSIZE*3; { Nomssi: avoid problems with Delphi 2 optimizer } + while inp <= MAXJSAMPLE do + begin + table^[inp] := out; + table^[-inp] := -out; + Inc(inp); + end; +end; + +{ Finish up at the end of each pass. } + +{METHODDEF} +procedure finish_pass1 (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + + { Select the representative colors and fill in cinfo^.colormap } + cinfo^.colormap := cquantize^.sv_colormap; + select_colors(cinfo, cquantize^.desired); + { Force next pass to zero the color index table } + cquantize^.needs_zeroed := TRUE; +end; + + +{METHODDEF} +procedure finish_pass2 (cinfo : j_decompress_ptr); +begin + { no work } +end; + + +{ Initialize for each processing pass. } + +{METHODDEF} +procedure start_pass_2_quant (cinfo : j_decompress_ptr; + is_pre_scan : boolean); +var + cquantize : my_cquantize_ptr; + histogram : hist3d; + i : int; +var + arraysize : size_t; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + histogram := cquantize^.histogram; + { Only F-S dithering or no dithering is supported. } + { If user asks for ordered dither, give him F-S. } + if (cinfo^.dither_mode <> JDITHER_NONE) then + cinfo^.dither_mode := JDITHER_FS; + + if (is_pre_scan) then + begin + { Set up method pointers } + cquantize^.pub.color_quantize := prescan_quantize; + cquantize^.pub.finish_pass := finish_pass1; + cquantize^.needs_zeroed := TRUE; { Always zero histogram } + end + else + begin + { Set up method pointers } + if (cinfo^.dither_mode = JDITHER_FS) then + cquantize^.pub.color_quantize := pass2_fs_dither + else + cquantize^.pub.color_quantize := pass2_no_dither; + cquantize^.pub.finish_pass := finish_pass2; + + { Make sure color count is acceptable } + i := cinfo^.actual_number_of_colors; + if (i < 1) then + ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_FEW_COLORS, 1); + if (i > MAXNUMCOLORS) then + ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + + if (cinfo^.dither_mode = JDITHER_FS) then + begin + arraysize := size_t ((cinfo^.output_width + 2) * + (3 * SIZEOF(FSERROR))); + { Allocate Floyd-Steinberg workspace if we didn't already. } + if (cquantize^.fserrors = NIL) then + cquantize^.fserrors := FS_ERROR_FIELD_PTR (cinfo^.mem^.alloc_large + (j_common_ptr(cinfo), JPOOL_IMAGE, arraysize)); + { Initialize the propagated errors to zero. } + jzero_far(cquantize^.fserrors, arraysize); + { Make the error-limit table if we didn't already. } + if (cquantize^.error_limiter = NIL) then + init_error_limit(cinfo); + cquantize^.on_odd_row := FALSE; + end; + + end; + { Zero the histogram or inverse color map, if necessary } + if (cquantize^.needs_zeroed) then + begin + for i := 0 to pred(HIST_C0_ELEMS) do + begin + jzero_far( histogram^[i], + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); + end; + cquantize^.needs_zeroed := FALSE; + end; +end; + + +{ Switch to a new external colormap between output passes. } + +{METHODDEF} +procedure new_color_map_2_quant (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + + { Reset the inverse color map } + cquantize^.needs_zeroed := TRUE; +end; + + +{ Module initialization routine for 2-pass color quantization. } + + +{GLOBAL} +procedure jinit_2pass_quantizer (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; + i : int; +var + desired : int; +begin + cquantize := my_cquantize_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_cquantizer))); + cinfo^.cquantize := jpeg_color_quantizer_ptr(cquantize); + cquantize^.pub.start_pass := start_pass_2_quant; + cquantize^.pub.new_color_map := new_color_map_2_quant; + cquantize^.fserrors := NIL; { flag optional arrays not allocated } + cquantize^.error_limiter := NIL; + + { Make sure jdmaster didn't give me a case I can't handle } + if (cinfo^.out_color_components <> 3) then + ERREXIT(j_common_ptr(cinfo), JERR_NOTIMPL); + + { Allocate the histogram/inverse colormap storage } + cquantize^.histogram := hist3d (cinfo^.mem^.alloc_small + (j_common_ptr (cinfo), JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d))); + for i := 0 to pred(HIST_C0_ELEMS) do + begin + cquantize^.histogram^[i] := hist2d (cinfo^.mem^.alloc_large + (j_common_ptr (cinfo), JPOOL_IMAGE, + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell))); + end; + cquantize^.needs_zeroed := TRUE; { histogram is garbage now } + + { Allocate storage for the completed colormap, if required. + We do this now since it is FAR storage and may affect + the memory manager's space calculations. } + + if (cinfo^.enable_2pass_quant) then + begin + { Make sure color count is acceptable } + desired := cinfo^.desired_number_of_colors; + { Lower bound on # of colors ... somewhat arbitrary as long as > 0 } + if (desired < 8) then + ERREXIT1(j_common_ptr (cinfo), JERR_QUANT_FEW_COLORS, 8); + { Make sure colormap indexes can be represented by JSAMPLEs } + if (desired > MAXNUMCOLORS) then + ERREXIT1(j_common_ptr (cinfo), JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + cquantize^.sv_colormap := cinfo^.mem^.alloc_sarray + (j_common_ptr (cinfo),JPOOL_IMAGE, JDIMENSION(desired), JDIMENSION(3)); + cquantize^.desired := desired; + end + else + cquantize^.sv_colormap := NIL; + + { Only F-S dithering or no dithering is supported. } + { If user asks for ordered dither, give him F-S. } + if (cinfo^.dither_mode <> JDITHER_NONE) then + cinfo^.dither_mode := JDITHER_FS; + + { Allocate Floyd-Steinberg workspace if necessary. + This isn't really needed until pass 2, but again it is FAR storage. + Although we will cope with a later change in dither_mode, + we do not promise to honor max_memory_to_use if dither_mode changes. } + + if (cinfo^.dither_mode = JDITHER_FS) then + begin + cquantize^.fserrors := FS_ERROR_FIELD_PTR (cinfo^.mem^.alloc_large + (j_common_ptr(cinfo), JPOOL_IMAGE, + size_t ((cinfo^.output_width + 2) * (3 * SIZEOF(FSERROR))) ) ); + { Might as well create the error-limiting table too. } + init_error_limit(cinfo); + end; +end; + +end. { QUANT_2PASS_SUPPORTED } diff --git a/mseide-msegui/lib/common/fpccompatibility/jutils_del.pas b/mseide-msegui/lib/common/fpccompatibility/jutils_del.pas new file mode 100644 index 0000000..e999d4c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jutils_del.pas @@ -0,0 +1,233 @@ +Unit jutils_del; + +{ This file contains tables and miscellaneous utility routines needed + for both compression and decompression. + Note we prefix all global names with "j" to minimize conflicts with + a surrounding application. } + +{ Source: jutils.c; Copyright (C) 1991-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del; + + +{ jpeg_zigzag_order[i] is the zigzag-order position of the i'th element + of a DCT block read in natural order (left to right, top to bottom). } + + +{$ifdef FALSE} { This table is not actually needed in v6a } + +const + jpeg_zigzag_order : array[0..DCTSIZE2] of int = + (0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63); + +{$endif} + + +{ jpeg_natural_order[i] is the natural-order position of the i'th element + of zigzag order. + + When reading corrupted data, the Huffman decoders could attempt + to reference an entry beyond the end of this array (if the decoded + zero run length reaches past the end of the block). To prevent + wild stores without adding an inner-loop test, we put some extra + "63"s after the real entries. This will cause the extra coefficient + to be stored in location 63 of the block, not somewhere random. + The worst case would be a run-length of 15, which means we need 16 + fake entries. } + + +const + jpeg_natural_order : array[0..DCTSIZE2+16-1] of int = + (0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, { extra entries for safety in decoder } + 63, 63, 63, 63, 63, 63, 63, 63); + + + +{ Arithmetic utilities } + +{GLOBAL} +function jdiv_round_up (a : long; b : long) : long; + +{GLOBAL} +function jround_up (a : long; b : long) : long; + +{GLOBAL} +procedure jcopy_sample_rows (input_array : JSAMPARRAY; + source_row : int; + output_array : JSAMPARRAY; dest_row : int; + num_rows : int; num_cols : JDIMENSION); + +{GLOBAL} +procedure jcopy_block_row (input_row : JBLOCKROW; + output_row : JBLOCKROW; + num_blocks : JDIMENSION); + +{GLOBAL} +procedure jzero_far (target : pointer;{far} bytestozero : size_t); + +procedure FMEMZERO(target : pointer; size : size_t); + +procedure FMEMCOPY(dest,src : pointer; size : size_t); + +implementation + +{GLOBAL} +function jdiv_round_up (a : long; b : long) : long; +{ Compute a/b rounded up to next integer, ie, ceil(a/b) } +{ Assumes a >= 0, b > 0 } +begin + jdiv_round_up := (a + b - long(1)) div b; +end; + + +{GLOBAL} +function jround_up (a : long; b : long) : long; +{ Compute a rounded up to next multiple of b, ie, ceil(a/b)*b } +{ Assumes a >= 0, b > 0 } +begin + Inc(a, b - long(1)); + jround_up := a - (a mod b); +end; + +{ On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays + and coefficient-block arrays. This won't work on 80x86 because the arrays + are FAR and we're assuming a small-pointer memory model. However, some + DOS compilers provide far-pointer versions of memcpy() and memset() even + in the small-model libraries. These will be used if USE_FMEM is defined. + Otherwise, the routines below do it the hard way. (The performance cost + is not all that great, because these routines aren't very heavily used.) } + + +{$ifndef NEED_FAR_POINTERS} { normal case, same as regular macros } +procedure FMEMZERO(target : pointer; size : size_t); +begin + FillChar(target^, size, 0); +end; + +procedure FMEMCOPY(dest,src : pointer; size : size_t); +begin + Move(src^, dest^, size); +end; + + +{$else} { 80x86 case, define if we can } + {$ifdef USE_FMEM} + FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) + FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size)) + {$endif} +{$endif} + + +{GLOBAL} +procedure jcopy_sample_rows (input_array : JSAMPARRAY; source_row : int; + output_array : JSAMPARRAY; dest_row : int; + num_rows : int; num_cols : JDIMENSION); +{ Copy some rows of samples from one place to another. + num_rows rows are copied from input_array[source_row++] + to output_array[dest_row++]; these areas may overlap for duplication. + The source and destination arrays must be at least as wide as num_cols. } +var + inptr, outptr : JSAMPLE_PTR; {register} +{$ifdef FMEMCOPY} + count : size_t; {register} +{$else} + count : JDIMENSION; {register} +{$endif} + row : int; {register} +begin +{$ifdef FMEMCOPY} + count := size_t(num_cols * SIZEOF(JSAMPLE)); +{$endif} + Inc(JSAMPROW_PTR(input_array), source_row); + Inc(JSAMPROW_PTR(output_array), dest_row); + + for row := pred(num_rows) downto 0 do + begin + inptr := JSAMPLE_PTR(input_array^[0]); + Inc(JSAMPROW_PTR(input_array)); + outptr := JSAMPLE_PTR(output_array^[0]); + Inc(JSAMPROW_PTR(output_array)); +{$ifdef FMEMCOPY} + FMEMCOPY(outptr, inptr, count); +{$else} + for count := pred(num_cols) downto 0 do + begin + outptr^ := inptr^; { needn't bother with GETJSAMPLE() here } + Inc(inptr); + Inc(outptr); + end; +{$endif} + end; +end; + + +{GLOBAL} +procedure jcopy_block_row (input_row : JBLOCKROW; + output_row : JBLOCKROW; + num_blocks : JDIMENSION); +{ Copy a row of coefficient blocks from one place to another. } +{$ifdef FMEMCOPY} +begin + FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))); +{$else} +var + inptr, outptr : JCOEFPTR; {register} + count : long; {register} +begin + inptr := JCOEFPTR (input_row); + outptr := JCOEFPTR (output_row); + for count := long(num_blocks) * DCTSIZE2 -1 downto 0 do + begin + outptr^ := inptr^; + Inc(outptr); + Inc(inptr); + end; +{$endif} +end; + + +{GLOBAL} +procedure jzero_far (target : pointer;{far} bytestozero : size_t); +{ Zero out a chunk of FAR memory. } +{ This might be sample-array data, block-array data, or alloc_large data. } +{$ifdef FMEMZERO} +begin + FMEMZERO(target, bytestozero); +{$else} +var + ptr : byteptr; + count : size_t; {register} +begin + ptr := target; + for count := bytestozero-1 downto 0 do + begin + ptr^ := 0; + Inc(ptr); + end; +{$endif} +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/mclasses.pas b/mseide-msegui/lib/common/fpccompatibility/mclasses.pas new file mode 100644 index 0000000..84be990 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mclasses.pas @@ -0,0 +1,9349 @@ +{ + This file is part of the Free Component Library (FCL) + Copyright (c) 1999-2000 by Michael Van Canneyt and Florian Klaempfl + + Classes unit for linux + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + Modified 2013-2016 by Martin Schreiber + + **********************************************************************} + +unit mclasses; +{$ifdef FPC} + {$mode objfpc} + {$h+} + { determine the type of the resource/form file } + {$define Win16Res} + {$define classesinline} + + {$INLINE ON} +{$endif} + +{$if defined(FPC) and (fpc_fullversion >= 020601)} + {$define mse_fpc_2_6_2} +{$ifend} +{$if fpc_fullversion >= 030000} {$define mse_fpc_3} {$endif} +{$if FPC_FULLVERSION >= 030100} {$define mse_fpc_3_2} {$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,typinfo,sysutils,msetypes,msesystypes {$ifndef FPC},classes_del{$endif}; + +type + ar8ty = array[0..7] of byte; +{$ifndef FPC} + TTextLineBreakStyle = (tlbsLF,tlbsCRLF,tlbsCR); + TValueType = (vaNull, vaList, vaInt8, vaInt16, vaInt32, vaExtended, + vaString, vaIdent, vaFalse, vaTrue, vaBinary, vaSet, vaLString, + vaNil, vaCollection, vaSingle, vaCurrency, vaDate, vaWString, vaInt64, + vaUTF8String, vaUString, vaQWord); +const + feInvalidHandle : THandle = THandle(-1); //return value on FileOpen error +type +{$endif} +{$ifndef mse_fpc_2_6_2} + tbytes = array of byte; +{$endif} +{$ifndef mse_fpc_3} + RawByteString = ansistring; +{$endif} + tstrings = class; + tstringlist = class; + tfiler = class; + treader = class; + twriter = class; + tcomponent = class; + tstream = class; + tfilestream = class; + tmemorystream = class; + + + TReaderProc = procedure(Reader: treader) of object; + TWriterProc = procedure(Writer: twriter) of object; + TStreamProc = procedure(Stream: TStream) of object; + +{$M+} + + tpersistent = class(TObject{,IFPObserved}) + private +// FObservers : TFPList; + procedure AssignError(Source: tpersistent); + protected + {$ifndef FPC} + function Equals(Obj: TObject) : boolean;virtual; + { IUnknown } + function QueryInterface(const IID: TGUID;out Obj): Hresult; stdcall; + function _AddRef: Integer; stdcall; + function _Release: Integer; stdcall; + {$endif} + procedure AssignTo(Dest: tpersistent); virtual; + procedure DefineProperties(Filer: tfiler); virtual; + function GetOwner: tpersistent; dynamic; +// Procedure FPOAttachObserver(AObserver : TObject); +// Procedure FPODetachObserver(AObserver : TObject); +// Procedure FPONotifyObservers(ASender : TObject; AOperation : TFPObservedOperation; Data : Pointer); + public + Destructor Destroy; override; + procedure Assign(Source: tpersistent); virtual; + function GetNamePath: string; virtual; {dynamic;} + end; + +{$M-} + + TPersistentClass = class of TPersistent; + + TGetChildProc = procedure (Child: TComponent) of object; + + TComponentClass = class of TComponent; + + tcomponent = class(tpersistent{,IUnknown,IInterfaceComponentReference}) + private + FOwner: tcomponent; + FName: TComponentName; + FTag: Ptrint; + FDesignInfo: Longint; + FVCLComObject: Pointer; + FComponentStyle: TComponentStyle; + ftagpo: pointer; +// function GetComObject: IUnknown; + function GetComponent(AIndex: Integer): tcomponent; + function GetComponentCount: Integer; + function GetComponentIndex: Integer; + procedure Insert(AComponent: tcomponent); + procedure ReadLeft(Reader: treader); + procedure ReadTop(Reader: treader); + procedure Remove(AComponent: tcomponent); + procedure RemoveNotification(AComponent: tcomponent); + procedure SetComponentIndex(Value: Integer); + procedure SetReference(Enable: Boolean); + procedure WriteLeft(Writer: twriter); + procedure WriteTop(Writer: twriter); + protected + FComponents: TFpList; + FFreeNotifies: TFpList; + FComponentState: TComponentState; + procedure ChangeName(const NewName: TComponentName); + procedure DefineProperties(Filer: tfiler); override; + procedure GetChildren(Proc: TGetChildProc; Root: tcomponent); dynamic; + function GetChildOwner: tcomponent; dynamic; + function GetChildParent: tcomponent; dynamic; + function GetOwner: tpersistent; override; + procedure Loaded; virtual; + procedure Loading; virtual; + procedure Notification(AComponent: tcomponent; + Operation: TOperation); virtual; + procedure PaletteCreated; dynamic; + procedure ReadState(Reader: treader); virtual; + procedure SetAncestor(Value: Boolean); + procedure SetDesigning(Value: Boolean; + SetChildren : Boolean = True); virtual; + procedure SetDesignInstance(Value: Boolean); + procedure SetInline(Value: Boolean); + procedure SetName(const NewName: TComponentName); virtual; + procedure SetChildOrder(Child: tcomponent; Order: Integer); dynamic; + procedure SetParentComponent(Value: tcomponent); dynamic; + procedure Updating; dynamic; + procedure Updated; dynamic; + class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); dynamic; + procedure ValidateRename(AComponent: tcomponent; + const CurName, NewName: string); virtual; + procedure ValidateContainer(AComponent: tcomponent); dynamic; + procedure ValidateInsert(AComponent: tcomponent); dynamic; + {$ifdef FPC} + { IUnknown } + function QueryInterface( + {$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; + out Obj): Hresult; virtual; {$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; + function _AddRef: Integer; {$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; + function _Release: Integer; {$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; + {$endif} + function iicrGetComponent: tcomponent; + { IDispatch } + function GetTypeInfoCount(out Count: Integer): HResult; stdcall; + function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall; + function GetIDsOfNames(const IID: TGUID; Names: Pointer; + NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall; + function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; + Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall; + public + //!! Moved temporary + // fpdoc doesn't handle this yet :( +{$ifndef fpdocsystem} +// function IInterfaceComponentReference.GetComponent=iicrgetcomponent; +{$endif} + procedure WriteState(Writer: twriter); virtual; + constructor Create(AOwner: tcomponent); virtual; + destructor Destroy; override; + procedure BeforeDestruction; override; + procedure DestroyComponents; + procedure Destroying; + function ExecuteAction(Action: TBasicAction): Boolean; dynamic; + function FindComponent(const AName: string): tcomponent; + function findtagcomponent(const atag: int32; + const aclass: tcomponentclass): tcomponent; + //returns first matching desecendent + procedure FreeNotification(AComponent: tcomponent); + procedure RemoveFreeNotification(AComponent: tcomponent); + procedure FreeOnRelease; +// function GetEnumerator: TComponentEnumerator; + function GetNamePath: string; override; + function GetParentComponent: tcomponent; dynamic; + function HasParent: Boolean; dynamic; + procedure InsertComponent(AComponent: tcomponent); + procedure RemoveComponent(AComponent: tcomponent); + function SafeCallException(ExceptObject: TObject; + ExceptAddr: Pointer): HResult; override; + procedure SetSubComponent(ASubComponent: Boolean); + function UpdateAction(Action: TBasicAction): Boolean; dynamic; +// property ComObject: IUnknown read GetComObject; +// function IsImplementorOf (const Intf:IInterface):boolean; +// procedure ReferenceInterface(const intf:IInterface;op:TOperation); + property Components[Index: Integer]: tcomponent read GetComponent; + property ComponentCount: Integer read GetComponentCount; + property ComponentIndex: Integer read GetComponentIndex write SetComponentIndex; + property ComponentState: TComponentState read FComponentState; + property ComponentStyle: TComponentStyle read FComponentStyle; + property DesignInfo: Longint read FDesignInfo write FDesignInfo; + property Owner: tcomponent read FOwner; + property VCLComObject: Pointer read FVCLComObject write FVCLComObject; + property tagpo: pointer read ftagpo write ftagpo; + published + property Name: TComponentName read FName write SetName stored False; + property Tag: PtrInt read FTag write FTag default 0; + end; + pcomponent = ^tcomponent; + + tcollection = class; + + TCollectionItem = class(TPersistent) + private + FCollection: TCollection; + FID: Integer; + FUpdateCount: Integer; + function GetIndex: Integer; + protected + procedure SetCollection(Value: TCollection);virtual; + procedure Changed(AllItems: Boolean); + function GetOwner: TPersistent; override; + function GetDisplayName: string; virtual; + procedure SetIndex(Value: Integer); virtual; + procedure SetDisplayName(const Value: string); virtual; + property UpdateCount: Integer read FUpdateCount; + public + constructor Create(ACollection: TCollection); virtual; + destructor Destroy; override; + function GetNamePath: string; override; + property Collection: TCollection read FCollection write SetCollection; + property ID: Integer read FID; + property Index: Integer read GetIndex write SetIndex; + property DisplayName: string read GetDisplayName write SetDisplayName; + end; + + TCollectionEnumerator = class + private + FCollection: TCollection; + FPosition: Integer; + public + constructor Create(ACollection: TCollection); + function GetCurrent: TCollectionItem; + function MoveNext: Boolean; + property Current: TCollectionItem read GetCurrent; + end; + + TCollectionItemClass = class of TCollectionItem; + TCollectionSortCompare = function (Item1, Item2: TCollectionItem): Integer; + + TCollection = class(TPersistent) + private + FItems: TFpList; + FUpdateCount: Integer; + FNextID: Integer; + FPropName: string; + function GetCount: Integer; + function GetPropName: string; + procedure InsertItem(Item: TCollectionItem); + procedure RemoveItem(Item: TCollectionItem); + procedure DoClear; + protected + FItemClass: TCollectionItemClass; + { Design-time editor support } + function GetAttrCount: Integer; dynamic; + function GetAttr(Index: Integer): string; dynamic; + function GetItemAttr(Index, ItemIndex: Integer): string; dynamic; + procedure Changed; + function GetItem(Index: Integer): TCollectionItem; + procedure SetItem(Index: Integer; Value: TCollectionItem); + procedure SetItemName(Item: TCollectionItem); virtual; + procedure SetPropName; virtual; + procedure Update(Item: TCollectionItem); virtual; + procedure Notify(Item: TCollectionItem;Action: TCollectionNotification); virtual; + property PropName: string read GetPropName write FPropName; + property UpdateCount: Integer read FUpdateCount; + public + constructor Create(AItemClass: TCollectionItemClass); + destructor Destroy; override; + function Owner: TPersistent; + function Add: TCollectionItem; + procedure Assign(Source: TPersistent); override; + procedure BeginUpdate; virtual; + procedure Clear; + procedure EndUpdate; virtual; + procedure Delete(Index: Integer); + function GetEnumerator: TCollectionEnumerator; + function GetNamePath: string; override; + function Insert(Index: Integer): TCollectionItem; + function FindItemID(ID: Integer): TCollectionItem; + procedure Exchange(Const Index1, index2: integer); + procedure Sort(Const Compare : TCollectionSortCompare); + property Count: Integer read GetCount; + property ItemClass: TCollectionItemClass read FItemClass; + property Items[Index: Integer]: TCollectionItem read GetItem write SetItem; + end; + + TOwnedCollection = class(TCollection) + private + FOwner: TPersistent; + protected + Function GetOwner: TPersistent; override; + public + Constructor Create(AOwner: TPersistent;AItemClass: TCollectionItemClass); + end; + + + TFindMethodEvent = procedure(Reader: TReader; const MethodName: string; + var Address: Pointer; var Error: Boolean) of object; + TSetMethodPropertyEvent = procedure(Reader: TReader; Instance: TPersistent; + PropInfo: PPropInfo; const TheMethodName: string; + var Handled: boolean) of object; + TSetNameEvent = procedure(Reader: TReader; Component: TComponent; + var Name: string) of object; + TReferenceNameEvent = procedure(Reader: TReader; var Name: string) of object; + TAncestorNotFoundEvent = procedure(Reader: TReader; const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent) of object; + TReadComponentsProc = procedure(Component: TComponent) of object; + TReaderError = procedure(Reader: TReader; const Message: string; + var Handled: Boolean) of object; + TPropertyNotFoundEvent = procedure(Reader: TReader; Instance: TPersistent; + var PropName: string; IsPath: boolean; var Handled, Skip: Boolean) of object; + TFindComponentClassEvent = procedure(Reader: TReader; const ClassName: string; + var ComponentClass: TComponentClass) of object; + TCreateComponentEvent = procedure(Reader: TReader; + ComponentClass: TComponentClass; var Component: TComponent) of object; + + TReadWriteStringPropertyEvent = procedure(Sender:TObject; + const Instance: TPersistent; PropInfo: PPropInfo; + var Content:string) of object; + + + TFindAncestorEvent = procedure (Writer: TWriter; Component: TComponent; + const Name: string; var Ancestor, RootAncestor: TComponent) of object; + TWriteMethodPropertyEvent = procedure (Writer: TWriter; Instance: TPersistent; + PropInfo: PPropInfo; + const MethodValue, DefMethodValue: TMethod; + var Handled: boolean) of object; + + tfiler = class(TObject) + private + FIgnoreChildren: Boolean; + protected + FRoot: tcomponent; + FLookupRoot: tcomponent; + FAncestor: tpersistent; + procedure SetRoot(ARoot: tcomponent); virtual; + public + procedure DefineProperty(const Name: string; + ReadData: TReaderProc; WriteData: TWriterProc; + HasData: Boolean); virtual; abstract; + procedure DefineBinaryProperty(const Name: string; + ReadData, WriteData: TStreamProc; + HasData: Boolean); virtual; abstract; + property Root: tcomponent read FRoot write SetRoot; + property LookupRoot: tcomponent read FLookupRoot; + property Ancestor: tpersistent read FAncestor write FAncestor; + property IgnoreChildren: Boolean read FIgnoreChildren write FIgnoreChildren; + end; + + TAbstractObjectReader = class + protected + freader: treader; + public + function NextValue: TValueType; virtual; abstract; + function ReadValue: TValueType; virtual; abstract; + procedure BeginRootComponent; virtual; abstract; + procedure BeginComponent(var Flags: TFilerFlags; var AChildPos: Integer; + var CompClassName, CompName: String); virtual; abstract; + function BeginProperty: String; virtual; abstract; + + //Please don't use read, better use ReadBinary whenever possible + procedure Read(var Buf; Count: LongInt); virtual; abstract; + { All ReadXXX methods are called _after_ the value type has been read! } + procedure ReadBinary(const DestData: TMemoryStream); virtual; abstract; +{$ifndef FPUNONE} + function ReadFloat: Extended; virtual; abstract; + function ReadSingle: Single; virtual; abstract; + function ReadDate: TDateTime; virtual; abstract; +{$endif} + function ReadCurrency: Currency; virtual; abstract; + function ReadIdent(ValueType: TValueType): String; virtual; abstract; + function ReadInt8: ShortInt; virtual; abstract; + function ReadInt16: SmallInt; virtual; abstract; + function ReadInt32: LongInt; virtual; abstract; + function ReadInt64: Int64; virtual; abstract; + function ReadSet(EnumType: ptypeinfo): Integer; virtual; abstract; + function ReadStr: String; virtual; abstract; + function ReadString(StringType: TValueType): String; virtual; abstract; + function Readutf8String(StringType: TValueType): utf8String; + virtual; abstract; + function ReadWideString: WideString;virtual;abstract; + function ReadUnicodeString: UnicodeString;virtual;abstract; + procedure SkipComponent(SkipComponentInfos: Boolean); virtual; abstract; + procedure SkipValue; virtual; abstract; + end; + + TBinaryObjectReader = class(TAbstractObjectReader) + protected + FStream: TStream; + FBuffer: Pointer; + FBufSize: Integer; + FBufPos: Integer; + FBufEnd: Integer; + + function ReadWord : word; + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + function ReadDWord : longword; + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + function ReadQWord : qword; + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$ifndef FPUNONE} + function ReadExtended : extended; + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$endif} + procedure SkipProperty; + procedure SkipSetBody; + public + constructor Create(Stream: TStream; BufSize: Integer); + destructor Destroy; override; + + function NextValue: TValueType; override; + function ReadValue: TValueType; override; + procedure BeginRootComponent; override; + procedure BeginComponent(var Flags: TFilerFlags; var AChildPos: Integer; + var CompClassName, CompName: String); override; + function BeginProperty: String; override; + + //Please don't use read, better use ReadBinary whenever possible + procedure Read(var Buf; Count: LongInt); override; + procedure ReadBinary(const DestData: TMemoryStream); override; +{$ifndef FPUNONE} + function ReadFloat: Extended; override; + function ReadSingle: Single; override; + function ReadDate: TDateTime; override; +{$endif} + function ReadCurrency: Currency; override; + function ReadIdent(ValueType: TValueType): String; override; + function ReadInt8: ShortInt; override; + function ReadInt16: SmallInt; override; + function ReadInt32: LongInt; override; + function ReadInt64: Int64; override; + function ReadSet(EnumType: ptypeinfo): Integer; override; + function ReadStr: String; override; + function ReadString(StringType: TValueType): String; override; + function Readutf8String(StringType: TValueType): utf8String; override; + function ReadWideString: WideString;override; + function ReadUnicodeString: UnicodeString;override; + procedure SkipComponent(SkipComponentInfos: Boolean); override; + procedure SkipValue; override; + end; + + enumerroreventty = procedure (const reader: treader; + const atype: ptypeinfo; const aenumname: string; + var avalue: longword) of object; + seterroreventty = procedure (const reader: treader; + const atype: ptypeinfo; const aitemname: string; + var avalue: integer) of object; + + treader = class(tfiler) + private + FDriver: TAbstractObjectReader; + FOwner: tcomponent; + FParent: tcomponent; + FFixups: TObject; + FOnFindMethod: TFindMethodEvent; + FOnSetMethodProperty: TSetMethodPropertyEvent; + FOnSetName: TSetNameEvent; + FOnReferenceName: TReferenceNameEvent; + FOnAncestorNotFound: TAncestorNotFoundEvent; + FOnError: TReaderError; + FOnPropertyNotFound: TPropertyNotFoundEvent; + FOnFindComponentClass: TFindComponentClassEvent; + FOnCreateComponent: TCreateComponentEvent; + FPropName: string; + FCanHandleExcepts: Boolean; + FOnReadStringProperty:TReadWriteStringPropertyEvent; + fonseterror: seterroreventty; + fonenumerror: enumerroreventty; + procedure DoFixupReferences; + function FindComponentClass(const AClassName: string; + const aflags: tfilerflags): TComponentClass; + protected + FLoaded: TFpList; + function Error(const Message: string): Boolean; virtual; + function FindMethod(ARoot: tcomponent; const AMethodName: string): Pointer; virtual; + procedure ReadProperty(AInstance: tpersistent); + procedure ReadPropValue(Instance: tpersistent; PropInfo: Pointer); + procedure PropertyError; + procedure ReadData(Instance: tcomponent); + property PropName: string read FPropName; + property CanHandleExceptions: Boolean read FCanHandleExcepts; + function CreateDriver(Stream: TStream; BufSize: Integer): TAbstractObjectReader; virtual; + public + constructor Create(Stream: TStream; BufSize: Integer); + destructor Destroy; override; + procedure BeginReferences; + procedure CheckValue(Value: TValueType); + procedure DefineProperty(const Name: string; + AReadData: TReaderProc; WriteData: TWriterProc; + HasData: Boolean); override; + procedure DefineBinaryProperty(const Name: string; + AReadData, WriteData: TStreamProc; + HasData: Boolean); override; + function beginoflist(): boolean; + function EndOfList: Boolean; + procedure EndReferences; + procedure FixupReferences; + function NextValue: TValueType; + //Please don't use read, better use ReadBinary whenever possible + //uuups, ReadBinary is protected .. + procedure Read(var Buf; Count: LongInt); virtual; + + function ReadBoolean: Boolean; + function ReadChar: Char; + function ReadWideChar: WideChar; + function ReadUnicodeChar: UnicodeChar; + procedure ReadCollection(Collection: TCollection); + function ReadComponent(Component: tcomponent): tcomponent; + procedure ReadComponents(AOwner, AParent: tcomponent; + Proc: TReadComponentsProc); +{$ifndef FPUNONE} + function ReadFloat: Extended; + function ReadSingle: Single; + function ReadDate: TDateTime; +{$endif} + function ReadCurrency: Currency; + function ReadIdent: string; + function ReadInteger: Longint; + function ReadInt64: Int64; + function readset(settype: ptypeinfo): longword; + function readenum(const enumtype: ptypeinfo): longword; + procedure ReadListBegin; + procedure ReadListEnd; + function ReadRootComponent(ARoot: tcomponent): tcomponent; + function ReadVariant: Variant; + function ReadString: string; + function Readutf8String: utf8string; + function ReadWideString: WideString; + function ReadUnicodeString: UnicodeString; + + function ReadValue: TValueType; + procedure CopyValue(Writer: twriter); + property Driver: TAbstractObjectReader read FDriver; + property Owner: tcomponent read FOwner write FOwner; + property Parent: tcomponent read FParent write FParent; + property OnError: TReaderError read FOnError write FOnError; + property OnPropertyNotFound: TPropertyNotFoundEvent + read FOnPropertyNotFound write FOnPropertyNotFound; + property OnFindMethod: TFindMethodEvent read FOnFindMethod + write FOnFindMethod; + property OnSetMethodProperty: TSetMethodPropertyEvent + read FOnSetMethodProperty write FOnSetMethodProperty; + property OnSetName: TSetNameEvent read FOnSetName write FOnSetName; + property OnReferenceName: TReferenceNameEvent read FOnReferenceName + write FOnReferenceName; + property OnAncestorNotFound: TAncestorNotFoundEvent + read FOnAncestorNotFound write FOnAncestorNotFound; + property OnCreateComponent: TCreateComponentEvent + read FOnCreateComponent write FOnCreateComponent; + property OnFindComponentClass: TFindComponentClassEvent + read FOnFindComponentClass write FOnFindComponentClass; + property OnReadStringProperty: TReadWriteStringPropertyEvent + read FOnReadStringProperty write FOnReadStringProperty; + property onenumerror: enumerroreventty read fonenumerror write fonenumerror; + property onseterror: seterroreventty read fonseterror write fonseterror; + end; + + TAbstractObjectWriter = class + protected + fwriter: twriter; + public + { Begin/End markers. Those ones who don't have an end indicator, use + "EndList", after the occurrence named in the comment. Note that this + only counts for "EndList" calls on the same level; each BeginXXX call + increases the current level. } + procedure BeginCollection; virtual; abstract; { Ends with the next "EndList" } + procedure BeginComponent(Component: TComponent; Flags: TFilerFlags; + ChildPos: Integer); virtual; abstract; { Ends after the second "EndList" } + procedure BeginList; virtual; abstract; + procedure EndList; virtual; abstract; + procedure BeginProperty(const PropName: String); virtual; abstract; + procedure EndProperty; virtual; abstract; + //Please don't use write, better use WriteBinary whenever possible + procedure Write(const Buffer; Count: Longint); virtual;abstract; + + procedure WriteBinary(const Buffer; Count: Longint); virtual; abstract; + procedure WriteBoolean(Value: Boolean); virtual; abstract; + // procedure WriteChar(Value: Char); +{$ifndef FPUNONE} + procedure WriteFloat(const Value: Extended); virtual; abstract; + procedure WriteSingle(const Value: Single); virtual; abstract; + procedure WriteDate(const Value: TDateTime); virtual; abstract; +{$endif} + procedure WriteCurrency(const Value: Currency); virtual; abstract; + procedure WriteIdent(const Ident: string); virtual; abstract; + procedure WriteInteger(Value: Int64); virtual; abstract; + procedure WriteUInt64(Value: QWord); virtual; abstract; + procedure WriteVariant(const Value: Variant); virtual; abstract; + procedure WriteMethodName(const Name: String); virtual; abstract; + procedure WriteSet(Value: LongInt; SetType: Pointer); virtual; abstract; + procedure WriteString(const Value: String); virtual; abstract; + procedure Writeutf8String(const Value: utf8String); virtual; abstract; + procedure WriteWideString(const Value: WideString);virtual;abstract; + procedure WriteUnicodeString(const Value: UnicodeString);virtual;abstract; + end; + + TBinaryObjectWriter = class(TAbstractObjectWriter) + protected + FStream: TStream; + FBuffer: Pointer; + FBufSize: Integer; + FBufPos: Integer; + FBufEnd: Integer; + FSignatureWritten: Boolean; + + procedure WriteWord(w : word); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + procedure WriteDWord(lw : longword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + procedure WriteQWord(qw : qword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$ifndef FPUNONE} + procedure WriteExtended(e : extended); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$endif} + procedure FlushBuffer; + procedure WriteValue(Value: TValueType); + public + constructor Create(Stream: TStream; BufSize: Integer); + destructor Destroy; override; + + procedure BeginCollection; override; + procedure BeginComponent(Component: TComponent; Flags: TFilerFlags; + ChildPos: Integer); override; + procedure BeginList; override; + procedure EndList; override; + procedure BeginProperty(const PropName: String); override; + procedure EndProperty; override; + + //Please don't use write, better use WriteBinary whenever possible + procedure Write(const Buffer; Count: Longint); override; + procedure WriteBinary(const Buffer; Count: LongInt); override; + procedure WriteBoolean(Value: Boolean); override; +{$ifndef FPUNONE} + procedure WriteFloat(const Value: Extended); override; + procedure WriteSingle(const Value: Single); override; + procedure WriteDate(const Value: TDateTime); override; +{$endif} + procedure WriteCurrency(const Value: Currency); override; + procedure WriteIdent(const Ident: string); override; + procedure WriteInteger(Value: Int64); override; + procedure WriteUInt64(Value: QWord); override; + procedure WriteMethodName(const Name: String); override; + procedure WriteSet(Value: LongInt; SetType: Pointer); override; + procedure WriteStr(const Value: String); + procedure WriteString(const Value: String); override; + procedure Writeutf8String(const Value: utf8String); override; + procedure WriteWideString(const Value: WideString); override; + procedure WriteUnicodeString(const Value: UnicodeString); override; + procedure WriteVariant(const VarValue: Variant);override; + end; + + twriter = class(tfiler) + private + FDestroyDriver: Boolean; + FOnWriteMethodProperty: TWriteMethodPropertyEvent; + FOnWriteStringProperty:TReadWriteStringPropertyEvent; + procedure AddToAncestorList(Component: tcomponent); + procedure WriteComponentData(Instance: tcomponent); + Procedure DetermineAncestor(Component: tcomponent); + procedure DoFindAncestor(Component : tcomponent); + protected + FPropPath: String; + FAncestors: tstringlist; + FAncestorPos: Integer; + FRootAncestor: tcomponent; + FOnFindAncestor: TFindAncestorEvent; + FDriver: TAbstractObjectWriter; + FCurrentPos: Integer; + procedure SetRoot(ARoot: tcomponent); override; + procedure WriteBinary(AWriteData: TStreamProc); + procedure WriteProperty(Instance: tpersistent; PropInfo: Pointer); + procedure WriteProperties(Instance: tpersistent); + procedure WriteChildren(Component: tcomponent); + function CreateDriver(Stream: TStream; + BufSize: Integer): TAbstractObjectWriter; virtual; + function getclassname(const aobj: tobject): shortstring; virtual; + public + constructor Create(ADriver: TAbstractObjectWriter); overload; + constructor Create(Stream: TStream; BufSize: Integer); overload; + destructor Destroy; override; + procedure DefineProperty(const Name: string; + ReadData: TReaderProc; AWriteData: TWriterProc; + HasData: Boolean); override; + procedure DefineBinaryProperty(const Name: string; + ReadData, AWriteData: TStreamProc; + HasData: Boolean); override; + //Please don't use write, better use WriteBinary whenever possible + //uuups, WriteBinary is protected .. + procedure Write(const Buffer; Count: Longint); virtual; + procedure WriteBoolean(Value: Boolean); + procedure WriteCollection(Value: TCollection); + procedure WriteComponent(Component: tcomponent); + procedure WriteChar(Value: Char); + procedure WriteWideChar(Value: WideChar); + procedure WriteDescendent(ARoot: tcomponent; AAncestor: tcomponent); +{$ifndef FPUNONE} + procedure WriteFloat(const Value: Extended); + procedure WriteSingle(const Value: Single); + procedure WriteDate(const Value: TDateTime); +{$endif} + procedure WriteCurrency(const Value: Currency); + procedure WriteIdent(const Ident: string); + procedure WriteInteger(Value: Longint); overload; + procedure WriteInteger(Value: Int64); overload; + procedure writeset(value: longword; settype: ptypeinfo); + procedure writeenum(value: longint; enumtype: ptypeinfo); + procedure WriteListBegin; + procedure WriteListEnd; + procedure WriteRootComponent(ARoot: tcomponent); + procedure WriteString(const Value: string); + procedure Writeutf8String(const Value: utf8string); + procedure WriteWideString(const Value: WideString); + procedure WriteUnicodeString(const Value: UnicodeString); + procedure WriteVariant(const VarValue: Variant); + property RootAncestor: tcomponent read FRootAncestor write FRootAncestor; + property OnFindAncestor: TFindAncestorEvent read FOnFindAncestor write FOnFindAncestor; + property OnWriteMethodProperty: TWriteMethodPropertyEvent read FOnWriteMethodProperty write FOnWriteMethodProperty; + property OnWriteStringProperty: TReadWriteStringPropertyEvent read FOnWriteStringProperty write FOnWriteStringProperty; + + property Driver: TAbstractObjectWriter read FDriver; + property PropertyPath: string read FPropPath; + end; + +TStringsEnumerator = class + private + FStrings: TStrings; + FPosition: Integer; + public + constructor Create(AStrings: TStrings); + function GetCurrent: String; + function MoveNext: Boolean; + property Current: String read GetCurrent; + end; + +{ tstrings class } + + tstrings = class(tpersistent) + private + FSpecialCharsInited : boolean; + FQuoteChar : Char; + FDelimiter : Char; + FNameValueSeparator : Char; + FUpdateCount: Integer; + FAdapter: IStringsAdapter; + FLBS : TTextLineBreakStyle; + FStrictDelimiter : Boolean; + function GetCommaText: string; + function GetName(Index: Integer): string; + function GetValue(const Name: string): string; + Function GetLBS : TTextLineBreakStyle; + Procedure SetLBS (AValue : TTextLineBreakStyle); + procedure ReadData(Reader: TReader); + procedure SetCommaText(const Value: string); + procedure SetStringsAdapter(const Value: IStringsAdapter); + procedure SetValue(const Name, Value: string); + procedure SetDelimiter(c:Char); + procedure SetQuoteChar(c:Char); + procedure SetNameValueSeparator(c:Char); + procedure WriteData(Writer: TWriter); + protected + procedure DefineProperties(Filer: tfiler); override; + procedure Error(const Msg: string; Data: Integer); overload; + procedure Error(const Msg: pstring; Data: Integer); overload; + function Get(Index: Integer): string; virtual; abstract; + function GetCapacity: Integer; virtual; + function GetCount: Integer; virtual; abstract; + function GetObject(Index: Integer): TObject; virtual; + function GetTextStr: string; virtual; + procedure Put(Index: Integer; const S: string); virtual; + procedure PutObject(Index: Integer; AObject: TObject); virtual; + procedure SetCapacity(NewCapacity: Integer); virtual; + procedure SetTextStr(const Value: string); virtual; + procedure SetUpdateState(Updating: Boolean); virtual; + property UpdateCount: Integer read FUpdateCount; + Function DoCompareText(const s1,s2 : string) : PtrInt; virtual; + Function GetDelimitedText: string; + Procedure SetDelimitedText(Const AValue: string); + Function GetValueFromIndex(Index: Integer): string; + Procedure SetValueFromIndex(Index: Integer; const Value: string); + Procedure CheckSpecialChars; + public + destructor Destroy; override; + function Add(const S: string): Integer; virtual; + function AddObject(const S: string; AObject: TObject): Integer; virtual; + procedure Append(const S: string); + procedure AddStrings(TheStrings: tstrings); overload; virtual; + procedure AddStrings(const TheStrings: array of string); overload; virtual; + procedure Assign(Source: tpersistent); override; + procedure BeginUpdate; + procedure Clear; virtual; abstract; + procedure Delete(Index: Integer); virtual; abstract; + procedure EndUpdate; + function Equals(Obj: TObject): Boolean; overload; override; + function Equals(TheStrings: tstrings): Boolean; reintroduce; overload; + procedure Exchange(Index1, Index2: Integer); virtual; + function GetEnumerator: TStringsEnumerator; + function GetText: PChar; virtual; + function IndexOf(const S: string): Integer; virtual; + function IndexOfName(const Name: string): Integer; virtual; + function IndexOfObject(AObject: TObject): Integer; virtual; + procedure Insert(Index: Integer; const S: string); virtual; abstract; + procedure InsertObject(Index: Integer; const S: string; + AObject: TObject); + procedure LoadFromFile(const FileName: string); virtual; + procedure LoadFromStream(Stream: TStream); virtual; + procedure Move(CurIndex, NewIndex: Integer); virtual; + procedure SaveToFile(const FileName: string); virtual; + procedure SaveToStream(Stream: TStream); virtual; + procedure SetText(TheText: PChar); virtual; + procedure GetNameValue(Index : Integer; Out AName,AValue : String); + function ExtractName(Const S:String):String; + Property TextLineBreakStyle : TTextLineBreakStyle Read GetLBS Write SetLBS; + property Delimiter: Char read FDelimiter write SetDelimiter; + property DelimitedText: string read GetDelimitedText write SetDelimitedText; + Property StrictDelimiter : Boolean Read FStrictDelimiter Write FStrictDelimiter; + property QuoteChar: Char read FQuoteChar write SetQuoteChar; + Property NameValueSeparator : Char Read FNameValueSeparator Write SetNameValueSeparator; + property ValueFromIndex[Index: Integer]: string read GetValueFromIndex write SetValueFromIndex; + property Capacity: Integer read GetCapacity write SetCapacity; + property CommaText: string read GetCommaText write SetCommaText; + property Count: Integer read GetCount; + property Names[Index: Integer]: string read GetName; + property Objects[Index: Integer]: TObject read GetObject write PutObject; + property Values[const Name: string]: string read GetValue write SetValue; + property Strings[Index: Integer]: string read Get write Put; default; + property Text: string read GetTextStr write SetTextStr; + property StringsAdapter: IStringsAdapter read FAdapter write SetStringsAdapter; + end; + + TStringListSortCompare = function(List: tstringlist; Index1, Index2: Integer): Integer; + + tstringlist = class(tstrings) + private + FList: PStringItemList; + FCount: Integer; + FCapacity: Integer; + FOnChange: TNotifyEvent; + FOnChanging: TNotifyEvent; + FDuplicates: TDuplicates; + FCaseSensitive : Boolean; + FSorted: Boolean; + FOwnsObjects : Boolean; + procedure ExchangeItems(Index1, Index2: Integer); + procedure Grow; + procedure InternalClear; + procedure QuickSort(L, R: Integer; CompareFn: TStringListSortCompare); + procedure SetSorted(Value: Boolean); + procedure SetCaseSensitive(b : boolean); + protected + procedure Changed; virtual; + procedure Changing; virtual; + function Get(Index: Integer): string; override; + function GetCapacity: Integer; override; + function GetCount: Integer; override; + function GetObject(Index: Integer): TObject; override; + procedure Put(Index: Integer; const S: string); override; + procedure PutObject(Index: Integer; AObject: TObject); override; + procedure SetCapacity(NewCapacity: Integer); override; + procedure SetUpdateState(Updating: Boolean); override; + procedure InsertItem(Index: Integer; const S: string); overload; virtual; + procedure InsertItem(Index: Integer; const S: string; O: TObject); + overload; virtual; + Function DoCompareText(const s1,s2 : string) : PtrInt; override; + + public + destructor Destroy; override; + function Add(const S: string): Integer; override; + procedure Clear; override; + procedure Delete(Index: Integer); override; + procedure Exchange(Index1, Index2: Integer); override; + function Find(const S: string; Out Index: Integer): Boolean; virtual; + function IndexOf(const S: string): Integer; override; + procedure Insert(Index: Integer; const S: string); override; + procedure Sort; virtual; + procedure CustomSort(CompareFn: TStringListSortCompare); virtual; + property Duplicates: TDuplicates read FDuplicates write FDuplicates; + property Sorted: Boolean read FSorted write SetSorted; + property CaseSensitive: Boolean read FCaseSensitive write SetCaseSensitive; + property OnChange: TNotifyEvent read FOnChange write FOnChange; + property OnChanging: TNotifyEvent read FOnChanging write FOnChanging; + property OwnsObjects : boolean read FOwnsObjects write FOwnsObjects; + end; + + TStream = class(TObject) + private + protected + procedure InvalidSeek; virtual; + procedure Discard(const Count: Int64); + procedure DiscardLarge(Count: int64; const MaxBufferSize: Longint); + procedure FakeSeekForward(Offset: Int64; const Origin: TSeekOrigin; const Pos: Int64); + function GetPosition: Int64; virtual; + procedure SetPosition(const Pos: Int64); virtual; + function GetSize: Int64; virtual; + procedure SetSize64(const NewSize: Int64); virtual; + procedure SetSize(NewSize: Longint); overload; virtual; + procedure SetSize(const NewSize: Int64); overload; virtual; + procedure ReadNotImplemented; + procedure WriteNotImplemented; + function getmemory: pointer; virtual; + public + function Read(var Buffer; Count: Longint): Longint; virtual; overload; + function Write(const Buffer; Count: Longint): Longint; virtual; overload; + function read(var buffer; const count: longint; + out acount: longint): syserrorty; virtual; overload; + function write(const buffer; const count: longint; + out acount: longint): syserrorty; virtual; overload; + function Seek(Offset: Longint; Origin: Word): Longint; overload; virtual; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; + overload; virtual; + function seek(const offset: int64; const origin: tseekorigin; + out newpos: int64): syserrorty; overload; virtual; + procedure ReadBuffer(var Buffer; Count: Longint); + function tryreadbuffer(var buffer; count: longint): syserrorty; + procedure WriteBuffer(const Buffer; Count: Longint); + function trywritebuffer(const buffer; count: longint): syserrorty; + function readdatastring: string; virtual; + //read available data + procedure writedatastring(const value: rawbytestring); virtual; + function CopyFrom(Source: TStream; Count: Int64): Int64; + function ReadComponent(Instance: TComponent): TComponent; + function ReadComponentRes(Instance: TComponent): TComponent; + procedure WriteComponent(Instance: TComponent); + procedure WriteComponentRes(const ResName: string; Instance: TComponent); + procedure WriteDescendent(Instance, Ancestor: TComponent); + procedure WriteDescendentRes(const ResName: string; Instance, Ancestor: TComponent); + procedure WriteResourceHeader(const ResName: string; {!!!:out} var FixupInfo: Integer); + procedure FixupResourceHeader(FixupInfo: Integer); + procedure ReadResHeader; + function ReadByte : Byte; + function ReadWord : Word; + function ReadDWord : Cardinal; + function ReadQWord : QWord; + function ReadAnsiString : String; + procedure WriteByte(b : Byte); + procedure WriteWord(w : Word); + procedure WriteDWord(d : Cardinal); + procedure WriteQWord(q : QWord); + Procedure WriteAnsiString (const S : String); + property Position: Int64 read GetPosition write SetPosition; + property Size: Int64 read GetSize write SetSize64; + property memory: pointer read getmemory; //nil if not suported + end; + + THandleStream = class(TStream) + private + protected + FHandle: filehandlety; + procedure SetSize(NewSize: Longint); override; + procedure SetSize(const NewSize: Int64); override; + public + constructor Create(AHandle: THandle); + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + property Handle: filehandlety read FHandle; + function releasehandle(): filehandlety virtual; + end; + + TFileStream = class(THandleStream) + Private + FFileName : String; + public + constructor Create(const AFileName: string; Mode: Word); overload; + constructor Create(const AFileName: string; Mode: Word; Rights: Cardinal); + overload; + destructor Destroy; override; + property FileName : String Read FFilename; + end; + + TCustomMemoryStream = class(TStream) + private + protected + FMemory: Pointer; + FSize, FPosition: PtrInt; + Function GetSize : Int64; Override; + function GetPosition: Int64; Override; + procedure SetPointer(Ptr: Pointer; ASize: PtrInt); + function getmemory: pointer; override; + public + function Read(var Buffer; Count: LongInt): LongInt; override; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + procedure SaveToStream(Stream: TStream); + procedure SaveToFile(const FileName: string); + property memory: Pointer read getmemory; + property position1: ptrint read fposition; + property size1: ptrint read fsize; + end; + + TMemoryStream = class(TCustomMemoryStream) + private + FCapacity: PtrInt; + protected + procedure SetCapacity(NewCapacity: PtrInt) virtual; + function getcapacity: ptrint virtual; + function Realloc(var NewCapacity: PtrInt): Pointer; virtual; + public + destructor Destroy; override; + procedure Clear; + procedure LoadFromStream(Stream: TStream); + procedure LoadFromFile(const FileName: string); + procedure SetSize({$ifdef CPU64}const{$endif CPU64} NewSize: PtrInt); override; + function Write(const Buffer; Count: LongInt): LongInt; override; + property Capacity: PtrInt read getcapacity write SetCapacity; + end; + + TStringStream = class(TStream) + private + FDataString: string; + FPosition: Integer; + protected + Function GetSize : Int64; Override; + function GetPosition: Int64; Override; + procedure SetSize(NewSize: Longint); override; + function getmemory: pointer; override; + public + constructor Create(const AString: string); + function Read(var Buffer; Count: Longint): Longint; override; + function ReadString(Count: Longint): string; + function Seek(Offset: Longint; Origin: Word): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + procedure WriteString(const AString: string); + property DataString: string read FDataString; + end; +{$ifdef FPC} +{$ifdef UNICODE} + TResourceStream = class(TCustomMemoryStream) + private + Res: TFPResourceHandle; + Handle: TFPResourceHGLOBAL; + procedure Initialize(Instance: TFPResourceHMODULE; Name, ResType: PWideChar; NameIsID: Boolean); + public + constructor Create(Instance: TFPResourceHMODULE; const ResName: WideString; ResType: PWideChar); + constructor CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PWideChar); + destructor Destroy; override; + end; +{$else} + TResourceStream = class(TCustomMemoryStream) + private + Res: TFPResourceHandle; + Handle: TFPResourceHGLOBAL; + procedure Initialize(Instance: TFPResourceHMODULE; Name, ResType: PChar; NameIsID: Boolean); + public + constructor Create(Instance: TFPResourceHMODULE; const ResName: string; ResType: PChar); + constructor CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PChar); + destructor Destroy; override; + end; +{$endif UNICODE} +{$endif} + + TOwnerStream = Class(TStream) + private + Protected + FOwner : Boolean; + FSource : TStream; + Public + Constructor Create(ASource : TStream); + Destructor Destroy; override; + Property Source : TStream Read FSource; + Property SourceOwner : Boolean Read Fowner Write FOwner; + end; + + TFindGlobalComponent = function(const Name: string): TComponent; + TInitComponentHandler = function(Instance: TComponent; RootAncestor : TClass): boolean; + +procedure RegisterFindGlobalComponentProc(AFindGlobalComponent: TFindGlobalComponent); +procedure UnregisterFindGlobalComponentProc(AFindGlobalComponent: TFindGlobalComponent); +function FindGlobalComponent(const Name: string): TComponent; + +function InitInheritedComponent(Instance: TComponent; RootAncestor: TClass): Boolean; +function InitComponentRes(const ResName: string; Instance: TComponent): Boolean; +function ReadComponentRes(const ResName: string; Instance: TComponent): TComponent; +function ReadComponentResEx(HInstance: THandle; const ResName: string): TComponent; +function ReadComponentResFile(const FileName: string; Instance: TComponent): TComponent; +procedure WriteComponentResFile(const FileName: string; Instance: TComponent); +procedure RegisterInitComponentHandler(ComponentClass: TComponentClass; Handler: TInitComponentHandler); + +procedure GlobalFixupReferences; +procedure GetFixupReferenceNames(Root: TComponent; Names: TStrings); +procedure GetFixupInstanceNames(Root: TComponent; + const ReferenceRootName: string; Names: TStrings); +procedure RedirectFixupReferences(Root: TComponent; const OldRootName, + NewRootName: string); +procedure RemoveFixupReferences(Root: TComponent; const RootName: string); +procedure RemoveFixups(Instance: TPersistent); +Function FindNestedComponent(Root : TComponent; APath : String; CStyle : Boolean = True) : TComponent; + +procedure BeginGlobalLoading; +procedure NotifyGlobalLoading; +procedure EndGlobalLoading; +procedure beginsuspendgloballoading; +procedure endsuspendgloballoading; + +function CollectionsEqual(C1, C2: TCollection): Boolean; overload; +function CollectionsEqual(C1, C2: TCollection; Owner1, + Owner2: TComponent): Boolean; overload; + +procedure RegisterClass(AClass: TPersistentClass); +procedure RegisterClasses(AClasses: array of TPersistentClass); +procedure RegisterClassAlias(AClass: TPersistentClass; const Alias: string); +procedure UnRegisterClass(AClass: TPersistentClass); +procedure UnRegisterClasses(AClasses: array of TPersistentClass); +procedure UnRegisterModuleClasses(Module: HMODULE); +function FindClass(const AClassName: string): TPersistentClass; +function GetClass(const AClassName: string): TPersistentClass; + +function ExtractStrings(Separators, WhiteSpace: TSysCharSet; Content: PChar; Strings: TStrings): Integer; + +{$ifndef FPUNONE} +{$IFNDEF FPC_HAS_TYPE_EXTENDED} +function ExtendedToDouble(e : pointer) : double; +procedure DoubleToExtended(d : double; e : pointer); +{$endif} +{$endif} + +{$ifndef FPC} +resourcestring + SStreamNoReading = 'Reading from %s is not supported'; + SStreamNoWriting = 'Writing to %s is not supported'; + SRangeError = 'Range error'; + SStreamInvalidSeek = 'Invalid stream operation %s.Seek'; + SEmptyStreamIllegalReader = 'Illegal Nil stream for TReader constructor'; + SEmptyStreamIllegalWriter = 'Illegal Nil stream for TWriter constructor'; + SErrNoVariantSupport = 'No variant support for properties. Please use the variants unit in your project and recompile'; + SUnsupportedPropertyVariantType = 'Unsupported property variant type %d'; + SUnknownPropertyType = 'Unknown property type %d'; + +Const + FilerSignature : Array[1..4] of char = 'TPF0'; +{$endif} + +implementation +uses + {$ifdef MSWINDOWS}windows,{$endif}rtlconsts,msesysintf,msesys; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifndef FPC} +{$define endian_little} +{$define FPC_HAS_TYPE_EXTENDED} +{$endif} + +Const + // Ratio of Pointer and Word Size. + WordRatio = SizeOf(Pointer) Div SizeOf(Word); + +Type + TLinkedListItem = Class + Public + Next : TLinkedListItem; + end; + TLinkedListItemClass = Class of TLinkedListItem; + + { TLinkedListVisitor } + + TLinkedListVisitor = Class + Function Visit(Item : TLinkedListItem) : Boolean; virtual; abstract; + end; + { TLinkedList } + + TLinkedList = Class + private + FItemClass: TLinkedListItemClass; + FRoot: TLinkedListItem; + function GetCount: Integer; + Public + Constructor Create(AnItemClass : TLinkedListItemClass); virtual; + Destructor Destroy; override; + Procedure Clear; + Function Add : TLinkedListItem; + Procedure ForEach(Visitor: TLinkedListVisitor); + Procedure RemoveItem(Item : TLinkedListItem; FreeItem : Boolean = False); + Property Root : TLinkedListItem Read FRoot; + Property ItemClass : TLinkedListItemClass Read FItemClass; + Property Count : Integer Read GetCount; + end; + +{ TLinkedList } + +function TLinkedList.GetCount: Integer; + +Var + I : TLinkedListItem; + +begin + I:=FRoot; + Result:=0; + While I<>Nil do + begin + I:=I.Next; + Inc(Result); + end; +end; + +constructor TLinkedList.Create(AnItemClass: TLinkedListItemClass); +begin + FItemClass:=AnItemClass; +end; + +destructor TLinkedList.Destroy; +begin + Clear; + inherited Destroy; +end; + +procedure TLinkedList.Clear; + +Var + I : TLinkedListItem; + +begin + // Can't use visitor, because it'd kill the next pointer... + I:=FRoot; + While I<>Nil do + begin + FRoot:=I; + I:=I.Next; + FRoot.Next:=Nil; + FreeAndNil(FRoot); + end; +end; + +function TLinkedList.Add: TLinkedListItem; +begin + Result:=FItemClass.Create; + Result.Next:=FRoot; + FRoot:=Result; +end; + +procedure TLinkedList.ForEach(Visitor : TLinkedListVisitor); + +Var + I : TLinkedListItem; + +begin + I:=FRoot; + While (I<>Nil) and Visitor.Visit(I) do + I:=I.Next; +end; + +procedure TLinkedList.RemoveItem(Item: TLinkedListItem; FreeItem : Boolean = False); + +Var + I : TLinkedListItem; + +begin + If (Item<>Nil) and (FRoot<>Nil) then + begin + If (Item=FRoot) then + FRoot:=Item.Next + else + begin + I:=FRoot; + While (I.Next<>Nil) and (I.Next<>Item) do + I:=I.Next; + If (I.Next=Item) then + I.Next:=Item.Next; + end; + If FreeItem Then + Item.Free; + end; +end; + + +{****************************************************************************} +{* TPersistent *} +{****************************************************************************} + +{$ifndef FPC} +function tpersistent.Equals(Obj: TObject) : boolean; +begin + result:= Obj = Self; +end; + +function tpersistent.QueryInterface(const IID: TGUID; + out Obj): HResult; stdcall; +begin + if GetInterface(IID, Obj) then + Result := S_OK + else + Result := E_NOINTERFACE; +end; + +function tpersistent._AddRef: Integer; stdcall; +begin + Result := -1; +end; + +function tpersistent._Release: Integer; stdcall; +begin + Result := -1; +end; +{$endif} + +procedure TPersistent.AssignError(Source: TPersistent); + +Var SourceName : String; + +begin + If Source<>Nil then + SourceName:=Source.ClassName + else + SourceName:='Nil'; + raise EConvertError.CreateFmt (SAssignError,[SourceName,ClassName]); +end; + + + +procedure TPersistent.AssignTo(Dest: TPersistent); + + +begin + Dest.AssignError(Self); +end; + + +procedure TPersistent.DefineProperties(Filer: TFiler); + +begin +end; + + +function TPersistent.GetOwner: TPersistent; + +begin + Result:=Nil; +end; + +destructor TPersistent.Destroy; +begin +// If Assigned(FObservers) then +// begin +// FPONotifyObservers(Self,ooFree,Nil); +// FreeAndNil(FObservers); +// end; + inherited Destroy; +end; +{ +procedure TPersistent.FPOAttachObserver(AObserver: TObject); +Var + I : IFPObserver; + +begin + If Not AObserver.GetInterface(SGUIDObserver,I) then + Raise EObserver.CreateFmt(SErrNotObserver,[AObserver.ClassName]); + If not Assigned(FObservers) then + FObservers:=TFPList.Create; + FObservers.Add(AObserver); +end; + +procedure TPersistent.FPODetachObserver(AObserver: TObject); +Var + I : IFPObserver; + +begin + If Not AObserver.GetInterface(SGUIDObserver,I) then + Raise EObserver.CreateFmt(SErrNotObserver,[AObserver.ClassName]); + If Assigned(FObservers) then + begin + FObservers.Remove(AObserver); + If (FObservers.Count=0) then + FreeAndNil(FObservers); + end; +end; + +procedure TPersistent.FPONotifyObservers(ASender: TObject; + AOperation: TFPObservedOperation; Data : Pointer); +Var + O : TObject; + I : Integer; + Obs : IFPObserver; + +begin + If Assigned(FObservers) then + For I:=FObservers.Count-1 downto 0 do + begin + O:=TObject(FObservers[i]); + If O.GetInterface(SGUIDObserver,Obs) then + Obs.FPOObservedChanged(Self,AOperation,Data); + end; +end; +} +procedure TPersistent.Assign(Source: TPersistent); + +begin + If Source<>Nil then + Source.AssignTo(Self) + else + AssignError(Nil); +end; + +function TPersistent.GetNamePath: string; + +Var OwnerName :String; + TheOwner: TPersistent; + +begin + Result:=ClassName; + TheOwner:=GetOwner; + If TheOwner<>Nil then + begin + OwnerName:=TheOwner.GetNamePath; + If OwnerName<>'' then Result:=OwnerName+'.'+Result; + end; +end; + +{****************************************************************************} +{* TComponent *} +{****************************************************************************} +(* +function TComponent.GetComObject: IUnknown; +begin + { Check if VCLComObject is not assigned - we need to create it by } + { the call to CreateVCLComObject routine. If in the end we are still } + { have no valid VCLComObject pointer we need to raise an exception } + if not Assigned(VCLComObject) then + begin + if Assigned(CreateVCLComObjectProc) then + CreateVCLComObjectProc(Self); + if not Assigned(VCLComObject) then + raise EComponentError.CreateFmt(SNoComSupport,[Name]); + end; + { VCLComObject is IVCComObject but we need to return IUnknown } + IVCLComObject(VCLComObject).QueryInterface(IUnknown, Result); +end; +*) +Function TComponent.GetComponent(AIndex: Integer): TComponent; + +begin + If not assigned(FComponents) then + Result:=Nil + else + Result:=TComponent(FComponents.Items[Aindex]); +end; +{ +function TComponent.IsImplementorOf (const Intf:IInterface):boolean; +var ref : IInterfaceComponentReference; +begin + result:=assigned(intf) and supports(intf,IInterfaceComponentReference,ref); + if result then + result:=ref.getcomponent=self; +end; + +procedure TComponent.ReferenceInterface(const intf:IInterface;op:TOperation); +var ref : IInterfaceComponentReference; + comp : TComponent; +begin + if assigned(intf) and supports(intf,IInterfaceComponentReference,ref) then + begin + comp:=ref.getcomponent; + if op = opInsert then + comp.FreeNotification(Self) + else + comp.RemoveFreeNotification(Self); + end; +end; +} +Function TComponent.GetComponentCount: Integer; + +begin + If not assigned(FComponents) then + result:=0 + else + Result:=FComponents.Count; +end; + + +Function TComponent.GetComponentIndex: Integer; + +begin + If Assigned(FOwner) and Assigned(FOwner.FComponents) then + Result:=FOWner.FComponents.IndexOf(Self) + else + Result:=-1; +end; + + +Procedure TComponent.Insert(AComponent: TComponent); + +begin + If not assigned(FComponents) then + FComponents:=TFpList.Create; + FComponents.Add(AComponent); + AComponent.FOwner:=Self; +end; + + +procedure tcomponent.readleft(reader: treader); + +var + int1: integer; +begin + int1:= reader.readinteger; + if (int1 < 0) or (int1 > $7fff) then begin + int1:= 0; //limit to positive values + end; + longrec(fdesigninfo).lo:= int1; +end; + + +procedure tcomponent.readtop(reader: treader); +var + int1: integer; +begin + int1:= reader.readinteger; + if (int1 < 0) or (int1 > $7fff) then begin + int1:= 0; //limit to positive values + end; + longrec(fdesigninfo).hi:= int1; +end; + + +Procedure TComponent.Remove(AComponent: TComponent); + +begin + AComponent.FOwner:=Nil; + If assigned(FCOmponents) then + begin + FComponents.Remove(AComponent); + IF FComponents.Count=0 then + begin + FComponents.Free; + FComponents:=Nil; + end; + end; +end; + + +Procedure TComponent.RemoveNotification(AComponent: TComponent); + +begin + if FFreeNotifies<>nil then + begin + FFreeNotifies.Remove(AComponent); + if FFreeNotifies.Count=0 then + begin + FFreeNotifies.Free; + FFreeNotifies:=nil; + Exclude(FComponentState,csFreeNotification); + end; + end; +end; + + +Procedure TComponent.SetComponentIndex(Value: Integer); + +Var Temp,Count : longint; + +begin + If Not assigned(Fowner) then exit; + Temp:=getcomponentindex; + If temp<0 then exit; + If value<0 then value:=0; + Count:=Fowner.FComponents.Count; + If Value>=Count then value:=count-1; + If Value<>Temp then + begin + FOWner.FComponents.Delete(Temp); + FOwner.FComponents.Insert(Value,Self); + end; +end; + + +Procedure TComponent.SetReference(Enable: Boolean); + +var + Field: ^TComponent; +begin + if Assigned(Owner) then + begin + Field := Owner.FieldAddress(Name); + if Assigned(Field) then + if Enable then + Field^ := Self + else + Field^ := nil; + end; +end; + + +Procedure TComponent.WriteLeft(Writer: TWriter); + +begin + Writer.WriteInteger(smallint(LongRec(FDesignInfo).Lo)); +end; + + +Procedure TComponent.WriteTop(Writer: TWriter); + +begin + Writer.WriteInteger(smallint(LongRec(FDesignInfo).Hi)); +end; + + +Procedure TComponent.ChangeName(const NewName: TComponentName); + +begin + FName:=NewName; +end; + + +Procedure TComponent.DefineProperties(Filer: TFiler); + +Var Ancestor : TComponent; + Temp : longint; + +begin + Temp:=0; + Ancestor:=TComponent(Filer.Ancestor); + If Assigned(Ancestor) then Temp:=Ancestor.FDesignInfo; + Filer.Defineproperty('left',{$ifdef FPC}@{$endif}readleft, + {$ifdef FPC}@{$endif}writeleft, + (longrec(FDesignInfo).Lo<>Longrec(temp).Lo)); + Filer.Defineproperty('top',{$ifdef FPC}@{$endif}readtop, + {$ifdef FPC}@{$endif}writetop, + (longrec(FDesignInfo).Hi<>Longrec(temp).Hi)); +end; + + +Procedure TComponent.GetChildren(Proc: TGetChildProc; Root: TComponent); + +begin + // Does nothing. +end; + + +Function TComponent.GetChildOwner: TComponent; + +begin + Result:=Nil; +end; + + +Function TComponent.GetChildParent: TComponent; + +begin + Result:=Self; +end; + +{ +Function TComponent.GetEnumerator: TComponentEnumerator; + +begin + Result:=TComponentEnumerator.Create(Self); +end; +} +Function TComponent.GetNamePath: string; + +begin + Result:=FName; +end; + + +Function TComponent.GetOwner: TPersistent; + +begin + Result:=FOwner; +end; + + +Procedure TComponent.Loaded; + +begin + Exclude(FComponentState,csLoading); +end; + +Procedure TComponent.Loading; + +begin + Include(FComponentState,csLoading); +end; + + +Procedure TComponent.Notification(AComponent: TComponent; + Operation: TOperation); + +Var Runner : Longint; + +begin + If (Operation=opRemove) and Assigned(FFreeNotifies) then + begin + FFreeNotifies.Remove(AComponent); + If FFreeNotifies.Count=0 then + begin + FFreeNotifies.Free; + FFreenotifies:=Nil; + end; + end; + If assigned(FComponents) then + For Runner:=0 To FComponents.Count-1 do + TComponent(FComponents.Items[Runner]).Notification(AComponent,Operation); +end; + + +procedure TComponent.PaletteCreated; + begin + end; + + +Procedure TComponent.ReadState(Reader: TReader); + +begin + Reader.ReadData(Self); +end; + + +Procedure TComponent.SetAncestor(Value: Boolean); + +Var Runner : Longint; + +begin + If Value then + Include(FComponentState,csAncestor) + else + Exclude(FCOmponentState,csAncestor); + if Assigned(FComponents) then + For Runner:=0 To FComponents.Count-1 do + TComponent(FComponents.Items[Runner]).SetAncestor(Value); +end; + + +Procedure TComponent.SetDesigning(Value: Boolean; SetChildren : Boolean = True); + +Var Runner : Longint; + +begin + If Value then + Include(FComponentState,csDesigning) + else + Exclude(FComponentState,csDesigning); + if Assigned(FComponents) and SetChildren then + For Runner:=0 To FComponents.Count - 1 do + TComponent(FComponents.items[Runner]).SetDesigning(Value); +end; + +Procedure TComponent.SetDesignInstance(Value: Boolean); + +begin + If Value then + Include(FComponentState,csDesignInstance) + else + Exclude(FComponentState,csDesignInstance); +end; + +Procedure TComponent.SetInline(Value: Boolean); + +begin + If Value then + Include(FComponentState,csInline) + else + Exclude(FComponentState,csInline); +end; + + +Procedure TComponent.SetName(const NewName: TComponentName); + +begin + If FName=NewName then exit; + If (NewName<>'') and not IsValidIdent(NewName) then + Raise EComponentError.CreateFmt(SInvalidName,[NewName]); + If Assigned(FOwner) Then + FOwner.ValidateRename(Self,FName,NewName) + else + ValidateRename(Nil,FName,NewName); + SetReference(False); + ChangeName(NewName); + Setreference(True); +end; + + +Procedure TComponent.SetChildOrder(Child: TComponent; Order: Integer); + +begin + // does nothing +end; + + +Procedure TComponent.SetParentComponent(Value: TComponent); + +begin + // Does nothing +end; + + +Procedure TComponent.Updating; + +begin + Include (FComponentState,csUpdating); +end; + + +Procedure TComponent.Updated; + +begin + Exclude(FComponentState,csUpdating); +end; + + +class Procedure TComponent.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); + +begin + // For compatibility only. +end; + + +Procedure TComponent.ValidateRename(AComponent: TComponent; + const CurName, NewName: string); + +begin +//!! This contradicts the Delphi manual. + If (AComponent<>Nil) and (CompareText(CurName,NewName)<>0) and (AComponent.Owner = Self) and + (FindComponent(NewName)<>Nil) then + raise EComponentError.Createfmt(SDuplicateName,[newname]); + If (csDesigning in FComponentState) and (FOwner<>Nil) then + FOwner.ValidateRename(AComponent,Curname,Newname); +end; + + +Procedure TComponent.ValidateContainer(AComponent: TComponent); + +begin + AComponent.ValidateInsert(Self); +end; + + +Procedure TComponent.ValidateInsert(AComponent: TComponent); + +begin + // Does nothing. +end; + + +Procedure TComponent.WriteState(Writer: TWriter); + +begin + Writer.WriteComponentData(Self); +end; + + +Constructor TComponent.Create(AOwner: TComponent); + +begin + FComponentStyle:=[csInheritable]; + If Assigned(AOwner) then AOwner.InsertComponent(Self); +end; + + +Destructor TComponent.Destroy; + +Var + I : Integer; + C : TComponent; + +begin + Destroying; + If Assigned(FFreeNotifies) then + begin + I:=FFreeNotifies.Count-1; + While (I>=0) do + begin + C:=TComponent(FFreeNotifies.Items[I]); + // Delete, so one component is not notified twice, if it is owned. + FFreeNotifies.Delete(I); + C.Notification (self,opRemove); + If (FFreeNotifies=Nil) then + I:=0 + else if (I>FFreeNotifies.Count) then + I:=FFreeNotifies.Count; + dec(i); + end; + FreeAndNil(FFreeNotifies); + end; + DestroyComponents; + If FOwner<>Nil Then FOwner.RemoveComponent(Self); + inherited destroy; +end; + + +Procedure TComponent.BeforeDestruction; +begin + if not(csDestroying in FComponentstate) then + Destroying; +end; + + +Procedure TComponent.DestroyComponents; + +Var acomponent: TComponent; + +begin + While assigned(FComponents) do + begin + aComponent:=TComponent(FComponents.Last); + Remove(aComponent); + Acomponent.Destroy; + end; +end; + + +Procedure TComponent.Destroying; + +Var Runner : longint; + +begin + If csDestroying in FComponentstate Then Exit; + include (FComponentState,csDestroying); + If Assigned(FComponents) then + for Runner:=0 to FComponents.Count-1 do + TComponent(FComponents.Items[Runner]).Destroying; +end; + + +function TComponent.ExecuteAction(Action: TBasicAction): Boolean; +begin + if Action.HandlesTarget(Self) then + begin + Action.ExecuteTarget(Self); + Result := True; + end + else + Result := False; +end; + + +Function TComponent.FindComponent(const AName: string): TComponent; + +Var I : longint; + +begin + Result:=Nil; + If (AName='') or Not assigned(FComponents) then exit; + For i:=0 to FComponents.Count-1 do + if (CompareText(TComponent(FComponents[I]).Name,AName)=0) then + begin + Result:=TComponent(FComponents.Items[I]); + exit; + end; +end; + +function tcomponent.findtagcomponent(const atag: int32; + const aclass: tcomponentclass): tcomponent; +var + i1: integer; + comp1: tcomponent; +begin + result:= nil; + for i1:= 0 to componentcount - 1 do begin + comp1:= components[i1]; + if (comp1.tag = atag) and + ((aclass = nil) or (comp1 is aclass)) then begin + result:= comp1; + exit; + end; + end; + if result = nil then begin + for i1:= 0 to componentcount - 1 do begin + result:= components[i1].findtagcomponent(atag,aclass); + if result <> nil then begin + exit; + end; + end; + end; +end; + +Procedure TComponent.FreeNotification(AComponent: TComponent); + +begin + If (Owner<>Nil) and (AComponent=Owner) then exit; + If not (Assigned(FFreeNotifies)) then + FFreeNotifies:=TFpList.Create; + If FFreeNotifies.IndexOf(AComponent)=-1 then + begin + FFreeNotifies.Add(AComponent); + AComponent.FreeNotification (self); + end; +end; + + +procedure TComponent.RemoveFreeNotification(AComponent: TComponent); +begin + RemoveNotification(AComponent); + AComponent.RemoveNotification (self); +end; + + +Procedure TComponent.FreeOnRelease; +begin + if Assigned(VCLComObject) then + IVCLComObject(VCLComObject).FreeOnRelease; +end; + + +Function TComponent.GetParentComponent: TComponent; + +begin + Result:=Nil; +end; + + +Function TComponent.HasParent: Boolean; + +begin + Result:=False; +end; + + +Procedure TComponent.InsertComponent(AComponent: TComponent); + +begin + AComponent.ValidateContainer(Self); + ValidateRename(AComponent,'',AComponent.FName); + Insert(AComponent); + AComponent.SetReference(True); + If csDesigning in FComponentState then + AComponent.SetDesigning(true); + Notification(AComponent,opInsert); +end; + + +Procedure TComponent.RemoveComponent(AComponent: TComponent); + +begin + Notification(AComponent,opRemove); + AComponent.SetReference(False); + Remove(AComponent); + Acomponent.Setdesigning(False); + ValidateRename(AComponent,AComponent.FName,''); +end; + + +Function TComponent.SafeCallException(ExceptObject: TObject; + ExceptAddr: Pointer): HResult; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).SafeCallException(ExceptObject, ExceptAddr) + else + Result := inherited SafeCallException(ExceptObject, ExceptAddr); +end; + +procedure TComponent.SetSubComponent(ASubComponent: Boolean); +begin + if ASubComponent then + Include(FComponentStyle, csSubComponent) + else + Exclude(FComponentStyle, csSubComponent); +end; + + +function TComponent.UpdateAction(Action: TBasicAction): Boolean; +begin + if Action.HandlesTarget(Self) then + begin + Action.UpdateTarget(Self); + Result := True; + end + else + Result := False; +end; + +{$ifdef FPC} +function TComponent.QueryInterface( +{$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; + out Obj): HResult;{$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).QueryInterface(IID, Obj) + else + if GetInterface(IID, Obj) then + Result := S_OK + else + Result := E_NOINTERFACE; +end; + +function TComponent._AddRef: Integer;{$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject)._AddRef + else + Result := -1; +end; + +function TComponent._Release: Integer;{$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject)._Release + else + Result := -1; +end; +{$endif} + +function TComponent.iicrGetComponent: TComponent; + +begin + result:=self; +end; + +function TComponent.GetTypeInfoCount(out Count: Integer): HResult; stdcall; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).GetTypeInfoCount(Count) + else + Result := E_NOTIMPL; +end; + +function TComponent.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).GetTypeInfo(Index, LocaleID, TypeInfo) + else + Result := E_NOTIMPL; +end; + +function TComponent.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, + LocaleID: Integer; DispIDs: Pointer): HResult; stdcall; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).GetIDsOfNames(IID, Names, NameCount, LocaleID, DispIDs) + else + Result := E_NOTIMPL; +end; + +function TComponent.Invoke(DispID: Integer; const IID: TGUID; + LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, + ArgErr: Pointer): HResult; stdcall; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).Invoke(DispID, IID, LocaleID, Flags, Params, + VarResult, ExcepInfo, ArgErr) + else + Result := E_NOTIMPL; +end; + +{****************************************************************************} +{* TStringsEnumerator *} +{****************************************************************************} + +constructor TStringsEnumerator.Create(AStrings: TStrings); +begin + inherited Create; + FStrings := AStrings; + FPosition := -1; +end; + +function TStringsEnumerator.GetCurrent: String; +begin + Result := FStrings[FPosition]; +end; + +function TStringsEnumerator.MoveNext: Boolean; +begin + Inc(FPosition); + Result := FPosition < FStrings.Count; +end; + +{****************************************************************************} +{* TStrings *} +{****************************************************************************} + +// Function to quote text. Should move maybe to sysutils !! +// Also, it is not clear at this point what exactly should be done. + +{ //!! is used to mark unsupported things. } + +Function QuoteString (Const S : String; Quote : String) : String; +Var + I,J : Integer; +begin + J:=0; + Result:=S; + for i:=1to length(s) do + begin + inc(j); + if S[i]=Quote then + begin + System.Insert(Quote,Result,J); + inc(j); + end; + end; + Result:=Quote+Result+Quote; +end; + +{ + For compatibility we can't add a Constructor to TSTrings to initialize + the special characters. Therefore we add a routine which is called whenever + the special chars are needed. +} + +Procedure Tstrings.CheckSpecialChars; + +begin + If Not FSpecialCharsInited then + begin + FQuoteChar:='"'; + FDelimiter:=','; + FNameValueSeparator:='='; + FSpecialCharsInited:=true; + FLBS:= ttextlinebreakstyle(DefaultTextLineBreakStyle); + end; +end; + +Function TStrings.GetLBS : TTextLineBreakStyle; +begin + CheckSpecialChars; + Result:=FLBS; +end; + +Procedure TStrings.SetLBS (AValue : TTextLineBreakStyle); +begin + CheckSpecialChars; + FLBS:=AValue; +end; + +procedure TStrings.SetDelimiter(c:Char); +begin + CheckSpecialChars; + FDelimiter:=c; +end; + + +procedure TStrings.SetQuoteChar(c:Char); +begin + CheckSpecialChars; + FQuoteChar:=c; +end; + +procedure TStrings.SetNameValueSeparator(c:Char); +begin + CheckSpecialChars; + FNameValueSeparator:=c; +end; + + +function TStrings.GetCommaText: string; + +Var + C1,C2 : Char; + FSD : Boolean; + +begin + CheckSpecialChars; + FSD:=StrictDelimiter; + C1:=Delimiter; + C2:=QuoteChar; + Delimiter:=','; + QuoteChar:='"'; + StrictDelimiter:=False; + Try + Result:=GetDelimitedText; + Finally + Delimiter:=C1; + QuoteChar:=C2; + StrictDelimiter:=FSD; + end; +end; + + +Function TStrings.GetDelimitedText: string; + +Var + I : integer; + p : pchar; + c : set of char; + S : String; + +begin + CheckSpecialChars; + result:=''; + if StrictDelimiter then + c:=[#0,Delimiter] + else + c:=[#0..' ',QuoteChar,Delimiter]; + For i:=0 to count-1 do + begin + S:=Strings[i]; + p:=pchar(S); + while not(p^ in c) do + inc(p); +// strings in list may contain #0 + if (p<>pchar(S)+length(S)) and not StrictDelimiter then + Result:=Result+QuoteString(S,QuoteChar) + else + Result:=Result+S; + if I0 then + begin + AName:=Copy(AValue,1,L-1); + System.Delete(AValue,1,L); + end + else + AName:=''; +end; + +function TStrings.ExtractName(const s:String):String; +var + L: Longint; +begin + CheckSpecialChars; + L:=Pos(FNameValueSeparator,S); + If L<>0 then + Result:=Copy(S,1,L-1) + else + Result:=''; +end; + +function TStrings.GetName(Index: Integer): string; + +Var + V : String; + +begin + GetNameValue(Index,Result,V); +end; + +Function TStrings.GetValue(const Name: string): string; + +Var + L : longint; + N : String; + +begin + Result:=''; + L:=IndexOfName(Name); + If L<>-1 then + GetNameValue(L,N,Result); +end; + +Function TStrings.GetValueFromIndex(Index: Integer): string; + +Var + N : String; + +begin + GetNameValue(Index,N,Result); +end; + +Procedure TStrings.SetValueFromIndex(Index: Integer; const Value: string); + +begin + If (Value='') then + Delete(Index) + else + begin + If (Index<0) then + Index:=Add(''); + CheckSpecialChars; + Strings[Index]:=GetName(Index)+FNameValueSeparator+Value; + end; +end; + +procedure TStrings.ReadData(Reader: TReader); +begin + Reader.ReadListBegin; + BeginUpdate; + try + Clear; + while not Reader.EndOfList do + Add(Reader.ReadString); + finally + EndUpdate; + end; + Reader.ReadListEnd; +end; + + +Procedure TStrings.SetDelimitedText(const AValue: string); +var i,j:integer; + aNotFirst:boolean; +begin + CheckSpecialChars; + BeginUpdate; + + i:=1; + j:=1; + aNotFirst:=false; + + try + Clear; + If StrictDelimiter then + begin + // Easier, faster loop. + While I<=Length(AValue) do + begin + If (AValue[I] in [FDelimiter,#0]) then + begin + Add(Copy(AValue,J,I-J)); + J:=I+1; + end; + Inc(i); + end; + If (Length(AValue)>0) then + Add(Copy(AValue,J,I-J)); + end + else + begin + while i<=length(AValue) do begin + // skip delimiter + if aNotFirst and (i<=length(AValue)) and (AValue[i]=FDelimiter) then inc(i); + + // skip spaces + while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i); + + // read next string + if i<=length(AValue) then begin + if AValue[i]=FQuoteChar then begin + // next string is quoted + j:=i+1; + while (j<=length(AValue)) and + ( (AValue[j]<>FQuoteChar) or + ( (j+1<=length(AValue)) and (AValue[j+1]=FQuoteChar) ) ) do begin + if (j<=length(AValue)) and (AValue[j]=FQuoteChar) then inc(j,2) + else inc(j); + end; + // j is position of closing quote + Add( StringReplace (Copy(AValue,i+1,j-i-1), + FQuoteChar+FQuoteChar,FQuoteChar, [rfReplaceAll])); + i:=j+1; + end else begin + // next string is not quoted + j:=i; + while (j<=length(AValue)) and + (Ord(AValue[j])>Ord(' ')) and + (AValue[j]<>FDelimiter) do inc(j); + Add( Copy(AValue,i,j-i)); + i:=j; + end; + end else begin + if aNotFirst then Add(''); + end; + + // skip spaces + while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i); + + aNotFirst:=true; + end; + end; + finally + EndUpdate; + end; +end; + +Procedure TStrings.SetCommaText(const Value: string); + +Var + C1,C2 : Char; + +begin + CheckSpecialChars; + C1:=Delimiter; + C2:=QuoteChar; + Delimiter:=','; + QuoteChar:='"'; + Try + SetDelimitedText(Value); + Finally + Delimiter:=C1; + QuoteChar:=C2; + end; +end; + + +Procedure TStrings.SetStringsAdapter(const Value: IStringsAdapter); + +begin +end; + + + +Procedure TStrings.SetValue(const Name, Value: string); + +Var L : longint; + +begin + CheckSpecialChars; + L:=IndexOfName(Name); + if L=-1 then + Add (Name+FNameValueSeparator+Value) + else + Strings[L]:=Name+FNameValueSeparator+value; +end; + + + +procedure TStrings.WriteData(Writer: TWriter); +var + i: Integer; +begin + Writer.WriteListBegin; + for i := 0 to Count - 1 do + Writer.WriteString(Strings[i]); + Writer.WriteListEnd; +end; + + + +procedure TStrings.DefineProperties(Filer: TFiler); +var + HasData: Boolean; +begin + if Assigned(Filer.Ancestor) then + // Only serialize if string list is different from ancestor + if Filer.Ancestor.InheritsFrom(TStrings) then + HasData := not Equals(TStrings(Filer.Ancestor)) + else + HasData := True + else + HasData := Count > 0; + Filer.DefineProperty('Strings', {$ifdef FPC}@{$endif}ReadData, + {$ifdef FPC}@{$endif}WriteData, HasData); +end; + + +Procedure TStrings.Error(const Msg: string; Data: Integer); +begin + Raise EStringListError.CreateFmt(Msg,[Data]) + {$ifdef FPC} at get_caller_addr(get_frame){$endif}; +end; + + +Procedure TStrings.Error(const Msg: pstring; Data: Integer); +begin + Raise EStringListError.CreateFmt(Msg^,[Data]) + {$ifdef FPC} at get_caller_addr(get_frame){$endif}; +end; + + +Function TStrings.GetCapacity: Integer; + +begin + Result:=Count; +end; + + + +Function TStrings.GetObject(Index: Integer): TObject; + +begin + Result:=Nil; +end; + + + +Function TStrings.GetTextStr: string; + +Var P : Pchar; + I,L,NLS : Longint; + S,NL : String; + +begin + nl:= ''; + CheckSpecialChars; + // Determine needed place + Case FLBS of + tlbsLF : NL:=#10; + tlbsCRLF : NL:=#13#10; + tlbsCR : NL:=#13; + end; + L:=0; + NLS:=Length(NL); + For I:=0 to count-1 do + L:=L+Length(Strings[I])+NLS; + Setlength(Result,L); + P:=Pointer(Result); + For i:=0 To count-1 do + begin + S:=Strings[I]; + L:=Length(S); + if L<>0 then + System.Move(Pointer(S)^,P^,L); + P:=P+L; + For L:=1 to NLS do + begin + P^:=NL[L]; + inc(P); + end; + end; +end; + + + +Procedure TStrings.Put(Index: Integer; const S: string); + +Var Obj : TObject; + +begin + Obj:=Objects[Index]; + Delete(Index); + InsertObject(Index,S,Obj); +end; + + + +Procedure TStrings.PutObject(Index: Integer; AObject: TObject); + +begin + // Empty. +end; + + + +Procedure TStrings.SetCapacity(NewCapacity: Integer); + +begin + // Empty. +end; + +Function GetNextLine (Const Value : String; Var S : String; Var P : Integer) : Boolean; + +Var + PS : PChar; + IP,L : Integer; + +begin + L:=Length(Value); + S:=''; + Result:=False; + If ((L-P)<0) then + exit; + if ((L-P)=0) and (not (value[P] in [#10,#13])) Then + Begin + s:=value[P]; + inc(P); + result:= true; + Exit; + End; + PS:=PChar(Value)+P-1; + IP:=P; + While ((L-P)>=0) and (not (PS^ in [#10,#13])) do + begin + P:=P+1; + Inc(PS); + end; + SetLength (S,P-IP); + System.Move (Value[IP],Pointer(S)^,P-IP); + If (P<=L) and (Value[P]=#13) then + Inc(P); + If (P<=L) and (Value[P]=#10) then + Inc(P); // Point to character after #10(#13) + Result:=True; +end; + +Procedure TStrings.SetTextStr(const Value: string); + +Var + S : String; + P : Integer; + +begin + Try + beginUpdate; + Clear; + P:=1; + While GetNextLine (Value,S,P) do + Add(S); + finally + EndUpdate; + end; +end; + +Procedure TStrings.SetUpdateState(Updating: Boolean); + +begin +// FPONotifyObservers(Self,ooChange,Nil); +end; + +destructor TSTrings.Destroy; + +begin + inherited destroy; +end; + + + +Function TStrings.Add(const S: string): Integer; + +begin + Result:=Count; + Insert (Count,S); +end; + + + +Function TStrings.AddObject(const S: string; AObject: TObject): Integer; + +begin + Result:=Add(S); + Objects[result]:=AObject; +end; + + + +Procedure TStrings.Append(const S: string); + +begin + Add (S); +end; + + + +Procedure TStrings.AddStrings(TheStrings: TStrings); + +Var Runner : longint; + +begin + try + beginupdate; + For Runner:=0 to TheStrings.Count-1 do + self.AddObject (Thestrings[Runner],TheStrings.Objects[Runner]); + finally + EndUpdate; + end; +end; + +Procedure TStrings.AddStrings(const TheStrings: array of string); + +Var Runner : longint; + +begin + try + beginupdate; + if Count + High(TheStrings)+1 > Capacity then + Capacity := Count + High(TheStrings)+1; + For Runner:=Low(TheStrings) to High(TheStrings) do + self.Add(Thestrings[Runner]); + finally + EndUpdate; + end; +end; + +Procedure TStrings.Assign(Source: TPersistent); + +Var + S : TStrings; + +begin + If Source is TStrings then + begin + S:=TStrings(Source); + BeginUpdate; + Try + clear; + FSpecialCharsInited:=S.FSpecialCharsInited; + FQuoteChar:=S.FQuoteChar; + FDelimiter:=S.FDelimiter; + FNameValueSeparator:=S.FNameValueSeparator; + FLBS:=S.FLBS; + AddStrings(S); + finally + EndUpdate; + end; + end + else + Inherited Assign(Source); +end; + + + +Procedure TStrings.BeginUpdate; + +begin + if FUpdateCount = 0 then SetUpdateState(true); + inc(FUpdateCount); +end; + + + +Procedure TStrings.EndUpdate; + +begin + If FUpdateCount>0 then + Dec(FUpdateCount); + if FUpdateCount=0 then + SetUpdateState(False); +end; + + + +Function TStrings.Equals(Obj: TObject): Boolean; + +begin + if Obj is TStrings then + Result := Equals(TStrings(Obj)) + else + Result := inherited Equals(Obj); +end; + + + +Function TStrings.Equals(TheStrings: TStrings): Boolean; + +Var Runner,Nr : Longint; + +begin + Result:=False; + Nr:=Self.Count; + if Nr<>TheStrings.Count then exit; + For Runner:=0 to Nr-1 do + If Strings[Runner]<>TheStrings[Runner] then exit; + Result:=True; +end; + + + +Procedure TStrings.Exchange(Index1, Index2: Integer); + +Var + Obj : TObject; + Str : String; + +begin + Try + beginUpdate; + Obj:=Objects[Index1]; + Str:=Strings[Index1]; + Objects[Index1]:=Objects[Index2]; + Strings[Index1]:=Strings[Index2]; + Objects[Index2]:=Obj; + Strings[Index2]:=Str; + finally + EndUpdate; + end; +end; + + +function TStrings.GetEnumerator: TStringsEnumerator; +begin + Result:=TStringsEnumerator.Create(Self); +end; + + +Function TStrings.GetText: PChar; +begin + Result:=StrNew(Pchar(Self.Text)); +end; + + +Function TStrings.DoCompareText(const s1,s2 : string) : PtrInt; + begin + result:=CompareText(s1,s2); + end; + + +Function TStrings.IndexOf(const S: string): Integer; +begin + Result:=0; + While (Result0) do Result:=Result+1; + if Result=Count then Result:=-1; +end; + + +Function TStrings.IndexOfName(const Name: string): Integer; +Var + len : longint; + S : String; +begin + CheckSpecialChars; + Result:=0; + while (Result0) and (DoCompareText(Name,Copy(S,1,Len))=0) then + exit; + inc(result); + end; + result:=-1; +end; + + +Function TStrings.IndexOfObject(AObject: TObject): Integer; +begin + Result:=0; + While (ResultAObject) do Result:=Result+1; + If Result=Count then Result:=-1; +end; + + +Procedure TStrings.InsertObject(Index: Integer; const S: string; + AObject: TObject); + +begin + Insert (Index,S); + Objects[Index]:=AObject; +end; + + + +Procedure TStrings.LoadFromFile(const FileName: string); +Var + TheStream : TFileStream; +begin + TheStream:=TFileStream.Create(FileName,fmOpenRead or fmShareDenyWrite); + try + LoadFromStream(TheStream); + finally + TheStream.Free; + end; +end; + + + +Procedure TStrings.LoadFromStream(Stream: TStream); +{ + Borlands method is no good, since a pipe for + instance doesn't have a size. + So we must do it the hard way. +} +Const + BufSize = 1024; + MaxGrow = 1 shl 29; + +Var + Buffer : AnsiString; + BytesRead, + BufLen, + I,BufDelta : Longint; +begin + // reread into a buffer + try + beginupdate; + Buffer:=''; + BufLen:=0; + I:=1; + Repeat + BufDelta:=BufSize*I; + SetLength(Buffer,BufLen+BufDelta); + BytesRead:=Stream.Read(Buffer[BufLen+1],BufDelta); + inc(BufLen,BufDelta); + If IBufDelta; + SetLength(Buffer, BufLen-BufDelta+BytesRead); + SetTextStr(Buffer); + SetLength(Buffer,0); + finally + EndUpdate; + end; +end; + + +Procedure TStrings.Move(CurIndex, NewIndex: Integer); +Var + Obj : TObject; + Str : String; +begin + BeginUpdate; + Obj:=Objects[CurIndex]; + Str:=Strings[CurIndex]; + Delete(Curindex); + InsertObject(NewIndex,Str,Obj); + EndUpdate; +end; + + + +Procedure TStrings.SaveToFile(const FileName: string); + +Var TheStream : TFileStream; + +begin + TheStream:=TFileStream.Create(FileName,fmCreate); + try + SaveToStream(TheStream); + finally + TheStream.Free; + end; +end; + + + +Procedure TStrings.SaveToStream(Stream: TStream); +Var + S : String; +begin + S:=Text; + if S = '' then Exit; + Stream.WriteBuffer(Pointer(S)^,Length(S)); +end; + + + + +Procedure TStrings.SetText(TheText: PChar); + +Var S : String; + +begin + If TheText<>Nil then + S:=StrPas(TheText) + else + S:=''; + SetTextStr(S); +end; + + +{****************************************************************************} +{* TStringList *} +{****************************************************************************} + + +Procedure TStringList.ExchangeItems(Index1, Index2: Integer); + +Var P1,P2 : Pointer; + +begin + P1:=Pointer(Flist^[Index1].FString); + P2:=Pointer(Flist^[Index1].FObject); + Pointer(Flist^[Index1].Fstring):=Pointer(Flist^[Index2].Fstring); + Pointer(Flist^[Index1].FObject):=Pointer(Flist^[Index2].FObject); + Pointer(Flist^[Index2].Fstring):=P1; + Pointer(Flist^[Index2].FObject):=P2; +end; + + + +Procedure TStringList.Grow; + +Var + NC : Integer; + +begin + NC:=FCapacity; + If NC>=256 then + NC:=NC+(NC Div 4) + else if NC=0 then + NC:=4 + else + NC:=NC*4; + SetCapacity(NC); +end; + +Procedure TStringList.InternalClear; + +Var + I: Integer; + +begin + if FOwnsObjects then + begin + For I:=0 to FCount-1 do + begin + Flist^[I].FString:=''; + freeandnil(Flist^[i].FObject); + end; + end + else + begin + For I:=0 to FCount-1 do + Flist^[I].FString:=''; + end; + FCount:=0; + SetCapacity(0); +end; + +Procedure TStringList.QuickSort(L, R: Integer; CompareFn: TStringListSortCompare); +var + Pivot, vL, vR: Integer; +begin + if R - L <= 1 then begin // a little bit of time saver + if L < R then + if CompareFn(Self, L, R) > 0 then + ExchangeItems(L, R); + + Exit; + end; + + vL := L; + vR := R; + + Pivot := L + Random(R - L); // they say random is best + + while vL < vR do begin + while (vL < Pivot) and (CompareFn(Self, vL, Pivot) <= 0) do + Inc(vL); + + while (vR > Pivot) and (CompareFn(Self, vR, Pivot) > 0) do + Dec(vR); + + ExchangeItems(vL, vR); + + if Pivot = vL then // swap pivot if we just hit it from one side + Pivot := vR + else if Pivot = vR then + Pivot := vL; + end; + + if Pivot - 1 >= L then + QuickSort(L, Pivot - 1, CompareFn); + if Pivot + 1 <= R then + QuickSort(Pivot + 1, R, CompareFn); +end; + + +Procedure TStringList.InsertItem(Index: Integer; const S: string); +begin + Changing; + If FCount=Fcapacity then Grow; + If IndexValue then + begin + If Value then sort; + FSorted:=VAlue + end; +end; + + + +Procedure TStringList.Changed; + +begin + If (FUpdateCount=0) Then + begin + If Assigned(FOnChange) then + FOnchange(Self); +// FPONotifyObservers(Self,ooChange,Nil); + end; +end; + + + +Procedure TStringList.Changing; + +begin + If FUpdateCount=0 then + if Assigned(FOnChanging) then + FOnchanging(Self); +end; + + + +Function TStringList.Get(Index: Integer): string; + +begin + If (Index<0) or (INdex>=Fcount) then + Error (SListIndexError,Index); + Result:=Flist^[Index].FString; +end; + + + +Function TStringList.GetCapacity: Integer; + +begin + Result:=FCapacity; +end; + + + +Function TStringList.GetCount: Integer; + +begin + Result:=FCount; +end; + + + +Function TStringList.GetObject(Index: Integer): TObject; + +begin + If (Index<0) or (INdex>=Fcount) then + Error (SListIndexError,Index); + Result:=Flist^[Index].FObject; +end; + + + +Procedure TStringList.Put(Index: Integer; const S: string); + +begin + If Sorted then + Error(SSortedListError,0); + If (Index<0) or (INdex>=Fcount) then + Error (SListIndexError,Index); + Changing; + Flist^[Index].FString:=S; + Changed; +end; + + + +Procedure TStringList.PutObject(Index: Integer; AObject: TObject); + +begin + If (Index<0) or (INdex>=Fcount) then + Error (SListIndexError,Index); + Changing; + Flist^[Index].FObject:=AObject; + Changed; +end; + + + +Procedure TStringList.SetCapacity(NewCapacity: Integer); + +Var NewList : Pointer; + MSize : Longint; + +begin + If (NewCapacity<0) then + Error (SListCapacityError,NewCapacity); + If NewCapacity>FCapacity then + begin + GetMem (NewList,NewCapacity*SizeOf(TStringItem)); + If NewList=Nil then + Error (SListCapacityError,NewCapacity); + If Assigned(FList) then + begin + MSize:=FCapacity*Sizeof(TStringItem); + System.Move (FList^,NewList^,MSize); + {$ifdef FPC} + FillWord (Pchar(NewList)[MSize],(NewCapacity-FCapacity)*WordRatio, 0); + {$else} + Fillchar(Pchar(NewList)[MSize],(NewCapacity-FCapacity)*sizeof(pointer),0); + {$endif} + FreeMem (Flist,MSize); + end; + Flist:=NewList; + FCapacity:=NewCapacity; + end + else if NewCapacity=FCount) then + Error(SlistINdexError,Index); + Changing; + Flist^[Index].FString:=''; + if FOwnsObjects then + FreeAndNil(Flist^[Index].FObject); + Dec(FCount); + If Index=FCount) then + Error(SListIndexError,Index1); + If (Index2<0) or (Index2>=FCount) then + Error(SListIndexError,Index2); + Changing; + ExchangeItems(Index1,Index2); + changed; +end; + + +procedure TStringList.SetCaseSensitive(b : boolean); + begin + if b<>FCaseSensitive then + begin + FCaseSensitive:=b; + if FSorted then + sort; + end; + end; + + +Function TStringList.DoCompareText(const s1,s2 : string) : PtrInt; + begin + if FCaseSensitive then + result:=AnsiCompareStr(s1,s2) + else + result:=AnsiCompareText(s1,s2); + end; + + +Function TStringList.Find(const S: string; Out Index: Integer): Boolean; + +var + L, R, I: Integer; + CompareRes: PtrInt; +begin + Result := false; + // Use binary search. + L := 0; + R := Count - 1; + while (L<=R) do + begin + I := L + (R - L) div 2; + CompareRes := DoCompareText(S, Flist^[I].FString); + if (CompareRes>0) then + L := I+1 + else begin + R := I-1; + if (CompareRes=0) then begin + Result := true; + if (Duplicates<>dupAccept) then + L := I; // forces end of while loop + end; + end; + end; + Index := L; +end; + + + +Function TStringList.IndexOf(const S: string): Integer; + +begin + If Not Sorted then + Result:=Inherited indexOf(S) + else + // faster using binary search... + If Not Find (S,Result) then + Result:=-1; +end; + + + +Procedure TStringList.Insert(Index: Integer; const S: string); + +begin + If Sorted then + Error (SSortedListError,0) + else + If (Index<0) or (Index>FCount) then + Error (SListIndexError,Index) + else + InsertItem (Index,S); +end; + + +Procedure TStringList.CustomSort(CompareFn: TStringListSortCompare); + +begin + If Not Sorted and (FCount>1) then + begin + Changing; + QuickSort(0,FCount-1, CompareFn); + Changed; + end; +end; + +function StringListAnsiCompare(List: TStringList; Index1, Index: Integer): Integer; + +begin + Result := List.DoCompareText(List.FList^[Index1].FString, + List.FList^[Index].FString); +end; + +Procedure TStringList.Sort; + +begin + CustomSort(@StringListAnsiCompare); +end; + +{****************************************************************************} +{* TStream *} +{****************************************************************************} + +procedure TStream.ReadNotImplemented; +begin + raise EStreamError.CreateFmt(SStreamNoReading, [ClassName]) + {$ifdef FPC} at get_caller_addr(get_frame){$endif}; +end; + +procedure TStream.WriteNotImplemented; +begin + raise EStreamError.CreateFmt(SStreamNoWriting, [ClassName]) + {$ifdef FPC} at get_caller_addr(get_frame){$endif}; +end; + +function TStream.Read(var Buffer; Count: Longint): Longint; +begin + ReadNotImplemented; + Result := 0; +end; + +function TStream.Write(const Buffer; Count: Longint): Longint; +begin + WriteNotImplemented; + Result := 0; +end; + + + function TStream.GetPosition: Int64; + + begin + Result:=Seek(0,soCurrent); + end; + + procedure TStream.SetPosition(const Pos: Int64); + + begin + Seek(pos,soBeginning); + end; + + procedure TStream.SetSize64(const NewSize: Int64); + + begin + // Required because can't use overloaded functions in properties + SetSize(NewSize); + end; + + function TStream.GetSize: Int64; + + var + p : int64; + + begin + p:=Seek(0,soCurrent); + GetSize:=Seek(0,soEnd); + Seek(p,soBeginning); + end; + + procedure TStream.SetSize(NewSize: Longint); + + begin + // We do nothing. Pipe streams don't support this + // As wel as possible read-ony streams !! + end; + + procedure TStream.SetSize(const NewSize: Int64); + + begin + // Backwards compatibility that calls the longint SetSize + if (NewSizeHigh(longint)) then + raise ERangeError.Create(SRangeError); + SetSize(longint(NewSize)); + end; + + function TStream.Seek(Offset: Longint; Origin: Word): Longint; + + type + TSeek64 = function(const offset:Int64;Origin:TSeekorigin):Int64 of object; + var + CurrSeek, + TStreamSeek : TSeek64; + CurrClass : TClass; + begin + // Redirect calls to 64bit Seek, but we can't call the 64bit Seek + // from TStream, because then we end up in an infinite loop + CurrSeek:=nil; + CurrClass:=Classtype; + while (CurrClass<>nil) and + (CurrClass<>TStream) do + CurrClass:=CurrClass.Classparent; + if CurrClass<>nil then + begin + CurrSeek:= {$ifdef FPC}@{$endif}Self.Seek; + TStreamSeek:={$ifdef FPC}@{$endif}TStream(@CurrClass).Seek; + if TMethod(TStreamSeek).Code=TMethod(CurrSeek).Code then + CurrSeek:=nil; + end; + if {$ifndef FPC}@{$endif}CurrSeek <> nil then + Result:=Seek(Int64(offset),TSeekOrigin(origin)) + else + raise EStreamError.CreateFmt(SSeekNotImplemented,[ClassName]); + end; + + procedure TStream.Discard(const Count: Int64); + + const + CSmallSize =255; + CLargeMaxBuffer =32*1024; // 32 KiB + var + Buffer: array[1..CSmallSize] of Byte; + + begin + if Count=0 then + Exit; + if Count<=SizeOf(Buffer) then + ReadBuffer(Buffer,Count) + else + DiscardLarge(Count,CLargeMaxBuffer); + end; + + procedure TStream.DiscardLarge(Count: int64; const MaxBufferSize: Longint); + + var + Buffer: array of Byte; + + begin + if Count=0 then + Exit; + if Count>MaxBufferSize then + SetLength(Buffer,MaxBufferSize) + else + SetLength(Buffer,Count); + while (Count>=Length(Buffer)) do + begin + ReadBuffer(Buffer[0],Length(Buffer)); + Dec(Count,Length(Buffer)); + end; + if Count>0 then + ReadBuffer(Buffer[0],Count); + end; + + procedure TStream.InvalidSeek; + + begin + raise EStreamError.CreateFmt(SStreamInvalidSeek, [ClassName]) + {$ifdef FPC} at get_caller_addr(get_frame){$endif}; + end; + + procedure TStream.FakeSeekForward(Offset: Int64; const Origin: TSeekOrigin; const Pos: Int64); + +// var +// Buffer: Pointer; +// BufferSize, i: LongInt; + + begin + if Origin=soBeginning then + Dec(Offset,Pos); + if (Offset<0) or (Origin=soEnd) then + InvalidSeek; + if Offset>0 then + Discard(Offset); + end; + + function TStream.Seek(const Offset: Int64; Origin: TSeekorigin): Int64; + + begin + // Backwards compatibility that calls the longint Seek + if (OffsetHigh(longint)) then + raise ERangeError.Create(SRangeError); + Result:=Seek(longint(Offset),ord(Origin)); + end; + +function tstream.seek(const offset: int64; const origin: tseekorigin; + out newpos: int64): syserrorty; +begin + newpos:= seek(offset,origin); + result:= sye_ok; + if newpos < 0 then begin + result:= sye_lasterror; + end; +end; + +function TStream.read(var buffer; const count: longint; + out acount: longint): syserrorty; +var + po1: pbyte; + int1,int2: integer; +begin + result:= sye_ok; + int2:= count; + po1:= @buffer; + repeat + int1:= read(po1^,int2); + if int1 <= 0 then begin + break; + end; + int2:= int2 - int1; + inc(po1,int1); + until int2 <= 0; + acount:= count - int2; + if int1 < 0 then begin + result:= syelasterror; + end + else begin + if (int2 > 0) then begin + result:= sye_read; + end; + end; +end; + +function TStream.tryreadbuffer(var buffer; count: longint): syserrorty; +var + int1: integer; +begin + result:= read(buffer,count,int1); +end; + +procedure TStream.ReadBuffer(var Buffer; Count: Longint); +begin + if tryreadbuffer(buffer,count) <> sye_ok then begin + Raise EReadError.Create(SReadError); + end; +end; + +function TStream.write(const buffer; const count: longint; + out acount: longint): syserrorty; +var + po1: pbyte; + int1,int2: integer; +begin + result:= sye_ok; + int2:= count; + po1:= @buffer; + repeat + int1:= write(po1^,int2); + if int1 <= 0 then begin + break; + end; + int2:= int2 - int1; + inc(po1,int1); + until int2 <= 0; + acount:= count - int2; + if int1 < 0 then begin + result:= syelasterror; + end + else begin + if (int2 > 0) then begin + result:= sye_write; + end; + end; +end; + +function TStream.trywritebuffer(const buffer; count: longint): syserrorty; +var + int1: integer; +begin + result:= write(buffer,count,int1); +end; + +procedure TStream.WriteBuffer(const Buffer; Count: Longint); +begin + if trywritebuffer(buffer,count) <> sye_ok then begin + Raise EWriteError.Create(SWriteError); + end; +end; + + function TStream.CopyFrom(Source: TStream; Count: Int64): Int64; + + var + Buffer: Pointer; + BufferSize, i: LongInt; + + const + MaxSize = $20000; + begin + + Result:=0; + if Count=0 then + Source.Position:=0; // This WILL fail for non-seekable streams... + BufferSize:=MaxSize; + if (Count>0) and (Count0 then + WriteBuffer(buffer^,i); + Inc(Result,i); + until i0 do + begin + if Count>BufferSize then + i:=BufferSize + else + i:=Count; + Source.ReadBuffer(buffer^,i); + WriteBuffer(buffer^,i); + Dec(count,i); + Inc(Result,i); + end; + finally + FreeMem(Buffer); + end; + + end; + +function TStream.readdatastring: string; +begin + setlength(result,size-position); + setlength(result,read(pointer(result)^,length(result))); +end; + +procedure TStream.writedatastring(const value: rawbytestring); +begin + if value <> '' then begin + writebuffer(pointer(value)^,length(value)); + end; +end; + + function TStream.ReadComponent(Instance: TComponent): TComponent; + + var + Reader: TReader; + + begin + + Reader := TReader.Create(Self, 4096); + try + Result := Reader.ReadRootComponent(Instance); + finally + Reader.Free; + end; + + end; + + function TStream.ReadComponentRes(Instance: TComponent): TComponent; + + begin + + ReadResHeader; + Result := ReadComponent(Instance); + + end; + + procedure TStream.WriteComponent(Instance: TComponent); + + begin + + WriteDescendent(Instance, nil); + + end; + + procedure TStream.WriteComponentRes(const ResName: string; Instance: TComponent); + + begin + + WriteDescendentRes(ResName, Instance, nil); + + end; + + procedure TStream.WriteDescendent(Instance, Ancestor: TComponent); + + var + Driver : TAbstractObjectWriter; + Writer : TWriter; + + begin + + Driver := TBinaryObjectWriter.Create(Self, 4096); + Try + Writer := TWriter.Create(Driver); + Try + Writer.WriteDescendent(Instance, Ancestor); + Finally + Writer.Destroy; + end; + Finally + Driver.Free; + end; + + end; + + procedure TStream.WriteDescendentRes(const ResName: string; Instance, Ancestor: TComponent); + + var + FixupInfo: Integer; + + begin + + { Write a resource header } + WriteResourceHeader(ResName, FixupInfo); + { Write the instance itself } + WriteDescendent(Instance, Ancestor); + { Insert the correct resource size into the resource header } + FixupResourceHeader(FixupInfo); + + end; + + procedure TStream.WriteResourceHeader(const ResName: string; {!!!: out} var FixupInfo: Integer); + var + ResType, Flags : word; + begin + ResType:=NtoLE(word($000A)); + Flags:=NtoLE(word($1030)); + { Note: This is a Windows 16 bit resource } + { Numeric resource type } + WriteByte($ff); + { Application defined data } + WriteWord(ResType); + { write the name as asciiz } + WriteBuffer(ResName[1],length(ResName)); + WriteByte(0); + { Movable, Pure and Discardable } + WriteWord(Flags); + { Placeholder for the resource size } + WriteDWord(0); + { Return current stream position so that the resource size can be + inserted later } + FixupInfo := Position; + end; + + procedure TStream.FixupResourceHeader(FixupInfo: Integer); + + var + ResSize,TmpResSize : Integer; + + begin + + ResSize := Position - FixupInfo; + TmpResSize := NtoLE(longword(ResSize)); + + { Insert the correct resource size into the placeholder written by + WriteResourceHeader } + Position := FixupInfo - 4; + WriteDWord(TmpResSize); + { Seek back to the end of the resource } + Position := FixupInfo + ResSize; + + end; + + procedure TStream.ReadResHeader; + var + ResType, Flags : word; + begin + try + { Note: This is a Windows 16 bit resource } + { application specific resource ? } + if ReadByte<>$ff then + raise EInvalidImage.Create(SInvalidImage); + ResType:=LEtoN(ReadWord); + if ResType<>$000a then + raise EInvalidImage.Create(SInvalidImage); + { read name } + while ReadByte<>0 do + ; + { check the access specifier } + Flags:=LEtoN(ReadWord); + if Flags<>$1030 then + raise EInvalidImage.Create(SInvalidImage); + { ignore the size } + ReadDWord; + except + on EInvalidImage do + raise; + else + raise EInvalidImage.create(SInvalidImage); + end; + end; + + function TStream.ReadByte : Byte; + + var + b : Byte; + + begin + ReadBuffer(b,1); + ReadByte:=b; + end; + + function TStream.ReadWord : Word; + + var + w : Word; + + begin + ReadBuffer(w,2); + ReadWord:=w; + end; + + function TStream.ReadDWord : Cardinal; + + var + d : Cardinal; + + begin + ReadBuffer(d,4); + ReadDWord:=d; + end; + + function TStream.ReadQWord: QWord; + var + q: QWord; + begin + ReadBuffer(q,8); + ReadQWord:=q; + + end; + + Function TStream.ReadAnsiString : String; + + Var + TheSize : Longint; + P : PByte ; + begin + ReadBuffer (TheSize,SizeOf(TheSize)); + SetLength(Result,TheSize); + // Illegal typecast if no AnsiStrings defined. + if TheSize>0 then + begin + ReadBuffer (Pointer(Result)^,TheSize); + P:= pointer(pchar(Pointer(Result))+TheSize); + p^:=0; + end; + end; + + Procedure TStream.WriteAnsiString (const S : String); + + Var L : Longint; + + begin + L:=Length(S); + WriteBuffer (L,SizeOf(L)); + WriteBuffer (Pointer(S)^,L); + end; + + procedure TStream.WriteByte(b : Byte); + + begin + WriteBuffer(b,1); + end; + + procedure TStream.WriteWord(w : Word); + + begin + WriteBuffer(w,2); + end; + + procedure TStream.WriteDWord(d : Cardinal); + + begin + WriteBuffer(d,4); + end; + + procedure TStream.WriteQWord(q: QWord); + begin + WriteBuffer(q,8); + end; + +function TStream.getmemory: pointer; +begin + result:= nil; +end; + + +{****************************************************************************} +{* TCustomMemoryStream *} +{****************************************************************************} + +procedure TCustomMemoryStream.SetPointer(Ptr: Pointer; ASize: PtrInt); + +begin + FMemory:=Ptr; + FSize:=ASize; +end; + + +function TCustomMemoryStream.GetSize: Int64; + +begin + Result:=FSize; +end; + +function TCustomMemoryStream.GetPosition: Int64; +begin + Result:=FPosition; +end; + + +function TCustomMemoryStream.Read(var Buffer; Count: LongInt): LongInt; + +begin + Result:=0; + If (FSize>0) and (FPosition=0) then + begin + Result:=FSize-FPosition; + If Result>Count then Result:=Count; + Move ((pchar(FMemory)+FPosition)^,Buffer,Result); + FPosition:=Fposition+Result; + end; +end; + + +function TCustomMemoryStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; + +begin + Case Word(Origin) of + soFromBeginning : FPosition:=Offset; + soFromEnd : FPosition:=FSize+Offset; + soFromCurrent : FPosition:=FPosition+Offset; + end; + Result:=FPosition; + {$IFDEF DEBUG} + if Result < 0 then + raise Exception.Create('TCustomMemoryStream'); + {$ENDIF} +end; + + +procedure TCustomMemoryStream.SaveToStream(Stream: TStream); + +begin + if FSize>0 then Stream.WriteBuffer (FMemory^,FSize); +end; + + +procedure TCustomMemoryStream.SaveToFile(const FileName: string); + +Var S : TFileStream; + +begin + S:=TFileStream.Create (FileName,fmCreate); + Try + SaveToStream(S); + finally + S.free; + end; +end; + +function TCustomMemoryStream.getmemory: pointer; +begin + result:= fmemory; +end; + +{****************************************************************************} +{* TMemoryStream *} +{****************************************************************************} + + +Const TMSGrow = 4096; { Use 4k blocks. } + +procedure TMemoryStream.SetCapacity(NewCapacity: PtrInt); + +begin + SetPointer (Realloc(NewCapacity),Fsize); + FCapacity:=NewCapacity; +end; + +function TMemoryStream.getcapacity: ptrint; +begin + result:= fcapacity; +end; + +function tmemorystream.Realloc(var NewCapacity: PtrInt): Pointer; +var + i1: ptrint; +begin + If NewCapacity < 0 Then begin + NewCapacity:=0 + end + else begin + if newcapacity > fcapacity then begin + if newcapacity > tmsgrow then begin + // if growing, grow at least a quarter + i1:= FCapacity + fcapacity div 4; + if NewCapacity < i1 then begin + NewCapacity:= i1; // round off to block size. + end; + NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1); + end + else begin + newcapacity:= newcapacity * 2 + 32; + end; + end; + end; + // Only now check ! + If NewCapacity = FCapacity then begin + Result:= FMemory + end + else begin + Result:= Reallocmem(FMemory,Newcapacity); + If (Result = Nil) and (Newcapacity > 0) then begin + Raise EStreamError.Create(SMemoryStreamError); + end; + end; +end; + +(* +function TMemoryStream.Realloc(var NewCapacity: PtrInt): Pointer; + +begin + If NewCapacity<0 Then + NewCapacity:=0 + else + begin + // if growing, grow at least a quarter + if (NewCapacity>FCapacity) and (NewCapacity < (5*FCapacity) div 4) then + NewCapacity := (5*FCapacity) div 4; + // round off to block size. + NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1); + end; + // Only now check ! + If NewCapacity=FCapacity then + Result:=FMemory + else + begin + {$ifdef FPC} + Result:= Reallocmem(FMemory,Newcapacity); + {$else} + Reallocmem(FMemory,Newcapacity); + result:= fmemory; + {$endif} + If (Result=Nil) and (Newcapacity>0) then + Raise EStreamError.Create(SMemoryStreamError); + end; +end; +*) + +destructor TMemoryStream.Destroy; + +begin + Clear; + Inherited Destroy; +end; + + +procedure TMemoryStream.Clear; + +begin + FSize:=0; + FPosition:=0; + SetCapacity (0); +end; + + +procedure TMemoryStream.LoadFromStream(Stream: TStream); + +begin + Stream.Position:=0; + SetSize(Stream.Size); + If FSize>0 then Stream.ReadBuffer(FMemory^,FSize); +end; + + +procedure TMemoryStream.LoadFromFile(const FileName: string); + +Var S : TFileStream; + +begin + S:=TFileStream.Create (FileName,fmOpenRead or fmShareDenyWrite); + Try + LoadFromStream(S); + finally + S.free; + end; +end; + + +procedure TMemoryStream.SetSize({$ifdef CPU64}const{$endif CPU64} NewSize: PtrInt); + +begin + SetCapacity (NewSize); + FSize:=NewSize; + IF FPosition>FSize then + FPosition:=FSize; +end; + +function TMemoryStream.Write(const Buffer; Count: LongInt): LongInt; + +Var NewPos : PtrInt; + +begin + If (Count=0) or (FPosition<0) then begin + result:= 0; + exit; + end; + NewPos:=FPosition+Count; + If NewPos>Fsize then + begin + IF NewPos>FCapacity then + SetCapacity (NewPos); + FSize:=Newpos; + end; + System.Move (Buffer,(pchar(FMemory)+FPosition)^,Count); + FPosition:=NewPos; + Result:=Count; +end; + +{****************************************************************************} +{* TBinaryObjectReader *} +{****************************************************************************} + +{$ifndef FPUNONE} +{$IFNDEF FPC_HAS_TYPE_EXTENDED} +function ExtendedToDouble(e : pointer) : double; +var mant : qword; + exp : smallint; + sign : boolean; + d : qword; +begin + move(pbyte(e)[0],mant,8); //mantissa : bytes 0..7 + move(pbyte(e)[8],exp,2); //exponent and sign: bytes 8..9 + mant:=LEtoN(mant); + exp:=LEtoN(word(exp)); + sign:=(exp and $8000)<>0; + if sign then begin + exp:=exp and $7FFF; + end; + case exp of + 0: begin + mant:= 0; //if denormalized, value is too small for double, + //so it's always zero + end; + $7FFF: begin + exp:=2047; //either infinity or NaN + if mant and $3fffffffffffffff = 0 then begin + mant:= 0; //infinity + end; + end + else begin + dec(exp,16383-1023); + if (exp>=-51) and (exp<=0) then begin //can be denormalized + mant:=mant shr (-exp); + exp:=0; + end + else begin + if (exp<-51) or (exp>2046) then begin //exponent too large. + Result:=0; + exit; + end + else begin //normalized value + mant:=mant shl 1; //hide most significant bit + end; + end; + end; + end; + d:=word(exp); + d:=d shl 52; + + mant:=mant shr 12; + d:=d or mant; + if sign then d:=d or $8000000000000000; + Result:=pdouble(@d)^; +end; +{$ENDIF} +{$endif} + +function TBinaryObjectReader.ReadWord : word; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin + Read(Result,2); + Result:=LEtoN(Result); +end; + +function TBinaryObjectReader.ReadDWord : longword; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin + Read(Result,4); + Result:=LEtoN(Result); +end; + +function TBinaryObjectReader.ReadQWord : qword; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin + Read(Result,8); + {$ifdef FPC} + Result:=LEtoN(Result); + {$endif} +end; + +{$IFDEF FPC_DOUBLE_HILO_SWAPPED} +procedure SwapDoubleHiLo(var avalue: double); {$ifdef CLASSESINLINE}inline{$endif CLASSESINLINE} +var dwo1 : dword; +type tdoublerec = array[0..1] of dword; +begin + dwo1:= tdoublerec(avalue)[0]; + tdoublerec(avalue)[0]:=tdoublerec(avalue)[1]; + tdoublerec(avalue)[1]:=dwo1; +end; +{$ENDIF FPC_DOUBLE_HILO_SWAPPED} + +{$ifndef FPUNONE} +function TBinaryObjectReader.ReadExtended : extended; + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$IFNDEF FPC_HAS_TYPE_EXTENDED} +var ext : array[0..9] of byte; +{$ENDIF} +begin + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + Read(ext[0],10); + Result:=ExtendedToDouble(@(ext[0])); + {$IFDEF FPC_DOUBLE_HILO_SWAPPED} + SwapDoubleHiLo(result); + {$ENDIF} + {$ELSE} + Read(Result,sizeof(Result)); + {$ENDIF} +end; +{$endif} + +constructor TBinaryObjectReader.Create(Stream: TStream; BufSize: Integer); +begin + inherited Create; + If (Stream=Nil) then + Raise EReadError.Create(SEmptyStreamIllegalReader); + FStream := Stream; + FBufSize := BufSize; + GetMem(FBuffer, BufSize); +end; + +destructor TBinaryObjectReader.Destroy; +begin + { Seek back the amount of bytes that we didn't process until now: } + FStream.Seek(Integer(FBufPos) - Integer(FBufEnd), soFromCurrent); + + if Assigned(FBuffer) then + FreeMem(FBuffer, FBufSize); + + inherited Destroy; +end; + +function TBinaryObjectReader.ReadValue: TValueType; +var + b: byte; +begin + Read(b, 1); + Result := TValueType(b); +end; + +function TBinaryObjectReader.NextValue: TValueType; +begin + Result := ReadValue; + { We only 'peek' at the next value, so seek back to unget the read value: } + Dec(FBufPos); +end; + +procedure TBinaryObjectReader.BeginRootComponent; +var + Signature: LongInt; +begin + { Read filer signature } + Read(Signature, 4); + {$ifdef FPC} + if Signature <> LongInt(unaligned(FilerSignature)) then + {$else} + if Signature <> LongInt(FilerSignature) then + {$endif} + raise EReadError.Create(SInvalidImage); +end; + +procedure TBinaryObjectReader.BeginComponent(var Flags: TFilerFlags; + var AChildPos: Integer; var CompClassName, CompName: String); +var + Prefix: Byte; + ValueType: TValueType; +begin + { Every component can start with a special prefix: } + Flags := []; + if (Byte(NextValue) and $f0) = $f0 then + begin + Prefix := Byte(ReadValue); + Flags := TFilerFlags({$ifdef FPC}longword{$else}byte{$endif}(Prefix and $0f)); + if ffChildPos in Flags then + begin + ValueType := ReadValue; + case ValueType of + vaInt8: + AChildPos := ReadInt8; + vaInt16: + AChildPos := ReadInt16; + vaInt32: + AChildPos := ReadInt32; + else + raise EReadError.Create(SInvalidPropertyValue); + end; + end; + end; + + CompClassName := ReadStr; + CompName := ReadStr; +end; + +function TBinaryObjectReader.BeginProperty: String; +begin + Result := ReadStr; +end; + +procedure TBinaryObjectReader.ReadBinary(const DestData: TMemoryStream); +var + BinSize: LongInt; +begin + BinSize:=LongInt(ReadDWord); + DestData.Size := BinSize; + Read(DestData.Memory^, BinSize); +end; + +{$ifndef FPUNONE} +function TBinaryObjectReader.ReadFloat: Extended; +begin + Result:= ReadExtended; +end; + +function TBinaryObjectReader.ReadSingle: Single; +begin +{$ifdef FPC} + Result:= single(ReadDWord); +{$else} + Result:= single(ar4ty(ReadDWord())); +{$endif} +end; +{$endif} + +function TBinaryObjectReader.ReadCurrency: Currency; +begin + {$ifdef FPC} + Result:=currency(ReadQWord); + {$else} + Result:=currency(ar8ty(ReadQWord())); + {$endif} +end; + +{$ifndef FPUNONE} +function TBinaryObjectReader.ReadDate: TDateTime; +begin + {$ifdef FPC} + Result:= TDateTime(ReadQWord); + {$else} + Result:= TDateTime(ar8ty(ReadQWord())); + {$endif} +end; +{$endif} + +function TBinaryObjectReader.ReadIdent(ValueType: TValueType): String; +var + i: Byte; +begin + result:= ''; + case ValueType of + vaIdent: + begin + Read(i, 1); + SetLength(Result, i); + Read(Pointer(@Result[1])^, i); + end; + vaNil: + Result := 'nil'; + vaFalse: + Result := 'False'; + vaTrue: + Result := 'True'; + vaNull: + Result := 'Null'; + end; +end; + +function TBinaryObjectReader.ReadInt8: ShortInt; +begin + Read(Result, 1); +end; + +function TBinaryObjectReader.ReadInt16: SmallInt; +begin + Result:=SmallInt(ReadWord); +end; + +function TBinaryObjectReader.ReadInt32: LongInt; +begin + Result:=LongInt(ReadDWord); +end; + +function TBinaryObjectReader.ReadInt64: Int64; +begin + Result:=Int64(ReadQWord); +end; + +function TBinaryObjectReader.ReadSet(EnumType: ptypeinfo): Integer; +type + tset = set of 0..31; +var + Name: String; + Value: Integer; +begin + try + Result := 0; + while True do + begin + Name := ReadStr; + if Length(Name) = 0 then + break; + Value := GetEnumValue(PTypeInfo(EnumType), Name); + if Value = -1 then begin + if (freader <> nil) and assigned(freader.fonseterror) then begin + freader.fonseterror(freader,enumtype,name,value); + end; + if value = -1 then begin + raise EReadError.Create(SInvalidPropertyValue); + end + else begin + if value = -2 then begin + continue; //skip + end; + end; + end; + include(tset(result),Value); + end; + except + SkipSetBody; + raise; + end; +end; + +function TBinaryObjectReader.ReadStr: String; +var + i: Byte; +begin + Read(i, 1); + SetLength(Result, i); + if i > 0 then + Read(Pointer(@Result[1])^, i); +end; + +function TBinaryObjectReader.ReadString(StringType: TValueType): String; +var + b: Byte; + i: Integer; +begin + case StringType of + vaLString, vaUTF8String: + i:=ReadDWord; + else + //vaString: + begin + Read(b, 1); + i := b; + end; + end; + SetLength(Result, i); + if i > 0 then + Read(Pointer(@Result[1])^, i); +end; + +function TBinaryObjectReader.Readutf8String(StringType: TValueType): utf8String; +var + b: Byte; + i: Integer; +begin + case StringType of + vaLString, vaUTF8String: + i:=ReadDWord; + else + //vaString: + begin + Read(b, 1); + i := b; + end; + end; + SetLength(Result, i); + if i > 0 then + Read(Pointer(@Result[1])^, i); +end; + + +function TBinaryObjectReader.ReadWideString: WideString; +var + len: DWord; +{$IFDEF ENDIAN_BIG} + i : integer; +{$ENDIF} +begin + len := ReadDWord; + SetLength(Result, len); + if (len > 0) then + begin + Read(Pointer(@Result[1])^, len*2); + {$IFDEF ENDIAN_BIG} + for i:=1 to len do + Result[i]:=widechar(SwapEndian(word(Result[i]))); + {$ENDIF} + end; +end; + +function TBinaryObjectReader.ReadUnicodeString: UnicodeString; +var + len: DWord; +{$IFDEF ENDIAN_BIG} + i : integer; +{$ENDIF} +begin + len := ReadDWord; + SetLength(Result, len); + if (len > 0) then + begin + Read(Pointer(@Result[1])^, len*2); + {$IFDEF ENDIAN_BIG} + for i:=1 to len do + Result[i]:=UnicodeChar(SwapEndian(word(Result[i]))); + {$ENDIF} + end; +end; + +procedure TBinaryObjectReader.SkipComponent(SkipComponentInfos: Boolean); +var + Flags: TFilerFlags; + Dummy: Integer; + CompClassName, CompName: String; +begin + if SkipComponentInfos then + { Skip prefix, component class name and component object name } + BeginComponent(Flags, Dummy, CompClassName, CompName); + + { Skip properties } + while NextValue <> vaNull do + SkipProperty; + ReadValue; + + { Skip children } + while NextValue <> vaNull do + SkipComponent(True); + ReadValue; +end; + +procedure TBinaryObjectReader.SkipValue; + + procedure SkipBytes(Count: LongInt); + var + Dummy: array[0..1023] of Byte; + SkipNow: Integer; + begin + while Count > 0 do + begin + if Count > 1024 then + SkipNow := 1024 + else + SkipNow := Count; + Read(Dummy, SkipNow); + Dec(Count, SkipNow); + end; + end; + +var + Count: LongInt; +begin + case ReadValue of + vaNull, vaFalse, vaTrue, vaNil: ; + vaList: + begin + while NextValue <> vaNull do + SkipValue; + ReadValue; + end; + vaInt8: + SkipBytes(1); + vaInt16: + SkipBytes(2); + vaInt32: + SkipBytes(4); + vaExtended: + SkipBytes(10); + vaString, vaIdent: + ReadStr; + vaBinary, vaLString,vautf8string: + begin + Count:=LongInt(ReadDWord); + SkipBytes(Count); + end; + vaWString: + begin + Count:=LongInt(ReadDWord); + SkipBytes(Count*sizeof(widechar)); + end; +{$ifdef FPC} + vaUString: + begin + Count:=LongInt(ReadDWord); + SkipBytes(Count*sizeof(widechar)); + end; +{$endif} + vaSet: + SkipSetBody; + vaCollection: + begin + while NextValue <> vaNull do + begin + { Skip the order value if present } + if NextValue in [vaInt8, vaInt16, vaInt32] then + SkipValue; + SkipBytes(1); + while NextValue <> vaNull do + SkipProperty; + ReadValue; + end; + ReadValue; + end; + vaSingle: +{$ifndef FPUNONE} + SkipBytes(Sizeof(Single)); +{$else} + SkipBytes(4); +{$endif} + {!!!: vaCurrency: + SkipBytes(SizeOf(Currency));} + vaDate, vaInt64: + SkipBytes(8); + end; +end; + +{ private methods } + +procedure TBinaryObjectReader.Read(var Buf; Count: LongInt); +var + CopyNow: LongInt; + Dest: Pointer; +begin + Dest := @Buf; + while Count > 0 do + begin + if FBufPos >= FBufEnd then + begin + FBufEnd := FStream.Read(FBuffer^, FBufSize); + if FBufEnd = 0 then + raise EReadError.Create(SReadError); + FBufPos := 0; + end; + CopyNow := FBufEnd - FBufPos; + if CopyNow > Count then + CopyNow := Count; + Move(PChar(FBuffer)[FBufPos], Dest^, CopyNow); + Inc(FBufPos, CopyNow); + Inc(pchar(Dest), CopyNow); + Dec(Count, CopyNow); + end; +end; + +procedure TBinaryObjectReader.SkipProperty; +begin + { Skip property name, then the property value } + ReadStr; + SkipValue; +end; + +procedure TBinaryObjectReader.SkipSetBody; +begin + while Length(ReadStr) > 0 do; +end; + +{ Object filing routines } + +var + IntConstList: TThreadList; + +type + TIntConst = class + IntegerType: PTypeInfo; // The integer type RTTI pointer + IdentToIntFn: TIdentToInt; // Identifier to Integer conversion + IntToIdentFn: TIntToIdent; // Integer to Identifier conversion + constructor Create(AIntegerType: PTypeInfo; AIdentToInt: TIdentToInt; + AIntToIdent: TIntToIdent); + end; + +constructor TIntConst.Create(AIntegerType: PTypeInfo; AIdentToInt: TIdentToInt; + AIntToIdent: TIntToIdent); +begin + IntegerType := AIntegerType; + IdentToIntFn := AIdentToInt; + IntToIdentFn := AIntToIdent; +end; + +procedure RegisterIntegerConsts(IntegerType: Pointer; IdentToIntFn: TIdentToInt; + IntToIdentFn: TIntToIdent); +begin + IntConstList.Add(TIntConst.Create(IntegerType, IdentToIntFn, IntToIdentFn)); +end; + +function FindIntToIdent(AIntegerType: Pointer): TIntToIdent; +var + i: Integer; +begin + with IntConstList.LockList do + try + for i := 0 to Count - 1 do + if TIntConst(Items[i]).IntegerType = AIntegerType then begin + result:= TIntConst(Items[i]).IntToIdentFn; + exit; + end; + Result := nil; + finally + IntConstList.UnlockList; + end; +end; + +function FindIdentToInt(AIntegerType: Pointer): TIdentToInt; +var + i: Integer; +begin + with IntConstList.LockList do + try + for i := 0 to Count - 1 do + with TIntConst(Items[I]) do + if TIntConst(Items[I]).IntegerType = AIntegerType then begin + result:= IdentToIntFn; + exit; + end; + Result := nil; + finally + IntConstList.UnlockList; + end; +end; + +function IdentToInt(const Ident: String; var Int: LongInt; + const Map: array of TIdentMapEntry): Boolean; +var + i: Integer; +begin + for i := Low(Map) to High(Map) do + if CompareText(Map[i].Name, Ident) = 0 then + begin + Int := Map[i].Value; + result:= true; + exit; + end; + Result := False; +end; + +function IntToIdent(Int: LongInt; var Ident: String; + const Map: array of TIdentMapEntry): Boolean; +var + i: Integer; +begin + for i := Low(Map) to High(Map) do + if Map[i].Value = Int then + begin + Ident := Map[i].Name; + result:= true; + exit; + end; + Result := False; +end; + +function GlobalIdentToInt(const Ident: String; var Int: LongInt):boolean; +var + i : Integer; +begin + with IntConstList.LockList do + try + for i := 0 to Count - 1 do + if TIntConst(Items[I]).IdentToIntFn(Ident, Int) then begin + result:= true; + Exit; + end; + Result := false; + finally + IntConstList.UnlockList; + end; +end; + +Var + InitHandlerList : TList; + FindGlobalComponentList : TList; + +Type + TInitHandler = Class(TObject) + AHandler : TInitComponentHandler; + AClass : TComponentClass; + end; +{$ifdef FPC} +function CreateComponentfromRes(const res : string;Inst : THandle;var Component : TComponent) : Boolean; + var + ResStream : TResourceStream; + begin + result:=true; + + if Inst=0 then + Inst:=HInstance; + + try + ResStream:=TResourceStream.Create(Inst,res,RT_RCDATA); + try + Component:=ResStream.ReadComponent(Component); + finally + ResStream.Free; + end; + except + on EResNotFound do + result:=false; + end; + end; +{$endif} + +function DefaultInitHandler(Instance: TComponent; RootAncestor: TClass): Boolean; + + function doinit(_class : TClass) : boolean; + begin + result:=false; + if (_class{.ClassType}=TComponent) or (_class{.ClassType}=RootAncestor) then + exit; + result:=doinit(_class.ClassParent); + {$ifdef FPC} + result:=CreateComponentfromRes(_class.ClassName,0,Instance) or result; + {$endif} + end; + + begin + GlobalNameSpace.BeginWrite; + try + result:=doinit(Instance.ClassType); + finally + GlobalNameSpace.EndWrite; + end; + end; + +function InitInheritedComponent(Instance: TComponent; RootAncestor: TClass): Boolean; +Var + I : Integer; +begin + I:=0; + if not Assigned(InitHandlerList) then begin + Result := True; + Exit; + end; + Result:=False; + With InitHandlerList do + begin + I:=0; + // Instance is the normally the lowest one, so that one should be used when searching. + While Not result and (INil); + If Result then + begin + C:=FindNestedComponent(C,FRelative); + Result:=C<>Nil; + If Result then + SetObjectProp(Instance, FPropInfo,C); + end; +end; + +Function TUnresolvedReference.RootMatches(ARoot : TComponent) : Boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + +begin + Result:=(ARoot=Nil) or (ARoot=FRoot); +end; + +Function TUnResolvedReference.NextRef : TUnresolvedReference; + +begin + Result:=TUnresolvedReference(Next); +end; + +{ tfixups } + +constructor tfixups.create; +begin + inherited create(TUnresolvedReference); +end; + +function tfixups.newreference(const aprop: ppropinfo): TUnResolvedReference; +begin + result:= tunresolvedreference(root); + while result <> nil do begin + if (result.fpropinfo = aprop) then begin + exit; + end; + result:= tunresolvedreference(result.next); + end; + result:= tunresolvedreference(add); +end; + +{ tlocalfixups } + +constructor tlocalfixups.create; +begin + inherited create(TLocalUnresolvedReference); +end; + +function tlocalfixups.newreference(const ainstance: tpersistent; + const aprop: ppropinfo): TLocalUnResolvedReference; +begin + result:= tlocalunresolvedreference(root); + while result <> nil do begin + if ((result.finstance) = ainstance) and (result.fpropinfo = aprop) then begin + exit; + end; + result:= tlocalunresolvedreference(result.next); + end; + result:= tlocalunresolvedreference(add); +end; + +{ TUnResolvedInstance } + +destructor TUnResolvedInstance.Destroy; +begin + FUnresolved.Free; + inherited Destroy; +end; + +function TUnResolvedInstance.AddReference(ARoot: TComponent; + APropInfo: PPropInfo; AGlobal, ARelative: String): TUnresolvedReference; +begin + If (FUnResolved = Nil) then begin + FUnResolved:= tfixups.create; + end; + Result:= FUnResolved.newreference(apropinfo); + Result.FGlobal:=AGLobal; + Result.FRelative:=ARelative; + Result.FPropInfo:=APropInfo; + Result.FRoot:=ARoot; +end; + +Function TUnResolvedInstance.RootUnresolved : TUnresolvedReference; + +begin + Result:=Nil; + If Assigned(FUnResolved) then + Result:=TUnresolvedReference(FUnResolved.Root); +end; + +Function TUnResolvedInstance.ResolveReferences:Boolean; + +Var + R,RN : TUnresolvedReference; + +begin + R:=RootUnResolved; + While (R<>Nil) do + begin + RN:=R.NextRef; + If R.Resolve(Self.Instance) then + FUnresolved.RemoveItem(R,True); + R:=RN; + end; + Result:=RootUnResolved=Nil; +end; + +{ TReferenceNamesVisitor } + +Constructor TReferenceNamesVisitor.Create(ARoot : TComponent;AList : TStrings); + +begin + FRoot:=ARoot; + FList:=AList; +end; + +Function TReferenceNamesVisitor.Visit(Item : TLinkedListItem) : Boolean; + +Var + R : TUnresolvedReference; + +begin + R:=TUnResolvedInstance(Item).RootUnresolved; + While (R<>Nil) do + begin + If R.RootMatches(FRoot) then + If (FList.IndexOf(R.FGlobal)=-1) then + FList.Add(R.FGlobal); + R:=R.NextRef; + end; + Result:=True; +end; + +{ TReferenceInstancesVisitor } + +Constructor TReferenceInstancesVisitor.Create(ARoot : TComponent; Const ARef : String;AList : TStrings); + +begin + FRoot:=ARoot; + FRef:=UpperCase(ARef); + FList:=AList; +end; + +Function TReferenceInstancesVisitor.Visit(Item : TLinkedListItem) : Boolean; + +Var + R : TUnresolvedReference; + +begin + R:=TUnResolvedInstance(Item).RootUnresolved; + While (R<>Nil) do + begin + If (FRoot=R.FRoot) and (FRef=UpperCase(R.FGLobal)) Then + If Flist.IndexOf(R.FRelative)=-1 then + Flist.Add(R.FRelative); + R:=R.NextRef; + end; + Result:=True; +end; + +{ TRedirectReferenceVisitor } + +Constructor TRedirectReferenceVisitor.Create(ARoot : TComponent; Const AOld,ANew : String); + +begin + FRoot:=ARoot; + FOld:=UpperCase(AOld); + FNew:=ANew; +end; + +Function TRedirectReferenceVisitor.Visit(Item : TLinkedListItem) : Boolean; + +Var + R : TUnresolvedReference; + +begin + R:=TUnResolvedInstance(Item).RootUnresolved; + While (R<>Nil) do + begin + If R.RootMatches(FRoot) and (FOld=UpperCase(R.FGLobal)) Then + R.FGlobal:=FNew; + R:=R.NextRef; + end; + Result:=True; +end; + +{ TRemoveReferenceVisitor } + +Constructor TRemoveReferenceVisitor.Create(ARoot : TComponent; Const ARef : String); + +begin + FRoot:=ARoot; + FRef:=UpperCase(ARef); +end; + +Function TRemoveReferenceVisitor.Visit(Item : TLinkedListItem) : Boolean; + +Var + I : Integer; + UI : TUnResolvedInstance; + R : TUnresolvedReference; + L : TFPList; + +begin + UI:=TUnResolvedInstance(Item); + R:=UI.RootUnresolved; + L:=Nil; + Try + // Collect all matches. + While (R<>Nil) do + begin + If R.RootMatches(FRoot) and ((FRef = '') or (FRef=UpperCase(R.FGLobal))) Then + begin + If Not Assigned(L) then + L:=TFPList.Create; + L.Add(R); + end; + R:=R.NextRef; + end; + // Remove all matches. + IF Assigned(L) then + begin + For I:=0 to L.Count-1 do + UI.FUnresolved.RemoveItem(TLinkedListitem(L[i]),True); + end; + // If any references are left, leave them. + If UI.FUnResolved.Root=Nil then + begin + If List=Nil then + List:=TFPList.Create; + List.Add(UI); + end; + Finally + L.Free; + end; + Result:=True; +end; + +{ TBuildListVisitor } + +Procedure TBuildListVisitor.Add(Item : TlinkedListItem); + +begin + If (List=Nil) then + List:=TFPList.Create; + List.Add(Item); +end; + +Destructor TBuildListVisitor.Destroy; + +Var + I : Integer; + +begin + If Assigned(List) then + For I:=0 to List.Count-1 do + NeedResolving.RemoveItem(TLinkedListItem(List[I]),True); + FreeAndNil(List); + Inherited; +end; + +{ TResolveReferenceVisitor } + +Function TResolveReferenceVisitor.Visit(Item : TLinkedListItem) : Boolean; + +begin + If TUnResolvedInstance(Item).ResolveReferences then + Add(Item); + Result:=True; +end; + +// Add an instance to the global list of instances which need resolving. +Function FindUnresolvedInstance(AInstance: TPersistent) : TUnResolvedInstance; + +begin + Result:=Nil; + EnterCriticalSection(ResolveSection); + Try + If Assigned(NeedResolving) then + begin + Result:=TUnResolvedInstance(NeedResolving.Root); + While (Result<>Nil) and (Result.Instance<>AInstance) do + Result:=TUnResolvedInstance(Result.Next); + end; + finally + LeaveCriticalSection(ResolveSection); + end; +end; + +Function AddtoResolveList(AInstance: TPersistent) : TUnResolvedInstance; + +begin + Result:=FindUnresolvedInstance(AInstance); + If (Result=Nil) then + begin + EnterCriticalSection(ResolveSection); + Try + If not Assigned(NeedResolving) then + NeedResolving:=TLinkedList.Create(TUnResolvedInstance); + Result:=NeedResolving.Add as TUnResolvedInstance; + Result.Instance:=AInstance; + finally + LeaveCriticalSection(ResolveSection); + end; + end; +end; + +// Walk through the global list of instances to be resolved. + +Procedure VisitResolveList(V : TLinkedListVisitor); + +begin + EnterCriticalSection(ResolveSection); + Try + try + NeedResolving.Foreach(V); + Finally + FreeAndNil(V); + end; + Finally + LeaveCriticalSection(ResolveSection); + end; +end; + +procedure GlobalFixupReferences; + +begin + If (NeedResolving=Nil) then + Exit; + GlobalNameSpace.BeginWrite; + try + VisitResolveList(TResolveReferenceVisitor.Create); + finally + GlobalNameSpace.EndWrite; + end; +end; + +procedure GetFixupReferenceNames(Root: TComponent; Names: TStrings); + +begin + If (NeedResolving=Nil) then + Exit; + VisitResolveList(TReferenceNamesVisitor.Create(Root,Names)); +end; + +procedure GetFixupInstanceNames(Root: TComponent; const ReferenceRootName: string; Names: TStrings); + +begin + If (NeedResolving=Nil) then + Exit; + VisitResolveList(TReferenceInstancesVisitor.Create(Root,ReferenceRootName,Names)); +end; + +procedure RedirectFixupReferences(Root: TComponent; const OldRootName, NewRootName: string); + +begin + If (NeedResolving=Nil) then + Exit; + VisitResolveList(TRedirectReferenceVisitor.Create(Root,OldRootName,NewRootName)); +end; + +procedure RemoveFixupReferences(Root: TComponent; const RootName: string); + +begin + If (NeedResolving=Nil) then + Exit; + VisitResolveList(TRemoveReferenceVisitor.Create(Root,RootName)); +end; + +procedure RemoveFixups(Instance: TPersistent); + +begin + // This needs work. +{ + if not Assigned(GlobalFixupList) then + exit; + + with GlobalFixupList.LockList do + try + for i := Count - 1 downto 0 do + begin + CurFixup := TPropFixup(Items[i]); + if (CurFixup.FInstance = Instance) then + begin + Delete(i); + CurFixup.Free; + end; + end; + finally + GlobalFixupList.UnlockList; + end; +} +end; + +Function FindNestedComponent(Root : TComponent; APath : String; CStyle : Boolean = True) : TComponent; + + Function GetNextName : String; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + + Var + P : Integer; + CM : Boolean; + + begin + P:=Pos('.',APath); + CM:=False; + If (P=0) then + begin + If CStyle then + begin + P:=Pos('->',APath); + CM:=P<>0; + end; + If (P=0) Then + P:=Length(APath)+1; + end; + Result:=Copy(APath,1,P-1); + Delete(APath,1,P+Ord(CM)); + end; + +Var + C : TComponent; + S : String; +begin + If (APath='') then + Result:=Nil + else + begin + Result:=Root; + While (APath<>'') And (Result<>Nil) do + begin + C:=Result; + S:=Uppercase(GetNextName); + Result:=C.FindComponent(S); + If (Result=Nil) And (S='OWNER') then + Result:=C; + end; + end; +end; + +type + tglobloadlist = class(tfplist) + protected + fsuspended: integer; + public + procedure beginsuspend; + procedure endsuspend; + end; + +threadvar + GlobalLoaded: tglobloadlist; + GlobalLists: TFpList; + +{ tglobloadlist } + +procedure tglobloadlist.beginsuspend; +begin + inc(fsuspended); +end; + +procedure tglobloadlist.endsuspend; +begin + dec(fsuspended); +end; + +procedure beginsuspendgloballoading; +begin + if globalloaded <> nil then begin + globalloaded.beginsuspend; + end; +end; + +procedure endsuspendgloballoading; +begin + if globalloaded <> nil then begin + globalloaded.endsuspend; + end; +end; + +procedure BeginGlobalLoading; + +begin + if not Assigned(GlobalLists) then + GlobalLists := TFpList.Create; + GlobalLists.Add(GlobalLoaded); + GlobalLoaded := tglobloadlist.Create; +end; + +procedure NotifyGlobalLoading; +var + i: Integer; +begin + for i := 0 to GlobalLoaded.Count - 1 do + TComponent(GlobalLoaded[i]).Loaded; +end; + +procedure EndGlobalLoading; +begin + { Free the memory occupied by BeginGlobalLoading } + GlobalLoaded.Free; + GlobalLoaded := tglobloadlist(GlobalLists.Last); + GlobalLists.Delete(GlobalLists.Count - 1); + if GlobalLists.Count = 0 then + begin + GlobalLists.Free; + GlobalLists := nil; + end; +end; + +function CollectionsEqual(C1, C2: TCollection): Boolean; +begin + // !!!: Implement this + CollectionsEqual:=false; +end; + +function CollectionsEqual(C1, C2: TCollection; Owner1, Owner2: TComponent): Boolean; + + procedure stream_collection(s : tstream;c : tcollection;o : tcomponent); + var + w : twriter; + begin + w:=twriter.create(s,4096); + try + w.root:=o; + w.flookuproot:=o; + w.writecollection(c); + finally + w.free; + end; + end; + + var + s1,s2 : tmemorystream; + begin + result:=false; + if (c1.classtype<>c2.classtype) or + (c1.count<>c2.count) then + exit; + if c1.count = 0 then + begin + result:= true; + exit; + end; + s1:=tmemorystream.create; + try + s2:=tmemorystream.create; + try + stream_collection(s1,c1,owner1); + stream_collection(s2,c2,owner2); + result:=(s1.size=s2.size) and + {$ifdef FPC} + (CompareChar(s1.memory^,s2.memory^,s1.size) = 0); + {$else} + Comparemem(s1.memory,s2.memory,s1.size); + {$endif} + finally + s2.free; + end; + finally + s1.free; + end; + end; + + +{ ********************************************************************* + * TFiler * + *********************************************************************} + +procedure TFiler.SetRoot(ARoot: TComponent); +begin + FRoot := ARoot; +end; + +{****************************************************************************} +{* TREADER *} +{****************************************************************************} + +type + TFieldInfo = packed record + FieldOffset: LongWord; + ClassTypeIndex: Word; + Name: ShortString; + end; + + PFieldClassTable = ^TFieldClassTable; + TFieldClassTable = +{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} + packed +{$endif FPC_REQUIRES_PROPER_ALIGNMENT} + record + Count: Word; + {$ifdef FPC} + {$ifdef mse_fpc_3_2} + Entries: array[Word] of ^TPersistentClass; + {$else} + Entries: array[Word] of TPersistentClass; + {$endif} + {$else} + Entries: array[Word] of ^TPersistentClass; + {$endif} + end; + + PFieldTable = ^TFieldTable; + TFieldTable = +{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} + packed +{$endif FPC_REQUIRES_PROPER_ALIGNMENT} + record + FieldCount: Word; + ClassTable: PFieldClassTable; + // Fields: array[Word] of TFieldInfo; Elements have variant size! + end; + +function getfieldclasstable(const aclass: tclass): pfieldclasstable; +begin + pointer(result):= ppointer(pchar(pointer(aclass))+vmtFieldTable)^; + if result <> nil then begin + result:= pfieldtable(pointer(result))^.classtable; + end; +end; + +function GetFieldClass(Instance: TObject; const ClassName: string): TPersistentClass; +var + UClassName: String; + ClassType: TClass; + ClassTable: PFieldClassTable; + i: Integer; +begin + // At first, try to locate the class in the class tables + UClassName := UpperCase(ClassName); + ClassType := Instance.ClassType; + while ClassType <> TPersistent do + begin + classtable:= getfieldclasstable(classtype); + if Assigned(ClassTable) then + for i := 0 to ClassTable^.Count - 1 do + begin + {$ifdef FPC} + {$ifdef mse_fpc_3_2} + Result := ClassTable^.Entries[i]^; + {$else} + Result := ClassTable^.Entries[i]; + {$endif} + {$else} + Result := ClassTable^.Entries[i]^; + {$endif} + if UpperCase(Result.ClassName) = UClassName then + exit; + end; + // Try again with the parent class type + ClassType := ClassType.ClassParent; + end; + Result := GetClass(ClassName); +end; + + +constructor TReader.Create(Stream: TStream; BufSize: Integer); +begin + inherited Create; + If (Stream=Nil) then + Raise EReadError.Create(SEmptyStreamIllegalReader); + FDriver := CreateDriver(Stream, BufSize); + fdriver.freader:= self; +end; + +destructor TReader.Destroy; +begin + FDriver.Free; + inherited Destroy; +end; + +function TReader.CreateDriver(Stream: TStream; BufSize: Integer): TAbstractObjectReader; +begin + Result := TBinaryObjectReader.Create(Stream, BufSize); +end; + +procedure TReader.BeginReferences; +begin + FLoaded := TFpList.Create; +end; + +procedure TReader.CheckValue(Value: TValueType); +begin + if FDriver.NextValue <> Value then + raise EReadError.Create(SInvalidPropertyValue) + else + FDriver.ReadValue; +end; + +procedure TReader.DefineProperty(const Name: String; AReadData: TReaderProc; + WriteData: TWriterProc; HasData: Boolean); +begin + if Assigned(AReadData) and (UpperCase(Name) = UpperCase(FPropName)) then + begin + AReadData(Self); + SetLength(FPropName, 0); + end; +end; + +procedure TReader.DefineBinaryProperty(const Name: String; + AReadData, WriteData: TStreamProc; HasData: Boolean); +var + MemBuffer: TMemoryStream; +begin + if Assigned(AReadData) and (UpperCase(Name) = UpperCase(FPropName)) then + begin + { Check if the next property really is a binary property} + if FDriver.NextValue <> vaBinary then + begin + FDriver.SkipValue; + FCanHandleExcepts := True; + raise EReadError.Create(SInvalidPropertyValue); + end else + FDriver.ReadValue; + + MemBuffer := TMemoryStream.Create; + try + FDriver.ReadBinary(MemBuffer); + FCanHandleExcepts := True; + AReadData(MemBuffer); + finally + MemBuffer.Free; + end; + SetLength(FPropName, 0); + end; +end; + +function treader.beginoflist(): boolean; +begin + result:= fdriver.nextvalue = valist; +end; + +function TReader.EndOfList: Boolean; +begin + Result := FDriver.NextValue = vaNull; +end; + +procedure TReader.EndReferences; +begin + FLoaded.Free; + FLoaded := nil; +end; + +function TReader.Error(const Message: String): Boolean; +begin + Result := False; + if Assigned(FOnError) then + FOnError(Self, Message, Result); +end; + +function TReader.FindMethod(ARoot: TComponent; const AMethodName: String): Pointer; +var + ErrorResult: Boolean; +begin + Result := ARoot.MethodAddress(AMethodName); + ErrorResult := Result = nil; + + { always give the OnFindMethod callback a chance to locate the method } + if Assigned(FOnFindMethod) then + FOnFindMethod(Self, AMethodName, Result, ErrorResult); + + if ErrorResult then + raise EReadError.Create(SInvalidPropertyValue); +end; + +procedure TReader.DoFixupReferences; + +Var + R,RN : TLocalUnresolvedReference; + G : TUnresolvedInstance; + Ref : String; + C : TComponent; + P : integer; + L : TLinkedList; + +begin + If Assigned(FFixups) then + begin + L:=TLinkedList(FFixups); + R:=TLocalUnresolvedReference(L.Root); + While (R<>Nil) do + begin + RN:=TLocalUnresolvedReference(R.Next); + Ref:=R.FRelative; + If Assigned(FOnReferenceName) then + FOnReferenceName(Self,Ref); + C:=FindNestedComponent(R.FRoot,Ref); + If Assigned(C) then + SetObjectProp(R.FInstance,R.FPropInfo,C) + else begin + P:=Pos('.',R.FRelative); + If (P<>0) then begin + G:= AddToResolveList(R.FInstance); + G.Addreference(R.FRoot,R.FPropInfo,Copy(R.FRelative,1,P-1),Copy(R.FRelative,P+1,Length(R.FRelative)-P)); + end; + end; + L.RemoveItem(R,True); + R:=RN; + end; + FreeAndNil(FFixups); + end; +end; + +procedure TReader.FixupReferences; +var + i: Integer; +begin + DoFixupReferences; + GlobalFixupReferences; + for i := 0 to FLoaded.Count - 1 do + TComponent(FLoaded[I]).Loaded; +end; + + +function TReader.NextValue: TValueType; +begin + Result := FDriver.NextValue; +end; + +procedure TReader.Read(var Buf; Count: LongInt); +begin + //This should give an exception if read is not implemented (i.e. TTextObjectReader) + //but should work with TBinaryObjectReader. + Driver.Read(Buf, Count); +end; + +procedure TReader.PropertyError; +begin + FDriver.SkipValue; + raise EReadError.CreateFmt(SUnknownProperty,[FPropName]); +end; + +function TReader.ReadBoolean: Boolean; +var + ValueType: TValueType; +begin + ValueType := FDriver.ReadValue; + if ValueType = vaTrue then + Result := True + else if ValueType = vaFalse then + Result := False + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +function TReader.ReadChar: Char; +var + s: String; +begin + s := ReadString; + if Length(s) = 1 then + Result := s[1] + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +function TReader.ReadWideChar: WideChar; + +var + W: WideString; + +begin + W := ReadWideString; + if Length(W) = 1 then + Result := W[1] + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +function TReader.ReadUnicodeChar: UnicodeChar; + +var + U: UnicodeString; + +begin + U := ReadUnicodeString; + if Length(U) = 1 then + Result := U[1] + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +procedure TReader.ReadCollection(Collection: TCollection); +var + Item: TCollectionItem; +begin + Collection.BeginUpdate; + if not EndOfList then + Collection.Clear; + while not EndOfList do begin + ReadListBegin; + Item := Collection.Add; + while NextValue<>vaNull do + ReadProperty(Item); + ReadListEnd; + end; + Collection.EndUpdate; + ReadListEnd; +end; + +function TReader.ReadComponent(Component: TComponent): TComponent; +var + Flags: TFilerFlags; + + function Recover(var Component: TComponent): Boolean; + begin + Result := False; + if ExceptObject.InheritsFrom(Exception) then + begin + if not ((ffInherited in Flags) or Assigned(Component)) then + Component.Free; + Component := nil; + FDriver.SkipComponent(False); + Result := Error(Exception(ExceptObject).Message); + end; + end; + +var + CompClassName, Name: String; + n, ChildPos: Integer; + SavedParent, SavedLookupRoot: TComponent; + ComponentClass: TComponentClass; + C, NewComponent: TComponent; + SubComponents: TList; +begin + FDriver.BeginComponent(Flags, ChildPos, CompClassName, Name); + SavedParent := Parent; + SavedLookupRoot := FLookupRoot; + SubComponents := nil; + try + Result := Component; + if not Assigned(Result) then + try + if ffInherited in Flags then + begin + { Try to locate the existing ancestor component } + + if Assigned(FLookupRoot) then + Result := FLookupRoot.FindComponent(Name) + else + Result := nil; + + if not Assigned(Result) then + begin + if Assigned(FOnAncestorNotFound) then + FOnAncestorNotFound(Self, Name, + FindComponentClass(CompClassName,flags), Result); + if not Assigned(Result) then + raise EReadError.CreateFmt(SAncestorNotFound, [Name]); + end; + + Parent := Result.GetParentComponent; + if not Assigned(Parent) then + Parent := Root; + end else + begin + Result := nil; + ComponentClass := FindComponentClass(CompClassName,flags); + if Assigned(FOnCreateComponent) then + FOnCreateComponent(Self, ComponentClass, Result); + if not Assigned(Result) then + begin + NewComponent := TComponent(ComponentClass.NewInstance); + if ffInline in Flags then + NewComponent.FComponentState := + NewComponent.FComponentState + [csLoading, csInline]; + NewComponent.Create(Owner); + + { Don't set Result earlier because else we would come in trouble + with the exception recover mechanism! (Result should be NIL if + an error occured) } + Result := NewComponent; + end; + Include(Result.FComponentState, csLoading); + end; + except + if not Recover(Result) then + raise; + end; + + if Assigned(Result) then + try + Include(Result.FComponentState, csLoading); + + { create list of subcomponents and set loading} + SubComponents := TList.Create; + for n := 0 to Result.ComponentCount - 1 do + begin + C := Result.Components[n]; + if csSubcomponent in C.ComponentStyle + then begin + SubComponents.Add(C); + Include(C.FComponentState, csLoading); + end; + end; + + if not (ffInherited in Flags) then + try + Result.SetParentComponent(Parent); + if Assigned(FOnSetName) then + FOnSetName(Self, Result, Name); + Result.Name := Name; + if FindGlobalComponent(Name) = Result then + Include(Result.FComponentState, csInline); + except + if not Recover(Result) then + raise; + end; + if not Assigned(Result) then + exit; + if csInline in Result.ComponentState then + FLookupRoot := Result; + + { Read the component state } + Include(Result.FComponentState, csReading); + for n := 0 to Subcomponents.Count - 1 do + Include(TComponent(Subcomponents[n]).FComponentState, csReading); + + Result.ReadState(Self); + + Exclude(Result.FComponentState, csReading); + for n := 0 to Subcomponents.Count - 1 do + Exclude(TComponent(Subcomponents[n]).FComponentState, csReading); + + if ffChildPos in Flags then + Parent.SetChildOrder(Result, ChildPos); + + { Add component to list of loaded components, if necessary } + if (not ((ffInherited in Flags) or (csInline in Result.ComponentState))) or + (FLoaded.IndexOf(Result) < 0) + then begin + for n := 0 to Subcomponents.Count - 1 do + FLoaded.Add(Subcomponents[n]); + FLoaded.Add(Result); + end; + except + if ((ffInherited in Flags) or Assigned(Component)) then + Result.Free; + raise; + end; + finally + Parent := SavedParent; + FLookupRoot := SavedLookupRoot; + Subcomponents.Free; + end; +end; + +procedure TReader.ReadData(Instance: TComponent); +var + SavedOwner, SavedParent: TComponent; + +begin + { Read properties } + while not EndOfList do + ReadProperty(Instance); + ReadListEnd; + + { Read children } + SavedOwner := Owner; + SavedParent := Parent; + try + Owner := Instance.GetChildOwner; + if not Assigned(Owner) then + Owner := Root; + Parent := Instance.GetChildParent; + + while not EndOfList do + ReadComponent(nil); + ReadListEnd; + finally + Owner := SavedOwner; + Parent := SavedParent; + end; + + { Fixup references if necessary (normally only if this is the root) } + If (Instance=FRoot) then + DoFixupReferences; +end; + +{$ifndef FPUNONE} +function TReader.ReadFloat: Extended; +begin + if FDriver.NextValue = vaExtended then + begin + ReadValue; + Result := FDriver.ReadFloat + end else + Result := ReadInteger; +end; + +function TReader.ReadSingle: Single; +begin + if FDriver.NextValue = vaSingle then + begin + FDriver.ReadValue; + Result := FDriver.ReadSingle; + end else + Result := ReadInteger; +end; +{$endif} + +function TReader.ReadCurrency: Currency; +begin + if FDriver.NextValue = vaCurrency then + begin + FDriver.ReadValue; + Result := FDriver.ReadCurrency; + end else + Result := ReadInteger; +end; + +{$ifndef FPUNONE} +function TReader.ReadDate: TDateTime; +begin + if FDriver.NextValue = vaDate then + begin + FDriver.ReadValue; + Result := FDriver.ReadDate; + end else + Result := ReadInteger; +end; +{$endif} + +function TReader.ReadIdent: String; +var + ValueType: TValueType; +begin + ValueType := FDriver.ReadValue; + if ValueType in [vaIdent, vaNil, vaFalse, vaTrue, vaNull] then + Result := FDriver.ReadIdent(ValueType) + else + raise EReadError.Create(SInvalidPropertyValue); +end; + + +function TReader.ReadInteger: LongInt; +begin + case FDriver.ReadValue of + vaInt8: + Result := FDriver.ReadInt8; + vaInt16: + Result := FDriver.ReadInt16; + vaInt32: + Result := FDriver.ReadInt32; + else + raise EReadError.Create(SInvalidPropertyValue); + end; +end; + +function TReader.ReadInt64: Int64; +begin + if FDriver.NextValue = vaInt64 then + begin + FDriver.ReadValue; + Result := FDriver.ReadInt64; + end else + Result := ReadInteger; +end; + +function treader.readset(settype: ptypeinfo): longword; +begin + if fdriver.nextvalue = vaset then begin + fdriver.readvalue; + result:= fdriver.readset( + gettypedata(settype)^.comptype{$ifndef FPC}^{$endif}); + end + else begin + result:= readinteger; + end; +end; + +procedure TReader.ReadListBegin; +begin + CheckValue(vaList); +end; + +procedure TReader.ReadListEnd; +begin + CheckValue(vaNull); +end; + +function TReader.ReadVariant: variant; +var + nv: TValueType; +begin +{$ifdef FPC} + { Ensure that a Variant manager is installed } + if not Assigned(VarClearProc) then + raise EReadError.Create(SErrNoVariantSupport); +{$endif} + FillChar(Result,sizeof(Result),0); + + nv:=NextValue; + case nv of + vaNil: + begin + Result:= {$ifdef FPC}system.{$endif}unassigned; + readvalue; + end; + vaNull: + begin + Result:= {$ifdef FPC}system.{$endif}null; + readvalue; + end; + { all integer sizes must be split for big endian systems } + vaInt8,vaInt16,vaInt32: + begin + Result:=ReadInteger; + end; + vaInt64: + begin + Result:=ReadInt64; + end; + vaQWord: + begin + Result:=QWord(ReadInt64); + end; + vaFalse,vaTrue: + begin + Result:=(nv<>vaFalse); + end; + vaCurrency: + begin + Result:=ReadCurrency; + end; +{$ifndef fpunone} + vaSingle: + begin + Result:=ReadSingle; + end; + vaExtended: + begin + Result:=ReadFloat; + end; + vaDate: + begin + Result:=ReadDate; + end; +{$endif fpunone} + vaWString,vaUTF8String: + begin + Result:=ReadWideString; + end; + vaString: + begin + Result:=ReadString; + end; + vaUString: + begin + Result:=ReadUnicodeString; + end; + else + raise EReadError.CreateFmt(SUnsupportedPropertyVariantType, [Ord(nv)]); + end; +end; + +procedure TReader.ReadProperty(AInstance: TPersistent); +var + Path: String; + Instance: TPersistent; + DotPos, NextPos: PChar; + PropInfo: PPropInfo; + Obj: TObject; + Name: String; + Skip: Boolean; + Handled: Boolean; + OldPropName: String; + + function HandleMissingProperty(IsPath: Boolean): boolean; + begin + Result:=true; + if Assigned(OnPropertyNotFound) then begin + // user defined property error handling + OldPropName:=FPropName; + Handled:=false; + Skip:=false; + OnPropertyNotFound(Self,Instance,FPropName,IsPath,Handled,Skip); + if Handled and (not Skip) and (OldPropName<>FPropName) then + // try alias property + PropInfo := GetPropInfo(Instance.ClassInfo, FPropName); + if Skip then begin + FDriver.SkipValue; + Result:=false; + exit; + end; + end; + end; + +begin + try + Path := FDriver.BeginProperty; + try + Instance := AInstance; + FCanHandleExcepts := True; + DotPos := PChar(Path); + while True do + begin + NextPos := StrScan(DotPos, '.'); + if Assigned(NextPos) then + FPropName := Copy(String(DotPos), 1, Integer(NextPos - DotPos)) + else + begin + FPropName := DotPos; + break; + end; + DotPos := NextPos + 1; + + PropInfo := GetPropInfo(Instance.ClassInfo, FPropName); + if not Assigned(PropInfo) then begin + if not HandleMissingProperty(true) then exit; + if not Assigned(PropInfo) then + PropertyError; + end; + + if PropInfo^.PropType^.Kind = tkClass then + Obj := TObject(GetObjectProp(Instance, PropInfo)) + else + Obj := nil; + + if not (Obj is TPersistent) then + begin + { All path elements must be persistent objects! } + FDriver.SkipValue; + raise EReadError.Create(SInvalidPropertyPath); + end; + Instance := TPersistent(Obj); + end; + + PropInfo := GetPropInfo(Instance.ClassInfo, FPropName); + if Assigned(PropInfo) then + ReadPropValue(Instance, PropInfo) + else + begin + FCanHandleExcepts := False; + Instance.DefineProperties(Self); + FCanHandleExcepts := True; + if Length(FPropName) > 0 then begin + if not HandleMissingProperty(false) then exit; + if not Assigned(PropInfo) then + PropertyError; + end; + end; + except + on e: Exception do + begin + SetLength(Name, 0); + if AInstance.InheritsFrom(TComponent) then + Name := TComponent(AInstance).Name; + if Length(Name) = 0 then + Name := AInstance.ClassName; + raise EReadError.CreateFmt(SPropertyException, + [Name, DotSep, Path, e.Message]); + end; + end; + except + on e: Exception do + if not FCanHandleExcepts or not Error(E.Message) then + raise; + end; +end; + +procedure TReader.ReadPropValue(Instance: TPersistent; PropInfo: Pointer); +const + NullMethod: TMethod = (Code: nil; Data: nil); +var + PropType: PTypeInfo; + Value: LongInt; +{ IdentToIntFn: TIdentToInt; } + Ident: String; + Method: TMethod; + Handled: Boolean; + TmpStr: String; + TmpStr8: utf8String; +begin + if not Assigned(PPropInfo(PropInfo)^.SetProc) then + raise EReadError.Create(SReadOnlyProperty); + +{$ifdef FPC} + PropType := PPropInfo(PropInfo)^.PropType; +{$else} + PropType := PPropInfo(PropInfo)^.PropType^; +{$endif} + case PropType^.Kind of + tkInteger: + if FDriver.NextValue = vaIdent then + begin + Ident := ReadIdent; + if GlobalIdentToInt(Ident,Value) then + SetOrdProp(Instance, PropInfo, Value) + else + raise EReadError.Create(SInvalidPropertyValue); + end else + SetOrdProp(Instance, PropInfo, ReadInteger); +{$ifdef FPC} + tkBool: + SetOrdProp(Instance, PropInfo, Ord(ReadBoolean)); +{$endif} + tkChar: + SetOrdProp(Instance, PropInfo, Ord(ReadChar)); + tkWChar{$ifdef FPC},tkUChar{$endif}: + SetOrdProp(Instance, PropInfo, Ord(ReadWideChar)); + tkEnumeration: + begin + ident:= ReadIdent; + Value := GetEnumValue(PropType, ident); + if Value = -1 then begin + if assigned(fonenumerror) then begin + fonenumerror(self,proptype,ident,value); + end; + end; + if Value = -1 then begin + raise EReadError.Create(SInvalidPropertyValue); + end; + SetOrdProp(Instance, PropInfo, Value); + end; +{$ifndef FPUNONE} + tkFloat: + SetFloatProp(Instance, PropInfo, ReadFloat); +{$endif} + tkSet: + begin + CheckValue(vaSet); + SetOrdProp(Instance, PropInfo, + {$ifdef FPC} + FDriver.ReadSet(GetTypeData(PropType)^.CompType)); + {$else} + FDriver.ReadSet(GetTypeData(PropType)^.CompType^)); + {$endif} + end; + tkMethod: + if FDriver.NextValue = vaNil then + begin + FDriver.ReadValue; + SetMethodProp(Instance, PropInfo, NullMethod); + end else + begin + Handled:=false; + Ident:=ReadIdent; + if Assigned(OnSetMethodProperty) then + OnSetMethodProperty(Self,Instance,PPropInfo(PropInfo),Ident, + Handled); + if not Handled then begin + Method.Code := FindMethod(Root, Ident); + Method.Data := Root; + if Assigned(Method.Code) then + SetMethodProp(Instance, PropInfo, Method); + end; + end; + {$ifdef FPC} + tkSString, tkLString, tkAString: + {$else} + tkString, tkLString: + {$endif} + begin + if proptype = typeinfo(utf8string) then begin + TmpStr8:=Readutf8String; + if Assigned(FOnReadStringProperty) then begin + tmpstr:= tmpstr8; + FOnReadStringProperty(Self,Instance,PropInfo,TmpStr); + tmpstr8:= tmpstr; + end; + SetStrProp(Instance, PropInfo, TmpStr8); + end + else begin + TmpStr:=ReadString; + if Assigned(FOnReadStringProperty) then + FOnReadStringProperty(Self,Instance,PropInfo,TmpStr); + SetStrProp(Instance, PropInfo, TmpStr); + end; + end; + {$ifdef FPC} + tkUstring: + SetUnicodeStrProp(Instance,PropInfo,ReadUnicodeString); + {$endif} + tkWString: + SetWideStrProp(Instance,PropInfo,ReadWideString); + tkVariant: + begin + SetVariantProp(Instance,PropInfo,ReadVariant); + end; + tkClass: + case FDriver.NextValue of + vaNil: + begin + FDriver.ReadValue; + SetOrdProp(Instance, PropInfo, 0) + end; + vaCollection: + begin + FDriver.ReadValue; + ReadCollection(TCollection(GetObjectProp(Instance, PropInfo))); + end + else begin + If Not Assigned(FFixups) then begin +// FFixups:=TLinkedList.Create(TLocalUnresolvedReference); + FFixups:= tlocalfixups.create; + end; +// With tfixups(FFixups).newreference(instance,propinfo) do begin + With TLocalUnresolvedReference(tlocalfixups(FFixups).add) do begin + FInstance:= Instance; + FRoot:= Root; + FPropInfo:= PropInfo; + FRelative:= ReadIdent; + end; + end; + end; + tkInt64{$ifdef FPC}, tkQWord{$endif}: + SetInt64Prop(Instance, PropInfo, ReadInt64); + else + raise EReadError.CreateFmt(SUnknownPropertyType, [Ord(PropType^.Kind)]); + end; +end; + +function TReader.ReadRootComponent(ARoot: TComponent): TComponent; +var + Dummy, i: Integer; + Flags: TFilerFlags; + CompClassName, CompName, ResultName: String; + localloaded: boolean; +begin + FDriver.BeginRootComponent; + Result := nil; + {!!!: GlobalNameSpace.BeginWrite; // Loading from stream adds to name space + try} + try + FDriver.BeginComponent(Flags, Dummy, CompClassName, CompName); + if not Assigned(ARoot) then + begin + { Read the class name and the object name and create a new object: } + Result := TComponentClass(FindClass(CompClassName)).Create(nil); + Result.Name := CompName; + end else + begin + Result := ARoot; + + if not (csDesigning in Result.ComponentState) then + begin + Result.FComponentState := + Result.FComponentState + [csLoading, csReading]; + + { We need an unique name } + i := 0; + { Don't use Result.Name directly, as this would influence + FindGlobalComponent in successive loop runs } + ResultName := CompName; + while Assigned(FindGlobalComponent(ResultName)) do + begin + Inc(i); + ResultName := CompName + '_' + IntToStr(i); + end; + Result.Name := ResultName; + end; + end; + + FRoot := Result; + FLookupRoot := Result; + localloaded:= not (Assigned(GlobalLoaded) and + (globalloaded.fsuspended <= 0)); + if localloaded then begin + FLoaded:= TFpList.Create; + end + else begin + FLoaded:= GlobalLoaded; + end; + try + if FLoaded.IndexOf(FRoot) < 0 then begin + FLoaded.Add(FRoot); + end; + FOwner := FRoot; + FRoot.FComponentState := FRoot.FComponentState + [csLoading, csReading]; + FRoot.ReadState(Self); + Exclude(FRoot.FComponentState, csReading); + + GlobalFixupReferences(); + + if localloaded then begin + for i := 0 to FLoaded.Count - 1 do begin + TComponent(FLoaded[i]).Loaded; + end; + end; + + finally + if localloaded then begin + FLoaded.Free; + end; + FLoaded := nil; + end; +// GlobalFixupReferences; + except + RemoveFixupReferences(ARoot, ''); + if not Assigned(ARoot) then + Result.Free; + raise; + end; + {finally + GlobalNameSpace.EndWrite; + end;} +end; + +procedure TReader.ReadComponents(AOwner, AParent: TComponent; + Proc: TReadComponentsProc); +var + Component: TComponent; +begin + Root := AOwner; + Owner := AOwner; + Parent := AParent; + BeginReferences; + try + while not EndOfList do + begin + FDriver.BeginRootComponent; + Component := ReadComponent(nil); + if Assigned(Proc) then + Proc(Component); + end; + ReadListEnd; + FixupReferences; + finally + EndReferences; + end; +end; + +function TReader.ReadString: String; +var + StringType: TValueType; +begin + StringType := FDriver.ReadValue; + if StringType in [vaString, vaLString,vaUTF8String] then + begin + Result := FDriver.ReadString(StringType); + if (StringType=vaUTF8String) then + Result:= ansistring(utf8Decode(Result)); + end + else if StringType in [vaWString] then + Result:= ansistring(FDriver.ReadWidestring) + else if StringType in [vaUString] then + Result:= ansistring(FDriver.ReadUnicodeString) + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +function TReader.Readutf8String: utf8String; +var + StringType: TValueType; +begin + StringType := FDriver.ReadValue; + if StringType in [vaUTF8String] then + Result := FDriver.Readutf8String(StringType) + else if StringType in [vaString, vaLString] then + begin + Result := FDriver.ReadString(StringType); + end + else if StringType in [vaWString] then + Result:= ansistring(FDriver.ReadWidestring) + else if StringType in [vaUString] then + Result:= ansistring(FDriver.ReadUnicodeString) + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +function TReader.ReadWideString: WideString; +var + s: String; + i: Integer; + vt:TValueType; +begin + if NextValue in [vaWString,vaUString,vaUTF8String] then + //vaUTF8String needs conversion? 2008-09-06 mse, YES!! AntonK + begin + vt:=ReadValue; + if vt=vaUTF8String then + Result := utf8decode(fDriver.ReadString(vaLString)) + else + Result := FDriver.ReadWideString + end + else + begin + //data probable from ObjectTextToBinary + s := ReadString; + setlength(result,length(s)); + for i:= 1 to length(s) do begin + result[i]:= widechar(ord(s[i])); //no code conversion + end; + end; +end; + + +function TReader.ReadUnicodeString: UnicodeString; +var + s: String; + i: Integer; + vt:TValueType; +begin + if NextValue in [vaWString,vaUString,vaUTF8String] then + //vaUTF8String needs conversion? 2008-09-06 mse, YES!! AntonK + begin + vt:=ReadValue; + if vt=vaUTF8String then + Result := utf8decode(fDriver.ReadString(vaLString)) + else + Result := FDriver.ReadWideString + end + else + begin + //data probable from ObjectTextToBinary + s := ReadString; + setlength(result,length(s)); + for i:= 1 to length(s) do begin + result[i]:= UnicodeChar(ord(s[i])); //no code conversion + end; + end; +end; + + +function TReader.ReadValue: TValueType; +begin + Result := FDriver.ReadValue; +end; + +procedure TReader.CopyValue(Writer: TWriter); + + procedure CopyBytes(Count: Integer); +{ var + Buffer: array[0..1023] of Byte; } + begin +{!!!: while Count > 1024 do + begin + FDriver.Read(Buffer, 1024); + Writer.Driver.Write(Buffer, 1024); + Dec(Count, 1024); + end; + if Count > 0 then + begin + FDriver.Read(Buffer, Count); + Writer.Driver.Write(Buffer, Count); + end;} + end; + +{var + s: String; + Count: LongInt; } +begin + case FDriver.NextValue of + vaNull: + Writer.WriteIdent('NULL'); + vaFalse: + Writer.WriteIdent('FALSE'); + vaTrue: + Writer.WriteIdent('TRUE'); + vaNil: + Writer.WriteIdent('NIL'); + {!!!: vaList, vaCollection: + begin + Writer.WriteValue(FDriver.ReadValue); + while not EndOfList do + CopyValue(Writer); + ReadListEnd; + Writer.WriteListEnd; + end;} + vaInt8, vaInt16, vaInt32: + Writer.WriteInteger(ReadInteger); +{$ifndef FPUNONE} + vaExtended: + Writer.WriteFloat(ReadFloat); +{$endif} + {!!!: vaString: + Writer.WriteStr(ReadStr);} + vaIdent: + Writer.WriteIdent(ReadIdent); + {!!!: vaBinary, vaLString, vaWString: + begin + Writer.WriteValue(FDriver.ReadValue); + FDriver.Read(Count, SizeOf(Count)); + Writer.Driver.Write(Count, SizeOf(Count)); + CopyBytes(Count); + end;} + {!!!: vaSet: + Writer.WriteSet(ReadSet);} +{$ifndef FPUNONE} + vaSingle: + Writer.WriteSingle(ReadSingle); +{$endif} + {!!!: vaCurrency: + Writer.WriteCurrency(ReadCurrency);} +{$ifndef FPUNONE} + vaDate: + Writer.WriteDate(ReadDate); +{$endif} + vaInt64: + Writer.WriteInteger(ReadInt64); + end; +end; + +function TReader.FindComponentClass(const AClassName: String; + const aflags: tfilerflags): TComponentClass; + +var + PersistentClass: TPersistentClass; + UClassName: shortstring; + + procedure FindInFieldTable(RootComponent: TComponent); + var + FieldClassTable: PFieldClassTable; + Entry: TPersistentClass; + i: Integer; + ComponentClassType: TClass; + begin + ComponentClassType:= RootComponent.ClassType; + // it is not necessary to look in the FieldTable of TComponent, + // because TComponent doesn't have published properties that are + // descendants of TComponent + while ComponentClassType <> TComponent do begin + fieldclasstable:= getfieldclasstable(componentclasstype); + if assigned(FieldClassTable) then begin + for i:= 0 to FieldClassTable^.Count -1 do begin + {$ifdef FPC} + {$ifdef mse_fpc_3_2} + Entry:= FieldClassTable^.Entries[i]^; + {$else} + Entry:= FieldClassTable^.Entries[i]; + {$endif} + {$else} + Entry:= FieldClassTable^.Entries[i]^; + {$endif} + //writeln(format('Looking for %s in field table of class %s. Found %s', + //[AClassName, ComponentClassType.ClassName, Entry.ClassName])); + if (UpperCase(Entry.ClassName) = UClassName) and + Entry.InheritsFrom(TComponent) then begin + Result:= TComponentClass(Entry); + Exit; + end; + end; + end; + // look in parent class + ComponentClassType:= ComponentClassType.ClassParent; + end; + end; + +begin + Result := nil; + if not (csdesigning in root.fcomponentstate) or + not (ffinline in aflags) then begin + UClassName:=UpperCase(AClassName); + FindInFieldTable(Root); + + if (Result=nil) and assigned(LookupRoot) and (LookupRoot<>Root) then + FindInFieldTable(LookupRoot); + + if (Result=nil) then begin + PersistentClass := GetClass(AClassName); + if {$ifndef FPC}(persistentclass <> nil) and{$endif} + PersistentClass.InheritsFrom(TComponent) then + Result := TComponentClass(PersistentClass); + end; + end; + if (Result=nil) and assigned(OnFindComponentClass) then + OnFindComponentClass(Self, AClassName, Result); + + if (Result=nil) or (not Result.InheritsFrom(TComponent)) then + raise EClassNotFound.CreateFmt(SClassNotFound, [AClassName]); +end; + +function treader.readenum(const enumtype: ptypeinfo): longword; +var + str1: string; +begin + str1:= ReadIdent; + result:= GetEnumValue(enumtype, str1); + if integer(result) = -1 then begin + if assigned(fonenumerror) then begin + fonenumerror(self,enumtype,str1,result); + end; + end; + if integer(result) = -1 then begin + raise EReadError.Create(SInvalidPropertyValue); + end; +end; + +{****************************************************************************} +{* TWriter *} +{****************************************************************************} + + +constructor TWriter.Create(ADriver: TAbstractObjectWriter); +begin + inherited Create; + FDriver := ADriver; +end; + +constructor TWriter.Create(Stream: TStream; BufSize: Integer); +begin + inherited Create; + If (Stream=Nil) then + Raise EWriteError.Create(SEmptyStreamIllegalWriter); + FDriver := CreateDriver(Stream, BufSize); + fdriver.fwriter:= self; + FDestroyDriver := True; +end; + +destructor TWriter.Destroy; +begin + if FDestroyDriver then + FDriver.Free; + inherited Destroy; +end; + +function TWriter.CreateDriver(Stream: TStream; BufSize: Integer): TAbstractObjectWriter; +begin + Result := TBinaryObjectWriter.Create(Stream, BufSize); +end; + +Type + TPosComponent = Class(TObject) + FPos : Integer; + FComponent : TComponent; + Constructor Create(APos : Integer; AComponent : TComponent); + end; + +Constructor TPosComponent.Create(APos : Integer; AComponent : TComponent); + +begin + FPos:=APos; + FComponent:=AComponent; +end; + +// Used as argument for calls to TComponent.GetChildren: +procedure TWriter.AddToAncestorList(Component: TComponent); +begin + FAncestors.AddObject(Component.Name,TPosComponent.Create(FAncestors.Count,Component)); +end; + +procedure TWriter.DefineProperty(const Name: String; + ReadData: TReaderProc; AWriteData: TWriterProc; HasData: Boolean); +begin + if HasData and Assigned(AWriteData) then + begin + // Write the property name and then the data itself + Driver.BeginProperty(FPropPath + Name); + AWriteData(Self); + Driver.EndProperty; + end; +end; + +procedure TWriter.DefineBinaryProperty(const Name: String; + ReadData, AWriteData: TStreamProc; HasData: Boolean); +begin + if HasData and Assigned(AWriteData) then + begin + // Write the property name and then the data itself + Driver.BeginProperty(FPropPath + Name); + WriteBinary(AWriteData); + Driver.EndProperty; + end; +end; + +procedure TWriter.Write(const Buffer; Count: Longint); +begin + //This should give an exception if write is not implemented (i.e. TTextObjectWriter) + //but should work with TBinaryObjectWriter. + Driver.Write(Buffer, Count); +end; + +procedure TWriter.SetRoot(ARoot: TComponent); +begin + inherited SetRoot(ARoot); + // Use the new root as lookup root too + FLookupRoot := ARoot; +end; + +procedure TWriter.WriteBinary(AWriteData: TStreamProc); +var + MemBuffer: TMemoryStream; + BufferSize: Longint; +begin + { First write the binary data into a memory stream, then copy this buffered + stream into the writing destination. This is necessary as we have to know + the size of the binary data in advance (we're assuming that seeking within + the writer stream is not possible) } + MemBuffer := TMemoryStream.Create; + try + AWriteData(MemBuffer); + BufferSize := MemBuffer.Size; + Driver.WriteBinary(MemBuffer.Memory^, BufferSize); + finally + MemBuffer.Free; + end; +end; + +procedure TWriter.WriteBoolean(Value: Boolean); +begin + Driver.WriteBoolean(Value); +end; + +procedure TWriter.WriteChar(Value: Char); +begin + WriteString(Value); +end; + +procedure TWriter.WriteWideChar(Value: WideChar); +begin + WriteWideString(Value); +end; + +procedure TWriter.WriteCollection(Value: TCollection); +var + i: Integer; +begin + Driver.BeginCollection; + if Assigned(Value) then + for i := 0 to Value.Count - 1 do + begin + { Each collection item needs its own ListBegin/ListEnd tag, or else the + reader wouldn't be able to know where an item ends and where the next + one starts } + WriteListBegin; + WriteProperties(Value.Items[i]); + WriteListEnd; + end; + WriteListEnd; +end; + +procedure TWriter.DetermineAncestor(Component : TComponent); + +Var + I : Integer; + +begin + // Should be set only when we write an inherited with children. + if Not Assigned(FAncestors) then + exit; + I:=FAncestors.IndexOf(Component.Name); + If (I=-1) then + begin + FAncestor:=Nil; + FAncestorPos:=-1; + end + else + With TPosComponent(FAncestors.Objects[i]) do + begin + FAncestor:=FComponent; + FAncestorPos:=FPos; + end; +end; + +procedure TWriter.DoFindAncestor(Component : TComponent); + +Var + C : TComponent; + +begin + if Assigned(FOnFindAncestor) then + if (Ancestor=Nil) or (Ancestor is TComponent) then + begin + C:=TComponent(Ancestor); + FOnFindAncestor(Self,Component,Component.Name,C,FRootAncestor); + Ancestor:=C; + end; +end; + +procedure TWriter.WriteComponent(Component: TComponent); + +var + SA : TPersistent; + SR, SRA : TComponent; +begin + SR:=FRoot; + SA:=FAncestor; + SRA:=FRootAncestor; + Try + Component.FComponentState:=Component.FComponentState+[csWriting]; + Try + // Possibly set ancestor. + DetermineAncestor(Component); + DoFindAncestor(Component); // Mainly for IDE when a parent form had an ancestor renamed... + // Will call WriteComponentData. + Component.WriteState(Self); + FDriver.EndList; + Finally + Component.FComponentState:=Component.FComponentState-[csWriting]; + end; + Finally + FAncestor:=SA; + FRoot:=SR; + FRootAncestor:=SRA; + end; +end; + +procedure TWriter.WriteChildren(Component : TComponent); + +Var + SRoot, SRootA : TComponent; + SList : TStringList; + SPos : Integer; + I : Integer; + +begin + // Write children list. + // While writing children, the ancestor environment must be saved + // This is recursive... + SRoot:=FRoot; + SRootA:=FRootAncestor; + SList:=FAncestors; + SPos:=FCurrentPos; + try + FAncestors:=Nil; + FCurrentPos:=0; + FAncestorPos:=-1; + if csInline in Component.ComponentState then + FRoot:=Component; + if (FAncestor is TComponent) then + begin + FAncestors:=TStringList.Create; + if csInline in TComponent(FAncestor).ComponentState then + FRootAncestor := TComponent(FAncestor); + TComponent(FAncestor).GetChildren( + {$ifdef FPC}@{$endif}AddToAncestorList,FRootAncestor); + FAncestors.Sorted:=True; + end; + try + Component.GetChildren({$ifdef FPC}@{$endif}WriteComponent, FRoot); + Finally + If Assigned(Fancestors) then + For I:=0 to FAncestors.Count-1 do + FAncestors.Objects[i].Free; + FreeAndNil(FAncestors); + end; + finally + FAncestors:=Slist; + FRoot:=SRoot; + FRootAncestor:=SRootA; + FCurrentPos:=SPos; + FAncestorPos:=Spos; + end; +end; + +procedure TWriter.WriteComponentData(Instance: TComponent); +var + Flags: TFilerFlags; +begin + Flags := []; + If (Assigned(FAncestor)) and //has ancestor + (not (csInline in Instance.ComponentState) or // no inline component + // .. or the inline component is inherited + (csAncestor in Instance.Componentstate) and (FAncestors <> nil)) then + Flags:=[ffInherited] + else If csInline in Instance.ComponentState then + Flags:=[ffInline]; + If (FAncestors<>Nil) and ((FCurrentPos<>FAncestorPos) or (FAncestor=Nil)) then + Include(Flags,ffChildPos); + FDriver.BeginComponent(Instance,Flags,FCurrentPos); + If (FAncestors<>Nil) then + Inc(FCurrentPos); + WriteProperties(Instance); + WriteListEnd; + // Needs special handling of ancestor. + If not IgnoreChildren then + WriteChildren(Instance); +end; + +procedure TWriter.WriteDescendent(ARoot: TComponent; AAncestor: TComponent); +begin + FRoot := ARoot; + FAncestor := AAncestor; + FRootAncestor := AAncestor; + FLookupRoot := ARoot; + + WriteComponent(ARoot); +end; + +{$ifndef FPUNONE} +procedure TWriter.WriteFloat(const Value: Extended); +begin + Driver.WriteFloat(Value); +end; + +procedure TWriter.WriteSingle(const Value: Single); +begin + Driver.WriteSingle(Value); +end; +{$endif} + +procedure TWriter.WriteCurrency(const Value: Currency); +begin + Driver.WriteCurrency(Value); +end; + +{$ifndef FPUNONE} +procedure TWriter.WriteDate(const Value: TDateTime); +begin + Driver.WriteDate(Value); +end; +{$endif} + +procedure TWriter.WriteIdent(const Ident: string); +begin + Driver.WriteIdent(Ident); +end; + +procedure TWriter.WriteInteger(Value: LongInt); +begin + Driver.WriteInteger(Value); +end; + +procedure TWriter.WriteInteger(Value: Int64); +begin + Driver.WriteInteger(Value); +end; + +procedure twriter.writeset(value: longword; settype: ptypeinfo); + +begin + driver.writeset(value, + gettypedata(settype)^.comptype{$ifndef FPC}^{$endif}); +end; + +procedure twriter.writeenum(value: longint; enumtype: ptypeinfo); + +begin + driver.writeident(getenumname(enumtype,value)); +end; + +procedure TWriter.WriteVariant(const VarValue: Variant); +begin + Driver.WriteVariant(VarValue); +end; + +procedure TWriter.WriteListBegin; +begin + Driver.BeginList; +end; + +procedure TWriter.WriteListEnd; +begin + Driver.EndList; +end; + +procedure TWriter.WriteProperties(Instance: TPersistent); +var PropCount,i : integer; + PropList : PPropList; +begin + PropCount:=GetPropList(Instance,PropList); + if PropCount>0 then + try + for i := 0 to PropCount-1 do + if IsStoredProp(Instance,PropList^[i]) then + WriteProperty(Instance,PropList^[i]); + Finally + Freemem(PropList); + end; + Instance.DefineProperties(Self); +end; + + +procedure TWriter.WriteProperty(Instance: TPersistent; PropInfo: Pointer); +var + HasAncestor: Boolean; + PropType: PTypeInfo; + Value, DefValue: LongInt; + Ident: String; + IntToIdentFn: TIntToIdent; +{$ifndef FPUNONE} + FloatValue, DefFloatValue: Extended; +{$endif} + MethodValue: TMethod; + DefMethodValue: TMethod; + WStrValue, WDefStrValue: WideString; + StrValue, DefStrValue: String; + UStrValue, UDefStrValue: UnicodeString; + AncestorObj: TObject; + C,Component: TComponent; + ObjValue: TObject; + SavedAncestor: TPersistent; + SavedPropPath, Name: String; + Int64Value, DefInt64Value: Int64; + VarValue, DefVarValue : tvardata; + BoolValue, DefBoolValue: boolean; + Handled: Boolean; + +begin + // do not stream properties without getter + if not Assigned(PPropInfo(PropInfo)^.GetProc) then + exit; + // properties without setter are only allowed, if they are subcomponents + PropType := PPropInfo(PropInfo)^.PropType{$ifndef FPC}^{$endif}; + if not Assigned(PPropInfo(PropInfo)^.SetProc) then begin + if PropType^.Kind<>tkClass then + exit; + ObjValue := TObject(GetObjectProp(Instance, PropInfo)); + if not ObjValue.InheritsFrom(TComponent) or + not (csSubComponent in TComponent(ObjValue).ComponentStyle) then + exit; + end; + + { Check if the ancestor can be used } + HasAncestor := Assigned(Ancestor) and ((Instance = Root) or + (Instance.ClassType = Ancestor.ClassType)); + //writeln('TWriter.WriteProperty Name=',PropType^.Name,' Kind=',GetEnumName(TypeInfo(TTypeKind),ord(PropType^.Kind)),' HasAncestor=',HasAncestor); + + case PropType^.Kind of + tkInteger, tkChar, tkEnumeration, tkSet, tkWChar: + begin + Value := GetOrdProp(Instance, PropInfo); + if HasAncestor then + DefValue := GetOrdProp(Ancestor, PropInfo) + else + DefValue := PPropInfo(PropInfo)^.Default; + // writeln(PPropInfo(PropInfo)^.Name, ', HasAncestor=', ord(HasAncestor), ', Value=', Value, ', Default=', DefValue); + if (Value <> DefValue) or (DefValue=longint($80000000)) then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + case PropType^.Kind of + tkInteger: + begin + // Check if this integer has a string identifier + IntToIdentFn := FindIntToIdent(PPropInfo(PropInfo)^.PropType); + if Assigned(IntToIdentFn) and IntToIdentFn(Value, Ident) then + // Integer can be written a human-readable identifier + WriteIdent(Ident) + else + // Integer has to be written just as number + WriteInteger(Value); + end; + tkChar: + WriteChar(Chr(Value)); + tkWChar: + WriteWideChar(WideChar(Value)); + tkSet: + Driver.WriteSet(Value, GetTypeData(PropType)^.CompType); + tkEnumeration: + WriteIdent(GetEnumName(PropType, Value)); + end; + Driver.EndProperty; + end; + end; +{$ifndef FPUNONE} + tkFloat: + begin + FloatValue := GetFloatProp(Instance, PropInfo); + if HasAncestor then + DefFloatValue := GetFloatProp(Ancestor, PropInfo) + else + begin + DefValue :=PPropInfo(PropInfo)^.Default; + DefFloatValue:=PSingle(@PPropInfo(PropInfo)^.Default)^; + end; + if (FloatValue<>DefFloatValue) or (DefValue=longint($80000000)) then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteFloat(FloatValue); + Driver.EndProperty; + end; + end; +{$endif} + tkMethod: + begin + MethodValue := GetMethodProp(Instance, PropInfo); + if HasAncestor then + DefMethodValue := GetMethodProp(Ancestor, PropInfo) + else begin + DefMethodValue.Data := nil; + DefMethodValue.Code := nil; + end; + + Handled:=false; + if Assigned(OnWriteMethodProperty) then + OnWriteMethodProperty(Self,Instance,PPropInfo(PropInfo),MethodValue, + DefMethodValue,Handled); + if (not Handled) and + (MethodValue.Code <> DefMethodValue.Code) and + ((not Assigned(MethodValue.Code)) or + ((Length(FLookupRoot.MethodName(MethodValue.Code)) > 0))) then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + if Assigned(MethodValue.Code) then + Driver.WriteMethodName(FLookupRoot.MethodName(MethodValue.Code)) + else + Driver.WriteMethodName(''); + Driver.EndProperty; + end; + end; +{$ifdef FPC} + tkSString, tkLString, tkAString: +{$else} + tkString, tkLString: +{$endif} + begin + StrValue := GetStrProp(Instance, PropInfo); + if HasAncestor then + DefStrValue := GetStrProp(Ancestor, PropInfo) + else + SetLength(DefStrValue, 0); + + if StrValue <> DefStrValue then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + if Assigned(FOnWriteStringProperty) then + FOnWriteStringProperty(Self,Instance,PropInfo,StrValue); + if proptype = typeinfo(utf8string) then begin + writeutf8string(strvalue); + end + else begin + WriteString(StrValue); + end; + Driver.EndProperty; + end; + end; + tkWString: + begin + WStrValue := GetWideStrProp(Instance, PropInfo); + if HasAncestor then + WDefStrValue := GetWideStrProp(Ancestor, PropInfo) + else + SetLength(WDefStrValue, 0); + + if WStrValue <> WDefStrValue then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteWideString(WStrValue); + Driver.EndProperty; + end; + end; +{$ifdef FPC} + tkUString: + begin + UStrValue := GetUnicodeStrProp(Instance, PropInfo); + if HasAncestor then + UDefStrValue := GetUnicodeStrProp(Ancestor, PropInfo) + else + SetLength(UDefStrValue, 0); + + if UStrValue <> UDefStrValue then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteUnicodeString(UStrValue); + Driver.EndProperty; + end; + end; +{$endif} + tkVariant: + begin + { Ensure that a Variant manager is installed } + {$ifdef FPC} + if not assigned(VarClearProc) then + raise EWriteError.Create(SErrNoVariantSupport); + {$endif} + VarValue := tvardata(GetVariantProp(Instance, PropInfo)); + if HasAncestor then + DefVarValue := tvardata(GetVariantProp(Ancestor, PropInfo)) + else + FillChar(DefVarValue,sizeof(DefVarValue),0); +{$ifdef FPC} + if (CompareByte(VarValue,DefVarValue,sizeof(VarValue)) <> 0) then +{$else} + if Comparemem(@VarValue,@DefVarValue,sizeof(VarValue)) then +{$endif} + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + { can't use variant() typecast, pulls in variants unit } + WriteVariant(pvariant(@VarValue)^); + Driver.EndProperty; + end; + end; + tkClass: + begin + ObjValue := TObject(GetObjectProp(Instance, PropInfo)); + if HasAncestor then + begin + AncestorObj := TObject(GetObjectProp(Ancestor, PropInfo)); + if (AncestorObj is TComponent) and + (ObjValue is TComponent) then + begin + //writeln('TWriter.WriteProperty AncestorObj=',TComponent(AncestorObj).Name,' OwnerFit=',TComponent(AncestorObj).Owner = FRootAncestor,' ',TComponent(ObjValue).Name,' OwnerFit=',TComponent(ObjValue).Owner = Root); + if (AncestorObj<> ObjValue) and + (TComponent(AncestorObj).Owner = FRootAncestor) and + (TComponent(ObjValue).Owner = Root) and + (UpperCase(TComponent(AncestorObj).Name) = UpperCase(TComponent(ObjValue).Name)) then + begin + // different components, but with the same name + // treat it like an override + AncestorObj := ObjValue; + end; + end; + end else + AncestorObj := nil; + + if not Assigned(ObjValue) then + begin + if ObjValue <> AncestorObj then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + Driver.WriteIdent('NIL'); + Driver.EndProperty; + end + end + else if ObjValue.InheritsFrom(TPersistent) then + begin + { Subcomponents are streamed the same way as persistents } + if ObjValue.InheritsFrom(TComponent) + and ((not (csSubComponent in TComponent(ObjValue).ComponentStyle)) + or ((TComponent(ObjValue).Owner<>Instance) and + (TComponent(ObjValue).Owner<>Nil))) then + begin + Component := TComponent(ObjValue); + if (ObjValue <> AncestorObj) + and not (csTransient in Component.ComponentStyle) then + begin + Name:= ''; + C:= Component; + While (C<>Nil) and (C.Name<>'') do + begin + If (Name<>'') Then + Name:='.'+Name; + if C.Owner = LookupRoot then + begin + Name := C.Name+Name; + break; + end + else if C = LookupRoot then + begin + Name := 'Owner' + Name; + break; + end; + Name:=C.Name + Name; + C:= C.Owner; + end; + if (C=nil) and (Component.Owner=nil) then + if (Name<>'') then //foreign root + Name:=Name+'.Owner'; + if Length(Name) > 0 then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteIdent(Name); + Driver.EndProperty; + end; // length Name>0 + end; //(ObjValue <> AncestorObj) + end // ObjValue.InheritsFrom(TComponent) + else if ObjValue.InheritsFrom(TCollection) then + begin + if (not HasAncestor) or (not CollectionsEqual(TCollection(ObjValue), + TCollection(GetObjectProp(Ancestor, PropInfo)),root,rootancestor)) then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + SavedPropPath := FPropPath; + try + SetLength(FPropPath, 0); + WriteCollection(TCollection(ObjValue)); + finally + FPropPath := SavedPropPath; + Driver.EndProperty; + end; + end; + end // Tcollection + else + begin + SavedAncestor := Ancestor; + SavedPropPath := FPropPath; + try + FPropPath := FPropPath + PPropInfo(PropInfo)^.Name + '.'; + if HasAncestor then + Ancestor := TPersistent(GetObjectProp(Ancestor, PropInfo)); + WriteProperties(TPersistent(ObjValue)); + finally + Ancestor := SavedAncestor; + FPropPath := SavedPropPath; + end; + end; + end; // Inheritsfrom(TPersistent) + end; + tkInt64 {$ifdef FPC}, tkQWord{$endif}: + begin + Int64Value := GetInt64Prop(Instance, PropInfo); + if HasAncestor then + DefInt64Value := GetInt64Prop(Ancestor, PropInfo) + else + DefInt64Value := 0; + if Int64Value <> DefInt64Value then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteInteger(Int64Value); + Driver.EndProperty; + end; + end; +{$ifdef FPC} + tkBool: + begin + BoolValue := GetOrdProp(Instance, PropInfo)<>0; + if HasAncestor then + DefBoolValue := GetOrdProp(Ancestor, PropInfo)<>0 + else + begin + DefBoolValue := PPropInfo(PropInfo)^.Default<>0; + DefValue:=PPropInfo(PropInfo)^.Default; + end; + // writeln(PPropInfo(PropInfo)^.Name, ', HasAncestor=', ord(HasAncestor), ', Value=', Value, ', Default=', DefBoolValue); + if (BoolValue<>DefBoolValue) or (DefValue=longint($80000000)) then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteBoolean(BoolValue); + Driver.EndProperty; + end; + end; +{$endif} + end; +end; + +procedure TWriter.WriteRootComponent(ARoot: TComponent); +begin + WriteDescendent(ARoot, nil); +end; + +procedure TWriter.WriteString(const Value: String); +begin + Driver.WriteString(Value); +end; + +procedure twriter.Writeutf8String(const Value: utf8string); +begin + Driver.Writeutf8String(Value); +end; + +procedure TWriter.WriteWideString(const Value: WideString); +begin + Driver.WriteWideString(Value); +end; + +procedure TWriter.WriteUnicodeString(const Value: UnicodeString); +begin + Driver.WriteUnicodeString(Value); +end; + +function twriter.getclassname(const aobj: tobject): shortstring; +begin + result:= aobj.classname; +end; + +{****************************************************************************} +{* TBinaryObjectWriter *} +{****************************************************************************} + +{$ifndef FPUNONE} +{$IFNDEF FPC_HAS_TYPE_EXTENDED} +procedure DoubleToExtended(d : double; e : pointer); +var mant : qword; + exp : smallint; + sign : boolean; +begin + mant:= (qword(d) and $000FFFFFFFFFFFFF) shl 12; + exp := (qword(d) shr 52) and $7FF; + sign:= (qword(d) and $8000000000000000) <> 0; + case exp of + 0: begin + if mant <> 0 then begin //denormalized value: hidden bit is 0. normalize it + exp:=16383-1022; + while (mant and $8000000000000000) = 0 do begin + dec(exp); + mant:= mant shl 1; + end; + dec(exp); //don't shift, most significant bit is not hidden in extended + end; + end; + 2047: begin + exp:= $7FFF; //either infinity or NaN + mant:= qword(d) and $000FFFFFFFFFFFFF or $8000000000000000; + end; + else begin + inc(exp,16383-1023); + mant:= (mant shr 1) or $8000000000000000; //unhide hidden bit + end; + end; + if sign then exp:=exp or $8000; + mant:=NtoLE(mant); + exp:=NtoLE(word(exp)); + move(mant,pbyte(e)[0],8); //mantissa : bytes 0..7 + move(exp,pbyte(e)[8],2); //exponent and sign: bytes 8..9 +end; +{$ENDIF} +{$endif} + +procedure TBinaryObjectWriter.WriteWord(w : word); + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin + w:=NtoLE(w); + Write(w,2); +end; + +procedure TBinaryObjectWriter.WriteDWord(lw : longword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin + lw:=NtoLE(lw); + Write(lw,4); +end; + +procedure TBinaryObjectWriter.WriteQWord(qw : qword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin +{$ifdef FPC} + qw:=NtoLE(qw); +{$endif} + Write(qw,8); +end; + +{$ifndef FPUNONE} +procedure TBinaryObjectWriter.WriteExtended(e : extended); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$IFNDEF FPC_HAS_TYPE_EXTENDED} +var ext : array[0..9] of byte; +{$ENDIF} +begin +{$IFNDEF FPC_HAS_TYPE_EXTENDED} + {$IFDEF FPC_DOUBLE_HILO_SWAPPED} + { SwapDoubleHiLo defined in reader.inc } + SwapDoubleHiLo(e); + {$ENDIF FPC_DOUBLE_HILO_SWAPPED} + DoubleToExtended(e,@(ext[0])); + Write(ext[0],10); +{$ELSE} + Write(e,sizeof(e)); +{$ENDIF} +end; +{$endif} + +constructor TBinaryObjectWriter.Create(Stream: TStream; BufSize: Integer); +begin + inherited Create; + If (Stream=Nil) then + Raise EWriteError.Create(SEmptyStreamIllegalWriter); + FStream := Stream; + FBufSize := BufSize; + GetMem(FBuffer, BufSize); +end; + +destructor TBinaryObjectWriter.Destroy; +begin + // Flush all data which hasn't been written yet + FlushBuffer; + + if Assigned(FBuffer) then + FreeMem(FBuffer, FBufSize); + + inherited Destroy; +end; + +procedure TBinaryObjectWriter.BeginCollection; +begin + WriteValue(vaCollection); +end; + +procedure TBinaryObjectWriter.BeginComponent(Component: TComponent; + Flags: TFilerFlags; ChildPos: Integer); +var + Prefix: Byte; +begin + if not FSignatureWritten then + begin + Write(FilerSignature, SizeOf(FilerSignature)); + FSignatureWritten := True; + end; + + { Only write the flags if they are needed! } + if Flags <> [] then + begin + Prefix := {$ifdef FPC}longword{$else}byte{$endif}(Flags) or $f0; + Write(Prefix, 1); + if ffChildPos in Flags then + WriteInteger(ChildPos); + end; + if fwriter <> nil then begin + WriteStr(fwriter.getclassname(Component)); + end + else begin + WriteStr(Component.ClassName); + end; + WriteStr(Component.Name); +end; + +procedure TBinaryObjectWriter.BeginList; +begin + WriteValue(vaList); +end; + +procedure TBinaryObjectWriter.EndList; +begin + WriteValue(vaNull); +end; + +procedure TBinaryObjectWriter.BeginProperty(const PropName: String); +begin + WriteStr(PropName); +end; + +procedure TBinaryObjectWriter.EndProperty; +begin +end; + +procedure TBinaryObjectWriter.WriteBinary(const Buffer; Count: LongInt); +begin + WriteValue(vaBinary); + WriteDWord(longword(Count)); + Write(Buffer, Count); +end; + +procedure TBinaryObjectWriter.WriteBoolean(Value: Boolean); +begin + if Value then + WriteValue(vaTrue) + else + WriteValue(vaFalse); +end; + +{$ifndef FPUNONE} +procedure TBinaryObjectWriter.WriteFloat(const Value: Extended); +begin + WriteValue(vaExtended); + WriteExtended(Value); +end; + +procedure TBinaryObjectWriter.WriteSingle(const Value: Single); +begin + WriteValue(vaSingle); +{$ifdef FPC} + WriteDWord(longword(Value)); +{$else} + WriteDWord(longword(ar4ty(Value))); +{$endif} +end; +{$endif} + +procedure TBinaryObjectWriter.WriteCurrency(const Value: Currency); +begin + WriteValue(vaCurrency); +{$ifdef FPC} + WriteQWord(qword(Value)); +{$else} + WriteQWord(qword(ar8ty(Value))); +{$endif} +end; + + +{$ifndef FPUNONE} +procedure TBinaryObjectWriter.WriteDate(const Value: TDateTime); +begin + WriteValue(vaDate); +{$ifdef FPC} + WriteQWord(qword(Value)); +{$else} + WriteQWord(qword(ar8ty(Value))); +{$endif} +end; +{$endif} + +procedure TBinaryObjectWriter.WriteIdent(const Ident: string); +begin + { Check if Ident is a special identifier before trying to just write + Ident directly } + if UpperCase(Ident) = 'NIL' then + WriteValue(vaNil) + else if UpperCase(Ident) = 'FALSE' then + WriteValue(vaFalse) + else if UpperCase(Ident) = 'TRUE' then + WriteValue(vaTrue) + else if UpperCase(Ident) = 'NULL' then + WriteValue(vaNull) else + begin + WriteValue(vaIdent); + WriteStr(Ident); + end; +end; + +procedure TBinaryObjectWriter.WriteInteger(Value: Int64); +var + s: ShortInt; + i: SmallInt; + l: Longint; +begin + { Use the smallest possible integer type for the given value: } + if (Value >= -128) and (Value <= 127) then + begin + WriteValue(vaInt8); + s := Value; + Write(s, 1); + end else if (Value >= -32768) and (Value <= 32767) then + begin + WriteValue(vaInt16); + i := Value; + WriteWord(word(i)); +{$ifdef FPC} + end else if (Value >= -$80000000) and (Value <= $7fffffff) then +{$else} + end else if (Value >= $80000000) and (Value <= $7fffffff) then +{$endif} + begin + WriteValue(vaInt32); + l := Value; + WriteDWord(longword(l)); + end else + begin + WriteValue(vaInt64); + WriteQWord(qword(Value)); + end; +end; + +procedure TBinaryObjectWriter.WriteUInt64(Value: QWord); +var + s: ShortInt; + i: SmallInt; + l: Longint; +begin + { Use the smallest possible integer type for the given value: } + if (Value <= 127) then + begin + WriteValue(vaInt8); + s := Value; + Write(s, 1); + end else if (Value <= 32767) then + begin + WriteValue(vaInt16); + i := Value; + WriteWord(word(i)); + end else if (Value <= $7fffffff) then + begin + WriteValue(vaInt32); + l := Value; + WriteDWord(longword(l)); + end else + begin +{$ifdef FPC} + WriteValue(vaQWord); +{$else} + WriteValue(vaint64); +{$endif} + WriteQWord(Value); + end; +end; + + +procedure TBinaryObjectWriter.WriteMethodName(const Name: String); +begin + if Length(Name) > 0 then + begin + WriteValue(vaIdent); + WriteStr(Name); + end else + WriteValue(vaNil); +end; + +procedure TBinaryObjectWriter.WriteSet(Value: LongInt; SetType: Pointer); +type + tset = set of 0..31; +var + i: Integer; +begin + WriteValue(vaSet); + for i := 0 to 31 do + begin + if (i in tset(Value)) then + WriteStr(GetEnumName(PTypeInfo(SetType), i)); + end; + WriteStr(''); +end; + +procedure TBinaryObjectWriter.WriteString(const Value: String); +var + i: Integer; + b: byte; +begin + i := Length(Value); + if i <= 255 then + begin + WriteValue(vaString); + b := i; + Write(b, 1); + end else + begin + WriteValue(vaLString); + WriteDWord(longword(i)); + end; + if i > 0 then + Write(Value[1], i); +end; + +procedure TBinaryObjectWriter.Writeutf8String(const Value: utf8String); +var + i: Integer; +begin + i := Length(Value); + WriteValue(vautf8String); + WriteDWord(longword(i)); + if i > 0 then + Write(Value[1], i); +end; + +procedure TBinaryObjectWriter.WriteWideString(const Value: WideString); +var len : longword; +{$IFDEF ENDIAN_BIG} + i : integer; + ws : widestring; +{$ENDIF} +begin + WriteValue(vaWString); + len:=Length(Value); + WriteDWord(len); + if len > 0 then + begin + {$IFDEF ENDIAN_BIG} + setlength(ws,len); + for i:=1 to len do + ws[i]:=widechar(SwapEndian(word(Value[i]))); + Write(ws[1], len*sizeof(widechar)); + {$ELSE} + Write(Value[1], len*sizeof(widechar)); + {$ENDIF} + end; +end; + +procedure TBinaryObjectWriter.WriteUnicodeString(const Value: UnicodeString); +var len : longword; +{$IFDEF ENDIAN_BIG} + i : integer; + us : UnicodeString; +{$ENDIF} +begin + WriteValue(vaUString); + len:=Length(Value); + WriteDWord(len); + if len > 0 then + begin + {$IFDEF ENDIAN_BIG} + setlength(us,len); + for i:=1 to len do + us[i]:=widechar(SwapEndian(word(Value[i]))); + Write(us[1], len*sizeof(UnicodeChar)); + {$ELSE} + Write(Value[1], len*sizeof(UnicodeChar)); + {$ENDIF} + end; +end; + +procedure TBinaryObjectWriter.WriteVariant(const VarValue: variant); +begin + { The variant manager will handle varbyref and vararray transparently for us + } + case (tvardata(VarValue).vtype and varTypeMask) of + varEmpty: + begin + WriteValue(vaNil); + end; + varNull: + begin + WriteValue(vaNull); + end; + { all integer sizes must be split for big endian systems } + varShortInt,varSmallInt,varInteger,varInt64: + begin + WriteInteger(VarValue); + end; +{$ifdef FPC} + varQWord: + begin + WriteUInt64(VarValue); + end; +{$endif} + varBoolean: + begin + WriteBoolean(VarValue); + end; + varCurrency: + begin + WriteCurrency(VarValue); + end; +{$ifndef fpunone} + varSingle: + begin + WriteSingle(VarValue); + end; + varDouble: + begin + WriteFloat(VarValue); + end; + varDate: + begin + WriteDate(VarValue); + end; +{$endif fpunone} + varOleStr,varString: + begin + WriteWideString(VarValue); + end; + else + raise EWriteError.CreateFmt(SUnsupportedPropertyVariantType, [Ord(tvardata(VarValue).vtype)]); + end; +end; + + +procedure TBinaryObjectWriter.FlushBuffer; +begin + FStream.WriteBuffer(FBuffer^, FBufPos); + FBufPos := 0; +end; + +procedure TBinaryObjectWriter.Write(const Buffer; Count: LongInt); +var + CopyNow: LongInt; + SourceBuf: PChar; +begin + SourceBuf:=@Buffer; + while Count > 0 do + begin + CopyNow := Count; + if CopyNow > FBufSize - FBufPos then + CopyNow := FBufSize - FBufPos; + Move(SourceBuf^, PChar(FBuffer)[FBufPos], CopyNow); + Dec(Count, CopyNow); + Inc(FBufPos, CopyNow); + inc(SourceBuf, CopyNow); + if FBufPos = FBufSize then + FlushBuffer; + end; +end; + +procedure TBinaryObjectWriter.WriteValue(Value: TValueType); +var + b: byte; +begin + b := byte(Value); + Write(b, 1); +end; + +procedure TBinaryObjectWriter.WriteStr(const Value: String); +var + i: integer; + b: byte; +begin + i := Length(Value); + if i > 255 then + i := 255; + b := i; + Write(b, 1); + if i > 0 then + Write(Value[1], i); +end; + +var + ClassList : TThreadlist; + ClassAliasList : TStringList; + +procedure commoninit(); forward; + +procedure RegisterClass(AClass: TPersistentClass); +var +aClassname : String; +begin + //Classlist is created during initialization. + if classlist = nil then begin + commoninit(); //initialization order sometimes wrong in FPC + end; + { + if classlist = nil then begin + classlist:= tthreadlist.create; + //initialization order sometimes wrong in FPC + end; + if classaliaslist = nil then begin + classaliaslist:= tstringlist.create; + //initialization order sometimes wrong in FPC + end; + } + with Classlist.Locklist do + try + while Indexof(AClass) = -1 do + begin + aClassname := AClass.ClassName; + if GetClass(aClassName) <> nil then //class alread registered! + Begin + //raise an error + exit; + end; + Add(AClass); + if AClass = TPersistent then break; + AClass := TPersistentClass(AClass.ClassParent); + end; + finally + ClassList.UnlockList; + end; +end; + +procedure RegisterClasses(AClasses: array of TPersistentClass); +var +I : Integer; +begin +for I := low(aClasses) to high(aClasses) do + RegisterClass(aClasses[I]); +end; + +procedure RegisterClassAlias(AClass: TPersistentClass; const Alias: string); + var + I : integer; + begin + i := ClassAliasList.IndexOf(Alias); + if I = -1 then + ClassAliasList.AddObject( Alias, TObject(AClass) ); + end; + +procedure UnRegisterClass(AClass: TPersistentClass); +begin + //dummy +end; + +procedure UnRegisterClasses(AClasses: array of TPersistentClass); +begin + //dummy +end; + +procedure UnRegisterModuleClasses(Module: HMODULE); +begin + //dummy +end; + +function FindClass(const AClassName: string): TPersistentClass; + +begin + Result := GetClass(AClassName); + if not Assigned(Result) then + raise EClassNotFound.CreateFmt(SClassNotFound, [AClassName]); +end; + +function GetClass(const AClassName: string): TPersistentClass; +var +I : Integer; +begin + with ClassList.LockList do + try + for I := 0 to Count-1 do + begin + Result := TPersistentClass(Items[I]); + if Result.ClassNameIs(AClassName) then Exit; + end; + I := ClassAliasList.Indexof(AClassName); + if I >= 0 then //found + Begin + Result := TPersistentClass(ClassAliasList.Objects[i]); + exit; + end; + Result := nil; + finally + ClassList.Unlocklist; + end; +end; + +{****************************************************************************} +{* TFileStream *} +{****************************************************************************} + +constructor TFileStream.Create(const AFileName: string; Mode: Word); + +begin + Create(AFileName,Mode,438); +end; + + +constructor TFileStream.Create(const AFileName: string; Mode: Word; Rights: Cardinal); + +begin + FFileName:=AFileName; + If (Mode and fmCreate) > 0 then +{$ifdef FPC} + FHandle:=FileCreate(AFileName,Mode,Rights) +{$else} + FHandle:=FileCreate(AFileName,Rights) +{$endif} + else + FHAndle:=FileOpen(AFileName,Mode); + + If (THandle(FHandle) = feInvalidHandle) then + If Mode=fmcreate then + raise EFCreateError.createfmt(SFCreateError,[AFileName]) + else + raise EFOpenError.Createfmt(SFOpenError,[AFilename]); +end; + + +destructor TFileStream.Destroy; + +begin + FileClose(FHandle); +end; + +{****************************************************************************} +{* THandleStream *} +{****************************************************************************} + +Constructor THandleStream.Create(AHandle: THandle); + +begin + Inherited Create; + FHandle:=AHandle; +end; + + +function THandleStream.Read(var Buffer; Count: Longint): Longint; + +begin + Result:=FileRead(FHandle,Buffer,Count); + If Result=-1 then Result:=0; +end; + + +function THandleStream.Write(const Buffer; Count: Longint): Longint; + +begin + Result:=FileWrite (FHandle,Buffer,Count); + If Result=-1 then Result:=0; +end; + +Procedure THandleStream.SetSize(NewSize: Longint); + +begin + SetSize(Int64(NewSize)); +end; + + +Procedure THandleStream.SetSize(const NewSize: Int64); + +begin + syserror(sys_truncatefile(FHandle,NewSize)); +end; + + +function THandleStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; + +begin + Result:=FileSeek(FHandle,Offset,ord(Origin)); +end; + +function THandleStream.releasehandle(): filehandlety; +begin + result:= fhandle; + fhandle:= invalidfilehandle; +end; + +{****************************************************************************} +{* TStringStream *} +{****************************************************************************} + +function TStringStream.GetSize: Int64; +begin + Result:=Length(FDataString); +end; + +function TStringStream.GetPosition: Int64; +begin + Result:=FPosition; +end; + +procedure TStringStream.SetSize(NewSize: Longint); + +begin + Setlength(FDataString,NewSize); + If FPosition>NewSize then FPosition:=NewSize; +end; + + +constructor TStringStream.Create(const AString: string); + +begin + Inherited create; + FDataString:=AString; +end; + + +function TStringStream.Read(var Buffer; Count: Longint): Longint; + +begin + Result:=Length(FDataString)-FPosition; + If Result>Count then Result:=Count; + // This supposes FDataString to be of type AnsiString ! + Move (Pchar(FDataString)[FPosition],Buffer,Result); + FPosition:=FPosition+Result; +end; + + +function TStringStream.ReadString(Count: Longint): string; + +Var NewLen : Longint; + +begin + NewLen:=Length(FDataString)-FPosition; + If NewLen>Count then NewLen:=Count; + SetLength(Result,NewLen); + Read (Pointer(Result)^,NewLen); +end; + + +function TStringStream.Seek(Offset: Longint; Origin: Word): Longint; + +begin + Case Origin of + soFromBeginning : FPosition:=Offset; + soFromEnd : FPosition:=Length(FDataString)+Offset; + soFromCurrent : FPosition:=FPosition+Offset; + end; + If FPosition>Length(FDataString) then + FPosition:=Length(FDataString) + else If FPosition<0 then + FPosition:=0; + Result:=FPosition; +end; + + +function TStringStream.Write(const Buffer; Count: Longint): Longint; + +begin + Result:=Count; + SetSize(FPosition+Count); + // This supposes that FDataString is of type AnsiString) + Move (Buffer,PChar(FDataString)[Fposition],Count); + FPosition:=FPosition+Count; +end; + + +procedure TStringStream.WriteString(const AString: string); + +begin + Write (PChar(Astring)[0],Length(AString)); +end; + +function TStringStream.getmemory: pointer; +begin + result:= pointer(fdatastring); +end; + +{$ifdef FPC} +{****************************************************************************} +{* TResourceStream *} +{****************************************************************************} + +{$ifdef UNICODE} +procedure TResourceStream.Initialize(Instance: TFPResourceHMODULE; Name, ResType: PWideChar; NameIsID: Boolean); + begin + Res:=FindResource(Instance, Name, ResType); + if Res=0 then + if NameIsID then + raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))]) + else + raise EResNotFound.CreateFmt(SResNotFound,[Name]); + Handle:=LoadResource(Instance,Res); + if Handle=0 then + if NameIsID then + raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))]) + else + raise EResNotFound.CreateFmt(SResNotFound,[Name]); + SetPointer(LockResource(Handle),SizeOfResource(Instance,Res)); + end; + +constructor TResourceStream.Create(Instance: TFPResourceHMODULE; const ResName: WideString; ResType: PWideChar); + begin + inherited create; + Initialize(Instance,PWideChar(ResName),ResType,False); + end; +constructor TResourceStream.CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PWideChar); + begin + inherited create; + Initialize(Instance,PWideChar(ResID),ResType,True); + end; +{$else UNICODE} + +procedure TResourceStream.Initialize(Instance: TFPResourceHMODULE; Name, ResType: PChar; NameIsID: Boolean); + begin + Res:=FindResource(Instance, Name, ResType); + if Res=0 then + if NameIsID then + raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))]) + else + raise EResNotFound.CreateFmt(SResNotFound,[Name]); + Handle:=LoadResource(Instance,Res); + if Handle=0 then + if NameIsID then + raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))]) + else + raise EResNotFound.CreateFmt(SResNotFound,[Name]); + SetPointer(LockResource(Handle),SizeOfResource(Instance,Res)); + end; + +constructor TResourceStream.Create(Instance: TFPResourceHMODULE; const ResName: string; ResType: PChar); + begin + inherited create; + Initialize(Instance,pchar(ResName),ResType,False); + end; +constructor TResourceStream.CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PChar); + begin + inherited create; + Initialize(Instance,pchar(PtrInt(ResID)),ResType,True); + end; +{$endif UNICODE} + + +destructor TResourceStream.Destroy; + begin + UnlockResource(Handle); + FreeResource(Handle); + inherited destroy; + end; +{$endif} + +{****************************************************************************} +{* TOwnerStream *} +{****************************************************************************} + +constructor TOwnerStream.Create(ASource: TStream); +begin + FSource:=ASource; +end; + +destructor TOwnerStream.Destroy; +begin + If FOwner then + FreeAndNil(FSource); + inherited Destroy; +end; + +{****************************************************************************} +{* TCollectionItem *} +{****************************************************************************} + + +function TCollectionItem.GetIndex: Integer; + +begin + if FCollection<>nil then + Result:=FCollection.FItems.IndexOf(Pointer(Self)) + else + Result:=-1; +end; + + + +procedure TCollectionItem.SetCollection(Value: TCollection); + +begin + IF Value<>FCollection then + begin + If FCollection<>Nil then FCollection.RemoveItem(Self); + if Value<>Nil then Value.InsertItem(Self); + FCollection:=Value; + end; +end; + + + +procedure TCollectionItem.Changed(AllItems: Boolean); + +begin + If (FCollection<>Nil) and (FCollection.UpdateCount=0) then + begin + If AllItems then + FCollection.Update(Nil) + else + FCollection.Update(Self); + end; +end; + + + +function TCollectionItem.GetNamePath: string; + +begin + If FCollection<>Nil then + Result:=FCollection.GetNamePath+'['+IntToStr(Index)+']' + else + Result:=ClassName; +end; + + +function TCollectionItem.GetOwner: TPersistent; + +begin + Result:=FCollection; +end; + + + +function TCollectionItem.GetDisplayName: string; + +begin + Result:=ClassName; +end; + + + +procedure TCollectionItem.SetIndex(Value: Integer); + +Var Temp : Longint; + +begin + Temp:=GetIndex; + If (Temp>-1) and (Temp<>Value) then + begin + FCollection.FItems.Move(Temp,Value); + Changed(True); + end; +end; + + +procedure TCollectionItem.SetDisplayName(const Value: string); + +begin + Changed(False); +end; + + + +constructor TCollectionItem.Create(ACollection: TCollection); + +begin + Inherited Create; + SetCollection(ACollection); +end; + + + +destructor TCollectionItem.Destroy; + +begin + SetCollection(Nil); + Inherited Destroy; +end; + +{****************************************************************************} +{* TCollectionEnumerator *} +{****************************************************************************} + +constructor TCollectionEnumerator.Create(ACollection: TCollection); +begin + inherited Create; + FCollection := ACollection; + FPosition := -1; +end; + +function TCollectionEnumerator.GetCurrent: TCollectionItem; +begin + Result := FCollection.Items[FPosition]; +end; + +function TCollectionEnumerator.MoveNext: Boolean; +begin + Inc(FPosition); + Result := FPosition < FCollection.Count; +end; + +{****************************************************************************} +{* TCollection *} +{****************************************************************************} + +function TCollection.Owner: TPersistent; +begin + result:=getowner; +end; + + +function TCollection.GetCount: Integer; + +begin + Result:=FItems.Count; +end; + + +Procedure TCollection.SetPropName; + +Var + TheOwner : TPersistent; + PropList : PPropList; + I, PropCount : Integer; + +begin + FPropName:=''; + TheOwner:=GetOwner; + if (TheOwner=Nil) Or (TheOwner.Classinfo=Nil) Then Exit; + // get information from the owner RTTI + PropCount:=GetPropList(TheOwner, PropList); + Try + For I:=0 To PropCount-1 Do + If (PropList^[i]^.PropType^.Kind=tkClass) And + (GetObjectProp(TheOwner, PropList^[i], ClassType)=Self) Then + Begin + FPropName:=PropList^[i]^.Name; + Exit; + End; + Finally + FreeMem(PropList); + End; +end; + + +function TCollection.GetPropName: string; + +Var + TheOwner : TPersistent; + +begin + Result:=FPropNAme; + TheOwner:=GetOwner; + If (Result<>'') or (TheOwner=Nil) Or (TheOwner.Classinfo=Nil) then exit; + SetPropName; + Result:=FPropName; +end; + + +procedure TCollection.InsertItem(Item: TCollectionItem); +begin + If Not(Item Is FitemClass) then + exit; + FItems.add(Pointer(Item)); + Item.FID:=FNextID; + inc(FNextID); + SetItemName(Item); + Notify(Item,cnAdded); + Changed; +end; + + +{$ifdef mse_fpc_2_6_2} +procedure TCollection.RemoveItem(Item: TCollectionItem); +Var + I : Integer; +begin + Notify(Item,cnExtracting); + I:=FItems.IndexOfItem(Item,fromEnd); + If (I<>-1) then + FItems.Delete(I); + Item.FCollection:=Nil; + Changed; +end; + +{$else} + +procedure TCollection.RemoveItem(Item: TCollectionItem); +begin +Notify(Item,cnExtracting); +FItems.Remove(Pointer(Item)); +Item.FCollection:=Nil; +Changed; +end; +{$endif} + +function TCollection.GetAttrCount: Integer; +begin + Result:=0; +end; + + +function TCollection.GetAttr(Index: Integer): string; +begin + Result:=''; +end; + + +function TCollection.GetItemAttr(Index, ItemIndex: Integer): string; +begin + Result:=TCollectionItem(FItems.Items[ItemIndex]).DisplayName; +end; + + +function TCollection.GetEnumerator: TCollectionEnumerator; +begin + Result := TCollectionEnumerator.Create(Self); +end; + + +function TCollection.GetNamePath: string; +var o : TPersistent; +begin + o:=getowner; + if assigned(o) and (propname<>'') then + result:=o.getnamepath+'.'+propname + else + result:=classname; +end; + + +procedure TCollection.Changed; +begin + if FUpdateCount=0 then + Update(Nil); +end; + + +function TCollection.GetItem(Index: Integer): TCollectionItem; +begin + Result:=TCollectionItem(FItems.Items[Index]); +end; + + +procedure TCollection.SetItem(Index: Integer; Value: TCollectionItem); +begin + TCollectionItem(FItems.items[Index]).Assign(Value); +end; + + +procedure TCollection.SetItemName(Item: TCollectionItem); +begin +end; + + + +procedure TCollection.Update(Item: TCollectionItem); +begin +// FPONotifyObservers(Self,ooChange,Pointer(Item)); +end; + + +constructor TCollection.Create(AItemClass: TCollectionItemClass); +begin + inherited create; + FItemClass:=AItemClass; + FItems:=TFpList.Create; +end; + + +destructor TCollection.Destroy; +begin + BeginUpdate; // Prevent OnChange + DoClear; + FItems.Free; + Inherited Destroy; +end; + + +function TCollection.Add: TCollectionItem; +begin + Result:=FItemClass.Create(Self); +end; + + +procedure TCollection.Assign(Source: TPersistent); +Var I : Longint; +begin + If Source is TCollection then + begin + Clear; + For I:=0 To TCollection(Source).Count-1 do + Add.Assign(TCollection(Source).Items[I]); + exit; + end + else + Inherited Assign(Source); +end; + + +procedure TCollection.BeginUpdate; +begin + inc(FUpdateCount); +end; + + +procedure TCollection.Clear; +begin + if FItems.Count=0 then + exit; // Prevent Changed + BeginUpdate; + try + DoClear; + finally + EndUpdate; + end; +end; + + +procedure TCollection.DoClear; +begin + While FItems.Count>0 do TCollectionItem(FItems.Last).Free; +end; + + +procedure TCollection.EndUpdate; +begin + dec(FUpdateCount); + if FUpdateCount=0 then + Changed; +end; + + +function TCollection.FindItemID(ID: Integer): TCollectionItem; +Var + I : Longint; +begin + For I:=0 to Fitems.Count-1 do + begin + Result:=TCollectionItem(FItems.items[I]); + If Result.Id=Id then + exit; + end; + Result:=Nil; +end; + + +procedure TCollection.Delete(Index: Integer); +Var + Item : TCollectionItem; +begin + Item:=TCollectionItem(FItems[Index]); + Notify(Item,cnDeleting); + Item.Free; +end; + + +function TCollection.Insert(Index: Integer): TCollectionItem; +begin + Result:=Add; + Result.Index:=Index; +end; + + +procedure TCollection.Notify(Item: TCollectionItem;Action: TCollectionNotification); +begin +{ + if Assigned(FObservers) then + Case Action of + cnAdded : FPONotifyObservers(Self,ooAddItem,Pointer(Item)); + cnExtracting : FPONotifyObservers(Self,ooDeleteItem,Pointer(Item)); + cnDeleting : FPONotifyObservers(Self,ooDeleteItem,Pointer(Item)); + end; +} +end; + +procedure TCollection.Sort(Const Compare : TCollectionSortCompare); + +begin + BeginUpdate; + try + FItems.Sort(TListSortCompare(Compare)); + Finally + EndUpdate; + end; +end; + +procedure TCollection.Exchange(Const Index1, index2: integer); + +begin + FItems.Exchange(Index1,Index2); +// FPONotifyObservers(Self,ooChange,Nil); +end; + +{****************************************************************************} +{* TOwnedCollection *} +{****************************************************************************} + + + +Constructor TOwnedCollection.Create(AOwner: TPersistent; AItemClass: TCollectionItemClass); + +Begin + FOwner := AOwner; + inherited Create(AItemClass); +end; + + + +Function TOwnedCollection.GetOwner: TPersistent; + +begin + Result:=FOwner; +end; + +function ExtractStrings(Separators, WhiteSpace: TSysCharSet; Content: PChar; Strings: TStrings): Integer; +var + b, c : pchar; + + procedure SkipWhitespace; + begin + while (c^ in Whitespace) do + inc (c); + end; + + procedure AddString; + var + l : integer; + s : string; + begin + l := c-b; + if l > 0 then + begin + if assigned(Strings) then + begin + setlength(s, l); + move (b^, s[1],l); + Strings.Add (s); + end; + inc (result); + end; + end; + +var + quoted : char; +begin + result := 0; + c := Content; + Quoted := #0; + Separators := Separators + [#13, #10] - ['''','"']; + SkipWhitespace; + b := c; + while (c^ <> #0) do + begin + if (c^ = Quoted) then + begin + if ((c+1)^ = Quoted) then + inc (c) + else + Quoted := #0 + end + else if (Quoted = #0) and (c^ in ['''','"']) then + Quoted := c^; + if (Quoted = #0) and (c^ in Separators) then + begin + AddString; + inc (c); + SkipWhitespace; + b := c; + end + else + inc (c); + end; + if (c <> b) then + AddString; +end; + +var + inited: boolean; + +procedure CommonInit; +begin + if inited then begin + exit; + end; + inited:= true; +// InitCriticalSection(SynchronizeCritSect); +// ExecuteEvent:=RtlEventCreate; +// SynchronizeTimeoutEvent:=RtlEventCreate; +// DoSynchronizeMethod:=false; +// MainThreadID:=GetCurrentThreadID; +{$ifdef FPC} + InitCriticalsection(ResolveSection); +{$else} + InitializeCriticalsection(ResolveSection); +{$endif} +// InitHandlerList:=Nil; +// FindGlobalComponentList:=nil; + IntConstList := TThreadList.Create; +// if classlist = nil then begin + ClassList := TThreadList.Create; +// end; +// if classaliaslist = nil then begin + ClassAliasList := TStringList.Create; +// end; + { on unix this maps to a simple rw synchornizer } + GlobalNameSpace := TMultiReadExclusiveWriteSynchronizer.Create; + RegisterInitComponentHandler(TComponent,@DefaultInitHandler); +end; + + +procedure CommonCleanup; +var + i: Integer; +begin + GlobalNameSpace.BeginWrite; + with IntConstList.LockList do + try + for i := 0 to Count - 1 do + TIntConst(Items[I]).Free; + finally + IntConstList.UnlockList; + end; + IntConstList.Free; + ClassList.Free; + ClassAliasList.Free; + RemoveFixupReferences(nil, ''); +{$ifdef FPC} + DoneCriticalsection(ResolveSection); +{$else} + DeleteCriticalsection(ResolveSection); +{$endif} + GlobalLists.Free; + // ComponentPages.Free; + FreeAndNil(NeedResolving); + globalnamespace.endwrite; + + { GlobalNameSpace is an interface so this is enough } +// GlobalNameSpace:=nil; + + if (InitHandlerList<>Nil) then + for i := 0 to InitHandlerList.Count - 1 do + TInitHandler(InitHandlerList.Items[I]).Free; + InitHandlerList.Free; + InitHandlerList:=Nil; + FindGlobalComponentList.Free; + FindGlobalComponentList:=nil; +// DoneCriticalSection(SynchronizeCritSect); +// RtlEventDestroy(ExecuteEvent); +// RtlEventDestroy(SynchronizeTimeoutEvent); +end; + +initialization + commoninit; +finalization + commoncleanup; +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/mdb.pas b/mseide-msegui/lib/common/fpccompatibility/mdb.pas new file mode 100644 index 0000000..d962c13 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mdb.pas @@ -0,0 +1,11557 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 1999-2000 by Michael Van Canneyt, member of the + Free Pascal development team + + + DB header file with interface section. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + Modified 2013-2018 by Martin Schreiber + + **********************************************************************} +unit mdb; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,sysutils,variants,fmtbcd,maskutils,msetypes,mseifiglob, + msestrings + {$ifndef FPC},classes_del{$endif}; + +const + + dsMaxBufferCount = MAXINT div 8; + dsMaxStringSize = 8192; + + // Used in AsBoolean for string fields to determine + // whether it's true or false. + YesNoChars : Array[Boolean] of char = ('N', 'Y'); + + SQLDelimiterCharacters = [';',',',' ','(',')',#13,#10,#9]; + +type + +{LargeInt} + LargeInt = Int64; + PLargeInt= ^LargeInt; + +{ Auxiliary type } + TStringFieldBuffer = Array[0..dsMaxStringSize] of Char; + +{ Misc Dataset types } + + TDataSetState = (dsInactive, dsBrowse, dsEdit, dsInsert, dsSetKey, + dsCalcFields, dsFilter, dsNewValue, dsOldValue, dsCurValue, dsBlockRead, + dsInternalCalc, dsOpening); + + TDataEvent = (deFieldChange, deRecordChange, deDataSetChange, + deDataSetScroll, deLayoutChange, deUpdateRecord, deUpdateState, + deCheckBrowseMode, dePropertyChange, deFieldListChange, deFocusControl, + deParentScroll,deConnectChange,deReconcileError,deDisabledStateChange); + + TUpdateStatus = (usUnmodified, usModified, usInserted, usDeleted); + TUpdateStatusSet = SET OF TUpdateStatus; + + TUpdateMode = (upWhereAll, upWhereChanged, upWhereKeyOnly); + TResolverResponse = (rrSkip, rrAbort, rrMerge, rrApply, rrIgnore); + +// providerflag1ty = (pf1_refreshinsert,pf1_refreshupdate,pf1_nocopyrecord); +// providerflags1ty = set of providerflag1ty; +// defaultproviderflags = [pfInInsert,pfInUpdate,pfInWhere]; + +{ Forward declarations } + + TFieldDef = class; + TFieldDefs = class; + TField = class; + TFields = Class; + TDataSet = class; + TDataBase = Class; + TDatasource = Class; + TDatalink = Class; + TDBTransaction = Class; + +{ Exception classes } + + EDatabaseError = class(Exception) + public + constructor create(const msg: string; const comp: tcomponent); overload; + end; + + EUpdateError = class(EDatabaseError) + private + FContext : String; + FErrorCode : integer; + FOriginalException : Exception; + FPreviousError : Integer; + public + constructor Create(NativeError, Context : String; + ErrCode, PrevError : integer; E: Exception); + Destructor Destroy; override; + property Context : String read FContext; + property ErrorCode : integer read FErrorcode; + property OriginalException : Exception read FOriginalException; + property PreviousError : Integer read FPreviousError; + end; + + +{ TFieldDef } + + TFieldClass = class of TField; + +{ + TFieldType = (ftUnknown, ftString, ftSmallint, ftInteger, ftWord, + ftBoolean, ftFloat, ftDate, ftTime, ftDateTime, + ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic, + ftFmtMemo, ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor); +} + + TFieldType = (ftUnknown, ftString, ftSmallint, ftInteger, ftWord, + ftBoolean, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime, + ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic, ftFmtMemo, + ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, ftFixedChar, + ftWideString, ftLargeint, ftADT, ftArray, ftReference, + ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, + ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd, ftFixedWideChar, ftWideMemo); + +{ Part of DBCommon, but temporary defined here (bug 8206) } + + TFieldMap = array[TFieldType] of Byte; + +{ TDateTimeRec } + + TDateTimeAlias = type TDateTime; + PDateTimeRec = ^TdateTimeRec; + TDateTimeRec = record + case TFieldType of + ftDate: (Date: Longint); + ftTime: (Time: Longint); + ftDateTime: (DateTime: TDateTimeAlias); + end; + + TFieldAttribute = (faHiddenCol, faReadonly, faRequired, faLink, faUnNamed, faFixed); + TFieldAttributes = set of TFieldAttribute; + + { TNamedItem } + + TNamedItem = class(TCollectionItem) + private + FName: string; + protected + function GetDisplayName: string; override; + procedure SetDisplayName(const AValue: string); override; + Public + property DisplayName : string read GetDisplayName write SetDisplayName; + published + property Name : string read FName write SetDisplayName; + end; + + { TDefCollection } + + TDefCollection = class(TOwnedCollection) + private + FDataset: TDataset; + FUpdated: boolean; + protected + procedure SetItemName(AItem: TCollectionItem); override; + public + constructor create(ADataset: TDataset; AOwner: TPersistent; AClass: TCollectionItemClass); + function Find(const AName: string): TNamedItem; + procedure GetItemNames(List: TStrings); + function IndexOf(const AName: string): Longint; + property Dataset: TDataset read FDataset; + property Updated: boolean read FUpdated write FUpdated; + end; + + { TFieldDef } + + TFieldDef = class(TNamedItem) + Private + FDataType : TFieldType; + FInternalCalcField : Boolean; + FPrecision : Longint; + FRequired : Boolean; + FSize : Integer; + FAttributes : TFieldAttributes; + Function GetFieldClass : TFieldClass; + procedure SetAttributes(AValue: TFieldAttributes); + procedure SetDataType(AValue: TFieldType); + procedure SetPrecision(const AValue: Longint); + procedure SetSize(const AValue: Integer); + procedure SetRequired(const AValue: Boolean); + protected + FFieldNo : Longint; + public + constructor create(ACollection : TCollection); overload; override; + constructor Create(AOwner: TFieldDefs; const AName: string; + ADataType: TFieldType; ASize: Integer; ARequired: Boolean; + AFieldNo: Longint); overload; + destructor Destroy; override; + procedure Assign(APersistent: TPersistent); override; + function CreateField(AOwner: TComponent): TField; + property FieldClass: TFieldClass read GetFieldClass; + property FieldNo: Longint read FFieldNo; + property InternalCalcField: Boolean read FInternalCalcField write FInternalCalcField; + property Required: Boolean read FRequired write SetRequired; + Published + property Attributes: TFieldAttributes read FAttributes write SetAttributes default []; + property DataType: TFieldType read FDataType write SetDataType; + property Precision: Longint read FPrecision write SetPrecision default -1; + property Size: Integer read FSize write SetSize default 0; + end; + +{ TFieldDefs } + + TFieldDefs = class(TDefCollection) + private + FHiddenFields : Boolean; + function GetItem(Index: Longint): TFieldDef; + procedure SetItem(Index: Longint; const AValue: TFieldDef); + public + constructor Create(ADataSet: TDataSet); +// destructor Destroy; override; + procedure Add(const AName: string; ADataType: TFieldType; ASize: Word; ARequired: Boolean); overload; + procedure Add(const AName: string; ADataType: TFieldType; ASize: Word); overload; + procedure Add(const AName: string; ADataType: TFieldType); overload; + Function AddFieldDef : TFieldDef; + procedure Assign(FieldDefs: TFieldDefs); overload; + function Find(const AName: string): TFieldDef; +// procedure Clear; +// procedure Delete(Index: Longint); + procedure Update; overload; + Function MakeNameUnique(const AName : String) : string; virtual; + Property HiddenFields : Boolean Read FHiddenFields Write FHiddenFields; + property Items[Index: Longint]: TFieldDef read GetItem write SetItem; default; + end; + +{ TField } + + TFieldKind = (fkData, fkCalculated, fkLookup, fkInternalCalc); + TFieldKinds = Set of TFieldKind; + + TProviderFlag = (pfInUpdate, pfInWhere, pfInKey, pfHidden) deprecated; +{$push}{$warnings off} + TProviderFlags = set of TProviderFlag deprecated; +{$pop} + + optionfieldty = (of_readonly,of_required,of_visible, + of_filter,of_filtermin,of_filtermax,of_find, + of_initinsert,of_initcopy,of_nocopyrecord,of_nomodified, + of_ininsert,of_inupdate,of_inwhere,of_inkey,of_hidden, + of_refreshinsert,of_refreshupdate, + of_user0,of_user1,of_user2,of_user3, + of_user4,of_user5,of_user6,of_user7); + optionsfieldty = set of optionfieldty; +const + defaultoptionsfield = [of_visible,of_ininsert,of_inupdate,of_inwhere]; + +type + TFieldNotifyEvent = procedure(Sender: TField) of object; + TFieldGetTextEvent = procedure(Sender: TField; var aText: string; + DisplayText: Boolean) of object; + TFieldSetTextEvent = procedure(Sender: TField; const aText: string) of object; + TFieldRef = ^TField; + TFieldChars = set of Char; + + PLookupListRec = ^TLookupListRec; + TLookupListRec = record + Key: Variant; + Value: Variant; + end; + + { TLookupList } + + TLookupList = class(TObject) + private + FList: TFPList; + public + constructor Create; + destructor Destroy; override; + procedure Add(const AKey, AValue: Variant); + procedure Clear; + function FirstKeyByValue(const AValue: Variant): Variant; + function ValueOfKey(const AKey: Variant): Variant; + procedure ValuesToStrings(AStrings: TStrings); + end; + + { TField } + + fielddataenteredeventty = procedure(const sender: tfield; + const editobj: tobject) of object; + integerfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: int32; var accept: boolean) of object; + int64fieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: int64; var accept: boolean) of object; + bcdfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: currency; var accept: boolean) of object; + floatfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: flo64; var accept: boolean) of object; + datetimefieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: tdatetime; var accept: boolean) of object; + + booleanfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: boolean; var accept: boolean) of object; + msestringfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: msestring; var accept: boolean) of object; + ansistringfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: ansistring; var accept: boolean) of object; + TField = class(TComponent) + private + FAlignment : TAlignment; + FAttributeSet : String; + FCalculated : Boolean; + FConstraintErrorMessage : String; + FCustomConstraint : String; + FDataSet : TDataSet; +// FDataSize : Word; + FDataType : TFieldType; + FDefaultExpression : String; + FDisplayLabel : utf8String; + FDisplayWidth : Longint; + FEditMask: TEditMask; + FFieldKind : TFieldKind; + FFieldName : String; + FFields : TFields; + FHasConstraints : Boolean; + FImportedConstraint : String; + FIsIndexField : Boolean; + FKeyFields : String; + FLookupCache : Boolean; + FLookupDataSet : TDataSet; + FLookupKeyfields : String; + FLookupresultField : String; + FLookupList: TLookupList; + FOnChange : TFieldNotifyEvent; + FOnGetText: TFieldGetTextEvent; + FOnSetText: TFieldSetTextEvent; + FOnValidate: TFieldNotifyEvent; + FOrigin : String; +// FReadOnly : Boolean; +// FRequired : Boolean; + FSize : integer; + FValidChars : TFieldChars; +// FVisible : Boolean; +// FProviderFlags : TProviderFlags; + foptionsfield: optionsfieldty; + fondataentered: fielddataenteredeventty; + function GetIndex : longint; + function GetLookup: Boolean; + procedure SetAlignment(const AValue: TAlignMent); + procedure SetIndex(const AValue: Integer); + function GetDisplayText: String; + function GetEditText: String; + procedure SetEditText(const AValue: string); + function getdisplaylabel(): utf8string; + procedure SetDisplayLabel(const AValue: utf8string); + procedure SetDisplayWidth(const AValue: Longint); + function GetDisplayWidth: integer; + procedure SetLookup(const AValue: Boolean); + procedure SetReadOnly(const AValue: Boolean); + procedure SetVisible(const AValue: Boolean); + function IsDisplayStored : Boolean; + function GetLookupList: TLookupList; + procedure CalcLookupValue; + function getProviderFlags: TProviderFlags; + procedure setProviderFlags(const avalue: TProviderFlags); + function getReadOnly: Boolean; + function getRequired: Boolean; + procedure setRequired(const avalue: Boolean); + function getVisible: Boolean; + procedure readproviderflags(reader: treader); + procedure readproviderflags1(reader: treader); + procedure readrequired(reader: treader); + procedure readvisible(reader: treader); + procedure readreadonly(reader: treader); + procedure setoptionsfield(const avalue: optionsfieldty); + procedure setlookupdataset(const avalue: tdataset); + function getbuffervalue: variant; + function getasid: int64; + procedure setasid(const avalue: int64); + protected + FValidating : Boolean; + FValueBuffer : Pointer; + FOffset : Word; + FFieldNo : Longint; + function AccessError(const TypeName: string): EDatabaseError; + procedure CheckInactive; + class procedure CheckTypeSize(AValue: Longint); virtual; + procedure Change; virtual; + procedure DataChanged; + procedure FreeBuffers; virtual; + function GetAsBCD: TBCD; virtual; + function GetAsBoolean: Boolean; virtual; + function GetAsBytes: TBytes; virtual; + function GetAsCurrency: Currency; virtual; + function GetAsLargeInt: LargeInt; virtual; + function GetAsDateTime: TDateTime; virtual; + function getasdate: tdatetime; virtual; + function getastime: tdatetime; virtual; + function GetAsFloat: Double; virtual; + function GetAsLongint: Longint; virtual; + function GetAsInteger: Longint; virtual; + function GetAsVariant: variant; virtual; + function GetOldValue: variant; virtual; + function GetAsString: string; virtual; + function GetAsWideString: WideString; virtual; + function getasunicodestring: unicodestring; virtual; + procedure setasunicodestring(const avalue: unicodestring); virtual; + function GetCanModify: Boolean; virtual; + function GetClassDesc: String; virtual; + function GetDataSize: Integer; virtual; + function GetDefaultWidth: Longint; virtual; + function GetDisplayName : String; + function GetCurValue: Variant; virtual; + function GetNewValue: Variant; virtual; + function GetIsNull: Boolean; virtual; + procedure GetText(var AText: string; ADisplayText: Boolean); virtual; + procedure Notification(AComponent: TComponent; + Operation: TOperation); override; + procedure PropertyChanged(LayoutAffected: Boolean); + procedure ReadState(Reader: TReader); override; + procedure SetAsBCD(const AValue: TBCD); virtual; + procedure SetAsBoolean(AValue: Boolean); virtual; + procedure SetAsBytes(const AValue: TBytes); virtual; + procedure SetAsCurrency(AValue: Currency); virtual; + procedure SetAsDateTime(AValue: TDateTime); virtual; + procedure setasdate(avalue: tdatetime); virtual; + procedure setastime(avalue: tdatetime); virtual; + procedure SetAsFloat(AValue: Double); virtual; + procedure SetAsLongint(AValue: Longint); virtual; + procedure SetAsInteger(AValue: Integer); virtual; + procedure SetAsLargeint(AValue: Largeint); virtual; + procedure SetAsVariant(const AValue: variant); virtual; + procedure SetAsString(const AValue: string); virtual; + procedure SetAsWideString(const aValue: WideString); virtual; + procedure SetDataset(AValue : TDataset); virtual; + procedure SetDataType(AValue: TFieldType); + procedure SetNewValue(const AValue: Variant); + procedure SetSize(AValue: Integer); virtual; + procedure SetParentComponent(AParent: TComponent); override; + procedure SetText(const AValue: string); virtual; + procedure SetVarValue(const AValue: Variant); virtual; + function getasguid: tguid; virtual; + procedure setasguid(const avalue: tguid); virtual; + procedure defineproperties(filer: tfiler); override; + procedure dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean) virtual; + procedure dosetvalue(const sender: tobject; var avalue: int64; + var accept: boolean) virtual; + procedure dosetvalue(const sender: tobject; var avalue: currency; + var accept: boolean) virtual; + procedure dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean) virtual; + procedure dosetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean) virtual; + procedure dosetvalue(const sender: tobject; var avalue: ansistring; + var accept: boolean) virtual; + procedure dodataentered(const sender: tobject) virtual; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure Assign(Source: TPersistent); override; + procedure AssignValue(const AValue: TVarRec); + function GetParentComponent: TComponent; override; + function HasParent: Boolean; override; + procedure Clear; virtual; + procedure FocusControl; + function GetData(Buffer: Pointer): Boolean; overload; + function GetData(Buffer: Pointer; + NativeFormat : Boolean): Boolean; overload; + class function IsBlob: Boolean; virtual; + function IsValidChar(InputChar: Char): Boolean; virtual; + procedure RefreshLookupList; + procedure SetData(Buffer: Pointer); overload; + procedure SetData(Buffer: Pointer; NativeFormat : Boolean); overload; + procedure SetFieldType(AValue: TFieldType); virtual; + procedure Validate(Buffer: Pointer); + property AsBCD: TBCD read GetAsBCD write SetAsBCD; + property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean; + property AsBytes: TBytes read GetAsBytes write SetAsBytes; + property AsCurrency: Currency read GetAsCurrency write SetAsCurrency; + property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime; + property asdate: tdatetime read getasdate write setasdate; + property astime: tdatetime read getastime write setastime; + property AsFloat: Double read GetAsFloat write SetAsFloat; + property asguid: tguid read getasguid write setasguid; + property AsLongint: Longint read GetAsLongint write SetAsLongint; + property AsLargeInt: LargeInt read GetAsLargeInt write SetAsLargeInt; + property asid: int64 read getasid write setasid; //-1 -> NULL + property AsInteger: Integer read GetAsInteger write SetAsInteger; + property AsString: string read GetAsString write SetAsString; + property AsWideString: WideString read GetAsWideString + write SetAsWideString; + property asunicodestring: unicodestring read getasunicodestring + write setasunicodestring; + property asmsestring: msestring read getasunicodestring + write setasunicodestring; + property AsVariant: variant read GetAsVariant write SetAsVariant; + property AttributeSet: string read FAttributeSet write FAttributeSet; + property Calculated: Boolean read FCalculated write FCalculated; + property CanModify: Boolean read GetCanModify; + property CurValue: Variant read GetCurValue; + property DataSet: TDataSet read FDataSet write SetDataSet; + property DataSize: Integer read GetDataSize; + property DataType: TFieldType read FDataType; + property DisplayName: String Read GetDisplayName; + property DisplayText: String read GetDisplayText; + property EditMask: TEditMask read FEditMask write FEditMask; + property EditMaskPtr: TEditMask read FEditMask; + property FieldNo: Longint read FFieldNo; + property IsIndexField: Boolean read FIsIndexField; + property IsNull: Boolean read GetIsNull; + property Lookup: Boolean read GetLookup write SetLookup; + property NewValue: Variant read GetNewValue write SetNewValue; + property Offset: word read FOffset; + property Size: Integer read FSize write SetSize; + property Text: string read GetEditText write SetEditText; + property ValidChars : TFieldChars read FValidChars write FValidChars; + property Value: variant read GetAsVariant write SetAsVariant; + property buffervalue: variant read getbuffervalue; + //returns current value in editbuffer, can be used in OnValidate + property OldValue: variant read GetOldValue; + property LookupList: TLookupList read GetLookupList; +{$push}{$warnings off} + property ProviderFlags : TProviderFlags read getProviderFlags + write setProviderFlags; deprecated; +{$pop} + property ReadOnly: Boolean read getReadOnly write SetReadOnly; + property Required: Boolean read getRequired write setRequired; + property Visible: Boolean read getVisible write SetVisible default True; + published + property Alignment : TAlignment read FAlignment write SetAlignment + default taLeftJustify; + property CustomConstraint: string read FCustomConstraint + write FCustomConstraint; + property ConstraintErrorMessage: string read FConstraintErrorMessage + write FConstraintErrorMessage; + property DefaultExpression: string read FDefaultExpression + write FDefaultExpression; + property DisplayLabel : utf8string read GetDisplaylabel + write SetDisplayLabel stored IsDisplayStored; + property DisplayWidth: Longint read GetDisplayWidth write SetDisplayWidth; + property FieldKind: TFieldKind read FFieldKind write FFieldKind; + property FieldName: string read FFieldName write FFieldName; + property HasConstraints: Boolean read FHasConstraints; + property Index: Longint read GetIndex write SetIndex; + property ImportedConstraint: string read FImportedConstraint + write FImportedConstraint; + property KeyFields: string read FKeyFields write FKeyFields; + property LookupCache: Boolean read FLookupCache write FLookupCache; + property LookupDataSet: TDataSet read FLookupDataSet write setLookupDataSet; + property LookupKeyFields: string read FLookupKeyFields + write FLookupKeyFields; + property LookupResultField: string read FLookupResultField + write FLookupResultField; + property Origin: string read FOrigin write FOrigin; + property optionsfield: optionsfieldty read foptionsfield + write setoptionsfield default defaultoptionsfield; + + property OnChange: TFieldNotifyEvent read FOnChange write FOnChange; + property OnGetText: TFieldGetTextEvent read FOnGetText write FOnGetText; + property OnSetText: TFieldSetTextEvent read FOnSetText write FOnSetText; + property OnValidate: TFieldNotifyEvent read FOnValidate write FOnValidate; + property ondataentered: fielddataenteredeventty read fondataentered write + fondataentered; + end; + +{ TStringField } + + TStringField = class(TField) + private + FFixedChar : boolean; + FTransliterate : Boolean; + fonsetvalue: ansistringfieldsetvalueeventty; + protected + class procedure CheckTypeSize(AValue: Longint); override; + function GetAsBoolean: Boolean; override; + function GetAsDateTime: TDateTime; override; + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + function GetDefaultWidth: Longint; override; + procedure GetText(var AText: string; ADisplayText: Boolean); override; + function GetValue(var AValue: string): Boolean; + procedure SetAsBoolean(AValue: Boolean); override; + procedure SetAsDateTime(AValue: TDateTime); override; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + procedure dosetvalue(const sender: tobject; var avalue: ansistring; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + procedure SetFieldType(AValue: TFieldType); override; + property FixedChar : Boolean read FFixedChar write FFixedChar; + property Transliterate: Boolean read FTransliterate write FTransliterate; + property Value: String read GetAsString write SetAsString; + published + property EditMask; + property Size default 20; + property onsetvalue: ansistringfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TWideStringField } + + TWideStringField = class(TStringField) + protected + class procedure CheckTypeSize(aValue: Integer); override; + + function GetValue(var aValue: WideString): Boolean; + + function GetAsString: string; override; + procedure SetAsString(const aValue: string); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + + function GetAsVariant: Variant; override; + procedure SetVarValue(const aValue: Variant); override; + + function GetAsWideString: WideString; override; + procedure SetAsWideString(const aValue: WideString); override; + + function GetDataSize: Integer; override; + public + constructor Create(aOwner: TComponent); override; + procedure SetFieldType(AValue: TFieldType); override; + property Value: WideString read GetAsWideString write SetAsWideString; + end; + + +{ TNumericField } + TNumericField = class(TField) + Private + FDisplayFormat : utf8String; + FEditFormat : utf8String; + protected + class procedure CheckTypeSize(AValue: Longint); override; + procedure RangeError(AValue, Min, Max: Double); + procedure SetDisplayFormat(const AValue: utf8string); + procedure SetEditFormat(const AValue: utf8string); + function GetAsBoolean: Boolean; override; + Procedure SetAsBoolean(AValue: Boolean); override; + public + constructor Create(AOwner: TComponent); override; + published + property Alignment default taRightJustify; + property DisplayFormat: utf8string read FDisplayFormat write SetDisplayFormat; + property EditFormat: utf8string read FEditFormat write SetEditFormat; + end; + +{ TLongintField } + + TLongintField = class(TNumericField) + private + FMinValue, + FMaxValue, + FMinRange, + FMAxRange : Longint; + fonsetvalue: integerfieldsetvalueeventty; + Procedure SetMinValue (AValue : longint); + Procedure SetMaxValue (AValue : longint); + protected + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + procedure GetText(var AText: string; ADisplayText: Boolean); override; + function GetValue(var AValue: Longint): Boolean; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + function GetAsLargeint: Largeint; override; + procedure SetAsLargeint(AValue: Largeint); override; + procedure dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + Function CheckRange(AValue : longint) : Boolean; + property Value: Longint read GetAsLongint write SetAsLongint; + published + property MaxValue: Longint read FMaxValue write SetMaxValue default 0; + property MinValue: Longint read FMinValue write SetMinValue default 0; + property onsetvalue: integerfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + TIntegerField = Class(TLongintField); + +{ TLargeintField } + + TLargeintField = class(TNumericField) + private + FMinValue, + FMaxValue, + FMinRange, + FMAxRange : Largeint; + fonsetvalue: int64fieldsetvalueeventty; + Procedure SetMinValue (AValue : Largeint); + Procedure SetMaxValue (AValue : Largeint); + protected + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsLargeint: Largeint; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + procedure GetText(var AText: string; ADisplayText: Boolean); override; + function GetValue(var AValue: Largeint): Boolean; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsLargeint(AValue: Largeint); override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + procedure dosetvalue(const sender: tobject; var avalue: int64; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + Function CheckRange(AValue : largeint) : Boolean; + property Value: Largeint read GetAsLargeint write SetAsLargeint; + published + property MaxValue: Largeint read FMaxValue write SetMaxValue default 0; + property MinValue: Largeint read FMinValue write SetMinValue default 0; + property onsetvalue: int64fieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TSmallintField } + + TSmallintField = class(TLongintField) + protected + function GetDataSize: Integer; override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TWordField } + + TWordField = class(TLongintField) + protected + function GetDataSize: Integer; override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TAutoIncField } + + TAutoIncField = class(TLongintField) + Protected + Procedure SetAsLongInt(AValue : Longint); override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TFloatField } + + TFloatField = class(TNumericField) + private + FCurrency: Boolean; + FMaxValue : Double; + FMinValue : Double; + FPrecision : Longint; + fonsetvalue: floatfieldsetvalueeventty; + procedure SetCurrency(const AValue: Boolean); + procedure SetPrecision(const AValue: Longint); + protected + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsVariant: variant; override; + function GetAsString: string; override; + function GetDataSize: Integer; override; + procedure GetText(var theText: string; ADisplayText: Boolean); override; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + procedure dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + Function CheckRange(AValue : Double) : Boolean; + property Value: Double read GetAsFloat write SetAsFloat; + + published + property Currency: Boolean read FCurrency write SetCurrency default False; + property MaxValue: Double read FMaxValue write FMaxValue; + property MinValue: Double read FMinValue write FMinValue; + property Precision: Longint read FPrecision write SetPrecision default 15; // min 2 instellen, delphi compat + property onsetvalue: floatfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TCurrencyField } + + TCurrencyField = class(TFloatField) + public + constructor Create(AOwner: TComponent); override; + published + property Currency default True; + end; + +{ TBooleanField } + + TBooleanField = class(TField) + private + FDisplayValues : String; + // First byte indicates uppercase or not. + FDisplays : Array[Boolean,Boolean] of string; + fonsetvalue: booleanfieldsetvalueeventty; + Procedure SetDisplayValues(const AValue : String); + protected + procedure dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean) override; + function GetAsBoolean: Boolean; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetAsInteger: Longint; override; + function GetDataSize: Integer; override; + function GetDefaultWidth: Longint; override; + procedure SetAsBoolean(AValue: Boolean); override; + procedure SetAsString(const AValue: string); override; + procedure SetAsInteger(AValue: Integer); override; + procedure SetVarValue(const AValue: Variant); override; + public + constructor Create(AOwner: TComponent); override; + property Value: Boolean read GetAsBoolean write SetAsBoolean; + published + property DisplayValues: string read FDisplayValues write SetDisplayValues; + property onsetvalue: booleanfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TDateTimeField } + + TDateTimeField = class(TField) + private + FDisplayFormat : String; + fonsetvalue: datetimefieldsetvalueeventty; + procedure SetDisplayFormat(const AValue: string); + protected + function GetAsDateTime: TDateTime; override; + function getasdate: tdatetime; override; + function getastime: tdatetime; override; + function GetAsFloat: Double; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + procedure GetText(var theText: string; ADisplayText: Boolean); override; + procedure SetAsDateTime(AValue: TDateTime); override; + procedure setasdate(avalue: tdatetime); override; + procedure setastime(avalue: tdatetime); override; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + procedure dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + property Value: TDateTime read GetAsDateTime write SetAsDateTime; + published + property DisplayFormat: string read FDisplayFormat write SetDisplayFormat; + property EditMask; + property onsetvalue: datetimefieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TDateField } + + TDateField = class(TDateTimeField) + public + constructor Create(AOwner: TComponent); override; + end; + +{ TTimeField } + + TTimeField = class(TDateTimeField) + protected + procedure SetAsString(const AValue: string); override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TBinaryField } + + TBinaryField = class(TField) + protected + class procedure CheckTypeSize(AValue: Longint); override; + function GetAsBytes: TBytes; override; + function GetAsString: string; override; + function GetAsVariant: Variant; override; + procedure GetText(var TheText: string; ADisplayText: Boolean); override; + procedure SetAsBytes(const AValue: TBytes); override; + procedure SetAsString(const AValue: string); override; + procedure SetText(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + public + constructor Create(AOwner: TComponent); override; + published + property Size default 16; + end; + +{ TBytesField } + + TBytesField = class(TBinaryField) + protected + function GetDataSize: Integer; override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TVarBytesField } + + TVarBytesField = class(TBytesField) + protected + function GetDataSize: Integer; override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TBCDField } + + TBCDField = class(TNumericField) + private + FMinValue, + FMaxValue : currency; + FPrecision : Longint; + FCurrency : boolean; + fonsetvalue: bcdfieldsetvalueeventty; + protected + class procedure CheckTypeSize(AValue: Longint); override; + function GetAsCurrency: Currency; override; + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsString: string; override; + function GetValue(var AValue: Currency): Boolean; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + function GetDefaultWidth: Longint; override; + procedure GetText(var TheText: string; ADisplayText: Boolean); override; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsString(const AValue: string); override; + procedure SetAsCurrency(AValue: Currency); override; + procedure SetVarValue(const AValue: Variant); override; + procedure dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + Function CheckRange(AValue : Currency) : Boolean; + property Value: Currency read GetAscurrency write SetAscurrency; + published + property Precision: Longint read FPrecision write FPrecision; + property Currency: Boolean read FCurrency write FCurrency; + property MaxValue: Currency read FMaxValue write FMaxValue; + property MinValue: Currency read FMinValue write FMinValue; + property Size default 4; + property onsetvalue: bcdfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TFMTBCDField } + + TFMTBCDField = class(TNumericField) + private + FMinValue, + FMaxValue : TBCD; + FPrecision : Longint; + FCurrency : boolean; + function GetMaxValue: string; + function GetMinValue: string; + procedure SetMaxValue(const AValue: string); + procedure SetMinValue(const AValue: string); + protected + class procedure CheckTypeSize(AValue: Longint); override; + function GetAsBCD: TBCD; override; + function GetAsCurrency: Currency; override; + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + function GetDefaultWidth: Longint; override; + procedure GetText(var TheText: string; ADisplayText: Boolean); override; + procedure SetAsBCD(const AValue: TBCD); override; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsString(const AValue: string); override; + procedure SetAsCurrency(AValue: Currency); override; + procedure SetVarValue(const AValue: Variant); override; + public + constructor Create(AOwner: TComponent); override; + function CheckRange(AValue : TBCD) : Boolean; + property Value: TBCD read GetAsBCD write SetAsBCD; + published + property Precision: Longint read FPrecision write FPrecision default 15; + property Currency: Boolean read FCurrency write FCurrency; + property MaxValue: string read GetMaxValue write SetMaxValue; + property MinValue: string read GetMinValue write SetMinValue; + property Size default 4; + end; + + +{ TBlobField } + TBlobStreamMode = (bmRead, bmWrite, bmReadWrite); + TBlobType = ftBlob..ftWideMemo; + + TBlobField = class(TField) + private + FBlobType : TBlobType; + FModified : Boolean; + FTransliterate : Boolean; + Function GetBlobStream (Mode : TBlobStreamMode) : TStream; + protected + procedure FreeBuffers; override; + function GetAsString: string; override; + function GetAsVariant: Variant; override; + function GetBlobSize: Longint; virtual; + function GetIsNull: Boolean; override; + procedure GetText(var TheText: string; ADisplayText: Boolean); override; + procedure SetAsString(const AValue: string); override; + procedure SetText(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + function GetAsWideString: WideString; override; + procedure SetAsWideString(const aValue: WideString); override; + public + constructor Create(AOwner: TComponent); override; + procedure Clear; override; + class function IsBlob: Boolean; override; + procedure LoadFromFile(const FileName: string); + procedure LoadFromStream(Stream: TStream); + procedure SaveToFile(const FileName: string); + procedure SaveToStream(Stream: TStream); + procedure SetFieldType(AValue: TFieldType); override; + property BlobSize: Longint read GetBlobSize; + property Modified: Boolean read FModified write FModified; + property Value: string read GetAsString write SetAsString; + property Transliterate: Boolean read FTransliterate write FTransliterate; + published + property BlobType: TBlobType read FBlobType write FBlobType; + property Size default 0; + end; + +{ TMemoField } + + TMemoField = class(TBlobField) + protected + function GetAsWideString: WideString; override; + procedure SetAsWideString(const aValue: WideString); override; + public + constructor Create(AOwner: TComponent); override; + published + property Transliterate default True; + end; + +{ TWideMemoField } + + TWideMemoField = class(TBlobField) + protected + function GetAsVariant: Variant; override; + procedure SetVarValue(const AValue: Variant); override; + + function GetAsString: string; override; + procedure SetAsString(const aValue: string); override; + public + constructor Create(aOwner: TComponent); override; + property Value: WideString read GetAsWideString write SetAsWideString; + published + end; + + +{ TGraphicField } + + TGraphicField = class(TBlobField) + public + constructor Create(AOwner: TComponent); override; + end; + +{ TVariantField } + + TVariantField = class(TField) + protected + class procedure CheckTypeSize(aValue: Integer); override; + + function GetAsBoolean: Boolean; override; + procedure SetAsBoolean(aValue: Boolean); override; + + function GetAsDateTime: TDateTime; override; + procedure SetAsDateTime(aValue: TDateTime); override; + + function GetAsFloat: Double; override; + procedure SetAsFloat(aValue: Double); override; + + function GetAsInteger: Longint; override; + procedure SetAsInteger(aValue: Longint); override; + + function GetAsString: string; override; + procedure SetAsString(const aValue: string); override; + + function GetAsWideString: WideString; override; + procedure SetAsWideString(const aValue: WideString); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + + function GetAsVariant: Variant; override; + procedure SetVarValue(const aValue: Variant); override; + + function GetDefaultWidth: Integer; override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TGuidField } + + TGuidField = class(TStringField) + protected + class procedure CheckTypeSize(AValue: Longint); override; + function GetDefaultWidth: Longint; override; + + function GetAsGuid: TGUID; override; + procedure SetAsGuid(const aValue: TGUID); override; + public + constructor Create(AOwner: TComponent); override; +// property AsGuid: TGUID read GetAsGuid write SetAsGuid; + end; + +{ TIndexDef } + + TIndexDefs = class; + + TIndexOption = (ixPrimary, ixUnique, ixDescending, ixCaseInsensitive, + ixExpression, ixNonMaintained); + TIndexOptions = set of TIndexOption; + + TIndexDef = class(TNamedItem) + Private + FCaseinsFields: string; + FDescFields: string; + FExpression : String; + FFields : String; + FOptions : TIndexOptions; + FSource : String; + protected + function GetExpression: string; + procedure SetCaseInsFields(const AValue: string); virtual; + procedure SetDescFields(const AValue: string); + procedure SetExpression(const AValue: string); + public + constructor Create(Owner: TIndexDefs; const AName, TheFields: string; + TheOptions: TIndexOptions); overload; + procedure Assign(Source: TPersistent); override; + property Expression: string read GetExpression write SetExpression; + property Fields: string read FFields write FFields; + property CaseInsFields: string read FCaseinsFields write SetCaseInsFields; + property DescFields: string read FDescFields write SetDescFields; + property Options: TIndexOptions read FOptions write FOptions; + property Source: string read FSource write FSource; + end; + +{ TIndexDefs } + + TIndexDefs = class(TDefCollection) + Private + Function GetItem(Index: Integer): TIndexDef; + Procedure SetItem(Index: Integer; Value: TIndexDef); + public + constructor Create(ADataSet: TDataSet); overload; virtual; + procedure Add(const Name, Fields: string; Options: TIndexOptions); + Function AddIndexDef: TIndexDef; + function Find(const IndexName: string): TIndexDef; + function FindIndexForFields(const Fields: string): TIndexDef; + function GetIndexForFields(const Fields: string; + CaseInsensitive: Boolean): TIndexDef; + procedure Update; overload; virtual; + Property Items[Index: Integer] : TIndexDef read GetItem write SetItem; default; + end; + +{ TCheckConstraint } + + TCheckConstraint = class(TCollectionItem) + Private + FCustomConstraint : String; + FErrorMessage : String; + FFromDictionary : Boolean; + FImportedConstraint : String; + public + procedure Assign(Source: TPersistent); override; + // function GetDisplayName: string; override; + published + property CustomConstraint: string read FCustomConstraint write FCustomConstraint; + property ErrorMessage: string read FErrorMessage write FErrorMessage; + property FromDictionary: Boolean read FFromDictionary write FFromDictionary; + property ImportedConstraint: string read FImportedConstraint write FImportedConstraint; + end; + +{ TCheckConstraints } + + TCheckConstraints = class(TCollection) + Private + Function GetItem(Index : Longint) : TCheckConstraint; + Procedure SetItem(index : Longint; Value : TCheckConstraint); + protected + function GetOwner: TPersistent; override; + public + constructor Create(AOwner: TPersistent); + function Add: TCheckConstraint; + property Items[Index: Longint]: TCheckConstraint read GetItem write SetItem; default; + end; + + { TFieldsEnumerator } + + TFieldsEnumerator = class + private + FPosition: Integer; + FFields: TFields; + function GetCurrent: TField; + public + constructor Create(AFields: TFields); + function MoveNext: Boolean; + property Current: TField read GetCurrent; + end; + +{ TFields } + + Tfields = Class(TObject) + Private + FDataset : TDataset; + FFieldList : TFpList; + FOnChange : TNotifyEvent; + FValidFieldKinds : TFieldKinds; + Protected + Procedure Changed; + Procedure CheckfieldKind(Fieldkind : TFieldKind; Field : TField); + Function GetCount : Longint; + Function GetField (Index : longint) : TField; + Procedure SetField(Index: Integer; Value: TField); + Procedure SetFieldIndex (Field : TField;Value : Integer); + Property OnChange : TNotifyEvent Read FOnChange Write FOnChange; + Property ValidFieldKinds : TFieldKinds Read FValidFieldKinds; + Public + Constructor Create(ADataset : TDataset); + Destructor Destroy;override; + Procedure Add(Field : TField); + Procedure CheckFieldName (Const Value : String); + Procedure CheckFieldNames (Const Value : String); + Procedure Clear; + Function FindField (Const Value : String) : TField; + Function FieldByName (Const Value : String) : TField; + Function FieldByNumber(FieldNo : Integer) : TField; + Function GetEnumerator: TFieldsEnumerator; + Procedure GetFieldNames (Values : TStrings); + Function IndexOf(Field : TField) : Longint; + procedure Remove(Value : TField); + Property Count : Integer Read GetCount; + Property Dataset : TDataset Read FDataset; + Property Fields [Index : Integer] : TField Read GetField Write SetField; default; + end; + + + { TParam } + + TBlobData = AnsiString; // Delphi defines it as alias to TBytes + + TParamBinding = array of integer; + + TParamType = (ptUnknown, ptInput, ptOutput, ptInputOutput, ptResult); + TParamTypes = set of TParamType; + + TParamStyle = (psInterbase,psPostgreSQL,psSimulated); + blobkindty = (bk_none,bk_binary,bk_text); + TParams = class; + + TParam = class(TCollectionItem) + private + FNativeStr: string; + FValue: Variant; + FPrecision: Integer; + FNumericScale: Integer; + FName: string; + FDataType: TFieldType; + FParamType: TParamType; + FSize: Integer; + fblobkind: blobkindty; + Function GetDataSet: TDataSet; + Function IsParamStored: Boolean; + protected + FBound: Boolean; + Procedure AssignParam(Param: TParam); + Procedure AssignTo(Dest: TPersistent); override; + Function GetAsBoolean: Boolean; + Function GetAsCurrency: Currency; + Function GetAsDateTime: TDateTime; + Function GetAsFloat: Double; + Function GetAsInteger: Longint; + Function GetAsLargeInt: LargeInt; + Function GetAsMemo: string; + Function GetAsString: string; + Function GetAsVariant: Variant; + Function GetAsFMTBCD: TBCD; + Function GetDisplayName: string; override; + Function GetIsNull: Boolean; + Function IsEqual(AValue: TParam): Boolean; + Procedure SetAsBlob(const AValue: TBlobData); + Procedure SetAsBoolean(AValue: Boolean); + Procedure SetAsCurrency(const AValue: Currency); + Procedure SetAsDate(const AValue: TDateTime); + Procedure SetAsDateTime(const AValue: TDateTime); + Procedure SetAsFloat(const AValue: Double); + Procedure SetAsInteger(AValue: Longint); + Procedure SetAsLargeInt(AValue: LargeInt); + Procedure SetAsMemo(const AValue: string); + Procedure SetAsSmallInt(AValue: LongInt); + Procedure SetAsString(const AValue: string); + Procedure SetAsTime(const AValue: TDateTime); + Procedure SetAsVariant(const AValue: Variant); + Procedure SetAsWord(AValue: LongInt); + Procedure SetAsFMTBCD(const AValue: TBCD); + Procedure SetDataType(AValue: TFieldType); + Procedure SetText(const AValue: string); + function GetAsWideString: WideString; + procedure SetAsWideString(const aValue: WideString); + function getasunicodestring: unicodestring; + procedure setasunicodestring(const avalue: unicodestring); + function getasnullmsestring: msestring; + procedure setasnullmsestring(const avalue: msestring); + function getasid: int64; + procedure setasid(const avalue: int64); + public + constructor Create(ACollection: TCollection); overload; override; + constructor Create(AParams: TParams; AParamType: TParamType); reintroduce; overload; + Procedure Assign(Source: TPersistent); override; + Procedure AssignField(Field: TField); + Procedure AssignToField(Field: TField); + Procedure AssignFieldValue(Field: TField; const AValue: Variant); + procedure AssignFromField(Field : TField); + Procedure Clear; + Procedure GetData(Buffer: Pointer); + Function GetDataSize: Integer; + Procedure LoadFromFile(const FileName: string; BlobType: TBlobType); + Procedure LoadFromStream(Stream: TStream; BlobType: TBlobType); + Procedure SetBlobData(Buffer: Pointer; ASize: Integer); + Procedure SetData(Buffer: Pointer); + Property AsBlob : TBlobData read GetAsString write SetAsBlob; + Property AsBoolean : Boolean read GetAsBoolean write SetAsBoolean; + Property AsCurrency : Currency read GetAsCurrency write SetAsCurrency; + Property AsDate : TDateTime read GetAsDateTime write SetAsDate; + Property AsDateTime : TDateTime read GetAsDateTime write SetAsDateTime; + Property AsFloat : Double read GetAsFloat write SetAsFloat; + Property AsInteger : LongInt read GetAsInteger write SetAsInteger; + Property AsLargeInt : LargeInt read GetAsLargeInt write SetAsLargeInt; + Property AsMemo : string read GetAsMemo write SetAsMemo; + Property AsSmallInt : LongInt read GetAsInteger write SetAsSmallInt; + Property AsString : string read GetAsString write SetAsString; + Property AsTime : TDateTime read GetAsDateTime write SetAsTime; + Property AsWord : LongInt read GetAsInteger write SetAsWord; + Property AsFMTBCD: TBCD read GetAsFMTBCD write SetAsFMTBCD; + Property Bound : Boolean read FBound write FBound; + Property Dataset : TDataset Read GetDataset; + Property IsNull : Boolean read GetIsNull; + Property NativeStr : string read FNativeStr write FNativeStr; + Property Text : string read GetAsString write SetText; + Property Value : Variant read GetAsVariant write SetAsVariant stored IsParamStored; + property AsWideString: WideString read GetAsWideString write SetAsWideString; + property asunicodestring: unicodestring read getasunicodestring + write setasunicodestring; + property asmsestring: msestring read getasunicodestring + write setasunicodestring; + property asnullmsestring: msestring read getasnullmsestring + write setasnullmsestring; + //'' -> null + property asid: int64 read getasid write setasid; //-1 -> null + property blobkind: blobkindty read fblobkind + write fblobkind default bk_none; + //for blobid + published + Property DataType : TFieldType read FDataType write SetDataType; + Property Name : string read FName write FName; + Property NumericScale : Integer read FNumericScale write FNumericScale default 0; + Property ParamType : TParamType read FParamType write FParamType; + Property Precision : Integer read FPrecision write FPrecision default 0; + Property Size : Integer read FSize write FSize default 0; + end; + + + { TParams } + + TParams = class(TCollection) + private + FOwner: TPersistent; + Function GetItem(Index: Integer): TParam; + Function GetParamValue(const ParamName: string): Variant; + Procedure SetItem(Index: Integer; Value: TParam); + Procedure SetParamValue(const ParamName: string; const Value: Variant); + protected + Procedure AssignTo(Dest: TPersistent); override; + Function GetDataSet: TDataSet; + Function GetOwner: TPersistent; override; + public + Constructor Create(AOwner: TPersistent); overload; + Constructor Create; overload; + Procedure AddParam(Value: TParam); + Procedure AssignValues(Value: TParams); + Function CreateParam(FldType: TFieldType; const ParamName: string; ParamType: TParamType): TParam; + Function FindParam(const Value: string): TParam; + Procedure GetParamList(List: TList; const ParamNames: string); + Function IsEqual(Value: TParams): Boolean; + Function ParamByName(const Value: string): TParam; + Function ParseSQL(SQL: String; DoCreate: Boolean): String; overload; + Function ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle): String; overload; + Function ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding): String; overload; + Function ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding; var ReplaceString : string): String; overload; + Procedure RemoveParam(Value: TParam); + Procedure CopyParamValuesFromDataset(ADataset : TDataset; CopyBound : Boolean); + Property Dataset : TDataset Read GetDataset; + Property Items[Index: Integer] : TParam read GetItem write SetItem; default; + Property ParamValues[const ParamName: string] : Variant read GetParamValue write SetParamValue; + end; + +{ TDataSet } + + TBookmark = Pointer; + TBookmarkStr = string; + + PBookmarkFlag = ^TBookmarkFlag; + TBookmarkFlag = (bfCurrent, bfBOF, bfEOF, bfInserted); + +{ These types are used by Delphi/Unicode to replace the ambiguous "pchar" buffer types. + For now, they are just aliases to PAnsiChar, but in Delphi/Unicode it is pbyte. This will + be changed later (2.8?), to allow a grace period for descendents to catch up. + + Testing with TRecordBuffer=PByte will turn up typing problems. TRecordBuffer=pansichar is backwards + compatible, even if overriden with "pchar" variants. +} + TRecordBufferBaseType = AnsiChar; // must match TRecordBuffer. + TRecordBuffer = PAnsiChar; + PBufferList = ^TBufferList; + TBufferList = array[0..dsMaxBufferCount - 1] of TRecordBuffer; // Dynamic array in Delphi. + TBufferArray = ^TRecordBuffer; + bufferaty = array[0..1] of trecordbuffer; + pbufferaty = ^bufferaty; + + TGetMode = (gmCurrent, gmNext, gmPrior); + + TGetResult = (grOK, grBOF, grEOF, grError); + + TResyncMode = set of (rmExact, rmCenter); + + TDataAction = (daFail, daAbort, daRetry); + + TUpdateAction = (uaFail, uaAbort, uaSkip, uaRetry, uaApplied); + + TUpdateKind = (ukModify, ukInsert, ukDelete); + + + TLocateOption = (loCaseInsensitive, loPartialKey); + TLocateOptions = set of TLocateOption; + + TDataOperation = procedure of object; + + TDataSetNotifyEvent = procedure(DataSet: TDataSet) of object; + TDataSetErrorEvent = procedure(DataSet: TDataSet; E: EDatabaseError; + var DataAction: TDataAction) of object; + + TFilterOption = (foCaseInsensitive, foNoPartialCompare); + TFilterOptions = set of TFilterOption; + + TFilterRecordEvent = procedure(DataSet: TDataSet; + var Accept: Boolean) of object; + + TDatasetClass = Class of TDataset; + + +{------------------------------------------------------------------------------} +{IProviderSupport interface} + + TPSCommandType = ( + ctUnknown, + ctQuery, + ctTable, + ctStoredProc, + ctSelect, + ctInsert, + ctUpdate, + ctDelete, + ctDDL + ); + + IProviderSupport = interface + procedure PSEndTransaction(ACommit: Boolean); + procedure PSExecute; + function PSExecuteStatement(const ASQL: string; AParams: TParams; + ResultSet: Pointer = nil): Integer; + procedure PSGetAttributes(List: TList); + function PSGetCommandText: string; + function PSGetCommandType: TPSCommandType; + function PSGetDefaultOrder: TIndexDef; + function PSGetIndexDefs(IndexTypes: TIndexOptions = [ixPrimary..ixNonMaintained]) + : TIndexDefs; + function PSGetKeyFields: string; + function PSGetParams: TParams; + function PSGetQuoteChar: string; + function PSGetTableName: string; + function PSGetUpdateException(E: Exception; Prev: EUpdateError): EUpdateError; + function PSInTransaction: Boolean; + function PSIsSQLBased: Boolean; + function PSIsSQLSupported: Boolean; + procedure PSReset; + procedure PSSetCommandText(const CommandText: string); + procedure PSSetParams(AParams: TParams); + procedure PSStartTransaction; + function PSUpdateRecord(UpdateKind: TUpdateKind; Delta: TDataSet): Boolean; + end; +{------------------------------------------------------------------------------} + + datasetinternalstatety = (dsis_checkingbrowsemode,dsis_refreshing, + dsis_recordcopy); + datasetinternalstatesty = set of datasetinternalstatety; + + TDataSet = class(TComponent) + Private + Procedure DoInsertAppend(DoAppend : Boolean); + Procedure DoInternalOpen; + Function GetBuffer (Index : longint) : TRecordBuffer; + Function GetField (Index : Longint) : TField; + Procedure RegisterDataSource(ADatasource : TDataSource); + Procedure RemoveField (Field : TField); + procedure SetConstraints(Value: TCheckConstraints); + Procedure SetField (Index : Longint;Value : TField); + Procedure ShiftBuffersForward; + Procedure ShiftBuffersBackward; + Function TryDoing (P : TDataOperation; Ev : TDatasetErrorEvent) : Boolean; + Procedure UnRegisterDataSource(ADatasource : TDatasource); + Procedure UpdateFieldDefs; + procedure SetBlockReadSize(AValue: Integer); virtual; + Procedure SetFieldDefs(AFieldDefs: TFieldDefs); + procedure DoInsertAppendRecord(const Values: array of const; DoAppend : boolean); + protected + FOpenAfterRead : boolean; + FActiveRecord: Longint; + FAfterCancel: TDataSetNotifyEvent; + FAfterClose: TDataSetNotifyEvent; + FAfterDelete: TDataSetNotifyEvent; + FAfterEdit: TDataSetNotifyEvent; + FAfterInsert: TDataSetNotifyEvent; + FAfterOpen: TDataSetNotifyEvent; + FAfterPost: TDataSetNotifyEvent; + FAfterRefresh: TDataSetNotifyEvent; + FAfterScroll: TDataSetNotifyEvent; + FAutoCalcFields: Boolean; + FBOF: Boolean; + FBeforeCancel: TDataSetNotifyEvent; + FBeforeClose: TDataSetNotifyEvent; + FBeforeDelete: TDataSetNotifyEvent; + FBeforeEdit: TDataSetNotifyEvent; + FBeforeInsert: TDataSetNotifyEvent; + FBeforeOpen: TDataSetNotifyEvent; + FBeforePost: TDataSetNotifyEvent; + FBeforeRefresh: TDataSetNotifyEvent; + FBeforeScroll: TDataSetNotifyEvent; + FBlobFieldCount: Longint; + FBlockReadSize: Integer; + FBookmarkSize: Longint; + FBuffers : TBufferArray; + FBufferCount: Longint; + FCalcBuffer: TRecordBuffer; + FCalcFieldsSize: Longint; + FConstraints: TCheckConstraints; + FDisableControlsCount : Integer; + FDisableControlsState : TDatasetState; + FCurrentRecord: Longint; + FDataSources : TList; + FDefaultFields: Boolean; + FEOF: Boolean; + FEnableControlsEvent : TDataEvent; + FFieldList : TFields; + FFieldDefs: TFieldDefs; + FFilterOptions: TFilterOptions; + FFilterText: string; + FFiltered: Boolean; + FFound: Boolean; + FInternalCalcFields: Boolean; + FModified: Boolean; + FOnCalcFields: TDataSetNotifyEvent; + FOnDeleteError: TDataSetErrorEvent; + FOnEditError: TDataSetErrorEvent; + FOnFilterRecord: TFilterRecordEvent; + FOnNewRecord: TDataSetNotifyEvent; + FOnPostError: TDataSetErrorEvent; + fonmodified: tdatasetnotifyevent; + FRecordCount: Longint; + FIsUniDirectional: Boolean; + FState : TDataSetState; + finternalstate: datasetinternalstatesty; + FInternalOpenComplete: Boolean; + Function GetActive : boolean; + procedure RecalcBufListSize; + procedure ActivateBuffers; virtual; + procedure BindFields(Binding: Boolean); + procedure BlockReadNext; virtual; + function BookmarkAvailable: Boolean; + procedure CalculateFields(Buffer: TRecordBuffer); virtual; + procedure CheckActive; virtual; + procedure CheckInactive; virtual; + procedure CheckBiDirectional; + procedure Loaded; override; + procedure ClearBuffers; virtual; + procedure ClearCalcFields(Buffer: TRecordBuffer); virtual; + procedure CloseBlob(Field: TField); virtual; + procedure CloseCursor; virtual; + procedure CreateFields; virtual; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); virtual; + procedure DestroyFields; virtual; + procedure DoAfterCancel; virtual; + procedure DoAfterClose; virtual; + procedure DoAfterDelete; virtual; + procedure DoAfterEdit; virtual; + procedure DoAfterInsert; virtual; + procedure DoAfterOpen; virtual; + procedure DoAfterPost; virtual; + procedure DoAfterScroll; virtual; + procedure DoAfterRefresh; virtual; + procedure DoBeforeCancel; virtual; + procedure DoBeforeClose; virtual; + procedure DoBeforeDelete; virtual; + procedure DoBeforeEdit; virtual; + procedure DoBeforeInsert; virtual; + procedure DoBeforeOpen; virtual; + procedure DoBeforePost; virtual; + procedure DoBeforeScroll; virtual; + procedure DoBeforeRefresh; virtual; + procedure DoOnCalcFields; virtual; + procedure DoOnNewRecord; virtual; + procedure domodified virtual; + function FieldByNumber(FieldNo: Longint): TField; + function FindRecord(Restart, GoForward: Boolean): Boolean; virtual; + procedure FreeFieldBuffers; virtual; + function GetBookmarkStr: TBookmarkStr; virtual; + procedure GetCalcFields(Buffer: TRecordBuffer); virtual; + function GetCanModify: Boolean; virtual; + procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; + function GetFieldClass(FieldType: TFieldType): TFieldClass; virtual; + Function GetfieldCount : Integer; + function GetFieldValues(const fieldname : string) : Variant; virtual; + function GetIsIndexField(Field: TField): Boolean; virtual; + function GetIndexDefs(IndexDefs : TIndexDefs; IndexTypes : TIndexOptions) : TIndexDefs; + function GetNextRecords: Longint; virtual; + function GetNextRecord: Boolean; virtual; + function GetPriorRecords: Longint; virtual; + function GetPriorRecord: Boolean; virtual; + function GetRecordCount: Longint; virtual; + function GetRecNo: Longint; virtual; + procedure InitFieldDefs; virtual; + procedure InitFieldDefsFromfields; + procedure InitRecord(Buffer: TRecordBuffer); virtual; + procedure InternalCancel; virtual; + procedure InternalEdit; virtual; + procedure InternalInsert; virtual; + procedure InternalRefresh; virtual; + procedure OpenCursor(InfoQuery: Boolean); virtual; + procedure OpenCursorcomplete; virtual; + procedure RefreshInternalCalcFields(Buffer: TRecordBuffer); virtual; + procedure RestoreState(const Value: TDataSetState); + procedure sortdatasources(); + Procedure SetActive (Value : Boolean); virtual; + procedure SetBookmarkStr(const Value: TBookmarkStr); virtual; + procedure SetBufListSize(Value: Longint); virtual; + procedure SetChildOrder(Component: TComponent; Order: Longint); override; + procedure SetCurrentRecord(Index: Longint); virtual; + procedure SetDefaultFields(const Value: Boolean); + procedure SetFiltered(Value: Boolean); virtual; + procedure SetFilterOptions(Value: TFilterOptions); virtual; + procedure SetFilterText(const Value: string); virtual; + procedure SetFieldValues(const fieldname: string; Value: Variant); virtual; + procedure SetFound(const Value: Boolean); virtual; + procedure SetModified(Value: Boolean); + procedure SetName(const Value: TComponentName); override; + procedure SetOnFilterRecord(const Value: TFilterRecordEvent); virtual; + procedure SetRecNo(Value: Longint); virtual; + procedure SetState(Value: TDataSetState); + function SetTempState(const Value: TDataSetState): TDataSetState; + Function Tempbuffer: TRecordBuffer; + procedure UpdateIndexDefs; virtual; + property ActiveRecord: Longint read FActiveRecord; + property CurrentRecord: Longint read FCurrentRecord; + property BlobFieldCount: Longint read FBlobFieldCount; + property BookmarkSize: Longint read FBookmarkSize write FBookmarkSize; + property Buffers[Index: Longint]: TRecordBuffer read GetBuffer; + property BufferCount: Longint read FBufferCount; + property CalcBuffer: TRecordBuffer read FCalcBuffer; + property CalcFieldsSize: Longint read FCalcFieldsSize; + property InternalCalcFields: Boolean read FInternalCalcFields; + property Constraints: TCheckConstraints read FConstraints write SetConstraints; + function AllocRecordBuffer: TRecordBuffer; virtual; + procedure FreeRecordBuffer(var Buffer: TRecordBuffer); virtual; + procedure GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); virtual; + function GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; virtual; + function GetDataSource: TDataSource; virtual; + function GetRecordSize: Word; virtual; + procedure InternalAddRecord(Buffer: Pointer; AAppend: Boolean); virtual; + procedure InternalDelete; virtual; + procedure InternalFirst; virtual; + procedure InternalGotoBookmark(ABookmark: Pointer); virtual; + procedure InternalHandleException; virtual; + procedure InternalInitRecord(Buffer: TRecordBuffer); virtual; + procedure InternalLast; virtual; + procedure InternalPost; virtual; + procedure InternalSetToRecord(Buffer: TRecordBuffer); virtual; + procedure SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); virtual; + procedure SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); virtual; + procedure SetUniDirectional(const Value: Boolean); + protected { abstract methods } + function GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean): TGetResult; virtual; abstract; + procedure InternalClose; virtual; abstract; + procedure InternalOpen; virtual; abstract; + procedure InternalInitFieldDefs; virtual; abstract; + function IsCursorOpen: Boolean; virtual; abstract; + protected { IProviderSupport methods } + procedure PSEndTransaction(Commit: Boolean); virtual; + procedure PSExecute; virtual; + function PSExecuteStatement(const ASQL: string; AParams: TParams; + ResultSet: Pointer = nil): Integer; virtual; + procedure PSGetAttributes(List: TList); virtual; + function PSGetCommandText: string; virtual; + function PSGetCommandType: TPSCommandType; virtual; + function PSGetDefaultOrder: TIndexDef; virtual; + function PSGetIndexDefs(IndexTypes: TIndexOptions = [ixPrimary..ixNonMaintained]) + : TIndexDefs; virtual; + function PSGetKeyFields: string; virtual; + function PSGetParams: TParams; virtual; + function PSGetQuoteChar: string; virtual; + function PSGetTableName: string; virtual; + function PSGetUpdateException(E: Exception; Prev: EUpdateError) + : EUpdateError; virtual; + function PSInTransaction: Boolean; virtual; + function PSIsSQLBased: Boolean; virtual; + function PSIsSQLSupported: Boolean; virtual; + procedure PSReset; virtual; + procedure PSSetCommandText(const CommandText: string); virtual; + procedure PSSetParams(AParams: TParams); virtual; + procedure PSStartTransaction; virtual; + function PSUpdateRecord(UpdateKind: TUpdateKind; Delta: TDataSet) + : Boolean; virtual; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + function ActiveBuffer: TRecordBuffer; + function GetFieldData(Field: TField; Buffer: Pointer): Boolean; overload; virtual; + function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; overload; virtual; + procedure SetFieldData(Field: TField; Buffer: Pointer); overload; virtual; + procedure SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean); overload; virtual; + procedure Append; + procedure AppendRecord(const Values: array of const); + function BookmarkValid(ABookmark: TBookmark): Boolean; virtual; + procedure Cancel; virtual; + procedure CheckBrowseMode; + procedure ClearFields; + procedure Close; + function ControlsDisabled: Boolean; + function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Longint; virtual; + function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; virtual; + procedure CursorPosChanged; + procedure DataConvert(aField: TField; aSource, aDest: Pointer; aToNative: Boolean); virtual; + procedure Delete; virtual; + procedure DisableControls; + procedure Edit; + procedure EnableControls; virtual; + function FieldByName(const FieldName: string): TField; + function FindField(const FieldName: string): TField; + function FindFirst: Boolean; virtual; + function FindLast: Boolean; virtual; + function FindNext: Boolean; virtual; + function FindPrior: Boolean; virtual; + procedure First; + procedure FreeBookmark(ABookmark: TBookmark); virtual; + function GetBookmark: TBookmark; virtual; + function GetCurrentRecord(Buffer: TRecordBuffer): Boolean; virtual; + procedure GetFieldList(List: TList; const FieldNames: string); + procedure GetFieldNames(List: TStrings); + procedure GotoBookmark(ABookmark: TBookmark); + procedure Insert; virtual; + procedure InsertRecord(const Values: array of const); + function IsEmpty: Boolean; + function IsLinkedTo(ADataSource: TDataSource): Boolean; + function IsSequenced: Boolean; virtual; + procedure Last; + function Locate(const keyfields: string; const keyvalues: Variant; options: TLocateOptions) : boolean; virtual; + function Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant; virtual; + function MoveBy(Distance: Longint): Longint; + procedure Next; + procedure Open; + procedure Post; virtual; + procedure Prior; + procedure Refresh; + function refreshing: boolean; + procedure Resync(Mode: TResyncMode); virtual; + procedure SetFields(const Values: array of const); + function Translate(Src, Dest: PChar; ToOem: Boolean): Integer; virtual; + procedure UpdateCursorPos; + procedure UpdateRecord; virtual; + function UpdateStatus: TUpdateStatus; virtual; + property BlockReadSize: Integer read FBlockReadSize write SetBlockReadSize; + property BOF: Boolean read FBOF; + property Bookmark: TBookmarkStr read GetBookmarkStr write SetBookmarkStr; + property CanModify: Boolean read GetCanModify; + property DataSource: TDataSource read GetDataSource; + property DefaultFields: Boolean read FDefaultFields; + property EOF: Boolean read FEOF; + property FieldCount: Longint read GetFieldCount; + property FieldDefs: TFieldDefs read FFieldDefs write SetFieldDefs; +// property Fields[Index: Longint]: TField read GetField write SetField; + property Found: Boolean read FFound; + property Modified: Boolean read FModified; + procedure modify(const callmodified: boolean = true); //set modified flag + procedure resetmodified(); //clears modified flag + property IsUniDirectional: Boolean read FIsUniDirectional default False; + property RecordCount: Longint read GetRecordCount; + property RecNo: Longint read GetRecNo write SetRecNo; + property RecordSize: Word read GetRecordSize; + property State: TDataSetState read FState; + property Fields : TFields read FFieldList; + property FieldValues[const fieldname: string] : Variant read GetFieldValues + write SetFieldValues; default; + property Filter: string read FFilterText write SetFilterText; + property Filtered: Boolean read FFiltered write SetFiltered default False; + property FilterOptions: TFilterOptions read FFilterOptions write SetFilterOptions; + property Active: Boolean read GetActive write SetActive default False; + property AutoCalcFields: Boolean read FAutoCalcFields write FAutoCalcFields default true; + property BeforeOpen: TDataSetNotifyEvent read FBeforeOpen write FBeforeOpen; + property AfterOpen: TDataSetNotifyEvent read FAfterOpen write FAfterOpen; + property BeforeClose: TDataSetNotifyEvent read FBeforeClose write FBeforeClose; + property AfterClose: TDataSetNotifyEvent read FAfterClose write FAfterClose; + property BeforeInsert: TDataSetNotifyEvent read FBeforeInsert write FBeforeInsert; + property AfterInsert: TDataSetNotifyEvent read FAfterInsert write FAfterInsert; + property BeforeEdit: TDataSetNotifyEvent read FBeforeEdit write FBeforeEdit; + property AfterEdit: TDataSetNotifyEvent read FAfterEdit write FAfterEdit; + property BeforePost: TDataSetNotifyEvent read FBeforePost write FBeforePost; + property AfterPost: TDataSetNotifyEvent read FAfterPost write FAfterPost; + property BeforeCancel: TDataSetNotifyEvent read FBeforeCancel write FBeforeCancel; + property AfterCancel: TDataSetNotifyEvent read FAfterCancel write FAfterCancel; + property BeforeDelete: TDataSetNotifyEvent read FBeforeDelete write FBeforeDelete; + property AfterDelete: TDataSetNotifyEvent read FAfterDelete write FAfterDelete; + property BeforeScroll: TDataSetNotifyEvent read FBeforeScroll write FBeforeScroll; + property AfterScroll: TDataSetNotifyEvent read FAfterScroll write FAfterScroll; + property BeforeRefresh: TDataSetNotifyEvent read FBeforeRefresh write FBeforeRefresh; + property AfterRefresh: TDataSetNotifyEvent read FAfterRefresh write FAfterRefresh; + property OnCalcFields: TDataSetNotifyEvent read FOnCalcFields write FOnCalcFields; + property OnDeleteError: TDataSetErrorEvent read FOnDeleteError write FOnDeleteError; + property OnEditError: TDataSetErrorEvent read FOnEditError write FOnEditError; + property OnFilterRecord: TFilterRecordEvent read FOnFilterRecord write SetOnFilterRecord; + property OnNewRecord: TDataSetNotifyEvent read FOnNewRecord write FOnNewRecord; + property OnPostError: TDataSetErrorEvent read FOnPostError write FOnPostError; + property onmodified: tdatasetnotifyevent read fonmodified write fonmodified; + end; + + TDataLink = class(TPersistent) + private + FFirstRecord, + FBufferCount : Integer; + FActive, + FDataSourceFixed, + FEditing, + FReadOnly, + FUpdatingRecord, + FVisualControl : Boolean; + FDataSource : TDataSource; + Function CalcFirstRecord(Index : Integer) : Integer; + Procedure CalcRange; + Procedure CheckActiveAndEditing; + Function GetDataset : TDataset; + procedure SetActive(AActive: Boolean); + procedure SetDataSource(Value: TDataSource); + Procedure SetReadOnly(Value : Boolean); + function getreadonly: Boolean; + function getactive: Boolean; + protected + function datasourcereadonly(): boolean virtual; + procedure updateactive(); + procedure ActiveChanged; virtual; + procedure CheckBrowseMode; virtual; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); virtual; + procedure DataSetChanged; virtual; + procedure DataSetScrolled(Distance: Integer); virtual; + procedure EditingChanged; virtual; + procedure FocusControl(Field: TFieldRef); virtual; + function GetActiveRecord: Integer; virtual; + function GetBOF: Boolean; virtual; + function GetBufferCount: Integer; virtual; + function GetEOF: Boolean; virtual; + function GetRecordCount: Integer; virtual; + procedure LayoutChanged; virtual; + function MoveBy(Distance: Integer): Integer; virtual; + procedure RecordChanged(Field: TField); virtual; + procedure SetActiveRecord(Value: Integer); virtual; + procedure SetBufferCount(Value: Integer); virtual; + procedure UpdateData; virtual; + property VisualControl: Boolean read FVisualControl write FVisualControl; + property FirstRecord: Integer read FFirstRecord write FFirstRecord; +// procedure doenter(const aobject: tobject); +// procedure doexit(const aobject: tobject); + public + constructor Create; + destructor Destroy; override; + function Edit: Boolean; + procedure UpdateRecord; + function ExecuteAction(Action: TBasicAction): Boolean; virtual; + function UpdateAction(Action: TBasicAction): Boolean; virtual; + property Active: Boolean read getactive; + property ActiveRecord: Integer read GetActiveRecord write SetActiveRecord; + property BOF: Boolean read GetBOF; + property BufferCount: Integer read GetBufferCount write SetBufferCount; + property DataSet: TDataSet read GetDataSet; + property DataSource: TDataSource read FDataSource write SetDataSource; + property DataSourceFixed: Boolean read FDataSourceFixed write FDataSourceFixed; + property Editing: Boolean read FEditing; + property Eof: Boolean read GetEOF; + property ReadOnly: Boolean read getreadonly write SetReadOnly; + property RecordCount: Integer read GetRecordCount; + end; + +{ TDetailDataLink } + + TDetailDataLink = class(TDataLink) + protected + function GetDetailDataSet: TDataSet; virtual; + public + property DetailDataSet: TDataSet read GetDetailDataSet; + end; + +{ TMasterDataLink } + + TMasterDataLink = class(TDetailDataLink) + private + FDetailDataSet: TDataSet; + FFieldNames: string; + FFields: TList; + FOnMasterChange: TNotifyEvent; + FOnMasterDisable: TNotifyEvent; + procedure SetFieldNames(const Value: string); + protected + procedure ActiveChanged; override; + procedure CheckBrowseMode; override; + function GetDetailDataSet: TDataSet; override; + procedure LayoutChanged; override; + procedure RecordChanged(Field: TField); override; + Procedure DoMasterDisable; virtual; + Procedure DoMasterChange; virtual; + public + constructor Create(ADataSet: TDataSet);virtual; + destructor Destroy; override; + property FieldNames: string read FFieldNames write SetFieldNames; + property Fields: TList read FFields; + property OnMasterChange: TNotifyEvent read FOnMasterChange write FOnMasterChange; + property OnMasterDisable: TNotifyEvent read FOnMasterDisable write FOnMasterDisable; + end; + +{ TDataSource } + + TDataChangeEvent = procedure(Sender: TObject; Field: TField) of object; + + ifistatechangedeventty = procedure(const sender: tdatasource; + const alink: tdatalink; const aclient: iificlient; + const astate: ifiwidgetstatesty) of object; + + TDataSource = class(TComponent) + private + FDataSet: TDataSet; + FDataLinks: TList; + FEnabled: Boolean; + FAutoEdit: Boolean; + FState: TDataSetState; + FOnStateChange: TNotifyEvent; + FOnDataChange: TDataChangeEvent; + FOnUpdateData: TNotifyEvent; +// fonenter: datasourcelinkobjecteventty; +// fonexit: datasourcelinkobjecteventty; + fonifistatechanged: ifistatechangedeventty; + freadonly: boolean; + fpriority: int32; + fonenabledchange: tnotifyevent; + procedure DistributeEvent(Event: TDataEvent; Info: Ptrint); + procedure RegisterDataLink(DataLink: TDataLink); + Procedure ProcessEvent(Event : TDataEvent; Info : Ptrint); + procedure SetDataSet(ADataSet: TDataSet); + procedure SetEnabled(Value: Boolean); + procedure UnregisterDataLink(DataLink: TDataLink); + procedure setreadonly(const avalue: boolean); + function getactive: boolean; + protected + function caneventdistribute: boolean; + Procedure DoDataChange (Info : Pointer);virtual; + Procedure DoStateChange; virtual; + procedure doenabledchange; virtual; + Procedure DoUpdateData; + property DataLinks: TList read FDataLinks; + procedure ifistatechanged(const sender: tdatalink; + const aclient: iificlient; + const astate: ifiwidgetstatesty); virtual; +// procedure doenter(const alink: tdatalink; const aobject: tobject); +// procedure doexit(const alink: tdatalink; const aobject: tobject); + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure Edit; + procedure updaterecord(); + function IsLinkedTo(ADataSet: TDataSet): Boolean; + property State: TDataSetState read FState; + property active: boolean read getactive; + published + property AutoEdit: Boolean read FAutoEdit write FAutoEdit default True; + property DataSet: TDataSet read FDataSet write SetDataSet; + property Enabled: Boolean read FEnabled write SetEnabled default True; + property readonly: boolean read freadonly write setreadonly default false; + property priority: int32 read fpriority write fpriority default 0; + //highest priority handled first by dataset + property OnStateChange: TNotifyEvent read FOnStateChange + write FOnStateChange; + property onenabledchange: tnotifyevent read fonenabledchange + write fonenabledchange; + property OnDataChange: TDataChangeEvent read FOnDataChange + write FOnDataChange; + property OnUpdateData: TNotifyEvent read FOnUpdateData write FOnUpdateData; + property onifistatechanged: ifistatechangedeventty + read fonifistatechanged write fonifistatechanged; +// property onenter: datasourcelinkobjecteventty read fonenter write fonenter; +// property onexit: datasourcelinkobjecteventty read fonexit write fonexit; + end; + + { TDBDataset } + + TDBDatasetClass = Class of TDBDataset; + TDBDataset = Class(TDataset) + Private + FDatabase : TDatabase; + FTransaction : TDBTransaction; + Protected + Procedure SetDatabase (Value : TDatabase); virtual; + Procedure SetTransaction(Value : TDBTransaction); virtual; + Procedure CheckDatabase; + Public + Destructor destroy; override; + Property DataBase : TDatabase Read FDatabase Write SetDatabase; + Property Transaction : TDBTransaction Read FTransaction Write SetTransaction; + end; + + { TDBTransaction } + + TDBTransactionClass = Class of TDBTransaction; + TDBTransaction = Class(TComponent) + Private + FActive : boolean; + FDatabase : TDatabase; + FDataSets : TList; + FOpenAfterRead : boolean; + Function GetDataSetCount : Longint; + Function GetDataset(Index : longint) : TDBDataset; + procedure RegisterDataset (DS : TDBDataset); + procedure UnRegisterDataset (DS : TDBDataset); + procedure RemoveDataSets; + procedure SetActive(Value : boolean); + Protected + Procedure SetDatabase (Value : TDatabase); virtual; + procedure CloseTrans; + procedure openTrans; + Procedure CheckDatabase; + Procedure CheckActive; + Procedure CheckInactive; + procedure EndTransaction; virtual; abstract; + procedure StartTransaction; virtual; abstract; + procedure InternalHandleException; virtual; + procedure Loaded; override; + Public + constructor Create(AOwner: TComponent); override; + Destructor destroy; override; + procedure CloseDataSets; + Property DataBase : TDatabase Read FDatabase Write SetDatabase; + published + property Active : boolean read FActive write setactive; + end; + + { TCustomConnection } + + TLoginEvent = procedure(Sender: TObject; Username, Password: string) of object; + + TCustomConnection = class(TComponent) + private + FAfterConnect: TNotifyEvent; + FAfterDisconnect: TNotifyEvent; + FBeforeConnect: TNotifyEvent; + FBeforeDisconnect: TNotifyEvent; + FLoginPrompt: Boolean; + FOnLogin: TLoginEvent; + FStreamedConnected: Boolean; + procedure SetAfterConnect(const AValue: TNotifyEvent); + procedure SetAfterDisconnect(const AValue: TNotifyEvent); + procedure SetBeforeConnect(const AValue: TNotifyEvent); + procedure SetBeforeDisconnect(const AValue: TNotifyEvent); + protected + procedure DoConnect; virtual; + procedure DoDisconnect; virtual; + function GetConnected : boolean; virtual; + Function GetDataset(Index : longint) : TDataset; virtual; + Function GetDataSetCount : Longint; virtual; + procedure InternalHandleException; virtual; + procedure Loaded; override; + procedure SetConnected (Value : boolean); virtual; + property Streamedconnected: Boolean read FStreamedConnected write FStreamedConnected; + public + procedure Close; + destructor Destroy; override; + procedure Open; + property DataSetCount: Longint read GetDataSetCount; + property DataSets[Index: Longint]: TDataSet read GetDataSet; + published + property Connected: Boolean read GetConnected write SetConnected; + property LoginPrompt: Boolean read FLoginPrompt write FLoginPrompt; + + property AfterConnect : TNotifyEvent read FAfterConnect write SetAfterConnect; + property AfterDisconnect : TNotifyEvent read FAfterDisconnect write SetAfterDisconnect; + property BeforeConnect : TNotifyEvent read FBeforeConnect write SetBeforeConnect; + property BeforeDisconnect : TNotifyEvent read FBeforeDisconnect write SetBeforeDisconnect; + property OnLogin: TLoginEvent read FOnLogin write FOnLogin; + end; + + + { TDatabase } + + TDatabaseClass = Class Of TDatabase; + + TDatabase = class(TCustomConnection) + private + FConnected : Boolean; + FDataBaseName : String; + FDataSets : TList; + FTransactions : TList; + FDirectory : String; + FKeepConnection : Boolean; + FParams : TStrings; + FSQLBased : Boolean; + FOpenAfterRead : boolean; + Function GetTransactionCount : Longint; + Function GetTransaction(Index : longint) : TDBTransaction; + procedure RegisterDataset (DS : TDBDataset); + procedure RegisterTransaction (TA : TDBTransaction); + procedure UnRegisterDataset (DS : TDBDataset); + procedure UnRegisterTransaction(TA : TDBTransaction); + procedure RemoveDataSets; + procedure RemoveTransactions; + procedure SetParams(AValue: TStrings); + protected + Procedure CheckConnected; + Procedure CheckDisConnected; + procedure DoConnect; override; + procedure DoDisconnect; override; + function GetConnected : boolean; override; + Function GetDataset(Index : longint) : TDataset; override; + Function GetDataSetCount : Longint; override; + Procedure DoInternalConnect; Virtual;Abstract; + Procedure DoInternalDisConnect; Virtual;Abstract; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure CloseDataSets; + procedure CloseTransactions; +// procedure ApplyUpdates; + procedure StartTransaction; virtual; abstract; + procedure EndTransaction; virtual; abstract; + property TransactionCount: Longint read GetTransactionCount; + property Transactions[Index: Longint]: TDBTransaction read GetTransaction; + property Directory: string read FDirectory write FDirectory; + property IsSQLBased: Boolean read FSQLBased; + published + property Connected: Boolean read FConnected write SetConnected; + property DatabaseName: string read FDatabaseName write FDatabaseName; + property KeepConnection: Boolean read FKeepConnection write FKeepConnection; + property Params : TStrings read FParams Write SetParams; + end; + + + TMasterParamsDataLink = Class(TMasterDataLink) + Private + FParams : TParams; + Procedure SetParams(AVAlue : TParams); + Protected + Procedure DoMasterDisable; override; + Procedure DoMasterChange; override; + Public + constructor Create(ADataSet: TDataSet); override; + Procedure RefreshParamNames; virtual; + Procedure CopyParamsFromMaster(CopyBound : Boolean); virtual; + Property Params : TParams Read FParams Write SetParams; + end; + +const + FieldTypetoVariantMap : array[TFieldType] of Integer = (varError, varOleStr, varSmallint, + varInteger, varSmallint, varBoolean, varDouble, varCurrency, varCurrency, + varDate, varDate, varDate, varOleStr, varOleStr, varInteger, varOleStr, + varOleStr, varOleStr, varOleStr, varOleStr, varOleStr, varOleStr, varError, + varOleStr, varOleStr, varError, varError, varError, varError, varError, + varOleStr, varOleStr, varVariant, varUnknown, varDispatch, varOleStr, + varOleStr, varDouble, varOleStr,varOleStr); + + +Const + Fieldtypenames : Array [TFieldType] of String[15] = + ( + 'Unknown', + 'String', + 'Smallint', + 'Integer', + 'Word', + 'Boolean', + 'Float', + 'Currency', + 'BCD', + 'Date', + 'Time', + 'DateTime', + 'Bytes', + 'VarBytes', + 'AutoInc', + 'Blob', + 'Memo', + 'Graphic', + 'FmtMemo', + 'ParadoxOle', + 'DBaseOle', + 'TypedBinary', + 'Cursor', + 'FixedChar', + 'WideString', + 'Largeint', + 'ADT', + 'Array', + 'Reference', + 'DataSet', + 'OraBlob', + 'OraClob', + 'Variant', + 'Interface', + 'IDispatch', + 'Guid', + 'TimeStamp', + 'FMTBcd', + 'FixedWideChar', + 'WideMemo' + ); + { 'Unknown', + 'String', + 'Smallint', + 'Integer', + 'Word', + 'Boolean', + 'Float', + 'Date', + 'Time', + 'DateTime', + 'Bytes', + 'VarBytes', + 'AutoInc', + 'Blob', + 'Memo', + 'Graphic', + 'FmtMemo', + 'ParadoxOle', + 'DBaseOle', + 'TypedBinary', + 'Cursor' + );} + +const + DefaultFieldClasses : Array [TFieldType] of TFieldClass = + ( { ftUnknown} Tfield, + { ftString} TStringField, + { ftSmallint} TSmallIntField, + { ftInteger} TLongintField, + { ftWord} TWordField, + { ftBoolean} TBooleanField, + { ftFloat} TFloatField, + { ftCurrency} TCurrencyField, + { ftBCD} TBCDField, + { ftDate} TDateField, + { ftTime} TTimeField, + { ftDateTime} TDateTimeField, + { ftBytes} TBytesField, + { ftVarBytes} TVarBytesField, + { ftAutoInc} TAutoIncField, + { ftBlob} TBlobField, + { ftMemo} TMemoField, + { ftGraphic} TGraphicField, + { ftFmtMemo} TBlobField, + { ftParadoxOle} TBlobField, + { ftDBaseOle} TBlobField, + { ftTypedBinary} TBlobField, + { ftCursor} Nil, + { ftFixedChar} TStringField, + { ftWideString} TWideStringField, + { ftLargeint} TLargeIntField, + { ftADT} Nil, + { ftArray} Nil, + { ftReference} Nil, + { ftDataSet} Nil, + { ftOraBlob} TBlobField, + { ftOraClob} TMemoField, + { ftVariant} TVariantField, + { ftInterface} Nil, + { ftIDispatch} Nil, + { ftGuid} TGuidField, + { ftTimeStamp} Nil, + { ftFMTBcd} TFMTBCDField, + { ftFixedWideString} TWideStringField, + { ftWideMemo} TWideMemoField + ); + + dsEditModes = [dsEdit, dsInsert, dsSetKey]; + dsWriteModes = [dsEdit, dsInsert, dsSetKey, dsCalcFields, dsFilter, + dsNewValue, dsInternalCalc]; + +{ Auxiliary functions } + +Procedure DatabaseError (Const Msg : String); overload; +Procedure DatabaseError (Const Msg : String; Comp : TComponent); overload; +Procedure DatabaseErrorFmt (Const Fmt : String; Args : Array Of Const); overload; +Procedure DatabaseErrorFmt (Const Fmt : String; Args : Array Of const; Comp : TComponent); overload; +Function ExtractFieldName(Const Fields: String; var Pos: Integer): String; +Function DateTimeRecToDateTime(DT: TFieldType; Data: TDateTimeRec): TDateTime; +Function DateTimeToDateTimeRec(DT: TFieldType; Data: TDateTime): TDateTimeRec; + +procedure DisposeMem(var Buffer; Size: Integer); +function BuffersEqual(Buf1, Buf2: Pointer; Size: Integer): Boolean; + +function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : boolean; + +implementation +uses + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},typinfo,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +resourcestring + sassigndate = 'Can not assign a date value to field "%s"'; + sassigntime = 'Can not assign a time value to field "%s"'; + +{ --------------------------------------------------------------------- + Auxiliary functions + ---------------------------------------------------------------------} + +Procedure DatabaseError (Const Msg : String); + +begin + Raise EDataBaseError.Create(Msg); +end; + +Procedure DatabaseError (Const Msg : String; Comp : TComponent); + +begin + raise edatabaseerror.create(msg,comp); +end; + +Procedure DatabaseErrorFmt (Const Fmt : String; Args : Array Of Const); + +begin + Raise EDatabaseError.CreateFmt(Fmt,Args); +end; + +Procedure DatabaseErrorFmt (Const Fmt : String; Args : Array Of const; + Comp : TComponent); +begin + if assigned(comp) then + Raise EDatabaseError.CreateFmt(Format('%s : %s',[Comp.Name,Fmt]),Args) + else + DatabaseErrorFmt(Fmt, Args); +end; + +function ExtractFieldName(const Fields: string; var Pos: Integer): string; +var + i: Integer; + FieldsLength: Integer; +begin + i:=Pos; + FieldsLength:=Length(Fields); + while (i<=FieldsLength) and (Fields[i]<>';') do Inc(i); + Result:=Trim(Copy(Fields,Pos,i-Pos)); + if (i<=FieldsLength) and (Fields[i]=';') then Inc(i); + Pos:=i; +end; + +{ EUpdateError } +constructor EUpdateError.Create(NativeError, Context : String; + ErrCode, PrevError : integer; E: Exception); + +begin + Inherited CreateFmt(NativeError,[Context]); + FContext := Context; + FErrorCode := ErrCode; + FPreviousError := PrevError; + FOriginalException := E; +end; + +Destructor EUpdateError.Destroy; + +begin + FOriginalException.Free; + Inherited; +end; + +{ TNamedItem } + +function TNamedItem.GetDisplayName: string; +begin + Result := FName; +end; + +procedure TNamedItem.SetDisplayName(const AValue: string); +Var TmpInd : Integer; +begin + if FName=AValue then exit; + if (AValue <> '') and (Collection is TFieldDefs) then + begin + TmpInd := (TDefCollection(Collection).IndexOf(AValue)); + if (TmpInd >= 0) and (TmpInd <> Index) then + DatabaseErrorFmt(SDuplicateName, [AValue, Collection.ClassName]); + end; + FName:=AValue; + inherited SetDisplayName(AValue); +end; + +{ TDefCollection } + +procedure TDefCollection.SetItemName(AItem: TCollectionItem); +begin + with AItem as TNamedItem do + if Name = '' then + begin + if assigned(Dataset) then + Name := Dataset.Name + Copy(ClassName, 2, 5) + IntToStr(ID+1) + else + Name := Copy(ClassName, 2, 5) + IntToStr(ID+1); + end + else inherited SetItemName(AItem); +end; + +constructor TDefCollection.create(ADataset: TDataset; AOwner: TPersistent; + AClass: TCollectionItemClass); +begin + inherited Create(AOwner,AClass); + FDataset := ADataset; +end; + +function TDefCollection.Find(const AName: string): TNamedItem; +var i: integer; +begin + Result := Nil; + for i := 0 to Count - 1 do if AnsiSameText(TNamedItem(Items[i]).Name, AName) then + begin + Result := TNamedItem(Items[i]); + Break; + end; +end; + +procedure TDefCollection.GetItemNames(List: TStrings); +var i: LongInt; +begin + for i := 0 to Count - 1 do + List.Add(TNamedItem(Items[i]).Name); +end; + +function TDefCollection.IndexOf(const AName: string): Longint; +var i: LongInt; +begin + Result := -1; + for i := 0 to Count - 1 do + if AnsiSameText(TNamedItem(Items[i]).Name, AName) then + begin + Result := i; + Break; + end; +end; + +{ TIndexDef } + +procedure TIndexDef.SetDescFields(const AValue: string); +begin + if FDescFields=AValue then exit; + if AValue <> '' then FOptions:=FOptions + [ixDescending]; + FDescFields:=AValue; +end; + +procedure TIndexDef.Assign(Source: TPersistent); +var idef : TIndexDef; +begin + idef := nil; + if Source is TIndexDef then idef := Source as TIndexDef; + if Assigned(idef) then + begin + FName := idef.Name; + FFields := idef.Fields; + FOptions := idef.Options; + FCaseinsFields := idef.CaseInsFields; + FDescFields := idef.DescFields; + FSource := idef.Source; + FExpression := idef.Expression; + end + else + inherited Assign(Source); +end; + +function TIndexDef.GetExpression: string; +begin + Result := FExpression; +end; + +procedure TIndexDef.SetExpression(const AValue: string); +begin + FExpression := AValue; +end; + +procedure TIndexDef.SetCaseInsFields(const AValue: string); +begin + if FCaseinsFields=AValue then exit; + if AValue <> '' then FOptions:=FOptions + [ixCaseInsensitive]; + FCaseinsFields:=AValue; +end; + +constructor TIndexDef.Create(Owner: TIndexDefs; const AName, TheFields: string; + TheOptions: TIndexOptions); + +begin + FName := aname; + inherited create(Owner); + FFields := TheFields; + FOptions := TheOptions; +end; + + +{ TIndexDefs } + +Function TIndexDefs.GetItem (Index : integer) : TIndexDef; + +begin + Result:=(Inherited GetItem(Index)) as TIndexDef; +end; + +Procedure TIndexDefs.SetItem(Index: Integer; Value: TIndexDef); +begin + Inherited SetItem(Index,Value); +end; + +constructor TIndexDefs.Create(ADataSet: TDataSet); + +begin + inherited create(ADataset, Owner, TIndexDef); +end; + + +Function TIndexDefs.AddIndexDef: TIndexDef; + +begin +// Result := inherited add as TIndexDef; + Result:=TIndexDef.Create(Self,'','',[]); +end; + +procedure TIndexDefs.Add(const Name, Fields: string; Options: TIndexOptions); + +begin + TIndexDef.Create(Self,Name,Fields,Options); +end; + +function TIndexDefs.Find(const IndexName: string): TIndexDef; +begin + Result := (inherited Find(IndexName)) as TIndexDef; + if (Result=Nil) Then + DatabaseErrorFmt(SIndexNotFound, [IndexName], FDataSet); +end; + +function TIndexDefs.FindIndexForFields(const Fields: string): TIndexDef; + +begin + result:= nil; + //!! To be implemented +end; + + +function TIndexDefs.GetIndexForFields(const Fields: string; + CaseInsensitive: Boolean): TIndexDef; + +var + i, FieldsLen: integer; + Last: TIndexDef; +begin + Last := nil; + FieldsLen := Length(Fields); + for i := 0 to Count - 1 do + begin + Result := Items[I]; + if (Result.Options * [ixDescending, ixExpression] = []) and + (not CaseInsensitive or (ixCaseInsensitive in Result.Options)) and + AnsiSameText(Fields, Result.Fields) then + begin + Exit; + end else + if AnsiSameText(Fields, Copy(Result.Fields, 1, FieldsLen)) and + ((Length(Result.Fields) = FieldsLen) or + (Result.Fields[FieldsLen + 1] = ';')) then + begin + if (Last = nil) or + ((Last <> nil) And (Length(Last.Fields) > Length(Result.Fields))) then + Last := Result; + end; + end; + Result := Last; +end; + +procedure TIndexDefs.Update; + +begin + if (not updated) and assigned(Dataset) then + begin + Dataset.UpdateIndexDefs; + updated := True; + end; +end; + +{ TCheckConstraint } + +procedure TCheckConstraint.Assign(Source: TPersistent); + +begin + //!! To be implemented +end; + + + +{ TCheckConstraints } + +Function TCheckConstraints.GetItem(Index : Longint) : TCheckConstraint; + +begin + //!! To be implemented + Result := nil; +end; + + +Procedure TCheckConstraints.SetItem(index : Longint; Value : TCheckConstraint); + +begin + //!! To be implemented +end; + + +function TCheckConstraints.GetOwner: TPersistent; + +begin + //!! To be implemented + Result := nil; +end; + + +constructor TCheckConstraints.Create(AOwner: TPersistent); + +begin + //!! To be implemented + inherited Create(TCheckConstraint); +end; + + +function TCheckConstraints.Add: TCheckConstraint; + +begin + //!! To be implemented + Result := nil; +end; + +{ TLookupList } + +constructor TLookupList.Create; + +begin + FList := TFPList.Create; +end; + +destructor TLookupList.Destroy; + +begin + Clear; + FList.Destroy; + inherited Destroy; +end; + +procedure TLookupList.Add(const AKey, AValue: Variant); + +var LookupRec: PLookupListRec; +begin + New(LookupRec); + LookupRec^.Key := AKey; + LookupRec^.Value := AValue; + FList.Add(LookupRec); +end; + +procedure TLookupList.Clear; +var i: integer; +begin + for i := 0 to FList.Count - 1 do Dispose(PLookupListRec(FList[i])); + FList.Clear; +end; + +function TLookupList.FirstKeyByValue(const AValue: Variant): Variant; +var + i: Integer; +begin + for i := 0 to FList.Count - 1 do + with PLookupListRec(FList[i])^ do + if Value = AValue then + begin + Result := Key; + exit; + end; + Result := Null; +end; + +function TLookupList.ValueOfKey(const AKey: Variant): Variant; + + Function VarArraySameValues(VarArray1,VarArray2 : Variant) : Boolean; + // This only works for one-dimensional vararrays with a lower bound of 0 + // and equal higher bounds wich only contains variants. + // The vararrays returned by GetFieldValues do apply. + var i : integer; + begin + Result := True; + if (VarArrayHighBound(VarArray1,1))<> (VarArrayHighBound(VarArray2,1)) then exit; + for i := 0 to VarArrayHighBound(VarArray1,1) do + begin + if VarArray1[i]<>VarArray2[i] then + begin + Result := false; + Exit; + end; + end; + end; + +var I: Integer; +begin + Result := Null; + if VarIsNull(AKey) then Exit; + i := FList.Count - 1; + if VarIsArray(AKey) then + while (i >= 0) And not VarArraySameValues(PLookupListRec(FList.Items[I])^.Key,AKey) do Dec(i) + else + while (i >= 0) And (PLookupListRec(FList.Items[I])^.Key <> AKey) do Dec(i); + if i >= 0 then Result := PLookupListRec(FList.Items[I])^.Value; +end; + +procedure TLookupList.ValuesToStrings(AStrings: TStrings); +var + i: Integer; + p: PLookupListRec; +begin + AStrings.Clear; + for i := 0 to FList.Count - 1 do + begin + p := PLookupListRec(FList[i]); + AStrings.AddObject(p^.Value, TObject(p)); + end; +end; + +procedure DisposeMem(var Buffer; Size: Integer); +begin + if Pointer(Buffer) <> nil then + begin + FreeMem(Pointer(Buffer), Size); + Pointer(Buffer) := nil; + end; +end; + +function BuffersEqual(Buf1, Buf2: Pointer; Size: Integer): Boolean; + +begin + {$ifdef FPC} + Result:= CompareByte(Buf1,Buf2,Size) = 0; + {$else} + Result:= Comparemem(Buf1,Buf2,Size); + {$endif} +end; + +{ --------------------------------------------------------------------- + TDataSet + ---------------------------------------------------------------------} + +Const + DefaultBufferCount = 10; + +constructor TDataSet.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + FFieldDefs:=TFieldDefs.Create(Self); + FFieldList:=TFields.Create(Self); + FDataSources:=TList.Create; + FConstraints:=TCheckConstraints.Create(Self); + +// FBuffer must be allocated on create, to make Activebuffer return nil + ReAllocMem(FBuffers,SizeOf(TRecordBuffer)); +// pointer(FBuffers^) := nil; + pbufferaty(FBuffers)^[0] := nil; + FActiveRecord := 0; + FBufferCount := -1; + FEOF := True; + FBOF := True; + FIsUniDirectional := False; + FAutoCalcFields := True; +end; + + + +destructor TDataSet.Destroy; + +var + i: Integer; + +begin + Active:=False; + FFieldDefs.Free; + FFieldList.Free; + With FDatasources do + begin + While Count>0 do + TDatasource(Items[Count - 1]).DataSet:=Nil; + Free; + end; + for i := 0 to FBufferCount do + FreeRecordBuffer(pbufferaty(FBuffers)^[i]); + FConstraints.Free; + FreeMem(FBuffers); + Inherited Destroy; +end; + +// This procedure must be called when the first record is made/read +Procedure TDataset.ActivateBuffers; + +begin + FBOF:=False; + FEOF:=False; + FActiveRecord:=0; +end; + +Procedure TDataset.UpdateFieldDefs; + +begin + //!! To be implemented +end; + +Procedure TDataset.BindFields(Binding: Boolean); + +var i, FieldIndex: Integer; + FieldDef: TFieldDef; +begin + { FieldNo is set to -1 for calculated/lookup fields, to 0 for unbound field + and for bound fields it is set to FieldDef.FieldNo } + FCalcFieldsSize := 0; + FBlobFieldCount := 0; + for i := 0 to Fields.Count - 1 do + with Fields[i] do begin + if Binding then begin + if FieldKind in [fkCalculated, fkLookup] then begin + FFieldNo := -1; + FOffset := FCalcFieldsSize; + Inc(FCalcFieldsSize, DataSize + 1); + if FieldKind in [fkLookup] then begin + if ((FLookupDataSet = nil) or (FLookupKeyFields = '') or + (FLookupResultField = '') or (FKeyFields = '')) then + DatabaseErrorFmt(SLookupInfoError, [DisplayName]); + FFields.CheckFieldNames(FKeyFields); + FLookupDataSet.Open; + FLookupDataSet.Fields.CheckFieldNames(FLookupKeyFields); + FLookupDataSet.FieldByName(FLookupResultField); + if FLookupCache then RefreshLookupList; + end + end else begin + FieldDef := nil; + FieldIndex := FieldDefs.IndexOf(Fields[i].FieldName); + if FieldIndex <> -1 then begin + FieldDef := FieldDefs[FieldIndex]; + FFieldNo := FieldDef.FieldNo; + if FieldDef.InternalCalcField then FInternalCalcFields := True; + if IsBlob then begin + FSize := FieldDef.Size; + FOffset := FBlobFieldCount; + Inc(FBlobFieldCount); + end; + end else FFieldNo := 0; + end; + end else FFieldNo := 0; + end; +end; + +Function TDataset.BookmarkAvailable: Boolean; + +Const BookmarkStates = [dsBrowse,dsEdit,dsInsert]; + +begin + Result:=(Not IsEmpty) and not FIsUniDirectional and (State in BookmarkStates) + and (getBookMarkFlag(ActiveBuffer)=bfCurrent); +end; + +Procedure TDataset.CalculateFields(Buffer: TRecordBuffer); +var + i: Integer; + OldState: TDatasetState; +begin + FCalcBuffer := Buffer; + if not IsUniDirectional and (FState <> dsInternalCalc) then + begin + OldState := FState; + FState := dsCalcFields; + try + ClearCalcFields(FCalcBuffer); + for i := 0 to FFieldList.Count - 1 do + if FFieldList[i].FieldKind = fkLookup then + FFieldList[i].CalcLookupValue; + finally + DoOnCalcFields; + FState := OldState; + end; + end; +end; + +Procedure TDataset.CheckActive; + +begin + If Not Active then + DataBaseError(SInactiveDataset); +end; + +Procedure TDataset.CheckInactive; + +begin + If Active then + DataBaseError(SActiveDataset); +end; + +Procedure TDataset.ClearBuffers; + +begin + FRecordCount:=0; + FactiveRecord:=0; + FCurrentRecord:=-1; + FBOF:=True; + FEOF:=True; +end; + +Procedure TDataset.ClearCalcFields(Buffer: TRecordBuffer); + +begin + // Empty +end; + +Procedure TDataset.CloseBlob(Field: TField); + +begin + //!! To be implemented +end; + +Procedure TDataset.CloseCursor; + +begin + FreeFieldBuffers; + ClearBuffers; + SetBufListSize(0); + InternalClose; + FInternalOpenComplete := False; +end; + +Procedure TDataset.CreateFields; + +Var I : longint; + +begin +{$ifdef DSDebug} + Writeln ('Creating fields'); + Writeln ('Count : ',fielddefs.Count); + For I:=0 to FieldDefs.Count-1 do + Writeln('Def ',I,' : ',Fielddefs.items[i].Name,'(',Fielddefs.items[i].FieldNo,')'); +{$endif} + For I:=0 to fielddefs.Count-1 do + With Fielddefs.Items[I] do + If DataType<>ftUnknown then + begin + {$ifdef DSDebug} + Writeln('About to create field',FieldDefs.Items[i].Name); + {$endif} + CreateField(self); + end; +end; + +Procedure TDataset.DataEvent(Event: TDataEvent; Info: Ptrint); + + procedure HandleFieldChange(aField: TField); + begin + if aField.FieldKind in [fkData, fkInternalCalc] then + SetModified(True); + + if State <> dsSetKey then begin + if aField.FieldKind = fkData then begin + if FInternalCalcFields then + RefreshInternalCalcFields(ActiveBuffer) + else if FAutoCalcFields and (FCalcFieldsSize <> 0) then + CalculateFields(ActiveBuffer); + end; + + aField.Change; + end; + end; + + procedure HandleScrollOrChange; + begin + if State <> dsInsert then + UpdateCursorPos; + end; + +var + i: Integer; +begin + case Event of + deFieldChange : HandleFieldChange(TField(Info)); + deDataSetChange, + deDataSetScroll : HandleScrollOrChange; + deLayoutChange : FEnableControlsEvent:=deLayoutChange; + end; + if not ControlsDisabled and (FState <> dsBlockRead) then begin + for i := 0 to FDataSources.Count - 1 do + TDataSource(FDataSources[i]).ProcessEvent(Event, Info); + end; +end; + +Procedure TDataset.DestroyFields; + +begin + FFieldList.Clear; +end; + +Procedure TDataset.DoAfterCancel; + +begin + If assigned(FAfterCancel) then + FAfterCancel(Self); +end; + +Procedure TDataset.DoAfterClose; + +begin + If assigned(FAfterClose) and not (csDestroying in ComponentState) then + FAfterClose(Self); +end; + +Procedure TDataset.DoAfterDelete; + +begin + If assigned(FAfterDelete) then + FAfterDelete(Self); +end; + +Procedure TDataset.DoAfterEdit; + +begin + If assigned(FAfterEdit) then + FAfterEdit(Self); +end; + +Procedure TDataset.DoAfterInsert; + +begin + If assigned(FAfterInsert) then + FAfterInsert(Self); +end; + +Procedure TDataset.DoAfterOpen; + +begin + If assigned(FAfterOpen) then + FAfterOpen(Self); +end; + +Procedure TDataset.DoAfterPost; + +begin + If assigned(FAfterPost) then + FAfterPost(Self); +end; + +Procedure TDataset.DoAfterScroll; + +begin + If assigned(FAfterScroll) then + FAfterScroll(Self); +end; + +Procedure TDataset.DoAfterRefresh; + +begin + If assigned(FAfterRefresh) then + FAfterRefresh(Self); +end; + +Procedure TDataset.DoBeforeCancel; + +begin + If assigned(FBeforeCancel) then + FBeforeCancel(Self); +end; + +Procedure TDataset.DoBeforeClose; + +begin + If assigned(FBeforeClose) and not (csDestroying in ComponentState) then + FBeforeClose(Self); +end; + +Procedure TDataset.DoBeforeDelete; + +begin + If assigned(FBeforeDelete) then + FBeforeDelete(Self); +end; + +Procedure TDataset.DoBeforeEdit; + +begin + If assigned(FBeforeEdit) then + FBeforeEdit(Self); +end; + +Procedure TDataset.DoBeforeInsert; + +begin + If assigned(FBeforeInsert) then + FBeforeInsert(Self); +end; + +Procedure TDataset.DoBeforeOpen; + +begin + If assigned(FBeforeOpen) then + FBeforeOpen(Self); +end; + +Procedure TDataset.DoBeforePost; + +begin + If assigned(FBeforePost) then + FBeforePost(Self); +end; + +Procedure TDataset.DoBeforeScroll; + +begin + If assigned(FBeforeScroll) then + FBeforeScroll(Self); +end; + +Procedure TDataset.DoBeforeRefresh; + +begin + If assigned(FBeforeRefresh) then + FBeforeRefresh(Self); +end; + +Procedure TDataset.DoInternalOpen; + +begin + InternalOpen; + FInternalOpenComplete := True; +{$ifdef dsdebug} + Writeln ('Calling internal open'); +{$endif} +{$ifdef dsdebug} + Writeln ('Calling RecalcBufListSize'); +{$endif} + FRecordcount := 0; + RecalcBufListSize; + FBOF:=True; + FEOF := (FRecordcount = 0); +end; + +Procedure TDataset.DoOnCalcFields; + +begin + If Assigned(FOnCalcfields) then + FOnCalcFields(Self); +end; + +Procedure TDataset.DoOnNewRecord; +var + int1: integer; + po1: ppointer; +begin + po1:= pointer(fields.ffieldlist.list); + for int1:= 0 to fields.count -1 do begin + with tfield(po1^) do begin + if dsis_recordcopy in finternalstate then begin + if of_initcopy in foptionsfield then begin + asstring:= defaultexpression; + end; + end + else begin + if of_initinsert in foptionsfield then begin + asstring:= defaultexpression; + end; + end; + end; + inc(po1); + end; + If assigned(FOnNewRecord) then + FOnNewRecord(Self); +end; + +procedure TDataSet.domodified; +begin + if assigned(fonmodified) then begin + fonmodified(self); + end; +end; + +Function TDataset.FieldByNumber(FieldNo: Longint): TField; + +begin + Result:=FFieldList.FieldByNumber(FieldNo); +end; + +Function TDataset.FindRecord(Restart, GoForward: Boolean): Boolean; + +begin + result:= false; + //!! To be implemented +end; + +Procedure TDataset.FreeFieldBuffers; + +Var I : longint; + +begin + For I:=0 to FFieldList.Count-1 do + FFieldList[i].FreeBuffers; +end; + +Function TDataset.GetBookmarkStr: TBookmarkStr; + +begin + Result:=''; + If BookMarkAvailable then + begin + SetLength(Result,FBookMarkSize); + GetBookMarkData(ActiveBuffer,Pointer(Result)); + end +end; + +Function TDataset.GetBuffer (Index : longint) : TRecordBuffer; + +begin + Result:= pbufferaty(FBuffers)^[Index]; +end; + +Procedure TDataset.GetCalcFields(Buffer: TRecordBuffer); + +begin + if (FCalcFieldsSize > 0) or FInternalCalcFields then + CalculateFields(Buffer); +end; + +Function TDataset.GetCanModify: Boolean; + +begin + Result:= not FIsUnidirectional; +end; + +Procedure TDataset.GetChildren(Proc: TGetChildProc; Root: TComponent); + +var + I: Integer; + Field: TField; + +begin + for I := 0 to Fields.Count - 1 do begin + Field := Fields[I]; + if (Field.Owner = Root) then + Proc(Field); + end; +end; + +Function TDataset.GetDataSource: TDataSource; +begin + Result:=nil; +end; + +function TDataSet.GetRecordSize: Word; +begin + Result := 0; +end; + +procedure TDataSet.InternalAddRecord(Buffer: Pointer; AAppend: Boolean); +begin + // empty stub +end; + +procedure TDataSet.InternalDelete; +begin + // empty stub +end; + +procedure TDataSet.InternalFirst; +begin + // empty stub +end; + +procedure TDataSet.InternalGotoBookmark(ABookmark: Pointer); +begin + // empty stub +end; + +function TDataSet.GetFieldData(Field: TField; Buffer: Pointer): Boolean; + +begin + Result := False; +end; + +procedure TDataSet.DataConvert(aField: TField; aSource, aDest: Pointer; + aToNative: Boolean); + + // There seems to be no WStrCopy defined, this is a copy of + // the generic StrCopy function, adapted for WideChar. + Function WStrCopy(Dest, Source:PWideChar): PWideChar; + var + counter : SizeInt; + Begin + counter := 0; + while Source[counter] <> #0 do + begin +// Dest[counter] := char(Source[counter]); + Dest[counter] := Source[counter]; + Inc(counter); + end; + { terminate the string } + Dest[counter] := #0; + WStrCopy := Dest; + end; + +var + DT : TFieldType; + +begin + DT := aField.DataType; + if aToNative then + begin + case DT of + ftDate, ftTime, ftDateTime: TDateTimeRec(aDest^) := DateTimeToDateTimeRec(DT, TDateTime(aSource^)); + ftTimeStamp : TTimeStamp(aDest^) := TTimeStamp(aSource^); +{$ifdef FPC} + ftBCD : TBCD(aDest^) := CurrToBCD(Currency(aSource^)); +{$else} + ftBCD : CurrToBCD(Currency(aSource^),TBCD(aDest^)); +{$endif} + ftFMTBCD : TBcd(aDest^) := TBcd(aSource^); + // See notes from mantis bug-report 8204 for more information + // ftBytes : ; + // ftVarBytes : ; + ftWideString : WStrCopy(PWideChar(aDest), PWideChar(aSource)); + end + end + else + begin + case DT of + ftDate, ftTime, ftDateTime: TDateTime(aDest^) := DateTimeRecToDateTime(DT, TDateTimeRec(aSource^)); + ftTimeStamp : TTimeStamp(aDest^) := TTimeStamp(aSource^); + ftBCD : BCDToCurr(TBCD(aSource^),Currency(aDest^)); + ftFMTBCD : TBcd(aDest^) := TBcd(aSource^); + // ftBytes : ; + // ftVarBytes : ; + ftWideString : WStrCopy(PWideChar(aDest), PWideChar(aSource)); + end + end +end; + +function TDataSet.GetFieldData(Field: TField; Buffer: Pointer; + NativeFormat: Boolean): Boolean; + +Var + AStatBuffer : Array[0..dsMaxStringSize] of Char; + ADynBuffer : pchar; + +begin + If NativeFormat then + Result:=GetFieldData(Field, Buffer) + else + begin + if Field.DataSize <= dsMaxStringSize then + begin + Result := GetfieldData(Field, @AStatBuffer); + if Result then DataConvert(Field,@AStatBuffer,Buffer,False); + end + else + begin + GetMem(ADynBuffer,Field.DataSize); + try + Result := GetfieldData(Field, ADynBuffer); + if Result then DataConvert(Field,ADynBuffer,Buffer,False); + finally + FreeMem(ADynBuffer); + end; + end; + end; +end; + +Function DateTimeRecToDateTime(DT: TFieldType; Data: TDateTimeRec): TDateTime; + +var + TS: TTimeStamp; + +begin + TS.Date:=0; + TS.Time:=0; + case DT of + ftDate: TS.Date := Data.Date; + ftTime: With TS do + begin + Time := Data.Time; + Date := DateDelta; + end; + else + try + TS:=MSecsToTimeStamp(trunc(Data.DateTime)); + except + end; + end; + Result:=TimeStampToDateTime(TS); +end; + +Function DateTimeToDateTimeRec(DT: TFieldType; Data: TDateTime): TDateTimeRec; + +var + TS : TTimeStamp; + +begin + TS:=DateTimeToTimeStamp(Data); + With Result do + case DT of + ftDate: + Date:=TS.Date; + ftTime: + Time:=TS.Time; + else + DateTime:=TimeStampToMSecs(TS); + end; +end; + +procedure TDataSet.SetFieldData(Field: TField; Buffer: Pointer); + +begin +// empty procedure +end; + +procedure TDataSet.SetFieldData(Field: TField; Buffer: Pointer; + NativeFormat: Boolean); + +Var + AStatBuffer : Array[0..dsMaxStringSize] of Char; + ADynBuffer : pchar; + +begin + if NativeFormat then + SetFieldData(Field, Buffer) + else + begin + if Field.DataSize <= dsMaxStringSize then + begin + DataConvert(Field,Buffer,@AStatBuffer,True); + SetfieldData(Field, @AStatBuffer); + end + else + begin + GetMem(ADynBuffer,Field.DataSize); + try + DataConvert(Field,Buffer,@AStatBuffer,True); + SetfieldData(Field, @AStatBuffer); + finally + FreeMem(ADynBuffer); + end; + end; + end; +end; + +Function TDataset.GetField (Index : Longint) : TField; + +begin + Result:=FFIeldList[index]; +end; + +Function TDataset.GetFieldClass(FieldType: TFieldType): TFieldClass; + +begin + Result := DefaultFieldClasses[FieldType]; +end; + +Function TDataset.GetIsIndexField(Field: TField): Boolean; + +begin + Result:=False; +end; + +function TDataSet.GetIndexDefs(IndexDefs: TIndexDefs; IndexTypes: TIndexOptions + ): TIndexDefs; + +var i,f : integer; + IndexFields : TStrings; + +begin + IndexDefs.Update; + Result := TIndexDefs.Create(Self); + Result.Assign(IndexDefs); + i := 0; + IndexFields := TStringList.Create; + while i < result.Count do + begin + if (not ((IndexTypes = []) and (result[i].Options = []))) and + ((IndexTypes * result[i].Options) = []) then + begin + result.Delete(i); + dec(i); + end + else + begin + ExtractStrings([';'],[' '],pchar(result[i].Fields),Indexfields); + for f := 0 to IndexFields.Count-1 do if FindField(Indexfields[f]) = nil then + begin + result.Delete(i); + dec(i); + break; + end; + end; + inc(i); + end; + IndexFields.Free; +end; + +Function TDataset.GetNextRecord: Boolean; + + procedure ExchangeBuffers(var buf1,buf2 : trecordbuffer); + + var tempbuf : pointer; + + begin + tempbuf := buf1; + buf1 := buf2; + buf2 := tempbuf; + end; + +begin +{$ifdef dsdebug} + Writeln ('Getting next record. Internal RecordCount : ',FRecordCount); +{$endif} + If FRecordCount>0 Then SetCurrentRecord(FRecordCount-1); + Result:=GetRecord(pbufferaty(FBuffers)^[FBuffercount],gmNext,True)=grOK; + + if result then + begin + If FRecordCount=0 then ActivateBuffers; + if FRecordcount=FBuffercount then + shiftbuffersbackward + else + begin + inc(FRecordCount); + FCurrentRecord:=FRecordCount - 1; + ExchangeBuffers(pbufferaty(FBuffers)^[FCurrentRecord], + pbufferaty(FBuffers)^[FBuffercount]); + end; + end + else + cursorposchanged; +{$ifdef dsdebug} + Writeln ('Result getting next record : ',Result); +{$endif} +end; + +Function TDataset.GetNextRecords: Longint; + +begin + Result:=0; +{$ifdef dsdebug} + Writeln ('Getting next record(s), need :',FBufferCount); +{$endif} + While (FRecordCount0 Then SetCurrentRecord(0); + Result:=GetRecord(pbufferaty(FBuffers)^[FBuffercount],gmPrior,True)=grOK; + if result then + begin + If FRecordCount=0 then ActivateBuffers; + shiftbuffersforward; + + if FRecordcount 0 then + begin + CheckActive; + SetState(dsBlockRead); + end + else + begin + //update state only when in dsBlockRead + if FState = dsBlockRead then + SetState(dsBrowse); + end; +end; + +Procedure TDataSet.SetFieldDefs(AFieldDefs: TFieldDefs); + +begin + FFieldDefs.Assign(AFieldDefs); +end; + +procedure TDataSet.DoInsertAppendRecord(const Values: array of const; DoAppend : boolean); +var i : integer; + ValuesSize : integer; +begin + ValuesSize:=Length(Values); + if ValuesSize>FieldCount then DatabaseError(STooManyFields,self); + if DoAppend then + Append + else + Insert; + + for i := 0 to ValuesSize-1 do with values[i] do + fields[i].AssignValue(values[i]); + Post; + +end; + +procedure TDataSet.InitFieldDefsFromfields; +var i : integer; +begin + if FieldDefs.count = 0 then + begin + FieldDefs.BeginUpdate; + try + for i := 0 to Fields.Count-1 do with fields[i] do + if not (FieldKind in [fkCalculated,fkLookup]) then // Do not add fielddefs for calculated/lookup fields. + begin + with TFieldDef.Create(FieldDefs,FieldName,DataType,Size,Required,FieldDefs.Count+1) do + begin + if Required then Attributes := attributes + [faRequired]; + if ReadOnly then Attributes := attributes + [faReadOnly]; + if DataType = ftBCD then precision := (fields[i] as TBCDField).Precision + else if DataType = ftFMTBcd then precision := (fields[i] as TFMTBCDField).Precision; + end; + end; + finally + FieldDefs.EndUpdate; + end; + end; +end; + +Procedure TDataset.InitRecord(Buffer: TRecordBuffer); + +begin + InternalInitRecord(Buffer); + ClearCalcFields(Buffer); +end; + +Procedure TDataset.InternalCancel; + +begin + //!! To be implemented +end; + +Procedure TDataset.InternalEdit; + +begin + //!! To be implemented +end; + +Procedure TDataset.InternalRefresh; + +begin + //!! To be implemented +end; + +Procedure TDataset.OpenCursor(InfoQuery: Boolean); + +begin + if InfoQuery then + InternalInitfieldDefs + else if state <> dsOpening then + DoInternalOpen; +end; + +procedure TDataSet.OpenCursorcomplete; +begin + try + if FState = dsOpening then DoInternalOpen + finally + if FInternalOpenComplete then + begin + SetState(dsBrowse); + DoAfterOpen; + if not IsEmpty then + DoAfterScroll; + end + else + begin + SetState(dsInactive); + CloseCursor; + end; + end; +end; + +Procedure TDataset.RefreshInternalCalcFields(Buffer: TRecordBuffer); + +begin + //!! To be implemented +end; + +Function TDataset.SetTempState(const Value: TDataSetState): TDataSetState; + +begin + result := FState; + FState := value; + inc(FDisableControlsCount); +end; + +Procedure TDataset.RestoreState(const Value: TDataSetState); + +begin + FState := value; + dec(FDisableControlsCount); +end; + +function TDataset.GetActive : boolean; + +begin + result := (FState <> dsInactive) and (FState <> dsOpening); +end; + +Procedure TDataset.InternalHandleException; + +begin + if assigned(classes.ApplicationHandleException) then + classes.ApplicationHandleException(self) + else + ShowException(ExceptObject,ExceptAddr); +end; + +procedure TDataSet.InternalInitRecord(Buffer: TRecordBuffer); +begin + // empty stub +end; + +procedure TDataSet.InternalLast; +begin + // empty stub +end; + +procedure TDataSet.InternalPost; + + Procedure Checkrequired; + + Var I : longint; + + begin + For I:=0 to FFieldList.Count-1 do + With FFieldList[i] do + // Required fields that are NOT autoinc !! Autoinc cannot be set !! + if Required and not ReadOnly and + (FieldKind=fkData) and Not (DataType=ftAutoInc) and IsNull then + DatabaseErrorFmt(SNeedField,[DisplayName],Self); + end; + +begin + Checkrequired; +end; + +procedure TDataSet.InternalSetToRecord(Buffer: TRecordBuffer); +begin + // empty stub +end; + +procedure TDataSet.SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); +begin + // empty stub +end; + +procedure TDataSet.SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); +begin + // empty stub +end; + +procedure TDataSet.SetUniDirectional(const Value: Boolean); +begin + FIsUniDirectional := Value; +end; + +function compdatasource(item1, item2: pointer): integer; +begin + result:= tdatasource(item2).priority - tdatasource(item1).priority; +end; + +procedure tdataset.sortdatasources(); +begin + quicksortpointer(fdatasources.list^,fdatasources.count,@compdatasource); + //position stable sort +end; + +Procedure TDataset.SetActive (Value : Boolean); + +begin + if value and (Fstate = dsInactive) then begin + if csLoading in ComponentState then begin + FOpenAfterRead := true; + exit; + end + else begin + sortdatasources(); + DoBeforeOpen; + FEnableControlsEvent:=deLayoutChange; + FInternalCalcFields:=False; + try + FDefaultFields:=FieldCount=0; + OpenCursor(False); + finally + if FState <> dsOpening then OpenCursorComplete; + end; + end; + FModified:=False; + end + else if not value and (Fstate <> dsinactive) then + begin + DoBeforeClose; + SetState(dsInactive); + CloseCursor; + DoAfterClose; + FModified:=False; + end +end; + +procedure TDataset.Loaded; + +begin + inherited; + try + if FOpenAfterRead then SetActive(true); + except + if csDesigning in Componentstate then + InternalHandleException + else + raise; + end; +end; + + +procedure TDataSet.RecalcBufListSize; + +var + i, j, ABufferCount: Integer; + DataLink: TDataLink; + +begin +{$ifdef dsdebug} + Writeln('Recalculating buffer list size - check cursor'); +{$endif} + If Not IsCursorOpen Then + Exit; +{$ifdef dsdebug} + Writeln('Recalculating buffer list size'); +{$endif} + ABufferCount := DefaultBufferCount; + for i := 0 to FDataSources.Count - 1 do + for j := 0 to TDataSource(FDataSources[i]).DataLinks.Count - 1 do + begin + DataLink:=TDataLink(TDataSource(FDataSources[i]).DataLinks[j]); + if DataLink.BufferCount>ABufferCount then + ABufferCount:=DataLink.BufferCount; + end; + + If (FBufferCount=ABufferCount) Then + exit; + +{$ifdef dsdebug} + Writeln('Setting buffer list size'); +{$endif} + + SetBufListSize(ABufferCount); +{$ifdef dsdebug} + Writeln('Getting next buffers'); +{$endif} + GetNextRecords; + if (FRecordCount < FBufferCount) and not IsUniDirectional then + begin + FActiveRecord := FActiveRecord + GetPriorRecords; + CursorPosChanged; + end; +{$Ifdef dsDebug} + WriteLn( + 'SetBufferCount: FActiveRecord=',FActiveRecord, + ' FCurrentRecord=',FCurrentRecord, + ' FBufferCount= ',FBufferCount, + ' FRecordCount=',FRecordCount); +{$Endif} +end; + +Procedure TDataset.SetBookmarkStr(const Value: TBookmarkStr); + +begin + GotoBookMark(Pointer(Value)) +end; + +Procedure TDataset.SetBufListSize(Value: Longint); + +Var I : longint; + +begin + if Value = 0 then Value := -1; +{$ifdef dsdebug} + Writeln ('SetBufListSize: ',Value); +{$endif} + If Value=FBufferCount Then + exit; + If Value>FBufferCount then + begin +{$ifdef dsdebug} + Writeln (' Reallocating memory :',(Value+1)*SizeOf(TRecordBuffer)); +{$endif} + ReAllocMem(FBuffers,(Value+1)*SizeOf(PChar)); +{$ifdef dsdebug} + Writeln (' Filling memory :',(Value+1-FBufferCount)*SizeOf(TRecordBuffer)); +{$endif} + inc(FBufferCount); // Cause FBuffers[FBufferCount] is already allocated + FillChar(pbufferaty(FBuffers)^[FBufferCount],(Value+1-FBufferCount)*SizeOF(TRecordBuffer),#0); +{$ifdef dsdebug} + Writeln (' Filled memory :'); +{$endif} + Try +{$ifdef dsdebug} + Writeln (' Assigning buffers :',(Value)*SizeOf(TRecordBuffer)); +{$endif} + For I:=FBufferCount to Value do + pbufferaty(FBuffers)^[i]:=AllocRecordBuffer; +{$ifdef dsdebug} + Writeln (' Assigned buffers ',FBufferCount,' :',(Value)*SizeOf(TRecordBuffer)); +{$endif} + except + I:=FBufferCount; + While (I<(Value+1)) do + begin + FreeRecordBuffer(pbufferaty(FBuffers)^[i]); + Inc(i); + end; + raise; + end; + end + else + begin +{$ifdef dsdebug} + Writeln (' Freeing buffers :',FBufferCount-Value); +{$endif} + if (value > -1) and (FActiveRecord>Value-1) then + begin + for i := 0 to (FActiveRecord-Value) do + shiftbuffersbackward; + FActiverecord := Value -1; + end; + + If Assigned(FBuffers) then + begin + For I:=Value+1 to FBufferCount do + FreeRecordBuffer(pbufferaty(FBuffers)^[i]); + // FBuffer must stay allocated, to make sure that Activebuffer returns nil + if Value = -1 then + begin + ReAllocMem(FBuffers,SizeOf(TRecordBuffer)); + pbufferaty(FBuffers)^[0] := nil; + end + else + ReAllocMem(FBuffers,(Value+1)*SizeOf(TRecordBuffer)); + end; + end; + FBufferCount:=Value; + If Value=-1 then + Value:=0; + if FRecordcount > Value then FRecordcount := Value; +{$ifdef dsdebug} + Writeln (' SetBufListSize: Final FBufferCount=',FBufferCount); +{$endif} +end; + +Procedure TDataset.SetChildOrder(Component: TComponent; Order: Longint); + +var + Field: TField; +begin + Field := Component as TField; + if Fields.IndexOf(Field) >= 0 then + Field.Index := Order; +end; + +Procedure TDataset.SetCurrentRecord(Index: Longint); + +begin + If FCurrentRecord<>Index then + begin +{$ifdef DSdebug} + Writeln ('Setting current record to',index); +{$endif} + if not FIsUniDirectional then Case GetBookMarkFlag(pbufferaty(FBuffers)^[Index]) of + bfCurrent : InternalSetToRecord(pbufferaty(FBuffers)^[Index]); + bfBOF : InternalFirst; + bfEOF : InternalLast; + end; + FCurrentRecord:=index; + end; +end; + +procedure TDataSet.SetDefaultFields(const Value: Boolean); +begin + FDefaultFields := Value; +end; + +Procedure TDataset.SetField (Index : Longint;Value : TField); + +begin + //!! To be implemented +end; + +Procedure TDataset.CheckBiDirectional; + +begin + if FIsUniDirectional then DataBaseError(SUniDirectional); +end; + +Procedure TDataset.SetFilterOptions(Value: TFilterOptions); + +begin + CheckBiDirectional; + FFilterOptions := Value; +end; + +Procedure TDataset.SetFilterText(const Value: string); + +begin + FFilterText := value; +end; + +Procedure TDataset.SetFiltered(Value: Boolean); + +begin + if Value then CheckBiDirectional; + FFiltered := value; +end; + +procedure TDataSet.SetFound(const Value: Boolean); +begin + FFound := Value; +end; + +Procedure TDataset.SetModified(Value: Boolean); + +begin + FModified := value; + if value and (fstate in [dsinsert,dsedit]) then begin + domodified(); + end; +end; + +Procedure TDataset.SetName(const Value: TComponentName); + +function CheckName(const FieldName: string): string; +var i,j: integer; +begin + Result := FieldName; + i := 0; + j := 0; + while (i < Fields.Count) do begin + if Result = Fields[i].FieldName then begin + inc(j); + Result := FieldName + IntToStr(j); + end else Inc(i); + end; +end; +var i: integer; + nm: string; + old: string; +begin + if Self.Name = Value then Exit; + old := Self.Name; + inherited SetName(Value); + if (csDesigning in ComponentState) and (old <> '') then begin + for i := 0 to Fields.Count - 1 do begin + nm := old + Fields[i].FieldName; + if Copy(Fields[i].Name, 1, Length(nm)) = nm then begin + Fields[i].Name := CheckName(Value + Fields[i].FieldName); + end; + end; + end; +end; + +Procedure TDataset.SetOnFilterRecord(const Value: TFilterRecordEvent); + +begin + CheckBiDirectional; + FOnFilterRecord := Value; +end; + +Procedure TDataset.SetRecNo(Value: Longint); + +begin + //!! To be implemented +end; + +Procedure TDataset.SetState(Value: TDataSetState); + +begin + If Value<>FState then + begin + FState:=Value; + if Value=dsBrowse then + FModified:=false; + DataEvent(deUpdateState,0); + end; +end; + +Function TDataset.Tempbuffer: TRecordBuffer; + +begin + Result := pbufferaty(FBuffers)^[FRecordCount]; +end; + +Procedure TDataset.UpdateIndexDefs; + +begin + // Empty Abstract +end; + +function TDataSet.AllocRecordBuffer: TRecordBuffer; +begin + Result := nil; +end; + +procedure TDataSet.FreeRecordBuffer(var Buffer: TRecordBuffer); +begin + // empty stub +end; + +procedure TDataSet.GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); +begin + // empty stub +end; + +function TDataSet.GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; +begin + Result := bfCurrent; +end; + +Function TDataset.ControlsDisabled: Boolean; + +begin + Result := (FDisableControlsCount > 0); +end; + +Function TDataset.ActiveBuffer: TRecordBuffer; + +begin +{$ifdef dsdebug} + Writeln ('Active buffer requested. Returning:',ActiveRecord); +{$endif} + Result:=pbufferaty(FBuffers)^[FActiveRecord]; +end; + +Procedure TDataset.Append; + +begin + DoInsertAppend(True); +end; + +Procedure TDataset.InternalInsert; + +begin + //!! To be implemented +end; + +Procedure TDataset.AppendRecord(const Values: array of const); + +begin + DoInsertAppendRecord(Values,True); +end; + +Function TDataset.BookmarkValid(ABookmark: TBookmark): Boolean; +{ + Should be overridden by descendant objects. +} +begin + Result:=False +end; + +Procedure TDataset.Cancel; + +begin + If State in [dsEdit,dsInsert] then + begin + DataEvent(deCheckBrowseMode,0); + DoBeforeCancel; + UpdateCursorPos; + InternalCancel; + FreeFieldBuffers; + if (state = dsInsert) and (FRecordcount = 1) then + begin + FEOF := true; + FBOF := true; + FRecordcount := 0; + InitRecord(ActiveBuffer); + SetState(dsBrowse); + DataEvent(deDatasetChange,0); + end + else + begin + SetState(dsBrowse); + SetCurrentRecord(FActiverecord); + resync([]); + end; + DoAfterCancel; + end; +end; + +Procedure TDataset.CheckBrowseMode; + +begin + if not (dsis_checkingbrowsemode in finternalstate) then begin + include(finternalstate,dsis_checkingbrowsemode); + try + CheckActive; + DataEvent(deCheckBrowseMode,0); + Case State of + dsedit,dsinsert: begin + UpdateRecord; + If Modified then Post else Cancel; + end; + dsSetKey: Post; + end; + finally + exclude(finternalstate,dsis_checkingbrowsemode); + end; + end; +end; + +Procedure TDataset.ClearFields; + + +begin + DataEvent(deCheckBrowseMode, 0); + FreeFieldBuffers; + InternalInitRecord(ActiveBuffer); + if State <> dsSetKey then GetCalcFields(ActiveBuffer); + DataEvent(deRecordChange, 0); +end; + +Procedure TDataset.Close; + +begin + Active:=False; +end; + +Function TDataset.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Longint; + +begin + Result:=0; +end; + +Function TDataset.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; + + +begin + Result:=Nil; +end; + +Procedure TDataset.CursorPosChanged; + + +begin + FCurrentRecord:=-1; +end; + +Procedure TDataset.Delete; + +begin + If Not CanModify then + DatabaseError(SDatasetReadOnly,Self); + If IsEmpty then + DatabaseError(SDatasetEmpty,Self); + if State in [dsInsert] then + begin + Cancel; + end else begin + DataEvent(deCheckBrowseMode,0); +{$ifdef dsdebug} + writeln ('Delete: checking required fields'); +{$endif} + DoBeforeDelete; + DoBeforeScroll; + If Not TryDoing({$ifdef FPC}@{$endif}InternalDelete,OnPostError) then exit; +{$ifdef dsdebug} + writeln ('Delete: Internaldelete succeeded'); +{$endif} + FreeFieldBuffers; + SetState(dsBrowse); +{$ifdef dsdebug} + writeln ('Delete: Browse mode set'); +{$endif} + SetCurrentRecord(FActiverecord); + Resync([]); + DoAfterDelete; + DoAfterScroll; + end; +end; + +Procedure TDataset.DisableControls; + + +begin + If FDisableControlsCount=0 then + begin + { Save current state, + needed to detect change of state when enabling controls. + } + FDisableControlsState:=FState; + FEnableControlsEvent:=deDatasetChange; + end; + Inc(FDisableControlsCount); +end; + +Procedure TDataset.DoInsertAppend(DoAppend : Boolean); + + + procedure DoInsert(DoAppend : Boolean); + + Var BookBeforeInsert : TBookmarkStr; + TempBuf : pointer; + + begin + bookbeforeinsert:= ''; + // need to scroll up al buffers after current one, + // but copy current bookmark to insert buffer. + If FRecordcount > 0 then + BookBeforeInsert:=Bookmark; + + if not DoAppend then + begin + if FRecordCount > 0 then + begin + TempBuf := pbufferaty(FBuffers)^[FBuffercount]; + move(pbufferaty(FBuffers)^[FActiveRecord], + pbufferaty(FBuffers)^[FActiveRecord+1], + (Fbuffercount-FActiveRecord)*sizeof(pbufferaty(FBuffers)^[0])); + pbufferaty(FBuffers)^[FActiveRecord]:=TempBuf; + end; + end + else if FRecordcount=FBuffercount then + shiftbuffersbackward + else + begin + if FRecordCount>0 then + inc(FActiveRecord); + end; + + // Active buffer is now edit buffer. Initialize. + InitRecord(pbufferaty(FBuffers)^[FActiveRecord]); + cursorposchanged; + + // Put bookmark in edit buffer. + if FRecordCount=0 then + SetBookmarkFlag(ActiveBuffer,bfEOF) + else + begin + fBOF := false; + // 29:01:05, JvdS: Why is this here?!? It can result in records with the same bookmark-data? + // I would say that the 'internalinsert' should do this. But I don't know how Tdbf handles it + + // 1-apr-06, JvdS: It just sets the bookmark of the newly inserted record to the place + // where the record should be inserted. So it is ok. + if FRecordcount > 0 then + SetBookMarkData(ActiveBuffer,pointer(BookBeforeInsert)); + end; + + InternalInsert; + + // update buffer count. + If FRecordCount dsbrowse then begin + exit; //posting canceled + end; + If Not CanModify then + DatabaseError(SDatasetReadOnly,Self); + DoBeforeInsert; + DoBeforeScroll; + If Not DoAppend then + begin +{$ifdef dsdebug} + Writeln ('going to insert mode'); +{$endif} + DoInsert(false); + end + else + begin +{$ifdef dsdebug} + Writeln ('going to append mode'); +{$endif} + ClearBuffers; + InternalLast; + GetPriorRecords; + if FRecordCount>0 then + FActiveRecord:=FRecordCount-1; + DoInsert(True); + SetBookmarkFlag(ActiveBuffer,bfEOF); + FBOF :=False; + FEOF := true; + end; + SetState(dsInsert); + try + DoOnNewRecord; + except + SetCurrentRecord(FActiverecord); + resync([]); + raise; + end; + // mark as not modified. + FModified:=False; + // Final events. + DataEvent(deDatasetChange,0); + DoAfterInsert; + DoAfterScroll; +{$ifdef dsdebug} + Writeln ('Done with append'); +{$endif} +end; + +Procedure TDataset.Edit; + +begin + If State in [dsedit,dsinsert] then exit; + CheckBrowseMode; + If Not CanModify then + DatabaseError(SDatasetReadOnly,Self); + If FRecordCount = 0 then + begin + Append; + Exit; + end; + DoBeforeEdit; + If Not TryDoing({$ifdef FPC}@{$endif}InternalEdit,OnEditError) then exit; + GetCalcFields(ActiveBuffer); + SetState(dsedit); + DataEvent(deRecordChange,0); + DoAfterEdit; +end; + +Procedure TDataset.EnableControls; + + +begin + if FDisableControlsCount > 0 then + Dec(FDisableControlsCount); + + if FDisableControlsCount = 0 then begin + if FState <> FDisableControlsState then + DataEvent(deUpdateState, 0); + + if (FState <> dsInactive) and (FDisableControlsState <> dsInactive) then + DataEvent(FEnableControlsEvent, 0); + end; +end; + +Function TDataset.FieldByName(const FieldName: string): TField; + + +begin + Result:=FindField(FieldName); + If Result=Nil then + DatabaseErrorFmt(SFieldNotFound,[FieldName],Self); +end; + +Function TDataset.FindField(const FieldName: string): TField; + + +begin + Result:=FFieldList.FindField(FieldName); +end; + +Function TDataset.FindFirst: Boolean; + + +begin + Result:=False; +end; + +Function TDataset.FindLast: Boolean; + + +begin + Result:=False; +end; + +Function TDataset.FindNext: Boolean; + + +begin + Result:=False; +end; + +Function TDataset.FindPrior: Boolean; + + +begin + Result:=False; +end; + +Procedure TDataset.First; + + +begin + CheckBrowseMode; + if fstate <> dsbrowse then begin + exit; //posting canceled + end; + DoBeforeScroll; + if not FIsUniDirectional then + ClearBuffers + else if not FBof then + begin + Active := False; + Active := True; + end; + try + InternalFirst; + if not FIsUniDirectional then GetNextRecords; + finally + FBOF:=True; + DataEvent(deDatasetChange,0); + DoAfterScroll; + end; +end; + +Procedure TDataset.FreeBookmark(ABookmark: TBookmark); + + +begin + FreeMem(ABookMark,FBookMarkSize); +end; + +Function TDataset.GetBookmark: TBookmark; + + +begin + if BookmarkAvailable then + begin + GetMem (Result,FBookMarkSize); + GetBookMarkdata(ActiveBuffer,Result); + end + else + Result:=Nil; +end; + +Function TDataset.GetCurrentRecord(Buffer: TRecordBuffer): Boolean; + + +begin + Result:=False; +end; + +Procedure TDataset.GetFieldList(List: TList; const FieldNames: string); + +var + F: TField; + N: String; + StrPos: Integer; + +begin + if (FieldNames = '') or (List = nil) then + Exit; + StrPos := 1; + repeat + N := ExtractFieldName(FieldNames, StrPos); + F := FieldByName(N); + List.Add(F); + until StrPos > Length(FieldNames); +end; + +Procedure TDataset.GetFieldNames(List: TStrings); + + +begin + FFieldList.GetFieldNames(List); +end; + +Procedure TDataset.GotoBookmark(ABookmark: TBookmark); + + +begin + If Assigned(ABookMark) then + begin + CheckBrowseMode; + DoBeforeScroll; + InternalGotoBookMark(ABookMark); + Resync([rmExact,rmCenter]); + DoAfterScroll; + end; +end; + +Procedure TDataset.Insert; + +begin + DoInsertAppend(False); +end; + +Procedure TDataset.InsertRecord(const Values: array of const); + +begin + DoInsertAppendRecord(Values,False); +end; + +Function TDataset.IsEmpty: Boolean; + +begin + Result:=(fBof and fEof) and + (not (state = dsinsert)); // After an insert on an empty dataset, both fBof and fEof are true +end; + +Function TDataset.IsLinkedTo(ADataSource: TDataSource): Boolean; + +begin +//!! Not tested, I never used nested DS + if (ADataSource = nil) or (ADataSource.Dataset = nil) then begin + Result := False + end else if ADataSource.Dataset = Self then begin + Result := True; + end else begin + Result := ADataSource.Dataset.IsLinkedTo(ADataSource.Dataset.DataSource); + end; +//!! DataSetField not implemented +end; + +Function TDataset.IsSequenced: Boolean; + +begin + Result := True; +end; + +Procedure TDataset.Last; + +begin + CheckBiDirectional; + CheckBrowseMode; + if fstate <> dsbrowse then begin + exit; //posting canceled + end; + DoBeforeScroll; + ClearBuffers; + try + InternalLast; + GetPriorRecords; + if FRecordCount>0 then + FActiveRecord:=FRecordCount-1 + finally + FEOF:=true; + DataEvent(deDataSetChange, 0); + DoAfterScroll; + end; +end; + +Function TDataset.MoveBy(Distance: Longint): Longint; +Var + TheResult: Integer; + + Function Scrollforward : Integer; + + begin + Result:=0; +{$ifdef dsdebug} + Writeln('Scrolling forward :',Distance); + Writeln('Active buffer : ',FActiveRecord); + Writeln('RecordCount : ',FRecordCount); + WriteLn('BufferCount : ',FBufferCount); +{$endif} + FBOF:=False; + While (Distance>0) and not FEOF do + begin + If FActiveRecord0 then + begin + Dec(FActiveRecord); + Inc(Distance); + Dec(TheResult); //Dec(Result); + end + else + begin + {$ifdef dsdebug} + Writeln('Moveby : need next record'); + {$endif} + If GetPriorRecord then + begin + Inc(Distance); + Inc(Result); + Dec(TheResult); //Dec(Result); + end + else + FBOF:=true; + end; + end + end; + +Var + Scrolled : Integer; + +begin + CheckBrowseMode; + Result:=0; + if fstate <> dsbrowse then begin + exit; //posting canceled + end; + TheResult:=0; + DoBeforeScroll; + If (Distance = 0) or + ((Distance>0) and FEOF) or + ((Distance<0) and FBOF) then + exit; + Try + Scrolled := 0; + If Distance>0 then + Scrolled:=ScrollForward + else + Scrolled:=ScrollBackward; + finally +{$ifdef dsdebug} + WriteLn('ActiveRecord=', FActiveRecord,' FEOF=',FEOF,' FBOF=',FBOF); +{$Endif} + DataEvent(deDatasetScroll,Scrolled); + DoAfterScroll; + Result:=TheResult; + end; +end; + +Procedure TDataset.Next; + +begin + if BlockReadSize>0 then + BlockReadNext + else + MoveBy(1); +end; + +Procedure TDataset.BlockReadNext; +begin + MoveBy(1); +end; + +Procedure TDataset.Open; + +begin + Active:=True; +end; + +Procedure TDataset.Post; + +begin + if State in [dsEdit,dsInsert] then + begin + DataEvent(deUpdateRecord,0); + DataEvent(deCheckBrowseMode,0); +{$ifdef dsdebug} + writeln ('Post: checking required fields'); +{$endif} + DoBeforePost; + If Not TryDoing({$ifdef FPC}@{$endif}InternalPost,OnPostError) then exit; + cursorposchanged; +{$ifdef dsdebug} + writeln ('Post: Internalpost succeeded'); +{$endif} + FreeFieldBuffers; +// First set the state to dsBrowse, then the Resync, to prevent the calling of +// the deDatasetChange event, while the state is still 'editable', while the db isn't + SetState(dsBrowse); + Resync([]); +{$ifdef dsdebug} + writeln ('Post: Browse mode set'); +{$endif} + DoAfterPost; + end + else + DatabaseErrorFmt(SNotEditing, [Name], Self); +end; + +Procedure TDataset.Prior; + +begin + MoveBy(-1); +end; + +Procedure TDataset.Refresh; + +begin + include(finternalstate,dsis_refreshing); + try + CheckbrowseMode; + DoBeforeRefresh; + UpdateCursorPos; + InternalRefresh; +{ SetCurrentRecord is called by UpdateCursorPos already, so as long as + InternalRefresh doesn't do strange things this should be ok. } +// SetCurrentRecord(FActiverecord); + Resync([]); + DoAfterRefresh; + finally + exclude(finternalstate,dsis_refreshing); + end; +end; + +function TDataSet.refreshing: boolean; +begin + result:= dsis_refreshing in finternalstate; +end; + +Procedure TDataset.RegisterDataSource(ADatasource : TDataSource); + +begin + FDatasources.Add(ADataSource); + if fstate <> dsinactive then begin + sortdatasources(); + end; + RecalcBufListSize; +end; + + +Procedure TDataset.Resync(Mode: TResyncMode); + +var i,count : integer; + +begin + // See if we can find the requested record. +{$ifdef dsdebug} + Writeln ('Resync called'); +{$endif} + if FIsUnidirectional then Exit; +// place the cursor of the underlying dataset to the active record +// SetCurrentRecord(FActiverecord); + +// Now look if the data on the current cursor of the underlying dataset is still available + If GetRecord(pbufferaty(FBuffers)^[0],gmcurrent,False)<>grOk Then +// If that fails and rmExact is set, then raise an exception + If rmExact in Mode then + DatabaseError(SNoSuchRecord,Self) +// else, if rmexact is not set, try to fetch the next or prior record in the underlying dataset + else if (GetRecord(pbufferaty(FBuffers)^[0],gmnext,True)<>grOk) and + (GetRecord(pbufferaty(FBuffers)^[0],gmprior,True)<>grOk) then + begin +{$ifdef dsdebug} + Writeln ('Resync: fuzzy resync'); +{$endif} + // nothing found, invalidate buffer and bail out. + ClearBuffers; + // Make sure that the active record is 'empty', ie: that all fields are null + InternalInitRecord(ActiveBuffer); + DataEvent(deDatasetChange,0); + exit; + end; + FCurrentRecord := 0; + FEOF := false; + FBOF := false; + +// If we've arrived here, FBuffer[0] is the current record + If (rmCenter in Mode) then + count := (FRecordCount div 2) + else + count := FActiveRecord; + i := 0; + FRecordcount := 1; + FActiveRecord := 0; + +// Fill the buffers before the active record + while (i < count) and GetPriorRecord do + inc(i); + FActiveRecord := i; +// Fill the rest of the buffer + getnextrecords; +// If the buffer is not full yet, try to fetch some more prior records + if FRecordcount < FBuffercount then inc(FActiverecord,getpriorrecords); +// That's all folks! + DataEvent(deDatasetChange,0); +end; + +Procedure TDataset.SetFields(const Values: array of const); + +Var I : longint; +begin + For I:=0 to high(Values) do + Fields[I].AssignValue(Values[I]); +end; + +Function TDataset.Translate(Src, Dest: PChar; ToOem: Boolean): Integer; + +begin + strcopy(dest,src); + Result:=StrLen(dest); +end; + +Function Tdataset.TryDoing (P : TDataOperation; Ev : TDatasetErrorEvent) : Boolean; + +Var Retry : TDataAction; + +begin +{$ifdef dsdebug} + Writeln ('Trying to do'); + If P=Nil then writeln ('Procedure to call is nil !!!'); +{$endif dsdebug} + Result:=True; + Retry:=daRetry; + while Retry=daRetry do + Try +{$ifdef dsdebug} + Writeln ('Trying : updatecursorpos'); +{$endif dsdebug} + UpdateCursorPos; +{$ifdef dsdebug} + Writeln ('Trying to do it'); +{$endif dsdebug} + P; + exit; + except + On E : EDatabaseError do + begin + retry:=daFail; + If Assigned(Ev) then + Ev(Self,E,Retry); + Case Retry of + daFail : Raise; + daAbort : Result:=False; + end; + end; + else + Raise; + end; +{$ifdef dsdebug} + Writeln ('Exit Trying to do'); +{$endif dsdebug} +end; + +Procedure TDataset.UpdateCursorPos; + +begin + If FRecordCount>0 then + SetCurrentRecord(FactiveRecord); +end; + +Procedure TDataset.UpdateRecord; + +begin + if not (State in dsEditModes) then + DatabaseErrorFmt(SNotEditing, [Name], Self); + DataEvent(deUpdateRecord, 0); +end; + +Function TDataSet.UpdateStatus: TUpdateStatus; + +begin + Result:=usUnmodified; +end; + +procedure TDataSet.modify(const callmodified: boolean = true); +begin + if fstate in [dsedit,dsinsert] then begin + if callmodified then begin + setmodified(true); + end + else begin + fmodified:= true; + end; + end; +end; + +procedure TDataSet.resetmodified(); +begin + setmodified(false); +end; + +Procedure TDataset.RemoveField (Field : TField); + +begin + //!! To be implemented +end; + +procedure TDataSet.SetConstraints(Value: TCheckConstraints); +begin + FConstraints.Assign(Value); +end; + +Function TDataset.Getfieldcount : Longint; + +begin + Result:=FFieldList.Count; +end; + +Procedure TDataset.ShiftBuffersBackward; + +var TempBuf : pointer; + +begin + TempBuf := pbufferaty(FBuffers)^[0]; + move(pbufferaty(FBuffers)^[1],pbufferaty(FBuffers)^[0], + (fbuffercount)*sizeof(pbufferaty(FBuffers)^[0])); + pbufferaty(FBuffers)^[buffercount]:=TempBuf; +end; + +Procedure TDataset.ShiftBuffersForward; + +var TempBuf : pointer; + +begin + TempBuf := pbufferaty(FBuffers)^[FBufferCount]; + move(pbufferaty(FBuffers)^[0],pbufferaty(FBuffers)^[1], + (fbuffercount)*sizeof(pbufferaty(FBuffers)^[0])); + pbufferaty(FBuffers)^[0]:=TempBuf; +end; + +function TDataset.GetFieldValues(const Fieldname: string): Variant; + +var i: Integer; + FieldList: TList; +begin + FieldList := TList.Create; + try + GetFieldList(FieldList, FieldName); + if FieldList.Count>1 then begin + Result := VarArrayCreate([0, FieldList.Count - 1], varVariant); + for i := 0 to FieldList.Count - 1 do + Result[i] := TField(FieldList[i]).Value; + end else + Result := FieldByName(FieldName).Value; + finally + FieldList.Free; + end; +end; + +procedure TDataset.SetFieldValues(const Fieldname: string; Value: Variant); + +var + i : Integer; + FieldList: TList; +begin + if VarIsArray(Value) then begin + FieldList := TList.Create; + try + GetFieldList(FieldList, FieldName); + for i := 0 to FieldList.Count -1 do + TField(FieldList[i]).Value := Value[i]; + finally + FieldList.Free; + end; + end else + FieldByName(Fieldname).Value := Value; +end; + +Function TDataset.Locate(const keyfields: string; const keyvalues: Variant; options: TLocateOptions) : boolean; + +begin + CheckBiDirectional; + Result := False; +end; + +Function TDataset.Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant; + +begin + CheckBiDirectional; + Result := Null; +end; + + +Procedure TDataset.UnRegisterDataSource(ADatasource : TDatasource); + +begin + FDataSources.Remove(ADataSource); +end; + +{------------------------------------------------------------------------------} +{ IProviderSupport methods} + +procedure TDataset.PSEndTransaction(Commit: Boolean); +begin + DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSExecute; +begin + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSExecuteStatement(const ASQL: string; AParams: TParams; + ResultSet: Pointer): Integer; +begin + Result := 0; + DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSGetAttributes(List: TList); +begin + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetCommandText: string; +begin + Result := ''; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetCommandType: TPSCommandType; +begin + Result := ctUnknown; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetDefaultOrder: TIndexDef; +begin + Result := nil; + //DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetIndexDefs(IndexTypes: TIndexOptions): TIndexDefs; +begin + Result := nil; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetKeyFields: string; +begin + Result := ''; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetParams: TParams; +begin + Result := nil; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetQuoteChar: string; +begin + Result := ''; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetTableName: string; +begin + Result := ''; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetUpdateException(E: Exception; Prev: EUpdateError + ): EUpdateError; +begin + if Prev <> nil then + Result := EUpdateError.Create(E.Message, '', 0, Prev.ErrorCode, E) + else + Result := EUpdateError.Create(E.Message, '', 0, 0, E) +end; + +function TDataset.PSInTransaction: Boolean; +begin + Result := False; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSIsSQLBased: Boolean; +begin + Result := False; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSIsSQLSupported: Boolean; +begin + Result := False; + DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSReset; +begin + //DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSSetCommandText(const CommandText: string); +begin + DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSSetParams(AParams: TParams); +begin + DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSStartTransaction; +begin + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSUpdateRecord(UpdateKind: TUpdateKind; Delta: TDataSet + ): Boolean; +begin + Result := False; + DatabaseError('Provider support not available', Self); +end; + +{------------------------------------------------------------------------------} + + +{ --------------------------------------------------------------------- + TFieldDef + ---------------------------------------------------------------------} + +Constructor TFieldDef.Create(ACollection : TCollection); + +begin + FPrecision:=-1; + Inherited create(ACollection); + FFieldNo:=Index+1; +end; + +Constructor TFieldDef.Create(AOwner: TFieldDefs; const AName: string; + ADataType: TFieldType; ASize: Integer; ARequired: Boolean; AFieldNo: Longint); + +begin +{$ifdef dsdebug } + Writeln('TFieldDef.Create : ',Aname,'(',AFieldNo,')'); +{$endif} + Inherited Create(AOwner); + Name:=Aname; + FDatatype:=ADatatype; + FSize:=ASize; + FRequired:=ARequired; + FPrecision:=-1; + FFieldNo:=AFieldNo; +end; + +Destructor TFieldDef.Destroy; + +begin + Inherited destroy; +end; + +procedure TFieldDef.Assign(APersistent: TPersistent); +var fd: TFieldDef; +begin + fd := nil; + if APersistent is TFieldDef then + fd := APersistent as TFieldDef; + if Assigned(fd) then begin + Collection.BeginUpdate; + try + Name := fd.Name; + DataType := fd.DataType; + Size := fd.Size; + Precision := fd.Precision; + FRequired := fd.Required; + finally + Collection.EndUpdate; + end; + end else + inherited Assign(APersistent); +end; + +Function TFieldDef.CreateField(AOwner: TComponent): TField; + +Var TheField : TFieldClass; + +begin +{$ifdef dsdebug} + Writeln ('Creating field '+FNAME); +{$endif dsdebug} + TheField:=GetFieldClass; + if TheField=Nil then + DatabaseErrorFmt(SUnknownFieldType,[FName]); + Result:=Thefield.Create(AOwner); + Try + Result.Size:=FSize; + Result.Required:=FRequired; + Result.FFieldName:=FName; + Result.FDisplayLabel:=DisplayName; + Result.FFieldNo:=Self.FieldNo; + Result.SetFieldType(DataType); + Result.ReadOnly:= (faReadOnly in Attributes); +{$ifdef dsdebug} + Writeln ('TFieldDef.CReateField : Trying to set dataset'); +{$endif dsdebug} +{$ifdef dsdebug} + Writeln ('TFieldDef.CReateField : Result Fieldno : ',Result.FieldNo,' Self : ',FieldNo); +{$endif dsdebug} + Result.Dataset:=TFieldDefs(Collection).Dataset; + If (Result is TFloatField) then + TFloatField(Result).Precision:=FPrecision; + if (Result is TBCDField) then + TBCDField(Result).Precision:=FPrecision; + if (Result is TFmtBCDField) then + TFmtBCDField(Result).Precision:=FPrecision; + except + Result.Free; + Raise; + end; + +end; + +procedure TFieldDef.SetAttributes(AValue: TFieldAttributes); +begin + FAttributes := AValue; + Changed(False); +end; + +procedure TFieldDef.SetDataType(AValue: TFieldType); +begin + FDataType := AValue; + Changed(False); +end; + +procedure TFieldDef.SetPrecision(const AValue: Longint); +begin + FPrecision := AValue; + Changed(False); +end; + +procedure TFieldDef.SetSize(const AValue: Integer); +begin + FSize := AValue; + Changed(False); +end; + +procedure TFieldDef.SetRequired(const AValue: Boolean); +begin + FRequired := AValue; + Changed(False); +end; + +Function TFieldDef.GetFieldClass : TFieldClass; + +begin + //!! Should be owner as tdataset but that doesn't work ?? + + If Assigned(Collection) And + (Collection is TFieldDefs) And + Assigned(TFieldDefs(Collection).Dataset) then + Result:=TFieldDefs(Collection).Dataset.GetFieldClass(FDataType) + else + Result:=Nil; +end; + +{ --------------------------------------------------------------------- + TFieldDefs + ---------------------------------------------------------------------} + +{ +destructor TFieldDefs.Destroy; + +begin + FItems.Free; + // This will destroy all fielddefs since we own them... + Inherited Destroy; +end; +} + +procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType); + +begin + Add(AName,ADatatype,0,False); +end; + +procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize : Word); + +begin + Add(AName,ADatatype,ASize,False); +end; + +procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize: Word; + ARequired: Boolean); + +begin + If Length(AName)=0 Then + DatabaseError(SNeedFieldName); + // the fielddef will register itself here as a owned component. + // fieldno is 1 based ! + BeginUpdate; + try + TFieldDef.Create(Self,AName,ADataType,ASize,Arequired,Count+1); + finally + EndUpdate; + end; +end; + +function TFieldDefs.GetItem(Index: Longint): TFieldDef; + +begin + Result := TFieldDef(inherited Items[Index]); +end; + +procedure TFieldDefs.SetItem(Index: Longint; const AValue: TFieldDef); +begin + inherited Items[Index] := AValue; +end; + +constructor TFieldDefs.Create(ADataset: TDataset); +begin + Inherited Create(ADataset, Owner, TFieldDef); +end; + +procedure TFieldDefs.Assign(FieldDefs: TFieldDefs); + +Var I : longint; + +begin + Clear; + For i:=0 to FieldDefs.Count-1 do + With FieldDefs[i] do + Add(Name,DataType,Size,Required); +end; + +function TFieldDefs.Find(const AName: string): TFieldDef; +begin + Result := (Inherited Find(AName)) as TFieldDef; + if Result=nil then DatabaseErrorFmt(SFieldNotFound,[AName],FDataset); +end; + +{ +procedure TFieldDefs.Clear; + +Var I : longint; + +begin + For I:=FItems.Count-1 downto 0 do + TFieldDef(Fitems[i]).Free; + FItems.Clear; +end; +} + +procedure TFieldDefs.Update; + +begin + if not Updated then + begin + If Assigned(Dataset) then + DataSet.InitFieldDefs; + Updated := True; + end; +end; + +function TFieldDefs.MakeNameUnique(const AName: String): string; +var DblFieldCount : integer; +begin + DblFieldCount := 0; + Result := AName; + while assigned(inherited Find(Result)) do + begin + inc(DblFieldCount); + Result := AName + '_' + IntToStr(DblFieldCount); + end; +end; + +Function TFieldDefs.AddFieldDef : TFieldDef; + +begin + Result:=TFieldDef.Create(Self,'',ftUnknown,0,False,Count+1); +end; + +{ --------------------------------------------------------------------- + TField + ---------------------------------------------------------------------} + +Const + SBCD = 'BCD'; + SBoolean = 'Boolean'; + SDateTime = 'TDateTime'; + SFloat = 'Float'; + SInteger = 'Integer'; + SLargeInt = 'LargeInt'; + SVariant = 'Variant'; + SString = 'String'; + SBytes = 'Bytes'; + +constructor TField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + foptionsfield:= defaultoptionsfield; +// FVisible:=True; + FValidChars:=[#0..#255]; + +// FProviderFlags := [pfInInsert,pfInUpdate,pfInWhere]; +end; + +destructor TField.Destroy; + +begin + IF Assigned(FDataSet) then + begin + FDataSet.Active:=False; + if Assigned(FFields) then + FFields.Remove(Self); + end; + FLookupList.Free; + Inherited Destroy; +end; + +function TField.AccessError(const TypeName: string): EDatabaseError; + +begin + Result:=EDatabaseError.CreateFmt(SinvalidTypeConversion,[TypeName,FFieldName]); +end; + +procedure TField.Assign(Source: TPersistent); + +begin + if Source = nil then Clear + else if Source is TField then begin + Value := TField(Source).Value; + end else + inherited Assign(Source); +end; + +procedure TField.AssignValue(const AValue: TVarRec); + procedure Error; + begin + DatabaseErrorFmt(SFieldValueError, [DisplayName]); + end; + +begin + with AValue do + case VType of + vtInteger: + AsInteger := VInteger; + vtBoolean: + AsBoolean := VBoolean; + vtChar: + AsString := VChar; + vtExtended: + AsFloat := VExtended^; + vtString: + AsString := VString^; + vtPointer: + if VPointer <> nil then Error; + vtPChar: + AsString := VPChar; + vtObject: + if (VObject = nil) or (VObject is TPersistent) then + Assign(TPersistent(VObject)) + else + Error; + vtAnsiString: + AsString := string(VAnsiString); + vtCurrency: + AsCurrency := VCurrency^; + vtVariant: + if not VarIsClear(VVariant^) then Self.Value := VVariant^; + vtWideString: + AsWideString := WideString(VWideString); + vtInt64: + AsLargeInt := VInt64^; + else + Error; + end; +end; + +procedure TField.Change; + +begin + If Assigned(FOnChange) Then + FOnChange(Self); +end; + +procedure TField.CheckInactive; + +begin + If Assigned(FDataSet) then + FDataset.CheckInactive; +end; + +procedure TField.Clear; + +begin + if FieldKind in [fkData, fkInternalCalc] then + SetData(Nil); +end; + +procedure TField.DataChanged; + +begin + FDataset.DataEvent(deFieldChange,ptrint(Self)); +end; + +procedure TField.FocusControl; +var + Field1: TField; +begin + Field1 := Self; + FDataSet.DataEvent(deFocusControl,ptrint(@Field1)); +end; + +procedure TField.FreeBuffers; + +begin + // Empty. Provided for backward compatibiliy; + // TDataset manages the buffers. +end; + +function TField.GetAsBCD: TBCD; +begin + raise AccessError(SBCD); +{$ifdef FPC} + result:= 0; //compiler warning +{$endif} +end; + +function TField.GetAsBoolean: Boolean; +begin + raise AccessError(SBoolean); + result:= false; //compiler warning +end; + +function TField.GetAsBytes: TBytes; +begin + SetLength(Result, DataSize); + if assigned(result) and not GetData(@Result[0], False) then + Result := nil; +end; + +function TField.GetAsDateTime: TDateTime; + +begin + raise AccessError(SdateTime); + result:= 0; //compiler warning +end; + +function TField.GetAsFloat: Double; + +begin + raise AccessError(SDateTime); + result:= 0; //compiler warning +end; + +function TField.GetAsLongint: Longint; + +begin + raise AccessError(SInteger); + result:= 0; //compiler warning +end; + +function TField.GetAsVariant: Variant; + +begin + raise AccessError(SVariant); + result:= 0; //compiler warning +end; + + +function TField.GetAsInteger: Integer; + +begin + Result:=GetAsLongint; +end; + +function TField.GetAsString: string; + +begin + Result := GetClassDesc; +end; + +function TField.GetAsWideString: WideString; +begin + Result := widestring(GetAsString); +end; + +function TField.GetOldValue: Variant; + +var SaveState : TDatasetState; + +begin + SaveState := FDataset.State; + try + FDataset.SetTempState(dsOldValue); + Result := GetAsVariant; + finally + FDataset.RestoreState(SaveState); + end; +end; + +function TField.GetNewValue: Variant; + +var SaveState : TDatasetState; + +begin + SaveState := FDataset.State; + try + FDataset.SetTempState(dsNewValue); + Result := GetAsVariant; + finally + FDataset.RestoreState(SaveState); + end; +end; + +procedure TField.SetNewValue(const AValue: Variant); + +var SaveState : TDatasetState; + +begin + SaveState := FDataset.State; + try + FDataset.SetTempState(dsNewValue); + SetAsVariant(AValue); + finally + FDataset.RestoreState(SaveState); + end; +end; + +function TField.GetCurValue: Variant; + +var SaveState : TDatasetState; + +begin + SaveState := FDataset.State; + try + FDataset.SetTempState(dsCurValue); + Result := GetAsVariant; + finally + FDataset.RestoreState(SaveState); + end; +end; + +function TField.GetCanModify: Boolean; + +begin + Result:=Not ReadOnly; + If Result then + begin + Result := FieldKind in [fkData, fkInternalCalc]; + if Result then + begin + Result:=Assigned(DataSet) and Dataset.Active; + If Result then + Result:= DataSet.CanModify; + end; + end; +end; + +function TField.GetClassDesc: String; +var ClassN : string; +begin + ClassN := copy(ClassName,2,pos('Field',ClassName)-2); + if isNull then + result := '(' + LowerCase(ClassN) + ')' + else + result := '(' + UpperCase(ClassN) + ')'; +end; + +function TField.GetData(Buffer: Pointer): Boolean; + +begin + Result:=GetData(Buffer,True); +end; + +function TField.GetData(Buffer: Pointer; NativeFormat : Boolean): Boolean; + +begin + IF FDataset=Nil then + DatabaseErrorFmt(SNoDataset,[FieldName]); + If FVAlidating then + begin + result:=assigned(FValueBuffer); + If Result and assigned(Buffer) then + Move (FValueBuffer^,Buffer^ ,DataSize); + end + else + Result:=FDataset.GetFieldData(Self,Buffer,NativeFormat); +end; + +function TField.GetDataSize: Integer; + +begin + Result:=0; +end; + +function TField.GetDefaultWidth: Longint; + +begin + Result:=10; +end; + +function TField.GetDisplayName : String; + +begin + If FDisplayLabel<>'' then + result:=FDisplayLabel + else + Result:=FFieldName; +end; + +Function TField.IsDisplayStored : Boolean; + +begin + Result:=(DisplayLabel<>FieldName); +end; + +function TField.GetLookupList: TLookupList; +begin + if not Assigned(FLookupList) then + FLookupList := TLookupList.Create; + Result := FLookupList; +end; + +procedure TField.CalcLookupValue; +begin + if FLookupCache then + Value := LookupList.ValueOfKey(FDataSet.FieldValues[FKeyFields]) + else if Assigned(FLookupDataSet) and FDataSet.Active then + Value := FLookupDataSet.Lookup(FLookupKeyfields, FDataSet.FieldValues[FKeyFields], FLookupresultField); +end; + +function TField.getIndex : longint; + +begin + If Assigned(FDataset) then + Result:=FDataset.FFieldList.IndexOf(Self) + else + Result:=-1; +end; + +function TField.GetLookup: Boolean; +begin + Result := FieldKind = fkLookup; +end; + +function TField.GetAsLargeInt: LargeInt; +begin + Raise AccessError(SLargeInt); + result:= 0; //compiler warning +end; + +function TField.GetAsCurrency: Currency; +begin + Result := GetAsFloat; +end; + +procedure TField.SetAlignment(const AValue: TAlignMent); +begin + if FAlignment <> AValue then + begin + FAlignment := Avalue; + PropertyChanged(false); + end; +end; + +procedure TField.SetIndex(const AValue: Integer); +begin + if FFields <> nil then FFields.SetFieldIndex(Self, AValue) +end; + +procedure TField.SetAsCurrency(AValue: Currency); +begin + SetAsFloat(AValue); +end; + +function TField.GetIsNull: Boolean; + +begin + Result:=Not(GetData (Nil)); +end; + +function TField.GetParentComponent: TComponent; + +begin + Result := DataSet; +end; + +procedure TField.GetText(var AText: string; ADisplayText: Boolean); + +begin + AText:=GetAsString; +end; + +function TField.HasParent: Boolean; + +begin + HasParent:=True; +end; + +function TField.IsValidChar(InputChar: Char): Boolean; + +begin + // FValidChars must be set in Create. + Result:=InputChar in FValidChars; +end; + +procedure TField.RefreshLookupList; +var + tmpActive: Boolean; +begin + if not Assigned(FLookupDataSet) or (Length(FLookupKeyfields) = 0) + or (Length(FLookupresultField) = 0) or (Length(FKeyFields) = 0) then + Exit; + + tmpActive := FLookupDataSet.Active; + try + FLookupDataSet.Active := True; + FFields.CheckFieldNames(FKeyFields); + FLookupDataSet.Fields.CheckFieldNames(FLookupKeyFields); + FLookupDataset.FieldByName(FLookupResultField); // I presume that if it doesn't exist it throws exception, and that a field with null value is still valid + LookupList.Clear; // have to be F-less because we might be creating it here with getter! + + FLookupDataSet.DisableControls; + try + FLookupDataSet.First; + while not FLookupDataSet.Eof do + begin + FLookupList.Add(FLookupDataSet.FieldValues[FLookupKeyfields], FLookupDataSet.FieldValues[FLookupResultField]); + FLookupDataSet.Next; + end; + finally + FLookupDataSet.EnableControls; + end; + finally + FLookupDataSet.Active := tmpActive; + end; +end; + +procedure TField.Notification(AComponent: TComponent; Operation: TOperation); + +begin + Inherited Notification(AComponent,Operation); + if (Operation = opRemove) and (AComponent = FLookupDataSet) then + FLookupDataSet := nil; +end; + +procedure TField.PropertyChanged(LayoutAffected: Boolean); + +begin + If (FDataset<>Nil) and (FDataset.Active) then + If LayoutAffected then + FDataset.DataEvent(deLayoutChange,0) + else + FDataset.DataEvent(deDatasetchange,0); +end; + +procedure TField.ReadState(Reader: TReader); + +begin + inherited ReadState(Reader); + if Reader.Parent is TDataSet then + DataSet := TDataSet(Reader.Parent); +end; + +procedure TField.SetAsBCD(const AValue: TBCD); +begin + Raise AccessError(SBCD); +end; + +procedure TField.SetAsBytes(const AValue: TBytes); +begin + raise AccessError(SBytes); +end; + +procedure TField.SetAsBoolean(AValue: Boolean); + +begin + Raise AccessError(SBoolean); +end; + +procedure TField.SetAsDateTime(AValue: TDateTime); + +begin + Raise AccessError(SDateTime); +end; + +function TField.getasdate: tdatetime; +begin + raise accesserror(sdatetime); + result:= 0; //compiler warning +end; + +function TField.getastime: tdatetime; +begin + raise accesserror(sdatetime); + result:= 0; //compiler warning +end; + +procedure TField.setasdate(avalue: tdatetime); +begin + raise accesserror(sdatetime); +end; + +procedure TField.setastime(avalue: tdatetime); +begin + raise accesserror(sdatetime); +end; + +procedure TField.SetAsFloat(AValue: Double); + +begin + Raise AccessError(SFloat); +end; + +procedure TField.SetAsVariant(const AValue: Variant); + +begin + if VarIsNull(AValue) then + Clear + else + try + SetVarValue(AValue); + except + on EVariantError do DatabaseErrorFmt(SFieldValueError, [DisplayName]); + end; +end; + + +procedure TField.SetAsLongint(AValue: Longint); + +begin + Raise AccessError(SInteger); +end; + +procedure TField.SetAsInteger(AValue: Integer); + +begin + SetAsLongint(AValue); +end; + +procedure TField.SetAsLargeint(AValue: Largeint); +begin + Raise AccessError(SLargeInt); +end; + +procedure TField.SetAsString(const AValue: string); + +begin + Raise AccessError(SString); +end; + +procedure TField.SetAsWideString(const aValue: WideString); +begin + SetAsString(ansistring(aValue)); +end; + +function TField.getasguid: tguid; +begin + result:= stringtoguid(asstring); +end; + +procedure TField.setasguid(const avalue: tguid); +begin + asstring:= guidtostring(avalue); +end; + +procedure TField.SetData(Buffer: Pointer); + +begin + SetData(Buffer,True); +end; + +procedure TField.SetData(Buffer: Pointer; NativeFormat : Boolean); + +begin + If Not Assigned(FDataset) then + DatabaseErrorFmt(SNoDataset,[FieldName]); + FDataSet.SetFieldData(Self,Buffer, NativeFormat); +end; + +Procedure TField.SetDataset (AValue : TDataset); + +begin +{$ifdef dsdebug} + Writeln ('Setting dataset'); +{$endif} + If AValue=FDataset then exit; + If Assigned(FDataset) Then + begin + FDataset.CheckInactive; + FDataset.FFieldList.Remove(Self); + end; + If Assigned(AValue) then + begin + AValue.CheckInactive; + AValue.FFieldList.Add(Self); + end; + FDataset:=AValue; +end; + +procedure TField.SetDataType(AValue: TFieldType); + +begin + FDataType := AValue; +end; + +procedure TField.SetFieldType(AValue: TFieldType); + +begin + { empty } +end; + +procedure TField.SetParentComponent(AParent: TComponent); + +begin + if not (csLoading in ComponentState) then + DataSet := AParent as TDataSet; +end; + +procedure TField.SetSize(AValue: Integer); + +begin + CheckInactive; + CheckTypeSize(AValue); + FSize:=AValue; +end; + +procedure TField.SetText(const AValue: string); + +begin + AsString:=AValue; +end; + +procedure TField.SetVarValue(const AValue: Variant); +begin + Raise AccessError(SVariant); +end; + +procedure TField.Validate(Buffer: Pointer); + +begin + If assigned(OnValidate) Then + begin + FValueBuffer:=Buffer; + FValidating:=True; + Try + OnValidate(Self); + finally + FValidating:=False; + end; + end; +end; + +class function Tfield.IsBlob: Boolean; + +begin + Result:=False; +end; + +class procedure TField.CheckTypeSize(AValue: Longint); + +begin + If (AValue<>0) and Not IsBlob Then + DatabaseErrorFmt(SInvalidFieldSize,[AValue]); +end; + +// TField private methods + +procedure TField.SetEditText(const AValue: string); +begin + if Assigned(OnSetText) then + OnSetText(Self, AValue) + else + SetText(AValue); +end; + +function TField.getdisplaylabel(): utf8string; +begin + result:= getdisplayname(); +end; + +function TField.GetEditText: String; +begin + SetLength(Result, 0); + if Assigned(OnGetText) then + OnGetText(Self, Result, False) + else + GetText(Result, False); +end; + +function TField.GetDisplayText: String; +begin + SetLength(Result, 0); + if Assigned(OnGetText) then + OnGetText(Self, Result, True) + else + GetText(Result, True); +end; + +procedure TField.SetDisplayLabel(const AValue: utf8string); +begin + if FDisplayLabel<>Avalue then + begin + FDisplayLabel:=Avalue; + PropertyChanged(true); + end; +end; + +procedure TField.SetDisplayWidth(const AValue: Longint); +begin + if FDisplayWidth<>AValue then + begin + FDisplayWidth:=AValue; + PropertyChanged(True); + end; +end; + +function TField.GetDisplayWidth: integer; +begin + if FDisplayWidth=0 then + result:=GetDefaultWidth + else + result:=FDisplayWidth; +end; + +procedure TField.SetLookup(const AValue: Boolean); +const + ValueToLookupMap: array[Boolean] of TFieldKind = (fkData, fkLookup); +begin + FieldKind := ValueToLookupMap[AValue]; +end; + +function TField.getasunicodestring: unicodestring; +begin + result:= unicodestring(getasstring); +end; + +procedure TField.setasunicodestring(const avalue: unicodestring); +begin + setasstring(ansistring(avalue)); +end; + +const + allproviderflags = [pfInUpdate, pfInWhere, pfInKey, pfHidden]; + allprovideroptions = [of_ininsert,of_InUpdate, of_InWhere, of_InKey, + of_Hidden]; + providerflagsshift = ord(of_inupdate); + +function TField.getProviderFlags: TProviderFlags; +begin +{$push}{$warnings off} + result:= tproviderflags(integer(foptionsfield) shr providerflagsshift) * + allproviderflags; +{$pop} +end; + +procedure TField.setoptionsfield(const avalue: optionsfieldty); +var + optcha: optionsfieldty; +begin + optcha:= (foptionsfield >< avalue) * [of_readonly,of_visible]; + foptionsfield:= avalue; + if optcha <> [] then begin + PropertyChanged(True); + end; +end; + +procedure TField.setlookupdataset(const avalue: tdataset); +begin + if flookupdataset <> nil then begin + flookupdataset.removefreenotification(self); + end; + flookupdataset:= avalue; + if flookupdataset <> nil then begin + flookupdataset.freenotification(self); + end; +end; + +function TField.getbuffervalue: variant; +var + bo1: boolean; +begin + bo1:= fvalidating; + try + fvalidating:= false; + result:= getasvariant(); + finally + fvalidating:= bo1; + end; +end; + +function tfield.getasid: int64; +begin + if isnull then begin + result:= -1; + end + else begin + result:= aslargeint; + end; +end; + +procedure tfield.setasid(const avalue: int64); +begin + if avalue = -1 then begin + clear; + end + else begin + aslargeint:= avalue; + end; +end; + +procedure TField.setProviderFlags(const avalue: TProviderFlags); +begin + foptionsfield:= (foptionsfield - allprovideroptions) + + optionsfieldty(integer(avalue) shl providerflagsshift); + if pfinupdate in avalue then begin + include(foptionsfield,of_ininsert); + end + else begin + exclude(foptionsfield,of_ininsert); + end; +end; + +function TField.getReadOnly: Boolean; +begin + result:= of_readonly in foptionsfield; +end; + +procedure TField.SetReadOnly(const AValue: Boolean); +begin + if avalue then begin + optionsfield:= optionsfield + [of_readonly]; + end + else begin + optionsfield:= optionsfield - [of_readonly]; + end; +end; + +function TField.getRequired: Boolean; +begin + result:= of_required in foptionsfield; +end; + +procedure TField.setRequired(const avalue: Boolean); +begin + if avalue then begin + include(foptionsfield,of_required); + end + else begin + exclude(foptionsfield,of_required); + end; +end; + +function TField.getVisible: Boolean; +begin + result:= of_visible in foptionsfield; +end; + +procedure TField.SetVisible(const AValue: Boolean); +begin + if avalue then begin + optionsfield:= optionsfield + [of_visible]; + end + else begin + optionsfield:= optionsfield - [of_visible]; + end; +end; + +procedure TField.readproviderflags(reader: treader); +begin +{$push}{$warnings off} + providerflags:= tproviderflags(reader.readset(typeinfo(tproviderflags))); +{$pop} +end; + +type + providerflag1ty = (pf1_refreshinsert,pf1_refreshupdate,pf1_nocopyrecord); + providerflags1ty = set of providerflag1ty; + +procedure TField.readproviderflags1(reader: treader); +var + flags: providerflags1ty; +begin + flags:= providerflags1ty(reader.readset(typeinfo(providerflags1ty))); + foptionsfield:= foptionsfield - + [of_refreshinsert,of_refreshupdate,of_nocopyrecord]; + if pf1_refreshinsert in flags then begin + include(foptionsfield,of_refreshinsert); + end; + if pf1_refreshupdate in flags then begin + include(foptionsfield,of_refreshupdate); + end; + if pf1_nocopyrecord in flags then begin + include(foptionsfield,of_nocopyrecord); + end; +end; + +procedure TField.readrequired(reader: treader); +begin + required:= reader.readboolean(); +end; + +procedure TField.readvisible(reader: treader); +begin + visible:= reader.readboolean(); +end; + +procedure TField.readreadonly(reader: treader); +begin + readonly:= reader.readboolean(); +end; + +procedure TField.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Required',@readrequired,nil,false); + filer.defineproperty('Visible',@readvisible,nil,false); + filer.defineproperty('ReadOnly',@readreadonly,nil,false); + filer.defineproperty('ProviderFlags',@readproviderflags,nil,false); + filer.defineproperty('providerflags1',@readproviderflags1,nil,false); +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: int64; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: currency; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: ansistring; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dodataentered(const sender: tobject); +begin + if assigned(fondataentered) then begin + fondataentered(self,sender); + end; +end; + +{ --------------------------------------------------------------------- + TStringField + ---------------------------------------------------------------------} + + +constructor TStringField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftString); + FFixedChar := False; + FTransliterate := False; + FSize:=20; +end; + +procedure TStringField.SetFieldType(AValue: TFieldType); +begin + if avalue in [ftString, ftFixedChar] then + SetDataType(AValue); +end; + +class procedure TStringField.CheckTypeSize(AValue: Longint); + +begin +// A size of 0 is allowed, since for example Firebird allows +// a query like: 'select '' as fieldname from table' which +// results in a string with size 0. + If (AValue<0) Then + databaseErrorFmt(SInvalidFieldSize,[AValue]) +end; + +function TStringField.GetAsBoolean: Boolean; + +Var S : String; + +begin + S:=GetAsString; + result := (Length(S)>0) and (Upcase(S[1]) in ['T',YesNoChars[True]]); +end; + +function TStringField.GetAsDateTime: TDateTime; + +begin + Result:=StrToDateTime(GetAsString); +end; + +function TStringField.GetAsFloat: Double; + +begin + Result:=StrToFloat(GetAsString); +end; + +function TStringField.GetAsLongint: Longint; + +begin + Result:=StrToInt(GetAsString); +end; + +function TStringField.GetAsString: string; + +begin + If Not GetValue(Result) then + Result:=''; +end; + +function TStringField.GetAsVariant: Variant; + +Var s : string; + +begin + If GetValue(s) then + Result:=s + else + Result:=Null; +end; + + +function TStringField.GetDataSize: Integer; + +begin + Result:=Size+1; +end; + +function TStringField.GetDefaultWidth: Longint; + +begin + result:=Size; +end; + +Procedure TStringField.GetText(var AText: string; ADisplayText: Boolean); + +begin + AText:=GetAsString; +end; + +function TStringField.GetValue(var AValue: string): Boolean; + +Var Buf, TBuf : TStringFieldBuffer; + DynBuf, TDynBuf : Array of char; + +begin + if DataSize <= dsMaxStringSize then + begin + Result:=GetData(@Buf); + buf[Size]:=#0; //limit string to Size + If Result then + begin + if transliterate then + begin +{$warnings off} + DataSet.Translate(Buf,TBuf,False); + AValue:=TBuf; + end + else + AValue:=Buf + end + end + else + begin + SetLength(DynBuf,DataSize); + Result:=GetData(@DynBuf[0]); + Dynbuf[Size]:=#0; //limit string to Size + If Result then + begin + if transliterate then + begin + SetLength(TDynBuf,DataSize); + DataSet.Translate(@DynBuf[0],@TDynBuf[0],False); + AValue:=pchar(TDynBuf); + end + else + AValue:=pchar(DynBuf); + end + end; +end; +{$warnings on} + +procedure TStringField.SetAsBoolean(AValue: Boolean); + +begin + If AValue Then + SetAsString('T') + else + SetAsString('F'); +end; + +procedure TStringField.SetAsDateTime(AValue: TDateTime); + +begin + SetAsString(DateTimeToStr(AValue)); +end; + +procedure TStringField.SetAsFloat(AValue: Double); + +begin + SetAsString(FloatToStr(AValue)); +end; + +procedure TStringField.SetAsLongint(AValue: Longint); + +begin + SetAsString(intToStr(AValue)); +end; + +procedure TStringField.SetAsString(const AValue: string); + +var Buf : TStringFieldBuffer; + +begin + IF Length(AValue)=0 then + begin + Buf := #0; + SetData(@buf); + end + else if FTransliterate then + begin +{$warnings off} + DataSet.Translate(@AValue[1],Buf,True); + Buf[DataSize-1] := #0; + SetData(@buf); + end + else + begin + // The data is copied into the buffer, since some TDataset descendents copy + // the whole buffer-length in SetData. (See bug 8477) +{$ifdef FPC} + Buf := AValue; +{$else} + copycharbuf(avalue,sizeof(buf),buf); +{$endif} + // If length(AValue) > Datasize the buffer isn't terminated properly + Buf[DataSize-1] := #0; + SetData(@Buf); + end; +end; +{$warnings on} + +procedure TStringField.SetVarValue(const AValue: Variant); +begin + SetAsString(AValue); +end; + +procedure TStringField.dosetvalue(const sender: tobject; var avalue: ansistring; + var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,avalue,accept); + end; +end; + +{ --------------------------------------------------------------------- + TWideStringField + ---------------------------------------------------------------------} + +class procedure TWideStringField.CheckTypeSize(aValue: Integer); +begin +// A size of 0 is allowed, since for example Firebird allows +// a query like: 'select '' as fieldname from table' which +// results in a string with size 0. + If (AValue<0) Then + databaseErrorFmt(SInvalidFieldSize,[AValue]); +end; + +constructor TWideStringField.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + SetDataType(ftWideString); +end; + +procedure TWideStringField.SetFieldType(AValue: TFieldType); +begin + if avalue in [ftWideString, ftFixedWideChar] then + SetDataType(AValue); +end; + +function TWideStringField.GetValue(var aValue: WideString): Boolean; +var + FixBuffer : array[0..dsMaxStringSize div 2] of WideChar; + DynBuffer : array of WideChar; + Buffer : PWideChar; +begin + if DataSize <= dsMaxStringSize then begin + Result := GetData(@FixBuffer, False); + FixBuffer[Size]:=#0; //limit string to Size + aValue := FixBuffer; + end else begin + SetLength(DynBuffer, Succ(Size)); + Buffer := PWideChar(DynBuffer); + Result := GetData(Buffer, False); + Buffer[Size]:=#0; //limit string to Size + if Result then + aValue := Buffer; + end; +end; + +function TWideStringField.GetAsString: string; +begin + Result := ansistring(GetAsWideString); +end; + +procedure TWideStringField.SetAsString(const aValue: string); +begin + SetAsWideString(widestring(aValue)); +end; + +function twidestringfield.getasunicodestring: unicodestring; +begin + result:= getaswidestring; +end; + +procedure twidestringfield.setasunicodestring(const avalue: unicodestring); +begin + setaswidestring(avalue); +end; + +function TWideStringField.GetAsVariant: Variant; +var + ws: WideString; +begin + if GetValue(ws) then + Result := ws + else + Result := Null; +end; + +procedure TWideStringField.SetVarValue(const aValue: Variant); +begin + SetAsWideString(aValue); +end; + +function TWideStringField.GetAsWideString: WideString; +begin + if not GetValue(Result) then + Result := ''; +end; + +procedure TWideStringField.SetAsWideString(const aValue: WideString); +const + NullWideChar : WideChar = #0; +var + Buffer : PWideChar; +begin + if Length(aValue)>0 then + Buffer := PWideChar(@aValue[1]) + else + Buffer := @NullWideChar; + SetData(Buffer, False); +end; + +function TWideStringField.GetDataSize: Integer; +begin + Result := + (Size + 1) * 2; +end; + + +{ --------------------------------------------------------------------- + TNumericField + ---------------------------------------------------------------------} + + +constructor TNumericField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + AlignMent:=taRightJustify; +end; + +class procedure TNumericField.CheckTypeSize(AValue: Longint); +begin + // This procedure is only added because some TDataset descendents have the + // but that they set the Size property as if it is the DataSize property. + // To avoid problems with those descendents, allow values <= 16. + If (AValue>16) Then + DatabaseErrorFmt(SInvalidFieldSize,[AValue]); +end; + +procedure TNumericField.RangeError(AValue, Min, Max: Double); + +begin + DatabaseErrorFMT(SRangeError,[AValue,Min,Max,FieldName]); +end; + +procedure TNumericField.SetDisplayFormat(const AValue: utf8string); + +begin + If FDisplayFormat<>AValue then + begin + FDisplayFormat:=AValue; + PropertyChanged(True); + end; +end; + +procedure TNumericField.SetEditFormat(const AValue: utf8string); + +begin + If FEDitFormat<>AValue then + begin + FEDitFormat:=AVAlue; + PropertyChanged(True); + end; +end; + +function TNumericField.GetAsBoolean: Boolean; +begin + Result:=GetAsInteger<>0; +end; + +procedure TNumericField.SetAsBoolean(AValue: Boolean); +begin + if AValue then + SetAsLongint(1) + else + SetAsLongint(0); +end; + +{ --------------------------------------------------------------------- + TLongintField + ---------------------------------------------------------------------} + + +constructor TLongintField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDatatype(ftinteger); + FMinRange:=Low(LongInt); + FMaxRange:=High(LongInt); + FValidchars:=['+','-','0'..'9']; +end; + +function TLongintField.GetAsFloat: Double; + +begin + Result:=GetAsLongint; +end; + +function TLongintField.GetAsLargeint: Largeint; +begin + Result:=GetAsLongint; +end; + +function TLongintField.GetAsLongint: Longint; + +begin + If Not GetValue(Result) then + Result:=0; +end; + +function TLongintField.GetAsVariant: Variant; + +Var L : Longint; + +begin + If GetValue(L) then + Result:=L + else + Result:=Null; +end; + +function TLongintField.GetAsString: string; + +Var L : Longint; + +begin + If GetValue(L) then + Result:=IntTostr(L) + else + Result:=''; +end; + +function TLongintField.GetDataSize: Integer; + +begin + Result:=SizeOf(Longint); +end; + +procedure TLongintField.GetText(var AText: string; ADisplayText: Boolean); + +var l : longint; + fmt : string; + +begin + Atext:=''; + If Not GetValue(l) then exit; + If ADisplayText or (FEditFormat='') then + fmt:=FDisplayFormat + else + fmt:=FEditFormat; + If length(fmt)<>0 then + AText:=FormatFloat(fmt,L) + else + Str(L,AText); +end; + +function TLongintField.GetValue(var AValue: Longint): Boolean; + +Var L : Longint; + P : PLongint; + +begin + P:=@L; + Result:=GetData(P); + If Result then + Case Datatype of + ftInteger,ftautoinc : AValue:=Plongint(P)^; + ftword : Avalue:=Pword(P)^; + ftsmallint : AValue:=PSmallint(P)^; + end; +end; + +procedure TLongintField.SetAsLargeint(AValue: Largeint); +begin + if (AValue>=FMinRange) and (AValue<=FMaxRange) then + SetAsLongint(AValue) + else + RangeError(AValue,FMinRange,FMaxRange); +end; + +procedure TLongintField.dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,avalue,accept); + end; +end; + +procedure TLongintField.SetAsFloat(AValue: Double); + +begin + SetAsLongint(Round(Avalue)); +end; + +procedure TLongintField.SetAsLongint(AValue: Longint); + +begin + If CheckRange(AValue) then + SetData(@AValue) + else + RangeError(Avalue,FMinrange,FMaxRange); +end; + +procedure TLongintField.SetVarValue(const AValue: Variant); +begin + SetAsLongint(AValue); +end; + +procedure TLongintField.SetAsString(const AValue: string); + +Var L,Code : longint; + +begin + If length(AValue)=0 then + Clear + else + begin + Val(AVAlue,L,Code); + If Code=0 then + SetAsLongint(L) + else + DatabaseErrorFMT(SNotAnInteger,[Avalue]); + end; +end; + +Function TLongintField.CheckRange(AValue : longint) : Boolean; + +begin + result := true; + if (FMaxValue=0) then + begin + if (AValue>FMaxRange) Then result := false; + end + else + if AValue>FMaxValue then result := false; + + if (FMinValue=0) then + begin + if (AValue=FMinRange) and (AValue<=FMaxRange) then + FMaxValue:=AValue + else + RangeError(AValue,FMinRange,FMaxRange); +end; + +Procedure TLongintField.SetMinValue (AValue : longint); + +begin + If (AValue>=FMinRange) and (AValue<=FMaxRange) then + FMinValue:=AValue + else + RangeError(AValue,FMinRange,FMaxRange); +end; + +{ --------------------------------------------------------------------- + TLargeintField + ---------------------------------------------------------------------} + + +constructor TLargeintField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDatatype(ftLargeint); + FMinRange:=Low(Largeint); + FMaxRange:=High(Largeint); + FValidchars:=['+','-','0'..'9']; +end; + +function TLargeintField.GetAsFloat: Double; + +begin + Result:=GetAsLargeint; +end; + +function TLargeintField.GetAsLargeint: Largeint; + +begin + If Not GetValue(Result) then + Result:=0; +end; + +function TLargeIntField.GetAsVariant: Variant; + +Var L : Largeint; + +begin + If GetValue(L) then + Result:=L + else + Result:=Null; +end; + +function TLargeintField.GetAsLongint: Longint; + +begin + Result:=GetAsLargeint; +end; + +function TLargeintField.GetAsString: string; + +Var L : Largeint; + +begin + If GetValue(L) then + Result:=IntTostr(L) + else + Result:=''; +end; + +function TLargeintField.GetDataSize: Integer; + +begin + Result:=SizeOf(Largeint); +end; + +procedure TLargeintField.GetText(var AText: string; ADisplayText: Boolean); + +var l : largeint; + fmt : string; + +begin + Atext:=''; + If Not GetValue(l) then exit; + If ADisplayText or (FEditFormat='') then + fmt:=FDisplayFormat + else + fmt:=FEditFormat; + If length(fmt)<>0 then + AText:=FormatFloat(fmt,L) + else + Str(L,AText); +end; + +function TLargeintField.GetValue(var AValue: Largeint): Boolean; + +type + PLargeint = ^Largeint; + +Var P : PLargeint; + +begin + P:=@AValue; + Result:=GetData(P); +end; + +procedure TLargeintField.SetAsFloat(AValue: Double); + +begin + SetAsLargeint(Round(Avalue)); +end; + +procedure TLargeintField.SetAsLargeint(AValue: Largeint); + +begin + If CheckRange(AValue) then + SetData(@AValue) + else + RangeError(Avalue,FMinrange,FMaxRange); +end; + +procedure TLargeintField.SetAsLongint(AValue: Longint); + +begin + SetAsLargeint(Avalue); +end; + +procedure TLargeintField.SetAsString(const AValue: string); + +Var L : largeint; + code : longint; + +begin + If length(AValue)=0 then + Clear + else + begin + Val(AVAlue,L,Code); + If Code=0 then + SetAsLargeint(L) + else + DatabaseErrorFMT(SNotAnInteger,[Avalue]); + end; +end; + +procedure TLargeintField.SetVarValue(const AValue: Variant); +begin + SetAsLargeint(AValue); +end; + +procedure TLargeintField.dosetvalue(const sender: tobject; var avalue: int64; + var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,avalue,accept); + end; +end; + +Function TLargeintField.CheckRange(AValue : largeint) : Boolean; + +begin + result := true; + if (FMaxValue=0) then + begin + if (AValue>FMaxRange) Then result := false; + end + else + if AValue>FMaxValue then result := false; + + if (FMinValue=0) then + begin + if (AValue=FMinRange) and (AValue<=FMaxRange) then + FMaxValue:=AValue + else + RangeError(AValue,FMinRange,FMaxRange); +end; + +Procedure TLargeintField.SetMinValue (AValue : largeint); + +begin + If (AValue>=FMinRange) and (AValue<=FMaxRange) then + FMinValue:=AValue + else + RangeError(AValue,FMinRange,FMaxRange); +end; + +{ TSmallintField } + +function TSmallintField.GetDataSize: Integer; + +begin + Result:=SizeOf(SmallInt); +end; + +constructor TSmallintField.Create(AOwner: TComponent); + +begin + inherited Create(AOwner); + SetDataType(ftSmallInt); + FMinRange:=-32768; + FMaxRange:=32767; +end; + + +{ TWordField } + +function TWordField.GetDataSize: Integer; + +begin + Result:=SizeOf(Word); +end; + +constructor TWordField.Create(AOwner: TComponent); + +begin + inherited Create(AOwner); + SetDataType(ftWord); + FMinRange:=0; + FMaxRange:=65535; + FValidchars:=['+','0'..'9']; +end; + +{ TAutoIncField } + +constructor TAutoIncField.Create(AOwner: TComponent); + +begin + Inherited Create(AOWner); + SetDataType(ftAutoInc); + foptionsfield:= (foptionsfield + [of_readonly]) - [of_ininsert,of_inupdate]; +// FReadOnly:=True; +// FProviderFlags:=FProviderFlags-[pfInUpdate]; +end; + +Procedure TAutoIncField.SetAsLongint(AValue : Longint); + +begin + // Some databases allows insertion of explicit values into identity columns + // (some of them also allows (some not) updating identity columns) + // So allow it at client side and leave check for server side + if not(FDataSet.State in [dsFilter,dsSetKey,dsInsert]) then + DataBaseError(SCantSetAutoIncFields); + inherited; +end; + +{ TFloatField } + +procedure TFloatField.SetCurrency(const AValue: Boolean); +begin + if FCurrency=AValue then exit; + FCurrency:=AValue; +end; + +procedure TFloatField.SetPrecision(const AValue: Longint); +begin + if (AValue = -1) or (AValue > 1) then + FPrecision := AValue + else + FPrecision := 2; +end; + +function TFloatField.GetAsFloat: Double; + +begin + If Not GetData(@Result) Then + Result:=0.0; +end; + +function TFloatField.GetAsVariant: Variant; + +Var f : Double; + +begin + If GetData(@f) then + Result := f + else + Result:=Null; +end; + +function TFloatField.GetAsLongint: Longint; + +begin + Result:=Round(GetAsFloat); +end; + +function TFloatField.GetAsString: string; + +Var R : Double; + +begin + If GetData(@R) then + Result:=FloatToStr(R) + else + Result:=''; +end; + +function TFloatField.GetDataSize: Integer; + +begin + Result:=SizeOf(Double); +end; + +procedure TFloatField.GetText(var TheText: string; ADisplayText: Boolean); + +Var + fmt : string; + E : Double; + Digits : integer; + ff: TFloatFormat; + +begin + TheText:=''; + If Not GetData(@E) then exit; + If ADisplayText or (Length(FEditFormat) = 0) Then + Fmt:=FDisplayFormat + else + Fmt:=FEditFormat; + + Digits := 0; + if not FCurrency then + ff := ffGeneral + else + begin + Digits := {$ifdef FPC}defaultformatsettings.{$endif}CurrencyDecimals; + if ADisplayText then + ff := ffCurrency + else + ff := ffFixed; + end; + + + If fmt<>'' then + TheText:=FormatFloat(fmt,E) + else + TheText:=FloatToStrF(E,ff,FPrecision,Digits); +end; + +procedure TFloatField.SetAsFloat(AValue: Double); + +begin + If CheckRange(AValue) then + SetData(@Avalue) + else + RangeError(AValue,FMinValue,FMaxValue); +end; + +procedure TFloatField.SetAsLongint(AValue: Longint); + +begin + SetAsFloat(Avalue); +end; + +procedure TFloatField.SetAsString(const AValue: string); + +Var R : Double; + +begin + If (AValue='') then + Clear + else + try + R := StrToFloat(AValue); + SetAsFloat(R); + except + DatabaseErrorFmt(SNotAFloat, [AValue]); + end; +end; + +procedure TFloatField.SetVarValue(const AValue: Variant); +begin + SetAsFloat(Avalue); +end; + +procedure TFloatField.dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,avalue,accept); + end; +end; + +constructor TFloatField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDatatype(ftfloat); + FPrecision:=15; + FValidChars := [{$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator, + '+', '-', '0'..'9', 'E', 'e']; +end; + +Function TFloatField.CheckRange(AValue : Double) : Boolean; + +begin + If (FMinValue<>0) or (FmaxValue<>0) then + Result:=(AValue>=FMinValue) and (AVAlue<=FMAxValue) + else + Result:=True; +end; + +{ TCurrencyField } + +Constructor TCurrencyField.Create(AOwner: TComponent); + +begin + inherited Create(AOwner); + SetDataType(ftCurrency); + Currency := True; +end; + +{ TBooleanField } + +function TBooleanField.GetAsBoolean: Boolean; + +var b : wordbool; + +begin + If GetData(@b) then + result := b + else + Result:=False; +end; + +function TBooleanField.GetAsVariant: Variant; + +Var b : wordbool; + +begin + If GetData(@b) then + Result := b + else + Result:=Null; +end; + +function TBooleanField.GetAsString: string; + +Var B : wordbool; + +begin + If Getdata(@B) then + Result:=FDisplays[False,B] + else + result:=''; +end; + +function TBooleanField.GetDataSize: Integer; + +begin + Result:=SizeOf(wordBool); +end; + +function TBooleanField.GetDefaultWidth: Longint; + +begin + Result:=Length(FDisplays[false,false]); + If Result0); +end; + +procedure TBooleanField.SetAsBoolean(AValue: Boolean); + +var b : wordbool; + +begin + b := AValue; + SetData(@b); +end; + +procedure TBooleanField.SetAsString(const AValue: string); + +Var Temp : string; + +begin + Temp:=UpperCase(AValue); + if Temp='' then + Clear + else if pos(Temp, FDisplays[True,True])=1 then + SetAsBoolean(True) + else if pos(Temp, FDisplays[True,False])=1 then + SetAsBoolean(False) + else + DatabaseErrorFmt(SNotABoolean,[AValue]); +end; + +procedure TBooleanField.SetVarValue(const AValue: Variant); +begin + SetAsBoolean(AValue); +end; + +constructor TBooleanField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftBoolean); + DisplayValues:='True;False'; +end; + +Procedure TBooleanField.SetDisplayValues(const AValue : String); + +Var I : longint; + +begin + If FDisplayValues<>AValue then + begin + I:=Pos(';',AValue); + If (I<2) or (I=Length(AValue)) then + DatabaseErrorFmt(SInvalidDisplayValues,[AValue]); + FdisplayValues:=AValue; + // Store display values and their uppercase equivalents; + FDisplays[False,True]:=Copy(AValue,1,I-1); + FDisplays[True,True]:=UpperCase(FDisplays[False,True]); + FDisplays[False,False]:=Copy(AValue,I+1,Length(AValue)-i); + FDisplays[True,False]:=UpperCase(FDisplays[False,False]); + PropertyChanged(True); + end; +end; + +procedure TBooleanField.dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean); +var + bo1: boolean; +begin + if assigned(fonsetvalue) then begin + bo1:= avalue <> 0; + fonsetvalue(self,sender,bo1,accept); + if bo1 then begin + avalue:= 1; + end + else begin + avalue:= 0; + end; + end; +end; + +{ TDateTimeField } + +procedure TDateTimeField.SetDisplayFormat(const AValue: string); +begin + if FDisplayFormat<>AValue then begin + FDisplayFormat:=AValue; + PropertyChanged(True); + end; +end; + +function TDateTimeField.GetAsDateTime: TDateTime; + +begin + If Not GetData(@Result,False) then + Result:=0; +end; + +procedure TDateTimeField.SetVarValue(const AValue: Variant); +begin + SetAsDateTime(AValue); +end; + +procedure TDateTimeField.dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,tdatetime(avalue),accept); + end; +end; + +function TDateTimeField.GetAsVariant: Variant; + +Var d : tDateTime; + +begin + If Getdata(@d,False) then + Result := d + else + Result:=Null; +end; + +function TDateTimeField.GetAsFloat: Double; + +begin + Result:=GetAsdateTime; +end; + + +function TDateTimeField.GetAsString: string; + +begin + GetText(Result,False); +end; + + +function TDateTimeField.GetDataSize: Integer; + +begin + Result:=SizeOf(TDateTime); +end; + + +procedure TDateTimeField.GetText(var TheText: string; ADisplayText: Boolean); + +Var R : TDateTime; + F : String; + +begin + If Not Getdata(@R,False) then + TheText:='' + else + begin + If (ADisplayText) and (Length(FDisplayFormat)<>0) then + F:=FDisplayFormat + else + Case DataType of + ftTime : F:= {$ifdef FPC}defaultformatsettings.{$endif}LongTimeFormat; + ftDate : F:= {$ifdef FPC}defaultformatsettings.{$endif}ShortDateFormat; + else + F:='c' + end; + TheText:=FormatDateTime(F,R); + end; +end; + + +procedure TDateTimeField.SetAsDateTime(AValue: TDateTime); + +begin + SetData(@Avalue,False); +end; + + +procedure TDateTimeField.SetAsFloat(AValue: Double); + +begin + SetAsDateTime(AValue); +end; + + +procedure TDateTimeField.SetAsString(const AValue: string); + +Var R : TDateTime; + +begin + if AValue<>'' then + begin + R:=StrToDateTime(AVAlue); + SetData(@R,False); + end + else + SetData(Nil); +end; + + +constructor TDateTimeField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftDateTime); +end; + +function TDateTimeField.getasdate: tdatetime; +begin + result:= int(getasdatetime); +end; + +function TDateTimeField.getastime: tdatetime; +begin + result:= frac(getasdatetime); +end; + +procedure TDateTimeField.setasdate(avalue: tdatetime); +begin + if datatype = fttime then begin + databaseerrorfmt(sassigndate,[fieldname],dataset); + end; + setasdatetime(avalue); +end; + +procedure TDateTimeField.setastime(avalue: tdatetime); +begin + if datatype = ftdate then begin + databaseerrorfmt(sassigntime,[fieldname],dataset); + end; + setasdatetime(avalue); +end; + + +{ TDateField } + +constructor TDateField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftDate); +end; + + +{ TTimeField } + +constructor TTimeField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftTime); +end; + +procedure TTimeField.SetAsString(const AValue: string); +Var R : TDateTime; +begin + if AValue='' then + Clear // set to NULL + else + begin + R:=StrToTime(AVAlue); + SetData(@R,False); + end; +end; + + + +{ TBinaryField } + +class procedure TBinaryField.CheckTypeSize(AValue: Longint); + +begin + // Just check for really invalid stuff; actual size is + // dependent on the record... + If AValue<1 then + DatabaseErrorFmt(SInvalidFieldSize,[AValue]); +end; + +function TBinaryField.GetAsBytes: TBytes; +var B: TBytes; +begin + SetLength(B, DataSize); + if not assigned(B) or not GetData(Pointer(B), True) then + SetLength(Result, 0) + else if DataType = ftVarBytes then + begin + SetLength(Result, PWord(B)^); + Move(B[sizeof(Word)], Result[0], Length(Result)); + end + else // ftBytes + Result := B; +end; + + +function TBinaryField.GetAsString: string; +var + B: TBytes; +begin + B := GetAsBytes; + if length(B) = 0 then + Result := '' + else + SetString(Result, pchar(@B[0]), length(B) div SizeOf(Char)); +end; + + +function TBinaryField.GetAsVariant: Variant; +var B: TBytes; + P: Pointer; +begin + B := GetAsBytes; + Result := VarArrayCreate([0, length(B)-1], varByte); + P := VarArrayLock(Result); + try + Move(B[0], P^, length(B)); + finally + VarArrayUnlock(Result); + end; +end; + + +procedure TBinaryField.GetText(var TheText: string; ADisplayText: Boolean); + +begin + TheText:=GetAsString; +end; + + +procedure TBinaryField.SetAsBytes(const AValue: TBytes); +var Buf: array[0..dsMaxStringSize] of byte; + DynBuf: TBytes; + Len: Word; + P: PByte; +begin + Len := Length(AValue); + if Len >= DataSize then + P := @AValue[0] + else begin + if DataSize <= dsMaxStringSize then + P := @Buf[0] + else begin + SetLength(DynBuf, DataSize); + P := @DynBuf[0]; + end; + + if DataType = ftVarBytes then begin + PWord(P)^ := Len; + Move(AValue[0], pchar(P)[sizeof(Word)], Len); + end + else begin // ftBytes + Move(AValue[0], P^, Len); + FillChar(pchar(P)[Len], DataSize-Len, 0); // right pad with #0 + end; + end; + SetData(P, True) +end; + + +procedure TBinaryField.SetAsString(const AValue: string); +var B : TBytes; +begin + If Length(AValue) = DataSize then + SetData(PChar(AValue)) + else + begin + SetLength(B, Length(AValue) * SizeOf(Char)); + Move(AValue[1], B[0], Length(B)); + SetAsBytes(B); + end; +end; + + +procedure TBinaryField.SetText(const AValue: string); + +begin + SetAsString(Avalue); +end; + +procedure TBinaryField.SetVarValue(const AValue: Variant); +var P: Pointer; + B: TBytes; + Len: integer; +begin + if VarIsArray(AValue) then + begin + P := VarArrayLock(AValue); + try + Len := VarArrayHighBound(AValue, 1) + 1; + SetLength(B, Len); + Move(P^, B[0], Len); + finally + VarArrayUnlock(AValue); + end; + SetAsBytes(B); + end + else + SetAsString(AValue); +end; + + +constructor TBinaryField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); +end; + + + +{ TBytesField } + +function TBytesField.GetDataSize: Integer; + +begin + Result:=Size; +end; + + +constructor TBytesField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftBytes); + Size:=16; +end; + + + +{ TVarBytesField } + +function TVarBytesField.GetDataSize: Integer; + +begin + Result:=Size+2; +end; + + +constructor TVarBytesField.Create(AOwner: TComponent); + +begin + INherited Create(AOwner); + SetDataType(ftvarbytes); + Size:=16; +end; + +{ TBCDField } + +class procedure TBCDField.CheckTypeSize(AValue: Longint); + +begin + If not (AValue in [0..4]) then + DatabaseErrorfmt(SInvalidFieldSize,[Avalue]); +end; + +function TBCDField.GetAsCurrency: Currency; + +begin + if not GetData(@Result) then + result := 0; +end; + +function TBCDField.GetAsVariant: Variant; + +Var c : system.Currency; + +begin + If GetData(@c) then + Result := c + else + Result:=Null; +end; + +function TBCDField.GetAsFloat: Double; + +begin + result := GetAsCurrency; +end; + + +function TBCDField.GetAsLongint: Longint; + +begin + result := round(GetAsCurrency); +end; + + +function TBCDField.GetAsString: string; + +var c : system.currency; + +begin + If GetData(@C) then + Result:=CurrToStr(C) + else + Result:=''; +end; + +function TBCDField.GetValue(var AValue: Currency): Boolean; + +begin + Result := GetData(@AValue); +end; + +function TBCDField.GetDataSize: Integer; + +begin + result := sizeof(system.currency); +end; + +function TBCDField.GetDefaultWidth: Longint; + +begin + if precision > 0 then result := precision + else result := 10; +end; + +procedure TBCDField.GetText(var TheText: string; ADisplayText: Boolean); +var + c : system.currency; + fmt: String; +begin + if GetData(@C) then begin + if aDisplayText or (FEditFormat='') then + fmt := FDisplayFormat + else + fmt := FEditFormat; + if fmt<>'' then + TheText := FormatFloat(fmt,C) + else if fCurrency then begin + if aDisplayText then + TheText := FloatToStrF(C, ffCurrency, FPrecision, 2{digits?}) + else + TheText := FloatToStrF(C, ffFixed, FPrecision, 2{digits?}); + end else + TheText := FloatToStrF(C, ffGeneral, FPrecision, 0{digits?}); + end else + TheText := ''; +end; + +procedure TBCDField.SetAsCurrency(AValue: Currency); + +begin + If CheckRange(AValue) then + setdata(@AValue) + else + RangeError(AValue,FMinValue,FMaxvalue); +end; + +procedure TBCDField.SetVarValue(const AValue: Variant); +begin + SetAsCurrency(AValue); +end; + +procedure TBCDField.dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean); +var + val1: currency; +begin + if assigned(fonsetvalue) then begin + val1:= avalue; + fonsetvalue(self,sender,val1,accept); + value:= val1; + end; +end; + +Function TBCDField.CheckRange(AValue : Currency) : Boolean; + +begin + If (FMinValue<>0) or (FmaxValue<>0) then + Result:=(AValue>=FMinValue) and (AVAlue<=FMaxValue) + else + Result:=True; +end; + +procedure TBCDField.SetAsFloat(AValue: Double); + +begin + SetAsCurrency(AValue); +end; + + +procedure TBCDField.SetAsLongint(AValue: Longint); + +begin + SetAsCurrency(AValue); +end; + + +procedure TBCDField.SetAsString(const AValue: string); + +begin + if AValue='' then + Clear // set to NULL + else + SetAsCurrency(strtocurr(AValue)); +end; + +constructor TBCDField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + FMaxvalue := 0; + FMinvalue := 0; + FValidChars := [{$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator, + '+', '-', '0'..'9']; + SetDataType(ftBCD); + FPrecision := 15; + Size:=4; +end; + + +{ TFMTBCDField } + +class procedure TFMTBCDField.CheckTypeSize(AValue: Longint); +begin + If AValue > MAXFMTBcdFractionSize then + DatabaseErrorfmt(SInvalidFieldSize,[AValue]); +end; + +constructor TFMTBCDField.Create(AOwner: TComponent); +begin + Inherited Create(AOwner); + FMaxValue := nullbcd; + FMinValue := nullbcd; + FValidChars := [{$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator, + '+', '-', '0'..'9']; + SetDataType(ftFMTBCD); +// Max.precision for NUMERIC,DECIMAL datatypes supported by some databases: +// Firebird-18; Oracle,SqlServer-38; MySQL-65; PostgreSQL-1000 + Precision := 15; //default number of digits + Size:=4; //default number of digits after decimal place +end; + +function TFMTBCDField.GetDataSize: Integer; +begin + Result := sizeof(TBCD); +end; + +function TFMTBCDField.GetDefaultWidth: Longint; +begin + if Precision > 0 then Result := Precision+1 + else Result := inherited GetDefaultWidth; +end; + +function TFMTBCDField.GetAsBCD: TBCD; +begin + if not GetData(@Result) then + Result := NullBCD; +end; + +function TFMTBCDField.GetAsCurrency: Currency; +var bcd: TBCD; +begin + if GetData(@bcd) then + BCDToCurr(bcd, Result) + else + Result := 0; +end; + +function TFMTBCDField.GetAsVariant: Variant; +var bcd: TBCD; +begin + If GetData(@bcd) then + Result := VarFMTBcdCreate(bcd) + else + Result := Null; +end; + +function TFMTBCDField.GetAsFloat: Double; +var bcd: TBCD; +begin + If GetData(@bcd) then + Result := BCDToDouble(bcd) + else + Result := 0; +end; + +function TFMTBCDField.GetAsLongint: Longint; +begin + Result := round(GetAsFloat); +end; + +function TFMTBCDField.GetAsString: string; +var bcd: TBCD; +begin + If GetData(@bcd) then + Result:=BCDToStr(bcd) + else + Result:=''; +end; + +procedure TFMTBCDField.GetText(var TheText: string; ADisplayText: Boolean); +var + bcd: TBCD; + fmt: String; +begin + if GetData(@bcd) then begin + if aDisplayText or (FEditFormat='') then + fmt := FDisplayFormat + else + fmt := FEditFormat; + if fmt<>'' then + TheText := BCDToStr(bcd) + //TheText := FormatBCD(fmt,bcd) //uncomment when formatBCD in fmtbcd.pp will be implemented + else if fCurrency then begin + if aDisplayText then + TheText := BcdToStrF(bcd, ffCurrency, FPrecision, 2) + else + TheText := BcdToStrF(bcd, ffFixed, FPrecision, 2); + end else + TheText := BcdToStrF(bcd, ffGeneral, FPrecision, FSize); + end else + TheText := ''; +end; + +function TFMTBCDField.GetMaxValue: string; +begin + Result:=BCDToStr(FMaxValue); +end; + +function TFMTBCDField.GetMinValue: string; +begin + Result:=BCDToStr(FMinValue); +end; + +procedure TFMTBCDField.SetMaxValue(const AValue: string); +begin + FMaxValue:=StrToBCD(AValue); +end; + +procedure TFMTBCDField.SetMinValue(const AValue: string); +begin + FMinValue:=StrToBCD(AValue); +end; + +Function TFMTBCDField.CheckRange(AValue: TBCD) : Boolean; +begin + If (bcdcompare(FMinValue,nullbcd) <> 0) or + (bcdcompare(FMaxValue,nullbcd)<> 0) then + Result:= (bcdcompare(AValue,FMinValue) >= 0) and + (bcdcompare(AValue,FMaxValue) <= 0) + else + Result:=True; +end; + +procedure TFMTBCDField.SetAsBCD(const AValue: TBCD); +begin + if CheckRange(AValue) then + SetData(@AValue) + else + RangeError(bcdtodouble(AValue), BCDToDouble(FMinValue), + BCDToDouble(FMaxValue)); +end; + +procedure TFMTBCDField.SetAsCurrency(AValue: Currency); +var bcd: TBCD; +begin + if CurrToBCD(AValue, bcd, 32, Size) then + SetAsBCD(bcd); +end; + +procedure TFMTBCDField.SetVarValue(const AValue: Variant); +begin + SetAsBCD(VarToBCD(AValue)); +end; + +procedure TFMTBCDField.SetAsFloat(AValue: Double); +begin + SetAsBCD(DoubleToBCD(AValue)); +end; + + +procedure TFMTBCDField.SetAsLongint(AValue: Longint); +begin + SetAsBCD(IntegerToBCD(AValue)); +end; + + +procedure TFMTBCDField.SetAsString(const AValue: string); +begin + if AValue='' then + Clear // set to NULL + else + SetAsBCD(StrToBCD(AValue)); +end; + + +{ TBlobField } + +Function TBlobField.GetBlobStream(Mode : TBlobStreamMode) : TStream; + +begin + Result:=FDataset.CreateBlobStream(Self,Mode); +end; + +procedure TBlobField.FreeBuffers; + +begin +end; + + +function TBlobField.GetAsString: string; +var + Stream : TStream; + Len : Integer; +begin + Stream := GetBlobStream(bmRead); + if Stream <> nil then + With Stream do + try + Len := Size; + SetLength(Result, Len); + if Len > 0 then + ReadBuffer(Result[1], Len); + finally + Free + end + else + Result := ''; +end; + +function TBlobField.GetAsWideString: WideString; +var + Stream : TStream; + Len : Integer; +begin + Stream := GetBlobStream(bmRead); + if Stream <> nil then + With Stream do + try + Len := Size; + SetLength(Result,Len div 2); + if Len > 0 then + ReadBuffer(Result[1] ,Len); + finally + Free + end + else + Result := ''; +end; + +function TBlobField.GetAsVariant: Variant; + +Var s : string; + +begin + if not GetIsNull then + begin + s := GetAsString; + result := s; + end + else result := Null; +end; + + +function TBlobField.GetBlobSize: Longint; +var + Stream: TStream; +begin + Stream := GetBlobStream(bmread); + if Stream <> nil then + With Stream do + try + Result:=Size; + finally + Free; + end + else + result := 0; +end; + + +function TBlobField.GetIsNull: Boolean; + +begin + If Not Modified then + result:= inherited GetIsnull + else + With GetBlobStream(bmread) do + try + Result:=(Size=0); + Finally + Free; + end; +end; + + +procedure TBlobField.GetText(var TheText: string; ADisplayText: Boolean); + +begin + TheText:=inherited GetAsString; +end; + + +procedure TBlobField.SetAsString(const AValue: string); +var + Len : Integer; +begin + With GetBlobStream(bmwrite) do + try + Len := Length(Avalue); + if Len > 0 then + WriteBuffer(aValue[1], Len); + finally + Free; + end; +end; + + +procedure TBlobField.SetAsWideString(const AValue: WideString); +var + Len : Integer; +begin + With GetBlobStream(bmwrite) do + try + Len := Length(Avalue) * 2; + if Len > 0 then + WriteBuffer(aValue[1], Len); + finally + Free; + end; +end; + + +procedure TBlobField.SetText(const AValue: string); + +begin + SetAsString(AValue); +end; + +procedure TBlobField.SetVarValue(const AValue: Variant); +begin + SetAsString(AValue); +end; + + +constructor TBlobField.Create(AOwner: TComponent); + +begin + Inherited Create(AOWner); + SetDataType(ftBlob); +end; + + +procedure TBlobField.Clear; + +begin + GetBlobStream(bmWrite).free; +end; + + +class function TBlobField.IsBlob: Boolean; + +begin + Result:=True; +end; + + +procedure TBlobField.LoadFromFile(const FileName: string); + +Var S : TFileStream; + +begin + S:=TFileStream.Create(FileName,fmOpenRead); + try + LoadFromStream(S); + finally + S.Free; + end; +end; + + +procedure TBlobField.LoadFromStream(Stream: TStream); + +begin + With GetBlobStream(bmWrite) do + Try + CopyFrom(Stream,0); + finally + Free; + end; +end; + + +procedure TBlobField.SaveToFile(const FileName: string); + +Var S : TFileStream; + +begin + S:=TFileStream.Create(FileName,fmCreate); + try + SaveToStream(S); + finally + S.Free; + end; +end; + + +procedure TBlobField.SaveToStream(Stream: TStream); + +Var S : TStream; + +begin + S:=GetBlobStream(bmRead); + Try + If Assigned(S) then + Stream.CopyFrom(S,0); + finally + S.Free; + end; +end; + +procedure TBlobField.SetFieldType(AValue: TFieldType); + +begin + If AValue in [Low(TBlobType)..High(TBlobType)] then + SetDatatype(Avalue); +end; + +{ TMemoField } + +constructor TMemoField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftMemo); +end; + +function TMemoField.GetAsWideString: WideString; +begin + Result := widestring(GetAsString); +end; + +procedure TMemoField.SetAsWideString(const aValue: WideString); +begin + SetAsString(ansistring(aValue)); +end; + +{ TWideMemoField } + +constructor TWideMemoField.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + SetDataType(ftWideMemo); +end; + +function TWideMemoField.GetAsString: string; +begin + Result := ansistring(GetAsWideString); +end; + +procedure TWideMemoField.SetAsString(const aValue: string); +begin + SetAsWideString(widestring(aValue)); +end; + +function TWideMemoField.GetAsVariant: Variant; + +//Var s : string; + +begin + if not GetIsNull then + begin + result:= getaswidestring; + { + s := GetAsWideString; + result := s; + } + end + else result := Null; +end; + +procedure TWideMemoField.SetVarValue(const AValue: Variant); +begin + SetAsWideString(AValue); +end; + +{ TGraphicField } + +constructor TGraphicField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftGraphic); +end; + +{ TGuidField } + +constructor TGuidField.Create(AOwner: TComponent); +begin + Size := 38; + inherited Create(AOwner); + SetDataType(ftGuid); +end; + +class procedure TGuidField.CheckTypeSize(AValue: LongInt); +begin + if aValue <> 38 then + DatabaseErrorFmt(SInvalidFieldSize,[AValue]); +end; + +function TGuidField.GetAsGuid: TGUID; +const + nullguid: TGUID = '{00000000-0000-0000-0000-000000000000}'; +var + S: string; +begin + S := GetAsString; + if S = '' then + Result := nullguid + else + Result := StringToGuid(S); +end; + +function TGuidField.GetDefaultWidth: LongInt; +begin + Result := 38; +end; + +procedure TGuidField.SetAsGuid(const aValue: TGUID); +begin + SetAsString(GuidToString(aValue)); +end; + +function TVariantField.GetDefaultWidth: Integer; +begin + Result := 15; +end; + +{ TVariantField } + +constructor TVariantField.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + SetDataType(ftVariant); +end; + +class procedure TVariantField.CheckTypeSize(aValue: Integer); +begin + { empty } +end; + +function TVariantField.GetAsBoolean: Boolean; +begin + Result := GetAsVariant; +end; + +function TVariantField.GetAsDateTime: TDateTime; +begin + Result := GetAsVariant; +end; + +function TVariantField.GetAsFloat: Double; +begin + Result := GetAsVariant; +end; + +function TVariantField.GetAsInteger: Longint; +begin + Result := GetAsVariant; +end; + +function TVariantField.GetAsString: string; +begin + Result := VarToStr(GetAsVariant); +end; + +function TVariantField.GetAsWideString: WideString; +begin + Result := VarToWideStr(GetAsVariant); +end; + +procedure tvariantfield.setasunicodestring(const avalue: unicodestring); +begin + setvarvalue(avalue); +end; + +function tvariantfield.getasunicodestring: unicodestring; +begin + Result := VarTounicodeStr(GetAsVariant); + { + if isnull then begin + result:= ''; + end + else begin + result:= getasvariant; + end; + } +end; + + +function TVariantField.GetAsVariant: Variant; +begin + if not GetData(@Result) then + Result := Null; +end; + +procedure TVariantField.SetAsBoolean(aValue: Boolean); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetAsDateTime(aValue: TDateTime); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetAsFloat(aValue: Double); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetAsInteger(aValue: Longint); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetAsString(const aValue: string); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetAsWideString(const aValue: WideString); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetVarValue(const aValue: Variant); +begin + SetData(@aValue); +end; + +{ TFieldsEnumerator } + +function TFieldsEnumerator.GetCurrent: TField; +begin + Result := FFields[FPosition]; +end; + +constructor TFieldsEnumerator.Create(AFields: TFields); +begin + inherited Create; + FFields := AFields; + FPosition := -1; +end; + +function TFieldsEnumerator.MoveNext: Boolean; +begin + inc(FPosition); + Result := FPosition < FFields.Count; +end; + +{ TFields } + +Constructor TFields.Create(ADataset : TDataset); + +begin + FDataSet:=ADataset; + FFieldList:=TFpList.Create; + FValidFieldKinds:=[fkData..fkInternalcalc]; +end; + +Destructor TFields.Destroy; + +begin + if Assigned(FFieldList) then + Clear; + FreeAndNil(FFieldList); + inherited Destroy; +end; + +Procedure Tfields.Changed; + +begin + if (FDataSet <> nil) and not (csDestroying in FDataSet.ComponentState) and FDataset.Active then + FDataSet.DataEvent(deFieldListChange, 0); + If Assigned(FOnChange) then + FOnChange(Self); +end; + +Procedure TFields.CheckfieldKind(Fieldkind : TFieldKind; Field : TField); + +begin + If Not (FieldKind in ValidFieldKinds) Then + DatabaseErrorFmt(SInvalidFieldKind,[Field.FieldName]); +end; + +Function Tfields.GetCount : Longint; + +begin + Result:=FFieldList.Count; +end; + + +Function TFields.GetField (Index : longint) : TField; + +begin + Result:=Tfield(FFieldList[Index]); +end; + +procedure Tfields.SetField(Index: Integer; Value: TField); +begin + Fields[Index].Assign(Value); +end; + +Procedure TFields.SetFieldIndex (Field : TField;Value : Integer); + +Var Old : Longint; + +begin + Old := FFieldList.indexOf(Field); + If Old=-1 then + Exit; + // Check value + If Value<0 Then Value:=0; + If Value>=Count then Value:=Count-1; + If Value<>Old then + begin + FFieldList.Delete(Old); + FFieldList.Insert(Value,Field); + Field.PropertyChanged(True); + Changed; + end; +end; + +Procedure TFields.Add(Field : TField); + +begin + CheckFieldName(Field.FieldName); + FFieldList.Add(Field); + Field.FFields:=Self; + Changed; +end; + +Procedure TFields.CheckFieldName (Const Value : String); + +begin + If FindField(Value)<>Nil then + DataBaseErrorFmt(SDuplicateFieldName,[Value],FDataset); +end; + +Procedure TFields.CheckFieldNames (Const Value : String); + + +Var I : longint; + S,T : String; +begin + T:=Value; + Repeat + I:=Pos(';',T); + If I=0 Then I:=Length(T)+1; + S:=Copy(T,1,I-1); + Delete(T,1,I); + // Will raise an error if no such field... + FieldByName(S); + Until (T=''); +end; + +Procedure TFields.Clear; +var + AField: TField; +begin + while FFieldList.Count > 0 do + begin + AField := TField(FFieldList.Last); + AField.FDataSet := Nil; + AField.Free; + FFieldList.Delete(FFieldList.Count - 1); + end; + Changed; +end; + +Function TFields.FindField (Const Value : String) : TField; + +Var S : String; + I : longint; + +begin + Result:=Nil; + S:=UpperCase(Value); + For I:=0 To FFieldList.Count-1 do + If S=UpperCase(TField(FFieldList[i]).FieldName) Then + Begin + {$ifdef dsdebug} + Writeln ('Found field ',Value); + {$endif} + Result:=TField(FFieldList[I]); + Exit; + end; +end; + +Function TFields.FieldByName (Const Value : String) : TField; + +begin + Result:=FindField(Value); + If result=Nil then + DatabaseErrorFmt(SFieldNotFound,[Value],FDataset); +end; + +Function TFields.FieldByNumber(FieldNo : Integer) : TField; + +Var i : Longint; + +begin + Result:=Nil; + For I:=0 to FFieldList.Count-1 do + If FieldNo=TField(FFieldList[I]).FieldNo then + begin + Result:=TField(FFieldList[i]); + Exit; + end; +end; + +Function TFields.GetEnumerator: TFieldsEnumerator; + +begin + Result:=TFieldsEnumerator.Create(Self); +end; + +Procedure TFields.GetFieldNames (Values : TStrings); + +Var i : longint; + +begin + Values.Clear; + For I:=0 to FFieldList.Count-1 do + Values.Add(Tfield(FFieldList[I]).FieldName); +end; + +Function TFields.IndexOf(Field : TField) : Longint; + +begin + Result:=FFieldList.IndexOf(Field); +end; + +procedure TFields.Remove(Value : TField); + +begin + FFieldList.Remove(Value); + Value.FFields := nil; + Changed; +end; + + +{ --------------------------------------------------------------------- + TDatalink + ---------------------------------------------------------------------} + +Constructor TDataLink.Create; + +begin + Inherited Create; + FBufferCount:=1; + FFirstRecord := 0; + FDataSource := nil; + FDatasourceFixed:=False; +end; + + +Destructor TDataLink.Destroy; + +begin + Factive:=False; + FEditing:=False; + FDataSourceFixed:=False; + DataSource:=Nil; + Inherited Destroy; +end; + + +Procedure TDataLink.ActiveChanged; + +begin + FFirstRecord := 0; +end; + +Procedure TDataLink.CheckActiveAndEditing; + +Var + B : Boolean; + +begin + B:=Assigned(DataSource) and (DataSource.State<>dsInactive); + If B<>FActive then + begin + FActive:=B; + ActiveChanged; + end; + B:=Assigned(DataSource) and (DataSource.State in dsEditModes) and Not FReadOnly; + If B<>FEditing Then + begin + FEditing:=B; + EditingChanged; + end; +end; + + +Procedure TDataLink.CheckBrowseMode; + +begin +end; + + +Function TDataLink.CalcFirstRecord(Index : Integer) : Integer; +begin + if DataSource.DataSet.FActiveRecord > FFirstRecord + Index + FBufferCount - 1 then + Result := DataSource.DataSet.FActiveRecord - (FFirstRecord + Index + FBufferCount - 1) + else if DataSource.DataSet.FActiveRecord < FFirstRecord + Index then + Result := DataSource.DataSet.FActiveRecord - (FFirstRecord + Index) + else Result := 0; + + Inc(FFirstRecord, Index + Result); +end; + + +Procedure TDataLink.CalcRange; +var + aMax, aMin: integer; +begin + aMin:= DataSet.FActiveRecord - FBufferCount + 1; + If aMin < 0 Then aMin:= 0; + aMax:= Dataset.FBufferCount - FBufferCount; + If aMax < 0 then aMax:= 0; + + If aMax>DataSet.FActiveRecord Then aMax:=DataSet.FActiveRecord; + + If FFirstRecord < aMin Then FFirstRecord:= aMin; + If FFirstrecord > aMax Then FFirstRecord:= aMax; + + If (FfirstRecord<>0) And + (DataSet.FActiveRecord - FFirstRecord < FBufferCount -1) Then + Dec(FFirstRecord, 1); + +end; + + +Procedure TDataLink.DataEvent(Event: TDataEvent; Info: Ptrint); + + +begin + Case Event of + deFieldChange, deRecordChange: + If Not FUpdatingRecord then + RecordChanged(TField(Info)); + deDataSetChange: begin + SetActive(DataSource.DataSet.Active); + CalcRange; + CalcFirstRecord(Info); + DatasetChanged; + end; + deDataSetScroll: DatasetScrolled(CalcFirstRecord(Info)); + deLayoutChange: begin + CalcFirstRecord(Info); + LayoutChanged; + end; + deUpdateRecord: UpdateRecord; + deUpdateState: CheckActiveAndEditing; + deCheckBrowseMode: CheckBrowseMode; + deFocusControl: FocusControl(TFieldRef(Info)); + end; +end; + + +Procedure TDataLink.DataSetChanged; + +begin + RecordChanged(Nil); +end; + + +Procedure TDataLink.DataSetScrolled(Distance: Integer); + +begin + DataSetChanged; +end; + + +Procedure TDataLink.EditingChanged; + +begin +end; + + +Procedure TDataLink.FocusControl(Field: TFieldRef); + +begin +end; + + +Function TDataLink.GetActiveRecord: Integer; + +begin + Result:=Dataset.FActiveRecord - FFirstRecord; +end; + +Function TDatalink.GetDataSet : TDataset; + +begin + If Assigned(Datasource) then + Result:=DataSource.DataSet + else + Result:=Nil; +end; + + +Function TDataLink.GetBOF: Boolean; + +begin + Result:=DataSet.BOF +end; + + +Function TDataLink.GetBufferCount: Integer; + +begin + Result:=FBufferCount; +end; + + +Function TDataLink.GetEOF: Boolean; + +begin + Result:=DataSet.EOF +end; + + +Function TDataLink.GetRecordCount: Integer; + +begin + Result:=Dataset.FRecordCount; + If Result>BufferCount then + Result:=BufferCount; +end; + + +Procedure TDataLink.LayoutChanged; + +begin + DataSetChanged; +end; + + +Function TDataLink.MoveBy(Distance: Integer): Integer; + +begin + Result:=DataSet.MoveBy(Distance); +end; + + +Procedure TDataLink.RecordChanged(Field: TField); + +begin +end; + + +Procedure TDataLink.SetActiveRecord(Value: Integer); + +begin +{$ifdef dsdebug} + Writeln('Datalink. Setting active record to ',Value,' with firstrecord ',ffirstrecord); +{$endif} + Dataset.FActiveRecord:=Value + FFirstRecord; +end; + + +Procedure TDataLink.SetBufferCount(Value: Integer); + +begin + If FBufferCount<>Value then + begin + FBufferCount:=Value; + if Active then begin + DataSet.RecalcBufListSize; + CalcRange; + end; + end; +end; + +procedure TDataLink.SetActive(AActive: Boolean); +begin + if Active <> AActive then + begin + FActive := AActive; + // !!!: Set internal state + ActiveChanged; + end; +end; + +Procedure TDataLink.SetDataSource(Value : TDatasource); + +begin + if FDataSource = Value then + Exit; + if not FDataSourceFixed then + begin + if Assigned(DataSource) then + Begin + DataSource.UnregisterDatalink(Self); + FDataSource := nil; + CheckActiveAndEditing; + End; + FDataSource := Value; + if Assigned(DataSource) then + begin + DataSource.RegisterDatalink(Self); + CheckActiveAndEditing; + End; + end; +end; + +Procedure TDatalink.SetReadOnly(Value : Boolean); + +begin + If FReadOnly<>Value then + begin + FReadOnly:=Value; + CheckActiveAndEditing; + end; +end; + +Procedure TDataLink.UpdateData; + +begin +end; + + + +Function TDataLink.Edit: Boolean; + +begin + If Not FReadOnly then + DataSource.Edit; + // Triggered event will set FEditing + Result:=FEditing; +end; + + +Procedure TDataLink.UpdateRecord; + +begin + FUpdatingRecord:=True; + Try + UpdateData; + finally + FUpdatingRecord:=False; + end; +end; + +function TDataLink.ExecuteAction(Action: TBasicAction): Boolean; +begin + if Action.HandlesTarget(DataSource) then + begin + Action.ExecuteTarget(DataSource); + Result := True; + end + else Result := False; +end; + +function TDataLink.UpdateAction(Action: TBasicAction): Boolean; +begin + if Action.HandlesTarget(DataSource) then + begin + Action.UpdateTarget(DataSource); + Result := True; + end + else Result := False; +end; + +function tdatalink.datasourcereadonly(): boolean; +begin + result:= fdatasource.readonly; +end; + +function TDataLink.getreadonly: Boolean; +begin + result:= freadonly or (fdatasource <> nil) and datasourcereadonly(); +end; + +function TDataLink.getactive: Boolean; +begin + result:= factive and (fdatasource <> nil) and (fdatasource.enabled); +end; + +procedure TDataLink.updateactive(); +begin + setactive((fdatasource <> nil) and (fdatasource.fdataset <> nil) and + fdatasource.fdataset.active); +end; +{ +procedure TDataLink.doenter(const aobject: tobject); +begin + if fdatasource <> nil then begin + fdatasource.doenter(self,aobject); + end; +end; + +procedure TDataLink.doexit(const aobject: tobject); +begin + if fdatasource <> nil then begin + fdatasource.doexit(self,aobject); + end; +end; +} + +{ --------------------------------------------------------------------- + TDetailDataLink + ---------------------------------------------------------------------} + +Function TDetailDataLink.GetDetailDataSet: TDataSet; + +begin + Result := nil; +end; + + +{ --------------------------------------------------------------------- + TMasterDataLink + ---------------------------------------------------------------------} + +constructor TMasterDataLink.Create(ADataSet: TDataSet); + +begin + inherited Create; + FDetailDataSet:=ADataSet; + FFields:=TList.Create; +end; + + +destructor TMasterDataLink.Destroy; + +begin + FFields.Free; + inherited Destroy; +end; + + +Procedure TMasterDataLink.ActiveChanged; + +begin + FFields.Clear; + if Active then + try + DataSet.GetFieldList(FFields, FFieldNames); + except + FFields.Clear; + raise; + end; + if FDetailDataSet.Active and not (csDestroying in FDetailDataSet.ComponentState) then + if Active and (FFields.Count > 0) then + DoMasterChange + else + DoMasterDisable; +end; + + +Procedure TMasterDataLink.CheckBrowseMode; + +begin + if FDetailDataSet.Active then FDetailDataSet.CheckBrowseMode; +end; + + +Function TMasterDataLink.GetDetailDataSet: TDataSet; + +begin + Result := FDetailDataSet; +end; + + +Procedure TMasterDataLink.LayoutChanged; + +begin + ActiveChanged; +end; + + +Procedure TMasterDataLink.RecordChanged(Field: TField); + +begin + if (DataSource.State <> dsSetKey) and FDetailDataSet.Active and + (FFields.Count > 0) and ((Field = nil) or + (FFields.IndexOf(Field) >= 0)) then + DoMasterChange; +end; + +procedure TMasterDatalink.SetFieldNames(const Value: string); + +begin + if FFieldNames <> Value then + begin + FFieldNames := Value; + ActiveChanged; + end; +end; + +Procedure TMasterDataLink.DoMasterDisable; + +begin + if Assigned(FOnMasterDisable) then + FOnMasterDisable(Self); +end; + +Procedure TMasterDataLink.DoMasterChange; + +begin + If Assigned(FOnMasterChange) then + FOnMasterChange(Self); +end; + +{ --------------------------------------------------------------------- + TMasterDataLink + ---------------------------------------------------------------------} + +constructor TMasterParamsDataLink.Create(ADataSet: TDataSet); + +Var + P : TParams; + +begin + inherited Create(ADataset); + If (ADataset<>Nil) then + begin + P:=TParams(GetObjectProp(ADataset,'Params',TParams)); + if (P<>Nil) then + Params:=P; + end; +end; + + +Procedure TMasterParamsDataLink.SetParams(AVAlue : TParams); + +begin + FParams:=AValue; + If (AValue<>Nil) then + RefreshParamNames; +end; + +Procedure TMasterParamsDataLink.RefreshParamNames; + +Var + FN : String; + DS : TDataset; + F : TField; + I : Integer; + +begin + FN:=''; + DS:=Dataset; + If Assigned(FParams) then + begin + F:=Nil; + For I:=0 to FParams.Count-1 do + begin + If Assigned(DS) then + F:=DS.FindField(FParams[i].Name); + If (Not Assigned(DS)) or (not DS.Active) or (F<>Nil) then + begin + If (FN<>'') then + FN:=FN+';'; + FN:=FN+FParams[i].Name; + end; + end; + end; + FieldNames:=FN; +end; + +Procedure TMasterParamsDataLink.CopyParamsFromMaster(CopyBound : Boolean); + +begin + if Assigned(FParams) then + FParams.CopyParamValuesFromDataset(Dataset,CopyBound); +end; + +Procedure TMasterParamsDataLink.DoMasterDisable; + +begin + Inherited; + If Assigned(DetailDataset) and DetailDataset.Active then + DetailDataset.Close; +end; + +Procedure TMasterParamsDataLink.DoMasterChange; + +begin + Inherited; + if Assigned(Params) and Assigned(DetailDataset) and DetailDataset.Active then + begin + DetailDataSet.CheckBrowseMode; + DetailDataset.Close; + DetailDataset.Open; + end; +end; + +{ --------------------------------------------------------------------- + TDatasource + ---------------------------------------------------------------------} + +Constructor TDataSource.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + FDatalinks := TList.Create; + FEnabled := True; + FAutoEdit := True; +end; + + +Destructor TDataSource.Destroy; + +begin + FOnStateCHange:=Nil; + Dataset:=Nil; + With FDataLinks do + While Count>0 do + TDatalink(Items[Count - 1]).DataSource:=Nil; + FDatalinks.Free; + inherited Destroy; +end; + + +Procedure TDatasource.Edit; + +begin + If (State=dsBrowse) and AutoEdit Then + Dataset.Edit; +end; + +Function TDataSource.IsLinkedTo(ADataSet: TDataSet): Boolean; + +begin + Result:=False; +end; + + +procedure TDatasource.DistributeEvent(Event: TDataEvent; Info: Ptrint); + + +Var + i : Longint; + +begin + With FDatalinks do + begin + For I:=0 to Count-1 do + With TDatalink(Items[i]) do + If Not VisualControl Then + DataEvent(Event,Info); + For I:=0 to Count-1 do + With TDatalink(Items[i]) do + If VisualControl Then + DataEvent(Event,Info); + end; +end; + +procedure TDatasource.RegisterDataLink(DataLink: TDataLink); + +begin + FDatalinks.Add(DataLink); + if Assigned(DataSet) then + DataSet.RecalcBufListSize; +end; + + +procedure TDatasource.SetDataSet(ADataSet: TDataSet); +begin + If FDataset<>Nil Then + Begin + FDataset.UnRegisterDataSource(Self); + FDataSet:=nil; + ProcessEvent(deUpdateState,0); + End; + If ADataset<>Nil Then + begin + ADataset.RegisterDatasource(Self); + FDataSet:=ADataset; + ProcessEvent(deUpdateState,0); + End; +end; + + +procedure TDatasource.SetEnabled(Value: Boolean); + +begin + if fenabled <> value then begin + FEnabled:=Value; + if caneventdistribute() then begin + processevent(dedisabledstatechange,0); + end; + end; +end; + + +Procedure TDatasource.DoDataChange (Info : Pointer); + +begin + If Assigned(OnDataChange) Then + OnDataChange(Self,TField(Info)); +end; + +Procedure TDatasource.DoStateChange; + +begin + If Assigned(OnStateChange) Then + OnStateChange(Self); +end; + +procedure tdatasource.doenabledchange(); + +begin + if assigned(fonenabledchange) then begin + onenabledchange(self); + end; +end; + + +Procedure TDatasource.DoUpdateData; + +begin + If Assigned(OnUpdateData) Then + OnUpdateData(Self); +end; + + +procedure TDatasource.UnregisterDataLink(DataLink: TDataLink); + +begin + FDatalinks.Remove(Datalink); + If Dataset<>Nil then + DataSet.RecalcBufListSize; + //Dataset.SetBufListSize(DataLink.BufferCount); +end; + + +procedure TDataSource.ProcessEvent(Event : TDataEvent; Info : Ptrint); + +Const + OnDataChangeEvents = [deRecordChange, deDataSetChange, deDataSetScroll, + deLayoutChange,deUpdateState,dedisabledstatechange]; + +Var + NeedDataChange : Boolean; + FLastState : TdataSetState; + +begin + if enabled or (event = dedisabledstatechange) then begin + + // Special UpdateState handling. + If Event=deUpdateState then + begin + NeedDataChange:=(FState=dsInactive); + FLastState:=FState; + If Assigned(Dataset) then + FState:=Dataset.State + else + FState:=dsInactive; + // Don't do events if nothing changed. + If FState=FlastState then + exit; + end + else + NeedDataChange:=True; + DistributeEvent(Event,Info); + if event = dedisabledstatechange then begin + distributeevent(dedatasetchange,0); + end; + // Extra handlers + If Not (csDestroying in ComponentState) then + begin + if event = dedisabledstatechange then begin + doenabledchange(); + end; + If (Event=deUpdateState) then + DoStateChange; + If (Event in OnDataChangeEvents) and + NeedDataChange Then + DoDataChange(Nil); + If (Event = deFieldChange) Then + DoDataCHange(Pointer(Info)); + If (Event=deUpdateRecord) then + DoUpdateData; + end; + end; +end; + +procedure TDataSource.updaterecord(); +begin + processevent(deupdaterecord,0); +end; + +procedure TDataSource.ifistatechanged(const sender: tdatalink; + const aclient: iificlient; const astate: ifiwidgetstatesty); +begin + if assigned(fonifistatechanged) and + (componentstate * [csloading,csdestroying] = []) then begin + fonifistatechanged(self,sender,aclient,astate); + end; +end; + +procedure TDataSource.setreadonly(const avalue: boolean); +begin + if freadonly <> avalue then begin + freadonly:= avalue; + if caneventdistribute and active then begin + processevent(dedisabledstatechange,0); + end; + end; +end; + +function TDataSource.getactive: boolean; +begin + result:= (fdataset <> nil) and (fdataset.active); +end; + +function TDataSource.caneventdistribute: boolean; +begin + result:= componentstate * [csloading,csreading,csdestroying] = []; +end; + +{ +procedure TDataSource.doenter(const alink: tdatalink; const aobject: tobject); +begin + if assigned(fonenter) and + (componentstate * [csloading,csdestroying] = []) then begin + fonenter(self,alink,aobject); + end; +end; + +procedure TDataSource.doexit(const alink: tdatalink; const aobject: tobject); +begin + if assigned(fonexit) and + (componentstate * [csloading,csdestroying] = []) then begin + fonexit(self,alink,aobject); + end; +end; +} +{ --------------------------------------------------------------------- + TDatabase + ---------------------------------------------------------------------} + +Procedure TDatabase.CheckConnected; + +begin + If Not Connected Then + DatabaseError(SNotConnected,Self); +end; + + +Procedure TDatabase.CheckDisConnected; +begin + If Connected Then + DatabaseError(SConnected,Self); +end; + +procedure TDatabase.DoConnect; +begin + DoInternalConnect; + FConnected := True; +end; + +procedure TDatabase.DoDisconnect; +begin + Closedatasets; + Closetransactions; + DoInternalDisConnect; + if csloading in ComponentState then + FOpenAfterRead := false; + FConnected := False; +end; + +function TDatabase.GetConnected: boolean; +begin + Result:= FConnected; +end; + +constructor TDatabase.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + FParams:=TStringlist.Create; + FDatasets:=TList.Create; + FTransactions:=TList.Create; + FConnected:=False; +end; + +destructor TDatabase.Destroy; + +begin + Connected:=False; + RemoveDatasets; + RemoveTransactions; + FDatasets.Free; + FTransactions.Free; + FParams.Free; + Inherited Destroy; +end; + +procedure TDatabase.CloseDataSets; + +Var I : longint; + +begin + If Assigned(FDatasets) then + begin + For I:=FDatasets.Count-1 downto 0 do + TDataset(FDatasets[i]).Close; + end; +end; + +procedure TDatabase.CloseTransactions; + +Var I : longint; + +begin + If Assigned(FTransactions) then + begin + For I:=FTransactions.Count-1 downto 0 do + TDBTransaction(FTransactions[i]).EndTransaction; + end; +end; + +procedure TDatabase.RemoveDataSets; + +Var I : longint; + +begin + If Assigned(FDatasets) then + For I:=FDataSets.Count-1 downto 0 do + TDBDataset(FDataSets[i]).Database:=Nil; +end; + +procedure TDatabase.RemoveTransactions; + +Var I : longint; + +begin + If Assigned(FTransactions) then + For I:=FTransactions.Count-1 downto 0 do + TDBTransaction(FTransactions[i]).Database:=Nil; +end; + +procedure TDatabase.SetParams(AValue: TStrings); +begin + if AValue<>nil then + FParams.Assign(AValue); +end; + +Function TDatabase.GetDataSetCount : Longint; + +begin + If Assigned(FDatasets) Then + Result:=FDatasets.Count + else + Result:=0; +end; + +Function TDatabase.GetTransactionCount : Longint; + +begin + If Assigned(FTransactions) Then + Result:=FTransactions.Count + else + Result:=0; +end; + +Function TDatabase.GetDataset(Index : longint) : TDataset; + +begin + If Assigned(FDatasets) then + Result:=TDataset(FDatasets[Index]) + else + begin + result := nil; + DatabaseError(SNoDatasets); + end; +end; + +Function TDatabase.GetTransaction(Index : longint) : TDBtransaction; + +begin + If Assigned(FTransactions) then + Result:=TDBTransaction(FTransactions[Index]) + else + begin + result := nil; + DatabaseError(SNoTransactions); + end; +end; + +procedure TDatabase.RegisterDataset (DS : TDBDataset); + +Var I : longint; + +begin + I:=FDatasets.IndexOf(DS); + If I=-1 then + FDatasets.Add(DS) + else + DatabaseErrorFmt(SDatasetRegistered,[DS.Name]); +end; + +procedure TDatabase.RegisterTransaction (TA : TDBTransaction); + +Var I : longint; + +begin + I:=FTransactions.IndexOf(TA); + If I=-1 then + FTransactions.Add(TA) + else + DatabaseErrorFmt(STransactionRegistered,[TA.Name]); +end; + +procedure TDatabase.UnRegisterDataset (DS : TDBDataset); + +Var I : longint; + +begin + I:=FDatasets.IndexOf(DS); + If I<>-1 then + FDatasets.Delete(I) + else + DatabaseErrorFmt(SNoDatasetRegistered,[DS.Name]); +end; + +procedure TDatabase.UnRegisterTransaction (TA : TDBTransaction); + +Var I : longint; + +begin + I:=FTransactions.IndexOf(TA); + If I<>-1 then + FTransactions.Delete(I) + else + DatabaseErrorFmt(SNoTransactionRegistered,[TA.Name]); +end; + + +{ --------------------------------------------------------------------- + TDBdataset + ---------------------------------------------------------------------} + +Procedure TDBDataset.SetDatabase (Value : TDatabase); + +begin + If Value<>FDatabase then + begin + CheckInactive; + If Assigned(FDatabase) then + FDatabase.UnregisterDataset(Self); + If Value<>Nil Then + Value.RegisterDataset(Self); + FDatabase:=Value; + end; +end; + +Procedure TDBDataset.SetTransaction (Value : TDBTransaction); + +begin + CheckInactive; + If Value<>FTransaction then + begin + If Assigned(FTransaction) then + FTransaction.UnregisterDataset(Self); + If Value<>Nil Then + Value.RegisterDataset(Self); + FTransaction:=Value; + end; +end; + +Procedure TDBDataset.CheckDatabase; + +begin + If (FDatabase=Nil) then + DatabaseError(SErrNoDatabaseAvailable,Self) +end; + +Destructor TDBDataset.Destroy; + +begin + Database:=Nil; + Transaction:=Nil; + Inherited; +end; + +{ --------------------------------------------------------------------- + TDBTransaction + ---------------------------------------------------------------------} +procedure TDBTransaction.SetActive(Value : boolean); +begin + if FActive and (not Value) then + EndTransaction + else if (not FActive) and Value then + if csLoading in ComponentState then + begin + FOpenAfterRead := true; + exit; + end + else + StartTransaction; +end; + +procedure TDBTransaction.Loaded; + +begin + inherited; + try + if FOpenAfterRead then SetActive(true); + except + if csDesigning in Componentstate then + InternalHandleException + else + raise; + end; +end; + +Procedure TDBTransaction.InternalHandleException; + +begin + if assigned(classes.ApplicationHandleException) then + classes.ApplicationHandleException(self) + else + ShowException(ExceptObject,ExceptAddr); +end; + +Procedure TDBTransaction.CheckActive; + +begin + If not FActive Then + DatabaseError(STransNotActive,Self); +end; + +Procedure TDBTransaction.CheckInActive; + +begin + If FActive Then + DatabaseError(STransActive,Self); +end; + +Procedure TDBTransaction.CloseTrans; + +begin + FActive := false; +end; + +Procedure TDBTransaction.OpenTrans; + +begin + FActive := true; +end; + +Procedure TDBTransaction.SetDatabase (Value : TDatabase); + +begin + If Value<>FDatabase then + begin + CheckInactive; + If Assigned(FDatabase) then + FDatabase.UnregisterTransaction(Self); + If Value<>Nil Then + Value.RegisterTransaction(Self); + FDatabase:=Value; + end; +end; + +constructor TDBTransaction.create(AOwner : TComponent); + +begin + inherited create(AOwner); + FDatasets:=TList.Create; +end; + +Procedure TDBTransaction.CheckDatabase; + +begin + If (FDatabase=Nil) then + DatabaseError(SErrNoDatabaseAvailable,Self) +end; + +procedure TDBTransaction.CloseDataSets; + +Var I : longint; + +begin + If Assigned(FDatasets) then + begin + For I:=FDatasets.Count-1 downto 0 do + TDBDataset(FDatasets[i]).Close; + end; +end; + +Destructor TDBTransaction.Destroy; + +begin + Database:=Nil; + CloseDataSets; + RemoveDatasets; + FDatasets.Free; + Inherited; +end; + +procedure TDBTransaction.RemoveDataSets; + +Var I : longint; + +begin + If Assigned(FDatasets) then + For I:=FDataSets.Count-1 downto 0 do + TDBDataset(FDataSets[i]).Transaction:=Nil; +end; + +Function TDBTransaction.GetDataSetCount : Longint; + +begin + If Assigned(FDatasets) Then + Result:=FDatasets.Count + else + Result:=0; +end; + +procedure TDBTransaction.UnRegisterDataset (DS : TDBDataset); + +Var I : longint; + +begin + I:=FDatasets.IndexOf(DS); + If I<>-1 then + FDatasets.Delete(I) + else + DatabaseErrorFmt(SNoDatasetRegistered,[DS.Name]); +end; + +procedure TDBTransaction.RegisterDataset (DS : TDBDataset); + +Var I : longint; + +begin + I:=FDatasets.IndexOf(DS); + If I=-1 then + FDatasets.Add(DS) + else + DatabaseErrorFmt(SDatasetRegistered,[DS.Name]); +end; + +Function TDBTransaction.GetDataset(Index : longint) : TDBDataset; + +begin + If Assigned(FDatasets) then + Result:=TDBDataset(FDatasets[Index]) + else + begin + result := nil; + DatabaseError(SNoDatasets); + end; +end; + +{ --------------------------------------------------------------------- + TCustomConnection + ---------------------------------------------------------------------} + +procedure TCustomConnection.SetAfterConnect(const AValue: TNotifyEvent); +begin + FAfterConnect:=AValue; +end; + +function TCustomConnection.GetDataSet(Index: Longint): TDataSet; +begin + Result := nil; +end; + +function TCustomConnection.GetDataSetCount: Longint; +begin + Result := 0; +end; + +procedure TCustomConnection.InternalHandleException; +begin + if assigned(classes.ApplicationHandleException) then + classes.ApplicationHandleException(self) + else + ShowException(ExceptObject,ExceptAddr); +end; + +procedure TCustomConnection.SetAfterDisconnect(const AValue: TNotifyEvent); +begin + FAfterDisconnect:=AValue; +end; + +procedure TCustomConnection.SetBeforeConnect(const AValue: TNotifyEvent); +begin + FBeforeConnect:=AValue; +end; + +procedure TCustomConnection.SetConnected(Value: boolean); +begin + If Value<>Connected then + begin + If Value then + begin + if csReading in ComponentState then + begin + FStreamedConnected := true; + exit; + end + else + begin + if Assigned(BeforeConnect) then + BeforeConnect(self); + if FLoginPrompt then if assigned(FOnLogin) then + FOnLogin(self,'',''); + DoConnect; + if Assigned(AfterConnect) then + AfterConnect(self); + end; + end + else + begin + if Assigned(BeforeDisconnect) then + BeforeDisconnect(self); + DoDisconnect; + if Assigned(AfterDisconnect) then + AfterDisconnect(self); + end; + end; +end; + +procedure TCustomConnection.SetBeforeDisconnect(const AValue: TNotifyEvent); +begin + FBeforeDisconnect:=AValue; +end; + +procedure TCustomConnection.DoConnect; + +begin + // Do nothing yet +end; + +procedure TCustomConnection.DoDisconnect; + +begin + // Do nothing yet +end; + +function TCustomConnection.GetConnected: boolean; + +begin + Result := False; +end; + +procedure TCustomConnection.Loaded; +begin + inherited Loaded; + try + if FStreamedConnected then + SetConnected(true); + except + if csDesigning in Componentstate then + InternalHandleException + else + raise; + end; +end; + +procedure TCustomConnection.Close; +begin + Connected := False; +end; + +destructor TCustomConnection.Destroy; +begin + Connected:=False; + Inherited Destroy; +end; + +procedure TCustomConnection.Open; +begin + Connected := True; +end; + + +procedure SkipQuotesString(var p : pchar; QuoteChar : char; EscapeSlash, EscapeRepeat : Boolean); +var notRepeatEscaped : boolean; +begin + Inc(p); + repeat + notRepeatEscaped := True; + while not (p^ in [#0, QuoteChar]) do + begin + if EscapeSlash and (p^='\') and (p[1] <> #0) then Inc(p,2) // make sure we handle \' and \\ correct + else Inc(p); + end; + if p^=QuoteChar then + begin + Inc(p); // skip final ' + if (p^=QuoteChar) and EscapeRepeat then // Handle escaping by '' + begin + notRepeatEscaped := False; + inc(p); + end + end; + until notRepeatEscaped; +end; + +{ TParams } + +Function TParams.GetItem(Index: Integer): TParam; +begin + Result:=(Inherited GetItem(Index)) as TParam; +end; + +Function TParams.GetParamValue(const ParamName: string): Variant; +begin + Result:=ParamByName(ParamName).Value; +end; + +Procedure TParams.SetItem(Index: Integer; Value: TParam); +begin + Inherited SetItem(Index,Value); +end; + +Procedure TParams.SetParamValue(const ParamName: string; const Value: Variant); +begin + ParamByName(ParamName).Value:=Value; +end; + +Procedure TParams.AssignTo(Dest: TPersistent); +begin + if (Dest is TParams) then + TParams(Dest).Assign(Self) + else + inherited AssignTo(Dest); +end; + +Function TParams.GetDataSet: TDataSet; +begin + If (FOwner is TDataset) Then + Result:=TDataset(FOwner) + else + Result:=Nil; +end; + +Function TParams.GetOwner: TPersistent; +begin + Result:=FOwner; +end; + + +constructor TParams.Create(AOwner: TPersistent); +begin + Inherited Create(TParam); + Fowner:=AOwner; +end; + +constructor TParams.Create; +begin + Create(TPersistent(Nil)); +end; + +Procedure TParams.AddParam(Value: TParam); +begin + Value.Collection:=Self; +end; + +Procedure TParams.AssignValues(Value: TParams); + +Var + I : Integer; + P,PS : TParam; + +begin + For I:=0 to Value.Count-1 do + begin + PS:=Value[i]; + P:=FindParam(PS.Name); + If Assigned(P) then + P.Assign(PS); + end; +end; + +Function TParams.CreateParam(FldType: TFieldType; const ParamName: string; + ParamType: TParamType): TParam; + +begin + Result:=Add as TParam; + Result.Name:=ParamName; + Result.DataType:=FldType; + Result.ParamType:=ParamType; +end; + +Function TParams.FindParam(const Value: string): TParam; + +Var + I : Integer; + +begin + Result:=Nil; + I:=Count-1; + While (Result=Nil) and (I>=0) do + If (CompareText(Value,Items[i].Name)=0) then + Result:=Items[i] + else + Dec(i); +end; + +Procedure TParams.GetParamList(List: TList; const ParamNames: string); + +Var + P: TParam; + N: String; + StrPos: Integer; + +begin + if (ParamNames = '') or (List = nil) then + Exit; + StrPos := 1; + repeat + N := ExtractFieldName(ParamNames, StrPos); + P := ParamByName(N); + List.Add(P); + until StrPos > Length(ParamNames); +end; + +Function TParams.IsEqual(Value: TParams): Boolean; + +Var + I : Integer; + +begin + Result:=(Value.Count=Count); + I:=Count-1; + While Result and (I>=0) do + begin + Result:=Items[I].IsEqual(Value[i]); + Dec(I); + end; +end; + +Function TParams.ParamByName(const Value: string): TParam; +begin + Result:=FindParam(Value); + If (Result=Nil) then + DatabaseErrorFmt(SParameterNotFound,[Value],Dataset); +end; + +Function TParams.ParseSQL(SQL: String; DoCreate: Boolean): String; + +var pb : TParamBinding; + rs : string; + +begin + Result := ParseSQL(SQL,DoCreate,True,True,psInterbase, pb, rs); +end; + +Function TParams.ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle): String; + +var pb : TParamBinding; + rs : string; + +begin + Result := ParseSQL(SQL,DoCreate,EscapeSlash,EscapeRepeat,ParameterStyle,pb, rs); +end; + +Function TParams.ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding): String; + +var rs : string; + +begin + Result := ParseSQL(SQL,DoCreate,EscapeSlash, EscapeRepeat, ParameterStyle,ParamBinding, rs); +end; + +function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : Boolean; + +begin + result := false; + case p^ of + '''': + begin + SkipQuotesString(p,'''',EscapeSlash,EscapeRepeat); // single quote delimited string + Result := True; + end; + '"': + begin + SkipQuotesString(p,'"',EscapeSlash,EscapeRepeat); // double quote delimited string + Result := True; + end; + '-': // possible start of -- comment + begin + Inc(p); + if p^='-' then // -- comment + begin + Result := True; + repeat // skip until at end of line + Inc(p); + until p^ in [#10, #0]; + end; + if p^<>#0 then Inc(p); // newline is part of comment + end; + '/': // possible start of /* */ comment + begin + Inc(p); + if p^='*' then // /* */ comment + begin + Result := True; + repeat + Inc(p); + if p^='*' then // possible end of comment + begin + Inc(p); + if p^='/' then Break; // end of comment + end; + until p^=#0; + if p^='/' then Inc(p); // skip final / + end; + end; + end; {case} +end; + +Function TParams.ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat: Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding; var ReplaceString : string): String; + +type + // used for ParamPart + TStringPart = record + Start,Stop:integer; + end; + +const + ParamAllocStepSize = 8; + +var + IgnorePart:boolean; + p,ParamNameStart,BufStart:PChar; + ParamName:string; + QuestionMarkParamCount,ParameterIndex,NewLength:integer; + ParamCount:integer; // actual number of parameters encountered so far; + // always <= Length(ParamPart) = Length(Parambinding) + // Parambinding will have length ParamCount in the end + ParamPart:array of TStringPart; // describe which parts of buf are parameters + NewQueryLength:integer; + NewQuery:string; + NewQueryIndex,BufIndex,CopyLen,i:integer; // Parambinding will have length ParamCount in the end + b:integer; + tmpParam:TParam; + +begin + if DoCreate then Clear; + // Parse the SQL and build ParamBinding + ParamCount:=0; + paramname:= ''; + paramnamestart:= nil; + NewQueryLength:=Length(SQL); + SetLength(ParamPart,ParamAllocStepSize); + SetLength(Parambinding,ParamAllocStepSize); + QuestionMarkParamCount:=0; // number of ? params found in query so far + + ReplaceString := '$'; + if ParameterStyle = psSimulated then + while pos(ReplaceString,SQL) > 0 do ReplaceString := ReplaceString+'$'; + + p:=PChar(SQL); + BufStart:=p; // used to calculate ParamPart.Start values + repeat + SkipComments(p,EscapeSlash,EscapeRepeat); + case p^ of + ':','?': // parameter + begin + IgnorePart := False; + if p^=':' then + begin // find parameter name + Inc(p); + if p^ in [':','=',' '] then // ignore ::, since some databases uses this as a cast (wb 4813) + begin + IgnorePart := True; + Inc(p); + end + else + begin + if p^='"' then // Check if the parameter-name is between quotes + begin + ParamNameStart:=p; + SkipQuotesString(p,'"',EscapeSlash,EscapeRepeat); + // Do not include the quotes in ParamName, but they must be included + // when the parameter is replaced by some place-holder. + ParamName:=Copy(ParamNameStart+1,1,p-ParamNameStart-2); + end + else + begin + ParamNameStart:=p; + while not (p^ in (SQLDelimiterCharacters+[#0,'=','+','-','*','\','/','[',']','|'])) do + Inc(p); + ParamName:=Copy(ParamNameStart,1,p-ParamNameStart); + end; + end; + end + else + begin + Inc(p); + ParamNameStart:=p; + ParamName:=''; + end; + + if not IgnorePart then + begin + Inc(ParamCount); + if ParamCount>Length(ParamPart) then + begin + NewLength:=Length(ParamPart)+ParamAllocStepSize; + SetLength(ParamPart,NewLength); + SetLength(ParamBinding,NewLength); + end; + + if DoCreate then + begin + // Check if this is the first occurance of the parameter + tmpParam := FindParam(ParamName); + // If so, create the parameter and assign the Parameterindex + if not assigned(tmpParam) then + ParameterIndex := CreateParam(ftUnknown, ParamName, ptInput).Index + else // else only assign the ParameterIndex + ParameterIndex := tmpParam.Index; + end + // else find ParameterIndex + else + begin + if ParamName<>'' then + ParameterIndex:=ParamByName(ParamName).Index + else + begin + ParameterIndex:=QuestionMarkParamCount; + Inc(QuestionMarkParamCount); + end; + end; + if ParameterStyle in [psPostgreSQL,psSimulated] then + begin + i:=ParameterIndex+1; + repeat + inc(NewQueryLength); + i:=i div 10; + until i=0; + end; + + // store ParameterIndex in FParamIndex, ParamPart data + ParamBinding[ParamCount-1]:=ParameterIndex; + ParamPart[ParamCount-1].Start:=ParamNameStart-BufStart; + ParamPart[ParamCount-1].Stop:=p-BufStart+1; + + // update NewQueryLength + Dec(NewQueryLength,p-ParamNameStart); + end; + end; + #0:Break; + else + Inc(p); + end; + until false; + + SetLength(ParamPart,ParamCount); + SetLength(ParamBinding,ParamCount); + + if ParamCount>0 then + begin + // replace :ParamName by ? for interbase and by $x for postgresql/psSimulated + // (using ParamPart array and NewQueryLength) + if (ParameterStyle = psSimulated) and (length(ReplaceString) > 1) then + inc(NewQueryLength,(paramcount)*(length(ReplaceString)-1)); + + SetLength(NewQuery,NewQueryLength); + NewQueryIndex:=1; + BufIndex:=1; + for i:=0 to High(ParamPart) do + begin + CopyLen:=ParamPart[i].Start-BufIndex; + Move(SQL[BufIndex],NewQuery[NewQueryIndex],CopyLen); + Inc(NewQueryIndex,CopyLen); + case ParameterStyle of + psInterbase : begin + NewQuery[NewQueryIndex]:='?'; + Inc(NewQueryIndex); + end; + psPostgreSQL, + psSimulated : begin + ParamName := IntToStr(ParamBinding[i]+1); + for b := 1 to length(ReplaceString) do + begin + NewQuery[NewQueryIndex]:='$'; + Inc(NewQueryIndex); + end; + for b := 1 to length(ParamName) do + begin + NewQuery[NewQueryIndex]:=ParamName[b]; + Inc(NewQueryIndex); + end; + end; + end; + BufIndex:=ParamPart[i].Stop; + end; + CopyLen:=Length(SQL)+1-BufIndex; + if CopyLen > 0 then + Move(SQL[BufIndex],NewQuery[NewQueryIndex],CopyLen); + end + else + NewQuery:=SQL; + + Result := NewQuery; +end; + + +Procedure TParams.RemoveParam(Value: TParam); +begin + Value.Collection:=Nil; +end; + +{ TParam } + +Function TParam.GetDataSet: TDataSet; +begin + If Assigned(Collection) and (Collection is TParams) then + Result:=TParams(Collection).GetDataset + else + Result:=Nil; +end; + +Function TParam.IsParamStored: Boolean; +begin + Result:=Bound; +end; + +function TParam.getasnullmsestring: msestring; +begin + if isnull then begin + result:= ''; + end + else begin + result:= getasunicodestring(); + end; +end; + +procedure TParam.setasnullmsestring(const avalue: msestring); +begin + if avalue = '' then begin + clear; + end + else begin + setasunicodestring(avalue); + end; +end; + +Procedure TParam.AssignParam(Param: TParam); +begin + if Not Assigned(Param) then + begin + Clear; + FDataType:=ftunknown; + FParamType:=ptUnknown; + Name:=''; + Size:=0; + Precision:=0; + NumericScale:=0; + blobkind:= bk_none; + end + else + begin + FDataType:=Param.DataType; + if Param.IsNull then + Clear + else + FValue:=Param.FValue; + FBound:=Param.Bound; + Name:=Param.Name; + if (ParamType=ptUnknown) then + ParamType:=Param.ParamType; + Size:=Param.Size; + Precision:=Param.Precision; + NumericScale:=Param.NumericScale; + blobkind:=Param.blobkind; + end; +end; + +Procedure TParam.AssignTo(Dest: TPersistent); +begin + if (Dest is TField) then + AssignToField(TField(Dest)) + else + inherited AssignTo(Dest); +end; + +Function TParam.GetAsBoolean: Boolean; +begin + If IsNull then + Result:=False + else + Result:=FValue; +end; + +Function TParam.GetAsCurrency: Currency; +begin + If IsNull then + Result:=0.0 + else + Result:=FValue; +end; + +Function TParam.GetAsDateTime: TDateTime; +begin + If IsNull then + Result:=0.0 + else + Result:=FValue; +end; + +Function TParam.GetAsFloat: Double; +begin + If IsNull then + Result:=0.0 + else + Result:=FValue; +end; + +Function TParam.GetAsInteger: Longint; +begin + If IsNull then + Result:=0 + else + Result:=FValue; +end; + +Function TParam.GetAsLargeInt: LargeInt; +begin + If IsNull then + Result:=0 + else + Result:=FValue; +end; + + +Function TParam.GetAsMemo: string; +begin + If IsNull then + Result:='' + else + Result:=FValue; +end; + +Function TParam.GetAsString: string; +var P: Pointer; +begin + If IsNull then + Result:='' + else if (FDataType in [ftBytes, ftVarBytes]) and VarIsArray(FValue) then + begin + SetLength(Result, (VarArrayHighBound(FValue, 1) + 1) div SizeOf(Char)); + P := VarArrayLock(FValue); + try + Move(P^, Result[1], Length(Result) * SizeOf(Char)); + finally + VarArrayUnlock(FValue); + end; + end + else + Result:=FValue; +end; + +function TParam.GetAsWideString: WideString; +begin + if IsNull then + Result := '' + else + Result := FValue; +end; + + +Function TParam.GetAsVariant: Variant; +begin + if IsNull then + Result:=Null + else + Result:=FValue; +end; + +function TParam.GetAsFMTBCD: TBCD; +begin + If IsNull then + Result:= nullbcd + else + Result:=VarToBCD(FValue); +end; + +Function TParam.GetDisplayName: string; +begin + if (FName<>'') then + Result:=FName + else + Result:=inherited GetDisplayName +end; + +Function TParam.GetIsNull: Boolean; +begin + Result:= VarIsNull(FValue) or VarIsClear(FValue); +end; + +Function TParam.IsEqual(AValue: TParam): Boolean; +begin + Result:=(Name=AValue.Name) + and (IsNull=AValue.IsNull) + and (Bound=AValue.Bound) + and (DataType=AValue.DataType) + and (ParamType=AValue.ParamType) + and (VarType(FValue)=VarType(AValue.FValue)) + and (FValue=AValue.FValue); +end; + +Procedure TParam.SetAsBlob(const AValue: TBlobData); +begin + FDataType:=ftBlob; + Value:=AValue; +end; + +Procedure TParam.SetAsBoolean(AValue: Boolean); +begin + FDataType:=ftBoolean; + Value:=AValue; +end; + +Procedure TParam.SetAsCurrency(const AValue: Currency); +begin + FDataType:=ftCurrency; + Value:=Avalue; +end; + +Procedure TParam.SetAsDate(const AValue: TDateTime); +begin + FDataType:=ftDate; + Value:=Avalue; +end; + +Procedure TParam.SetAsDateTime(const AValue: TDateTime); +begin + FDataType:=ftDateTime; + Value:=AValue; +end; + +Procedure TParam.SetAsFloat(const AValue: Double); +begin + FDataType:=ftFloat; + Value:=AValue; +end; + +Procedure TParam.SetAsInteger(AValue: Longint); +begin + FDataType:=ftInteger; + Value:=AValue; +end; + +Procedure TParam.SetAsLargeInt(AValue: LargeInt); +begin + FDataType:=ftLargeint; + Value:=AValue; +end; + +Procedure TParam.SetAsMemo(const AValue: string); +begin + FDataType:=ftMemo; + Value:=AValue; +end; + + +Procedure TParam.SetAsSmallInt(AValue: LongInt); +begin + FDataType:=ftSmallInt; + Value:=AValue; +end; + +Procedure TParam.SetAsString(const AValue: string); +begin + if FDataType <> ftFixedChar then + FDataType := ftString; + Value:=AValue; +end; + +procedure TParam.SetAsWideString(const aValue: WideString); +begin + if FDataType <> ftFixedWideChar then + FDataType := ftWideString; + Value := aValue; +end; + +function TParam.getasunicodestring: unicodestring; +begin + if IsNull then + Result := '' + else + Result := FValue; +end; + +procedure TParam.setasunicodestring(const avalue: unicodestring); +begin + if FDataType <> ftFixedWideChar then + FDataType := ftWideString; + Value := aValue; +end; + +function tparam.getasid: int64; +begin + if isnull then begin + result:= -1; + end + else begin + result:= aslargeint; + end; +end; + +procedure tparam.setasid(const avalue: int64); +begin + if avalue = -1 then begin + clear; + end + else begin + aslargeint:= avalue; + end; +end; + + +Procedure TParam.SetAsTime(const AValue: TDateTime); +begin + FDataType:=ftTime; + Value:=AValue; +end; + +Procedure TParam.SetAsVariant(const AValue: Variant); +begin + FValue:=AValue; + FBound:=not VarIsClear(AValue); + if FDataType = ftUnknown then + case VarType(Value) of + varBoolean : FDataType:=ftBoolean; + varSmallint, + varShortInt, + varByte : FDataType:=ftSmallInt; + varWord, + varInteger : FDataType:=ftInteger; + varCurrency : FDataType:=ftCurrency; + varLongWord, + varSingle, + varDouble : FDataType:=ftFloat; + varDate : FDataType:=ftDateTime; + varString, + varOleStr : if (FDataType<>ftFixedChar) then + FDataType:=ftString; + varInt64 : FDataType:=ftLargeInt; + else + if VarIsFmtBCD(Value) then + FDataType:=ftFmtBCD + else if VarIsArray(AValue) and (VarType(AValue) and varTypeMask = varByte) then + FDataType:=ftBytes + else + FDataType:=ftUnknown; + end; +end; + +Procedure TParam.SetAsWord(AValue: LongInt); +begin + FDataType:=ftWord; + Value:=AValue; +end; + +procedure TParam.SetAsFMTBCD(const AValue: TBCD); +begin + FDataType:=ftFMTBcd; + FValue:=VarFmtBCDCreate(AValue); +end; + +Procedure TParam.SetDataType(AValue: TFieldType); + +Var + VT : Integer; + +begin + FDataType:=AValue; + VT:=FieldTypetoVariantMap[AValue]; + If (VT=varError) then + clear + else + if not VarIsEmpty(FValue) then + begin + Try + FValue:=VarAsType(FValue,VT) + except + Clear; + end { try } + end; +end; + +Procedure TParam.SetText(const AValue: string); +begin + Value:=AValue; +end; + +constructor TParam.Create(ACollection: TCollection); +begin + inherited Create(ACollection); + ParamType:=ptUnknown; + DataType:=ftUnknown; + FValue:=Unassigned; +end; + +constructor TParam.Create(AParams: TParams; AParamType: TParamType); +begin + Create(AParams); + ParamType:=AParamType; +end; + +Procedure TParam.Assign(Source: TPersistent); +begin + if (Source is TParam) then + AssignParam(TParam(Source)) + else if (Source is TField) then + AssignField(TField(Source)) + else if (source is TStrings) then + AsMemo:=TStrings(Source).Text + else + inherited Assign(Source); +end; + +Procedure TParam.AssignField(Field: TField); +begin + if Assigned(Field) then + begin + // Need TField.Value + AssignFieldValue(Field,Field.Value); + Name:=Field.FieldName; + end + else + begin + Clear; + Name:=''; + end +end; + +procedure TParam.AssignToField(Field : TField); + +begin + if Assigned(Field) then + case FDataType of + ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + // Need TField.AsSmallInt + ftSmallint : Field.AsInteger:=AsSmallInt; + // Need TField.AsWord + ftWord : Field.AsInteger:=AsWord; + ftInteger, + ftAutoInc : Field.AsInteger:=AsInteger; + ftCurrency : Field.AsCurrency:=AsCurrency; + ftFloat : Field.AsFloat:=AsFloat; + ftBoolean : Field.AsBoolean:=AsBoolean; + ftBlob, + ftGraphic..ftTypedBinary, + ftOraBlob, + ftOraClob, + ftString, + ftMemo, + ftAdt, + ftFixedChar: Field.AsString:=AsString; + ftTime, + ftDate, + ftDateTime : Field.AsDateTime:=AsDateTime; + ftBytes, + ftVarBytes : Field.AsVariant:=Value; + ftFmtBCD : Field.AsBCD:=AsFMTBCD; + else + If not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then + DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet); + end; +end; + +procedure TParam.AssignFromField(Field : TField); + +begin + if Assigned(Field) then + begin + FDataType:=Field.DataType; + case Field.DataType of + ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + // Need TField.AsSmallInt + ftSmallint : AsSmallint:=Field.AsInteger; + // Need TField.AsWord + ftWord : AsWord:=Field.AsInteger; + ftInteger, + ftAutoInc : AsInteger:=Field.AsInteger; + ftBCD, + ftCurrency : AsCurrency:=Field.AsCurrency; + ftFloat : AsFloat:=Field.AsFloat; + ftBoolean : AsBoolean:=Field.AsBoolean; + ftBlob, + ftGraphic..ftTypedBinary, + ftOraBlob, + ftOraClob, + ftString, + ftMemo, + ftAdt, + ftFixedChar: AsString:=Field.AsString; + ftTime, + ftDate, + ftDateTime : AsDateTime:=Field.AsDateTime; + ftBytes, + ftVarBytes : Value:=Field.AsVariant; + ftFmtBCD : AsFMTBCD:=Field.AsBCD; + else + If not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then + DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet); + end; + end; +end; + +Procedure TParam.AssignFieldValue(Field: TField; const AValue: Variant); + +begin + If Assigned(Field) then + begin + + if (Field.DataType = ftString) and TStringField(Field).FixedChar then + FDataType := ftFixedChar + else if (Field.DataType = ftMemo) and (Field.Size > 255) then + FDataType := ftString + else if (Field.DataType = ftWideString) and TWideStringField(Field).FixedChar then + FDataType := ftFixedWideChar + else if (Field.DataType = ftWideMemo) and (Field.Size > 255) then + FDataType := ftWideString + else + FDataType := Field.DataType; + + if VarIsNull(AValue) then + Clear + else + Value:=AValue; + + Size:=Field.DataSize; + FBound:=True; + + end; +end; + +Procedure TParam.Clear; +begin + FValue:=UnAssigned; + fblobkind:= bk_none; +end; + +Procedure TParam.GetData(Buffer: Pointer); + +Var + P : Pointer; + S : String; + ws : WideString; + l : Integer; +begin + case FDataType of + ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + ftSmallint : PSmallint(Buffer)^:=AsSmallInt; + ftWord : PWord(Buffer)^:=AsWord; + ftInteger, + ftAutoInc : PInteger(Buffer)^:=AsInteger; + ftCurrency : PDouble(Buffer)^:=AsCurrency; + ftFloat : PDouble(Buffer)^:=AsFloat; + ftBoolean : PWordBool(Buffer)^:=AsBoolean; + ftString, + ftMemo, + ftAdt, + ftFixedChar: + begin + S:=AsString; + StrMove(PChar(Buffer),Pchar(S),Length(S)+1); + end; + ftWideString, + ftWideMemo: begin + ws := GetAsWideString; + l := Length(ws); + if l > 0 then + Move(ws[1], Buffer, Succ(l)*2) + else + PWideChar(Buffer)^ := #0 + end; + ftTime : PInteger(Buffer)^:=DateTimeToTimeStamp(AsTime).Time; + ftDate : PInteger(Buffer)^:=DateTimeToTimeStamp(AsTime).Date; + ftDateTime : PDouble(Buffer)^:=TimeStampToMSecs(DateTimeToTimeStamp(AsDateTime)); + ftBlob, + ftGraphic..ftTypedBinary, + ftOraBlob, + ftOraClob : + begin + S:=GetAsString; + Move(PChar(S)^, Buffer^, Length(S)); + end; + ftBytes, ftVarBytes: + begin + if VarIsArray(FValue) then + begin + P:=VarArrayLock(FValue); + try + Move(P^, Buffer^, VarArrayHighBound(FValue, 1) + 1); + finally + VarArrayUnlock(FValue); + end; + end; + end; + ftFmtBCD : PBCD(Buffer)^:=AsFMTBCD; + else + If not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then + DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet); + end; +end; + +Function TParam.GetDataSize: Integer; +begin + Result:=0; + case DataType of + ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + ftBoolean : Result:=SizeOf(WordBool); + ftInteger, + ftAutoInc : Result:=SizeOf(Integer); + ftSmallint : Result:=SizeOf(SmallInt); + ftWord : Result:=SizeOf(Word); + ftTime, + ftDate : Result:=SizeOf(Integer); + ftDateTime, + ftCurrency, + ftFloat : Result:=SizeOf(Double); + ftString, + ftFixedChar, + ftMemo, + ftADT : Result:=Length(AsString)+1; + ftBytes, + ftVarBytes : if VarIsArray(FValue) then + Result:=VarArrayHighBound(FValue,1)+1 + else + Result:=0; + ftBlob, + ftGraphic..ftTypedBinary, + ftOraClob, + ftOraBlob : Result:=Length(AsString); + ftArray, + ftDataSet, + ftReference, + ftCursor : Result:=0; + ftFmtBCD : Result:=SizeOf(TBCD); + else + DatabaseErrorFmt(SBadParamFieldType,[Name],DataSet); + end; + + +end; + +Procedure TParam.LoadFromFile(const FileName: string; BlobType: TBlobType); + +Var + S : TFileStream; + +begin + S:=TFileStream.Create(FileName,fmOpenRead); + Try + LoadFromStream(S,BlobType); + Finally + FreeAndNil(S); + end; +end; + +Procedure TParam.LoadFromStream(Stream: TStream; BlobType: TBlobType); + +Var + Temp : String; + +begin + FDataType:=BlobType; + With Stream do + begin + Position:=0; + SetLength(Temp,Size); + ReadBuffer(Pointer(Temp)^,Size); + FValue:=Temp; + end; +end; + +Procedure TParam.SetBlobData(Buffer: Pointer; ASize: Integer); + +Var + Temp : String; + +begin + SetLength(Temp,ASize); + Move(Buffer^,Temp,ASize); + AsBlob:=Temp; +end; + +Procedure TParam.SetData(Buffer: Pointer); + + Function FromTimeStamp(T,D : Integer) : TDateTime; + + Var TS : TTimeStamp; + + begin + TS.Time:=T; + TS.Date:=D; + Result:=TimeStampToDateTime(TS); + end; + +begin + case FDataType of + ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + ftSmallint : AsSmallInt:=PSmallint(Buffer)^; + ftWord : AsWord:=PWord(Buffer)^; + ftInteger, + ftAutoInc : AsInteger:=PInteger(Buffer)^; + ftCurrency : AsCurrency:= PDouble(Buffer)^; + ftFloat : AsFloat:=PDouble(Buffer)^; + ftBoolean : AsBoolean:=PWordBool(Buffer)^; + ftString, + ftFixedChar: AsString:=StrPas(Buffer); + ftMemo : AsMemo:=StrPas(Buffer); + ftTime : AsTime:=FromTimeStamp(PInteger(Buffer)^,DateDelta); + ftDate : Asdate:=FromTimeStamp(0,PInteger(Buffer)^); + ftDateTime : AsDateTime:=TimeStampToDateTime(MSecsToTimeStamp(trunc(PDouble(Buffer)^))); + ftCursor : FValue:=0; + ftBlob, + ftGraphic..ftTypedBinary, + ftOraBlob, + ftOraClob : SetBlobData(Buffer, StrLen(PChar(Buffer))); + ftFmtBCD : AsFMTBCD:=PBCD(Buffer)^; + else + DatabaseErrorFmt(SBadParamFieldType,[Name],DataSet); + end; +end; + +Procedure TParams.CopyParamValuesFromDataset(ADataset : TDataset; CopyBound : Boolean); + +Var + I : Integer; + P : TParam; + F : TField; + +begin + If (ADataSet<>Nil) then + For I:=0 to Count-1 do + begin + P:=Items[i]; + if CopyBound or (not P.Bound) then + begin + F:=ADataset.FieldByName(P.Name); + P.AssignField(F); + If Not CopyBound then + P.Bound:=False; + end; + end; +end; + +{ EDatabaseError } + +constructor EDatabaseError.create(const msg: string; const comp: tcomponent); +begin + if (comp <> nil) and (comp.name <> '') then begin + createfmt('%s : %s',[comp.Name,msg]); + end + else begin + inherited create(msg); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/mdbf.pas b/mseide-msegui/lib/common/fpccompatibility/mdbf.pas new file mode 100644 index 0000000..162455a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mdbf.pas @@ -0,0 +1,3065 @@ +unit mdbf; + +// Modified 2013 by Martin Schreiber + +{ design info in dbf_reg.pas } + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$I dbf_common.inc} + +uses + classes,mclasses, + mdb, + dbf_common, + dbf_dbffile, + dbf_parser, + mdbf_prsdef, + dbf_cursor, + dbf_fields, + dbf_pgfile, + dbf_idxfile; +// If you got a compilation error here or asking for dsgnintf.pas, then just add +// this file in your project: +// dsgnintf.pas in 'C: \Program Files\Borland\Delphi5\Source\Toolsapi\dsgnintf.pas' + +type + +//==================================================================== + pBookmarkData = ^TBookmarkData; + TBookmarkData = record + PhysicalRecNo: Integer; + end; + + pDbfRecord = ^TDbfRecordHeader; + TDbfRecordHeader = record + BookmarkData: TBookmarkData; + BookmarkFlag: TBookmarkFlag; + SequentialRecNo: Integer; + DeletedFlag: Char; + end; +//==================================================================== + TDbf = class; +//==================================================================== + TDbfStorage = (stoMemory,stoFile); + TDbfOpenMode = (omNormal,omAutoCreate,omTemporary); + TDbfLanguageAction = (laReadOnly, laForceOEM, laForceANSI, laDefault); + TDbfTranslationMode = (tmNoneAvailable, tmNoneNeeded, tmSimple, tmAdvanced); + TDbfFileName = (dfDbf, dfMemo, dfIndex); +//==================================================================== + TDbfFileNames = set of TDbfFileName; +//==================================================================== + TCompareRecordEvent = procedure(Dbf: TDbf; var Accept: Boolean) of object; + TTranslateEvent = function(Dbf: TDbf; Src, Dest: PChar; ToOem: Boolean): Integer of object; + TLanguageWarningEvent = procedure(Dbf: TDbf; var Action: TDbfLanguageAction) of object; + TConvertFieldEvent = procedure(Dbf: TDbf; DstField, SrcField: TField) of object; + TBeforeAutoCreateEvent = procedure(Dbf: TDbf; var DoCreate: Boolean) of object; +//==================================================================== + // TDbfBlobStream keeps a reference count to number of references to + // this instance. Only if FRefCount reaches zero, then the object will be + // destructed. AddReference `clones' a reference. + // This allows the VCL to use Free on the object to `free' that + // particular reference. + + TDbfBlobStream = class(TMemoryStream) + private + FBlobField: TBlobField; + FMode: TBlobStreamMode; + FDirty: boolean; { has possibly modified data, needs to be written } + FMemoRecNo: Integer; + { -1 : invalid contents } + { 0 : clear, no contents } + { >0 : data from page x } + FReadSize: Integer; + FRefCount: Integer; + + function GetTransliterate: Boolean; + procedure Translate(ToOem: Boolean); + procedure SetMode(NewMode: TBlobStreamMode); + public + constructor Create(FieldVal: TField); + destructor Destroy; override; + + function AddReference: TDbfBlobStream; + procedure FreeInstance; override; + + procedure Cancel; + procedure Commit; + + property Dirty: boolean read FDirty; + property Transliterate: Boolean read GetTransliterate; + property MemoRecNo: Integer read FMemoRecNo write FMemoRecNo; + property ReadSize: Integer read FReadSize write FReadSize; + property Mode: TBlobStreamMode write SetMode; + property BlobField: TBlobField read FBlobField; + end; +//==================================================================== + TDbfIndexDefs = class(TCollection) + public + FOwner: TDbf; + private + function GetItem(N: Integer): TDbfIndexDef; + procedure SetItem(N: Integer; Value: TDbfIndexDef); + protected + function GetOwner: TPersistent; override; + public + constructor Create(AOwner: TDbf); + + function Add: TDbfIndexDef; + function GetIndexByName(const Name: string): TDbfIndexDef; + function GetIndexByField(const Name: string): TDbfIndexDef; + procedure Update; {$ifdef SUPPORT_REINTRODUCE} reintroduce; {$endif} + + property Items[N: Integer]: TDbfIndexDef read GetItem write SetItem; default; + end; +//==================================================================== + TDbfMasterLink = class(TDataLink) + private + FDetailDataSet: TDbf; + FParser: TDbfParser; + FFieldNames: string; + FValidExpression: Boolean; + FOnMasterChange: TNotifyEvent; + FOnMasterDisable: TNotifyEvent; + + function GetFieldsVal: TRecordBuffer; + + procedure SetFieldNames(const Value: string); + protected + procedure ActiveChanged; override; + procedure CheckBrowseMode; override; + procedure LayoutChanged; override; + procedure RecordChanged(Field: TField); override; + + public + constructor Create(ADataSet: TDbf); + destructor Destroy; override; + + property FieldNames: string read FFieldNames write SetFieldNames; + property ValidExpression: Boolean read FValidExpression write FValidExpression; + property FieldsVal: TRecordBuffer read GetFieldsVal; + property Parser: TDbfParser read FParser; + + property OnMasterChange: TNotifyEvent read FOnMasterChange write FOnMasterChange; + property OnMasterDisable: TNotifyEvent read FOnMasterDisable write FOnMasterDisable; + end; +//==================================================================== + PDbfBlobList = ^TDbfBlobList; + TDbfBlobList = array[0..MaxListSize-1] of TDbfBlobStream; +//==================================================================== + TDbf = class(TDataSet) + private + FDbfFile: TDbfFile; + FCursor: TVirtualCursor; + FOpenMode: TDbfOpenMode; + FStorage: TDbfStorage; + FMasterLink: TDbfMasterLink; + FParser: TDbfParser; + FBlobStreams: PDbfBlobList; + FUserStream: TStream; // user stream to open + FTableName: string; // table path and file name + FRelativePath: string; + FAbsolutePath: string; + FIndexName: string; + FReadOnly: Boolean; + FFilterBuffer: TRecordBuffer; + FTempBuffer: TRecordBuffer; + FEditingRecNo: Integer; +{$ifdef SUPPORT_VARIANTS} + FLocateRecNo: Integer; +{$endif} + FLanguageID: Byte; + FTableLevel: Integer; + FExclusive: Boolean; + FShowDeleted: Boolean; + FPosting: Boolean; + FDisableResyncOnPost: Boolean; + FTempExclusive: Boolean; + FInCopyFrom: Boolean; + FStoreDefs: Boolean; + FCopyDateTimeAsString: Boolean; + FFindRecordFilter: Boolean; + FIndexFile: TIndexFile; + FDateTimeHandling: TDateTimeHandling; + FTranslationMode: TDbfTranslationMode; + FIndexDefs: TDbfIndexDefs; + FBeforeAutoCreate: TBeforeAutoCreateEvent; + FOnTranslate: TTranslateEvent; + FOnLanguageWarning: TLanguageWarningEvent; + FOnLocaleError: TDbfLocaleErrorEvent; + FOnIndexMissing: TDbfIndexMissingEvent; + FOnCompareRecord: TNotifyEvent; + FOnCopyDateTimeAsString: TConvertFieldEvent; + + function GetIndexName: string; + function GetVersion: string; + function GetPhysicalRecNo: Integer; + function GetLanguageStr: string; + function GetCodePage: Cardinal; + function GetExactRecordCount: Integer; + function GetPhysicalRecordCount: Integer; + function GetKeySize: Integer; + function GetMasterFields: string; + function FieldDefsStored: Boolean; + + procedure SetIndexName(AIndexName: string); + procedure SetDbfIndexDefs(const Value: TDbfIndexDefs); + procedure SetFilePath(const Value: string); + procedure SetTableName(const S: string); + procedure SetVersion(const S: string); + procedure SetLanguageID(NewID: Byte); + procedure SetDataSource(Value: TDataSource); + procedure SetMasterFields(const Value: string); + procedure SetTableLevel(const NewLevel: Integer); + procedure SetPhysicalRecNo(const NewRecNo: Integer); + + procedure MasterChanged(Sender: TObject); + procedure MasterDisabled(Sender: TObject); + procedure DetermineTranslationMode; + procedure UpdateRange; + procedure SetShowDeleted(Value: Boolean); + procedure GetFieldDefsFromDbfFieldDefs; + procedure InitDbfFile(FileOpenMode: TPagedFileMode); + function ParseIndexName(const AIndexName: string): string; + procedure ParseFilter(const AFilter: string); + function GetDbfFieldDefs: TDbfFieldDefs; + function ReadCurrentRecord(Buffer: TRecordBuffer; var Acceptable: Boolean): TGetResult; + function SearchKeyBuffer(Buffer: PChar; SearchType: TSearchKeyType): Boolean; + procedure SetRangeBuffer(LowRange: PChar; HighRange: PChar); + + protected + { abstract methods } + function AllocRecordBuffer: TRecordBuffer; override; {virtual abstract} + procedure ClearCalcFields(Buffer: TRecordBuffer); override; + procedure FreeRecordBuffer(var Buffer: TRecordBuffer); override; {virtual abstract} + procedure GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); override; {virtual abstract} + function GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; override; {virtual abstract} + function GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override; {virtual abstract} + function GetRecordSize: Word; override; {virtual abstract} + procedure InternalAddRecord(Buffer: Pointer; AAppend: Boolean); override; {virtual abstract} + procedure InternalClose; override; {virtual abstract} + procedure InternalDelete; override; {virtual abstract} + procedure InternalFirst; override; {virtual abstract} + procedure InternalGotoBookmark(ABookmark: Pointer); override; {virtual abstract} + procedure InternalHandleException; override; {virtual abstract} + procedure InternalInitFieldDefs; override; {virtual abstract} + procedure InternalInitRecord(Buffer: TRecordBuffer); override; {virtual abstract} + procedure InternalLast; override; {virtual abstract} + procedure InternalOpen; override; {virtual abstract} + procedure InternalEdit; override; {virtual} + procedure InternalCancel; override; {virtual} +{$ifndef FPC} +{$ifndef DELPHI_3} + procedure InternalInsert; override; {virtual} +{$endif} +{$endif} + procedure InternalPost; override; {virtual abstract} + procedure InternalSetToRecord(Buffer: TRecordBuffer); override; {virtual abstract} + procedure InitFieldDefs; override; + function IsCursorOpen: Boolean; override; {virtual abstract} + procedure SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); override; {virtual abstract} + procedure SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); override; {virtual abstract} + + { virtual methods (mostly optionnal) } + function GetDataSource: TDataSource; {$ifndef VER1_0}override;{$endif} + function GetRecordCount: Integer; override; {virtual} + function GetRecNo: Integer; override; {virtual} + function GetCanModify: Boolean; override; {virtual} + procedure SetRecNo(Value: Integer); override; {virual} + procedure SetFiltered(Value: Boolean); override; {virtual;} + procedure SetFilterText(const Value: String); override; {virtual;} +{$ifdef SUPPORT_DEFCHANGED} + procedure DefChanged(Sender: TObject); override; +{$endif} + function FindRecord(Restart, GoForward: Boolean): Boolean; override; + + function GetIndexFieldNames: string; {virtual;} + procedure SetIndexFieldNames(const Value: string); {virtual;} + +{$ifdef SUPPORT_VARIANTS} + function LocateRecordLinear(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean; + function LocateRecordIndex(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean; + function LocateRecord(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean; +{$endif} + + procedure DoFilterRecord(var Acceptable: Boolean); + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + { abstract methods } + procedure SetFieldData(Field: TField; Buffer: Pointer); + {$ifdef SUPPORT_OVERLOAD} overload; {$endif} override; {virtual abstract} + function GetFieldData(Field: TField; Buffer: Pointer): Boolean; + {$ifdef SUPPORT_OVERLOAD} overload; {$endif} override; {virtual abstract} + { virtual methods (mostly optionnal) } + procedure Resync(Mode: TResyncMode); override; + function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override; {virtual} +{$ifdef SUPPORT_NEW_TRANSLATE} + function Translate(Src, Dest: PChar; ToOem: Boolean): Integer; override; {virtual} +{$else} + procedure Translate(Src, Dest: PChar; ToOem: Boolean); override; {virtual} +{$endif} + +{$ifdef SUPPORT_OVERLOAD} + function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; + {$ifdef SUPPORT_BACKWARD_FIELDDATA} overload; override; {$else} reintroduce; overload; {$endif} + procedure SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean); + {$ifdef SUPPORT_BACKWARD_FIELDDATA} overload; override; {$else} reintroduce; overload; {$endif} +{$endif} + + function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer; override; + procedure CheckDbfFieldDefs(ADbfFieldDefs: TDbfFieldDefs); + +{$ifdef VER1_0} + procedure DataEvent(Event: TDataEvent; Info: Longint); override; +{$endif} + + // my own methods and properties + // most look like ttable functions but they are not tdataset related + // I (try to) use the same syntax to facilitate the conversion between bde and TDbf + + // index support (use same syntax as ttable but is not related) +{$ifdef SUPPORT_DEFAULT_PARAMS} + procedure AddIndex(const AIndexName, AFields: String; Options: TIndexOptions; const DescFields: String=''); +{$else} + procedure AddIndex(const AIndexName, AFields: String; Options: TIndexOptions); +{$endif} + procedure RegenerateIndexes; + + procedure CancelRange; + procedure CheckMasterRange; +{$ifdef SUPPORT_VARIANTS} + function SearchKey(Key: Variant; SearchType: TSearchKeyType; KeyIsANSI: boolean + {$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif}): Boolean; + procedure SetRange(LowRange: Variant; HighRange: Variant; KeyIsANSI: boolean + {$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif}); +{$endif} + function PrepareKey(Buffer: Pointer; BufferType: TExpressionType): PChar; + function SearchKeyPChar(Key: PChar; SearchType: TSearchKeyType; KeyIsANSI: boolean + {$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif}): Boolean; + procedure SetRangePChar(LowRange: PChar; HighRange: PChar; KeyIsANSI: boolean + {$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif}); + function GetCurrentBuffer: TRecordBuffer; + procedure ExtractKey(KeyBuffer: PChar); + procedure UpdateIndexDefs; override; + procedure GetFileNames(Strings: TStrings; Files: TDbfFileNames); {$ifdef SUPPORT_DEFAULT_PARAMS} overload; {$endif} +{$ifdef SUPPORT_DEFAULT_PARAMS} + function GetFileNames(Files: TDbfFileNames = [dfDbf] ): string; overload; +{$else} + function GetFileNamesString(Files: TDbfFileNames (* = [dfDbf] *) ): string; +{$endif} + procedure GetIndexNames(Strings: TStrings); + procedure GetAllIndexFiles(Strings: TStrings); + + procedure TryExclusive; + procedure EndExclusive; + function LockTable(const Wait: Boolean): Boolean; + procedure UnlockTable; + procedure OpenIndexFile(IndexFile: string); + procedure DeleteIndex(const AIndexName: string); + procedure CloseIndexFile(const AIndexName: string); + procedure RepageIndexFile(const AIndexFile: string); + procedure CompactIndexFile(const AIndexFile: string); + +{$ifdef SUPPORT_VARIANTS} + function Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant; override; + function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; override; +{$endif} + + function IsDeleted: Boolean; + procedure Undelete; + + procedure CreateTable; + procedure CreateTableEx(ADbfFieldDefs: TDbfFieldDefs); + procedure CopyFrom(DataSet: TDataSet; FileName: string; DateTimeAsString: Boolean; Level: Integer); + procedure RestructureTable(ADbfFieldDefs: TDbfFieldDefs; Pack: Boolean); + procedure PackTable; + procedure EmptyTable; + procedure Zap; + +{$ifndef SUPPORT_INITDEFSFROMFIELDS} + procedure InitFieldDefsFromFields; +{$endif} + + property AbsolutePath: string read FAbsolutePath; + property DbfFieldDefs: TDbfFieldDefs read GetDbfFieldDefs; + property PhysicalRecNo: Integer read GetPhysicalRecNo write SetPhysicalRecNo; + property LanguageID: Byte read FLanguageID write SetLanguageID; + property LanguageStr: String read GetLanguageStr; + property CodePage: Cardinal read GetCodePage; + property ExactRecordCount: Integer read GetExactRecordCount; + property PhysicalRecordCount: Integer read GetPhysicalRecordCount; + property KeySize: Integer read GetKeySize; + property DbfFile: TDbfFile read FDbfFile; + property UserStream: TStream read FUserStream write FUserStream; + property DisableResyncOnPost: Boolean read FDisableResyncOnPost write FDisableResyncOnPost; + published + property DateTimeHandling: TDateTimeHandling + read FDateTimeHandling write FDateTimeHandling default dtBDETimeStamp; + property Exclusive: Boolean read FExclusive write FExclusive default false; + property FilePath: string read FRelativePath write SetFilePath; + property FilePathFull: string read FAbsolutePath write SetFilePath stored false; + property Indexes: TDbfIndexDefs read FIndexDefs write SetDbfIndexDefs stored false; + property IndexDefs: TDbfIndexDefs read FIndexDefs write SetDbfIndexDefs; + property IndexFieldNames: string read GetIndexFieldNames write SetIndexFieldNames stored false; + property IndexName: string read GetIndexName write SetIndexName; + property MasterFields: string read GetMasterFields write SetMasterFields; + property MasterSource: TDataSource read GetDataSource write SetDataSource; + property OpenMode: TDbfOpenMode read FOpenMode write FOpenMode default omNormal; + property ReadOnly: Boolean read FReadOnly write FReadonly default false; + property ShowDeleted: Boolean read FShowDeleted write SetShowDeleted default false; + property Storage: TDbfStorage read FStorage write FStorage default stoFile; + property StoreDefs: Boolean read FStoreDefs write FStoreDefs default False; + property TableName: string read FTableName write SetTableName; + property TableLevel: Integer read FTableLevel write SetTableLevel; + property Version: string read GetVersion write SetVersion stored false; + property BeforeAutoCreate: TBeforeAutoCreateEvent read FBeforeAutoCreate write FBeforeAutoCreate; + property OnCompareRecord: TNotifyEvent read FOnCompareRecord write FOnCompareRecord; + property OnLanguageWarning: TLanguageWarningEvent read FOnLanguageWarning write FOnLanguageWarning; + property OnLocaleError: TDbfLocaleErrorEvent read FOnLocaleError write FOnLocaleError; + property OnIndexMissing: TDbfIndexMissingEvent read FOnIndexMissing write FOnIndexMissing; + property OnCopyDateTimeAsString: TConvertFieldEvent read FOnCopyDateTimeAsString write FOnCopyDateTimeAsString; + property OnTranslate: TTranslateEvent read FOnTranslate write FOnTranslate; + + // redeclared data set properties + property Active; + property FieldDefs stored FieldDefsStored; + property Filter; + property Filtered; + property FilterOptions; + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; +{$ifdef SUPPORT_REFRESHEVENTS} + property BeforeRefresh; + property AfterRefresh; +{$endif} + property BeforeScroll; + property AfterScroll; + property OnCalcFields; + property OnDeleteError; + property OnEditError; + property OnFilterRecord; + property OnNewRecord; + property OnPostError; + end; + + TDbf_GetBasePathFunction = function: string; + +var + DbfBasePath: TDbf_GetBasePathFunction; + +implementation + +uses + SysUtils, +{$ifndef FPC} + DBConsts, +{$endif} +{$ifdef WINDOWS} + Windows, +{$else} +{$ifdef KYLIX} + Libc, +{$endif} + Types, + dbf_wtil, +{$endif} +{$ifdef SUPPORT_SEPARATE_VARIANTS_UNIT} + Variants, +{$endif} + dbf_idxcur, + dbf_memo, + dbf_str; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifdef FPC} +const + // TODO: move these to DBConsts + SNotEditing = 'Dataset not in edit or insert mode'; + SCircularDataLink = 'Circular datalinks are not allowed'; +{$endif} + +function TableLevelToDbfVersion(TableLevel: integer): TXBaseVersion; +begin + case TableLevel of + 3: Result := xBaseIII; + 7: Result := xBaseVII; + TDBF_TABLELEVEL_FOXPRO: Result := xFoxPro; + else + {4:} Result := xBaseIV; + end; +end; + +//========================================================== +//============ TDbfBlobStream +//========================================================== +constructor TDbfBlobStream.Create(FieldVal: TField); +begin + FBlobField := FieldVal as TBlobField; + FReadSize := 0; + FMemoRecNo := 0; + FRefCount := 1; + FDirty := false; +end; + +destructor TDbfBlobStream.Destroy; +begin + // only continue destroy if all references released + if FRefCount = 1 then + begin + // this is the last reference + inherited + end else begin + // fire event when dirty, and the last "user" is freeing it's reference + // tdbf always has the last reference + if FDirty and (FRefCount = 2) then + begin + // a second referer to instance has changed the data, remember modified +// TDbf(FBlobField.DataSet).SetModified(true); + // is following better? seems to provide notification for user (from VCL) + if not (FBlobField.DataSet.State in [dsCalcFields, dsFilter, dsNewValue]) then + TDbf(FBlobField.DataSet).DataEvent(deFieldChange, PtrInt(FBlobField)); + end; + end; + Dec(FRefCount); +end; + +procedure TDbfBlobStream.FreeInstance; +begin + // only continue freeing if all references released + if FRefCount = 0 then + inherited; +end; + +procedure TDbfBlobStream.SetMode(NewMode: TBlobStreamMode); +begin + FMode := NewMode; + FDirty := FDirty or (NewMode = bmWrite) or (NewMode = bmReadWrite); +end; + +procedure TDbfBlobStream.Cancel; +begin + FDirty := false; + FMemoRecNo := -1; +end; + +procedure TDbfBlobStream.Commit; +var + Dbf: TDbf; +begin + if FDirty then + begin + Size := Position; // Strange but it leave tailing trash bytes if I do not write that. + Dbf := TDbf(FBlobField.DataSet); + Translate(true); + Dbf.FDbfFile.MemoFile.WriteMemo(FMemoRecNo, FReadSize, Self); + Dbf.FDbfFile.SetFieldData(FBlobField.FieldNo-1, ftInteger, @FMemoRecNo, + @pDbfRecord(TDbf(FBlobField.DataSet).ActiveBuffer)^.DeletedFlag, false); + FDirty := false; + end; +end; + +function TDbfBlobStream.AddReference: TDbfBlobStream; +begin + Inc(FRefCount); + Result := Self; +end; + +function TDbfBlobStream.GetTransliterate: Boolean; +begin + Result := FBlobField.Transliterate; +end; + +procedure TDbfBlobStream.Translate(ToOem: Boolean); +var + bytesToDo, numBytes: Integer; + bufPos: PChar; + saveChar: Char; +begin + if (Transliterate) and (Size > 0) then + begin + // get number of bytes to be translated + bytesToDo := Size; + // make space for final null-terminator + Size := Size + 1; + bufPos := Memory; + repeat + // process blocks of 512 bytes + numBytes := bytesToDo; + if numBytes > 512 then + numBytes := 512; + // null-terminate memory + saveChar := bufPos[numBytes]; + bufPos[numBytes] := #0; + // translate memory + TDbf(FBlobField.DataSet).Translate(bufPos, bufPos, ToOem); + // restore char + bufPos[numBytes] := saveChar; + // numBytes bytes translated + Dec(bytesToDo, numBytes); + Inc(bufPos, numBytes); + until bytesToDo = 0; + // cut ending null-terminator + Size := Size - 1; + end; +end; + +//==================================================================== +// TDbf = TDataset Descendant. +//==================================================================== +constructor TDbf.Create(AOwner: TComponent); {override;} +begin + inherited; + + if DbfGlobals = nil then + DbfGlobals := TDbfGlobals.Create; + + BookmarkSize := sizeof(TBookmarkData); + FIndexDefs := TDbfIndexDefs.Create(Self); + FMasterLink := TDbfMasterLink.Create(Self); + FMasterLink.OnMasterChange := MasterChanged; + FMasterLink.OnMasterDisable := MasterDisabled; + FDateTimeHandling := dtBDETimeStamp; + FStorage := stoFile; + FOpenMode := omNormal; + FParser := nil; + FPosting := false; + FReadOnly := false; + FExclusive := false; + FDisableResyncOnPost := false; + FTempExclusive := false; + FCopyDateTimeAsString := false; + FInCopyFrom := false; + FFindRecordFilter := false; + FEditingRecNo := -1; + FTableLevel := 4; + FIndexName := EmptyStr; + FilePath := EmptyStr; + FTempBuffer := nil; + FFilterBuffer := nil; + FIndexFile := nil; + FOnTranslate := nil; + FOnCopyDateTimeAsString := nil; +end; + +destructor TDbf.Destroy; {override;} +var + I: Integer; +begin + inherited Destroy; + + if FIndexDefs <> nil then + begin + for I := FIndexDefs.Count - 1 downto 0 do + TDbfIndexDef(FIndexDefs.Items[I]).Free; + FIndexDefs.Free; + end; + FMasterLink.Free; +end; + +function TDbf.AllocRecordBuffer: TRecordBuffer; {override virtual abstract from TDataset} +begin + GetMem(Result, SizeOf(TDbfRecordHeader)+FDbfFile.RecordSize+CalcFieldsSize+1); +end; + +procedure TDbf.FreeRecordBuffer(var Buffer: TRecordBuffer); {override virtual abstract from TDataset} +begin + FreeMemAndNil(Pointer(Buffer)); +end; + +procedure TDbf.GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); {override virtual abstract from TDataset} +begin + pBookmarkData(Data)^ := pDbfRecord(Buffer)^.BookmarkData; +end; + +function TDbf.GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; {override virtual abstract from TDataset} +begin + Result := pDbfRecord(Buffer)^.BookmarkFlag; +end; + +function TDbf.GetCurrentBuffer: TRecordBuffer; +begin + case State of + dsFilter: Result := FFilterBuffer; + dsCalcFields: Result := CalcBuffer; +// dsSetKey: Result := FKeyBuffer; // TO BE Implemented + else + if IsEmpty then + begin + Result := nil; + end else begin + Result := ActiveBuffer; + end; + end; + if Result <> nil then + Result := @PDbfRecord(Result)^.DeletedFlag; +end; + +// we don't want converted data formats, we want native :-) +// it makes coding easier in TDbfFile.GetFieldData +// ftCurrency: +// Delphi 3,4: BCD array +// ftBCD: +// ftDateTime is more difficult though + +function TDbf.GetFieldData(Field: TField; Buffer: Pointer): Boolean; {override virtual abstract from TDataset} +{$ifdef SUPPORT_OVERLOAD} +begin + { calling through 'old' delphi 3 interface, use compatible/'native' format } + Result := GetFieldData(Field, Buffer, true); +end; + +function TDbf.GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; {overload; override;} +{$else} +const + { no overload => delphi 3 => use compatible/'native' format } + NativeFormat = true; +{$endif} +var + Src: TRecordBuffer; +begin + Src := GetCurrentBuffer; + if Src = nil then + begin + Result := false; + exit; + end; + + if Field.FieldNo>0 then + begin + Result := FDbfFile.GetFieldData(Field.FieldNo-1, Field.DataType, Src, Buffer, NativeFormat); + end else begin { weird calculated fields voodoo (from dbtables).... } + Inc(PChar(Src), Field.Offset + GetRecordSize); + Result := Boolean(Src[0]); + if Result and (Buffer <> nil) then + Move(Src[1], Buffer^, Field.DataSize); + end; +end; + +procedure TDbf.SetFieldData(Field: TField; Buffer: Pointer); {override virtual abstract from TDataset} +{$ifdef SUPPORT_OVERLOAD} +begin + { calling through 'old' delphi 3 interface, use compatible/'native' format } + SetFieldData(Field, Buffer, true); +end; + +procedure TDbf.SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean); {overload; override;} +{$else} +const + { no overload => delphi 3 => use compatible/'native' format } + NativeFormat = true; +{$endif} +var + Dst: PChar; +begin + if (Field.FieldNo >= 0) then + begin + if State in [dsEdit, dsInsert, dsNewValue] then + Field.Validate(Buffer); + Dst := @PDbfRecord(ActiveBuffer)^.DeletedFlag; + FDbfFile.SetFieldData(Field.FieldNo - 1, Field.DataType, Buffer, Dst, NativeFormat); + end else begin { ***** fkCalculated, fkLookup ***** } + Dst := @PDbfRecord(CalcBuffer)^.DeletedFlag; + Inc(PChar(Dst), RecordSize + Field.Offset); + Boolean(Dst[0]) := Buffer <> nil; + if Buffer <> nil then + Move(Buffer^, Dst[1], Field.DataSize) + end; { end of ***** fkCalculated, fkLookup ***** } + if not (State in [dsCalcFields, dsFilter, dsNewValue]) then begin + DataEvent(deFieldChange, PtrInt(Field)); + end; +end; + +procedure TDbf.DoFilterRecord(var Acceptable: Boolean); +begin + // check filtertext + if Length(Filter) > 0 then + begin +{$ifndef VER1_0} + Acceptable := Boolean((FParser.ExtractFromBuffer(GetCurrentBuffer))^); +{$else} + // strange problem + // dbf.pas(716,19) Error: Incompatible types: got "CHAR" expected "BOOLEAN" + Acceptable := not ((FParser.ExtractFromBuffer(GetCurrentBuffer))^ = #0); +{$endif} + end; + + // check user filter + if Acceptable and Assigned(OnFilterRecord) then + OnFilterRecord(Self, Acceptable); +end; + +function TDbf.ReadCurrentRecord(Buffer: TRecordBuffer; var Acceptable: Boolean): TGetResult; +var + lPhysicalRecNo: Integer; + pRecord: pDbfRecord; +begin + lPhysicalRecNo := FCursor.PhysicalRecNo; + if (lPhysicalRecNo = 0) or not FDbfFile.IsRecordPresent(lPhysicalRecNo) then + begin + Result := grError; + Acceptable := false; + end else begin + Result := grOK; + pRecord := pDbfRecord(Buffer); + FDbfFile.ReadRecord(lPhysicalRecNo, @pRecord^.DeletedFlag); + Acceptable := (FShowDeleted or (pRecord^.DeletedFlag <> '*')) + end; +end; + +function TDbf.GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean): TGetResult; {override virtual abstract from TDataset} +var + pRecord: pDbfRecord; + acceptable: Boolean; + SaveState: TDataSetState; +// s: string; +begin + if FCursor = nil then + begin + Result := grEOF; + exit; + end; + + pRecord := pDbfRecord(Buffer); + acceptable := false; + repeat + Result := grOK; + case GetMode of + gmNext : + begin + Acceptable := FCursor.Next; + if Acceptable then begin + Result := grOK; + end else begin + Result := grEOF + end; + end; + gmPrior : + begin + Acceptable := FCursor.Prev; + if Acceptable then begin + Result := grOK; + end else begin + Result := grBOF + end; + end; + end; + + if (Result = grOK) then + Result := ReadCurrentRecord(Buffer, acceptable); + + if (Result = grOK) and acceptable then + begin + pRecord^.BookmarkData.PhysicalRecNo := FCursor.PhysicalRecNo; + pRecord^.BookmarkFlag := bfCurrent; + pRecord^.SequentialRecNo := FCursor.SequentialRecNo; + GetCalcFields(Buffer); + + if Filtered or FFindRecordFilter then + begin + FFilterBuffer := Buffer; + SaveState := SetTempState(dsFilter); + DoFilterRecord(acceptable); + RestoreState(SaveState); + end; + end; + + if (GetMode = gmCurrent) and not acceptable then + Result := grError; + until (Result <> grOK) or acceptable; + + if Result <> grOK then + pRecord^.BookmarkData.PhysicalRecNo := -1; +end; + +function TDbf.GetRecordSize: Word; {override virtual abstract from TDataset} +begin + Result := FDbfFile.RecordSize; +end; + +procedure TDbf.InternalAddRecord(Buffer: Pointer; AAppend: Boolean); {override virtual abstract from TDataset} + // this function is called from TDataSet.InsertRecord and TDataSet.AppendRecord + // goal: add record with Edit...Set Fields...Post all in one step +var + pRecord: pDbfRecord; + newRecord: integer; +begin + // if InternalAddRecord is called, we know we are active + pRecord := Buffer; + + // we can not insert records in DBF files, only append + // ignore Append parameter + newRecord := FDbfFile.Insert(@pRecord^.DeletedFlag); + if newRecord > 0 then + FCursor.PhysicalRecNo := newRecord; + + // set flag that TDataSet is about to post...so we can disable resync + FPosting := true; +end; + +procedure TDbf.InternalClose; {override virtual abstract from TDataset} +var + lIndex: TDbfIndexDef; + I: Integer; +begin + // clear automatically added MDX index entries + I := 0; + while I < FIndexDefs.Count do + begin + // is this an MDX index? + lIndex := FIndexDefs.Items[I]; + if (Length(ExtractFileExt(lIndex.IndexFile)) = 0) and + TDbfIndexDef(FIndexDefs.Items[I]).Temporary then + begin +{$ifdef SUPPORT_DEF_DELETE} + // delete this entry + FIndexDefs.Delete(I); +{$else} + // does this work? I hope so :-) + FIndexDefs.Items[I].Free; +{$endif} + end else begin + // NDX entry -> goto next + Inc(I); + end; + end; + + // free blobs + if FBlobStreams <> nil then + begin + for I := 0 to Pred(FieldDefs.Count) do + FBlobStreams^[I].Free; + FreeMemAndNil(Pointer(FBlobStreams)); + end; + FreeRecordBuffer(FTempBuffer); + // disconnect field objects + BindFields(false); + // Destroy field object (if not persistent) + if DefaultFields then + DestroyFields; + + if FParser <> nil then + FreeAndNil(FParser); + FreeAndNil(FCursor); + if FDbfFile <> nil then + FreeAndNil(FDbfFile); +end; + +procedure TDbf.InternalCancel; +var + I: Integer; +begin + // cancel blobs + for I := 0 to Pred(FieldDefs.Count) do + if Assigned(FBlobStreams^[I]) then + FBlobStreams^[I].Cancel; + // if we have locked a record, unlock it + if FEditingRecNo >= 0 then + begin + FDbfFile.UnlockPage(FEditingRecNo); + FEditingRecNo := -1; + end; +end; + +procedure TDbf.InternalDelete; {override virtual abstract from TDataset} +var + lRecord: pDbfRecord; +begin + // start editing + InternalEdit; + SetState(dsEdit); + // get record pointer + lRecord := pDbfRecord(ActiveBuffer); + // flag we deleted this record + lRecord^.DeletedFlag := '*'; + // notify indexes this record is deleted + FDbfFile.RecordDeleted(FEditingRecNo, @lRecord^.DeletedFlag); + // done! + InternalPost; +end; + +procedure TDbf.InternalFirst; {override virtual abstract from TDataset} +begin + FCursor.First; +end; + +procedure TDbf.InternalGotoBookmark(ABookmark: Pointer); {override virtual abstract from TDataset} +begin + with PBookmarkData(ABookmark)^ do + begin + if (PhysicalRecNo = 0) then begin + First; + end else + if (PhysicalRecNo = MaxInt) then begin + Last; + end else begin + if FCursor.PhysicalRecNo <> PhysicalRecNo then + FCursor.PhysicalRecNo := PhysicalRecNo; + end; + end; +end; + +procedure TDbf.InternalHandleException; {override virtual abstract from TDataset} +begin + SysUtils.ShowException(ExceptObject, ExceptAddr); +end; + +procedure TDbf.GetFieldDefsFromDbfFieldDefs; +var + I, N: Integer; + TempFieldDef: TDbfFieldDef; + TempMdxFile: TIndexFile; + BaseName, lIndexName: string; +begin + FieldDefs.Clear; + + // get all fields + for I := 0 to FDbfFile.FieldDefs.Count - 1 do + begin + TempFieldDef := FDbfFile.FieldDefs.Items[I]; + // handle duplicate field names + N := 1; + BaseName := TempFieldDef.FieldName; + while FieldDefs.IndexOf(TempFieldDef.FieldName)>=0 do + begin + Inc(N); + TempFieldDef.FieldName:=BaseName+IntToStr(N); + end; + // add field + if TempFieldDef.FieldType in [ftString, ftBCD, ftBytes] then + FieldDefs.Add(TempFieldDef.FieldName, TempFieldDef.FieldType, TempFieldDef.Size, false) + else + FieldDefs.Add(TempFieldDef.FieldName, TempFieldDef.FieldType, 0, false); + + if TempFieldDef.FieldType = ftFloat then + begin + FieldDefs[I].Size := 0; // Size is not defined for float-fields + FieldDefs[I].Precision := TempFieldDef.Size; + end; + +{$ifdef SUPPORT_FIELDDEF_ATTRIBUTES} + // AutoInc fields are readonly + if TempFieldDef.FieldType = ftAutoInc then + FieldDefs[I].Attributes := [Db.faReadOnly]; + + // if table has dbase lock field, then hide it + if TempFieldDef.IsLockField then + FieldDefs[I].Attributes := [Db.faHiddenCol]; +{$endif} + end; + + // get all (new) MDX index defs + TempMdxFile := FDbfFile.MdxFile; + for I := 0 to FDbfFile.IndexNames.Count - 1 do + begin + // is this an MDX index? + lIndexName := FDbfFile.IndexNames.Strings[I]; + if FDbfFile.IndexNames.Objects[I] = TempMdxFile then + if FIndexDefs.GetIndexByName(lIndexName) = nil then + TempMdxFile.GetIndexInfo(lIndexName, FIndexDefs.Add); + end; +end; + +procedure TDbf.InitFieldDefs; +begin + InternalInitFieldDefs; +end; + +procedure TDbf.InitDbfFile(FileOpenMode: TPagedFileMode); +const + FileModeToMemMode: array[TPagedFileMode] of TPagedFileMode = + (pfNone, pfMemoryCreate, pfMemoryOpen, pfMemoryCreate, pfMemoryOpen, + pfMemoryCreate, pfMemoryOpen, pfMemoryOpen); +begin + FDbfFile := TDbfFile.Create; + if FStorage = stoMemory then + begin + FDbfFile.Stream := FUserStream; + FDbfFile.Mode := FileModeToMemMode[FileOpenMode]; + end else begin + FDbfFile.FileName := FAbsolutePath + FTableName; + FDbfFile.Mode := FileOpenMode; + end; + FDbfFile.AutoCreate := false; + FDbfFile.DateTimeHandling := FDateTimeHandling; + FDbfFile.OnLocaleError := FOnLocaleError; + FDbfFile.OnIndexMissing := FOnIndexMissing; +end; + +procedure TDbf.InternalInitFieldDefs; {override virtual abstract from TDataset} +var + MustReleaseDbfFile: Boolean; +begin + MustReleaseDbfFile := false; + with FieldDefs do + begin + if FDbfFile = nil then + begin + // do not AutoCreate file + InitDbfFile(pfReadOnly); + FDbfFile.Open; + MustReleaseDbfFile := true; + end; + GetFieldDefsFromDbfFieldDefs; + if MustReleaseDbfFile then + FreeAndNil(FDbfFile); + end; +end; + +procedure TDbf.InternalInitRecord(Buffer: TRecordBuffer); {override virtual abstract from TDataset} +var + pRecord: pDbfRecord; +begin + pRecord := pDbfRecord(Buffer); + pRecord^.BookmarkData.PhysicalRecNo := 0; + pRecord^.BookmarkFlag := bfCurrent; + pRecord^.SequentialRecNo := 0; +// Init Record with zero and set autoinc field with next value + FDbfFile.InitRecord(@pRecord^.DeletedFlag); +end; + +procedure TDbf.InternalLast; {override virtual abstract from TDataset} +begin + FCursor.Last; +end; + +procedure TDbf.DetermineTranslationMode; +var + lCodePage: Cardinal; +begin + lCodePage := FDbfFile.UseCodePage; + if lCodePage = GetACP then + FTranslationMode := tmNoneNeeded + else + if lCodePage = GetOEMCP then + FTranslationMode := tmSimple + // check if this code page, although non default, is installed + else + if DbfGlobals.CodePageInstalled(lCodePage) then + FTranslationMode := tmAdvanced + else + FTranslationMode := tmNoneAvailable; +end; + +procedure TDbf.InternalOpen; {override virtual abstract from TDataset} +const + DbfOpenMode: array[Boolean, Boolean] of TPagedFileMode = + ((pfReadWriteOpen, pfExclusiveOpen), (pfReadOnly, pfReadOnly)); +var + lIndex: TDbfIndexDef; + lIndexName: string; + LanguageAction: TDbfLanguageAction; + doCreate: Boolean; + I: Integer; +begin + // close current file + FreeAndNil(FDbfFile); + + // does file not exist? -> create + if ((FStorage = stoFile) and + not FileExists(FAbsolutePath + FTableName) and + (FOpenMode in [omAutoCreate, omTemporary])) or + ((FStorage = stoMemory) and (FUserStream = nil)) then + begin + doCreate := true; + if Assigned(FBeforeAutoCreate) then + FBeforeAutoCreate(Self, doCreate); + if doCreate then + CreateTable + else + exit; + end; + + // now we know for sure the file exists + InitDbfFile(DbfOpenMode[FReadOnly, FExclusive]); + FDbfFile.Open; + + // fail open? +{$ifndef FPC} + if FDbfFile.ForceClose then + Abort; +{$endif} + + // determine dbf version + case FDbfFile.DbfVersion of + xBaseIII: FTableLevel := 3; + xBaseIV: FTableLevel := 4; + xBaseVII: FTableLevel := 7; + xFoxPro: FTableLevel := TDBF_TABLELEVEL_FOXPRO; + end; + FLanguageID := FDbfFile.LanguageID; + + // build VCL fielddef list from native DBF FieldDefs +(* + if (FDbfFile.HeaderSize = 0) or (FDbfFile.FieldDefs.Count = 0) then + begin + if FieldDefs.Count > 0 then + begin + CreateTableFromFieldDefs; + end else begin + CreateTableFromFields; + end; + end else begin +*) +// GetFieldDefsFromDbfFieldDefs; +// end; + +{$ifdef SUPPORT_FIELDDEFS_UPDATED} + FieldDefs.Updated := False; + FieldDefs.Update; +{$else} + InternalInitFieldDefs; +{$endif} + + // create the fields dynamically + if DefaultFields then + CreateFields; // Create fields from fielddefs. + + BindFields(true); + + // create array of blobstreams to store memo's in. each field is a possible blob + FBlobStreams := AllocMem(FieldDefs.Count * SizeOf(TDbfBlobStream)); + + // check codepage settings + DetermineTranslationMode; + if FTranslationMode = tmNoneAvailable then + begin + // no codepage available? ask user + LanguageAction := laReadOnly; + if Assigned(FOnLanguageWarning) then + FOnLanguageWarning(Self, LanguageAction); + case LanguageAction of + laReadOnly: FTranslationMode := tmNoneAvailable; + laForceOEM: + begin + FDbfFile.UseCodePage := GetOEMCP; + FTranslationMode := tmSimple; + end; + laForceANSI: + begin + FDbfFile.UseCodePage := GetACP; + FTranslationMode := tmNoneNeeded; + end; + laDefault: + begin + FDbfFile.UseCodePage := DbfGlobals.DefaultOpenCodePage; + DetermineTranslationMode; + end; + end; + end; + + // allocate a record buffer for temporary data + FTempBuffer := AllocRecordBuffer; + + // open indexes + for I := 0 to FIndexDefs.Count - 1 do + begin + lIndex := FIndexDefs.Items[I]; + lIndexName := ParseIndexName(lIndex.IndexFile); + // if index does not exist -> create, if it does exist -> open only + FDbfFile.OpenIndex(lIndexName, lIndex.SortField, false, lIndex.Options); + end; + + // parse filter expression + try + ParseFilter(Filter); + except + // oops, a problem with parsing, clear filter for now + on E: EDbfError do Filter := EmptyStr; + end; + + SetIndexName(FIndexName); + +// SetIndexName will have made the cursor for us if no index selected :-) +// if FCursor = nil then FCursor := TDbfCursor.Create(FDbfFile); + + if FMasterLink.Active and Assigned(FIndexFile) then + CheckMasterRange; + InternalFirst; + +// FDbfFile.SetIndex(FIndexName); +// FDbfFile.FIsCursorOpen := true; +end; + +function TDbf.GetCodePage: Cardinal; +begin + if FDbfFile <> nil then + Result := FDbfFile.UseCodePage + else + Result := 0; +end; + +function TDbf.GetLanguageStr: String; +begin + result:= ''; + if FDbfFile <> nil then + Result := FDbfFile.LanguageStr; +end; + +function TDbf.LockTable(const Wait: Boolean): Boolean; +begin + CheckActive; + Result := FDbfFile.LockAllPages(Wait); +end; + +procedure TDbf.UnlockTable; +begin + CheckActive; + FDbfFile.UnlockAllPages; +end; + +procedure TDbf.InternalEdit; +var + I: Integer; +begin + // store recno we are editing + FEditingRecNo := FCursor.PhysicalRecNo; + // reread blobs, execute cancel -> clears remembered memo pageno, + // causing it to reread the memo contents + for I := 0 to Pred(FieldDefs.Count) do + if Assigned(FBlobStreams^[I]) then + FBlobStreams^[I].Cancel; + // try to lock this record + FDbfFile.LockRecord(FEditingRecNo, @pDbfRecord(ActiveBuffer)^.DeletedFlag); + // succeeded! +end; + +{$ifndef FPC} +{$ifndef DELPHI_3} + +procedure TDbf.InternalInsert; {override virtual from TDataset} +begin + CursorPosChanged; +end; + +{$endif} +{$endif} + +procedure TDbf.InternalPost; {override virtual abstract from TDataset} +var + pRecord: pDbfRecord; + I, newRecord: Integer; +begin + // if internalpost is called, we know we are active + pRecord := pDbfRecord(ActiveBuffer); + // commit blobs + for I := 0 to Pred(FieldDefs.Count) do + if Assigned(FBlobStreams^[I]) then + FBlobStreams^[I].Commit; + if State = dsEdit then + begin + // write changes + FDbfFile.UnlockRecord(FEditingRecNo, @pRecord^.DeletedFlag); + // not editing anymore + FEditingRecNo := -1; + end else begin + // insert + newRecord := FDbfFile.Insert(@pRecord^.DeletedFlag); + if newRecord > 0 then + FCursor.PhysicalRecNo := newRecord; + end; + // set flag that TDataSet is about to post...so we can disable resync + FPosting := true; +end; + +procedure TDbf.Resync(Mode: TResyncMode); +begin + // try to increase speed + if not FDisableResyncOnPost or not FPosting then + inherited; + // clear post flag + FPosting := false; +end; + + +{$ifndef SUPPORT_INITDEFSFROMFIELDS} + +procedure TDbf.InitFieldDefsFromFields; +var + I: Integer; + F: TField; +begin + { create fielddefs from persistent fields if needed } + for I := 0 to FieldCount - 1 do + begin + F := Fields[I]; + with F do + if FieldKind = fkData then begin + FieldDefs.Add(FieldName,DataType,Size,Required); + end; + end; +end; + +{$endif} + +procedure TDbf.CreateTable; +begin + CreateTableEx(nil); +end; + +procedure TDbf.CheckDbfFieldDefs(ADbfFieldDefs: TDbfFieldDefs); +var + I: Integer; + TempDef: TDbfFieldDef; + + function FieldTypeStr(const FieldType: char): string; + begin + if FieldType = #0 then + Result := 'NULL' + else if FieldType > #127 then + Result := 'ASCII '+IntToStr(Byte(FieldType)) + else + Result := ' "'+fieldType+'" '; + Result := ' ' + Result + '(#'+IntToHex(Byte(FieldType),SizeOf(FieldType))+') ' + end; + +begin + if ADbfFieldDefs = nil then exit; + + for I := 0 to ADbfFieldDefs.Count - 1 do + begin + // check dbffielddefs for errors + TempDef := ADbfFieldDefs.Items[I]; + if FTableLevel < 7 then + if not (TempDef.NativeFieldType in ['C', 'F', 'N', 'D', 'L', 'M']) then + raise EDbfError.CreateFmt(STRING_INVALID_FIELD_TYPE, + [FieldTypeStr(TempDef.NativeFieldType), TempDef.FieldName]); + end; +end; + +procedure TDbf.CreateTableEx(ADbfFieldDefs: TDbfFieldDefs); +var + I: Integer; + lIndex: TDbfIndexDef; + lIndexName: string; + tempFieldDefs: Boolean; +begin + CheckInactive; + tempFieldDefs := ADbfFieldDefs = nil; + try + try + if tempFieldDefs then + begin + ADbfFieldDefs := TDbfFieldDefs.Create(Self); + ADbfFieldDefs.DbfVersion := TableLevelToDbfVersion(FTableLevel); + + // get fields -> fielddefs if no fielddefs +{$ifndef FPC_VERSION} + if FieldDefs.Count = 0 then + InitFieldDefsFromFields; +{$endif} + + // fielddefs -> dbffielddefs + for I := 0 to FieldDefs.Count - 1 do + begin + with ADbfFieldDefs.AddFieldDef do + begin + FieldName := FieldDefs.Items[I].Name; + FieldType := FieldDefs.Items[I].DataType; + if FieldDefs.Items[I].Size > 0 then + begin + Size := FieldDefs.Items[I].Size; + Precision := FieldDefs.Items[I].Precision; + end else begin + SetDefaultSize; + end; + end; + end; + end; + + InitDbfFile(pfExclusiveCreate); + FDbfFile.CopyDateTimeAsString := FInCopyFrom and FCopyDateTimeAsString; + FDbfFile.DbfVersion := TableLevelToDbfVersion(FTableLevel); + FDbfFile.FileLangID := FLanguageID; + FDbfFile.Open; + FDbfFile.FinishCreate(ADbfFieldDefs, 512); + + // if creating memory table, copy stream pointer + if FStorage = stoMemory then + FUserStream := FDbfFile.Stream; + + // create all indexes + for I := 0 to FIndexDefs.Count-1 do + begin + lIndex := FIndexDefs.Items[I]; + lIndexName := ParseIndexName(lIndex.IndexFile); + FDbfFile.OpenIndex(lIndexName, lIndex.SortField, true, lIndex.Options); + end; + except + // dbf file created? + if (FDbfFile <> nil) and (FStorage = stoFile) then + begin + FreeAndNil(FDbfFile); + SysUtils.DeleteFile(FAbsolutePath+FTableName); + end; + raise; + end; + finally + // free temporary fielddefs + if tempFieldDefs and Assigned(ADbfFieldDefs) then + ADbfFieldDefs.Free; + FreeAndNil(FDbfFile); + end; +end; + +procedure TDbf.EmptyTable; +begin + Zap; +end; + +procedure TDbf.Zap; +begin + // are we active? + CheckActive; + FDbfFile.Zap; +end; + +procedure TDbf.RestructureTable(ADbfFieldDefs: TDbfFieldDefs; Pack: Boolean); +begin + CheckInactive; + + // check field defs for errors + CheckDbfFieldDefs(ADbfFieldDefs); + + // open dbf file + InitDbfFile(pfExclusiveOpen); + FDbfFile.Open; + + // do restructure + try + FDbfFile.RestructureTable(ADbfFieldDefs, Pack); + finally + // close file + FreeAndNil(FDbfFile); + end; +end; + +procedure TDbf.PackTable; +var + oldIndexName: string; +begin + CheckBrowseMode; + // deselect any index while packing + oldIndexName := IndexName; + IndexName := EmptyStr; + // pack + FDbfFile.RestructureTable(nil, true); + // reselect index + IndexName := oldIndexName; +end; + +procedure TDbf.CopyFrom(DataSet: TDataSet; FileName: string; DateTimeAsString: Boolean; Level: Integer); +var + lPhysFieldDefs, lFieldDefs: TDbfFieldDefs; + lSrcField, lDestField: TField; + I: integer; +begin + FInCopyFrom := true; + lFieldDefs := TDbfFieldDefs.Create(nil); + lPhysFieldDefs := TDbfFieldDefs.Create(nil); + try + if Active then + Close; + FilePath := ExtractFilePath(FileName); + TableName := ExtractFileName(FileName); + FCopyDateTimeAsString := DateTimeAsString; + TableLevel := Level; + if not DataSet.Active then + DataSet.Open; + DataSet.FieldDefs.Update; + // first get a list of physical field defintions + // we need it for numeric precision in case source is tdbf + if DataSet is TDbf then + begin + lPhysFieldDefs.Assign(TDbf(DataSet).DbfFieldDefs); + IndexDefs.Assign(TDbf(DataSet).IndexDefs); + end else begin +{$ifdef SUPPORT_FIELDDEF_TPERSISTENT} + lPhysFieldDefs.Assign(DataSet.FieldDefs); +{$endif} + IndexDefs.Clear; + end; + // convert list of tfields into a list of tdbffielddefs + // so that our tfields will correspond to the source tfields + for I := 0 to Pred(DataSet.FieldCount) do + begin + lSrcField := DataSet.Fields[I]; + with lFieldDefs.AddFieldDef do + begin + if Length(lSrcField.Name) > 0 then + FieldName := lSrcField.Name + else + FieldName := lSrcField.FieldName; + FieldType := lSrcField.DataType; + Required := lSrcField.Required; + if (1 <= lSrcField.FieldNo) + and (lSrcField.FieldNo <= lPhysFieldDefs.Count) then + begin + Size := lPhysFieldDefs.Items[lSrcField.FieldNo-1].Size; + Precision := lPhysFieldDefs.Items[lSrcField.FieldNo-1].Precision; + end; + end; + end; + + CreateTableEx(lFieldDefs); + Open; + DataSet.First; +{$ifdef USE_CACHE} + FDbfFile.BufferAhead := true; + if DataSet is TDbf then + TDbf(DataSet).DbfFile.BufferAhead := true; +{$endif} + while not DataSet.EOF do + begin + Append; + for I := 0 to Pred(FieldCount) do + begin + lSrcField := DataSet.Fields[I]; + lDestField := Fields[I]; + if not lSrcField.IsNull then + begin + if lSrcField.DataType = ftDateTime then + begin + if FCopyDateTimeAsString then + begin + lDestField.AsString := lSrcField.AsString; + if Assigned(FOnCopyDateTimeAsString) then + FOnCopyDateTimeAsString(Self, lDestField, lSrcField) + end else + lDestField.AsDateTime := lSrcField.AsDateTime; + end else + lDestField.Assign(lSrcField); + end; + end; + Post; + DataSet.Next; + end; + Close; + finally +{$ifdef USE_CACHE} + if (DataSet is TDbf) and (TDbf(DataSet).DbfFile <> nil) then + TDbf(DataSet).DbfFile.BufferAhead := false; +{$endif} + FInCopyFrom := false; + lFieldDefs.Free; + lPhysFieldDefs.Free; + end; +end; + +function TDbf.FindRecord(Restart, GoForward: Boolean): Boolean; +var + oldRecNo: Integer; +begin + CheckBrowseMode; + DoBeforeScroll; + Result := false; + UpdateCursorPos; + oldRecNo := RecNo; + try + FFindRecordFilter := true; + if GoForward then + begin + if Restart then FCursor.First; + Result := GetRecord(FTempBuffer, gmNext, false) = grOK; + end else begin + if Restart then FCursor.Last; + Result := GetRecord(FTempBuffer, gmPrior, false) = grOK; + end; + finally + FFindRecordFilter := false; + if not Result then + begin + RecNo := oldRecNo; + end else begin + CursorPosChanged; + Resync([]); + DoAfterScroll; + end; + end; +end; + +{$ifdef SUPPORT_VARIANTS} + +function TDbf.Lookup(const KeyFields: string; const KeyValues: Variant; + const ResultFields: string): Variant; +var +// OldState: TDataSetState; + saveRecNo: integer; + saveState: TDataSetState; +begin + Result := Null; + if (FCursor = nil) or VarIsNull(KeyValues) then exit; + + saveRecNo := FCursor.SequentialRecNo; + try + if LocateRecord(KeyFields, KeyValues, []) then + begin + // FFilterBuffer contains record buffer + saveState := SetTempState(dsCalcFields); + try + CalculateFields(FFilterBuffer); + if KeyValues = FieldValues[KeyFields] then + Result := FieldValues[ResultFields]; + finally + RestoreState(saveState); + end; + end; + finally + FCursor.SequentialRecNo := saveRecNo; + end; +end; + +function TDbf.Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; +var + saveRecNo: integer; +begin + if FCursor = nil then + begin + CheckActive; + Result := false; + exit; + end; + + DoBeforeScroll; + saveRecNo := FCursor.SequentialRecNo; + FLocateRecNo := -1; + Result := LocateRecord(KeyFields, KeyValues, Options); + CursorPosChanged; + if Result then + begin + if FLocateRecNo <> -1 then + FCursor.PhysicalRecNo := FLocateRecNo; + Resync([]); + DoAfterScroll; + end else + FCursor.SequentialRecNo := saveRecNo; +end; + +function TDbf.LocateRecordLinear(const KeyFields: String; const KeyValues: Variant; + Options: TLocateOptions): Boolean; +var + lstKeys : TList; + iIndex : Integer; + Field : TField; + bMatchedData : Boolean; + bVarIsArray : Boolean; + varCompare : Variant; + + function CompareValues: Boolean; + var + sCompare: String; + begin + if (Field.DataType = ftString) then + begin + sCompare := VarToStr(varCompare); + if loCaseInsensitive in Options then + begin + Result := AnsiCompareText(Field.AsString,sCompare) = 0; + if not Result and (iIndex = lstKeys.Count - 1) and (loPartialKey in Options) and + (Length(sCompare) < Length(Field.AsString)) then + begin + if Length(sCompare) = 0 then + Result := true + else + Result := AnsiCompareText (Copy (Field.AsString,1,Length (sCompare)),sCompare) = 0; + end; + end else begin + Result := Field.AsString = sCompare; + if not Result and (iIndex = lstKeys.Count - 1) and (loPartialKey in Options) and + (Length (sCompare) < Length (Field.AsString)) then + begin + if Length (sCompare) = 0 then + Result := true + else + Result := Copy(Field.AsString, 1, Length(sCompare)) = sCompare; + end; + end; + end + else + Result := Field.Value = varCompare; + end; + +var + SaveState: TDataSetState; + lPhysRecNo: integer; +begin + Result := false; + bVarIsArray := false; + lstKeys := TList.Create; + FFilterBuffer := TempBuffer; + SaveState := SetTempState(dsFilter); + try + GetFieldList(lstKeys, KeyFields); + if VarArrayDimCount(KeyValues) = 0 then + bMatchedData := lstKeys.Count = 1 + else if VarArrayDimCount (KeyValues) = 1 then + begin + bMatchedData := VarArrayHighBound (KeyValues,1) + 1 = lstKeys.Count; + bVarIsArray := true; + end else + bMatchedData := false; + if bMatchedData then + begin + FCursor.First; + while not Result and FCursor.Next do + begin + lPhysRecNo := FCursor.PhysicalRecNo; + if (lPhysRecNo = 0) or not FDbfFile.IsRecordPresent(lPhysRecNo) then + break; + + FDbfFile.ReadRecord(lPhysRecNo, @PDbfRecord(FFilterBuffer)^.DeletedFlag); + Result := FShowDeleted or (PDbfRecord(FFilterBuffer)^.DeletedFlag <> '*'); + if Result and Filtered then + DoFilterRecord(Result); + + iIndex := 0; + while Result and (iIndex < lstKeys.Count) Do + begin + Field := TField (lstKeys [iIndex]); + if bVarIsArray then + varCompare := KeyValues [iIndex] + else + varCompare := KeyValues; + Result := CompareValues; + Inc(iIndex); + end; + end; + end; + finally + lstKeys.Free; + RestoreState(SaveState); + end; +end; + +function TDbf.LocateRecordIndex(const KeyFields: String; const KeyValues: Variant; + Options: TLocateOptions): Boolean; +var + searchFlag: TSearchKeyType; + matchRes: Integer; + lTempBuffer: array [0..100] of Char; + acceptable, checkmatch: boolean; +begin + if loPartialKey in Options then + searchFlag := stGreaterEqual + else + searchFlag := stEqual; + if TIndexCursor(FCursor).VariantToBuffer(KeyValues, @lTempBuffer[0]) = etString then + Translate(@lTempBuffer[0], @lTempBuffer[0], true); + Result := FIndexFile.SearchKey(@lTempBuffer[0], searchFlag); + if not Result then + exit; + + checkmatch := false; + repeat + if ReadCurrentRecord(TempBuffer, acceptable) = grError then + begin + Result := false; + exit; + end; + if acceptable then break; + checkmatch := true; + FCursor.Next; + until false; + + if checkmatch then + begin + matchRes := TIndexCursor(FCursor).IndexFile.MatchKey(@lTempBuffer[0]); + if loPartialKey in Options then + Result := matchRes <= 0 + else + Result := matchRes = 0; + end; + + FFilterBuffer := TempBuffer; +end; + +function TDbf.LocateRecord(const KeyFields: String; const KeyValues: Variant; + Options: TLocateOptions): Boolean; +var + lCursor, lSaveCursor: TVirtualCursor; + lSaveIndexName, lIndexName: string; + lIndexDef: TDbfIndexDef; + lIndexFile, lSaveIndexFile: TIndexFile; +begin + lsaveindexname:= ''; + lCursor := nil; + lSaveCursor := nil; + lIndexFile := nil; + lSaveIndexFile := FIndexFile; + if (FCursor is TIndexCursor) + and (TIndexCursor(FCursor).IndexFile.Expression = KeyFields) then + begin + lCursor := FCursor; + end else begin + lIndexDef := FIndexDefs.GetIndexByField(KeyFields); + if lIndexDef <> nil then + begin + lIndexName := ParseIndexName(lIndexDef.IndexFile); + lIndexFile := FDbfFile.GetIndexByName(lIndexName); + if lIndexFile <> nil then + begin + lSaveCursor := FCursor; + lCursor := TIndexCursor.Create(lIndexFile); + lSaveIndexName := lIndexFile.IndexName; + lIndexFile.IndexName := lIndexName; + FIndexFile := lIndexFile; + end; + end; + end; + if lCursor <> nil then + begin + FCursor := lCursor; + Result := LocateRecordIndex(KeyFields, KeyValues, Options); + if lSaveCursor <> nil then + begin + FCursor.Free; + FCursor := lSaveCursor; + end; + if lIndexFile <> nil then + begin + FLocateRecNo := FIndexFile.PhysicalRecNo; + lIndexFile.IndexName := lSaveIndexName; + FIndexFile := lSaveIndexFile; + end; + end else + Result := LocateRecordLinear(KeyFields, KeyValues, Options); +end; + +{$endif} + +procedure TDbf.TryExclusive; +begin + // are we active? + if Active then + begin + // already in exclusive mode? + FDbfFile.TryExclusive; + // update file mode + FExclusive := not FDbfFile.IsSharedAccess; + FReadOnly := FDbfFile.Mode = pfReadOnly; + end else begin + // just set exclusive to true + FExclusive := true; + FReadOnly := false; + end; +end; + +procedure TDbf.EndExclusive; +begin + if Active then + begin + // call file handler + FDbfFile.EndExclusive; + // update file mode + FExclusive := not FDbfFile.IsSharedAccess; + FReadOnly := FDbfFile.Mode = pfReadOnly; + end else begin + // just set exclusive to false + FExclusive := false; + end; +end; + +function TDbf.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; {override virtual} +var + MemoPageNo: Integer; + MemoFieldNo: Integer; + lBlob: TDbfBlobStream; +begin + // check if in editing mode if user wants to write + if (Mode = bmWrite) or (Mode = bmReadWrite) then + if not (State in [dsEdit, dsInsert]) then +{$ifdef DELPHI_3} + DatabaseError(SNotEditing); +{$else} + DatabaseError(SNotEditing, Self); +{$endif} + // already created a `placeholder' blob for this field? + MemoFieldNo := Field.FieldNo - 1; + if FBlobStreams^[MemoFieldNo] = nil then + FBlobStreams^[MemoFieldNo] := TDbfBlobStream.Create(Field); + lBlob := FBlobStreams^[MemoFieldNo].AddReference; + // update pageno of blob <-> location where to read/write in memofile + if FDbfFile.GetFieldData(Field.FieldNo-1, ftInteger, GetCurrentBuffer, @MemoPageNo, false) then + begin + // read blob? different blob? + if (Mode = bmRead) or (Mode = bmReadWrite) then + begin + if MemoPageNo <> lBlob.MemoRecNo then + begin + FDbfFile.MemoFile.ReadMemo(MemoPageNo, lBlob); + lBlob.ReadSize := lBlob.Size; + lBlob.Translate(false); + end; + end else begin + lBlob.Size := 0; + lBlob.ReadSize := 0; + end; + lBlob.MemoRecNo := MemoPageNo; + end else + if not lBlob.Dirty or (Mode = bmWrite) then + begin + // reading and memo is empty and not written yet, or rewriting + lBlob.Size := 0; + lBlob.ReadSize := 0; + lBlob.MemoRecNo := 0; + end; + { this is a hack, we actually need to know per user who's modifying, and who is not } + { Mode is more like: the mode of the last "creation" } + { if create/free is nested, then everything will be alright, i think ;-) } + lBlob.Mode := Mode; + { this is a hack: we actually need to know per user what it's position is } + lBlob.Position := 0; + Result := lBlob; +end; + +{$ifdef SUPPORT_NEW_TRANSLATE} + +function TDbf.Translate(Src, Dest: PChar; ToOem: Boolean): Integer; {override virtual} +var + FromCP, ToCP: Cardinal; +begin + if (Src <> nil) and (Dest <> nil) then + begin + if Assigned(FOnTranslate) then + begin + Result := FOnTranslate(Self, Src, Dest, ToOem); + if Result = -1 then + Result := StrLen(Dest); + end else begin + if FTranslationMode <> tmNoneNeeded then + begin + if ToOem then + begin + FromCP := GetACP; + ToCP := FDbfFile.UseCodePage; + end else begin + FromCP := FDbfFile.UseCodePage; + ToCP := GetACP; + end; + end else begin + FromCP := GetACP; + ToCP := FromCP; + end; + Result := TranslateString(FromCP, ToCP, Src, Dest, -1); + end; + end else + Result := 0; +end; + +{$else} + +procedure TDbf.Translate(Src, Dest: PChar; ToOem: Boolean); {override virtual} +var + FromCP, ToCP: Cardinal; +begin + if (Src <> nil) and (Dest <> nil) then + begin + if Assigned(FOnTranslate) then + begin + FOnTranslate(Self, Src, Dest, ToOem); + end else begin + if FTranslationMode <> tmNoneNeeded then + begin + if ToOem then + begin + FromCP := GetACP; + ToCP := FDbfFile.UseCodePage; + end else begin + FromCP := FDbfFile.UseCodePage; + ToCP := GetACP; + end; + TranslateString(FromCP, ToCP, Src, Dest, -1); + end; + end; + end; +end; + +{$endif} + +procedure TDbf.ClearCalcFields(Buffer: TRecordBuffer); +var + lRealBuffer, lCalcBuffer: PChar; +begin + lRealBuffer := @pDbfRecord(Buffer)^.DeletedFlag; + lCalcBuffer := lRealBuffer + FDbfFile.RecordSize; + FillChar(lCalcBuffer^, CalcFieldsSize, 0); +end; + +procedure TDbf.InternalSetToRecord(Buffer: TRecordBuffer); {override virtual abstract from TDataset} +var + pRecord: pDbfRecord; +begin + if Buffer <> nil then + begin + pRecord := pDbfRecord(Buffer); + if pRecord^.BookmarkFlag = bfInserted then + begin + // do what ??? + end else begin + FCursor.SequentialRecNo := pRecord^.SequentialRecNo; + end; + end; +end; + +function TDbf.IsCursorOpen: Boolean; {override virtual abstract from TDataset} +begin + Result := FCursor <> nil; +end; + +function TDbf.FieldDefsStored: Boolean; +begin + Result := StoreDefs and (FieldDefs.Count > 0); +end; + +procedure TDbf.SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); {override virtual abstract from TDataset} +begin + pDbfRecord(Buffer)^.BookmarkFlag := Value; +end; + +procedure TDbf.SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); {override virtual abstract from TDataset} +begin + pDbfRecord(Buffer)^.BookmarkData := pBookmarkData(Data)^; +end; + +// this function counts real number of records: skip deleted records, filter, etc. +// warning: is very slow, compared to GetRecordCount +function TDbf.GetExactRecordCount: Integer; +var + prevRecNo: Integer; + getRes: TGetResult; +begin + // init vars + Result := 0; + + // check if FCursor open + if FCursor = nil then + exit; + + // store current position + prevRecNo := FCursor.SequentialRecNo; + FCursor.First; + repeat + // repeatedly retrieve next record until eof encountered + getRes := GetRecord(FTempBuffer, gmNext, true); + if getRes = grOk then + inc(Result); + until getRes <> grOk; + // restore current position + FCursor.SequentialRecNo := prevRecNo; +end; + +// this functions returns the physical number of records present in file +function TDbf.GetPhysicalRecordCount: Integer; +begin + if FDbfFile <> nil then + Result := FDbfFile.RecordCount + else + Result := 0 +end; + +// this function is just for the grid scrollbars +// it doesn't have to be perfectly accurate, but fast. +function TDbf.GetRecordCount: Integer; {override virtual} +begin + if FCursor <> nil then + Result := FCursor.SequentialRecordCount + else + Result := 0 +end; + +// this function is just for the grid scrollbars +// it doesn't have to be perfectly accurate, but fast. +function TDbf.GetRecNo: Integer; {override virtual} +var + pBuffer: pointer; +begin + if FCursor <> nil then + begin + if State = dsCalcFields then + pBuffer := CalcBuffer + else + pBuffer := ActiveBuffer; + Result := pDbfRecord(pBuffer)^.SequentialRecNo; + end else + Result := 0; +end; + +procedure TDbf.SetRecNo(Value: Integer); {override virtual} +begin + CheckBrowseMode; + if Value = RecNo then + exit; + + DoBeforeScroll; + FCursor.SequentialRecNo := Value; + CursorPosChanged; + Resync([]); + DoAfterScroll; +end; + +function TDbf.GetCanModify: Boolean; {override;} +begin + if FReadOnly or (csDesigning in ComponentState) then + Result := false + else + Result := FTranslationMode > tmNoneAvailable; +end; + +{$ifdef SUPPORT_DEFCHANGED} + +procedure TDbf.DefChanged(Sender: TObject); +begin + StoreDefs := true; +end; + +{$endif} + +procedure TDbf.ParseFilter(const AFilter: string); +begin + // parser created? + if Length(AFilter) > 0 then + begin + if (FParser = nil) and (FDbfFile <> nil) then + begin + FParser := TDbfParser.Create(FDbfFile); + // we need truncated, translated (to ANSI) strings + FParser.StringFieldMode := smAnsiTrim; + end; + // have a parser now? + if FParser <> nil then + begin + // set options + FParser.PartialMatch := not (foNoPartialCompare in FilterOptions); + FParser.CaseInsensitive := foCaseInsensitive in FilterOptions; + // parse expression + FParser.ParseExpression(AFilter); + end; + end; +end; + +procedure TDbf.SetFilterText(const Value: String); +begin + if Value = Filter then + exit; + + // parse + ParseFilter(Value); + + // call dataset method + inherited; + + // refilter dataset if filtered + if (FDbfFile <> nil) and Filtered then Refresh; +end; + +procedure TDbf.SetFiltered(Value: Boolean); {override;} +begin + if Value = Filtered then + exit; + + // pass on to ancestor + inherited; + + // only refresh if active + if FCursor <> nil then + Refresh; +end; + +procedure TDbf.SetFilePath(const Value: string); +begin + CheckInactive; + + FRelativePath := Value; + if Length(FRelativePath) > 0 then + FRelativePath := IncludeTrailingPathDelimiter(FRelativePath); + + if IsFullFilePath(Value) then + begin + FAbsolutePath := IncludeTrailingPathDelimiter(Value); + end else begin + FAbsolutePath := GetCompletePath(DbfBasePath(), FRelativePath); + end; +end; + +procedure TDbf.SetTableName(const s: string); +var + lPath: string; +begin + FTableName := ExtractFileName(s); + lPath := ExtractFilePath(s); + if (Length(lPath) > 0) then + FilePath := lPath; + // force IDE to reread fielddefs when a different file is opened +{$ifdef SUPPORT_FIELDDEFS_UPDATED} + FieldDefs.Updated := false; +{$else} + // TODO ... ?? +{$endif} +end; + +procedure TDbf.SetDbfIndexDefs(const Value: TDbfIndexDefs); +begin + FIndexDefs.Assign(Value); +end; + +procedure TDbf.SetLanguageID(NewID: Byte); +begin + CheckInactive; + + FLanguageID := NewID; +end; + +procedure TDbf.SetTableLevel(const NewLevel: Integer); +begin + if NewLevel <> FTableLevel then + begin + // check validity + if not ((NewLevel = 3) or (NewLevel = 4) or (NewLevel = 7) or (NewLevel = 25)) then + exit; + + // can only assign tablelevel if table is closed + CheckInactive; + FTableLevel := NewLevel; + end; +end; + +function TDbf.GetIndexName: string; +begin + Result := FIndexName; +end; + +function TDbf.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer; +const + RetCodes: array[Boolean, Boolean] of ShortInt = ((2,-1),(1,0)); +var + b1,b2: Integer; +begin + // Check for uninitialized bookmarks + Result := RetCodes[Bookmark1 = nil, Bookmark2 = nil]; + if (Result = 2) then + begin + b1 := PInteger(Bookmark1)^; + b2 := PInteger(Bookmark2)^; + if b1 < b2 then Result := -1 + else if b1 > b2 then Result := 1 + else Result := 0; + end; +end; + +function TDbf.GetVersion: string; +begin + Result := Format('%d.%02d', [TDBF_MAJOR_VERSION, TDBF_MINOR_VERSION]); +end; + +procedure TDbf.SetVersion(const S: string); +begin + // What an idea... +end; + +function TDbf.ParseIndexName(const AIndexName: string): string; +begin + // if no ext, then it is a MDX tag, get complete only if it is a filename + // MDX: get first 10 characters only + if Length(ExtractFileExt(AIndexName)) > 0 then + Result := GetCompleteFileName(FAbsolutePath, AIndexName) + else + Result := AIndexName; +end; + +procedure TDbf.RegenerateIndexes; +begin + CheckBrowseMode; + FDbfFile.RegenerateIndexes; +end; + +{$ifdef SUPPORT_DEFAULT_PARAMS} +procedure TDbf.AddIndex(const AIndexName, AFields: String; Options: TIndexOptions; const DescFields: String=''); +{$else} +procedure TDbf.AddIndex(const AIndexName, AFields: String; Options: TIndexOptions); +{$endif} +var + lIndexFileName: string; +begin + CheckActive; + lIndexFileName := ParseIndexName(AIndexName); + FDbfFile.OpenIndex(lIndexFileName, AFields, true, Options); + + // refresh our indexdefs + InternalInitFieldDefs; +end; + +procedure TDbf.SetIndexName(AIndexName: string); +var + lRecNo: Integer; +begin + FIndexName := AIndexName; + if FDbfFile = nil then + exit; + + // get accompanying index file + AIndexName := ParseIndexName(Trim(AIndexName)); + FIndexFile := FDbfFile.GetIndexByName(AIndexName); + // store current lRecNo + if FCursor = nil then + begin + lRecNo := 1; + end else begin + UpdateCursorPos; + lRecNo := FCursor.PhysicalRecNo; + end; + // select new cursor + FreeAndNil(FCursor); + if FIndexFile <> nil then + begin + FCursor := TIndexCursor.Create(FIndexFile); + // select index + FIndexFile.IndexName := AIndexName; + // check if can activate master link + CheckMasterRange; + end else begin + FCursor := TDbfCursor.Create(FDbfFile); + FIndexName := EmptyStr; + end; + // reset previous lRecNo + FCursor.PhysicalRecNo := lRecNo; + // refresh records + if State = dsBrowse then + Resync([]); + // warn user if selecting non-existing index + if (FCursor = nil) and (AIndexName <> EmptyStr) then + raise EDbfError.CreateFmt(STRING_INDEX_NOT_EXIST, [AIndexName]); +end; + +function TDbf.GetIndexFieldNames: string; +var + lIndexDef: TDbfIndexDef; +begin + lIndexDef := FIndexDefs.GetIndexByName(IndexName); + if lIndexDef = nil then + Result := EmptyStr + else + Result := lIndexDef.SortField; +end; + +procedure TDbf.SetIndexFieldNames(const Value: string); +var + lIndexDef: TDbfIndexDef; +begin + // Exception if index not found? + lIndexDef := FIndexDefs.GetIndexByField(Value); + if lIndexDef = nil then + IndexName := EmptyStr + else + IndexName := lIndexDef.IndexFile; +end; + +procedure TDbf.DeleteIndex(const AIndexName: string); +var + lIndexFileName: string; +begin + // extract absolute path if NDX file + lIndexFileName := ParseIndexName(AIndexName); + // try to delete index + FDbfFile.DeleteIndex(lIndexFileName); + + // refresh index defs + InternalInitFieldDefs; +end; + +procedure TDbf.OpenIndexFile(IndexFile: string); +var + lIndexFileName: string; +begin + CheckActive; + // make absolute path + lIndexFileName := GetCompleteFileName(FAbsolutePath, IndexFile); + // open index + FDbfFile.OpenIndex(lIndexFileName, '', false, []); +end; + +procedure TDbf.CloseIndexFile(const AIndexName: string); +var + lIndexFileName: string; +begin + CheckActive; + // make absolute path + lIndexFileName := GetCompleteFileName(FAbsolutePath, AIndexName); + // close this index + FDbfFile.CloseIndex(lIndexFileName); +end; + +procedure TDbf.RepageIndexFile(const AIndexFile: string); +begin + if FDbfFile <> nil then + FDbfFile.RepageIndex(ParseIndexName(AIndexFile)); +end; + +procedure TDbf.CompactIndexFile(const AIndexFile: string); +begin + if FDbfFile <> nil then + FDbfFile.CompactIndex(ParseIndexName(AIndexFile)); +end; + +procedure TDbf.GetFileNames(Strings: TStrings; Files: TDbfFileNames); +var + I: Integer; +begin + Strings.Clear; + if FDbfFile <> nil then + begin + if dfDbf in Files then + Strings.Add(FDbfFile.FileName); + if (dfMemo in Files) and (FDbfFile.MemoFile <> nil) then + Strings.Add(FDbfFile.MemoFile.FileName); + if dfIndex in Files then + for I := 0 to Pred(FDbfFile.IndexFiles.Count) do + Strings.Add(TPagedFile(FDbfFile.IndexFiles.Items[I]).FileName); + end else + Strings.Add(IncludeTrailingPathDelimiter(FilePathFull) + TableName); +end; + +{$ifdef SUPPORT_DEFAULT_PARAMS} +function TDbf.GetFileNames(Files: TDbfFileNames (* = [dfDbf] *) ): string; +{$else} +function TDbf.GetFileNamesString(Files: TDbfFileNames ): string; +{$endif} +var + sl: TStrings; +begin + sl := TStringList.Create; + try + GetFileNames(sl, Files); + Result := sl.Text; + finally + sl.Free; + end; +end; + + + +procedure TDbf.GetIndexNames(Strings: TStrings); +begin + CheckActive; + Strings.Assign(DbfFile.IndexNames) +end; + +procedure TDbf.GetAllIndexFiles(Strings: TStrings); +var + SR: TSearchRec; +begin + CheckActive; + Strings.Clear; + if SysUtils.FindFirst(IncludeTrailingPathDelimiter(ExtractFilePath(FDbfFile.FileName)) + + '*.NDX', faAnyFile, SR) = 0 then + begin + repeat + Strings.Add(SR.Name); + until SysUtils.FindNext(SR)<>0; + SysUtils.FindClose(SR); + end; +end; + +function TDbf.GetPhysicalRecNo: Integer; +var + pBuffer: pointer; +begin + // check if active, test state: if inserting, then -1 + if (FCursor <> nil) and (State <> dsInsert) then + begin + if State = dsCalcFields then + pBuffer := CalcBuffer + else + pBuffer := ActiveBuffer; + Result := pDbfRecord(pBuffer)^.BookmarkData.PhysicalRecNo; + end else + Result := -1; +end; + +procedure TDbf.SetPhysicalRecNo(const NewRecNo: Integer); +begin + // editing? + CheckBrowseMode; + DoBeforeScroll; + FCursor.PhysicalRecNo := NewRecNo; + CursorPosChanged; + Resync([]); + DoAfterScroll; +end; + +function TDbf.GetDbfFieldDefs: TDbfFieldDefs; +begin + if FDbfFile <> nil then + Result := FDbfFile.FieldDefs + else + Result := nil; +end; + +procedure TDbf.SetShowDeleted(Value: Boolean); +begin + // test if changed + if Value <> FShowDeleted then + begin + // store new value + FShowDeleted := Value; + // refresh view only if active + if FCursor <> nil then + Refresh; + end; +end; + +function TDbf.IsDeleted: Boolean; +var + src: TRecordBuffer; +begin + src := GetCurrentBuffer; + IsDeleted := (src=nil) or (AnsiChar(src^) = '*') +end; + +procedure TDbf.Undelete; +var + src: TRecordBuffer; +begin + if State <> dsEdit then + inherited Edit; + // get active buffer + src := GetCurrentBuffer; + if (src <> nil) and (AnsiChar(src^) = '*') then + begin + // notify indexes record is about to be recalled + FDbfFile.RecordRecalled(FCursor.PhysicalRecNo, src); + // recall record + src^ := TRecordBufferBaseType(' '); + FDbfFile.WriteRecord(FCursor.PhysicalRecNo, src); + end; +end; + +procedure TDbf.CancelRange; +begin + if FIndexFile = nil then + exit; + + // disable current range if any + FIndexFile.CancelRange; + // reretrieve previous and next records + Refresh; +end; + +procedure TDbf.SetRangeBuffer(LowRange: PChar; HighRange: PChar); +begin + if FIndexFile = nil then + exit; + + FIndexFile.SetRange(LowRange, HighRange); + // go to first in this range + if Active then + inherited First; +end; + +{$ifdef SUPPORT_VARIANTS} + +procedure TDbf.SetRange(LowRange: Variant; HighRange: Variant; KeyIsANSI: boolean); +var + LowBuf, HighBuf: array[0..100] of Char; +begin + if (FIndexFile = nil) or VarIsNull(LowRange) or VarIsNull(HighRange) then + exit; + + // convert variants to index key type + if (TIndexCursor(FCursor).VariantToBuffer(LowRange, @LowBuf[0]) = etString) and KeyIsANSI then + Translate(@LowBuf[0], @LowBuf[0], true); + if (TIndexCursor(FCursor).VariantToBuffer(HighRange, @HighBuf[0]) = etString) and KeyIsANSI then + Translate(@HighBuf[0], @HighBuf[0], true); + SetRangeBuffer(@LowBuf[0], @HighBuf[0]); +end; + +{$endif} + +procedure TDbf.SetRangePChar(LowRange: PChar; HighRange: PChar; KeyIsANSI: boolean); +var + LowBuf, HighBuf: array [0..100] of Char; + LowPtr, HighPtr: PChar; +begin + if FIndexFile = nil then + exit; + + // convert to pchars + if KeyIsANSI then + begin + Translate(LowRange, @LowBuf[0], true); + Translate(HighRange, @HighBuf[0], true); + LowRange := @LowBuf[0]; + HighRange := @HighBuf[0]; + end; + LowPtr := TIndexCursor(FCursor).CheckUserKey(LowRange, @LowBuf[0]); + HighPtr := TIndexCursor(FCursor).CheckUserKey(HighRange, @HighBuf[0]); + SetRangeBuffer(LowPtr, HighPtr); +end; + +procedure TDbf.ExtractKey(KeyBuffer: PChar); +begin + if FIndexFile <> nil then + StrCopy(FIndexFile.ExtractKeyFromBuffer(GetCurrentBuffer), KeyBuffer) + else + KeyBuffer[0] := #0; +end; + +function TDbf.GetKeySize: Integer; +begin + if FCursor is TIndexCursor then + Result := TIndexCursor(FCursor).IndexFile.KeyLen + else + Result := 0; +end; + +{$ifdef SUPPORT_VARIANTS} + +function TDbf.SearchKey(Key: Variant; SearchType: TSearchKeyType; KeyIsANSI: boolean): Boolean; +var + TempBuffer: array [0..100] of Char; +begin + if (FIndexFile = nil) or VarIsNull(Key) then + begin + Result := false; + exit; + end; + + // FIndexFile <> nil -> FCursor as TIndexCursor <> nil + if (TIndexCursor(FCursor).VariantToBuffer(Key, @TempBuffer[0]) = etString) and KeyIsANSI then + Translate(@TempBuffer[0], @TempBuffer[0], true); + Result := SearchKeyBuffer(@TempBuffer[0], SearchType); +end; + +{$endif} + +function TDbf.PrepareKey(Buffer: Pointer; BufferType: TExpressionType): PChar; +begin + if FIndexFile = nil then + begin + Result := nil; + exit; + end; + + Result := TIndexCursor(FCursor).IndexFile.PrepareKey(Buffer, BufferType); +end; + +function TDbf.SearchKeyPChar(Key: PChar; SearchType: TSearchKeyType; KeyIsANSI: boolean): Boolean; +var + StringBuf: array [0..100] of Char; +begin + if FCursor = nil then + begin + Result := false; + exit; + end; + + if KeyIsANSI then + begin + Translate(Key, @StringBuf[0], true); + Key := @StringBuf[0]; + end; + Result := SearchKeyBuffer(TIndexCursor(FCursor).CheckUserKey(Key, @StringBuf[0]), SearchType); +end; + +function TDbf.SearchKeyBuffer(Buffer: PChar; SearchType: TSearchKeyType): Boolean; +var + matchRes: Integer; +begin + if FIndexFile = nil then + begin + Result := false; + exit; + end; + + CheckBrowseMode; + Result := FIndexFile.SearchKey(Buffer, SearchType); + { if found, then retrieve new current record } + if Result then + begin + CursorPosChanged; + Resync([]); + UpdateCursorPos; + { recno could have been changed due to deleted record, check if still matches } + matchRes := TIndexCursor(FCursor).IndexFile.MatchKey(Buffer); + case SearchType of + stEqual: Result := matchRes = 0; + stGreater: Result := (not Eof) and (matchRes < 0); + stGreaterEqual: Result := (not Eof) and (matchRes <= 0); + end; + end; +end; + +procedure TDbf.UpdateIndexDefs; +begin + FieldDefs.Update; +end; + +// A hack to upgrade method visibility, only necessary for FPC 1.0.x + +{$ifdef VER1_0} + +procedure TDbf.DataEvent(Event: TDataEvent; Info: Longint); +begin + inherited; +end; + +{$endif} + +{ Master / Detail } + +procedure TDbf.CheckMasterRange; +begin + if FMasterLink.Active and FMasterLink.ValidExpression and (FIndexFile <> nil) then + UpdateRange; +end; + +procedure TDbf.UpdateRange; +var + fieldsVal: TRecordBuffer; + tempBuffer: array[0..300] of char; +begin + fieldsVal := FMasterLink.FieldsVal; + if (TDbf(FMasterLink.DataSet).DbfFile.UseCodePage <> FDbfFile.UseCodePage) + and (FMasterLink.Parser.ResultType = etString) then + begin + FMasterLink.DataSet.Translate(pansichar(fieldsVal), @tempBuffer[0], false); + fieldsVal := @tempBuffer[0]; + Translate(pansichar(fieldsVal), pansichar(fieldsVal), true); + end; + // preparekey, setrangebuffer and updatekeyfrom* are functions which arguments + // are not entirely classified in pchar<>trecordbuffer terms. + // so we typecast for now. + fieldsVal := TRecordBuffer(TIndexCursor(FCursor).IndexFile.PrepareKey((fieldsVal), FMasterLink.Parser.ResultType)); + SetRangeBuffer(pansichar(fieldsVal), pansichar(fieldsVal)); +end; + +procedure TDbf.MasterChanged(Sender: TObject); +begin + CheckBrowseMode; + CheckMasterRange; +end; + +procedure TDbf.MasterDisabled(Sender: TObject); +begin + CancelRange; +end; + +function TDbf.GetDataSource: TDataSource; +begin + Result := FMasterLink.DataSource; +end; + +procedure TDbf.SetDataSource(Value: TDataSource); +begin +{$ifndef FPC} + if IsLinkedTo(Value) then + begin +{$ifdef DELPHI_4} + DatabaseError(SCircularDataLink, Self); +{$else} + DatabaseError(SCircularDataLink); +{$endif} + end; +{$endif} + FMasterLink.DataSource := Value; +end; + +function TDbf.GetMasterFields: string; +begin + Result := FMasterLink.FieldNames; +end; + +procedure TDbf.SetMasterFields(const Value: string); +begin + FMasterLink.FieldNames := Value; +end; + +//========================================================== +//============ TDbfIndexDefs +//========================================================== +constructor TDbfIndexDefs.Create(AOwner: TDbf); +begin + inherited Create(TDbfIndexDef); + FOwner := AOwner; +end; + +function TDbfIndexDefs.Add: TDbfIndexDef; +begin + Result := TDbfIndexDef(inherited Add); +end; + +procedure TDbfIndexDefs.SetItem(N: Integer; Value: TDbfIndexDef); +begin + inherited SetItem(N, Value); +end; + +function TDbfIndexDefs.GetItem(N: Integer): TDbfIndexDef; +begin + Result := TDbfIndexDef(inherited GetItem(N)); +end; + +function TDbfIndexDefs.GetOwner: tpersistent; +begin + Result := FOwner; +end; + +function TDbfIndexDefs.GetIndexByName(const Name: string): TDbfIndexDef; +var + I: Integer; + lIndex: TDbfIndexDef; +begin + for I := 0 to Count-1 do + begin + lIndex := Items[I]; + if lIndex.IndexFile = Name then + begin + Result := lIndex; + exit; + end + end; + Result := nil; +end; + +function TDbfIndexDefs.GetIndexByField(const Name: string): TDbfIndexDef; +var + lIndex: TDbfIndexDef; + searchStr: string; + i: integer; +begin + searchStr := AnsiUpperCase(Trim(Name)); + Result := nil; + if searchStr = EmptyStr then + exit; + + for I := 0 to Count-1 do + begin + lIndex := Items[I]; + if AnsiUpperCase(Trim(lIndex.SortField)) = searchStr then + begin + Result := lIndex; + exit; + end + end; +end; + +procedure TDbfIndexDefs.Update; +begin + if Assigned(FOwner) then + FOwner.UpdateIndexDefs; +end; + +//========================================================== +//============ TDbfMasterLink +//========================================================== + +constructor TDbfMasterLink.Create(ADataSet: TDbf); +begin + inherited Create; + + FDetailDataSet := ADataSet; + FParser := TDbfParser.Create(nil); + FValidExpression := false; +end; + +destructor TDbfMasterLink.Destroy; +begin + FParser.Free; + + inherited; +end; + +procedure TDbfMasterLink.ActiveChanged; +begin + if Active and (FFieldNames <> EmptyStr) then + begin + FValidExpression := false; + FParser.DbfFile := (DataSet as TDbf).DbfFile; + FParser.ParseExpression(FFieldNames); + FValidExpression := true; + end else begin + FParser.ClearExpressions; + FValidExpression := false; + end; + + if FDetailDataSet.Active and not (csDestroying in FDetailDataSet.ComponentState) then + if Active then + begin + if Assigned(FOnMasterChange) then FOnMasterChange(Self); + end else + if Assigned(FOnMasterDisable) then FOnMasterDisable(Self); +end; + +procedure TDbfMasterLink.CheckBrowseMode; +begin + if FDetailDataSet.Active then + FDetailDataSet.CheckBrowseMode; +end; + +procedure TDbfMasterLink.LayoutChanged; +begin + ActiveChanged; +end; + +procedure TDbfMasterLink.RecordChanged(Field: TField); +begin + if (DataSource.State <> dsSetKey) and FDetailDataSet.Active and Assigned(FOnMasterChange) then + FOnMasterChange(Self); +end; + +procedure TDbfMasterLink.SetFieldNames(const Value: string); +begin + if FFieldNames <> Value then + begin + FFieldNames := Value; + ActiveChanged; + end; +end; + +function TDbfMasterLink.GetFieldsVal: TRecordBuffer; +begin + Result := TRecordBuffer(FParser.ExtractFromBuffer(@pDbfRecord(TDbf(DataSet).ActiveBuffer)^.DeletedFlag)); +end; + +//////////////////////////////////////////////////////////////////////////// + +function ApplicationPath: string; +begin + Result := ExtractFilePath(ParamStr(0)); +end; + + +//////////////////////////////////////////////////////////////////////////// + +initialization + + DbfBasePath := ApplicationPath; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/mdbf_prscore.pas b/mseide-msegui/lib/common/fpccompatibility/mdbf_prscore.pas new file mode 100644 index 0000000..35b6b1f --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mdbf_prscore.pas @@ -0,0 +1,2347 @@ +unit mdbf_prscore; + +{-------------------------------------------------------------- +| TCustomExpressionParser +| +| - contains core expression parser +| +| This code is based on code from: +| +| Original author: Egbert van Nes +| With contributions of: John Bultena and Ralf Junker +| Homepage: http://www.slm.wau.nl/wkao/parseexpr.html +| +| see also: http://www.datalog.ro/delphi/parser.html +| (Renate Schaaf (schaaf at math.usu.edu), 1993 +| Alin Flaider (aflaidar at datalog.ro), 1996 +| Version 9-10: Stefan Hoffmeister, 1996-1997) +| +| Modified 2013 by Martin Schreiber +| +|---------------------------------------------------------------} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$I dbf_common.inc} + +uses + SysUtils, + classes,mclasses, + mdb, + mdbf_prssupp, + mdbf_prsdef; + +{$define ENG_NUMBERS} + +// ENG_NUMBERS will force the use of english style numbers 8.1 instead of 8,1 +// (if the comma is your decimal separator) +// the advantage is that arguments can be separated with a comma which is +// fairly common, otherwise there is ambuigity: what does 'var1,8,4,4,5' mean? +// if you don't define ENG_NUMBERS and DecimalSeparator is a comma then +// the argument separator will be a semicolon ';' + +type + + TCustomExpressionParser = class(TObject) + private + FHexChar: Char; + FArgSeparator: Char; + FDecimalSeparator: Char; + FOptimize: Boolean; + FConstantsList: TOCollection; + FLastRec: PExpressionRec; + FCurrentRec: PExpressionRec; + FExpResult: PChar; + FExpResultPos: PChar; + FExpResultSize: Integer; + + procedure ParseString(AnExpression: string; DestCollection: TExprCollection); + function MakeTree(Expr: TExprCollection; FirstItem, LastItem: Integer): PExpressionRec; + procedure MakeLinkedList(var ExprRec: PExpressionRec; Memory: PPChar; + MemoryPos: PPChar; MemSize: PInteger); + procedure Check(AnExprList: TExprCollection); + procedure CheckArguments(ExprRec: PExpressionRec); + procedure RemoveConstants(var ExprRec: PExpressionRec); + function ResultCanVary(ExprRec: PExpressionRec): Boolean; + protected + FWordsList: TSortedCollection; + + function MakeRec: PExpressionRec; virtual; + procedure FillExpressList; virtual; abstract; + procedure HandleUnknownVariable(VarName: string); virtual; abstract; + + procedure CompileExpression(AnExpression: string); + procedure EvaluateCurrent; + procedure DisposeList(ARec: PExpressionRec); + procedure DisposeTree(ExprRec: PExpressionRec); + function CurrentExpression: string; virtual; abstract; + function GetResultType: TExpressionType; virtual; + + property CurrentRec: PExpressionRec read FCurrentRec write FCurrentRec; + property LastRec: PExpressionRec read FLastRec write FLastRec; + property ExpResult: PChar read FExpResult; + property ExpResultPos: PChar read FExpResultPos write FExpResultPos; + + public + constructor Create; + destructor Destroy; override; + + function DefineFloatVariable(AVarName: string; AValue: PDouble): TExprWord; + function DefineIntegerVariable(AVarName: string; AValue: PInteger): TExprWord; +// procedure DefineSmallIntVariable(AVarName: string; AValue: PSmallInt); +{$ifdef SUPPORT_INT64} + function DefineLargeIntVariable(AVarName: string; AValue: PLargeInt): TExprWord; +{$endif} + function DefineDateTimeVariable(AVarName: string; AValue: PDateTimeRec): TExprWord; + function DefineBooleanVariable(AVarName: string; AValue: PBoolean): TExprWord; + function DefineStringVariable(AVarName: string; AValue: PPChar): TExprWord; + function DefineFunction(AFunctName, AShortName, ADescription, ATypeSpec: string; + AMinFunctionArg: Integer; AResultType: TExpressionType; AFuncAddress: TExprFunc): TExprWord; + procedure Evaluate(AnExpression: string); + function AddExpression(AnExpression: string): Integer; + procedure ClearExpressions; virtual; +// procedure GetGeneratedVars(AList: TList); + procedure GetFunctionNames(AList: TStrings); + function GetFunctionDescription(AFunction: string): string; + property HexChar: Char read FHexChar write FHexChar; + property ArgSeparator: Char read FArgSeparator write FArgSeparator; + property Optimize: Boolean read FOptimize write FOptimize; + property ResultType: TExpressionType read GetResultType; + + + //if optimize is selected, constant expressions are tried to remove + //such as: 4*4*x is evaluated as 16*x and exp(1)-4*x is repaced by 2.17 -4*x + end; + + +//--Expression functions----------------------------------------------------- + +procedure FuncFloatToStr(Param: PExpressionRec); +procedure FuncIntToStr_Gen(Param: PExpressionRec; Val: {$ifdef SUPPORT_INT64}Int64{$else}Integer{$endif}); +procedure FuncIntToStr(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure FuncInt64ToStr(Param: PExpressionRec); +{$endif} +procedure FuncDateToStr(Param: PExpressionRec); +procedure FuncSubString(Param: PExpressionRec); +procedure FuncUppercase(Param: PExpressionRec); +procedure FuncLowercase(Param: PExpressionRec); +procedure FuncAdd_F_FF(Param: PExpressionRec); +procedure FuncAdd_F_FI(Param: PExpressionRec); +procedure FuncAdd_F_II(Param: PExpressionRec); +procedure FuncAdd_F_IF(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure FuncAdd_F_FL(Param: PExpressionRec); +procedure FuncAdd_F_IL(Param: PExpressionRec); +procedure FuncAdd_F_LL(Param: PExpressionRec); +procedure FuncAdd_F_LF(Param: PExpressionRec); +procedure FuncAdd_F_LI(Param: PExpressionRec); +{$endif} +procedure FuncSub_F_FF(Param: PExpressionRec); +procedure FuncSub_F_FI(Param: PExpressionRec); +procedure FuncSub_F_II(Param: PExpressionRec); +procedure FuncSub_F_IF(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure FuncSub_F_FL(Param: PExpressionRec); +procedure FuncSub_F_IL(Param: PExpressionRec); +procedure FuncSub_F_LL(Param: PExpressionRec); +procedure FuncSub_F_LF(Param: PExpressionRec); +procedure FuncSub_F_LI(Param: PExpressionRec); +{$endif} +procedure FuncMul_F_FF(Param: PExpressionRec); +procedure FuncMul_F_FI(Param: PExpressionRec); +procedure FuncMul_F_II(Param: PExpressionRec); +procedure FuncMul_F_IF(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure FuncMul_F_FL(Param: PExpressionRec); +procedure FuncMul_F_IL(Param: PExpressionRec); +procedure FuncMul_F_LL(Param: PExpressionRec); +procedure FuncMul_F_LF(Param: PExpressionRec); +procedure FuncMul_F_LI(Param: PExpressionRec); +{$endif} +procedure FuncDiv_F_FF(Param: PExpressionRec); +procedure FuncDiv_F_FI(Param: PExpressionRec); +procedure FuncDiv_F_II(Param: PExpressionRec); +procedure FuncDiv_F_IF(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure FuncDiv_F_FL(Param: PExpressionRec); +procedure FuncDiv_F_IL(Param: PExpressionRec); +procedure FuncDiv_F_LL(Param: PExpressionRec); +procedure FuncDiv_F_LF(Param: PExpressionRec); +procedure FuncDiv_F_LI(Param: PExpressionRec); +{$endif} +procedure FuncStrI_EQ(Param: PExpressionRec); +procedure FuncStrI_NEQ(Param: PExpressionRec); +procedure FuncStrI_LT(Param: PExpressionRec); +procedure FuncStrI_GT(Param: PExpressionRec); +procedure FuncStrI_LTE(Param: PExpressionRec); +procedure FuncStrI_GTE(Param: PExpressionRec); +procedure FuncStrIP_EQ(Param: PExpressionRec); +procedure FuncStrP_EQ(Param: PExpressionRec); +procedure FuncStr_EQ(Param: PExpressionRec); +procedure FuncStr_NEQ(Param: PExpressionRec); +procedure FuncStr_LT(Param: PExpressionRec); +procedure FuncStr_GT(Param: PExpressionRec); +procedure FuncStr_LTE(Param: PExpressionRec); +procedure FuncStr_GTE(Param: PExpressionRec); +procedure Func_FF_EQ(Param: PExpressionRec); +procedure Func_FF_NEQ(Param: PExpressionRec); +procedure Func_FF_LT(Param: PExpressionRec); +procedure Func_FF_GT(Param: PExpressionRec); +procedure Func_FF_LTE(Param: PExpressionRec); +procedure Func_FF_GTE(Param: PExpressionRec); +procedure Func_FI_EQ(Param: PExpressionRec); +procedure Func_FI_NEQ(Param: PExpressionRec); +procedure Func_FI_LT(Param: PExpressionRec); +procedure Func_FI_GT(Param: PExpressionRec); +procedure Func_FI_LTE(Param: PExpressionRec); +procedure Func_FI_GTE(Param: PExpressionRec); +procedure Func_II_EQ(Param: PExpressionRec); +procedure Func_II_NEQ(Param: PExpressionRec); +procedure Func_II_LT(Param: PExpressionRec); +procedure Func_II_GT(Param: PExpressionRec); +procedure Func_II_LTE(Param: PExpressionRec); +procedure Func_II_GTE(Param: PExpressionRec); +procedure Func_IF_EQ(Param: PExpressionRec); +procedure Func_IF_NEQ(Param: PExpressionRec); +procedure Func_IF_LT(Param: PExpressionRec); +procedure Func_IF_GT(Param: PExpressionRec); +procedure Func_IF_LTE(Param: PExpressionRec); +procedure Func_IF_GTE(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure Func_LL_EQ(Param: PExpressionRec); +procedure Func_LL_NEQ(Param: PExpressionRec); +procedure Func_LL_LT(Param: PExpressionRec); +procedure Func_LL_GT(Param: PExpressionRec); +procedure Func_LL_LTE(Param: PExpressionRec); +procedure Func_LL_GTE(Param: PExpressionRec); +procedure Func_LF_EQ(Param: PExpressionRec); +procedure Func_LF_NEQ(Param: PExpressionRec); +procedure Func_LF_LT(Param: PExpressionRec); +procedure Func_LF_GT(Param: PExpressionRec); +procedure Func_LF_LTE(Param: PExpressionRec); +procedure Func_LF_GTE(Param: PExpressionRec); +procedure Func_FL_EQ(Param: PExpressionRec); +procedure Func_FL_NEQ(Param: PExpressionRec); +procedure Func_FL_LT(Param: PExpressionRec); +procedure Func_FL_GT(Param: PExpressionRec); +procedure Func_FL_LTE(Param: PExpressionRec); +procedure Func_FL_GTE(Param: PExpressionRec); +procedure Func_LI_EQ(Param: PExpressionRec); +procedure Func_LI_NEQ(Param: PExpressionRec); +procedure Func_LI_LT(Param: PExpressionRec); +procedure Func_LI_GT(Param: PExpressionRec); +procedure Func_LI_LTE(Param: PExpressionRec); +procedure Func_LI_GTE(Param: PExpressionRec); +procedure Func_IL_EQ(Param: PExpressionRec); +procedure Func_IL_NEQ(Param: PExpressionRec); +procedure Func_IL_LT(Param: PExpressionRec); +procedure Func_IL_GT(Param: PExpressionRec); +procedure Func_IL_LTE(Param: PExpressionRec); +procedure Func_IL_GTE(Param: PExpressionRec); +{$endif} +procedure Func_AND(Param: PExpressionRec); +procedure Func_OR(Param: PExpressionRec); +procedure Func_NOT(Param: PExpressionRec); + +var + DbfWordsSensGeneralList, DbfWordsInsensGeneralList: TExpressList; + DbfWordsSensPartialList, DbfWordsInsensPartialList: TExpressList; + DbfWordsSensNoPartialList, DbfWordsInsensNoPartialList: TExpressList; + DbfWordsGeneralList: TExpressList; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure LinkVariable(ExprRec: PExpressionRec); +begin + with ExprRec^ do + begin + if ExprWord.IsVariable then + begin + // copy pointer to variable + Args[0] := ExprWord.AsPointer; + // store length as second parameter + Args[1] := PChar(ExprWord.LenAsPointer); + end; + end; +end; + +procedure LinkVariables(ExprRec: PExpressionRec); +var + I: integer; +begin + with ExprRec^ do + begin + I := 0; + while (I < MaxArg) and (ArgList[I] <> nil) do + begin + LinkVariables(ArgList[I]); + Inc(I); + end; + end; + LinkVariable(ExprRec); +end; + +{ TCustomExpressionParser } + +constructor TCustomExpressionParser.Create; +begin + inherited; + + FHexChar := '$'; +{$IFDEF ENG_NUMBERS} + FDecimalSeparator := '.'; + FArgSeparator := ','; +{$ELSE} + FDecimalSeparator := DecimalSeparator; + if DecimalSeparator = ',' then + FArgSeparator := ';' + else + FArgSeparator := ','; +{$ENDIF} + FConstantsList := TOCollection.Create; + FWordsList := TExpressList.Create; + GetMem(FExpResult, ArgAllocSize); + FExpResultPos := FExpResult; + FExpResultSize := ArgAllocSize; + FOptimize := true; + FillExpressList; +end; + +destructor TCustomExpressionParser.Destroy; +begin + ClearExpressions; + FreeMem(FExpResult); + FConstantsList.Free; + FWordsList.Free; + + inherited; +end; + +procedure TCustomExpressionParser.CompileExpression(AnExpression: string); +var + ExpColl: TExprCollection; + ExprTree: PExpressionRec; +begin + if Length(AnExpression) > 0 then + begin + ExprTree := nil; + ExpColl := TExprCollection.Create; + try + // FCurrentExpression := anExpression; + ParseString(AnExpression, ExpColl); + Check(ExpColl); + ExprTree := MakeTree(ExpColl, 0, ExpColl.Count - 1); + FCurrentRec := nil; + CheckArguments(ExprTree); + LinkVariables(ExprTree); + if Optimize then + RemoveConstants(ExprTree); + // all constant expressions are evaluated and replaced by variables + FCurrentRec := nil; + FExpResultPos := FExpResult; + MakeLinkedList(ExprTree, @FExpResult, @FExpResultPos, @FExpResultSize); + except + on E: Exception do + begin + DisposeTree(ExprTree); + ExpColl.Free; + raise; + end; + end; + ExpColl.Free; + end; +end; + +procedure TCustomExpressionParser.CheckArguments(ExprRec: PExpressionRec); +var + TempExprWord: TExprWord; + I, error, firstFuncIndex, funcIndex: Integer; + foundAltFunc: Boolean; + + procedure FindAlternate; + begin + // see if we can find another function + if funcIndex < 0 then + begin + firstFuncIndex := FWordsList.IndexOf(ExprRec^.ExprWord); + funcIndex := firstFuncIndex; + end; + // check if not last function + if (0 <= funcIndex) and (funcIndex < FWordsList.Count - 1) then + begin + inc(funcIndex); + TempExprWord := TExprWord(FWordsList.Items[funcIndex]); + if FWordsList.Compare(FWordsList.KeyOf(ExprRec^.ExprWord), FWordsList.KeyOf(TempExprWord)) = 0 then + begin + ExprRec^.ExprWord := TempExprWord; + ExprRec^.Oper := ExprRec^.ExprWord.ExprFunc; + foundAltFunc := true; + end; + end; + end; + + procedure InternalCheckArguments; + begin + I := 0; + error := 0; + foundAltFunc := false; + with ExprRec^ do + begin + if WantsFunction <> (ExprWord.IsFunction and not ExprWord.IsOperator) then + begin + error := 4; + exit; + end; + + while (I < ExprWord.MaxFunctionArg) and (ArgList[I] <> nil) and (error = 0) do + begin + // test subarguments first + CheckArguments(ArgList[I]); + + // test if correct type + if (ArgList[I]^.ExprWord.ResultType <> ExprCharToExprType(ExprWord.TypeSpec[I+1])) then + error := 2; + + // goto next argument + Inc(I); + end; + + // test if enough parameters passed; I = num args user passed + if (error = 0) and (I < ExprWord.MinFunctionArg) then + error := 1; + + // test if too many parameters passed + if (error = 0) and (I > ExprWord.MaxFunctionArg) then + error := 3; + end; + end; + +begin + funcIndex := -1; + repeat + InternalCheckArguments; + + // error occurred? + if error <> 0 then + FindAlternate; + until (error = 0) or not foundAltFunc; + + // maybe it's an undefined variable + if (error <> 0) and not ExprRec^.WantsFunction and (firstFuncIndex >= 0) then + begin + HandleUnknownVariable(ExprRec^.ExprWord.Name); + { must not add variable as first function in this set of duplicates, + otherwise following searches will not find it } + FWordsList.Exchange(firstFuncIndex, firstFuncIndex+1); + ExprRec^.ExprWord := TExprWord(FWordsList.Items[firstFuncIndex+1]); + ExprRec^.Oper := ExprRec^.ExprWord.ExprFunc; + InternalCheckArguments; + end; + + // fatal error? + case error of + 1: raise EParserException.Create('Function or operand has too few arguments'); + 2: raise EParserException.Create('Argument type mismatch'); + 3: raise EParserException.Create('Function or operand has too many arguments'); + 4: raise EParserException.Create('No function with this name, remove brackets for variable'); + end; +end; + +function TCustomExpressionParser.ResultCanVary(ExprRec: PExpressionRec): + Boolean; +var + I: Integer; +begin + with ExprRec^ do + begin + Result := ExprWord.CanVary; + if not Result then + for I := 0 to ExprWord.MaxFunctionArg - 1 do + if (ArgList[I] <> nil) and ResultCanVary(ArgList[I]) then + begin + Result := true; + Exit; + end + end; +end; + +procedure TCustomExpressionParser.RemoveConstants(var ExprRec: PExpressionRec); +var + I: Integer; +begin + if not ResultCanVary(ExprRec) then + begin + if not ExprRec^.ExprWord.IsVariable then + begin + // reset current record so that make list generates new + FCurrentRec := nil; + FExpResultPos := FExpResult; + MakeLinkedList(ExprRec, @FExpResult, @FExpResultPos, @FExpResultSize); + + try + // compute result + EvaluateCurrent; + + // make new record to store constant in + ExprRec := MakeRec; + + // check result type + with ExprRec^ do + begin + case ResultType of + etBoolean: ExprWord := TBooleanConstant.Create(EmptyStr, PBoolean(FExpResult)^); + etFloat: ExprWord := TFloatConstant.CreateAsDouble(EmptyStr, PDouble(FExpResult)^); + etString: ExprWord := TStringConstant.Create(FExpResult); + end; + + // fill in structure + Oper := ExprWord.ExprFunc; + Args[0] := ExprWord.AsPointer; + FConstantsList.Add(ExprWord); + end; + finally + DisposeList(FCurrentRec); + FCurrentRec := nil; + end; + end; + end else + with ExprRec^ do + begin + for I := 0 to ExprWord.MaxFunctionArg - 1 do + if ArgList[I] <> nil then + RemoveConstants(ArgList[I]); + end; +end; + +procedure TCustomExpressionParser.DisposeTree(ExprRec: PExpressionRec); +var + I: Integer; +begin + if ExprRec <> nil then + begin + with ExprRec^ do + begin + if ExprWord <> nil then + for I := 0 to ExprWord.MaxFunctionArg - 1 do + DisposeTree(ArgList[I]); + if Res <> nil then + Res.Free; + end; + Dispose(ExprRec); + end; +end; + +procedure TCustomExpressionParser.DisposeList(ARec: PExpressionRec); +var + TheNext: PExpressionRec; + I: Integer; +begin + if ARec <> nil then + repeat + TheNext := ARec^.Next; + if ARec^.Res <> nil then + ARec^.Res.Free; + I := 0; + while ARec^.ArgList[I] <> nil do + begin + FreeMem(ARec^.Args[I]); + Inc(I); + end; + Dispose(ARec); + ARec := TheNext; + until ARec = nil; +end; + +procedure TCustomExpressionParser.MakeLinkedList(var ExprRec: PExpressionRec; + Memory: PPChar; MemoryPos: PPChar; MemSize: PInteger); +var + I: Integer; +begin + // test function type + if @ExprRec^.ExprWord.ExprFunc = nil then + begin + // special 'no function' function + // indicates no function is present -> we can concatenate all instances + // we don't create new arguments...these 'fall' through + // use destination as we got it + I := 0; + while ExprRec^.ArgList[I] <> nil do + begin + // convert arguments to list + MakeLinkedList(ExprRec^.ArgList[I], Memory, MemoryPos, MemSize); + // goto next argument + Inc(I); + end; + // don't need this record anymore + Dispose(ExprRec); + ExprRec := nil; + end else begin + // inc memory pointer so we know if we are first + ExprRec^.ResetDest := MemoryPos^ = Memory^; + Inc(MemoryPos^); + // convert arguments to list + I := 0; + while ExprRec^.ArgList[I] <> nil do + begin + // save variable type for easy access + ExprRec^.ArgsType[I] := ExprRec^.ArgList[I]^.ExprWord.ResultType; + // check if we need to copy argument, variables in general do not + // need copying, except for fixed len strings which are not + // null-terminated +// if ExprRec^.ArgList[I].ExprWord.NeedsCopy then +// begin + // get memory for argument + GetMem(ExprRec^.Args[I], ArgAllocSize); + ExprRec^.ArgsPos[I] := ExprRec^.Args[I]; + ExprRec^.ArgsSize[I] := ArgAllocSize; + MakeLinkedList(ExprRec^.ArgList[I], @ExprRec^.Args[I], @ExprRec^.ArgsPos[I], + @ExprRec^.ArgsSize[I]); +// end else begin + // copy reference +// ExprRec^.Args[I] := ExprRec^.ArgList[I].Args[0]; +// ExprRec^.ArgsPos[I] := ExprRec^.Args[I]; +// ExprRec^.ArgsSize[I] := 0; +// FreeMem(ExprRec^.ArgList[I]); +// ExprRec^.ArgList[I] := nil; +// end; + + // goto next argument + Inc(I); + end; + + // link result to target argument + ExprRec^.Res := TDynamicType.Create(Memory, MemoryPos, MemSize); + + // link to next operation + if FCurrentRec = nil then + begin + FCurrentRec := ExprRec; + FLastRec := ExprRec; + end else begin + FLastRec^.Next := ExprRec; + FLastRec := ExprRec; + end; + end; +end; + +function TCustomExpressionParser.MakeTree(Expr: TExprCollection; + FirstItem, LastItem: Integer): PExpressionRec; + +{ +- This is the most complex routine, it breaks down the expression and makes + a linked tree which is used for fast function evaluations +- it is implemented recursively +} + +var + I, IArg, IStart, IEnd, lPrec, brCount: Integer; + ExprWord: TExprWord; +begin + // remove redundant brackets + brCount := 0; + while (FirstItem+brCount < LastItem) and (TExprWord( + Expr.Items[FirstItem+brCount]).ResultType = etLeftBracket) do + Inc(brCount); + I := LastItem; + while (I > FirstItem) and (TExprWord( + Expr.Items[I]).ResultType = etRightBracket) do + Dec(I); + // test max of start and ending brackets + if brCount > (LastItem-I) then + brCount := LastItem-I; + // count number of bracket pairs completely open from start to end + // IArg is min.brCount + I := FirstItem + brCount; + IArg := brCount; + while (I <= LastItem - brCount) and (brCount > 0) do + begin + case TExprWord(Expr.Items[I]).ResultType of + etLeftBracket: Inc(brCount); + etRightBracket: + begin + Dec(brCount); + if brCount < IArg then + IArg := brCount; + end; + end; + Inc(I); + end; + // useful pair bracket count, is in minimum, is IArg + brCount := IArg; + // check if subexpression closed within (bracket level will be zero) + if brCount > 0 then + begin + Inc(FirstItem, brCount); + Dec(LastItem, brCount); + end; + + // check for empty range + if LastItem < FirstItem then + begin + Result := nil; + exit; + end; + + // get new record + Result := MakeRec; + + // simple constant, variable or function? + if LastItem = FirstItem then + begin + Result^.ExprWord := TExprWord(Expr.Items[FirstItem]); + Result^.Oper := Result^.ExprWord.ExprFunc; + exit; + end; + + // no...more complex, find operator with lowest precedence + brCount := 0; + IArg := 0; + IEnd := FirstItem-1; + lPrec := -1; + for I := FirstItem to LastItem do + begin + ExprWord := TExprWord(Expr.Items[I]); + if (brCount = 0) and ExprWord.IsOperator and (TFunction(ExprWord).OperPrec > lPrec) then + begin + IEnd := I; + lPrec := TFunction(ExprWord).OperPrec; + end; + case ExprWord.ResultType of + etLeftBracket: Inc(brCount); + etRightBracket: Dec(brCount); + end; + end; + + // operator found ? + if IEnd >= FirstItem then + begin + // save operator + Result^.ExprWord := TExprWord(Expr.Items[IEnd]); + Result^.Oper := Result^.ExprWord.ExprFunc; + // recurse into left part if present + if IEnd > FirstItem then + begin + Result^.ArgList[IArg] := MakeTree(Expr, FirstItem, IEnd-1); + Inc(IArg); + end; + // recurse into right part if present + if IEnd < LastItem then + Result^.ArgList[IArg] := MakeTree(Expr, IEnd+1, LastItem); + end else + if TExprWord(Expr.Items[FirstItem]).IsFunction then + begin + // save function + Result^.ExprWord := TExprWord(Expr.Items[FirstItem]); + Result^.Oper := Result^.ExprWord.ExprFunc; + Result^.WantsFunction := true; + // parse function arguments + IEnd := FirstItem + 1; + IStart := IEnd; + brCount := 0; + if TExprWord(Expr.Items[IEnd]).ResultType = etLeftBracket then + begin + // opening bracket found, first argument expression starts at next index + Inc(brCount); + Inc(IStart); + while (IEnd < LastItem) and (brCount <> 0) do + begin + Inc(IEnd); + case TExprWord(Expr.Items[IEnd]).ResultType of + etLeftBracket: Inc(brCount); + etComma: + if brCount = 1 then + begin + // argument separation found, build tree of argument expression + Result^.ArgList[IArg] := MakeTree(Expr, IStart, IEnd-1); + Inc(IArg); + IStart := IEnd + 1; + end; + etRightBracket: Dec(brCount); + end; + end; + + // parse last argument + Result^.ArgList[IArg] := MakeTree(Expr, IStart, IEnd-1); + end; + end else + raise EParserException.Create('Operator/function missing'); +end; + +procedure TCustomExpressionParser.ParseString(AnExpression: string; DestCollection: TExprCollection); +var + isConstant: Boolean; + I, I1, I2, Len, DecSep: Integer; + W, S: string; + TempWord: TExprWord; + + procedure ReadConstant(AnExpr: string; isHex: Boolean); + begin + isConstant := true; + while (I2 <= Len) and ((AnExpr[I2] in ['0'..'9']) or + (isHex and (AnExpr[I2] in ['a'..'f', 'A'..'F']))) do + Inc(I2); + if I2 <= Len then + begin + if AnExpr[I2] = FDecimalSeparator then + begin + Inc(I2); + while (I2 <= Len) and (AnExpr[I2] in ['0'..'9']) do + Inc(I2); + end; + if (I2 <= Len) and (AnExpr[I2] = 'e') then + begin + Inc(I2); + if (I2 <= Len) and (AnExpr[I2] in ['+', '-']) then + Inc(I2); + while (I2 <= Len) and (AnExpr[I2] in ['0'..'9']) do + Inc(I2); + end; + end; + end; + + procedure ReadWord(AnExpr: string); + var + OldI2: Integer; + constChar: Char; + begin + isConstant := false; + I1 := I2; + while (I1 < Len) and (AnExpr[I1] = ' ') do + Inc(I1); + I2 := I1; + if I1 <= Len then + begin + if AnExpr[I2] = HexChar then + begin + Inc(I2); + OldI2 := I2; + ReadConstant(AnExpr, true); + if I2 = OldI2 then + begin + isConstant := false; + while (I2 <= Len) and (AnExpr[I2] in ['a'..'z', 'A'..'Z', '_', '0'..'9']) do + Inc(I2); + end; + end + else if AnExpr[I2] = FDecimalSeparator then + ReadConstant(AnExpr, false) + else + case AnExpr[I2] of + '''', '"': + begin + isConstant := true; + constChar := AnExpr[I2]; + Inc(I2); + while (I2 <= Len) and (AnExpr[I2] <> constChar) do + Inc(I2); + if I2 <= Len then + Inc(I2); + end; + 'a'..'z', 'A'..'Z', '_': + begin + while (I2 <= Len) and (AnExpr[I2] in ['a'..'z', 'A'..'Z', '_', '0'..'9']) do + Inc(I2); + end; + '>', '<': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] in ['=', '<', '>'] then + Inc(I2); + end; + '=': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] in ['<', '>', '='] then + Inc(I2); + end; + '&': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] in ['&'] then + Inc(I2); + end; + '|': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] in ['|'] then + Inc(I2); + end; + ':': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] = '=' then + Inc(I2); + end; + '!': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] = '=' then //support for != + Inc(I2); + end; + '+': + begin + Inc(I2); + if (AnExpr[I2] = '+') and FWordsList.Search(PChar('++'), I) then + Inc(I2); + end; + '-': + begin + Inc(I2); + if (AnExpr[I2] = '-') and FWordsList.Search(PChar('--'), I) then + Inc(I2); + end; + '^', '/', '\', '*', '(', ')', '%', '~', '$': + Inc(I2); + '0'..'9': + ReadConstant(AnExpr, false); + else + begin + Inc(I2); + end; + end; + end; + end; + +begin + I2 := 1; + S := Trim(AnExpression); + Len := Length(S); + repeat + ReadWord(S); + W := Trim(Copy(S, I1, I2 - I1)); + if isConstant then + begin + if W[1] = HexChar then + begin + // convert hexadecimal to decimal + W[1] := '$'; + W := IntToStr(StrToInt(W)); + end; + if (W[1] = '''') or (W[1] = '"') then + TempWord := TStringConstant.Create(W) + else begin + DecSep := Pos(FDecimalSeparator, W); + if (DecSep > 0) then + begin +{$IFDEF ENG_NUMBERS} + // we'll have to convert FDecimalSeparator into DecimalSeparator + // otherwise the OS will not understand what we mean + W[DecSep] := DefaultFormatSettings.DecimalSeparator; +{$ENDIF} + TempWord := TFloatConstant.Create(W, W) + end else begin + TempWord := TIntegerConstant.Create(StrToInt(W)); + end; + end; + DestCollection.Add(TempWord); + FConstantsList.Add(TempWord); + end + else if Length(W) > 0 then + if FWordsList.Search(PChar(W), I) then + begin + DestCollection.Add(FWordsList.Items[I]) + end else begin + // unknown variable -> fire event + HandleUnknownVariable(W); + // try to search again + if FWordsList.Search(PChar(W), I) then + begin + DestCollection.Add(FWordsList.Items[I]) + end else begin + raise EParserException.Create('Unknown variable '''+W+''' found.'); + end; + end; + until I2 > Len; +end; + +procedure TCustomExpressionParser.Check(AnExprList: TExprCollection); +var + I, J, K, L: Integer; +begin + AnExprList.Check; + with AnExprList do + begin + I := 0; + while I < Count do + begin + {----CHECK ON DOUBLE MINUS OR DOUBLE PLUS----} + if ((TExprWord(Items[I]).Name = '-') or + (TExprWord(Items[I]).Name = '+')) + and ((I = 0) or + (TExprWord(Items[I - 1]).ResultType = etComma) or + (TExprWord(Items[I - 1]).ResultType = etLeftBracket) or + (TExprWord(Items[I - 1]).IsOperator and (TExprWord(Items[I - 1]).MaxFunctionArg + = 2))) then + begin + {replace e.g. ----1 with +1} + if TExprWord(Items[I]).Name = '-' then + K := -1 + else + K := 1; + L := 1; + while (I + L < Count) and ((TExprWord(Items[I + L]).Name = '-') + or (TExprWord(Items[I + L]).Name = '+')) and ((I + L = 0) or + (TExprWord(Items[I + L - 1]).ResultType = etComma) or + (TExprWord(Items[I + L - 1]).ResultType = etLeftBracket) or + (TExprWord(Items[I + L - 1]).IsOperator and (TExprWord(Items[I + L - + 1]).MaxFunctionArg = 2))) do + begin + if TExprWord(Items[I + L]).Name = '-' then + K := -1 * K; + Inc(L); + end; + if L > 0 then + begin + Dec(L); + for J := I + 1 to Count - 1 - L do + Items[J] := Items[J + L]; + Count := Count - L; + end; + if K = -1 then + begin + if FWordsList.Search(pchar('-@'), J) then + Items[I] := FWordsList.Items[J]; + end + else if FWordsList.Search(pchar('+@'), J) then + Items[I] := FWordsList.Items[J]; + end; + {----CHECK ON DOUBLE NOT----} + if (TExprWord(Items[I]).Name = 'not') + and ((I = 0) or + (TExprWord(Items[I - 1]).ResultType = etLeftBracket) or + TExprWord(Items[I - 1]).IsOperator) then + begin + {replace e.g. not not 1 with 1} + K := -1; + L := 1; + while (I + L < Count) and (TExprWord(Items[I + L]).Name = 'not') and ((I + + L = 0) or + (TExprWord(Items[I + L - 1]).ResultType = etLeftBracket) or + TExprWord(Items[I + L - 1]).IsOperator) do + begin + K := -K; + Inc(L); + end; + if L > 0 then + begin + if K = 1 then + begin //remove all + for J := I to Count - 1 - L do + Items[J] := Items[J + L]; + Count := Count - L; + end + else + begin //keep one + Dec(L); + for J := I + 1 to Count - 1 - L do + Items[J] := Items[J + L]; + Count := Count - L; + end + end; + end; + {-----MISC CHECKS-----} + if (TExprWord(Items[I]).IsVariable) and ((I < Count - 1) and + (TExprWord(Items[I + 1]).IsVariable)) then + raise EParserException.Create('Missing operator between '''+TExprWord(Items[I]).Name+''' and '''+TExprWord(Items[I]).Name+''''); + if (TExprWord(Items[I]).ResultType = etLeftBracket) and (I >= Count - 1) then + raise EParserException.Create('Missing closing bracket'); + if (TExprWord(Items[I]).ResultType = etRightBracket) and ((I < Count - 1) and + (TExprWord(Items[I + 1]).ResultType = etLeftBracket)) then + raise EParserException.Create('Missing operator between )('); + if (TExprWord(Items[I]).ResultType = etRightBracket) and ((I < Count - 1) and + (TExprWord(Items[I + 1]).IsVariable)) then + raise EParserException.Create('Missing operator between ) and constant/variable'); + if (TExprWord(Items[I]).ResultType = etLeftBracket) and ((I > 0) and + (TExprWord(Items[I - 1]).IsVariable)) then + raise EParserException.Create('Missing operator between constant/variable and ('); + + {-----CHECK ON INTPOWER------} + if (TExprWord(Items[I]).Name = '^') and ((I < Count - 1) and + (TExprWord(Items[I + 1]).ClassType = TIntegerConstant)) then + if FWordsList.Search(PChar('^@'), J) then + Items[I] := FWordsList.Items[J]; //use the faster intPower if possible + Inc(I); + end; + end; +end; + +procedure TCustomExpressionParser.EvaluateCurrent; +var + TempRec: PExpressionRec; +begin + if FCurrentRec <> nil then + begin + // get current record + TempRec := FCurrentRec; + // execute list + repeat + with TempRec^ do + begin + // do we need to reset pointer? + if ResetDest then + Res.MemoryPos^ := Res.Memory^; + + Oper(TempRec); + + // goto next + TempRec := Next; + end; + until TempRec = nil; + end; +end; + +function TCustomExpressionParser.DefineFunction(AFunctName, AShortName, ADescription, ATypeSpec: string; + AMinFunctionArg: Integer; AResultType: TExpressionType; AFuncAddress: TExprFunc): TExprWord; +begin + Result := TFunction.Create(AFunctName, AShortName, ATypeSpec, AMinFunctionArg, AResultType, AFuncAddress, ADescription); + FWordsList.Add(Result); +end; + +function TCustomExpressionParser.DefineIntegerVariable(AVarName: string; AValue: PInteger): TExprWord; +begin + Result := TIntegerVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +{$ifdef SUPPORT_INT64} + +function TCustomExpressionParser.DefineLargeIntVariable(AVarName: string; AValue: PLargeInt): TExprWord; +begin + Result := TLargeIntVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +{$endif} + +function TCustomExpressionParser.DefineDateTimeVariable(AVarName: string; AValue: PDateTimeRec): TExprWord; +begin + Result := TDateTimeVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +function TCustomExpressionParser.DefineBooleanVariable(AVarName: string; AValue: PBoolean): TExprWord; +begin + Result := TBooleanVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +function TCustomExpressionParser.DefineFloatVariable(AVarName: string; AValue: PDouble): TExprWord; +begin + Result := TFloatVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +function TCustomExpressionParser.DefineStringVariable(AVarName: string; AValue: PPChar): TExprWord; +begin + Result := TStringVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +{ +procedure TCustomExpressionParser.GetGeneratedVars(AList: TList); +var + I: Integer; +begin + AList.Clear; + with FWordsList do + for I := 0 to Count - 1 do + begin + if TObject(Items[I]).ClassType = TGeneratedVariable then + AList.Add(Items[I]); + end; +end; +} + +function TCustomExpressionParser.GetResultType: TExpressionType; +begin + Result := etUnknown; + if FCurrentRec <> nil then + begin + //LAST operand should be boolean -otherwise If(,,) doesn't work + while (FLastRec^.Next <> nil) do + FLastRec := FLastRec^.Next; + if FLastRec^.ExprWord <> nil then + Result := FLastRec^.ExprWord.ResultType; + end; +end; + +function TCustomExpressionParser.MakeRec: PExpressionRec; +var + I: Integer; +begin + New(Result); + Result^.Oper := nil; + Result^.AuxData := nil; + Result^.WantsFunction := false; + for I := 0 to MaxArg - 1 do + begin + Result^.Args[I] := nil; + Result^.ArgsPos[I] := nil; + Result^.ArgsSize[I] := 0; + Result^.ArgsType[I] := etUnknown; + Result^.ArgList[I] := nil; + end; + Result^.Res := nil; + Result^.Next := nil; + Result^.ExprWord := nil; + Result^.ResetDest := false; +end; + +procedure TCustomExpressionParser.Evaluate(AnExpression: string); +begin + if Length(AnExpression) > 0 then + begin + AddExpression(AnExpression); + EvaluateCurrent; + end; +end; + +function TCustomExpressionParser.AddExpression(AnExpression: string): Integer; +begin + if Length(AnExpression) > 0 then + begin + Result := 0; + CompileExpression(AnExpression); + end else + Result := -1; + //CurrentIndex := Result; +end; + +procedure TCustomExpressionParser.ClearExpressions; +begin + DisposeList(FCurrentRec); + FCurrentRec := nil; + FLastRec := nil; +end; + +function TCustomExpressionParser.GetFunctionDescription(AFunction: string): + string; +var + S: string; + p, I: Integer; +begin + S := AFunction; + p := Pos('(', S); + if p > 0 then + S := Copy(S, 1, p - 1); + if FWordsList.Search(pchar(S), I) then + Result := TExprWord(FWordsList.Items[I]).Description + else + Result := EmptyStr; +end; + +procedure TCustomExpressionParser.GetFunctionNames(AList: TStrings); +var + I, J: Integer; + S: string; +begin + with FWordsList do + for I := 0 to Count - 1 do + with TExprWord(FWordsList.Items[I]) do + if Length(Description) > 0 then + begin + S := Name; + if MaxFunctionArg > 0 then + begin + S := S + '('; + for J := 0 to MaxFunctionArg - 2 do + S := S + ArgSeparator; + S := S + ')'; + end; + AList.Add(S); + end; +end; + + +//--Expression functions----------------------------------------------------- + +procedure FuncFloatToStr(Param: PExpressionRec); +var + width, numDigits, resWidth: Integer; + extVal: Extended; +begin + with Param^ do + begin + // get params; + numDigits := 0; + if Args[1] <> nil then + width := PInteger(Args[1])^ + else + width := 18; + if Args[2] <> nil then + numDigits := PInteger(Args[2])^; + // convert to string + Res.AssureSpace(width); + extVal := PDouble(Args[0])^; + resWidth := FloatToText(Res.MemoryPos^, extVal, {$ifndef FPC_VERSION}fvExtended,{$endif} ffFixed, 18, numDigits); + // always use dot as decimal separator + if numDigits > 0 then + Res.MemoryPos^[resWidth-numDigits-1] := '.'; + // result width smaller than requested width? -> add space to compensate + if (Args[1] <> nil) and (resWidth < width) then + begin + // move string so that it's right-aligned + Move(Res.MemoryPos^^, (Res.MemoryPos^)[width-resWidth], resWidth); + // fill gap with spaces + FillChar(Res.MemoryPos^^, width-resWidth, ' '); + // resWidth has been padded, update + resWidth := width; + end else if resWidth > width then begin + // result width more than requested width, cut + resWidth := width; + end; + // advance pointer + Inc(Res.MemoryPos^, resWidth); + // null-terminate + Res.MemoryPos^^ := #0; + end; +end; + +procedure FuncIntToStr_Gen(Param: PExpressionRec; Val: {$ifdef SUPPORT_INT64}Int64{$else}Integer{$endif}); +var + width: Integer; +begin + with Param^ do + begin + // width specified? + if Args[1] <> nil then + begin + // convert to string + width := PInteger(Args[1])^; +{$ifdef SUPPORT_INT64} + GetStrFromInt64_Width +{$else} + GetStrFromInt_Width +{$endif} + (Val, width, Res.MemoryPos^, #32); + // advance pointer + Inc(Res.MemoryPos^, width); + // need to add decimal? + if Args[2] <> nil then + begin + // get number of digits + width := PInteger(Args[2])^; + // add decimal dot + Res.MemoryPos^^ := '.'; + Inc(Res.MemoryPos^); + // add zeroes + FillChar(Res.MemoryPos^^, width, '0'); + // go to end + Inc(Res.MemoryPos^, width); + end; + end else begin + // convert to string + width := +{$ifdef SUPPORT_INT64} + GetStrFromInt64 +{$else} + GetStrFromInt +{$endif} + (Val, Res.MemoryPos^); + // advance pointer + Inc(Param^.Res.MemoryPos^, width); + end; + // null-terminate + Res.MemoryPos^^ := #0; + end; +end; + +procedure FuncIntToStr(Param: PExpressionRec); +begin + FuncIntToStr_Gen(Param, PInteger(Param^.Args[0])^); +end; + +{$ifdef SUPPORT_INT64} + +procedure FuncInt64ToStr(Param: PExpressionRec); +begin + FuncIntToStr_Gen(Param, PInt64(Param^.Args[0])^); +end; + +{$endif} + +procedure FuncDateToStr(Param: PExpressionRec); +var + TempStr: string; +begin + with Param^ do + begin + // create in temporary string + DateTimeToString(TempStr, 'yyyymmdd', PDateTimeRec(Args[0])^.DateTime); + // copy to buffer + Res.Append(PChar(TempStr), Length(TempStr)); + end; +end; + +procedure FuncSubString(Param: PExpressionRec); +var + srcLen, index, count: Integer; +begin + with Param^ do + begin + srcLen := StrLen(Args[0]); + index := PInteger(Args[1])^ - 1; + if Args[2] <> nil then + begin + count := PInteger(Args[2])^; + if index + count > srcLen then + count := srcLen - index; + end else + count := srcLen - index; + Res.Append(Args[0]+index, count) + end; +end; + +procedure FuncUppercase(Param: PExpressionRec); +var + dest: PChar; +begin + with Param^ do + begin + // first copy + dest := (Res.MemoryPos)^; + Res.Append(Args[0], StrLen(Args[0])); + // make uppercase + AnsiStrUpper(dest); + end; +end; + +procedure FuncLowercase(Param: PExpressionRec); +var + dest: PChar; +begin + with Param^ do + begin + // first copy + dest := (Res.MemoryPos)^; + Res.Append(Args[0], StrLen(Args[0])); + // make lowercase + AnsiStrLower(dest); + end; +end; + +procedure FuncAdd_F_FF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PDouble(Args[1])^; +end; + +procedure FuncAdd_F_FI(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInteger(Args[1])^; +end; + +procedure FuncAdd_F_II(Param: PExpressionRec); +begin + with Param^ do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInteger(Args[1])^; +end; + +procedure FuncAdd_F_IF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ + PDouble(Args[1])^; +end; + +{$ifdef SUPPORT_INT64} + +procedure FuncAdd_F_FL(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInt64(Args[1])^; +end; + +procedure FuncAdd_F_IL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInt64(Args[1])^; +end; + +procedure FuncAdd_F_LL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInt64(Args[1])^; +end; + +procedure FuncAdd_F_LF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ + PDouble(Args[1])^; +end; + +procedure FuncAdd_F_LI(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInteger(Args[1])^; +end; + +{$endif} + +procedure FuncSub_F_FF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PDouble(Args[1])^; +end; + +procedure FuncSub_F_FI(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInteger(Args[1])^; +end; + +procedure FuncSub_F_II(Param: PExpressionRec); +begin + with Param^ do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInteger(Args[1])^; +end; + +procedure FuncSub_F_IF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ - PDouble(Args[1])^; +end; + +{$ifdef SUPPORT_INT64} + +procedure FuncSub_F_FL(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInt64(Args[1])^; +end; + +procedure FuncSub_F_IL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInt64(Args[1])^; +end; + +procedure FuncSub_F_LL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInt64(Args[1])^; +end; + +procedure FuncSub_F_LF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ - PDouble(Args[1])^; +end; + +procedure FuncSub_F_LI(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInteger(Args[1])^; +end; + +{$endif} + +procedure FuncMul_F_FF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PDouble(Args[1])^; +end; + +procedure FuncMul_F_FI(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInteger(Args[1])^; +end; + +procedure FuncMul_F_II(Param: PExpressionRec); +begin + with Param^ do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInteger(Args[1])^; +end; + +procedure FuncMul_F_IF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ * PDouble(Args[1])^; +end; + +{$ifdef SUPPORT_INT64} + +procedure FuncMul_F_FL(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInt64(Args[1])^; +end; + +procedure FuncMul_F_IL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInt64(Args[1])^; +end; + +procedure FuncMul_F_LL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInt64(Args[1])^; +end; + +procedure FuncMul_F_LF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ * PDouble(Args[1])^; +end; + +procedure FuncMul_F_LI(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInteger(Args[1])^; +end; + +{$endif} + +procedure FuncDiv_F_FF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PDouble(Args[1])^; +end; + +procedure FuncDiv_F_FI(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInteger(Args[1])^; +end; + +procedure FuncDiv_F_II(Param: PExpressionRec); +begin + with Param^ do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInteger(Args[1])^; +end; + +procedure FuncDiv_F_IF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ / PDouble(Args[1])^; +end; + +{$ifdef SUPPORT_INT64} + +procedure FuncDiv_F_FL(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInt64(Args[1])^; +end; + +procedure FuncDiv_F_IL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInt64(Args[1])^; +end; + +procedure FuncDiv_F_LL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInt64(Args[1])^; +end; + +procedure FuncDiv_F_LF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ / PDouble(Args[1])^; +end; + +procedure FuncDiv_F_LI(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInteger(Args[1])^; +end; + +{$endif} + +procedure FuncStrI_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) = 0); +end; + +procedure FuncStrIP_EQ(Param: PExpressionRec); +var + arg0len, arg1len: integer; + match: boolean; + str0, str1: string; +begin + with Param^ do + begin + arg1len := StrLen(Args[1]); + if Args[1][0] = '*' then + begin + if Args[1][arg1len-1] = '*' then + begin + str0 := AnsiStrUpper(Args[0]); + str1 := AnsiStrUpper(Args[1]+1); + setlength(str1, arg1len-2); + match := AnsiPos(str1, str0) <> 0; + end else begin + arg0len := StrLen(Args[0]); + // at least length without asterisk + match := arg0len >= arg1len - 1; + if match then + match := AnsiStrLIComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0; + end; + end else + if Args[1][arg1len-1] = '*' then + begin + arg0len := StrLen(Args[0]); + match := arg0len >= arg1len - 1; + if match then + match := AnsiStrLIComp(Args[0], Args[1], arg1len-1) = 0; + end else begin + match := AnsiStrIComp(Args[0], Args[1]) = 0; + end; + Res.MemoryPos^^ := Char(match); + end; +end; + +procedure FuncStrI_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <> 0); +end; + +procedure FuncStrI_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) < 0); +end; + +procedure FuncStrI_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) > 0); +end; + +procedure FuncStrI_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <= 0); +end; + +procedure FuncStrI_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) >= 0); +end; + +procedure FuncStrP_EQ(Param: PExpressionRec); +var + arg0len, arg1len: integer; + match: boolean; +begin + with Param^ do + begin + arg1len := StrLen(Args[1]); + if Args[1][0] = '*' then + begin + if Args[1][arg1len-1] = '*' then + begin + Args[1][arg1len-1] := #0; + match := AnsiStrPos(Args[0], Args[1]+1) <> nil; + Args[1][arg1len-1] := '*'; + end else begin + arg0len := StrLen(Args[0]); + // at least length without asterisk + match := arg0len >= arg1len - 1; + if match then + match := AnsiStrLComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0; + end; + end else + if Args[1][arg1len-1] = '*' then + begin + arg0len := StrLen(Args[0]); + match := arg0len >= arg1len - 1; + if match then + match := AnsiStrLComp(Args[0], Args[1], arg1len-1) = 0; + end else begin + match := AnsiStrComp(Args[0], Args[1]) = 0; + end; + Res.MemoryPos^^ := Char(match); + end; +end; + +procedure FuncStr_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) = 0); +end; + +procedure FuncStr_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <> 0); +end; + +procedure FuncStr_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) < 0); +end; + +procedure FuncStr_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) > 0); +end; + +procedure FuncStr_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <= 0); +end; + +procedure FuncStr_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) >= 0); +end; + +procedure Func_FF_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PDouble(Args[1])^); +end; + +procedure Func_FF_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PDouble(Args[1])^); +end; + +procedure Func_FF_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PDouble(Args[1])^); +end; + +procedure Func_FF_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PDouble(Args[1])^); +end; + +procedure Func_FF_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PDouble(Args[1])^); +end; + +procedure Func_FF_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PDouble(Args[1])^); +end; + +procedure Func_FI_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInteger(Args[1])^); +end; + +procedure Func_FI_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInteger(Args[1])^); +end; + +procedure Func_FI_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInteger(Args[1])^); +end; + +procedure Func_FI_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInteger(Args[1])^); +end; + +procedure Func_FI_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInteger(Args[1])^); +end; + +procedure Func_FI_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInteger(Args[1])^); +end; + +procedure Func_II_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInteger(Args[1])^); +end; + +procedure Func_II_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInteger(Args[1])^); +end; + +procedure Func_II_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInteger(Args[1])^); +end; + +procedure Func_II_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInteger(Args[1])^); +end; + +procedure Func_II_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInteger(Args[1])^); +end; + +procedure Func_II_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInteger(Args[1])^); +end; + +procedure Func_IF_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PDouble(Args[1])^); +end; + +procedure Func_IF_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PDouble(Args[1])^); +end; + +procedure Func_IF_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PDouble(Args[1])^); +end; + +procedure Func_IF_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PDouble(Args[1])^); +end; + +procedure Func_IF_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PDouble(Args[1])^); +end; + +procedure Func_IF_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PDouble(Args[1])^); +end; + +{$ifdef SUPPORT_INT64} + +procedure Func_LL_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInt64(Args[1])^); +end; + +procedure Func_LL_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInt64(Args[1])^); +end; + +procedure Func_LL_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInt64(Args[1])^); +end; + +procedure Func_LL_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInt64(Args[1])^); +end; + +procedure Func_LL_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInt64(Args[1])^); +end; + +procedure Func_LL_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInt64(Args[1])^); +end; + +procedure Func_LF_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PDouble(Args[1])^); +end; + +procedure Func_LF_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PDouble(Args[1])^); +end; + +procedure Func_LF_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PDouble(Args[1])^); +end; + +procedure Func_LF_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PDouble(Args[1])^); +end; + +procedure Func_LF_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PDouble(Args[1])^); +end; + +procedure Func_LF_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PDouble(Args[1])^); +end; + +procedure Func_FL_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInt64(Args[1])^); +end; + +procedure Func_FL_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInt64(Args[1])^); +end; + +procedure Func_FL_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInt64(Args[1])^); +end; + +procedure Func_FL_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInt64(Args[1])^); +end; + +procedure Func_FL_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInt64(Args[1])^); +end; + +procedure Func_FL_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInt64(Args[1])^); +end; + +procedure Func_LI_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInteger(Args[1])^); +end; + +procedure Func_LI_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInteger(Args[1])^); +end; + +procedure Func_LI_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInteger(Args[1])^); +end; + +procedure Func_LI_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInteger(Args[1])^); +end; + +procedure Func_LI_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInteger(Args[1])^); +end; + +procedure Func_LI_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInteger(Args[1])^); +end; + +procedure Func_IL_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInt64(Args[1])^); +end; + +procedure Func_IL_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInt64(Args[1])^); +end; + +procedure Func_IL_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInt64(Args[1])^); +end; + +procedure Func_IL_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInt64(Args[1])^); +end; + +procedure Func_IL_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInt64(Args[1])^); +end; + +procedure Func_IL_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInt64(Args[1])^); +end; + +{$endif} + +procedure Func_AND(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(Boolean(Args[0]^) and Boolean(Args[1]^)); +end; + +procedure Func_OR(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(Boolean(Args[0]^) or Boolean(Args[1]^)); +end; + +procedure Func_NOT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(not Boolean(Args[0]^)); +end; + +initialization + + DbfWordsGeneralList := TExpressList.Create; + DbfWordsInsensGeneralList := TExpressList.Create; + DbfWordsInsensNoPartialList := TExpressList.Create; + DbfWordsInsensPartialList := TExpressList.Create; + DbfWordsSensGeneralList := TExpressList.Create; + DbfWordsSensNoPartialList := TExpressList.Create; + DbfWordsSensPartialList := TExpressList.Create; + + with DbfWordsGeneralList do + begin + // basic function functionality + Add(TLeftBracket.Create('(', nil)); + Add(TRightBracket.Create(')', nil)); + Add(TComma.Create(',', nil)); + + // operators - name, param types, result type, func addr, precedence + Add(TFunction.CreateOper('+', 'SS', etString, nil, 40)); + Add(TFunction.CreateOper('+', 'FF', etFloat, FuncAdd_F_FF, 40)); + Add(TFunction.CreateOper('+', 'FI', etFloat, FuncAdd_F_FI, 40)); + Add(TFunction.CreateOper('+', 'IF', etFloat, FuncAdd_F_IF, 40)); + Add(TFunction.CreateOper('+', 'II', etInteger, FuncAdd_F_II, 40)); +{$ifdef SUPPORT_INT64} + Add(TFunction.CreateOper('+', 'FL', etFloat, FuncAdd_F_FL, 40)); + Add(TFunction.CreateOper('+', 'IL', etLargeInt, FuncAdd_F_IL, 40)); + Add(TFunction.CreateOper('+', 'LF', etFloat, FuncAdd_F_LF, 40)); + Add(TFunction.CreateOper('+', 'LL', etLargeInt, FuncAdd_F_LI, 40)); + Add(TFunction.CreateOper('+', 'LI', etLargeInt, FuncAdd_F_LL, 40)); +{$endif} + Add(TFunction.CreateOper('-', 'FF', etFloat, FuncSub_F_FF, 40)); + Add(TFunction.CreateOper('-', 'FI', etFloat, FuncSub_F_FI, 40)); + Add(TFunction.CreateOper('-', 'IF', etFloat, FuncSub_F_IF, 40)); + Add(TFunction.CreateOper('-', 'II', etInteger, FuncSub_F_II, 40)); +{$ifdef SUPPORT_INT64} + Add(TFunction.CreateOper('-', 'FL', etFloat, FuncSub_F_FL, 40)); + Add(TFunction.CreateOper('-', 'IL', etLargeInt, FuncSub_F_IL, 40)); + Add(TFunction.CreateOper('-', 'LF', etFloat, FuncSub_F_LF, 40)); + Add(TFunction.CreateOper('-', 'LL', etLargeInt, FuncSub_F_LI, 40)); + Add(TFunction.CreateOper('-', 'LI', etLargeInt, FuncSub_F_LL, 40)); +{$endif} + Add(TFunction.CreateOper('*', 'FF', etFloat, FuncMul_F_FF, 40)); + Add(TFunction.CreateOper('*', 'FI', etFloat, FuncMul_F_FI, 40)); + Add(TFunction.CreateOper('*', 'IF', etFloat, FuncMul_F_IF, 40)); + Add(TFunction.CreateOper('*', 'II', etInteger, FuncMul_F_II, 40)); +{$ifdef SUPPORT_INT64} + Add(TFunction.CreateOper('*', 'FL', etFloat, FuncMul_F_FL, 40)); + Add(TFunction.CreateOper('*', 'IL', etLargeInt, FuncMul_F_IL, 40)); + Add(TFunction.CreateOper('*', 'LF', etFloat, FuncMul_F_LF, 40)); + Add(TFunction.CreateOper('*', 'LL', etLargeInt, FuncMul_F_LI, 40)); + Add(TFunction.CreateOper('*', 'LI', etLargeInt, FuncMul_F_LL, 40)); +{$endif} + Add(TFunction.CreateOper('/', 'FF', etFloat, FuncDiv_F_FF, 40)); + Add(TFunction.CreateOper('/', 'FI', etFloat, FuncDiv_F_FI, 40)); + Add(TFunction.CreateOper('/', 'IF', etFloat, FuncDiv_F_IF, 40)); + Add(TFunction.CreateOper('/', 'II', etInteger, FuncDiv_F_II, 40)); +{$ifdef SUPPORT_INT64} + Add(TFunction.CreateOper('/', 'FL', etFloat, FuncDiv_F_FL, 40)); + Add(TFunction.CreateOper('/', 'IL', etLargeInt, FuncDiv_F_IL, 40)); + Add(TFunction.CreateOper('/', 'LF', etFloat, FuncDiv_F_LF, 40)); + Add(TFunction.CreateOper('/', 'LL', etLargeInt, FuncDiv_F_LI, 40)); + Add(TFunction.CreateOper('/', 'LI', etLargeInt, FuncDiv_F_LL, 40)); +{$endif} + + Add(TFunction.CreateOper('=', 'FF', etBoolean, Func_FF_EQ , 80)); + Add(TFunction.CreateOper('<', 'FF', etBoolean, Func_FF_LT , 80)); + Add(TFunction.CreateOper('>', 'FF', etBoolean, Func_FF_GT , 80)); + Add(TFunction.CreateOper('<=','FF', etBoolean, Func_FF_LTE, 80)); + Add(TFunction.CreateOper('>=','FF', etBoolean, Func_FF_GTE, 80)); + Add(TFunction.CreateOper('<>','FF', etBoolean, Func_FF_NEQ, 80)); + Add(TFunction.CreateOper('=', 'FI', etBoolean, Func_FI_EQ , 80)); + Add(TFunction.CreateOper('<', 'FI', etBoolean, Func_FI_LT , 80)); + Add(TFunction.CreateOper('>', 'FI', etBoolean, Func_FI_GT , 80)); + Add(TFunction.CreateOper('<=','FI', etBoolean, Func_FI_LTE, 80)); + Add(TFunction.CreateOper('>=','FI', etBoolean, Func_FI_GTE, 80)); + Add(TFunction.CreateOper('<>','FI', etBoolean, Func_FI_NEQ, 80)); + Add(TFunction.CreateOper('=', 'II', etBoolean, Func_II_EQ , 80)); + Add(TFunction.CreateOper('<', 'II', etBoolean, Func_II_LT , 80)); + Add(TFunction.CreateOper('>', 'II', etBoolean, Func_II_GT , 80)); + Add(TFunction.CreateOper('<=','II', etBoolean, Func_II_LTE, 80)); + Add(TFunction.CreateOper('>=','II', etBoolean, Func_II_GTE, 80)); + Add(TFunction.CreateOper('<>','II', etBoolean, Func_II_NEQ, 80)); + Add(TFunction.CreateOper('=', 'IF', etBoolean, Func_IF_EQ , 80)); + Add(TFunction.CreateOper('<', 'IF', etBoolean, Func_IF_LT , 80)); + Add(TFunction.CreateOper('>', 'IF', etBoolean, Func_IF_GT , 80)); + Add(TFunction.CreateOper('<=','IF', etBoolean, Func_IF_LTE, 80)); + Add(TFunction.CreateOper('>=','IF', etBoolean, Func_IF_GTE, 80)); + Add(TFunction.CreateOper('<>','IF', etBoolean, Func_IF_NEQ, 80)); +{$ifdef SUPPORT_INT64} + Add(TFunction.CreateOper('=', 'LL', etBoolean, Func_LL_EQ , 80)); + Add(TFunction.CreateOper('<', 'LL', etBoolean, Func_LL_LT , 80)); + Add(TFunction.CreateOper('>', 'LL', etBoolean, Func_LL_GT , 80)); + Add(TFunction.CreateOper('<=','LL', etBoolean, Func_LL_LTE, 80)); + Add(TFunction.CreateOper('>=','LL', etBoolean, Func_LL_GTE, 80)); + Add(TFunction.CreateOper('<>','LL', etBoolean, Func_LL_NEQ, 80)); + Add(TFunction.CreateOper('=', 'LF', etBoolean, Func_LF_EQ , 80)); + Add(TFunction.CreateOper('<', 'LF', etBoolean, Func_LF_LT , 80)); + Add(TFunction.CreateOper('>', 'LF', etBoolean, Func_LF_GT , 80)); + Add(TFunction.CreateOper('<=','LF', etBoolean, Func_LF_LTE, 80)); + Add(TFunction.CreateOper('>=','LF', etBoolean, Func_LF_GTE, 80)); + Add(TFunction.CreateOper('<>','FI', etBoolean, Func_LF_NEQ, 80)); + Add(TFunction.CreateOper('=', 'LI', etBoolean, Func_LI_EQ , 80)); + Add(TFunction.CreateOper('<', 'LI', etBoolean, Func_LI_LT , 80)); + Add(TFunction.CreateOper('>', 'LI', etBoolean, Func_LI_GT , 80)); + Add(TFunction.CreateOper('<=','LI', etBoolean, Func_LI_LTE, 80)); + Add(TFunction.CreateOper('>=','LI', etBoolean, Func_LI_GTE, 80)); + Add(TFunction.CreateOper('<>','LI', etBoolean, Func_LI_NEQ, 80)); + Add(TFunction.CreateOper('=', 'FL', etBoolean, Func_FL_EQ , 80)); + Add(TFunction.CreateOper('<', 'FL', etBoolean, Func_FL_LT , 80)); + Add(TFunction.CreateOper('>', 'FL', etBoolean, Func_FL_GT , 80)); + Add(TFunction.CreateOper('<=','FL', etBoolean, Func_FL_LTE, 80)); + Add(TFunction.CreateOper('>=','FL', etBoolean, Func_FL_GTE, 80)); + Add(TFunction.CreateOper('<>','FL', etBoolean, Func_FL_NEQ, 80)); + Add(TFunction.CreateOper('=', 'IL', etBoolean, Func_IL_EQ , 80)); + Add(TFunction.CreateOper('<', 'IL', etBoolean, Func_IL_LT , 80)); + Add(TFunction.CreateOper('>', 'IL', etBoolean, Func_IL_GT , 80)); + Add(TFunction.CreateOper('<=','IL', etBoolean, Func_IL_LTE, 80)); + Add(TFunction.CreateOper('>=','IL', etBoolean, Func_IL_GTE, 80)); + Add(TFunction.CreateOper('<>','IL', etBoolean, Func_IL_NEQ, 80)); +{$endif} + + Add(TFunction.CreateOper('NOT', 'B', etBoolean, Func_NOT, 85)); + Add(TFunction.CreateOper('AND', 'BB', etBoolean, Func_AND, 90)); + Add(TFunction.CreateOper('OR', 'BB', etBoolean, Func_OR, 100)); + + // Functions - name, description, param types, min params, result type, Func addr + Add(TFunction.Create('STR', '', 'FII', 1, etString, FuncFloatToStr, '')); + Add(TFunction.Create('STR', '', 'III', 1, etString, FuncIntToStr, '')); + {$ifdef SUPPORT_INT64} + Add(TFunction.Create('STR', '', 'LII', 1, etString, FuncInt64ToStr, '')); + {$endif} + Add(TFunction.Create('DTOS', '', 'D', 1, etString, FuncDateToStr, '')); + Add(TFunction.Create('SUBSTR', 'SUBS', 'SII', 3, etString, FuncSubString, '')); + Add(TFunction.Create('UPPERCASE', 'UPPER', 'S', 1, etString, FuncUppercase, '')); + Add(TFunction.Create('LOWERCASE', 'LOWER', 'S', 1, etString, FuncLowercase, '')); + end; + + with DbfWordsInsensGeneralList do + begin + Add(TFunction.CreateOper('<', 'SS', etBoolean, FuncStrI_LT , 80)); + Add(TFunction.CreateOper('>', 'SS', etBoolean, FuncStrI_GT , 80)); + Add(TFunction.CreateOper('<=','SS', etBoolean, FuncStrI_LTE, 80)); + Add(TFunction.CreateOper('>=','SS', etBoolean, FuncStrI_GTE, 80)); + Add(TFunction.CreateOper('<>','SS', etBoolean, FuncStrI_NEQ, 80)); + end; + + with DbfWordsInsensNoPartialList do + Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrI_EQ , 80)); + + with DbfWordsInsensPartialList do + Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrIP_EQ, 80)); + + with DbfWordsSensGeneralList do + begin + Add(TFunction.CreateOper('<', 'SS', etBoolean, FuncStr_LT , 80)); + Add(TFunction.CreateOper('>', 'SS', etBoolean, FuncStr_GT , 80)); + Add(TFunction.CreateOper('<=','SS', etBoolean, FuncStr_LTE, 80)); + Add(TFunction.CreateOper('>=','SS', etBoolean, FuncStr_GTE, 80)); + Add(TFunction.CreateOper('<>','SS', etBoolean, FuncStr_NEQ, 80)); + end; + + with DbfWordsSensNoPartialList do + Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStr_EQ , 80)); + + with DbfWordsSensPartialList do + Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrP_EQ , 80)); + +finalization + + DbfWordsGeneralList.Free; + DbfWordsInsensGeneralList.Free; + DbfWordsInsensNoPartialList.Free; + DbfWordsInsensPartialList.Free; + DbfWordsSensGeneralList.Free; + DbfWordsSensNoPartialList.Free; + DbfWordsSensPartialList.Free; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/mdbf_prsdef.pas b/mseide-msegui/lib/common/fpccompatibility/mdbf_prsdef.pas new file mode 100644 index 0000000..050f38b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mdbf_prsdef.pas @@ -0,0 +1,1053 @@ +unit mdbf_prsdef; + +// Modified 2013 by Martin Schreiber + +interface + +{$I dbf_common.inc} + +uses + SysUtils, + classes,mclasses, + mdb, + mdbf_prssupp; + +const + MaxArg = 6; + ArgAllocSize = 32; + +type + TExpressionType = (etInteger, etString, etBoolean, etLargeInt, etFloat, etDateTime, + etLeftBracket, etRightBracket, etComma, etUnknown); + + EParserException = class(Exception); + PExpressionRec = ^TExpressionRec; + PDynamicType = ^TDynamicType; + PDateTimeRec = ^TDateTimeRec; +{$ifdef SUPPORT_INT64} + PLargeInt = ^Int64; +{$endif} + + TExprWord = class; + + TExprFunc = procedure(Expr: PExpressionRec); + +//----- + + TDynamicType = class(TObject) + private + FMemory: PPChar; + FMemoryPos: PPChar; + FSize: PInteger; + public + constructor Create(DestMem, DestPos: PPChar; ASize: PInteger); + + procedure AssureSpace(ASize: Integer); + procedure Resize(NewSize: Integer; Exact: Boolean); + procedure Rewind; + procedure Append(Source: PChar; Length: Integer); + procedure AppendInteger(Source: Integer); + + property Memory: PPChar read FMemory; + property MemoryPos: PPChar read FMemoryPos; + property Size: PInteger read FSize; + end; + + TExpressionRec = record + //used both as linked tree and linked list for maximum evaluation efficiency + Oper: TExprFunc; + Next: PExpressionRec; + Res: TDynamicType; + ExprWord: TExprWord; + AuxData: pointer; + ResetDest: boolean; + WantsFunction: boolean; + Args: array[0..MaxArg-1] of PChar; + ArgsPos: array[0..MaxArg-1] of PChar; + ArgsSize: array[0..MaxArg-1] of Integer; + ArgsType: array[0..MaxArg-1] of TExpressionType; + ArgList: array[0..MaxArg-1] of PExpressionRec; + end; + + TExprCollection = class(TNoOwnerCollection) + public + procedure Check; + procedure EraseExtraBrackets; + end; + + TExprWordRec = record + Name: PChar; + ShortName: PChar; + IsOperator: Boolean; + IsVariable: Boolean; + IsFunction: Boolean; + NeedsCopy: Boolean; + FixedLen: Boolean; + CanVary: Boolean; + ResultType: TExpressionType; + MinArg: Integer; + MaxArg: Integer; + TypeSpec: PChar; + Description: PChar; + ExprFunc: TExprFunc; + end; + + TExprWord = class(TObject) + private + FName: string; + FExprFunc: TExprFunc; + protected + FRefCount: Cardinal; + + function GetIsOperator: Boolean; virtual; + function GetIsVariable: Boolean; + function GetNeedsCopy: Boolean; + function GetFixedLen: Integer; virtual; + function GetCanVary: Boolean; virtual; + function GetResultType: TExpressionType; virtual; + function GetMinFunctionArg: Integer; virtual; + function GetMaxFunctionArg: Integer; virtual; + function GetDescription: string; virtual; + function GetTypeSpec: string; virtual; + function GetShortName: string; virtual; + procedure SetFixedLen(NewLen: integer); virtual; + public + constructor Create(AName: string; AExprFunc: TExprFunc); + + function LenAsPointer: PInteger; virtual; + function AsPointer: PChar; virtual; + function IsFunction: Boolean; virtual; + + property ExprFunc: TExprFunc read FExprFunc; + property IsOperator: Boolean read GetIsOperator; + property CanVary: Boolean read GetCanVary; + property IsVariable: Boolean read GetIsVariable; + property NeedsCopy: Boolean read GetNeedsCopy; + property FixedLen: Integer read GetFixedLen write SetFixedLen; + property ResultType: TExpressionType read GetResultType; + property MinFunctionArg: Integer read GetMinFunctionArg; + property MaxFunctionArg: Integer read GetMaxFunctionArg; + property Name: string read FName; + property ShortName: string read GetShortName; + property Description: string read GetDescription; + property TypeSpec: string read GetTypeSpec; + end; + + TExpressShortList = class(TSortedCollection) + public + function KeyOf(Item: Pointer): Pointer; override; + function Compare(Key1, Key2: Pointer): Integer; override; + procedure FreeItem(Item: Pointer); override; + end; + + TExpressList = class(TSortedCollection) + private + FShortList: TExpressShortList; + public + constructor Create; + destructor Destroy; override; + procedure Add(Item: Pointer); override; + function KeyOf(Item: Pointer): Pointer; override; + function Compare(Key1, Key2: Pointer): Integer; override; + function Search(Key: Pointer; var Index: Integer): Boolean; override; + procedure FreeItem(Item: Pointer); override; + end; + + TConstant = class(TExprWord) + private + FResultType: TExpressionType; + protected + function GetResultType: TExpressionType; override; + public + constructor Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc); + end; + + TFloatConstant = class(TConstant) + private + FValue: Double; + public + // not overloaded to support older Delphi versions + constructor Create(AName: string; AValue: string); + constructor CreateAsDouble(AName: string; AValue: Double); + + function AsPointer: PChar; override; + + property Value: Double read FValue write FValue; + end; + + TUserConstant = class(TFloatConstant) + private + FDescription: string; + protected + function GetDescription: string; override; + public + constructor CreateAsDouble(AName, Descr: string; AValue: Double); + end; + + TStringConstant = class(TConstant) + private + FValue: string; + public + constructor Create(AValue: string); + + function AsPointer: PChar; override; + end; + + TIntegerConstant = class(TConstant) + private + FValue: Integer; + public + constructor Create(AValue: Integer); + + function AsPointer: PChar; override; + end; + + TBooleanConstant = class(TConstant) + private + FValue: Boolean; + public + // not overloaded to support older Delphi versions + constructor Create(AName: string; AValue: Boolean); + + function AsPointer: PChar; override; + + property Value: Boolean read FValue write FValue; + end; + + TVariable = class(TExprWord) + private + FResultType: TExpressionType; + protected + function GetCanVary: Boolean; override; + function GetResultType: TExpressionType; override; + public + constructor Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc); + end; + + TFloatVariable = class(TVariable) + private + FValue: PDouble; + public + constructor Create(AName: string; AValue: PDouble); + + function AsPointer: PChar; override; + end; + + TStringVariable = class(TVariable) + private + FValue: PPChar; + FFixedLen: Integer; + protected + function GetFixedLen: Integer; override; + procedure SetFixedLen(NewLen: integer); override; + public + constructor Create(AName: string; AValue: PPChar); + + function LenAsPointer: PInteger; override; + function AsPointer: PChar; override; + + property FixedLen: Integer read FFixedLen; + end; + + TDateTimeVariable = class(TVariable) + private + FValue: PDateTimeRec; + public + constructor Create(AName: string; AValue: PDateTimeRec); + + function AsPointer: PChar; override; + end; + + TIntegerVariable = class(TVariable) + private + FValue: PInteger; + public + constructor Create(AName: string; AValue: PInteger); + + function AsPointer: PChar; override; + end; + +{$ifdef SUPPORT_INT64} + + TLargeIntVariable = class(TVariable) + private + FValue: PLargeInt; + public + constructor Create(AName: string; AValue: PLargeInt); + + function AsPointer: PChar; override; + end; + +{$endif} + + TBooleanVariable = class(TVariable) + private + FValue: PBoolean; + public + constructor Create(AName: string; AValue: PBoolean); + + function AsPointer: PChar; override; + end; + + TLeftBracket = class(TExprWord) + function GetResultType: TExpressionType; override; + end; + + TRightBracket = class(TExprWord) + protected + function GetResultType: TExpressionType; override; + end; + + TComma = class(TExprWord) + protected + function GetResultType: TExpressionType; override; + end; + + TFunction = class(TExprWord) + private + FIsOperator: Boolean; + FOperPrec: Integer; + FMinFunctionArg: Integer; + FMaxFunctionArg: Integer; + FDescription: string; + FTypeSpec: string; + FShortName: string; + FResultType: TExpressionType; + protected + function GetDescription: string; override; + function GetIsOperator: Boolean; override; + function GetMinFunctionArg: Integer; override; + function GetMaxFunctionArg: Integer; override; + function GetResultType: TExpressionType; override; + function GetTypeSpec: string; override; + function GetShortName: string; override; + + procedure InternalCreate(AName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType; + AExprFunc: TExprFunc; AIsOperator: Boolean; AOperPrec: Integer); + public + constructor Create(AName, AShortName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType; AExprFunc: TExprFunc; Descr: string); + constructor CreateOper(AName, ATypeSpec: string; AResultType: TExpressionType; AExprFunc: TExprFunc; AOperPrec: Integer); + + function IsFunction: Boolean; override; + + property OperPrec: Integer read FOperPrec; + property TypeSpec: string read FTypeSpec; + end; + + TVaryingFunction = class(TFunction) + // Functions that can vary for ex. random generators + // should be TVaryingFunction to be sure that they are + // always evaluated + protected + function GetCanVary: Boolean; override; + end; + +const + ListChar = ','; {the delimiter used with the 'in' operator: e.g., + ('a' in 'a,b') =True + ('c' in 'a,b') =False} + +function ExprCharToExprType(ExprChar: Char): TExpressionType; + +implementation + +function ExprCharToExprType(ExprChar: Char): TExpressionType; +begin + case ExprChar of + 'B': Result := etBoolean; + 'I': Result := etInteger; + 'L': Result := etLargeInt; + 'F': Result := etFloat; + 'D': Result := etDateTime; + 'S': Result := etString; + else + Result := etUnknown; + end; +end; + +procedure _FloatVariable(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^; +end; + +procedure _BooleanVariable(Param: PExpressionRec); +begin + with Param^ do + PBoolean(Res.MemoryPos^)^ := PBoolean(Args[0])^; +end; + +procedure _StringConstant(Param: PExpressionRec); +begin + with Param^ do + Res.Append(Args[0], StrLen(Args[0])); +end; + +procedure _StringVariable(Param: PExpressionRec); +var + length: integer; +begin + with Param^ do + begin + length := PInteger(Args[1])^; + if length = -1 then + length := StrLen(PPChar(Args[0])^); + Res.Append(PPChar(Args[0])^, length); + end; +end; + +procedure _DateTimeVariable(Param: PExpressionRec); +begin + with Param^ do + PDateTimeRec(Res.MemoryPos^)^ := PDateTimeRec(Args[0])^; +end; + +procedure _IntegerVariable(Param: PExpressionRec); +begin + with Param^ do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^; +end; + +{ +procedure _SmallIntVariable(Param: PExpressionRec); +begin + with Param^ do + PSmallInt(Res.MemoryPos^)^ := PSmallInt(Args[0])^; +end; +} + +{$ifdef SUPPORT_INT64} + +procedure _LargeIntVariable(Param: PExpressionRec); +begin + with Param^ do + PLargeInt(Res.MemoryPos^)^ := PLargeInt(Args[0])^; +end; + +{$endif} + +{ TExpressionWord } + +constructor TExprWord.Create(AName: string; AExprFunc: TExprFunc); +begin + FName := AName; + FExprFunc := AExprFunc; +end; + +function TExprWord.GetCanVary: Boolean; +begin + Result := False; +end; + +function TExprWord.GetDescription: string; +begin + Result := EmptyStr; +end; + +function TExprWord.GetShortName: string; +begin + Result := EmptyStr; +end; + +function TExprWord.GetIsOperator: Boolean; +begin + Result := False; +end; + +function TExprWord.GetIsVariable: Boolean; +begin + // delphi wants to call the function pointed to by the variable, use '@' + // fpc simply returns pointer to function, no '@' needed + Result := (@FExprFunc = @_StringVariable) or + (@FExprFunc = @_StringConstant) or + (@FExprFunc = @_FloatVariable) or + (@FExprFunc = @_IntegerVariable) or +// (FExprFunc = @_SmallIntVariable) or +{$ifdef SUPPORT_INT64} + (@FExprFunc = @_LargeIntVariable) or +{$endif} + (@FExprFunc = @_DateTimeVariable) or + (@FExprFunc = @_BooleanVariable); +end; + +function TExprWord.GetNeedsCopy: Boolean; +begin + Result := (@FExprFunc <> @_StringConstant) and +// (@FExprFunc <> @_StringVariable) and +// (@FExprFunc <> @_StringVariableFixedLen) and +// string variable cannot be used as normal parameter +// because it is indirectly referenced and possibly +// not null-terminated (fixed len) + (@FExprFunc <> @_FloatVariable) and + (@FExprFunc <> @_IntegerVariable) and +// (FExprFunc <> @_SmallIntVariable) and +{$ifdef SUPPORT_INT64} + (@FExprFunc <> @_LargeIntVariable) and +{$endif} + (@FExprFunc <> @_DateTimeVariable) and + (@FExprFunc <> @_BooleanVariable); +end; + +function TExprWord.GetFixedLen: Integer; +begin + // -1 means variable, non-fixed length + Result := -1; +end; + +function TExprWord.GetMinFunctionArg: Integer; +begin + Result := 0; +end; + +function TExprWord.GetMaxFunctionArg: Integer; +begin + Result := 0; +end; + +function TExprWord.GetResultType: TExpressionType; +begin + Result := etUnknown; +end; + +function TExprWord.GetTypeSpec: string; +begin + Result := EmptyStr; +end; + +function TExprWord.AsPointer: PChar; +begin + Result := nil; +end; + +function TExprWord.LenAsPointer: PInteger; +begin + Result := nil; +end; + +function TExprWord.IsFunction: Boolean; +begin + Result := False; +end; + +procedure TExprWord.SetFixedLen(NewLen: integer); +begin +end; + +{ TConstant } + +constructor TConstant.Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc); +begin + inherited Create(AName, AExprFunc); + + FResultType := AVarType; +end; + +function TConstant.GetResultType: TExpressionType; +begin + Result := FResultType; +end; + +{ TFloatConstant } + +constructor TFloatConstant.Create(AName, AValue: string); +begin + inherited Create(AName, etFloat, _FloatVariable); + + if Length(AValue) > 0 then + FValue := StrToFloat(AValue) + else + FValue := 0.0; +end; + +constructor TFloatConstant.CreateAsDouble(AName: string; AValue: Double); +begin + inherited Create(AName, etFloat, _FloatVariable); + + FValue := AValue; +end; + +function TFloatConstant.AsPointer: PChar; +begin + Result := PChar(@FValue); +end; + +{ TUserConstant } + +constructor TUserConstant.CreateAsDouble(AName, Descr: string; AValue: Double); +begin + FDescription := Descr; + + inherited CreateAsDouble(AName, AValue); +end; + +function TUserConstant.GetDescription: string; +begin + Result := FDescription; +end; + +{ TStringConstant } + +constructor TStringConstant.Create(AValue: string); +var + firstChar, lastChar: Char; +begin + inherited Create(AValue, etString, _StringConstant); + + firstChar := AValue[1]; + lastChar := AValue[Length(AValue)]; + if (firstChar = lastChar) and ((firstChar = '''') or (firstChar = '"')) then + FValue := Copy(AValue, 2, Length(AValue) - 2) + else + FValue := AValue; +end; + +function TStringConstant.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{ TBooleanConstant } + +constructor TBooleanConstant.Create(AName: string; AValue: Boolean); +begin + inherited Create(AName, etBoolean, _BooleanVariable); + + FValue := AValue; +end; + +function TBooleanConstant.AsPointer: PChar; +begin + Result := PChar(@FValue); +end; + +{ TIntegerConstant } + +constructor TIntegerConstant.Create(AValue: Integer); +begin + inherited Create(IntToStr(AValue), etInteger, _IntegerVariable); + + FValue := AValue; +end; + +function TIntegerConstant.AsPointer: PChar; +begin + Result := PChar(@FValue); +end; + +{ TVariable } + +constructor TVariable.Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc); +begin + inherited Create(AName, AExprFunc); + + FResultType := AVarType; +end; + +function TVariable.GetCanVary: Boolean; +begin + Result := True; +end; + +function TVariable.GetResultType: TExpressionType; +begin + Result := FResultType; +end; + +{ TFloatVariable } + +constructor TFloatVariable.Create(AName: string; AValue: PDouble); +begin + inherited Create(AName, etFloat, _FloatVariable); + FValue := AValue; +end; + +function TFloatVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{ TStringVariable } + +constructor TStringVariable.Create(AName: string; AValue: PPChar); +begin + // variable or fixed length? + inherited Create(AName, etString, _StringVariable); + + // store pointer to string + FValue := AValue; + FFixedLen := -1; +end; + +function TStringVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +function TStringVariable.GetFixedLen: Integer; +begin + Result := FFixedLen; +end; + +function TStringVariable.LenAsPointer: PInteger; +begin + Result := @FFixedLen; +end; + +procedure TStringVariable.SetFixedLen(NewLen: integer); +begin + FFixedLen := NewLen; +end; + +{ TDateTimeVariable } + +constructor TDateTimeVariable.Create(AName: string; AValue: PDateTimeRec); +begin + inherited Create(AName, etDateTime, _DateTimeVariable); + FValue := AValue; +end; + +function TDateTimeVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{ TIntegerVariable } + +constructor TIntegerVariable.Create(AName: string; AValue: PInteger); +begin + inherited Create(AName, etInteger, _IntegerVariable); + FValue := AValue; +end; + +function TIntegerVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{$ifdef SUPPORT_INT64} + +{ TLargeIntVariable } + +constructor TLargeIntVariable.Create(AName: string; AValue: PLargeInt); +begin + inherited Create(AName, etLargeInt, _LargeIntVariable); + FValue := AValue; +end; + +function TLargeIntVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{$endif} + +{ TBooleanVariable } + +constructor TBooleanVariable.Create(AName: string; AValue: PBoolean); +begin + inherited Create(AName, etBoolean, _BooleanVariable); + FValue := AValue; +end; + +function TBooleanVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{ TLeftBracket } + +function TLeftBracket.GetResultType: TExpressionType; +begin + Result := etLeftBracket; +end; + +{ TRightBracket } + +function TRightBracket.GetResultType: TExpressionType; +begin + Result := etRightBracket; +end; + +{ TComma } + +function TComma.GetResultType: TExpressionType; +begin + Result := etComma; +end; + +{ TExpressList } + +constructor TExpressList.Create; +begin + inherited; + + FShortList := TExpressShortList.Create; +end; + +destructor TExpressList.Destroy; +begin + inherited; + FShortList.Free; +end; + +procedure TExpressList.Add(Item: Pointer); +var + I: Integer; +begin + inherited; + + { remember we reference the object } + Inc(TExprWord(Item).FRefCount); + + { also add ShortName as reference } + if Length(TExprWord(Item).ShortName) > 0 then + begin + FShortList.Search(FShortList.KeyOf(Item), I); + FShortList.Insert(I, Item); + end; +end; + +function TExpressList.Compare(Key1, Key2: Pointer): Integer; +begin + Result := StrIComp(PChar(Key1), PChar(Key2)); +end; + +function TExpressList.KeyOf(Item: Pointer): Pointer; +begin + Result := PChar(TExprWord(Item).Name); +end; + +procedure TExpressList.FreeItem(Item: Pointer); +begin + Dec(TExprWord(Item).FRefCount); + FShortList.Remove(Item); + if TExprWord(Item).FRefCount = 0 then + inherited; +end; + +function TExpressList.Search(Key: Pointer; var Index: Integer): Boolean; +var + SecIndex: Integer; +begin + Result := inherited Search(Key, Index); + if not Result then + begin + Result := FShortList.Search(Key, SecIndex); + if Result then + Index := IndexOf(FShortList.Items[SecIndex]); + end; +end; + +function TExpressShortList.Compare(Key1, Key2: Pointer): Integer; +begin + Result := StrIComp(PChar(Key1), PChar(Key2)); +end; + +function TExpressShortList.KeyOf(Item: Pointer): Pointer; +begin + Result := PChar(TExprWord(Item).ShortName); +end; + +procedure TExpressShortList.FreeItem(Item: Pointer); +begin +end; + +{ TExprCollection } + +procedure TExprCollection.Check; +var + brCount, I: Integer; +begin + brCount := 0; + for I := 0 to Count - 1 do + begin + case TExprWord(Items[I]).ResultType of + etLeftBracket: Inc(brCount); + etRightBracket: Dec(brCount); + end; + end; + if brCount <> 0 then + raise EParserException.Create('Unequal brackets'); +end; + +procedure TExprCollection.EraseExtraBrackets; +var + I: Integer; + brCount: Integer; +begin + if (TExprWord(Items[0]).ResultType = etLeftBracket) then + begin + brCount := 1; + I := 1; + while (I < Count) and (brCount > 0) do + begin + case TExprWord(Items[I]).ResultType of + etLeftBracket: Inc(brCount); + etRightBracket: Dec(brCount); + end; + Inc(I); + end; + if (brCount = 0) and (I = Count) and (TExprWord(Items[I - 1]).ResultType = + etRightBracket) then + begin + for I := 0 to Count - 3 do + Items[I] := Items[I + 1]; + Count := Count - 2; + EraseExtraBrackets; //Check if there are still too many brackets + end; + end; +end; + +{ TFunction } + +constructor TFunction.Create(AName, AShortName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType; + AExprFunc: TExprFunc; Descr: string); +begin + //to increase compatibility don't use default parameters + FDescription := Descr; + FShortName := AShortName; + InternalCreate(AName, ATypeSpec, AMinFuncArg, AResultType, AExprFunc, false, 0); +end; + +constructor TFunction.CreateOper(AName, ATypeSpec: string; AResultType: TExpressionType; + AExprFunc: TExprFunc; AOperPrec: Integer); +begin + InternalCreate(AName, ATypeSpec, -1, AResultType, AExprFunc, true, AOperPrec); +end; + +procedure TFunction.InternalCreate(AName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType; + AExprFunc: TExprFunc; AIsOperator: Boolean; AOperPrec: Integer); +begin + inherited Create(AName, AExprFunc); + + FMaxFunctionArg := Length(ATypeSpec); + FMinFunctionArg := AMinFuncArg; + if AMinFuncArg = -1 then + FMinFunctionArg := FMaxFunctionArg; + FIsOperator := AIsOperator; + FOperPrec := AOperPrec; + FTypeSpec := ATypeSpec; + FResultType := AResultType; + + // check correctness + if FMaxFunctionArg > MaxArg then + raise EParserException.Create('Too many arguments'); +end; + +function TFunction.GetDescription: string; +begin + Result := FDescription; +end; + +function TFunction.GetIsOperator: Boolean; +begin + Result := FIsOperator; +end; + +function TFunction.GetMinFunctionArg: Integer; +begin + Result := FMinFunctionArg; +end; + +function TFunction.GetMaxFunctionArg: Integer; +begin + Result := FMaxFunctionArg; +end; + +function TFunction.GetResultType: TExpressionType; +begin + Result := FResultType; +end; + +function TFunction.GetShortName: string; +begin + Result := FShortName; +end; + +function TFunction.GetTypeSpec: string; +begin + Result := FTypeSpec; +end; + +function TFunction.IsFunction: Boolean; +begin + Result := True; +end; + +{ TVaryingFunction } + +function TVaryingFunction.GetCanVary: Boolean; +begin + Result := True; +end; + +{ TDynamicType } + +constructor TDynamicType.Create(DestMem, DestPos: PPChar; ASize: PInteger); +begin + inherited Create; + + FMemory := DestMem; + FMemoryPos := DestPos; + FSize := ASize; +end; + +procedure TDynamicType.Rewind; +begin + FMemoryPos^ := FMemory^; +end; + +procedure TDynamicType.AssureSpace(ASize: Integer); +begin + // need more memory? + if ((FMemoryPos^) - (FMemory^) + ASize) > (FSize^) then + Resize((FMemoryPos^) - (FMemory^) + ASize, False); +end; + +procedure TDynamicType.Resize(NewSize: Integer; Exact: Boolean); +var + tempBuf: PChar; + bytesCopy, pos: Integer; +begin + // if not exact requested make newlength a multiple of ArgAllocSize + if not Exact then + NewSize := NewSize div ArgAllocSize * ArgAllocSize + ArgAllocSize; + // create new buffer + GetMem(tempBuf, NewSize); + // copy memory + bytesCopy := FSize^; + if bytesCopy > NewSize then + bytesCopy := NewSize; + Move(FMemory^^, tempBuf^, bytesCopy); + // save position in string + pos := FMemoryPos^ - FMemory^; + // delete old mem + FreeMem(FMemory^); + // assign new + FMemory^ := tempBuf; + FSize^ := NewSize; + // assign position + FMemoryPos^ := FMemory^ + pos; +end; + +procedure TDynamicType.Append(Source: PChar; Length: Integer); +begin + // make room for string plus null-terminator + AssureSpace(Length+4); + // copy + Move(Source^, FMemoryPos^^, Length); + Inc(FMemoryPos^, Length); + // null-terminate + FMemoryPos^^ := #0; +end; + +procedure TDynamicType.AppendInteger(Source: Integer); +begin + // make room for number + AssureSpace(12); + Inc(FMemoryPos^, GetStrFromInt(Source, FMemoryPos^)); + FMemoryPos^^ := #0; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/mdbf_prssupp.pas b/mseide-msegui/lib/common/fpccompatibility/mdbf_prssupp.pas new file mode 100644 index 0000000..2f798d8 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mdbf_prssupp.pas @@ -0,0 +1,269 @@ +unit mdbf_prssupp; + +// parse support + +{$I dbf_common.inc} + +interface + +uses + Classes; + +type + + {TOCollection interfaces between OWL TCollection and VCL TList} + + TOCollection = class(TList) + public + procedure AtFree(Index: Integer); + procedure FreeAll; + procedure DoFree(Item: Pointer); + procedure FreeItem(Item: Pointer); virtual; + destructor Destroy; override; + end; + + TNoOwnerCollection = class(TOCollection) + public + procedure FreeItem(Item: Pointer); override; + end; + + { TSortedCollection object } + + TSortedCollection = class(TOCollection) + public + function Compare(Key1, Key2: Pointer): Integer; virtual; abstract; + function IndexOf(Item: Pointer): Integer; virtual; + procedure Add(Item: Pointer); virtual; + procedure AddReplace(Item: Pointer); virtual; + procedure AddList(Source: TList; FromIndex, ToIndex: Integer); + {if duplicate then replace the duplicate else add} + function KeyOf(Item: Pointer): Pointer; virtual; + function Search(Key: Pointer; var Index: Integer): Boolean; virtual; + end; + + { TStrCollection object } + + TStrCollection = class(TSortedCollection) + public + function Compare(Key1, Key2: Pointer): Integer; override; + procedure FreeItem(Item: Pointer); override; + end; + +function GetStrFromInt(Val: Integer; const Dst: PChar): Integer; +procedure GetStrFromInt_Width(Val: Integer; const Width: Integer; const Dst: PChar; const PadChar: Char); +{$ifdef SUPPORT_INT64} +function GetStrFromInt64(Val: Int64; const Dst: PChar): Integer; +procedure GetStrFromInt64_Width(Val: Int64; const Width: Integer; const Dst: PChar; const PadChar: Char); +{$endif} + +implementation + +uses SysUtils; + +destructor TOCollection.Destroy; +begin + FreeAll; + inherited Destroy; +end; + +procedure TOCollection.AtFree(Index: Integer); +var + Item: Pointer; +begin + Item := Items[Index]; + Delete(Index); + FreeItem(Item); +end; + + +procedure TOCollection.FreeAll; +var + I: Integer; +begin + try + for I := 0 to Count - 1 do + FreeItem(Items[I]); + finally + Count := 0; + end; +end; + +procedure TOCollection.DoFree(Item: Pointer); +begin + AtFree(IndexOf(Item)); +end; + +procedure TOCollection.FreeItem(Item: Pointer); +begin + if (Item <> nil) then + with TObject(Item) as TObject do + Free; +end; + +{----------------------------------------------------------------virtual; + Implementing TNoOwnerCollection + -----------------------------------------------------------------} + +procedure TNoOwnerCollection.FreeItem(Item: Pointer); +begin +end; + +{ TSortedCollection } + +function TSortedCollection.IndexOf(Item: Pointer): Integer; +var + I: Integer; +begin + IndexOf := -1; + if Search(KeyOf(Item), I) then + begin + while (I < Count) and (Item <> Items[I]) do + Inc(I); + if I < Count then IndexOf := I; + end; +end; + +procedure TSortedCollection.AddReplace(Item: Pointer); +var + Index: Integer; +begin + if Search(KeyOf(Item), Index) then + Delete(Index); + Add(Item); +end; + +procedure TSortedCollection.Add(Item: Pointer); +var + I: Integer; +begin + Search(KeyOf(Item), I); + Insert(I, Item); +end; + +procedure TSortedCollection.AddList(Source: TList; FromIndex, ToIndex: Integer); +var + I: Integer; +begin + for I := FromIndex to ToIndex do + Add(Source.Items[I]); +end; + +function TSortedCollection.KeyOf(Item: Pointer): Pointer; +begin + Result := Item; +end; + +function TSortedCollection.Search(Key: Pointer; var Index: Integer): Boolean; +var + L, H, I, C: Integer; +begin + Result := false; + L := 0; + H := Count - 1; + while L <= H do + begin + I := (L + H) div 2; + C := Compare(KeyOf(Items[I]), Key); + if C < 0 then + L := I + 1 + else begin + H := I - 1; + Result := C = 0; + end; + end; + Index := L; +end; + +{ TStrCollection } + +function TStrCollection.Compare(Key1, Key2: Pointer): Integer; +begin + Compare := StrComp(Key1, Key2); +end; + +procedure TStrCollection.FreeItem(Item: Pointer); +begin + StrDispose(Item); +end; + +// it seems there is no pascal function to convert an integer into a PChar??? +// NOTE: in dbf_dbffile.pas there is also a convert routine, but is slightly different + +function GetStrFromInt(Val: Integer; const Dst: PChar): Integer; +var + Temp: array[0..10] of Char; + I, J: Integer; +begin + Val := Abs(Val); + // we'll have to store characters backwards first + I := 0; + J := 0; + repeat + Temp[I] := Chr((Val mod 10) + Ord('0')); + Val := Val div 10; + Inc(I); + until Val = 0; + + // remember number of digits + Result := I; + // copy value, remember: stored backwards + repeat + Dst[J] := Temp[I-1]; + Inc(J); + Dec(I); + until I = 0; + // done! +end; + +// it seems there is no pascal function to convert an integer into a PChar??? + +procedure GetStrFromInt_Width(Val: Integer; const Width: Integer; const Dst: PChar; const PadChar: Char); +var + Temp: array[0..10] of Char; + I, J: Integer; + NegSign: boolean; +begin + {$I getstrfromint.inc} +end; + +{$ifdef SUPPORT_INT64} + +procedure GetStrFromInt64_Width(Val: Int64; const Width: Integer; const Dst: PChar; const PadChar: Char); +var + Temp: array[0..19] of Char; + I, J: Integer; + NegSign: boolean; +begin + {$I getstrfromint.inc} +end; + +function GetStrFromInt64(Val: Int64; const Dst: PChar): Integer; +var + Temp: array[0..19] of Char; + I, J: Integer; +begin + Val := Abs(Val); + // we'll have to store characters backwards first + I := 0; + J := 0; + repeat + Temp[I] := Chr((Val mod 10) + Ord('0')); + Val := Val div 10; + Inc(I); + until Val = 0; + + // remember number of digits + Result := I; + // copy value, remember: stored backwards + repeat + Dst[J] := Temp[I-1]; + inc(J); + dec(I); + until I = 0; + // done! +end; + +{$endif} + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/msdfdata.pas b/mseide-msegui/lib/common/fpccompatibility/msdfdata.pas new file mode 100644 index 0000000..e4d3de4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/msdfdata.pas @@ -0,0 +1,1149 @@ +unit msdfdata; + +// +{$mode objfpc} +{$h+} + +//----------------------------------------------------------------------------- +{ Unit Name : SdfData Application : TSdfDataSet TFixedFormatDataSet Components + Version : 2.05 + Author : Orlando Arrocha email: oarrocha@hotmail.com + Purpose : This components are designed to access directly text files as + database tables. The files may be limited (SDF) or fixed size + columns. +--------------- +Modifications +--------------- +7/Jun/12 BigChimp: + Quote fields with delimiters or quotes to match Delphi SDF definition + (see e.g. help on TStrings.CommaText) +14/Jul/11 BigChimp: + Added AllowMultiLine property so user can use fields that have line endings + (Carriage Return and/or Line Feed) embedded in their fields (fields need to be + quoted). For now: output only (reading these fields does not work yet) +12/Mar/04 Lazarus version (Sergey Smirnov AKA SSY) + Locate and CheckString functions are removed because of Variant data type. + Many things are changed for FPC/Lazarus compatibility. +02/Jun/02 Version 2.05 (Doriano Biondelli) + TrimSpace property added for those cases where you need to retrieve the + field with spaces. +01/Jan/02 Version 2.04 (Orlando Arrocha) + FieldList is now populated. + Locate was changed to improve speed and some bug fixing too. Thanks for + asking and testing Marcelo Castro +16/Dec/01 Version 2.03 (Orlando Arrocha) + Fixed some bugs and added some recomentdations. Here is a list: + Quotations on the last field was not removed properly. Special thanks to + Daniel Nakasone for helping with the solution. + Appending first record to empty files was failing. Thanks again Daniel + Nakasone for the report + GetFieldData now trims the trailing spaces of the field, so users doesn't + needs to do it by themselves anymore. Thanks for the recomendation + Juergen Gehrke. + FieldDefs is now available from the designer. Recomended by Leslie Drewery. + ****** THANKS TO ALL & KEEP SENDING RECOMENDATIONS ***** +05/Oct/01 Version 2.02 (Ben Hay) + Locate function : implement the virtual tdataset method "Locate". + ****** THANKS BEN ***** +11/Sep/01 Version 2.01 (Leslie Drewery) + Added additional logic to handle Corrupt Data by making sure the + Quotes are closed and the delimiter// are the next + characters. + Altered buffer method to create on constructor and cleared when opened. + New Resource File. Nice Icons + SavetoStream method included + LoadFromStream method included + ****** THANKS LESLIE ***** +14/Ago/01 Version 2.00 (Orlando Arrocha) + John Dung Nguyen showed me how to make this compatible with C-Builder + and encouraged me to include a filter. + Dimitry V. Borko says that russian CSV files used other delimiters, + so now you can change it. + OnFilter and other events included. + Delimiter property added to TSdfDataSet. No more dependency on CommaText + methodology -- choose your own delimiter. + BufToStore/StoreToBuf methods lets you translate data records to and from + your propietary storage format. + TTextDataSet removed dependencies. + TBaseTextDataSet class removed. // TBaseTextDataSet = TFixedFormatDataSet; + ****** THANKS JOHN ****** ***** THANKS DIMMY ***** +19/Jul/01 Version 1.03 (Orlando Arrocha) + TBaseTextDataSet class introduced. + FileName property changed datatype to TFileName and removed the property + editor to segregate design-time code from runtime units. + *** To add file browsing functionality please install + *** TFileNamePropertyEditor -- also freeware. + ********** THANKS WAYNE ********* +18/Jun/01 Version 1.02 (Wayne Brantley) + Schema replaces SchemaFileName property. Same as SchemaFileName, except + you can define the schema inside the component. If you still need an + external file, just use Schema.LoadFromFile() + TFixedFormatDataSet class introduced. Use this class for a Fixed length + format file (instead of delimited). The full schema definition + (including lengths) is obviously required. + Bug Fixed - When FirstLineSchema is true and there were no records, it + would display garbage. + +30/Mar/01 Version 1.01 (Orlando Arrocha) + Ligia Maria Pimentel suggested to use the first line of the file to + define the field names. ****** THANKS LIGIA ****** + FileMustExist property. You must put this property to FALSE if you want to + create a new file. + FirstLineSchema property. You can define the field names on the first line + of your file. Fields have to be defined with this format + [= field_size1] , [= field_size2] ... + SchemaFileName property. (Changed to Schema by 1.02 Wayne) + Lets you define the fields attributes (only supports field name and + size). Have to be defined in this format (one field per line) : + [= field_size] + NOTE: fields that doesn't define the length get the record size. + RemoveBlankRecords procedure. Removes all the blank records from the file. + RemoveExtraColumns procedure. If the file have more columns than the + scheme or the field definition at design time, it remove the extra + values from the file. + SaveFileAs. Let you save the file to another filename. + NOTE: This component save changes on closing the table, so you can use + this to save data before that event. +Jan 2001 Version 1.0 TSdfDataSet introduced. +--------- +TERMS +--------- + This component is provided AS-IS without any warranty of any kind, either + express or implied. This component is freeware and can be used in any software + product. Credits on applications will be welcomed. + If you find it useful, improve it or have a wish list... please drop me a mail, + I'll be glad to hear your comments. +---------------- +How to Install +---------------- + 1. Copy this SDFDATA.PAS and the associated SDFDATA.DCR to the folder from + where you wish to install the component. This will probably be $(DELPHI)\lib + or a sub-folder. + 2. Install the TSdfDataSet and TFixedFormatDataSet components by choosing the + Component | Install Component menu option. + 3. Select the "Into exisiting package" page of the Install Components dialogue. + 4. Browse to the folder where you saved this file and select it. + 5. Ensure that the "Package file name" edit box contains $(DELPHI)\DCLUSR??.DPK + or the one you prefer for DB related objects. + 6. Accept that the package will be rebuilt. +} +//----------------------------------------------------------------------------- +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mdb, classes,mclasses,SysUtils, DBConst; + +type +//----------------------------------------------------------------------------- +// TRecInfo + PRecInfo = ^TRecInfo; + TRecInfo = packed record + RecordNumber: PtrInt; + BookmarkFlag: TBookmarkFlag; + end; +//----------------------------------------------------------------------------- +// TBaseTextDataSet + TFixedFormatDataSet = class(TDataSet) + private + FSchema :TStringList; + FFileName :TFileName; + FFilterBuffer :TRecordBuffer; + FFileMustExist :Boolean; + FReadOnly :Boolean; + FLoadfromStream :Boolean; + FTrimSpace :Boolean; + procedure SetSchema(const Value: TStringList); + procedure SetFileName(Value : TFileName); + procedure SetFileMustExist(Value : Boolean); + procedure SetTrimSpace(Value : Boolean); + procedure SetReadOnly(Value : Boolean); + procedure RemoveWhiteLines(List : TStrings; IsFileRecord : Boolean); + procedure LoadFieldScheme(List : TStrings; MaxSize : Integer); + function GetActiveRecBuf(var RecBuf: TRecordBuffer): Boolean; + procedure SetFieldPos(var Buffer : TRecordBuffer; FieldNo : Integer); + protected + FData :TStringlist; + FCurRec :Integer; + FRecBufSize :Integer; + FRecordSize :Integer; + FLastBookmark :PtrInt; + FRecInfoOfs :Integer; + FBookmarkOfs :Integer; + FSaveChanges :Boolean; + FDefaultRecordLength:Cardinal; + FDataOffset : Integer; + protected + function AllocRecordBuffer: TRecordBuffer; override; + procedure FreeRecordBuffer(var Buffer: TRecordBuffer); override; + procedure InternalAddRecord(Buffer: Pointer; DoAppend: Boolean); override; + procedure InternalClose; override; + procedure InternalDelete; override; + procedure InternalFirst; override; + procedure InternalGotoBookmark(ABookmark: Pointer); override; + procedure InternalHandleException; override; + procedure InternalInitFieldDefs; override; + procedure InternalInitRecord(Buffer: TRecordBuffer); override; + procedure InternalLast; override; + procedure InternalOpen; override; + procedure InternalPost; override; + procedure InternalEdit; override; + procedure InternalSetToRecord(Buffer: TRecordBuffer); override; + function IsCursorOpen: Boolean; override; + procedure GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); override; + function GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; override; + function GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override; + function GetRecordSize: Word; override; + procedure SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); override; + procedure SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); override; + procedure ClearCalcFields(Buffer: TRecordBuffer); override; + function GetRecordCount: Integer; override; + function GetRecNo: Integer; override; + procedure SetRecNo(Value: Integer); override; + function GetCanModify: boolean; override; + function TxtGetRecord(Buffer : TRecordBuffer; GetMode: TGetMode): TGetResult; + function RecordFilter(RecBuf: Pointer; ARecNo: Integer): Boolean; + function BufToStore(Buffer: TRecordBuffer): String; virtual; + function StoreToBuf(Source: String): String; virtual; + public + property DefaultRecordLength: Cardinal read FDefaultRecordLength + write FDefaultRecordLength default 250; + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure SetFieldData(Field: TField; Buffer: Pointer); override; + function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override; + procedure RemoveBlankRecords; dynamic; + procedure RemoveExtraColumns; dynamic; + procedure SaveFileAs(strFileName : String); dynamic; + property CanModify; + procedure LoadFromStream(Stream :TStream); + procedure SavetoStream(Stream :TStream); + published + property FileMustExist: Boolean read FFileMustExist write SetFileMustExist; + property ReadOnly: Boolean read FReadOnly write SetReadOnly; + property FileName : TFileName read FFileName write SetFileName; + property Schema: TStringList read FSchema write SetSchema; + property TrimSpace: Boolean read FTrimSpace write SetTrimSpace default True; + property FieldDefs; + property Active; + property AutoCalcFields; + property Filtered; + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; + property BeforeScroll; + property AfterScroll; +// property BeforeRefresh; +// property AfterRefresh; + property OnCalcFields; + property OnDeleteError; + property OnEditError; + property OnFilterRecord; + property OnNewRecord; + property OnPostError; + property onmodified; + end; + +//----------------------------------------------------------------------------- +// TSdfDataSet + TSdfDataSet = class(TFixedFormatDataSet) + private + FDelimiter : Char; + FFirstLineAsSchema : Boolean; + FFMultiLine :Boolean; + procedure SetMultiLine(const Value: Boolean); + procedure SetFirstLineAsSchema(Value : Boolean); + procedure SetDelimiter(Value : Char); + protected + procedure InternalInitFieldDefs; override; + function GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean) + : TGetResult; override; + function BufToStore(Buffer: TRecordBuffer): String; override; + function StoreToBuf(Source: String): String; override; + public + constructor Create(AOwner: TComponent); override; + published + property AllowMultiLine: Boolean read FFMultiLine write SetMultiLine default True; //Whether or not to allow fields containing CR and/or LF + property Delimiter: Char read FDelimiter write SetDelimiter; + property FirstLineAsSchema: Boolean read FFirstLineAsSchema write SetFirstLineAsSchema; + end; +//procedure Register; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +//{$R *.Res} + +//----------------------------------------------------------------------------- +// TFixedFormatDataSet +//----------------------------------------------------------------------------- +constructor TFixedFormatDataSet.Create(AOwner : TComponent); +begin + FDefaultRecordLength := 250; + FFileMustExist := TRUE; + FLoadfromStream := False; + FRecordSize := 0; + FTrimSpace := TRUE; + FSchema := TStringList.Create; + FData := TStringList.Create; // Load the textfile into a stringlist + inherited Create(AOwner); +end; + +destructor TFixedFormatDataSet.Destroy; +begin + inherited Destroy; + FData.Free; + FSchema.Free; +end; + +procedure TFixedFormatDataSet.SetSchema(const Value: TStringList); +begin + CheckInactive; + FSchema.Assign(Value); +end; + +procedure TFixedFormatDataSet.SetFileMustExist(Value : Boolean); +begin + CheckInactive; + FFileMustExist := Value; +end; + +procedure TFixedFormatDataSet.SetTrimSpace(Value : Boolean); +begin + CheckInactive; + FTrimSpace := Value; +end; + +procedure TFixedFormatDataSet.SetReadOnly(Value : Boolean); +begin + CheckInactive; + FReadOnly := Value; +end; + +procedure TFixedFormatDataSet.SetFileName(Value : TFileName); +begin + CheckInactive; + FFileName := Value; +end; + +procedure TFixedFormatDataSet.InternalInitFieldDefs; +var + i, len, Maxlen :Integer; + LstFields :TStrings; +begin + if not Assigned(FData) then + exit; + FRecordSize := 0; + Maxlen := 0; + FieldDefs.Clear; + for i := FData.Count - 1 downto 0 do // Find out the longest record + begin + len := Length(FData[i]); + if len > Maxlen then + Maxlen := len; + FData.Objects[i] := TObject(Pointer(i+1)); // Fabricate Bookmarks + end; + if (Maxlen = 0) then + Maxlen := FDefaultRecordLength; + LstFields := TStringList.Create; + try + LoadFieldScheme(LstFields, Maxlen); + for i := 0 to LstFields.Count -1 do // Add fields + begin + len := StrToIntDef(LstFields.Values[LstFields.Names[i]], Maxlen); + FieldDefs.Add(Trim(LstFields.Names[i]), ftString, len, False); + Inc(FRecordSize, len); + end; + finally + LstFields.Free; + end; +end; + +procedure TFixedFormatDataSet.InternalOpen; +var + Stream : TStream; +begin + FCurRec := -1; + FSaveChanges := FALSE; + if not Assigned(FData) then + FData := TStringList.Create; + if (not FileMustExist) and (not FileExists(FileName)) then + begin + Stream := TFileStream.Create(FileName, fmCreate); + Stream.Free; + end; + if not FLoadfromStream then + FData.LoadFromFile(FileName); + FRecordSize := FDefaultRecordLength; + InternalInitFieldDefs; + if DefaultFields then + CreateFields; + BindFields(TRUE); + if FRecordSize = 0 then + FRecordSize := FDefaultRecordLength; + BookmarkSize := SizeOf(PtrInt); + FRecInfoOfs := FRecordSize + CalcFieldsSize; // Initialize the offset for TRecInfo in the buffer + FBookmarkOfs := FRecInfoOfs + SizeOf(TRecInfo); + FRecBufSize := FBookmarkOfs + BookmarkSize; + FLastBookmark := FData.Count; +end; + +procedure TFixedFormatDataSet.InternalClose; +begin + if (not FReadOnly) and (FSaveChanges) then // Write any edits to disk + FData.SaveToFile(FileName); + FLoadfromStream := False; + FData.Clear; + BindFields(FALSE); + if DefaultFields then // Destroy the TField + DestroyFields; + FCurRec := -1; // Reset these internal flags + FLastBookmark := 0; + FRecordSize := 0; +end; + +function TFixedFormatDataSet.IsCursorOpen: Boolean; +begin + Result := Assigned(FData) and (FRecordSize > 0); +end; + +procedure TFixedFormatDataSet.InternalHandleException; +begin +{$ifndef fpc} + Application.HandleException(Self); +{$else} + inherited; +{$endif} +end; + +// Loads Data from a stream. +procedure TFixedFormatDataSet.LoadFromStream(Stream: TStream); +begin + if assigned(stream) then + begin + Active := False; //Make sure the Dataset is Closed. + Stream.Position := 0; //Make sure you are at the top of the Stream. + FLoadfromStream := True; + if not Assigned(FData) then + raise Exception.Create('Data buffer unassigned'); + FData.LoadFromStream(Stream); + Active := True; + end + else + raise exception.Create('Invalid Stream Assigned (Load From Stream'); +end; + +// Saves Data as text to a stream. +procedure TFixedFormatDataSet.SavetoStream(Stream: TStream); +begin + if assigned(stream) then + FData.SaveToStream(Stream) + else + raise exception.Create('Invalid Stream Assigned (Save To Stream'); +end; + +// Record Functions +function TFixedFormatDataSet.AllocRecordBuffer: TRecordBuffer; +begin + if FRecBufSize > 0 then + Result := AllocMem(FRecBufSize) + else + Result := nil; +end; + +procedure TFixedFormatDataSet.FreeRecordBuffer(var Buffer: TRecordBuffer); +begin + if Buffer <> nil then + FreeMem(Buffer); +end; + +procedure TFixedFormatDataSet.InternalInitRecord(Buffer: TRecordBuffer); +begin + FillChar(Buffer[0], FRecordSize, 0); +end; + +procedure TFixedFormatDataSet.ClearCalcFields(Buffer: TRecordBuffer); +begin + FillChar(Buffer[RecordSize], CalcFieldsSize, 0); +end; + +function TFixedFormatDataSet.GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; + DoCheck: Boolean): TGetResult; +begin + if (FData.Count < (1+FDataOffset)) then + Result := grEOF + else + Result := TxtGetRecord(Buffer, GetMode); + if Result = grOK then + begin + if (CalcFieldsSize > 0) then + GetCalcFields(Buffer); + with PRecInfo(Buffer + FRecInfoOfs)^ do + begin + BookmarkFlag := bfCurrent; + RecordNumber := PtrInt(FData.Objects[FCurRec]); + end; + end + else + if (Result = grError) and DoCheck then + DatabaseError('No Records'); +end; + +function TFixedFormatDataSet.GetRecordCount: Longint; +begin + Result := FData.Count; +end; + +function TFixedFormatDataSet.GetRecNo: Longint; +var + BufPtr: TRecordBuffer; +begin + Result := -1; + if GetActiveRecBuf(BufPtr) then + Result := PRecInfo(BufPtr + FRecInfoOfs)^.RecordNumber; +end; + +procedure TFixedFormatDataSet.SetRecNo(Value: Integer); +begin + CheckBrowseMode; + if (Value >= 0) and (Value < FData.Count) and (Value <> RecNo) then + begin + DoBeforeScroll; + FCurRec := Value - 1; + Resync([]); + DoAfterScroll; + end; +end; + +function TFixedFormatDataSet.GetRecordSize: Word; +begin + Result := FRecordSize; +end; + +function TFixedFormatDataSet.GetActiveRecBuf(var RecBuf: TRecordBuffer): Boolean; +begin + case State of + dsBrowse: if IsEmpty then RecBuf := nil else RecBuf := ActiveBuffer; + dsEdit, dsInsert: RecBuf := ActiveBuffer; + dsCalcFields: RecBuf := CalcBuffer; + dsFilter: RecBuf := FFilterBuffer; + else + RecBuf := nil; + end; + Result := RecBuf <> nil; +end; + +function TFixedFormatDataSet.TxtGetRecord(Buffer : TRecordBuffer; GetMode: TGetMode): TGetResult; +var + Accepted : Boolean; +begin + Result := grOK; + repeat + Accepted := TRUE; + case GetMode of + gmNext: + if FCurRec >= RecordCount - 1 then + Result := grEOF + else + Inc(FCurRec); + gmPrior: + if FCurRec <= FDataOffset then + Result := grBOF + else + Dec(FCurRec); + gmCurrent: + if (FCurRec < FDataOffset) or (FCurRec >= RecordCount) then + Result := grError; + end; + if (Result = grOk) then + begin + Move(PChar(StoreToBuf(FData[FCurRec]))^, Buffer[0], FRecordSize); + if Filtered then + begin + Accepted := RecordFilter(Buffer, FCurRec +1); + if not Accepted and (GetMode = gmCurrent) then + Inc(FCurRec); + end; + end; + until Accepted; +end; + +function TFixedFormatDataSet.RecordFilter(RecBuf: Pointer; ARecNo: Integer): Boolean; +var + Accept: Boolean; + SaveState: TDataSetState; +begin // Returns true if accepted in the filter + SaveState := SetTempState(dsFilter); + FFilterBuffer := RecBuf; + PRecInfo(FFilterBuffer + FRecInfoOfs)^.RecordNumber := ARecNo; + Accept := TRUE; + if Accept and Assigned(OnFilterRecord) then + OnFilterRecord(Self, Accept); + RestoreState(SaveState); + Result := Accept; +end; + +function TFixedFormatDataSet.GetCanModify: boolean; +begin + Result := not FReadOnly; +end; + +// Field Related +procedure TFixedFormatDataSet.LoadFieldScheme(List : TStrings; MaxSize : Integer); +var + tmpFieldName : string; + tmpSchema : TStrings; + i : Integer; +begin + tmpSchema := TStringList.Create; + try // Load Schema Structure + if (Schema.Count > 0) then + begin + tmpSchema.Assign(Schema); + RemoveWhiteLines(tmpSchema, FALSE); + end + else + tmpSchema.Add('Line'); + for i := 0 to tmpSchema.Count -1 do // Interpret Schema + begin + tmpFieldName := tmpSchema.Names[i]; + if (tmpFieldName = '') then + tmpFieldName := Format('%s=%d', [tmpSchema[i], MaxSize]) + else + tmpFieldName := tmpSchema[i]; + List.Add(tmpFieldName); + end; + finally + tmpSchema.Free; + end; +end; + +function TFixedFormatDataSet.GetFieldData(Field: TField; Buffer: Pointer): Boolean; +var + TempPos, recbuf : PChar; +begin + Result := GetActiveRecBuf(TRecordBuffer(RecBuf)); + if Result then + begin + if Field.FieldNo > 0 then + begin + TempPos := RecBuf; + SetFieldPos(TRecordBuffer(RecBuf), Field.FieldNo); + Result := (RecBuf < StrEnd(TempPos)); + end + else + if (State in [dsBrowse, dsEdit, dsInsert, dsCalcFields]) then + begin + Inc(RecBuf, FRecordSize + Field.Offset); + Result := Boolean(Byte(RecBuf[0])); + end; + end; + if Result and (Buffer <> nil) then + begin + StrLCopy(Buffer, RecBuf, Field.Size); + if FTrimSpace then + begin + TempPos := StrEnd(Buffer); + repeat + Dec(TempPos); + if (TempPos[0] = ' ') then + TempPos[0]:= #0 + else + break; + until (TempPos = Buffer); + end; + end; +end; + +procedure TFixedFormatDataSet.SetFieldData(Field: TField; Buffer: Pointer); +var + RecBuf: PChar; + BufEnd: PChar; + p : Integer; +begin + if not (State in dsWriteModes) then + DatabaseError(SNotEditing, Self); + GetActiveRecBuf(TRecordBuffer(RecBuf)); + if Field.FieldNo > 0 then + begin + if State = dsCalcFields then + DatabaseError('Dataset not in edit or insert mode', Self); + if Field.ReadOnly and not (State in [dsSetKey, dsFilter]) then + DatabaseErrorFmt(SReadOnlyField, [Field.DisplayName]); + if State in [dsEdit, dsInsert, dsNewValue] then + Field.Validate(Buffer); + if Field.FieldKind <> fkInternalCalc then + begin + SetFieldPos(TRecordBuffer(RecBuf), Field.FieldNo); + BufEnd := StrEnd(pansichar(ActiveBuffer)); // Fill with blanks when necessary + if BufEnd > RecBuf then + BufEnd := RecBuf; + FillChar(BufEnd[0], Field.Size + PtruInt(RecBuf) - PtruInt(BufEnd), Ord(' ')); + p := StrLen(Buffer); + if p > Field.Size then + p := Field.Size; + Move(Buffer^, RecBuf[0], p); + end; + end + else // fkCalculated, fkLookup + begin + Inc(RecBuf, FRecordSize + Field.Offset); + Move(Buffer^, RecBuf[0], Field.Size); + end; + if not (State in [dsCalcFields, dsFilter, dsNewValue]) then + DataEvent(deFieldChange, Ptrint(Field)); +end; + +procedure TFixedFormatDataSet.SetFieldPos(var Buffer : TRecordBuffer; FieldNo : Integer); +var + i : Integer; +begin + i := 1; + while (i < FieldNo) and (i < FieldDefs.Count) do + begin + Inc(Buffer, FieldDefs.Items[i-1].Size); + Inc(i); + end; +end; + +// Navigation / Editing +procedure TFixedFormatDataSet.InternalFirst; +begin + FCurRec := -1; +end; + +procedure TFixedFormatDataSet.InternalLast; +begin + FCurRec := FData.Count; +end; + +procedure TFixedFormatDataSet.InternalPost; +begin + FSaveChanges := TRUE; + inherited UpdateRecord; + if (State = dsEdit) then // just update the data in the string list + begin + FData[FCurRec] := BufToStore(ActiveBuffer); + end + else + InternalAddRecord(ActiveBuffer, FALSE); +end; + +procedure TFixedFormatDataSet.InternalEdit; +begin + +end; + +procedure TFixedFormatDataSet.InternalDelete; +begin + FSaveChanges := TRUE; + FData.Delete(FCurRec); + if FCurRec >= FData.Count then + Dec(FCurRec); +end; + +procedure TFixedFormatDataSet.InternalAddRecord(Buffer: Pointer; DoAppend: Boolean); +begin + FSaveChanges := TRUE; + Inc(FLastBookmark); + if DoAppend then + InternalLast; + if (FCurRec >=0) then + FData.InsertObject(FCurRec, BufToStore(Buffer), TObject(Pointer(FLastBookmark))) + else + FData.AddObject(BufToStore(Buffer), TObject(Pointer(FLastBookmark))); +end; + +procedure TFixedFormatDataSet.InternalGotoBookmark(ABookmark: Pointer); +var + Index: Integer; +begin + Index := FData.IndexOfObject(TObject(PPtrInt(ABookmark)^)); + if Index <> -1 then + FCurRec := Index + else + DatabaseError('Bookmark not found'); +end; + +procedure TFixedFormatDataSet.InternalSetToRecord(Buffer: TRecordBuffer); +begin + if (State <> dsInsert) then + InternalGotoBookmark(@PRecInfo(Buffer + FRecInfoOfs)^.RecordNumber); +end; + +function TFixedFormatDataSet.GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; +begin + Result := PRecInfo(Buffer + FRecInfoOfs)^.BookmarkFlag; +end; + +procedure TFixedFormatDataSet.SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); +begin + PRecInfo(Buffer + FRecInfoOfs)^.BookmarkFlag := Value; +end; + +procedure TFixedFormatDataSet.GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); +begin + Move(Buffer[FRecInfoOfs], Data^, BookmarkSize); +end; + +procedure TFixedFormatDataSet.SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); +begin + Move(Data^, Buffer[FRecInfoOfs], BookmarkSize); +end; + +procedure TFixedFormatDataSet.RemoveWhiteLines(List : TStrings; IsFileRecord : Boolean); +var + i : integer; +begin + for i := List.Count -1 downto 0 do + begin + if (Trim(List[i]) = '' ) then + if IsFileRecord then + begin + FCurRec := i; + InternalDelete; + end + else + List.Delete(i); + end; +end; + +procedure TFixedFormatDataSet.RemoveBlankRecords; +begin + RemoveWhiteLines(FData, TRUE); +end; + +procedure TFixedFormatDataSet.RemoveExtraColumns; +var + i : Integer; +begin + for i := FData.Count -1 downto 0 do + FData[i] := BufToStore(trecordbuffer(StoreToBuf(FData[i]))); + FData.SaveToFile(FileName); +end; + +procedure TFixedFormatDataSet.SaveFileAs(strFileName : String); +begin + FData.SaveToFile(strFileName); + FFileName := strFileName; + FSaveChanges := FALSE; +end; + +function TFixedFormatDataSet.StoreToBuf(Source: String): String; +begin + Result := Source; +end; + +function TFixedFormatDataSet.BufToStore(Buffer: TRecordBuffer): String; +begin + Result := Copy(pansichar(Buffer), 1, FRecordSize); +end; + +//----------------------------------------------------------------------------- +// TSdfDataSet +//----------------------------------------------------------------------------- +constructor TSdfDataSet.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FDelimiter := ','; + FFirstLineAsSchema := FALSE; + FFMultiLine :=False; +end; + +procedure TSdfDataSet.InternalInitFieldDefs; +var + pStart, pEnd, len : Integer; +begin + if not IsCursorOpen then + exit; + if (FData.Count = 0) and (Schema.Count > 0) and FirstLineAsSchema then + begin + Schema.Delimiter := Delimiter; + FData.Append(Schema.DelimitedText); + end + else if (FData.Count = 0) or (Trim(FData[0]) = '') then + begin + FirstLineAsSchema := FALSE; + FDataOffset:=0; + end + else if (Schema.Count = 0) or (FirstLineAsSchema) then + begin + Schema.Clear; + len := Length(FData[0]); + pEnd := 1; + repeat + while (pEnd <= len) and (FData[0][pEnd] in [#1..' ']) do + Inc(pEnd); + + if (pEnd > len) then + break; + + pStart := pEnd; + + if (FData[0][pStart] = '"') then + begin + repeat + Inc(pEnd); + until (pEnd > len) or (FData[0][pEnd] = '"'); + + if (FData[0][pEnd] = '"') then + Inc(pStart); + end + else + while (pEnd <= len) and (FData[0][pEnd] <> Delimiter) do + Inc(pEnd); + + if (FirstLineAsSchema) then + Schema.Add(Copy(FData[0], pStart, pEnd - pStart)) + else + Schema.Add(Format('Field%d', [Schema.Count + 1])); + + if (FData[0][pEnd] = '"') then + while (pEnd <= len) and (FData[0][pEnd] <> Delimiter) do + Inc(pEnd); + + if (FData[0][pEnd] = Delimiter) then + Inc(pEnd); + + until (pEnd > len); + end; + inherited; +end; + +function TSdfDataSet.GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; + DoCheck: Boolean): TGetResult; +begin + if FirstLineAsSchema then + begin + if (FData.Count < 2) then + begin + if GetMode=gmPrior then + Result := grBOF + else + Result := grEOF + end + else + begin + If (FCurrec=-1) and (GetMode=gmNext) then + inc(FCurrec); + Result := inherited GetRecord(Buffer, GetMode, DoCheck); + end; + end + else + Result := inherited GetRecord(Buffer, GetMode, DoCheck); +end; + +function TSdfDataSet.StoreToBuf(Source: String): String; +const + CR :char = #13; + LF :char = #10; + Quote :char = #34; // Character that encloses field if quoted. Hard-coded to " +var + IsQuoted // Whether or not field starts with a quote + :Boolean; + FieldMaxSize, // Maximum fields size as defined in FieldDefs + i, // Field counter (0..) + p // Length of string in field + :Integer; + pDeQuoted, // Temporary buffer for dedoubling quotes + pRet, // Pointer to insertion point in return value + pStr, // Beginning of field + pStrEnd // End of field + :PChar; + Ret :String; +begin + SetLength(Ret, FRecordSize); + FillChar(PChar(Ret)^, FRecordSize, Ord(' ')); + + PStrEnd := PChar(Source); + pRet := PChar(Ret); + + for i := 0 to FieldDefs.Count - 1 do + begin + FieldMaxSize := FieldDefs[i].Size; + IsQuoted := false; + while Boolean(Byte(pStrEnd[0])) and (pStrEnd[0] in [#1..' ']) do + begin + if FFMultiLine then + begin + if ((pStrEnd[0]=CR) or (pStrEnd[0]=LF)) then + begin + //view this as text, not control characters, so do nothing + //todo: check if this is really necessary, probably revert + //to original code as quoted case is handled below + end; + end + else + begin + Inc(pStrEnd); + end; + end; + + if not Boolean(Byte(pStrEnd[0])) then + break; + + pStr := pStrEnd; + + if (pStr[0] = Quote) then + begin + IsQuoted := true; // See below: accept end of string without explicit quote + if FFMultiLine then + begin + repeat + Inc(pStrEnd); + until not Boolean(Byte(pStrEnd[0])) or + ((pStrEnd[0] = Quote) and ((pStrEnd + 1)[0] in [Delimiter,#0])); + end + else + begin + // No multiline, so treat cr/lf as end of record + repeat + Inc(pStrEnd); + until not Boolean(Byte(pStrEnd[0])) or + ((pStrEnd[0] = Quote) and ((pStrEnd + 1)[0] in [Delimiter,CR,LF,#0])); + end; + + if (pStrEnd[0] = Quote) then + Inc(pStr); //Skip final quote + end + else + while Boolean(Byte(pStrEnd[0])) and (pStrEnd[0] <> Delimiter) do + Inc(pStrEnd); + + // Copy over entire field (or at least up to field length): + p := pStrEnd - pStr; + if IsQuoted then + begin + pDeQuoted := pRet; //Needed to avoid changing insertion point + // Copy entire field but not more than maximum field length: + // (We can mess with pStr now; the next loop will reset it after + // pStrEnd): + while (pstr < pStrEnd) and (pDeQuoted-pRet <= FieldMaxSize) do + begin + if pStr^ = Quote then inc(pStr);// skip first quote + pDeQuoted^ := pStr^; + inc(pStr); + inc(pDeQuoted); + end; + end + else + begin + if (p > FieldMaxSize) then + p := FieldMaxSize; + Move(pStr[0], pRet[0], p); + end; + + Inc(pRet, FieldMaxSize); + + // Move the end of field position past quotes and delimiters + // ready for processing the next field + if (pStrEnd[0] = Quote) then + while Boolean(Byte(pStrEnd[0])) and (pStrEnd[0] <> Delimiter) do + Inc(pStrEnd); + + if (pStrEnd[0] = Delimiter) then + Inc(pStrEnd); + end; + + Result := ret; +end; + +function TSdfDataSet.BufToStore(Buffer: TRecordBuffer): String; +const + QuoteDelimiter='"'; +var + Str : String; + p, i : Integer; + QuoteMe: boolean; +begin + Result := ''; + p := 1; + for i := 0 to FieldDefs.Count - 1 do + begin + QuoteMe:=false; + Str := Trim(Copy(pansichar(Buffer), p, FieldDefs[i].Size)); + Inc(p, FieldDefs[i].Size); + if FFMultiLine then + begin + // If multiline enabled, quote whenever we find carriage return or linefeed + if (not QuoteMe) and (StrScan(PChar(Str), #10) <> nil) then QuoteMe:=true; + if (not QuoteMe) and (StrScan(PChar(Str), #13) <> nil) then QuoteMe:=true; + end + else + begin + // If we don't allow multiline, remove all CR and LF because they mess with the record ends: + Str := StringReplace(Str, #10, '', [rfReplaceAll]); + Str := StringReplace(Str, #13, '', [rfReplaceAll]); + end; + // Check for any delimiters or quotes occurring in field text + if (not QuoteMe) then + if (StrScan(PChar(Str), FDelimiter) <> nil) or + (StrScan(PChar(Str), QuoteDelimiter) <> nil) then QuoteMe:=true; + if (QuoteMe) then + begin + Str := Stringreplace(Str, QuoteDelimiter, QuoteDelimiter+QuoteDelimiter, [rfReplaceAll]); + Str := QuoteDelimiter + Str + QuoteDelimiter; + end; + Result := Result + Str + FDelimiter; + end; + p := Length(Result); + while (p > 0) and (Result[p] = FDelimiter) do + begin + System.Delete(Result, p, 1); + Dec(p); + end; +end; + +procedure TSdfDataSet.SetDelimiter(Value : Char); +begin + CheckInactive; + FDelimiter := Value; +end; + +procedure TSdfDataSet.SetFirstLineAsSchema(Value : Boolean); +begin + CheckInactive; + FFirstLineAsSchema := Value; + FDataOffset:=Ord(FFirstLineAsSchema); +end; + +procedure TSdfDataSet.SetMultiLine(const Value: Boolean); +begin + FFMultiLine:=Value; +end; +{ + +//----------------------------------------------------------------------------- +// This procedure is used to register this component on the component palette +//----------------------------------------------------------------------------- +procedure Register; +begin + RegisterComponents('Data Access', [TFixedFormatDataSet]); + RegisterComponents('Data Access', [TSdfDataSet]); +end; +} +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/pngcomn.pp b/mseide-msegui/lib/common/fpccompatibility/pngcomn.pp new file mode 100644 index 0000000..ec2f7ef --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/pngcomn.pp @@ -0,0 +1,88 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + PNG reader/writer common code. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +//modified 2013 by Martin Schreiber + +{$mode objfpc}{$h+} +unit PNGcomn; + +interface + +uses SysUtils, FPImage, FPImgCmn; + +type + + PNGImageException = class (FPImageException); + + TChunkTypes = ( + ctIHDR, ctcHRM, ctgAMA, ctsBIT, + ctPLTE, ctbKGD, cthIST, cttRNS, + ctoFFs, ctpHYs, ctIDAT, cttIME, + ctsCAL, cttEXt, ctzTXt, ctIEND, + ctsRGB, ctiCCP, ctiTXt, ctsPLT, + ctUnknown + ); + + EightLong = array[0..7] of longword; + TChunkCode = array[0..3] of char; + + TChunk = record + acapacity, alength, CRC : longword; + ReadType : TChunkCode; + data : PByteArray; + aType : TChunkTypes; + end; + + TChunkHeader = record + CLength : longword; + CType : TChunkCode; + end; + + THeaderChunk = record + Width, height : longword; + BitDepth, ColorType, Compression, Filter, Interlace : byte; + end; + +const + + Signature : Array[0..7] of Byte = ($89, $50, $4E, $47, $0D, $0A, $1A, $0A); + + MaxChunkLength = $7FFFFFFF; + All1Bits : longword = $FFFFFFFF; + + ChunkTypes : array[TChunkTypes] of TChunkCode = ( + 'IHDR', 'cHRM', 'gAMA', 'sBIT', + 'PLTE', 'bKGD', 'hIST', 'tRNS', + 'oFFs', 'pHYs', 'IDAT', 'tIME', + 'sCAL', 'tEXt', 'zTXt', 'IEND', + 'sRGB', 'iCCP', 'iTXt', 'sPLT', + 'Unkn' + ); + + ChunkAncillary = $10000000; + ChunkPrivate = $00100000; + ChunkReserved = $00001000; + ChunkSafeCopy = $00000010; + + + StartRow : Array[0..7] of Integer = (0, 0, 0, 4, 0, 2, 0, 1); + StartCol : Array[0..7] of Integer = (0, 0, 4, 0, 2, 0, 1, 0); + RowInc : Array[0..7] of Integer = (1, 8, 8, 8, 4, 4, 2, 2); + ColInc : Array[0..7] of Integer = (1, 8, 8, 4, 4, 2, 2, 1); + BlockHght : Array[0..7] of Integer = (1, 8, 8, 4, 4, 2, 2, 1); + BlockWdth : Array[0..7] of Integer = (1, 8, 4, 4, 2, 2, 1, 1); + +implementation + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/zstream.pas b/mseide-msegui/lib/common/fpccompatibility/zstream.pas new file mode 100644 index 0000000..48019fd --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/zstream.pas @@ -0,0 +1,428 @@ +unit zstream; + +{********************************************************************** + This file is part of the Free Pascal free component library. + + Copyright (c) 2007 by Daniel Mantione + member of the Free Pascal development team + + Implements a Tstream descendents that allow you to read and write + compressed data according to the Deflate algorithm described in + RFC1951. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + + **********************************************************************} +//modified 2013 by Martin Schreiber + +{$ifdef FPC}{$mode objfpc}{$endif} + +{***************************************************************************} + interface +{***************************************************************************} + +uses classes,mclasses, + {$ifdef FPC}zbase,gzio{$else}zbase_del,gzio_del{$endif}; + +type + Tcompressionlevel=( + clnone, {Do not use compression, just copy data.} + clfastest, {Use fast (but less) compression.} + cldefault, {Use default compression} + clmax {Use maximum compression} + ); + + Tgzopenmode=( + gzopenread, {Open file for reading.} + gzopenwrite {Open file for writing.} + ); + + Tcustomzlibstream=class(Townerstream) + protected + Fstream:z_stream; + Fbuffer:pointer; + Fonprogress:Tnotifyevent; + procedure progress(sender:Tobject); + property onprogress:Tnotifyevent read Fonprogress write Fonprogress; + public + constructor create(stream:Tstream); + destructor destroy;override; + end; + + Tcompressionstream=class(Tcustomzlibstream) + protected + raw_written,compressed_written:longint; + public + constructor create(level:Tcompressionlevel; + dest:Tstream; + Askipheader:boolean=false); + destructor destroy;override; + function write(const buffer;count:longint):longint;override; + procedure flush; + function get_compressionrate:single; + property OnProgress; + end; + + Tdecompressionstream=class(Tcustomzlibstream) + protected + raw_read,compressed_read:longint; + skipheader:boolean; + procedure reset; + function GetPosition() : Int64; override; + public + constructor create(Asource:Tstream;Askipheader:boolean=false); + destructor destroy;override; + function read(var buffer;count:longint):longint;override; + function seek(offset:longint;origin:word):longint;override; + function get_compressionrate:single; + property OnProgress; + end; + + TGZFileStream = Class(TStream) + protected + Fgzfile:gzfile; + Ffilemode:Tgzopenmode; + public + constructor create(filename:ansistring;filemode:Tgzopenmode); + function read(var buffer;count:longint):longint;override; + function write(const buffer;count:longint):longint;override; + function seek(offset:longint;origin:word):longint;override; + destructor destroy;override; + end; + + Ezliberror=class(Estreamerror) + end; + + Egzfileerror=class(Ezliberror) + end; + + Ecompressionerror=class(Ezliberror) + end; + + Edecompressionerror=class(Ezliberror) + end; + +{***************************************************************************} + implementation +{***************************************************************************} + +uses {$ifdef FPC}zdeflate,zinflate{$else}zdeflate_del,zinflate_del{$endif}; + +const bufsize=16384; {Size of the buffer used for temporarily storing + data from the child stream.} + +resourcestring Sgz_open_error='Could not open gzip compressed file %s.'; + Sgz_read_only='Gzip compressed file was opened for reading.'; + Sgz_write_only='Gzip compressed file was opened for writing.'; + Sseek_failed='Seek in deflate compressed stream failed.'; + +constructor Tcustomzlibstream.create(stream:Tstream); + +begin + assert(stream<>nil); + inherited create(stream); + getmem(Fbuffer,bufsize); +end; + +procedure Tcustomzlibstream.progress(sender:Tobject); + +begin + if {$ifndef FPC}@{$endif}Fonprogress<>nil then + Fonprogress(sender); +end; + +destructor Tcustomzlibstream.destroy; + +begin + freemem(Fbuffer); + inherited destroy; +end; + +{***************************************************************************} + +constructor Tcompressionstream.create(level:Tcompressionlevel; + dest:Tstream; + Askipheader:boolean=false); + +var err,l:smallint; + +begin + l:= 0; + inherited create(dest); + Fstream.next_out:=Fbuffer; + Fstream.avail_out:=bufsize; + + case level of + clnone: + l:=Z_NO_COMPRESSION; + clfastest: + l:=Z_BEST_SPEED; + cldefault: + l:=Z_DEFAULT_COMPRESSION; + clmax: + l:=Z_BEST_COMPRESSION; + end; + + if Askipheader then + err:=deflateInit2(Fstream,l,Z_DEFLATED,-MAX_WBITS,DEF_MEM_LEVEL,0) + else + err:=deflateInit(Fstream,l); + if err<>Z_OK then + raise Ecompressionerror.create(zerror(err)); +end; + +function Tcompressionstream.write(const buffer;count:longint):longint; + +var err:smallint; + lastavail, + written:longint; + +begin + Fstream.next_in:=@buffer; + Fstream.avail_in:=count; + lastavail:=count; + while Fstream.avail_in<>0 do + begin + if Fstream.avail_out=0 then + begin + { Flush the buffer to the stream and update progress } + written:=source.write(Fbuffer^,bufsize); + inc(compressed_written,written); + inc(raw_written,lastavail-Fstream.avail_in); + lastavail:=Fstream.avail_in; + progress(self); + { reset output buffer } + Fstream.next_out:=Fbuffer; + Fstream.avail_out:=bufsize; + end; + err:=deflate(Fstream,Z_NO_FLUSH); + if err<>Z_OK then + raise Ecompressionerror.create(zerror(err)); + end; + inc(raw_written,lastavail-Fstream.avail_in); + write:=count; +end; + +function Tcompressionstream.get_compressionrate:single; + +begin + get_compressionrate:=100*compressed_written/raw_written; +end; + + +procedure Tcompressionstream.flush; + +var err:smallint; + written:longint; + +begin + {Compress remaining data still in internal zlib data buffers.} + repeat + if Fstream.avail_out=0 then + begin + { Flush the buffer to the stream and update progress } + written:=source.write(Fbuffer^,bufsize); + inc(compressed_written,written); + progress(self); + { reset output buffer } + Fstream.next_out:=Fbuffer; + Fstream.avail_out:=bufsize; + end; + err:=deflate(Fstream,Z_FINISH); + if err=Z_STREAM_END then + break; + if (err<>Z_OK) then + raise Ecompressionerror.create(zerror(err)); + until false; + if Fstream.avail_outZ_OK then + raise Ecompressionerror.create(zerror(err)); +end; + +function Tdecompressionstream.read(var buffer;count:longint):longint; + +var err:smallint; + lastavail:longint; + +begin + Fstream.next_out:=@buffer; + Fstream.avail_out:=count; + lastavail:=count; + while Fstream.avail_out<>0 do + begin + if Fstream.avail_in=0 then + begin + {Refill the buffer.} + Fstream.next_in:=Fbuffer; + Fstream.avail_in:=source.read(Fbuffer^,bufsize); + inc(compressed_read,Fstream.avail_in); + inc(raw_read,lastavail-Fstream.avail_out); + lastavail:=Fstream.avail_out; + progress(self); + end; + err:=inflate(Fstream,Z_NO_FLUSH); + if err=Z_STREAM_END then + break; + if err<>Z_OK then + raise Edecompressionerror.create(zerror(err)); + end; + if err=Z_STREAM_END then + dec(compressed_read,Fstream.avail_in); + inc(raw_read,lastavail-Fstream.avail_out); + read:=count-Fstream.avail_out; +end; + +procedure Tdecompressionstream.reset; + +var err:smallint; + +begin + source.seek(-compressed_read,sofromcurrent); + raw_read:=0; + compressed_read:=0; + inflateEnd(Fstream); + if skipheader then + err:=inflateInit2(Fstream,-MAX_WBITS) + else + err:=inflateInit(Fstream); + if err<>Z_OK then + raise Edecompressionerror.create(zerror(err)); +end; + +function Tdecompressionstream.GetPosition() : Int64; +begin + GetPosition := raw_read; +end; + +function Tdecompressionstream.seek(offset:longint;origin:word):longint; + +var c:longint; + +begin + if (origin=sofrombeginning) or + ((origin=sofromcurrent) and (offset+raw_read>=0)) then + begin + if origin = sofromcurrent then + seek := raw_read + offset + else + seek := offset; + + if origin=sofrombeginning then + dec(offset,raw_read); + if offset<0 then + begin + inc(offset,raw_read); + reset; + end; + while offset>0 do + begin + c:=offset; + if c>bufsize then + c:=bufsize; + c:=read(Fbuffer^,c); + dec(offset,c); + end; + end + else + raise Edecompressionerror.create(Sseek_failed); +end; + +function Tdecompressionstream.get_compressionrate:single; + +begin + get_compressionrate:=100*compressed_read/raw_read; +end; + + +destructor Tdecompressionstream.destroy; + +begin + inflateEnd(Fstream); + inherited destroy; +end; + + +{***************************************************************************} + +constructor Tgzfilestream.create(filename:ansistring;filemode:Tgzopenmode); + +begin + if filemode=gzopenread then + Fgzfile:=gzopen(filename,'rb') + else + Fgzfile:=gzopen(filename,'wb'); + Ffilemode:=filemode; + if Fgzfile=nil then + raise Egzfileerror.createfmt(Sgz_open_error,[filename]); +end; + +function Tgzfilestream.read(var buffer;count:longint):longint; + +begin + if Ffilemode=gzopenwrite then + raise Egzfileerror.create(Sgz_write_only); + read:=gzread(Fgzfile,@buffer,count); +end; + +function Tgzfilestream.write(const buffer;count:longint):longint; + +begin + if Ffilemode=gzopenread then + raise Egzfileerror.create(Sgz_write_only); + write:=gzwrite(Fgzfile,@buffer,count); +end; + +function Tgzfilestream.seek(offset:longint;origin:word):longint; + +begin + result:= gzseek(Fgzfile,offset,origin); + if result = -1 then + raise egzfileerror.create(Sseek_failed); +end; + +destructor Tgzfilestream.destroy; + +begin + gzclose(Fgzfile); + inherited destroy; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msebitmap.pas b/mseide-msegui/lib/common/graphics/msebitmap.pas new file mode 100644 index 0000000..36d38cb --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msebitmap.pas @@ -0,0 +1,3863 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msebitmap; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegraphics,msetypes,msestrings,mseinterfaces, + msegraphutils,mseclasses,mseglob,sysutils,mseguiglob; + +const + defaultimagelistwidth = 16; + defaultimagelistheight = 16; + defaultimagelistsize: sizety = (cx: defaultimagelistwidth; + cy: defaultimagelistheight); + +type +{ + imagebufferinfoty = record + image: imagety; + mask: imagety; + end; +} + tbitmapcomp = class; + + tbitmap = class(tsimplebitmap) + private + fimage: imagety; + fonchange: notifyeventty; + falignment: alignmentsty; + fopacity: colorty; + fnochange: integer; + function getscanline(index: integer): pointer; + procedure checkimage(const bgr: boolean); + procedure getimage; + procedure putimage; + function getpixel(const index: pointty): colorty; + procedure setpixel(const index: pointty; const value: colorty); + function getpixels(const x,y: integer): colorty; + procedure setpixels(const x,y: integer; const value: colorty); + function checkindex(const index: pointty): integer; overload; + function checkindex(const x,y: integer): integer; overload; + //returns index in imagety pixels for bmk_mono and bmk_rgb, + //byte offset for bmk_gray + procedure setalignment(const Value: alignmentsty); + procedure setopacity(avalue: colorty); + procedure updatealignment(const dest,source: rectty; + var alignment: alignmentsty; out newdest,newsource: rectty; + out tileorigin: pointty); + //expand copy areas in order to avoid missing pixels by position rounding + + procedure setcolorbackground(const Value: colorty); + procedure setcolorforeground(const Value: colorty); + procedure readtransparency(reader: treader); + protected + procedure getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); override; + procedure setsize(const Value: sizety); override; + function getasize: sizety; virtual; + procedure destroyhandle; override; + procedure createhandle(copyfrom: pixmapty); override; + function getsource: tbitmapcomp; virtual; + procedure assign1(const source: tsimplebitmap; const docopy: boolean); override; + //calls change + procedure dochange; virtual; + procedure defineproperties(filer: tfiler); override; + function getimageref(out aimage: imagety): boolean; + //true if buffer must be destroyed + procedure setkind(const avalue: bitmapkindty); override; + public +// constructor create(const amonochrome: boolean; +// const agdifuncs: pgdifunctionaty = nil); + //nil -> default + constructor create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); + //nil -> default + + procedure savetoimage(out aimage: imagety); + procedure loadfromimage(const aimage: imagety); + procedure assign(source: tpersistent); override; + procedure change; + procedure beginupdate; + procedure endupdate; + procedure loaddata(const asize: sizety; const data: pbyte; + const msbitfirst: boolean = false; const dwordaligned: boolean = false; + const bottomup: boolean = false); virtual; //calls change + function hasimage: boolean; + procedure paint(const acanvas: tcanvas; const dest: rectty; + const asource: rectty; aalignment: alignmentsty = []; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + //used for monochrome bitmaps, + //cl_default-> acanvas.color, acanvas.colorbackground + const aopacity: colorty = cl_default + //cl_default-> self.opacity + ); + overload; + procedure paint(const acanvas: tcanvas; const dest: pointty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default + ); overload; + //useses self.size and self.alignment + procedure paint(const acanvas: tcanvas; const dest: pointty; + const aalignment: alignmentsty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); overload; + //useses self.size + procedure paint(const acanvas: tcanvas; const dest: rectty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); overload; + //useses self.size and self.alignment + procedure paint(const acanvas: tcanvas; const dest: rectty; + const aalignment: alignmentsty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); overload; + //useses self.size + + procedure init(const acolor: colorty); override; + function compressdata: longwordarty; + procedure decompressdata(const asize: sizety; const adata: longwordarty); + property pixel[const index: pointty]: colorty read getpixel write setpixel; + property pixels[const x,y: integer]: colorty read getpixels write setpixels; + property scanline[index: integer]: pointer read getscanline; + property scanhigh: integer read fscanhigh; + //max index in scanline[0] ??? + property scanlinestep: integer read fscanlinestep; //bytes + property colorforeground: colorty read fcolorforeground write setcolorforeground default cl_black; + //used for monochrome -> color conversion + property colorbackground: colorty read fcolorbackground write setcolorbackground default cl_white; + //used for monochrome -> color conversion, + //colorbackground for color -> monochrome conversion + property alignment: alignmentsty read falignment write setalignment default []; + property opacity: colorty read fopacity write setopacity default cl_none; + property onchange: notifyeventty read fonchange write fonchange; + end; + + imageformatty = (imfor_default); + imageinfoty = (iminf_monochrome,iminf_masked,iminf_colormask, + iminf_gray,iminf_graymask); + imageinfosty = set of imageinfoty; + imageheaderty = packed record + format: longword; //imageformatty; + info: longword; //imageinfosty; + width: integer; + height: integer; + datasize: integer; + reserve: array[0..7] of longword; + end; +{ + tbitmapcanvas = class(tcanvas) + protected + function getimage(const bgr: boolean): imagety; override; + public + constructor create(const user: tbitmap); + end; +} + bitmapoptionty = (bmo_monochrome,bmo_gray, + bmo_masked,bmo_graymask,bmo_colormask, + bmo_storeorigformat, //needs mseformat*read unit at runtime + //in uses + bmo_runtimeformatdata); //do not clear origformatdata after + //load at runtime + bitmapoptionsty = set of bitmapoptionty; +const + bmokindoptions = [bmo_monochrome,bmo_gray]; + bmomaskkindoptions = [bmo_graymask,bmo_colormask]; + +type + townedbitmap = class(tbitmap) + private + fowner: tbitmap; + protected + procedure dochange; override; + public + constructor create(const aowner: tbitmap; const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); + end; + + tmaskedbitmap = class(tbitmap,iobjectlink) + private + ftransparentcolor: colorty; + fsource: tbitmapcomp; + fobjectlinker: tobjectlinker; + fmaskcolorforeground,fmaskcolorbackground: colorty; + forigformat: string; + forigformatdata: string; + fmask_source: tbitmapcomp; + procedure checkmask(); + procedure freemask(); + procedure settransparentcolor(const Value: colorty); + procedure setmask(const Value: tbitmap); + function getobjectlinker: tobjectlinker; + procedure setsource(const Value: tbitmapcomp); + function getmasked(): boolean; + procedure setmasked(const Value: boolean); + procedure readimage(stream: tstream); + procedure writeimage(stream: tstream); + procedure readimagedata(stream: tstream); + procedure writeimagedata(stream: tstream); + function getmask1(): tbitmap; + function getoptions: bitmapoptionsty; + procedure setoptions(const avalue: bitmapoptionsty); + function getcolormask(): boolean; + procedure setcolormask(const avalue: boolean); + procedure setorigformatdata(const avalue: string); + function getmaskkind(): bitmapkindty; + procedure setmaskkind(const avalue: bitmapkindty); + function getgraymask(): boolean; + procedure setgraymask(const avalue: boolean); + procedure setmask_source(const avalue: tbitmapcomp); + procedure setmaskpos(const avalue: pointty); + procedure setmask_x(const avalue: int32); + procedure setmask_y(const avalue: int32); + protected + foptions: bitmapoptionsty; + fmask: tbitmap; + fmask_pos: pointty; + procedure setkind(const avalue: bitmapkindty); override; + function gettranspcolor(): colorty; +// procedure setmonochrome(const avalue: boolean); override; + function getasize: sizety; override; + procedure createmask(const akind: bitmapkindty); virtual; + function getconverttomonochromecolorbackground: colorty; override; + procedure destroyhandle; override; + procedure setsize(const Value: sizety); override; + function writedata(const ancestor: tmaskedbitmap): boolean; + procedure defineproperties(filer: tfiler); override; + procedure objectevent(const sender: tobject; const event: objecteventty); + function getmask(out apos: pointty): tsimplebitmap; override; + function getsource: tbitmapcomp; override; + procedure assign1(const source: tsimplebitmap; const docopy: boolean); override; + procedure getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); override; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + function doloadfromstream(const atry: boolean; + const stream: tstream; + const format: string; const params: array of const): string; + function doloadfromfile(const atry: boolean; + const filename: filenamety; + const format: string; const params: array of const): string; + function doloadfromstring(const atry: boolean; + const avalue: string; + const format: string; const params: array of const): string; + public + constructor create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); + //nil -> default + destructor destroy; override; + procedure clear; override; +// class procedure freeimageinfo(var ainfo: maskedimagety); + procedure loadfrommaskedimage(const aimage: maskedimagety); + procedure savetomaskedimage(out aimage: maskedimagety); +// procedure loadfromimagebuffer(const abuffer: maskedimagety); +// procedure savetoimagebuffer(out abuffer: maskedimagety); + function bitmap: tmaskedbitmap; //self if source = nil + + procedure releasehandle; override; + procedure acquirehandle; override; + procedure initmask; + procedure stretch(const dest: tmaskedbitmap; + const aalignment: alignmentsty = + [al_stretchx,al_stretchy,al_intpol]); overload; + procedure stretch(const source: rectty; const dest: tmaskedbitmap; + const aalignment: alignmentsty = + [al_stretchx,al_stretchy,al_intpol]); overload; + procedure remask; //recalc mask + procedure automask; //transparentcolor is bottomright pixel + + + function loadfromstring(const avalue: string; const format: string; + //'' = any + const params: array of const): string; + //returns format name + function loadfromstring(const avalue: string): string; + //returns format name + function loadfromstream(const stream: tstream; const format: string; + //'' = any + const params: array of const): string; + //returns format name + function loadfromstream(const stream: tstream): string; + //returns format name + + function loadfromfile(const filename: filenamety; const format: string; + //'' = any + const params: array of const): string; + //returns format name + function loadfromfile(const filename: filenamety): string; + //returns format name + + function tryloadfromstring(const avalue: string; const format: string; + //'' = any + const params: array of const): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + function tryloadfromstring(const avalue: string): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + function tryloadfromstream(const stream: tstream; const format: string; + //'' = any + const params: array of const): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + function tryloadfromstream(const stream: tstream): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + function tryloadfromfile(const filename: filenamety; const format: string; + //'' = any + const params: array of const): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + function tryloadfromfile(const filename: filenamety): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + + procedure writetostring(out avalue: string; const format: string; + const params: array of const); overload; + function writetostring(const format: string; + const params: array of const): string; overload; + procedure writetostream(const stream: tstream; const format: string; + const params: array of const); + procedure writetofile(const filename: filenamety; const format: string; + const params: array of const); + property mask: tbitmap read getmask1 write setmask; + property maskkind: bitmapkindty read getmaskkind + write setmaskkind default bmk_mono; + property masked: boolean read getmasked write setmasked default false; + property graymask: boolean read getgraymask write setgraymask default false; + property colormask: boolean read getcolormask write setcolormask default false; + property maskcolorforeground: colorty read fmaskcolorforeground + write fmaskcolorforeground default $ffffff; + //used to init colormask + property maskcolorbackground: colorty read fmaskcolorbackground + write fmaskcolorbackground default $000000; //max transparent + //used to convert monchrome mask to colormask + property mask_pos: pointty read fmask_pos write setmaskpos; + property origformatdata: string read forigformatdata write setorigformatdata; + published + property transparentcolor: colorty read ftransparentcolor + write settransparentcolor default cl_default; + //cl_default ->bottom left pixel + property options: bitmapoptionsty read getoptions write setoptions default []; + property source: tbitmapcomp read fsource write setsource; + property mask_source: tbitmapcomp read fmask_source write setmask_source; + property mask_x: int32 read fmask_pos.x write setmask_x default 0; + property mask_y: int32 read fmask_pos.y write setmask_y default 0; + property origformat: string read forigformat write forigformat; + property colorforeground; + property colorbackground; + property alignment; + property opacity; + end; + + tcenteredbitmap = class(tmaskedbitmap) + public + constructor create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); + published + property alignment default [al_xcentered,al_ycentered]; + end; + + tbitmapcomp = class(tmsecomponent) + private + fbitmap: tmaskedbitmap; + fonchange: notifyeventty; + procedure setbitmap(const Value: tmaskedbitmap); + procedure change(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property bitmap: tmaskedbitmap read fbitmap write setbitmap; + property onchange: notifyeventty read fonchange write fonchange; + end; + + timagelist = class(tmsecomponent) + private + fsize: sizety; + fcolcount,frowcount: integer; +// fbitmap: tmaskedbitmap; + fbitmaps: array of tmaskedbitmap; + fcount: integer; + fupdating: integer; + fonchange: notifyeventty; +// fkind: bitmapkindty; + findexlookup: msestring; +// fcornermask: msestring; + fcornermask_topleft: msestring; + fcornermask_bottomleft: msestring; + fcornermask_bottomright: msestring; + fcornermask_topright: msestring; + fneedscornermaskcheck: boolean; + fhascornermask: boolean; + procedure setsize(const avalue: sizety); +// function getmonochrome: boolean; +// procedure setmonochrome(const Value: boolean); + procedure setcount(const Value: integer); + function getmasked: boolean; + procedure setmasked(const Value: boolean); + function gettransparentcolor: colorty; + procedure settransparentcolor(avalue: colorty); + procedure setheight(const Value: integer); + procedure setwidth(const Value: integer); +// procedure setbitmap(const Value: tmaskedbitmap); + procedure copyimages(const image: tmaskedbitmap; const destindex: integer; + const aversion: int32); + function getcolormask: boolean; + procedure setcolormask(const avalue: boolean); + function getkind: bitmapkindty; + procedure setkind(const avalue: bitmapkindty); + procedure setmaskkind(const avalue: bitmapkindty); + function getmaskkind: bitmapkindty; + function getgraymask: boolean; + procedure setgraymask(const avalue: boolean); + procedure readmasked(reader: treader); + procedure readcolormask(reader: treader); + procedure readmonochrome(reader: treader); + procedure readcornermask(reader: treader); + function getoptions: bitmapoptionsty; + procedure setoptions(const avalue: bitmapoptionsty); + procedure setindexlookup(const avalue: msestring); + procedure setcornermask_topleft(const avalue: msestring); + procedure setcornermask_bottomleft(const avalue: msestring); + procedure setcornermask_bottomright(const avalue: msestring); + procedure setcornermask_topright(const avalue: msestring); + function getversioncount: int32; + procedure setversioncount(const avalue: int32); + function getbitmap: tmaskedbitmap; + procedure setversiondefault(avalue: int32); + function getbitmaps(aindex: int32): tmaskedbitmap; + protected + fversionhigh: int32; //versioncount - 1 + fversiondefault: int32; //use for painting + fcornermaskmaxtopleft: int32; //biggest value of cornermask + fcornermaskmaxbottomleft: int32; //biggest value of cornermask + fcornermaskmaxbottomright: int32; //biggest value of cornermask + fcornermaskmaxtopright: int32; //biggest value of cornermask + procedure updateversionindex(var aindex: int32); + function indextoorg(index: integer): pointty; + procedure change; + procedure defineproperties(filer: tfiler); override; + procedure cornermaskchanged(); + procedure loaded() override; + procedure writeimage(stream: tstream); + procedure readimage(stream: tstream); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure beginupdate; + procedure endupdate; + + procedure clear; + procedure deleteimage(const index: integer); + + //aimage-1 -> use versiondefault + + procedure moveimage(const fromindex: integer; const toindex: integer; + aversion: int32 = -1); + procedure setimage(index: integer; image: tmaskedbitmap; + const source: rectty; aalignment: alignmentsty = []; + aversion: int32 = -1); + procedure setimage(index: integer; image: tmaskedbitmap; + //nil -> empty item + const aalignment: alignmentsty = []; aversion: int32 = -1); + procedure getimage(const index: integer; const dest: tmaskedbitmap; + aversion: int32 = -1); + function addimage(const image: tmaskedbitmap; //nil -> empty item + const aalignment: alignmentsty = []{; + const aversion: int32 = 0}): integer; + + procedure clipcornermask(const canvas: tcanvas; + const arect: rectty; const ahiddenedges: edgesty); + procedure paint(const acanvas: tcanvas; const index: integer; + const dest: pointty; const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + procedure paint(const acanvas: tcanvas; const index: integer; + const dest: rectty; const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + procedure paint(const acanvas: tcanvas; const index: integer; + const dest: rectty; source: rectty; + const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + procedure paintlookup(const acanvas: tcanvas; const index: integer; + const dest: pointty; const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + procedure paintlookup(const acanvas: tcanvas; const index: integer; + const dest: rectty; const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + procedure paintlookup(const acanvas: tcanvas; const index: integer; + const dest: rectty; source: rectty; + const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + function lookup(const aindex: int32): int32; + + procedure assign(sender: tpersistent); override; + + property size: sizety read fsize write setsize; +// property bitmap: tmaskedbitmap read fbitmap write setbitmap; + property bitmap: tmaskedbitmap read getbitmap; + property bitmaps[const aindex: int32]: tmaskedbitmap read getbitmaps; + + property kind: bitmapkindty read getkind write setkind default bmk_rgb; + property maskkind: bitmapkindty read getmaskkind + write setmaskkind default bmk_mono; +{ + property monochrome: boolean read getmonochrome + write setmonochrome default false; +} + property masked: boolean read getmasked write setmasked default true; + property graymask: boolean read getgraymask write setgraymask default false; + property colormask: boolean read getcolormask + write setcolormask default false; + property hascornermask: boolean read fhascornermask; + published + property versioncount: int32 read getversioncount + write setversioncount default 1; //first! + property versiondefault: int32 read fversiondefault + write setversiondefault default 0; + property width: integer read fsize.cx + write setwidth default defaultimagelistwidth; + property height: integer read fsize.cy + write setheight default defaultimagelistheight; + property options: bitmapoptionsty read getoptions + write setoptions default [bmo_masked]; + property transparentcolor: colorty read gettransparentcolor + write settransparentcolor default cl_none; + property count: integer read fcount write setcount default 0; + //last! + property indexlookup: msestring read findexlookup write setindexlookup; + //array of int16 + property cornermask_topleft: msestring read fcornermask_topleft + write setcornermask_topleft; + property cornermask_bottomleft: msestring read fcornermask_bottomleft + write setcornermask_bottomleft; + property cornermask_bottomright: msestring read fcornermask_bottomright + write setcornermask_bottomright; + property cornermask_topright: msestring read fcornermask_topright + write setcornermask_topright; + //array of int16, used in tframe for clipping corners of client area + //cornermask[n] = number of clipped pixels from edge of row n. + property onchange: notifyeventty read fonchange write fonchange; + end; + + iimagelistinfo = interface(inullinterface)[miid_iimagelistinfo] + function getimagelist: timagelist; + end; + + tformatstream = class + private + fstream: tstream; + fformatname: string; + fseekpos: integer; + procedure setpos(const Value: integer); + public + constructor create(stream: tstream; formatname: string); + procedure formaterror; + procedure read(var dest; count: integer); + procedure seek(count: integer); + procedure resetpos(apos: integer = 0); + property pos: integer read fseekpos write setpos; + end; + +implementation +uses + mseguiintf,msebits,msestream,mseevent,msesys,msearrayutils,msegraphicstream, + rtlconsts + {$ifndef FPC},classes_del{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsimplebitmap1 = class(tsimplebitmap); + tcanvas1 = class(tcanvas); + twriter1 = class(twriter); +type + tbitmap1 = class(tbitmap); + +procedure freeimage(var aimage: imagety); +begin + if aimage.pixels <> nil then begin + gui_freeimagemem(aimage.pixels); + fillchar(aimage,sizeof(aimage),0); + end; +end; + +procedure freeimage(var aimage: maskedimagety); +begin + freeimage(aimage.image); + freeimage(aimage.mask); +end; + +{ tformatstream } + +constructor tformatstream.create(stream: tstream; formatname: string); +begin + fstream:= stream; + fformatname:= formatname; +end; + +procedure tformatstream.formaterror; +begin + raise egraphicformat.create('Invalid file format '+fformatname); +end; + +procedure tformatstream.read(var dest; count: integer); +begin + inc(fseekpos,count); + fstream.read(dest,count); +end; + +procedure tformatstream.resetpos(apos: integer); +begin + fseekpos:= apos; +end; + +procedure tformatstream.seek(count: integer); +begin + inc(fseekpos,count); + fstream.seek(count,sofromcurrent); +end; + +procedure tformatstream.setpos(const Value: integer); +begin + seek(value-fseekpos); +end; + +{ tbitmap } + +constructor tbitmap.create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); +begin + fopacity:= cl_none; + inherited; +end; + +procedure tbitmap.assign1(const source: tsimplebitmap; const docopy: boolean); +var + bo1: boolean; +begin + if source is tbitmap then begin + bo1:= tbitmap(source).hasimage and (tbitmap(source).fimage.pixels = nil) and + (getgdiintf <> tbitmap(source).getgdiintf); + with tbitmap(source) do begin + if (fimage.pixels <> nil) or bo1 then begin + self.clear; + if bo1 then begin + savetoimage(self.fimage); + end + else begin + self.fimage:= fimage; + self.fimage.pixels:= gui_allocimagemem(fimage.length); + move(fimage.pixels^,self.fimage.pixels^,fimage.length*sizeof(longword)); + //get a copy + end; + self.fsize:= self.fimage.size; + self.fkind:= fkind; + self.updatescanline(); + { + if monochrome then begin + include(self.fstate,pms_monochrome); + end + else begin + exclude(self.fstate,pms_monochrome); + end; + } + end + else begin + inherited; + end; + end; + end + else begin + inherited; + end; + change; +end; + +procedure tbitmap.loaddata(const asize: sizety; const data: pbyte; + const msbitfirst: boolean = false; const dwordaligned: boolean = false; + const bottomup: boolean = false); +var + sourcerowstep,rowstep: integer; + ps,pd: pbyteaty; + int1,int2,int3: integer; +begin + if fkind <> bmk_mono then begin + gdierror(gde_notmonochrome,self); + end; + destroyhandle; + fsize:= asize; + if (asize.cx > 0) and (asize.cy > 0) then begin + allocimage(fimage,size,bmk_mono); + with fimage do begin +// monochrome:= true; +// size:= asize; +// rowstep:= (size.cx+31) div 32; //words +// length:= size.cy * rowstep; +// rowstep:= rowstep*4; //bytes + rowstep:= linebytes; +// pixels:= gui_allocimagemem(length); + if dwordaligned then begin + sourcerowstep:= rowstep; + end + else begin + sourcerowstep:= (asize.cx+7) div 8; + end; + int1:= asize.cy - 1; + int3:= sourcerowstep - 1; + if bottomup then begin + pd:= pointer(pchar(pixels) + int1*rowstep); + rowstep:= -rowstep; + end + else begin + pd:= pointer(pixels); + end; + ps:= pointer(data); + if msbitfirst then begin + for int1:= int1 downto 0 do begin + for int2:= int3 downto 0 do begin + pd^[int2]:= bitreverse[ps^[int2]]; + end; + inc(pbyte(ps),sourcerowstep); + inc(pbyte(pd),rowstep); + end; + end + else begin + for int1:= int1 downto 0 do begin + for int2:= int3 downto 0 do begin + pd^[int2]:= ps^[int2]; + end; + inc(pbyte(ps),sourcerowstep); + inc(pbyte(pd),rowstep); + end; + end; + end; + end; +// creategc; + change; +end; + +{ +procedure tbitmap.loaddata(const asize: sizety; data: pbyte; + msbitfirst: boolean = false; dwordaligned: boolean = false; + bottomup: boolean = false); +begin + if not monochrome then begin + gdierror(gde_notmonochrome,self); + end; + destroyhandle; + fsize:= asize; + gdi_lock; + fhandle:= gui_createbitmapfromdata(asize,data,msbitfirst,dwordaligned,bottomup); + gdi_unlock; + if fhandle = 0 then begin + gdierror(gde_pixmap); + end; + creategc; + change; +end; +} +procedure tbitmap.paint(const acanvas: tcanvas; const dest: rectty; + const asource: rectty; aalignment: alignmentsty = []; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); +var + bmp: tbitmap; + sourcebmp: tbitmapcomp; + amask: tsimplebitmap; + maskpos1: pointty; +// maskpx: pixmapty; +// maskgchandle: longword; + rect1,rect2: rectty; + po1: pointty; + col1,col2: colorty; + opa: colorty; + canvas2: tcanvas; + bmp1: tmaskedbitmap; + po2: prgbtripleaty; + int1,int2: integer; +begin + if aopacity = cl_default then begin + opa:= opacity; + end + else begin + opa:= aopacity; + end; + sourcebmp:= getsource; + amask:= getmask(maskpos1); + if sourcebmp <> nil then begin + bmp:= sourcebmp.fbitmap; +// if amask = nil then begin +// amask:= sourcebmp.fbitmap.getmask(maskpos1); +// end; + end + else begin + bmp:= self; + end; + with bmp do begin + if not isempty then begin + updatealignment(dest,asource,aalignment,rect1,rect2,po1); +// amask:= getmask(maskpos1); +// maskpx:= getmaskhandle(maskgchandle); + if (al_grayed in aalignment) and ((amask <> nil) or + (fkind = bmk_mono)) then begin + if (amask <> nil) and not (amask.kind = bmk_mono) then begin + //reduced contrast grayscale + bmp1:= tmaskedbitmap.create(bmk_rgb); + bmp1.colormask:= true; + bmp1.size:= rect2.size; + bmp1.canvas.copyarea(canvas,rect2,nullpoint); + bmp1.mask.canvas.copyarea(amask.canvas,rect2,nullpoint); + po2:= bmp1.scanline[0]; + for int1:= bmp1.scanhigh downto 0 do begin + with po2^[int1] do begin + int2:= (red+green+blue) div 8 + $80; + red:= int2; + green:= int2; + blue:= int2; + end; + end; + rect2.pos:= nullpoint; + tcanvas1(acanvas).internalcopyarea(bmp1.canvas,rect2, + rect1,acanvas.rasterop,cl_default,bmp1.mask,maskpos1, + aalignment,po1,opa); + bmp1.free; + end + else begin //shaddowed mask + if kind = bmk_mono then begin + canvas2:= canvas; + end + else begin + canvas2:= amask.canvas; + end; + with acanvas do begin + col1:= colorbackground; + col2:= color; + colorbackground:= cl_transparent; + color:= cl_white; + // copyarea(canvas2,rect2,addpoint(rect1.pos,makepoint(1,1)),acanvas.rasterop); + inc(rect1.x); + inc(rect1.y); + inc(po1.x); + inc(po1.y); + tcanvas1(acanvas).internalcopyarea(canvas2,rect2, + rect1,acanvas.rasterop,cl_default,amask,maskpos1, + aalignment,po1,opa); + color:= cl_dkgray; + // copyarea(canvas2,rect2,rect1.pos,acanvas.rasterop); + dec(rect1.x); + dec(rect1.y); + dec(po1.x); + dec(po1.y); + tcanvas1(acanvas).internalcopyarea(canvas2,rect2, + rect1,acanvas.rasterop,cl_default,amask,maskpos1, + aalignment,po1,opa); + color:= col2; + colorbackground:= col1; + end; + end; + end + else begin + if kind = bmk_mono then begin + col1:= acanvas.color; + col2:= acanvas.colorbackground; + if acolorforeground <> cl_default then begin + acanvas.color:= acolorforeground; + end + else begin + acanvas.color:= self.fcolorforeground; + end; + if acolorbackground <> cl_default then begin + acanvas.colorbackground:= acolorbackground; + end + else begin + acanvas.colorbackground:= self.fcolorbackground; + end; + tcanvas1(acanvas).internalcopyarea(bmp.canvas,rect2, + rect1,acanvas.rasterop,cl_default,amask,maskpos1, + aalignment,po1,opa); + acanvas.color:= col1; + acanvas.colorbackground:= col2; + end + else begin + tcanvas1(acanvas).internalcopyarea(bmp.canvas,rect2, + rect1,acanvas.rasterop,cl_default,amask,maskpos1, + aalignment,po1,opa); + end; + end; + end; + end; +end; + +procedure tbitmap.paint(const acanvas: tcanvas; const dest: rectty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); +begin + with tcanvas1(canvas).fvaluepo^.origin do begin + paint(acanvas,dest,makerect(makepoint(-x,-y),getasize),falignment, + acolorforeground,acolorbackground,aopacity); + end; +end; + +procedure tbitmap.paint(const acanvas: tcanvas; const dest: rectty; + const aalignment: alignmentsty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); +begin + with tcanvas1(canvas).fvaluepo^.origin do begin + paint(acanvas,dest,makerect(makepoint(-x,-y),getasize),aalignment, + acolorforeground,acolorbackground,aopacity); + end; +end; + +procedure tbitmap.paint(const acanvas: tcanvas; const dest: pointty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); +begin + with tcanvas1(canvas).fvaluepo^.origin do begin + paint(acanvas,makerect(dest,fsize),makerect(makepoint(-x,-y),getasize), + falignment,acolorforeground,acolorbackground,aopacity); + end; +end; + +procedure tbitmap.paint(const acanvas: tcanvas; const dest: pointty; + const aalignment: alignmentsty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); +begin + with tcanvas1(canvas).fvaluepo^.origin do begin + paint(acanvas,makerect(dest,getasize),makerect(makepoint(-x,-y),getasize), + aalignment,acolorforeground,acolorbackground,aopacity); + end; +end; + +procedure tbitmap.init(const acolor: colorty); +var + rgb: longword; + by1: byte; + int1: integer; +begin + if fimage.pixels = nil then begin + inherited; + end + else begin + rgb:= colortopixel(normalizeinitcolor(acolor)); + case fkind of + bmk_mono: begin + if odd(rgb xor colortopixel(cl_0)) then begin + by1:= $ff; + end + else begin + by1:= $00; + end; + fillchar(fimage.pixels^,fimage.length*sizeof(longword),by1); + end; + bmk_gray: begin + by1:= (integer(rgbtriplety(rgb).red)+integer(rgbtriplety(rgb).green)+ + integer(rgbtriplety(rgb).blue)) div 3; + fillchar(fimage.pixels^,fimage.length*sizeof(longword),by1); + end; + else begin + for int1:= 0 to fimage.length-1 do begin + fimage.pixels^[int1]:= rgb; + end; + end; + end; + end; + change; +end; +{ +procedure tbitmap.allocimagemem; +var + step: integer; +begin + if fimage.monochrome then begin + step:= (fsize.cx+31) div 32; + fimage.length:= step * fsize.cy; + end + else begin + step:= fsize.cx; + fimage.length:= fsize.cx * fsize.cy; + end; + if fimage.length > 0 then begin + fimage.pixels:= gui_allocimagemem(fimage.length); + end + else begin + fimage.pixels:= nil; + end; +end; +} +procedure tbitmap.getimage; +var + info1: drawinfoty; +begin + if fhandle <> 0 then begin + if fcanvas <> nil then begin + with tcanvas1(fcanvas),fdrawinfo.pixmapimage do begin + fillchar(image,sizeof(image),0); + pixmap:= fhandle; + gdi(gdf_pixmaptoimage); + fimage:= image; + end; + end + else begin + with info1,pixmapimage do begin + fillchar(image,sizeof(image),0); + gc.handle:= 0; + pixmap:= fhandle; + gdi_call(gdf_pixmaptoimage,info1,getgdiintf); + fimage:= image; + end; + end; + { + gdi_lock; + if fcanvas <> nil then begin + gdierrorlocked(gui_pixmaptoimage(fhandle,fimage, + tcanvas1(fcanvas).fdrawinfo.gc.handle)); + end + else begin + gdierrorlocked(gui_pixmaptoimage(fhandle,fimage,0)); + end; + } + end + else begin +// fimage.size:= fsize; +// fimage.monochrome:= monochrome; + allocimage(fimage,fsize,kind); + end; +end; + +procedure tbitmap.checkimage(const bgr: boolean); +begin + if fimage.pixels = nil then begin + getimage; + internaldestroyhandle; + end; + checkimagebgr(fimage,bgr); +end; + +procedure tbitmap.putimage; +var + info1: drawinfoty; +begin + checkimagebgr(fimage,false); + drawinfoinit(info1); + with info1,pixmapimage do begin + image:= fimage; + gc.handle:= 0; + gdi_call(gdf_imagetopixmap,info1,getgdiintf); + if error = gde_ok then begin + handle:= pixmap; +// fkind:= fimage.kind; //???necessary + { + if fimage.monochrome then begin + include(fstate,pms_monochrome); + end; + } + include(fstate,pms_ownshandle); + end; + end; +end; + +function tbitmap.checkindex(const index: pointty): integer; +begin + if (index.x < 0) or (index.y < 0) or + (index.x >= fsize.cx) or (index.y >= fsize.cy) then begin + gdierror(gde_invalidindex,self); + end; + result:= index.y*fscanlinewords; + case fkind of + bmk_mono: begin + result:= result + index.x div 32; + end; + bmk_gray: begin + result:= result*4 + index.x; + end; + else begin + result:= result + index.x; + end; + end; +end; + +function tbitmap.checkindex(const x,y: integer): integer; +begin + if (x < 0) or (y < 0) or + (x >= fsize.cx) or (y >= fsize.cy) then begin + gdierror(gde_invalidindex,self); + end; + result:= y*fscanlinewords; + case fkind of + bmk_mono: begin + result:= result + x div 32; + end; + bmk_gray: begin + result:= result*4 + x; + end; + else begin + result:= result + x; + end; + end; +end; + +function tbitmap.getscanline(index: integer): pointer; +begin + checkimage(false); + if fkind = bmk_gray then begin + result:= @pbyte(fimage.pixels)[checkindex(makepoint(0,index))]; //bytes + end + else begin + result:= @fimage.pixels[checkindex(makepoint(0,index))]; + end; +end; + +function tbitmap.getpixel(const index: pointty): colorty; +var + int1: integer; + lwo1: longword; +begin + int1:= checkindex(index); + checkimage(false); + case fkind of + bmk_mono: begin + if fimage.pixels^[int1] and bits[index.x and $1f] <> 0 then begin + result:= cl_1; + end + else begin + result:= cl_0; + end; + end; + bmk_gray: begin + lwo1:= pbyte(fimage.pixels)[int1]; + result:= lwo1 or (lwo1 shl 8) or (lwo1 shl 16); + end; + else begin + result:= fimage.pixels^[int1] and $ffffff; + end; + end; +end; + +procedure tbitmap.setpixel(const index: pointty; const value: colorty); +var + int1: integer; +begin + int1:= checkindex(index); + checkimage(false); + case kind of + bmk_mono: begin + if value = 0 then begin + fimage.pixels^[int1]:= fimage.pixels^[int1] and not bits[index.x and $1f]; + end + else begin + fimage.pixels^[int1]:= fimage.pixels^[int1] or bits[index.x and $1f]; + end; + end; + bmk_gray: begin + with rgbtriplety(value) do begin + pbyte(fimage.pixels)[int1]:= (word(red)+word(green)+word(blue)) div 3; + end; + end; + else begin + fimage.pixels^[int1]:= value and $ffffff; + end; + end; +end; + +function tbitmap.getpixels(const x,y: integer): colorty; +var + int1: integer; + lwo1: longword; +begin + int1:= checkindex(x,y); + checkimage(false); + case fkind of + bmk_mono: begin + if fimage.pixels^[int1] and bits[x and $1f] <> 0 then begin + result:= cl_1; + end + else begin + result:= cl_0; + end; + end; + bmk_gray: begin + lwo1:= pbyte(fimage.pixels)[int1]; + result:= lwo1 or (lwo1 shl 8) or (lwo1 shl 16); + end; + else begin + result:= fimage.pixels^[int1] and $ffffff; + end; + end; +end; + +procedure tbitmap.setpixels(const x,y: integer; const value: colorty); +var + int1: integer; +begin + int1:= checkindex(x,y); + checkimage(false); + case kind of + bmk_mono: begin + if value = 0 then begin + fimage.pixels^[int1]:= fimage.pixels^[int1] and not bits[x and $1f]; + end + else begin + fimage.pixels^[int1]:= fimage.pixels^[int1] or bits[x and $1f]; + end; + end; + bmk_gray: begin + with rgbtriplety(value) do begin + pbyte(fimage.pixels)[int1]:= (word(red)+word(green)+word(blue)) div 3; + end; + end; + else begin + fimage.pixels^[int1]:= value and $ffffff; + end; + end; +end; + +function tbitmap.getasize: sizety; +begin + result:= fsize; +end; + +procedure tbitmap.destroyhandle; +begin + if fimage.pixels <> nil then begin + gui_freeimagemem(fimage.pixels); + fimage.pixels:= nil; + end; + inherited; +end; + +procedure tbitmap.createhandle(copyfrom: pixmapty); +begin + if (fhandle = 0) and (fimage.pixels <> nil) then begin + putimage; + gui_freeimagemem(fimage.pixels); + fimage.pixels:= nil; + end + else begin + inherited; + end; +end; +{ +function tbitmap.getimagepo: pimagety; +begin + result:= @fimage; +end; +} +function tbitmap.getsource: tbitmapcomp; +begin + result:= nil; +end; + +procedure tbitmap.dochange; +begin + if assigned(fonchange) then begin + fonchange(self); + end; +end; + +procedure tbitmap.change; +begin + if (fnochange = 0) then begin + dochange; + end; +end; + +procedure tbitmap.setalignment(const Value: alignmentsty); +begin + if falignment <> value then begin + movealignment(value,falignment); + change; + end; +end; + +procedure tbitmap.setopacity(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if fopacity <> avalue then begin + fopacity:= avalue; + change; + end; +end; + +procedure tbitmap.updatealignment(const dest,source: rectty; + var alignment: alignmentsty; out newdest,newsource: rectty; + out tileorigin: pointty); + //expand copy areas in order to avoid missing pixels by position rounding +var + int1: integer; +begin + newdest:= dest; + newsource:= source; + if (al_fit in alignment) or (al_thumbnail in alignment) and + ((dest.cx < source.cx) or (dest.cy < source.cy)) then begin + exit; + end; + int1:= 0; + if al_xcentered in alignment then begin + if dest.cx < source.cx then begin + int1:= -1; + end; + newdest.x:= dest.x + (dest.cx - source.cx + int1) div 2 + end + else begin + if al_right in alignment then begin + newdest.x:= dest.x + dest.cx - source.cx; + end; + end; + if al_ycentered in alignment then begin + if dest.cy < source.cy then begin + int1:= -1; + end; + newdest.y:= dest.y + (dest.cy - source.cy + int1) div 2 + end + else begin + if al_bottom in alignment then begin + newdest.y:= dest.y + dest.cy - source.cy; + end; + end; + alignment:= alignment - [al_right,al_bottom,al_xcentered,al_ycentered]; + tileorigin:= newdest.pos; + if al_tiled in alignment then begin + newdest:= dest; + end + else begin + if al_stretchx in alignment then begin + newdest.x:= dest.x; + newdest.cx:= dest.cx; + end + else begin + int1:= newdest.x - dest.x; + if int1 < 0 then begin + dec(newdest.x,int1); + dec(newsource.x,int1); + inc(newsource.cx,int1); + end; + int1:= dest.x + dest.cx - (newdest.x + newsource.cx); + if int1 < 0 then begin + inc(newsource.cx,int1); + end; + newdest.cx:= newsource.cx; + end; + if al_stretchy in alignment then begin + newdest.y:= dest.y; + newdest.cy:= dest.cy; + end + else begin + int1:= newdest.y - dest.y; + if int1 < 0 then begin + dec(newdest.y,int1); + dec(newsource.y,int1); + inc(newsource.cy,int1); + end; + int1:= dest.y + dest.cy - (newdest.y + newsource.cy); + if int1 < 0 then begin + inc(newsource.cy,int1); + end; + newdest.cy:= newsource.cy; + end; + end; +end; + +procedure tbitmap.beginupdate; +begin + inc(fnochange); +end; + +procedure tbitmap.endupdate; +begin + dec(fnochange); + if fnochange = 0 then begin + dochange; + end; +end; + +procedure tbitmap.setcolorbackground(const Value: colorty); +begin + if fcolorbackground <> value then begin + fcolorbackground := Value; + change; + end; +end; + +procedure tbitmap.setcolorforeground(const Value: colorty); +begin + if fcolorforeground <> value then begin + fcolorforeground := Value; + change; + end; +end; + +function tbitmap.compressdata: longwordarty; +var + int1,int2,int3: integer; + po1: plongword; + ca1: longword; +begin + checkimage(false); + result:= nil; + allocuninitedarray(fimage.length,sizeof(longword),result); //max + case fkind of + bmk_mono,bmk_gray: begin + move(fimage.pixels^,result[0],fimage.length*sizeof(longword)); + end; + else begin + po1:= @fimage.pixels^[0]; + int2:= 0; //msb = run length + int1:= fimage.length; + while int1 > 0 do begin + ca1:= po1^ and $ffffff; + int3:= 0; + repeat + inc(po1); + inc(int3); + dec(int1); + until (po1^ and $ffffff <> ca1) or (int3 = 255) or (int1 = 0); + result[int2]:= ca1 or longword(int3 shl 24); + inc(int2); + end; + setlength(result,int2); + end; + end; +end; + +procedure tbitmap.decompressdata(const asize: sizety; const adata: longwordarty); +var + int1,int2,int3: integer; + po1: plongword; + ca1: longword; +begin + clear; + fsize:= asize; +// fimage.size:= fsize; +// fimage.monochrome:= monochrome; + allocimage(fimage,fsize,kind); + case kind of + bmk_mono,bmk_gray: begin + move(adata[0],fimage.pixels^,fimage.Length*sizeof(longword)); + end; + else begin + int2:= fimage.length; + if int2 > 0 then begin + po1:= @fimage.pixels^[0]; + for int1:= 0 to high(adata) do begin + ca1:= adata[int1] and $ffffff; + for int3:= (adata[int1] shr 24) - 1 downto 0 do begin + po1^:= ca1; + inc(po1); + dec(int2); + if int2 <= 0 then begin + break; + end; + end; + if int2 <= 0 then begin + break; + end; + end; + end; + end; + end; +end; + +procedure tbitmap.assign(source: tpersistent); +begin + if source is tbitmap then begin + with tbitmap(source) do begin + self.fcolorforeground:= colorforeground; + self.fcolorbackground:= colorbackground; + self.falignment:= alignment; + self.fopacity:= opacity; + end; + end; + inherited; +end; + +function tbitmap.hasimage: boolean; +var + bmp1: tbitmapcomp; +begin + bmp1:= getsource; + if bmp1 <> nil then begin + result:= not bmp1.bitmap.isempty; + end + else begin + result:= not isempty; + end; +end; + +procedure tbitmap.setsize(const Value: sizety); +begin + inherited; + change; +end; + +procedure tbitmap.savetoimage(out aimage: imagety); +begin + if hasimage then begin + if fimage.pixels = nil then begin + getimage; + aimage:= fimage; + fimage.pixels:= nil; + end + else begin + aimage:= fimage; + fimage.pixels:= gui_allocimagemem(fimage.length); +// allocimagemem; + move(aimage.pixels^,fimage.pixels^,fimage.length * sizeof(longword)); + //get a copy + end; + end + else begin + fillchar(aimage,sizeof(aimage),0); + end; +end; + +function tbitmap.getimageref(out aimage: imagety): boolean; + //true if buffer must be destroyed +begin + result:= fimage.pixels = nil; + if result then begin + savetoimage(aimage); + end + else begin + aimage:= fimage; + end; +end; + +procedure tbitmap.loadfromimage(const aimage: imagety); +begin + if aimage.pixels = nil then begin + clear; + end + else begin + size:= aimage.size; + { + if aimage.monochrome then begin + include(fstate,pms_monochrome); + end + else begin + exclude(fstate,pms_monochrome); + end; + } + fimage:= aimage; + fkind:= fimage.kind; + putimage; + fimage.pixels:= nil; //does not own image + end; +end; + +procedure tbitmap.getcanvasimage(const bgr: boolean; var aimage: maskedimagety); +begin + checkimage(bgr); + aimage.image:= fimage; +end; + +procedure tbitmap.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('transparency',@readtransparency,nil,false); +end; + +procedure tbitmap.readtransparency(reader: treader); +begin + opacity:= transparencytoopacity(colorty(reader.readinteger)); +end; + +procedure tbitmap.setkind(const avalue: bitmapkindty); +begin + if fkind <> avalue then begin + inherited; + if not isempty then begin + change; + end; + end; +end; + +{ tmaskedbitmap } + +constructor tmaskedbitmap.create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); + //nil -> default +begin + ftransparentcolor:= cl_default; + fmaskcolorbackground:= $000000; //max transparent + fmaskcolorforeground:= $ffffff; + case akind of + bmk_mono: begin + include(foptions,bmo_monochrome); + end; + bmk_gray: begin + include(foptions,bmo_gray); + end; + end; + inherited; +end; + +destructor tmaskedbitmap.destroy; +begin + freemask; + inherited; + fobjectlinker.free; +end; + +procedure tmaskedbitmap.clear; +begin + forigformatdata:= ''; + inherited; +end; + +{ +class procedure tmaskedbitmap.freeimageinfo(var ainfo: imagebufferinfoty); +begin + with ainfo do begin + if image.pixels <> nil then begin + gui_freeimagemem(image.pixels); + image.pixels:= nil; + end; + if mask.pixels <> nil then begin + gui_freeimagemem(mask.pixels); + mask.pixels:= nil; + end; + end; +end; +} +procedure tmaskedbitmap.freemask; +begin + freeandnil(fmask); +end; + +function tmaskedbitmap.getasize: sizety; +begin + if fsource = nil then begin + result:= fsize; + end + else begin + result:= fsource.fbitmap.fsize; + end; +end; +{ +procedure tmaskedbitmap.createmask(const acolormask: boolean); +begin + if fmask = nil then begin + fmask:= tbitmap.create(true,fgdifuncs); + with fmask do begin + fcolorforeground:= fmaskcolorforeground; + fcolorbackground:= fmaskcolorbackground; + end; + end + else begin + fmask.clear; + end; + fmask.monochrome:= not acolormask; + exclude(fstate,pms_maskvalid); +end; +} +procedure tmaskedbitmap.createmask(const akind: bitmapkindty); +begin + if fmask = nil then begin + fmask:= townedbitmap.create(self,akind,fgdifuncs); + with fmask do begin + fcolorforeground:= fmaskcolorforeground; + fcolorbackground:= fmaskcolorbackground; + end; + end + else begin + fmask.clear; //todo: gray ??? + end; +// fmask.monochrome:= not acolormask; + exclude(fstate,pms_maskvalid); +end; + +procedure tmaskedbitmap.initmask; +var + bo1: boolean; +begin + if fmask <> nil then begin + bo1:= fmask.fcanvas = nil; + fmask.size:= fsize; + if not isnullsize(fsize) then begin + if fmask.kind = bmk_mono then begin + fmask.init(cl_1); + end + else begin + fmask.init(fmaskcolorforeground); + end; + end; + if bo1 then begin + fmask.freecanvas; + end; + include(fstate,pms_maskvalid); + end; +end; + +function tmaskedbitmap.gettranspcolor(): colorty; +begin + if (ftransparentcolor = cl_default) and not isempty then begin + result:= pixel[makepoint(0,fsize.cy-1)]; + end + else begin + result:= ftransparentcolor; + end; +end; + +function tmaskedbitmap.getconverttomonochromecolorbackground(): colorty; +begin + result:= gettranspcolor(); + if ftransparentcolor = cl_none then begin + result:= inherited getconverttomonochromecolorbackground; + end; +end; + +procedure tmaskedbitmap.checkmask(); +var + col1: colorty; + ki1,ki2: bitmapkindty; +begin + ki1:= bmk_mono; + if bmo_colormask in foptions then begin + ki1:= bmk_rgb; + end + else begin + if bmo_graymask in foptions then begin + ki1:= bmk_gray; + end; + end; + ki2:= ki1; + if not(pms_maskvalid in fstate) and not isempty() then begin + col1:= gettranspcolor(); + if (col1 <> cl_none) then begin + ki2:= bmk_mono; //create a stencil mask from transparent color + end; + end; + if fmask = nil then begin + createmask(ki2); +// createmask((ftransparentcolor = cl_none) and (bmo_colormask in foptions)); + end + else begin + if fmask.kind <> ki2 then begin + if not (pms_maskvalid in fstate) then begin + fmask.clear; + end; + fmask.kind:= ki2; + end; + end; + if not isempty and not (pms_maskvalid in fstate) then begin + fmask.size:= fsize; + if col1 <> cl_none then begin //get mono mask + if kind = bmk_mono then begin + if col1 = cl_0 then begin + fmask.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint,rop_copy); + end + else begin + fmask.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint,rop_notcopy); + end + end + else begin + fmask.canvas.copyarea(canvas,makerect(nullpoint,fsize), + nullpoint,rop_copy,col1); + end; + end + else begin + initmask; + end; + include(fstate,pms_maskvalid); + end; + fmask.kind:= ki1; +// fmask.monochrome:= not (bmo_colormask in foptions); +end; + +function tmaskedbitmap.getmask1(): tbitmap; +begin + checkmask; + result:= fmask; +end; + +procedure tmaskedbitmap.settransparentcolor(const Value: colorty); +begin + if ftransparentcolor <> value then begin + ftransparentcolor:= Value; + if value <> cl_none then begin + remask; + end; + end; +end; + +function tmaskedbitmap.getmasked: boolean; +begin + result:= fmask <> nil; +end; + +procedure tmaskedbitmap.setmasked(const Value: boolean); +begin + if getmasked <> value then begin + exclude(fstate,pms_maskvalid); + if value then begin + include(foptions,bmo_masked); + checkmask; + end + else begin + exclude(foptions,bmo_masked); + freemask; + end; + change; + end; +end; +{ +procedure tmaskedbitmap.setmonochrome(const avalue: boolean); +begin + inherited; + if avalue xor (bmo_monochrome in foptions) then begin + updatebit1(longword(foptions),ord(bmo_monochrome),avalue); + change; + end; +end; +} +function tmaskedbitmap.getcolormask: boolean; +begin + result:= bmo_colormask in foptions; +end; + +procedure tmaskedbitmap.setcolormask(const avalue: boolean); +begin + if avalue then begin + options:= foptions + [bmo_colormask]; + end + else begin + options:= foptions - [bmo_colormask]; + end; +end; + +function tmaskedbitmap.getgraymask(): boolean; +begin + result:= bmo_graymask in foptions; +end; + +procedure tmaskedbitmap.setgraymask(const avalue: boolean); +begin + if avalue then begin + options:= foptions + [bmo_graymask]; + end + else begin + options:= foptions - [bmo_graymask]; + end; +end; + +procedure tmaskedbitmap.setmask_source(const avalue: tbitmapcomp); +begin + if avalue <> fmask_source then begin + getobjectlinker.setlinkedvar(iobjectlink(self),avalue, + tmsecomponent(fmask_source)); + change(); + end; +end; + +procedure tmaskedbitmap.setmaskpos(const avalue: pointty); +begin + fmask_pos:= avalue; + change(); +end; + +procedure tmaskedbitmap.setmask_x(const avalue: int32); +begin + if fmask_pos.x <> avalue then begin + fmask_pos.x:= avalue; + change(); + end; +end; + +procedure tmaskedbitmap.setmask_y(const avalue: int32); +begin + if fmask_pos.y <> avalue then begin + fmask_pos.y:= avalue; + change(); + end; +end; + +function tmaskedbitmap.getoptions: bitmapoptionsty; +begin + result:= foptions; + (* + updatebit({$ifdef FPC}longword{$else}byte{$endif}(result),ord(bmo_monochrome), + monochrome); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(result),ord(bmo_masked), + masked); + *) +end; + +procedure tmaskedbitmap.setoptions(const avalue: bitmapoptionsty); +//const +// mask1: bitmapoptionsty = [bmo_colormask]; +var + optbefore,opt2: bitmapoptionsty; + ki1: bitmapkindty; +begin + optbefore:= foptions; + foptions:= bitmapoptionsty(setsinglebit(longword(avalue),longword(foptions), + [longword([bmo_monochrome,bmo_gray]), + longword([bmo_colormask,bmo_graymask])])); + opt2:= foptions >< optbefore; + if opt2 <> [] then begin + beginupdate(); + try + if opt2 * bmokindoptions <> [] then begin + ki1:= bmk_rgb; + if bmo_monochrome in foptions then begin + ki1:= bmk_mono; + end + else begin + if bmo_gray in foptions then begin + ki1:= bmk_gray; + end; + end; + kind:= ki1; + end; + if (opt2 * bmomaskkindoptions <> []) and + (bmo_masked in foptions) and masked then begin + checkmask; + end; + masked:= bmo_masked in foptions; + finally + endupdate(); + end; + end; +(* + if (longword(foptions) xor longword(avalue)) and + {$ifdef FPC}longword{$else}byte{$endif}(mask1) <> 0 then begin + foptions:= avalue; + if fmask <> nil then begin + checkmask; + fmask.monochrome:= not (bmo_colormask in avalue); + change; + end; + end + else begin + foptions:= avalue; + end; +*) +// monochrome:= bmo_monochrome in foptions; +// masked:= bmo_masked in foptions; +end; + +function tmaskedbitmap.getmaskkind: bitmapkindty; +begin + result:= bmk_mono; + if bmo_graymask in foptions then begin + result:= bmk_gray; + end; + if bmo_colormask in foptions then begin + result:= bmk_rgb; + end; +end; + +procedure tmaskedbitmap.setmaskkind(const avalue: bitmapkindty); +var + opt1: bitmapoptionsty; +begin + opt1:= foptions - bmomaskkindoptions; + case avalue of + bmk_gray: begin + include(opt1,bmo_graymask); + end; + bmk_rgb: begin + include(opt1,bmo_colormask); + end; + end; + options:= opt1; +end; + +procedure tmaskedbitmap.remask; +begin + if fmask <> nil then begin + exclude(fstate,pms_maskvalid); + checkmask; + change; + end; +end; + +procedure tmaskedbitmap.automask; +begin + exclude(fstate,pms_maskvalid); + if not isempty then begin + transparentcolor:= pixel[makepoint(fsize.cx-1,fsize.cy-1)]; + end; + masked:= true; + checkmask; + change; +end; +{ +procedure tmaskedbitmap.savetomaskedimage(out aimage: maskedimagety); +begin + savetoimage(aimage.image); + if masked then begin + fmask.savetoimage(aimage.mask); + end + else begin + freeimage(aimage.mask); + end; +end; + +procedure tmaskedbitmap.loadfrommaskedimage(const aimage: maskedimagety); +begin + loadfromimage(aimage.image); + if aimage.mask.pixels <> nil then begin + if fmask = nil then begin + createmask(aimage.mask.kind); + end; + fmask.loadfromimage(aimage.mask); +// include(fstate,pms_maskvalid); + end + else begin + masked:= false; + end; +end; +} +procedure tmaskedbitmap.setmask(const Value: tbitmap); +var + ki1: bitmapkindty; +begin + if fmask <> value then begin + freemask; + if value <> nil then begin + ki1:= bmk_mono; + if bmo_colormask in foptions then begin + ki1:= bmk_rgb; + end + else begin + if bmo_graymask in foptions then begin + ki1:= bmk_gray; + end; + end; + createmask(ki1); + fmask.size:= fsize; + if sizeisequal(fsize,value.fsize) and + (value.kind = kind) then begin + fmask.handle:= value.handle; + end + else begin + case ki1 of + bmk_gray,bmk_rgb: begin + fmask.init(fmaskcolorbackground); + end; + else begin + fmask.init(cl_0); + end; + end; + fmask.copyarea(value,makerect(nullpoint,fsize),nullpoint,rop_copy,false, + fmaskcolorforeground,fmaskcolorbackground); + end; + include(fstate,pms_maskvalid); + end; + if masked then begin + change; + end; + end; +end; +{ +function tmaskedbitmap.getmaskhandle(var gchandle: longword): pixmapty; +begin + if fmask <> nil then begin + result:= tsimplebitmap1(fmask).handle; + if tsimplebitmap1(fmask).fcanvas <> nil then begin + gchandle:= tcanvas1(tsimplebitmap1(fmask).fcanvas).fdrawinfo.gc.handle; + end + else begin + gchandle:= 0; + end; + end + else begin + result:= 0; + end; +end; +} +function tmaskedbitmap.getmask(out apos: pointty): tsimplebitmap; +begin + if (fmask_source <> nil) then begin + result:= fmask_source.bitmap; + end + else begin + if fsource <> nil then begin + result:= fsource.bitmap.getmask(apos); //apos not used + if result = nil then begin + result:= fmask; + end; + end + else begin + result:= fmask; + end; + end; + apos:= fmask_pos; +end; + +procedure tmaskedbitmap.assign1(const source: tsimplebitmap; const docopy: boolean); +begin + beginupdate; + try + if source is tmaskedbitmap then begin + with tmaskedbitmap(source) do begin + if source <> nil then begin + self.source:= source; + end + else begin + inherited; + self.freemask; + replacebits1(longword(self.foptions),longword(foptions), + longword(bmomaskkindoptions+bmokindoptions)); + if fmask <> nil then begin + self.fmask:= tbitmap.create(fmask.kind,self.fgdifuncs); + with self,fmask do begin + fcolorforeground:= fmaskcolorforeground; + fcolorbackground:= fmaskcolorbackground; + end; +{$warnings off} + tsimplebitmap1(self.fmask).assign1(fmask,docopy); +{$warnings on} + include(self.fstate,pms_maskvalid); + include(self.foptions,bmo_masked); + end + else begin + if masked then begin + include(self.foptions,bmo_masked); + exclude(self.fstate,pms_maskvalid); + end + else begin + exclude(self.foptions,bmo_masked); + end; + end; + self.ftransparentcolor:= ftransparentcolor; + self.forigformat:= forigformat; + self.forigformatdata:= forigformatdata; + end; + end; + end + else begin + inherited; + freemask; + end; + finally + endupdate; + end; +end; + +procedure tmaskedbitmap.releasehandle; +begin + inherited; +// if fmask <> nil then begin +// tsimplebitmap1(fmask).releasehandle; +// end; +end; + +procedure tmaskedbitmap.acquirehandle; +begin + inherited; +// if fmask <> nil then begin +// tsimplebitmap1(fmask).acquirehandle; +// end; +end; + +procedure tmaskedbitmap.destroyhandle; +begin +// if fmask <> nil then begin +// tsimplebitmap1(fmask).destroyhandle; +// end; + inherited; +end; + +function tmaskedbitmap.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(iobjectlink(self),{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tmaskedbitmap.setsource(const Value: tbitmapcomp); +var + bmpcomp1: tbitmapcomp; +begin + if fsource <> value then begin + bmpcomp1:= value; + while bmpcomp1 <> nil do begin + if bmpcomp1.bitmap = self then begin + raise exception.create('Recursive bitmap source.'); + end; + bmpcomp1:= bmpcomp1.bitmap.source; + end; + beginupdate; + try + clear; + getobjectlinker.setlinkedvar(iobjectlink(self),value,tmsecomponent(fsource)); + finally + endupdate; + end; + end; +end; + +procedure tmaskedbitmap.objectevent(const sender: tobject; const event: objecteventty); +begin + if sender = fsource then begin + case event of +// oe_destroyed: source:= nil; + oe_changed: change; + end; + end; +end; + +procedure tmaskedbitmap.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tmaskedbitmap.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tmaskedbitmap.objevent(const sender: iobjectlink; const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tmaskedbitmap.getinstance: tobject; +begin + result:= self; +end; + +function tmaskedbitmap.getsource: tbitmapcomp; +begin + result:= fsource; +end; + +procedure tmaskedbitmap.setsize(const Value: sizety); +begin + inherited; + initmask; +end; + +procedure tmaskedbitmap.stretch(const source: rectty; + const dest: tmaskedbitmap; + const aalignment: alignmentsty = + [al_stretchx,al_stretchy,al_intpol]); +const + tfo = bmokindoptions+bmomaskkindoptions+[bmo_masked]; +var + size1: sizety; + bo1: boolean; + destrect: rectty; +begin + dest.beginupdate; + try + size1:= dest.size; + dest.clear; + dest.options:= (dest.options - tfo) + (options*tfo); + { + dest.monochrome:= monochrome; + dest.colormask:= colormask; + dest.masked:= masked; + } + dest.size:= size1; + bo1:= (aalignment * [al_stretchx,al_stretchy] <> + [al_stretchx,al_stretchy]) and + not (al_tiled in aalignment) and + ((source.cx <> size1.cx) or (source.cy <> size1.cy)); + if bo1 then begin + dest.init(dest.colorbackground); + end; + destrect:= calcrectalignment(mr(nullpoint,size1),source,aalignment); + tcanvas1(dest.canvas).internalcopyarea(canvas,source,destrect, + rop_copy,cl_none,nil,nullpoint,aalignment, + nullpoint,cl_none); + + if masked then begin + if bo1 then begin + dest.mask.init(dest.mask.colorbackground); + end; + tcanvas1(dest.fmask.canvas).internalcopyarea(mask.canvas,source, + destrect,rop_copy,cl_none,nil,nullpoint,aalignment,nullpoint,cl_none); + include(dest.fstate,pms_maskvalid); + end; + finally + dest.endupdate; + end; +end; + +procedure tmaskedbitmap.stretch(const dest: tmaskedbitmap; + const aalignment: alignmentsty = [al_stretchx,al_stretchy,al_intpol]); +begin + stretch(mr(nullpoint,size),dest,aalignment); +end; + +function tmaskedbitmap.writedata(const ancestor: tmaskedbitmap): boolean; +begin + result:= (fsource = nil) and not isempty and not (pms_nosave in fstate); + if result and (ancestor <> nil) then begin + result:= ((options >< ancestor.options)* + (bmokindoptions+bmomaskkindoptions+[bmo_masked]) <> []) or + (size.cx <> ancestor.size.cx) or + (size.cy <> ancestor.size.cy) or + (bmo_storeorigformat in options) and + (origformatdata <> ancestor.origformatdata); + if not result then begin + if masked then begin + fmask.checkimage(false); + ancestor.fmask.checkimage(false); + zeropad(fmask.fimage); + zeropad(ancestor.fmask.fimage); + result:= (fmask.fimage.length <> ancestor.fmask.fimage.length) or + not comparemem(fmask.fimage.pixels,ancestor.fmask.fimage.pixels, + fmask.fimage.length * sizeof(longword)); + end; + if not result then begin + checkimage(false); + ancestor.checkimage(false); + result:= (fimage.length <> ancestor.fimage.length) or + not comparemem(fimage.pixels,ancestor.fimage.pixels, + fimage.length * sizeof(longword)); + end; + end; + end; +end; + +procedure tmaskedbitmap.defineproperties(filer: tfiler); +var + bo1: boolean; +begin + inherited; + bo1:= (forigformatdata <> '') and (bmo_storeorigformat in options); + filer.DefineBinaryProperty('image',{$ifdef FPC}@{$endif}readimage, + {$ifdef FPC}@{$endif}writeimage, + not bo1 and writedata(tmaskedbitmap(filer.ancestor))); + filer.DefineBinaryProperty('imagedata',{$ifdef FPC}@{$endif}readimagedata, + {$ifdef FPC}@{$endif}writeimagedata, + bo1 and writedata(tmaskedbitmap(filer.ancestor))); + if (filer is treader) and not(csdesigning in filer.root.componentstate) and + not(bmo_runtimeformatdata in options) then begin + forigformatdata:= ''; + end; +end; + +procedure tmaskedbitmap.writeimage(stream: tstream); +var + header: imageheaderty; + int1: integer; + ar1: longwordarty; +begin + fillchar(header,sizeof(header),0); + with header do begin + width:= fsize.cx; + height:= fsize.cy; + case fkind of + bmk_mono: begin + setbit1(info,ord(iminf_monochrome)); + end; + bmk_gray: begin + setbit1(info,ord(iminf_gray)); + end; + end; + if masked then begin + setbit1(info,ord(iminf_masked)); + case fmask.fkind of + bmk_gray: begin + setbit1(info,ord(iminf_graymask)); + end; + bmk_rgb: begin + setbit1(info,ord(iminf_colormask)); + end; + end; + end; + ar1:= compressdata; + datasize:= length(ar1)*4; + stream.Writebuffer(header,sizeof(header)); + stream.Writebuffer(ar1[0],datasize); + end; + if masked then begin + checkmask; + ar1:= fmask.compressdata; + int1:= length(ar1)*4; + if fmask.kind <> bmk_mono then begin + stream.WriteBuffer(int1,4); + end; + stream.WriteBuffer(ar1[0],int1); + end; +end; + +procedure tmaskedbitmap.readimage(stream: tstream); +var + header: imageheaderty; + int1: integer; + ar1: longwordarty; + ki1: bitmapkindty; + +begin + beginupdate; + try + clear; + stream.readbuffer(header,sizeof(header)); + fkind:= bmk_rgb; + with header do begin + if checkbit(info,ord(iminf_monochrome)) then begin + fkind:= bmk_mono; +// include(fstate,pms_monochrome); + end + else begin + if checkbit(info,ord(iminf_gray)) then begin + fkind:= bmk_gray; + end; +// exclude(fstate,pms_monochrome); + end; + if checkbit(info,ord(iminf_masked)) then begin +// ftransparentcolor:= cl_none; + ki1:= bmk_mono; + if checkbit(info,ord(iminf_colormask)) then begin + ki1:= bmk_rgb; + end + else begin + if checkbit(info,ord(iminf_graymask)) then begin + ki1:= bmk_gray; + end; + end; + createmask(ki1); +// createmask(checkbit(info,ord(iminf_colormask))); + end + else begin + freemask; + end; + allocuninitedarray(datasize div 4,4,ar1); +// setlength(ar1,datasize div 4); + stream.ReadBuffer(ar1[0],length(ar1)*4); + decompressdata(makesize(width,height),ar1); + if masked then begin + if fmask.kind = bmk_mono then begin + int1:= ((fsize.cx + 31) div 32) * fsize.cy; + end + else begin + stream.ReadBuffer(int1,sizeof(int1)); + int1:= int1 div 4; + end; + setlength(ar1,int1); + stream.readbuffer(ar1[0],int1*4); + fmask.decompressdata(fsize,ar1); + include(fstate,pms_maskvalid); + end; + end; + finally + endupdate; + end; +end; + +procedure tmaskedbitmap.readimagedata(stream: tstream); +var + lint1: int64; + str1: string; + optionsbefore: bitmapoptionsty; +begin + stream.readbuffer(lint1,sizeof(lint1)); +{$ifdef FPC} + lint1:= leton(lint1); +{$endif} + setlength(str1,lint1); + optionsbefore:= options; + stream.readbuffer(pchar(pointer(str1))^,lint1); + origformatdata:= str1; + options:= optionsbefore; // restore mask options +end; + +procedure tmaskedbitmap.writeimagedata(stream: tstream); +var + lint1: int64; +begin + lint1:= length(forigformatdata); +{$ifdef FPC} + stream.writebuffer(lint1,sizeof(ntole(lint1))); +{$else} + stream.writebuffer(lint1,sizeof(lint1)); +{$endif} + stream.writebuffer(pchar(pointer(forigformatdata))^,lint1); +end; + +function tmaskedbitmap.doloadfromstream(const atry: boolean; + const stream: tstream; + const format: string; const params: array of const): string; +var + int1,int2: integer; +begin + int1:= stream.position; + if atry then begin + result:= tryreadgraphic(stream,self,format,params); + end + else begin + result:= readgraphic(stream,self,format,params); + end; + int2:= stream.position; + if bmo_storeorigformat in options then begin + forigformat:= result; + int2:= int2-int1; + setlength(forigformatdata,int2); + stream.position:= int1; + stream.readbuffer(pchar(pointer(forigformatdata))^,int2); + end; +end; + +function tmaskedbitmap.doloadfromfile(const atry: boolean; + const filename: filenamety; + const format: string; const params: array of const): string; +var + stream: tmsefilestream; +begin + stream:= tmsefilestream.create(filename,fm_read); + try + result:= doloadfromstream(atry,stream,format,params); + finally + stream.free; + end; +end; + +function tmaskedbitmap.doloadfromstring(const atry: boolean; + const avalue: string; + const format: string; const params: array of const): string; +var + stream1: tstringcopystream; +begin + result:= ''; + if avalue = '' then begin + clear; + end + else begin + stream1:= tstringcopystream.create(avalue); + try + result:= doloadfromstream(atry,stream1,format,params); + finally + stream1.free; + end; + end; +end; + +function tmaskedbitmap.tryloadfromstream(const stream: tstream; + const format: string; const params: array of const): string; +begin + result:= doloadfromstream(true,stream,format,params); +end; + +function tmaskedbitmap.loadfromstream(const stream: tstream; + const format: string; const params: array of const): string; +begin + result:= doloadfromstream(false,stream,format,params); +end; + + +function tmaskedbitmap.loadfromfile(const filename: filenamety; + const format: string; const params: array of const): string; +begin + result:= doloadfromfile(false,filename,format,params); +end; + +function tmaskedbitmap.tryloadfromfile(const filename: filenamety; + const format: string; const params: array of const): string; +begin + result:= doloadfromfile(true,filename,format,params); +end; + +function tmaskedbitmap.loadfromstring(const avalue: string; + const format: string; const params: array of const): string; +begin + result:= doloadfromstring(false,avalue,format,params); +end; + +function tmaskedbitmap.tryloadfromstring(const avalue: string; + const format: string; const params: array of const): string; +begin + result:= doloadfromstring(true,avalue,format,params); +end; + +function tmaskedbitmap.loadfromstring(const avalue: string): string; +begin + result:= loadfromstring(avalue,'',[]); +end; + +function tmaskedbitmap.loadfromstream(const stream: tstream): string; +begin + result:= loadfromstream(stream,'',[]); +end; + +function tmaskedbitmap.loadfromfile(const filename: filenamety): string; +begin + result:= loadfromfile(filename,'',[]); +end; + +function tmaskedbitmap.tryloadfromstring(const avalue: string): string; +begin + result:= tryloadfromstring(avalue,'',[]); +end; + +function tmaskedbitmap.tryloadfromstream(const stream: tstream): string; +begin + result:= tryloadfromstream(stream,'',[]); +end; + +function tmaskedbitmap.tryloadfromfile(const filename: filenamety): string; +begin + result:= tryloadfromfile(filename,'',[]); +end; + +procedure tmaskedbitmap.writetostring(out avalue: string; const format: string; + const params: array of const); +var + stream1: tstringstream; +begin + stream1:= tstringstream.create(''); + try + writetostream(stream1,format,params); + avalue:= stream1.datastring; + finally + stream1.free; + end; +end; + +function tmaskedbitmap.writetostring(const format: string; + const params: array of const): string; +begin + writetostring(result,format,params); +end; + +procedure tmaskedbitmap.writetostream(const stream: tstream; const format: string; + const params: array of const); +begin + writegraphic(stream,self,format,params); +end; + +procedure tmaskedbitmap.writetofile(const filename: filenamety; const format: string; + const params: array of const); +var + stream1: tmsefilestream; +begin + stream1:= tmsefilestream.create(filename,fm_create); + try + writetostream(stream1,format,params) + finally + stream1.free; + end; +end; + +procedure tmaskedbitmap.loadfrommaskedimage(const aimage: maskedimagety); +begin + loadfromimage(aimage.image); + if aimage.mask.pixels <> nil then begin + include(foptions,bmo_masked); + createmask(aimage.mask.kind); + fmask.loadfromimage(aimage.mask); + foptions:= foptions - bmomaskkindoptions; + case aimage.mask.kind of + bmk_rgb: begin + include(foptions,bmo_colormask); + end; + bmk_gray: begin + include(foptions,bmo_graymask); + end; + end; +{ + if abuffer.mask.monochrome then begin + exclude(foptions,bmo_colormask); + end + else begin + include(foptions,bmo_colormask); + end; +} + include(fstate,pms_maskvalid); + end + else begin + freemask; + exclude(foptions,bmo_masked); + exclude(fstate,pms_maskvalid); + end; +end; + +procedure tmaskedbitmap.savetomaskedimage(out aimage: maskedimagety); +begin + savetoimage(aimage.image); + if fmask <> nil then begin + fmask.savetoimage(aimage.mask); + end + else begin + fillchar(aimage.mask,sizeof(aimage.mask),0); + end; +end; + +function tmaskedbitmap.bitmap: tmaskedbitmap; +begin + if fsource = nil then begin + result:= self; + end + else begin + result:= fsource.bitmap; + end; +end; + +procedure tmaskedbitmap.getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); +begin + inherited; + if fmask <> nil then begin + fmask.checkimage(bgr); + aimage.mask:= fmask.fimage; + end; +end; + +procedure tmaskedbitmap.setorigformatdata(const avalue: string); +begin + forigformatdata:= avalue; + if avalue <> '' then begin + loadfromstring(avalue,forigformat,[]); + end; +end; + +procedure tmaskedbitmap.setkind(const avalue: bitmapkindty); +begin + foptions:= foptions - bmokindoptions; + case avalue of + bmk_gray: begin + include(foptions,bmo_gray); + end; + bmk_mono: begin + include(foptions,bmo_monochrome); + end; + end; + inherited; +end; + +{ +procedure tmaskedbitmap.loadfromresourcename(instance: longword; + const resname: string); +var + stream: tresourcestream; + formatstream: tformatstream; +begin + stream:= tresourcestream.Create(instance,uppercase(resname),RT_BITMAP); + formatstream:= tformatstream.create(stream,'bmp'); + try + readbmp(formatstream,0,self); + finally + formatstream.Free; + stream.Free; + end; +end; +} +{ +procedure tmaskedbitmap.readimagefile(const filename: filenamety); +var + stream: tmsefilestream; +begin + stream:= tmsefilestream.create(filename,fm_read); + try + msebitmap.readimage(stream,self); + finally + stream.Free; + end; + change; +end; +} +{ tbitmapcomp } + +constructor tbitmapcomp.create(aowner: tcomponent); +begin + inherited; + fbitmap:= tmaskedbitmap.create(bmk_rgb); + fbitmap.fonchange:= {$ifdef FPC}@{$endif}change; +end; + +destructor tbitmapcomp.destroy; +begin + inherited; + fbitmap.Free; +end; + +procedure tbitmapcomp.setbitmap(const Value: tmaskedbitmap); +begin + fbitmap.assign(value); +end; + +procedure tbitmapcomp.change(const sender: tobject); +begin + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; + if assigned(fonchange) then begin + fonchange(self); + end; +end; + +{ timagelist } + +constructor timagelist.create(aowner: tcomponent); +var + bmp1: tmaskedbitmap; +begin + fsize:= defaultimagelistsize; + inherited; + bmp1:= tmaskedbitmap.create(bmk_rgb); + bmp1.transparentcolor:= cl_none; + setlength(fbitmaps,1); + fbitmaps[0]:= bmp1; + masked:= true; +end; + +destructor timagelist.destroy; +begin + if fbitmaps <> nil then begin //otherwise exception in constructor + versioncount:= 1; + fbitmaps[0].Free; + end; + inherited; +end; + +function timagelist.getversioncount: int32; +begin + result:= fversionhigh + 1; +end; + +procedure timagelist.setversioncount(const avalue: int32); +var + i1,i2: int32; + bmp1,bmp2: tmaskedbitmap; +begin + i1:= avalue - 1; + if i1 < 0 then begin + i1:= 0; + end; + if i1 <> fversionhigh then begin + if i1 < fversionhigh then begin + for i2:= fversionhigh downto i1 + 1 do begin + fbitmaps[i2].destroy(); + end; + setlength(fbitmaps,i1+1); + end + else begin + bmp1:= fbitmaps[0]; + setlength(fbitmaps,avalue); + for i2:= fversionhigh + 1 to i1 do begin + bmp2:= tmaskedbitmap.create(bmp1.kind); + if not (csreading in componentstate) then begin + bmp2.assign(bmp1); + end + else begin + bmp2.transparentcolor:= bmp1.transparentcolor; + bmp2.options:= bmp1.options; + bmp2.size:= bmp1.size; + end; + fbitmaps[i2]:= bmp2; + end; + end; + fversionhigh:= i1; + if fversiondefault > i1 then begin + fversiondefault:= 0; + end; + end; +end; + +procedure timagelist.setversiondefault(avalue: int32); +begin + if (avalue < 0) or (avalue > fversionhigh) then begin + avalue:= 0; + end; + if fversiondefault <> avalue then begin + fversiondefault:= avalue; + change(); + end; +end; + +procedure timagelist.updateversionindex(var aindex: int32); +begin + if (aindex < 0) then begin + aindex:= fversiondefault; + end + else begin + if aindex > fversionhigh then begin + tlist.Error(SListIndexError, aIndex); + end; + end; +end; + +function timagelist.getbitmaps(aindex: int32): tmaskedbitmap; +begin + updateversionindex(aindex); + result:= fbitmaps[aindex]; +end; + +function timagelist.getbitmap: tmaskedbitmap; +begin + result:= fbitmaps[0]; +end; + +procedure timagelist.clear; +begin + count:= 0; +end; + +procedure timagelist.setsize(const avalue: sizety); +var + int1: integer; + bmp1,bmp2: tmaskedbitmap; + sizebefore: sizety; + countbefore: integer; + rect1,rect2: rectty; + i1: int32; +begin + if not sizeisequal(fsize,avalue) then begin + sizebefore:= fsize; + fsize:= avalue; + if fcount <> 0 then begin + beginupdate; + for i1:= 0 to fversionhigh do begin + bmp1:= tmaskedbitmap.create(bmk_rgb); + bmp1.assign(fbitmaps[i1]); + bmp2:= tmaskedbitmap.create(bmk_rgb); + bmp2.assign(fbitmaps[i1]); //get mask and color modes + bmp2.size:= sizebefore; + fbitmaps[i1].clear; + countbefore:= fcount; + count:= 0; + count:= countbefore; + rect1:= makerect(nullpoint,fsize); + rect2:= makerect(nullpoint,sizebefore); + centerinrect(rect1,rect2); + for int1:= 0 to count - 1 do begin + bmp2.canvas.copyarea(bmp1.canvas,rect2,nullpoint); + if bmp1.mask <> nil then begin + bmp2.mask.canvas.copyarea(bmp1.mask.canvas,rect2,nullpoint); + end; + setimage(int1,bmp2,rect1); + with rect2 do begin + inc(x,cx); + if x >= bmp1.fsize.cx then begin + x:= 0; + inc(y,cy); + end; + end; + end; + bmp1.free; + bmp2.free; + end; + endupdate; + end; + end; +end; + +function timagelist.indextoorg(index: integer): pointty; +begin + if (index < 0) or (index >= fcount) then begin + gdierror(gde_invalidindex); + end; + result.x:= (index mod fcolcount) * fsize.cx; + result.y:= (index div frowcount) * fsize.cy; +end; + +function timagelist.getmasked: boolean; +begin + result:= fbitmaps[0].masked; +end; + +procedure timagelist.setmasked(const Value: boolean); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].masked:= value; + end; +end; +{ +function timagelist.getmonochrome: boolean; +begin + result:= fbitmap.monochrome; +end; +} +function timagelist.getgraymask: boolean; +begin + result:= fbitmaps[0].graymask; +end; + +procedure timagelist.setgraymask(const avalue: boolean); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].graymask:= avalue; + end; +end; + +function timagelist.getcolormask: boolean; +begin + result:= fbitmaps[0].colormask; +end; + +procedure timagelist.setcolormask(const avalue: boolean); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].colormask:= avalue; + end; +end; +{ +procedure timagelist.setmonochrome(const Value: boolean); +begin + if fbitmap.monochrome <> value then begin + fbitmap.monochrome:= value; + change; + end; +end; +} +procedure timagelist.paint(const acanvas: tcanvas; const index: integer; + const dest: rectty; const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; + aversion: int32 = -1); +begin + if (index >= 0) and (index < count) then begin + updateversionindex(aversion); + fbitmaps[aversion].paint(acanvas,dest,makerect(indextoorg(index),fsize), + alignment,acolor, + acolorbackground,aopacity); + end; +end; + +procedure timagelist.paint(const acanvas: tcanvas; const index: integer; + const dest: rectty; source: rectty; + const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; + aversion: int32 = -1); + +begin + if (index >= 0) and (index < count) then begin + updateversionindex(aversion); + addpoint1(source.pos,indextoorg(index)); + fbitmaps[aversion].paint(acanvas,dest,source,alignment,acolor,acolorbackground, + aopacity); + end; +end; + +procedure timagelist.paintlookup(const acanvas: tcanvas; const index: integer; + const dest: pointty; const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); +begin + paint(acanvas,lookup(index),dest,acolor,acolorbackground,aopacity,aversion); +end; + +procedure timagelist.paintlookup(const acanvas: tcanvas; const index: integer; + const dest: rectty; const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); +begin + paint(acanvas,lookup(index),dest,alignment,acolor,acolorbackground,aopacity, + aversion); +end; + +procedure timagelist.paintlookup(const acanvas: tcanvas; const index: integer; + const dest: rectty; source: rectty; + const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); +begin + paint(acanvas,lookup(index),dest,alignment,acolor,acolorbackground,aopacity, + aversion); +end; + +procedure timagelist.clipcornermask(const canvas: tcanvas; + const arect: rectty; const ahiddenedges: edgesty); +var + rect2,rect3: rectty; + po1,ps,pe: pint16; + i1: int32; +begin + if hascornermask then begin + rect2.cy:= 1; + rect3:= arect; + if ahiddenedges * [edg_top,edg_left] = [] then begin + po1:= pointer(cornermask_topleft); + pe:= po1 + length(msestring(pointer(po1))); + rect2.pos:= rect3.pos; + ps:= po1; + while ps < pe do begin + rect2.cx:= ps^; + canvas.subcliprect(rect2); + inc(rect2.y); + inc(ps); + end; + end; + if ahiddenedges * [edg_left,edg_bottom] = [] then begin + po1:= pointer(cornermask_bottomleft); + pe:= po1 + length(msestring(pointer(po1))); + rect2.x:= rect3.x; + rect2.y:= rect3.y + rect3.cy - 1; + ps:= po1; + while ps < pe do begin + rect2.cx:= ps^; + canvas.subcliprect(rect2); + dec(rect2.y); + inc(ps); + end; + end; + if ahiddenedges * [edg_bottom,edg_right] = [] then begin + po1:= pointer(cornermask_bottomright); + pe:= po1 + length(msestring(pointer(po1))); + rect2.y:= rect3.y + rect3.cy - 1; + ps:= po1; + i1:= arect.x + arect.cx; + while ps < pe do begin + rect2.cx:= ps^; + rect2.x:= i1 - ps^; + canvas.subcliprect(rect2); + dec(rect2.y); + inc(ps); + end; + end; + if ahiddenedges * [edg_right,edg_top] = [] then begin + po1:= pointer(cornermask_topright); + pe:= po1 + length(msestring(pointer(po1))); + rect2.y:= rect3.y; + ps:= po1; + i1:= rect3.x + rect3.cx; + while ps < pe do begin + rect2.cx:= ps^; + rect2.x:= i1 - ps^; + canvas.subcliprect(rect2); + inc(rect2.y); + inc(ps); + end; + end; + end; +end; + +procedure timagelist.paint(const acanvas: tcanvas; const index: integer; + const dest: pointty; const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; + aversion: int32 = -1); +begin + paint(acanvas,index,makerect(dest,size),[],acolor,acolorbackground, + aopacity,aversion); +end; + +function timagelist.gettransparentcolor: colorty; +begin + result:= fbitmaps[0].ftransparentcolor; +end; + +procedure timagelist.settransparentcolor(avalue: colorty); +var + i1: int32; +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].transparentcolor:= avalue; + end; +end; + +procedure timagelist.setimage(index: integer; image: tmaskedbitmap; + const source: rectty; aalignment: alignmentsty = []; + aversion: int32 = -1); +var + rect1,rect2,destrect: rectty; + bo1: boolean; + ima1: tmaskedbitmap; + bmp1: tmaskedbitmap; +begin + if (al_thumbnail in aalignment) and + ((source.cx > fsize.cx) or (source.cy > fsize.cy)) then begin + include(aalignment,al_fit); + exclude(aalignment,al_thumbnail); + end; + rect2.pos:= indextoorg(index); + rect2.size:= fsize; + updateversionindex(aversion); + bmp1:= fbitmaps[aversion]; + if image = nil then begin + bmp1.canvas.fillrect(rect2, + bmp1.colorbackground); + if masked then begin + if bmp1.mask.kind = bmk_mono then begin + bmp1.mask.canvas.fillrect(rect2,cl_0); + end + else begin + bmp1.mask.canvas.fillrect( + rect2,bmp1.fmaskcolorbackground); + end; + end; + end + else begin + rect1:= source; + ima1:= image; + destrect:= calcrectalignment(rect2,source,aalignment); + with rect1 do begin + bo1:= (al_fit in aalignment) or + (x < 0) or (y < 0) or (x + cx > ima1.fsize.cx) or + (y + cy > ima1.fsize.cy) or + not(al_stretchx in aalignment) and (cx < fsize.cx) or + not(al_stretchy in aalignment) and (cy < fsize.cy); + if not (al_fit in aalignment) then begin + if not (al_stretchx in aalignment) and (cx > fsize.cx) then begin + cx:= fsize.cx; + end; + if not (al_stretchy in aalignment) and (cy > fsize.cy) then begin + cy:= fsize.cy; + end; + end; + end; + if masked then begin + bmp1.copyarea(ima1,rect1,rect2,aalignment,rop_copy,false); + if ima1.masked then begin + if bo1 then begin + if bmp1.mask.kind = bmk_mono then begin + bmp1.mask.canvas.fillrect(rect2,cl_0); + end + else begin + bmp1.mask.canvas.fillrect(rect2, + bmp1.fmaskcolorbackground); + end; + end; + bmp1.mask.copyarea( + ima1.mask,rect1,rect2,aalignment,rop_copy,false, + bmp1.fmaskcolorforeground, + bmp1.fmaskcolorbackground); + end + else begin + if bo1 then begin + if bmp1.mask.kind = bmk_mono then begin + bmp1.mask.canvas.fillrect(rect2,cl_0); + end + else begin + bmp1.mask.canvas.fillrect(rect2, + bmp1.fmaskcolorbackground); + end; + end; + if bmp1.mask.kind = bmk_mono then begin + bmp1.mask.canvas.fillrect(destrect,cl_1); + end + else begin + bmp1.mask.canvas.fillrect( + destrect,bmp1.fmaskcolorforeground); + end; + end; + end + else begin + if bo1 then begin + if kind = bmk_mono then begin + bmp1.canvas.fillrect(rect2,cl_0); + end + else begin + bmp1.canvas.fillrect(rect2,bmp1.fcolorbackground); + end; + end; + bmp1.copyarea(ima1,rect1,rect2,aalignment,rop_copy,false); + end; + end; + change; +end; + +procedure timagelist.getimage(const index: integer; const dest: tmaskedbitmap; + aversion: int32 = -1); +var + rect1: rectty; + bmp1: tmaskedbitmap; +begin + dest.clear; + if (index >= 0) or (index < fcount) then begin + updateversionindex(aversion); + bmp1:= fbitmaps[aversion]; + dest.beginupdate(); + dest.kind:= bmp1.kind; + dest.masked:= bmp1.masked; + if dest.masked then begin + dest.mask.kind:= bmp1.mask.kind; + end; + dest.transparentcolor:= bmp1.transparentcolor; + dest.colorforeground:= bmp1.colorforeground; + dest.colorbackground:= bmp1.colorbackground; + rect1.pos:= indextoorg(index); + rect1.size:= size; + dest.size:= size; + dest.copyarea(bmp1,rect1,nullpoint,rop_copy,false); + if dest.masked then begin + dest.mask.copyarea(bmp1.fmask,rect1,nullpoint,rop_copy,false); + end; + dest.endupdate(); + end; +end; + +procedure timagelist.setimage(index: integer; image: tmaskedbitmap; + const aalignment: alignmentsty = []; + aversion: int32 = -1); +begin + if image = nil then begin + setimage(index,nil,makerect(nullpoint,fsize),[],aversion); + end + else begin + setimage(index,image,makerect(nullpoint,image.fsize),aalignment,aversion); + end; +end; + +procedure timagelist.copyimages(const image: tmaskedbitmap; + const destindex: integer; + const aversion: int32); +var + rect1: rectty; + int1,int2: integer; +begin + with image.fsize do begin + if fsize.cx > cx then begin + int2:= -(fsize.cx - cx) div 2; + end + else begin + int2:= 0; + end; + if fsize.cy > cy then begin + rect1.y:= -(fsize.cy - cy) div 2; + end + else begin + rect1.y:= 0; + end; + rect1.cx:= cx - int2; + rect1.cy:= cy - rect1.y; + end; + int1:= destindex; + while rect1.y < image.fsize.cy do begin + rect1.x:= int2; + while rect1.x < image.fsize.cx do begin + if int1 >= fcount then begin + exit; + end; + setimage(int1,image,rect1,[],aversion); + inc(int1); + inc(rect1.x,fsize.cx); + end; + inc(rect1.y,fsize.cy); + end; +end; + +procedure timagelist.setcount(const Value: integer); + +var + int1,int2: integer; + buffer: tmaskedbitmap; + bo1: boolean; + i1: int32; + +begin + if fcount <> value then begin + fcount := Value; + if value = 0 then begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].clear; + end; + frowcount:= 0; + fcolcount:= 0; + end + else begin + int1:= bits[highestbit(fcount) div 2 + 1]; + repeat + int2:= int1; + int1:= (int1 * 7) shr 3; //7/8 -> 0.875*0.875 -> 0.765 + if int1 = int2 then begin + dec(int1); + end; + until int1 * int1 < fcount; + bo1:= (frowcount <> int2) or (fcolcount <> int2); + frowcount:= int2; //square + fcolcount:= int2; + if bo1 then begin + for i1:= 0 to fversionhigh do begin + buffer:= tmaskedbitmap.create(kind); + buffer.assign1(fbitmaps[i1],false); + fbitmaps[i1].size:= makesize(int2*fsize.cx,int2*fsize.cy); + if not buffer.isempty then begin + copyimages(buffer,0,i1); + end; + buffer.Free; + end; + end; + end; + change; + end; +end; + +function timagelist.addimage(const image: tmaskedbitmap; + const aalignment: alignmentsty = []{; + const aversion: int32 = 0}): integer; +var + newcolcount,newrowcount,newcount: integer; + bmp1: tmaskedbitmap; + i1: int32; +begin +// checkversionindex(aversion); + result:= -1; + if image = nil then begin + result:= fcount; + count:= fcount+1; + for i1:= 0 to fversionhigh do begin + setimage(result,nil,[],i1); + end; + end + else begin + if not image.isempty then begin + result:= fcount; + beginupdate; + bmp1:= nil; + try + if (fsize.cx = 0) or (fsize.cy = 0) then begin + if image = nil then begin + exit; + end; + fsize:= image.fsize; + end; + if aalignment <> [] then begin + bmp1:= tmaskedbitmap.create(image.kind); + bmp1.size:= fsize; + image.stretch(bmp1,aalignment); + end + else begin + bmp1:= image; + end; + newcolcount:= (bmp1.size.cx + fsize.cx-1) div fsize.cx; + newrowcount:= (bmp1.size.cy + fsize.cy-1) div fsize.cy; + newcount:= newcolcount * newrowcount; + count:= fcount + newcount; + for i1:= 0 to fversionhigh do begin + copyimages(bmp1,result,i1); + end; + finally + if bmp1 <> image then begin + bmp1.free; + end; + endupdate; + end; + end; + end; +end; + +procedure timagelist.deleteimage(const index: integer); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + moveimage(index,count-1,i1); + end; + count:= fcount - 1; +end; + +procedure timagelist.moveimage(const fromindex: integer; const toindex: integer; + aversion: int32 = -1); +var + bmp1,bmp2: tmaskedbitmap; + int1: integer; +// i1,i2: int32; +begin + if fromindex <> toindex then begin + updateversionindex(aversion); + beginupdate; + try + bmp1:= tmaskedbitmap.create(kind); + bmp1.maskkind:= fbitmaps[0].maskkind; + bmp1.masked:= masked; + bmp2:= tmaskedbitmap.create(kind); + bmp2.maskkind:= fbitmaps[0].maskkind; + bmp2.masked:= masked; +// i2:= fversioncurrent; + try +// for i1:= 0 to fversionhigh do begin +// fversioncurrent:= i1; + getimage(fromindex,bmp1,aversion); + if fromindex < toindex then begin + for int1:= fromindex + 1 to toindex do begin + getimage(int1,bmp2,aversion); + setimage(int1-1,bmp2,[],aversion); + end; + end + else begin + for int1:= fromindex-1 downto toindex do begin + getimage(int1,bmp2,aversion); + setimage(int1+1,bmp2,[],aversion); + end; + end; + setimage(toindex,bmp1,[],aversion); +// end; + finally +// fversioncurrent:= i2; + bmp1.free; + bmp2.Free; + end; + finally + endupdate; + end; + end; +end; + +procedure timagelist.setheight(const Value: integer); +begin + setsize(makesize(fsize.cx,Value)); +end; + +procedure timagelist.setwidth(const Value: integer); +begin + setsize(makesize(value,fsize.cy)); +end; +{ +procedure timagelist.setbitmap(const Value: tmaskedbitmap); +begin + addimage(fbitmap); //??? +end; +} +procedure timagelist.beginupdate; +begin + inc(fupdating); +end; + +procedure timagelist.endupdate; +begin + dec(fupdating); + change; +end; + +procedure timagelist.change; +begin + if (fupdating = 0) then begin + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + end; +end; + +procedure timagelist.readmasked(reader: treader); +begin + masked:= reader.readboolean; +end; + +procedure timagelist.readcolormask(reader: treader); +begin + colormask:= reader.readboolean; +end; + +procedure timagelist.readmonochrome(reader: treader); +begin + if reader.readboolean then begin + kind:= bmk_mono; + end; +end; + +procedure timagelist.readcornermask(reader: treader); +begin + fcornermask_topleft:= reader.readunicodestring; + fcornermask_bottomleft:= fcornermask_topleft; + fcornermask_bottomright:= fcornermask_topleft; + fcornermask_topright:= fcornermask_topleft; + cornermaskchanged(); +end; + +procedure timagelist.writeimage(stream: tstream); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].writeimage(stream); + end; +end; + +procedure timagelist.readimage(stream: tstream); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].readimage(stream); + end; +end; + +procedure timagelist.defineproperties(filer: tfiler); + + function checkimage(): boolean; + var + i1: int32; + begin + with timagelist(filer.ancestor) do begin + result:= (self.count <> count) or (self.fversionhigh <> fversionhigh) or + (self.fsize.cx <> fsize.cx) or (self.fsize.cy <> fsize.cy) or + (self.fbitmaps[0].options <> fbitmaps[0].options); + if not result then begin + for i1:= 0 to fversionhigh do begin + if self.fbitmaps[i1].writedata(fbitmaps[i1]) then begin + result:= true; + break; + end; + end; + end; + end; + end; //checkimage + +var + ancestorbefore: tpersistent; +begin + inherited; + filer.defineproperty('monochrome',@readmonochrome,nil,false); + filer.defineproperty('masked',@readmasked,nil,false); + filer.defineproperty('colormask',@readcolormask,nil,false); + filer.defineproperty('cornermask',@readcornermask,nil,false); + if fversionhigh = 0 then begin + ancestorbefore:= filer.ancestor; + if (ancestorbefore <> nil) then begin + filer.ancestor:= timagelist(ancestorbefore).fbitmaps[0]; + end; + fbitmaps[0].defineproperties(filer); //imagedata + filer.ancestor:= ancestorbefore; + end + else begin + filer.definebinaryproperty('image',@readimage,@writeimage, + (filer.ancestor = nil) or checkimage()); + end; +end; + +function timagelist.lookup(const aindex: int32): int32; +begin + result:= aindex; + if findexlookup <> '' then begin + result:= -1; + if (aindex >= 0) and (aindex < length(findexlookup)) then begin + result:= pint16(findexlookup)[aindex]; + end; + end; +end; + +procedure timagelist.assign(sender: tpersistent); +var + i1: int32; +begin + if sender is timagelist then begin + count:= 0; + with timagelist(sender) do begin + self.versioncount:= versioncount; + self.fsize:= fsize; + self.fcolcount:= fcolcount; + self.frowcount:= frowcount; + self.fcount:= fcount; + for i1:= 0 to fversionhigh do begin + self.fbitmaps[i1].assign(fbitmaps[i1]); + end; + end; + change; + end + else begin + inherited; + end; +end; + +function timagelist.getkind: bitmapkindty; +begin + result:= fbitmaps[0].kind; +end; + +procedure timagelist.setkind(const avalue: bitmapkindty); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].kind:= avalue; + end; +end; + +function timagelist.getmaskkind: bitmapkindty; +begin + result:= fbitmaps[0].maskkind; +end; + +procedure timagelist.setmaskkind(const avalue: bitmapkindty); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].maskkind:= avalue; + end; +end; + +function timagelist.getoptions: bitmapoptionsty; +begin + result:= fbitmaps[0].options; +end; + +procedure timagelist.setoptions(const avalue: bitmapoptionsty); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].options:= avalue; + end; +end; + +procedure timagelist.setindexlookup(const avalue: msestring); +begin + findexlookup:= avalue; + change; +end; + +procedure timagelist.setcornermask_topleft(const avalue: msestring); +begin + fcornermask_topleft:= avalue; + cornermaskchanged(); +end; + +procedure timagelist.setcornermask_bottomleft(const avalue: msestring); +begin + fcornermask_bottomleft:= avalue; + cornermaskchanged(); +end; + +procedure timagelist.setcornermask_bottomright(const avalue: msestring); +begin + fcornermask_bottomright:= avalue; + cornermaskchanged(); +end; + +procedure timagelist.setcornermask_topright(const avalue: msestring); +begin + fcornermask_topright:= avalue; + cornermaskchanged(); +end; + +procedure timagelist.cornermaskchanged(); + + procedure check(const avalue: msestring; var maxwidth: int32); + var + po1,pe: pint16; + begin + maxwidth:= 0; + if avalue <> '' then begin + fhascornermask:= true; + po1:= pointer(avalue); + pe:= po1 + length(avalue); + while po1 < pe do begin + if po1^ > maxwidth then begin + maxwidth := po1^; + end; + inc(po1); + end; + end; + end; //check + +begin + if not (csloading in componentstate) then begin + fhascornermask:= false; + check(fcornermask_topleft,fcornermaskmaxtopleft); + check(fcornermask_bottomleft,fcornermaskmaxbottomleft); + check(fcornermask_bottomright,fcornermaskmaxbottomright); + check(fcornermask_topright,fcornermaskmaxtopright); + change; + end + else begin + fneedscornermaskcheck:= true; + end; +end; + +procedure timagelist.loaded(); +begin + inherited; + if fneedscornermaskcheck then begin + cornermaskchanged(); + fneedscornermaskcheck:= false; + end; +end; + +{ tcenteredbitmap } + +constructor tcenteredbitmap.create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); +begin + inherited; + alignment:= [al_xcentered,al_ycentered]; +end; + +{ tbitmapcanvas } +{ +constructor tbitmapcanvas.create(const user: tbitmap); +begin + inherited create(user,icanvas(user)); +end; + +function tbitmapcanvas.getimage(const bgr: boolean): imagety; +begin + with tbitmap(fuser) do begin + checkimage(bgr); + result:= fimage; + end; +end; +} +{ townedbitmap } + +constructor townedbitmap.create(const aowner: tbitmap; + const akind: bitmapkindty; const agdifuncs: pgdifunctionaty = nil); +begin + fowner:= aowner; + inherited create(akind,agdifuncs); +end; + +procedure townedbitmap.dochange; +begin + inherited; + fowner.change(); +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msedrawtext.pas b/mseide-msegui/lib/common/graphics/msedrawtext.pas new file mode 100644 index 0000000..7d20786 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msedrawtext.pas @@ -0,0 +1,1859 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedrawtext; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +//todo: optimize speed + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msegraphics,mserichstring, + msegraphutils, + msearrayprops,mseclasses,msestrings,msetypes,mseguiglob; + +const + defaulttabwidth = 20; //mm + textellipse = msestring('...'); + +type + textflagty = (tf_left,tf_xcentered,tf_right,tf_xjustify, + tf_top,tf_ycentered,tf_bottom, + //order fix, used in msepostscriptprinter + //tf_left and tf_right can be combined with tf_xcentered, + //tf_top and tf_bottom can be combined with tf_ycentered + //for limitting centering to avalable space + + tf_rotate90,tf_rotate180, +// tf_forcealignment, //do not use default alignment for buttons + tf_clipi,tf_clipo, + tf_grayed,tf_wordbreak,tf_softhyphen, + tf_noselect,tf_underlineselect, + tf_ellipseleft,{tf_ellipsemid,}tf_ellipseright, + tf_tabtospace,tf_showtabs,tf_glueimage, //used in button captions + tf_force); + textflagsty = set of textflagty; +const + ellipsemask: textflagsty = [tf_ellipseleft,{tf_ellipsemid,}tf_ellipseright]; + textalignments = [tf_left,tf_xcentered,tf_right,tf_xjustify, + tf_top,tf_ycentered,tf_bottom]; + +type + + tabulatorkindty = (tak_left,tak_right,tak_centered,tak_decimal); + tabulatorty = record + index: integer; + tabkind: tabulatorkindty; + linepos: integer; + textpos: integer; + width: integer; + cellwidth: integer; + end; + tabulatorarty = array of tabulatorty; + tabulatorstatety = (tas_editactive); + tabulatorstatesty = set of tabulatorstatety; + + ttabulatoritem = class(townedpersistent) + private + fkind: tabulatorkindty; + fpos: real; + procedure setkind(const avalue: tabulatorkindty); + procedure setdistleft(const avalue: real); + procedure setdistright(const avalue: real); + protected + fstate: tabulatorstatesty; + fdistleft: real; + fdistright: real; + function getenabled(): boolean virtual; + procedure setpos(const avalue: real); virtual; + property distleft: real read fdistleft write setdistleft; //mm + property distright: real read fdistright write setdistright; //mm + public + published + property kind: tabulatorkindty read fkind write setkind default tak_left; + property pos: real read fpos write setpos; //mm + end; + tabulatoritemclassty = class of ttabulatoritem; + + tcustomtabulators = class(townedpersistentarrayprop) + private + fppmm: real; + fuptodate: boolean; + fdefaultdist: real; + procedure setppmm(const avalue: real); + function gettabs: tabulatorarty; + function getitems(const index: integer): ttabulatoritem; + procedure setitems(const index: integer; const avalue: ttabulatoritem); + procedure setdefaultdist(const avalue: real); + function getpos(const index: integer): integer; + function getlinepos(const index: integer): integer; + procedure setlinepos(const index: integer; const avalue: integer); + protected + ftabs: tabulatorarty; + procedure checkuptodate; + procedure dochange(const index: integer); override; + procedure changed(const sender: ttabulatoritem); + class function getitemclass: tabulatoritemclassty; virtual; + public + constructor create; reintroduce; + class function getitemclasstype: persistentclassty; override; + procedure assign(source: tpersistent); override; + procedure add(const apos: real; const akind: tabulatorkindty); + procedure setdefaulttabs(const awidth: real = 20; const acount: integer = 20; + const akind: tabulatorkindty = tak_left); + property tabs: tabulatorarty read gettabs; + property ppmm: real read fppmm write setppmm; + //pixel per millimeter + property defaultdist: real read fdefaultdist write setdefaultdist; //0 -> none + property items[const index: integer]: ttabulatoritem read getitems + write setitems; default; + property pos[const index: integer]: integer read getpos; + property linepos[const index: integer]: integer read getlinepos write setlinepos; + end; + + ttabulators = class(tcustomtabulators) + published + property ppmm; + property defaultdist; + end; + + drawtextinfoty = record + text: richstringty; + dest,clip: rectty; + flags: textflagsty; + font: tfont; + tabulators: tcustomtabulators; + res: rectty; + end; + + tabinfoty = record + index: integer; + kind: tabulatorkindty; + linepos: integer; + end; + tabinfoarty = array of tabinfoty; + + textlineinfoty = record + liindex,licount: integer; + liy: integer; + listartx: integer; + liwidth: integer; + tabchars: tabinfoarty; + justifychars: tabinfoarty; + linebreak: boolean; //true if newline sequence detected + end; + textlineinfoarty = array of textlineinfoty; + + layoutinfoty = record + charwidths: integerarty; + lineinfos: textlineinfoarty; + ascent,descent,lineheight, + underline,strikeout: integer; + starty: integer; + height: integer; + xyswapped: boolean; + reversed: boolean; + end; + +function checktextflags(old,new: textflagsty): textflagsty; + +procedure drawtext(const canvas: tcanvas; var info: drawtextinfoty); overload; +procedure drawtext(const canvas: tcanvas; const text: richstringty; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); overload; +procedure drawtext(const canvas: tcanvas; const text: richstringty; + const dest,clip: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); overload; +procedure drawtext(const canvas: tcanvas; const text: msestring; + const dest,clip: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); overload; +procedure drawtext(const canvas: tcanvas; const text: msestring; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); overload; +procedure layouttext(const canvas: tcanvas; var info: drawtextinfoty; + out layoutinfo: layoutinfoty); overload; +function breaklines(const canvas: tcanvas; + var info: drawtextinfoty): richstringarty; overload; +function breaklines(const canvas: tcanvas; const text: richstringty; + const width: integer; font: tfont = nil): richstringarty; overload; +function breaklines(const canvas: tcanvas; const text: msestring; + const width: integer; font: tfont = nil): msestringarty; overload; + +procedure textrect(const canvas: tcanvas; var info: drawtextinfoty); overload; + //result in info.res +function textrect(const canvas: tcanvas; const text: richstringty; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil): rectty; overload; +function textrect(const canvas: tcanvas; const text: richstringty; + flags: textflagsty = []; font: tfont = nil; + tabulators: tcustomtabulators = nil): rectty; overload; +function textrect(const canvas: tcanvas; const text: msestring; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil): rectty; overload; +function textrect(const canvas: tcanvas; const text: msestring; + flags: textflagsty = []; font: tfont = nil; + tabulators: tcustomtabulators = nil): rectty; overload; +function textclipped(const canvas: tcanvas; var info: drawtextinfoty): boolean; + +function postotextindex(const canvas: tcanvas; var info: drawtextinfoty; + const pos: pointty; out aindex: integer): boolean; + //false if out of text +function textindextopos(const canvas: tcanvas; var info: drawtextinfoty; + aindex: integer): pointty; + +implementation +uses + mseguiintf,msebits,msearrayutils,{$ifdef FPC}math{$else}Math{$endif},msereal, + sysutils,msefont,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcanvas1 = class(tcanvas); + +function checktextflags(old,new: textflagsty): textflagsty; +const +// xmask: textflagsty = [tf_xcentered,tf_right]; + xmask: textflagsty = [tf_left,tf_right]; +// ymask: textflagsty = [tf_ycentered,tf_bottom]; + ymask: textflagsty = [tf_top,tf_bottom]; +begin + result:= new; + result:= textflagsty(setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(result), + {$ifdef FPC}longword{$else}longword{$endif}(old), + {$ifdef FPC}longword{$else}longword{$endif}(ymask))); + result:= textflagsty(setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(result), + {$ifdef FPC}longword{$else}longword{$endif}(old), + {$ifdef FPC}longword{$else}longword{$endif}(xmask))); + result:= textflagsty(setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(result), + {$ifdef FPC}longword{$else}longword{$endif}(old), + {$ifdef FPC}longword{$else}longword{$endif}(ellipsemask))); +// if tf_default in result then begin +// result:= [tf_default]; +// end; +end; + +procedure additem(var dest: tabinfoarty; const value: integer); +begin + setlength(dest,high(dest)+2); + with dest[high(dest)] do begin + index:= value; + kind:= tabulatorkindty(-1); //invalid + end; +end; + +procedure addtabchar(var dest: tabinfoarty; const aindex: integer; + const akind: tabulatorkindty; const alinepos: integer); + procedure setdata(const ind: integer); + begin + with dest[ind] do begin + index:= aindex; + kind:= akind; + linepos:= alinepos; + end; + end; + +var + int1: integer; +begin + for int1:= 0 to high(dest) do begin + if dest[int1].index = aindex then begin + exit; + end; + if dest[int1].index > aindex then begin + setlength(dest,high(dest) + 2); + move(dest[aindex],dest[aindex+1],(high(dest)-aindex) * sizeof(dest[0])); + setdata(int1); + exit; + end; + end; + setlength(dest,high(dest) + 2); + setdata(high(dest)); +end; + +function comparetabinfo(const l,r): integer; +begin + result:= tabinfoty(l).index-tabinfoty(r).index; +end; + +function mergearray(const a,b: tabinfoarty): tabinfoarty; + //result is sorted without duplicates +var + int1,int2: integer; + ar1: integerarty; +begin + setlength(result,length(a)+length(b)); + if result <> nil then begin + move(a[0],result[0],length(a)*sizeof(result[0])); + move(b[0],result[length(a)],length(b)*sizeof(result[0])); + mergesortarray(result,sizeof(result[0]),length(result), + @comparetabinfo,ar1,true); + int2:= 0; + for int1:= 1 to high(result) do begin + if result[int2].index <> result[int1].index then begin + inc(int2); + result[int2]:= result[int1]; + end; + end; + setlength(result,int2+1); + end; +end; + +procedure layouttext(const canvas: tcanvas; var info: drawtextinfoty; + out layoutinfo: layoutinfoty); +var + drawinfo: drawinfoty; + awidth: integer; + resultpo1: pinteger; + text1: pmsechar; + highresfo: boolean; + + procedure getcharwidths(acount: integer); + var + fontmetrics1: fontmetricsty; + int1: integer; + begin + if acount <= 0 then begin + exit; + end; + if fs_blank in canvas.font.style then begin + for int1:= 0 to acount-1 do begin + {$ifdef FPC} + resultpo1[int1]:= 0; + {$else} + pinteger(pchar(pointer(resultpo1))+int1*sizeof(integer))^:= 0; + {$endif} + end; + end + else begin + with drawinfo.getchar16widths do begin + fontdata:= getfontdata(canvas.font.handle); + resultpo:= resultpo1; + text:= text1; + count:= acount; + if highresfo then begin + checkhighresfont(fontdata,tcanvas1(canvas).fdrawinfo); + end; + getchar16widths(drawinfo); + end; + if tf_tabtospace in info.flags then begin + with drawinfo.getfontmetrics do begin + fontdata:= drawinfo.getchar16widths.fontdata; + char:= ord(' '); + resultpo:= @fontmetrics1; + getfontmetrics({datapo,}drawinfo); + end; + for int1:= 0 to acount-1 do begin + if (text1+int1)^ = c_tab then begin + pintegeraty(resultpo1)^[int1]:= fontmetrics1.width; + end; + end; + end; + end; + inc(text1,acount); + inc(resultpo1,acount); + end; + + function checklinebreak(var aindex: integer): boolean; + var + ch1: msechar; + begin + ch1:= info.text.text[aindex]; + result:= (ch1 = c_return) or (ch1 = c_linefeed); + if result then begin + with layoutinfo do begin + with lineinfos[high(lineinfos)] do begin + licount:= aindex - liindex; + liwidth:= awidth; + linebreak:= true; + end; + inc(aindex); + if (ch1 = c_return) and (aindex <= length(info.text.text)) and + (info.text.text[aindex] = c_linefeed) then begin + inc(aindex); + end; + setlength(lineinfos,high(lineinfos) + 2); + with lineinfos[high(lineinfos)] do begin + liindex:= aindex; + end; + end; + end; + end; +//{$define mswindows} + function tabitemwidth(const charindex: integer; + const stopchar: msechar): integer; + var + po1: pinteger; + po2: pmsechar; + begin + result:= 0; + po1:= @{pointer}(layoutinfo.charwidths[charindex]); + po2:= @info.text.text[charindex+1]; + while true do begin + case po2^ of + ' ',c_tab,c_return,c_linefeed,#0: begin + break; + end; + else begin + if po2^ = stopchar then begin + break; + end; + result:= result + po1^; + inc(po1); + inc(po2); + end; + end; + end; + end; +var + int1,int2,int3,int4: integer; + textlen: integer; + style1: fontstylesty; + nexttab: integer; + rea1,rea2: real; + tabs: tabulatorarty; + po1: pmsecharaty; + bo1: boolean; + wch1: widechar; + + procedure checksofthyphen(const alineinfo: integer); + begin + if tf_softhyphen in info.flags then begin + with layoutinfo do begin + if (int2 > 0) and (info.text.text[int2] = c_softhyphen) then begin + charwidths[int2-1]:= 0; + additem(lineinfos[alineinfo].tabchars,int2); + end; + end; + end; + end; + +var + y1,orig1,int5: integer; + fontmetrics1: fontmetricsty; + hasitaliccomp: boolean; +{$ifdef mswindows} + italicsafetymargin: int32; +{$endif} + +begin + tabs:= nil; //compiler warning + if info.font <> nil then begin + canvas.font:= info.font; + end; + try + gdi_lock; + with info,tcanvas1(canvas),layoutinfo do begin + if tf_rotate90 in flags then begin + swapxy1(dest); + end; + checkgcstate([cs_gc]); + highresfo:= df_highresfont in fdrawinfo.gc.drawingflags; + canvas.initdrawinfo(drawinfo); + ascent:= font.ascent; + descent:= font.descent; + lineheight:= font.lineheight; + textlen:= length(text.text); + setlength(charwidths,textlen); + text1:= pointer(info.text.text); + resultpo1:= pointer(charwidths); + if text.format = nil then begin + getcharwidths(textlen); + end + else begin + int2:= 0; + style1:= font.style; + for int1:= 0 to high(text.format) do begin + with text.format[int1] do begin + if newinfos * fontlayoutflags <> [] then begin + if index > textlen then begin + getcharwidths(textlen-int2); + end + else begin + getcharwidths(index-int2); + end; + int2:= index; + font.style:= style.fontstyle; + end; + end; + end; + if int2 < length(text.text) then begin + getcharwidths(length(text.text)-int2); + end; + font.style:= style1; + end; + setlength(lineinfos,1); + lineinfos[0].liindex:= 1; + int1:= 1; + awidth:= 0; //textwidth + if tf_wordbreak in flags then begin + int2:= 0; + while int1 <= textlen do begin + int2:= 0; //index of last whitespace + int3:= 0; //textwidth of last whitespace + awidth:= 0; //textwidth + while int1 <= textlen do begin + wch1:= text.text[int1]; + if (wch1 = ' ') or + ((wch1 = '-') and (int1 > 1) and (text.text[int1-1] <> ' ') or + (wch1 = c_softhyphen)) and + (awidth + charwidths[int1-1] <= info.dest.cx) then begin + checksofthyphen(high(lineinfos)); + int2:= int1; + int3:= awidth; + end + else begin + if checklinebreak(int1) then begin + checksofthyphen(high(lineinfos)-1); + break; + end; + end; + if (wch1 <> c_softhyphen) or not (tf_softhyphen in flags) then begin + inc(awidth,charwidths[int1-1]); + end; + if (awidth > info.dest.cx) and (awidth > charwidths[int1-1]) then begin + //min one char on line + with lineinfos[high(lineinfos)] do begin + if (int2 > 0) then begin //use last whitespace for break + if text.text[int2] <> ' ' then begin + inc(int3,charwidths[int2-1]); //'-' + licount:= int2 - liindex + 1; + end + else begin + licount:= int2 - liindex; + end; + liwidth:= int3; + int1:= int2 + 1; + end + else begin + licount:= int1 - liindex; //no whitespace to break + liwidth:= awidth - charwidths[int1-1]; + end; + end; + setlength(lineinfos,high(lineinfos) + 2); + with lineinfos[high(lineinfos)] do begin + liindex:= int1; + end; + break; + end; + inc(int1); + end; + checksofthyphen(high(lineinfos)); + end; + with lineinfos[high(lineinfos)] do begin + if textlen > 0 then begin + licount:= textlen - liindex + 1; + end; + liwidth:= awidth; + end; + end + else begin //no linebreak + if (info.tabulators = nil) or + (info.tabulators.count = 0) and (info.tabulators.defaultdist = 0) or + (tf_tabtospace in flags) then begin + while int1 <= textlen do begin + if (tf_softhyphen in info.flags) and (info.text.text[int1] = c_softhyphen) then begin + charwidths[int1-1]:= 0; + additem(lineinfos[high(lineinfos)].tabchars,int1); + end; + if not checklinebreak(int1) then begin + inc(awidth,charwidths[int1-1]); + inc(int1); + end + else begin + awidth:= 0; + end; + end; + end + else begin //with tabulators + tabs:= info.tabulators.tabs; + rea1:= info.tabulators.defaultdist * info.tabulators.ppmm; + nexttab:= -1; + while int1 <= textlen do begin + if (tf_softhyphen in info.flags) and + (info.text.text[int1] = c_softhyphen) then begin + charwidths[int1-1]:= 0; + additem(lineinfos[high(lineinfos)].tabchars,int1); + end; + if not checklinebreak(int1) then begin + if info.text.text[int1] = c_tab then begin + if tabs <> nil then begin + inc(nexttab); + if nexttab < info.tabulators.count then begin + case tabs[nexttab].tabkind of + tak_right: begin + charwidths[int1-1]:= tabs[nexttab].textpos - awidth - + tabitemwidth(int1,#0); + end; + tak_centered: begin + charwidths[int1-1]:= tabs[nexttab].textpos - awidth - + tabitemwidth(int1,#0) div 2; + end; + tak_decimal: begin + charwidths[int1-1]:= tabs[nexttab].textpos - awidth - + tabitemwidth(int1, + defaultformatsettingsmse.decimalseparator); + end; + else begin //tak_left + charwidths[int1-1]:= tabs[nexttab].textpos - awidth; + end; + end; + with tabs[nexttab] do begin + addtabchar(lineinfos[high(lineinfos)].tabchars,int1,tabkind,linepos); + end; + end + else begin + if rea1 > 0 then begin + int5:= round(ceil(awidth / rea1)*rea1); + charwidths[int1-1]:= int5 - awidth; + addtabchar(lineinfos[high(lineinfos)].tabchars,int1,tak_left,int5); + end; + end; + end + else begin + if rea1 > 0 then begin + int5:= round(floor((awidth+rea1+0.1)/rea1)*rea1); + charwidths[int1-1]:= int5 - awidth; + addtabchar(lineinfos[high(lineinfos)].tabchars,int1,tak_left,int5); + end; + end; + end; + inc(awidth,charwidths[int1-1]); + inc(int1); + end + else begin + awidth:= 0; + nexttab:= -1; + end; + end; + end; + with lineinfos[high(lineinfos)] do begin + liwidth:= awidth; + licount:= int1-liindex; + end; + end; + if high(lineinfos) >= 0 then begin + height:= lineheight*high(lineinfos)+ascent+descent; + end + else begin + height:= 0; + end; + res.y:= info.dest.y; + if tf_ycentered in flags then begin + if info.dest.cy < height then begin + if tf_bottom in flags then begin + res.y:= res.y + info.dest.cy - height; + end + else begin + if not (tf_top in flags) then begin + res.y:= res.y + (info.dest.cy - height -1) div 2; + end; + end; + end + else begin + res.y:= res.y + (info.dest.cy - height) div 2; + end; + end + else begin + if tf_bottom in flags then begin + res.y:= res.y + info.dest.cy - height; + end; + end; + y1:= res.y + ascent; //layoutinfo + starty:= y1; + res.x:= bigint; + res.cy:= height; + res.cx:= 0; + hasitaliccomp:= (text.format = nil) and font.italic; + if hasitaliccomp then begin + with drawinfo.getfontmetrics do begin + fontdata:= getfontdata(canvas.font.handle); + resultpo:= @fontmetrics1; + {$ifdef mswindows} + italicsafetymargin:= (lineheight+10) div 20; + {$endif} + end; + end; + for int3:= 0 to high(lineinfos) do begin + with layoutinfo.lineinfos[int3] do begin + liy:= y1; + y1:= y1 + lineheight; + listartx:= info.dest.x; + if hasitaliccomp and (licount > 0) then begin + with drawinfo.getfontmetrics do begin + char:= getucs4char(text.text,liindex); + msefont.getfontmetrics({datapo,}drawinfo); + listartx:= listartx - fontmetrics1.leftbearing + {$ifdef mswindows} + 1{$endif}; + liwidth:= liwidth - fontmetrics1.leftbearing; + char:= getucs4char(text.text,liindex+licount-1); + msefont.getfontmetrics({datapo,}drawinfo); + liwidth:= liwidth-fontmetrics1.rightbearing + {$ifdef mswindows}+ 1 + italicsafetymargin{$endif}; + end; + end; + if tf_xcentered in flags then begin + if info.dest.cx < liwidth then begin + if tf_right in flags then begin + listartx:= listartx + info.dest.cx - liwidth; + end + else begin + if not (tf_left in flags) then begin + listartx:= listartx + (info.dest.cx - liwidth - 1) div 2; + end; + end; + end + else begin + listartx:= listartx + (info.dest.cx - liwidth) div 2; + end; + end + else begin + if tf_right in flags then begin + listartx:= listartx + info.dest.cx - liwidth; + end; + end; + if res.x > listartx then begin + res.x:= listartx; + end; + if res.cx < liwidth then begin + res.cx:= liwidth; + end; + end; + end; + if (tf_xjustify in flags) and (dest.cx > 0) then begin + po1:= pointer(info.text.text); + bo1:= false; + int3:= high(lineinfos); + if tf_wordbreak in flags then begin + dec(int3); + end; + for int3:= 0 to int3 do begin + with lineinfos[int3] do begin + if not linebreak then begin + bo1:= true; + int4:= 0; + setlength(justifychars,licount); //max + for int1:= liindex-1 to liindex + licount - 2 do begin + if po1^[int1] = ' ' then begin + with justifychars[int4] do begin + index:= int1+1; + end; + inc(int4); + end; + end; + setlength(justifychars,int4); + if (int4 > 0) and not (cs_internaldrawtext in fstate) then begin + rea1:= (dest.cx - liwidth) / int4; + rea2:= 0; + int2:= 0; + for int1:= 0 to high(justifychars) do begin + rea2:= rea2 + rea1; + int4:= round(rea2) - int2; + inc(charwidths[justifychars[int1].index-1],int4); + inc(int2,int4); + end; + listartx:= dest.x; + if tabchars <> nil then begin + tabchars:= mergearray(tabchars,justifychars); + end + else begin + tabchars:= justifychars; + end; + justifychars:= nil; + end; + end; + end; + end; + if bo1 then begin + if res.cx <= dest.cx then begin + res.x:= dest.x; + res.cx:= dest.cx; + end; + end; + end; + underline:= descent div 2 + 1; + if underline = 0 then begin + underline:= 1; + end; + if underline >= descent then begin + underline:= descent - 1; + end; + strikeout:= - (ascent div 3); + xyswapped:= false; + reversed:= false; + if flags * [tf_rotate90,tf_rotate180] <> [] then begin + if (tf_rotate90 in flags) xor (tf_rotate180 in flags) then begin //mirror x + orig1:= dest.x + dest.x + dest.cx; + res.x:= orig1 - res.x - res.cx; + for int1:= 0 to high(lineinfos) do begin + with lineinfos[int1] do begin + listartx:= orig1-listartx; + end; + end; + for int1:= 0 to high(charwidths) do begin + charwidths[int1]:= - charwidths[int1]; + end; + end; + reversed:= (tf_rotate180 in flags); + if reversed then begin //mirror y + ascent:= -ascent; + descent:= -descent; + lineheight:= -lineheight; + underline:= -underline; + strikeout:= -strikeout; + orig1:= dest.y + dest.y + dest.cy; + res.y:= orig1 - res.y - res.cy; + starty:= orig1 - starty; + for int1:= 0 to high(lineinfos) do begin + with lineinfos[int1] do begin + liy:= orig1-liy; + end; + end; + end; + xyswapped:= tf_rotate90 in flags; + if xyswapped then begin + swapxy1(dest); + swapxy1(res); + end; + end; + end; + finally + gdi_unlock; + end; +end; + +function breaklines(const canvas: tcanvas; + var info: drawtextinfoty): richstringarty; +var + la1: layoutinfoty; + int1: integer; +begin + layouttext(canvas,info,la1); + setlength(result,length(la1.lineinfos)); + for int1:= 0 to high(result) do begin + with la1.lineinfos[int1] do begin + result[int1]:= richcopy(info.text,liindex,licount); + end; + end; +end; + +function breaklines(const canvas: tcanvas; const text: richstringty; + const width: integer; font: tfont = nil): richstringarty; +var + info: drawtextinfoty; +begin + info.text:= text; + info.dest.pos:= nullpoint; + info.dest.cx:= width; + info.dest.cy:= bigint; + info.flags:= [tf_wordbreak]; + info.font:= font; + info.tabulators:= nil; + result:= breaklines(canvas,info); +end; + +function breaklines(const canvas: tcanvas; const text: msestring; + const width: integer; font: tfont = nil): msestringarty; +var + rstr1: richstringty; + ar1: richstringarty; + int1: integer; +begin + rstr1.format:= nil; + rstr1.text:= text; + ar1:= breaklines(canvas,rstr1,width,font); + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= ar1[int1].text; + end; +end; + +procedure adjustellipse(const acanvas: tcanvas; const info: drawtextinfoty; + const layoutinfo: layoutinfoty; + const line: integer; var startx: integer; + out startindex: integer; out endindex: integer); +var + ellipsewidth,ellipsewidthsum: integer; + int1: integer; +begin + with info,layoutinfo,lineinfos[line] do begin + startindex:= liindex; + endindex:= liindex + licount - 1; + if (liwidth > dest.cx) and (flags * ellipsemask <> []) then begin + ellipsewidth:= acanvas.getstringwidth(textellipse); + ellipsewidthsum:= liwidth + ellipsewidth; + if tf_ellipseleft in flags then begin + startindex:= licount; + for int1:= liindex-1 to liindex+licount-2 do begin + dec(ellipsewidthsum,charwidths[int1]); + if ellipsewidthsum < dest.cx then begin + startindex:= int1+2; + break; + end; + end; + startx:= startx + ellipsewidth; + end + else begin + for int1:= liindex+licount-2 downto liindex-1 do begin + dec(ellipsewidthsum,charwidths[int1]); + if ellipsewidthsum < dest.cx then begin + endindex:= int1; + break; + end; + end; + end; + if tf_right in flags then begin + startx:= startx + (liwidth-ellipsewidthsum); + end + else begin + if tf_xcentered in flags then begin + startx:= startx + (liwidth-ellipsewidthsum) div 2; + end; + end; + end; + end; +end; + +function postotextindex(const canvas: tcanvas; var info: drawtextinfoty; + const pos: pointty; out aindex: integer): boolean; + //false if out of text +var + layoutinfo: layoutinfoty; + int1,int2: integer; + startindex,endindex: integer; +begin + result:= true; + with info,canvas,layoutinfo do begin + if text.text = '' then begin + result:= false; + aindex:= 0; + exit; + end; + layouttext(canvas,info,layoutinfo); + if pos.y < res.y then begin + result:= false; + aindex:= 0; + end + else begin + if pos.y >= res.y + height then begin + aindex:= length(text.text); + result:= false; + end + else begin + int1:= (pos.y-starty+ascent) div lineheight; + if int1 > high(lineinfos) then begin + int1:= high(lineinfos); //last line is ascent+descent + end; + with lineinfos[int1] do begin + int2:= listartx; + adjustellipse(canvas,info,layoutinfo,int1,int2,startindex,endindex); +// int3:= liindex + licount - 1; + aindex:= endindex; + result:= false; +// for int1:= liindex-1 to liindex+licount-2 do begin + for int1:= startindex-1 to endindex-1 do begin + inc(int2,charwidths[int1]); + if int2 >= pos.x then begin + aindex:= int1; + result:= true; + break; + end; + end; + if aindex < endindex then begin + if int2 - pos.x < charwidths[aindex] div 2 then begin + inc(aindex); + end; + end; + end; + end; + end; + end; +end; + +function textindextopos(const canvas: tcanvas; var info: drawtextinfoty; + aindex: integer): pointty; +var + layoutinfo: layoutinfoty; + int1,int2,int3: integer; + startindex,endindex: integer; +begin + with info,layoutinfo do begin + layouttext(canvas,info,layoutinfo); + if aindex > length(text.text) then begin + aindex:= length(text.text); + end + else begin + if aindex < 0 then begin + aindex:= 0; + end; + end; + int3:= 0; //compiler warning + for int1:= 0 to high(lineinfos) do begin + with lineinfos[int1] do begin + if liindex + licount > aindex then begin + int3:= int1; + break; + end; + end; + end; + result.y:= starty + int3 * lineheight; + with lineinfos[int3] do begin + int2:= listartx; + adjustellipse(canvas,info,layoutinfo,int3,int2,startindex,endindex); +// for int1:= liindex-1 to aindex-1 do begin + for int1:= startindex-1 to aindex-1 do begin + inc(int2,charwidths[int1]); + end; + result.x:= int2; + end; + end; +end; + +procedure drawtext(const canvas: tcanvas; var info: drawtextinfoty); +const + stopmask = [ni_bold,ni_italic,ni_blank,ni_underline,ni_strikeout,ni_selected, + ni_fontcolor,ni_colorbackground]; + fonthandlemask = [ni_bold,ni_italic]; + fontstylemask = [ni_bold,ni_italic,ni_blank,ni_underline,ni_strikeout]; + +var + layoutinfo: layoutinfoty; + pos: pointty; + infoindexbefore,charindexbefore: integer; + last: boolean; + count: integer; + defaultcolor,defaultcolorbackground: colorty; + afontstyle,fontstylebefore,overridefontstyle: fontstylesty; + grayed: boolean; + formatactive: boolean; + endindex: integer; + ellipsewidthsum: integer; + rot: real; + + procedure drawsubstring(const row,astart,acount: integer); + var + int2,int3,int4,int5,int6: integer; + xbefore: integer; + x: integer; + co1: colorty; + begin + if acount > 0 then begin + if layoutinfo.xyswapped then begin + x:= pos.y; + end + else begin + x:= pos.x; + end; + xbefore:= x; + + with info,tcanvas1(canvas),layoutinfo,lineinfos[row] do begin + if tabchars = nil then begin + drawstring(@text.text[astart],acount,pos,nil,grayed,rot); + for int2:= astart - 1 to astart + acount - 2 do begin + inc(x,charwidths[int2]); + end; + end + else begin + int2:= astart - 1; + for int4:= 0 to high(tabchars) do begin + if (tabchars[int4].index >= astart) and + (tabchars[int4].index < astart + acount) then begin + drawstring(@text.text[int2+1],tabchars[int4].index - int2 - 1,pos,nil, + grayed,rot); + for int2:= int2 to tabchars[int4].index - 1 do begin + inc(x,charwidths[int2]); + end; + int3:= charwidths[tabchars[int4].index - 1]; + co1:= font.colorbackground; + if (co1 <> cl_transparent) and (co1 <> cl_default) then begin + if xyswapped then begin + if reversed then begin + fillrect(makerect(pos.x-font.descent,x - int3, + font.ascent+font.descent,int3),font.colorbackground); + end + else begin + fillrect(makerect(pos.x-font.ascent,x - int3 - 1, + font.ascent+font.descent,int3),font.colorbackground); + end; + end + else begin + if reversed then begin + fillrect(makerect(x - int3 - 1,pos.y-font.descent,int3, + font.ascent+font.descent),font.colorbackground); + end + else begin + fillrect(makerect(x - int3,pos.y-font.ascent,int3, + font.ascent+font.descent),font.colorbackground); + end; + end; + end; + with tabchars[int4] do begin + int2:= index; + int5:= pos.y - font.ascent div 2; + int6:= x - int3 div 2 + 1; + if (tf_showtabs in flags) and (kind <> tabulatorkindty(-1)) and + not xyswapped and not reversed then begin + drawline(mp(int6 - 3,int5),mp(int6,int5),font.color); + drawlines([mp(int6,int5-1),mp(int6+1,int5), + mp(int6,int5+1)],true,font.color); + { + case kind of + tak_left: begin + drawlines([mp(linepos,int5-2),mp(linepos,int5), + mp(linepos+2,int5)],false,font.color); + end; + tak_right: begin + drawlines([mp(linepos,int5-2),mp(linepos,int5), + mp(linepos-2,int5)],false,font.color); + end; + tak_centered,tak_decimal: begin + drawlinesegments([mg(mp(linepos,int5-2),mp(linepos,int5)), + mg(mp(linepos-2,int5),mp(linepos+2,int5))],font.color); + end; + end; + } + end; + end; + if xyswapped then begin + pos.y:= x; + end + else begin + pos.x:= x; + end; + end; + end; + int3:= acount - int2 + astart - 1; + drawstring(@text.text[int2+1],int3,pos,nil,grayed,rot); + for int2:= int2 to int2 + int3 - 1 do begin + inc(x,charwidths[int2]); + end; + end; + if not grayed then begin + if fs_underline in canvas.font.style then begin + if xyswapped then begin + drawfontline(makepoint(pos.x+underline,xbefore), + makepoint(pos.x+underline,x-1)); + end + else begin + drawfontline(makepoint(xbefore,pos.y+underline), + makepoint(x-1,pos.y+underline)); + end; + end; + if fs_strikeout in font.style then begin + if xyswapped then begin + drawfontline(makepoint(pos.x+layoutinfo.strikeout,xbefore), + makepoint(pos.x+layoutinfo.strikeout,x-1)); + end + else begin + drawfontline(makepoint(xbefore,pos.y+layoutinfo.strikeout), + makepoint(x-1,pos.y+layoutinfo.strikeout)); + end; + end; + end; + if layoutinfo.xyswapped then begin + pos.y:= x; + end + else begin + pos.x:= x; + end; + end; + end; + end; + + procedure adjustellipsepos(delta: integer); + begin + if tf_right in info.flags then begin + pos.x:= pos.x - delta; + end + else begin + if tf_xcentered in info.flags then begin + pos.x:= pos.x - delta div 2; + end; + end; + end; + + procedure updatefont(const aformat: formatinfoty); + begin + with aformat,info,canvas do begin + if newinfos * fontstylemask <> [] then begin + afontstyle:= afontstyle * fontstylesty( + not {$ifdef FPC}longword({$else}byte(word{$endif}(newinfos))) + + style.fontstyle; + font.style:= afontstyle + overridefontstyle; + end; + if (ni_selected in newinfos) and not (tf_noselect in flags)then begin + if tf_underlineselect in flags then begin + if not (fs_underline in style.fontstyle) then begin + if fs_selected in style.fontstyle then begin + font.style:= font.style + [fs_underline]; + end + else begin + font.style:= font.style - [fs_underline]; + end; + end; + end + else begin + if (fs_selected in style.fontstyle) then begin + if font.colorselect = cl_default then begin + font.color:= cl_selectedtext; + end + else begin + font.color:= font.colorselect; + end; + if font.colorselectbackground = cl_default then begin + font.colorbackground:= cl_selectedtextbackground; + end + else begin + font.colorbackground:= font.colorselectbackground; + end; + end + else begin + if style.fontcolor = 0 then begin + font.color:= defaultcolor; + end + else begin + font.color:= not style.fontcolor; + end; + if style.colorbackground = 0 then begin + font.colorbackground:= defaultcolorbackground; + end + else begin + font.colorbackground:= not style.colorbackground; + end; + end; + end; + end; + if not (fs_selected in style.fontstyle) or + (tf_underlineselect in flags) then begin + if ni_fontcolor in newinfos then begin + if style.fontcolor = 0 then begin + font.color:= defaultcolor; + end + else begin + font.color:= not style.fontcolor; + end; + end; + if ni_colorbackground in newinfos then begin + if style.colorbackground = 0 then begin + font.colorbackground:= defaultcolorbackground; + end + else begin + font.colorbackground:= not style.colorbackground; + end; + end; + end; + end; + end; + +var + row: integer; + ellipsewidth: integer; + int1,int3{,int4}: integer; + lastover: boolean; + textbackup: msestring; + formatbackup: formatinfoarty; + +label + endlab; + +begin //drawtext + with info,tcanvas1(canvas) do begin + if tf_rotate90 in flags then begin + if tf_rotate180 in flags then begin + rot:= 1.5*pi; + end + else begin + rot:= 0.5*pi; + end; + end + else begin + if tf_rotate180 in flags then begin + rot:= pi; + end + else begin + rot:= 0; + end; + end; + if tf_tabtospace in flags then begin + textbackup:= text.text; //backup + replacechar1(text.text,msechar(c_tab),msechar(' ')); + end; + if flags * ellipsemask <> [] then begin + formatbackup:= text.format; + text.format:= nil; //no format handling with ellipse + end; + try + if cs_internaldrawtext in fstate then begin + internaldrawtext(info); + exit; + end; + save; + if tf_clipi in flags then begin + intersectcliprect(dest); + end; + if tf_clipo in flags then begin + intersectcliprect(clip); + end; + if text.text = '' then begin + info.res:= nullrect; + goto endlab; + end; + layouttext(canvas,info,layoutinfo); + defaultcolor:= font.color; + defaultcolorbackground:= font.colorbackground; + fontstylebefore:= font.style; + afontstyle:= fontstylebefore; + overridefontstyle:= afontstyle * [fs_bold,fs_italic,fs_underline]; + grayed:= tf_grayed in flags; + if info.text.format <> nil then begin + infoindexbefore:= -1; + int1:= 0; //format index + row:= 0; //layoutinfo row index + lastover:= false; + while row <= high(layoutinfo.lineinfos) do begin + with layoutinfo.lineinfos[row] do begin + if layoutinfo.xyswapped then begin + pos.x:= liy; + pos.y:= listartx; + end + else begin + pos.y:= liy; + pos.x:= listartx; + end; + charindexbefore:= liindex-1; + endindex:= charindexbefore + licount; + end; + while true do begin + with text.format[int1] do begin + formatactive:= (index < endindex); + last:= (int1 >= high(text.format)) or not formatactive; + if last or (newinfos * stopmask <> []) then begin + if infoindexbefore >= 0 then begin + updatefont(text.format[infoindexbefore]); + end; + if formatactive and not lastover then begin + count:= text.format[int1].index - charindexbefore; + if count > 0 then begin + drawsubstring(row,charindexbefore+1,count); + inc(charindexbefore,count); + end; + infoindexbefore:= int1; + if last then begin + updatefont(text.format[int1]); + count:= endindex - charindexbefore; + drawsubstring(row,charindexbefore+1,count); + inc(charindexbefore,count); + lastover:= true; + break; + end; + end + else begin + drawsubstring(row,charindexbefore+1,endindex - charindexbefore); + break; + end; + end; + end; + inc(int1); + end; + inc(row); + end; + font.color:= defaultcolor; + font.colorbackground:= defaultcolorbackground; + font.style:= fontstylebefore; + end + else begin + for row:= 0 to high(layoutinfo.lineinfos) do begin + with layoutinfo.lineinfos[row] do begin + if layoutinfo.xyswapped then begin + pos.x:= liy; + pos.y:= listartx; + end + else begin + pos.y:= liy; + pos.x:= listartx; + end; + if (liwidth > dest.cx) and (flags * ellipsemask <> []) then begin + ellipsewidth:= getstringwidth(textellipse); + ellipsewidthsum:= liwidth + ellipsewidth; + int1:= liindex; + if tf_ellipseleft in flags then begin + int3:= liindex + licount; + while int1 < int3 do begin + dec(ellipsewidthsum,layoutinfo.charwidths[int1-1]); + inc(int1); + if ellipsewidthsum <= dest.cx then begin + break; + end; + end; + adjustellipsepos(ellipsewidthsum -liwidth); + drawstring(textellipse,pos,nil,tf_grayed in flags); + inc(pos.x,ellipsewidth); + dec(licount,int1-liindex); + liindex:= int1; + drawsubstring(row,liindex,licount); + end + else begin + if tf_ellipseright in flags then begin + int1:= int1 + licount; + while int1 > liindex do begin + dec(int1); + dec(ellipsewidthsum,layoutinfo.charwidths[int1-1]); + if ellipsewidthsum <= dest.cx then begin + break; + end; + end; + end; + licount:= int1 - liindex; + adjustellipsepos(ellipsewidthsum -liwidth); + drawsubstring(row,liindex,licount); + drawstring(textellipse,pos,nil,tf_grayed in flags); + end; + end + else begin + drawsubstring(row,liindex,licount); + end; + inc(pos.y,layoutinfo.lineheight); + end; + end; + end; +endlab: + restore; + finally + if tf_tabtospace in flags then begin + text.text:= textbackup; + end; + if flags * ellipsemask <> [] then begin + text.format:= formatbackup; + end; + end; + end; +end; + +procedure drawtext(const canvas: tcanvas; const text: richstringty; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); +var + info: drawtextinfoty; +begin + info.text:= text; + info.dest:= dest; + info.flags:= flags - [tf_clipo]; + info.font:= font; + info.tabulators:= tabulators; + drawtext(canvas,info); +end; + +procedure drawtext(const canvas: tcanvas; const text: richstringty; + const dest,clip: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); +var + info: drawtextinfoty; +begin +// info.canvas:= canvas; + info.text:= text; + info.dest:= dest; + info.clip:= clip; + info.flags:= flags; + info.font:= font; + info.tabulators:= tabulators; + drawtext(canvas,info); +end; + +procedure drawtext(const canvas: tcanvas; const text: msestring; + const dest,clip: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); +var + info: drawtextinfoty; +begin +// info.canvas:= canvas; + info.text.format:= nil; + info.text.text:= text; + info.dest:= dest; + info.clip:= clip; + info.flags:= flags; + info.font:= font; + info.tabulators:= tabulators; + drawtext(canvas,info); +end; + +procedure drawtext(const canvas: tcanvas; const text: msestring; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); +var + ristr1: richstringty; +begin + ristr1.text:= text; + ristr1.format:= nil; + drawtext(canvas,ristr1,dest,flags,font,tabulators); +end; + +procedure textrect(const canvas: tcanvas; var info: drawtextinfoty); +var + layoutinfo: layoutinfoty; +begin + layouttext(canvas,info,layoutinfo); +end; + +function textclipped(const canvas: tcanvas; var info: drawtextinfoty): boolean; +begin + textrect(canvas,info); + result:= not rectinrect(info.res,info.dest); +end; + +function textrect(const canvas: tcanvas; const text: richstringty; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil): rectty; +var + info: drawtextinfoty; +begin + info.text:= text; + info.dest:= dest; +// info.clip:= dest; + info.flags:= flags - [tf_clipo]; + info.font:= font; + info.tabulators:= tabulators; + textrect(canvas,info); + result:= info.res; +end; + +function textrect(const canvas: tcanvas; const text: richstringty; + flags: textflagsty = []; font: tfont = nil; + tabulators: tcustomtabulators = nil): rectty; overload; +begin + flags:= flags - [tf_right,tf_bottom,tf_xcentered,tf_ycentered]; + result:= textrect(canvas,text,makerect(0,0,bigint,bigint),flags,font,tabulators); +end; + +function textrect(const canvas: tcanvas; const text: msestring; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil): rectty; +var + str1: richstringty; +begin + str1.text:= text; + result:= textrect(canvas,str1,dest,flags,font,tabulators); +end; + +function textrect(const canvas: tcanvas; const text: msestring; + flags: textflagsty = []; font: tfont = nil; + tabulators: tcustomtabulators = nil): rectty; +var + str1: richstringty; +begin + str1.text:= text; + result:= textrect(canvas,str1,flags,font,tabulators); +end; + +{ ttabulatoritem } + +procedure ttabulatoritem.setkind(const avalue: tabulatorkindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + tcustomtabulators(fowner).changed(self); + end; +end; + +procedure ttabulatoritem.setpos(const avalue: real); +begin + if fpos <> avalue then begin + fpos:= avalue; + tcustomtabulators(fowner).changed(self); + end; +end; + +procedure ttabulatoritem.setdistleft(const avalue: real); +begin + if fdistleft <> avalue then begin + fdistleft:= avalue; + tcustomtabulators(fowner).changed(self); + end; +end; + +procedure ttabulatoritem.setdistright(const avalue: real); +begin + if fdistright <> avalue then begin + fdistright:= avalue; + tcustomtabulators(fowner).changed(self); + end; +end; + +function ttabulatoritem.getenabled(): boolean; +begin + result:= true; +end; + +{ tcustomtabulators } + +constructor tcustomtabulators.create; +begin + fppmm:= defaultppmm; + inherited create(self,getitemclass); +end; + +class function tcustomtabulators.getitemclasstype: persistentclassty; +begin + result:= getitemclass; +end; + +procedure tcustomtabulators.assign(source: tpersistent); +var + int1: integer; +begin + if source is tcustomtabulators then begin + beginupdate; + with tcustomtabulators(source) do begin + self.count:= count; + for int1:= 0 to high(fitems) do begin + ttabulatoritem(self.fitems[int1]).fkind:= ttabulatoritem(fitems[int1]).fkind; + ttabulatoritem(self.fitems[int1]).fpos:= ttabulatoritem(fitems[int1]).fpos; + end; + self.fdefaultdist:= fdefaultdist; + end; + endupdate; + end + else begin + inherited; + end; +end; + +class function tcustomtabulators.getitemclass: tabulatoritemclassty; +begin + result:= ttabulatoritem; +end; + +procedure tcustomtabulators.changed(const sender: ttabulatoritem); +begin + dochange(-1); +end; + +procedure tcustomtabulators.dochange(const index: integer); +begin + fuptodate:= false; + inherited; +end; + +procedure tcustomtabulators.add(const apos: real; const akind: tabulatorkindty); +begin + beginupdate; + count:= count + 1; + with ttabulatoritem(fitems[high(fitems)]) do begin + fpos:= apos; + fkind:= akind; + end; + endupdate; +end; + +procedure tcustomtabulators.setdefaulttabs(const awidth: real; + const acount: integer; const akind: tabulatorkindty); +var + int1: integer; +begin + beginupdate; + count:= acount; + for int1:= 0 to high(fitems) do begin + with ttabulatoritem(fitems[int1]) do begin + fpos:= (int1+1)*awidth; + fkind:= akind; + end; + end; + endupdate; +end; + +procedure tcustomtabulators.setppmm(const avalue: real); +begin + if fppmm <> avalue then begin + fppmm:= avalue; + changed(nil); + end; +end; + +function cmptab(const l,r): integer; +begin + result:= tabulatorty(l).linepos - tabulatorty(r).linepos; +end; + +procedure tcustomtabulators.checkuptodate; +var + int1: integer; + prevtab,nexttab: int32; +begin + if not fuptodate then begin + setlength(ftabs,count); + for int1:= 0 to high(ftabs) do begin + with ftabs[int1] do begin + index:= int1; + with ttabulatoritem(fitems[int1]) do begin + tabkind:= fkind; + linepos:= round(fpos*fppmm); + case kind of + tak_left: begin + textpos:= round((fpos + fdistleft)*fppmm); + end; + tak_right{,tak_decimal}: begin + textpos:= round((fpos - fdistright)*fppmm); + end; + else begin //tak_center +// textpos:= round((fpos + (fdistleft - fdistright))*fppmm); + textpos:= linepos; + end; + end; + end; + end; + end; + sortarray(ftabs,sizeof(ftabs[0]),{$ifdef FPC}@{$endif}cmptab); + for int1:= 0 to high(ftabs) do begin + with ftabs[int1],ttabulatoritem(fitems[index]) do begin + prevtab:= int1-1; + while (prevtab >= 0) and + not ttabulatoritem(fitems[ftabs[prevtab].index]).getenabled do begin + dec(prevtab); + end; + nexttab:= int1+2; + while (nexttab <= high(fitems)) and + not ttabulatoritem(fitems[ftabs[nexttab].index]).getenabled do begin + inc(nexttab); + end; + if nexttab <= high(ftabs) then begin + cellwidth:= ftabs[nexttab].linepos - linepos; + end + else begin + cellwidth:= 0; + end; + case tabkind of + tak_right,tak_decimal: begin + width:= -round(fdistleft*fppmm); + if prevtab >= 0 then begin + width:= textpos - ftabs[prevtab].linepos + width; + end + else begin + width:= textpos + width; + end; + end; + tak_centered: begin + width:= -round((fdistright+fdistleft)*fppmm); + if (prevtab >= 0) and (nexttab <= high(ftabs)) then begin + width:= ftabs[nexttab].linepos - ftabs[prevtab].linepos + width; + end + else begin + width:= 2 * linepos + width; + end; + end; + else begin //tak_left + width:= -round((fdistright)*fppmm); + if nexttab <= high(ftabs) then begin + width:= ftabs[nexttab].linepos - textpos + width + end; + end; + end; + end; + end; + fuptodate:= true; + end; +end; + +function tcustomtabulators.gettabs: tabulatorarty; +begin + checkuptodate; + result:= ftabs; +end; + +function tcustomtabulators.getitems(const index: integer): ttabulatoritem; +begin + result:= ttabulatoritem(inherited getitems(index)); +end; + +procedure tcustomtabulators.setitems(const index: integer; const avalue: ttabulatoritem); +begin + getitems(index).assign(avalue); +end; + +procedure tcustomtabulators.setdefaultdist(const avalue: real); +begin + fdefaultdist:= avalue; + if fdefaultdist < 0 then begin + fdefaultdist:= 0; + end; + dochange(-1); +end; + +function tcustomtabulators.getpos(const index: integer): integer; +var + int1: integer; +begin + checkuptodate; + if index <= high(ftabs) then begin + result:= ftabs[index].textpos; + end + else begin + if length(ftabs) > 0 then begin + if fdefaultdist > 0 then begin + int1:= trunc(ftabs[high(ftabs)].linepos/fdefaultdist); + end + else begin + result:= ftabs[high(ftabs)].textpos; + exit; + end; + end + else begin + int1:= 0; + end; + result:= round((int1 + index - high(ftabs)) * fdefaultdist); + end; +end; + +function tcustomtabulators.getlinepos(const index: integer): integer; +var + int1: integer; +begin + checkuptodate; + if index <= high(ftabs) then begin + result:= ftabs[index].linepos; + end + else begin + if length(ftabs) > 0 then begin + if fdefaultdist > 0 then begin + int1:= trunc(ftabs[high(ftabs)].linepos/fdefaultdist); + end + else begin + result:= ftabs[high(ftabs)].linepos; + exit; + end; + end + else begin + int1:= 0; + end; + result:= round((int1 + index - high(ftabs)) * fdefaultdist); + end; +end; + +procedure tcustomtabulators.setlinepos(const index: integer; + const avalue: integer); +begin + checkuptodate; + checkindex(index); + ttabulatoritem(fitems[ftabs[index].index]).pos:= avalue / ppmm; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/mseellipsetria.pas b/mseide-msegui/lib/common/graphics/mseellipsetria.pas new file mode 100644 index 0000000..ac46493 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/mseellipsetria.pas @@ -0,0 +1,522 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseellipsetria; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics,msegraphutils,msetriaglob; + +procedure fillellipsetria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer); + //returns trifan +procedure fillarctria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer); + //returns trifan +function arctria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; + //true if triangles, tristrip otherwise +function ellipsetria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; + //true if triangles, tristrip otherwise + + +implementation +uses + mselinetria; + +procedure adjustellipsecenter(const drawinfo: drawinfoty; + var center: pointty); +begin + with drawinfo,rect.rect^ do begin + center.x:= (x+origin.x) shl 16; + if not odd(cx) then begin + center.x:= center.x + $8000; + end + else begin + center.x:= center.x + $10000; + end; + center.y:= (y+origin.y) shl 16; + if not odd(cy) then begin + center.y:= center.y + $8000; + end + else begin + center.y:= center.y + $10000; + end; + end; +end; + +procedure fillellipsetria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer); +//todo: optimize +var + rea1,sx,sy,f,si,co: real; + x1,y1: integer; + q0,q1,q2,q3: ppointty; + npoints: integer; + int1: integer; + center: pointty; +begin + with drawinfo,drawinfo.rect.rect^ do begin + int1:= cx; + if cy > int1 then begin + int1:= cy; + end; + if int1 = 0 then begin + apointcount:= 0; + apoints:= nil; + exit; + end; + int1:= (int1+1) div 2; //samples per quadrant + rea1:= pi/(2*int1); + npoints:= 2+4*int1; //center + endpoint + allocbuffer(buffer,npoints*sizeof(pointty)); + si:= sin(rea1); + co:= cos(rea1); + adjustellipsecenter(drawinfo,center); + q0:= buffer.buffer; + q0^:= center; + inc(q0); + q1:= q0+int1; + q2:= q1+int1; + q3:= q2+int1; + if cx > cy then begin + f:= cy/cx; + sx:= cx*(65536/2); + sy:= 0; + for int1:= int1-1 downto 0 do begin + y1:= round(sy*f); + x1:= round(sx); + q0^.x:= center.x + x1; + q0^.y:= center.y - y1; + inc(q0); + q2^.x:= center.x - x1; + q2^.y:= center.y + y1; + inc(q2); + x1:= round(sx*f); + y1:= round(sy); + q1^.x:= center.x - y1; + q1^.y:= center.y - x1; + inc(q1); + q3^.x:= center.x + y1; + q3^.y:= center.y + x1; + inc(q3); + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + end + else begin + f:= cx/cy; + sy:= cy*(65536/2); + sx:= 0; + for int1:= int1-1 downto 0 do begin + x1:= round(sx*f); + y1:= round(sy); + q0^.y:= center.y - y1; + q0^.x:= center.x + x1; + inc(q0); + q2^.y:= center.y + y1; + q2^.x:= center.x - x1; + inc(q2); + y1:= round(sy*f); + x1:= round(sx); + q1^.y:= center.y - x1; + q1^.x:= center.x - y1; + inc(q1); + q3^.y:= center.y + x1; + q3^.x:= center.x + y1; + inc(q3); + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + end; + q3^:= (ppointty(buffer.buffer)+1)^; //endpoint + apoints:= buffer.buffer; + apointcount:= npoints; + end; +end; + +procedure fillarctria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer); + //returns trifan +var + rea1,sx,sy,cx1,cy1,si,co: real; + x1,y1: integer; + q0: ppointty; + npoints: integer; + int1: integer; + center: pointty; +begin + with drawinfo,triagcty(gc.platformdata).d,drawinfo.arc,rect^ do begin + int1:= cx; + if cy > int1 then begin + int1:= cy; + end; + if int1 = 0 then begin + apointcount:= 0; + apoints:= nil; + exit; + end; + int1:= round(int1*abs(extentang)/pi); //steps + adjustellipsecenter(drawinfo,center); + cx1:= cx * (65536 div 2); + cy1:= cy * (65536 div 2); + sx:= cos(startang); + sy:= sin(startang); + rea1:= extentang/int1; //step + si:= sin(rea1); + co:= cos(rea1); + npoints:= int1+2; //center + endpoint + allocbuffer(buffer,npoints*sizeof(pointty)); + q0:= ppointty(buffer.buffer)+1; + for int1:= int1 downto 0 do begin + x1:= round(cx1*sx); + y1:= round(cy1*sy); + q0^.x:= center.x + x1; + q0^.y:= center.y - y1; + inc(q0); + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + if not pieslice then begin + dec(q0); + with (ppointty(buffer.buffer)+1)^ do begin + center.x:= (q0^.x + x) div 2; + center.y:= (q0^.y + y) div 2; + end; + end; + ppointty(buffer.buffer)^:= center; + apoints:= buffer.buffer; + apointcount:= npoints; + end; +end; + +function arctria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; +var + rea1,sx,sy,w,cxw,cyw,cx1,cy1,cx2,cy2,{xdy,ydx,}si,co: real; + x1,y1,x2,y2,x3,y3,x4,y4: integer; + q0: ppointty; +// po1: ptrianglety; + npoints: integer; + int1: integer; + center: pointty; + circle,lineendings: boolean; + step,dashstep,dashsum: real; + dashindex: integer; + wasoff: boolean; + li: lineshiftinfoty; + shiftfact: integer; +begin + result:= false; + dashstep:= 0; + x2:= 0; + y2:= 0; + with drawinfo,drawinfo.arc,rect^,triagcty(gc.platformdata).d do begin + lineendings:= not (trf_capbutt in triaflags); + li.offsx:= 0; + li.offsy:= 0; + int1:= cx; + if cy > int1 then begin + int1:= cy; + end; + if int1 = 0 then begin + apoints:= nil; + apointcount:= 0; + exit; + end; + li.reverse:= extentang >= 0; + if li.reverse then begin + shiftfact:= -2; + end + else begin + shiftfact:= 2; + end; + int1:= round(int1*abs(extentang)/pi); //steps + if int1 = 0 then begin + int1:= 1; + end; + adjustellipsecenter(drawinfo,center); + cx1:= cx * (65536 div 2); + cx2:= cx1*cx1; + cy1:= cy * (65536 div 2); + cy2:= cy1*cy1; + w:= linewidth16 div 2; + cxw:= cx1*w; + cyw:= cy1*w; + sx:= cos(startang); + sy:= sin(startang); + if df_dashed in gc.drawingflags then begin + result:= true; + int1:= int1*4; //quarter pixel resolution + circle:= cx = cy; + step:= extentang/int1; //step + si:= sin(step); + co:= cos(step); + if not li.reverse then begin + step:= - step; + end; + if circle then begin + dashstep:= cx*step/2; //constant + end + else begin + step:= step / 65536; //variable dashstep + end; + dashsum:= -ord(xftdashes[1]); + dashindex:= 1; + wasoff:= true; + allocbuffer(buffer,(6*int1+12)*sizeof(pointty)); + //+ start dummy + endpoint, max + q0:= ppointty(buffer.buffer)+2; + for int1:= 0 to int1 do begin + x1:= round(cx1*sx); + y1:= round(cy1*sy); + rea1:= sqrt(cx2*sy*sy+cy2*sx*sx); + if odd(dashindex) then begin + if rea1 = 0 then begin + x2:= round(w); + y2:= 0; + end + else begin + x2:= round(cyw*sx/rea1); + y2:= round(cxw*sy/rea1); + end; + x3:= center.x + x1 + x2; + y3:= center.y - y1 - y2; + x4:= center.x + x1 - x2; + y4:= center.y - y1 + y2; + if not wasoff then begin + q0^.x:= x3; + q0^.y:= y3; + inc(q0); + q0^:= (q0-2)^; + inc(q0); + q0^.x:= x3; + q0^.y:= y3; + inc(q0); + q0^.x:= x4; + q0^.y:= y4; + inc(q0); + end; + q0^.x:= x3; + q0^.y:= y3; + inc(q0); + q0^.x:= x4; + q0^.y:= y4; + inc(q0); + if lineendings and wasoff then begin + li.v.shift.x:= shiftfact*x2; + li.v.shift.y:= shiftfact*y2; + li.dest:= q0; + updatestarttria(drawinfo,li); + q0:= li.dest; + end; + wasoff:= false; + end + else begin + if not wasoff then begin + wasoff:= true; + dec(q0,2); + if lineendings then begin + li.v.shift.x:= shiftfact*x2; + li.v.shift.y:= shiftfact*y2; + li.dest:= q0; + updateendtria(drawinfo,li); + q0:= li.dest; + end; + end; + end; + if not circle then begin + dashstep:= rea1*step; + end; + dashsum:= dashsum + dashstep; + if dashsum >= 0 then begin + inc(dashindex); + if dashindex > length(xftdashes) then begin + dashindex:= 1; + end; + dashsum:= dashsum-ord(xftdashes[dashindex]); + end; + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + if odd(dashindex) then begin + dec(q0,2); + if lineendings then begin + li.v.shift.x:= shiftfact*x2; + li.v.shift.y:= shiftfact*y2; + li.dest:= q0; + updateendtria(drawinfo,li); + q0:= li.dest; + end; + end; + apoints:= ppointty(buffer.buffer)+2; + apointcount:= q0-apoints; + end + else begin + rea1:= extentang/int1; //step + si:= sin(rea1); + co:= cos(rea1); + npoints:= 2*(int1+linewidth1)+2; //+ endpoint + round caps + allocbuffer(buffer,npoints*sizeof(pointty)); + q0:= buffer.buffer; + for int1:= 0 to int1 do begin + x1:= round(cx1*sx); + y1:= round(cy1*sy); + rea1:= sqrt(cx2*sy*sy+cy2*sx*sx); + if rea1 = 0 then begin + x2:= round(w); + y2:= 0; + end + else begin + x2:= round(cyw*sx/rea1); + y2:= round(cxw*sy/rea1); + end; + q0^.x:= center.x + x1 + x2; + q0^.y:= center.y - y1 - y2; + inc(q0); + q0^.x:= center.x + x1 - x2; + q0^.y:= center.y - y1 + y2; + inc(q0); + if lineendings and (int1 = 0) then begin + li.v.shift.x:= shiftfact*x2; + li.v.shift.y:= shiftfact*y2; + li.dest:= q0; + updatestartstrip(drawinfo,li); + q0:= li.dest; + end; + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + if lineendings then begin + li.v.shift.x:= shiftfact*x2; + li.v.shift.y:= shiftfact*y2; + li.dest:= q0; + updateendstrip(drawinfo,li); + q0:= li.dest; + end; + apoints:= buffer.buffer; + apointcount:= q0-apoints; + end; + end; +end; + +function ellipsetria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; +var + rea1,sx,sy,w,cxw,cyw,cx1,cy1,cx2,cy2,{xdy,ydx,}si,co: real; + x1,y1,x2,y2: integer; + q0,q1,q2,q3: ppointty; + npoints: integer; + int1,int2: integer; + center: pointty; + circle: boolean; +begin + result:= false; + with drawinfo,rect.rect^,triagcty(gc.platformdata).d do begin + if df_dashed in gc.drawingflags then begin + arc.startang:= 0; + arc.extentang:= 2*pi; + result:= arctria(drawinfo,apoints,apointcount); + exit; + end; + circle:= cx = cy; + int1:= cx; + if cy > int1 then begin + int1:= cy; + end; + if int1 = 0 then begin + apoints:= nil; + apointcount:= 0; + exit; + end; + int1:= (int1+1) div 2; //samples per quadrant + rea1:= pi/(2*int1); + npoints:= 8*int1+2; //+ endpoint + allocbuffer(buffer,npoints*sizeof(pointty)); + si:= sin(rea1); + co:= cos(rea1); + adjustellipsecenter(drawinfo,center); + int2:= int1*2; + q0:= buffer.buffer; + q1:= q0+int2; + q2:= q1+int2; + q3:= q2+int2; + cx1:= cx * (65536 div 2); + cx2:= cx1*cx1; + cy1:= cy * (65536 div 2); + cy2:= cy1*cy1; + w:= linewidth16 div 2; + cxw:= cx1*w; + cyw:= cy1*w; + sx:= 1; + sy:= 0; + for int1:= int1-1 downto 0 do begin + x1:= round(cx1*sx); + y1:= round(cy1*sy); + rea1:= sqrt(cx2*sy*sy+cy2*sx*sx); + if rea1 = 0 then begin + x2:= round(w); + y2:= 0; + end + else begin + x2:= round(cyw*sx/rea1); + y2:= round(cxw*sy/rea1); + end; + q0^.x:= center.x + x1 + x2; + q0^.y:= center.y - y1 - y2; + inc(q0); + q0^.x:= center.x + x1 - x2; + q0^.y:= center.y - y1 + y2; + inc(q0); + q2^.x:= center.x - x1 - x2; + q2^.y:= center.y + y1 + y2; + inc(q2); + q2^.x:= center.x - x1 + x2; + q2^.y:= center.y + y1 - y2; + inc(q2); + if not circle then begin + x1:= round(cy1*sx); + y1:= round(cx1*sy); + rea1:= sqrt(cy2*sy*sy+cx2*sx*sx); + if rea1 <> 0 then begin + x2:= round(cxw*sx/rea1); + y2:= round(cyw*sy/rea1); + end; + end; + q1^.x:= center.x - y1 - y2; + q1^.y:= center.y - x1 - x2; + inc(q1); + q1^.x:= center.x - y1 + y2; + q1^.y:= center.y - x1 + x2; + inc(q1); + q3^.x:= center.x + y1 + y2; + q3^.y:= center.y + x1 + x2; + inc(q3); + q3^.x:= center.x + y1 - y2; + q3^.y:= center.y + x1 - x2; + inc(q3); + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + q3^:= ppointty(buffer.buffer)^; //endpoint + inc(q3); + q3^:= (ppointty(buffer.buffer)+1)^; + apoints:= buffer.buffer; + apointcount:= npoints; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msefcfontselect.pas b/mseide-msegui/lib/common/graphics/msefcfontselect.pas new file mode 100644 index 0000000..ed39775 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msefcfontselect.pas @@ -0,0 +1,309 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefcfontselect; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics,msetypes,msefontconfig; + +const + highresfontshift = 6; //64 + highresfontfakt = 1 shl highresfontshift; + highresfontmask = highresfontfakt - 1; + +type + fontnamety = ( + fn_foundry,fn_family_name,fn_weight_name,fn_slant,fn_setwidth_name, + fn_addstyle_name,fn_pixel_size,fn_point_size,fn_resolution_x, + fn_resolution_y,fn_spacing,fn_average_width,fn_charset_registry, + fn_encoding); + fontinfoty = array[fontnamety] of string; + +procedure setupfontinfo(const fontdata: fontdataty; var fontinfo: fontinfoty); +procedure setfontinfoname(const aname: string; var ainfo: fontinfoty); +function buildxftpat(const fontdata: fontdataty; + const fontinfo: fontinfoty; const highres: boolean): pfcpattern; +function getfcfontfile(const ainfo: getfontinfoty; out filename: string; + out index: integer; out height: integer): boolean; + +var + defaultfontinfo: fontinfoty; + simpledefaultfont: boolean; + hasdefaultfontarg: boolean;//true if -fn + noxft: boolean; + +implementation +uses + sysutils,msestrings,msegraphutils,msectypes; + +procedure setfontinfoname(const aname: string; var ainfo: fontinfoty); +var + ar1: stringarty; +begin + ar1:= splitstring(aname,':'); + if (high(ar1) = 1) and (ar1[0] <> '') and (ar1[1] <> '') then begin + ainfo[fn_foundry]:= ar1[0]; + ainfo[fn_family_name]:= ar1[1]; + end + else begin + ainfo[fn_family_name]:= aname; + end; +end; + +procedure setupfontinfo(const fontdata: fontdataty; var fontinfo: fontinfoty); +var + ar1: stringarty; + height1,width1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + ar1:= nil; //compiler warning; + fontinfo:= defaultfontinfo; + with pfontdataty(@fontdata)^ do begin + height1:= (h.d.height + fontsizeroundvalue) shr fontsizeshift; + width1:= (h.d.width + fontsizeroundvalue) shr fontsizeshift; + if height1 <> 0 then begin + fontinfo[fn_pixel_size]:= inttostr(height1); + end; + if width1 <> 0 then begin + fontinfo[fn_average_width]:= inttostr(width1); + end; + if h.charset <> '' then begin + ar1:= splitstring(h.charset,'-'); + fontinfo[fn_charset_registry]:= ar1[0]; + if high(ar1) > 0 then begin + fontinfo[fn_encoding]:= ar1[1]; + end; + end; + if h.name <> '' then begin + setfontinfoname(h.name,fontinfo); + end + else begin + end; + if fs_bold in h.d.style then begin + fontinfo[fn_weight_name]:= 'bold'; + end; + if fs_italic in h.d.style then begin + fontinfo[fn_slant]:= 'i'; + end; + end; +end; + +function buildxftpat(const fontdata: fontdataty; + const fontinfo: fontinfoty; const highres: boolean): pfcpattern; +var + int1: integer; +// str1: ansistring; + mat1: tfcmatrix; + rea1: real; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with fontdata do begin +// if fontinfo[fn_charset_registry] <> '*' then begin +// str1:= fontinfo[fn_charset_registry]; +// if fontinfo[fn_encoding] <> '*' then begin +// str1:= str1 +'-'+fontinfo[fn_encoding]; +// end; +// result:= fcnameparse(pansichar(str1)); +// end +// else begin + result:= fcpatterncreate(); +// end; + if fontinfo[fn_foundry] <> '*' then begin + fcpatternaddstring(result,fc_foundry,pansichar(fontinfo[fn_foundry])); + end; + if (h.d.familyoptions = []) then begin + if (h.d.pitchoptions = []) and (fontinfo[fn_family_name] <> '*') then begin + fcpatternaddstring(result,fc_family,pansichar(fontinfo[fn_family_name])); + end; + end + else begin + if foo_helvetica in h.d.familyoptions then begin + fcpatternaddstring(result,fc_family,'sans'); + end + else begin + if foo_roman in h.d.familyoptions then begin + fcpatternaddstring(result,fc_family,'serif'); + end + else begin + if foo_decorative in h.d.familyoptions then begin + end + else begin + if foo_script in h.d.familyoptions then begin + end; + end; + end; + end; + end; + if fs_bold in h.d.style then begin + fcpatternaddinteger(result,fc_weight,fc_weight_bold); + end; + if fs_italic in h.d.style then begin + fcpatternaddinteger(result,fc_slant,fc_slant_italic); + end; + if fontinfo[fn_pixel_size] <> '*' then begin + if trystrtofloat(fontinfo[fn_pixel_size],rea1) then begin + if highres then begin + rea1:= rea1 * highresfontfakt; + end; +// fcpatternadddouble(result,fc_pixel_size,rea1); + //double does not work on raspberry pi + fcpatternaddinteger(result,fc_pixel_size,round(rea1)); + end; + end; + if fontinfo[fn_average_width] <> '*' then begin + if trystrtoint(fontinfo[fn_average_width],int1) then begin + int1:= (int1 + 5) div 10; + fcpatternaddinteger(result,fc_char_width,int1); + end; + end; + if foo_fixed in h.d.pitchoptions then begin + fcpatternaddinteger(result,fc_spacing,fc_mono); + end; + if foo_proportional in h.d.pitchoptions then begin + fcpatternaddinteger(result,fc_spacing,fc_proportional); + end; + if [foo_antialiased,foo_antialiased2]*h.d.antialiasedoptions <> [] then begin + fcpatternaddbool(result,fc_antialias,true); + end; + if foo_nonantialiased in h.d.antialiasedoptions then begin + fcpatternaddbool(result,fc_antialias,false); + end; + if (h.d.xscale <> 1.0) or (h.d.rotation <> 0) then begin + fcmatrixinit(mat1); + mat1.xx:= h.d.xscale; + if h.d.rotation <> 0 then begin + fcmatrixrotate(@mat1,cos(h.d.rotation),sin(h.d.rotation)); + end; + fcpatternaddmatrix(result,fc_matrix,@mat1); + end; + { + if foo_xcore in xcoreoptions then begin + str1:= str1 + ':core=1'; + end; + if foo_noxcore in xcoreoptions then begin + str1:= str1 + ':core=0'; + end; + } + end; +end; + +function getfcfontfile(const ainfo: getfontinfoty; out filename: string; + out index: integer; out height: integer): boolean; +var + fontinfo: fontinfoty; + po1,po2: pfcpattern; + res1: tfcresult; + po3: pchar; + int1: integer; + do1: cdouble; +begin + result:= false; + filename:= ''; + index:= 0; + setupfontinfo(ainfo.fontdata^,fontinfo); + po1:= buildxftpat(ainfo.fontdata^,fontinfo,false); + fcconfigsubstitute(nil,po1,fcmatchpattern); + fcdefaultsubstitute(po1); + po2:= fcfontmatch(nil,po1,@res1); + if po2 <> nil then begin + if fcpatterngetstring(po2,'file',0,@po3) = fcresultmatch then begin + filename:= po3; + end; + if fcpatterngetinteger(po2,'index',0,@int1) = fcresultmatch then begin + index:= int1; + end; + if fcpatterngetdouble(po2,'pixelsize',0,@do1) = fcresultmatch then begin + height:= round(do1); + end + else begin + if fontinfo[fn_pixel_size] <> '' then begin + height:= strtoint(fontinfo[fn_pixel_size]); + end + else begin + height:= 14; + end; + end; + result:= true; + fcpatterndestroy(po2); + end; + fcpatterndestroy(po1); +end; + +procedure x11initdefaultfont; +var + int1,int2: integer; + str1: string; + av: pcharpoaty; + ac: pinteger; + ar1: stringarty; + en1: fontnamety; +begin + ar1:= nil; //compiler warning + simpledefaultfont:= false; + for en1:= low(fontnamety) to high(fontnamety) do begin + defaultfontinfo[en1]:= '*'; + end; + defaultfontinfo[fn_family_name]:= 'helvetica'; + defaultfontinfo[fn_weight_name]:= 'medium'; + defaultfontinfo[fn_slant]:= 'r'; + defaultfontinfo[fn_pixel_size]:= '12'; + defaultfontinfo[fn_charset_registry]:= 'iso10646'; + defaultfontinfo[fn_encoding]:= '1'; + ac:= {$ifdef FPC}@argc{$else}@argcount{$endif}; + av:= pcharpoaty({$ifdef FPC}argv{$else}argvalues{$endif}); + for int1:= ac^ - 1 downto 1 do begin + if (av^[int1] = '-fn') or (av^[int1] = '-font') then begin + hasdefaultfontarg:= true; + if int1 < ac^ - 1 then begin + str1:= av^[int1+1]; + if (length(str1) > 0) then begin + if str1[1] = '-' then begin + ar1:= splitstring(str1,'-'); + for int2:= 1 to high(ar1) do begin + str1:= trim(ar1[int2]); + if str1 <> '*' then begin + defaultfontinfo[fontnamety(int2-1)]:= str1; + end; + if int2 = ord(high(fontnamety)) then begin + break; + end; + end; + noxft:= + (high(ar1) > ord(high(fontnamety))+1) and + (ar1[ord(high(fontnamety))+2] ='noxft'); + end + else begin + setfontinfoname(str1,defaultfontinfo); +// defaultfontinfo[fn_family_name]:= str1; + simpledefaultfont:= true; + end; + dec(ac^,2); //remove font arguments + if int1 < ac^ then begin + move(av^[int1+2],av^[int1],(ac^-int1)*sizeof(av^[0])); + end; + av^[ac^]:= nil; + end; + end; + break; + end; + end; +end; + +initialization + x11initdefaultfont; +{$ifdef mswindows} +// defaultfontinfo[fn_family_name]:= 'Tahoma'; + defaultfontinfo[fn_family_name]:= 'Arial'; +{$endif} +end. diff --git a/mseide-msegui/lib/common/graphics/msefont.pas b/mseide-msegui/lib/common/graphics/msefont.pas new file mode 100644 index 0000000..220f40f --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msefont.pas @@ -0,0 +1,814 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefont; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +interface +uses + mseguiglob,msegraphics,mseclasses; + +function getfontnum(const fontinfo: fontinfoty; var drawinfo: drawinfoty; + getfont: getfontfuncty; var atemplate: tfontcomp): fontnumty; +procedure addreffont(font: fontnumty); +procedure releasefont(font: fontnumty); + +procedure checkhighresfont(const afont: pfontdataty; var drawinfo: drawinfoty); +procedure getchar16widths(var drawinfo: drawinfoty); +procedure getfontmetrics(var drawinfo: drawinfoty); + +function getfontdata(font: fontnumty): pfontdataty; +function findfontdata(const afont: fontty): pfontdataty; +function registerfontalias(const alias,name: string; + mode: fontaliasmodety = fam_nooverwrite; + const height: integer = 0; const width: integer = 0; + const options: fontoptionsty = []; + const xscale: real = 1.0; + ancestor: string = defaultfontalias; + const template: tfontcomp = nil): boolean; + //true if registering ok +function unregisterfontalias(const alias: string): boolean; + //false if alias does not exist +procedure clearfontalias; //removes all alias which are not fam_fix +function fontaliascount: integer; +procedure setfontaliascount(const acount: integer); +function realfontname(const aliasname: string): string; +function getfontforglyph(const abasefont: fontty; + const glyph: unicharty): fontnumty; +function fontoptioncharstooptions(const astring: string): fontoptionsty; + +procedure init; +procedure deinit; + +const + defaultmaxfontcachecount = 64; +var + maxfontcachecount: integer = defaultmaxfontcachecount; + +implementation +uses + mselist,sysutils,mseguiintf,msegraphutils,msetypes,msesys, + msestrings,mseformatstr,msehash,mseglob; + +type + fontnumdataty = record + num: integer; + end; + fontnumhashdataty = record + header: hashheaderty; + data: fontnumdataty; + end; + pfontnumhashdataty = ^fontnumhashdataty; + + tfonthashlist = class(thashdatalist) + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean override; + function getrecordsize(): int32 override; + public +// constructor create; + function find(const afont: fonthashdataty): integer; + procedure add(const afont: fontnumty); + procedure delete(const afont: fontnumty); + end; + + fontdatarecty = record + refcount: integer; + data: pfontdataty; + end; + fontdatarecpoty = ^fontdatarecty; + + fontaliasty = record + alias: string; + ancestor: string; + name: string; + mode: fontaliasmodety; + height: integer; + width: integer; + options: fontoptionsty; + xscale: real; + template: tfontcomp; + end; + pfontaliasty = ^fontaliasty; + fontaliasaty = array[0..0] of fontaliasty; + pfontaliasaty = ^fontaliasaty; + + tfontaliaslist = class(tlinkedrecordlist) + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + procedure updatefontdata(var info: fontdataty; var atemplate: tfontcomp); + function find(const alias: string): integer; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create; + function registeralias(const alias,name: string; + mode: fontaliasmodety = fam_nooverwrite; + const height: integer = 0; const width: integer = 0; + const options: fontoptionsty = []; + const xscale: real = 1.0; + const ancestor: string = ''; + const template: tfontcomp = nil): boolean; + //true if registering ok + end; + +var + fonts: array of fontdatarecty; + lastreusedfont: integer; + ffontaliaslist: tfontaliaslist; + ffonthashlist: tfonthashlist; + +function fontaliaslist: tfontaliaslist; +begin + if ffontaliaslist = nil then begin + ffontaliaslist:= tfontaliaslist.create; + end; + result:= ffontaliaslist; +end; + +function registerfontalias(const alias,name: string; + mode: fontaliasmodety = fam_nooverwrite; + const height: integer = 0; const width: integer = 0; + const options: fontoptionsty = []; + const xscale: real = 1.0; + ancestor: string = defaultfontalias; + const template: tfontcomp = nil): boolean; + //true if registering ok +begin + if (alias = defaultfontalias) and (ancestor = defaultfontalias) then begin + ancestor:= ''; + end; + result:= fontaliaslist.registeralias(alias,name,mode,height,width,options, + xscale,ancestor,template); +end; + +function realfontname(const aliasname: string): string; +var + int1: integer; + str1: string; +begin + result:= ''; + if ffontaliaslist <> nil then begin + str1:= aliasname; + while str1 <> '' do begin + int1:= ffontaliaslist.find(str1); + if int1 >= 0 then begin + with pfontaliasaty(ffontaliaslist.datapo)^[int1] do begin + if (result = '') and (name <> '') then begin + result:= name; + break; + end; + end; + end + else begin + break; + end; + end; + end; + if result = '' then begin + result:= aliasname; + end; +end; + +function unregisterfontalias(const alias: string): boolean; + //false if alias does not exist +var + int1: integer; +begin + result:= false; + if ffontaliaslist <> nil then begin + int1:= ffontaliaslist.find(alias); + if int1 >= 0 then begin + ffontaliaslist.delete(int1); + if ffontaliaslist.count = 0 then begin + freeandnil(ffontaliaslist); + end; + end; + end; +end; + +procedure clearfontalias; //removes all alias which are not fam_fix +var + int1: integer; +begin + if ffontaliaslist <> nil then begin + for int1:= ffontaliaslist.count - 1 downto 0 do begin + if pfontaliasty(ffontaliaslist.getitempo(int1))^.mode <> fam_fix then begin + ffontaliaslist.delete(int1); + end; + end; + end; +end; + +function fontaliascount: integer; +begin + result:= ffontaliaslist.count; +end; + +procedure setfontaliascount(const acount: integer); +begin + ffontaliaslist.count:= acount; +end; + +function getfontdata(font: fontnumty): pfontdataty; +begin + dec(font); + if font >= longword(length(fonts)) then begin + result:= nil; + end + else begin + result:= fonts[font].data; + end; +end; + +function findfontdata(const afont: fontty): pfontdataty; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fonts) do begin + with fonts[int1] do begin + if (refcount > 0) and (data^.font = afont) then begin + result:= fonts[int1].data; + break; + end; + end; + end; +end; + +procedure freefont(index: integer); +var + drawinfo: drawinfoty; +begin + ffonthashlist.delete(index); + with fonts[index] do begin + gdi_lock; + drawinfo.getfont.fontdata:= data; + freefontdata(drawinfo); + finalize(data^); + gdi_unlock; + refcount:= 0; + end; +end; + +type + fontmatrixmodety = (fmm_fix,fmm_linear,fmm_matrix); + x11fontdatadty = record + infopo: pointer; + matrixmode: fontmatrixmodety; + defaultwidth: integer; + xftascent,xftdescent: integer; + rowlength: word; + xftdirection: graphicdirectionty; + end; + px11fontdatadty = ^x11fontdatadty; + x11fontdataty = record + case integer of + 0: (d: x11fontdatadty;); + 1: (_bufferspace: fontdatapty;); + end; + +function registerfont(var fontdata: fontdataty): fontnumty; + + procedure reusefont(startindex: integer); + var + int1: integer; + begin + for int1:= startindex to high(fonts) do begin //reuse oldest + if fonts[int1].refcount <= 0 then begin + freefont(int1); + lastreusedfont:= int1; + result:= int1+1; + break; + end; + end; + end; +var + int1: integer; +begin //registerfont + result:= 0; + if length(fonts) > maxfontcachecount then begin + reusefont(lastreusedfont+1); + if result = 0 then begin + reusefont(0); + end; + end; + if result = 0 then begin + result:= length(fonts)+1; + setlength(fonts,result); + with fonts[high(fonts)] do begin + getmem(data,sizeof(fontdataty)); + fillchar(data^,sizeof(fontdataty),0); + end; + end; + int1:= result-1; + fonts[int1].data^:= fontdata; +// move(fontdata,fonts[int1].data^,sizeof(fontdata)); + fonts[int1].refcount:= 1; + ffonthashlist.add(int1); +end; + +procedure releasefont(font: fontnumty); +begin + dec(font); + if integer(font) < 0 then begin + exit; + end; + if integer(font) <= high(fonts) then begin + with fonts[font] do begin + if refcount > 0 then begin + dec(refcount); + end; + end; + end; +end; + +procedure addreffont(font: fontnumty); +begin + if font > 0 then begin + inc(fonts[font-1].refcount); + end; +end; + +procedure checkhighresfont(const afont: pfontdataty; var drawinfo: drawinfoty); +var + fontinfobefore: getfontinfoty; +begin + with afont^ do begin + if fonthighres = 0 then begin + fontinfobefore:= drawinfo.getfont; + with drawinfo.getfont do begin + fontdata:= afont; + basefont:= 0; + end; + gdi_lock; +// gdi_getfonthighres(drawinfo); + h.d.gdifuncs^[gdf_getfonthighres](drawinfo); + gdi_unlock; + drawinfo.getfont:= fontinfobefore; + end; + end; +end; + +procedure getchar16widths(var drawinfo: drawinfoty); +begin + with drawinfo.getchar16widths.fontdata^ do begin + h.d.gdifuncs^[gdf_getchar16widths](drawinfo); + end; +end; + +procedure getfontmetrics(var drawinfo: drawinfoty); +begin + with drawinfo.getfontmetrics.fontdata^ do begin + h.d.gdifuncs^[gdf_getfontmetrics](drawinfo); + end; +end; + +function comparefont(const s: fontinfoty; const d: fontdataty): boolean; +begin + result:= + (d.h.d.glyph = s.glyph) and //unicode substitutes + (d.h.d.gdifuncs = s.gdifuncs) and + (d.h.d.height = s.baseinfo.height) and + (d.h.d.width = s.baseinfo.width) and + (d.h.d.pitchoptions = s.baseinfo.options * fontpitchmask) and + (d.h.d.familyoptions = s.baseinfo.options * fontfamilymask) and + (d.h.d.antialiasedoptions = s.baseinfo.options * fontantialiasedmask) and + ({$ifdef FPC}longword{$else}byte{$endif}(d.h.d.style) xor + {$ifdef FPC}longword{$else}byte{$endif}(s.baseinfo.style) and + fontstylehandlemask = 0) and + (d.h.name = s.baseinfo.name) and + (d.h.charset = s.baseinfo.charset) and + (d.h.d.rotation = s.rotation) and + (d.h.d.xscale = s.baseinfo.xscale); + +end; + +{ tfonthashlist } +{ +constructor tfonthashlist.create; +begin + inherited create(sizeof(fontnumdataty)); +end; +} +function tfonthashlist.hashkey(const akey): hashvaluety; +begin + with fontdataty(akey) do begin + result:= stringhash(h.name) xor stringhash(h.charset) xor + datahash(h.d,sizeof(h.d)); + end; +end; + +function tfonthashlist.checkkey(const akey; const aitem: phashdataty): boolean; +var + po1: pfontdataty; +begin + po1:= fonts[pfontnumhashdataty(aitem)^.data.num].data; + with fontdataty(akey) do begin + result:= comparemem(@po1^.h.d,@h.d,sizeof(h.d)) and + (po1^.h.name = h.name) and (po1^.h.charset = h.charset); + end; +end; + +function tfonthashlist.getrecordsize(): int32; +begin + result:= sizeof(fontnumhashdataty); +end; + +function tfonthashlist.find(const afont: fonthashdataty): integer; +var + po1: pfontnumhashdataty; +begin + result:= -1; + po1:= pfontnumhashdataty(internalfind(afont)); + if po1 <> nil then begin + result:= po1^.data.num; + end; +end; + +procedure tfonthashlist.add(const afont: fontnumty); +var + po1: pfontnumhashdataty; +begin + po1:= pfontnumhashdataty(internaladd(fonts[afont].data^.h)); + po1^.data.num:= afont; +end; + +procedure tfonthashlist.delete(const afont: fontnumty); +begin + internaldeleteitem(internalfind(fonts[afont].data^.h)); +end; + +procedure getfontvalues(const s: fontinfoty; var d: fontdataty); +begin + fillchar(d.h.d,sizeof(d.h.d),0); + d.h.d.gdifuncs:= s.gdifuncs; + d.h.d.height:= s.baseinfo.height; + d.h.d.width:= s.baseinfo.width; + d.h.d.familyoptions:= s.baseinfo.options * fontfamilymask; + d.h.d.pitchoptions:= s.baseinfo.options * fontpitchmask; + d.h.d.antialiasedoptions:= s.baseinfo.options * fontantialiasedmask; + d.h.d.style:= fontstylesty({$ifdef FPC}longword{$else}byte{$endif} + (s.baseinfo.style) and fontstylehandlemask); + d.h.d.glyph:= s.glyph; + d.h.d.rotation:= s.rotation; + d.h.d.xscale:= s.baseinfo.xscale; + d.h.name:= s.baseinfo.name; + d.h.charset:= s.baseinfo.charset; +end; + +function getfontnum(const fontinfo: fontinfoty; var drawinfo: drawinfoty; + getfont: getfontfuncty; var atemplate: tfontcomp): fontnumty; +var + int1: integer; + data1: fontdataty; +begin + gdi_lock; + with fontinfo do begin + getfontvalues(fontinfo,data1); + int1:= ffonthashlist.find(data1.h); + if int1 >= 0 then begin + with fonts[int1] do begin + inc(refcount); + result:= int1 + 1; + end; + end + else begin //todo: do not load same substitute multiple times + finalize(data1); + fillchar(data1,sizeof(data1),0); + getfontvalues(fontinfo,data1); + if ffontaliaslist <> nil then begin + ffontaliaslist.updatefontdata(data1,atemplate); + end; + drawinfo.getfont.fontdata:= @data1; + drawinfo.getfont.basefont:= 0; + if getfont(drawinfo) then begin + data1.realfont:= data1.h; + if data1.realfont.d.height = 0 then begin + if data1.realheight = 0 then begin + data1.realheight:= data1.linespacing; + end; + data1.realfont.d.height:= data1.realheight shl fontsizeshift; + end; + getfontvalues(fontinfo,data1); + data1.basefont:= drawinfo.getfont.basefont; + result:= registerfont(data1); + end + else begin + result:= 0; + end; + end; + end; + gdi_unlock; +end; + +function getfontforglyph(const abasefont: fontty; const glyph: unicharty): fontnumty; +var + info: drawinfoty; + int1: integer; +begin + result:= 0; + info.fonthasglyph.unichar:= glyph; + gdi_lock; + for int1:= 0 to high(fonts) do begin + with fonts[int1],data^ do begin + if (refcount >= 0) and (basefont = abasefont) then begin + info.fonthasglyph.font:= font; + getdefaultgdifuncs^[gdf_fonthasglyph](info); + if info.fonthasglyph.hasglyph then begin + result:= int1 + 1; + end; + end; + end; + end; + gdi_unlock; +end; + +function fontoptioncharstooptions(const astring: string): fontoptionsty; +var + int1: integer; + option1: fontoptionty; +begin + result:= []; + for int1:= 1 to length(astring) do begin + for option1:= low(fontoptionty) to high(fontoptionty) do begin + if astring[int1] = fontaliasoptionchars[option1] then begin + include(result,option1); + end; + end; + end; +end; + +procedure initfontalias; +//format aliasdef: +//--FONTALIAS=,[,[,[,[,] +// [,]]] +const + paramname = '--FONTALIAS='; +var + ar1,ar2: msestringarty; + int1,{int2,}int3,int4{,int5}: integer; + ar3: array[0..1] of integer; + options1: fontoptionsty; + xscale1: real; + str1: string; + bo1: boolean; +begin + ar1:= getcommandlinearguments; + int3:= 1; + xscale1:= 1.0; + for int1:= 1 to high(ar1) do begin + if msestrlicomp(pmsechar(ar1[int1]),pmsechar(paramname), + length(paramname)) = 0 then begin + ar2:= nil; + splitstringquoted(copy(ar1[int1],length(paramname)+1,bigint),ar2,'"',','); + if (high(ar2) >= 1) and (high(ar2) <= 6) then begin + try + for int4:= 0 to high(ar3) do begin + if int4 + 2 > high(ar2) then begin + ar3[int4]:= 0; + end + else begin + if trim(ar2[int4+2]) <> '' then begin + ar3[int4]:= strtoint(ar2[int4+2]); + end + else begin + ar3[int4]:= 0; + end; + end; + end; + options1:= []; + if high(ar2) >= 4 then begin + options1:= fontoptioncharstooptions(ansistring(ar2[4])); + end; + if (high(ar2) >= 5) and (trim(ar2[5]) <> '') then begin + xscale1:= strtoreal(ar2[5]); + end; + bo1:= lowercase(ar2[0]) = defaultfontalias; + if bo1 and (ar2[1] = '') then begin + ar2[1]:= msestring(gui_getdefaultfontnames[stf_default]); + end; + if high(ar2) >= 6 then begin + str1:= ansistring(trim(ar2[6])); + end + else begin + if bo1 then begin + str1:= ''; + end + else begin + str1:= defaultfontalias; + end; + end; + + fontaliaslist.registeralias(ansistring(ar2[0]),ansistring(ar2[1]), + fam_overwrite,ar3[0],ar3[1],options1,xscale1,str1); + deletecommandlineargument(int3); + dec(int3); + except + end; + end; + end; + inc(int3); + end; +end; + +procedure init; +begin + ffonthashlist:= tfonthashlist.create; + initfontalias; +end; + +procedure deinit; +var + int1: integer; +begin + for int1:= 0 to high(fonts) do begin + with fonts[int1] do begin + refcount:= 1; + freefont(int1); + freemem(data); + end; + end; + freeandnil(ffontaliaslist); + freeandnil(ffonthashlist); +end; + +{ tfontaliaslist } + +constructor tfontaliaslist.create; +begin + inherited create(sizeof(fontaliasty),[rels_needsfinalize,rels_needscopy]); +end; + +procedure tfontaliaslist.finalizerecord(var item); +begin + finalize(fontaliasty(item)); +end; + +procedure tfontaliaslist.copyrecord(var item); +begin + with fontaliasty(item) do begin + stringaddref(alias); + stringaddref(name); + end; +end; + +function tfontaliaslist.find(const alias: string): integer; +var + str1: string; + po1: pfontaliasaty; + int1: integer; +begin + result:= -1; + str1:= struppercase(alias); + po1:= datapo; + for int1:= 0 to count-1 do begin + if po1^[int1].alias = str1 then begin + result:= int1; + break; + end; + end; +end; + +procedure tfontaliaslist.updatefontdata(var info: fontdataty; + var atemplate: tfontcomp); +var + int1: integer; + str1: string; + po1: pchar; +begin + str1:= info.h.name; + po1:= nil; + while str1 <> '' do begin + int1:= find(str1); + if int1 < 0 then begin + break; + end; + with pfontaliasty(getitempo(int1))^ do begin + str1:= ancestor; + if (name <> '') and (po1 = nil) then begin + po1:= pchar(name); + end; + if (height <> 0) and (info.h.d.height = 0) then begin + info.h.d.height:= height; + end; + if (width <> 0) and (info.h.d.width = 0) then begin + info.h.d.width:= width; + end; + if (xscale <> 1) and (info.h.d.xscale = 1) then begin + info.h.d.xscale:= xscale; + end; + if (options * fontpitchmask <> []) and + (info.h.d.pitchoptions * fontpitchmask = []) then begin + info.h.d.pitchoptions:= options * fontpitchmask; + end; + if (options * fontfamilymask <> []) and + (info.h.d.pitchoptions * fontfamilymask = []) then begin + info.h.d.familyoptions:= options * fontfamilymask; + end; + if (options * fontantialiasedmask <> []) and + (info.h.d.pitchoptions * fontantialiasedmask = []) then begin + info.h.d.antialiasedoptions:= options * fontantialiasedmask; + end; + if (template <> nil) and (atemplate = nil) then begin + atemplate:= template; + end; + end; + end; + if po1 <> nil then begin + info.h.name:= po1; + end; +end; + +function tfontaliaslist.registeralias(const alias,name: string; + mode: fontaliasmodety = fam_nooverwrite; + const height: integer = 0; const width: integer = 0; + const options: fontoptionsty = []; + const xscale: real = 1.0; + const ancestor: string = ''; + const template: tfontcomp = nil): boolean; + //true if registering ok +var + po1: pfontaliasty; + + procedure doupdate; + begin + po1^.name:= name; + po1^.mode:= mode; + po1^.height:= height shl fontsizeshift; + po1^.width:= width shl fontsizeshift; + po1^.options:= options; + po1^.xscale:= xscale; + po1^.ancestor:= ancestor; + if template <> po1^.template then begin + getobjectlinker.setlink(iobjectlink(self),template, + tmsecomponent(po1^.template)); + end; + end; + +var + int1: integer; + str1,str2: string; +begin + result:= false; + str1:= uppercase(alias); + str2:= uppercase(ancestor); + while str2 <> '' do begin + if str1 = str2 then begin + raise exception.create('Recursive fontalias "' + +alias+'" name "'+name+'" caller "'+str1+'".'); + end; + int1:= find(str2); + if int1 >= 0 then begin + str2:= uppercase(pfontaliasty(getitempo(int1))^.ancestor); + end + else begin + break; + end; + end; + int1:= find(alias); + if int1 >= 0 then begin + po1:= pfontaliasty(getitempo(int1)); + if not (mode in [fam_nooverwrite,fam_fixnooverwrite]) then begin + if po1^.mode <> fam_fix then begin + doupdate; + end; + end; + end + else begin + count:= count + 1; + po1:= getitempo(count-1); + po1^.alias:= struppercase(alias); + doupdate; + end; + if mode = fam_fixnooverwrite then begin + po1^.mode:= fam_fix; + end; +end; + +procedure tfontaliaslist.objectevent(const sender: tobject; + const event: objecteventty); +var + po1,pe: pfontaliasty; +begin + inherited; + if event = oe_destroyed then begin + po1:= datapo; + pe:= po1 + count; + while po1 < pe do begin + if po1^.template = sender then begin + po1^.template:= nil; + end; + inc(po1); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msefontcache.pas b/mseide-msegui/lib/common/graphics/msefontcache.pas new file mode 100644 index 0000000..aaaa4c2 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msefontcache.pas @@ -0,0 +1,210 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +// +//under construction +// +unit msefontcache; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msehash,msegraphics,mseguiglob; + +type + fontcachedataty = record +// h: fontcachehdataty; + keyname: string; + keyheight: integer; + refcount: integer; + + height: integer; + ascent: integer; + descent: integer; + linespacing: integer; + caretshift: integer; + + font: ptruint; +// handle: pcachefontty; + end; + pfontcachedataty = ^fontcachedataty; + fontcachehashdataty = record + header: hashheaderty; + data: fontcachedataty; + end; + pfontcachehashdataty = ^fontcachehashdataty; + + pfontcache = ^tfontcache; + + tfontcache = class(thashdatalist) + private + finstancepo: pfontcache; + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; + const aitem: phashdataty): boolean; override; + procedure finalizeitem(const aitem: phashdataty); override; + function find(const afont: fontdataty): pfontcachehashdataty; + + procedure internalfreefont(const afont: ptruint); virtual; + function internalgetfont(const ainfo: getfontinfoty; + out aheight: integer): boolean; virtual; abstract; + procedure updatefontinfo(const adataoffset: hashoffsetty; + var adata: fontcachedataty); virtual; abstract; + function getdataoffsfont(const afont: fontty): hashoffsetty; virtual; abstract; + function getrecordsize(): int32 override; + public + constructor create(var ainstance: tfontcache); + procedure getfont(var drawinfo: drawinfoty); + procedure freefontdata(var drawinfo: drawinfoty); + procedure gettext16width(var drawinfo: drawinfoty); virtual; abstract; + procedure getchar16widths(var drawinfo: drawinfoty); virtual; abstract; + procedure getfontmetrics(var drawinfo: drawinfoty); virtual; abstract; + procedure drawstring16(var drawinfo: drawinfoty; + const afont: fontty); virtual; abstract; + end; + +implementation +uses + sysutils,msedynload; //release dynload needed in finalization + +{ tfontcache } + +constructor tfontcache.create(var ainstance: tfontcache); +begin + finstancepo:= @ainstance; + ainstance:= self; + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +procedure tfontcache.finalizeitem(const aitem: phashdataty); +begin + finalize(pfontcachehashdataty(aitem)^.data); +end; + +function tfontcache.hashkey(const akey): hashvaluety; +begin + with fontdataty(akey) do begin + result:= stringhash(h.name) xor h.d.height; + end; +end; + +function tfontcache.checkkey(const akey; const aitem: phashdataty): boolean; +begin + with fontdataty(akey),pfontcachehashdataty(aitem)^.data do begin + result:= (h.name = keyname) and (h.d.height = keyheight); + end; +end; + +function tfontcache.find(const afont: fontdataty): pfontcachehashdataty; +begin + result:= pfontcachehashdataty(internalfind(afont)); +end; + +procedure tfontcache.getfont(var drawinfo: drawinfoty); +var + po1: pfontcachehashdataty; + h1: integer; +begin + with drawinfo.getfont do begin + ok:= true; + po1:= find(fontdata^); + with fontdata^ do begin + if po1 = nil then begin + if not internalgetfont(drawinfo.getfont,h1) then begin + font:= 0; + ok:= false; + exit; + end; + po1:= pfontcachehashdataty(internaladd(fontdata^)); + po1^.data.keyname:= fontdata^.h.name; + po1^.data.keyheight:= fontdata^.h.d.height; + po1^.data.font:= font; + po1^.data.height:= h1; + updatefontinfo(getdataoffs(@po1^.data),po1^.data); + end; + inc(po1^.data.refcount); + font:= po1^.data.font; + ascent:= po1^.data.ascent; + descent:= po1^.data.descent; + linespacing:= po1^.data.linespacing; + realheight:= po1^.data.height; + caretshift:= po1^.data.caretshift; + end; + end; +end; + +(* +procedure tfontcache.getfont(var drawinfo: drawinfoty); +var + po1: pfontcachedataty; + po2: pftglfont; +begin + with drawinfo.getfont do begin + ok:= true; + po1:= find(fontdata^); + with fontdata^ do begin + getmem(pointer(font),ffontdatasize); + with pftglfontty(font)^ do begin + if po1 = nil then begin + po2:= ftglcreatepixmapfont('/usr/share/fonts/truetype/arial.ttf'); + if po2 = nil then begin + freemem(pointer(font)); + pointer(font):= nil; + ok:= false; + exit; + end; + po1:= @((internaladd(fontdata^)^.data)); + po1^.h.name:= fontdata^.h.name; + po1^.h.height:= fontdata^.h.d.height; + po1^.handle:= pointer(po2); + ftglsetfontcharmap(po1^.handle,ft_encoding_unicode); + ftglsetfontfacesize(po1^.handle,20,72); + end; + inc(po1^.refcount); + handle:= po1^.handle; + ascent:= round(ftglgetfontascender(handle)); + descent:= -round(ftglgetfontdescender(handle)); + linespacing:= round(ftglgetfontlineheight(handle)); + caretshift:= 0; + end; + end; + end; +end; +*) +procedure tfontcache.internalfreefont(const afont: ptruint); +begin + //dummy +end; + +function tfontcache.getrecordsize(): int32; +begin + result:= sizeof(fontcachehashdataty); +end; + +procedure tfontcache.freefontdata(var drawinfo: drawinfoty); +var + po1: pfontcachehashdataty; +begin + with drawinfo.getfont.fontdata^ do begin + if font <> 0 then begin + po1:= getdatapo(getdataoffsfont(font)); + dec(po1^.data.refcount); + if po1^.data.refcount = 0 then begin + internalfreefont(font); + end; + internaldeleteitem(phashdataty(po1)); + end; + end; + if count = 0 then begin + freeandnil(finstancepo^); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msefontconfig.pas b/mseide-msegui/lib/common/graphics/msefontconfig.pas new file mode 100644 index 0000000..d0c7379 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msefontconfig.pas @@ -0,0 +1,329 @@ +{ MSEgui Copyright (c) 2011-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefontconfig; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msestrings,msectypes,msetypes; + +const + {$ifdef mswindows} + fontconfiglib: array[0..1] of filenamety = + ('libfontconfig-1.dll','fontconfig1.dll'); + {$else} + fontconfiglib: array[0..1] of filenamety = + ('libfontconfig.so.1','libfontconfig.so'); + {$endif} + FC_FAMILY = 'family'; //* String */ + FC_STYLE = 'style'; //* String */ + FC_SLANT = 'slant'; //* Int */ + FC_WEIGHT = 'weight'; //* Int */ + FC_SIZE = 'size'; //* Double */ + FC_ASPECT = 'aspect'; //* Double */ + FC_PIXEL_SIZE = 'pixelsize'; //* Double */ + FC_SPACING = 'spacing'; //* Int */ + FC_FOUNDRY = 'foundry'; //* String */ + FC_ANTIALIAS = 'antialias'; //* Bool (depends) */ + FC_HINTING = 'hinting'; //* Bool (true) */ + FC_VERTICAL_LAYOUT = 'verticallayout';//* Bool (false) */ + FC_AUTOHINT = 'autohint'; //* Bool (false) */ + FC_GLOBAL_ADVANCE = 'globaladvance'; //* Bool (true) */ + FC_FILE = 'file'; //* String */ + FC_INDEX = 'index'; //* Int */ + FC_FT_FACE = 'ftface'; //* FT_Face */ + FC_RASTERIZER = 'rasterizer'; //* String */ + FC_OUTLINE = 'outline'; //* Bool */ + FC_SCALABLE = 'scalable'; //* Bool */ + FC_SCALE = 'scale'; //* double */ + FC_DPI = 'dpi'; //* double */ + FC_RGBA = 'rgba'; //* Int */ + FC_MINSPACE = 'minspace'; //* Bool use minimum line spacing */ + FC_SOURCE = 'source'; //* String (X11, freetype) */ + FC_CHARSET = 'charset'; //* CharSet */ + FC_LANG = 'lang'; //* String RFC 3066 langs */ + FC_FONTVERSION = 'fontversion'; //* Int from 'head' table */ + + FC_MATRIX = 'matrix'; + FC_CHAR_WIDTH = 'charwidth'; + + FC_WEIGHT_BOLD = 200; + FC_SLANT_ITALIC = 100; + FC_PROPORTIONAL = 0; + FC_MONO = 100; + + +type + TFcChar8 = byte; + PFcChar8 = ^TFcChar8; + TFcChar16 = word; + PFcChar16 = ^TFcChar16; + TFcChar32 = dword; + PFcChar32 = ^TFcChar32; + TFcBool = longbool; //integer; + PFcBool = ^TFcBool; + TFcEndian = (FcEndianBig, FcEndianLittle); + TFcResult = (FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId); + PFcResult = ^TFcResult; + + TFcType = (FcTypeVoid,FcTypeInteger,FcTypeDouble, + FcTypeString,FcTypeBool,FcTypeMatrix, + FcTypeCharSet,FcTypeFTFace,FcTypeLangSet + ); + TFcMatchKind = (FcMatchPattern,FcMatchFont); + TFcMatrix = record + xx: cdouble; + xy: cdouble; + yx: cdouble; + yy: cdouble; + end; + PFcMatrix = ^TFcMatrix; + + TFcLangSet = record + //dummy + end; + PFcLangSet = ^TFcLangset; + + TFcStrList = record + //dummy + end; + PFcStrList = ^TFcStrList; + + TFcCharset = record + //dummy + end; + PFcCharset = ^TFcCharset; + PPFcCharset = ^PFcCharset; + + TFcPattern = record + //dummy + end; + PFcPattern = ^TFcPattern; + PPFcPattern = ^PFcPattern; + pfcpatternpoaty = array[0..0] of PFcPattern; + + TFcValue = record + _type: TFcType; + u: record + case longint of + 0 : ( s : ^TFcChar8 ); + 1 : ( i : longint ); + 2 : ( b : TFcBool ); + 3 : ( d : cdouble ); + 4 : ( m : ^TFcMatrix ); + 5 : ( c : ^TFcCharSet ); + 6 : ( f : pointer ); + 7 : ( p : ^TFcPattern ); + 8 : ( l : ^TFcLangSet ); + end; + end; + + TFcObjectSet = record + nobject: longint; + sobject: longint; + objects: ppchar; + end; + PFcObjectSet = ^TFcObjectSet; + + TFcConfig = record + //dummy + end; + PFcConfig = ^TFcConfig; + + TFcFontSet = record + nfont : integer; + sfont : integer; + fonts : PPFcPattern; + end; + PFcFontSet = ^TFcFontSet; + +var + FcInit: function: tfcbool;cdecl; + FcFini: procedure;cdecl; + FcConfigCreate: function: PFcConfig;cdecl; + FcConfigParseAndLoad: function(config: PFcConfig; afile: pchar; + complain: TFcBool): TFcBool;cdecl; + FcConfigGetCurrent: function: PFcConfig;cdecl; + FcConfigBuildFonts: function(config: PFcConfig): TFcBool;cdecl; + FcConfigGetConfigFiles: function(config: PFcConfig): PFcStrList;cdecl; + FcConfigGetFontDirs: function(config: PFcConfig): PFcStrList;cdecl; + FcConfigFilename: function(name: pchar): pchar;cdecl; + FcPatternDestroy: procedure(p:PFcPattern);cdecl; + FcFontSetDestroy: procedure(s:PFcFontSet);cdecl; + FcObjectSetCreate: function: PFcObjectSet;cdecl; + FcObjectSetAdd: function(os: PFcObjectSet; aobject:Pchar):TFcBool;cdecl; + FcObjectSetDestroy: procedure(os: PFcObjectSet);cdecl; + FcFontList: function(config: PFcConfig; p:PFcPattern; + os:PFcObjectSet): PFcFontSet;cdecl; + FcCharSetCreate: function: PFcCharSet;cdecl; + FcCharSetDestroy: procedure(fcs:PFcCharSet);cdecl; + FcCharSetAddChar: function(fcs:PFcCharSet; ucs4:TFcChar32):TFcBool;cdecl; + FcPatternAdd: function(p:PFcPattern; aobject:Pchar; value:TFcValue; + append:TFcBool):TFcBool;cdecl; + FcPatternCreate: function: PFcPattern;cdecl; + FcConfigSubstitute: function(config:PFcConfig; p:PFcPattern; + kind:TFcMatchKind):TFcBool;cdecl; + FcDefaultSubstitute: procedure (pattern:PFcPattern);cdecl; + FcFontSort: function (config:PFcConfig; p:PFcPattern; trim:TFcBool; + csp:PPFcCharSet; result:PFcResult): PFcFontSet;cdecl; + FcCharSetHasChar: function(fcs:PFcCharSet; ucs4:TFcChar32):TFcBool;cdecl; + FcPatternDuplicate: function (p:PFcPattern): PFcPattern;cdecl; + FcPatternGetCharSet: function (p:PFcPattern; aobject:Pchar; n:longint; + c:PPFcCharSet):TFcResult;cdecl; + FcFontRenderPrepare: function(config:PFcConfig; pat:PFcPattern; + font:PFcPattern): PFcPattern;cdecl; + FcFontMatch: function(config: PFcConfig; p: PFcPattern; + result: PFcResult): PFcPattern;cdecl; + FcMatrixRotate: procedure(m:PFcMatrix; c:cdouble; s:cdouble);cdecl; + FcMatrixScale: procedure(m:PFcMatrix; sx:cdouble; sy:cdouble);cdecl; + FcPatternAddInteger: function(p:PFcPattern; aobject:Pchar; i:longint):TFcBool; cdecl; + FcPatternAddDouble: function(p:PFcPattern; aobject:Pchar; d:cdouble):TFcBool; cdecl; + FcPatternAddString: function(p:PFcPattern; aobject:Pchar; s: pansichar):TFcBool; cdecl; + FcPatternAddMatrix: function(p:PFcPattern; aobject:Pchar; s:PFcMatrix):TFcBool; cdecl; + FcPatternAddCharSet: function(p:PFcPattern; + aobject:Pchar; c:PFcCharSet):TFcBool;cdecl; + FcPatternAddBool: function(p:PFcPattern; aobject:Pchar; b:TFcBool):TFcBool; cdecl; + FcPatternAddLangSet: function(p:PFcPattern; aobject:Pchar; + ls:PFcLangSet):TFcBool;cdecl; + + FcPatternGetString: function(p: PFcPattern; aobject: Pchar; n: integer; + s: ppchar): tfcresult; cdecl; + FcPatternGetInteger: function(p: PFcPattern; aobject: Pchar; n: integer; + i: pinteger): tfcresult; cdecl; + FcPatternGetDouble: function(p: PFcPattern; aobject: Pchar; n: integer; + i: pcdouble): tfcresult; cdecl; + FcNameParse: function(name: pchar): PFcPattern; cdecl; + FcStrListNext: function(list: PFcStrList): pchar; cdecl; + FcStrListDone: procedure(list: PFcStrList); cdecl; + +procedure FcMatrixInit(var m: TFcMatrix); + +procedure initializefontconfig(const sonames: array of filenamety); +procedure releasefontconfig; + +implementation + +uses + msesys,msedynload,sysutils; +var + libinfo: dynlibinfoty; + +procedure FcMatrixInit(var m: TFcMatrix); +begin + m.xx:= 1; + m.yy:= 1; + m.xy:= 0; + m.yx:= 0; +end; + +procedure init(const data: pointer); +{$ifdef mswindows} +var + li: pfcstrlist; + bo1: boolean; + str1: string; + conf1{,conf2}: pfcconfig; +{$endif} +begin + if not fcinit() then begin + raise exception.create( + 'Fontconfig: Can not read the default configuration file.'); + end; +{$ifdef mswindows} + li:= fcconfiggetconfigfiles(nil); + bo1:= fcstrlistnext(li) = nil; + fcstrlistdone(li); + if bo1 then begin + str1:= getenvironmentvariable('FC_CONFIG_FILE'); + if str1 = '' then begin + raise exception.create( + 'Fontconfig: No configuration file defined.'+lineend+ + 'Please set environment variable FC_CONFIG_FILE.'); + end; + conf1:= fcconfiggetcurrent(); + if not fcconfigparseandload(conf1,pchar(str1),false) then begin + raise exception.create( + 'Fontconfig: Can not read config file:'+lineend+str1); + end; + end; +{$endif} + if not fcconfigbuildfonts(nil) then begin + raise exception.create( + 'Fontconfig: Can not build default fonts.'); + end; +end; + +procedure deinit(const data: pointer); +begin +// fcfini; +end; + +procedure initializefontconfig(const sonames: array of filenamety); +const + funcs: array[0..42] of funcinfoty = ( + (n: 'FcPatternDestroy'; d: {$ifndef FPC}@{$endif}@FcPatternDestroy), //0 + (n: 'FcFontSetDestroy'; d: {$ifndef FPC}@{$endif}@FcFontSetDestroy), //1 + (n: 'FcObjectSetCreate'; d: {$ifndef FPC}@{$endif}@FcObjectSetCreate), //2 + (n: 'FcObjectSetAdd'; d: {$ifndef FPC}@{$endif}@FcObjectSetAdd), //3 + (n: 'FcObjectSetDestroy'; d: {$ifndef FPC}@{$endif}@FcObjectSetDestroy), //4 + (n: 'FcFontList'; d: {$ifndef FPC}@{$endif}@FcFontList), //5 + (n: 'FcCharSetCreate'; d: {$ifndef FPC}@{$endif}@FcCharSetCreate), //6 + (n: 'FcCharSetDestroy'; d: {$ifndef FPC}@{$endif}@FcCharSetDestroy), //7 + (n: 'FcCharSetAddChar'; d: {$ifndef FPC}@{$endif}@FcCharSetAddChar), //8 + (n: 'FcPatternAdd'; d: {$ifndef FPC}@{$endif}@FcPatternAdd), //9 + (n: 'FcPatternCreate'; d: {$ifndef FPC}@{$endif}@FcPatternCreate), //10 + (n: 'FcConfigSubstitute'; d: {$ifndef FPC}@{$endif}@FcConfigSubstitute), //11 + (n: 'FcDefaultSubstitute'; d: {$ifndef FPC}@{$endif}@FcDefaultSubstitute), //12 + (n: 'FcFontSort'; d: {$ifndef FPC}@{$endif}@FcFontSort), //13 + (n: 'FcCharSetHasChar'; d: {$ifndef FPC}@{$endif}@FcCharSetHasChar), //14 + (n: 'FcPatternDuplicate'; d: {$ifndef FPC}@{$endif}@FcPatternDuplicate), //15 + (n: 'FcPatternGetCharSet'; d: {$ifndef FPC}@{$endif}@FcPatternGetCharSet), //16 + (n: 'FcFontRenderPrepare'; d: {$ifndef FPC}@{$endif}@FcFontRenderPrepare), //17 + (n: 'FcMatrixRotate'; d: {$ifndef FPC}@{$endif}@FcMatrixRotate), //18 + (n: 'FcMatrixScale'; d: {$ifndef FPC}@{$endif}@FcMatrixScale), //19 + (n: 'FcPatternAddInteger'; d: {$ifndef FPC}@{$endif}@FcPatternAddInteger), //20 + (n: 'FcPatternAddDouble'; d: {$ifndef FPC}@{$endif}@FcPatternAddDouble), //21 + (n: 'FcPatternAddString'; d: {$ifndef FPC}@{$endif}@FcPatternAddString), //22 + (n: 'FcPatternAddMatrix'; d: {$ifndef FPC}@{$endif}@FcPatternAddMatrix), //23 + (n: 'FcPatternAddCharSet'; d: {$ifndef FPC}@{$endif}@FcPatternAddCharSet), //24 + (n: 'FcPatternAddBool'; d: {$ifndef FPC}@{$endif}@FcPatternAddBool), //25 + (n: 'FcPatternAddLangSet'; d: {$ifndef FPC}@{$endif}@FcPatternAddLangSet), //26 + (n: 'FcPatternGetString'; d: {$ifndef FPC}@{$endif}@FcPatternGetString), //27 + (n: 'FcInit'; d: {$ifndef FPC}@{$endif}@FcInit), //28 + (n: 'FcFini'; d: {$ifndef FPC}@{$endif}@FcFini), //29 + (n: 'FcNameParse'; d: {$ifndef FPC}@{$endif}@FcNameParse), //30 + (n: 'FcFontMatch'; d: {$ifndef FPC}@{$endif}@FcFontMatch), //31 + (n: 'FcPatternGetInteger'; d: {$ifndef FPC}@{$endif}@FcPatternGetInteger), //32 + (n: 'FcPatternGetDouble'; d: {$ifndef FPC}@{$endif}@FcPatternGetDouble), //33 + (n: 'FcConfigFilename'; d: {$ifndef FPC}@{$endif}@FcConfigFilename), //34 + (n: 'FcConfigCreate'; d: {$ifndef FPC}@{$endif}@FcConfigCreate), //35 + (n: 'FcConfigParseAndLoad'; d: {$ifndef FPC}@{$endif}@FcConfigParseAndLoad), //36 + (n: 'FcStrListNext'; d: {$ifndef FPC}@{$endif}@FcStrListNext), //37 + (n: 'FcStrListDone'; d: {$ifndef FPC}@{$endif}@FcStrListDone), //38 + (n: 'FcConfigGetConfigFiles'; d: {$ifndef FPC}@{$endif}@FcConfigGetConfigFiles),//39 + (n: 'FcConfigGetFontDirs'; d: {$ifndef FPC}@{$endif}@FcConfigGetFontDirs), //40 + (n: 'FcConfigBuildFonts'; d: {$ifndef FPC}@{$endif}@FcConfigBuildFonts), //41 + (n: 'FcConfigGetCurrent'; d: {$ifndef FPC}@{$endif}@FcConfigGetCurrent) //42 + ); + errormessage = 'Can not load FontConfig library. '; +begin + initializedynlib(libinfo,sonames,fontconfiglib,funcs,[],errormessage,@init); +end; + +procedure releasefontconfig; +begin + releasedynlib(libinfo,@deinit); +end; + + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/graphics/msefreetype.pas b/mseide-msegui/lib/common/graphics/msefreetype.pas new file mode 100644 index 0000000..b971449 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msefreetype.pas @@ -0,0 +1,475 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + modified 2011 by Martin Schreiber + + **********************************************************************} +{$mode objfpc} {$h+} +unit msefreetype; + +{ Note that these are not all the availlable calls from the dll yet. + This unit is used by TStringBitMaps and FTFont } + +interface +uses + msetypes,sysutils,msectypes; + +const + +{$ifdef FPC} + {$packrecords c} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} + +{$ifdef mswindows} + freetypelib: array[0..2] of filenamety = + ('libfreetype-6.dll','freetype6.dll','freetype.dll'); +{$else} + freetypelib: array[0..1] of filenamety = ('libfreetype.so.6','libfreetype.so'); +{$endif} + +type + FT_Encoding = array[0..3] of char; + + efreetype = class(exception) + end; + +const + FT_FACE_FLAG_SCALABLE = 1 shl 0; + FT_FACE_FLAG_FIXED_SIZES = 1 shl 1; + FT_FACE_FLAG_FIXED_WIDTH = 1 shl 2; + FT_FACE_FLAG_SFNT = 1 shl 3; + FT_FACE_FLAG_HORIZONTAL = 1 shl 4; + FT_FACE_FLAG_VERTICAL = 1 shl 5; + FT_FACE_FLAG_KERNING = 1 shl 6; + FT_FACE_FLAG_FAST_GLYPHS = 1 shl 7; + FT_FACE_FLAG_MULTIPLE_MASTERS = 1 shl 8; + FT_FACE_FLAG_GLYPH_NAMES = 1 shl 9; + FT_FACE_FLAG_EXTERNAL_STREAM = 1 shl 10; + + FT_STYLE_FLAG_ITALIC = 1 shl 0; + FT_STYLE_FLAG_BOLD = 1 shl 1; + + FT_LOAD_DEFAULT = $0000; + FT_LOAD_NO_SCALE = $0001; + FT_LOAD_NO_HINTING = $0002; + FT_LOAD_RENDER = $0004; + FT_LOAD_NO_BITMAP = $0008; + FT_LOAD_VERTICAL_LAYOUT = $0010; + FT_LOAD_FORCE_AUTOHINT = $0020; + FT_LOAD_CROP_BITMAP = $0040; + FT_LOAD_PEDANTIC = $0080; + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH = $0200; + FT_LOAD_NO_RECURSE = $0400; + FT_LOAD_IGNORE_TRANSFORM = $0800; + FT_LOAD_MONOCHROME = $1000; + FT_LOAD_LINEAR_DESIGN = $2000; + + ft_glyph_format_none = $00000000; + ft_glyph_format_composite = $636F6D70; //comp 099 111 109 112 + ft_glyph_format_bitmap = $62697473; //bits 098 105 116 115 + ft_glyph_format_outline = $6F75746C; //outl 111 117 116 108 + ft_glyph_format_plotter = $706C6F74; //plot 112 108 111 116 + + FT_ENCODING_MS_SYMBOL : FT_Encoding = 'symb'; + FT_ENCODING_UNICODE : FT_Encoding = 'unic'; + FT_ENCODING_MS_SJIS : FT_Encoding = 'sjis'; + FT_ENCODING_MS_GB2312 : FT_Encoding = 'gb '; + FT_ENCODING_MS_BIG5 : FT_Encoding = 'big5'; + FT_ENCODING_MS_WANSUNG : FT_Encoding = 'wans'; + FT_ENCODING_MS_JOHAB : FT_Encoding = 'joha'; + FT_ENCODING_ADOBE_STANDARD : FT_Encoding = 'ADOB'; + FT_ENCODING_ADOBE_EXPERT : FT_Encoding = 'ADBE'; + FT_ENCODING_ADOBE_CUSTOM : FT_Encoding = 'ADBC'; + FT_ENCODING_ADOBE_LATIN_1 : FT_Encoding = 'lat1'; + FT_ENCODING_OLD_LATIN_2 : FT_Encoding = 'lat2'; + FT_ENCODING_APPLE_ROMAN : FT_Encoding = 'armn'; + + ft_glyph_bbox_unscaled = 0; //* return unscaled font units */ + ft_glyph_bbox_subpixels = 0; //* return unfitted 26.6 coordinates */ + ft_glyph_bbox_gridfit = 1; //* return grid-fitted 26.6 coordinates */ + ft_glyph_bbox_truncate = 2; //* return coordinates in integer pixels */ + ft_glyph_bbox_pixels = 3; //* return grid-fitted pixel coordinates */ + + FT_KERNING_DEFAULT = 0; + FT_KERNING_UNFITTED = 1; + FT_KERNING_UNSCALED = 2; + + +type + + FT_Bool = cuchar; + FT_FWord = cshort; + FT_UFWord = cushort; + FT_Char = cchar; + FT_Byte = cuchar; + FT_Bytes = ^FT_Byte; + FT_String = cchar; + FT_Short = cshort; + FT_UShort = cushort; + FT_Int = cint; + FT_UInt = cuint; + FT_Long = clong; + FT_ULong = culong; + FT_Pos = clong; + FT_F2Dot14 = cshort; + FT_F26Dot6 = clong; + FT_Fixed = clong; + FT_Error = cint; + FT_Pointer = pointer; + //FT_Offset = size_t; + //FT_PtrDist = size_t; + + FT_Render_Mode = (FT_RENDER_MODE_NORMAL, FT_RENDER_MODE_LIGHT, + FT_RENDER_MODE_MONO, FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V, + FT_RENDER_MODE_MAX); + + FT_UnitVector_ = record + x : FT_F2Dot14; + y : FT_F2Dot14; + end; + FT_UnitVector = FT_UnitVector_; + + FT_Matrix = record + xx : FT_Fixed; + xy : FT_Fixed; + yx : FT_Fixed; + yy : FT_Fixed; + end; + PFT_Matrix = ^FT_Matrix; + + FT_Data = record + pointer : ^FT_Byte; + length : FT_Int; + end; + + FT_Generic_Finalizer = procedure (AnObject:pointer);cdecl; + + FT_Generic = record + data : pointer; + finalizer : FT_Generic_Finalizer; + end; + + FT_Glyph_Metrics = record + width : FT_Pos; + height : FT_Pos; + horiBearingX : FT_Pos; + horiBearingY : FT_Pos; + horiAdvance : FT_Pos; + vertBearingX : FT_Pos; + vertBearingY : FT_Pos; + vertAdvance : FT_Pos; + end; + + FT_Bitmap_Size = record + height : FT_Short; + width : FT_Short; + end; + AFT_Bitmap_Size = array [0..1023] of FT_Bitmap_Size; + PFT_Bitmap_Size = ^AFT_Bitmap_Size; + + FT_Vector = record + x : FT_Pos; + y : FT_Pos; + end; + PFT_Vector = ^FT_Vector; + + FT_BBox = record + xMin, yMin : FT_Pos; + xMax, yMax : FT_Pos; + end; + PFT_BBox = ^FT_BBox; + + FT_Bitmap = record + rows : cint; + width : cint; + pitch : cint; + buffer : pointer; + num_grays : ft_short; + pixel_mode : cchar; + palette_mode : cchar; + palette : pointer; + end; + + FT_Outline = record + n_contours, + n_points : smallint; + points : PFT_Vector; + tags : pchar; + contours : ^smallint; + flags : integer; + end; + PFT_Outline = ^FT_Outline; + + FT_Outline_MoveToFunc = function(const to_: PFT_Vector; user: Pointer): integer; + FT_Outline_LineToFunc = function(const to_: PFT_Vector; user: Pointer): integer; + FT_Outline_ConicToFunc = function(const control, to_: PFT_Vector; user: Pointer): integer; + FT_Outline_CubicToFunc = function(const control1, control2, to_: PFT_Vector; user: Pointer): integer; + + FT_Outline_Funcs = record + move_to: FT_Outline_MoveToFunc; + line_to: FT_Outline_LineToFunc; + conic_to: FT_Outline_ConicToFunc; + cubic_to: FT_Outline_CubicToFunc; + shift: integer; + delta: FT_Pos; + end; + PFT_Outline_Funcs = ^FT_Outline_Funcs; + + FT_Size_Metrics = record + x_ppem : FT_UShort; + y_ppem : FT_UShort; + x_scale : FT_Fixed; + y_scale : FT_Fixed; + ascender : FT_Pos; + descender : FT_Pos; + height : FT_Pos; + max_advance : FT_Pos; + end; + + + PFT_Library = ^TFT_Library; + //PPFT_Library = ^PFT_Library; + PFT_Face = ^TFT_Face; + //PPFT_Face = ^PFT_Face; + PFT_Charmap = ^TFT_Charmap; + PPFT_Charmap = ^PFT_Charmap; + PFT_GlyphSlot = ^TFT_GlyphSlot; + PFT_Subglyph = ^TFT_Subglyph; + PFT_Size = ^TFT_Size; + + PFT_Glyph = ^TFT_Glyph; + //PPFT_Glyph = ^PFT_Glyph; + PFT_BitmapGlyph = ^TFT_BitmapGlyph; + PFT_OutlineGlyph = ^TFT_OutlineGlyph; + + + TFT_Library = record + end; + + TFT_Charmap = record + face : PFT_Face; + encoding : FT_Encoding; + platform_id, encoding_id : FT_UShort; + end; + + TFT_Size = record + face : PFT_Face; + generic : FT_Generic; + metrics : FT_Size_Metrics; + //internal : FT_Size_Internal; + end; + + TFT_Subglyph = record // TODO + end; + + TFT_GlyphSlot = record + alibrary : PFT_Library; + face : PFT_Face; + next : PFT_GlyphSlot; + flags : FT_UInt; + generic : FT_Generic; + metrics : FT_Glyph_Metrics; + linearHoriAdvance : FT_Fixed; + linearVertAdvance : FT_Fixed; + advance : FT_Vector; + format : longword; + bitmap : FT_Bitmap; + bitmap_left : FT_Int; + bitmap_top : FT_Int; + outline : FT_Outline; + num_subglyphs : FT_UInt; + subglyphs : PFT_SubGlyph; + control_data : pointer; + control_len : longint; + other : pointer; + end; + + TFT_Face = record + num_faces : FT_Long; + face_index : FT_Long; + face_flags : FT_Long; + style_flags : FT_Long; + num_glyphs : FT_Long; + family_name : pchar; + style_name : pchar; + num_fixed_sizes : FT_Int; + available_sizes : PFT_Bitmap_Size; // is array + num_charmaps : FT_Int; + charmaps : PPFT_CharMap; // is array + generic : FT_Generic; + bbox : FT_BBox; + units_per_EM : FT_UShort; + ascender : FT_Short; + descender : FT_Short; + height : FT_Short; + max_advance_width : FT_Short; + max_advance_height : FT_Short; + underline_position : FT_Short; + underline_thickness : FT_Short; + glyph : PFT_GlyphSlot; + size : PFT_Size; + charmap : PFT_CharMap; + end; + + TFT_Glyph = record + FTlibrary : PFT_Library; + clazz : pointer; + aFormat : longword; + advance : FT_Vector; + end; + + TFT_BitmapGlyph = record + root : TFT_Glyph; + left, top : FT_Int; + bitmap : FT_Bitmap; + end; + + TFT_OutlineGlyph = record + root : TFT_Glyph; + outline : FT_Outline; + end; + + function FT_IS_SCALABLE(face: PFT_Face): boolean; + +var + ftlib: pft_library; +//Base Interface + FT_Done_Face: function(face: PFT_Face): integer; cdecl; + FT_Done_FreeType: function(alibrary: PFT_Library): integer; cdecl; + FT_Get_Char_Index: function(face: PFT_Face; charcode: FT_ULong): FT_UInt; cdecl; + FT_Get_Kerning: function(face: PFT_Face; left_glyph, right_glyph, + kern_mode: FT_UInt; out akerning: FT_Vector): integer; cdecl; + FT_Init_FreeType: function(var alibrary: PFT_Library): integer; cdecl; + FT_Load_Char: function(face: PFT_Face; charcode: FT_ULong; + load_flags: longint): integer; cdecl; + FT_Load_Glyph: function(face: PFT_Face; glyph_index: FT_UInt; + load_flags: longint): integer; cdecl; + FT_Render_Glyph: function(slot: PFT_GlyphSlot; + render_mode: FT_Render_Mode): integer; cdecl; + FT_New_Face: function(alibrary: PFT_Library; filepathname: PChar; + face_index: integer; var aface: PFT_Face): integer; cdecl; + FT_Set_Char_Size: function(face: PFT_Face; char_width, char_height: FT_F26dot6; + horz_res, vert_res: FT_UInt): integer; cdecl; + FT_Set_Pixel_Sizes: function(face: PFT_Face; + pixel_width, pixel_height: FT_UInt): integer; cdecl; + FT_Set_Transform: procedure(face: PFT_Face; matrix: PFT_Matrix; + delta: PFT_Vector); cdecl; + +//Outline Processing + FT_Outline_Decompose: function(outline: PFT_Outline; + const func_interface: PFT_Outline_Funcs; user: Pointer): integer; cdecl; + +//FreeType Version + FT_Library_Version: procedure(alibrary: PFT_Library; + var amajor, aminor, apatch: integer); cdecl; + +//Glyph Management + FT_Get_Glyph: function(slot: PFT_GlyphSlot; + out aglyph: PFT_Glyph): integer; cdecl; + FT_Glyph_Copy: function(Source: PFT_Glyph; + out target: PFT_Glyph): integer; cdecl; + FT_Glyph_To_Bitmap: function(var the_glyph: PFT_Glyph; + render_mode: FT_Render_Mode; origin: PFT_Vector; + Destroy: FT_Bool): integer; cdecl; + FT_Glyph_Transform: function(glyph: PFT_Glyph; matrix: PFT_Matrix; + delta: PFT_Vector): integer; cdecl; + FT_Done_Glyph: procedure(glyph: PFT_Glyph); cdecl; + FT_Glyph_Get_CBox: procedure(glyph: PFT_Glyph; bbox_mode: FT_UInt; + var acbox: FT_BBox); cdecl; + +procedure initializefreetype(const sonames: array of filenamety); +procedure releasefreetype; +procedure ftcheckerror(const aerror: ft_error; const amessage: msestring = ''); +function ftpostopixel(const apos: ft_pos): integer; inline; + +implementation + +uses + msesys,msedynload; +var + libinfo: dynlibinfoty; +const + ftposshift = 6; + ftposscale = 64; //2^6 + ftposhalf = (1 shl ftposshift) div 2; + +function ftpostopixel(const apos: ft_pos): integer; inline; +begin + result:= (apos + ftposhalf) div ftposscale; +end; + +function FT_IS_SCALABLE(face: PFT_Face): boolean; +begin + Result := (face^.face_flags and FT_FACE_FLAG_SCALABLE) = 1; +end; + +procedure ftcheckerror(const aerror: integer; const amessage: msestring); +begin + if aerror <> 0 then begin + raise efreetype.create('Freetype error '+inttostr(aerror)+':'+lineend+ + ansistring(amessage)); + end; +end; + +procedure initft(const data: pointer); +begin + ftcheckerror(ft_init_freetype(ftlib),'Init freetype library.'); +end; + +procedure deinitft(const data: pointer); +begin + ftcheckerror(ft_done_freetype(ftlib),'Deinit freetype library.'); + ftlib:= nil; +end; + +procedure initializefreetype(const sonames: array of filenamety); +const + funcs: array[0..19] of funcinfoty = ( + (n: 'FT_Done_Face'; d: @FT_Done_Face), //0 + (n: 'FT_Done_FreeType'; d: @FT_Done_FreeType), //1 + (n: 'FT_Get_Char_Index'; d: @FT_Get_Char_Index), //2 + (n: 'FT_Get_Kerning'; d: @FT_Get_Kerning), //3 + (n: 'FT_Init_FreeType'; d: @FT_Init_FreeType), //4 + (n: 'FT_Load_Char'; d: @FT_Load_Char), //5 + (n: 'FT_Load_Glyph'; d: @FT_Load_Glyph), //6 + (n: 'FT_New_Face'; d: @FT_New_Face), //7 + (n: 'FT_Set_Char_Size'; d: @FT_Set_Char_Size), //8 + (n: 'FT_Set_Pixel_Sizes'; d: @FT_Set_Pixel_Sizes), //9 + (n: 'FT_Set_Transform'; d: @FT_Set_Transform), //10 + (n: 'FT_Outline_Decompose'; d: @FT_Outline_Decompose),//11 + (n: 'FT_Library_Version'; d: @FT_Library_Version), //12 + (n: 'FT_Get_Glyph'; d: @FT_Get_Glyph), //13 + (n: 'FT_Glyph_Copy'; d: @FT_Glyph_Copy), //14 + (n: 'FT_Glyph_To_Bitmap'; d: @FT_Glyph_To_Bitmap), //15 + (n: 'FT_Glyph_Transform'; d: @FT_Glyph_Transform), //16 + (n: 'FT_Done_Glyph'; d: @FT_Done_Glyph), //17 + (n: 'FT_Glyph_Get_CBox'; d: @FT_Glyph_Get_CBox), //18 + (n: 'FT_Render_Glyph'; d: @FT_Render_Glyph) //19 + ); + errormessage = 'Can not load Freetype library. '; +begin + initializedynlib(libinfo,sonames,freetypelib,funcs,[],errormessage,@initft); +end; + +procedure releasefreetype; +begin + releasedynlib(libinfo,@deinitft); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/graphics/mseftfontcache.pas b/mseide-msegui/lib/common/graphics/mseftfontcache.pas new file mode 100644 index 0000000..f082726 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/mseftfontcache.pas @@ -0,0 +1,438 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +// +//under construction +// +unit mseftfontcache; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +//todo: limit buffer size + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msefontcache,msegraphics,msestrings,msetypes,mseguiglob,msegraphutils,msehash; + +type + bitmapdataty = record + width: smallint; + height: smallint; + left: smallint; + top: smallint; + data: record + end; + end; + pbitmapdataty= ^bitmapdataty; + + tftfontcache = class(tfontcache) + protected + procedure internalfreefont(const afont: ptruint); override; + function internalgetfont(const ainfo: getfontinfoty; + out aheight: integer): boolean; override; + procedure updatefontinfo(const adataoffset: hashoffsetty; + var adata: fontcachedataty); override; + procedure drawglyph(var drawinfo: drawinfoty; const pos: pointty; + const bitmap: pbitmapdataty); virtual; abstract; + function getdataoffsfont(const afont: fontty): hashoffsetty; override; + function textbackgroundrect(const drawinfo: drawinfoty; + const afont: fontty; out arect: rectty): boolean; + public + constructor create(var ainstance: tftfontcache); + destructor destroy; override; + procedure gettext16width(var drawinfo: drawinfoty); override; + procedure getchar16widths(var drawinfo: drawinfoty); override; + procedure getfontmetrics(var drawinfo: drawinfoty); override; + procedure drawstring16(var drawinfo: drawinfoty; + const afont: fontty); override; + end; + +implementation +uses + msefreetype,msefontconfig,msefcfontselect,math; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + charcount = $10000; //UCS2 + bucketshift = 9; //charrowlength = 128 + charbucketcount = 1 shl bucketshift; + charrowlength = charcount div charbucketcount; + charrowmask = charrowlength - 1; + +type + glyphinfoty = record + width: smallint; + leftbearing: smallint; + rightbearing: smallint; + bitmap: longword; //buffer offset to bitmapdatatyty 0->not rendered yet + end; + + pglyphinfoty = ^glyphinfoty; + charrowty = array[0..charrowlength-1] of longword; //offset in buffer + pcharrowty = ^charrowty; + charbucketty = array[0..charbucketcount-1] of longword; + //offset to charrowty in buffer + tftface = class + private + fface: pft_face; + fbuckets: charbucketty; + fbuffer: pointer; + fsize: longword; + fcapacity: longword; + protected + fdataoffset: hashoffsetty; + fascent: integer; + fdescent: integer; + fglyphheight: integer; + flinespacing: integer; + function getbuffer(const asize: integer; const ainit: boolean): longword; + public + constructor create(const aface: pft_face); + destructor destroy; override; + function getglyph(const achar: msechar; out ainfo: pglyphinfoty; + const forceload: boolean): boolean; + //true if found + procedure renderglyph(var ainfo: pglyphinfoty); + end; + +{ tftfontcache } + +constructor tftfontcache.create(var ainstance: tftfontcache); +begin + initializefreetype([]); + initializefontconfig([]); + inherited create(tfontcache(ainstance)); +end; + +destructor tftfontcache.destroy; +begin + inherited; + releasefreetype; + releasefontconfig; +end; + +procedure tftfontcache.internalfreefont(const afont: ptruint); +begin + tftface(pointer(afont)).free; +end; + +function tftfontcache.internalgetfont(const ainfo: getfontinfoty; + out aheight: integer): boolean; +var + ftface: pft_face; + str1: string; + int1: integer; +begin + result:= false; + with ainfo do begin + if getfcfontfile(ainfo,str1,int1,aheight) then begin + if ft_new_face(ftlib,pchar(str1),int1,ftface) = 0 then begin + if ft_set_pixel_sizes(ftface,0,aheight) = 0 then begin + pointer(fontdata^.font):= tftface.create(ftface); + result:= true; + end; + end; + end; + end; +end; + +procedure tftfontcache.updatefontinfo(const adataoffset: hashoffsetty; + var adata: fontcachedataty); +var + scale: real; +begin + with tftface(pointer(adata.font)),fface^ do begin + fdataoffset:= adataoffset; + scale:= adata.height/units_per_em; + fascent:= round(ascender*scale); + fdescent:= -round(descender*scale); + fglyphheight:= fascent+fdescent; + flinespacing:= ceil(height*scale); + adata.ascent:= fascent; + adata.descent:= fdescent; + adata.height:= fglyphheight; + adata.linespacing:= flinespacing; + adata.caretshift:= 0; + end; +end; + +procedure tftfontcache.gettext16width(var drawinfo: drawinfoty); +var + po1: pmsecharaty; + po3: pglyphinfoty; + face1: tftface; + int1,int2: integer; +begin + with drawinfo.gettext16width do begin + face1:= tftface(pointer(fontdata^.font)); + po1:= pointer(text); + face1:= tftface(pointer(fontdata^.font)); + int2:= 0; + for int1:= count-1 downto 0 do begin + if face1.getglyph(po1^[int1],po3,false) then begin + int2:= int2 + po3^.width; + end + end; + result:= int2; + end; +end; + +procedure tftfontcache.getchar16widths(var drawinfo: drawinfoty); +var + int1: integer; + po1: pmsecharaty; + po2: pintegeraty; + po3: pglyphinfoty; + face1: tftface; +begin + with drawinfo.getchar16widths do begin + face1:= tftface(pointer(fontdata^.font)); + po1:= pointer(text); + po2:= pointer(resultpo); + for int1:= count-1 downto 0 do begin + if face1.getglyph(po1^[int1],po3,false) then begin + po2^[int1]:= po3^.width; + end + else begin + po2^[int1]:= 0; + end; + end; + end; +end; + +procedure tftfontcache.getfontmetrics(var drawinfo: drawinfoty); +var + face: tftface; + po1: pglyphinfoty; +begin + with drawinfo.getfontmetrics do begin + face:= tftface(pointer(fontdata^.font)); + if face.getglyph(msechar(char),po1,false) then begin //todo: 32bit + with resultpo^ do begin + width:= po1^.width; + leftbearing:= po1^.leftbearing; + rightbearing:= po1^.rightbearing; //correct??? + end; + end + else begin + with resultpo^ do begin + width:= 0; + leftbearing:= 0; + rightbearing:= 0; + end; + end; + end; +end; + +function tftfontcache.textbackgroundrect(const drawinfo: drawinfoty; + const afont: fontty; out arect: rectty): boolean; + +var + face: tftface; + po1: pglyphinfoty; + po2: pmsecharaty; + int1,int2: integer; +begin + result:= false; + with drawinfo,text16pos do begin + if count = 0 then begin + arect:= nullrect; + exit; + end; + face:= tftface(pointer(afont)); + po2:= pointer(text); + if face.getglyph(po2^[0],po1,false) then begin + with arect do begin + x:= text16pos.pos^.x {+ po1^.leftbearing}; + int2:= po1^.width {- po1^.leftbearing}; + for int1:= 1 to count - 1 do begin + if face.getglyph(po2^[int1],po1,false) then begin + int2:= int2+po1^.width; + end; + end; + cx:= int2 {+ po1^.rightbearing}; + y:= text16pos.pos^.y - face.fascent; + cy:= face.fglyphheight; + end; + result:= true; + end; + end; +end; + +procedure tftfontcache.drawstring16(var drawinfo: drawinfoty; + const afont: fontty); +var + face: tftface; + po1: pglyphinfoty; + po2: pmsecharaty; + po3: pbitmapdataty; + int1: integer; +// rect1: rectty; + pt1: pointty; + y1: integer; +begin + with drawinfo,text16pos do begin + if count = 0 then begin + exit; + end; + pt1.x:= pos^.x + origin.x; + y1:= pos^.y + origin.y - 1; + face:= tftface(pointer(afont)); + po2:= pointer(text); + for int1:= 0 to count-1 do begin + if face.getglyph(po2^[int1],po1,true) then begin + if po1^.bitmap = 0 then begin + face.renderglyph(po1); + end; + if po1^.bitmap <> 0 then begin //render error otherwise + po3:= pointer(pchar(face.fbuffer)+po1^.bitmap); + pt1.x:= pt1.x + po3^.left; + pt1.y:= y1 - po3^.top; + drawglyph(drawinfo,pt1,po3); + end; + pt1.x:= pt1.x - po3^.left + po1^.width; + end; + end; + end; +end; + +function tftfontcache.getdataoffsfont(const afont: fontty): hashoffsetty; +begin + result:= tftface(pointer(afont)).fdataoffset; +end; + +{ tftface } + +constructor tftface.create(const aface: pft_face); +begin + fface:= aface; + fsize:= sizeof(longword); //dummy + fcapacity:= 1024; + getmem(fbuffer,fcapacity); +end; + +destructor tftface.destroy; +begin + inherited; + freemem(fbuffer); + ft_done_face(fface); +end; + +function tftface.getbuffer(const asize: integer; + const ainit: boolean): longword; +begin + result:= fsize; + fsize:= (fsize + asize + 3) and not 3; //4 byte align + if fsize > fcapacity then begin + fcapacity:= fcapacity * 2 - fcapacity div 2; //* 1.5 + reallocmem(fbuffer,fcapacity); + end; + if ainit then begin + fillchar((pchar(fbuffer)+result)^,asize,0); + end; +end; + +procedure tftface.renderglyph(var ainfo: pglyphinfoty); + //must be called after getglyph +var + po1: pchar; + so,de: pbyteaty; + int1,int2,int3: integer; + bm1: pbitmapdataty; +begin + if ft_render_glyph(fface^.glyph,ft_render_mode_normal) = 0 then begin + with fface^.glyph^,bitmap do begin +//todo: check bitmap format + po1:= fbuffer; + int3:= getbuffer(sizeof(bitmapdataty) + width * rows,false); + ainfo:= pointer(pchar(ainfo) + + (pchar(fbuffer) - pchar(po1))); + ainfo^.bitmap:= int3; + bm1:= pointer(pchar(fbuffer)+int3); + bm1^.width:= width; + bm1^.height:= rows; + bm1^.left:= bitmap_left; + bm1^.top:= bitmap_top-rows; + de:= @bm1^.data; + if pitch < 0 then begin + so:= buffer; + end + else begin + so:= pointer(pchar(buffer)+(rows-1)*pitch); + end; + for int1:= rows - 1 downto 0 do begin + for int2:= width-1 downto 0 do begin + de[int2]:= so[int2]; + end; + de:= pointer(pchar(de)+width); + so:= pointer(pchar(so)-pitch); + end; + end; + end +end; + //todo: 32bit +function tftface.getglyph(const achar: msechar; out ainfo: pglyphinfoty; + const forceload: boolean): boolean; +var + int1,int2,int3: integer; + po1: pcharrowty; +begin + result:= true; + int1:= word(achar) shr bucketshift; + int2:= word(achar) and charrowmask; + if fbuckets[int1] = 0 then begin + fbuckets[int1]:= getbuffer(sizeof(charrowty),true); + end; + po1:= pcharrowty(pchar(fbuffer)+fbuckets[int1]); + int3:= po1^[int2]; + if int3 = 0 then begin + if ft_load_glyph(fface,ft_get_char_index(fface,ord(achar)), + ft_load_default) = 0 then begin + int3:= getbuffer(sizeof(glyphinfoty),false); + po1^[int2]:= int3; + ainfo:= pglyphinfoty(pchar(fbuffer)+int3); + with fface^.glyph^ do begin + ainfo^.width:= ftpostopixel(advance.x); + ainfo^.leftbearing:= ftpostopixel(metrics.horibearingx); + ainfo^.rightbearing:= ftpostopixel(metrics.horiadvance-metrics.width); + end; + ainfo^.bitmap:= 0; //not rendered yet + end + else begin + ainfo:= nil; + result:= false; + end; + end + else begin + if forceload then begin + if ft_load_glyph(fface,ft_get_char_index(fface,ord(achar)), + ft_load_default) <> 0 then begin + result:= false; + end; + end; + ainfo:= pglyphinfoty(pchar(fbuffer)+int3); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/mseftglyphs.pas b/mseide-msegui/lib/common/graphics/mseftglyphs.pas new file mode 100644 index 0000000..3587d41 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/mseftglyphs.pas @@ -0,0 +1,287 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseftglyphs; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +uses + msefreetype,msestrings,msebitmap,msetypes,msegraphutils; + +type + tftglyphs = class + private + fftface: pft_face; + procedure setheight(const avalue: int32); + protected + fheight: int32; + fascent: int32; + fascent64: int32; + fdescent: int32; + fglyphheight: int32; + flinespacing: int32; + function internalgetglyph(const abitmap: tmaskedbitmap; + const achar: card32; const arot: real; + const aframe: framety; const acolor: colorty; + const acell: boolean): boolean; + public + constructor create(const afontfile: filenamety; const afontindex: int32; + const aheight: int32); //pixels + destructor destroy(); override; + + function getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + function getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const aframe: framety; //padding + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + function getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const arotation: real; //0.0..1.0 -> 0..360deg CCW + const aframe: framety; //padding + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + function getcell(const abitmap: tmaskedbitmap; const achar: card32; + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + function getcell(const abitmap: tmaskedbitmap; const achar: card32; + const aframe: framety; //padding + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + function getcell(const abitmap: tmaskedbitmap; const achar: card32; + const arotation: real; //0.0..1.0 -> 0..360deg CCW + const aframe: framety; //padding + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + property height: int32 read fheight write setheight; + property ascent: int32 read fascent; + property descent: int32 read fdescent; + property glyphheight: int32 read fglyphheight; + property linespacing: int32 read flinespacing; + end; + +implementation +uses + msefileutils,sysutils,math; + +{ tftglyphs } + +constructor tftglyphs.create(const afontfile: filenamety; + const afontindex: int32; const aheight: int32); +begin + initializefreetype([]); + if ft_new_face(ftlib,pchar(ansistring(tosysfilepath(afontfile))), + afontindex,fftface) = 0 then begin + fheight:= -1; //force loading of 0 + height:= aheight; + end + else begin + raise exception.create('Can not load font "'+ansistring(afontfile)+'"'); + end; +end; + +procedure tftglyphs.setheight(const avalue: int32); +var + scale: real; +begin + if fheight <> avalue then begin + fheight:= avalue; + if ft_set_pixel_sizes(fftface,0,avalue) <> 0 then begin + raise exception.create('Can not set font height '+inttostr(fheight)); + end; + with fftface^ do begin + scale:= fheight/units_per_em; + fascent64:= round(ascender*scale*64); //for transformation matrix + fascent:= (fascent64 + 32) div 64; //pixels + fdescent:= -round(descender*scale); + fglyphheight:= fascent+fdescent; + flinespacing:= ceil(height*scale); + end; + end; +end; + +destructor tftglyphs.destroy(); +begin + if fftface <> nil then begin + ft_done_face(fftface); + end; + releasefreetype(); +end; + +function tftglyphs.internalgetglyph(const abitmap: tmaskedbitmap; + const achar: card32; const arot: real; const aframe: framety; + const acolor: colorty; const acell: boolean): boolean; +const + numscale = $10000; //for 16.16 ft number +var + so,de: pbyte; + i1,i2,step: int32; + sourcestart: pointty; + sourcesize: sizety; + destsize: sizety; + deststart: pointty; + mat1: ft_matrix; + vec1: ft_vector; + rea1: real; + fcos1,fsin1: real; + cos1,sin1: int32; + charindex1: int32; + centre1: pointty; +label + endlab; +begin + result:= false; + abitmap.beginupdate(); + abitmap.clear(); + charindex1:= ft_get_char_index(fftface,ord(achar)); + if arot <> 0 then begin + rea1:= 2*pi*arot; + fcos1:= cos(rea1); + fsin1:= sin(rea1); + cos1:= round(fcos1*numscale); + sin1:= round(fsin1*numscale); + mat1.xx:= cos1; + mat1.xy:= -sin1; + mat1.yx:= sin1; + mat1.yy:= cos1; + if acell then begin + ft_set_transform(fftface,nil,nil); + if ft_load_glyph(fftface,charindex1,ft_load_default) <> 0 then begin + goto endlab; + end; + with fftface^.glyph^.metrics do begin +// centre1.x:= width div 2 - horibearingx; + centre1.x:= horiadvance div 2; +// centre1.y:= horibearingy - height div 2 ; + centre1.y:= fascent64 - fheight * 32; + vec1.x:= -round(centre1.x*fcos1 - centre1.y*fsin1) + centre1.x; + vec1.y:= -round(centre1.x*fsin1 + centre1.y*fcos1) + centre1.y; + end; + ft_set_transform(fftface,@mat1,@vec1); + end + else begin + ft_set_transform(fftface,@mat1,nil); + end; + end + else begin + ft_set_transform(fftface,nil,nil); + end; + if ft_load_glyph(fftface,charindex1,ft_load_default) = 0 then begin + if ft_render_glyph(fftface^.glyph,ft_render_mode_normal) = 0 then begin + abitmap.options:= abitmap.options + [bmo_masked,bmo_graymask]; + with fftface^.glyph^.bitmap do begin //todo: check bitmap format + if (width > 0) and (rows > 0) then begin + sourcesize.cx:= width; + sourcesize.cy:= rows; + if acell then begin +// destsize.cx:= (fftface^.glyph^.advance.x + 32) div 64; + with fftface^.glyph^.metrics do begin + destsize.cx:= (horiadvance + 32) div 64; + end; + destsize.cy:= fglyphheight; + deststart.x:= aframe.left + fftface^.glyph^.bitmap_left; + deststart.y:= aframe.top + fascent - fftface^.glyph^.bitmap_top; + end + else begin + destsize:= sourcesize; + deststart:= pointty(aframe.topleft); + end; + destsize.cx:= destsize.cx + aframe.left + aframe.right; + destsize.cy:= destsize.cy + aframe.top + aframe.bottom; + if (destsize.cx > 0) and (destsize.cx > 0) and + (deststart.x < destsize.cx) and + (deststart.y < destsize.cy) then begin + abitmap.size:= destsize; + sourcestart.x:= 0; + if deststart.x < 0 then begin + sourcestart.x:= -deststart.x; + sourcesize.cx:= sourcesize.cx + deststart.x; + deststart.x:= 0; + end; + sourcestart.y:= 0; + if deststart.y < 0 then begin + sourcestart.y:= -deststart.y; + sourcesize.cy:= sourcesize.cy + deststart.y; + deststart.y:= 0; + end; + if deststart.x + sourcesize.cx > destsize.cx then begin + sourcesize.cx:= destsize.cx - deststart.x; + end; + if deststart.y + sourcesize.cy > destsize.cy then begin + sourcesize.cy:= destsize.cy - deststart.y; + end; + abitmap.size:= destsize; + abitmap.mask.init(0); + de:= abitmap.mask.scanline[deststart.y] + deststart.x; + abitmap.init(acolor); + if pitch < 0 then begin + so:= buffer+(rows-1-sourcestart.y)*pitch; + end + else begin + so:= buffer+sourcestart.y*pitch; + end; + so:= so + sourcestart.x; + step:= abitmap.mask.scanlinestep; + for i1:= sourcesize.cy - 1 downto 0 do begin + for i2:= sourcesize.cx-1 downto 0 do begin + de[i2]:= so[i2]; + end; + so:= so + pitch; + de:= de + step; + end; + end; + end; + end; + result:= true; + end; + end; +endlab: + abitmap.endupdate(); +end; + +function tftglyphs.getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,0.0,nullframe,acolor,false); +end; + +function tftglyphs.getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const aframe: framety; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,0.0,aframe,acolor,false); +end; + +function tftglyphs.getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const arotation: real; const aframe: framety; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,arotation,aframe,acolor,false); +end; + +function tftglyphs.getcell(const abitmap: tmaskedbitmap; const achar: card32; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,0.0,nullframe,acolor,true); +end; + +function tftglyphs.getcell(const abitmap: tmaskedbitmap; const achar: card32; + const aframe: framety; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,0.0,aframe,acolor,true); +end; + +function tftglyphs.getcell(const abitmap: tmaskedbitmap; const achar: card32; + const arotation: real; const aframe: framety; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,arotation,aframe,acolor,true); +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msegdi32gdi.pas b/mseide-msegui/lib/common/graphics/msegdi32gdi.pas new file mode 100644 index 0000000..4d6f14e --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msegdi32gdi.pas @@ -0,0 +1,3375 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegdi32gdi; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$goto on} +interface +uses + msegraphics,msetypes,windows,msestrings,mseguiglob; + +procedure init; +procedure deinit; + +function gdi32getgdifuncs: pgdifunctionaty; +//function gdi32getgdinum: integer; +procedure gdi32initdefaultfont; +function gdi32getdefaultfontnames: defaultfontnamesty; +//function gdi32creategc(paintdevice: paintdevicety; const akind: gckindty; +// var gc: gcty; const aprintername: msestring): guierrorty; + +{$ifdef FPC} +function GetNextWindow(hWnd: HWND; uCmd: UINT): HWND; stdcall; + external user32 name 'GetWindow'; +function CreateRectRgnIndirect(const _para1:tRECT):HRGN; stdcall; + external gdi32 name 'CreateRectRgnIndirect'; +function winFillRect(hDC:HDC; const lprc:tRECT; hbr:HBRUSH):longint; stdcall; + external user32 name 'FillRect'; + +type + tTEXTMETRICW = record + tmHeight: Longint; + tmAscent: Longint; + tmDescent: Longint; + tmInternalLeading: Longint; + tmExternalLeading: Longint; + tmAveCharWidth: Longint; + tmMaxCharWidth: Longint; + tmWeight: Longint; + tmOverhang: Longint; + tmDigitizedAspectX: Longint; + tmDigitizedAspectY: Longint; + tmFirstChar: WideChar; + tmLastChar: WideChar; + tmDefaultChar: WideChar; + tmBreakChar: WideChar; + tmItalic: Byte; + tmUnderlined: Byte; + tmStruckOut: Byte; + tmPitchAndFamily: Byte; + tmCharSet: Byte; + end; + tTEXTMETRICA = record + tmHeight: Longint; + tmAscent: Longint; + tmDescent: Longint; + tmInternalLeading: Longint; + tmExternalLeading: Longint; + tmAveCharWidth: Longint; + tmMaxCharWidth: Longint; + tmWeight: Longint; + tmOverhang: Longint; + tmDigitizedAspectX: Longint; + tmDigitizedAspectY: Longint; + tmFirstChar: Char; + tmLastChar: Char; + tmDefaultChar: Char; + tmBreakChar: Char; + tmItalic: Byte; + tmUnderlined: Byte; + tmStruckOut: Byte; + tmPitchAndFamily: Byte; + tmCharSet: Byte; + end; + + tGCPRESULTSW = record + lStructSize : DWORD; + lpOutString : pwidechar; + lpOrder : ^UINT; + lpDx : ^WINT; + lpCaretPos : ^WINT; + lpClass : pwidechar; + lpGlyphs : ^UINT; + nGlyphs : UINT; + nMaxFit : UINT; + end; +{$else} +function GetCharacterPlacementW(DC: HDC; p2: PWideChar; p3, p4: Integer; + var p5: TGCPResultsw; p6: DWORD): DWORD; stdcall; + external gdi32 name 'GetCharacterPlacementW'; +type + WINT = longint; +{$endif} + +const + rasterops2: array[rasteropty] of byte = + ($01,$09,$05,$0d, + $03,$0b,$07,$0f, + $02,$0a,$06,$0e, + $04,$0c,$08,$10); + +{ inverse mono bitmap +source dest + rop2 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0a $0b $0c $0d $0e $0f $10 + 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 + 0 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 + 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 + 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 + rop3 $ff $ee $dd $cc $bb $aa $99 $88 $77 $66 $55 $44 $33 $22 $11 $00 +} + + inverserops2: array[rasteropty] of byte = + //for 1->foreground in monochromebitmaps + //rop_clear,rop_and,rop_andnot,rop_copy, + ($10, $0f, $0e, $0d, + //rop_notand,rop_nop,rop_xor,rop_or, + $0c, $0b, $0a, $09, + //rop_nor,rop_notxor,rop_not,rop_ornot, + $08, $07, $06, $05, + //rop_notcopy,rop_notor,rop_nand,rop_set); + $04, $03, $02, $01); + + firstrasterops2: array[rasteropty] of byte = //backgroudcolor = $ffffff, + ($09,$09,$09,$09, //textcolor = $000000, and + $09,$09,$09,$09, + $09,$09,$09,$09, + $09,$09,$09,$09); + + secondrasterops2: array[rasteropty] of byte = //colorbackground = $000000, + ($0f,$0f,$0f,$0f, //textcolor = $ffffff, or + $0f,$0f,$0f,$0f, + $0f,$0f,$0f,$0f, + $0f,$0f,$0f,$0f); + +type + rop3tabty = array[rasteropty] of longword; + prop3tabty = ^rop3tabty; +const +{ inverse mono bitmap +P S D clear,and,andnot,copy,notand,nop,xor,or, +x 1 1 1 0 1 0 1 0 1 0 +x 1 0 1 1 0 0 1 1 0 0 +x 0 1 1 1 1 1 0 0 0 0 +x 0 0 1 1 1 1 1 1 1 1 + $f $e $d $c $b $a $9 $8 +P S D nor,notxor,not,ornot,notcopy,notor,nand,set +x 1 1 1 0 1 0 1 0 1 0 +x 1 0 1 1 0 0 1 1 0 0 +x 0 1 1 1 1 1 0 0 0 0 +x 0 0 0 0 0 0 0 0 0 0 + $7 $6 $5 $4 $3 $2 $1 $0 +} + inverserops3: rop3tabty = + //for 1->foreground in monochromebitmaps + // $ff $ee $dd $cc + ($ff0062,$ee0086,$dd0228,$cc0020, + // $bb $aa $99 $88 + $bb0226,$aa0029,$990066,$8800c6, + // $77 $66 $55 $44 + $7700e6,$660046,$550009,$440328, + // $33 $22 $11 $00 + $330008,$220326,$1100a6,$000042); + + rasterops3: rop3tabty = + ($000042,$8800c6,$440328,$cc0020, + $220326,$aa0029,$660046,$ee0086, + $1100a6,$990066,$550009,$dd0228, + $330008,$bb0226,$7700e6,$ff0062); + +{ inverse mono bitmap +P S D clear,and,andnot,copy,notand,nop,xor, or, +1 x 1 1 0 1 0 1 0 1 0 +1 x 0 1 1 0 0 1 1 0 0 +1 x 1 1 0 1 0 1 0 1 0 +1 x 0 1 1 0 0 1 1 0 0 +0 x 1 1 1 1 1 0 0 0 0 +0 x 0 1 1 1 1 1 1 1 1 +0 x 1 1 1 1 1 0 0 0 0 +0 x 0 1 1 1 1 1 1 1 1 + $ff $fa $f5 $f0 $af $aa $a5 $a0 +P S D nor,notxor,not,ornot,notcopy,notor,nand,set +1 x 1 1 0 1 0 1 0 1 0 +1 x 0 1 1 0 0 1 1 0 0 +1 x 1 1 0 1 0 1 0 1 0 +1 x 0 1 1 0 0 1 1 0 0 +0 x 1 1 1 1 1 0 0 0 0 +0 x 0 0 0 0 0 0 0 0 0 +0 x 1 1 1 1 1 0 0 0 0 +0 x 0 0 0 0 0 0 0 0 0 + $5f $5a $55 $50 $0f $0a $05 $00 +} + inversepatrops3: rop3tabty = + // $ff $fa $f5 $f0 + ($ff0062,$fa0089,$f50225,$f00021, + // $af $aa $a5 $a0 + $af0229,$aa0029,$a50065,$a000c9, + // $5f $5a $55 $50 + $5f00e9,$5a0049,$550009,$500325, + // $0f $0a $05 $00 + $0f0001,$0a0329,$0500a9,$000042); + + + + patrops3: rop3tabty = + ($000042,$a000c9,$500325,$f00021, + $0a0329,$aa0029,$5a0049,$fa0089, + $0500a9,$a50065,$550009,$f50225, + $0f0001,$af0229,$5f00e2,$ff0062); + +implementation +uses + mseguiintf,msegraphutils,msesysintf1,sysutils,msegdiplus; + +type + shapety = (fs_copyarea,fs_rect,fs_ellipse,fs_arc,fs_polygon); + + gcflagty = (gcf_backgroundbrushvalid, + gcf_colorbrushvalid,gcf_patternbrushvalid, + gcf_rasterop, + gcf_selectforegroundbrush,gcf_selectbackgroundbrush, + gcf_foregroundpenvalid, + gcf_selectforegroundpen,gcf_selectnullpen,gcf_selectnullbrush, + gcf_ispatternpen,gcf_isopaquedashpen,gcf_smooth, + gcf_gpregionvalid, + gcf_gpbrushcolorvalid,gcf_gpbrushoriginvalid, + gcf_gpmonochromebrush, + gcf_gppencolorvalid,gcf_gppenvalid,gcf_gppenmode,gcf_gpshiftpen, + {gcf_gpsolidfillvalid,gcf_gpspenvalid,} + gcf_last = 31); + //-> longword + gcflagsty = set of gcflagty; + pgcflagsty = ^gcflagsty; +type + monopalettety = record + Flags: UINT; + Count: UINT; + val0: ARGB; + val1: ARGB; + end; + + graypalettety = record + Flags: UINT; + Count: UINT; + values: array[byte] of ARGB; + end; + gdigraypalettety = record + palVersion: WORD; + palNumEntries: WORD; + values: array[byte] of PALETTEENTRY; + end; + pgdigraypalettety = ^gdigraypalettety; + + win32gcdty = record + flags: gcflagsty; + gpflags: gcflagsty; + backgroundcol,foregroundcol: longword; + backgroundbrush: hbrush; + colorbrush: hbrush; + patternbrush: hbrush; + foregroundpen: hpen; + kind: gckindty; + bru: pixmapty; + rop: rasteropty; + brushorg: pointty; + peninfo: lineinfoty; + gccliporigin: pointty; + selectedpen: hpen; + selectedbrush: hbrush; + secondpen: hpen; +// graypal: hpalette; + gpgraphic: pgpgraphics; + gpregion: pgpregion; + gpsolidfill: pgpsolidfill; + gptexture: pgptexture; + gppalettedata: monopalettety; + gptextureimage: pgpbitmap; + gpbrush: pgpbrush; + gppen: pgppen; + end; + {$if sizeof(win32gcdty) > sizeof(gcpty)} {$error 'buffer overflow'}{$ifend} + win32gcty = record + case integer of + 0: (d: win32gcdty;); + 1: (_bufferspace: gcpty;); + end; + pwin32gcty = ^win32gcty; + + charwidthsty = array[0..255] of integer; + pcharwidthsty = ^charwidthsty; + win32fontdataty = record + charwidths: pcharwidthsty; + overhang: integer; + xwidth: integer; + local: array[{$ifdef cpu64}2{$else}3{$endif}..15] of pointer; //plattform dependent + end; + +type + tsimplebitmap1 = class(tsimplebitmap); + tcanvas1 = class(tcanvas); + +{ +const + graypalette: graypalettety = ( + flags: 0; + count: 256; + values: ( +$00000000,$00010101,$00020202,$00030303,$00040404,$00050505,$00060606,$00070707, +$00080808,$00090909,$000a0a0a,$000b0b0b,$000c0c0c,$000d0d0d,$000e0e0e,$000f0f0f, +$00101010,$00111111,$00121212,$00131313,$00141414,$00151515,$00161616,$00171717, +$00181818,$00191919,$001a1a1a,$001b1b1b,$001c1c1c,$001d1d1d,$001e1e1e,$001f1f1f, +$00202020,$00212121,$00222222,$00232323,$00242424,$00252525,$00262626,$00272727, +$00282828,$00292929,$002a2a2a,$002b2b2b,$002c2c2c,$002d2d2d,$002e2e2e,$002f2f2f, +$00303030,$00313131,$00323232,$00333333,$00343434,$00353535,$00363636,$00373737, +$00383838,$00393939,$003a3a3a,$003b3b3b,$003c3c3c,$003d3d3d,$003e3e3e,$003f3f3f, +$00404040,$00414141,$00424242,$00434343,$00444444,$00454545,$00464646,$00474747, +$00484848,$00494949,$004a4a4a,$004b4b4b,$004c4c4c,$004d4d4d,$004e4e4e,$004f4f4f, +$00505050,$00515151,$00525252,$00535353,$00545454,$00555555,$00565656,$00575757, +$00585858,$00595959,$005a5a5a,$005b5b5b,$005c5c5c,$005d5d5d,$005e5e5e,$005f5f5f, +$00606060,$00616161,$00626262,$00636363,$00646464,$00656565,$00666666,$00676767, +$00686868,$00696969,$006a6a6a,$006b6b6b,$006c6c6c,$006d6d6d,$006e6e6e,$006f6f6f, +$00707070,$00717171,$00727272,$00737373,$00747474,$00757575,$00767676,$00777777, +$00787878,$00797979,$007a7a7a,$007b7b7b,$007c7c7c,$007d7d7d,$007e7e7e,$007f7f7f, +$00808080,$00818181,$00828282,$00838383,$00848484,$00858585,$00868686,$00878787, +$00888888,$00898989,$008a8a8a,$008b8b8b,$008c8c8c,$008d8d8d,$008e8e8e,$008f8f8f, +$00909090,$00919191,$00929292,$00939393,$00949494,$00959595,$00969696,$00979797, +$00989898,$00999999,$009a9a9a,$009b9b9b,$009c9c9c,$009d9d9d,$009e9e9e,$009f9f9f, +$00a0a0a0,$00a1a1a1,$00a2a2a2,$00a3a3a3,$00a4a4a4,$00a5a5a5,$00a6a6a6,$00a7a7a7, +$00a8a8a8,$00a9a9a9,$00aaaaaa,$00ababab,$00acacac,$00adadad,$00aeaeae,$00afafaf, +$00b0b0b0,$00b1b1b1,$00b2b2b2,$00b3b3b3,$00b4b4b4,$00b5b5b5,$00b6b6b6,$00b7b7b7, +$00b8b8b8,$00b9b9b9,$00bababa,$00bbbbbb,$00bcbcbc,$00bdbdbd,$00bebebe,$00bfbfbf, +$00c0c0c0,$00c1c1c1,$00c2c2c2,$00c3c3c3,$00c4c4c4,$00c5c5c5,$00c6c6c6,$00c7c7c7, +$00c8c8c8,$00c9c9c9,$00cacaca,$00cbcbcb,$00cccccc,$00cdcdcd,$00cecece,$00cfcfcf, +$00d0d0d0,$00d1d1d1,$00d2d2d2,$00d3d3d3,$00d4d4d4,$00d5d5d5,$00d6d6d6,$00d7d7d7, +$00d8d8d8,$00d9d9d9,$00dadada,$00dbdbdb,$00dcdcdc,$00dddddd,$00dedede,$00dfdfdf, +$00e0e0e0,$00e1e1e1,$00e2e2e2,$00e3e3e3,$00e4e4e4,$00e5e5e5,$00e6e6e6,$00e7e7e7, +$00e8e8e8,$00e9e9e9,$00eaeaea,$00ebebeb,$00ececec,$00ededed,$00eeeeee,$00efefef, +$00f0f0f0,$00f1f1f1,$00f2f2f2,$00f3f3f3,$00f4f4f4,$00f5f5f5,$00f6f6f6,$00f7f7f7, +$00f8f8f8,$00f9f9f9,$00fafafa,$00fbfbfb,$00fcfcfc,$00fdfdfd,$00fefefe,$00ffffff + ); + ); +} +var + nullpen: hpen; + nullbrush: hbrush; +// graypalette: hpalette; + + capstyles: array[capstylety] of longword = + (ps_endcap_flat,ps_endcap_round,ps_endcap_square); + joinstyles: array[joinstylety] of longword = + (ps_join_miter,ps_join_round,ps_join_bevel); + +const + highresfontshift = 6; //64 + highresfontfakt = 1 shl highresfontshift; + highresfontmask = highresfontfakt - 1; + CLEARTYPE_QUALITY = ANTIALIASED_QUALITY+1; + + defaultfontname = 'Tahoma'; +// defaultfontname = 'MS Sans Serif'; + defaultfontnames: defaultfontnamesty = + //stf_default stf_empty stf_unicode stf_menu stf_message stf_hint stf_report + (defaultfontname, '', '', '', '', '', 'Arial', + //stf_proportional stf_fixed, + defaultfontname, 'Courier New', + //stf_helvetica stf_roman stf_courier + 'Arial', 'Times New Roman', 'Courier New'); + +function gdi32getdefaultfontnames: defaultfontnamesty; +begin + result:= defaultfontnames; +end; + +procedure gdi_createpixmap(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.createpixmap do begin + pixmap:= gui_createpixmap(size,0,kind,copyfrom); + end; +end; + +procedure gdi_pixmaptoimage(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.pixmapimage do begin + gui_pixmaptoimage(pixmap,image,drawinfo.gc.handle); + end; +end; + +procedure gdi_imagetopixmap(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.pixmapimage do begin + error:= gui_imagetopixmap(image,pixmap,drawinfo.gc.handle); + end; +end; + +//function gdi32creategc(paintdevice: paintdevicety; const akind: gckindty; +// var gc: gcty; const aprintername: msestring): guierrorty; +procedure gdi_creategc(var drawinfo: drawinfoty); +var + wrect1: trect; +// palpo: pgdigraypalettety; +// by1: byte; +begin + with drawinfo,creategc do begin + gcpo^.gdifuncs:= gui_getgdifuncs; + with win32gcty(gcpo^.platformdata) do begin + d.kind:= kind; +// d.graypal:= 0; + end; + case kind of + gck_pixmap: begin + error:= gde_creategc; + gcpo^.handle:= createcompatibledc(0); + if gcpo^.handle <> 0 then begin + deleteobject(selectobject(gcpo^.handle,paintdevice)); + { + if gcpo^.kind = bmk_gray then begin + if graypalette = 0 then begin + palpo:= pointer(gui_allocimagemem((sizeof(gdigraypalettety)+3) div 4)); + with palpo^ do begin + palversion:= $0300; + palnumentries:= length(values); + for by1:= 0 to high(values) do begin + with values[by1] do begin + pered:= by1; + pegreen:= by1; + peblue:= by1; + peflags:= 0; + end; + end; + end; + graypalette:= createpalette(logpalette(pointer(palpo)^)); + gui_freeimagemem(pointer(palpo)); + end; + end; + } + end; + end; + gck_printer: begin + error:= gde_createprintergc; + gcpo^.handle:= createdc('WINSPOOL',pansichar(ansistring(printernamepo^)),nil,nil); + setmapperflags(gcpo^.handle,1); //match font-device aspectratio + end; + gck_metafile: begin + error:= gde_createmetafilegc; + wrect1.left:= 0; + wrect1.top:= 0; + wrect1.right:= round((gcpo^.paintdevicesize.cx*100)/gcpo^.ppmm); + wrect1.bottom:= round((gcpo^.paintdevicesize.cy*100)/gcpo^.ppmm); + if printernamepo^ = '' then begin + gcpo^.handle:= createenhmetafilew(gcpo^.refgc,nil,@wrect1,nil); //memory + end + else begin + gcpo^.handle:= createenhmetafilew(gcpo^.refgc,pmsechar(printernamepo^),@wrect1,nil); + //file + end; + setmapperflags(gcpo^.handle,1); //match font-device aspectratio + end; + else begin + error:= gde_creategc; + gcpo^.handle:= getdc(paintdevice); + end; + end; + if gcpo^.handle <> 0 then begin + {$ifdef mse_debuggdi} + inc(gccount); + {$endif} + settextalign(gcpo^.handle,ta_left or ta_baseline or ta_noupdatecp); + setbkmode(gcpo^.handle,transparent); + setmapmode(gcpo^.handle,mm_text); + error:= gde_ok; + end; + end; +end; + +procedure transformpoints(var drawinfo: drawinfoty; const aclose: boolean); +var + po1: ppointty; + po2: ppointty; + int1: integer; +begin + with drawinfo.points do begin + int1:= count; + if aclose then begin + inc(int1); + end; + allocbuffer(drawinfo.buffer,int1*sizeof(pointty)); + po1:= points; + po2:= drawinfo.buffer.buffer; + int1:= count; + with drawinfo.origin do begin + while int1 > 0 do begin + po2^.x:= po1^.x + x; + po2^.y:= po1^.y + y; + inc(po1); + inc(po2); + dec(int1); + end; + end; + if aclose then begin + move(drawinfo.buffer.buffer^,(pchar(drawinfo.buffer.buffer)+ + count*sizeof(pointty))^,sizeof(pointty)); + end; + end; +end; + +procedure adjustlineend(po: ppointty); //solve lineto lastpixel problem +var + po1: ppoint; + dx,dy,dist: integer; + +begin + po1:= ppoint(pchar(po)-sizeof(pointty)); + dx:= po^.x - po1^.x; + dy:= po^.y - po1^.y; + dist:= (abs(dx) + abs(dy)) div 2; + if dx < 0 then begin + if dx + dist <= 0 then begin + dec(po^.x); + end; + end + else begin + if dx >= dist then begin + inc(po^.x); + end; + end; + if dy < 0 then begin + if dy + dist <= 0 then begin + dec(po^.y); + end; + end + else begin + if dy >= dist then begin + inc(po^.y); + end; + end; +end; + +procedure transformrect(var drawinfo: drawinfoty); +begin + allocbuffer(drawinfo.buffer,sizeof(trect)); + with drawinfo,prect(buffer.buffer)^,rect do begin + Left:= rect^.x + origin.x; + right:= Left + rect^.cx; + top:= rect^.y + origin.y; + bottom:= top + rect^.cy; + end; +end; + +procedure offsetrect(var drawinfo: drawinfoty); +begin + allocbuffer(drawinfo.buffer,sizeof(rectty)); + with drawinfo,prectty(buffer.buffer)^,rect do begin + x:= rect^.x + origin.x; + cx:= rect^.cx; + y:= rect^.y + origin.y; + cy:= rect^.cy; + end; +end; + +procedure transformellipseinfo(var drawinfo: drawinfoty; const fill: boolean); +var + int1: integer; +begin + allocbuffer(drawinfo.buffer,sizeof(trect)); + int1:= 1; + if fill then begin + int1:= 2; + end; + with drawinfo,prect(buffer.buffer)^,rect do begin + Left:= rect^.x + origin.x - drawinfo.rect.rect^.cx div 2; + right:= Left + rect^.cx+int1; + top:= rect^.y + origin.y - drawinfo.rect.rect^.cy div 2; + bottom:= top + rect^.cy+int1; + end; +end; + +procedure updateopaquemode(var gc: gcty); +begin + with gc,win32gcty(platformdata).d do begin + settextcolor(handle,foregroundcol); + if df_opaque in drawingflags then begin + setbkmode(handle,opaque); + setbkcolor(handle,backgroundcol); + end + else begin + setbkmode(handle,transparent); + end; + end; +end; + +procedure checkgc2(var gc: gcty); + //second pass for transparent patternpen +begin + with gc,win32gcty(platformdata).d do begin + if gcf_isopaquedashpen in flags then begin + selectobject(handle,secondpen); + deleteobject(selectedpen); + selectedpen:= secondpen; + foregroundpen:= secondpen; + exclude(flags,gcf_foregroundpenvalid); + end + else begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + setrop2(handle,secondrasterops2[rop]); + exclude(flags,gcf_rasterop); + end; + end; +end; + +function checkgc(var gc: gcty; aflags: gcflagsty): boolean; + //true if second drawing needed +var + flags1: gcflagsty; + brushinfo: logbrush; + adashes: array[0..high(dashesstringty)] of longword; + int1: integer; + po1: pointer; + dashlen: integer; + astyle: longword; + awidth: integer; + +begin + result:= false; + with gc,win32gcty(platformdata).d do begin + exclude(flags,gcf_isopaquedashpen); + if (df_brush in drawingflags) xor (gcf_ispatternpen in flags) then begin + exclude(flags,gcf_foregroundpenvalid); + end; + if not (gcf_rasterop in flags) and + ([gcf_selectforegroundbrush,gcf_selectforegroundpen] * aflags <> + [gcf_selectforegroundbrush,gcf_selectforegroundpen]) then begin + exclude(flags,gcf_selectforegroundbrush); //refresh rasterop + exclude(flags,gcf_selectforegroundpen); + if df_canvasismonochrome in drawingflags then begin + setrop2(handle,inverserops2[rop]); + end + else begin + setrop2(handle,rasterops2[rop]); + end; + include(flags,gcf_rasterop); + end; + flags1:= gcflagsty((longword(aflags) xor longword(flags)) and longword(aflags)); + //needed objects + if df_brush in drawingflags then begin + exclude(flags1,gcf_colorbrushvalid); + end + else begin + exclude(flags1,gcf_patternbrushvalid); + end; + if gcf_backgroundbrushvalid in flags1 then begin + if backgroundbrush <> 0 then begin + if backgroundbrush = selectedbrush then begin + selectobject(handle,nullbrush); + end; + deleteobject(backgroundbrush); + end; + backgroundbrush:= createsolidbrush(backgroundcol); + end; + if gcf_colorbrushvalid in flags1 then begin + if colorbrush <> 0 then begin + if colorbrush = selectedbrush then begin + selectobject(handle,nullbrush); + end; + deleteobject(colorbrush); + end; + colorbrush:= createsolidbrush(foregroundcol); + end; + if gcf_patternbrushvalid in flags1 then begin + if patternbrush <> 0 then begin + if patternbrush = selectedbrush then begin + selectobject(handle,nullbrush); + end; + deleteobject(patternbrush); + end; + patternbrush:= createpatternbrush(bru); + end; + if gcf_foregroundpenvalid in flags1 then begin + if foregroundpen <> 0 then begin + if selectedpen = foregroundpen then begin + selectobject(handle,nullpen); + end; + deleteobject(foregroundpen); + end; + //todo: emulations for win95, opaquemode + with peninfo do begin + po1:= nil; + dashlen:= length(dashes); + if dashlen > 0 then begin + if df_opaque in drawingflags then begin + include(flags,gcf_isopaquedashpen); + result:= true; + end; + if iswin95 then begin + astyle:= ps_dot; + end + else begin + if dashes = #1#1 then begin + astyle:= ps_alternate or ps_cosmetic; + dashlen:= 0; + end + else begin + for int1:= 1 to length(dashes) do begin + adashes[int1-1]:= ord(dashes[int1]){ div 3}; + end; + po1:= @adashes; + astyle:= ps_userstyle or ps_geometric; + end; + end; + end + else begin + if (df_brush in drawingflags) or (width > 0) then begin + astyle:= ps_geometric; + end + else begin + astyle:= ps_cosmetic; + end; + end; + if astyle and ps_geometric <> 0 then begin + astyle:= astyle or capstyles[capstyle] or joinstyles[joinstyle]; + end; + with brushinfo do begin + if df_brush in drawingflags then begin + lbStyle:= bs_pattern; + lbhatch:= bru; + include(flags,gcf_ispatternpen); + end + else begin + lbStyle:= bs_solid; + lbColor:= foregroundcol; + exclude(flags,gcf_ispatternpen); + end; + end; + if width = 0 then begin + awidth:= 1 + end + else begin + awidth:= width + end; + foregroundpen:= extcreatepen(astyle,awidth,brushinfo, + dashlen,po1); + if gcf_isopaquedashpen in flags then begin + secondpen:= foregroundpen; + with brushinfo do begin + lbStyle:= bs_solid; + lbColor:= backgroundcol; + end; + foregroundpen:= extcreatepen(astyle and + not(ps_userstyle or ps_dot or ps_alternate),awidth,brushinfo, + 0,nil); + end; + end; + end; + if gcf_selectbackgroundbrush in aflags then begin + selectobject(gc.handle,backgroundbrush); + selectedbrush:= backgroundbrush; + end; + if gcf_selectforegroundbrush in aflags then begin + if df_brush in drawingflags then begin + selectobject(gc.handle,patternbrush); + selectedbrush:= patternbrush; + end + else begin + selectobject(gc.handle,colorbrush); + selectedbrush:= colorbrush; + end; + end; + if gcf_selectforegroundpen in aflags then begin + if (gcf_ispatternpen in flags) and + (drawingflags * [df_monochrome,df_opaque] = [df_monochrome]) then begin + result:= true; + setbkcolor(handle,$ffffff); + settextcolor(handle,$000000); + setrop2(handle,firstrasterops2[rop]); + end + else begin + updateopaquemode(gc); + end; + selectobject(gc.handle,foregroundpen); + selectedpen:= foregroundpen; + end; + if gcf_selectnullpen in aflags then begin + selectobject(gc.handle,nullpen); + selectedpen:= nullpen; + end; + if gcf_selectnullbrush in aflags then begin + selectobject(gc.handle,nullbrush); + selectedbrush:= nullbrush; + end; + flags:= flags + flags1; + end; +end; + +procedure deletepgtexture(var gc: gcty); +begin + with win32gcty(gc.platformdata).d do begin + if gptexture <> nil then begin + gdipdeletebrush(pgpbrush(gptexture)); + gptexture:= nil; + end; + if gptextureimage <> nil then begin + gdipdisposeimage(pgpimage(gptextureimage)); +// gdipfree(gptextureimage); + gptextureimage:= nil; + end; + gpflags:= gpflags - + [gcf_gpmonochromebrush,gcf_patternbrushvalid, + gcf_gpbrushoriginvalid,gcf_gpbrushcolorvalid]; + end; +end; + +const + alphamax = $ff000000; + +function gpcolor(const apixel: pixelty): pixelty; inline; +begin + result:= apixel and $0000ff00 or + (apixel and $00ff0000 shr 16) or + (apixel and $000000ff shl 16) or alphamax; +end; + +//todo: optimize, update invalid values only + +const + gpcaps: array[capstylety] of gplinecap = + (linecapflat,linecapround,linecapsquare); + gpdashcaps: array[capstylety] of gpdashcap = + (dashcapflat,dashcapround,dashcaptriangle); + gpjoins: array[joinstylety] of gplinejoin = + (linejoinmiterclipped,linejoinround,linejoinbevel); +const + gpstartflags = [gcf_patternbrushvalid,gcf_gpbrushoriginvalid,gcf_gpregionvalid, + gcf_gpmonochromebrush, + gcf_gpbrushcolorvalid,gcf_gppencolorvalid,gcf_gppenvalid]; +// gcfgpflags = [gcf_gppenmode]; + gplineflags = [gcf_selectforegroundpen]; + gpfillflags = [gcf_selectforegroundbrush]; + +procedure checkgpgc(var gc: gcty; aflags: gcflagsty); + + function checkbrushorcolor: boolean; //true if changed + procedure updatepalette; + begin + with gc,win32gcty(platformdata).d do begin + if gcf_gpmonochromebrush in gpflags then begin + with gppalettedata do begin + longword(val0):= gpcolor(foregroundcol) or $ff000000; + if df_opaque in drawingflags then begin + longword(val1):= gpcolor(backgroundcol) or $ff000000; + flags:= 0; + end + else begin + longword(val1):= backgroundcol; + flags:= PaletteFlagsHasAlpha; + end; + end; + gdipsetimagepalette(pgpimage(gptextureimage),@gppalettedata); + end; + end; + end; //checkgpgc +var + newtexture: boolean; + begin + result:= false; + with gc,win32gcty(platformdata).d do begin + newtexture:= false; + if df_brush in drawingflags then begin + if not (gcf_patternbrushvalid in gpflags) then begin + if gdipcreatebitmapfromhbitmap(bru,0,@gptextureimage) = ok then begin + if df_monochrome in drawingflags then begin + include(gpflags,gcf_gpmonochromebrush); + end; + updatepalette; + gdipcreatetexture(pgpimage(gptextureimage),wrapmodetile,@gptexture); + end; + include(gpflags,gcf_patternbrushvalid); + newtexture:= true; + result:= true; + end; + if gptexture <> nil then begin + gpbrush:= pgpbrush(gptexture); + if not (gcf_gpbrushoriginvalid in gpflags) then begin + gdipresettexturetransform(gptexture); + gdiptranslatetexturetransform(gptexture,brushorg.x,brushorg.y, + matrixorderprepend); + include(gpflags,gcf_gpbrushoriginvalid); + result:= true; + end; + end + else begin + gpbrush:= pgpbrush(gpsolidfill); //error + end; + end + else begin + gpbrush:= pgpbrush(gpsolidfill); + end; + if not (gcf_gpbrushcolorvalid in gpflags) then begin + result:= true; + gdipsetsolidfillcolor(gpsolidfill,gpcolor(foregroundcol)); + if not newtexture then begin + updatepalette; + if gpbrush = pointer(gptexture) then begin + gdipdeletebrush(gpbrush); + gdipcreatetexture(pgpimage(gptextureimage), + wrapmodetile,@gptexture); + gdiptranslatetexturetransform(gptexture,brushorg.x,brushorg.y, + matrixorderprepend); + gpbrush:= pgpbrush(gptexture); + end; + end; + include(gpflags,gcf_gpbrushcolorvalid); + end; + end; + end; //checkbrushorcolor + +var + cap1: gplinecap; + dash1: array[0..high(dashesstringty)] of gpreal; + int1: integer; + dasca: real; + reg: hrgn; +begin + with gc,win32gcty(platformdata).d do begin + if not (gcf_gpregionvalid in gpflags) then begin + if gpregion <> nil then begin + gdipdeleteregion(gpregion); + end; + reg:= createrectrgn(0,0,0,0); + if getcliprgn(handle,reg) = 0 then begin + gdipresetclip(gpgraphic); + gpregion:= nil; + end + else begin + GdipCreateRegionHrgn(reg,@gpregion); + gdipsetclipregion(gpgraphic,gpregion,combinemodereplace); + end; + include(gpflags,gcf_gpregionvalid); + deleteobject(reg); + end; + if gcf_selectforegroundpen in aflags then begin + if checkbrushorcolor then begin + if df_brush in drawingflags then begin + gdipsetpenbrushfill(gppen,gpbrush); + end + else begin + gdipsetpencolor(gppen,gpcolor(foregroundcol)); + end; + end; + if not (gcf_gppenvalid in gpflags) then begin + exclude(gpflags,gcf_gppenmode); + if df_brush in drawingflags then begin + gdipsetpenbrushfill(gppen,gpbrush); + end + else begin + gdipsetpencolor(gppen,gpcolor(foregroundcol)); + end; + exclude(gpflags,gcf_gpshiftpen); + if peninfo.width = 0 then begin + gdipsetpenwidth(gppen,1); + dasca:= 1; + end + else begin + if not odd(peninfo.width) then begin + include(gpflags,gcf_gpshiftpen); + end; + gdipsetpenwidth(gppen,peninfo.width); + dasca:= 1/peninfo.width; + end; + cap1:= gpcaps[peninfo.capstyle]; + gdipsetpenlinecap197819(gppen,cap1,cap1, + gpdashcaps[peninfo.capstyle]); + gdipsetpenlinejoin(gppen,gpjoins[peninfo.joinstyle]); + if length(peninfo.dashes) > 0 then begin + for int1:= 1 to length(peninfo.dashes) do begin + dash1[int1-1]:= ord(peninfo.dashes[int1])*dasca; + end; + gdipsetpendasharray(gppen,@dash1,length(peninfo.dashes)); + gdipsetpendashoffset(gppen,0.5*dasca); + end + else begin + gdipsetpendashstyle(gppen,dashstylesolid); + end; + include(gpflags,gcf_gppenvalid); + end; + end; + if gcf_selectforegroundbrush in aflags then begin + checkbrushorcolor; + end; + if (gcf_selectforegroundpen in aflags) xor + (gcf_gppenmode in gpflags) then begin + if (gcf_selectforegroundpen in aflags) then begin + if gcf_gpshiftpen in gpflags then begin + gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodehalf); + end + else begin + gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodenone); + end; +// gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodehalf); + include(gpflags,gcf_gppenmode); + end + else begin + gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodehalf); + exclude(gpflags,gcf_gppenmode); + end; +{ + gdipresetworldtransform(gpgraphic); + if gcf_gppenmode in aflags then begin + gdiptranslateworldtransform(gpgraphic,0.5,0.5,matrixorderprepend); + include(gpflags,gcf_gppenmode); + end + else begin + exclude(gpflags,gcf_gppenmode); + end; +} + end; + end; +end; + +function createregion: regionty; overload; +begin +{$ifdef mse_debuggdi} + inc(regioncount); +{$endif} + result:= createrectrgnindirect(trect(nullrect)); +end; + +function createregion(var rect: rectty; const gc: gcty): regionty; overload; +var + rect1: rectty; +begin +{$ifdef mse_debuggdi} + inc(regioncount); +{$endif} + if win32gcty(gc.platformdata).d.kind = gck_printer then begin + rect1:= rect; + recttowinrect(rect1); + lptodp(gc.handle, + {$ifdef FPC}lppoint(@{$endif}rect1{$ifdef FPC}){$endif},2); + result:= createrectrgnindirect(trect(rect1)); + end + else begin + recttowinrect(rect); + result:= createrectrgnindirect(trect(rect)); + winrecttorect(rect); + end; +end; + +procedure gdi_createemptyregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + dest:= createregion; + end; +end; + +procedure gdi_setcliporigin(var drawinfo: drawinfoty); +var + reg1: hrgn; + delta: pointty; +begin + with drawinfo.gc,win32gcty(platformdata).d do begin + delta:= subpoint(cliporigin,gccliporigin); + if (delta.x <> 0) or (delta.y <> 0) then begin + reg1:= createregion; + if getcliprgn(handle,reg1) > 0 then begin + offsetrgn(reg1,delta.x,delta.y); + selectcliprgn(handle,reg1); + end; + deleteobject(reg1); +{$ifdef mse_debuggdi} + dec(regioncount); +{$endif} + end; + gccliporigin:= cliporigin; + end; +// gdierror(gde_notimplemented,'setcliporigin'); +end; + +procedure gdi_createrectregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + dest:= createregion(rect,drawinfo.gc); + end; +end; + +procedure gdi_createrectsregion(var drawinfo: drawinfoty); +var + reg1: hrgn; + int1: integer; + rect1: rectty; +begin + with drawinfo.regionoperation do begin + dest:= createregion; + if rectscount > 0 then begin + if win32gcty(drawinfo.gc.platformdata).d.kind = gck_printer then begin + for int1:= 0 to rectscount - 1 do begin + rect1:= rectspo^[int1]; + recttowinrect(rect1); + lptodp(drawinfo.gc.handle, + {$ifdef FPC}lppoint(@{$endif}rect1{$ifdef FPC}){$endif},2); + reg1:= createrectrgnindirect(trect(rect1)); + combinergn(dest,dest,reg1,rgn_or); + deleteobject(reg1); + end; + end + else begin + recttowinrect(@rectspo^[0],rectscount); + for int1:= 0 to rectscount - 1 do begin + reg1:= createrectrgnindirect(trect(rectspo^[int1])); + combinergn(dest,dest,reg1,rgn_or); + deleteobject(reg1); + end; + winrecttorect(@rectspo^[0],rectscount); + end; + end; + end; +end; + +procedure gdi_destroyregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + if source <> 0 then begin +{$ifdef mse_debuggdi} + dec(regioncount); +{$endif} + deleteobject(source); + end; + end; +end; + +procedure gdi_regionisempty(var drawinfo: drawinfoty); +var + rect1: trect; +begin + with drawinfo.regionoperation do begin + if getrgnbox(source,rect1) = nullregion then begin + dest:= 1; + end + else begin + dest:= 0; + end; + end; +end; + +procedure gdi_regionclipbox(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + getrgnbox(source,trect(rect)); + if win32gcty(drawinfo.gc.platformdata).d.kind = gck_printer then begin + dptolp(drawinfo.gc.handle, + {$ifdef FPC}lppoint(@{$endif}rect{$ifdef FPC}){$endif},2); + end; + winrecttorect(rect); + end; +end; + +procedure gdi_copyregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + if source = 0 then begin + dest:= 0; + end + else begin + dest:= createregion; + combinergn(dest,source,0,rgn_copy); + end; + end; +end; + +procedure gdi_moveregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + offsetrgn(source,rect.x,rect.y); + end; +end; + +procedure gdi_regsubrect(var drawinfo: drawinfoty); +var + reg1: hrgn; +begin + with drawinfo.regionoperation do begin + reg1:= createregion(rect,drawinfo.gc); + combinergn(dest,dest,reg1,rgn_diff); + deleteobject(reg1); +{$ifdef mse_debuggdi} + dec(regioncount); +{$endif} + end; +end; + +procedure gdi_regsubregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + combinergn(dest,dest,source,rgn_diff); + end; +end; + +procedure gdi_regaddrect(var drawinfo: drawinfoty); +var + reg1: hrgn; +begin + with drawinfo.regionoperation do begin + reg1:= createregion(rect,drawinfo.gc); + combinergn(dest,dest,reg1,rgn_or); + deleteobject(reg1); +{$ifdef mse_debuggdi} + dec(regioncount); +{$endif} + end; +end; + +procedure gdi_regaddregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + combinergn(dest,dest,source,rgn_or); + end; +end; + +procedure gdi_regintersectrect(var drawinfo: drawinfoty); +var + reg1: hrgn; +begin + with drawinfo.regionoperation do begin + reg1:= createregion(rect,drawinfo.gc); + combinergn(dest,dest,reg1,rgn_and); + deleteobject(reg1); +{$ifdef mse_debuggdi} + dec(regioncount); +{$endif} + end; +end; + +procedure gdi_regintersectregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + combinergn(dest,dest,source,rgn_and); + end; +end; + +var + fgdipluschecked: boolean; + fhasgdiplus: boolean; + +procedure gdi_destroygc(var drawinfo: drawinfoty); +begin + with drawinfo,gc,win32gcty(platformdata).d do begin + selectobject(handle,nullpen); + selectobject(handle,nullbrush); +{$ifdef mse_debuggdi} + dec(gccount); +{$endif} + if handle <> 0 then begin + case kind of + gck_pixmap,gck_printer: begin + // bmp1:= createcompatiblebitmap(handle,0,0); + // bmp2:= selectobject(handle,bmp1); //select actual bitmap out of dc + //really needed? + deletedc(handle); + // deleteobject(bmp1); + end; + gck_metafile: begin + deleteenhmetafile(closeenhmetafile(handle)); + end + else begin + releasedc(paintdevice,handle); + end; + end; + end; + if backgroundbrush <> 0 then begin + deleteobject(backgroundbrush); + backgroundbrush:= 0; + end; + if colorbrush <> 0 then begin + deleteobject(colorbrush); + colorbrush:= 0; + end; + if patternbrush <> 0 then begin + deleteobject(patternbrush); + patternbrush:= 0; + end; + if foregroundpen <> 0 then begin + deleteobject(foregroundpen); + foregroundpen:= 0; + end; + selectedpen:= 0; + selectedbrush:= 0; + if fhasgdiplus then begin + if gpgraphic <> nil then begin + gdipdeletegraphics(gpgraphic); + gpgraphic:= nil; + gdipdeletebrush(pgpbrush(gpsolidfill)); + gdipdeletepen(gppen); + if gpregion <> nil then begin + gdipdeleteregion(gpregion); + gpregion:= nil; + end; + if gptexture <> nil then begin + gdipdeletebrush(pgpbrush(gptexture)); + gptexture:= nil; + end; + deletepgtexture(gc); + end; + end; + end; +end; + +function hasgdiplus: boolean; +begin + if not fhasgdiplus and not fgdipluschecked then begin + fgdipluschecked:= true; + fhasgdiplus:= initializegdiplus([],true); + end; + result:= fhasgdiplus; +end; + +procedure checkgdiplusgraphic(var drawinfo: drawinfoty); +var + reg: hrgn; + int1: int; +begin + with drawinfo.gc,win32gcty(platformdata).d do begin + if gpgraphic = nil then begin + with gppalettedata do begin + flags:= 0; + count:= 2; + val0:= 0; + val1:= $ffffffff; + end; + reg:= createrectrgn(0,0,0,0); + int1:= getcliprgn(handle,reg); + selectcliprgn(handle,0); //use full paintdevice rect + gdipcreatefromhdc(handle,@gpgraphic); + if int1 > 0 then begin + selectcliprgn(handle,reg); + end; + deleteobject(reg); + if gpgraphic <> nil then begin + gdipsetsmoothingmode(gpgraphic,smoothingmodeantialias); + gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodehalf); +// gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodenone); + gdipcreatesolidfill(alphamax,@gpsolidfill); + gdipcreatepen1(alphamax,1,unitpixel,@gppen); + gpflags:= []; +// gdipsetpenmode(gppen,penalignmentcenter); + end; + end; + end; +end; + +procedure gdi_changegc(var drawinfo: drawinfoty); +begin + with drawinfo.gcvalues^,drawinfo.gc,win32gcty(platformdata).d do begin + if gvm_colorbackground in mask then begin + exclude(flags,gcf_backgroundbrushvalid); + exclude(gpflags,gcf_gpbrushcolorvalid); + backgroundcol:= colorbackground; + end; + if gvm_colorforeground in mask then begin + flags:= flags - [gcf_colorbrushvalid,gcf_foregroundpenvalid]; + gpflags:= gpflags - [gcf_gpbrushcolorvalid,gcf_gppencolorvalid]; + foregroundcol:= colorforeground; + end; + if mask * [gvm_linewidth,gvm_dashes,gvm_capstyle,gvm_joinstyle] <> [] then begin + exclude(flags,gcf_foregroundpenvalid); + exclude(gpflags,gcf_gppenvalid); + peninfo:= lineinfo; + peninfo.width:= (peninfo.width + linewidthroundvalue) shr linewidthshift; + end; + if gvm_rasterop in mask then begin + exclude(flags,gcf_rasterop); + rop:= rasterop; + end; + if gvm_brush in mask then begin + exclude(flags,gcf_patternbrushvalid); +// exclude(gpflags,gcf_patternbrushvalid); + bru:= tsimplebitmap1(brush).handle; + deletepgtexture(drawinfo.gc); //resets vaildflags + end; + if gvm_brushorigin in mask then begin + exclude(gpflags,gcf_gpbrushoriginvalid); + brushorg:= brushorigin; + setbrushorgex(handle,brushorigin.x,brushorigin.y,nil); + end; + if gvm_clipregion in mask then begin + gccliporigin:= cliporigin; + if ((cliporigin.x <> 0) or (cliporigin.y <> 0)) and (clipregion <> 0) then begin + offsetrgn(clipregion,cliporigin.x,cliporigin.y); + selectcliprgn(handle,clipregion); + offsetrgn(clipregion,-cliporigin.x,-cliporigin.y); + end + else begin + selectcliprgn(handle,clipregion); + end; + exclude(gpflags,gcf_gpregionvalid); + end + else begin +// include(gpflags,gcf_gpregionvalid); //??? + end; + if gvm_font in mask then begin + selectobject(handle,font); + end; + if gvm_options in mask then begin + if cao_smooth in options then begin + if hasgdiplus then begin + checkgdiplusgraphic(drawinfo); + if gpgraphic <> nil then begin + if not (gcf_smooth in flags) then begin + gpflags:= gpflags - gpstartflags; + include(flags,gcf_smooth); + end; + end; + end; + end + else begin + exclude(flags,gcf_smooth); + end; + end; +// gpflags:= gpflags - ((flags >< flagsbefore)*flagsbefore); + //invalidate gdiplus + end; +end; + +procedure gdi_getcanvasclass(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_endpaint(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_flush(var drawinfo: drawinfoty); //gdifunc +begin + with win32gcty(drawinfo.gc.platformdata).d do begin + if gpgraphic <> nil then begin + gdipflush(gpgraphic,flushintentionsync); + end; + end; +end; + +procedure gdi_movewindowrect(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.moverect do begin + gui_movewindowrect(drawinfo.paintdevice,dist^,rect^); + end; +end; + +procedure gdi_drawlines(var drawinfo: drawinfoty); +var + po1: ppointty; + bo1: boolean; +begin + transformpoints(drawinfo,false); + if gcf_smooth in win32gcty(drawinfo.gc.platformdata).d.flags then begin + checkgpgc(drawinfo.gc,gplineflags); + with drawinfo,points,win32gcty(gc.platformdata).d do begin + if closed then begin + gdipdrawpolygoni(gpgraphic,gppen,buffer.buffer,count); + end + else begin + gdipdrawlinesi(gpgraphic,gppen,buffer.buffer,count); + end; + end; + end + else begin + with drawinfo,points do begin + if closed then begin + bo1:= checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen, + gcf_selectnullbrush]); + windows.polygon(gc.handle,buffer.buffer^,count); + if bo1 then begin + checkgc2(gc); + windows.polygon(gc.handle,buffer.buffer^,count); + end; + end + else begin + bo1:= checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen]); + if ((win32gcty(gc.platformdata).d.peninfo.width <= 1) or + (win32gcty(gc.platformdata).d.peninfo.capstyle = cs_butt)) and + (count > 0) then begin + po1:= @pointarty(buffer.buffer)[count-1]; //endpoint + if (po1^.x <> pointarty(buffer.buffer)[0].x) or + (po1^.y <> pointarty(buffer.buffer)[0].y) then begin + adjustlineend(po1); + end; + end; + windows.polyline(gc.handle,buffer.buffer^,count); + if bo1 then begin + checkgc2(gc); + windows.polyline(gc.handle,buffer.buffer^,count); + end; + end; + end; + end; +end; + +procedure gdi_drawlinesegments(var drawinfo: drawinfoty); +var + int1,int2: integer; + po1,po2: pdword; + po3: ppointty; + bo1: boolean; +begin + with drawinfo,win32gcty(gc.platformdata).d do begin + int1:= points.count div 2; + allocbuffer(buffer,points.count*sizeof(pointty)+int1*sizeof(integer)); + //reserve memory + transformpoints(drawinfo,false); + po3:= buffer.buffer; //segments + int1:= points.count div 2; //segmentcount + if gcf_smooth in flags then begin + checkgpgc(drawinfo.gc,gplineflags); + for int2:= 0 to int1-1 do begin + gdipdrawlinesi(gpgraphic,gppen,pointer(po3),2); + inc(po3,2); + end; + end + else begin + po1:= pointer(pchar(buffer.buffer) + int1*sizeof(segmentty)); + inc(po3); //segmentend + po2:= po1; //counts + bo1:= (win32gcty(gc.platformdata).d.peninfo.width < 1); + for int2:= 0 to int1 - 1 do begin + if bo1 then begin + adjustlineend(po3); + inc(po3,2); + end; + po2^:= 2; + inc(po2); + end; + bo1:= checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen]); + windows.polyPolyline(gc.handle,buffer.buffer^,po1^,int1); + if bo1 then begin + checkgc2(gc); + windows.polyPolyline(gc.handle,buffer.buffer^,po1^,int1); + end; + end; + end; +end; + +procedure gdi_drawellipse(var drawinfo: drawinfoty); +var + bo1: boolean; +begin + if gcf_smooth in win32gcty(drawinfo.gc.platformdata).d.flags then begin + checkgpgc(drawinfo.gc,gplineflags); + with drawinfo,rect.rect^,win32gcty(gc.platformdata).d do begin + gdipdrawellipsei(gpgraphic,gppen,origin.x+x-cx div 2, + origin.y+y-cy div 2,cx,cy); + end; + end + else begin + transformellipseinfo(drawinfo,false); + with drawinfo do begin + bo1:= checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen, + gcf_selectnullbrush]); + windows.ellipse(gc.handle,trect(buffer.buffer^).Left, + trect(buffer.buffer^).top, + trect(buffer.buffer^).right, + trect(buffer.buffer^).bottom); + if bo1 then begin + checkgc2(gc); + windows.ellipse(gc.handle,trect(buffer.buffer^).Left, + trect(buffer.buffer^).top, + trect(buffer.buffer^).right, + trect(buffer.buffer^).bottom); + end; + end; + end; +end; + +procedure getarcinfo(const info: drawinfoty; + out xstart,ystart,xend,yend: integer); +var + stopang: real; +begin + with info,arc,rect^ do begin + stopang:= (startang+extentang); + xstart:= (round(cos(startang)*cy) div 2) + x + origin.x; + ystart:= (round(-sin(startang)*cy) div 2) + y + origin.y; + xend:= (round(cos(stopang)*cy) div 2) + x + origin.x; + yend:= (round(-sin(stopang)*cy) div 2) + y + origin.y; + end; +end; + +const + radianttograd = -360.0/(2.0*pi); + +type + gparcinfoty = record + rect: rectty; + startang,extentang: real; + end; + +procedure adjustgparc(const drawinfo: drawinfoty; out ainfo: gparcinfoty); +begin + with drawinfo,arc,rect^ do begin + ainfo.rect.x:= x + origin.x - cx div 2; + ainfo.rect.y:= y + origin.y - cy div 2; + ainfo.rect.size:= size; + ainfo.startang:= startang*radianttograd; + ainfo.extentang:= extentang*radianttograd; + { + if extentang < 0 then begin + startang:= startang+extentang; + extentang:= -extentang; + end; + while startang < 0 do begin + startang:= startang + 360; + end; + } + end; +end; + +procedure gdi_drawarc(var drawinfo: drawinfoty); +var //todo: optimize + bo1: boolean; + xstart,ystart,xend,yend: integer; + arcinfo: gparcinfoty; +begin + if gcf_smooth in win32gcty(drawinfo.gc.platformdata).d.flags then begin + checkgpgc(drawinfo.gc,gplineflags); + adjustgparc(drawinfo,arcinfo); + with drawinfo,arcinfo,win32gcty(gc.platformdata).d do begin + gdipdrawarci(gpgraphic,gppen,rect.x,rect.y,rect.cx,rect.cy, + startang,extentang); + end; + end + else begin + getarcinfo(drawinfo,xstart,ystart,xend,yend); + with drawinfo,arc,rect^ do begin + if (xstart = xend) and (ystart = yend) and (abs(extentang) < 1) then begin + checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen,gcf_selectnullbrush]); + movetoex(gc.handle,xstart,ystart,nil); + if (win32gcty(gc.platformdata).d.peninfo.width = 0) {and + (win32gcty(gc.platformdata).peninfo.capstyle <> cs_butt)} then begin + inc(xstart); + end; + lineto(gc.handle,xstart,ystart); + exit; + end; + if extentang < 0 then begin + setarcdirection(gc.handle,ad_clockwise); + end + else begin + setarcdirection(gc.handle,ad_counterclockwise); + end; + end; + transformellipseinfo(drawinfo,false); + with drawinfo do begin + bo1:= checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen,gcf_selectnullbrush]); + windows.arc(gc.handle,trect(buffer.buffer^).Left, + trect(buffer.buffer^).top, + trect(buffer.buffer^).right, + trect(buffer.buffer^).bottom, + xstart,ystart,xend,yend); + if bo1 then begin + checkgc2(gc); + windows.arc(gc.handle,trect(buffer.buffer^).Left, + trect(buffer.buffer^).top, + trect(buffer.buffer^).right, + trect(buffer.buffer^).bottom, + xstart,ystart,xend,yend); + end; + end; + end; +end; + +procedure gdi_drawstring16(var drawinfo: drawinfoty); +begin + with drawinfo do begin + updateopaquemode(gc); + with gc,drawinfo.text16pos do begin + windows.textoutw(handle,pos^.x + origin.x,pos^.y + origin.y,text,count); + end; + end; +end; + +//todo!!!!!: support all rops on win95, test!!! + +function win95maskblt(DestDC: HDC; XDest, YDest, Width, Height: Integer; SrcDC: HDC; + XScr, YScr: Integer; Mask: HBITMAP; amaskdc: hdc; xMask, yMask: Integer; Rop: rasteropty): boolean; +var + maskdc: hdc; + bmp: hbitmap; + dc: hdc; + textcol,bkcol: longword; + + procedure getcopy(arop: rasteropty); + begin + textcol:= gettextcolor(destdc); + bkcol:= getbkcolor(destdc); + settextcolor(destdc,$ffffff); + setbkcolor(destdc,$000000); + bmp:= createcompatiblebitmap(destdc,width,height); + dc:= createcompatibledc(destdc); + selectobject(dc,bmp); + settextcolor(dc,textcol); + setbkcolor(dc,bkcol); + bitblt(dc,0,0,width,height,srcdc,xscr,yscr,rasterops3[rop_copy]); + settextcolor(dc,$ffffff); + setbkcolor(dc,$000000); + bitblt(dc,0,0,width,height,maskdc,xmask,ymask,rasterops3[arop]); + end; + +begin + result:= true; + bmp:= 0; + if amaskdc = 0 then begin + maskdc:= createcompatibledc(0); + selectobject(maskdc,mask); + end + else begin + maskdc:= amaskdc; + end; + case rop of + rop_copy,rop_xor,rop_or: begin + getcopy(rop_and); + if rop = rop_copy then begin + bitblt(destdc,xdest,ydest,width,height,maskdc,xmask,ymask,rasterops3[rop_notand]); + settextcolor(destdc,textcol); + setbkcolor(destdc,bkcol); + bitblt(destdc,xdest,ydest,width,height,dc,0,0,rasterops3[rop_or]); + end + else begin + settextcolor(destdc,textcol); + setbkcolor(destdc,bkcol); + bitblt(destdc,xdest,ydest,width,height,dc,0,0,rasterops3[rop]); + end; + end; + rop_and: begin + getcopy(rop_notor); + settextcolor(destdc,textcol); + setbkcolor(destdc,bkcol); + bitblt(destdc,xdest,ydest,width,height,dc,0,0,rasterops3[rop]); + end; + end; + if amaskdc = 0 then begin + deletedc(maskdc); + end; + if bmp <> 0 then begin + deletedc(dc); + deleteobject(bmp); + end; +end; + +procedure fill(var drawinfo: drawinfoty; shape: shapety); + +var + xstart,ystart,xend,yend: integer; + rop3tab: prop3tabty; + patrop3tab: prop3tabty; + + procedure fill1( adc: hdc; arop: rasteropty); + begin + with drawinfo do begin + if (shape <> fs_rect) and (shape <> fs_copyarea) then begin + if df_canvasismonochrome in gc.drawingflags then begin + setrop2(adc,inverserops2[arop]); + end + else begin + setrop2(adc,rasterops2[arop]); + end; + end; + if shape <> fs_copyarea then begin + with win32gcty(gc.platformdata).d do begin + if patternbrush <> 0 then begin + selectobject(adc,patternbrush); + if adc = gc.handle then begin + selectedbrush:= patternbrush; + end; + end; + end; + end; + case shape of + fs_copyarea: begin + with copyarea,sourcerect^ do begin + if mask = nil then begin + bitblt(adc,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle,x,y,rop3tab^[arop]); + end + else begin + if iswin95 or (win32gcty(gc.platformdata).d.kind = gck_printer) then begin +// win95maskblt(adc,destrect^.x,destrect^.y,cx,cy,source^.gc.handle, +// x,y,mask,maskgchandle,x,y,arop); + tcanvas1(mask.canvas).checkgcstate([cs_gc]); + win95maskblt(adc,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,tsimplebitmap1(mask).handle, + tcanvas1(mask.canvas).fdrawinfo.gc.handle,x,y,arop); + end + else begin + maskblt(adc,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,tsimplebitmap1(mask).handle,x,y, + makerop4(rop3tab^[rop_nop],rop3tab^[arop])); + end; + end; + end; + end; + fs_rect: begin + with prectty(buffer.buffer)^ do begin + windows.patblt(adc,x,y,cx,cy,patrop3tab^[arop]); + end; + end; + fs_ellipse: begin + with trect(buffer.buffer^) do begin + windows.ellipse(adc,left,top,right,bottom); + end; + end; + fs_arc: begin + with trect(buffer.buffer^) do begin + if arc.pieslice then begin + windows.pie(adc,left,top,right,bottom,xstart,ystart,xend,yend); + end + else begin + windows.chord(adc,left,top,right,bottom,xstart,ystart,xend,yend); + end; + end; + end; + fs_polygon: begin + windows.Polygon(adc,buffer.buffer^,points.count); + end; + end; + end; + end; + +var + rect1,rect2: rectty; + po1: ppointty; + int1: integer; + bmp: hbitmap; + dc1: hdc; + +begin + if shape = fs_arc then begin + getarcinfo(drawinfo,xstart,ystart,xend,yend); + end; + with drawinfo do begin + with gc,win32gcty(platformdata).d do begin + if df_canvasismonochrome in gc.drawingflags then begin + rop3tab:= @inverserops3; + patrop3tab:= @inversepatrops3; + end + else begin + rop3tab:= @rasterops3; + patrop3tab:= @patrops3; + end; + + if (drawingflags * [df_monochrome,df_opaque,df_brush] = + [df_monochrome,df_brush]) then begin + if shape <> fs_rect then begin + if shape <> fs_copyarea then begin + checkgc(gc,[gcf_patternbrushvalid,gcf_selectnullpen]); + exclude(flags,gcf_rasterop); + end; + end + else begin + checkgc(gc,[gcf_patternbrushvalid]); + end; + if rop in [rop_or,rop_xor,rop_and,rop_copy,rop_set,rop_clear] then begin + case rop of + rop_or,rop_xor: begin +// setbkcolor(handle,foregroundcol); + settextcolor(handle,foregroundcol); +// settextcolor(handle,$00000000); + setbkcolor(handle,$00000000); + fill1(handle,rop); + end; + rop_and: begin +// setbkcolor(handle,foregroundcol); + settextcolor(handle,foregroundcol); +// settextcolor(handle,$00ffffff); + setbkcolor(handle,$00ffffff); + fill1(handle,rop_and); + end; + rop_set: begin +// setbkcolor(handle,$00ffffff); + settextcolor(handle,$00ffffff); +// settextcolor(handle,$00000000); + setbkcolor(handle,$00000000); + fill1(handle,rop_or); //set pattern + end + else begin +// setbkcolor(handle,$00000000); + settextcolor(handle,$00000000); +// settextcolor(handle,$00ffffff); + setbkcolor(handle,$00ffffff); + fill1(handle,rop_and); //clear pattern + if rop = rop_copy then begin +// settextcolor(handle,$00000000); + setbkcolor(handle,$00000000); +// setbkcolor(handle,foregroundcol); + settextcolor(handle,foregroundcol); + fill1(handle,rop_or); //fill pattern + end; + end; + end; + end + else begin //buffer needed + getclipbox(handle,trect(rect1)); + winrecttorect(rect1); + if (shape = fs_rect) or (shape = fs_copyarea) then begin + rect2:= prectty(buffer.buffer)^; + end + else begin + rect2.x:= maxint; + rect2.y:= maxint; + rect2.cx:= minint; + rect2.cy:= minint; + case shape of //calculate max. dims + fs_polygon: begin + po1:= buffer.buffer; + for int1:= 0 to points.count - 1 do begin + if po1^.x < rect2.x then begin + rect2.x:= po1^.x; + end; + if po1^.x > rect2.cx then begin + rect2.cx:= po1^.x; + end; + if po1^.y < rect2.y then begin + rect2.y:= po1^.y; + end; + if po1^.y > rect2.cy then begin + rect2.cy:= po1^.y; + end; + inc(po1); + end; + end; + end; + winrecttorect(rect2); + end; + if msegraphutils.intersectrect(rect1,rect2,rect1) then begin +// bmp:= gui_createpixmap(rect1.size,0,df_canvasismonochrome in drawingflags); + bmp:= gui_createpixmap(rect1.size,0,gc.kind); + if bmp <> 0 then begin + dc1:= createcompatibledc(0); + if dc1 <> 0 then begin + selectobject(dc1,bmp); + setwindoworgex(dc1,rect1.x,rect1.y,nil); + bitblt(dc1,rect1.x,rect1.y,rect1.cx,rect1.cy,handle,rect1.x,rect1.y,srccopy); //get copy + setbrushorgex(dc1,brushorg.x-rect1.x,brushorg.y-rect1.y,nil); + settextcolor(dc1,foregroundcol); + setbkcolor(dc1,backgroundcol); + fill1(dc1,rop); //draw pattern + settextcolor(dc1,$00000000); + setbkcolor(dc1,$00ffffff); + fill1(dc1,rop_notand); //erase background + settextcolor(handle,$00000000); + setbkcolor(handle,$00ffffff); + fill1(handle,rop_and); //erase pattern + bitblt(handle,rect1.x,rect1.y,rect1.cx,rect1.cy,dc1,rect1.x,rect1.y, + rop3tab^[rop_or]); //combine + deletedc(dc1); + end; + gui_freepixmap(bmp); + end; + end; + end; + end + else begin + if df_opaque in drawingflags then begin +// settextcolor(handle,backgroundcol); + setbkcolor(handle,backgroundcol); +// setbkcolor(handle,foregroundcol); + settextcolor(handle,foregroundcol); + end; + if shape <> fs_rect then begin + checkgc(gc,[gcf_colorbrushvalid,gcf_patternbrushvalid, + gcf_selectforegroundbrush,gcf_selectnullpen]); + end; + case shape of + fs_rect: begin + with prectty(buffer.buffer)^ do begin + if (df_brush in drawingflags) then begin + checkgc(gc,[gcf_colorbrushvalid,gcf_patternbrushvalid, + gcf_selectforegroundbrush]); + windows.patblt(handle,x,y,cx,cy,patrop3tab^[rop]); + end + else begin + if rop = rop_copy then begin + checkgc(gc,[gcf_colorbrushvalid]); + {$ifdef FPC} + winfillrect(handle,mrect(x,y,x+cx,y+cy),colorbrush); + {$else} + windows.fillrect(handle,mrect(x,y,x+cx,y+cy),colorbrush); + {$endif} + end + else begin + checkgc(gc,[gcf_colorbrushvalid,gcf_selectforegroundbrush]); + windows.patblt(handle,x,y,cx,cy,patrop3tab^[rop]); + end; + end; + end; + end; + fs_ellipse: begin + with trect(buffer.buffer^) do begin + windows.ellipse(gc.handle,left,top,right,bottom); + end; + end; + fs_arc: begin + with trect(buffer.buffer^) do begin + if arc.pieslice then begin + windows.pie(gc.handle,left,top,right,bottom,xstart,ystart,xend,yend); + end + else begin + windows.chord(gc.handle,left,top,right,bottom,xstart,ystart,xend,yend); + end; + end; + end; + fs_polygon: begin + windows.Polygon(gc.handle,buffer.buffer^,points.count); + end; + end; + end; + end; + end; +end; + +procedure gdi_fillrect(var drawinfo: drawinfoty); +begin + offsetrect(drawinfo); + fill(drawinfo,fs_rect); +end; + +procedure gdi_fillellipse(var drawinfo: drawinfoty); +begin + if gcf_smooth in win32gcty(drawinfo.gc.platformdata).d.flags then begin + checkgpgc(drawinfo.gc,gpfillflags); + with drawinfo,rect.rect^,win32gcty(gc.platformdata).d do begin + gdipfillellipsei(gpgraphic,gpbrush,origin.x+x-cx div 2, + origin.y+y-cy div 2,cx,cy); + end; + end + else begin + transformellipseinfo(drawinfo,true); + fill(drawinfo,fs_ellipse); + end; +end; + +procedure gdi_fillarc(var drawinfo: drawinfoty); +var + pa1: pGpPath; + arc1: gparcinfoty; +begin + if gcf_smooth in win32gcty(drawinfo.gc.platformdata).d.flags then begin + checkgpgc(drawinfo.gc,gpfillflags); + adjustgparc(drawinfo,arc1); + with drawinfo,arc1,win32gcty(gc.platformdata).d do begin + if arc.pieslice then begin + gdipfillpiei(gpgraphic,gpbrush, + rect.x,rect.y,rect.cx,rect.cy,startang,extentang); + end + else begin + gdipcreatepath(fillmodealternate,@pa1); + gdipaddpatharc(pa1,rect.x,rect.y,rect.cx,rect.cy,startang,extentang); + gdipfillpath(gpgraphic,gpbrush,pa1); + gdipdeletepath(pa1); + end; + end; + end + else begin + transformellipseinfo(drawinfo,true); + fill(drawinfo,fs_arc); + end; +end; + +procedure gdi_fillpolygon(var drawinfo: drawinfoty); +begin + transformpoints(drawinfo,false); + with win32gcty(drawinfo.gc.platformdata).d do begin + if gcf_smooth in flags then begin + checkgpgc(drawinfo.gc,gpfillflags); + gdipfillpolygon2i(gpgraphic,gpbrush,drawinfo.buffer.buffer, + drawinfo.points.count); + end + else begin + fill(drawinfo,fs_polygon); + end; + end; +end; + +procedure gdi_copyarea(var drawinfo: drawinfoty); + +var + maskbmp,stretchedbmp: pixmapty; + smaskdc,destdc: hdc; + bufferbmp: hbitmap; + rect1: rectty; + nomaskblt: boolean; + maskpos: pointty; + + procedure setintpolmode(const ahandle: hdc); + var + pt1: tpoint; + begin + with drawinfo.copyarea do begin + if (al_intpol in alignment) and not iswin95 then begin + getbrushorgex(ahandle,pt1); + setstretchbltmode(ahandle,halftone); + setbrushorgex(ahandle,pt1.x,pt1.y,nil); + end + else begin + if al_or in alignment then begin + setstretchbltmode(ahandle,blackonwhite); + end + else begin + if al_and in alignment then begin + setstretchbltmode(ahandle,whiteonblack); + end + else begin + setstretchbltmode(ahandle,coloroncolor); + end; + end; + end; + end; + end; + + procedure getstretchedbmps; + var + po1: pointty; + begin + with drawinfo,copyarea,sourcerect^,gc do begin + po1.x:= destrect^.x - rect1.x; + po1.y:= destrect^.y - rect1.y; + if mask <> nil then begin + tcanvas1(mask.canvas).checkgcstate([cs_gc]); + smaskdc:= tcanvas1(mask.canvas).fdrawinfo.gc.handle; + maskbmp:= gui_createpixmap(rect1.size,0,bmk_mono); +// maskbmp:= gui_createpixmap(rect1.size,0,true); + end + else begin + maskbmp:= 0; + end; + stretchedbmp:= createcompatiblebitmap(tcanvas1(source).fdrawinfo.gc.handle, + rect1.cx,rect1.cy); + destdc:= createcompatibledc(0); + setintpolmode(destdc); + if mask <> nil then begin + selectobject(destdc,maskbmp); + if al_nomaskscale in alignment then begin + stretchblt(destdc,po1.x,po1.y,destrect^.cx,destrect^.cy,smaskdc, + maskpos.x,maskpos.y,destrect^.cx,destrect^.cy, + rasterops3[rop_copy]); + end + else begin + stretchblt(destdc,po1.x,po1.y,destrect^.cx,destrect^.cy,smaskdc, + maskpos.x,maskpos.y,cx,cy,rasterops3[rop_copy]); + end; + end; + selectobject(destdc,stretchedbmp); + stretchblt(destdc,po1.x,po1.y,destrect^.cx,destrect^.cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,cx,cy,rasterops3[rop_copy]); + end; + end; + + procedure deletestretchedbmps; + begin + if maskbmp <> 0 then begin + if bufferbmp = 0 then begin + gui_freepixmap(maskbmp); +// deleteobject(maskbmp); + end; + end; + deletedc(destdc); + deleteobject(stretchedbmp); + end; + + procedure transfer(double: boolean = false; inverserop: boolean = false); + var + rop3tab: prop3tabty; + begin + if inverserop then begin + rop3tab:= @inverserops3; + end + else begin + rop3tab:= @rasterops3; + end; + with drawinfo,copyarea,sourcerect^,gc,win32gcty(platformdata).d do begin + if alignment * [al_stretchx,al_stretchy] = [] then begin + if mask = nil then begin + bitblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,rop3tab^[copymode]); + if double then begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + bitblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,rop3tab^[rop_or]); + end; + end + else begin + if nomaskblt then begin + tcanvas1(mask.canvas).checkgcstate([cs_gc]); + win95maskblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,tsimplebitmap1(mask).fhandle, + tcanvas1(mask.canvas).fdrawinfo.gc.handle, + maskpos.x,maskpos.y,copymode); + end + else begin + maskblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,tsimplebitmap1(mask).handle, + maskpos.x,maskpos.y, + makerop4(rop3tab^[rop_nop],rop3tab^[copymode])); + end; + if double then begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + if nomaskblt then begin + win95maskblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + maskpos.x,maskpos.y,tsimplebitmap1(mask).fhandle, + tcanvas1(mask.canvas).fdrawinfo.gc.handle,x,y,rop_or); + end + else begin + maskblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + maskpos.x,maskpos.y,tsimplebitmap1(mask).fhandle,x,y, + makerop4(rop3tab^[rop_nop],rop3tab^[rop_or])); + end; + end; + end; + end + else begin + if mask = nil then begin + stretchblt(handle,destrect^.x,destrect^.y,destrect^.cx,destrect^.cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,cx,cy,rop3tab^[copymode]); + if double then begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + stretchblt(handle,destrect^.x,destrect^.y,destrect^.cx,destrect^.cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,cx,cy,rop3tab^[rop_or]); + end; + end + else begin + getstretchedbmps; + if nomaskblt then begin + win95maskblt(handle,rect1.x,rect1.y,rect1.cx,rect1.cy,destdc, + 0,0,maskbmp,0,0,0,copymode); + end + else begin + maskblt(handle,rect1.x,rect1.y,rect1.cx,rect1.cy,destdc, + 0,0,maskbmp,0,0,makerop4(rop3tab^[rop_nop], + rop3tab^[copymode])); + end; + if double then begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + if nomaskblt then begin + win95maskblt(handle,rect1.x,rect1.y,rect1.cx,rect1.cy,destdc, + 0,0,maskbmp,0,0,0,rop_or); + end + else begin + maskblt(handle,rect1.x,rect1.y,rect1.cx,rect1.cy,destdc, + 0,0,maskbmp,0,0,makerop4(rop3tab^[rop_nop], + rop3tab^[rop_or])); + end; + end; + deletestretchedbmps; + end; + end; + end; + end; //transfer + +var + ropbefore: rasteropty; + destdcbefore: hdc; + destpointbefore: pointty; + rect1posbefore: pointty; + destbmp,colormaskbmp: hbitmap; + destbmpdc,maskdc,colormaskdc: hdc; + destimage,sourceimage,colormaskimage: imagety; + rs,gs,bs,rd,gd,bd: integer; + int1: integer; + colormask: tsimplebitmap1; + bufferbmpback: hbitmap; +// point1: tpoint; + maskbefore: tsimplebitmap; + sbmp,dbmp: hbitmap; + sdc,ddcbefore,ddc: hdc; + sourceposbefore: pointty; + pm,ps,pd,pe,po1: pointer; + scanstep: integer; +// by1,by2: byte; + wo1{,wo2}: word; + ca1,ca2: card32; + lwo1: longword; + pint1: ptrint; +begin + with drawinfo,copyarea,gc,win32gcty(platformdata).d do begin + getclipbox(handle,trect(rect1)); + winrecttorect(rect1); + if not intersectrect(destrect^,rect1,rect1) then begin + exit; + end; + + nomaskblt:= iswin95 or (kind = gck_printer); + setintpolmode(handle); + maskbefore:= mask; + maskpos:= addpoint(sourcerect^.pos,maskshift); + if (mask <> nil) and (mask.kind <> bmk_mono) then begin + colormask:= tsimplebitmap1(mask); + mask:= nil; + end + else begin + colormask:= nil; + end; + if ((longword(opacity) <> maxopacity) or (colormask <> nil)) + and not (df_canvasismonochrome in drawingflags) then begin + maskbmp:= 0; + destdcbefore:= handle; + destpointbefore:= destrect^.pos; + bufferbmp:= createcompatiblebitmap(handle,rect1.cx,rect1.cy); + destrect^.pos:= subpoint(destrect^.pos,rect1.pos); + handle:= createcompatibledc(0); + setintpolmode(handle); + selectobject(handle,bufferbmp); + rect1posbefore:= rect1.pos; + rect1.pos:= nullpoint; + end + else begin + bufferbmp:= 0; + destdcbefore:= 0; //compilerwarning + end; + if df_colorconvert in drawingflags then begin + if df_canvasismonochrome in drawingflags then begin + //convert to monochrome + setbkcolor(tcanvas1(source).fdrawinfo.gc.handle,transparentcolor); +// copymode:= rasteropty(inverserops[copymode]); + transfer; + end + else begin + if df_canvasismonochrome in + tcanvas1(source).fdrawinfo.gc.drawingflags + {source.kind = bmk_mono} then begin + //convert from monochrome + if not (df_opaque in drawingflags) then begin + if copymode = rop_xor then begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + transfer; + end + else begin + ropbefore:= copymode; + setbkcolor(handle,$ffffff); + settextcolor(handle,$000000); + copymode:= rop_and; + transfer(true); + copymode:= ropbefore; + end; + end + else begin + setbkcolor(handle,backgroundcol); + settextcolor(handle,foregroundcol); + transfer; + end; + end + else begin + sbmp:= createbitmapdata(sourcerect^.size,source.kind,ps); + sdc:= createcompatibledc(0); + selectobject(sdc,sbmp); + bitblt(sdc,0,0,sourcerect^.cx,sourcerect^.cy,source.gchandle, + sourcerect^.x,sourcerect^.y,srccopy); + dbmp:= createbitmapdata(sourcerect^.size,gc.kind,pd); + ddc:= createcompatibledc(0); + selectobject(ddc,dbmp); + scanstep:= ((sourcerect^.cx+3) div 4) * 4; + if source.kind = bmk_gray then begin + //gray to color + for int1:= 0 to sourcerect^.cy - 1 do begin + po1:= ps; + pe:= po1 + sourcerect^.cx; + repeat + wo1:= pbyte(po1)^; + plongword(pd)^:= wo1 or (wo1 shl 8) or (wo1 shl 16); + inc(po1); + inc(plongword(pd)); + until po1 >= pe; + ps:= ps + scanstep; + end; + end + else begin //color to gray + for int1:= 0 to sourcerect^.cy - 1 do begin + po1:= pd; + pe:= po1 + sourcerect^.cx; + repeat + lwo1:= plongword(ps)^; + pbyte(po1)^:= ((lwo1 and $ff) + ((lwo1 and $ff00) shr 8) + + ((lwo1 and $ff0000) shr 16)) div 3; + inc(po1); + inc(plongword(ps)); + until po1 >= pe; + pd:= pd + scanstep; + end; + end; + ddcbefore:= tcanvas1(source).fdrawinfo.gc.handle; + tcanvas1(source).fdrawinfo.gc.handle:= ddc; + sourceposbefore:= sourcerect^.pos; + sourcerect^.pos:= nullpoint; + + transfer; //gray <-> color + tcanvas1(source).fdrawinfo.gc.handle:= ddcbefore; + sourcerect^.pos:= sourceposbefore; + + deletedc(sdc); + deletedc(ddc); + deleteobject(sbmp); + deleteobject(dbmp); + end; + end; + end + else begin //no colorconvert + if df_canvasismonochrome in drawingflags then begin + setbkcolor(handle,$ffffff); + settextcolor(handle,$000000); + transfer(false,true); + end + else begin + transfer(false,false); + end; + end; + if bufferbmp <> 0 then begin //alpha operation //todo: optimze + rect1.pos:= rect1posbefore; + destbmp:= createcompatiblebitmap(handle,rect1.cx,rect1.cy); + destbmpdc:= createcompatibledc(0); + setintpolmode(destbmpdc); + selectobject(destbmpdc,destbmp); + bitblt(destbmpdc,0,0,rect1.cx,rect1.cy,destdcbefore,rect1.x,rect1.y,srccopy); + gui_pixmaptoimage(destbmp,destimage,destbmpdc); + gui_pixmaptoimage(bufferbmp,sourceimage,handle); + ps:= sourceimage.pixels; + pd:= destimage.pixels; + pint1:= ps-pd; + if colormask = nil then begin + rs:= (opacity.red*256 + 128) div 255; + gs:= (opacity.green*256 + 128) div 255; + bs:= (opacity.blue*256 + 128) div 255; + rd:= 256-rs; + gd:= 256-gs; + bd:= 256-bs; + case destimage.kind of + bmk_gray: begin + gs:= (word(rs)+word(gs)+word(bs)) div 3; + gd:= 256-gs; + for int1:= 0 to destimage.size.cy - 1 do begin + po1:= pd; + ps:= po1+pint1; + pe:= po1 + destimage.size.cx; + repeat + pbyte(po1)^:= (rd*pbyte(po1)^ + rs*pbyte(ps)^) shr 8; + inc(po1); + inc(ps); + until po1 >= pe; + pd:= pd + destimage.linebytes; + end; + end; + else begin + for int1:= 0 to destimage.length - 1 do begin + with rgbtriplety(destimage.pixels^[int1]) do begin + red:= (rd*red + rs*rgbtriplety(sourceimage.pixels^[int1]).red) shr 8; + green:= (gd*green + gs*rgbtriplety(sourceimage.pixels^[int1]).green) shr 8; + blue:= (bd*blue + bs*rgbtriplety(sourceimage.pixels^[int1]).blue) shr 8; + end; + end; + end; + end; + end + else begin + tcanvas1(colormask.canvas).checkgcstate([cs_gc]); + colormaskbmp:= gui_createpixmap(rect1.size,0, + tcanvas1(colormask.canvas).fdrawinfo.gc.kind); + colormaskdc:= createcompatibledc(0); + setintpolmode(colormaskdc); + deleteobject(selectobject(colormaskdc,colormaskbmp)); + if al_nomaskscale in alignment then begin + with destrect^ do begin + stretchblt(colormaskdc,x,y,cx,cy, + tcanvas1(colormask.canvas).fdrawinfo.gc.handle, + maskpos.x,maskpos.y,cx,cy, + rasterops3[rop_copy]); + end; + end + else begin + with sourcerect^ do begin + stretchblt(colormaskdc,destrect^.x,destrect^.y,destrect^.cx,destrect^.cy, + tcanvas1(colormask.canvas).fdrawinfo.gc.handle, + maskpos.x,maskpos.y,cx,cy, + rasterops3[rop_copy]); + end; + end; + gui_pixmaptoimage(colormaskbmp,colormaskimage,colormaskdc); + pm:= colormaskimage.pixels; + case colormaskimage.kind of + bmk_gray: begin + rs:= ((word(opacity.red)+word(opacity.green)+word(opacity.blue))*257) div + (3*255); + //-> 0..256 + case destimage.kind of + bmk_gray: begin + for int1:= 0 to destimage.size.cy - 1 do begin + po1:= pd; + ps:= po1 + pint1; + pe:= po1 + destimage.size.cx; + while po1 < pe do begin + ca1:= pbyte(pm)^*rs; + ca2:= 256*256-ca1; + pbyte(po1)^:= (pbyte(po1)^*ca2 + pbyte(ps)^*ca1) div (256*256); + inc(po1); + inc(ps); + inc(pm); + end; + pd:= pd + destimage.linebytes; + end; + end; + else begin + for int1:= 0 to destimage.size.cy - 1 do begin + po1:= pm; + pe:= po1 + colormaskimage.size.cx; + repeat + ca1:= pbyte(po1)^*rs; + ca2:= 256*256-ca1; + with prgbtriplety(pd)^ do begin + red:= (ca2*red + ca1*prgbtriplety(ps)^.red) div (256*256); + green:= (ca2*green + ca1*prgbtriplety(ps)^.green) div (256*256); + blue:= (ca2*blue + ca1*prgbtriplety(ps)^.blue) div (256*256); + end; + inc(po1); + inc(ps,4); + inc(pd,4); + until po1 >= pe; + pm:= pm + colormaskimage.linebytes; + end; + end; + end; + end; + else begin //bmk_rgb + case destimage.kind of + bmk_gray: begin + rs:= ((word(opacity.red)+word(opacity.green)+ + word(opacity.blue))*257) div (3*255); + //->0..256 + for int1:= 0 to destimage.size.cy - 1 do begin + po1:= pd; + ps:= po1 + pint1; + pe:= po1 + destimage.size.cx; + repeat + with prgbtriplety(pm)^ do begin + ca1:= (rs*(word(red)+word(green)+word(blue))); + end; + ca2:= 3*256*256-ca1; + pbyte(po1)^:= (pbyte(po1)^*ca2 + pbyte(ps)^*ca1) div (3*256*256); + inc(po1); + inc(ps); + inc(pm,4); + until po1 >= pe; + pd:= pd + destimage.linebytes; + end; + end; + else begin //bmk_rgb + rs:= (word(opacity.red)*257) div (255); //->0..256 + gs:= (word(opacity.green)*257) div (255); //->0..256 + bs:= (word(opacity.blue)*257) div (255); //->0..256 + po1:= pd; + ps:= po1+pint1; + pe:= po1+destimage.length*4; + while po1 < pe do begin + with prgbtriplety(po1)^ do begin + ca1:= prgbtriplety(pm)^.red*rs; + red:= (prgbtriplety(po1)^.red*(256*256-ca1)+ + (prgbtriplety(ps)^.red*ca1)) div (256*256); + ca1:= prgbtriplety(pm)^.green*gs; + green:= (prgbtriplety(po1)^.green*(256*256-ca1)+ + (prgbtriplety(ps)^.green*ca1)) div (256*256); + ca1:= prgbtriplety(pm)^.blue*bs; + blue:= (prgbtriplety(po1)^.blue*(256*256-ca1)+ + (prgbtriplety(ps)^.blue*ca1)) div (256*256); + end; + inc(po1,4); + inc(ps,4); + inc(pm,4); + end; + { + for int1:= 0 to destimage.length - 1 do begin + with rgbtriplety(destimage.pixels[int1]) do begin + red:= (byte(256 - + rgbtriplety(colormaskimage.pixels^[int1]).red) * red + + rgbtriplety(colormaskimage.pixels^[int1]).red * + rgbtriplety(sourceimage.pixels^[int1]).red) div 256); + green:= (byte(255 - + rgbtriplety(colormaskimage.pixels^[int1]).green) * green + + rgbtriplety(colormaskimage.pixels^[int1]).green * + rgbtriplety(sourceimage.pixels^[int1]).green) div byte(255); + blue:= (byte(255 - + rgbtriplety(colormaskimage.pixels^[int1]).blue) * blue + + rgbtriplety(colormaskimage.pixels^[int1]).blue * + rgbtriplety(sourceimage.pixels^[int1]).blue) div byte(255); + end; + end; + } + end; + end; + end; + end; + gui_freeimagemem(colormaskimage.pixels); + deletedc(colormaskdc); + deleteobject(colormaskbmp); + end; + bufferbmpback:= bufferbmp; + gui_imagetopixmap(destimage,pixmapty(bufferbmp),handle); +//{$ifdef mse_debuggdi} +// dec(pixmapcount); +//{$endif} + gui_freeimagemem(destimage.pixels); + gui_freeimagemem(sourceimage.pixels); + if mask <> nil then begin + if maskbmp <> 0 then begin + if nomaskblt then begin + maskdc:= createcompatibledc(0); + selectobject(maskdc,maskbmp); + settextcolor(destdcbefore,$000000); + setbkcolor(destdcbefore,$ffffff); + bitblt(destdcbefore,rect1.x,rect1.y,rect1.cx,rect1.cy, + maskdc,0,0,rasterops3[rop_and]); + settextcolor(handle,$ffffff); + setbkcolor(handle,$000000); + bitblt(handle,0,0,rect1.cx,rect1.cy,maskdc,rect1.x,rect1.y,rasterops3[rop_and]); + bitblt(destdcbefore,rect1.x,rect1.y,rect1.cx,rect1.cy, + handle,0,0,rasterops3[rop_or]); + deletedc(maskdc); + end + else begin + maskblt(destdcbefore,rect1.x,rect1.y, + rect1.cx,rect1.cy,handle,0,0,maskbmp,0,0, + makerop4(rasterops3[rop_nop],srccopy)); + end; + deleteobject(maskbmp); + end + else begin + if nomaskblt then begin + tcanvas1(mask.canvas).checkgcstate([cs_gc]); + smaskdc:= tcanvas1(mask.canvas).fdrawinfo.gc.handle; + settextcolor(destdcbefore,$000000); + setbkcolor(destdcbefore,$ffffff); + bitblt(destdcbefore,rect1.x,rect1.y,rect1.cx,rect1.cy, + smaskdc,sourcerect^.x-destrect^.x, + sourcerect^.y-destrect^.y,rasterops3[rop_and]); + settextcolor(handle,$ffffff); + setbkcolor(handle,$000000); + bitblt(handle,0,0,destrect^.cx,destrect^.cy,smaskdc, + sourcerect^.x-destrect^.x,sourcerect^.y-destrect^.y, + rasterops3[rop_and]); + bitblt(destdcbefore,rect1.x,rect1.y,rect1.cx,rect1.cy, + handle,0,0,rasterops3[rop_or]); + end + else begin + maskblt(destdcbefore,rect1.x,rect1.y, + rect1.cx,rect1.cy,handle, + 0,0,tsimplebitmap1(mask).handle, + sourcerect^.x-destrect^.x,sourcerect^.y-destrect^.y, + makerop4(rasterops3[rop_nop],srccopy)); + end; + end; + end + else begin + bitblt(destdcbefore,rect1.x,rect1.y,rect1.cx, + rect1.cy,handle,0,0,srccopy); + end; + deletedc(handle); +// deleteobject(bufferbmp); + gui_freepixmap(bufferbmp); + deleteobject(bufferbmpback); + handle:= destdcbefore; + destrect^.pos:= destpointbefore; + deletedc(destbmpdc); + deleteobject(destbmp); + end; + mask:= maskbefore; + end; +end; + +procedure gdi_getimage(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_fonthasglyph(var drawinfo: drawinfoty); +begin + with drawinfo,fonthasglyph do begin + hasglyph:= true; + end; +end; + +var + defaultfontinfo: logfont; +type + charsetinfoty = record + name: string; + code: integer; + end; + charsetinfoaty = array[0..18] of charsetinfoty; + +const + charsets: charsetinfoaty = ( + (name: 'ANSI'; code: 0), + (name: 'DEFAULT'; code: 1), + (name: 'SYMBOL'; code: 2), + (name: 'SHIFTJIS'; code: $80), + (name: 'HANGEUL'; code: 129), + (name: 'GB2312'; code: 134), + (name: 'CHINESEBIG5'; code: 136), + (name: 'OEM'; code: 255), + (name: 'JOHAB'; code: 130), + (name: 'HEBREW'; code: 177), + (name: 'ARABIC'; code: 178), + (name: 'GREEK'; code: 161), + (name: 'TURKISH'; code: 162), + (name: 'VIETNAMESE'; code: 163), + (name: 'THAI'; code: 222), + (name: 'EASTEUROPE'; code: 238), + (name: 'RUSSIAN'; code: 204), + (name: 'MAC'; code: 77), + (name: 'BALTIC'; code: 186)); + +type + pboolean = ^boolean; + +{$ifdef FPC} +function fontenumcallback(var _para1:ENUMLOGFONTEX; + var _para2:NEWTEXTMETRICEX; _para3:longint; _para4:LPARAM):longint; stdcall; +{$else} +function fontenumcallback(var _para1:ENUMLOGFONTEX; + var _para2:TNEWTEXTMETRICEXa; _para3:longint; _para4:LPARAM):longint; stdcall; +{$endif} +begin + pboolean(_para4)^:= true; + result:= 0; +end; + + +procedure gdi32initdefaultfont; +var + dc1: hdc; + bo1: boolean; +begin + fillchar(defaultfontinfo,sizeof(defaultfontinfo),0); + defaultfontinfo.lfHeight:= -11; + bo1:= false; + defaultfontinfo.lfFaceName:= defaultfontname; + dc1:= getdc(0); + {$ifdef FPC} + enumfontfamiliesex(dc1,@defaultfontinfo,@fontenumcallback,ptruint(@bo1),0); + {$else} + enumfontfamiliesex(dc1,defaultfontinfo,@fontenumcallback,ptruint(@bo1),0); + {$endif} + if not bo1 then begin + defaultfontinfo.lfFaceName:= 'MS Sans Serif'; + end; + releasedc(0,dc1); +end; + +function dogetfont(var drawinfo: drawinfoty; const ahighres: boolean): boolean; + +var + dc1: hdc; //printer gc is invalid -> create temporary gc + fontbefore: hfont; + font1: hfont; + + procedure closedc; + begin + selectobject(dc1,fontbefore); + releasedc(0,dc1); + with drawinfo.getfont.fontdata^ do begin + if (font1 <> font) and (font1 <> fonthighres) then begin + deleteobject(font1); + end; + end; + end; + +var + fontinfo1: logfont; +// textmetricsw: ttextmetricw; + textmetricsa: ttextmetrica; + str1: string; + int1: integer; +// ar1: array[0..255] of abc; + height1,width1: integer; + rea1: real; + +label + endlab; + +begin + result:= false; + with drawinfo.getfont.fontdata^ do begin + height1:= (h.d.height + fontsizeroundvalue) shr fontsizeshift; + width1:= (h.d.width + fontsizeroundvalue) shr fontsizeshift; + fontinfo1:= defaultfontinfo; + with fontinfo1 do begin + if height1 <> 0 then begin + lfheight:= -height1; //use character height + end; + if h.d.xscale = 1 then begin + if width1 <> 0 then begin + lfwidth:= (width1 + 5) div 10; + if lfwidth = 0 then begin + lfwidth:= 1; + end; + lfoutprecision:= out_tt_only_precis; + end; + end; + if fs_bold in h.d.style then begin + lfweight:= fw_bold; + end; + if fs_italic in h.d.style then begin + lfitalic:= 1; + end; + if (h.d.pitchoptions <> []) or (h.d.familyoptions <> []) then begin + lffacename[0]:= #0; + end + else begin + if (h.name <> '') then begin + strlcopy(@lffacename,pchar(h.name),sizeof(lffacename)-1); + end; + end; + if h.charset <> '' then begin + str1:= uppercase(h.charset); + for int1:= 0 to high(charsets) do begin + if charsets[int1].name = str1 then begin + lfcharset:= charsets[int1].code; + break; + end; + end; + end; + if foo_fixed in h.d.pitchoptions then begin + lfpitchandfamily:= lfpitchandfamily or fixed_pitch; + end + else begin + if foo_proportional in h.d.pitchoptions then begin + lfpitchandfamily:= lfpitchandfamily or variable_pitch; + end + end; + if foo_helvetica in h.d.familyoptions then begin + lfpitchandfamily:= lfpitchandfamily or ff_swiss; + end + else begin + if foo_roman in h.d.familyoptions then begin + lfpitchandfamily:= lfpitchandfamily or ff_roman; + end + else begin + if foo_script in h.d.familyoptions then begin + lfpitchandfamily:= lfpitchandfamily or ff_script; + end + else begin + if foo_decorative in h.d.familyoptions then begin + lfpitchandfamily:= lfpitchandfamily or ff_decorative; + end + end; + end; + end; + if (foo_antialiased2 in h.d.antialiasedoptions) then begin + if cancleartype then begin + lfquality:= cleartype_quality; + end + else begin + lfquality:= antialiased_quality; + end; + end + else begin + if foo_antialiased in h.d.antialiasedoptions then begin + lfquality:= antialiased_quality; + end + else begin + if foo_nonantialiased in h.d.antialiasedoptions then begin + lfquality:= nonantialiased_quality; + end; + end; + end; + if h.d.rotation <> 0 then begin + int1:= round(h.d.rotation*((10*360)/(2*pi))); + lfescapement:= int1; + lforientation:= int1; + lfoutprecision:= out_tt_only_precis; + end; + if ahighres then begin + lfheight:= lfheight * highresfontfakt; + lfwidth:= lfwidth * highresfontfakt; + end; + + font1:= createfontindirect({$ifdef FPC}@{$endif}fontinfo1); + end; + if font1 = 0 then begin + fontinfo1.lfFaceName:= defaultfontinfo.lfFaceName; + font1:= createfontindirect({$ifdef FPC}@{$endif}fontinfo1); + if font1 = 0 then begin + if ahighres then begin + exit; //no highres font available + end; + font1:= createfontindirect({$ifdef FPC}@{$endif}defaultfontinfo); + end; + end; + if font1 <> 0 then begin + dc1:= getdc(0); + fontbefore:= selectobject(dc1,font1); + if not gettextmetricsa(dc1,{$ifdef FPC}@{$endif}textmetricsa) then begin + goto endlab; + end; + if h.d.xscale <> 1 then begin + closedc; + int1:= h.d.width; + rea1:= h.d.xscale; + with win32fontdataty(platformdata) do begin + if ahighres then begin + fontinfo1.lfwidth:= ((xwidth+5) div 10) shl highresfontshift; + //round up + fonthighres:= createfontindirect({$ifdef FPC}@{$endif}fontinfo1); + result:= fonthighres <> 0; + end + else begin + xwidth:= round(h.d.xscale * textmetricsa.tmavecharwidth*10); + h.d.width:= xwidth shl fontsizeshift; + h.d.xscale:= 1.0; + result:= dogetfont(drawinfo,false); + end; + end; + h.d.width:= int1; //restore + h.d.xscale:= rea1; + exit; + end; + with win32fontdataty(platformdata) do begin + if ahighres then begin + fonthighres:= font1; + goto endlab; + end; + font:= font1; + ascent:= textmetricsa.tmAscent; + descent:= textmetricsa.tmDescent; + linespacing:= textmetricsa.tmheight + textmetricsa.tmexternalleading; + realheight:= textmetricsa.tmheight; + overhang:= textmetricsa.tmOverhang; + if textmetricsa.tmpitchandfamily and tmpf_truetype <> 0 then begin + caretshift:= 0; + end + else begin + caretshift:= 1; + end; + if iswin95 then begin + new(charwidths); + (* + if false {getcharabcwidths(dc1,0,255,ar1)} then begin + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + charwidths^[int1]:= abca + integer(abcb) + abcc; + end; + end; + end + else begin //no truetype font + *) + if not getcharwidthw(dc1,0,255,charwidths^) then begin + dispose(charwidths); + goto endlab; + end; + if Overhang <> 0 then begin + for int1:= 0 to high(charwidths^) do begin + dec(charwidths^[int1],Overhang); + end; + end; +// end; + end + else begin + { + new(charwidths); + if not getcharwidth32w(dc1,0,255,charwidths^) then begin + dispose(charwidths); + closedc; + exit; + end; + } + end; + end; + result:= true; + end; + end; +endlab: +{$ifdef mse_debuggdi} + if result then begin + inc(fontcount); + end; +{$endif} + closedc; +end; + +procedure gdi_getfonthighres(var drawinfo: drawinfoty); +begin + dogetfont(drawinfo,true); +end; + +procedure gdi_getfont(var drawinfo: drawinfoty); +begin + drawinfo.getfont.ok:= dogetfont(drawinfo,false); +end; + +procedure gdi_freefontdata(var drawinfo: drawinfoty); +begin + with drawinfo.getfont.fontdata^,win32fontdataty(platformdata) do begin + if charwidths <> nil then begin + dispose(charwidths); + end; + if font <> 0 then begin +{$ifdef mse_debuggdi} + dec(fontcount); +{$endif} + deleteobject(font); + end; + if fonthighres <> 0 then begin +{$ifdef mse_debuggdi} + dec(fontcount); +{$endif} + deleteobject(fonthighres); + end; + end; +end; + +procedure gdi_gettext16width(var drawinfo: drawinfoty); +label //todo: kerning? + endlab; +var + int1,int2: integer; + po1: pmsechar; + wo1: word; + widths: pcharwidthsty; + overha: integer; + fh1: hfont; + gc1: hdc; + gcpresults: tgcpresultsw; +begin + with drawinfo.gettext16width do begin + if drawinfo.gc.handle = invalidgchandle then begin + gc1:= getdc(0); //use default dc + end + else begin + gc1:= drawinfo.gc.handle; + end; + fh1:= selectobject(gc1,fontdata^.font); + if fh1 <> 0 then begin + if not iswin95 then begin + fillchar(gcpresults,sizeof(gcpresults),0); + gcpresults.lstructsize:= sizeof(gcpresults); + gcpresults.nglyphs:= count; + {$ifdef FPC} + result:= getcharacterplacementw(gc1,text,count,0,@gcpresults,0) and $ffff; + {$else} + result:= getcharacterplacementw(gc1,text,count,0,gcpresults,0) and $ffff; + {$endif} + end + else begin + result:= 0; + int1:= count; + po1:= text; + with win32fontdataty(fontdata^.platformdata) do begin + widths:= charwidths; + overha:= overhang; + end; + while int1 > 0 do begin + wo1:= word(po1^); + if wo1 < 256 then begin + inc(result,widths^[wo1]); + end + else begin + int2:= 0; + if iswin95 then begin + if not getcharwidthw(gc1,wo1,wo1,int2) then begin + result:= -1; + goto endlab; + end; + dec(int2,overha); + end + else begin + if not getcharwidth32w(gc1,wo1,wo1,int2) then begin + result:= -1; + goto endlab; + end; + end; + inc(result,int2); + end; + dec(int1); + inc(po1); + end; + end; + end + else begin + result:= -1; + end; +endlab: + if fh1 <> 0 then begin + selectobject(gc1,fh1); + end; + if drawinfo.gc.handle = invalidgchandle then begin + releasedc(0,gc1); + end; + end; +end; + +procedure gdi_getchar16widths(var drawinfo: drawinfoty); +label //todo: kerning? + endlab; +var + int1,int2: integer; + po1,pe: pmsechar; + po2,pde: {$ifdef FPC}objpas.{$endif}pinteger; + wo1: word; + widths: pcharwidthsty; + overha: integer; + ahandle: thandle; + gc1: hdc; + gcpresults: tgcpresultsw; +// fo1: hfont; + hires: boolean; +begin +// result:= gde_fontmetrics; + with drawinfo.getchar16widths do begin + hires:= (df_highresfont in drawinfo.gc.drawingflags) and + (fontdata^.fonthighres <> 0); + if (drawinfo.gc.handle = invalidgchandle) or hires then begin + gc1:= getdc(0); //use default dc + end + else begin + gc1:= drawinfo.gc.handle; + end; + if hires then begin + ahandle:= selectobject(gc1,fontdata^.fonthighres); + end + else begin + ahandle:= selectobject(gc1,fontdata^.font); + end; + if ahandle <> 0 then begin + if not iswin95 then begin + fillchar(gcpresults,sizeof(gcpresults),0); + gcpresults.lstructsize:= sizeof(gcpresults); + gcpresults.lpdx:= pointer(resultpo); + gcpresults.nglyphs:= count; + {$ifdef FPC} + getcharacterplacementw(gc1,text,count,0,@gcpresults,0); + {$else} + getcharacterplacementw(gc1,text,count,0,gcpresults,0); + {$endif} + if hires then begin + po2:= resultpo; + int2:= highresfontfakt div 2; //round up + for int1:= 0 to count - 1 do begin + int2:= int2 + po2^; + po2^:= int2 shr highresfontshift; + int2:= int2 and highresfontmask; + inc(po2); + end; + end; + int1:= count - gcpresults.nglyphs; + if int1 > 0 then begin //has surrogate pairs, + //insert dummy 0's for low pair part + //not tested! + po1:= text; + pe:= text + count; + po2:= resultpo; + pde:= po2 + count; + while (po1 < pe) and (int1 > 0) do begin + if card16(po1^) and $fc00 = $d800 then begin + inc(po1); + if card16(po1^) and $fc00 = $dc00 then begin + inc(po2); + move(po2^,(po2+1)^,((pde-po2)-int1)*sizeof(po2^)); + po2^:= 0; + dec(int1); + end; + end; + inc(po1); + inc(po2); + end; + end; + end + else begin + po1:= text; + po2:= resultpo; + with win32fontdataty(fontdata^.platformdata) do begin + widths:= charwidths; + overha:= overhang; + end; + int1:= count; + while int1 > 0 do begin + wo1:= word(po1^); + if wo1 < 256 then begin + po2^:= widths^[wo1]; + end + else begin + if iswin95 then begin + if not getcharwidthw(gc1,wo1,wo1,po2^) then begin + goto endlab; + end; + dec(po2^,overha); + end + else begin + if not getcharwidth32w(gc1,wo1,wo1,po2^) then begin + goto endlab; + end; + end; + end; + inc(po1); + inc(po2); + dec(int1); + end; + end; +// selectobject(gc1,ahandle); +// result:= gde_ok; + end; + end; + +endlab: + if ahandle <> 0 then begin + selectobject(gc1,ahandle); + end; + if (drawinfo.gc.handle = invalidgchandle) or hires then begin + releasedc(0,gc1); + end; +end; + +procedure gdi_getfontmetrics(var drawinfo: drawinfoty); +var + data: abc; + bo1: boolean; + ahandle: thandle; + +begin +// result:= gde_fontmetrics; + with drawinfo,drawinfo.getfontmetrics do begin + ahandle:= selectobject(gc.handle,fontdata^.font); + if ahandle <> 0 then begin + fillchar(data,sizeof(data),0); + if iswin95 then begin + bo1:= getcharabcwidthsw(gc.handle,longword(char),longword(char),data); + { + if ord(char) < 256 then begin + bo1:= getcharabcwidthsa(gc.handle,longword(char),longword(char),data); + end + else begin + bo1:= false; + end; + } + end + else begin + bo1:= getcharabcwidthsw(gc.handle,longword(char),longword(char),data); + end; + if not bo1 then begin + if iswin95 then begin + bo1:= getcharwidthw(drawinfo.gc.handle,longword(char),longword(char),data.abcb); + dec(data.abcB,win32fontdataty(fontdata^.platformdata).overhang); + end + else begin + bo1:= getcharwidth32w(drawinfo.gc.handle,longword(char),longword(char),data.abcb); + end; + data.abca:= 0; + data.abcC:= 0; + end; + if bo1 then begin + with resultpo^ do begin + leftbearing:= data.abca; + width:= data.abca + integer(data.abcb) + data.abcc; + rightbearing:= data.abcc; + end; + selectobject(gc.handle,ahandle); +// result:= gde_ok; + end; + end; + end; +end; + +procedure init; +var + brushinfo: tlogbrush; +begin + nullpen:= createpen(ps_null,0,0); + fillchar(brushinfo,sizeof(brushinfo),0); + brushinfo.lbStyle:= bs_null; + nullbrush:= createbrushindirect(brushinfo); +end; + +procedure deinit; +begin + deleteobject(nullpen); + nullpen:= 0; + deleteobject(nullbrush); + nullbrush:= 0; +{ + if graypalette <> 0 then begin + deleteobject(graypalette); + graypalette:= 0; + end; +} + if fhasgdiplus then begin + releasegdiplus; + end; +end; + +const + gdifunctions: gdifunctionaty = ( + {$ifdef FPC}@{$endif}gdi_creategc, + {$ifdef FPC}@{$endif}gdi_destroygc, + {$ifdef FPC}@{$endif}gdi_changegc, + {$ifdef FPC}@{$endif}gdi_createpixmap, + {$ifdef FPC}@{$endif}gdi_pixmaptoimage, + {$ifdef FPC}@{$endif}gdi_imagetopixmap, + {$ifdef FPC}@{$endif}gdi_getcanvasclass, + {$ifdef FPC}@{$endif}gdi_endpaint, + {$ifdef FPC}@{$endif}gdi_flush, + {$ifdef FPC}@{$endif}gdi_movewindowrect, + {$ifdef FPC}@{$endif}gdi_drawlines, + {$ifdef FPC}@{$endif}gdi_drawlinesegments, + {$ifdef FPC}@{$endif}gdi_drawellipse, + {$ifdef FPC}@{$endif}gdi_drawarc, + {$ifdef FPC}@{$endif}gdi_fillrect, + {$ifdef FPC}@{$endif}gdi_fillellipse, + {$ifdef FPC}@{$endif}gdi_fillarc, + {$ifdef FPC}@{$endif}gdi_fillpolygon, +// {$ifdef FPC}@{$endif}gdi_drawstring, + {$ifdef FPC}@{$endif}gdi_drawstring16, + {$ifdef FPC}@{$endif}gdi_setcliporigin, + {$ifdef FPC}@{$endif}gdi_createemptyregion, + {$ifdef FPC}@{$endif}gdi_createrectregion, + {$ifdef FPC}@{$endif}gdi_createrectsregion, + {$ifdef FPC}@{$endif}gdi_destroyregion, + {$ifdef FPC}@{$endif}gdi_copyregion, + {$ifdef FPC}@{$endif}gdi_moveregion, + {$ifdef FPC}@{$endif}gdi_regionisempty, + {$ifdef FPC}@{$endif}gdi_regionclipbox, + {$ifdef FPC}@{$endif}gdi_regsubrect, + {$ifdef FPC}@{$endif}gdi_regsubregion, + {$ifdef FPC}@{$endif}gdi_regaddrect, + {$ifdef FPC}@{$endif}gdi_regaddregion, + {$ifdef FPC}@{$endif}gdi_regintersectrect, + {$ifdef FPC}@{$endif}gdi_regintersectregion, + {$ifdef FPC}@{$endif}gdi_copyarea, + {$ifdef FPC}@{$endif}gdi_getimage, + {$ifdef FPC}@{$endif}gdi_fonthasglyph, + {$ifdef FPC}@{$endif}gdi_getfont, + {$ifdef FPC}@{$endif}gdi_getfonthighres, + {$ifdef FPC}@{$endif}gdi_freefontdata, + {$ifdef FPC}@{$endif}gdi_gettext16width, + {$ifdef FPC}@{$endif}gdi_getchar16widths, + {$ifdef FPC}@{$endif}gdi_getfontmetrics +); + +//var +// gdinumber: integer; + +function gdi32getgdifuncs: pgdifunctionaty; +begin + result:= @gdifunctions; +end; +{ +function gdi32getgdinum: integer; +begin + result:= gdinumber; +end; + +initialization + gdinumber:= registergdi(gdi32getgdifuncs); +} +end. diff --git a/mseide-msegui/lib/common/graphics/msegdiplus.pas b/mseide-msegui/lib/common/graphics/msegdiplus.pas new file mode 100644 index 0000000..71a294e --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msegdiplus.pas @@ -0,0 +1,495 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegdiplus; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + windows,msestrings,msectypes,sysutils,msetypes; + +const + gdipluslib: array[0..0] of filenamety = ('gdiplus.dll'); + +type +{$packrecords c}{$packenum 4} + + GpStatus = ( + Ok = 0, + GenericError = 1, + InvalidParameter = 2, + OutOfMemory = 3, + ObjectBusy = 4, + InsufficientBuffer = 5, + NotImplemented = 6, + Win32Error = 7, + WrongState = 8, + Aborted = 9, + FileNotFound = 10, + ValueOverflow = 11, + AccessDenied = 12, + UnknownImageFormat = 13, + FontFamilyNotFound = 14, + FontStyleNotFound = 15, + NotTrueTypeFont = 16, + UnsupportedGdiplusVersion = 17, + GdiplusNotInitialized = 18, + PropertyNotFound = 19, + PropertyNotSupported = 20 + ); + +const + gdipluserrormessages: array[GpStatus] of string = ( + 'Ok', + 'GenericError', + 'InvalidParameter', + 'OutOfMemory', + 'ObjectBusy', + 'InsufficientBuffer', + 'NotImplemented', + 'Win32Error', + 'WrongState', + 'Aborted', + 'FileNotFound', + 'ValueOverflow', + 'AccessDenied', + 'UnknownImageFormat', + 'FontFamilyNotFound', + 'FontStyleNotFound', + 'NotTrueTypeFont', + 'UnsupportedGdiplusVersion', + 'GdiplusNotInitialized', + 'PropertyNotFound', + 'PropertyNotSupported' + ); +type + egdiplus = class(exception) + public + constructor create(const aerror: GpStatus); + end; + + DebugEventLevel = ( + DebugEventLevelFatal, + DebugEventLevelWarning + ); + + DebugEventProc = procedure(level: DebugEventLevel; + message: pchar); stdcall; + GdiplusStartupInput = record + GdiplusVersion: cUINT32; + DebugEventCallback: DebugEventProc; + SuppressBackgroundThread: BOOL; + SuppressExternalCodecs: BOOL; + end; + pGdiplusStartupinput = ^GdiplusStartupinput; + + NotificationHookProc = function(token: ppointer): GpStatus; stdcall; + NotificationUnhookProc = procedure(token: pointer); stdcall; + + GdiplusStartupOutput = record + NotificationHook: NotificationHookProc; + NotificationUnhook: NotificationUnhookProc; + end; + pGdiplusStartupoutput = ^GdiplusStartupoutput; + + GpGraphics = record end;//opaque + PGpGraphics = ^GpGraphics; + PPGpGraphics = ^PGpGraphics; + + INT = cint; + REAL = single; + GpREAL = REAL; + pReal = ^REAL; + ARGB = uint32; + pARGB = ^ARGB; + GpPoint = record + X: INT; + Y: INT; + end; + pGpPoint = ^GpPoint; + +const + PaletteFlagsHasAlpha = $0001; + PaletteFlagsGrayScale = $0002; + PaletteFlagsHalftone = $0004; + +type + ColorPalette = record + Flags: UINT; // Palette flags + Count: UINT; // Number of color entries + Entries: array[0..0] of ARGB; // Palette color entries + end; + pColorPalette = ^ColorPalette; + + GpImage = record end; + pGpImage = ^GpImage; + GpBitmap = record end; + pGpBitmap = ^GpBitmap; + ppGpBitmap = ^pGpBitmap; + GpTexture = record end; + pGpTexture = ^GpTexture; + ppGpTexture = ^pGpTexture; + GpBrush = record end; + pGpBrush = ^GpBrush; + GpSolidFill = record end; + pGpSolidFill = ^GpSolidFill; + ppGpSolidFill = ^pGpSolidFill; + GpPen = record end; + pGpPen = ^GpPen; + ppGpPen = ^pGpPen; + GpPath = record end; + pGpPath = ^GpPath; + ppGpPath = ^pGpPath; + GpRegion = record end; + pGpRegion = ^GpRegion; + ppGpRegion = ^pGpRegion; + + QualityMode = ( + QualityModeInvalid = -1, + QualityModeDefault = 0, + QualityModeLow = 1, // Best performance + QualityModeHigh = 2 // Best rendering quality + ); + pQualityMode = ^QualityMode; + + SmoothingMode = ( + SmoothingModeInvalid = ord(QualityModeInvalid), + SmoothingModeDefault = ord(QualityModeDefault), + SmoothingModeHighSpeed = ord(QualityModeLow), + SmoothingModeHighQuality = ord(QualityModeHigh), + SmoothingModeNone, + SmoothingModeAntiAlias + ); + pSmoothingMode = ^SmoothingMode; + + WrapMode = ( + WrapModeTile, // 0 + WrapModeTileFlipX, // 1 + WrapModeTileFlipY, // 2 + WrapModeTileFlipXY, // 3 + WrapModeClamp // 4 + ); + + GpUnit = ( + UnitWorld, // 0 -- World coordinate (non-physical unit) + UnitDisplay, // 1 -- Variable -- for PageTransform only + UnitPixel, // 2 -- Each unit is one device pixel. + UnitPoint, // 3 -- Each unit is a printer's point, or 1/72 inch. + UnitInch, // 4 -- Each unit is 1 inch. + UnitDocument, // 5 -- Each unit is 1/300 inch. + UnitMillimeter // 6 -- Each unit is 1 millimeter. + ); + GpMatrixOrder = ( + MatrixOrderPrepend = 0, + MatrixOrderAppend = 1 +); + + GpFillMode = ( + FillModeAlternate, // 0 + FillModeWinding // 1 + ); + + GpPenAlignment = ( + PenAlignmentCenter = 0, + PenAlignmentInset = 1 +); + GpLineCap = ( + LineCapFlat = 0, + LineCapSquare = 1, + LineCapRound = 2, + LineCapTriangle = 3, + + LineCapNoAnchor = $10, // corresponds to flat cap + LineCapSquareAnchor = $11, // corresponds to square cap + LineCapRoundAnchor = $12, // corresponds to round cap + LineCapDiamondAnchor = $13, // corresponds to triangle cap + LineCapArrowAnchor = $14, // no correspondence + + LineCapCustom = $ff // custom cap + +// LineCapAnchorMask = 0xf0 // mask to check for anchor or not. + ); + + GpDashCap = ( + DashCapFlat = 0, + DashCapRound = 2, + DashCapTriangle = 3 + ); + + GpDashStyle = ( + DashStyleSolid, // 0 + DashStyleDash, // 1 + DashStyleDot, // 2 + DashStyleDashDot, // 3 + DashStyleDashDotDot, // 4 + DashStyleCustom // 5 +); + + GpLineJoin = ( + LineJoinMiter = 0, + LineJoinBevel = 1, + LineJoinRound = 2, + LineJoinMiterClipped = 3 + ); + + GpCombineMode = ( + CombineModeReplace, // 0 + CombineModeIntersect, // 1 + CombineModeUnion, // 2 + CombineModeXor, // 3 + CombineModeExclude, // 4 + CombineModeComplement // 5 (Exclude From) + ); + + GpFlushIntention = ( + FlushIntentionFlush = 0, // Flush all batched rendering operations + FlushIntentionSync = 1 // Flush all batched rendering operations + // and wait for them to complete + ); + + GpPixelOffsetMode = ( + PixelOffsetModeInvalid = ord(QualityModeInvalid), + PixelOffsetModeDefault = ord(QualityModeDefault), + PixelOffsetModeHighSpeed = ord(QualityModeLow), + PixelOffsetModeHighQuality = ord(QualityModeHigh), + PixelOffsetModeNone, // No pixel offset + PixelOffsetModeHalf // Offset by -0.5, -0.5 for fast anti-alias perf +); +var + GdiplusStartup: function(token: ppointer; input: pGdiplusStartupInput; + output: pGdiplusStartupOutput): GpStatus; stdcall; + GdiplusShutdown: function(token: pointer): GpStatus; stdcall; + + GdipFree: function(ptr: pointer): GpStatus; stdcall; + GdipCreateFromHDC: function(hdc_: HDC; + graphics: PPGpGraphics): GpStatus; stdcall; + GdipCreateFromHDC2: function(hdc_: HDC; hDevice: HANDLE; + graphics: ppGpGraphics): GpStatus; stdcall; + GdipCreateFromHWND: function(hwnd_: HWND; + graphics: ppGpGraphics): GpStatus; stdcall; + GdipDeleteGraphics: function(graphics: PGpGraphics): GpStatus; stdcall; + GdipFlush: function(graphics: pGpGraphics; + intention: GpFlushIntention): Gpstatus; stdcall; + GdipTranslateWorldTransform: function(graphics: pGpGraphics; + dx: REAL; dy: REAL; order: GpMatrixOrder): GpStatus; stdcall; + + GdipSetSmoothingMode: function(graphics: pGpGraphics; + smoothingMode_: SmoothingMode): GpStatus; stdcall; + GdipGetSmoothingMode: function(graphics: pGpGraphics; + smoothingMode: pSmoothingMode): GpStatus; stdcall; + GdipSetPixelOffsetMode: function(graphics: pGpGraphics; + pixelOffsetMode: GpPixelOffsetMode): GpStatus; stdcall; + GdipSetClipRegion: function(graphics: pGpGraphics; region: pGpRegion; + combineMode_: GpCombineMode): GpStatus; stdcall; + GdipResetClip: function(graphics: pGpGraphics): GpStatus; stdcall; + + GdipDeleteBrush: function(brush: pGpBrush): GpStatus; stdcall; + GdipCreateSolidFill: function(color: ARGB; + brush: ppGpSolidFill): GpStatus; stdcall; + GdipSetSolidFillColor: function(brush: pGpSolidFill; + color: ARGB): GpStatus; stdcall; + GdipGetSolidFillColor: function(brush: pGpSolidFill; + color: pARGB): GpStatus; stdcall; + + GdipFillRectangleI: function(graphics: pGpGraphics; brush: pGpBrush; + x: INT; y: INT; width: INT; height: INT): GpStatus; stdcall; + GdipFillPolygon2I: function(graphics: pGpGraphics; brush: pGpBrush; + points: pGpPoint; count: INT): GpStatus; stdcall; + + GdipCreatePen1: function(color: ARGB; width: REAL; unit_: GpUnit; + pen: ppGpPen): GpStatus; stdcall; + GdipDeletePen: function(pen: pGpPen): GpStatus; stdcall; + GdipSetPenMode: function(pen: pGpPen; + penMode: GpPenAlignment): GpStatus; stdcall; + GdipSetPenWidth: function(pen: pGpPen; width: REAL): GpStatus; stdcall; + GdipGetPenWidth: function(pen: pGpPen; width: pREAL): GpStatus; stdcall; + GdipSetPenColor: function(pen: pGpPen; argb_: ARGB): GpStatus; stdcall; + GdipGetPenColor: function(pen: pGpPen; argb_: pARGB): GpStatus; stdcall; + GdipSetPenBrushFill: function(pen: pGpPen; brush: pGpBrush): GpStatus; stdcall; + GdipSetPenLineCap197819: function(pen: pGpPen; startCap: GpLineCap; + endCap: GpLineCap; dashCap: GpDashCap): GpStatus; stdcall; + GdipSetPenLineJoin: function(pen: pGpPen; + lineJoin: GpLineJoin): GpStatus; stdcall; + GdipSetPenDashArray: function(pen: pGpPen; dash: pREAL; + count: INT): GpStatus; stdcall; + GdipSetPenDashOffset: function(pen: pGpPen; offset: REAL): GpStatus; stdcall; + GdipSetPenDashStyle: function(pen: pGpPen; + dashstyle: GpDashStyle): GpStatus; stdcall; + + GdipDrawLinesI: function(graphics: pGpGraphics; pen: pGpPen; + points: pGpPoint; count: INT): GpStatus; stdcall; + GdipDrawPolygonI: function(graphics: pGpGraphics; pen: pGpPen; + points: pGpPoint; count: INT): GpStatus; stdcall; + GdipDrawEllipseI: function(graphics: pGpGraphics; pen: pGpPen; x: INT; y: INT; + width: INT; height: INT): GpStatus; stdcall; + GdipFillEllipseI: function(graphics: pGpGraphics; brush: pGpBrush; + x: INT; y: INT; width: INT; height: INT): GpStatus; stdcall; + GdipDrawArcI: function(graphics: pGpGraphics; pen: pGpPen; x: INT; y: INT; + width: INT; heigh: INT; + startAngle: REAL; sweepAngle: REAL): GpStatus; stdcall; + GdipFillPieI: function(graphics: pGpGraphics; brush: pGpBrush; x: INT; y: INT; + width: INT; height: INT; startAngle: REAL; + sweepAngle: REAL): GpStatus; stdcall; + GdipCreatePath: function(brushMode: GpFillMode; + path: ppGpPath): GpStatus; stdcall; + GdipDeletePath: function(path: pGpPath): GpStatus; stdcall; + GdipStartPathFigure: function(path: pGpPath): GpStatus; stdcall; + GdipClosePathFigure: function(path: pGpPath): GpStatus; stdcall; + GdipAddPathArc: function(path: pGpPath; x: REAL; y: REAL; + width: REAL; height: REAL; + startangle: REAL; sweepangle: REAL): GpStatus; stdcall; + GdipFillPath: function(graphics: pGpGraphics; brush: pGpBrush; + path: pGpPath): GpStatus; stdcall; + GdipCreateRegionHrgn: function(hRgn_: HRGN; + region: ppGpRegion): GpStatus; stdcall; + GdipDeleteRegion: function(region: pGpRegion): GpStatus; stdcall; + GdipResetWorldTransform: function(graphics: pGpGraphics): GpStatus; stdcall; + + GdipDisposeImage: function(image: pGpImage): GpStatus; stdcall; + GdipCreateBitmapFromHBITMAP: function(hbm: HBITMAP; hpal: HPALETTE; + bitmap: ppGpBitmap): GpStatus; stdcall; + GdipSetImagePalette: function(image: pGpImage; + palette: pColorPalette): GpStatus; stdcall; + + GdipCreateTexture: function(image: pGpImage; wrapmode: WrapMode; + texture: ppGpTexture): GpStatus; stdcall; + GdipResetTextureTransform: function (brush: pGpTexture): GpStatus; stdcall; + GdipTranslateTextureTransform: function(brush: pGpTexture; dx: REAL; + dy: REAL; order: GpMatrixOrder): GpStatus; stdcall; + +function initializegdiplus(const sonames: array of filenamety; + const noexception: boolean = false): boolean; + //false if not available +procedure releasegdiplus; +function gdipcheckerror(const aerror: gpstatus): boolean; //true if ok + +implementation +uses + msesys,msedynload; +var + libinfo: dynlibinfoty; + instance: pointer; + +function gdipcheckerror(const aerror: gpstatus): boolean; //true if ok +begin + result:= aerror = ok; + if not result then begin + raise egdiplus.create(aerror); + end; +end; + +procedure initgdiplus(const data: pointer); +var + startupin: gdiplusstartupinput; +// startupout: gdiplusstartupoutput; +begin + fillchar(startupin,sizeof(startupin),0); + startupin.gdiplusversion:= 1; + instance:= nil; + gdipcheckerror(gdiplusstartup(@instance,@startupin,nil{@startupout})); +end; + +procedure deinitgdiplus(const data: pointer); +begin + if instance <> nil then begin + gdiplusshutdown(instance); + instance:= nil; + end; +end; + +function initializegdiplus(const sonames: array of filenamety; + const noexception: boolean = false): boolean; +const + funcs: array[0..54] of funcinfoty = ( + (n: 'GdiplusStartup'; d: @GdiplusStartup), //0 + (n: 'GdiplusShutdown'; d: @GdiplusShutdown), //1 + (n: 'GdipCreateFromHDC'; d: @GdipCreateFromHDC), //2 + (n: 'GdipDeleteGraphics'; d: @GdipDeleteGraphics), //3 + (n: 'GdipDeleteBrush'; d: @GdipDeleteBrush), //4 + (n: 'GdipCreateSolidFill'; d: @GdipCreateSolidFill), //5 + (n: 'GdipSetSolidFillColor'; d: @GdipSetSolidFillColor),//6 + (n: 'GdipGetSolidFillColor'; d: @GdipGetSolidFillColor),//7 + (n: 'GdipFillRectangleI'; d: @GdipFillRectangleI), //8 + (n: 'GdipFillPolygon2I'; d: @GdipFillPolygon2I), //9 + (n: 'GdipSetSmoothingMode'; d: @GdipSetSmoothingMode), //10 + (n: 'GdipGetSmoothingMode'; d: @GdipGetSmoothingMode), //11 + (n: 'GdipDrawLinesI'; d: @GdipDrawLinesI), //12 + (n: 'GdipDrawPolygonI'; d: @GdipDrawPolygonI), //13 + (n: 'GdipCreatePen1'; d: @GdipCreatePen1), //14 + (n: 'GdipDeletePen'; d: @GdipDeletePen), //15 + (n: 'GdipSetPenWidth'; d: @GdipSetPenWidth), //16 + (n: 'GdipGetPenWidth'; d: @GdipGetPenWidth), //17 + (n: 'GdipSetPenColor'; d: @GdipSetPenColor), //18 + (n: 'GdipGetPenColor'; d: @GdipGetPenColor), //19 + (n: 'GdipDrawEllipseI'; d: @GdipDrawEllipseI), //20 + (n: 'GdipFillEllipseI'; d: @GdipFillEllipseI), //21 + (n: 'GdipDrawArcI'; d: @GdipDrawArcI), //22 + (n: 'GdipFillPieI'; d: @GdipFillPieI), //23 + (n: 'GdipCreatePath'; d: @GdipCreatePath), //24 + (n: 'GdipDeletePath'; d: @GdipDeletePath), //25 + (n: 'GdipAddPathArc'; d: @GdipAddPathArc), //26 + (n: 'GdipStartPathFigure'; d: @GdipStartPathFigure), //27 + (n: 'GdipClosePathFigure'; d: @GdipClosePathFigure), //28 + (n: 'GdipAddPathArc'; d: @GdipAddPathArc), //29 + (n: 'GdipFillPath'; d: @GdipFillPath), //30 + (n: 'GdipSetPenLineCap197819'; d: @GdipSetPenLineCap197819), //31 + (n: 'GdipSetPenLineJoin'; d: @GdipSetPenLineJoin), //32 + (n: 'GdipSetPenDashArray'; d: @GdipSetPenDashArray), //33 + (n: 'GdipSetPenDashOffset'; d: @GdipSetPenDashOffset), //34 + (n: 'GdipSetPenDashStyle'; d: @GdipSetPenDashStyle), //35 + (n: 'GdipCreateRegionHrgn'; d: @GdipCreateRegionHrgn), //36 + (n: 'GdipSetClipRegion'; d: @GdipSetClipRegion), //37 + (n: 'GdipDeleteRegion'; d: @GdipDeleteRegion), //38 + (n: 'GdipFlush'; d: @GdipFlush), //39 + (n: 'GdipResetClip'; d: @GdipResetClip), //40 + (n: 'GdipCreateFromHDC2'; d: @GdipCreateFromHDC2), //41 + (n: 'GdipCreateFromHWND'; d: @GdipCreateFromHWND), //42 + (n: 'GdipSetPixelOffsetMode'; d: @GdipSetPixelOffsetMode),//43 + (n: 'GdipSetPenMode'; d: @GdipSetPenMode), //44 + (n: 'GdipTranslateWorldTransform'; d: @GdipTranslateWorldTransform),//45 + (n: 'GdipResetWorldTransform'; d: @GdipResetWorldTransform),//46 + (n: 'GdipDisposeImage'; d: @GdipDisposeImage), //47 + (n: 'GdipCreateBitmapFromHBITMAP'; d: @GdipCreateBitmapFromHBITMAP),//48 + (n: 'GdipCreateTexture'; d: @GdipCreateTexture),//49 + (n: 'GdipResetTextureTransform'; d: @GdipResetTextureTransform),//50 + (n: 'GdipTranslateTextureTransform'; d: @GdipTranslateTextureTransform),//51 + (n: 'GdipSetPenBrushFill'; d: @GdipSetPenBrushFill),//52 + (n: 'GdipFree'; d: @GdipFree),//53 + (n: 'GdipSetImagePalette'; d: @GdipSetImagePalette)//54 + ); +// (n: ''; d: @),// +const + errormessage = 'Can not load gdi+ library. '; +begin + result:= initializedynlib(libinfo,sonames,gdipluslib,funcs,[],errormessage, + @initgdiplus,noexception); +end; + +procedure releasegdiplus; +begin + releasedynlib(libinfo,@deinitgdiplus); +end; + +{ egdiplus } + +constructor egdiplus.create(const aerror: GpStatus); +var + str1: string; +begin + str1:= 'gdi+ error '+inttostr(ord(aerror)); + if aerror <= high(gdipluserrormessages) then begin + str1:= str1+': '+gdipluserrormessages[aerror]; + end; + inherited create(str1); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/graphics/msegenericgdi.pas b/mseide-msegui/lib/common/graphics/msegenericgdi.pas new file mode 100644 index 0000000..362f8bc --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msegenericgdi.pas @@ -0,0 +1,1285 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegenericgdi; +// +// under construction +// +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +//{$checkpointer on} +uses + mseguiglob,msegraphics,msetypes,msegraphutils; +type + rectextentty = integer; + prectextentty = ^rectextentty; + rectextentaty = array[0..0] of rectextentty; + prectextentaty = ^rectextentaty; + + rectdataty = record + gap: rectextentty; + width: rectextentty; + end; + prectdataty = ^rectdataty; + rectdataaty = array[0..0] of rectdataty; + prectdataaty = ^rectdataaty; + + stripedataty = record //aray[n] of rectdataty + end; + + stripeheaderty = record + height: rectextentty; + rectcount: rectextentty; + end; + + stripety = record + header: stripeheaderty; + data: stripedataty; + end; + pstripety = ^stripety; + + regiondataty = record + end; + + regioninfoty = record + buffersize: ptruint; + datasize: ptruint; + rectcount: integer; + stripecount: integer; + stripestart: rectextentty; + stripeend: rectextentty; + rectstart: rectextentty; //minint = invalid + rectend: rectextentty; //maxint = invalid + datapo: pstripety; + end; + pregioninfoty = ^regioninfoty; + + pointsfprocty = procedure(const gc: gcty; const points: pfpointty; + const count: integer; const close: boolean); + +procedure gdinotimplemented; +function gdi_regiontorects(const aregion: regionty): rectarty; + +procedure gdi_createemptyregion(var drawinfo: drawinfoty); +procedure gdi_createrectregion(var drawinfo: drawinfoty); +procedure gdi_createrectsregion(var drawinfo: drawinfoty); +procedure gdi_destroyregion(var drawinfo: drawinfoty); +procedure gdi_copyregion(var drawinfo: drawinfoty); +procedure gdi_moveregion(var drawinfo: drawinfoty); +procedure gdi_regionisempty(var drawinfo: drawinfoty); +procedure gdi_regionclipbox(var drawinfo: drawinfoty); +procedure gdi_regsubrect(var drawinfo: drawinfoty); +procedure gdi_regsubregion(var drawinfo: drawinfoty); +procedure gdi_regaddrect(var drawinfo: drawinfoty); +procedure gdi_regaddregion(var drawinfo: drawinfoty); +procedure gdi_regintersectrect(var drawinfo: drawinfoty); +procedure gdi_regintersectregion(var drawinfo: drawinfoty); + +procedure segmentellipsef(var drawinfo: drawinfoty; + const segmentsproc: pointsfprocty); + +{$ifdef mse_debugregion} +procedure dumpregion(const atext: string; const aregion: regionty; + const nocheck: boolean = false); +{$endif} + +implementation +//todo: optimize, especially memory handling, use changebuffer +uses + msesysutils,sysutils,math{$ifdef mse_debugregion},typinfo,mseformatstr{$endif} +; + +type + regopty = (reop_add,reop_sub,reop_intersect); + + regionrectstripety = record + header: stripeheaderty; + data: rectdataty; + end; + regionemptystripety = record + header: stripeheaderty; + end; + +const + rowheadersize = 2*sizeof(rectextentty); //height, colstart + celldatasize = 2*sizeof(rectextentty); //width, gap or 0 + +{$ifdef mse_debugregion} + +procedure dodumpstripes(po1: pstripety; const stripecount: rectextentty; + s1: rectextentty; out stripeheight: integer); +var + int1,int2,int3: integer; + c1: rectextentty; +begin + stripeheight:= s1; + for int1:= 0 to stripecount - 1 do begin + with po1^.header do begin + debugwriteln(' stripe'+inttostr(int1)+' $'+hextostr(po1)+ + ' start: '+inttostr(s1)+ + ' height: '+inttostr(height)+ + ' end: ' + inttostr(s1+height)+ + ' rectcount: '+ inttostr(rectcount) + ); + int2:= rectcount; + s1:= s1 + height; + end; + inc(po1); + c1:= 0; + for int3:= 0 to int2-1 do begin + c1:= c1+prectextentty(po1)^; + inc(prectextentty(po1)); + debugwriteln(' '+inttostr(int3)+' start: '+inttostr(c1)+' width: '+ + inttostr(prectextentty(po1)^)); + c1:= c1+prectextentty(po1)^; + inc(prectextentty(po1)); + end; + end; + stripeheight:= s1-stripeheight; +end; + +procedure dumpstripes(const atext: string; const astripe: pstripety; + const stripecount: rectextentty; + const stripestart: rectextentty); +var + int1: integer; +begin + if astripe = nil then begin + debugwriteln('****'+atext+' NIL'); + end + else begin + debugwriteln('****'+atext+' '+ + 'stripecount: '+inttostr(stripecount)+ + ' stripestart: '+inttostr(stripestart)); + dodumpstripes(astripe,stripecount,stripestart,int1); + end; +end; + +procedure dumpregion(const atext: string; const aregion: regionty; + const nocheck: boolean = false); +var + stripeheight: integer; +begin + if aregion = 0 then begin + debugwriteln('*****'+atext+' NIL'); + end + else begin + with pregioninfoty(aregion)^ do begin + debugwriteln('*****'+atext+' '+ + 'stripecount: '+inttostr(stripecount)+ + ' stripestart: '+inttostr(stripestart)+ + ' stripeend: '+inttostr(stripeend)+ + ' rectstart: '+inttostr(rectstart)+ + ' rectend: '+inttostr(rectend)+ + ' rectcount: '+ inttostr(rectcount)+ + ' datasize: '+inttostr(datasize)+ + ' buffersize: '+inttostr(buffersize) + ); + dodumpstripes(datapo,stripecount,stripestart,stripeheight); + if not nocheck and (stripeheight <> stripeend-stripestart) then begin + debugwriteln(' *** ERROR *** stripeheight expected '+ + inttostr(stripeheight)+' stripeend '+inttostr(stripeheight+stripestart)); + end; + end; + end; +end; + +procedure dumpstripe(const atext: string; const astripe: pstripety); +var + int1: integer; + c1: rectextentty; + po1: prectextentty; +begin + with astripe^.header do begin + debugwriteln('***'+atext+' height: '+inttostr(height)+ + ' rectcount: '+inttostr(rectcount)); + po1:= @astripe^.data; + c1:= 0; + for int1:= 0 to rectcount - 1 do begin + c1:= c1+po1^; + inc(po1); + debugwriteln(' '+inttostr(int1)+' start: '+inttostr(c1)+' width: '+ + inttostr(po1^)); + inc(po1); + end; + end; +end; + +{$endif} + +procedure gdinotimplemented; +begin + guierror(gue_notimplemented); +end; + +function calcdatasize(const rowcount,rectcount: integer): ptruint; + {$ifdef FPC} inline;{$endif} +begin + result:= rowcount*rowheadersize + rectcount*celldatasize; +end; + +function stripesize(const astripe: pstripety): integer; +begin + result:= sizeof(stripeheaderty)+ + astripe^.header.rectcount*sizeof(rectdataty) +end; + +procedure incstripe(var astripe: pstripety); {$ifdef FPC} inline;{$endif} +begin + astripe:= pstripety(pchar(astripe)+sizeof(stripeheaderty)+ + astripe^.header.rectcount*sizeof(rectdataty)); +end; + +function nextstripe(const astripe: pstripety):pstripety; + {$ifdef FPC} inline;{$endif} +begin + result:= pstripety(pchar(astripe)+sizeof(stripeheaderty)+ + astripe^.header.rectcount*sizeof(rectdataty)); +end; + +function getregmem(const astripecount,arectcount: integer): pregioninfoty; +begin + getmem(result,sizeof(regioninfoty)); + with result^ do begin + stripecount:= astripecount; + rectcount:= arectcount; + buffersize:= calcdatasize(stripecount,rectcount); + datasize:= buffersize; + rectstart:= maxint; + rectend:= minint; + if buffersize > 0 then begin + getmem(datapo,buffersize); + end + else begin + datapo:= nil; + end; + end; +end; + +procedure checkbuffersize(var reg: regioninfoty; const sizedelta: ptruint; + var refpointer: pointer); +var + po1: pointer; +begin + with reg do begin + datasize:= datasize + sizedelta; + if datasize > buffersize then begin + buffersize:= 2*buffersize + sizedelta; + po1:= datapo; + reallocmem(datapo,buffersize); + refpointer:= refpointer + (pchar(datapo) - pchar(po1)); + end; + end; +end; + +procedure checkbuffersize(var reg: regioninfoty; + const stripechange,rectchange: integer; var refpointer: pointer); +begin + with reg do begin + checkbuffersize(reg,calcdatasize(stripechange,rectchange),refpointer); + stripecount:= stripecount + stripechange; + rectcount:= rectcount + rectchange; + end; +end; + +procedure insertmem(var reg: regioninfoty; const size: ptruint; + var refpointer: pointer); +begin + checkbuffersize(reg,size,refpointer); + move(refpointer^,(pchar(refpointer)+size)^, + reg.datasize-size-(pchar(refpointer)-pchar(reg.datapo))); +end; + +procedure insertemptystripe(var reg: regioninfoty; + const stripe: pstripety; const astart,aheight: rectextentty; + out start: pstripety); +var +// po1: pointer; + ext1: rectextentty; +begin + with reg do begin +// po1:= datapo; + start:= stripe; + insertmem(reg,sizeof(regionemptystripety),start); + start^.header.height:= aheight; + start^.header.rectcount:= 0; + if (stripecount = 0) or (astart < stripestart) then begin + stripestart:= astart; + if stripecount = 0 then begin + stripeend:= astart+aheight; + end; + end; + inc(stripecount); + ext1:= astart + aheight; + if ext1 > stripeend then begin + stripeend:= ext1; + end; + end; +end; + +procedure copystripe(var reg: regioninfoty; + const stripe: pstripety; out start,stop: pstripety); +var +// po1: pointer; + pui1: ptruint; + int1: integer; +begin + with reg do begin +// po1:= datapo; + start:= stripe; + int1:= stripe^.header.rectcount; + pui1:= sizeof(stripeheaderty) + sizeof(rectdataty)*int1; + insertmem(reg,pui1,start); + stop:= pstripety(pchar(start) + pui1); + move(stop^,start^,pui1); + inc(stripecount); + rectcount:= rectcount + int1; + end; +end; + +function findstripe(const reg: regioninfoty; const start: rectextentty; + out astripestart: rectextentty; + out below: pstripety): pstripety; +var + ext1: rectextentty; + po1: pstripety; +begin + result:= nil; + below:= nil; + astripestart:= 0; + with reg do begin + if stripecount > 0 then begin + ext1:= stripestart; + if (ext1 <= start) and (start < stripeend) then begin + po1:= datapo; + while true do begin + ext1:= ext1 + po1^.header.height; + if ext1 > start then begin + ext1:= ext1-po1^.header.height; + break; + end; + below:= po1; + inc(pchar(po1),sizeof(stripeheaderty)+ + po1^.header.rectcount*sizeof(rectdataty)); + end; + astripestart:= ext1; + result:= po1; + end; + end; + end; +end; + +procedure splitstripes(var reg: regioninfoty; + const astripestart: rectextentty; const astripe: pstripety; + out start: pstripety; out belowref: ptrint; + out splitstripecount,splitrectcount: integer); + //start = first deststripe from astripe + //belowref = distance datapo to above last deststripe from astripe +var + po1,po2,po3: pstripety; + ext1,ext2,ext3: rectextentty; + stripeend1: rectextentty; + pui1: ptruint; + bo1: boolean; + int1: integer; +begin + with reg do begin + belowref:= -1; + splitstripecount:= 1; + stripeend1:= astripestart+astripe^.header.height; + if (stripecount = 0) or (astripestart <= stripestart) then begin + ext1:= stripestart; + bo1:= (stripecount = 0) or (stripeend1 < ext1); + if bo1 then begin + ext2:= astripe^.header.height; + end + else begin + ext2:= stripestart-astripestart; + end; + if (astripestart = stripestart) and (stripecount > 0) then begin + start:= datapo; + end + else begin + insertemptystripe(reg,datapo,astripestart,ext2,start); + end; + if bo1 and (stripecount > 1) then begin + po1:= datapo; + ext2:= astripestart+astripe^.header.height; + insertemptystripe(reg, + pstripety(pchar(start)+sizeof(regionemptystripety)), + ext2,ext1-ext2,po2); + pui1:= pchar(datapo)-pchar(po1); //follow reallocmem + start:= pstripety(pchar(start)+pui1); + end; + end + else begin + if astripestart >= stripeend then begin + if astripestart = stripeend then begin + po1:= datapo; + for int1:= stripecount-2 downto 0 do begin + incstripe(po1); + end; //current last + belowref:= pchar(po1)-pchar(datapo); + insertemptystripe(reg, + pstripety(pchar(datapo)+calcdatasize(stripecount,rectcount)), + astripestart,astripe^.header.height,start); + end + else begin + insertemptystripe(reg, + pstripety(pchar(datapo)+calcdatasize(stripecount,rectcount)), + stripeend,astripestart-stripeend,po1); + insertemptystripe(reg, + pstripety(pchar(datapo)+calcdatasize(stripecount,rectcount)), + astripestart,astripe^.header.height,start); + end; + end + else begin + start:= findstripe(reg,astripestart,ext1,po1); + if ext1 <> astripestart then begin + belowref:= pchar(start)-pchar(datapo); + ext2:= astripestart-ext1; + ext3:= start^.header.height-ext2; + start^.header.height:= ext2; + copystripe(reg,start,po1,start); + start^.header.height:= ext3; + end + else begin + if po1 <> nil then begin + belowref:= pchar(po1)-pchar(datapo); + end; + end; + end; + end; + po1:= start; + ext1:= astripestart; + splitrectcount:= 0; + while true do begin //find end of range + splitrectcount:= splitrectcount + po1^.header.rectcount; + ext1:= ext1 + po1^.header.height; + if (ext1 >= stripeend1) or (ext1 >= stripeend) then begin + break; + end; + inc(splitstripecount); + po1:= pstripety(pchar(po1)+sizeof(stripeheaderty)+ + po1^.header.rectcount*sizeof(rectdataty)); + end; + if ext1 < stripeend1 then begin + po1:= datapo; + insertemptystripe(reg, + pstripety(pchar(datapo)+calcdatasize(stripecount,rectcount)), + stripeend,stripeend1-ext1,po2); + start:= pstripety(pchar(start)+(pchar(datapo)-pchar(po1))); + inc(splitstripecount); + end + else begin + if ext1 <> stripeend1 then begin + ext2:= ext1-stripeend1; + ext3:= po1^.header.height-ext2; + po1^.header.height:= ext3; + po2:= datapo; + copystripe(reg,po1,po3,po3); + start:= pstripety(pchar(start)+(pchar(datapo)-pchar(po2))); + po3^.header.height:= ext2; + end; + end; + end; +end; + +function getbuffer(var reg: regioninfoty; + const stripecount,rectcount: integer; + const additionalbuffer: integer): pstripety; +var + pui1,pui2: ptruint; +begin + pui1:= calcdatasize(stripecount,rectcount); + with reg do begin + pui2:= datasize + pui1 + additionalbuffer; + if buffersize < pui2 then begin + reallocmem(datapo,pui2); + buffersize:= pui2; + end; + result:= pstripety(pchar(datapo)+buffersize-pui1); + end; +end; + +type + regopdataty = record + counta: rectextentty; //new + countb: rectextentty; //existing + end; + +function addop(var data: regopdataty): boolean; +begin + with data do begin + result:= odd(counta) or odd(countb); + end; +end; + +function subop(var data: regopdataty): boolean; +begin + with data do begin + result:= not odd(counta) and odd(countb); + end; +end; + +function intersectop(var data: regopdataty): boolean; +begin + with data do begin + result:= odd(counta) and odd(countb); + end; +end; + +type + regopprocty = function (var data: regopdataty): boolean; + +const + regops: array[regopty] of regopprocty = (@addop,@subop,@intersectop); + +procedure stripeop(var reg: regioninfoty; + const astripestart: rectextentty; + const stripe: pstripety; const op: regopty); +var + d: regopdataty; + po1,po6,psa1,psb,psb1,psbb1,pd,pd1,pd2: pstripety; + lastdeststripe: pstripety; + psbbelowref: ptrint; + po2,po3: prectextentaty; +// po4: pointer; +// po5: ppointer; + stripeco,rectco: integer; + posa,posb,startb,startd,endb: rectextentty; + ext1,ext2,ext3: rectextentty; + int1,{int2,}int3: integer; + bo1: boolean; + pui1,pui2: ptruint; + opproc: regopprocty; + don: boolean; + dpos: rectextentty; + dstripeco,drectco: rectextentty; + pendingmovecount: integer; + moves,moved: pointer; +const + endmark = maxint-1; +begin +{$ifdef mse_debugregion} + debugwriteln(''); + debugwriteln('********* stripeop '+getenumname(typeinfo(regopty),ord(op))); + dumpstripes('sourcestripe',stripe,1,astripestart); + dumpregion('region before split ',ptruint(@reg)); +{$endif} + splitstripes(reg,astripestart,stripe,psb,psbbelowref,stripeco,rectco); + with reg do begin + po1:= reg.datapo; + pd:= getbuffer(reg,stripeco,stripeco*(rectco+stripe^.header.rectcount), + stripeco*stripe^.header.rectcount*sizeof(rectdataty)); + //max + {$ifdef mse_debugregion} + dumpregion('region after split ',ptruint(@reg)); + debugwriteln('* stripeco: '+inttostr(stripeco)+' rectco: '+inttostr(rectco)); + {$endif} + pd1:= pd; + psb:= pstripety(pchar(psb)+(pchar(datapo)-(pchar(po1))));//follow reallocmem + psb1:= psb; //first touched + opproc:= regops[op]; + drectco:= 0; + for int1:= stripeco-1 downto 0 do begin + psa1:= stripe; //new + pd1^.header.height:= psb1^.header.height; + pd2:= pd1; //header backup + pd1:= @pd1^.data; + posa:= endmark; + posb:= endmark; + dpos:= 0; + don:= false; + d.counta:= psa1^.header.rectcount * 2; + psa1:= @psa1^.data; + if d.counta > 0 then begin + posa:= prectextentty(psa1)^; + end; + d.countb:= psb1^.header.rectcount * 2; + psb1:= @psb1^.data; + if d.countb > 0 then begin + posb:= prectextentty(psb1)^; + end; + startb:= posb; + startd:= endmark; + while (d.counta > 0) or (d.countb > 0) do begin + while posb < posa do begin //existing + dec(d.countb); + if opproc(d) <> don then begin + don:= not don; + prectextentty(pd1)^:= posb-dpos; + dpos:= posb; + if startd = endmark then begin + startd:= posb; + end; + inc(prectextentty(pd1)); + end; + inc(prectextentty(psb1)); + if (d.countb = 0) then begin + endb:= posb; + posb:= endmark; + break; + end; + posb:= posb + prectextentty(psb1)^; + end; + while posa <= posb do begin //new + if posb = posa then begin + if posa = endmark then begin + break; + end; + dec(d.countb); + inc(prectextentty(psb1)); + if d.countb = 0 then begin + endb:= posb; + posb:= endmark; + end + else begin + posb:= posb + prectextentty(psb1)^; + end; + end; + dec(d.counta); + if opproc(d) <> don then begin + don:= not don; + prectextentty(pd1)^:= posa-dpos; + dpos:= posa; + if startd = endmark then begin + startd:= posa; + end; + inc(prectextentty(pd1)); + end; + inc(prectextentty(psa1)); + if (d.counta = 0) then begin + posa:= endmark; + break; + end; + posa:= posa + prectextentty(psa1)^; + end; + end; + pd2^.header.rectcount:= ((pchar(pd1)-pchar(pd2))-sizeof(stripeheaderty)) + div sizeof(rectdataty); + drectco:= drectco + pd2^.header.rectcount; + if startd <> endmark then begin //has result rects + if startd <= rectstart then begin + rectstart:= startd; + end + else begin + if startb = rectstart then begin //higher + rectstart:= minint; //invalid + end; + end; + if dpos >= rectend then begin + rectend:= dpos; + end + else begin + if endb = rectend then begin //lower + rectend:= maxint; //invalid + end; + end; + end + else begin //no result rects + if startb = rectstart then begin + rectstart:= minint; //invalid + end; + if endb = rectend then begin + rectend:= maxint; + end; + end; + end; + {$ifdef mse_debugregion} + dumpstripes('dest after operation ',pd,stripeco,astripestart); +// dumpregion('region after operation ',ptruint(@reg)); + {$endif} + + //merge stripes in block + + psb1:= pd; //dest + psbb1:= pd; //dest buffer + psa1:= pd; //init last stripe + po1:= nextstripe(pd);//source + int1:= stripeco; + dstripeco:= int1; + dec(int1); + pendingmovecount:= 0; + moves:= nil; //compiler warning + moved:= nil; //compiler warning + while int1 <> 0 do begin //pack similar stripes +// psa1:= po1; //backup last stripe + psa1:= psb1; //backup last stripe + while (int1 <> 0) and + (po1^.header.rectcount = psbb1^.header.rectcount) do begin + po2:= @po1^.data; + po3:= @psbb1^.data; + bo1:= false; + for int3:= psbb1^.header.rectcount*2-1 downto 0 do begin + if po2^[int3] <> po3^[int3] then begin + bo1:= true; //different + break; + end; + end; + if bo1 then begin + break; + end; + dec(dstripeco); + drectco:= drectco - psbb1^.header.rectcount; //merge stripe + psbb1^.header.height:= psbb1^.header.height + po1^.header.height; + incstripe(po1); + dec(int1); + end; + if int1 <> 0 then begin + if pendingmovecount <> 0 then begin + move(moves^,moved^,pendingmovecount); + end; + incstripe(psb1); + if psb1 <> po1 then begin + pendingmovecount:= stripesize(po1); + psbb1:= po1; + moves:= po1; + moved:= psb1; +// move(po1^,psb1^,stripesize(po1)); //first of next group + end + else begin + pendingmovecount:= 0; + psbb1:= psb1; + end; + incstripe(po1); + dec(int1); + end + else begin + if pendingmovecount <> 0 then begin + move(moves^,moved^,pendingmovecount); + end; + end; + end; + lastdeststripe:= psb1; + {$ifdef mse_debugregion} + dumpstripes('dest after pack ',pd,dstripeco,astripestart); +// dumpregion('region after pack',ptruint(@reg)); + {$endif} + + if op <> reop_intersect then begin + //merge stripe above + + pui1:= calcdatasize(stripeco,rectco); //old size + po1:= pstripety(pchar(psb) + pui1); //first stripe after touched block + if (pchar(po1) < (pchar(datapo) + datasize)) and + (po1^.header.rectcount = psa1^.header.rectcount) then begin + po3:= @psa1^.data; //last stripe in new block + po2:= @po1^.data; + bo1:= false; + for int1:= 0 to psa1^.header.rectcount*2-1 do begin + if po2^[int1] <> po3^[int1] then begin + bo1:= true; + break; + end; + end; + if not bo1 then begin + psa1^.header.height:= psa1^.header.height + po1^.header.height; +// po1^.header.height:= psa1^.header.height + po1^.header.height; + //merge to existing + dec(stripecount); + rectcount:= rectcount-psa1^.header.rectcount; + {$ifdef mse_debugregion} + dumpstripes('dest after merge above ',pd,dstripeco,astripestart); + debugwriteln('* stripecoount: '+ + inttostr(stripecount)+' rectcount: '+inttostr(rectcount)); + {$endif} + incstripe(po1); + end; + end; + + //merge stripe below + + if (psbbelowref >= 0) then begin + po6:= pstripety(pchar(datapo)+psbbelowref); //stripe below touched block + if po6^.header.rectcount = pd^.header.rectcount then begin + bo1:= false; + po3:= @pd^.data; //first stripe in new block + po2:= @po6^.data; + for int1:= 0 to pd^.header.rectcount*2-1 do begin + if po2^[int1] <> po3^[int1] then begin + bo1:= true; + break; + end; + end; + if not bo1 then begin + pd^.header.height:= pd^.header.height + po6^.header.height; + dec(stripecount); + rectcount:= rectcount-pd^.header.rectcount; + psb:= po6; + end; + end; + end; + {$ifdef mse_debugregion} + dumpstripes('dest after merge below ',pd,dstripeco,0); + debugwriteln('* stripecoount: '+ + inttostr(stripecount)+' rectcount: '+inttostr(rectcount)); + {$endif} + end + else begin + psb:= datapo; //intersect + stripestart:= astripestart; + stripeend:= stripestart + stripe^.header.height; + end; + if psb = datapo then begin //first stripe + int1:= 0; + po6:= pd; + while (po6^.header.rectcount = 0) and (int1 < dstripeco) do begin + stripestart:= stripestart + po6^.header.height; + inc(int1); + inc(po6); + end; + inc(pd,int1); //remove leading empty stripes + dstripeco:= dstripeco-int1; + end; + pui2:= calcdatasize(dstripeco,drectco); //new size + if op = reop_intersect then begin + datasize:= pui2; + stripecount:= dstripeco; + rectcount:= drectco; + move(pd^,psb^,pui2); //new data + end + else begin + psb1:= pstripety(pchar(psb)+ pui2); //new block end + move(po1^,psb1^,datasize-(pchar(po1)-pchar(datapo))); + //existing data + move(pd^,psb^,pui2); //new data + rectcount:= rectcount - rectco + drectco; + stripecount:= stripecount - stripeco + dstripeco; + datasize:= calcdatasize(stripecount,rectcount); + + {$ifdef mse_debugregion} + dumpregion('region after move',ptruint(@reg)); + {$endif} + + end; + if (lastdeststripe^.header.rectcount = 0) and + ((pchar(psb)-pchar(datapo))+pui2 = datasize) then begin + //changed last stripe + po1:= pd; + ext1:= 0; + ext2:= 0; + ext3:= 0; + for int1:= dstripeco-1 downto 0 do begin + ext1:= ext1+po1^.header.height; + inc(ext3); //empty stripes + if po1^.header.rectcount > 0 then begin + ext3:= 0; + ext2:= ext1; + end; + incstripe(po1); + end; + stripeend:= stripeend-ext1+ext2; //remove trailing empty stripes + stripecount:= stripecount-ext3; + datasize:= datasize-ext3*sizeof(stripeheaderty); + end; + end; +{$ifdef mse_debugregion} + dumpregion('afterstripeop ',ptruint(@reg)); +{$endif} +end; + +procedure regionop(const source: regioninfoty; var dest: regioninfoty; + const op: regopty); +var + int1: integer; + ext1: rectextentty; + po1: pstripety; +begin + with source do begin + po1:= datapo; + ext1:= stripestart; + for int1:= stripecount - 1 downto 0 do begin + stripeop(dest,ext1,po1,op); + ext1:= ext1 + po1^.header.height; + incstripe(po1); + end; + end; +end; + +function recttostripe(const rect: rectty; out stripestart: rectextentty; + out stripe: regionrectstripety): boolean; +begin + result:= (rect.cx > 0) and (rect.cy > 0); + if result then begin + stripestart:= rect.y; + with stripe do begin + header.height:= rect.cy; + header.rectcount:= 1; + data.gap:= rect.x; + data.width:= rect.cx; + end; + end; +end; + +function regextents(var reg: regioninfoty): rectty; +var + mi,ma: rectextentty; + po1,po2: pstripety; + int1: rectextentty; + ext1: rectextentty; +begin + with reg do begin + if rectcount = 0 then begin + result:= nullrect; + end + else begin + if rectend = maxint then begin //invalid + mi:= maxint; + ma:= minint; + po1:= datapo; + po2:= pstripety(pchar(po1)+datasize); + repeat + int1:= po1^.header.rectcount; + po1:= @po1^.data; + if int1 > 0 then begin + ext1:= prectextentty(po1)^; + if ext1 < mi then begin + mi:= ext1 + end; + for int1:= int1*2-2 downto 0 do begin + inc(prectextentty(po1)); + ext1:= ext1 + prectextentty(po1)^; + end; + inc(prectextentty(po1)); + if ext1 > ma then begin + ma:= ext1; + end; + end; + until po1 >= po2; + rectstart:= mi; + rectend:= ma; + end + else begin + if rectstart = minint then begin //invalid + mi:= maxint; + po1:= datapo; + po2:= pstripety(pchar(po1)+datasize); + repeat + int1:= po1^.header.rectcount; + if int1 > 0 then begin + ext1:= prectdataty(@po1^.data)^.gap; + if ext1 < mi then begin + mi:= ext1; + end; + end; + po1:= pstripety(pchar(po1) + sizeof(stripeheaderty) + + sizeof(rectdataty)*int1); + until po1 >= po2; + rectstart:= mi; + end; + end; + result.x:= rectstart; + result.y:= stripestart; + result.cx:= rectend-rectstart; + result.cy:= stripeend-stripestart; + end; + end; +end; + +function gdi_regiontorects(const aregion: regionty): rectarty; +var + po1: prectextentty; + po2: prectty; + int1,int2: integer; + c1,s1,h1: rectextentty; +begin + if aregion = 0 then begin + result:= nil; + exit; + end; + with pregioninfoty(aregion)^ do begin + setlength(result,rectcount); + po1:= pointer(datapo); + po2:= pointer(result); + s1:= stripestart; + for int1:= stripecount-1 downto 0 do begin + h1:= po1^; //rowheight + inc(po1); + c1:= 0; + for int2:= po1^-1 downto 0 do begin + inc(po1); //gap + c1:= c1+po1^; + po2^.x:= c1; + inc(po1); //width + c1:= c1+po1^; + po2^.cx:= po1^; + po2^.y:= s1; + po2^.cy:= h1; + inc(po2); + end; + s1:= s1 + h1; //next row + inc(po1); + end; + end; +end; + +procedure gdi_createemptyregion(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + pointer(dest):= getregmem(0,0); + end; +end; + +procedure gdi_createrectsregion(var drawinfo: drawinfoty); //gdifunc +var + stri1: regionrectstripety; + int1: integer; +begin + gdi_createemptyregion(drawinfo); + with drawinfo.regionoperation do begin + stri1.header.rectcount:= 1; + for int1:= rectscount - 1 downto 0 do begin + with rectspo^[int1] do begin + stri1.header.height:= cy; + stri1.data.gap:= x; + stri1.data.width:= cx; + stripeop(pregioninfoty(dest)^,y,@stri1,reop_add); + end; + end; + end; +end; + +procedure gdi_createrectregion(var drawinfo: drawinfoty); //gdifunc +//var +// int1: ptruint; +begin + with drawinfo.regionoperation do begin + if (rect.cx = 0) or (rect.cy = 0) then begin + gdi_createemptyregion(drawinfo); + end + else begin + pointer(dest):= getregmem(1,1); + with pregioninfoty(dest)^ do begin + stripestart:= rect.y; + stripeend:= rect.y + rect.cy; + stripecount:= 1; + rectcount:= 1; + rectstart:= rect.x; + rectend:= rect.x + rect.cx; + with datapo^ do begin + header.height:= rect.cy; + header.rectcount:= 1; + with prectdataty(@data)^ do begin + gap:= rect.x; + width:= rect.cx; + end; + end; + end; + end; + end; +end; + +procedure gdi_destroyregion(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + if source <> 0 then begin + with pregioninfoty(source)^ do begin + if buffersize > 0 then begin + freemem(datapo); + end; + end; + freemem(pointer(source)); + end; + end; +end; + +procedure gdi_copyregion(var drawinfo: drawinfoty); //gdifunc +//var +// int1: integer; +begin + with drawinfo.regionoperation do begin + getmem(pointer(dest),sizeof(regioninfoty)); + move(pointer(source)^,pointer(dest)^,sizeof(regioninfoty)); + with pregioninfoty(dest)^ do begin + if datasize > 0 then begin + getmem(datapo,datasize); + move(pregioninfoty(source)^.datapo^,datapo^,datasize); + end + else begin + datapo:= nil; + end; + buffersize:= datasize; + end; + end; +end; + +procedure gdi_moveregion(var drawinfo: drawinfoty); //gdifunc +var + int1,int2: integer; + po1: pstripety; +begin + with drawinfo.regionoperation do begin + with pregioninfoty(dest)^ do begin + stripestart:= stripestart + rect.y; + stripeend:= stripeend + rect.y; + if rect.x <> 0 then begin + if rectstart <> minint then begin + rectstart:= rectstart + rect.x; + end; + if rectend <> maxint then begin + rectend:= rectend + rect.x; + end; + po1:= datapo; + for int1:= stripecount - 1 downto 0 do begin + int2:= po1^.header.rectcount; + inc(po1); + if int2 <> 0 then begin + prectextentty(po1)^:= prectextentty(po1)^+rect.x; + inc(prectdataty(po1),int2); + end; + end; + end; + end; + end; +end; + +procedure gdi_regionisempty(var drawinfo: drawinfoty); //gdifunc +begin + with pregioninfoty(drawinfo.regionoperation.source)^ do begin + drawinfo.regionoperation.dest:= 0; + if rectcount = 0 then begin + drawinfo.regionoperation.dest:= 1; + end; + end; +end; + +procedure gdi_regionclipbox(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + rect:= regextents(pregioninfoty(source)^); + end; +end; + +procedure gdi_regsubrect(var drawinfo: drawinfoty); //gdifunc +var + stri1: regionrectstripety; + ext1: rectextentty; +begin + with drawinfo.regionoperation do begin + if recttostripe(rect,ext1,stri1) then begin + stripeop(pregioninfoty(dest)^,ext1,@stri1,reop_sub); + end; + end; +end; + +procedure gdi_regsubregion(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + regionop(pregioninfoty(source)^,pregioninfoty(dest)^,reop_sub); + end; +end; + +procedure gdi_regaddrect(var drawinfo: drawinfoty); //gdifunc +var + stri1: regionrectstripety; + ext1: rectextentty; +begin + with drawinfo.regionoperation do begin + if recttostripe(rect,ext1,stri1) then begin + stripeop(pregioninfoty(dest)^,ext1,@stri1,reop_add); + end; + end; +end; + +procedure gdi_regaddregion(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + regionop(pregioninfoty(source)^,pregioninfoty(dest)^,reop_add); + end; +end; + +procedure gdi_regintersectrect(var drawinfo: drawinfoty); //gdifunc +var + stri1: regionrectstripety; + ext1: rectextentty; +begin + with drawinfo.regionoperation do begin + if recttostripe(rect,ext1,stri1) then begin + stripeop(pregioninfoty(dest)^,ext1,@stri1,reop_intersect); + end; + end; +end; + +procedure gdi_regintersectregion(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + regionop(pregioninfoty(source)^,pregioninfoty(dest)^,reop_intersect); + end; +end; + +procedure segmentellipsef(var drawinfo: drawinfoty; + const segmentsproc: pointsfprocty); +//todo: optimize +var + count: integer; + po1: pfpointty; + ox,oy,x1,y1,si,co,a: double; + do1: double; + int1: integer; +begin + po1:= nil; //compilerwarning + with drawinfo,drawinfo.rect.rect^ do begin + count:= 2; + if cx = 0 then begin + allocbuffer(buffer,2*sizeof(po1^)); + po1:= buffer.buffer; + po1^.x:= x; + po1^.y:= y; + inc(po1); + po1^.x:= x; + po1^.y:= y+cy; + end + else begin + if cy = 0 then begin + allocbuffer(buffer,2*sizeof(po1^)); + po1:= buffer.buffer; + po1^.x:= x; + po1^.y:= y; + inc(po1); + po1^.x:= x+cx; + po1^.y:= y; + end + else begin + int1:= abs(cx); + if abs(cy) > int1 then begin + int1:= abs(cy); + end; + count:= ceil((0.5*pi)/arccos((int1-1)/int1))*4; //one pixel resolution + if count = 0 then begin + count:= 4; + end; + allocbuffer(buffer,count*sizeof(po1^)); + a:= cy/cx; + oy:= y+cy/2; + do1:= cx/2; + x1:= do1; + y1:= 0; + ox:= x+do1; + do1:= 2*pi/count; + si:= sin(do1); + co:= cos(do1); + po1:= buffer.buffer; + po1^.x:= x1+ox; + po1^.y:= oy; + for int1:= count-2 downto 0 do begin + do1:= x1*co - y1*si; + y1:= y1*co + x1*si; + x1:= do1; + inc(po1); + po1^.x:= x1+ox; + po1^.y:= y1*a+oy; + end; + end; + end; + segmentsproc(gc,buffer.buffer,count,true); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msegraphics.pas b/mseide-msegui/lib/common/graphics/msegraphics.pas new file mode 100644 index 0000000..d286313 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msegraphics.pas @@ -0,0 +1,7255 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegraphics; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msetypes,msestrings,mseerr, + msegraphutils,mseguiglob,mseclasses,mseglob,msesys; + +const + + linewidthshift = 16; + linewidthroundvalue = $8000; + fontsizeshift = 16; + fontsizeroundvalue = $8000; + defaultfontalias = 'stf_default'; + + invalidgchandle = ptruint(-1); + +type + gckindty = (gck_screen,gck_pixmap,gck_printer,gck_metafile); + + drawingflagty = (df_canvasispixmap,df_canvasismonochrome,df_highresfont, + df_doublebuffer,df_smooth, + df_colorconvert, + df_opaque,df_monochrome,df_brush,df_dashed,df_last = 31); + drawingflagsty = set of drawingflagty; + + capstylety = (cs_butt,cs_round,cs_projecting); + joinstylety = (js_miter,js_round,js_bevel); + + dashesstringty = string[8]; + +const + fillmodeinfoflags = [df_opaque,df_monochrome,df_brush]; + da_dot = dashesstringty(#1#1); + da_dash = dashesstringty(#3#3); + da_dashdot = dashesstringty(#3#1#1#1); + +type + //fontalias option char: + fontoptionty = (foo_fixed, // 'p' + foo_proportional, // 'P' + foo_helvetica, // 'H' + foo_roman, // 'R' + foo_script, // 'S' + foo_decorative, // 'D' + foo_antialiased, // 'A' + foo_antialiased2, // 'B' cleartype on windows + foo_nonantialiased // 'a' +// foo_xcore, // 'C' //seems not to work with xft2 +// foo_noxcore // 'c' + ); + fontoptionsty = set of fontoptionty; + +const + fontpitchmask = [foo_fixed,foo_proportional]; + fontfamilymask = [foo_helvetica,foo_roman,foo_script,foo_decorative]; + fontantialiasedmask = [foo_antialiased,foo_antialiased2,foo_nonantialiased]; +// fontxcoremask = [foo_xcore,foo_noxcore]; + fontaliasoptionchars : array[fontoptionty] of char = + ('p','P','H','R','S','D','A','B','a'{,'C','c'}); +type + canvasstatety = + (cs_regioncopy,cs_clipregion,cs_origin,cs_gc, + cs_acolorbackground,cs_acolorforeground,cs_color,cs_colorbackground, + cs_dashes,cs_linewidth,cs_capstyle,cs_joinstyle,cs_options, + cs_fonthandle,cs_font,cs_fontcolor,cs_fontcolorbackground,cs_fonteffect, + cs_rasterop,cs_brush,cs_brushorigin, + cs_painted,cs_internaldrawtext,cs_highresdevice, + cs_inactive,cs_pagestarted,cs_metafile{,cs_monochrome}); + canvasstatesty = set of canvasstatety; +const + linecanvasstates = [cs_dashes,cs_linewidth,cs_capstyle,cs_joinstyle]; + +const + fontstylehandlemask = 3; //[fs_bold,fs_italic] + fontstylesmamask: fontstylesty = + [fs_bold,fs_italic,fs_underline,fs_strikeout,fs_selected]; + +type + pgdifunctionaty = ^gdifunctionaty; + + fontdatapty = array[0..15] of pointer; + + fonthashdty = record //hashed by byteshash + glyph: unicharty; + gdifuncs: pgdifunctionaty; //gdi framework + height: integer; + width: integer; + style: fontstylesty; //fs_bold,fs_italic + pitchoptions,familyoptions,antialiasedoptions: fontoptionsty; + rotation: real; //0..1 -> 0deg..360deg CCW + xscale: real; //default 1.0 + end; + + fonthashdataty = record + d: fonthashdty; + name: string; + charset: string; + end; + + fontdataty = record + h: fonthashdataty; + realfont: fonthashdataty; + + font: fontty; + fonthighres: fontty; + basefont: fontty; + ascent,descent,linespacing,caretshift,linewidth,realheight: integer; + platformdata: fontdatapty; //platform dependent + end; + pfontdataty = ^fontdataty; + + fontmetricsty = record + leftbearing: integer; //left undersize, origin of left edge + width: integer; //character advance + rightbearing: integer;//right undersize + sum: integer; //with - leftbearing - rightbearing, glyph width + end; + pfontmetricsty = ^fontmetricsty; + + + + rasteropty = (rop_clear,rop_and,rop_andnot,rop_copy, + rop_notand,rop_nop,rop_xor,rop_or, + rop_nor,rop_notxor,rop_not,rop_ornot, + rop_notcopy,rop_notor,rop_nand,rop_set); + + tfont = class; + tsimplebitmap = class; + fontchangedeventty = procedure(sender: tfont; changed: canvasstatesty) of object; + + fontstatety = (fsta_infovalid,fsta_none); + fontstatesty = set of fontstatety; + + fontnumty = longword; + + tcanvas = class; + + fontaliasmodety = ( + fam_nooverwrite, //do not change if allready registered + fam_overwrite, //do change if allready registered not fam_fix + fam_fix, //will never be changed + fam_fixnooverwrite //do not change if allready registered, + ); //fix existing + + basefontinfoty = record + color: colorty; + colorbackground: colorty; + colorselect: colorty; + colorselectbackground: colorty; + shadow_color: colorty; + shadow_shiftx: integer; + shadow_shifty: integer; + gloss_color: colorty; + gloss_shiftx: integer; + gloss_shifty: integer; + grayed_color: colorty; + grayed_colorshadow: colorty; + grayed_shiftx: integer; + grayed_shifty: integer; + style: fontstylesty; + xscale: real; //default 1.0 + + height: integer; + width: integer; + extraspace: integer; + name: string; + charset: string; + options: fontoptionsty; + end; + + fontlocalpropty = ( + flp_color,flp_colorbackground,flp_colorselect,flp_colorselectbackground, + flp_shadow_color,flp_shadow_shiftx,flp_shadow_shifty, + flp_gloss_color,flp_gloss_shiftx,flp_gloss_shifty, + flp_grayed_color,flp_grayed_colorshadow,flp_grayed_shiftx,flp_grayed_shifty, + flp_style,flp_xscale,flp_height,flp_width,flp_extraspace,flp_name,flp_charset, + flp_options + ); + fontlocalpropsty = set of fontlocalpropty; + + fontinfoty = record + handles: array[0..fontstylehandlemask] of fontnumty; + baseinfo: basefontinfoty; + glyph: unicharty; + gdifuncs: pgdifunctionaty; + rotation: real; //0..2*pi -> 0deg..360deg CCW + end; + pfontinfoty = ^fontinfoty; + + bitmapkindty = (bmk_mono,bmk_gray,bmk_rgb); + + imagety = record + kind: bitmapkindty; + bgr: boolean; + size: sizety; + length: integer; //number of longword + linelength: integer; //number of longword in row + linebytes: integer; //number of bytes in row + pixels: plongwordaty; + end; + pimagety = ^imagety; + + maskedimagety = record + image: imagety; + mask: imagety; + end; + + icanvas = interface(inullinterface) + procedure gcneeded(const sender: tcanvas); + function getkind: bitmapkindty; + function getsize: sizety; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + end; + + canvasclassty = class of tcanvas; + + gcpty = array[0..63] of pointer; + gcty = record + handle: ptruint;//cardinal; + refgc: ptruint;//cardinal; //for windowsmetafile + gdifuncs: pgdifunctionaty; + fontgdifuncs: pgdifunctionaty; + drawingflags: drawingflagsty; + kind: bitmapkindty; + cliporigin: pointty; + paintdevicesize: sizety; + ppmm: real; + platformdata: gcpty; //platform dependent + end; + pgcty = ^gcty; + + bufferty = record + size: integer; //memory size + buffer: pointer; + cursize: integer; //used size + end; + + pdrawinfoty = ^drawinfoty; + rectinfoty = record /// + rect: prectty; // + end; // same layout! + arcinfoty = record // + rect: prectty; /// //rect^.pos = center of ellipse + //rect^.size = dimensions of ellipse + startang: real; //in radiant CCW, 0 = horizontal to the right, + //2*pi = full circle + extentang: real; //in radiant CCW, 2*pi = full circle + pieslice: boolean; + end; + posinfoty = record /// + pos: ppointty; // + end; // same layout! + textposinfoty = record // + pos: ppointty; /// + text: pchar; + count: integer; + end; + text16posinfoty = record + pos: ppointty; + text: pmsechar; + count: integer; + end; + pointsinfoty = record + points: ppointty; + count: integer; + closed: boolean; + end; + colorinfoty = record + color: colorty; + end; + getfontinfoty = record + fontdata: pfontdataty; + basefont: fontty; + ok: boolean; + end; + gettext16widthinfoty = record + text: pmsechar; + count: integer; + fontdata: pfontdataty; + result: integer; + end; + getchar16widthsinfoty = record + text: pmsechar; + count: integer; + fontdata: pfontdataty; + resultpo: pinteger; + end; + getfontmetricsinfoty = record + char: ucs4char; + fontdata: pfontdataty; + resultpo: pfontmetricsty; + end; + copyareainfoty = record + source: tcanvas{pdrawinfoty}; //can be equal to self + sourcerect: prectty; + destrect: prectty; + tileorigin: ppointty; + alignment: alignmentsty; + copymode: rasteropty; + transparentcolor: pixelty; + mask: tsimplebitmap; + maskshiftscaled,maskshift: pointty; + opacity: rgbtriplety; + end; + fonthasglyphinfoty = record + font: fontty; + unichar: unicharty; + hasglyph: boolean; + end; + + rectsty = array[0..bigint div sizeof(rectty)] of rectty; + prectsty = ^rectsty; + regionoperationinfoty = record + source,dest: regionty; + rect: rectty; + rectspo: prectsty; + rectscount: integer; + end; + + createpixmapinfoty = record + size: sizety; + kind: bitmapkindty; + copyfrom: pixmapty; + pixmap: pixmapty; + end; + + pixmapimageinfoty = record + pixmap: pixmapty; + image: imagety; + error: gdierrorty; + end; + + creategcinfoty = record + paintdevice: paintdevicety; + kind: gckindty; + printernamepo: pmsestring; + contextinfopo: pointer; + gcpo: pgcty; + windowrect: prectty; + parent: winidty; + createpaintdevice: boolean; + error: gdierrorty; + end; + + getimageinfoty = record + error: gdierrorty; + image: maskedimagety; + end; + + getcanvasclassinfoty = record + canvasclass: canvasclassty; + kind: bitmapkindty;//monochrome: boolean; + end; + + moverectinfoty = record + dist: ppointty; + rect: prectty; + end; + + gcvaluemaskty = (gvm_clipregion,gvm_colorbackground,gvm_colorforeground, + gvm_dashes,gvm_linewidth,gvm_capstyle,gvm_joinstyle, + gvm_options, + gvm_font,gvm_brush,gvm_brushorigin,gvm_rasterop, + gvm_brushflag); + gcvaluemasksty = set of gcvaluemaskty; + + lineinfoty = record + width: integer; //pixel shl linewidthshift + dashes: dashesstringty; + capstyle: capstylety; + joinstyle: joinstylety; +// options: lineoptionsty; + end; + + canvasoptionty = (cao_smooth); + canvasoptionsty = set of canvasoptionty; + + gcvaluesty = record + mask: gcvaluemasksty; + clipregion: regionty; + colorbackground: pixelty; + colorforeground: pixelty; + font: fontty; + fontnum: fontnumty; + fontdata: pfontdataty; + brush: tsimplebitmap; + brushorigin: pointty; + rasterop: rasteropty; + lineinfo: lineinfoty; + options: canvasoptionsty; + end; + pgcvaluesty = ^gcvaluesty; + + drawinfoty = record + buffer: bufferty; + gc: gcty; + statestamp: longword; +// gcident: longword; + paintdevice: paintdevicety; + origin: pointty; + acolorbackground,acolorforeground: colorty; + gcvalues: pgcvaluesty; //valid in gui_changegc + case integer of + 0: (rect: rectinfoty); + 1: (arc: arcinfoty); + 2: (pos: posinfoty); + 3: (textpos: textposinfoty); + 4: (text16pos: text16posinfoty); + 5: (points: pointsinfoty); + 6: (color: colorinfoty); + 7: (getfont: getfontinfoty); +// 8: (gettextwidth: gettextwidthinfoty); + 9: (gettext16width: gettext16widthinfoty); +// 10: (getcharwidths: getcharwidthsinfoty); + 11: (getchar16widths: getchar16widthsinfoty); + 12: (getfontmetrics: getfontmetricsinfoty); + 13: (copyarea: copyareainfoty); + 14: (regionoperation: regionoperationinfoty); + 15: (fonthasglyph: fonthasglyphinfoty); + 16: (creategc: creategcinfoty); + 17: (getimage: getimageinfoty); + 18: (getcanvasclass: getcanvasclassinfoty); + 19: (createpixmap: createpixmapinfoty); + 20: (pixmapimage: pixmapimageinfoty); + 21: (moverect: moverectinfoty) + end; + + tfonttemplate = class(tpersistenttemplate) + private + procedure setcolor(const avalue: colorty); + procedure setcolorbackground(const avalue: colorty); + procedure setcolorselect(const avalue: colorty); + procedure setcolorselectbackground(const avalue: colorty); + procedure setshadow_color(const avalue: colorty); + procedure setshadow_shiftx(const avalue: integer); + procedure setshadow_shifty(const avalue: integer); + procedure setgloss_color(const avalue: colorty); + procedure setgloss_shiftx(const avalue: integer); + procedure setgloss_shifty(const avalue: integer); + procedure setgrayed_color(const avalue: colorty); + procedure setgrayed_colorshadow(const avalue: colorty); + procedure setgrayed_shiftx(const avalue: integer); + procedure setgrayed_shifty(const avalue: integer); + procedure setstyle(const avalue: fontstylesty); + procedure setxscale(const avalue: real); + procedure setheight(const avalue: integer); + procedure setwidth(const avalue: integer); + procedure setextraspace(const avalue: integer); + procedure setname(const avalue: string); + procedure setcharset(const avalue: string); + procedure setoptions(const avalue: fontoptionsty); + protected + fi: basefontinfoty; + procedure doassignto(dest: tpersistent); override; + function getinfosize: integer; override; + function getinfoad: pointer; override; + public + constructor create(const owner: tmsecomponent; + const onchange: notifyeventty); override; + published + property color: colorty read fi.color write setcolor default cl_default; + //cl_text + property colorbackground: colorty read fi.colorbackground + write setcolorbackground default cl_default; //cl_transparent + property colorselect: colorty read fi.colorselect + write setcolorselect default cl_default; //cl_selectedtext + property colorselectbackground: colorty read fi.colorselectbackground + write setcolorselectbackground default cl_default; + //cl_selectedtextbackground + + property shadow_color: colorty read fi.shadow_color + write setshadow_color default cl_none; + property shadow_shiftx: integer read fi.shadow_shiftx write + setshadow_shiftx default 1; + property shadow_shifty: integer read fi.shadow_shifty write + setshadow_shifty default 1; + + property gloss_color: colorty read fi.gloss_color + write setgloss_color default cl_none; + property gloss_shiftx: integer read fi.gloss_shiftx write + setgloss_shiftx default -1; + property gloss_shifty: integer read fi.gloss_shifty write + setgloss_shifty default -1; + + property grayed_color: colorty read fi.grayed_color + write setgrayed_color default cl_default; //cl_grayed + property grayed_colorshadow: colorty read fi.grayed_colorshadow + write setgrayed_colorshadow default cl_default; + //cl_grayedshadow; + property grayed_shiftx: integer read fi.grayed_shiftx write + setgrayed_shiftx default 1; + property grayed_shifty: integer read fi.grayed_shifty write + setgrayed_shifty default 1; + + property height: integer read fi.height write setheight default 0; + //pixel + property width: integer read fi.width write setwidth default 0; + //avg. character width in 1/10 pixel, 0 = default + property extraspace: integer read fi.extraspace write setextraspace + default 0; + property style: fontstylesty read fi.style write setstyle default []; + property name: string read fi.name write setname; + property charset: string read fi.charset write setcharset; + property options: fontoptionsty read fi.options write setoptions default []; + property xscale: real read fi.xscale write setxscale; + //default 1.0 + + end; + + tfontcomp = class(ttemplatecontainer) + private + function gettemplate: tfonttemplate; + procedure settemplate(const avalue: tfonttemplate); + protected + function gettemplateclass: templateclassty; override; + public + published + property template: tfonttemplate read gettemplate write settemplate; + end; + + getfontfuncty = function (var drawinfo: drawinfoty): boolean of object; + + tfont = class(tlinkedoptionalpersistent,icanvas) + private + finfopo: pfontinfoty; + fonchange: notifyeventty; + flocalprops: fontlocalpropsty; + ftemplate: tfontcomp; + function getextraspace: integer; + procedure setextraspace(const avalue: integer); + procedure setcolorbackground(const Value: colorty); + function getcolorbackground: colorty; + procedure setcolorselectbackground(const Value: colorty); + function getcolorselectbackground: colorty; + + procedure setshadow_color(avalue: colorty); + function getshadow_color: colorty; + procedure setshadow_shiftx(const avalue: integer); + function getshadow_shiftx: integer; + procedure setshadow_shifty(const avalue: integer); + function getshadow_shifty: integer; + + procedure setgloss_color(avalue: colorty); + function getgloss_color: colorty; + procedure setgloss_shiftx(const avalue: integer); + function getgloss_shiftx: integer; + procedure setgloss_shifty(const avalue: integer); + function getgloss_shifty: integer; + + procedure setcolor(const Value: colorty); + function getcolor: colorty; + procedure setcolorselect(const Value: colorty); + function getcolorselect: colorty; + procedure setheight(avalue: integer); + procedure setheightflo(avalue: flo64); + function getheight: integer; + function getheightflo: flo64; + function getwidth: integer; + procedure setwidth(avalue: integer); + procedure setstyle(const Value: fontstylesty); + function getstyle: fontstylesty; + function getascent: integer; + function getdescent: integer; + function getglyphheight: integer; + function getlineheight: integer; + function getcaretshift: integer; + procedure updatehandlepo; + procedure releasehandles(const nochanged: boolean = false); + function getcharset: string; + function getname: string; + procedure setcharset(const Value: string); + function getoptions: fontoptionsty; + procedure setoptions(const avalue: fontoptionsty); + function getbold: boolean; + procedure setbold(const avalue: boolean); + function getitalic: boolean; + procedure setitalic(const avalue: boolean); + function getunderline: boolean; + procedure setunderline(const avalue: boolean); + function getstrikeout: boolean; + procedure setstrikeout(const avalue: boolean); + procedure createhandle(const canvas: tcanvas); + function getrotation: real; + procedure setrotation(const avalue: real); + function getxscale: real; + procedure setxscale(const avalue: real); + + procedure readcolorshadow(reader: treader); + function getlinewidth: integer; + + //icanvas + procedure gcneeded(const sender: tcanvas); +// function getmonochrome: boolean; + function getkind: bitmapkindty; + function getsize: sizety; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + function getgrayed_color: colorty; + procedure setgrayed_color(const avalue: colorty); + function getgrayed_colorshadow: colorty; + procedure setgrayed_colorshadow(const avalue: colorty); + function getgrayed_shiftx: integer; + procedure setgrayed_shiftx(const avalue: integer); + function getgrayed_shifty: integer; + procedure setgrayed_shifty(const avalue: integer); + procedure settemplate(const avalue: tfontcomp); + function iscolorstored(): boolean; + function iscolorbackgroundstored(): boolean; + function iscolorselectstored(): boolean; + function iscolorselectbackgroundstored(): boolean; + function isshadow_colorstored(): boolean; + function isshadow_shiftxstored(): boolean; + function isshadow_shiftystored(): boolean; + function isgloss_colorstored(): boolean; + function isgloss_shiftxstored(): boolean; + function isgloss_shiftystored(): boolean; + function isgrayed_colorstored(): boolean; + function isgrayed_colorshadowstored(): boolean; + function isgrayed_shiftxstored(): boolean; + function isgrayed_shiftystored(): boolean; + function isxscalestored(): boolean; + function isstylestored(): boolean; + procedure readdummy(reader: treader); + procedure setlocalprops(const avalue: fontlocalpropsty); + protected + finfo: fontinfoty; + fhandlepo: ^fontnumty; + procedure dochanged(const changed: canvasstatesty; + const nochange: boolean); virtual; + function getfont(var drawinfo: drawinfoty): boolean; virtual; + procedure setname(const Value: string); virtual; + function gethandle: fontnumty; virtual; + function getdatapo: pfontdataty; + procedure assignproperties(const source: tfont; + const ahandles: boolean); virtual; + property rotation: real read getrotation write setrotation; + //0..2*pi-> 0degree..360degree CCW + procedure defineproperties(filer: tfiler); override; + procedure settemplateinfo(const ainfo: basefontinfoty); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function isheightstored(): boolean; + function iswidthstored(): boolean; + function isextraspacestored(): boolean; + function isnamestored(): boolean; + function ischarsetstored(): boolean; + function isoptionsstored(): boolean; + public + constructor create; override; + destructor destroy; override; + procedure assign(source: tpersistent); override; + procedure scale(const ascale: real); virtual; + + function gethandleforcanvas(const canvas: tcanvas): fontnumty; + property handle: fontnumty read gethandle; + property ascent: integer read getascent; + property descent: integer read getdescent; + property glyphheight: integer read getglyphheight; //ascent + descent + property lineheight: integer read getlineheight; + property linewidth: integer read getlinewidth; + property caretshift: integer read getcaretshift; + property onchange: notifyeventty read fonchange write fonchange; + + property bold: boolean read getbold write setbold; + property italic: boolean read getitalic write setitalic; + property underline: boolean read getunderline write setunderline; + property strikeout: boolean read getstrikeout write setstrikeout; + property heightflo: flo64 read getheightflo write setheightflo; + //pixel, 0 = default + + published + property color: colorty read getcolor write setcolor + stored iscolorstored default cl_default; //cl_text + property colorbackground: colorty read getcolorbackground + write setcolorbackground stored iscolorbackgroundstored + default cl_default; //cl_transparent + property colorselect: colorty read getcolorselect write setcolorselect + stored iscolorselectstored default cl_default; //cl_selectedtext + property colorselectbackground: colorty read getcolorselectbackground + write setcolorselectbackground stored iscolorselectbackgroundstored + default cl_default; //cl_selectedtextbackground + property shadow_color: colorty read getshadow_color write setshadow_color + stored isshadow_colorstored default cl_none; + property shadow_shiftx: integer read getshadow_shiftx write setshadow_shiftx + stored isshadow_shiftxstored default 1; + property shadow_shifty: integer read getshadow_shifty write setshadow_shifty + stored isshadow_shiftystored default 1; + + property gloss_color: colorty read getgloss_color + write setgloss_color + stored isgloss_colorstored default cl_none; + property gloss_shiftx: integer read getgloss_shiftx write setgloss_shiftx + stored isgloss_shiftxstored default -1; + property gloss_shifty: integer read getgloss_shifty write setgloss_shifty + stored isgloss_shiftystored default -1; + + property grayed_color: colorty read getgrayed_color + write setgrayed_color + stored isgrayed_colorstored default cl_default;//cl_grayed + property grayed_colorshadow: colorty read getgrayed_colorshadow + write setgrayed_colorshadow + stored isgrayed_colorshadowstored default cl_default; + //cl_grayedshadow + property grayed_shiftx: integer read getgrayed_shiftx write + setgrayed_shiftx + stored isgrayed_shiftxstored default 1; + property grayed_shifty: integer read getgrayed_shifty write + setgrayed_shifty + stored isgrayed_shiftystored default 1; + + property height: integer read getheight write setheight + stored isheightstored default 0; + //pixel, 0 = default + property width: integer read getwidth write setwidth + stored iswidthstored default 0; + //avg. character width in 1/10 pixel, 0 = default + property extraspace: integer read getextraspace write setextraspace + stored isextraspacestored default 0; + property style: fontstylesty read getstyle write setstyle + stored isstylestored default []; + property name: string read getname write setname stored isnamestored; + property charset: string read getcharset write setcharset + stored ischarsetstored; + property options: fontoptionsty read getoptions write setoptions + stored isoptionsstored default []; + property xscale: real read getxscale write setxscale stored isxscalestored; + //default 1.0 + + property localprops: fontlocalpropsty read flocalprops write setlocalprops; + //before template! + //No default, is optional object streaming placeholder + property template: tfontcomp read ftemplate write settemplate; + end; + pfont = ^tfont; + fontarty = array of tfont; + + toptionalfont = class(tfont) + end; + + tparentfont = class(tfont) + public + class function getinstancepo(owner: tobject): pfont; virtual; abstract; + end; + parentfontclassty = class of tparentfont; + + tcanvasfont = class(tfont) + private + protected + fcanvas: tcanvas; + fgdifuncs: pgdifunctionaty; + procedure dochanged(const changed: canvasstatesty; + const nochange: boolean); override; + function gethandle: fontnumty; override; + procedure assignproperties(const source: tfont; + const ahandles: boolean); override; + public + constructor create(const acanvas: tcanvas); reintroduce; + end; + + gdifunctionty = procedure(var drawinfo: drawinfoty); + + gdifuncty = (gdf_creategc,gdf_destroygc,gdf_changegc,gdf_createpixmap, + gdf_pixmaptoimage,gdf_imagetopixmap, + gdf_getcanvasclass,gdf_endpaint,gdf_flush,gdf_movewindowrect, + gdf_drawlines,gdf_drawlinesegments,gdf_drawellipse,gdf_drawarc, + gdf_fillrect, + gdf_fillellipse,gdf_fillarc,gdf_fillpolygon,{gdf_drawstring,} + gdf_drawstring16, + gdf_setcliporigin, + gdf_createemptyregion,gdf_createrectregion,gdf_createrectsregion, + gdf_destroyregion,gdf_copyregion,gdf_moveregion, + gdf_regionisempty,gdf_regionclipbox, + gdf_regsubrect,gdf_regsubregion, + gdf_regaddrect,gdf_regaddregion,gdf_regintersectrect, + gdf_regintersectregion, + gdf_copyarea,gdf_getimage, + gdf_fonthasglyph, + gdf_getfont,gdf_getfonthighres,gdf_freefontdata, + gdf_gettext16width,gdf_getchar16widths,gdf_getfontmetrics + ); + + gdifunctionaty = array[gdifuncty] of gdifunctionty; +// pgdifunctionaty = ^gdifunctionaty; + + canvasvaluesty = record + changed: canvasstatesty; + origin: pointty; + brushorigin: pointty; + clipregion: regionty; + color: colorty; + rasterop: rasteropty; + colorbackground: colorty; + font: fontinfoty; + brush: tsimplebitmap; + lineinfo: lineinfoty; + options: canvasoptionsty; + end; + + canvasvaluespoty = ^canvasvaluesty; + canvasvaluesarty = array of canvasvaluesty; + + canvasvaluestackty = record + count: integer; + stack: canvasvaluesarty; + end; + + edgecolorinfoty = record + color,effectcolor: colorty; + effectwidth: integer; + end; + edgecolorpairinfoty = record + light,shadow: edgecolorinfoty; + end; + framecolorinfoty = record + edges: edgecolorpairinfoty; + frame: colorty; + hiddenedges: edgesty; + end; + + edgeinfoty = (kin_dark,kin_reverseend,kin_reversestart); + edgeinfosty = set of edgeinfoty; + + gdiintffuncty = procedure (func: gdifuncty; var drawinfo: drawinfoty); + canvasarty = array of tcanvas; + + tcanvas = class(tpersistent) + private + fvaluestack: canvasvaluestackty; + gccolorbackground,gccolorforeground: colorty; + gcoptions: canvasoptionsty; + fdefaultfont: fontnumty; + fcliporigin: pointty; + fgclinksto: canvasarty; + fgclinksfrom: canvasarty; + procedure adjustrectar(po: prectty; count: integer); + procedure readjustrectar(po: prectty; count: integer); + procedure error(nr: gdierrorty; const text: msestring); + procedure intparametererror(value: integer; const text: msestring); + procedure freevalues(var values: canvasvaluesty); + + function getcolor: colorty; + procedure setcolor(const value: colorty); + procedure setclipregion(const Value: regionty); + function getorigin: pointty; + procedure setorigin(const Value: pointty); + + + function checkforeground(acolor: colorty; lineinfo: boolean): boolean; + procedure checkcolors; + procedure setfont(const Value: tfont); + procedure updatefontinfo; + function getbrush: tsimplebitmap; + procedure setbrush(const Value: tsimplebitmap); + function getbrushorigin: pointty; + procedure setbrushorigin(const Value: pointty); + function getrootbrushorigin: pointty; + procedure setrootbrushorigin(const Value: pointty); + function getcolorbackground: colorty; + procedure setcolorbackground(const Value: colorty); + function getrasterop: rasteropty; + procedure setrasterop(const Value: rasteropty); + function getdashes: dashesstringty; + procedure setdashes(const Value: dashesstringty); + function getlinewidth: integer; + procedure setlinewidth(Value: integer); + function getcapstyle: capstylety; + function getjoinstyle: joinstylety; + function getoptions: canvasoptionsty; inline; + procedure setcapstyle(const Value: capstylety); + procedure setjoinstyle(const Value: joinstylety); + procedure setoptions(const avalue: canvasoptionsty); + procedure initregrect(const adest: regionty; const arect: rectty); + procedure initregreg(const adest: regionty; const asource: regionty); + procedure updatecliporigin(const Value: pointty); + function getlinewidthmm: real; + procedure setlinewidthmm(const avalue: real); + function getkind: bitmapkindty; +// function getmonochrome: boolean; + procedure readlineoptions(reader: treader); + function getsmooth: boolean; + procedure setsmooth(const avalue: boolean); + protected + fuser: tobject; + fintf: pointer; //icanvas; + fstate: canvasstatesty; + fvaluepo: canvasvaluespoty; + fdrawinfo: drawinfoty; + gcfonthandle1: fontnumty; + afonthandle1: fontnumty; + ffont: tfont; + + function getgdifuncs: pgdifunctionaty; virtual; + procedure registergclink(const dest: tcanvas); + procedure unregistergclink(const dest: tcanvas); + procedure gcdestroyed(const sender: tcanvas); virtual; + + procedure setppmm(avalue: real); virtual; + function getfitrect: rectty; virtual; + procedure valuechanged(value: canvasstatety); inline; + procedure valueschanged(values: canvasstatesty); inline; + procedure initgcvalues; virtual; + procedure initgcstate; virtual; + procedure finalizegcstate; virtual; + procedure checkrect(const rect: rectty); + procedure checkgcstate(state: canvasstatesty); virtual; + procedure checkregionstate; //copies region if necessary + function defaultcliprect: rectty; virtual; + function lock: boolean; virtual; + procedure unlock; virtual; + procedure doflush; + procedure gdi(const func: gdifuncty); virtual; + procedure init; + procedure beforeread; + procedure afterread; + procedure internalcopyarea(asource: tcanvas; const asourcerect: rectty; + const adestrect: rectty; acopymode: rasteropty; + atransparentcolor: colorty; + amask: tsimplebitmap; const amaskpos: pointty; + aalignment: alignmentsty; + //only al_stretchx, al_stretchy and al_tiled used + const atileorigin: pointty; + const aopacity: colorty); //cl_none -> opaque); + + procedure setcliporigin(const Value: pointty); + //value not saved! + function getgchandle: ptruint; + function getcanvasimage(const abgr: boolean = false): imagety; + function getimage(const bgr: boolean): maskedimagety; + + procedure fillarc(const def: rectty; const startang,extentang: real; + const acolor: colorty; const pieslice: boolean); + procedure getarcinfo(out startpo,endpo: pointty); + procedure internaldrawtext(var info); virtual; + //info = drawtextinfoty + function createfont: tcanvasfont; virtual; + procedure drawfontline(const startpoint,endpoint: pointty); + //draws line with font color + procedure nextpage; virtual; //used by tcustomprintercanvas + function getcontextinfopo: pointer; virtual; + procedure updatesize(const asize: sizety); virtual; + procedure movewindowrect(const adist: pointty; const arect: rectty); + procedure defineproperties(filer: tfiler); override; + public + target: tobject; //currently assigned widget in twidget.paint() + drawinfopo: pointer; //used to transport additional drawing information + constructor create(const user: tobject; const intf: icanvas); virtual; + destructor destroy; override; + class function getclassgdifuncs: pgdifunctionaty; virtual; + + procedure updatewindowoptions(var aoptions: internalwindowoptionsty); virtual; + function creategc(const apaintdevice: paintdevicety; const akind: gckindty; + var gc: gcty; const aprintername: msestring = ''): gdierrorty; + procedure linktopaintdevice(apaintdevice: paintdevicety; const gc: gcty; + const cliporigin: pointty); virtual; + //calls reset, resets cliporigin, canvas owns the gc! + procedure fitppmm(const asize: sizety); + //for printercanvas + function size: sizety; + + function highresdevice: boolean; + procedure initflags(const dest: tcanvas); virtual; + procedure unlink; //frees gc + procedure initdrawinfo(var adrawinfo: drawinfoty); + function active: boolean; + + procedure reset; virtual;//clears savestack, origin and clipregion + function save: integer; //returns current saveindex + function restore(index: integer = -1): integer; //-1 -> pop from stack + //returns current saveindex + procedure resetpaintedflag; + procedure endpaint; //opengl swap buffer + + procedure move(const dist: pointty); //add dist to origin + procedure remove(const dist: pointty); //sub dist from origin + + procedure copyarea(const asource: tcanvas; const asourcerect: rectty; + const adestpoint: pointty; const acopymode: rasteropty = rop_copy; + const atransparentcolor: colorty = cl_default; + //atransparentcolor used for convert color to monochrome + //cl_default -> colorbackground + const aopacity: colorty = cl_none); overload; + procedure copyarea(const asource: tcanvas; const asourcerect: rectty; + const adestrect: rectty; const alignment: alignmentsty = []; + const acopymode: rasteropty = rop_copy; + const atransparentcolor: colorty = cl_default; + //atransparentcolor used for convert color to monochrome + //cl_default -> colorbackground + const aopacity: colorty = cl_none); overload; + + procedure drawpoint(const point: pointty; const acolor: colorty = cl_default); + procedure drawpoints(const apoints: array of pointty; + const acolor: colorty = cl_default; + first: integer = 0; acount: integer = -1); //-1 -> all + + procedure drawline(const startpoint,endpoint: pointty; + const acolor: colorty = cl_default); + procedure drawline(const startpoint: pointty; const length: sizety; + const acolor: colorty = cl_default); + procedure drawlinesegments(const apoints: array of segmentty; + const acolor: colorty = cl_default); + + procedure drawlines(const apoints: array of pointty; + const aclosed: boolean = false; + const acolor: colorty = cl_default; + const first: integer = 0; const acount: integer = -1); overload; + //-1 = all + procedure drawlines(const apoints: array of pointty; + const abreaks: array of integer; //ascending order + const aclosed: boolean = false; + const acolor: colorty = cl_default; + const first: integer = 0; const acount: integer = -1); overload; + + procedure drawvect(const startpoint: pointty; + const direction: graphicdirectionty; + const length: integer; const acolor: colorty = cl_default); + overload; + procedure drawvect(const startpoint: pointty; + const direction: graphicdirectionty; + const length: integer; out endpoint: pointty; + const acolor: colorty = cl_default); overload; + + procedure drawrect(const arect: rectty; const acolor: colorty = cl_default); + procedure drawcross(const arect: rectty; const acolor: colorty = cl_default; + const alignment: alignmentsty = [al_xcentered,al_ycentered]); + + procedure drawellipse(const def: rectty; const acolor: colorty = cl_default); + //def.pos = center, def.cx = width, def.cy = height + procedure drawellipse1(const def: rectty; const acolor: colorty = cl_default); + //def.pos = topleft + procedure drawcircle(const center: pointty; const radius: integer; + const acolor: colorty = cl_default); + procedure drawarc(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default); overload; + //def.pos = center, def.cx = width, def.cy = height + //startang,extentang in radiant (2*pi = 360deg CCW) + procedure drawarc1(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default); + //def.pos = topleft + procedure drawarc(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default); overload; + + procedure fillrect(const arect: rectty; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + procedure fillellipse(const def: rectty; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + //def.pos = center, def.cx = width, def.cy = height + procedure fillellipse1(const def: rectty; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + //def.pos = topleft + procedure fillcircle(const center: pointty; const radius: integer; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + procedure fillarcchord(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); overload; + //def.pos = center, def.cx = width, def.cy = height + //startang,extentang in radiant (2*pi = 360deg CCW) + procedure fillarcchord1(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + //def.pos = topleft + procedure fillarcchord(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); overload; + procedure fillarcpieslice(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); overload; + //def.pos = center, def.cx = width, def.cy = height + //startang,extentang in radiant (2*pi = 360deg CCW) + procedure fillarcpieslice1(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); overload; + //def.pos = topleft + procedure fillarcpieslice(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); overload; + procedure fillpolygon(const apoints: array of pointty; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + + procedure drawframe(const arect: rectty; awidth: integer = -1; + const acolor: colorty = cl_default; + const hiddenedges: edgesty = []); overload; + //no dashes, awidth < 0 -> inside frame,! + procedure drawframe(const arect: rectty; awidth: framety; + const acolor: colorty = cl_default; + const hiddenedges: edgesty = []); overload; + procedure drawxorframe(const arect: rectty; const awidth: integer = -1; + const abrush: tsimplebitmap = nil); overload; + procedure drawxorframe(const po1: pointty; const po2: pointty; + const awidth: integer = -1; + const abrush: tsimplebitmap = nil); overload; + procedure fillxorrect(const arect: rectty; + const abrush: tsimplebitmap = nil); overload; + procedure fillxorrect(const start: pointty; const length: integer; + const direction: graphicdirectionty; + const awidth: integer = 0; + const abrush: tsimplebitmap = nil); overload; + procedure drawstring(const atext: msestring; const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false; + const arotation: real = 0); overload; + //0..2*pi-> 0degree..360degree CCW + procedure drawstring(const atext: pmsechar; const acount: integer; const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false; + const arotation: real = 0); overload; + function getstringwidth(const atext: msestring; + const afont: tfont = nil): integer; overload; + function getstringwidth(const atext: pmsechar; const acount: integer; + const afont: tfont = nil): integer; overload; + //sum of cellwidths + function getfontmetrics(const achar: ucs4char; + const afont: tfont = nil): fontmetricsty; + function getfontmetrics(const achar: msechar; + const afont: tfont = nil): fontmetricsty; + + //all boundaries of regionrects are clipped to + // -$8000..$7fff in device space + procedure resetclipregion; + procedure setcliprect(const rect: rectty); + procedure addcliprect(const rect: rectty); + procedure addclipframe(const frame: rectty; inflate: integer); + procedure subcliprect(const rect: rectty); + procedure subclipframe(const frame: rectty; inflate: integer); + procedure intersectcliprect(const rect: rectty); + procedure intersectclipframe(const frame: rectty; inflate: integer); + + procedure addclipregion(const region: regionty); + procedure subclipregion(const region: regionty); + procedure intersectclipregion(const region: regionty); + + function copyclipregion: regionty; + //returns a copy of the current clipregion + + function clipregionisempty: boolean; //true if no drawing possible + function clipbox: rectty; //smallest possible rect around clipregion + + function createregion: regionty; overload; + function createregion(const asource: regionty): regionty; overload; + function createregion(const arect: rectty): regionty; overload; + function createregion(const rects: array of rectty): regionty; overload; + function createregion(frame: rectty; const inflate: integer): regionty; overload; + procedure destroyregion(region: regionty); + + procedure regmove(const adest: regionty; const dist: pointty); + procedure regremove(const adest: regionty; const dist: pointty); + procedure regaddrect(const dest: regionty; const rect: rectty); + procedure regsubrect(const dest: regionty; const rect: rectty); + procedure regintersectrect(const dest: regionty; const rect: rectty); + procedure regaddregion(const dest: regionty; const region: regionty); + procedure regsubregion(const dest: regionty; const region: regionty); + procedure regintersectregion(const dest: regionty; const region: regionty); + + function regionisempty(const region: regionty): boolean; + function regionclipbox(const region: regionty): rectty; + //returns nullrect if region = 0 + + property origin: pointty read getorigin write setorigin; + property clipregion: regionty {read getclipregion} write setclipregion; + //canvas owns the region! + +// property monochrome: boolean read getmonochrome; + property kind: bitmapkindty read getkind; + property color: colorty read getcolor write setcolor default cl_black; + property colorbackground: colorty read getcolorbackground + write setcolorbackground default cl_transparent; + property rasterop: rasteropty read getrasterop write setrasterop default rop_copy; + property font: tfont read ffont write setfont; + property brush: tsimplebitmap read getbrush write setbrush; + property brushorigin: pointty read getbrushorigin write setbrushorigin; + property rootbrushorigin: pointty read getrootbrushorigin write setrootbrushorigin; + //origin = paintdevice top left + procedure adjustbrushorigin(const arect: rectty; + const alignment: alignmentsty); + + property linewidth: integer read getlinewidth write setlinewidth default 0; + property linewidthmm: real read getlinewidthmm write setlinewidthmm; + + property dashes: dashesstringty read getdashes write setdashes; + //todo: dashoffset + property capstyle: capstylety read getcapstyle write setcapstyle + default cs_butt; + property joinstyle: joinstylety read getjoinstyle write setjoinstyle + default js_miter; + property smooth: boolean read getsmooth write setsmooth; + property options: canvasoptionsty read getoptions write setoptions + default []; + + property paintdevice: paintdevicety read fdrawinfo.paintdevice; + property gchandle: ptruint read getgchandle; + property ppmm: real read fdrawinfo.gc.ppmm write setppmm; + //used for linewidth mm, value not saved/restored + property statestamp: longword read fdrawinfo.statestamp; + //incremented by drawing operations + end; + + pixmapstatety = ({pms_monochrome,}pms_ownshandle,pms_maskvalid,pms_nosave, + pms_staticcanvas); + pixmapstatesty = set of pixmapstatety; + + pixmapinfoty = record + handle: pixmapty; + size: sizety; + depth: integer; + end; + + tsimplebitmap = class(tnullinterfacedpersistent,icanvas) + private + function gethandle: pixmapty; + procedure sethandle(const Value: pixmapty); + function getcanvas: tcanvas; + procedure switchtomonochrome; + procedure setwidth(const avalue: integer); + procedure setheight(const avalue: integer); + { + function getgrayscale: boolean; + procedure setgrayscale(const avalue: boolean); + function getmonochrome: boolean; + procedure setmonochrome(const avalue: boolean); + } + protected + fgdifuncs: pgdifunctionaty; + fcanvasclass: canvasclassty; + fcanvas: tcanvas; + fhandle: pixmapty; + fsize: sizety; + fscanlinestep: integer; //bytes + fscanlinewords: integer; + fscanhigh: integer; + fkind: bitmapkindty; + fstate: pixmapstatesty; + fcolorbackground: colorty; + fcolorforeground: colorty; + fdefaultcliporigin: pointty; + procedure updatescanline(); + function createcanvas: tcanvas; virtual; + procedure creategc; + procedure internaldestroyhandle; + procedure destroyhandle; virtual; + procedure createhandle(acopyfrom: pixmapty); virtual; + procedure setkind(const avalue: bitmapkindty); virtual; + function getconverttomonochromecolorbackground: colorty; virtual; + function getmask(out apos: pointty): tsimplebitmap; virtual; + procedure setsize(const avalue: sizety); virtual; + function normalizeinitcolor(const acolor: colorty): colorty; + procedure assign1(const source: tsimplebitmap; const docopy: boolean); virtual; + function getgdiintf: pgdifunctionaty; + //icanvas + procedure gcneeded(const sender: tcanvas); + function getsize: sizety; + function getkind: bitmapkindty; + procedure getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); virtual; + public + constructor create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); reintroduce; + //nil -> default + destructor destroy; override; + + procedure copyhandle; + procedure releasehandle; virtual; + procedure acquirehandle; virtual; + property handle: pixmapty read gethandle write sethandle; + + procedure assign(source: tpersistent); override; + procedure assignnegative(source: tsimplebitmap); + //gets negative copy + procedure clear; virtual;//sets with and height to 0 + procedure init(const acolor: colorty); virtual; + procedure freecanvas; + function canvasallocated: boolean; + procedure copyarea(const asource: tsimplebitmap; const asourcerect: rectty; + const adestpoint: pointty; const acopymode: rasteropty = rop_copy; + const masked: boolean = true; + const acolorforeground: colorty = cl_default; + //cl_default -> asource.colorforeground + //used for monochrome -> color conversion + const acolorbackground: colorty = cl_default; + //cl_default -> asource.colorbackground + //used for monochrome -> color conversion or + //colorbackground for color -> monochrome conversion + const aopacity: colorty = cl_none); overload; + procedure copyarea(const asource: tsimplebitmap; const asourcerect: rectty; + const adestrect: rectty; const aalignment: alignmentsty = []; + const acopymode: rasteropty = rop_copy; + const masked: boolean = true; + const acolorforeground: colorty = cl_default; + //cl_default -> asource.colorforeground + //used for monochrome -> color conversion + const acolorbackground: colorty = cl_default; + //cl_default -> asource.colorbackground + //used for monochrome -> color conversion or + //colorbackground for color -> monochrome conversion + const aopacity: colorty = cl_none); overload; + + property kind: bitmapkindty read fkind write setkind; + { + property monochrome: boolean read getmonochrome write setmonochrome; + property grayscale: boolean read getgrayscale write setgrayscale; + } + property canvas: tcanvas read getcanvas; + property size: sizety read fsize write setsize; + //pixels are not initialized + property width: integer read fsize.cx write setwidth; + property height: integer read fsize.cy write setheight; + function isempty: boolean; + end; + +const + {$ifdef FPC} + {$warnings off} + {$endif} + nullgc: gcty = (handle: 0); + {$ifdef FPC} + {$warnings on} + {$endif} + changedmask = [cs_clipregion,cs_origin,cs_rasterop,cs_options, + cs_acolorbackground,cs_acolorforeground, + cs_color,cs_colorbackground, + cs_fonthandle,cs_font,cs_fontcolor,cs_fontcolorbackground, + cs_fonteffect, + cs_brush,cs_brushorigin] + linecanvasstates; + +type + editfontcolorinfoty = record + text: colorty; + textbackground: colorty; + selectedtext: colorty; + selectedtextbackground: colorty; + end; + +var + defaultframecolors: framecolorinfoty = + (edges:(light: (color: cl_light; effectcolor: cl_highlight; effectwidth: 1); + shadow: (color: cl_shadow; effectcolor: cl_dkshadow; effectwidth: 1); + ); + frame: cl_black; + hiddenedges: [] + ); + + defaulteditfontcolors: editfontcolorinfoty = ( + text: cl_text; + textbackground: cl_transparent; + selectedtext: cl_selectedtext; + selectedtextbackground: cl_selectedtextbackground; + ); + +procedure init; +procedure deinit; + +procedure initdefaultvalues(var avalue: edgecolorinfoty); +procedure initdefaultvalues(var avalue: edgecolorpairinfoty); +procedure drawinfoinit(var info: drawinfoty); + +procedure gdi_lock(); +procedure gdi_unlock(); +function gdi_locked(): boolean; +function gdi_unlockall(): int32; +procedure gdi_relockall(const acount: int32); + +procedure gdi_call(const func: gdifuncty; var drawinfo: drawinfoty; + gdi: pgdifunctionaty = nil); +function getdefaultgdifuncs: pgdifunctionaty;{$ifdef FPC}inline;{$endif} +function registergdi(const agdifuncs: pgdifunctionaty): integer; + //returns unique number +function getgdicanvasclass(const agdi: pgdifunctionaty; + const akind: bitmapkindty): canvasclassty; +function creategdicanvas(const agdi: pgdifunctionaty; + const akind: bitmapkindty; + const user: tobject; const intf: icanvas): tcanvas; + +procedure freefontdata(var drawinfo: drawinfoty); + +procedure allocbuffer(var buffer: bufferty; size: integer); +procedure extendbuffer(var buffer: bufferty; const extension: integer; + var reference: pointer); +function replacebuffer(var buffer: bufferty; size: integer): pointer; +procedure freebuffer(var buffer: bufferty); + +procedure gdierrorlocked(error: gdierrorty; const text: msestring = ''); overload; +procedure gdierrorlocked(error: gdierrorty; sender: tobject; + text: msestring = ''); overload; + +function colortorgb(color: colorty): rgbtriplety; +function colortopixel(color: colorty): pixelty; +function graytopixel(color: colorty): pixelty; +function rgbtocolor(const red,green,blue: integer): colorty; +function blendcolor(const weight: real; const a,b: colorty): colorty; + //0..1 +function opacitycolor(const opacity: real): colorty; +function invertcolor(const color: colorty): colorty; + +procedure setcolormapvalue(index: colorty; const red,green,blue: integer); overload; + //RGB values 0..255 +procedure setcolormapvalue(const index: colorty; const acolor: colorty); overload; +function isvalidmapcolor(index: colorty): boolean; +function transparencytoopacity(const trans: colorty): colorty; + +procedure drawdottedlinesegments(const acanvas: tcanvas; const lines: segmentarty; + const colorline: colorty); + +procedure allocimage(out image: imagety; const asize: sizety; + const akind: bitmapkindty); +procedure freeimage(var image: imagety); +procedure freeimage(var image: maskedimagety); +procedure zeropad(var image: imagety); +procedure checkimagebgr(var aimage: imagety; const bgr: boolean); +procedure movealignment(const source: alignmentsty; var dest: alignmentsty); + +var + flushgdi: boolean; +{$ifdef mse_debuggdisync} +procedure checkgdilock; +procedure checkgdiunlocked; +{$endif} + +implementation +uses + SysUtils,msegui,mseguiintf,msestreaming,mseformatstr,msestockobjects, + msearrayutils,mselist,msebits,msewidgets,msesystypes, + msesysintf1,msesysintf,msesysutils,msefont; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + lineoptionty = (lio_antialias); + lineoptionsty = set of lineoptionty; + +var + gdilockcount: integer; + gdilockthread: threadty; + +procedure initdefaultvalues(var avalue: edgecolorinfoty); +begin + avalue.color:= cl_default; + avalue.effectcolor:= cl_default; + avalue.effectwidth:= -1; +end; + +procedure initdefaultvalues(var avalue: edgecolorpairinfoty); +begin + initdefaultvalues(avalue.shadow); + initdefaultvalues(avalue.light); +end; + +procedure drawinfoinit(var info: drawinfoty); +begin + if flushgdi then begin + fillchar(info.gc.platformdata,sizeof(info.gc.platformdata),0); + end; +end; + +{$ifdef mse_debuggdisync} +procedure gdilockerror(const text: msestring); +var + str1: string; +begin + str1:= text+lineend+ + 'currentth:'+inttostr(sys_getcurrentthread)+ + ' mainth:'+inttostr(application.mainthread)+ + ' applockth:'+inttostr(application.lockthread)+ + ' applockc:'+inttostr(application.lockcount)+lineend+ + ' gdilockc:'+inttostr(gdilockcount)+lineend+ + 'appmutexlockth:'+inttostr(appmutexlockth)+ + ' appmutexunlockth:'+inttostr(appmutexunlockth)+ + ' appmutexlockc:'+inttostr(appmutexlockc)+ + ' appmutexunlockc:'+inttostr(appmutexunlockc)+ + ' appmutexlocks:'+inttostr(appmutexlocks)+ + ' appmutexunlocks:'+inttostr(appmutexunlocks); + debugwriteln(str1); + debugwritestack; +end; + +procedure checkgdilock; +begin + if not application.islockedthread then begin + gdilockerror('GDI lock error.'); + end; +end; + +procedure checkgdiunlocked; +begin + if gdilockcount <> 0 then begin + gdilockerror('GDI unlock error.'); + end; +end; +{$endif} + +function transparencytoopacity(const trans: colorty): colorty; +begin + result:= trans; + if trans <= $00ffffff then begin + result:= result xor $00ffffff; + end; +end; + +procedure movealignment(const source: alignmentsty; var dest: alignmentsty); +begin + dest:= alignmentsty(setsinglebit( + longword(source),longword(dest), + [longword([al_intpol,al_or,al_and]), + longword([al_left,al_xcentered,al_right]), + longword([al_top,al_ycentered,al_bottom]), + longword([al_fit,al_thumbnail,al_tiled])])); +end; + +procedure allocimage(out image: imagety; const asize: sizety; + const akind: bitmapkindty); +begin + with image do begin +// monochrome:= amonochrome; + kind:= akind; + bgr:= false; + pixels:= nil; + size:= asize; + length:= 0; + linelength:= 0; + linebytes:= 0; + if (size.cx <> 0) and (size.cy <> 0) then begin + case kind of + bmk_mono: begin + linelength:= (size.cx+31) div 32; + end; + bmk_gray: begin + linelength:= (size.cx+3) div 4; + end; + else begin + linelength:= size.cx; + length:= size.cy * size.cx; + end; + end; + length:= size.cy * linelength; + linebytes:= linelength * 4; + pixels:= gui_allocimagemem(length); + end; + end; +end; + +procedure freeimage(var image: imagety); +begin + if image.pixels <> nil then begin + gui_freeimagemem(image.pixels); + fillchar(image,sizeof(image),0); + end; +end; + +procedure freeimage(var image: maskedimagety); +begin + freeimage(image.image); + freeimage(image.mask); +end; + +procedure zeropad(var image: imagety); +var + mask: longword; + step: integer; + po1: plongword; + int1: integer; +begin + with image do begin //todo: little/big endian + case kind of + bmk_mono: begin + mask:= bitmask[size.cx and $1f]; + end; + bmk_gray: begin + case size.cx and $3 of + 0: begin + mask:= 0; + end; + 1: begin + mask:= $000000ff; + end; + 2: begin + mask:= $0000ffff; + end; + 3: begin + mask:= $00ffffff; + end; + end; + end + else begin + mask:= 0; + end; + if mask <> 0 then begin + step:= linelength; + po1:= @pixels[step-1]; + for int1:= size.cy - 1 downto 0 do begin + po1^:= po1^ and mask; //mask padding + inc(po1,step); + end; + end; + end; + end; +end; + +procedure checkimagebgr(var aimage: imagety; const bgr: boolean); +var + by1: byte; + int1: integer; + po1: prgbtriplety; +begin + if (aimage.kind = bmk_rgb) and (aimage.bgr xor bgr) then begin + po1:= prgbtriplety(aimage.pixels); + for int1:= aimage.length-1 downto 0 do begin + by1:= po1^.red; + po1^.red:= po1^.blue; + po1^.blue:= by1; + inc(po1); + end; + aimage.bgr:= bgr; + end; +end; + +var + gdinum: integer; + gdifuncs: array of pgdifunctionaty; + +function getdefaultgdifuncs: pgdifunctionaty; {$ifdef FPC}inline;{$endif} +begin + if gdifuncs = nil then begin + gui_registergdi; + end; + result:= gdifuncs[0]; +end; + +function registergdi(const agdifuncs: pgdifunctionaty): integer; + //returns unique number +var + int1: integer; +begin + for int1:= 0 to high(gdifuncs) do begin + if gdifuncs[int1] = agdifuncs then begin + result:= int1; + exit; + end; + end; + setlength(gdifuncs,gdinum+1); //item 0 = system default + gdifuncs[gdinum]:= agdifuncs; + result:= gdinum; + inc(gdinum); +end; + +procedure gdi_lock(); +begin + application.lock(); + gdilockthread:= sys_getcurrentthread(); + if (gdilockcount = 0) and not application.ismainthread then begin + gui_disconnectmaineventqueue(); + end; + inc(gdilockcount); +end; + +procedure gdi_unlock(); +begin + dec(gdilockcount); + if gdilockcount = 0 then begin + gdilockthread:= 0; + if not application.ismainthread then begin + gui_connectmaineventqueue(); + end; + end; + application.unlock(); +end; + +function gdi_locked(): boolean; +begin + result:= (gdilockcount > 0) or application.islockedmainthread(); +end; + +function gdi_unlockall(): int32; +begin + if gdilockthread = sys_getcurrentthread() then begin + result:= gdilockcount; + if result > 1 then begin + gdilockcount:= 1; + end; + if result > 0 then begin + gdi_unlock(); + end; + end + else begin + result:= 0; + end; +end; + +procedure gdi_relockall(const acount: int32); +begin + if acount > 0 then begin + gdi_lock(); + gdilockcount:= gdilockcount + acount - 1; + end; +end; + +procedure gdi_call(const func: gdifuncty; var drawinfo: drawinfoty; + gdi: pgdifunctionaty = nil); + + procedure doflush(); + begin + gdi^[gdf_flush](drawinfo); + gui_flushgdi(); + end; //doflush + +begin + if gdi = nil then begin + gdi:= gdifuncs[0];//gui_getgdifuncs; + end; + if not gdi_locked() then begin + gdi_lock(); + try + gdi^[func](drawinfo); + if flushgdi then begin + doflush() + end; + finally + gdi_unlock(); + end; + end + else begin + gdi^[func](drawinfo); + if flushgdi then begin + doflush(); + end; + end; +end; + +procedure drawdottedlinesegments(const acanvas: tcanvas; const lines: segmentarty; + const colorline: colorty); + {$ifdef mswindows} +var + int1: integer; +// int2: integer; + {$endif} +begin + acanvas.save; + acanvas.color:= colorline; + acanvas.brush:= stockobjects.bitmaps[stb_dens50]; +{$ifdef mswindows} + {workaround: colors are wrong by negativ x on win2000! bug?} + { + int2:= levelshift; + acanvas.remove(makepoint(int2,0)); + for int1:= 0 to high(lines) do begin + inc(lines[int1].a.x,int2); + inc(lines[int1].b.x,int2); + end; + } + if iswin95 then begin //win95 can not draw brushed lines + for int1:= 0 to high(lines) do begin + with lines[int1] do begin + if a.x <> b.x then begin + acanvas.fillrect(makerect(a.x,a.y,b.x-a.x+1,1),cl_brushcanvas); + end + else begin + acanvas.fillrect(makerect(a.x,a.y,1,b.y-a.y+1),cl_brushcanvas); + end; + end; + end; + end + else begin +{$endif} + acanvas.drawlinesegments(lines,cl_brushcanvas); +{$ifdef mswindows} + end; +{$endif} + acanvas.restore; +end; + +var + colormaps: array[colormapsty] of array of pixelty; + inited: boolean; + +function checkfontoptions(const new,old: fontoptionsty): fontoptionsty; +const + mask1: fontoptionsty = fontpitchmask; + mask2: fontoptionsty = fontfamilymask; + mask3: fontoptionsty = fontantialiasedmask; +// mask4: fontoptionsty = fontxcoremask; +var + value1: fontoptionsty; + value2: fontoptionsty; + value3: fontoptionsty; +// value4: fontoptionsty; +begin + value1:= fontoptionsty( + setsinglebit({$ifdef FPC}longword{$else}word{$endif}(new), + {$ifdef FPC}longword{$else}word{$endif}(old), + {$ifdef FPC}longword{$else}word{$endif}(mask1))); + value2:= fontoptionsty( + setsinglebit({$ifdef FPC}longword{$else}word{$endif}(new), + {$ifdef FPC}longword{$else}word{$endif}(old), + {$ifdef FPC}longword{$else}word{$endif}(mask2))); + value3:= fontoptionsty( + setsinglebit({$ifdef FPC}longword{$else}word{$endif}(new), + {$ifdef FPC}longword{$else}word{$endif}(old), + {$ifdef FPC}longword{$else}word{$endif}(mask3))); +(* + value4:= fontoptionsty( + setsinglebit({$ifdef FPC}longword{$else}byte{$endif}(new), + {$ifdef FPC}longword{$else}byte{$endif}(old), + {$ifdef FPC}longword{$else}byte{$endif}(mask4))); +*) + result:= value1 * mask1 + value2 * mask2 + value3 * mask3 {+ value4 * mask4}; +end; + +procedure freebuffer(var buffer: bufferty); +begin + if buffer.buffer <> nil then begin +// freemem(buffer.buffer,buffer.size); + freemem(buffer.buffer); + buffer.size:= 0; + buffer.buffer:= nil; + end; +end; + +procedure allocbuffer(var buffer: bufferty; size: integer); +begin + if size > buffer.size then begin + freebuffer(buffer); + getmem(buffer.buffer,size); + buffer.size:= size; + end; +end; + +procedure extendbuffer(var buffer: bufferty; const extension: integer; + var reference: pointer); +var + po1: pointer; +begin + with buffer do begin + cursize:= cursize + extension; + if cursize > size then begin + size:= cursize*2+1024; + po1:= buffer; + reallocmem(buffer,size); + reference:= reference + (buffer-po1); + end; + end; +end; + +function replacebuffer(var buffer: bufferty; size: integer): pointer; +begin + result:= buffer.buffer; + getmem(buffer.buffer,size); + buffer.size:= size; +end; + +procedure gdierrorlocked(error: gdierrorty; const text: msestring = ''); overload; +begin + gdi_unlock; + gdierror(error,text); +end; + +procedure gdierrorlocked(error: gdierrorty; sender: tobject; + text: msestring = ''); overload; +begin + gdi_unlock; + gdierror(error,sender,text); +end; + +function getdefaultcolorinfo(map: colormapsty; index: integer): pcolorinfoty; +begin + case map of + cm_functional: begin + result:= @defaultfunctional[index]; + end; + cm_mapped: begin + result:= @defaultmapped[index]; + end; + cm_namedrgb: begin + result:= @defaultnamedrgb[index]; + end; + cm_user: begin + result:= @defaultuser[index]; + end; + else begin + result:= nil; + end; + end; +end; + +function colortorgb(color: colorty): rgbtriplety; +var + map: colormapsty; +begin + map:= colormapsty((longword(color) shr speccolorshift)); + color:= colorty(longword(color) and not speccolormask); + if map = cm_rgb then begin + result:= rgbtriplety(color); + end + else begin + dec(map,7); + if (map < cm_rgb) or (map > high(map)) or + (longword(color) >= longword(mapcolorcounts[map])) then begin + result:= colortorgb(cl_invalid); +{ + gdierror(gde_invalidcolor, + hextostrmse(longword(color)+longword(map) shl speccolorshift,8)); +} + end + else begin + result:= rgbtriplety(gui_pixeltorgb(colormaps[map][longword(color)])); + end; + end; +end; + +function colortopixel(color: colorty): pixelty; +var + map: colormapsty; +begin + map:= colormapsty((longword(color) shr speccolorshift)); + color:= colorty(longword(color) and not speccolormask); + if map = cm_rgb then begin + result:= gui_rgbtopixel(color); + end + else begin + dec(map,7); + if (map < cm_rgb) or (map > high(map)) or + (longword(color) >= longword(mapcolorcounts[map])) then begin + result:= colortopixel(cl_invalid); +{ + gdierror(gde_invalidcolor, + hextostrmse(longword(color)+longword(map) shl speccolorshift,8)); +} + end + else begin + result:= colormaps[map][longword(color)]; + end; + end; +end; + +function graytopixel(color: colorty): pixelty; +var + co1: rgbtriplety; + by1: byte; +begin + pixelty(co1):= colortopixel(color); + by1:= (integer(co1.red)+integer(co1.green)+integer(co1.blue)) div 3; + result:= by1 or (by1 shl 8) or (by1 shl 16); +end; + +function rgbtocolor(const red,green,blue: integer): colorty; +begin + result:= (blue and $ff) or ((green and $ff) shl 8) or ((red and $ff) shl 16); +end; + +function blendcolor(const weight: real; const a,b: colorty): colorty; +var +// by1: byte; + ca,cb: rgbtriplety; +begin + ca:= colortorgb(a); + cb:= colortorgb(b); + rgbtriplety(result).red:= ca.red + round((cb.red - ca.red)*weight); + rgbtriplety(result).green:= ca.green + round((cb.green - ca.green)*weight); + rgbtriplety(result).blue:= ca.blue + round((cb.blue - ca.blue)*weight); + rgbtriplety(result).res:= 0; +end; + +function opacitycolor(const opacity: real): colorty; +begin + with rgbtriplety(result) do begin + red:= round(255 * opacity); + green:= red; + blue:= red; + res:= 0; + end; +end; + +function invertcolor(const color: colorty): colorty; +begin + rgbtriplety(result):= colortorgb(color); + with rgbtriplety(result) do begin + red:= 255-red; + green:= 255-green; + blue:= 255-blue; + end; +end; + +function initcolormap: boolean; +var + colormap: colormapsty; + int1: integer; +begin + result:= true; + for colormap:= low(colormapsty) to high(colormapsty) do begin + setlength(colormaps[colormap],mapcolorcounts[colormap]); + {$ifdef FPC} {$checkpointer off} {$endif} + for int1:= 0 to mapcolorcounts[colormap] - 1 do begin + colormaps[colormap][int1]:= gui_rgbtopixel( + longword(getdefaultcolorinfo(colormap,int1)^.rgb)); + end; + {$ifdef FPC} {$checkpointer default} {$endif} + end; + colormaps[cm_namedrgb,integer(longword(cl_0)-longword(cl_namedrgb))]:= + mseguiintf.pixel0; + colormaps[cm_namedrgb,integer(longword(cl_1)-longword(cl_namedrgb))]:= + mseguiintf.pixel1; + gui_initcolormap; +end; + +function isvalidmapcolor(index: colorty): boolean; +var + map: colormapsty; +begin + result:= true; + application.initialize; //colormap must be valid + map:= colormapsty((longword(index) shr speccolorshift)); + index:= colorty(longword(index) and not speccolormask); + dec(map,7); + if (map <= cm_rgb) or (map > high(map)) or + (longword(index) >= longword(mapcolorcounts[map])) then begin + result:= false; + end; +end; + +procedure setcolormapvalue(index: colorty; const red,green,blue: integer); +var + map: colormapsty; +begin + application.initialize; //colormap must be valid + map:= colormapsty((longword(index) shr speccolorshift)); + index:= colorty(longword(index) and not speccolormask); + dec(map,7); + if (map <= cm_rgb) or (map > high(map)) or + (longword(index) >= longword(mapcolorcounts[map])) then begin + gdierror(gde_invalidcolor, + hextostrmse(longword(index)+longword(map) shl speccolorshift,8)); + end; + colormaps[map][longword(index)]:= gui_rgbtopixel(rgbtocolor(red,green,blue)); +end; + +procedure setcolormapvalue(const index: colorty; const acolor: colorty); +var + rgb1: rgbtriplety; +begin + rgb1:= colortorgb(acolor); + setcolormapvalue(index,rgb1.red,rgb1.green,rgb1.blue); +end; + +function getgdicanvasclass(const agdi: pgdifunctionaty; + const akind: bitmapkindty): canvasclassty; +var + info1: drawinfoty; +begin +{$warnings off} + with info1.getcanvasclass do begin + kind:= akind; + canvasclass:= tcanvas; //default + agdi^[gdf_getcanvasclass](info1); + result:= canvasclass; + end; +end; +{$warnings on} + +function creategdicanvas(const agdi: pgdifunctionaty; + const akind: bitmapkindty; const user: tobject; + const intf: icanvas): tcanvas; +begin + result:= getgdicanvasclass(agdi,akind).create(user,intf); +end; + +procedure freefontdata(var drawinfo: drawinfoty); +begin + drawinfo.getfont.fontdata^.h.d.gdifuncs^[gdf_freefontdata](drawinfo); +end; + +procedure init; +var + icon,mask: pixmapty; +begin + gdi_lock; + try + initcolormap; + msefont.init; + msestockobjects.init; + inited:= true; + getwindowicon(nil,icon,mask); + gui_setapplicationicon(icon,mask); + finally + gdi_unlock; + end; +end; + +procedure deinit; +begin + if inited then begin + msestockobjects.deinit; + msefont.deinit; + end; + inited:= false; +end; + + + { tsimplebitmap } + +constructor tsimplebitmap.create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); +begin + fgdifuncs:= agdifuncs; + if fgdifuncs = nil then begin + fgdifuncs:= getdefaultgdifuncs; + end; + fcanvasclass:= getgdicanvasclass(fgdifuncs,kind); + fkind:= akind; +// if monochrome then begin +// include(fstate,pms_monochrome); +// end; + fcolorbackground:= cl_white; + fcolorforeground:= cl_black; +end; + +destructor tsimplebitmap.destroy; +begin + inherited; + destroyhandle; + freeandnil(fcanvas); +end; + +procedure tsimplebitmap.freecanvas; +begin + if pms_staticcanvas in fstate then begin + if fcanvas <> nil then begin + fcanvas.reset; + end; + end + else begin + freeandnil(fcanvas); + end; +end; + +function tsimplebitmap.canvasallocated: boolean; +begin + result:= fcanvas <> nil; +end; + +procedure tsimplebitmap.clear; +begin + size:= nullsize; +end; +{ +function tsimplebitmap.getmonochrome: boolean; +begin + result:= fkind = bmk_mono; +// result:= pms_monochrome in fstate; +end; + +procedure tsimplebitmap.setmonochrome(const avalue: boolean); +begin + kind:= bmk_mono; +end; + +function tsimplebitmap.getgrayscale: boolean; +begin + result:= fkind = bmk_gray; +end; + +procedure tsimplebitmap.setgrayscale(const avalue: boolean); +begin + kind:= bmk_gray; +end; +} +function tsimplebitmap.getconverttomonochromecolorbackground: colorty; +begin + result:= fcolorbackground; +end; +(* +procedure tsimplebitmap.setmonochrome(const avalue: boolean); +var + bmp: tsimplebitmap; + ahandle: pixmapty; +begin + if avalue <> getmonochrome then begin + if isempty then begin + if avalue then begin + fkind:= bmk_mono; + end + else begin + fkind:= bmk_rgb; + end; + { + if avalue then begin + include(fstate,pms_monochrome); + end + else begin + exclude(fstate,pms_monochrome); + end + } + end + else begin + if avalue then begin + bmp:= tsimplebitmap.create(bmk_mono,fgdifuncs); + bmp.size:= fsize; + bmp.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint,rop_copy, + getconverttomonochromecolorbackground); + end + else begin + bmp:= tsimplebitmap.create(bmk_rgb,fgdifuncs); + bmp.size:= fsize; + bmp.canvas.colorbackground:= fcolorbackground; + bmp.canvas.color:= fcolorforeground; + bmp.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint); + end; + ahandle:= bmp.fhandle; + bmp.releasehandle; + bmp.Free; + handle:= ahandle; + acquirehandle; + end; + end; +end; +*) +procedure tsimplebitmap.setkind(const avalue: bitmapkindty); +var + bmp: tsimplebitmap; + ahandle: pixmapty; +begin + if fkind <> avalue then begin + if isempty then begin + destroyhandle(); + fkind:= avalue; + end + else begin + bmp:= tsimplebitmap.create(avalue,fgdifuncs); + bmp.size:= fsize; + case avalue of + bmk_mono: begin + bmp.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint,rop_copy, + getconverttomonochromecolorbackground); + end; + else begin + bmp.canvas.colorbackground:= fcolorbackground; + bmp.canvas.color:= fcolorforeground; + bmp.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint); + end; + end; + ahandle:= bmp.fhandle; + bmp.releasehandle; + bmp.Free; + fkind:= avalue; + handle:= ahandle; + acquirehandle; + end; + end; +end; + + +procedure tsimplebitmap.switchtomonochrome; +begin +// include(fstate,pms_monochrome); + fkind:= bmk_mono; + if fcanvas <> nil then begin + fcanvas.init; + end; +end; + +procedure tsimplebitmap.creategc; +var + gc: gcty; + err: gdierrorty; +begin + if fcanvas <> nil then begin + fillchar(gc,sizeof(gcty),0); + gc.drawingflags:= [df_canvasispixmap]; + gc.paintdevicesize:= fsize; +// if pms_monochrome in fstate then begin + if fkind = bmk_mono then begin + include(gc.drawingflags,df_canvasismonochrome); + end; + gc.kind:= fkind; + gdi_lock; + err:= fcanvas.creategc(fhandle,gck_pixmap,gc); + gdi_unlock; + gdierror(err,self); + fcanvas.linktopaintdevice(fhandle,gc,fdefaultcliporigin); + end; +end; + +function tsimplebitmap.createcanvas: tcanvas; +begin + result:= fcanvasclass.create(self,icanvas(self)); +end; + +function tsimplebitmap.getcanvas: tcanvas; +begin + if fcanvas = nil then begin + fcanvas:= createcanvas; + end; + result:= fcanvas; +end; + +procedure tsimplebitmap.createhandle(acopyfrom: pixmapty); + //copyfrom does not work on windows with in dc selected bmp! +var + info: drawinfoty; +begin + if (fsize.cx > 0) and (fsize.cy > 0) then begin + if fhandle = 0 then begin +{$warnings off} + drawinfoinit(info); + with info.createpixmap do begin + size:= fsize; +// monochrome:= (pms_monochrome in fstate); + kind:= fkind; + copyfrom:= acopyfrom; + handle:= 0; + gdi_call(gdf_createpixmap,info,getgdiintf); + fhandle:= pixmap; + end; +// gdi_lock; +// fhandle:= gui_createpixmap(fsize,0,(pms_monochrome in fstate) and +// (fcanvasclass = nil,copyfrom); +// gdi_unlock; + if fhandle = 0 then begin + gdierror(gde_pixmap); + end; + include(fstate,pms_ownshandle); + end; + end; +end; +{$warnings on} + +procedure tsimplebitmap.releasehandle; +begin + if fhandle <> 0 then begin + if fcanvas <> nil then begin + fcanvas.unlink; + end; +// fhandle:= 0; + exclude(fstate,pms_ownshandle); + end; +end; + +procedure tsimplebitmap.acquirehandle; +begin + if fhandle <> 0 then begin + include(fstate,pms_ownshandle); + end; +end; + +procedure tsimplebitmap.copyhandle; +var + ahandle: pixmapty; +begin + releasehandle; + ahandle:= fhandle; + fhandle:= 0; + createhandle(ahandle); +end; + +procedure tsimplebitmap.internaldestroyhandle; +var + bo1: boolean; +begin + if fhandle <> 0 then begin + bo1:= pms_ownshandle in fstate; + releasehandle; + if bo1 then begin + gdi_lock; + gui_freepixmap(fhandle); + gdi_unlock; + end; + fhandle:= 0; + end; +end; + +procedure tsimplebitmap.destroyhandle; +begin + internaldestroyhandle; +end; + +function tsimplebitmap.getsize: sizety; +begin + result:= fsize; +end; + +procedure tsimplebitmap.setsize(const avalue: sizety); +begin + destroyhandle; + fsize:= avalue; + updatescanline(); +end; + +function tsimplebitmap.getkind(): bitmapkindty; +begin + result:= fkind; +end; + +function tsimplebitmap.isempty(): boolean; +begin + result:= (fsize.cx = 0) or (fsize.cy = 0); +end; + +function tsimplebitmap.gethandle(): pixmapty; +begin + if fhandle = 0 then begin + createhandle(0); + end; + result:= fhandle; +end; + +procedure tsimplebitmap.sethandle(const Value: pixmapty); +var + info: pixmapinfoty; +begin + if fhandle <> value then begin + internaldestroyhandle; + end; + if value <> 0 then begin + info.handle:= value; +// gdi_lock; +// try + gdierror(gui_getpixmapinfo(info)); +// finally +// gdi_unlock; +// end; + fhandle:= value; + with info do begin + fsize:= size; + case depth of + 1: begin + fkind:= bmk_mono; + end; + 8: begin + fkind:= bmk_gray; + end; + else begin + fkind:= bmk_rgb; + end; + end; + { + if depth = 1 then begin + include(fstate,pms_monochrome); + end + else begin + exclude(fstate,pms_monochrome); + end; + } + updatescanline(); + end; + end; +end; + +procedure tsimplebitmap.gcneeded(const sender: tcanvas); +begin + if isempty then begin + gdierror(gde_pixmap); + end + else begin + if not (pms_ownshandle in fstate) and (fhandle <> 0) then begin + copyhandle; + end + else begin + createhandle(0); + end; + creategc; + end; +end; + +function tsimplebitmap.normalizeinitcolor(const acolor: colorty): colorty; +begin + if acolor = cl_transparent then begin + if kind = bmk_mono then begin + result:= cl_0; + end + else begin + result:= cl_white; + end; + end + else begin + result:= acolor; + end; +end; + +procedure tsimplebitmap.init(const acolor: colorty); +begin + with canvas.fvaluepo^.origin do begin + canvas.fillrect(makerect(-x,-y,fsize.cx,fsize.cy),normalizeinitcolor(acolor)); + end; +end; + +procedure tsimplebitmap.assign1(const source: tsimplebitmap; const docopy: boolean); +begin + clear; + with tsimplebitmap(source) do begin + if not isempty then begin + if docopy then begin + // self.handle:= handle; //windows problem: copy handle does not work with bmp selected in dc + // self.copyhandle; + self.clear; + self.kind:= kind; + self.size:= size; + self.copyarea(source,makerect(nullpoint,fsize),nullpoint,rop_copy,false); + end + else begin + self.handle:= handle; + releasehandle; + self.acquirehandle; + end; + end; + end; +end; + +procedure tsimplebitmap.assign(source: tpersistent); +begin + if source is tsimplebitmap then begin + assign1(tsimplebitmap(source),true); + end + else begin + inherited; + end; +end; + +procedure tsimplebitmap.assignnegative(source: tsimplebitmap); + //gets negative copy +begin + clear; + kind:= source.kind; + if not source.isempty then begin + size:= source.size; + copyarea(source,makerect(nullpoint,fsize),nullpoint,rop_notcopy); + end; +end; + +procedure tsimplebitmap.copyarea(const asource: tsimplebitmap; + const asourcerect: rectty; + const adestrect: rectty; const aalignment: alignmentsty = []; + const acopymode: rasteropty = rop_copy; + const masked: boolean = true; + const acolorforeground: colorty = cl_default; + //cl_default -> asource.colorforeground + //used for monochrome -> color conversion + const acolorbackground: colorty = cl_default; + //cl_default -> asource.colorbackground + //used for monochrome -> color conversion or + //colorbackground for color -> monochrome conversion + const aopacity: colorty = cl_none); +var + bo1,bo2: boolean; + amask: tsimplebitmap; + maskpos1: pointty; +begin + bo1:= canvasallocated; + bo2:= asource.canvasallocated; + if bo1 then begin + canvas.save; + canvas.clipregion:= 0; + canvas.origin:= nullpoint; + end; + if bo2 then begin + asource.canvas.save; + asource.canvas.origin:= nullpoint; + end; + if acolorforeground = cl_default then begin + canvas.color:= asource.fcolorforeground; + end + else begin + canvas.color:= acolorforeground; + end; + if acolorbackground = cl_default then begin + canvas.colorbackground:= asource.fcolorbackground; + end + else begin + canvas.colorbackground:= acolorbackground; + end; + if masked then begin + amask:= asource.getmask(maskpos1); + end + else begin + amask:= nil; + maskpos1:= nullpoint; + end; + canvas.internalcopyarea(asource.canvas,asourcerect, + calcrectalignment(adestrect,asourcerect,aalignment),acopymode, + cl_default,amask,maskpos1,aalignment,nullpoint,aopacity); + if bo1 then begin + canvas.restore; + end + else begin + freecanvas; + end; + if bo2 then begin + asource.canvas.restore; + end + else begin + asource.freecanvas; + end; +end; + +procedure tsimplebitmap.copyarea(const asource: tsimplebitmap; const asourcerect: rectty; + const adestpoint: pointty; const acopymode: rasteropty = rop_copy; + const masked: boolean = true; + const acolorforeground: colorty = cl_default; //cl_default -> asource.colorforeground + //used if asource is monchrome + const acolorbackground: colorty = cl_default;//cl_default -> asource.colorbackground + //used if asource is monchrome or + //colorbackground for color -> monochrome conversion + const aopacity: colorty = cl_none); +begin + copyarea(asource,asourcerect,makerect(adestpoint,asourcerect.size),[],acopymode, + masked,acolorforeground,acolorbackground,aopacity); +end; + +{ +procedure tsimplebitmap.stretch(const source: tsimplebitmap; const asize: sizety); +type + cardarty = array[0..0] of longword; +var + sim: pimagety; + simage,dimage: imagety; + po1: ^cardarty; + po2: plongword; + ca1,ca2: longword; + stepx: longword; + int1: integer; +begin + if source.isempty then begin + gdierror(gde_pixmap,self,'stretch'); + end; + if source <> self then begin + clear; + if source.monochrome <> monochrome then begin + gdierror(gde_unmatchedmonochrome,self,'stretch'); + end; + if monochrome then begin + include(fstate,pms_monochrome); + end + else begin + exclude(fstate,pms_monochrome); + end; + end; + sim:= source.getimagepo; + if sim = nil then begin + source.initimage(false,simage); + end + else begin + simage:= sim^; + end; + if simage.pixels = nil then begin + if source.fcanvas <> nil then begin + gdierror(gui_pixmaptoimage(source.handle,simage,source.fcanvas.fdrawinfo.gc.handle)) + end + else begin + gdierror(gui_pixmaptoimage(source.handle,simage,0)) + end; + end; + size:= asize; + initimage(true,dimage); + if monochrome then begin + end + else begin + po1:= pointer(simage.pixels); + po2:= pointer(dimage.pixels); + stepx:= ((($10000*simage.size.cx) + $8000) div dimage.size.cx) shl 15; + ca2:= 0; + for int1:= 0 to asize.cx - 1 do begin + ca1:= po1^[int1]; + repeat + po2^:= ca1; + inc(po2); + inc(ca2,stepx); + until integer(ca2) < 0; + dec(ca2,$80000000); + end; + end; +end; +} +{ +function tsimplebitmap.getmaskhandle(var gchandle: ptruint): pixmapty; +begin + result:= 0; //dummy +end; +} + +function tsimplebitmap.getmask(out apos: pointty): tsimplebitmap; +begin + result:= nil; //dummy +end; +{ +function tsimplebitmap.getimagepo: pimagety; +begin + result:= nil; //dummy +end; +} +{ +procedure tsimplebitmap.initimage(alloc: boolean; out aimage: imagety); + //allocates memory, no clear +var + int1: integer; +begin + with aimage do begin + monochrome:= pms_monochrome in fstate; + pixels:= nil; + size:= fsize; + if alloc and (size.cx <> 0) and (size.cy <> 0) then begin + if monochrome then begin + int1:= fsize.cy * ((fsize.cx+31) div 32); + end + else begin + int1:= fsize.cy * fsize.cx; + end; + allocuninitedarray(int1,sizeof(longword),pixels); + end; + end; +end; +} +procedure tsimplebitmap.getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); +begin + //dummy +end; + +function tsimplebitmap.getgdiintf: pgdifunctionaty; +begin + result:= nil; + if fcanvas <> nil then begin + result:= fcanvas.fdrawinfo.gc.gdifuncs; + end; + if result = nil then begin + result:= fcanvasclass.getclassgdifuncs; + end; +end; + +procedure tsimplebitmap.setwidth(const avalue: integer); +begin + size:= ms(avalue,height); +end; + +procedure tsimplebitmap.setheight(const avalue: integer); +begin + size:= ms(width,avalue); +end; + +procedure tsimplebitmap.updatescanline(); +begin + case fkind of + bmk_mono: begin + fscanlinewords:= ((fsize.cx + 31) div 32); + end; + bmk_gray: begin + fscanlinewords:= ((fsize.cx + 3) div 4); + end; + else begin + fscanlinewords:= fsize.cx; + end; + end; + fscanlinestep:= fscanlinewords * 4; + fscanhigh:= fsize.cx * fsize.cy - 1; +end; + + +procedure initfontinfo(var ainfo: basefontinfoty); +begin + with ainfo do begin + color:= cl_default; //cl_text + colorbackground:= cl_default; //cl_transparent + colorselect:= cl_default; //cl_selectedtext + colorselectbackground:= cl_default; //cl_selectedtxtbackground + shadow_color:= cl_none; + shadow_shiftx:= 1; + shadow_shifty:= 1; + + gloss_color:= cl_none; + gloss_shiftx:= -1; + gloss_shifty:= -1; + + grayed_color:= cl_default; //cl_grayed; + grayed_colorshadow:= cl_default; //cl_grayedshadow; + grayed_shiftx:= 1; + grayed_shifty:= 1; + + xscale:= 1.0; + end; +end; + +{ tfont } + +constructor tfont.create; +begin + if finfopo = nil then begin + finfopo:= @finfo; + end; + initfontinfo(finfopo^.baseinfo); + updatehandlepo; + dochanged([cs_fontcolor,cs_fontcolorbackground,cs_fonteffect],true); +end; + +destructor tfont.destroy; +begin + //handle:= 0; + releasehandles(true); + inherited; +end; + +function tfont.getfont(var drawinfo: drawinfoty): boolean; +begin + gdi_lock; +// gdi_getfont(drawinfo); + drawinfo.gc.gdifuncs^[gdf_getfont](drawinfo); + result:= drawinfo.getfont.ok; + if result then begin + with drawinfo.getfont.fontdata^ do begin + linewidth:= height div (9 * (1 shl fontsizeshift)); + end; + end; + gdi_unlock; +end; + +procedure tfont.createhandle(const canvas: tcanvas); +var + int1: integer; + templ1: tfontcomp; + po1: pfontdataty; + info1: fontinfoty; + opt1: fontoptionsty; +begin + if (canvas <> nil) then begin + canvas.checkgcstate([cs_gc]); //windows needs gc + if finfopo^.gdifuncs <> nil then begin + if finfopo^.gdifuncs <> canvas.fdrawinfo.gc.fontgdifuncs then begin + for int1:= 0 to high(finfopo^.handles) do begin + releasefont(finfopo^.handles[int1]); + finfopo^.handles[int1]:= 0; + end; + end + else begin + releasefont(fhandlepo^); + end; + end; + finfopo^.gdifuncs:= canvas.fdrawinfo.gc.fontgdifuncs; +// finfopo^.gdifuncs:= gdifuncs[canvas.fgdinum]; + templ1:= nil; + fhandlepo^:= getfontnum(finfopo^,canvas.fdrawinfo, + {$ifdef FPC}@{$endif}getfont,templ1); + if fhandlepo^ = 0 then begin + canvas.error(gde_font,msestring(finfopo^.baseinfo.name)); + end; + if (templ1 <> nil) and (ftemplate = nil) then begin + po1:= getfontdata(fhandlepo^); + settemplateinfo(templ1.template.fi); + if fhandlepo^ = 0 then begin + info1:= finfopo^; + with po1^.realfont do begin + if (info1.baseinfo.name = '') and (name <> '') then begin + info1.baseinfo.name:= name; + end; + if (info1.baseinfo.height = 0) and (d.height <> 0) then begin + info1.baseinfo.height:= d.height; + end; + if info1.baseinfo.options = [] then begin + opt1:= d.familyoptions + d.pitchoptions + d.antialiasedoptions; + if opt1 <> [] then begin + info1.baseinfo.options:= opt1; + end; + end; + if (info1.baseinfo.width = 0) and (d.width <> 0) then begin + info1.baseinfo.width:= d.width; + end; + if (info1.baseinfo.xscale = 1) and (d.xscale <> 1) then begin + info1.baseinfo.xscale:= d.xscale; + end; + end; + fhandlepo^:= getfontnum(info1,canvas.fdrawinfo,@getfont,templ1); + end; + end; + end + else begin + fhandlepo^:= 0; + finfopo^.gdifuncs:= nil; + end; +end; + +function tfont.gethandleforcanvas(const canvas: tcanvas): fontnumty; +begin + if (fhandlepo^ <> 0) and + (finfopo^.gdifuncs <> canvas.fdrawinfo.gc.gdifuncs) then begin + releasehandles(true); + end; + if fhandlepo^ = 0 then begin + createhandle(canvas); + end; + result:= fhandlepo^; +end; + +function tfont.gethandle: fontnumty; +var + canvas: tcanvas; +begin + if fhandlepo^ = 0 then begin + canvas:= creategdicanvas(getdefaultgdifuncs,bmk_rgb,self,icanvas(self)); +// canvas:= tcanvas.create(self,icanvas(self)); + try + createhandle(canvas); + finally + canvas.Free; + end; + end; + result:= fhandlepo^; +end; + +function tfont.getdatapo: pfontdataty; +begin + result:= getfontdata(gethandle); +end; +{ +procedure tfont.sethandle(const Value: fontty); +begin + if fhandlepo^ <> value then begin + releasefont(fhandlepo^); + fhandlepo^ := Value; + dochanged([cs_font]); + end; +end; +} +procedure tfont.dochanged(const changed: canvasstatesty; + const nochange: boolean); +begin + if assigned(fonchange) and not nochange then begin + fonchange(self); + end; +end; + +function tfont.getascent: integer; +begin + result:= getdatapo^.ascent {+ finfopo^.extraspace}; +end; + +function tfont.getdescent: integer; +begin + result:= getdatapo^.descent; +end; + +function tfont.getglyphheight: integer; +begin + with getdatapo^ do begin + result:= ascent+descent; + end; +end; + +function tfont.getlineheight: integer; +begin + with getdatapo^ do begin + result:= ascent + descent; + if linespacing > result then begin + result:= linespacing; + end; + end; + result:= result + finfopo^.baseinfo.extraspace; +end; + +function tfont.getlinewidth: integer; +begin + result:= getdatapo^.linewidth; +end; + +function tfont.getcaretshift: integer; +begin + result:= getdatapo^.caretshift; +end; + +function tfont.getextraspace: integer; +begin + result:= finfopo^.baseinfo.extraspace; +end; + +procedure tfont.setextraspace(const avalue: integer); +begin + include(flocalprops,flp_extraspace); + if finfopo^.baseinfo.extraspace <> avalue then begin + finfopo^.baseinfo.extraspace := avalue; + dochanged([cs_font],false); + end; +end; + +procedure tfont.setcolorbackground(const Value: colorty); +begin + include(flocalprops,flp_colorbackground); + with finfopo^.baseinfo do begin + if colorbackground <> value then begin + colorbackground:= Value; + dochanged([cs_fontcolorbackground],false); + end; + end; +end; + +procedure tfont.setcolorselectbackground(const Value: colorty); +begin + include(flocalprops,flp_colorselectbackground); + with finfopo^.baseinfo do begin + if colorselectbackground <> value then begin + colorselectbackground:= Value; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getcolorbackground: colorty; +begin + result:= finfopo^.baseinfo.colorbackground; +end; + +function tfont.getcolorselectbackground: colorty; +begin + result:= finfopo^.baseinfo.colorselectbackground; +end; + +procedure tfont.setshadow_color(avalue: colorty); +begin + include(flocalprops,flp_shadow_color); + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + with finfopo^.baseinfo do begin + if shadow_color <> avalue then begin + shadow_color:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getshadow_color: colorty; +begin + result:= finfopo^.baseinfo.shadow_color; +end; + +procedure tfont.setshadow_shiftx(const avalue: integer); +begin + include(flocalprops,flp_shadow_shiftx); + with finfopo^.baseinfo do begin + if shadow_shiftx <> avalue then begin + shadow_shiftx:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getshadow_shiftx: integer; +begin + result:= finfopo^.baseinfo.shadow_shiftx; +end; + +procedure tfont.setshadow_shifty(const avalue: integer); +begin + include(flocalprops,flp_shadow_shifty); + with finfopo^.baseinfo do begin + if shadow_shifty <> avalue then begin + shadow_shifty:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getshadow_shifty: integer; +begin + result:= finfopo^.baseinfo.shadow_shifty; +end; + +procedure tfont.setgloss_color(avalue: colorty); +begin + include(flocalprops,flp_gloss_color); + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + with finfopo^.baseinfo do begin + if gloss_color <> avalue then begin + gloss_color:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgloss_color: colorty; +begin + result:= finfopo^.baseinfo.gloss_color; +end; + +procedure tfont.setgloss_shiftx(const avalue: integer); +begin + include(flocalprops,flp_gloss_shiftx); + with finfopo^.baseinfo do begin + if gloss_shiftx <> avalue then begin + gloss_shiftx:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgloss_shiftx: integer; +begin + result:= finfopo^.baseinfo.gloss_shiftx; +end; + +procedure tfont.setgloss_shifty(const avalue: integer); +begin + include(flocalprops,flp_gloss_shifty); + with finfopo^.baseinfo do begin + if gloss_shifty <> avalue then begin + gloss_shifty:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgloss_shifty: integer; +begin + result:= finfopo^.baseinfo.gloss_shifty; +end; + +function tfont.getgrayed_color: colorty; +begin + result:= finfopo^.baseinfo.grayed_color; +end; + +procedure tfont.setgrayed_color(const avalue: colorty); +begin + include(flocalprops,flp_grayed_color); + with finfopo^.baseinfo do begin + if grayed_color <> avalue then begin + grayed_color:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgrayed_colorshadow: colorty; +begin + result:= finfopo^.baseinfo.grayed_colorshadow; +end; + +procedure tfont.setgrayed_colorshadow(const avalue: colorty); +begin + include(flocalprops,flp_grayed_colorshadow); + with finfopo^.baseinfo do begin + if grayed_colorshadow <> avalue then begin + grayed_colorshadow:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgrayed_shiftx: integer; +begin + result:= finfopo^.baseinfo.grayed_shiftx; +end; + +procedure tfont.setgrayed_shiftx(const avalue: integer); +begin + include(flocalprops,flp_grayed_shiftx); + with finfopo^.baseinfo do begin + if grayed_shiftx <> avalue then begin + grayed_shiftx:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgrayed_shifty: integer; +begin + result:= finfopo^.baseinfo.grayed_shifty; +end; + +procedure tfont.setgrayed_shifty(const avalue: integer); +begin + include(flocalprops,flp_grayed_shifty); + with finfopo^.baseinfo do begin + if grayed_shifty <> avalue then begin + grayed_shifty:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +procedure tfont.setcolor(const Value: colorty); +begin + include(flocalprops,flp_color); + with finfopo^.baseinfo do begin + if color <> value then begin + color := Value; + dochanged([cs_fontcolor],false); + end; + end; +end; + +procedure tfont.setcolorselect(const Value: colorty); +begin + include(flocalprops,flp_colorselect); + with finfopo^.baseinfo do begin + if colorselect <> value then begin + colorselect := Value; + dochanged([cs_fonteffect],false); + end; + end; +end; + +procedure tfont.assignproperties(const source: tfont; const ahandles: boolean); +var + int1: integer; + bo1: boolean; + changed: canvasstatesty; +begin + changed:= []; + with source,self.finfopo^ do begin + if baseinfo.colorbackground <> finfopo^.baseinfo.colorbackground then begin + baseinfo.colorbackground:= finfopo^.baseinfo.colorbackground; + include(changed,cs_fontcolorbackground); + end; + if baseinfo.colorselectbackground <> + finfopo^.baseinfo.colorselectbackground then begin + baseinfo.colorselectbackground:= finfopo^.baseinfo.colorselectbackground; + include(changed,cs_fonteffect); + end; + + if baseinfo.shadow_color <> finfopo^.baseinfo.shadow_color then begin + baseinfo.shadow_color:= finfopo^.baseinfo.shadow_color; + include(changed,cs_fonteffect); + end; + if baseinfo.shadow_shiftx <> finfopo^.baseinfo.shadow_shiftx then begin + baseinfo.shadow_shiftx:= finfopo^.baseinfo.shadow_shiftx; + include(changed,cs_fonteffect); + end; + if baseinfo.shadow_shifty <> finfopo^.baseinfo.shadow_shifty then begin + baseinfo.shadow_shifty:= finfopo^.baseinfo.shadow_shifty; + include(changed,cs_fonteffect); + end; + + if baseinfo.gloss_color <> finfopo^.baseinfo.gloss_color then begin + baseinfo.gloss_color:= finfopo^.baseinfo.gloss_color; + include(changed,cs_fonteffect); + end; + if baseinfo.gloss_shiftx <> finfopo^.baseinfo.gloss_shiftx then begin + baseinfo.gloss_shiftx:= finfopo^.baseinfo.gloss_shiftx; + include(changed,cs_fonteffect); + end; + if baseinfo.gloss_shifty <> finfopo^.baseinfo.gloss_shifty then begin + baseinfo.gloss_shifty:= finfopo^.baseinfo.gloss_shifty; + include(changed,cs_fonteffect); + end; + + if baseinfo.grayed_color <> finfopo^.baseinfo.grayed_color then begin + baseinfo.grayed_color:= finfopo^.baseinfo.grayed_color; + include(changed,cs_fonteffect); + end; + if baseinfo.grayed_colorshadow <> finfopo^.baseinfo.grayed_colorshadow then begin + baseinfo.grayed_colorshadow:= finfopo^.baseinfo.grayed_colorshadow; + include(changed,cs_fonteffect); + end; + if baseinfo.grayed_shiftx <> finfopo^.baseinfo.grayed_shiftx then begin + baseinfo.grayed_shiftx:= finfopo^.baseinfo.grayed_shiftx; + include(changed,cs_fonteffect); + end; + if baseinfo.grayed_shifty <> finfopo^.baseinfo.grayed_shifty then begin + baseinfo.grayed_shifty:= finfopo^.baseinfo.grayed_shifty; + include(changed,cs_fonteffect); + end; + + if baseinfo.color <> finfopo^.baseinfo.color then begin + baseinfo.color:= finfopo^.baseinfo.color; + include(changed,cs_fontcolor); + end; + if baseinfo.colorselect <> finfopo^.baseinfo.colorselect then begin + baseinfo.colorselect:= finfopo^.baseinfo.colorselect; + include(changed,cs_fonteffect); + end; + if baseinfo.style <> finfopo^.baseinfo.style then begin + baseinfo.style:= finfopo^.baseinfo.style; + self.updatehandlepo; + include(changed,cs_font); + end; + if baseinfo.extraspace <> finfopo^.baseinfo.extraspace then begin + baseinfo.extraspace:= finfopo^.baseinfo.extraspace; + include(changed,cs_font); + end; + if baseinfo.height <> finfopo^.baseinfo.height then begin + baseinfo.height:= finfopo^.baseinfo.height; + include(changed,cs_font); + end; + if baseinfo.width <> finfopo^.baseinfo.width then begin + baseinfo.width:= finfopo^.baseinfo.width; + include(changed,cs_font); + end; + if baseinfo.name <> finfopo^.baseinfo.name then begin + baseinfo.name:= finfopo^.baseinfo.name; + include(changed,cs_font); + end; + if baseinfo.charset <> finfopo^.baseinfo.charset then begin + baseinfo.charset:= finfopo^.baseinfo.charset; + include(changed,cs_font); + end; + if baseinfo.options <> finfopo^.baseinfo.options then begin + baseinfo.options:= finfopo^.baseinfo.options; + include(changed,cs_font); + end; + if baseinfo.xscale <> finfopo^.baseinfo.xscale then begin + baseinfo.xscale:= finfopo^.baseinfo.xscale; + include(changed,cs_font); + end; + bo1:= false; + if ahandles then begin + for int1:= 0 to high(handles) do begin + if handles[int1] <> finfopo^.handles[int1] then begin + bo1:= true; + releasefont(handles[int1]); + handles[int1]:= finfopo^.handles[int1]; + addreffont(handles[int1]); + end; + end; + gdifuncs:= finfopo^.gdifuncs; + end + else begin + for int1:= 0 to high(handles) do begin + if handles[int1] <> 0 then begin + bo1:= true; + releasefont(handles[int1]); + handles[int1]:= 0; + end; + end; + end; + if bo1 then begin + include(changed,cs_fonthandle); + end; + end; + if changed <> [] then begin + dochanged(changed,false); + end; +end; + +procedure tfont.readcolorshadow(reader: treader); +begin + shadow_color:= reader.readinteger; +end; + +procedure tfont.readdummy(reader: treader); +begin + reader.readinteger(); +end; + +procedure tfont.setlocalprops(const avalue: fontlocalpropsty); +begin + if flocalprops <> avalue then begin + flocalprops:= avalue; + if ftemplate <> nil then begin + settemplateinfo(ftemplate.template.fi); + end; + end; +end; + +procedure tfont.defineproperties(filer: tfiler); +begin +// inherited; //no dummy necessary because of localprops + filer.defineproperty('dummy',@readdummy,nil,false); + filer.defineproperty('colorshadow',{$ifdef FPC}@{$endif}readcolorshadow, + nil,false); +end; + +procedure tfont.assign(source: tpersistent); +begin + if source <> self then begin + if source is tfont then begin + assignproperties(tfont(source),true); + end + else begin + inherited; + end; + end; +end; + +procedure tfont.updatehandlepo; +begin + fhandlepo:= @finfopo^.handles[ + {$ifdef FPC}longword{$else}byte{$endif}(finfopo^.baseinfo.style) and + fontstylehandlemask]; +end; + +procedure tfont.setstyle(const Value: fontstylesty); +begin + include(flocalprops,flp_style); + if finfopo^.baseinfo.style <> value then begin + finfopo^.baseinfo.style := Value; + updatehandlepo; + dochanged([cs_font],false); + end; +end; + +procedure tfont.releasehandles(const nochanged: boolean = false); +var + int1: integer; + bo1: boolean; + fo1: fontnumty; +begin + bo1:= false; + for int1:= 0 to high(finfopo^.handles) do begin + fo1:= finfopo^.handles[int1]; + if fo1 <> 0 then begin + bo1:= true; + releasefont(fo1); + end; + end; + if bo1 then begin + fillchar(finfopo^.handles,sizeof(finfopo^.handles),0); + dochanged([cs_font,cs_fonthandle],nochanged); + end + else begin + dochanged([cs_font],nochanged); + end; +end; + +function tfont.getcolor: colorty; +begin + result:= finfopo^.baseinfo.color; +end; + +function tfont.getcolorselect: colorty; +begin + result:= finfopo^.baseinfo.colorselect; +end; + +function tfont.getheight: integer; +begin + result:= (finfopo^.baseinfo.height + fontsizeroundvalue) shr fontsizeshift; +end; + +function tfont.getheightflo: flo64; +begin + result:= finfopo^.baseinfo.height / (1 shl fontsizeshift); +end; + +procedure tfont.setheight(avalue: integer); +begin + include(flocalprops,flp_height); + if avalue < 0 then begin + avalue:= 0; + end; + if finfopo^.baseinfo.height <> avalue then begin + finfopo^.baseinfo.height:= avalue shl fontsizeshift; + releasehandles; + end; +end; + +procedure tfont.setheightflo(avalue: flo64); +begin + include(flocalprops,flp_height); + if avalue < 0 then begin + avalue:= 0; + end; +// if finfopo^.baseinfo.height <> avalue then begin + finfopo^.baseinfo.height:= round(avalue * (1 shl fontsizeshift)); + releasehandles; +// end; +end; + +function tfont.getwidth: integer; +begin + result:= (finfopo^.baseinfo.width + fontsizeroundvalue) shr fontsizeshift; +end; + +procedure tfont.setwidth(avalue: integer); +begin + include(flocalprops,flp_width); + if avalue < 0 then begin + avalue:= 0; + end; + if finfopo^.baseinfo.width <> avalue then begin + finfopo^.baseinfo.width:= avalue shl fontsizeshift; + releasehandles; + end; +end; + +function tfont.getstyle: fontstylesty; +begin + result:= finfopo^.baseinfo.style; +end; + +function tfont.getname: string; +begin + result:= finfopo^.baseinfo.name; +end; + +procedure tfont.setname(const Value: string); +begin + if finfopo^.baseinfo.name <> value then begin + finfopo^.baseinfo.name := trim(Value); + releasehandles; + end; +end; + +function tfont.getoptions: fontoptionsty; +begin + result:= finfopo^.baseinfo.options; +end; + +procedure tfont.setoptions(const avalue: fontoptionsty); +begin + include(flocalprops,flp_options); + if finfopo^.baseinfo.options <> avalue then begin + finfopo^.baseinfo.options:= + checkfontoptions(avalue,finfopo^.baseinfo.options); + releasehandles; + end; +end; + +function tfont.getrotation: real; +begin + result:= finfopo^.rotation; +end; + +procedure tfont.setrotation(const avalue: real); +begin + if finfopo^.rotation <> avalue then begin + finfopo^.rotation:= avalue; + releasehandles(true); + end; +end; + +function tfont.getxscale: real; +begin + result:= finfopo^.baseinfo.xscale; +end; + +procedure tfont.setxscale(const avalue: real); +begin + include(flocalprops,flp_xscale); + if finfopo^.baseinfo.xscale <> avalue then begin + finfopo^.baseinfo.xscale:= avalue; + releasehandles; + end; +end; + +function tfont.getcharset: string; +begin + result:= finfopo^.baseinfo.charset; +end; + +procedure tfont.setcharset(const Value: string); +begin + if finfopo^.baseinfo.charset <> value then begin + finfopo^.baseinfo.charset:= trim(Value); + releasehandles; + end; +end; + + //icanvas +procedure tfont.gcneeded(const sender: tcanvas); +var + gc: gcty; + err: gdierrorty; +begin + fillchar(gc,sizeof(gcty),0); + gc.kind:= bmk_rgb; //default +// gdi_lock; + err:= sender.creategc(0,gck_screen,gc); +// gdi_unlock; + gdierror(err,self); + sender.linktopaintdevice(0,gc,{nullsize,}nullpoint); +end; +{ +function tfont.getmonochrome: boolean; +begin + result:= false; +end; +} +function tfont.getkind: bitmapkindty; +begin + result:= bmk_rgb; +end; + +function tfont.getsize: sizety; +begin + result:= nullsize; +end; + +function tfont.getbold: boolean; +begin + result:= fs_bold in style; +end; + +procedure tfont.setbold(const avalue: boolean); +begin + if avalue then begin + style:= style + [fs_bold]; + end + else begin + style:= style - [fs_bold]; + end; +end; + +function tfont.getitalic: boolean; +begin + result:= fs_italic in style; +end; + +procedure tfont.setitalic(const avalue: boolean); +begin + if avalue then begin + style:= style + [fs_italic]; + end + else begin + style:= style - [fs_italic]; + end; +end; + +function tfont.getunderline: boolean; +begin + result:= fs_underline in style; +end; + +procedure tfont.setunderline(const avalue: boolean); +begin + if avalue then begin + style:= style + [fs_underline]; + end + else begin + style:= style - [fs_underline]; + end; +end; + +function tfont.getstrikeout: boolean; +begin + result:= fs_strikeout in style; +end; + +procedure tfont.setstrikeout(const avalue: boolean); +begin + if avalue then begin + style:= style + [fs_strikeout]; + end + else begin + style:= style - [fs_strikeout]; + end; +end; + +procedure tfont.scale(const ascale: real); +begin + height:= round(height * ascale); + width:= round(width * ascale); +end; + +procedure tfont.getcanvasimage(const bgr: boolean; var aimage: maskedimagety); +begin + //dummy +end; + +procedure tfont.settemplate(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(ftemplate)); + if (avalue <> nil) and not (csreading in avalue.componentstate) then begin + assign(avalue); + dochanged([],false); + end; +end; + +procedure tfont.settemplateinfo(const ainfo: basefontinfoty); +var + changed1: canvasstatesty = []; +begin + with finfopo^.baseinfo do begin + if not (flp_color in flocalprops) then begin + if color <> ainfo.color then begin + color:= ainfo.color; + include(changed1,cs_fontcolor); + end; + end; + if not (flp_colorbackground in flocalprops) then begin + if colorbackground <> ainfo.colorbackground then begin + colorbackground:= ainfo.colorbackground; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_colorselect in flocalprops) then begin + if colorselect <> ainfo.colorselect then begin + colorselect:= ainfo.colorselect; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_colorselectbackground in flocalprops) then begin + if colorselectbackground <> ainfo.colorselectbackground then begin + colorselectbackground:= ainfo.colorselectbackground; + include(changed1,cs_fontcolorbackground); + end; + end; + if not (flp_shadow_color in flocalprops) then begin + if shadow_color <> ainfo.shadow_color then begin + shadow_color:= ainfo.shadow_color; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_shadow_shiftx in flocalprops) then begin + if shadow_shiftx <> ainfo.shadow_shiftx then begin + shadow_shiftx:= ainfo.shadow_shiftx; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_shadow_shifty in flocalprops) then begin + if shadow_shifty <> ainfo.shadow_shifty then begin + shadow_shifty:= ainfo.shadow_shifty; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_gloss_color in flocalprops) then begin + if gloss_color <> ainfo.gloss_color then begin + gloss_color:= ainfo.gloss_color; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_gloss_shiftx in flocalprops) then begin + if gloss_shiftx <> ainfo.gloss_shiftx then begin + gloss_shiftx:= ainfo.gloss_shiftx; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_gloss_shifty in flocalprops) then begin + if gloss_shifty <> ainfo.gloss_shifty then begin + gloss_shifty:= ainfo.gloss_shifty; + include(changed1,cs_fonteffect); + end; + end; + + if not (flp_grayed_color in flocalprops) then begin + if grayed_color <> ainfo.grayed_color then begin + grayed_color:= ainfo.grayed_color; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_grayed_colorshadow in flocalprops) then begin + if grayed_colorshadow <> ainfo.grayed_colorshadow then begin + grayed_colorshadow:= ainfo.grayed_colorshadow; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_grayed_shifty in flocalprops) then begin + if grayed_shiftx <> ainfo.grayed_shiftx then begin + grayed_shiftx:= ainfo.grayed_shiftx; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_grayed_shifty in flocalprops) then begin + if grayed_shifty <> ainfo.grayed_shifty then begin + grayed_shifty:= ainfo.grayed_shifty; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_xscale in flocalprops) then begin + if (xscale <> 1) and (xscale <> ainfo.xscale) then begin + xscale:= ainfo.xscale; + include(changed1,cs_fonthandle); + end; + end; + if not (flp_style in flocalprops) then begin + if style <> ainfo.style then begin + style:= ainfo.style; + updatehandlepo(); + include(changed1,cs_font); + end; + end; + + if not (flp_height in flocalprops) then begin + if (ainfo.height <> 0) and (height <> + (ainfo.height shl fontsizeshift)) then begin + height:= ainfo.height shl fontsizeshift; + include(changed1,cs_fonthandle); + end; + end; + + if not (flp_width in flocalprops) then begin + if (ainfo.width <> 0) and (width <> + (ainfo.width shl fontsizeshift)) then begin + width:= ainfo.width shl fontsizeshift; + include(changed1,cs_fonthandle); + end; + end; + if not (flp_extraspace in flocalprops) then begin + if extraspace <> ainfo.extraspace then begin + extraspace:= ainfo.extraspace; + include(changed1,cs_font); + end; + end; + if not (flp_name in flocalprops) then begin + if (ainfo.name <> '') and (name <> ainfo.name) then begin + name:= ainfo.name; + include(changed1,cs_fonthandle); + end; + end; + if not (flp_charset in flocalprops) then begin + if charset <> ainfo.charset then begin + charset:= ainfo.charset; + include(changed1,cs_fonthandle); + end; + end; + if not (flp_options in flocalprops) then begin + if (ainfo.options <> []) and (options <> ainfo.options) then begin + options:= ainfo.options; + include(changed1,cs_fonthandle); + end; + end; + + if changed1 <> [] then begin + if cs_fonthandle in changed1 then begin + releasehandles(true); + include(changed1,cs_font); + end; + dochanged(changed1,true); + end; + end; +end; + +function tfont.iscolorstored: boolean; +begin + result:= (ftemplate = nil) and (finfopo^.baseinfo.color <> cl_default) or + (flp_color in flocalprops); +end; + +function tfont.iscolorbackgroundstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.colorbackground <> cl_default) or + (flp_colorbackground in flocalprops); +end; + +function tfont.iscolorselectstored: boolean; +begin + result:= (ftemplate = nil) and (finfopo^.baseinfo.colorselect <> cl_default) or + (flp_colorselect in flocalprops); +end; + +function tfont.iscolorselectbackgroundstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.colorselectbackground <> cl_default) or + (flp_colorselectbackground in flocalprops); +end; + +function tfont.isshadow_colorstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.shadow_color <> cl_none) or + (flp_shadow_color in flocalprops); +end; + +function tfont.isshadow_shiftxstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.shadow_shiftx <> 1) or + (flp_shadow_shiftx in flocalprops); +end; + +function tfont.isshadow_shiftystored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.shadow_shifty <> 1) or + (flp_shadow_shifty in flocalprops); +end; + +function tfont.isgloss_colorstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.gloss_color <> cl_none) or + (flp_gloss_color in flocalprops); +end; + +function tfont.isgloss_shiftxstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.gloss_shiftx <> -1) or + (flp_gloss_shiftx in flocalprops); +end; + +function tfont.isgloss_shiftystored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.gloss_shifty <> -1) or + (flp_gloss_shifty in flocalprops); +end; + +function tfont.isgrayed_colorstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.grayed_color <> cl_grayed) or + (flp_grayed_color in flocalprops); +end; + +function tfont.isgrayed_colorshadowstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.grayed_colorshadow <> cl_grayedshadow) or + (flp_grayed_colorshadow in flocalprops); +end; + +function tfont.isgrayed_shiftxstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.grayed_shifty <> 1) or + (flp_grayed_shifty in flocalprops); +end; + +function tfont.isgrayed_shiftystored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.grayed_shifty <> 1) or + (flp_grayed_shifty in flocalprops); +end; + +function tfont.isxscalestored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.xscale <> 1) or (flp_xscale in flocalprops); +end; + +function tfont.isstylestored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.style <> []) or (flp_style in flocalprops); +end; + +function tfont.isheightstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.height <> 0) or (flp_height in flocalprops); +end; + +function tfont.iswidthstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.width <> 0) or (flp_width in flocalprops); +end; + +function tfont.isextraspacestored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.extraspace <> 0) or + (flp_extraspace in flocalprops); +end; + +function tfont.isnamestored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.name <> '') or (flp_name in flocalprops); +end; + +function tfont.ischarsetstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.charset <> '') or (flp_charset in flocalprops); +end; + +function tfont.isoptionsstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.options <> []) or (flp_options in flocalprops); +end; + +procedure tfont.objectevent(const sender: tobject; const event: objecteventty); +begin + inherited; + if (event = oe_changed) and (ftemplate <> nil) and + (ftemplate = sender) then begin + settemplateinfo(tfontcomp(sender).template.fi); + dochanged([],false); + end; +end; + +{ tcanvasfont } + +constructor tcanvasfont.create(const acanvas: tcanvas); +begin + fcanvas:= acanvas; + fgdifuncs:= fcanvas.getgdifuncs; + finfopo:= @fcanvas.fvaluepo^.font; + inherited create; +end; + +procedure tcanvasfont.dochanged(const changed: canvasstatesty; + const nochange: boolean); +begin +// inherited; + fcanvas.valueschanged(changed); +end; + +function tcanvasfont.gethandle: fontnumty; +begin + if fhandlepo^ = 0 then begin + createhandle(fcanvas); + end; + result:= fhandlepo^; +// result:= gethandleforcanvas(fcanvas); +end; + +procedure tcanvasfont.assignproperties(const source: tfont; + const ahandles: boolean); +begin + inherited assignproperties(source,ahandles and + (source.finfopo^.gdifuncs = fgdifuncs)); +end; + +{ tcanvas } + +constructor tcanvas.create(const user: tobject; const intf: icanvas); +begin + fdrawinfo.gc.gdifuncs:= getgdifuncs; //default + fdrawinfo.gc.fontgdifuncs:= fdrawinfo.gc.gdifuncs; + fuser:= user; + fintf:= pointer(intf); + with fvaluestack do begin + setlength(stack,1); + count:= 1; + fvaluepo:= @stack[0]; + end; + ffont:= createfont; + initflags(self); + init; +end; + +destructor tcanvas.destroy; +var + int1: integer; +begin + inherited; + unlink; //deinit, unregister defaultfont + ffont.free; + freebuffer(fdrawinfo.buffer); + for int1:= 0 to high(fgclinksto) do begin + removeitem(pointerarty(tcanvas(fgclinksto[int1]).fgclinksfrom),self); + end; + for int1:= 0 to high(fgclinksfrom) do begin + removeitem(pointerarty(tcanvas(fgclinksfrom[int1]).fgclinksto),self); + end; +end; + +function tcanvas.creategc(const apaintdevice: paintdevicety; + const akind: gckindty; + var gc: gcty; const aprintername: msestring = ''): gdierrorty; +begin + with fdrawinfo.creategc do begin + paintdevice:= apaintdevice; + kind:= akind; + printernamepo:= @aprintername; + contextinfopo:= getcontextinfopo; + gcpo:= @gc; + getgdifuncs^[gdf_creategc](fdrawinfo); + if gc.fontgdifuncs = nil then begin + gc.fontgdifuncs:= gc.gdifuncs; + end; + result:= error; + end; +end; + +procedure tcanvas.registergclink(const dest: tcanvas); +begin + adduniqueitem(pointerarty(dest.fgclinksto),self); + adduniqueitem(pointerarty(fgclinksfrom),dest); +end; + +procedure tcanvas.unregistergclink(const dest: tcanvas); +begin + removeitem(pointerarty(dest.fgclinksto),self); + removeitem(pointerarty(fgclinksfrom),dest); +end; + +procedure tcanvas.gcdestroyed(const sender: tcanvas); +begin + //dummy +end; + +function tcanvas.createfont: tcanvasfont; +begin + result:= tcanvasfont.create(self); +end; + +class function tcanvas.getclassgdifuncs: pgdifunctionaty; +begin + result:= getdefaultgdifuncs; +end; + +function tcanvas.getgdifuncs: pgdifunctionaty; +begin + result:= getclassgdifuncs; +// result:= gui_getgdifuncs; +end; + +procedure tcanvas.error(nr: gdierrorty; const text: msestring); +begin + gdierror(nr,fuser,text); +end; + +function tcanvas.lock: boolean; +begin + result:= not gdi_locked(); + if result then begin + gdi_lock(); + end; +{ + with application do begin + result:= not gdilocked(); + if result then begin + lockgdi(); + end; + end; +} +end; + +procedure tcanvas.unlock; +begin + gdi_unlock(); +// application.unlockgdi(); +end; + +procedure tcanvas.doflush; +begin + fdrawinfo.gc.gdifuncs^[gdf_flush](fdrawinfo); + gui_flushgdi; +end; + +procedure tcanvas.gdi(const func: gdifuncty); +begin + if lock then begin + try + fdrawinfo.gc.gdifuncs^[func](fdrawinfo); + if flushgdi then begin + doflush(); + end; + finally + unlock; + end; + end + else begin + fdrawinfo.gc.gdifuncs^[func](fdrawinfo); + if flushgdi then begin + doflush(); + end; + end; +end; + +procedure tcanvas.checkrect(const rect: rectty); +begin + if (rect.cx < 0) or (rect.cy < 0) then begin + error(gde_invalidrect,''); + end; +end; + + +procedure tcanvas.intparametererror(value: integer; const text: msestring); +begin + error(gde_parameter,text + ' ' + inttostrmse(value)); +end; + +procedure tcanvas.initgcvalues; +begin + gccolorbackground:= cl_none; + gccolorforeground:= cl_none; + gcoptions:= []; + gcfonthandle1:= 0; + fstate:= fstate - changedmask; +end; + +procedure tcanvas.initgcstate; +begin + initgcvalues; +end; + +procedure tcanvas.finalizegcstate; +begin + //dummy +end; + +//var +// gcident: longword; + +procedure tcanvas.linktopaintdevice(apaintdevice: paintdevicety; + const gc: gcty; const cliporigin: pointty); +var + rea1: real; + int1: integer; + func1: pgdifunctionaty; + func2: pgdifunctionaty; +begin + resetpaintedflag; + if (fdrawinfo.gc.handle <> 0) then begin + for int1:= 0 to high(fgclinksto) do begin + fgclinksto[int1].gcdestroyed(self); + end; + gdi(gdf_destroygc); + end; + fdrawinfo.paintdevice:= apaintdevice; + rea1:= fdrawinfo.gc.ppmm; + func1:= fdrawinfo.gc.gdifuncs; + func2:= fdrawinfo.gc.fontgdifuncs; + fdrawinfo.gc:= gc; + if fdrawinfo.gc.fontgdifuncs = nil then begin + fdrawinfo.gc.fontgdifuncs:= fdrawinfo.gc.gdifuncs; + end; + fdrawinfo.gc.ppmm:= rea1; //restore + if fdrawinfo.gc.gdifuncs = nil then begin + fdrawinfo.gc.gdifuncs:= func1; //restore in case of unlink + fdrawinfo.gc.fontgdifuncs:= func2; //restore in case of unlink + end; + updatecliporigin(cliporigin); + if gc.handle <> 0 then begin + gdi(gdf_setcliporigin); + end; + if fdefaultfont <> 0 then begin + releasefont(fdefaultfont); + fdefaultfont:= 0; + end; + if gc.handle <> 0 then begin + initgcstate; + end + else begin + finalizegcstate; + end; +end; + +procedure tcanvas.unlink; +begin + reset; + gdi_lock; + try + linktopaintdevice(0,nullgc,{nullsize,}nullpoint); + finally + gdi_unlock; + end; +end; + +procedure tcanvas.initdrawinfo(var adrawinfo: drawinfoty); +begin + with fdrawinfo do begin + adrawinfo.paintdevice:= paintdevice; + adrawinfo.gc:= gc; + end; +end; + +// +// save stack, properties +// + +procedure tcanvas.init; + + procedure initvalues(var values: canvasvaluesty); + begin + with values do begin + if icanvas(fintf).getkind = bmk_mono then begin + color:= cl_1; + colorbackground:= cl_0; + font.baseinfo.color:= cl_1; + font.baseinfo.colorbackground:= cl_transparent; + end + else begin + color:= cl_black; + colorbackground:= cl_transparent; + font.baseinfo.color:= cl_default; + font.baseinfo.colorbackground:= cl_default; + end; + rasterop:= rop_copy; + end; + end; + +begin + fdrawinfo.gc.ppmm:= defaultppmm; + restore(0); +// reset; + initvalues(fvaluestack.stack[0]); + initvalues(fvaluestack.stack[1]); +end; + +procedure tcanvas.reset; +begin + restore(0); + fstate:= fstate - changedmask; +// clipregion:= 0; +// origin:= nullpoint; +end; + +function tcanvas.save: integer; +var + int1,int2: integer; + +begin +// if fdrawinfo.gc.handle <> 0 then begin +// checkgcstate([]); //update pending changes +// end; + with fvaluestack do begin + result:= count-1; + if count >= length(stack) then begin + setlength(stack,count+1); + end; + if count > 0 then begin + system.move(stack[count-1],stack[count],sizeof(canvasvaluesty)); + end + else begin + error(gde_invalidsaveindex,'save 0'); + end; + fvaluepo:= @stack[count]; + for int1:= 0 to high(fvaluepo^.font.handles) do begin + int2:= fvaluepo^.font.handles[int1]; + if int2 <> 0 then begin + addreffont(int2); + end; + end; + stringaddref(fvaluepo^.font.baseinfo.name); + stringaddref(fvaluepo^.font.baseinfo.charset); + updatefontinfo; + fvaluepo^.changed:= []; //reset changes + inc(count); + end; +end; + +procedure tcanvas.freevalues(var values: canvasvaluesty); +var + int1,int2: integer; +begin + with values do begin + if cs_regioncopy in changed then begin + destroyregion(clipregion); + end; + for int1:= 0 to high(values.font.handles) do begin + int2:= values.font.handles[int1]; + if int2 <> 0 then begin + releasefont(int2); + values.font.handles[int1]:= 0; + end; + end; +// stringrelease({fvaluepo^.}font.name); +// stringrelease({fvaluepo^.}font.charset); + end; + finalize(values); +end; + +function tcanvas.restore(index: integer = -1): integer; +var + int1: integer; + achanged: canvasstatesty; +begin + with fvaluestack do begin + if index >= count then begin + error(gde_invalidsaveindex,inttostrmse(index)); +//index:= count-1; + end; + if index < 0 then begin + if count < 2 then begin + error(gde_invalidsaveindex,inttostrmse(index)); + end; + index:= count - 2; + end; + achanged:= []; + for int1:= count-1 downto index + 1 do begin + achanged:= achanged + stack[int1].changed; + freevalues(stack[int1]); + end; + fstate:= fstate - achanged * changedmask; + fvaluepo:= @stack[index]; + updatefontinfo; + count:= index + 1; + if index = 0 then begin + result:= save; + end + else begin + result:= index; + end; + end; +end; + +procedure tcanvas.valuechanged(value: canvasstatety); +begin + include(fvaluepo^.changed,value); + exclude(fstate,value); +end; + +procedure tcanvas.valueschanged(values: canvasstatesty); +begin + fvaluepo^.changed:= fvaluepo^.changed + values; + fstate:= fstate - values; +end; + +procedure tcanvas.setfont(const Value: tfont); +begin + if ffont <> nil then begin +// if value.fhandlepo^ = 0 then begin +// value.createhandle(self); +// end; + ffont.assignproperties(value,true); +// ffont.assign(Value); + end; +end; + +procedure tcanvas.updatefontinfo; +begin + ffont.finfopo:= @fvaluepo^.font; + ffont.updatehandlepo; +end; + +// +// painting +// + +function ispaintcolor(acolor: colorty): boolean; {$ifdef FPC}inline;{$endif} +begin + result:= (acolor <> cl_transparent) and (acolor <> cl_none); +end; + +procedure tcanvas.checkgcstate(state: canvasstatesty); +var + values: gcvaluesty; + bo1,bo2: boolean; + po1: pfontdataty; +begin + if fdrawinfo.gc.handle = 0 then begin + gdi_lock; + try + icanvas(fintf).gcneeded(self); + finally + gdi_unlock; + end; + if fdrawinfo.gc.handle = 0 then begin + gdierror(gde_invalidgc,fuser); + end; + end; + if state = [cs_gc] then begin + exit; + end; + include(fstate,cs_painted); + inc(fdrawinfo.statestamp); + values.mask:= []; + + if not (cs_clipregion in fstate) then begin + values.clipregion:= fvaluepo^.clipregion; + include(values.mask,gvm_clipregion); + include(fstate,cs_clipregion); + end; + if not (cs_origin in fstate) then begin + fdrawinfo.origin:= fvaluepo^.origin; + include(fstate,cs_origin); + exclude(fstate,cs_brushorigin); + end; + if not (cs_rasterop in fstate) then begin + values.rasterop:= fvaluepo^.rasterop; + include(values.mask,gvm_rasterop); + include(fstate,cs_rasterop); + end; + with fdrawinfo,gc do begin + if not (cs_options in fstate) and (cs_options in state) then begin + values.options:= fvaluepo^.options; + if cao_smooth in values.options then begin + include(drawingflags,df_smooth); + end + else begin + exclude(drawingflags,df_smooth); + end; + include(values.mask,gvm_options); + include(fstate,cs_options); + end; + bo2:= df_brush in drawingflags; + drawingflags:= drawingflags - fillmodeinfoflags; + + if (cs_acolorforeground in state) then begin + bo1:= (acolorforeground = cl_brushcanvas); + if ((acolorforeground = cl_brush) or bo1) and (fvaluepo^.brush <> nil) then begin + include(drawingflags,df_brush); + end; + if (df_brush in drawingflags) xor bo2 then begin + include(values.mask,gvm_brushflag); + end; + if (df_brush in drawingflags) and not (cs_brushorigin in fstate) then begin + include(fstate,cs_brushorigin); + include(values.mask,gvm_brushorigin); + values.brushorigin:= fvaluepo^.brushorigin; + end; + if acolorforeground <> gccolorforeground then begin + if df_brush in drawingflags then begin + with fvaluepo^.brush do begin + if not (cs_brush in self.fstate) then begin + include(values.mask,gvm_brush); + values.brush:= fvaluepo^.brush; + end; + if getkind = bmk_mono then begin + include(drawingflags,df_monochrome); + include(state,cs_acolorbackground); + if bo1 then begin //use canvas colors + acolorforeground:= fvaluepo^.color; + acolorbackground:= fvaluepo^.colorbackground; + end + else begin //use brush colors + acolorforeground:= fcolorforeground; + acolorbackground:= fcolorbackground; + end; + end + else begin + exclude(drawingflags,df_monochrome); + end; + end; + include(fstate,cs_brush); + end; + end; + if acolorforeground <> gccolorforeground then begin + if drawingflags * [df_brush,df_monochrome] <> [df_brush] then begin + include(values.mask,gvm_colorforeground); + if kind = bmk_gray then begin + values.colorforeground:= graytopixel(acolorforeground); + end + else begin + values.colorforeground:= colortopixel(acolorforeground); + end; + end; + gccolorforeground:= acolorforeground; + include(fstate,cs_acolorforeground); + end; + end; + if (cs_acolorbackground in state) and (acolorbackground <> gccolorbackground) then begin + include(values.mask,gvm_colorbackground); + if kind = bmk_gray then begin + values.colorbackground:= graytopixel(acolorbackground); + end + else begin + values.colorbackground:= colortopixel(acolorbackground); + end; + gccolorbackground:= acolorbackground; + end; + if ispaintcolor(gccolorbackground) then begin + include(drawingflags,df_opaque); + end + else begin + exclude(drawingflags,df_opaque); + end; + if cs_font in state then begin + if (afonthandle1 <> gcfonthandle1) then begin + include(values.mask,gvm_font); + values.fontnum:= afonthandle1; + po1:= getfontdata(afonthandle1); + values.fontdata:= po1; + with po1^ do begin + values.font:= font; + if (df_highresfont in fdrawinfo.gc.drawingflags) then begin + checkhighresfont(po1,fdrawinfo); + end; + end; + gcfonthandle1:= afonthandle1; + end; + include(drawingflags,df_monochrome); + end; + + state:= (state - fstate) * linecanvasstates; //update lineinfos + if state <> [] then begin + values.lineinfo:= fvaluepo^.lineinfo; + if length(dashes) > 0 then begin + include(fdrawinfo.gc.drawingflags,df_dashed); + end + else begin + exclude(fdrawinfo.gc.drawingflags,df_dashed); + end; + fstate:= fstate + state; + if cs_linewidth in state then include(values.mask,gvm_linewidth); + if cs_dashes in state then include(values.mask,gvm_dashes); + if cs_capstyle in state then include(values.mask,gvm_capstyle); + if cs_joinstyle in state then include(values.mask,gvm_joinstyle); + fstate:= fstate + state; + end; + if values.mask <> [] then begin + fdrawinfo.gcvalues:= @values; + gdi(gdf_changegc); + end; + end; +end; + +function tcanvas.getgchandle: ptruint; +begin + checkgcstate([cs_gc]); + result:= fdrawinfo.gc.handle; +end; + +function tcanvas.getimage(const bgr: boolean): maskedimagety; +begin + fillchar(result,sizeof(result),0); + icanvas(fintf).getcanvasimage(bgr,result); +end; + +function tcanvas.checkforeground(acolor: colorty; lineinfo: boolean): boolean; +begin + with fdrawinfo do begin + if (acolor = cl_default) or (acolor = cl_parent) then begin + acolorforeground:= fvaluepo^.color; + end + else begin + acolorforeground:= acolor; + end; + if ispaintcolor(acolorforeground) then begin + if lineinfo then begin + if length(dashes) > 0 then begin + acolorbackground:= fvaluepo^.colorbackground; + checkgcstate([cs_options,cs_acolorforeground,cs_acolorbackground]+ + linecanvasstates); + end + else begin + checkgcstate([cs_options,cs_acolorforeground]+linecanvasstates); + end; + end + else begin + checkgcstate([cs_options,cs_acolorforeground]); + end; + result:= true; + end + else begin + result:= false; + end; + end; +end; + +procedure tcanvas.checkcolors; +begin + with fdrawinfo do begin + acolorforeground:= fvaluepo^.color; + acolorbackground:= fvaluepo^.colorbackground; + checkgcstate([cs_acolorforeground,cs_acolorbackground]); + end; +end; + +procedure tcanvas.internalcopyarea(asource: tcanvas; const asourcerect: rectty; + const adestrect: rectty; acopymode: rasteropty; + atransparentcolor: colorty; + amask: tsimplebitmap; + const amaskpos: pointty; + aalignment: alignmentsty; + const atileorigin: pointty; + const aopacity: colorty); //cl_none -> opaque + + //todo: use serverside tiling + // limit stretched rendering to cliprects +var + srect,drect,rect1: rectty; + spoint,dpoint,tileorig: pointty; + startx: integer; + endx,endy: integer; +// endcx,endcy: integer; + stepx,stepy: integer; + sourcex,sourcey: integer; + int1{,int2}: integer; +// bo1,bo2: boolean; + + function checkmaskrect(var arect,brect: rectty): boolean; + var + rect2: rectty; + begin + rect2:= intersectrect(arect,mr(amaskpos,amask.size)); + if (rect2.cx < arect.cx) or (rect2.cy < arect.cy) then begin + //mask not big enough + if (rect2.cx <= 0) or (rect2.cy <= 0) then begin + result:= true; + exit; + end; + brect.x:= brect.x + (rect2.x - arect.x) * brect.cx div arect.cx; + brect.y:= brect.y + (rect2.y - arect.y) * brect.cy div arect.cy; + brect.cx:= (brect.cx * rect2.cx) div arect.cx; + brect.cy:= (brect.cy * rect2.cy) div arect.cy; + arect:= rect2; + end; + result:= false; + end; + +var + al1: alignmentsty; +begin + if (asourcerect.cx <= 0) or (asourcerect.cy <= 0) or + (adestrect.cx <= 0) or (adestrect.cy <= 0) then begin //no div 0 + exit; + end; + if (al_thumbnail in aalignment) and ((asourcerect.cx > adestrect.cx) or + (asourcerect.cy > adestrect.cy)) then begin + include(aalignment,al_fit); + end; + checkgcstate([]); //gc must be valid + if asource <> self then begin + asource.checkgcstate([cs_gc]); //gc must be valid + end; + dpoint:= adestrect.pos; + if aalignment * [al_fit{,al_tiled}] = [] then begin + if not (al_stretchx in aalignment) then begin + int1:= adestrect.cx - asourcerect.cx; + if al_right in aalignment then begin + dpoint.x:= dpoint.x + int1; + end + else begin + if al_xcentered in aalignment then begin + if int1 < 0 then begin + dec(int1); + end; + dpoint.x:= dpoint.x + int1 div 2; + end; + end; + end; + if not (al_stretchy in aalignment) then begin + int1:= adestrect.cy - asourcerect.cy; + if al_bottom in aalignment then begin + dpoint.y:= dpoint.y + int1; + end + else begin + if al_ycentered in aalignment then begin + if int1 < 0 then begin + dec(int1); + end; + dpoint.y:= dpoint.y + int1 div 2; + end; + end; + end; + end; + tileorig:= atileorigin; + if al_tiled in aalignment then begin + if aalignment * [al_xcentered,al_right] <> [] then begin + tileorig.x:= dpoint.x; + end; + if aalignment * [al_ycentered,al_bottom] <> [] then begin + tileorig.y:= dpoint.y; + end; + dpoint:= adestrect.pos; + end; + dpoint.x:= dpoint.x + fdrawinfo.origin.x; + dpoint.y:= dpoint.y + fdrawinfo.origin.y; + tileorig.x:= tileorig.x + fdrawinfo.origin.x; + tileorig.y:= tileorig.y + fdrawinfo.origin.y; + with asourcerect,asource.fvaluepo^ do begin + spoint.x:= x + origin.x; + spoint.y:= y + origin.y; + end; + rect1:= moverect(clipbox,fvaluepo^.origin); + drect.size:= adestrect.size; + if not msegraphutils.intersectrect(makerect(spoint,asourcerect.size), + makerect(makepoint(0,0),icanvas(asource.fintf).getsize),srect) then begin + exit; + end; + al1:= aalignment * [al_stretchx,al_stretchy,al_fit,al_tiled]; + if al1 = [] then begin //clip areas to paintdevice rect + dpoint.x:= dpoint.x + srect.x - spoint.x; + dpoint.y:= dpoint.y + srect.y - spoint.y; + if not msegraphutils.intersectrect(makerect(dpoint,srect.size), + rect1,drect) then begin + exit; + end; + srect.x:= srect.x + drect.x - dpoint.x; + srect.cx:= drect.cx; + srect.y:= srect.y + drect.y - dpoint.y; + srect.cy:= drect.cy; + end + else begin + srect.pos:= spoint; + srect.size:= asourcerect.size; + drect.pos:= dpoint; + if al1 = [al_stretchx] then begin + drect.cy:= srect.cy; + end; + if al1 = [al_stretchy] then begin + drect.cx:= srect.cx; + end; + end; + if amask <> nil then begin + if al_nomaskscale in aalignment then begin + if checkmaskrect(drect,srect) then begin + exit; + end; + end + else begin + if checkmaskrect(srect,drect) then begin + exit; + end; + end; + end; + with fdrawinfo,copyarea do begin + source:= asource; + sourcerect:= @srect; + destrect:= @drect; + alignment:= aalignment; + copymode:= acopymode; + mask:= amask; + if (srect.cx = 0) or (srect.cy = 0) then begin + exit; + end; + if al_fit in aalignment then begin + alignment:= alignment + [al_stretchx,al_stretchy]; + if srect.cy * drect.cx > srect.cx * drect.cy then begin //fit vert + drect.cx:= (srect.cx * drect.cy) div srect.cy; + int1:= adestrect.cx - drect.cx; + if al_right in aalignment then begin + drect.x:= drect.x + int1; + end + else begin + if al_xcentered in aalignment then begin + if int1 < 0 then begin + dec(int1); + end; + drect.x:= drect.x + int1 div 2; + end; + end; + end + else begin + drect.cy:= (srect.cy * drect.cx) div srect.cx; + int1:= adestrect.cy - drect.cy; + if al_bottom in aalignment then begin + drect.y:= drect.y + int1; + end + else begin + if al_ycentered in aalignment then begin + if int1 < 0 then begin + dec(int1); + end; + drect.y:= drect.y + int1 div 2; + end; + end; + end; + end; + maskshift.x:= -amaskpos.x; + maskshift.y:= -amaskpos.y; + maskshiftscaled.x:= (maskshift.x*drect.cx) div srect.cx; + maskshiftscaled.y:= (maskshift.y*drect.cy) div srect.cy; + if aopacity = cl_none then begin + longword(opacity):= maxopacity; + end + else begin + opacity:= colortorgb(aopacity); + end; + + if gc.kind <> source.fdrawinfo.gc.kind then begin //different colorformat + include(gc.drawingflags,df_colorconvert); + with fdrawinfo,gc do begin + acolorforeground:= fvaluepo^.color; + if source.fdrawinfo.gc.kind = bmk_mono then begin //monochrome to color or gray + acolorbackground:= fvaluepo^.colorbackground; + checkgcstate([cs_acolorforeground,cs_acolorbackground]); + end + else begin + if gc.kind = bmk_mono then begin //color or gray to monochrome + if atransparentcolor = cl_default then begin + atransparentcolor:= fvaluepo^.colorbackground; + end; + if source.fdrawinfo.gc.kind = bmk_gray then begin + transparentcolor:= graytopixel(atransparentcolor); + end + else begin + transparentcolor:= colortopixel(atransparentcolor); + end; + end; + end; + end; + end + else begin + exclude(gc.drawingflags,df_colorconvert); + end; + end; + if al_tiled in aalignment then begin + if msegraphutils.intersectrect(drect,rect1,rect1) then begin + if not (al_stretchy in aalignment) then begin + drect.cy:= srect.cy; + if drect.y >= tileorig.y then begin + drect.y:= tileorig.y + ((rect1.y - tileorig.y) div srect.cy) * srect.cy; + end + else begin + drect.y:= tileorig.y - ((tileorig.y - rect1.y + srect.cy) div srect.cy) * srect.cy; + end; + end; + if not (al_stretchx in aalignment) then begin + drect.cx:= srect.cx; + if drect.x >= tileorig.x then begin + startx:= tileorig.x + ((rect1.x - tileorig.x) div srect.cx) * srect.cx; + end + else begin + startx:= tileorig.x - ((tileorig.x - rect1.x + srect.cx) div srect.cx) * srect.cx; + end; + end + else begin + startx:= drect.x; + end; + stepx:= srect.cx; + stepy:= srect.cy; + endx:= rect1.x + rect1.cx; + endy:= rect1.y + rect1.cy; + sourcex:= srect.x; + sourcey:= srect.y; + if not (al_stretchy in aalignment) then begin + int1:= drect.y - rect1.y; + if int1 < 0 then begin + dec(srect.y,int1); + dec(drect.y,int1); + inc(srect.cy,int1); + drect.cy:= srect.cy; + end; + end; + if al_stretchx in aalignment then begin + int1:= 0; + end + else begin + int1:= startx - rect1.x; + if int1 > 0 then begin + int1:= 0; + end; + end; + repeat + if not (al_stretchy in aalignment) then begin + if drect.y + srect.cy > endy then begin + srect.cy:= endy - drect.y; + end; + drect.cy:= srect.cy; + end; + drect.x:= startx; + dec(srect.x,int1); + dec(drect.x,int1); + inc(srect.cx,int1); + repeat + if not (al_stretchx in aalignment) then begin + if drect.x + srect.cx > endx then begin + srect.cx:= endx - drect.x; + end; + drect.cx:= srect.cx; + end; + if (srect.cx > 0) and (srect.cy > 0) then begin + gdi(gdf_copyarea); + end; + inc(drect.x,srect.cx); + srect.cx:= stepx; + srect.x:= sourcex; + until (al_stretchx in aalignment) or (drect.x >= endx); + inc(drect.y,srect.cy); + srect.y:= sourcey; + srect.cy:= stepy; + drect.cy:= stepy; + until (al_stretchy in aalignment) or (drect.y >= endy); + end; + end + else begin + gdi(gdf_copyarea); + end; + if amask <> nil then begin + exclude(fstate,cs_clipregion); + end; +end; + +procedure tcanvas.copyarea(const asource: tcanvas; const asourcerect: rectty; + const adestpoint: pointty; + const acopymode: rasteropty = rop_copy; + const atransparentcolor: colorty = cl_default; + const aopacity: colorty = cl_none); +begin + if cs_inactive in fstate then exit; + internalcopyarea(asource,asourcerect,makerect(adestpoint,asourcerect.size), + acopymode,atransparentcolor,nil,nullpoint,[],nullpoint,aopacity); +end; + +procedure tcanvas.copyarea(const asource: tcanvas; const asourcerect: rectty; + const adestrect: rectty; const alignment: alignmentsty = []; + const acopymode: rasteropty = rop_copy; + const atransparentcolor: colorty = cl_default; + //atransparentcolor used for convert color to monochrome + //cl_default -> colorbackground + const aopacity: colorty = cl_none); +begin + if cs_inactive in fstate then exit; + internalcopyarea(asource,asourcerect,adestrect, + acopymode,atransparentcolor,nil,nullpoint,alignment, + nullpoint,aopacity); +end; + +procedure tcanvas.drawpoints(const apoints: array of pointty; const acolor: colorty; + first, acount: integer); +var + int1,int2: integer; + pointar: pointarty; +begin + if cs_inactive in fstate then exit; + if length(apoints) > 0 then begin + if checkforeground(acolor,true) then begin + with fdrawinfo.points do begin + int1:= length(apoints) - first; + if int1 < 0 then begin + intparametererror(first,'drawpoints first'); + end; + if acount < 0 then begin + acount:= int1; + end + else begin + if acount > int1 then begin + intparametererror(acount,'drawponts acount'); + end; + end; + count:= 2*acount; + setlength(pointar,count); + int2:= 0; + for int1:= first to first + acount - 1 do begin + pointar[int2]:= apoints[int1]; + pointar[int2+1]:= apoints[int1]; + inc(int2,2); + end; + points:= @pointar[0]; + end; + gdi(gdf_drawlinesegments); + end; + end; +end; + +procedure tcanvas.drawpoint(const point: pointty; + const acolor: colorty = cl_default); +begin + if cs_inactive in fstate then exit; + drawpoints(point,acolor,0,1); +end; + +procedure tcanvas.drawlines(const apoints: array of pointty; + const aclosed: boolean = false; + const acolor: colorty = cl_default; + const first: integer = 0; const acount: integer = -1); + //-1 -> all +var + int1: integer; +begin + if cs_inactive in fstate then exit; + if length(apoints) > 0 then begin + if checkforeground(acolor,true) then begin + with fdrawinfo.points do begin + int1:= length(apoints) - first; + if int1 < 0 then begin + intparametererror(first,'drawlines first'); + end; + if acount < 0 then begin + count:= int1; + end + else begin + if acount > int1 then begin + intparametererror(acount,'drawlines acount'); + end; + count:= acount; + end; + int1:= count - 2; + if (int1 > 0) and (apoints[int1].x = apoints[int1+1].x) and + (apoints[int1].y = apoints[int1+1].y) then begin + //coincident endpoints are not drawn on x11 + dec(count); + end; + closed:= aclosed; + points:= @apoints[first]; + end; + gdi(gdf_drawlines); + end; + end; +end; + +procedure tcanvas.drawlines(const apoints: array of pointty; + const abreaks: array of integer; //ascending order + const aclosed: boolean = false; + const acolor: colorty = cl_default; + const first: integer = 0; const acount: integer = -1); +var + int1: integer; + s,e: integer; + e1: integer; +begin + if cs_inactive in fstate then exit; + if length(apoints) > 0 then begin + if checkforeground(acolor,true) then begin + int1:= length(apoints) - first; + if int1 < 0 then begin + intparametererror(first,'drawlines first'); + end; + if acount < 0 then begin + e1:= int1; + end + else begin + if acount > int1 then begin + intparametererror(acount,'drawlines acount'); + end; + e1:= acount; + end; + + s:= first; + e1:= s + e1; + int1:= 0; + while int1 <= high(abreaks) do begin + if abreaks[int1] > s then begin + break; + end; + inc(int1); + end; + with fdrawinfo.points do begin + closed:= false; + repeat + e:= e1; + if (int1 <= high(abreaks)) and (abreaks[int1] < e) then begin + e:= abreaks[int1]; + inc(int1); + end; + points:= @apoints[s]; + count:= e-s; + if (first = 0) and (e = length(apoints)) then begin + closed:= aclosed; + end; + gdi(gdf_drawlines); + s:= e; + until e = e1; + end; + end; + end; +end; + +procedure tcanvas.drawrect(const arect: rectty; const acolor: colorty = cl_default); +begin + if cs_inactive in fstate then exit; + with arect do begin + drawlines([pos,makepoint(x+cx,y),makepoint(x+cx,y+cy),makepoint(x,y+cy)], + true,acolor); + end; +end; + +procedure tcanvas.drawcross(const arect: rectty; const acolor: colorty = cl_default; + const alignment: alignmentsty = [al_xcentered,al_ycentered]); +var + ar1: segmentarty; +begin + if cs_inactive in fstate then exit; + if (arect.cx > 0) and (arect.cy > 0) then begin + setlength(ar1,2); + with arect do begin + with ar1[0] do begin + a:= pos; + b.x:= x + cx - 1; + b.y:= y + cy - 1; + end; + with ar1[1] do begin + a.x:= x; + a.y:= ar1[0].b.y; + b.x:= ar1[0].b.x; + b.y:= y; + end; + drawlinesegments(ar1,acolor); + end; + end; +end; + +procedure tcanvas.drawlinesegments(const apoints: array of segmentty; + const acolor: colorty = cl_default); +begin + if cs_inactive in fstate then exit; + if length(apoints) > 0 then begin + if (high(apoints) >= 0) and checkforeground(acolor,true) then begin + with fdrawinfo.points do begin + points:= @apoints[0]; + count:= length(apoints) * 2; + end; + gdi(gdf_drawlinesegments); + end; + end; +end; + +procedure tcanvas.drawline(const startpoint,endpoint: pointty; + const acolor: colorty = cl_default); +begin + if cs_inactive in fstate then exit; + drawlinesegments([segment(startpoint,endpoint)],acolor); +end; + +procedure tcanvas.drawline(const startpoint: pointty; const length: sizety; + const acolor: colorty = cl_default); +var + seg1: segmentty; +begin + if cs_inactive in fstate then exit; + seg1.a:= startpoint; + seg1.b.x:= seg1.a.x + length.cx; + seg1.b.y:= seg1.a.y + length.cy; + drawlinesegments([seg1],acolor); +end; + +procedure tcanvas.drawvect(const startpoint: pointty; + const direction: graphicdirectionty; + const length: integer; out endpoint: pointty; + const acolor: colorty = cl_default); +var + endpoint1: pointty; +begin + if cs_inactive in fstate then exit; + endpoint1:= startpoint; + case direction of + gd_right: inc(endpoint1.x,length); + gd_up: dec(endpoint1.y,length); + gd_left: dec(endpoint1.x,length); + gd_down: inc(endpoint1.y,length); + else begin + endpoint:= endpoint1; + exit; + end; + end; + drawlinesegments([segment(startpoint,endpoint1)],acolor); + endpoint:= endpoint1; +end; + +procedure tcanvas.drawvect(const startpoint: pointty; + const direction: graphicdirectionty; + const length: integer; const acolor: colorty = cl_default); +var + po1: pointty; +begin + if cs_inactive in fstate then exit; + drawvect(startpoint,direction,length,po1,acolor); +end; + +procedure tcanvas.drawellipse(const def: rectty; + const acolor: colorty = cl_default); + //def.pos = center, def.cx = width, def.cy = height +begin + if cs_inactive in fstate then exit; + if checkforeground(acolor,true) then begin + fdrawinfo.rect.rect:= @def; + gdi(gdf_drawellipse); + end; +end; + +procedure tcanvas.drawcircle(const center: pointty; const radius: integer; + const acolor: colorty = cl_default); +var + rect1: rectty; +begin + rect1.pos:= center; + rect1.cx:= 2*radius; + rect1.cy:= rect1.cx; + drawellipse(rect1,acolor); +end; + +procedure tcanvas.drawellipse1(const def: rectty; + const acolor: colorty = cl_default); + //def.pos = topleft, def.cx = width, def.cy = height +begin + drawellipse(recenterrect(def),acolor); +end; + +procedure tcanvas.drawarc(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default); +begin + if cs_inactive in fstate then exit; + if checkforeground(acolor,true) then begin + fdrawinfo.arc.rect:= @def; + fdrawinfo.arc.startang:= startang; + fdrawinfo.arc.extentang:= extentang; + gdi(gdf_drawarc); + end; +end; + +procedure tcanvas.drawarc(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default); +var + rect1: rectty; +begin + rect1.pos:= center; + rect1.cx:= 2*radius; + rect1.cy:= rect1.cx; + drawarc(rect1,startang,extentang,acolor); +end; + +procedure tcanvas.drawarc1(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default); +begin + drawarc(recenterrect(def),startang,extentang,acolor); +end; + +procedure tcanvas.fillrect(const arect: rectty; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + rect1: rectty; +begin + if cs_inactive in fstate then exit; + if checkforeground(acolor,false) then begin + with fdrawinfo.rect do begin + rect:= @arect; + if (arect.cx < 0) then begin + rect:= @rect1; + rect1.x:= arect.x + arect.cx + 1; + rect1.cx:= -arect.cx; + if arect.cy < 0 then begin + rect1.y:= arect.y + arect.cy + 1; + rect1.cy:= -arect.cy; + end + else begin + rect1.y:= arect.y; + rect1.cy:= arect.cy; + end; + end + else begin + if arect.cy < 0 then begin + rect:= @rect1; + rect1.y:= arect.y + arect.cy + 1; + rect1.cy:= -arect.cy; + rect1.x:= arect.x; + rect1.cx:= arect.cx; + end; + end; + end; + gdi(gdf_fillrect); + end; + if (linecolor <> cl_none) then begin + drawrect(arect,linecolor); + end; +end; + +procedure tcanvas.fillellipse(const def: rectty; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +begin + if (cs_inactive in fstate) or (def.cx = 0) or (def.cy = 0) then exit; + if checkforeground(acolor,false) then begin + with fdrawinfo.rect do begin + rect:= @def; + end; + gdi(gdf_fillellipse); + end; + if (linecolor <> cl_none) then begin + drawellipse(def,linecolor); + end; +end; + +procedure tcanvas.fillcircle(const center: pointty; const radius: integer; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + rect1: rectty; +begin + rect1.pos:= center; + rect1.cx:= 2*radius; + rect1.cy:= rect1.cx; + fillellipse(rect1,acolor,linecolor); +end; + +procedure tcanvas.fillellipse1(const def: rectty; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +begin + fillellipse(recenterrect(def),acolor,linecolor); +end; + +procedure tcanvas.fillarc(const def: rectty; const startang: real; + const extentang: real; const acolor: colorty; + const pieslice: boolean); +begin + if cs_inactive in fstate then exit; + if checkforeground(acolor,false) then begin + fdrawinfo.arc.rect:= @def; + fdrawinfo.arc.startang:= startang; + fdrawinfo.arc.extentang:= extentang; + fdrawinfo.arc.pieslice:= pieslice; + gdi(gdf_fillarc); + end; +end; + +procedure tcanvas.getarcinfo(out startpo,endpo: pointty); +var + stopang: real; +begin + with fdrawinfo,arc,rect^ do begin + stopang:= (startang+extentang); + startpo.x:= (round(cos(startang)*cx) div 2) + x; + startpo.y:= (round(-sin(startang)*cy) div 2) + y; + endpo.x:= (round(cos(stopang)*cx) div 2) + x; + endpo.y:= (round(-sin(stopang)*cy) div 2) + y; + end; +end; + +procedure tcanvas.fillarcchord(const def: rectty; const startang: real; + const extentang: real; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + startpo,endpo: pointty; +begin + if cs_inactive in fstate then exit; + fillarc(def,startang,extentang,acolor,false); + if (linecolor <> cl_none) then begin + fdrawinfo.arc.rect:= @def; //necessary for 64 bit + getarcinfo(startpo,endpo); + drawline(startpo,endpo,linecolor); + drawarc(def,startang,extentang,linecolor); + end; +end; + +procedure tcanvas.fillarcchord(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + rect1: rectty; +begin + rect1.pos:= center; + rect1.cx:= 2*radius; + rect1.cy:= rect1.cx; + fillarcchord(rect1,startang,extentang,acolor,linecolor); +end; + +procedure tcanvas.fillarcchord1(const def: rectty; const startang: real; + const extentang: real; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +begin + fillarcchord(recenterrect(def),startang,extentang,acolor,linecolor); +end; + +procedure tcanvas.fillarcpieslice(const def: rectty; const startang: real; + const extentang: real; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + startpo,endpo: pointty; +begin + if cs_inactive in fstate then exit; + fillarc(def,startang,extentang,acolor,true); + if (linecolor <> cl_none) then begin + fdrawinfo.arc.rect:= @def; //necessary for 64 bit + getarcinfo(startpo,endpo); + drawlines([startpo,def.pos,endpo],false,linecolor); + drawarc(def,startang,extentang,linecolor); + end; +end; + +procedure tcanvas.fillarcpieslice(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + rect1: rectty; +begin + rect1.pos:= center; + rect1.cx:= 2*radius; + rect1.cy:= rect1.cx; + fillarcpieslice(rect1,startang,extentang,acolor,linecolor); +end; + +procedure tcanvas.fillarcpieslice1(const def: rectty; const startang: real; + const extentang: real; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +begin + fillarcpieslice(recenterrect(def),startang,extentang,acolor,linecolor); +end; + +procedure tcanvas.fillpolygon(const apoints: array of pointty; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +begin + if cs_inactive in fstate then exit; + if checkforeground(acolor,false) then begin + with fdrawinfo.points do begin + points:= @apoints; + count:= length(apoints); + end; + gdi(gdf_fillpolygon); + end; + if (linecolor <> cl_none) then begin + drawlines(apoints,true,linecolor); + end; +end; + +procedure tcanvas.drawstring(const atext: pmsechar; const acount: integer; + const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false; + const arotation: real = 0); +var + afontnum: integer; + po1: pfontinfoty; + font1: tfont; +// int1: integer; +begin + if cs_inactive in fstate then exit; + with fdrawinfo do begin + if afont <> nil then begin //foreign font + if fs_blank in afont.style then begin + exit; + end; + font1:= afont; + with afont do begin + po1:= finfopo; + rotation:= arotation; + afontnum:= gethandleforcanvas(self); + afonthandle1:= afontnum; + acolorbackground:= colorbackground; + end; + end + else begin + if fs_blank in ffont.style then begin + exit; + end; + font1:= ffont; + ffont.rotation:= arotation; + afonthandle1:= ffont.gethandle; + po1:= @fvaluepo^.font; + with fvaluepo^.font do begin + acolorbackground:= baseinfo.colorbackground; + end; + end; + with fdrawinfo.text16pos do begin + pos:= @apos; + text:= pointer(atext); + count:= acount; + if grayed and (po1^.baseinfo.grayed_colorshadow <> cl_none) or + (po1^.baseinfo.shadow_color <> cl_none) or + (po1^.baseinfo.gloss_color <> cl_none) then begin + if grayed then begin + acolorforeground:= po1^.baseinfo.grayed_colorshadow;//cl_white; + if acolorforeground = cl_default then begin + acolorforeground:= cl_grayedshadow; + end; + inc(pos^.x,po1^.baseinfo.grayed_shiftx); + inc(pos^.y,po1^.baseinfo.grayed_shifty); +// inc(pos^.x,po1^.shadow_shiftx); +// inc(pos^.y,po1^.shadow_shifty); + end + else begin + if po1^.baseinfo.shadow_color <> cl_none then begin + acolorforeground:= po1^.baseinfo.shadow_color; + inc(pos^.x,po1^.baseinfo.shadow_shiftx); + inc(pos^.y,po1^.baseinfo.shadow_shifty); + end + else begin + acolorforeground:= po1^.baseinfo.gloss_color; + inc(pos^.x,po1^.baseinfo.gloss_shiftx); + inc(pos^.y,po1^.baseinfo.gloss_shifty); + end; + end; + acolorbackground:= cl_transparent; + if acolorforeground = cl_default then begin + acolorforeground:= cl_text; + end; + checkgcstate([cs_font,cs_acolorforeground,cs_acolorbackground]); + gdi(gdf_drawstring16); + if grayed then begin + dec(pos^.x,po1^.baseinfo.grayed_shiftx); + dec(pos^.y,po1^.baseinfo.grayed_shifty); + acolorforeground:= po1^.baseinfo.grayed_color;//cl_dkgray; + if acolorforeground = cl_default then begin + acolorforeground:= cl_grayed; + end; + end + else begin + if po1^.baseinfo.shadow_color <> cl_none then begin + dec(pos^.x,po1^.baseinfo.shadow_shiftx); + dec(pos^.y,po1^.baseinfo.shadow_shifty); + if po1^.baseinfo.gloss_color <> cl_none then begin + acolorforeground:= po1^.baseinfo.gloss_color; + inc(pos^.x,po1^.baseinfo.gloss_shiftx); + inc(pos^.y,po1^.baseinfo.gloss_shifty); + checkgcstate([cs_font,cs_acolorforeground,cs_acolorbackground]); + gdi(gdf_drawstring16); + dec(pos^.x,po1^.baseinfo.gloss_shiftx); + dec(pos^.y,po1^.baseinfo.gloss_shifty); + end; + end + else begin + dec(pos^.x,po1^.baseinfo.gloss_shiftx); + dec(pos^.y,po1^.baseinfo.gloss_shifty); + end; + acolorforeground:= po1^.baseinfo.color; + end; + if acolorforeground = cl_default then begin + acolorforeground:= cl_text; + end; + checkgcstate([cs_acolorforeground]); + gdi(gdf_drawstring16); + end + else begin + if grayed then begin + acolorforeground:= po1^.baseinfo.grayed_color; + end + else begin + acolorforeground:= po1^.baseinfo.color; + end; + if acolorforeground = cl_default then begin + acolorforeground:= cl_text; + end; + if acolorbackground = cl_default then begin + acolorbackground:= cl_transparent; + end; + checkgcstate([cs_font,cs_acolorforeground,cs_acolorbackground]); + gdi(gdf_drawstring16); + end; + end; + font1.rotation:= 0; + end; +end; + +procedure tcanvas.drawfontline(const startpoint,endpoint: pointty); + //draws line with font color +var + linewidthbefore: integer; + capstylebefore: capstylety; + pt1,pt2: pointty; + co1: colorty; +begin + linewidthbefore:= linewidth; + capstylebefore:= capstyle; + linewidth:= font.linewidth; + capstyle:= cs_butt; + + with fvaluepo^.font do begin + if (baseinfo.shadow_color <> cl_none) then begin + pt1.x:= startpoint.x + baseinfo.shadow_shiftx; + pt1.y:= startpoint.y + baseinfo.shadow_shifty; + pt2.x:= endpoint.x + baseinfo.shadow_shiftx; + pt2.y:= endpoint.y + baseinfo.shadow_shifty; + drawline(pt1,pt2,baseinfo.shadow_color); + end; + if (baseinfo.gloss_color <> cl_none) then begin + pt1.x:= startpoint.x + baseinfo.gloss_shiftx; + pt1.y:= startpoint.y + baseinfo.gloss_shifty; + pt2.x:= endpoint.x + baseinfo.gloss_shiftx; + pt2.y:= endpoint.y + baseinfo.gloss_shifty; + drawline(pt1,pt2,baseinfo.gloss_color); + end; + end; + co1:= font.color; + if co1 = cl_default then begin + co1:= cl_text; + end; + drawline(startpoint,endpoint,co1); + linewidth:= linewidthbefore; + capstyle:= capstylebefore; +end; + +procedure tcanvas.nextpage; //used by tcustomprintercanvas +begin + //dummy +end; + +procedure tcanvas.drawstring(const atext: msestring; const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false; + const arotation: real = 0); +begin + if cs_inactive in fstate then exit; + drawstring(pointer(atext),length(atext),apos,afont,grayed,arotation); +end; + +function tcanvas.getstringwidth(const atext: pmsechar; const acount: integer; + const afont: tfont = nil): integer; +var + afontnum: integer; +begin + result:= 0; + if atext <> '' then begin + checkgcstate([cs_gc]); + if afont <> nil then begin //foreign font + if fs_blank in afont.style then begin + exit; + end; + afontnum:= afont.gethandleforcanvas(self); + end + else begin + if fs_blank in ffont.style then begin + exit; + end; + afontnum:= ffont.handle; + end; + with fdrawinfo.gettext16width do begin + fontdata:= getfontdata(afontnum); + text:= atext; + count:= acount; + end; + gdi(gdf_gettext16width); + result:= fdrawinfo.gettext16width.result; + end; +end; + +function tcanvas.getstringwidth(const atext: msestring; const afont: tfont = nil): integer; +begin + result:= getstringwidth(pmsechar(atext),length(atext),afont); +end; + +function tcanvas.getfontmetrics(const achar: ucs4char; + const afont: tfont = nil): fontmetricsty; +var + afontnum: integer; +begin + if afont <> nil then begin //foreign font + afontnum:= afont.gethandleforcanvas(self); + end + else begin + afontnum:= ffont.handle; + end; + with fdrawinfo.getfontmetrics do begin + fontdata:= getfontdata(afontnum); + char:= achar; + resultpo:= @result; + end; + checkgcstate([cs_gc]); + gdi(gdf_getfontmetrics); +// gdi_lock; +// gdierrorlocked(gui_getfontmetrics(fdrawinfo),self); + with result do begin + sum:= width - leftbearing - rightbearing; + end; +end; + +function tcanvas.getfontmetrics(const achar: msechar; + const afont: tfont = nil): fontmetricsty; +begin + result:= getfontmetrics(ucs4char(card16(achar)),afont); +end; + +procedure tcanvas.drawframe(const arect: rectty; awidth: integer; + const acolor: colorty; const hiddenedges: edgesty); +var + rect1,rect2: rectty; +begin + if cs_inactive in fstate then exit; + + if ispaintcolor(acolor) then begin + if awidth <> 0 then begin + if awidth < 0 then begin + rect2:= arect; + awidth:= - awidth; + end + else begin + rect2.x:= arect.x - awidth; + rect2.y:= arect.y - awidth; + rect2.cx:= arect.cx + awidth + awidth; + rect2.cy:= arect.cy + awidth + awidth; + end; + if checkforeground(acolor,false) then begin + with fdrawinfo.rect do begin + rect:= @rect1; + with rect2 do begin + rect1.pos:= pos; + rect1.cx:= cx; + rect1.cy:= awidth; + if not (edg_top in hiddenedges) then begin + gdi(gdf_fillrect); //top + end; + rect1.pos.y:= y + cy - awidth; + if not (edg_bottom in hiddenedges) then begin + gdi(gdf_fillrect); //bottom + end; + rect1.pos.y:= y; + rect1.cy:= cy; + if not (edg_top in hiddenedges) then begin + inc(rect1.pos.y,awidth); + dec(rect1.cy,awidth); + end; + if not (edg_bottom in hiddenedges) then begin + dec(rect1.cy,awidth); + end; + rect1.cx:= awidth; + if not (edg_left in hiddenedges) then begin + gdi(gdf_fillrect); //left + end; + rect1.pos.x:= x + cx - awidth; + if not (edg_right in hiddenedges) then begin + gdi(gdf_fillrect); //right + end; + end; + end; + end; + end; + end; +end; + +procedure tcanvas.drawframe(const arect: rectty; awidth: framety; + const acolor: colorty = cl_default; + const hiddenedges: edgesty = []); +var + rect1,rect2: rectty; +begin + if cs_inactive in fstate then exit; + if ispaintcolor(acolor) then begin + rect2:= arect; + if checkforeground(acolor,false) then begin + with fdrawinfo.rect do begin + rect:= @rect1; + with rect2 do begin + rect1.pos:= pos; + rect1.cx:= cx; + rect1.cy:= awidth.top; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + gdi(gdf_fillrect); //top + end; + rect1.pos.y:= y + cy - awidth.bottom; + rect1.cy:= awidth.bottom; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + gdi(gdf_fillrect); //bottom + end; + rect1.pos.y:= y; + rect1.cy:= cy; + inc(rect1.pos.y,awidth.top); + dec(rect1.cy,awidth.top); + dec(rect1.cy,awidth.bottom); + rect1.cx:= awidth.left; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + gdi(gdf_fillrect); //left + end; + rect1.pos.x:= x + cx - awidth.right; + rect1.cx:= awidth.right; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + gdi(gdf_fillrect); //right + end; + end; + end; + end; + end; +end; + +procedure tcanvas.drawxorframe(const arect: rectty; const awidth: integer = -1; + const abrush: tsimplebitmap = nil); +var + rasteropbefore: rasteropty; + brushbefore: tsimplebitmap; + brushoriginbefore: pointty; + int1: integer; +begin + if cs_inactive in fstate then exit; + int1:= -awidth*2; + if (abs(arect.cx) < int1) or (abs(arect.cy) < int1) then begin + fillxorrect(arect,abrush); //avoid xor overlap + end + else begin + rasteropbefore:= rasterop; + rasterop:= rop_xor; + if abrush = nil then begin + drawframe(arect,awidth,cl_white); + end + else begin + brushbefore:= brush; + brushoriginbefore:= brushorigin; + brushorigin:= nullpoint; + brush:= abrush; + drawframe(arect,awidth,cl_brush); + brush:= brushbefore; + brushorigin:= brushoriginbefore; + end; + rasterop:= rasteropbefore; + end; +end; + +procedure tcanvas.drawxorframe(const po1, po2: pointty; const awidth: integer = -1; + const abrush: tsimplebitmap = nil); +begin + if cs_inactive in fstate then exit; + drawxorframe(makerect(po1,makesize(po2.x-po1.x,po2.y-po1.y)),awidth,abrush); +end; + +procedure tcanvas.fillxorrect(const arect: rectty; + const abrush: tsimplebitmap = nil); +var + rasteropbefore: rasteropty; + brushbefore: tsimplebitmap; + brushoriginbefore: pointty; +begin + if cs_inactive in fstate then exit; + rasteropbefore:= rasterop; + rasterop:= rop_xor; + if abrush = nil then begin + fillrect(arect,cl_white); + end + else begin + brushbefore:= brush; + brushoriginbefore:= brushorigin; + brushorigin:= nullpoint; + brush:= abrush; + fillrect(arect,cl_brush); + brush:= brushbefore; + brushorigin:= brushoriginbefore; + end; + rasterop:= rasteropbefore; +end; + +procedure tcanvas.fillxorrect(const start: pointty; const length: integer; + const direction: graphicdirectionty; + const awidth: integer = 0; + const abrush: tsimplebitmap = nil); +var + rect1: rectty; +begin + case direction of + gd_left: begin + rect1.x:= start.x - length; + rect1.y:= start.y - awidth div 2; + rect1.cx:= length; + rect1.cy:= awidth; + end; + gd_down: begin + rect1.y:= start.y; + rect1.x:= start.x - awidth div 2; + rect1.cy:= length; + rect1.cx:= awidth; + end; + gd_up: begin + rect1.y:= start.y - length; + rect1.x:= start.x - awidth div 2; + rect1.cy:= length; + rect1.cx:= awidth; + end; + else begin //gd_right + rect1.x:= start.x; + rect1.y:= start.y - awidth div 2; + rect1.cx:= length; + rect1.cy:= awidth; + end; + end; + fillxorrect(rect1,abrush); +end; + + +// +// region helpers +// + +function tcanvas.createregion: regionty; +begin + fdrawinfo.gc.gdifuncs^[gdf_createemptyregion](fdrawinfo); + result:= fdrawinfo.regionoperation.dest; +end; + +function tcanvas.createregion(const asource: regionty): regionty; +begin + with fdrawinfo.regionoperation do begin + source:= asource; + fdrawinfo.gc.gdifuncs^[gdf_copyregion](fdrawinfo); + result:= dest; + end; +end; + +function tcanvas.createregion(const arect: rectty): regionty; +begin + with fvaluepo^,fdrawinfo.regionoperation do begin + rect:= arect; + inc(rect.x,origin.x); + inc(rect.y,origin.y); + fdrawinfo.gc.gdifuncs^[gdf_createrectregion](fdrawinfo); + result:= dest; + end; +end; + +function tcanvas.createregion(const rects: array of rectty): regionty; +begin + result:= 0; + with fdrawinfo.regionoperation do begin + rectscount:= high(rects) + 1; + if rectscount > 0 then begin + rectspo:= @rects[0]; + adjustrectar(@rects[0],rectscount); + fdrawinfo.gc.gdifuncs^[gdf_createrectsregion](fdrawinfo); + result:= dest; + readjustrectar(@rects[0],rectscount); + end + else begin + result:= createregion; + end; + end; +end; + +function tcanvas.createregion(frame: rectty; const inflate: integer): regionty; + //frame +var + reg1: regionty; +begin + with fvaluepo^ do begin + inc(frame.x,origin.x); + inc(frame.y,origin.y); + end; + if inflate > 0 then begin + result:= createregion(inflaterect(frame,inflate)); + reg1:= createregion(frame); + end + else begin + result:= createregion(frame); + reg1:= createregion(inflaterect(frame,inflate)); + end; + regsubregion(result,reg1); + destroyregion(reg1); +end; + +procedure tcanvas.destroyregion(region: regionty); +begin + with fdrawinfo.regionoperation do begin + source:= region; + fdrawinfo.gc.gdifuncs^[gdf_destroyregion](fdrawinfo); + end; +end; + +procedure tcanvas.regmove(const adest: regionty; const dist: pointty); +begin + with fdrawinfo.regionoperation do begin + dest:= adest; + rect.pos:= dist; + end; + fdrawinfo.gc.gdifuncs^[gdf_moveregion](fdrawinfo); +end; + +procedure tcanvas.regremove(const adest: regionty; const dist: pointty); +begin + regmove(adest,makepoint(-dist.x,-dist.y)); +end; + +procedure tcanvas.initregrect(const adest: regionty; const arect: rectty); +begin + with fdrawinfo,regionoperation do begin + dest:= adest; + rect:= arect; + inc(rect.x,fvaluepo^.origin.x); + dec(rect.x,gc.cliporigin.x); + inc(rect.y,fvaluepo^.origin.y); + dec(rect.y,gc.cliporigin.y); + if rect.x < -$8000 then begin + rect.x:= -$8000; + end; + if rect.x > $7fff then begin + rect.x:= $7fff; + end; + if rect.cx < 0 then begin + rect.cx:= 0; + end; + if rect.cx + rect.x > $7fff then begin + rect.cx:= $7fff - rect.x + end; + if rect.y < -$8000 then begin + rect.y:= -$8000; + end; + if rect.y > $7fff then begin + rect.y:= $7fff; + end; + if rect.cy < 0 then begin + rect.cy:= 0; + end; + if rect.cy + rect.y > $7fff then begin + rect.cy:= $7fff - rect.y; + end; + end; +end; + +procedure tcanvas.initregreg(const adest: regionty; const asource: regionty); +begin + with fdrawinfo,regionoperation do begin + dest:= adest; + source:= asource; + end; +end; + +procedure tcanvas.regsubrect(const dest: regionty; const rect: rectty); +begin + initregrect(dest,rect); + fdrawinfo.gc.gdifuncs^[gdf_regsubrect](fdrawinfo); +end; + +procedure tcanvas.regaddrect(const dest: regionty; const rect: rectty); +begin + initregrect(dest,rect); + fdrawinfo.gc.gdifuncs^[gdf_regaddrect](fdrawinfo); +end; + +procedure tcanvas.regintersectrect(const dest: regionty; const rect: rectty); +begin + initregrect(dest,rect); + fdrawinfo.gc.gdifuncs^[gdf_regintersectrect](fdrawinfo); +end; + +procedure tcanvas.regaddregion(const dest: regionty; const region: regionty); +begin + initregreg(dest,region); + fdrawinfo.gc.gdifuncs^[gdf_regaddregion](fdrawinfo); +end; + +procedure tcanvas.regsubregion(const dest: regionty; const region: regionty); +begin + initregreg(dest,region); + fdrawinfo.gc.gdifuncs^[gdf_regsubregion](fdrawinfo); +end; + +procedure tcanvas.regintersectregion(const dest: regionty; const region: regionty); +begin + initregreg(dest,region); + fdrawinfo.gc.gdifuncs^[gdf_regintersectregion](fdrawinfo); +end; + +function tcanvas.regionisempty(const region: regionty): boolean; +begin + with fdrawinfo.regionoperation do begin + source:= region; + fdrawinfo.gc.gdifuncs^[gdf_regionisempty](fdrawinfo); + result:= dest <> 0; + end; +end; + +function tcanvas.regionclipbox(const region: regionty): rectty; +begin + if region <> 0 then begin + with fdrawinfo.regionoperation do begin + source:= region; + fdrawinfo.gc.gdifuncs^[gdf_regionclipbox](fdrawinfo); + result:= rect; + end; + end + else begin + result:= nullrect; + end; +end; + +// +// clip region functions +// + +procedure tcanvas.setclipregion(const Value: regionty); +begin + with fvaluepo^ do begin + if cs_regioncopy in changed then begin + destroyregion(clipregion); + end; + include(changed,cs_regioncopy); + clipregion := Value; + valuechanged(cs_clipregion); + end; +end; + +procedure tcanvas.subcliprect(const rect: rectty); +begin + checkregionstate; + regsubrect(fvaluepo^.clipregion,rect); +end; + +procedure tcanvas.subclipframe(const frame: rectty; inflate: integer); +var + reg1: regionty; +begin + checkregionstate; + reg1:= createregion(frame,inflate); + regsubregion(fvaluepo^.clipregion,reg1); + destroyregion(reg1); +end; + +procedure tcanvas.subclipregion(const region: regionty); +begin + checkregionstate; + regsubregion(fvaluepo^.clipregion,region); +end; + +procedure tcanvas.addcliprect(const rect: rectty); +begin + checkregionstate; + regaddrect(fvaluepo^.clipregion,rect); +end; + +procedure tcanvas.setcliprect(const rect: rectty); +begin + clipregion:= createregion(removerect(rect,fcliporigin)); +end; + +procedure tcanvas.addclipframe(const frame: rectty; inflate: integer); +var + reg1: regionty; +begin + checkregionstate; + reg1:= createregion(frame,inflate); + regaddregion(fvaluepo^.clipregion,reg1); + destroyregion(reg1); +end; + +procedure tcanvas.addclipregion(const region: regionty); +begin + checkregionstate; + regaddregion(fvaluepo^.clipregion,region); +end; + +procedure tcanvas.intersectcliprect(const rect: rectty); +begin + checkregionstate; + regintersectrect(fvaluepo^.clipregion,rect); +end; + +procedure tcanvas.intersectclipframe(const frame: rectty; inflate: integer); +var + reg1: regionty; +begin + checkregionstate; + reg1:= createregion(frame,inflate); + regintersectregion(fvaluepo^.clipregion,reg1); + destroyregion(reg1); +end; + +procedure tcanvas.intersectclipregion(const region: regionty); +begin + checkregionstate; + regintersectregion(fvaluepo^.clipregion,region); +end; + +procedure tcanvas.resetclipregion; +begin + clipregion:= 0; +end; + +function tcanvas.copyclipregion: regionty; +begin + with fdrawinfo.regionoperation do begin + source:= fvaluepo^.clipregion; + fdrawinfo.gc.gdifuncs^[gdf_copyregion](fdrawinfo); + result:= dest; + end; +end; + +// +// +// + +procedure tcanvas.adjustrectar(po: prectty; count: integer); +var + dx,dy: integer; +begin + dx:= fvaluepo^.origin.x; + dy:= fvaluepo^.origin.y; + if (dx <> 0) or (dy <> 0 ) then begin + while count > 0 do begin + inc(po^.x,dx); + inc(po^.y,dy); + inc(po); + dec(count); + end; + end; +end; + +procedure tcanvas.readjustrectar(po: prectty; count: integer); +var + dx,dy: integer; +begin + dx:= fvaluepo^.origin.x; + dy:= fvaluepo^.origin.y; + if (dx <> 0) or (dy <> 0 ) then begin + while count > 0 do begin + dec(po^.x,dx); + dec(po^.y,dy); + inc(po); + dec(count); + end; + end; +end; + +function tcanvas.getcolor: colorty; +begin + result:= fvaluepo^.color; +end; + +procedure tcanvas.setcolor(const value: colorty); +begin + if fvaluepo^.color <> value then begin + fvaluepo^.color:= value; + valuechanged(cs_color); + end; +end; + +function tcanvas.getcolorbackground: colorty; +begin + result:= fvaluepo^.colorbackground; +end; + +procedure tcanvas.setcolorbackground(const Value: colorty); +begin + if fvaluepo^.colorbackground <> value then begin + fvaluepo^.colorbackground:= value; + valuechanged(cs_colorbackground); + end; +end; + +function tcanvas.getrasterop: rasteropty; +begin + result:= fvaluepo^.rasterop; +end; + +procedure tcanvas.setrasterop(const Value: rasteropty); +begin + if fvaluepo^.rasterop <> value then begin + fvaluepo^.rasterop:= value; + valuechanged(cs_rasterop); + end; +end; + +function tcanvas.getlinewidth: integer; +begin + result:= (fvaluepo^.lineinfo.width + linewidthroundvalue) shr linewidthshift; +end; + +procedure tcanvas.setlinewidth(Value: integer); +begin + value:= value shl linewidthshift; + if fvaluepo^.lineinfo.width <> value then begin + fvaluepo^.lineinfo.width:= value; + valuechanged(cs_linewidth); + end; +end; + +function tcanvas.getlinewidthmm: real; +begin + result:= fvaluepo^.lineinfo.width / + (fdrawinfo.gc.ppmm * (1 shl linewidthshift)); +end; + +procedure tcanvas.setlinewidthmm(const avalue: real); +var + int1: integer; +begin + int1:= round(avalue * (1 shl linewidthshift) * fdrawinfo.gc.ppmm); + if fvaluepo^.lineinfo.width <> int1 then begin + fvaluepo^.lineinfo.width:= int1; + valuechanged(cs_linewidth); + end; +end; + +function tcanvas.getdashes: dashesstringty; +begin + result:= fvaluepo^.lineinfo.dashes; +end; + +procedure tcanvas.setdashes(const Value: dashesstringty); +var + int1: integer; +begin + with fvaluepo^.lineinfo do begin + dashes:= value; + for int1:= 1 to length(dashes) do begin + if dashes[int1] = #0 then begin + setlength(dashes,int1-1); + break; + end; + end; + if odd(length(dashes)) then begin + setlength(dashes,length(dashes)-1); + end; + end; + valuechanged(cs_dashes); +end; + +function tcanvas.getcapstyle: capstylety; +begin + result:= fvaluepo^.lineinfo.capstyle; +end; + +procedure tcanvas.setcapstyle(const Value: capstylety); +begin + fvaluepo^.lineinfo.capstyle:= value; + valuechanged(cs_capstyle); +end; + +function tcanvas.getjoinstyle: joinstylety; +begin + result:= fvaluepo^.lineinfo.joinstyle; +end; + +function tcanvas.getoptions: canvasoptionsty; +begin + result:= fvaluepo^.options; +end; + +procedure tcanvas.setjoinstyle(const Value: joinstylety); +begin + fvaluepo^.lineinfo.joinstyle:= value; + valuechanged(cs_joinstyle); +end; + +procedure tcanvas.setoptions(const avalue: canvasoptionsty); +begin + fvaluepo^.options:= avalue; + valuechanged(cs_options); +end; + +function tcanvas.defaultcliprect: rectty; +begin + result:= makerect(nullpoint,fdrawinfo.gc.paintdevicesize); +end; + +procedure tcanvas.checkregionstate; +begin + with fvaluepo^ do begin + if clipregion = 0 then begin + checkgcstate([cs_gc]); //fsize must be valid + clipregion:= createregion(defaultcliprect); + end + else begin + if not (cs_regioncopy in changed) then begin + clipregion:= createregion(clipregion); + end; + end; + include(changed,cs_regioncopy); + include(changed,cs_clipregion); + end; + exclude(fstate,cs_clipregion); +end; + +procedure tcanvas.move(const dist: pointty); +begin + if (dist.x <> 0) or (dist.y <> 0) then begin + with fvaluepo^ do begin + inc(origin.x,dist.x); + inc(origin.y,dist.y); + end; + valuechanged(cs_origin); + end; +end; + +procedure tcanvas.remove(const dist: pointty); +begin + with fvaluepo^ do begin + dec(origin.x,dist.x); + dec(origin.y,dist.y); + end; + valuechanged(cs_origin); +end; + +function tcanvas.getorigin: pointty; +begin + result:= subpoint(fvaluepo^.origin,fdrawinfo.gc.cliporigin); +end; + +procedure tcanvas.setorigin(const Value: pointty); +var + po1: pointty; +begin + po1:= addpoint(value,fdrawinfo.gc.cliporigin); + if not pointisequal(fvaluepo^.origin,po1) then begin + fvaluepo^.origin:= po1; + valuechanged(cs_origin); + end; +end; + +function tcanvas.clipregionisempty: boolean; +begin + with fvaluepo^ do begin + if clipregion = 0 then begin + result:= false; + end + else begin + result:= regionisempty(clipregion); + end; + end; +end; + +function tcanvas.clipbox: rectty; +begin + with fvaluepo^ do begin + if clipregion = 0 then begin + result:= makerect(makepoint(-origin.x,-origin.y),icanvas(fintf).getsize); + end + else begin + result:= regionclipbox(clipregion); + dec(result.x,origin.x); + inc(result.x,fdrawinfo.gc.cliporigin.x); + dec(result.y,origin.y); + inc(result.y,fdrawinfo.gc.cliporigin.y); + end; + end; +end; + +{ +procedure tcanvas.drawedge(const vector: graphicvectorty; level: integer; + const colorinfo: framecolorinfoty); +//procedure paintkante2(painter: qpainterh; const startpoint: tpoint; +// length: integer; direction: tgraphicdirection; +// width: integer; const color: qcolorh; +// glanz: integer = 0; const colorglanz: qcolorh = nil; +// infos: kanteninfosty = []); + //glanz < 0 -> am schluss bei dark +var + points: tpointarray; + breite1,breite2: integer; + step1a,step2a,step3a: integer; + step1b,step2b,step3b: integer; + reverseoffset: integer; + +begin + if length <= 0 then begin + exit; + end; + if not (kin_dark in infos) then begin + glanz:= -glanz; + end; + setlength(points,8); + points[0]:= startpoint; + if glanz <= 0 then begin //glanz am schluss + breite1:= width+glanz; + qpainter_setpen(painter,color); + qpainter_setbrush(painter,color); + end + else begin //glanz zu beginn + breite1:= glanz; + qpainter_setpen(painter,colorglanz); + qpainter_setbrush(painter,colorglanz); + end; + if breite1 > width then begin + breite1:= width; + end; + if breite1 < 0 then begin + breite1:= 0; + end; + reverseoffset:= 2*width; + dec(length); + dec(width); + dec(breite1); + breite2:= width-breite1-1; + if kin_reverseend in infos then begin + step1a:= -breite1; + step2a:= -1; + step3a:= -width; + length:= length-reverseoffset; + end + else begin + step1a:= breite1; + step2a:= 1; + step3a:= width; + end; + if kin_reversestart in infos then begin + step1b:= -breite1+reverseoffset; + step2b:= -1; + step3b:= -width+reverseoffset; + end + else begin + reverseoffset:= 0; + step1b:= breite1; + step2b:= 1; + step3b:= width; + end; + case direction of + gd_right: begin + points[0].X:= startpoint.X + reverseoffset; + points[1].x:= startpoint.X + length; + points[1].Y:= startpoint.Y; + points[2].X:= points[1].X - step1a; + points[2].Y:= startpoint.Y + breite1; + points[3].x:= startpoint.x + step1b; + points[3].Y:= points[2].Y; + if breite2 >= 0 then begin + points[4].X:= points[3].X + step2b; + points[4].Y:= points[3].Y + 1; + points[5].X:= points[2].X - step2a; + points[5].y:= points[2].y + 1; + points[6].X:= points[1].X - step3a; + points[6].Y:= startpoint.Y + width; + points[7].x:= startpoint.x + step3b; + points[7].Y:= points[6].Y; + end; + end; + gd_up: begin + points[0].y:= startpoint.y - reverseoffset; + points[1].x:= startpoint.X; + points[1].Y:= startpoint.Y-length; + points[2].X:= startpoint.X + breite1; + points[2].Y:= points[1].Y + step1a; + points[3].x:= points[2].x; + points[3].Y:= startpoint.Y - step1b; + if breite2 >= 0 then begin + points[4].X:= points[3].X + 1; + points[4].Y:= points[3].Y - step2b; + points[5].X:= points[2].X + 1; + points[5].y:= points[2].y + step2a; + points[6].X:= startpoint.x + width; + points[6].Y:= points[1].Y + step3a; + points[7].x:= points[6].x; + points[7].Y:= startpoint.y - step3b; + end; + end; + gd_left: begin + points[0].X:= startpoint.X - reverseoffset; + points[1].x:= startpoint.X - length; + points[1].Y:= startpoint.Y; + points[2].X:= points[1].X + step1a; + points[2].Y:= startpoint.Y - breite1; + points[3].x:= startpoint.x - step1b; + points[3].Y:= points[2].Y; + if breite2 >= 0 then begin + points[4].X:= points[3].X - step2b; + points[4].Y:= points[3].Y - 1; + points[5].X:= points[2].X + step2a; + points[5].y:= points[2].y - 1; + points[6].X:= points[1].X + step3a; + points[6].Y:= startpoint.Y - width; + points[7].x:= startpoint.x - step3b; + points[7].Y:= points[6].Y; + end; + end; + gd_down: begin + points[0].y:= startpoint.y + reverseoffset; + points[1].x:= startpoint.X; + points[1].Y:= startpoint.Y+length; + points[2].X:= startpoint.X - breite1; + points[2].Y:= points[1].Y - step1a; + points[3].x:= points[2].x; + points[3].Y:= startpoint.Y + step1b; + if breite2 >= 0 then begin + points[4].X:= points[3].X - 1; + points[4].Y:= points[3].Y + step2b; + points[5].X:= points[2].X - 1; + points[5].y:= points[2].y - step2a; + points[6].X:= startpoint.x - width; + points[6].Y:= points[1].Y - step3a; + points[7].x:= points[6].x; + points[7].Y:= startpoint.y + step3b; + end; + end; + end; + if breite1 >= 0 then begin + if breite1 > 1 then begin + qpainter_drawpolygon(painter,@points[0],false,0,4); + end + else begin + qpainter_moveto(painter,@points[0]); + qpainter_lineto(painter,@points[1]); + if breite1 = 1 then begin + qpainter_moveto(painter,@points[2]); + qpainter_lineto(painter,@points[3]); + end; + end; + end; + if breite2 >= 0 then begin + if glanz < 0 then begin + qpainter_setpen(painter,colorglanz); + qpainter_setbrush(painter,colorglanz); + end + else begin + qpainter_setpen(painter,color); + qpainter_setbrush(painter,color); + end; + if breite2 > 1 then begin + qpainter_drawpolygon(painter,@points[0],false,4,4); + end + else begin + qpainter_moveto(painter,@points[4]); + qpainter_lineto(painter,@points[5]); + if breite2 = 1 then begin + qpainter_moveto(painter,@points[6]); + qpainter_lineto(painter,@points[7]); + end; + end; + end; +end; +} +{ +procedure tcanvas.drawedge(const vector: graphicvectorty; level: integer; + const colorinfo: framecolorinfoty); +var + poly: pointarty; + + procedure shrink(value: integer); + begin + case vector.direction of + gd_right: begin + poly[2].x:= poly[1].x - value; + poly[2].y:= poly[1].y - value; + poly[3].x:= poly[0].x + value; + poly[3].y:= poly[0].y - value; + end; + gd_up: begin + poly[2].x:= poly[1].x - value; + poly[2].y:= poly[1].y + value; + poly[3].x:= poly[0].x - value; + poly[3].y:= poly[0].y - value; + end; + gd_left: begin + poly[2].x:= poly[1].x - value; + poly[2].y:= poly[1].y + value; + poly[3].x:= poly[0].x + value; + poly[3].y:= poly[0].y + value; + end; + gd_down: begin + poly[2].x:= poly[1].x + value; + poly[2].y:= poly[1].y + value; + poly[3].x:= poly[0].x + value; + poly[3].y:= poly[0].y - value; + end; + end; + end; + + procedure offset; + begin + case vector.direction of + gd_right: begin + inc(poly[0].x); + dec(poly[0].y); + dec(poly[1].x); + dec(poly[1].y); + end; + gd_up: begin + dec(poly[0].x); + dec(poly[0].y); + dec(poly[1].x); + inc(poly[1].y); + end; + gd_left: begin + inc(poly[0].x); + inc(poly[0].y); + dec(poly[1].x); + inc(poly[1].y); + end; + gd_down: begin + inc(poly[0].x); + dec(poly[0].y); + inc(poly[1].x); + inc(poly[1].y); + end; + end; + end; + + procedure draw(with1,with2: integer; col1,col2: colorty); + begin + if with1 > 0 then begin + if with1 = 1 then begin + drawlines(poly,col1,2); + end + else begin + shrink(with1); + fillpolygon(poly,col1); + poly[0]:= poly[3]; + poly[1]:= poly[2]; + end; + end; + if with2 > 0 then begin + offset; + if with2 = 1 then begin + drawlines(poly,col2,2); + end + else begin + shrink(with2); + fillpolygon(poly,col2); + end; + end; + end; + +var + topleft,inlight,effectfirst: boolean; + effcol,normcol: colorty; + effwidth: integer; + +begin + if level = 0 then begin + exit; + end; + with colorinfo do begin + topleft:= vector.direction in [gd_left,gd_down]; + inlight:= topleft; + if level < 0 then begin + level:= -level; + inlight:= not inlight; + end; + if inlight then begin + normcol:= collight; + effcol:= colhighlight; + effwidth:= highlight; + end + else begin + normcol:= colshadow; + effcol:= coldkshadow; + effwidth:= dkshadow; + end; + if effwidth < 0 then begin + effwidth:= -effwidth; + effectfirst:= topleft; + end + else begin + effectfirst:= false; + end; + if effwidth > level then begin + effwidth:= level; + level:= 0; + end + else begin + level:= level - effwidth; + end; + if not inlight then begin + if (level = 0) then begin + level:= effwidth; + effwidth:= 0; + end; + end; + end; + setlength(poly,4); + vectortoline(vector,poly[0],poly[1]); + poly[0]:= vector.start; + if effectfirst then begin + draw(effwidth,level,effcol,normcol); + end + else begin + draw(level,effwidth,normcol,effcol); + end; +end; +} +function tcanvas.getbrush: tsimplebitmap; +begin + result:= fvaluepo^.brush; +end; + +procedure tcanvas.setbrush(const Value: tsimplebitmap); +begin + if fvaluepo^.brush <> value then begin + fvaluepo^.brush:= value; + valuechanged(cs_brush); + gccolorforeground:= cl_none; //force reload + end; +end; + +procedure tcanvas.resetpaintedflag; +begin + exclude(fstate,cs_painted); +end; + +function tcanvas.getbrushorigin: pointty; +begin + result.x:= fvaluepo^.brushorigin.x-fvaluepo^.origin.x; + result.y:= fvaluepo^.brushorigin.y-fvaluepo^.origin.y; +end; + +procedure tcanvas.setbrushorigin(const Value: pointty); +begin + fvaluepo^.brushorigin.x:= value.x+fvaluepo^.origin.x; + fvaluepo^.brushorigin.y:= value.y+fvaluepo^.origin.y; + valuechanged(cs_brushorigin); +end; + +function tcanvas.getrootbrushorigin: pointty; +begin + result.x:= fvaluepo^.brushorigin.x-fcliporigin.x; + result.y:= fvaluepo^.brushorigin.y-fcliporigin.y; +end; + +procedure tcanvas.setrootbrushorigin(const Value: pointty); +begin + fvaluepo^.brushorigin.x:= value.x+fcliporigin.x; + fvaluepo^.brushorigin.y:= value.y+fcliporigin.y; + valuechanged(cs_brushorigin); +end; + +procedure tcanvas.adjustbrushorigin(const arect: rectty; + const alignment: alignmentsty); +var + siz1: sizety; + pt1: pointty; +begin + if fvaluepo^.brush <> nil then begin + siz1:= fvaluepo^.brush.size; + end + else begin + siz1:= nullsize; + end; + pt1.x:= -fvaluepo^.origin.x; + pt1.y:= -fvaluepo^.origin.y; + if al_left in alignment then begin + pt1.x:= arect.x; + end + else begin + if al_xcentered in alignment then begin + pt1.x:= arect.x + (arect.cx - siz1.cx) div 2; + end + else begin + if al_right in alignment then begin + pt1.x:= arect.x + arect.cx - siz1.cx; + end; + end; + end; + if al_top in alignment then begin + pt1.y:= arect.y; + end + else begin + if al_ycentered in alignment then begin + pt1.y:= arect.y + (arect.cy - siz1.cy) div 2; + end + else begin + if al_bottom in alignment then begin + pt1.y:= arect.y + arect.cy - siz1.cy; + end; + end; + end; + brushorigin:= pt1; +end; + +function tcanvas.active: boolean; +begin + result:= fdrawinfo.gc.handle <> 0; +end; + +procedure tcanvas.updatecliporigin(const Value: pointty); +var + delta: pointty; + int1: integer; +begin + delta:= subpoint(value,fcliporigin); + fcliporigin:= value; + fdrawinfo.gc.cliporigin:= value; + with fvaluestack do begin + for int1:= 0 to count-1 do begin + addpoint1(stack[int1].origin,delta); + end; + end; + addpoint1(fdrawinfo.origin,delta); +end; + +procedure tcanvas.setcliporigin(const Value: pointty); +begin + checkgcstate([cs_gc]); + updatecliporigin(value); + gdi(gdf_setcliporigin); +end; + +procedure tcanvas.setppmm(avalue: real); +begin + if avalue < 0.1 then begin + avalue:= 0.1; + end; + fdrawinfo.gc.ppmm:= avalue; +end; + +procedure tcanvas.internaldrawtext(var info); +begin + gdierror(gde_notimplemented); +end; + +procedure tcanvas.initflags(const dest: tcanvas); +begin + with dest do begin + exclude(fdrawinfo.gc.drawingflags,df_highresfont); + ffont.releasehandles; + gcfonthandle1:= 0; //invalid + end; +end; + +function tcanvas.highresdevice: boolean; +begin + result:= cs_highresdevice in fstate; +end; + +function tcanvas.getkind: bitmapkindty; +begin + result:= icanvas(fintf).getkind; +end; + +function tcanvas.getcontextinfopo: pointer; +begin + result:= nil; //dummy +end; + +function tcanvas.getcanvasimage(const abgr: boolean = false): imagety; + //todo: handle monochrome and mask +var + int1: integer; +begin + fillchar(fdrawinfo.getimage,sizeof(fdrawinfo.getimage),0); + with fdrawinfo,getimage do begin + if gc.handle <> 0 then begin + image.image.bgr:= abgr; + int1:= gc.paintdevicesize.cx * gc.paintdevicesize.cy; + if int1 > 0 then begin + allocimage(image.image,gc.paintdevicesize,bmk_rgb); + with image.image do begin +// pixels:= gui_allocimagemem(int1); + if pixels <> nil then begin +// size:= gc.paintdevicesize; +// length:= int1; + error:= gde_notimplemented; + gdi(gdf_getimage); + end; + end; + end; + end; + checkimagebgr(image.image,abgr); + result:= image.image; + end; +end; + +procedure tcanvas.endpaint; +begin + if fdrawinfo.gc.handle <> 0 then begin + gdi(gdf_endpaint); + end; +end; + +procedure tcanvas.updatewindowoptions(var aoptions: internalwindowoptionsty); +begin + //dummy +end; + +procedure tcanvas.updatesize(const asize: sizety); +begin + fdrawinfo.gc.paintdevicesize:= asize; +end; + +procedure tcanvas.movewindowrect(const adist: pointty; const arect: rectty); +begin + checkgcstate([cs_gc]); + with fdrawinfo.moverect do begin + dist:= @adist; + rect:= @arect; + gdi(gdf_movewindowrect); + end; +end; + +procedure tcanvas.fitppmm(const asize: sizety); +begin + with getfitrect do begin + if (asize.cx <> 0) and (asize.cy <> 0) and + (size.cx <> 0) and (size.cy <> 0) then begin + if asize.cx/asize.cy > size.cx/size.cy then begin + self.ppmm:= ppmm * asize.cx/size.cx; + end + else begin + self.ppmm:= ppmm * asize.cy/size.cy; + end; + end; + end; +end; + +function tcanvas.getfitrect: rectty; +begin + result.pos:= nullpoint; + checkgcstate([cs_gc]); + result.size:= fdrawinfo.gc.paintdevicesize; +end; + +procedure tcanvas.beforeread; +begin + reset; +end; + +procedure tcanvas.afterread; +begin + fvaluestack.stack[0]:= fvaluestack.stack[1]; //streamed values are default + fstate:= fstate - changedmask; +end; + +procedure tcanvas.readlineoptions(reader: treader); +var + liopt1: lineoptionsty; +begin + liopt1:= lineoptionsty(reader.readset(typeinfo(lineoptionsty))); + if lio_antialias in liopt1 then begin + options:= options + [cao_smooth]; + end; +end; + +procedure tcanvas.defineproperties(filer: tfiler); +begin + filer.defineproperty('lineoptions',@readlineoptions,nil,false); +end; + +function tcanvas.getsmooth: boolean; +begin + result:= cao_smooth in fvaluepo^.options; +end; + +procedure tcanvas.setsmooth(const avalue: boolean); +begin + if avalue <> (cao_smooth in fvaluepo^.options) then begin + if avalue then begin + options:= fvaluepo^.options + [cao_smooth]; + end + else begin + options:= fvaluepo^.options - [cao_smooth]; + end; + end; +end; + +function tcanvas.size: sizety; +begin + result:= getfitrect().size; +end; + +{ tfontcomp } + +function tfontcomp.gettemplate: tfonttemplate; +begin + result:= tfonttemplate(ftemplate); +end; + +procedure tfontcomp.settemplate(const avalue: tfonttemplate); +begin + ftemplate.assign(avalue); +end; + +function tfontcomp.gettemplateclass: templateclassty; +begin + result:= tfonttemplate; +end; + +{ tfonttemplate } + +constructor tfonttemplate.create(const owner: tmsecomponent; + const onchange: notifyeventty); +begin + initfontinfo(fi); + inherited; +end; + +procedure tfonttemplate.setcolor(const avalue: colorty); +begin + fi.color:= avalue; + changed(); +end; + +procedure tfonttemplate.setcolorbackground(const avalue: colorty); +begin + fi.colorbackground:= avalue; + changed(); +end; + +procedure tfonttemplate.setcolorselect(const avalue: colorty); +begin + fi.colorselect:= avalue; + changed(); +end; + +procedure tfonttemplate.setcolorselectbackground(const avalue: colorty); +begin + fi.colorselectbackground:= avalue; + changed(); +end; + +procedure tfonttemplate.setshadow_color(const avalue: colorty); +begin + fi.shadow_color:= avalue; + changed(); +end; + +procedure tfonttemplate.setshadow_shiftx(const avalue: integer); +begin + fi.shadow_shiftx:= avalue; + changed(); +end; + +procedure tfonttemplate.setshadow_shifty(const avalue: integer); +begin + fi.shadow_shifty:= avalue; + changed(); +end; + +procedure tfonttemplate.setgloss_color(const avalue: colorty); +begin + fi.gloss_color:= avalue; + changed(); +end; + +procedure tfonttemplate.setgloss_shiftx(const avalue: integer); +begin + fi.gloss_shiftx:= avalue; + changed(); +end; + +procedure tfonttemplate.setgloss_shifty(const avalue: integer); +begin + fi.gloss_shifty:= avalue; + changed(); +end; + +procedure tfonttemplate.setgrayed_color(const avalue: colorty); +begin + fi.grayed_color:= avalue; + changed(); +end; + +procedure tfonttemplate.setgrayed_colorshadow(const avalue: colorty); +begin + fi.grayed_colorshadow:= avalue; + changed(); +end; + +procedure tfonttemplate.setgrayed_shiftx(const avalue: integer); +begin + fi.grayed_shiftx:= avalue; + changed(); +end; + +procedure tfonttemplate.setgrayed_shifty(const avalue: integer); +begin + fi.grayed_shifty:= avalue; + changed(); +end; + +procedure tfonttemplate.setstyle(const avalue: fontstylesty); +begin + fi.style:= avalue; + changed(); +end; + +procedure tfonttemplate.setxscale(const avalue: real); +begin + fi.xscale:= avalue; + changed(); +end; + +procedure tfonttemplate.doassignto(dest: tpersistent); +begin + if dest is tfont then begin + with tfont(dest) do begin + settemplateinfo(self.fi); + end; + end; +end; + +function tfonttemplate.getinfosize: integer; +begin + result:= sizeof(fi); +end; + +function tfonttemplate.getinfoad: pointer; +begin + result:= @fi; +end; + +procedure tfonttemplate.setheight(const avalue: integer); +begin + fi.height:= avalue; + changed(); +end; + +procedure tfonttemplate.setwidth(const avalue: integer); +begin + fi.width:= avalue; + changed(); +end; + +procedure tfonttemplate.setextraspace(const avalue: integer); +begin + fi.extraspace:= avalue; + changed(); +end; + +procedure tfonttemplate.setname(const avalue: string); +begin + fi.name:= avalue; + changed(); +end; + +procedure tfonttemplate.setcharset(const avalue: string); +begin + fi.charset:= avalue; + changed(); +end; + +procedure tfonttemplate.setoptions(const avalue: fontoptionsty); +begin + fi.options:= avalue; + changed(); +end; + +initialization +{$ifdef mse_flushgdi} + flushgdi:= true; +{$endif} +// setlength(gdifuncs,1); //item 0 = system default +// gdifuncs[0]:= gui_getgdifuncs; +finalization + deinit; +end. diff --git a/mseide-msegui/lib/common/graphics/msegraphutils.pas b/mseide-msegui/lib/common/graphics/msegraphutils.pas new file mode 100644 index 0000000..70f32f9 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msegraphutils.pas @@ -0,0 +1,2113 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegraphutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msetypes,msestrings,mseerr; + +const + redmask = $ff0000; + redshift = 16; + greenmask = $00ff00; + greenshift = 8; + bluemask = $0000ff; + blueshift = 0; + +type + imagenrty = type integer; //for timagelist + facenrty = type integer; //for tfacelist + pixelty = longword; + pixelaty = array[0..0] of pixelty; + ppixelaty = ^pixelaty; + + colorty = type longword; + pcolorty = ^colorty; + colorarty = array of colorty; + + rgbtriplety = packed record + blue: byte; + green: byte; + red: byte; + res: byte; + end; + prgbtriplety = ^rgbtriplety; + rgbtriplearty = array of rgbtriplety; + rgbtripleaty = array[0..0] of rgbtriplety; + prgbtripleaty = ^rgbtripleaty; + + colormapsty = (cm_rgb,cm_functional,cm_mapped,cm_namedrgb,cm_user); + colormapty = array[colormapsty] of longwordarty; + + colorinfoty = record + name: string; + rgb: rgbtriplety; + end; + pcolorinfoty = ^colorinfoty; + colorinfoarty = array of colorinfoty; + +const + maxopacity = $00ffffff; + speccolormask = $f0000000; + speccolorshift = 28; + cl_functional = colorty($80000000); + cl_mapped = colorty($90000000); + cl_namedrgb = colorty($a0000000); + cl_user = colorty($b0000000); + + cl_invalid = cl_functional + 0; + //can not be used as default value + cl_default = cl_functional + 1; + cl_parent = cl_functional + 2; + cl_transparent = cl_functional + 3; + cl_brush = cl_functional + 4; + cl_brushcanvas = cl_functional + 5; + cl_none = cl_functional + 6; cl_nonenum = 6; + cl_font = cl_functional + 7; //use color of current font + cl_normal = cl_functional + 8; //used in tmenitem.coloractive + cl_lastfunctional = cl_functional + 9; + + cl_dkshadow = cl_mapped + 0; + cl_shadow = cl_mapped + 1; + cl_mid = cl_mapped + 2; + cl_light = cl_mapped + 3; + cl_highlight = cl_mapped + 4; + cl_background = cl_mapped + 5; + cl_foreground = cl_mapped + 6; + cl_active = cl_mapped + 7; + cl_noedit = cl_mapped + 8; + cl_text = cl_mapped + 9; + cl_selectedtext = cl_mapped + 10; + cl_selectedtextbackground = cl_mapped + 11; + cl_infobackground = cl_mapped + 12; + cl_glyph = cl_mapped + 13; + cl_activegrip = cl_mapped + 14; + cl_empty = cl_mapped + 15; + cl_emptytext = cl_mapped + 16; + cl_emptytextbackground = cl_mapped + 17; + cl_zebra = cl_mapped + 18; + cl_grayed = cl_mapped + 19; + cl_grayedshadow = cl_mapped + 20; + + cl_gridactive = cl_mapped + 21; + cl_gridfocus = cl_mapped + 22; + cl_gridselect = cl_mapped + 23; + cl_gridline = cl_mapped + 24; + cl_gridlinefix = cl_mapped + 25; + cl_gridframe = cl_mapped + 26; + cl_scrollbarpattern = cl_mapped + 27; + cl_scrollbarpatternclicked = cl_mapped + 28; + cl_buttondefaultrect = cl_mapped + 29; + cl_glyphactive = cl_mapped + 30; + cl_treeline = cl_mapped + 31; + cl_treelineactive = cl_mapped + 32; + cl_lastmapped = cl_mapped + 33; + + cl_0 = cl_namedrgb + 0; //select colorbackground for monochrome bitmaps + cl_1 = cl_namedrgb + 1; //select colorforeground + cl_black = cl_namedrgb + 2; + cl_dkgray = cl_namedrgb + 3; + cl_gray = cl_namedrgb + 4; + cl_ltgray = cl_namedrgb + 5; + cl_white = cl_namedrgb + 6; + + cl_red = cl_namedrgb + 7; + cl_green = cl_namedrgb + 8; + cl_blue = cl_namedrgb + 9; + cl_cyan = cl_namedrgb + 10; + cl_magenta = cl_namedrgb + 11; + cl_yellow = cl_namedrgb + 12; + + cl_dkred = cl_namedrgb + 13; + cl_dkgreen = cl_namedrgb + 14; + cl_dkblue = cl_namedrgb + 15; + cl_dkcyan = cl_namedrgb + 16; + cl_dkmagenta = cl_namedrgb + 17; + cl_dkyellow = cl_namedrgb + 18; + + cl_ltred = cl_namedrgb + 19; + cl_ltgreen = cl_namedrgb + 20; + cl_ltblue = cl_namedrgb + 21; + cl_ltcyan = cl_namedrgb + 22; + cl_ltmagenta = cl_namedrgb + 23; + cl_ltyellow = cl_namedrgb + 24; + + cl_lastnamedrgb = cl_namedrgb + 25; + + cl_user0 = cl_user + 0; + cl_user1 = cl_user + 1; + cl_user2 = cl_user + 2; + cl_user3 = cl_user + 3; + cl_user4 = cl_user + 4; + cl_user5 = cl_user + 5; + cl_user6 = cl_user + 6; + cl_user7 = cl_user + 7; + cl_user8 = cl_user + 8; + cl_user9 = cl_user + 9; + cl_user10 = cl_user + 10; + cl_user11 = cl_user + 11; + cl_user12 = cl_user + 12; + cl_user13 = cl_user + 13; + cl_user14 = cl_user + 14; + cl_user15 = cl_user + 15; + cl_user16 = cl_user + 16; + cl_user17 = cl_user + 17; + cl_user18 = cl_user + 18; + cl_user19 = cl_user + 19; + cl_fade0 = cl_user + 20; + cl_fade1 = cl_user + 21; + cl_fade2 = cl_user + 22; + cl_fade3 = cl_user + 23; + cl_fade4 = cl_user + 24; + cl_fade5 = cl_user + 25; + cl_fade6 = cl_user + 26; + cl_fade7 = cl_user + 27; + cl_fade8 = cl_user + 28; + cl_fade9 = cl_user + 29; + + cl_lastuser = cl_user + 30; + + functionalcolorcount = integer(cl_lastfunctional)-integer(cl_functional); + mappedcolorcount = integer(cl_lastmapped)-integer(cl_mapped); + namedrgbcolorcount = integer(cl_lastnamedrgb)-integer(cl_namedrgb); + usercolorcount = integer(cl_lastuser)-integer(cl_user); + mapcolorcounts: array[colormapsty] of integer = ( + 0, + functionalcolorcount, + mappedcolorcount, + namedrgbcolorcount, + usercolorcount + ); + + defaultfunctional: array[0..functionalcolorcount-1] + of colorinfoty = + ( + (name: 'cl_invalid'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //0 + (name: 'cl_default'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //1 + (name: 'cl_parent'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //2 + (name: 'cl_transparent'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //3 + (name: 'cl_brush'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //4 + (name: 'cl_brushcanvas'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //5 + (name: 'cl_none'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //6 + (name: 'cl_font'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //7 + (name: 'cl_normal'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)) //8 +// (name: 'cl_mask'; rgb: (blue: $00; green: $00; red: $00; res: $00)) +// (name: 'cl_grayed'; rgb: (blue: $80; green: $80; red: $80; res: $00)) + ); + + defaultmapped: array[0..mappedcolorcount-1] + of colorinfoty = + ( + (name: 'cl_dkshadow'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //0 + (name: 'cl_shadow'; rgb: (blue: $80; green: $80; red: $80; res: $00)), //1 + (name: 'cl_mid'; rgb: (blue: $c0; green: $c0; red: $c0; res: $00)), //2 + (name: 'cl_light'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //3 + (name: 'cl_highlight'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //4 + (name: 'cl_background'; rgb: (blue: $d0; green: $d0; red: $d0; res: $00)), //5 + (name: 'cl_foreground'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //6 + (name: 'cl_active'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //7 + (name: 'cl_noedit'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //8 + //canvas defaultcolors + (name: 'cl_text'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //9 + (name: 'cl_selectedtext'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //10 + (name: 'cl_selectedtextbackground'; rgb: (blue: $c0; green: $00; red: $00; res: $00)), //11 + (name: 'cl_infobackground'; rgb: (blue: $e0; green: $ff; red: $ff; res: $00)), //12 + (name: 'cl_glyph'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //13 + (name: 'cl_activegrip'; rgb: (blue: $90; green: $20; red: $20; res: $00)), //14 + (name: 'cl_empty'; rgb: (blue: $a0; green: $a0; red: $ff; res: $00)), //15 + (name: 'cl_emptytext'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //16 + (name: 'cl_emptytextbackground'; rgb: (blue: $00; green: $00; red: $ff; res: $00)), //17 + (name: 'cl_zebra'; rgb: (blue: $ff; green: $ff; red: $e0; res: $00)), //18 + (name: 'cl_grayed'; rgb: (blue: $80; green: $80; red: $80; res: $00)), //19 + (name: 'cl_grayedshadow'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //20 + + (name: 'cl_gridactive'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //21 + (name: 'cl_gridfocus'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //22 + (name: 'cl_gridselect'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //23 + (name: 'cl_gridline'; rgb: (blue: $80; green: $80; red: $80; res: $00)), //24 + (name: 'cl_gridlinefix'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //25 + (name: 'cl_gridframe'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //26 + (name: 'cl_scrollbarpattern'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //27 + (name: 'cl_scrollbarpatternclicked'; rgb:(blue: $00; green: $00; red: $00; res: $00)), //28 + (name: 'cl_buttondefaultrect'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //29 + (name: 'cl_glyphactive'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //30 + (name: 'cl_treeline'; rgb: (blue: $80; green: $80; red: $80; res: $00)), //31 + (name: 'cl_treelineactive'; rgb: (blue: $80; green: $80; red: $80; res: $00)) //32 + ); + + defaultnamedrgb: array[0..namedrgbcolorcount-1] + of colorinfoty = + ( + (name: 'cl_0'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //0 + (name: 'cl_1'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //1 + + (name: 'cl_black'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //2 + (name: 'cl_dkgray'; rgb: (blue: $80; green: $80; red: $80; res: $00)), //3 + (name: 'cl_gray'; rgb: (blue: $c0; green: $c0; red: $c0; res: $00)), //4 + (name: 'cl_ltgray'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //5 + (name: 'cl_white'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //6 + + (name: 'cl_red'; rgb: (blue: $00; green: $00; red: $ff; res: $00)), //7 + (name: 'cl_green'; rgb: (blue: $00; green: $ff; red: $00; res: $00)), //8 + (name: 'cl_blue'; rgb: (blue: $ff; green: $00; red: $00; res: $00)), //9 + (name: 'cl_cyan'; rgb: (blue: $ff; green: $ff; red: $00; res: $00)), //10 + (name: 'cl_magenta'; rgb: (blue: $ff; green: $00; red: $ff; res: $00)), //11 + (name: 'cl_yellow'; rgb: (blue: $00; green: $ff; red: $ff; res: $00)), //12 + + (name: 'cl_dkred'; rgb: (blue: $00; green: $00; red: $c0; res: $00)), //13 + (name: 'cl_dkgreen'; rgb: (blue: $00; green: $c0; red: $00; res: $00)), //14 + (name: 'cl_dkblue'; rgb: (blue: $c0; green: $00; red: $00; res: $00)), //15 + (name: 'cl_dkcyan'; rgb: (blue: $80; green: $80; red: $00; res: $00)), //16 + (name: 'cl_dkmagenta'; rgb: (blue: $80; green: $00; red: $80; res: $00)), //17 + (name: 'cl_dkyellow'; rgb: (blue: $00; green: $80; red: $80; res: $00)), //18 + + (name: 'cl_ltred'; rgb: (blue: $a0; green: $a0; red: $ff; res: $00)), //19 + (name: 'cl_ltgreen'; rgb: (blue: $a0; green: $ff; red: $a0; res: $00)), //20 + (name: 'cl_ltblue'; rgb: (blue: $ff; green: $a0; red: $a0; res: $00)), //21 + (name: 'cl_ltcyan'; rgb: (blue: $ff; green: $ff; red: $a0; res: $00)), //22 + (name: 'cl_ltmagenta'; rgb: (blue: $ff; green: $a0; red: $ff; res: $00)), //23 + (name: 'cl_ltyellow'; rgb: (blue: $a0; green: $ff; red: $ff; res: $00)) //24 + ); + + defaultuser: array[0..usercolorcount-1] + of colorinfoty = + ( + (name: 'cl_user0'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //0 + (name: 'cl_user1'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //1 + (name: 'cl_user2'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //2 + (name: 'cl_user3'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //3 + (name: 'cl_user4'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //4 + (name: 'cl_user5'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //5 + (name: 'cl_user6'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //6 + (name: 'cl_user7'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //7 + (name: 'cl_user8'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //8 + (name: 'cl_user9'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //9 + (name: 'cl_user10'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //10 + (name: 'cl_user11'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //11 + (name: 'cl_user12'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //12 + (name: 'cl_user13'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //13 + (name: 'cl_user14'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //14 + (name: 'cl_user15'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //15 + (name: 'cl_user16'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //16 + (name: 'cl_user17'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //17 + (name: 'cl_user18'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //18 + (name: 'cl_user19'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //19 + (name: 'cl_fade0'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //20 + (name: 'cl_fade1'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //21 + (name: 'cl_fade2'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //22 + (name: 'cl_fade3'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //23 + (name: 'cl_fade4'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //24 + (name: 'cl_fade5'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //25 + (name: 'cl_fade6'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //26 + (name: 'cl_fade7'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //27 + (name: 'cl_fade8'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //28 + (name: 'cl_fade9'; rgb: (blue: $00; green: $00; red: $00; res: $00)) //29 + ); + +type + graphicdirectionty = (gd_right,gd_up,gd_left,gd_down,gd_none); + pgraphicdirectionty = ^graphicdirectionty; + graphicdirectionsty = set of graphicdirectionty; + pgraphicdirectionsty = ^graphicdirectionsty; + //0 1 2 3 4 5 + alignmentty = (al_left,al_xcentered,al_right,al_top,al_ycentered,al_bottom, + //6 + al_grayed, + //7 8 9 10 11 + al_stretchx,al_stretchy,al_fit,al_thumbnail,al_tiled, + //12 + al_nomaskscale, + //13 14 15 + al_intpol,al_or,al_and); + alignmentsty = set of alignmentty; + + edgety = (edg_right,edg_top,edg_left,edg_bottom); + edgesty = set of edgety; + + fontstylety = (fs_bold,fs_italic, + fs_underline,fs_strikeout,fs_selected,fs_blank, + fs_force); + //order fix + fontstylesty = set of fontstylety; + + pointty = record + x,y: integer; + end; + ppointty = ^pointty; + pointarty = array of pointty; + ppointarty = ^pointarty; + pointararty = array of pointarty; + pointaty = array[0..0] of pointty; + ppointaty = ^pointaty; + pointpoarty = array of ppointty; + pppointty = ^ppointty; + + fpointty = record + x,y: single; + end; + pfpointty = ^fpointty; + fpointarty = array of fpointty; + pfpointarty = ^fpointarty; + fpointaty = array[0..0] of fpointty; + pfpointaty = ^fpointaty; + + dpointty = record + x,y: double; + end; + pdpointty = ^dpointty; + dpointarty = array of dpointty; + pdpointarty = ^dpointarty; + dpointaty = array[0..0] of dpointty; + pdpointaty = ^dpointaty; + + segmentty = record a,b: pointty end; + psegmentty = ^segmentty; + segmentarty = array of segmentty; + + graphicvectorty = record + start: pointty; + direction: graphicdirectionty; + length: integer; + end; + + sizety = record + cx,cy: integer; + end; + + rectty = record + case integer of + 0: (x,y,cx,cy: integer); + 1: (pos: pointty; size: sizety); + end; + framety = record + case integer of + 0: (left,top,right,bottom: integer); + 1: (topleft,bottomright: sizety); + end; + pframety = ^framety; + prectty = ^rectty; + rectarty = array of rectty; + prectarty = ^rectarty; + rectextty = record + case integer of + 0: (left,top,right,bottom: integer); + 1: (topleft,bottomright: pointty); + end; + prectextty = ^rectextty; + +const + nullpoint: pointty = (x: 0; y: 0); + nullsize: sizety = (cx: 0; cy: 0); + nullrect: rectty = (x: 0; y: 0; cx: 0; cy: 0); + nullframe: framety = (left: 0; top: 0; right: 0; bottom: 0); + emptyrectext: rectextty = (left: maxint; top: maxint; right: minint; + bottom: minint); + + minimalframe: framety = (left: 1; top: 1; right: 1; bottom: 1); + minimaltextframe: framety = (left: 1; top: 0; right: 1; bottom: 0); + +type + gdierrorty = (gde_ok, + gde_creategc,gde_createprintergc,gde_createmetafilegc, + gde_invalidgc, + gde_notruecolor, + gde_invalidcolor, + gde_invalidsaveindex, + gde_parameter, + gde_font, + gde_pixmap,gde_freepixmap, + gde_invalidcopymode,gde_mustbebitmap, + gde_notmonochrome,gde_unmatchedmonochrome, + gde_fontmetrics,gde_image,gde_invalidrect,gde_invalidfileformat, + gde_invalidindex, + gde_notimplemented, + gde_noglx,gde_novisual,gde_rendercontext,gde_glxpixmap, + gde_createwindow + ); + + egdi = class(eerror) + private + ferror1: gdierrorty; + public + constructor create(aerror: gdierrorty; atext: string); + property error: gdierrorty read ferror1; + end; + +type + getrectintegerty = function(const arect: rectty): integer; + setrectintegerty = procedure(var arect: rectty; const avalue: integer); + getintpointty = function(const value,ovalue: integer): pointty; + getintsizety = function(const value,ovalue: integer): sizety; + getpointintty = function(const apoint: pointty): integer; + getsizeintty = function(const asize: sizety): integer; + setpointintty = procedure(var apoint: pointty; const avalue: integer); + setsizeintty = procedure(var asize: sizety; const avalue: integer); + + rectaccessty = record + pos,size,stop,opos,osize,ostop: getrectintegerty; + setpos,setsize,setstop,setopos,setosize,setostop: setrectintegerty; + makepos,makeopos: getintpointty; + makesize,makeosize: getintsizety; + pt,opt: getpointintty; + si,osi: getsizeintty; + setpt,setopt: setpointintty; + setsi,setosi: setsizeintty; + end; + prectaccessty = ^rectaccessty; + +function rx(const arect: rectty): integer; +function ry(const arect: rectty): integer; +function rcx(const arect: rectty): integer; +function rcy(const arect: rectty): integer; +function rstopx(const arect: rectty): integer; +function rstopy(const arect: rectty): integer; +procedure rsetx(var arect: rectty; const avalue: integer); +procedure rsety(var arect: rectty; const avalue: integer); +procedure rsetcx(var arect: rectty; const avalue: integer); +procedure rsetcy(var arect: rectty; const avalue: integer); +procedure rsetstopx(var arect: rectty; const avalue: integer); +procedure rsetstopy(var arect: rectty; const avalue: integer); +function makesizex(const value,ovalue: integer): sizety; +function makesizey(const value,ovalue: integer): sizety; +function makeposx(const value,ovalue: integer): pointty; +function makeposy(const value,ovalue: integer): pointty; +function px(const apoint: pointty): integer; +function py(const apoint: pointty): integer; +function sx(const asize: sizety): integer; +function sy(const asize: sizety): integer; +procedure psetx(var apoint: pointty; const avalue: integer); +procedure psety(var apoint: pointty; const avalue: integer); +procedure ssetx(var asize: sizety; const avalue: integer); +procedure ssety(var asize: sizety; const avalue: integer); + +const + rectaccessx: rectaccessty = ( + pos: {$ifdef FPC}@{$endif}rx; + size: {$ifdef FPC}@{$endif}rcx; + stop: {$ifdef FPC}@{$endif}rstopx; + opos: {$ifdef FPC}@{$endif}ry; + osize: {$ifdef FPC}@{$endif}rcy; + ostop: {$ifdef FPC}@{$endif}rstopy; + setpos: {$ifdef FPC}@{$endif}rsetx; + setsize: {$ifdef FPC}@{$endif}rsetcx; + setstop: {$ifdef FPC}@{$endif}rsetstopx; + setopos: {$ifdef FPC}@{$endif}rsety; + setosize: {$ifdef FPC}@{$endif}rsetcy; + setostop: {$ifdef FPC}@{$endif}rsetstopy; + makepos: {$ifdef FPC}@{$endif}makeposx; + makeopos: {$ifdef FPC}@{$endif}makeposy; + makesize: {$ifdef FPC}@{$endif}makesizex; + makeosize: {$ifdef FPC}@{$endif}makesizey; + pt: {$ifdef FPC}@{$endif}px; + opt: {$ifdef FPC}@{$endif}py; + si: {$ifdef FPC}@{$endif}sx; + osi: {$ifdef FPC}@{$endif}sy; + setpt: {$ifdef FPC}@{$endif}psetx; + setopt: {$ifdef FPC}@{$endif}psety; + setsi: {$ifdef FPC}@{$endif}ssetx; + setosi: {$ifdef FPC}@{$endif}ssety; + ); + rectaccessy: rectaccessty = ( + pos: {$ifdef FPC}@{$endif}ry; + size: {$ifdef FPC}@{$endif}rcy; + stop: {$ifdef FPC}@{$endif}rstopy; + opos: {$ifdef FPC}@{$endif}rx; + osize: {$ifdef FPC}@{$endif}rcx; + ostop: {$ifdef FPC}@{$endif}rstopy; + setpos: {$ifdef FPC}@{$endif}rsety; + setsize: {$ifdef FPC}@{$endif}rsetcy; + setstop: {$ifdef FPC}@{$endif}rsetstopy; + setopos: {$ifdef FPC}@{$endif}rsetx; + setosize: {$ifdef FPC}@{$endif}rsetcx; + setostop: {$ifdef FPC}@{$endif}rsetstopx; + makepos: {$ifdef FPC}@{$endif}makeposy; + makeopos: {$ifdef FPC}@{$endif}makeposx; + makesize: {$ifdef FPC}@{$endif}makesizey; + makeosize: {$ifdef FPC}@{$endif}makesizex; + pt: {$ifdef FPC}@{$endif}py; + opt: {$ifdef FPC}@{$endif}px; + si: {$ifdef FPC}@{$endif}sy; + osi: {$ifdef FPC}@{$endif}sx; + setpt: {$ifdef FPC}@{$endif}psety; + setopt: {$ifdef FPC}@{$endif}psetx; + setsi: {$ifdef FPC}@{$endif}ssety; + setosi: {$ifdef FPC}@{$endif}ssetx; + ); + +procedure gdierror(error: gdierrorty; const text: msestring = ''); overload; +procedure gdierror(error: gdierrorty; sender: tobject; + text: msestring = ''); overload; + +function stringtocolor(const text: string): colorty; +function trystringtocolor(text: string; out value: colorty): boolean; +function colortostring(value: colorty): string; +function getcolornames: msestringarty; +function getcolorvalues: colorarty; + +function makepoint(const x,y: integer): pointty; {$ifdef FPC}inline;{$endif} +function makesize(const cx,cy: integer): sizety; {$ifdef FPC}inline;{$endif} +function makerect(const x,y,cx,cy: integer): rectty; overload; + {$ifdef FPC}inline;{$endif} +function makerect(const pos: pointty; const size: sizety): rectty; overload; + {$ifdef FPC}inline;{$endif} +function makesegment(const a,b: pointty): segmentty; + {$ifdef FPC}inline;{$endif} +function makeframe(const left,top,right,bottom: integer): framety; + {$ifdef FPC}inline;{$endif} + +function mp(const x,y: integer): pointty; {$ifdef FPC}inline;{$endif} +function ms(const cx,cy: integer): sizety; {$ifdef FPC}inline;{$endif} +function mr(const x,y,cx,cy: integer): rectty; overload; + {$ifdef FPC}inline;{$endif} +function mr(const pos: pointty; const size: sizety): rectty; overload; + {$ifdef FPC}inline;{$endif} +function mg(const a,b: pointty): segmentty; + {$ifdef FPC}inline;{$endif} +function mf(const left,top,right,bottom: integer): framety; + {$ifdef FPC}inline;{$endif} + +function bottomright(const rect: rectty): pointty; {$ifdef FPC}inline;{$endif} +function isnullpoint(const point: pointty): boolean; {$ifdef FPC}inline;{$endif} +function isnullsize(const size: sizety): boolean; {$ifdef FPC}inline;{$endif} +function isnullrect(const rect: rectty): boolean; {$ifdef FPC}inline;{$endif} +function isnullframe(const frame: framety): boolean; {$ifdef FPC}inline;{$endif} +function pointisequal(const a,b: pointty): boolean; {$ifdef FPC}inline;{$endif} +function sizeisequal(const a,b: sizety): boolean; {$ifdef FPC}inline;{$endif} +function rectisequal(const a,b: rectty): boolean; {$ifdef FPC}inline;{$endif} +function frameisequal(const a,b: framety): boolean; {$ifdef FPC}inline;{$endif} + +function addpoint(const a,b: pointty): pointty;{$ifdef FPC}inline;{$endif} + //result:= a+b +procedure addpoint1(var dest: pointty; const point: pointty);{$ifdef FPC}inline;{$endif} +function subpoint(const a,b: pointty): pointty; {$ifdef FPC}inline;{$endif} + //result:= a-b +procedure subpoint1(var dest: pointty; const point: pointty); + {$ifdef FPC}inline;{$endif} +function distance(const a,b: pointty): integer;{$ifdef FPC}inline;{$endif} + +function addsize(const a,b: sizety): sizety;{$ifdef FPC}inline;{$endif} + //result:= a+b +procedure addsize1(var dest: sizety; const size: sizety); + {$ifdef FPC}inline;{$endif} +function subsize(const a,b: sizety): sizety; {$ifdef FPC}inline;{$endif} + //result:= a-b +procedure subsize1(var dest: sizety; const size: sizety); + {$ifdef FPC}inline;{$endif} + +function fitsize(const asize: sizety; const maxsize: sizety): sizety; + +function rectcenter(const arect: rectty): pointty; +procedure centerrect(apos: pointty; asize: integer; out rect: rectty); +function excenterrect(const arect: rectty): rectty; +function recenterrect(const arect: rectty): rectty; + +function inflaterect(const rect: rectty; value: integer): rectty; +function inflaterect(const rect: rectty; const value: int32; + const disablededges: edgesty): rectty; +function inflaterect(const rect: rectty; const frame: framety): rectty; +procedure inflaterect1(var rect: rectty; value: integer); +procedure inflaterect1(var rect: rectty; const value: int32; + const disablededges: edgesty); +procedure inflaterect1(var rect: rectty; const frame: framety); +function deflaterect(const rect: rectty; const frame: framety): rectty; +procedure deflaterect1(var rect: rectty; const frame: framety); +procedure normalizerect1(var arect: rectty); +function normalizerect(const arect: rectty): rectty; +procedure swapxy1(var arect: rectty); + +function addframe(const a,b: framety): framety; +procedure addframe1(var dest: framety; const frame: framety); +function subframe(const a,b: framety): framety; +procedure subframe1(var dest: framety; const frame: framety); +function expandrectext(const a,b: rectextty): rectextty; +procedure expandrectext1(var dest: rectextty; const frame: rectextty); + +procedure inflaterectext1(var ext: rectextty; const frame: framety); +function inflaterectext(const ext: rectextty; const frame: framety): rectextty; +procedure deflaterectext1(var ext: rectextty; const frame: framety); +function deflaterectext(const ext: rectextty; const frame: framety): rectextty; + +procedure inflateframe1(var frame: framety; value: integer); +function inflateframe(const frame: framety; value: integer): framety; + +function moverect(const rect: rectty; const dist: pointty): rectty; +procedure moverect1(var rect: rectty; const dist: pointty); +function removerect(const rect: rectty; const dist: pointty): rectty; +procedure removerect1(var rect: rectty; const dist: pointty); +procedure shiftinrect(var rect: rectty; const outerrect: rectty); +procedure centerinrect(var rect: rectty; const outerrect: rectty); +function changerectdirection(const arect: rectty; + const olddirction,newdirection: graphicdirectionty): rectty; +function rotateframe(const aframe: framety; const olddirection, + newdirection: graphicdirectionty): framety; +procedure rotateframe1(var aframe: framety; const olddirection, + newdirection: graphicdirectionty); + +function intersectrect(const a,b: rectty; out dest: rectty): boolean; overload; +function intersectrect(const a,b: rectty): rectty; overload; +procedure intersectrect1(var dest: rectty; const source: rectty); +function testintersectrect(const a,b: rectty): boolean; + //true on intersection +function combinerect(const a,b: rectty): rectty; +procedure combinerect1(var a: rectty; const b: rectty); +function clipinrect(const point: pointty; + const boundsrect: rectty): pointty; overload; +function clipinrect(const rect: rectty; + const boundsrect: rectty): rectty; overload; +function clipinrect1(var point: pointty; + const boundsrect: rectty): boolean; overload; +function clipinrect1(var rect: rectty; + const boundsrect: rectty): boolean; overload; + //true if changed +function calcrectalignment(const dest: rectty; source: rectty; + const alignment: alignmentsty): rectty; + +function pointinrect(const point: pointty; const rect: rectty): boolean; + //true if point is in rect +function pointinellipse(const point: pointty; const rect: rectty): boolean; + //true if point is in ellipse circumscribed by rect +function rectinrect(const inner,outer: rectty): boolean; + //true if inner in outer + +function segment(const a,b: pointty): segmentty; {$ifdef FPC}inline;{$endif} + +procedure vectortoline(const vector: graphicvectorty; out a,b: pointty); + +function rotatedirection(const olddest,newvalue, + oldvalue: graphicdirectionty): graphicdirectionty; + +procedure removeduplicatedpoints(var vect: pointarty); + +function hsbtorgb(hue,sat,bri: word): colorty; + +implementation +uses + mseglob,SysUtils,mseformatstr,classes,mclasses; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + errortexts: array[gdierrorty] of string = ( + '', + 'Invalid GC', + 'Can not create gc', + 'Can not create printer gc', + 'Can not create metafile gc', + 'Color mode must be truecolor', + 'Invalid color', + 'Invalid saveindex', + 'Invalid parameter', + 'Invalid font', + 'Invalid pixmap', + 'Can not free pixmap', + 'Invalid copymode', + 'Must be bitmap', + 'Must be monochrome', + 'Unmatched monochrome', + 'Invalid fontmetrics', + 'Can not create image', + 'Invalid rect', + 'Invalid file format', + 'Invalid index', + 'Not implemented', + 'GLX extension not supported.', + 'Could not find visual.', + 'Could not create a rendering context.', + 'Could not create a GLXPixmap.', + 'Could not create canvas window.' + ); + +function hsbtorgb(hue,sat,bri: word): colorty; +var + r,g,b: real; + int1: integer; + rea1,rea2: real; +begin + if hue > 360 then begin + hue:= 360; + end; + if sat > 100 then begin + sat:= 100; + end; + if bri > 100 then begin + bri:= 100; + end; + int1:= hue; + r:= 0; + g:= 0; + b:= 0; + if int1 < 60 then begin + r:= 60; + g:= int1; + end + else begin + if int1 < 120 then begin + r:= 120 - int1; + g:= 60; + end + else begin + if int1 < 180 then begin + g:= 60; + b:= int1 - 120; + end + else begin + if int1 < 240 then begin + g:= 240 - int1; + b:= 60 + end + else begin + if int1 < 300 then begin + b:= 60; + r:= int1 - 240; + end + else begin + b:= 360 - int1; + r:= 60; + end; + end; + end; + end; + end; + rea1:= sat / 100; + rea2:= 1-rea1; + rea1:= rea1 / 60; + r:= r * rea1 + rea2; + g:= g * rea1 + rea2; + b:= b * rea1 + rea2; + rea1:= bri / 100; + r:= r*rea1; + g:= g*rea1; + b:= b*rea1; + with rgbtriplety(result) do begin + res:= 0; + red:= round(r*255); + green:= round(g*255); + blue:= round(b*255); + end; +end; + +function calcrectalignment(const dest: rectty; source: rectty; + const alignment: alignmentsty): rectty; +begin + result:= dest; + if (al_tiled in alignment) or + (al_thumbnail in alignment) and + ((dest.cx < source.cx) or (dest.cy < source.cy)) then begin + exit; + end; + if al_fit in alignment then begin + if source.cy * dest.cx > source.cx * dest.cy then begin //fit vert + if source.cy <> 0 then begin + source.cx:= (source.cx * dest.cy) div source.cy; + source.cy:= (source.cy * dest.cy) div source.cy; + end; + end + else begin + if source.cx <> 0 then begin + source.cy:= (source.cy * dest.cx) div source.cx; + source.cx:= (source.cx * dest.cx) div source.cx; //fit horz + end; + end; + end; + if al_stretchx in alignment then begin + source.cx:= dest.cx; + end; + if al_stretchy in alignment then begin + source.cy:= dest.cy; + end; + result.size:= source.size; + if al_xcentered in alignment then begin + result.x:= dest.x + (dest.cx - source.cx) div 2 + end + else begin + if al_right in alignment then begin + result.x:= dest.x + dest.cx - source.cx; + end; + end; + if al_ycentered in alignment then begin + result.y:= dest.y + (dest.cy - source.cy) div 2 + end + else begin + if al_bottom in alignment then begin + result.y:= dest.y + dest.cy - source.cy; + end; + end; + intersectrect1(result,dest); +end; + +procedure removeduplicatedpoints(var vect: pointarty); +var + ar1: pointarty; + int1,int2: integer; +begin + if vect <> nil then begin + setlength(ar1,length(vect)); + int2:= 0; + ar1[0]:= vect[0]; + for int1:= 1 to high(vect) do begin + if (ar1[int2].x <> vect[int1].x) or (ar1[int2].y <> vect[int1].y) then begin + inc(int2); + ar1[int2]:= vect[int1]; + end; + end; + setlength(ar1,int2+1); + vect:= ar1; + end; +end; + +function trystringtocolor(text: string; out value: colorty): boolean; +var + ca1: longword; +begin + value:= cl_none; + result:= true; + text:= trim(text); + if trystrtohex(text,longword(value)) then begin + if longword(result) > $00ffffff then begin + result:= false; + exit; + end; + end + else begin + text:= lowercase(text); + for ca1:= 0 to mapcolorcounts[cm_namedrgb] - 1 do begin + if defaultnamedrgb[ca1].name = text then begin + value:= colorty(ca1 + longword(cl_namedrgb)); + exit; + end; + end; + for ca1:= 0 to mapcolorcounts[cm_mapped] - 1 do begin + if defaultmapped[ca1].name = text then begin + value:= colorty(ca1 + longword(cl_mapped)); + exit; + end; + end; + for ca1:= 0 to mapcolorcounts[cm_functional] - 1 do begin + if defaultfunctional[ca1].name = text then begin + value:= colorty(ca1 + longword(cl_functional)); + exit; + end; + end; + for ca1:= 0 to mapcolorcounts[cm_user] - 1 do begin + if defaultuser[ca1].name = text then begin + value:= colorty(ca1 + longword(cl_user)); + exit; + end; + end; + result:= false; + end; +end; + +function stringtocolor(const text: string): colorty; +begin + if not trystringtocolor(text,result) then begin + gdierror(gde_invalidcolor); + end; +end; + +function colortostring(value: colorty): string; +begin + if longword(value) <= $00ffffff then begin + result:= '$'+hextostr(longword(value),6); + end + else begin + if (longword(value) >= longword(cl_namedrgb)) and + (longword(value) < longword(cl_lastnamedrgb)) then begin + result:= defaultnamedrgb[longword(value) - longword(cl_namedrgb)].name; + end + else begin + if (longword(value) >= longword(cl_mapped)) and + (longword(value) < longword(cl_lastmapped)) then begin + result:= defaultmapped[longword(value) - longword(cl_mapped)].name; + end + else begin + if (longword(value) >= longword(cl_functional)) and + (longword(value) < longword(cl_lastfunctional)) then begin + result:= defaultfunctional[longword(value) - longword(cl_functional)].name; + end + else begin + if (longword(value) >= longword(cl_user)) and + (longword(value) < longword(cl_lastuser)) then begin + result:= defaultuser[longword(value) - longword(cl_user)].name; + end + else begin + result:= 'Invalid ($'+hextostr(longword(value),8)+')'; + end; + end; + end; + end; + end; +end; + +var + mappedcolorlookup: array[0..mappedcolorcount-1] of int32 = ( + 0, //cl_dkshadow = cl_mapped + 0; + 1, //cl_shadow = cl_mapped + 1; + 2, //cl_mid = cl_mapped + 2; + 3, //cl_light = cl_mapped + 3; + 4, //cl_highlight = cl_mapped + 4; + 5, //cl_background = cl_mapped + 5; + 6, //cl_foreground = cl_mapped + 6; + 7, //cl_active = cl_mapped + 7; + 8, //cl_noedit = cl_mapped + 8; + 9, //cl_text = cl_mapped + 9; + 10,//cl_selectedtext = cl_mapped + 10; + 11,//cl_selectedtextbackground = cl_mapped + 11; + 12,//cl_infobackground = cl_mapped + 12; + 13,//cl_glyph = cl_mapped + 13; + 30,//cl_glyphactive = cl_mapped + 30; + 14,//cl_activegrip = cl_mapped + 14; + 15,//cl_empty = cl_mapped + 15; + 16,//cl_emptytext = cl_mapped + 16; + 17,//cl_emptytextbackground = cl_mapped + 17; + 18,//cl_zebra = cl_mapped + 18; + 19,//cl_grayed = cl_mapped + 19; + 20,//cl_grayedshadow = cl_mapped + 20; + + 21,//cl_gridactive = cl_mapped + 21; + 22,//cl_gridfocus = cl_mapped + 22; + 23,//cl_gridselect = cl_mapped + 23; + 24,//cl_gridline = cl_mapped + 24; + 25,//cl_gridlinefix = cl_mapped + 25; + 26,//cl_gridframe = cl_mapped + 26; + 27,//cl_scrollbarpattern = cl_mapped + 27; + 28,//cl_scrollbarpatternclicked = cl_mapped + 28; + 29,//cl_buttondefaultrect = cl_mapped + 29; + 31,//cl_treeline = cl_mapped + 31; + 32 //cl_treelineactive = cl_mapped + 32; + ); + +function getcolornames: msestringarty; +var + int1,int2: integer; +begin + setlength(result,namedrgbcolorcount+mappedcolorcount+ + functionalcolorcount+usercolorcount-1); //cl_invalid skipped + for int1:= 0 to high(defaultnamedrgb) do begin + result[int1]:= msestring(defaultnamedrgb[int1].name); + end; + int2:= namedrgbcolorcount; + for int1:= 0 to high(defaultmapped) do begin + result[int1+int2]:= msestring(defaultmapped[mappedcolorlookup[int1]].name); + end; + inc(int2,mappedcolorcount); + result[int2]:= msestring(defaultfunctional[cl_nonenum].name); + //cl_invalid skipped + for int1:= 1 to cl_nonenum-1 do begin + result[int1+int2]:= msestring(defaultfunctional[int1].name); + end; + for int1:= cl_nonenum + 1 to functionalcolorcount-1 do begin + result[int1-1+int2]:= msestring(defaultfunctional[int1].name); + end; + { + for int1:= cl_nonenum+1 to high(defaultfunctional) do begin + result[int1+int2-1]:= defaultfunctional[int1].name; + end; + } + inc(int2,functionalcolorcount-1); + for int1:= 0 to high(defaultuser) do begin + result[int1+int2]:= msestring(defaultuser[int1].name); + end; +end; + +function getcolorvalues: colorarty; +var + int1,int2: integer; +begin + setlength(result,namedrgbcolorcount+mappedcolorcount+ + functionalcolorcount+usercolorcount-1);//cl_invalid skipped + for int1:= 0 to high(defaultnamedrgb) do begin + result[int1]:= cl_namedrgb + longword(int1); + end; + int2:= namedrgbcolorcount; + for int1:= 0 to high(defaultmapped) do begin + result[int1+int2]:= cl_mapped + longword(mappedcolorlookup[int1]); + end; + inc(int2,mappedcolorcount); + result[int2]:= cl_functional+cl_nonenum; //cl_invalid skipped + for int1:= 1 to cl_nonenum-1 do begin + result[int1+int2]:= cl_functional + longword(int1); + end; + for int1:= cl_nonenum+1 to functionalcolorcount-1 do begin + result[int1-1+int2]:= cl_functional + longword(int1); + end; + inc(int2,functionalcolorcount-1); + for int1:= 0 to high(defaultuser) do begin + result[int1+int2]:= cl_user + longword(int1); + end; +end; + +function rotateframe(const aframe: framety; const olddirection, + newdirection: graphicdirectionty): framety; +begin + result:= aframe; + rotateframe1(result,olddirection,newdirection); +end; + +procedure rotateframe1(var aframe: framety; const olddirection, + newdirection: graphicdirectionty); +var + int1: integer; + frame1: framety; +begin + if olddirection <> newdirection then begin + frame1:= aframe; + int1:= (ord(newdirection) - ord(olddirection)) and $3; + case int1 of + 1: begin + aframe.top:= frame1.right; + aframe.left:= frame1.top; + aframe.bottom:= frame1.left; + aframe.right:= frame1.bottom; + end; + 2: begin + aframe.left:= frame1.right; + aframe.bottom:= frame1.top; + aframe.right:= frame1.left; + aframe.top:= frame1.bottom; + end; + 3: begin + aframe.bottom:= frame1.right; + aframe.right:= frame1.top; + aframe.top:= frame1.left; + aframe.left:= frame1.bottom; + end; + end; + end; +end; + +function rotatedirection(const olddest,newvalue, + oldvalue: graphicdirectionty): graphicdirectionty; +begin + result:= graphicdirectionty(((ord(olddest)+ord(newvalue)-ord(oldvalue)) and $3)); +end; + +procedure shiftinrect(var rect: rectty; const outerrect: rectty); +var + int1: integer; +begin + with rect do begin + int1:= outerrect.x + outerrect.cx - (x + cx); + if int1 < 0 then begin + inc(x,int1); + end; + int1:= outerrect.y + outerrect.cy - (y + cy); + if int1 < 0 then begin + inc(y,int1); + end; + if x < outerrect.x then begin + x:= outerrect.x; + end; + if y < outerrect.y then begin + y:= outerrect.y; + end; + end; +end; + +procedure centerinrect(var rect: rectty; const outerrect: rectty); +begin + with outerrect do begin + rect.x:= x + (cx - rect.cx) div 2; + rect.y:= y + (cy - rect.cy) div 2; + end; +end; + +function changerectdirection(const arect: rectty; + const olddirction,newdirection: graphicdirectionty): rectty; +begin + result.pos:= arect.pos; + if (olddirction in [gd_left,gd_right]) xor + (newdirection in [gd_left,gd_right]) then begin + result.cx:= arect.cy; + result.cy:= arect.cx; + end + else begin + result.size:= arect.size; + end; +end; + +function makepoint(const x,y: integer): pointty; {$ifdef FPC}inline;{$endif} +begin + result.x:= x; + result.y:= y; +end; + +function makesize(const cx,cy: integer): sizety; {$ifdef FPC}inline;{$endif} +begin + result.cx:= cx; + result.cy:= cy; +end; + +function makerect(const x,y,cx,cy: integer): rectty; {$ifdef FPC}inline;{$endif} +begin + result.x:= x; + result.y:= y; + result.cx:= cx; + result.cy:= cy; +end; + +function makerect(const pos: pointty; const size: sizety): rectty; overload; + {$ifdef FPC}inline;{$endif} +begin + result.pos:= pos; + result.size:= size; +end; + +function makeframe(const left,top,right,bottom: integer): framety; + {$ifdef FPC}inline;{$endif} +begin + result.left:= left; + result.top:= top; + result.right:= right; + result.bottom:= bottom; +end; + +function mf(const left,top,right,bottom: integer): framety; + {$ifdef FPC}inline;{$endif} +begin + result.left:= left; + result.top:= top; + result.right:= right; + result.bottom:= bottom; +end; + +function makesegment(const a,b: pointty): segmentty; + {$ifdef FPC}inline;{$endif} +begin + result.a:= a; + result.b:= b; +end; + +function mp(const x,y: integer): pointty;{$ifdef FPC}inline;{$endif} +begin + result.x:= x; + result.y:= y; +end; + +function ms(const cx,cy: integer): sizety; {$ifdef FPC}inline;{$endif} +begin + result.cx:= cx; + result.cy:= cy; +end; + +function mr(const x,y,cx,cy: integer): rectty; {$ifdef FPC}inline;{$endif} +begin + result.x:= x; + result.y:= y; + result.cx:= cx; + result.cy:= cy; +end; + +function mr(const pos: pointty; const size: sizety): rectty; overload; + {$ifdef FPC}inline;{$endif} +begin + result.pos:= pos; + result.size:= size; +end; + +function mg(const a,b: pointty): segmentty; + {$ifdef FPC}inline;{$endif} +begin + result.a:= a; + result.b:= b; +end; + +function bottomright(const rect: rectty): pointty; {$ifdef FPC}inline;{$endif} +begin + result.x:= rect.x + rect.cx; + result.y:= rect.y + rect.cy; +end; + +function isnullpoint(const point: pointty): boolean;{$ifdef FPC}inline;{$endif} +begin + with point do begin + result:= (x = 0) and (y = 0); + end; +end; + +function isnullsize(const size: sizety): boolean;{$ifdef FPC}inline;{$endif} +begin + with size do begin + result:= (cx = 0) and (cy = 0); + end; +end; + +function isnullrect(const rect: rectty): boolean;{$ifdef FPC}inline;{$endif} +begin + with rect do begin + result:= (x = 0) and (y = 0) and (cx = 0) and (cy = 0); + end; +end; + +function isnullframe(const frame: framety): boolean;{$ifdef FPC}inline;{$endif} +begin + with frame do begin + result:= (left = 0) and (top = 0) and (right = 0) and (bottom = 0); + end; +end; + +function pointisequal(const a,b: pointty): boolean;{$ifdef FPC}inline;{$endif} +begin + result:= (a.x = b.x) and (a.y = b.y); +end; + +function sizeisequal(const a,b: sizety): boolean; {$ifdef FPC}inline;{$endif} +begin + result:= (a.cx = b.cx) and (a.cy = b.cy); +end; + +function rectisequal(const a,b: rectty): boolean; {$ifdef FPC}inline;{$endif} +begin + result:= (a.x = b.x) and (a.y = b.y) and + (a.cx = b.cx) and (a.cy = b.cy); +end; + +function frameisequal(const a,b: framety): boolean;{$ifdef FPC}inline;{$endif} +begin + result:= (a.left = b.left) and (a.top = b.top) and + (a.right = b.right) and (a.bottom = b.bottom); +end; + +function addpoint(const a,b: pointty): pointty;{$ifdef FPC}inline;{$endif} + //result:= a-b +begin + result.x:= a.x+b.x; + result.y:= a.y+b.y; +end; + +procedure addpoint1(var dest: pointty; const point: pointty); + {$ifdef FPC}inline;{$endif} +begin + inc(dest.x,point.x); + inc(dest.y,point.y); +end; + +function subpoint(const a,b: pointty): pointty;{$ifdef FPC}inline;{$endif} + //result:= a-b +begin + result.x:= a.x-b.x; + result.y:= a.y-b.y; +end; + +procedure subpoint1(var dest: pointty; const point: pointty); + {$ifdef FPC}inline;{$endif} +begin + dec(dest.x,point.x); + dec(dest.y,point.y); +end; + +function distance(const a,b: pointty): integer;{$ifdef FPC}inline;{$endif} +begin + result:= abs(a.x-b.x) + abs(a.y-b.y); +end; + +function addsize(const a,b: sizety): sizety;{$ifdef FPC}inline;{$endif} + //result:= a+b +begin + result.cx:= a.cx+b.cx; + result.cy:= a.cy+b.cy; +end; + +procedure addsize1(var dest: sizety; const size: sizety); + {$ifdef FPC}inline;{$endif} +begin + inc(dest.cx,size.cx); + inc(dest.cy,size.cy); +end; + +function subsize(const a,b: sizety): sizety;{$ifdef FPC}inline;{$endif} + //result:= a-b +begin + result.cx:= a.cx-b.cx; + result.cy:= a.cy-b.cy; +end; + +procedure subsize1(var dest: sizety; const size: sizety); + {$ifdef FPC}inline;{$endif} +begin + dec(dest.cx,size.cx); + dec(dest.cy,size.cy); +end; + +function segment(const a,b: pointty): segmentty; {$ifdef FPC}inline;{$endif} +begin + result.a:= a; + result.b:= b; +end; + +procedure vectortoline(const vector: graphicvectorty; out a,b: pointty); +begin + with vector do begin + a:= start; + case direction of + gd_right: begin + b.x:= start.x+length; + b.y:= start.y; + end; + gd_up: begin + b.x:= start.x; + b.y:= start.y - length; + end; + gd_left: begin + b.x:= start.x - length; + b.y:= start.y; + end; + gd_down: begin + b.x:= start.x; + b.y:= start.y + length; + end; + end; + end; +end; + +function deflaterect(const rect: rectty; const frame: framety): rectty; +begin + result.x:= rect.x + frame.left; + result.cx:= rect.cx - frame.left - frame.right; + result.y:= rect.y + frame.top; + result.cy:= rect.cy - frame.top - frame.bottom; +end; + +procedure deflaterect1(var rect: rectty; const frame: framety); +begin + inc(rect.x,frame.left); + dec(rect.cx,frame.left); + inc(rect.y,frame.top); + dec(rect.cy,frame.top); + dec(rect.cx,frame.right); + dec(rect.cy,frame.bottom); +end; + +procedure normalizerect1(var arect: rectty); +begin + if arect.cx < 0 then begin + arect.x:= arect.x + arect.cx + 1; + arect.cx:= -arect.cx; + end; + if arect.cy < 0 then begin + arect.y:= arect.y + arect.cy + 1; + arect.cy:= -arect.cy; + end; +end; + +function normalizerect(const arect: rectty): rectty; +begin + result:= arect; + normalizerect1(result); +end; + +procedure swapxy1(var arect: rectty); +var + int1: integer; +begin + with arect do begin + int1:= x; + x:= y; + y:= int1; + int1:= cx; + cx:= cy; + cy:= int1; + end; +end; + +function addframe(const a,b: framety): framety; +begin + with result do begin + left:= a.left + b.left; + top:= a.top + b.top; + right:= a.right + b.right; + bottom:= a.bottom + b.bottom; + end; +end; + +procedure addframe1(var dest: framety; const frame: framety); +begin + with dest do begin + left:= left + frame.left; + top:= top + frame.top; + right:= right + frame.right; + bottom:= bottom + frame.bottom; + end; +end; + +function subframe(const a,b: framety): framety; +begin + with result do begin + left:= a.left - b.left; + top:= a.top - b.top; + right:= a.right - b.right; + bottom:= a.bottom - b.bottom; + end; +end; + +procedure subframe1(var dest: framety; const frame: framety); +begin + with dest do begin + left:= left - frame.left; + top:= top - frame.top; + right:= right - frame.right; + bottom:= bottom - frame.bottom; + end; +end; + +function expandrectext(const a,b: rectextty): rectextty; +begin + result:= a; + with result do begin + if b.left < left then begin + left:= b.left; + end; + if b.right > right then begin + right:= b.right; + end; + if b.top < top then begin + top:= b.top; + end; + if b.bottom < bottom then begin + bottom:= b.bottom; + end; + end; +end; + +procedure expandrectext1(var dest: rectextty; const frame: rectextty); +begin + with dest do begin + if frame.left < left then begin + left:= frame.left; + end; + if frame.right > right then begin + right:= frame.right; + end; + if frame.top < top then begin + top:= frame.top; + end; + if frame.bottom > bottom then begin + bottom:= frame.bottom; + end; + end; +end; + +procedure inflaterectext1(var ext: rectextty; const frame: framety); +begin + with ext do begin + left:= left - frame.left; + top:= top - frame.top; + right:= right + frame.right; + bottom:= bottom + frame.bottom; + end; +end; + +function inflaterectext(const ext: rectextty; const frame: framety): rectextty; +begin + with result do begin + left:= ext.left - frame.left; + top:= ext.top - frame.top; + right:= ext.right + frame.right; + bottom:= ext.bottom + frame.bottom; + end; +end; + +procedure deflaterectext1(var ext: rectextty; const frame: framety); +begin + with ext do begin + left:= left + frame.left; + top:= top + frame.top; + right:= right - frame.right; + bottom:= bottom - frame.bottom; + end; +end; + +function deflaterectext(const ext: rectextty; const frame: framety): rectextty; +begin + with result do begin + left:= ext.left + frame.left; + top:= ext.top + frame.top; + right:= ext.right - frame.right; + bottom:= ext.bottom - frame.bottom; + end; +end; + +function pointinrect(const point: pointty; const rect: rectty): boolean; + //true if point is in rect +begin + result:= (point.x >= rect.x) and (point.x < rect.x + rect.cx) and + (point.y >= rect.y) and (point.y < rect.y + rect.cy); +end; + +function pointinellipse(const point: pointty; const rect: rectty): boolean; + //true if point is in ellipse circumscribed by rect +var + x1,y1: real; + x0q,y0q: real; +begin + x1:= point.x - rect.x - rect.cx div 2; + y1:= point.y - rect.y - rect.cy div 2; + x0q:= rect.cx*rect.cx; + y0q:= rect.cy*rect.cy; + result:= (x1*x1*y0q+y1*y1*x0q)*4 <= x0q*y0q; +end; + +function fitsize(const asize: sizety; const maxsize: sizety): sizety; +begin + result:= nullsize; + if asize.cx*maxsize.cy > maxsize.cx*asize.cy then begin //fit horz + result.cx:= maxsize.cx; + if asize.cx <> 0 then begin + result.cy:= (asize.cy*maxsize.cx) div asize.cx; + end; + end + else begin //fit vert + result.cy:= maxsize.cy; + if asize.cy <> 0 then begin + result.cx:= (asize.cx*maxsize.cy) div asize.cy; + end; + end; +end; + +function rectcenter(const arect: rectty): pointty; +begin + with arect do begin + result.x:= x + cx div 2; + result.y:= y + cy div 2; + end; +end; + +procedure centerrect(apos: pointty; asize: integer; out rect: rectty); +var + int1: integer; +begin + int1:= asize div 2; + with rect do begin + x:= apos.x - int1; + y:= apos.y - int1; + cx:= asize; + cy:= asize; + end; +end; + +function excenterrect(const arect: rectty): rectty; +begin + with result do begin + x:= arect.x - arect.cx div 2; + y:= arect.y - arect.cy div 2; + cx:= arect.cx; + cy:= arect.cy; + end; +end; + +function recenterrect(const arect: rectty): rectty; +begin + with result do begin + x:= arect.x + arect.cx div 2; + y:= arect.y + arect.cy div 2; + cx:= arect.cx; + cy:= arect.cy; + end; +end; + +function inflaterect(const rect: rectty; value: integer): rectty; +begin + with rect do begin + result.x:= x - value; + result.y:= y - value; + result.cx:= cx + value + value; + result.cy:= cy + value + value; + end; +end; + +function inflaterect(const rect: rectty; const value: int32; + const disablededges: edgesty): rectty; +begin + result:= rect; + with result do begin + if not (edg_left in disablededges) then begin + dec(x,value); + inc(cx,value); + end; + if not (edg_top in disablededges) then begin + dec(y,value); inc(cy,value); + end; + if not (edg_right in disablededges) then begin + inc(cx,value); + end; + if not (edg_bottom in disablededges) then begin + inc(cy,value); + end; + end; +end; + +function inflaterect(const rect: rectty; const frame: framety): rectty; +begin + result.x:= rect.x - frame.left; + result.cx:= rect.cx + frame.left + frame.right; + result.y:= rect.y - frame.top; + result.cy:= rect.cy + frame.top + frame.bottom; +end; + +procedure inflaterect1(var rect: rectty; value: integer); +begin + with rect do begin + dec(x,value); + dec(y,value); + inc(cx,value); + inc(cx,value); + inc(cy,value); + inc(cy,value); + end; +end; + +procedure inflaterect1(var rect: rectty; const value: int32; + const disablededges: edgesty); +begin + with rect do begin + if not (edg_left in disablededges) then begin + dec(x,value); + inc(cx,value); + end; + if not (edg_top in disablededges) then begin + dec(y,value); + inc(cy,value); + end; + if not (edg_right in disablededges) then begin + inc(cx,value); + end; + if not (edg_bottom in disablededges) then begin + inc(cy,value); + end; + end; +end; + +procedure inflaterect1(var rect: rectty; const frame: framety); +begin + dec(rect.x,frame.left); + inc(rect.cx,frame.left); + dec(rect.y,frame.top); + inc(rect.cy,frame.top); + inc(rect.cx,frame.right); + inc(rect.cy,frame.bottom); +end; + + +procedure inflateframe1(var frame: framety; value: integer); +begin + inc(frame.left,value); + inc(frame.top,value); + inc(frame.right,value); + inc(frame.bottom,value); +end; + +function inflateframe(const frame: framety; value: integer): framety; +begin + result.left:= frame.left + value; + result.top:= frame.top + value; + result.right:= frame.right + value; + result.bottom:= frame.bottom + value; +end; + + +function moverect(const rect: rectty; const dist: pointty): rectty; +begin + result.x:= rect.x + dist.x; + result.y:= rect.y + dist.y; + result.size:= rect.size; +end; + +procedure moverect1(var rect: rectty; const dist: pointty); +begin + inc(rect.x,dist.x); + inc(rect.y,dist.y); +end; + +function removerect(const rect: rectty; const dist: pointty): rectty; +begin + result.x:= rect.x - dist.x; + result.y:= rect.y - dist.y; + result.size:= rect.size; +end; + +procedure removerect1(var rect: rectty; const dist: pointty); +begin + dec(rect.x,dist.x); + dec(rect.y,dist.y); +end; + +function intersectrect(const a,b: rectty; out dest: rectty): boolean; +var + rect1: rectty; +begin + with rect1 do begin + if a.x > b.x then begin + x:= a.x; + if a.x + a.cx > b.x + b.cx then begin + cx:= b.x + b.cx - a.x; + end + else begin + cx:= a.cx; + end; + end + else begin + x:= b.x; + if b.x + b.cx > a.x + a.cx then begin + cx:= a.x + a.cx - b.x; + end + else begin + cx:= b.cx; + end; + end; + if a.y > b.y then begin + y:= a.y; + if a.y + a.cy > b.y + b.cy then begin + cy:= b.y + b.cy - a.y; + end + else begin + cy:= a.cy; + end; + end + else begin + y:= b.y; + if b.y + b.cy > a.y + a.cy then begin + cy:= a.y + a.cy - b.y; + end + else begin + cy:= b.cy; + end; + end; + if (cx <= 0) or (cy <= 0) then begin + result:= false; + dest:= nullrect; + end + else begin + result:= true; + dest:= rect1; + end; + end; +end; + +function intersectrect(const a,b: rectty): rectty; +begin + intersectrect(a,b,result); +end; + +procedure intersectrect1(var dest: rectty; const source: rectty); +begin + intersectrect(source,dest,dest); +end; + +function testintersectrect(const a,b: rectty): boolean; + //true on intersection +var + rect1: rectty; +begin + result:= intersectrect(a,b,rect1); +end; + +function combinerect(const a,b: rectty): rectty; +var + i1: int32; + ps,pe: pointty; +begin + ps:= a.pos; + if a.x > b.x then begin + ps.x:= b.x; + end; + if a.y > b.y then begin + ps.y:= b.y; + end; + pe.x:= a.x + a.cx; + i1:= b.x + b.cx; + if i1 > pe.x then begin + pe.x:= i1; + end; + pe.y:= a.y + a.cy; + i1:= b.y + b.cy; + if i1 > pe.y then begin + pe.y:= i1; + end; + result.pos:= ps; + result.cx:= pe.x-ps.x; + result.cy:= pe.y-ps.y; +end; + +procedure combinerect1(var a: rectty; const b: rectty); +begin + a:= combinerect(a,b); +end; + +function rectinrect(const inner,outer: rectty): boolean; + + procedure normalize(const rect: rectty; out topleft,bottomright: pointty); + begin + with rect do begin + if cx < 0 then begin + topleft.x:= x + cx; + bottomright.x:= x; + end + else begin + topleft.x:= x; + bottomright.x:= x + cx; + end; + if cy < 0 then begin + topleft.y:= y + cy; + bottomright.y:= y; + end + else begin + topleft.y:= y; + bottomright.y:= y + cy; + end; + end; + end; + +var + itopleft,ibottomright: pointty; + otopleft,obottomright: pointty; +begin + normalize(inner,itopleft,ibottomright); + normalize(outer,otopleft,obottomright); + result:= (itopleft.x >= otopleft.x) and (ibottomright.x <= obottomright.x) and + (itopleft.y >= otopleft.y) and (ibottomright.y <= obottomright.y); +end; + +function clipinrect1(var point: pointty; const boundsrect: rectty): boolean; +begin + result:= false; + with boundsrect do begin + if point.x < x then begin + result:= true; + point.x:= x; + end; + if point.x >= x + cx then begin + result:= true; + point.x:= x + cx - 1; + end; + if point.y < y then begin + result:= true; + point.y:= y; + end; + if point.y >= y + cy then begin + result:= true; + point.y:= y + cy - 1; + end; + end; +end; + +function clipinrect(const point: pointty; const boundsrect: rectty): pointty; +begin + result:= point; + clipinrect1(result,boundsrect); +end; + +function clipinrect1(var rect: rectty; const boundsrect: rectty): boolean; +begin + result:= false; + with boundsrect do begin + if rect.x < x then begin + result:= true; + rect.x:= x; + end; + if rect.x + rect.cx > x + cx then begin + rect.x:= x + cx - rect.cx; + if rect.x < x then begin + result:= true; + rect.x:= x; + rect.cx:= cx; + end; + end; + if rect.y < y then begin + result:= true; + rect.y:= y; + end; + if rect.y + rect.cy > y + cy then begin + result:= true; + rect.y:= y + cy - rect.cy; + if rect.y < y then begin + rect.y:= y; + rect.cy:= cy; + end; + end; + end; +end; + +function clipinrect(const rect: rectty; const boundsrect: rectty): rectty; +begin + result:= rect; + clipinrect1(result,boundsrect); +end; + +function rx(const arect: rectty): integer; +begin + result:= arect.x; +end; + +function ry(const arect: rectty): integer; +begin + result:= arect.y; +end; + +function rcx(const arect: rectty): integer; +begin + result:= arect.cx; +end; + +function rcy(const arect: rectty): integer; +begin + result:= arect.cy; +end; + +function rstopx(const arect: rectty): integer; +begin + result:= arect.x + arect.cx; +end; + +function rstopy(const arect: rectty): integer; +begin + result:= arect.y + arect.cy; +end; + +procedure rsetx(var arect: rectty; const avalue: integer); +begin + arect.x:= avalue; +end; + +procedure rsety(var arect: rectty; const avalue: integer); +begin + arect.y:= avalue; +end; + +procedure rsetcx(var arect: rectty; const avalue: integer); +begin + arect.cx:= avalue; +end; + +procedure rsetcy(var arect: rectty; const avalue: integer); +begin + arect.cy:= avalue; +end; + +procedure rsetstopx(var arect: rectty; const avalue: integer); +begin + arect.cx:= avalue - arect.x; +end; + +procedure rsetstopy(var arect: rectty; const avalue: integer); +begin + arect.cy:= avalue - arect.y; +end; + +function makesizex(const value,ovalue: integer): sizety; +begin + result.cx:= value; + result.cy:= ovalue; +end; + +function makesizey(const value,ovalue: integer): sizety; +begin + result.cy:= value; + result.cx:= ovalue; +end; + +function makeposx(const value,ovalue: integer): pointty; +begin + result.x:= value; + result.y:= ovalue; +end; + +function makeposy(const value,ovalue: integer): pointty; +begin + result.y:= value; + result.x:= ovalue; +end; + +function px(const apoint: pointty): integer; +begin + result:= apoint.x; +end; + +function py(const apoint: pointty): integer; +begin + result:= apoint.y; +end; + +function sx(const asize: sizety): integer; +begin + result:= asize.cx; +end; + +function sy(const asize: sizety): integer; +begin + result:= asize.cy; +end; + +procedure psetx(var apoint: pointty; const avalue: integer); +begin + apoint.x:= avalue; +end; + +procedure psety(var apoint: pointty; const avalue: integer); +begin + apoint.y:= avalue; +end; + +procedure ssetx(var asize: sizety; const avalue: integer); +begin + asize.cx:= avalue; +end; + +procedure ssety(var asize: sizety; const avalue: integer); +begin + asize.cy:= avalue; +end; + +procedure gdierror(error: gdierrorty; const text: msestring = ''); overload; +begin + if error = gde_ok then begin + exit; + end; + raise egdi.create(error,ansistring(text)); +end; + +procedure gdierror(error: gdierrorty; sender: tobject; + text: msestring = ''); overload; +begin + if error = gde_ok then begin + exit; + end; + if sender <> nil then begin + text:= msestring(sender.classname) + ' ' + text; + if sender is tcomponent then begin + text:= text + ' ' + msestring(fullcomponentname(tcomponent(sender))); + end; + end; + gdierror(error,text); +end; + +{ egdi } + +constructor egdi.create(aerror: gdierrorty; atext: string); +begin + inherited create(integer(aerror),atext,errortexts); +end; + +end. + diff --git a/mseide-msegui/lib/common/graphics/mselinetria.pas b/mseide-msegui/lib/common/graphics/mselinetria.pas new file mode 100644 index 0000000..8ebf75c --- /dev/null +++ b/mseide-msegui/lib/common/graphics/mselinetria.pas @@ -0,0 +1,943 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mselinetria; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics,msegraphutils,msetriaglob; +type + lineshiftvectorty = record + shift: pointty; + d: pointty; //delta + c: integer; //length + end; + lineshiftinfoty = record + dist: integer; + offsx,offsy: integer; + pointa: ppointty; + pointb: ppointty; + linestart: ppointty; + v: lineshiftvectorty; + offs: pointty; + dest: ppointty; + dashlen: integer; + dashind: integer; + dashpos: integer; + dashref: integer; + reverse: boolean; + end; + plineshiftinfoty = ^lineshiftinfoty; + +function linestria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; + //true if triangles, tristrip otherwise +procedure linesegmentstria(var drawinfo: drawinfoty; + out atriangles: ptrianglety; out atrianglecount: integer); + +procedure updatestarttria(var drawinfo: drawinfoty; var li: lineshiftinfoty); +procedure updatestartstrip(var drawinfo: drawinfoty; var li: lineshiftinfoty); +procedure updateendtria(var drawinfo: drawinfoty; var li: lineshiftinfoty); +procedure updateendstrip(var drawinfo: drawinfoty; var li: lineshiftinfoty); + +implementation +const + arctablesize = 20; // max diameter + arcrowsize = arctablesize div 2 - 2; + arcscalefact = 256; //value scaling = 128 + bevelangsin = sin(2*pi*11.0/360.0); +type + arctablety = array[0..arctablesize,0..arcrowsize] of byte; +const + arctable: arctablety = ( + (0,0,0,0,0,0,0,0,0), //0 + (0,0,0,0,0,0,0,0,0), //1 + (0,0,0,0,0,0,0,0,0), //2 + (33,0,0,0,0,0,0,0,0), //3 + (17,0,0,0,0,0,0,0,0), //4 + (11,51,0,0,0,0,0,0,0), //5 + (7,33,0,0,0,0,0,0,0), //6 + (5,23,62,0,0,0,0,0,0), //7 + (4,17,43,0,0,0,0,0,0), //8 + (3,13,33,69,0,0,0,0,0), //9 + (3,11,26,51,0,0,0,0,0), //10 + (2,9,21,40,75,0,0,0,0), //11 + (2,7,17,33,57,0,0,0,0), //12 + (2,6,14,27,46,79,0,0,0), //13 + (1,5,12,23,38,62,0,0,0), //14 + (1,5,11,20,33,51,82,0,0), //15 + (1,4,9,17,28,43,66,0,0), //16 + (1,4,8,15,24,37,55,85,0), //17 + (1,3,7,13,22,33,48,69,0), //18 + (1,3,7,12,19,29,41,59,87), //19 + (1,3,6,11,17,26,37,51,72) //20 +); +// +//todo: optimize smooth line generation +// +function calclineshift(const drawinfo: drawinfoty; var info: lineshiftinfoty; + const skipzerolength: boolean): boolean; + //true if valid +var + dx1,dy1: integer; +begin + result:= true; + with info do begin + dx1:= pointb^.x - pointa^.x; + dy1:= pointb^.y - pointa^.y; + if skipzerolength and (dx1 = 0) and (dy1 = 0) then begin + result:= false; + exit; + end; + v.c:= round(sqrt(dx1*dx1 + dy1*dy1)); //todo: optimize + offsx:= 0; + offsy:= 0; + if v.c = 0 then begin + v.shift.x:= 0; //default direction + v.shift.y:= dist; + end + else begin + v.shift.x:= (dy1*dist) div v.c; + v.shift.y:= (dx1*dist) div v.c; + if dist and $10000 <> 0 then begin //odd, shift 0.5 pixel + offsx:= abs(dy1 shl 15) div v.c; + offsy:= abs(dx1 shl 15) div v.c; + end; + end; + offs.x:= (drawinfo.origin.x shl 16) + v.shift.x div 2 + offsx; + offs.y:= (drawinfo.origin.y shl 16) - v.shift.y div 2 + offsy; + linestart:= pointa; + v.d.x:= dx1; + v.d.y:= dy1; + end; +end; + +function isbevelang(const li: lineshiftinfoty; const da: pointty): boolean; +const + bevelangmax = round(bevelangsin*256); +var + int1,int2: integer; + dax,day,dbx,dby: integer; +begin + result:= false; + with li do begin + dax:= da.y div 256; //with is orthogonal to vector, negative + day:= da.x div 256; + dbx:= li.v.shift.y div 256; + dby:= li.v.shift.x div 256; + if dax*dbx + day*dby < 0 then begin + int1:= dbx*day - dax*dby; + int2:= dist div (16*256); + result:= abs(int1 div (int2 * int2)) < bevelangmax; + end; + end; +end; + +procedure shiftpoint(var info: lineshiftinfoty); +var + x1,y1: integer; +begin + with info do begin + x1:= (pointa^.x shl 16) + offs.x; + y1:= (pointa^.y shl 16) + offs.y; + dest^.x:= x1; + dest^.y:= y1; + inc(dest); + dest^.x:= x1 - v.shift.x; + dest^.y:= y1 + v.shift.y; + inc(dest); + pointa:= pointb; + inc(pointb); + end; +end; + +procedure shiftpointa(var info: lineshiftinfoty); + //no source increment +var + x1,y1: integer; +begin + with info do begin + x1:= (pointa^.x shl 16) + offs.x; + y1:= (pointa^.y shl 16) + offs.y; + dest^.x:= x1; + dest^.y:= y1; + inc(dest); + dest^.x:= x1 - v.shift.x; + dest^.y:= y1 + v.shift.y; + inc(dest); + end; +end; + +procedure shiftpointb(var info: lineshiftinfoty); + //no source increment +var + x1,y1: integer; +begin + with info do begin + x1:= (pointb^.x shl 16) + offs.x; + y1:= (pointb^.y shl 16) + offs.y; + dest^.x:= x1; + dest^.y:= y1; + inc(dest); + dest^.x:= x1 - v.shift.x; + dest^.y:= y1 + v.shift.y; + inc(dest); + end; +end; + +type + intersectinfoty = record + da,db: pointty; + p0,p1: ppointty; + isect: pointty; + axbx,axby,aybx,ayby: int64; + q: integer; + end; + +procedure intersect2(var info: intersectinfoty); + //todo: limit overflow +begin + with info do begin +//xa == (dxa*dxb*y0 - dxa*dxb*y1 + dxa*dyb*x1 - dxb*dya*x0)/(dxa*dyb - dxb*dya) + isect.x:= (axbx*p0^.y - axbx*p1^.y + axby*p1^.x - aybx*p0^.x) div q; +//ya == (dxa*dyb*y0 - dxb*dya*y1 - dya*dyb*x0 + dya*dyb*x1)/(dxa*dyb - dxb*dya) + isect.y:= (axby*p0^.y - aybx*p1^.y - ayby*p0^.x + ayby*p1^.x) div q; + end; +end; + +function intersect(var info: intersectinfoty): boolean; + //todo: limit overflow +begin + result:= false; + with info do begin + axby:= da.x*db.y; + aybx:= da.y*db.x; + q:= axby - aybx; + if q <> 0 then begin + result:= true; + axbx:= da.x*db.x; + ayby:= da.y*db.y; + intersect2(info); + end; + end; +end; + +procedure roundcapstarttria(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1,sx2,sy2: integer; + int1: integer; + po1: ppointty; + po2: pbyte; + pt1,pt2: pointty; + first: boolean; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + po1:= li.dest; + dec(po1); + pt2:= (po1)^; + dec(po1); + pt1:= (po1)^; + if linewidth <= arctablesize then begin + sx1:= (li.v.shift.y) div 2; //axial + sy1:= (li.v.shift.x) div 2; + po1^.x:= (pt1.x + pt2.x) div 2 - sx1; + po1^.y:= (pt1.y + pt2.y) div 2 - sy1; + inc(po1); + po2:= @arctable[linewidth]; + inc(po2,linewidth1 div 2 - 2); + first:= true; + for int1:= linewidth div 2 - 1 downto 1 do begin + if not first then begin + po1^:= (po1-2)^; //0 + inc(po1); + po1^:= (po1-2)^; //1 + inc(po1); + end; + sx1:= (li.v.shift.y*int1) div linewidth1; //axial + sy1:= (li.v.shift.x*int1) div linewidth1; + sx2:= (li.v.shift.x*po2^) div arcscalefact; //orthogonal + sy2:= (li.v.shift.y*po2^) div arcscalefact; + if li.reverse then begin + sx2:= -sx2; + sy2:= -sy2; + end; + po1^.x:= pt1.x - sx1 - sx2; //2 + po1^.y:= pt1.y - sy1 + sy2; + inc(po1); + if not first then begin + po1^:= (po1-2)^; //3 + inc(po1); + po1^:= (po1-2)^; //4 + inc(po1); + end; + po1^.x:= pt2.x - sx1 + sx2; //5 + po1^.y:= pt2.y - sy1 - sy2; + inc(po1); + dec(po2); + first:= false; + end; + if not first then begin + po1^:= (po1-2)^; //0 + inc(po1); + po1^:= (po1-2)^; //1 + inc(po1); + po1^:= pt1; //2 + inc(po1); + po1^:= (po1-2)^; //3 + inc(po1); + end; + po1^:= pt1; //4 + inc(po1); + po1^:= pt2; //5 + inc(po1); + po1^:= pt1; //0 + inc(po1); + po1^:= pt2; //1 + inc(po1); + li.dest:= po1; + end; + end; +end; + +procedure updatestarttria(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1: integer; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + if (linewidth = 0) or (trf_capprojecting in triaflags) then begin + sx1:= li.v.shift.y div 2 - li.offsy; + sy1:= li.v.shift.x div 2 - li.offsx; + with (li.dest-2)^ do begin + x:= x - sx1; + y:= y - sy1; + end; + with (li.dest-1)^ do begin + x:= x - sx1; + y:= y - sy1; + end; + end + else begin + if trf_capround in triaflags then begin + roundcapstarttria(drawinfo,li); + end; + end; + end; +end; + +procedure roundcapstartstrip(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1,sx2,sy2: integer; + int1: integer; + po1: ppointty; + po2: pbyte; + pt1,pt2: pointty; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + po1:= li.dest; + dec(po1); + pt2:= (po1)^; + dec(po1); + pt1:= (po1)^; + if linewidth <= arctablesize then begin + sx1:= (li.v.shift.y) div 2; //axial + sy1:= (li.v.shift.x) div 2; + po1^.x:= (pt1.x + pt2.x) div 2 - sx1; + po1^.y:= (pt1.y + pt2.y) div 2 - sy1; + inc(po1); + po2:= @arctable[linewidth]; + inc(po2,linewidth1 div 2 - 2); + for int1:= linewidth div 2 - 1 downto 1 do begin + sx1:= (li.v.shift.y*int1) div linewidth1; //axial + sy1:= (li.v.shift.x*int1) div linewidth1; + sx2:= (li.v.shift.x*po2^) div arcscalefact; //orthogonal + sy2:= (li.v.shift.y*po2^) div arcscalefact; + if li.reverse then begin + sx2:= -sx2; + sy2:= -sy2; + end; + po1^.x:= pt1.x - sx1 - sx2; + po1^.y:= pt1.y - sy1 + sy2; + inc(po1); + po1^.x:= pt2.x - sx1 + sx2; + po1^.y:= pt2.y - sy1 - sy2; + inc(po1); + dec(po2); + end; + po1^:= pt1; + inc(po1); + po1^:= pt2; + inc(po1); + li.dest:= po1; + end; + end; +end; + +procedure updatestartstrip(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1: integer; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + if (linewidth = 0) or (trf_capprojecting in triaflags) then begin + sx1:= li.v.shift.y div 2 - li.offsy; + sy1:= li.v.shift.x div 2 - li.offsx; + with (li.dest-2)^ do begin + x:= x - sx1; + y:= y - sy1; + end; + with (li.dest-1)^ do begin + x:= x - sx1; + y:= y - sy1; + end; + end + else begin + if trf_capround in triaflags then begin + roundcapstartstrip(drawinfo,li); + end; + end; + end; +end; + +procedure updateendtria(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1,sx2,sy2: integer; + int1: integer; + po1: ppointty; + po2: pbyte; + pt1,pt2: pointty; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + if (linewidth = 0) or (trf_capprojecting in triaflags) then begin + sx1:= li.v.shift.y div 2 + li.offsy; + sy1:= li.v.shift.x div 2 + li.offsx; + with (li.dest-2)^ do begin + x:= x + sx1; + y:= y + sy1; + end; + with (li.dest-1)^ do begin + x:= x + sx1; + y:= y + sy1; + end; + end + else begin + if trf_capround in triaflags then begin + if linewidth <= arctablesize then begin + po1:= li.dest; + (po1-4)^:= (po1-2)^; + pt1:= (po1-2)^; + pt2:= (po1-1)^; + po1^:= pt1; + inc(po1); + po1^:= pt2; + inc(po1); + po2:= @arctable[linewidth]; + for int1:= 1 to linewidth div 2 - 1 do begin + sx1:= (li.v.shift.y*int1) div linewidth1; //axial + sy1:= (li.v.shift.x*int1) div linewidth1; + sx2:= (li.v.shift.x*po2^) div arcscalefact; //orthogonal + sy2:= (li.v.shift.y*po2^) div arcscalefact; + if li.reverse then begin + sx2:= -sx2; + sy2:= -sy2; + end; + po1^.x:= pt1.x + sx1 - sx2; //0 + po1^.y:= pt1.y + sy1 + sy2; + inc(po1); + po1^:= (po1-2)^; //1 + inc(po1); + po1^:= (po1-2)^; //2 + inc(po1); + po1^.x:= pt2.x + sx1 + sx2; //3 + po1^.y:= pt2.y + sy1 - sy2; + inc(po1); + po1^:= (po1-2)^; //4 + inc(po1); + po1^:= (po1-2)^; //5 + inc(po1); + inc(po2); + end; + sx1:= (li.v.shift.y) div 2; //axial + sy1:= (li.v.shift.x) div 2; + po1^.x:= (pt1.x + pt2.x) div 2 + sx1; + po1^.y:= (pt1.y + pt2.y) div 2 + sy1; + inc(po1); + li.dest:= po1; + exit; + end; + end; + end; + end; + (li.dest-4)^:= (li.dest-2)^; +end; + +procedure updateendstrip(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1,sx2,sy2: integer; + int1: integer; + po1: ppointty; + po2: pbyte; + pt1,pt2: pointty; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + if (linewidth = 0) or (trf_capprojecting in triaflags) then begin + sx1:= li.v.shift.y div 2 + li.offsy; + sy1:= li.v.shift.x div 2 + li.offsx; + with (li.dest-2)^ do begin + x:= x + sx1; + y:= y + sy1; + end; + with (li.dest-1)^ do begin + x:= x + sx1; + y:= y + sy1; + end; + end + else begin + if trf_capround in triaflags then begin + if linewidth <= arctablesize then begin + po1:= li.dest; + pt1:= (po1-2)^; + pt2:= (po1-1)^; + po2:= @arctable[linewidth]; + for int1:= 1 to linewidth div 2 - 1 do begin + sx1:= (li.v.shift.y*int1) div linewidth1; //axial + sy1:= (li.v.shift.x*int1) div linewidth1; + sx2:= (li.v.shift.x*po2^) div arcscalefact; //orthogonal + sy2:= (li.v.shift.y*po2^) div arcscalefact; + if li.reverse then begin + sx2:= -sx2; + sy2:= -sy2; + end; + po1^.x:= pt1.x + sx1 - sx2; + po1^.y:= pt1.y + sy1 + sy2; + inc(po1); + po1^.x:= pt2.x + sx1 + sx2; + po1^.y:= pt2.y + sy1 - sy2; + inc(po1); + inc(po2); + end; + sx1:= (li.v.shift.y) div 2; //axial + sy1:= (li.v.shift.x) div 2; + po1^.x:= (pt1.x + pt2.x) div 2 + sx1; + po1^.y:= (pt1.y + pt2.y) div 2 + sy1; + inc(po1); + li.dest:= po1; + end; + end; + end; + end; +end; + +procedure dashinit(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + int1: integer; +begin + with drawinfo,triagcty(gc.platformdata).d do begin +// allocbuffer(buffer,3*sizeof(pointty)); //possible first triangle + buffer.cursize:= 0; + li.dest:= buffer.buffer; + li.dashlen:= 0; + for int1:= 1 to length(xftdashes) do begin + li.dashlen:= li.dashlen + ord(xftdashes[int1]); + end; + end; +end; + +procedure dash(var drawinfo: drawinfoty; var li: lineshiftinfoty; + const start: boolean; const endpoint: boolean); +var + po3: ppointty; + pt0: pointty; + dx,dy: integer; + dashstop,dashpos,dashind: integer; + x1,y1: integer; + int1: integer; +begin + with drawinfo,triagcty(gc.platformdata).d do begin + if start then begin + dashpos:= ord(xftdashes[1]); + dashind:= 1; + li.dashref:= 0; + end + else begin + dashpos:= li.dashpos-li.dashref; + dashind:= li.dashind; + end; + dashstop:= li.v.c; + int1:= ((dashstop-dashpos) div li.dashlen + 1)*length(xftdashes) + 3*2; + //+3*2 -> additional memory for ends and vertex + if trf_capround in triaflags then begin + int1:= int1*linewidth1; + end; + int1:= int1 * 6*sizeof(pointty); //2 triangles per segment + extendbuffer(buffer,int1,li.dest); + po3:= li.dest; + pt0.x:= (li.linestart^.x shl 16) + li.offs.x; + pt0.y:= (li.linestart^.y shl 16) + li.offs.y; + dx:= (li.v.d.x shl 16) div li.v.c; + dy:= (li.v.d.y shl 16) div li.v.c; + while dashpos < dashstop do begin + if odd(dashind) then begin //end dash + x1:= pt0.x + dashpos*dx; + y1:= pt0.y + dashpos*dy; + po3^.x:= x1; + po3^.y:= y1; + inc(po3); + po3^:= (po3-2)^; + inc(po3); + po3^.x:= x1; + po3^.y:= y1; + inc(po3); + po3^.x:= x1 - li.v.shift.x; + po3^.y:= y1 + li.v.shift.y; + inc(po3); + li.dest:= po3; + if linewidth <> 0 then begin + updateendtria(drawinfo,li); + po3:= li.dest; + end; + end + else begin //start dash + x1:= pt0.x + dashpos*dx; + y1:= pt0.y + dashpos*dy; + po3^.x:= x1; + po3^.y:= y1; + inc(po3); + po3^.x:= x1 - li.v.shift.x; + po3^.y:= y1 + li.v.shift.y; + inc(po3); + li.dest:= po3; + if linewidth <> 0 then begin + updatestarttria(drawinfo,li); + po3:= li.dest; + end; + end; + inc(dashind); + if dashind > length(xftdashes) then begin + dashind:= 1; + end; + dashpos:= dashpos + ord(xftdashes[dashind]); + end; + if odd(dashind) and endpoint then begin //end dash + x1:= pt0.x + (li.v.d.x shl 16); + y1:= pt0.y + (li.v.d.y shl 16); + po3^.x:= x1; + po3^.y:= y1; + inc(po3); + po3^:= (po3-2)^; + inc(po3); + po3^.x:= x1; + po3^.y:= y1; + inc(po3); + po3^.x:= x1 - li.v.shift.x; + po3^.y:= y1 + li.v.shift.y; + inc(po3); + li.dest:= po3; + if linewidth <> 0 then begin + updateendtria(drawinfo,li); + po3:= li.dest; + end; + end; + li.dest:= po3; + li.dashind:= dashind; + li.dashpos:= dashpos+li.dashref; + li.dashref:= li.dashref+li.v.c; + end; +end; + +function linestria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; +var + li: lineshiftinfoty; + pt0,pt1,pt3: pointty; + int1,int2: integer; + pointcount: integer; + ints: intersectinfoty; + pend: ppointty; + firstdash,bo1,bo2: boolean; + singlepoint: array[0..1] of pointty; + pointsbefore: ppointty; + pt2: pointty; + po0: ppointty; + +begin + //todo: remove overlapping regions + result:= false; + with drawinfo,points,triagcty(gc.platformdata).d do begin + pointsbefore:= points; + pointcount:= count; + if count = 1 then begin + singlepoint[0]:= points^; + singlepoint[1]:= points^; //dummy segment + points:= @singlepoint[0]; + inc(pointcount); + end; + if closed then begin + inc(pointcount); + end; + pointcount:= pointcount*2; + li.pointa:= points; + pend:= points+count; + li.pointb:= li.pointa+1; + li.dist:= linewidth16; + li.reverse:= false; + if closed then begin + int2:= count-1; + end + else begin + int2:= count-3; + end; + if df_dashed in gc.drawingflags then begin + result:= true; + int1:= (pointcount+linewidth1); //for round caps + if trf_joinround in triaflags then begin + int1:= int1 + linewidth div 2; //round corners + end; + allocbuffer(buffer,int1*2*6*sizeof(pointty)); + dashinit(drawinfo,li); + calclineshift(drawinfo,li,false); + shiftpoint(li); + if (linewidth <> 0) and not closed then begin + updatestarttria(drawinfo,li); + end; + firstdash:= true; //start dash + for int1:= 0 to int2 do begin + if li.pointb = pend then begin + li.pointb:= points; + end; + dash(drawinfo,li,firstdash,false); + firstdash:= false; + if odd(li.dashind) then begin //dash end + inc(li.dest); + li.dest^:= (li.dest-2)^; + inc(li.dest); + shiftpointa(li); + (li.dest-4)^:= (li.dest-2)^; + end; + + ints.da:= li.v.d; + pt2:= li.v.shift; + calclineshift(drawinfo,li,false); + shiftpoint(li); + po0:= li.dest; + ints.db:= li.v.d; + ints.p0:= po0-4; + ints.p1:= po0-2; + pt0:= (li.dest-2)^; + pt1:= (li.dest-1)^; + if trf_joinround in triaflags then begin + if odd(li.dashind) then begin + roundcapstarttria(drawinfo,li); + end; + end + else begin + if intersect(ints) then begin + pt3:= subpoint(ints.isect,ints.p1^); //intersection - bstart + bo1:= ((pt3.x > 0) xor (li.v.d.x > 0)) or ((pt3.y > 0) xor (li.v.d.y > 0)); + //outer, cw + bo2:= (trf_joinbevel in triaflags) or + (trf_joinmiter in triaflags) and isbevelang(li,pt2); + ///bevel + if not bo1 then begin + inc(ints.p0); + inc(ints.p1); + intersect2(ints); + if not bo2 then begin + pt1:= ints.isect; + end; + end + else begin + if not bo2 then begin + pt0:= ints.isect; + end; + end; + if odd(li.dashind) then begin + if bo1 then begin //cw + if bo2 then begin //bevel + po0^:= (po0-4)^; + inc(po0); + po0^:= (po0-3)^; //start next + inc(po0); + po0^:= (po0-3)^; + inc(po0); + end + else begin //mieter + pt0:= ints.isect; + po0^:= pt0; //8 + inc(po0); + po0^:= pt0; //9 + inc(po0); + po0^:= (po0-6)^; //10 + inc(po0); + po0^:= (po0-4)^; //11 + inc(po0); + po0^:= (po0-6)^; //12 + inc(po0); + po0^:= (po0-6)^; //13 + inc(po0); + end; + end + else begin //ccw + if bo2 then begin //bevel + po0^:= (po0-3)^; + inc(po0); + po0^:= (po0-3)^; //start next + inc(po0); + po0^:= (po0-3)^; + inc(po0); + end + else begin //miter + pt1:= ints.isect; + po0^:= pt1; //8 + inc(po0); + po0^:= pt1; //9 + inc(po0); + po0^:= (po0-5)^; //10 + inc(po0); + po0^:= (po0-5)^; //11 + inc(po0); + po0^:= (po0-6)^; //12 + inc(po0); + po0^:= (po0-6)^; //13 + inc(po0); + end; + end; + end; + end; + li.dest:= po0; + end; + if not odd(li.dashind) then begin //no dash + dec(li.dest,2); //remove start + end; + end; + if closed then begin +{$warnings off} + (ppointty(buffer.buffer))^:= pt0; + (ppointty(buffer.buffer)+1)^:= pt1; + (ppointty(buffer.buffer)+3)^:= pt1; + end + else begin + dash(drawinfo,li,firstdash,true); + end; + end + else begin + int1:= 2; //for bevel + if trf_joinround in triaflags then begin + int1:= int1 + (linewidth1+1) div 2; //round corners + end; + int1:= int1*pointcount+linewidth; //for round caps + allocbuffer(buffer,int1*(2*sizeof(pointty))); + li.dest:= buffer.buffer; + calclineshift(drawinfo,li,false); + shiftpoint(li); + if not closed then begin + updatestartstrip(drawinfo,li); + end; + for int1:= 0 to int2 do begin + if li.pointb = pend then begin + li.pointb:= points; + end; + shiftpointa(li); //no source increment + ints.da:= li.v.d; + pt2:= li.v.shift; + if calclineshift(drawinfo,li,true) then begin + shiftpoint(li); + ints.db:= li.v.d; + ints.p0:= li.dest-4; + ints.p1:= li.dest-2; + if intersect(ints) then begin + if trf_joinround in triaflags then begin + roundcapstartstrip(drawinfo,li); + ints.p1:= li.dest-1; + end + else begin + pt1:= subpoint(ints.isect,ints.p1^); //intersection - bstart + bo1:= ((pt1.x > 0) xor (li.v.d.x > 0)) or + ((pt1.y > 0) xor (li.v.d.y > 0)); //outer + bo2:= (trf_joinbevel in triaflags) or + (trf_joinmiter in triaflags) and isbevelang(li,pt2); + if bo1 and not bo2 then begin //move to intersection + ints.p1^:= ints.isect; + (ints.p1-2)^:= ints.isect; + end; + inc(ints.p0); + inc(ints.p1); + intersect2(ints); + if not bo1 and not bo2 then begin //move to intersection + ints.p1^:= ints.isect; + (ints.p1-2)^:= ints.isect; + end; + end; + end; + end + else begin //zero length line + dec(li.dest,2); + li.pointa:= li.pointb; + inc(li.pointb); + end; + end; + if closed then begin + (ppointty(buffer.buffer))^:= (ints.p1-1)^; + (ppointty(buffer.buffer)+1)^:= ints.p1^; + end + else begin + shiftpoint(li); + updateendstrip(drawinfo,li); + end; + end; + points:= pointsbefore; + apoints:= buffer.buffer; + apointcount:= li.dest-ppointty(buffer.buffer); + end; +end; +{$warnings on} +procedure linesegmentstria(var drawinfo: drawinfoty; + out atriangles: ptrianglety; out atrianglecount: integer); +var + int1: integer; + li: lineshiftinfoty; +begin + with drawinfo,drawinfo.points,triagcty(gc.platformdata).d do begin + li.pointa:= points; + li.pointb:= li.pointa+1; + li.dist:= linewidth16; + li.reverse:= false; + allocbuffer(buffer,count*(6+6*linewidth1)*sizeof(pointty)); + //for round caps + if df_dashed in gc.drawingflags then begin + dashinit(drawinfo,li); + for int1:= 0 to (count div 2)-1 do begin + calclineshift(drawinfo,li,false); + shiftpoint(li); + if linewidth <> 0 then begin + updatestarttria(drawinfo,li); + end; + dash(drawinfo,li,true,true); + li.pointa:= li.pointb; + inc(li.pointb); + end; + end + else begin + li.dest:= buffer.buffer; + for int1:= 0 to (count div 2)-1 do begin + calclineshift(drawinfo,li,false); + shiftpoint(li); + updatestarttria(drawinfo,li); + inc(li.dest); + li.dest^:= (li.dest-2)^; + inc(li.dest); + shiftpoint(li); + updateendtria(drawinfo,li); +// (li.dest-4)^:= (li.dest-2)^; + end; + end; + atriangles:= buffer.buffer; + atrianglecount:= (li.dest-ppointty(buffer.buffer)) div 3; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msepolytria.pas b/mseide-msegui/lib/common/graphics/msepolytria.pas new file mode 100644 index 0000000..98abf49 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msepolytria.pas @@ -0,0 +1,1793 @@ +{ MSEgui Copyright (c) 2013-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepolytria; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics,msegraphutils,msetriaglob; + +procedure polytria(var drawinfo: drawinfoty; out atriangles: ptrianglety; + out trianglecount: integer); + +{$ifdef mse_debugpolytria1} +type + trapdispinfoty = array[0..3] of pointty; + trity = record + p: array[0..2] of pointty; + end; + triarty = array of trity; + mountaininfoty = record + chain: pointarty; + end; + mountaininfoarty = array of mountaininfoty; +var + debugtraps: array of trapdispinfoty; + debugtriangles: triarty; + debugmountains: mountaininfoarty; + debugdiags: segmentarty; +{$endif} + +{$ifdef mse_debugpolytria} +var + debugstop: integer = -1; //stop at segment n + debugnoa: boolean; //do not handle point a of segment + debugnob: boolean; //do not handle point b of segment + debugnoseg: boolean; //do not handle segment + debugnosegsplit: boolean; //not handle segsplit + debugdumperror: boolean; + +{$endif} + +implementation +uses + msetypes,msenoise + {$ifdef mse_debugpolytria} + ,mseformatstr,sysutils,msearrayutils,msesysutils + {$endif}; + +type + trapnodekindty = (tnk_y,tnk_x,tnk_trap); + segdirty = (sd_none,sd_same,sd_up,sd_down,sd_left,sd_right); + xposty = (xp_left,xp_center,xp_right); + + + ptrapinfoty = ^trapinfoty; + pseginfoty = ^seginfoty; + ptrapnodeinfoty = ^trapnodeinfoty; + + trapinfoty = record + top,bottom: ppointty; + left,right: pseginfoty; + node: ptrapnodeinfoty; + above,abover,below,belowr: ptrapinfoty; //above,below = single or left + end; + + segflagty = (sf_pointhandled,sf_reverse); //sf_reverse -> b below a + segflagsty = set of segflagty; + ppseginfoty = ^pseginfoty; + segheaderty = record + previous: pseginfoty; + next: pseginfoty; + b: ppointty; //a is in previous segment + end; + seginfoty = record + h: segheaderty; + flags: segflagsty; + dx,dy: integer; //a-b + trap: ptrapinfoty; //inserted trap for b + splitseg: pseginfoty; //segment for horizontal split at b + diags: array[0..2] of pseginfoty; + end; + + trapnodeinfoty = record + p,l,r: ptrapnodeinfoty; //parent,left,right + case kind: trapnodekindty of + tnk_y: (y: ppointty); + tnk_x: (seg: pseginfoty); + tnk_trap: (trap: ptrapinfoty); + end; + + pmountainpointty = ^mountainpointty; + mountainpointty = record + p: ppointty; + prev: pmountainpointty; + next: pmountainpointty; + end; +const + trapcountfact = 4; //todo: check maximal buffer size + nodecountfact = 8; + mountaincountfact = 1; + trianglecountfact = 1; + trapsize = sizeof(trapinfoty)*trapcountfact; + trapnodesize = sizeof(trapnodeinfoty)*nodecountfact; + mountainsize = (3 * sizeof(mountainpointty)) * mountaincountfact; + //worst case + trianglesize = sizeof(trianglety) * trianglecountfact; + firstsize = trapsize+trapnodesize; + secondsize = mountainsize+trianglesize; +{$if secondsize > firstsize} + {$error 'mountain-triangles memory overflow'} +{$endif} + +{$ifdef mse_debugpolytria1} +function calcx(const y: integer; const seg: seginfoty): integer; +var + int1: integer; +begin + with seg do begin + if dy = 0 then begin + int1:= y - h.b^.y; + if int1 > 0 then begin + result:= bigint; + end + else begin + if int1 = 0 then begin + result:= h.b^.x; + exit; + end + else begin + result:= -bigint; + end; + end; + result:= result * dx; + end + else begin + result:= h.b^.x + (y - h.b^.y) * dx div dy; + end; + end; +end; +{$endif} + +{$ifdef mse_debugpolytria} +type + trapdumpinfoty = record + t: ptrapinfoty; + index: integer; + end; + +function calcx(const seg: pseginfoty; const y: integer): integer; +begin + with seg^ do begin + if dy = 0 then begin + result:= bigint; + if y < seg^.h.b^.y then begin + result:= -bigint; + end; + result:= result*dx; + end + else begin + result:= h.b^.x + ((y - h.b^.y)*dx) div dy; + end; + end; +end; + +function cmptrap(const l,r): integer; +var + y: integer; +begin + result:= 0; + y:= 0; + if trapdumpinfoty(l).t^.top = nil then begin + if trapdumpinfoty(r).t^.top <> nil then begin + result:= -1; + end; + end + else begin + if trapdumpinfoty(r).t^.top = nil then begin + result:= 1; + end + else begin + y:= trapdumpinfoty(r).t^.top^.y; + result:= trapdumpinfoty(l).t^.top^.y - y; + if result = 0 then begin + result:= trapdumpinfoty(l).t^.top-trapdumpinfoty(r).t^.top; + end; + end; + end; + if result = 0 then begin + if trapdumpinfoty(l).t^.left = nil then begin + if trapdumpinfoty(r).t^.left <> nil then begin + result:= -1; + end; + end + else begin + if trapdumpinfoty(r).t^.left = nil then begin + result:= 1; + end + else begin + result:= calcx(trapdumpinfoty(l).t^.left,y) - + calcx(trapdumpinfoty(r).t^.left,y); + if result = 0 then begin + if trapdumpinfoty(r).t^.right = nil then begin + result:= -1; + end; + if trapdumpinfoty(l).t^.right = nil then begin + inc(result); + end; + end; + end; + end; + end; +end; + +function intvalx(const value: integer): string; +begin + if value <= -10000 then begin + result:= ' <'; + end + else begin + if value >= 10000 then begin + result:= ' >'; + end + else begin + result:= rstring(inttostr(value),5); + end; + end; +end; + +function intvaly(const value: integer): string; +begin + if value <= -10000 then begin + result:= ' ^'; + end + else begin + if value >= 10000 then begin + result:= ' v'; + end + else begin + result:= rstring(inttostr(value),5); + end; + end; +end; + +function pointval(const x,y: integer): string; +begin + result:= intvalx(x)+':'+intvaly(y)+' '; +end; //pointval + +function pointval(const apoint: ppointty): string; +begin + result:= intvalx(apoint^.x)+':'+intvaly(apoint^.y)+' '; +end; //pointval + + +procedure dumpnodes(const anodes: ptrapnodeinfoty; + const atraps: ptrapinfoty; const asegments: pseginfoty); +type + levelsty = array[0..255] of boolean; +var + level: integer; + levels: levelsty; + + procedure dump(const n: ptrapnodeinfoty; const lline,rline: boolean); + var + int1: integer; + begin + if n <> nil then begin + inc(level); + if n^.kind <> tnk_trap then begin + levels[level-1]:= lline; + dump(n^.l,false,true); + end; + for int1:= 0 to level-2 do begin + if levels[int1] then begin + debugwrite('|'); + end + else begin + debugwrite(' '); + end; + end; + debugwrite('+'); + case n^.kind of + tnk_trap: begin + debugwriteln('('+inttostr(n^.trap-atraps)+')$'+hextostr(ptruint(n))); + end; + tnk_x: begin + debugwriteln('X='+inttostr(n^.seg-asegments)); + end; + tnk_y: begin + debugwriteln('Y='+inttostr(n^.y^.y)); + end; + end; + if n^.kind <> tnk_trap then begin + levels[level-1]:= rline; + dump(n^.r,true,false); + end; + dec(level); + levels[level]:= false; + end; + end; +begin + level:= 0; + dump(anodes,false,false); +end; + +function trapval(const atrap: ptrapinfoty; const atraps: ptrapinfoty): string; +begin + if atrap = nil then begin + result:= 'NIL'; + end + else begin + result:= rstring(inttostr(atrap-atraps),3); + end; +end; //trapval + +procedure dumpseg(const seg: pseginfoty; const asegments: pseginfoty; + const anpoints: integer; + const atraps: ptrapinfoty); +var + seg1: pseginfoty; +begin +// debugwriteln('********************************'); + debugwriteln(' S A B Atr Asp Brt Bsp'); + seg1:= seg-1; + if seg1 < asegments then begin + inc(seg1,anpoints); + end; + debugwriteln(rstring(inttostr(seg-asegments),3)+ + pointval(seg1^.h.b)+' '+pointval(seg^.h.b)+' '+ + trapval(seg1^.trap,atraps)+' '+trapval(nil,atraps)+' '+ + trapval(seg^.trap,atraps)+' '+trapval(nil,atraps)+' '); +end; + +procedure dumptraps(const atraps: ptrapinfoty; const acount: integer; + const asegments: pseginfoty; const anpoints: integer; + const caption: string; const noerr: boolean); +var + ar1: array of trapdumpinfoty; + ar2: integerarty; + + function trapval(const atrap: ptrapinfoty): string; + begin + if atrap = nil then begin + result:= 'NIL'; + end + else begin + result:= rstring(inttostr(atrap-atraps),3); + end; + end; //trapval + + procedure getpoints(const seg: pseginfoty; out top,bottom: ppointty); + var + seg1: pseginfoty; + begin + top:= nil; + bottom:= nil; + if seg <> nil then begin + seg1:= seg-1; + if seg1 < asegments then begin + inc(seg1,anpoints); + end; + if sf_reverse in seg^.flags then begin + top:= seg^.h.b; + bottom:= seg1^.h.b; + end + else begin + top:= seg1^.h.b; + bottom:= seg^.h.b; + end; + end; + end; //getpoints + +type + pointposty = (pp_none,pp_left,pp_right,pp_both); + + function pointpos(const p: ppointty; + const left,right: ppointty): pointposty; + begin + result:= pp_none; + if p = left then begin + result:= pp_left; + if p = right then begin + result:= pp_both; + end; + end + else begin + if p = right then begin + result:= pp_right; + end; + end; + end; //pointpos + + function pointpostop(const trap: ptrapinfoty): pointposty; + var + lefttop,leftbottom,righttop,rightbottom: ppointty; + begin + with trap^ do begin + getpoints(left,lefttop,leftbottom); + getpoints(right,righttop,rightbottom); + result:= pointpos(top,lefttop,righttop); + end; + end; + + function pointposbottom(const trap: ptrapinfoty): pointposty; + var + lefttop,leftbottom,righttop,rightbottom: ppointty; + begin + with trap^ do begin + getpoints(left,lefttop,leftbottom); + getpoints(right,righttop,rightbottom); + result:= pointpos(bottom,leftbottom,rightbottom); + end; + end; + +var + error: boolean; + + procedure seterror; + begin + if not noerr then begin + error:= true; + end; + end; + +var + int1: integer; + lt,lb,rt,rb,t,b: integer; + toterror: boolean; + trap1: ptrapinfoty; + +begin + setlength(ar1,acount); + for int1:= 0 to high(ar1) do begin + ar1[int1].t:= atraps+int1; + ar1[int1].index:= int1; + end; + sortarray(ar1,sizeof(trapdumpinfoty),@cmptrap,ar2); + debugwriteln('------------------------------------------------------- '+caption); + debugwriteln(' T t b tl tr bl br A AR B BR'); + toterror:= false; + for int1:= 0 to high(ar1) do begin + trap1:= ar1[int1].t; + with trap1^ do begin + lt:= -10000; + lb:= -10000; + t:= -10000; + rt:= 10000; + rb:= 10000; + b:= 10000; + if top <> nil then begin + t:= top^.y; + end; + if bottom <> nil then begin + b:= bottom^.y; + end; + if left <> nil then begin + lt:= calcx(left,t); + lb:= calcx(left,b); + end; + if right <> nil then begin + rt:= calcx(right,t); + rb:= calcx(right,b); + end; + debugwrite(rstring(inttostr(ar1[int1].index),3)+' '+ + intvaly(t)+' '+intvaly(b)+' '+ + intvalx(lt)+' '+intvalx(rt)+' '+intvalx(lb)+' '+intvalx(rb)+' '+ + trapval(above)+' '+trapval(abover)+' '+ + trapval(below)+' '+trapval(belowr)); + error:= false; + + if above <> nil then begin + case pointpostop(trap1) of + pp_left: begin + case pointposbottom(above) of + pp_left: begin + if (above^.below <> trap1) or (above^.belowr <> nil) then begin + seterror; + end; + end; + pp_none: begin + if (above^.belowr <> trap1) or (above^.below = trap1) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + pp_right: begin + case pointposbottom(above) of + pp_right: begin + if (above^.below <> trap1) or (above^.belowr <> nil) then begin + seterror; + end; + end; + pp_none: begin + if (above^.below <> trap1) or (above^.belowr = trap1) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + pp_none: begin + case pointposbottom(above) of + pp_right: begin + if (abover = nil) or (abover^.below <> trap1) then begin + seterror; + end; + end; + pp_none: begin + if (above^.below <> trap1) or (above^.belowr <> nil) then begin + seterror; + end; + end; + end; + end; + end; + if abover <> nil then begin + case pointpostop(trap1) of + pp_none: begin + if (abover^.below <> trap1) or (abover^.belowr <> nil) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + end + else begin + if abover <> nil then begin + seterror; + end; + end; + + if below <> nil then begin + case pointposbottom(trap1) of + pp_left: begin + case pointpostop(below) of + pp_left: begin + if (below^.above <> trap1) or (below^.abover <> nil) then begin + seterror; + end; + end; + pp_none: begin + if (below^.abover <> trap1) or (below^.above = nil) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + pp_right: begin + case pointpostop(below) of + pp_right: begin + if (below^.above <> trap1) or (below^.abover <> nil) then begin + seterror; + end; + end; + pp_none: begin + if (below^.above <> trap1) or (below^.abover = nil) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + pp_none: begin + case pointpostop(below) of + pp_right,pp_none: begin + if (below^.above <> trap1) or (below^.abover <> nil) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + end; + if belowr <> nil then begin + case pointposbottom(trap1) of + pp_none: begin + case pointpostop(belowr) of + pp_left: begin + if (belowr^.above <> trap1) or (belowr^.abover <> nil) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + else begin + seterror; + end; + end; + end; + end + else begin + if belowr <> nil then begin + seterror; + end; + end; + if error then begin + debugwriteln(' *'); + toterror:= true; + end + else begin + debugwriteln(''); + end; + end; + end; + if toterror then begin + debugwriteln(' ***error***'); + debugdumperror:= true; + end; +end; + +procedure dump(const atraps: ptrapinfoty; const ntraps: integer; + const asegments: pseginfoty; const anpoints: integer; + const anodes: ptrapnodeinfoty; const caption: string; + const noerr: boolean); +begin + debugdumperror:= false; + dumptraps(atraps,ntraps,asegments,anpoints,caption,noerr); + debugwriteln(''); + dumpnodes(anodes,atraps,asegments); +end; +{$endif mse_debugpolytria} + +procedure polytria(var drawinfo: drawinfoty; out atriangles: ptrianglety; + out trianglecount: integer); + +// x,y range = $7fff..-$8000 (16 bit X11 space) +var + points: ppointty; + npoints: integer; + traps: ptrapinfoty; + nodes: ptrapnodeinfoty; + segments: pseginfoty; + shuffle: ppseginfoty; + newtraps: ptrapinfoty; + newnodes: ptrapnodeinfoty; + + function newtrap: ptrapinfoty; + begin + result:= newtraps; + inc(newtraps); + result^.above:= nil; + result^.abover:= nil; + result^.below:= nil; + result^.belowr:= nil; + result^.node:= nil; + end; + + function newnode: ptrapnodeinfoty; + begin + result:= newnodes; + inc(newnodes); + end; + + function isbelow(const l,r: ppointty): boolean; //true if l beow r + var + int1: integer; + begin + int1:= l^.y - r^.y; + if int1 = 0 then begin + result:= l - r >= 0; + end + else begin + result:= int1 >= 0; + end; + end; //isbelow + + function xdist(const point: ppointty; ref: pseginfoty): integer; + var + int1: integer; + begin + if ref^.dy = 0 then begin + result:= point^.y - ref^.h.b^.y; + if result = 0 then begin + if ref = segments then begin + int1:= npoints-1; + end + else begin + int1:= 1; + end; + if not (sf_reverse in ref^.flags) then begin + int1:= -int1; + end; + result:= int1*(point^.x - ref^.h.b^.x) - (point-ref^.h.b)*ref^.dx; + if not (sf_reverse in ref^.flags) then begin + result:= -result; + end; + end + else begin + if not (sf_reverse in ref^.flags) then begin //?????? + result:= -result; + end; + end; + end + else begin + // result:= point^.x -(ref^.h.b^.x + (point^.y-ref^.h.b^.y)*ref^.dx div ref^.dy); + result:= ref^.dy*(point^.x - ref^.h.b^.x) - (point^.y-ref^.h.b^.y)*ref^.dx; + if ref^.dy < 0 then begin + result:= -result; + end; + end; + end; + + function isright(const point: ppointty; ref: pseginfoty): boolean; + //true if point right of segment + begin + // result:= xpos(point,ref) = xp_right; + result:= xdist(point,ref) >= 0; + end; + + function segdirdown(const seg,ref: pseginfoty): segdirty; + var + segcommon: pseginfoty; + ptseg,ptref: ppointty; + begin + if seg = ref then begin + result:= sd_same; + end + else begin + segcommon:= seg^.h.previous; + if segcommon = ref then begin + ptseg:= seg^.h.b; + ptref:= ref^.h.previous^.h.b; + end + else begin + segcommon:= ref^.h.previous; + if segcommon = seg then begin + ptseg:= seg^.h.previous^.h.b; + ptref:= ref^.h.b; + end + else begin + result:= sd_none; + exit; + end; + end; + if isbelow(segcommon^.h.b,ptseg) then begin + result:= sd_up; + end + else begin + result:= sd_left; + if ptseg^.x = ptref^.x then begin + if isbelow(ptseg,ptref) then begin + result:= sd_right; + end; + end + else begin + if seg^.dy = 0 then begin + if ref^.dy = 0 then begin + if ptref^.x-segcommon^.h.b^.x < 0 then begin + if ptseg^.x-segcommon^.h.b^.x > 0 then begin + result:= sd_right; + end + else begin + if isbelow(ptseg,ptref) then begin + result:= sd_right; + end; + end; + end + else begin + if ptseg^.x-segcommon^.h.b^.x > 0 then begin + if isbelow(ptref,ptseg) then begin + result:= sd_right; + end; + end; + end; + end + else begin + if ptseg^.x-segcommon^.h.b^.x >= 0 then begin + result:= sd_right; + end; + end; + end + else begin + if ref^.dy = 0 then begin + if ptref^.x-segcommon^.h.b^.x < 0 then begin + result:= sd_right; + end; + end + else begin + if (seg^.dx*ref^.dy < ref^.dx*seg^.dy) xor + not((sf_reverse in ref^.flags) xor (sf_reverse in seg^.flags)) then begin + // not((ref^.dy < 0) xor (seg^.dy < 0)) then begin + //direction of one segment reversed + result:= sd_right; + end; + end; + end; + end; + end; + end; + end; + + function angdelta(const a,b,c: pointty): integer; + //>0 -> ccw, a.y <= b.y <= c.y + var + dx1,dy1,dx2,dy2: integer; + + procedure calctandiff; + begin + dy1:= b.y - a.y; + dy2:= c.y - b.y; + result:= dx2*dy1 - dx1*dy2; //y is top-down + end; //calctandiff + + begin + result:= 0; + dx1:= b.x - a.x; + dx2:= c.x - b.x; + if dx1 >= 0 then begin + if dx2 < 0 then begin + if c.y-a.y < 0 then begin + result:= 1; + end + else begin + result:= -1; + end; + end + else begin + calctandiff; + end; + end + else begin + if dx2 > 0 then begin + if c.y-a.y < 0 then begin + result:= -1; + end + else begin + result:= 1; + end; + end + else begin + calctandiff; + end; + end; + end; //angdelta + +var + toptrap: ptrapinfoty = nil; + + procedure finddiags; + + function checkdiag(const atrap: ptrapinfoty; const up: boolean): boolean; + //false if error or triangle + var + topseg,bottomseg,lefta,righta: pseginfoty; + begin + result:= true; + with atrap^ do begin + if (atrap = nil) or (left = nil) or (right = nil) or + (top = nil) or (bottom = nil) then begin //segment crossing + result:= false; + exit; + end; + lefta:= left^.h.previous; + righta:= right^.h.previous; + if (left = righta) and (up xor (left^.h.b = bottom)) or + (right = lefta) and (up xor (right^.h.b = bottom)) then begin //triangle + result:= false; + end; + if not((top = left^.h.b) and (bottom = lefta^.h.b) or + (bottom = left^.h.b) and (top = lefta^.h.b) or + (top = right^.h.b) and (bottom = righta^.h.b) or + (bottom = right^.h.b) and (top = righta^.h.b)) then begin + topseg:= segments+(top-points); + bottomseg:= segments+(bottom-points); + with topseg^ do begin + if diags[0] <> nil then begin + if diags[1] <> nil then begin + diags[2]:= bottomseg; + end + else begin + diags[1]:= bottomseg; + end; + end + else begin + diags[0]:= bottomseg; + end; + end; + with bottomseg^ do begin + if diags[0] <> nil then begin + if diags[1] <> nil then begin + diags[2]:= topseg; + end + else begin + diags[1]:= topseg; + end; + end + else begin + diags[0]:= topseg; + end; + end; + end; + end; + end; //checkdiag + + procedure findup(const atrap: ptrapinfoty); forward; + + procedure finddown(const atrap: ptrapinfoty); + var + tr1: ptrapinfoty; + begin + tr1:= atrap; + while checkdiag(tr1,false) do begin + with tr1^ do begin + if belowr <> nil then begin + finddown(belowr); + end; + if below^.above = tr1 then begin + if below^.abover <> nil then begin + findup(below^.abover); + end; + end + else begin + findup(below^.above); + end; + tr1:= below; + end; + end; + end; //finddown + + procedure findup(const atrap: ptrapinfoty); + var + tr1: ptrapinfoty; + begin + tr1:= atrap; + while checkdiag(tr1,true) do begin + with tr1^ do begin + if abover <> nil then begin + findup(abover); + end; + if above^.below = tr1 then begin + if above^.belowr <> nil then begin + finddown(above^.belowr); + end; + end + else begin + finddown(above^.below); + end; + tr1:= above; + end; + end; + end; //findup + + begin + finddown(toptrap); + end; //finddiags + + function newnode(const atrap: ptrapinfoty; + const aparent: ptrapnodeinfoty): ptrapnodeinfoty; + begin + result:= newnodes; + inc(newnodes); + result^.kind:= tnk_trap; + result^.trap:= atrap; + result^.p:= aparent; + atrap^.node:= result; + end; //newnode + + function findtrap(const apoint,second: ppointty): ptrapinfoty; + //second used if apoint is on edge + var + no1,no2: ptrapnodeinfoty; + int1: integer; + begin + {$ifdef mse_debugpolytria} + debugwrite('Search '+inttostr(apoint^.x)+':'+inttostr(apoint^.y)); + {$endif} + no1:= nodes; + while true do begin + no2:= no1^.l; + case no1^.kind of + tnk_trap: begin + result:= no1^.trap; + break; + end; + tnk_y: begin + if isbelow(apoint,no1^.y) then begin + no2:= no1^.r; + end; + end; + tnk_x: begin + int1:= xdist(apoint,no1^.seg); + if int1 = 0 then begin + int1:= xdist(second,no1^.seg); + end; + if int1 > 0 then begin + no2:= no1^.r; + end; + end; + end; + no1:= no2; + end; +{$ifdef mse_debugpolytria} + debugwriteln(' found trap '+inttostr(result-traps)); +{$endif} + end; //findtrap + + procedure handlepoint(const seg: pseginfoty); + var + tplower,tpupper,tpbelow,tpbelowr: ptrapinfoty; + no1,nol,nor: ptrapnodeinfoty; + ppt1: ppointty; + begin + ppt1:= seg^.h.b; + tpupper:= findtrap(ppt1,ppt1); + tplower:= newtrap; //split trap, lower + tplower^.top:= ppt1; + tplower^.bottom:= tpupper^.bottom; + tpupper^.bottom:= ppt1; //upper + tplower^.left:= tpupper^.left; //same segment + tplower^.right:= tpupper^.right; //same segment + tplower^.below:= tpupper^.below; //same below + tplower^.belowr:= tpupper^.belowr;//same belowr + tplower^.above:= tpupper; //abover = nil + tpbelow:= tpupper^.below; + tpbelowr:= tpupper^.belowr; + if tpbelow <> nil then begin + if tpbelow^.above = tpupper then begin + tpbelow^.above:= tplower; + end; + if tpbelow^.abover = tpupper then begin + tpbelow^.abover:= tplower; + end; + if tpbelowr <> nil then begin + if tpbelowr^.above = tpupper then begin + tpbelowr^.above:= tplower; + end; + if tpbelowr^.abover = tpupper then begin + tpbelowr^.abover:= tplower; + end; + end; + end; + tpupper^.below:= tplower; + tpupper^.belowr:= nil; //no split segment + seg^.trap:= tplower; + + no1:= tpupper^.node; //old leaf + nol:= newnode(tpupper,no1); //new leaf + nor:= newnode(tplower,no1); //new leaf + no1^.l:= nol; + no1^.r:= nor; + no1^.kind:= tnk_y; + no1^.y:= ppt1; + + include(seg^.flags,sf_pointhandled); + end; //handlepoint + +var + segcounter: integer; + + procedure handlesegment(const aseg: pseginfoty); + + procedure splitnode(const newright: boolean; const ltrap,rtrap: ptrapinfoty); + var + noabove,noleft,noright: ptrapnodeinfoty; + begin + if newright then begin + noabove:= ltrap^.node; + noleft:= newnode(ltrap,noabove); + noright:= rtrap^.node; + if noright = nil then begin //new trap + noright:= newnode(rtrap,noabove); + end; + end + else begin + noabove:= rtrap^.node; + noright:= newnode(rtrap,noabove); + noleft:= ltrap^.node; + if noleft = nil then begin //new trap + noleft:= newnode(ltrap,noabove); + end; + end; + with noabove^ do begin + l:= noleft; // (Tb) -> (s) + r:= noright; // (Tl) (Tr) + kind:= tnk_x; + seg:= aseg; + end; + end; //splitnode horz + + var + bottompoint: ppointty; + + procedure updatebelow(const newright: boolean; const trold,trnew: ptrapinfoty); + var + aisright: boolean; + seg1: pseginfoty; + begin + if trold^.below = nil then begin + exit; //crossing + end; + + if newright then begin + seg1:= trold^.right; + end + else begin + seg1:= trold^.left; + end; + if trold^.below^.top = bottompoint then begin //last + if trold^.belowr <> nil then begin //existing segment below + if newright then begin + trnew^.below:= trold^.belowr; + trnew^.below^.above:= trnew; + end + else begin + trnew^.below:= trold^.below; + trold^.below^.above:= trnew; + trold^.below:= trold^.belowr; + end; + trold^.belowr:= nil; + trnew^.belowr:= nil; + end + else begin + if trold^.below^.abover <> nil then begin //existing segment above + trnew^.below:= trold^.below; + if (trold^.below^.above = trold) xor newright then begin + //existing trap is not on new side + if newright then begin + trold^.below^.abover:= trnew; + end + else begin + trold^.below^.above:= trnew; + end; + end; + end + else begin //no existing segment + trnew^.below:= trold^.below; + with trold^.below^ do begin + if newright then begin + abover:= trnew; + end + else begin + above:= trnew; + abover:= trold; + end; + end; + end; + end; + end + else begin //not last + aisright:= isright(trold^.below^.top,seg1); + if trold^.belowr = nil then begin //no existing segment below + trnew^.below:= trold^.below; + with trold^.below^ do begin + if abover = nil then begin //single trap above + if newright then begin + abover:= trnew; + end + else begin + abover:= trold; + above:= trnew; + end; + end + else begin + if aisright then begin + if newright then begin + above:= trnew; + end; + end + else begin + if not newright then begin + abover:= trnew; + end; + end; + end; + end; + end + else begin //existing segment below + if aisright then begin + trnew^.below:= trold^.below; + if newright then begin + trnew^.belowr:= trold^.belowr; + trnew^.below^.above:= trnew; + trold^.belowr^.above:= trnew; + trold^.belowr:= nil; + end; + end + else begin + if newright then begin + trnew^.below:= trold^.belowr; + end + else begin + trnew^.below:= trold^.below; + trnew^.below^.above:= trnew; + trnew^.belowr:= trold^.belowr; + trnew^.belowr^.above:= trnew; + trold^.below:= trold^.belowr; + trold^.belowr:= nil; + end; + end; + end; + end; + end; //updatebelow + + procedure splittrap(const newright: boolean; const old: ptrapinfoty; + var left,right,trnew: ptrapinfoty); + var + trabove: ptrapinfoty; + trabover: ptrapinfoty; + begin + trnew:= newtrap; + trabove:= old^.above; + trabover:= old^.abover; + trnew^.top:= old^.top; + trnew^.bottom:= old^.bottom; + trnew^.left:= old^.left; + trnew^.right:= old^.right; + trnew^.above:= trabove; + if newright then begin + old^.right:= aseg; + trnew^.left:= aseg; + right:= trnew; + left:= old; + old^.abover:= nil; + end + else begin + old^.left:= aseg; + trnew^.right:= aseg; + right:= old; + left:= trnew; + if old^.abover <> nil then begin + old^.above:= old^.abover; + old^.abover:= nil; + end; + end; + updatebelow(newright,old,trnew); + left^.above:= trabove; + if trabover = nil then begin //no existing segment above + right^.above:= trabove; + if newright or (trabove^.belowr = nil) then begin //first segment + trabove^.belowr:= right; + end + else begin + if not newright then begin + trabove^.below:= left; + end; + end; + end + else begin + trabove^.below:= left; + right^.above:= trabover; + trabover^.below:= right; + end; + splitnode(newright,left,right); + end; //splittrap + + var + sd1: segdirty; + sega,segb: pseginfoty; + trap1,trap2,trap1l,trap1r,trbelow,trbelowr,exttrap: ptrapinfoty; + isright1{,bo2}: boolean; + + begin + if sf_reverse in aseg^.flags then begin + sega:= aseg; + segb:= aseg^.h.previous; + end + else begin + segb:= aseg; + sega:= aseg^.h.previous; + end; + bottompoint:= segb^.trap^.top; + if sega^.splitseg = nil then begin //no existing edge + isright1:= false; + splittrap(true,sega^.trap,trap1l,trap1r,trap1); + sega^.splitseg:= aseg; + end + else begin + trap1:= sega^.trap; + sd1:= segdirdown(sega^.splitseg,aseg); + case sd1 of + sd_up: begin //existing edge above + if trap1^.below = nil then begin + exit; //error + end; + isright1:= isright(trap1^.below^.top,aseg); + end; + sd_right: begin + if trap1^.above = nil then begin + exit; //error + end; + trap1:= trap1^.above^.below; + isright1:= true; + if (trap1^.above = traps) then begin + toptrap:= trap1; + end; + end; + else begin + if trap1^.above = nil then begin + exit; //error + end; + trap1:= trap1^.above^.belowr; + isright1:= false; + if (trap1^.above = traps) then begin + toptrap:= trap1; + end; + end; + end; + splittrap(not isright1,trap1,trap1l,trap1r,trap1); + end; + {$ifdef mse_debugpolytria} + dump(traps,newtraps-traps,segments,npoints,nodes,'segment0',true); + if not ((segcounter = debugstop) and debugnosegsplit) then begin + {$endif} + + while trap1^.below <> nil do begin + trap2:= trap1^.below; + if trap2^.top = bottompoint then begin + break; + end; + + isright1:= isright(trap2^.top,aseg); //point right of segment + if (trap1^.belowr <> nil) and not isright1 then begin + trap2:= trap1^.belowr; + end; + trbelow:= trap2^.below; + trbelowr:= trap2^.belowr; + + //split crossed lines by segment + if isright1 then begin + exttrap:= trap1l; + trap2^.left:= aseg; //move edge to right + if trap2^.above = exttrap then begin + trap2^.above:= trap2^.abover; + trap2^.abover:= nil; + end; + trap1l^.bottom:= trap2^.bottom; + trap1r:= trap2; + trap1l^.below:= trbelow; + trap1l^.belowr:= trbelowr; + end + else begin + exttrap:= trap1r; + trap2^.right:= aseg; //move edge to left + if trap2^.abover = exttrap then begin + trap2^.abover:= nil; + end; + trap1l:= trap2; + if trbelowr <> nil then begin + trap1r^.below:= trbelowr; + end + else begin + trap1r^.below:= trbelow; + end; + trap1r^.belowr:= nil; + end; + exttrap^.bottom:= trap2^.bottom; + updatebelow(not isright1,trap2,exttrap); + splitnode(not isright1,trap1l,trap1r); + trap1:= trap2; + end; +{$ifdef mse_debugpolytria} + end; +{$endif} + segb^.splitseg:= aseg; + {$ifdef mse_debugpolytria} + dump(traps,newtraps-traps,segments,npoints,nodes,'segment1',false); + {$endif} + end; + +var + int1,int2: integer; + seg1,seg2: pseginfoty; + sizetraps,sizenodes: integer; + ppt1,ppt2: ppointty; + bo1: boolean; + newmountain: pmountainpointty; + triangles,newtriangle: ptrianglety; + + procedure findmountains(const aseg: pseginfoty; const first: boolean); + var + seg1,seg2: pseginfoty; + int1: integer; + start: pmountainpointty; + rightside,bottomup: boolean; + pttop,ptbottom,pt1,pt2: pmountainpointty; + dy,dx: integer; + searchcount: integer; + begin + start:= newmountain; + seg1:= aseg; + repeat + with seg1^ do begin + newmountain^.prev:= newmountain-1; + newmountain^.next:= newmountain+1; + newmountain^.p:= h.b; + inc(newmountain); + seg2:= nil; + int1:= 0; + if diags[0] <> nil then begin + seg2:= diags[0]; + end; + if (seg2 <> aseg) and ((diags[1] > seg2) or (diags[1] = aseg)) then begin + seg2:= diags[1]; + int1:= 1; + end; + if (seg2 <> aseg) and ((diags[2] > seg2) or (diags[2] = aseg)) then begin + seg2:= diags[2]; + int1:= 2; + end; + if seg2 <> nil then begin + diags[int1]:= nil; //eat + if seg2 <> aseg then begin //new mountain + {$ifdef mse_debugpolytria1} + setlength(debugdiags,high(debugdiags)+2); + with debugdiags[high(debugdiags)] do begin + a:= seg1^.h.b^;; + b:= seg2^.h.b^; + end; + {$endif} + findmountains(seg1,false); + end; + seg1:= seg2; + end + else begin + seg1:= seg1^.h.next; + end; + end; + until seg1 = aseg; + + {$ifdef mse_debugpolytria1} + setlength(debugmountains,high(debugmountains)+2); + with debugmountains[high(debugmountains)] do begin + setlength(chain,newmountain-start); + for int1:= 0 to high(chain) do begin + chain[int1]:= start[int1].p^; + end; + end; + {$endif} + + dec(newmountain); //last + start^.prev:= nil; + newmountain^.next:= nil; + ptbottom:= start; + pttop:= start; + pt1:= start; + repeat + if isbelow(pt1^.p,ptbottom^.p) then begin + ptbottom:= pt1; + end; + if isbelow(pttop^.p,pt1^.p) then begin + pttop:= pt1; + end; + pt1:= pt1^.next; + until pt1 = nil; + start^.prev:= newmountain; + newmountain^.next:= start; + if ptbottom^.next = pttop then begin + ptbottom^.next:= nil; + pttop^.prev:= nil; + end + else begin + pttop^.next:= nil; + ptbottom^.prev:= nil; + end; + if pttop^.p^.y <> ptbottom^.p^.y then begin //not empty + bottomup:= ptbottom^.prev = nil; + if bottomup then begin + pt1:= ptbottom^.next; + end + else begin + pt1:= pttop^.next; + end; + pt2:= pt1; + int1:= 0; + dx:= pttop^.p^.x - ptbottom^.p^.x; + dy:= pttop^.p^.y - ptbottom^.p^.y; //always negative + repeat + int1:= dy*(pt1^.p^.x - pttop^.p^.x) - (pt1^.p^.y-pttop^.p^.y)*dx; + pt1:= pt1^.next; + until (int1 <> 0) or (pt1 = nil); + if int1 <> 0 then begin //not empty + rightside:= int1 < 0; + pt1:= pt2; + bo1:= false; + searchcount:= 0; + while searchcount < 4 do begin //else error + int1:= angdelta(pt1^.prev^.p^,pt1^.p^,pt1^.next^.p^); + if int1 <> 0 then begin //not empty + if (int1 > 0) xor rightside xor bottomup then begin //cut ear + searchcount:= 0; + newtriangle^[0]:= pt1^.prev^.p^; + newtriangle^[1]:= pt1^.p^; + newtriangle^[2]:= pt1^.next^.p^; + inc(newtriangle); + end + else begin //no ear, try next + if bo1 then begin + pt1:= pt1^.prev; + if pt1^.prev = nil then begin + inc(searchcount); + pt1:= pt1^.next; + bo1:= false; + end; + end + else begin + pt1:= pt1^.next; + if pt1^.next = nil then begin + inc(searchcount); + pt1:= pt1^.prev; + bo1:= true; + end; + end; + continue; + end; + end; + pt1^.prev^.next:= pt1^.next; + pt1^.next^.prev:= pt1^.prev; + pt1:= pt1^.prev; + if pt1^.prev = nil then begin + pt1:= pt1^.next; + if pt1^.next = nil then begin + break; + end; + end; + end; + end; + end; + newmountain:= start; //restore + end; //findmountains + +var + noisestate: mwcinfoty; + pt1,pt2: ppointty; +begin + noisestate.fw:= defaultmwcseedw; //"random" seed + noisestate.fz:= defaultmwcseedz; //"random" seed + npoints:= drawinfo.points.count; + if npoints < 3 then begin + atriangles:= nil; + trianglecount:= 0; + exit; + end; + + points:= drawinfo.points.points; + + sizetraps:= npoints*trapsize; + sizenodes:= npoints*trapnodesize; + allocbuffer(drawinfo.buffer,npoints*(sizeof(pointty)+sizeof(seginfoty)+ + sizeof(pseginfoty)) + sizetraps + sizenodes); + with drawinfo,drawinfo.points do begin + int1:= count; + pt1:= points; + pt2:= buffer.buffer; + with origin do begin + repeat + pt2^.x:= pt1^.x + x; + pt2^.y:= pt1^.y + y; + inc(pt1); + inc(pt2); + dec(int1); + until int1 = 0; + end; + end; + points:= drawinfo.buffer.buffer; + segments:= pointer(points+npoints); + shuffle:= pointer(segments+npoints); + traps:= pointer(shuffle+npoints); + nodes:= pointer(traps)+sizetraps; + ppt1:= points; //b + ppt2:= points+npoints-1; //a + seg1:= segments; + for int1:= npoints-1 downto 0 do begin //init segments + shuffle[int1]:= seg1; + with seg1^ do begin + h.previous:= seg1-1; + h.next:= seg1+1; + splitseg:= nil; + trap:= nil; + flags:= []; + diags[0]:= nil; + diags[1]:= nil; + diags[2]:= nil; + + h.b:= ppt1; + dx:= ppt2^.x-ppt1^.x; //b->a slope + dy:= ppt2^.y-ppt1^.y; //b->a slope + if dy = 0 then begin + if ppt2 > ppt1 then begin + include(flags,sf_reverse); + end; + end + else begin + if dy > 0 then begin + include(flags,sf_reverse); + end; + end; + ppt2:= ppt1; + inc(ppt1); + end; + inc(seg1); + end; + segments^.h.previous:= segments + npoints - 1; + (segments+npoints-1)^.h.next:= segments; + for int1:= npoints-1 downto 0 do begin //shuffle segments + int2:= mwcnoise(noisestate) mod npoints; + seg1:= shuffle[int2]; + shuffle[int2]:= shuffle[int1]; + shuffle[int1]:= seg1; + end; + + newtraps:= traps; //init memory sources + newnodes:= nodes; + + with newnode^ do begin //init root node + kind:= tnk_trap; + trap:= traps; + end; + + with newtrap^ do begin //init trap plane + node:= nodes; + left:= nil; + right:= nil; + top:= nil; + bottom:= nil; + end; + + for segcounter:= npoints-1 downto 0 do begin + seg1:= shuffle[segcounter]; + seg2:= seg1^.h.previous; + {$ifdef mse_debugpolytria} + debugwriteln('************************************** ('+ + inttostr(segcounter)+')'); + dumpseg(seg1,segments,npoints,traps); + {$endif} + + {$ifdef mse_debugpolytria} + if not((segcounter = debugstop) and debugnoa) then begin + {$endif} + + if not (sf_pointhandled in seg2^.flags) then begin + handlepoint(seg2); + {$ifdef mse_debugpolytria} + dump(traps,newtraps-traps,segments,npoints,nodes,'point A',false); + {$endif} + end; + + {$ifdef mse_debugpolytria} + end; + {$endif} + + {$ifdef mse_debugpolytria} + if not((segcounter = debugstop) and debugnoa) then begin + {$endif} + + if not (sf_pointhandled in seg1^.flags) then begin + handlepoint(seg1); + {$ifdef mse_debugpolytria} + dump(traps,newtraps-traps,segments,npoints,nodes,'point B',false); + {$endif} + end; + + {$ifdef mse_debugpolytria} + end; + debugwriteln('----------------'); + dumpseg(seg1,segments,npoints,traps); + if (segcounter = debugstop) and + (debugnoseg or debugnoa or debugnob) then begin + break; + end; + {$endif} + + handlesegment(seg1); + {$ifdef mse_debugpolytria} + debugwriteln('----------------'); + dumpseg(seg1,segments,npoints,traps); + {$endif} + end; +{$ifdef mse_debugpolytria} + debugwriteln('toptrap: '+trapval(toptrap,traps)+' points: '+inttostr(npoints)+ + ' traps: '+inttostr(newtraps-traps)+' nodes: '+inttostr(newnodes-nodes)+ + ' '+formatfloatmse((newnodes-nodes)/npoints,'0.00')); + if debugdumperror then begin + debugwriteln('****error**** '+ + '****error****'); + end + else begin + debugwriteln('OK '+ + ' OK'); + end; +{$endif} +{$ifdef mse_debugpolytria1} + setlength(debugtraps,newtraps-traps); + int2:= 0; + for int1:= 0 to high(debugtraps) do begin + with traps[int1] do begin + if top = nil then begin + debugtraps[int1][0].y:= 0; + debugtraps[int1][1].y:= 0; + end + else begin + debugtraps[int1][0].y:= top^.y; + debugtraps[int1][1].y:= top^.y; + end; + if bottom = nil then begin + debugtraps[int1][2].y:= maxint; + debugtraps[int1][3].y:= maxint; + end + else begin + debugtraps[int1][2].y:= bottom^.y; + debugtraps[int1][3].y:= bottom^.y; + end; + if left = nil then begin + debugtraps[int1][0].x:= 0; + debugtraps[int1][3].x:= 0; + end + else begin + if top = nil then begin + debugtraps[int1][0].x:= 0; + end + else begin + debugtraps[int1][0].x:= calcx(top^.y,left^); + end; + if bottom = nil then begin + debugtraps[int1][3].x:= maxint; + end + else begin + debugtraps[int1][3].x:= calcx(bottom^.y,left^); + end; + end; + if right = nil then begin + debugtraps[int1][1].x:= maxint; + debugtraps[int1][2].x:= maxint; + end + else begin + if top = nil then begin + debugtraps[int1][1].x:= maxint; + end + else begin + debugtraps[int1][1].x:= calcx(top^.y,right^); + end; + if bottom = nil then begin + debugtraps[int1][2].x:= 0; + end + else begin + debugtraps[int1][2].x:= calcx(bottom^.y,right^); + end; + end; + end; + end; +{$endif} + + finddiags; + newmountain:= pointer(traps); //traps not used anymore + triangles:= pointer(newmountain)+npoints*mountainsize; + newtriangle:= triangles; +{$ifdef mse_debugpolytria1} + debugmountains:= nil; + debugdiags:= nil; +{$endif} + findmountains(segments,true); +{$ifdef mse_debugpolytria1} + setlength(debugtriangles,newtriangle-triangles); + for int1:= 0 to high(debugtriangles) do begin + with debugtriangles[int1] do begin + p[0].x:= triangles[int1][0].x; + p[0].y:= triangles[int1][0].y; + p[1].x:= triangles[int1][1].x; + p[1].y:= triangles[int1][1].y; + p[2].x:= triangles[int1][2].x; + p[2].y:= triangles[int1][2].y; + end; + end; +{$endif} + atriangles:= triangles; + trianglecount:= (newtriangle-triangles); +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msetriaglob.pas b/mseide-msegui/lib/common/graphics/msetriaglob.pas new file mode 100644 index 0000000..4ec9e4c --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msetriaglob.pas @@ -0,0 +1,51 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msetriaglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphutils,msegraphics; +type + trianglety = array[0..2] of pointty; + ptrianglety = ^trianglety; + + triaflagty = (trf_capbutt,trf_capround,trf_capprojecting, + trf_joinmiter,trf_joinround,trf_joinbevel); + triaflagsty = set of triaflagty; + +const + triacapflags: array[capstylety] of triaflagsty = ( + [trf_capbutt],[trf_capround],[trf_capprojecting]); + triajoinflags: array[joinstylety] of triaflagsty = ( + [trf_joinmiter],[trf_joinround],[trf_joinbevel]); + triacapmask = [trf_capbutt,trf_capround,trf_capprojecting]; + triajoinmask = [trf_joinmiter,trf_joinround,trf_joinbevel]; + +type + triainfoty = record + linewidth: integer; + linewidth1: integer; + linewidth16: integer; +// xftlinewidthsquare: integer; + xftdashes: dashesstringty; + triaflags: triaflagsty; +// capstyle: capstylety; +// joinstyle: joinstylety; +// zerowidth: boolean; + end; + + triagcty = record + case integer of + 0: (d: triainfoty;); + 1: (_bufferspace: gcpty;); + end; + +implementation +end. diff --git a/mseide-msegui/lib/common/graphics/msex11gdi.pas b/mseide-msegui/lib/common/graphics/msex11gdi.pas new file mode 100644 index 0000000..b32f9f0 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msex11gdi.pas @@ -0,0 +1,3335 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msex11gdi; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +uses + {$ifdef FPC}xlib{$else}Xlib{$endif},mxft, + {$ifdef FPC}x,xutil,dynlibs,{$endif} + msegraphics,mseguiglob,msestrings,msegraphutils,mseguiintf,msetypes, + msectypes,mxrender,msefontconfig,msetriaglob; + +procedure init(const adisp: pdisplay; const avisual: msepvisual; + const adepth: integer); +function hasxft: boolean; +function fontdatatoxftpat(const fontdata: fontdataty; + const highres: boolean): pfcpattern; +procedure getxftfontdata(po: pxftfont; var drawinfo: drawinfoty); + +function x11getgdifuncs: pgdifunctionaty; +//function x11getgdinum: integer; + +//function x11creategc(paintdevice: paintdevicety; const akind: gckindty; +// var gc: gcty; const aprintername: msestring): guierrorty; +function x11regiontorects(const aregion: regionty): rectarty; +function x11getdefaultfontnames: defaultfontnamesty; + +type + createcolorpicfuncty = function(const acolor: txrendercolor): tpicture; +var + createcolorpic: createcolorpicfuncty; +// pictformats: array[bitmapkindty] of pxrenderpictformat; + screenrenderpictformat,bitmaprenderpictformat, + alpharenderpictformat, + rgbrenderpictformat,argbrenderpictformat: pxrenderpictformat; + +function createalphapicture(const size: sizety; + const arepeat: boolean = false): tpicture; +function creatergbpicture(const size: sizety; + const arepeat: boolean = false; + const alphamap: tpicture = 0): tpicture; +function createargbpicture(const size: sizety; + const arepeat: boolean = false): tpicture; + +{$ifdef FPC} + {$macro on} + {$define xchar2b:=txchar2b} + {$define xcharstruct:=txcharstruct} + {$define xfontstruct:=txfontstruct} + {$define xfontprop:=txfontprop} + {$define xpoint:=txpoint} + {$define xgcvalues:=txgcvalues} + {$define region:=tregion} + {$define ximage:=tximage} + {$define xwindowattributes:=txwindowattributes} + {$define xclientmessageevent:=txclientmessageevent} + {$define xtype:=_type} + {$define xrectangle:=txrectangle} + {$define keysym:=tkeysym} + {$define xsetwindowattributes:=txsetwindowattributes} + {$define xwindowchanges:=txwindowchanges} + {$define xevent:=txevent} + {$define xfunction:=_function} + {$define xwindow:=window} + {$define xlookupkeysym_:=xlookupkeysymval} + {$define c_class:= _class} + {$define xtextproperty:= txtextproperty} +{$endif} +type + + //from region.h + box = record + x1,x2,y1,y2: smallint + end; + pbox = ^box; + XRegion = record + size: clong; + numRects: clong; + rects: pbox; + extents: box; + end; + pxregion = ^xregion; + + fontmatrixmodety = (fmm_fix,fmm_linear,fmm_matrix); + x11fontdatadty = record + infopo: pxfontstruct; + matrixmode: fontmatrixmodety; + defaultwidth: integer; + xftascent,xftdescent: integer; + rowlength: word; + xftdirection: graphicdirectionty; + end; + px11fontdatadty = ^x11fontdatadty; + x11fontdataty = record + case integer of + 0: (d: x11fontdatadty;); + 1: (_bufferspace: fontdatapty;); + end; + + +{$ifndef staticxft} +var //xft functions + XftDrawDestroy: procedure(draw:PXftDraw); cdecl; + XftDrawSetClipRectangles: function (draw:PXftDraw; xOrigin:longint; + yOrigin:longint; rects:PXRectangle; n:longint):TFcBool; cdecl; + XftDrawCreate: function(dpy:PDisplay; drawable:TDrawable; visual:PVisual; + colormap:TColormap): PXftDraw; cdecl; + XftDrawSetClip: function(draw:PXftDraw; r:TRegion):TFcBool; cdecl; + XftTextExtents16: procedure(dpy:PDisplay; pub:PXftFont; + _string: pwidechar{PFcChar16}; len:longint; extents:PXGlyphInfo); cdecl; + XftTextExtentsUtf16: procedure (dpy: pDisplay; pub: pXftFont; + _string: pFcChar8; endian: tFcEndian; + len: cint; extents: pXGlyphInfo); cdecl; + XftTextExtents32: procedure(dpy: pDisplay; pub: pXftFont; _string: pFcChar32; + len: cint; extents: pXGlyphInfo); cdecl; + XftFontOpenName: function(dpy:PDisplay; screen:longint;name:Pchar):PXftFont; + cdecl; + XftFontClose: procedure(dpy:PDisplay; pub:PXftFont); cdecl; + XftDrawString16: procedure(draw:PXftDraw; color:PXftColor; pub:PXftFont; + x:longint; y:longint; _string:pwidechar; len:longint); cdecl; + XftDrawStringUtf16: procedure(draw: pXftDraw; color: pXftColor; pub: pXftFont; + x: cint; y: cint; _string: pFcChar8; endian: tFcEndian; len: cint); + cdecl; + XftDefaultHasRender: function(dpy:PDisplay):TFcBool; cdecl; + XftGetVersion: function():longint; cdecl; + XftInit: function(config:Pchar):TFcBool; cdecl; + XftInitFtLibrary: function ():TFcBool; cdecl; + + XftCharExists: function(dpy:PDisplay; pub:PXftFont; ucs4:TFcChar32):TFcBool; + cdecl; + XftNameParse: function(name:Pchar): PFcPattern;cdecl; + XftFontMatch: function(dpy:PDisplay; screen:longint; pattern:PFcPattern; + result:PFcResult): PFcPattern;cdecl; + XftFontOpenPattern: function(dpy:PDisplay; pattern:PFcPattern):PXftFont;cdecl; + XftDefaultSubstitute: procedure(dpy:PDisplay; screen:longint; + pattern:PFcPattern);cdecl; + XftDrawPicture: function(draw: PXftDraw): tpicture; cdecl; + XftDrawSrcPicture: function(draw: pXftDraw; color: pXftColor): tpicture; cdecl; +{$endif} + +var + XRenderSetPictureClipRectangles: procedure(dpy:PDisplay; picture:TPicture; + xOrigin:longint; yOrigin:longint; rects:PXRectangle; n:longint); + cdecl; + XRenderSetPictureClipRegion: procedure(dpy: pDisplay; picture: TPicture; + r: regionty); cdecl; + XRenderCreatePicture: function(dpy:PDisplay; drawable:TDrawable; + format: PXRenderPictFormat; valuemask: culong; + attributes: PXRenderPictureAttributes): TPicture; cdecl; + XRenderFillRectangle: procedure(dpy: PDisplay; op: longint; dst: TPicture; + color: PXRenderColor; x: longint; + y: longint; width: dword; height: dword);cdecl; + XRenderSetPictureTransform: procedure(dpy:PDisplay; picture:TPicture; + transform:PXTransform); + cdecl; + XRenderSetPictureFilter: procedure(dpy:PDisplay; picture:TPicture; + filter: pchar; params: pinteger; nparams: integer); + cdecl; + XRenderCreateSolidFill: function(dpy: pDisplay; + color: pXRenderColor): TPicture; cdecl; + + XRenderFreePicture: procedure(dpy:PDisplay; picture:TPicture); + cdecl; + XRenderComposite: procedure(dpy:PDisplay; op:longint; src:TPicture; + mask:TPicture; dst:TPicture; + src_x:longint; src_y:longint; mask_x:longint; mask_y:longint; + dst_x:longint; + dst_y:longint; width:dword; height:dword);cdecl; + XRenderQueryExtension: function(dpy: PDisplay; event_basep: Pinteger; + error_basep: Pinteger): TBool;cdecl; + XRenderFindVisualFormat: function(dpy: PDisplay; + visual: PVisual): PXRenderPictFormat;cdecl; + XRenderFindStandardFormat: function(dpy: PDisplay; + format: longint): PXRenderPictFormat; cdecl; + XRenderFindFormat: function(dpy: PDisplay; mask: culong; + templ: PXRenderPictFormat; count: longint): PXRenderPictFormat; cdecl; + + XRenderCompositeTriangles: procedure(dpy: pDisplay; op: cint; src: tPicture; + dst: tPicture; maskFormat: pXRenderPictFormat; + xSrc: cint; ySrc: cint; triangles: pXTriangle; + ntriangle: cint); cdecl; + XRenderCompositeTriStrip: procedure(dpy: pdisplay; op: cint; src: tpicture; + dst: tpicture; maskFormat: PXRenderPictFormat; + xSrc: cint; ySrc: cint; points: PXPointFixed; + npoint: cint); cdecl; + XRenderCompositeTriFan: procedure(dpy: pdisplay; op: cint; src: tpicture; + dst: tpicture; maskFormat: PXRenderPictFormat; + xSrc: cint; ySrc: cint; points: PXPointFixed; + npoint: cint); cdecl; + XRenderChangePicture: procedure(dpy: pdisplay; picture: tpicture; + valuemask: culong; attributes: PXRenderPictureAttributes); cdecl; + +implementation +uses + msesys,msesonames,sysutils,msefcfontselect,msedynload, + msepolytria,mselinetria,mseellipsetria; + +// +//todo: optimise tesselation +// + +(* +//function fontdatatoxftname(const fontdata: fontdataty): string; +*) +type + tsimplebitmap1 = class(tsimplebitmap); + tcanvas1 = class(tcanvas); + +const +// xrenderlineshiftx = 65536 div 2; +// xrenderlineshifty = 65536 div 2; +// xrenderfillshiftx = 0; +// xrenderfillshifty = 0; + xrenderop = pictopover; + xrendercolorsourcesize = 1; + xrendernullcolor: txrendercolor = (red: 0; green: 0; blue: 0; alpha: 0); + + capstyles: array[capstylety] of integer = (capbutt,capround,capprojecting); + joinstyles: array[joinstylety] of integer = (joinmiter,joinround,joinbevel); + defaultfontnames: defaultfontnamesty = + //stf_default stf_empty stf_unicode stf_menu stf_message stf_hint stf_report + ('Helvetica', '', '', '', '', '', 'Arial', + //stf_proportional stf_fixed, + 'Helvetica', 'Courier', + //stf_helvetica stf_roman stf_courier + 'Arial', 'Times New Roman', 'Courier New'); + + xftdefaultfontnames: defaultfontnamesty = + //stf_default stf_empty stf_unicode stf_menu stf_message stf_hint stf_report + ('sans', '', '', '', '', '', 'Arial', + //stf_proportional stf_fixed, + 'sans', 'monospace', + //stf_helvetica stf_roman stf_courier + 'Arial', 'serif', 'Courier New'); +const + wholecircle = 360*64; + +type + fontpropertiesty = ( + FOUNDRY,FAMILY_NAME,WEIGHT_NAME,SLANT,SETWIDTH_NAME,ADD_STYLE_NAME, + PIXEL_SIZE,POINT_SIZE,RESOLUTION_X,RESOLUTION_Y,SPACING,AVERAGE_WIDTH, + CHARSET_REGISTRY,CHARSET_ENCODING,{QUAD_WIDTH,RESOLUTION,}MIN_SPACE, + NORM_SPACE,MAX_SPACE,END_SPACE,SUPERSCRIPT_X,SUPERSCRIPT_Y,SUBSCRIPT_X, + SUBSCRIPT_Y,UNDERLINE_POSITION,UNDERLINE_THICKNESS,STRIKEOUT_ASCENT, + STRIKEOUT_DESCENT,ITALIC_ANGLE,X_HEIGHT,WEIGHT,FACE_NAME,{FULL_NAME,} + FONT,COPYRIGHT,AVG_CAPITAL_WIDTH,AVG_LOWERCASE_WIDTH,RELATIVE_SETWIDTH, + RELATIVE_WEIGHT,CAP_HEIGHT,SUPERSCRIPT_SIZE,FIGURE_WIDTH,SUBSCRIPT_SIZE, + SMALL_CAP_SIZE,NOTICE,DESTINATION,FONT_TYPE,FONT_VERSION,RASTERIZER_NAME, + RASTERIZER_VERSION,RAW_ASCENT,RAW_DESCENT,AXIS_NAMES,AXIS_LIMITS, + AXIS_TYPES,fpnone); + + fontpropty = record + name: string; isstring: boolean; + end; + + intfontproparty = array[fontpropertiesty] of ptrint; + strfontproparty = array[fontpropertiesty] of string; + + const + fontpropertynames: array[fontpropertiesty] of fontpropty = ( + (name: 'FOUNDRY'; isstring: true), + (name: 'FAMILY_NAME'; isstring: true), + (name: 'WEIGHT_NAME'; isstring: true), + (name: 'SLANT'; isstring: true), + (name: 'SETWIDTH_NAME'; isstring: true), + (name: 'ADD_STYLE_NAME'; isstring: true), + (name: 'PIXEL_SIZE'; isstring: false), + (name: 'POINT_SIZE'; isstring: false), + (name: 'RESOLUTION_X'; isstring: false), + (name: 'RESOLUTION_Y'; isstring: false), + (name: 'SPACING'; isstring: true), + (name: 'AVERAGE_WIDTH'; isstring: false), + (name: 'CHARSET_REGISTRY'; isstring: true), + (name: 'CHARSET_ENCODING'; isstring: true), + {'QUAD_WIDTH','RESOLUTION',} + (name: 'MIN_SPACE'; isstring: false), + (name: 'NORM_SPACE'; isstring: false), + (name: 'MAX_SPACE'; isstring: false), + (name: 'END_SPACE'; isstring: false), + (name: 'SUPERSCRIPT_X'; isstring: false), + (name: 'SUPERSCRIPT_Y'; isstring: false), + (name: 'SUBSCRIPT_X'; isstring: false), + (name: 'SUBSCRIPT_Y'; isstring: false), + (name: 'UNDERLINE_POSITION'; isstring: false), + (name: 'UNDERLINE_THICKNESS'; isstring: false), + (name: 'STRIKEOUT_ASCENT'; isstring: false), + (name: 'STRIKEOUT_DESCENT'; isstring: false), + (name: 'ITALIC_ANGLE'; isstring: false), + (name: 'X_HEIGHT'; isstring: false), + (name: 'WEIGHT'; isstring: false), + (name: 'FACE_NAME'; isstring: true), + {'FULL_NAME',} + (name: 'FONT'; isstring: true), + (name: 'COPYRIGHT'; isstring: true), + (name: 'AVG_CAPITAL_WIDTH'; isstring: false), + (name: 'AVG_LOWERCASE_WIDTH'; isstring: false), + (name: 'RELATIVE_SETWIDTH'; isstring: false), + (name: 'RELATIVE_WEIGHT'; isstring: false), + (name: 'CAP_HEIGHT'; isstring: false), + (name: 'SUPERSCRIPT_SIZE'; isstring: false), + (name: 'FIGURE_WIDTH'; isstring: false), + (name: 'SUBSCRIPT_SIZE'; isstring: false), + (name: 'SMALL_CAP_SIZE'; isstring: false), + (name: 'NOTICE'; isstring: true), + (name: 'DESTINATION'; isstring: false), + (name: 'FONT_TYPE'; isstring: true), + (name: 'FONT_VERSION'; isstring: true), + (name: 'RASTERIZER_NAME'; isstring: true), + (name: 'RASTERIZER_VERSION'; isstring: true), + (name: 'RAW_ASCENT'; isstring: false), + (name: 'RAW_DESCENT'; isstring: false), + (name: 'AXIS_NAMES'; isstring: true), + (name: 'AXIS_LIMITS'; isstring: true), + (name: 'AXIS_TYPES'; isstring: true), + (name: ''; isstring: false) + ); + +var + appdisp: pdisplay; + defvisual: msepvisual; + defdepth: integer; + hasxrender: boolean; + fhasxft: boolean; +type + xftcolorcacheinfoty = record + picture: tpicture; + pixel: pixelty; + end; + +const + xftcolorcachemask = $1f; +type + xftstatety = (xfts_clipregionvalid,xfts_smooth,xfts_foregroundvalid, + xfts_monobrush,xfts_hasdashes); + xftstatesty = set of xftstatety; + x11gcdty = record + triainfo: triainfoty; //first! + gcdrawingflags: drawingflagsty; + gcrasterop: rasteropty; + gcclipregion: regionty; + gclinewidth_: int32; + gccapstyle_: int32; +// gchasdashes: boolean; + xftdraw: pxftdraw; + xftdrawpic: tpicture; + xftcolor: txftcolor; + xftcolorbackground: txftcolor; + xftfont: pxftfont; + xftfontdata: px11fontdatadty; + xftstate: xftstatesty; + xftforegroundpic: tpicture; +// xftcolorforegroundpicx: xftcolorcacheinfoty; +// xftcolorbackgroundpicx: xftcolorcacheinfoty; + xftbrush: pixmapty; + xftbrushorigin: pointty; + xftbrushsize: sizety; + xftbrushpic: tpicture; + xftbrushalphapic: tpicture; + end; + {$if sizeof(x11gcdty) > sizeof(gcpty)} {$error 'buffer overflow'}{$ifend} + x11gcty = record + case integer of + 0: (d: x11gcdty;); + 1: (_bufferspace: gcpty;); + end; + +var +// xftcolorcache: array[0..xftcolorcachemask] of xftcolorcacheinfoty; + fontpropertyatoms: array[fontpropertiesty] of atom; + +procedure init(const adisp: pdisplay; const avisual: msepvisual; + const adepth: integer); +var + int1,int2: integer; + fontpropnames: strfontproparty; + propnum: fontpropertiesty; +begin + appdisp:= adisp; + defvisual:= avisual; + defdepth:= adepth; + + hasxrender:= hasxrender and + (xrenderqueryextension(appdisp,@int1,@int2) <> 0); + if hasxrender then begin +// pictformats[bmk_mono]:= xrenderfindstandardformat(appdisp,pictstandarda1); +// pictformats[bmk_gray]:= xrenderfindstandardformat(appdisp,pictstandarda8); +// pictformats[bmk_rgb]:= xrenderfindvisualformat(appdisp,pvisual(defvisual)); + screenrenderpictformat:= xrenderfindvisualformat(appdisp,pvisual(defvisual)); + bitmaprenderpictformat:= xrenderfindstandardformat(appdisp,pictstandarda1); + alpharenderpictformat:= xrenderfindstandardformat(appdisp,pictstandarda8); + rgbrenderpictformat:= xrenderfindstandardformat(appdisp,pictstandardrgb24); + argbrenderpictformat:= xrenderfindstandardformat(appdisp,pictstandardargb32); + end; + if not noxft then begin + fhasxft:= fhasxft and xftdefaulthasrender(appdisp) and (xftgetversion() >= 20000); + if fhasxft then begin + fhasxft:= xftinit(nil); + if fhasxft then begin + fhasxft:= xftinitftlibrary(); + if fhasxft and not hasdefaultfontarg then begin + defaultfontinfo[fn_family_name]:= 'sans'; + end; + end; + end; + end + else begin + fhasxft:= false; + end; + for propnum:= low(fontpropertiesty) to high(fontpropertiesty) do begin + fontpropnames[propnum]:= fontpropertynames[propnum].name; + end; + + xinternatoms(appdisp,@fontpropnames[low(fontpropertiesty)], + integer(high(fontpropertiesty)),{$ifdef xboolean}true{$else}1{$endif}, + @fontpropertyatoms[low(fontpropertiesty)]); + +end; + +function fontinfotoxlfdname(const info: fontinfoty): string; +var + en1: fontnamety; +begin + result:= ''; + for en1:= low(fontnamety) to high(fontnamety) do begin + result:= result + '-' + info[en1]; + end; +end; + +procedure getxftfontdata(po: pxftfont; var drawinfo: drawinfoty); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if po <> nil then begin + {$ifdef FPC} {$checkpointer off} {$endif} + with drawinfo.getfont.fontdata^,x11fontdataty(platformdata) do begin + font:= ptruint(po); + ascent:= po^.ascent; + descent:= po^.descent; + // linespacing:= ascent + descent; + linespacing:= po^.height; +// realheight:= po^.height; + caretshift:= 0; + d.infopo:= nil; + d.xftascent:= po^.ascent; + d.xftdescent:= po^.descent; + d.xftdirection:= gd_right; + end; + {$ifdef FPC} {$checkpointer default} {$endif} + end; +end; + +(* +function buildxftname(const fontdata: fontdataty; + const fontinfo: fontinfoty): ansistring; +var + str1: ansistring; + int1: integer; +begin + with fontdata do begin + str1:= ''; + if fontinfo[fn_foundry] <> '*' then begin + str1:= str1+':foundry='+fontinfo[fn_foundry]; + end; + if (familyoptions = []) then begin + if (pitchoptions = []) and (fontinfo[fn_family_name] <> '*') then begin + str1:= str1 + ':family=' + fontinfo[fn_family_name]; + end; + end + else begin + if foo_helvetica in familyoptions then begin + str1:= str1 + ':family=sans'; + end + else begin + if foo_roman in familyoptions then begin + str1:= str1 + ':family=serif'; + end + else begin + if foo_decorative in familyoptions then begin + end + else begin + if foo_script in familyoptions then begin + end; + end; + end; + end; + end; + if fs_bold in style then begin + str1:= str1 + ':bold'; + end; + if fs_italic in style then begin + str1:= str1 + ':italic'; + end; + if fontinfo[fn_pixel_size] <> '*' then begin + str1:= str1 + ':pixelsize=' + fontinfo[fn_pixel_size]; + end; + if fontinfo[fn_average_width] <> '*' then begin + try + int1:= (strtoint(fontinfo[fn_average_width]) + 5) div 10; + str1:= str1 + ':charwidth='+inttostr(int1); + except + end; + end; + if foo_fixed in pitchoptions then begin + str1:= str1 + ':mono'; + end; + if foo_proportional in pitchoptions then begin + str1:= str1 + ':proportional'; + end; + if foo_antialiased in antialiasedoptions then begin + str1:= str1 + ':antialias=1'; + end; + if foo_nonantialiased in antialiasedoptions then begin + str1:= str1 + ':antialias=0'; + end; + { + if foo_xcore in xcoreoptions then begin + str1:= str1 + ':core=1'; + end; + if foo_noxcore in xcoreoptions then begin + str1:= str1 + ':core=0'; + end; + } + if fontinfo[fn_charset_registry] <> '*' then begin + str1:= str1 + ':encoding=' + fontinfo[fn_charset_registry]; + if fontinfo[fn_encoding] <> '*' then begin + str1:= str1 +'-'+fontinfo[fn_encoding]; + end; + end; + end; + result:= str1; +end; +*) + +{ +function fontdatatoxftname(const fontdata: fontdataty): ansistring; +var + fontinfo: fontinfoty; +begin + setupfontinfo(fontdata,fontinfo); + result:= buildxftname(fontdata,fontinfo); +end; +} +function fontdatatoxftpat(const fontdata: fontdataty; const highres: boolean): pfcpattern; +var + fontinfo: fontinfoty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + setupfontinfo(fontdata,fontinfo); + result:= buildxftpat(fontdata,fontinfo,highres); +end; + +procedure gdi_createpixmap(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.createpixmap do begin + pixmap:= gui_createpixmap(size,0,kind,copyfrom); + end; +end; + +procedure gdi_pixmaptoimage(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.pixmapimage do begin + gui_pixmaptoimage(pixmap,image,drawinfo.gc.handle); + end; +end; + +procedure gdi_imagetopixmap(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.pixmapimage do begin + error:= gui_imagetopixmap(image,pixmap,drawinfo.gc.handle); + end; +end; + +function creategc(const device: paintdevicety): tgc; +var + xvalues: xgcvalues; +begin + xvalues.graphics_exposures:= 0; + result:= xcreategc(appdisp,device,gcgraphicsexposures,@xvalues); +end; + +//function x11creategc(paintdevice: paintdevicety; const akind: gckindty; +// var gc: gcty; const aprintername: msestring): guierrorty; +procedure gdi_creategc(var drawinfo: drawinfoty); //gdifunc +begin +// gdi_lock; + with drawinfo.creategc do begin +// gcpo^.gdifuncs:= getdefaultgdifuncs; + gcpo^.gdifuncs:= x11getgdifuncs; + if paintdevice = 0 then begin + paintdevice:= gui_getrootwindow(); + end; + gcpo^.handle:= ptruint(creategc(paintdevice) + {xcreategc(appdisp,paintdevice,0,nil)}); + if gcpo^.handle = 0 then begin + error:= gde_creategc; + end + else begin +// xsetgraphicsexposures(appdisp,tgc(gcpo^.handle), +// {$ifdef xboolean}false{$else}0{$endif}); + with x11gcty(gcpo^.platformdata) do begin + //nothing to do, gc is nulled + end; + error:= gde_ok; + end; + end; +// gdi_unlock; +end; + +procedure transformpoints(var drawinfo: drawinfoty; const aclose: boolean); +var + po1: ppointty; + po2: pxpoint; + int1: integer; +begin + with drawinfo,drawinfo.points do begin + int1:= count; + if aclose then begin + inc(int1); + end; + allocbuffer(buffer,int1*sizeof(xpoint)); + int1:= count; + po1:= points; + po2:= buffer.buffer; + with origin do begin + while int1 > 0 do begin + po2^.x:= po1^.x + x; + po2^.y:= po1^.y + y; + inc(po1); + inc(po2); + dec(int1); + end; + end; + if aclose then begin + move(buffer.buffer^,(pchar(buffer.buffer)+count*sizeof(xpoint))^,sizeof(xpoint)); + end; + end; +end; + +procedure transformpos(var drawinfo: drawinfoty); +begin + with drawinfo,drawinfo.pos do begin + allocbuffer(buffer,sizeof(xpoint)); + with pxpoint(buffer.buffer)^ do begin + x:= pos^.x + origin.x; + y:= pos^.y + origin.y; + end; + end; +end; + +function transformtext16pos(var drawinfo: drawinfoty): pxchar2b; +var + po1: pword; + po2: pword; + int1: integer; +begin + with drawinfo,drawinfo.text16pos do begin + allocbuffer(buffer,sizeof(xpoint)+count*2); + with pxpoint(buffer.buffer)^ do begin + x:= pos^.x + origin.x; + y:= pos^.y + origin.y; + end; + po1:= pword(text); + result:= pxchar2b(pchar(buffer.buffer) + sizeof(xpoint)); + po2:= pword(result); + for int1:= count-1 downto 0 do begin + po2^:= (po1^ shl 8) or (po1^ shr 8); //simply swap bytes + inc(po1); + inc(po2); + end; + end; +end; + +function x11regiontorects(const aregion: regionty): rectarty; +var + int1: integer; + boxpo: pbox; +begin + gdi_lock; + if aregion = 0 then begin + result:= nil; + end + else begin + with pxregion(aregion)^ do begin + setlength(result,numrects); + boxpo:= rects; + for int1:= 0 to numrects-1 do begin + with boxpo^,result[int1] do begin + x:= x1; + y:= y1; + cx:= x2 - x1; + cy:= y2 - y1; + end; + inc(boxpo); + end; + end; + end; + gdi_unlock; +end; + +function x11getdefaultfontnames: defaultfontnamesty; +begin + if fhasxft then begin + result:= xftdefaultfontnames; + end + else begin + result:= defaultfontnames; + end; +end; + +procedure freexftbrush(var drawinfo: drawinfoty); +begin + with x11gcty(drawinfo.gc.platformdata).d do begin + if xftbrushpic <> 0 then begin + xrenderfreepicture(appdisp,xftbrushpic); + xftbrushpic:= 0; + end; + if xftbrushalphapic <> 0 then begin + xrenderfreepicture(appdisp,xftbrushalphapic); + xftbrushalphapic:= 0; + end; + end; +end; + +procedure gdi_destroygc(var drawinfo: drawinfoty); //gdifunc +begin + gdi_lock; + with drawinfo do begin + with x11gcty(gc.platformdata).d do begin + if xftdraw <> nil then begin + freexftbrush(drawinfo); + xftdrawdestroy(xftdraw); + end; + end; + xfreegc(appdisp,tgc(gc.handle)); + end; + gdi_unlock; +end; + +function colortorendercolor(const avalue: rgbtriplety): txrendercolor; overload; +begin + with result do begin + red:= (avalue.red shl 8) or avalue.red; + green:= (avalue.green shl 8) or avalue.green; + blue:= (avalue.blue shl 8) or avalue.blue; + alpha:= $ffff; + end; +end; + +function colortorendercolor(const avalue: colorty): txrendercolor; overload; +begin + result:= colortorendercolor(colortorgb(avalue)); +end; + +function alphatorendercolor(const avalue: rgbtriplety): txrendercolor; overload; +var + wo1: word; +begin + with result do begin + wo1:= (integer(avalue.red)+integer(avalue.green)+integer(avalue.blue)) div 3; + wo1:= wo1 or (wo1 shl 8); + red:= 0; + green:= 0; + blue:= 0; + alpha:= wo1; + end; +end; + +function alphatorendercolor(const avalue: colorty): txrendercolor; overload; +begin + result:= alphatorendercolor(colortorgb(avalue)); +end; + +function graytorendercolor(const avalue: rgbtriplety): txrendercolor; overload; +var + wo1: word; +begin + with result do begin + wo1:= (integer(avalue.red)+integer(avalue.green)+integer(avalue.blue)) div 3; + wo1:= wo1 or (wo1 shl 8); + red:= wo1; + green:= wo1; + blue:= wo1; + alpha:= $ffff; + end; +end; + +function graytorendercolor(const avalue: colorty): txrendercolor; overload; +begin + result:= graytorendercolor(colortorgb(avalue)); +end; + +procedure setregion(var gc: gcty; const aregion: region; + const pic: tpicture = 0; const draw: pxftdraw = nil); +var + po1,rectspo: pxrectangle; + boxpo: pbox; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + {$ifdef FPC} {$checkpointer off} {$endif} + with pxregion(aregion)^ do begin + if numrects > 0 then begin + boxpo:= rects; + getmem(rectspo,numrects*sizeof(xrectangle)); + po1:= rectspo; + for int1:= numrects - 1 downto 0 do begin + rectspo^.x:= boxpo^.x1; + rectspo^.y:= boxpo^.y1; + rectspo^.width:= boxpo^.x2-boxpo^.x1; + rectspo^.height:= boxpo^.y2-boxpo^.y1; + inc(boxpo); + inc(rectspo); + end; + if pic <> 0 then begin + xrendersetpicturecliprectangles(appdisp,pic,gc.cliporigin.x, + gc.cliporigin.y,po1,numrects); + end + else begin + if draw <> nil then begin + xftdrawsetcliprectangles(draw,gc.cliporigin.x,gc.cliporigin.y,po1,numrects); + end + else begin + xsetcliprectangles(appdisp,tgc(gc.handle),gc.cliporigin.x,gc.cliporigin.y,po1,numrects,yxbanded); + end; + end; + freemem(po1); + end + else begin + if pic <> 0 then begin + xrendersetpicturecliprectangles(appdisp,pic,gc.cliporigin.x,gc.cliporigin.y,nil,0); + end + else begin + if draw <> nil then begin + xftdrawsetcliprectangles(draw,gc.cliporigin.x,gc.cliporigin.y,nil,0); + end + else begin + xsetcliprectangles(appdisp,tgc(gc.handle),gc.cliporigin.x,gc.cliporigin.y,nil,0,yxbanded); + end; + end; + end; + end; + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +const + unitytransform: txtransform = ((65536,0,0), + (0,65536,0), + (0,0,65536)); + +function creatergbpicture(const size: sizety; + const arepeat: boolean = false; + const alphamap: tpicture = 0): tpicture; +var + attributes: txrenderpictureattributes; + pixmap: pixmapty; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + pixmap:= xcreatepixmap(appdisp,gui_getrootwindow(),size.cx,size.cy,24); + attributes._repeat:= repeatnormal; + attributes.alpha_map:= alphamap; + int1:= 0; + if arepeat then begin + int1:= cprepeat; + end; + if alphamap <> 0 then begin + int1:= int1 or cpalphamap; + end; + result:= xrendercreatepicture(appdisp,pixmap, + rgbrenderpictformat,int1,@attributes); + xfreepixmap(appdisp,pixmap); +end; + +function createalphapicture(const size: sizety; + const arepeat: boolean = false): tpicture; +var + attributes: txrenderpictureattributes; + pixmap: pixmapty; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + pixmap:= xcreatepixmap(appdisp,gui_getrootwindow(),size.cx,size.cy,8); + attributes._repeat:= repeatnormal; + int1:= cpcomponentalpha; + if arepeat then begin + int1:= cprepeat; + end; + result:= xrendercreatepicture(appdisp,pixmap, + alpharenderpictformat,int1,@attributes); + xfreepixmap(appdisp,pixmap); +end; + +function createargbpicture(const size: sizety; + const arepeat: boolean = false): tpicture; +var + attributes: txrenderpictureattributes; + pixmap: pixmapty; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + pixmap:= xcreatepixmap(appdisp,gui_getrootwindow(),size.cx,size.cy,32); + attributes._repeat:= repeatnormal; + int1:= 0; + if arepeat then begin + int1:= cprepeat; + end; + result:= xrendercreatepicture(appdisp,pixmap, + argbrenderpictformat,int1,@attributes); + xfreepixmap(appdisp,pixmap); +end; + +function createcolorpi(const acolor: txrendercolor; + const aformat: pxrenderpictformat): tpicture; +var + attributes: txrenderpictureattributes; +// col: txrendercolor; + pixmap: pixmapty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + pixmap:= gui_createpixmap( + makesize(xrendercolorsourcesize,xrendercolorsourcesize)); + attributes._repeat:= repeatnormal; + result:= xrendercreatepicture(appdisp,pixmap, + screenrenderpictformat,cprepeat,@attributes); +// col:= colortorendercolor(acolor); + xrenderfillrectangle(appdisp,pictopsrc,result,@acolor,0,0, + xrendercolorsourcesize,xrendercolorsourcesize); + xfreepixmap(appdisp,pixmap); +end; + +function createcolorpic1(const acolor: txrendercolor): tpicture; +begin + result:= createcolorpi(acolor,screenrenderpictformat); +end; + +function createcolorpic2(const acolor: txrendercolor): tpicture; +//var +// col: txrendercolor; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} +// col:= colortorendercolor(acolor); + result:= xrendercreatesolidfill(appdisp,@acolor); +end; + +function createcolorpicture(const acolor: colorty): tpicture; +begin + result:= createcolorpic(colortorendercolor(acolor)); +end; + +function creategraycolorpicture(const acolor: colorty): tpicture; +begin + result:= createcolorpic(graytorendercolor(acolor)); +end; + +function createalphacolorpicture(const acolor: colorty): tpicture; +begin + result:= createcolorpic(alphatorendercolor(acolor)); +end; +{ +function creategraypicture(const acolor: colorty): tpicture; +begin + result:= createcolorpi(alphatorendercolor(acolor),alpharenderpictformat); +end; +} +type + ppxrenderpictformat = ^pxrenderpictformat; + +const + renderformats: array[bitmapkindty] of ppxrenderpictformat = +// bmk_mono, bmk_gray, bmk_rgb + (@bitmaprenderpictformat,@alpharenderpictformat,@screenrenderpictformat); + +function createmaskpicture(const acolor: rgbtriplety; + const akind: bitmapkindty): tpicture; +var + attributes: txrenderpictureattributes; + col: txrendercolor; + pixmap: pixmapty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + pixmap:= gui_createpixmap(makesize(1,1),0,akind); + attributes._repeat:= repeatnormal; + col:= colortorendercolor(acolor); + attributes.component_alpha:= 1; + if akind = bmk_gray then begin + col.alpha:= (col.red + col.green + col.blue) div 3; + end; + result:= xrendercreatepicture(appdisp,pixmap,renderformats[akind]^, + cprepeat or cpcomponentalpha,@attributes); + xrenderfillrectangle(appdisp,pictopsrc,result,@col,0,0,1,1); + gui_freepixmap(pixmap); +end; + +function createmaskpicture(const ahandle: pixmapty; + const akind: bitmapkindty): tpicture; +var + attributes: txrenderpictureattributes; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= 0; + if ahandle <> 0 then begin + attributes.component_alpha:= 0; + if akind = bmk_rgb then begin + attributes.component_alpha:= 1; + end; + result:= xrendercreatepicture(appdisp,ahandle, + renderformats[akind]^,cpcomponentalpha,@attributes); + end; +end; + +function createmaskpicture(const amask: tsimplebitmap): tpicture; overload; +begin + if amask <> nil then begin + result:= createmaskpicture(tsimplebitmap1(amask).handle,amask.kind); + end; +end; + +procedure checkxftdraw(var drawinfo: drawinfoty); +var + attr: txrenderpictureattributes; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with x11gcty(drawinfo.gc.platformdata).d do begin + if xftdraw = nil then begin + xftdraw:= xftdrawcreate(appdisp,drawinfo.paintdevice, + xlib.pvisual(defvisual),0); + xftdrawpic:= xftdrawpicture(xftdraw); + attr.poly_edge:= polyedgesmooth; + attr.poly_mode:= polymodeprecise; +// attr.poly_mode:= polymodeimprecise; + xrenderchangepicture(appdisp,xftdrawpic,cppolyedge or cppolymode,@attr); +// xftcolorforegroundpic:= createcolorpicture(cl_black); + end; + if not (xfts_clipregionvalid in xftstate) then begin + if gcclipregion = 0 then begin + xftdrawsetclip(xftdraw,nil); + end + else begin + setregion(drawinfo.gc,region(gcclipregion),0,xftdraw); + end; + include(xftstate,xfts_clipregionvalid); + end; + end; +end; + +procedure checkxftstate(var drawinfo: drawinfoty; const aflags: xftstatesty); + procedure updatemonocolor; + var + co1: txrendercolor; + begin + with drawinfo.gc,x11gcty(platformdata).d do begin + if df_opaque in drawingflags then begin + co1:= xftcolorbackground.color; + end + else begin + co1:= xrendernullcolor; + end; + xrenderfillrectangle(appdisp,pictopsrc,xftbrushpic, + @co1,0,0,xftbrushsize.cx,xftbrushsize.cy); + xrendercomposite(appdisp,pictopover,xftdrawsrcpicture(xftdraw,@xftcolor), + xftbrushalphapic,xftbrushpic,0,0,0,0, + 0,0,xftbrushsize.cx,xftbrushsize.cy); + end; + end; //updatemonocolor + +var + flags1: xftstatesty; + attributes: txrenderpictureattributes; +//todo: fix xftbrushorigin, seems to be unreliable +begin + with drawinfo.gc,x11gcty(platformdata).d do begin + if not (xfts_clipregionvalid in xftstate) then begin + if gcclipregion = 0 then begin + xftdrawsetclip(xftdraw,nil); + end + else begin + setregion(drawinfo.gc,region(gcclipregion),0,xftdraw); + end; + include(xftstate,xfts_clipregionvalid); + end; + flags1:= (xftstate >< aflags) * aflags; + if xfts_foregroundvalid in flags1 then begin + if df_brush in drawinfo.gc.drawingflags then begin + if (xftbrush <> 0) then begin + if (xftbrushpic = 0) then begin + attributes._repeat:= repeatnormal; + if xfts_monobrush in xftstate then begin + xftbrushalphapic:= xrendercreatepicture(appdisp,xftbrush, + bitmaprenderpictformat,cprepeat,@attributes); + xftbrushpic:= createargbpicture(xftbrushsize,true); + updatemonocolor; + end + else begin + xftbrushpic:= xrendercreatepicture(appdisp,xftbrush, + screenrenderpictformat,cprepeat,@attributes); + end; + end + else begin + if xfts_monobrush in xftstate then begin + updatemonocolor; + end; + end; + end; + xftforegroundpic:= xftbrushpic; + end + else begin + xftforegroundpic:= xftdrawsrcpicture(xftdraw,@xftcolor); + end; + include(xftstate,xfts_foregroundvalid); + end; + end; +end; +const + posroundval = $0;//7fff; + +procedure compositetriangles(var drawinfo: drawinfoty; + const triangles: ptrianglety; const trianglecount: integer); +begin + checkxftstate(drawinfo,[xfts_foregroundvalid]); + with x11gcty(drawinfo.gc.platformdata).d do begin + xrendercompositetriangles(appdisp,xrenderop,xftforegroundpic, + xftdrawpic,alpharenderpictformat, + xftbrushorigin.x+(ppointty(triangles)^.x+posroundval) div 65536, + xftbrushorigin.y+(ppointty(triangles)^.y+posroundval) div 65536, + pxtriangle(triangles),trianglecount); + end; +end; + +procedure compositetristrip(var drawinfo: drawinfoty; + const points: ppointty; const pointcount: integer); +begin + checkxftstate(drawinfo,[xfts_foregroundvalid]); + with x11gcty(drawinfo.gc.platformdata).d do begin + xrendercompositetristrip(appdisp,xrenderop,xftforegroundpic, + xftdrawpic,alpharenderpictformat, + xftbrushorigin.x+(points^.x+posroundval) div 65536, + xftbrushorigin.y+(points^.y+posroundval) div 65536, + pxpointfixed(points),pointcount); + end; +end; + +procedure compositetrifan(var drawinfo: drawinfoty; + const points: ppointty; const pointcount: integer); +begin + checkxftstate(drawinfo,[xfts_foregroundvalid]); + with x11gcty(drawinfo.gc.platformdata).d do begin + xrendercompositetrifan(appdisp,xrenderop,xftforegroundpic, + xftdrawpic,alpharenderpictformat, + xftbrushorigin.x+(points^.x+posroundval) div 65536, + xftbrushorigin.y+(points^.y+posroundval) div 65536, + pxpointfixed(points),pointcount); + end; +end; + +procedure gdi_changegc(var drawinfo: drawinfoty); //gdifunc +var + xmask: longword; + xvalues: xgcvalues; + agc: tgc; + int1: integer; + needslinecheck: boolean; + +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xmask:= 0; + with drawinfo.gcvalues^,drawinfo.gc,x11gcty(platformdata).d do begin + agc:= tgc(handle); + needslinecheck:= false; + if gvm_colorforeground in mask then begin + xmask:= xmask or gcforeground; + xvalues.foreground:= colorforeground; + xvalues.fill_style:= fillsolid; + if fhasxft then begin + xftcolor.pixel:= colorforeground; + xftcolor.color:= colortorendercolor(drawinfo.acolorforeground); + exclude(xftstate,xfts_foregroundvalid); + end; + end; + if (drawingflags >< gcdrawingflags) + * (fillmodeinfoflags+[df_smooth]) <> [] then begin + xmask:= xmask or gcfillstyle; + if df_brush in drawingflags then begin + if df_monochrome in drawingflags then begin + include(xftstate,xfts_monobrush); + if df_opaque in drawingflags then begin + xvalues.fill_style:= fillopaquestippled; + end + else begin + xvalues.fill_style:= fillstippled; + end; + end + else begin + xvalues.fill_style:= filltiled; + end; + end + else begin + exclude(xftstate,xfts_monobrush); + xvalues.fill_style:= fillsolid; + end; + if (df_smooth in drawingflags) and fhasxft then begin + checkxftdraw(drawinfo); + if not (xfts_smooth in xftstate) then begin + include(xftstate,xfts_smooth); + needslinecheck:= true; + end; + end + else begin + if xfts_smooth in xftstate then begin + exclude(xftstate,xfts_smooth); + needslinecheck:= true; + end; + end; + end; + gcdrawingflags:= drawingflags; + + if gvm_rasterop in mask then begin + xmask:= xmask or gcfunction; + xvalues.xfunction:= integer(rasterop); + gcrasterop:= rasterop; + end; + if gvm_linewidth in mask then begin + needslinecheck:= true; + xmask:= xmask or gclinewidth; + xvalues.line_width:= + (lineinfo.width + linewidthroundvalue) shr linewidthshift; + triainfo.linewidth:= xvalues.line_width; + if triainfo.linewidth = 0 then begin + triainfo.linewidth1:= 1; + end + else begin + triainfo.linewidth1:= triainfo.linewidth; + end; + triainfo.linewidth16:= triainfo.linewidth1 shl 16; + gclinewidth_:= xvalues.line_width; + end; + if gvm_dashes in mask then begin + with lineinfo do begin + needslinecheck:= true; + if dashes = '' then begin + exclude(xftstate,xfts_hasdashes); + end + else begin + include(xftstate,xfts_hasdashes); + end; + triainfo.xftdashes:= dashes; + int1:= length(dashes); + if int1 <> 0 then begin + if df_opaque in drawingflags then begin + xvalues.line_style:= linedoubledash; + end + else begin + xvalues.line_style:= lineonoffdash; + end; + xsetdashes(appdisp,agc,0,@lineinfo.dashes[1],int1); + end + else begin + xvalues.line_style:= linesolid; + end; + end; + xmask:= xmask or gclinestyle; + end; + if gvm_capstyle in mask then begin + needslinecheck:= true; +// triainfo.capstyle:= lineinfo.capstyle; + triainfo.triaflags:= triainfo.triaflags - triacapmask + + triacapflags[lineinfo.capstyle]; + xvalues.cap_style:= capstyles[lineinfo.capstyle]; + gccapstyle_:= xvalues.cap_style; + xmask:= xmask or gccapstyle; + end; + if gvm_joinstyle in mask then begin +// triainfo.joinstyle:= lineinfo.joinstyle; + triainfo.triaflags:= triainfo.triaflags - triajoinmask + + triajoinflags[lineinfo.joinstyle]; + xvalues.join_style:= joinstyles[lineinfo.joinstyle]; + xmask:= xmask or gcjoinstyle; + end; + if gvm_font in mask then begin +// fontdirection:= x11fontdataty(fontdata^.platformdata).d.direction; + if fhasxft then begin + xftfont:= pxftfont(font); + xftfontdata:= @x11fontdataty(fontdata^.platformdata).d; + end + else begin + xmask:= xmask or gcfont; + xvalues.font:= font; + end; + end; + if gvm_colorbackground in mask then begin + xmask:= xmask or gcbackground; + xvalues.background:= colorbackground; + if df_dashed in drawingflags then begin + if df_opaque in drawingflags then begin + xvalues.line_style:= linedoubledash; + end + else begin + xvalues.line_style:= lineonoffdash; + end; + xmask:= xmask or gclinestyle; + end; + if fhasxft then begin + xftcolorbackground.pixel:= colorbackground; + xftcolorbackground.color:= colortorendercolor(drawinfo.acolorbackground); + if xfts_monobrush in xftstate then begin + exclude(xftstate,xfts_foregroundvalid); + end; + end; + end; + if gvm_brushorigin in mask then begin + xmask:= xmask or gctilestipxorigin or gctilestipyorigin; + xvalues.ts_x_origin:= brushorigin.x; + xvalues.ts_y_origin:= brushorigin.y; + xftbrushorigin.x:= -brushorigin.x;//-drawinfo.origin.x; + xftbrushorigin.y:= -brushorigin.y;//-drawinfo.origin.y; + end; + + if gvm_brush in mask then begin + exclude(xftstate,xfts_foregroundvalid); + with tsimplebitmap1(brush) do begin + xftbrush:= handle; + xftbrushsize:= size; + end; + freexftbrush(drawinfo); + if df_monochrome in drawingflags then begin + xvalues.stipple:= xftbrush; + xmask:= xmask or gcstipple; + end + else begin + xvalues.tile:= xftbrush; + xmask:= xmask or gctile; + end; + end; + + if needslinecheck and zerolineworkaround then begin + if (gclinewidth_ = 0) and not (xfts_smooth in xftstate) then begin + xvalues.line_width:= 1; + if xfts_hasdashes in xftstate then begin + xvalues.cap_style:= capbutt; + end + else begin + xvalues.cap_style:= capprojecting; + end; + end + else begin + xvalues.line_width:= gclinewidth_; + xvalues.cap_style:= gccapstyle_; + end; + xmask:= xmask or (gclinewidth or gccapstyle); + end; + + if xmask <> 0 then begin + xchangegc(appdisp,agc,xmask,@xvalues); + end; + if gvm_clipregion in mask then begin + exclude(xftstate,xfts_clipregionvalid); + gcclipregion:= clipregion; + if clipregion = 0 then begin + xsetclipmask(appdisp,agc,none); + end + else begin + setregion(drawinfo.gc,region(clipregion)); +// xsetregion(appdisp,agc,region(clipregion)); + end; + end; + end; +end; + +procedure gdi_getcanvasclass(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_endpaint(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_flush(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_movewindowrect(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.moverect do begin + gui_movewindowrect(drawinfo.paintdevice,dist^,rect^); + end; +end; + +function getmatrixcharstruct(char: msechar; const fontdata: x11fontdataty): pxcharstruct; +type + xchar2b = record + byte2: byte; //lsb + byte1: byte; //msb + end; + +begin +{$ifdef FPC} {$checkpointer off} {$endif} + with fontdata,d.infopo^ do begin + if (xchar2b(char).byte1 >= min_byte1) and (xchar2b(char).byte1 <= max_byte1) and + (xchar2b(char).byte2 >= min_char_or_byte2) and + (xchar2b(char).byte2 <= max_char_or_byte2) then begin + result:= pxcharstruct(pchar(per_char) + + ((xchar2b(char).byte1 - min_byte1) * d.rowlength + + (xchar2b(char).byte2 - min_char_or_byte2) + ) * sizeof(xcharstruct)); + end + else begin + result:= nil; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} +end; + +procedure gdi_getchar16widths(var drawinfo: drawinfoty); +var + int1,int2: integer; + char: word; + po1,pe: pmsechar; + po2: pinteger; + charstructpo: pxcharstruct; + glyphinfo: txglyphinfo; + bo1: boolean; + po3: pxftfont; + ca1: card32; + +begin + gdi_lock; + with drawinfo.getchar16widths do begin + po1:= text; + po2:= resultpo; +{$ifdef FPC} {$checkpointer off} {$endif} + with fontdata^,x11fontdataty(platformdata),d.infopo^ do begin + if fhasxft then begin + bo1:= (df_highresfont in drawinfo.gc.drawingflags) and + (fonthighres <> 0); + if bo1 then begin + po3:= pxftfont(fonthighres); + end + else begin + po3:= pxftfont(font); + end; + pe:= po1 + count; + while po1 < pe do begin + ca1:= card16(po1^); + if (ca1 and $fc00 = $d800) then begin //surrogate pair + inc(po1); + if (card16(po1^) and $fc00 = $dc00) then begin + ca1:= ((ca1 + ($0040-$d800)) shl 10) + card16(po1^) - $dc00; + xfttextextents32(appdisp,po3,@ca1,1,@glyphinfo); + po2^:= glyphinfo.xoff; + inc(po2); + po2^:= 0; + end + else begin + dec(po1); //invalid low part + xfttextextents32(appdisp,po3,@ca1,1,@glyphinfo); + po2^:= glyphinfo.xoff; + end; + end + else begin + xfttextextents32(appdisp,po3,@ca1,1,@glyphinfo); + po2^:= glyphinfo.xoff; + end; + inc(po1); + inc(po2); + end; + + if bo1 then begin + po2:= resultpo; + int2:= highresfontfakt div 2; //round up + for int1:= 0 to count - 1 do begin + int2:= int2 + po2^; + po2^:= int2 shr highresfontshift; + int2:= int2 and highresfontmask; + inc(po2); + end; + end; + end + else begin + case d.matrixmode of + fmm_linear: begin + for int1:= 0 to count - 1 do begin + char:= word(po1^); + if (char >= min_char_or_byte2) and (char <= max_char_or_byte2) then begin + po2^:= pxcharstruct(pchar(per_char) + + (char - min_char_or_byte2)*sizeof(xcharstruct))^.width; + end + else begin + po2^:= d.defaultwidth; + end; + inc(po1); + inc(po2); + end; + end; + fmm_matrix: begin + for int1:= 0 to count -1 do begin + charstructpo:= getmatrixcharstruct(po1^, + x11fontdataty(fontdata^.platformdata)); + if charstructpo <> nil then begin + po2^:= charstructpo^.width; + if po2^ = 0 then begin + po2^:= d.defaultwidth; + end; + end + else begin + po2^:= d.defaultwidth; + end; + inc(po1); + inc(po2); + end; + end; + else begin //fm_fix + int2:= max_bounds.width; + for int1:= 0 to count - 1 do begin + po2^:= int2; + inc(po2); + end; + end; + end; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} + end; +// result:= gde_ok; + gdi_unlock; +end; + +procedure gdi_getfontmetrics(var drawinfo: drawinfoty); +var + po1: pxcharstruct; + glyphinfo: txglyphinfo; +begin + gdi_lock; + with drawinfo.getfontmetrics do begin +{$ifdef FPC} {$checkpointer off} {$endif} + with fontdata^,x11fontdataty(platformdata),d.infopo^ do begin + if fhasxft then begin + xfttextextents32(appdisp,pxftfont(font),@char,1,@glyphinfo); + with resultpo^ do begin + width:= glyphinfo.xoff; + leftbearing:= -glyphinfo.x; + rightbearing:= glyphinfo.xoff-glyphinfo.width+glyphinfo.x; + end; + end + else begin + case d.matrixmode of + fmm_linear: begin + if (word(char) >= min_char_or_byte2) and (word(char) <= max_char_or_byte2) then begin + po1:= pxcharstruct(pchar(per_char) + + (word(char) - min_char_or_byte2)*sizeof(xcharstruct)); + end + else begin + po1:= pxcharstruct(pchar(per_char) + + (default_char - min_char_or_byte2)*sizeof(xcharstruct)); + end; + end; + fmm_matrix: begin + po1:= getmatrixcharstruct(msechar(card16(char)), + x11fontdataty(fontdata^.platformdata)); + if po1 = nil then begin + po1:= getmatrixcharstruct(msechar(default_char), + x11fontdataty(fontdata^.platformdata)); + if po1 = nil then begin + with resultpo^ do begin + width:= 0; + leftbearing:= 0; + rightbearing:= 0; + end; + end; + end; + end; + else begin //fm_fix + po1:= @max_bounds; + end; + end; + with resultpo^ do begin + width:= po1^.width; + leftbearing:= po1^.lbearing; + rightbearing:= width - po1^.rbearing; + end; + end; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} +// result:= gde_ok; + gdi_unlock; +end; + +procedure gdi_gettext16width(var drawinfo: drawinfoty); +var + int1: integer; + char: word; + charstructpo: pxcharstruct; + glyphinfo: txglyphinfo; +begin + gdi_lock; +{$ifdef FPC} {$checkpointer off} {$endif} + with drawinfo.gettext16width do begin + result:= 0; + with fontdata^,x11fontdataty(platformdata),d.infopo^ do begin + if fhasxft then begin + xfttextextentsutf16(appdisp,pxftfont(font),pointer(text),fcendianlittle, + count*2,@glyphinfo); + result:= glyphinfo.xoff; + end + else begin + case d.matrixmode of + fmm_linear: begin + for int1:= 0 to count - 1 do begin + char:= word(text[int1]); + if (char >= min_char_or_byte2) and (char <= max_char_or_byte2) then begin + inc(result,pxcharstruct(pchar(per_char) + + (char - min_char_or_byte2)*sizeof(xcharstruct))^.width); + end + else begin + inc(result,d.defaultwidth); + end; + end; + end; + fmm_matrix: begin + for int1:= 0 to count - 1 do begin + charstructpo:= getmatrixcharstruct(text[int1], + x11fontdataty(fontdata^.platformdata)); + if charstructpo <> nil then begin + inc(result,charstructpo^.width); + end + else begin + inc(result,d.defaultwidth); + end; + end; + end; + else begin //fm_fix + result:= max_bounds.width * count; + end; + end; + end; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} + gdi_unlock; +end; + +function getcharstruct(const fontdata: fontdataty; char: msechar): pxcharstruct; +begin +{$ifdef FPC} {$checkpointer off} {$endif} + result:= nil; + with fontdata,x11fontdataty(platformdata),d.infopo^ do begin + case d.matrixmode of + fmm_linear: begin + if (word(char) >= min_char_or_byte2) and + (word(char) <= max_char_or_byte2) then begin + result:= pxcharstruct(pchar(per_char) + + (word(char) - min_char_or_byte2)*sizeof(xcharstruct)); + end; + end; + fmm_matrix: begin + result:= getmatrixcharstruct(char,x11fontdataty(fontdata.platformdata)); + end; + else begin //fmm_fix + result:= @d.infopo^.max_bounds; + end; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} +end; + + +type + fontpropinfoty = record + foundry: string; + family_name: string; + weight_name: string; + slant: string; + setwidth_name: string; + add_style_name: string; + pixel_size: ptrint; + point_size: ptrint; + resolution_x: ptrint; + resolution_y: ptrint; + spacing: string; + average_width: ptrint; + charset_registry: string; + charset_encodeing: string; + min_space: ptrint; + norm_space: ptrint; + max_space: ptrint; + end_space: ptrint; + superscript_x: ptrint; + superscript_y: ptrint; + subscript_x: ptrint; + subscript_y: ptrint; + underline_position: ptrint; + underline_thickness: ptrint; + strikeout_ascent: ptrint; + strikeout_descent: ptrint; + italic_angle: ptrint; + x_height: ptrint; + weight: ptrint; + face_name: string; + font: string; + copyright: string; + avg_capital_width: ptrint; + avg_lowercase_width: ptrint; + relative_setwidth: ptrint; + relative_weight: ptrint; + cap_height: ptrint; + superscript_size: ptrint; + figure_width: ptrint; + subscript_size: ptrint; + small_cap_size: ptrint; + notice: string; + destination: ptrint; + font_type: string; + font_version: string; + rasterizer_name: string; + rasterizer_version: string; + raw_ascent: ptrint; + raw_descent: ptrint; + axis_names: string; + axis_limits: string; + axis_types: string; + dummy: ptrint; + end; + +procedure getfontproperties(var fontstruct: xfontstruct; var propinfo: fontpropinfoty); + + procedure setproperty(const prop: xfontprop); + + var + propnum: fontpropertiesty; + po: pchar; + + begin //setproperty + with prop do begin + for propnum:= low(fontpropertiesty) to high(fontpropertiesty) do begin + if name = fontpropertyatoms[propnum] then begin + break; + end; + end; + if propnum < fpnone then begin + if fontpropertynames[propnum].isstring then begin + if prop.card32 = 0 then begin + strfontproparty(propinfo)[propnum]:= ''; + end + else begin + po:= xgetatomname(appdisp,prop.card32); + strfontproparty(propinfo)[propnum]:= po; + xfree(po); + end; + end + else begin + intfontproparty(propinfo)[propnum]:= prop.card32; + end; + end; + end; + end; +var + int1: integer; + po: pxfontprop; + +begin //getfontproperties +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with fontstruct do begin + po:= properties; + for int1:= 0 to n_properties - 1 do begin + setproperty(po^); + inc(po); + end; + end; +end; + + +procedure gdi_getfonthighres(var drawinfo: drawinfoty); +var + pat1,pat2: pfcpattern; + res1: tfcresult; +// po1: pxftfont; +begin + gdi_lock; + if fhasxft then begin + with drawinfo.getfont do begin + pat1:= fontdatatoxftpat(fontdata^,true); + pat2:= xftfontmatch(appdisp,xdefaultscreen(appdisp),pat1,@res1); + if pat2 <> nil then begin + fontdata^.fonthighres:= ptruint(xftfontopenpattern(appdisp,pat2)); + end; + fcpatterndestroy(pat1); + end; + end; + gdi_unlock; +end; + +procedure gdi_getfont(var drawinfo: drawinfoty); + + procedure getfontdata(po: pxfontstruct); + var + charstructpo: pxcharstruct; + begin +{$ifdef FPC} {$checkpointer off} {$endif} + with drawinfo.getfont,fontdata^,x11fontdataty(platformdata) do begin + font:= po^.fid; + ascent:= po^.ascent; + descent:= po^.descent; + linespacing:= ascent + descent; + realheight:= linespacing; + caretshift:= 0; + d.infopo:= po; + with po^ do begin + if per_char = nil then begin + d.matrixmode:= fmm_fix; + end + else begin + if (min_byte1 = 0) and (max_byte1 = 0) then begin + d.matrixmode:= fmm_linear; + end + else begin + d.matrixmode:= fmm_matrix; + d.rowlength:= max_char_or_byte2 - min_char_or_byte2 + 1; + end; + end; + charstructpo:= getcharstruct(fontdata^,msechar(default_char)); + if charstructpo <> nil then begin + d.defaultwidth:= charstructpo^.width; + end; //0 otherwise + end; +{$ifdef FPC} {$checkpointer default} {$endif} + end; + end; + +var + po1: pxfontstruct; + po2: pxftfont; + fontinfo: fontinfoty; + int1: integer; + po3,po4: pfcpattern; + res1: tfcresult; + rea1: real; + {$ifdef mse_debugxft} + po5: pchar; + {$endif} +begin + gdi_lock; + setupfontinfo(drawinfo.getfont.fontdata^,fontinfo); +{$ifdef FPC} {$checkpointer off} {$endif} + with drawinfo.getfont.fontdata^ do begin + if fhasxft then begin + drawinfo.getfont.ok:= false; + po3:= buildxftpat(drawinfo.getfont.fontdata^,fontinfo,false); + po4:= xftfontmatch(appdisp,xdefaultscreen(appdisp),po3,@res1); + if po4 <> nil then begin + if fcpatterngetinteger(po4,fc_pixel_size,0,@int1) = fcresultmatch then begin + realheight:= int1; + end; + {$ifdef mse_debugxft} + if fcpatterngetstring(po4,fc_file,0,@po5) = fcresultmatch then begin + writeln('Font found. Name: "'+h.name+'" Height: '+ + inttostr(h.d.height)+' Realheight: '+inttostr(int1)+' File:'); + writeln('"'+string(po5)+'"'); + end; + {$endif} + po2:= xftfontopenpattern(appdisp,po4); //font owns the pattern + if po2 <> nil then begin + drawinfo.getfont.ok:= true; + getxftfontdata(po2,drawinfo); + if h.d.rotation <> 0 then begin //ascent and descent are 0 for rotated fonts + fcpatterndestroy(po3); + rea1:= h.d.rotation; + if rea1 <> 0 then begin + int1:= round(rea1/(pi/2)) mod 4; + if int1 < 0 then begin + int1:= int1 + 4; + end; + x11fontdataty(platformdata).d.xftdirection:= graphicdirectionty(int1); + //for xft colorbackground + end; + h.d.rotation:= 0; + po3:= buildxftpat(drawinfo.getfont.fontdata^,fontinfo,false); + po4:= xftfontmatch(appdisp,xdefaultscreen(appdisp),po3,@res1); + if po4 <> nil then begin + po2:= xftfontopenpattern(appdisp,po4); + if po2 <> nil then begin + ascent:= po2^.ascent; + descent:= po2^.descent; + x11fontdataty(platformdata).d.xftascent:= po2^.ascent; + x11fontdataty(platformdata).d.xftdescent:= po2^.descent; + xftfontclose(appdisp,po2); + end; + end; + h.d.rotation:= rea1; + end; + end; + end; + fcpatterndestroy(po3); + end + else begin + po1:= xloadqueryfont(appdisp,pchar(fontinfotoxlfdname(fontinfo))); + if po1 = nil then begin + if fs_italic in h.d.style then begin + fontinfo[fn_slant]:= 'o'; + po1:= xloadqueryfont(appdisp,pchar(fontinfotoxlfdname(fontinfo))); + fontinfo[fn_slant]:= 'i'; + end; + if po1 = nil then begin + if (h.name <> '') and (h.d.style * [fs_italic,fs_bold] = []) and + (h.charset <> '') and (h.d.height = 0) then begin + po1:= xloadqueryfont(appdisp,pchar(h.name)); + end; + if po1 = nil then begin + if simpledefaultfont then begin + po1:= xloadqueryfont(appdisp,pchar(fontinfo[fn_family_name])); + end; + if po1 = nil then begin + fontinfo[fn_family_name]:= 'fixed'; + po1:= xloadqueryfont(appdisp,pchar(fontinfotoxlfdname(fontinfo))); + if po1 = nil then begin + po1:= xloadqueryfont(appdisp,'fixed'); + end; + end; + end; + end; + end; + if po1 <> nil then begin + getfontdata(po1); + drawinfo.getfont.ok:= true; + end + else begin + drawinfo.getfont.ok:= false; + end; + end; + end; + {$ifdef FPC} {$checkpointer default} {$endif} + gdi_unlock; +end; + +procedure gdi_freefontdata(var drawinfo: drawinfoty); +begin + gdi_lock; + with drawinfo.getfont.fontdata^ do begin + if fhasxft then begin + xftfontclose(appdisp,pxftfont(font)); + if fonthighres <> 0 then begin + xftfontclose(appdisp,pxftfont(fonthighres)); + end; + end + else begin + with x11fontdataty(platformdata) do begin + xfreefontinfo(nil,d.infopo,1); + xunloadfont(appdisp,font); + end; + end; + end; + gdi_unlock; +end; + +{ +const + rgbwhite: rgbtriplety = (blue: $ff; green: $ff; red: $ff; res: $00); +} +procedure graytorgb(const sdev: paintdevicety; const srect: rectty; + const ddev: paintdevicety; const dpos: pointty; const gc: pgcty); +var + putpixelfunc: function (para1:PXImage; para2:cint; + para3:cint; para4:culong):cint; cdecl; + dimage,simage: pximage; + ps,ps1,pse,pd,pd1,pde: pointer; + int1,int2: integer; + gc1: tgc; +begin + with srect do begin + simage:= xgetimage(appdisp,sdev,x,y,cx,cy,$ff,zpixmap); + if simage <> nil then begin + dimage:= xcreateimage(appdisp,defvisual,defdepth,zpixmap,0,nil, + cx,cy,32,0); + if dimage <> nil then begin + try + int1:= cy*dimage^.bytes_per_line; + getmem(dimage^.data,int1); + ps:= simage^.data; + pd:= dimage^.data; + pde:= pd+int1; + if dimage^.bits_per_pixel = 32 then begin + repeat + ps1:= ps; + pse:= ps+cx; + pd1:= pd; + repeat + pbyte(pd1)^:= pbyte(ps1)^; + inc(pd1); + pbyte(pd1)^:= pbyte(ps1)^; + inc(pd1); + pbyte(pd1)^:= pbyte(ps1)^; + inc(pd1,2); + inc(ps1); + until ps1 = pse; + ps:= ps+simage^.bytes_per_line; + pd:= pd+dimage^.bytes_per_line; + until pd = pde; + end + else begin + putpixelfunc:= dimage^.f.put_pixel; + for int1:= 0 to cy - 1 do begin + ps1:= ps; + for int2:= 0 to cx - 1 do begin + putpixelfunc(dimage,int2,int1,gui_graytopixel(pbyte(ps1)[int2])); + end; + ps:= ps+simage^.bytes_per_line; + end; + end; + except + end; + if gc <> nil then begin + gc1:= tgc(gc^.handle); + end + else begin + gc1:= creategc(ddev); + end; + xputimage(appdisp,ddev,gc1,dimage,0,0,dpos.x,dpos.y,cx,cy); + if gc = nil then begin + xfreegc(appdisp,gc1); + end; + if dimage^.data <> nil then begin + freemem(dimage^.data); + dimage^.data:= nil; + end; + xdestroyimage(dimage); + end; + xdestroyimage(simage); + end; + end; +end; + +procedure rgbtogray(const sdev: paintdevicety; const srect: rectty; + const ddev: paintdevicety; const dpos: pointty; const gc: pgcty); +var + getpixelfunc: function (para1:PXImage; para2:cint; para3:cint):culong; cdecl; + dimage,simage: pximage; + ps,ps1,pse,pd,pd1,pde: pointer; + int1,int2: integer; + wo1: word; + lwo1: word; + gc1: tgc; +begin + with srect do begin + simage:= xgetimage(appdisp,sdev,x,y,cx,cy,$ffffff,zpixmap); + if simage <> nil then begin + dimage:= xcreateimage(appdisp,defvisual,8,zpixmap,0,nil,cx,cy,32,0); + if dimage <> nil then begin + try + int1:= cy*dimage^.bytes_per_line; + getmem(dimage^.data,int1); + ps:= simage^.data; + pd:= dimage^.data; + pde:= pd+int1; + if simage^.bits_per_pixel = 32 then begin + repeat + ps1:= ps; + pse:= ps+cx*4; + pd1:= pd; + repeat + wo1:= pbyte(ps1)^; + inc(ps1); + wo1:= wo1 + pbyte(ps1)^; + inc(ps1); + pbyte(pd1)^:= (wo1 + pbyte(ps1)^) div 3; + inc(ps1,2); + inc(pd1); + until ps1 = pse; + ps:= ps+simage^.bytes_per_line; + pd:= pd+dimage^.bytes_per_line; + until pd = pde; + end + else begin + getpixelfunc:= simage^.f.get_pixel; + for int1:= 0 to cy - 1 do begin + pd1:= pd; + for int2:= 0 to cx - 1 do begin + lwo1:= getpixelfunc(simage,int2,int1); + pbyte(pd1)[int2]:= (lwo1 and $ff + ((lwo1 and $ff00) shr 8) + + ((lwo1 and $ff0000) shr 16)) div 3; + + end; + pd:= pd+dimage^.bytes_per_line; + end; + end; + except + end; + if gc <> nil then begin + gc1:= tgc(gc^.handle); + end + else begin + gc1:= creategc(ddev); + end; + xputimage(appdisp,ddev,gc1,dimage,0,0,dpos.x,dpos.y,cx,cy); + if gc = nil then begin + xfreegc(appdisp,gc1); + end; + if dimage^.data <> nil then begin + freemem(dimage^.data); + dimage^.data:= nil; + end; + xdestroyimage(dimage); + end; + xdestroyimage(simage); + end; + end; +end; + +procedure gdi_copyarea(var drawinfo: drawinfoty); //gdifunc +var + needstransform: boolean; + transform: txtransform; + + procedure updatetransform(const apic: tpicture); + begin + if needstransform then begin + xrendersetpicturetransform(appdisp,apic,@transform); + if al_intpol in drawinfo.copyarea.alignment then begin + xrendersetpicturefilter(appdisp,apic,'good',nil,0); + end; + end + end; + + function getscale(const sourcesize,destsize,sourcepos: integer; + out destpos: integer): txfixed; +// var +// int1: integer; + begin + if (sourcesize > 0) and (sourcesize <> destsize) then begin + result:= (sourcesize * $10000) div destsize; + //pixel end to pixel end + if result > 0 then begin + if sourcesize * $10000 div result < destsize then begin + dec(result); + end; + destpos:= (sourcepos * $10000 + result div 2) div result; + end + else begin + destpos:= sourcepos * $10000; //very big + end; + end + else begin + result:= $10000; + destpos:= sourcepos; + end; + end; + +var + amask: pixmapty; + xvalues: xgcvalues; + pixmap: pixmapty; + pixmapgc: tgc; + maskgc: gcty; + bitmap: pixmapty; + bitmapgc,bitmapgc2: tgc; + int1: integer; + spic,dpic,cpic,maskpic: tpicture; + sattributes: txrenderpictureattributes; + dattributes: txrenderpictureattributes; + pixmap2: pixmapty; + pictop: integer; + sourceformats: culong = cpclipmask or cpclipxorigin or cpclipyorigin; + destformats: culong = cpgraphicsexposure; + monomask: boolean; +// stipplemask: boolean; + spd: paintdevicety; + skind,dkind: bitmapkindty; + x1,y1: integer; + int2: integer; + format1: pxrenderpictformat; + ax,ay,sx,sy,dx,dy: integer; + sdev: paintdevicety; + ddev: paintdevicety; + + procedure checkddevcopy(); + begin + with drawinfo,copyarea do begin + if ddev <> paintdevice then begin + sdev:= gui_createpixmap(destrect^.size,0,bmk_gray); + rgbtogray(ddev,mr(nullpoint,destrect^.size),sdev,nullpoint,nil); + with destrect^ do begin + xcopyarea(appdisp,sdev,paintdevice,tgc(gc.handle),0,0,cx,cy,x,y); + end; + xfreepixmap(appdisp,sdev); + xfreepixmap(appdisp,ddev); + end; + end; + end; + +var + opapic,masksourcepic: tpicture; + destcopygc: tgc; + dpic2: tpicture; + ddev2: paintdevicety; +label + endlab,endlab2; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xvalues.graphics_exposures:= {$ifdef xboolean}false{$else}0{$endif}; + with drawinfo,copyarea,sourcerect^,gc,x11gcty(platformdata).d do begin + dkind:= kind; + skind:= tcanvas1(source).fdrawinfo.gc.kind; + needstransform:= (alignment * [al_stretchx,al_stretchy] <> []) and + ((destrect^.cx <> sourcerect^.cx) or + (destrect^.cy <> sourcerect^.cy)) and + (destrect^.cx > 0) and (destrect^.cy > 0); + monomask:= (mask = nil) or (mask.kind = bmk_mono); +// stipplemask:= false; + if hasxrender and (needstransform or (longword(opacity) <> maxopacity) or + not monomask) then begin + if needstransform then begin + if mask <> nil then begin + monomask:= false; //xrender ignores clip_mask for transformations + end; + transform:= unitytransform; + transform[0,0]:= getscale(cx,destrect^.cx,x,ax); + transform[1,1]:= getscale(cy,destrect^.cy,y,ay); + end + else begin + ax:= x; + ay:= y; + end; + sx:= ax; + sy:= ay; + pictop:= pictopsrc; + maskpic:= 0; + if (longword(opacity) <> maxopacity) and (mask = nil){monomask} then begin + maskpic:= createmaskpicture(opacity,bmk_rgb); + //clip_mask ignored by xrender + pictop:= pictopover; + end + else begin + if not monomask then begin + if (longword(opacity) <> maxopacity) then begin + ax:= 0; + ay:= 0; + bitmap:= gui_createpixmap(size,0,mask.kind); + if bitmap <> 0 then begin + xvalues.foreground:= 0; + bitmapgc2:= xcreategc(appdisp,bitmap, + gcforeground or gcgraphicsexposures,@xvalues); + if bitmapgc2 <> nil then begin + xfillrectangle(appdisp,bitmap,bitmapgc2,0,0,cx,cy); + xfreegc(appdisp,bitmapgc2); + opapic:= createmaskpicture(opacity,mask.kind); + masksourcepic:= createmaskpicture(mask); + maskpic:= createmaskpicture(bitmap,mask.kind); + xrendercomposite(appdisp,pictopover,masksourcepic,opapic,maskpic, + x,y,0,0,0,0,cx,cy); + xrenderfreepicture(appdisp,opapic); + xrenderfreepicture(appdisp,masksourcepic); + end; + gui_freepixmap(bitmap); + end; + end + else begin + maskpic:= createmaskpicture(mask); + end; + if not(al_nomaskscale in alignment) then begin + updatetransform(maskpic); + end; + pictop:= pictopover; + end; + end; + with sattributes do begin + clip_x_origin:= 0; + clip_y_origin:= 0; + if (mask <> nil) and monomask then begin + clip_mask:= tsimplebitmap1(mask).handle; + end + else begin + clip_mask:= 0; + end; + end; + with dattributes do begin + graphics_exposures:= 0; +// clip_mask:= sattributes.clip_mask; + end; + if (dkind <> skind) and ((dkind = bmk_mono) or (skind = bmk_mono)) then begin + if dkind = bmk_mono then begin //color to mono + if maskpic <> 0 then begin + xrenderfreepicture(appdisp,maskpic); + end; + exit; //not supported; //todo !!! + end + else begin //monochrome -> color + bitmapgc2:= nil; + bitmap:= 0; + if (mask <> nil) and (mask.kind = bmk_mono) then begin + bitmap:= gui_createpixmap(size,0,bmk_mono); + if bitmap <> 0 then begin + bitmapgc2:= xcreategc(appdisp,bitmap,gcgraphicsexposures,@xvalues); + if bitmapgc2 <> nil then begin + xcopyarea(appdisp,tcanvas1(source).fdrawinfo.paintdevice, + bitmap,bitmapgc2,x,y,cx,cy,0,0); + xvalues.xfunction:= gxand; + xchangegc(appdisp,bitmapgc2,gcfunction,@xvalues); + xcopyarea(appdisp,mask.handle,bitmap,bitmapgc2,x,y,cx,cy,0,0); + //new source = source and mask + ax:= 0; + ay:= 0; + x1:= 0; + y1:= 0; + with sattributes do begin + clip_x_origin:= 0; + clip_y_origin:= 0; + end; + end + else begin + goto endlab2; + end; + end + else begin + goto endlab2; + end; + spd:= bitmap; + end + else begin + spd:= tcanvas1(source).fdrawinfo.paintdevice; + x1:= x; + y1:= y; + end; + spic:= xrendercreatepicture(appdisp,spd,bitmaprenderpictformat, + sourceformats,@sattributes); + format1:= screenrenderpictformat; + dx:= destrect^.x; + dy:= destrect^.y; + ddev:= paintdevice; + if (maskpic <> 0) or (dkind = bmk_gray) then begin + //bmk_gray is alpha only -> needs rgb copy + dx:= 0; + dy:= 0; + ddev:= gui_createpixmap(destrect^.size,0,bmk_rgb); + if dkind = bmk_gray then begin + graytorgb(paintdevice,destrect^,ddev,nullpoint,nil); + if maskpic <> 0 then begin //get original copy + ddev2:= gui_createpixmap(destrect^.size,0,bmk_rgb); + destcopygc:= xcreategc(appdisp,ddev,gcgraphicsexposures, + @xvalues); + with destrect^ do begin + xcopyarea(appdisp,ddev,ddev2,destcopygc,0,0,cx,cy,0,0); + end; + xfreegc(appdisp,destcopygc); + end; + end + else begin + destcopygc:= xcreategc(appdisp,ddev,gcgraphicsexposures, + @xvalues); + with destrect^ do begin + xcopyarea(appdisp,paintdevice,ddev,destcopygc,x,y,cx,cy,0,0); + end; + xfreegc(appdisp,destcopygc); + ddev2:= paintdevice; //use original destination + end; + end; + dpic:= xrendercreatepicture(appdisp,ddev,format1, + destformats,@dattributes); + pictop:= pictopover; + if dkind = bmk_gray then begin + cpic:= creategraycolorpicture(acolorforeground); + end + else begin + cpic:= createcolorpicture(acolorforeground); + end; + if (gcclipregion <> 0) and (ddev = paintdevice) then begin + setregion(gc,region(gcclipregion),dpic); + end; + updatetransform(spic); + if acolorforeground <> cl_transparent then begin + xrendercomposite(appdisp,pictop,cpic,spic,dpic,0,0,ax,ay, + dx,dy,destrect^.cx,destrect^.cy); + end; + xrenderfreepicture(appdisp,cpic); + if df_opaque in gc.drawingflags then begin + if bitmap <> 0 then begin + xvalues.xfunction:= gxorinverted; + xchangegc(appdisp,bitmapgc2,gcfunction,@xvalues); + xcopyarea(appdisp,mask.handle,bitmap,bitmapgc2,x,y,cx,cy,0,0); + end; + xvalues.xfunction:= gxxor; + xvalues.foreground:= $ffffffff; + bitmapgc:= xcreategc(appdisp,spd, + gcforeground or gcfunction or gcgraphicsexposures,@xvalues); + xfillrectangle(appdisp,spd,bitmapgc,x1,y1,cx,cy); + if dkind = bmk_gray then begin + cpic:= creategraycolorpicture(acolorbackground); + end + else begin + cpic:= createcolorpicture(acolorbackground); + end; + xrendercomposite(appdisp,pictop,cpic,spic,dpic,0,0,ax,ay, + dx,dy,destrect^.cx,destrect^.cy); + xrenderfreepicture(appdisp,cpic); + xfillrectangle(appdisp,spd,bitmapgc,x1,y1,cx,cy); + xfreegc(appdisp,bitmapgc); + end; + xrenderfreepicture(appdisp,spic); + if maskpic <> 0 then begin + dpic2:= xrendercreatepicture(appdisp,ddev2,format1, + destformats,@dattributes); + with destrect^ do begin + xrendercomposite(appdisp,pictop,dpic,maskpic,dpic2,0,0,ax,ay,x,y,cx,cy); + end; + xrenderfreepicture(appdisp,dpic2); + xfreepixmap(appdisp,ddev); + if dkind = bmk_gray then begin + ddev:= ddev2; + end + else begin + ddev:= paintdevice; //no checkddevcopy() + end; + end; + xrenderfreepicture(appdisp,dpic); + checkddevcopy(); //possibly rgb -> gray conversion +endlab2: + if maskpic <> 0 then begin + xrenderfreepicture(appdisp,maskpic); + end; + if bitmapgc2 <> nil then begin + xfreegc(appdisp,bitmapgc2); + end; + if bitmap <> 0 then begin + xfreepixmap(appdisp,bitmap); + end; + end; + end + else begin //no colorconvert + if al_nomaskscale in alignment then begin + ax:= ax + maskshift.x; + ay:= ay + maskshift.y; + end + else begin + ax:= ax + maskshiftscaled.x; + ay:= ay + maskshiftscaled.y; + end; + dx:= destrect^.x; + dy:= destrect^.y; + format1:= screenrenderpictformat; + sdev:= tcanvas1(source).paintdevice; + ddev:= paintdevice; + if skind = bmk_gray then begin + sx:= 0; + sy:= 0; + sdev:= gui_createpixmap(sourcerect^.size,0,bmk_rgb); + graytorgb(tcanvas1(source).paintdevice,sourcerect^,sdev,nullpoint,nil); + end; + if dkind = bmk_gray then begin + dx:= 0; + dy:= 0; + ddev:= gui_createpixmap(destrect^.size,0,bmk_rgb); + graytorgb(paintdevice,destrect^,ddev,nullpoint,nil); + end; + spic:= xrendercreatepicture(appdisp,sdev,format1, + sourceformats,@sattributes); + dpic:= xrendercreatepicture(appdisp,ddev,format1, + destformats,@dattributes); + if (gcclipregion <> 0) and (ddev = paintdevice) then begin + setregion(gc,region(gcclipregion),dpic); + end; + updatetransform(spic); + xrendercomposite(appdisp,pictop,spic,maskpic,dpic,sx,sy,ax,ay, + dx,dy,destrect^.cx,destrect^.cy); + xrenderfreepicture(appdisp,spic); + xrenderfreepicture(appdisp,dpic); + if sdev <> tcanvas1(source).paintdevice then begin + xfreepixmap(appdisp,sdev); + end; + checkddevcopy(); + if maskpic <> 0 then begin + xrenderfreepicture(appdisp,maskpic); + end; + end; + end + else begin //direct x11 + pixmap2:= 0; + if copymode <> gcrasterop then begin + xsetfunction(appdisp,tgc(gc.handle),integer(copymode)); + end; + if mask <> nil then begin + amask:= tsimplebitmap1(mask).handle; + if gcclipregion <> 0 then begin + pixmap2:= gui_createpixmap(size,0,bmk_mono); + maskgc.handle:= ptruint(xcreategc(appdisp,pixmap2,gcgraphicsexposures, + @xvalues)); + xfillrectangle(appdisp,pixmap2,tgc(maskgc.handle),0,0,cx,cy); + maskgc.cliporigin:= subpoint(cliporigin,destrect^.pos); + setregion(maskgc,region(gcclipregion)); + xcopyarea(appdisp,amask,pixmap2,tgc(maskgc.handle), + x+maskshiftscaled.x,y+maskshiftscaled.y,cx,cy,0,0); + xvalues.clip_x_origin:= destrect^.x; + xvalues.clip_y_origin:= destrect^.y; + xvalues.clip_mask:= pixmap2; + xchangegc(appdisp,tgc(gc.handle),gcclipxorigin or gcclipyorigin or + gcclipmask,@xvalues); + xfreegc(appdisp,tgc(maskgc.handle)); + end + else begin + xvalues.clip_mask:= amask; + xvalues.clip_x_origin:= destrect^.x - x - maskshiftscaled.x; + xvalues.clip_y_origin:= destrect^.y - y - maskshiftscaled.y; + xchangegc(appdisp,tgc(gc.handle),gcclipxorigin or gcclipyorigin or + gcclipmask,@xvalues); + end; + end; + if skind = dkind then begin + xcopyarea(appdisp,tcanvas1(source).fdrawinfo.paintdevice,paintdevice, + tgc(gc.handle),x,y,cx,cy,destrect^.x,destrect^.y); + end + else begin + if (skind = bmk_gray) and (dkind = bmk_rgb) then begin + graytorgb(tcanvas1(source).fdrawinfo.paintdevice,sourcerect^, + paintdevice,destrect^.pos,@gc); + end + else begin + if (skind = bmk_rgb) and (dkind = bmk_gray) then begin + rgbtogray(tcanvas1(source).fdrawinfo.paintdevice,sourcerect^, + paintdevice,destrect^.pos,@gc); + end + else begin + if dkind = bmk_mono then begin //convert to monochrome + pixmap:= gui_createpixmap(size,0,skind); + if pixmap = 0 then begin + goto endlab; + end; + pixmapgc:= xcreategc(appdisp,pixmap,gcgraphicsexposures,@xvalues); + if pixmapgc <> nil then begin + xcopyarea(appdisp,tcanvas1(source).fdrawinfo.paintdevice,pixmap, + pixmapgc,x,y,cx,cy,0,0); + xvalues.foreground:= transparentcolor; + xvalues.xfunction:= integer(rop_xor); + xchangegc(appdisp,pixmapgc,gcforeground or gcfunction,@xvalues); + xfillrectangle(appdisp,pixmap,pixmapgc,0,0,cx,cy); + bitmap:= gui_createpixmap(size,0,bmk_mono); + if bitmap <> 0 then begin + xvalues.foreground:= pixel0; + bitmapgc:= xcreategc(appdisp,bitmap, + gcforeground or gcgraphicsexposures,@xvalues); + if bitmapgc <> nil then begin + xfillrectangle(appdisp,bitmap,bitmapgc,0,0,cx,cy); + xvalues.xfunction:= integer(rop_or); + xvalues.background:= pixel0; + xvalues.foreground:= pixel1; + xchangegc(appdisp,bitmapgc,gcfunction or gcforeground or + gcbackground,@xvalues); + if skind = bmk_gray then begin + int2:= 8; + end + else begin + int2:= defdepth; + end; + for int1:= 0 to int2-1 do begin + xcopyplane(appdisp,pixmap,bitmap,bitmapgc,0,0,cx,cy, + 0,0,1 shl int1); + end; + xcopyarea(appdisp,bitmap,paintdevice,tgc(gc.handle),0,0,cx,cy, + destrect^.x,destrect^.y); + xfreegc(appdisp,bitmapgc); + end; + xfreepixmap(appdisp,bitmap) + end; + xfreegc(appdisp,pixmapgc); + end; + xfreepixmap(appdisp,pixmap); + end + else begin + //convert from monochrome +// stipplemask:= true; + pixmapgc:= xcreategc(appdisp,paintdevice,gcgraphicsexposures,@xvalues); + if pixmapgc <> nil then begin + xcopygc(appdisp,tgc(gc.handle),gcfunction or gcplanemask or + gcsubwindowmode or gcgraphicsexposures or gcclipxorigin or + gcclipyorigin or gcclipmask or gcforeground or gcbackground,pixmapgc); + with xvalues do begin + stipple:= tcanvas1(source).fdrawinfo.paintdevice; + ts_x_origin:= destrect^.x-x; + ts_y_origin:= destrect^.y-y; + if df_opaque in gc.drawingflags then begin + fill_style:= fillopaquestippled; + end + else begin + fill_style:= fillstippled; + end; + end; + xchangegc(appdisp,pixmapgc,gcfillstyle or gcstipple or + gctilestipxorigin or gctilestipyorigin,@xvalues); + xfillrectangle(appdisp,paintdevice,pixmapgc,destrect^.x,destrect^.y,cx,cy); + xfreegc(appdisp,pixmapgc); + end; + end; + end; + end; + end; + if mask <> nil then begin + xvalues.clip_x_origin:= 0; + xvalues.clip_y_origin:= 0; + xchangegc(appdisp,tgc(gc.handle),gcclipxorigin or gcclipyorigin,@xvalues); + end; + if copymode <> gcrasterop then begin + xsetfunction(appdisp,tgc(gc.handle),integer(gcrasterop)); + end; +endlab: + if pixmap2 <> 0 then begin + xfreepixmap(appdisp,pixmap2); + end; + end; + end; +end; + +procedure gdi_getimage(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_fonthasglyph(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,fonthasglyph do begin + if fhasxft then begin + hasglyph:= xftcharexists(appdisp,pxftfont(font),unichar); + end + else begin + hasglyph:= true; + end; + end; +end; + +procedure gdi_drawlines(var drawinfo: drawinfoty); //gdifunc +var + po1: ppointty; + pointcount: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,points,x11gcty(gc.platformdata).d do begin + if xfts_smooth in xftstate then begin + if linestria(drawinfo,po1,pointcount) then begin + compositetriangles(drawinfo,ptrianglety(po1),pointcount div 3); + end + else begin + compositetristrip(drawinfo,po1,pointcount); + end; + end + else begin + transformpoints(drawinfo,closed); + pointcount:= count; + if closed then begin + inc(pointcount); + end; + xdrawlines(appdisp,paintdevice,tgc(gc.handle),buffer.buffer,pointcount, + coordmodeorigin); + end; + end; +end; + +procedure gdi_drawlinesegments(var drawinfo: drawinfoty); //gdifunc +var + triacount: integer; + po1: ptrianglety; + +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,drawinfo.points,x11gcty(gc.platformdata).d do begin + if xfts_smooth in xftstate then begin + linesegmentstria(drawinfo,po1,triacount); + compositetriangles(drawinfo,po1,triacount); + end + else begin + transformpoints(drawinfo,false); + xdrawsegments(appdisp,paintdevice,tgc(gc.handle),buffer.buffer,count div 2); + end; + end; +end; + +procedure gdi_fillellipse(var drawinfo: drawinfoty); //gdifunc +var + po1: ppointty; + pointcount: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,drawinfo.rect.rect^ do begin + if xfts_smooth in x11gcty(gc.platformdata).d.xftstate then begin + fillellipsetria(drawinfo,po1,pointcount); + with x11gcty(gc.platformdata).d do begin + compositetrifan(drawinfo,po1,pointcount); + end; + end + else begin + xfillarc(appdisp,paintdevice,tgc(gc.handle), + x+origin.x-cx div 2,y+origin.y - cy div 2,cx,cy,0,wholecircle); + end; + end; +end; + +const + angscale = 64*360/(2*pi); + +procedure gdi_fillarc(var drawinfo: drawinfoty); //gdifunc +var + xvalues: xgcvalues; + po1: ppointty; + pointcount: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,x11gcty(gc.platformdata).d,drawinfo.arc,rect^ do begin + if xfts_smooth in xftstate then begin + fillarctria(drawinfo,po1,pointcount); + compositetrifan(drawinfo,po1,pointcount); + end + else begin + if pieslice then begin + xvalues.arc_mode:= arcpieslice; + end + else begin + xvalues.arc_mode:= arcchord; + end; + xchangegc(appdisp,tgc(gc.handle),gcarcmode,@xvalues); + xfillarc(appdisp,paintdevice,tgc(gc.handle), + x+origin.x-cx div 2,y+origin.y - cy div 2,cx,cy, + round(startang*angscale),round(extentang*angscale)); + end; + end; +end; + +procedure gdi_drawarc(var drawinfo: drawinfoty); //gdifunc +var + po1: ppointty; + pointcount: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,x11gcty(gc.platformdata).d,drawinfo.arc,rect^, + triagcty(gc.platformdata).d do begin + if xfts_smooth in xftstate then begin + if arctria(drawinfo,po1,pointcount) then begin + compositetriangles(drawinfo,ptrianglety(po1),pointcount div 3); + end + else begin + compositetristrip(drawinfo,po1,pointcount); + end; + end + else begin + xdrawarc(appdisp,paintdevice,tgc(gc.handle), + x+origin.x-cx div 2,y+origin.y - cy div 2,cx,cy, + round(startang*angscale),round(extentang*angscale)); + end; + end; +end; + +procedure gdi_drawellipse(var drawinfo: drawinfoty); //gdifunc +var + po1: ppointty; + pointcount: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,x11gcty(gc.platformdata).d,rect.rect^ do begin + if xfts_smooth in xftstate then begin + with x11gcty(gc.platformdata).d do begin + if ellipsetria(drawinfo,po1,pointcount) then begin + compositetriangles(drawinfo,ptrianglety(po1),pointcount div 3); + end + else begin + compositetristrip(drawinfo,po1,pointcount); + end; + end; + end + else begin + xdrawarc(appdisp,paintdevice,tgc(gc.handle), + x+origin.x-cx div 2,y+origin.y - cy div 2,cx,cy,0,wholecircle); + end; + end; +end; + +procedure gdi_drawstring16(var drawinfo: drawinfoty); //gdifunc +var + po1: pxchar2b; + xvalues: xgcvalues; + glyphinfo: txglyphinfo; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,drawinfo.text16pos do begin + if fhasxft then begin + {$ifdef FPC}{$checkpointer off}{$endif} + checkxftdraw(drawinfo); + checkxftstate(drawinfo,[]); + transformpos(drawinfo); + with pxpoint(buffer.buffer)^ do begin + with x11gcty(gc.platformdata).d do begin + if df_opaque in gc.drawingflags then begin + xfttextextentsutf16(appdisp,xftfont,pointer(text),fcendianlittle, + count*2,@glyphinfo); + xvalues.foreground:= xftcolorbackground.pixel; + xchangegc(appdisp,tgc(gc.handle),gcforeground,@xvalues); + with x11gcty(gc.platformdata).d.xftfontdata^ do begin + case xftdirection of + gd_right: begin + xfillrectangle(appdisp,paintdevice,tgc(gc.handle), + x{-glyphinfo.x},y-xftascent, + glyphinfo.xoff,xftascent+xftdescent); + end; + gd_up: begin + xfillrectangle(appdisp,paintdevice,tgc(gc.handle), + x-xftascent,y+glyphinfo.yoff, + xftascent+xftdescent,-glyphinfo.yoff); + end; + gd_left: begin + xfillrectangle(appdisp,paintdevice,tgc(gc.handle), + x+glyphinfo.xoff{-glyphinfo.x},y-xftdescent, + -glyphinfo.xoff,xftascent+xftdescent); + end; + gd_down: begin + xfillrectangle(appdisp,paintdevice,tgc(gc.handle), + x-xftdescent,y, + xftascent+xftdescent,glyphinfo.yoff); + end; + end; + end; + xvalues.foreground:= xftcolor.pixel; + xchangegc(appdisp,tgc(gc.handle),gcforeground,@xvalues); + end; + xftdrawstringutf16(xftdraw,@xftcolor,xftfont,x,y,pointer(text), + fcendianlittle,count*2); + end; + end +{$ifdef FPC}{$checkpointer default}{$endif} + end + else begin + po1:= transformtext16pos(drawinfo); //swap bytes + with pxpoint(buffer.buffer)^ do begin + if df_opaque in gc.drawingflags then begin + xdrawimagestring16(appdisp,paintdevice,tgc(gc.handle),x,y,po1,count); + end + else begin + xdrawstring16(appdisp,paintdevice,tgc(gc.handle),x,y,po1,count); + end; + end; + end; + end; +end; + +procedure gdi_setcliporigin(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,gc do begin + xsetcliporigin(appdisp,tgc(handle),cliporigin.x,cliporigin.y); + end; +end; + +procedure gdi_fillrect(var drawinfo: drawinfoty); //gdifunc +var + points1: array[0..3] of xpoint; + x1,y1: smallint; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,drawinfo.rect.rect^ do begin + x1:= x+origin.x; + y1:= y+origin.y; + points1[0].x:= x1; + points1[0].y:= y1; + points1[1].y:= y1; + points1[3].x:= x1; + inc(x1,cx); + inc(y1,cy); + points1[1].x:= x1; + points1[2].x:= x1; + points1[2].y:= y1; + points1[3].y:= y1; + + xfillpolygon(appdisp,paintdevice,tgc(gc.handle),@points1[0],4, + complex,coordmodeorigin); + end; +end; + +procedure gdi_fillpolygon(var drawinfo: drawinfoty); //gdifunc +var + int1: integer; + po1,po2: pxpointfixed; + po3: ppointty; +// offsx,offsy: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo do begin + if xfts_smooth in x11gcty(gc.platformdata).d.xftstate then begin + if points.count > 2 then begin + polytria(drawinfo,ptrianglety(po3),int1); + if int1 > 0 then begin + po1:= pointer(po3); + po2:= pointer(ptrianglety(po3)+int1); + repeat + po1^.x:= po1^.x << 16; + po1^.y:= po1^.y << 16; + inc(po1); + until po1 = po2; + compositetriangles(drawinfo,ptrianglety(po3),int1); + end; + end; + end + else begin + transformpoints(drawinfo,false); + with points do begin + xfillpolygon(appdisp,paintdevice,tgc(gc.handle),buffer.buffer, + count,complex,coordmodeorigin); + end; + end; + end; +end; + + +function createregion: regionty; overload; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= regionty(xcreateregion()); +end; + +function recttoxrect(const rect: rectty): xrectangle; +begin + with rect do begin + result.x:= x; + result.y:= y; + result.width:= cx; + result.height:= cy; + end; +end; + +function createregion(const rect: rectty): regionty; overload; +var + rect1: xrectangle; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= regionty(xcreateregion); + rect1:= recttoxrect(rect); + xunionrectwithregion(@rect1,region(result),region(result)); +end; + +procedure gdi_createemptyregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + dest:= createregion; + end; +end; + +procedure gdi_createrectregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + dest:= createregion(rect); + end; +end; + +procedure gdi_createrectsregion(var drawinfo: drawinfoty); //gdifunc +var + int1: integer; + rect1: xrectangle; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + dest:= createregion; + for int1:= 0 to rectscount - 1 do begin + rect1:= recttoxrect(rectspo^[int1]); + xunionrectwithregion(@rect1,region(dest),region(dest)); + end; + end; +end; + +procedure gdi_destroyregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + if source <> 0 then begin + xdestroyregion(region(source)); + end; + end; +end; + +procedure gdi_regionisempty(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + dest:= xemptyregion(region(source)); + if dest <> 0 then begin + dest:= 1; + end; + end; +end; + +procedure gdi_regionclipbox(var drawinfo: drawinfoty); //gdifunc +var + rect1: xrectangle; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + xclipbox(region(source),@rect1); + rect.x:= rect1.x; + rect.y:= rect1.y; + rect.cx:= rect1.width; + rect.cy:= rect1.height; + end; +end; + +procedure gdi_copyregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + if source = 0 then begin + dest:= 0; + end + else begin + dest:= ptruint(xcreateregion); + xunionregion(region(dest),region(source),region(dest)); + end; + end; +end; + +procedure gdi_moveregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + xoffsetregion(region(source),rect.x,rect.y); + end; +end; + +procedure gdi_regsubrect(var drawinfo: drawinfoty); //gdifunc +var + reg1: region; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + reg1:= region(createregion(rect)); + xsubtractregion(region(dest),reg1,region(dest)); + xdestroyregion(reg1); + end; +end; + +procedure gdi_regintersectrect(var drawinfo: drawinfoty); //gdifunc +var + reg1: region; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + reg1:= region(createregion(rect)); + xintersectregion(region(dest),reg1,region(dest)); + xdestroyregion(reg1); + end; +end; + +procedure gdi_regintersectregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + xintersectregion(region(dest),region(source),region(dest)); + end; +end; + +procedure gdi_regaddrect(var drawinfo: drawinfoty); //gdifunc +var + rect1: xrectangle; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + rect1:= recttoxrect(rect); + xunionrectwithregion(@rect1,region(dest),region(dest)); + end; +end; + +procedure gdi_regaddregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + xunionregion(region(dest),region(source),region(dest)); + end; +end; + +procedure gdi_regsubregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + xsubtractregion(region(dest),region(source),region(dest)); + end; +end; + +function hasxft: boolean; +begin + result:= fhasxft; +end; + +var + fhasfontconfig: boolean; + +function getxftlib: boolean; +const + funcs: array[0..21] of funcinfoty = ( + (n: 'XftDrawDestroy'; d: @XftDrawDestroy), + (n: 'XftDrawSetClipRectangles'; d: @XftDrawSetClipRectangles), + (n: 'XftDrawCreate'; d: @XftDrawCreate), + (n: 'XftDrawSetClip'; d: @XftDrawSetClip), + (n: 'XftTextExtents16'; d: @XftTextExtents16), + (n: 'XftTextExtentsUtf16'; d: @XftTextExtentsUtf16), + (n: 'XftTextExtents32'; d: @XftTextExtents32), + (n: 'XftFontOpenName'; d: @XftFontOpenName), + (n: 'XftFontClose'; d: @XftFontClose), + (n: 'XftDrawString16'; d: @XftDrawString16), + (n: 'XftDrawStringUtf16'; d: @XftDrawStringUtf16), + (n: 'XftDefaultHasRender'; d: @XftDefaultHasRender), + (n: 'XftGetVersion'; d: @XftGetVersion), + (n: 'XftInit'; d: @XftInit), + (n: 'XftInitFtLibrary'; d: @XftInitFtLibrary), + (n: 'XftCharExists'; d: @XftCharExists), + (n: 'XftNameParse'; d: @XftNameParse), + (n: 'XftFontMatch'; d: @XftFontMatch), + (n: 'XftFontOpenPattern'; d: @XftFontOpenPattern), + (n: 'XftDefaultSubstitute'; d: @XftDefaultSubstitute), + (n: 'XftDrawPicture'; d: @XftDrawPicture), + (n: 'XftDrawSrcPicture'; d: @XftDrawSrcPicture) + ); +begin +{$ifndef staticxft} + result:= false; + initializefontconfig([]); + fhasfontconfig:= true; + if getprocaddresses(xftnames,funcs,true) = 0 then begin + exit; + end; +{$endif} //not staticxft + result:= true; +end; + +function getxrenderlib: boolean; +const + funcs: array[0..14] of funcinfoty = ( + (n: 'XRenderSetPictureClipRectangles'; + d: {$ifndef FPC}@{$endif}@XRenderSetPictureClipRectangles), + (n: 'XRenderCreatePicture'; d: {$ifndef FPC}@{$endif}@XRenderCreatePicture), + (n: 'XRenderFillRectangle'; d: {$ifndef FPC}@{$endif}@XRenderFillRectangle), + (n: 'XRenderSetPictureTransform'; + d: {$ifndef FPC}@{$endif}@XRenderSetPictureTransform), + (n: 'XRenderSetPictureFilter'; + d: {$ifndef FPC}@{$endif}@XRenderSetPictureFilter), + (n: 'XRenderFreePicture'; d: {$ifndef FPC}@{$endif}@XRenderFreePicture), + (n: 'XRenderComposite'; d: {$ifndef FPC}@{$endif}@XRenderComposite), + (n: 'XRenderQueryExtension'; + d: {$ifndef FPC}@{$endif}@XRenderQueryExtension), + (n: 'XRenderFindVisualFormat'; + d: {$ifndef FPC}@{$endif}@XRenderFindVisualFormat), + (n: 'XRenderFindStandardFormat'; + d: {$ifndef FPC}@{$endif}@XRenderFindStandardFormat), + (n: 'XRenderCompositeTriStrip'; + d: {$ifndef FPC}@{$endif}@XRenderCompositeTriStrip), + (n: 'XRenderCompositeTriFan'; + d: {$ifndef FPC}@{$endif}@XRenderCompositeTriFan), + (n: 'XRenderCompositeTriangles'; + d: {$ifndef FPC}@{$endif}@XRenderCompositeTriangles), + (n: 'XRenderChangePicture'; + d: {$ifndef FPC}@{$endif}@XRenderChangePicture), + (n: 'XRenderFindFormat'; + d: {$ifndef FPC}@{$endif}@XRenderFindFormat) + ); + + funcsopt: array[0..1] of funcinfoty = ( + (n: 'XRenderCreateSolidFill'; + d: {$ifndef FPC}@{$endif}@XRenderCreateSolidFill), + (n: 'XRenderSetPictureClipRegion'; + d: {$ifndef FPC}@{$endif}@XRenderSetPictureClipRegion) + ); + +var + handle: tlibhandle; +begin + handle:= getprocaddresses(xrendernames,funcs,true); + result:= handle <> 0; + if result then begin + getprocaddresses(handle,funcsopt,true); + if xrendercreatesolidfill <> nil then begin + createcolorpic:= @createcolorpic2; + end + else begin + createcolorpic:= @createcolorpic1; + end; + end; +end; + +const + gdifunctions: gdifunctionaty = ( + {$ifdef FPC}@{$endif}gdi_creategc, + {$ifdef FPC}@{$endif}gdi_destroygc, + {$ifdef FPC}@{$endif}gdi_changegc, + {$ifdef FPC}@{$endif}gdi_createpixmap, + {$ifdef FPC}@{$endif}gdi_pixmaptoimage, + {$ifdef FPC}@{$endif}gdi_imagetopixmap, + {$ifdef FPC}@{$endif}gdi_getcanvasclass, + {$ifdef FPC}@{$endif}gdi_endpaint, + {$ifdef FPC}@{$endif}gdi_flush, + {$ifdef FPC}@{$endif}gdi_movewindowrect, + {$ifdef FPC}@{$endif}gdi_drawlines, + {$ifdef FPC}@{$endif}gdi_drawlinesegments, + {$ifdef FPC}@{$endif}gdi_drawellipse, + {$ifdef FPC}@{$endif}gdi_drawarc, + {$ifdef FPC}@{$endif}gdi_fillrect, + {$ifdef FPC}@{$endif}gdi_fillellipse, + {$ifdef FPC}@{$endif}gdi_fillarc, + {$ifdef FPC}@{$endif}gdi_fillpolygon, + {$ifdef FPC}@{$endif}gdi_drawstring16, + {$ifdef FPC}@{$endif}gdi_setcliporigin, + {$ifdef FPC}@{$endif}gdi_createemptyregion, + {$ifdef FPC}@{$endif}gdi_createrectregion, + {$ifdef FPC}@{$endif}gdi_createrectsregion, + {$ifdef FPC}@{$endif}gdi_destroyregion, + {$ifdef FPC}@{$endif}gdi_copyregion, + {$ifdef FPC}@{$endif}gdi_moveregion, + {$ifdef FPC}@{$endif}gdi_regionisempty, + {$ifdef FPC}@{$endif}gdi_regionclipbox, + {$ifdef FPC}@{$endif}gdi_regsubrect, + {$ifdef FPC}@{$endif}gdi_regsubregion, + {$ifdef FPC}@{$endif}gdi_regaddrect, + {$ifdef FPC}@{$endif}gdi_regaddregion, + {$ifdef FPC}@{$endif}gdi_regintersectrect, + {$ifdef FPC}@{$endif}gdi_regintersectregion, + {$ifdef FPC}@{$endif}gdi_copyarea, + {$ifdef FPC}@{$endif}gdi_getimage, + {$ifdef FPC}@{$endif}gdi_fonthasglyph, + {$ifdef FPC}@{$endif}gdi_getfont, + {$ifdef FPC}@{$endif}gdi_getfonthighres, + {$ifdef FPC}@{$endif}gdi_freefontdata, + {$ifdef FPC}@{$endif}gdi_gettext16width, + {$ifdef FPC}@{$endif}gdi_getchar16widths, + {$ifdef FPC}@{$endif}gdi_getfontmetrics +); + +//var +// gdinumber: integer; + +function x11getgdifuncs: pgdifunctionaty; +begin + result:= @gdifunctions; +end; +{ +function x11getgdinum: integer; +begin + result:= gdinumber; +end; +} +initialization +// zerolineworkaround:= true; + fhasxft:= getxftlib; + hasxrender:= getxrenderlib; +// gdinumber:= registergdi(x11getgdifuncs); +finalization + if fhasfontconfig then begin + releasefontconfig; + end; +end. diff --git a/mseide-msegui/lib/common/i18n/msei18nglob.pas b/mseide-msegui/lib/common/i18n/msei18nglob.pas new file mode 100644 index 0000000..0e43fde --- /dev/null +++ b/mseide-msegui/lib/common/i18n/msei18nglob.pas @@ -0,0 +1,26 @@ +{ MSEgui Copyright (c) 2005-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msei18nglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + registerlangname = 'registerlang'; + unregisterlangname = 'unregisterlang'; +type + registermodulety = procedure(datapo: pointer; //pobjectdataty + const objectclassname: shortstring; + const name: shortstring); cdecl; + registerresourcety = procedure(datapo: pointer); cdecl; + //pobjectdataty + +// procedure registerlang(const registerlangmoduleproc: registerlangmodulety); + +implementation +end. diff --git a/mseide-msegui/lib/common/i18n/msei18nutils.pas b/mseide-msegui/lib/common/i18n/msei18nutils.pas new file mode 100644 index 0000000..e953e5e --- /dev/null +++ b/mseide-msegui/lib/common/i18n/msei18nutils.pas @@ -0,0 +1,359 @@ +{ MSEgui Copyright (c) 2005-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msei18nutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +{$undef internalresstrhandling} +{$ifndef FPC} + {$define internalresstrhandling} +{$endif} + +{$if fpc_fullversion >= 30000} + {$define mse_fpc_3} +{$endif} + +(* +{$ifdef FPC} + {$if fpc_fullversion < 20301} + {$ifndef VER2_2}{$define internalresstrhandling}{$endif} + {$endif} +{$endif} +*) + +interface +uses + msetypes,msei18nglob,msefileutils; +//todo: optimize resourcestring loading +// wide resourcestrings + +function loadlangunit(aname: string; + const quiet: boolean = false): boolean; + //'' -> reset to builtin + //true if ok +procedure registermodule(datapo: pointer; //pobjectdataty + const objectclassname: shortstring; + const name: shortstring); cdecl; +procedure unregistermodule(datapo: pointer; //pobjectdataty + const objectclassname: shortstring; + const name: shortstring); cdecl; +procedure registerresourcestrings(datapo: pointer); cdecl; +{$ifdef internalresstrhandling} +procedure unregisterresourcestrings(datapo: pointer); cdecl; +{$endif} + +implementation +uses + {$ifdef FPC}dynlibs,{$ifdef UNIX}dl,{$endif}{$endif}sysutils,mseclasses, + mselist,msearrayutils,msestrings,mseapplication,msesysintf; + +type + resourcestringinfoty = record + name: string; + value: msestring; + end; + presourcestringinfoty = ^resourcestringinfoty; + + tresourcestringlist = class(torderedrecordlist) + protected + function getcomparefunc: sortcomparemethodty; override; + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + function compare(const l,r): integer; + public + constructor create; + procedure readvalues(data: pobjectdataty); + function find(const aname: string; out po: presourcestringinfoty): boolean; + end; + +{$ifdef internalresstrhandling} +Type //copied from objpas.pp + + PResourceStringRecord = ^TResourceStringRecord; + TResourceStringRecord = Packed Record + DefaultValue, + CurrentValue : AnsiString; + HashValue : longint; + Name : AnsiString; + end; + + TResourceStringTable = Packed Record + Count : longint; + Resrec : Array[Word] of TResourceStringRecord; + end; + PResourceStringTable = ^TResourceStringTable; + + TResourceTableList = Packed Record + Count : longint; + Tables : Array[Word] of PResourceStringTable; + end; + + +Var + ResourceStringTable : TResourceTablelist; + {$ifdef FPC} External Name 'FPC_RESOURCESTRINGTABLES';{$endif} + //todo: fix for delphi +{$endif} + +var + langlibhandle: {$ifdef FPC}tlibhandle{$else}hmodule{$endif}; +type + registerlangty = procedure(const registermoduleproc: registermodulety; + const registerresourceproc: registerresourcety); + +procedure registermodule(datapo: pointer; const objectclassname: shortstring; + const name: shortstring); cdecl; +begin + registerobjectdata(pobjectdataty(datapo),objectclassname,name); +end; + +procedure unregistermodule(datapo: pointer; const objectclassname: shortstring; + const name: shortstring); cdecl; +begin + unregisterobjectdata(objectclassname,name); +end; + +{$ifndef internalresstrhandling} +Function setresstr(Name,Value: AnsiString; Hash: Longint; + arg: pointer) : AnsiString; +var + po1: presourcestringinfoty; +begin + if tresourcestringlist(arg).find(name,po1) then begin + {$ifdef mse_fpc_3} + result:= ''; + utf8string(pointer(result)):= stringtoutf8(po1^.value); + {$else} + result:= po1^.value; + {$endif} + end + else begin + result:= ''; + end; +end; + +Function unsetresstr(Name,Value: AnsiString; Hash: Longint; + arg: pointer) : AnsiString; +var + po1: presourcestringinfoty; +begin + if tresourcestringlist(arg).find(name,po1) then begin + result:= value; + end + else begin + result:= ''; + end; +end; +{$endif} + +procedure registerresourcestrings(datapo: pointer); cdecl; +{$ifdef FPC} +var + list1: tresourcestringlist; +{$ifdef internalresstrhandling} + int1,int2: integer; + po1: presourcestringinfoty; +{$endif} +{$endif} +begin +{$ifdef FPC} + list1:= tresourcestringlist.create; + try + list1.readvalues(pobjectdataty(datapo)); +{$ifndef internalresstrhandling} + setresourcestrings(@setresstr,list1); +{$else} + for int1:= 0 to resourcestringtable.count - 1 do begin + with resourcestringtable.tables[int1]^ do begin + for int2:= 0 to count - 1 do begin + with resrec[int2] do begin + if list1.find(name,po1) then begin + currentvalue:= po1^.value; + end; + end; + end; + end; + end; +{$endif} + finally + list1.free; + end; +{$endif} +end; + +procedure unregisterresourcestrings(datapo: pointer); cdecl; +var + list1: tresourcestringlist; +{$ifdef internalresstrhandling} + int1,int2: integer; + po1: presourcestringinfoty; +{$endif} +begin + list1:= tresourcestringlist.create; + try + list1.readvalues(pobjectdataty(datapo)); +{$ifndef internalresstrhandling} + setresourcestrings(@unsetresstr,list1); +{$else} + for int1:= 0 to resourcestringtable.count - 1 do begin + with resourcestringtable.tables[int1]^ do begin + for int2:= 0 to count - 1 do begin + with resrec[int2] do begin + if list1.find(name,po1) then begin + currentvalue:= defaultvalue; + end; + end; + end; + end; + end; +{$endif} + finally + list1.free; + end; +end; + +function loadlangunit(aname: string; const quiet: boolean = false): boolean; + //true if ok +var + reglang: registerlangty; +{$ifndef windows} + fdir,fname: filenamety; +{$endif} +begin + result:= false; + try + resetchangedmodules; + if langlibhandle <> 0 then begin + {$ifdef FPC}pointer({$endif}reglang{$ifdef FPC}){$endif}:= + getprocaddress(langlibhandle,unregisterlangname); + if {$ifndef FPC}@{$endif}reglang <> nil then begin + reglang(@unregistermodule,@unregisterresourcestrings); + end; + {$ifdef FPC}unloadlibrary{$else}freelibrary{$endif}(langlibhandle); + langlibhandle:= 0; + end; + if aname <> '' then begin + {$ifdef mswindows} + aname:= aname+'.dll'; + {$else} + splitfilepath(aname,fdir,fname); +// aname:= 'lib'+aname+'.so'; + aname:= fdir+'lib'+fname+'.so'; + {$endif} + langlibhandle:= loadlibrary( + {$ifndef FPC}pchar({$endif}aname{$ifndef FPC}){$endif}); + {$ifdef UNIX} + if (langlibhandle = 0) and (fdir = '') then begin + //try in application dir + langlibhandle:= loadlibrary({$ifndef FPC}pchar({$endif} + filedir(sys_getapplicationpath)+aname{$ifndef FPC}){$endif}); + end; + {$endif} + if langlibhandle <> 0 then begin + {$ifdef FPC}pointer({$endif}reglang{$ifdef FPC}){$endif}:= + getprocaddress(langlibhandle,registerlangname); + if {$ifndef FPC}@{$endif}reglang <> nil then begin + reglang(@registermodule,@registerresourcestrings); + end; + result:= true; + end + else begin + if not quiet then begin + {$ifdef FPC} + {$ifdef UNIX} + raise exception.create(dlerror); + {$else} + raise exception.create('Library not found.'); + {$endif} + {$else} + raise exception.create('Library not found.'); + {$endif} + end + else begin + exit; + end; + end; + end; + reloadchangedmodules; + except + on e: exception do begin + e.message:= 'Can not load langunit "'+aname+'":'+lineend+e.message; + application.handleexception(nil); + end; + end; +end; + +{ tresourcestringlist } + +constructor tresourcestringlist.create; +begin + inherited create(sizeof(resourcestringinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +procedure tresourcestringlist.finalizerecord(var item); +begin + finalize(resourcestringinfoty(item)); +end; + +procedure tresourcestringlist.copyrecord(var item); +begin + with resourcestringinfoty(item) do begin + stringaddref(name); + stringaddref(value); + end; +end; + +function tresourcestringlist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}compare; +end; + +function tresourcestringlist.compare(const l,r): integer; +begin + result:= stringcomp(resourcestringinfoty(l).name,resourcestringinfoty(r).name); +end; + +procedure tresourcestringlist.readvalues(data: pobjectdataty); +var + po1: pchar; + info: resourcestringinfoty; + str1: string; +begin + clear; + if data^.size > 0 then begin + po1:= @data^.data; + repeat + info.name:= po1; + inc(po1,length(info.name)+1); + str1:= po1; + inc(po1,length(str1)+1); + info.value:= utf8tostringansi(str1); + add(info); + until po1 - pchar(@data^.data) >= data^.size; + end; +end; + +function tresourcestringlist.find(const aname: string; + out po: presourcestringinfoty): boolean; +var + info: resourcestringinfoty; + int1: integer; +begin + info.name:= aname; + result:= internalfind(info,int1); + if result then begin + po:= presourcestringinfoty(pchar(datapo) + int1 * sizeof(resourcestringinfoty)); + end + else begin + po:= nil; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/i18n/mselanglink.pas b/mseide-msegui/lib/common/i18n/mselanglink.pas new file mode 100644 index 0000000..114274e --- /dev/null +++ b/mseide-msegui/lib/common/i18n/mselanglink.pas @@ -0,0 +1,59 @@ +unit mselanglink; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msei18nglob; + +type + registermodulehookty = procedure( + const registermoduleproc: registermodulety); + registerresourcehookty = procedure( + const registerresourceproc: registerresourcety); +var + registermodulehook: registermodulehookty; + registerresourcehook: registerresourcehookty; + +procedure registerlang(const registermoduleproc: registermodulety; + const registerresourceproc: registerresourcety); +procedure unregisterlang(const unregistermoduleproc: registermodulety; + const unregisterresourceproc: registerresourcety); + +implementation + +var + lastmodulehook: registermodulehookty; + lastresourcehook: registerresourcehookty; + +procedure registerlang(const registermoduleproc: registermodulety; + const registerresourceproc: registerresourcety); +begin + if registermodulehook = nil then begin + registermodulehook:= lastmodulehook; + end; + lastmodulehook:= registermodulehook; + while registermodulehook <> nil do begin + registermodulehook(registermoduleproc); + end; + if registerresourcehook = nil then begin + registerresourcehook:= lastresourcehook; + end; + lastresourcehook:= registerresourcehook; + while registerresourcehook <> nil do begin + registerresourcehook(registerresourceproc); + end; +end; + +procedure unregisterlang(const unregistermoduleproc: registermodulety; + const unregisterresourceproc: registerresourcety); +begin + registermodulehook:= lastmodulehook; + while registermodulehook <> nil do begin + registermodulehook(unregistermoduleproc); + end; + registerresourcehook:= lastresourcehook; + while registerresourcehook <> nil do begin + registerresourcehook(unregisterresourceproc); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/i18n/msestringcontainer.pas b/mseide-msegui/lib/common/i18n/msestringcontainer.pas new file mode 100644 index 0000000..f2dfc15 --- /dev/null +++ b/mseide-msegui/lib/common/i18n/msestringcontainer.pas @@ -0,0 +1,184 @@ +{ MSEgui Copyright (c) 2012-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestringcontainer; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseclasses,msedatalist,classes,mclasses,msehash,msestrings; + +type + tstringcontainer = class; + + getstringeventty = procedure(const sender: tobject; + const aindex: integer; var avalue: msestring) of object; + + tcustomstringcontainer = class(tmsecomponent) + private + fonreadstate: notifyeventty; + foneventloopstart: notifyeventty; + protected + procedure readstate(reader: treader); override; + procedure doasyncevent(var atag: integer); override; + published + property onreadstate: notifyeventty read fonreadstate write fonreadstate; + property oneventloopstart: notifyeventty read foneventloopstart + write foneventloopstart; + end; + + tstringcontainer = class(tcustomstringcontainer) + private + fstrings: tmsestringdatalist; + fongetstring: getstringeventty; + procedure setstrings(const avalue: tmsestringdatalist); + protected + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function i(const aindex: integer): msestring; //by index + property byindex[const aindex: integer]: msestring read i; default; + published + property strings: tmsestringdatalist read fstrings write setstrings; + property ongetstring: getstringeventty read fongetstring write fongetstring; + end; + + tkeystringdatalist = class(tdoublemsestringdatalist) + end; + + tkeystringcontainer = class(tcustomstringcontainer) + private + fstrings: tkeystringdatalist; + fhash: tintegermsestringhashdatalist; + fongetstring: getstringeventty; + procedure setstrings(const avalue: tkeystringdatalist); + protected + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function k(const akey: msestring): msestring; //by key + function i(const aindex: integer): msestring; //by index + property byindex[const aindex: integer]: msestring read i; default; + published + property strings: tkeystringdatalist read fstrings write setstrings; + //a = strings, b = keys + property ongetstring: getstringeventty read fongetstring write fongetstring; + end; + +implementation + +{ tcustomstringcontainer } + +procedure tcustomstringcontainer.readstate(reader: treader); +begin + inherited; + if assigned(fonreadstate) then begin + fonreadstate(self); + end; + if assigned(foneventloopstart) then begin + asyncevent; + end; +end; + +procedure tcustomstringcontainer.doasyncevent(var atag: integer); +begin + inherited; + if canevent(tmethod(foneventloopstart)) then begin + foneventloopstart(self); + end; +end; + +{ tstringcontainer } + +constructor tstringcontainer.create(aowner: tcomponent); +begin + fstrings:= tmsestringdatalist.create; + inherited; +end; + +destructor tstringcontainer.destroy; +begin + inherited; + fstrings.free; +end; + +function tstringcontainer.i(const aindex: integer): msestring; +begin + if (aindex < 0) or (aindex >= fstrings.count) then begin + result:= ''; + end + else begin + result:= pmsestringaty(fstrings.datapo)^[aindex]; + if assigned(fongetstring) then begin + fongetstring(self,aindex,result); + end; + end; +end; + +procedure tstringcontainer.setstrings(const avalue: tmsestringdatalist); +begin + fstrings.assign(avalue); +end; + +{ tkeystringcontainer } + +constructor tkeystringcontainer.create(aowner: tcomponent); +begin + fstrings:= tkeystringdatalist.create; + fhash:= tintegermsestringhashdatalist.create; + inherited; +end; + +destructor tkeystringcontainer.destroy; +begin + inherited; + fstrings.free; + fhash.free; +end; + +function tkeystringcontainer.k(const akey: msestring): msestring; +var + po1: pdoublemsestringaty; + int1: integer; +begin + with fstrings do begin + if not (dls_sortio in fstate) then begin + include(fstate,dls_sortio); + fhash.clear; + fhash.capacity:= count; + po1:= datapo; + for int1:= 0 to count-1 do begin + fhash.add(po1^[int1].b,int1); + end; + end; + end; + result:= i(fhash.find(akey)); + if result = '' then begin + result:= akey; + end; +end; + +function tkeystringcontainer.i(const aindex: integer): msestring; +begin + if (aindex < 0) or (aindex >= fstrings.count) then begin + result:= ''; + end + else begin + result:= pdoublemsestringaty(fstrings.datapo)^[aindex].a; + if assigned(fongetstring) then begin + fongetstring(self,aindex,result); + end; + end; +end; + +procedure tkeystringcontainer.setstrings(const avalue: tkeystringdatalist); +begin + fstrings.assign(avalue); +end; + +end. diff --git a/mseide-msegui/lib/common/i18n/mseucs2toru.pas b/mseide-msegui/lib/common/i18n/mseucs2toru.pas new file mode 100644 index 0000000..083d8d0 --- /dev/null +++ b/mseide-msegui/lib/common/i18n/mseucs2toru.pas @@ -0,0 +1,168 @@ +{ MSEgui Copyright (c) 2007 by IvankoB + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseucs2toru; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msestrings; + +function ucs2to866(const avalue: msechar): char; +function ucs2to866(const avalue: msestring): ansistring; + +function cp866toUCS2(const avalue: char): msechar; +function cp866toUCS2(const avalue: ansistring): msestring; + +implementation + +const + + cp866_2: array[$2550..$256C] of byte = ( + $cd,$ba,$d5,$d6,$c9,$b8,$b7,$bb,$d4,$d3,$c8,$be,$bd,$bc,$c6, + $c7,$cc,$b5,$b6,$b9,$d1,$d2,$cb,$cf,$d0,$ca,$d8,$d7,$ce + ); + + cpUCS2_1: array[$b5..$be] of longword = ( + $2561,$2562,$2556,$2555,$2563,$2551,$2557,$255D,$255C,$255B + ); + + cpUCS2_2: array[$c6..$d8] of longword = ( + $255E,$255F,$255A,$2554,$2569,$2566,$2560,$2550,$256C,$2567, + $2568,$2564,$2565,$2559,$2558,$2552,$2553,$256B,$256A + ); + + + +function ucs2to866(const avalue: msechar): char; +var + i: longword; +begin +i:= longword(avalue); +case i of + $0..$7f: result:= char(avalue); + $A0: result:= char($ff); + $A4: result:= char($fd); + $B0,$BA: result:= char($f8); + $B7: result:= char($fa); + $401: result:= char($f0); + $404: result:= char($f2); + $407: result:= char($f4); + $40E: result:= char($f6); + $410..$43f: result:= char(i-$390); + $440..$44f: result:= char(i-$360); + $451: result:= char($f1); + $454: result:= char($f3); + $457: result:= char($f5); + $45E: result:= char($f7); + $2116: result:= char($fc); + $2219: result:= char($f9); + $221A: result:= char($fb); + $2500: result:= char($c4); + $2502: result:= char($b3); + $250C: result:= char($da); + $2510: result:= char($bf); + $2514: result:= char($c0); + $2518: result:= char($d9); + $251C: result:= char($c3); + $2524: result:= char($b4); + $252C: result:= char($c2); + $2534: result:= char($c1); + $253C: result:= char($c5); + $2550..$256C: result:= char(cp866_2[i]); + $2580: result:= char($df); + $2584: result:= char($dc); + $2588: result:= char($db); + $258C: result:= char($dd); + $2590: result:= char($de); + $2591: result:= char($b0); + $2592: result:= char($b1); + $2593: result:= char($b2); + $25A0: result:= char($fe); +else + result:= char($20); +end; +end; + + +function ucs2to866(const avalue: msestring): ansistring; +var + i,i1: integer; +begin +i1:= length(avalue); +setlength(result,i1); +for i:= 1 to i1 do begin + result[i]:= ucs2to866(avalue[i]); +end; +end; + + +function cp866toUCS2(const avalue: char): msechar; +var + i: byte; +begin +i:= byte(avalue); +case i of + $0..$7f: result:= widechar(avalue); + $80..$af: result:= widechar(i + $390); + $b0: result:= widechar($2591); + $b1: result:= widechar($2592); + $b2: result:= widechar($2593); + $b3: result:= widechar($2502); + $b4: result:= widechar($2524); + $b5..$be: result:= widechar(cpUCS2_1[i]); + $bf: result:= widechar($2510); + $c0: result:= widechar($2514); + $c1: result:= widechar($2534); + $c2: result:= widechar($252C); + $c3: result:= widechar($251C); + $c4: result:= widechar($2500); + $c5: result:= widechar($253C); + $c6..$d8: result:= widechar(cpUCS2_2[i]); + $d9: result:= widechar($2518); + $da: result:= widechar($250C); + $db: result:= widechar($2588); + $dc: result:= widechar($2584); + $dd: result:= widechar($258C); + $de: result:= widechar($2590); + $df: result:= widechar($2580); + $e0..$ef: result:= widechar(i + $360); + $f0: result:= widechar($401); + $f1: result:= widechar($451); + $f2: result:= widechar($404); + $f3: result:= widechar($454); + $f4: result:= widechar($407); + $f5: result:= widechar($457); + $f6: result:= widechar($40E); + $f7: result:= widechar($45E); + $f8: result:= widechar($B0); + $f9: result:= widechar($2219); + $fa: result:= widechar($b7); + $fb: result:= widechar($221A); + $fc: result:= widechar($2116); + $fd: result:= widechar($a4); + $fe: result:= widechar($25A0); + $ff: result:= widechar($a0); + else + result:= widechar($20); +end; +end; + +function cp866toUCS2(const avalue: ansistring): msestring; +var + i,i1: integer; +begin +i1:= length(avalue); +setlength(result,i1); +for i:= 1 to i1 do begin + result[i]:= cp866toUCS2(avalue[i]); +end; +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifi.pas b/mseide-msegui/lib/common/ifi/mseifi.pas new file mode 100644 index 0000000..0b51c40 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifi.pas @@ -0,0 +1,2089 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseifi; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseapplication,mseclasses,msearrayprops,mseact,msestrings, + msetypes,mseevent, + mseglob,msestream,msepipestream,{msegui,}mseifiglob,typinfo,msebintree, + msesystypes,msesockets,msecryptio,msethread,msedatalist,msesercomm; + +//todo: use icommclient instead of oninputavailable + +type + + sequencety = longword; + + ifireckindty = (ik_none,ik_data,ik_itemheader,ik_actionfired,ik_propertychanged, + ik_widgetcommand,ik_widgetproperties,ik_requestmodule, + ik_moduledata, + ik_requestfielddefs,ik_fielddefsdata,ik_fieldrec, + ik_griddata,ik_gridcommand,ik_coldatachange,ik_rowstatechange, + ik_selection, + ik_requestopen,ik_dsdata,ik_postresult,ik_modulecommand); + ifireckindsty = set of ifireckindty; +const + ifiitemkinds = [ik_actionfired,ik_propertychanged,ik_widgetcommand, + ik_widgetproperties,ik_requestmodule,ik_moduledata, + ik_modulecommand]; + ifiasynckinds = [ik_moduledata]; +// mainloopifikinds = [ik_moduledata]; + +type + ifinamety = array[0..0] of char; //null terminated + pifinamety = ^ifinamety; + + ifidatakindty = (idk_none,idk_null,idk_integer,idk_int64,idk_currency, + idk_real,idk_realint, + idk_msestring,idk_msestringint, + idk_bytes, + idk_rowstate,idk_rowstatecolmerge, + idk_rowstaterowheight, + idk_selection); + pifidatakindty = ^ifidatakindty; + + datarecty = record //dummy + end; + + ifirealintty = record + rea: double; + int: integer; + end; + pifirealintty = ^ifirealintty; + + ifimsestringintty = record + int: integer; + mstr: ifinamety; + end; + pifimsestringintty = ^ifimsestringintty; + + selectdataty = record + col: integer; + row: integer; + select: boolean; + end; + pselectdataty = ^selectdataty; + + ifibytesty = record + length: integer; + data: datarecty; + end; + pifibytesty = ^ifibytesty; + + ifidataheaderty = record + kind: ifidatakindty; + end; + ifidataty = record + header: ifidataheaderty; + data: datarecty; //variable length + end; + pifidataty = ^ifidataty; + + itemheaderty = record + tag: integer; + name: ifinamety; + end; + pitemheaderty = ^itemheaderty; + + modulecommanddataty = record + command: ificommandcodety; + end; + pmodulecommanddataty = ^modulecommanddataty; + modulecommandty = record + header: itemheaderty; + data: modulecommanddataty; + end; + pmodulecommandty = ^modulecommandty; + + actionfiredty = record + header: itemheaderty; + end; + + propertychangedty = record + header: itemheaderty; + propertyname: ifinamety; + data: ifidataty; + end; + ppropertychangedty = ^propertychangedty; + + ifiwidgetcommandty = (iwc_enable,iwc_disable,iwc_show,iwc_hide); + pifiwidgetcommandty = ^ifiwidgetcommandty; + widgetcommandty = record + header: itemheaderty; + command: ifiwidgetcommandty; + end; + + widgetpropertiesty = record + header: itemheaderty; + streamdata: ifibytesty; + end; + pwidgetpropertiesty = ^widgetpropertiesty; + + requestmodulety = record + header: itemheaderty; + moduleclassname: ifinamety; + end; + + moduledatadataty = record +// sequence: sequencety; + parentclass: ifinamety; + data: ifibytesty; + end; + pmoduledatadataty = ^moduledatadataty; + + moduledataty = record + header: itemheaderty; + data: moduledatadataty; + end; + + requestfielddefsty = record + header: itemheaderty; + end; + fielddefsdatadataty = record + data: datarecty; //dummy + end; + pfielddefsdatadataty = ^fielddefsdatadataty; + + fielddefsdataty = record + header: itemheaderty; + data: fielddefsdatadataty; + end; + + postresultcodety = (pc_none,pc_ok,pc_error); + + postresultdataty = record + code: postresultcodety; + message: ifinamety; + end; + ppostresultdataty = ^postresultdataty; + + postresultty = record + header: itemheaderty; + data: postresultdataty; + end; + + fielddataheaderty = record + index: integer; + end; + fielddataty = record + header: fielddataheaderty; + data: ifidataty; + end; + pfielddataty = ^fielddataty; + + requestopenty = record + header: itemheaderty; + end; + fieldreckindty = (frk_edit,frk_insert,frk_delete); + fieldrecheaderty = record + kind: fieldreckindty; + rowindex: integer; //null based + count: integer; + end; + fieldrecdataty = record + header: fieldrecheaderty; + data: datarecty; //dummy, array[count] of fielddataty + end; + pfieldrecdataty = ^fieldrecdataty; + + fieldrecty = record + header: itemheaderty; + data: fieldrecdataty; + end; + + rowstateheaderty = record + row: integer; + end; + prowstateheaderty = ^rowstateheaderty; + rowstatedataty = record + header: rowstateheaderty; + data: ifidataty; //idk_rowstate, idk_rowstatecolmerge, idk_rowstaterowheight + end; + prowstatedataty = ^rowstatedataty; + + selectiondataty = record + data: ifidataty; //idk_selection + end; + + colitemheaderty = record + row: integer; + name: ifinamety; + end; + colitemdataty = record + header: colitemheaderty; + data: ifidataty; + end; + pcolitemdataty = ^colitemdataty; + + coldataty = record + kind: listdatatypety; + name: ifinamety; + data: datarecty; //array[0..rows-1] of datatype + end; + pcoldataty = ^coldataty; + griddatadataty = record + cols: integer; + rows: integer; + data: datarecty; //array[0..cols-1] of coldataty + rowinfo: ifibytesty; //if folded + end; + pgriddatadataty = ^griddatadataty; + griddataty = record + header: itemheaderty; + data: griddatadataty; + end; + + gridcommandkindty = (gck_insertrow,gck_deleterow,gck_moverow,gck_rowenter); + gridcommanddatadataty = record + kind: gridcommandkindty; + dest: integer; + source: integer; + count: integer; + end; + pgridcommanddatadataty = ^gridcommanddatadataty; + gridcommanddataty = record + header: itemheaderty; + data: gridcommanddatadataty; + end; + + recdataheaderty = record + count: integer; //recordcount + end; + recdataty = record + header: recdataheaderty; + data: datarecty; //dummy, array[count] of + //array[fielddef count] of ifidataty + end; + precdataty = ^recdataty; + + dsdataty = record + header: itemheaderty; + fileddefs: fielddefsdatadataty; + recdata: recdataty; + end; + +type + ifirecstatety = (irs_async); + ifirecstatesty = set of ifirecstatety; + ifiheaderty = record + size: integer; //overall size + sequence: sequencety; + answersequence: sequencety; + kind: ifireckindty; + state: ifirecstatesty; + end; + pifiheaderty = ^ifiheaderty; + + ifirecty = record + header: ifiheaderty; + case ifireckindty of + ik_data:( + data: ifidataty; + ); + ik_itemheader:( + itemheader: itemheaderty; + ); + ik_actionfired:( + actionfired: actionfiredty; + ); + ik_propertychanged:( + propertychanged: propertychangedty; + ); + ik_widgetcommand: ( + widgetcommand: widgetcommandty; + ); + ik_requestmodule: ( + requestmodule: requestmodulety; + ); + ik_moduledata: ( + moduledata: moduledataty; + ); + ik_requestfielddefs: ( + requestfielddefs: requestfielddefsty; + ); + ik_fielddefsdata: ( + fielddefsdata: fielddefsdataty; + ); + ik_fieldrec: ( + fieldrec: fieldrecty; + ); + ik_griddata: ( + griddata: griddataty; + ); + ik_requestopen: ( + requestopends: requestopenty; + ); + ik_postresult: ( + postresult: postresultty; + ); + ik_modulecommand: ( + modulecommand: modulecommandty; + ); + end; + pifirecty = ^ifirecty; + + twaitingclient = class(tintegeravlnode) + private + fsem: semty; + public + constructor create(const asequence: sequencety); + destructor destroy; override; + procedure answered; + function wait(const awaitus: integer): boolean; + end; + + tiosynchronizer = class; + stringdataprocty = procedure(var adata: string) of object; + + tiosynchronizer = class(teventthread) + private + fwaitingclients: tintegeravltree; //todo: use hashlist + fondatareceived: stringdataprocty; + protected + procedure datareceived(const adata: string); + procedure eventloop; + function execute(thread: tmsethread): integer; override; + public + constructor create(const aondatareceived: stringdataprocty); + destructor destroy; override; + procedure answerreceived(const asequence: sequencety); + function preparewait(const asequence: sequencety): twaitingclient; + function waitforanswer(const aclient: twaitingclient; + const waitus: integer): boolean; //false on timeout + end; + + tcustomiochannel = class; + iochanneleventty = procedure(const sender: tcustomiochannel) of object; + optioniochty = (oic_releaseondisconnect); + optionsiochty = set of optioniochty; + iochannelstatety = (iocs_connecting,iocs_disconnecting, + iocs_localsetting); + iochannelstatesty = set of iochannelstatety; + + tcustomiochannel = class(tactcomponent) + private + frxdata: string; + factive: boolean; + fsequence: sequencety; + fonbeforeconnect: iochanneleventty; + fonafterconnect: iochanneleventty; + fonbeforedisconnect: iochanneleventty; + fonafterdisconnect: iochanneleventty; + foptionsio: optionsiochty; + flocalconn: tcustomiochannel; + procedure setlocalconn(const avalue: tcustomiochannel); + protected + fsynchronizer: tiosynchronizer; + fstate: iochannelstatesty; + procedure setactive(const avalue: boolean); override; + procedure checkinactive; + function canconnect: boolean; virtual; + procedure datareceived(var adata: ansistring); + procedure internalconnect; virtual; abstract; + procedure internaldisconnect; virtual; abstract; + function commio: boolean; virtual; + procedure localsenddata(const adata: ansistring); virtual; + procedure internalsenddata(const adata: ansistring); virtual; abstract; + procedure loaded; override; + procedure dobeforeconnect; + procedure doafterconnect; virtual; + procedure connect; + procedure disconnect; + procedure disconnected; + procedure doactivated; override; + procedure dodeactivated; override; + procedure receiveevent(const event: tobjectevent); override; + procedure receivelocaldata(const adata: string); virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function checkconnection: boolean; + procedure senddata(const adata: ansistring); + function sequence: sequencety; + procedure asyncrx; //posts current rxdata to application queue + property synchronizer: tiosynchronizer read fsynchronizer; + property active: boolean read factive write setactive default false; + property rxdata: string read frxdata write frxdata; + property localconn: tcustomiochannel read flocalconn write setlocalconn; + published + property optionsio: optionsiochty read foptionsio write foptionsio default []; + property onbeforeconnect: iochanneleventty read fonbeforeconnect + write fonbeforeconnect; + property onafterconnect: iochanneleventty read fonafterconnect + write fonafterconnect; + property onbeforedisconnect: iochanneleventty read fonbeforedisconnect + write fonbeforedisconnect; + property onafterdisconnect: iochanneleventty read fonafterdisconnect + write fonafterdisconnect; + end; + + pipeiostatety = (pis_rxstarted); + pipeiostatesty = set of pipeiostatety; + + tstuffediochannel = class(tcustomiochannel) + private + fbuffer: string; + fpipestate: pipeiostatesty; + frxcheckedindex: integer; + protected + function stuff(const adata: string): string; + function unstuff(const adata: string): string; + procedure resetrxbuffer; + procedure addata(const adata: string); + procedure receivelocaldata(const adata: string); override; + end; + + tcustompipeiochannel = class(tstuffediochannel) + private + frx: tpipereader; + ftx: tpipewriter; + fserverapp: msestring; + fprochandle: integer; + protected + procedure internalconnect; override; + procedure internaldisconnect; override; + function commio: boolean; override; + procedure localsenddata(const adata: ansistring); override; + procedure internalsenddata(const adata: ansistring); override; + procedure doinputavailable(const sender: tpipereader); + procedure dopipebroken(const sender: tpipereader); + procedure doasyncevent(var atag: integer); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property active; + end; + + tpipeiochannel = class(tcustompipeiochannel) + published + property active; + property activator; + property serverapp: msestring read fserverapp write fserverapp; + //stdin, stdout if '' + property localconn; + end; + + tsocketstdiochannel = class(tcustompipeiochannel) + private + fcryptoio: tcryptoio; + fcryptoioinfo: cryptoioinfoty; + procedure setcryptoio(const avalue: tcryptoio); + protected + procedure internalconnect; override; + procedure internaldisconnect; override; + public + constructor create(aowner: tcomponent); override; + published + property active; + property activator; + property cryptoio: tcryptoio read fcryptoio write setcryptoio; + property cryptoiokindt: cryptoiokindty read fcryptoioinfo.kind + write fcryptoioinfo.kind; + end; + + tifisocketclient = class(tcustomsocketclient) + published + property pipes; + property cryptoio; + + property kind; + property url; + property port; + end; + + tsocketclientiochannel = class(tstuffediochannel) + private + fsocket: tifisocketclient; + procedure setsocket(const avalue: tifisocketclient); + protected + procedure internalconnect; override; + procedure internaldisconnect; override; + function commio: boolean; override; + procedure localsenddata(const adata: ansistring); override; + procedure internalsenddata(const adata: ansistring); override; + procedure doinputavailable(const sender: tpipereader); + procedure dobeforedisconnect(const sender: tcustomcommpipes); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property active; + property activator; + property socket: tifisocketclient read fsocket write setsocket; + property localconn; + end; + + tcustomsocketserveriochannel = class(tstuffediochannel) + private + fpipes: tcustomsocketpipes; + funlinking: integer; + protected + procedure internalconnect; override; + procedure internaldisconnect; override; + function commio: boolean; override; + procedure localsenddata(const adata: ansistring); override; + procedure internalsenddata(const adata: ansistring); override; + procedure doinputavailable(const sender: tpipereader); + procedure dobeforedisconnect(const sender: tcustomcommpipes); + procedure unlink; reintroduce; + function canconnect: boolean; override; + public + destructor destroy; override; + procedure link(const apipes: tcustomcommpipes); + end; + + tsocketserveriochannel = class(tcustomsocketserveriochannel) + public + published + property localconn; + end; + + tifiiolinkcomponent = class(tmsecomponent) + private + procedure setchannel(const avalue: tcustomiochannel); + protected + fchannel: tcustomiochannel; + published + property channel: tcustomiochannel read fchannel write setchannel; + end; + +procedure initifirec(out arec: string; const akind: ifireckindty; + const asequence: sequencety; const datalength: integer; out datapo: pchar); +procedure inititemheader(const atag: integer; const aname: string; + out arec: string; const akind: ifireckindty; + const asequence: sequencety; const datasize: integer; out datapo: pchar); +function ifinametostring(const source: pifinamety; out dest: string): integer; +function stringtoifiname(const source: string; const dest: pifinamety): integer; + +function encodeifinull(const headersize: integer = 0): string; +function encodeifidata(const avalue: boolean; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: integer; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: int64; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: currency; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: real; + const headersize: integer = 0): string; overload; +{$ifndef FPC} +function encodeifidatareal(const avalue: real; + const headersize: integer = 0): string; overload; +{$endif} +function encodeifidata(const avalue: realintty; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: msestring; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: msestringintty; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: ansistring; + const headersize: integer = 0): string; overload; +function encodeifidata(const alist: tdatalist; const aindex: integer; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: rowstatety; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: rowstatecolmergety; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: rowstaterowheightty; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: selectdataty; + const headersize: integer = 0): string; overload; + +function skipifidata(const source: pifidataty): integer; +function decodeifidata(const source: pifidataty; out dest: msestring): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: string): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: integer): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: int64): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: real): integer; + overload; +{$ifndef FPC} +function decodeifidatareal(const source: pifidataty; out dest: double): integer; + overload; +{$endif} +function decodeifidata(const source: pifidataty; out dest: realintty): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: currency): integer; + overload; +function decodeifidata(const source: pifidataty; + out dest: msestringintty): integer; overload; +function decodeifidata(const source: pifidataty; out dest: variant): integer; + overload; +function decodeifidata(const source: pifidataty; const aindex: integer; + const alist: tdatalist): integer; overload; + //alist can be nil +function decodeifidata(const source: pifidataty; const aindex: integer; + const alist: subdatainfoty): integer; overload; +function decodeifidata(const source: pifidataty; out dest: rowstatety): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: rowstatecolmergety): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: rowstaterowheightty): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: selectdataty): integer; + overload; + +procedure addifiintegervalue(var adata: ansistring; var adatapo: pchar; + const avalue: integer); +function readifivariant(const adata: pifirecty; var adatapo: pchar): variant; +function setifibytes(const source: pointer; const size: integer; + const dest: pifibytesty): integer; overload; + +const + datarecsizes: array[ifidatakindty] of integer = ( + sizeof(ifidataty), //idk_none + sizeof(ifidataty), //idk_null + sizeof(ifidataty)+sizeof(integer), //idk_integer + sizeof(ifidataty)+sizeof(int64), //idk_int64 + sizeof(ifidataty)+sizeof(currency), //idk_currency + sizeof(ifidataty)+sizeof(double), //idk_real + sizeof(ifidataty)+sizeof(ifirealintty), //idk_realint + sizeof(ifidataty)+sizeof(ifinamety), //idk_msestring + sizeof(ifidataty)+sizeof(ifimsestringintty), //idk_msestringint + sizeof(ifidataty)+sizeof(ifibytesty), //idk_bytes + sizeof(ifidataty)+sizeof(rowstatety), //idk_rowstate + sizeof(ifidataty)+sizeof(rowstatecolmergety), //idk_rowstatecolmerge + sizeof(ifidataty)+sizeof(rowstaterowheightty), //idk_rowstaterowheight + sizeof(ifidataty)+sizeof(selectdataty) //idk_selection + ); +implementation +uses + sysutils,mseprocutils,msesysintf1,msesysintf,{mseforms,}msetmpmodules, + msesysutils,variants,msesumlist {$ifndef FPC},classes_del{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsocketreader1 = class(tsocketreader); + tsocketwriter1 = class(tsocketwriter); + +const + headersizes: array[ifireckindty] of integer = ( + sizeof(ifiheaderty), //ik_none + sizeof(ifiheaderty), //ik_data + sizeof(ifiheaderty)+sizeof(itemheaderty), //ik_itemheader + sizeof(ifiheaderty)+sizeof(actionfiredty), //ik_actionfired + sizeof(ifiheaderty)+sizeof(propertychangedty), //ik_propertychanged + sizeof(ifiheaderty)+sizeof(widgetcommandty), //ik_widgetcommand + sizeof(ifiheaderty)+sizeof(widgetpropertiesty), //ik_widgetproperties + sizeof(ifiheaderty)+sizeof(requestmodulety), //ik_requestmodule + sizeof(ifiheaderty)+sizeof(moduledataty), //ik_moduledata + sizeof(ifiheaderty)+sizeof(requestfielddefsty), //ik_requestfielddefs + sizeof(ifiheaderty)+sizeof(fielddefsdataty), //ik_fielddefsdata + sizeof(ifiheaderty)+sizeof(fieldrecty), //ik_fieldrec + sizeof(ifiheaderty)+sizeof(griddataty), //ik_griddata + sizeof(ifiheaderty)+sizeof(gridcommanddataty), //ik_gridcommand + sizeof(ifiheaderty)+sizeof(colitemdataty), //ik_coldatachange + sizeof(ifiheaderty)+sizeof(rowstatedataty), //ik_rowstatechange + sizeof(ifiheaderty)+sizeof(selectiondataty), //ik_selection + sizeof(ifiheaderty)+sizeof(requestopenty), //ik_requestopen + sizeof(ifiheaderty)+sizeof(dsdataty), //ik_dsdata + sizeof(ifiheaderty)+sizeof(postresultty), //ik_postresult + sizeof(ifiheaderty)+sizeof(modulecommandty) //ik_modulecommand + ); + + stuffchar = c_dle; + stx = c_dle + c_stx; + etx = c_dle + c_etx; + +function setifibytes(const source: pointer; const size: integer; + const dest: pifibytesty): integer; overload; +begin + result:= sizeof(ifibytesty) + size; + dest^.length:= size; + move(source^,dest^.data,size); +end; + +function setifibytes(const source: string; + const dest: pifibytesty): integer; overload; +var + int1: integer; +begin + int1:= length(source); + result:= sizeof(ifibytesty) + int1; + dest^.length:= int1; + move(pointer(source)^,dest^.data,int1); +end; + +function initdataheader(const headersize: integer; const kind: ifidatakindty; + const datasize: integer; out data: string): pchar; +begin + setlength(data,headersize+datarecsizes[kind]+datasize); + result:= pointer(data); + fillchar(result^,headersize,0); + inc(result,headersize); + pifidataty(result)^.header.kind:= kind; + inc(result,sizeof(ifidataheaderty)); +end; + +function encodeifinull(const headersize: integer = 0): string; +begin + initdataheader(headersize,idk_null,0,result) +end; + +function encodeifidata(const avalue: boolean; + const headersize: integer = 0): string; overload; +var + int1: integer; +begin + int1:= 0; + if avalue then begin + int1:= integer(longbool(true)); + end; + pinteger(initdataheader(headersize,idk_integer,0,result))^:= int1; +end; + +function encodeifidata(const avalue: integer; + const headersize: integer = 0): string; overload; +begin + pinteger(initdataheader(headersize,idk_integer,0,result))^:= avalue; +// result:= encodeifidata(int64(avalue),headersize); +end; + +function encodeifidata(const avalue: int64; + const headersize: integer = 0): string; overload; +begin + pint64(initdataheader(headersize,idk_int64,0,result))^:= avalue; +end; + +function encodeifidata(const avalue: currency; + const headersize: integer = 0): string; overload; +begin + pcurrency(initdataheader(headersize,idk_currency,0,result))^:= avalue; +end; + +function encodeifidata(const avalue: real; + const headersize: integer = 0): string; overload; +begin + preal(initdataheader(headersize,idk_real,0,result))^:= avalue; +end; + +{$ifndef FPC} +function encodeifidatareal(const avalue: real; + const headersize: integer = 0): string; overload; +begin + preal(initdataheader(headersize,idk_real,0,result))^:= avalue; +end; +{$endif} + +function encodeifidata(const avalue: realintty; + const headersize: integer = 0): string; overload; +begin + with pifirealintty(initdataheader(headersize,idk_realint,0,result))^ do begin + rea:= avalue.rea; + int:= avalue.int; + end; +end; + +function encodeifidata(const avalue: msestring; + const headersize: integer = 0): string; overload; +var + str1: string; +begin + str1:= stringtoutf8ansi(avalue); + stringtoifiname(str1,pifinamety( + initdataheader(headersize,idk_msestring,length(str1),result))); +end; + +function encodeifidata(const avalue: msestringintty; + const headersize: integer = 0): string; overload; +var + str1: string; + po1: pifimsestringintty; +begin + str1:= stringtoutf8ansi(avalue.mstr); + po1:= pifimsestringintty(initdataheader( + headersize,idk_msestringint,length(str1),result)); + po1^.int:= avalue.int; + stringtoifiname(str1,@po1^.mstr); +end; + +function encodeifidata(const avalue: ansistring; + const headersize: integer = 0): string; overload; +begin + setifibytes(avalue,pifibytesty( + initdataheader(headersize,idk_bytes,length(avalue),result))); +end; + +function encodeifidata(const alist: tdatalist; const aindex: integer; + const headersize: integer = 0): string; +begin + case alist.datatype of + dl_integer: begin + result:= encodeifidata(tintegerdatalist(alist).items[aindex],headersize); + end; + dl_msestring: begin + result:= encodeifidata(tmsestringdatalist(alist).items[aindex],headersize); + end; + dl_real: begin + {$ifdef FPC} + result:= encodeifidata(trealdatalist(alist).items[aindex],headersize); + {$else} + result:= encodeifidatareal(trealdatalist(alist).items[aindex],headersize); + {$endif} + end; + dl_msestringint: begin + result:= encodeifidata(tmsestringintdatalist(alist).doubleitems[aindex],headersize); + end; + dl_realint,dl_realsum: begin + result:= encodeifidata(trealintdatalist(alist).doubleitems[aindex],headersize); + end; + else begin + raise exception.create('Wrong datakind.'); + //result:= ''; + end; + end; +end; + +function encodeifidata(const avalue: rowstatety; + const headersize: integer = 0): string; overload; +begin + prowstatety(initdataheader(headersize, + idk_rowstate,0,result))^:= avalue; +end; + +function encodeifidata(const avalue: rowstatecolmergety; + const headersize: integer = 0): string; overload; +begin + prowstatecolmergety(initdataheader(headersize, + idk_rowstatecolmerge,0,result))^:= avalue; +end; + +function encodeifidata(const avalue: rowstaterowheightty; + const headersize: integer = 0): string; overload; +begin + prowstaterowheightty(initdataheader(headersize, + idk_rowstatecolmerge,0,result))^:= avalue; +end; + +function encodeifidata(const avalue: selectdataty; + const headersize: integer = 0): string; overload; +begin + pselectdataty(initdataheader(headersize,idk_selection,0,result))^:= avalue; +end; + +procedure addifiintegervalue(var adata: ansistring; var adatapo: pchar; + const avalue: integer); +begin + setlength(adata,adatapo-pointer(adata)); + adata:= adata + encodeifidata(avalue); + pifirecty(adata)^.header.size:= length(adata); + adatapo:= pchar(pointer(adata)) + length(adata); +end; + +function readifivariant(const adata: pifirecty; var adatapo: pchar): variant; +type + variantarty = array of variant; +var + ar1: variantarty; + po1: pchar; +// int1: integer; +begin + ar1:= nil; //compiler warning + po1:= pchar(adata)+adata^.header.size; + while adatapo < po1 do begin + setlength(ar1,high(ar1)+2); + inc(adatapo,decodeifidata(pifidataty(adatapo),ar1[high(ar1)])); + end; + case high(ar1) of + -1: begin + result:= null; + end; + 0: begin + result:= ar1[0]; + end; + else begin + dynarraytovariant(result,pointer(ar1),typeinfo(variantarty)); + end; + end; +end; + +procedure datakinderror; +begin + raise exception.create('Wrong datakind.'); +end; + +function skipifidata(const source: pifidataty): integer; +var + str1: string; +begin + case source^.header.kind of + idk_msestring: begin + ifinametostring(pifinamety(@source^.data),str1); + result:= length(str1); + end; + idk_bytes: begin + result:= pifibytesty(@source^.data)^.length; + end; + else begin + result:= 0; + end; + end; + result:= result + datarecsizes[source^.header.kind]; +end; + +function decodeifidata(const source: pifidataty; out dest: msestring): integer; +var + str1: string; +begin + if source^.header.kind <> idk_msestring then begin + datakinderror; + end; + ifinametostring(pifinamety(@source^.data),str1); + dest:= utf8tostringansi(str1); + result:= datarecsizes[idk_msestring] + length(str1); +end; + +function decodeifidata(const source: pifidataty; out dest: string): integer; +begin + if source^.header.kind <> idk_bytes then begin + datakinderror; + end; + with pifibytesty(@source^.data)^ do begin + setlength(dest,length); + if length > 0 then begin + move(data,pointer(dest)^,length); + end; + result:= datarecsizes[idk_bytes] + length; + end; +end; + +function decodeifidata(const source: pifidataty; out dest: integer): integer; +begin + if source^.header.kind <> idk_integer then begin + datakinderror; + end; + dest:= pinteger(@source^.data)^; + result:= datarecsizes[idk_integer]; +end; + +function decodeifidata(const source: pifidataty; out dest: int64): integer; +begin + if source^.header.kind <> idk_int64 then begin + datakinderror; + end; + dest:= pint64(@source^.data)^; + result:= datarecsizes[idk_int64]; +end; + +function decodeifidata(const source: pifidataty; out dest: real): integer; +begin + if source^.header.kind <> idk_real then begin + datakinderror; + end; + dest:= preal(@source^.data)^; + result:= datarecsizes[idk_real]; +end; + +{$ifndef FPC} +function decodeifidatareal(const source: pifidataty; out dest: double): integer; +begin + if source^.header.kind <> idk_real then begin + datakinderror; + end; + dest:= preal(@source^.data)^; + result:= datarecsizes[idk_real]; +end; +{$endif} + +function decodeifidata(const source: pifidataty; out dest: realintty): integer; +begin + if source^.header.kind <> idk_realint then begin + datakinderror; + end; + with pifirealintty(@source^.data)^ do begin + dest.rea:= rea; + dest.int:= int; + end; + result:= datarecsizes[idk_realint]; +end; + +function decodeifidata(const source: pifidataty; out dest: currency): integer; +begin + if source^.header.kind <> idk_currency then begin + datakinderror; + end; + dest:= pcurrency(@source^.data)^; + result:= datarecsizes[idk_currency]; +end; + +function decodeifidata(const source: pifidataty; + out dest: msestringintty): integer; overload; +var + str1: string; + po1: pifimsestringintty; +begin + if source^.header.kind <> idk_msestringint then begin + datakinderror; + end; + po1:= @source^.data; + dest.int:= po1^.int; + ifinametostring(pifinamety(@po1^.mstr),str1); + dest.mstr:= utf8tostringansi(str1); + result:= datarecsizes[idk_msestringint] + length(str1); +end; + +function decodeifidata(const source: pifidataty; out dest: variant): integer; +var + integer1: integer; + int641: int64; + currency1: currency; + real1: real; + msestring1: msestring; + ansistring1: ansistring; +begin + case source^.header.kind of + idk_null: begin + dest:= null; + result:= sizeof(ifidataty); + end; + idk_integer: begin + result:= decodeifidata(source,integer1); + dest:= integer1; + end; + idk_int64: begin + result:= decodeifidata(source,int641); + dest:= int641; + end; + idk_currency: begin + result:= decodeifidata(source,currency1); + dest:= currency1; + end; + idk_real: begin + result:= decodeifidata(source,real1); + dest:= real1; + end; + idk_msestring: begin + result:= decodeifidata(source,msestring1); + dest:= msestring1; + end; + idk_bytes: begin + result:= decodeifidata(source,ansistring1); + dest:= ansistring1; + end; + else begin + raise exception.create('Invalid IfI data'); + end; + end; +end; + +function decodeifidata(const source: pifidataty; const aindex: integer; + const alist: tdatalist): integer; overload; + //alist can be nil +var + ainfo: subdatainfoty; +begin + ainfo.list:= alist; + ainfo.subindex:= 0; + result:= decodeifidata(source,aindex,ainfo); +end; + +function decodeifidata(const source: pifidataty; const aindex: integer; + const alist: subdatainfoty): integer; overload; + //alist can be nil +var + int1: integer; + lint1: int64; + rea1: real; + mstr1: msestring; + strint1: msestringintty; + realint1: realintty; +begin + with alist do begin + result:= 0; + if (list <> nil) and (aindex < list.count) then begin + if alist.subindex = 0 then begin + case source^.header.kind of + idk_null: begin + list.cleardata(aindex); + end; + idk_integer: begin + if list.datatype = dl_integer then begin + result:= decodeifidata(source,int1); + tintegerdatalist(list)[aindex]:= int1; + end; + end; + idk_int64: begin + if list.datatype = dl_int64 then begin + result:= decodeifidata(source,lint1); + tint64datalist(list)[aindex]:= lint1; + end; + end; + idk_msestring: begin + if list.datatype = dl_msestring then begin + result:= decodeifidata(source,mstr1); + tmsestringdatalist(list)[aindex]:= mstr1; + end; + end; + idk_real: begin + if list.datatype in [dl_real,dl_realsum] then begin + result:= decodeifidata(source,rea1); + trealdatalist(list)[aindex]:= rea1; + end; + end; + idk_msestringint: begin + if list.datatype = dl_msestringint then begin + result:= decodeifidata(source,strint1); + tmsestringintdatalist(list)[aindex]:= strint1; + end; + end; + idk_realint: begin + if list is trealintdatalist then begin + result:= decodeifidata(source,realint1); + trealintdatalist(list).doubleitems[aindex]:= realint1; + end; + end; + end; + end + else begin + case source^.header.kind of + idk_null: begin + list.clearmemberitem(subindex,aindex); + end; + idk_integer: begin + result:= decodeifidata(source,int1); + list.setmemberitem(subindex,aindex,int1); + end; + end; + end; + end; + if result = 0 then begin + result:= skipifidata(source); + end; + end; +end; + +function decodeifidata(const source: pifidataty; out dest: rowstatety): integer; +begin + if not (source^.header.kind in + [idk_rowstate,idk_rowstatecolmerge,idk_rowstaterowheight]) then begin + datakinderror; + end; + dest:= prowstatety(@source^.data)^; + result:= datarecsizes[source^.header.kind]; +end; + +function decodeifidata(const source: pifidataty; + out dest: rowstatecolmergety): integer; +begin + case source^.header.kind of + idk_rowstate: begin + fillchar(dest.colmerge,sizeof(dest.colmerge),0); + prowstatety(@dest)^:= prowstatety(@source^.data)^; + end; + idk_rowstatecolmerge,idk_rowstaterowheight: begin + dest:= prowstatecolmergety(@source^.data)^; + end; + else begin + datakinderror; + end; + end; + result:= datarecsizes[source^.header.kind]; +end; + +function decodeifidata(const source: pifidataty; + out dest: rowstaterowheightty): integer; +begin + case source^.header.kind of + idk_rowstate: begin + fillchar(dest.colmerge,sizeof(dest.colmerge)+sizeof(dest.rowheight),0); + prowstatety(@dest)^:= prowstatety(@source^.data)^; + end; + idk_rowstatecolmerge: begin + fillchar(dest.rowheight,sizeof(dest.rowheight),0); + prowstatecolmergety(@dest)^:= prowstatecolmergety(@source^.data)^; + end; + idk_rowstaterowheight: begin + dest:= prowstaterowheightty(@source^.data)^; + end; + else begin + datakinderror; + end; + end; + result:= datarecsizes[source^.header.kind]; +end; + +function decodeifidata(const source: pifidataty; out dest: selectdataty): integer; +begin + if source^.header.kind <> idk_selection then begin + datakinderror; + end; + dest:= pselectdataty(@source^.data)^; + result:= datarecsizes[idk_selection]; +end; + +{ +function decodecolitemdata(const source: pcolitemdataty; + const alist: tdatalist): integer; +begin + result:= sizeof(colitemheaderty) + + decodeifidata(@source^.data,alist,source^.header.row); +end; +} +procedure initifirec(out arec: string; const akind: ifireckindty; + const asequence: sequencety; const datalength: integer; + out datapo: pchar); +var + int1: integer; +begin + int1:= headersizes[akind] + datalength; + arec:= nullstring(int1); +// setlength(arec,int1); +// fillchar(arec[1],int1,0); + with pifiheaderty(arec)^ do begin + size:= int1; + answersequence:= asequence; +// sequence:= fsequence; + kind:= akind; + end; + datapo:= pchar(pointer(arec)) + sizeof(ifiheaderty); +end; + +function stringtoifiname(const source: string; const dest: pifinamety): integer; +var + int1: integer; +begin + int1:= length(source); + if int1 > 0 then begin + move(source[1],dest^,int1); + end; + pchar(dest)[int1]:= #0; + result:= int1 + 1; +end; + +function ifinametostring(const source: pifinamety; + out dest: string): integer; +begin + dest:= pchar(source); + result:= length(dest) + 1; +end; +{ +procedure ifidatasynchronize(const sender: tiosynchronizer; var adata: string); +begin + if length(adata) >= sizeof(ifiheaderty) then begin + with pifiheaderty(adata)^ do begin + if answersequence <> 0 then begin + sender.answerreceived(answersequence); + end; + end; + end; +end; +} +procedure inititemheader(const atag: integer; const aname: string; + out arec: string; const akind: ifireckindty; const asequence: sequencety; + const datasize: integer; out datapo: pchar); +var + po1: pchar; +begin + initifirec(arec,akind,asequence,datasize+length(aname),po1); + with pitemheaderty(po1)^ do begin + tag:= atag; + po1:= @name; + end; + inc(po1,stringtoifiname(aname,pifinamety(po1))); + datapo:= po1; +end; + +{ tcustomiochannel } + +constructor tcustomiochannel.create(aowner: tcomponent); +begin + fsynchronizer:= tiosynchronizer.create({$ifdef FPC}@{$endif}datareceived); + inherited; +end; + +destructor tcustomiochannel.destroy; +begin + fsynchronizer.free; + active:= false; + localconn:= nil; + inherited; +end; + +function tcustomiochannel.checkconnection: boolean; +begin + result:= commio; + if not result and not (csloading in componentstate) then begin + internaldisconnect(); + factive:= false; + if canconnect then begin + connect; + result:= commio; + end; + end; +end; + +function tcustomiochannel.sequence: sequencety; +begin + inc(fsequence); + if fsequence = 0 then begin + inc(fsequence); + end; + result:= fsequence; +end; + +procedure tcustomiochannel.localsenddata(const adata: ansistring); +begin + flocalconn.receivelocaldata(adata); +end; + +procedure tcustomiochannel.senddata(const adata: ansistring); +begin + if checkconnection then begin + if flocalconn <> nil then begin + localsenddata(adata); + end + else begin + internalsenddata(adata); + end; + end; +end; + +procedure tcustomiochannel.datareceived(var adata: ansistring); +var + str1: string; +begin + str1:= frxdata; + frxdata:= adata; + try + sendchangeevent(oe_dataready); //todo: don't broadcast, use hashed list + finally + frxdata:= str1; + end; +end; + +procedure tcustomiochannel.receiveevent(const event: tobjectevent); +begin + if (event.kind = ek_objectdata) and (event is tstringobjectevent) then begin + datareceived(tstringobjectevent(event).data); + end + else begin + inherited; + end; +end; + +procedure tcustomiochannel.receivelocaldata(const adata: string); +begin + //dummy +end; + +procedure tcustomiochannel.asyncrx; //posts current rxdata to application queue +var + str1: ansistring; +begin + str1:= frxdata; + frxdata:= ''; + application.postevent(tstringobjectevent.create(str1,ievent(self))); +end; + +procedure tcustomiochannel.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + if componentstate * [csloading,csdesigning] = [] then begin + if avalue then begin + connect; + end + else begin + disconnect; + end; + end; + factive:= avalue; + end; +end; + +procedure tcustomiochannel.loaded; +begin + inherited; + if factive and not (csdesigning in componentstate) then begin + connect; + end; +end; + +procedure tcustomiochannel.dobeforeconnect; +begin + if canevent(tmethod(fonbeforeconnect)) then begin + fonbeforeconnect(self); + end; +end; + +procedure tcustomiochannel.doafterconnect; +begin + if canevent(tmethod(fonafterconnect)) then begin + fonafterconnect(self); + end; +end; + +procedure tcustomiochannel.connect; +begin + if not (iocs_connecting in fstate) then begin +{$ifdef mse_debugsockets} + debugout(self,'connect'); +{$endif} + include(fstate,iocs_connecting); + try + dobeforeconnect; + if flocalconn <> nil then begin + flocalconn.connect; + doactivated; + end + else begin + internalconnect; + end; + doafterconnect; + {$ifdef mse_debugsockets} + debugout(self,'connected'); + {$endif} + finally + exclude(fstate,iocs_connecting); + end; + end; +end; + +procedure tcustomiochannel.disconnected; +begin +{$ifdef mse_debugsockets} + debugout(self,'disconnected'); +{$endif} + if canevent(tmethod(fonafterdisconnect)) then begin + fonafterdisconnect(self); + end; + if (oic_releaseondisconnect in foptionsio) and + not (csdesigning in componentstate) and (owner is tactcomponent) then begin + tactcomponent(owner).release; + end; +end; + +procedure tcustomiochannel.disconnect; +begin + if not(iocs_disconnecting in fstate) then begin + include(fstate,iocs_disconnecting); + {$ifdef mse_debugsockets} + debugout(self,'disconnect'); + {$endif} + try + if canevent(tmethod(fonbeforedisconnect)) then begin + fonbeforedisconnect(self); + end; + if flocalconn <> nil then begin + flocalconn.disconnect; + end + else begin + internaldisconnect; + end; + factive:= false; + disconnected; + finally + exclude(fstate,iocs_disconnecting); + end; + end; +end; + +procedure tcustomiochannel.checkinactive; +begin + if active and not(csloading in componentstate) then begin + exception.create(name+': Must be inactive.'); + end; +end; + +function tcustomiochannel.canconnect: boolean; +begin + result:= true; +end; + +function tcustomiochannel.commio: boolean; +begin + result:= (flocalconn <> nil) and flocalconn.active; +end; + +procedure tcustomiochannel.doactivated; +begin + active:= true; +// if factive then begin +// connect; +// end; +end; + +procedure tcustomiochannel.dodeactivated; +begin + active:= false; +end; + +procedure tcustomiochannel.setlocalconn(const avalue: tcustomiochannel); +begin + if (avalue <> flocalconn) and not (iocs_localsetting in fstate) then begin + include(fstate,iocs_localsetting); + try + if avalue <> nil then begin + checkinactive; + avalue.checkinactive; + end + else begin + active:= false; + end; + if flocalconn <> nil then begin + flocalconn.localconn:= nil; + end; + flocalconn:= avalue; + if avalue <> nil then begin + avalue.localconn:= self; + end; + finally + exclude(fstate,iocs_localsetting); + end; + end; +end; + +{ tstuffediochannel } + +procedure tstuffediochannel.resetrxbuffer; +begin + fbuffer:= ''; + exclude(fpipestate,pis_rxstarted); + frxcheckedindex:= 0; +end; + +procedure tstuffediochannel.addata(const adata: string); +var + int1,int2: integer; + po1: pchar; + str1: string; +begin + fbuffer:= fbuffer + adata; + int1:= length(fbuffer); + if (int1 >= 2) then begin + po1:= pointer(fbuffer); + if (pis_rxstarted in fpipestate) then begin + for int2:= frxcheckedindex to int1-2 do begin + if (po1[int2] = c_dle) and (po1[int2+1] = c_etx) and + ((int2 = 0) or (po1[int2-1] <> c_dle)) then begin + str1:= copy(fbuffer,int2+3,int1); //next frame + setlength(fbuffer,int2); + try + fsynchronizer.datareceived(unstuff(fbuffer)); + except + application.handleexception(self); + end; + resetrxbuffer; + if str1 <> '' then begin + addata(str1); + end; + exit; + end; + end; + end + else begin + for int2:= 0 to int1-2 do begin + if (po1[int2] = c_dle) and (po1[int2+1] = c_stx) and + ((int2 = 0) or (po1[int2-1] <> c_dle)) then begin + fbuffer:= copy(fbuffer,int2+3,int1); + include(fpipestate,pis_rxstarted); + addata(''); + exit; + end; + end; + end; + repeat + dec(int1); + until (int1 = 0) or (po1[int1] <> c_dle); + frxcheckedindex:= int1; + end; +end; + +procedure tstuffediochannel.receivelocaldata(const adata: string); +begin + addata(adata); +end; + +function tstuffediochannel.stuff(const adata: string): string; +var + int1: integer; + po1,po2: pchar; +begin + setlength(result,2*length(adata)); //max + po1:= pointer(adata); + po2:= pointer(result); + for int1:= 0 to length(adata) - 1 do begin + po2^:= po1[int1]; + if po2^ = stuffchar then begin + inc(po2); + po2^:= stuffchar; + end; + inc(po2); + end; + setlength(result,po2-pointer(result)); +end; + +function tstuffediochannel.unstuff(const adata: string): string; +var +// int1: integer; + po1,po2,po3: pchar; +begin + setlength(result,length(adata)); //max + po1:= pointer(adata); + po3:= po1 + length(adata); + po2:= pointer(result); + while po1 < po3 do begin + po2^:= po1^; + if (po1^ = stuffchar) and (po1[1] = stuffchar) then begin + inc(po1); + end; + inc(po1); + inc(po2); + end; + setlength(result,po2-pointer(result)); +end; + +{ tcustompipeiochannel } + +constructor tcustompipeiochannel.create(aowner: tcomponent); +begin + if frx = nil then begin + frx:= tpipereader.create; + end; + if ftx = nil then begin + ftx:= tpipewriter.create; + end; + fprochandle:= invalidprochandle; + frx.oninputavailable:= {$ifdef FPC}@{$endif}doinputavailable; + frx.onpipebroken:= {$ifdef FPC}@{$endif}dopipebroken; + inherited; +end; + +destructor tcustompipeiochannel.destroy; +begin + inherited; + ftx.free; + frx.free; +end; + +procedure tcustompipeiochannel.internalconnect; +begin + resetrxbuffer; + if fserverapp <> '' then begin + fprochandle:= execmse2(fserverapp,ftx,frx,nil,{false,}-1,[exo_inactive] + {true,false}); + end + else begin + ftx.connect(sys_stdout); + frx.connect(sys_stdin); + end; +end; + +procedure tcustompipeiochannel.internaldisconnect; +var + int1: integer; +begin + ftx.close; + frx.close; + fbuffer:= ''; + if fprochandle <> invalidprochandle then begin + int1:= fprochandle; + fprochandle:= invalidprochandle; + killprocess(int1); + end; +end; + +function tcustompipeiochannel.commio: boolean; +begin + result:= inherited commio or + ((fserverapp = '') or (fprochandle <> invalidprochandle)) + and frx.active; +end; + +procedure tcustompipeiochannel.localsenddata(const adata: ansistring); +begin + flocalconn.receivelocaldata(stx+stuff(adata)+etx); +end; + +procedure tcustompipeiochannel.internalsenddata(const adata: ansistring); +begin + ftx.writestr(stx+stuff(adata)+etx); +end; + +procedure tcustompipeiochannel.doinputavailable(const sender: tpipereader); +begin + addata(sender.readdatastring); +end; + +procedure tcustompipeiochannel.dopipebroken(const sender: tpipereader); +begin + asyncevent(closepipestag); +end; + +procedure tcustompipeiochannel.doasyncevent(var atag: integer); +begin + if atag = closepipestag then begin + disconnect; + end + else begin + inherited; + end; +end; + +{ tpipeifichannel } +{ +constructor tpipeifichannel.create(aowner: tcomponent); +begin + fsynchronizer:= tifisynchronizer.create; + inherited; +end; +} +{ tsocketpipeiochannel } +{ +constructor tsocketpipeiochannel.create(aowner: tcomponent); +begin + if freader = nil then begin + freader:= tsocketreader.create; + end; + if fwriter = nil then begin + fwriter:= tsocketwriter.create; + end; + inherited; +end; +} +{ tiosynchronizer } + +constructor tiosynchronizer.create(const aondatareceived: stringdataprocty); +begin + fondatareceived:= aondatareceived; + fwaitingclients:= tintegeravltree.create; + inherited create; +end; + +destructor tiosynchronizer.destroy; +begin + fwaitingclients.free; + inherited; +end; + +procedure tiosynchronizer.answerreceived(const asequence: sequencety); +var + client1: twaitingclient; +begin + if fwaitingclients.find(integer(asequence),tintegeravlnode(client1)) then begin + client1.answered; + end; +end; + +function tiosynchronizer.preparewait(const asequence: sequencety): twaitingclient; +begin + if threadty(getcurrentthreadid) = id then begin + raise exception.create('Deadlock in tiosynchrionizer.waitforanswer.'); + end; + result:= twaitingclient.create(asequence); + fwaitingclients.addnode(result); +end; + +function tiosynchronizer.waitforanswer(const aclient: twaitingclient; + const waitus: integer): boolean; +var + int1: integer; +begin + int1:= application.unlockall; + try + result:= aclient.wait(waitus); + finally + application.relockall(int1); + end; + fwaitingclients.removenode(aclient); + aclient.free; +end; + +procedure tiosynchronizer.datareceived(const adata: string); +begin + postevent(tstringevent.create(adata)); +end; + +procedure tiosynchronizer.eventloop; +var + str1: string; + event: tstringevent; +begin + while not terminated do begin + event:= tstringevent(waitevent); + if event <> nil then begin + str1:= event.data; + event.free1; + application.lock; + try + fondatareceived(str1); + except + application.handleexception(self); + end; + application.unlock; + end; + end; +end; + +function tiosynchronizer.execute(thread: tmsethread): integer; +begin + eventloop; + result:= 0; +end; + +{ twaitingclient } + +constructor twaitingclient.create(const asequence: sequencety); +begin + sys_semcreate(fsem,0); + inherited create(integer(asequence)); +end; + +destructor twaitingclient.destroy; +begin + sys_semdestroy(fsem); +end; + +procedure twaitingclient.answered; +begin + sys_sempost(fsem); +end; + +function twaitingclient.wait(const awaitus: integer): boolean; +begin + result:= sys_semwait(fsem,awaitus) = sye_ok; +// application.processmessages; +end; + +{ tifisocketclient } +{ +constructor tifisocketclient.create(aowner: tcomponent); +begin + fpipes:= tifisocketclientpipes.create(self); + inherited; +end; +} +{ tsocketclientiochannel } + +constructor tsocketclientiochannel.create(aowner: tcomponent); +begin + fsocket:= tifisocketclient.create(self{nil}); + fsocket.setsubcomponent(true); + fsocket.pipes.rx.oninputavailable:= {$ifdef FPC}@{$endif}doinputavailable; + fsocket.pipes.onbeforedisconnect:= {$ifdef FPC}@{$endif}dobeforedisconnect; + inherited; +end; + +destructor tsocketclientiochannel.destroy; +begin + freeandnil(fsocket);; + inherited; +end; + +procedure tsocketclientiochannel.internalconnect; +begin + fsocket.active:= true; +end; + +procedure tsocketclientiochannel.internaldisconnect; +begin + if fsocket <> nil then begin + fsocket.active:= false; + end; +end; + +function tsocketclientiochannel.commio: boolean; +begin + result:= inherited commio or (fsocket.active and fsocket.pipes.rx.active); +end; + +procedure tsocketclientiochannel.internalsenddata(const adata: ansistring); +begin + fsocket.pipes.tx.writestr(stx+stuff(adata)+etx); +end; + +procedure tsocketclientiochannel.localsenddata(const adata: ansistring); +begin + flocalconn.receivelocaldata(stx+stuff(adata)+etx); +end; + +procedure tsocketclientiochannel.doinputavailable(const sender: tpipereader); +begin + addata(sender.readdatastring); +end; + +procedure tsocketclientiochannel.setsocket(const avalue: tifisocketclient); +begin + fsocket.assign(avalue); +end; + +procedure tsocketclientiochannel.dobeforedisconnect( + const sender: tcustomcommpipes); +begin + disconnect; +end; + +{ tsocketclientifichannel } +{ +constructor tsocketclientifichannel.create(aowner: tcomponent); +begin + fsynchronizer:= tifisynchronizer.create; + inherited; +end; +} +{ tcustomsocketserveriochannel } + +destructor tcustomsocketserveriochannel.destroy; +begin + unlink; + inherited; +end; + +procedure tcustomsocketserveriochannel.link(const apipes: tcustomcommpipes); +begin + unlink; + dobeforeconnect; + setlinkedvar(apipes,tlinkedpersistent(fpipes)); + fpipes.onbeforedisconnect:= {$ifdef FPC}@{$endif}dobeforedisconnect; + fpipes.rx.oninputavailable:= {$ifdef FPC}@{$endif}doinputavailable; + doafterconnect; +end; + +procedure tcustomsocketserveriochannel.unlink; +begin + if funlinking = 0 then begin + inc(funlinking); + try + if fpipes <> nil then begin + fpipes.rx.oninputavailable:= nil; + fpipes.close; + end; + finally + setlinkedvar(nil,tlinkedpersistent(fpipes)); +// fpipes:= nil; + dec(funlinking); + end; + end; +end; + +procedure tcustomsocketserveriochannel.internalconnect; +begin + raise exception.create('Not implemented.'); +end; + +procedure tcustomsocketserveriochannel.internaldisconnect; +begin + if fpipes <> nil then begin + fpipes.close; + end; +end; + +function tcustomsocketserveriochannel.commio: boolean; +begin + result:= inherited commio or (fpipes <> nil) and fpipes.rx.active; +end; + +procedure tcustomsocketserveriochannel.internalsenddata(const adata: ansistring); +begin + fpipes.tx.writestr(stx+stuff(adata)+etx); +end; + +procedure tcustomsocketserveriochannel.localsenddata(const adata: ansistring); +begin + flocalconn.receivelocaldata(stx+stuff(adata)+etx); +end; + +procedure tcustomsocketserveriochannel.doinputavailable(const sender: tpipereader); +begin + addata(sender.readdatastring); +end; + +procedure tcustomsocketserveriochannel.dobeforedisconnect( + const sender: tcustomcommpipes); +begin + disconnect; + unlink; +end; + +function tcustomsocketserveriochannel.canconnect: boolean; +begin + result:= false; +end; + +{ tsocketserveriochannel } + +{ tifiiolinkcomponent } + +procedure tifiiolinkcomponent.setchannel(const avalue: tcustomiochannel); +begin + setlinkedvar(avalue,tmsecomponent(fchannel)); +// avalue.fsynchronizer.onsynchronize:= @ifidatasynchronize; +end; + +{ tsocketserverifichannel } +{ +constructor tsocketserverifichannel.create(aowner: tcomponent); +begin + fsynchronizer:= tifisynchronizer.create; + inherited; +end; +} +{ tsocketserverstdifichannel } +{ +constructor tsocketserverstdifichannel.create(aowner: tcomponent); +begin + fsynchronizer:= tifisynchronizer.create; + inherited; +end; +} +{ tsocketstdiochannel } + +constructor tsocketstdiochannel.create(aowner: tcomponent); +begin + frx:= tsocketreader.create(nil); //todo: test!!!!!! + tsocketreader1(frx).fonafterconnect:= {$ifdef FPC}@{$endif}doafterconnect; + ftx:= tsocketwriter.create(nil); + inherited; +end; + +procedure tsocketstdiochannel.setcryptoio(const avalue: tcryptoio); +begin + setlinkedvar(avalue,tmsecomponent(fcryptoio)); +end; +{ +procedure tsocketstdiochannel.doafterconnect; +begin + fcryptioinfo.handler:= fcryptio; + connectcryptio(tsocketwriter(ftx),tsocketreader(frx),fcryptioinfo); +end; +} +procedure tsocketstdiochannel.internalconnect; +begin +// fcryptioinfo.handler:= fcryptio; + connectcryptoio(fcryptoio,tsocketwriter(ftx),tsocketreader(frx),fcryptoioinfo, + sys_stdout,sys_stdin); + inherited; +end; + +procedure tsocketstdiochannel.internaldisconnect; +begin + inherited; + cryptounlink(fcryptoioinfo); +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseificomp.pas b/mseide-msegui/lib/common/ifi/mseificomp.pas new file mode 100644 index 0000000..ed0fd36 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseificomp.pas @@ -0,0 +1,5392 @@ +{ MSEgui Copyright (c) 2009-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + experimental user <-> business logic connection components. + Warning: works with RTTI and is therefore slow. +} +{$ifdef FPC} + {$if defined(FPC) and (fpc_fullversion >= 020501)} + {$define mse_fpc_2_6} + {$ifend} + {$if defined(FPC) and (fpc_fullversion >= 030000)} + {$define mse_fpc_3_0} + {$ifend} + {$ifdef mse_fpc_2_6} + {$define mse_hasvtunicodestring} + {$endif} + {$ifdef mse_fpc_3_0} + {$define mse_hastkpointer} + {$endif} +{$endif} +unit mseificomp; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,{msegui,}mseifiglob,mseglob,typinfo,msestrings, + msetypes,mseinterfaces,msetimer, + mseificompglob,msearrayprops,msedatalist,msestat,msestatfile,mseapplication, + mseeditglob; + +type + tifilinkcomp = class; + tifivaluelinkcomp = class; + tcustomificlientcontroller = class; + tstringclientcontroller = class; + tintegerclientcontroller = class; + tint64clientcontroller = class; + tpointerclientcontroller = class; + tbooleanclientcontroller = class; + trealclientcontroller = class; + tdatetimeclientcontroller = class; + + ifieventty = procedure(const sender: tcustomificlientcontroller) of object; + ificlienteventty = procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient) of object; + ifistringclienteventty = procedure(const sender: tstringclientcontroller; + const aclient: iifidatalink) of object; + ifiintegerclienteventty = procedure(const sender: tintegerclientcontroller; + const aclient: iifidatalink) of object; + ifiint64clienteventty = procedure(const sender: tint64clientcontroller; + const aclient: iifidatalink) of object; + ifipointerclienteventty = procedure(const sender: tpointerclientcontroller; + const aclient: iifidatalink) of object; + ifibooleanclienteventty = procedure(const sender: tbooleanclientcontroller; + const aclient: iifidatalink) of object; + ifirealclienteventty = procedure(const sender: trealclientcontroller; + const aclient: iifidatalink) of object; + ifidatetimeclienteventty = procedure(const sender: tdatetimeclientcontroller; + const aclient: iifidatalink) of object; + + ificlientstateeventty = procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; + const astate: ifiwidgetstatesty; + const achangedstate: ifiwidgetstatesty) of object; + ificlientmodalresulteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; + const amodalresult: modalresultty) of object; + ificlientclosequeryeventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; + var amodalresult: modalresultty) of object; + + ifivaluelinkstatety = (ivs_linking,ivs_valuesetting,ivs_loadedproc); + ifivaluelinkstatesty = set of ifivaluelinkstatety; + valueclientoptionty = (vco_datalist,vco_nosync,vco_novaluetoclient, + vco_readonly,vco_notnull); + valueclientoptionsty = set of valueclientoptionty; + + tcustomificlientcontroller = class(tlinkedpersistent,iifidataserver,istatfile) + private + fonclientvaluechanged: ificlienteventty; + fonclientexecute: ificlienteventty; + fonclientstatechanged: ificlientstateeventty; + fonclientmodalresult: ificlientmodalresulteventty; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: integer; + fonchangebefore: ifieventty; + fonchangeafter: ifieventty; + fonclientclosequery: ificlientclosequeryeventty; + function getintegerpro(const aname: string): integer; + procedure setintegerpro(const aname: string; const avalue: integer); + function getmsestringpro(const aname: string): msestring; + procedure setmsestringpro(const aname: string; const avalue: msestring); + function getbooleanpro(const aname: string): boolean; + procedure setbooleanpro(const aname: string; const avalue: boolean); + function getrealtypro(const aname: string): realty; + procedure setrealtypro(const aname: string; const avalue: realty); + function getdatetimepro(const aname: string): tdatetime; + procedure setdatetimepro(const aname: string; const avalue: tdatetime); + procedure setstatfile(const avalue: tstatfile); + protected + fowner: tmsecomponent; + fkind: ttypekind; + fstate: ifivaluelinkstatesty; + foptionsvalue: valueclientoptionsty; + fwidgetstate: ifiwidgetstatesty; + fwidgetstatebefore: ifiwidgetstatesty; + fchangedclient: pointer; + + fapropname: string; + fapropkind: ttypekind; + fapropvalue: pointer; + + procedure dogetprop(const alink: pointer); + procedure getprop(const aname: string; const akind: ttypekind; + const avaluepo: pointer); + procedure dosetprop(const alink: pointer); + procedure setprop(const aname: string; const akind: ttypekind; + const avaluepo: pointer); + procedure finalizelink(const alink: pointer); + procedure finalizelinks; + procedure loaded; virtual; + function errorname(const ainstance: tobject): string; + procedure interfaceerror; + function getifilinkkind: ptypeinfo; virtual; + function checkcomponent(const aintf: iifilink): pointer; virtual; + //returns interface info, exception if link invalid + procedure valuestootherclient(const alink: pointer); + procedure valuestoclient(const alink: pointer); virtual; + procedure clienttovalues(const alink: pointer); virtual; + procedure change(const alink: iificlient = nil); +// procedure change(); + procedure linkset(const alink: iificlient); virtual; + + function setmsestringval(const alink: iificlient; const aname: string; + const avalue: msestring): boolean; + //true if found + function getmsestringval(const alink: iificlient; const aname: string; + var avalue: msestring): boolean; + //true if found + function setintegerval(const alink: iificlient; const aname: string; + const avalue: integer): boolean; + //true if found + function getintegerval(const alink: iificlient; const aname: string; + var avalue: integer): boolean; + //true if found + function setint64val(const alink: iificlient; const aname: string; + const avalue: int64): boolean; + //true if found + function getint64val(const alink: iificlient; const aname: string; + var avalue: int64): boolean; + //true if found + function setpointerval(const alink: iifidatalink; const aname: string; + const avalue: pointer): boolean; + //true if found + function getpointerval(const alink: iifidatalink; const aname: string; + var avalue: pointer): boolean; + //true if found + function setbooleanval(const alink: iificlient; const aname: string; + const avalue: boolean): boolean; + //true if found + function getbooleanval(const alink: iificlient; const aname: string; + var avalue: boolean): boolean; + //true if found + function setrealtyval(const alink: iificlient; const aname: string; + const avalue: realty): boolean; + //true if found + function getrealtyval(const alink: iificlient; const aname: string; + var avalue: realty): boolean; + //true if found + function setdatetimeval(const alink: iificlient; const aname: string; + const avalue: tdatetime): boolean; + //true if found + function getdatetimeval(const alink: iificlient; const aname: string; + var avalue: tdatetime): boolean; + //true if found + procedure distribute(const sender: iificlient; + const local: boolean; const exec: boolean); virtual; + //iifiserver + procedure execute(const sender: iificlient); virtual; + procedure valuechanged(const sender: iifidatalink); + procedure statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); virtual; + procedure setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); virtual; + procedure dataentered(const sender: iificlient; const arow: integer); virtual; + procedure closequery(const sender: iificlient; + var amodalresult: modalresultty); virtual; + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); virtual; + procedure updateoptionsedit(var avalue: optionseditty); virtual; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(const aowner: tmsecomponent; const akind: ttypekind); + reintroduce; overload; + constructor create(const aowner: tmsecomponent); overload; virtual; + function canconnect(const acomponent: tcomponent): boolean; virtual; + + property msestringprop[const aname: string]: msestring read getmsestringpro + write setmsestringpro; + property integerprop[const aname: string]: integer read getintegerpro + write setintegerpro; + property booleanprop[const aname: string]: boolean read getbooleanpro + write setbooleanpro; + property realtyprop[const aname: string]: realty read getrealtypro + write setrealtypro; + property datetimeprop[const aname: string]: tdatetime read getdatetimepro + write setdatetimepro; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read fstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property onchangebefore: ifieventty read fonchangebefore + write fonchangebefore; + //for data change and execute + property onchangeafter: ifieventty read fonchangeafter write fonchangeafter; + //for data change and execute + property onclientvaluechanged: ificlienteventty read fonclientvaluechanged + write fonclientvaluechanged; + property onclientstatechanged: ificlientstateeventty + read fonclientstatechanged write fonclientstatechanged; + property onclientclosequery: ificlientclosequeryeventty + read fonclientclosequery write fonclientclosequery; + property onclientmodalresult: ificlientmodalresulteventty + read fonclientmodalresult write fonclientmodalresult; + property onclientexecute: ificlienteventty read fonclientexecute + write fonclientexecute; + end; + + customificlientcontrollerclassty = class of tcustomificlientcontroller; + + tificlientcontroller = class(tcustomificlientcontroller) + published + property statfile; + property statvarname; + property statpriority; + property onchangebefore; + property onchangeafter; + { + property onclientvaluechanged; + } + property onclientstatechanged; + property onclientclosequery; + property onclientmodalresult; + property onclientexecute; + end; + + texecclientcontroller = class(tificlientcontroller) + private + fenabled: boolean; + procedure setenabled(const avalue: boolean); + protected + function getifilinkkind: ptypeinfo; override; + procedure setclientenabled(const alink: pointer); + procedure valuestoclient(const alink: pointer); override; + procedure execute(const sender: iificlient) override; + procedure linkset(const alink: iificlient); override; + procedure dostatread(const reader: tstatreader) override; + procedure dostatwrite(const writer: tstatwriter) override; + public + constructor create(const aowner: tmsecomponent); override; + function canconnect(const acomponent: tcomponent): boolean; override; + procedure execute; reintroduce; + published + property optionsvalue: valueclientoptionsty read foptionsvalue + write foptionsvalue default []; + property enabled: boolean read fenabled write setenabled default true; + property onclientvaluechanged; + end; + + tformclientcontroller = class(tificlientcontroller) + private + procedure setmodalresult(const avalue: modalresultty); + protected + fmodalresult: modalresultty; + function getifilinkkind: ptypeinfo; override; +// procedure execute(const sender: iificlient); overload; override; + procedure linkset(const alink: iificlient) override; + procedure valuestoclient(const alink: pointer) override; + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty) override; + public + property modalresult: modalresultty read fmodalresult write setmodalresult; + property onclientvaluechanged; + end; + + valarsetterty = procedure(const alink: pointer; var handled: boolean) of object; + valargetterty = procedure(const alink: pointer; var handled: boolean) of object; + + itemsetterty = procedure(const alink: pointer; var handled: boolean) of object; + itemgetterty = procedure(const alink: pointer; var handled: boolean) of object; + + tifidatasource = class; + ififieldnamety = type ansistring; //type for property editor + ifisourcefieldnamety = type ansistring; //type for property editor + + iififieldinfo = interface(inullinterface)[miid_iififieldinfo] + procedure getfieldinfo(const apropname: ififieldnamety; + var adatasource: tifidatasource; + var atypes: listdatatypesty); + end; + + iifidatasourceclient = interface(iobjectlink) + function getobjectlinker: tobjectlinker; + procedure bindingchanged; + function ifigriddata: tdatalist; + function ififieldname: string; + end; + + indexeventty = procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; const aindex: integer) of object; + + setbooleanclienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: boolean; + var accept: boolean; const aindex: integer) of object; + setstringclienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: msestring; + var accept: boolean; const aindex: integer) of object; + setansistringclienteventty = procedure( + const sender: tcustomificlientcontroller; + var avalue: ansistring; + var accept: boolean; const aindex: integer) of object; + setintegerclienteventty = + procedure(const sender: tobject; const aclient: iificlient; + var avalue: integer; + var accept: boolean; const aindex: integer) of object; + //equal parameters as setcoloreventty for tcoloredit! + setint64clienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: int64; + var accept: boolean; const aindex: integer) of object; + setpointerclienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: pointer; + var accept: boolean; const aindex: integer) of object; + setrealclienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: realty; + var accept: boolean; const aindex: integer) of object; + setdatetimeclienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: tdatetime; + var accept: boolean; const aindex: integer) of object; + + tvalueclientcontroller = class(tificlientcontroller, + iififieldinfo,iifidatasourceclient) + private +// fvalarpo: pointer; + fitempo: pointer; +// fitemindex: integer; + fonclientdataentered: indexeventty; + fdatasource: tifidatasource; + ffieldname: ififieldnamety; + procedure setoptionsvalue(const avalue: valueclientoptionsty); + procedure setdatasource(const avalue: tifidatasource); + procedure setfieldname(const avalue: ififieldnamety); + procedure linkdatalist1(const alink: pointer); + procedure updatereadonlystate1(const alink: pointer); + protected + fdatalist: tdatalist; + procedure updateoptionsedit(var avalue: optionseditty); override; + procedure linkset(const alink: iificlient); override; + + function getifilinkkind: ptypeinfo; override; + procedure setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); override; + procedure dataentered(const sender: iificlient; + const arow: integer); override; + procedure loaded; override; + procedure statreadvalue(const reader: tstatreader); virtual; + procedure statwritevalue(const reader: tstatwriter); virtual; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + + procedure linkdatalist; + procedure updatereadonlystate; + procedure optionsvaluechanged; virtual; + function createdatalist: tdatalist; virtual; abstract; + function getlistdatatypes: listdatatypesty; virtual; abstract; + procedure statreadlist(const alink: pointer); + procedure statwritelist(const alink: pointer; var handled: boolean); + //iifidatasourceclient + procedure bindingchanged; + function ifigriddata: tdatalist; + function ififieldname: string; + //iififieldinfo + procedure getfieldinfo(const apropname: ififieldnamety; + var adatasource: tifidatasource; + var atypes: listdatatypesty); + public + destructor destroy; override; + function canconnect(const acomponent: tcomponent): boolean; override; + property datalist: tdatalist read fdatalist; + published + property onclientdataentered: indexeventty read fonclientdataentered + write fonclientdataentered; + property optionsvalue: valueclientoptionsty read foptionsvalue + write setoptionsvalue default []; + property datasource: tifidatasource read fdatasource write setdatasource; + property fieldname: ififieldnamety read ffieldname write setfieldname; + end; + + tifimsestringdatalist = class; + + tstringclientcontroller = class(tvalueclientcontroller) + private + fvalue: msestring; + fvaluedefault: msestring; + fonclientsetvalue: setstringclienteventty; + procedure setvalue1(const avalue: msestring); + function getgriddata: tifimsestringdatalist; + function getonclientvaluechanged: ifistringclienteventty; + procedure setonclientvaluechanged(const avalue: ifistringclienteventty); + protected + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifimsestringdatalist read getgriddata; +// property gridvalues: msestringarty read getgridvalues write setgridvalues; +// property gridvalue[const index: integer]: msestring read getgridvalue +// write setgridvalue; + published + property value: msestring read fvalue write setvalue1; + property valuedefault: msestring read fvaluedefault write fvaluedefault; + property onclientsetvalue: setstringclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifistringclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tifidropdowncol = class(tmsestringdatalist,iififieldinfo,iifidatasourceclient) + private + fdatasource: tifidatasource; + fdatafield: ififieldnamety; + procedure setdatasource(const avalue: tifidatasource); + procedure setdatafield(const avalue: ififieldnamety); + protected + //iifidatasourceclient + procedure bindingchanged; + function ifigriddata: tdatalist; + function ififieldname: string; + //iififieldinfo + procedure getfieldinfo(const apropname: ififieldnamety; + var adatasource: tifidatasource; + var atypes: listdatatypesty); + published + property datasource: tifidatasource read fdatasource write setdatasource; + property datafield: ififieldnamety read fdatafield write setdatafield; + end; + + tifidropdownlistcontroller = class; + + tifidropdowncols = class(townedpersistentarrayprop) + private + function getitems(const index: integer): tifidropdowncol; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure colchanged(const sender: tobject); + procedure dochange(const index: integer); override; + public + class function getitemclasstype: persistentclassty; override; + constructor create(const aowner: tifidropdownlistcontroller); reintroduce; + property items[const index: integer]: tifidropdowncol read getitems; default; + end; + + iifidropdownlistdatalink = interface(iifidatalink) + procedure ifidropdownlistchanged(const acols: tifidropdowncols); + end; + + tifidropdownlistcontroller = class(teventpersistent) + private + fcols: tifidropdowncols; + fowner: tvalueclientcontroller; + procedure setcols(const avalue: tifidropdowncols); + procedure valuestoclient(const alink: pointer); + public + constructor create(const aowner: tvalueclientcontroller); reintroduce; + destructor destroy; override; + published + property cols: tifidropdowncols read fcols write setcols; + end; + + tdropdownlistclientcontroller = class(tstringclientcontroller) + private + fdropdown: tifidropdownlistcontroller; + procedure setdropdown(const avalue: tifidropdownlistcontroller); + protected + function getifilinkkind: ptypeinfo; override; + procedure valuestoclient(const alink: pointer); override; + public + constructor create(const aowner: tmsecomponent); override; + destructor destroy; override; + published + property dropdown: tifidropdownlistcontroller read fdropdown write setdropdown; + end; + + tifiintegerdatalist = class; + + tintegerclientcontroller = class(tvalueclientcontroller) + private + fvalue: integer; + fvaluedefault: integer; + fvaluemin: integer; + fvaluemax: integer; + fonclientsetvalue: setintegerclienteventty; + procedure setvalue1(const avalue: integer); + procedure setvaluemin(const avalue: integer); + procedure setvaluemax(const avalue: integer); + function getgriddata: tifiintegerdatalist; + procedure readmin(reader: treader); + procedure readmax(reader: treader); + function getonclientvaluechanged: ifiintegerclienteventty; + procedure setonclientvaluechanged(const avalue: ifiintegerclienteventty); + protected + procedure defineproperties(filer: tfiler) override; + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifiintegerdatalist read getgriddata; + published + property value: integer read fvalue write setvalue1 default 0; + property valuedefault: integer read fvaluedefault + write fvaluedefault default 0; + property valuemin: integer read fvaluemin write setvaluemin default 0; + property valuemax: integer read fvaluemax write setvaluemax default maxint; + property onclientsetvalue: setintegerclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifiintegerclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tifiint64datalist = class; + + tint64clientcontroller = class(tvalueclientcontroller) + private + fvalue: int64; + fvaluedefault: int64; + fvaluemin: int64; + fvaluemax: int64; + fonclientsetvalue: setint64clienteventty; + procedure setvalue1(const avalue: int64); + procedure setvaluemin(const avalue: int64); + procedure setvaluemax(const avalue: int64); + function getgriddata: tifiint64datalist; + procedure readmin(reader: treader); + procedure readmax(reader: treader); + function getonclientvaluechanged: ifiint64clienteventty; + procedure setonclientvaluechanged(const avalue: ifiint64clienteventty); + protected + procedure defineproperties(filer: tfiler) override; + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifiint64datalist read getgriddata; + published + property value: int64 read fvalue write setvalue1 default 0; + property valuedefault: int64 read fvaluedefault + write fvaluedefault default 0; + property valuemin: int64 read fvaluemin write setvaluemin default 0; + property valuemax: int64 read fvaluemax write setvaluemax default maxint; + property onclientsetvalue: setint64clienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifiint64clienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tifipointerdatalist = class; + + tpointerclientcontroller = class(tvalueclientcontroller) + private + fvalue: pointer; + fonclientsetvalue: setpointerclienteventty; + procedure setvalue1(const avalue: pointer); + function getgriddata: tifipointerdatalist; + function getonclientvaluechanged: ifipointerclienteventty; + procedure setonclientvaluechanged(const avalue: ifipointerclienteventty); + protected + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + function getlistdatatypes: listdatatypesty; override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifipointerdatalist read getgriddata; + property value: pointer read fvalue write setvalue1 default nil; + published + property onclientsetvalue: setpointerclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifipointerclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tenumclientcontroller = class(tintegerclientcontroller) + private + fdropdown: tifidropdownlistcontroller; + procedure setdropdown(const avalue: tifidropdownlistcontroller); + protected + function getifilinkkind: ptypeinfo; override; + procedure valuestoclient(const alink: pointer); override; + public + constructor create(const aowner: tmsecomponent); override; + destructor destroy; override; + published + property dropdown: tifidropdownlistcontroller read fdropdown write setdropdown; + property value default -1; + property valuedefault default -1; + property valuemin default -1; + end; + + tifibooleandatalist = class; + + tbooleanclientcontroller = class(tvalueclientcontroller) + private + fvalue: longbool; + fvaluedefault: longbool; + fonclientsetvalue: setbooleanclienteventty; + function getvalue: boolean; + procedure setvalue1(const avalue: boolean); + function getvaluedefault: boolean; + procedure setvaluedefault(const avalue: boolean); +// function getgridvalues: longboolarty; +// procedure setgridvalues(const avalue: longboolarty); +// function getgridvalue(const index: integer): boolean; +// procedure setgridvalue(const index: integer; const avalue: boolean); + function getgriddata: tifibooleandatalist; + function getonclientvaluechanged: ifibooleanclienteventty; + procedure setonclientvaluechanged(const avalue: ifibooleanclienteventty); + protected + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifibooleandatalist read getgriddata; +// property gridvalues: longboolarty read getgridvalues write setgridvalues; +// property gridvalue[const index: integer]: boolean read getgridvalue +// write setgridvalue; + published + property value: boolean read getvalue write setvalue1 default false; + property valuedefault: boolean read getvaluedefault write setvaluedefault + default false; + property onclientsetvalue: setbooleanclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifibooleanclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tifirealdatalist = class; + + trealclientcontroller = class(tvalueclientcontroller) + private + fvalue: realty; + fvaluedefault: realty; + fvaluemin: realty; + fvaluemax: realty; + fonclientsetvalue: setrealclienteventty; + procedure setvalue1(const avalue: realty); + procedure setvaluemin(const avalue: realty); + procedure setvaluemax(const avalue: realty); + procedure readvalue(reader: treader); + procedure readmin1(reader: treader); + procedure readmax1(reader: treader); + procedure readvaluedefault(reader: treader); + function getgriddata: tifirealdatalist; + procedure readmin(reader: treader); + procedure readmax(reader: treader); + function getonclientvaluechanged: ifirealclienteventty; + procedure setonclientvaluechanged(const avalue: ifirealclienteventty); + protected + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + procedure defineproperties(filer: tfiler); override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifirealdatalist read getgriddata; +// property gridvalues: realarty read getgridvalues write setgridvalues; +// property gridvalue[const index: integer]: real read getgridvalue +// write setgridvalue; + published + property value: realty read fvalue write setvalue1 {stored false}; + property valuedefault: realty read fvaluedefault + write fvaluedefault {stored false}; + property valuemin: realty read fvaluemin write setvaluemin {stored false}; + property valuemax: realty read fvaluemax write setvaluemax {stored false}; + property onclientsetvalue: setrealclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifirealclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tifidatetimedatalist = class; + + tdatetimeclientcontroller = class(tvalueclientcontroller) + private + fvalue: tdatetime; + fvaluedefault: tdatetime; + fvaluemin: tdatetime; + fvaluemax: tdatetime; + fonclientsetvalue: setdatetimeclienteventty; + procedure setvalue1(const avalue: tdatetime); + procedure setvaluemin(const avalue: tdatetime); + procedure setvaluemax(const avalue: tdatetime); + procedure readvalue(reader: treader); + procedure readmin1(reader: treader); + procedure readmax1(reader: treader); + procedure readvaluedefault(reader: treader); + function getgriddata: tifidatetimedatalist; + procedure readmin(reader: treader); + procedure readmax(reader: treader); + function getonclientvaluechanged: ifidatetimeclienteventty; + procedure setonclientvaluechanged(const avalue: ifidatetimeclienteventty); + protected + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + procedure defineproperties(filer: tfiler); override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifidatetimedatalist read getgriddata; + published + property value: tdatetime read fvalue write setvalue1 {stored false}; + property valuedefault: tdatetime read fvaluedefault + write fvaluedefault {stored false}; + property valuemin: tdatetime read fvaluemin write setvaluemin {stored false}; + property valuemax: tdatetime read fvaluemax write setvaluemax {stored false}; + property onclientsetvalue: setdatetimeclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifidatetimeclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + ificelleventty = procedure(const sender: tobject; + var info: ificelleventinfoty) of object; + ifibeforeblockeventty = procedure(const sender: tobject; + var aindex,acount: integer; const userinput: boolean) of object; + ifiafterblockeventty = procedure(const sender: tobject; + const aindex,acount: integer; const userinput: boolean) of object; + + tificolitem = class(tmsecomponentlinkitem) + private + function getlink: tifivaluelinkcomp; + procedure setlink(const avalue: tifivaluelinkcomp); + published + property link: tifivaluelinkcomp read getlink write setlink; + end; + + tifilinkcomparrayprop = class(tmsecomponentlinkarrayprop) + private + function getitems(const index: integer): tificolitem; + public + constructor create; + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tificolitem read getitems; default; + end; + + tgridclientcontroller = class; + + trowstatehandler = class(tdatalist,iifidatalink) + private + fifilink: tifivaluelinkcomp; + flistlink: listlinkinfoty; + findexpar: integer; + procedure setifilink(const avalue: tifivaluelinkcomp); + protected + fowner: tgridclientcontroller; + procedure updateclient(const alink: pointer); virtual; abstract; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); virtual; abstract; + procedure itemchanged(const sender: tcustomrowstatelist; + const aindex: integer); + //iifidatalink + procedure setifiserverintf(const aintf: iifiserver); + function getdefaultifilink: iificlient; virtual; + procedure ifisetvalue(var avalue; var accept: boolean); + procedure getifivalue(var avalue); + procedure setifivalue(const avalue); + function getifilinkkind: ptypeinfo; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; reintroduce; overload; + function getvalueprop: ppropinfo; + procedure updatereadonlystate; + property ifilink: tifivaluelinkcomp read fifilink write setifilink; + public + constructor create(const aowner: tgridclientcontroller); reintroduce; + destructor destroy; override; + procedure listdestroyed(const sender: tdatalist); override; + procedure sourcechange(const sender: tdatalist; + const aindex: integer); override; + function canlink(const asource: tdatalist; + const atag: integer): boolean; override; + end; + + tifiintegerlinkcomp = class; + + trowstateintegerhandler = class(trowstatehandler) + private + function getifilink: tifiintegerlinkcomp; + procedure setifilink(const avalue: tifiintegerlinkcomp); + public + property ifilink: tifiintegerlinkcomp read getifilink write setifilink; + end; + + tifibooleanlinkcomp = class; + + trowstatebooleanhandler = class(trowstatehandler) + private + function getifilink: tifibooleanlinkcomp; + procedure setifilink(const avalue: tifibooleanlinkcomp); + public + property ifilink: tifibooleanlinkcomp read getifilink write setifilink; + end; + + trowstatecolorhandler = class(trowstateintegerhandler) + protected + procedure updateclient(const alink: pointer); override; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); override; + end; + + trowstatefonthandler = class(trowstateintegerhandler) + protected + procedure updateclient(const alink: pointer); override; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); override; + end; + + trowstatefoldlevelhandler = class(trowstateintegerhandler) + protected + procedure updateclient(const alink: pointer); override; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); override; + end; + + trowstatehiddenhandler = class(trowstatebooleanhandler) + protected + procedure updateclient(const alink: pointer); override; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); override; + end; + + trowstatefoldissumhandler = class(trowstatebooleanhandler) + protected + procedure updateclient(const alink: pointer); override; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); override; + end; + + gridclientstatety = (gcs_itemchangelock); + gridclientstatesty = set of gridclientstatety; + + tgridclientcontroller = class(tificlientcontroller,idatalistclient) + private + frowcount: integer; + foncellevent: ificelleventty; + fdatacols: tifilinkcomparrayprop; + fcheckautoappend: boolean; + fitempo: pointer; + frowstatecolor: trowstatecolorhandler; + frowstatefont: trowstatefonthandler; + frowstatefoldlevel: trowstatefoldlevelhandler; + frowstatehidden: trowstatehiddenhandler; + frowstatefoldissum: trowstatefoldissumhandler; + fonrowsinserting: ifibeforeblockeventty; + fonrowsinserted: ifiafterblockeventty; + fonrowsdeleting: ifibeforeblockeventty; + fonrowsdeleted: ifiafterblockeventty; + procedure setrowcount(const avalue: integer); + procedure setdatacols(const avalue: tifilinkcomparrayprop); + function getrowstate: tcustomrowstatelist; + procedure statreadrowstate(const alink: pointer); + procedure statwriterowstate(const alink: pointer; var handled: boolean); + function getrowstate_color: tifiintegerlinkcomp; + procedure setrowstate_color(const avalue: tifiintegerlinkcomp); + function getrowstate_font: tifiintegerlinkcomp; + procedure setrowstate_font(const avalue: tifiintegerlinkcomp); + function getrowstate_foldlevel: tifiintegerlinkcomp; + procedure setrowstate_foldlevel(const avalue: tifiintegerlinkcomp); + function getrowstate_hidden: tifibooleanlinkcomp; + procedure setrowstate_hidden(const avalue: tifibooleanlinkcomp); + function getrowstate_foldissum: tifibooleanlinkcomp; + procedure setrowstate_foldissum(const avalue: tifibooleanlinkcomp); + protected + fgridstate: gridclientstatesty; + procedure itemchanged(const sender: tdatalist; const aindex: integer); + function getifilinkkind: ptypeinfo; override; + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure itemappendrow(const alink: pointer); + procedure getrowstate1(const alink: pointer; var handled: boolean); + procedure canclose1(const alink: pointer; var handled: boolean); + + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + function checkcomponent(const aintf: iifilink): pointer; override; + public + constructor create(const aowner: tmsecomponent); override; + destructor destroy; override; + procedure docellevent(var info: ificelleventinfoty); + procedure dorowsinserting(var index,count: integer; + const userinput: boolean); + procedure dorowsinserted(const index,count: integer; + const userinput: boolean); + procedure dorowsdeleting(var index,count: integer; + const userinput: boolean); + procedure dorowsdeleted(const index,count: integer; + const userinput: boolean); + procedure appendrow(const avalues: array of const; + const checkautoappend: boolean = false); + function canclose: boolean; + function rowempty(const arow: integer): boolean; + property rowstate: tcustomrowstatelist read getrowstate; + published + property rowcount: integer read frowcount write setrowcount default 0; + property oncellevent: ificelleventty read foncellevent write foncellevent; + property onrowsinserting: ifibeforeblockeventty read fonrowsinserting + write fonrowsinserting; + property onrowsinserted: ifiafterblockeventty read fonrowsinserted + write fonrowsinserted; + property onrowsdeleting: ifibeforeblockeventty read fonrowsdeleting + write fonrowsdeleting; + property onrowsdeleted: ifiafterblockeventty read fonrowsdeleted + write fonrowsdeleted; +// property onclientcellevent: celleventty read fclientcellevent +// write fclientcellevent; + property datacols: tifilinkcomparrayprop read fdatacols write setdatacols; +// property rowstate_font: tintegerlinkcomp read frowstate_font +// write setrowstate_font; + property rowstate_color: tifiintegerlinkcomp read getrowstate_color + write setrowstate_color; + property rowstate_font: tifiintegerlinkcomp read getrowstate_font + write setrowstate_font; + property rowstate_foldlevel: tifiintegerlinkcomp read getrowstate_foldlevel + write setrowstate_foldlevel; + property rowstate_hidden: tifibooleanlinkcomp read getrowstate_hidden + write setrowstate_hidden; + property rowstate_foldissum: tifibooleanlinkcomp read getrowstate_foldissum + write setrowstate_foldissum; + end; + + tifilinkcomp = class(tmsecomponent) + private + fcontroller: tcustomificlientcontroller; + protected + procedure setcontroller(const avalue: tcustomificlientcontroller); + function getcontrollerclass: customificlientcontrollerclassty; virtual; + procedure loaded; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property c: tcustomificlientcontroller read fcontroller + write setcontroller; + property controller: tcustomificlientcontroller read fcontroller + write setcontroller; + published + end; + + tifivaluelinkcomp = class(tifilinkcomp) + private + function getcontroller: tvalueclientcontroller; + public + property c: tvalueclientcontroller read getcontroller; + property controller: tvalueclientcontroller read getcontroller; + end; + + tifistringlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tstringclientcontroller; + procedure setcontroller(const avalue: tstringclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tstringclientcontroller read getcontroller + write setcontroller; + published + property controller: tstringclientcontroller read getcontroller + write setcontroller; + end; + + tifidropdownlistlinkcomp = class(tifistringlinkcomp) + private + function getcontroller: tdropdownlistclientcontroller; + procedure setcontroller(const avalue: tdropdownlistclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tdropdownlistclientcontroller read getcontroller + write setcontroller; + published + property controller: tdropdownlistclientcontroller read getcontroller + write setcontroller; + end; + + tifiintegerlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tintegerclientcontroller; + procedure setcontroller(const avalue: tintegerclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tintegerclientcontroller read getcontroller + write setcontroller; + published + property controller: tintegerclientcontroller read getcontroller + write setcontroller; + end; + + tifiint64linkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tint64clientcontroller; + procedure setcontroller(const avalue: tint64clientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tint64clientcontroller read getcontroller + write setcontroller; + published + property controller: tint64clientcontroller read getcontroller + write setcontroller; + end; + + tifipointerlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tpointerclientcontroller; + procedure setcontroller(const avalue: tpointerclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tpointerclientcontroller read getcontroller + write setcontroller; + published + property controller: tpointerclientcontroller read getcontroller + write setcontroller; + end; + + tifienumlinkcomp = class(tifiintegerlinkcomp) + private + function getcontroller: tenumclientcontroller; + procedure setcontroller(const avalue: tenumclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tenumclientcontroller read getcontroller + write setcontroller; + published + property controller: tenumclientcontroller read getcontroller + write setcontroller; + end; + + tifibooleanlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tbooleanclientcontroller; + procedure setcontroller(const avalue: tbooleanclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tbooleanclientcontroller read getcontroller + write setcontroller; + published + property controller: tbooleanclientcontroller read getcontroller + write setcontroller; + end; + + tifireallinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: trealclientcontroller; + procedure setcontroller(const avalue: trealclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: trealclientcontroller read getcontroller + write setcontroller; + published + property controller: trealclientcontroller read getcontroller + write setcontroller; + end; + + tifidatetimelinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tdatetimeclientcontroller; + procedure setcontroller(const avalue: tdatetimeclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tdatetimeclientcontroller read getcontroller + write setcontroller; + published + property controller: tdatetimeclientcontroller read getcontroller + write setcontroller; + end; + + tifiactionlinkcomp = class(tifilinkcomp) + private + function getcontroller: texecclientcontroller; + procedure setcontroller(const avalue: texecclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: texecclientcontroller read getcontroller + write setcontroller; + published + property controller: texecclientcontroller read getcontroller + write setcontroller; + end; + + tififormlinkcomp = class(tifilinkcomp) + private + function getcontroller: tformclientcontroller; + procedure setcontroller(const avalue: tformclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tformclientcontroller read getcontroller + write setcontroller; + published + property controller: tformclientcontroller read getcontroller + write setcontroller; + end; + + tifigridlinkcomp = class(tifilinkcomp) + private + function getcontroller: tgridclientcontroller; + procedure setcontroller(const avalue: tgridclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tgridclientcontroller read getcontroller + write setcontroller; + published + property controller: tgridclientcontroller read getcontroller + write setcontroller; + end; + + iififieldsource = interface(inullinterface)[miid_iififieldsource] + function getfieldnames(const atypes: listdatatypesty): msestringarty; + end; + + iififieldlinksource = interface(inullinterface)[miid_iififieldlinksource] + function getfieldnames(const apropname: ifisourcefieldnamety): msestringarty; + procedure setdesignsourcefieldname(const aname: ifisourcefieldnamety); + end; + + tififield = class(tvirtualpersistent) + private + ffieldname: ansistring; + fdatatype: listdatatypety; + public + published + property fieldname: ansistring read ffieldname write ffieldname; + property datatype: listdatatypety read fdatatype write fdatatype; + end; + ififieldclassty = class of tififield; + + tififields = class(tpersistentarrayprop,iififieldsource) + protected + function getififieldclass: ififieldclassty; virtual; + public + constructor create; +// function destdatalists: datalistarty; + //iififieldsource + class function getitemclasstype: persistentclassty; override; + function getfieldnames(const atypes: listdatatypesty): msestringarty; + end; + + tififieldlinks = class; + + tififieldlink = class(tififield,iififieldlinksource) + private + fsourcefieldname: ifisourcefieldnamety; + protected + fowner: tififieldlinks; + //iififieldlinksource + function getfieldnames( + const appropname: ifisourcefieldnamety): msestringarty; + procedure setdesignsourcefieldname(const aname: ifisourcefieldnamety); + {$ifndef FPC} + function _addref: integer; stdcall; + function _release: integer; stdcall; + function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; + {$endif} + public + published + property sourcefieldname: ifisourcefieldnamety read fsourcefieldname + write fsourcefieldname; + end; + ififieldlinkclassty = class of tififieldlink; + + tififieldlinks = class(tififields) + protected + function getififieldclass: ififieldlinkclassty; reintroduce; virtual; + procedure createitem(const index: integer; var item: tpersistent); override; + function getfieldnames( + const adatatype: listdatatypety): msestringarty; virtual; + public + function sourcefieldnames: stringarty; + function sourcefieldtype(const afieldname: string): listdatatypety virtual; +end; + + iifidataconnection = interface(inullinterface)[miid_iifidataconnection] + procedure fetchdata(const acolnames: array of string; + acols: array of tdatalist); + function getfieldnames(const adatatype: listdatatypety): msestringarty; + function getdatatype(const aname: ansistring): listdatatypety; + //dl_none if not found + end; + +//{$define usedelegation} not working in FPC 2.4 + tifidatasource = class(tactcomponent,iififieldsource) + private + {$ifdef usedelegation} + ffieldsourceintf: iififieldsource; + {$endif} + fopenafterread: boolean; + + fonbeforeopen: notifyeventty; + fonafteropen: notifyeventty; + findex: integer; + fnamear: stringarty; + flistar: datalistarty; + ftimer: tsimpletimer; + procedure setfields(const avalue: tififields); + {$ifdef usedelegation} + property fieldsurceintf: iififieldsource read ffieldsourceintf + implements iififieldsource; + //not working in FPC 2.4 + {$endif} + procedure getbindinginfo(const alink: pointer); + protected + factive: boolean; + frefreshing: boolean; + ffields: tififields; + procedure setactive(const avalue: boolean); override; + procedure open; virtual; + procedure afteropen; + procedure dorefresh(const sender: tobject); + procedure close; virtual; + procedure loaded; override; + procedure doactivated; override; + procedure dodeactivated; override; + procedure destdatalists(out names: stringarty; out lists: datalistarty); +{$ifndef usedelegation} + //iififieldsource + function getfieldnames(const atypes: listdatatypesty): msestringarty; +{$endif} + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure refresh(const delayus: integer = -1); + //-1 -> no delay, 0 -> in onidle + procedure checkrefresh(); //makes pending delayed refresh + property refreshing: boolean read frefreshing; + published + property fields: tififields read ffields write setfields; + property active: boolean read factive write setactive default false; + property activator; + property onbeforeopen: notifyeventty read fonbeforeopen write fonbeforeopen; + property onafteropen: notifyeventty read fonafteropen write fonafteropen; + end; + + tconnectedifidatasource = class; + tificonnectedfields = class(tififieldlinks) + protected + fowner: tconnectedifidatasource; + function getfieldnames( + const adatatype: listdatatypety): msestringarty; override; + public + constructor create(const aowner: tconnectedifidatasource); + function sourcefieldtype(const afieldname: string): listdatatypety override; + end; + + tconnectedifidatasource = class(tifidatasource) + private + fconnection: tmsecomponent; + procedure setconnection(const avalue: tmsecomponent); + function getfields: tificonnectedfields; + procedure setfields(const avalue: tificonnectedfields); + protected + fconnectionintf: iifidataconnection; + function getfieldnames(const adatatype: listdatatypety): msestringarty; + procedure open; override; + procedure close; override; + procedure checkconnection; + public + constructor create(aowner: tcomponent); override; + published + property connection: tmsecomponent read fconnection write setconnection; + property fields: tificonnectedfields read getfields write setfields; + end; + + tifiintegerdatalist = class(tintegerdatalist) + protected + fowner: tintegerclientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: tintegerclientcontroller); reintroduce; + end; + + tifiint64datalist = class(tint64datalist) + protected + fowner: tint64clientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: tint64clientcontroller); reintroduce; + end; + + tifipointerdatalist = class(tpointerdatalist) + protected + fowner: tpointerclientcontroller; + public + constructor create(const aowner: tpointerclientcontroller); reintroduce; + end; + + tifibooleandatalist = class(tbooleandatalist) + private + protected + fowner: tbooleanclientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: tbooleanclientcontroller); reintroduce; + end; + + tifirealdatalist = class(trealdatalist) + protected + fowner: trealclientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: trealclientcontroller); reintroduce; + end; + + tifidatetimedatalist = class(tdatetimedatalist) + protected + fowner: tdatetimeclientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: tdatetimeclientcontroller); reintroduce; + end; + + tifimsestringdatalist = class(tmsestringdatalist) + protected + fowner: tstringclientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: tstringclientcontroller); reintroduce; + end; + +procedure setifilinkcomp(const alink: iifilink; + const alinkcomp: tifilinkcomp; var dest: tifilinkcomp); +procedure setifidatasource(const aintf: iifidatasourceclient; + const source: tifidatasource; var dest: tifidatasource); + +implementation +uses + sysutils,msereal,msestreaming; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + valuevarname = '_value'; + listvarname = '_list'; +// arvaluevarname = 'arvalue'; + rowstatevarname = '_rowstate'; + +type + tmsecomponent1 = class(tmsecomponent); + tdatalist1 = class(tdatalist); + +procedure setifilinkcomp(const alink: iifilink; + const alinkcomp: tifilinkcomp; var dest: tifilinkcomp); +var + po1: pointer; +begin + alink.setifiserverintf(nil); + po1:= nil; + if alinkcomp <> nil then begin + po1:= alinkcomp.fcontroller.checkcomponent(alink); + end; + alink.getobjectlinker.setlinkedvar(alink,alinkcomp,tmsecomponent(dest),po1); + if dest <> nil then begin + alink.setifiserverintf(iifidataserver(dest.fcontroller)); + if (alinkcomp is tifivaluelinkcomp) and + not (csloading in alinkcomp.componentstate) and + (vco_datalist in + tifivaluelinkcomp(alinkcomp).controller.optionsvalue) then begin + iifidatalink(alink).updateifigriddata(alinkcomp, + tifivaluelinkcomp(alinkcomp).controller.fdatalist); + end; + dest.fcontroller.linkset(alink); +// dest.fcontroller.change(alink); + end; +end; + +procedure setifidatasource(const aintf: iifidatasourceclient; + const source: tifidatasource; var dest: tifidatasource); +begin + aintf.getobjectlinker.setlinkedvar(aintf,source,tmsecomponent(dest), + typeinfo(iifidatasourceclient)); + aintf.bindingchanged; +end; + +{ tcustomificlientcontroller} + +constructor tcustomificlientcontroller.create(const aowner: tmsecomponent; + const akind: ttypekind); +begin + fowner:= aowner; + fkind:= akind; + inherited create; +end; + +constructor tcustomificlientcontroller.create(const aowner: tmsecomponent); +begin + create(aowner,tkunknown); +end; + +procedure tcustomificlientcontroller.interfaceerror; +begin + raise exception.create(fowner.name+' wrong iificlient interface.'); + //todo: better error message +end; + +function tcustomificlientcontroller.checkcomponent( + const aintf: iifilink): pointer; +begin + if not isinterface(aintf.getifilinkkind,getifilinkkind) then begin + interfaceerror; + end; + result:= self; +end; + +{ +procedure tcustomifivaluewidgetcontroller.setcomponent(const aintf: iificlient); +var + kind1: ttypekind; + prop1: ppropinfo; + inst1: tobject; +begin + if not (ivs_linking in fstate) then begin + include(fstate,ivs_linking); + try + prop1:= nil; + kind1:= tkunknown; + if aintf <> nil then begin + inst1:= aintf.getinstance; + prop1:= getpropinfo(inst1,'value'); + if prop1 = nil then begin + raise exception.create(errorname(inst1)+' has no value property.'); + end + else begin + kind1:= prop1^.proptype^.kind; + if kind1 <> fkind then begin + raise exception.create(errorname(inst1)+' wrong value data kind.'); + end; + end; + end; + if fintf <> nil then begin + fintf.setifiserverintf(nil); + end; + setlinkedvar(aintf,iobjectlink(fintf)); + fintf:= aintf; + fvalueproperty:= prop1; + if fintf <> nil then begin + fintf.setifiserverintf(iifiserver(self)); + valuetowidget; +// if not (csloading in fowner.componentstate) then begin +// updatestate; +// end; + end; + finally + exclude(fstate,ivs_linking); + end; + end; +end; +} +procedure tcustomificlientcontroller.distribute(const sender: iificlient; + const local: boolean; const exec: boolean); +begin + if not (ivs_valuesetting in fstate) and + not(csloading in fowner.componentstate) then begin + include(fstate,ivs_valuesetting); + try + if assigned(fonchangebefore) then begin + fonchangebefore(self); + end; + if local then begin + if not (vco_novaluetoclient in foptionsvalue) then begin + if sender <> nil then begin + valuestoclient(pointer(sender)); + end + else begin + tmsecomponent1(fowner).getobjectlinker.forall( + {$ifdef FPC}@{$endif}valuestoclient,self); + end; + end; + end + else begin + clienttovalues(pointer(sender)); + if foptionsvalue*[vco_nosync,vco_datalist] = [] then begin + fchangedclient:= pointer(sender); + tmsecomponent1(fowner).getobjectlinker.forall( + {$ifdef FPC}@{$endif}valuestootherclient,self); + end; + end; + if assigned(fonchangeafter) then begin + fonchangeafter(self); + end; + if not local then begin + if exec then begin + if assigned(fonclientexecute) then begin + fonclientexecute(self,sender); + end; + end + else begin + if assigned(fonclientvaluechanged) then begin + fonclientvaluechanged(self,sender); + end; + end; + end; + finally + exclude(fstate,ivs_valuesetting); + end; + end; +end; + +procedure tcustomificlientcontroller.change(const alink: iificlient); +begin + distribute(alink,true,false); +end; +(* +procedure tcustomificlientcontroller.change(const alink: iificlient); +begin + if {(fvalueproperty <> nil) and} not (ivs_valuesetting in fstate) and + not (csloading in fowner.componentstate) then begin + include(fstate,ivs_valuesetting); + try + if assigned(fonchangebefore) then begin + fonchangebefore(self); + end; + if not (vco_novaluetoclient in foptionsvalue) then begin + if alink <> nil then begin + valuestoclient(pointer(alink)); + end + else begin + tmsecomponent1(fowner).getobjectlinker.forall( + {$ifdef FPC}@{$endif}valuestoclient,self); + end; + end; + if assigned(fonchangeafter) then begin + fonchangeafter(self); + end; + finally + exclude(fstate,ivs_valuesetting); + end; + end; +end; +*) +procedure tcustomificlientcontroller.valuechanged(const sender: iifidatalink); +begin + distribute(sender,false,false); +// dovaluechanged(sender,false); +end; + +procedure tcustomificlientcontroller.execute(const sender: iificlient); +begin + distribute(sender,false,true); +{ + if fowner.canevent(tmethod(fonclientexecute)) then begin + fonclientexecute(self,sender); + end; +} +end; + + +procedure tcustomificlientcontroller.statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); +begin + fwidgetstate:= astate; + if fowner.canevent(tmethod(fonclientstatechanged)) then begin + fonclientstatechanged(self,sender,astate, + ifiwidgetstatesty({$ifdef FPC}longword{$else}byte{$endif}(astate) xor + {$ifdef FPC}longword{$else}byte{$endif}(fwidgetstatebefore))); + fwidgetstatebefore:= astate; + end; +end; + +procedure tcustomificlientcontroller.closequery(const sender: iificlient; + var amodalresult: modalresultty); +begin + if fowner.canevent(tmethod(fonclientclosequery)) then begin + fonclientclosequery(self,sender,amodalresult); + end; +end; + + +procedure tcustomificlientcontroller.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +begin + if fowner.canevent(tmethod(fonclientmodalresult)) then begin + fonclientmodalresult(self,sender,amodalresult); + end; +end; +{ +procedure tcustomifivaluewidgetcontroller.widgettovalue; +begin + //dummy +end; +} + +procedure tcustomificlientcontroller.valuestoclient(const alink: pointer); +var + obj: tobject; +begin + if not (ivs_loadedproc in fstate) and + (fowner.componentstate * [csdesigning,csloading,csdestroying] = + [csdesigning]) then begin + obj:= iobjectlink(alink).getinstance; + if (obj is tcomponent) and (tcomponent(obj).owner <> fowner.owner) then begin + designchanged(tcomponent(obj)); + end; + end; +end; + +procedure tcustomificlientcontroller.valuestootherclient(const alink: pointer); +begin + if alink <> fchangedclient then begin + valuestoclient(alink); + end; +end; + +procedure tcustomificlientcontroller.clienttovalues(const alink: pointer); +begin + //dummy +end; + +{ +function tcustomifivaluewidgetcontroller.getclientinstance: tobject; +begin + result:= nil; + if fintf <> nil then begin + result:= fintf.getinstance; + end; +end; +} +{ +function tcustomifivaluewidgetcontroller.getwidget: twidget; +begin + result:= twidget(fcomponent); +end; + +procedure tcustomifivaluewidgetcontroller.setwidget(const avalue: twidget); +var + intf1: iifilink; +begin + intf1:= nil; + if (avalue <> nil) and + not getcorbainterface(avalue,typeinfo(iifilink),intf1) then begin + raise exception.create(avalue.name + ' is no IfI data widget.'); + end; + setcomponent(avalue,intf1); +end; +} +procedure tcustomificlientcontroller.linkset(const alink: iificlient); +begin + fwidgetstatebefore:= []; + change(alink); +end; + +procedure tcustomificlientcontroller.finalizelink(const alink: pointer); +begin + iificlient(alink).setifiserverintf(nil); +end; + +procedure tcustomificlientcontroller.finalizelinks; +begin + if tmsecomponent1(fowner).fobjectlinker <> nil then begin + tmsecomponent1(fowner).fobjectlinker.forall({$ifdef FPC}@{$endif}finalizelink,self); + end; +end; + +procedure tcustomificlientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + //dummy +end; + +procedure tcustomificlientcontroller.dataentered(const sender: iificlient; + const arow: integer); +begin + //dummy +end; + +function tcustomificlientcontroller.canconnect( + const acomponent: tcomponent): boolean; +var + po1: pointer; +begin +// result:= getcorbainterface(acomponent,typeinfo(iifilink),po1); + result:= getcorbainterface(acomponent,getifilinkkind(),po1); +end; + +function tcustomificlientcontroller.errorname(const ainstance: tobject): string; +begin + if ainstance = nil then begin + result:= 'NIL'; + end + else begin + if ainstance is tcomponent then begin + result:= tcomponent(ainstance).name; + end + else begin + result:= ainstance.classname; + end; + end; +end; + +function tcustomificlientcontroller.setmsestringval(const alink: iificlient; + const aname: string; const avalue: msestring): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = msestringtypekind); + if result then begin + setmsestringprop(inst,prop,avalue); + end; +end; + +function tcustomificlientcontroller.getmsestringval( + const alink: iificlient; const aname: string; + var avalue: msestring): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = msestringtypekind); + if result then begin + avalue:= getmsestringprop(inst,prop); + end; +end; + +function tcustomificlientcontroller.setintegerval(const alink: iificlient; + const aname: string; const avalue: integer): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkinteger); + if result then begin + setordprop(inst,prop,avalue); + end; +end; + +function tcustomificlientcontroller.getintegerval( + const alink: iificlient; const aname: string; + var avalue: integer): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkinteger); + if result then begin + avalue:= getordprop(inst,prop); + end; +end; + +function tcustomificlientcontroller.setint64val(const alink: iificlient; + const aname: string; const avalue: int64): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkint64); + if result then begin + setordprop(inst,prop,avalue); + end; +end; + +function tcustomificlientcontroller.getint64val( + const alink: iificlient; const aname: string; + var avalue: int64): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkint64); + if result then begin + avalue:= getordprop(inst,prop); + end; +end; + +function tcustomificlientcontroller.setpointerval(const alink: iifidatalink; + const aname: string; const avalue: pointer): boolean; +var + inst: tobject; + prop: ppropinfo; +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkint64); + if result then begin + setordprop(inst,prop,ptrint(avalue)); + end + else begin + alink.setifivalue(avalue); + end; +end; + +function tcustomificlientcontroller.getpointerval(const alink: iifidatalink; + const aname: string; var avalue: pointer): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and + {$ifdef mse_hastkpointer} + (prop^.proptype^.kind = tkpointer) + {$else} + (prop^.proptype^.kind = + {$ifdef cpu64}tkint64{$else}tkinteger{$endif}) + {$endif} + ; + if result then begin + avalue:= pointer(ptrint(getordprop(inst,prop))); + end + else begin + alink.getifivalue(avalue); + end; +end; + +function tcustomificlientcontroller.setbooleanval(const alink: iificlient; + const aname: string; const avalue: boolean): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind in boolprops); + if result then begin + setordprop(inst,prop,ord(avalue)); + end; +end; + +function tcustomificlientcontroller.getbooleanval( + const alink: iificlient; const aname: string; + var avalue: boolean): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind in boolprops); + if result then begin + avalue:= getordprop(inst,prop) <> 0; + end; +end; + +function tcustomificlientcontroller.setrealtyval(const alink: iificlient; + const aname: string; const avalue: realty): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkfloat); + if result then begin + setfloatprop(inst,prop,avalue); + end; +end; + +function tcustomificlientcontroller.getrealtyval( + const alink: iificlient; const aname: string; + var avalue: realty): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkfloat); + if result then begin + avalue:= getfloatprop(inst,prop); + end; +end; + +function tcustomificlientcontroller.setdatetimeval(const alink: iificlient; + const aname: string; const avalue: tdatetime): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkfloat); + if result then begin + setfloatprop(inst,prop,avalue); + end; +end; + +function tcustomificlientcontroller.getdatetimeval( + const alink: iificlient; const aname: string; + var avalue: tdatetime): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkfloat); + if result then begin + avalue:= getfloatprop(inst,prop); + end; +end; + +procedure tcustomificlientcontroller.loaded; +begin + include(fstate,ivs_loadedproc); + try + change; + finally + exclude(fstate,ivs_loadedproc); + end; +end; + +procedure tcustomificlientcontroller.dogetprop(const alink: pointer); +begin + case fapropkind of + tkinteger: begin + getintegerval(iificlient(alink),fapropname,pinteger(fapropvalue)^); + end; + tkint64: begin + getint64val(iificlient(alink),fapropname,pint64(fapropvalue)^); + end; + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + getbooleanval(iificlient(alink),fapropname,pboolean(fapropvalue)^); + end; + tkfloat: begin + getrealtyval(iificlient(alink),fapropname,prealty(fapropvalue)^); + end; + msestringtypekind: begin + getmsestringval(iificlient(alink),fapropname,pmsestring(fapropvalue)^); + end; + end; +end; + +procedure tcustomificlientcontroller.getprop(const aname: string; + const akind: ttypekind; const avaluepo: pointer); +begin + fapropname:= aname; + fapropkind:= akind; + fapropvalue:= avaluepo; + tmsecomponent1(fowner).getobjectlinker.forall({$ifdef FPC}@{$endif}dogetprop,self); +end; + +procedure tcustomificlientcontroller.dosetprop(const alink: pointer); +begin + case fapropkind of + tkinteger: begin + setintegerval(iificlient(alink),fapropname,pinteger(fapropvalue)^); + end; + tkint64: begin + setint64val(iificlient(alink),fapropname,pint64(fapropvalue)^); + end; + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + setbooleanval(iificlient(alink),fapropname,pboolean(fapropvalue)^); + end; + tkfloat: begin + setrealtyval(iificlient(alink),fapropname,prealty(fapropvalue)^); + end; + msestringtypekind: begin + setmsestringval(iificlient(alink),fapropname,pmsestring(fapropvalue)^); + end; + end; +end; + +procedure tcustomificlientcontroller.setprop(const aname: string; + const akind: ttypekind; const avaluepo: pointer); +begin + fapropname:= aname; + fapropkind:= akind; + fapropvalue:= avaluepo; + tmsecomponent1(fowner).getobjectlinker.forall({$ifdef FPC}@{$endif}dosetprop,self); +end; + +function tcustomificlientcontroller.getintegerpro(const aname: string): integer; +begin + result:= 0; + getprop(aname,tkinteger,@result); +end; + +procedure tcustomificlientcontroller.setintegerpro(const aname: string; + const avalue: integer); +begin + setprop(aname,tkinteger,@avalue); +end; + +function tcustomificlientcontroller.getmsestringpro(const aname: string): msestring; +begin + result:= ''; + getprop(aname,msestringtypekind,@result); +end; + +procedure tcustomificlientcontroller.setmsestringpro(const aname: string; + const avalue: msestring); +begin + setprop(aname,msestringtypekind,@avalue); +end; + +function tcustomificlientcontroller.getbooleanpro(const aname: string): boolean; +begin + result:= false; + getprop(aname,{$ifdef FPC}tkbool{$else}tkenumeration{$endif},@result); +end; + +procedure tcustomificlientcontroller.setbooleanpro(const aname: string; + const avalue: boolean); +begin + setprop(aname,{$ifdef FPC}tkbool{$else}tkenumeration{$endif},@avalue); +end; + +function tcustomificlientcontroller.getrealtypro(const aname: string): realty; +begin + result:= emptyreal; + getprop(aname,tkfloat,@result); +end; + +procedure tcustomificlientcontroller.setrealtypro(const aname: string; + const avalue: realty); +begin + setprop(aname,tkfloat,@avalue); +end; + +function tcustomificlientcontroller.getdatetimepro(const aname: string): tdatetime; +begin + result:= emptydatetime; + getprop(aname,tkfloat,@result); +end; + +procedure tcustomificlientcontroller.setdatetimepro(const aname: string; + const avalue: tdatetime); +begin + setprop(aname,tkfloat,@avalue); +end; + +function tcustomificlientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifilink); +end; + +procedure tcustomificlientcontroller.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tcustomificlientcontroller.dostatread(const reader: tstatreader); +begin + //dummy +end; + +procedure tcustomificlientcontroller.dostatwrite(const writer: tstatwriter); +begin + //dummy +end; + +procedure tcustomificlientcontroller.statreading; +begin + //dummy +end; + +procedure tcustomificlientcontroller.statread; +begin + //dummy +end; + +function tcustomificlientcontroller.getstatvarname: msestring; +begin + if fstatvarname = '' then begin + result:= msestring(ownernamepath(fowner)); + if result = '' then begin + result:= '.'; //dummy, statfiler can not get componentname because + //self is no tcomponent + end; + end + else begin + result:= fstatvarname; + end; +end; + +procedure tcustomificlientcontroller.updateoptionsedit(var avalue: optionseditty); +begin + //dummy +end; + +function tcustomificlientcontroller.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tifilinkcomp } + +constructor tifilinkcomp.create(aowner: tcomponent); +begin + fcontroller:= getcontrollerclass.create(self); + inherited; +end; + +destructor tifilinkcomp.destroy; +begin + fcontroller.finalizelinks; + inherited; + fcontroller.free; +end; + +procedure tifilinkcomp.setcontroller(const avalue: tcustomificlientcontroller); +begin + fcontroller.assign(avalue); +end; + +function tifilinkcomp.getcontrollerclass: customificlientcontrollerclassty; +begin + result:= tificlientcontroller; +end; + +procedure tifilinkcomp.loaded; +begin + inherited; + fcontroller.loaded; +end; + +{ tvalueclientcontroller } + +destructor tvalueclientcontroller.destroy; +begin + freeandnil(fdatalist); + inherited; +end; + +function tvalueclientcontroller.canconnect(const acomponent: tcomponent): boolean; +var + prop1: ppropinfo; +begin + result:= inherited canconnect(acomponent); + if result then begin + prop1:= getpropinfo(acomponent,'value'); + result:= (prop1 <> nil) and (prop1^.proptype^.kind = fkind); + end; +end; + +function tvalueclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; +{ +procedure tvalueclientcontroller.getdatalist1(const alink: pointer; + var handled: boolean); +var + datalist1: tdatalist; +begin + datalist1:= iifidatalink(alink).ifigriddata; + if datalist1 <> nil then begin + pdatalist(fitempo)^:= datalist1; + handled:= true; + end; +end; + +function tvalueclientcontroller.getfirstdatalist1: tdatalist; +begin + result:= fdatalist; + if result = nil then begin + fitempo:= @result; + tmsecomponent1(fowner).getobjectlinker.forfirst(@getdatalist1, + self); + if result = nil then begin + raise exception.create('No datalist.'); + end; + end; +end; + +function tvalueclientcontroller.getfirstdatalist: tdatalist; +begin + result:= getfirstdatalist1; + if result = nil then begin + raise exception.create('No datalist.'); + end; +end; +} +{ +procedure tvalueclientcontroller.setmsestringvalar(const alink: pointer; + var handled: boolean); +//var +// datalist: tdatalist; +begin +// datalist:= iifidatalink(alink).ifigriddata; + if datalist is tmsestringdatalist then begin + tmsestringdatalist(datalist).asarray:= pmsestringarty(fvalarpo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getmsestringvalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tmsestringdatalist then begin + pmsestringarty(fvalarpo)^:= tmsestringdatalist(datalist).asarray; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setintegervalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + tintegerdatalist(datalist).asarray:= pintegerarty(fvalarpo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getintegervalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + pintegerarty(fvalarpo)^:= tintegerdatalist(datalist).asarray; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setrealtyvalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + trealdatalist(datalist).asarray:= prealarty(fvalarpo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getrealtyvalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + prealarty(fvalarpo)^:= trealdatalist(datalist).asarray; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setdatetimevalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + trealdatalist(datalist).asarray:= pdatetimearty(fvalarpo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getdatetimevalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + prealarty(fvalarpo)^:= trealdatalist(datalist).asarray; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setbooleanvalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + tintegerdatalist(datalist).asarray:= pintegerarty(fvalarpo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getbooleanvalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + pintegerarty(fvalarpo)^:= tintegerdatalist(datalist).asarray; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getvalar(const agetter: valargetterty; + var avalue); +begin + fvalarpo:= @avalue; + tmsecomponent1(fowner).getobjectlinker.forfirst(agetter,self); +end; + +procedure tvalueclientcontroller.setvalar(const asetter: valarsetterty; + const avalue); +begin + fvalarpo:= @avalue; + tmsecomponent1(fowner).getobjectlinker.forfirst(asetter,self); +end; + +procedure tvalueclientcontroller.setmsestringitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; + int1: integer; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tmsestringdatalist then begin + int1:= fitemindex; + if int1 = maxint then begin + int1:= datalist.count - 1; + end; + tmsestringdatalist(datalist)[int1]:= pmsestring(fitempo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getmsestringitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tmsestringdatalist then begin + pmsestring(fitempo)^:= tmsestringdatalist(datalist)[fitemindex]; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setintegeritem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; + int1: integer; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + int1:= fitemindex; + if int1 = maxint then begin + int1:= datalist.count - 1; + end; + tintegerdatalist(datalist)[int1]:= pinteger(fitempo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getintegeritem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + pinteger(fitempo)^:= tintegerdatalist(datalist)[fitemindex]; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setrealtyitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; + int1: integer; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + int1:= fitemindex; + if int1 = maxint then begin + int1:= datalist.count - 1; + end; + trealdatalist(datalist)[int1]:= prealty(fitempo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getrealtyitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + prealty(fitempo)^:= trealdatalist(datalist)[fitemindex]; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setdatetimeitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; + int1: integer; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + int1:= fitemindex; + if int1 = maxint then begin + int1:= datalist.count - 1; + end; + trealdatalist(datalist)[int1]:= pdatetime(fitempo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getdatetimeitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + pdatetime(fitempo)^:= trealdatalist(datalist)[fitemindex]; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setbooleanitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; + int1: integer; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + int1:= fitemindex; + if int1 = maxint then begin + int1:= datalist.count - 1; + end; + if pinteger(fitempo)^ = 0 then begin + tintegerdatalist(datalist)[int1]:= longint(longbool(false)); + end + else begin + tintegerdatalist(datalist)[int1]:= longint(longbool(true)); + end; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getbooleanitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + pintegerarty(fitempo)^:= tintegerdatalist(datalist).asarray; + handled:= true + end; +end; + +procedure tvalueclientcontroller.getitem(const index: integer; + const agetter: itemgetterty; var avalue); +begin + fitempo:= @avalue; + fitemindex:= index; + tmsecomponent1(fowner).getobjectlinker.forfirst(agetter,self); +end; + +procedure tvalueclientcontroller.setitem(const index: integer; + const asetter: itemsetterty; const avalue); +begin + fitempo:= @avalue; + fitemindex:= index; + tmsecomponent1(fowner).getobjectlinker.forfirst(asetter,self); +end; +} +procedure tvalueclientcontroller.statreadlist(const alink: pointer); +//var +// datalist: tdatalist; +begin +// datalist:= iifidatalink(alink).ifigriddata; + if datalist <> nil then begin + tstatreader(fitempo).readdatalist(getstatvarname,datalist); + end; +end; + +procedure tvalueclientcontroller.statwritelist(const alink: pointer; + var handled: boolean); +//var +// datalist: tdatalist; +begin +// datalist:= iifidatalink(alink).ifigriddata; + if datalist <> nil then begin + tstatwriter(fitempo).writedatalist(getstatvarname,datalist); + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); +begin + inherited; +// if accept and fowner.canevent(tmethod(fonclientdataentered)) then begin +// fonclientdataentered(fowner,arow); +// end; +end; + +procedure tvalueclientcontroller.dataentered(const sender: iificlient; + const arow: integer); +begin + inherited; + if fowner.canevent(tmethod(fonclientdataentered)) then begin + fonclientdataentered(self,sender,arow); + end; +end; + +procedure tvalueclientcontroller.setoptionsvalue( + const avalue: valueclientoptionsty); +begin + if foptionsvalue <> avalue then begin + foptionsvalue:= avalue; + optionsvaluechanged; + end; +end; + +procedure tvalueclientcontroller.linkdatalist1(const alink: pointer); +begin + iifidatalink(alink).updateifigriddata(fowner,fdatalist); +end; + +procedure tvalueclientcontroller.linkdatalist; +begin + with tmsecomponent1(fowner) do begin + if fobjectlinker <> nil then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}self.linkdatalist1,self); + end; + end; +end; + +procedure tvalueclientcontroller.updatereadonlystate1(const alink: pointer); +begin + iifidatalink(alink).updatereadonlystate; +end; + +procedure tvalueclientcontroller.updatereadonlystate; +begin + with tmsecomponent1(fowner) do begin + if fobjectlinker <> nil then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}self.updatereadonlystate1,self); + end; + end; +end; + +procedure tvalueclientcontroller.optionsvaluechanged; +begin + if (vco_datalist in foptionsvalue) xor (fdatalist <> nil) then begin + if vco_datalist in foptionsvalue then begin + fdatalist:= createdatalist; + if fdatalist <> nil then begin + include(tdatalist1(fdatalist).fstate,dls_remote); + if not (csloading in fowner.componentstate) then begin + linkdatalist; + end; + end; + end + else begin + freeandnil(fdatalist); + end; + end; + if not (csloading in fowner.componentstate) then begin + updatereadonlystate; + end; +end; + +procedure tvalueclientcontroller.loaded; +begin + if fdatalist <> nil then begin + linkdatalist; + end; + updatereadonlystate; + inherited; +end; + +procedure tvalueclientcontroller.setdatasource(const avalue: tifidatasource); +begin + if avalue <> fdatasource then begin + setifidatasource(iifidatasourceclient(self),avalue,fdatasource); + end; +end; + +procedure tvalueclientcontroller.setfieldname(const avalue: ififieldnamety); +begin + if avalue <> ffieldname then begin + ffieldname:= avalue; + bindingchanged; + end; +end; + +procedure tvalueclientcontroller.bindingchanged; +begin +end; + +function tvalueclientcontroller.ifigriddata: tdatalist; +begin + result:= fdatalist; + if result = nil then begin + componentexception(fowner,'No datalist, activate optionsvalue vco_datalist.'); + end; +end; + +function tvalueclientcontroller.ififieldname: string; +begin + result:= ffieldname; +end; + +procedure tvalueclientcontroller.getfieldinfo(const apropname: ififieldnamety; + var adatasource: tifidatasource; var atypes: listdatatypesty); +begin + adatasource:= fdatasource; + atypes:= getlistdatatypes; +end; + +procedure tvalueclientcontroller.dostatread(const reader: tstatreader); +begin + inherited; + if reader.candata then begin + if fdatalist = nil then begin + statreadvalue(reader); + end + else begin + reader.readdatalist(listvarname,fdatalist); + end; + end; +end; + +procedure tvalueclientcontroller.dostatwrite(const writer: tstatwriter); +begin + inherited; + if writer.candata then begin + if fdatalist = nil then begin + statwritevalue(writer); + end + else begin + writer.writedatalist(listvarname,fdatalist); + end; + end; +end; + +procedure tvalueclientcontroller.statreadvalue(const reader: tstatreader); +begin + //dummy +end; + +procedure tvalueclientcontroller.statwritevalue(const reader: tstatwriter); +begin + //dummy +end; + +procedure tvalueclientcontroller.updateoptionsedit(var avalue: optionseditty); +begin + if not (csdesigning in fowner.componentstate) then begin + if vco_readonly in foptionsvalue then begin + include(avalue,oe_readonly); + end; + if vco_notnull in foptionsvalue then begin + include(avalue,oe_notnull); + end; + end; +end; + +procedure tvalueclientcontroller.linkset(const alink: iificlient); +begin + if not (vco_nosync in foptionsvalue) then begin + inherited; + end; +end; + +{ tstringclientcontroller } + +constructor tstringclientcontroller.create(const aowner: tmsecomponent); +begin + inherited create(aowner,msestringtypekind); +end; + +procedure tstringclientcontroller.setvalue1(const avalue: msestring); +begin + fvalue:= avalue; + change; +end; + +procedure tstringclientcontroller.valuestoclient(const alink: pointer); +begin + setmsestringval(iificlient(alink),'value',fvalue); + inherited; +end; + +procedure tstringclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getmsestringval(iificlient(alink),'value',fvalue); +end; + +{ +procedure tstringwidgetcontroller.widgettovalue; +begin + value:= getmsestringprop(clientinstance,fvalueproperty); +end; +} +procedure tstringclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,msestring(avalue),accept,arow); + end; + inherited; +end; +{ +function tstringclientcontroller.getgridvalues: msestringarty; +begin + result:= nil; + getvalar(@getmsestringvalar,result); +end; + +procedure tstringclientcontroller.setgridvalues(const avalue: msestringarty); +begin + setvalar(@setmsestringvalar,avalue); +end; + +function tstringclientcontroller.getgridvalue(const index: integer): msestring; +begin + result:= ''; + getitem(index,@getmsestringitem,result); +end; + +procedure tstringclientcontroller.setgridvalue(const index: integer; + const avalue: msestring); +begin + setitem(index,@setmsestringitem,avalue); +end; +} +function tstringclientcontroller.getgriddata: tifimsestringdatalist; +begin + result:= tifimsestringdatalist(ifigriddata); +end; + +function tstringclientcontroller.getonclientvaluechanged: + ifistringclienteventty; +begin + result:= ifistringclienteventty(fonclientvaluechanged); +end; + +procedure tstringclientcontroller.setonclientvaluechanged( + const avalue: ifistringclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tstringclientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readmsestring(valuevarname,value); +end; + +procedure tstringclientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writemsestring(valuevarname,value); +end; + +function tstringclientcontroller.createdatalist: tdatalist; +begin + result:= tifimsestringdatalist.create(self); +end; + +function tstringclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_msestring]; +end; + +{ tintegerclientcontroller } + +constructor tintegerclientcontroller.create(const aowner: tmsecomponent); +begin + fvaluemax:= maxint; + inherited create(aowner,tkinteger); +end; + +procedure tintegerclientcontroller.setvalue1(const avalue: integer); +begin + fvalue:= avalue; + change; +end; + +procedure tintegerclientcontroller.valuestoclient(const alink: pointer); +begin + setintegerval(iificlient(alink),'value',fvalue); + setintegerval(iificlient(alink),'valuemin',fvaluemin); + setintegerval(iificlient(alink),'valuemax',fvaluemax); + inherited; +end; + +procedure tintegerclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getintegerval(iificlient(alink),'value',fvalue); +end; + +procedure tintegerclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(fowner,sender,integer(avalue),accept,arow); + end; + inherited; +end; + +procedure tintegerclientcontroller.setvaluemin(const avalue: integer); +begin + fvaluemin:= avalue; + change; +end; + +procedure tintegerclientcontroller.setvaluemax(const avalue: integer); +begin + fvaluemax:= avalue; + change; +end; +{ +function tintegerclientcontroller.getgridvalues: integerarty; +begin + result:= nil; + getvalar(@getintegervalar,result); +end; + +procedure tintegerclientcontroller.setgridvalues(const avalue: integerarty); +begin + setvalar(@setintegervalar,avalue); +end; + +function tintegerclientcontroller.getgridvalue(const index: integer): integer; +begin + result:= 0; + getitem(index,@getintegeritem,result); +end; + +procedure tintegerclientcontroller.setgridvalue(const index: integer; + const avalue: integer); +begin + setitem(index,@setintegeritem,avalue); +end; +} +function tintegerclientcontroller.getgriddata: tifiintegerdatalist; +begin + result:= tifiintegerdatalist(ifigriddata); +end; + +procedure tintegerclientcontroller.readmin(reader: treader); +begin + valuemin:= reader.readinteger; +end; + +procedure tintegerclientcontroller.readmax(reader: treader); +begin + valuemax:= reader.readinteger; +end; + +function tintegerclientcontroller.getonclientvaluechanged: ifiintegerclienteventty; +begin + result:= ifiintegerclienteventty(fonclientvaluechanged); +end; + +procedure tintegerclientcontroller.setonclientvaluechanged( + const avalue: ifiintegerclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tintegerclientcontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +procedure tintegerclientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readinteger(valuevarname,value,valuemin,valuemax); +end; + +procedure tintegerclientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writeinteger(valuevarname,value); +end; + +function tintegerclientcontroller.createdatalist: tdatalist; +begin + result:= tifiintegerdatalist.create(self); +end; + +function tintegerclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_integer]; +end; + +{ tint64clientcontroller } + +constructor tint64clientcontroller.create(const aowner: tmsecomponent); +begin + fvaluemax:= maxint; + inherited create(aowner,tkint64); +end; + +procedure tint64clientcontroller.setvalue1(const avalue: int64); +begin + fvalue:= avalue; + change; +end; + +procedure tint64clientcontroller.valuestoclient(const alink: pointer); +begin + setint64val(iificlient(alink),'value',fvalue); + setint64val(iificlient(alink),'valuemin',fvaluemin); + setint64val(iificlient(alink),'valuemax',fvaluemax); + inherited; +end; + +procedure tint64clientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getint64val(iificlient(alink),'value',fvalue); +end; + +procedure tint64clientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,int64(avalue),accept,arow); + end; + inherited; +end; + +procedure tint64clientcontroller.setvaluemin(const avalue: int64); +begin + fvaluemin:= avalue; + change; +end; + +procedure tint64clientcontroller.setvaluemax(const avalue: int64); +begin + fvaluemax:= avalue; + change; +end; +{ +function tint64clientcontroller.getgridvalues: int64arty; +begin + result:= nil; + getvalar(@getint64valar,result); +end; + +procedure tint64clientcontroller.setgridvalues(const avalue: int64arty); +begin + setvalar(@setint64valar,avalue); +end; + +function tint64clientcontroller.getgridvalue(const index: int64): int64; +begin + result:= 0; + getitem(index,@getint64item,result); +end; + +procedure tint64clientcontroller.setgridvalue(const index: int64; + const avalue: int64); +begin + setitem(index,@setint64item,avalue); +end; +} +function tint64clientcontroller.getgriddata: tifiint64datalist; +begin + result:= tifiint64datalist(ifigriddata); +end; + +procedure tint64clientcontroller.readmin(reader: treader); +begin + valuemin:= reader.readint64(); +end; + +procedure tint64clientcontroller.readmax(reader: treader); +begin + valuemax:= reader.readint64() +end; + +function tint64clientcontroller.getonclientvaluechanged: ifiint64clienteventty; +begin + result:= ifiint64clienteventty(fonclientvaluechanged); +end; + +procedure tint64clientcontroller.setonclientvaluechanged( + const avalue: ifiint64clienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tint64clientcontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +procedure tint64clientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readint64(valuevarname,value,valuemin,valuemax); +end; + +procedure tint64clientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writeint64(valuevarname,value); +end; + +function tint64clientcontroller.createdatalist: tdatalist; +begin + result:= tifiint64datalist.create(self); +end; + +function tint64clientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_int64]; +end; + +{ tpointerclientcontroller } + + +constructor tpointerclientcontroller.create(const aowner: tmsecomponent); +begin +{$ifdef mse_hastkpointer} + inherited create(aowner,tkpointer); +{$else} + inherited create(aowner,{$ifdef cpu64}tkint64{$else}tkinteger{$endif}); +{$endif} +end; + +procedure tpointerclientcontroller.setvalue1(const avalue: pointer); +begin + fvalue:= avalue; + change; +end; + +function tpointerclientcontroller.getgriddata: tifipointerdatalist; +begin + result:= tifipointerdatalist(ifigriddata); +end; + +function tpointerclientcontroller.getonclientvaluechanged(): + ifipointerclienteventty; +begin + result:= ifipointerclienteventty(fonclientvaluechanged); +end; + +procedure tpointerclientcontroller.setonclientvaluechanged( + const avalue: ifipointerclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tpointerclientcontroller.valuestoclient(const alink: pointer); +begin + setpointerval(iifidatalink(alink),'value',fvalue); + inherited; +end; + +procedure tpointerclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getpointerval(iifidatalink(alink),'value',fvalue); +end; + +procedure tpointerclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,pointer(avalue),accept,arow); + end; + inherited; +end; + +function tpointerclientcontroller.createdatalist: tdatalist; +begin + result:= tifipointerdatalist.create(self); +end; + +function tpointerclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_pointer]; +end; + +{ tbooleanclientcontroller } + +constructor tbooleanclientcontroller.create(const aowner: tmsecomponent); +begin + inherited create(aowner,{$ifdef FPC}tkbool{$else}tkenumeration{$endif}); +end; + +procedure tbooleanclientcontroller.setvalue1(const avalue: boolean); +begin + fvalue:= avalue; + change; +end; + +procedure tbooleanclientcontroller.valuestoclient(const alink: pointer); +begin + setbooleanval(iificlient(alink),'value',fvalue); + inherited; +end; + +procedure tbooleanclientcontroller.clienttovalues(const alink: pointer); +var + bo1: boolean; +begin + inherited; + bo1:= fvalue; + getbooleanval(iificlient(alink),'value',bo1); + fvalue:= bo1; +end; + +procedure tbooleanclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,boolean(avalue),accept,arow); + end; + inherited; +end; + +function tbooleanclientcontroller.createdatalist: tdatalist; +begin + result:= tifibooleandatalist.create(self); +end; + +{ +function tbooleanclientcontroller.getgridvalues: longboolarty; +begin + result:= nil; + getvalar(@getbooleanvalar,result); +end; + +procedure tbooleanclientcontroller.setgridvalues(const avalue: longboolarty); +begin + setvalar(@setbooleanvalar,avalue); +end; + +function tbooleanclientcontroller.getgridvalue(const index: integer): boolean; +begin + result:= false; + getitem(index,@getbooleanitem,result); +end; + +procedure tbooleanclientcontroller.setgridvalue(const index: integer; + const avalue: boolean); +begin + setitem(index,@setbooleanitem,avalue); +end; +} +function tbooleanclientcontroller.getgriddata: tifibooleandatalist; +begin + result:= tifibooleandatalist(ifigriddata); +end; + +function tbooleanclientcontroller.getonclientvaluechanged: + ifibooleanclienteventty; +begin + result:= ifibooleanclienteventty(fonclientvaluechanged); +end; + +procedure tbooleanclientcontroller.setonclientvaluechanged( + const avalue: ifibooleanclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tbooleanclientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readboolean(valuevarname,value); +end; + +procedure tbooleanclientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writeboolean(valuevarname,value); +end; + +function tbooleanclientcontroller.getvalue: boolean; +begin + result:= fvalue; +end; + +function tbooleanclientcontroller.getvaluedefault: boolean; +begin + result:= fvaluedefault; +end; + +procedure tbooleanclientcontroller.setvaluedefault(const avalue: boolean); +begin + fvaluedefault:= avalue; +end; + +function tbooleanclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_integer]; +end; + +{ trealclientcontroller } + +constructor trealclientcontroller.create(const aowner: tmsecomponent); +begin + fvalue:= emptyreal; + fvaluedefault:= emptyreal; + fvaluemin:= emptyreal; + fvaluemax:= bigreal; + inherited create(aowner,tkfloat); +end; + +procedure trealclientcontroller.setvalue1(const avalue: realty); +begin + fvalue:= avalue; + change; +end; + +procedure trealclientcontroller.valuestoclient(const alink: pointer); +begin + setrealtyval(iificlient(alink),'value',fvalue); + setrealtyval(iificlient(alink),'valuemin',fvaluemin); + setrealtyval(iificlient(alink),'valuemax',fvaluemax); + inherited; +end; + +procedure trealclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getrealtyval(iificlient(alink),'value',fvalue); +end; + +procedure trealclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,realty(avalue),accept,arow); + end; + inherited; +end; + +function trealclientcontroller.createdatalist: tdatalist; +begin + result:= tifirealdatalist.create(self); +end; + +procedure trealclientcontroller.setvaluemin(const avalue: realty); +begin + fvaluemin:= avalue; + change; +end; + +procedure trealclientcontroller.setvaluemax(const avalue: realty); +begin + fvaluemax:= avalue; + change; +end; + +procedure trealclientcontroller.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; + +procedure trealclientcontroller.readmin1(reader: treader); +begin + fvaluemin:= readrealty(reader); +end; + +procedure trealclientcontroller.readmax1(reader: treader); +begin + fvaluemax:= readrealty(reader); +end; + +procedure trealclientcontroller.readvaluedefault(reader: treader); +begin + valuedefault:= readrealty(reader); +end; + +procedure trealclientcontroller.readmin(reader: treader); +begin + valuemin:= reader.readfloat; +end; + +procedure trealclientcontroller.readmax(reader: treader); +begin + valuemax:= reader.readfloat; +end; + +function trealclientcontroller.getonclientvaluechanged: ifirealclienteventty; +begin + result:= ifirealclienteventty(fonclientvaluechanged); +end; + +procedure trealclientcontroller.setonclientvaluechanged( + const avalue: ifirealclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure trealclientcontroller.defineproperties(filer: tfiler); +begin + inherited; + + filer.DefineProperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); + filer.DefineProperty('mi',{$ifdef FPC}@{$endif}readmin1,nil,false); + filer.DefineProperty('ma',{$ifdef FPC}@{$endif}readmax1,nil,false); + filer.DefineProperty('def',{$ifdef FPC}@{$endif}readvaluedefault,nil,false); + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +function trealclientcontroller.getgriddata: tifirealdatalist; +begin + result:= tifirealdatalist(ifigriddata); +end; + +procedure trealclientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readreal(valuevarname,value,valuemin,valuemax); +end; + +procedure trealclientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writereal(valuevarname,value); +end; + +function trealclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_real]; +end; + +{ tdatetimeclientcontroller } + +constructor tdatetimeclientcontroller.create(const aowner: tmsecomponent); +begin + fvalue:= emptydatetime; + fvaluedefault:= emptydatetime; + fvaluemin:= emptydatetime; + fvaluemax:= bigdatetime; + inherited create(aowner,tkfloat); +end; + +procedure tdatetimeclientcontroller.setvalue1(const avalue: tdatetime); +begin + fvalue:= avalue; + change; +end; + +procedure tdatetimeclientcontroller.valuestoclient(const alink: pointer); +begin + setdatetimeval(iificlient(alink),'value',fvalue); + setdatetimeval(iificlient(alink),'valuemin',fvaluemin); + setdatetimeval(iificlient(alink),'valuemax',fvaluemax); + inherited; +end; + +procedure tdatetimeclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getdatetimeval(iificlient(alink),'value',fvalue); +end; + +procedure tdatetimeclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,tdatetime(avalue),accept,arow); + end; + inherited; +end; + +function tdatetimeclientcontroller.createdatalist: tdatalist; +begin + result:= tifidatetimedatalist.create(self); +end; + +procedure tdatetimeclientcontroller.setvaluemin(const avalue: tdatetime); +begin + fvaluemin:= avalue; + change; +end; + +procedure tdatetimeclientcontroller.setvaluemax(const avalue: tdatetime); +begin + fvaluemax:= avalue; + change; +end; + +procedure tdatetimeclientcontroller.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; +{ +procedure tdatetimeclientcontroller.writevalue(writer: twriter); +begin + writerealty(writer,fvalue); +end; +} +procedure tdatetimeclientcontroller.readmin1(reader: treader); +begin + fvaluemin:= readrealty(reader); +end; +{ +procedure tdatetimeclientcontroller.writemin(writer: twriter); +begin + writerealty(writer,fmin); +end; +} +procedure tdatetimeclientcontroller.readmax1(reader: treader); +begin + fvaluemax:= readrealty(reader); +end; +{ +procedure tdatetimeclientcontroller.writemax(writer: twriter); +begin + writerealty(writer,fmax); +end; +} +procedure tdatetimeclientcontroller.readvaluedefault(reader: treader); +begin + valuedefault:= readrealty(reader); +end; +{ +procedure tdatetimeclientcontroller.writevaluedefault(writer: twriter); +begin + writerealty(writer,fvaluedefault); +end; +} +procedure tdatetimeclientcontroller.readmin(reader: treader); +begin + valuemin:= reader.readfloat(); +end; + +procedure tdatetimeclientcontroller.readmax(reader: treader); +begin + valuemax:= reader.readfloat(); +end; + +function tdatetimeclientcontroller.getonclientvaluechanged: + ifidatetimeclienteventty; +begin + result:= ifidatetimeclienteventty(fonclientvaluechanged); +end; + +procedure tdatetimeclientcontroller.setonclientvaluechanged( + const avalue: ifidatetimeclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tdatetimeclientcontroller.defineproperties(filer: tfiler); +begin + inherited; + + filer.DefineProperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); + filer.DefineProperty('mi',{$ifdef FPC}@{$endif}readmin1,nil,false); + filer.DefineProperty('ma',{$ifdef FPC}@{$endif}readmax1,nil,false); + filer.DefineProperty('def',{$ifdef FPC}@{$endif}readvaluedefault,nil,false); + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; +{ +function tdatetimeclientcontroller.getgridvalues: datetimearty; +begin + result:= nil; + getvalar(@getdatetimevalar,result); +end; + +procedure tdatetimeclientcontroller.setgridvalues(const avalue: datetimearty); +begin + setvalar(@setdatetimevalar,avalue); +end; + +function tdatetimeclientcontroller.getgridvalue(const index: integer): tdatetime; +begin + result:= emptydatetime; + getitem(index,@getdatetimeitem,result); +end; + +procedure tdatetimeclientcontroller.setgridvalue(const index: integer; + const avalue: tdatetime); +begin + setitem(index,@setdatetimeitem,avalue); +end; +} +function tdatetimeclientcontroller.getgriddata: tifidatetimedatalist; +begin + result:= tifidatetimedatalist(ifigriddata); +end; + +procedure tdatetimeclientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readreal(valuevarname,value,valuemin,valuemax); +end; + +procedure tdatetimeclientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writereal(valuevarname,value); +end; + +function tdatetimeclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_real]; +end; + +{ tifistringlinkcomp } + +function tifistringlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tstringclientcontroller; +end; + +function tifistringlinkcomp.getcontroller: tstringclientcontroller; +begin + result:= tstringclientcontroller(inherited controller); +end; + +procedure tifistringlinkcomp.setcontroller(const avalue: tstringclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifidropdownlistlinkcomp } + +function tifidropdownlistlinkcomp.getcontroller: tdropdownlistclientcontroller; +begin + result:= tdropdownlistclientcontroller(inherited controller); +end; + +procedure tifidropdownlistlinkcomp.setcontroller( + const avalue: tdropdownlistclientcontroller); +begin + inherited setcontroller(avalue); +end; + +function tifidropdownlistlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tdropdownlistclientcontroller; +end; + +{ tifiintegerlinkcomp } + +function tifiintegerlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tintegerclientcontroller; +end; + +function tifiintegerlinkcomp.getcontroller: tintegerclientcontroller; +begin + result:= tintegerclientcontroller(inherited controller); +end; + +procedure tifiintegerlinkcomp.setcontroller(const avalue: tintegerclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifiint64linkcomp } + +function tifiint64linkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tint64clientcontroller; +end; + +function tifiint64linkcomp.getcontroller: tint64clientcontroller; +begin + result:= tint64clientcontroller(inherited controller); +end; + +procedure tifiint64linkcomp.setcontroller(const avalue: tint64clientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifipointerlinkcomp } + +function tifipointerlinkcomp.getcontroller: tpointerclientcontroller; +begin + result:= tpointerclientcontroller(inherited controller); +end; + +procedure tifipointerlinkcomp.setcontroller( + const avalue: tpointerclientcontroller); +begin + inherited setcontroller(avalue); +end; + +function tifipointerlinkcomp.getcontrollerclass: customificlientcontrollerclassty; +begin + result:= tpointerclientcontroller; +end; + +{ tifibooleanlinkcomp } + +function tifibooleanlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tbooleanclientcontroller; +end; + +function tifibooleanlinkcomp.getcontroller: tbooleanclientcontroller; +begin + result:= tbooleanclientcontroller(inherited controller); +end; + +procedure tifibooleanlinkcomp.setcontroller(const avalue: tbooleanclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifireallinkcomp } + +function tifireallinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= trealclientcontroller; +end; + +function tifireallinkcomp.getcontroller: trealclientcontroller; +begin + result:= trealclientcontroller(inherited controller); +end; + +procedure tifireallinkcomp.setcontroller(const avalue: trealclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifidatetimelinkcomp } + +function tifidatetimelinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tdatetimeclientcontroller; +end; + +function tifidatetimelinkcomp.getcontroller: tdatetimeclientcontroller; +begin + result:= tdatetimeclientcontroller(inherited controller); +end; + +procedure tifidatetimelinkcomp.setcontroller(const avalue: tdatetimeclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tificlientcontroller } + +{ tifiactionlinkcomp } + +function tifiactionlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= texecclientcontroller; +end; + +function tifiactionlinkcomp.getcontroller: texecclientcontroller; +begin + result:= texecclientcontroller(inherited controller); +end; + +procedure tifiactionlinkcomp.setcontroller(const avalue: texecclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tififormlinkcomp } + +function tififormlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tformclientcontroller; +end; + +function tififormlinkcomp.getcontroller: tformclientcontroller; +begin + result:= tformclientcontroller(inherited controller); +end; + +procedure tififormlinkcomp.setcontroller(const avalue: tformclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ texecclientcontroller } + +constructor texecclientcontroller.create(const aowner: tmsecomponent); +begin + fenabled:= true; + inherited; +end; + +procedure texecclientcontroller.setclientenabled(const alink: pointer); +begin + iifiexeclink(alink).ifisetenabled(fenabled); +end; + +procedure texecclientcontroller.setenabled(const avalue: boolean); +begin + if fenabled <> avalue then begin + fenabled:= avalue; + if not (csloading in fowner.componentstate) then begin + tmsecomponent1(fowner).getobjectlinker.forall(@setclientenabled,self); + end; + end; +end; + +function texecclientcontroller.canconnect(const acomponent: tcomponent): boolean; +var + po1: pointer; +// prop1: ppropinfo; +begin +// result:= inherited canconnect(acomponent); + result:= getcorbainterface(acomponent,typeinfo(iifiexeclink),po1); + { + if result then begin + prop1:= getpropinfo(acomponent,'onexecute'); + result:= (prop1 <> nil) and (prop1^.proptype^.kind = tkmethod); + end; + } +end; + +procedure texecclientcontroller.valuestoclient(const alink: pointer); +begin + if not (ivs_loadedproc in fstate) then begin + iifiexeclink(alink).execute; + end; +end; + +procedure texecclientcontroller.execute(const sender: iificlient); +begin + if fenabled then begin + inherited; + end; +end; + +{ +procedure texecclientcontroller.execute(const sender: iificlient); +begin + dovaluechanged(sender,true); //distribute event + inherited; +end; +} +procedure texecclientcontroller.execute; +begin + if enabled then begin + distribute(nil,true,true); + end; +// dovaluechanged(nil,true); //distribute event +end; + +procedure texecclientcontroller.linkset(const alink: iificlient); +begin + //do nothing +end; + +procedure texecclientcontroller.dostatread(const reader: tstatreader); +begin + inherited; + if reader.canstate then begin + enabled:= reader.readboolean('_enabled',fenabled); + end; +end; + +procedure texecclientcontroller.dostatwrite(const writer: tstatwriter); +begin + inherited; + if writer.canstate then begin + writer.writeboolean('_enabled',fenabled); + end; +end; + +function texecclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifiexeclink); +end; + +{ tifigridlinkcomp } + +function tifigridlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tgridclientcontroller; +end; + +function tifigridlinkcomp.getcontroller: tgridclientcontroller; +begin + result:= tgridclientcontroller(inherited controller); +end; + +procedure tifigridlinkcomp.setcontroller(const avalue: tgridclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifilinkcomparrayprop } + +constructor tifilinkcomparrayprop.create; +begin + inherited create(tificolitem); +end; + +class function tifilinkcomparrayprop.getitemclasstype: persistentclassty; +begin + result:= tificolitem; +end; + +function tifilinkcomparrayprop.getitems(const index: integer): tificolitem; +begin + result:= tificolitem(inherited getitems(index)); +end; + +{ tifivaluelinkcomp } + +function tifivaluelinkcomp.getcontroller: tvalueclientcontroller; +begin + result:= tvalueclientcontroller(fcontroller); +end; + +{ tificolitem } + +function tificolitem.getlink: tifivaluelinkcomp; +begin + result:= tifivaluelinkcomp(item); +end; + +procedure tificolitem.setlink(const avalue: tifivaluelinkcomp); +begin + item:= avalue; +end; + +{ tifidropdowncols } + +constructor tifidropdowncols.create(const aowner: tifidropdownlistcontroller); +begin + inherited create(aowner,nil); +end; + +class function tifidropdowncols.getitemclasstype: persistentclassty; +begin + result:= tifidropdowncol; +end; + +procedure tifidropdowncols.createitem(const index: integer; + var item: tpersistent); +begin + item:= tifidropdowncol.create; + tifidropdowncol(item).onchange:= {$ifdef FPC}@{$endif}colchanged; +end; + +function tifidropdowncols.getitems(const index: integer): tifidropdowncol; +begin + result:= tifidropdowncol(inherited getitems(index)); +end; + +procedure tifidropdowncols.colchanged(const sender: tobject); +begin + change(-1); +end; + +procedure tifidropdowncols.dochange(const index: integer); +begin + tifidropdownlistcontroller(fowner).fowner.change(nil); +end; + +{ tifidropdownlistcontroller } + +constructor tifidropdownlistcontroller.create( + const aowner: tvalueclientcontroller); +begin + fowner:= aowner; + fcols:= tifidropdowncols.create(self); + inherited create; +end; + +destructor tifidropdownlistcontroller.destroy; +begin + inherited; + fcols.free; +end; + +procedure tifidropdownlistcontroller.setcols(const avalue: tifidropdowncols); +begin + fcols.assign(avalue); +end; + +procedure tifidropdownlistcontroller.valuestoclient(const alink: pointer); +begin + iifidropdownlistdatalink(alink).ifidropdownlistchanged(fcols); +end; + +{ tdropdownlistclientcontroller } + +constructor tdropdownlistclientcontroller.create(const aowner: tmsecomponent); +begin + fdropdown:= tifidropdownlistcontroller.create(self); + inherited; +end; + +destructor tdropdownlistclientcontroller.destroy; +begin + inherited; + fdropdown.free; +end; + +procedure tdropdownlistclientcontroller.setdropdown( + const avalue: tifidropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tdropdownlistclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidropdownlistdatalink); +end; + +procedure tdropdownlistclientcontroller.valuestoclient(const alink: pointer); +begin + fdropdown.valuestoclient(alink); + inherited; +end; + +{ tenumclientcontroller } + +constructor tenumclientcontroller.create(const aowner: tmsecomponent); +begin + fdropdown:= tifidropdownlistcontroller.create(self); + inherited; + fvaluemin:= -1; + fvalue:= -1; + fvaluedefault:= -1; +end; + +destructor tenumclientcontroller.destroy; +begin + inherited; + fdropdown.free; +end; + +procedure tenumclientcontroller.setdropdown( + const avalue: tifidropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tenumclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidropdownlistdatalink); +end; + +procedure tenumclientcontroller.valuestoclient(const alink: pointer); +begin + fdropdown.valuestoclient(alink); + inherited; +end; + +{ tifienumlinkcomp } + +function tifienumlinkcomp.getcontroller: tenumclientcontroller; +begin + result:= tenumclientcontroller(inherited controller); +end; + +procedure tifienumlinkcomp.setcontroller( + const avalue: tenumclientcontroller); +begin + inherited setcontroller(avalue); +end; + +function tifienumlinkcomp.getcontrollerclass: customificlientcontrollerclassty; +begin + result:= tenumclientcontroller; +end; + +{ tifidropdowncol } + +procedure tifidropdowncol.setdatasource(const avalue: tifidatasource); +begin + if avalue <> fdatasource then begin + setifidatasource(iifidatasourceclient(self),avalue,fdatasource); + end; +end; + +procedure tifidropdowncol.setdatafield(const avalue: ififieldnamety); +begin + if avalue <> fdatafield then begin + fdatafield:= avalue; + bindingchanged; + end; +end; + +procedure tifidropdowncol.bindingchanged; +begin +end; + +procedure tifidropdowncol.getfieldinfo(const apropname: ififieldnamety; + var adatasource: tifidatasource; var atypes: listdatatypesty); +begin + adatasource:= fdatasource; + atypes:= [dl_msestring,dl_ansistring]; +end; + +function tifidropdowncol.ifigriddata: tdatalist; +begin + result:= self; +end; + +function tifidropdowncol.ififieldname: string; +begin + result:= fdatafield; +end; + +{ tifidatasource } + +constructor tifidatasource.create(aowner: tcomponent); +begin + if ffields = nil then begin + ffields:= tififields.create; + end; +{$ifdef usedelegation} + ffieldsourceintf:= iififieldsource(ffields); +{$endif} + inherited; +end; + +destructor tifidatasource.destroy; +begin + freeandnil(ftimer); + inherited; + ffields.free; +end; + +procedure tifidatasource.setfields(const avalue: tififields); +begin + ffields.assign(avalue); +end; +{$ifndef usedelegation} +function tifidatasource.getfieldnames(const atypes: listdatatypesty): msestringarty; +begin + result:= ffields.getfieldnames(atypes); +end; +{$endif} + +procedure tifidatasource.open; +begin + if canevent(tmethod(fonbeforeopen)) then begin + fonbeforeopen(self); + end; +end; + +procedure tifidatasource.afteropen; +begin + factive:= true; + if canevent(tmethod(fonafteropen)) then begin + fonafteropen(self); + end; +end; + +procedure tifidatasource.close; +begin + factive:= false; +end; + +procedure tifidatasource.setactive(const avalue: boolean); +begin + if csreading in componentstate then begin + fopenafterread:= avalue; + end + else begin + if factive <> avalue then begin + if avalue then begin + open; + end + else begin + fopenafterread:= false; + close; + end; + end; + end; +end; + +procedure tifidatasource.dorefresh(const sender: tobject); +var + b1: boolean; + ar1: datalistarty; + ar2: stringarty; + int1: integer; +begin + destdatalists(ar2,ar1); + b1:= frefreshing; + frefreshing:= true; + for int1:= 0 to high(ar1) do begin + ar1[int1].beginupdate(); + end; + try + active:= false; + active:= true; + finally + for int1:= 0 to high(ar1) do begin + ar1[int1].endupdate(); + end; + frefreshing:= b1; + end; +end; + +procedure tifidatasource.refresh(const delayus: integer = -1); +begin + if delayus < 0 then begin + freeandnil(ftimer); + dorefresh(nil); + end + else begin + if ftimer = nil then begin + ftimer:= tsimpletimer.create(delayus,@dorefresh,true,[to_single]); + end + else begin + ftimer.interval:= delayus; //single shot + ftimer.enabled:= true; + end; + end; +end; + +procedure tifidatasource.checkrefresh(); +begin + if ftimer <> nil then begin + ftimer.firependingandstop; //cancel wait + end; +end; + +procedure tifidatasource.loaded; +begin + inherited; + if fopenafterread then begin + try + active:= true; + except + if csdesigning in componentstate then begin + application.handleexception; + end + else begin + raise; + end; + end; + end; +end; + +procedure tifidatasource.doactivated; +begin + active:= true; +end; + +procedure tifidatasource.dodeactivated; +begin + active:= false; +end; + +procedure tifidatasource.getbindinginfo(const alink: pointer); +begin + with iifidatasourceclient(alink) do begin + fnamear[findex]:= ififieldname; + flistar[findex]:= ifigriddata; + end; + inc(findex); +end; + +procedure tifidatasource.destdatalists(out names: stringarty; + out lists: datalistarty); +var + int1,int2,int3: integer; +begin + with getobjectlinker do begin + setlength(fnamear,count); + setlength(flistar,count); + setlength(names,count); + setlength(lists,count); + findex:= 0; + forall({$ifdef FPC}@{$endif}getbindinginfo,typeinfo(iifidatasourceclient)); + end; + int3:= 0; + with ffields do begin +// result:= nil; +// setlength(result,count); + for int1:= 0 to high(fnamear) do begin + if fnamear[int1] <> '' then begin + for int2:= 0 to high(fitems) do begin + if (fnamear[int1] = tififield(fitems[int2]).ffieldname) then begin + names[int3]:= fnamear[int1]; + lists[int3]:= flistar[int1]; + inc(int3); + break; + end; + end; + end; + end; + end; + setlength(lists,int3); + setlength(names,int3); + fnamear:= nil; + flistar:= nil; +// for int1:= 0 to high(result) do begin +// end; +end; + +{ tififield } + +{ tififields } + +constructor tififields.create; +begin + inherited create(getififieldclass); +end; + +function tififields.getififieldclass: ififieldclassty; +begin + result:= tififield; +end; + +function tififields.getfieldnames(const atypes: listdatatypesty): msestringarty; +var + int1,int2: integer; +begin + setlength(result,count); + int2:= 0; + for int1:= 0 to count - 1 do begin + with tififield(fitems[int1]) do begin + if (atypes = []) or (datatype in atypes) then begin + result[int2]:= msestring(fieldname); + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +class function tififields.getitemclasstype: persistentclassty; +begin + result:= tififield; +end; + +{ tififieldlink } + +function tififieldlink.getfieldnames( + const appropname: ifisourcefieldnamety): msestringarty; +begin + result:= fowner.getfieldnames(datatype); +end; + +procedure tififieldlink.setdesignsourcefieldname( + const aname: ifisourcefieldnamety); +begin + if ffieldname = '' then begin + ffieldname:= aname; + end; + if fdatatype = dl_none then begin + datatype:= fowner.sourcefieldtype(aname); + end; +end; + +{$ifndef FPC} +function tififieldlink._addref: integer; +begin + result:= -1; +end; + +function tififieldlink._release: integer; +begin + result:= -1; +end; + +function tififieldlink.QueryInterface(const IID: TGUID; out Obj): HResult; +begin + if GetInterface(IID, Obj) then begin + Result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; +{$endif} +{ tififieldlinks } + +function tififieldlinks.getififieldclass: ififieldlinkclassty; +begin + result:= tififieldlink; +end; + +procedure tififieldlinks.createitem(const index: integer; var item: tpersistent); +begin + item:= getififieldclass.create; + tififieldlink(item).fowner:= self; +end; + +function tififieldlinks.getfieldnames( + const adatatype: listdatatypety): msestringarty; +begin + result:= nil; +end; + +function tififieldlinks.sourcefieldnames: stringarty; +var + int1: integer; +begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= tififieldlink(fitems[int1]).sourcefieldname; + end; +end; + +function tififieldlinks.sourcefieldtype( + const afieldname: string): listdatatypety; +begin + result:= dl_none; //dummy +end; + +{ tificonnectedfields } + +constructor tificonnectedfields.create(const aowner: tconnectedifidatasource); +begin + inherited create; + fowner:= aowner; +end; + +function tificonnectedfields.sourcefieldtype( + const afieldname: string): listdatatypety; +begin + result:= dl_none; + if fowner.fconnectionintf <> nil then begin + result:= fowner.fconnectionintf.getdatatype(afieldname); + end; +end; + +function tificonnectedfields.getfieldnames( + const adatatype: listdatatypety): msestringarty; +begin + result:= fowner.getfieldnames(adatatype); +end; + +{ tconnectedifidatasource } + +constructor tconnectedifidatasource.create(aowner: tcomponent); +begin + if ffields = nil then begin + ffields:= tificonnectedfields.create(self); + end; + inherited; +end; + +procedure tconnectedifidatasource.setconnection(const avalue: tmsecomponent); +begin + if avalue <> nil then begin + checkcorbainterface(self,avalue,typeinfo(iifidataconnection),fconnectionintf); + end; + setlinkedvar(avalue,fconnection); +end; + +function tconnectedifidatasource.getfields: tificonnectedfields; +begin + result:= tificonnectedfields(inherited fields); +end; + +procedure tconnectedifidatasource.setfields(const avalue: tificonnectedfields); +begin + inherited setfields(avalue); +end; + +function tconnectedifidatasource.getfieldnames( + const adatatype: listdatatypety): msestringarty; +begin + result:= nil; + if fconnectionintf <> nil then begin + result:= fconnectionintf.getfieldnames(adatatype); + end; +end; + +procedure tconnectedifidatasource.open; +var + ar1: stringarty; + ar2: datalistarty; +begin + inherited; + checkconnection; + destdatalists(ar1,ar2); + fconnectionintf.fetchdata(ar1,ar2); + afteropen; +end; + +procedure tconnectedifidatasource.close; +var + ar1: datalistarty; + ar2: stringarty; + int1: integer; +begin + destdatalists(ar2,ar1); + for int1:= 0 to high(ar1) do begin + ar1[int1].clear; + end; + inherited; +end; + +procedure tconnectedifidatasource.checkconnection; +begin + if fconnectionintf = nil then begin + raise exception.create(name+': No connection.'); + end; +end; + +{ tifiintegerdatalist } + +constructor tifiintegerdatalist.create(const aowner: tintegerclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifiintegerdatalist.getdefault: pointer; +begin + result:= @fowner.valuedefault; +end; + +{ tifiint64datalist } + +constructor tifiint64datalist.create(const aowner: tint64clientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifiint64datalist.getdefault: pointer; +begin + result:= @fowner.valuedefault; +end; + +{ tifipointerdatalist } + +constructor tifipointerdatalist.create(const aowner: tpointerclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +{ tifibooleandatalist } + +constructor tifibooleandatalist.create(const aowner: tbooleanclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifibooleandatalist.getdefault: pointer; +begin + result:= @fowner.fvaluedefault; +end; + +{ tifirealdatalist } + +constructor tifirealdatalist.create(const aowner: trealclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifirealdatalist.getdefault: pointer; +begin + result:= @fowner.fvaluedefault; +end; + +{ tifidatetimedatalist } + +constructor tifidatetimedatalist.create(const aowner: tdatetimeclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifidatetimedatalist.getdefault: pointer; +begin + result:= @fowner.fvaluedefault; +end; + +{ tifimsestringdatalist } + +constructor tifimsestringdatalist.create(const aowner: tstringclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifimsestringdatalist.getdefault: pointer; +begin + result:= @fowner.fvaluedefault; +end; + +{ trowstatehandler } + +constructor trowstatehandler.create(const aowner: tgridclientcontroller); +begin + fowner:= aowner; + initsource(flistlink); + inherited create; +end; + +destructor trowstatehandler.destroy; +begin + removesource(flistlink); + inherited; +end; + +procedure trowstatehandler.setifilink(const avalue: tifivaluelinkcomp); +begin + setifilinkcomp(iifidatalink(self),avalue,tifilinkcomp(fifilink)); +end; + +procedure trowstatehandler.setifiserverintf(const aintf: iifiserver); +begin + //dummy +end; + +procedure trowstatehandler.ifisetvalue(var avalue; var accept: boolean); +begin + //dummy +end; + +procedure trowstatehandler.getifivalue(var avalue); +begin + //dummy +end; + +procedure trowstatehandler.setifivalue(const avalue); +begin + //dummy +end; + +function trowstatehandler.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure trowstatehandler.setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); +begin + //dummy +end; + +procedure trowstatehandler.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + internallinksource(alist,0,flistlink.source); +end; + +function trowstatehandler.getgriddata: tdatalist; +begin + result:= nil; +end; + +function trowstatehandler.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure trowstatehandler.sourcechange(const sender: tdatalist; + const aindex: integer); +begin //todo: optimize + if checksourcechange(flistlink,sender,aindex) then begin + if not (dls_remotelock in fstate) then begin + include(fstate,dls_remotelock); + try + if aindex < 0 then begin + fowner.rowcount:= sender.count; + end; + findexpar:= aindex; + tmsecomponent1(fowner.fowner).getobjectlinker.forall( + {$ifdef FPC}@{$endif}updateclient,fowner); + //... + finally + exclude(fstate,dls_remotelock); + end; + end; + end; +end; + +function trowstatehandler.canlink(const asource: tdatalist; + const atag: integer): boolean; +begin + result:= true; //datalist type defined by ifidatalink kind +end; + +procedure trowstatehandler.listdestroyed(const sender: tdatalist); +begin + if sender = flistlink.source then begin + flistlink.source:= nil; + end; + inherited; +end; + +procedure trowstatehandler.itemchanged(const sender: tcustomrowstatelist; + const aindex: integer); +begin //todo: optimize + if (flistlink.source <> nil) and not (dls_remotelock in fstate) then begin + include(fstate,dls_remotelock); + try + if aindex < 0 then begin + flistlink.source.count:= sender.count; + end; + updateremote(sender,aindex); + finally + exclude(fstate,dls_remotelock); + end; + end; +end; + +procedure trowstatehandler.updatereadonlystate; +begin + //dummy +end; + +function trowstatehandler.getdefaultifilink: iificlient; +begin + result:= iifidatalink(self); +end; + +{ trowstateintegerhandler } + +function trowstateintegerhandler.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure trowstateintegerhandler.setifilink(const avalue: tifiintegerlinkcomp); +begin + inherited setifilink(avalue); +end; + +{ trowstatebooleanhandler } + +function trowstatebooleanhandler.getifilink: tifibooleanlinkcomp; +begin + result:= tifibooleanlinkcomp(fifilink); +end; + +procedure trowstatebooleanhandler.setifilink(const avalue: tifibooleanlinkcomp); +begin + inherited setifilink(avalue); +end; + +{ trowstatecolorhandler } + +procedure trowstatecolorhandler.updateclient(const alink: pointer); +begin + with iifigridlink(alink) do begin + with getrowstate do begin + if findexpar < 0 then begin + colorar:= tintegerdatalist(flistlink.source).asarray; + end + else begin + color[findexpar]:= tintegerdatalist(flistlink.source)[findexpar]; + end; + rowchanged(findexpar); + end; + end; +end; + +procedure trowstatecolorhandler.updateremote(const sender: tcustomrowstatelist; + const aindex: integer); +begin + if aindex < 0 then begin + tintegerdatalist(flistlink.source).asarray:= sender.colorar; + end + else begin + tintegerdatalist(flistlink.source)[aindex]:= sender.color[aindex]; + end; +end; + +{ trowstatefonthandler } + +procedure trowstatefonthandler.updateclient(const alink: pointer); +begin + with iifigridlink(alink) do begin + with getrowstate do begin + if findexpar < 0 then begin + fontar:= tintegerdatalist(flistlink.source).asarray; + end + else begin + font[findexpar]:= tintegerdatalist(flistlink.source)[findexpar]; + end; + rowchanged(findexpar); + end; + end; +end; + +procedure trowstatefonthandler.updateremote(const sender: tcustomrowstatelist; + const aindex: integer); +begin + if aindex < 0 then begin + tintegerdatalist(flistlink.source).asarray:= sender.fontar; + end + else begin + tintegerdatalist(flistlink.source)[aindex]:= sender.font[aindex]; + end; +end; + +{ trowstatefoldlevelhandler } + +procedure trowstatefoldlevelhandler.updateclient(const alink: pointer); +begin + with iifigridlink(alink) do begin + with getrowstate do begin + if findexpar < 0 then begin + foldlevelar:= tintegerdatalist(flistlink.source).asarray; + end + else begin + foldlevel[findexpar]:= tintegerdatalist(flistlink.source)[findexpar]; + end; + rowchanged(findexpar); + rowstatechanged(findexpar); + end; + end; +end; + +procedure trowstatefoldlevelhandler.updateremote(const sender: tcustomrowstatelist; + const aindex: integer); +begin + if aindex < 0 then begin + tintegerdatalist(flistlink.source).asarray:= sender.foldlevelar; + end + else begin + tintegerdatalist(flistlink.source)[aindex]:= sender.foldlevel[aindex]; + end; +end; + +{ trowstatehiddenhandler } + +procedure trowstatehiddenhandler.updateclient(const alink: pointer); +begin + with iifigridlink(alink) do begin + with getrowstate do begin + if findexpar < 0 then begin + hiddenar:= tbooleandatalist(flistlink.source).asarray; + end + else begin + hidden[findexpar]:= tbooleandatalist(flistlink.source)[findexpar]; + end; +// rowchanged(findexpar); +// rowstatechanged(findexpar); +// layoutchanged; + end; + end; +end; + +procedure trowstatehiddenhandler.updateremote(const sender: tcustomrowstatelist; + const aindex: integer); +begin + if aindex < 0 then begin + tbooleandatalist(flistlink.source).asarray:= sender.hiddenar; + end + else begin + tbooleandatalist(flistlink.source)[aindex]:= sender.hidden[aindex]; + end; +end; + +{ trowstatehiddenhandler } + +procedure trowstatefoldissumhandler.updateclient(const alink: pointer); +begin + with iifigridlink(alink) do begin + with getrowstate do begin + if findexpar < 0 then begin + foldissumar:= tbooleandatalist(flistlink.source).asarray; + end + else begin + foldissum[findexpar]:= tbooleandatalist(flistlink.source)[findexpar]; + end; +// rowchanged(findexpar); +// rowstatechanged(findexpar); +// layoutchanged; + end; + end; +end; + +procedure trowstatefoldissumhandler.updateremote(const sender: tcustomrowstatelist; + const aindex: integer); +begin + if aindex < 0 then begin + tbooleandatalist(flistlink.source).asarray:= sender.foldissumar; + end + else begin + tbooleandatalist(flistlink.source)[aindex]:= sender.foldissum[aindex]; + end; +end; + +{ tgridclientcontroller } + +constructor tgridclientcontroller.create(const aowner: tmsecomponent); +begin + fdatacols:= tifilinkcomparrayprop.create; + frowstatecolor:= trowstatecolorhandler.create(self); + frowstatefont:= trowstatefonthandler.create(self); + frowstatefoldlevel:= trowstatefoldlevelhandler.create(self); + frowstatehidden:= trowstatehiddenhandler.create(self); + frowstatefoldissum:= trowstatefoldissumhandler.create(self); + inherited; +end; + +destructor tgridclientcontroller.destroy; +begin + fdatacols.free; + frowstatecolor.free; + frowstatefont.free; + frowstatefoldlevel.free; + frowstatehidden.free; + frowstatefoldissum.free; + inherited; +end; + +procedure tgridclientcontroller.statreadrowstate(const alink: pointer); +var + list1: tcustomrowstatelist; +begin + list1:= iifigridlink(alink).getrowstate; + if list1 <> nil then begin + tstatreader(fitempo).readdatalist(rowstatevarname,list1); + end; +end; + +procedure tgridclientcontroller.dostatread(const reader: tstatreader); +var + int1: integer; + lico: tifivaluelinkcomp; +begin + inherited; + fitempo:= reader; + tmsecomponent1(fowner).getobjectlinker.forall({$ifdef FPC}@{$endif}statreadrowstate,self); + for int1:= 0 to datacols.count - 1 do begin + lico:= datacols[int1].link; + if lico <> nil then begin + with lico.controller do begin + if fstatfile = nil then begin + dostatread(reader); + end; + end; + end; + end; +end; + +procedure tgridclientcontroller.statwriterowstate(const alink: pointer; + var handled: boolean); +var + list1: tcustomrowstatelist; +begin + list1:= iifigridlink(alink).getrowstate; + if list1 <> nil then begin + tstatwriter(fitempo).writedatalist(rowstatevarname,list1); + handled:= true; + end; +end; + +procedure tgridclientcontroller.dostatwrite(const writer: tstatwriter); +var + int1: integer; + lico: tifivaluelinkcomp; +begin + inherited; + fitempo:= writer; + tmsecomponent1(fowner).getobjectlinker.forfirst({$ifdef FPC}@{$endif}statwriterowstate,self); + for int1:= 0 to datacols.count - 1 do begin + lico:= datacols[int1].link; + if lico <> nil then begin + with lico.controller do begin + if fstatfile = nil then begin + dostatwrite(writer); +// fitempo:= writer; +// tmsecomponent1(fowner).getobjectlinker.forfirst( +// @statwritelist,lico.controller); + end; + end; + end; + end; +end; + +procedure tgridclientcontroller.setrowcount(const avalue: integer); +begin + frowcount:= avalue; + change; +end; + +procedure tgridclientcontroller.valuestoclient(const alink: pointer); +begin + setintegerval(iifigridlink(alink),'rowcount',frowcount); + inherited; +end; + +procedure tgridclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getintegerval(iifigridlink(alink),'rowcount',frowcount); +end; + +procedure tgridclientcontroller.docellevent(var info: ificelleventinfoty); +begin + if fowner.canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; +end; + +procedure tgridclientcontroller.dorowsinserting(var index: integer; + var count: integer; const userinput: boolean); +begin + if fowner.canevent(tmethod(fonrowsinserting)) then begin + fonrowsinserting(self,index,count,userinput); + end; +end; + +procedure tgridclientcontroller.dorowsinserted(const index: integer; + const count: integer; const userinput: boolean); +begin + if fowner.canevent(tmethod(fonrowsinserted)) then begin + fonrowsinserted(self,index,count,userinput); + end; +end; + +procedure tgridclientcontroller.dorowsdeleting(var index: integer; + var count: integer; const userinput: boolean); +begin + if fowner.canevent(tmethod(fonrowsdeleting)) then begin + fonrowsdeleting(self,index,count,userinput); + end; +end; + +procedure tgridclientcontroller.dorowsdeleted(const index: integer; + const count: integer; const userinput: boolean); +begin + if fowner.canevent(tmethod(fonrowsdeleted)) then begin + fonrowsdeleted(self,index,count,userinput); + end; +end; + +function tgridclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifigridlink); +end; + +procedure tgridclientcontroller.setdatacols(const avalue: tifilinkcomparrayprop); +begin + fdatacols.assign(avalue); +end; + +procedure tgridclientcontroller.itemappendrow(const alink: pointer); +begin + iifigridlink(alink).appendrow(fcheckautoappend); +end; + +procedure tgridclientcontroller.getrowstate1(const alink: pointer; + var handled: boolean); +var + list1: tcustomrowstatelist; +begin + list1:= iifigridlink(alink).getrowstate; + if list1 <> nil then begin + handled:= true; + pdatalist(fitempo)^:= list1; + end; +end; + +function tgridclientcontroller.getrowstate: tcustomrowstatelist; +begin + result:= nil; + fitempo:= @result; + tmsecomponent1(fowner).getobjectlinker.forfirst({$ifdef FPC}@{$endif}getrowstate1,self); +end; + +procedure tgridclientcontroller.appendrow(const avalues: array of const; + const checkautoappend: boolean = false); +var + int1,int2: integer; + comp1: tifilinkcomp; +begin + fcheckautoappend:= checkautoappend; + tmsecomponent1(fowner).getobjectlinker.forall({$ifdef FPC}@{$endif}itemappendrow,self); + int2:= high(avalues); + if int2 >= datacols.count then begin + int2:= datacols.count; + end; + for int1:= 0 to int2 do begin + comp1:= tificolitem(fdatacols.fitems[int1]).link; + if comp1 <> nil then begin + with avalues[int1] do begin + case vtype of + vtstring: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= msestring(vstring^); + end; + end; + end; + end; + vtansistring: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= msestring(ansistring(vansistring)); + end; + end; + end; + end; + {$ifdef mse_hasvtunicodestring} + vtunicodestring: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= unicodestring(vunicodestring); + end; + end; + end; + end; + {$endif} + vtwidestring: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= widestring(vwidestring); + end; + end; + end; + end; + vtpchar: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= msestring(ansistring(vpchar)); + end; + end; + end; + end; + vtpwidechar: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= msestring(vpwidechar); + end; + end; + end; + end; + vtchar: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= msestring(vchar); + end; + end; + end; + end; + vtwidechar: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= vwidechar; + end; + end; + end; + end; + vtboolean: begin + if comp1 is tifibooleanlinkcomp then begin + with tifibooleanlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= longbool(vboolean); + end; + end; + end; + end; + vtinteger: begin + if comp1 is tifiintegerlinkcomp then begin + with tifiintegerlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= vinteger; + end; + end; + end; + end; + vtextended: begin + if comp1 is tifireallinkcomp then begin + with tifireallinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= vextended^; + end; + end; + end + else begin + if comp1 is tifidatetimelinkcomp then begin + with tifidatetimelinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= vextended^; + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tgridclientcontroller.rowempty(const arow: integer): boolean; +var + int1: integer; + link1: tifivaluelinkcomp; +begin + result:= true; + if arow >= 0 then begin + for int1:= 0 to high(datacols.fitems) do begin + link1:= tificolitem(datacols.fitems[int1]).link; + if link1 <> nil then begin + with link1.controller.datalist do begin + if (arow < count) and not empty(arow) then begin + result:= false; + break; + end; + end; + end; + end; + end; +end; + +function tgridclientcontroller.getrowstate_color: tifiintegerlinkcomp; +begin + result:= frowstatecolor.ifilink; +end; + +procedure tgridclientcontroller.setrowstate_color(const avalue: tifiintegerlinkcomp); +begin + frowstatecolor.ifilink:= avalue; +end; + +function tgridclientcontroller.getrowstate_font: tifiintegerlinkcomp; +begin + result:= frowstatefont.ifilink; +end; + +procedure tgridclientcontroller.setrowstate_font( + const avalue: tifiintegerlinkcomp); +begin + frowstatefont.ifilink:= avalue; +end; + +function tgridclientcontroller.getrowstate_foldlevel: tifiintegerlinkcomp; +begin + result:= frowstatefoldlevel.ifilink; +end; + +procedure tgridclientcontroller.setrowstate_foldlevel( + const avalue: tifiintegerlinkcomp); +begin + frowstatefoldlevel.ifilink:= avalue; +end; + +function tgridclientcontroller.getrowstate_hidden: tifibooleanlinkcomp; +begin + result:= frowstatehidden.ifilink; +end; + +procedure tgridclientcontroller.setrowstate_hidden( + const avalue: tifibooleanlinkcomp); +begin + frowstatehidden.ifilink:= avalue; +end; + +function tgridclientcontroller.getrowstate_foldissum: tifibooleanlinkcomp; +begin + result:= frowstatefoldissum.ifilink; +end; + +procedure tgridclientcontroller.setrowstate_foldissum( + const avalue: tifibooleanlinkcomp); +begin + frowstatefoldissum.ifilink:= avalue; +end; + +function tgridclientcontroller.checkcomponent(const aintf: iifilink): pointer; +begin + result:= inherited checkcomponent(aintf); + iifigridlink(aintf).getrowstate.linkclient(idatalistclient(self)); +end; + +procedure tgridclientcontroller.itemchanged(const sender: tdatalist; + const aindex: integer); +begin + if not (gcs_itemchangelock in fgridstate) then begin + include(fgridstate,gcs_itemchangelock); + try + frowstatecolor.itemchanged(tcustomrowstatelist(sender),aindex); + frowstatefont.itemchanged(tcustomrowstatelist(sender),aindex); + frowstatefoldlevel.itemchanged(tcustomrowstatelist(sender),aindex); + frowstatehidden.itemchanged(tcustomrowstatelist(sender),aindex); + frowstatefoldissum.itemchanged(tcustomrowstatelist(sender),aindex); + finally + exclude(fgridstate,gcs_itemchangelock); + end; + end; +end; + +procedure tgridclientcontroller.canclose1(const alink: pointer; + var handled: boolean); +begin + pboolean(fitempo)^:= iifigridlink(alink).canclose1; + handled:= not pboolean(fitempo)^; +end; + +function tgridclientcontroller.canclose: boolean; +begin + result:= true; + fitempo:= @result; + tmsecomponent1(fowner).getobjectlinker.forfirst( + {$ifdef FPC}@{$endif}canclose1,self); +end; + +{ tformclientcontroller } + +procedure tformclientcontroller.setmodalresult(const avalue: modalresultty); +begin + fmodalresult:= avalue; + change(nil); +end; + +function tformclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iififormlink); +end; + +procedure tformclientcontroller.linkset(const alink: iificlient); +begin + //do nothing +end; + +procedure tformclientcontroller.valuestoclient(const alink: pointer); +begin + iififormlink(alink).setmodalresult(fmodalresult); +end; + +procedure tformclientcontroller.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +begin + fmodalresult:= amodalresult; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseificompglob.pas b/mseide-msegui/lib/common/ifi/mseificompglob.pas new file mode 100644 index 0000000..a8fa562 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseificompglob.pas @@ -0,0 +1,81 @@ +{ MSEgui Copyright (c) 2010-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseificompglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + mseglob,mseifiglob,mseclasses,msetypes,msegridsglob,mseguiglob,msegraphutils, + typinfo,msedatalist,mseapplication,mseinterfaces; + +type + ificelleventinfoty = record //same layout as celleventinfoty + cell: gridcoordty; + grid: tobject; + case eventkind: celleventkindty of + cek_exit,cek_enter,cek_focusedcellchanged: + (cellbefore,newcell: gridcoordty; selectaction: focuscellactionty); + cek_select: + (selected: boolean; accept: boolean); + cek_mousemove,cek_mousepark,cek_firstmousepark, + cek_buttonpress,cek_buttonrelease: + (zone: cellzonety; mouseeventinfopo: pmouseeventinfoty; + gridmousepos: pointty); + cek_keydown,cek_keyup: + (keyeventinfopo: pkeyeventinfoty); + end; + + iifilink = interface(iificlient)[miid_iifilink] + function getifilinkkind: ptypeinfo; + function getobjectlinker: tobjectlinker; + end; + + iifiexeclink = interface(iifilink)[miid_iifiexeclink] + procedure execute(const force: boolean = false); + procedure ifisetenabled(const avalue: boolean); + end; + + iififormlink = interface(iifilink)[miid_iififormlink] + procedure setmodalresult(const avalue: modalresultty); + end; + + iifidialoglink = interface(iifilink)[miid_iifidialoglink] + function showdialog(out adialog: tactcomponent): modalresultty; + end; + + iifidatalink = interface(iifilink)[miid_iifidatalink] + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue); //for pointer property without RTTI + procedure setifivalue(const avalue); //for pointer property without RTTI + procedure updatereadonlystate; + end; + + iifigridlink = interface(iifidatalink)[miid_iifigridlink] + function appendrow(const checkautoappend: boolean = false): integer; + function getrowstate: tcustomrowstatelist; + procedure rowchanged(const arow: integer); + procedure rowstatechanged(const arow: integer); + procedure layoutchanged; + function canclose1: boolean; + end; + + iifidataserver = interface(iifiserver) + procedure valuechanged(const sender: iifidatalink); + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); + end; + + iifigridserver = interface(iifiserver) + + end; + +implementation +end. diff --git a/mseide-msegui/lib/common/ifi/mseifidbcomp.pas b/mseide-msegui/lib/common/ifi/mseifidbcomp.pas new file mode 100644 index 0000000..a4020dc --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifidbcomp.pas @@ -0,0 +1,265 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + experimental user <-> business logic connection components. + Warning: works with RTTI and is therefore slow. +} +unit mseifidbcomp; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + mseglob,mseificomp,msesqlresult,msqldb,mseclasses,classes,msedatalist,msestrings,mdb, + msedb,msetypes,mseinterfaces; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +type +{ + tifisqldatasource = class; + tifisqlfieldlinks = class(tififieldlinks) + protected + fowner: tifisqldatasource; + function getfieldnames( + const adatatype: listdatatypety): msestringarty; override; + end; + + tifisqldatasource = class(tifidatasource) + private + fsource: tsqlresult; + procedure setsource(const avalue: tsqlresult); + protected + procedure open; override; + procedure close; override; + public + constructor create(aowner: tcomponent); override; + procedure refresh; + published + property source: tsqlresult read fsource write setsource; + end; +} + dbfieldinfoty = record + name: msestring; + datatype: tfieldtype; + end; + dbfieldinfoarty = array of dbfieldinfoty; + + iifidbdataconnection = interface(iifidataconnection)[miid_iifidbdataconnection] + function getfieldinfos: dbfieldinfoarty; + end; + + tifisqlresult = class(tsqlresult,iifidataconnection,iifidbdataconnection) + protected + //iifidataconnection + procedure fetchdata(const acolnames: array of string; + acols: array of tdatalist); + function getfieldnames(const adatatype: listdatatypety): msestringarty; + function getdatatype(const aname: ansistring): listdatatypety; + //dl_none if not found + //iifidbdataconnection + function getfieldinfos: dbfieldinfoarty; + public + end; + +const + listtypecompatibledbtypes: array[listdatatypety] of fieldtypesty = + ( +//dl_none,dl_integer, dl_int64, dl_currency, + [], longintfcomp,largeintfcomp+[ftlargeint],realfcomp, +//dl_real, dl_realint,dl_realsum, + realfcomp,realfcomp, realfcomp, +//dl_datetime, + datetimefcomp, +//dl_pointer + [], +//dl_ansistring,dl_msestring,dl_doublemsestring,dl_msestringint, + stringfcomp, stringfcomp, stringfcomp, stringfcomp, +//dl_complex,dl_rowstate,dl_custom + [], [], []); + + compatiblelisttypes: array[tfieldtype] of listdatatypety = ( + //ftUnknown,ftString, ftSmallint,ftInteger, ftWord, + dl_none, dl_msestring,dl_integer,dl_integer,dl_integer, + // ftBoolean,ftFloat,ftCurrency,ftBCD, + dl_integer, dl_real,dl_real, dl_currency, + //ftDate, ftTime, ftDateTime, + dl_datetime,dl_datetime,dl_datetime, + //ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, + dl_ansistring,dl_ansistring,dl_integer,dl_ansistring,dl_msestring, + //ftGraphic, ftFmtMemo, + dl_ansistring,dl_msestring, + //ftParadoxOle,ftDBaseOle,ftTypedBinary,ftCursor,ftFixedChar, + dl_none, dl_none, dl_none, dl_none, dl_msestring, + //ftWideString,ftLargeint,ftADT, ftArray,ftReference, + dl_msestring,dl_int64, dl_none,dl_none,dl_none, + //ftDataSet,ftOraBlob,ftOraClob,ftVariant,ftInterface, + dl_none, dl_none, dl_none, dl_none, dl_none, + //ftIDispatch,ftGuid, ftTimeStamp,ftFMTBcd,ftFixedWideChar,ftWideMemo); + dl_none, dl_none,dl_datetime,dl_real, dl_msestring, dl_msestring + ); + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function matchfielddatatypes(const afielddefs: tfielddefs; + const atype: listdatatypety): msestringarty; +var + int1,int2: integer; +begin + result:= nil; + if afielddefs <> nil then begin + int2:= 0; + setlength(result,afielddefs.count); + for int1:= 0 to afielddefs.count-1 do begin + with afielddefs[int1] do begin + if (atype = dl_none) or + (datatype in listtypecompatibledbtypes[atype]) then begin + result[int2]:= msestring(name); + inc(int2); + end; + end; + end; + setlength(result,int2); + end; +end; + +function fielddefstodatatype(const afielddefs: tfielddefs; + const aname: ansistring): listdatatypety; +var + int1: integer; +begin + result:= dl_none; + for int1:= 0 to afielddefs.count - 1 do begin + with afielddefs[int1] do begin + if name = aname then begin + result:= compatiblelisttypes[datatype]; + break; + end; + end; + end; +end; + +(* +{ tifisqlfieldlinks } + +function tifisqlfieldlinks.getfieldnames( + const adatatype: listdatatypety): msestringarty; +begin + result:= matchfielddatatypes(fowner.fsource.fielddefs,adatatype); +end; + +{ tifisqldatasource } + +constructor tifisqldatasource.create(aowner: tcomponent); +begin + if ffields = nil then begin + ffields:= tifisqlfieldlinks.create; + tifisqlfieldlinks(ffields).fowner:= self; + end; + inherited; +end; + +procedure tifisqldatasource.setsource(const avalue: tsqlresult); +begin + setlinkedvar(avalue,tmsecomponent(fsource)); +end; + +procedure tifisqldatasource.open; +begin + inherited; + if fsource <> nil then begin + fsource.refresh; + end; + afteropen; +end; + +procedure tifisqldatasource.close; +begin + if fsource <> nil then begin + fsource.active:= false; + end; + inherited; +end; + +procedure tifisqldatasource.refresh; +begin + inherited close; + open; +end; +*) +{ tifisqlresult } + +function tifisqlresult.getfieldnames( + const adatatype: listdatatypety): msestringarty; +begin + result:= matchfielddatatypes(fielddefs,adatatype); +end; + +function tifisqlresult.getdatatype(const aname: ansistring): listdatatypety; + //dl_none if not found +begin + result:= fielddefstodatatype(fielddefs,aname); +end; + +procedure tifisqlresult.fetchdata(const acolnames: array of string; + acols: array of tdatalist); +//var +// ar1: datalistarty; +// ar2: integerarty; +// int1: integer; +begin + refresh; + if high(acols) <> high(acolnames) then begin + componentexception(self,'fetchdata() item count mismatch.'); + end; + internalloaddatalists(datacols.colsindexbyname(acolnames),acols); +{ + ar2:= cols.colsindexbyname(acolnames); + if high(ar2) > high(acols) then begin + setlength(ar2,length(acols)); + end; +} + { + setlength(ar1,cols.count); + for int1:= 0 to high(ar2) do begin + ar1[ar2[int1]]:= acols[int1]; + end; +// internalloaddatalists(acols); + } +// internalloaddatalists(ar1,ar2); + active:= false; +end; + +function tifisqlresult.getfieldinfos: dbfieldinfoarty; +var + int1: integer; + def1: tfielddef; +begin + setlength(result,fielddefs.count); + for int1:= 0 to high(result) do begin + def1:= fielddefs[int1]; + with result[int1] do begin + name:= msestring(def1.name); + datatype:= def1.datatype; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifidbgui.pas b/mseide-msegui/lib/common/ifi/mseifidbgui.pas new file mode 100644 index 0000000..7f149cd --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifidbgui.pas @@ -0,0 +1,228 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseifidbgui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,mseifigui,mseifids,mseifi,msedatalist,msegui,msemenus, + msegrids,mseguiglob,msetypes,mseapplication,msegraphics; +type + tdbrxwidgetgrid = class; + + bindnamesty = array[rowstatememberty] of string; +// rowstatebindingty = array[rowstatememberty] of integer; + + tifidbwidgetgridcontroller = class(tifiwidgetgridcontroller) + private +// frowstatebinding: rowstatebindingty; + fcolbinding: subdatainfoarty; + fnames: bindnamesty; + protected + procedure decoderecord(const aindex: integer; var adatapo: pifidataty); + procedure processdata(const adata: pifirecty; var adatapo: pchar); override; + function getifireckinds: ifireckindsty; override; + function bindnames(const aname: string; var ainfo: subdatainfoty): boolean; + public + constructor create(const aowner: tdbrxwidgetgrid; + const aintf: iactivatorclient); + published + property name_select: string read fnames[rsm_select] write fnames[rsm_select]; + property name_color: string read fnames[rsm_color] write fnames[rsm_color]; + property name_font: string read fnames[rsm_font] write fnames[rsm_font]; + property name_readonly: string read fnames[rsm_readonly] + write fnames[rsm_readonly]; + property name_foldlevel: string read fnames[rsm_foldlevel] + write fnames[rsm_foldlevel]; + property name_foldissum: string read fnames[rsm_foldissum] + write fnames[rsm_foldissum]; + property name_hidden: string read fnames[rsm_hidden] + write fnames[rsm_hidden]; + property name_merged: string read fnames[rsm_merged] + write fnames[rsm_merged]; + property name_height: string read fnames[rsm_height] write fnames[rsm_height]; + end; + + tdbrxwidgetgrid = class(trxwidgetgrid) + private + function getifi1: tifidbwidgetgridcontroller; + procedure setifi1(const avalue: tifidbwidgetgridcontroller); + protected + procedure rowstatechanged(const arow: integer); override; + public + constructor create(aowner: tcomponent); override; + published + property ifi: tifidbwidgetgridcontroller read getifi1 write setifi1; + end; + +implementation +uses + mseifilink; + +{ tifidbwidgetgridcontroller } + +constructor tifidbwidgetgridcontroller.create(const aowner: tdbrxwidgetgrid; + const aintf: iactivatorclient); +begin + inherited create(aowner,aintf); +end; + +function tifidbwidgetgridcontroller.getifireckinds: ifireckindsty; +begin + result:= inherited getifireckinds + [ik_dsdata,ik_fieldrec]; +end; + +procedure tifidbwidgetgridcontroller.decoderecord(const aindex: integer; + var adatapo: pifidataty); +var + int1: integer; +begin + for int1:= 0 to high(fcolbinding) do begin + inc(pchar(adatapo),decodeifidata(adatapo,aindex,fcolbinding[int1])); + end; +end; + +procedure tifidbwidgetgridcontroller.processdata(const adata: pifirecty; + var adatapo: pchar); +var + fielddefs1: tfielddefs; + int1,int2: integer; + index1: integer; +begin + with adata^.header do begin + case kind of + ik_dsdata: begin + fielddefs1:= tfielddefs.create(nil); + try + if decodefielddefs(pfdefdataty(adatapo),fielddefs1,int1) then begin + inc(adatapo,int1); + with tdbrxwidgetgrid(fowner) do begin +// fillchar(frowstatebinding,sizeof(frowstatebinding),0); + fcolbinding:= nil; + setlength(fcolbinding,fielddefs1.count); + for int1:= 0 to high(fcolbinding) do begin + if not bindnames(fielddefs1[int1].name,fcolbinding[int1]) then begin + fcolbinding[int1]:= datacols.colsubdatainfo(fielddefs1[int1].name); + end; + end; + if (igo_state in foptionsrx) or + (answersequence <> 0) and (answersequence = fdatasequence) then begin + beginupdate; + inc(fcommandlock); + try + rowcount:= precdataty(adatapo)^.header.count; + inc(adatapo,sizeof(recdataheaderty)); + for int1:= 0 to rowcount - 1 do begin + decoderecord(int1,pifidataty(adatapo)); + end; + include(fistate,rws_datareceived); + finally + dec(fcommandlock); + endupdate; + end; + end; + end; + end; + finally + fielddefs1.free; + end; + end; + ik_fieldrec: begin + with pfieldrecdataty(adatapo)^.header do begin + index1:= rowindex; + int2:= count; + with tdbrxwidgetgrid(fowner) do begin + case kind of + frk_insert: begin + insertrow(index1); + end; + frk_delete: begin + deleterow(index1); + exit; + end; + end; + end; + end; + adatapo:= @pfieldrecdataty(adatapo)^.data; + inc(fcommandlock); + try + for int1:= 0 to int2 - 1 do begin + with pfielddataty(adatapo)^ do begin + inc(adatapo,decodeifidata(@data,index1,fcolbinding[header.index]) + + sizeof(fielddataheaderty)); + end; + end; + finally + dec(fcommandlock); + end; + end; + else begin + inherited; + end; + end; + end; +end; + +function tifidbwidgetgridcontroller.bindnames(const aname: string; + var ainfo: subdatainfoty): boolean; +var + na1: rowstatememberty; +begin + result:= false; + for na1:= low(rowstatememberty) to high(rowstatememberty) do begin + if fnames[na1] = aname then begin + ainfo.list:= tdbrxwidgetgrid(fowner).datacols.rowstate; + ainfo.subindex:= ord(na1) + 1; + result:= true; + break; + end; + end; +end; + +{ tdbrxwidgetgrid } + +constructor tdbrxwidgetgrid.create(aowner: tcomponent); +begin + fifi:= tifidbwidgetgridcontroller.create(self,iactivatorclient(self)); + inherited; +end; + +function tdbrxwidgetgrid.getifi1: tifidbwidgetgridcontroller; +begin + result:= tifidbwidgetgridcontroller(fifi); +end; + +procedure tdbrxwidgetgrid.setifi1(const avalue: tifidbwidgetgridcontroller); +begin + setifi(avalue); +end; + +procedure tdbrxwidgetgrid.rowstatechanged(const arow: integer); +var + rsm1: rowstatememberty; +begin + with tifidbwidgetgridcontroller(fifi) do begin + if cancommandsend(igo_coldata) then begin + if arow < 0 then begin + //todo + end + else begin + for rsm1:= low(rowstatememberty) to high(rowstatememberty) do begin + if fnames[rsm1] <> '' then begin + senditem(ik_coldatachange,[encodecolchangedata(fnames[rsm1],arow, + fdatacols.rowstate,rsm1)]); + end; + end; + end; + end; + end; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifidialogcomp.pas b/mseide-msegui/lib/common/ifi/mseifidialogcomp.pas new file mode 100644 index 0000000..e13f6ea --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifidialogcomp.pas @@ -0,0 +1,153 @@ +{ MSEgui Copyright (c) 2009-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseifidialogcomp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseificompglob,mseificomp,mseapplication,mseclasses,mseglob,mseact,mserttistat; + +type + + beforedialogeventty = procedure(const sender: tobject; + const adialog: tactcomponent) of object; + afterdialogeventty = procedure(const sender: tobject; + const adialog: tactcomponent; + const amodalresult: modalresultty) of object; + + ifidialoginfoty = record + modalresult: modalresultty; + dialog: tactcomponent; + end; + pifidialoginfoty = ^ifidialoginfoty; + + tdialogclientcontroller = class(tcustomificlientcontroller) + private + fonbeforedialog: beforedialogeventty; + fonafterdialog: afterdialogeventty; + finfopo: pifidialoginfoty; + faction: tcustomaction; + frttistat: tcustomrttistat; + procedure execdialog(const alink: pointer; var handled: boolean); + procedure setaction(const avalue: tcustomaction); + procedure setrttistat(const avalue: tcustomrttistat); + protected + procedure beforedialog(const adialog: tactcomponent); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + function execute: modalresultty; reintroduce; + published + property onbeforedialog: beforedialogeventty read fonbeforedialog + write fonbeforedialog; + property onafterdialog: afterdialogeventty read fonafterdialog + write fonafterdialog; + property action: tcustomaction read faction write setaction; + property rttistat: tcustomrttistat read frttistat write setrttistat; + end; + + tifidialoglinkcomp = class(tifilinkcomp) + private + function getcontroller: tdialogclientcontroller; + procedure setcontroller(const avalue: tdialogclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + published + property controller: tdialogclientcontroller read getcontroller + write setcontroller; + end; + +implementation +type + tmsecomponent1 = class(tmsecomponent); + +{ tdialogclientcontroller } + +procedure tdialogclientcontroller.beforedialog(const adialog: tactcomponent); +begin + if frttistat <> nil then begin + frttistat.objtovalues(adialog); + end; + if fowner.canevent(tmethod(fonbeforedialog)) then begin + fonbeforedialog(self,adialog); + end; +end; + +procedure tdialogclientcontroller.execdialog(const alink: pointer; + var handled: boolean); +begin + handled:= true; + with finfopo^ do begin + modalresult:= iifidialoglink(alink).showdialog(dialog); + if (modalresult = mr_ok) and (frttistat <> nil) then begin + frttistat.valuestoobj(dialog); + end; + if fowner.canevent(tmethod(fonafterdialog)) then begin + fonafterdialog(self,dialog,modalresult); + end; + end; +end; + +function tdialogclientcontroller.execute: modalresultty; +var + info1: ifidialoginfoty; + po1: pifidialoginfoty; +begin + po1:= finfopo; + fillchar(info1,sizeof(info1),0); + finfopo:= @info1; + try + tmsecomponent1(fowner).getobjectlinker.forfirst( + {$ifdef FPC}@{$endif}execdialog,self); + result:= info1.modalresult; + finally + info1.dialog.release; + finfopo:= po1; + end; +end; + +procedure tdialogclientcontroller.setaction(const avalue: tcustomaction); +begin + setlinkedvar(avalue,tmsecomponent(faction)); +end; + +procedure tdialogclientcontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_fired) and (sender = faction) then begin + execute; + end; +end; + +procedure tdialogclientcontroller.setrttistat(const avalue: tcustomrttistat); +begin + setlinkedvar(avalue,tmsecomponent(frttistat)); +end; + +{ tifidialoglinkcomp } + +function tifidialoglinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tdialogclientcontroller; +end; + +function tifidialoglinkcomp.getcontroller: tdialogclientcontroller; +begin + result:= tdialogclientcontroller(inherited controller); +end; + +procedure tifidialoglinkcomp.setcontroller( + const avalue: tdialogclientcontroller); +begin + inherited setcontroller(avalue); +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifids.pas b/mseide-msegui/lib/common/ifi/mseifids.pas new file mode 100644 index 0000000..2d7a2c4 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifids.pas @@ -0,0 +1,3100 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseifids; +{$if defined(FPC) and (fpc_fullversion >= 020200)} + {$define mse_FPC_2_2} +{$ifend} +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mdb,mseifi,mseclasses,mseglob,mseevent,msedb,msetypes, + msebufdataset,msehash, + msestrings,mseifilink,msesqldb,msearrayprops,mseapplication; + + +type + ififieldoptionty = (ifo_local); + ififieldoptionsty = set of ififieldoptionty; +(* + recheaderty = record + blobinfo: pointer; //dummy + fielddata: fielddataty; + end; + precheaderty = ^recheaderty; + + intheaderty = record + end; + + intrecordty = record + intheader: intheaderty; + header: recheaderty; + end; + pintrecordty = ^intrecordty; + + bookmarkdataty = record + recno: integer; + recordpo: pintrecordty; + end; + pbookmarkdataty = ^bookmarkdataty; + + bufbookmarkty = record + data: bookmarkdataty; + flag : tbookmarkflag; + end; + pbufbookmarkty = ^bufbookmarkty; + + dsheaderty = record + bookmark: bufbookmarkty; + end; + dsrecordty = record + dsheader: dsheaderty; + header: recheaderty; + end; + pdsrecordty = ^dsrecordty; +*) +const +{$ifdef FPC} + intheadersize = sizeof(intrecordty.intheader); + dsheadersize = sizeof(dsrecordty.dsheader); +{$else} + intheadersize = sizeof(intheaderty); + dsheadersize = sizeof(dsheaderty); +{$endif} +type + +// structure of internal recordbuffer: +// +------------------+ +// intrecheaderty, |recheaderty,fielddata | +// |moved to tdataset buffer header| +// |fieldoffsets are in ffieldinfos[].offset +// | | +// structure of dataset recordbuffer: +// +--------------------------------+ +// +------------------+ | +// dsrecheaderty, |recheaderty,fielddata |calcfields | +// |moved to internal buffer header| | +// |<-field offsets are in ffieldinfos[].offset | +// |<-calcfield offsets are in fcalcfieldbufpositions| + + ifidsstatety = (ids_openpending,ids_fielddefsreceived,ids_remotedata, + ids_updating,ids_append,ids_sendpostresult,ids_postpending); + ifidsstatesty = set of ifidsstatety; +type + iifidscontroller = interface(iactivatorclient) + function getfielddefs: tfielddefs; + function getfieldinfos: fieldinfoarty; + procedure requestopendsreceived(const asequence: sequencety); + procedure fielddefsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); + procedure dsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); + procedure cancelconnection; + function getmodifiedfields: string; + procedure initmodifiedfields; + function setcurrentbuf(const abuf: pintrecordty): pintrecordty; + end; + + tififieldoptions = class(tsetarrayprop) + end; + + tpostechoevent = class(tobjectevent) + private + fmodifiedfields: string; + fbookmark: string; + public + constructor create(const amodifiedfields: string; const abookmark:string; + const dest: ievent); + end; + + changedataty = record + header: ptruintdataty; + data: record end; //array of byte for change flags + end; + changehashdataty = record + header: hashheaderty; + data: changedataty; + end; + pchangehashdataty = ^changehashdataty; + + tcurrentchangedlist = class(tptruinthashdatalist) + private + fnullmasksize: int32; + protected + function getrecordsize(): int32 override; + public + constructor create(const anullmasksize: integer); + procedure fieldchanged(const afield: tfield; const aindex: integer); + end; + + ifioptiondbty = (iod_autopost); + ifioptionsdbty = set of ifioptiondbty; + + tifidscontroller = class(tificontroller,ievent) + private +// fintf: iifidscontroller; + fremotedatachange: notifyeventty; + fpostsequence: sequencety; + fpostcode: postresultcodety; + fpostmessage: msestring; + frxbindings: integerarty; + ftxbindings: integerarty; + foptionsdb: ifioptionsdbty; + protected + fistate: ifidsstatesty; + fdscontroller: tdscontroller; + procedure requestfielddefsreceived(const asequence: sequencety); + procedure processfieldrecdata(const asequence: sequencety; + const adata: pfieldrecdataty); + procedure processdata(const adata: pifirecty; var adatapo: pchar); + override; + function getifireckinds: ifireckindsty; override; + procedure doremotedatachange; + function encodefielddefs: string; + procedure postrecord1(const akind: fieldreckindty; + const amodifiedfields: pbyte); + procedure receiveevent(const event: tobjectevent); + procedure sendchangedrecord(const aitem: pchangehashdataty); + procedure setowneractive(const avalue: boolean); override; + public + constructor create(const aowner: tdataset; const aintf: iifidscontroller); + destructor destroy; override; + function getfield(const aindex: integer): tfield; + function encoderecord(const aindex: integer; + const recpo: pintrecordty): string; + function encoderecords(const arecordcount: integer; + const abufs: pointerarty): string; + procedure sendpostresult(const asequence: sequencety; + const acode: postresultcodety; const amessage: msestring); + procedure sendchangedrecords(const alist: tcurrentchangedlist); + procedure post; + procedure delete; + procedure opened; + procedure closed; + procedure updaterxbindings; + published + property remotedatachange: notifyeventty read fremotedatachange + write fremotedatachange; + property optionsdb: ifioptionsdbty read foptionsdb write foptionsdb + default []; + end; + + tifidataset = class(tdataset,idscontroller,igetdscontroller,imselocate, + iifidscontroller,iifimodulelink,iactivatorclient) + private +// fifimodulelink: iifimodulelink; +// property ifimodulelink: iifimodulelink read fifimodulelink +// implements iifimodulelink; + //compiler crash +// fstrings: integerarty; +// fmsestrings: integerarty; + fcontroller: tdscontroller; + fificontroller: tifidscontroller; + fmsestringpositions: integerarty; + fansistringpositions: integerarty; + Ffieldinfos: fieldinfoarty; + frecordsize: integer; + fcalcrecordsize: integer; + fnullmasksize: integer; + fmodifiedfields: string; //same layout as nullmask + + frecno: integer; + fbrecordcount: integer; //always 1 if open + fcurrentbuf: pintrecordty; + fbufs: pointerarty; + fopen: boolean; + +// fremotedatachange: notifyeventty; +// foptions: ifirxoptionsty; + fupdating: integer; + procedure initmodifiedfields; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; virtual; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + + function intallocrecord: pintrecordty; + procedure finalizestrings(var header: recheaderty); + procedure finalizecalcstrings(var header: recheaderty); + procedure finalizechangedstrings(const tocompare: recheaderty; + var tofinalize: recheaderty); + procedure addrefstrings(var header: recheaderty); + procedure intfinalizerecord(const buffer: pintrecordty); + procedure intfreerecord(var buffer: pintrecordty); + procedure internalsetrecno(const avalue: integer); + function findrecord(arecordpo: pintrecordty): integer; reintroduce; + //returns index, -1 if not found + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + + procedure setificountroller(const avalue: tifidscontroller); + function getifistate: ifidsstatesty; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + protected + ffielddefsequence: sequencety; + procedure checkrecno(const avalue: integer); +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + + //iifidscontroller + function updatesortfield(const afield: tfield; + const adescend: boolean): boolean; + function getfielddefs: tfielddefs; + function getfieldinfos: fieldinfoarty; + procedure requestfielddefsreceived(const asequence: sequencety); virtual; + procedure requestopendsreceived(const asequence: sequencety); virtual; + procedure fielddefsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); virtual; + procedure dsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); virtual; + function getmodifiedfields: string; + function setcurrentbuf(const abuf: pintrecordty): pintrecordty; + + procedure decoderecord(var adata: pointer; const dest: pintrecordty); + function decoderecords(const adata: precdataty; out asize: integer): boolean; + + procedure notimplemented(const atext: string); + + procedure bindfields(const bind: boolean); + function AllocRecordBuffer: PChar; override; + procedure FreeRecordBuffer(var Buffer: PChar); override; + procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override; + function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override; + function GetRecord(Buffer: PChar; GetMode: TGetMode; + DoCheck: Boolean): TGetResult; override; + function GetRecordSize: Word; override; + function getrecno: integer; override; + procedure setrecno(value: longint); override; + function GetRecordCount: Longint; override; + + function getfieldbuffer(const afield: tfield; + out buffer: pointer; out datasize: integer): boolean; overload; + //read, true if not null + function getfieldbuffer(const afield: tfield; + const isnull: boolean; out datasize: integer): pointer; overload; + //write + function getmsestringdata(const sender: tmsestringfield; + out avalue: msestring): boolean; + procedure setmsestringdata(const sender: tmsestringfield; avalue: msestring); + + procedure dataevent(event: tdataevent; info: ptrint); override; + + procedure InternalCancel; override; + procedure internaledit; override; + procedure InternalRefresh; override; + + procedure InternalAddRecord(Buffer: Pointer; AAppend: Boolean); override; + procedure InternalClose; override; + procedure InternalDelete; override; + procedure InternalFirst; override; + procedure InternalGotoBookmark(ABookmark: Pointer); override; +// procedure InternalHandleException; override; + procedure InternalInitFieldDefs; override; + procedure InternalInitRecord(Buffer: PChar); override; + procedure InternalLast; override; + procedure InternalOpen; override; + procedure InternalPost; override; + procedure InternalSetToRecord(Buffer: PChar); override; + function IsCursorOpen: Boolean; override; + procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override; + procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override; + function getcanmodify: boolean; override; + + procedure cancelconnection; + procedure calcrecordsize; + + procedure setactive (const value : boolean);{ override;} reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure openlocal; + procedure internalinsert; override; + procedure begindisplaydata; + procedure enddisplaydata; + //iifimodulelink + procedure connectmodule(const sender: tcustommodulelink); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure beginupdate; + procedure endupdate; + + procedure Append; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; + reintroduce; +{ + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: string; const field: tfield; + const options: locateoptionsty = []): locateresultty; +} + function getfielddata(field: tfield; buffer: pointer; + nativeformat: boolean): boolean; override; + function getfielddata(field: tfield; buffer: pointer): boolean; override; + procedure setfielddata(field: tfield; buffer: pointer); override; + procedure setfielddata(field: tfield; buffer: pointer; + nativeformat: boolean); override; + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + function islastrecord: boolean; + property ifistate: ifidsstatesty read getifistate; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property ifi: tifidscontroller read fificontroller write setificountroller; + + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; + property BeforeScroll; + property AfterScroll; + property OnCalcFields; + property OnDeleteError; + property OnEditError; + property OnFilterRecord; + property OnNewRecord; + property OnPostError; + property onmodified; + property AutoCalcFields default false; + end; + + trxdataset = class(tifidataset,iifitxaction) + private + procedure inheritedinternalopen; override; + protected + procedure txactionfired(var adata: ansistring; var adatapo: pchar); + procedure fielddefsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); override; + procedure dsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); override; + published + property fielddefs; + end; + + ttxdataset = class(tifidataset) + private + protected + procedure requestopendsreceived(const asequence: sequencety); override; +// procedure inheritedinternalopen; override; + public + constructor create(aowner: tcomponent); override; + published + property fielddefs; + end; + + ttxsqlquery = class(tmsesqlquery,iifidscontroller,iactivatorclient) + private + fificontroller: tifidscontroller; + fmodifiedfields: string; //same layout as nullmask + fclientbefporeopen: tdatasetnotifyevent; + fclientbeforeopen: tdatasetnotifyevent; + fclientafteropen: tdatasetnotifyevent; + fcurrentchanged: tcurrentchangedlist; + procedure setificontroller(const avalue: tifidscontroller); + procedure initmodifiedfields; + protected + + procedure currentrecordupdated(const aindex: integer); + + procedure internalopen; override; + procedure internalclose; override; + procedure InternalPost; override; + function getfieldbuffer(const afield: tfield; + const aisnull: boolean; out datasize: integer): pointer; override; + procedure iactivatorclient.setactive = setcontrolleractive; + procedure iifidscontroller.setactive = setcontrolleractive; + //iifids + function getfielddefs: tfielddefs; + function getfieldinfos: fieldinfoarty; + procedure requestopendsreceived(const asequence: sequencety); + procedure fielddefsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); + procedure dsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); + function getmodifiedfields: string; + function setcurrentbuf(const abuf: pintrecordty): pintrecordty; + procedure aftercurrentset(const afield: tfield); override; + + procedure cancelconnection; + procedure internaledit; override; + procedure inheritedinternalinsert; override; + procedure inheritedinternaldelete; override; + procedure fixupcurrentset; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure currentbeginupdate; override; + procedure currentendupdate; override; +// procedure deccurrentupdate; override; + published + property ifi: tifidscontroller read fificontroller write setificontroller; + property clientbeforeopen: tdatasetnotifyevent read fclientbefporeopen + write fclientbeforeopen; + property clientafteropen: tdatasetnotifyevent read fclientafteropen + write fclientafteropen; + end; + + fdefitemty = record + datatype: tfieldtype; + size: integer; + name: ifinamety; + end; + pfdefitemty = ^fdefitemty; + fdefdataty = record + count: integer; + items: datarecty; //dummy + end; + pfdefdataty = ^fdefdataty; + +procedure loadtxdatagridfromdataset(const agrid: ttxdatagrid; + const asource: tdataset); +function decodefielddefs(const adata: pfdefdataty; + const fielddefs: tfielddefs; out asize: integer): boolean; + +implementation +uses + sysutils,msearrayutils,msedatalist, + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},msereal; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +type + tmsestringfield1 = class(tmsestringfield); + tdataset1 = class(tdataset); + +const + ifidskinds = [ik_requestfielddefs,ik_requestopen,ik_fielddefsdata, + ik_fieldrec,ik_dsdata,ik_postresult,ik_coldatachange, + ik_gridcommand]; + openflags = [ids_openpending,ids_fielddefsreceived,ids_append]; + +type + ttxdatagrid1 = class(ttxdatagrid); + +fieldtoificolprocty = procedure(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +fieldtoificolprocarty = array of fieldtoificolprocty; + +procedure storemsestringfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + acol.asmsestring[aindex]:= tmsestringfield(afield).asmsestring; +end; + +procedure storestringfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + acol.asmsestring[aindex]:= msestring(afield.asstring); +end; + +procedure storelongintfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + acol.asinteger[aindex]:= afield.aslongint; +end; + +procedure storelargintfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + acol.asint64[aindex]:= afield.aslargeint; +end; + +procedure storefloatfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + if afield.isnull then begin + acol.asreal[aindex]:= emptyreal; + end + else begin + acol.asreal[aindex]:= afield.asfloat; + end; +end; + +procedure storebcdfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + acol.ascurrency[aindex]:= afield.ascurrency; +end; + +procedure loadtxdatagridfromdataset(const agrid: ttxdatagrid; + const asource: tdataset); +type + fieldlinkinfoty = record + col: tifidatacol; + field: tfield; + proc: fieldtoificolprocty; + end; + fieldlinkinfoarty = array of fieldlinkinfoty; + +var + bm: string; + ar1: fieldlinkinfoarty; + int1,int2: integer; + str1: string; + bo1: boolean; +begin + setlength(ar1,agrid.datacols.count); //max + int2:= 0; + for int1:= 0 to high(ar1) do begin + bo1:= false; + with ar1[int2] do begin + col:= agrid.datacols[int1]; + str1:= col.name; + if str1 <> '' then begin + field:= asource.findfield(str1); + if field <> nil then begin + bo1:= true; + if field is tmsestringfield then begin + proc:= @storemsestringfield; + end + else begin + case field.datatype of + ftboolean,ftsmallint,ftinteger,ftword: begin + proc:= @storelongintfield; + end; + ftstring: begin + proc:= @storestringfield; + end; + ftbcd: begin + proc:= @storebcdfield; + end; + ftfloat,fttime,ftdate,ftdatetime: begin + proc:= @storefloatfield; + end; + else begin + bo1:= false; + end; + end; + end; + end; + end; + if bo1 then begin + inc(int2); + end; + end; + end; + setlength(ar1,int2); + + with ttxdatagrid1(agrid) do begin + asource.disablecontrols; + bm:= asource.bookmark; + try + beginupdate; + try + clear; + asource.first; + int2:= 0; + while not asource.eof do begin + agrid.rowcount:= int2+1; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + proc(col,int2,field); + end; + end; + asource.next; + inc(int2); + end; + finally + endupdate; + end; + finally + asource.bookmark:= bm; + asource.enablecontrols; + end; + end; +end; + +function decodefielddefs(const adata: pfdefdataty; + const fielddefs: tfielddefs; out asize: integer): boolean; +var + po1: pchar; + int1: integer; + str1: string; + datatype1: tfieldtype; + size1: integer; +begin + fielddefs.clear; + po1:= @adata^.items; + for int1:= 0 to adata^.count - 1 do begin + datatype1:= pfdefitemty(po1)^.datatype; + size1:= pfdefitemty(po1)^.size; + po1:= @pfdefitemty(po1)^.name; + inc(po1,ifinametostring(pifinamety(po1),str1)); + tfielddef.create(fielddefs,str1,datatype1,size1,false,int1+1); + end; + asize:= pchar(pointer(po1)) - pchar(pointer(adata)); + result:= true; +end; + +function decodepostresult(const adata: ppostresultdataty; + out acode: postresultcodety; + out amessage: msestring): boolean; +var + str1: string; +begin + result:= true; + with adata^ do begin + acode:= code; + ifinametostring(@message,str1); + amessage:= utf8tostringansi(str1); + end; +end; + +function encodefielddata(const ainfo: fieldinfoty; const headersize: integer): string; +begin + with ainfo,base,ext do begin + if field.isnull then begin + result:= encodeifinull(headersize); + end + else begin + case fieldtype of + ftinteger: begin + result:= encodeifidata(field.asinteger,headersize); + end; + ftlargeint: begin + result:= encodeifidata(field.aslargeint,headersize); + end; + ftfloat,ftcurrency: begin + {$ifdef FPC} + result:= encodeifidata(field.asfloat,headersize); + {$else} + result:= encodeifidatareal(field.asfloat,headersize); + {$endif} + end; + ftbcd: begin + {$ifdef FPC} + result:= encodeifidata(field.ascurrency,headersize); + {$else} + result:= encodeifidatareal(field.ascurrency,headersize); + {$endif} + end; + ftblob,ftgraphic,ftmemo: begin + result:= encodeifidata(field.asstring,headersize); + end; + ftstring: begin + if field is tmsestringfield then begin + result:= encodeifidata(tmsestringfield(field).asmsestring,headersize); + end + else begin + result:= encodeifidata(msestring(field.asstring),headersize); + end; + end; + else begin + result:=''; + exit; + end; + end; + end; + end; +end; + +{ tpostechoevent } + +constructor tpostechoevent.create(const amodifiedfields: string; + const abookmark: string; const dest: ievent); +begin + fmodifiedfields:= amodifiedfields; + setlength(fmodifiedfields,length(fmodifiedfields)); //unique + fbookmark:= abookmark; + inherited create(ek_mse,dest); +end; + +{ tifidscontroller } + +constructor tifidscontroller.create(const aowner: tdataset; + const aintf: iifidscontroller); +var + intf1: igetdscontroller; +begin +// fintf:= aintf; + if getcorbainterface(aowner,typeinfo(igetdscontroller),intf1) then begin + fdscontroller:= intf1.getcontroller; + end; +// ffieldoptions:= tififieldoptions.create(typeinfo(ififieldoptionsty)); + inherited create(aowner,aintf); +end; + +destructor tifidscontroller.destroy; +begin + inherited; +// ffieldoptions.free; +end; + +function tifidscontroller.encodefielddefs: string; +var + int1,int2: integer; + po1: pchar; + infos: fieldinfoarty; +begin + int2:= 0; + infos:= iifidscontroller(fintf).getfieldinfos; + for int1:= 0 to high(ftxbindings) do begin + int2:= int2 + length(infos[ftxbindings[int1]].ext.field.fieldname); + end; + setlength(result,sizeof(fdefdataty)+length(ftxbindings)*sizeof(fdefitemty)+ + int2*6); //max + with pfdefdataty(result)^ do begin + count:= length(ftxbindings); + po1:= @items; + end; + for int1:= 0 to high(ftxbindings) do begin + with infos[ftxbindings[int1]],base,ext do begin + pfdefitemty(po1)^.datatype:= fieldtype; + pfdefitemty(po1)^.size:= dbfieldsize; + po1:= @pfdefitemty(po1)^.name; + inc(po1,stringtoifiname(field.fieldname,pifinamety(po1))); + end; + end; + setlength(result,pchar(pointer(po1))-pchar(pointer(result))); +end; + +procedure tifidscontroller.postrecord1(const akind: fieldreckindty; + const amodifiedfields: pbyte); + function encodefdat(const ainfo: fieldinfoty; const aindex: integer): string; + begin + result:= encodefielddata(ainfo,sizeof(fielddataheaderty)); + if result <> '' then begin + with pfielddataty(result)^ do begin + header.index:= aindex; + end; + end; + end; + +var + int1,int2,int3: integer; + str1: string; + ar1: stringarty; + po1: pfieldrecdataty; + po2: pchar; +// modifiedfields: pbyte; + fieldinfos1: fieldinfoarty; + index1: integer; + +begin //postrecord + fieldinfos1:= iifidscontroller(fintf).getfieldinfos; + setlength(ar1,length(fieldinfos1)); //max + int2:= 0; + int3:= 0; + if akind <> frk_delete then begin +// modifiedfields:= pbyte(amodifiedfields); + for int1:= 0 to high(ftxbindings) do begin + index1:= ftxbindings[int1]; + if getfieldflag(amodifiedfields,index1) then begin + ar1[int2]:= encodefdat(fieldinfos1[index1],int1); + if ar1[int2] <> '' then begin + inc(int2); + end; + end; + end; + for int1:= 0 to int2 - 1 do begin + int3:= int3 + length(ar1[int1]); + end; + end; + inititemheader(str1,ik_fieldrec,0,int3+sizeof(fieldrecdataty), + pchar(po1)); + po1^.header.kind:= akind; + po1^.header.rowindex:= fdscontroller.recnozerobased; + po1^.header.count:= int2; + po2:= @po1^.data; + for int1:= 0 to int2 - 1 do begin + int3:= length(ar1[int1]); + move(ar1[int1][1],po2^,int3); + inc(po2,int3); + end; + if not (ids_sendpostresult in fistate) then begin + include(fistate,ids_postpending); + fpostsequence:= 0; + fpostcode:= pc_none; + if not senddataandwait(str1,fpostsequence) then begin + exclude(fistate,ids_postpending); + application.errormessage('Timeout.'); + iifidscontroller(fintf).cancelconnection; + end + else begin + if (fpostcode <> pc_ok) then begin + exclude(fistate,ids_postpending); + application.errormessage(fpostmessage); + tdataset(fowner).refresh; //todo: optimize + end; + end; + exclude(fistate,ids_postpending); + end + else begin + senddata(str1); + end; +end; + +procedure tifidscontroller.post; +begin + if fistate * [ids_remotedata,ids_updating] = [] then begin + if tdataset(fowner).state = dsinsert then begin + postrecord1(frk_insert,pbyte(iifidscontroller(fintf).getmodifiedfields)); + end + else begin + postrecord1(frk_edit,pbyte(iifidscontroller(fintf).getmodifiedfields)); + end; + exclude(fistate,ids_append); + iifidscontroller(fintf).initmodifiedfields; + end; +end; + +procedure tifidscontroller.sendchangedrecord(const aitem: pchangehashdataty); +begin + fdscontroller.recnozerobased:= aitem^.data.header.key; + postrecord1(frk_edit,@(aitem^.data.data)); +// postrecord1(frk_edit,pbyte(@aitem.data)); +end; + +procedure tifidscontroller.sendchangedrecords(const alist: tcurrentchangedlist); +//var +// int1: integer; +begin + if alist.count > 0 then begin + fdscontroller.beginupdate; + try + alist.iterate(hashiteratorprocty(@sendchangedrecord)); + finally + fdscontroller.endupdate; + end; + end; +end; + +procedure tifidscontroller.delete; +begin + if fistate * [ids_remotedata,ids_updating] = [] then begin + postrecord1(frk_delete,nil); + iifidscontroller(fintf).initmodifiedfields; + end; +end; + +procedure tifidscontroller.doremotedatachange; +begin + if checkcanevent(fowner,tmethod(fremotedatachange)) then begin + fremotedatachange(fowner); + end; +end; + +procedure tifidscontroller.requestfielddefsreceived(const asequence: sequencety); +var + str1,str2: ansistring; + po1: pchar; +begin + str2:= encodefielddefs; + inititemheader(str1,ik_fielddefsdata,asequence,length(str2),po1); + with pfielddefsdatadataty(po1)^ do begin + move(str2[1],data,length(str2)); + end; + senddata(str1); +end; + +procedure tifidscontroller.receiveevent(const event: tobjectevent); +var + bm1: ansistring; +begin + if (event.kind = ek_mse) and (event is tpostechoevent) then begin + with tdataset(fowner),tpostechoevent(event) do begin + bm1:= bookmark; + try + bookmark:= fbookmark; + postrecord1(frk_edit,pbyte(fmodifiedfields)); + except + end; + bookmark:= bm1; + end; + end; +end; + +function ifidatatofield(const datapo: pifidataty; const afield: tfield): integer; +var + str1: string; + mstr1: msestring; + integer1: integer; + int641: int64; + rea1: real; + cu1: currency; + realint1: realintty; +begin + result:= 0; + case datapo^.header.kind of + idk_null: begin + afield.clear; + result:= sizeof(ifidataty); + end; + idk_integer: begin + result:= decodeifidata(datapo,integer1); + afield.asinteger:= integer1; + end; + idk_int64: begin + result:= decodeifidata(datapo,int641); + afield.aslargeint:= int641; + end; + idk_real: begin + result:= decodeifidata(datapo,rea1); + afield.asfloat:= rea1; + end; + idk_realint: begin + result:= decodeifidata(datapo,realint1); + afield.asfloat:= realint1.rea; + end; + idk_currency: begin + result:= decodeifidata(datapo,cu1); + afield.ascurrency:= cu1; + end; + idk_bytes: begin + result:= decodeifidata(datapo,str1); + afield.asstring:= str1; + end; + idk_msestring: begin + result:= decodeifidata(datapo,mstr1); + afield.aswidestring:= mstr1; + { + if afield is tmsestringfield then begin + tmsestringfield(afield).asmsestring:= mstr1; + end + else begin + afield.asstring:= mstr1; + end; + } + end; + end; +end; + +procedure tifidscontroller.processfieldrecdata(const asequence: sequencety; + const adata: pfieldrecdataty); +var + int1: integer; + index1: integer; + po1: pchar; + str1: string; +// field1: tfield; + bo1: boolean; + bm: ansistring; + ar1: fieldinfoarty; +begin + with tdataset(fowner) do begin + if active then begin + try + checkbrowsemode; +// disablecontrols; + ar1:= iifidscontroller(fintf).getfieldinfos; + bm:= bookmark; + include(fistate,ids_remotedata); + try + if adata^.header.kind = frk_delete then begin + fdscontroller.recnozerobased:= adata^.header.rowindex; + delete; + end + else begin + bo1:= adata^.header.kind = frk_insert; + if bo1 then begin + if adata^.header.rowindex >= recordcount-1 then begin + append; + end + else begin + fdscontroller.recnozerobased:= adata^.header.rowindex; + insert; + end; + end + else begin + fdscontroller.recnozerobased:= adata^.header.rowindex; + edit; + end; + po1:= @adata^.data; + for int1:= 0 to adata^.header.count - 1 do begin + index1:= pfielddataty(po1)^.header.index; + if (index1 >= 0) and (index1 <= high(frxbindings)) then begin + with ar1[frxbindings[index1]],base,ext do begin + {$ifdef FPC} + inc(po1,sizeof(mseifi.fielddataty.header)); + {$else} + inc(po1,sizeof(mseifi.fielddataheaderty)); + {$endif} + inc(po1,ifidatatofield(pifidataty(po1),field)); + clearfieldflag(pbyte(iifidscontroller(fintf).getmodifiedfields),index1); + //reset changeflag + end; + end; + end; + iifidscontroller(fintf).initmodifiedfields; //init for postecho + post; + end; + if (irxo_postecho in foptions) and + (adata^.header.kind in [frk_insert,frk_edit]) then begin + str1:= iifidscontroller(fintf).getmodifiedfields; + if not isnullstring(str1) then begin + application.postevent(tpostechoevent.create(str1,bookmark, + ievent(self))); + end; + end; + doremotedatachange; + finally + try + bookmark:= bm; + except + end; + exclude(fistate,ids_remotedata); +// enablecontrols; + end; + if ids_sendpostresult in fistate then begin + sendpostresult(asequence,pc_ok,''); + end; + except + on e: exception do begin + if ids_sendpostresult in fistate then begin + sendpostresult(asequence,pc_error,msestring(e.message)); + end; + end; + end; + end + else begin + if ids_sendpostresult in fistate then begin + sendpostresult(asequence,pc_error,'Dataset inactive.'); + end; + end; + end; +end; + +procedure tifidscontroller.processdata(const adata: pifirecty; var adatapo: pchar); +var + int1: integer; + str1: string; + field1: tfield; + ckind1: gridcommandkindty; + source1,dest1,count1: integer; +begin + with adata^ do begin + case header.kind of + ik_requestfielddefs: begin + requestfielddefsreceived(header.sequence); + end; + ik_requestopen: begin + iifidscontroller(fintf).requestopendsreceived(header.sequence); + end; + ik_fielddefsdata: begin + iifidscontroller(fintf).fielddefsdatareceived(header.answersequence, + pfielddefsdatadataty(adatapo)); + end; + ik_dsdata: begin + iifidscontroller(fintf).dsdatareceived(header.answersequence,pfielddefsdatadataty(adatapo)); + end; + ik_postresult: begin + if (ids_postpending in fistate) and + (header.answersequence = fpostsequence) then begin + decodepostresult(ppostresultdataty(adatapo),fpostcode,fpostmessage); + end; + end; + ik_fieldrec: begin + processfieldrecdata(header.sequence,pfieldrecdataty(adatapo)); + end; + ik_coldatachange: begin + int1:= pcolitemdataty(adatapo)^.header.row; + ifinametostring(@pcolitemdataty(adatapo)^.header.name,str1); + adatapo:= pchar(@pcolitemdataty(adatapo)^.data)+length(str1); + with tdataset(fowner) do begin + field1:= findfield(str1); + if field1 <> nil then begin + include(fistate,ids_remotedata); + fdscontroller.recnozerobased:= int1; + try + if not (state in [dsedit,dsinsert]) then begin + edit; + end; + inc(adatapo,ifidatatofield(pifidataty(adatapo),field1)); + if iod_autopost in foptionsdb then begin + post; + end; + finally + exclude(fistate,ids_remotedata); + end; + end; + end; + end; + ik_gridcommand: begin + inc(adatapo,decodegridcommanddata(adatapo,ckind1,source1,dest1,count1)); + include(fistate,ids_remotedata); + try + with tdataset(fowner) do begin + case ckind1 of + gck_insertrow: begin + if dest1 >= recordcount then begin + append; + end + else begin + fdscontroller.recnozerobased:= dest1; + insert; + end; +// post; + end; + gck_deleterow: begin + fdscontroller.recnozerobased:= dest1; + delete; + end; + end; + end; + finally + exclude(fistate,ids_remotedata); + end; + end; + end; + end; +end; + +function tifidscontroller.encoderecord(const aindex: integer; + const recpo: pintrecordty): string; +var + str1: string; + mstr1: msestring; + +begin + if not getfieldflag(pbyte(@recpo^.header.fielddata.nullmask),aindex) then begin + result:= encodeifinull; + end + else begin + with iifidscontroller(fintf).getfieldinfos[aindex],base,ext do begin + case fieldtype of + ftinteger: begin + result:= encodeifidata(pinteger(pchar(pointer(recpo))+offset)^); + end; + ftlargeint: begin + result:= encodeifidata(plargeint(pchar(pointer(recpo))+offset)^); + end; + ftsmallint: begin + result:= encodeifidata(integer(psmallint(pchar(pointer(recpo))+offset)^)); + end; + ftword: begin + result:= encodeifidata(integer(pword(pchar(pointer(recpo))+offset)^)); + end; + ftboolean: begin + result:= encodeifidata(integer(pwordbool(pchar(pointer(recpo))+offset)^)); + end; + ftfloat,ftcurrency: begin + {$ifdef FPC} + result:= encodeifidata(pdouble(pchar(pointer(recpo))+offset)^); + {$else} + result:= encodeifidatareal(pdouble(pchar(pointer(recpo))+offset)^); + {$endif} + end; + ftbcd: begin + {$ifdef FPC} + result:= encodeifidata(pcurrency(pchar(pointer(recpo))+offset)^); + {$else} + result:= encodeifidatareal(pcurrency(pchar(pointer(recpo))+offset)^); + {$endif} + end; + ftmemo: begin + mstr1:= field.aswidestring; + result:= encodeifidata(mstr1); + end; + ftblob,ftgraphic: begin + str1:= field.asstring; + result:= encodeifidata(str1); + end; + ftstring: begin + result:= encodeifidata(pmsestring(pchar(pointer(recpo))+offset)^); + end; + else begin + result:= encodeifinull; +// result:=''; + exit; + end; + end; + end; + end; +end; + +function tifidscontroller.encoderecords(const arecordcount: integer; + const abufs: pointerarty): string; + //todo: optimize +var + ind1: integer; + + procedure put(const avalue: string; const alength: integer); + begin + if ind1 + alength > length(result) then begin + setlength(result,length(result)*2); + end; + move(avalue,result[ind1],alength); + inc(ind1,alength); + end; + +var + int1,int2: integer; + str1: string; + bufbefore: pintrecordty; + statebefore: tdatasetstate; + +begin + setlength(result,16); + ind1:= 1; + move(arecordcount,result[1],sizeof(arecordcount)); + inc(ind1,sizeof(arecordcount)); + bufbefore:= iifidscontroller(fintf).setcurrentbuf(nil); + statebefore:= tdataset1(fowner).settempstate(dscurvalue); + for int1:= 0 to arecordcount - 1 do begin + iifidscontroller(fintf).setcurrentbuf(abufs[int1]); + for int2:= 0 to high(ftxbindings) do begin + str1:= encoderecord(ftxbindings[int2],abufs[int1]); + if ind1 + length(str1) > length(result) then begin + setlength(result,length(result)*2+length(str1)); + end; + move(str1[1],result[ind1],length(str1)); + inc(ind1,length(str1)); + end; + end; + iifidscontroller(fintf).setcurrentbuf(bufbefore); + tdataset1(fowner).restorestate(statebefore); + setlength(result,ind1 - 1); +end; + +procedure tifidscontroller.sendpostresult(const asequence: sequencety; + const acode: postresultcodety; const amessage: msestring); +var + str1,str2: string; + po1: pointer; +begin + str2:= stringtoutf8ansi(amessage); + inititemheader(str1,ik_postresult,asequence, + length(str2),pchar(po1)); + with ppostresultdataty(po1)^ do begin + code:= acode; + stringtoifiname(str2,@message); + end; + senddata(str1); +end; +{ +procedure tifidscontroller.setfieldoptions(const avalue: tififieldoptions); +begin + ffieldoptions.assign(avalue); +end; +} +function tifidscontroller.getfield(const aindex: integer): tfield; +var + ar1: fieldinfoarty; +begin + result:= nil; + ar1:= iifidscontroller(fintf).getfieldinfos; + if aindex <= high(ar1) then begin + result:= ar1[aindex].ext.field; + end; +end; + +procedure tifidscontroller.opened; +var + int1,int2: integer; + ar1: fieldinfoarty; +begin + ar1:= iifidscontroller(fintf).getfieldinfos; + setlength(ftxbindings,length(ar1)); + int2:= 0; + for int1:= 0 to high(ftxbindings) do begin + with ar1[int1].ext do begin + if field <> nil then begin + with field do begin + if not (of_hidden in optionsfield) {and (recno >= 0)} then begin + ftxbindings[int2]:= int1; + inc(int2); + end; + end; + end; + end; + end; + setlength(ftxbindings,int2); + frxbindings:= ftxbindings; + { + with tdataset(fowner) do begin + setlength(fbindings,fields.count); + setlength(ffielddefindex,fields.count); + int2:= 0; + for int1:= 0 to high(fbindings) do begin + with fields[int1] do begin + if not (pfhidden in providerflags) and (index >= 0) then begin + fbindings[int2]:= field1.index; + ffielddefindex[int2]:= int1; + inc(int2); + end; + end; + setlength(fbindings,int2); + setlength(ffielddefindex,int2); + end; + } +end; + +function tifidscontroller.getifireckinds: ifireckindsty; +begin + result:= ifidskinds; +end; + +procedure tifidscontroller.updaterxbindings; +var + int1,int2: integer; + field1: tfield; +begin + with tdataset(fowner) do begin + setlength(frxbindings,fielddefs.count); + int2:= 0; + for int1:= 0 to high(frxbindings) do begin + field1:= findfield(fielddefs[int1].name); + if (field1 <> nil) and (field1.index >= 0) then begin + frxbindings[int2]:= field1.index; + inc(int2); + end; + end; + setlength(frxbindings,int2); + ftxbindings:= frxbindings; + end; +end; + +procedure tifidscontroller.closed; +begin + frxbindings:= nil; + ftxbindings:= nil; +end; + +procedure tifidscontroller.setowneractive(const avalue: boolean); +begin + tdataset(fowner).active:= avalue; +end; + +{ tifidataset } + +constructor tifidataset.create(aowner: tcomponent); +begin +// foptions:= defaultifidsoptions; + frecno:= -1; +// fdefaulttimeout:= defaultifidstimeout; +// fobjectlinker:= tobjectlinker.create(ievent(self), +// {$ifdef FPC}@{$endif}objectevent); +// setunidirectional(true); + inherited; + bookmarksize := sizeof(bufbookmarkty); + fcontroller:= tdscontroller.create(self,idscontroller(self),-1,false); + fificontroller:= tifidscontroller.create(self,iifidscontroller(self)); +// fifimoduleink:= iifimodulelink(fificontroller); +end; + +destructor tifidataset.destroy; +begin + fcontroller.free; + inherited; + fificontroller.free; +// fobjectlinker.free; +end; + +procedure tifidataset.connectmodule(const sender: tcustommodulelink); +begin + fificontroller.connectmodule(sender); +end; + +function tifidataset.intallocrecord: pintrecordty; +begin + result:= allocmem(frecordsize+intheadersize); + fillchar(result^,frecordsize+intheadersize,0); +end; + +procedure tifidataset.finalizestrings(var header: recheaderty); +var + int1: integer; +begin + for int1:= high(fmsestringpositions) downto 0 do begin + pmsestring(pointer(pchar(@header)+fmsestringpositions[int1]))^:= ''; + end; + for int1:= high(fansistringpositions) downto 0 do begin + pansistring(pointer(pchar(@header)+fansistringpositions[int1]))^:= ''; + end; +end; + +procedure tifidataset.finalizecalcstrings(var header: recheaderty); +begin +end; + +procedure tifidataset.finalizechangedstrings(const tocompare: recheaderty; + var tofinalize: recheaderty); +var + int1: integer; +begin + for int1:= high(fmsestringpositions) downto 0 do begin + if ppointer(pointer(pchar(@tocompare)+fmsestringpositions[int1]))^ <> + ppointer(pointer(pchar(@tofinalize)+fmsestringpositions[int1]))^ then begin + pmsestring(pointer(pchar(@tofinalize)+fmsestringpositions[int1]))^:= ''; + end; + end; + for int1:= high(fansistringpositions) downto 0 do begin + if ppointer(pointer(pchar(@tocompare)+fansistringpositions[int1]))^ <> + ppointer(pointer(pchar(@tofinalize)+fansistringpositions[int1]))^ then begin + pansistring(pointer(pchar(@tofinalize)+fansistringpositions[int1]))^:= ''; + end; + end; +end; + +procedure tifidataset.addrefstrings(var header: recheaderty); +var + int1: integer; +begin + for int1:= high(fmsestringpositions) downto 0 do begin + stringaddref(pmsestring(pointer(pchar(@header)+fmsestringpositions[int1]))^); + end; + for int1:= high(fansistringpositions) downto 0 do begin + stringaddref(pansistring(pointer(pchar(@header)+fansistringpositions[int1]))^); + end; +end; + +procedure tifidataset.intfinalizerecord(const buffer: pintrecordty); +begin +// freeblobs(buffer^.header.blobinfo); + finalizestrings(buffer^.header); +end; + +procedure tifidataset.intfreerecord(var buffer: pintrecordty); +begin + if buffer <> nil then begin + intfinalizerecord(buffer); + freemem(buffer); + buffer:= nil; + end; +end; + +function tifidataset.AllocRecordBuffer: PChar; +begin + result := allocmem(dsheadersize+fcalcrecordsize); + initrecord(result); +end; + +procedure tifidataset.FreeRecordBuffer(var Buffer: PChar); +begin + if buffer <> nil then begin + reallocmem(buffer,0); + end; +end; + +procedure tifidataset.GetBookmarkData(Buffer: PChar; Data: Pointer); +begin + move(pdsrecordty(buffer)^.dsheader.bookmark,data^,sizeof(bookmarkdataty)); +end; + +function tifidataset.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; +begin + result:= pdsrecordty(buffer)^.dsheader.bookmark.flag; +end; +{ +function tifidataset.GetDataSource: TDataSource; +begin +end; +} +procedure tifidataset.internalsetrecno(const avalue: integer); +begin + frecno:= avalue; + if (avalue < 0) or (avalue >= fbrecordcount) then begin + fcurrentbuf:= nil; + end + else begin + fcurrentbuf:= fbufs[avalue]; + end; +end; + +function tifidataset.GetRecord(Buffer: PChar; GetMode: TGetMode; + DoCheck: Boolean): TGetResult; +begin + result:= grok; + case getmode of + gmprior: begin + if frecno <= 0 then begin + result := grbof; + end + else begin + internalsetrecno(frecno-1); + end; + end; + gmcurrent: begin + if (frecno < 0) or (frecno >= fbrecordcount) or (fcurrentbuf = nil) then begin + result := grerror; + end; + end; + gmnext: begin + if frecno >= fbrecordcount - 1 then begin + result:= greof; + end + else begin + internalsetrecno(frecno+1); + end; + end; + end; + if result = grok then begin + with pdsrecordty(buffer)^ do begin + with dsheader.bookmark do begin + data.recno:= frecno; + data.recordpo:= fcurrentbuf; + flag:= bfcurrent; + end; + move(fcurrentbuf^.header,header,frecordsize); + { + getcalcfields(buffer); + if filtered then begin + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + dofilterrecord(acceptable); + finally + restorestate(state1); + end; + end; + if (getmode = gmcurrent) and not acceptable then begin + result:= grerror; + end; + } + end; + end; +end; + +function tifidataset.GetRecordSize: Word; +begin + result:= frecordsize; +end; + +procedure tifidataset.bindfields(const bind: boolean); +var + int1: integer; + field1: tfield; + int2: integer; + fielddef1: tfielddef; +begin + fielddef1:= nil; + for int1:= fields.count - 1 downto 0 do begin + field1:= fields[int1]; + if bind then begin + if field1.fieldkind = fkdata then begin + fielddef1:= tfielddef(fielddefs.find(field1.fieldname)); + //needed for FPC 2_2 + if fielddef1 <> nil then begin + field1.fieldname:= fielddef1.name; + //get exact name for quoting in update statements + end; + end + else begin + fielddef1:= nil; + end; + end; + if field1 is tmsestringfield then begin + int2:= 0; + if bind then begin + int2:= field1.size; + if fielddef1 <> nil then begin + int2:= fielddef1.size; + end; + tmsestringfield1(field1).setismsestring({$ifdef FPC}@{$endif}getmsestringdata, + {$ifdef FPC}@{$endif}setmsestringdata,int2,false); + end + else begin + tmsestringfield1(field1).setismsestring(nil,nil,int2,false); + end; + end + else begin + if field1 is tmseblobfield then begin + { + if bind then begin + tmseblobfield1(field1).fgetblobid:= @getfieldblobid; + end + else begin + tmseblobfield1(field1).fgetblobid:= nil; + end; + } + end; + end; + end; + inherited bindfields(bind); +end; + +function tifidataset.getfieldbuffer(const afield: tfield; out buffer: pointer; + out datasize: integer): boolean; + //read, true if not null +var + int1: integer; +begin + result:= false; + buffer:= nil; + if not active then begin + exit; + end; + int1:= afield.fieldno - 1; + case ord(state) of + ord(dscalcfields): begin +// buffer:= @pdsrecordty(calcbuffer)^.header; + end; + dscheckfilter: begin +// buffer:= @fcheckfilterbuffer^.header; + end; + ord(dsfilter): begin +// buffer:= @ffilterbuffer^.header; + end; + ord(dscurvalue): begin +// buffer:= @fcurrentbuf^.header; + end; + else begin + buffer:= @pdsrecordty(activebuffer)^.header; + { + if bs_internalcalc in fbstate then begin + if int1 < 0 then begin//calc field + buffer:= @pdsrecordty(activebuffer)^.header; + //values invalid! + end + else begin + buffer:= @fcurrentbuf^.header; + end; + end + else begin + if bs_recapplying in fbstate then begin + buffer:= @fnewvaluebuffer^.header; + end + else begin + buffer:= @pdsrecordty(activebuffer)^.header; + end; + end; + } + end; + end; + if int1 >= 0 then begin // data field + result:= false; + { + if state = dsoldvalue then begin + if getrecordupdatebuffer then begin + buffer:= fupdatebuffer[fcurrentupdatebuffer].oldvalues; + if buffer <> nil then begin + buffer:= @pintrecordty(buffer)^.header; + end; + end + else begin + buffer:= @fcurrentbuf^.header //there is no old value available + end; + end; + } + if buffer <> nil then begin + result:= getfieldflag(@precheaderty(buffer)^.fielddata.nullmask,int1); + inc(pchar(buffer),ffieldinfos[int1].base.offset{ffieldbufpositions[int1]}); + datasize:= ffieldinfos[int1].base.size{ffieldsizes[int1]}; + end + else begin + datasize:= 0; + end; + end + else begin + int1:= -2 - int1; + if int1 >= 0 then begin //calc field + { + result:= not getfieldisnull(pbyte(buffer+frecordsize),int1); + inc(buffer,fcalcfieldbufpositions[int1]); + datasize:= fcalcfieldsizes[int1]; + } + end + else begin + buffer:= nil; + datasize:= 0; + end; + end; +end; + +function tifidataset.getfieldbuffer(const afield: tfield; const isnull: boolean; + out datasize: integer): pointer; + //write +var + int1: integer; +begin + result:= nil; + if not ((state in dswritemodes - [dsinternalcalc,dscalcfields]) or + (afield.fieldkind = fkinternalcalc) and + (state = dsinternalcalc) or + (afield.fieldkind = fkcalculated) and + (state = dscalcfields)) then begin + databaseerrorfmt(snotediting,[name],self); + end; + int1:= afield.fieldno-1; + case state of + dscalcfields: begin +// result:= @pdsrecordty(calcbuffer)^.header; + end; + dsfilter: begin +// result:= @ffilterbuffer^.header; + end; + else begin + result:= @pdsrecordty(activebuffer)^.header; + { + if bs_internalcalc in fbstate then begin + if int1 < 0 then begin//calc field + result:= @pdsrecordty(activebuffer)^.header; + //values invalid! + end + else begin + result:= @fcurrentbuf^.header; + end; + end + else begin + if bs_recapplying in fbstate then begin + result:= @fnewvaluebuffer^.header; + end + else begin + result:= @pdsrecordty(activebuffer)^.header; + end; + end; + } + end; + end; + if int1 >= 0 then begin // data field + setfieldflag(pointer(fmodifiedfields),int1); //modified + if isnull then begin + clearfieldflag(@precheaderty(result)^.fielddata.nullmask,int1); + end + else begin + setfieldflag(@precheaderty(result)^.fielddata.nullmask,int1); + end; + inc(pchar(result),ffieldinfos[int1].base.offset{ffieldbufpositions[int1]}); + datasize:= ffieldinfos[int1].base.size{ffieldsizes[int1]}; + end + else begin + int1:= -2 - int1; + result:= nil; + datasize:= 0; + { + if int1 >= 0 then begin //calc field + if isnull then begin + setfieldisnull(pbyte(result+frecordsize),int1); + end + else begin + unsetfieldisnull(pbyte(result+frecordsize),int1); + end; + inc(result,fcalcfieldbufpositions[int1]); + datasize:= fcalcfieldsizes[int1]; + end + else begin + result:= nil; + datasize:= 0; + end; + } + end; +end; + +function tifidataset.getmsestringdata(const sender: tmsestringfield; + out avalue: msestring): boolean; +var + po1: pointer; + int1: integer; +begin + result:= getfieldbuffer(sender,po1,int1); + if result then begin + avalue:= msestring(po1^); + end + else begin + avalue:= ''; + end; +end; + +procedure tifidataset.setmsestringdata(const sender: tmsestringfield; + avalue: msestring); +var + po1: pointer; + int1: integer; +begin + po1:= getfieldbuffer(sender,false,int1); + msestring(po1^):= avalue; + if (sender.characterlength > 0) and + (length(avalue) > sender.characterlength) then begin + setlength(msestring(po1^),sender.characterlength); + end; + if (sender.fieldno > 0) and not + (state in [dscalcfields,dsinternalcalc,{dsfilter,}dsnewvalue]) then begin + dataevent(defieldchange,ptrint(sender)); + end; +end; + +function tifidataset.getfielddata(field: tfield; buffer: pointer; + nativeformat: boolean): boolean; +begin + result:= getfielddata(field,buffer); +end; + +function tifidataset.getfielddata(field: tfield; buffer: pointer): boolean; +var + po1: pointer; + datasize: integer; +begin + result:= getfieldbuffer(field,po1,datasize); + if (buffer <> nil) and result then begin + move(po1^,buffer^,datasize); + end; +end; + +procedure tifidataset.setfielddata(field: tfield; buffer: pointer; + nativeformat: boolean); +begin + setfielddata(field,buffer); +end; + +procedure tifidataset.setfielddata(field: tfield; buffer: pointer); +var + po1: pointer; + datasize: integer; +begin + po1:= getfieldbuffer(field,buffer = nil,datasize); + if buffer <> nil then begin + move(buffer^,po1^,datasize); + end; + if (field.fieldno > 0) and not + (state in [dscalcfields,dsinternalcalc,{dsfilter,}dsnewvalue]) then begin + dataevent(defieldchange, ptrint(field)); + end; +end; + +procedure tifidataset.initmodifiedfields; +begin + setlength(fmodifiedfields,fnullmasksize); + fillchar(pointer(fmodifiedfields)^,fnullmasksize,#0); +end; + +procedure tifidataset.InternalCancel; +begin + with pdsrecordty(activebuffer)^,header do begin + finalizestrings(header); + end; + exclude(fificontroller.fistate,ids_append); +end; + +procedure tifidataset.internaledit; +begin + initmodifiedfields; + addrefstrings(pdsrecordty(activebuffer)^.header); + inherited; +end; + +procedure tifidataset.InternalPost; +begin + with pdsrecordty(activebuffer)^ do begin + if state = dsinsert then begin + fcurrentbuf:= intallocrecord; + dsheader.bookmark.data.recordpo:= fcurrentbuf; + dsheader.bookmark.data.recno:= frecno; + if fbrecordcount >= high(fbufs) then begin + setlength(fbufs,(high(fbufs)+7)*2); + end; + move(fbufs[frecno],fbufs[frecno+1],(fbrecordcount-frecno)*sizeof(pointer)); + fbufs[frecno]:= fcurrentbuf; + inc(fbrecordcount); + end + else begin + finalizestrings(fcurrentbuf^.header); + end; + + move(header,fcurrentbuf^.header,frecordsize); //get new field values +// fillchar(pointer(fmodifiedfields)^,fnullmasksize,0); + end; + fificontroller.post; +end; + +procedure tifidataset.InternalAddRecord(Buffer: Pointer; AAppend: Boolean); +begin + notimplemented('Add record'); +end; + +procedure tifidataset.InternalFirst; +begin + internalsetrecno(-1); +end; + +function tifidataset.findrecord(arecordpo: pintrecordty): integer; +var + int1: integer; +begin + if arecordpo = fcurrentbuf then begin + result:= frecno; + end + else begin + for int1:= frecno to fbrecordcount - 1 do begin + if fbufs[int1] = arecordpo then begin + result:= int1; + exit; + end; + end; + for int1:= frecno downto 0 do begin + if fbufs[int1] = arecordpo then begin + result:= int1; + exit; + end; + end; + result:= -1; + end; +end; + +procedure tifidataset.InternalGotoBookmark(ABookmark: Pointer); +var + int1: integer; + int2: integer; +begin + if abookmark <> nil then begin + with pbufbookmarkty(abookmark)^.data do begin + if (recno >= fbrecordcount) or (recno < 0) then begin + databaseerror('Invalid bookmark recno: '+inttostr(recno)+'.'); + end; + int1:= recno; + if recordpo <> nil then begin + int2:= -1; + for int1:= frecno to high(fbufs) do begin + if fbufs[int1] = recordpo then begin + int2:= int1; + break; + end; + end; + for int1:= frecno downto 0 do begin + if fbufs[int1] = recordpo then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + databaseerror('Invalid bookmarkdata.'); + end; + end + else begin + int2:= recno; + end; + internalsetrecno(int2); + end; + end; +end; +{ +procedure tifidataset.InternalHandleException; +begin +end; +} +procedure tifidataset.InternalInitFieldDefs; +begin + //dummy +end; + +procedure tifidataset.InternalInitRecord(Buffer: PChar); +begin + with pdsrecordty(buffer)^ do begin + fillchar(header,fcalcrecordsize, #0); + end; +end; + +procedure tifidataset.InternalLast; +begin + internalsetrecno(fbrecordcount) +end; + +procedure tifidataset.InternalSetToRecord(Buffer: PChar); +begin + internalsetrecno(pdsrecordty(buffer)^.dsheader.bookmark.data.recno); +end; + +function tifidataset.IsCursorOpen: Boolean; +begin + result:= fopen; +end; + +procedure tifidataset.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); +begin + pdsrecordty(buffer)^.dsheader.bookmark.flag:= value; +end; + +procedure tifidataset.SetBookmarkData(Buffer: PChar; Data: Pointer); +begin + move(data^,pdsrecordty(buffer)^.dsheader.bookmark,sizeof(bookmarkdataty)); +end; + +procedure tifidataset.notimplemented(const atext: string); +begin + raise exception.create(name+': '+atext+' not implemented.'); +end; + +procedure tifidataset.calcrecordsize; +var + int1,int2,int3: integer; + field1: tfield; +begin + int3:= 0; + fmsestringpositions:= nil; + fansistringpositions:= nil; + int1:= fielddefs.count; +// frecordsize:= 0; + frecordsize:= sizeof(blobinfoarty); + fnullmasksize:= (int1+7) div 8; + inc(frecordsize,fnullmasksize); + alignfieldpos(frecordsize); + setlength(ffieldinfos,int1); + for int2:= 0 to int1 - 1 do begin + with fielddefs[int2] do begin + field1:= fields.findfield(name); + if (field1 <> nil) and (field1.fieldkind = fkdata) then begin + case datatype of + ftstring,ftfixedchar: begin + additem(fmsestringpositions,frecordsize); + int3:= sizeof(msestring); + end; + ftsmallint,ftinteger,ftword: begin + int3:= sizeof(longint); + end; + ftboolean: begin + int3:= sizeof(wordbool); + end; + ftbcd: begin + int3:= sizeof(currency); + end; + ftfloat,ftcurrency: begin + int3:= sizeof(double); + end; + ftlargeint: begin + int3:= sizeof(largeint); + end; + fttime,ftdate,ftdatetime: begin + int3:= sizeof(tdatetime); + end; + ftblob,ftmemo: begin + additem(fansistringpositions,frecordsize); + int3:= sizeof(string); + end; + else begin + int3:= 0; + end; + end; + end; + with ffieldinfos[int2],base,ext do begin + offset:= frecordsize; + inc(frecordsize,int3); + alignfieldpos(frecordsize); + size:= int3; + fieldtype:= datatype; + field:= field1; + end; + end; + end; + fcalcrecordsize:= frecordsize; //no calcfields +end; + +function tifidataset.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tifidataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tifidataset.locate(const key: string; + const field: tfield; const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +procedure tifidataset.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tifidataset.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tifidataset.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tifidataset.cancelconnection; +begin + fificontroller.fistate:= fificontroller.fistate - openflags; +end; + +procedure tifidataset.setactive(const value: boolean); +begin + if not value then begin + cancelconnection; + end; + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tifidataset.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tifidataset.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tifidataset.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tifidataset.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tifidataset.inheritedcancel; +begin + inherited cancel; +end; + +procedure tifidataset.cancel; +begin + fcontroller.cancel; +end; + +function tifidataset.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tifidataset.inheritedinternalinsert; +begin + initmodifiedfields; + with pdsrecordty(activebuffer)^.dsheader.bookmark.data do begin + recordpo:= nil; + recno:= frecno; + end; + inherited internalinsert; +end; + +procedure tifidataset.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tifidataset.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tifidataset.inheritedinternalopen; +begin + if defaultfields then begin + createfields; + end; + bindfields(true); + calcrecordsize; + fopen:= true; + fificontroller.opened; +end; + +procedure tifidataset.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tifidataset.inheritedpost; +begin + inherited post; +end; + +procedure tifidataset.post; +begin + fcontroller.post; +end; + +procedure tifidataset.inheritedinternaldelete; +begin + if state = dsedit then begin + internalcancel; + end; + intfreerecord(fcurrentbuf); + dec(fbrecordcount); + move(fbufs[frecno+1],fbufs[frecno],(fbrecordcount-frecno)*sizeof(pointer)); + fificontroller.delete; +end; + +procedure tifidataset.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tifidataset.openlocal; +begin + inheritedinternalopen; +end; + +procedure tifidataset.inheritedinternalclose; +var + int1: integer; +begin + cancelconnection; + fopen:= false; + bindfields(false); + if defaultfields then begin + destroyfields; + end; + for int1:= 0 to fbrecordcount - 1 do begin + intfreerecord(pintrecordty(fbufs[int1])); + end; + frecno:= -1; + fcurrentbuf:= nil; + fbrecordcount:= 0; +// inherited internalclose; +end; + +procedure tifidataset.internalclose; +begin + fificontroller.closed; + fcontroller.internalclose; +end; + +function tifidataset.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tifidataset.getnumboolean: boolean; +begin + result:= true; +end; + +function tifidataset.getfloatdate: boolean; +begin + result:= false; +end; + +function tifidataset.getint64currency: boolean; +begin + result:= false; +end; + +function tifidataset.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; +{ +procedure tifidataset.setchannel(const avalue: tcustomiochannel); +begin + fobjectlinker.setlinkedvar(ievent(self),avalue,fchannel); +end; + +procedure tifidataset.link(const source: iobjectlink; const dest: iobjectlink; + valuepo: pointer = nil; ainterfacetype: pointer = nil; + once: boolean = false); +begin + fobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tifidataset.unlink(const source: iobjectlink; const dest: iobjectlink; + valuepo: pointer = nil); +begin + fobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tifidataset.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + fobjectlinker.objevent(sender,event); +end; + +function tifidataset.getinstance: tobject; +begin + result:= self; +end; + +procedure tifidataset.objectevent(const sender: tobject; + const event: objecteventty); +var + po1: pifirecty; +begin + if (event = oe_dataready) and (sender = fchannel) then begin + if (length(fchannel.rxdata) >= sizeof(ifiheaderty)) then begin + with fchannel do begin + po1:= pifirecty(rxdata); + with po1^.header do begin + if size = length(rxdata) then begin + processdata(po1); + end; + end; + end; + end; + end; +end; + +procedure tifidataset.receiveevent(const event: tobjectevent); +begin + //dummy +end; +} +procedure tifidataset.requestfielddefsreceived(const asequence: sequencety); +begin + //dummy +end; + +procedure tifidataset.requestopendsreceived(const asequence: sequencety); +begin + //dummy +end; + +procedure tifidataset.fielddefsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +begin + //dummy +end; + +procedure tifidataset.dsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +begin + //dummy +end; + +{ +procedure tifidataset.waitforanswer(const asequence: sequencety; + waitus: integer = 0); +begin + if waitus = 0 then begin + waitus:= fdefaulttimeout; + end; + fchannel.waitforanswer(asequence,fdefaulttimeout); +end; +} +{ +procedure tifidataset.fieldrecdatareceived(const adata: pfieldrecdataty); +var + int1: integer; + index1: integer; + po1: pchar; + mstr1: msestring; + int641: int64; + rea1: real; + cu1: currency; + str1: string; + field1: tfield; + bo1: boolean; + bm: string; + +begin + if active then begin + checkbrowsemode; + disablecontrols; + include(fificontroller.fistate,ids_remotedata); + bm:= bookmark; + try + if adata^.kind = frk_delete then begin + recno:= adata^.recno; + delete; + end + else begin + bo1:= adata^.kind = frk_insert; + if bo1 then begin + if adata^.recno >= recordcount then begin + append; + end + else begin + recno:= adata^.recno; + insert; + end; + end + else begin + recno:= adata^.recno; + edit; + end; + po1:= @adata^.data; + for int1:= 0 to adata^.count - 1 do begin + index1:= pfielddataty(po1)^.header.index; + if (index1 >= 0) and (index1 <= high(fbindings)) and + (fbindings[index1] >= 0) then begin + field1:= fields[fbindings[index1]]; + inc(po1,sizeof(mseifi.fielddataty.header)); + case pifidataty(po1)^.header.kind of + idk_null: begin + field1.clear; + inc(po1,sizeof(ifidataty)); + end; + idk_int64: begin + inc(po1,decodeifidata(pifidataty(po1),int641)); + field1.aslargeint:= int641; + end; + idk_real: begin + inc(po1,decodeifidata(pifidataty(po1),rea1)); + field1.asfloat:= rea1; + end; + idk_currency: begin + inc(po1,decodeifidata(pifidataty(po1),cu1)); + field1.ascurrency:= cu1; + end; + idk_bytes: begin + inc(po1,decodeifidata(pifidataty(po1),str1)); + field1.asstring:= str1; + end; + idk_msestring: begin + inc(po1,decodeifidata(pifidataty(po1),mstr1)); + if field1 is tmsestringfield then begin + tmsestringfield(field1).asmsestring:= mstr1; + end + else begin + field1.asstring:= mstr1; + end; + end; + end; + end; + setfieldisnull(pointer(fmodifiedfields),index1); //reset changeflag + end; + post; + end; + fificontroller.doremotedatachange; + try + bookmark:= bm; + except + end; + finally + exclude(fificontroller.fistate,ids_remotedata); + enablecontrols; + end; + end; +end; +} +procedure tifidataset.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + if (event = defieldchange) and + (fificontroller.fistate * [ids_remotedata,ids_updating] = []) then begin + if TField(Info).FieldKind in [fkData,fkInternalCalc] then begin + SetModified(True); + end; + exit; + end; + inherited dataevent(event,info); +end; + +procedure tifidataset.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +procedure tifidataset.Append; +begin + include(fificontroller.fistate,ids_append); + inherited; +end; + +procedure tifidataset.checkrecno(const avalue: integer); +begin + if (avalue > recordcount) or (avalue < 1) then begin + databaseerror(snosuchrecord,self); + end; +end; + +function tifidataset.getrecno: integer; +begin + result:= 0; + if activebuffer <> nil then begin + with pdsrecordty(activebuffer)^.dsheader.bookmark do begin + if state = dsinsert then begin + if (ids_append in fificontroller.fistate) or (fbrecordcount = 0) then begin + result:= fbrecordcount + 1; + end + else begin + result:= data.recno + 1; + end; + end + else begin + if fbrecordcount > 0 then begin + result:= data.recno + 1; + end; + end; + end; + end; +end; + +procedure tifidataset.setrecno(value: longint); +var + bm: bufbookmarkty; +begin + checkbrowsemode; + checkrecno(value); + bm.data.recordpo:= nil; + bm.data.recno:= value-1; + gotobookmark(@bm); +end; + +function tifidataset.GetRecordCount: Longint; +begin + result:= fbrecordcount; +end; + +procedure tifidataset.decoderecord(var adata: pointer; const dest: pintrecordty); +var + integer1: integer; + int641: int64; + double1: double; + cur1: currency; + mstr1: msestring; + str1: string; + int1: integer; +begin + for int1:= 0 to high(fificontroller.frxbindings) do begin +// if fificontroller.fbindings[int1] >= 0 then begin + if pifidataty(adata)^.header.kind <> idk_null then begin + setfieldflag(pbyte(@dest^.header.fielddata.nullmask), + fificontroller.frxbindings[int1]); + with ffieldinfos[fificontroller.frxbindings[int1]].base do begin + case fieldtype of + ftinteger: begin + inc(pchar(adata),decodeifidata(pifidataty(adata),integer1)); + pinteger(pchar(pointer(dest))+offset)^:= integer1; + end; + ftlargeint: begin + inc(pchar(adata),decodeifidata(pifidataty(adata),int641)); + plargeint(pchar(pointer(dest))+offset)^:= int641; + end; + ftfloat,ftcurrency: begin + {$ifdef FPC} + inc(pchar(adata),decodeifidata(pifidataty(adata),double1)); + {$else} + inc(pchar(adata),decodeifidatareal(pifidataty(adata),double1)); + {$endif} + pdouble(pchar(pointer(dest))+offset)^:= double1; + end; + ftbcd: begin + inc(pchar(adata),decodeifidata(pifidataty(adata),cur1)); + pcurrency(pchar(pointer(dest))+offset)^:= cur1; + end; + ftblob,ftgraphic,ftmemo: begin + inc(pchar(adata),decodeifidata(pifidataty(adata),str1)); + pstring(pchar(pointer(dest))+offset)^:= str1; + end; + ftstring: begin + inc(pchar(adata),decodeifidata(pifidataty(adata),mstr1)); + pmsestring(pchar(pointer(dest))+offset)^:= mstr1; + end; + end; + end; + end + else begin + inc(pchar(adata),skipifidata(pifidataty(adata))); + end; + end; +end; + +function tifidataset.decoderecords(const adata: precdataty; + out asize: integer): boolean; +var + int1: integer; + po1: pointer; +begin + result:= true; + fbrecordcount:= adata^.header.count; + setlength(fbufs,fbrecordcount); + po1:= @adata^.data; + for int1:= 0 to high(fbufs) do begin + fbufs[int1]:= intallocrecord; + decoderecord(po1,fbufs[int1]); + end; + asize:= pchar(po1) - pchar(pointer(adata)); +end; + +function tifidataset.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tifidataset.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tifidataset.endfilteredit; +begin + //dummy +end; + +procedure tifidataset.clearfilter; +begin + //dumm +end; + +procedure tifidataset.beginupdate; +begin + inc(fupdating); + include(fificontroller.fistate,ids_updating); +end; + +procedure tifidataset.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + exclude(fificontroller.fistate,ids_updating); + end; +end; + +procedure tifidataset.setificountroller(const avalue: tifidscontroller); +begin + fificontroller.assign(avalue); +end; + +function tifidataset.getfielddefs: tfielddefs; +begin + result:= fielddefs; +end; +{ +procedure tifidataset.doidleapplyupdates; +begin + //dummy +end; +} +{ +function tifidataset.getbindings: integerarty; +begin + result:= fbindings; +end; +} +function tifidataset.getmodifiedfields: string; +begin + result:= fmodifiedfields; +end; + +function tifidataset.setcurrentbuf(const abuf: pintrecordty): pintrecordty; +begin + result:= fcurrentbuf; + fcurrentbuf:= abuf; +end; + +function tifidataset.getifistate: ifidsstatesty; +begin + result:= fificontroller.fistate; +end; + +function tifidataset.getfieldinfos: fieldinfoarty; +begin + result:= ffieldinfos; +end; + +procedure tifidataset.InternalRefresh; +begin + active:= false; + active:= true; +end; + +function tifidataset.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tifidataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tifidataset.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tifidataset.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tifidataset.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +function tifidataset.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tifidataset.begindisplaydata; +begin + //dummy +end; + +procedure tifidataset.enddisplaydata; +begin + //dummy +end; + +procedure tifidataset.inheriteddelete; +begin + inherited delete(); +end; + +procedure tifidataset.inheritedinsert; +begin + inherited insert(); +end; + +{ trxdataset } + +procedure trxdataset.fielddefsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +var + int1: integer; +begin + if (ids_openpending in fificontroller.fistate) and + (asequence = ffielddefsequence) then begin + if decodefielddefs(@adata^.data,fielddefs,int1) then begin + exclude(fificontroller.fistate,ids_openpending); + include(fificontroller.fistate,ids_fielddefsreceived); +// active:= true; + end + else begin + cancelconnection; + end; + end; +end; + +procedure trxdataset.dsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +var + int1,int2: integer; +begin + if (ids_openpending in fificontroller.fistate) and + (asequence = ffielddefsequence) then begin + if decodefielddefs(@adata^.data,fielddefs,int1) then begin + inherited inheritedinternalopen; + fificontroller.updaterxbindings; + if decoderecords(pointer(pchar(@adata^.data)+int1),int2) then begin + exclude(fificontroller.fistate,ids_openpending); + include(fificontroller.fistate,ids_fielddefsreceived); + end; + end + else begin + cancelconnection; + end; + end; +end; + +procedure trxdataset.inheritedinternalopen; +var + str1: ansistring; + po1: pointer; +begin + with fificontroller do begin + if (channel <> nil) or + not ((csdesigning in componentstate) and + (irxo_useclientchannel in foptions)) then begin + inititemheader(str1,ik_requestopen,0,0,pchar(po1)); + include(fistate,ids_openpending); + if senddataandwait(str1,ffielddefsequence) and + (ids_fielddefsreceived in fistate) then begin + // inherited; + end + else begin + sysutils.abort; + //error + end; + end + else begin + inherited; + end; + end; +end; + +procedure trxdataset.txactionfired(var adata: ansistring; var adatapo: pchar); +begin + if active then begin + checkbrowsemode; + end; + addifiintegervalue(adata,adatapo,recno); +end; + +{ ttxdataset } + +constructor ttxdataset.create(aowner: tcomponent); +begin + inherited; + include(fificontroller.fistate,ids_sendpostresult); +end; + +{ +procedure ttxdataset.inheritedinternalopen; +begin + inherited; +end; +} +procedure ttxdataset.requestopendsreceived(const asequence: sequencety); +var + str1,str2,str3: ansistring; + po1: pchar; +begin + str2:= fificontroller.encodefielddefs; + str3:= fificontroller.encoderecords(fbrecordcount,fbufs); + fificontroller.inititemheader(str1,ik_dsdata,asequence, + length(str2)+length(str3),po1); + with pfielddefsdatadataty(po1)^ do begin +// sequence:= asequence; + move(str2[1],data,length(str2)); + move(str3[1],(pointer(pchar(@data)+length(str2)))^,length(str3)); + end; + fificontroller.senddata(str1); +end; + +{ ttxsqlquery } + +constructor ttxsqlquery.create(aowner: tcomponent); +begin + inherited; + fificontroller:= tifidscontroller.create(self,iifidscontroller(self)); + include(fificontroller.fistate,ids_sendpostresult); +end; + +destructor ttxsqlquery.destroy; +begin + inherited; + fificontroller.free; + fcurrentchanged.free +end; + +procedure ttxsqlquery.setificontroller(const avalue: tifidscontroller); +begin + fificontroller.assign(avalue); +end; + +procedure ttxsqlquery.requestopendsreceived(const asequence: sequencety); +var + str1,str2,str3: ansistring; + po1: pchar; +begin + if checkcanevent(self,tmethod(fclientbeforeopen)) then begin + fclientbeforeopen(self); + end; + str2:= fificontroller.encodefielddefs; + if factindexpo = nil then begin + str3:= fificontroller.encoderecords(fbrecordcount,nil); + end + else begin + str3:= fificontroller.encoderecords(fbrecordcount,factindexpo^.ind); + end; + fificontroller.inititemheader(str1,ik_dsdata,asequence, + length(str2)+length(str3),po1); + with pfielddefsdatadataty(po1)^ do begin +// sequence:= asequence; + move(str2[1],data,length(str2)); + move(str3[1],(pointer(pchar(@data)+length(str2)))^,length(str3)); + end; + fificontroller.senddata(str1); + if checkcanevent(self,tmethod(fclientafteropen)) then begin + fclientafteropen(self); + end; +end; + +procedure ttxsqlquery.fielddefsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +begin +end; + +procedure ttxsqlquery.dsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +begin +end; +{ +procedure ttxsqlquery.fieldrecdatareceived(const adata: pfieldrecdataty); +begin +end; +} +function ttxsqlquery.getfielddefs: tfielddefs; +begin + result:= fielddefs; +end; + +procedure ttxsqlquery.internalopen; +begin + inherited; + fcurrentchanged.free; + fcurrentchanged:= tcurrentchangedlist.create(nullmasksize); + fificontroller.opened; +end; + +procedure ttxsqlquery.internalclose; +begin + fificontroller.closed; + inherited; +end; + +function ttxsqlquery.getmodifiedfields: string; +begin + result:= fmodifiedfields; +end; + +function ttxsqlquery.setcurrentbuf(const abuf: pintrecordty): pintrecordty; +begin + result:= fcurrentbuf; + fcurrentbuf:= abuf; +end; + +procedure ttxsqlquery.initmodifiedfields; +begin + setlength(fmodifiedfields,nullmasksize); + fillchar(pointer(fmodifiedfields)^,nullmasksize,#0); +end; + +procedure ttxsqlquery.internaledit; +begin + initmodifiedfields; + inherited; +end; + +procedure ttxsqlquery.inheritedinternalinsert; +begin + initmodifiedfields; + inherited; +end; + +procedure ttxsqlquery.InternalPost; +begin + fificontroller.post; + inherited; +end; + +function ttxsqlquery.getfieldinfos: fieldinfoarty; +begin + result:= ffieldinfos; +end; + +procedure ttxsqlquery.inheritedinternaldelete; +begin + fificontroller.delete; + inherited; +end; + +function ttxsqlquery.getfieldbuffer(const afield: tfield; const aisnull: boolean; + out datasize: integer): pointer; +var + int1: integer; +begin + result:= inherited getfieldbuffer(afield,aisnull,datasize); + int1:= afield.fieldno-1; + if (int1 >= 0) and (state <> dscurvalue) and + not (bs_fetching in fbstate) then begin //datafield + setfieldflag(pointer(fmodifiedfields),int1); //modified + end; +end; + +procedure ttxsqlquery.cancelconnection; +begin + //dummy +end; + +procedure ttxsqlquery.fixupcurrentset; +begin + inherited; +end; +{ +procedure ttxsqlquery.deccurrentupdate; +begin + if fcurrentupdating = 0 then begin + fupdatedcurrentrecords:= nil; + fupdatedcurrentrecordcount:= 0; + end; + inherited; +end; +} +procedure ttxsqlquery.aftercurrentset(const afield: tfield); +begin + inherited; + if flastcurrentindex >= 0 then begin + if fcurrentupdating = 0 then begin + currentrecordupdated(flastcurrentindex); + end + else begin + fcurrentchanged.fieldchanged(afield,flastcurrentindex); + end; + end; +end; + +procedure ttxsqlquery.currentrecordupdated(const aindex: integer); +begin +end; + +procedure ttxsqlquery.currentbeginupdate; +begin + if fcurrentupdating = 0 then begin + fcurrentchanged.clear; + end; + inherited; +end; + +procedure ttxsqlquery.currentendupdate; +begin + inherited; + if fcurrentupdating = 0 then begin + fificontroller.sendchangedrecords(fcurrentchanged); + fcurrentchanged.clear; + end; +end; + +{ tcurrentchangedlist } + +constructor tcurrentchangedlist.create(const anullmasksize: integer); +begin + fnullmasksize:= anullmasksize; + inherited create(); + include(fstate,hls_needsnull); +end; + +function tcurrentchangedlist.getrecordsize(): int32; +begin + result:= sizeof(ptruinthashdataty)+fnullmasksize; +end; + +procedure tcurrentchangedlist.fieldchanged(const afield: tfield; + const aindex: integer); +begin + setfieldflag(@pchangehashdataty(addunique(ptruint(aindex)))^.data.data, + afield.fieldno-1); +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifiendpoint.pas b/mseide-msegui/lib/common/ifi/mseifiendpoint.pas new file mode 100644 index 0000000..bef20ce --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifiendpoint.pas @@ -0,0 +1,418 @@ +{ MSEgui Copyright (c) 2013-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseifiendpoint; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msestrings,mclasses,mseclasses,mseificompglob,mseificomp,typinfo,msedatalist, + msetypes; + +type + tifidataendpoint = class(tmsecomponent,iifidatalink) + private + fonchange: notifyeventty; + protected + fifilink: tifilinkcomp; + procedure change; + //iifidatalink + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifilinkcomp); + function ifigriddata: tdatalist; + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue) virtual; + procedure setifivalue(const avalue) virtual; + procedure updatereadonlystate; + published + property onchange: notifyeventty read fonchange write fonchange; + end; + + tifiintegerendpoint = class(tifidataendpoint) + private + fvalue: integer; + fondatachange: updateintegereventty; + function getifilink: tifiintegerlinkcomp; + procedure setifilink(const avalue: tifiintegerlinkcomp); + procedure setvalue(const avalue: integer); + published + property ifilink: tifiintegerlinkcomp read getifilink write setifilink; + property value: integer read fvalue write setvalue default 0; + property ondatachange: updateintegereventty read fondatachange + write fondatachange; + end; + + tifiint64endpoint = class(tifidataendpoint) + private + fvalue: int64; + fondatachange: updateint64eventty; + function getifilink: tifiint64linkcomp; + procedure setifilink(const avalue: tifiint64linkcomp); + procedure setvalue(const avalue: int64); + published + property ifilink: tifiint64linkcomp read getifilink write setifilink; + property value: int64 read fvalue write setvalue default 0; + property ondatachange: updateint64eventty read fondatachange + write fondatachange; + end; + + tifipointerendpoint = class(tifidataendpoint) + private + fvalue: pointer; + fondatachange: updatepointereventty; + function getifilink: tifipointerlinkcomp; + procedure setifilink(const avalue: tifipointerlinkcomp); + procedure setvalue(const avalue: pointer); + protected + procedure getifivalue(var avalue) override; + procedure setifivalue(const avalue) override; + public + property value: pointer read fvalue write setvalue default nil; + published + property ifilink: tifipointerlinkcomp read getifilink write setifilink; + property ondatachange: updatepointereventty read fondatachange + write fondatachange; + end; + + tifibooleanendpoint = class(tifidataendpoint) + private + fvalue: boolean; + fondatachange: updatebooleaneventty; + function getifilink: tifibooleanlinkcomp; + procedure setifilink(const avalue: tifibooleanlinkcomp); + procedure setvalue(const avalue: boolean); + published + property ifilink: tifibooleanlinkcomp read getifilink write setifilink; + property value: boolean read fvalue write setvalue default false; + property ondatachange: updatebooleaneventty read fondatachange + write fondatachange; + end; + + tifirealendpoint = class(tifidataendpoint) + private + fvalue: real; + fondatachange: updaterealeventty; + function getifilink: tifireallinkcomp; + procedure setifilink(const avalue: tifireallinkcomp); + procedure setvalue(const avalue: real); + public + constructor create(aowner: tcomponent); override; + published + property ifilink: tifireallinkcomp read getifilink write setifilink; + property value: real read fvalue write setvalue; + property ondatachange: updaterealeventty read fondatachange + write fondatachange; + end; + + tifidatetimeendpoint = class(tifidataendpoint) + private + fvalue: tdatetime; + fondatachange: updatedatetimeeventty; + function getifilink: tifidatetimelinkcomp; + procedure setifilink(const avalue: tifidatetimelinkcomp); + procedure setvalue(const avalue: tdatetime); + public + constructor create(aowner: tcomponent); override; + published + property ifilink: tifidatetimelinkcomp read getifilink write setifilink; + property value: tdatetime read fvalue write setvalue; + property ondatachange: updatedatetimeeventty read fondatachange + write fondatachange; + end; + + tifistringendpoint = class(tifidataendpoint) + private + fvalue: msestring; + fondatachange: updatestringeventty; + function getifilink: tifistringlinkcomp; + procedure setifilink(const avalue: tifistringlinkcomp); + procedure setvalue(const avalue: msestring); + public + published + property ifilink: tifistringlinkcomp read getifilink write setifilink; + property value: msestring read fvalue write setvalue; + property ondatachange: updatestringeventty read fondatachange + write fondatachange; + end; + + tifiactionendpoint = class(tmsecomponent,iifiexeclink) + private + fonexecute: notifyeventty; + procedure setifilink(const avalue: tifiactionlinkcomp); + //iifilink + function getifilinkkind: ptypeinfo; + protected + fifilink: tifiactionlinkcomp; + public + //iifiexeclink + procedure execute(const force: boolean = false); + procedure ifisetenabled(const avalue: boolean); + published + property ifilink: tifiactionlinkcomp read fifilink write setifilink; + property onexecute: notifyeventty read fonexecute write fonexecute; + end; + +implementation + +{ tifidataendpoint } + +function tifidataendpoint.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure tifidataendpoint.setifilink(const avalue: tifilinkcomp); +begin + mseificomp.setifilinkcomp(iifidatalink(self),avalue,fifilink); +end; + +function tifidataendpoint.ifigriddata: tdatalist; +begin + result:= nil; +end; + +procedure tifidataendpoint.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +function tifidataendpoint.getgriddata: tdatalist; +begin + result:= nil; +end; + +function tifidataendpoint.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure tifidataendpoint.getifivalue(var avalue); +begin + //dummy +end; + +procedure tifidataendpoint.setifivalue(const avalue); +begin + //dummy +end; + +procedure tifidataendpoint.updatereadonlystate; +begin + //dummy +end; + +procedure tifidataendpoint.change; +begin + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + if fifiserverintf <> nil then begin + iifidataserver(fifiserverintf).valuechanged(iifidatalink(self)); + end; +end; + +{ tifiintegerendpoint } + +function tifiintegerendpoint.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure tifiintegerendpoint.setifilink(const avalue: tifiintegerlinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifiintegerendpoint.setvalue(const avalue: integer); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifiint64endpoint } + +function tifiint64endpoint.getifilink: tifiint64linkcomp; +begin + result:= tifiint64linkcomp(fifilink); +end; + +procedure tifiint64endpoint.setifilink(const avalue: tifiint64linkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifiint64endpoint.setvalue(const avalue: int64); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifipointerendpoint } + +function tifipointerendpoint.getifilink: tifipointerlinkcomp; +begin + result:= tifipointerlinkcomp(fifilink); +end; + +procedure tifipointerendpoint.setifilink(const avalue: tifipointerlinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifipointerendpoint.setvalue(const avalue: pointer); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +procedure tifipointerendpoint.getifivalue(var avalue); +begin + pointer(avalue):= fvalue; +end; + +procedure tifipointerendpoint.setifivalue(const avalue); +begin + fvalue:= pointer(avalue); +end; + +{ tifibooleanendpoint } + +function tifibooleanendpoint.getifilink: tifibooleanlinkcomp; +begin + result:= tifibooleanlinkcomp(fifilink); +end; + +procedure tifibooleanendpoint.setifilink(const avalue: tifibooleanlinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifibooleanendpoint.setvalue(const avalue: boolean); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifirealendpoint } + +constructor tifirealendpoint.create(aowner: tcomponent); +begin + fvalue:= emptyreal; + inherited; +end; + +function tifirealendpoint.getifilink: tifireallinkcomp; +begin + result:= tifireallinkcomp(fifilink); +end; + +procedure tifirealendpoint.setifilink(const avalue: tifireallinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifirealendpoint.setvalue(const avalue: real); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifidatetimeendpoint } + +constructor tifidatetimeendpoint.create(aowner: tcomponent); +begin + fvalue:= emptydatetime; + inherited; +end; + +function tifidatetimeendpoint.getifilink: tifidatetimelinkcomp; +begin + result:= tifidatetimelinkcomp(fifilink); +end; + +procedure tifidatetimeendpoint.setifilink(const avalue: tifidatetimelinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifidatetimeendpoint.setvalue(const avalue: tdatetime); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifistringendpoint } + +function tifistringendpoint.getifilink: tifistringlinkcomp; +begin + result:= tifistringlinkcomp(fifilink); +end; + +procedure tifistringendpoint.setifilink(const avalue: tifistringlinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifistringendpoint.setvalue(const avalue: msestring); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifiactionendpoint } + +procedure tifiactionendpoint.setifilink(const avalue: tifiactionlinkcomp); +begin + mseificomp.setifilinkcomp(iifiexeclink(self),avalue,tifilinkcomp(fifilink)); +end; + +procedure tifiactionendpoint.execute(const force: boolean = false); +begin + if canevent(tmethod(fonexecute)) then begin + fonexecute(self); + end; + if fifiserverintf <> nil then begin + fifiserverintf.execute(iifiexeclink(self)); + end; +end; + +procedure tifiactionendpoint.ifisetenabled(const avalue: boolean); +begin + //dummy +end; + +function tifiactionendpoint.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifiexeclink); +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifiglob.pas b/mseide-msegui/lib/common/ifi/mseifiglob.pas new file mode 100644 index 0000000..6f02fdc --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifiglob.pas @@ -0,0 +1,62 @@ +{ MSEgui Copyright (c) 2007-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseifiglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + mseglob,mseeditglob,typinfo,mseinterfaces; +{$ifdef mse_no_ifi} + {$error 'MSEifi support required, please do not compile with "-dmse_no_ifi"'} +{$endif} +const + ifiwidgetstatename = '#widgetstate#'; + ifiwidgetmodalresultname = '#modalres#'; +{$ifdef FPC} + boolprops = [tkbool,tkinteger,tkenumeration]; +{$else} + boolprops = [tkinteger,tkenumeration]; +{$endif} + +type + ifiwidgetstatety = ({iws_closed,}iws_loaded,iws_releasing,iws_destroying, + iws_visible,iws_enabled,iws_entered,iws_focused,iws_active); + ifiwidgetstatesty = set of ifiwidgetstatety; +const + ifidatatypes = [dl_integer,dl_int64,dl_currency,dl_real, + dl_msestring,dl_ansistring,dl_msestringint, + dl_realint,dl_realsum]; + +type + iificlient = interface; + + iifiserver = interface(inullinterface) + procedure execute(const sender: iificlient); +// procedure valuechanged(const sender: iificlient); + procedure statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); + procedure dataentered(const sender: iificlient; const arow: integer); + procedure closequery(const sender: iificlient; + var amodalresult: modalresultty); + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); + procedure updateoptionsedit(var avalue: optionseditty); + end; + + iificlient = interface(iobjectlink)[miid_iificlient] + procedure setifiserverintf(const aintf: iifiserver); + function getdefaultifilink: iificlient; + function getifidatatype: listdatatypety; + end; + ificommandcodety = (icc_none,icc_close,icc_release); + iificommand = interface(inullinterface)[miid_iificommand] + procedure executeificommand(var acommand: ificommandcodety); + end; +implementation +end. diff --git a/mseide-msegui/lib/common/ifi/mseifigui.pas b/mseide-msegui/lib/common/ifi/mseifigui.pas new file mode 100644 index 0000000..ac6014b --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifigui.pas @@ -0,0 +1,856 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseifigui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseclasses,mseguiglob,mseifiglob,mseifi,mseact,msegui,typinfo, + msestrings,mseapplication,mseforms,msedatanodes,msedataedits, + msearrayprops,mseglob,msetypes,mseifilink,msewidgetgrid,msemenus, + mseevent,msegrids,msegraphutils,msedatalist,mseificomp,mseificompglob, + mseifidialogcomp,msegraphics; + +type + + ifiwidgetlinkoptionty = (iwlo_sendvalue,iwlo_sendmodalresult, + iwlo_sendhide,iwlo_sendshow, + iwlo_sendfocus,iwlo_senddefocus,iwlo_sendactivate,iwlo_senddeactivate); + ifiwidgetlinkoptionsty = set of ifiwidgetlinkoptionty; +const + widgetstateoptionsty = [iwlo_sendhide,iwlo_sendshow,iwlo_sendfocus, + iwlo_senddefocus,iwlo_sendactivate,iwlo_senddeactivate]; +type + + tvaluewidgetlink = class(tcustomvaluecomponentlink) + private + foptions: ifiwidgetlinkoptionsty; + fwidgetstatebefore: ifiwidgetstatesty; + function getwidget: twidget; + procedure setwidget(const avalue: twidget); + published + property widget: twidget read getwidget write setwidget; + property options: ifiwidgetlinkoptionsty read foptions + write foptions default []; + end; + + tvaluewidgetlinks = class(tvaluelinks) + private + function getitems(const index: integer): tvaluewidgetlink; + protected + function getitemclass: modulelinkpropclassty; override; + public + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): tvaluewidgetlink; + property items[const index: integer]: tvaluewidgetlink read getitems; default; + end; + + tformlink = class(tcustommodulelink) + private + function getvaluewidgets: tvaluewidgetlinks; + procedure setvaluewidgets(const avalue: tvaluewidgetlinks); + protected + function widgetcommandreceived(const atag: integer; const aname: string; + const acommand: ifiwidgetcommandty): boolean; + function widgetpropertiesreceived(const atag: integer; const aname: string; + const adata: pifibytesty): boolean; + function processdataitem(const adata: pifirecty; var adatapo: pchar; + const atag: integer; const aname: string): boolean; override; + procedure valuechanged(const sender: iificlient); override; + procedure statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); override; + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property valuewidgets: tvaluewidgetlinks read getvaluewidgets + write setvaluewidgets; + property valuecomponents; + property linkname; + property actionsrx; + property actionstx; + property modulesrx; + property modulestx; + property channel; + property options; + end; + + trxwidgetgrid = class; + + tifiwidgetgridcontroller = class(tifigridcontroller) + protected + procedure processdata(const adata: pifirecty; var adatapo: pchar); override; + procedure setowneractive(const avalue: boolean); override; + function encodegriddata(const asequence: sequencety): ansistring; override; + public + constructor create(const aowner: trxwidgetgrid; + const aintf: iactivatorclient); + end; + + tifiwidgetcol = class(twidgetcol) + protected + procedure datachange(const arow: integer); override; + end; + ifiwidgetcolarty = array of tifiwidgetcol; + + rxwidgetstatety = ({rws_openpending,}rws_datareceived,rws_commandsending); + rxwidgetstatesty = set of rxwidgetstatety; + + trxwidgetgrid = class(twidgetgrid,iifimodulelink) + private + factive: boolean; + procedure setactive1(const avalue: boolean); + protected + fistate: rxwidgetstatesty; + fifi: tifiwidgetgridcontroller; + procedure setactive(const avalue: boolean); override; + procedure setifi(const avalue: tifiwidgetgridcontroller); + procedure loaded; override; + procedure internalopen; + procedure internalclose; + procedure docolmoved(const fromindex,toindex: integer); override; + procedure dorowsmoved(const fromindex,toindex,count: integer); override; + procedure dorowsinserted(const index,count: integer); override; + procedure dorowsdeleted(index,count: integer); override; + procedure rowstatechanged(const arow: integer); override; + procedure docellevent(var info: celleventinfoty); override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure setselected(const cell: gridcoordty; + const avalue: boolean); override; + //iifimodulelink + procedure connectmodule(const sender: tcustommodulelink); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property ifi: tifiwidgetgridcontroller read fifi write setifi; + property active: boolean read factive write setactive1 default false; + end; + + getdialogclasseventty = procedure(const sender: tobject; + var adialogclass: custommseformclassty) of object; + + tifidialog = class(tmsecomponent,iifidialoglink) + private + fifilink: tifidialoglinkcomp; + fongetdialogclass: getdialogclasseventty; + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifidialoglinkcomp); + protected + function showdialog(out adialog: tactcomponent): modalresultty; virtual; + published + property ifilink: tifidialoglinkcomp read fifilink write setifilink; + property ongetdialogclass: getdialogclasseventty + read fongetdialogclass write fongetdialogclass; + end; + +implementation +uses + sysutils,msestream,msesysutils,msetmpmodules,mseeditglob,mselistbrowser; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustommodulelink1 = class(tcustommodulelink); + tdatacols1 = class(tdatacols); + tdialogclientcontroller1 = class(tdialogclientcontroller); + +// tlinkdata1 = class(tlinkdata); + +{ tvaluewidgetlink } + +function tvaluewidgetlink.getwidget: twidget; +begin + result:= twidget(fcomponent); +end; + +procedure tvaluewidgetlink.setwidget(const avalue: twidget); +var + intf1: iificlient; +begin + intf1:= nil; + fwidgetstatebefore:= []; + fvalueproperty:= nil; + if (avalue <> nil) and + not getcorbainterface(avalue,typeinfo(iificlient),intf1) then begin + raise exception.create(avalue.name+': No ifiwidget.'); + end; + if fintf <> nil then begin + fintf.setifiserverintf(nil); + end; + fintf:= intf1; + if fintf <> nil then begin + fintf:= fintf.getdefaultifilink(); + fintf.setifiserverintf(iifiserver(tcustommodulelink(fowner))); + end; + inherited component:= avalue; +end; + +{ tvaluewidgetlinks } + +class function tvaluewidgetlinks.getitemclasstype: persistentclassty; +begin + result:= tvaluewidgetlink; +end; + +function tvaluewidgetlinks.getitems(const index: integer): tvaluewidgetlink; +begin + result:= tvaluewidgetlink(inherited getitems(index)); +end; + +function tvaluewidgetlinks.byname(const aname: string): tvaluewidgetlink; +begin + result:= tvaluewidgetlink(inherited byname(aname)); +end; + +function tvaluewidgetlinks.getitemclass: modulelinkpropclassty; +begin + result:= tvaluewidgetlink; +end; + +{ tformlink } + +constructor tformlink.create(aowner: tcomponent); +begin + if fvalues = nil then begin + fvalues:= tvaluewidgetlinks.create(self); + end; + inherited; +end; + +destructor tformlink.destroy; +begin + inherited; +end; + +function tformlink.getvaluewidgets: tvaluewidgetlinks; +begin + result:= tvaluewidgetlinks(fvalues); +end; + +procedure tformlink.setvaluewidgets(const avalue: tvaluewidgetlinks); +begin + fvalues.assign(avalue); +end; + +function tformlink.processdataitem(const adata: pifirecty; + var adatapo: pchar; const atag: integer; const aname: string): boolean; +var + command1: ifiwidgetcommandty; +begin + with adata^ do begin + case header.kind of + ik_widgetcommand: begin + command1:= pifiwidgetcommandty(adatapo)^; + result:= widgetcommandreceived(atag,aname,command1); + end; + ik_widgetproperties: begin + result:= widgetpropertiesreceived(atag,aname,pifibytesty(adatapo)); + end; + else begin + result:= inherited processdataitem(adata,adatapo,atag,aname); + end; + end; + end; +end; + +function tformlink.widgetcommandreceived(const atag: integer; + const aname: string; const acommand: ifiwidgetcommandty): boolean; +var + wi1: tvaluewidgetlink; +begin + wi1:= tvaluewidgetlink(fvalues.finditem(aname)); + result:= wi1 <> nil; + if result and (wi1.fcomponent <> nil) then begin + with wi1.widget do begin + case acommand of + iwc_enable: begin + enabled:= true; + end; + iwc_disable: begin + enabled:= false; + end; + iwc_show: begin + visible:= true; + end; + iwc_hide: begin + visible:= false; + end; + end; + end; + end; +end; + +function tformlink.widgetpropertiesreceived(const atag: integer; + const aname: string; const adata: pifibytesty): boolean; +var + wi1: tvaluewidgetlink; + stream1: tmemorystream; +begin + wi1:= tvaluewidgetlink(fvalues.finditem(aname)); + result:= wi1 <> nil; + if result and (wi1.fcomponent <> nil) then begin + stream1:= tmemorycopystream.create(@adata^.data,adata^.length); + try + stream1.readcomponent(wi1.fcomponent); + finally + stream1.free; + end; + end; +end; + +procedure tformlink.valuechanged(const sender: iificlient); +var + int1: integer; +begin + if hasconnection then begin + with tvaluewidgetlinks(fvalues ) do begin + for int1:= 0 to high(fitems) do begin + with tvaluewidgetlink(fitems[int1]) do begin + if fupdatelock = 0 then begin + if (fintf = sender) then begin + if iwlo_sendvalue in options then begin + sendvalue(fvalueproperty); + end; + break; + end; + end; + end; + end; + end; + end; +end; + +procedure tformlink.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +var + int1: integer; +begin + if hasconnection then begin + with tvaluewidgetlinks(fvalues ) do begin + for int1:= 0 to high(fitems) do begin + with tvaluewidgetlink(fitems[int1]) do begin + if fupdatelock = 0 then begin + if (fintf = sender) then begin + if iwlo_sendmodalresult in options then begin + sendmodalresult(amodalresult); + end; + break; + end; + end; + end; + end; + end; + end; +end; + +procedure tformlink.statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); +var + int1: integer; + states1: ifiwidgetstatesty; +begin + if hasconnection then begin + with tvaluewidgetlinks(fvalues ) do begin + for int1:= 0 to high(fitems) do begin + with tvaluewidgetlink(fitems[int1]) do begin + if (fintf = sender) then begin + if options * widgetstateoptionsty <> [] then begin + states1:= ifiwidgetstatesty( + {$ifdef FPC}longword{$else}byte{$endif}(fwidgetstatebefore) xor + {$ifdef FPC}longword{$else}byte{$endif}(astate)); + if (iws_visible in states1) and + ((iwlo_sendshow in options) and (iws_visible in astate) or + (iwlo_sendhide in options) and not (iws_visible in astate)) or + (iws_focused in states1) and + ((iwlo_sendfocus in options) and (iws_focused in astate) or + (iwlo_senddefocus in options) and not(iws_focused in astate)) or + (iws_active in states1) and + ((iwlo_sendactivate in options) and (iws_active in astate) or + (iwlo_senddeactivate in options) and not(iws_active in astate)) + then begin + sendstate(astate); + end; + end; + fwidgetstatebefore:= astate; + break; + end; + end; + end; + end; + end; +end; + +{ tifiwidgetgridcontroller } + +constructor tifiwidgetgridcontroller.create(const aowner: trxwidgetgrid; + const aintf: iactivatorclient); +begin + inherited create(aowner,aintf); +end; + +procedure tifiwidgetgridcontroller.setowneractive(const avalue: boolean); +begin + trxwidgetgrid(fowner).active:= avalue; +end; + +function tifiwidgetgridcontroller.encodegriddata( + const asequence: sequencety): ansistring; +var + po1: pchar; + int1,int2,int3: integer; + ar1: booleanarty; +begin + with trxwidgetgrid(fowner) do begin + setlength(ar1,datacols.count); + int2:= 0; + int3:= 0; + for int1:= 0 to datacols.count - 1 do begin + with datacols[int1] do begin + ar1[int1]:= (name <> '') and (datalist <> nil) and + (datalist.datatype in ifidatatypes); + if ar1[int1] then begin + inc(int3); + int2:= int2 + (sizeof(listdatatypety)+1) + length(name) + + datalisttoifidata(datalist); + end; + end; + end; +{$warnings off} + int2:= int2 + datalisttoifidata(tdatacols1(datacols).frowstate); +{$warnings on} + inititemheader(result,ik_griddata,asequence,int2,po1); + with pgriddatadataty(po1)^ do begin + rows:= rowcount; + cols:= int3; + po1:= @data; + for int1:= 0 to high(ar1) do begin + if ar1[int1] then begin + with datacols[int1] do begin + with pcoldataty(po1)^ do begin + kind:= datalist.datatype; + po1:= @name; + end; + inc(po1,stringtoifiname(name,pifinamety(po1))); + datalisttoifidata(datalist,po1); + end; + end; + end; +{$warnings off} + datalisttoifidata(tdatacols1(datacols).frowstate,po1); +{$warnings on} + end; + end; +end; + +procedure tifiwidgetgridcontroller.processdata(const adata: pifirecty; + var adatapo: pchar); +var + int1,int2: integer; + rows1,cols1: integer; + kind1: listdatatypety; + po1: pchar; + str1: ansistring; + ckind1: gridcommandkindty; + source1,dest1,count1: integer; + rowstate1: rowstaterowheightty; + select1: selectdataty; + datalist1: subdatainfoty; + po3: prowstaterowheightty; + ifikind1: ifidatakindty; +begin + with adata^.header do begin + case kind of + ik_requestopen: begin + senddata(encodegriddata(sequence)); + end; + ik_griddata: begin + if (igo_state in foptionsrx) or + (answersequence <> 0) and (answersequence = fdatasequence) then begin + with trxwidgetgrid(fowner) do begin + beginupdate; + try + with pgriddatadataty(adatapo)^ do begin + rows1:= rows; + rowcount:= rows1; + cols1:= cols; + po1:= @data; + end; + for int1:= 0 to cols1 - 1 do begin + with pcoldataty(po1)^ do begin + kind1:= kind; + po1:= @name; + inc(po1,ifinametostring(pifinamety(po1),str1)); + inc(po1,ifidatatodatalist(kind1,rows1,po1, + datacols.colsubdatainfo(str1))); + end; + end; +{$warnings off} + inc(po1,ifidatatodatalist(dl_rowstate,rows1,po1, + tdatacols1(datacols).frowstate)); +{$warnings on} + include(fistate,rws_datareceived); + finally + endupdate; + end; + end; + end; + end; + ik_gridcommand: begin + inc(adatapo,decodegridcommanddata(adatapo,ckind1,source1,dest1,count1)); + with trxwidgetgrid(fowner) do begin + inc(fcommandlock); + try + case ckind1 of + gck_insertrow: begin + if igo_rowinsert in foptionsrx then begin + insertrow(dest1,count1); + end; + end; + gck_deleterow: begin + if igo_rowdelete in foptionsrx then begin + deleterow(dest1,count1); + end; + end; + gck_moverow: begin + if igo_rowmove in foptionsrx then begin + moverow(source1,dest1,count1); + end; + end; + gck_rowenter: begin + if igo_rowenter in foptionsrx then begin + row:= dest1; + end; + end; + end; + finally + dec(fcommandlock); + end; + end; + end; + ik_coldatachange: begin + if igo_coldata in foptionsrx then begin + inc(fcommandlock); + try + int1:= pcolitemdataty(adatapo)^.header.row; + ifinametostring(@pcolitemdataty(adatapo)^.header.name,str1); + inc(adatapo,sizeof(colitemheaderty)+length(str1)); + datalist1.list:= nil; + if igo_coldata in foptionsrx then begin + datalist1:= trxwidgetgrid(fowner).fdatacols.colsubdatainfo(str1); + end; //skip data otherwise + inc(adatapo,decodeifidata(pifidataty(adatapo),int1,datalist1)); + finally + dec(fcommandlock); + end; + end; + end; + ik_rowstatechange: begin + if igo_rowstate in foptionsrx then begin + inc(fcommandlock); + try + int1:= prowstatedataty(adatapo)^.header.row; + inc(adatapo,sizeof(rowstateheaderty)); + ifikind1:= pifidataty(adatapo)^.header.kind; + case ifikind1 of + idk_rowstatecolmerge: begin + inc(adatapo,decodeifidata(pifidataty(adatapo), + prowstatecolmergety(@rowstate1)^)); + end; + idk_rowstaterowheight: begin + inc(adatapo,decodeifidata(pifidataty(adatapo), + prowstaterowheightty(@rowstate1)^)); + + end; + else begin + inc(adatapo,decodeifidata(pifidataty(adatapo), + prowstatety(@rowstate1)^)); + end; + end; + with trxwidgetgrid(fowner) do begin + int2:= ord(datacols.rowstate.infolevel) - ord(ril_normal); + if ord(ifikind1)-ord(idk_rowstate) < int2 then begin + ifikind1:= ifidatakindty(ord(idk_rowstate)+int2); + end; + rowcolorstate[int1]:= rowstate1.normal.color; + rowfontstate[int1]:= rowstate1.normal.font; + rowhidden[int1]:= rowstate1.normal.fold and foldhiddenmask <> 0; + rowfoldlevel[int1]:= rowstate1.normal.fold and foldlevelmask; + if ifikind1 >= idk_rowstatecolmerge then begin + po3:= prowstaterowheightty(fdatacols.rowstate.getitempo(int1)); + if po3^.colmerge.merged <> rowstate1.colmerge.merged then begin + po3^.colmerge.merged:= rowstate1.colmerge.merged; + tdatacols1(fdatacols).mergechanged(int1); + end; + if ifikind1 >= idk_rowstaterowheight then begin + rowheight[int1]:= rowstate1.rowheight.height; + end; + end; + end; + finally + dec(fcommandlock); + end; + end; + end; + ik_selection: begin + if igo_selection in foptionsrx then begin + inc(fcommandlock); + try + inc(adatapo,decodeifidata(pifidataty(adatapo),select1)); + with select1 do begin + trxwidgetgrid(fowner).fdatacols.selected[makegridcoord(col,row)]:= select; + end; + finally + dec(fcommandlock); + end; + end; + end; + end; + end; +end; + +{ tifiwidgetcol } + +procedure tifiwidgetcol.datachange(const arow: integer); +begin + with trxwidgetgrid(fcellinfo.grid).fifi do begin + if (self.name <> '') and (arow >= 0) and cancommandsend(igo_coldata) and + (fdata <> nil) then begin + senditem(ik_coldatachange,[encodecolchangedata(self.name,arow,fdata)]); + end; + end; +end; + +{ trxwidgetgrid } + +constructor trxwidgetgrid.create(aowner: tcomponent); +begin + if fifi = nil then begin + fifi:= tifiwidgetgridcontroller.create(self,iactivatorclient(self)); + end; + inherited; +end; + +destructor trxwidgetgrid.destroy; +begin + inherited; + fifi.free; +end; + +procedure trxwidgetgrid.setifi(const avalue: tifiwidgetgridcontroller); +begin + fifi.assign(avalue); +end; + +procedure trxwidgetgrid.setactive(const avalue: boolean); +begin + if avalue <> factive then begin + if avalue then begin + try + internalopen; + except + active:= false; + raise; + end; + factive:= true; + end + else begin + internalclose; + factive:= false; + end; + end; +end; + +procedure trxwidgetgrid.loaded; +begin + inherited; + fifi.loaded; +end; + +procedure trxwidgetgrid.internalopen; +var + str1: string; + po1: pchar; +begin + with fifi do begin + if cansend then begin + inititemheader(str1,ik_requestopen,0,0,po1); + if senddataandwait(str1,fdatasequence) and + (rws_datareceived in fistate) then begin + end + else begin + raise exception.create('Can not open '+name+'.'); //sysutils.abort; + end; + end; + end; +end; + +procedure trxwidgetgrid.internalclose; +begin + rowcount:= 0; +end; + +procedure trxwidgetgrid.docolmoved(const fromindex: integer; + const toindex: integer); +begin + inherited; +end; + +procedure trxwidgetgrid.dorowsmoved(const fromindex: integer; + const toindex: integer; const count: integer); +begin + inherited; + with fifi do begin + if cancommandsend(igo_rowmove) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_moverow,fromindex,toindex,count)]); + end; + end; +end; + +procedure trxwidgetgrid.dorowsinserted(const index: integer; + const count: integer); +begin + inherited; + with fifi do begin + if cancommandsend(igo_rowinsert) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_insertrow,index,index,count)]); + end; + end; +end; + +procedure trxwidgetgrid.dorowsdeleted(index: integer; count: integer); +begin + inherited; + with fifi do begin + if cancommandsend(igo_rowdelete) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_deleterow,index,index,count)]); + end; + end; +end; + +procedure trxwidgetgrid.rowstatechanged(const arow: integer); +begin + inherited; + with fifi do begin + if cancommandsend(igo_rowstate) then begin + case fdatacols.rowstate.infolevel of + ril_normal: begin + senditem(ik_rowstatechange, + [encoderowstatedata(arow,fdatacols.rowstate.items[arow])]); + end; + ril_colmerge: begin + senditem(ik_rowstatechange, + [encoderowstatedata(arow,fdatacols.rowstate.itemscolmerge[arow])]); + end; + ril_rowheight: begin + senditem(ik_rowstatechange, + [encoderowstatedata(arow,fdatacols.rowstate.itemsrowheight[arow])]); + end; + end; + end; + end; +end; + +procedure trxwidgetgrid.setselected(const cell: gridcoordty; + const avalue: boolean); +begin + inherited; + with fifi do begin + if cancommandsend(igo_selection) then begin + senditem(ik_selection,[encodeselectiondata(cell,avalue)]); + end; + end; +end; + +procedure trxwidgetgrid.docellevent(var info: celleventinfoty); +begin + inherited; + if isrowenter(info) and fifi.cancommandsend(igo_rowenter) then begin + fifi.senditem(ik_gridcommand,[ + encodegridcommanddata(gck_rowenter,info.cell.row,info.cell.row,0)]); + end; +end; + +procedure trxwidgetgrid.createdatacol(const index: integer; out item: tdatacol); +begin + item:= tifiwidgetcol.create(self,fdatacols); +end; + +procedure trxwidgetgrid.connectmodule(const sender: tcustommodulelink); +begin + fifi.connectmodule(sender); +end; + +procedure trxwidgetgrid.setactive1(const avalue: boolean); +begin + if fifi.setactive(avalue) then begin + setactive(avalue); + end; +end; + +{ tifidialog } + +function tifidialog.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidialoglink); +end; + +procedure tifidialog.setifilink(const avalue: tifidialoglinkcomp); +begin + mseificomp.setifilinkcomp(iifidialoglink(self),avalue,tifilinkcomp(fifilink)); +end; + +function tifidialog.showdialog(out adialog: tactcomponent): modalresultty; +var + dia1: custommseformclassty; +begin + dia1:= nil; + adialog:= nil; + result:= mr_none; + dia1:= nil; + if owner is tcustommseform then begin + dia1:= custommseformclassty(owner.classtype); + end; + if canevent(tmethod(fongetdialogclass)) then begin + fongetdialogclass(self,dia1); + end; + if dia1 <> nil then begin + adialog:= dia1.create(nil); + if fifilink <> nil then begin + tdialogclientcontroller1(fifilink.controller).beforedialog(adialog); + end; + try + result:= twidget(adialog).show(ml_application); + except + result:= mr_exception; + application.handleexception; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifilink.pas b/mseide-msegui/lib/common/ifi/mseifilink.pas new file mode 100644 index 0000000..f582f0d --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifilink.pas @@ -0,0 +1,3936 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseifilink; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseclasses,mseifiglob,mseifi,msearrayprops,mseapplication, + mseact,mseinterfaces, + mseevent,mseglob,msestrings,msetypes,msedatalist,msegraphutils,typinfo, + mseeditglob; + +type + formlinkoptionty = (flo_useclientchannel); + formlinkoptionsty = set of formlinkoptionty; +const + defaultformlinkoptions = [flo_useclientchannel]; +type + tmodulelinkarrayprop = class; + + tmodulelinkprop = class(townedeventpersistent) + private + fprop: tmodulelinkarrayprop; + fname: ansistring; + ftag: integer; + protected + procedure inititemheader(out arec: string; + const akind: ifireckindty; const asequence: sequencety; + const datasize: integer; + out datapo: pchar); virtual; + public + property prop: tmodulelinkarrayprop read fprop; + published + property name: ansistring read fname write fname; + property tag: integer read ftag write ftag default 0; + end; + modulelinkpropclassty = class of tmodulelinkprop; + + tcustommodulelink = class; + + tmodulelinkarrayprop = class(tpersistentarrayprop) + private + fowner: tcustommodulelink; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + function getitemclass: modulelinkpropclassty; virtual; abstract; + public + constructor create(const aowner: tcustommodulelink); + function finditem(const aname: string): tmodulelinkprop; + function byname(const aname: string): tmodulelinkprop; + property owner: tcustommodulelink read fowner; + end; + + tlinkaction = class(tmodulelinkprop) + private + faction: tcustomaction; + procedure setaction(const avalue: tcustomaction); + protected + public + destructor destroy; override; + published + property action: tcustomaction read faction write setaction; + end; + + trxlinkaction = class; + + ifiexecuteeventty = procedure(const sender: trxlinkaction; const atag: integer; + const aparams: variant) of object; + + trxlinkaction = class(tlinkaction) + private + fonexecute: ifiexecuteeventty; + published + property onexecute: ifiexecuteeventty read fonexecute write fonexecute; + //sender = item, avalue = tx tag + end; + + iifitxaction = interface(inullinterface)[miid_iifitxaction] + procedure txactionfired(var adata: ansistring; var adatapo: pchar); + end; + + ttxlinkaction = class(tlinkaction) + private + fificomp: tcomponent; + fificompintf: iifitxaction; + procedure setificomp(const avalue: tcomponent); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + procedure execute; + published + property ificomp: tcomponent read fificomp write setificomp; + end; + + tlinkactions = class(tmodulelinkarrayprop) + private + protected + public + end; + + trxlinkactions = class(tlinkactions) + private + fonexecute: ifiexecuteeventty; + function getitems(const index: integer): trxlinkaction; + protected + function getitemclass: modulelinkpropclassty; override; + public + constructor create(const aowner: tcustommodulelink); + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): trxlinkaction; + property items[const index: integer]: trxlinkaction read getitems; default; + published + property onexecute: ifiexecuteeventty read fonexecute write fonexecute; + //sender = item, avalue = tx tag + end; + + ttxlinkactions = class; + + ttxactiondestroyhandler = class(tcomponent) + private + fowneractions: ttxlinkactions; + protected + procedure notification(acomponent: tcomponent; + operation: toperation); override; + public + constructor create(aowner: ttxlinkactions); reintroduce; + end; + + ttxlinkactions = class(tlinkactions) + private + fdestroyhandler: ttxactiondestroyhandler; + function getitems(const index: integer): ttxlinkaction; + protected + function getitemclass: modulelinkpropclassty; override; + public + constructor create(const aowner: tcustommodulelink); + destructor destroy; override; + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): ttxlinkaction; + property items[const index: integer]: ttxlinkaction read getitems; default; + end; + + tlinkmodule = class(tmodulelinkprop) + end; + + ttxlinkmodule = class(tlinkmodule) + private + fmoduleclassname: string; + fmoduleparentclassname: string; + public + procedure sendmodule; + procedure close; + published + property moduleclassname: string read fmoduleclassname write fmoduleclassname; + property moduleparentclassname: string read fmoduleparentclassname + write fmoduleparentclassname; + end; + + ttxlinkmodules = class(tmodulelinkarrayprop) + private + function getitems(const index: integer): ttxlinkmodule; + protected + function getitemclass: modulelinkpropclassty; override; + public + constructor create(const aowner: tcustommodulelink); + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): ttxlinkmodule; + property items[const index: integer]: ttxlinkmodule read getitems; default; + end; + + trxlinkmodule = class; + rxlinkmoduleeventty = procedure(sender: trxlinkmodule) of object; + + rxlinkoptionty = (rlo_closeconnonfree); + rxlinkoptionsty = set of rxlinkoptionty; + + trxlinkmodule = class(tlinkaction) + private + fmodule: tmsecomponent; + fcommandintf: iificommand; + fonmodulereceived: rxlinkmoduleeventty; + fsequence: sequencety; + foptions: rxlinkoptionsty; + protected + procedure objevent(const sender: iobjectlink; + const event: objecteventty); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure domodulereceived; + public + procedure requestmodule; + property module: tmsecomponent read fmodule; + published + property onmodulereceived: rxlinkmoduleeventty read fonmodulereceived + write fonmodulereceived; + property options: rxlinkoptionsty read foptions write foptions default []; + end; + + trxlinkmodules = class(tmodulelinkarrayprop) + private + function getitems(const index: integer): trxlinkmodule; + protected + function finditem(const asequence: sequencety): trxlinkmodule; overload; + function getitemclass: modulelinkpropclassty; override; + public + constructor create(const aowner: tcustommodulelink); + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): trxlinkmodule; + property items[const index: integer]: trxlinkmodule read getitems; default; + end; + + tvaluelink = class; + + propertychangedeventty = procedure(const sender: tvaluelink; + const atag: integer; const apropertyname: string) of object; + widgetstatechangedeventty = procedure(const sender: tvaluelink; + const atag: integer; const astate: ifiwidgetstatesty) of object; + modalresulteventty = procedure(const sender: tvaluelink; + const atag: integer; const amodalresult: modalresultty) of object; + +//todo: beginupdate/endupdate, use tifivaluelinkcontroller + + tvaluelink = class(tmodulelinkprop) + private + fint64value: int64; + fdoublevalue: double; + fmsestringvalue: msestring; +// fansistringvalue: ansistring; + fdatakind: ifidatakindty; + fonpropertychanged: propertychangedeventty; + fonwidgetstatechanged: widgetstatechangedeventty; + fonmodalresult: modalresulteventty; + procedure checkdatakind(const akind: ifidatakindty); + function getasinteger: integer; + procedure setasinteger(const avalue: integer); + function getaslargeint: int64; + procedure setaslargeint(const avalue: int64); + function getasfloat: double; + procedure setasfloat(const avalue: double); + function getasmsestring: msestring; + procedure setasmsestring(const avalue: msestring); + function getasansistring: ansistring; + procedure setasansistring(const avalue: ansistring); + procedure setenabled(const avalue: boolean); + procedure setvisible(const avalue: boolean); + protected + procedure setdata(const adata: pifidataty; const aname: ansistring); virtual; + procedure initpropertyrecord(out arec: string; const apropertyname: string; + const akind: ifidatakindty; const datasize: integer; out datapo: pchar); + procedure sendvalue(const aname: string; const avalue: int64); overload; + procedure sendvalue(const aname: string; const avalue: double); overload; + procedure sendvalue(const aname: string; const avalue: msestring); overload; + procedure sendvalue(const aname: string; const avalue: ansistring); overload; + procedure sendcommand(const acommand: ifiwidgetcommandty); + public + procedure sendproperty(const aname: string; const avalue: boolean); overload; + procedure sendproperty(const aname: string; const avalue: integer); overload; + procedure sendproperty(const aname: string; const avalue: colorty); overload; + procedure sendproperty(const aname: string; const avalue: int64); overload; + procedure sendproperty(const aname: string; const avalue: string); overload; + procedure sendproperty(const aname: string; const avalue: msestring); overload; + procedure sendproperty(const aname: string; const avalue: realty); overload; + procedure sendproperty(const aname: string; const avalue: currency); overload; + + property asinteger: integer read getasinteger write setasinteger; + property aslargeint: int64 read getaslargeint write setaslargeint; + property asfloat: double read getasfloat write setasfloat; + property asmsestring: msestring read getasmsestring write setasmsestring; + property asstring: string read getasansistring write setasansistring; + property enabled: boolean write setenabled; + property visible: boolean write setvisible; + published + property onpropertychanged: propertychangedeventty read fonpropertychanged + write fonpropertychanged; + property onwidgetstatechanged: widgetstatechangedeventty + read fonwidgetstatechanged write fonwidgetstatechanged; + property onmodalresult: modalresulteventty read fonmodalresult + write fonmodalresult; + end; + + tvaluelinks = class(tmodulelinkarrayprop) + private + function getitems(const index: integer): tvaluelink; + protected + function getitemclass: modulelinkpropclassty; override; + public + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): tvaluelink; + property items[const index: integer]: tvaluelink read getitems; default; + end; + + tcustomvaluecomponentlink = class(tvaluelink) + private + procedure setcomponent(const avalue: tmsecomponent); + procedure checkcomponent; + protected + fcomponent: tmsecomponent; + fintf: iificlient; + fvalueproperty: ppropinfo; + fupdatelock: integer; + procedure setdata(const adata: pifidataty; const aname: ansistring); override; + procedure sendvalue(const aproperty: ppropinfo); overload; + procedure sendstate(const astate: ifiwidgetstatesty); + procedure sendmodalresult(const amodalresult: modalresultty); + public + procedure sendvalue(const aname: string; const avalue: colorty); overload; + procedure sendproperties; + property component: tmsecomponent read fcomponent write setcomponent; + end; + + tvaluecomponentlink = class(tcustomvaluecomponentlink) + published + property component; + end; + + tvaluecomponentlinks = class(tvaluelinks) + private + function getitems(const index: integer): tvaluecomponentlink; + protected + function getitemclass: modulelinkpropclassty; override; + public + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): tvaluecomponentlink; + property items[const index: integer]: tvaluecomponentlink read getitems; default; + end; + + iifimodulelink = interface(inullinterface)[miid_iifimodulelink] + procedure connectmodule(const sender: tcustommodulelink); + end; + + tcustommodulelink = class(tifiiolinkcomponent,iifiserver,iifimodulelink) + private + factionsrx: trxlinkactions; + factionstx: ttxlinkactions; + fmodulestx: ttxlinkmodules; + fmodulesrx: trxlinkmodules; + foptions: formlinkoptionsty; + flinkname: string; + procedure setactionsrx(const avalue: trxlinkactions); + procedure setactionstx(const avalue: ttxlinkactions); + procedure setmodulestx(const avalue: ttxlinkmodules); + procedure setmodulesrx(const avalue: trxlinkmodules); + procedure setvalues(const avalue: tvaluelinks); + procedure setvaluecomponents(const avalue: tvaluecomponentlinks); + protected + fvalues: tvaluelinks; + fvaluecomponents: tvaluecomponentlinks; + function hasconnection: boolean; + function encodemodulecommand(const acommand: ificommandcodety; + const atag: integer; const aname: string): string; + procedure closemodule(const atag: integer; const aname: string); + function encodeactionfired(const atag: integer; const aname: string; + out adatapo: pchar): string; + procedure actionfired(const sender: tlinkaction; + const acompintf: iifitxaction); virtual; + function actionreceived(const adata: pifirecty; var adatapo: pchar; + const atag: integer; const aname: string):boolean; + function requestmodulereceived(const atag: integer; const aname: string; + const asequence: sequencety): boolean; + function modulecommandreceived(const atag: integer; const aname: string; + const adata: pmodulecommanddataty): boolean; + function moduledatareceived(const atag: integer; const aname: string; + const asequence: sequencety; + const adata: pmoduledatadataty): boolean; + procedure moduleloaded(const sender: tmsecomponent); + function propertychangereceived(const atag: integer; const aname: string; + const apropertyname: string; const adata: pifidataty): boolean; + + procedure objectevent(const sender: tobject; const event: objecteventty); override; + function processdataitem(const adata: pifirecty; var adatapo: pchar; + const atag: integer; const aname: string): boolean; virtual; + //true if handled + function processdata(const adata: pifirecty): boolean; + //true if handled + function senddata(const adata: ansistring): sequencety; + //returns sequence number + procedure receiveevent(const event: tobjectevent); override; + //iifiserver + procedure execute(const sender: iificlient); virtual; + procedure valuechanged(const sender: iificlient); virtual; + procedure statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); virtual; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); + procedure dataentered(const sender: iificlient; const arow: integer); + procedure updateoptionsedit(var avalue: optionseditty); + procedure closequery(const sender: iificlient; + var amodalresult: modalresultty); + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); virtual; + //imodulelink + procedure connectmodule(const sender: tcustommodulelink); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure updatecomponent(const anamepath: ansistring; + const aobjecttext: ansistring); + property linkname: string read flinkname write flinkname; + property actionsrx: trxlinkactions read factionsrx write setactionsrx; + property actionstx: ttxlinkactions read factionstx write setactionstx; + property modulesrx: trxlinkmodules read fmodulesrx write setmodulesrx; + property modulestx: ttxlinkmodules read fmodulestx write setmodulestx; + property valuecomponents: tvaluecomponentlinks read fvaluecomponents + write setvaluecomponents; + property values: tvaluelinks read fvalues write setvalues; + property options: formlinkoptionsty read foptions write foptions + default defaultformlinkoptions; + end; + + tmodulelink = class(tcustommodulelink) + published + property linkname; + property actionsrx; + property actionstx; + property modulesrx; + property modulestx; + property values; + property valuecomponents; + property channel; + property options; + end; + + ifirxoptionty = (irxo_useclientchannel,irxo_postecho); + ifirxoptionsty = set of ifirxoptionty; + +const + defaultifirxoptions = [irxo_useclientchannel]; + defaultifirxtimeout = 10000000; //10 second + +type + tificontroller = class(tactivatorcontroller,iifimodulelink) + private + fchannel: tcustomiochannel; + flinkname: string; + ftag: integer; + fdefaulttimeout: integer; + procedure setchannel(const avalue: tcustomiochannel); + protected + foptions: ifirxoptionsty; + procedure objectevent(const sender: tobject; const event: objecteventty); + override; + function senddata(const adata: ansistring; + const asequence: sequencety = 0): sequencety; + function senddataandwait(const adata: ansistring; + out asequence: sequencety; atimeoutus: integer = 0): boolean; + function senditem(const kind: ifireckindty; + const data: array of ansistring): sequencety; + //returns sequence number + procedure inititemheader(out arec: string; + const akind: ifireckindty; const asequence: sequencety; + const datasize: integer; out datapo: pchar); + procedure processdata(const adata: pifirecty; var adatapo: pchar); + virtual; abstract; + function getifireckinds: ifireckindsty; virtual; + //iifimodulelink + procedure connectmodule(const sender: tcustommodulelink); + public + constructor create(const aowner: tcomponent; const aintf: iactivatorclient); + function cansend: boolean; + published + property channel: tcustomiochannel read fchannel write setchannel; + property linkname: string read flinkname write flinkname; + property tag: integer read ftag write ftag default 0; + property options: ifirxoptionsty read foptions write foptions + default defaultifirxoptions; + property timeoutus: integer read fdefaulttimeout write fdefaulttimeout + default defaultifirxtimeout; + end; +{ + tifirxcontroller = class(tificontroller) + end; + tifitxcontroller = class(tificontroller) + end; +} + tifidatacol = class; + + ifidatacolchangeeventty = procedure(const sender: tifidatacol; + const aindex: integer) of object; + + ifidatacolstatety = (icos_selected); + ifidatacolstatesty = set of ifidatacolstatety; + + tifidatacol = class(tindexpersistent) + private + fdata: tdatalist; + fdatakind: ifidatakindty; + fname: ansistring; + fonchange: ifidatacolchangeeventty; + fstate: ifidatacolstatesty; + fselectedrow: integer; + fselectlock: integer; + procedure setdatakind(const avalue: ifidatakindty); + function getdatalist: tdatalist; + function getasinteger(const aindex: integer): integer; + procedure setasinteger(const aindex: integer; const avalue: integer); + function getasint64(const aindex: integer): int64; + procedure setasint64(const aindex: integer; const avalue: int64); + function getascurrency(const aindex: integer): currency; + procedure setascurrency(const aindex: integer; const avalue: currency); + function getasreal(const aindex: integer): real; + procedure setasreal(const aindex: integer; const avalue: real); + function getasmsestring(const aindex: integer): msestring; + procedure setasmsestring(const aindex: integer; const avalue: msestring); + function getasbytes(const aindex: integer): ansistring; + procedure setasbytes(const aindex: integer; const avalue: ansistring); + function getasmsestringint(const aindex: integer): msestringintty; + procedure setasmsestringint(const aindex: integer; const avalue: msestringintty); + function getasmsestringinti(const aindex: integer): integer; + procedure setasmsestringinti(const aindex: integer; const avalue: integer); + function getasmsestringints(const aindex: integer): msestring; + procedure setasmsestringints(const aindex: integer; const avalue: msestring); + function getselected(row: integer): boolean; + procedure setselected(row: integer; const avalue: boolean); + function getmerged(const row: integer): boolean; virtual; + procedure setmerged(const row: integer; const avalue: boolean); virtual; + function getasrealint(const aindex: integer): realintty; + procedure setasrealint(const aindex: integer; const avalue: realintty); + function getasrealintr(const aindex: integer): realty; + procedure setasrealintr(const aindex: integer; const avalue: realty); + function getasrealinti(const aindex: integer): integer; + procedure setasrealinti(const aindex: integer; const avalue: integer); + protected + procedure freedatalist; + procedure checkdatalist; overload; + procedure checkdatalist(const akind: ifidatakindty); overload; + procedure dochange(const sender: tdatalist; const aindex: integer); + procedure doselectionchanged; + procedure beginselect; + procedure endselect; + procedure datachange(const aindex: integer); + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); override; + destructor destroy; override; + property datalist: tdatalist read getdatalist; + + property asinteger[const aindex: integer]: integer read getasinteger + write setasinteger; + property asint64[const aindex: integer]: int64 read getasint64 + write setasint64; + property ascurrency[const aindex: integer]: currency read getascurrency + write setascurrency; + property asreal[const aindex: integer]: real read getasreal + write setasreal; + property asmsestring[const aindex: integer]: msestring read getasmsestring + write setasmsestring; + property asmsestringint[const aindex: integer]: msestringintty + read getasmsestringint write setasmsestringint; + property asmsestringinti[const aindex: integer]: integer + read getasmsestringinti write setasmsestringinti; + property asmsestringints[const aindex: integer]: msestring + read getasmsestringints write setasmsestringints; + property asrealint[const aindex: integer]: realintty read getasrealint write + setasrealint; + property asrealintr[const aindex: integer]: realty read getasrealintr write + setasrealintr; + property asrealinti[const aindex: integer]: integer read getasrealinti write + setasrealinti; + property asbytes[const aindex: integer]: ansistring read getasbytes + write setasbytes; + property merged[const row: integer]: boolean read getmerged write setmerged; + property selected[row: integer]: boolean read getselected write setselected; + published + property datakind: ifidatakindty read fdatakind write setdatakind + default idk_none; + property name: ansistring read fname write fname; + property onchange: ifidatacolchangeeventty read fonchange write fonchange; + end; + + ttxdatagrid = class; + tifirowstatelist = class(tcustomrowstatelist) + protected + procedure sethidden(const index: integer; const avalue: boolean); override; + procedure setfoldlevel(const index: integer; const avalue: byte); + procedure setfoldissum(const index: integer; const avalue: boolean); override; + public + property hidden[const index: integer]: boolean read gethidden write sethidden; + property foldlevel[const index: integer]: byte read getfoldlevel + write setfoldlevel; //0..63 + property foldissum[const index: integer]: boolean read getfoldissum + write setfoldissum; + end; + + tifidatacols = class(tindexpersistentarrayprop) + private + frowstate: tifirowstatelist; + fselectedrow: integer; //-1 none, -2 more than one + function getcols(const index: integer): tifidatacol; + procedure setcols(const index: integer; const avalue: tifidatacol); + function getselectedcells: gridcoordarty; + procedure setselectedcells(const avalue: gridcoordarty); + function Getselected(const cell: gridcoordty): boolean; + procedure Setselected(const cell: gridcoordty; const avalue: boolean); + procedure beginselect; + procedure endselect; + public + constructor create(const aowner: ttxdatagrid); reintroduce; + destructor destroy; override; + class function getitemclasstype: persistentclassty; override; + function colbyname(const aname: ansistring): tifidatacol; + function datalistbyname(const aname: ansistring): tdatalist; + + procedure clearselection; + function hasselection: boolean; + function selectedcellcount: integer; + function hascolselection: boolean; + property selectedcells: gridcoordarty read getselectedcells write setselectedcells; + property selected[const cell: gridcoordty]: boolean read Getselected write Setselected; + //col < 0 and row < 0 -> whole grid, col < 0 -> whole col, + //row = < 0 -> whole row + procedure setselectedrange(const rect: gridrectty; const value: boolean); overload; + procedure setselectedrange(const start,stop: gridcoordty; + const value: boolean); overload; + + procedure mergecols(const arow: integer; const astart: longword = 0; + const acount: longword = bigint); + procedure unmergecols(const arow: integer = invalidaxis); + //invalidaxis = all + + property rowstate: tifirowstatelist read frowstate; + property cols[const index: integer]: tifidatacol read getcols write setcols; + default; + end; + + ifigridoptionty = ( + igo_state, //send the whole gridstate after endupdate + igo_rowenter,igo_rowmove,igo_rowdelete, + igo_rowinsert,igo_rowstate,igo_selection,igo_coldata); + ifigridoptionsty = set of ifigridoptionty; + + tifigridcontroller = class(tificontroller) + private + fupdating: integer; + protected + foptionstx: ifigridoptionsty; + foptionsrx: ifigridoptionsty; + fdatasequence: sequencety; + fcommandlock: integer; + function encodegriddata(const asequence: sequencety): ansistring; + virtual; abstract; + function getifireckinds: ifireckindsty; override; + public + function cancommandsend(const akind: ifigridoptionty): boolean; + procedure beginupdate; + procedure endupdate; + procedure sendstate; + published + property optionstx: ifigridoptionsty read foptionstx + write foptionstx default[]; + property optionsrx: ifigridoptionsty read foptionsrx + write foptionsrx default[]; + + end; + + ttxdatagridcontroller = class(tifigridcontroller) + private + protected +// function getifireckinds: ifireckindsty; override; + procedure setowneractive(const avalue: boolean); override; + procedure processdata(const adata: pifirecty; var adatapo: pchar); + override; + function encodegriddata(const asequence: sequencety): ansistring; override; + public + constructor create(const aowner: ttxdatagrid; const aintf: iactivatorclient); + end; + + ifigriditemeventty = procedure(const sender: ttxdatagrid; + const aindex: integer) of object; + ifigridblockeventty = procedure(const sender: ttxdatagrid; + const aindex: integer; const acount: integer) of object; + ifigridblockmovedeventty = procedure(const sender: ttxdatagrid; + const fromindex,toindex,acount: integer) of object; + ifigrideventty = procedure(const sender: ttxdatagrid) of object; + + ttxdatagrid = class(tactcomponent) + private + fifi: ttxdatagridcontroller; + fdatacols: tifidatacols; + frowcount: integer; + frow: integer; + fonrowsdeleted: ifigridblockeventty; + fonrowsinserted: ifigridblockeventty; + fonrowsmoved: ifigridblockmovedeventty; + fonrowindexchanged: ifigrideventty; + fonrowstatechanged: ifigriditemeventty; + fonbeforeopen: ifigrideventty; + procedure rowstatechanged(const aindex: integer); + procedure setifi(const avalue: ttxdatagridcontroller); + procedure setdatacols(const avalue: tifidatacols); + procedure setrowcount(const avalue: integer); + function getrowhigh: integer; + procedure setrow(const avalue: integer); + function getrowcolorstate(index: integer): rowstatenumty; + procedure setrowcolorstate(index: integer; const avalue: rowstatenumty); + function getrowfontstate(index: integer): rowstatenumty; + procedure setrowfontstate(index: integer; const avalue: rowstatenumty); + function getrowreadonlystate(const index: integer): boolean; + procedure setrowreadonlystate(const index: integer; const avalue: boolean); + function getrowhidden(const index: integer): boolean; + procedure setrowhidden(const index: integer; const avalue: boolean); + function getrowfoldlevel(const index: integer): byte; + procedure setrowfoldlevel(const index: integer; const avalue: byte); + function getrowfoldissum(const index: integer): boolean; + procedure setrowfoldissum(const index: integer; const avalue: boolean); + protected + procedure setselected(const cell: gridcoordty; const avalue: boolean); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure beginupdate; + procedure endupdate; + procedure clear; + procedure moverow(const curindex,newindex: integer; const count: integer = 1); + procedure insertrow(index: integer; count: integer = 1); + procedure deleterow(index: integer; count: integer = 1); + property rowhigh: integer read getrowhigh; + property row: integer read frow write setrow; + property rowcolorstate[index: integer]: rowstatenumty read getrowcolorstate + write setrowcolorstate; //default = -1 + property rowfontstate[index: integer]: rowstatenumty read getrowfontstate + write setrowfontstate; //default = -1 + property rowreadonlystate[const index: integer]: boolean read getrowreadonlystate + write setrowreadonlystate; + property rowhidden[const index: integer]: boolean read getrowhidden + write setrowhidden; + property rowfoldlevel[const index: integer]: byte read getrowfoldlevel + write setrowfoldlevel; + property rowfoldissum[const index: integer]: boolean read getrowfoldissum + write setrowfoldissum; + published + property ifi: ttxdatagridcontroller read fifi write setifi; + property datacols: tifidatacols read fdatacols write setdatacols; + property rowcount: integer read frowcount write setrowcount default 0; + property onrowsdeleted: ifigridblockeventty read fonrowsdeleted + write fonrowsdeleted; + property onrowsinserted: ifigridblockeventty read fonrowsinserted + write fonrowsinserted; + property onrowsmoved: ifigridblockmovedeventty read fonrowsmoved + write fonrowsmoved; + property onrowindexchanged: ifigrideventty read fonrowindexchanged + write fonrowindexchanged; + property onrowstatechanged: ifigriditemeventty read fonrowstatechanged + write fonrowstatechanged; + property onbeforeopen: ifigrideventty read fonbeforeopen write fonbeforeopen; + end; + +function ifidatatodatalist(const akind: listdatatypety; const arowcount: integer; + const adata: pchar; const adatalist: tdatalist): integer; overload; + //returns datasize +function ifidatatodatalist(const akind: listdatatypety; const arowcount: integer; + const adata: pchar; const adatalist: subdatainfoty): integer; overload; + //returns datasize +function datalisttoifidata(const adatalist: tdatalist): integer; overload; +procedure datalisttoifidata(const adatalist: tdatalist; + var dest: pchar); overload; + +function encodegridcommanddata(const akind: gridcommandkindty; + const asource,adest,acount: integer): string; +function decodegridcommanddata(const adata: pchar; out akind: gridcommandkindty; + out asource,adest,acount: integer): integer; +function encodecolchangedata(const acolname: string; const arow: integer; + const alist: tdatalist): string; overload; +function encodecolchangedata(const acolname: string; const arow: integer; + const alist: tcustomrowstatelist; + const subindex: rowstatememberty): string; overload; +function encoderowstatedata(const arow: integer; + const astate: rowstatety): string; overload; +function encoderowstatedata(const arow: integer; + const astate: rowstatecolmergety): string; overload; +function encoderowstatedata(const arow: integer; + const astate: rowstaterowheightty): string; overload; +function encodeselectiondata(const acell: gridcoordty; + const avalue: boolean): string; + +implementation +uses + sysutils,msestream,msesysutils,msetmpmodules,msebits,mseobjecttext, + msestreaming{$ifndef FPC},classes_del{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustomrowstatelist1 = class(tcustomrowstatelist); + + tmoduledataevent = class(tstringobjectevent) + protected + fmodulelink: trxlinkmodule; + fmoduledata: pmoduledatadataty; + public + constructor create(const adata: ansistring; const dest: ievent; + const amodulelink: trxlinkmodule; const amoduledata: pmoduledatadataty); + end; + +function encodegridcommanddata(const akind: gridcommandkindty; + const asource,adest,acount: integer): string; +begin + result:= nullstring(sizeof(gridcommanddatadataty)); + with pgridcommanddatadataty(result)^ do begin + kind:= akind; + dest:= adest; + source:= asource; + count:= acount; + end; +end; + +function decodegridcommanddata(const adata: pchar; out akind: gridcommandkindty; + out asource,adest,acount: integer): integer; +begin + result:= sizeof(gridcommanddatadataty); + with pgridcommanddatadataty(adata)^ do begin + akind:= kind; + adest:= dest; + asource:= source; + acount:= count; + end; +end; + +function encodecolchangedata(const acolname: string; const arow: integer; + const alist: tdatalist): string; +begin + result:= encodeifidata(alist,arow,sizeof(colitemheaderty)+length(acolname)); + if result <> '' then begin + with pcolitemdataty(result)^.header do begin + row:= arow; + stringtoifiname(acolname,@name); + end; + end; +end; + +function encodecolchangedata(const acolname: string; const arow: integer; + const alist: tcustomrowstatelist; + const subindex: rowstatememberty): string; +var + int1: integer; +begin + result:= ''; + int1:= sizeof(colitemheaderty)+length(acolname); + case subindex of + rsm_select: begin + result:= encodeifidata(alist.selected[arow],int1); + end; + rsm_color: begin + result:= encodeifidata(alist.color[arow],int1); + end; + rsm_font: begin + result:= encodeifidata(alist.font[arow],int1); + end; + rsm_readonly: begin + result:= encodeifidata(alist.readonly[arow],int1); + end; + rsm_foldlevel: begin + result:= encodeifidata(alist.foldlevel[arow],int1); + end; + rsm_foldissum: begin + result:= encodeifidata(alist.foldissum[arow],int1); + end; + rsm_hidden: begin + result:= encodeifidata(alist.foldissum[arow],int1); + end; + rsm_merged: begin + if alist.infolevel >= ril_colmerge then begin + result:= encodeifidata(alist.merged[arow],int1); + end; + end; + rsm_height: begin + if alist.infolevel >= ril_rowheight then begin + result:= encodeifidata(alist.height[arow],int1); + end; + end; + end; + if result <> '' then begin + with pcolitemdataty(result)^.header do begin + row:= arow; + stringtoifiname(acolname,@name); + end; + end; +end; + +function encoderowstatedata(const arow: integer; + const astate: rowstatety): string; +begin + result:= encodeifidata(astate,sizeof(rowstateheaderty)); + with prowstatedataty(result)^.header do begin + row:= arow; + end; +end; + +function encoderowstatedata(const arow: integer; + const astate: rowstatecolmergety): string; +begin + result:= encodeifidata(astate,sizeof(rowstateheaderty)); + with prowstatedataty(result)^.header do begin + row:= arow; + end; +end; + +function encoderowstatedata(const arow: integer; + const astate: rowstaterowheightty): string; +begin + result:= encodeifidata(astate,sizeof(rowstateheaderty)); + with prowstatedataty(result)^.header do begin + row:= arow; + end; +end; + +function encodeselectiondata(const acell: gridcoordty; + const avalue: boolean): string; +var + sel1: selectdataty; +begin + fillchar(sel1,sizeof(sel1),0); + sel1.col:= acell.col; + sel1.row:= acell.row; + sel1.select:= avalue; + result:= encodeifidata(sel1); +end; + +{ tmodulelinkprop } + +procedure tmodulelinkprop.inititemheader(out arec: string; + const akind: ifireckindty; const asequence: sequencety; + const datasize: integer; out datapo: pchar); +begin + mseifi.inititemheader(ftag,fname,arec,akind,asequence,datasize,datapo); +end; + +{ tlinkaction } + +destructor tlinkaction.destroy; +begin + action:= nil; + inherited; +end; + +procedure tlinkaction.setaction(const avalue: tcustomaction); +begin + setlinkedvar(avalue,tmsecomponent(faction)); +end; + +{ trxlinkaction } + +{ ttxlinkaction } + +procedure ttxlinkaction.execute; +begin + tcustommodulelink(fowner).actionfired(self,fificompintf); +end; + +procedure ttxlinkaction.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_fired) and (sender = faction) then begin + execute; + end; +end; + +procedure ttxlinkaction.setificomp(const avalue: tcomponent); +begin + if fificomp <> nil then begin + ttxlinkactions(prop).fdestroyhandler.removefreenotification(fificomp); + end; + fificomp:= avalue; + if fificomp <> nil then begin + ttxlinkactions(prop).fdestroyhandler.freenotification(fificomp); + mseclasses.getcorbainterface(fificomp,typeinfo(iifitxaction),fificompintf); + end + else begin + fificompintf:= nil; + end; +end; + +{ tmodulelinkarrayprop } + +constructor tmodulelinkarrayprop.create(const aowner: tcustommodulelink); +begin + fowner:= aowner; + inherited create(getitemclass); +end; + +procedure tmodulelinkarrayprop.createitem(const index: integer; var item: tpersistent); +begin + item:= modulelinkpropclassty(fitemclasstype).create(fowner); + tmodulelinkprop(item).fprop:= self; +end; + +function tmodulelinkarrayprop.finditem(const aname: string): tmodulelinkprop; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fitems) do begin + if tmodulelinkprop(fitems[int1]).fname = aname then begin + result:= tmodulelinkprop(fitems[int1]); + exit; + end; + end; +end; + +function tmodulelinkarrayprop.byname(const aname: string): tmodulelinkprop; +begin + result:= finditem(aname); + if result = nil then begin + raise exception.create(fowner.name+': array property "'+aname+'" not found.'); + end; +end; + +{ trxlinkactions } + +constructor trxlinkactions.create(const aowner: tcustommodulelink); +begin + inherited create(aowner); +end; + +class function trxlinkactions.getitemclasstype: persistentclassty; +begin + result:= trxlinkaction; +end; + +function trxlinkactions.getitems(const index: integer): trxlinkaction; +begin + result:= trxlinkaction(inherited getitems(index)); +end; + +function trxlinkactions.byname(const aname: string): trxlinkaction; +begin + result:= trxlinkaction(inherited byname(aname)); +end; + +function trxlinkactions.getitemclass: modulelinkpropclassty; +begin + result:= trxlinkaction; +end; + +{ ttxactiondestroyhandler } + +constructor ttxactiondestroyhandler.create(aowner: ttxlinkactions); +begin + fowneractions:= aowner; + inherited create(nil); +end; + +procedure ttxactiondestroyhandler.notification(acomponent: tcomponent; + operation: toperation); +var + int1: integer; +begin + inherited; + if operation = opremove then begin + with fowneractions do begin + for int1:= 0 to high(fitems) do begin + with ttxlinkaction(fitems[int1]) do begin + if acomponent = fificomp then begin + fificomp:= nil; + fificompintf:= nil; + end; + end; + end; + end; + end; +end; + +{ ttxlinkactions } + +constructor ttxlinkactions.create(const aowner: tcustommodulelink); +begin + fdestroyhandler:= ttxactiondestroyhandler.create(self); + inherited create(aowner); +end; + +destructor ttxlinkactions.destroy; +begin + inherited; + fdestroyhandler.destroy; +end; + +class function ttxlinkactions.getitemclasstype: persistentclassty; +begin + result:= ttxlinkaction; +end; + +function ttxlinkactions.getitems(const index: integer): ttxlinkaction; +begin + result:= ttxlinkaction(inherited getitems(index)); +end; + +function ttxlinkactions.byname(const aname: string): ttxlinkaction; +begin + result:= ttxlinkaction(inherited byname(aname)); +end; + +function ttxlinkactions.getitemclass: modulelinkpropclassty; +begin + result:= ttxlinkaction; +end; + +{ ttxlinkmodules } + +constructor ttxlinkmodules.create(const aowner: tcustommodulelink); +begin + inherited create(aowner); +end; + +class function ttxlinkmodules.getitemclasstype: persistentclassty; +begin + result:= ttxlinkmodule; +end; + +function ttxlinkmodules.getitems(const index: integer): ttxlinkmodule; +begin + result:= ttxlinkmodule(inherited getitems(index)); +end; + +function ttxlinkmodules.byname(const aname: string): ttxlinkmodule; +begin + result:= ttxlinkmodule(inherited byname(aname)); +end; + +function ttxlinkmodules.getitemclass: modulelinkpropclassty; +begin + result:= ttxlinkmodule; +end; + +{ trxlinkmodule } + +procedure trxlinkmodule.requestmodule; +var + str1: string; + po1: pchar; +begin + inititemheader(str1,ik_requestmodule,0,0,po1); + fsequence:= tcustommodulelink(fowner).senddata(str1); +end; + +procedure trxlinkmodule.objevent(const sender: iobjectlink; + const event: objecteventty); +var + conn1: tcustomiochannel; +begin + if (event = oe_destroyed) and (rlo_closeconnonfree in foptions) and + (sender.getinstance = fmodule) then begin + conn1:= tcustommodulelink(fowner).channel; + if conn1 <> nil then begin + conn1.active:= false; + end; + end; + inherited; +end; + +procedure trxlinkmodule.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_fired) and (sender = faction) then begin + requestmodule; + end; +end; + +procedure trxlinkmodule.domodulereceived; +begin + if tcustommodulelink(fowner).canevent(tmethod(fonmodulereceived)) then begin + fonmodulereceived(self); + end; +end; + +{ trxlinkmodules } + +constructor trxlinkmodules.create(const aowner: tcustommodulelink); +begin + inherited create(aowner); +end; + +class function trxlinkmodules.getitemclasstype: persistentclassty; +begin + result:= trxlinkmodule; +end; + +function trxlinkmodules.getitems(const index: integer): trxlinkmodule; +begin + result:= trxlinkmodule(inherited getitems(index)); +end; + +function trxlinkmodules.byname(const aname: string): trxlinkmodule; +begin + result:= trxlinkmodule(inherited byname(aname)); +end; + +function trxlinkmodules.finditem(const asequence: sequencety): trxlinkmodule; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + if trxlinkmodule(fitems[int1]).fsequence = asequence then begin + result:= trxlinkmodule(fitems[int1]); + exit; + end; + end; + result:= nil; +end; + +function trxlinkmodules.getitemclass: modulelinkpropclassty; +begin + result:= trxlinkmodule; +end; + +{ tvaluelink } + +procedure tvaluelink.sendvalue(const aname: string; const avalue: int64); +var + str1: string; + po1: pchar; +begin + initpropertyrecord(str1,aname,idk_int64,0,po1); + pint64(po1)^:= avalue; + tcustommodulelink(fowner).senddata(str1); +end; + +procedure tvaluelink.sendvalue(const aname: string; const avalue: double); +var + str1: string; + po1: pchar; +begin + initpropertyrecord(str1,aname,idk_real,0,po1); + pdouble(po1)^:= avalue; + tcustommodulelink(fowner).senddata(str1); +end; + +procedure tvaluelink.sendvalue(const aname: string; const avalue: msestring); +var + str1,str2: string; + po1: pchar; +begin + str2:= stringtoutf8ansi(avalue); + initpropertyrecord(str1,aname,idk_msestring,length(str2),po1); + stringtoifiname(str2,pifinamety(po1)); + tcustommodulelink(fowner).senddata(str1); +end; + +procedure tvaluelink.sendvalue(const aname: string; const avalue: ansistring); +begin + sendvalue(aname,msestring(avalue)); +end; +{ +procedure tvaluelink.sendvalue(const aname: string; const avalue: ansistring); +var + str1: string; + po1: pchar; +begin + initpropertyrecord(str1,aname,idk_ansistring,length(avalue),po1); + stringtoifiname(avalue,pifinamety(po1)); + tcustommodulelink(fowner).senddata(str1); +end; +} +procedure tvaluelink.initpropertyrecord(out arec: string; + const apropertyname: string; const akind: ifidatakindty; + const datasize: integer; out datapo: pchar); +var + po1: pchar; +begin + inititemheader(arec,ik_propertychanged,0,datarecsizes[akind]+ + length(apropertyname)+datasize,po1); + + inc(po1,stringtoifiname(apropertyname,pifinamety(po1))); + pifidataty(po1)^.header.kind:= akind; + datapo:= po1 + sizeof(ifidataheaderty); +end; + +procedure tvaluelink.sendcommand(const acommand: ifiwidgetcommandty); +var + str1: string; + po1: pchar; +begin + inititemheader(str1,ik_widgetcommand,0,0,po1); + pifiwidgetcommandty(po1)^:= acommand; + tcustommodulelink(fowner).senddata(str1); +end; + +procedure tvaluelink.setdata(const adata: pifidataty; const aname: ansistring); +var + str1: string; +begin + with adata^ do begin + fdatakind:= header.kind; + case fdatakind of + idk_int64: begin + fint64value:= pint64(@data)^; + end; + idk_real: begin + fdoublevalue:= pdouble(@data)^; + end; + idk_msestring: begin + ifinametostring(pifinamety(@data),str1); + fmsestringvalue:= utf8tostringansi(str1); + end; + end; + end; +end; + +procedure tvaluelink.checkdatakind(const akind: ifidatakindty); +begin + if fdatakind <> akind then begin + raise exception.create('Invalid datakind'); + end; +end; + +function tvaluelink.getasinteger: integer; +begin + checkdatakind(idk_int64); + result:= fint64value; +end; + +procedure tvaluelink.setasinteger(const avalue: integer); +begin + setaslargeint(avalue); +end; + +function tvaluelink.getaslargeint: int64; +begin + checkdatakind(idk_int64); + result:= fint64value; +end; + +procedure tvaluelink.setaslargeint(const avalue: int64); +begin + fdatakind:= idk_int64; + fint64value:= avalue; + sendvalue('value',fint64value); +end; + +function tvaluelink.getasfloat: double; +begin + checkdatakind(idk_real); + result:= fdoublevalue; +end; + +procedure tvaluelink.setasfloat(const avalue: double); +begin + fdatakind:= idk_real; + fdoublevalue:= avalue; + sendvalue('value',fdoublevalue); +end; + +function tvaluelink.getasmsestring: msestring; +begin + checkdatakind(idk_msestring); + result:= fmsestringvalue; +{ + if fdatakind = idk_ansistring then begin + result:= fansistringvalue; + end + else begin + checkdatakind(idk_msestring); + result:= fmsestringvalue; + end; + } +end; + +procedure tvaluelink.setasmsestring(const avalue: msestring); +begin + fdatakind:= idk_msestring; + fmsestringvalue:= avalue; + sendvalue('value',fmsestringvalue); +end; + +function tvaluelink.getasansistring: ansistring; +begin + result:= ansistring(getasmsestring); +end; + +procedure tvaluelink.setasansistring(const avalue: ansistring); +begin + setasmsestring(msestring(avalue)); +end; + +procedure tvaluelink.setenabled(const avalue: boolean); +begin + if avalue then begin + sendcommand(iwc_enable); + end + else begin + sendcommand(iwc_disable); + end; +end; + +procedure tvaluelink.setvisible(const avalue: boolean); +begin + if avalue then begin + sendcommand(iwc_show); + end + else begin + sendcommand(iwc_hide); + end; +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: boolean); +var + int1: integer; +begin + int1:= 0; + if avalue then begin + int1:= -1; + end; + sendvalue(aname,int1); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: integer); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: colorty); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: int64); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: string); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: msestring); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: realty); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: currency); +begin + sendvalue(aname,avalue); +end; + +{ tvaluelinks } + +class function tvaluelinks.getitemclasstype: persistentclassty; +begin + result:= tvaluelink; +end; + +function tvaluelinks.getitems(const index: integer): tvaluelink; +begin + result:= tvaluelink(inherited getitems(index)); +end; + +function tvaluelinks.byname(const aname: string): tvaluelink; +begin + result:= tvaluelink(inherited byname(aname)); +end; + +function tvaluelinks.getitemclass: modulelinkpropclassty; +begin + result:= tvaluelink; +end; + +{ tcustomvaluecomponentlink } + +procedure tcustomvaluecomponentlink.setcomponent(const avalue: tmsecomponent); +begin + setlinkedvar(avalue,fcomponent); + if avalue <> nil then begin + fvalueproperty:= getpropinfo(avalue,'value'); + end; +end; + +procedure tcustomvaluecomponentlink.checkcomponent; +begin + if fcomponent = nil then begin + exception.create(tcustommodulelink(fowner).name+': No component.'); + end; +end; + +function getnestedpropinfo(var ainstance: tobject; + apropname: pchar; out aindex: integer; + out arraypropkind: arraypropkindty): ppropinfo; +var + po1,po2: pchar; + prop1: ppropinfo; + index1: integer; +begin + result:= nil; + po2:= nil; + po1:= apropname; + index1:= -1; + arraypropkind:= apk_none; + while po1^ <> #0 do begin + if po1^ = '.' then begin + break; + end; + if po1^ = '[' then begin + po2:= po1+1; + while (po2^ <> ']') and (po2^ <> #0) do begin + inc(po2); + end; + if po2^ <> #0 then begin + if not trystrtoint(psubstr(po1+1,po2),index1) then begin + index1:= -1; + end; + inc(po2); + end; + break; + end; + inc(po1); + end; + if po1 <> apropname then begin + result:= getpropinfo(ainstance,psubstr(apropname,po1)); + if result <> nil then begin + if result^.proptype^.kind = tkclass then begin + ptruint(ainstance):= ptruint(getordprop(ainstance,result)); + prop1:= result; + result:= nil; + if ainstance <> nil then begin + if index1 >= 0 then begin + if ainstance is tarrayprop then begin + with tarrayprop(ainstance) do begin + if index1 < count then begin + arraypropkind:= propkind; + if arraypropkind = apk_tpersistent then begin + ainstance:= tpersistentarrayprop(ainstance)[index1]; + if po2^ = '.' then begin + result:= getnestedpropinfo(ainstance,po2+1,index1,arraypropkind); + end; + end + else begin + result:= prop1; + end; + end; + end; + end + end + else begin + if (po1^ = '.') then begin + result:= getnestedpropinfo(ainstance,po1+1,index1,arraypropkind); + end + else begin + result:= nil; + end; + end; + end; + end; + end; + end; + aindex:= index1; +end; + +procedure tcustomvaluecomponentlink.setdata(const adata: pifidataty; + const aname: ansistring); +var + aproperty: ppropinfo; + instance: tobject; + index1: integer; + arraypropkind: arraypropkindty; +begin + inherited; + aproperty:= nil; + instance:= fcomponent; + with adata^ do begin + if aname = 'value' then begin + aproperty:= fvalueproperty; + index1:= -1; + end + else begin + if fcomponent <> nil then begin + aproperty:= getnestedpropinfo(instance,pchar(aname),index1,arraypropkind); + end; + end; + if (aproperty <> nil) and (instance <> nil) then begin + inc(fupdatelock); + try + if index1 >= 0 then begin + case arraypropkind of + apk_integer,apk_colorty: begin + tintegerarrayprop(instance)[index1]:= asinteger; + end; + apk_real: begin + trealarrayprop(instance)[index1]:= asfloat; + end; + apk_string: begin + tstringarrayprop(instance)[index1]:= asstring; + end; + apk_msestring: begin + tmsestringarrayprop(instance)[index1]:= asmsestring; + end; + apk_boolean: begin + tbooleanarrayprop(instance)[index1]:= asinteger <> 0;; + end; + end; + end + else begin + case aproperty^.proptype^.kind of + tkInteger,{$ifdef FPC}tkBool,{$endif}tkInt64,tkset: begin + setordprop(instance,aproperty,aslargeint); + end; + tkFloat: begin + setfloatprop(instance,aproperty,asfloat); + end; + tkWString: begin + setwidestrprop(instance,aproperty,asmsestring); + end; + {$if defined(FPC) and (FPC_FULLVERSION >= 20300)} +// {$ifdef mse_unicodestring} + tkUString: begin + setunicodestrprop(instance,aproperty,asmsestring); + end; + {$ifend} + {$ifdef FPC} + tkSString,tkLString,tkAString: begin + {$else} + tkString,tkLString: begin + {$endif} + setstrprop(instance,aproperty,asstring); + end; + end; + end; + finally + dec(fupdatelock); + end; + end; + end; +end; + +procedure tcustomvaluecomponentlink.sendvalue(const aproperty: ppropinfo); +begin + if aproperty <> nil then begin + case aproperty^.proptype^.kind of + tkInteger,{$ifdef FPC}tkBool,{$endif}tkInt64: begin + sendvalue(aproperty^.name,getordprop(fcomponent,aproperty)); + end; + tkFloat: begin + {$ifdef FPC} + sendvalue(aproperty^.name,double(getfloatprop(fcomponent,aproperty))); + {$else} + sendvalue(aproperty^.name,getfloatprop(fcomponent,aproperty)); + {$endif} + end; + {$if defined(FPC) and (FPC_FULLVERSION >= 20300)} +// {$ifdef mse_unicodestring} + tkUString: begin + sendvalue(aproperty^.name,getunicodestrprop(fcomponent,aproperty)); + end; + {$ifend} + tkWString: begin + sendvalue(aproperty^.name,getwidestrprop(fcomponent,aproperty)); + end; + {$ifdef FPC} + tkSString,tkLString,tkAString: begin + {$else} + tkString,tkLString: begin + {$endif} + sendvalue(aproperty^.name,getstrprop(fcomponent,aproperty)); + end; + end; + end; +end; + +procedure tcustomvaluecomponentlink.sendstate(const astate: ifiwidgetstatesty); +begin + sendvalue(ifiwidgetstatename,{$ifdef FPC}integer{$else}byte{$endif}(astate)); +end; + +procedure tcustomvaluecomponentlink.sendmodalresult(const amodalresult: modalresultty); +begin + sendvalue(ifiwidgetmodalresultname,integer(amodalresult)); +end; + +procedure tcustomvaluecomponentlink.sendproperties; +var + stream1: tmemorystream; + str1: string; + po1: pchar; +begin + checkcomponent; + stream1:= tmemorystream.create; + try + writecomponentmse(stream1,fcomponent); + inititemheader(str1,ik_widgetproperties,0,stream1.size,po1); + setifibytes(stream1.memory,stream1.size,pifibytesty(po1)); + finally + stream1.free; + end; + tcustommodulelink(fowner).senddata(str1); +end; + +procedure tcustomvaluecomponentlink.sendvalue(const aname: string; + const avalue: colorty); +begin + sendvalue(aname,int64(avalue)); +end; + +{ tvaluecomponentlinks } + +class function tvaluecomponentlinks.getitemclasstype: persistentclassty; +begin + result:= tvaluecomponentlink; +end; + +function tvaluecomponentlinks.getitems(const index: integer): tvaluecomponentlink; +begin + result:= tvaluecomponentlink(inherited getitems(index)); +end; + +function tvaluecomponentlinks.byname(const aname: string): tvaluecomponentlink; +begin + result:= tvaluecomponentlink(inherited byname(aname)); +end; + +function tvaluecomponentlinks.getitemclass: modulelinkpropclassty; +begin + result:= tvaluecomponentlink; +end; + +{ tcustommodulelink } + +constructor tcustommodulelink.create(aowner: tcomponent); +begin + foptions:= defaultformlinkoptions; + factionsrx:= trxlinkactions.create(self); + factionstx:= ttxlinkactions.create(self); + fmodulestx:= ttxlinkmodules.create(self); + fmodulesrx:= trxlinkmodules.create(self); + fvaluecomponents:= tvaluecomponentlinks.create(self); + if fvalues = nil then begin + fvalues:= tvaluelinks.create(self); + end; + inherited; +end; + +destructor tcustommodulelink.destroy; +begin + factionsrx.free; + factionstx.free; + fmodulesrx.free; + fmodulestx.free; + fvaluecomponents.free; + fvalues.free; + inherited; +end; + +procedure tcustommodulelink.setactionsrx(const avalue: trxlinkactions); +begin + factionsrx.assign(avalue); +end; + +procedure tcustommodulelink.setactionstx(const avalue: ttxlinkactions); +begin + factionstx.assign(avalue); +end; + +procedure tcustommodulelink.updatecomponent(const anamepath: ansistring; + const aobjecttext: ansistring); +var + comp1: tcomponent; + stream1: tstringcopystream; + stream2: tmemorystream; +begin + comp1:= findcomponentbynamepath(anamepath); + if comp1 = nil then begin + raise exception.create('Component "'+anamepath+'" not found.'); + end; + stream1:= tstringcopystream.create(aobjecttext); + stream2:= tmemorystream.create; + try + objecttexttobinarymse(stream1,stream2); + stream2.position:= 0; + stream2.readcomponent(comp1); + finally + stream1.free; + stream2.free; + end; +end; + +function tcustommodulelink.encodemodulecommand(const acommand: ificommandcodety; + const atag: integer; const aname: string): string; +var + po1: pchar; +begin + initifirec(result,ik_modulecommand,0,length(aname),po1); + with pmodulecommandty(po1)^ do begin + with header do begin + tag:= atag; + po1:= @name; + inc(po1,stringtoifiname(aname,@name)); + end; + end; + with pmodulecommanddataty(po1)^ do begin + command:= acommand; + end; +end; + +procedure tcustommodulelink.closemodule(const atag: integer; const aname: string); +begin + if fchannel <> nil then begin + fchannel.senddata(encodemodulecommand(icc_close,atag,aname)); + end; +end; + +procedure tcustommodulelink.actionfired(const sender: tlinkaction; + const acompintf: iifitxaction); +var + str1: string; + po1: pchar; +begin + if fchannel <> nil then begin + str1:= encodeactionfired(sender.tag,sender.name,po1); + if acompintf <> nil then begin + acompintf.txactionfired(str1,po1); + end; + fchannel.senddata(str1); + end; +end; + +function tcustommodulelink.encodeactionfired(const atag: integer; + const aname: string; out adatapo: pchar): string; +var + po1: pchar; +begin + initifirec(result,ik_actionfired,0,length(aname),po1); + with pifirecty(result)^.actionfired.header do begin + tag:= atag; + adatapo:= @name; + inc(adatapo,stringtoifiname(aname,pifinamety(adatapo))); + end; +end; + +procedure tcustommodulelink.objectevent(const sender: tobject; + const event: objecteventty); +var + po1: pifirecty; +// str1: string; +begin + if (event = oe_dataready) and (sender = fchannel) then begin + if (length(fchannel.rxdata) >= sizeof(ifiheaderty)) then begin + with fchannel do begin + po1:= pifirecty(rxdata); + with po1^.header do begin + if size = length(rxdata) then begin + if (kind in ifiasynckinds) and not (irs_async in state) then begin + include(state,irs_async); + asyncrx; + end + else begin + if processdata(po1) then begin + rxdata:= ''; + end; + end; + end; + end; + end; + end; + end; +end; + +function tcustommodulelink.processdataitem(const adata: pifirecty; + var adatapo: pchar; const atag: integer; const aname: string): boolean; +var + str2: string; +begin + result:= false; + with adata^ do begin + case header.kind of + ik_actionfired: begin + result:= actionreceived(adata,adatapo,atag,aname); + end; + ik_propertychanged: begin + with propertychanged.header do begin + inc(adatapo,ifinametostring(pifinamety(adatapo),str2)); + result:= propertychangereceived(atag,aname,str2,pifidataty(adatapo)); + end; + end; + ik_requestmodule: begin + result:= requestmodulereceived(atag,aname,adata^.header.sequence); + end; + ik_moduledata: begin + result:= moduledatareceived(atag,aname,header.answersequence, + pmoduledatadataty(adatapo)); + end; + ik_modulecommand: begin + result:= modulecommandreceived(atag,aname,pmodulecommanddataty(adatapo)); + end; + end; + end; +end; + +function tcustommodulelink.processdata(const adata: pifirecty): boolean; + //todo: optimize link name check +var + tag1: integer; + str1: string; + po1: pchar; + ar1: stringarty; +begin + result:= false; + with adata^ do begin + if header.kind in ifiitemkinds then begin + with itemheader do begin + tag1:= tag; + po1:= @name; + end; + inc(po1,ifinametostring(pifinamety(po1),str1)); + ar1:= splitstring(str1,'.'); + if high(ar1) = 1 then begin + if ar1[0] <> flinkname then begin + exit; + end; + str1:= ar1[1]; + end; + result:= processdataitem(adata,po1,tag1,str1); + if result and (header.answersequence <> 0) then begin + channel.synchronizer.answerreceived(header.answersequence); + end; + end; + end; +end; + +procedure tcustommodulelink.receiveevent(const event: tobjectevent); +var +// comp1: tmsecomponent; + stream1: tmemorycopystream; + po1: pchar; + str1: string; +begin + if event.kind = ek_objectdata then begin + if event is tmoduledataevent then begin + with tmoduledataevent(event) do begin + po1:= @fmoduledata^.parentclass; + inc(po1,ifinametostring(pifinamety(po1),str1)); + with fmodulelink do begin + freeandnil(fmodule); + with pifibytesty(po1)^ do begin + stream1:= tmemorycopystream.create(@data,length); + try + fmodule:= createtmpmodule(str1,stream1,{$ifdef FPC}@{$endif}moduleloaded); + fmodule.getcorbainterface(typeinfo(iificommand),fcommandintf); + finally + stream1.free; + end; + end; + setlinkedvar(fmodule,fmodule); + domodulereceived; + end; + end; + end; + end + else begin + inherited; + end; +end; + +function tcustommodulelink.actionreceived(const adata: pifirecty; + var adatapo: pchar; const atag: integer; const aname: string): boolean; +var + act1: trxlinkaction; +// int1: integer; + var1: variant; +begin + result:= false; + with factionsrx do begin + act1:= trxlinkaction(finditem(aname)); + if act1 <> nil then begin + result:= true; + if adatapo^ <> #0 then begin + var1:= readifivariant(adata,adatapo); + end + else begin //end of string + var1:= null; + end; + if assigned(act1.fonexecute) then begin + act1.fonexecute(act1,atag,var1); + end; + if assigned(fonexecute) then begin + fonexecute(act1,atag,var1); + end; + with act1 do begin + if (faction <> nil) and faction.enabled then begin + faction.execute; + end; + end; + end; + end; +end; + +function tcustommodulelink.requestmodulereceived(const atag: integer; + const aname: string; const asequence: sequencety): boolean; +var + mo1: ttxlinkmodule; + po1: pobjectdataty; + str1,str2: string; + po2,po3: pchar; +begin + {$ifdef mse_debugifi} + debugout(self,'requestmodule '+aname); + {$endif} + mo1:= ttxlinkmodule(fmodulestx.finditem(aname)); + result:= mo1 <> nil; + if result and (mo1.fmoduleclassname <> '') then begin + po1:= findmoduledata(mo1.fmoduleclassname,str2); + if mo1.moduleparentclassname <> '' then begin + str2:= mo1.moduleparentclassname; + end; + if po1 <> nil then begin + mo1.inititemheader(str1,ik_moduledata,asequence,length(str2)+po1^.size,po2); + with pmoduledatadataty(po2)^ do begin + po3:= @parentclass; + inc(po3,stringtoifiname(str2,pifinamety(po3))); + setifibytes(@po1^.data,po1^.size,pifibytesty(po3)); + end; + senddata(str1); + end + else begin + raise exception.create('Module resouces for "'+aname+'" class "'+ + mo1.fmoduleclassname+'" not found.'); + end; + end; +end; + +procedure tcustommodulelink.connectmodule(const sender: tcustommodulelink); +begin + if flo_useclientchannel in options then begin + channel:= sender.channel; + end; +end; + +procedure tcustommodulelink.moduleloaded(const sender: tmsecomponent); +var + int1: integer; + intf1: iifimodulelink; +begin + with sender do begin + for int1:= 0 to componentcount - 1 do begin + if mseclasses.getcorbainterface(components[int1],typeinfo(iifimodulelink), + intf1) then begin + intf1.connectmodule(self); + end; + end; + end; +end; + +function tcustommodulelink.modulecommandreceived(const atag: integer; + const aname: string; const adata: pmodulecommanddataty): boolean; +var + mo1: trxlinkmodule; +begin + mo1:= trxlinkmodule(fmodulesrx.finditem(aname)); + result:= mo1 <> nil; + if result then begin + with mo1 do begin + if fmodule <> nil then begin + if fcommandintf <> nil then begin + fcommandintf.executeificommand(adata^.command); + end; + end; + end; + end; +end; + +function tcustommodulelink.moduledatareceived(const atag: integer; + const aname: string; const asequence: sequencety; + const adata: pmoduledatadataty): boolean; +var + mo1: trxlinkmodule; + comp1: tmsecomponent; + stream1: tmemorycopystream; + po1: pchar; + str1: string; +begin + if csdesigning in componentstate then begin + result:= false; + exit; + end; + if asequence <> 0 then begin + mo1:= fmodulesrx.finditem(asequence); + end + else begin + mo1:= trxlinkmodule(fmodulesrx.finditem(aname)); + end; + result:= mo1 <> nil; + if result then begin + with mo1 do begin + po1:= adata^.parentclass; + inc(po1,ifinametostring(pifinamety(po1),str1)); + freeandnil(fmodule); + with pifibytesty(po1)^ do begin + stream1:= tmemorycopystream.create(@data,length); + try + comp1:= createtmpmodule(str1,stream1,{$ifdef FPC}@{$endif}moduleloaded); + comp1.getcorbainterface(typeinfo(iificommand),fcommandintf); + finally + stream1.free; + end; + end; + setlinkedvar(comp1,fmodule); + end; + end; +end; + +function tcustommodulelink.propertychangereceived(const atag: integer; + const aname: string; const apropertyname: string; + const adata: pifidataty): boolean; + + procedure check(const alinks: tvaluelinks); + var + wi1: tvaluelink; + begin + wi1:= tvaluelink(alinks.finditem(aname)); + result:= wi1 <> nil; + if result then begin + with wi1 do begin + setdata(adata,apropertyname); + if apropertyname = ifiwidgetstatename then begin + if assigned(fonwidgetstatechanged) then begin + fonwidgetstatechanged(wi1,atag,ifiwidgetstatesty( + {$ifndef FPC}byte({$endif}asinteger{$ifndef FPC}){$endif})); + end; + end + else begin + if apropertyname = ifiwidgetmodalresultname then begin + if assigned(fonmodalresult) then begin + fonmodalresult(wi1,atag,modalresultty(asinteger)); + end; + end + else begin + if assigned(fonpropertychanged) then begin + fonpropertychanged(wi1,atag,apropertyname); + end; + end; + end; + end; + end; + end; //check + +begin + result:= false; + check(fvalues); + if not result then begin + check(fvaluecomponents); + end; +end; + +procedure tcustommodulelink.execute(const sender: iificlient); +begin + //dummy +end; + +procedure tcustommodulelink.valuechanged(const sender: iificlient); +begin + //dummy +end; + +procedure tcustommodulelink.dataentered(const sender: iificlient; + const arow: integer); +begin + //dummy +end; + +procedure tcustommodulelink.updateoptionsedit(var avalue: optionseditty); +begin + //dummy +end; + +procedure tcustommodulelink.closequery(const sender: iificlient; + var amodalresult: modalresultty); +begin + //dummy +end; + +procedure tcustommodulelink.statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); +begin + //dummy +end; + +procedure tcustommodulelink.setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); +begin + //dummy +end; + +procedure tcustommodulelink.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +begin + //dummy +end; + +function tcustommodulelink.hasconnection: boolean; +begin + result:= (fchannel <> nil) and fchannel.checkconnection; +end; + +function tcustommodulelink.senddata(const adata: ansistring): sequencety; +begin + if fchannel = nil then begin + raise exception.create(name+': No IO channel assigned.'); + end; + result:= fchannel.sequence; + with pifirecty(adata)^.header do begin + sequence:= result; + end; + fchannel.senddata(adata); +end; + +procedure tcustommodulelink.setmodulestx(const avalue: ttxlinkmodules); +begin + fmodulestx.assign(avalue); +end; + +procedure tcustommodulelink.setmodulesrx(const avalue: trxlinkmodules); +begin + fmodulesrx.assign(avalue); +end; + +procedure tcustommodulelink.setvalues(const avalue: tvaluelinks); +begin + fvalues.assign(avalue); +end; + +procedure tcustommodulelink.setvaluecomponents(const avalue: tvaluecomponentlinks); +begin + fvaluecomponents.assign(avalue); +end; + +{ ttxlinkmodule } + +procedure ttxlinkmodule.sendmodule; +begin + tcustommodulelink(fowner).requestmodulereceived(tag,name,0); +end; + +procedure ttxlinkmodule.close; +begin + tcustommodulelink(fowner).closemodule(tag,name); +end; + +{ tmoduledataevent } + +constructor tmoduledataevent.create(const adata: ansistring; const dest: ievent; + const amodulelink: trxlinkmodule; + const amoduledata: pmoduledatadataty); +begin + fmodulelink:= amodulelink; + fmoduledata:= amoduledata; + inherited create(adata,dest); +end; + +{ tificontroller } + +constructor tificontroller.create(const aowner: tcomponent; + const aintf: iactivatorclient); +begin + foptions:= defaultifirxoptions; + fdefaulttimeout:= defaultifirxtimeout; + inherited create(aowner,aintf); +end; + +procedure tificontroller.connectmodule(const sender: tcustommodulelink); +begin + if irxo_useclientchannel in options then begin + channel:= sender.channel; + end; +end; + +procedure tificontroller.inititemheader(out arec: string; + const akind: ifireckindty; const asequence: sequencety; + const datasize: integer; out datapo: pchar); +begin + mseifi.inititemheader(tag,flinkname,arec,akind,asequence,datasize,datapo); +end; + +procedure tificontroller.setchannel(const avalue: tcustomiochannel); +begin + setlinkedvar(avalue,tmsecomponent(fchannel)); +end; + +function tificontroller.senddata(const adata: ansistring; + const asequence: sequencety = 0): sequencety; +begin + if fchannel = nil then begin + raise exception.create(fowner.name+': No IO channel assigned.'); + end; + result:= asequence; + if result = 0 then begin + result:= fchannel.sequence; + end; + with pifirecty(adata)^.header do begin + sequence:= result; + end; + fchannel.senddata(adata); +end; + +function tificontroller.senddataandwait(const adata: ansistring; + out asequence: sequencety; atimeoutus: integer = 0): boolean; +var + client1: twaitingclient; +begin + if fchannel = nil then begin + raise exception.create(fowner.name+': No IO channel assigned.'); + end; + asequence:= fchannel.sequence; + client1:= fchannel.synchronizer.preparewait(asequence); + senddata(adata,asequence); + if atimeoutus = 0 then begin + atimeoutus:= timeoutus; + end; + result:= fchannel.synchronizer.waitforanswer(client1,atimeoutus); + if not result then begin + asequence:= 0; //!!! race condition? + end; +end; + +function tificontroller.senditem(const kind: ifireckindty; + const data: array of ansistring): sequencety; + //returns sequence number +var + str1: ansistring; + po1: pchar; + int1,int2: integer; +begin + int2:= 0; + for int1:= 0 to high(data) do begin + inc(int2,length(data[int1])); + end; + inititemheader(str1,ik_itemheader,0,int2,po1); + pifirecty(str1)^.header.kind:= kind; + for int1:= 0 to high(data) do begin + int2:= length(data[int1]); + move(pointer(data[int1])^,po1^,int2); + inc(po1,int2); + end; + result:= senddata(str1); +end; + +procedure tificontroller.objectevent(const sender: tobject; + const event: objecteventty); +var + po1: pifirecty; +// tag1: integer; + str1: string; + po2: pchar; +// int1: integer; +// mstr1: msestring; +begin + if (event = oe_dataready) and (sender = fchannel) then begin + if (length(fchannel.rxdata) >= sizeof(ifiheaderty)) then begin + with fchannel do begin + po1:= pifirecty(rxdata); + with po1^,header do begin + if (size = length(rxdata)) and (kind in getifireckinds) then begin + with itemheader do begin +// tag1:= tag; + po2:= @name; + end; + inc(po2,ifinametostring(pifinamety(po2),str1)); + if str1 = flinkname then begin + processdata(po1,po2); + if answersequence <> 0 then begin + channel.synchronizer.answerreceived(answersequence); + end; +// rxdata:= ''; + end; + end; + end; + end; + end; + end + else begin + inherited; + end; +end; + +function tificontroller.getifireckinds: ifireckindsty; +begin + result:= []; +end; + +function tificontroller.cansend: boolean; +begin + result:= (channel <> nil) or + not ((csdesigning in fowner.componentstate) and + (irxo_useclientchannel in foptions)); +end; + +{ tifidatacol } + +constructor tifidatacol.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + fselectedrow:= -1; + inherited; +end; + +destructor tifidatacol.destroy; +begin + freedatalist; + inherited; +end; + +procedure tifidatacol.freedatalist; +begin + fdata.free; +end; + +procedure tifidatacol.setdatakind(const avalue: ifidatakindty); +begin + if fdatakind <> avalue then begin + freedatalist; + fdatakind:= avalue; + end; +end; + +procedure tifidatacol.checkdatalist; +begin + if fdata = nil then begin + case datakind of + idk_integer: begin + fdata:= tintegerdatalist.create; + end; + { + idk_int64: begin + fdatalist:= tint64datalist.create; + end; + idk_currency: begin + fdatalist:= tcurrencydatalist.create; + end; + } + idk_real: begin + fdata:= trealdatalist.create; + end; + idk_msestring: begin + fdata:= tmsestringdatalist.create; + end; + idk_msestringint: begin + fdata:= tmsestringintdatalist.create; + end; + idk_bytes: begin + fdata:= tansistringdatalist.create; + end; + idk_realint: begin + fdata:= trealintdatalist.create; + end; + else begin + raise exception.create('Invalid ifidatakind.'); + end; + end; + end; + fdata.count:= ttxdatagrid(fowner).rowcount; + fdata.onitemchange:= {$ifdef FPC}@{$endif}dochange; +end; + +procedure tifidatacol.checkdatalist(const akind: ifidatakindty); +begin + if akind <> datakind then begin + raise exception.create('Wrong datakind.'); + end; + if fdata = nil then begin + checkdatalist; + end; +end; + +procedure tifidatacol.dochange(const sender: tdatalist; const aindex: integer); +begin + if ttxdatagrid(fowner).canevent(tmethod(fonchange)) then begin + fonchange(self,aindex); + end; +end; + +function tifidatacol.getdatalist: tdatalist; +begin + checkdatalist; + result:= fdata; +end; + +procedure tifidatacol.datachange(const aindex: integer); +begin + with ttxdatagrid(fowner).fifi do begin + if (self.name <> '') and cancommandsend(igo_coldata) and + (fdata <> nil) then begin + senditem(ik_coldatachange,[encodecolchangedata(self.name,aindex,fdata)]); + end; + end; +end; + +function tifidatacol.getasinteger(const aindex: integer): integer; +begin + checkdatalist(idk_integer); + result:= tintegerdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasinteger(const aindex: integer; const avalue: integer); +begin + checkdatalist(idk_integer); + tintegerdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasint64(const aindex: integer): int64; +begin + checkdatalist(idk_int64); + result:= tint64datalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasint64(const aindex: integer; const avalue: int64); +begin + checkdatalist(idk_int64); + tint64datalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getascurrency(const aindex: integer): currency; +begin + checkdatalist(idk_currency); + result:= tcurrencydatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setascurrency(const aindex: integer; + const avalue: currency); +begin + checkdatalist(idk_currency); + tcurrencydatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasreal(const aindex: integer): real; +begin + checkdatalist(idk_real); + result:= trealdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasreal(const aindex: integer; const avalue: real); +begin + checkdatalist(idk_real); + trealdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasmsestring(const aindex: integer): msestring; +begin + checkdatalist(idk_msestring); + result:= tmsestringdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasmsestring(const aindex: integer; + const avalue: msestring); +begin + checkdatalist(idk_msestring); + tmsestringdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasbytes(const aindex: integer): ansistring; +begin + checkdatalist(idk_bytes); + result:= tansistringdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasbytes(const aindex: integer; + const avalue: ansistring); +begin + checkdatalist(idk_bytes); + tansistringdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasmsestringint(const aindex: integer): msestringintty; +begin + checkdatalist(idk_msestringint); + result:= tmsestringintdatalist(fdata).doubleitems[aindex]; +end; + +procedure tifidatacol.setasmsestringint(const aindex: integer; + const avalue: msestringintty); +begin + checkdatalist(idk_msestringint); + tmsestringintdatalist(fdata).doubleitems[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasmsestringinti(const aindex: integer): integer; +begin + checkdatalist(idk_msestringint); + result:= tmsestringintdatalist(fdata).itemsb[aindex]; +end; + +procedure tifidatacol.setasmsestringinti(const aindex: integer; + const avalue: integer); +begin + checkdatalist(idk_msestringint); + tmsestringintdatalist(fdata).itemsb[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasmsestringints(const aindex: integer): msestring; +begin + checkdatalist(idk_msestringint); + result:= tmsestringintdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasmsestringints(const aindex: integer; + const avalue: msestring); +begin + checkdatalist(idk_msestringint); + tmsestringintdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasrealint(const aindex: integer): realintty; +begin + checkdatalist(idk_realint); + result:= trealintdatalist(fdata).doubleitems[aindex]; +end; + +procedure tifidatacol.setasrealint(const aindex: integer; + const avalue: realintty); +begin + checkdatalist(idk_realint); + trealintdatalist(fdata).doubleitems[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasrealintr(const aindex: integer): realty; +begin + checkdatalist(idk_realint); + result:= trealintdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasrealintr(const aindex: integer; + const avalue: realty); +begin + checkdatalist(idk_realint); + trealintdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasrealinti(const aindex: integer): integer; +begin + checkdatalist(idk_realint); + result:= trealintdatalist(fdata).itemsb[aindex]; +end; + +procedure tifidatacol.setasrealinti(const aindex: integer; + const avalue: integer); +begin + checkdatalist(idk_realint); + trealintdatalist(fdata).itemsb[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getmerged(const row: integer): boolean; +begin + if index = 0 then begin + result:= false; + end + else begin + if index > mergedcolmax then begin + result:= tifidatacols(prop).frowstate.getitempocolmerge(row)^.colmerge.merged = mergedcolall; + end + else begin + result:= tifidatacols(prop).frowstate.getitempocolmerge(row)^.colmerge.merged and + bits[index-1] <> 0; + end; + end; +end; + +procedure tifidatacol.setmerged(const row: integer; const avalue: boolean); +begin + if (index > 0) and (index <= mergedcolmax) then begin + if updatebit(tifidatacols(prop).frowstate.getitempocolmerge(row)^.colmerge.merged,index-1, + avalue) then begin + ttxdatagrid(fowner).rowstatechanged(row); + end; + end; +end; + +function tifidatacol.getselected(row: integer): boolean; +begin + if ident <= selectedcolmax then begin + if row >= 0 then begin + result:= (icos_selected in fstate) or + (tifidatacols(prop).frowstate.getitempo(row)^.selected and + (bits[ident] or wholerowselectedmask) <> 0); + end + else begin + result:= icos_selected in fstate; + end; + end + else begin + result:= false; + end; +end; + +procedure tifidatacol.setselected(row: integer; const avalue: boolean); +var + po1: prowstatety; + ca1: longword; + int1: integer; +begin + if ident <= selectedcolmax then begin + if row >= 0 then begin + with tifidatacols(prop).frowstate.getitempo(row)^ do begin + ca1:= selected; + if avalue then begin + ca1:= selected or bits[ident]; + end + else begin + ca1:= selected and not (bits[ident] {or wholerowselectedmask}); + end; + if ca1 <> selected then begin + if avalue then begin + if fselectedrow = -1 then begin + fselectedrow:= row; + end + else begin + fselectedrow:= -2; + end; + end + else begin + if fselectedrow = row then begin + fselectedrow:= -1; + end; + end; +// invalidatecell(row); + doselectionchanged; + end; + end; + end + else begin //row < 0 + if avalue then begin + if not (icos_selected in fstate) then begin + include(fstate,icos_selected); + fselectedrow:= -2; +// changed; + doselectionchanged; + end; + end + else begin + exclude(fstate,icos_selected); + if fselectedrow <> -1 then begin + po1:= tifidatacols(prop).frowstate.datapo; + ca1:= not (bits[ident] {or wholerowselectedmask}); + if fselectedrow >= 0 then begin + prowstateaty(po1)^[fselectedrow].selected:= + prowstateaty(po1)^[fselectedrow].selected and ca1; +// invalidatecell(fselectedrow); +// cellchanged(fselectedrow); + end + else begin + for int1:= 0 to ttxdatagrid(fowner).frowcount - 1 do begin + po1^.selected:= po1^.selected and ca1; + inc(po1); + end; +// changed; + end; + fselectedrow:= -1; + doselectionchanged; + end; + end; + end; + end; +end; + +procedure tifidatacol.doselectionchanged; +begin + //dummy +end; + +procedure tifidatacol.beginselect; +begin +end; + +procedure tifidatacol.endselect; +begin +end; + +{ tifidatacols } + +constructor tifidatacols.create(const aowner: ttxdatagrid); +begin + fselectedrow:= -1; + frowstate:= tifirowstatelist.create(ril_colmerge); + inherited create(aowner,tifidatacol); +end; + +destructor tifidatacols.destroy; +begin + inherited; + frowstate.free; +end; + +class function tifidatacols.getitemclasstype: persistentclassty; +begin + result:= tifidatacol; +end; + +function tifidatacols.getcols(const index: integer): tifidatacol; +begin + result:= tifidatacol(inherited getitems(index)); +end; + +procedure tifidatacols.setcols(const index: integer; const avalue: tifidatacol); +begin + tifidatacol(inherited getitems(index)).assign(avalue); +end; + +function tifidatacols.colbyname(const aname: ansistring): tifidatacol; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to count - 1 do begin + if tifidatacol(fitems[int1]).fname = aname then begin + result:= tifidatacol(fitems[int1]); + break; + end; + end; +end; + +function tifidatacols.datalistbyname(const aname: ansistring): tdatalist; +var + col1: tifidatacol; +begin + result:= nil; + col1:= colbyname(aname); + if col1 <> nil then begin + result:= col1.datalist; + end; +end; + +function tifidatacols.getselectedcells: gridcoordarty; +const + capacitystep = 64; +var + int1,int2,int3: integer; + cell: gridcoordty; + bo1: boolean; +begin + result:= nil; + if hasselection then begin //todo: optimize + int3:= 0; + bo1:= hascolselection; + for int1:= 0 to frowstate.count - 1 do begin + if bo1 or (frowstate.getitempo(int1)^.selected <> 0) then begin + cell.row:= int1; + for int2:= 0 to count - 1 do begin + if tifidatacol(fitems[int2]).selected[int1] then begin + if int3 >= length(result) then begin + setlength(result,length(result)*2 + capacitystep); + end; + cell.col:= int2; + result[int3]:= cell; + inc(int3); + end; + end; + end; + end; + setlength(result,int3); + end; +end; + +procedure tifidatacols.setselectedcells(const avalue: gridcoordarty); +var + int1: integer; +begin + ttxdatagrid(fowner).beginupdate; + beginselect; + clearselection; + for int1:= 0 to high(avalue) do begin + setselected(avalue[int1],true); + end; + endselect; + ttxdatagrid(fowner).endupdate; +end; + +function tifidatacols.Getselected(const cell: gridcoordty): boolean; +var + int1: integer; +begin + if cell.col >= 0 then begin + result:= cols[cell.col].getselected(cell.row); + end + else begin + if cell.row >= 0 then begin + result:= (frowstate.getitempo(cell.row)^.selected and wholerowselectedmask <> 0); + end + else begin + result:= true; + for int1:= 0 to count - 1 do begin + if not (icos_selected in cols[int1].fstate) then begin + result:= false; + break; + end; + end; + end; + end; +end; + +procedure tifidatacols.Setselected(const cell: gridcoordty; + const avalue: boolean); +var + lwo1: longword; +// bo1: boolean; + po1: prowstatety; + int1: integer; +begin + ttxdatagrid(fowner).setselected(cell,avalue); + if cell.col >= 0 then begin + cols[cell.col].setselected(cell.row,avalue); + end + else begin //select-deselect whole row +// fgrid.beginupdate; +// try + for int1:= 0 to count - 1 do begin + cols[int1].setselected(cell.row,avalue); + end; + if avalue then begin + lwo1:= $ffffffff; + end + else begin + lwo1:= 0; + end; +// bo1:= false; + if cell.row >= 0 then begin + po1:= frowstate.getitempo(cell.row); + if lwo1 <> po1^.selected then begin + if avalue then begin + if fselectedrow = -1 then begin + fselectedrow:= cell.row; + end + else begin + fselectedrow:= -2; + end; + end + else begin + if fselectedrow = cell.row then begin + fselectedrow:= -1; + end; + end; + po1^.selected:= lwo1; +// fgrid.invalidaterow(cell.row); //for fixcols +// bo1:= true; + end; + end + else begin + po1:= frowstate.datapo; + if avalue then begin + for int1:= 0 to frowstate.count - 1 do begin +// if ca1 <> po1^.selected then begin + po1^.selected:= lwo1; +// fgrid.invalidaterow(int1); //for fixcols +// end; + inc(po1); + end; + fselectedrow:= -2; + end + else begin + if fselectedrow <> -1 then begin + if fselectedrow >= 0 then begin + prowstateaty(po1)^[fselectedrow].selected:= lwo1; +// fgrid.invalidaterow(fselectedrow); //for fixcols +// bo1:= true; + end + else begin + for int1:= 0 to frowstate.count - 1 do begin + if lwo1 <> po1^.selected then begin + po1^.selected:= lwo1; +// fgrid.invalidaterow(int1); //for fixcols +// bo1:= true; + end; + inc(po1); + end; + end; + fselectedrow:= -1; + end; + end; + end; + end; +// if bo1 then begin +// fgrid.internalselectionchanged; +// end; + +end; + +function tifidatacols.selectedcellcount: integer; +var + int1,int2: integer; + bo1: boolean; +begin + result:= 0; + if hasselection then begin + bo1:= hascolselection; + for int1:= 0 to frowstate.count - 1 do begin + if bo1 or (frowstate.getitempo(int1)^.selected <> 0) then begin + for int2:= 0 to count - 1 do begin + if tifidatacol(fitems[int2]).selected[int1] then begin + inc(result); + end; + end; + end; + end; + end; +end; + +function tifidatacols.hascolselection: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count - 1 do begin + if icos_selected in tifidatacol(fitems[int1]).fstate then begin + result:= true; + exit; + end; + end; +end; + +procedure tifidatacols.setselectedrange(const rect: gridrectty; + const value: boolean); +begin + setselectedrange(rect.pos, + makegridcoord(rect.col+rect.colcount,rect.row+rect.rowcount), + value); +end; + +procedure tifidatacols.setselectedrange(const start: gridcoordty; + const stop: gridcoordty; const value: boolean); +var + int1,int2: integer; +// mo1: cellselectmodety; + rect: gridrectty; +begin + rect.pos:= start; + rect.colcount:= stop.col - start.col; + rect.rowcount:= stop.row - start.row; + normalizerect1(rectty(rect)); + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + cols[int1].beginselect; + for int2:= rect.row to rect.row + rect.rowcount - 1 do begin + selected[makegridcoord(int1,int2)]:= value; + end; + end; + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + dec(cols[int1].fselectlock); + end; +end; + +procedure tifidatacols.mergecols(const arow: integer; + const astart: longword = 0; const acount: longword = bigint); +begin + if frowstate.mergecols(arow,astart,acount) then begin + ttxdatagrid(fowner).rowstatechanged(arow); + end; +end; + +procedure tifidatacols.unmergecols(const arow: integer = invalidaxis); +begin + if frowstate.unmergecols(arow) then begin + ttxdatagrid(fowner).rowstatechanged(arow); + end; +end; + +function tifidatacols.hasselection: boolean; +var + int1: integer; +begin + result:= fselectedrow <> -1; + if not result then begin + for int1:= 0 to count - 1 do begin + if cols[int1].fselectedrow <> -1 then begin + result:= true; + break; + end; + end; + end; +end; + +procedure tifidatacols.beginselect; +begin +end; + +procedure tifidatacols.endselect; +begin +end; + +procedure tifidatacols.clearselection; +begin + setselected(invalidcell,false); +end; + +{ ttxdatagrid } + +constructor ttxdatagrid.create(aowner: tcomponent); +begin + fifi:= ttxdatagridcontroller.create(self,iactivatorclient(self)); + inherited; + fdatacols:= tifidatacols.create(self); +end; + +destructor ttxdatagrid.destroy; +begin + fdatacols.free; + inherited; + fifi.free; +end; + +procedure ttxdatagrid.setifi(const avalue: ttxdatagridcontroller); +begin + fifi.assign(avalue); +end; + +procedure ttxdatagrid.setdatacols(const avalue: tifidatacols); +begin + fdatacols.assign(avalue); +end; + +procedure ttxdatagrid.setrowcount(const avalue: integer); +var + int1: integer; +begin + if frowcount <> avalue then begin + frowcount:= avalue; + with fdatacols do begin + for int1:= 0 to high(fitems) do begin + with tifidatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.count:= avalue; + end; + end; + end; + frowstate.count:= avalue; + end; + end; +end; + +function ttxdatagrid.getrowcolorstate(index: integer): rowstatenumty; +begin + result:= fdatacols.frowstate.color[index]; +end; + +procedure ttxdatagrid.setrowcolorstate(index: integer; + const avalue: rowstatenumty); +begin + fdatacols.frowstate.color[index]:= avalue; + rowstatechanged(index); +end; + +function ttxdatagrid.getrowfontstate(index: integer): rowstatenumty; +begin + result:= fdatacols.frowstate.font[index]; +end; + +procedure ttxdatagrid.setrowfontstate(index: integer; + const avalue: rowstatenumty); +begin + fdatacols.frowstate.font[index]:= avalue; + rowstatechanged(index); +end; + +function ttxdatagrid.getrowreadonlystate(const index: integer): boolean; +begin + result:= fdatacols.frowstate.readonly[index]; +end; + +procedure ttxdatagrid.setrowreadonlystate(const index: integer; + const avalue: boolean); +begin + fdatacols.frowstate.readonly[index]:= avalue; + rowstatechanged(index); +end; + +function ttxdatagrid.getrowhidden(const index: integer): boolean; +begin + result:= fdatacols.frowstate.hidden[index]; +end; + +procedure ttxdatagrid.setrowhidden(const index: integer; + const avalue: boolean); +begin + fdatacols.frowstate.hidden[index]:= avalue; +end; + +function ttxdatagrid.getrowfoldlevel(const index: integer): byte; +begin + result:= fdatacols.frowstate.foldlevel[index]; +end; + +procedure ttxdatagrid.setrowfoldlevel(const index: integer; + const avalue: byte); +begin + fdatacols.frowstate.foldlevel[index]:= avalue; +end; + +function ttxdatagrid.getrowfoldissum(const index: integer): boolean; +begin + result:= fdatacols.frowstate.foldissum[index]; +end; + +procedure ttxdatagrid.setrowfoldissum(const index: integer; + const avalue: boolean); +begin + fdatacols.frowstate.foldissum[index]:= avalue; +end; + +function ttxdatagrid.getrowhigh: integer; +begin + result:= frowcount - 1; +end; + +procedure ttxdatagrid.moverow(const curindex: integer; const newindex: integer; + const count: integer = 1); +var + int1: integer; +begin + with fdatacols do begin + for int1:= 0 to high(fitems) do begin + with tifidatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.blockmovedata(curindex,newindex,count); + end; + end; + end; + frowstate.blockmovedata(curindex,newindex,count); + end; + if canevent(tmethod(fonrowsmoved)) then begin + fonrowsmoved(self,curindex,newindex,count); + end; + with fifi do begin + if cancommandsend(igo_rowmove) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_moverow,curindex,newindex,count)]); + end; + end; +end; + +procedure ttxdatagrid.insertrow(index: integer; count: integer = 1); +var + int1: integer; +begin + with fdatacols do begin + for int1:= 0 to high(fitems) do begin + with tifidatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.insertitems(index,count); + end; + end; + end; + frowstate.insertitems(index,count); + end; + if canevent(tmethod(fonrowsinserted)) then begin + fonrowsinserted(self,index,count); + end; + with fifi do begin + if cancommandsend(igo_rowinsert) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_insertrow,index,index,count)]); + end; + end; +end; + +procedure ttxdatagrid.deleterow(index: integer; count: integer = 1); +var + int1: integer; +begin + with fdatacols do begin + for int1:= 0 to high(fitems) do begin + with tifidatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.deleteitems(index,count); + end; + end; + end; + frowstate.deleteitems(index,count); + end; + if canevent(tmethod(fonrowsdeleted)) then begin + fonrowsdeleted(self,index,count); + end; + with fifi do begin + if cancommandsend(igo_rowdelete) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_deleterow,index,index,count)]); + end; + end; +end; + +procedure ttxdatagrid.setrow(const avalue: integer); +begin + frow:= avalue; + if canevent(tmethod(fonrowindexchanged)) then begin + fonrowindexchanged(self); + end; + with fifi do begin + if cancommandsend(igo_rowenter) then begin + senditem(ik_gridcommand, + [encodegridcommanddata(gck_rowenter,avalue,avalue,0)]); + end; + end; +end; + +procedure ttxdatagrid.rowstatechanged(const aindex: integer); +begin + if canevent(tmethod(fonrowstatechanged)) then begin + fonrowstatechanged(self,aindex); + end; + with fifi do begin + if cancommandsend(igo_rowstate) then begin + senditem(ik_rowstatechange, + [encoderowstatedata(aindex,fdatacols.rowstate.itemscolmerge[aindex])]); + end; + end; +end; + +procedure ttxdatagrid.beginupdate; +begin + fifi.beginupdate; +end; + +procedure ttxdatagrid.endupdate; +begin + fifi.endupdate; +end; + +procedure ttxdatagrid.clear; +begin + rowcount:= 0; +end; + +procedure ttxdatagrid.setselected(const cell: gridcoordty; + const avalue: boolean); +begin + with fifi do begin + if cancommandsend(igo_selection) then begin + senditem(ik_selection,[encodeselectiondata(cell,avalue)]); + end; + end; +end; + +{ tifigridcontroller } + +function tifigridcontroller.getifireckinds: ifireckindsty; +begin + result:= [ik_griddata,ik_requestopen,ik_gridcommand, + ik_coldatachange,ik_rowstatechange,ik_selection]; +end; + +function tifigridcontroller.cancommandsend( + const akind: ifigridoptionty): boolean; +begin + result:= (akind in foptionstx) and (fcommandlock = 0) and + (fupdating = 0) and cansend; +end; + +procedure tifigridcontroller.sendstate; +begin + if cansend then begin + senddata(encodegriddata(0)); + end; +end; + +procedure tifigridcontroller.beginupdate; +begin + inc(fupdating); +end; + +procedure tifigridcontroller.endupdate; +begin + dec(fupdating); + if (fupdating = 0) and cancommandsend(igo_state) then begin + sendstate; + end; +end; + +{ ttxdatagridcontroller } + +constructor ttxdatagridcontroller.create(const aowner: ttxdatagrid; + const aintf: iactivatorclient); +begin + inherited create(aowner,aintf); +end; + +procedure ttxdatagridcontroller.processdata(const adata: pifirecty; + var adatapo: pchar); +var + int1: integer; + rows1,cols1: integer; + kind1: listdatatypety; + po1: pchar; + str1: ansistring; + datalist1: tdatalist; + ckind1: gridcommandkindty; + source1,dest1,count1: integer; + rowstate1: rowstatecolmergety; + lwo1: longword; + select1: selectdataty; + +begin + with adata^.header do begin + case kind of + ik_requestopen: begin + with ttxdatagrid(fowner) do begin + if canevent(tmethod(fonbeforeopen)) then begin + inc(fcommandlock); + inc(fupdating); + try + fonbeforeopen(ttxdatagrid(fowner)); + finally + dec(fcommandlock); + dec(fupdating); + end; + end; + end; + senddata(encodegriddata(sequence)); + end; + ik_griddata: begin + if (igo_state in foptionsrx) then begin + with ttxdatagrid(fowner) do begin + with pgriddatadataty(adatapo)^ do begin + rows1:= rows; + rowcount:= rows1; + cols1:= cols; + po1:= @data; + end; + for int1:= 0 to cols1 - 1 do begin + with pcoldataty(po1)^ do begin + kind1:= kind; + po1:= @name; + inc(po1,ifinametostring(pifinamety(po1),str1)); + inc(po1,ifidatatodatalist(kind1,rows1,po1, + datacols.datalistbyname(str1))); + end; + end; + end; + end; + end; + ik_gridcommand: begin + inc(adatapo,decodegridcommanddata(adatapo,ckind1,source1,dest1,count1)); + with ttxdatagrid(fowner) do begin + inc(fcommandlock); + try + case ckind1 of + gck_insertrow: begin + if igo_rowinsert in foptionsrx then begin + insertrow(dest1,count1); + end; + end; + gck_deleterow: begin + if igo_rowdelete in foptionsrx then begin + deleterow(dest1,count1); + end; + end; + gck_moverow: begin + if igo_rowmove in foptionsrx then begin + moverow(source1,dest1,count1); + end; + end; + gck_rowenter: begin + if igo_rowenter in foptionsrx then begin + row:= dest1; + end; + end; + end; + finally + dec(fcommandlock); + end; + end; + end; + ik_coldatachange: begin + if igo_coldata in foptionsrx then begin + inc(fcommandlock); + try + int1:= pcolitemdataty(adatapo)^.header.row; + ifinametostring(@pcolitemdataty(adatapo)^.header.name,str1); + inc(adatapo,sizeof(colitemheaderty)+length(str1)); + datalist1:= nil; + if igo_coldata in foptionsrx then begin + datalist1:= ttxdatagrid(fowner).fdatacols.datalistbyname(str1); + end; //skip data otherwise + inc(adatapo,decodeifidata(pifidataty(adatapo),int1,datalist1)); + finally + dec(fcommandlock); + end; + end; + end; + ik_rowstatechange: begin + if igo_rowstate in foptionsrx then begin + inc(fcommandlock); + try + int1:= prowstatedataty(adatapo)^.header.row; + inc(adatapo,sizeof(rowstateheaderty)); + inc(adatapo,decodeifidata(pifidataty(adatapo),rowstate1)); + with ttxdatagrid(fowner),rowstate1 do begin + rowcolorstate[int1]:= normal.color; + rowfontstate[int1]:= normal.font; + lwo1:= fdatacols.rowstate[int1].selected; + if lwo1 <> normal.selected then begin + fdatacols.rowstate.getitempo(int1)^.selected:= lwo1; + end; + rowhidden[int1]:= normal.fold and foldhiddenmask <> 0; + rowfoldlevel[int1]:= normal.fold and foldlevelmask; + end; + finally + dec(fcommandlock); + end; + end; + end; + ik_selection: begin + if igo_selection in foptionsrx then begin + inc(fcommandlock); + try + inc(adatapo,decodeifidata(pifidataty(adatapo),select1)); + with ttxdatagrid(fowner),select1 do begin + fdatacols.selected[makegridcoord(col,row)]:= select; + end; + finally + dec(fcommandlock); + end; + end; + end; + end; + end; +end; + +procedure ttxdatagridcontroller.setowneractive(const avalue: boolean); +begin + //dummy +end; +{ +function ttxdatagridcontroller.getifireckinds: ifireckindsty; +begin + result:= [ik_requestopen,ik_griddata,ik_gridcommand,ik_coldatachange, + ik_rowstatechange]; +end; +} +function ifidatatodatalist(const akind: listdatatypety; const arowcount: integer; + const adata: pchar; const adatalist: tdatalist): integer; + //returns datasize +var + info1: subdatainfoty; +begin + info1.subindex:= 0; + info1.list:= adatalist; + result:= ifidatatodatalist(akind,arowcount,adata,info1); +end; + +function ifidatatodatalist(const akind: listdatatypety; const arowcount: integer; + const adata: pchar; const adatalist: subdatainfoty): integer; +var + int1,int2: integer; + posource,podest: pchar; + movesize,sourcestep,deststep: integer; + po1: pmsestring; + po2: pinteger; + po3: pansistring; + po4: pmsestringintty; +begin + with adatalist do begin + if (list <> nil) and (list.datatype <> akind) and + not((akind = dl_realint) and (list.datatype = dl_realsum)) then begin + raise exception.create('Datakinds do not match.'); + end; + case akind of + dl_integer: begin + result:= arowcount * sizeof(integer); + if list <> nil then begin + move(adata^,list.datapo^,result); + end; + end; + dl_int64: begin + result:= arowcount * sizeof(int64); + if list <> nil then begin + move(adata^,list.datapo^,result); + end; + end; + dl_currency: begin + result:= arowcount * sizeof(currency); + if list <> nil then begin + move(adata^,list.datapo^,result); + end; + end; + dl_real: begin + result:= arowcount * sizeof(real); + if list <> nil then begin + move(adata^,list.datapo^,result); + end; + end; + dl_msestring: begin + po2:= pinteger(adata); + result:= arowcount * sizeof(integer); + if list <> nil then begin + deststep:= list.size; + po1:= list.datapo; + for int1:= 0 to arowcount - 1 do begin + move(po2^,int2,sizeof(integer)); + setlength(po1^,int2); + int2:= int2 * sizeof(msechar); + result:= result + int2; + inc(po2); + move(po2^,pointer(po1^)^,int2); + inc(pchar(pointer(po2)),int2); + inc(pchar(po1),deststep); + end; + end + else begin + for int1:= 0 to arowcount - 1 do begin + int2:= po2^*sizeof(msechar); + result:= result + int2; + inc(po2); + inc(pchar(pointer(po2)),int2); + end; + end; + end; + dl_msestringint: begin + po2:= pinteger(adata); + result:= arowcount * (sizeof(integer)+sizeof(integer)); + if list <> nil then begin + po4:= list.datapo; + deststep:= list.size; + for int1:= 0 to arowcount - 1 do begin + move(po2^,po4^.int,sizeof(integer)); + inc(po2); + move(po2^,int2,sizeof(integer)); + setlength(po4^.mstr,int2); + int2:= int2 * sizeof(msechar); + result:= result + int2; + inc(po2); + move(po2^,po4^.mstr[1],int2); + inc(pchar(pointer(po2)),int2); + inc(pchar(po4),deststep); + end; + end + else begin + for int1:= 0 to arowcount - 1 do begin + inc(po2); + int2:= po2^*sizeof(msechar); + result:= result + int2; + inc(po2); + inc(pchar(pointer(po2)),int2); + end; + end; + end; + dl_realint,dl_realsum: begin + result:= list.setdatablock(adata,sizeof(ifirealintty),arowcount); + exit; + end; + dl_rowstate: begin + move(adata^,int1,sizeof(int1)); + posource:= adata; + inc(posource,sizeof(int1)); + sourcestep:= rowinfosizes[rowinfolevelty(int1)]; + result:= arowcount * sourcestep; + if list <> nil then begin + // tcustomrowstatelist1(adatalist).initdirty; + if tcustomrowstatelist(list).infolevel = + rowinfolevelty(int1) then begin + move(posource^,list.datapo^,result); + end + else begin + podest:= list.datapo; + deststep:= list.size; + movesize:= deststep; + if movesize > sourcestep then begin + movesize:= sourcestep; + end; + for int2:= 0 to arowcount - 1 do begin + move(posource^,podest^,movesize); + inc(posource,sourcestep); + inc(podest,deststep); + end; + end; + tcustomrowstatelist1(list).recalchidden; + end; + result:= result + sizeof(int1); + end; + dl_ansistring: begin + po2:= pinteger(adata); + result:= arowcount * sizeof(integer); + if list <> nil then begin + deststep:= list.size; + po3:= list.datapo; + for int1:= 0 to arowcount - 1 do begin + move(po2^,int2,sizeof(integer)); + setlength(po3^,int2); + result:= result + int2; + inc(po2); + move(po2^,pansistringaty(po3)^[int1][1],int2); + inc(pchar(pointer(po2)),int2); + inc(pchar(po3),deststep); + end; + end + else begin + for int1:= 0 to arowcount - 1 do begin + int2:= po2^; + result:= result + int2; + inc(po2); + inc(pchar(pointer(po2)),int2); + end; + end; + end; + else begin + raise exception.create('Invalid datakind.'); + end; + end; + if list <> nil then begin + list.change(-1); + end; + end; +end; + +procedure datalisttoifidata(const adatalist: tdatalist; + var dest: pchar); overload; +var + int1,int2: integer; + po4: pchar; +begin + with adatalist do begin + po4:= datapo; + case datatype of + dl_integer: begin + int2:= count * sizeof(integer); + move(po4^,dest^,int2); + inc(dest,int2); + end; + dl_int64: begin + int2:= count * sizeof(int64); + move(po4^,dest^,int2); + inc(dest,int2); + end; + dl_currency: begin + int2:= count * sizeof(currency); + move(po4^,dest^,int2); + inc(dest,int2); + end; + dl_real: begin + int2:= count * sizeof(real); + move(po4^,dest^,int2); + inc(dest,int2); + end; + dl_realint,dl_realsum: begin + inc(dest,getdatablock(dest,sizeof(ifirealintty))); + end; + dl_msestring: begin + for int1:= 0 to count - 1 do begin + int2:= length(pmsestringaty(po4)^[int1]); + move(int2,dest^,sizeof(integer)); + int2:= int2 * sizeof(msechar); + inc(dest,sizeof(integer)); + move(pointer(pmsestringaty(po4)^[int1])^,dest^,int2); + inc(dest,int2); + end; + end; + dl_msestringint: begin + for int1:= 0 to count - 1 do begin + move(pmsestringintaty(po4)^[int1].int,dest^,sizeof(integer)); + inc(dest,sizeof(integer)); + int2:= length(pmsestringintaty(po4)^[int1].mstr); + move(int2,dest^,sizeof(integer)); + int2:= int2 * sizeof(msechar); + inc(dest,sizeof(integer)); + move(pmsestringintaty(po4)^[int1].mstr[1],dest^,int2); + inc(dest,int2); + end; + end; + dl_rowstate: begin + int1:= integer(tcustomrowstatelist(adatalist).infolevel); + move(int1,dest^,sizeof(integer)); + inc(dest,sizeof(integer)); + int2:= count * size; + move(po4^,dest^,int2); + inc(dest,int2); + end; + dl_ansistring: begin + for int1:= 0 to count - 1 do begin + int2:= length(pansistringaty(po4)^[int1]); + move(int2,dest^,sizeof(integer)); + inc(dest,sizeof(integer)); + move(pointer(pansistringaty(po4)^[int1])^,dest^,int2); + inc(dest,int2); + end; + end; + else begin + raise exception.create('No ifi datalist'); + end; + end; + end; +end; + +function datalisttoifidata(const adatalist: tdatalist): integer; overload; +// returns size +var + int1: integer; + po1: pmsestring; + po2: pansistring; + po3: pmsestringintty; + s1: integer; +begin + with adatalist do begin + s1:= size; + case adatalist.datatype of + dl_integer: begin + result:= count * sizeof(integer); + end; + dl_int64: begin + result:= count * sizeof(int64); + end; + dl_currency: begin + result:= count * sizeof(currency); + end; + dl_real: begin + result:= count * sizeof(real); + end; + dl_msestring: begin + po1:= datapo; + result:= count * sizeof(integer); + for int1:= 0 to count - 1 do begin + result:= result + length(po1^) * sizeof(msechar); + inc(pchar(po1),s1); + end; + end; + dl_msestringint: begin + po3:= datapo; + result:= count * (sizeof(integer)+sizeof(integer)); + for int1:= 0 to count - 1 do begin + result:= result + length(po3^.mstr) * sizeof(msechar); + inc(pchar(po3),s1); + end; + end; + dl_realint,dl_realsum: begin + result:= count * sizeof(ifirealintty); + end; + dl_rowstate: begin + result:= count * size + sizeof(integer); + end; + dl_ansistring: begin + po2:= datapo; + result:= count * sizeof(integer); + for int1:= 0 to count - 1 do begin + result:= result + length(po2^); + inc(pchar(po2),s1); + end; + end; + else begin + raise exception.create('No ifi datalist.'); + end; + end; + end; +end; + +function ttxdatagridcontroller.encodegriddata( + const asequence: sequencety): ansistring; +var + po1{,po4}: pchar; + int1,int2{,int3,int4}: integer; +// po2: pmsestring; +// po3: pansistring; + ar1: booleanarty; +begin + with ttxdatagrid(fowner) do begin + setlength(ar1,datacols.count); + int2:= 0; + for int1:= 0 to datacols.count - 1 do begin + with datacols[int1] do begin + checkdatalist; + ar1[int1]:= (name <> '') and (datalist.datatype in ifidatatypes); + if ar1[int1] then begin + int2:= int2 + (sizeof(listdatatypety)+1) + length(name) + + datalisttoifidata(datalist); + end; + end; + end; + int2:= int2 + datalisttoifidata(datacols.frowstate); + inititemheader(result,ik_griddata,asequence,int2,po1); + with pgriddatadataty(po1)^ do begin + rows:= rowcount; + cols:= datacols.count; + po1:= @data; + for int1:= 0 to high(ar1) do begin + if ar1[int1] then begin + with datacols[int1] do begin + with pcoldataty(po1)^ do begin + kind:= datalist.datatype; + po1:= @name; + end; + inc(po1,stringtoifiname(name,pifinamety(po1))); + datalisttoifidata(datalist,po1); + end; + end; + end; + datalisttoifidata(datacols.frowstate,po1); + end; + end; +end; + +{ tifirowstatelist } + +procedure tifirowstatelist.sethidden(const index: integer; + const avalue: boolean); +begin + updatebit(getitempo(index)^.fold,foldhiddenbit,avalue); +end; + +procedure tifirowstatelist.setfoldlevel(const index: integer; + const avalue: byte); +begin + replacebits1(byte(getitempo(index)^.fold),byte(avalue),byte(foldlevelmask)); +end; + +procedure tifirowstatelist.setfoldissum(const index: integer; + const avalue: boolean); +begin + updatebit(getitempo(index)^.flags,foldissumbit,avalue); +end; + +end. + diff --git a/mseide-msegui/lib/common/ifi/msejson.pas b/mseide-msegui/lib/common/ifi/msejson.pas new file mode 100644 index 0000000..e5b6ff5 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/msejson.pas @@ -0,0 +1,1177 @@ +{ MSEgui Copyright (c) 2015-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit msejson; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,msestrings,msesystypes,msetypes,sysutils,mseformatstr; + +type + ejsonerror = class(exception); + + jsonencodeoptionty = (jseo_tabindent); + jsonencodeoptionsty = set of jsonencodeoptionty; + + jsondatatypty = (jot_null,jot_string,jot_boolean,jot_int32,jot_int64, + jot_flo64); //zero init -> null + jsondataty = record + case typ: jsondatatypty of + jot_null: (vnull: record end); + jot_string: (vstring: pointer); //msestring + jot_boolean: (vboolean: boolean); + jot_int32: (vint32: int32); + jot_int64: (vint64: int64); + jot_flo64: (vflo64: double); + end; + + jsonkindty = (jok_empty,jok_error,jok_value,jok_object,jok_array); + //zero init -> empty + jsonvaluety = record + case kind: jsonkindty of + jok_empty,jok_error: (err: record end); + jok_object:(obj: pointer); //jsonitemarty + jok_array: (ar: pointer); //jsonvaluearty + jok_value: (val: jsondataty); + end; + pjsonvaluety = ^jsonvaluety; + jsonvaluearty = array of jsonvaluety; + + jsonitemty = record + name: msestring; + value: jsonvaluety; + end; + pjsonitemty = ^jsonitemty; + jsonitemarty = array of jsonitemty; + + arraystartmethodty = procedure(var adata; + const acount: int32) of object; + arrayitemmethodty = procedure(var adata; + const aindex: int32; const aitem: jsonvaluety) of object; + + arraystartprocty = procedure(var adata; + const acount: int32); + arrayitemprocty = procedure(var adata; + const aindex: int32; const aitem: jsonvaluety); + + tjsoncontainer = class + private + protected + fvalue: jsonvaluety; + function findvaluevalue(const names: array of msestring): pjsonvaluety; + public + constructor create(const avalue: jsonvaluety); //owns the value + constructor create(const adata: string); + class function trycreate(out ainstance: tjsoncontainer; + const adata: string): boolean; + destructor destroy(); override; + property value: jsonvaluety read fvalue; + function findvalue(const names: array of msestring; + const raiseexception: boolean = false): pjsonvaluety; + //nil if not found + function asstring(const names: array of msestring): msestring; + function asboolean(const names: array of msestring): boolean; + function asint32(const names: array of msestring): int32; + function asint64(const names: array of msestring): int64; + function asflo64(const names: array of msestring): flo64; + procedure iteratearray(const names: array of msestring; var adata; + const startproc: arraystartmethodty; + const itemproc: arrayitemmethodty); + procedure iteratearray(const names: array of msestring; var adata; + const startproc: arraystartprocty; + const itemproc: arrayitemprocty); + end; + +procedure jsonvalueinit(var avalue: jsonvaluety); //inits to null value +procedure jsonvaluefree(var avalue: jsonvaluety); + +function jsonfindvalue(const avalue: jsonvaluety; + const names: array of msestring; + const raiseexception: boolean = false): pjsonvaluety; +function jsonasstring(const avalue: jsonvaluety; + const names: array of msestring): msestring; +function jsonasint32(const avalue: jsonvaluety; + const names: array of msestring): int32; +function jsonasint64(const avalue: jsonvaluety; + const names: array of msestring): int64; +function jsonasflo64(const avalue: jsonvaluety; + const names: array of msestring): flo64; +function jsonasboolean(const avalue: jsonvaluety; + const names: array of msestring): boolean; +procedure jsoniteratearray(const avalue: jsonvaluety; + const names: array of msestring; + var adata; const startproc: arraystartprocty; + const itemproc: arrayitemprocty); +procedure jsoniteratearray(const avalue: jsonvaluety; + const names: array of msestring; + var adata; const startproc: arraystartmethodty; + const itemproc: arrayitemmethodty); +function jsonadditems(var jvalue: jsonvaluety; const anames: array of msestring; + const avalues: array of const): pjsonvaluety; + //if jvalue is a null value it will be converted to object + //[nil] -> null, returns the last added item or @jvalue +function jsonaddvalues(var jvalue: jsonvaluety; + const avalues: array of const): pjsonvaluety; + //if jvalue is a null value it will be converted to array + //[nil] -> null, returns the last added item or @jvalue + +function jsondecode(const adata: string; out avalue:jsonvaluety): boolean; +function jsonencode(const avalue: jsonvaluety; const adest: tstream; + const aoptions: jsonencodeoptionsty = []): syserrorty; + +implementation +uses + msearrayutils,msefloattostr; + +procedure error(const atext: msestring); +begin + raise ejsonerror.create('json error: '+ansistring(atext)); +end; + +procedure nameserror(const names: array of msestring); +begin + error('"'+concatstrings(opentodynarraym(names),'.')+'" not found'); +end; + +procedure conversionerror(const names: array of msestring); +begin + error('"'+concatstrings(opentodynarraym(names),'.')+'" conversion error'); +end; + +{$implicitexceptions off} + +procedure jsonvalueinit(var avalue: jsonvaluety); +begin + avalue.kind:= jok_value; + avalue.val.typ:= jot_null; +end; + +procedure jsonitemfree(var aitem: jsonitemty); forward; + +procedure jsonvaluefree(var avalue: jsonvaluety); +var + po1: pjsonitemty; + po2: pjsonvaluety; + pe: pointer; +begin + case avalue.kind of + jok_value: begin + if avalue.val.typ = jot_string then begin + msestring(avalue.val.vstring):= ''; + end; + end; + jok_array: begin + po2:= avalue.ar; + if po2 <> nil then begin + pe:= po2 + high(jsonvaluearty(po2)); + while po2 <= pe do begin + jsonvaluefree(po2^); + inc(po2); + end; + freeuninitedarray(avalue.ar); + end; + end; + jok_object: begin + po1:= avalue.obj; + if po1 <> nil then begin + pe:= po1 + high(jsonitemarty(po1)); + while po1 <= pe do begin + jsonitemfree(po1^); + inc(po1); + end; + freeuninitedarray(avalue.obj); + end; + end; + end; + avalue.kind:= jok_value; + avalue.val.typ:= jot_null; +end; + +procedure jsonitemfree(var aitem: jsonitemty); +begin + aitem.name:= ''; + jsonvaluefree(aitem.value); +end; + +function stringtojsonstringascii(const avalue: msestring): ansistring; +var + ps,pe: pmsechar; + pd: pchar; + ch1: char; + mch1: msechar; +begin + setlength(result,length(avalue)*6+2); //max; + ps:= pointer(avalue); + pe:= ps + length(avalue); + pd:= pointer(result); + pd^:= '"'; + inc(pd); + while ps < pe do begin + ch1:= char(byte(ps^)); + pd^:= '\'; + case ps^ of + '"','\','/': begin + inc(pd); + end; + c_backspace: begin + inc(pd); + ch1:= 'b'; + end; + c_formfeed: begin + inc(pd); + ch1:= 'f'; + end; + c_linefeed: begin + inc(pd); + ch1:= 'r'; + end; + c_return: begin + inc(pd); + ch1:= 'r'; + end; + c_tab: begin + inc(pd); + ch1:= 't'; + end; + else begin + mch1:= ps^; + if (mch1 < #$20) or (mch1 > #$7f) then begin + inc(pd); + pd^:= 'u'; + inc(pd); + pd^:= charhex[(card16(mch1) and $f000) shr 12]; + inc(pd); + pd^:= charhex[(card16(mch1) and $0f00) shr 8]; + inc(pd); + pd^:= charhex[(card16(mch1) and $00f0) shr 4]; + inc(pd); + ch1:= charhex[(card16(mch1) and $000f)]; + end; + end; + end; + pd^:= ch1; + inc(pd); + inc(ps); + end; + pd^:= '"'; + inc(pd); + setlength(result,pd-pchar(pointer(result))); +end; + +const + maxindent = 32; + indents: array[0..maxindent] of char8 = ( + c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab, //8 + c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab, //16 + c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab, //24 + c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab, //32 + c_tab); + +function jsonencode(const avalue: jsonvaluety; const adest: tstream; + const aoptions: jsonencodeoptionsty = []): syserrorty; +var + error: syserrorty; + indentlevel,indentcount: int32; + hasindent: boolean; + + procedure incindent(); + begin + if hasindent then begin + inc(indentlevel); + if indentlevel <= maxindent then begin + indentcount:= indentlevel; + end; + end; + end; + + procedure decindent(); + begin + if hasindent then begin + dec(indentlevel); + if indentlevel <= maxindent then begin + indentcount:= indentlevel; + end; + end; + end; + + procedure putindent(); + begin + if (indentcount > 0) and (error = sye_ok) then begin + error:= adest.trywritebuffer(indents,indentcount); + end; + end;//putindent + + procedure put(const atext: string); + begin + if error = sye_ok then begin + error:= adest.trywritebuffer(pointer(atext)^,length(atext)); + end; + end;//put + + procedure putvalue(const avalue: jsonvaluety); + var + pi: pjsonitemty; + pv: pjsonvaluety; + pe: pointer; + begin + case avalue.kind of + jok_object: begin + put('{'+c_linefeed); + incindent(); + pi:= avalue.obj; + pe:= pi + dynarraylength(avalue.obj); + if pe > pi then begin + while error = sye_ok do begin + putindent(); + put(stringtojsonstringascii(pi^.name)+':'); + putvalue(pi^.value); + inc(pi); + if pi >= pe then begin + break; + end; + put(','+c_linefeed); + end; + end + else begin +// decindent(); //same indent as '{' + putindent(); +// incindent() + end; + put('}'); + decindent(); + end; + jok_array: begin + put('['+c_linefeed); + incindent(); + pv:= avalue.ar; + pe:= pv + dynarraylength(avalue.ar); + if pe > pv then begin + while error = sye_ok do begin + putindent(); + putvalue(pv^); + inc(pv); + if pv >= pe then begin + break; + end; + put(','+c_linefeed); + end; + end + else begin + putindent(); + end; + put(']'); + decindent(); + end; + jok_value: begin + case avalue.val.typ of + jot_null: begin + put('null'); + end; + jot_string: begin + put(stringtojsonstringascii(msestring(avalue.val.vstring))); + end; + jot_boolean: begin + if avalue.val.vboolean then begin + put('true'); + end + else begin + put('false'); + end; + end; + jot_int32: begin + put(inttostr(avalue.val.vint32)); + end; + jot_int64: begin + put(inttostr(avalue.val.vint64)); + end; + jot_flo64: begin + put(ansistring(doubletostring(avalue.val.vflo64,0,fsm_default,'.'))); + end; + end; + end; + end; + end;//putvalue + +begin + error:= sye_ok; + indentlevel:= 0; + indentcount:= 0; + hasindent:= jseo_tabindent in aoptions; + putvalue(avalue); + result:= error; +end; + +function jsondecode(const adata: string; out avalue: jsonvaluety): boolean; +const + whitechars = [' ',c_tab,c_linefeed,c_return]; +var + pc,pe: pchar; + error: boolean; + + procedure skipwhitespace(); inline; + begin + if pc < pe then begin + inc(pc); + while (pc^ in whitechars) and (pc < pe) do begin + inc(pc); + end; + end; + end;//skipwhitespace + + function getstring: msestring; + var + po1,po2,pe1: pchar; + len,capacity: int32; + i1: int32; + mstr1: msestring; + mch1: msechar; + ca1: card32; + + procedure put(); inline; + begin + if po1 <> po2 then begin + mstr1:= utf8tostring(po2,po1-po2); + i1:= len; + len:= len + length(mstr1); + if len >= capacity then begin //at least one character reserve + capacity:= 2*len+32; + setlength(result,capacity); + end; + move(pointer(mstr1)^,(pmsechar(pointer(result))+i1)^, + length(mstr1)*sizeof(msechar)); + end + else begin + if len >= capacity then begin //at least one character reserve + capacity:= 2*len+32; + setlength(result,capacity); + end; + end; + end;//put + + begin//getstring + po1:= pc; + pe1:= pe; + result:= ''; + len:= 0; + capacity:= 0; + inc(po1); //leading " + po2:= po1; + while (po1^ <> '"') and (po1 < pe1) do begin + if po1^ = '\' then begin + put(); + inc(po1); // '\' + case po1^ of + '"': mch1:= '"'; + '\': mch1:= '\'; + '/': mch1:= '/'; + 'b': mch1:= c_backspace; + 'f': mch1:= c_formfeed; + 'n': mch1:= c_linefeed; + 'r': mch1:= c_return; + 't': mch1:= c_tab; + 'u': begin + inc(po1); + if pe1-po1 > 4 then begin + if not trystrtohex(po1,4,ca1) then begin + error:= true; + break; + end; + inc(po1,3); + mch1:= msechar(card16(ca1)); + end; + end; + end; + pmsechar(pointer(result))[len]:= mch1; + inc(len); + po2:= po1 + 1; //new start + end; + inc(po1); + end; + put(); + pc:= po1; + if po1^ <> '"' then begin + error:= true; + end; + setlength(result,len); + end;//getstring + + procedure getobj(var avalue: jsonvaluety); forward; + procedure getarray(var avalue: jsonvaluety); forward; + + procedure getvalue(var avalue: jsonvaluety); + var + mstr1: msestring; + po1,po2,po3: pchar; + i1: int32; + lstr1: lstringty; + begin + skipwhitespace(); + if pc < pe then begin + avalue.kind:= jok_value; //default + case pc^ of + '{': begin + getobj(avalue); + end; + '[': begin + getarray(avalue); + end; + '"': begin + avalue.val.typ:= jot_string; + mstr1:= getstring; + stringaddref(mstr1); + avalue.val.vstring:= pointer(mstr1); + end; + else begin + po1:= pc; + po2:= po1; + while not (po2^ in whitechars+[',',']','}']) and (po2 < pe) do begin + inc(po2); + end; + pc:= po2-1; + i1:= po2-po1; + if i1 = 4 then begin + if (po1^ = 't') and ((po1+1)^ = 'r') and ((po1+2)^ = 'u') and + ((po1+3)^ = 'e') then begin + avalue.val.typ:= jot_boolean; + avalue.val.vboolean:= true; + exit; + end; + if (po1^ = 'n') and ((po1+1)^ = 'u') and ((po1+2)^ = 'l') and + ((po1+3)^ = 'l') then begin + avalue.val.typ:= jot_null; + exit; + end; + end + else begin + if (i1 = 5) and (po1^ = 'f') and ((po1+1)^ = 'a') and ((po1+2)^ = 'l') and + ((po1+3)^ = 's') and ((po1+4)^ = 'e') then begin + avalue.val.typ:= jot_boolean; + avalue.val.vboolean:= true; + exit; + end + else begin + po3:= po1; + lstr1.po:= po1; + lstr1.len:= i1; + while po3 < po2 do begin + if po3^ in ['.','e','E'] then begin + if trystrtodouble(lstr1,avalue.val.vflo64,'.') then begin + avalue.val.typ:= jot_flo64; + end + else begin + error:= true; + end; + exit; + end; + inc(po3); + end; + if trystrtoint(lstr1,avalue.val.vint32) then begin + avalue.val.typ:= jot_int32; + end + else begin + if trystrtoint64(lstr1,avalue.val.vint64) then begin + avalue.val.typ:= jot_int64; + end + else begin + error:= true; + end; + end; + end; + end; + end; + end; + end; + end;//getvalue + + procedure getarray(var avalue: jsonvaluety); + var + ar1: jsonvaluearty; + count: int32; + value: pjsonvaluety; + begin + ar1:= nil; + avalue.kind:= jok_array; + count:= 0; + skipwhitespace(); + if pc^ <> ']' then begin //else empty + dec(pc); //restore leading char + repeat + additem(ar1,typeinfo(ar1),count); + value:= @ar1[count-1]; + getvalue(value^); //calls skipwhitespace() + skipwhitespace(); + if pc^ <> ',' then begin + if pc^ <> ']' then begin + error:= true; + end; + break; + end; + until error; + end; + setlength(ar1,count); + arrayaddref(ar1); + avalue.ar:= pointer(ar1); + end;//getarray + + procedure getobj(var avalue: jsonvaluety); + var + ar1: jsonitemarty; + count: int32; + item: pjsonitemty; + begin + ar1:= nil; + avalue.kind:= jok_object; + count:= 0; + repeat + additem(ar1,typeinfo(ar1),count); + item:= @ar1[count-1]; + skipwhitespace(); //leading '{' or ',' + if pc^ <> '"' then begin + error:= true; + break; + end; + item^.name:= getstring(); + skipwhitespace(); + if pc^ = ':' then begin + getvalue(item^.value); //calls skipwhitespace() + end + else begin + error:= true; + end; + skipwhitespace(); + if pc^ <> ',' then begin + if pc^ <> '}' then begin + error:= true; + end; + break; + end; + until error; + setlength(ar1,count); + arrayaddref(ar1); + avalue.obj:= pointer(ar1); + end;//getobj + +begin + error:= false; + if adata <> '' then begin + pc:= pointer(adata); + pe:= pc+length(adata); + dec(pc); + getvalue(avalue); + if error then begin + jsonvaluefree(avalue); + avalue.kind:= jok_error; + end; + end + else begin + avalue.kind:= jok_value; + avalue.val.typ:= jot_null; + end; + result:= not error; +end; + +function jsonfindvalue(const avalue: jsonvaluety; + const names: array of msestring; + const raiseexception: boolean = false): pjsonvaluety; + //todo: use hash cache +var + pv: pjsonvaluety; + pi: pjsonitemty; + pe: pointer; + i1: int32; + mstr1: msestring; + + procedure nameerror(); + begin + pv:= nil; + if raiseexception then begin + nameserror(copy(opentodynarraym(names),0,i1+1)); + end; + end;//nameerror + +begin + pv:= @avalue; + if high(names) >= 0 then begin + for i1:= 0 to high(names) do begin + if pv^.kind <> jok_object then begin + nameerror(); + break; + end; + mstr1:= names[i1]; + pi:= pv^.obj; + pe:= pi + dynarraylength(pi); + while (pi < pe) and (pi^.name <> mstr1) do begin + inc(pi); + end; + if pi < pe then begin + pv:= @pi^.value; + end + else begin + nameerror(); + break; + end; + end; + end; + result:= pv; +end; + +function jsonfindvaluevalue(const avalue: jsonvaluety; + const names: array of msestring): pjsonvaluety; +begin + result:= jsonfindvalue(avalue,names,true); + if result^.kind <> jok_value then begin + error('No value'); + end; +end; + +function jsonasstring(const avalue: jsonvaluety; + const names: array of msestring): msestring; +var + po1: pjsonvaluety; +begin + po1:= jsonfindvaluevalue(avalue,names); + case po1^.val.typ of + jot_null: begin + result:= ''; + end; + jot_string: begin + result:= msestring(po1^.val.vstring); + end; + jot_boolean: begin + if po1^.val.vboolean then begin + result:= 'true'; + end + else begin + result:= 'false'; + end; + end; + jot_int32: begin + result:= inttostrmse(po1^.val.vint32); + end; + jot_int64: begin + result:= inttostrmse(po1^.val.vint64); + end; + jot_flo64: begin + result:= realtostrmse(po1^.val.vflo64); + end; + end; +end; + +function jsonasint32(const avalue: jsonvaluety; + const names: array of msestring): int32; +var + po1: pjsonvaluety; +begin + po1:= jsonfindvaluevalue(avalue,names); + case po1^.val.typ of + jot_int32: begin + result:= po1^.val.vint32; + end; + jot_int64: begin + result:= po1^.val.vint64; + end; + jot_flo64: begin + result:= round(po1^.val.vflo64); + end; + jot_boolean: begin + if po1^.val.vboolean then begin + result:= 1; + end + else begin + result:= 0; + end; + end; + jot_null: begin + result:= 0; + end; + jot_string: begin + if not trystrtoint(msestring(po1^.val.vstring),result) then begin + conversionerror(names); + end; + end; + end; +end; + +function jsonasint64(const avalue: jsonvaluety; + const names: array of msestring): int64; +var + po1: pjsonvaluety; +begin + po1:= jsonfindvaluevalue(avalue,names); + case po1^.val.typ of + jot_int64: begin + result:= po1^.val.vint64; + end; + jot_int32: begin + result:= po1^.val.vint32; + end; + jot_flo64: begin + result:= round(po1^.val.vflo64); + end; + jot_boolean: begin + if po1^.val.vboolean then begin + result:= 1; + end + else begin + result:= 0; + end; + end; + jot_null: begin + result:= 0; + end; + jot_string: begin + if not trystrtoint64(msestring(po1^.val.vstring),result) then begin + conversionerror(names); + end; + end; + end; +end; + +function jsonasflo64(const avalue: jsonvaluety; + const names: array of msestring): flo64; +var + po1: pjsonvaluety; +begin + po1:= jsonfindvaluevalue(avalue,names); + case po1^.val.typ of + jot_flo64: begin + result:= po1^.val.vflo64; + end; + jot_int32: begin + result:= po1^.val.vint32; + end; + jot_int64: begin + result:= po1^.val.vint64; + end; + jot_boolean: begin + if po1^.val.vboolean then begin + result:= 1; + end + else begin + result:= 0; + end; + end; + jot_null: begin + result:= 0; + end; + jot_string: begin + if not trystrtodouble(msestring(po1^.val.vstring),result,'.') then begin + conversionerror(names); + end; + end; + end; +end; + +function jsonasboolean(const avalue: jsonvaluety; + const names: array of msestring): boolean; +var + po1: pjsonvaluety; +begin + po1:= jsonfindvaluevalue(avalue,names); + case po1^.val.typ of + jot_boolean: begin + result:= po1^.val.vboolean; + end; + jot_int32: begin + result:= po1^.val.vint32 <> 0; + end; + jot_int64: begin + result:= po1^.val.vint64 <> 0; + end; + jot_flo64: begin + result:= round(po1^.val.vflo64) <> 0; + end; + jot_null: begin + result:= false; + end; + jot_string: begin + result:= msestring(po1^.val.vstring) = 'true'; + if not result and (msestring(po1^.val.vstring) <> 'false') then begin + conversionerror(names); + end; + end; + end; +end; + +procedure jsoniteratearray(const avalue: jsonvaluety; + const names: array of msestring; + var adata; const startproc: arraystartprocty; + const itemproc: arrayitemprocty); +var + po1: pjsonvaluety; + i1: int32; + pv,pe: pjsonvaluety; +begin + po1:= jsonfindvalue(avalue,names,true); + if po1^.kind <> jok_array then begin + error('No array'); + end; + pv:= po1^.ar; + i1:= dynarraylength(pv); + if startproc <> nil then begin + startproc(adata,i1); + end; + if itemproc <> nil then begin + pe:= pv + i1; + i1:= 0; + while pv < pe do begin + itemproc(adata,i1,pv^); + inc(pv); + inc(i1); + end; + end; +end; + +procedure jsoniteratearray(const avalue: jsonvaluety; + const names: array of msestring; + var adata; const startproc: arraystartmethodty; + const itemproc: arrayitemmethodty); +var + po1: pjsonvaluety; + i1: int32; + pv,pe: pjsonvaluety; +begin + po1:= jsonfindvalue(avalue,names,true); + if po1^.kind <> jok_array then begin + error('No array'); + end; + pv:= po1^.ar; + i1:= dynarraylength(pv); + if startproc <> nil then begin + startproc(adata,i1); + end; + if itemproc <> nil then begin + pe:= pv + i1; + i1:= 0; + while pv < pe do begin + itemproc(adata,i1,pv^); + inc(pv); + inc(i1); + end; + end; +end; + +procedure setvalue(var jvalue: jsonvaluety; const avalue: tvarrec); +begin + with jvalue,avalue do begin //todo: vtvariant + kind:= jok_value; + case avalue.vtype of + vtinteger: begin + val.typ:= jot_int32; + val.vint32:= vinteger; + end; + vtunicodestring: begin + val.typ:= jot_string; + msestring(val.vstring):= unicodestring(vunicodestring); + end; + vtwidestring: begin + val.typ:= jot_string; + msestring(val.vstring):= widestring(vunicodestring); + end; + vtansistring: begin + val.typ:= jot_string; + msestring(val.vstring):= widestring(vansistring); + end; + vtchar: begin + val.typ:= jot_string; + msestring(val.vstring):= msestring(vchar); + end; + vtwidechar: begin + val.typ:= jot_string; + msestring(val.vstring):= vwidechar; + end; + vtstring: begin + val.typ:= jot_string; + msestring(val.vstring):= msestring(vstring^); + end; + vtpchar: begin + val.typ:= jot_string; + msestring(val.vstring):= msestring(string(vpchar)); + end; + vtpwidechar: begin + val.typ:= jot_string; + msestring(val.vstring):= msestring(vpwidechar); + end; + vtextended: begin + val.typ:= jot_flo64; + val.vflo64:= vextended^; + end; + vtcurrency: begin + val.typ:= jot_flo64; + val.vflo64:= vcurrency^; + end; + vtboolean: begin + val.typ:= jot_boolean; + val.vboolean:= vboolean; + end; + vtint64: begin + val.typ:= jot_int64; + val.vint64:= vint64^; + end; + else begin + val.typ:= jot_null; + end; + end; + end; +end; + +function jsonadditems(var jvalue: jsonvaluety; const anames: array of msestring; + const avalues: array of const): pjsonvaluety; + //if jvalue is a null value it will be converted to object + //[nil] -> null, returns the last added item or @jvalue +var + i1,i2: int32; + pi: pjsonitemty; +begin + if high(anames) <> high(avalues) then begin + error('jsonadditems(): Name count <> value count'); + end; + if (jvalue.kind = jok_value) and (jvalue.val.typ = jot_null) then begin + jvalue.kind:= jok_object; + jvalue.obj:= nil; + end; + if jvalue.kind <> jok_object then begin + error('jsonadditems(): jvalue must be jok_object or null value'); + end; + i2:= high(avalues); + if i2 >= 0 then begin + i1:= high(jsonitemarty(jvalue.ar)); + setlength(jsonitemarty(jvalue.ar),i1+i2+2); + pi:= @jsonitemarty(jvalue.ar)[i1+1]; + for i1:= 0 to i2 do begin + pi^.name:= anames[i1]; + setvalue(pi^.value,avalues[i1]); + inc(pi); + end; + result:= @((pi-1)^.value); + end + else begin + result:= @jvalue; + end; +end; + +function jsonaddvalues(var jvalue: jsonvaluety; + const avalues: array of const): pjsonvaluety; + //if jvalue is a null value it will be converted to array + //[nil] -> null, returns the last added item or @jvalue +var + i1,i2: int32; + pv: pjsonvaluety; +begin + if (jvalue.kind = jok_value) and (jvalue.val.typ = jot_null) then begin + jvalue.kind:= jok_array; + jvalue.ar:= nil; + end; + if jvalue.kind <> jok_array then begin + error('jsonaddvalues(): jvalue must be jok_object or null value'); + end; + i2:= high(avalues); + if i2 >= 0 then begin + i1:= high(jsonvaluearty(jvalue.ar)); + setlength(jsonvaluearty(jvalue.ar),i1+i2+2); + pv:= @jsonvaluearty(jvalue.ar)[i1+1]; + for i1:= 0 to i2 do begin + setvalue(pv^,avalues[i1]); + inc(pv); + end; + result:= pv-1; + end + else begin + result:= @jvalue; + end; +end; + +{$implicitexceptions on} + +{ tjsoncontainer } + +constructor tjsoncontainer.create(const avalue: jsonvaluety); +begin + fvalue:= avalue; +end; + +class function tjsoncontainer.trycreate(out ainstance: tjsoncontainer; + const adata: string): boolean; +var + val1: jsonvaluety; +begin + result:= jsondecode(adata,val1); + if result then begin + ainstance:= tjsoncontainer.create(val1); + ainstance.fvalue:= val1; + end; +end; + +constructor tjsoncontainer.create(const adata: string); +begin + if not jsondecode(adata,fvalue) then begin + error('Invalid json data'); + end; +end; + +destructor tjsoncontainer.destroy; +begin + jsonvaluefree(fvalue); +end; + +function tjsoncontainer.findvalue(const names: array of msestring; + const raiseexception: boolean = false): pjsonvaluety; + //todo: use hash cache +begin + result:= jsonfindvalue(fvalue,names,raiseexception); +end; + +function tjsoncontainer.findvaluevalue( + const names: array of msestring): pjsonvaluety; +begin + result:= jsonfindvaluevalue(fvalue,names); +end; + +function tjsoncontainer.asstring(const names: array of msestring): msestring; +begin + result:= jsonasstring(fvalue,names); +end; + +function tjsoncontainer.asint32(const names: array of msestring): int32; +begin + result:= jsonasint32(fvalue,names); +end; + +function tjsoncontainer.asint64(const names: array of msestring): int64; +begin + result:= jsonasint64(fvalue,names); +end; + +function tjsoncontainer.asflo64(const names: array of msestring): flo64; +begin + result:= jsonasflo64(fvalue,names); +end; + +function tjsoncontainer.asboolean(const names: array of msestring): boolean; +begin + result:= jsonasboolean(fvalue,names); +end; + +procedure tjsoncontainer.iteratearray(const names: array of msestring; + var adata; const startproc: arraystartprocty; + const itemproc: arrayitemprocty); +begin + jsoniteratearray(fvalue,names,adata,startproc,itemproc); +end; + +procedure tjsoncontainer.iteratearray(const names: array of msestring; + var adata; const startproc: arraystartmethodty; + const itemproc: arrayitemmethodty); +begin + jsoniteratearray(fvalue,names,adata,startproc,itemproc); +end; + +end. + diff --git a/mseide-msegui/lib/common/ifi/msesockets.pas b/mseide-msegui/lib/common/ifi/msesockets.pas new file mode 100644 index 0000000..3779352 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/msesockets.pas @@ -0,0 +1,815 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesockets; +//todo: separate comm base code and sockets + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + classes,mclasses,mseglob,mseclasses,msesystypes,msesys,msestrings,msepipestream, + mseapplication,msethread,mseevent,msecryptio,msetypes,msesercomm; + +const + defaultmaxconnections = 16; + +type + + tsocketreader = class(tcommreader) + protected + procedure settimeoutms(const avalue: integer); override; + procedure sethandle(value: integer); override; + function internalread(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean = false): boolean; override; + procedure closehandle(const ahandle: integer); override; + public + constructor create(const aowner: tcustomcommpipes); + end; + + tsocketwriter = class(tcommwriter) + protected + procedure settimeoutms(const avalue: integer); override; + procedure closehandle(const ahandle: integer); override; + function internalwrite(const buffer; count: longint): longint; override; + end; + + tcustomsocketclient = class; + + tcustomsocketpipes = class(tcustomcommpipes) + protected + procedure createpipes; override; + end; + + tsocketpipes = class(tcustomsocketpipes) + published + property optionsreader; + property overloadsleepus; + property oninputavailable; + property oncommbroken; + end; +{ + tclientsocketpipes = class(tsocketpipes) + protected + procedure doafterconnect; override; + end; + + + tserversocketpipes = class(tcustomsocketpipes) + protected + procedure doafterconnect; override; + end; +} + + socketpipesarty = array of tsocketpipes; + tcustomsocketserver = class; + + tcustomsocketcomp = class(tcustomcommcomp) + end; + + tsocketcomp = class(tcustomsocketcomp) + published + property active; + property activator; + property cryptoio; + property onbeforeconnect; + property onafterconnect; + property onbeforedisconnect; + property onafterdisconnect; + end; + + tcustomurlsocketcomp = class(tcustomsocketcomp) + private + fkind: socketkindty; + furl: msestring; + fport: word; + procedure seturl(const avalue: filenamety); + protected + function getsockaddr: socketaddrty; + property kind: socketkindty read fkind write fkind default sok_local; + property url: filenamety read furl write seturl; + property port: word read fport write fport default 0; + end; + + turlsocketcomp = class(tcustomurlsocketcomp) + published + property active; + property activator; + property cryptoio; + property onbeforeconnect; + property onafterconnect; + property onbeforedisconnect; + property onafterdisconnect; + + property kind; + property url; + property port; + end; + + tcustomsocketclient = class(tcustomurlsocketcomp) + private + procedure setpipes(const avalue: tsocketpipes); + protected + fpipes: tsocketpipes; + procedure internalconnect; override; + procedure internaldisconnect; override; + procedure closepipes(const sender: tcustomcommpipes); override; + procedure doasyncevent(var atag: integer); override; + function trywritedata(const adata: string): syserrorty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property pipes: tsocketpipes read fpipes write setpipes; + end; + + tsocketclient = class(tcustomsocketclient) + published + property pipes; + property active; + property activator; + property cryptoio; + property onbeforeconnect; + property onafterconnect; + property onbeforedisconnect; + property onafterdisconnect; + + property kind; + property url; + property port; + end; + + tsocketstdio = class(tsocketcomp) + private + procedure setpipes(const avalue: tsocketpipes); + function getcryptoiokind: cryptoiokindty; + procedure setcryptoiokind(const avalue: cryptoiokindty); + protected + fpipes: tsocketpipes; + procedure internalconnect; override; + procedure internaldisconnect; override; + procedure closepipes(const sender: tcustomcommpipes); override; + procedure doasyncevent(var atag: integer); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property pipes: tsocketpipes read fpipes write setpipes; + property cryptiokind: cryptoiokindty read getcryptoiokind + write setcryptoiokind default cyk_none; + end; + + + socketaccepteventty = procedure(const sender: tcustomsocketserver; + const asocket: integer; + const addr: socketaddrty; var accept: boolean) of object; + socketserverconnecteventty = procedure(const sender: tcustomsocketserver; + const apipes: tcustomcommpipes) of object; + + socketserverstatety = (sss_closepipespending); + socketserverstatesty = set of socketserverstatety; + + tcustomsocketserver = class(tcustomurlsocketcomp) + private + fstate: socketserverstatesty; + fthread: tmsethread; + fmaxconnections: integer; + faccepttimeoutms: integer; + fonaccept: socketaccepteventty; + fonbeforechconnect: socketserverconnecteventty; + fonafterchconnect: socketserverconnecteventty; + fonbeforechdisconnect: socketserverconnecteventty; + fonafterchdisconnect: socketserverconnecteventty; + fpipes: socketpipesarty; + foverloadsleepus: integer; + foninputavailable: commpipeseventty; + fonsocketbroken: commpipeseventty; + fconnectioncount: integer; + foptionsreader: pipereaderoptionsty; + frxtimeoutms: integer; + ftxtimeoutms: integer; + function execthread(thread: tmsethread): integer; + protected + procedure internaldisconnect; override; + procedure doclosepipes; + procedure closepipes(const sender: tcustomcommpipes); override; + procedure doasyncevent(var atag: integer); override; + procedure doafterchconnect(const sender: tcustomcommpipes); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure runhandlerapp(const asocket: integer; const acommandline: filenamety); + property connectioncount: integer read fconnectioncount; + published + property maxconnections: integer read fmaxconnections write fmaxconnections + default defaultmaxconnections; + property accepttimeoutms: integer read faccepttimeoutms + write faccepttimeoutms default 0; + property rxtimeoutms: integer read frxtimeoutms write frxtimeoutms default 0; + property txtimeoutms: integer read ftxtimeoutms write ftxtimeoutms default 0; + + property onaccept: socketaccepteventty read fonaccept write fonaccept; + property onbeforechconnect: socketserverconnecteventty read fonbeforechconnect + write fonbeforechconnect; + property onafterchconnect: socketserverconnecteventty read fonafterchconnect + write fonafterchconnect; + property onbeforechdisconnect: socketserverconnecteventty read fonbeforechdisconnect + write fonbeforechdisconnect; + property onafterchdisconnect: socketserverconnecteventty read fonafterchdisconnect + write fonafterchdisconnect; + property overloadsleepus: integer read foverloadsleepus + write foverloadsleepus default -1; + //checks application.checkoverload before calling oninputavaliable + //if >= 0 + property optionsreader: pipereaderoptionsty read foptionsreader + write foptionsreader default []; + property oninputavailable: commpipeseventty read foninputavailable + write foninputavailable; + property onsocketbroken: commpipeseventty read fonsocketbroken + write fonsocketbroken; + end; + + tsocketserver = class(tcustomsocketserver) + protected + procedure internalconnect; override; + published + property active; + property activator; + property cryptoio; + property onbeforeconnect; + property onafterconnect; + property onbeforedisconnect; + property onafterdisconnect; + + property kind; + property url; + property port; + end; + + tsocketserverstdio = class(tcustomsocketserver) + protected + procedure internalconnect; override; + public + constructor create(aowner: tcomponent); override; + published + property active; + end; + +procedure checksyserror(const aresult: integer); + +procedure socketerror(const error: syserrorty; const text: string = ''); + +implementation +uses + msefileutils,msesysintf,sysutils,msestream,mseprocutils,msesysutils, + msesocketintf,msearrayutils; + +type + tcustompipes1 = class(tcustomcommpipes); + +procedure socketerror(const error: syserrorty; const text: string = ''); +begin + case error of + sye_ok: begin + end; + sye_sockaddr: begin + raise esys.create(error,text+soc_getaddrerrortext(mselasterror)); + end; + sye_socket: begin + raise esys.create(error,text+soc_geterrortext(mselasterror)); + end; + else begin + syserror(error,msestring(text)); + end; + end; +end; + +procedure checksyserror(const aresult: integer); +begin + if aresult <> 0 then begin + syserror(syelasterror); + end; +end; + +{ tcustomurlsocketcomp} + +procedure tcustomurlsocketcomp.seturl(const avalue: filenamety); +begin + checkinactive; + furl:= avalue; +end; + +function tcustomurlsocketcomp.getsockaddr: socketaddrty; +begin + with result do begin + kind:= fkind; + port:= fport; + fillchar(platformdata,sizeof(platformdata),0); + size:= 0; + url:= furl; + case fkind of + sok_local: begin + end; + sok_inet,sok_inet6: begin + socketerror(soc_urltoaddr(result)); + end; + end; + end; +end; + +{ tsocketstdio } + +constructor tsocketstdio.create(aowner: tcomponent); +begin + if fpipes = nil then begin + fpipes:= tsocketpipes.create(self,cyk_none); + end; + inherited; +end; + +destructor tsocketstdio.destroy; +begin + fpipes.free; + inherited; +end; + +procedure tsocketstdio.setpipes(const avalue: tsocketpipes); +begin + fpipes.assign(avalue); +end; + +procedure tsocketstdio.internalconnect; +begin + fpipes.tx.handle:= sys_stdout; + fpipes.rx.handle:= sys_stdin; + factive:= true; +end; + +procedure tsocketstdio.internaldisconnect; +begin + fpipes.handle:= invalidfilehandle; + inherited +end; + +procedure tsocketstdio.closepipes(const sender: tcustomcommpipes); +begin + asyncevent(closepipestag); +end; + +procedure tsocketstdio.doasyncevent(var atag: integer); +begin + if atag = closepipestag then begin + disconnect; + end; +end; + +function tsocketstdio.getcryptoiokind: cryptoiokindty; +begin + result:= fpipes.fcryptoioinfo.kind; +end; + +procedure tsocketstdio.setcryptoiokind(const avalue: cryptoiokindty); +begin + fpipes.fcryptoioinfo.kind:= avalue; +end; + +{ tclientsocketpipes } +{ +procedure tclientsocketpipes.doafterconnect; +begin + if fcryptioinfo.handler <> nil then begin + ftx.fcrypt:= @fcryptioinfo; + frx.fcrypt:= @fcryptioinfo; + fcryptioinfo.handler.link(ftx.handle,frx.handle,fcryptioinfo); + cryptconnect(fcryptioinfo,frx.timeoutms); + end; + inherited; +end; +} +{ tcustomsocketclient } + +constructor tcustomsocketclient.create(aowner: tcomponent); +begin + if fpipes = nil then begin + fpipes:= tsocketpipes.create(self,cyk_client); + end; + inherited; +end; + +destructor tcustomsocketclient.destroy; +begin + fpipes.free; + inherited; +end; + +procedure tcustomsocketclient.setpipes(const avalue: tsocketpipes); +begin + fpipes.assign(avalue); +end; + +procedure tcustomsocketclient.internalconnect; +begin + socketerror(soc_open(fkind,true,fhandle)); + try + socketerror(soc_connect(fhandle,getsockaddr,fpipes.tx.timeoutms)); + except + sys_closefile(fhandle); + fhandle:= invalidfilehandle; + raise; + end; + try + fpipes.onafterconnect:= {$ifdef FPC}@{$endif}doafterconnect; + fpipes.setcryptoio(fcryptoio); + fpipes.handle:= fhandle; + except + internaldisconnect; + raise; + end; + factive:= true; +end; + +procedure tcustomsocketclient.internaldisconnect; +begin + fpipes.handle:= invalidfilehandle; + inherited +end; + +procedure tcustomsocketclient.closepipes(const sender: tcustomcommpipes); +begin + if (csdestroying in componentstate) and application.ismainthread then begin + disconnect; + end + else begin + asyncevent(closepipestag); + end; +end; + +procedure tcustomsocketclient.doasyncevent(var atag: integer); +begin + if atag = closepipestag then begin + disconnect; + end; +end; + +function tcustomsocketclient.trywritedata(const adata: string): syserrorty; +begin + result:= fpipes.tx.trywritebuffer(pointer(adata)^,length(adata)); +end; + +{ tserversocketpipes } +{ +procedure tserversocketpipes.doafterconnect; +begin + if fcryptioinfo.handler <> nil then begin + ftx.fcrypt:= @fcryptioinfo; + frx.fcrypt:= @fcryptioinfo; + fcryptioinfo.handler.link(ftx.handle,frx.handle,fcryptioinfo); + cryptaccept(fcryptioinfo,frx.timeoutms); + end; + inherited; +end; +} +{ tcustomsocketserver } + +constructor tcustomsocketserver.create(aowner: tcomponent); +begin + fmaxconnections:= defaultmaxconnections; + foverloadsleepus:= -1; + inherited; +end; + +destructor tcustomsocketserver.destroy; +var + int1: integer; +begin + disconnect; + inherited; + freeandnil(fthread); + for int1:= 0 to high(fpipes) do begin + fpipes[int1].free; + end; +end; + +procedure tcustomsocketserver.doafterchconnect(const sender: tcustomcommpipes); +begin + if canevent(tmethod(fonafterchconnect)) then begin + application.lock; + try + fonafterchconnect(self,sender); + finally + application.unlock; + end; + end; +end; + +function tcustomsocketserver.execthread(thread: tmsethread): integer; +var + addr: socketaddrty; + conn: integer; + bo1: boolean; + int1,int2: integer; + err: syserrorty; +// cryptioinfo: cryptioinfoty; +begin +{$ifdef mse_debugsockets} + debugout(self,'server execthread'); +{$endif} + result:= 0; + addr.kind:= fkind; + addr.size:= sizeof(addr.platformdata); + while not thread.terminated do begin + err:= soc_accept(fhandle,true,conn,addr,0); +{$ifdef mse_debugsockets} + debugout(self,'accept error:' + inttostr(ord(err))); +{$endif} + if not thread.terminated then begin + if err = sye_ok then begin + try + application.lock; + try + if canevent(tmethod(fonaccept)) then begin + bo1:= false; + fonaccept(self,conn,addr,bo1); + end + else begin + bo1:= true; + end; + if bo1 then begin + int2:= -1; + for int1:= 0 to high(fpipes) do begin + if fpipes[int1] = nil then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + setlength(fpipes,high(fpipes)+2); + int2:= high(fpipes); + end; + fpipes[int2]:= tsocketpipes.create(self,cyk_server); + inc(fconnectioncount); + with fpipes[int2] do begin + rx.timeoutms:= frxtimeoutms; + tx.timeoutms:= ftxtimeoutms; + optionsreader:= self.foptionsreader; + overloadsleepus:= self.foverloadsleepus; + oninputavailable:= self.foninputavailable; + onsocketbroken:= self.fonsocketbroken; + onafterconnect:= {$ifdef FPC}@{$endif}self.doafterchconnect; + if canevent(tmethod(fonbeforechconnect)) then begin + fonbeforechconnect(self,fpipes[int2]); + end; + setcryptoio(fcryptoio); + handle:= conn; + end; + end + else begin + // sys_shutdownsocket(conn,ssk_both); + soc_close(conn); + end; + finally + application.unlock; + end; + except + application.handleexception(self); + end; + end + else begin + if (err <> sye_timeout) or (fconnectioncount = 0) then begin + asyncevent(closeconnectiontag); + break; + end; + end; + end; + {$ifdef mse_debugsockets} + debugout(self,'server exitthread'); + {$endif} + end; +end; + +procedure tcustomsocketserver.internaldisconnect; +var + int1: integer; +begin +{$ifdef mse_debugsockets} + debugout(self,'internaldisconnect'); +{$endif} + if fthread <> nil then begin + fthread.terminate; + end; + for int1:= 0 to high(fpipes) do begin + if fpipes[int1] <> nil then begin + try + closepipes(fpipes[int1]); + except + end; + end; + end; + if fhandle <> invalidfilehandle then begin + soc_shutdown(fhandle,ssk_rx); + soc_close(fhandle); + end; + if fthread <> nil then begin + application.waitforthread(fthread); + end; + freeandnil(fthread); +// soc_close(fhandle); + inherited; +end; + +procedure tcustomsocketserver.doclosepipes; +var + int1: integer; +begin + for int1:= 0 to high(fpipes) do begin + if (fpipes[int1] <> nil) and + (fpipes[int1].tx.handle = invalidfilehandle) then begin + fpipes[int1].release; + if not (csdestroying in application.componentstate) and + not application.terminated then begin + fpipes[int1]:= nil; //destroying can be delayed + end; + end; + end; +end; + +procedure tcustomsocketserver.closepipes(const sender: tcustomcommpipes); +begin + if (sender.rx.handle <> invalidfilehandle) or + (cps_detached in tcustompipes1(sender).fstate) then begin + exclude(tcustompipes1(sender).fstate,cps_detached); + if canevent(tmethod(fonbeforechdisconnect)) then begin + try + fonbeforechdisconnect(self,sender); + except + application.handleexception(self); + end; + end; + sender.tx.handle:= invalidfilehandle; + dec(fconnectioncount); + if (csdestroying in componentstate) and application.ismainthread then begin + doclosepipes; + end + else begin + if not (sss_closepipespending in fstate) then begin + include(fstate,sss_closepipespending); + asyncevent(closepipestag); + end; + end; + if canevent(tmethod(fonafterchdisconnect)) then begin + fonafterchdisconnect(self,sender); + end; + end; +end; + +procedure tcustomsocketserver.doasyncevent(var atag: integer); +begin + case atag of + closepipestag: begin + exclude(fstate,sss_closepipespending); + doclosepipes; + end; + closeconnectiontag: begin + active:= false; + end; + end; +end; + +procedure tcustomsocketserver.runhandlerapp(const asocket: integer; + const acommandline: filenamety); +var + int1,int2: integer; +begin + syserror(sys_dup(asocket,int1)); + syserror(sys_dup(asocket,int2)); + execmse3(acommandline,@int1,@int2); +end; + +{ tsocketserver } + +procedure tsocketserver.internalconnect; +begin + if not (csdesigning in componentstate) then begin + syserror(soc_open(fkind,true,fhandle)); + try + syserror(soc_bind(fhandle,getsockaddr)); + except + sys_closefile(fhandle); + fhandle:= invalidfilehandle; + raise; + end; + try + syserror(soc_listen(fhandle,fmaxconnections)); + except + internaldisconnect; + raise; + end; + factive:= true; + fthread:= tmsethread.create({$ifdef FPC}@{$endif}execthread); + end; + factive:= true; +end; + +{ tsocketserverstdio } + +constructor tsocketserverstdio.create(aowner: tcomponent); +begin + inherited; + fkind:= sok_inet; +end; + +procedure tsocketserverstdio.internalconnect; +begin + if not (csdesigning in componentstate) then begin + syserror(sys_dup(sys_stdin,fhandle)); + factive:= true; + fthread:= tmsethread.create({$ifdef FPC}@{$endif}execthread); + end + else begin + factive:= true; + end; +end; + +{ tsocketreader } + +constructor tsocketreader.create(const aowner: tcustomcommpipes); +begin + inherited; + fstate:= fstate + [tss_nosigio,tss_unblocked]; +end; + +procedure tsocketreader.sethandle(value: integer); +begin + if value <> invalidfilehandle then begin + soc_setnonblock(value,true); + end; + inherited; +end; + +function tsocketreader.internalread(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean = false): boolean; +var + int1: integer; +begin + if nonblocked then begin + int1:= -1; + end + else begin + int1:= 0; + end; + soc_read(handle,@buf,acount,readcount,int1); + result:= readcount >= 0; + if not result then begin + readcount:= 0; + end; +end; + +procedure tsocketreader.closehandle(const ahandle: integer); +begin + soc_shutdown(ahandle,ssk_rx); + inherited; +end; + +procedure tsocketreader.settimeoutms(const avalue: integer); +begin + inherited; + if handle <> invalidfilehandle then begin + soc_setrxtimeout(handle,avalue); + end; +end; + +{ tsocketwriter } + +procedure tsocketwriter.closehandle(const ahandle: integer); +begin +// sys_shutdownsocket(ahandle,ssk_tx); + inherited; +end; + +procedure tsocketwriter.settimeoutms(const avalue: integer); +begin + inherited; + if handle <> invalidfilehandle then begin + soc_settxtimeout(handle,avalue); + end; +end; + +function tsocketwriter.internalwrite(const buffer; count: longint): longint; +begin + soc_write(handle,@buffer,count,result,0); +end; + +{ tcustomsocketpipes } + +procedure tcustomsocketpipes.createpipes; +begin + frx:= tsocketreader.create(self); + ftx:= tsocketwriter.create(self); +end; + +end. diff --git a/mseide-msegui/lib/common/image/mseformatbmpicoread.pas b/mseide-msegui/lib/common/image/mseformatbmpicoread.pas new file mode 100644 index 0000000..0ca8be0 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatbmpicoread.pas @@ -0,0 +1,505 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformatbmpicoread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + bmplabel = 'bmp'; + icolabel = 'ico'; +procedure registerformat; + +//param for ico: [index: integer] + +implementation +uses + classes,mclasses,msebitmap,msebits,msegraphutils,mseguiintf,msegraphicstream, + msestockobjects,msegraphics; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tbitmap1 = class(tbitmap); + +const + RT_BITMAP = PChar(2); + +type + DWORD = longword; + BITMAPFILEHEADERty = packed record + bfType: Word; + bfSize: DWORD; + bfReserved1: Word; + bfReserved2: Word; + bfOffBits: DWORD; + end; + BITMAPINFOHEADERty = packed record + biSize: DWORD; + biWidth: Longint; + biHeight: Longint; + biPlanes: Word; + biBitCount: Word; + biCompression: DWORD; + biSizeImage: DWORD; + biXPelsPerMeter: Longint; + biYPelsPerMeter: Longint; + biClrUsed: DWORD; + biClrImportant: DWORD; + end; + RGBQUADty = packed record + rgbBlue: Byte; + rgbGreen: Byte; + rgbRed: Byte; + rgbReserved: Byte; + end; + ICONHEADERty = packed record + idReserved: WORD; // Reserved (must be 0) + idType: WORD; // Resource Type (1 for icons) + idCount: WORD; // How many images? + //ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of 'em) + end; + ICONDIRENTRYty = packed record + bWidth: BYTE; // Width, in pixels, of the image + bHeight: BYTE; // Height, in pixels, of the image + bColorCount: BYTE; // Number of colors in image (0 if >=8bpp) + bReserved: BYTE; // Reserved ( must be 0) + wPlanes: WORD; // Color Planes + wBitCount: WORD; // Bits per pixel + dwBytesInRes: DWORD; // How many bytes in this resource? + dwImageOffset: DWORD; // Where in the file is this image? + end; + ICONIMAGEty = packed record + icHeader: BITMAPINFOHEADERty; // DIB header +// RGBQUAD icColors[1]; // Color table +// BYTE icXOR[1]; // DIB bits for XOR mask +// BYTE icAND[1]; // DIB bits for AND mask + end; + + +const + BM = $4d42; + BI_RGB = 0; + BI_RLE8 = 1; + BI_RLE4 = 2; + BI_BITFIELDS = 3; + +function readbmp(stream: tformatstream; bfoffbits: integer; dest: tbitmap; + icomode: boolean = false): boolean; + //bfoffbits <= 0 -> image at colormapend - bfoffbits + //true if biheight < 0 +var + infoheader: bitmapinfoheaderty; + palette: array of longword; + pixdata: array of byte; + rowbytelength,paddingcount: integer; + int1,int2: integer; + start,stop,step: integer; + po1: pbyte; + po2: plongword; + wo1: word; + +begin + stream.read(infoheader,sizeof(infoheader)); + with infoheader do begin + if icomode then begin + biheight:= biheight div 2; + end; + result:= biheight < 0; + if result then begin + biheight:= -biheight; + start:= 0; + stop:= biheight; + step:= 1; + end + else begin + start:= biheight-1; + stop:= -1; + step:= -1; + end; + if bicompression <> bi_rgb then begin + stream.formaterror; + end; + if bisize > sizeof(infoheader) then begin + stream.seek(infoheader.bisize-sizeof(infoheader)); + end; + if (bibitcount > 32) or (biclrused > bits[bibitcount]) then begin + stream.formaterror; + end; + if (biclrused = 0) and (bibitcount <= 8) then begin + biclrused:= bits[bibitcount]; + end; + if bfoffbits <= 0 then begin + bfoffbits:= stream.pos + integer(biclrused) * sizeof(longword) - bfoffbits; + end; + paddingcount:= ((biwidth * bibitcount+7) div 8); //bytecount + rowbytelength:= ((paddingcount+3) div 4) * 4; //4 byte boundaries + paddingcount:= rowbytelength - paddingcount; + setlength(pixdata,rowbytelength*biheight); + dest.clear; + if bibitcount = 1 then begin + dest.kind:= bmk_mono; + end + else begin + dest.kind:= bmk_rgb; + end; + dest.size:= makesize(biwidth,biheight); + int1:= start; + po1:= @pixdata[0]; + case bibitcount of + 16: begin + stream.pos:= bfoffbits; + stream.read(pixdata[0],length(pixdata)); + while int1 <> stop do begin + po2:= dest.scanline[int1]; + for int2:= 0 to biwidth - 1 do begin + wo1:= pword(po1)^; + pbyte(po2)^:= (wo1 and $7c00) shr 7; //red + inc(pbyte(po2)); + pbyte(po2)^:= (wo1 and $3e0) shr 2; //green + inc(pbyte(po2)); + pbyte(po2)^:= (wo1 and $1f) shl 3; //blue + inc(pbyte(po2)); + pbyte(po2)^:= 0; + inc(po1,2); + end; + inc(po1,paddingcount); + inc(int1,step); + end; + end; + 32: begin + stream.Pos:= bfoffbits; + while int1 <> stop do begin + stream.read(dest.scanline[int1]^,biwidth*4); + inc(int1,step); + end; + end; + 24: begin + stream.pos:= bfoffbits; + stream.read(pixdata[0],length(pixdata)); + while int1 <> stop do begin + po2:= dest.scanline[int1]; + for int2:= 0 to biwidth - 1 do begin + po2^:= plongword(po1)^ and $ffffff; + inc(po1,3); + inc(po2) + end; + inc(po1,paddingcount); + inc(int1,step); + end; + end; + 1: begin + stream.pos:= bfoffbits; + stream.read(pixdata[0],length(pixdata)); + while int1 <> stop do begin + po2:= dest.scanline[int1]; + for int2:= 0 to rowbytelength - 1 do begin + pbyte(po2)^:= not bitreverse[po1^]; + inc(pbyte(po2)); + inc(po1); + end; + inc(int1,step); + end; + end; + 4,8: begin + setlength(palette,bits[bibitcount]); + stream.read(palette[0],biclrused*sizeof(longword)); +// for int2:= 0 to biclrused - 1 do begin +// swaprgb1(palette[int2]); +// end; + stream.pos:= bfoffbits; + stream.read(pixdata[0],length(pixdata)); + if bibitcount = 4 then begin + if odd(biwidth) then begin + inc(paddingcount); + end; + while int1 <> stop do begin + po2:= dest.scanline[int1]; + for int2:= 0 to biwidth - 1 do begin + if not odd(int2) then begin + po2^:= palette[po1^ shr 4]; + end + else begin + po2^:= palette[po1^ and $0f]; + inc(po1); + end; + inc(po2); + end; + inc(po1,paddingcount); + inc(int1,step); + end; + end + else begin + while int1 <> stop do begin + po2:= dest.scanline[int1]; + for int2:= 0 to biwidth - 1 do begin + po2^:= palette[po1^]; + inc(po2); + inc(po1); + end; + inc(po1,paddingcount); + inc(int1,step); + end; + end; + end; + else begin + stream.formaterror; + end; + end; + end; +end; + +function readimagebmp(source: tstream; dest: tbitmap): boolean; +var + stream: tformatstream; + fileheader: bitmapfileheaderty; + +begin + result:= false; + stream:= tformatstream.create(source,'bmp'); + try + stream.read(fileheader,sizeof(fileheader)); + if (fileheader.bftype <> BM) then begin + exit; +// stream.formaterror; + end; + dest.clear; + if dest is tmaskedbitmap then begin + tmaskedbitmap(dest).masked:= false; + end; + dest.kind:= bmk_rgb; +// dest.monochrome:= false; + readbmp(stream,fileheader.bfoffbits,dest); + finally + stream.free; + end; + result:= true; +end; + +function readimageico1(source: tstream; dest1: tmaskedbitmap; + dest2: timagelist; index: integer): boolean; +var + stream: tformatstream; + iconheader: iconheaderty; + icondir: array of icondirentryty; + + procedure readicobmp(index: integer; dest: tmaskedbitmap); + var + bo1: boolean; + po1: pbyte; + po2: plongword; + int1,int3,int4: integer; + begin + dest.clear; +// dest.monochrome:= false; + dest.kind:= bmk_rgb; + with icondir[index] do begin + stream.Pos:= dwimageoffset; + bo1:= readbmp(stream,0,dest,true); + int3:= ((bwidth+31) div 32)*4; + int4:=int3*bheight; + getmem(po1,int4); + stream.read(po1^,int4); + po2:= pointer(po1); + for int1:= 0 to int4 div 4 - 1 do begin + po2^:= not po2^; + inc(po2); + end; + tbitmap1(dest.mask).handle:= gui_createbitmapfromdata(makesize(bwidth,bheight), + po1,true,true,not bo1); + freemem(po1); + end; + end; + +var + size1: sizety; + mono: boolean; + int1: integer; + buffer: tmaskedbitmap; + +begin + result:= false; + stream:= tformatstream.create(source,'ico'); + try + stream.Read(iconheader,sizeof(iconheader)); + with iconheader do begin + if (idtype <> 1) or (idcount <= index) then begin + exit; +// stream.formaterror; + end; + setlength(icondir,idcount); + stream.Read(icondir[0],length(icondir)*sizeof(icondirentryty)); + if dest1 <> nil then begin + readicobmp(index,dest1); + end + else begin + if dest2 <> nil then begin + size1:= nullsize; + mono:= true; + for int1:= 0 to idcount - 1 do begin + with icondir[int1] do begin + if bwidth > size1.cx then begin + size1.cx:= bwidth; + end; + if bheight > size1.cy then begin + size1.cy:= bheight; + end; + if bcolorcount <> 1 then begin + mono:= false; + end; + end; + end; + with dest2 do begin + size:= size1; + if mono then begin + kind:= bmk_mono; + end + else begin + kind:= bmk_rgb; + end; +// monochrome:= mono; + masked:= true; + count:= idcount; + end; + if mono then begin + buffer:= tmaskedbitmap.create(bmk_mono); + end + else begin + buffer:= tmaskedbitmap.create(bmk_rgb); + end; + try + for int1:= 0 to idcount - 1 do begin + readicobmp(int1,buffer); + dest2.setimage(int1,buffer); + end; + finally + buffer.free; + end; + end; + end; + end; + finally + stream.free; + end; + result:= true; +end; + +procedure readimageico(source: tstream; dest: tmaskedbitmap; index: integer = 0); + overload; +begin + readimageico1(source,dest,nil,index); +end; + +procedure readimageico(source: tstream; dest: timagelist); overload; +begin + readimageico1(source,nil,dest,0); +end; + +procedure readimage(source: tstream; dest: tmaskedbitmap); +var + posbefore: integer; +begin + posbefore:= source.Position; + try + readimagebmp(source,dest); + dest.masked:= false; + except + on egraphicformat do begin + source.Position:= posbefore; + readimageico(source,dest); + end; + else raise; + end; +end; + +function readgraphicbmp(const asource: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + result:= false; + if dest is tbitmap then begin + result:= readimagebmp(asource,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + if dest is timagelist then begin + result:= readimagebmp(asource,timagelist(dest).bitmap); + if result then begin + timagelist(dest).bitmap.change; + end; + end + else begin + result:= false; + end; + end; +end; + +function readgraphicico(const asource: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +var + int1: integer; +begin + result:= false; + if dest is tmaskedbitmap then begin + with tmaskedbitmap(dest) do begin + int1:= -1; + if (high(params) >= 0) then begin + with tvarrec(params[0]) do begin + if vtype = vtinteger then begin + int1:= vinteger; + end; + end; + end; + if int1 < 0 then begin + int1:= 0; + end; + result:= readimageico1(asource,tmaskedbitmap(dest),nil,int1); + if result then begin + change; + end; + end; + end + else begin + if dest is timagelist then begin + result:= readimageico1(asource,nil,timagelist(dest),0); + end + else begin + result:= false; + end; + end; +end; + +procedure registerformat; +begin + registergraphicformat(bmplabel,{$ifdef FPC}@{$endif}readgraphicbmp,nil, + stockobjects.captions[sc_MS_Bitmap],['*.bmp']); + registergraphicformat(icolabel,{$ifdef FPC}@{$endif}readgraphicico,nil, + stockobjects.captions[sc_MS_Icon],['*.ico']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatjpgread.pas b/mseide-msegui/lib/common/image/mseformatjpgread.pas new file mode 100644 index 0000000..b0fef34 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatjpgread.pas @@ -0,0 +1,70 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformatjpgread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + jpglabel = 'jpeg'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadjpeg,msegraphicstream, + msestockobjects,msestream; + +type + tmsefpreaderjpeg = class(tfpreaderjpeg) + protected + function InternalCheck(Str: TStream): boolean; override; + end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreaderjpeg,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +{ tmsefpreaderjpeg } + +function tmsefpreaderjpeg.InternalCheck(Str: TStream): boolean; +var + int1: integer; + ar1: array[0..1] of byte; +begin + result:= false; + int1:= str.position; + try + str.readbuffer(ar1,sizeof(ar1)); + if (ar1[0] = $ff) and (ar1[1] = $d8) then begin + result:= true; + end; + finally + str.position:= int1; + end; +end; + +procedure registerformat; +begin + registergraphicformat(jpglabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_JPEG_Image],['*.jpg','*.jpeg']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatjpgwrite.pas b/mseide-msegui/lib/common/image/mseformatjpgwrite.pas new file mode 100644 index 0000000..8d3b574 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatjpgwrite.pas @@ -0,0 +1,51 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformatjpgwrite; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + jpglabel = 'jpeg'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadjpeg,msegraphicstream, + msestockobjects,msestream,fpwritejpeg,sysutils,typinfo; + +procedure writegraphic(const dest: tstream; + const source: tobject; const format: string; + const params: array of const); + //[compressionquality: integer] 0..100, default 75 +var + ima: tmsefpmemoryimage; + writer: tfpwriterjpeg; +begin + try + ima:= tmsefpmemoryimage.create(0,0); + ima.assign(tpersistent(source)); + writer:= tfpwriterjpeg.create; + if (length(params) > 0) and (tvarrec(params[0]).vtype = vtinteger) then begin + writer.compressionquality:= tvarrec(params[0]).vinteger; + end; + ima.writetostream(dest,writer); + finally + ima.free; + end; +end; + +procedure registerformat; +begin + registergraphicformat(jpglabel,nil,{$ifdef FPC}@{$endif}writegraphic, + stockobjects.captions[sc_JPEG_Image],['*.jpg','*.jpeg']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatpngread.pas b/mseide-msegui/lib/common/image/mseformatpngread.pas new file mode 100644 index 0000000..71760c5 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatpngread.pas @@ -0,0 +1,70 @@ +{ MSEgui Copyright (c) 2006-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformatpngread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + pnglabel = 'png'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadpng,msegraphicstream, + msestockobjects; + +type + tmsefpreaderpng = class(tfpreaderpng) + protected +// function InternalCheck(Str: TStream): boolean; override; + end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreaderpng,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +{ tmsefpreaderpng } +{ +function tmsefpreaderpng.InternalCheck(Str: TStream): boolean; +var + int1: integer; + ar1: array[0..7] of char; +begin + result:= false; + int1:= str.position; + try + str.readbuffer(ar1,sizeof(ar1)); + if ar1 = #137#80#78#71#13#10#26#10 then begin + result:= true; + end; + finally + str.position:= int1; + end; +end; +} +procedure registerformat; +begin + registergraphicformat(pnglabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_PNG_Image],['*.png']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatpngwrite.pas b/mseide-msegui/lib/common/image/mseformatpngwrite.pas new file mode 100644 index 0000000..597631a --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatpngwrite.pas @@ -0,0 +1,87 @@ +{ MSEgui Copyright (c) 2006-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformatpngwrite; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + pnglabel = 'png'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpwritepng,msegraphicstream,msestockobjects, + fpimage; + +procedure writegraphic(const dest: tstream; + const source: tobject; const format: string; + const params: array of const); + //[grayscale (default false), + // indexed (default false), + // compressedtext (default true), + // wordsized (default false), + // usealpha (default source): boolean] +var + ima: tmsefpmemoryimage; + writer: tfpwriterpng; + col1: tfpcolor; +begin + try + ima:= tmsefpmemoryimage.create(0,0); + ima.assign(tpersistent(source)); + writer:= tfpwriterpng.create; + writer.grayscale:= false; + writer.indexed:= false; + writer.compressedtext:= true; + writer.wordsized:= false; + writer.usealpha:= ima.hasalpha; + if (length(params) > 0) and (tvarrec(params[0]).vtype = vtboolean) then begin + writer.grayscale:= tvarrec(params[0]).vboolean; + if (length(params) > 1) and (tvarrec(params[1]).vtype = vtboolean) then begin + writer.indexed:= tvarrec(params[1]).vboolean; + if (length(params) > 2) and (tvarrec(params[2]).vtype = vtboolean) then begin + writer.compressedtext:= tvarrec(params[2]).vboolean; + if (length(params) > 3) and (tvarrec(params[3]).vtype = vtboolean) then begin + writer.wordsized:= tvarrec(params[3]).vboolean; + if (length(params) > 4) and (tvarrec(params[4]).vtype = vtboolean) then begin + writer.usealpha:= tvarrec(params[4]).vboolean; + end; + end; + end; + end; + end; + with ima do begin + if hasalpha and monoalpha then begin + if (height <> 0) and (width <> 0) then begin + col1:= colors[0,0]; //force mode 4 + if col1.alpha = 0 then begin + col1.alpha:= 1; + end + else begin + col1.alpha:= $fffe; + end; + colors[0,0]:= col1; + end; + end; + end; + ima.writetostream(dest,writer); + finally + ima.free; + end; +end; + +procedure registerformat; +begin + registergraphicformat(pnglabel,nil,{$ifdef FPC}@{$endif}writegraphic, + stockobjects.captions[sc_PNG_Image],['*.png']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatpnmread.pas b/mseide-msegui/lib/common/image/mseformatpnmread.pas new file mode 100644 index 0000000..25c9ef1 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatpnmread.pas @@ -0,0 +1,70 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformatpnmread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + pnmlabel = 'pnm'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadpnm,msegraphicstream, + msestockobjects; + +type + tmsefpreaderpnm = class(tfpreaderpnm) + protected + function InternalCheck(Str: TStream): boolean; override; + end; + +{ tmsefpreaderpnm } + +function tmsefpreaderpnm.InternalCheck(Str: TStream): boolean; +var + int1: integer; + ar1: array[0..1] of char; +begin + result:= false; + int1:= str.position; + try + str.readbuffer(ar1,sizeof(ar1)); + if (ar1[0] = 'P') and (ar1[1] >= '1') and (ar1[1] <= '6') then begin + result:= true; + end; + finally + str.position:= int1; + end; +end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreaderpnm,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +procedure registerformat; +begin + registergraphicformat(pnmlabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_PNM_Image],['*.pnm','*.pgm','*.pbm']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformattgaread.pas b/mseide-msegui/lib/common/image/mseformattgaread.pas new file mode 100644 index 0000000..d093481 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformattgaread.pas @@ -0,0 +1,71 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformattgaread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + tgalabel = 'tga'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadtga,msegraphicstream, + msestockobjects; + +type + tmsefpreadertarga = class(tfpreadertarga) + protected + function InternalCheck(Str: TStream): boolean; override; + end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreadertarga,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +{ tmsefpreadertarga } + +function tmsefpreadertarga.InternalCheck(Str: TStream): boolean; +var + int1: integer; + ar1: array[0..2] of byte; +begin + result:= false; + int1:= str.position; + try + str.readbuffer(ar1,sizeof(ar1)); + if ((ar1[1] = $00) or (ar1[1] = $01)) and + (ar1[2] > 0) and (ar1[2] <= 11) then begin + result:= true; + end; + finally + str.position:= int1; + end; +end; + +procedure registerformat; +begin + registergraphicformat(tgalabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_TARGA_Image],['*.tga']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformattiffread.pas b/mseide-msegui/lib/common/image/mseformattiffread.pas new file mode 100644 index 0000000..9a3a61b --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformattiffread.pas @@ -0,0 +1,70 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformattiffread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + tifflabel = 'tif'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadtiff,msegraphicstream, + msestockobjects; + +type + tmsefpreadertiff = class(tfpreadertiff) + protected +// function InternalCheck(Str: TStream): boolean; override; + end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreadertiff,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +{ tmsefpreadertiff } +{ +function tmsefpreadertiff.InternalCheck(Str: TStream): boolean; +var + int1: integer; + ar1: array[0..7] of char; +begin + result:= false; + int1:= str.position; + try + str.readbuffer(ar1,sizeof(ar1)); + if ar1 = #137#80#78#71#13#10#26#10 then begin + result:= true; + end; + finally + str.position:= int1; + end; +end; +} +procedure registerformat; +begin + registergraphicformat(tifflabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_TIFF_Image],['*.tif','*.tiff']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformattiffwrite.pas b/mseide-msegui/lib/common/image/mseformattiffwrite.pas new file mode 100644 index 0000000..77fcccf --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformattiffwrite.pas @@ -0,0 +1,52 @@ +{ MSEgui Copyright (c) 2012-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformattiffwrite; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + tifflabel = 'tif'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpwritetiff,msegraphicstream,msestockobjects, + fpimage; + +// +// todo: -TFPWriterTiff writes a black image, maybe it needs initialization +// -add parameter +// +procedure writegraphic(const dest: tstream; + const source: tobject; const format: string; + const params: array of const); + //no params up to now +var + ima: tmsefpmemoryimage; + writer: tfpwritertiff; +begin + try + ima:= tmsefpmemoryimage.create(0,0); + ima.assign(tpersistent(source)); + writer:= tfpwritertiff.create; + ima.writetostream(dest,writer); + finally + ima.free; + end; +end; + +procedure registerformat; +begin + registergraphicformat(tifflabel,nil,{$ifdef FPC}@{$endif}writegraphic, + stockobjects.captions[sc_TIFF_Image],['*.tif','*.tiff']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatxpmread.pas b/mseide-msegui/lib/common/image/mseformatxpmread.pas new file mode 100644 index 0000000..a761505 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatxpmread.pas @@ -0,0 +1,59 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformatxpmread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + xpmlabel = 'xpm'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadxpm,msegraphicstream, + msestockobjects,fpimage; + +type + tmsefpreaderxpm = class(tfpreaderxpm) + protected + procedure InternalRead (Str:TStream; Img:TFPCustomImage); override; + end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreaderxpm,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +{ tmsefpreadertaxpm } + +procedure tmsefpreaderxpm.InternalRead(Str: TStream; Img: TFPCustomImage); +begin + img.usepalette:= true; + inherited; +end; + +procedure registerformat; +begin + registergraphicformat(xpmlabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_XPM_Image],['*.xpm']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/msegraphicsmagick.pas b/mseide-msegui/lib/common/image/msegraphicsmagick.pas new file mode 100644 index 0000000..2788d74 --- /dev/null +++ b/mseide-msegui/lib/common/image/msegraphicsmagick.pas @@ -0,0 +1,1124 @@ +{ MSEgui Copyright (c) 2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegraphicsmagick; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes{msestrings},msectypes,msedynload; + +const +{$ifdef mswindows} + graphicsmagiclib: array[0..0] of filenamety = ('CORE_RL_magick_.dll'); + graphicsmagicwandlib: array[0..0] of filenamety = ('CORE_RL_wand_.dll'); +{$else} + graphicsmagicwandlib: array[0..1] of filenamety = + ('libGraphicsMagickWand.so.2','libGraphicsMagickWand.so'); + graphicsmagiclib: array[0..1] of filenamety = + ('libGraphicsMagick.so.3','libGraphicsMagick.so'); +{$endif} + +{$packrecords c} + +type + quantumdepthty = (qd_8,qd_16,qd_32); + + MagickBool = cuint; +const + MagickTrue = 1; + MagickFalse = 0; +type + MagickPassFail = cuint; +const + MagickPass = 1; + MagickFail = 0; + +type + EndianType = ( + UndefinedEndian, + LSBEndian, //* "little" endian */ + MSBEndian, //* "big" endian */ + NativeEndian //* native endian */ + ); + StorageType = ( + CharPixel, //* Unsigned 8 bit 'unsigned char' */ + ShortPixel, //* Unsigned 16 bit 'unsigned short int' */ + IntegerPixel, //* Unsigned 32 bit 'unsigned int' */ + LongPixel, //* Unsigned 32 or 64 bit (CPU dependent) 'unsigned long' */ + FloatPixel, //* Floating point 32-bit 'float' */ + DoublePixel //* Floating point 64-bit 'double' */ + ); + + QuantumType = ( + UndefinedQuantum, //* Not specified */ + IndexQuantum, //* Colormap indexes */ + GrayQuantum, //* Grayscale values (minimum value is black) */ + IndexAlphaQuantum, //* Colormap indexes with transparency */ + GrayAlphaQuantum, //* Grayscale values with transparency */ + RedQuantum, //* Red values only (RGBA) */ + CyanQuantum, //* Cyan values only (CMYKA) */ + GreenQuantum, //* Green values only (RGBA) */ + YellowQuantum, //* Yellow values only (CMYKA) */ + BlueQuantum, //* Blue values only (RGBA) */ + MagentaQuantum, //* Magenta values only (CMYKA) */ + AlphaQuantum, //* Transparency values (RGBA or CMYKA) */ + BlackQuantum, //* Black values only (CMYKA) */ + RGBQuantum, //* Red, green, and blue values */ + RGBAQuantum, //* Red, green, blue, and transparency values */ + CMYKQuantum, //* Cyan, magenta, yellow, and black values */ + CMYKAQuantum, //* Cyan, magenta, yellow, black, and transparency values */ + CIEYQuantum, //* CIE Y values, based on CCIR-709 primaries */ + CIEXYZQuantum //* CIE XYZ values, based on CCIR-709 primaries */ + ); + + QuantumSampleType = ( + UndefinedQuantumSampleType, //* Not specified */ + UnsignedQuantumSampleType, //* Unsigned integral type (1-32 or 64 bits) */ + FloatQuantumSampleType //* Floating point type (16, 24, 32, or 64 bit) */ + ); + + CompressionType = ( + UndefinedCompression, + NoCompression, + BZipCompression, + FaxCompression, +// Group3Compression = FaxCompression, + Group4Compression, + JPEGCompression, + LosslessJPEGCompression, + LZWCompression, + RLECompression, + ZipCompression, + LZMACompression, //* Lempel-Ziv-Markov chain algorithm */ + JPEG2000Compression, //* ISO/IEC std 15444-1 */ + JBIG1Compression, //* ISO/IEC std 11544 / ITU-T rec T.82 */ + JBIG2Compression //* ISO/IEC std 14492 / ITU-T rec T.88 */ + ); + + InterlaceType = ( + UndefinedInterlace, + NoInterlace, + LineInterlace, + PlaneInterlace, + PartitionInterlace + ); + + ResolutionType = ( + UndefinedResolution, + PixelsPerInchResolution, + PixelsPerCentimeterResolution + ); + + ColorspaceType = ( + UndefinedColorspace, + RGBColorspace, //* Plain old RGB colorspace */ + GRAYColorspace, //* Plain old full-range grayscale */ + TransparentColorspace, //* RGB but preserve matte channel during quantize */ + OHTAColorspace, + XYZColorspace, //* CIE XYZ */ + YCCColorspace, //* Kodak PhotoCD PhotoYCC */ + YIQColorspace, + YPbPrColorspace, + YUVColorspace, + CMYKColorspace, //* Cyan, magenta, yellow, black, alpha */ + sRGBColorspace, //* Kodak PhotoCD sRGB */ + HSLColorspace, //* Hue, saturation, luminosity */ + HWBColorspace, //* Hue, whiteness, blackness */ + LABColorspace, //* LAB colorspace not supported yet other than via lcms */ + CineonLogRGBColorspace,//* RGB data with Cineon Log scaling, 2.048 density range */ + Rec601LumaColorspace, //* Luma (Y) according to ITU-R 601 */ + Rec601YCbCrColorspace, //* YCbCr according to ITU-R 601 */ + Rec709LumaColorspace, //* Luma (Y) according to ITU-R 709 */ + Rec709YCbCrColorspace //* YCbCr according to ITU-R 709 */ + ); + + ImageType = ( + UndefinedType, + BilevelType, + GrayscaleType, + GrayscaleMatteType, + PaletteType, + PaletteMatteType, + TrueColorType, + TrueColorMatteType, + ColorSeparationType, + ColorSeparationMatteType, + OptimizeType + ); + + PreviewType = ( + UndefinedPreview = 0, + RotatePreview, + ShearPreview, + RollPreview, + HuePreview, + SaturationPreview, + BrightnessPreview, + GammaPreview, + SpiffPreview, + DullPreview, + GrayscalePreview, + QuantizePreview, + DespecklePreview, + ReduceNoisePreview, + AddNoisePreview, + SharpenPreview, + BlurPreview, + ThresholdPreview, + EdgeDetectPreview, + SpreadPreview, + SolarizePreview, + ShadePreview, + RaisePreview, + SegmentPreview, + SwirlPreview, + ImplodePreview, + WavePreview, + OilPaintPreview, + CharcoalDrawingPreview, + JPEGPreview + ); + + ClassType = ( + UndefinedClass, + DirectClass, + PseudoClass + ); + + OrientationType = ( //* Line direction / Frame Direction */ + //* -------------- / --------------- */ + UndefinedOrientation, //* Unknown / Unknown */ + TopLeftOrientation, //* Left to right / Top to bottom */ + TopRightOrientation, //* Right to left / Top to bottom */ + BottomRightOrientation, //* Right to left / Bottom to top */ + BottomLeftOrientation, //* Left to right / Bottom to top */ + LeftTopOrientation, //* Top to bottom / Left to right */ + RightTopOrientation, //* Top to bottom / Right to left */ + RightBottomOrientation, //* Bottom to top / Right to left */ + LeftBottomOrientation //* Bottom to top / Left to right */ + ); + + RenderingIntent = ( + UndefinedIntent, + SaturationIntent, + PerceptualIntent, + AbsoluteIntent, + RelativeIntent + ); + + FilterTypes = ( + UndefinedFilter, + PointFilter, + BoxFilter, + TriangleFilter, + HermiteFilter, + HanningFilter, + HammingFilter, + BlackmanFilter, + GaussianFilter, + QuadraticFilter, + CubicFilter, + CatromFilter, + MitchellFilter, + LanczosFilter, + BesselFilter, + SincFilter + ); + + GravityType = ( + ForgetGravity, + NorthWestGravity, + NorthGravity, + NorthEastGravity, + WestGravity, + CenterGravity, + EastGravity, + SouthWestGravity, + SouthGravity, + SouthEastGravity, + StaticGravity + ); + + CompositeOperator = ( + UndefinedCompositeOp = 0, + OverCompositeOp, + InCompositeOp, + OutCompositeOp, + AtopCompositeOp, + XorCompositeOp, + PlusCompositeOp, + MinusCompositeOp, + AddCompositeOp, + SubtractCompositeOp, + DifferenceCompositeOp, + MultiplyCompositeOp, + BumpmapCompositeOp, + CopyCompositeOp, + CopyRedCompositeOp, + CopyGreenCompositeOp, + CopyBlueCompositeOp, + CopyOpacityCompositeOp, + ClearCompositeOp, + DissolveCompositeOp, + DisplaceCompositeOp, + ModulateCompositeOp, + ThresholdCompositeOp, + NoCompositeOp, + DarkenCompositeOp, + LightenCompositeOp, + HueCompositeOp, + SaturateCompositeOp, + ColorizeCompositeOp, + LuminizeCompositeOp, + ScreenCompositeOp, //* Not yet implemented */ + OverlayCompositeOp, //* Not yet implemented */ + CopyCyanCompositeOp, + CopyMagentaCompositeOp, + CopyYellowCompositeOp, + CopyBlackCompositeOp, + DivideCompositeOp + ); + + DisposeType = ( + UndefinedDispose, + NoneDispose, + BackgroundDispose, + PreviousDispose + ); + + TimerState = ( + UndefinedTimerState, + StoppedTimerState, + RunningTimerState + ); + + Quantum8 = cuchar; + Quantum16 = cushort; + Quantum32 = cuint; + + PixelPacket8 = record + {$ifdef WORDS_BIGENDIAN} + //* RGBA */ + {$define MAGICK_PIXELS_RGBA} + red: Quantum8; + green: Quantum8; + blue: Quantum8; + opacity: Quantum8; + {$else} + //* BGRA (as used by Microsoft Windows DIB) */ + {$define MAGICK_PIXELS_BGRA} + blue: Quantum8; + green: Quantum8; + red: Quantum8; + opacity: Quantum8; + {$endif} + end; + pPixelPacket8 = ^PixelPacket8; + + PixelPacket16 = record + {$ifdef WORDS_BIGENDIAN} + //* RGBA */ + {$define MAGICK_PIXELS_RGBA} + red: Quantum16; + green: Quantum16; + blue: Quantum16; + opacity: Quantum16; + {$else} + //* BGRA (as used by Microsoft Windows DIB) */ + {$define MAGICK_PIXELS_BGRA} + blue: Quantum16; + green: Quantum16; + red: Quantum16; + opacity: Quantum16; + {$endif} + end; + pPixelPacket16 = ^PixelPacket16; + + PixelPacket32 = record + {$ifdef WORDS_BIGENDIAN} + //* RGBA */ + {$define MAGICK_PIXELS_RGBA} + red: Quantum32; + green: Quantum32; + blue: Quantum32; + opacity: Quantum32; + {$else} + //* BGRA (as used by Microsoft Windows DIB) */ + {$define MAGICK_PIXELS_BGRA} + blue: Quantum32; + green: Quantum32; + red: Quantum32; + opacity: Quantum32; + {$endif} + end; + pPixelPacket32 = ^PixelPacket32; + + _FILE = record + end; //todo: link tstream and C-stream + pFILE = ^_FILE; + _CacheInfoPtr_ = pointer; + _BlobInfoPtr_ = pointer; + + MaxTextExtent = 0..2052; //??? + + const //ExceptionBaseType + UndefinedExceptionBase = 0; + ExceptionBase = 1; + ResourceBase = 2; + ResourceLimitBase = 2; + TypeBase = 5; + AnnotateBase = 5; + OptionBase = 10; + DelegateBase = 15; + MissingDelegateBase = 20; + CorruptImageBase = 25; + FileOpenBase = 30; + BlobBase = 35; + StreamBase = 40; + CacheBase = 45; + CoderBase = 50; + ModuleBase = 55; + DrawBase = 60; + RenderBase = 60; + ImageBase = 65; + WandBase = 67; + TemporaryFileBase = 70; + TransformBase = 75; + XServerBase = 80; + X11Base = 81; + UserBase = 82; + MonitorBase = 85; + LocaleBase = 86; + DeprecateBase = 87; + RegistryBase = 90; + ConfigureBase = 95; + //ExceptionType + UndefinedException = 0; + EventException = 100; + ExceptionEvent = EventException + ExceptionBase; + ResourceEvent = EventException + ResourceBase; + ResourceLimitEvent = EventException + ResourceLimitBase; + TypeEvent = EventException + TypeBase; + AnnotateEvent = EventException + AnnotateBase; + OptionEvent = EventException + OptionBase; + DelegateEvent = EventException + DelegateBase; + MissingDelegateEvent = EventException + MissingDelegateBase; + CorruptImageEvent = EventException + CorruptImageBase; + FileOpenEvent = EventException + FileOpenBase; + BlobEvent = EventException + BlobBase; + StreamEvent = EventException + StreamBase; + CacheEvent = EventException + CacheBase; + CoderEvent = EventException + CoderBase; + ModuleEvent = EventException + ModuleBase; + DrawEvent = EventException + DrawBase; + RenderEvent = EventException + RenderBase; + ImageEvent = EventException + ImageBase; + WandEvent = EventException + WandBase; + TemporaryFileEvent = EventException + TemporaryFileBase; + TransformEvent = EventException + TransformBase; + XServerEvent = EventException + XServerBase; + X11Event = EventException + X11Base; + UserEvent = EventException + UserBase; + MonitorEvent = EventException + MonitorBase; + LocaleEvent = EventException + LocaleBase; + DeprecateEvent = EventException + DeprecateBase; + RegistryEvent = EventException + RegistryBase; + ConfigureEvent = EventException + ConfigureBase; + + WarningException = 300; + ExceptionWarning = WarningException + ExceptionBase; + ResourceWarning = WarningException + ResourceBase; + ResourceLimitWarning = WarningException + ResourceLimitBase; + TypeWarning = WarningException + TypeBase; + AnnotateWarning = WarningException + AnnotateBase; + OptionWarning = WarningException + OptionBase; + DelegateWarning = WarningException + DelegateBase; + MissingDelegateWarning = WarningException + MissingDelegateBase; + CorruptImageWarning = WarningException + CorruptImageBase; + FileOpenWarning = WarningException + FileOpenBase; + BlobWarning = WarningException + BlobBase; + StreamWarning = WarningException + StreamBase; + CacheWarning = WarningException + CacheBase; + CoderWarning = WarningException + CoderBase; + ModuleWarning = WarningException + ModuleBase; + DrawWarning = WarningException + DrawBase; + RenderWarning = WarningException + RenderBase; + ImageWarning = WarningException + ImageBase; + WandWarning = WarningException + WandBase; + TemporaryFileWarning = WarningException + TemporaryFileBase; + TransformWarning = WarningException + TransformBase; + XServerWarning = WarningException + XServerBase; + X11Warning = WarningException + X11Base; + UserWarning = WarningException + UserBase; + MonitorWarning = WarningException + MonitorBase; + LocaleWarning = WarningException + LocaleBase; + DeprecateWarning = WarningException + DeprecateBase; + RegistryWarning = WarningException + RegistryBase; + ConfigureWarning = WarningException + ConfigureBase; + + ErrorException = 400; + ExceptionError = ErrorException + ExceptionBase; + ResourceError = ErrorException + ResourceBase; + ResourceLimitError = ErrorException + ResourceLimitBase; + TypeError = ErrorException + TypeBase; + AnnotateError = ErrorException + AnnotateBase; + OptionError = ErrorException + OptionBase; + DelegateError = ErrorException + DelegateBase; + MissingDelegateError = ErrorException + MissingDelegateBase; + CorruptImageError = ErrorException + CorruptImageBase; + FileOpenError = ErrorException + FileOpenBase; + BlobError = ErrorException + BlobBase; + StreamError = ErrorException + StreamBase; + CacheError = ErrorException + CacheBase; + CoderError = ErrorException + CoderBase; + ModuleError = ErrorException + ModuleBase; + DrawError = ErrorException + DrawBase; + RenderError = ErrorException + RenderBase; + ImageError = ErrorException + ImageBase; + WandError = ErrorException + WandBase; + TemporaryFileError = ErrorException + TemporaryFileBase; + TransformError = ErrorException + TransformBase; + XServerError = ErrorException + XServerBase; + X11Error = ErrorException + X11Base; + UserError = ErrorException + UserBase; + MonitorError = ErrorException + MonitorBase; + LocaleError = ErrorException + LocaleBase; + DeprecateError = ErrorException + DeprecateBase; + RegistryError = ErrorException + RegistryBase; + ConfigureError = ErrorException + ConfigureBase; + + FatalErrorException = 700; + ExceptionFatalError = FatalErrorException + ExceptionBase; + ResourceFatalError = FatalErrorException + ResourceBase; + ResourceLimitFatalError = FatalErrorException + ResourceLimitBase; + TypeFatalError = FatalErrorException + TypeBase; + AnnotateFatalError = FatalErrorException + AnnotateBase; + OptionFatalError = FatalErrorException + OptionBase; + DelegateFatalError = FatalErrorException + DelegateBase; + MissingDelegateFatalError = FatalErrorException + MissingDelegateBase; + CorruptImageFatalError = FatalErrorException + CorruptImageBase; + FileOpenFatalError = FatalErrorException + FileOpenBase; + BlobFatalError = FatalErrorException + BlobBase; + StreamFatalError = FatalErrorException + StreamBase; + CacheFatalError = FatalErrorException + CacheBase; + CoderFatalError = FatalErrorException + CoderBase; + ModuleFatalError = FatalErrorException + ModuleBase; + DrawFatalError = FatalErrorException + DrawBase; + RenderFatalError = FatalErrorException + RenderBase; + ImageFatalError = FatalErrorException + ImageBase; + WandFatalError = FatalErrorException + WandBase; + TemporaryFileFatalError = FatalErrorException + TemporaryFileBase; + TransformFatalError = FatalErrorException + TransformBase; + XServerFatalError = FatalErrorException + XServerBase; + X11FatalError = FatalErrorException + X11Base; + UserFatalError = FatalErrorException + UserBase; + MonitorFatalError = FatalErrorException + MonitorBase; + LocaleFatalError = FatalErrorException + LocaleBase; + DeprecateFatalError = FatalErrorException + DeprecateBase; + RegistryFatalError = FatalErrorException + RegistryBase; + ConfigureFatalError = FatalErrorException + ConfigureBase; +type + ExceptionInfo = record + severity: cint; //* Exception severity, reason, and description */ + reason: pcchar; + description: pcchar; + error_number: cint; //* Value of errno (or equivalent) when exception was thrown. */ + module: pcchar; //*Reporting source module, function (if available), and source + // module line. */ + _function: pchar; + line: culong; + signature: culong; //* Structure sanity check + end; + pExceptionInfo = ^ExceptionInfo; + + PrimaryInfo = record + x: cdouble; + y: cdouble; + z: cdouble; + end; + + ChromaticityInfo = record + red_primary: PrimaryInfo; + green_primary: PrimaryInfo; + blue_primary: PrimaryInfo; + white_point: PrimaryInfo; + end; + + RectangleInfo = record + width: culong; + height: culong; + x: clong; + y: clong; + end; + + ErrorInfo = record + mean_error_per_pixel: cdouble; //* Average error per pixel (absolute range) */ + normalized_mean_error: cdouble; //* Average error per pixel (normalized to 1.0) */ + normalized_maximum_error: cdouble; //* Maximum error encountered (normalized to 1.0) */ + end; + + Timer = record + start: cdouble; + stop: cdouble; + total: cdouble; + end; + + TimerInfo = record + user: Timer; + elapsed: Timer; + state: TimerState; + signature: culong; + end; + + _ThreadViewSetPtr_ = pointer; + _ImageAttributePtr_ = pointer; + _Ascii85InfoPtr_ = pointer; + _SemaphoreInfoPtr_ = pointer; + + Imagea = record + storage_class: ClassType; //* DirectClass (TrueColor) or PseudoClass (colormapped) */ + colorspace: ColorspaceType; //* Current image colorspace/model */ + compression: CompressionType; //* Compression algorithm to use when encoding image */ + dither: MagickBool; //* True if image is to be dithered */ + matte: MagickBool; //* True if image has an opacity (alpha) channel */ + columns: culong; //* Number of image columns */ + rows: culong; //* Number of image rows */ + colors: cuint; //* Current number of colors in PseudoClass colormap */ + depth: cuint; //* Bits of precision to preserve in color quantum */ + end; + Imageb8 = record + colormap: pPixelPacket8; //* Pseudoclass colormap array */ + background_color: PixelPacket8; //* Background color */ + border_color: PixelPacket8; //* Border color */ + matte_color: PixelPacket8; //* Matte (transparent) color */ + end; + Imageb16 = record + colormap: pPixelPacket16; //* Pseudoclass colormap array */ + background_color: PixelPacket16; //* Background color */ + border_color: PixelPacket16; //* Border color */ + matte_color: PixelPacket16; //* Matte (transparent) color */ + end; + Imageb32 = record + colormap: pPixelPacket32; //* Pseudoclass colormap array */ + background_color: PixelPacket32; //* Background color */ + border_color: PixelPacket32; //* Border color */ + matte_color: PixelPacket32; //* Matte (transparent) color */ + end; + Imagec = record + gamma: cdouble; //* Image gamma (e.g. 0.45) */ + chromaticity: ChromaticityInfo; //* Red, green, blue, and white chromaticity values */ + orientation: OrientationType; //* Image orientation */ + rendering_intent: RenderingIntent; //* Rendering intent */ + units: ResolutionType; //* Units of image resolution (density) */ + montage: pcchar; //* Tile size and offset within an image montage */ + directory: pcchar; //* Tile names from within an image montage */ + geometry: pcchar; //* Composite/Crop options */ + offset: clong; //* Offset to start of image data */ + x_resolution: cdouble; //* Horizontal resolution (also see units) */ + y_resolution: cdouble; //* Vertical resolution (also see units) */ + page: RectangleInfo; //* Offset to apply when placing image */ + tile_info: RectangleInfo; //* Subregion tile dimensions and offset */ + blur: cdouble; //* Amount of blur to apply when zooming image */ + fuzz: cdouble; //* Colors within this distance match target color */ + filter: FilterTypes; //* Filter to use when zooming image */ + interlace: InterlaceType; //* Interlace pattern to use when writing image */ + endian: EndianType; //* Byte order to use when writing image */ + gravity: GravityType; //* Image placement gravity */ + compose: CompositeOperator; //* Image placement composition (default OverCompositeOp) */ + _dispose: DisposeType; //* GIF disposal option */ + scene: culong; //* Animation frame scene number */ + delay: culong; //* Animation frame scene delay */ + iterations: culong; //* Animation iterations */ + total_colors: culong; //* Number of unique colors. See GetNumberColors() */ + start_loop: clong; //* Animation frame number to start looping at */ + error: ErrorInfo; //* Computed image comparison or quantization error */ + timer: TimerInfo; //* Operation micro-timer */ + client_data: pointer; //* User specified opaque data pointer */ +//* +// Output file name. +// A colon delimited format identifier may be prepended to the file +// name in order to force a particular output format. Otherwise the +// file extension is used. If no format prefix or file extension is +// present, then the output format is determined by the 'magick' +// field. */ + filename: array[MaxTextExtent] of char; +//* Original file name (name of input image file) */ + magick_filename: array[MaxTextExtent] of cchar; +//* +// File format of the input file, and the default output format. +// The precedence when selecting the output format is: +// 1) magick prefix to file name (e.g. "jpeg:foo). +// 2) file name extension. (e.g. "foo.jpg") +// 3) content of this magick field. */ + magick: array[MaxTextExtent] of cchar; +//* Original image width (before transformations) */ + magick_columns: culong; +//* Original image height (before transformations) */ + magick_rows: culong; + exception: ExceptionInfo; //* Any error associated with this image frame */ + previous: pointer{pImage}; //* Pointer to previous frame */ + next: pointer{pImage}; //* Pointer to next frame */ +//* To be added here for a later release: +// quality? +// subsampling +// video black/white setup levels (ReferenceBlack/ReferenceWhite) +// sample format (integer/float) */ + +//* Only private members appear past this point */ + profiles: pointer; //* Private, Embedded profiles */ + is_monochrome: cuint; //* Private, True if image is known to be monochrome */ + is_grayscale: cuint; //* Private, True if image is known to be grayscale */ + taint: cuint; //* Private, True if image has not been modifed */ + clip_mask: pointer{pImage}; //* Private, Clipping mask to apply when updating pixels */ + ping: MagickBool; //* Private, if true, pixels are undefined */ + cache: _CacheInfoPtr_; //* Private, image pixel cache */ + default_views: _ThreadViewSetPtr_; //* Private, default cache views */ + attributes: _ImageAttributePtr_; //* Private, Image attribute list */ + ascii85: _Ascii85InfoPtr_; //* Private, supports huffman encoding */ + blob: _BlobInfoPtr_; //* Private, file I/O object */ + reference_count: clong; //* Private, Image reference count */ + semaphore: _SemaphoreInfoPtr_; //* Private, Per image lock (for reference count) */ + logging: cuint; //* Private, True if logging is enabled */ + list: pointer{pImage}; //* Private, used only by display */ + signature: culong; //* Private, Unique code to validate structure */ + end; + + Image8 = record + a: Imagea; + b: Imageb8; + c: Imagec; + end; + pImage8 = ^Image8; + Image16 = record + a: Imagea; + b: Imageb16; + c: Imagec; + end; + pImage16 = ^Image16; + Image32 = record + a: Imagea; + b: Imageb32; + c: Imagec; + end; + pImage32 = ^Image32; + + + ImageInfoa = record + compression: CompressionType; //* Image compression to use while decoding */ + temporary: MagickBool; //* Remove file "filename" once it has been read. */ + adjoin: MagickBool; //* If True, join multiple frames into one file */ + antialias: MagickBool; //* If True, antialias while rendering */ + subimage: culong; //* Starting image scene ID to select */ + subrange: culong; //* Span of image scene IDs (from starting scene) to select */ + depth: culong; //* Number of quantum bits to preserve while encoding */ + size: pchar; //* Desired/known dimensions to use when decoding image */ + tile: pchar; //* Deprecated, name of image to tile on background */ + page: pchar; //* Output page size & offset */ + interlace: InterlaceType; //* Interlace scheme to use when decoding image */ + endian: EndianType; //* Select MSB/LSB endian output for TIFF format */ + units: ResolutionType; //* Units to apply when evaluating the density option */ + quality: culong; //* Compression quality factor (format specific) */ + sampling_factor: pchar; //* JPEG, MPEG, and YUV chroma downsample factor */ + server_name: pchar; //* X11 server display specification */ + font: pchar; //* Font name to use for text annotations */ + texture: pchar; //* Name of texture image to use for background fills */ + density: pchar; //* Image resolution (also see units) */ + pointsize: cdouble; //* Font pointsize */ + fuzz: cdouble; //* Colors within this distance are a match */ + end; + ImageInfob8 = record + pen: PixelPacket8; //* Stroke or fill color while drawing */ + background_color: PixelPacket8; //* Background color */ + border_color: PixelPacket8; //* Border color (color surrounding frame) */ + matte_color: PixelPacket8; //* Matte color (frame color) */ + end; + ImageInfob16 = record + pen: PixelPacket16; //* Stroke or fill color while drawing */ + background_color: PixelPacket16; //* Background color */ + border_color: PixelPacket16; //* Border color (color surrounding frame) */ + matte_color: PixelPacket16; //* Matte color (frame color) */ + end; + ImageInfob32 = record + pen: PixelPacket8; //* Stroke or fill color while drawing */ + background_color: PixelPacket8; //* Background color */ + border_color: PixelPacket8; //* Border color (color surrounding frame) */ + matte_color: PixelPacket8; //* Matte color (frame color) */ + end; + ImageInfoc = record + dither: MagickBool; //* If true, dither image while writing */ + monochrome: MagickBool; //* If true, use monochrome format */ + progress: MagickBool; //* If true, show progress indication */ + colorspace: ColorspaceType; //* Colorspace representations of image pixels */ + _type: ImageType; //* Desired image type (used while reading or writing) */ + group: clong; //* X11 window group ID */ + verbose: cuint; //* If non-zero, display high-level processing */ + view: pchar; //* FlashPIX view specification */ + authenticate: pchar; //* Password used to decrypt file */ + client_data: pointer; //* User-specified data to pass to coder */ + _file: pFILE; //* If not null, stdio FILE * to read image from + // (fopen mode "rb") or write image to (fopen + // mode "rb+"). */ + magick: array[MaxTextExtent] of cchar; //* File format to read. Overrides file extension */ + filename: array[MaxTextExtent] of cchar; //* File name to read */ + + // Only private members appear past this point + + cache: _CacheInfoPtr_;//* Private. Used to pass image via open cache */ + definitions: pointer; //* Private. Map of coder specific options passed by user. + //Use AddDefinitions, RemoveDefinitions, & AccessDefinition + //to access and manipulate this data. */ + attributes: pointer{pImage}; //* Private. Image attribute list */ + ping: MagickBool; //* Private, if true, read file header only */ + preview_type: PreviewType; //* Private, used by PreviewImage */ + affirm: MagickBool; //* Private, when true do not intuit image format */ + blob: _BlobInfoPtr_; //* Private, used to pass in open blob */ + length: size_t; //* Private, used to pass in open blob length */ + unique: array[MaxTextExtent] of cchar; //* Private, passes temporary filename to TranslateText */ + zero: array[MaxTextExtent] of cchar; //* Private, passes temporary filename to TranslateText */ + signature: culong; //* Private, used to validate structure */ + end; + ImageInfo8 = record + a: ImageInfoa; + b: ImageInfob8; + c:ImageInfoc + end; + pImageInfo8 = ^ImageInfo8; + + ImageInfo16 = record + a: ImageInfoa; + b: ImageInfob16; + c:ImageInfoc + end; + pImageInfo16 = ^ImageInfo16; + + ImageInfo32 = record + a: ImageInfoa; + b: ImageInfob32; + c:ImageInfoc + end; + pImageInfo32 = ^ImageInfo32; + +// pExportPixelAreaOptions = ^ExportPixelAreaOptions; + + ExportPixelAreaOptions = record + sample_type: QuantumSampleType; //* Quantum sample type */ + double_minvalue: cdouble; + //* Minimum value (default 0.0) for linear floating point samples */ + double_maxvalue: cdouble; + //* Maximum value (default 1.0) for linear floating point samples */ + grayscale_miniswhite: MagickBool; + //* Grayscale minimum value is white rather than black */ + pad_bytes: culong; + //* Number of pad bytes to output after pixel data */ + pad_value: cuchar; + //* Value to use when padding end of pixel data */ + endian: EndianType; + //* Endian orientation for 16/32/64 bit types (default MSBEndian) */ + signature: culong; + end; + pExportPixelAreaOptions = ^ExportPixelAreaOptions; + + ImportPixelAreaOptions = record + sample_type: QuantumSampleType; //* Quantum sample type */ + double_minvalue: cdouble; + //* Minimum value (default 0.0) for linear floating point samples */ + double_maxvalue: cdouble; + //* Maximum value (default 1.0) for linear floating point samples */ + grayscale_miniswhite: MagickBool; + //* Grayscale minimum value is white rather than black */ + endian: EndianType; //* Endian orientation for 16/32/64 bit types + //(default MSBEndian) */ + signature: culong; + end; + pImportPixelAreaOptions = ^ImportPixelAreaOptions; + + ExportPixelAreaInfo = record + bytes_exported: size_t; //* Number of bytes which were exported */ + end; + pExportPixelAreaInfo = ^ExportPixelAreaInfo; + + ImportPixelAreaInfo = record + bytes_imported: size_t; //* Number of bytes which were imported */ + end; + pImportPixelAreaInfo = ^ImportPixelAreaInfo; + + MagickWand = record + end; + pMagickWand = ^MagickWand; + +var + InitializeMagick: procedure(path: pcchar); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + DestroyMagick: procedure(); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickMalloc: function(size: size_t): pointer; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickFree: procedure(memory: pointer); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + MagickGetVersion: function(version: pculong): pcchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickGetQuantumDepth: function(depth: pculong): pchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickQueryFormats: function(pattern: pcchar; + number_formats: pculong): ppcchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GetExceptionInfo: procedure(exception: pExceptionInfo); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + DestroyExceptionInfo: procedure(exception: pExceptionInfo); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + CloneImageInfo: function(image_info: pointer{pImageInfo}): pointer{pImageInfo}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + DestroyImageInfo: procedure(image_info: pointer{pImageInfo}); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + AllocateImage: function(image_info: pointer{pImageInfo}): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PingImage: function(image_info: pointer{pImageInfo}; + exception: pExceptionInfo):pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ReadImage: function(image_info: pointer{pImageInfo}; + exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PingBlob: function(imageinfo: pointer{pImageInfo}; blob: pointer; + length: size_t; exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BlobToImage: function(image_info: pointer{pImageInfo}; blob: pointer; + length: size_t; exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + WriteImage: function(image_info: pointer{pImageInfo}; + image: pointer{pImage}): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ImageToBlob: function(image_info: pointer{pImageInfo}; + image: pointer{pImage}; length: psize_t; + exception: pExceptionInfo): pointer; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + DestroyImage: procedure(image: pointer{pImage}); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + DispatchImage: function(image: pointer{pImage8}; + x_offset: clong; y_offset: clong; + columns: culong; rows: culong; map: pcchar; _type: StorageType; + pixels: pointer; exception: pExceptionInfo): MagickPassFail; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ConstituteImage: function(width: cuint; height: cuint; + map: pcchar; _type: StorageType; pixels: pointer; + exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + ExportImagePixelArea: function(image: pointer{pImage}; + quantum_type: QuantumType; + quantum_size: cuint; destination: pcuchar; + options: pExportPixelAreaOptions; + export_info: pExportPixelAreaInfo): MagickPassFail; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ImportImagePixelArea: function(image: pointer{pImage}; + quantum_type: QuantumType; + quantum_size: cuint; source: pcuchar; + options: pImportPixelAreaOptions; + import_info: pImportPixelAreaInfo): MagickPassFail; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ImportPixelAreaOptionsInit: procedure(options: pImportPixelAreaOptions); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ExportPixelAreaOptionsInit: procedure(options: pExportPixelAreaOptions); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GetImagePixels: function(image: pointer{pImage}; x: clong; y: clong; + columns: culong; rows: culong): pointer{pPixelPacket}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + SetImagePixels: function(image: pointer{pImage}; x: clong; const y: clong; + columns: culong; rows: culong): pointer{pPixelPacket}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + SyncImagePixels: function(image: pointer{pImage}): MagickPassFail; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + AllocateImageColormap: function(image: pointer{pImage}; colors: culong): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + SampleImage: function(image: pointer{pImage}; columns: culong; + rows: culong; exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ScaleImage: function(image: pointer{pImage}; columns: culong; + rows: culong; exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ResizeImage: function(image: pointer{pImage}; columns: culong; rows: culong; + filter: FilterTypes; blur: cdouble; + exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + RotateImage: function(image: pointer{pImage}; degrees: cdouble; + exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + NewMagickWand: function(): pMagickWand; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + DestroyMagickWand: procedure(wand: pMagickWand); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + MagickReadImage: function(wand: pMagickWand; filename: pcchar): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickReadImageBlob: function(wand: pMagickWand; blob: pcuchar; + length: size_t): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickReadImageFile: function(wand: pMagickWand; _file: pFILE): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + MagickWriteImage: function(wand: pMagickWand; filename: pcchar): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickWriteImageFile: function(wand: pMagickWand; _file: pFILE): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickWriteImageBlob: function(wand: pMagickWand; length: psize_t): cuchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickSetFormat: function(wand: pMagickWand; format: pcchar): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +procedure initializegraphicsmagick(const sonames, + sonameswand: array of filenamety); + //[] = default +procedure releasegraphicsmagick; +function quantumdepth: quantumdepthty; + +procedure reggminit(const initproc: dynlibprocty); +procedure reggmdeinit(const deinitproc: dynlibprocty); +procedure reggmwandinit(const initproc: dynlibprocty); +procedure reggmwanddeinit(const deinitproc: dynlibprocty); + +implementation +uses + mseapplication; + +var + libinfo: dynlibinfoty; + libinfowand: dynlibinfoty; + qdepth: quantumdepthty; + +procedure reggminit(const initproc: dynlibprocty); +begin + regdynlibinit(libinfo,initproc); +end; + +procedure reggmdeinit(const deinitproc: dynlibprocty); +begin + regdynlibdeinit(libinfo,deinitproc); +end; + +procedure reggmwandinit(const initproc: dynlibprocty); +begin + regdynlibinit(libinfowand,initproc); +end; + +procedure reggmwanddeinit(const deinitproc: dynlibprocty); +begin + regdynlibdeinit(libinfowand,deinitproc); +end; + +function quantumdepth: quantumdepthty; +begin + result:= qdepth; +end; + +procedure init(const data: pointer); +var + l1: culong; +begin + initializemagick(pcchar(application.applicationname)); + magickgetquantumdepth(@l1); + case l1 of + 8: begin + qdepth:= qd_8; + end; + 16: begin + qdepth:= qd_16; + end + else begin + qdepth:= qd_32; + end; + end; +end; + +procedure deinit(const data: pointer); +begin + destroymagick(); +end; + +procedure initializegraphicsmagick(const sonames, + sonameswand: array of filenamety); + //[] = default +const + funcs: array[0..29] of funcinfoty = ( +// (n: ''; d: {$ifndef FPC}@{$endif}@), + (n: 'InitializeMagick'; d: {$ifndef FPC}@{$endif}@InitializeMagick), + (n: 'DestroyMagick'; d: {$ifndef FPC}@{$endif}@DestroyMagick), + (n: 'MagickMalloc'; d: {$ifndef FPC}@{$endif}@MagickMalloc), + (n: 'MagickFree'; d: {$ifndef FPC}@{$endif}@MagickFree), + (n: 'ExportImagePixelArea'; d: {$ifndef FPC}@{$endif}@ExportImagePixelArea), + (n: 'PingImage'; d: {$ifndef FPC}@{$endif}@PingImage), + (n: 'ReadImage'; d: {$ifndef FPC}@{$endif}@ReadImage), + (n: 'CloneImageInfo'; d: {$ifndef FPC}@{$endif}@CloneImageInfo), + (n: 'GetExceptionInfo'; d: {$ifndef FPC}@{$endif}@GetExceptionInfo), + (n: 'DestroyExceptionInfo'; d: {$ifndef FPC}@{$endif}@DestroyExceptionInfo), + (n: 'DestroyImage'; d: {$ifndef FPC}@{$endif}@DestroyImage), + (n: 'DispatchImage'; d: {$ifndef FPC}@{$endif}@DispatchImage), + (n: 'PingBlob'; d: {$ifndef FPC}@{$endif}@PingBlob), + (n: 'BlobToImage'; d: {$ifndef FPC}@{$endif}@BlobToImage), + (n: 'ConstituteImage'; d: {$ifndef FPC}@{$endif}@ConstituteImage), + (n: 'ImportImagePixelArea'; d: {$ifndef FPC}@{$endif}@ImportImagePixelArea), + (n: 'ImportPixelAreaOptionsInit'; + d: {$ifndef FPC}@{$endif}@ImportPixelAreaOptionsInit), + (n: 'ExportPixelAreaOptionsInit'; + d: {$ifndef FPC}@{$endif}@ExportPixelAreaOptionsInit), + (n: 'AllocateImage'; d: {$ifndef FPC}@{$endif}@AllocateImage), + (n: 'GetImagePixels'; d: {$ifndef FPC}@{$endif}@GetImagePixels), + (n: 'SetImagePixels'; d: {$ifndef FPC}@{$endif}@SetImagePixels), + (n: 'DestroyImageInfo'; d: {$ifndef FPC}@{$endif}@DestroyImageInfo), + (n: 'WriteImage'; d: {$ifndef FPC}@{$endif}@WriteImage), + (n: 'ImageToBlob'; d: {$ifndef FPC}@{$endif}@ImageToBlob), + (n: 'SyncImagePixels'; d: {$ifndef FPC}@{$endif}@SyncImagePixels), + (n: 'AllocateImageColormap'; + d: {$ifndef FPC}@{$endif}@AllocateImageColormap), + (n: 'ResizeImage'; d: {$ifndef FPC}@{$endif}@ResizeImage), + (n: 'SampleImage'; d: {$ifndef FPC}@{$endif}@SampleImage), + (n: 'ScaleImage'; d: {$ifndef FPC}@{$endif}@ScaleImage), + (n: 'RotateImage'; d: {$ifndef FPC}@{$endif}@RotateImage) + ); + errormessage = 'Can not load GraphicsMagick library. '; + + funcswand: array[0..11] of funcinfoty = ( + (n: 'NewMagickWand'; d: {$ifndef FPC}@{$endif}@NewMagickWand), + (n: 'DestroyMagickWand'; d: {$ifndef FPC}@{$endif}@DestroyMagickWand), + (n: 'MagickGetVersion'; d: {$ifndef FPC}@{$endif}@MagickGetVersion), + (n: 'MagickGetQuantumDepth'; + d: {$ifndef FPC}@{$endif}@MagickGetQuantumDepth), + (n: 'MagickQueryFormats'; d: {$ifndef FPC}@{$endif}@MagickQueryFormats), + (n: 'MagickReadImage'; d: {$ifndef FPC}@{$endif}@MagickReadImage), + (n: 'MagickReadImageBlob'; d: {$ifndef FPC}@{$endif}@MagickReadImageBlob), + (n: 'MagickReadImageFile'; d: {$ifndef FPC}@{$endif}@MagickReadImageFile), + (n: 'MagickWriteImage'; d: {$ifndef FPC}@{$endif}@MagickWriteImage), + (n: 'MagickWriteImageFile'; d: {$ifndef FPC}@{$endif}@MagickWriteImageFile), + (n: 'MagickWriteImageBlob'; d: {$ifndef FPC}@{$endif}@MagickWriteImageBlob), + (n: 'MagickSetFormat'; d: {$ifndef FPC}@{$endif}@MagickSetFormat) + ); + errormessagewand = 'Can not load GraphicsMagickWand library. '; + +begin + initializedynlib(libinfo,sonames,graphicsmagiclib,funcs,[],errormessage,nil); + initializedynlib(libinfowand,sonameswand,graphicsmagicwandlib,funcswand, + [],errormessagewand,@init); +end; + +procedure releasegraphicsmagick; +begin + releasedynlib(libinfowand,@deinit); + releasedynlib(libinfo,@deinit); +end; + +initialization + initializelibinfo(libinfo); + initializelibinfo(libinfowand); +finalization + finalizelibinfo(libinfo); + finalizelibinfo(libinfowand); +end. diff --git a/mseide-msegui/lib/common/image/msegraphicstream.pas b/mseide-msegui/lib/common/image/msegraphicstream.pas new file mode 100644 index 0000000..85b883a --- /dev/null +++ b/mseide-msegui/lib/common/image/msegraphicstream.pas @@ -0,0 +1,933 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegraphicstream; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + sysutils,classes,mclasses,msebitmap,msegraphics,fpimage, + msestrings,msetypes; + +const + graphicformatdelimiter = ';'; +type + egraphicformat = class(exception); + + fpreaderclassty = class of tfpcustomimagereader; + + tmsefpmemoryimage = class(tfpmemoryimage) + private + fhasalpha: boolean; + fmonoalpha: boolean; + public + procedure assign(source: tpersistent); override; + procedure assignto(dest: tpersistent); override; + procedure writetostream(const dest: tstream; + const awriter: tfpcustomimagewriter); + //owns the writer + property hasalpha: boolean read fhasalpha; + property monoalpha: boolean read fmonoalpha; + end; + + readgraphicprocty = function(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; + writegraphicprocty = procedure(const dest: tstream; + const source: tobject; const format: string; + const params: array of const); + +function readgraphic(const source: tstream; const dest: tbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //returns formatname +function readgraphic(const source: tstream; const dest: tmaskedbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //returns formatname +function readgraphic(const source: tstream; + const dest: timagelist): string; overload; + //returns formatname +function tryreadgraphic(const source: tstream; const dest: tbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //returns format name, '' = unknown/not supported + //exception in case of read error +function tryreadgraphic(const source: tstream; const dest: tmaskedbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //returns format name, '' = unknown/not supported + //exception in case of read error +function tryreadgraphic(const source: tstream; + const dest: timagelist): string; overload; + //returns format name, '' = unknown/not supported + //exception in case of read error + +procedure writegraphic(const dest: tstream; const source: tbitmap; + const aformatname: string; + const params: array of const); overload; +procedure writegraphic(const dest: tstream; const source: tmaskedbitmap; + const aformatname: string; + const params: array of const); overload; +procedure writegraphic(const dest: tstream; const source: timagelist); overload; + //for ico + +procedure registergraphicformat(const aformatlabel: string; + const areadproc: readgraphicprocty; + const awriteproc: writegraphicprocty; + const afiltername: msestring; + const afilemask: array of msestring); +function graphicformatlabels: stringarty; +function graphicfilemasks: filenamearty; +function graphicfilefilternames: msestringarty; +function graphicfilefiltermasks: msestringarty; +function graphicfilefilterlabel(const index: integer): string; + +function readfpgraphic(const source: tstream; const readerclass: fpreaderclassty; + const dest: tpersistent): boolean; + +implementation +uses + msestockobjects,msegraphutils,msearrayutils; + +type + tmaskedbitmap1 = class(tmaskedbitmap); + + graphicformatinfoty = record + formatlabel: string; + readproc: readgraphicprocty; + writeproc: writegraphicprocty; + filtername: msestring; + filemask: msestringarty; + end; + graphicformatinfoarty = array of graphicformatinfoty; + +var + formats: graphicformatinfoarty; + +function order: integerarty; +var + ar1: msestringarty; + int1: integer; +begin + setlength(ar1,length(formats)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= formats[int1].filtername; + end; + sortarray(ar1,sms_upi,result); +end; + +function graphicformatlabels: stringarty; +var + ar1: stringarty; + int1: integer; +begin + setlength(ar1,length(formats)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= formats[int1].formatlabel; + end; + orderarray(order,ar1); + setlength(result,1); + result[0]:= ''; + stackarray(ar1,result); +end; + +function graphicfilefilterlabel(const index: integer): string; +var + ar1: stringarty; +begin + ar1:= graphicformatlabels; + if (index < 0) or (index > high(ar1)) then begin + result:= ''; + end + else begin + result:= ar1[index]; + end; +end; + +function graphicfilefilternames: msestringarty; +var + ar1: msestringarty; + int1: integer; +begin + setlength(ar1,length(formats)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= formats[int1].filtername; + end; + orderarray(order,ar1); + setlength(result,1); + result[0]:= stockobjects.captions[sc_All]; + stackarray(ar1,result); +end; + +function graphicfilefiltermasks: msestringarty; +var + ar1: msestringararty; + int1,int2: integer; + ar2: msestringarty; +begin + setlength(ar1,length(formats)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= formats[int1].filemask; + end; + orderarray(order,ar1,sizeof(ar1[0])); + setlength(result,1); + for int1:= 0 to high(ar1) do begin + for int2:= 0 to high(ar1[int1]) do begin + result[0]:= result[0]+'"'+ar1[int1][int2]+'" '; + end; + end; + if result[0] <> '' then begin + setlength(result[0],length(result[0])-1); + end; + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar2) do begin + if high(ar1[int1]) > 0 then begin + for int2:= 0 to high(ar1[int1]) do begin + ar2[int1]:= ar2[int1] + '"' + ar1[int1][int2] + '" '; + end; + setlength(ar2[int1],length(ar2[int1])-1); + end + else begin + if ar1[int1] <> nil then begin + ar2[int1]:= ar1[int1][0]; + end; + end; + end; + setlength(result,1+length(ar2)); + for int1:= 0 to high(ar2) do begin + result[int1+1]:= ar2[int1]; + end; +end; + +function graphicfilemasks: filenamearty; +var + co: integer; + int1,int2: integer; +begin + co:= 0; + for int1:= 0 to high(formats) do begin + for int2:= 0 to high(formats[int1].filemask) do begin + additem(result,formats[int1].filemask[int2],co); + end; + end; + setlength(result,co); +end; + +procedure formaterror(const text,format: string); +var + str1: string; +begin + str1:= text; + if format <> '' then begin + str1:= str1 + ': '+format; + end; + str1:= str1 + '.'; + raise egraphicformat.create(str1); +end; + +procedure registergraphicformat(const aformatlabel: string; + const areadproc: readgraphicprocty; + const awriteproc: writegraphicprocty; + const afiltername: msestring; + const afilemask: array of msestring); +var + int1,int2: integer; +begin + int2:= -1; + for int1:= 0 to high(formats) do begin + if formats[int1].formatlabel = aformatlabel then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + setlength(formats,high(formats) + 2); + int2:= high(formats); + end; + with formats[int2] do begin + formatlabel:= aformatlabel; + if {$ifndef FPC}@{$endif}areadproc <> nil then begin + readproc:= areadproc; + end; + if {$ifndef FPC}@{$endif}awriteproc <> nil then begin + writeproc:= awriteproc; + end; + filtername:= afiltername; + setlength(filemask,length(afilemask)); + for int1:= 0 to high(filemask) do begin + filemask[int1]:= afilemask[int1]; + end; + end; +end; + +function readgraphic1(const atry: boolean; const source: tstream; + const adest: tobject; const aformatlabel: string; + const params: array of const): string; + //index = select image in ico format +var + int1,int3: integer; + ar1: stringarty; + found: boolean; + str1: string; +begin + result:= ''; + ar1:= nil; //compiler warning + if aformatlabel = '' then begin + found:= high(formats) >= 0; + for int1:= 0 to high(formats) do begin + with formats[int1] do begin + if assigned(readproc) then begin + str1:= formats[int1].formatlabel; + if readproc(source,adest,str1,params) then begin + result:= str1; + exit; + end; + source.position:= 0; + end; + end; + end; + end + else begin + found:= false; + ar1:= splitstring(aformatlabel,graphicformatdelimiter); + for int3:= 0 to high(ar1) do begin + for int1:= 0 to high(formats) do begin + with formats[int1] do begin + if (formatlabel = ar1[int3]) then begin + found:= true; + if assigned(readproc) then begin + str1:= formats[int1].formatlabel; + if readproc(source,adest,str1,params) then begin + result:= str1; + exit; + end; + end; + break; + end; + end; + end; + end; + end; + if not atry then begin + if not found then begin + formaterror( + ansistring(stockobjects.captions[sc_graphic_format_not_supported]), + aformatlabel); + end + else begin + formaterror(ansistring(stockobjects.captions[sc_graphic_format_error]), + aformatlabel); + end; + end; +end; + +procedure writegraphic1(const dest: tstream; const asource: tobject; + const aformatlabel: string; const params: array of const); +var + int1,int2: integer; +begin + int2:= -1; + for int1:= 0 to high(formats) do begin + with formats[int1] do begin + if (formatlabel = aformatlabel) then begin + if assigned(writeproc) then begin + int2:= int1; + end; + break; + end; + end; + end; + if int2 < 0 then begin + formaterror( + ansistring(stockobjects.captions[sc_graphic_format_not_supported]), + aformatlabel); + end; + with formats[int2] do begin + writeproc(dest,asource,aformatlabel,params); + end; +end; + +function readgraphic(const source: tstream; const dest: tbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; +begin + result:= readgraphic1(false,source,dest,aformatname,params); +end; + +function readgraphic(const source: tstream; const dest: tmaskedbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //index = select image in ico format +begin + result:= readgraphic1(false,source,dest,aformatname,params); +end; + +function readgraphic(const source: tstream; + const dest: timagelist): string; overload; +begin + result:= readgraphic1(false,source,dest,'ico',[-1]); +end; + +function tryreadgraphic(const source: tstream; const dest: tbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; +begin + result:= readgraphic1(true,source,dest,aformatname,params); +end; + +function tryreadgraphic(const source: tstream; const dest: tmaskedbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //index = select image in ico format +begin + result:= readgraphic1(true,source,dest,aformatname,params); +end; + +function tryreadgraphic(const source: tstream; + const dest: timagelist): string; overload; +begin + result:= readgraphic1(true,source,dest,'ico',[-1]); +end; + +procedure writegraphic(const dest: tstream; const source: tbitmap; + const aformatname: string; + const params: array of const); overload; +begin + writegraphic1(dest,source,aformatname,params); +end; + +procedure writegraphic(const dest: tstream; const source: tmaskedbitmap; + const aformatname: string; + const params: array of const); overload; + +begin + writegraphic1(dest,source,aformatname,params); +end; + +procedure writegraphic(const dest: tstream; const source: timagelist); overload; + //index = select image in ico format +begin + writegraphic1(dest,source,'ico',[]); +end; + +function readfpgraphic(const source: tstream; const readerclass: fpreaderclassty; + const dest: tpersistent): boolean; +var + reader: tfpcustomimagereader; + img: tmsefpmemoryimage; + int1: integer; +begin + result:= false; + reader:= readerclass.create; + try + int1:= source.position; + if reader.checkcontents(source) then begin + img:= tmsefpmemoryimage.create(0,0); + img.usepalette:= false; + try + source.position:= int1; + reader.imageread(source,img); + dest.assign(img); + result:= true; + finally + img.free; + end; + end + else begin + source.position:= int1; + end; + finally + reader.free; + end; +end; + +{ tmsefpmemoryimage } + +procedure tmsefpmemoryimage.writetostream(const dest: tstream; + const awriter: tfpcustomimagewriter); + //owns the writer +begin + try + savetostream(dest,awriter); + finally + awriter.free; + end; +end; + +procedure tmsefpmemoryimage.assign(source: tpersistent); + function to16(const acolor: colorty): tfpcolor; + var + rgb1: rgbtriplety; + begin + rgb1:= colortorgb(acolor); + result.red:= rgb1.red + (rgb1.red shl 8); + result.green:= rgb1.green + (rgb1.green shl 8); + result.blue:= rgb1.blue + (rgb1.blue shl 8); + result.alpha:= 0; + end; +var + col1,col0,col3: tfpcolor; + int1,int2: integer; + wo1: word; + lwo1: longword; + masked1: boolean; + maskkind1: bitmapkindty; + pimageline,pmaskline: pointer; + pi,pm: pointer; + imagestep,maskstep: integer; +begin + if source is tbitmap then begin + setsize(0,0); //clear + masked1:= source is tmaskedbitmap; + if masked1 then begin + with tmaskedbitmap(source) do begin + masked1:= masked; + if masked1 then begin + with mask do begin + maskkind1:= mask.kind; + fmonoalpha:= maskkind1 = bmk_mono; + pmaskline:= scanline[0]; + maskstep:= scanlinestep; + end; + end; + end; + end; + fhasalpha:= masked1; + with tbitmap(source) do begin + pimageline:= scanline[0]; + imagestep:= scanlinestep; + self.setsize(width,height); + usepalette:= false; + col3.alpha:= 0; + case kind of + bmk_mono: begin //mono + col0:= to16(colorbackground); + col1:= to16(colorforeground); + usepalette:= true; + if masked1 then begin + case maskkind1 of + bmk_mono: begin //mono monmask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + lwo1:= $00000001; + for int2:= 0 to width-1 do begin + if plongword(pi)^ and lwo1 <> 0 then begin + if plongword(pm)^ and lwo1 <> 0 then begin + col1.alpha:= $ffff; + end + else begin + col1.alpha:= $0000; + end; + colors[int2,int1]:= col1; + end + else begin + if plongword(pm)^ and lwo1 <> 0 then begin + col0.alpha:= $ffff; + end + else begin + col0.alpha:= $0000; + end; + colors[int2,int1]:= col0; + end; + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(plongword(pi)); + inc(plongword(pm)); + lwo1:= $00000001; + end; + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + bmk_gray: begin //mono graymask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + lwo1:= $00000001; + for int2:= 0 to width-1 do begin + if plongword(pi)^ and lwo1 <> 0 then begin + wo1:= pbyte(pm)^; + col1.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col1; + end + else begin + wo1:= pbyte(pm)^; + col1.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col0; + end; + lwo1:= lwo1 shl 1; + inc(pbyte(pm)); + if lwo1 = 0 then begin + inc(plongword(pi)); + lwo1:= $00000001; + end; + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + else begin //mono rgbmask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + lwo1:= $00000001; + for int2:= 0 to width-1 do begin + if plongword(pi)^ and lwo1 <> 0 then begin + wo1:= (word(prgbtriplety(pm)^.red)+ + word(prgbtriplety(pm)^.green)+ + word(prgbtriplety(pm)^.blue)) div 3; + col1.alpha:= wo1 or (wo1 shl 8); + colors[int1,int2]:= col1; + end + else begin + wo1:= (word(prgbtriplety(pm)^.red)+ + word(prgbtriplety(pm)^.green)+ + word(prgbtriplety(pm)^.blue)) div 3; + col0.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col0; + end; + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(plongword(pi)); + lwo1:= $00000001; + end; + inc(plongword(pm)); + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + end; + end + else begin //mono unmasked + for int1:= 0 to height - 1 do begin + pi:= pimageline; + lwo1:= $00000001; + for int2:= 0 to width-1 do begin + if plongword(pi)^ and lwo1 <> 0 then begin + colors[int2,int1]:= col1; + end + else begin + colors[int2,int1]:= col0; + end; + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(plongword(pm)); + lwo1:= $00000001; + end; + end; + inc(pimageline,imagestep); + end; + end; + end; + bmk_gray: begin + if masked1 then begin + case maskkind1 of + bmk_mono: begin //gray monomask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + lwo1:= $00000001; + for int2:= 0 to width - 1 do begin + wo1:= pbyte(pi)^; + wo1:= wo1 shl 8; + col3.red:= wo1; + col3.green:= wo1; + col3.blue:= wo1; + if plongword(pm)^ and lwo1 <> 0 then begin + col3.alpha:= $ffff; + end + else begin + col3.alpha:= $0000; + end; + colors[int2,int1]:= col3; + inc(pbyte(pi)); + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(plongword(pm)); + lwo1:= $00000001; + end; + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + bmk_gray: begin //gray graymask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + for int2:= 0 to width - 1 do begin + wo1:= pbyte(pi)^; + wo1:= wo1 shl 8; + col3.red:= wo1; + col3.green:= wo1; + col3.blue:= wo1; + wo1:= pbyte(pm)^; + col3.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col3; + inc(pbyte(pi)); + inc(pbyte(pm)); + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + else begin //gray colormask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + for int2:= 0 to width - 1 do begin + wo1:= pbyte(pi)^; + wo1:= wo1 shl 8; + col3.red:= wo1; + col3.green:= wo1; + col3.blue:= wo1; + wo1:= (prgbtriplety(pm)^.red + prgbtriplety(pm)^.green + + prgbtriplety(pm)^.blue) div 3; + col3.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col3; + inc(pbyte(pi)); + inc(prgbtriplety(pm)); + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + end; + end + else begin //gray unmasked + for int1:= 0 to height - 1 do begin + pi:= pimageline; + for int2:= 0 to width - 1 do begin + wo1:= pbyte(pi)^; + wo1:= wo1 shl 8; + col3.red:= wo1; + col3.green:= wo1; + col3.blue:= wo1; + colors[int2,int1]:= col3; + inc(pbyte(pi)); + end; + inc(pimageline,imagestep); + end; + end; + end; + else begin //bmk_rgb + if masked1 then begin + case maskkind1 of + bmk_mono: begin //color monomask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + lwo1:= $00000001; + for int2:= 0 to width - 1 do begin + wo1:= prgbtriplety(pi)^.red; + col3.red:= wo1 or wo1 shl 8; + wo1:= prgbtriplety(pi)^.green; + col3.green:= wo1 or wo1 shl 8; + wo1:= prgbtriplety(pi)^.blue; + col3.blue:= wo1 or wo1 shl 8; + if plongword(pm)^ and lwo1 <> 0 then begin + col3.alpha:= $ffff; + end + else begin + col3.alpha:= $0000; + end; + colors[int2,int1]:= col3; + inc(plongword(pi)); + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(plongword(pm)); + lwo1:= $00000001; + end; + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + bmk_gray: begin //color graymask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + for int2:= 0 to width - 1 do begin + wo1:= (prgbtriplety(pi)^.red); + col3.red:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.green); + col3.green:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.blue); + col3.blue:= wo1 or (wo1 shl 8); + wo1:= pbyte(pm)^; + col3.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col3; + inc(prgbtriplety(pi)); + inc(pbyte(pm)); + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + else begin //color colormask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + for int2:= 0 to width - 1 do begin + wo1:= (prgbtriplety(pi)^.red); + col3.red:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.green); + col3.green:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.blue); + col3.blue:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pm)^.red + prgbtriplety(pm)^.green + + prgbtriplety(pm)^.blue) div 3; + col3.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col3; + inc(prgbtriplety(pi)); + inc(prgbtriplety(pm)); + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + end; + end + else begin //color unmasked + for int1:= 0 to height - 1 do begin + pi:= pimageline; + for int2:= 0 to width - 1 do begin + wo1:= (prgbtriplety(pi)^.red); + col3.red:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.green); + col3.green:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.blue); + col3.blue:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col3; + inc(prgbtriplety(pi)); + end; + inc(pimageline,imagestep); + end; + end; + end; + end; + end; + end + else begin + inherited; + end; +end; + +procedure tmsefpmemoryimage.assignto(dest: tpersistent); + +var + grayalpha1: boolean; + + function getmaskdata(ashift: word): boolean; + var + int1,int2,int3: integer; + bo1,bo2: boolean; +// po1: prgbtripleaty; + po1: pbyte; + by1: byte; + begin + bo1:= false; + bo2:= false; + with tmaskedbitmap1(dest) do begin + with fmask do begin + po1:= scanline[0]; + int3:= scanlinestep; + end; + for int1:= 0 to height - 1 do begin + for int2:= 0 to width - 1 do begin + by1:= colors[int2,int1].alpha shr ashift; + bo1:= bo1 or ((by1 < 255) and (by1 > 0)); + bo2:= bo2 and (by1 <> 0); + po1[int2]:= by1; + { + with po1^[int2] do begin + red:= by1; + green:= by1; + blue:= by1; + res:= 0; + end; + } + end; + inc(po1,int3); + end; + end; + grayalpha1:= bo1; + result:= bo2; + end; + +var + int1,int2,int3: integer; + po1: prgbtripleaty; + col1: tfpcolor; + col2: colorty; + bo1: boolean; + ismaskedbitmap: boolean; +begin + if dest is tbitmap then begin + ismaskedbitmap:= dest is tmaskedbitmap; + try + with tbitmap(dest) do begin + beginupdate(); + if ismaskedbitmap then begin + tmaskedbitmap(dest).masked:= false; + end; + clear(); + kind:= bmk_rgb; + size:= makesize(self.width,self.height); + bo1:= false; + po1:= scanline[0]; + int3:= scanlinestep; + for int1:= 0 to height - 1 do begin + for int2:= 0 to width - 1 do begin + col1:= colors[int2,int1]; + with po1^[int2] do begin + red:= col1.red shr 8; + green:= col1.green shr 8; + blue:= col1.blue shr 8; + res:= 0; + bo1:= bo1 or (col1.alpha < $ff00); + end; + end; + inc(pointer(po1),int3); + end; + fhasalpha:= bo1; + fmonoalpha:= false; + if ismaskedbitmap then begin + with tmaskedbitmap1(dest) do begin + if self.hasalpha then begin + graymask:= true; + include(foptions,bmo_masked); + createmask(bmk_gray); + fmask.size:= size; + include(fstate,pms_maskvalid); + if not getmaskdata(8) then begin + getmaskdata(0); //try 8 bit + end; + col2:= maskcolorbackground; + maskcolorbackground:= 0; + graymask:= grayalpha1; + fmonoalpha:= not grayalpha1; + maskcolorbackground:= col2; + include(foptions,bmo_masked); + end; + end; + end; + change; + end; + finally + tmaskedbitmap(dest).endupdate(); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/image/msemagickstream.pas b/mseide-msegui/lib/common/image/msemagickstream.pas new file mode 100644 index 0000000..cfb9f52 --- /dev/null +++ b/mseide-msegui/lib/common/image/msemagickstream.pas @@ -0,0 +1,1148 @@ +{ MSEgui Copyright (c) 2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msemagickstream; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes{msestrings},msegraphicsmagick,sysutils,mclasses,msebitmap,msegraphutils; +const + defaultblur = 1.0; +type + tmagickexception = class(exception) + public + constructor create(const ainfo: exceptioninfo); + end; + gminfoty = record + formatlabel: string; + size: sizety; + depth: integer; + end; + gmoptionty = ( + rgmo_rotmonomask, + rgmo_rotbeforescale, //rotate before scaling + rgmo_rotafterscale, //rotate after scaling + rgmo_sample, //use SampleImage() instead of ScaleImage() + rgmo_resize //use ResizeImage() with filtertype instead of ScaleImage() + ); + gmoptionsty = set of gmoptionty; + +procedure registerformats(const labels: array of string; + const filternames: array of msestring; + const filemasks: array of msestringarty); +//readgraphic parameters: + //[index: integer, width: integer, height: integer, rotation: real, + //sequence nr 0 = default 0 = default 0..2pi CCW + // -1 = default + // backgroundcolor: colorty, pixelpermm: real, options: gmoptionsty, + // default = cl_transparent 0 = default default = [] + // filter: filtertypes, blur: real] + // default = UndefinedFilter default = 1 + +//writegraphic parameters: + //[compressionquality: integer, width: integer, height: integer, + // 0..100, -1 = default 0 = default 0 = default + // rotation: real, backgroundcolor: colorty, pixelpermm: real, + // 0..2pi CCW default 0 default = cl_transparent 0 = default + // options: gmoptionsty filter: filtertypes, blur: real] + // default = [] default = UndefinedFilter default = 1 + +function readgmgraphic(const source: tstream; const dest: tbitmap; + const aindex: integer = -1; const awidth: integer = 0; + const aheight: integer = 0; const arotation: real = 0; + const abackgroundcolor: colorty = cl_transparent; + const apixelpermm: real = 0; + const aoptions: gmoptionsty = []; + const afilter: filtertypes = undefinedfilter; + const ablur: real = defaultblur): string; + //returns label +procedure writegmgraphic(const dest: tstream; const source: tbitmap; + const format: string; const aquality: integer = -1; + const awidth: integer = 0; const aheight: integer = 0; + const arotation: real = 0; + const abackgroundcolor: colorty = cl_transparent; + const apixelpermm: real = 0; + const aoptions: gmoptionsty = []; + const afilter: filtertypes = undefinedfilter; + const ablur: real = defaultblur); +function pinggmgraphic(const source: tstream; + out ainfo: gminfoty): boolean; + +implementation +uses + msegraphics,msegraphicstream,msestream,msestockobjects, + msectypes,msebits,mseclasses,mseformatstr,math; + +type + tbitmap1 = class(tbitmap); +const + ppmmtoppi = 25.4; +var + inited: boolean; + qdepth: quantumdepthty; + +procedure checkinit; +begin + if not inited then begin + initializegraphicsmagick([],[]); + qdepth:= quantumdepth(); + inited:= true; + end; +end; + +function checksnap90(const arotation: double): boolean; +begin + result:= (abs(frac(arotation / (pi/2.0))) < 0.0000001); +end; + +function snap90(const arotation: double): double; +begin + result:= arotation*(-180/pi); + if checksnap90(arotation) then begin + result:= round(result); + end; +end; + +procedure setcolor(const acolor: colorty; const dest: pointer; + const index: integer = 0); +var + rgb: rgbtriplety; + opac: card32; +begin + if acolor = cl_transparent then begin + opac:= $ffffffff; + end + else begin + opac:= 0; + end; + rgb:= colortorgb(acolor); + case qdepth of + qd_8: begin + with ppixelpacket8(dest)[index] do begin + red:= rgb.red; + green:= rgb.green; + blue:= rgb.blue; + opacity:= opac; + end; + end; + qd_16: begin + with ppixelpacket16(dest)[index] do begin + red:= rgb.red + (rgb.red shl 8); + green:= rgb.green + (rgb.green shl 8); + blue:= rgb.blue + (rgb.blue shl 8); + opacity:= opac; + end; + end; + qd_32: begin + with ppixelpacket32(dest)[index] do begin + red:= rgb.red + (rgb.red shl 8)+ (rgb.red shl 16)+ (rgb.red shl 24); + green:= rgb.green + (rgb.green shl 8) + (rgb.green shl 16) + + (rgb.green shl 24); + blue:= rgb.blue + (rgb.blue shl 8) + (rgb.blue shl 16) + (rgb.blue shl 24); + opacity:= opac; + end; + end; + end; +end; + +procedure setimagebackgroundcolor(const image: pointer; color: colorty); +begin + case qdepth of + qd_8: begin + with pimage8(image)^ do begin + setcolor(color,@b.background_color); + end; + end; + qd_16: begin + with pimage16(image)^ do begin + setcolor(color,@b.background_color); + end; + end; + else begin + with pimage32(image)^ do begin + setcolor(color,@b.background_color); + end; + end; + end; +end; + +procedure swapbits(var aimage: imagety); +var + po1,e: pbyte; +begin + with aimage do begin + po1:= pointer(pixels); + e:= po1 + length*4-1; + repeat + po1^:= bitreverse[po1^]; + inc(po1); + until po1 = e; + end; +end; + +function gmstring(const avalue: string): pcchar; +begin + result:= magickmalloc(length(avalue)+1); + move(pchar(avalue)^,result^,length(avalue)+1); +end; + +function rotrect(const avalue: sizety; const rotation: real): dpointty; + //calculate rotated dimensions + //todo: simplify +var + si1,co1: double; + minx: double = 0; + maxx: double = 0; + miny: double = 0; + maxy: double = 0; + + procedure rot(var p: dpointty); + var + x,y: double; + begin + x:= p.x * co1 + p.y * si1; + y:= -p.x * si1 + p.y * co1; + p.x:= x; + p.y:= y; + end; //rot + + procedure checkmax(var p: dpointty); + begin + if p.x < minx then begin + minx:= p.x; + end; + if p.y < miny then begin + miny:= p.y; + end; + if p.x > maxx then begin + maxx:= p.x; + end; + if p.y > maxy then begin + maxy:= p.y; + end; + end; //checkmax + +var + points: array[0..2] of dpointty; + int1: integer; + +begin + if rotation <> 0.0 then begin + si1:= sin(rotation); //todo: simplify + co1:= cos(rotation); + fillchar(points,sizeof(points),0); + points[0].x:= avalue.cx; + points[1].y:= avalue.cy; + points[2].x:= avalue.cx; + points[2].y:= avalue.cy; + for int1:= 0 to high(points) do begin + rot(points[int1]); + end; + for int1:= 0 to high(points) do begin + checkmax(points[int1]); + end; + result.x:= maxx-minx; + result.y:= maxy-miny; + end + else begin + result.x:= avalue.cx; + result.y:= avalue.cy; + end; +end; + +function fitscale(const width: integer; const height: integer; + const current: sizety; out dest: sizety; + const rotation: real; const rotafter: boolean; + const rotcurrent: dpointty): boolean; + //true if scaling necessary +var + {rotcurrent,}rotdest: dpointty; + sca1: double; +begin + dest:= current; + result:= (current.cx > 0) and (current.cy > 0); + if result then begin + if rotafter and (rotation <> 0) then begin + { + si1:= sin(rotation); //todo: simplify + co1:= cos(rotation); + fillchar(points,sizeof(points),0); + points[0].x:= current.cx; + points[1].y:= current.cy; + points[2].x:= current.cx; + points[2].y:= current.cy; + for int1:= 0 to high(points) do begin + rot(points[int1]); + end; + for int1:= 0 to high(points) do begin + checkmax(points[int1]); + end; + rotcurrent.x:= maxx-minx; + rotcurrent.y:= maxy-miny; + } + rotdest:= rotcurrent; + if width <> 0 then begin + rotdest.x:= width; + end; + if height <> 0 then begin + rotdest.y:= height; + end; + if rotdest.x*rotcurrent.y > rotdest.y*rotcurrent.x then begin + rotdest.x:= (rotcurrent.x*rotdest.y) / rotcurrent.y; + sca1:= rotdest.x/rotcurrent.x; + end + else begin + rotdest.y:= (rotcurrent.y*rotdest.x) / rotcurrent.x; + sca1:= rotdest.y/rotcurrent.y; + end; + dest.cx:= round(current.cx*sca1); + dest.cy:= round(current.cy*sca1); + end + else begin //scale to fit in destrect + if width <> 0 then begin + dest.cx:= width; + end; + if height <> 0 then begin + dest.cy:= height; + end; + if dest.cx*current.cy > dest.cy*current.cx then begin + dest.cx:= (current.cx*dest.cy) div current.cy; + end + else begin + dest.cy:= (current.cy*dest.cx) div current.cx; + end; + end; + result:= (current.cx <> dest.cx) or (current.cy <> dest.cy); + end; +end; + +function checkrotafter(const asize: sizety; const awidth: integer; + const aheight: integer; const aoptions: gmoptionsty; + const rotation: real; out rotcurrent: dpointty): boolean; +var + si1: sizety; +begin + rotcurrent:= rotrect(asize,rotation); + if rgmo_rotbeforescale in aoptions then begin + result:= false; + end + else begin + if rgmo_rotafterscale in aoptions then begin + result:= true; + end + else begin + si1:= asize; + if awidth <> 0 then begin + si1.cx:= awidth; + end; + if aheight <> 0 then begin + si1.cy:= aheight; + end; + result:= (si1.cx < rotcurrent.x) or (si1.cy < rotcurrent.y); + end; + end; +end; + +procedure writegmgraphic(const dest: tstream; const source: tbitmap; + const format: string; const aquality: integer = -1; + const awidth: integer = 0; const aheight: integer = 0; + const arotation: real = 0; + const abackgroundcolor: colorty = cl_transparent; + const apixelpermm: real = 0; + const aoptions: gmoptionsty = []; + const afilter: filtertypes = undefinedfilter; + const ablur: real = defaultblur); +var + exceptinf: exceptioninfo; + image,image2: pointer; + hasmask,monomask,rotmask: boolean; + si1,si2: sizety; + imagebuffer: maskedimagety; + buf: pointer; + maskscanstep: integer; + maskscanpo: pointer; + rotcurrent: dpointty; + + procedure error; + begin + raise tmagickexception.create(exceptinf); + end; + + procedure dorotate(); + begin + if arotation <> 0 then begin + image2:= rotateimage(image,snap90(arotation),@exceptinf); + if image2 = nil then begin + exit; + end; + destroyimage(image); + image:= image2; + if rotmask then begin + pimage8(image)^.a.matte:= magicktrue; + end; + si1:= ms(pimage8(image)^.a.columns,pimage8(image)^.a.rows); + end; + end; //dorotate + + procedure doscale(const rotafter: boolean); + begin + if fitscale(awidth,aheight,si1,si2,arotation,rotafter,rotcurrent) then begin + if rgmo_sample in aoptions then begin + image2:= sampleimage(image,si2.cx,si2.cy,@exceptinf); + end + else begin + if rgmo_resize in aoptions then begin + image2:= resizeimage(image,si2.cx,si2.cy,afilter,ablur,@exceptinf); + end + else begin + image2:= scaleimage(image,si2.cx,si2.cy,@exceptinf); + end; + end; + if image2 = nil then begin + exit; + end; + destroyimage(image); + image:= image2; + si1:= ms(pimage8(image)^.a.columns,pimage8(image)^.a.rows); + end; + end; //doscale + + procedure checkcolormask(); + var + d,e: pbyte; + s: prgbtriplety; + begin + with imagebuffer.mask do begin + if kind = bmk_rgb then begin + getmem(buf,length); + d:= buf; + e:= buf + length; + s:= pointer(imagebuffer.mask.pixels); + maskscanpo:= buf; + maskscanstep:= imagebuffer.mask.size.cx; + repeat + d^:= (word(s^.red) + word(s^.green) + word(s^.blue)) div 3; + inc(s); + inc(d); + until d = e; + end + else begin + maskscanpo:= imagebuffer.mask.pixels; + maskscanstep:= imagebuffer.mask.linebytes; + end; + end; + if monomask then begin + swapbits(imagebuffer.mask); + end; + end; + +var + bo1,bo2: boolean; + imageinfo: pointer; + si: size_t; + blob: pointer; + int1: integer; + po1,po2: pointer; + s,d,e,e1: prgbtriplety; + sw1,sw2: plongword; + sb1: pbyte; + lwo1: longword; + +begin + if source is tbitmap then begin + with tbitmap1(source) do begin + if hasimage then begin + checkinit; + getexceptioninfo(@exceptinf); + imageinfo:= nil; + image:= nil; + blob:= nil; + buf:= nil; + try + rotmask:= (abackgroundcolor = cl_transparent) and + not checksnap90(arotation); + monomask:= false; + hasmask:= (source is tmaskedbitmap) and (tmaskedbitmap(source).masked); + bo1:= getimageref(imagebuffer.image); + bo2:= false; + if hasmask then begin + bo2:= tbitmap1(tmaskedbitmap(source).mask).getimageref(imagebuffer.mask); + monomask:= imagebuffer.mask.kind = bmk_mono; + end; + case imagebuffer.image.kind of + bmk_mono: begin //mono + imageinfo:= cloneimageinfo(nil); + image:= allocateimage(imageinfo); + allocateimagecolormap(image,2); + with pimage8(image)^ do begin + a.storage_class:= pseudoclass; + a.columns:= imagebuffer.image.size.cx; + a.rows:= imagebuffer.image.size.cy; + a.depth:= 1; + if hasmask then begin + a.matte:= magicktrue; + checkcolormask(); + end; + end; + case qdepth of + qd_8: begin + with pimage8(image)^ do begin + setcolor(colorbackground,b.colormap,0); + setcolor(colorforeground,b.colormap,1); + end; + end; + qd_16: begin + with pimage16(image)^ do begin + setcolor(colorbackground,b.colormap,0); + setcolor(colorforeground,b.colormap,1); + end; + end; + else begin + with pimage32(image)^ do begin + setcolor(colorbackground,b.colormap,0); + setcolor(colorforeground,b.colormap,1); + end; + end; + end; + with imagebuffer.image do begin + swapbits(imagebuffer.image); + po1:= pixels; + po2:= maskscanpo; + for int1:= 0 to imagebuffer.image.size.cy-1 do begin + if (setimagepixels(image,0,int1, + imagebuffer.image.size.cx,1) = nil) or + (importimagepixelarea(image,indexquantum,1,po1, + nil,nil) = magickfail) then begin + error(); + end; + if hasmask then begin + if monomask then begin + if importimagepixelarea(image,alphaquantum,1,po2, + nil,nil) = magickfail then begin + error(); + end; + end + else begin + if importimagepixelarea(image,alphaquantum,8,po2, + nil,nil) = magickfail then begin + error(); + end; + end; + inc(po2,maskscanstep); + end; + if SyncImagePixels(image) = 0 then begin + error(); + end; + inc(po1,scanlinestep); + end; + if not bo1 then begin //restore bit order + swapbits(imagebuffer.image); + end; + if hasmask then begin + if monomask and not bo2 then begin + swapbits(imagebuffer.mask); //restore bit order + end; + with pimage8(image)^ do begin + a.colors:= 0; + a.storage_class:= directclass; + end; + case qdepth of //GraphicMagick removes + qd_8: begin //alpha channel for palette images + with pimage8(image)^ do begin + magickfree(b.colormap); + b.colormap:= nil; + end; + end; + qd_16: begin + with pimage16(image)^ do begin + magickfree(b.colormap); + b.colormap:= nil; + end; + end; + qd_32: begin + with pimage32(image)^ do begin + magickfree(b.colormap); + b.colormap:= nil; + end; + end; + end; + end; + end; + end; + bmk_gray: begin //gray + imageinfo:= cloneimageinfo(nil); + image:= allocateimage(imageinfo); + with pimage8(image)^ do begin + a.storage_class:= directclass; + a.columns:= imagebuffer.image.size.cx; + a.rows:= imagebuffer.image.size.cy; + a.depth:= 8; + if hasmask then begin + a.matte:= magicktrue; + checkcolormask(); + end; + end; + with imagebuffer.image do begin + po1:= pixels; + po2:= maskscanpo; + for int1:= 0 to imagebuffer.image.size.cy-1 do begin + if (setimagepixels(image,0,int1, + imagebuffer.image.size.cx,1) = nil) or + (importimagepixelarea(image,redquantum,8,po1, + nil,nil) = magickfail) or + (importimagepixelarea(image,greenquantum,8,po1, + nil,nil) = magickfail) or + (importimagepixelarea(image,bluequantum,8,po1, + nil,nil) = magickfail) + then begin + error(); + end; + if hasmask then begin + if monomask then begin + if importimagepixelarea(image,alphaquantum,1,po2, + nil,nil) = magickfail then begin + error(); + end; + end + else begin + if importimagepixelarea(image,alphaquantum,8,po2, + nil,nil) = magickfail then begin + error(); + end; + end; + inc(po2,maskscanstep); + end; + if SyncImagePixels(image) = 0 then begin + error(); + end; + inc(po1,scanlinestep); + end; + end; + if monomask and not bo2 then begin + swapbits(imagebuffer.mask); //restore bit order + end; + end; + bmk_rgb: begin //color + if hasmask then begin + d:= pointer(imagebuffer.image.pixels); + e:= d + imagebuffer.image.length; + case imagebuffer.mask.kind of + bmk_mono: begin + sw1:= pointer(imagebuffer.mask.pixels); + repeat + lwo1:= $00000001; + sw2:= sw1; + e1:= d + width; + repeat + if sw2^ and lwo1 <> 0 then begin + d^.res:= $ff; + end + else begin + d^.res:= 0; + end; + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(sw2); + lwo1:= $00000001; + end; + inc(d); + until d = e1; + sw1:= pointer(sw1) + imagebuffer.mask.linebytes; + until d = e; + end; + bmk_gray: begin + sb1:= pointer(imagebuffer.mask.pixels); + repeat + d^.res:= sb1^; + inc(sb1); + inc(d); + until d = e; + end; + else begin + s:= pointer(imagebuffer.mask.pixels); + repeat + d^.res:= (word(s^.red) + word(s^.green) + word(s^.blue)) div 3; + inc(s); + inc(d); + until d = e; + end; + end; + image:= constituteimage(imagebuffer.image.size.cx, + imagebuffer.image.size.cy,'BGRA',charpixel, + imagebuffer.image.pixels,@exceptinf); + if not bo1 then begin //restore res byte + s:= pointer(imagebuffer.mask.pixels); + d:= pointer(imagebuffer.image.pixels); + repeat + d^.res:= 0; + inc(d); + until d = e; + end; + end + else begin + image:= constituteimage(imagebuffer.image.size.cx, + imagebuffer.image.size.cy,'BGRP',charpixel, + imagebuffer.image.pixels,@exceptinf); + end; + end; + end; + if image = nil then begin + raise tmagickexception.create(exceptinf); + end; + imageinfo:= cloneimageinfo(nil); + with pimageinfo8(imageinfo)^ do begin + if aquality >= 0 then begin + a.quality:= aquality; + end; + end; + case qdepth of + qd_8: begin + with pimage8(image)^ do begin + c.magick:= uppercase(format); + end; + end; + qd_16: begin + with pimage16(image)^ do begin + c.magick:= uppercase(format); + end; + end; + else begin + with pimage32(image)^ do begin + c.magick:= uppercase(format); + end; + end; + end; + setimagebackgroundcolor(image,abackgroundcolor); + si1:= imagebuffer.image.size; + if checkrotafter(si1,awidth,aheight,aoptions,arotation,rotcurrent) then begin + doscale(true); + dorotate(); + end + else begin + dorotate(); + doscale(false); + end; + if apixelpermm > 0 then begin + with pimageinfo8(imageinfo)^ do begin + a.units:= pixelsperinchresolution; + a.density:= gmstring(ansistring(formatfloatmse(apixelpermm*ppmmtoppi, + '',true))); + end; + end; + + blob:= imagetoblob(imageinfo,image,@si,@exceptinf); + if blob = nil then begin + error(); + end; + dest.writebuffer(blob^,si); + finally + if buf <> nil then begin + freemem(buf); + end; + if blob <> nil then begin + magickfree(blob); + end; + if imageinfo <> nil then begin + destroyimageinfo(imageinfo); + end; + if image <> nil then begin + destroyimage(image); + end; + destroyexceptioninfo(@exceptinf); + if bo1 then begin + freeimage(imagebuffer.image); + end; + if bo2 then begin + freeimage(imagebuffer.mask); + end; + end; + end; + end; + end; +end; + +function pinggmgraphic(const source: tstream; + out ainfo: gminfoty): boolean; +var + imageinfo: pointer; + exceptinf: exceptioninfo; + image: pointer; + str1: string; + datapo: pointer; + datalen: card32; +begin + result:= false; + checkinit; + datapo:= source.memory; + datalen:= source.size; + if datapo = nil then begin + str1:= source.readdatastring; + datapo:= pointer(str1); + datalen:= length(str1); + end; + getexceptioninfo(@exceptinf); + imageinfo:= cloneimageinfo(nil); + image:= pingblob(imageinfo,datapo,datalen,@exceptinf); + if image <> nil then begin + with pimage8(image)^ do begin + ainfo.size.cx:= a.columns; + ainfo.size.cy:= a.rows; + ainfo.depth:= a.depth; + end; + case qdepth of + qd_8: begin + with pimage8(image)^ do begin + ainfo.formatlabel:= lowercase(c.magick); + end; + end; + qd_16: begin + with pimage16(image)^ do begin + ainfo.formatlabel:= lowercase(c.magick); + end; + end; + else begin + with pimage32(image)^ do begin + ainfo.formatlabel:= lowercase(c.magick); + end; + end; + end; + result:= true; + destroyimage(image); + end; + destroyimageinfo(imageinfo); + destroyexceptioninfo(@exceptinf); +end; + +function readgmgraphic(const source: tstream; const dest: tbitmap; + const aindex: integer = -1; + const awidth: integer = 0; const aheight: integer = 0; + const arotation: real = 0; + const abackgroundcolor: colorty = cl_transparent; + const apixelpermm: real = 0; + const aoptions: gmoptionsty = []; + const afilter: filtertypes = undefinedfilter; + const ablur: real = defaultblur): string; + //returns label +var + exceptinf: exceptioninfo; + image,image2: pointer; + hasmask,monomask,rotmask: boolean; + si1,si2: sizety; + rotcurrent: dpointty; + + procedure dorotate(); + begin + if arotation <> 0 then begin + setimagebackgroundcolor(image,abackgroundcolor); + image2:= rotateimage(image,snap90(arotation),@exceptinf); + if image2 = nil then begin + exit; + end; + destroyimage(image); + image:= image2; + if rotmask then begin + pimage8(image)^.a.matte:= magicktrue; + monomask:= not hasmask and (rgmo_rotmonomask in aoptions); + hasmask:= true; + end; + si1:= ms(pimage8(image)^.a.columns,pimage8(image)^.a.rows); + end; + end; //dorotate + + procedure doscale(const rotafter: boolean); + begin + if fitscale(awidth,aheight,si1,si2,arotation,rotafter,rotcurrent) then begin + if rgmo_sample in aoptions then begin + image2:= sampleimage(image,si2.cx,si2.cy,@exceptinf); + end + else begin + if rgmo_resize in aoptions then begin + image2:= resizeimage(image,si2.cx,si2.cy,afilter,ablur,@exceptinf); + end + else begin + image2:= scaleimage(image,si2.cx,si2.cy,@exceptinf); + end; + end; +// image2:= scaleimage(image,si2.cx,si2.cy,@exceptinf); + if image2 = nil then begin + exit; + end; + destroyimage(image); + image:= image2; + si1:= ms(pimage8(image)^.a.columns,pimage8(image)^.a.rows); + end; + end; //doscale + +var + imageinfo: pointer; + imagebuffer: maskedimagety; + str1: string; //todo: use tstream -> c-stream adaptor + bo2: boolean; + datapo: pointer; + datalen: card32; + po1: pointer; + int1: integer; + cx1,cy1: integer; + +begin + result:= ''; + monomask:= false; + bo2:= dest is tmaskedbitmap; + rotmask:= bo2 and (abackgroundcolor = cl_transparent) and + (abs(frac(arotation / (pi/2.0))) > 0.0000001); + imagebuffer.image.pixels:= nil; + imagebuffer.mask.pixels:= nil; + checkinit; + datapo:= source.memory; + datalen:= source.size; + if datapo = nil then begin + str1:= source.readdatastring; + datapo:= pointer(str1); + datalen:= length(str1); + end; + getexceptioninfo(@exceptinf); + image:= nil; + imageinfo:= cloneimageinfo(nil); + try + with pimageinfo8(imageinfo)^ do begin //a identical for all dephts + if apixelpermm > 0 then begin + a.units:= pixelsperinchresolution; + a.density:= gmstring(ansistring(formatfloatmse(apixelpermm*ppmmtoppi, + '',true))); + end; + if aindex >= 0 then begin + a.subimage:= aindex; + end; + image:= pingblob(imageinfo,datapo,datalen,@exceptinf); + if image = nil then begin + exit; + end; + if (pimage8(image)^.a.columns > 0) and (pimage8(image)^.a.rows > 0) then begin + //limit to necessary size + if (awidth <> 0) and (pimage8(image)^.a.columns > awidth) or + (aheight <> 0) and (pimage8(image)^.a.rows > aheight) then begin + cx1:= awidth; + if cx1 = 0 then begin + cx1:= (pimage8(image)^.a.columns * aheight) div pimage8(image)^.a.rows; + end; + cy1:= aheight; + if cy1 = 0 then begin + cy1:= (pimage8(image)^.a.rows * awidth) div pimage8(image)^.a.columns; + end; + a.size:= gmstring(inttostr(cx1)+'x'+inttostr(cy1)); + end; + end; + destroyimage(image); + image:= nil; + end; + case qdepth of + qd_8: begin + with pimageinfo8(imageinfo)^ do begin + end; + end; + qd_16: begin + with pimageinfo16(imageinfo)^ do begin + end; + end; + else begin + with pimageinfo32(imageinfo)^ do begin + end; + end; + end; + + image:= blobtoimage(imageinfo,datapo,datalen,@exceptinf); + if image <> nil then begin + with pimage8(image)^ do begin //a is identical for all depths + hasmask:= a.matte = magicktrue; + si1:= ms(a.columns,a.rows); + end; + if checkrotafter(si1,awidth,aheight,aoptions,arotation,rotcurrent) then begin + doscale(true); + dorotate(); + end + else begin + dorotate(); + doscale(false); + end; + case qdepth of + qd_8: begin + with pimage8(image)^ do begin + result:= lowercase(c.magick); + if result = '' then begin + result:= lowercase(c.magick_filename); + end; + end; + end; + qd_16: begin + with pimage16(image)^ do begin + result:= lowercase(c.magick); + if result = '' then begin + result:= lowercase(c.magick_filename); + end; + end; + end; + else begin + with pimage32(image)^ do begin + result:= lowercase(c.magick); + if result = '' then begin + result:= lowercase(c.magick_filename); + end; + end; + end; + end; + allocimage(imagebuffer.image,si1,bmk_rgb); + if dispatchimage(image,0,0,si1.cx,si1.cy,'BGRP',charpixel, + imagebuffer.image.pixels,@exceptinf) = magickpass then begin + if hasmask and bo2 then begin + if monomask then begin + allocimage(imagebuffer.mask,si1,bmk_mono); + po1:= imagebuffer.mask.pixels; + for int1:= 0 to si1.cy-1 do begin + if getimagepixels(image,0,int1,si1.cx,1) = nil then begin + result:= ''; + break; + end; + if exportimagepixelarea(image,alphaquantum,1,po1, + nil,nil) = magickfail then begin + result:= ''; + break; + end; + inc(po1,imagebuffer.mask.linebytes); + end; + swapbits(imagebuffer.mask); + end + else begin + allocimage(imagebuffer.mask,si1,bmk_gray); + po1:= imagebuffer.mask.pixels; + for int1:= 0 to si1.cy-1 do begin + if getimagepixels(image,0,int1,si1.cx,1) = nil then begin + result:= ''; + break; + end; + if exportimagepixelarea(image,alphaquantum,8,po1, + nil,nil) = magickfail then begin + result:= ''; + break; + end; + inc(po1,imagebuffer.mask.linebytes); + end; + end; + end; + end + else begin + result:= ''; + end; + end; + if result <> '' then begin + if bo2 then begin + tmaskedbitmap(dest).loadfrommaskedimage(imagebuffer); + end + else begin + tbitmap(dest).loadfromimage(imagebuffer.image); + end; + tbitmap(dest).change; + end; + finally + freeimage(imagebuffer.image); + freeimage(imagebuffer.mask); + destroyimageinfo(imageinfo); + destroyexceptioninfo(@exceptinf); + if image <> nil then begin + destroyimage(image); + end; + end; +end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +var + index: integer = -1; + width: integer = 0; + height: integer = 0; + rotation: extended = 0; + backgroundcolor: colorty = cl_transparent; + density: extended = 0; + options: gmoptionsty = []; + filter: filtertypes = undefinedfilter; + blur: extended = defaultblur; +begin + result:= false; + if dest is tbitmap then begin + matchparams(params, + [index,width,height,rotation,backgroundcolor,density,longword(options), + filter,blur], + [@index,@width,@height,@rotation,@backgroundcolor,@density,@options, + @filter,@blur]); + format:= readgmgraphic(source,tbitmap(dest),index,width,height,rotation, + backgroundcolor,density,options,filter,blur); + result:= format <> ''; + end; +end; + +procedure writegraphic(const dest: tstream; const source: tobject; + const format: string; const params: array of const); +var + quality: integer = -1; + width: integer = 0; + height: integer = 0; + rotation: extended = 0; + backgroundcolor: colorty = cl_transparent; + density: extended = 0; + options: gmoptionsty = []; + filter: filtertypes = undefinedfilter; + blur: extended = defaultblur; +begin + if source is tbitmap then begin + matchparams(params, + [quality,width,height,rotation,backgroundcolor,density, + longword(options),filter,blur], + [@quality,@width,@height,@rotation,@backgroundcolor,@density,@filter,@blur]); + writegmgraphic(dest,tbitmap(source),format,quality,width,height, + rotation,backgroundcolor,density,options,filter,blur); + end; +end; + +procedure registerformats(const labels: array of string; + const filternames: array of msestring; + const filemasks: array of msestringarty); +var + int1: integer; + fname: msestring; + fmask: msestringarty; +begin + checkinit(); + for int1:= 0 to high(labels) do begin + fname:= ''; + fmask:= nil; + if int1 <= high(filternames) then begin + fname:= filternames[int1]; + end; + if int1 <= high(filemasks) then begin + fmask:= filemasks[int1]; + end; + registergraphicformat(labels[int1],@readgraphic,@writegraphic,fname,fmask); + end; +end; + +{ tmagickexception } + +constructor tmagickexception.create(const ainfo: exceptioninfo); +begin + inherited create('GraphicsMagick exception'+lineend+ainfo.reason+lineend+ + ainfo.description); +end; + +initialization +finalization + if inited then begin + releasegraphicsmagick(); + inited:= false; + end; +end. diff --git a/mseide-msegui/lib/common/kernel/kernel_bmp.pas b/mseide-msegui/lib/common/kernel/kernel_bmp.pas new file mode 100644 index 0000000..6af88a7 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/kernel_bmp.pas @@ -0,0 +1,33 @@ +unit kernel_bmp; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_taction: record size: integer; data: array[0..293] of byte end = + (size: 294; data: ( + 84,80,70,48,16,116,98,105,116,109,97,112,99,111,110,116,97,105,110,101, + 114,7,116,97,99,116,105,111,110,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,0,0,0,128,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,216,0,0,0,0,0,0,0, + 0,0,0,0,24,0,0,0,24,0,0,0,164,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,0,255,87,0,0,255,2,255,0,255,20, + 0,0,255,2,255,0,255,19,0,0,255,3,255,0,255,19,0,0,255,2, + 255,0,255,20,0,0,255,2,255,0,255,23,0,0,255,2,255,0,255,24, + 0,0,255,2,255,0,255,24,0,0,255,2,255,0,255,24,0,0,255,2, + 255,0,255,21,0,0,255,2,255,0,255,21,0,0,255,1,255,0,255,17, + 0,0,255,1,255,0,255,3,0,0,255,2,255,0,255,18,0,0,255,1, + 255,0,255,2,0,0,255,1,255,0,255,19,0,0,255,1,255,0,255,1, + 0,0,255,2,255,0,255,20,0,0,255,2,255,0,255,1,0,0,255,3, + 255,0,255,18,0,0,255,3,255,0,255,137,0,0) + ); + +initialization + registerobjectdata(@objdata_taction,tbitmapcontainer,'taction'); +end. diff --git a/mseide-msegui/lib/common/kernel/linux/cwstring.pas b/mseide-msegui/lib/common/kernel/linux/cwstring.pas new file mode 100644 index 0000000..b6a2c2a --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/cwstring.pas @@ -0,0 +1,641 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2005 by Florian Klaempfl, + member of the Free Pascal development team. + + libc based wide string support + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + 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. + **********************************************************************} +{$ifdef FPC}{$mode objfpc}{$endif} + +{$define unicodeversion} +{$if fpc_fullversion >= 30000} + {$define mse_fpc_3} +{$endif} +{$if fpc_fullversion >= 30001} + {$define hascompareoptions} +{$endif} +unit cwstring; +{$ifndef FPC} +interface //dummy +implementation + +{$else} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msetypes,sysutils,msesetlocale,mselibc{$ifdef mse_fpc_3},unixcp{$endif}; +type + eiconv = class(econverterror) + end; + +procedure SetCWidestringManager(); + +implementation +{$ifdef FPC}{$linklib c}{$endif} + +{$ifndef linux} // Linux (and maybe glibc platforms in general), have iconv in glibc. + {$ifndef FreeBSD5} + {$linklib iconv} + {$define useiconv} + {$endif} +{$endif linux} +Uses +// BaseUnix, + msectypes,{$ifndef FPC}msetypes,{$endif} +// unix, +// unixtype, +// sysutils, +// initc, + {msedatalist,}msesysintf1,msesysintf,msestrings; + +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +Const +{$ifdef useiconv} + libiconvname='iconv'; +{$else} + libiconvname='c'; // is in libc under Linux. +{$endif} + +{$if defined(darwin) or defined(freebsd) and not defined(freebsd5)} + prefix = 'lib'; +{$else} + prefix = ''; +{$endif} + +{ Case-mapping "arrays" } +//var +// AnsiUpperChars: AnsiString; // 1..255 +// AnsiLowerChars: AnsiString; // 1..255 +// WideUpperChars: WideString; // 1..65535 +// WideLowerChars: WideString; // 1..65535 + +{ the following declarations are from the libc unit for linux so they + might be very linux centric + maybe this needs to be splitted in an os depend way later } +function towlower(__wc:wint_t):wint_t;cdecl;external libiconvname name 'towlower'; +function towupper(__wc:wint_t):wint_t;cdecl;external libiconvname name 'towupper'; +function wcscoll (__s1:pwchar_t; __s2:pwchar_t):cint;cdecl;external libiconvname name 'wcscoll'; +function strcoll (__s1:pchar; __s2:pchar):cint;cdecl;external libiconvname name 'strcoll'; + +const +//{$ifdef linux} +// __LC_CTYPE = 0; +// _NL_CTYPE_CLASS = (__LC_CTYPE shl 16); +// _NL_CTYPE_CODESET_NAME = (_NL_CTYPE_CLASS)+14; +// CODESET = _NL_CTYPE_CODESET_NAME; +//{$else linux} +//{$ifdef darwin} +// CODESET = 0; +//{$else darwin} +//{$ifdef FreeBSD} // actually FreeBSD5. internationalisation is afaik not default on 4. +// CODESET = 0; +//{$else freebsd} +//{$ifdef solaris} +// CODESET=49; +//{$else} +//{$error lookup the value of CODESET in /usr/include/langinfo.h for your OS } +// and while doing it, check if iconv is in libc, and if the symbols are prefixed with iconv_ or libiconv_ +//{$endif solaris} +//{$endif FreeBSD} +//{$endif darwin} +//{$endif linux} + +{ unicode encoding name } +{$ifdef FPC_LITTLE_ENDIAN} + unicode_encoding = 'UNICODELITTLE'; +{$else FPC_LITTLE_ENDIAN} + unicode_encoding = 'UNICODEBIG'; +{$endif FPC_LITTLE_ENDIAN} + +type + + piconv_t = ^iconv_t; + iconv_t = pointer; + nl_item = cint; + +function nl_langinfo(__item:nl_item):pchar cdecl + external libiconvname name 'nl_langinfo'; +function iconv_open(__tocode: pchar; __fromcode: pchar): iconv_t cdecl + external libiconvname name prefix+'iconv_open'; +function iconv(__cd: iconv_t; __inbuf: ppchar; __inbytesleft: psize_t; + __outbuf: ppchar; __outbytesleft: psize_t): size_t cdecl + external libiconvname name prefix+'iconv'; +function iconv_close(__cd: iconv_t): cint cdecl + external libiconvname name prefix+'iconv_close'; + +var +// iconv_ansi2ucs4, +// iconv_ucs42ansi, + iconv_ansi2wide, + iconv_wide2ansi : iconv_t; + +// lock_ansi2ucs4 : integer = -1; +// lock_ucs42ansi : integer = -1; + lock_ansi2wide : integer = -1; + lock_wide2ansi : integer = -1; + +procedure lockiconv(var lockcount: integer); +begin + while interlockedincrement(lockcount) <> 0 do begin + interlockeddecrement(lockcount); + sys_threadschedyield; + end; +end; + +procedure unlockiconv(var lockcount: integer); +begin + interlockeddecrement(lockcount); +end; + +{$ifdef mse_fpc_3} +Type + PAnsiRec = ^TAnsiRec; + TAnsiRec = Record + CodePage : TSystemCodePage; + ElementSize : Word; +{$ifdef CPU64} + { align fields } + Dummy : DWord; +{$endif CPU64} + Ref : SizeInt; + Len : SizeInt; + end; + +procedure Wide2AnsiMove(source:pwidechar;var dest:RawByteString; + cp : TSystemCodePage; len:SizeInt); + //todo: convert codepages +{$else} +procedure Wide2AnsiMove(source:pwidechar; var dest:ansistring; len:SizeInt); +{$endif} + var + outlength, + outoffset, + srclen, + outleft : size_t; + srcpos : pwidechar; + destpos: pchar; + mynil : pchar; + my0 : size_t; + begin +{$ifdef mse_fpc_3} + if (cp = cp_utf8) or (cp = cp_acp) and + (DefaultSystemCodePage = cp_utf8) then begin + dest:= stringtoutf8(source,len); + end + else begin +{$endif} + mynil:=nil; + my0:=0; + { rought estimation } + setlength(dest,len*3); + outlength:=len*3; + srclen:=len*2; + srcpos:=source; + destpos:=pchar(dest); + outleft:=outlength; + lockiconv(lock_wide2ansi); + while iconv(iconv_wide2ansi,@srcpos,@srclen,@destpos,@outleft)=size_t(-1) do + begin + case __errno_location()^ of +// case fpgetCerrno of + EILSEQ: + begin + { skip and set to '?' } + inc(srcpos); + dec(srclen,2); + destpos^:='?'; + inc(destpos); + dec(outleft); + { reset } + iconv(iconv_wide2ansi,@mynil,@my0,@mynil,@my0); + end; + E2BIG: + begin + outoffset:=destpos-pchar(dest); + { extend } + setlength(dest,outlength+len*3); + inc(outleft,len*3); + inc(outlength,len*3); + { string could have been moved } + destpos:=pchar(dest)+outoffset; + end; + else + begin + unlockiconv(lock_wide2ansi); + raise eiconv.Create('iconv error '+ + IntToStr(sys_getlasterror{fpgetCerrno})); + end; + end; + end; + unlockiconv(lock_wide2ansi); + // truncate string + setlength(dest,length(dest)-outleft); + {$ifdef mse_fpc_3} + pansirec(pointer(dest)-sizeof(tansirec))^.codepage:= cp; + {$endif} +{$ifdef mse_fpc_3} + end; +{$endif} +end; + +{$ifdef mse_fpc_3} +procedure Ansi2WideMove(source:pchar;cp : TSystemCodePage; + var dest:widestring;len:SizeInt); + //todo: codepages +{$else} +procedure Ansi2WideMove(source:pchar;var dest:widestring;len:SizeInt); +{$endif} + var + outlength, + outoffset, + outleft : size_t; + srcpos, + destpos: pchar; + mynil : pchar; + my0 : size_t; + begin +{$ifdef mse_fpc_3} + if (cp = cp_utf8) or (cp = cp_acp) and + (DefaultSystemCodePage = cp_utf8) then begin + dest:= utf8tostring(source,len); + end + else begin +{$endif} + mynil:=nil; + my0:=0; + // extra space + outlength:=len+1; + setlength(dest,outlength); + outlength:=len+1; + srcpos:=source; + destpos:=pchar(dest); + outleft:=outlength*2; + lockiconv(lock_ansi2wide); + while iconv(iconv_ansi2wide,@srcpos,@len,@destpos,@outleft)=size_t(-1) do + begin +// case fpgetCerrno of + case __errno_location()^ of + EILSEQ: + begin + { skip and set to '?' } + inc(srcpos); + dec(len); + pwidechar(destpos)^:='?'; + inc(destpos,2); + dec(outleft,2); + { reset } + iconv(iconv_ansi2wide,@mynil,@my0,@mynil,@my0); + end; + E2BIG: + begin + outoffset:=destpos-pchar(dest); + { extend } + setlength(dest,outlength+len); + inc(outleft,len*2); + inc(outlength,len); + { string could have been moved } + destpos:=pchar(dest)+outoffset; + end; + else + begin + unlockiconv(lock_ansi2wide); + raise eiconv.Create('iconv error '+ + IntToStr(sys_getlasterror{fpgetCerrno})); + end; + end; + end; + unlockiconv(lock_ansi2wide); + // truncate string + setlength(dest,length(dest)-outleft div 2); +{$ifdef mse_fpc_3} + end; +{$endif} +end; + + +function lowerwidestring(const s : widestring) : widestring; +var + i1: int32; + ps,pd,pe: pmsechar; +begin + i1:= length(s); + setlength(result,i1); + ps:= pointer(s); + pd:= pointer(result); + pe:= pd + i1; + while pd < pe do begin + pd^:= widechar(towlower(wint_t(ps^))); + inc(ps); + inc(pd); + end; +end; + +function upperwidestring(const s : widestring) : widestring; +var + i1: int32; + ps,pd,pe: pmsechar; +begin + i1:= length(s); + setlength(result,i1); + ps:= pointer(s); + pd:= pointer(result); + pe:= pd + i1; + while pd < pe do begin + pd^:= widechar(towupper(wint_t(ps^))); + inc(ps); + inc(pd); + end; +end; + +function CompareTextWideString(const s1, s2 : WideString): PtrInt; +var //no surrogate pair handling, no decomposition handling + w1,w2: array[0..1] of ucs4char; + int1: integer; + max: integer; + pa,pb,pe: pmsechar; +begin + result:= 0; + if pointer(s1) <> pointer(s2) then begin + if s1 = '' then begin + result:= -1; + end + else begin + if s2 = '' then begin + result:= 1; + end + else begin + pa:= pointer(s1); + pb:= pointer(s2); + max:= length(s1); + int1:= length(s2); + if max > int1 then begin + max:= int1; + end; + pe:= pa + max; + while pa <= pe do begin //including terminating #0 + if pa^ <> pb^ then begin + w1[0]:= towupper(wint_t(word(pa^))); + w2[0]:= towupper(wint_t(word(pb^))); + if w1[0] <> w2[0] then begin + w1[1]:= 0; + w2[1]:= 0; + result:= wcscoll(pwchar_t(@w1),pwchar_t(@w2)); + break; + end; + end; + inc(pa); + inc(pb); + end; + end; + end; + end; +end; + +function CompareWideString(const s1, s2 : WideString + {$ifdef hascompareoptions};Options : TCompareOptions{$endif}): PtrInt; +var //no surrogate pair handling, no decomposition handling + w1,w2: array[0..1] of ucs4char; + int1: integer; + max: integer; + pa,pb,pe: pmsechar; +begin +{$ifdef hascompareoptions} + if (coignorecase in options) then begin + result:= comparetextwidestring(s1,s2); + exit; + end; +{$endif} + result:= 0; + if pointer(s1) <> pointer(s2) then begin + if s1 = '' then begin + result:= -1; + end + else begin + if s2 = '' then begin + result:= 1; + end + else begin + pa:= pointer(s1); + pb:= pointer(s2); + max:= length(s1); + int1:= length(s2); + if max > int1 then begin + max:= int1; + end; + pe:= pa + max; + while pa <= pe do begin //including terminating #0 + if pa^ <> pb^ then begin + w1[0]:= ord(pa^); + w1[1]:= 0; + w2[0]:= ord(pb^); + w2[1]:= 0; + result:= wcscoll(pwchar_t(@w1),pwchar_t(@w2)); + break; + end; + inc(pa); + inc(pb); + end; + end; + end; + end; +end; + +function StrCompAnsi(s1,s2 : PChar): PtrInt; + begin + result:=strcoll(s1,s2); + end; + +{$ifdef mse_fpc_3} +//copied from fpc rtl +{$ifdef FPC_HAS_CPSTRING} + +function envvarset(const varname: pchar): boolean; +var + varval: pchar; +begin + varval:= getenv(varname); + result:= + assigned(varval) and + (varval[0]<>#0); +end; + +function GetStandardCodePage( + const stdcp: TStandardCodePageEnum): TSystemCodePage; +var + langinfo: pchar; +begin +{$ifdef FPCRTL_FILESYSTEM_UTF8} + if stdcp=scpFileSystemSingleByte then + begin + result:=CP_UTF8; + exit; + end; +{$endif} + { if none of the relevant LC_* environment variables are set, fall back to + UTF-8 (this happens under some versions of OS X for GUI applications, which + otherwise get CP_ASCII) } + if envvarset('LC_ALL') or + envvarset('LC_CTYPE') or + envvarset('LANG') then + begin + langinfo:=nl_langinfo(CODESET); + { there's a bug in the Mac OS X 10.5 libc (based on FreeBSD's) + that causes it to return an empty string of UTF-8 locales + -> patch up (and in general, UTF-8 is a good default on + Unix platforms) } + if not assigned(langinfo) or + (langinfo^=#0) then + langinfo:='UTF-8'; + Result:= GetCodepageByName(ansistring(langinfo)); + end + else + Result:=unixcp.GetSystemCodepage; +end; + +procedure SetStdIOCodePage(var T: Text); inline; +begin + case TextRec(T).Mode of + fmInput:TextRec(T).CodePage:=GetStandardCodePage(scpConsoleInput); + fmOutput:TextRec(T).CodePage:=GetStandardCodePage(scpConsoleOutput); + end; +end; + +procedure SetStdIOCodePages; inline; +begin + SetStdIOCodePage(system.Input); + SetStdIOCodePage(system.Output); + SetStdIOCodePage(system.ErrOutput); + SetStdIOCodePage(system.StdOut); + SetStdIOCodePage(system.StdErr); +end; +{$endif FPC_HAS_CPSTRING} + +{$endif} + +var +{$ifdef unicodeversion} + widestringmanagerbefore : TUnicodeStringManager; +{$else} + widestringmanagerbefore : TWideStringManager; +{$endif} + +Procedure SetCWideStringManager; +Var +{$ifdef unicodeversion} + CWideStringManager : TUnicodeStringManager; +{$else} + CWideStringManager : TWideStringManager; +{$endif} +begin + widestringmanagerbefore:= widestringmanager; + CWideStringManager:= widestringmanager; + With CWideStringManager do begin + Wide2AnsiMoveProc:= @Wide2AnsiMove; + Ansi2WideMoveProc:= @Ansi2WideMove; + + UpperWideStringProc:= @UpperWideString; + LowerWideStringProc:= @LowerWideString; + + CompareWideStringProc:= @CompareWideString; + {$ifndef hascompareoptions} + CompareTextWideStringProc:= @CompareTextWideString; + {$endif} +{$ifdef unicodeversion} + Unicode2AnsiMoveProc:= @Wide2AnsiMove; + Ansi2UnicodeMoveProc:= @Ansi2WideMove; + + UpperUnicodeStringProc:= @UpperWideString; + LowerUnicodeStringProc:= @LowerWideString; + + CompareUnicodeStringProc:= @CompareWideString; + {$ifndef hascompareoptions} + CompareTextUnicodeStringProc:= @CompareTextWideString; + {$endif} +{$endif} + { + CharLengthPCharProc + + UpperAnsiStringProc + LowerAnsiStringProc + CompareStrAnsiStringProc + CompareTextAnsiStringProc + } + StrCompAnsiStringProc:=@StrCompAnsi; + { + StrICompAnsiStringProc + StrLCompAnsiStringProc + StrLICompAnsiStringProc + StrLowerAnsiStringProc + StrUpperAnsiStringProc + } + {$ifdef mse_fpc_3} + GetStandardCodePageProc:=@GetStandardCodePage; + {$endif} + end; + SetWideStringManager(CWideStringManager); +end; + +procedure unSetCWidestringManager(); +begin + widestringmanager:= widestringmanagerbefore; +end; + +initialization + setlocale(LC_ALL,''); + { init conversion tables } + +{$ifdef mse_fpc_3} + { set the DefaultSystemCodePage } + DefaultSystemCodePage:=GetStandardCodePage(scpAnsi); + DefaultFileSystemCodePage:=GetStandardCodePage(scpFileSystemSingleByte); + DefaultRTLFileSystemCodePage:=DefaultFileSystemCodePage; + + {$ifdef FPC_HAS_CPSTRING} + SetStdIOCodePages; + {$endif FPC_HAS_CPSTRING} +{$endif} + + iconv_wide2ansi:=iconv_open(nl_langinfo(CODESET),unicode_encoding); + iconv_ansi2wide:=iconv_open(unicode_encoding,nl_langinfo(CODESET)); +// iconv_ucs42ansi:=iconv_open(nl_langinfo(CODESET),'UCS4'); +// iconv_ansi2ucs4:=iconv_open('UCS4',nl_langinfo(CODESET)); + SetCWideStringManager(); + +finalization + unSetCWideStringManager(); + if iconv_wide2ansi <> nil then begin + iconv_close(iconv_wide2ansi); + end; + if iconv_ansi2wide <> nil then begin + iconv_close(iconv_ansi2wide); + end; +// iconv_close(iconv_ucs42ansi); +// if iconv_ansi2ucs4 <> nil then begin +// iconv_close(iconv_ansi2ucs4); +// end; +{$endif} +end. diff --git a/mseide-msegui/lib/common/kernel/linux/ice.pas b/mseide-msegui/lib/common/kernel/linux/ice.pas new file mode 100644 index 0000000..545f4e5 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/ice.pas @@ -0,0 +1,148 @@ + +unit ice; +interface +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +{$IFDEF FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$ENDIF} + + + { $Xorg: ICE.h,v 1.4 2001/02/09 02:03:26 xorgcvs Exp $ } + {***************************************************************************** + + + Copyright 1993, 1998 The Open Group + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of The Open Group shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from The Open Group. + + Author: Ralph Mor, X Consortium + + ***************************************************************************** } + { + * Protocol Version + } + + const + IceProtoMajor = 1; + IceProtoMinor = 0; + { + * Byte Order + } + IceLSBfirst = 0; + IceMSBfirst = 1; + { + * ICE minor opcodes + } + ICE_Error = 0; + ICE_ByteOrder = 1; + ICE_ConnectionSetup = 2; + ICE_AuthRequired = 3; + ICE_AuthReply = 4; + ICE_AuthNextPhase = 5; + ICE_ConnectionReply = 6; + ICE_ProtocolSetup = 7; + ICE_ProtocolReply = 8; + ICE_Ping = 9; + ICE_PingReply = 10; + ICE_WantToClose = 11; + ICE_NoClose = 12; + { + * Error severity + } + IceCanContinue = 0; + IceFatalToProtocol = 1; + IceFatalToConnection = 2; + { + * ICE error classes that are common to all protocols + } + IceBadMinor = $8000; + IceBadState = $8001; + IceBadLength = $8002; + IceBadValue = $8003; + { + * ICE error classes that are specific to the ICE protocol + } + IceBadMajor = 0; + IceNoAuth = 1; + IceNoVersion = 2; + IceSetupFailed = 3; + IceAuthRejected = 4; + IceAuthFailed = 5; + IceProtocolDuplicate = 6; + IceMajorOpcodeDuplicate = 7; + IceUnknownProtocol = 8; + { _ICE_H_ } + +type + Bool = integer;{longbool}//protocoll does not accept -1 for true + IcePointer = pointer; + IceConn = pointer; + Status = integer; + IceProcessMessagesStatus = (IceProcessMessagesSuccess,IceProcessMessagesIOError, + IceProcessMessagesConnectionClosed); + + IceReplyWaitInfo = record + sequence_of_request: longword; + major_opcode_of_request: integer; + minor_opcode_of_request: integer; + reply: IcePointer; + end; + pIceReplyWaitInfo = ^IceReplyWaitInfo; + + IceWatchProc = procedure(_iceConn: IceConn; clientData: IcePointer; + opening: Bool; var watchData: IcePointer); cdecl; + +var + IceConnectionNumber: function (_iceConn: IceConn): integer; cdecl; + IceAddConnectionWatch: function(watchProc: IceWatchProc; + clientData: IcePointer): Status; cdecl; + IceRemoveConnectionWatch: procedure(watchProc: IceWatchProc; + clientData: IcePointer); cdecl; + IceProcessMessages: function(_iceConn: IceConn; replyWait: pIceReplyWaitInfo; + var replyReadyRet: bool): IceProcessMessagesStatus; cdecl; +function geticelib: boolean; + +implementation +uses + msesys,msesonames,msedynload; + +function geticelib: boolean; +begin + result:= checkprocaddresses(icenames, + [ + 'IceConnectionNumber', //0 + 'IceAddConnectionWatch', //1 + 'IceRemoveConnectionWatch', //2 + 'IceProcessMessages' //3 + ], + [ + {$ifndef FPC}@{$endif}@IceConnectionNumber, //0 + {$ifndef FPC}@{$endif}@IceAddConnectionWatch, //1 + {$ifndef FPC}@{$endif}@IceRemoveConnectionWatch,//2 + {$ifndef FPC}@{$endif}@IceProcessMessages //3 + ]); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mseguiintf.pas b/mseide-msegui/lib/common/kernel/linux/mseguiintf.pas new file mode 100644 index 0000000..52fb1ed --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mseguiintf.pas @@ -0,0 +1,7148 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseguiintf; //X11 + +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifdef mse_debugwindowfocus} + {$define mse_debug} +{$endif} +{$ifdef mse_debugconfigure} + {$define mse_debug} +{$endif} +{$ifdef mse_debugshow} + {$define mse_debug} +{$endif} +uses + {$ifdef FPC}xlib{$else}Xlib{$endif},msetypes,mseapplication,msesys, + msegraphutils,mseevent,msepointer,mseguiglob,msesystypes,{msestockobjects,} + msethread{$ifdef FPC},x,xutil,dynlibs{$endif}, + mselibc,msectypes,msesysintf,msegraphics, + msestrings,mxft,mxrender,mxrandr; + +{$ifdef FPC} + {$define xbooleanresult} + {$if defined(FPC) and (fpc_fullversion < 020300)} + {$define xboolean} + {$ifend} + {$ifdef UNIX} + {$ifdef msedebug} +var + _IO_stdin: P_IO_FILE; cvar; + //avoid link errors if rtl is compiled with stabs info + _IO_stdout: P_IO_FILE; cvar; + _IO_stderr: P_IO_FILE; cvar; + __malloc_initialized : longint;cvar; + h_errno : longint;cvar; + {$endif} + {$endif} +{$endif} + +{ $define smdebug} + +{$include ../mseguiintf.inc} + +{$define with_sm} + +{$ifndef with_sm} + { $define with_saveyourself} +{$endif} +type +{$ifndef FPC} + txevent = xevent; +{$endif} + + x11internalwindowoptionsdty = record + depth: cint; + visual: pvisual; + colormap: tcolormap; + end; + {$if sizeof(x11internalwindowoptionsdty) > sizeof(internalwindowoptionspty)} + {$error 'buffer overflow'} + {$ifend} + x11internalwindowoptionsty = record + case integer of + 0: (d: x11internalwindowoptionsdty;); + 1: (_bufferspace: internalwindowoptionspty;); + end; + + {$if sizeof(x11internalwindowoptionsdty) > sizeof(internalwindowoptionspty)} + {$error 'buffer overflow'} + {$ifend} + + syseventty = type txevent; +const + //from keysymdef.h + XK_BackSpace = $FF08; //* back space, back char */ + XK_Tab = $FF09; + XK_Linefeed = $FF0A; //* Linefeed, LF */ + XK_Clear = $FF0B; + XK_Return = $FF0D; //* Return, enter */ + XK_Pause = $FF13; //* Pause, hold */ + XK_Scroll_Lock = $FF14; + XK_Sys_Req = $FF15; + XK_Escape = $FF1B; + XK_Delete = $FFFF; //* Delete, rubout */ + +//* Cursor control & motion */ + XK_Home = $FF50; + XK_Left = $FF51; //* Move left, left arrow */ + XK_Up = $FF52; //* Move up, up arrow */ + XK_Right = $FF53; //* Move right, right arrow */ + XK_Down = $FF54; //* Move down, down arrow */ + XK_Prior = $FF55; //* Prior, previous */ + XK_Page_Up = $FF55; + XK_Next = $FF56; //* Next */ + XK_Page_Down = $FF56; + XK_End = $FF57; //* EOL */ + XK_Begin = $FF58; //* BOL */ + +//* Misc Functions */ + XK_Select = $FF60; //* Select, mark */ + XK_Print = $FF61; + XK_Execute = $FF62; //* Execute, run, do */ + XK_Insert = $FF63; //* Insert, insert here */ + XK_Undo = $FF65; //* Undo, oops */ + XK_Redo = $FF66; //* redo, again */ + XK_Menu = $FF67; + XK_Find = $FF68; //* Find, search */ + XK_Cancel = $FF69; //* Cancel, stop, abort, exit */ + XK_Help = $FF6A; //* Help */ + XK_Break = $FF6B; + XK_Mode_switch = $FF7E; //* Character set switch */ + XK_script_switch = $FF7E; //* Alias for mode_switch */ + XK_Num_Lock = $FF7F; + +//* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ + XK_KP_Space = $FF80; //* space */ + XK_KP_Tab = $FF89; + XK_KP_Enter = $FF8D; //* enter */ + XK_KP_F1 = $FF91; //* PF1, KP_A, ... */ + XK_KP_F2 = $FF92; + XK_KP_F3 = $FF93; + XK_KP_F4 = $FF94; + XK_KP_Home = $FF95; + XK_KP_Left = $FF96; + XK_KP_Up = $FF97; + XK_KP_Right = $FF98; + XK_KP_Down = $FF99; + XK_KP_Prior = $FF9A; + XK_KP_Page_Up = $FF9A; + XK_KP_Next = $FF9B; + XK_KP_Page_Down = $FF9B; + XK_KP_End = $FF9C; + XK_KP_Begin = $FF9D; + XK_KP_Insert = $FF9E; + XK_KP_Delete = $FF9F; + XK_KP_Equal = $FFBD; //* equals */ + XK_KP_Multiply = $FFAA; + XK_KP_Add = $FFAB; + XK_KP_Separator = $FFAC; //* separator, often comma */ + XK_KP_Subtract = $FFAD; + XK_KP_Decimal = $FFAE; + XK_KP_Divide = $FFAF; + + XK_KP_0 = $FFB0; + XK_KP_1 = $FFB1; + XK_KP_2 = $FFB2; + XK_KP_3 = $FFB3; + XK_KP_4 = $FFB4; + XK_KP_5 = $FFB5; + XK_KP_6 = $FFB6; + XK_KP_7 = $FFB7; + XK_KP_8 = $FFB8; + XK_KP_9 = $FFB9; + + XK_F1 = $FFBE; + XK_F35 = $FFE0; + +//* Modifiers */ + XK_Shift_L = $FFE1; //* Left shift */ + XK_Shift_R = $FFE2; //* Right shift */ + XK_Control_L = $FFE3; //* Left control */ + XK_Control_R = $FFE4; //* Right control */ + XK_Caps_Lock = $FFE5; //* Caps lock */ + XK_Shift_Lock = $FFE6; //* Shift lock */ + + XK_Meta_L = $FFE7; //* Left meta */ + XK_Meta_R = $FFE8; //* Right meta */ + XK_Alt_L = $FFE9; //* Left alt */ + XK_Alt_R = $FFEA; //* Right alt */ + XK_Super_L = $FFEB; //* Left super */ + XK_Super_R = $FFEC; //* Right super */ + XK_Hyper_L = $FFED; //* Left hyper */ + XK_Hyper_R = $FFEE; //* Right hyper */ + + //ISO 9995 Function and Modifier Keys + //Byte 3 = 0xFE + + XK_ISO_Lock = $FE01; + XK_ISO_Level2_Latch = $FE02; + XK_ISO_Level3_Shift = $FE03; + XK_ISO_Level3_Latch = $FE04; + XK_ISO_Level3_Lock = $FE05; + XK_ISO_Level5_Shift = $FE11; + XK_ISO_Level5_Latch = $FE12; + XK_ISO_Level5_Lock = $FE13; + XK_ISO_Group_Shift = $FF7E; + XK_ISO_Group_Latch = $FE06; + XK_ISO_Group_Lock = $FE07; + XK_ISO_Next_Group = $FE08; + XK_ISO_Next_Group_Lock = $FE09; + XK_ISO_Prev_Group = $FE0A; + XK_ISO_Prev_Group_Lock = $FE0B; + XK_ISO_First_Group = $FE0C; + XK_ISO_First_Group_Lock = $FE0D; + XK_ISO_Last_Group = $FE0E; + XK_ISO_Last_Group_Lock = $FE0F; + + XK_ISO_Left_Tab = $FE20; + XK_ISO_Move_Line_Up = $FE21; + XK_ISO_Move_Line_Down = $FE22; + XK_ISO_Partial_Line_Up = $FE23; + XK_ISO_Partial_Line_Down = $FE24; + XK_ISO_Partial_Space_Left = $FE25; + XK_ISO_Partial_Space_Right = $FE26; + XK_ISO_Set_Margin_Left = $FE27; + XK_ISO_Set_Margin_Right = $FE28; + XK_ISO_Release_Margin_Left = $FE29; + XK_ISO_Release_Margin_Right = $FE2A; + XK_ISO_Release_Both_Margins = $FE2B; + XK_ISO_Fast_Cursor_Left = $FE2C; + XK_ISO_Fast_Cursor_Right = $FE2D; + XK_ISO_Fast_Cursor_Up = $FE2E; + XK_ISO_Fast_Cursor_Down = $FE2F; + XK_ISO_Continuous_Underline = $FE30; + XK_ISO_Discontinuous_Underline = $FE31; + XK_ISO_Emphasize = $FE32; + XK_ISO_Center_Object = $FE33; + XK_ISO_Enter = $FE34; + + //from cursorfont.h + XC_num_glyphs = 154; + XC_X_cursor = 0; + XC_arrow = 2; + XC_based_arrow_down = 4; + XC_based_arrow_up = 6; + XC_boat = 8; + XC_bogosity = 10; + XC_bottom_left_corner = 12; + XC_bottom_right_corner = 14; + XC_bottom_side = 16; + XC_bottom_tee = 18; + XC_box_spiral = 20; + XC_center_ptr = 22; + XC_circle = 24; + XC_clock = 26; + XC_coffee_mug = 28; + XC_cross = 30; + XC_cross_reverse = 32; + XC_crosshair = 34; + XC_diamond_cross = 36; + XC_dot = 38; + XC_dotbox = 40; + XC_double_arrow = 42; + XC_draft_large = 44; + XC_draft_small = 46; + XC_draped_box = 48; + XC_exchange = 50; + XC_fleur = 52; + XC_gobbler = 54; + XC_gumby = 56; + XC_hand1 = 58; + XC_hand2 = 60; + XC_heart = 62; + XC_icon = 64; + XC_iron_cross = 66; + XC_left_ptr = 68; + XC_left_side = 70; + XC_left_tee = 72; + XC_leftbutton = 74; + XC_ll_angle = 76; + XC_lr_angle = 78; + XC_man = 80; + XC_middlebutton = 82; + XC_mouse = 84; + XC_pencil = 86; + XC_pirate = 88; + XC_plus = 90; + XC_question_arrow = 92; + XC_right_ptr = 94; + XC_right_side = 96; + XC_right_tee = 98; + XC_rightbutton = 100; + XC_rtl_logo = 102; + XC_sailboat = 104; + XC_sb_down_arrow = 106; + XC_sb_h_double_arrow = 108; + XC_sb_left_arrow = 110; + XC_sb_right_arrow = 112; + XC_sb_up_arrow = 114; + XC_sb_v_double_arrow = 116; + XC_shuttle = 118; + XC_sizing = 120; + XC_spider = 122; + XC_spraycan = 124; + XC_star = 126; + XC_target = 128; + XC_tcross = 130; + XC_top_left_arrow = 132; + XC_top_left_corner = 134; + XC_top_right_corner = 136; + XC_top_side = 138; + XC_top_tee = 140; + XC_trek = 142; + XC_ul_angle = 144; + XC_umbrella = 146; + XC_ur_angle = 148; + XC_watch = 150; + XC_xterm = 152; + + {$ifdef FPC} +// threadslib = 'pthread'; + Xlibmodulename = 'X11'; + {$endif} + sXlib = Xlibmodulename; + pixel0 = $000000; + pixel1 = $ffffff; +type + Bool = cint; + XID = type culong; +// TXICCEncodingStyle = (XStringStyle,XCompoundTextStyle,XTextStyle, +// XStdICCTextStyle,XUTF8StringStyle); +{$ifdef FPC} + Colormap = TXID; + Atom = type culong; +// Atom = type longword; + Cursor = TXID; + ppwchar_t = ^pwchar_t; +{$endif} + wchar_t = longword; + pwchar_t = ^wchar_t; + patom = ^atom; + atomarty = array of atom; + atomaty = array[0..0] of atom; + patomaty = ^atomaty; + ulongarty = array of culong; + +function msedisplay: pdisplay; +function msevisual: pvisual; +//function mserootwindow(id: winidty = 0): winidty; +function msedefaultscreen: pscreen; +function msedefaultscreenno: integer; + +{$ifdef FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} + +type + _XIM = record end; + XIM = ^_XIM; + _XIC = record end; + XIC = ^_XIC; + ppucs4char = ^pucs4char; + dword = longword; + + VisualID = culong; + Visual = record + ext_data: PXExtData; { hook for extension to hang data } + visualid: VisualID; { visual id of this visual } + _class: cint; + red_mask: culong; + green_mask: culong; + blue_mask: culong; + bits_per_rgb: cint; + map_entries: cint; + end; + msepvisual = ^visual; + +(* + VisualID = dword; + Visual = record + ext_data: PXExtData; { hook for extension to hang data } + visualid: VisualID; { visual id of this visual } + _class: Longint; + red_mask: longword; + green_mask: longword; + blue_mask: longword; + bits_per_rgb: Longint; + map_entries: Longint; + end; + msepvisual = ^visual; +*) + PXWMHints = ^XWMHints; + XWMHints = record + flags: clong; { marks which fields in this structure are defined } + input: Bool; { does this application rely on the window manager to get keyboard input? } + initial_state: Longint; { see below } + icon_pixmap: xid; { pixmap to be used as icon } + icon_window: xid; { window to be used as icon } + icon_x: cint; { initial position of icon } + icon_y: cint; + icon_mask: xid; { icon mask bitmap } + window_group: XID; { id of related window group } + { this structure may be extended in the future } + end; + +{ definition for flags of XWMHints } +const + InputHint = 1 shl 0; + StateHint = 1 shl 1; + IconPixmapHint = 1 shl 2; + IconWindowHint = 1 shl 3; + IconPositionHint = 1 shl 4; + IconMaskHint = 1 shl 5; + WindowGroupHint = 1 shl 6; + AllHints = (((((InputHint or StateHint) or IconPixmapHint) or IconWindowHint) + or IconPositionHint) or IconMaskHint) or WindowGroupHint; + XUrgencyHint = 1 shl 8; + +type + MwmHints = record + flags: culong; + functions: culong; + decorations: culong; + input_mode: clong; + status: culong + end; + +const + MWM_HINTS_FUNCTIONS = 1 shl 0; + MWM_HINTS_DECORATIONS = 1 shl 1; + + MWM_FUNC_ALL = 1 shl 0; + MWM_FUNC_RESIZE = 1 shl 1; + MWM_FUNC_MOVE = 1 shl 2; + MWM_FUNC_MINIMIZE = 1 shl 3; + MWM_FUNC_MAXIMIZE = 1 shl 4; + MWM_FUNC_CLOSE = 1 shl 5; +{ +type + TXICCEncodingStyle = (XStringStyle,XCompoundTextStyle,XTextStyle, + XStdICCTextStyle,XUTF8StringStyle); + } +function XSetWMHints(Display: PDisplay; W: xid; WMHints: PXWMHints): cint; cdecl; + external sXLib name 'XSetWMHints'; +function XSetForeground(Display: PDisplay; GC: TGC; + Foreground: culong): cint; cdecl; external sXLib name 'XSetForeground'; + //bug in borland Xlib.pas +procedure XDrawImageString(Display: PDisplay; D: TDrawable; GC: TGC; + X, Y: Integer; S: PChar; Len: Integer); cdecl; + external sXLib name 'XDrawImageString'; +procedure XDrawImageString16(Display: PDisplay; D: TDrawable; GC: TGC; + X, Y: Integer; S: Pxchar2b; Len: Integer); cdecl; + external sXLib name 'XDrawImageString16'; +procedure XDrawString16(Display: PDisplay; D: TDrawable; GC: TGC; + X, Y: Integer; S: Pxchar2b; Len: Integer); cdecl; + external sXLib name 'XDrawString16'; +function XOpenIM(Display: PDisplay; rdb: PXrmHashBucketRec; + res_name: pchar; res_class: pchar): XIM; cdecl; + external sXLib name 'XOpenIM'; +function XCloseIM(IM: XIM): TStatus; cdecl; + external sXLib name 'XCloseIM'; +function XCreateIC(IM: XIM): XIC; cdecl; varargs; + external sXLib name 'XCreateIC'; +procedure XDestroyIC(IC: XIC); cdecl; + external sXLib name 'XDestroyIC'; +function XSetLocaleModifiers(modifier_list: pchar): pchar; cdecl; + external sXLib name 'XSetLocaleModifiers'; +function XSetICValues(IC: XIC): PChar; cdecl; varargs; + external sXLib name 'XSetICValues'; +function XSetIMValues(IC: XIM): PChar; cdecl; varargs; + external sXLib name 'XSetIMValues'; +//function XSetICValues(para1:XIC; dotdotdot:array of const):Pchar;cdecl; +// external sXLib name 'XSetICValues'; +function XGetICValues(IC: XIC): PChar; cdecl; varargs; + external sXLib name 'XGetICValues'; +procedure XSetICFocus(IC: XIC); cdecl; + external sXLib name 'XSetICFocus'; +procedure XUnsetICFocus(IC: XIC); cdecl; + external sXLib name 'XUnsetICFocus'; +{ +function XwcLookupString(IC: XIC; Event: PXKeyPressedEvent; + BufferReturn: Pucs4char; WCharsBuffer: Longint; KeySymReturn: PKeySym; + StatusReturn: PStatus): Longint; cdecl; + external sXLib name 'XwcLookupString'; +} +function Xutf8LookupString(IC: XIC; Event: PXKeyPressedEvent; + BufferReturn: Pchar; CharsBuffer: Longint; KeySymReturn: PKeySym; + StatusReturn: PStatus): Longint; cdecl; + external sXLib name 'Xutf8LookupString'; +(* +function XwcTextListToTextProperty(para1:PDisplay; para2:PPucs4Char; + para3: integer; para4: integer{TXICCEncodingStyle}; + para5:PXTextProperty): integer;cdecl; + external sXLib name 'XwcTextListToTextProperty'; +*) +function XCreateImage(Display: PDisplay; Visual: msePVisual; Depth: longword; + Format: Longint; Offset: Longint; Data: PChar; Width, Height: longword; + BitmapPad: Longint; BytesPerLine: Longint): PXImage; cdecl; + external sXLib name 'XCreateImage'; +function Xutf8TextListToTextProperty(para1:PDisplay; para2:PPchar; + para3: integer; para4: integer{TXICCEncodingStyle}; + para5: PXTextProperty): integer; cdecl; + external sXLib name 'Xutf8TextListToTextProperty'; + +function Xutf8TextPropertyToTextList(para1:PDisplay; para2:PXTextProperty; + para3:PPPchar; para4: pinteger): integer; cdecl; + external sXlib name 'Xutf8TextPropertyToTextList'; + +implementation +uses + msebits,msekeyboard,sysutils,msesysutils,msefileutils,msedatalist,msedragglob + {$ifdef with_sm},sm,ice{$endif},msesonames,msegui,mseactions,msex11gdi, + msearrayutils,msesysintf1,msesysdnd,classes,rtlconsts,mseclasses, + mseglob,msetimer,mseprocess,mseprocmonitor,typinfo + {$ifdef mse_debug},mseformatstr{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + xdndprotocolversion = 4; +var + pixmapcount: integer; + +type + pwinid = ^TXID; + + twindow1 = class(msegui.twindow); + tguiapplication1 = class(tguiapplication); + tcanvas1 = class(tcanvas); + +{$ifdef FPC} + {$macro on} + {$define xchar2b:=txchar2b} + {$define xcharstruct:=txcharstruct} + {$define xfontstruct:=txfontstruct} + {$define xfontprop:=txfontprop} + {$define xpoint:=txpoint} + {$define xgcvalues:=txgcvalues} + {$define region:=tregion} + {$define ximage:=tximage} + {$define xwindowattributes:=txwindowattributes} + {$define xclientmessageevent:=txclientmessageevent} + {$define xselectionevent:= txselectionevent} + {$define xselectionclearevent:=txselectionclearevent} + {$define xselectionrequestevent:=txselectionrequestevent} + {$define xtype:=_type} + {$define xrectangle:=txrectangle} + {$define keysym:=tkeysym} + {$define xsetwindowattributes:=txsetwindowattributes} + {$define xwindowchanges:=txwindowchanges} + {$define xevent:=txevent} + {$define xfunction:=_function} + {$define xwindow:=window} + {$define xlookupkeysym_:=xlookupkeysymval} + {$define c_class:= _class} + {$define xtextproperty:= txtextproperty} + {$define xcolor:= txcolor} + {$define xpointer:= txpointer} + TXIMProc = procedure (para1:PXIM; para2:XPointer; para3:XPointer);cdecl; + + TXICProc = function (para1:PXIC; para2:XPointer; para3:XPointer):TBool;cdecl; + PXIMCallback = ^TXIMCallback; + TXIMCallback = record + client_data : TXPointer; + callback : TXIMProc; + end; + + PXICCallback = ^TXICCallback; + TXICCallback = record + client_data : TXPointer; + callback : TXICProc; + end; +{$else} + tboolresult = longbool; + PXIM = ^TXIM; + TXIM = record + end; + + PXIC = ^TXIC; + TXIC = record + end; + TXIMProc = procedure (para1:TXIM; para2:XPointer; para3:XPointer);cdecl; + + TXICProc = function (para1:TXIC; para2:XPointer; para3:XPointer):TBool;cdecl; + PXIMCallback = ^TXIMCallback; + TXIMCallback = record + client_data : XPointer; + callback : TXIMProc; + end; + + PXICCallback = ^TXICCallback; + TXICCallback = record + client_data : XPointer; + callback : TXICProc; + end; +{$endif} + +const + x_copyarea = 62; + IsUnmapped = 0; + IsUnviewable = 1; + IsViewable = 2; + +{ definitions for initial window state } +{ for windows that are not mapped } + WithdrawnState = 0; + {$EXTERNALSYM WithdrawnState} +{ most applications want to start this way } + NormalState = 1; + {$EXTERNALSYM NormalState} +{ application wants to start as an icon } + IconicState = 3; + {$EXTERNALSYM IconicState} +{ Obsolete states no longer defined by ICCCM } +{ don't know or care } + DontCareState = 0; + {$EXTERNALSYM DontCareState} +{ application wants to start zoomed } + ZoomState = 2; + {$EXTERNALSYM ZoomState} +{ application believes it is seldom used; } + InactiveState = 4; + {$EXTERNALSYM InactiveState} + +type + + x11windowdty = record + ic: xic; + end; + x11windowty = record + case integer of + 0: (d: x11windowdty;); + 1: (_bufferspace: windowpty;); + end; + +const + atombits = sizeof(atom)*8; + mouseeventmask = buttonpressmask or buttonreleasemask or pointermotionmask; + + + { + cursorshapety = (cr_default, + cr_none,cr_arrow,cr_cross,cr_wait,cr_ibeam, + cr_sizever,cr_sizehor,cr_sizebdiag,cr_sizefdiag,cr_sizeall, + cr_splitv,cr_splith,cr_pointinghand,cr_forbidden,cr_drag, + cr_topleftcorner,cr_bottomleftcorner, + cr_bottomrightcorner,cr_toprightcorner, + cr_res0,cr_res1,cr_res2,cr_res3,cr_res4,cr_res5,cr_res6,cr_res7, + cr_user); + } + defaultshape = xc_left_ptr; + standardcursors: array[cursorshapety] of longword = ( + defaultshape,defaultshape,defaultshape, + xc_left_ptr,{xc_tcross}xc_crosshair,xc_watch,xc_xterm, + xc_sb_v_double_arrow,xc_sb_h_double_arrow,xc_top_right_corner, + xc_bottom_right_corner,xc_fleur, + xc_sb_v_double_arrow,xc_sb_h_double_arrow,xc_hand2,xc_circle,xc_sailboat, + xc_top_left_corner,xc_bottom_left_corner, + xc_bottom_right_corner,xc_top_right_corner, + defaultshape,defaultshape,defaultshape,defaultshape, + defaultshape,defaultshape,defaultshape,defaultshape, + defaultshape); +type + wmprotocolty = (wm_delete_window + {$ifdef with_saveyourself},wm_save_yourself{$endif}); + XErrorHandler = function (Display: PDisplay; ErrorEvent: PXErrorEvent): + Longint; cdecl; + wmstatety = (wms_none,wms_withdrawn,wms_normal,wms_invalid,wms_iconic); + +var + xlockerror: integer = 0; + appdisp: pdisplay; + appid: winidty; +// defscreenid: cint; + defscreen: pscreen; + defvisual: msepvisual; + defdepth: integer; + msecolormap: colormap; + istruecolor: boolean; + is8bitcolor: boolean; + xredmask,xgreenmask,xbluemask: longword; + xredshift,xgreenshift,xblueshift: integer; + xredshiftbase,xgreenshiftbase,xblueshiftbase: integer; + xredshiftleft,xgreenshiftleft,xblueshiftleft: boolean; + defcolormap: colormap; + hassm: boolean; + hasxrandrlib: boolean; + hasxrandr: boolean; + xrandreventbase: cint; + xrandrerrorbase: cint; + + numlockstate: cuint; + rootid: winidty; + lastfocuswindow: winidty; + atomatom: atom; + mseclientmessageatom,{timeratom,wakeupatom,} + wmprotocolsatom,wmstateatom,wmnameatom,wmclassatom: atom; + wmtransientforatom,wmclientleaderatom: atom; + wmprotocols: array[wmprotocolty] of atom; +// clipboardatom: atom; + cardinalatom,windowatom,stringatom,utf8_stringatom,compound_textatom, + textatom,textplainatom: atom; + timestampatom: atom; + multipleatom: atom; + targetsatom: atom; + convertselectionpropertyatom: atom; + + {$ifdef with_sm} +type + sminfoty = record + iceconnection: iceconn; + smconnection: smcconn; + fd: integer; + shutdown: boolean; + shutdownpending: boolean; + interactstyle: integer; + interactwaiting,interactgranted: boolean; + end; + psminfoty = ^sminfoty; +var + sminfo: sminfoty; + {$endif} + + {$ifdef with_saveyourself} + wmcommandatom: atom; + saveyourselfwindow: integer; + {$endif} + +type + netatomty = + (net_supported, + //suports checked below + net_workarea, + net_wm_state, + net_wm_state_maximized_vert,net_wm_state_maximized_horz, + //not needed below + net_wm_window_type, + net_wm_state_fullscreen, + net_wm_state_skip_taskbar,net_wm_state_demands_attention, + net_restack_window,net_close_window,net_active_window, + //not supports checked below + net_wm_pid,net_wm_desktop, + + net_wm_window_type_desktop, + net_wm_window_type_dock, + net_wm_window_type_toolbar, + net_wm_window_type_menu, + net_wm_window_type_utility, + net_wm_window_type_splash, + net_wm_window_type_dialog, + net_wm_window_type_dropdown_menu, + net_wm_window_type_popup_menu, + net_wm_window_type_tooltip, + net_wm_window_type_notification, + net_wm_window_type_combo, + net_wm_window_type_dnd, + net_wm_window_type_normal, + net_wm_icon, + net_wm_name, + + net_frame_extents, + net_request_frame_extents, + net_system_tray_s0,net_system_tray_opcode,net_system_tray_message_data, + xembed,xembed_info,motif_wm_hints,wm_normal_hints, + //onlyifexist below + net_wm_window_opacity, + + net_none //dummy +); + netwmstateoperationty = (nso_remove,nso_add,nso_toggle); +const + needednetatom = net_wm_state_maximized_horz; + firstcheckedatom = net_workarea; + lastcheckedatom = net_active_window; + firstonlyifexistatom = net_wm_window_opacity; + netatomnames: array[netatomty] of string = + ('_NET_SUPPORTED','_NET_WORKAREA', + '_NET_WM_STATE', + '_NET_WM_STATE_MAXIMIZED_VERT','_NET_WM_STATE_MAXIMIZED_HORZ', + //not needed below + '_NET_WM_WINDOW_TYPE', + '_NET_WM_STATE_FULLSCREEN', + '_NET_WM_STATE_SKIP_TASKBAR','_NET_WM_STATE_DEMANDS_ATTENTION', + '_NET_RESTACK_WINDOW','_NET_CLOSE_WINDOW','_NET_ACTIVE_WINDOW', + '_NET_WM_PID','_NET_WM_DESKTOP', + + '_NET_WM_WINDOW_TYPE_DESKTOP', + '_NET_WM_WINDOW_TYPE_DOCK', + '_NET_WM_WINDOW_TYPE_TOOLBAR', + '_NET_WM_WINDOW_TYPE_MENU', + '_NET_WM_WINDOW_TYPE_UTILITY', + '_NET_WM_WINDOW_TYPE_SPLASH', + '_NET_WM_WINDOW_TYPE_DIALOG', + '_NET_WM_WINDOW_TYPE_DROPDOWN_MENU', + '_NET_WM_WINDOW_TYPE_POPUP_MENU', + '_NET_WM_WINDOW_TYPE_TOOLTIP', + '_NET_WM_WINDOW_TYPE_NOTIFICATION', + '_NET_WM_WINDOW_TYPE_COMBO', + '_NET_WM_WINDOW_TYPE_DND', + '_NET_WM_WINDOW_TYPE_NORMAL', + '_NET_WM_ICON', + '_NET_WM_NAME', + + '_NET_FRAME_EXTENTS', + '_NET_REQUEST_FRAME_EXTENTS', + '_NET_SYSTEM_TRAY_S0','_NET_SYSTEM_TRAY_OPCODE', + '_NET_SYSTEM_TRAY_MESSAGE_DATA', + '_XEMBED','_XEMBED_INFO', + '_MOTIF_WM_HINTS','WM_NORMAL_HINTS', + '_NET_WM_WINDOW_OPACITY', + ''); +// needednetatom = netatomty(ord(high(netatomty))-4); +type + xdndatomty = (xdnd_aware,xdnd_selection,xdnd_typelist, + xdnd_actionlist,xdnd_actiondescription,xdnd_proxy, + xdnd_enter,xdnd_position,xdnd_status,xdnd_leave,xdnd_drop,xdnd_finished + ); +const + xdndatomnames: array[xdndatomty] of string = ( + 'XdndAware','XdndSelection','XdndTypeList', + 'XdndActionList','XdndActionDescription','XdndProxy', + 'XdndEnter','XdndPosition','XdndStatus','XdndLeave','XdndDrop','XdndFinished' + ); + xdndactionatomnames: array[dndactionty] of string = ( + 'XdndActionCopy','XdndActionMove','XdndActionLink','XdndActionAsk', + 'XdndActionPrivate' + ); + +type + clipboardinfoty = record + name: atom; + buffer: msestring; + timestamp: ttime; + end; +const + clipboardnames: array[clipboardbufferty] of string = ('CLIPBOARD','PRIMARY'); + +var + netatoms: array[netatomty] of atom; + xdndatoms: array[xdndatomty] of atom; + xdndactionatoms: array[dndactionty] of atom; + + netsupported: boolean; + canfullscreen: boolean; + canframeextents: boolean; + netsupportedatom: atom; + + sigtimerbefore: sighandler_t; + sigtermbefore: sighandler_t; + sigchldbefore: sighandler_t; + + timerevent: boolean; + terminated: boolean; + childevent: boolean; +// cursorshape: cursorshapety; +// screencursor: cursor; + im: xim; + appic: xic; + appicmask: longword; +// icwindow: windowty; + imewinid: winidty; + errorhandlerbefore: xerrorhandler; + lasteventtime: ttime; +// lastshiftstate: shiftstatesty; + clipboardbuffers: array[clipboardbufferty] of clipboardinfoty; + fidnum: integer; + +procedure deleteitemat(var dest: atomarty; index: integer); overload; +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitemwi(var dest: winidarty; index: integer); overload; +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure usevariables; +begin + if (multipleatom = 0) and (wmnameatom = 0) and (defcolormap = 0) then begin + end; +end; + +function getidnum: longword; +begin + result:= interlockedincrement(fidnum); + if result = 0 then begin + result:= interlockedincrement(fidnum); + end; +end; + +type + ucs4string = array of wchar_t; + +function msestringtoucs4string(const value: msestring): ucs4string; +var + po1: pmsechar; + po2: pwchar_t; + ca1: ucs4char; +begin + setlength(result,length(value)+1); //max + po1:= pmsechar(value); + po2:= pwchar_t(result); + while true do begin + ca1:= card16(po1^); + if ca1 and $fc00 = $d800 then begin + inc(po1); + if (card16(po1^) and $fc00 = $dc00) then begin + ca1:= ((ca1 + ($0040-$d800)) shl 10) + card16(po1^) - $dc00; + end; + end; + po2^:= ca1; + inc(po1); + inc(po2); + if ca1 = 0 then begin + break; + end; + end; + setlength(result,po2-pwchar_t(pointer(result))); +end; + +procedure setstringproperty(id: winidty; prop: atom; value: string); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xchangeproperty(appdisp,id,prop,stringatom,8,propmodereplace, + pbyte(pchar(value)),length(value)+1); +end; + +procedure setmsestringproperty(id: winidty; prop: atom; const value: msestring); +var + str1: string; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + str1:= stringtoutf8(value); + xchangeproperty(appdisp,id,prop,utf8_stringatom,8,propmodereplace, + pbyte(pchar(str1)),length(str1)+1); +end; + +procedure setwinidproperty(id: winidty; prop: atom; value: winidty); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xchangeproperty(appdisp,id,prop,windowatom,32,propmodereplace,@value,1); +end; + +procedure setlongproperty(id: winidty; prop: atom; value: culong); overload; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xchangeproperty(appdisp,id,prop,cardinalatom,32,propmodereplace,@value,1); +end; + +procedure setlongproperty(const id: winidty; const prop: atom; + const value: array of culong; + const datatype: atom); overload; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if (prop <> 0) and (datatype <> 0) then begin + xchangeproperty(appdisp,id,prop,datatype,32,propmodereplace,@value, + length(value)); + end; +end; + +function readatomproperty(id: winidty; name: atom; var value: atomarty): boolean; +var + actualtype: atom; + actualformat: cint; + nitems: clong; + bytesafter: culong; + prop: pchar; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if xgetwindowproperty(appdisp,id,name,0,10000,{$ifdef xboolean}false{$else}0{$endif}, + atomatom,@actualtype,@actualformat,@nitems,@bytesafter,@prop) = success then begin + if (actualtype = atomatom) and (actualformat = 32) then begin + setlength(value,nitems); + if nitems > 0 then begin + {$ifdef FPC} {$checkpointer off} {$endif} + move(prop^,value[0],nitems*sizeof(value[0])); + {$ifdef FPC} {$checkpointer default} {$endif} + end; + result:= true; + end; + xfree(prop); + end; +end; + +procedure setatomproperty(id: winidty; prop: atom; value: atom); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xchangeproperty(appdisp,id,prop,atomatom,32,propmodereplace,@value,1); +end; + +procedure setatomarrayitemproperty(id: winidty; prop: atom; value: atom); +var + ar1: atomarty; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + readatomproperty(id,prop,ar1); + for int1:= 0 to high(ar1) do begin + if ar1[int1] = value then begin + exit; //already set + end; + end; + setlength(ar1,high(ar1)+2); + ar1[high(ar1)]:= value; + xchangeproperty(appdisp,id,prop,atomatom,32,propmodereplace, + pointer(ar1),length(ar1)); +end; + +procedure resetatomarrayitemproperty(id: winidty; prop: atom; value: atom); +var + ar1: atomarty; + int1: integer; + bo1: boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + readatomproperty(id,prop,ar1); + bo1:= false; + for int1:= high(ar1) downto 0 do begin + if ar1[int1] = value then begin + deleteitemat(ar1,int1); + bo1:= true; + end; + end; + if bo1 then begin + xchangeproperty(appdisp,id,prop,atomatom,32,propmodereplace,pointer(ar1), + length(ar1)); + end; +end; + +function readcardinalproperty(id: winidty; name: atom; count: longword; + var value): boolean; +var + actualtype: atom; + actualformat: cint; + nitems: clong; + bytesafter: culong; + prop: pchar; + {$ifdef CPU64} + int1: integer; + po1: pculong; + po2: plongword; + {$endif} +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if xgetwindowproperty(appdisp,id,name,0,count,{$ifdef xboolean}false{$else}0{$endif}, + anypropertytype,@actualtype,@actualformat,@nitems,@bytesafter,@prop) = success then begin + if (nitems = count) and (actualformat = 32) then begin +{$ifdef CPU64} + po1:= pointer(prop); + po2:= @value; + for int1:= count-1 downto 0 do begin + po2^:= po1^; + inc(po1); + inc(po2); + end; +{$else} + {$ifdef FPC} {$checkpointer off} {$endif} + move(prop^,value,nitems*sizeof(longword)); + {$ifdef FPC} {$checkpointer default} {$endif} +{$endif} + result:= true; + end; + xfree(prop); + end; +end; + +function readcardinallistproperty(const id: winidty; const name: atom; + out value: longwordarty): boolean; +var + actualtype: atom; + actualformat: cint; + nitems: clong; + bytesafter: culong; + prop: pchar; + {$ifdef CPU64} + int1: integer; + po1: pculong; + po2: plongword; + {$endif} +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if xgetwindowproperty(appdisp,id,name,0,bigint,{$ifdef xboolean}false{$else}0{$endif}, + anypropertytype,@actualtype,@actualformat, + @nitems,@bytesafter,@prop) = success then begin + if actualformat = 32 then begin + setlength(value,nitems); +{$ifdef CPU64} + po1:= pointer(prop); + po2:= pointer(value); + for int1:= nitems-1 downto 0 do begin + po2^:= po1^; + inc(po1); + inc(po2); + end; +{$else} + {$ifdef FPC} {$checkpointer off} {$endif} + move(prop^,value,nitems*sizeof(value[0])); + {$ifdef FPC} {$checkpointer default} {$endif} + result:= true; +{$endif} + end; + xfree(prop); + end; +end; + +function stringtotextproperty(const value: msestring; + const style: txiccencodingstyle; + out textproperty: xtextproperty): boolean; +var + listxwctext: array[0..0] of ucs4string; + listutf8: array[0..0] of pchar; + str1: string; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if style = xstdicctextstyle then begin + listxwctext[0]:= msestringtoucs4string(value); + result:= xwctextlisttotextproperty(appdisp,@listxwctext,1,style, + @textproperty) >= 0; + end + else begin + str1:= stringtoutf8ansi(value); + listutf8[0]:= pchar(str1); + result:= xutf8textlisttotextproperty( + appdisp,@listutf8,1,ord(style),@textproperty) >= 0; + end; + if not result then begin + fillchar(textproperty,0,sizeof(textproperty)); + end; +end; + + +function setnetstring(const id: winidty; const aproperty: netatomty; + const avalue: msestring): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if netatoms[aproperty] <> 0 then begin + setmsestringproperty(id,netatoms[aproperty],avalue); + result:= true; + end; +end; + +function setnetcardinal(const id: winidty; const aproperty: netatomty; + const avalue: longword): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if netatoms[aproperty] <> 0 then begin + setlongproperty(id,netatoms[aproperty],avalue); + result:= true; + end; +end; + +function getnetcardinal(const id: winidty; const aproperty: netatomty; + out avalue: longword): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if netatoms[aproperty] <> 0 then begin + result:= readcardinalproperty(id,netatoms[aproperty],1,avalue); + end; +end; + +function setnetatom(const id: winidty; const aproperty: netatomty; + const avalue: netatomty): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if (netatoms[aproperty] <> 0) and (netatoms[avalue] <> 0) then begin + setatomproperty(id,netatoms[aproperty],netatoms[avalue]); + result:= true; + end; +end; + +function setnetatomarrayitem(const id: winidty; const aproperty: netatomty; + const avalue: netatomty): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if (netatoms[aproperty] <> 0) and (netatoms[avalue] <> 0) then begin + setatomarrayitemproperty(id,netatoms[aproperty],netatoms[avalue]); + result:= true; + end; +end; + +function resetnetatomarrayitem(const id: winidty; const aproperty: netatomty; + const avalue: netatomty): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if (netatoms[aproperty] <> 0) and (netatoms[avalue] <> 0) then begin + resetatomarrayitemproperty(id,netatoms[aproperty],netatoms[avalue]); + result:= true; + end; +end; + +function gui_sethighrestimer(const avalue: boolean): guierrorty; +begin + result:= gue_ok; //dummy +end; + +function gui_grouphideminimizedwindows: boolean; +begin + result:= false; +end; +{ +function hasxft: boolean; +begin + result:= fhasxft; +end; +} +function gui_getdefaultfontnames: defaultfontnamesty; +begin + result:= x11getdefaultfontnames; +end; + +function gui_canstackunder: boolean; +begin + result:= not norestackwindow or not noreconfigurewmwindow; +end; + +function gui_copytoclipboard(const value: msestring; + const buffer: clipboardbufferty): guierrorty; +begin + gdi_lock; + with clipboardbuffers[buffer] do begin + buffer:= value; + timestamp:= lasteventtime; + // clipboardtimestamp:= clipboardtimestamp; //no "not used" compiler message + xsetselectionowner(appdisp,name,appid,lasteventtime); + result:= gue_ok; + end; + gdi_unlock; +end; + +function eventlater(const atime: ttime): boolean; +begin + result:= (atime = currenttime) or (lasteventtime = currenttime) or + laterorsame(lasteventtime,atime); +end; + +function pastefromclipboard(out value: string; const selection: atom; + const timestamp: longword; + const datatypes: array of atom; + out acttype: atom; out actformat: cint; + out nitems1: integer): guierrorty; +const + transferbuffersize = 1024 div 4; //1kb +var + clipboardowner: longword; + value1: string; +// nitems1: integer; +// acttype: atom; +// actformat: cint; + + function getdata(const target: atom; const resulttarget: atom): guierrorty; + var + event: xevent; + po1: pchar; + nitems: culong; + bytesafter: culong; + charoffset: integer; + longoffset: clong; + time1: longword; + int1: integer; + bo1{,bo2}: boolean; + begin + result:= gue_clipboard; + charoffset:= 1; + longoffset:= 0; + xdeleteproperty(appdisp,appid,convertselectionpropertyatom); + repeat //remove pending notifications +// until not (xcheckwindowevent(appdisp,appid, +// propertychangemask,@event) +// {$ifndef xbooleanresult} <> 0{$endif}); + until not (xchecktypedevent(appdisp,selectionnotify,@event) + {$ifndef xbooleanresult} <> 0{$endif}); + + xconvertselection(appdisp,selection,target,convertselectionpropertyatom, + appid,timestamp); + time1:= timestep(2000000); //2 sec + bo1:= true; + repeat +// bo1:= {not} (xcheckwindowevent(appdisp,appid, +// propertychangemask or selectionnotifymask,@event) +// {$ifndef xbooleanresult} <> 0 {$endif}); + bo1:= (xchecktypedevent(appdisp,selectionnotify,@event) + {$ifndef xbooleanresult} <> 0{$endif}); + + if bo1 then begin + case event.xany.xtype of + selectionnotify: begin + with event.xselection do begin + {$ifdef FPC} + if _property <> convertselectionpropertyatom then begin + {$else} + if xproperty <> convertselectionpropertyatom then begin + {$endif} + exit; + end; + end; + end; + else begin + exit; //error + end; + end; + end; +// if xcheckwindowevent(appdisp,appid,propertychangemask,@event) +// {$ifndef FPC} = 0 {$endif} then begin + if not bo1 then begin + if timeout(time1) then begin + exit; + end; + if bo1 then begin + bo1:= false; +// sys_threadschedyield; + sys_schedyield; + end + else begin + sleep(20); + end; + end + else begin +// with event.xproperty do begin + nitems1:= 0; + bytesafter:= 0; + value1:= ''; + repeat + if xgetwindowproperty(appdisp,appid,convertselectionpropertyatom, + longoffset,transferbuffersize,{$ifdef xboolean} true{$else}1{$endif}, + anypropertytype,@acttype,@actformat,@nitems,@bytesafter,@po1) = success then begin + if (resulttarget = 0) or (acttype = resulttarget) then begin + if actformat = 32 then begin + actformat:= atombits; + end; + int1:= (actformat div 8) * nitems; //bytecount + if nitems > 0 then begin + inc(nitems1,nitems); + setlength(value1,length(value1) + int1 ); + move(po1^,value1[charoffset],int1); + inc(charoffset,int1); + inc(longoffset,int1 div sizeof(dword)); +// inc(longoffset,int1 div sizeof(atom)); //32/64 bit + result:= gue_ok; + end; + end + else begin + bytesafter:= 0; + result:= gue_clipboard; + end; + xfree(po1); + end + else begin + if timeout(time1) then begin + exit; + end; + end; + until bytesafter = 0; + break; + end; +// end; + until false; + end; //getdata + +var + int1,int2: integer; + po1: patomaty; +// atoms1: array[0..4] of atom; + atom1: atom; + +begin + value1:= ''; + gdi_lock; + acttype:= 0; + actformat:= 0; + nitems1:= 0; + clipboardowner:= xgetselectionowner(appdisp,selection); + if clipboardowner = appid then begin +// value:= clipboard; + result:= gue_ok; + end + else begin + result:= gue_clipboard; + value:= ''; + if clipboardowner <> none then begin + atom1:= 0; + if high(datatypes) > 0 then begin + result:= getdata(targetsatom,atomatom); + if result = gue_ok then begin + po1:= pointer(value1); + for int2:= low(datatypes) to high(datatypes) do begin + for int1:= 0 to (length(value1) div sizeof(atom)) - 1 do begin + if po1^[int1] = datatypes[int2] then begin + atom1:= datatypes[int2]; + break; + end; + end; + if atom1 <> 0 then begin + break; + end; + end; + end; + end + else begin + if high(datatypes) = 0 then begin + atom1:= datatypes[0]; + end; + end; + if atom1 <> 0 then begin + result:= getdata(atom1,0); + if result = gue_ok then begin + value:= value1; + end; + end; + end; + end; + gdi_unlock; +end; + +function gui_pastefromclipboard(out value: msestring; + const buffer: clipboardbufferty): guierrorty; +var + value1: string; + acttype: atom; + actformat: cint; + nitems1: integer; + po2: ppchar; + prop1: xtextproperty; + int1: integer; +begin + gdi_lock(); + with clipboardbuffers[buffer] do begin + result:= pastefromclipboard(value1,name,lasteventtime, + [utf8_stringatom,compound_textatom,textatom,textplainatom,stringatom], + acttype,actformat,nitems1); + if result = gue_ok then begin + if acttype = 0 then begin + value:= buffer; + end + else begin + if acttype = utf8_stringatom then begin + value:= utf8tostringansi(value1); + end + else begin + if (acttype = textatom) or (acttype = textplainatom) then begin + value:= msestring(value1); //current locale + end + else begin + if acttype = compound_textatom then begin + with prop1 do begin + value:= pointer(value1); + encoding:= acttype; + format:= actformat; + nitems:= nitems1; + end; + xutf8textpropertytotextlist(appdisp,@prop1,@po2,@int1); + if int1 >= 1 then begin + value:= utf8tostringansi(string(po2^)); + end; + xfreestringlist(po2); + end + else begin + value:= latin1tostring(value1); + end; + end; + end; + end; + end; + end; + gdi_unlock(); +end; + +function gui_canpastefromclipboard(const buffer: clipboardbufferty): boolean; +begin + gdi_lock; + with clipboardbuffers[buffer] do begin + result:= xgetselectionowner(appdisp,name) <> none; + end; + gdi_unlock; +end; + +function windowmapped(const id: winidty): boolean; +var + attributes: xwindowattributes; +begin + xgetwindowattributes(appdisp,id,@attributes); + result:= attributes.map_state = isviewable; +end; + +function getwmstate(id: winidty): wmstatety; +type + wmstatety = record + state: longword; + icon: winidty; + end; + pwmstatety = ^wmstatety; + +var + typeatom: atom; + format: cint; + itemcount: culong; + po1: pwmstatety; + bytesafterreturn: culong; + +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= wms_none; + if xgetwindowproperty(appdisp,id,wmstateatom,0,2, + {$ifdef xboolean}false{$else}0{$endif},wmstateatom,@typeatom,@format, + @itemcount,@bytesafterreturn,@po1) = success then begin +{$ifdef FPC} {$checkpointer off} {$endif} + if (format = 32) and (itemcount = 2) then begin + longword(result):= po1^.state + longword(wms_withdrawn); + end; +{$ifdef FPC} {$checkpointer default} {$endif} + xfree(po1); + end; +end; + +function gui_getrootwindow(id: winidty = 0): winidty; +var + x,y: cint; + width,height,border,depth: cuint; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if id <> 0 then begin + if xgetgeometry(appdisp,id,@result,@x,@y, + @width,@height,@border,@depth) <> 0 then begin + exit; + end; + end; + result:= rootid; +end; + +function gui_getwindowsize(id: winidty): windowsizety; +var + state: wmstatety; + atomar: atomarty; + int1: integer; + maxh,maxv: boolean; +begin + gdi_lock; + state:= getwmstate(id); + case state of + wms_iconic: begin + result:= wsi_minimized; + end; + else begin + result:= wsi_normal; + if netsupported and readatomproperty(id,netatoms[net_wm_state],atomar) then begin + maxh:= false; + maxv:= false; + for int1:= 0 to high(atomar) do begin + if atomar[int1] = netatoms[net_wm_state_fullscreen] then begin + result:= wsi_fullscreen; + break; + end; + if (atomar[int1] = netatoms[net_wm_state_maximized_vert]) then begin + maxv:= true; + end + else begin + if (atomar[int1] = netatoms[net_wm_state_maximized_horz]) then begin + maxh:= true; + end; + end; + end; + if (result = wsi_normal) and maxh and maxv then begin + result:= wsi_maximized; + end; + end; + end; + end; + gdi_unlock; +end; + +function gui_getwindowdesktop(const id: winidty): integer; +var + lwo1: longword; +begin + result:= 0; + if getnetcardinal(id,net_wm_desktop,lwo1) then begin + result:= lwo1; + end; +end; + +function changenetwmstate(id: winidty; const operation: netwmstateoperationty; + const value1: netatomty; const value2: netatomty = net_none): boolean; +var + xevent: xclientmessageevent; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if netsupported then begin + fillchar(xevent,sizeof(xevent),0); + with xevent do begin + xtype:= clientmessage; + display:= appdisp; + xwindow:= id; + format:= 32; + message_type:= netatoms[net_wm_state]; + data.l[0]:= ord(operation); + data.l[1]:= netatoms[value1]; + data.l[2]:= netatoms[value2]; + if xsendevent(appdisp,gui_getrootwindow(id), + {$ifdef xboolean}false{$else}0{$endif}, + substructurenotifymask or + substructureredirectmask,@xevent) <> 0 then begin + result:= true; + end; + end; + end; +end; + +function sendnetcardinalmessage(const adest: winidty; const messagetype: atom; + const aid: winidty; const adata: array of longword; + const amask: longword = noeventmask): boolean; + //true if ok +var + xevent: xclientmessageevent; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= netsupported and (messagetype <> 0) and (high(adata) <= 4); + if result then begin + fillchar(xevent,sizeof(xevent),0); + with xevent do begin + xtype:= clientmessage; + display:= appdisp; + xwindow:= aid; + format:= 32; + message_type:= messagetype; + for int1:= 0 to high(adata) do begin + data.l[int1]:= adata[int1]; + end; + result:= xsendevent(appdisp,adest, + {$ifdef xboolean}false{$else}0{$endif},amask,@xevent) <> 0; + end; + end; +end; + +function sendnetrootcardinalmessage(const messagetype: atom; + const aid: winidty; const adata: array of longword): boolean; + //true if ok +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= sendnetcardinalmessage(rootid,messagetype,aid,adata, + substructurenotifymask or substructureredirectmask); +end; + +function waitfordecoration(id: winidty; raiseexception: boolean = true): boolean; +var + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + int1:= 0; + result:= false; + repeat + xsync(appdisp,0); //windowmanager has to work +// xflush(appdisp); //windowmanager has to work + sys_schedyield; + if gui_windowvisible(id) then begin + result:= true; + break; + end; +// xflush(appdisp); //windowmanager has to work + sleep(5*int1); + inc(int1); + until (int1 > 45); + if raiseexception and not result then begin + raise exception.Create('not decorated'); + end; +end; + +function gui_setwindowstate(id: winidty; size: windowsizety; + visible: boolean): guierrorty; + procedure fullscreen; + begin + if size = wsi_fullscreenvirt then begin + gui_reposwindow(id,gui_getscreenrect(0)); + end + else begin + gui_reposwindow(id,gui_getscreenrect(id)); + end + end; + +begin + gdi_lock; + result:= gue_ok; + if visible then begin +{$ifdef mse_debugshow} + debugwindow('*gui_setwindowstate xmapwindow ',id); +{$endif} + if (getwmstate(id) = wms_iconic) and windowmapped(id) and + (netatoms[net_active_window] <> 0)then begin + //probably gnome mutter + sendnetrootcardinalmessage(netatoms[net_active_window],id, + [1,lasteventtime,lastfocuswindow]); + end + else begin + xmapwindow(appdisp,id); + end; + end; + if size in [wsi_fullscreen,wsi_fullscreenvirt] then begin + if not canfullscreen or + not changenetwmstate(id,nso_add,net_wm_state_fullscreen) then begin + fullscreen; //no windowmanager + end; + end + else begin + changenetwmstate(id,nso_remove,net_wm_state_fullscreen); + case size of + wsi_minimized: begin + if xiconifywindow(appdisp,id,0) = 0 then begin + result:= gue_show; + end; + gdi_unlock; + exit; + end; + wsi_maximized: begin + if not changenetwmstate(id,nso_add, + net_wm_state_maximized_horz,net_wm_state_maximized_vert) then begin + fullscreen; + end; + end + else begin + changenetwmstate(id,nso_remove, + net_wm_state_maximized_horz,net_wm_state_maximized_vert); + end; + end; + end; + gdi_unlock; +end; + +procedure freetextproperty(const value: xtextproperty); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xfree(value.value); +end; + +function gui_setwindowcaption(id: winidty; + const caption: msestring): guierrorty; +var + textprop: xtextproperty; +begin + gdi_lock; + if stringtotextproperty(caption, + xstdicctextstyle{xutf8stringstyle},textprop) then begin + //jwm can not handle xutf8stringstyle + xsetwmname(appdisp,id,@textprop); + freetextproperty(textprop); + result:= gue_ok; + end + else begin + result:= gue_characterencoding; + end; + setnetstring(id,net_wm_name,caption); + gdi_unlock; +end; + +function gui_setwindowicon(id: winidty; const icon,mask: pixmapty): guierrorty; +var + hints: pxwmhints; + ima,maskima: imagety; + ps,pe,ps1: pbyte; + pd,pde: prgbtriplety; + ar1: longwordarty; + {$ifdef cpu64} +// ar2: qwordarty; + ar2: array of culong; + {$endif} + int1: integer; + bmask,lwo1: longword; + rgb1: rgbtriplety; + npixels: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + hints:= pxwmhints(xgetwmhints(appdisp,id)); + if hints = nil then begin + hints:= pxwmhints(xallocwmhints); + end; + with hints^ do begin + icon_pixmap:= icon; + icon_mask:= mask; + if icon <> 0 then begin + flags:= flags or (1 shl 2); //iconpixmaphint + end + else begin + flags:= flags and not(1 shl 2); + end; + if mask <> 0 then begin + flags:= flags or (1 shl 5); //iconmaskhint + end + else begin + flags:= flags and not(1 shl 5); + end; + end; + xsetwmhints(appdisp,id,hints); + xfree(hints); + if netatoms[net_wm_icon] <> 0 then begin + ima.pixels:= nil; + maskima.pixels:= nil; + if icon <> 0 then begin + if gui_pixmaptoimage(icon,ima,0) <> gde_ok then begin + ima.pixels:= nil; + end; + end; + if mask <> 0 then begin + if gui_pixmaptoimage(mask,maskima,0) <> gde_ok then begin + maskima.pixels:= nil; + end; + end; + if ima.pixels <> nil then begin + npixels:= ima.size.cx*ima.size.cy; + int1:= 2 + npixels; + setlength(ar1,int1); + ar1[0]:= ima.size.cx; + ar1[1]:= ima.size.cy; + pd:= @ar1[2]; + ps:= pointer(ima.pixels); + case ima.kind of + bmk_rgb: begin + move(ps^,pd^,npixels*sizeof(longword)); + end; + bmk_gray: begin + for int1:= 0 to ima.size.cy-1 do begin + ps1:= ps; + pe:= ps+ima.size.cx; + repeat + pd^.red:= ps1^; + pd^.green:= ps1^; + pd^.blue:= ps1^; + inc(ps1); + inc(pd); + until ps1 >= pe; + ps:= ps+ima.linebytes; + end; + end; + bmk_mono: begin + for int1:= 0 to ima.size.cy-1 do begin + pde:= pd+ima.size.cx; + ps1:= ps; + bmask:= 1; + lwo1:= plongword(ps1)^; + repeat + if lwo1 and bmask = 0 then begin + longword(pd^):= $ffffffff; //ar1 is nulled + end; + bmask:= bmask shl 1; + if bmask = 0 then begin + bmask:= 1; + inc(plongword(ps1)); + lwo1:= plongword(ps1)^; + end; + inc(pd); + until pd >= pde; + pd:= pde; + ps:= ps+ima.linebytes; + end; + end; + else begin + ar1:= nil; //not supported + end; + end; + if maskima.pixels <> nil then begin + pd:= @ar1[2]; + ps:= pointer(maskima.pixels); + case maskima.kind of + bmk_rgb: begin + pde:= pd+npixels; + repeat + rgb1:= prgbtriplety(ps)^; + pd^.res:= (word(rgb1.red)+word(rgb1.green)+word(rgb1.blue)) div 3; + inc(pd); + inc(prgbtriplety(ps)); + until pd >= pde; + end; + bmk_gray: begin + for int1:= 0 to ima.size.cx-1 do begin + ps1:= ps; + pe:= ps+ima.size.cx; + repeat + pd^.res:= ps1^; + inc(pd); + inc(ps1); + until ps1 >= pe; + ps:= ps+maskima.linebytes; + end; + end; + bmk_mono: begin + for int1:= 0 to ima.size.cy-1 do begin + pde:= pd+ima.size.cx; + ps1:= ps; + bmask:= 1; + lwo1:= plongword(ps1)^; + repeat + if lwo1 and bmask <> 0 then begin + pd^.res:= $ff; + end + else begin + pd^.res:= $00; + end; + bmask:= bmask shl 1; + if bmask = 0 then begin + bmask:= 1; + inc(plongword(ps1)); + lwo1:= plongword(ps1)^; + end; + inc(pd); + until pd >= pde; + pd:= pde; + ps:= ps+maskima.linebytes; + end; + end; + else begin + ar1:= nil; //not supported + end; + end; + end + else begin + pd:= @ar1[2]; + pde:= pd+npixels; + repeat + pd^.res:= $ff; + inc(pd); + until pd >= pde; + end; + gui_freeimagemem(ima.pixels); + if ar1 <> nil then begin + {$ifdef cpu64} + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar2) do begin + ar2[int1]:= ar1[int1]; + end; + setlongproperty(id,netatoms[net_wm_icon],ar2,cardinalatom); + {$else} + setlongproperty(id,netatoms[net_wm_icon],ar1,cardinalatom); + {$endif} + end; + end; + if maskima.pixels <> nil then begin + gui_freeimagemem(maskima.pixels); + end; + end; + result:= gue_ok; +end; + +function gui_setwindowopacity(id: winidty; const opacity: real): guierrorty; +var + f1: flo64; + at1: atom; +begin + result:= gue_notsupported; + at1:= netatoms[net_wm_window_opacity]; + if at1 <> 0 then begin + if opacity = emptyreal then begin + xdeleteproperty(appdisp,id,at1); + end + else begin + f1:= opacity; + if (f1 < 0) then begin + f1:= 0; + end + else begin + if (f1 > 1) then begin + f1:= 1; + end; + end; + setlongproperty(id,at1,round($ffffffff*f1)); + end; + result:= gue_ok; + end; +end; + +function gui_setapplicationicon(const icon,mask: pixmapty): guierrorty; +begin + result:= gue_ok; +end; + +function gui_pidtowinid(const pids: procidarty): winidty; + +var + level: integer; + + function scanchildren(const aparent: winidty): boolean; + + function checkpid(const apid: integer): boolean; + var + int1: integer; + begin + result:= false; + for int1:= 0 to high(pids) do begin + if pids[int1] = apid then begin + result:= true; + break; + end; + end; + end; + + var + parent,root: winidty; + ca1: longword; + children: pwinid; + int1: integer; +// id1: winidty; + ar1: atomarty; + begin + children:= nil; + result:= false; + if (gui_windowvisible(aparent) or (getwmstate(aparent) = wms_iconic)) and + readcardinalproperty(aparent,netatoms[net_wm_pid],1,int1) and checkpid(int1) then begin + result:= true; + gui_pidtowinid:= aparent; + end + else begin + if not netsupported or + not readatomproperty(aparent,netatoms[net_wm_state],ar1) then begin + //no wm toplevel window + if (xquerytree(appdisp,aparent,@root,@parent,@children,@ca1) <> 0) and + (children <> nil) then begin + inc(level); + for int1:= integer(ca1)-1 downto 0 do begin + if scanchildren(pwinidaty(children)^[int1]) then begin + result:= true; + break; + end; + end; + dec(level); + xfree(children); + end; + end; + end; + end; + +begin + gdi_lock; + result:= 0; + level:= 0; + if (netatoms[net_wm_pid] <> 0) then begin + scanchildren(rootid); + end; + gdi_unlock; +end; + +function XDestroyImage(Image: PXImage): Longint; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} +{$ifdef FPC} {$checkpointer off} {$endif} + Result := Image^.f.destroy_image(Image); +{$ifdef FPC} {$checkpointer default} {$endif} +end; + +function getwindowstack(const id: winidty): winidarty; +var + parent,root: winidty; + ca1: longword; + children: pwinid; + count: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= nil; + count:= 0; + additem(result,id,count); + parent:= id; + repeat + if (xquerytree(appdisp,parent,@root,@parent,@children,@ca1) <> 0) then begin + if children <> nil then begin + xfree(children); + end; + end + else begin + break; + end; + additem(result,parent,count); + until (parent = root); + setlength(result,count); +end; + +function toplevelwindow(const id: winidty): winidty; +var + ar1: winidarty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if id = rootid then begin + result:= rootid; + end + else begin + ar1:= getwindowstack(id); + if high(ar1) > 0 then begin + result:= ar1[high(ar1)-1]; + end + else begin + result:= 0; + end; + end; +end; + +function gui_getzorder(const ids: winidarty; out zorders: integerarty): guierrorty; +var + ar1: winidararty; + int1,int2,int3: integer; + bo1: boolean; + parent,root: winidty; + ca1: longword; + children: pwinid; + +begin + gdi_lock; +{$ifdef FPC} {$checkpointer off} {$endif} + setlength(zorders,length(ids)); + if high(ids) > 0 then begin + setlength(ar1,length(ids)); + for int1:= 0 to high(ids) do begin + ar1[int1]:= getwindowstack(ids[int1]); + end; + if high(ar1[0]) > 0 then begin + int2:= 0; + bo1:= false; + repeat //find common ancestor + inc(int2); + int3:= ar1[0][high(ar1[0])-int2]; + for int1:= 1 to high(ar1) do begin + if (int2 > high(ar1[int1])) or (integer(ar1[int1][high(ar1[int1])-int2]) <> int3) then begin + bo1:= true; + break; + end; + end; + until bo1; + if (xquerytree(appdisp,ar1[0][high(ar1[0])-(int2-1)],@root,@parent,@children,@ca1) <> 0) then begin + for int1:= 0 to ca1 - 1 do begin + for int3:= 0 to high(ids) do begin + if integer(ar1[int3][high(ar1[int3])-int2]) = pwinidaty(children)^[int1] then begin + zorders[int3]:= int1; + break; + end; + end; + end; + if children <> nil then begin + xfree(children); + end; + end; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} + result:= gue_ok; + gdi_unlock; +end; + +function gui_raisewindow(id: winidty; + const topmost: boolean = false): guierrorty; +begin + gdi_lock; +{$ifdef mse_debugzorder} + debugwindow('* gui_raisewindow ',id); +{$endif} + if toplevelraise then begin +// waitfordecoration(id); + xraisewindow(appdisp,toplevelwindow(id)); + end + else begin + xraisewindow(appdisp,id); + end; + result:= gue_ok; + gdi_unlock; +end; + +function gui_lowerwindow(id: winidty; + const topmost: boolean = false): guierrorty; +begin + gdi_lock; +{$ifdef mse_debugzorder} + debugwindow('* gui_lowerwindow ',id); +{$endif} + xlowerwindow(appdisp,id); + result:= gue_ok; + gdi_unlock; +end; + +function stackwindow(id: winidty; predecessor: winidty; + stackmode: integer): guierrorty; +var + bo1: boolean; +// id1: winidty; + changes: xwindowchanges; + ar1: winidarty; + int1: integer; + idindex,pindex: integer; +// topid,toppred: winidty; +// winar1: array[0..1] of winidty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} +{$ifdef mse_debugzorder} + if stackmode = above then begin + debugwindow('*stackwindow above'+' ',id); + end + else begin + if stackmode = below then begin + debugwindow('*stackwindow below'+' ',id); + end + else begin + debugwindow('*stackwindow '+inttostr(stackmode)+' ',id); + end; + end; + debugwindow(' predecessor ',predecessor); +{$endif} + if predecessor = 0 then begin + result:= gui_raisewindow(id); + end + else begin + if id <> predecessor then begin + if gui_canstackunder then begin + bo1:= not norestackwindow and (netatoms[net_restack_window] <> 0); + if {not bo1 and} (stackmode = below) and stackmodebelowworkaround then begin + // xflush(appdisp); + // xsync(appdisp,false); + //many WM place stack_mode below windows + //below all other windows so we need this ugly workaround + //??? OK ??? + application.sortzorder; + ar1:= application.winidar; + pindex:= -1; + for int1:= high(ar1) downto 0 do begin + if ar1[int1] = predecessor then begin + pindex:= int1; + break; + end; + end; + if bo1 then begin + sendnetrootcardinalmessage(netatoms[net_restack_window],predecessor, + [2,id,above]); + {$ifdef mse_debugzorder} + debugwriteln(' net_restack_window workaround'); + {$endif} + end + else begin + {$ifdef mse_debugzorder} + debugwriteln(' reconfigurewmwindow workaround'); + {$endif} + changes.stack_mode:= above; + changes.sibling:= id; + xreconfigurewmwindow(appdisp,predecessor,msedefaultscreenno, + cwsibling or cwstackmode,@changes); + end; + if pindex > 0 then begin + for int1:= pindex+1 to high(ar1) do begin + if (ar1[int1] <> id) and (ar1[int1-1] <> id) then begin + if bo1 then begin + sendnetrootcardinalmessage(netatoms[net_restack_window],ar1[int1], + [2,ar1[int1-1],above]); + end + else begin + changes.sibling:= ar1[int1-1]; + xreconfigurewmwindow(appdisp,ar1[int1],msedefaultscreenno, + cwsibling or cwstackmode,@changes); + end; + end; + end; + end; + // xflush(appdisp); + end + else begin + if bo1 then begin + {$ifdef mse_debugzorder} + debugwriteln(' net_restack_window'); + {$endif} + sendnetrootcardinalmessage(netatoms[net_restack_window],id, + [2,predecessor,stackmode]); + end + else begin + changes.sibling:= predecessor; + changes.stack_mode:= stackmode; + {$ifdef mse_debugzorder} + debugwriteln(' reconfigurewmwindow'); + debugwindow( ' window: ',id); + debugwindow( ' sibling:',changes.sibling); + debugwriteln(' mode: '+inttostr(changes.stack_mode)); + {$endif} + xreconfigurewmwindow(appdisp,id,msedefaultscreenno, + cwsibling or cwstackmode,@changes); + end; + end; + { + changes.sibling:= predecessor; + changes.stack_mode:= stackmode; + xreconfigurewmwindow(appdisp,id,msedefaultscreenno, + cwsibling or cwstackmode,@changes); + } + { + topid:= toplevelwindow(id); + toppred:= toplevelwindow(predecessor); + if stackmode = above then begin + winar1[0]:= topid; + winar1[1]:= toppred; + end + else begin + winar1[0]:= toppred; + winar1[1]:= topid; + end; + xrestackwindows(appdisp,@winar1,2); + } + { + changes.sibling:= toplevelwindow(predecessor); + changes.stack_mode:= stackmode; + xconfigurewindow(appdisp,toplevelwindow(id),cwsibling or cwstackmode,@changes); + } + end + else begin + application.sortzorder; + ar1:= application.winidar; + idindex:= -1; + pindex:= -1; + for int1:= high(ar1) downto 0 do begin + if ar1[int1] = id then begin + idindex:= int1; + break; + end; + end; + for int1:= high(ar1) downto 0 do begin + if ar1[int1] = predecessor then begin + pindex:= int1; + break; + end; + end; + if (idindex >= 0) and (pindex >= 0) then begin + if not ( + (stackmode = above) and (pindex < high(ar1)) and (ar1[pindex+1] = id) or + (stackmode <> above) and (pindex > 0) and (ar1[pindex-1] = id) + ) then begin + deleteitem(ar1,idindex); + if idindex < pindex then begin + dec(pindex); + end; + if stackmode = above then begin + insertitem(ar1,pindex+1,id); + end + else begin + insertitem(ar1,pindex,id); + dec(pindex); + end; + if pindex < 0 then begin + pindex:= 0; + end; + for int1:= pindex to high(ar1) do begin + gui_raisewindow(ar1[int1]); + end; + end; + end; + { //code below does not work because wm takes no notice about the new stacking order + if xgetwindowattributes(appdisp,changes.sibling,@attributes1) <> 0 then begin + changes.sibling:= toplevelwindow(predecessor); + changes.stack_mode:= stackmode; + id1:= toplevelwindow(id); + if xgetwindowattributes(appdisp,id1,@attributes2) <> 0 then begin + attributes3.override_redirect:= 1; + if attributes1.override_redirect = 0 then begin + xchangewindowattributes(appdisp,changes.sibling,cwoverrideredirect,@attributes3); + end; + if attributes2.override_redirect = 0 then begin + xchangewindowattributes(appdisp,id1,cwoverrideredirect,@attributes3); + end; + xconfigurewindow(appdisp,id1,cwsibling or cwstackmode,@changes); + attributes3.override_redirect:= 0; + if attributes1.override_redirect = 0 then begin + xchangewindowattributes(appdisp,changes.sibling,cwoverrideredirect,@attributes3); + end; + if attributes2.override_redirect = 0 then begin + xchangewindowattributes(appdisp,id1,cwoverrideredirect,@attributes3); + end; + end; + application.sortzorder; + ar1:= application.winidar; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] = id) or (ar1[int1] = predecessor) then begin + for int2:= int1 to high(ar1) do begin + xraisewindow(appdisp,ar1[int1]); + end; + break; + end; + end; + end; + } + end; + end; + result:= gue_ok; + end; +end; + +function gui_stackunderwindow(id: winidty; predecessor: winidty): guierrorty; +begin + gdi_lock; + result:= stackwindow(id,predecessor,below); + gdi_unlock; +end; + +function gui_stackoverwindow(id: winidty; predecessor: winidty): guierrorty; +begin + gdi_lock; + result:= stackwindow(id,predecessor,above); + gdi_unlock; +end; + +type + screeninfoty = record + rect: rectty; + ppmmwidth,ppmmheight: flo64; + end; + screeninfoarty = array of screeninfoty; + +var + screenrects: screeninfoarty; + screenrectsvalid: boolean; + +procedure updatescreenrects(); +var + info: pxrrscreenresources; + int1,int2: integer; + rectnum: integer; + po1: prroutput; + po2: pxrroutputinfo; + po3: pxrrcrtcinfo; + crtcs: array of pxrrcrtcinfo; +begin + if hasxrandr then begin + info:= xrrgetscreenresources(appdisp,rootid); + setlength(crtcs,info^.ncrtc); + for int1:= 0 to high(crtcs) do begin + crtcs[int1]:= xrrgetcrtcinfo(appdisp,info,info^.crtcs[int1]); + end; + setlength(screenrects,info^.noutput); + po1:= info^.outputs; + rectnum:= 0; + for int1:= 0 to high(screenrects) do begin + po2:= xrrgetoutputinfo(appdisp,info,po1^); + if (po2 <> nil) and (po2^.crtc <> 0) then begin + for int2:= 0 to high(crtcs) do begin + if po2^.crtc = info^.crtcs[int2] then begin + po3:= crtcs[int2]; + if po3 <> nil then begin + with screenrects[rectnum] do begin + with rect do begin + x:= po3^.x; + y:= po3^.y; + cx:= po3^.width; + cy:= po3^.height; + inc(rectnum); + end; + if po2^.mm_width > 0 then begin + ppmmwidth:= po3^.width / po2^.mm_width; + end + else begin + ppmmwidth:= 0; + end; + if po2^.mm_height > 0 then begin + ppmmheight:= po3^.height / po2^.mm_height; + end + else begin + ppmmheight:= 0; + end; + end; + end; + end; + end; + xrrfreeoutputinfo(po2); + end; + inc(po1); + end; + xrrfreescreenresources(info); + setlength(screenrects,rectnum); + for int1:= 0 to high(crtcs) do begin + if crtcs[int1] <> nil then begin + xrrfreecrtcinfo(crtcs[int1]); + end; + end; + end + else begin + screenrects:= nil; + end; + screenrectsvalid:= true; +end; + +procedure checkscreenrects(); +begin + if not screenrectsvalid then begin + updatescreenrects(); + end; +end; + +function getscreenrectindex(id: winidty): int32; +var + i1: int32; + rect1: rectty; + pt1: pointty; +label + endlab; +begin + result:= -1; + checkscreenrects(); + if screenrects <> nil then begin + if id = 0 then begin + id:= rootid; + end; + if gui_getdecoratedwindowrect(id,rect1) = gue_ok then begin + for i1:= 0 to high(screenrects) do begin + if rectinrect(rect1,screenrects[i1].rect) then begin + result:= i1; + goto endlab; + end; + end; + pt1.x:= rect1.x + rect1.cx div 2; + pt1.y:= rect1.y + rect1.cy div 2; + for i1:= 0 to high(screenrects) do begin + if pointinrect(pt1,screenrects[i1].rect) then begin + result:= i1; + goto endlab; + end; + end; + end; + for i1:= 0 to high(screenrects) do begin + if testintersectrect(rect1,screenrects[i1].rect) then begin + result:= i1; + goto endlab; + end; + end; + end; +endlab: +end; + +function gui_getscreenrect(const id: winidty): rectty; //0 -> virtual screen +var + i1: int32; +label + endlab; +begin + gdi_lock(); + if id <> 0 then begin + i1:= getscreenrectindex(id); + if i1 >= 0 then begin + result:= screenrects[i1].rect; + goto endlab; + end; + end; + result.pos:= nullpoint; +{$ifdef FPC} {$checkpointer off} {$endif} + result.cx:= defscreen^.width; + result.cy:= defscreen^ .height; +{$ifdef FPC} {$checkpointer default} {$endif} +endlab: + gdi_unlock(); +end; + + +function gui_getworkarea(id: winidty): rectty; +var + i1: int32; + bo1: boolean; +begin + gdi_lock; + bo1:= false; + if netsupported then begin + bo1:= readcardinalproperty(gui_getrootwindow(id), + netatoms[net_workarea],4,result); + end; + if not bo1 then begin + result:= gui_getscreenrect(id); + end; + i1:= getscreenrectindex(id); + if i1 >= 0 then begin + result:= intersectrect(result,screenrects[i1].rect); + end; + gdi_unlock; +end; + +procedure gui_getppmm(id: winidty; out appmmwidth,appmmheight: flo64); + //0.0 if not supported +var + i1: int32; +begin + gdi_lock(); + i1:= getscreenrectindex(id); + appmmwidth:= 0; + appmmheight:= 0; + if i1 >= 0 then begin + with screenrects[i1] do begin + appmmwidth:= ppmmwidth; + appmmheight:= ppmmheight; + end; + end; + if appmmwidth = 0 then begin + with defscreen^ do begin + if mwidth > 0 then begin + appmmwidth:= width / mwidth; + end; + end; + end; + if appmmheight = 0 then begin + with defscreen^ do begin + if mheight > 0 then begin + appmmheight:= height / mheight; + end; + end; + end; + gdi_unlock(); +end; + +function getwindowframe(id: winidty): framety; +var + bo1: boolean; + ar1: array[0..3] of integer; +// win1: winidty; +// root: winidty; + rect1,rect2: rectty; +// int1: integer; +// pt1: pointty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + bo1:= false; + if canframeextents then begin + bo1:= readcardinalproperty(id,netatoms[net_frame_extents],4,ar1); + end; + if bo1 then begin + with result do begin + left:= ar1[0]; + top:= ar1[2]; + right:= ar1[1]; + bottom:= ar1[3]; + end; + end + else begin + result:= nullframe; + if (gui_getwindowrect(id,rect1) = gue_ok) and + (gui_getwindowrect(toplevelwindow(id),rect2) = gue_ok) then begin + result.left:= rect1.x - rect2.x; + result.top:= rect1.y - rect2.y; + result.right:= rect2.x + rect2.cx - rect1.x - rect1.cx; + result.bottom:= rect2.y + rect2.cy - rect1.y - rect1.cy; + end; + end; +end; + +function gui_setmainthread: guierrorty; //set mainthread to currentthread +begin + //not used in linux-x11 + result:= gue_ok; +end; + +function gui_getpointerpos: pointty; +var + ca1: longword; +begin + gdi_lock; + xquerypointer(appdisp,rootid,@ca1,@ca1,@result.x,@result.y,@ca1,@ca1,@ca1); + gdi_unlock; +end; + +function gui_setpointerpos(const pos: pointty): guierrorty; +begin + gdi_lock; + xwarppointer(appdisp,none,rootid,0,0,0,0,pos.x,pos.y); + result:= gue_ok; + gdi_unlock; +end; + +function gui_movepointer(const dist: pointty): guierrorty; +begin + gdi_lock; + xwarppointer(appdisp,rootid,none,0,0,0,0,dist.x,dist.y); + result:= gue_ok; + gdi_unlock; +end; + +var + pointergrabbed: boolean; + grabwinid: winidty; + +function gui_grabpointer(id: winidty): guierrorty; +begin + gdi_lock; + xflush(appdisp); //possibly show window + if xgrabpointer(appdisp,id,{$ifdef xboolean}false{$else}0{$endif}, + mouseeventmask,grabmodeasync,grabmodeasync, + none,none,currenttime) = grabsuccess then begin + result:= gue_ok; + pointergrabbed:= true; + grabwinid:= id; + xflush(appdisp); + end + else begin + result:= gue_capturemouse; + end; + gdi_unlock; +end; + +function gui_ungrabpointer: guierrorty; +begin + gdi_lock; + xungrabpointer(appdisp,currenttime); + result:= gue_ok; + pointergrabbed:= false; + xflush(appdisp); + gdi_unlock; +end; + +function gui_allocimagemem(length: integer): plongwordaty; +begin + if length = 0 then begin + result:= nil; + end + else begin + getmem(result,length * sizeof(longword)); + end; +end; + +procedure gui_freeimagemem(data: plongwordaty); +begin + freemem(data); +end; + +function gui_pixmaptoimage(pixmap: pixmapty; out image: imagety; + gchandle: longword): gdierrorty; +var + info: pixmapinfoty; + ximage1: pximage; + po1: plongword; + po2: pbyte; + int1,int2: integer; + wordmax: integer; +begin + gdi_lock; + info.handle:= pixmap; + result:= gui_getpixmapinfo(info); + if result = gde_ok then begin + image.size:= info.size; + image.pixels:= nil; + case info.depth of + 1: begin //monochrome + // image.kind:= bmk_mono; + ximage1:= xgetimage(appdisp,pixmap,0,0,info.size.cx,info.size.cy,1,xypixmap); + if ximage1 = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + {$ifdef FPC} {$checkpointer off} {$endif} + with ximage1^ do begin + // wordmax:= (image.size.cx + 31) div 32; + // image.length:= wordmax * image.size.cy; + // image.pixels:= gui_allocimagemem(image.length); + allocimage(image,info.size,bmk_mono); + wordmax:= image.linelength; + po1:= @image.pixels^[0]; + po2:= pbyte(data); + if bitmap_pad = 32 then begin + move(po2^,po1^,image.size.cy * bytes_per_line); + end + else begin + for int1:= 0 to image.size.cy - 1 do begin + move(po2^,po1^,bytes_per_line); + inc(po2,bytes_per_line); + inc(po1,wordmax); + end; + end; + if byte_order <> lsbfirst then begin + case bitmap_unit of + 32: begin + for int1:= 0 to image.length - 1 do begin + swapbytes1(image.pixels^[int1]); + end; + end; + 16: begin + for int1:= 0 to image.length*2-1 do begin + swapbytes1(pwordaty(image.pixels)^[int1]); + end; + end; + end; + end; + if bitmap_bit_order <> lsbfirst then begin + po2:= @image.pixels^[0]; + for int1:= 0 to image.length*4-1 do begin + po2^:= bitreverse[po2^]; + inc(po2); + end; + end; + end; + {$ifdef FPC} {$checkpointer default} {$endif} + end; + 8: begin //gray //what about indexed pixmap???? + ximage1:= xgetimage(appdisp,pixmap,0,0,info.size.cx,info.size.cy,$ff,zpixmap); + if ximage1 = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + allocimage(image,info.size,bmk_gray); + with ximage1^ do begin + po1:= @image.pixels^[0]; + po2:= pbyte(data); + if bitmap_pad = 32 then begin + move(po2^,po1^,image.size.cy * bytes_per_line); + end + else begin + wordmax:= image.linelength; + for int1:= 0 to image.size.cy - 1 do begin + move(po2^,po1^,bytes_per_line); + inc(po2,bytes_per_line); + inc(po1,wordmax); + end; + end; + end; + end; + else begin + // image.monochrome:= false; + // image.length:= image.size.cx * image.size.cy; + ximage1:= xgetimage(appdisp,pixmap,0,0,info.size.cx,info.size.cy, + $ffffffff,zpixmap); + if ximage1 = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + allocimage(image,info.size,bmk_rgb); + // image.pixels:= gui_allocimagemem(image.length); + + //todo: optimize + + po1:= @image.pixels[0]; + for int1:= 0 to info.size.cy - 1 do begin + for int2:= 0 to info.size.cx - 1 do begin + po1^:= gui_pixeltorgb(ximage1^.f.get_pixel(ximage1,int2,int1)); + inc(po1); + end; + end; + end; + end; + xdestroyimage(ximage1); + end; + gdi_unlock; +end; + +function gui_getpixel(const id: winidty; const pos: pointty; + out pixel: pixelty): guierrorty; +var + ximage1: pximage; +begin + gdi_lock(); + result:= gue_error; + ximage1:= xgetimage(appdisp,id,pos.x,pos.y,1,1,$ffffffff,zpixmap); + if ximage1 <> nil then begin + pixel:= ximage1^.f.get_pixel(ximage1,0,0); + xdestroyimage(ximage1); + result:= gue_ok; + end; + gdi_unlock(); +end; + +function gui_imagetopixmap(const image: imagety; out pixmap: pixmapty; + gchandle: longword): gdierrorty; +var + ximage: pximage; + po1: prgbtriplety; + po2: pchar; + gc: tgc; + int1,int2: integer; +begin + gdi_lock; + result:= gde_ok; + po2:= nil; + case image.kind of + bmk_mono: begin + ximage:= XCreateImage(appdisp,nil,1,xypixmap,0,nil, + image.size.cx,image.size.cy,32,0); + if ximage = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + with ximage^ do begin + bitmap_bit_order:= LSBFirst; + byte_order:= lsbfirst; + bitmap_unit:= 32; + data:= @image.pixels[0]; + end; + end; + bmk_gray: begin + ximage:= XCreateImage(appdisp,nil,8,zpixmap,0,nil, + image.size.cx,image.size.cy,32,0); + if ximage = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + with ximage^ do begin + bitmap_bit_order:= LSBFirst; + byte_order:= lsbfirst; + bitmap_unit:= 32; + data:= @image.pixels[0]; + end; + end; + else begin + ximage:= XCreateImage(appdisp,defvisual,defdepth,zpixmap,0,nil, + image.size.cx,image.size.cy,32,0); + if ximage = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + with ximage^ do begin + { + bitmap_bit_order:= LSBFirst; + byte_order:= lsbfirst; + bitmap_unit:= 32; + red_mask:= redmask; + green_mask:= greenmask; + blue_mask:= bluemask; + data:= @image.pixels[0]; + } + getmem(po2,image.size.cy * bytes_per_line); + data:= po2; + po1:= @image.pixels^[0]; + for int1:= 0 to image.size.cy - 1 do begin + for int2:= 0 to image.size.cx - 1 do begin + f.put_pixel(ximage,int2,int1,gui_rgbtopixel(longword(po1^))); + inc(po1); + end; + end; + end; + end; + end; + pixmap:= gui_createpixmap(image.size,0,image.kind); + gc:= xcreategc(appdisp,pixmap,0,nil); + xsetgraphicsexposures(appdisp,gc,{$ifdef xboolean}false{$else}0{$endif}); + xputimage(appdisp,pixmap,gc,ximage,0,0,0,0,image.size.cx,image.size.cy); + xfreegc(appdisp,gc); + ximage^.data:= nil; + xdestroyimage(ximage); + if po2 <> nil then begin + freemem(po2); + end; + gdi_unlock; +end; + +function gui_createpixmap(const size: sizety; winid: winidty = 0; + kind: bitmapkindty = bmk_rgb; copyfrom: pixmapty = 0): pixmapty; +var + gc: tgc; +begin + gdi_lock; + inc(pixmapcount); + if winid = 0 then begin + winid:= rootid; + end; + case kind of + bmk_mono: begin + result:= xcreatepixmap(appdisp,winid,size.cx,size.cy,1); + end; + bmk_gray: begin + result:= xcreatepixmap(appdisp,winid,size.cx,size.cy,8); + end; + else begin + result:= xcreatepixmap(appdisp,winid,size.cx,size.cy,defdepth); + end; + end; + if copyfrom <> 0 then begin + gc:= xcreategc(appdisp,result,0,nil); + xcopyarea(appdisp,copyfrom,result,gc,0,0,size.cx,size.cy,0,0); + xfreegc(appdisp,gc); + end; + gdi_unlock; +end; + +function gui_freepixmap(pixmap: pixmapty): gdierrorty; +begin + gdi_lock; + dec(pixmapcount); + if xfreepixmap(appdisp,pixmap) <> success then begin + result:= gde_pixmap; + end + else begin + result:= gde_ok; + end; + gdi_unlock; +end; + +function gui_createbitmapfromdata(const size: sizety; datapo: pbyte; + msbitfirst: boolean = false; dwordaligned: boolean = false; + bottomup: boolean = false): pixmapty; +var + image: ximage; + gc: tgc; + po1,po2: pbyte; + int1: integer; + +begin + gdi_lock; +// result:= xcreatebitmapfromdata(appdisp,rootid,datapo,size.cx,size.cy); + inc(pixmapcount); + result:= XCreatePixmap(appdisp,rootid,size.cx,size.cy,1); + if result <> 0 then begin + gc:= XCreateGC(appdisp,result,0,nil); + if gc = nil then begin + xfreepixmap(appdisp,result); + result:= 0; + end + else begin + with image do begin + width:= size.cx; + height:= size.cy; + depth:= 1; + bits_per_pixel:= 1; + xoffset:= 0; + format:= XYPixmap; + byte_order:= LSBFirst; + bitmap_unit:= 8; + if msbitfirst then begin + bitmap_bit_order:= mSBFirst; + end + else begin + bitmap_bit_order:= lSBFirst; + end; + if dwordaligned then begin + bitmap_pad:= 32; + bytes_per_line:= ((size.cx+31) div 32)*4; + end + else begin + bitmap_pad:= 8; + bytes_per_line:= (size.cx+7) div 8; + end; + if bottomup then begin + getmem(po1,bytes_per_line*size.cy); + data:= pchar(po1); + po2:= pbyte(pchar(datapo)+bytes_per_line*(size.cy-1)); + for int1:= 0 to size.cy - 1 do begin + move(po2^,po1^,bytes_per_line); + inc(po1,bytes_per_line); + dec(po2,bytes_per_line); + end; + XPutImage(appdisp,result,gc,@image,0,0,0,0,size.cx,size.cy); + freemem(data); + end + else begin + data:= pchar(datapo); + XPutImage(appdisp,result,gc,@image,0,0,0,0,size.cx,size.cy); + end; + end; + XFreeGC(appdisp, gc); + end; + end; + gdi_unlock; +end; + +function gui_getpixmapinfo(var info: pixmapinfoty): gdierrorty; +var + ca1: longword; +begin + gdi_lock; + with info do begin + if xgetgeometry(appdisp,handle,@ca1,@ca1,@ca1,@size.cx,@size.cy,@ca1, + @depth) = 0 then begin + result:= gde_pixmap; + end + else begin + result:= gde_ok; + end; + end; + gdi_unlock; +end; + +function gui_windowvisible(id: winidty): boolean; +var + attributes: xwindowattributes; +begin + gdi_lock; + xgetwindowattributes(appdisp,id,@attributes); + result:= (attributes.map_state = isviewable) and + (getwmstate(id) = wms_normal); + //gnome does not unmap iconic windows + gdi_unlock; +end; + +function hasoverrideredirect(const id: winidty): boolean; +var + attributes: xwindowattributes; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xgetwindowattributes(appdisp,id,@attributes); + result:= (attributes.override_redirect {$ifndef xboolean}<> 0{$endif}); +end; + +function gui_showwindow(id: winidty): guierrorty; +var + min,max: sizety; + rect1: rectty; + transientfor: winidty; + bo1: boolean; +begin + gdi_lock; + xmapwindow(appdisp,id); +{$ifdef mse_debugshow} + debugwindow('*gui_showwindow ',id); +{$endif} + result:= gue_ok; + rect1:= nullrect; + application.checkwindowrect(id,rect1); + min:= rect1.size; + rect1.cx:= bigint; + rect1.cy:= bigint; + application.checkwindowrect(id,rect1); + max:= rect1.size; + if max.cx = bigint then begin + max.cx:= 0; + end; + if max.cy = bigint then begin + max.cy:= 0; + end; + if (max.cx <> 0) or (max.cy <> 0) or (min.cx <> 0) or (min.cy <> 0) then begin + waitfordecoration(id); + gui_setsizeconstraints(id,min,max); + end; + transientfor:= 0; + bo1:= xgettransientforhint(appdisp,id,@transientfor) <> 0; + if hasoverrideredirect(id) or bo1 then begin + waitfordecoration(id); + if (transientfor = 0) or (transientfor = rootid) then begin + gui_raisewindow(id); + end + else begin + waitfordecoration(transientfor); + gui_raisewindow(transientfor); + gui_raisewindow(id); +// gui_stackunderwindow(transientfor,id); + end; + end; + gdi_unlock; +end; +{ +procedure printwindowname(aid: winidty; const atext: string); +var + window1: twindow1; +begin + if application.findwindow(aid,window1) then begin + writeln(window1.fowner.name,' ',atext); + end; +end; +} +function getic(const awindow: winidty): xic; +var + window1: twindow1; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= appic; + {$ifdef FPC} + if application.findwindow(awindow,twindow(window1)) then begin + {$else} + if application.findwindow(awindow,twindow(window1)) then begin + {$endif} + with x11windowty(window1.fwindow.platformdata).d do begin + if ic <> nil then begin + result:= ic; + end; + end; + end; +end; + +function gui_setwindowfocus(id: winidty): guierrorty; +begin + gdi_lock; +{$ifdef mse_debugwindowfocus} + debugwindow('*gui_setwindowfocus ',id); +{$endif} + +// xseticfocus(getic(id)); + waitfordecoration(id); + if netatoms[net_active_window] <> 0 then begin + sendnetrootcardinalmessage(netatoms[net_active_window],id, + [1,lasteventtime,lastfocuswindow]); + end; +// setnetatomarrayitem(id,net_wm_state,net_wm_state_demands_attention); + xsetinputfocus(appdisp,id,reverttoparent,currenttime); + xsync(appdisp,0); +// xflush(appdisp); + result:= gue_ok; + gdi_unlock; +end; + +function gui_setimefocus(var awindow: windowty): guierrorty; +begin + gdi_lock; + result:= gue_ok; + with awindow,x11windowty(platformdata).d do begin + if ic <> nil then begin + xseticvalues(ic,pchar(xnfocuswindow),id,nil); + xseticfocus(ic); + end + else begin + xseticvalues(appic,pchar(xnfocuswindow),id,nil); + imewinid:= id; + xseticfocus(appic); + end; + end; + gdi_unlock; +end; + +procedure unsetime(const awindow: winidty); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if awindow = imewinid then begin + xunseticfocus(appic); + xseticvalues(appic,pchar(xnfocuswindow),appid,nil); + imewinid:= 0; + end; +end; + +function gui_unsetimefocus(var awindow: windowty): guierrorty; +begin + gdi_lock; + result:= gue_ok; + with x11windowty(awindow.platformdata).d do begin + if ic <> nil then begin + xunseticfocus(ic); + end + else begin + unsetime(awindow.id); + end; + end; + gdi_unlock; +end; + +function gui_setappfocus(id: winidty): guierrorty; +begin + result:= gui_setwindowfocus(id); +end; + +function gui_minimizeapplication: guierrorty; +begin + result:= gue_ok; //dummy +end; + +function gui_setcursorshape(winid: winidty; shape: cursorshapety): guierrorty; +var + cursor1: cursor; + bmp: pixmapty; + color: xcolor; +begin + result:= gue_ok; + if winid = 0 then begin + exit; //do not modify root window cursor + end; + gdi_lock; + if shape = cr_none then begin + fillchar(color,sizeof(color),0); + bmp:= xcreatebitmapfromdata(appdisp,winid,@color,1,1); //dummy data + cursor1:= xcreatepixmapcursor(appdisp,bmp,bmp,@color,@color,0,0); + xfreepixmap(appdisp,bmp); + end + else begin + cursor1:= xcreatefontcursor(appdisp,standardcursors[shape]); + end; + if cursor1 <> 0 then begin + xdefinecursor(appdisp,winid,cursor1); + xflush(appdisp); + xfreecursor(appdisp,cursor1); + end + else begin + result:= gue_cursor; + end; + gdi_unlock; +end; + +var + mainthreadid: threadty; + connectpipe: tpipedescriptors; + dummybyte: byte; + +procedure sigtimer(SigNum: Integer); cdecl; +begin + timerevent:= true; + if sys_getcurrentthread() <> mainthreadid then begin + //FreeBSD needs this + sys_write(connectpipe.writedes,@dummybyte,1); + end; +end; + +procedure sigterminate(SigNum: Integer); cdecl; +begin + terminated:= true; +end; + +procedure sigchild(SigNum: Integer); cdecl; +begin + childevent:= true; + mseprocmonitor.sigchildcallback(); +end; + +function getclientpointer(const event: xclientmessageevent): pointer; +begin + with event do begin + {$ifdef CPU64} + result:= pointer((data.l[0] and $ffffffff) + ((data.l[1] and $ffffffff) shl 32)); + {$else} + result:= pointer(data.l[0]); + {$endif} + end; +end; + +procedure setclientpointer(const ptr: pointer; out event: xclientmessageevent); +begin + fillchar(event,sizeof(event),0); + with event do begin + xtype:= clientmessage; + format:= 32; + message_type:= mseclientmessageatom; + {$ifdef CPU64} + data.l[0]:= ptruint(ptr) and $ffffffff; + data.l[1]:= (ptruint(ptr) shr 32) and $ffffffff; + {$else} + data.l[0]:= ptruint(ptr); + {$endif} + end; +end; + +function gui_postevent(event: tmseevent): guierrorty; +var + xevent1: xclientmessageevent; +begin + gdi_lock; + setclientpointer(event,xevent1); + if xsendevent(appdisp,appid,{$ifdef xboolean}false{$else}0{$endif},0, + @xevent1) = 0 then begin + result:= gue_postevent; + end + else begin + xflush(appdisp); + result:= gue_ok; + end; + gdi_unlock; +end; + +function settimer1(us: longword): guierrorty; + //send et_timer event after delay of us (micro seconds) +var + timerval: itimerval; +begin + fillchar(timerval,sizeof(timerval),0); + timerval.it_value.tv_sec:= us div 1000000; + timerval.it_value.tv_usec:= us mod 1000000; + if mselibc.setitimer(itimer_real,@timerval,nil) = 0 then begin + result:= gue_ok; + end + else begin + result:= gue_timer; + end; +end; + +function gui_settimer(us: longword): guierrorty; +begin + if us = 0 then begin + us:= 1; + end; + result:= settimer1(us); +end; + +function gui_rgbtopixel(rgb: longword): pixelty; +var + lwo1: longword; +begin //todo: speedup + if xredshiftleft then begin + lwo1:= ((rgb and redmask) shl xredshift) and xredmask; + end + else begin + lwo1:= ((rgb and redmask) shr xredshift) and xredmask; + end; + if xgreenshiftleft then begin + lwo1:= lwo1 or (((rgb and greenmask) shl xgreenshift) and xgreenmask); + end + else begin + lwo1:= lwo1 or (((rgb and greenmask) shr xgreenshift) and xgreenmask); + end; + if xblueshiftleft then begin + result:= lwo1 or (((rgb and bluemask) shl xblueshift) and xbluemask); + end + else begin + result:= lwo1 or (((rgb and bluemask) shr xblueshift) and xbluemask); + end; +end; + +function gui_graytopixel(gray: byte): pixelty; +var + lwo1: longword; +begin + lwo1:= gray; //todo: speedup + result:= (lwo1 shl xredshiftbase) and xredmask or + (lwo1 shl xgreenshiftbase) and xgreenmask or + (lwo1 shl xblueshiftbase) and xbluemask; +end; + +{ +function gui_rgbtocolormappixel(rgb: longword): pixelty; +begin + with rgbtriplety(rgb) do begin + if is8bitcolor and (red = green) and (red = blue) and (red <> 255) then begin + red:= red and xbluemask; + green:= green and xbluemask; //more neutral gray + end; + end; + result:= gui_rgbtopixel(rgb); +end; +} +function gui_pixeltorgb(pixel: longword): longword; +begin +// if istruecolor then begin + if xredshiftleft then begin + result:= (pixel and xredmask) shr xredshift; + end + else begin + result:= (pixel and xredmask) shl xredshift; + end; + if xgreenshiftleft then begin + result:= result or ((pixel and xgreenmask) shr xgreenshift); + end + else begin + result:= result or ((pixel and xgreenmask) shl xgreenshift); + end; + if xblueshiftleft then begin + result:= result or ((pixel and xbluemask) shr xblueshift); + end + else begin + result:= result or ((pixel and xbluemask) shl xblueshift); + end; +// end; +end; + +function gui_pixeltogray(pixel: pixelty): byte; +var + int1: integer; +begin + int1:= (pixel and xredmask) shr xredshiftbase; + int1:= int1 + ((pixel and xgreenmask) shr xgreenshiftbase); + int1:= int1 + ((pixel and xbluemask) shr xblueshiftbase); + result:= int1 div 3; +end; + + +function xtomousebutton(button: longword): mousebuttonty; +begin + case button of + button1: result:= mb_left; + button2: result:= mb_middle; + button3: result:= mb_right; + else result:= mb_none; + end; +end; + +function xtoshiftstate(const shiftstate: longword; + const key: keyty; const button: mousebuttonty; + const up: boolean): shiftstatesty; +begin + result:= []; + if shiftstate and button1mask <> 0 then include(result,ss_left); + if shiftstate and button2mask <> 0 then include(result,ss_middle); + if shiftstate and button3mask <> 0 then include(result,ss_right); + if shiftstate and shiftmask <> 0 then include(result,ss_shift); + if shiftstate and controlmask <> 0 then include(result,ss_ctrl); + if shiftstate and mod1mask <> 0 then include(result,ss_alt); + case key of + key_shift: if up then exclude(result,ss_shift) else include(result,ss_shift); + key_control: if up then exclude(result,ss_ctrl) else include(result,ss_ctrl); + key_alt: if up then exclude(result,ss_alt) else include(result,ss_alt); + end; + case button of + mb_left: if up then exclude(result,ss_left) else include(result,ss_left); + mb_middle: if up then exclude(result,ss_middle) else include(result,ss_middle); + mb_right: if up then exclude(result,ss_right) else include(result,ss_right); + end; +end; + +//var +// messcount: integer; + +procedure freeclientevents; +var + xev: xevent; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + while xpending(appdisp) > 0 do begin + xnextevent(appdisp,@xev); + with xev.xclient do begin + if (xtype = clientmessage) and (display = appdisp) and + (message_type = mseclientmessageatom) then begin + tmseevent(getclientpointer(xev.xclient)).free1; + end; + end; + end; +end; + +function gui_hasevent: boolean; +begin + gdi_lock; + result:= ((xpending(appdisp) > 0) or timerevent) and not terminated; + gdi_unlock; +end; + +function xkeytokey(key: keysym; var shiftstate: shiftstatesty): keyty; +begin + if (key >= $61) and (key <= $7a) then begin //a..z + result:= keyty(key - $20); //A..Z + end + else begin + case key of + xk_backspace: result:= key_backspace; + xk_tab: result:= key_tab; + xk_iso_left_tab: result:= key_backtab; +// xk_linefeed: result:= key_linefeed; +// xk_clear: result:= key_clear; + xk_return: result:= key_return; + xk_pause: result:= key_pause; + xk_scroll_lock: result:= key_scrolllock; + xk_sys_req: result:= key_sysreq; + xk_escape: result:= key_escape; + xk_delete: result:= key_delete; + xk_home: result:= key_home; + xk_left: result:= key_left; + xk_up: result:= key_up; + xk_right: result:= key_right; + xk_down: result:= key_down; +// xk_prior: result:= key_prior; + xk_page_up: result:= key_pageup; +// xk_next: result:= key_next; + xk_page_down: result:= key_pagedown; + xk_end: result:= key_end; +// xk_begin: result:= key_begin; + +// xk_select: result:= key_select; + xk_print: result:= key_print; +// xk_execute: result:= key_execute; + xk_insert: result:= key_insert; +// xk_undo: result:= key_undo; +// xk_redo: result:= key_redo; + xk_menu: result:= key_menu; +// xk_find: result:= key_find; +// xk_cancel: result:= key_cancel; + xk_help: result:= key_help; + xk_break: result:= key_pause; //key_break; +// xk_mode_switch: result:= key_modeswitch; +// xk_script_switch: result:= key_scriptswitch; + xk_num_lock: result:= key_numlock; + + xk_kp_space: begin + result:= key_space; + include(shiftstate,ss_second); + end; + xk_kp_tab: begin + result:= key_tab; + include(shiftstate,ss_second); + end; + xk_kp_enter: begin + result:= key_return; + include(shiftstate,ss_second); + end; + xk_kp_f1: begin + result:= key_f1; + include(shiftstate,ss_second); + end; + xk_kp_f2: begin + result:= key_f2; + include(shiftstate,ss_second); + end; + xk_kp_f3: begin + result:= key_f3; + include(shiftstate,ss_second); + end; + xk_kp_f4: begin + result:= key_f4; + include(shiftstate,ss_second); + end; + xk_kp_home: begin + result:= key_home; + include(shiftstate,ss_second); + end; + xk_kp_left: begin + result:= key_left; + include(shiftstate,ss_second); + end; + xk_kp_up: begin + result:= key_up; + include(shiftstate,ss_second); + end; + xk_kp_right: begin + result:= key_right; + include(shiftstate,ss_second); + end; + xk_kp_down: begin + result:= key_down; + include(shiftstate,ss_second); + end; +// xk_kp_prior: result:= key_prior; + xk_kp_page_up: begin + result:= key_pageup; + include(shiftstate,ss_second); + end; +// xk_kp_next: result:= key_next; + xk_kp_page_down: begin + result:= key_pagedown; + include(shiftstate,ss_second); + end; + xk_kp_end: begin + result:= key_end; + include(shiftstate,ss_second); + end; +// xk_kp_begin: result:= key_begin; + xk_kp_insert: begin + result:= key_insert; + include(shiftstate,ss_second); + end; + xk_kp_delete: begin + result:= key_delete; + include(shiftstate,ss_second); + end; + xk_kp_equal: begin + result:= key_equal; + include(shiftstate,ss_second); + end; + xk_kp_multiply: begin + result:= key_asterisk; + include(shiftstate,ss_second); + end; + xk_kp_add: begin + result:= key_plus; + include(shiftstate,ss_second); + end; + xk_kp_separator: begin + result:= key_comma; + include(shiftstate,ss_second); + end; + xk_kp_subtract: begin + result:= key_minus; + include(shiftstate,ss_second); + end; + xk_kp_decimal: begin + result:= key_decimal; + include(shiftstate,ss_second); + end; + xk_kp_divide: begin + result:= key_slash; + include(shiftstate,ss_second); + end; + xk_kp_0..xk_kp_9: begin + result:= keyty(longword(key_0) + key - xk_kp_0); + include(shiftstate,ss_second); + end; + + xk_f1..xk_f35: result:= keyty(longword(key_f1) + key - xk_f1); + + xk_shift_l: result:= key_shift; + xk_shift_r: begin + result:= key_shift; + include(shiftstate,ss_second); + end; + xk_control_l: result:= key_control; + xk_control_r: begin + result:= key_control; + include(shiftstate,ss_second); + end; + xk_caps_lock: result:= key_capslock; +// xk_shift_lock: result:= key_shift_lock; + + xk_meta_l: result:= key_meta; + xk_meta_r: begin + result:= key_meta; + include(shiftstate,ss_second); + end; + xk_alt_l: result:= key_alt; + xk_alt_r: begin + result:= key_alt; + include(shiftstate,ss_second); + end; + xk_super_l: result:= key_super; + xk_super_r: begin + result:= key_super; + include(shiftstate,ss_second); + end; + xk_hyper_l: result:= key_hyper; + xk_hyper_r: begin + result:= key_hyper; + include(shiftstate,ss_second); + end; + + xk_iso_level3_shift: begin + result:= key_altgr; + end; + + else result:= keyty(key and not modmask); + end; + end; +end; + +function pchartomsestring(value: pchar; len: integer): msestring; +var + int1: integer; + buffer: longwordarty; +begin + setlength(buffer,len); + int1:= mbsnrtowcs(pointer(buffer),@value,len,len,nil); + if int1 > 0 then begin + setlength(result,int1); + for int1:= 0 to int1-1 do begin + result[int1+1]:= msechar(buffer[int1]); + end; + end + else begin + setlength(result,0); + end; +end; + +function ucs4stringtomsestring(const source: longwordarty): msestring; +var + int1: integer; +begin + setlength(result,length(source)); + for int1:= 0 to length(source)-1 do begin + result[int1+1]:= msechar(source[int1]); + end; +end; + +var + getrootpathlevel: integer; + +function getrootpath(const id: winidty; out rootpath: longwordarty): boolean; +var + root,parent: winidty;//{$ifdef FPC}dword{$else}xlib.twindow{$endif}; + children: pwinid; + count: integer; + ca1: longword; + id1: winidty; + +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + id1:= id; + setlength(rootpath,5); + rootpath[0]:= id; + count:= 1; //reserve for root + inc(xlockerror); //parent window possibly destroyed by WM + repeat + if xquerytree(appdisp,id1,@root,@parent,@children,@ca1) = 0 then begin + dec(xlockerror); + if (count > 1) and (getrootpathlevel < 4) then begin + {$ifdef mse_debugrootpath} + debugwindow('*** rootpatherror ',id); + {$endif} + inc(getrootpathlevel); + result:= getrootpath(id,rootpath); + dec(getrootpathlevel); + end; + exit; + end; + if children <> nil then begin + xfree(children); + end; + if count >= length(rootpath) then begin + setlength(rootpath,count+5); + end; + rootpath[count]:= parent; + id1:= parent; + inc(count); + until parent = root; + dec(xlockerror); + setlength(rootpath,count); + result:= true; +end; + +function gui_getchildren(const id: winidty; out children: winidarty): guierrorty; +var + root,parent: winidty;//{$ifdef FPC}dword{$else}xlib.twindow{$endif}; + chi: pwinid; +// count: integer; + ca1: longword; + int1: integer; +begin + gdi_lock; + result:= gue_getchildren; + children:= nil; + if xquerytree(appdisp,id,@root,@parent,@chi,@ca1) = 0 then begin + gdi_unlock; + exit; + end; + if chi <> nil then begin + setlength(children,ca1); + for int1:= 0 to high(children) do begin + children[int1]:= pwinidaty(chi)^[int1]; + end; + xfree(chi); + end; + result:= gue_ok; + gdi_unlock; +end; + +function getrootoffset(const id: winidty; var aoffset: pointty): boolean; +var + int1: integer; + rootpath: longwordarty; + ax,ay: integer; + width,height,border: longword; + ca1: longword; + offset: pointty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= getrootpath(id,rootpath); + if result then begin + result:= false; + offset:= nullpoint; + for int1:= 1 to high(rootpath) - 1 do begin + if xgetgeometry(appdisp,rootpath[int1],@ca1,@ax,@ay,@width, + @height,@border,@ca1) = 0 then begin + exit; + end; + with offset do begin + inc(x,ax); + inc(y,ay); + end; + end; + end; +{$warnings off} + aoffset:= offset; + result:= true; +end; +{$warnings on} +function settransientforhint(id,transientfor: winidty): guierrorty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if transientfor = 0 then begin + if wmtransientforatom <> 0 then begin + xdeleteproperty(appdisp,id,wmtransientforatom); + end + else begin + xsettransientforhint(appdisp,id,rootid); + end; + end + else begin + xsettransientforhint(appdisp,id,transientfor); + end; + result:= gue_ok; +end; + +function gui_settransientfor(var awindow: windowty; + const transientfor: winidty): guierrorty; +//var +// attributes: xwindowattributes; +begin + gdi_lock; + result:= settransientforhint(awindow.id,transientfor); +(* + if result = gue_ok then begin + if xgetwindowattributes(appdisp,awindow.id,@attributes) <> 0 then begin + if attributes.override_redirect{$ifndef xboolean} <> 0 {$endif}then begin + gui_stackunderwindow(transientfor,awindow.id); + end; + end; + end; +*) + gdi_unlock; +end; + +function gui_windowatpos(const pos: pointty): winidty; +var + int1: integer; + id: winidty; +begin + gdi_lock; + id:= rootid; + repeat + result:= id; + if longint(xtranslatecoordinates(appdisp,rootid,result, + pos.x,pos.y,@int1,@int1,@id)) = 0 then begin + result:= 0; + gdi_unlock; + exit; + end; + until id = none; + gdi_unlock; +end; + +function windowsatpos(const pos: pointty): winidarty; + //top down without root +var + int1: integer; + id,id1: winidty; + int2: integer; +begin + id:= rootid; + int2:= 0; + while true do begin + id1:= id; + if (longint(xtranslatecoordinates(appdisp,rootid,id1, + pos.x,pos.y,@int1,@int1,@id)) = 0) or (id = 0) then begin + break; + end; + additem(integerarty(result),id,int2); + end; + setlength(result,int2); +end; + +function gui_setwindowgroup(id,group: winidty): guierrorty; +var + wmhints: pxwmhints; +begin + gdi_lock; +{$ifdef FPC}{$checkpointer off}{$endif} + wmhints:= pxwmhints(xgetwmhints(appdisp,id)); + if wmhints = nil then begin + wmhints:= pxwmhints(xallocwmhints); + end; + with wmhints^ do begin + window_group:= group; + flags:= flags or windowgrouphint; + xsetwmhints(appdisp,id,wmhints); + end; + xfree(wmhints); +{$ifdef FPC}{$checkpointer default}{$endif} + setwinidproperty(id,wmclientleaderatom,group); + result:= gue_ok; + gdi_unlock; +end; + +const + windowtypes: array[windowtypeoptionty] of netatomty = + ( +// wo_popup, wo_message, +net_wm_window_type_dropdown_menu,net_wm_window_type_dialog, +//wo_desktop, wo_dock, wo_toolbar, +net_wm_window_type_desktop,net_wm_window_type_dock,net_wm_window_type_toolbar, +//wo_menu, wo_utility, wo_splash, +net_wm_window_type_menu,net_wm_window_type_utility,net_wm_window_type_splash, +//wo_dialog, wo_dropdownmenu, +net_wm_window_type_dialog,net_wm_window_type_dropdown_menu, +//wo_popupmenu, wo_tooltip, +net_wm_window_type_popup_menu,net_wm_window_type_tooltip, +//wo_notification, wo_combo, wo_dnd +net_wm_window_type_notification,net_wm_window_type_combo,net_wm_window_type_dnd + ); + +function gui_createwindow(const rect: rectty; + var options: internalwindowoptionsty; var awindow: windowty): guierrorty; +var + attributes: xsetwindowattributes; + valuemask: longword; + width,height: integer; + id1: winidty; + icmask: longword; + colormap1: tcolormap; + opt1: windowtypeoptionty; +begin + gdi_lock; + with awindow,x11windowty(platformdata).d do begin + valuemask:= 0; + if options.options * [wo_popup,wo_overrideredirect] <> [] then begin + attributes.override_redirect:= {$ifdef xboolean}true{$else}1{$endif}; + valuemask:= valuemask or cwoverrideredirect; + end; + if rect.cx <= 0 then begin + width:= 1; + end + else begin + width:= rect.cx; + end; + if rect.cy <= 0 then begin + height:= 1; + end + else begin + height:= rect.cy; + end; + if options.parent <> 0 then begin + id1:= options.parent; + end + else begin + id1:= rootid; + end; + with x11internalwindowoptionsty(options.platformdata).d do begin + if colormap <> 0 then begin + colormap1:= colormap; + end + else begin + colormap1:= msecolormap; + end; + if colormap1 <> 0 then begin + attributes.colormap:= colormap1; + valuemask:= valuemask or cwcolormap; + end; + if depth = 0 then begin + depth:= copyfromparent; + end; + if visual = nil then begin + visual:= pvisual(copyfromparent); + end; +// if nocreatestaticgravity then begin + attributes.win_gravity:= northwestgravity; +// end +// else begin +// attributes.win_gravity:= staticgravity; +// end; + attributes.bit_gravity:= northwestgravity; + valuemask:= valuemask or cwwingravity or cwbitgravity; + + id:= xcreatewindow(appdisp,id1,rect.x,rect.y,width,height,0, + depth,copyfromparent,visual, + valuemask,@attributes); + if colormap <> 0 then begin + xfreecolormap(appdisp,colormap); + colormap:= 0; + end; + end; + if id = 0 then begin + result:= gue_createwindow; + gdi_unlock; + exit; + end; + result:= gue_ok; + if options.parent <> 0 then begin //embedded window + xselectinput(appdisp,id,exposuremask); //will be mapped to parent + gdi_unlock; + exit; + end; + if (options.transientfor <> 0) or + (options.options * [wo_popup,wo_message] <> []) then begin + settransientforhint(id,options.transientfor); + end; + with options do begin + if icon <> 0 then begin + gui_setwindowicon(id,icon,iconmask); + end; + end; + if options.setgroup then begin + if options.groupleader = 0 then begin + gui_setwindowgroup(id,id); + end + else begin + gui_setwindowgroup(id,options.groupleader); + end; + end; + if options.pos <> wp_default then begin + gui_reposwindow(id,rect); + end; +{ //single ic for whole application + ic:= xcreateic(im,pchar(xninputstyle), + ximstatusnothing or ximpreeditnothing, + pchar(xnclientwindow),id,nil); +} + icmask:= appicmask; + if ic <> nil then begin + xgeticvalues(ic,pchar(xnfilterevents),@icmask,nil); + xseticvalues(ic,pchar(xnresetstate),pchar(ximpreservestate),nil); + end; + xselectinput(appdisp,id,icmask or + KeymapStateMask or + KeyPressMask or KeyReleaseMask or + buttonpressmask or buttonreleasemask or + pointermotionmask or + EnterWindowMask or LeaveWindowMask or + FocusChangeMask or PropertyChangeMask or + exposuremask or structurenotifymask + ); + xsetwmprotocols(appdisp,id,@wmprotocols[low(wmprotocolty)], + integer(high(wmprotocolty))+1); + setstringproperty(id,wmclassatom,ansistring( + filename(sys_getapplicationpath)+#0+application.applicationname)); + setnetcardinal(id,net_wm_pid,getpid); + if (wo_popup in options.options) and (options.transientfor <> 0) then begin + gui_raisewindow(options.transientfor); + //transientforhint not used by overrideredirect + end; + if options.options * windowtypeoptions <> [] then begin + for opt1:= low(windowtypeoptionty) to high(windowtypeoptionty) do begin + if opt1 in options.options then begin + setnetatomarrayitem(id,net_wm_window_type,windowtypes[opt1]); +// break; + end; + end; + end + else begin + setnetatomarrayitem(id,net_wm_window_type,net_wm_window_type_normal); + end; + if (options.options * noframewindowtypes <> []) and + (netatoms[motif_wm_hints] <> 0) then begin + setlongproperty(id,netatoms[motif_wm_hints],[mwm_hints_decorations,0,0,0,0], + netatoms[motif_wm_hints]); + end; + if (wo_popup in options.options) then begin + gui_raisewindow(id); + end + else begin + if wo_notaskbar in options.options then begin +// changenetwmstate(id,nso_add,net_wm_state_skip_taskbar,net_none); + setnetatomarrayitem(id,net_wm_state,net_wm_state_skip_taskbar); + end; + end; + if wo_sysdnd in options.options then begin + setatomproperty(id,xdndatoms[xdnd_aware],xdndprotocolversion); + end + else begin + xdeleteproperty(appdisp,id,xdndatoms[xdnd_aware]); + end; + end; + gdi_unlock; +end; + +function gui_destroywindow(var awindow: windowty): guierrorty; +begin + gdi_lock; + with awindow,x11windowty(platformdata).d do begin + if ic <> nil then begin + xdestroyic(ic); + ic:= nil; + end; + if id <> 0 then begin + {$ifdef with_saveyourself} + if id <> saveyourselfwindow then begin + {$endif} + unsetime(id); + xdestroywindow(appdisp,id); + {$ifdef with_saveyourself} + end; + {$endif} + end; + end; + result:= gue_ok; + gdi_unlock; +end; + +function getwindowrect(id: winidty; out rect: rectty; out origin: pointty): guierrorty; +var + int1: integer; +begin + result:= gue_error; + with rect do begin + if getrootoffset(id,origin) and + (xgetgeometry(appdisp,id,@int1,@x,@y,@cx,@cy,@int1,@int1) <> 0) then begin + result:= gue_ok; + end; + end; +end; + +function gui_getwindowrect(id: winidty; out rect: rectty): guierrorty; +var +// int1: integer; + po1: pointty; +begin + gdi_lock; + result:= getwindowrect(id,rect,po1); + if result = gue_ok then begin + addpoint1(rect.pos,po1); + end; + gdi_unlock; +end; + +function gui_getwindowpos(id: winidty; out pos: pointty): guierrorty; +var + int1: integer; +// po1: pointty; +begin + gdi_lock; + result:= gue_error; + with pos do begin + if xgetgeometry(appdisp,id,@int1,@x,@y,@int1,@int1,@int1,@int1) <> 0 then begin + result:= gue_ok; + end; + end; + gdi_unlock; +end; + +procedure wmwait; +begin + xsync(appdisp,false); + sys_schedyield; + xsync(appdisp,false); +end; + +function gui_reposwindow(id: winidty; const rect: rectty): guierrorty; +var + changes: xwindowchanges; + sizehints: pxsizehints; + int1: clong; +// rect1: rectty; + frame1: framety; + bo1: boolean; +begin + gdi_lock; + fillchar(changes,sizeof(changes),0); + bo1:= hasoverrideredirect(id); + with changes do begin + if not bo1 and nostaticgravity then begin + wmwait(); + frame1:= getwindowframe(id); + {$ifdef mse_debugconfigure} + debugwindow('*reposw.framekorr'+' '+inttostr(frame1.left)+' '+ + inttostr(frame1.top)+' ',id); + {$endif} + x:= rect.x-frame1.left; + y:= rect.y-frame1.top; + end + else begin + x:= rect.x; + y:= rect.y; + end; + width:= rect.cx; + height:= rect.cy; + if width <= 0 then begin + width:= 1; + end; + if height <= 0 then begin + height:= 1; + end; + end; + if not bo1 then begin + {$ifdef FPC} {$checkpointer off} {$endif} + sizehints:= xallocsizehints; + xgetwmnormalhints(appdisp,id,sizehints,@int1); + with sizehints^ do begin + flags:= flags or pposition or psize or usposition or ussize + {or pbasesize} or pwingravity; + x:= changes.x; + y:= changes.y; + width:= changes.width; + height:= changes.height; +// base_width:= width; //openbox does not allow size smaller than this? +// base_height:= height; + if nostaticgravity then begin + win_gravity:= northwestgravity; + end + else begin + win_gravity:= staticgravity; + end; + end; + xsetwmnormalhints(appdisp,id,sizehints); + xfree(sizehints); + end; + {$ifdef mse_debugconfigure} + with changes do begin + debugwindow('*reposwindow '+' '+inttostr(x)+' '+inttostr(y)+ + ' '+inttostr(width)+' '+inttostr(height)+' ',id); + end; + {$endif} + xconfigurewindow(appdisp,id,cwx or cwy or cwwidth or cwheight,@changes); +(* + if nostaticgravity and gui_windowvisible(id) then begin + wmwait; + if (gui_getwindowrect(id,rect1) = gue_ok) and + not rectisequal(rect1,rect) then begin + //simulate staticgravity + with changes do begin + x:= x + rect.x-rect1.x; + y:= y + rect.y-rect1.y; + width:= width + rect.cx-rect1.cx; + height:= height + rect.cy-rect1.cy; + end; + {$ifdef mse_debugconfigure} + with changes do begin + debugwindow('*reposwindow2 '+' '+inttostr(x)+' '+inttostr(y)+ + ' '+inttostr(width)+' '+inttostr(height)+' ',id); + end; + {$endif} + xconfigurewindow(appdisp,id,cwx or cwy or cwwidth or cwheight,@changes); + end; + end; +*) + {$ifdef FPC} {$checkpointer default} {$endif} + result:= gue_ok; +// xflush(appdisp); + gdi_unlock; +end; + +function gui_getdecoratedwindowrect(id: winidty; out arect: rectty): guierrorty; +//var +// frame1: framety; +begin + gdi_lock; + result:= gui_getwindowrect(id,arect); + if result = gue_ok then begin + inflaterect1(arect,getwindowframe(id)) + end; + gdi_unlock; +end; + +function gui_setdecoratedwindowrect(id: winidty; const rect: rectty; + out clientrect: rectty): guierrorty; +var + frame1: framety; +begin + gdi_lock; + frame1:= getwindowframe(id); + with clientrect,frame1 do begin + x:= rect.x + left; + cx:= rect.cx - left - right; + y:= rect.y + top; + cy:= rect.cy - top - bottom; + end; + result:= gui_reposwindow(id,clientrect); + gdi_unlock; +end; + +function gui_setembeddedwindowrect(id: winidty; const rect: rectty): guierrorty; +var + changes: xwindowchanges; +begin + gdi_lock; + fillchar(changes,sizeof(changes),0); + with changes do begin + x:= rect.x; + y:= rect.y; + width:= rect.cx; + height:= rect.cy; + if width <= 0 then begin + width:= 1; + end; + if height <= 0 then begin + height:= 1; + end; + end; + xconfigurewindow(appdisp,id,cwx or cwy or cwwidth or cwheight,@changes); + gdi_unlock(); + result:= gue_ok; +end; + +function gui_setsizeconstraints(id: winidty; const min,max: sizety): guierrorty; +var + sizehints: pxsizehints; + int1: clong; +begin + gdi_lock; + sizehints:= xallocsizehints; + {$ifdef FPC} {$checkpointer off} {$endif} + xgetwmnormalhints(appdisp,id,sizehints,@int1); + with sizehints^ do begin +// flags:= flags or pminsize or pmaxsize; + if (min.cx <> 0) or (min.cy <> 0) then begin + flags:= flags or pminsize; + end + else begin + flags:= flags and not pminsize; + end; + if (max.cx <> 0) or (max.cy <> 0) then begin + flags:= flags or pmaxsize; + end + else begin + flags:= flags and not pmaxsize; + end; + min_width:= min.cx; + min_height:= min.cy; + if max.cx = 0 then begin + max_width:= 30000; + end + else begin + max_width:= max.cx; + end; + if max.cy = 0 then begin + max_height:= 30000; + end + else begin + max_height:= max.cy; + end; + end; + {$ifdef FPC} {$checkpointer default} {$endif} + xsetwmnormalhints(appdisp,id,sizehints); + xfree(sizehints); + result:= gue_ok; + gdi_unlock; +end; + +procedure unmapwindow(id: winidty); +var + ev1: txunmapevent; + root1: winidty; +begin + root1:= gui_getrootwindow(id); + xunmapwindow(appdisp,id); + ev1._type:= unmapnotify; + ev1.event:= root1; + ev1.window:= id; + ev1.from_configure:= 0; + xsendevent(appdisp,root1,{$ifdef xboolean}false{$else}0{$endif}, + substructurenotifymask or substructureredirectmask,@ev1); + //synthetic +end; + +function gui_hidewindow(id: winidty): guierrorty; +begin + gdi_lock; + unsetime(id); + unmapwindow(id); + result:= gue_ok; + gdi_unlock; +end; + +function gui_getparentwindow(const awindow: winidty): winidty; +var + root,parent: winidty;//{$ifdef FPC}dword{$else}xlib.twindow{$endif}; + children: pwinid; +// count: integer; + ca1: longword; +begin + gdi_lock; + result:= 0; + if xquerytree(appdisp,awindow,@root,@parent,@children,@ca1) = 0 then begin + gdi_unlock; + exit; + end; + if children <> nil then begin + xfree(children); + end; + result:= parent; + gdi_unlock; +end; + +function gui_reparentwindow(const child: winidty; const parent: winidty; + const pos: pointty): guierrorty; +var + wi1: winidty; +begin + gdi_lock; + result:= gue_ok; + wi1:= parent; + if wi1 = 0 then begin + wi1:= rootid; + end; + xsync(appdisp,0); + xreparentwindow(appdisp,child,wi1,pos.x,pos.y); + xsync(appdisp,0); + gdi_unlock; +end; + + +function getsyswin(const akind: syswindowty): winidty; +var + at1: atom; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= 0; + case akind of + sywi_tray: begin + at1:= netatoms[net_system_tray_s0]; + if at1 <> 0 then begin + result:= xgetselectionowner(appdisp,at1); + end; + end; + end; +end; + +const + xembedversion = 0; + xembedflagsunmapped = 0; + xembedflagsmapped = 1; + +procedure initxembed(const id: winidty; const flags: int32); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + setlongproperty(id,netatoms[xembed_info],[xembedversion,flags], + netatoms[xembed_info]{cardinalatom}); +end; + +procedure finalizexembed(const id: winidty); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xdeleteproperty(appdisp,id,netatoms[xembed_info]); +end; + +function gui_showsysdock(var awindow: windowty): guierrorty; +begin + gdi_lock; + initxembed(awindow.id,xembedflagsmapped); + result:= gui_showwindow(awindow.id); //xembedflagsmapped + //does not work for some WM's + result:= gue_ok; + gdi_unlock; +end; + +function gui_hidesysdock(var awindow: windowty): guierrorty; +begin + gdi_lock; + initxembed(awindow.id,xembedflagsunmapped); + result:= gui_hidewindow(awindow.id); //xembedflagsunmapped + //does not work for some WM's + result:= gue_ok; + gdi_unlock; +end; + + +const + system_tray_request_dock = 0; + system_tray_begin_message = 1; + system_tray_cancel_message = 2; + +function sendtraymessage(const dest: winidty; const awindow: winidty; + const opcode: integer; + const data1: longword = 0; const data2: longword = 0; + const data3: longword = 0): guierrorty; +var + at1: atom; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= gue_notraywindow; + if dest <> 0 then begin + at1:= netatoms[net_system_tray_opcode]; + if (at1 <> 0) and sendnetcardinalmessage(dest,at1,awindow, + [{currenttime}lasteventtime,opcode,data1,data2,data3]) then begin + result:= gue_ok; + end; + end; +end; + +function removesizehints(id: winidty): guierrorty; +var + sizehints: pxsizehints; +begin + sizehints:= xallocsizehints; + with sizehints^ do begin + flags:= 0; + end; + xsetwmnormalhints(appdisp,id,sizehints); + xfree(sizehints); + result:= gue_ok; +end; + +function gui_docktosyswindow(var child: windowty; + const akind: syswindowty): guierrorty; +var + syswin: winidty; + parentbefore,id1: winidty; + i1: integer; + pt1: pointty; + rect1: rectty; +const + maxwait = 200; //1s +begin + gdi_lock; + gui_hidewindow(child.id); //window must be unmapped for some WM's + xsync(appdisp,0); + if akind = sywi_none then begin + //does not work with newer WM's, + //window must be destroyed + result:= getwindowrect(child.id,rect1,pt1); + if result = gue_ok then begin + result:= gui_reparentwindow(child.id,0,rect1.pos); + end; + finalizexembed(child.id); + end + else begin + result:= gue_windownotfound; + syswin:= getsyswin(akind); + if syswin <> 0 then begin + removesizehints(child.id); + initxembed(child.id,xembedflagsunmapped); +// xdeleteproperty(appdisp,child.id,netatoms[wm_normal_hints]); +// xdeleteproperty(appdisp,child.id,wmclassatom); + parentbefore:= gui_getparentwindow(child.id); + result:= gue_ok; + i1:= 0; + case akind of + sywi_tray: begin + result:= sendtraymessage(syswin,syswin, + system_tray_request_dock,child.id); + end; + end; + repeat + { + case akind of + sywi_tray: begin + result:= sendtraymessage(syswin,syswin, + system_tray_request_dock,child.id); + //does not always work the first time... + end; + end; + } + xsync(appdisp,0); + sys_schedyield; + id1:= gui_getparentwindow(child.id); + if (id1 <> parentbefore) and (id1 <> rootid) then begin + break; + end; + sleep(5); + inc(i1); + until i1 = maxwait; + if i1 >= maxwait then begin + {$ifdef mse_debugxembed} + debugwindow('***error docktosyswindow child ',child.id); + debugwindow(' syswin ',syswin); + {$endif} + result:= gue_docktosyswindow; + end + else begin + {$ifdef mse_debugxembed} + debugwindow('* docktosyswindow attempt:'+inttostr(i1)+' child',child.id); + debugwindow(' syswin ',syswin); + {$endif} + end; + end + else begin + {$ifdef mse_debugxembed} + debugwindow('***error docktosyswindow child:',child.id); + debugwindow(' syswin:',syswin); + {$endif} + end; + end; + gdi_unlock; +end; + +function gui_traymessage(var awindow: windowty; const message: msestring; + out messageid: longword; + const timeoutms: longword = 0): guierrorty; +var + str1: ansistring; + int1: integer; + event1: xclientmessageevent; + po1: pchar; + win1: winidty; + at1: atom; +label + errorlab; +begin + gdi_lock; + result:= gue_notraywindow; + win1:= getsyswin(sywi_tray); + at1:= netatoms[net_system_tray_message_data]; + if (win1 <> 0) and (at1 <> 0) then begin + messageid:= getidnum; + str1:= stringtoutf8ansi(message); + int1:= length(str1); + str1:= str1 + #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0; + result:= sendtraymessage(win1,awindow.id,system_tray_begin_message,timeoutms, + int1,messageid); + if result = gue_ok then begin + fillchar(event1,sizeof(event1),0); + with event1 do begin + xtype:= clientmessage; + display:= appdisp; + xwindow:= awindow.id; + format:= 8; + message_type:= at1; + po1:= pchar(str1); + while (result = gue_ok) and (int1 > 0) do begin + move(po1^,data.b[0],20); + inc(po1,20); + int1:= int1 - 20; + if xsendevent(appdisp,win1,false,0 + {structurenotifymask or substructurenotifymask},@event1) = 0 then begin + result:= gue_sendevent; + end; + end; + end; + xsync(appdisp,0); + end; + end; +errorlab: + gdi_unlock; +end; + +function gui_canceltraymessage(var awindow: windowty; + const messageid: longword): guierrorty; +begin + gdi_lock; + result:= sendtraymessage(getsyswin(sywi_tray),awindow.id, + system_tray_cancel_message,messageid,0,0); + gdi_unlock; +end; + +function gui_settrayicon(var awindow: windowty; + const icon,mask: pixmapty): guierrorty; +begin + result:= gui_setwindowicon(awindow.id,icon,mask); +end; + +function gui_settrayhint(var awindow: windowty; + const hint: msestring): guierrorty; +begin + result:= gue_ok; //dummy +end; + +{$ifndef FPC} +type + tlibhandle = longword; +{$endif} + + +function gui_regiontorects(const aregion: regionty): rectarty; +begin + result:= x11regiontorects(aregion); +end; + +function gui_movewindowrect(id: winidty; const dist: pointty; + const rect: rectty): guierrorty; +var + gc: tgc; +begin + gdi_lock; + gc:= xcreategc(appdisp,id,0,nil); + if gc <> nil then begin + xcopyarea(appdisp,id,id,gc,rect.x,rect.y,rect.cx,rect.cy,rect.x+dist.x, + rect.y+dist.y); + xfreegc(appdisp,gc); + result:= gue_ok; + end + else begin + result:= gue_scroll; + end; + gdi_unlock; +end; + +procedure gui_beep; +begin + gdi_lock; + xbell(appdisp,0); + xflush(appdisp); + gdi_unlock; +end; + +function gui_flushgdi(const synchronize: boolean = false): guierrorty; +begin + gdi_lock; + if synchronize then begin + xsync(appdisp,0); + end + else begin + xflush(appdisp); + end; + result:= gue_ok; + gdi_unlock; +end; + +function msedisplay: pdisplay; +begin + result:= appdisp; +end; + +function msevisual: pvisual; +begin + result:= pvisual(defvisual); +end; + +function msedefaultscreen: pscreen; +begin + result:= defscreen; +end; + +function msedefaultscreenno: integer; +begin + result:= xscreennumberofscreen(defscreen); +end; + +{$ifdef with_sm} +//callbacks +procedure icewatch(_iceConn: IceConn; clientData: IcePointer; + opening: Bool; var watchData: IcePointer); cdecl; +begin + with psminfoty(clientdata)^ do begin + if iceconnection = nil then begin + iceconnection:= _iceconn; + end; + if _iceconn = iceconnection then begin + if (opening <> 0) then begin + fd:= iceconnectionnumber(_iceconn); + end + else begin + fd:= -1; + end; + end; + end; +end; + +procedure SmcSaveYourself(_smcConn: SmcConn; clientData: pointer; + saveType: integer; ashutdown: bool; + ainteractStyle: integer; fast: bool); cdecl; +begin + with psminfoty(clientdata)^ do begin + if (ashutdown <> 0) then begin + shutdown:= true; + interactstyle:= ainteractstyle; + end + else begin + smcsaveyourselfdone(_smcconn,1); + end; + end; +end; + +procedure SmcDie(_smcConn: SmcConn; clientData: pointer); cdecl; +begin +end; + +procedure SmcSaveComplete(_smcConn: SmcConn; clientData: pointer); cdecl; +begin +end; + +procedure SmcShutdownCancelled(_smcConn: SmcConn; + clientData: pointer); cdecl; +begin + with psminfoty(clientdata)^ do begin + shutdown:= false; + shutdownpending:= false; + end; +end; + +procedure interact(_smcConn: SmcConn; clientData: SmPointer); cdecl; +begin + with psminfoty(clientdata)^ do begin + interactgranted:= true; + end; +end; + +{$endif} + +procedure gui_cancelshutdown; +begin +{$ifdef with_sm} + gdi_lock; + if hassm then begin + with sminfo do begin + {$ifdef smdebug} + writeln('gui_cancelshutdown ',shutdown,shutdownpending, + interactwaiting,interactgranted); + {$endif} + if shutdown and shutdownpending and interactgranted then begin + smcinteractdone(smconnection,1); + {$ifdef smdebug} + writeln('gui_cancelshutdown smcinteractdone'); + {$endif} + smcsaveyourselfdone(smconnection,1); + {$ifdef smdebug} + writeln('gui_cancelshutdown smcsaveyourselfdone'); + {$endif} + interactwaiting:= false; + interactgranted:= false; + end; + end; + end; + gdi_unlock; +{$endif} +end; + +var + escapepressed: boolean; + +function gui_escapepressed: boolean; +begin + result:= escapepressed; +end; + +procedure gui_resetescapepressed; +begin + escapepressed:= false; +end; + +function getkeynomod(var xev: {$ifdef FPC}txkeyevent{$else} + xkeyevent{$endif}): keyty; +const + modimask = not (shiftmask or lockmask or controlmask or + mod1mask or mod2mask or mod3mask or + mod4mask or mod5mask); +var +// keysym1: pkeysym; +// int1{,int2}: integer; + ss1: shiftstatesty; +// po1: pcuint; + statebefore: cuint; + keysym1: keysym; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= key_none; + statebefore:= xev.state; + xev.state:= xev.state and modimask or numlockstate; + xlookupstring(@xev,nil,0,@keysym1,nil); + xev.state:= statebefore; + ss1:= []; + result:= xkeytokey(keysym1,ss1); + + (* + {$ifdef fpc} {$checkpointer off} {$endif} + inc(xlockerror); + ss1:= []; + keysym1:= xgetkeyboardmapping(appdisp,xev.keycode,1,@int1); + if keysym1 <> nil then begin + result:= xkeytokey(keysym1^,ss1); + xfree(keysym1); + end; + dec(xlockerror); + {$ifdef fpc} {$checkpointer default} {$endif} +*) +end; + +var + timeoutcount: integer; //for safety timertick + repeatkey: integer; + repeatkeytime: ttime; + +procedure resetrepeatkey(); +begin +{$ifdef mse_debugkey} + debugwriteln('resetrepeatkey key:'+inttostr(repeatkey)+ + ' time:'+inttostr(repeatkeytime)); +{$endif} + repeatkey:= 0; + repeatkeytime:= 0; +end; + +type + tsysdndreader = class //todo: scrolling + private + fwinid: winidty; + fsource: winidty; + fprotocolversion: byte; + faction: atom; + fdataformats: msestringarty; + fformatistext: booleanarty; + fdatatypeatoms: atomarty; + fdata: stringarty; + ftext: msestringarty; + fpos: pointty; + fshiftstate: shiftstatesty; + fscroll: boolean; + fdroptimestamp: longword; + protected + function handleevent(var aevent: xclientmessageevent): tmseevent; + public + constructor create(const aevent: xclientmessageevent); + property winid: winidty read fwinid; + function readdata(var adata: string; + const typeindex: integer): guierrorty; + function readtext(var atext: msestring; + const typeindex: integer): guierrorty; + end; + + sysdndwriterstatety = (sdws_destroying); + sysdndwriterstatesty = set of sysdndwriterstatety; + + tsysdndwriter = class(tlinkedobject) + private + frepeater: tsimpletimer; + fstate: sysdndwriterstatesty; + fintf: isysdnd; + ftimestamp: longword; + fformats: atomarty; + fsource: winidty; + fdest: winidty; + fdestaccepts: boolean; + fpos: pointty; + fentervalues: array[0..4] of longword; + fpositionvalues: array[0..4] of longword; + protected + procedure startcheckrepeater; + procedure docheckrepeat(const sender: tobject); + procedure resetdest; + procedure selectioncleared(var aevent: xselectionclearevent); + function check(const apos: pointty): boolean; + function handleevent(var aevent: xclientmessageevent): tmseevent; + function drop: boolean; + function getdata(var aevent: xselectionrequestevent; + var adata: string; var aproperty: atom): boolean; + //false if no data + procedure objevent(const sender: iobjectlink; + const event: objecteventty); override; + public + constructor create(const aintf: isysdnd; const asource: winidty); + destructor destroy; override; + end; + +var + sysdndreader: tsysdndreader; + sysdndwriter: tsysdndwriter; + +{ tsysdndreader } + +constructor tsysdndreader.create(const aevent: xclientmessageevent); +var + lwo1: longword; + int1,int2: integer; + ar1: atomarty; +begin + freeandnil(sysdndwriter); + with aevent do begin + fwinid:= xwindow; + fsource:= data.l[0]; + lwo1:= data.l[1]; + fprotocolversion:= lwo1 shr 24; + faction:= data.l[4]; + if lwo1 and 1 <> 0 then begin //more than 3 types + //todo: suport for inc protocol + readatomproperty(fsource,xdndatoms[xdnd_typelist],ar1); + end + else begin + setlength(ar1,3); + move(data.l[2],ar1[0],3*sizeof(ar1[0])); + end; + setlength(fdataformats,length(ar1)); + setlength(fdatatypeatoms,length(ar1)); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> 0 then begin + fdatatypeatoms[int2]:= ar1[int1]; + fdataformats[int2]:= msestring(xgetatomname(appdisp,ar1[int1])); + inc(int2); + end; + end; + setlength(fdataformats,int2); + setlength(fdata,int2); + setlength(ftext,int2); + fformatistext:= nil; + setlength(fformatistext,int2); + end; +end; + +function tsysdndreader.readdata(var adata: string; + const typeindex: integer): guierrorty; +var + acttype: atom; + actformat: cint; + nitems: integer; +begin + if (typeindex < 0) or (typeindex > high(fdatatypeatoms)) then begin + result:= gue_index; + end + else begin + result:= gue_ok; + if fdata[typeindex] = '' then begin + result:= pastefromclipboard(fdata[typeindex],xdndatoms[xdnd_selection], + fdroptimestamp,[fdatatypeatoms[typeindex]],acttype,actformat,nitems); + end; + if result = gue_ok then begin + adata:= fdata[typeindex]; + end; + end; +end; + +function tsysdndreader.readtext(var atext: msestring; + const typeindex: integer): guierrorty; +var + acttype: atom; + actformat: cint; + nitems: integer; +begin + if (typeindex < 0) or (typeindex > high(fdatatypeatoms)) then begin + result:= gue_index; + end + else begin + result:= gue_ok; + if ftext[typeindex] = '' then begin + result:= pastefromclipboard(fdata[typeindex],xdndatoms[xdnd_selection], + fdroptimestamp,[fdatatypeatoms[typeindex]],acttype,actformat,nitems); + if result = gue_ok then begin + ftext[typeindex]:= msestring(fdata[typeindex]); + end; + end; + if result = gue_ok then begin + atext:= ftext[typeindex]; + end; + end; +end; + +function tsysdndreader.handleevent(var aevent: xclientmessageevent): tmseevent; + + function checkhandler(const updateposition: boolean): boolean; + begin + result:= false; + if sysdndreader <> nil then begin + if (sysdndreader.winid <> aevent.xwindow) or + (aevent.data.l[0] <> sysdndreader.fsource) then begin + freeandnil(sysdndreader); //there is something wrong + end + else begin + result:= true; + if updateposition then begin + with aevent,sysdndreader do begin + fpos:= mp(longword(data.l[2]) shr 16,data.l[2] and $ffff); + fshiftstate:= xtoshiftstate(data.l[1] and $ff,key_none,mb_none,false); + fscroll:= data.l[1] and (1 shl 10) <> 0; + faction:= data.l[4]; + end; + end; + end; + end; + end; //checkhandler + + function createevent(const akind: drageventkindty): tsysdndevent; + var + act1: dndactionty; + act2: dndactionsty; + begin + with sysdndreader do begin + act2:= []; + for act1:= low(dndactionty) to high(dndactionty) do begin + if xdndactionatoms[act1] = faction then begin + include(act2,act1); + break; + end; + end; + result:= tsysdndevent.create(akind,fwinid,fpos,fshiftstate, + fscroll,fdataformats,fformatistext,act2); + end; + end; //createevent + +begin + result:= nil; + with aevent do begin + if message_type = xdndatoms[xdnd_position] then begin + if checkhandler(true) then begin + result:= createevent(dek_check); + end; + end + else begin + if message_type = xdndatoms[xdnd_drop] then begin + if checkhandler(false) then begin + result:= createevent(dek_drop); + sysdndreader.fdroptimestamp:= data.l[2]; + end; + end + else begin + if message_type = xdndatoms[xdnd_leave] then begin + result:= createevent(dek_leavesysdnd); + freeandnil(sysdndreader); + end; + end; + end; + end; +end; + +function getactionatom(const aactions: dndactionsty): atom; +var + act1: dndactionty; +begin + result:= 0; + for act1:= low(dndactionty) to high(dndactionty) do begin + if act1 in aactions then begin + result:= xdndactionatoms[act1]; + break; + end; + end; +end; + +{ tsysdndwriter } + +constructor tsysdndwriter.create(const aintf: isysdnd; const asource: winidty); +var + ar1: msestringarty; + int1: integer; +// act1: dndactionty; +// act2: dndactionsty; +begin + fintf:= aintf; + getobjectlinker.link(iobjectlink(self),aintf); + fsource:= asource; + ftimestamp:= lasteventtime; + freeandnil(sysdndreader); + fentervalues[0]:= fsource; + fpositionvalues[0]:= fsource; + fpositionvalues[3]:= ftimestamp; + fpositionvalues[4]:= getactionatom(aintf.getactions); + ar1:= aintf.getformats; + setlength(fformats,length(ar1)); //todo: what about empty types? + for int1:= 0 to high(ar1) do begin + fformats[int1]:= xinternatom(appdisp,pchar(string(ar1[int1])), + {$ifdef xboolean}false{$else}0{$endif}); + if int1 <= high(fentervalues)-2 then begin + fentervalues[int1+2]:= fformats[int1]; + end; + end; + if high(fformats) > 2 then begin + setlongproperty(fsource,xdndatoms[xdnd_typelist],ulongarty(fformats),atomatom); + end; + gdi_lock; + xsetselectionowner(appdisp,xdndatoms[xdnd_selection],fsource,ftimestamp); + gdi_unlock; +end; + +destructor tsysdndwriter.destroy; +begin + include(fstate,sdws_destroying); + gdi_lock; + resetdest; + xsetselectionowner(appdisp,xdndatoms[xdnd_selection],0,ftimestamp); + //release selection + xdeleteproperty(appdisp,appid,xdndatoms[xdnd_typelist]); + gdi_unlock; + if fintf <> nil then begin + fintf.cancelsysdnd; + end; + inherited; +end; + +procedure tsysdndwriter.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + inherited; + if (sender = fintf) and (event = oe_destroyed) then begin + fintf:= nil; + if not (sdws_destroying in fstate) then begin + freeandnil(sysdndwriter); + end; + end; +end; + +procedure tsysdndwriter.selectioncleared(var aevent: xselectionclearevent); +begin + if laterorsame(ftimestamp,aevent.time) then begin + if fintf <> nil then begin + fintf.cancelsysdnd; + end; + if sysdndwriter <> nil then begin //??? + sysdndwriter:= nil; + inherited destroy; + end; + end; +end; + +procedure tsysdndwriter.resetdest; +begin + if fdest <> 0 then begin + freeandnil(frepeater); + fdestaccepts:= false; + sendnetcardinalmessage(fdest,xdndatoms[xdnd_leave],fdest,[fsource]); + fdest:= 0; + freeandnil(frepeater); + end; +end; + +function tsysdndwriter.check(const apos: pointty): boolean; +var + ar1: atomarty; + ar2: winidarty; + int1: integer; +begin + result:= false; + ar2:= windowsatpos(apos); + for int1:= high(ar2) downto 0 do begin + if readatomproperty(ar2[int1],xdndatoms[xdnd_aware],ar1) and + (high(ar1) = 0) then begin + if ar2[int1] <> fdest then begin + if fdest <> 0 then begin + fdestaccepts:= false; + sendnetcardinalmessage(fdest,xdndatoms[xdnd_leave],fdest,[fsource]); + end; + fdest:= ar2[int1]; + if ar1[0] < 3 then begin + ar1[0]:= 3; + end + else begin + if ar1[0] > 4 then begin + ar1[0]:= 4; + end; + end; + ar1[0]:= ar1[0] shr 24; + if high(fformats) > 2 then begin + ar1[0]:= ar1[0] or 1; + end; + fentervalues[1]:= ar1[0]; + sendnetcardinalmessage(fdest,xdndatoms[xdnd_enter],fdest,fentervalues); + end; + fpos:= apos; + fpositionvalues[2]:= (fpos.x shl 16) or (fpos.y and $ffff); + fpositionvalues[4]:= getactionatom(fintf.getactions); + sendnetcardinalmessage(fdest,xdndatoms[xdnd_position],fdest,fpositionvalues); + result:= true; + startcheckrepeater; + exit; + end; + end; + if fdest <> 0 then begin + application.postevent(tsysdndstatusevent.create(fintf.geteventintf,false)); + end; + resetdest; +end; + +procedure tsysdndwriter.docheckrepeat(const sender: tobject); +begin + sendnetcardinalmessage(fdest,xdndatoms[xdnd_position],fdest,fpositionvalues); +end; + +const + checkrepeatinterval = 200000; + +procedure tsysdndwriter.startcheckrepeater; +begin + if frepeater = nil then begin + frepeater:= tsimpletimer.create(checkrepeatinterval, + {$ifdef FPC}@{$endif}docheckrepeat,true,[]); + end + else begin + frepeater.interval:= checkrepeatinterval; + end; +end; + +function tsysdndwriter.handleevent(var aevent: xclientmessageevent): tmseevent; +begin + result:= nil; + with aevent do begin + if (message_type = xdndatoms[xdnd_status]) then begin + if (fdest <> 0) and (data.l[0] = fdest) then begin + fdestaccepts:= data.l[1] and 1 <> 0; + result:= tsysdndstatusevent.create(fintf.geteventintf,fdestaccepts); + end; + end + else begin + if (message_type = xdndatoms[xdnd_finished]) then begin + freeandnil(sysdndwriter); + end; + end; + end; +end; + +function tsysdndwriter.drop: boolean; +begin + result:= true; + sendnetcardinalmessage(fdest,xdndatoms[xdnd_drop],fdest, + [fsource,0,ftimestamp]); +end; + +function tsysdndwriter.getdata(var aevent: xselectionrequestevent; + var adata: string; var aproperty: atom): boolean; +var + int1: integer; +begin + result:= false; + with aevent do begin + for int1:= 0 to high(fformats) do begin + if fformats[int1] = target then begin + adata:= fintf.convertmimedata(int1); + result:= true; + break; + end; + end; + end; + if not result then begin + aproperty:= none; + end; +end; + +function gui_sysdnd(const action: sysdndactionty; + const aintf: isysdnd; const arect: rectty; + out aresult: boolean): guierrorty; +var + act1: atom; +begin + aresult:= false; + result:= gue_nodragpending; + if sysdndwriter <> nil then begin + result:= gue_ok; + case action of + sdnda_begin: begin + freeandnil(sysdndwriter); + sysdndwriter:= tsysdndwriter.create(aintf,appid); + end; + sdnda_finished: begin + if sysdndwriter <> nil then begin + if not sysdndwriter.fdestaccepts then begin //todo: timeout + freeandnil(sysdndwriter); + end; + end; + end; + sdnda_destroyed: begin + freeandnil(sysdndwriter); + end; + sdnda_check: begin + aresult:= sysdndwriter.check(arect.pos); + end; + sdnda_drop: begin + aresult:= sysdndwriter.drop; + end; + else begin + result:= gue_error; + end; + end; + end + else begin + if sysdndreader <> nil then begin + //todo: use limit rectangle + result:= gue_ok; + with sysdndreader do begin + if aintf <> nil then begin + act1:= getactionatom(aintf.getactions); + end + else begin + act1:= faction; + end; + case action of + sdnda_reject: begin + sendnetcardinalmessage(fsource,xdndatoms[xdnd_status],fsource, + [fwinid,2,0,0,act1]); //always get position messages + end; + sdnda_accept: begin + sendnetcardinalmessage(fsource,xdndatoms[xdnd_status],fsource, + [fwinid,3,0,0,act1]); //always get position messages + end; + sdnda_finished: begin + sendnetcardinalmessage(fsource,xdndatoms[xdnd_finished],fsource, + [fwinid,1,act1]); //always accepted + freeandnil(sysdndreader); + end; + else begin + result:= gue_error; + end; + end; + end; + end + else begin //writer = nil + result:= gue_ok; + case action of + sdnda_begin: begin + sysdndwriter:= tsysdndwriter.create(aintf,appid); + end; + else begin + result:= gue_nodragpending; + end; + end; + end; + end; +end; + +function gui_sysdndreaddata(var adata: string; + const typeindex: integer): guierrorty; +begin + result:= gue_nodragpending; + if sysdndreader <> nil then begin + result:= sysdndreader.readdata(adata,typeindex); + end; +end; + +function gui_sysdndreadtext(var atext: msestring; + const typeindex: integer): guierrorty; +begin + result:= gue_nodragpending; + if sysdndreader <> nil then begin + result:= sysdndreader.readtext(atext,typeindex); + end; +end; + +function handlexdnd(var aevent: xclientmessageevent): tmseevent; + +begin + result:= nil; + with aevent do begin + if sysdndwriter <> nil then begin + result:= sysdndwriter.handleevent(aevent); + end + else begin + if message_type = xdndatoms[xdnd_enter] then begin + freeandnil(sysdndreader); + sysdndreader:= tsysdndreader.create(aevent); + end + else begin + if sysdndreader <> nil then begin + result:= sysdndreader.handleevent(aevent); + end; + end; + end; + end; +end; + +function getclipboarddata(var aevent: xselectionrequestevent; + const buffer: clipboardbufferty; + var adata: string; var aproperty: atom): boolean; + //false if no data +var + atomar: array[0..7] of atom; + textprop: xtextproperty; +begin + with aevent,clipboardbuffers[buffer] do begin + result:= false; + if target = targetsatom then begin + atomar[0]:= textplainatom; + atomar[1]:= utf8_stringatom; + atomar[2]:= compound_textatom; + atomar[3]:= stringatom; + atomar[4]:= textatom; + atomar[5]:= targetsatom; + atomar[6]:= timestampatom; +// atomar[7]:= multipleatom; //not implemented + xchangeproperty(appdisp,requestor,aproperty,atomatom,32, + propmodereplace,@atomar[0],7); + end + else begin + if target = timestampatom then begin + atomar[0]:= timestamp; + xchangeproperty(appdisp,requestor,aproperty,target,32, + propmodereplace,@atomar[0],1); + end + else begin + result:= true; + if target = utf8_stringatom then begin + adata:= stringtoutf8ansi(buffer); + end + else begin + if target = stringatom then begin + adata:= stringtolatin1(buffer); + end + else begin + if (target = textatom) or (target = textplainatom) then begin + adata:= ansistring(buffer); //current locale + end + else begin + result:= false; + if target = compound_textatom then begin + if stringtotextproperty(buffer,xcompoundtextstyle, + textprop) then begin + with textprop do begin + xchangeproperty(appdisp,requestor, + {$ifdef FPC}_property{$else}xproperty{$endif},encoding, + format,propmodereplace,value,nitems); + xfree(value); + end; + end + else begin + aproperty:= none; + end; + end + else begin + aproperty:= none; + end; + end; + end; + end; + end; + end; + end; +end; + +function isclipboard(const aselection: atom; + out buffer: clipboardbufferty): boolean; +var + buf1: clipboardbufferty; +begin + result:= false; + for buf1:= low(clipboardbufferty) to high(clipboardbufferty) do begin + if clipboardbuffers[buf1].name = aselection then begin + buffer:= buf1; + result:= true; + break; + end; + end; +end;//isclipboard + +procedure handleselectionrequest(var aevent: xselectionrequestevent); +var + event1: xselectionevent; + str1: string; + bo1: boolean; + buffer: clipboardbufferty; + +begin + with aevent do begin + event1.xtype:= selectionnotify; + event1.requestor:= requestor; + event1.selection:= selection; + if {$ifdef FPC}_property{$else}xproperty{$endif} = none then begin + {$ifdef FPC}_property{$else}xproperty{$endif}:= target; + end; + event1.target:= target; + event1.{$ifdef FPC}_property{$else}xproperty{$endif}:= + {$ifdef FPC}_property{$else}xproperty{$endif}; + event1.time:= time; + bo1:= false; + if isclipboard(selection,buffer) then begin + bo1:= getclipboarddata(aevent,buffer,str1, + event1.{$ifdef FPC}_property{$else}xproperty{$endif}); + end + else begin + if (selection = xdndatoms[xdnd_selection]) and + (sysdndwriter <> nil) then begin + bo1:= sysdndwriter.getdata(aevent,str1, + {$ifdef FPC}_property{$else}xproperty{$endif}); + end + else begin + {$ifdef FPC}_property{$else}xproperty{$endif}:= none; + end; + end; + if bo1 then begin + xchangeproperty(appdisp,requestor, + {$ifdef FPC}_property{$else}xproperty{$endif},target,8, + propmodereplace,pbyte(pchar(str1)),length(str1)); + end; + xsendevent(appdisp,requestor,{$ifdef xboolean}false{$else}0{$endif},0, + @event1); + end; +end; + +var + connectmutex1: mutexty; + connectmutex2: mutexty; + +procedure gui_disconnectmaineventqueue(); //called by gdi_lock() +begin + sys_mutexlock(connectmutex2); + if sys_mutextrylock(connectmutex1) <> sye_ok then begin + sys_write(connectpipe.writedes,@dummybyte,1); + sys_mutexlock(connectmutex1); + end; +end; + +procedure gui_connectmaineventqueue(); //called by gdi_unlock() +begin + sys_mutexunlock(connectmutex1); + sys_mutexunlock(connectmutex2); +end; + +type + pollinfoarty = array of pollfd; + pollinfoty = record + callback: pollcallbackty; + data: pointer; + end; + pollinfodestarty = array of pollinfoty; + pollinfty = record + pollinfo: pollinfoarty; + pollinfodest: pollinfodestarty; + end; + ppollinfty = ^pollinfty; + +var +// pollinfo: array[0..2] of pollfd; + //0 connection, 1 sessionmanagement + pollinf: ppollinfty; + +function gui_addpollfd(var id: int32; const afd: int32; + const aflags: pollflagsty; + const acallback: pollcallbackty = nil; + const adata: pointer = nil): guierrorty; +begin + result:= gue_ok; + with pollinf^ do begin + setlength(pollinfo,high(pollinfo)+2); + setlength(pollinfodest,length(pollinfo)); + id:= high(pollinfo); + with pollinfo[id] do begin + fd:= afd; + events:= int32(aflags * [pf_in,pf_pri,pf_out]); + with pollinfodest[id] do begin + callback:= acallback; + data:= adata; + end; + end; + end; +end; + +function gui_removepollfd(const id: int32): guierrorty; +begin + with pollinf^ do begin + if (id < 0) or (id > high(pollinfo)) then begin + result:= gue_index; + end + else begin + deleteitem(pollinfo,typeinfo(pollinfo),id); + deleteitem(pollinfodest,typeinfo(pollinfodest),id); + result:= gue_ok; + end; + end; +end; + +function gui_setpollfdactive(const id: int32; + const aactive: boolean): guierrorty; +begin + with pollinf^ do begin + if (id < 0) or (id > high(pollinfo)) then begin + result:= gue_index; + end + else begin + with pollinfo[id] do begin + if (fd >= 0) xor aactive then begin + if fd = 0 then begin + fd:= minint; + end + else begin + if fd = minint then begin + fd:= 0; + end + else begin + fd:= -fd; + end; + end; + end; + end; + result:= gue_ok; + end; + end; +end; + +{$ifdef mse_debugsysevent} + +function eventname(const event: int32): string; +begin + case event of + 2: result:= 'KeyPress'; + 3: result:= 'KeyRelease'; + 4: result:= 'ButtonPress'; + 5: result:= 'ButtonRelease'; + 6: result:= 'MotionNotify'; + 7: result:= 'EnterNotify'; + 8: result:= 'LeaveNotify'; + 9: result:= 'FocusIn'; + 10: result:= 'FocusOut'; + 11: result:= 'KeymapNotify'; + 12: result:= 'Expose'; + 13: result:= 'GraphicsExpose'; + 14: result:= 'NoExpose'; + 15: result:= 'VisibilityNotify'; + 16: result:= 'CreateNotify'; + 17: result:= 'DestroyNotify'; + 18: result:= 'UnmapNotify'; + 19: result:= 'MapNotify'; + 20: result:= 'MapRequest'; + 21: result:= 'ReparentNotify'; + 22: result:= 'ConfigureNotify'; + 23: result:= 'ConfigureRequest'; + 24: result:= 'GravityNotify'; + 25: result:= 'ResizeRequest'; + 26: result:= 'CirculateNotify'; + 27: result:= 'CirculateRequest'; + 28: result:= 'PropertyNotify'; + 29: result:= 'SelectionClear'; + 30: result:= 'SelectionRequest'; + 31: result:= 'SelectionNotify'; + 32: result:= 'ColormapNotify'; + 33: result:= 'ClientMessage'; + 34: result:= 'MappingNotify'; + 35: result:= 'GenericEvent'; + else result:= ''; + end; +end; + +procedure debugevent(const aevent: xevent); +var + atomar: atomarty; + i1: int32; +begin + debugwrite(debugwindow1('sysevent ',aevent.xany.xwindow)+' '+ + inttostr(aevent.xany.xtype)+' '+eventname(aevent.xany.xtype)); + case aevent.xany.xtype of + propertynotify: begin + debugwrite(' '+xgetatomname(appdisp,aevent.xproperty.atom)); + if aevent.xproperty.atom = wmstateatom then begin + debugwrite(' '+getenumname(typeinfo(wmstatety), + ord(getwmstate(aevent.xproperty.xwindow)))); + end + else begin + if aevent.xproperty.atom = netatoms[net_wm_state] then begin + readatomproperty(aevent.xproperty.xwindow,netatoms[net_wm_state],atomar); + debugwrite(':'); + for i1:= 0 to high(atomar) do begin + debugwrite(' '+xgetatomname(appdisp,atomar[i1])); + end; + end; + end; + end; + end; + debugwriteln(''); +end; +{$endif} + +var + hasminimizeunmapworkaround: boolean; //for gnome + lastmapwindow: xid; + +function windowdestroyed(const w: winidty): boolean; +var + xev2: txevent; +begin + xsync(appdisp,0); + result:= xchecktypedwindowevent(appdisp,w,destroynotify,@xev2); +end; + +function gui_getevent: tmseevent; + + function checkrepeatkey(const aevent: xevent): boolean; + begin + if (repeatkey = aevent.xkey.keycode) and + (repeatkeytime = aevent.xkey.time) then begin + {$ifdef mse_debugkey} + debugwriteln('is repeatkey key:'+inttostr(repeatkey)+ + ' time:'+inttostr(repeatkeytime)); + {$endif} + result:= true; + end + else begin + resetrepeatkey(); + result:= false; + end; + end;//checkrepeatkey + +var + xev,xev2: xevent; +// w: winidty; + eventkind: eventkindty; + akey: keysym; + buffer: string; + icstatus: tstatus; + chars: msestring; + i1,i2: integer; +// event: xevent; +// str1: string; +{$ifdef with_sm} + int2: integer; +{$endif} + shiftstate1: shiftstatesty; + key1,key2: keyty; + button1: mousebuttonty; + bo1: boolean; + rect1: rectty; + pt1: pointty; + aic: xic; + window1: twindow; + buf1: clipboardbufferty; + fdwakeup: boolean; + allsig,sig1: sigset_t; + timeout1: timespec; + b1: boolean; + win1: twindow; + +type + char_0_19 = array[0..19] of char; + +label + eventrestart; +begin + result:= nil; + sigfillset(allsig); + timeout1.tv_sec:= 10; + timeout1.tv_nsec:= 0; + fdwakeup:= false; + while not fdwakeup do begin + if timerevent then begin + application.postevent(tmseevent.create(ek_timer)); + timerevent:= false; + end; + if terminated then begin + application.postevent(tmseevent.create(ek_terminate)); + terminated:= false; + end; + if childevent then begin + childevent:= false; + handlesigchld; + end; + if gui_hasevent then begin + break; + end; + + pthread_sigmask(sig_block,@allsig,@sig1); //block signals + if not timerevent and not terminated and not childevent then begin + repeat + if not application.unlock() then begin + guierror(gue_notlocked); + end; + + sys_mutexlock(connectmutex1); +// int1:= poll(@pollinfo[0],length(pollinfo),1000); +// //todo: use ppoll? no timeout? + with pollinf^ do begin + i1:= ppoll(@pollinfo[0],length(pollinfo),@timeout1,@sig1); + if pollinfo[1].revents <> 0 then begin + repeat //empty pipe + until (__read(connectpipe.readdes,dummybyte,1) < 0) and + (sys_getlasterror() = ewouldblock); + end; + sys_mutexunlock(connectmutex1); + sys_mutexlock(connectmutex2); + sys_mutexunlock(connectmutex2); + + if i1 > 0 then begin + for i2:= 0 to high(pollinfo) do begin + with pollinfo[i2] do begin + if (fd >= 0) then begin + with pollinfodest[i2] do begin + if (callback <> nil) and (revents <> 0) then begin + callback(pollflagsty(card32(card16(revents))),data); + fdwakeup:= true; + end; + end; + end; + end; + end; + end; + end; + //wakeup clientmessages are sometimes missed with xcb ??? + if i1 = 0 then begin //timeout + inc(timeoutcount); + if timeoutcount mod 1 = 0 then begin + timerevent:= true; //every 10 seconds without messages + //in case of lost timer alarm + end; + end; + application.lock; + until (i1 <> -1) or timerevent or terminated or childevent or fdwakeup; + pthread_sigmask(sig_setmask,@sig1,nil); //enable signals + {$ifdef with_sm} + if hassm then begin + if (i1 > 0) and (pollinf^.pollinfo[2].revents <> 0) then begin + iceprocessmessages(sminfo.iceconnection,nil,int2); + with sminfo do begin + if shutdown then begin + if not shutdownpending then begin + interactgranted:= false; + shutdownpending:= true; + if (interactstyle = sminteractstyleerrors) or + (interactstyle = sminteractstyleany) then begin + if SmcInteractRequest(smconnection,smdialognormal, + {$ifdef FPC}@{$endif}interact,@sminfo) = 0 then begin + {$ifdef smdebug} + writeln('gui_getevent SmcInteractRequest'); + {$endif} + terminated:= true; + end + else begin + interactwaiting:= true; + end; + end + else begin + interactwaiting:= false; + terminated:= true; + end; + end + else begin + if interactwaiting and interactgranted then begin + terminated:= true; + interactwaiting:= false; + end; + end; + end; + end; + end; + end; +{$endif} + end + else begin + pthread_sigmask(sig_setmask,@sig1,nil); //enable signals + end; + end; + +eventrestart: + b1:= false; + while true do begin + i1:= xpending(appdisp); + if i1 > 0 then begin + xnextevent(appdisp,@xev); + if (xev.xtype = keyrelease) then begin + {$ifdef mse_debugkey} + debugwriteln('repeatkey start pending:'+inttostr(i1)); + {$endif} + if i1 < 2 then begin + xsync(appdisp,0); + i1:= xpending(appdisp) + 1; + {$ifdef mse_debugkey} + debugwriteln('repeatkey second pending:'+inttostr(i1)); + {$endif} + end; + if i1 > 1 then begin + xpeekevent(appdisp,@xev2); + if (xev2.xtype = keypress) and + (xev.xkey.keycode = xev2.xkey.keycode) and + (xev.xkey.time = xev2.xkey.time) then begin + repeatkey:= xev.xkey.keycode; + repeatkeytime:= xev.xkey.time; + {$ifdef mse_debugkey} + debugwriteln('repeatkey key:'+inttostr(repeatkey)+ + ' time:'+inttostr(repeatkeytime)); + {$endif} + end; + end; + end; + {$ifdef mse_debugsysevent} + debugevent(xev); + {$endif} + if longint(xfilterevent(@xev,none)) = 0 then begin + b1:= true; + break; + end + else begin + {$ifdef mse_debugsysevent} + debugwriteln('sysevent filtered'); + {$endif} + end; + end + else begin + break; + end; + end; + if not b1 then begin + {$ifdef mse_debugsysevent} + debugwriteln('sysevent exit'); + {$endif} + exit; + end; + + bo1:= false; + tguiapplication1(application).sysevent(xev.xany.xwindow,syseventty(xev),bo1); + if bo1 then begin + exit; + end; + if xev.xany.xwindow = appid then begin + if (xev.xtype = selectionclear) then begin + if isclipboard(xev.xselectionclear.selection,buf1) then begin + clipboardbuffers[buf1].buffer:= ''; + exit; + end; + if (xev.xselectionclear.selection = xdndatoms[xdnd_selection]) and + (sysdndwriter <> nil) then begin + sysdndwriter.selectioncleared(xev.xselectionclear); + end; + end + else begin + if xev.xtype = selectionrequest then begin + handleselectionrequest(xev.xselectionrequest); + exit; + end; + end; + end; + case xev.xtype of + clientmessage: begin + with xev.xclient do begin + if display = appdisp then begin + if message_type = mseclientmessageatom then begin + result:= tmseevent(getclientpointer(xev.xclient)); + end + else begin + if message_type = wmprotocolsatom then begin + if longword(data.l[0]) = wmprotocols[wm_delete_window] then begin + result:= twindowevent.create(ek_close,xwindow); +{$ifdef with_saveyourself} + end + else begin + if longword(data.l[0]) = wmprotocols[wm_save_yourself] then begin + result:= tevent.create(ek_terminate); + saveyourselfwindow:= window; + end; + end; +{$else} + end; +{$endif} + end + else begin + {$ifdef mse_debugxembed} + if (netatoms[xembed] <> 0) and + (message_type = netatoms[xembed]) then begin + debugwindow('*xembed ',window); + writeln(' ',inttohex(data.l[0],8),' ', + inttohex(data.l[1],8),' ', + inttohex(data.l[2],8),' ', + inttohex(data.l[3],8),' ', + inttohex(data.l[4],8)); + end; + if (netatoms[net_system_tray_message_data] <> 0) and + (message_type = netatoms[net_system_tray_message_data]) then begin + debugwindow( + '*net_system_tray_message_data format:'+inttostr(format)+' ',window); + writeln(' ',char_0_19(data.b)); + end; + if (netatoms[net_system_tray_opcode] <> 0) and + (message_type = netatoms[net_system_tray_opcode]) then begin + debugwindow( + '*net_system_tray_opcode format:'+inttostr(format)+' ',window); + writeln(' ',inttohex(data.l[0],8),' ', + inttohex(data.l[1],8),' ', + inttohex(data.l[2],8),' ', + inttohex(data.l[3],8),' ', + inttohex(data.l[4],8)); + end; + {$endif} + result:= handlexdnd(xev.xclient); + end; + end; + end; + end; + end; + propertynotify: begin + with xev.xproperty do begin + if atom = wmstateatom then begin //gnome workaround, missing unmap/map + if application.findwindow(xwindow,win1) then begin + if windowdestroyed(xwindow) then begin + result:= twindowevent.create(ek_destroy,xwindow); + end + else begin + case getwmstate(xwindow) of + wms_iconic: begin + if windowmapped(xwindow) then begin + result:= twindowevent.create(ek_hide,xwindow); + hasminimizeunmapworkaround:= true; + lastmapwindow:= 0; + {$ifdef mse_debugsysevent} + debugwriteln(' synthetic ek_hide'); + {$endif} + end; + end; + wms_normal: begin + if hasminimizeunmapworkaround and + (lastmapwindow <> xwindow) then begin + lastmapwindow:= 0; + result:= twindowevent.create(ek_show,xwindow); + {$ifdef mse_debugsysevent} + debugwriteln(' synthetic ek_show'); + {$endif} + end; + end; + end; + end; + end; + end; + end; + end; + enternotify: begin + with xev.xcrossing do begin + result:= tmouseenterevent.create(xwindow, + makepoint(x,y),xtoshiftstate(state,key_none,mb_none,false), + time*1000); + end; + end; + leavenotify: begin + with xev.xcrossing do begin + if mode = notifynormal then begin //?? + result:= twindowevent.create(ek_leavewindow,xwindow); + end; + end; + end; + motionnotify: begin + with xev.xmotion do begin + lasteventtime:= time; + result:= tmouseevent.create(xwindow,false,mb_none,mw_none, + makepoint(x,y),xtoshiftstate(state,key_none,mb_none,false),time*1000); + end; + end; + keypress: begin + with xev.xkey do begin + b1:= false; + {$ifdef FPC} + aic:= getic(window); + {$else} + aic:= getic(xwindow); + {$endif} + lasteventtime:= time; + setlength(buffer,20); + i1:= xutf8lookupstring(aic,@xev.xkey,@buffer[1],length(buffer), + @akey,@icstatus); + setlength(buffer,i1); + if icstatus = xbufferoverflow then begin + xutf8lookupstring(aic,@xev.xkey,@buffer[1],length(buffer),@akey,@icstatus); + end; + chars:= utf8tostringansi(buffer); + {$ifdef mse_debugkey} + debugwriteln('*X11keypress window '+hextostr(window,8)+'"'+buffer+'" key:'+ + inttostr(akey)+' time:'+inttostr(time)); + {$endif} + case icstatus of + xlookupnone: exit; + xlookupchars: akey:= 0; + xlookupkeysym_: chars:= ''; + end; + {$ifdef mse_debugkey} + debugwriteln('after icstatuscheck'); + {$endif} + shiftstate1:= []; + key1:= xkeytokey(akey,shiftstate1); + if key1 = key_escape then begin + escapepressed:= true; + end; + shiftstate1:= shiftstate1 + xtoshiftstate(state,key1,mb_none,false); + if checkrepeatkey(xev) then begin + include(shiftstate1,ss_repeat); + end; + if (keycode = repeatkey) and (time = repeatkeytime) then begin + include(shiftstate1,ss_repeat); + resetrepeatkey; + end; + key2:= getkeynomod(xev.xkey); + result:= tkeyevent.create(xwindow,false,key1,key2, + shiftstate1,chars,time*1000); + end; + end; + keyrelease: begin + with xev.xkey do begin + lasteventtime:= time; + if checkrepeatkey(xev) then begin + {$ifdef mse_debugkey} + debugwriteln('keyrelease dropped, eventrestart'); + {$endif} + goto eventrestart; + end; + i1:= keycode; + xlookupstring(@xev.xkey,nil,0,@akey,nil); + {$ifdef mse_debugkey} + debugwriteln('*X11keyrelease window '+hextostr(window,8)+ + ' key:'+inttostr(akey)+' time:'+inttostr(time)); + {$endif} + shiftstate1:= []; + key1:= xkeytokey(akey,shiftstate1); + key2:= getkeynomod(xev.xkey); + shiftstate1:= shiftstate1 + xtoshiftstate(state,key1,mb_none,true); + (* does not work anymore because of intermediate messages by IM + if xpending(appdisp) > 0 then begin + xpeekevent(appdisp,@xev); + if (xev.xtype = keypress) and (time - lasteventtime < 10) and + (keycode = int1) then begin + repeatkey:= int1; + repeatkeytime:= time; + {$ifdef mse_debugkey} + debugwriteln('eventrestart'); + {$endif} + goto eventrestart; //auto repeat key, don't send + end; + end; + *) + result:= tkeyevent.create(xwindow,true,key1,key2,shiftstate1,'',time*1000); + end; + end; + buttonpress,buttonrelease: begin + with xev.xbutton do begin + {$ifdef mse_debugmouse} + if xtype = buttonpress then begin + debugwrite('*X11buttonpress'); + end + else begin + debugwrite('*X11buttonrelease'); + end; + debugwriteln(' window '+hextostr(window,8)+ + ' button:'+inttostr(button)+' x:'+inttostr(x)+' y:'+inttostr(y)+ + ' time:'+inttostr(time)); + {$endif} + lasteventtime:= time; + button1:= xtomousebutton(button); + shiftstate1:= xtoshiftstate(state,key_none,button1,xev.xtype=buttonrelease); + if button = 4 then begin + if xev.xtype = buttonpress then begin + result:= tmouseevent.create(xwindow,false,mb_none,mw_up, + makepoint(x,y),shiftstate1,time*1000); + end; + end + else begin + if button = 5 then begin + if xev.xtype = buttonpress then begin + result:= tmouseevent.create(xwindow,false,mb_none,mw_down, + makepoint(x,y),shiftstate1,time*1000); + end; + end + else begin + result:= tmouseevent.create(xwindow,xtype = buttonrelease,button1,mw_none, + makepoint(x,y),shiftstate1,time*1000); + end; + end; + end; + end; + mappingnotify: begin + xrefreshkeyboardmapping(@xev.xkeymap); + end; + mapnotify: begin + with xev.xmap do begin + lastmapwindow:= xwindow; + result:= twindowevent.create(ek_show,xwindow); + if application.findwindow(xwindow,window1) and + (wo_notaskbar in window1.options) then begin + setnetatomarrayitem(xwindow,net_wm_state,net_wm_state_skip_taskbar); + end; + end; + end; + unmapnotify: begin + with xev.xunmap do begin + result:= twindowevent.create(ek_hide,xwindow); + end; + end; + reparentnotify: begin + with xev.xreparent do begin + result:= treparentevent.create(ek_reparent,xwindow,parent); + end; + end; + focusin,focusout: begin + with xev.xfocus do begin + if xtype = focusin then begin + eventkind:= ek_focusin; + lastfocuswindow:= window; + end + else begin + eventkind:= ek_focusout; + lastfocuswindow:= 0; + end; + if mode <> notifypointer then begin + result:= twindowevent.create(eventkind,window); + end; + end; + end; + expose: begin + with xev.xexpose do begin + result:= twindowrectevent.create(ek_expose,xwindow, + makerect(x,y,width,height),nullpoint); + end; + end; + graphicsexpose: begin + with xev.xgraphicsexpose do begin + result:= twindowrectevent.create(ek_expose,drawable, + makerect(x,y,width,height),nullpoint); + end; + end; + configurenotify: begin + with xev.xconfigure do begin + if windowdestroyed(xwindow) then begin + result:= twindowevent.create(ek_destroy,xwindow); + end + else begin + if not application.deinitializing then begin + rect1.x:= x; + rect1.y:= y; + pt1:= nullpoint; + if send_event = 0 then begin //from window manager? + getrootoffset(xwindow,pt1); //no, map to screen origin + end; + rect1.cx:= width; + rect1.cy:= height; + {$ifdef mse_debugconfigure} + debugwindow('*conf winrect:'+ + inttostr(pt1.x)+' '+inttostr(pt1.y)+'|'+ + inttostr(rect1.x)+' '+inttostr(rect1.y)+ + ' '+inttostr(rect1.cx)+' '+inttostr(rect1.cy)+ + ' above:',above,xwindow); + {$endif} + result:= twindowrectevent.create(ek_configure,xwindow,rect1,pt1); + end; + +(* gnome bug workaround + if not application.deinitializing and + (getwindowrect(w,rect1,pt1) = gue_ok) then begin + //there can be an Xerror? + //gnome returns a different pos on window resizing than on window moving! + {$ifdef mse_debugconfigure} + debugwindow('*conf winrect '+ + inttostr(pt1.x)+' '+inttostr(pt1.y)+'|'+ + inttostr(rect1.x)+' '+inttostr(rect1.y)+ + ' '+inttostr(rect1.cx)+' '+inttostr(rect1.cy)+' ',w); + {$endif} + result:= twindowrectevent.create(ek_configure,w,rect1,pt1); + end; + {$ifdef mse_debugconfigure} + debugwriteln(' '+inttostr(x)+' '+inttostr(y)+ + ' '+inttostr(width)+' '+inttostr(height)); + {$endif} + while tboolresult(xchecktypedwindowevent( + appdisp,w,configurenotify,@xev)) do begin + {$ifdef mse_debugconfigure} + debugwriteln(' '+inttostr(x)+' '+inttostr(y)+ + ' '+inttostr(width)+' '+inttostr(height)); + {$endif} + end; +*) + end; + end; + end; + destroynotify: begin + with xev.xdestroywindow do begin + if xwindow = lastmapwindow then begin + lastmapwindow:= 0; + end; + if (sysdndreader <> nil) and + (sysdndreader.winid = xwindow) then begin + freeandnil(sysdndreader); + end; + if (sysdndwriter <> nil) then begin + with sysdndwriter do begin + if fdest = xwindow then begin + fdest:= 0; + end; + if fsource = xwindow then begin + freeandnil(sysdndwriter); + end; + end; + end; + result:= twindowevent.create(ek_destroy,xwindow); + end; + end; + else begin + if hasxrandr and (xev.xtype >= xrandreventbase) and + (xev.xtype <= xrandreventbase+rrlastnotify) then begin + screenrectsvalid:= false; + xrrupdateconfiguration(@xev); + end; + end; + end; +end; + +function errorhandler(Display: PDisplay; ErrorEvent: PXErrorEvent): + Longint; cdecl; +const + buflen = 256; +var + buffer: array[0..buflen] of char; +begin + if xlockerror = 0 then begin + xgeterrortext(display,errorevent^.error_code,@buffer,buflen); + sys_errorout('X Error: '+ pchar(@buffer) + ' '+inttostr(errorevent^.error_code)+ + lineend +' Major opcode: '+inttostr(errorevent^.request_code)+lineend); + end; + result:= 0; +end; + +function gui_initcolormap: guierrorty; +begin + gdi_lock; + if is8bitcolor and istruecolor then begin + setcolormapvalue(cl_background,$d0,$e0,$d0); + //green instead of blue tint + end; + result:= gue_ok; + gdi_unlock; +end; + +procedure initcolormap; +const + redm = $07; + reds = 5; + greenm = $38; + greens = 2; + bluem = $c0; + blues = 0; +{ + redm = $e0; + reds = 0; + greenm = $1c; + greens = 3; + bluem = $03; + blues = 6; +} +var + map1: array[0..255] of xcolor; + int1: integer; +begin + msecolormap:= xcreatecolormap(appdisp,rootid,pointer(defvisual),allocall); + if msecolormap <> 0 then begin + xredshiftbase:= reds; + xgreenshiftbase:= greens; + xblueshiftbase:= blues; + xredshiftleft:= false; + xredshift:= 16 + reds; + xredmask:= redm; + xgreenshiftleft:= false; + xgreenshift:= 8 + greens; + xgreenmask:= greenm; + xblueshiftleft:= false; + xblueshift:= 0 + blues; + xbluemask:= bluem; + for int1:= 0 to 255 do begin +{$warnings off} + with map1[int1] do begin + pixel:= int1; + red:= ($ffff*(int1 and redm)) div redm ; + green:= ($ffff*(int1 and greenm)) div greenm ; + blue:= ($ffff*(int1 and bluem)) div bluem ; + {$ifdef FPC} + flags:= dored or dogreen or doblue; + pad:= 0; + {$else} + flags:= char(dored or dogreen or doblue); + pad:= #0; + {$endif} + end; + end; + with map1[$f6] do begin //value for cl_background + red:= $d000; + green:= $d000; + blue:= $d000; + end; + xstorecolors(appdisp,msecolormap,@map1,256); + end; +end; +{$warnings on} +{ +function createappic: boolean; forward; +function icdestroyed(ic: txic; client_data: txpointer; + call_data: txpointer): longbool; cdecl; +begin + result:= false; + appic:= nil; + if not terminated then begin + if not createappic then begin + debugwriteln('Input context lost.'); + halt(1); + end; + end; +end; +} +function createappic: boolean; +//var +// xiccallback: txiccallback; +begin + appic:= xcreateic(im,pchar(xninputstyle),ximstatusnothing or ximpreeditnothing,nil); + result:= appic <> nil; + if result then begin + { + xiccallback.client_data:= nil; + xiccallback.callback:= @icdestroyed; + } + xseticvalues(appic,pchar(xnclientwindow),appid, + {pchar(xndestroycallback)@,xiccallback,}nil); + xgeticvalues(appic,pchar(xnfilterevents),@appicmask,nil); + end; +end; + +function createim: boolean; forward; + +function checklocale: pchar; +begin + result:= setlocale(lc_all,''); + if xsupportslocale() = 0 then begin + setlocale(lc_all,'en_US.UTF-8'); + if xsupportslocale() = 0 then begin + setlocale(lc_all,'en_US.utf8'); + if xsupportslocale() = 0 then begin + setlocale(lc_all,'POSIX'); + if xsupportslocale() = 0 then begin + setlocale(lc_all,'C'); + xsupportslocale(); + end; + end; + end; + end; +end; + +procedure imdestroyed(ic: pxim; client_data: xpointer; + call_data: xpointer); cdecl; +var + po1: pchar; +begin + im:= nil; + appic:= nil; + if not terminated then begin + po1:= checklocale; + if not createim or not createappic then begin + debugwriteln('Input method lost.'); + halt(1); + end; + setlocale(lc_all,po1); //restore original + end; +end; + +function createim: boolean; +var + ximcallback: tximcallback; +begin + xsetlocalemodifiers(''); + im:= xopenim(appdisp,nil,nil,nil); + if im = nil then begin + xsetlocalemodifiers('@im=none'); + im:= xopenim(appdisp,nil,nil,nil); + { + xsetlocalemodifiers('@im=local'); + im:= xopenim(appdisp,nil,nil,nil); + if im = nil then begin + xsetlocalemodifiers('@im='); + im:= xopenim(appdisp,nil,nil,nil); + end; + } + end; + result:= im <> nil; + if result then begin + ximcallback.client_data:= nil; + ximcallback.callback:= @imdestroyed; + xsetimvalues(im,pchar(xndestroycallback),@ximcallback,nil); + end; +end; + +function gui_init: guierrorty; +label + error; +var +// fontpropnames: strfontproparty; +// propnum: fontpropertiesty; + attrib: xsetwindowattributes; + netnum: netatomty; + int1,int2: integer; + po1: pchar; + atom1: atom; + atomar: atomarty; + rect1: rectty; + sigset1,sigset2: sigset_t; +{$ifdef with_sm} + smcb: smccallbacks; + clientid: pchar; + smerror: array[0..255] of char; +{$endif} + po2: pkeycode; + modmap: pxmodifierkeymap; + numlockcode: cuint; + buf1: clipboardbufferty; + +begin + gdi_lock; + try + getmem(pollinf,sizeof(pollinfty)); + fillchar(pollinf^,sizeof(pollinfty),0); + sys_mutexcreate(connectmutex1); + sys_mutexcreate(connectmutex2); + pipe2(connectpipe,o_cloexec or o_nonblock); + resetrepeatkey; + {$ifdef mse_flushgdi} + xinitthreads; + {$endif} + {$ifdef with_sm} + if hassm then begin + if sminfo.smconnection = nil then begin + if iceaddconnectionwatch(@icewatch,@sminfo) <> 0 then begin + with smcb do begin + save_yourself.callback:= @SmcSaveYourself; + save_yourself.client_data:= @sminfo; + die.callback:= @SmcDie; + die.client_data:= @sminfo; + save_complete.callback:= @SmcSaveComplete; + save_complete.client_data:= @sminfo; + shutdown_cancelled.callback:= @SmcShutdownCancelled; + shutdown_cancelled.client_data:= @sminfo; + end; + + sminfo.smconnection:= smcopenconnection(nil,nil,SmProtoMajor,SmProtoMinor, + SmcSaveYourselfProcMask or SmcDieProcMask or SmcSaveCompleteProcMask or + SmcShutdownCancelledProcMask,smcb,nil,clientid,sizeof(smerror),@smerror); + if clientid <> nil then begin + xfree(clientid); + end; + if sminfo.smconnection = nil then begin + hassm:= false; + sys_errorout('Sessionmanager Error: '+ smerror+lineend); + end; + end; + end; + end; + {$endif} + {$ifdef with_saveyourself} + saveyourselfwindow:= 0; + {$endif} + lasteventtime:= currenttime; + + po1:= checklocale; + terminated:= false; + result:= gue_nodisplay; + timerevent:= false; + sigtimerbefore:= signal(sigalrm,{$ifdef FPC}@{$endif}sigtimer); + sigtermbefore:= signal(sigterm,{$ifdef FPC}@{$endif}sigterminate); + sigchldbefore:= signal(sigchld,{$ifdef FPC}@{$endif}sigchild); + sigemptyset(sigset1); + sigaddset(sigset1,sigchld); + pthread_sigmask(sig_unblock,@sigset1,@sigset2); + + appdisp:= xopendisplay(nil); + if appdisp = nil then begin + goto error; + end; + + if not createim then begin + result:= gue_inputmanager; + goto error; + end; + setlocale(lc_all,po1); //restore original + +// defscreenid:= xdefaultscreen(appdisp); + defscreen:= xdefaultscreenofdisplay(appdisp); + rootid:= xrootwindowofscreen(defscreen); + defvisual:= msepvisual(xdefaultvisualofscreen(defscreen)); + defdepth:= xdefaultdepthofscreen(defscreen); + msex11gdi.init(appdisp,defvisual,defdepth); + attrib.event_mask:= propertychangemask; + appid:= xcreatewindow(appdisp,rootid,0,0,200,200,0, + 0,inputonly,xlib.pvisual(copyfromparent),cweventmask,@attrib); + if appid = 0 then begin + result:= gue_createwindow; + goto error; + end; + + if hasxrandrlib then begin + hasxrandr:= xrrqueryextension( + appdisp,@xrandreventbase,@xrandrerrorbase) <> 0; + if hasxrandr then begin + xrrselectinput(appdisp,rootid, RRScreenChangeNotifyMask or + RRCrtcChangeNotifyMask or RROutputChangeNotifyMask); + end; + end + else begin + hasxrandr:= false; + end; + + if not createappic then begin + result:= gue_inputcontext; + goto error; + end; + {$ifdef FPC} + is8bitcolor:= defaultdepthofscreen(defscreen) = 8; + {$else} + is8bitcolor:= defscreen^.root_depth = 8; + {$endif} + if (defvisual^._class = pseudocolor) and is8bitcolor then begin + istruecolor:= false; + initcolormap; + if msecolormap = 0 then begin + result:= gue_nocolormap; + goto error; + end; + end + else begin + istruecolor:= (defvisual^._class = truecolor) or + (defvisual^._class = directcolor); + if istruecolor then begin + xredmask:= defvisual^.red_mask; + xgreenmask:= defvisual^.green_mask; + xbluemask:= defvisual^.blue_mask; + xredshiftbase:= highestbit(xredmask)-7; + xgreenshiftbase:= highestbit(xgreenmask)-7; + xblueshiftbase:= highestbit(xbluemask)-7; + xredshift:= xredshiftbase - redshift; + if xredshift < 0 then begin + xredshiftleft:= false; + xredshift:= -xredshift; + end + else begin + xredshiftleft:= true; + end; + xgreenshift:= xgreenshiftbase - greenshift; + if xgreenshift < 0 then begin + xgreenshiftleft:= false; + xgreenshift:= -xgreenshift; + end + else begin + xgreenshiftleft:= true; + end; + xblueshift:= xblueshiftbase - blueshift; + if xblueshift < 0 then begin + xblueshiftleft:= false; + xblueshift:= -xblueshift; + end + else begin + xblueshiftleft:= true; + end; + end + else begin + result:= gue_notruecolor; + goto error; + end; + end; + + defcolormap:= xdefaultcolormapofscreen(defscreen); + + atomatom:= xinternatom(appdisp,'ATOM', + {$ifdef xboolean}true{$else}1{$endif}); + mseclientmessageatom:= xinternatom(appdisp,'mseclientmessage', + {$ifdef xboolean}false{$else}0{$endif}); + wmprotocolsatom:= xinternatom(appdisp,'WM_PROTOCOLS', + {$ifdef xboolean}false{$else}0{$endif}); + wmnameatom:= xinternatom(appdisp,'WM_NAME', + {$ifdef xboolean}false{$else}0{$endif}); + wmclassatom:= xinternatom(appdisp,'WM_CLASS', + {$ifdef xboolean}false{$else}0{$endif}); + wmprotocols[wm_delete_window]:= xinternatom(appdisp,'WM_DELETE_WINDOW', + {$ifdef xboolean}false{$else}0{$endif}); + {$ifdef with_saveyourself} + wmprotocols[wm_save_yourself]:= xinternatom(appdisp,'WM_SAVE_YOURSELF', + {$ifdef FPC}false{$else}0{$endif}); + wmcommandatom:= xinternatom(appdisp,'WM_COMMAND', + {$ifdef FPC}false{$else}0{$endif}); + {$endif} + wmstateatom:= xinternatom(appdisp,'WM_STATE', + {$ifdef xboolean}false{$else}0{$endif}); + wmtransientforatom:= xinternatom(appdisp,'WM_TRANSIENT_FOR', + {$ifdef xboolean}false{$else}0{$endif}); + wmclientleaderatom:= xinternatom(appdisp,'WM_CLIENT_LEADER', + {$ifdef xboolean}false{$else}0{$endif}); + for buf1:= low(clipboardbuffers) to high(clipboardbuffers) do begin + clipboardbuffers[buf1].name:= xinternatom(appdisp, + pchar(clipboardnames[buf1]),{$ifdef xboolean}false{$else}0{$endif}); + end; + cardinalatom:= xinternatom(appdisp,'CARDINAL', + {$ifdef xboolean}false{$else}0{$endif}); + windowatom:= xinternatom(appdisp,'WINDOW', + {$ifdef xboolean}false{$else}0{$endif}); + stringatom:= xinternatom(appdisp,'STRING', + {$ifdef xboolean}false{$else}0{$endif}); + textatom:= xinternatom(appdisp,'TEXT', + {$ifdef xboolean}false{$else}0{$endif}); + textplainatom:= xinternatom(appdisp,'text/plain', + {$ifdef xboolean}false{$else}0{$endif}); + compound_textatom:= xinternatom(appdisp,'COMPOUND_TEXT', + {$ifdef xboolean}false{$else}0{$endif}); + utf8_stringatom:= xinternatom(appdisp,'UTF8_STRING', + {$ifdef xboolean}false{$else}0{$endif}); + timestampatom:= xinternatom(appdisp,'TIMESTAMP', + {$ifdef xboolean}false{$else}0{$endif}); + multipleatom:= xinternatom(appdisp,'MULTIPLE', + {$ifdef xboolean}false{$else}0{$endif}); + targetsatom:= xinternatom(appdisp,'TARGETS', + {$ifdef xboolean}false{$else}0{$endif}); + convertselectionpropertyatom:= xinternatom(appdisp,'mseconvselprop', + {$ifdef xboolean}false{$else}0{$endif}); + + netsupportedatom:= xinternatom(appdisp,'_NET_SUPPORTED', + {$ifdef xboolean}false{$else}0{$endif}); + + fillchar(xdndatoms,sizeof(xdndatoms),0); //get or create xdnd atoms + xinternatoms(appdisp,@xdndatomnames[low(xdndatomty)], + integer(high(xdndatomty))+1,{$ifdef xboolean}false{$else}0{$endif}, + @xdndatoms[low(xdndatomty)]); + fillchar(xdndactionatoms,sizeof(xdndactionatoms),0); //get or create xdnd atoms + xinternatoms(appdisp,@xdndactionatomnames[firstdndaction], + integer(high(dndactionty)),{$ifdef xboolean}false{$else}0{$endif}, + @xdndactionatoms[firstdndaction]); //first = 0 + + fillchar(netatoms,sizeof(netatoms),0); //check _net_ + xinternatoms(appdisp,@netatomnames[low(netatomty)], + integer(firstonlyifexistatom),false,@netatoms[low(netatomty)]); + xinternatoms(appdisp,@netatomnames[firstonlyifexistatom], + integer(high(netatomty))-integer(firstonlyifexistatom), + true,@netatoms[firstonlyifexistatom]); + + netsupported:= netsupportedatom <> 0; + if netsupported then begin + netsupported:= readatomproperty(rootid,netsupportedatom,atomar); + for netnum:= firstcheckedatom to lastcheckedatom do begin + atom1:= netatoms[netnum]; + netatoms[netnum]:= 0; + for int1:= 0 to high(atomar) do begin + if atomar[int1] = atom1 then begin + netatoms[netnum]:= atom1; + break; + end; + end; + end; + end; + for netnum:= low(netatomty) to needednetatom do begin + if netatoms[netnum] = 0 then begin + netsupported:= false; + break; + end; + end; + + netsupported:= netsupported and + readcardinalproperty(rootid,netatoms[net_workarea],4,rect1); + canframeextents:= netatoms[net_frame_extents] <> 0; + canfullscreen:= netatoms[net_wm_state_fullscreen] <> 0; + if netsupported and not canfullscreen then begin + netatoms[net_wm_state_fullscreen]:= xinternatom(appdisp, + @netatomnames[net_wm_state_fullscreen], + {$ifdef xboolean}false{$else}0{$endif}); //fake + end; + + numlockstate:= 0; + numlockcode:= xkeysymtokeycode(appdisp,xk_num_lock); + if numlockcode <> nosymbol then begin //return numlock state + modmap:= xgetmodifiermapping(appdisp); + {$ifdef FPC} {$checkpointer off} {$endif} + po2:= modmap^.modifiermap; + for int1:= 0 to 7 do begin + for int2:= 0 to modmap^.max_keypermod - 1 do begin + if po2^ = numlockcode then begin + numlockstate:= 1 shl int1; + break; + end; + inc(po2); + end; + if numlockstate <> 0 then begin + break; + end; + end; + xfreemodifiermap(modmap); + {$ifdef FPC} {$checkpointer default} {$endif} + end; + +// fillchar(pollinfo,sizeof(pollinfo),0); +// pollcount:= 2; + pollinf^.pollinfo:= nil; + gui_addpollfd(int1,xconnectionnumber(appdisp),[pf_in,pf_pri]); //0 + gui_addpollfd(int1,connectpipe.readdes,[pf_in,pf_pri]); //1 + {$ifdef with_sm} + if hassm and (sminfo.fd > 0) then begin + gui_addpollfd(int1,sminfo.fd,[pf_in,pf_pri]); //2 + end; + {$endif} +(* + with pollinfo[0] do begin + fd:= xconnectionnumber(appdisp); + events:= pollin or pollpri; + end; + with pollinfo[1] do begin + fd:= connectpipe.readdes; + events:= pollin or pollpri; + end; +{$ifdef with_sm} + if hassm then begin + if sminfo.fd > 0 then begin + with pollinfo[2] do begin + fd:= sminfo.fd; + events:= pollin or pollpri; + end; + inc(pollcount); + end; + end; +{$endif} +*) + result:= gue_ok; + {$ifdef mse_flushgdi} + xsynchronize(appdisp,1); + {$endif} + errorhandlerbefore:= xseterrorhandler({$ifdef FPC}@{$endif}errorhandler); + exit; + error: + deinit; + finally + gdi_unlock; + end; +end; + +function gui_deinit: guierrorty; +var + buf1: clipboardbufferty; +begin + gdi_lock; + try + freeandnil(sysdndreader); + freeandnil(sysdndwriter); + for buf1:= low(clipboardbuffers) to high(clipboardbuffers) do begin + clipboardbuffers[buf1].buffer:= ''; + end; + result:= gue_ok; + settimer1(0); //kill timer + terminated:= true; + freeclientevents; + {$ifdef with_sm} + if hassm then begin + with sminfo do begin + if smconnection <> nil then begin + if shutdown and shutdownpending then begin + if interactwaiting and interactgranted then begin + smcinteractdone(smconnection,0); + {$ifdef smdebug} + writeln('gui_deinit smcinteractdone'); + {$endif} + end; + smcsaveyourselfdone(smconnection,1); + {$ifdef smdebug} + writeln('gui_deinit saveyourselfdone'); + {$endif} + end; + iceremoveconnectionwatch({$ifdef FPC}@{$endif}icewatch,@sminfo); + {$ifdef smdebug} + writeln('gui_deinit iceremoveconnectionwatch'); + {$endif} + smccloseconnection(sminfo.smconnection,0,nil); + {$ifdef smdebug} + writeln('gui_deinit smccloseconnection'); + {$endif} + fillchar(sminfo,sizeof(sminfo),0); + end; + end; + end; + {$endif} + {$ifdef with_saveyourself} + if saveyourselfwindow <> 0 then begin + setstringproperty(saveyourselfwindow,wmcommandatom,''); + end; + {$endif} + if appic <> nil then begin + xdestroyic(appic); + appic:= nil; + end; + if im <> nil then begin + xcloseim(im); + im:= nil; + end; + if appid <> 0 then begin + xdestroywindow(appdisp,appid); + appid:= 0; + end; + // if screencursor <> 0 then begin + // xfreecursor(appdisp,screencursor); + // screencursor:= 0; + // end; + if appdisp <> nil then begin + if msecolormap <> 0 then begin + xfreecolormap(appdisp,msecolormap); + msecolormap:= 0; + end; + xclosedisplay(appdisp); + appdisp:= nil; + end; + sys_closefile(connectpipe.writedes); + sys_closefile(connectpipe.readdes); + sys_mutexdestroy(connectmutex1); + sys_mutexdestroy(connectmutex2); + signal(sigalrm,sigtimerbefore); + signal(sigterm,sigtermbefore); + signal(sigchld,sigchldbefore); + xseterrorhandler(errorhandlerbefore); + screenrects:= nil; + screenrectsvalid:= false; + finalize(pollinf^); + freemem(pollinf); + finally + gdi_unlock; + end; +end; + +{ +procedure gui_gdifunc(const func: gdifuncty; var drawinfo: drawinfoty); +begin + gdifunctions[func](drawinfo); +end; +} + +function gui_getgdifuncs: pgdifunctionaty; +begin + result:= x11getgdifuncs; +end; + +var + debugungrabbed: boolean; + +procedure GUI_DEBUGBEGIN; +var + int1: integer; +begin + int1:= sys_getlasterror; + if pointergrabbed then begin + debugungrabbed:= true; + gui_ungrabpointer; + end; + if appdisp <> nil then begin + xflush(appdisp); + end; + sys_setlasterror(int1); +end; + +procedure GUI_DEBUGEND; +var + int1: integer; +begin + if debugungrabbed then begin + int1:= sys_getlasterror; + gui_grabpointer(grabwinid); + sys_setlasterror(int1); + debugungrabbed:= false; + end; +end; + +function gui_registergdi: guierrorty; +begin + registergdi(x11getgdifuncs); + result:= gue_ok; +end; + +initialization + mainthreadid:= sys_getcurrentthread(); + norestackwindow:= true; + noreconfigurewmwindow:= true; + stackmodebelowworkaround:= false; +// nocreatestaticgravity:= true; + hassm:= geticelib and getsmlib; + hasxrandrlib:= getxrandrlib; +end. \ No newline at end of file diff --git a/mseide-msegui/lib/common/kernel/linux/msenoguiintf.pas b/mseide-msegui/lib/common/kernel/linux/msenoguiintf.pas new file mode 100644 index 0000000..4297578 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/msenoguiintf.pas @@ -0,0 +1,126 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msenoguiintf; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msesystypes; + +{$include ../msenoguiintf.inc} + +implementation +uses + mselibc,mseevent,msesysintf1,mseapplication,msenogui,mseprocmonitor; +type + tapplication1 = class(tnoguiapplication); +var + sigtimerbefore: sighandler_t; + sigtermbefore: sighandler_t; + sigchldbefore: sighandler_t; + timerevent: boolean; + terminated: boolean; + childevent: boolean; + sempo: psemty; + +procedure settimer1(us: longword); + //send et_timer event after delay of us (micro seconds) +var + timerval: itimerval; +begin + fillchar(timerval,sizeof(timerval),0); + timerval.it_value.tv_sec:= us div 1000000; + timerval.it_value.tv_usec:= us mod 1000000; + mselibc.setitimer(itimer_real,{$ifdef FPC}@{$endif}timerval,nil); +end; + +procedure nogui_waitevent; + procedure checkevents; + begin + if timerevent then begin + timerevent:= false; + application.postevent(tmseevent.create(ek_timer)); + end; + if terminated then begin + timerevent:= false; + application.postevent(tmseevent.create(ek_terminate)); + end; + if childevent then begin + childevent:= false; + handlesigchld; + end; + end; + +begin + with tapplication1(application) do begin + include(fstate,aps_waiting); + checkevents; + while eventlist.count = 0 do begin + with linuxsemty(sempo^) do begin + unlock; + sem_wait(d.sema); + lock; + checkevents; + end; + end; + fstate:= fstate -[aps_waiting,aps_woken]; + end; +end; + +procedure nogui_settimer(us: longword); +begin + if us = 0 then begin + us:= 1; + end; + settimer1(us); +end; + +procedure sigtimer(SigNum: Integer); cdecl; +begin + timerevent:= true; + sem_post(linuxsemty(sempo^).d.sema); +end; + +procedure sigterminate(SigNum: Integer); cdecl; +begin + terminated:= true; + sem_post(linuxsemty(sempo^).d.sema); +end; + +procedure sigchild(SigNum: Integer); cdecl; +begin + childevent:= true; + mseprocmonitor.sigchildcallback(); + sem_post(linuxsemty(sempo^).d.sema); +end; + +procedure nogui_init(const asempo: psemty); +var + sigset1,sigset2: sigset_t; +begin + sempo:= asempo; + sigtimerbefore:= signal(sigalrm,{$ifdef FPC}@{$endif}sigtimer); + sigtermbefore:= signal(sigterm,{$ifdef FPC}@{$endif}sigterminate); + sigchldbefore:= signal(sigchld,{$ifdef FPC}@{$endif}sigchild); + sigemptyset(sigset1); + sigaddset(sigset1,sigchld); + sigprocmask(sig_unblock,@sigset1,@sigset2); +end; + +procedure nogui_deinit; +begin + terminated:= true; + settimer1(0); + signal(sigalrm,sigtimerbefore); + signal(sigterm,sigtermbefore); + signal(sigchld,sigchldbefore); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mseprocmonitor.pas b/mseide-msegui/lib/common/kernel/linux/mseprocmonitor.pas new file mode 100644 index 0000000..4b9ecec --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mseprocmonitor.pas @@ -0,0 +1,239 @@ +{ MSEgui Copyright (c) 2008-2009 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseprocmonitor; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + msesystypes,mseglob,msetypes,mselibc; + + {$include ../mseprocmonitor.inc} + +procedure sigchildcallback; +function timedwaitpid(__pid: __pid_t; __stat_loc: plongint; + const waitus: integer): __pid_t; + //waitus must be > 0 + //result -1 -> error, -2 -> timeout + +implementation +uses + mseapplication,msedatalist,msearrayutils,msesysintf1,msesysutils,sysutils; + +type + procinfoty = record + prochandle: prochandlety; + dest: iprocmonitor; + data: pointer; + end; + procinfoarty = array of procinfoty; +var + infos: procinfoarty; + +function pro_listentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor; const adata: pointer): boolean; +begin + application.lock; + setlength(infos,high(infos)+2); + with infos[high(infos)] do begin + prochandle:= aprochandle; + dest:= adest; + data:= adata; + end; + application.unlock; + result:= true; +end; + +procedure pro_unlistentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor); +var + int1: integer; +begin + application.lock; + for int1:= high(infos) downto 0 do begin + with infos[int1] do begin + if (prochandle = aprochandle) and (dest = adest) then begin + deleteitem(infos,typeinfo(procinfoarty),int1); + end; + end; + end; + application.unlock; +end; + +procedure checkchildproc(); +var + int1,int2,int3: integer; + dwo1: dword; + execresult: integer; +begin + application.lock; + int1:= high(infos); + while int1 >= 0 do begin + int3:= waitpid(infos[int1].prochandle,@dwo1,wnohang); + if (int3 > 0) and (wifexited(dwo1) or wifsignaled(dwo1)) then begin + execresult:= wexitstatus(dwo1); + end + else begin + execresult:= -2; //still running for int3 = 0 + if (int3 < 0) and (sys_getlasterror() = ECHILD) then begin + execresult:= -1; + end; + end; + if execresult >= -1 then begin + for int2:= int1 downto 0 do begin + with infos[int2] do begin + if prochandle = infos[int1].prochandle then begin + if dest <> nil then begin + dest.processdied(prochandle,execresult,data); + end; + deleteitem(infos,typeinfo(procinfoarty),int2); + if int2 <> int1 then begin + dec(int1); + end; + end; + end; + end; + end; + dec(int1); + end; + application.unlock; +end; + +procedure pro_killzombie(const aprochandle: prochandlety); +begin + pro_listentoprocess(aprochandle,nil,nil); +end; + +type + psemelety = ^semelety; + semelety = record + prev: psemelety; + next: psemelety; + sem: semty; + end; + +var + semaphorelock: mutexty; + semaphores: psemelety; +{$ifdef mse_debugprocmonitor} +var + semcount: int32; + +procedure checksemaphores(); +var + i1: int32; + po1: psemelety; +begin + i1:= 0; + po1:= semaphores; + while po1 <> nil do begin + inc(i1); + po1:= po1^.next; + end; + if i1 <> semcount then begin + raise exception.create('Invalid procmonitor semaphores'); + end; +end; + +{$endif} + +procedure sigchildcallback(); +var + po1: psemelety; +begin +{$ifdef mse_debugprocmonitor} + checksemaphores(); +{$endif} + po1:= semaphores; + while po1 <> nil do begin + sys_sempost(po1^.sem); + po1:= po1^.next; + end; +end; + +function timedwaitpid(__pid: __pid_t; __stat_loc: plongint; + const waitus: integer): __pid_t; + //waitus must be > 0 + //result -1 -> error, -2 -> timeout +var + semele: semelety; + lwo1: longword; + int1: integer; +begin + result:= -1; + if waitus > 0 then begin + lwo1:= timestep(waitus); + sys_semcreate(semele.sem,0); + + sys_mutexlock(semaphorelock); +{$ifdef mse_debugprocmonitor} + checksemaphores(); +{$endif} + semele.prev:= semaphores; + semele.next:= nil; + if semaphores = nil then begin + interlockedexchange(semaphores,@semele); + end + else begin + interlockedexchange(semaphores^.next,@semele); + end; +{$ifdef mse_debugprocmonitor} + inc(semcount); + checksemaphores(); +{$endif} + sys_mutexunlock(semaphorelock); + + while true do begin + repeat + result:= waitpid(__pid,__stat_loc,wnohang); + until (result >= 0) or (sys_getlasterror <> eintr); + if (result = __pid) or (result < 0) then begin + break; + end; + int1:= lwo1-timestamp; + if int1 > 0 then begin + sys_semwait(semele.sem,int1); + end + else begin + result:= waitpid(__pid,__stat_loc,wnohang); + if result < 0 then begin + result:= -2; + end; + break; + end; + end; + + sys_mutexlock(semaphorelock); +{$ifdef mse_debugprocmonitor} + checksemaphores(); +{$endif} +// if semele.prev = nil then begin + if semaphores = @semele then begin + interlockedexchange(semaphores,semele.next); + end + else begin + interlockedexchange(semele.prev^.next,semele.next); + end; +{$ifdef mse_debugprocmonitor} + dec(semcount); + checksemaphores(); +{$endif} + sys_mutexunlock(semaphorelock); + + sys_semdestroy(semele.sem); + end; +end; + +initialization + onhandlesigchld:= @checkchildproc; + sys_mutexcreate(semaphorelock); + +finalization + onhandlesigchld:= nil; + sys_mutexdestroy(semaphorelock); +end. diff --git a/mseide-msegui/lib/common/kernel/linux/msesetlocale.pas b/mseide-msegui/lib/common/kernel/linux/msesetlocale.pas new file mode 100644 index 0000000..45f89d5 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/msesetlocale.pas @@ -0,0 +1,258 @@ +{ MSEgui Copyright (c) 1999-2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesetlocale; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mselibc,msesys; + +function getcodeset(): string; + +implementation +uses + cwstring,sysutils,msestrings,mseformatstr,msetypes,msesysintf; + +function getlocstr(const id: integer; const defaultvalue: string): string; +var + po1: pchar; +begin + po1:= nl_langinfo(id); + if po1 = nil then begin + result:= defaultvalue; + end + else begin + result:= po1; + end; +end; + +function getcodeset(): string; +begin + result:= getlocstr(codeset,''); +end; + +function convertcformatstring(const source,defaultvalue: string): string; +var + po1: pchar; +begin + result:= ''; + po1:= pchar(source); + while po1^ <> #0 do begin + if po1^ = '%' then begin + inc(po1); + case po1^ of + '%': result:= result + '%'; + 'a': result:= result + 'ddd'; + 'A': result:= result + 'dddd'; + 'b': result:= result + 'mmm'; + 'B': result:= result + 'mmmm'; + 'c': result:= result + 'c'; +// 'C': + 'd': result:= result + 'dd'; + 'D': result:= result + 'mm/dd/yy'; + 'e': result:= result + 'd'; +// 'E': + 'g': result:= result + 'yy'; + 'G': result:= result + 'yyyy'; + 'h': result:= result + 'mmm'; + 'H': result:= result + 'HH'; + 'I': result:= result + 'hh'; +// 'j': + 'k': result:= result + 'H'; + 'l': result:= result + 'h'; + 'm': result:= result + 'mm'; + 'M': result:= result + 'nn'; + 'n': result:= result + lineend; +// 'O': + 'P','p': result:= result + 'ampm'; + 'r': result:= result + convertcformatstring(nl_langinfo(t_fmt_ampm),''); + 'R': result:= result + 'hh:nn'; +// 's': + 'S': result:= result + 'ss'; + 't': result:= result + c_tab; + 'T': result:= result + 'hh:nn:ss'; +// 'u': +// 'U': +// 'V': +// 'w': +// 'W': + 'x': result:= result + convertcformatstring(nl_langinfo(d_fmt),''); + 'X': result:= result + convertcformatstring(nl_langinfo(t_fmt),''); + 'y': result:= result + 'yy'; + 'Y': result:= result + 'yyyy'; +// 'z': + end; + end + else begin + result:= result + po1^; + end; + inc(po1); + end; + result:= trimright(result); + if result = '' then begin + result:= defaultvalue; + end; +end; + +procedure findfirstchar(const value,chars: msestring; var result: msechar); +var + int1: integer; + po1: pmsechar; +begin + po1:= pmsechar(value); + while po1^ <> #0 do begin + for int1:= 1 to length(chars) do begin + if po1^ = chars[int1] then begin + result:= po1^; + break; + end; + end; + inc(po1); + end; +end; + +procedure initformatsettings; +{$ifdef FPC} +var + int1: integer; + ch1,ch2{$ifdef linux},ch3{$endif}: char; + str1,str2: string; + mstr1: msestring; +{$ifndef linux} + bo1: boolean; +{$endif} + + currfo: array[0..1,0..1] of byte = ((1,3),(0,2)); + //[p_cs_precedes,p_sep_by_space] +{$ifdef linux} + negcurrfo: array[0..1,0..1,0..4] of byte = + (((4,5,7,6,7),(15,8,10,13,10)),((0,1,3,1,2),(14,9,11,9,12))); + //[n_cs_precedes,n_sep_by_space,n_sign_posn] +{$endif} +{$endif} +begin + initdefaultformatsettings; + //msesys initialization will be called after msesetlocale initialization. + //FPC bug? + + with defaultformatsettingsmse do begin + {$ifdef FPC} + mstr1:= msestring(getlocstr(decimal_point,ansistring(decimalseparator))); + if mstr1 <> '' then begin + decimalseparator:= mstr1[1]; + end; + mstr1:= msestring(getlocstr(thousands_sep,ansistring(thousandseparator))); + if mstr1 <> '' then begin + thousandseparator:= mstr1[1]; + end + else begin + mstr1:= msestring(getlocstr(mon_decimal_point,ansistring(decimalseparator))); + if mstr1 <> '' then begin + decimalseparator:= mstr1[1]; + mstr1:= msestring(getlocstr(mon_thousands_sep, + ansistring(thousandseparator))); + if mstr1 <> '' then begin + thousandseparator:= mstr1[1]; + end + else begin + thousandseparator:= ' '; + end; + end + else begin + thousandseparator:= ' '; + end; + end; + + for int1:= 1 to 12 do begin + shortmonthnames[int1]:= msestring(getlocstr(abmon_1 + int1 - 1, + ansistring(shortmonthnames[int1]))); + longmonthnames[int1]:= msestring(getlocstr(mon_1 + int1 - 1, + ansistring(longmonthnames[int1]))); + end; + for int1:= 1 to 7 do begin + shortdaynames[int1]:= msestring(getlocstr(abday_1 + int1 - 1, + ansistring(shortdaynames[int1]))); + longdaynames[int1]:= msestring(getlocstr(day_1 + int1 - 1, + ansistring(longdaynames[int1]))); + end; + shortdateformat:= msestring(convertcformatstring(getlocstr(d_fmt,''), + ansistring(shortdateformat))); + str1:= getlocstr(d_t_fmt,''); + str2:= getlocstr(t_fmt,''); + int1:= pos(str2,str1); + if int1 > 0 then begin + str1:= trimright(copy(str1,1,int1-1)); + end; + longdateformat:= msestring(convertcformatstring(str1, + ansistring(longdateformat))); + // longdateformat:= convertcformatstring(getlocstr(d_t_fmt,''),longdateformat); + shorttimeformat:= msestring(convertcformatstring(getlocstr(t_fmt,''), + ansistring(shorttimeformat))); + longtimeformat:= msestring(convertcformatstring(getlocstr(t_fmt_ampm,''), + ansistring(longtimeformat))); + findfirstchar(shortdateformat,'./-',dateseparator); + findfirstchar(shorttimeformat,':.',timeseparator); + + timeamstring:= msestring(getlocstr(am_str,ansistring(timeamstring))); + if timeamstring = '' then begin + timeamstring:= 'am'; + end; + timepmstring:= msestring(getlocstr(pm_str,ansistring(timepmstring))); + if timepmstring = '' then begin + timepmstring:= 'pm'; + end; + currencystring:= msestring(getlocstr(currency_symbol, + ansistring(currencystring))); +{$ifdef linux} + {$ifdef FPC}{$checkpointer off}{$endif} + ch1:= nl_langinfo(p_cs_precedes)^; + ch2:= nl_langinfo(p_sep_by_space)^; + if (ch1 in [#0,#1]) and (ch2 in [#0,#1]) then begin + currencyformat:= currfo[ord(ch1),ord(ch2)]; + ch3:= nl_langinfo(p_sign_posn)^; + if ord(ch3) in [0..4] then begin + negcurrformat:= negcurrfo[ord(ch1),ord(ch2),ord(ch3)]; + end; + end; + ch1:= nl_langinfo(frac_digits)^; + if byte(ch1) < 127 then begin + currencydecimals:= ord(ch1); + end; +{$else} //bsd + if currencystring <> '' then begin + ch1:= #0; + ch2:= #0; + bo1:= true; + case currencystring[1] of + '-': ch1:= #1; + '+': ch1:= #0; + '.': ch1:= #0; //not suported + else bo1:= false; + end; + if bo1 then begin + currencystring:= copy(currencystring,2,bigint); + currencyformat:= currfo[ord(ch1),ord(ch2)]; + end; + end; +{$endif} + saveformatsettings; + {$ifdef FPC}{$checkpointer default}{$endif} + {$endif} + end; + + str1:= strlowercase(getcodeset()); + if (str1 = 'utf8') or (str1 = 'utf-8') then begin + filenameutfoptions:= [uto_storeinvalid]; + end; +end; + +initialization + setlocale(LC_ALL,''); + initformatsettings; +end. diff --git a/mseide-msegui/lib/common/kernel/linux/msesocketintf.pas b/mseide-msegui/lib/common/kernel/linux/msesocketintf.pas new file mode 100644 index 0000000..8c49e30 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/msesocketintf.pas @@ -0,0 +1,501 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesocketintf; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msesystypes,msesys; +{$ifdef FPC} + {$include ../msesocketintf.inc} +{$else} + {$include msesocketintf.inc} +{$endif} + +implementation +uses + mselibc,msefileutils,msesysintf1,msesysintf,msesysutils,sysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + datarecty = record + //dummy + end; + + locsockaddrty = record + sa_family: sa_family_t; + sa_data: datarecty; + end; + plocsockaddrty = ^locsockaddrty; + + linuxsockadty = record + case integer of + 0: (addr: sockaddr_in); + 1: (addr6: sockaddr_in6); + end; + + linuxsockaddrty = record + ad: linuxsockadty; + platformdata: array[7..32] of longword; + end; + +function soc_getaddrerrortext(aerror: integer): string; +begin + result:= strpas(gai_strerror(aerror)); +end; + +function soc_geterrortext(aerror: integer): string; +begin + result:= inttostr(aerror); +end; + +function soc_setnonblock(const handle: integer; const nonblock: boolean): syserrorty; +var + int1: integer; +begin + result:= sye_ok; + int1:= fcntl(handle,f_getfl,[0]); + if int1 = -1 then begin + result:= syelasterror + end + else begin + if nonblock then begin + int1:= int1 or o_nonblock; + end + else begin + int1:= int1 and not o_nonblock; + end; + if fcntl(handle,f_setfl,[int1]) = -1 then begin + result:= sye_lasterror; + end; + end; +end; + +function soc_open(const kind: socketkindty; const nonblock: boolean; + out handle: integer): syserrorty; +var + int1: integer; +begin + case kind of + sok_inet: int1:= pf_inet; + sok_inet6: int1:= pf_inet6; + else int1:= pf_local; //sok_local + end; + handle:= socket(int1,sock_stream,0); + if handle = -1 then begin + result:= syelasterror; + end + else begin + result:= soc_setnonblock(handle,nonblock); + end; +end; + +function soc_shutdown(const handle: integer; + const kind: socketshutdownkindty): syserrorty; +begin + if mselibc.shutdown(handle,ord(kind)) <> 0 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function soc_close(const handle: integer): syserrorty; +begin + if mselibc.__close(handle) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function soc_connect(const handle: integer; const addr: socketaddrty; + const timeoutms: integer): syserrorty; +var + str1: string; + po1: plocsockaddrty; + int1{,int2}: integer; + pollres: pollkindsty; +begin + result:= sye_ok; + with addr do begin + if kind = sok_local then begin + str1:= ansistring(tosysfilepath(url)); + int1:= sizeof(locsockaddrty)+length(str1)+1; + getmem(po1,int1); + po1^.sa_family:= af_local; + move(str1[1],po1^.sa_data,length(str1)); + pchar(@po1^.sa_data)[length(str1)]:= #0; + {$ifdef FPC} + if connect(handle,pointer(po1),int1) <> 0 then begin + {$else} + if connect(handle,psockaddr(po1)^,int1) <> 0 then begin + {$endif} + result:= soc_poll(handle,[poka_write],timeoutms,pollres); + if result = sye_ok then begin + {$ifdef FPC} + if connect(handle,pointer(po1),int1) <> 0 then begin + {$else} + if connect(handle,psockaddr(po1)^,int1) <> 0 then begin + {$endif} + result:= syelasterror; + end; + end; + end; + freemem(po1); + end + else begin + with linuxsockaddrty(platformdata) do begin + {$ifdef linux} + int1:= __libc_sa_len(ad.addr.sa_family); + {$else} + int1:= ad.addr.sa_len; + {$endif} + po1:= @ad.addr; + {$ifdef FPC} + if connect(handle,pointer(po1),int1) <> 0 then begin + {$else} + if connect(handle,psockaddr(po1)^,int1) <> 0 then begin + {$endif}; + result:= soc_poll(handle,[poka_write],timeoutms,pollres); + if result = sye_ok then begin + {$ifdef FPC} + if connect(handle,pointer(po1),int1) <> 0 then begin + {$else} + if connect(handle,psockaddr(po1)^,int1) <> 0 then begin + {$endif} + result:= syelasterror; + end; + end; + end; + end; + end; + end; +end; + +function soc_read(const fd: longint; const buf: pointer; + const nbytes: longword; out readbytes: integer; + const timeoutms: integer): syserrorty; + //atimeoutms < 0 -> nonblocked +var + pollres: pollkindsty; +begin + result:= sye_ok; + if timeoutms >= 0 then begin + result:= soc_poll(fd,[poka_read],timeoutms,pollres); + end; + if result = sye_ok then begin + readbytes:= __read(fd,buf^,nbytes); + if readbytes <= 0 then begin + if (timeoutms < 0) then begin + if not ((sys_getlasterror = ewouldblock) or + (sys_getlasterror = eagain)) then begin + result:= syelasterror; + end + else begin + readbytes:= 0; + end; + end + else begin + result:= syelasterror; + end; + end; + end + else begin + readbytes:= -1; + end; +end; + +function soc_write(const fd: longint; buf: pointer; + nbytes: longword; out writebytes: integer; + const timeoutms: integer): syserrorty; +begin + writebytes:= sys_write(fd,buf,nbytes); + if writebytes > 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function soc_bind(const handle: integer; + const addr: socketaddrty): syserrorty; +var + str1: string; + po1: plocsockaddrty; + int1,int2: integer; +begin + result:= sye_ok; + with addr do begin + if kind = sok_local then begin + str1:= ansistring(tosysfilepath(url)); + int1:= sizeof(locsockaddrty)+length(str1)+1; + getmem(po1,int1); + po1^.sa_family:= af_local; + move(str1[1],po1^.sa_data,length(str1)); + pchar(@po1^.sa_data)[length(str1)]:= #0; + int2:= bind(handle,pointer(po1),int1); + if (int2 <> 0) and (sys_getlasterror = EADDRINUSE) then begin + mselibc.unlink(pchar(str1)); + int2:= bind(handle,pointer(po1),int1); + end; + if int2 <> 0 then begin + result:= syelasterror; + end; + freemem(po1); + end + else begin + with linuxsockaddrty(platformdata) do begin + {$ifdef linux} + if bind(handle,@ad,__libc_sa_len(ad.addr.sa_family)) <> 0 then begin + {$else} + if bind(handle,@ad,ad.addr.sa_len) <> 0 then begin + {$endif} + result:= syelasterror; + end; + end; + end; + end; +end; + +function soc_listen(const handle: integer; const maxconnections: integer): syserrorty; +begin + if listen(handle,maxconnections) <> 0 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function soc_accept(const handle: integer; const nonblock: boolean; out conn: integer; + out addr: socketaddrty; const timeoutms: integer): syserrorty; +var + pollres: pollkindsty; +begin + result:= soc_poll(handle,[poka_read],timeoutms,pollres); + if result = sye_ok then begin + addr.size:= sizeof(linuxsockadty); + conn:= accept(handle,@addr.platformdata,@addr.size); + if conn = -1 then begin + result:= syelasterror; + end + else begin + result:= soc_setnonblock(conn,nonblock); + end; + end; +end; + +function setsocktimeout(const handle: integer; const ms: integer; + const optname: integer): syserrorty; +var + ti: ttimeval; +begin + ti.tv_sec:= ms div 1000; + ti.tv_usec:= (ms mod 1000) * 1000; + if setsockopt(handle,sol_socket,optname,@ti,sizeof(ti)) <> 0 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function soc_setrxtimeout(const handle: integer; const ms: integer): syserrorty; +begin + result:= setsocktimeout(handle,ms,so_rcvtimeo); +end; + +function soc_settxtimeout(const handle: integer; const ms: integer): syserrorty; +begin + result:= setsocktimeout(handle,ms,so_sndtimeo); +end; + +function soc_urltoaddr(var addr: socketaddrty): syserrorty; +var + str1: string; + int1: integer; +// str2: string; +// err: integer; + info1: addrinfo; + po1: paddrinfo; +begin + result:= sye_ok; + with addr,linuxsockaddrty(platformdata) do begin + if kind = sok_local then begin + str1:= ansistring(tosysfilepath(url)); + end + else begin + str1:= ansistring(url); + end; + fillchar(info1,sizeof(addrinfo),0); + with info1 do begin + ai_socktype:= ord(sock_stream); + case kind of + sok_local: begin + ai_family:= af_local; + end; + sok_inet: begin + ai_family:= af_inet; + end; + sok_inet6: begin + ai_family:= af_inet6; + end; + end; + end; + int1:= getaddrinfo(pchar(str1),nil,@info1,@po1); + if int1 <> 0 then begin + mselasterror:= int1; + result:= sye_sockaddr; + end + else begin + with po1^ do begin + move(ai_addr^,ad,ai_addrlen); + if port <> 0 then begin + case ai_family of + af_inet: begin + ad.addr.sin_port:= htons(port); + end; + af_inet6: begin + ad.addr6.sin6_port:= htons(port); + end; + end; + end; + end; + freeaddrinfo(po1); + end; + end; +end; + +function soc_getaddr(const addr: socketaddrty): string; +begin + with linuxsockaddrty(addr.platformdata).ad do begin + case addr.sa_family of + af_inet: begin + setlength(result,sizeof(addr.sin_addr)); + move(addr.sin_addr,result[1],length(result)); + end; + af_inet6: begin + setlength(result,sizeof(addr6.sin6_addr)); + move(addr6.sin6_addr,result[1],length(result)); + end; + else begin + result:= ''; + end; + end; + end; +end; + +function soc_poll(const handle: integer; const kind: pollkindsty; + const timeoutms: longword; + out pollres: pollkindsty): syserrorty; + //0 -> no timeout + //for blocking mode +var + int1,int2: integer; + lwo1,lwo2: longword; + info: pollfd; +begin + lwo1:= 0; + pollres:= []; + fillchar(info,sizeof(info),0); + with info do begin + fd:= handle; + if poka_read in kind then begin + events:= events or pollin; + end; + if poka_write in kind then begin + events:= events or pollout; + end; + if poka_except in kind then begin + events:= events or pollpri; + end; + end; + if timeoutms > 0 then begin + lwo1:= timestampms + timeoutms; + int2:= timeoutms; + end + else begin + int2:= -1; + end; + while true do begin + int1:= poll(@info,1,int2); + if (int1 >= 0) or (sys_getlasterror <> eintr) then begin + break; + end; + if timeoutms > 0 then begin + lwo2:= lwo1 - timestampms; + if integer(lwo2) <= 0 then begin + int1:= 0; + break; + end; + int2:= lwo2; + end; + end; + if int1 < 0 then begin + result:= syelasterror; + end + else begin + if int1 = 0 then begin + result:= sye_timeout; + end + else begin + with info do begin + if revents and not pollin <> 0 then begin + include(pollres,poka_read); + end; + if revents and not pollout <> 0 then begin + include(pollres,poka_write); + end; + if revents and not pollpri <> 0 then begin + include(pollres,poka_except); + end; + end; + result:= sye_ok; + end; + end; +end; + +function soc_getport(const addr: socketaddrty): integer; +begin + with linuxsockaddrty(addr.platformdata).ad do begin + case addr.sa_family of + af_inet: begin + result:= ntohs(addr.sin_port); + end; + af_inet6: begin + result:= ntohs(addr6.sin6_port); + end; + else begin + result:= 0; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/msesysintf.pas b/mseide-msegui/lib/common/kernel/linux/msesysintf.pas new file mode 100644 index 0000000..4b34a21 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/msesysintf.pas @@ -0,0 +1,1450 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesysintf; //linux, freebsd +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +{$ifdef mse_debuglock} + {$define mse_debugmutex} +{$endif} +{$ifdef mse_debuggdisync} + {$define mse_debugmutex} +{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion > 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msesys,msesystypes,msesetlocale,{$ifdef FPC}cthreads,cwstring,{$endif}msetypes, + mselibc,msectypes, + msestrings,msestream; + +var + thread1: threadty; + filenameutfoptions: utfoptionsty; + +{$ifdef msedebug} +var //!!!!todo: link with correct location + _IO_stdin: P_IO_FILE; cvar; + _IO_stdout: P_IO_FILE; cvar; + _IO_stderr: P_IO_FILE; cvar; + __malloc_initialized : longint;cvar; + h_errno : longint;cvar; +{$endif} + +{$include ../msesysintf.inc} + +function timestampms: longword; +function blocksignal(const signum: integer): boolean; + //true if blocked before +function unblocksignal(const signum: integer): boolean; + //true if blocked before + +function sigactionex(SigNum: Integer; var Action: TSigActionex; OldAction: PSigAction): Integer; + +procedure setcloexec(const fd: integer); + +implementation +uses + msesysintf1,sysutils,msesysutils,msefileutils,msearrayutils + {$ifdef FPC},dateutils{$else},DateUtils,classes_del{$endif},msedate + {$ifdef mse_debugmutex},mseapplication{$endif} + {$ifdef freebsd},msedynload{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function sigactionex(SigNum: Integer; var Action: TSigActionex; + OldAction: PSigAction): Integer; +begin + action.sa_flags:= action.sa_flags or SA_SIGINFO; + result:= sigaction(signum,@action,oldaction); +end; + + +(* + tstatbuf64 = packed record // Renamed due to conflict with stat64 function + st_dev: __dev_t; { Device. } + __pad1: Word; + __st_ino: __ino_t; { 32bit file serial number. } + st_mode: __mode_t; { File mode. } + st_nlink: __nlink_t; { Link count. } + st_uid: __uid_t; { User ID of the file's owner. } + st_gid: __gid_t; { Group ID of the file's group. } + st_rdev: __dev_t; { Device number, if device. } + __pad2: Word; + st_size: __off64_t; { Size of file, in bytes. } + st_blksize: __blksize_t; { Optimal block size for I/O. } + st_blocks: __blkcnt64_t; { Number 512-byte blocks allocated. } + st_atime: __time_t; { Time of last access. } + st_atime_usec: LongWord; + st_mtime: __time_t; { Time of last modification. } + st_mtime_usec: LongWord; + st_ctime: __time_t; { Time of last status change. } + st_ctime_usec: LongWord; + st_ino: __ino64_t; { File serial number. } + end; +*) + +const +// stat_ver_mse = 3; + + path_max = 1024; + filetypes: array[filetypety] of longword = (0,s_ifdir,s_ifblk, + s_ifchr,s_ifreg,s_iflnk,s_ifsock,s_ififo); +// timeoffset = 0.0; +// o_cloexec = $080000; + +type + dirstreamlinuxdty = record + dir: pdirectorystream; + dirpath: pointer; + needsstat: boolean; + needstype: boolean; + end; + {$if sizeof(dirstreamlinuxdty) > sizeof(dirstreampty)} + {$error 'buffer overflow'} + {$ifend} + dirstreamlinuxty = record + case integer of + 0: (d: dirstreamlinuxdty;); + 1: (_bufferspace: dirstreampty;); + end; + +function unblocksignal(const signum: integer): boolean; + //true if blocked before +var + set1,set2: tsigset; +begin + sigemptyset(set1); + sigaddset(set1,signum); + pthread_sigmask(sig_unblock,@set1,@set2); + result:= sigismember(set2,signum) <> 0; +end; + +function blocksignal(const signum: integer): boolean; + //true if blocked before +var + set1,set2: tsigset; +begin + sigemptyset(set1); + sigaddset(set1,signum); + pthread_sigmask(sig_block,@set1,@set2); + result:= sigismember(set2,signum) <> 0; +end; + +function sys_getpid: procidty; +begin + result:= mselibc.getpid; +end; + +function sys_terminateprocess(const proc: prochandlety): syserrorty; +begin + if (kill(proc,sigterm) = 0) or (sys_getlasterror = esrch) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function sys_killprocess(const proc: prochandlety): syserrorty; +begin + if (kill(proc,sigkill) = 0) or (sys_getlasterror = esrch) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function sys_stdin: integer; +begin + result:= stdin; +end; + +function sys_stdout: integer; +begin + result:= stdout; +end; + +function sys_stderr: integer; +begin + result:= stderr; +end; + +function sys_getprintcommand: msestring; +begin + result:= defaultprintcommand; + if result = '' then begin + result:= 'lp -'; + end; +end; + +{$ifdef freebsd} +{$packrecords c} +type + procstat = record + end; + pprocstat = ^procstat; + + pargs = record //from user.h + end; + ppargs = ^pargs; + proc = record + end; + pproc = ^proc; + user = record + end; + puser = ^user; + vnode = record + end; + pvnode = ^vnode; + filedesc = record + end; + pfiledesc = ^filedesc; + vmspace = record + end; + pvmspace = ^vmspace; + + kinfo_proc = record + ki_structsize: cint; //* size of this structure */ + ki_layout: cint; //* reserved: layout identifier */ + ki_args: ppargs; //* address of command arguments */ + ki_paddr: pproc; //* address of proc */ + ki_addr: puser; //* kernel virtual addr of u-area */ + ki_tracep: pvnode; //* pointer to trace file */ + ki_textvp: pvnode; //* pointer to executable file */ + ki_fd: pfiledesc; //* pointer to open file info */ + ki_vmspace: pvmspace; //* pointer to kernel vmspace struct */ + ki_wchan: pointer; //* sleep address */ + ki_pid: pid_t; //* Process identifier */ + ki_ppid: pid_t; //* parent process id */ + ki_pgid: pid_t; //* process group id */ + ki_tpgid: pid_t; //* tty process group id */ + ki_sid: pid_t; //* Process session ID */ + ki_tsid: pid_t; //* Terminal session ID */ + ki_jobc: cshort; //* job control counter */ + //... see below + end; + pkinfo_proc = ^kinfo_proc; +{ + short ki_spare_short1; /* unused (just here for alignment) */ + dev_t ki_tdev; /* controlling tty dev */ + sigset_t ki_siglist; /* Signals arrived but not delivered */ + sigset_t ki_sigmask; /* Current signal mask */ + sigset_t ki_sigignore; /* Signals being ignored */ + sigset_t ki_sigcatch; /* Signals being caught by user */ + uid_t ki_uid; /* effective user id */ + uid_t ki_ruid; /* Real user id */ + uid_t ki_svuid; /* Saved effective user id */ + gid_t ki_rgid; /* Real group id */ + gid_t ki_svgid; /* Saved effective group id */ + short ki_ngroups; /* number of groups */ + short ki_spare_short2; /* unused (just here for alignment) */ + gid_t ki_groups[KI_NGROUPS]; /* groups */ + vm_size_t ki_size; /* virtual size */ + segsz_t ki_rssize; /* current resident set size in pages */ + segsz_t ki_swrss; /* resident set size before last swap */ + segsz_t ki_tsize; /* text size (pages) XXX */ + segsz_t ki_dsize; /* data size (pages) XXX */ + segsz_t ki_ssize; /* stack size (pages) */ + u_short ki_xstat; /* Exit status for wait & stop signal */ + u_short ki_acflag; /* Accounting flags */ + fixpt_t ki_pctcpu; /* %cpu for process during ki_swtime */ + u_int ki_estcpu; /* Time averaged value of ki_cpticks */ + u_int ki_slptime; /* Time since last blocked */ + u_int ki_swtime; /* Time swapped in or out */ + u_int ki_cow; /* number of copy-on-write faults */ + u_int64_t ki_runtime; /* Real time in microsec */ + struct timeval ki_start; /* starting time */ + struct timeval ki_childtime; /* time used by process children */ + long ki_flag; /* P_* flags */ + long ki_kiflag; /* KI_* flags (below) */ + int ki_traceflag; /* Kernel trace points */ + char ki_stat; /* S* process status */ + signed char ki_nice; /* Process "nice" value */ + char ki_lock; /* Process lock (prevent swap) count */ + char ki_rqindex; /* Run queue index */ + u_char ki_oncpu; /* Which cpu we are on */ + u_char ki_lastcpu; /* Last cpu we were on */ + char ki_tdname[TDNAMLEN+1]; /* thread name */ + char ki_wmesg[WMESGLEN+1]; /* wchan message */ + char ki_login[LOGNAMELEN+1]; /* setlogin name */ + char ki_lockname[LOCKNAMELEN+1]; /* lock name */ + char ki_comm[COMMLEN+1]; /* command name */ + char ki_emul[KI_EMULNAMELEN+1]; /* emulation name */ + char ki_loginclass[LOGINCLASSLEN+1]; /* login class */ + /* + * When adding new variables, take space for char-strings from the + * front of ki_sparestrings, and ints from the end of ki_spareints. + * That way the spare room from both arrays will remain contiguous. + */ + char ki_sparestrings[50]; /* spare string space */ + int ki_spareints[KI_NSPARE_INT]; /* spare room for growth */ + int ki_flag2; /* P2_* flags */ + int ki_fibnum; /* Default FIB number */ + u_int ki_cr_flags; /* Credential flags */ + int ki_jid; /* Process jail ID */ + int ki_numthreads; /* XXXKSE number of threads in total */ + lwpid_t ki_tid; /* XXXKSE thread id */ + struct priority ki_pri; /* process priority */ + struct rusage ki_rusage; /* process rusage statistics */ + /* XXX - most fields in ki_rusage_ch are not (yet) filled in */ + struct rusage ki_rusage_ch; /* rusage of children processes */ + struct pcb *ki_pcb; /* kernel virtual addr of pcb */ + void *ki_kstack; /* kernel virtual addr of stack */ + void *ki_udata; /* User convenience pointer */ + struct thread *ki_tdaddr; /* address of thread */ + /* + * When adding new variables, take space for pointers from the + * front of ki_spareptrs, and longs from the end of ki_sparelongs. + * That way the spare room from both arrays will remain contiguous. + */ + void *ki_spareptrs[KI_NSPARE_PTR]; /* spare room for growth */ + long ki_sparelongs[KI_NSPARE_LONG]; /* spare room for growth */ + long ki_sflag; /* PS_* flags */ + long ki_tdflags; /* XXXKSE kthread flag */ +} +const +///* +// * KERN_PROC subtypes +// */ + KERN_PROC_ALL = 0; //* everything */ + KERN_PROC_PID = 1; //* by process id */ + KERN_PROC_PGRP = 2; //* by process group id */ + KERN_PROC_SESSION = 3; //* by session of pid */ + KERN_PROC_TTY = 4; //* by controlling tty */ + KERN_PROC_UID = 5; //* by effective uid */ + KERN_PROC_RUID = 6; //* by real uid */ + KERN_PROC_ARGS = 7; //* get/set arguments/proctitle */ + KERN_PROC_PROC = 8; //* only return procs */ + KERN_PROC_SV_NAME = 9; //* get syscall vector name */ + KERN_PROC_RGID = 10; //* by real group id */ + KERN_PROC_GID = 11; //* by effective group id */ + KERN_PROC_PATHNAME = 12; //* path to executable */ + KERN_PROC_OVMMAP = 13; //* Old VM map entries for process */ + KERN_PROC_OFILEDESC = 14; //* Old file descriptors for process */ + KERN_PROC_KSTACK = 15; //* Kernel stacks for process */ + KERN_PROC_INC_THREAD = $10; //* +// * modifier for pid, pgrp, tty, +// * uid, ruid, gid, rgid and proc +// * This effectively uses 16-31 +// */ + KERN_PROC_VMMAP = 32; //* VM map entries for process */ + KERN_PROC_FILEDESC = 33; //* File descriptors for process */ + KERN_PROC_GROUPS = 34; //* process groups */ + KERN_PROC_ENV = 35; //* get environment */ + KERN_PROC_AUXV = 36; //* get ELF auxiliary vector */ + KERN_PROC_RLIMIT = 37; //* process resource limits */ + KERN_PROC_PS_STRINGS = 38; //* get ps_strings location */ + KERN_PROC_UMASK = 39; //* process umask */ + KERN_PROC_OSREL = 40; //* osreldate for process binary */ + KERN_PROC_SIGTRAMP = 41; //* signal trampoline location */ + +var + haslibprocstat: boolean; + procstat_open_sysctl: function(): pprocstat; cdecl; + procstat_close: procedure(procstat: pprocstat); cdecl; + procstat_getprocs: function(procstat: pprocstat; what: cint; arg: cint; + count: pcuint): pkinfo_proc; cdecl; + procstat_freeprocs: procedure(procstat: pprocstat; p: pkinfo_proc); cdecl; + +function sys_getprocesses: procitemarty; +var + stat: pprocstat; + proc,po1: pkinfo_proc; + ca1: cuint; +begin + result:= nil; + if haslibprocstat then begin + stat:= procstat_open_sysctl(); + if stat <> nil then begin + proc:= procstat_getprocs(stat,KERN_PROC_PROC,0,@ca1); + if proc <> nil then begin + setlength(result,ca1); + po1:= proc; + for ca1:= 0 to high(result) do begin + result[ca1].pid:= po1^.ki_pid; + result[ca1].ppid:= po1^.ki_ppid; + inc(pointer(po1),po1^.ki_structsize); + end; + procstat_freeprocs(stat,proc); + end; + procstat_close(stat); + end; + end; +end; + +{$else} +function sys_getprocesses: procitemarty; +var + filelist: tfiledatalist; + int1,int2: integer; + stream: ttextstream; + str1: string; +begin + filelist:= tfiledatalist.create(); + filelist.adddirectory('/proc',fil_name,nil,[fa_dir]); + setlength(result,filelist.count); + int2:= 0; + for int1:= 0 to filelist.count - 1 do begin + with filelist[int1] do begin + if (name[1] >= '0') and (name[1] <= '9') then begin + if ttextstream.trycreate(stream,'/proc/'+name+'/stat',fm_read) = + sye_ok then begin + stream.readln(str1); + with result[int2] do begin + if mselibc.sscanf(pchar(str1),'%d (%*a[^)]) %*c %d', +// {$ifdef FPC}[{$endif}@pid,@ppid{$ifdef FPC}]{$endif}) = 2 then begin + [@pid,@ppid]) = 2 then begin + inc(int2); + end; + end; + stream.free; + end; + end; + end; + end; + filelist.free; + setlength(result,int2); +end; +{$endif} + +procedure sys_schedyield; +begin + sched_yield; +end; + +procedure sys_usleep(const us: longword); +begin + if us = 0 then begin + sched_yield; + end + else begin + mselibc.usleep(us); + end; +end; + +function sys_filesystemiscaseinsensitive: boolean; +begin + result:= false; +end; + +function sys_getapplicationpath: filenamety; +begin + result:= filenamety(paramstr(0)); +end; + +function sys_getcommandlinearguments: msestringarty; +var + av: pcharpoaty; + ac: pinteger; + int1: integer; +begin + ac:= {$ifdef FPC}@argc{$else}@argcount{$endif}; + av:= pcharpoaty({$ifdef FPC}argv{$else}argvalues{$endif}); + setlength(result,ac^); + for int1:= 0 to ac^-1 do begin + result[int1]:= av^[int1]; + end; +end; + +procedure sys_getenvvars(out names: msestringarty; out values: msestringarty); +var + str1: string; + po1: ppchar; + po2,po3,po4: pchar; +begin + po1:= environ; + if po1 <> nil then begin + while true do begin + po2:= po1^; + if po2 = nil then begin + break; + end; + po3:= po2; + while po3^ <> #0 do begin + inc(po3); + end; + po4:= po2; + while (po4^ <> '=') and (po4 < po3) do begin + inc(po4); + end; + str1:= psubstr(po2,po4); + additem(names,msestring(str1)); + str1:= psubstr(po4+1,po3); + additem(values,msestring(str1)); + inc(po1); + end; + end; +end; + +function sys_getenv(const aname: msestring; out avalue: msestring): boolean; + //true if found +var + po1: pchar; + str1: ansistring; +begin + avalue:= ''; + po1:= getenv(pchar(ansistring(aname))); + result:= po1 <> nil; + if result then begin + str1:= po1; + avalue:= msestring(str1); + end; +end; + +function sys_setenv(const aname: msestring; const avalue: msestring): syserrorty; +begin + result:= sye_ok; + if setenv(pchar(ansistring(aname)),pchar(ansistring(avalue)),1) <> 0 then begin + result:= syelasterror; + end; +end; + +function sys_unsetenv(const aname: msestring): syserrorty; +begin + result:= sye_ok; + if unsetenv(pchar(ansistring(aname))) <> 0 then begin + result:= syelasterror; + end; +end; + +function timestampms: longword; +var + t1: timeval; +begin + gettimeofday(@t1,ptimezone(nil)); + result:= t1.tv_sec * 1000 + t1.tv_usec div 1000; +end; + +var + lastlocaltime: integer; + gmtoff: real; + +function sys_localtimeoffset: tdatetime; +var + tm: tunixtime; + int1: integer; +begin + int1:= __time(nil); + if int1 <> lastlocaltime then begin + lastlocaltime:= int1; + localtime_r(@int1,@tm); + gmtoff:= tm.__tm_gmtoff / (24.0*60.0*60.0); + end; + result:= gmtoff; +end; + +function sys_getutctime: tdatetime; +var + ti: timeval; +begin + gettimeofday(@ti,nil); +{$ifdef FPC} + result:= ti.tv_sec / (double(24.0)*60.0*60.0) + + ti.tv_usec / (double(24.0)*60.0*60.0*1e6) - unidatetimeoffset; +{$else} + result:= ti.tv_sec / (24.0*60.0*60.0) + + ti.tv_usec / (24.0*60.0*60.0*1e6) - unidatetimeoffset; +{$endif} +end; + +function sys_getlocaltime: tdatetime; +var + ti: timeval; +begin + gettimeofday(@ti,nil); +{$ifdef FPC} + result:= ti.tv_sec / (double(24.0)*60.0*60.0) + + ti.tv_usec / (double(24.0)*60.0*60.0*1e6) - unidatetimeoffset; +{$else} + result:= ti.tv_sec / (24.0*60.0*60.0) + + ti.tv_usec / (24.0*60.0*60.0*1e6) - unidatetimeoffset; +{$endif} + if ti.tv_sec = lastlocaltime then begin + result:= result + gmtoff; + end + else begin + result:= result + sys_localtimeoffset; + end; +end; + +function sys_tosysfilepath(var path: msestring): syserrorty; +begin + result:= sye_ok; +end; + +const + openmodes: array[fileopenmodety] of longword = +// fm_none,fm_read, fm_write,fm_readwrite,fm_create, + (0, o_rdonly,o_wronly,o_rdwr, o_rdwr or o_creat or o_trunc, +// fm_append + o_rdwr or o_creat {or o_trunc}); + +function getfilerights(const rights: filerightsty): longword; +const + filerights: array[filerightty] of longword = + (mselibc.s_irusr,mselibc.s_iwusr,mselibc.s_ixusr, + mselibc.s_irgrp,mselibc.s_iwgrp,mselibc.s_ixgrp, + mselibc.s_iroth,mselibc.s_iwoth,mselibc.s_ixoth, + mselibc.s_isuid,mselibc.s_isgid,mselibc.s_isvtx); +var + fr: filerightty; +begin + result:= 0; + for fr:= low(filerightty) to high(filerightty) do begin + if fr in rights then begin + result:= result or filerights[fr]; + end; + end; +end; + +function tosys(const avalue: filenamety): string; +begin + if filenameutfoptions <> [] then begin + result:= stringtoutf8(avalue,filenameutfoptions); + end + else begin + result:= ansistring(avalue); + end; +end; + +function fromsys(const avalue: string): filenamety; +begin + if filenameutfoptions <> [] then begin + result:= utf8tostringansi(avalue,filenameutfoptions); + end + else begin + result:= filenamety(avalue); + end; +end; + +function sys_createdir(const path: msestring; const rights: filerightsty): syserrorty; +var + str1: string; +begin + str1:= tosys(path); + if mselibc.__mkdir(pchar(str1), + getfilerights(rights)) <> 0 then begin +// result:= sye_createdir; + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +procedure setcloexec(const fd: integer); +var + flags: integer; +begin + flags:= fcntl(fd,f_getfd); + if flags <> -1 then begin + flags:= flags or fd_cloexec; + fcntl(fd,f_setfd,[flags]) + end; +end; + +function sys_openfile(const path: filenamety; const openmode: fileopenmodety; + const accessmode: fileaccessmodesty; + const rights: filerightsty; out handle: integer): syserrorty; +var + str1: string; + str2: msestring; + stat1: _stat; +const + defaultopenflags = o_cloexec; +begin + str2:= path; + sys_tosysfilepath(str2); + str1:= tosys(str2); + handle:= Integer(mselibc.open(PChar(str1), openmodes[openmode] or + defaultopenflags,[getfilerights(rights)])); + if handle >= 0 then begin + if fstat(handle,@stat1) = 0 then begin + if s_isdir(stat1.st_mode) then begin + mselibc.__close(handle); + handle:= -1; + result:= sye_isdir; + end + else begin + setcloexec(handle); + result:= sye_ok; + end; + end + else begin + mselibc.__close(handle); + handle:= -1; + result:= syelasterror; + end; + end + else begin + result:= syelasterror; + end; +end; + +function sys_closefile(const handle: integer): syserrorty; +var + int1: cint; +begin + result:= sye_ok; + if (handle <> invalidfilehandle) then begin + repeat + int1:= mselibc.__close(handle); + until (int1 = 0) or (sys_getlasterror <> EINTR); + if int1 <> 0 then begin + result:= syelasterror; + end; + end; +end; + +function sys_flushfile(const handle: integer): syserrorty; +begin + result:= sye_ok; + while mselibc.fsync(handle) <> 0 do begin + if sys_getlasterror <> eintr then begin + result:= syelasterror; + break; + end; + end; +end; + +function sys_dup(const source: integer; out dest: integer): syserrorty; +begin + dest:= dup(source); + if dest = -1 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function sys_truncatefile(const handle: integer; const size: int64): syserrorty; +begin + result:= sye_ok; + while mselibc.ftruncate64(handle,size) <> 0 do begin + if sys_getlasterror <> eintr then begin + result:= syelasterror; + break; + end; + end; +end; + +function sys_read(fd: longint; buf: pointer; nbytes: dword): integer; +begin + repeat + result:= mselibc.__read(fd,buf^,nbytes); + until (result >= 0) or (sys_getlasterror <> eintr); + if (result < 0) and (sys_getlasterror = EAGAIN) then begin + result:= 0; //nonblock + end; +end; + +function sys_write(fd:longint; buf: pointer; nbytes: longword): integer; +var + int1: integer; +begin + result:= nbytes; + repeat + int1:= mselibc.__write(fd,buf^,nbytes); + if int1 = -1 then begin + if sys_getlasterror <> eintr then begin + result:= int1; + break; + end; + continue; + end; + inc(pchar(buf),int1); + dec(nbytes,int1); + until integer(nbytes) <= 0; +end; + +function sys_errorout(const atext: string): syserrorty; +begin + if (length(atext) = 0) or + (mselibc.__write(2, + pchar(atext)^,length(atext)) = length(atext)) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +{$R-} +function sys_gettimeus: longword; +var + time1: timeval; + time2: timespec; +begin + if ({$ifndef FPC}@{$endif}clock_gettime = nil) or + (clock_gettime(clock_monotonic,@time2) <> 0) then begin + gettimeofday(@time1,ptimezone(nil)); + result:= time1.tv_sec * 1000000 + time1.tv_usec; + end + else begin + result:= time2.tv_sec * 1000000 + time2.tv_nsec div 1000; + end; +end; + +{$ifdef FPC} + +function threadexec(infopo : pointer) : ptrint{longint}; +begin + threadinfoty(infopo^).id:= threadty(getcurrentthreadid); + pthread_setcanceltype(pthread_cancel_asynchronous,nil); + pthread_setcancelstate(pthread_cancel_enable,nil); + unblocksignal(sigio); + result:= threadinfoty(infopo^).threadproc(); +end; + +{$else} + +function threadexec(infopo: pointer): integer; cdecl; +begin + threadinfoty(infopo^).id:= threadty(getcurrentthreadid); + pthread_setcanceltype(pthread_cancel_asynchronous,nil); + pthread_setcancelstate(pthread_cancel_enable,nil); + result:= threadinfoty(infopo^).threadproc(); +end; + +{$endif} + +function sys_issamethread(const a,b: threadty): boolean; +begin + result:= pthread_equal(a,b) <> 0; +end; + +function sys_threadcreate(var info: threadinfoty): syserrorty; +var +{$ifndef FPC} + attr: pthread_attr_t; +{$else} + id1: threadty; +{$endif} + sigs1,sigs2: __sigset_t; +begin + {$ifdef FPC} + with info do begin + sigfillset(sigs1); //block all + pthread_sigmask(sig_block,@sigs1,@sigs2); + id:= 0; + id:= threadty(beginthread(@threadexec,@info,tthreadid(id1),info.stacksize)); + pthread_sigmask(sig_setmask,@sigs2,nil); //restore + if id = 0 then begin + result:= sye_thread; + end + else begin + result:= sye_ok; + end; + end; + {$else} + with info do begin + ismultithread:= true; + pthread_attr_init(attr); + if pthread_create(ppthread_t(@id), + @attr,{$ifdef FPC}@{$endif}threadexec,@info) <> 0 then begin + result:= sye_thread; + end + else begin + result:= sye_ok; + end; + end; + {$endif} +end; + +function sys_threadwaitfor(var info: threadinfoty): syserrorty; +begin +{$ifdef FPC} + waitforthreadterminate(tthreadid(info.id),0); + result:= sye_ok; +{$else} + result:= syeseterror(pthread_join(info.id,nil)); +{$endif} +end; + +function sys_threaddestroy(var info: threadinfoty): syserrorty; +begin + result:= sye_ok; +{$ifdef FPC} + killthread(tthreadid(info.id)); +{$else} + pthread_detach(info.id); + pthread_cancel(info.id); +{$endif} +end; + +function sys_threadschedyield: syserrorty; +begin + result:= sye_ok; + sched_yield; +end; + +function sys_getcurrentthread: threadty; +begin + result:= pthread_self; +end; + +function sys_copyfile(const oldfile,newfile: msestring): syserrorty; +const + bufsize = $2000; //8k +var + str1,str2: string; + source,dest: integer; + stat: _stat64; + lwo1: longword; + po1: pointer; +begin + str1:= tosys(oldfile); + str2:= tosys(newfile); + result:= sye_copyfile; + source:= mselibc.open(pchar(str1),o_rdonly); + if source <> -1 then begin + if fstat64(source,@stat) = 0 then begin + dest:= mselibc.open(pchar(str2),o_rdwr or o_creat or o_trunc, + [s_irusr or s_iwusr]); + if dest <> -1 then begin + getmem(po1,bufsize); + lwo1:= 0; //compiler warning + while true do begin + lwo1:= mselibc.__read(source,po1^,bufsize); + if (lwo1 = 0) or (lwo1 = longword(-1)) then begin + break; + end; + if mselibc.__write(dest,po1^,lwo1) <> integer(lwo1) then begin + break; + end; + end; + freemem(po1); + if lwo1 = 0 then begin + if mselibc.fchmod(dest,stat.st_mode) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + result:= syelasterror; + end; + mselibc.__close(dest); + end + else begin + result:= syelasterror; + end; + end + else begin + result:= syelasterror; + end; + mselibc.__close(source); + end + else begin + result:= syelasterror; + end; +end; + +function sys_renamefile(const oldname,newname: filenamety): syserrorty; +var + str1,str2: string; +begin + str1:= tosys(oldname); + str2:= tosys(newname); + if mselibc.__rename(pchar(str1),pchar(str2)) = -1 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function sys_deletefile(const filename: filenamety): syserrorty; +var + str1: string; +begin + str1:= tosys(filename); + if mselibc.unlink(pchar(str1)) = -1 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function sys_deletedir(const filename: filenamety): syserrorty; +var + str1: string; +begin + str1:= tosys(filename); + if mselibc.rmdir(pchar(str1)) = -1 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function getfiletype(value: longword): filetypety; +var + count: filetypety; +begin + result:= ft_unknown; + value:= value and s_ifmt; + for count:= low(filetypety) to high(filetypety) do begin + if value = filetypes[count] then begin + result:= count; + break; + end; + end; +end; + +function getfileattributes(value: __mode_t): fileattributesty; +begin + result:= []; + + if value and s_irusr <> 0 then include(result,fa_rusr); + if value and s_iwusr <> 0 then include(result,fa_wusr); + if value and s_ixusr <> 0 then include(result,fa_xusr); + + if value and s_irgrp <> 0 then include(result,fa_rgrp); + if value and s_iwgrp <> 0 then include(result,fa_wgrp); + if value and s_ixgrp <> 0 then include(result,fa_xgrp); + + if value and s_iroth <> 0 then include(result,fa_roth); + if value and s_iwoth <> 0 then include(result,fa_woth); + if value and s_ixoth <> 0 then include(result,fa_xoth); + + if value and s_isuid <> 0 then include(result,fa_suid); + if value and s_isgid <> 0 then include(result,fa_sgid); + if value and s_isvtx <> 0 then include(result,fa_svtx); + +end; + +function getmodebits(const value: fileattributesty): __mode_t; +begin + result:= 0; + + if fa_rusr in value then result:= result or s_irusr; + if fa_wusr in value then result:= result or s_iwusr; + if fa_xusr in value then result:= result or s_ixusr; + + if fa_rgrp in value then result:= result or s_irgrp; + if fa_wgrp in value then result:= result or s_iwgrp; + if fa_xgrp in value then result:= result or s_ixgrp; + + if fa_roth in value then result:= result or s_iroth; + if fa_woth in value then result:= result or s_iwoth; + if fa_xoth in value then result:= result or s_ixoth; + + if fa_suid in value then result:= result or s_isuid; + if fa_sgid in value then result:= result or s_isgid; + if fa_svtx in value then result:= result or s_isvtx; + +end; + +function getaccessbits(const value: accessmodesty): cint; +begin + result:= 0; + if am_read in value then result:= result or r_ok; + if am_write in value then result:= result or w_ok; + if am_execute in value then result:= result or x_ok; + if am_exist in value then result:= result or f_ok; +end; + +function filetimetodatetime(const value: timespec): tdatetime; +begin + result:= value.tv_sec / (double(24.0)*60.0*60.0) + + value.tv_nsec / (double(24.0)*60.0*60.0*1e9) - unidatetimeoffset; +end; + +function filetimetodatetime(const sec,nsec: culong): tdatetime; +begin + result:= sec / (double(24.0)*60.0*60.0) + + nsec / (double(24.0)*60.0*60.0*1e9) - unidatetimeoffset; +end; + +function sys_getcurrentdir: msestring; +var + str1: string; + po1: pchar; +begin + str1:= ''; + repeat + setlength(str1,length(str1) + path_max); + po1:= getcwd(@str1[1],length(str1)); + until (po1 <> nil) or (sys_getlasterror() <> erange); + setlength(str1,strlen(po1)); + result:= msestring(str1); +end; + +function sys_getuserhomedir: filenamety; +var + po1: pchar; +begin + po1:= getenv('HOME'); + if po1 <> nil then begin + result:= filenamety(string(po1)); + end + else begin + result:= ''; + end; +end; + +function sys_getusername: msestring; +var + po1: pchar; + s1: string; + pwd: passwd; + res: ppasswd; + i1: cint; +begin + result:= ''; + if getpwuid_r <> nil then begin + setlength(s1,10000); + while true do begin + i1:= getpwuid_r(getuid(),@pwd,pointer(s1),length(s1),@res); + case i1 of + 0: begin + if res <> nil then begin + result:= msestring(ansistring(pwd.pw_name)); + end; + break; + end; + eintr: begin + //try again + end; + erange: begin + setlength(s1,length(s1)*2); + end; + else begin + break; //error + end; + end; + end; + end + else begin + if cuserid <> nil then begin + po1:= cuserid(nil); + result:= msestring(ansistring(po1)); + end; + end; +end; + +function sys_getapphomedir: filenamety; +begin + result:= sys_getuserhomedir; +end; + +function sys_gettempdir: filenamety; +var + str1: string; +begin + str1:= getenvironmentvariable('temp'); + if str1 = '' then begin + str1:= getenvironmentvariable('tmp'); + end; + if str1 = '' then begin + str1:= '/tmp/' + end; + str1:= includetrailingpathdelimiter(str1); + result:= tomsefilepath(filenamety(str1)); +end; + +function sys_setcurrentdir(const dirname: filenamety): syserrorty; +var + str1: string; +begin + str1:= tosys(dirname); + if mselibc.__chdir(pchar(str1)) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +const + nameattributes = [fa_hidden]; + typeattributes = nameattributes + [fa_dir]; + +function sys_opendirstream(var stream: dirstreamty): syserrorty; +var + str1: string; +begin + checkdirstreamdata(stream); + str1:= tosys(stream.dirinfo.dirname); + with stream,dirinfo,dirstreamlinuxty(platformdata) do begin +{$ifdef FPC} + d.dir:= pdir(opendir(pchar(str1))); +{$else} + pointer(d.dir):= pdir(opendir(pchar(str1))); +{$endif} + if d.dir = nil then begin + result:= syelasterror; + end + else begin + if (str1 <> '') and (str1[length(str1)] <> '/') then begin + str1:= str1 + '/'; + end; + string(d.dirpath):= str1; //for stat + d.needsstat:= (infolevel >= fil_ext1) or + not (fa_all in include) and (include-typeattributes <> []) or + (exclude-typeattributes <> []); + d.needstype:= not d.needsstat and + ((infolevel >= fil_type) or + not (fa_all in include) and (include-nameattributes <> []) or + (exclude-nameattributes <> [])); + result:= sye_ok; + end; + end; +end; + +function sys_closedirstream(var stream: dirstreamty): syserrorty; +begin + with dirstreamlinuxty(stream.platformdata) do begin + string(d.dirpath):= ''; + if closedir(pointer(d.dir)) = 0 then begin + result:= sye_ok; + end + else begin + result:= sye_dirstream; + end; + end; +end; + +function sys_readdirstream(var stream: dirstreamty; var info: fileinfoty): boolean; + //true if valid +var + dirent: dirent64; + po1: pdirent64; + statbuffer: _stat64; + //stat1: tstatbuf; + str1: string; + error: boolean; +begin + result:= false; + po1:= nil; + with stream,dirinfo,dirstreamlinuxty(platformdata) do begin + if not ((include <> []) and (fa_all in exclude)) then begin + while true do begin + if (readdir64_r(pdir(d.dir),@dirent,@po1) = 0) and + (po1 <> nil) then begin + with info do begin + str1:= dirent.d_name; + name:= fromsys(str1); + if checkfilename(info.name,stream) then begin + if d.needsstat or d.needstype and + ((dirent.d_type = dt_unknown) or (dirent.d_type = dt_lnk)) then begin + error:= stat64(pchar(string(d.dirpath)+str1),@statbuffer) <> 0; + end + else begin + error:= false; + statbuffer.st_mode:= dirent.d_type shl 12; + end; + with extinfo1,extinfo2,statbuffer do begin + if not error then begin + filetype:= getfiletype(st_mode); + attributes:= getfileattributes(st_mode); + if (length(name) > 0) and (info.name[1] = '.') then begin + system.include(attributes,fa_hidden); + end; + if filetype = ft_dir then begin + system.include(attributes,fa_dir); + end; + if ((fa_all in include) or (attributes * include <> [])) and + ((attributes * exclude) = []) then begin + if d.needstype then begin + system.include(state,fis_typevalid); + end; + if d.needsstat then begin + state:= state + [fis_typevalid,fis_extinfo1valid,fis_extinfo2valid]; + size:= st_size; + modtime:= filetimetodatetime(st_mtime,st_mtime_nsec); + accesstime:= filetimetodatetime(st_atime,st_atime_nsec); + ctime:= filetimetodatetime(st_ctime,st_ctime_nsec); + id:= st_ino; + owner:= st_uid; + group:= st_gid; + end; + result:= true; + break; + end; + end; + end; + end; + end; + end + else begin + break; + end; + end; + end; + end; +end; + +procedure stattofileinfo(const statbuffer: _stat64; var info: fileinfoty); +begin + with info,extinfo1,extinfo2,statbuffer do begin + filetype:= getfiletype(st_mode); + attributes:= getfileattributes(st_mode); + if (length(name) > 0) and (info.name[1] = '.') then begin + system.include(attributes,fa_hidden); + end; + if filetype = ft_dir then begin + system.include(attributes,fa_dir); + end; + state:= state + [fis_typevalid,fis_extinfo1valid,fis_extinfo2valid]; + size:= st_size; + modtime:= filetimetodatetime(st_mtime,st_mtime_nsec); + accesstime:= filetimetodatetime(st_atime,st_atime_nsec); + ctime:= filetimetodatetime(st_ctime,st_ctime_nsec); + id:= st_ino; + owner:= st_uid; + group:= st_gid; + end; +end; + +function sys_getfileinfo(const path: filenamety; var info: fileinfoty): boolean; +var + str1: filenamety; + statbuffer: _stat64; +begin + clearfileinfo(info); + str1:= tosysfilepath(path); + fillchar(statbuffer,sizeof(statbuffer),0); + result:= stat64(pchar(tosys(str1)),@statbuffer) = 0; + if result then begin + stattofileinfo(statbuffer,info); + splitfilepath(filepath(path),str1,info.name); + end; +end; + +function sys_getfdinfo(const fd: longint; var info: fileinfoty): boolean; +var + statbuffer: _stat64; +begin + clearfileinfo(info); + fillchar(statbuffer,sizeof(statbuffer),0); + result:= fstat64(fd,@statbuffer) = 0; + if result then begin + stattofileinfo(statbuffer,info); + end; +end; + +function sys_access(const path: filenamety; + const accessmodes: accessmodesty): syserrorty; +var + str1: filenamety; +begin + str1:= tosysfilepath(path); + if mselibc.access(pchar(string(str1)), + getaccessbits(accessmodes)) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror(); + end; +end; + +function sys_setfilerights(const path: filenamety; + const rights: filerightsty): syserrorty; +var + str1: filenamety; +begin + str1:= tosysfilepath(path); + if chmod(pchar(tosys(str1)), + getmodebits(fileattributesty(rights))) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror(); + end; +end; + +function sys_setfdrights(const fd: longint; + const rights: filerightsty; + const filename: filenamety = ''): syserrorty; +begin + if fchmod(fd,getmodebits(fileattributesty(rights))) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror(); + end; +end; + +function sys_getlangname: string; +var + po1: pchar; + ar1: stringarty; +begin + po1:= setlocale(lc_messages,nil); + ar1:= splitstring(string(po1),'_'); + if high(ar1) >= 0 then begin + result:= ar1[0]; + end + else begin + result:= string(po1); + end; +end; + +procedure sigtest(SigNum: Integer); cdecl; +begin +end; + +procedure sigdummy(SigNum: Integer); cdecl; +begin +end; + +procedure setsighandlers; +var + info: tsigaction; +begin + fillchar(info,sizeof(info),0); + with info do begin + {$ifdef FPC} + sa_handler:= @sigdummy; + {$else} + __sigaction_handler:= @sigdummy; + {$endif} + sa_flags:= sa_restart; + end; + sigaction(sigio,@info,nil); +end; + +{$ifdef freebsd} +procedure initfreebsd(); +begin + haslibprocstat:= checkprocaddresses(['libprocstat.so.1','libprocstat.so'], + ['procstat_open_sysctl','procstat_close','procstat_getprocs', + 'procstat_freeprocs'], + [@procstat_open_sysctl,@procstat_close,@procstat_getprocs, + @procstat_freeprocs]); +end; +{$endif} + +initialization + setsighandlers; +{$ifdef freebsd} + initfreebsd(); +{$endif} +end. diff --git a/mseide-msegui/lib/common/kernel/linux/msesysintf1.pas b/mseide-msegui/lib/common/kernel/linux/msesysintf1.pas new file mode 100644 index 0000000..55469e2 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/msesysintf1.pas @@ -0,0 +1,432 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesysintf1; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msesystypes,mselibc,sysutils; +type + linuxmutexty = record + case integer of + 0: (mutex: pthread_mutex_t;); + 1: (_bufferspace: mutexty;); + end; + linuxconddty = record + cond: tcondvar; + mutex: pthread_mutex_t; + end; + linuxcondty = record + case integer of + 0: (d: linuxconddty;); + 1: (_bufferspace: condty;); + end; + + linuxsemdty = record + destroyed: integer; + sema: tsemaphore; + end; + linuxsemty = record + case integer of + 0: (d: linuxsemdty;); + 1: (_bufferspace: semty;); + end; + +{$ifdef FPC} + {$include ../msesysintf1.inc} +{$else} + {$include msesysintf1.inc} +{$endif} + +function unigettimestamp(timeoutusec: integer): timespec; +procedure initmutex(out mutex: pthread_mutex_t); + +{$ifdef mse_debuggdisync} + {$define mse_debugmutex} +{$endif} +{$ifdef mse_debugmutex} +var + mutexsequ: integer; + mutexcount: integer; + appmutexcount: integer; + appmutexlockth: threadty; + appmutexlockc: integer; + appmutexlocks: integer; + appmutexunlockth: threadty; + appmutexunlockc: integer; + appmutexunlocks: integer; +{$endif} + +implementation + +uses + dateutils {$ifdef mse_debugmutex},mseapplication,msesysintf{$endif} + (*,msedate *); + +const + unidatetimeoffset = -25569; + +function unigettimestamp(timeoutusec: integer): timespec; +var + ti: timeval; +begin + gettimeofday(@ti,nil); + ti.tv_usec:= ti.tv_usec + timeoutusec; + result.tv_sec:= ti.tv_sec + integer(longword(ti.tv_usec) div 1000000); + result.tv_nsec:= (longword(ti.tv_usec) mod 1000000) * 1000; +end; + +function sys_getlasterror: Integer; +begin + {$ifdef FPC}{$checkpointer off}{$endif} + Result := __errno_location()^; + {$ifdef FPC}{$checkpointer default}{$endif} +end; + +procedure sys_setlasterror(const avalue: integer); +begin + {$ifdef FPC}{$checkpointer off}{$endif} + __errno_location()^:= avalue; + {$ifdef FPC}{$checkpointer default}{$endif} +end; + +function sys_geterrortext(aerror: integer): string; +const + buflen = 1024; +var + buffer: array[0..buflen] of char; + po1: pchar; +begin + result:= ''; //compilerwarning + po1:= strerror_r(aerror,pchar(@buffer),buflen); + setstring(result,po1,strlen(po1)); +end; + +procedure initmutex(out mutex: pthread_mutex_t); +var + attr: tmutexattribute; +begin + pthread_mutexattr_init(attr); + pthread_mutexattr_settype(attr,recursive); +// attr.__mutexkind:= recursive; + pthread_mutex_init(@mutex,@attr); + pthread_mutexattr_destroy(attr); +end; + +procedure destroymutex(var mutex: pthread_mutex_t); +begin + while pthread_mutex_destroy(mutex) = ebusy do begin + pthread_mutex_unlock(mutex); + {$ifdef mse_debugmutex} + interlockeddecrement(mutexcount); + if application.getmutexaddr = @mutex then begin + interlockeddecrement(appmutexcount); + end; + {$endif} + end; +end; + +function sys_mutexcreate(out mutex: mutexty): syserrorty; +begin + initmutex(linuxmutexty(mutex).mutex); + result:= sye_ok; +end; + +function sys_mutexdestroy(var mutex: mutexty): syserrorty; +begin + destroymutex(linuxmutexty(mutex).mutex); + result:= sye_ok; +end; + +function sys_mutexlock(var mutex: mutexty): syserrorty; +begin + if pthread_mutex_lock(linuxmutexty(mutex).mutex) = 0 then begin + result:= sye_ok; + {$ifdef mse_debugmutex} + interlockedincrement(mutexsequ); + interlockedincrement(mutexcount); + if applicationallocated and (application.getmutexaddr = @mutex) then begin + interlockedincrement(appmutexcount); + appmutexlockth:= sys_getcurrentthread; + appmutexlockc:= appmutexcount; + appmutexlocks:= mutexsequ; + end; + {$endif} + end + else begin + result:= sye_mutex; + end; +end; + +function sys_mutextrylock(var mutex: mutexty): syserrorty; +var + int1: integer; +begin + int1:= pthread_mutex_trylock(linuxmutexty(mutex).mutex); + {$ifdef mse_debugmutex} + if int1 = 0 then begin + interlockedincrement(mutexsequ); + interlockedincrement(mutexcount); + if application.getmutexaddr = @mutex then begin + interlockedincrement(appmutexcount); + appmutexlockth:= sys_getcurrentthread; + appmutexlockc:= appmutexcount; + appmutexlocks:= mutexsequ; + end; + end; + {$endif} + case int1 of + 0: result:= sye_ok; + ebusy: result:= sye_busy; + else result:= sye_mutex; + end; +end; + +function sys_mutexunlock(var mutex: mutexty): syserrorty; +begin + {$ifdef mse_debugmutex} + interlockedincrement(mutexsequ); + interlockeddecrement(mutexcount); + if applicationallocated and (application.getmutexaddr = @mutex) then begin + interlockeddecrement(appmutexcount); + appmutexunlockth:= sys_getcurrentthread; + appmutexunlockc:= appmutexcount; + appmutexunlocks:= mutexsequ; + end; + {$endif} + if pthread_mutex_unlock(linuxmutexty(mutex).mutex) = 0 then begin + result:= sye_ok; + end + else begin + result:= sye_mutex; + end; +end; + +function sys_semcreate(out sem: semty; count: integer): syserrorty; +begin + fillchar(sem,sizeof(sem),0); + with linuxsemty(sem) do begin + if sem_init(d.sema,0,count) = 0 then begin + result:= sye_ok; + end + else begin + result:= sye_semaphore; + end; + end; +end; + +function sempost1(var sem: semty): syserrorty; +begin + with linuxsemty(sem) do begin + if sem_post(d.sema) = 0 then begin + result:= sye_ok; + end + else begin + result:= sye_semaphore; + end; + end; +end; + +function sys_sempost(var sem: semty): syserrorty; +begin + with linuxsemty(sem) do begin + if d.destroyed <> 0 then begin + result:= sye_semaphore; + exit; + end; + end; + result:= sempost1(sem); +end; + +function sys_semdestroy(var sem: semty): syserrorty; +var + int1: integer; +begin + result:= sye_ok; + with linuxsemty(sem) do begin + int1:= interlockedincrement(d.destroyed); + if int1 = 1 then begin + while sys_semcount(sem) = 0 do begin + if sem_post(d.sema) <> 0 then begin + break; + end; + end; + sem_destroy(d.sema); + end; + end; +end; + +function sys_semwait(var sem: semty; timeoutusec: integer): syserrorty; + //timeoutus = 0 -> no timeout; +var + time1: ttimespec; +// err: integer; +begin + result:= sye_semaphore; + with linuxsemty(sem) do begin + if d.destroyed <> 0 then begin + exit; + end; + if timeoutusec <= 0 then begin + while sem_wait(d.sema) <> 0 do begin + if sys_getlasterror <> eintr then begin + exit; + end; + end; + end + else begin + time1:= unigettimestamp(timeoutusec); + while sem_timedwait(d.sema,@time1) <> 0 do begin + case sys_getlasterror of + eintr: begin + end; + etimedout: begin + result:= sye_timeout; + exit; + end + else begin + exit; + end; + end; + end; + end; + end; + result:= sye_ok; +end; + +function sys_semtrywait(var sem: semty): boolean; +begin + with linuxsemty(sem) do begin + if d.destroyed <> 0 then begin + result:= false; + exit; + end; + repeat + result:= sem_trywait(d.sema) = 0; + until result or (sys_getlasterror <> eintr); + end; +end; + +function sys_semcount(var sem: semty): integer; +begin + with linuxsemty(sem) do begin + sem_getvalue(d.sema,@result); + end; +end; + +function sys_condcreate(out cond: condty): syserrorty; +begin + pthread_cond_init(linuxcondty(cond).d.cond,nil); + initmutex(linuxcondty(cond).d.mutex); + result:= sye_ok; +end; + +function sys_conddestroy(var cond: condty): syserrorty; +begin + while true do begin + pthread_mutex_lock(linuxcondty(cond).d.mutex); + if pthread_cond_destroy(linuxcondty(cond).d.cond) = 0 then begin + pthread_mutex_unlock(linuxcondty(cond).d.mutex); + destroymutex(linuxcondty(cond).d.mutex); + break; + end; + pthread_cond_broadcast(linuxcondty(cond).d.cond); + pthread_mutex_unlock(linuxcondty(cond).d.mutex); + end; + result:= sye_ok; +end; + +function sys_condlock(var cond: condty): syserrorty; +begin + pthread_mutex_lock(linuxcondty(cond).d.mutex); + result:= sye_ok; +end; + +function sys_condunlock(var cond: condty): syserrorty; +begin + pthread_mutex_unlock(linuxcondty(cond).d.mutex); + result:= sye_ok; +end; + +function sys_condsignal(var cond: condty): syserrorty; +begin + pthread_cond_signal(linuxcondty(cond).d.cond); + result:= sye_ok; +end; + +function sys_condbroadcast(var cond: condty): syserrorty; +begin + pthread_cond_broadcast(linuxcondty(cond).d.cond); + result:= sye_ok; +end; + +function sys_condwait(var cond: condty; timeoutusec: integer): syserrorty; + //timeoutus = 0 -> no timeout; + //gue_ok -> condition signaled + //gue_timeout -> timeout + //gue_cond -> error +var + time1: ttimespec; +begin + result:= sye_ok; + if timeoutusec = 0 then begin + pthread_cond_wait(linuxcondty(cond).d.cond,linuxcondty(cond).d.mutex); + end + else begin + time1:= unigettimestamp(timeoutusec); + if pthread_cond_timedwait(linuxcondty(cond).d.cond,linuxcondty(cond).d.mutex, + @time1) <> 0 then begin + result:= sye_timeout; + end; + end; +end; + +function sys_utctolocaltime(const value: tdatetime): tdatetime; +var + ti1: integer; + rea1: real; + tm: tunixtime; +begin + rea1:= value + unidatetimeoffset; + if rea1 < 0 then begin + ti1:= 0; + end + else begin + ti1:= round(rea1) * 24*60*60; //seconds + end; + localtime_r(@ti1,@tm); + result:= incsecond(value,tm.__tm_gmtoff); +// result:= value + sys_localtimeoffset; +end; + +function sys_localtimetoutc(const value: tdatetime): tdatetime; +var + year,month,day,hour,minute,second,millisecond: word; + tm: tunixtime; +begin + if value < -unidatetimeoffset then begin + decodedatetime(-unidatetimeoffset,year,month,day,hour,minute,second,millisecond); + end + else begin + decodedatetime(value,year,month,day,hour,minute,second,millisecond); + end; + with tm do begin + tm_sec:= second; + tm_min:= minute; + tm_hour:= hour; + tm_mday:= day; + tm_mon:= month; + tm_year:= year-1900; + end; + timelocal(tm); + result:= incsecond(value,-tm.__tm_gmtoff); +// result:= value - sys_localtimeoffset; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mseuniintf.pas b/mseide-msegui/lib/common/kernel/linux/mseuniintf.pas new file mode 100644 index 0000000..ef55ea9 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mseuniintf.pas @@ -0,0 +1,131 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseuniintf; //X11 + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics,msetypes{msestrings}; + +{$include ../mseuniintf.inc} + +function uni_listfontswithglyph(achar: msechar): msestringarty; + +implementation +uses + mseguiintf,msex11gdi,mxft,xlib,msefontconfig; + +function uni_getfontwithglyph(var drawinfo: drawinfoty): boolean; +var + pat1: pfcpattern; + charset1,charset2: pfccharset; + res1: tfcresult; + fontset1: pfcfontset; + po1: ppfcpattern; + int1: integer; + font1: pxftfont; +begin + result:= false; + if hasxft then begin +{$ifdef FPC} {$checkpointer off} {$endif} + pat1:= fontdatatoxftpat(drawinfo.getfont.fontdata^,false); + if pat1 <> nil then begin + with drawinfo.getfont.fontdata^ do begin + charset1:= fccharsetcreate(); + fccharsetaddchar(charset1,h.d.glyph); + fcpatternaddcharset(pat1,fc_charset,charset1); + fccharsetdestroy(charset1); + fcconfigsubstitute(nil,pat1,fcmatchpattern); + fcconfigsubstitute(nil,pat1,fcmatchfont); + xftdefaultsubstitute(msedisplay,xdefaultscreen(msedisplay),pat1); + fontset1:= fcfontsort(nil,pat1,true,@charset1,@res1); + if fccharsethaschar(charset1,h.d.glyph) then begin + with fontset1^ do begin + po1:= fonts; + for int1:= 0 to nfont - 1 do begin + if fcpatterngetcharset(po1^,fc_charset,0,@charset2) = fcresultmatch then begin + if fccharsethaschar(charset2,h.d.glyph) then begin + font1:= xftfontopenpattern(msedisplay, + fcfontrenderprepare(nil,pat1,po1^)); + if font1 <> nil then begin + if xftcharexists(msedisplay,font1,h.d.glyph) then begin + getxftfontdata(font1,drawinfo); + result:= true; + end + else begin + xftfontclose(msedisplay,font1); + end; + end; + break; + end; + end; + inc(po1); + end; + end; + end; + fccharsetdestroy(charset1); + fcpatterndestroy(pat1); + fcfontsetdestroy(fontset1); + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} + end; +end; + +function uni_listfontswithglyph(achar: msechar): msestringarty; +var + pat1: pfcpattern; + charset1,charset2: pfccharset; + res1: tfcresult; + fontset1: pfcfontset; + po1: ppfcpattern; + int1,int2: integer; +// font1: pxftfont; + po2: pchar; +begin + result:= nil; + if hasxft then begin +{$ifdef FPC} {$checkpointer off} {$endif} + pat1:= fcpatterncreate(); + charset1:= fccharsetcreate(); + fccharsetaddchar(charset1,longword(achar)); + fcpatternaddcharset(pat1,fc_charset,charset1); + fccharsetdestroy(charset1); + fcconfigsubstitute(nil,pat1,fcmatchpattern); + fcconfigsubstitute(nil,pat1,fcmatchfont); + xftdefaultsubstitute(msedisplay,xdefaultscreen(msedisplay),pat1); + fontset1:= fcfontsort(nil,pat1,true,@charset1,@res1); + if fccharsethaschar(charset1,longword(achar)) then begin + with fontset1^ do begin + po1:= fonts; + setlength(result,nfont); + int2:= 0; + for int1:= 0 to nfont - 1 do begin + if fcpatterngetcharset(po1^,fc_charset,0,@charset2) = fcresultmatch then begin + if fccharsethaschar(charset2,longword(achar)) then begin + if fcpatterngetstring(po1^,fc_family,0,@po2) = fcresultmatch then begin + result[int2]:= po2; + end; + inc(int2); + end; + end; + inc(po1); + end; + setlength(result,int2); + end; + end; + fccharsetdestroy(charset1); + fcpatterndestroy(pat1); + fcfontsetdestroy(fontset1); + end; +{$ifdef FPC} {$checkpointer default} {$endif} +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mxft.pas b/mseide-msegui/lib/common/kernel/linux/mxft.pas new file mode 100644 index 0000000..4f48f73 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mxft.pas @@ -0,0 +1,454 @@ +unit mxft; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + {$ifdef FPC}x,{$endif}Xlib,mxrender,mselibc,msectypes,msefontconfig; + +{ + Automatically converted by H2Pas 0.99.16 from Xft.h + The following command line parameters were used: + -D + -l + xft + -o + xft.pas + -T + -u + xft + Xft.h +} + +{$IFDEF FPC} + {$PACKRECORDS C} +{$ELSE} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$ENDIF} + +type //from fontconfig.h, XftCompat.h + XftType = ( + XftTypeVoid, + XftTypeInteger, + XftTypeDouble, + XftTypeString, + XftTypeBool, + XftTypeMatrix, + XftTypeCharSet, + XftTypeFTFace, + XftTypeLangSet + ); + const + External_library='libXft.so'; +// fclib = 'libfontconfig.so'; + Type + + TFT_FaceRec = record //from freetype.h + //dummy + end; + TFT_Face = ^TFT_FaceRec; + + TFT_UInt = longword; //from fttypes.h + + +// PDisplay = ^Display; + PFT_UInt = ^TFT_UInt; + Plongint = ^longint; +// PVisual = ^Visual; + + { + * $XFree86: xc/lib/Xft/Xft.h,v 1.32 2003/02/25 21:57:53 dawes Exp $ + * + * Copyright ? 2000 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + } + const + XFT_MAJOR = 2; + XFT_MINOR = 1; + XFT_REVISION = 0; + XftVersion = ((XFT_MAJOR * 10000) + (XFT_MINOR * 100) + (XFT_REVISION)); + + const + XFT_CORE = 'core'; + XFT_RENDER = 'render'; + XFT_XLFD = 'xlfd'; + XFT_MAX_GLYPH_MEMORY = 'maxglyphmemory'; + XFT_MAX_UNREF_FONTS = 'maxunreffonts'; +{ + var + _XftFTlibrary : TFT_Library;cvar;external; +} + type + + TXftDraw = record + //dummy + end; + PXftDraw = ^TXftDraw; + + TXftFont = record + ascent : longint; + descent : longint; + height : longint; + max_advance_width : longint; + charset : ^TFcCharSet; + pattern : ^TFcPattern; + end; + PXftFont = ^TXftFont; + + TXftFontinfo = record + //dummy + end; + PXftFontInfo = ^TXftFontInfo; + + TXftColor = record + pixel : culong; + color : TXRenderColor; + end; + PXftColor = ^TXftColor; + + TXftCharSpec = record + ucs4 : TFcChar32; + x : smallint; + y : smallint; + end; + PXftCharSpec = ^TXftCharSpec; + + TXftCharFontSpec = record + font : ^TXftFont; + ucs4 : TFcChar32; + x : smallint; + y : smallint; + end; + PXftCharFontSpec = ^TXftCharFontSpec; + + TXftGlyphSpec = record + glyph : TFT_UInt; + x : smallint; + y : smallint; + end; + PXftGlyphSpec = ^TXftGlyphSpec; + + TXftGlyphFontSpec = record + font : ^TXftFont; + glyph : TFT_UInt; + x : smallint; + y : smallint; + end; + PXftGlyphFontSpec = ^TXftGlyphFontSpec; + + +{$ifdef staticxft} + { fccharset.c } + function FcCharSetCreate: PFcCharSet;cdecl; + external fclib name 'FcCharSetCreate'; + procedure FcCharSetDestroy(fcs:PFcCharSet);cdecl; + external fclib name 'FcCharSetDestroy'; + function FcCharSetAddChar(fcs:PFcCharSet; ucs4:TFcChar32):TFcBool;cdecl; + external fclib name 'FcCharSetAddChar'; + function FcCharSetHasChar(fcs:PFcCharSet; ucs4:TFcChar32):TFcBool;cdecl; + external External_library name 'FcCharSetHasChar'; + { fcpat.c } + function FcPatternCreate: PFcPattern;cdecl; + external fclib name 'FcPatternCreate'; + function FcPatternDuplicate(p:PFcPattern): PFcPattern;cdecl; + external fclib name 'FcPatternDuplicate'; + function FcPatternAdd(p:PFcPattern; aobject:Pchar; value:TFcValue; + append:TFcBool):TFcBool;cdecl; + external fclib name 'FcPatternAdd'; + procedure FcPatternDestroy(p: PFcPattern);cdecl; + external fclib name 'FcPatternDestroy'; + function FcPatternGetCharSet(p:PFcPattern; aobject:Pchar; n:longint; + c:PPFcCharSet):TFcResult;cdecl; + external fclib name 'FcPatternGetCharSet'; + function FcPatternAddInteger(p:PFcPattern; aobject:Pchar; i:longint):TFcBool; + cdecl;external fclib name 'FcPatternAddInteger'; + function FcPatternAddDouble(p:PFcPattern; aobject:Pchar; d:Tdouble):TFcBool; + cdecl;external fclib name 'FcPatternAddDouble'; + function FcPatternAddString(p:PFcPattern; aobject:Pchar; s: pansichar):TFcBool; + cdecl;external fclib name 'FcPatternAddString'; + function FcPatternAddMatrix(p:PFcPattern; aobject:Pchar; s:PFcMatrix):TFcBool; + cdecl;external fclib name 'FcPatternAddMatrix'; + function FcPatternAddCharSet(p:PFcPattern; + aobject:Pchar; c:PFcCharSet):TFcBool;cdecl; + external fclib name 'FcPatternAddCharSet'; + function FcPatternAddBool(p:PFcPattern; aobject:Pchar; b:TFcBool):TFcBool; + cdecl;external fclib name 'FcPatternAddBool'; + function FcPatternAddLangSet(p:PFcPattern; aobject:Pchar; + ls:PFcLangSet):TFcBool;cdecl; + external fclib name 'FcPatternAddLangSet'; + { fclist.c } + function FcObjectSetCreate: PFcObjectSet;cdecl; + external fclib name 'FcObjectSetCreate'; + function FcObjectSetAdd(os: PFcObjectSet; aobject:Pchar):TFcBool;cdecl; + external fclib name 'FcObjectSetAdd'; + procedure FcObjectSetDestroy(os: PFcObjectSet);cdecl; + external fclib name 'FcObjectSetDestroy'; + function FcFontList(config: PFcConfig; p:PFcPattern; + os:PFcObjectSet): PFcFontSet;cdecl; + external fclib name 'FcFontList'; + { fcmatch.c } + function FcFontSort(config:PFcConfig; p:PFcPattern; trim:TFcBool; + csp:PPFcCharSet; result:PFcResult): PFcFontSet;cdecl; + external fclib name 'FcFontSort'; + function FcFontRenderPrepare(config:PFcConfig; pat:PFcPattern; + font:PFcPattern): PFcPattern;cdecl; + external fclib name 'FcFontRenderPrepare'; + { fcfs.c } + procedure FcFontSetDestroy(s:PFcFontSet);cdecl; + external fclib name 'FcFontSetDestroy'; + + { fccfg.c } + function FcConfigSubstitute(config:PFcConfig; p:PFcPattern; + kind:TFcMatchKind):TFcBool;cdecl; + external fclib name 'FcConfigSubstitute'; + { fcdefault.c } + procedure FcDefaultSubstitute(pattern:PFcPattern);cdecl; + external fclib name 'FcDefaultSubstitute'; + { fcmatrix-c } + procedure FcMatrixRotate(m:PFcMatrix; c:Tdouble; s:Tdouble);cdecl; + external fclib name 'FcMatrixRotate'; + + procedure FcMatrixScale(m:PFcMatrix; sx:Tdouble; sy:Tdouble);cdecl; + external fclib name 'FcMatrixScale'; + { xftcolor.c } + + function XftColorAllocName (dpy: PDisplay; visual: PVisual; cmap: TColormap; + name: PChar; result: PXftColor): TFcBool; + cdecl;external External_library name 'XftColorAllocName'; + + function XftColorAllocValue(dpy:PDisplay; visual:PVisual; cmap:TColormap; + color:PXRenderColor; result:PXftColor):TFcBool; + cdecl;external External_library name 'XftColorAllocValue'; + + procedure XftColorFree(dpy:PDisplay; visual:PVisual; cmap:TColormap; color:PXftColor);cdecl;external External_library name 'XftColorFree'; + + { xftcore.c } + { xftdir.c } + function XftDirScan(aset:PFcFontSet; dir:Pchar; force:TFcBool):TFcBool;cdecl;external External_library name 'XftDirScan'; + + function XftDirSave(aset:PFcFontSet; dir:Pchar):TFcBool;cdecl;external External_library name 'XftDirSave'; + + { xftdpy.c } + function XftDefaultHasRender(dpy:PDisplay):TFcBool;cdecl;external External_library name 'XftDefaultHasRender'; + + function XftDefaultSet(dpy:PDisplay; defaults:PFcPattern):TFcBool;cdecl;external External_library name 'XftDefaultSet'; + + procedure XftDefaultSubstitute(dpy:PDisplay; screen:longint; pattern:PFcPattern);cdecl;external External_library name 'XftDefaultSubstitute'; + + { xftdraw.c } + function XftDrawCreate(dpy:PDisplay; drawable:TDrawable; visual:PVisual; colormap:TColormap): PXftDraw;cdecl;external External_library name 'XftDrawCreate'; + + function XftDrawCreateBitmap(dpy:PDisplay; bitmap:TPixmap): PXftDraw;cdecl;external External_library name 'XftDrawCreateBitmap'; + + function XftDrawCreateAlpha(dpy:PDisplay; pixmap:TPixmap; depth:longint): PXftDraw;cdecl;external External_library name 'XftDrawCreateAlpha'; + + procedure XftDrawChange(draw:PXftDraw; drawable:TDrawable);cdecl;external External_library name 'XftDrawChange'; + + function XftDrawDisplay(draw:PXftDraw): PDisplay;cdecl;external External_library name 'XftDrawDisplay'; + + function XftDrawDrawable(draw:PXftDraw):TDrawable;cdecl;external External_library name 'XftDrawDrawable'; + + function XftDrawColormap(draw:PXftDraw):TColormap;cdecl;external External_library name 'XftDrawColormap'; + + function XftDrawVisual(draw:PXftDraw): PVisual;cdecl;external External_library name 'XftDrawVisual'; + + procedure XftDrawDestroy(draw:PXftDraw);cdecl;external External_library name 'XftDrawDestroy'; + + function XftDrawPicture(draw:PXftDraw):TPicture;cdecl;external External_library name 'XftDrawPicture'; + + function XftDrawSrcPicture(draw:PXftDraw; color:PXftColor):TPicture;cdecl;external External_library name 'XftDrawSrcPicture'; + + procedure XftDrawGlyphs(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + glyphs:PFT_UInt; nglyphs:longint);cdecl;external External_library name 'XftDrawGlyphs'; + + procedure XftDrawString8(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + _string:PFcChar8; len:longint);cdecl;external External_library name 'XftDrawString8'; + + procedure XftDrawString16(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + _string:pwidechar; len:longint);cdecl;external External_library name 'XftDrawString16'; + + procedure XftDrawString32(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + _string:PFcChar32; len:longint);cdecl;external External_library name 'XftDrawString32'; + + procedure XftDrawStringUtf8(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + _string:PFcChar8; len:longint);cdecl;external External_library name 'XftDrawStringUtf8'; + + procedure XftDrawStringUtf16(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + _string:PFcChar8; endian:TFcEndian; len:longint);cdecl;external External_library name 'XftDrawStringUtf16'; + + procedure XftDrawCharSpec(draw:PXftDraw; color:PXftColor; pub:PXftFont; chars:PXftCharSpec; len:longint);cdecl;external External_library name 'XftDrawCharSpec'; + + procedure XftDrawCharFontSpec(draw:PXftDraw; color:PXftColor; chars:PXftCharFontSpec; len:longint);cdecl;external External_library name 'XftDrawCharFontSpec'; + + procedure XftDrawGlyphSpec(draw:PXftDraw; color:PXftColor; pub:PXftFont; glyphs:PXftGlyphSpec; len:longint);cdecl;external External_library name 'XftDrawGlyphSpec'; + + procedure XftDrawGlyphFontSpec(draw:PXftDraw; color:PXftColor; glyphs:PXftGlyphFontSpec; len:longint);cdecl;external External_library name 'XftDrawGlyphFontSpec'; + + procedure XftDrawRect(draw:PXftDraw; color:PXftColor; x:longint; y:longint; width:dword; + height:dword);cdecl;external External_library name 'XftDrawRect'; + + function XftDrawSetClip(draw:PXftDraw; r:TRegion):TFcBool;cdecl;external External_library name 'XftDrawSetClip'; + + function XftDrawSetClipRectangles(draw:PXftDraw; xOrigin:longint; yOrigin:longint; rects:PXRectangle; n:longint):TFcBool;cdecl;external External_library name 'XftDrawSetClipRectangles'; + + procedure XftDrawSetSubwindowMode(draw:PXftDraw; mode:longint);cdecl;external External_library name 'XftDrawSetSubwindowMode'; + + { xftextent.c } + procedure XftGlyphExtents(dpy:PDisplay; pub:PXftFont; glyphs:PFT_UInt; nglyphs:longint; extents:PXGlyphInfo);cdecl;external External_library name 'XftGlyphExtents'; + + procedure XftTextExtents8(dpy:PDisplay; pub:PXftFont; _string:PFcChar8; len:longint; extents:PXGlyphInfo);cdecl;external External_library name 'XftTextExtents8'; + + procedure XftTextExtents16(dpy:PDisplay; pub:PXftFont; _string: pwidechar{PFcChar16}; len:longint; extents:PXGlyphInfo);cdecl;external External_library name 'XftTextExtents16'; + + procedure XftTextExtents32(dpy:PDisplay; pub:PXftFont; _string:PFcChar32; len:longint; extents:PXGlyphInfo);cdecl;external External_library name 'XftTextExtents32'; + + procedure XftTextExtentsUtf8(dpy:PDisplay; pub:PXftFont; _string:PFcChar8; len:longint; extents:PXGlyphInfo);cdecl;external External_library name 'XftTextExtentsUtf8'; + + procedure XftTextExtentsUtf16(dpy:PDisplay; pub:PXftFont; _string:PFcChar8; endian:TFcEndian; len:longint; + extents:PXGlyphInfo);cdecl;external External_library name 'XftTextExtentsUtf16'; + + { xftfont.c } + function XftFontMatch(dpy:PDisplay; screen:longint; pattern:PFcPattern; result:PFcResult): PFcPattern;cdecl;external External_library name 'XftFontMatch'; + + function XftFontOpen(dpy:PDisplay; screen:longint; args: array of const):PXftFont;cdecl;external External_library name 'XftFontOpen'; + + function XftFontOpenName(dpy:PDisplay; screen:longint; name:Pchar):PXftFont;cdecl;external External_library name 'XftFontOpenName'; + + function XftFontOpenXlfd(dpy:PDisplay; screen:longint; xlfd:Pchar):PXftFont;cdecl;external External_library name 'XftFontOpenXlfd'; + + function XftLockFace(pub:PXftFont):TFT_Face;cdecl;external External_library name 'XftLockFace'; + + procedure XftUnlockFace(pub:PXftFont);cdecl;external External_library name 'XftUnlockFace'; + + function XftFontInfoCreate(dpy:PDisplay; pattern:PFcPattern):PXftFontInfo;cdecl;external External_library name 'XftFontInfoCreate'; + + procedure XftFontInfoDestroy(dpy:PDisplay; fi:PXftFontInfo);cdecl;external External_library name 'XftFontInfoDestroy'; + + function XftFontInfoHash(fi:PXftFontInfo):TFcChar32;cdecl;external External_library name 'XftFontInfoHash'; + + function XftFontInfoEqual(a:PXftFontInfo; b:PXftFontInfo):TFcBool;cdecl;external External_library name 'XftFontInfoEqual'; + + function XftFontOpenInfo(dpy:PDisplay; pattern:PFcPattern; fi:PXftFontInfo): PXftFont;cdecl;external External_library name 'XftFontOpenInfo'; + + function XftFontOpenPattern(dpy:PDisplay; pattern:PFcPattern):PXftFont;cdecl;external External_library name 'XftFontOpenPattern'; + + function XftFontCopy(dpy:PDisplay; pub:PXftFont):PXftFont;cdecl;external External_library name 'XftFontCopy'; + + procedure XftFontClose(dpy:PDisplay; pub:PXftFont);cdecl;external External_library name 'XftFontClose'; + + function XftInitFtLibrary:TFcBool;cdecl;external External_library name 'XftInitFtLibrary'; + + { xftglyphs.c } + procedure XftFontLoadGlyphs(dpy:PDisplay; pub:PXftFont; need_bitmaps:TFcBool; glyphs:PFT_UInt; nglyph:longint);cdecl;external External_library name 'XftFontLoadGlyphs'; + + procedure XftFontUnloadGlyphs(dpy:PDisplay; pub:PXftFont; glyphs:PFT_UInt; nglyph:longint);cdecl;external External_library name 'XftFontUnloadGlyphs'; + + + const + XFT_NMISSING = 256; + + function XftFontCheckGlyph(dpy:PDisplay; pub:PXftFont; need_bitmaps:TFcBool; glyph:TFT_UInt; missing:PFT_UInt; + nmissing:Plongint):TFcBool;cdecl;external External_library name 'XftFontCheckGlyph'; + + function XftCharExists(dpy:PDisplay; pub:PXftFont; ucs4:TFcChar32):TFcBool;cdecl;external External_library name 'XftCharExists'; + + function XftCharIndex(dpy:PDisplay; pub:PXftFont; ucs4:TFcChar32):TFT_UInt;cdecl;external External_library name 'XftCharIndex'; + + { xftgram.y } + { xftinit.c } + function XftInit(config:Pchar):TFcBool;cdecl;external External_library name 'XftInit'; + + function XftGetVersion:longint;cdecl;external External_library name 'XftGetVersion'; + + { xftlex.l } + { xftlist.c } + + function XftListFonts(dpy:PDisplay; screen:longint; + args:array of const):PFcFontSet;cdecl;external External_library name 'XftListFonts'; + + { xftmatch.c } + { xftmatrix.c } + { xftname.c } + function XftNameParse(name:Pchar): PFcPattern;cdecl;external External_library name 'XftNameParse'; + + { xftpat.c } + + { xftrender.c } + procedure XftGlyphRender(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; glyphs:PFT_UInt; + nglyphs:longint);cdecl;external External_library name 'XftGlyphRender'; + + procedure XftGlyphSpecRender(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; glyphs:PXftGlyphSpec; nglyphs:longint);cdecl;external External_library name 'XftGlyphSpecRender'; + + procedure XftCharSpecRender(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; chars:PXftCharSpec; len:longint);cdecl;external External_library name 'XftCharSpecRender'; + + procedure XftGlyphFontSpecRender(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; srcx:longint; + srcy:longint; glyphs:PXftGlyphFontSpec; nglyphs:longint);cdecl;external External_library name 'XftGlyphFontSpecRender'; + + procedure XftCharFontSpecRender(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; srcx:longint; + srcy:longint; chars:PXftCharFontSpec; len:longint);cdecl;external External_library name 'XftCharFontSpecRender'; + + procedure XftTextRender8(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRender8'; + + procedure XftTextRender16(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar16; + len:longint);cdecl;external External_library name 'XftTextRender16'; + + procedure XftTextRender16BE(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRender16BE'; + + procedure XftTextRender16LE(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRender16LE'; + + procedure XftTextRender32(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar32; + len:longint);cdecl;external External_library name 'XftTextRender32'; + + procedure XftTextRender32BE(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRender32BE'; + + procedure XftTextRender32LE(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRender32LE'; + + procedure XftTextRenderUtf8(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRenderUtf8'; + + procedure XftTextRenderUtf16(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + endian:TFcEndian; len:longint);cdecl;external External_library name 'XftTextRenderUtf16'; + + { xftstr.c } + { xftxlfd.c } + function XftXlfdParse(xlfd_orig:Pchar; ignore_scalable:TFcBool; complete:TFcBool):PFcPattern;cdecl;external External_library name 'XftXlfdParse'; + +{$endif staticxft} + +implementation + + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mxrandr.pas b/mseide-msegui/lib/common/kernel/linux/mxrandr.pas new file mode 100644 index 0000000..3d178df --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mxrandr.pas @@ -0,0 +1,216 @@ +unit mxrandr; +{/* + * Copyright © 2000 Compaq Computer Corporation, Inc. + * Copyright © 2002 Hewlett-Packard Company, Inc. + * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Keith Packard, Intel Corporation + */} +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msectypes,x,xlib; + +{$packrecords c} + +const +//* Event selection bits */ + RRScreenChangeNotifyMask = 1 shl 0; +///* V1.2 additions */ + RRCrtcChangeNotifyMask = 1 shl 1; + RROutputChangeNotifyMask = 1 shl 2; + RROutputPropertyNotifyMask = 1 shl 3; +//* V1.4 additions */ + RRProviderChangeNotifyMask = 1 shl 4; + RRProviderPropertyNotifyMask = 1 shl 5; + RRResourceChangeNotifyMask = 1 shl 6; + +//* Event codes */ + RRScreenChangeNotify = 0; +//* V1.2 additions */ + RRNotify = 1; +//* RRNotify Subcodes */ + RRNotify_CrtcChange = 0; + RRNotify_OutputChange = 0; + RRNotify_OutputProperty = 2; + RRNotify_ProviderChange = 3; + RRNotify_ProviderProperty = 4; + RRNotify_ResourceChange = 5; + rrlastnotify = RRNotify + 5; + +//* used in the rotation field; rotation and reflection in 0.1 proto. */ + RR_Rotate_0 = 1; + RR_Rotate_90 = 2; + RR_Rotate_180 = 4; + RR_Rotate_270 = 8; + +//* new in 1.0 protocol, to allow reflection of screen */ + + RR_Reflect_X = 16; + RR_Reflect_Y = 32; + +type + Window = txid; + Rotation = cushort; + Connection = cushort; + SubpixelOrder = cushort; + SizeID = cushort; + + RROutput = txid; + pRROutput = ^RROutput; + RRCrtc = txid; + pRRCrtc = ^RRCrtc; + RRMode = txid; + pRRMode = ^RRMode; + RRProvider = txid; + pRRProvider = ^RRProvider; + + Time = culong; + pTime = pculong; + + XRRModeFlags = culong; + + XRRModeInfo = record + id: RRMode; + width: cuint; + height: cuint; + dotClock: culong; + hSyncStart: cuint; + hSyncEnd: cuint; + hTotal: cuint; + hSkew: cuint; + vSyncStart: cuint; + vSyncEnd: cuint; + vTotal: cuint; + name: pchar; + nameLength: cuint; + modeFlags: XRRModeFlags; + end; + pXRRModeInfo = ^XRRModeInfo; + + XRRScreenResources = record + timestamp: Time; + configTimestamp:Time; + ncrtc: cint; + crtcs: pRRCrtc; + noutput: cint; + outputs: pRROutput; + nmode: cint; + modes: pXRRModeInfo; + end; + pXRRScreenResources = ^XRRScreenResources; + + XRROutputInfo = record + timestamp: Time; + crtc: RRCrtc; + name: pcchar; + nameLen: cint; + mm_width: culong; + mm_height: culong; + connection: Connection; + subpixel_order: SubpixelOrder; + ncrtc: cint ; + crtcs: pRRCrtc; + nclone: cint; + clones: pRROutput; + nmode: cint; + npreferred: cint; + modes: pRRMode; + end; + pXRROutputInfo = ^XRROutputInfo; + + XRRCrtcInfo = record + timestamp: Time; + x,y: cint; + width,height: cuint; + mode: RRMode; + rotation: Rotation; + noutput: cint; + outputs: pRROutput; + rotations: Rotation; + npossible: cint; + possible: pRROutput; + end; + pXRRCrtcInfo = ^XRRCrtcInfo; + + XRRScreenChangeNotifyEvent = record + _type: cint ; //* event base */ + serial: culong; //* # of last request processed by server */ + send_event: cBool; //* true if this came from a SendEvent request */ + display: pDisplay; //* Display the event was read from */ + window: Window; //* window which selected for this event */ + root: Window; //* Root window for changed screen */ + timestamp: Time ; //* when the screen change occurred */ + config_timestamp: Time; //* when the last configuration change */ + size_index: SizeID; + subpixel_order: SubpixelOrder; + rotation: Rotation; + width: cint; + height: cint; + mwidth: cint; + mheight: cint; + end; + +var + XRRQueryExtension: function (dpy: pDisplay; event_base_return: pcint; + error_base_return: pcint): cBool cdecl; + XRRGetScreenResources: function(dpy: pDisplay; + window: Window): pXRRScreenResources cdecl; + XRRFreeScreenResources: procedure(resources: pXRRScreenResources) cdecl; + XRRGetCrtcInfo: function(dpy: pDisplay; resources: pXRRScreenResources; + crtc: RRCrtc): pXRRCrtcInfo cdecl; + XRRFreeCrtcInfo: procedure(crtcInfo: pXRRCrtcInfo) cdecl; + XRRGetOutputInfo: function(dpy: pDisplay; resources: pXRRScreenResources; + output: RROutput): pXRROutputInfo cdecl; + XRRFreeOutputInfo: procedure(outputInfo: pXRROutputInfo) cdecl; + + XRRSelectInput: procedure(dpy: pDisplay; window: Window; mask: cint) cdecl; + XRRUpdateConfiguration: function(event: pXEvent): cint cdecl; + +function getxrandrlib: boolean; + +implementation +uses + msesys,msesonames,msedynload; + +function getxrandrlib: boolean; +const +// (n: ''; d: @) + funcs: array[0..8] of funcinfoty = ( + (n: 'XRRQueryExtension'; d: @XRRQueryExtension), + (n: 'XRRGetScreenResources'; d: @XRRGetScreenResources), + (n: 'XRRFreeScreenResources'; d: @XRRFreeScreenResources), + (n: 'XRRGetCrtcInfo'; d: @XRRGetCrtcInfo), + (n: 'XRRFreeCrtcInfo'; d: @XRRFreeCrtcInfo), + (n: 'XRRGetOutputInfo'; d: @XRRGetOutputInfo), + (n: 'XRRFreeOutputInfo'; d: @XRRFreeOutputInfo), + (n: 'XRRSelectInput'; d: @XRRSelectInput), + (n: 'XRRUpdateConfiguration'; d: @XRRUpdateConfiguration) + ); + +begin + result:= checkprocaddresses(xrandrnames,funcs); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mxrender.pas b/mseide-msegui/lib/common/kernel/linux/mxrender.pas new file mode 100644 index 0000000..aff50e9 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mxrender.pas @@ -0,0 +1,490 @@ +unit mxrender; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + {$ifdef FPC} x,{$endif}Xlib,mselibc,msectypes; + + const + External_library='libXrender.so'; + +{$IFDEF FPC} + {$PACKRECORDS C} +{$ELSE} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$ENDIF} + + + { + * $XFree86: xc/lib/Xrender/Xrender.h,v 1.18 2002/11/23 02:34:45 keithp Exp $ + * + * Copyright ? 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + } + + type + +{$ifndef FPC} + txid = xid; +{$endif} + TBool = integer; + dword = longword; + Pdword = ^dword; + Tdouble = double; + TXFixed = integer; + PXFixed = ^TXFixed; + TGlyph = txid; + PGlyph = ^TGlyph; + TGlyphSet = txid; + PGlyphSet = ^TGlyphSet; + TPicture = txid; + PPicture = ^TPicture; + TPictFormat = txid; + PPictFormat = ^TPictFormat; + {$ifdef FPC} + TRegion = pointer; + {$else} + TRegion = Region; + {$endif} + PRegion = ^TRegion; + + const //from render.h + BadPictFormat = 0; + BadPicture = 1; + BadPictOp = 2; + BadGlyphSet = 3; + BadGlyph = 4; + RenderNumberErrors = BadGlyph + 1; + PictTypeIndexed = 0; + PictTypeDirect = 1; + PictOpMinimum = 0; + PictOpClear = 0; + PictOpSrc = 1; + PictOpDst = 2; + PictOpOver = 3; + PictOpOverReverse = 4; + PictOpIn = 5; + PictOpInReverse = 6; + PictOpOut = 7; + PictOpOutReverse = 8; + PictOpAtop = 9; + PictOpAtopReverse = 10; + PictOpXor = 11; + PictOpAdd = 12; + PictOpSaturate = 13; + PictOpMaximum = 13; + { + * Operators only available in version 0.2 + } + PictOpDisjointMinimum = $10; + PictOpDisjointClear = $10; + PictOpDisjointSrc = $11; + PictOpDisjointDst = $12; + PictOpDisjointOver = $13; + PictOpDisjointOverReverse = $14; + PictOpDisjointIn = $15; + PictOpDisjointInReverse = $16; + PictOpDisjointOut = $17; + PictOpDisjointOutReverse = $18; + PictOpDisjointAtop = $19; + PictOpDisjointAtopReverse = $1a; + PictOpDisjointXor = $1b; + PictOpDisjointMaximum = $1b; + PictOpConjointMinimum = $20; + PictOpConjointClear = $20; + PictOpConjointSrc = $21; + PictOpConjointDst = $22; + PictOpConjointOver = $23; + PictOpConjointOverReverse = $24; + PictOpConjointIn = $25; + PictOpConjointInReverse = $26; + PictOpConjointOut = $27; + PictOpConjointOutReverse = $28; + PictOpConjointAtop = $29; + PictOpConjointAtopReverse = $2a; + PictOpConjointXor = $2b; + PictOpConjointMaximum = $2b; + PolyEdgeSharp = 0; + PolyEdgeSmooth = 1; + PolyModePrecise = 0; + PolyModeImprecise = 1; + CPRepeat = 1 shl 0; + CPAlphaMap = 1 shl 1; + CPAlphaXOrigin = 1 shl 2; + CPAlphaYOrigin = 1 shl 3; + CPClipXOrigin = 1 shl 4; + CPClipYOrigin = 1 shl 5; + CPClipMask = 1 shl 6; + CPGraphicsExposure = 1 shl 7; + CPSubwindowMode = 1 shl 8; + CPPolyEdge = 1 shl 9; + CPPolyMode = 1 shl 10; + CPDither = 1 shl 11; + CPComponentAlpha = 1 shl 12; + CPLastBit = 11; + { Filters included in 0.6 } + FilterNearest = 'nearest'; + FilterBilinear = 'bilinear'; + FilterFast = 'fast'; + FilterGood = 'good'; + FilterBest = 'best'; + FilterAliasNone = -(1); + { Subpixel orders included in 0.6 } + SubPixelUnknown = 0; + SubPixelHorizontalRGB = 1; + SubPixelHorizontalBGR = 2; + SubPixelVerticalRGB = 3; + SubPixelVerticalBGR = 4; + SubPixelNone = 5; + +type + TXRenderDirectFormat = record + red : smallint; + redMask : smallint; + green : smallint; + greenMask : smallint; + blue : smallint; + blueMask : smallint; + alpha : smallint; + alphaMask : smallint; + end; + PXRenderDirectFormat = ^TXRenderDirectFormat; + + TXRenderPictFormat = record + id : TPictFormat; + _type : longint; + depth : longint; + direct : TXRenderDirectFormat; + colormap : TColormap; + end; + PXRenderPictFormat = ^TXRenderPictFormat; + + const + PictFormatID = 1 shl 0; + PictFormatType = 1 shl 1; + PictFormatDepth = 1 shl 2; + PictFormatRed = 1 shl 3; + PictFormatRedMask = 1 shl 4; + PictFormatGreen = 1 shl 5; + PictFormatGreenMask = 1 shl 6; + PictFormatBlue = 1 shl 7; + PictFormatBlueMask = 1 shl 8; + PictFormatAlpha = 1 shl 9; + PictFormatAlphaMask = 1 shl 10; + PictFormatColormap = 1 shl 11; + RepeatNone = 0; + RepeatNormal = 1; + RepeatPad = 2; + RepeatReflect = 2; + + type + + TXRenderPictureAttributes = record + _repeat : TBool; + alpha_map : TPicture; + alpha_x_origin : longint; + alpha_y_origin : longint; + clip_x_origin : longint; + clip_y_origin : longint; + clip_mask : TPixmap; + graphics_exposures : TBool; + subwindow_mode : longint; + poly_edge : longint; + poly_mode : longint; + dither : TAtom; + component_alpha : TBool; + end; + PXRenderPictureAttributes = ^TXRenderPictureAttributes; + + TXRenderColor = record + red : word; + green : word; + blue : word; + alpha : word; + end; + PXRenderColor = ^TXRenderColor; + + TXGlyphInfo = record + width : word; + height : word; + x : smallint; + y : smallint; + xOff : smallint; + yOff : smallint; + end; + PXGlyphInfo = ^TXGlyphInfo; + + TXGlyphElt8 = record + glyphset : TGlyphSet; + chars : ^char; + nchars : longint; + xOff : longint; + yOff : longint; + end; + PXGlyphElt8 = ^TXGlyphElt8; + + TXGlyphElt16 = record + glyphset : TGlyphSet; + chars : ^word; + nchars : longint; + xOff : longint; + yOff : longint; + end; + PXGlyphElt16 = TXGlyphElt16; + + TXGlyphElt32 = record + glyphset : TGlyphSet; + chars : ^dword; + nchars : longint; + xOff : longint; + yOff : longint; + end; + PXGlyphElt32 = ^TXGlyphElt32; + + TXDouble = Tdouble; + + TXPointDouble = record + x : TXDouble; + y : TXDouble; + end; + PXPointDouble = ^TXPointDouble; + + TXPointFixed = record + x : TXFixed; + y : TXFixed; + end; + PXPointFixed = ^TXPointFixed; + + TXLineFixed = record + p1 : TXPointFixed; + p2 : TXPointFixed; + end; + PXLineFixed = ^TXLineFixed; + + TXTriangle = record + p1 : TXPointFixed; + p2 : TXPointFixed; + p3 : TXPointFixed; + end; + PXTriangle = ^TXTriangle; + + TXTrapezoid = record + top : TXFixed; + bottom : TXFixed; + left : TXLineFixed; + right : TXLineFixed; + end; + PXTrapezoid = ^TXTrapezoid; + + TXTransform = array[0..2] //row + of array[0..2] of TXFixed; //col + //m00,m01,0 + //m10,m11,0 x' = m00 * x + m01 * y + dx + //dx, dy, 1 y' = m11 * y + m10 * x + dy + + PXTransform = ^TXTransform; + + TXFilters = record + nfilter : longint; + filter : PPchar; + nalias : longint; + alias : ^smallint; + end; + PXFilters = ^TXFilters; + + TXIndexValue = record + pixel : culong; + red : word; + green : word; + blue : word; + alpha : word; + end; + PXIndexValue = ^TXIndexValue; + + TXAnimCursor = record + cursor : TCursor; + delay : culong; + end; + PXAnimCursor = ^TXAnimCursor; + + const + PictStandardARGB32 = 0; + PictStandardRGB24 = 1; + PictStandardA8 = 2; + PictStandardA4 = 3; + PictStandardA1 = 4; + PictStandardNUM = 5; + +{$ifdef staticxrender} + + function XRenderQueryExtension(dpy: PDisplay; event_basep: Pinteger; + error_basep: Pinteger): TBool; + cdecl;external External_library name 'XRenderQueryExtension'; + + function XRenderQueryVersion(dpy:PDisplay; major_versionp:Plongint; + minor_versionp:Plongint):TStatus; + cdecl;external External_library name 'XRenderQueryVersion'; + + function XRenderQueryFormats(dpy:PDisplay):TStatus; + cdecl;external External_library name 'XRenderQueryFormats'; + + function XRenderQuerySubpixelOrder(dpy:PDisplay; screen:longint):longint; + cdecl;external External_library name 'XRenderQuerySubpixelOrder'; + + function XRenderSetSubpixelOrder(dpy: PDisplay; screen: longint; + subpixel: longint): TBool; cdecl; + external External_library name 'XRenderSetSubpixelOrder'; + + function XRenderFindVisualFormat(dpy: PDisplay; + visual: PVisual): PXRenderPictFormat; cdecl; + external External_library name 'XRenderFindVisualFormat'; + + function XRenderFindFormat(dpy: PDisplay; mask: culong; + templ: PXRenderPictFormat; count: longint): PXRenderPictFormat; cdecl; + external External_library name 'XRenderFindFormat'; + + + function XRenderFindStandardFormat(dpy:PDisplay; + format:longint):PXRenderPictFormat; + cdecl;external External_library name 'XRenderFindStandardFormat'; + +function XRenderQueryPictIndexValues(dpy:PDisplay; format:PXRenderPictFormat; + num:Plongint):PXIndexValue; + cdecl;external External_library name 'XRenderQueryPictIndexValues'; + +function XRenderCreatePicture(dpy:PDisplay; drawable:TDrawable; + format:PXRenderPictFormat; valuemask:culong; + attributes:PXRenderPictureAttributes):TPicture; + cdecl;external External_library name 'XRenderCreatePicture'; + +procedure XRenderFreePicture(dpy:PDisplay; picture:TPicture); + cdecl;external External_library name 'XRenderFreePicture'; + +procedure XRenderChangePicture(dpy:PDisplay; picture:TPicture; + valuemask:culong; attributes:PXRenderPictureAttributes); + cdecl;external External_library name 'XRenderChangePicture'; + +procedure XRenderSetPictureClipRectangles(dpy:PDisplay; picture:TPicture; + xOrigin:longint; yOrigin:longint; rects:PXRectangle; n:longint); + cdecl;external External_library name 'XRenderSetPictureClipRectangles'; + +procedure XRenderSetPictureClipRegion(dpy:PDisplay; picture:TPicture; r:TRegion); + cdecl;external External_library name 'XRenderSetPictureClipRegion'; + +procedure XRenderSetPictureTransform(dpy:PDisplay; picture:TPicture; transform:PXTransform); + cdecl;external External_library name 'XRenderSetPictureTransform'; + + +procedure XRenderComposite(dpy:PDisplay; op:longint; src:TPicture; mask:TPicture; dst:TPicture; + src_x:longint; src_y:longint; mask_x:longint; mask_y:longint; dst_x:longint; + dst_y:longint; width:dword; height:dword);cdecl;external External_library name 'XRenderComposite'; + + function XRenderCreateGlyphSet(dpy:PDisplay; format:PXRenderPictFormat):TGlyphSet;cdecl;external External_library name 'XRenderCreateGlyphSet'; + + function XRenderReferenceGlyphSet(dpy:PDisplay; existing:TGlyphSet):TGlyphSet;cdecl;external External_library name 'XRenderReferenceGlyphSet'; + + procedure XRenderFreeGlyphSet(dpy:PDisplay; glyphset:TGlyphSet);cdecl;external External_library name 'XRenderFreeGlyphSet'; + + procedure XRenderAddGlyphs(dpy:PDisplay; glyphset:TGlyphSet; gids:PGlyph; glyphs:PXGlyphInfo; nglyphs:longint; + images:Pchar; nbyte_images:longint);cdecl;external External_library name 'XRenderAddGlyphs'; + + procedure XRenderFreeGlyphs(dpy:PDisplay; glyphset:TGlyphSet; gids:PGlyph; nglyphs:longint);cdecl;external External_library name 'XRenderFreeGlyphs'; + + procedure XRenderCompositeString8(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + glyphset:TGlyphSet; xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; + _string:Pchar; nchar:longint);cdecl;external External_library name 'XRenderCompositeString8'; + + procedure XRenderCompositeString16(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + glyphset:TGlyphSet; xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; + _string:Pword; nchar:longint);cdecl;external External_library name 'XRenderCompositeString16'; + + procedure XRenderCompositeString32(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + glyphset:TGlyphSet; xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; + _string:Pdword; nchar:longint);cdecl;external External_library name 'XRenderCompositeString32'; + + procedure XRenderCompositeText8(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; elts:PXGlyphElt8; + nelt:longint);cdecl;external External_library name 'XRenderCompositeText8'; + + procedure XRenderCompositeText16(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; elts:PXGlyphElt16; + nelt:longint);cdecl;external External_library name 'XRenderCompositeText16'; + + procedure XRenderCompositeText32(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; elts:PXGlyphElt32; + nelt:longint);cdecl;external External_library name 'XRenderCompositeText32'; + + procedure XRenderFillRectangle(dpy:PDisplay; op:longint; dst:TPicture; color:PXRenderColor; x:longint; + y:longint; width:dword; height:dword);cdecl;external External_library name 'XRenderFillRectangle'; + + procedure XRenderFillRectangles(dpy:PDisplay; op:longint; dst:TPicture; color:PXRenderColor; rectangles:PXRectangle; + n_rects:longint);cdecl;external External_library name 'XRenderFillRectangles'; + + procedure XRenderCompositeTrapezoids(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; traps:PXTrapezoid; ntrap:longint);cdecl;external External_library name 'XRenderCompositeTrapezoids'; + + procedure XRenderCompositeTriangles(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; triangles:PXTriangle; ntriangle:longint);cdecl;external External_library name 'XRenderCompositeTriangles'; + + procedure XRenderCompositeTriStrip(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; points:PXPointFixed; npoint:longint);cdecl;external External_library name 'XRenderCompositeTriStrip'; + + procedure XRenderCompositeTriFan(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; points:PXPointFixed; npoint:longint);cdecl;external External_library name 'XRenderCompositeTriFan'; + +// procedure XRenderCompositeDoublePoly(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; +// xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; fpoints:PXPointDouble; +// npoints:longint; winding:longint);cdecl;external External_library name 'XRenderCompositeDoublePoly'; + + function XRenderParseColor(dpy:PDisplay; spec:Pchar; def:PXRenderColor):TStatus;cdecl;external External_library name 'XRenderParseColor'; + + function XRenderCreateCursor(dpy:PDisplay; source:TPicture; x:dword; y:dword):TCursor;cdecl;external External_library name 'XRenderCreateCursor'; + + function XRenderQueryFilters(dpy:PDisplay; drawable:TDrawable):PXFilters;cdecl;external External_library name 'XRenderQueryFilters'; + + procedure XRenderSetPictureFilter(dpy:PDisplay; picture:TPicture; filter:Pchar; params:PXFixed; nparams:longint);cdecl;external External_library name 'XRenderSetPictureFilter'; + + function XRenderCreateAnimCursor(dpy:PDisplay; ncursor:longint; cursors:PXAnimCursor):TCursor;cdecl;external External_library name 'XRenderCreateAnimCursor'; + +{$endif staticxrender} + + //macros + + function XDoubleToFixed(f : TXDouble) : TXFixed; +//#define XDoubleToFixed(f) ((XFixed) ((f) * 65536)) + + function XFixedToDouble(f : TXFixed) : TXDouble; +//#define XFixedToDouble(f) (((XDouble) (f)) / 65536) + +implementation + + function XDoubleToFixed(f : TXDouble) : TXFixed; + begin + XDoubleToFixed:= round(f * 65536); + end; + + function XFixedToDouble(f : TXFixed) : TXDouble; + begin + XFixedToDouble:= f / 65536; + end; + + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/sm.pas b/mseide-msegui/lib/common/kernel/linux/sm.pas new file mode 100644 index 0000000..92504e6 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/sm.pas @@ -0,0 +1,197 @@ + +unit sm; +interface +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +{$IFDEF FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$ENDIF} + + + { $Xorg: SM.h,v 1.4 2001/02/09 02:03:30 xorgcvs Exp $ } + { + + Copyright 1993, 1998 The Open Group + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of The Open Group shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from The Open Group. + + } + { + * Author: Ralph Mor, X Consortium + } + { + * Protocol Version + } + + const + SmProtoMajor = 1; + SmProtoMinor = 0; + { + * Interact Style + } + SmInteractStyleNone = 0; + SmInteractStyleErrors = 1; + SmInteractStyleAny = 2; + { + * Dialog Type + } + SmDialogError = 0; + SmDialogNormal = 1; + { + * Save Type + } + SmSaveGlobal = 0; + SmSaveLocal = 1; + SmSaveBoth = 2; + { + * Restart Style Hints + } + SmRestartIfRunning = 0; + SmRestartAnyway = 1; + SmRestartImmediately = 2; + SmRestartNever = 3; + { + * Property names + } + SmCloneCommand = 'CloneCommand'; + SmCurrentDirectory = 'CurrentDirectory'; + SmDiscardCommand = 'DiscardCommand'; + SmEnvironment = 'Environment'; + SmProcessID = 'ProcessID'; + SmProgram = 'Program'; + SmRestartCommand = 'RestartCommand'; + SmResignCommand = 'ResignCommand'; + SmRestartStyleHint = 'RestartStyleHint'; + SmShutdownCommand = 'ShutdownCommand'; + SmUserID = 'UserID'; + { + * Property types + } + SmCARD8 = 'CARD8'; + SmARRAY8 = 'ARRAY8'; + SmLISTofARRAY8 = 'LISTofARRAY8'; + { + * SM minor opcodes + } + SM_Error = 0; + SM_RegisterClient = 1; + SM_RegisterClientReply = 2; + SM_SaveYourself = 3; + SM_SaveYourselfRequest = 4; + SM_InteractRequest = 5; + SM_Interact = 6; + SM_InteractDone = 7; + SM_SaveYourselfDone = 8; + SM_Die = 9; + SM_ShutdownCancelled = 10; + SM_CloseConnection = 11; + SM_SetProperties = 12; + SM_DeleteProperties = 13; + SM_GetProperties = 14; + SM_PropertiesReply = 15; + SM_SaveYourselfPhase2Request = 16; + SM_SaveYourselfPhase2 = 17; + SM_SaveComplete = 18; + { _SM_H_ } + SmcSaveYourselfProcMask = 1 shl 0; + SmcDieProcMask = 1 shl 1; + SmcSaveCompleteProcMask = 1 shl 2; + SmcShutdownCancelledProcMask = 1 shl 3; + +type + bool = integer;{longbool} //protocoll does not accept -1 for true + Status = integer; + SmPointer = pointer; + SmcConn = pointer; + SmcCloseStatus = (SmcClosedNow,SmcClosedASAP,SmcConnectionInUse); + + SmcSaveYourselfProc = procedure(_smcConn: SmcConn; clientData: pointer; + saveType: integer; shutdown: bool; + interactStyle: integer; fast: bool); cdecl; + SmcDieProc = procedure(_smcConn: SmcConn; clientData: pointer); cdecl; + SmcSaveCompleteProc = procedure(_smcConn: SmcConn; clientData: pointer); cdecl; + SmcShutdownCancelledProc = procedure(_smcConn: SmcConn; + clientData: pointer); cdecl; + + SmcCallbacks = record + save_yourself: record + callback: SmcSaveYourselfProc; + client_data: pointer; + end; + die: record + callback: SmcDieProc; + client_data: pointer; + end; + save_complete: record + callback: SmcSaveCompleteProc; + client_data: pointer; + end; + shutdown_cancelled: record + callback: SmcShutdownCancelledProc; + client_data: pointer; + end; + end; + + SmcInteractProc = procedure(_smcConn: SmcConn; clientData: SmPointer); cdecl; + +var + SmcOpenConnection: function(networkIdsList: pchar; context: Pointer; + xsmpMajorRev: integer; xsmpMinorRev: integer; + mask: longword; var callbacks: SmcCallbacks; + previousId: pchar; var clientIdRet: pchar; + errorLength: integer; errorStringRet: pchar): SmcConn; cdecl; + SmcCloseConnection: function(_smcConn: SmcConn; + count: integer; reasonMsgs: ppchar): SmcCloseStatus; cdecl; + SmcSaveYourselfDone: procedure(_smcConn: SmcConn; success: Bool); cdecl; + SmcInteractRequest: function(_smcConn: SmcConn; dialogType: integer; + interactProc: SmcInteractProc; clientData: SmPointer): Status; + cdecl; + SmcInteractDone: procedure(_smcConn: SmcConn; cancelShutdown: Bool); cdecl; + +function getsmlib: boolean; + +implementation +uses + msesys,msesonames,msedynload; + +function getsmlib: boolean; +begin + result:= checkprocaddresses(smnames, + [ + 'SmcOpenConnection', //0 + 'SmcCloseConnection', //1 + 'SmcSaveYourselfDone', //2 + 'SmcInteractRequest', //3 + 'SmcInteractDone' //4 + ], + [ + {$ifndef FPC}@{$endif}@SmcOpenConnection, //0 + {$ifndef FPC}@{$endif}@SmcCloseConnection, //1 + {$ifndef FPC}@{$endif}@SmcSaveYourselfDone, //2 + {$ifndef FPC}@{$endif}@SmcInteractRequest, //3 + {$ifndef FPC}@{$endif}@SmcInteractDone //4 + ]); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseact.pas b/mseide-msegui/lib/common/kernel/mseact.pas new file mode 100644 index 0000000..408acf3 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseact.pas @@ -0,0 +1,1472 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseact; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,mserichstring, + msetypes,mseglob,mseapplication, mseevent,msestat,msestatfile,msestrings, + typinfo,msegraphutils,mseinterfaces + {$ifdef mse_with_ifi},mseifiglob,mseificomp,mseificompglob{$endif}; + +const + defaultactionstates = []; +type + shapestatety = (shs_disabled,shs_invisible,shs_checked,shs_default, + //actionstatesty + + shs_separator,shs_optional, //for menu separators + shs_checkbox,shs_radiobutton, + //menuactionoptionty + + shs_clicked,shs_mouse,shs_moveclick,shs_focused,shs_active, + shs_suppressed, + shs_horz,shs_vert,shs_opposite,shs_ellipsemouse, + shs_widgetorg,shs_showfocusrect,shs_showdefaultrect, + shs_flat,shs_noanimation,shs_nomouseanimation, + shs_noclickanimation,shs_nofocusanimation,shs_focusanimation, + shs_focuscolor, + //use cl_selectedtext and cl_selecetetextbackground + //if focused + shs_checkbutton,shs_menuarrow,shs_noinnerrect); + shapestatesty = set of shapestatety; + + actionstatety = (as_disabled = ord(shs_disabled),as_invisible=ord(shs_invisible), + as_checked=ord(shs_checked),as_default=ord(shs_default), + as_repeatshortcut, + as_localdisabled,as_localinvisible,as_localchecked,as_localdefault, + as_localrepeatshortcut, + as_localcaption, + as_localimagelist,as_localimagenr,as_localimagenrdisabled, + as_localimagecheckedoffset, + as_localcolorglyph,as_localcolor, + as_localhint,as_localshortcut,as_localshortcut1,as_localtag, + as_localgroup,as_localonbeforeexecute,as_localonexecute, + as_localonafterexecute,as_syncdisabledlocked); + actionstatesty = set of actionstatety; + actionstatesarty = array of actionstatesty; + + menuactionoptionty = (mao_separator, + mao_optional, //suppress separators without adjacent + //visible normal items + mao_checkbox,mao_radiobutton, + + mao_shortcutcaption, + mao_asyncexecute,mao_singleregion, + mao_showhint,mao_noshowhint, + mao_nocandefocus); + menuactionoptionsty = set of menuactionoptionty; + +const + invisibleactionstates = [ord(as_syncdisabledlocked)]; + actionstatesmask: actionstatesty = + [as_disabled,as_checked,as_invisible,as_default, + as_repeatshortcut]; + actionshapestatesconst = [as_disabled,as_invisible,as_checked,as_default]; + actionshapestates: actionstatesty = actionshapestatesconst; + actionoptionshapestates: menuactionoptionsty = + [mao_separator,mao_optional,mao_checkbox,mao_radiobutton]; + actionoptionshapelshift = ord(shs_separator); + + localactionstates: actionstatesty = + [as_localdisabled,as_localinvisible,as_localchecked,as_localdefault, + as_localrepeatshortcut, + as_localcaption, + as_localimagelist,as_localimagenr,as_localimagenrdisabled, + as_localimagecheckedoffset, + as_localcolorglyph,as_localcolor, + as_localhint,as_localshortcut,as_localshortcut1,as_localtag, + as_localgroup,as_localonbeforeexecute,as_localonexecute, + as_localonafterexecute]; + localactionlshift = ord(as_localdisabled); + localactionstatestates: actionstatesty = + [as_localdisabled,as_localinvisible,as_localchecked,as_localdefault, + as_localrepeatshortcut]; +type + actionoptionty = (ao_updateonidle,ao_localshortcut,ao_globalshortcut, + ao_nocandefocus); +const + defaultactionoptions = []; + +type + tcustomaction = class; + actioneventty = procedure(const sender: tcustomaction) of object; + + actioninfoty = record + action: tcustomaction; + captiontext: msestring; + caption1: richstringty; + state: actionstatesty; + options: menuactionoptionsty; + shortcut: shortcutarty; + shortcut1: shortcutarty; + group: integer; + imagenr: imagenrty; //imagenrty; + imagenrdisabled: imagenrty; //-2 -> grayed + colorglyph: colorty; + color: colorty; + imagecheckedoffset: integer; + imagelist: tobject; //timagelist + hint: msestring; + tag: integer; + tagpo: pointer; + onexecute: notifyeventty; + onbeforeexecute: accepteventty; + onafterexecute: notifyeventty; + end; + pactioninfoty = ^actioninfoty; + + iactionlink = interface(iobjectlink)[miid_iactionlink] + function getactioninfopo: pactioninfoty; + procedure actionchanged; + function loading: boolean; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + end; + + asynceventty = procedure(const sender: tobject; var atag: integer) of object; + + actionoptionsty = set of actionoptionty; + + tcustomaction = class(tactcomponent,istatfile{,iimagelistinfo} + {$ifdef mse_with_ifi},iifiexeclink{$endif}) + private + fonupdate: actioneventty; + fstatvarname: msestring; + fstatfile: tstatfile; + fonchange: notifyeventty; + fonasyncevent: asynceventty; + fonexecuteaction: actioneventty; + fstatpriority: integer; +{$ifdef mse_with_ifi} + fifilink: tifiactionlinkcomp; + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifiactionlinkcomp); overload; +{$endif} + function getcaption: captionty; + procedure setcaption(const Value: captionty); + procedure setonexecute(const avalue: notifyeventty); + procedure setonbeforeexecute(const avalue: accepteventty); + procedure setonafterexecute(const avalue: notifyeventty); + procedure setimagenr(const Value: imagenrty); + procedure setimagenrdisabled(const avalue: imagenrty); + procedure setcolorglyph(const avalue: colorty); + procedure setcolor(const avalue: colorty); + procedure setimagecheckedoffset(const Value: integer); + function getstate: actionstatesty; + procedure setstate(const Value: actionstatesty); + function getgroup: integer; + procedure setgroup(const Value: integer); + procedure sethint(const Value: msestring); + procedure settag(const Value: integer); + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + procedure ifisetenabled(const avalue: boolean); + procedure doupdateinfo(const info: linkinfoty); + procedure dounlinkaction(const info: linkinfoty); + function getchecked: boolean; + procedure setchecked(const Value: boolean); + procedure setoptions(const Value: actionoptionsty); + procedure setstatfile(const Value: tstatfile); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + protected + finfo: actioninfoty; + foptions: actionoptionsty; + procedure registeronshortcut(const avalue: boolean); virtual; + procedure loaded; override; + procedure changed; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure receiveevent(const event: tobjectevent) override; + procedure doidle(var again: boolean); + procedure doasyncevent(var atag: integer); override; + procedure eventfired(const sender: tobject; const ainfo: actioninfoty); + procedure doafterunlink; virtual; + + //istatfile, saves state of as_checked + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + //iimagelistinfo +// function getimagelist: timagelist; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure doupdate; + procedure execute(const force: boolean = false); + procedure asyncexecute(); + procedure updateinfo(const sender: iactionlink); + property caption: captionty read getcaption write setcaption; + property state: actionstatesty read getstate write setstate default []; + property visible: boolean read getvisible write setvisible; + property enabled: boolean read getenabled write setenabled; + property checked: boolean read getchecked write setchecked; + property group: integer read getgroup write setgroup default 0; + property imagenr: imagenrty read finfo.imagenr write setimagenr default -1; + property imagenrdisabled: imagenrty read finfo.imagenrdisabled + write setimagenrdisabled default -2; + property colorglyph: colorty read finfo.colorglyph + write setcolorglyph default cl_default; + property color: colorty read finfo.color write setcolor default cl_default; + property imagecheckedoffset: integer read finfo.imagecheckedoffset + write setimagecheckedoffset default 0; + property hint: msestring read finfo.hint write sethint; + property tagaction: integer read finfo.tag write settag default 0; + property options: actionoptionsty read foptions write setoptions + default defaultactionoptions; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; +{$ifdef mse_with_ifi} + property ifilink: tifiactionlinkcomp read fifilink write setifilink; +{$endif} + + property onexecute: notifyeventty read finfo.onexecute write setonexecute; + property onbeforeexecute: accepteventty read finfo.onbeforeexecute + write setonbeforeexecute; + property onafterexecute: notifyeventty read finfo.onafterexecute + write setonafterexecute; + property onexecuteaction: actioneventty read fonexecuteaction write fonexecuteaction; + property onupdate: actioneventty read fonupdate write fonupdate; + property onchange: notifyeventty read fonchange write fonchange; + property onasyncevent: asynceventty read fonasyncevent write fonasyncevent; + end; + + tnoguiaction = class(tcustomaction) + protected + published + property caption; + property state; + property group; + property tagaction; +// property imagelist; + property imagenr; + property imagenrdisabled; + property colorglyph; + property color; + property imagecheckedoffset; + property hint; +// property shortcut; + property statfile; + property statvarname; + property statpriority; + property options; + property onexecute; + property onbeforeexecute; + property onafterexecute; + property onupdate; + property onchange; + property onasyncevent; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + +procedure linktoaction(const sender: iactionlink; const aaction: tcustomaction; + var info: actioninfoty); + //remove existing link, copy action to instance +procedure setactionchecked(const sender: iactionlink; const value: boolean); +procedure setactioncaption(const sender: iactionlink; const value: msestring); +function isactioncaptionstored(const info: actioninfoty): boolean; + +procedure setactionimagenr(const sender: iactionlink; const value: integer); +function isactionimagenrstored(const info: actioninfoty): boolean; +procedure setactionimagenrdisabled(const sender: iactionlink; + const value: integer); +function isactionimagenrdisabledstored(const info: actioninfoty): boolean; +procedure setactioncolorglyph(const sender: iactionlink; const value: colorty); +function isactioncolorglyphstored(const info: actioninfoty): boolean; +procedure setactioncolor(const sender: iactionlink; const value: colorty); +function isactioncolorstored(const info: actioninfoty): boolean; +procedure setactionimagecheckedoffset(const sender: iactionlink; + const value: integer); +function isactionimagecheckedoffsetstored(const info: actioninfoty): boolean; +procedure setactionhint(const sender: iactionlink; const value: msestring); +function isactionhintstored(const info: actioninfoty): boolean; +procedure setactiontag(const sender: iactionlink; const value: integer); +function isactiontagstored(const info: actioninfoty): boolean; + +procedure setactionstate(const sender: iactionlink; + const value: actionstatesty); +function isactionstatestored(const info: actioninfoty): boolean; + +procedure setactionoptions(const sender: iactionlink; + const value: menuactionoptionsty); + +procedure setactiongroup(const sender: iactionlink; const value: integer); +function isactiongroupstored(const info: actioninfoty): boolean; +procedure setactiononexecute(const sender: iactionlink; + const value: notifyeventty; const aloading: boolean); +function isactiononexecutestored(const info: actioninfoty): boolean; +procedure setactiononbeforeexecute(const sender: iactionlink; + const value: accepteventty; const aloading: boolean); +function isactiononbeforeexecutestored(const info: actioninfoty): boolean; +procedure setactiononafterexecute(const sender: iactionlink; + const value: notifyeventty; const aloading: boolean); +function isactiononafterexecutestored(const info: actioninfoty): boolean; + +procedure actionbeginload(const sender: iactionlink); +procedure actionendload(const sender: iactionlink); + +function doactionexecute(const sender: tobject; var info: actioninfoty; + const nocheckbox: boolean = false; + const nocandefocus: boolean = false; + const beforeexecute: proceventty = nil; + const force: boolean = false): boolean; + //true if local checked changed +function doactionexecute1(const sender: tobject; var info: actioninfoty; + out changed: boolean; + const nocheckbox: boolean = false; + const nocandefocus: boolean = false; + const beforeexecute: proceventty = nil; + const force: boolean = false): boolean; + //true if not canceled + +procedure initactioninfo(var info: actioninfoty; + aoptions: menuactionoptionsty = []); +procedure actionstatestoshapestates(const source: actioninfoty; + var dest: shapestatesty); +procedure shapestatestoactionstates(source: shapestatesty; + var dest: actionstatesty; + const mask: actionstatesty = actionshapestatesconst); +function translateshortcut(const akey: shortcutty): shortcutty; +procedure translateshortcut1(var akey: shortcutty); + //update for new modifier layout + +var + assistiveexechandler: procedure(const sender: tobject; + const info: actioninfoty); +implementation +uses + msebits,sysutils,msekeyboard; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure translateshortcut1(var akey: shortcutty); +begin + if akey and $1000 <> 0 then begin //update for new modifier layout + akey:= akey and not $1000 or $0100; + end; +end; + +function translateshortcut(const akey: shortcutty): shortcutty; +begin + result:= akey; + translateshortcut1(result); +end; + +function doactionexecute1(const sender: tobject; var info: actioninfoty; + out changed: boolean; + const nocheckbox: boolean = false; + const nocandefocus: boolean = false; + const beforeexecute: proceventty = nil; + const force: boolean = false): boolean; + //true if not canceled +var + bo1: boolean; +begin + result:= false; + changed:= false; + with info do begin + if not (as_disabled in state) or force then begin + if not nocandefocus and + ((action = nil) or not(ao_nocandefocus in action.options)) then begin + if not application.candefocus then begin + exit; + end; + end; + if checkcanevent(tmethod(info.onbeforeexecute)) then begin + bo1:= true; + info.onbeforeexecute(sender,bo1); + if not bo1 then begin + exit; + end; + end; + if not nocheckbox then begin + if (mao_checkbox in info.options) then begin + if action <> nil then begin + action.checked:= not action.checked; + end + else begin + togglebit1(longword(info.state),ord(as_checked)); + changed:= true; + end; + end + else begin + if mao_radiobutton in info.options then begin + if action <> nil then begin + action.checked:= true; + end + else begin + if not checkbit(longword(info.state),ord(as_checked)) then begin + setbit1(longword(info.state),ord(as_checked)); + changed:= true; + end; + end; + end; + end; + end; + if assigned(assistiveexechandler) then begin + assistiveexechandler(sender,info); + end; + if assigned(beforeexecute) then begin + beforeexecute; + end; + if checkcanevent(tmethod(info.onexecute)) then begin + info.onexecute(sender); + end; + if info.action <> nil then begin + info.action.eventfired(sender,info); + end; + if checkcanevent(tmethod(info.onafterexecute)) then begin + info.onafterexecute(sender); + end; + result:= true; + end; + end; +end; + +function doactionexecute(const sender: tobject; var info: actioninfoty; + const nocheckbox: boolean = false; + const nocandefocus: boolean = false; + const beforeexecute: proceventty = nil; + const force: boolean = false): boolean; + //true if local checked changed +begin + doactionexecute1(sender,info,result,nocheckbox,nocandefocus,beforeexecute, + force); +end; + +procedure actionstatestoshapestates(const source: actioninfoty; var dest: shapestatesty); +begin + dest:= shapestatesty(replacebits({$ifdef FPC}longword{$else}longword{$endif}(source.state), + {$ifdef FPC}longword{$else}longword{$endif}(dest), + {$ifdef FPC}longword{$else}longword{$endif}(actionshapestates))); + dest:= shapestatesty(replacebits( + {$ifdef FPC}longword{$else}word{$endif}( + {$ifdef FPC}longword{$else}word{$endif}(source.options) + shl {$ifdef FPC}longword{$else}word{$endif}(actionoptionshapelshift) + ), + {$ifdef FPC}longword{$else}longword{$endif}(dest), + {$ifdef FPC}longword{$else}word{$endif}( + {$ifdef FPC}longword{$else}word{$endif}(actionoptionshapestates) + shl {$ifdef FPC}longword{$else}longword{$endif}(actionoptionshapelshift)) + ) + ); +end; + +procedure shapestatestoactionstates(source: shapestatesty; var dest: actionstatesty; + const mask: actionstatesty = actionshapestatesconst); +begin + dest:= actionstatesty(replacebits({$ifdef FPC}longword{$else}longword{$endif}(source), + {$ifdef FPC}longword{$else}longword{$endif}(dest), + {$ifdef FPC}longword{$else}longword{$endif}(actionshapestates*mask))); +end; + +procedure resetlocalstates(var states: actionstatesty); +begin + states:= states - localactionstates; +end; + +procedure setlocalstates(var states: actionstatesty); +begin + states:= states + localactionstates; +end; + +procedure initactioninfo(var info: actioninfoty; + aoptions: menuactionoptionsty = []); +begin + with info do begin + imagenr:= -1; + imagenrdisabled:= -2; + options:= aoptions; + colorglyph:= cl_default; + color:= cl_default; + end; +end; + +procedure actionbeginload(const sender: iactionlink); +begin +// include(sender.getactioninfopo^.options,mao_loading); +end; + +procedure actionendload(const sender: iactionlink); +var + p1: pactioninfoty; + b1: boolean; +begin + p1:= sender.getactioninfopo(); + b1:= as_syncdisabledlocked in p1^.state; + include(p1^.state,as_syncdisabledlocked); + try +// exclude(sender.getactioninfopo^.options,mao_loading); + sender.actionchanged; + finally + if not b1 then begin + exclude(p1^ .state,as_syncdisabledlocked); + end; + end; +end; + +procedure linktoaction(const sender: iactionlink; const aaction: tcustomaction; + var info: actioninfoty); +//var +// sepchar: msechar; +begin + with info do begin + if aaction <> action then begin + setlinkedcomponent(sender,aaction,tmsecomponent(action),typeinfo(iactionlink)); + if action <> nil then begin + action.updateinfo(sender); + end + else begin + if state * localactionstates <> localactionstates then begin + // sepchar:= sender.shortcutseparator; + if not (as_localcaption in state) then begin + captiontext:= ''; + sender.calccaptiontext(info); + end; + if not (as_localshortcut in state) then begin + shortcut:= nil; + sender.calccaptiontext(info); + end; + if not (as_localshortcut1 in state) then begin + shortcut1:= nil; + end; + if not (as_localimagelist in state) then begin + imagelist:= nil; //do not unink,imagelist is owned by action + end; + if not (as_localimagenr in state) then begin + imagenr:= -1; + end; + if not (as_localimagenrdisabled in state) then begin + imagenrdisabled:= -2; + end; + if not (as_localcolorglyph in state) then begin + colorglyph:= cl_default; + end; + if not (as_localcolor in state) then begin + color:= cl_default; + end; + if not (as_localimagecheckedoffset in state) then begin + imagecheckedoffset:= 0; + end; + if not (as_localtag in state) then begin + tag:= 0; + end; + if not (as_localgroup in state) then begin + group:= 0; + end; + if not (as_localhint in state) then begin + hint:= ''; + end; + if not (as_localonexecute in state) then begin + onexecute:= nil; + end; + if not (as_localonbeforeexecute in state) then begin + onbeforeexecute:= nil; + end; + if not (as_localonafterexecute in state) then begin + onafterexecute:= nil; + end; + state:= state - actionstatesty( + longword(localactionstatestates) shr localactionlshift); + sender.actionchanged; + end; + end; + end; + end; +end; +{ +procedure actiondoidle(const info: actioninfoty); +begin + if info.action <> nil then begin + info.action.doupdate; + end; +end; +} +{ +function isactionvisiblestored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (ss_localinvisible in state) and + not ((action = nil) and not(ss_invisible in state)); + end; +end; + +function isactioncheckedstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (ss_localchecked in state) and + not ((action = nil) and not (ss_checked in state)); + end; +end; +} + +procedure setactionchecked(const sender: iactionlink; const value: boolean); +var + po1: pactioninfoty; + bo1: boolean; +begin + po1:= sender.getactioninfopo; + with po1^ do begin + bo1:= as_checked in state; + if bo1 <> value then begin + if not (as_localchecked in state) and (action <> nil) then begin + action.checked:= value; + end + else begin + updatebit(longword(state),ord(as_checked),value); + sender.actionchanged; + end; + end; + end; +end; + +procedure setactioncaption(const sender: iactionlink; const value: msestring); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + with po1^ do begin + captiontext:= value; + include(state,as_localcaption); + end; + sender.calccaptiontext(po1^); + sender.actionchanged; +end; + +function isactioncaptionstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localcaption in state) and + not ((action = nil) and (captiontext = '')); + end; +end; + +procedure setactiontag(const sender: iactionlink; const value: integer); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + with po1^ do begin + tag:= value; + include(state,as_localtag); + end; + sender.actionchanged; +end; + +function isactiontagstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localtag in state) and + not ((action = nil) and (tag = 0)); + end; +end; + +procedure setactionimagenr(const sender: iactionlink; const value: integer); +begin + with sender.getactioninfopo^ do begin + imagenr:= value; + include(state,as_localimagenr); + end; + sender.actionchanged; +end; + +function isactionimagenrstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localimagenr in state) and + not ((action = nil) and (imagenr = -1)); + end; +end; + +procedure setactionimagenrdisabled(const sender: iactionlink; const value: integer); +begin + with sender.getactioninfopo^ do begin + imagenrdisabled:= value; + include(state,as_localimagenrdisabled); + end; + sender.actionchanged; +end; + +function isactionimagenrdisabledstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localimagenrdisabled in state) and + not ((action = nil) and (imagenrdisabled = -2)); + end; +end; + +procedure setactioncolorglyph(const sender: iactionlink; const value: colorty); +begin + with sender.getactioninfopo^ do begin + colorglyph:= value; + include(state,as_localcolorglyph); + end; + sender.actionchanged; +end; + +procedure setactioncolor(const sender: iactionlink; const value: colorty); +begin + with sender.getactioninfopo^ do begin + color:= value; + include(state,as_localcolor); + end; + sender.actionchanged; +end; + +function isactioncolorglyphstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localcolorglyph in state) and + not ((action = nil) and (colorglyph = cl_default)); + end; +end; + +function isactioncolorstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localcolor in state) and + not ((action = nil) and (color = cl_default)); + end; +end; + +procedure setactionimagecheckedoffset(const sender: iactionlink; const value: integer); +begin + with sender.getactioninfopo^ do begin + imagecheckedoffset:= value; + include(state,as_localimagecheckedoffset); + end; + sender.actionchanged; +end; + +function isactionimagecheckedoffsetstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localimagecheckedoffset in state) and + not ((action = nil) and (imagecheckedoffset = 0)); + end; +end; + +procedure setactionhint(const sender: iactionlink; const value: msestring); +begin + with sender.getactioninfopo^ do begin + hint:= value; + include(state,as_localhint); + end; + sender.actionchanged; +end; + +function isactionhintstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localhint in state) and + not ((action = nil) and (hint = '')); + end; +end; + +procedure setactionstate(const sender: iactionlink; const value: actionstatesty); +var + startstate,statebefore: actionstatesty; + bo1: boolean; + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + with po1^ do begin + startstate:= state; + statebefore:= state; + state:= actionstatesty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(state), + {$ifdef FPC}longword{$else}longword{$endif}(localactionstates))); + bo1:= state <> statebefore; + statebefore:= state; + state:= actionstatesty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(state), + {$ifdef FPC}longword{$else}longword{$endif}(actionstatesmask))); + if statebefore <> state then begin + if (mao_shortcutcaption in options) and + (statebefore * [as_disabled] <> state * [as_disabled]) then begin + sender.calccaptiontext(po1^); + end; + end; + if not sender.loading then begin +{$ifdef FPC}longword{$else}longword{$endif}(state):= + {$ifdef FPC}longword{$else}longword{$endif}(state) or + ( + ( + ( + {$ifdef FPC}longword{$else}longword{$endif}(state) xor + {$ifdef FPC}longword{$else}longword{$endif}(statebefore) + ) and + {$ifdef FPC}longword{$else}longword{$endif}(actionstatesmask) + ) + shl localactionlshift + ); + end; + if bo1 and (action <> nil) then begin + action.updateinfo(sender); + end; + if state <> startstate then begin + sender.actionchanged; + end; + end; +end; + +procedure setactionoptions(const sender: iactionlink; + const value: menuactionoptionsty); +const + mask1: menuactionoptionsty = [mao_showhint,mao_noshowhint]; + mask2: menuactionoptionsty = [mao_checkbox,mao_radiobutton]; +var + optionsbefore: menuactionoptionsty; + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + with po1^ do begin + optionsbefore:= options; + options:= menuactionoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}word{$endif}(value), + {$ifdef FPC}longword{$else}word{$endif}(options), + {$ifdef FPC}longword{$else}word{$endif}(mask1))); + options:= menuactionoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}word{$endif}(options), + {$ifdef FPC}longword{$else}word{$endif}(optionsbefore), + {$ifdef FPC}longword{$else}word{$endif}(mask2))); + if optionsbefore * [mao_shortcutcaption] <> options * + [mao_shortcutcaption] then begin + sender.calccaptiontext(po1^); + end; + end; + sender.actionchanged; +end; + +function isactionstatestored(const info: actioninfoty): boolean; +begin + result:= true; + { + with info do begin + result:= (state * localactionstatestates <> []) and + not ((action = nil) and (state * actionstatesmask = [])); + end; + } +end; + +procedure setactiongroup(const sender: iactionlink; const value: integer); +begin + with sender.getactioninfopo^ do begin + group:= value; + include(state,as_localgroup); + end; + sender.actionchanged; +end; + +function isactiongroupstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localgroup in state) and + not ((action = nil) and (group = 0)); + end; +end; + +procedure setactiononexecute(const sender: iactionlink; + const value: notifyeventty; const aloading: boolean); +begin + with sender.getactioninfopo^ do begin + onexecute:= value; + if not aloading then begin //IDE sets csloading while method pointer swapping + include(state,as_localonexecute); + end; + end; + sender.actionchanged; +end; + +function isactiononexecutestored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localonexecute in state) and + not ((action = nil) and + (tmethod(info.onexecute).code = nil) and + (tmethod(info.onexecute).data = nil)); + end; +end; + +procedure setactiononbeforeexecute(const sender: iactionlink; + const value: accepteventty; const aloading: boolean); +begin + with sender.getactioninfopo^ do begin + onbeforeexecute:= value; + if not aloading then begin //IDE sets csloading while method pointer swapping + include(state,as_localonbeforeexecute); + end; + end; + sender.actionchanged; +end; + +function isactiononbeforeexecutestored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localonbeforeexecute in state) and + not ((action = nil) and (tmethod(info.onexecute).code = nil) and + (tmethod(info.onexecute).data = nil)); + //assigned does not work + end; +end; + +procedure setactiononafterexecute(const sender: iactionlink; + const value: notifyeventty; const aloading: boolean); +begin + with sender.getactioninfopo^ do begin + onafterexecute:= value; + if not aloading then begin //IDE sets csloading while method pointer swapping + include(state,as_localonafterexecute); + end; + end; + sender.actionchanged; +end; + +function isactiononafterexecutestored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localonafterexecute in state) and + not ((action = nil) and + (tmethod(info.onafterexecute).code = nil) and + (tmethod(info.onafterexecute).data = nil)); + end; +end; + + {tcustomaction} + +constructor tcustomaction.create(aowner: tcomponent); +begin + initactioninfo(finfo); + finfo.action:= self; + foptions:= defaultactionoptions; + inherited; +end; + +procedure tcustomaction.dounlinkaction(const info: linkinfoty); +begin + linktoaction(iactionlink(info.dest),nil, + iactionlink(info.dest).getactioninfopo^); +end; + +destructor tcustomaction.destroy; +begin + if fobjectlinker <> nil then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}dounlinkaction,typeinfo(iactionlink)); + end; + doafterunlink; + options:= []; + inherited; +end; + +procedure tcustomaction.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +function tcustomaction.getcaption: captionty; +begin + result:= finfo.captiontext; +end; + +procedure tcustomaction.setcaption(const Value: captionty); +begin + finfo.captiontext:= value; + changed; +end; +{ +function tcustomaction.getimagelist: timagelist; +begin + result:= finfo.imagelist; +end; +} +{ +function tcustomaction.getimagenr: integer; +begin + result:= finfo.imagenr; +end; +} +procedure tcustomaction.setimagenr(const Value: imagenrty); +begin + finfo.imagenr:= value; + changed; +end; + +procedure tcustomaction.setimagenrdisabled(const avalue: imagenrty); +begin + finfo.imagenrdisabled:= avalue; + changed; +end; + +procedure tcustomaction.setcolorglyph(const avalue: colorty); +begin + finfo.colorglyph:= avalue; + changed; +end; + +procedure tcustomaction.setcolor(const avalue: colorty); +begin + finfo.color:= avalue; + changed; +end; + +procedure tcustomaction.setimagecheckedoffset(const Value: integer); +begin + finfo.imagecheckedoffset:= value; + changed; +end; + +{ +function tcustomaction.gethint: msestring; +begin + result:= finfo.hint; +end; +} +procedure tcustomaction.sethint(const Value: msestring); +begin + finfo.hint:= value; + changed; +end; + +function tcustomaction.getstate: actionstatesty; +begin + result:= finfo.state; +end; + +procedure tcustomaction.setstate(const Value: actionstatesty); +begin + if value * actionstatesmask <> finfo.state * actionstatesmask then begin + finfo.state:= actionstatesty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(finfo.state), + {$ifdef FPC}longword{$else}longword{$endif}(actionstatesmask))); + changed; + end; +end; + +function tcustomaction.getgroup: integer; +begin + result:= finfo.group; +end; + +procedure tcustomaction.setgroup(const Value: integer); +begin + finfo.group:= value; + changed; +end; + +procedure tcustomaction.settag(const Value: integer); +begin + finfo.tag := Value; + changed; +end; + +procedure tcustomaction.setonexecute(const avalue: notifyeventty); +begin + if not issamemethod(tmethod(avalue),tmethod(finfo.onexecute)) then begin + finfo.onexecute := avalue; + changed; + end; +end; + +procedure tcustomaction.setonbeforeexecute(const avalue: accepteventty); +begin + if not issamemethod(tmethod(avalue),tmethod(finfo.onbeforeexecute)) then begin + finfo.onbeforeexecute:= avalue; + changed; + end; +end; + +procedure tcustomaction.setonafterexecute(const avalue: notifyeventty); +begin + if not issamemethod(tmethod(avalue),tmethod(finfo.onafterexecute)) then begin + finfo.onafterexecute:= avalue; + changed; + end; +end; + +procedure tcustomaction.loaded; +begin + inherited; + changed; +end; + +procedure tcustomaction.updateinfo(const sender: iactionlink); +var + bo1: boolean; + mask: actionstatesty; + po1: pactioninfoty; +// sepchar: msechar; +begin + bo1:= false; + po1:= sender.getactioninfopo; + with po1^ do begin +// sepchar:= sender.shortcutseparator; + if not (as_localcaption in state) and + (captiontext <> finfo.captiontext) then begin + captiontext:= finfo.captiontext; + sender.calccaptiontext(po1^); + bo1:= true; + end; + if not (as_localshortcut in state) and + (shortcut <> finfo.shortcut) then begin + shortcut:= finfo.shortcut; + sender.calccaptiontext(po1^); + bo1:= true; + end; + if not (as_localshortcut1 in state) and + (shortcut1 <> finfo.shortcut1) then begin + shortcut1:= finfo.shortcut1; + bo1:= true; + end; + if not (as_localimagelist in state) and + (imagelist <> finfo.imagelist) then begin + imagelist:= finfo.imagelist; + bo1:= true; + end; + if not (as_localimagenr in state) and + (imagenr <> finfo.imagenr) then begin + imagenr:= finfo.imagenr; + bo1:= true; + end; + if not (as_localimagenrdisabled in state) and + (imagenrdisabled <> finfo.imagenrdisabled) then begin + imagenrdisabled:= finfo.imagenrdisabled; + bo1:= true; + end; + if not (as_localcolorglyph in state) and + (colorglyph <> finfo.colorglyph) then begin + colorglyph:= finfo.colorglyph; + bo1:= true; + end; + if not (as_localcolor in state) and + (color <> finfo.color) then begin + color:= finfo.color; + bo1:= true; + end; + if not (as_localimagecheckedoffset in state) and + (imagecheckedoffset <> finfo.imagecheckedoffset) then begin + imagecheckedoffset:= finfo.imagecheckedoffset; + bo1:= true; + end; + if not (as_localtag in state) and + (tag <> finfo.tag) then begin + tag:= finfo.tag; + bo1:= true; + end; + if not (as_localgroup in state) and + (group <> finfo.group) then begin + group:= finfo.group; + bo1:= true; + end; + if not (as_localhint in state) and + (hint <> finfo.hint) then begin + hint:= finfo.hint; + bo1:= true; + end; + if not (as_localonexecute in state) and + not issamemethod(tmethod(onexecute),tmethod(finfo.onexecute)) then begin + onexecute:= finfo.onexecute; + bo1:= true; + end; + if not (as_localonbeforeexecute in state) and + not issamemethod(tmethod(onbeforeexecute), + tmethod(finfo.onbeforeexecute)) then begin + onbeforeexecute:= finfo.onbeforeexecute; + bo1:= true; + end; + if not (as_localonafterexecute in state) and + not issamemethod(tmethod(onafterexecute), + tmethod(finfo.onafterexecute)) then begin + onafterexecute:= finfo.onafterexecute; + bo1:= true; + end; + mask:= actionstatesmask - + actionstatesty( + {$ifdef FPC}longword{$else}longword{$endif}( + {$ifdef FPC}longword{$else}longword{$endif}(state * localactionstatestates) shr + localactionlshift) + ); +// if as_localstate in state then begin +// mask:= mask - actionstatesmask; +// end; + { + if ss_localchecked in state then begin + exclude(mask,ss_checked); + end; + } + if state * mask <> finfo.state * mask then begin + bo1:= true; + state:= actionstatesty( + replacebits({$ifdef FPC}longword{$else}longword{$endif}(finfo.state), + {$ifdef FPC}longword{$else}longword{$endif}(state), + {$ifdef FPC}longword{$else}longword{$endif}(mask))); + end; + end; + if bo1 then begin + sender.actionchanged; + end; +end; + +procedure tcustomaction.doupdateinfo(const info: linkinfoty); +begin + updateinfo(iactionlink(info.dest)); +end; + +procedure tcustomaction.changed; +begin + if not (csloading in componentstate) then begin + if fobjectlinker <> nil then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}doupdateinfo, + typeinfo(iactionlink)); + end; + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + end; +end; + +procedure tcustomaction.doupdate; +begin + if assigned(fonupdate) and not (csdesigning in componentstate) then begin + fonupdate(self); + end; +end; + +procedure tcustomaction.doidle(var again: boolean); +begin + doupdate; +end; + +procedure tcustomaction.execute(const force: boolean = false); +begin + if (componentstate*[csloading,csdesigning,csdestroying] = []) and + doactionexecute(self,finfo,false,false,nil,force) then begin + changed; + end; +end; + +procedure tcustomaction.asyncexecute(); +begin + application.postevent(tobjectevent.create(ek_execute,self)); +end; + +procedure tcustomaction.receiveevent(const event: tobjectevent); +begin + inherited; + case event.kind of + ek_execute: begin + execute(); + end; + end; +end; + +procedure tcustomaction.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_destroyed) and (sender = finfo.imagelist) then begin + finfo.imagelist:= nil; + changed; + end; +end; + +function tcustomaction.getenabled: boolean; +begin + result:= not (as_disabled in finfo.state); +end; + +procedure tcustomaction.setenabled(const avalue: boolean); +begin + if avalue then begin + state:= finfo.state - [as_disabled]; + end + else begin + state:= finfo.state + [as_disabled]; + end; +end; + +procedure tcustomaction.ifisetenabled(const avalue: boolean); +begin + if not (as_localdisabled in finfo.state) then begin + setenabled(avalue); + end; +end; + +function tcustomaction.getchecked: boolean; +begin + result:= as_checked in finfo.state; +end; + +procedure tcustomaction.setchecked(const Value: boolean); +begin + if value then begin + state:= state + [as_checked]; + end + else begin + state:= state - [as_checked]; + end; +end; + +procedure tcustomaction.setoptions(const Value: actionoptionsty); +var + delta: actionoptionsty; +begin + delta:= actionoptionsty({$ifdef FPC}longword{$else}byte{$endif}(foptions) xor + {$ifdef FPC}longword{$else}byte{$endif}(value)); + if delta <> [] then begin + foptions := Value; + if not (csdesigning in componentstate) then begin + if ao_updateonidle in delta then begin + if (ao_updateonidle in value) and + not (csdesigning in componentstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doidle); + end + else begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + end; + if [ao_globalshortcut,ao_localshortcut] * delta <> [] then begin + registeronshortcut([ao_globalshortcut,ao_localshortcut] * value <> []); + end; + end; + end; +end; + +procedure tcustomaction.dostatread(const reader: tstatreader); +begin + if reader.candata then begin + checked:= reader.readboolean('checked',checked); + end; +end; + +procedure tcustomaction.dostatwrite(const writer: tstatwriter); +begin + if writer.candata then begin + writer.writeboolean('checked',checked); + end; +end; + +procedure tcustomaction.statreading; +begin + //dummy +end; + +procedure tcustomaction.statread; +begin + //dummy +end; + +function tcustomaction.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomaction.doasyncevent(var atag: integer); +begin + if canevent(tmethod(fonasyncevent)) then begin + fonasyncevent(self,atag); + end; +end; + +procedure tcustomaction.eventfired(const sender: tobject; + const ainfo: actioninfoty); +begin + if canevent(tmethod(fonexecuteaction)) then begin + fonexecuteaction(self); + end; + sendchangeevent(oe_fired); +{$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.execute(iifiexeclink(self)); + end; +{$endif} +end; + +procedure tcustomaction.registeronshortcut(const avalue: boolean); +begin + //dummy +end; + +procedure tcustomaction.doafterunlink; +begin + //dummy +end; + +{$ifdef mse_with_ifi} +function tcustomaction.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifiexeclink); +end; + +procedure tcustomaction.setifilink(const avalue: tifiactionlinkcomp); +begin + mseificomp.setifilinkcomp(iifiexeclink(self),avalue,tifilinkcomp(fifilink)); + if (fifilink <> nil) then begin + ifisetenabled(fifilink.c.enabled); + end; +end; +{$endif} + +function tcustomaction.getvisible: boolean; +begin + result:= not(as_invisible in finfo.state); +end; + +procedure tcustomaction.setvisible(const avalue: boolean); +begin + if avalue then begin + state:= state - [as_invisible]; + end + else begin + state:= state + [as_invisible]; + end; +end; + +function tcustomaction.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +end. + diff --git a/mseide-msegui/lib/common/kernel/mseactions.pas b/mseide-msegui/lib/common/kernel/mseactions.pas new file mode 100644 index 0000000..b74ffd8 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseactions.pas @@ -0,0 +1,2250 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseactions; +{$ifdef FPC} + {$mode objfpc}{$h+} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseact,mseglob,mseguiglob,msegui,mseevent,mseclasses,msebitmap, + msekeyboard,msetypes,msestrings,msearrayprops,msestatfile,msestat, + mseinterfaces; + +type + + sysshortcutty = (sho_copy,sho_paste,sho_cut,sho_selectall, + sho_rowinsert,sho_rowappend,sho_rowdelete, + sho_copycells,sho_pastecells,sho_groupundo,sho_groupredo); + sysshortcutaty = array[sysshortcutty] of shortcutty; + psysshortcutaty = ^sysshortcutaty; + + shortcutconstty = array[0..2] of shortcutty; + assistiveshortcutty = (shoa_speakagain,shoa_speakpath, + shoa_firstelement,shoa_lastelement, + shoa_cancelspeech, + shoa_slower,shoa_faster,shoa_volumedown,shoa_volumeup); + assistiveshortcutconstty = array[assistiveshortcutty] of shortcutconstty; + assistiveshortcutaty = array[assistiveshortcutty] of shortcutarty; + passistiveshortcutaty = ^assistiveshortcutaty; + + taction = class(tcustomaction,iimagelistinfo,iactionlink) + private +// fmultishortcut: integer; //0 = none, 1 = shortcut, 2 = shortcut1 +// fmultiindex: integer; //index of current checked char + procedure setimagelist(const Value: timagelist); + function getshortcut: shortcutty; + procedure setshortcut(const avalue: shortcutty); + function getshortcut1: shortcutty; + procedure setshortcut1(const avalue: shortcutty); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + procedure readshortcut(reader: treader); + procedure readshortcut1(reader: treader); + procedure readsc(reader: treader); + procedure writesc(writer: twriter); + procedure readsc1(reader: treader); + procedure writesc1(writer: twriter); + //iimagelistinfo + function getimagelist: timagelist; + //iactionlink + function getactioninfopo: pactioninfoty; + procedure actionchanged; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + protected + procedure registeronshortcut(const avalue: boolean); override; + procedure doshortcut(const sender: twidget; var keyinfo: keyeventinfoty); + procedure doafterunlink; override; + procedure defineproperties(filer: tfiler); override; + public +// destructor destroy; override; + property shortcuts: shortcutarty read finfo.shortcut write setshortcuts; + property shortcuts1: shortcutarty read finfo.shortcut1 write setshortcuts1; + published + property imagelist: timagelist read getimagelist write setimagelist; + property shortcut: shortcutty read getshortcut write setshortcut + stored false default ord(key_none) ; + property shortcut1: shortcutty read getshortcut1 write setshortcut1 + stored false default ord(key_none); + property caption; + property state; + property group; + property tagaction; + property imagenr; + property imagenrdisabled; + property colorglyph; + property color; + property imagecheckedoffset; + property hint; + property statfile; + property statvarname; + property statpriority; + property options; + property onexecute; + property onbeforeexecute; + property onafterexecute; + property onexecuteaction; + property onupdate; + property onchange; + property onasyncevent; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + + tshortcutaction = class(townedeventpersistent,iactionlink) + private + finfo: actioninfoty; //as interface to shortcut propertyeditor + faction: taction; +// fshortcutsdefault: shortcutarty; +// fshortcuts1default: shortcutarty; + fdispname: msestring; +// fhint: msestring; + procedure setaction(const avalue: taction); + procedure readsc(reader: treader); + procedure writesc(writer: twriter); + procedure readsc1(reader: treader); + procedure writesc1(writer: twriter); + procedure readshortcut(reader: treader); + procedure readshortcut1(reader: treader); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + //iactionlink + function getactioninfopo: pactioninfoty; + procedure actionchanged; + function loading: boolean; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + + protected + function getshortcutdefault: shortcutty; + procedure setshortcutdefault(const avalue: shortcutty); + function getshortcut1default: shortcutty; + procedure setshortcut1default(const avalue: shortcutty); + procedure defineproperties(filer: tfiler); override; + public + property shortcutsdefault: shortcutarty read finfo.shortcut + write setshortcuts; + property shortcuts1default: shortcutarty read finfo.shortcut1 + write setshortcuts1; + published + property action: taction read faction write setaction; + property shortcutdefault: shortcutty read getshortcutdefault + write setshortcutdefault + stored false default 0; + property shortcut1default: shortcutty read getshortcut1default + write setshortcut1default + stored false default 0; + property dispname: msestring read fdispname write fdispname; + property hint: msestring read finfo.hint write finfo.hint; + end; + +type + shortcutrecarty = array of + record + name: string; + value: int32; + end; + + tshortcutcontroller = class; + tshortcutactions = class(townedeventpersistentarrayprop) + private + protected + function getitems(const index: integer): tshortcutaction; + public + constructor create(const aowner: tshortcutcontroller); reintroduce; + class function getitemclasstype: persistentclassty; override; + public + property items[const index: integer]: tshortcutaction read getitems; + default; + end; + + tsysshortcuts = class(tintegerarrayprop) + private + fowner: tcomponent; + fdatapo: psysshortcutaty; + fshortcuts: shortcutrecarty; + function getitems(const index: sysshortcutty): shortcutty; + procedure setitems(const index: sysshortcutty; const avalue: shortcutty); + function getshortcutrecord(const index: integer): msestring; + procedure setshortcutcount(const acount: integer); + procedure setshortcutrecord(const index: integer; const avalue: msestring); + protected + procedure setfixcount(const avalue: integer); override; + procedure dochange(const aindex: integer); override; + procedure dostatread(const varname: msestring; const reader: tstatreader); + procedure dostatwrite(const varname: msestring; const writer: tstatwriter); + procedure readitem(const index: integer; reader: treader); override; + public + constructor create(const aowner: tcomponent; const adatapo: psysshortcutaty); + property items[const index: sysshortcutty]: shortcutty read getitems + write setitems; default; + end; + + assistiveshortcutrecarty = array of + record + name: string; + value: shortcutarty; + end; + + tassistiveshortcuts = class(tdynarrayarrayprop) + private + fowner: tcomponent; + fdatapo: passistiveshortcutaty; + fshortcuts: assistiveshortcutrecarty; + function getitems(const index: assistiveshortcutty): shortcutarty; + procedure setitems(const index: assistiveshortcutty; const avalue: shortcutarty); + function getshortcutrecord(const index: integer): msestring; + procedure setshortcutcount(const acount: integer); + procedure setshortcutrecord(const index: integer; const avalue: msestring); + protected + procedure internalsetcount(const acount: int32) override; + procedure setfixcount(const avalue: integer); override; + procedure dochange(const aindex: integer); override; + procedure dostatread(const varname: msestring; const reader: tstatreader); + procedure dostatwrite(const varname: msestring; const writer: tstatwriter); + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + public + constructor create(const aowner: tcomponent; const adatapo: passistiveshortcutaty); + property items[const index: assistiveshortcutty]: shortcutarty read getitems + write setitems; default; + end; + + shortcutstatinfoty = record + name: ansistring; + shortcut: shortcutarty; + shortcut1: shortcutarty; + end; + shortcutstatinfoarty = array of shortcutstatinfoty; + shortcutcontrollereventty = procedure( + const sender: tshortcutcontroller) of object; + tshortcutcontroller = class(tmsecomponent,istatfile) + private + factions: tshortcutactions; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatinfos: shortcutstatinfoarty; + fsysshortcuts: tsysshortcuts; + fsysshortcuts1: tsysshortcuts; + fonafterupdate: shortcutcontrollereventty; + fstatpriority: integer; + fassistiveshortcuts: tassistiveshortcuts; + fassistiveshortcuts1: tassistiveshortcuts; + procedure setactions(const avalue: tshortcutactions); + procedure setstatfile(const avalue: tstatfile); + function getactionrecord(const index: integer): msestring; + procedure setactionreccount(const acount: integer); + procedure setactionrecord(const index: integer; const avalue: msestring); + procedure setsysshortcuts(const avalue: tsysshortcuts); + procedure setsysshortcuts1(const avalue: tsysshortcuts); + procedure setassistiveshortcuts(const avalue: tassistiveshortcuts); + procedure setassistiveshortcuts1(const avalue: tassistiveshortcuts); + protected + procedure updateaction(const aaction: taction); reintroduce; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure doafterupdate; + published + property actions: tshortcutactions read factions write setactions; + property sysshortcuts: tsysshortcuts read fsysshortcuts + write setsysshortcuts; + property sysshortcuts1: tsysshortcuts read fsysshortcuts1 + write setsysshortcuts1; + property assistiveshortcuts: tassistiveshortcuts read fassistiveshortcuts + write setassistiveshortcuts; + property assistiveshortcuts1: tassistiveshortcuts read fassistiveshortcuts1 + write setassistiveshortcuts1; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property onafterupdate: shortcutcontrollereventty read fonafterupdate + write fonafterupdate; + end; + + tcustomhelpcontroller = class; + helpcontrollereventty = procedure(const sender: tcustomhelpcontroller; + const helpsender: tmsecomponent; var handled: boolean) of object; + helpcontrollerprocty = procedure(const sender: tcustomhelpcontroller; + const helpsender: tmsecomponent; var handled: boolean); + + tcustomhelpcontroller = class(tmsecomponent) + private + fonhelp: helpcontrollereventty; + fonhelp1: helpcontrollerprocty; + fshortcut: shortcutty; + fshortcut1: shortcutty; + fshortcutregistered: boolean; + procedure setshortcut(const avalue: shortcutty); + procedure setshortcut1(const avalue: shortcutty); + procedure checkshortcuts(); + protected + procedure dohelp(const sender: tmsecomponent; var handled: boolean); virtual; + procedure doshortcut(const sender: twidget; var keyinfo: keyeventinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property onhelp: helpcontrollereventty read fonhelp write fonhelp; + property onhelp1: helpcontrollerprocty read fonhelp1 write fonhelp1; + property shortcut: shortcutty read fshortcut write setshortcut + default ord(key_none) ; + property shortcut1: shortcutty read fshortcut1 write setshortcut1 + default ord(key_none); + end; + + thelpcontroller = class(tcustomhelpcontroller) + published + property onhelp; + property shortcut; + property shortcut1; + end; + +function issameshortcut(const a,b: shortcutarty): boolean; +function getsimpleshortcut(const asource: shortcutarty): shortcutty; overload; +function getsimpleshortcut(const asource: actioninfoty): shortcutty; overload; +function getsimpleshortcut1(const asource: actioninfoty): shortcutty; +function setsimpleshortcut(const avalue: shortcutty): shortcutarty; overload; +procedure setsimpleshortcut(const avalue: shortcutty; + var adest: shortcutarty); overload; +procedure setsimpleshortcut(const avalue: shortcutty; + var adest: actioninfoty); overload; +procedure setsimpleshortcut1(const avalue: shortcutty; var adest: actioninfoty); +function checkshortcutconflict(const a,b: shortcutarty): boolean; + +procedure setactionshortcuts(const sender: iactionlink; + const value: shortcutarty); +procedure setactionshortcuts1(const sender: iactionlink; + const value: shortcutarty); +procedure setactionshortcut(const sender: iactionlink; const value: shortcutty); +procedure setactionshortcut1(const sender: iactionlink; + const value: shortcutty); +function isactionshortcutstored(const info: actioninfoty): boolean; +function isactionshortcut1stored(const info: actioninfoty): boolean; +procedure setactionimagelist(const sender: iactionlink; + const value: timagelist); +function isactionimageliststored(const info: actioninfoty): boolean; + +procedure getshortcutlist(out keys: integerarty; out names: msestringarty); +function getshortcutname(const shortcut: shortcutty): msestring; +function getshortcutname(const key: keyty; + const shiftstate: shiftstatesty): msestring; +//function getshortcutname(key: shortcutarty): msestring; +function getsysshortcutdispname(const aitem: sysshortcutty): msestring; +function getassistiveshortcutdispname( + const aitem: assistiveshortcutty): msestring; + +function isvalidshortcut(const ashortcut: shortcutty): boolean; +function encodeshortcut(const akey: keyty; + const ashiftstate: shiftstatesty): shortcutty; +function encodeshortcutname(const key: shortcutarty): msestring; overload; +function encodeshortcutname(const key: shortcutty): msestring; overload; +function checkshortcutcode(const shortcut: shortcutty; + const info: keyeventinfoty; + const apreview: boolean = false): boolean; overload; +function checkshortcutcode(const shortcut: shortcutty; + const info: keyinfoty): boolean; overload; +function checkactionshortcut(const ashortcut: shortcutarty; + var keyinfo: keyeventinfoty): boolean; //true if done +function checkactionshortcut(var info: actioninfoty; + var keyinfo: keyeventinfoty): boolean; //true if done +function doactionshortcut(const sender: tobject; var info: actioninfoty; + var keyinfo: keyeventinfoty; + const beforeexecute: proceventty = nil): boolean; + //true if executed +procedure calccaptiontext(var info: actioninfoty; const aseparator: msechar); +function issysshortcut(const ashortcut: sysshortcutty; + const ainfo: keyeventinfoty): boolean; + +const + shift = ord(key_modshift); + ctrl = ord(key_modctrl); + alt = ord(key_modalt); + pad = ord(key_modpad); + + modmask = shift or ctrl or alt or $1000 or pad; // $1000 -> old format + + defaultsysshortcuts: sysshortcutaty = +//sho_copy, sho_paste, sho_cut, + (ctrl+ord(key_c), ctrl+ord(key_v), ctrl+ord(key_x), +//sho_selectall + ctrl+ord(key_a), +//sho_rowinsert, sho_rowappend, sho_rowdelete + ctrl+ord(key_insert),shift+ctrl+ord(key_insert),ctrl+ord(key_delete), +//sho_copycells sho_pastecells + (ctrl+shift+ord(key_c)),(ctrl+shift+ord(key_v)), +//sho_groupundo, sho_groupredo + ctrl+ord(key_z), shift+ctrl+ord(key_z) + ); + + defaultsysshortcuts1: sysshortcutaty = +//sho_copy, sho_paste, sho_cut, + (ord(key_none), shift+ord(key_insert), shift+ord(key_delete), +//sho_selectall + ord(key_none), +//sho_rowinsert, sho_rowappend, sho_rowdelete + ord(key_none), ord(key_none), ord(key_none), +//sho_copycells sho_pastecells + ord(key_none), ord(key_none), +//sho_groupundo, sho_groupredo + ord(key_none), ord(key_none) + ); + + defaultassistiveshortcuts: assistiveshortcutconstty = + //shoa_speakagain, shoa_speakpath + ((ctrl+ord(key_space),0,0),(ctrl+shift+ord(key_space),0,0), + //shoa_firstelement, shoa_lastelement + (ctrl+ord(key_y),ord(key_f),0),(ctrl+ord(key_y),ord(key_l),0), + //shoa_cancelspeech + (ctrl+ord(key_y),ord(key_c),0), + //shoa_slower, shoa_faster + (pad+ctrl+ord(key_minus),0,0),(pad+ctrl+ord(key_plus),0,0), + //shoa_volumedown, shoa_volumeup + (pad+shift+ctrl+ord(key_minus),0,0),(pad+shift+ctrl+ord(key_plus),0,0) + ); + defaultassistiveshortcuts1: assistiveshortcutconstty = + //shoa_speakagain, shoa_speakpath + ((pad+ctrl+ord(key_return),0,0),(pad+ctrl+shift+ord(key_return),0,0), + //shoa_firstelement, shoa_lastelement + (ord(key_none),0,0),(ord(key_none),0,0), + //shoa_cancelspeech + (ord(key_none),0,0), + //shoa_slower, shoa_faster + (ord(key_none),0,0),(ord(key_none),0,0), + //shoa_volumedown, shoa_volumeup + (ord(key_none),0,0),(ord(key_none),0,0) + ); +var + sysshortcuts: sysshortcutaty; + sysshortcuts1: sysshortcutaty; + assistiveshortcuts: assistiveshortcutaty; + assistiveshortcuts1: assistiveshortcutaty; + +implementation +uses + sysutils,mserichstring,msestream,typinfo,mseformatstr,msestreaming, + msestockobjects,mseassistiveserver,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + +const + letterkeycount = ord('z') - ord('a') + 1; + cipherkeycount = ord('9') - ord('0') + 1; + functionkeycount = 12; + misckeycount = ord(key_sysreq) - ord(key_escape) + 1; + cursorkeycount = ord(key_pagedown) - ord(key_home) + 1; + specialshortcutcount = ord(high(specialshortcutty))+1; + specialkeycount = misckeycount + specialshortcutcount + cursorkeycount; + padcharkeycount = ord(key_slash)-ord(key_asterisk) + 1; + padspecialkeycount = ord(key_decimal)-ord(key_decimal) + 1; +{ + shortcutcount = (letterkeycount + cipherkeycount) * 2 + //ctrl,shiftctrl + 3 + //space + functionkeycount * 4 + //none,shift,ctrl,shiftctrl + specialkeycount * 4; //none,shift,ctrl,shiftctrl +} + baseshortcutcount = letterkeycount + cipherkeycount + 1 + //Space + functionkeycount + specialkeycount; + shortcutcount = 4 * (baseshortcutcount + padcharkeycount + padspecialkeycount + + cipherkeycount); + //none,shift,ctrl,shift+ctrl + +var + shortcutkeys: integerarty; + shortcutnames: msestringarty; + baseshortcutkeys: integerarty; + baseshortcutnames: msestringarty; + padcharshortcutkeys: integerarty; + padcharshortcutnames: msestringarty; + padspecialshortcutkeys: integerarty; + padspecialshortcutnames: msestringarty; + +procedure handleassistiveexec(const sender: tobject; const info: actioninfoty); +begin + if assistiveserver <> nil then begin + if sender is twidget then begin + assistiveserver.doactionexecute(twidget1(sender).getiassistiveclient(), + sender,info); + end + else begin + assistiveserver.doactionexecute(nil,sender,info); + end; + end; +end; + +function issysshortcut(const ashortcut: sysshortcutty; + const ainfo: keyeventinfoty): boolean; +begin + result:= checkshortcutcode(sysshortcuts[ashortcut],ainfo) or + checkshortcutcode(sysshortcuts1[ashortcut],ainfo); +end; + +procedure getvalues(var bottom: integer; prefix: msestring; + const modvalue: integer; var keys: integerarty; + var names: msestringarty); +var + int1: integer; + akey: keyty; +begin + keys[bottom]:= ord(key_space) + modvalue; + names[bottom]:= prefix+spacekeyname; + inc(bottom); + for int1:= bottom to bottom+cipherkeycount-1 do begin + keys[int1]:= ord(key_0) + int1-bottom + modvalue; + names[int1]:= prefix+msestring(msechar(int1-bottom+ord('0'))); + end; + bottom:= bottom + cipherkeycount; + for int1:= bottom to bottom+letterkeycount-1 do begin + keys[int1]:= ord(key_a) + int1-bottom + modvalue; + names[int1]:= prefix+msestring(msechar(int1-bottom+ord('A'))); + end; + bottom:= bottom + letterkeycount; + for int1:= bottom to bottom + functionkeycount - 1 do begin + keys[int1]:= (ord(key_f1) + int1-bottom) or modvalue; + names[int1]:= prefix+'F'+inttostrmse(int1-bottom+1); + end; + bottom:= bottom+functionkeycount; + for int1:= bottom to bottom+misckeycount-1 do begin + akey:= keyty(ord(key_escape) + int1-bottom); + keys[int1]:= ord(akey)or modvalue; + names[int1]:= prefix+shortmisckeynames[akey]; + end; + bottom:= bottom+misckeycount; + for int1:= bottom to bottom+specialshortcutcount-1 do begin + keys[int1]:= ord(specialkeys[specialshortcutty(int1-bottom)]) or modvalue; + names[int1]:= prefix+specialkeynames[specialshortcutty(int1-bottom)]; + end; + bottom:= bottom+specialshortcutcount; + for int1:= bottom to bottom+cursorkeycount-1 do begin + akey:= keyty(ord(key_home) + int1-bottom); + keys[int1]:= ord(akey)or modvalue; + names[int1]:= prefix+shortcursorkeynames[akey]; + end; + bottom:= bottom+cursorkeycount; +end; + +procedure getpadcharvalues(var bottom: integer; prefix: msestring; + const modvalue: integer; var keys: integerarty; + var names: msestringarty); +var + int1: integer; + akey: keyty; +begin + for int1:= bottom to bottom + padcharkeycount - 1 do begin + akey:= keyty(ord(key_asterisk) + int1-bottom); + keys[int1]:= ord(akey) or modvalue; + names[int1]:= prefix+padcharkeynames[akey]; + end; + bottom:= bottom+padcharkeycount; +end; + +procedure getpadspecialvalues(var bottom: integer; prefix: msestring; + const modvalue: integer; var keys: integerarty; + var names: msestringarty); +var + int1: integer; + akey: keyty; +begin + for int1:= bottom to bottom + padspecialkeycount - 1 do begin + akey:= keyty(ord(key_decimal) + int1-bottom); + keys[int1]:= ord(akey) or modvalue; + names[int1]:= prefix+padspecialkeynames[akey]; + end; + bottom:= bottom+padspecialkeycount; +end; + +procedure getpadvalues(var bottom: integer; prefix: msestring; + const modvalue: integer; var keys: integerarty; + var names: msestringarty); +var + int1: integer; + akey: keyty; +begin + for int1:= bottom to bottom+cipherkeycount-1 do begin + keys[int1]:= ord(key_0) + int1-bottom + modvalue; + names[int1]:= prefix+msestring(msechar(int1-bottom+ord('0'))); + end; + bottom:= bottom + cipherkeycount; + for int1:= bottom to bottom + padcharkeycount - 1 do begin + akey:= keyty(ord(key_asterisk) + int1-bottom); + keys[int1]:= ord(akey) or modvalue; + names[int1]:= prefix+padcharkeynames[akey]; + end; + bottom:= bottom+padcharkeycount; + for int1:= bottom to bottom + padspecialkeycount - 1 do begin + akey:= keyty(ord(key_decimal) + int1-bottom); + keys[int1]:= ord(akey) or modvalue; + names[int1]:= prefix+padspecialkeynames[akey]; + end; + bottom:= bottom+padspecialkeycount; +end; + +procedure getshortcutlist(out keys: integerarty; out names: msestringarty); +var +// int1: integer; + bo1: boolean; + bottom: integer; +// akey: keyty; +begin + bo1:= false; + if shortcutkeys = nil then begin + setlength(shortcutkeys,shortcutcount); + bo1:= true; + end; + if shortcutnames = nil then begin + setlength(shortcutnames,shortcutcount); + bo1:= true; + end; + keys:= shortcutkeys; + names:= shortcutnames; + if bo1 then begin + bottom:= 0; + getvalues(bottom,'',0,keys,names); + getvalues(bottom,'Shift+',key_modshift,keys,names); + getvalues(bottom,'Ctrl+',key_modctrl,keys,names); + getvalues(bottom,'Shift+Ctrl+',key_modshiftctrl,keys,names); + getpadvalues(bottom,'Pad+',key_modpad,keys,names); + getpadvalues(bottom,'Shift+Pad+',key_modpadshift,keys,names); + getpadvalues(bottom,'Ctrl+Pad+',key_modpadctrl,keys,names); + getpadvalues(bottom,'Shift+Ctrl+Pad+',key_modpadshiftctrl,keys,names); + end; +end; + +function getshortcutname(const shortcut: shortcutty): msestring; +var + int1{,int2}: integer; + keys: integerarty; + names: msestringarty; +begin + result:= ''; + if shortcut <> 0 then begin + getshortcutlist(keys,names); + for int1:= 0 to high(keys) do begin + if shortcut = keys[int1] then begin + result:= names[int1]; + exit; + end; + end; + result:= '$'+msestring(intvaluetostr(shortcut,nb_hex,16)); + end; +end; + +function getshortcutname(const key: keyty; + const shiftstate: shiftstatesty): msestring; +var + shortcut: shortcutty; +begin + shortcut:= ord(key); + if ss_shift in shiftstate then begin + shortcut:= shortcut or shift; + end; + if ss_ctrl in shiftstate then begin + shortcut:= shortcut or ctrl; + end; + if ss_alt in shiftstate then begin + shortcut:= shortcut or alt; + end; + if ss_second in shiftstate then begin + shortcut:= shortcut or pad; + end; + result:= getshortcutname(shortcut); +end; +{ +function getshortcutname(key: shortcutarty): msestring; +var + keys: integerarty; + names: msestringarty; + int1,int2,int3: integer; +begin + result:= ''; + if high(key) >= 0 then begin + getshortcutlist(keys,names); + for int3:= 0 to high(key) do begin + int2:= key[int3]; + for int1:= 0 to high(keys) do begin + if keys[int1] = int2 then begin + result:= result + names[int1] + ' '; + break; + end; + end; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; + end; +end; +} +//todo: internationalize +function getsysshortcutdispname(const aitem: sysshortcutty): msestring; +const + list: array[sysshortcutty] of stockcaptionty = ( + sc_Copy,sc_Paste,sc_cut,sc_select_all, + sc_row_insert,sc_row_append,sc_row_delete, + sc_copy_cells,sc_paste_cells,sc_undo,sc_redo); +begin + result:= stockobjects.captions[list[aitem]]; +end; + +function getassistiveshortcutdispname( + const aitem: assistiveshortcutty): msestring; +const + list: array[assistiveshortcutty] of stockcaptionty = ( + sc_speakagain,sc_speakpath,sc_firstelement,sc_lastelement, + sc_cancelspeech, + sc_slower,sc_faster,sc_volumedown,sc_volumeup); +begin + result:= stockobjects.captions[list[aitem]]; +end; + +function isnormalkey(const akey: shortcutty): boolean; +begin + result:= (akey >= ord(key_0)) and (akey <= ord(key_9)) or + (akey >= ord(key_a)) and (akey <= ord(key_z)) or + (akey >= ord(key_asterisk)) and (akey <= ord(key_slash)) or + (akey = ord(key_left)) or + (akey = ord(key_right)) or + (akey = ord(key_up)) or + (akey = ord(key_down)) or + (akey = ord(key_tab)) or + (akey = ord(key_space)) or + (akey = ord(key_return)){ or + (akey = ord(key_enter))}; +end; + +function isnormalshiftkey(const akey: shortcutty): boolean; +begin + result:= (akey >= ord(key_0)) and (akey <= ord(key_9)) or + (akey >= ord(key_a)) and (akey <= ord(key_z)) or + (akey = ord(key_tab)); +end; + +function isvalidshortcut(const ashortcut: shortcutty): boolean; +var + key: word; +begin + key:= ashortcut and not modmask; + result:= (key <> 0) and (key <> word(not modmask)); + if result then begin + if ashortcut and (modmask and not pad) = 0 then begin + result:= not isnormalkey(key); + end + else begin + if ashortcut and modmask = shift then begin + result:= not isnormalshiftkey(key); + end; + end; + end; +end; + +function encodeshortcut(const akey: keyty; + const ashiftstate: shiftstatesty): shortcutty; +begin + result:= ord(akey) and not modmask; + if ss_shift in ashiftstate then begin + result:= result or shift; + end; + if ss_ctrl in ashiftstate then begin + result:= result or ctrl; + end; + if ss_alt in ashiftstate then begin + result:= result or alt; + end; + if ss_second in ashiftstate then begin + result:= result or pad; + end; +end; + +function encodeshortcutname(const key: shortcutty): msestring; +var + bo1: boolean; + int1: integer; + k1: shortcutty; + mstr1: msestring; +begin + bo1:= false; + if baseshortcutkeys = nil then begin + setlength(baseshortcutkeys,baseshortcutcount); + bo1:= true; + end; + if baseshortcutnames = nil then begin + setlength(baseshortcutnames,baseshortcutcount); + bo1:= true; + end; + if padcharshortcutkeys = nil then begin + setlength(padcharshortcutkeys,padcharkeycount); + bo1:= true; + end; + if padcharshortcutnames = nil then begin + setlength(padcharshortcutnames,padcharkeycount); + bo1:= true; + end; + if padspecialshortcutkeys = nil then begin + setlength(padspecialshortcutkeys,padspecialkeycount); + bo1:= true; + end; + if padspecialshortcutnames = nil then begin + setlength(padspecialshortcutnames,padspecialkeycount); + bo1:= true; + end; + if bo1 then begin + int1:= 0; + getvalues(int1,'',0,baseshortcutkeys,baseshortcutnames); + int1:= 0; + getpadcharvalues(int1,'',0,padcharshortcutkeys,padcharshortcutnames); + int1:= 0; + getpadspecialvalues(int1,'',0,padspecialshortcutkeys,padspecialshortcutnames); + end; + mstr1:= ''; + k1:= key and not modmask; + for int1:= 0 to high(baseshortcutkeys) do begin + if baseshortcutkeys[int1] = k1 then begin + mstr1:= baseshortcutnames[int1]; + break; + end; + end; + if mstr1 = '' then begin + for int1:= 0 to high(padcharshortcutkeys) do begin + if padcharshortcutkeys[int1] = k1 then begin + mstr1:= padcharshortcutnames[int1]; + break; + end; + end; + end; + if mstr1 = '' then begin + for int1:= 0 to high(padspecialshortcutkeys) do begin + if padspecialshortcutkeys[int1] = k1 then begin + mstr1:= padspecialshortcutnames[int1]; + break; + end; + end; + end; + if mstr1 = '' then begin + if key = 0 then begin + result:= ''; + end + else begin + result:= '$'+hextostrmse(key,4); + end; + end + else begin + result:= ''; + if (key and shift) <> 0 then begin + result:= result + 'Shift+'; + end; + if (key and alt) <> 0 then begin + result:= result + 'Alt+'; + end; + if (key and ctrl) <> 0 then begin + result:= result + 'Ctrl+'; + end; + if (key and pad) <> 0 then begin + result:= result + 'Pad+'; + end; + result:= result + mstr1; + end; +end; + +function encodeshortcutname(const key: shortcutarty): msestring; +var + int1: integer; +begin + result:= ''; + if high(key) >= 0 then begin + for int1:= 0 to high(key) do begin + result:= result + encodeshortcutname(key[int1]) + ' '; + end; + setlength(result,length(result)-1); + end; +end; + +procedure calccaptiontext(var info: actioninfoty; const aseparator: msechar); +var + str1: msestring; +begin + str1:= info.captiontext; + if (info.shortcut <> nil) and (mao_shortcutcaption in info.options) then begin + str1:= str1 + aseparator + '('+encodeshortcutname(info.shortcut)+')'; + end; + captiontorichstring(str1,info.caption1); +end; + +function issameshortcut(const a,b: shortcutarty): boolean; +var + int1: integer; +begin + result:= (a = b); + if not result then begin + result:= high(a) = high(b); + if result then begin + for int1:= 0 to high(a) do begin + if a[int1] <> b[int1] then begin + result:= false; + break; + end; + end; + end; + end; +end; + +function getsimpleshortcut(const asource: shortcutarty): shortcutty; +begin + result:= 0; + if asource <> nil then begin + result:= asource[0]; + end; +end; + +function getsimpleshortcut(const asource: actioninfoty): shortcutty; +begin + result:= 0; + if asource.shortcut <> nil then begin + result:= asource.shortcut[0]; + end; +end; + +function getsimpleshortcut1(const asource: actioninfoty): shortcutty; +begin + result:= 0; + if asource.shortcut1 <> nil then begin + result:= asource.shortcut1[0]; + end; +end; + +procedure setsimpleshortcut(const avalue: shortcutty; var adest: shortcutarty); +begin + if avalue = 0 then begin + adest:= nil; + end + else begin + setlength(adest,1); + adest[0]:= avalue; + end; +end; + +function setsimpleshortcut(const avalue: shortcutty): shortcutarty; +begin + setsimpleshortcut(avalue,result); +end; + +procedure setsimpleshortcut(const avalue: shortcutty; var adest: actioninfoty); +begin + if avalue = 0 then begin + adest.shortcut:= nil; + end + else begin + setlength(adest.shortcut,1); + adest.shortcut[0]:= avalue; + end; +end; + +procedure setsimpleshortcut1(const avalue: shortcutty; var adest: actioninfoty); +begin + if avalue = 0 then begin + adest.shortcut1:= nil; + end + else begin + setlength(adest.shortcut1,1); + adest.shortcut1[0]:= avalue; + end; +end; + +function checkshortcutconflict(const a,b: shortcutarty): boolean; + function pos1(const sub,checked:shortcutarty): boolean; + var + int1,int2: integer; + begin + result:= sub <> nil; + if result then begin + result:= sub = checked; + if not result and (high(checked) >= high(sub)) then begin + for int1:= 0 to high(checked) - high(sub) do begin + if checked[int1] = sub[0] then begin + result:= true; + for int2:= 1 to high(sub) do begin + if checked[int1+int2] <> sub[int2] then begin + result:= false; + break; + end; + end; + if result then begin + break; + end; + end; + end; + end; + end; + end; //pos1 +begin + result:= pos1(a,b) or pos1(b,a); +end; + +procedure setactionshortcut(const sender: iactionlink; const value: shortcutty); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + setsimpleshortcut(value,po1^); + include(po1^.state,as_localshortcut); + sender.calccaptiontext(po1^{,sender.shortcutseparator}); + sender.actionchanged; +end; + +procedure setactionshortcut1(const sender: iactionlink; const value: shortcutty); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + setsimpleshortcut1(value,po1^); + include(po1^.state,as_localshortcut1); + sender.actionchanged; +end; + +procedure setactionshortcuts(const sender: iactionlink; + const value: shortcutarty); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + po1^.shortcut:= value; + include(po1^.state,as_localshortcut); + sender.calccaptiontext(po1^{,sender.shortcutseparator}); + sender.actionchanged; +end; + +procedure setactionshortcuts1(const sender: iactionlink; + const value: shortcutarty); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + po1^.shortcut1:= value; + include(po1^.state,as_localshortcut1); + sender.actionchanged; +end; + +function isactionshortcutstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localshortcut in state) and + not ((action = nil) and (shortcut = nil)); + end; +end; + +function isactionshortcut1stored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localshortcut1 in state) and + not ((action = nil) and (shortcut1 = nil)); + end; +end; + +procedure setactionimagelist(const sender: iactionlink; const value: timagelist); +begin + with sender.getactioninfopo^ do begin + if not (as_localimagelist in state) then begin + imagelist:= nil; //do not unink,imagelist is owned by action + end; + setlinkedcomponent(sender,value,tmsecomponent(imagelist)); + include(state,as_localimagelist); + end; + sender.actionchanged; +end; + +function isactionimageliststored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localimagelist in state) and + not ((action = nil) and (imagelist = nil)); + end; +end; + +function checkshortcutcode(const shortcut: shortcutty; + const info: keyeventinfoty; const apreview: boolean = false): boolean; +var + acode: shortcutty; +begin + result:= false; + if (shortcut <> 0) and + ((es_preview in info.eventstate) xor not apreview) then begin + with info do begin + acode:= 0; + if ss_shift in shiftstate then begin + acode:= acode or key_modshift; + end; + if ss_ctrl in shiftstate then begin + acode:= acode or key_modctrl; + end; + if ss_alt in shiftstate then begin + acode:= acode or key_modalt; + end; + if ss_second in shiftstate then begin + acode:= acode or key_modpad; + end; + result:= (acode or ord(key) = shortcut) or + (acode or ord(keynomod) = shortcut); + end; + end; +end; + +function checkshortcutcode(const shortcut: shortcutty; + const info: keyinfoty): boolean; +var + acode: shortcutty; +begin + result:= false; + if (shortcut <> 0) then begin + with info do begin + acode:= 0; + if ss_shift in shiftstate then begin + acode:= acode or key_modshift; + end; + if ss_ctrl in shiftstate then begin + acode:= acode or key_modctrl; + end; + if ss_alt in shiftstate then begin + acode:= acode or key_modalt; + end; + if ss_second in shiftstate then begin + acode:= acode or key_modpad; + end; + result:= (acode or ord(key) = shortcut) or + (acode or ord(keynomod) = shortcut); + end; + end; +end; + +function getshortcutcodenomod(const info: keyeventinfoty): shortcutty; +begin + with info do begin + result:= ord(info.keynomod); + if ss_shift in info.shiftstate then begin + result:= result or key_modshift; + end; + if ss_ctrl in info.shiftstate then begin + result:= result or key_modctrl; + end; + if ss_alt in info.shiftstate then begin + result:= result or key_modalt; + end; + end; +end; + +{ +function doactionshortcut(const sender: tobject; var info: actioninfoty; + var keyinfo: keyeventinfoty): boolean; + //true if done +var + key: word; +begin + result:= false; + with info do begin + if not (as_disabled in state) and not (es_processed in keyinfo.eventstate) and + (not (ss_repeat in keyinfo.shiftstate) or + (as_repeatshortcut in info.state)) then begin + if high(shortcut) = 0 then begin + if checkshortcutcode(shortcut[0],keyinfo) then begin + doactionexecute(sender,info,false,false); + result:= true; + end; + end; + if not result then begin + if high(shortcut1) = 0 then begin + if checkshortcutcode(shortcut1[0],keyinfo) then begin + doactionexecute(sender,info); + result:= true; + end; + end; + end; + if result then begin + include(keyinfo.eventstate,es_processed); + end; + end; + end; +end; +} + +function check(const ar1: shortcutarty; out exec: boolean; + var keyinfo: keyeventinfoty): boolean; +var + int1,int2,int3: integer; +begin +{ + if anum = 2 then begin + ar1:= info.shortcut1; + end + else begin + ar1:= info.shortcut; + end; +} + result:= false; + exec:= false; + if (high(ar1) > 0) and (es_preview in keyinfo.eventstate) then begin + exec:= true; + for int1:= high(ar1) downto 0 do begin + if checkshortcutcode(ar1[int1],keyinfo,true) then begin + result:= true; + with application do begin + if high(keyhistory) >= int1-1 then begin + int3:= 0; + if int1 > 0 then begin + for int2:= int1 - 1 downto 0 do begin + if not checkshortcutcode(ar1[int2],keyhistory[int3]) then begin + result:= false; + exec:= false; + break; + end; + inc(int3); + end; + end + else begin + exec:= false; + end; + end + else begin + exec:= false; + result:= false; + end; + end; + if exec then begin + break; + end; + end + else begin + exec:= false + end; + end; + if exec then begin + application.clearkeyhistory; + end; + end + else begin + if high(ar1) >= 0 then begin + if checkshortcutcode(ar1[0],keyinfo,false) then begin + result:= true; + if high(ar1) = 0 then begin + exec:= true; + end; + end; + end; + end; +end; //check + +function checkactionshortcut(var info: actioninfoty; + var keyinfo: keyeventinfoty): boolean; //true if done +var + bo1: boolean; +begin + bo1:= check(info.shortcut,result,keyinfo); + if not bo1 then begin + bo1:= check(info.shortcut1,result,keyinfo); + end; + if bo1 then begin + include(keyinfo.eventstate,es_processed); + end; +end; + +function checkactionshortcut(const ashortcut: shortcutarty; + var keyinfo: keyeventinfoty): boolean; //true if done +begin + if check(ashortcut,result,keyinfo) then begin + include(keyinfo.eventstate,es_processed); + end; +end; + + +function doactionshortcut(const sender: tobject; var info: actioninfoty; + var keyinfo: keyeventinfoty; + const beforeexecute: proceventty = nil): boolean; //true if done +var + bo1: boolean; +begin + result:= checkactionshortcut(info,keyinfo); + if result then begin + result:= doactionexecute1(sender,info,bo1,false,false,beforeexecute); + end; +end; + +{ taction } + +function taction.getimagelist: timagelist; +begin + result:= timagelist(finfo.imagelist); +end; + +procedure taction.setimagelist(const Value: timagelist); +begin + if value <> finfo.imagelist then begin + setlinkedvar(value,tmsecomponent(finfo.imagelist)); + changed; + end; +end; +{ +function taction.getshortcut: shortcutty; +begin + result:= shortcutty(finfo.shortcut); +end; +} +function taction.getshortcut: shortcutty; +begin + result:= getsimpleshortcut(finfo); +end; + +procedure taction.setshortcut(const avalue: shortcutty); +begin + setsimpleshortcut(avalue,finfo); + changed; +end; + +function taction.getshortcut1: shortcutty; +begin + result:= getsimpleshortcut1(finfo); +end; + +procedure taction.setshortcut1(const avalue: shortcutty); +begin + setsimpleshortcut1(avalue,finfo); + changed; +end; + +procedure taction.setshortcuts(const avalue: shortcutarty); +begin + finfo.shortcut:= avalue; + changed; +end; + +procedure taction.setshortcuts1(const avalue: shortcutarty); +begin + finfo.shortcut1:= avalue; + changed; +end; + +procedure taction.registeronshortcut(const avalue: boolean); +begin + if avalue then begin + application.registeronshortcut({$ifdef FPC}@{$endif}doshortcut); + end + else begin + application.unregisteronshortcut({$ifdef FPC}@{$endif}doshortcut); + end; +end; + +procedure taction.doshortcut(const sender: twidget; var keyinfo: keyeventinfoty); +begin + if not (es_local in keyinfo.eventstate) and (ao_globalshortcut in foptions) or + (es_local in keyinfo.eventstate) and (ao_localshortcut in foptions) and + (owner <> nil) and issubcomponent(owner,sender) then begin + doupdate; + with finfo do begin + if not (as_disabled in state) and + not (es_processed in keyinfo.eventstate) and + (not (ss_repeat in keyinfo.shiftstate) or + (as_repeatshortcut in finfo.state)) then begin + if doactionshortcut(sender,finfo,keyinfo) then begin + changed; + end; + end; + end; + end; +end; + +(* +procedure taction.doshortcut(const sender: twidget; var keyinfo: keyeventinfoty); + + function check(const anum: integer; out exec: boolean): boolean; + var + ar1: shortcutarty; + int1,int2,int3: integer; + begin + if anum = 2 then begin + ar1:= finfo.shortcut1; + end + else begin + ar1:= finfo.shortcut; + end; + result:= false; + exec:= false; + if (high(ar1) > 0) and (es_preview in keyinfo.eventstate) then begin + exec:= true; + for int1:= high(ar1) downto 0 do begin + if checkshortcutcode(ar1[int1],keyinfo,true) then begin + result:= true; + with application do begin + if high(keyhistory) >= int1-1 then begin + int3:= 0; + if int1 > 0 then begin + for int2:= int1 - 1 downto 0 do begin + if not checkshortcutcode(ar1[int2],keyhistory[int3]) then begin + result:= false; + exec:= false; + break; + end; + inc(int3); + end; + end + else begin + exec:= false; + end; + end + else begin + exec:= false; + result:= false; + end; + end; + if exec then begin + break; + end; + end + else begin + exec:= false + end; + end; + if exec then begin + application.clearkeyhistory; + end; + end + else begin + if high(ar1) >= 0 then begin + if checkshortcutcode(ar1[0],keyinfo,false) then begin + result:= true; + if high(ar1) = 0 then begin + exec:= true; + end; + end; + end; + end; + end; //check + +var + bo1,bo2: boolean; +begin + bo1:= false; + if not (es_local in keyinfo.eventstate) and (ao_globalshortcut in foptions) or + (es_local in keyinfo.eventstate) and (ao_localshortcut in foptions) and + (owner <> nil) and issubcomponent(owner,sender) then begin + doupdate; + with finfo do begin + if not (as_disabled in state) and + not (es_processed in keyinfo.eventstate) and + (not (ss_repeat in keyinfo.shiftstate) or + (as_repeatshortcut in finfo.state)) then begin + bo1:= check(1,bo2); + if not bo1 then begin + bo1:= check(2,bo2); + end; + end; + end; + end; + if bo1 then begin + include(keyinfo.eventstate,es_processed); + if bo2 then begin + doactionexecute(sender,finfo,false,false); + changed; + end; + end; +end; +*) +procedure taction.doafterunlink; +begin + imagelist:= nil; +end; + +procedure taction.readshortcut(reader: treader); +begin + shortcut:= translateshortcut(reader.readinteger); +end; + +procedure taction.readshortcut1(reader: treader); +begin + shortcut1:= translateshortcut(reader.readinteger); +end; + +procedure taction.readsc(reader: treader); +begin + shortcuts:= readshortcutarty(reader); +end; + +procedure taction.writesc(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut); +end; + +procedure taction.readsc1(reader: treader); +begin + shortcuts1:= readshortcutarty(reader); +end; + +procedure taction.writesc1(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut1); +end; + +procedure taction.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('shortcut',{$ifdef FPC}@{$endif}readshortcut,nil,false); + filer.defineproperty('shortcut1',{$ifdef FPC}@{$endif}readshortcut1,nil,false); + filer.defineproperty('sc',{$ifdef FPC}@{$endif}readsc, + {$ifdef FPC}@{$endif}writesc, + (filer.ancestor = nil) and (shortcuts <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(shortcuts,taction(filer.ancestor).shortcuts))); + filer.defineproperty('sc1',{$ifdef FPC}@{$endif}readsc1, + {$ifdef FPC}@{$endif}writesc1, + (filer.ancestor = nil) and (shortcuts1 <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(shortcuts1,taction(filer.ancestor).shortcuts1))); +end; + +function taction.getactioninfopo: pactioninfoty; +begin + result:= @finfo; +end; + +procedure taction.actionchanged; +begin + changed; +end; + +function taction.shortcutseparator: msechar; +begin + result:= ' '; +end; + +procedure taction.calccaptiontext(var ainfo: actioninfoty); +begin + //dummy +end; + +{ tshortcutactions } + +constructor tshortcutactions.create(const aowner: tshortcutcontroller); +begin + inherited create(aowner,tshortcutaction); +end; + +class function tshortcutactions.getitemclasstype: persistentclassty; +begin + result:= tshortcutaction; +end; + +function tshortcutactions.getitems(const index: integer): tshortcutaction; +begin + result:= tshortcutaction(inherited getitems(index)); +end; + +{ tshortcutcontroller } + +constructor tshortcutcontroller.create(aowner: tcomponent); +begin + factions:= tshortcutactions.create(self); + fsysshortcuts:= tsysshortcuts.create(self,@mseactions.sysshortcuts); + fsysshortcuts1:= tsysshortcuts.create(self,@mseactions.sysshortcuts1); + fassistiveshortcuts:= tassistiveshortcuts.create(self, + @mseactions.assistiveshortcuts); + fassistiveshortcuts1:= tassistiveshortcuts.create(self, + @mseactions.assistiveshortcuts1); + inherited; +end; + +destructor tshortcutcontroller.destroy; +begin + inherited; + factions.free; + fsysshortcuts.free; + fsysshortcuts1.free; + fassistiveshortcuts.free; + fassistiveshortcuts1.free; +end; + +procedure tshortcutcontroller.setactions(const avalue: tshortcutactions); +begin + factions.assign(avalue); +end; + +procedure tshortcutcontroller.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tshortcutcontroller.setactionreccount(const acount: integer); +begin + fstatinfos:= nil; + setlength(fstatinfos,acount); +end; + +procedure tshortcutcontroller.setactionrecord(const index: integer; + const avalue: msestring); +var + ar1: msestringarty; + int1,int2: integer; +begin + ar1:= splitstring(avalue, msechar(' ')); + with fstatinfos[index] do begin + if high(ar1) >= 0 then begin + name:= ansistring(ar1[0]); + setlength(shortcut,high(ar1) div 2); + setlength(shortcut1,length(shortcut)); + //backward compatibilty with single shortcut + int2:= 1; + for int1:= 0 to high(shortcut) do begin + shortcut[int1]:= translateshortcut(strtoint(ar1[int2])); + inc(int2); + shortcut1[int1]:= translateshortcut(strtoint(ar1[int2])); + inc(int2); + end; + for int1:= 0 to high(shortcut) do begin + if shortcut[int1] = 0 then begin + setlength(shortcut,int1); + break; + end; + end; + for int1:= 0 to high(shortcut1) do begin + if shortcut1[int1] = 0 then begin + setlength(shortcut1,int1); + break; + end; + end; + end; + end; +end; + +procedure tshortcutcontroller.dostatread(const reader: tstatreader); +begin + if reader.candata then begin + fsysshortcuts.dostatread('sysshortcuts',reader); + fsysshortcuts1.dostatread('sysshortcuts1',reader); + fassistiveshortcuts.dostatread('assistiveshortcuts',reader); + fassistiveshortcuts1.dostatread('assistiveshortcuts1',reader); + reader.readrecordarray('shortcuts',{$ifdef FPC}@{$endif}setactionreccount, + {$ifdef FPC}@{$endif}setactionrecord); + end; +end; + +function tshortcutcontroller.getactionrecord(const index: integer): msestring; +var + int1,int2: integer; +begin + with tshortcutaction(factions[index]) do begin + if action <> nil then begin + result:= msestring(ownernamepath(action)); + with action do begin + int2:= high(shortcuts); + if high(shortcuts1) > int2 then begin + int2:= high(shortcuts1) + end; + for int1:= 0 to int2 do begin + if int1 <= high(shortcuts) then begin + result:= result + ' '+inttostrmse(shortcuts[int1]); + end + else begin + result:= result + ' 0'; + end; + if int1 <= high(shortcuts1) then begin + result:= result + ' '+inttostrmse(shortcuts1[int1]); + end + else begin + result:= result + ' 0'; + end; + end; + end; +// result:= encoderecord([ownernamepath(action),integer(action.shortcut), +// integer(action.shortcut1)]); + end + else begin + result:= ''; + end; + end; +end; + +procedure tshortcutcontroller.dostatwrite(const writer: tstatwriter); +begin + if writer.candata then begin + fsysshortcuts.dostatwrite('sysshortcuts',writer); + fsysshortcuts1.dostatwrite('sysshortcuts1',writer); + fassistiveshortcuts.dostatwrite('assistiveshortcuts',writer); + fassistiveshortcuts1.dostatwrite('assistiveshortcuts1',writer); + writer.writerecordarray('shortcuts',factions.count, + {$ifdef FPC}@{$endif}getactionrecord); + end; +end; + +procedure tshortcutcontroller.statreading; +begin + //dummy +end; + +procedure tshortcutcontroller.doafterupdate; +begin + if canevent(tmethod(fonafterupdate)) then begin + fonafterupdate(self); + end; +end; + +procedure tshortcutcontroller.statread; +var + int1: integer; +begin + for int1:= 0 to factions.count - 1 do begin + with factions[int1] do begin + if action <> nil then begin + updateaction(action); + end; + end; + end; + doafterupdate; +end; + +function tshortcutcontroller.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tshortcutcontroller.updateaction(const aaction: taction); +var + int1: integer; + str1: ansistring; +begin + str1:= ownernamepath(aaction); + for int1:= 0 to high(fstatinfos) do begin + with fstatinfos[int1] do begin + if str1 = name then begin + aaction.shortcuts:= shortcut; + aaction.shortcuts1:= shortcut1; + end; + end; + end; +end; + +procedure tshortcutcontroller.setsysshortcuts(const avalue: tsysshortcuts); +begin + fsysshortcuts.assign(avalue); +end; + +procedure tshortcutcontroller.setsysshortcuts1(const avalue: tsysshortcuts); +begin + fsysshortcuts1.assign(avalue); +end; + +procedure tshortcutcontroller.setassistiveshortcuts( + const avalue: tassistiveshortcuts); +begin + fassistiveshortcuts.assign(avalue); +end; + +procedure tshortcutcontroller.setassistiveshortcuts1( + const avalue: tassistiveshortcuts); +begin + fassistiveshortcuts1.assign(avalue); +end; + +function tshortcutcontroller.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tshortcutaction } + +procedure tshortcutaction.setaction(const avalue: taction); +begin + with tshortcutcontroller(fowner) do begin + setlinkedvar(avalue,tmsecomponent(faction)); + if (avalue <> nil) then begin + if csdesigning in componentstate then begin + shortcutsdefault:= avalue.shortcuts; + shortcuts1default:= avalue.shortcuts1; + end + else begin + updateaction(avalue); + end; + end; + end; +end; + +function tshortcutaction.getshortcutdefault: shortcutty; +begin + result:= getsimpleshortcut(finfo.shortcut); +end; + +procedure tshortcutaction.setshortcutdefault(const avalue: shortcutty); +begin + setsimpleshortcut(avalue,finfo.shortcut); +end; + +function tshortcutaction.getshortcut1default: shortcutty; +begin + result:= getsimpleshortcut(finfo.shortcut1); +end; + +procedure tshortcutaction.setshortcut1default(const avalue: shortcutty); +begin + setsimpleshortcut(avalue,finfo.shortcut1); +end; + +procedure tshortcutaction.readsc(reader: treader); +begin + finfo.shortcut:= readshortcutarty(reader); +end; + +procedure tshortcutaction.writesc(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut); +end; + +procedure tshortcutaction.readsc1(reader: treader); +begin + finfo.shortcut:= readshortcutarty(reader); +end; + +procedure tshortcutaction.writesc1(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut); +end; + +procedure tshortcutaction.readshortcut(reader: treader); +begin + shortcutdefault:= translateshortcut(reader.readinteger); +end; + +procedure tshortcutaction.readshortcut1(reader: treader); +begin + shortcut1default:= translateshortcut(reader.readinteger); +end; + +procedure tshortcutaction.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('shortcut',{$ifdef FPC}@{$endif}readshortcut,nil,false); + filer.defineproperty('shortcut1',{$ifdef FPC}@{$endif}readshortcut1,nil,false); + filer.defineproperty('sc',{$ifdef FPC}@{$endif}readsc, + {$ifdef FPC}@{$endif}writesc, + (filer.ancestor = nil) and (finfo.shortcut <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(finfo.shortcut, + tshortcutaction(filer.ancestor).shortcutsdefault))); + filer.defineproperty('sc1',{$ifdef FPC}@{$endif}readsc1, + {$ifdef FPC}@{$endif}writesc1, + (filer.ancestor = nil) and (finfo.shortcut1 <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(finfo.shortcut1, + tshortcutaction(filer.ancestor).shortcuts1default))); +end; + +procedure tshortcutaction.setshortcuts(const avalue: shortcutarty); +begin + finfo.shortcut:= avalue; +end; + +procedure tshortcutaction.setshortcuts1(const avalue: shortcutarty); +begin + finfo.shortcut1:= avalue; +end; + +function tshortcutaction.getactioninfopo: pactioninfoty; +begin + result:= @finfo; +end; + +procedure tshortcutaction.actionchanged; +begin + //dummy +end; + +function tshortcutaction.loading: boolean; +begin + result:= csloading in tcomponent(fowner).componentstate; +end; + +function tshortcutaction.shortcutseparator: msechar; +begin + result:= ' '; //not used +end; + +procedure tshortcutaction.calccaptiontext(var ainfo: actioninfoty); +begin + mseactions.calccaptiontext(ainfo,shortcutseparator); +end; + +{ tsysshortcuts } + +constructor tsysshortcuts.create(const aowner: tcomponent; + const adatapo: psysshortcutaty); +var + sc1: sysshortcutty; +begin + inherited create; + inherited setfixcount(ord(high(sysshortcutty))+1); + fowner:= aowner; + fdatapo:= adatapo; + for sc1:= low(sc1) to high(sc1) do begin + fitems[ord(sc1)]:= ord(fdatapo^[sc1]); //init with current values + end; +end; + +function tsysshortcuts.getitems(const index: sysshortcutty): shortcutty; +begin + result:= inherited getitems(ord(index)); +end; + +procedure tsysshortcuts.setitems(const index: sysshortcutty; + const avalue: shortcutty); +begin + inherited setitems(ord(index),ord(avalue)); +end; + +procedure tsysshortcuts.setfixcount(const avalue: integer); +begin + //dummy +end; + +procedure tsysshortcuts.dochange(const aindex: integer); +var + sc1: sysshortcutty; +begin + inherited; + if (fowner <> nil) and not (csdesigning in fowner.componentstate) then begin + if aindex < 0 then begin + for sc1:= low(sc1) to high(sc1) do begin + fdatapo^[sc1]:= fitems[ord(sc1)]; + end; + end + else begin + fdatapo^[sysshortcutty(aindex)]:= fitems[aindex]; + end; + end; +end; + +procedure tsysshortcuts.setshortcutcount(const acount: integer); +begin + setlength(fshortcuts,acount); +end; + +procedure tsysshortcuts.setshortcutrecord(const index: integer; + const avalue: msestring); +begin + with fshortcuts[index] do begin + decoderecord(avalue,[@name,@value],'si'); + end; +end; + +procedure tsysshortcuts.dostatread(const varname: msestring; + const reader: tstatreader); +var + int1,int2: integer; +begin + fshortcuts:= nil; + reader.readrecordarray(varname,{$ifdef FPC}@{$endif}setshortcutcount, + {$ifdef FPC}@{$endif}setshortcutrecord); + for int1:= 0 to high(fshortcuts) do begin + with fshortcuts[int1] do begin + value:= translateshortcut(value); + int2:= getenumvalue(typeinfo(sysshortcutty),name); + if int2 >= 0 then begin + items[sysshortcutty(int2)]:= value; + end; + end; + end; + fshortcuts:= nil; +end; + +function tsysshortcuts.getshortcutrecord(const index: integer): msestring; +begin + result:= encoderecord([getenumname(typeinfo(sysshortcutty),index),fitems[index]]); +end; + +procedure tsysshortcuts.dostatwrite(const varname: msestring; + const writer: tstatwriter); +begin + writer.writerecordarray(varname,count, + {$ifdef FPC}@{$endif}getshortcutrecord); +end; + +procedure tsysshortcuts.readitem(const index: integer; reader: treader); +begin + inherited; + fitems[index]:= translateshortcut(fitems[index]); +end; + +{ tassistiveshortcuts } + +constructor tassistiveshortcuts.create(const aowner: tcomponent; + const adatapo: passistiveshortcutaty); +var + sc1: assistiveshortcutty; +begin + inherited create; + inherited setfixcount(ord(high(assistiveshortcutty))+1); + fowner:= aowner; + fdatapo:= adatapo; + for sc1:= low(sc1) to high(sc1) do begin + shortcutarty(fitems[ord(sc1)]):= fdatapo^[sc1]; //init with current values + end; +end; + +function tassistiveshortcuts.getitems( + const index: assistiveshortcutty): shortcutarty; +begin + result:= shortcutarty(inherited getitems(ord(index))); +end; + +procedure tassistiveshortcuts.setitems(const index: assistiveshortcutty; + const avalue: shortcutarty); +begin + checkindex(ord(index)); + shortcutarty(fitems[ord(index)]):= avalue; + change(ord(index)); +end; + +procedure tassistiveshortcuts.setfixcount(const avalue: integer); +begin + //dummy +end; + +procedure tassistiveshortcuts.dochange(const aindex: integer); +var + sc1: assistiveshortcutty; +begin + inherited; + if (fowner <> nil) and not (csdesigning in fowner.componentstate) then begin + if aindex < 0 then begin + for sc1:= low(sc1) to high(sc1) do begin + fdatapo^[sc1]:= shortcutarty(fitems[ord(sc1)]); + end; + end + else begin + fdatapo^[assistiveshortcutty(aindex)]:= shortcutarty(fitems[aindex]); + end; + end; +end; + +procedure tassistiveshortcuts.setshortcutcount(const acount: integer); +begin + setlength(fshortcuts,acount); +end; + +procedure tassistiveshortcuts.setshortcutrecord(const index: integer; + const avalue: msestring); +var + s1: string; + ar1: stringarty; + ar2: shortcutarty; + c1: card32; + i1: int32; +begin + with fshortcuts[index] do begin + decoderecord(avalue,[@name,@s1],'ss'); + value:= nil; + ar1:= splitstring(s1,' '); + setlength(ar2,length(ar1)); + for i1:= 0 to high(ar1) do begin + if not trystrtohex(ar1[i1],c1) then begin + exit; + end; + ar2[i1]:= c1; + end; + value:= ar2; + end; +end; + +procedure tassistiveshortcuts.internalsetcount(const acount: int32); +begin + setlength(int16ararty(fitems),acount); +end; + +procedure tassistiveshortcuts.dostatread(const varname: msestring; + const reader: tstatreader); +var + int1,int2: integer; +begin + fshortcuts:= nil; + reader.readrecordarray(varname,@setshortcutcount,@setshortcutrecord); + for int1:= 0 to high(fshortcuts) do begin + with fshortcuts[int1] do begin +// value:= translateshortcut(value); + int2:= getenumvalue(typeinfo(assistiveshortcutty),name); + if int2 >= 0 then begin + items[assistiveshortcutty(int2)]:= value; + end; + end; + end; + fshortcuts:= nil; +end; + +function tassistiveshortcuts.getshortcutrecord(const index: integer): msestring; +var + s1: string; + i1: int32; + ar1: shortcutarty; +begin + ar1:= shortcutarty(fitems[index]); + s1:= ''; + for i1:= 0 to high(ar1) do begin + s1:= s1+hextostr(ar1[i1],4); + if i1 <> high(ar1) then begin + s1:= s1+' '; + end; + end; + result:= encoderecord([getenumname(typeinfo(assistiveshortcutty),index),s1]); +end; + +procedure tassistiveshortcuts.dostatwrite(const varname: msestring; + const writer: tstatwriter); +begin + writer.writerecordarray(varname,count,@getshortcutrecord); +end; + +procedure tassistiveshortcuts.writeitem(const index: integer; writer: twriter); +begin + writeintar(writer,int16arty(fitems[index])); +end; + +procedure tassistiveshortcuts.readitem(const index: integer; reader: treader); +var + ar1: int16arty; +begin + readintar(reader,ar1); + int16arty(fitems[index]):= ar1; +// inherited; +// fitems[index]:= translateshortcut(fitems[index]); +end; + +{ tcustomhelpcontroller } + +constructor tcustomhelpcontroller.create(aowner: tcomponent); +begin + inherited; + if not (csdesigning in componentstate) then begin + application.registerhelphandler({$ifdef FPC}@{$endif}dohelp); + end; +end; + +destructor tcustomhelpcontroller.destroy; +begin + if not (csdesigning in componentstate) then begin + application.unregisterhelphandler({$ifdef FPC}@{$endif}dohelp); + fshortcut:= 0; + fshortcut1:= 0; + checkshortcuts(); //unregister + end; + inherited; +end; + +procedure tcustomhelpcontroller.setshortcut(const avalue: shortcutty); +begin + if avalue <> fshortcut then begin + fshortcut:= avalue; + checkshortcuts(); + end; +end; + +procedure tcustomhelpcontroller.setshortcut1(const avalue: shortcutty); +begin + if avalue <> fshortcut1 then begin + fshortcut1:= avalue; + checkshortcuts(); + end; +end; + +procedure tcustomhelpcontroller.checkshortcuts(); +begin + if not (csdesigning in componentstate) and + (fshortcutregistered xor + ((fshortcut <> 0) or (fshortcut1 <> 0))) then begin + if fshortcutregistered then begin + application.unregisteronshortcut(@doshortcut); + fshortcutregistered:= false; + end + else begin + application.registeronshortcut(@doshortcut); + fshortcutregistered:= true; + end; + end; +end; + +procedure tcustomhelpcontroller.dohelp(const sender: tmsecomponent; + var handled: boolean); +begin + if not handled and canevent(tmethod(fonhelp)) then begin + fonhelp(self,sender,handled); + end; + if not handled and assigned(fonhelp1) then begin + fonhelp1(self,sender,handled); + end; +end; + +procedure tcustomhelpcontroller.doshortcut(const sender: twidget; + var keyinfo: keyeventinfoty); +begin + if not (es_processed in keyinfo.eventstate) and + not (ss_repeat in keyinfo.shiftstate) and + (checkshortcutcode(fshortcut,keyinfo) or + checkshortcutcode(fshortcut1,keyinfo)) then begin + include(keyinfo.eventstate,es_processed); + application.help(sender); + end; +end; + +procedure doinit(); + + procedure setdefault(const source: assistiveshortcutconstty; + out dest: assistiveshortcutaty); + var + i1: int32; + sh1: assistiveshortcutty; + begin + for sh1:= low(sh1) to high(sh1) do begin + dest[sh1]:= nil; + for i1:= 0 to high(source[low(sh1)]) do begin + if source[sh1][i1] = 0 then begin + break; + end; + additem(int16arty(dest[sh1]),int16(source[sh1][i1])); + end; + end; + end; //setdefault + +begin + sysshortcuts:= defaultsysshortcuts; + sysshortcuts1:= defaultsysshortcuts1; + setdefault(defaultassistiveshortcuts,assistiveshortcuts); + setdefault(defaultassistiveshortcuts1,assistiveshortcuts1); + assistiveexechandler:= @handleassistiveexec; +end; + +initialization + doinit(); +end. diff --git a/mseide-msegui/lib/common/kernel/mseapplication.pas b/mseide-msegui/lib/common/kernel/mseapplication.pas new file mode 100644 index 0000000..d2a931d --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseapplication.pas @@ -0,0 +1,2147 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseapplication; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +{$ifdef mse_debuglock} + {$define mse_debugmutex} +{$endif} +{$ifdef mse_debuggdisync} + {$define mse_debugmutex} +{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,mseevent,mseglob,sysutils,msetypes,mselist, + msethread,msesystypes,msesys,{msethreadcomp,}msestrings,mseinterfaces + {$ifdef mse_with_ifi},mseifiglob{$endif}; + +type + activatoroptionty = (avo_activateonloaded,avo_activatedelayed, + avo_deactivateonterminated,avo_deactivatebottomup, + avo_handleexceptions,avo_quietexceptions, + avo_abortonexception,avo_waitcursor); + activatoroptionsty = set of activatoroptionty; + activatorabortactionty = (aaa_abortexception,aaa_abort,aaa_deactivate, + aaa_retry); + +const + defaultactivatoroptions = [avo_handleexceptions,avo_quietexceptions]; + +type + iactivator = interface(inullinterface) + end; + iactivatorclient = interface(inullinterface)[miid_iactivatorclient] + procedure setactive(const avalue: boolean); + end; + + tactivator = class; + + activateerroreventty = procedure(const sender: tactivator; + const aclient: tobject; const aexception: exception; + var handled: boolean) of object; + + actcomponentstatety = (acs_releasing,acs_dooncreatecalled); + actcomponentstatesty = set of actcomponentstatety; + + tactcomponent = class(tmsecomponent,iactivatorclient) + private + factivator: tactivator; + procedure setactivator(const avalue: tactivator); + protected + factstate: actcomponentstatesty; + fdesignchangedlock: integer; + procedure designchanged(const apropname: string = ''; + const apropindex: int32 = -1); //for designer notify + procedure loaded; override; + procedure doactivated; virtual; + procedure dodeactivated; virtual; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure receiveevent(const event: tobjectevent); override; + {$ifdef mse_with_ifi} + procedure executeificommand(var acommand: ificommandcodety); override; + {$endif} + //iactivatorclient + procedure setactive(const avalue: boolean); virtual; + public + procedure release(const nomodaldefer: boolean=false); virtual; + function releasing: boolean; + procedure deactivate(const achildren: boolean = true); virtual; + property activator: tactivator read factivator write setactivator; + end; + pactcomponent = ^tactcomponent; + + applicationeventeventty = procedure(const sender: tactcomponent; + var aevent: tmseevent; var handled: boolean) of object; + + activatoraborteventty = procedure(const sender: tactivator; + var aaction: activatorabortactionty) of object; + tactivator = class(tactcomponent) + private + foptions: activatoroptionsty; + fonbeforeactivate: notifyeventty; + fonafteractivate: notifyeventty; + fonbeforedeactivate: notifyeventty; + fonafterdeactivate: notifyeventty; + factive: boolean; + factivated: boolean; + factivecount: integer; + fonactivateerror: activateerroreventty; + fonabort: activatoraborteventty; + fabortaction: activatorabortactionty; + procedure readclientnames(reader: treader); + procedure writeclientnames(writer: twriter); + function getclients: integer; + procedure setclients(const avalue: integer); + procedure setoptions(const avalue: activatoroptionsty); + function getclientinstances(const index: integer): tobject; + function getclientinterfaces(const index: integer): iobjectlink; + protected + fclientnames: stringarty; + fclients: pointerarty; + procedure setactive(const avalue: boolean); override; + procedure registerclient(const aclient: iobjectlink); + procedure unregisterclient(const aclient: iobjectlink); + procedure updateorder; + function getclientnames: stringarty; + procedure defineproperties(filer: tfiler); override; + procedure doasyncevent(var atag: integer); override; + procedure loaded; override; + procedure unlink(const source,dest: iobjectlink; + valuepo: pointer = nil); override; + procedure objevent(const sender: iobjectlink; + const event: objecteventty); override; + procedure doterminated(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + class procedure addclient(const aactivator: tactivator; + const aclient: iobjectlink; var dest: tactivator); + procedure activaterecursive; //increments activecount + procedure deactivaterecursive; //decrements activecount + procedure activateclients; + procedure deactivateclients; + property activated: boolean read factivated; + property activecount: integer read factivecount; + property clientinstances[const index: integer]: tobject + read getclientinstances; + property clientinterfaces[const index: integer]: iobjectlink + read getclientinterfaces; + property clientcount: integer read getclients; + published + property clients: integer read getclients write setclients; + //hook for object inspector + property options: activatoroptionsty read foptions write setoptions + default defaultactivatoroptions; + property active: boolean read factive write setactive default false; + property abortaction: activatorabortactionty read fabortaction + write fabortaction default aaa_abortexception; + property onbeforeactivate: notifyeventty read fonbeforeactivate + write fonbeforeactivate; + property onactivateerror: activateerroreventty read fonactivateerror + write fonactivateerror; + property onabort: activatoraborteventty read fonabort write fonabort; + property onafteractivate: notifyeventty read fonafteractivate + write fonafteractivate; + property onbeforedeactivate: notifyeventty read fonbeforedeactivate + write fonbeforedeactivate; + property onafterdeactivate: notifyeventty read fonafterdeactivate + write fonafterdeactivate; + property activator; + end; + + tactivatorcontroller = class(tlinkedpersistent) + private + factive: boolean; + floaded: boolean; + factivator: tactivator; + procedure setactivator(const avalue: tactivator); + protected + fowner: tcomponent; + fintf: iactivatorclient; + function getinstance: tobject; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure setowneractive(const avalue: boolean); virtual; abstract; + public + constructor create(const aowner: tcomponent; const aintf: iactivatorclient); reintroduce; + function setactive (const value : boolean): boolean; + procedure loaded; + published + property activator: tactivator read factivator write setactivator; + end; + + exceptioneventty = procedure (const sender: tobject; const e: exception; + const leadingtext: msestring; var handled: boolean) of object; + + terminatequeryeventty = procedure (var terminate: boolean) of object; + idleeventty = procedure (var again: boolean) of object; + + tonterminatequerylist = class(tmethodlist) + protected + public + function doterminatequery: boolean; + //true if accepted + end; + + tonidlelist = class(tmethodlist) + protected + public + function doidle: boolean; //true if again requested + public + end; + + applicationstatety = + (aps_inited,aps_running,aps_terminated,aps_mousecaptured, + aps_invalidated,aps_zordervalid,aps_needsupdatewindowstack, + aps_focused,aps_activewindowchecked,aps_restorelocktransientfor, + aps_exitloop,aps_cancelloop,aps_looplocked, + aps_active,aps_waiting,aps_woken, + aps_terminating,aps_deinitializing, + aps_shortcutting,aps_clearkeyhistory, + aps_waitstarted,aps_waitcanceled,aps_waitterminated,aps_waitok, + aps_waitidlelock,aps_eventflushing,aps_processmessages); + applicationstatesty = set of applicationstatety; + + synchronizeprocty = procedure(const adata: pointer); + synchronizeeventty = procedure(const adata: pointer) of object; + + teventlist = class(tobjectqueue) + protected + procedure finalizeitem(var item: pointer); override; + end; + + applicationeventhandlereventty = procedure(var aevent: tmseevent; + var handled: boolean) of object; + + tonapplicationeventlist = class(tmethodlist) + public + procedure doevent(var aevent: tmseevent; var handled: boolean); + end; + + applicationoptionty = (apo_terminateonexception,apo_noautodestroymodules); + applicationoptionsty = set of applicationoptionty; + + tcustomapplication = class(tmsecomponent) + private + fapplicationname: filenamety; + flockthread: threadty; + fmutex: mutexty; + feventlist: teventlist; + feventlock: mutexty; + fpostedevents: eventarty; + fpostedeventslocal: eventarty; + fidlecount: integer; + fcheckoverloadlock: integer; + fexceptioncount: integer; + fonexception: exceptioneventty; + finiting: integer; + fhighrestimercount: integer; + function dolock: boolean; + function internalunlock(count: integer): boolean; + function getterminated: boolean; + procedure setterminated(const Value: boolean); + function gethighrestimer: boolean; + protected + flockcount: integer; + foptions: applicationoptionsty; + fthread: threadty; + fstate: applicationstatesty; + fwaitcount: integer; + fserial: card32; + fnoignorewaitevents: integer; + fonterminatedlist: tnotifylist; + fonterminatequerylist: tonterminatequerylist; + fonidlelist: tonidlelist; + fonapplicationeventlist: tonapplicationeventlist; + ftimertriggercount: integer; + procedure receiveevent(const event: tobjectevent); override; + procedure flusheventbuffer; + procedure doidle; + procedure sethighrestimer(const avalue: boolean); virtual; abstract; + procedure dopostevent(const aevent: tmseevent); virtual; abstract; + function getevents: integer; virtual; abstract; + //application must be locked + //returns count of queued events + procedure doeventloop(const once: boolean); virtual; abstract; + procedure incidlecount; + procedure dobeforerun; virtual; + procedure doafterrun; virtual; + procedure dowakeup(sender: tobject); + property eventlist: teventlist read feventlist; + procedure internalinitialize; virtual; + procedure internaldeinitialize; virtual; + procedure objecteventdestroyed(const sender: tobjectevent); virtual; + procedure resettimertrigger; + public + {$ifdef mse_debugmutex} + function getmutexaddr: pointer; + function getmutexcount: integer; + procedure checklockcount; + {$endif} + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure beforedestruction() override; + procedure initialize; + procedure deinitialize; + procedure beginhighrestimer; + procedure endhighrestimer; + property highrestimer: boolean read gethighrestimer; + + function procid: procidty; + function getserial(): card32; + function createdatamodule(instanceclass: msecomponentclassty; + var reference): tmsecomponent; + procedure run; + function running: boolean; //true if eventloop entered + procedure processmessages; virtual; //handle with care! + function idle: boolean; virtual; + function modallevel: integer; virtual; abstract; //-1 invalid, + //0 single loop stack + property applicationname: msestring read fapplicationname + write fapplicationname; + + procedure postevent(event: tmseevent; + const aoptions: posteventoptionsty = []); + //peo_local -> direcly to the internal queue + //peo_first implies peo_local + //peo_modaldefer -> deliver in current modallevel + function checkoverload(const asleepus: integer = 100000): boolean; + //true if never idle since last call, + // unlocks application and calls sleep if not mainthread and asleepus >= 0 + procedure handleexception(sender: tobject = nil; + const leadingtext: msestring = ''); + procedure showexception(e: exception; const leadingtext: msestring = ''); + virtual; abstract; + procedure errormessage(const amessage: msestring); virtual; abstract; + procedure registeronterminated(const method: notifyeventty); + procedure unregisteronterminated(const method: notifyeventty); + procedure registeronterminate(const method: terminatequeryeventty); + procedure unregisteronterminate(const method: terminatequeryeventty); + procedure registeronidle(const method: idleeventty); + procedure unregisteronidle(const method: idleeventty); + procedure registerapplicationeventhandler( + const method: applicationeventhandlereventty); + procedure unregisterapplicationeventhandler( + const method: applicationeventhandlereventty); + + procedure settimer(const us: integer); virtual; + + function islockedthread: boolean; //true if calling thread holds the lock + function islockedmainthread: boolean; + //true if calling thread holds the lock and is mainthread + function trylock: boolean; + function lock: boolean; + //synchronizes calling thread with main event loop (mutex), + //false if calling thread allready holds the mutex + //mutex is recursive + function unlock: boolean; + //release mutex if calling thread holds the mutex, + //false if no unlock done + function unlockall: integer virtual; + //release mutex recursive if calling thread holds the mutex, + //returns count for relockall + procedure relockall(count: integer) virtual; + procedure lockifnotmainthread; + procedure unlockifnotmainthread; + + function synchronize(const proc: proceventty; const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; + function synchronize(const proc: synchronizeeventty; const data: pointer; + const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; + function synchronize(const proc: synchronizeprocty; const data: pointer; + const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; + //true if not aborted, quiet -> show no exceptions + + procedure queueasynccall(const proc: proceventty; + const aoptions: posteventoptionsty = []); + procedure queueasynccall(const proc: synchronizeeventty; const data: pointer; + const aoptions: posteventoptionsty = []); + procedure queueasynccall(const proc: synchronizeprocty; const data: pointer; + const aoptions: posteventoptionsty = []); + + procedure releaseobject(const aobject: tobject); + function ismainthread: boolean; + function islockthread: boolean; + procedure waitforthread(athread: tmsethread); + //does unlock-relock for waiting + function semwait(var sem: semty; timeoutusec: integer): syserrorty; + //does unlock-relock for waiting + //timeoutusec <= 0 -> no timeout + //sye_ok -> semaphore signaled + //sye_timeout -> timeout + //sye_semaphore -> error + procedure wakeupmainthread; + procedure langchanged; virtual; + procedure beginwait(const aprocessmessages: boolean = false); virtual; + procedure endwait; virtual; + function waitescaped: boolean; virtual; + procedure idlesleep(const asleepus: integer); + //calls unlockall-relockall + function candefocus(const caller: tobject=nil): boolean; virtual; + property terminated: boolean read getterminated write setterminated; + //thread safe + property mainthread: threadty read fthread; + property lockthread: threadty read flockthread; + property lockcount: integer read flockcount; + property exceptioncount: integer read fexceptioncount; + property options: applicationoptionsty read foptions write foptions; + property onexception: exceptioneventty read fonexception write fonexception; + end; + applicationclassty = class of tcustomapplication; + +function application: tcustomapplication; +function applicationallocated: boolean; +function applicationdestroyed: boolean; + +procedure registerapplicationclass(const aclass: applicationclassty); + +procedure freedesigncomponent(const acomponent: tcomponent); +procedure designvalidaterename(const acomponent: tcomponent; + const curname, newname: string); +procedure handlesigchld; + + //helper functions for component extenders +procedure updateclientorder(var fclientnames: stringarty; + var fclients: pointerarty; + const getclientnames: getstringareventty); +function getclientname(const avalue: tobject; + const aindex: integer): string; +procedure designchanged(const acomponent: tcomponent); //for designer notify + +type + validaterenameeventty = procedure(const acomponent: tcomponent; + const curname, newname: string) of object; + propertynotifyeventty = procedure(const sender: tobject; + const propname: string; const itemindex: int32) of object; +var + onhandlesigchld: procedure; + //designer hooks + ondesignchanged: propertynotifyeventty; + onfreedesigncomponent: componenteventty; + ondesignvalidaterename: validaterenameeventty; + ondesignexception: notifyeventty; + +procedure releaseandnil(var acomponent: tactcomponent); + +implementation +uses + msebits,msesysintf1,msesysintf,msesysutils,msefileutils,msedatalist, + msearrayutils{$ifndef FPC},classes_del{$endif} + {$ifdef mse_debuggdisync},msegraphics{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tobjectevent1 = class(tobjectevent); + + tasyncqueueevent = class(texecuteevent) + end; + + tappasyncevent = class(tasyncqueueevent) + private + fproc: proceventty; + protected + procedure execute(); override; + public + constructor create(const aproc: proceventty); + end; + + tappasyncdataevent = class(tasyncqueueevent) + private + fproc: synchronizeeventty; + fdata: pointer; + protected + procedure execute(); override; + public + constructor create(const aproc: synchronizeeventty; const adata: pointer); + end; + + tappasyncprocevent = class(tasyncqueueevent) + private + fproc: synchronizeprocty; + fdata: pointer; + protected + procedure execute(); override; + public + constructor create(const aproc: synchronizeprocty; const adata: pointer); + end; + + tappsynchronizeevent = class(tsynchronizeevent) + private + fproc: proceventty; + protected + procedure execute; override; + public + constructor create(const aproc: proceventty; const aquiet: boolean); + end; + + tappsynchronizedataevent = class(tsynchronizeevent) + private + fproc: synchronizeeventty; + fdata: pointer; + protected + procedure execute; override; + public + constructor create(const aproc: synchronizeeventty; const adata: pointer; + const aquiet: boolean); + end; + + tappsynchronizeprocevent = class(tsynchronizeevent) + private + fproc: synchronizeprocty; + fdata: pointer; + protected + procedure execute; override; + public + constructor create(const aproc: synchronizeprocty; const adata: pointer; + const aquiet: boolean); + end; + + treleaseevent = class(tobjectevent) + private + fobject: tobject; + public + constructor create(const dest: ievent; const aobject: tobject); + end; + +var + appinst: tcustomapplication; + appclass: applicationclassty; + fapplicationdestroyed: boolean; + +threadvar + exceptionactive: integer; + +procedure releaseandnil(var acomponent: tactcomponent); +begin + if acomponent <> nil then begin + acomponent.release; + acomponent:= nil; + end; +end; + + +procedure designchanged(const acomponent: tcomponent); //for designer notify +begin + if assigned(ondesignchanged) and + (acomponent.componentstate*[csdesigning,csloading,csdestroying] = + [csdesigning]) then begin + ondesignchanged(acomponent,'',-1); + end; +end; + +function getclientname(const avalue: tobject; + const aindex: integer): string; +begin + if avalue is tcomponent then begin + result:= ownernamepath(tcomponent(avalue)); + { + with tcomponent(avalue) do begin + if owner <> nil then begin + if not (csdesigning in componentstate) or + ((owner.owner <> nil) and (owner.owner.owner = nil)) then begin + result:= owner.name+'.'+name; + end + else begin + result:= name; + end; + end + else begin + result:= ''; + end; + end; + } + end + else begin + result:= inttostr(aindex)+'<'+avalue.classname+'>'; + end; +end; + +procedure updateclientorder(var fclientnames: stringarty; + var fclients: pointerarty; + const getclientnames: getstringareventty); +var + int1,int2: integer; + ar1: stringarty; + ar2,ar3: integerarty; +begin + ar1:= nil; //compilerwarning + if fclientnames <> nil then begin + ar1:= getclientnames(); + setlength(ar2,length(ar1)); + for int1:= 0 to high(fclientnames) do begin + for int2:= 0 to high(ar1) do begin + if ar1[int2] = fclientnames[int1] then begin + ar2[int2]:= int1-bigint; //not found items last + ar1[int2]:= ''; + end; + end; + end; + sortarray(ar2,ar3); + orderarray(ar3,fclients); + end; +end; + +procedure handlesigchld; +begin + if assigned(onhandlesigchld) then begin + onhandlesigchld; + end; +end; + +procedure freedesigncomponent(const acomponent: tcomponent); +begin + if assigned(onfreedesigncomponent) then begin + onfreedesigncomponent(acomponent); + end + else begin + acomponent.free; + end; +end; + +procedure designvalidaterename(const acomponent: tcomponent; + const curname, newname: string); +begin + if assigned(ondesignvalidaterename) then begin + ondesignvalidaterename(acomponent,curname,newname); + end; +end; + +function application: tcustomapplication; +begin + if appinst = nil then begin + if appclass = nil then begin + raise exception.create('No application class registered.'); + end; + appclass.create(nil); + end; + result:= appinst; +end; + +function applicationallocated: boolean; +begin + result:= appinst <> nil; +end; + +function applicationdestroyed: boolean; +begin + result:= fapplicationdestroyed; +end; + +procedure registerapplicationclass(const aclass: applicationclassty); +begin + if appclass <> nil then begin + raise exception.create('Application class already registered.'); + end; + appclass:= aclass; +end; + +{ tactcomponent } + +procedure tactcomponent.designchanged(const apropname: string = ''; + const apropindex: int32 = -1); //for designer notify +begin + if assigned(ondesignchanged) and (fdesignchangedlock = 0) and + (componentstate*[csdesigning,csloading] = [csdesigning]) then begin + ondesignchanged(self,apropname,apropindex); + end; +end; + +procedure tactcomponent.setactivator(const avalue: tactivator); +begin + tactivator.addclient(avalue,ievent(self),factivator); +end; + +procedure tactcomponent.loaded; +begin + inherited; + if (factivator <> nil) and factivator.activated then begin + doactivated; + end; +end; + +procedure tactcomponent.doactivated; +begin + //dummy; +end; + +procedure tactcomponent.dodeactivated; +begin + //dummy; +end; + +procedure tactcomponent.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = factivator) then begin + case event of + oe_activate: begin + doactivated; + end; + oe_deactivate: begin + dodeactivated; + end; + end; + end; +end; + +procedure tactcomponent.release(const nomodaldefer: boolean = false); +begin + if not (acs_releasing in factstate) and + not (csdestroying in componentstate) then begin + appinst.postevent(tobjectevent.create(ek_release,ievent(self), + not nomodaldefer)); + { + if nomodaldefer then begin + appinst.postevent(tobjectevent.create(ek_release,ievent(self))); + end + else begin + appinst.postevent(tobjectevent.create(ek_releasedefer,ievent(self))); + end; + } + include(factstate,acs_releasing); + end; +end; + +function tactcomponent.releasing: boolean; +begin + result:= acs_releasing in factstate; +end; + +procedure tactcomponent.receiveevent(const event: tobjectevent); +begin + inherited; + case event.kind of + ek_release: begin + free; + end; + end; +end; + +procedure tactcomponent.setactive(const avalue: boolean); +begin + //dummy +end; + +procedure tactcomponent.deactivate(const achildren: boolean = true); + procedure deactivateall(const acomp: tcomponent); + var + intf1: iactivatorclient; + int1: integer; + begin + if mseclasses.getcorbainterface(acomp, + typeinfo(iactivatorclient),intf1) then begin + intf1.setactive(false); + end; + with acomp do begin + int1:= componentcount - 1; + while int1 >= 0 do begin + if int1 >= componentcount then begin + int1:= componentcount - 1; + end; + deactivateall(components[int1]); + dec(int1); + end; + end; + end; +begin + if achildren then begin + deactivateall(self); + end; + setactive(false); +end; + +{$ifdef mse_with_ifi} +procedure tactcomponent.executeificommand(var acommand: ificommandcodety); +begin + inherited; + case acommand of + icc_release: begin + release; + end; + end; +end; + +{$endif} + +{ tactivator } + +constructor tactivator.create(aowner: tcomponent); +begin + foptions:= defaultactivatoroptions; + inherited; + application.registeronterminated({$ifdef FPC}@{$endif}doterminated); +end; + +destructor tactivator.destroy; +begin + application.unregisteronterminated({$ifdef FPC}@{$endif}doterminated); + inherited; +end; + +class procedure tactivator.addclient(const aactivator: tactivator; + const aclient: iobjectlink; var dest: tactivator); +var + act1: tactivator; +begin + if dest <> nil then begin + dest.unregisterclient(aclient); + end; + if aactivator <> nil then begin + act1:= tactivator(aclient.getinstance); + if act1 is tactivator then begin + repeat + if act1 = aactivator then begin + raise exception.create('Circular reference.'); + end; + act1:= act1.activator; + until act1 = nil; + end; + aclient.link(aclient,ievent(aactivator),@dest); + aactivator.registerclient(aclient); + end; + dest:= aactivator; +end; + +procedure tactivator.registerclient(const aclient: iobjectlink); +begin + additem(fclients,pointer(aclient)); +end; + +procedure tactivator.unregisterclient(const aclient: iobjectlink); +begin + removeitem(fclients,pointer(aclient)); +end; + +procedure tactivator.updateorder; +begin + updateclientorder(fclientnames,fclients,{$ifdef FPC}@{$endif}getclientnames); +end; +{ +procedure tactivator.updateorder; +var + int1,int2: integer; + ar1: stringarty; + ar2,ar3: integerarty; +begin + ar1:= nil; //compilerwarning + if fclientnames <> nil then begin + ar1:= getclientnames; + setlength(ar2,length(ar1)); + for int1:= 0 to high(fclientnames) do begin + for int2:= 0 to high(ar1) do begin + if ar1[int2] = fclientnames[int1] then begin + ar2[int2]:= int1-bigint; //not found items last + ar1[int2]:= ''; + end; + end; + end; + sortarray(ar2,ar3); + orderarray(ar3,fclients); + end; +end; +} +procedure tactivator.doasyncevent(var atag: integer); +begin + activateclients; +end; + +procedure tactivator.loaded; +begin + inherited; + if not (csdesigning in componentstate) or factive then begin + if avo_activateonloaded in foptions then begin + if csdesigning in componentstate then begin + try + activateclients; + except + application.handleexception(self); + factivated:= false; //do not activate in clients.loaded + end; + end + else begin + activateclients; + end; + end; + if avo_activatedelayed in foptions then begin + asyncevent; + end; + end; +end; + +procedure tactivator.doterminated(const sender: tobject); +begin + if avo_deactivateonterminated in foptions then begin + deactivateclients; + end; +end; + +{ +function tactivator.getclientname(const avalue: tobject; + const aindex: integer): string; +begin + if avalue is tcomponent then begin + with tcomponent(avalue) do begin + if owner <> nil then begin + if not (csdesigning in componentstate) or + ((owner.owner <> nil) and (owner.owner.owner = nil)) then begin + result:= owner.name+'.'+name; + end + else begin + result:= name; + end; + end + else begin + result:= ''; + end; + end; + end + else begin + result:= inttostr(aindex)+'<'+avalue.classname+'>'; + end; +end; +} +function tactivator.getclientnames: stringarty; +var + int1: integer; +begin + setlength(result,length(fclients)); + for int1:= 0 to high(result) do begin + result[int1]:= getclientname(iobjectlink(fclients[int1]).getinstance,int1); + end; +end; + +procedure tactivator.readclientnames(reader: treader); +begin + readstringar(reader,fclientnames); +end; + +procedure tactivator.writeclientnames(writer: twriter); +begin + writestringar(writer,getclientnames); +end; + +procedure tactivator.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('clientnames',{$ifdef FPC}@{$endif}readclientnames, + {$ifdef FPC}@{$endif}writeclientnames,high(fclients) >= 0); +end; + +procedure tactivator.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + inherited; + if (event = oe_activate) and (sender.getinstance = activator) then begin + activateclients; + end; +end; + +procedure tactivator.unlink(const source,dest: iobjectlink; + valuepo: pointer = nil); +begin + removeitem(fclients,pointer(dest)); + inherited; +end; + +function tactivator.getclients: integer; +begin + result:= length(fclients); +end; + +procedure tactivator.setclients(const avalue: integer); +begin + // dummy; +end; + +procedure tactivator.activateclients; +var + int1: integer; + bo1,bo2: boolean; + act1: activatorabortactionty; +begin + try + if avo_waitcursor in foptions then begin + application.beginwait; + end; + factive:= true; + factivated:= true; + if canevent(tmethod(fonbeforeactivate)) then begin + fonbeforeactivate(self); + end; + if factive then begin + updateorder; + bo2:= canevent(tmethod(fonactivateerror)); + for int1:= 0 to high(fclients) do begin + try + iobjectlink(fclients[int1]).objevent(ievent(self),oe_activate); + except + on e: exception do begin + bo1:= false; + if bo2 then begin + fonactivateerror(self,iobjectlink(fclients[int1]).getinstance,e,bo1); + end; + if not bo1 then begin + if (avo_handleexceptions in foptions) and + not (csdesigning in componentstate) then begin + if not (avo_quietexceptions in foptions) then begin + application.showexception(e); + end; + end + else begin + // factive:= false; + raise; + end; + end; + if avo_abortonexception in foptions then begin + act1:= fabortaction; + if canevent(tmethod(fonabort)) then begin + fonabort(self,act1); + end; + factivated:= false; //no activation in clients.loaded + case act1 of + aaa_retry,aaa_deactivate: begin + deactivateclients; + if act1 = aaa_retry then begin + activateclients; + end; + exit; + end; + aaa_abortexception: begin + abort; + end; + end; + break; + end; + end; + end; + end; + if canevent(tmethod(fonafteractivate)) then begin + fonafteractivate(self); + end; + end; + finally + if avo_waitcursor in foptions then begin + application.endwait; + end; + end; +end; + +procedure tactivator.deactivateclients; +var + int1: integer; +begin + factive:= false; + factivecount:= 0; + if canevent(tmethod(fonbeforedeactivate)) then begin + fonbeforedeactivate(self); + end; + if not active then begin + updateorder; + if avo_deactivatebottomup in foptions then begin + for int1:= 0 to high(fclients) do begin + iobjectlink(fclients[int1]).objevent(ievent(self),oe_deactivate); + end; + end + else begin + for int1:= high(fclients) downto 0 do begin + iobjectlink(fclients[int1]).objevent(ievent(self),oe_deactivate); + end; + end; + if canevent(tmethod(fonafterdeactivate)) then begin + fonafterdeactivate(self); + end; + end; +end; + +procedure tactivator.setactive(const avalue: boolean); +begin + if avalue <> factive then begin + if componentstate * [csloading,csdesigning] = [csloading,csdesigning] then begin + factive:= avalue; + end + else begin + if not (csloading in componentstate) then begin + if avalue then begin + activateclients; + end + else begin + deactivateclients; + end; + end; + end; + end; +end; + +procedure tactivator.setoptions(const avalue: activatoroptionsty); +const + mask: activatoroptionsty = [avo_activateonloaded,avo_activatedelayed]; +begin + foptions:= activatoroptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); +end; + +procedure tactivator.activaterecursive; +begin + inc(factivecount); + active:= true; +end; + +procedure tactivator.deactivaterecursive; +begin + dec(factivecount); + if factivecount < 0 then begin + factivecount:= 0; + end; + if factivecount = 0 then begin + active:= false; + end; +end; + +function tactivator.getclientinstances(const index: integer): tobject; +var + intf1: iobjectlink; +begin + intf1:= getclientinterfaces(index); + result:= nil; + if intf1 <> nil then begin + result:= intf1.getinstance; + end; +end; + +function tactivator.getclientinterfaces(const index: integer): iobjectlink; +begin + checkarrayindex(fclients,index); + result:= iobjectlink(fclients[index]); +end; + +{ tonterminatequerylist } + +function tonterminatequerylist.doterminatequery: boolean; +begin + factitem:= 0; + result:= true; + while (factitem < fcount) and result do begin + terminatequeryeventty(getitempo(factitem)^)(result); + inc(factitem); + end; +end; + +{ tonidlelist} + +function tonidlelist.doidle: boolean; +var + bo1: boolean; +begin + result:= false; + factitem:= 0; + while factitem < fcount do begin + bo1:= false; + idleeventty(getitempo(factitem)^)(bo1); + result:= result or bo1; + inc(factitem); + end; +end; + +{ teventlist } + +procedure teventlist.finalizeitem(var item: pointer); +begin + if ownsobjects then begin + tmseevent(item).Free1; + item:= nil; + end; +end; + +{ tonapplicationeventlist } + +procedure tonapplicationeventlist.doevent(var aevent: tmseevent; + var handled: boolean); +begin + factitem:= 0; + while (factitem < fcount) and not handled do begin + applicationeventhandlereventty(getitempo(factitem)^)(aevent,handled); + inc(factitem); + end; +end; + +{ tcustomapplication } + +{$ifdef mse_debugmutex} +function tcustomapplication.getmutexaddr: pointer; +begin + result:= @fmutex; +end; +function tcustomapplication.getmutexcount: integer; +begin + result:= flockcount; +end; +procedure tcustomapplication.checklockcount; +var + str1: string; +begin + if appmutexcount <> flockcount then begin + str1:= 'appmutexerror, lockcount: '+inttostr(flockcount)+ + ' mutexcount: '+inttostr(appmutexcount); + debugwriteln(str1); + debugwritestack; + raise exception.create(str1); + end; +end; +{$endif} + +constructor tcustomapplication.create(aowner: tcomponent); +begin + if appinst <> nil then begin + raise exception.create('Application already created.'); + end; + appinst:= self; + fapplicationname:= filename(sys_getapplicationpath); + fthread:= sys_getcurrentthread; + feventlist:= teventlist.create(true); + fonterminatedlist:= tnotifylist.create; + fonterminatequerylist:= tonterminatequerylist.create; + fonidlelist:= tonidlelist.create; + sys_mutexcreate(fmutex); + sys_mutexcreate(feventlock); + classes.wakemainthread:= {$ifdef FPC}@{$endif}dowakeup; + fonapplicationeventlist:= tonapplicationeventlist.create; + lock; + initialize; +end; + +destructor tcustomapplication.destroy; +begin + inherited; + deinitialize; + fonidlelist.free; + fonterminatedlist.free; + fonterminatequerylist.free; + feventlist.free; + sys_mutexdestroy(fmutex); + sys_mutexdestroy(feventlock); + fonapplicationeventlist.free; +end; + +procedure tcustomapplication.registeronterminated(const method: notifyeventty); +begin + fonterminatedlist.add(tmethod(method)); +end; + +procedure tcustomapplication.unregisteronterminated(const method: notifyeventty); +begin + fonterminatedlist.remove(tmethod(method)); +end; + +procedure tcustomapplication.registeronterminate(const method: terminatequeryeventty); +begin + fonterminatequerylist.add(tmethod(method)); +end; + +procedure tcustomapplication.unregisteronterminate(const method: terminatequeryeventty); +begin + fonterminatequerylist.remove(tmethod(method)); +end; + +procedure tcustomapplication.registeronidle(const method: idleeventty); +begin + fonidlelist.add(tmethod(method)); +end; + +procedure tcustomapplication.unregisteronidle(const method: idleeventty); +begin + fonidlelist.remove(tmethod(method)); +end; + +procedure tcustomapplication.registerapplicationeventhandler( + const method: applicationeventhandlereventty); +begin + fonapplicationeventlist.add(tmethod(method)); +end; + +procedure tcustomapplication.unregisterapplicationeventhandler( + const method: applicationeventhandlereventty); +begin + fonapplicationeventlist.remove(tmethod(method)); +end; + +function tcustomapplication.dolock: boolean; +var + athread: threadty; +begin + inc(flockcount); + athread:= sys_getcurrentthread; + if not sys_issamethread(flockthread,athread) then begin + result:= true; + flockthread:= athread; + end + else begin + result:= false; + end; + {$ifdef mse_debuglock} + debugout(self,'lock, count: '+inttostr(flockcount) + ' thread: '+ + inttostr(flockthread)); + {$endif} + {$ifdef mse_debugmutex} + checklockcount; + {$endif} +end; + +function tcustomapplication.lock: boolean; +begin + syserror(sys_mutexlock(fmutex)); + result:= dolock; +end; + +function tcustomapplication.islockedthread: boolean; + //true if calling thread holds the lock +begin + result:= (flockcount > 0) and (flockthread = sys_getcurrentthread()); +end; + +function tcustomapplication.islockedmainthread: boolean; +var + id: threadty; +begin + id:= sys_getcurrentthread(); + result:= (flockcount > 0) and (id = flockthread) and (id = fthread); +end; + +function tcustomapplication.trylock: boolean; +begin + result:= sys_mutextrylock(fmutex) = sye_ok; + {$ifdef mse_debuglock} + debugout(self,'trylock, result: '+booltostr(result)+' count: '+ + inttostr(flockcount) + ' thread: '+ + inttostr(flockthread)); + {$endif} + if result then begin + dolock; + end; +end; + +function tcustomapplication.internalunlock(count: integer): boolean; +begin + result:= sys_issamethread(flockthread,sys_getcurrentthread); + if result then begin + if count > flockcount then begin + raise exception.create('tcustomapplication.internalunlock lock count error.'); + end; + flusheventbuffer; + while count > 0 do begin + {$ifdef mse_debugmutex} + checklockcount; + {$endif} + dec(count); + dec(flockcount); + if flockcount = 0 then begin + flockthread:= 0; + end; + sys_mutexunlock(fmutex); + end; + {$ifdef mse_debuglock} + debugout(self,'unlock, result: '+booltostr(result)+ + ' count: '+inttostr(flockcount) + ' thread: '+ + inttostr(flockthread)); + {$endif} + end; +end; + +function tcustomapplication.unlock: boolean; +begin + result:= internalunlock(1); +end; + +function tcustomapplication.unlockall: integer; +begin + if ismainthread then begin + inc(fcheckoverloadlock); + end; + result:= flockcount; + if not internalunlock(flockcount) then begin + result:= 0; + end; +end; + +procedure tcustomapplication.relockall(count: integer); +begin + if count > 0 then begin + lock; + dec(count); + inc(flockcount,count); + while count > 0 do begin + sys_mutexlock(fmutex); + dec(count); + end; + if ismainthread then begin + dec(fcheckoverloadlock); + end; + end; +end; + +procedure tcustomapplication.lockifnotmainthread; +begin + if not ismainthread then begin + lock; + end; +end; + +procedure tcustomapplication.unlockifnotmainthread; +begin + if not ismainthread then begin + unlock; + end; +end; + +function tcustomapplication.synchronize(const proc: proceventty; + const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; +var + event: tappsynchronizeevent; +begin + event:= tappsynchronizeevent.create(proc,quiet); + try + result:= synchronizeevent(event,aoptions); + finally + event.free; + end; +end; + +function tcustomapplication.synchronize(const proc: synchronizeeventty; + const data: pointer; const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; +var + event: tappsynchronizedataevent; +begin + event:= tappsynchronizedataevent.create(proc,data,quiet); + try + result:= synchronizeevent(event,aoptions); + finally + event.free; + end; +end; + +function tcustomapplication.synchronize(const proc: synchronizeprocty; + const data: pointer; const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; +var + event: tappsynchronizeprocevent; +begin + event:= tappsynchronizeprocevent.create(proc,data,quiet); + try + result:= synchronizeevent(event,aoptions); + finally + event.free; + end; +end; + +procedure tcustomapplication.queueasynccall(const proc: proceventty; + const aoptions: posteventoptionsty = []); +begin + postevent(tappasyncevent.create(proc),aoptions) +end; + +procedure tcustomapplication.queueasynccall(const proc: synchronizeeventty; + const data: pointer; const aoptions: posteventoptionsty = []); +begin + postevent(tappasyncdataevent.create(proc,data),aoptions); +end; + +procedure tcustomapplication.queueasynccall(const proc: synchronizeprocty; + const data: pointer; const aoptions: posteventoptionsty = []); +begin + postevent(tappasyncprocevent.create(proc,data),aoptions); +end; + +function tcustomapplication.ismainthread: boolean; +begin + result:= sys_getcurrentthread = fthread; +end; + +function tcustomapplication.islockthread: boolean; +begin + result:= sys_getcurrentthread = flockthread; +end; + +procedure tcustomapplication.waitforthread(athread: tmsethread); + //does unlock-relock before waiting +var + int1: integer; +begin + int1:= unlockall; + try + athread.waitfor; + finally + relockall(int1); + end; +end; + +function tcustomapplication.semwait(var sem: semty; + timeoutusec: integer): syserrorty; + //does unlock-relock before waiting +var + int1: integer; +begin + int1:= unlockall; + try + result:= sys_semwait(sem,timeoutusec); + finally + relockall(int1); + end; +end; + +procedure tcustomapplication.incidlecount; +begin + inc(fidlecount); +end; + +procedure tcustomapplication.flusheventbuffer; +var + int1: integer; + event1: tmseevent; +begin + sys_mutexlock(feventlock); + if not (aps_eventflushing in fstate) then begin + include(fstate,aps_eventflushing); + for int1:= 0 to high(fpostedeventslocal) do begin + event1:= fpostedeventslocal[int1]; + if (event1 is tobjectevent) {and ismainthread} then begin + with tobjectevent1(event1) do begin + if oes_modaldeferred in fstate then begin + fmodallevel:= self.modallevel; + end; + end; + end; + feventlist.add(event1); + end; + fpostedeventslocal:= nil; + for int1:= 0 to high(fpostedevents) do begin + event1:= fpostedevents[int1]; + if (event1 is tobjectevent) {and ismainthread} then begin + with tobjectevent1(event1) do begin + if oes_modaldeferred in fstate then begin + fmodallevel:= self.modallevel; + end; + end; + end; + dopostevent(event1); + end; + fpostedevents:= nil; + exclude(fstate,aps_eventflushing); + end; + sys_mutexunlock(feventlock); +end; + +procedure tcustomapplication.postevent(event: tmseevent; + const aoptions: posteventoptionsty); +var + bo1: boolean; +begin + if csdestroying in componentstate then begin + event.free1; + end + else begin + bo1:= event is tobjectevent; + if (peo_modaldefer in aoptions) and bo1 then begin + include(tobjectevent1(event).fstate,oes_modaldeferred); + end; + if trylock then begin + try + if bo1 then begin + with tobjectevent1(event) do begin + if (oes_modaldeferred in fstate) then begin + fmodallevel:= self.modallevel; + end; + end; + end; + flusheventbuffer; + if aoptions * [peo_local,peo_first] <> [] then begin + if peo_first in aoptions then begin + eventlist.insert(0,event); + end + else begin + eventlist.add(event); + end; + wakeupmainthread; + end + else begin + dopostevent(event); + end; + except + event.free1; + unlock; + raise; + end; + unlock; + end + else begin + sys_mutexlock(feventlock); + if (peo_local in aoptions) then begin + setlength(fpostedeventslocal,high(fpostedeventslocal) + 2); + fpostedeventslocal[high(fpostedeventslocal)]:= event; + end + else begin + setlength(fpostedevents,high(fpostedevents) + 2); + fpostedevents[high(fpostedevents)]:= event; + end; + sys_mutexunlock(feventlock); + end; + end; +end; + +function tcustomapplication.checkoverload(const asleepus: integer = 100000): boolean; + //true if never idle since last call, + // unlocks application and calls sleep if not mainthread and asleepus >= 0 +//todo: fix for concurent calls, use wait queue instead of sleep +var + int1: integer; +begin + result:= (fidlecount = 0) and not (aps_waiting in fstate) and + (fcheckoverloadlock = 0); + fidlecount:= 0; + if result and (asleepus >= 0) and not ismainthread then begin + int1:= unlockall; + repeat + sleepus(asleepus); + until (fidlecount > 0) or (aps_waiting in fstate) or (fcheckoverloadlock <> 0); + relockall(int1); + end; +end; + +function tcustomapplication.getterminated: boolean; +begin + result:= aps_terminated in fstate; +end; + +procedure tcustomapplication.setterminated(const Value: boolean); +begin + if value then begin + lock; + include(fstate,aps_terminated); + if not ismainthread then begin + wakeupmainthread; + end; + unlock; + end + else begin + exclude(fstate,aps_terminated); + end; +end; + +procedure tcustomapplication.wakeupmainthread; +begin + if fstate * [aps_running,aps_waiting,aps_woken] = + [aps_running,aps_waiting] then begin + include(fstate,aps_woken); + postevent(tmseevent.create(ek_wakeup)); + end; +end; + +procedure tcustomapplication.langchanged; +begin + //dummy +end; + +procedure tcustomapplication.beginwait(const aprocessmessages: boolean = false); +begin + if aprocessmessages then begin + processmessages; + end; +end; + +procedure tcustomapplication.endwait; +begin + //dummy +end; + +procedure tcustomapplication.idlesleep(const asleepus: integer); +var + int1: integer; +begin + int1:= unlockall; + sleepus(asleepus); + relockall(int1); +end; + +{ +function tcustomapplication.waitdialog(const athread: tthreadcomp = nil; + const atext: msestring = ''; const caption: msestring = ''; + const acancelaction: notifyeventty = nil; + const aexecuteaction: notifyeventty = nil; + const aidleaction: waitidleeventty = nil): boolean; +begin + result:= false; //dummy +end; +} +procedure tcustomapplication.handleexception(sender: tobject = nil; + const leadingtext: msestring = ''); +var + handled: boolean; + exceptobj: tobject; +begin + exceptobj:= exceptobject; + if exceptobj is exception then begin + if not (exceptobj is eabort) then begin + if exceptionactive = 0 then begin + //do not handle subsequent exceptions + inc(exceptionactive); + try + interlockedincrement(fexceptioncount); + handled:= false; + if assigned(fonexception) then begin + fonexception(sender,exception(exceptobj),leadingtext,handled); + end; + if not handled then begin + showexception(exception(exceptobj),leadingtext); + end; + finally + dec(exceptionactive); + if apo_terminateonexception in foptions then begin + terminated:= true; + end; + end; + end + else begin + interlockedincrement(fexceptioncount); +// sysutils.showexception(exceptobject, exceptaddr); + end; + end; + end; +end; + +procedure tcustomapplication.run; +var + threadbefore: threadty; +begin + dobeforerun; + threadbefore:= fthread; + fthread:= sys_getcurrentthread; + include(fstate,aps_running); + try + doeventloop(false); + fonterminatedlist.notify(application); + finally + fthread:= threadbefore; + exclude(fstate,aps_running); + end; + doafterrun; +end; + +function tcustomapplication.running: boolean; +begin + result:= aps_running in fstate; +end; + +procedure tcustomapplication.processmessages; +var + bo1: boolean; +begin + if not ismainthread then begin + raise exception.create('processmessages must be called from main thread.'); + end; + bo1:= aps_processmessages in fstate; + include(fstate,aps_processmessages); +// int1:= unlockall; + lock(); + try + doeventloop(true); + finally +// relockall(int1); + if not bo1 then begin + exclude(fstate,aps_processmessages); + end; + unlock(); + end; +end; + +procedure tcustomapplication.dobeforerun; +begin + //dummy +end; + +procedure tcustomapplication.doafterrun; +begin + //dummy +end; + +procedure tcustomapplication.doidle; +var + int1: integer; +begin + while true do begin + if not fonidlelist.doidle then begin + break; + end; + int1:= getevents; + if int1 <> 0 then begin + break; + end; + end; + if ismainthread then begin + checksynchronize; + end; +end; + +function tcustomapplication.createdatamodule(instanceclass: msecomponentclassty; + var reference): tmsecomponent; +begin + result:= mseclasses.createmodule(self,instanceclass,reference); +end; +{ +procedure tcustomapplication.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + inherited; +end; + +procedure tcustomapplication.setlinkedvar(const source: tlinkedobject; + var dest: tlinkedobject; const linkintf: iobjectlink = nil); +begin + inherited; +end; + +procedure tcustomapplication.setlinkedvar(const source: tlinkedpersistent; + var dest: tlinkedpersistent; const linkintf: iobjectlink = nil); +begin + inherited; +end; +} +procedure tcustomapplication.dowakeup(sender: tobject); +begin + wakeupmainthread; +end; + +function tcustomapplication.idle: boolean; +begin + result:= (high(fpostedevents) < 0) and (high(fpostedeventslocal) < 0) and + (feventlist.count = 0); +end; + +function tcustomapplication.candefocus(const caller: tobject = nil): boolean; +begin + result:= true; //dummy +end; + +function tcustomapplication.procid: procidty; +begin + result:= sys_getpid; +end; + +function tcustomapplication.getserial(): card32; +begin + repeat + result:= interlockedincrement(fserial); + until result <> 0; +end; + +procedure tcustomapplication.internalinitialize; +begin + //dummy +end; + +procedure tcustomapplication.internaldeinitialize; +begin + //dummy +end; + +procedure tcustomapplication.initialize; +begin + if not (aps_inited in fstate) and (finiting = 0) then begin + inc(finiting); + fstate:= []; + try + internalinitialize; + finally + dec(finiting); + end; + include(fstate,aps_inited); + end; +end; + +procedure tcustomapplication.deinitialize; +begin + if aps_inited in fstate then begin + include(fstate,aps_deinitializing); + try + internaldeinitialize; + finally + exclude(fstate,aps_deinitializing); + end; + exclude(fstate,aps_inited); + end; +end; + +procedure tcustomapplication.objecteventdestroyed(const sender: tobjectevent); +begin + //dummy +end; + +procedure tcustomapplication.beginhighrestimer; +begin + if fhighrestimercount = 0 then begin + sethighrestimer(true); + end; + inc(fhighrestimercount); +end; + +procedure tcustomapplication.endhighrestimer; +begin + dec(fhighrestimercount); + if fhighrestimercount = 0 then begin + sethighrestimer(false); + end; +end; + +function tcustomapplication.gethighrestimer: boolean; +begin + result:= fhighrestimercount > 0; +end; + +function tcustomapplication.waitescaped: boolean; +begin + result:= false; +end; + +procedure tcustomapplication.settimer(const us: integer); +begin + if interlockedincrement(ftimertriggercount) = 1 then begin + postevent(tmseevent.create(ek_timer)); + end; +end; + +procedure tcustomapplication.resettimertrigger; +begin + interlockedexchange(ftimertriggercount,0); +end; + +procedure tcustomapplication.beforedestruction(); +begin + fapplicationdestroyed:= true; + inherited; +end; + +procedure tcustomapplication.releaseobject(const aobject: tobject); +begin + postevent(treleaseevent.create(ievent(self),aobject)); +end; + +procedure tcustomapplication.receiveevent(const event: tobjectevent); +begin + inherited; + if (event.kind = ek_releaseobject) and + (event is treleaseevent) then begin + treleaseevent(event).fobject.free; + end; +end; + +{ tactivatorcontroller } + +constructor tactivatorcontroller.create(const aowner: tcomponent; + const aintf: iactivatorclient); +begin + fintf:= aintf; + fowner:= aowner; + inherited create; +end; + +function tactivatorcontroller.setactive(const value: boolean): boolean; +begin + factive:= value; + result:= floaded or not (csloading in fowner.componentstate); +end; + +procedure tactivatorcontroller.loaded; +begin + floaded:= true; + try + if (factivator = nil) or factivator.activated then begin + if factivator <> nil then begin + factive:= true; //activated + end; + if csdesigning in fowner.componentstate then begin + try + setowneractive(factive); + except + if assigned(ondesignexception) then begin + ondesignexception(fowner); + end + else begin + application.handleexception(fowner); + end; + end; + end + else begin + setowneractive(factive); + end; + end; + finally + floaded:= false; + end; +end; + +procedure tactivatorcontroller.setactivator(const avalue: tactivator); +begin + tactivator.addclient(avalue,iobjectlink(self),factivator); +end; + +procedure tactivatorcontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (sender = factivator) then begin + case event of + oe_activate: begin + floaded:= true; + factive:= true; + try + setowneractive(factive); + finally + floaded:= false; + end; + end; + oe_deactivate: begin + factive:= false; + setowneractive(factive); + end; + end; + end; +end; + +function tactivatorcontroller.getinstance: tobject; +begin + result:= fowner; +end; + +{ tappasyncevent } + +constructor tappasyncevent.create(const aproc: proceventty); +begin + fproc:= aproc; + inherited create(); +end; + +procedure tappasyncevent.execute(); +begin + fproc(); +end; + +{ tappasyncdataevent } + +constructor tappasyncdataevent.create(const aproc: synchronizeeventty; + const adata: pointer); +begin + fproc:= aproc; + fdata:= adata; + inherited create(); +end; + +procedure tappasyncdataevent.execute(); +begin + fproc(fdata); +end; + +{ tappasyncprocevent } + +constructor tappasyncprocevent.create(const aproc: synchronizeprocty; + const adata: pointer); +begin + fproc:= aproc; + fdata:= adata; + inherited create(); +end; + +procedure tappasyncprocevent.execute(); +begin + fproc(fdata); +end; + +{ tappsynchronizeevent } + +constructor tappsynchronizeevent.create(const aproc: proceventty; + const aquiet: boolean); +begin + fproc:= aproc; + inherited create(aquiet); +end; + +procedure tappsynchronizeevent.execute; +begin + fproc; +end; + +{ tappsynchronizedataeevent } + +constructor tappsynchronizedataevent.create(const aproc: synchronizeeventty; + const adata: pointer; const aquiet: boolean); +begin + fproc:= aproc; + fdata:= adata; + inherited create(aquiet); +end; + +procedure tappsynchronizedataevent.execute; +begin + fproc(fdata); +end; + +{ tappsynchronizeprocevent } + +constructor tappsynchronizeprocevent.create(const aproc: synchronizeprocty; + const adata: pointer; const aquiet: boolean); +begin + fproc:= aproc; + fdata:= adata; + inherited create(aquiet); +end; + +procedure tappsynchronizeprocevent.execute; +begin + fproc(fdata); +end; + +{ treleaseevent } + +constructor treleaseevent.create(const dest: ievent; const aobject: tobject); +begin + fobject:= aobject; + inherited create(ek_releaseobject,dest); +end; + +initialization +finalization + appinst.Free; + appinst:= nil; +end. diff --git a/mseide-msegui/lib/common/kernel/msearrayprops.pas b/mseide-msegui/lib/common/kernel/msearrayprops.pas new file mode 100644 index 0000000..8cfc06a --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msearrayprops.pas @@ -0,0 +1,2266 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msearrayprops; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + sysutils,classes,mclasses,typinfo,mselist, + msegraphutils,msetypes,msestrings,mseclasses,mseglob,msestat; + +type + earraystreamerror = class(estreamerror); + earrayproperror = class(exception); + + tarrayprop = class; + arrayproparrayty = array of tarrayprop; + + arraychangeeventty = procedure(const sender: tarrayprop; + const index: integer) of object; + arraysizechangeeventty = procedure(sender: tarrayprop) of object; + + arraypropstatety = (aps_linking,aps_destroying,aps_needsindexing,aps_moved); + arraypropsstatesty = set of arraypropstatety; + + arraypropkindty = (apk_none,apk_tpersistent,apk_integer,apk_colorty,apk_real, + apk_string,apk_msestring,apk_boolean,apk_pointer,apk_int64); + + tarrayprop = class(tpersistent) + private + itemsread: boolean; + linkedarrays: arrayproparrayty; + fonchange: arraychangeeventty; + ffixcount: integer; + procedure internalinsert(const index: integer; const init: boolean); + protected + fstate: arraypropsstatesty; + fupdating: integer; + fcountbefore: integer; + procedure setfixcount(const avalue: integer); virtual; + procedure change(const index: integer); virtual; + function getcount: integer; virtual; abstract; + function getdatapo: pointer; virtual; abstract; + procedure checkcount(var acount: integer); virtual; + procedure setcount1(acount: integer; doinit: boolean); virtual; + procedure setcount(const acount: integer); + procedure dosizechanged; virtual; + function getsize: integer; virtual; abstract; + function getitemspo(const index: integer): pointer; virtual; abstract; + procedure writeitem(const index: integer; writer: twriter); virtual; abstract; + procedure readitem(const index: integer; reader: treader); virtual; abstract; + procedure defineproperties(filer: tfiler); override; + procedure readcount(reader: treader); + procedure writecount(writer: twriter); + procedure readitems(reader: treader); + procedure writeitems(writer: twriter); + procedure init(startindex,endindex: integer); virtual; + procedure dochange(const aindex: integer); virtual; + procedure checkindex(const index: integer); + function checkstored(ancestor: tpersistent): boolean; virtual; + public + function propkind: arraypropkindty; virtual; + procedure beginupdate; + procedure endupdate(nochange: boolean = false); + procedure clear; + procedure insertempty(const index: integer); + procedure insertdefault(const index: integer); + procedure delete(const index: integer); + procedure move(const curindex,newindex: integer); virtual; + procedure order(const sourceorder: integerarty); //sourceorder can be nil + procedure reorder(const destorder: integerarty); //destorder can be nil + procedure link(alinkedarrays: array of tarrayprop{; + onsizechanged: arraysizechangeeventty = nil}); + property fixcount: integer read ffixcount write setfixcount default 0; + property onchange: arraychangeeventty read fonchange write fonchange; + published + property count: integer read getcount write setcount default 0; + end; + + tintegerarrayprop = class(tarrayprop) + private + protected + fitems: integerarty; + function getitems(const index: integer): integer; + procedure setitems(const index: integer; const Value: integer); + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + property items[const index: integer]: integer read getitems write setitems; default; + end; + + tcolorarrayprop = class(tintegerarrayprop) + private + function getitems(const index: integer): colorty; + procedure setitems(const index: integer; const Value: colorty); + protected + fvaluedefault: colorty; + procedure init(startindex,endindex: integer); override; + public + constructor create; + function propkind: arraypropkindty; override; + property items[const index: integer]: colorty read getitems + write setitems; default; + end; + + tint64arrayprop = class(tarrayprop) + private + protected + fitems: int64arty; + function getitems(const index: integer): int64; + procedure setitems(const index: integer; const Value: int64); + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + property items[const index: integer]: int64 read getitems write setitems; default; + end; + + trealarrayprop = class(tarrayprop) + private + function getitems(const index: integer): real; + procedure setitems(const index: integer; const Value: real); + protected + fitems: realarty; + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + property items[const index: integer]: real read getitems write setitems; default; + end; + + tstringarrayprop = class(tarrayprop) + private + function getitems(const index: integer): string; + procedure setitems(const index: integer; const Value: string); + protected + fitems: stringarty; + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + function itemar: stringarty; + property items[const index: integer]: string read getitems write setitems; default; + end; + + tmsestringarrayprop = class(tarrayprop) + private + function getitems(const index: integer): msestring; + procedure setitems(const index: integer; const Value: msestring); + protected + fitems: msestringarty; + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + property items[const index: integer]: msestring read getitems write setitems; default; + end; + + tbooleanarrayprop = class(tintegerarrayprop) + private + function getitems(const index: integer): boolean; + procedure setitems(const index: integer; const Value: boolean); + public + function propkind: arraypropkindty; override; + property items[const index: integer]: boolean read getitems write setitems; default; + end; + + tenumarrayprop = class(tintegerarrayprop) + protected + ftypeinfo: ptypeinfo; + public + constructor create(typeinfo: ptypeinfo); reintroduce; + end; + + tsetarrayprop = class(tintegerarrayprop) + private + function getitems(const index: integer): tintegerset; + protected + ftypeinfo: ptypeinfo; + procedure setitems(const index: integer; const Value: tintegerset); virtual; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + public + constructor create(typeinfo: ptypeinfo); reintroduce; + property typeinfo: ptypeinfo read ftypeinfo; + property items[const index: integer]: tintegerset read getitems write setitems; default; + end; + + tpointerarrayprop = class(tarrayprop) + private + protected + fitems: pointerarty; + function getitems(const index: integer): pointer; + procedure setitems(const index: integer; const Value: pointer); + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + property items[const index: integer]: pointer read getitems write setitems; default; + end; + + tdynarrayarrayprop = class(tpointerarrayprop) + protected + procedure internalsetcount(const acount: int32) virtual abstract; + procedure setcount1(acount: integer; doinit: boolean); override; + public + destructor destroy(); override; + end; + + tpersistentarrayprop = class(tarrayprop,iobjectlink) + private //same layout as tpointerarrayprop! + protected + fitems: persistentarty; //same layout as tintegerarrayprop! + fdestroyingitem: tpersistent; + fitemclasstype: virtualpersistentclassty; + fobjectlinker: tobjectlinker; + function _addref: integer; stdcall; + function _release: integer; stdcall; + function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; + + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; const event: objecteventty); virtual; + function getitems(const index: integer): tpersistent;{ virtual;} + procedure init(startindex,endindex: integer); override; + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + procedure createitem(const index: integer; var item: tpersistent); virtual; + procedure defineproperties(filer: tfiler); override; + procedure readcollection(reader: treader); + procedure writecollection(writer: twriter); + function getcollectionname(const index: integer): string; virtual; + function ispropertystored(index: integer): boolean; virtual; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); overload; + public + constructor create(aitemclasstype: virtualpersistentclassty); reintroduce; + destructor destroy; override; + procedure itemdestroyed(const aitem: tpersistent); + procedure assign(source: tpersistent); override; + function propkind: arraypropkindty; override; + function displayname(const index: integer): msestring; virtual; + procedure add(const item: tpersistent); + function add(): tpersistent; //returns added element + function indexof(const aitem: tpersistent): integer; //-1 if not found + class function getitemclasstype: persistentclassty; virtual; + //used in dumpunitgroups + property itemclasstype: virtualpersistentclassty read fitemclasstype; + property items[const index: integer]: tpersistent read getitems; default; + end; + persistentarraypropclassty = class of tpersistentarrayprop; + + tmsecomponentlinkarrayprop = class; + + tmsecomponentlinkitem = class(tvirtualpersistent) + private + fitem: tmsecomponent; + procedure setitem(const avalue: tmsecomponent); + protected + fprop: tmsecomponentlinkarrayprop; + property item: tmsecomponent read fitem write setitem; + public + destructor destroy; override; + published + end; + + msecomponentlinkitemclassty = class of tmsecomponentlinkitem; + + tmsecomponentlinkarrayprop = class(tpersistentarrayprop) + private +// function getitems(const index: integer): tmsecomponent; +// procedure setitems(const index: integer; const avalue: tmsecomponent); + protected + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aitemclasstype: msecomponentlinkitemclassty); + class function getitemclasstype: persistentclassty; override; +// property items[const index: integer]: tmsecomponent read getitems +// write setitems; default; + end; + + ownedpersistentclassty = class of townedpersistent; + + townedpersistentarrayprop = class(tpersistentarrayprop) + private + protected + fowner: tobject; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure internalcreate(const aowner: tobject; + aclasstype: virtualpersistentclassty); + public + constructor create(const aowner: tobject; + aclasstype: ownedpersistentclassty); virtual; + end; + + tindexpersistentarrayprop = class; + + ownedeventpersistentclassty = class of townedeventpersistent; + + townedeventpersistentarrayprop = class(tpersistentarrayprop) + private + protected + fowner: tobject; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tobject; + aclasstype: ownedeventpersistentclassty); + end; + + tpersistonchangearrayprop = class(tpersistentarrayprop) + protected + onchange1: notifyeventty; + public + constructor create(aclasstype: virtualpersistentclassty; aonchange: notifyeventty); + end; + + tstringlistarrayprop = class(tpersistentarrayprop) + private + function getitems(index: integer): tstringlist; reintroduce; + procedure setitems(index: integer; const Value: tstringlist); reintroduce; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + public + property items[index: integer]: tstringlist read getitems write setitems; + end; + + tindexpersistent = class(townedeventpersistent) + private + fident: integer; + fprop: tindexpersistentarrayprop; + protected + findex: integer; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure dostatread(const reader: tstatreader); virtual; + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); reintroduce; virtual; + property index: integer read findex; + property ident: integer read fident; + property prop: tindexpersistentarrayprop read fprop; + end; + + indexpersistentclassty = class of tindexpersistent; + + tindexpersistentarrayprop = class(townedpersistentarrayprop) + private + fident: integer; + function getidents: integerarty; + function getidentmap: integerarty; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure change(const index: integer); override; + function getidentnum(const index: integer): integer; + procedure dosizechanged; override; + function originalorder: integerarty; //restores original order, returns sort vector + public + constructor create(const aowner: tobject; aclasstype: indexpersistentclassty); + reintroduce; virtual; + procedure add(const item: tindexpersistent); + procedure dostatwrite(const writer: tstatwriter; const aorder: boolean); + procedure writeorder(const writer: tstatwriter); + function readorder(const reader: tstatreader): integerarty; + procedure dostatread(const reader: tstatreader; const aorder: boolean); + procedure clearorder; //ident order = index order + function newident: integer; + property idents: integerarty read getidents; + property identmap: integerarty read getidentmap; + end; +{ + tsubcomponentitem = class(tindexpersistent) + protected + fitem: tcomponent; + function createitem: tcomponent; virtual; abstract; + function getnamebase: string; virtual; + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); override; + destructor destroy; override; + end; + subcomponentitemclassty = class of tsubcomponentitem; + + tsubcomponentarrayprop = class(tindexpersistentarrayprop) + protected +// procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tcomponent; + const aitemclasstype: subcomponentitemclassty); reintroduce; + end; +} +implementation +uses + rtlconsts,msedatalist,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tbinaryobjectreader1 = class(tbinaryobjectreader); + twriter1 = class(twriter); + treader1 = class(treader); + +{ tarrayprop } + +procedure tarrayprop.checkindex(const index: integer); +begin + if (index < 0) or (index >= count) then begin + tlist.Error({$ifndef FPC}@{$endif}SListIndexError, Index); + end; +end; + +function tarrayprop.checkstored(ancestor: tpersistent): boolean; +begin + if ancestor is tarrayprop then begin + with tarrayprop(ancestor) do begin + result:= (self.count <> 0) or (count <> 0); + end; + end + else begin + result:= false; + end; +end; + +procedure tarrayprop.change(const index: integer); +begin + if (fupdating = 0) and not (aps_destroying in fstate) then begin + dochange(index); + end; +end; + +procedure tarrayprop.beginupdate; +begin + inc(fupdating); +end; + +procedure tarrayprop.endupdate(nochange: boolean = false); +begin + dec(fupdating); + if not nochange then begin + change(-1); + end; +end; + +procedure tarrayprop.clear; +begin + count:= 0; +end; + +procedure tarrayprop.dosizechanged; +begin + //dummy +{ + if assigned(fonsizechanged) then begin + fonsizechanged(self); + end; + } +end; + +procedure tarrayprop.checkcount(var acount: integer); +begin + if ffixcount <> 0 then begin + acount:= ffixcount; + end; +end; + +procedure tarrayprop.setcount1(acount: integer; doinit: boolean); +var + int1: integer; + obj: tarrayprop; + count2: integer; + +begin + if acount <> fcountbefore then begin + if acount = 0 then begin + fstate:= fstate - [aps_needsindexing,aps_moved]; + end; + count2:= fcountbefore; + if acount > fcountbefore then begin +// fillchar(getitemspo(fcountbefore)^,(acount-fcountbefore)*getsize,#0); + if doinit then begin + init(fcountbefore,acount-1); + end; + end + else begin + if aps_moved in fstate then begin + include(fstate,aps_needsindexing); + end; + end; + fcountbefore:= acount; + if not (aps_linking in fstate) then begin + for int1:= 0 to length(linkedarrays) - 1 do begin + obj:= linkedarrays[int1]; + if obj <> self then begin + include(obj.fstate,aps_linking); + try + obj.count:= acount; + finally + exclude(obj.fstate,aps_linking); + end; + end; + end; + end; + change(-1); + if (count2 <> acount) and not (aps_destroying in fstate) then begin + dosizechanged; + end; + end; +end; + +procedure tarrayprop.setcount(const acount: integer); +begin + setcount1(acount,true); +end; + +procedure tarrayprop.setfixcount(const avalue: integer); +begin + if ffixcount <> avalue then begin + ffixcount:= avalue; + setcount(avalue); + end; +end; + +procedure tarrayprop.readcount(reader: treader); +begin + beginupdate; + try + count:= reader.ReadInteger; + finally + endupdate; + end; +end; + +procedure tarrayprop.writecount(writer: twriter); +begin + writer.writeinteger(count); +end; + +procedure tarrayprop.readitems(reader: treader); +var + int1: integer; +begin + int1:= 0; + reader.ReadListBegin; + while not reader.EndOfList do begin + if int1 >= count then begin + raise earraystreamerror.create('Arrayproperty length mismatch: '+ + inttostr(count) + '.'); + end; + readitem(int1,reader); + inc(int1); + end; + reader.readlistend; + itemsread:= true; +end; + +procedure tarrayprop.writeitems(writer: twriter); +var + int1: integer; +begin + writer.writeListBegin; + for int1:= 0 to count-1 do begin + writeitem(int1,writer); + end; + writer.writelistend; +end; + +procedure tarrayprop.defineproperties(filer: tfiler); + + function DoWrite: Boolean; + begin + if Filer.Ancestor <> nil then begin + Result := checkstored(filer.Ancestor); + end + else begin + Result := Count > 0; + end; + end; + +begin +// filer.DefineProperty('count',readcount,writecount,true); + filer.DefineProperty('items',{$ifdef FPC}@{$endif}readitems, + {$ifdef FPC}@{$endif}writeitems,dowrite); + if itemsread then begin + itemsread:= false; + change(-1); + end; +end; + +procedure tarrayprop.link(alinkedarrays: array of tarrayprop{; + onsizechanged: arraysizechangeeventty = nil}); +var + int1: integer; +begin +// fonsizechanged:= onsizechanged; + setlength(linkedarrays,high(alinkedarrays)+1); + for int1:= 0 to high(alinkedarrays) do begin + linkedarrays[int1]:= alinkedarrays[int1]; + end; + for int1:= 0 to length(linkedarrays)-1 do begin + if linkedarrays[int1] <> self then begin + linkedarrays[int1].linkedarrays:= linkedarrays; + end; + end; + setcount(count); +end; + +procedure tarrayprop.init(startindex, endindex: integer); +begin + //dummy +end; + +procedure tarrayprop.dochange(const aindex: integer); +begin + if assigned(fonchange) then begin + fonchange(self,aindex); + end; +end; + +procedure tarrayprop.move(const curindex, newindex: integer); +var + postart,pocur,ponew,poend,backup: pchar; + size,count1: integer; +begin + if curindex <> newindex then begin + checkindex(curindex); + checkindex(newindex); + include(fstate,aps_moved); + size:= getsize; + count1:= getcount; + postart:= getitemspo(0); + pocur:= postart + curindex*size; + ponew:= postart + newindex*size; + poend:= postart + count1*size; + getmem(backup,size); + try + system.move(pocur^,backup^,size); + system.move((pocur+size)^,pocur^,poend-pocur-size); + system.move(ponew^,(ponew+size)^,poend-ponew-size); + system.move(backup^,ponew^,size); + finally + freemem(backup); + end; + change(-1); +// change(curindex); +// change(newindex); + end; +end; + +procedure tarrayprop.order(const sourceorder: integerarty); +var + int1: integer; +begin + if sourceorder <> nil then begin + int1:= getcount; + if int1 <> length(sourceorder) then begin + raise exception.create('tarrayprop: Wrong length of neworder'); + end; + if int1 > 0 then begin + include(fstate,aps_moved); + orderarray(sourceorder,getdatapo^,getsize); + end; + change(-1); + end; +end; + +procedure tarrayprop.reorder(const destorder: integerarty); +var + int1: integer; +begin + int1:= getcount; + if int1 <> length(destorder) then begin + raise exception.create('tarrayprop: Wrong length of neworder'); + end; + if int1 > 0 then begin + include(fstate,aps_moved); + reorderarray(destorder,getdatapo^,getsize); + end; + change(-1); +end; + +procedure tarrayprop.delete(const index: integer); +begin + beginupdate; + try + move(index,count - 1); + count:= count - 1; + finally + endupdate; + end; +end; + +procedure tarrayprop.internalinsert(const index: integer; const init: boolean); +begin + include(fstate,aps_moved); + beginupdate; + try + setcount1(count + 1,init); + move(count-1,index); + finally + endupdate; + end; +end; + +procedure tarrayprop.insertempty(const index: integer); +begin + internalinsert(index,false); +end; + +procedure tarrayprop.insertdefault(const index: integer); +begin + internalinsert(index,true); +end; + +function tarrayprop.propkind: arraypropkindty; +begin + result:= apk_none; +end; + +{ tintegerarrayprop } + +function tintegerarrayprop.checkstored(ancestor: tpersistent): boolean; +begin + result:= not (ancestor is tintegerarrayprop); + if not result then begin + with tintegerarrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + result:= not comparemem(@self.fitems[0],@fitems[0], + length(fitems)*sizeof(integer)); + end; + end; + end; +end; + +function tintegerarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +procedure tintegerarrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= reader.ReadInteger; +end; + +procedure tintegerarrayprop.writeitem(const index: integer; writer: twriter); +begin + writer.writeinteger(fitems[index]); +end; + +procedure tintegerarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +function tintegerarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tintegerarrayprop.getsize: integer; +begin + result:= sizeof(integer); +end; + +function tintegerarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +function tintegerarrayprop.getitems(const index: integer): integer; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure tintegerarrayprop.setitems(const index: integer; const Value: integer); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +procedure tintegerarrayprop.assign(source: tpersistent); +begin + if source is tintegerarrayprop then begin + fitems:= copy(tintegerarrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function tintegerarrayprop.propkind: arraypropkindty; +begin + result:= apk_integer; +end; + +{ tcolorarrayprop } + +constructor tcolorarrayprop.create; +begin + fvaluedefault:= cl_none; + inherited; +end; + +function tcolorarrayprop.getitems(const index: integer): colorty; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure tcolorarrayprop.setitems(const index: integer; const Value: colorty); +begin + inherited setitems(index,value); +end; + +procedure tcolorarrayprop.init(startindex, endindex: integer); +var + int1: integer; +begin + for int1:= startindex to endindex do begin + items[int1]:= fvaluedefault; + end; +end; + +function tcolorarrayprop.propkind: arraypropkindty; +begin + result:= apk_colorty; +end; + +{ tint64arrayprop } + +function tint64arrayprop.checkstored(ancestor: tpersistent): boolean; +begin + result:= not (ancestor is tint64arrayprop); + if not result then begin + with tint64arrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + result:= not comparemem(@self.fitems[0],@fitems[0], + length(fitems)*sizeof(int64)); + end; + end; + end; +end; + +function tint64arrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +procedure tint64arrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= reader.ReadInt64; +end; + +procedure tint64arrayprop.writeitem(const index: integer; writer: twriter); +begin + writer.writeinteger(fitems[index]); +end; + +procedure tint64arrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +function tint64arrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tint64arrayprop.getsize: integer; +begin + result:= sizeof(int64); +end; + +function tint64arrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +function tint64arrayprop.getitems(const index: integer): int64; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure tint64arrayprop.setitems(const index: integer; const Value: int64); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +procedure tint64arrayprop.assign(source: tpersistent); +begin + if source is tint64arrayprop then begin + fitems:= copy(tint64arrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function tint64arrayprop.propkind: arraypropkindty; +begin + result:= apk_int64; +end; + +{ trealarrayprop } + +function trealarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +function trealarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function trealarrayprop.getsize: integer; +begin + result:= sizeof(real); +end; + +function trealarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +procedure trealarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +procedure trealarrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= reader.ReadFloat; +end; + +procedure trealarrayprop.writeitem(const index: integer; writer: twriter); +begin + writer.writefloat(fitems[index]); +end; + +function trealarrayprop.getitems(const index: integer): real; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure trealarrayprop.setitems(const index: integer; const Value: real); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +function trealarrayprop.checkstored(ancestor: tpersistent): boolean; +begin + result:= not (ancestor is trealarrayprop); + if not result then begin + with trealarrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + result:= not comparemem(@self.fitems[0],@fitems[0], + length(fitems)*sizeof(real)); + end; + end; + end; +end; + +procedure trealarrayprop.assign(source: tpersistent); +begin + if source is trealarrayprop then begin + fitems:= copy(trealarrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function trealarrayprop.propkind: arraypropkindty; +begin + result:= apk_real; +end; + +{ tstringarrayprop } + +function tstringarrayprop.checkstored(ancestor: tpersistent): boolean; +var + int1: integer; +begin + result:= not (ancestor is tstringarrayprop); + if not result then begin + with tstringarrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + for int1:= 0 to count - 1 do begin + if self.fitems[int1] <> fitems[int1] then begin + result:= true; + break; + end; + end; + end; + end; + end; +end; + +function tstringarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +function tstringarrayprop.getitems(const index: integer): string; +begin + checkindex(index); + result:= fitems[index]; +end; + +function tstringarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tstringarrayprop.getsize: integer; +begin + result:= sizeof(string); +end; + +function tstringarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +procedure tstringarrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= reader.Readstring; +end; + +procedure tstringarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +procedure tstringarrayprop.setitems(const index: integer; const Value: string); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +procedure tstringarrayprop.writeitem(const index: integer; writer: twriter); +begin + writer.writestring(fitems[index]); +end; + +procedure tstringarrayprop.assign(source: tpersistent); +begin + if source is tstringarrayprop then begin + fitems:= copy(tstringarrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function tstringarrayprop.propkind: arraypropkindty; +begin + result:= apk_string; +end; + +function tstringarrayprop.itemar: stringarty; +begin + result:= copy(fitems); +end; + +{ tmsestringarrayprop } + +function tmsestringarrayprop.checkstored(ancestor: tpersistent): boolean; +var + int1: integer; +begin + result:= not (ancestor is tmsestringarrayprop); + if not result then begin + with tmsestringarrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + for int1:= 0 to count - 1 do begin + if self.fitems[int1] <> fitems[int1] then begin + result:= true; + break; + end; + end; + end; + end; + end; +end; + +function tmsestringarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +function tmsestringarrayprop.getitems(const index: integer): msestring; +begin + checkindex(index); + result:= fitems[index]; +end; + +function tmsestringarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tmsestringarrayprop.getsize: integer; +begin + result:= sizeof(msestring); +end; + +function tmsestringarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +procedure tmsestringarrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= treader_readmsestring(reader); //msestringimplementation +// {$ifdef mse_unicodestring} +// fitems[index]:= reader.Readunicodestring; //msestringimplementation +// {$else} +// fitems[index]:= reader.Readwidestring; //msestringimplementation +// {$endif} +end; + +procedure tmsestringarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +procedure tmsestringarrayprop.setitems(const index: integer; const Value: msestring); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +procedure tmsestringarrayprop.writeitem(const index: integer; writer: twriter); +begin + twriter_writemsestring(writer,fitems[index]); +// {$ifdef mse_unicodestring} +// writer.writeunicodestring(fitems[index]); +// {$else} +// writer.writewidestring(fitems[index]); //msestringimplementation +// {$endif} +end; + +procedure tmsestringarrayprop.assign(source: tpersistent); +begin + if source is tmsestringarrayprop then begin + fitems:= copy(tmsestringarrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function tmsestringarrayprop.propkind: arraypropkindty; +begin + result:= apk_msestring; +end; + +{ tbooleanarrayprop } + +function tbooleanarrayprop.getitems(const index: integer): boolean; +begin + checkindex(index); + result:= boolean(fitems[index]); +end; + +procedure tbooleanarrayprop.setitems(const index: integer; + const Value: boolean); +begin + inherited setitems(index,integer(value)); +end; + +function tbooleanarrayprop.propkind: arraypropkindty; +begin + result:= apk_boolean; +end; + +{ tenumarrayprop } + +constructor tenumarrayprop.create(typeinfo: ptypeinfo); +begin + if typeinfo^.Kind <> tkenumeration then begin + raise earrayproperror.Create('typ muss enum sein!'); + end; + ftypeinfo:= typeinfo; + inherited create; +end; + +{ tsetarraypropmse } + +constructor tsetarrayprop.create(typeinfo: ptypeinfo); +var + typedatapo: ptypedata; + +begin + if typeinfo^.Kind <> tkset then begin + raise earrayproperror.Create('typ muss set sein!'); + end; + ftypeinfo:= typeinfo; + typedatapo:= gettypedata(ftypeinfo); + typedatapo:= gettypedata(typedatapo^.comptype{$ifndef FPC}^{$endif}); +// fsize:= (typedatapo^.maxvalue - typedatapo^.minvalue) div 8 + 1; + if (typedatapo^.maxvalue - typedatapo^.minvalue) div 8 + 1 > + sizeof(tintegerset) then begin + raise earrayproperror.Create('set muss <= 32 sein!'); + end; +// {$ifdef FPC} +// fsize:= sizeof(longword); +// {$endif} + inherited create; +end; +{ +function tsetarrayprop.getcount: integer; +begin + result:= length(fitems); +end; +} +function tsetarrayprop.getitems(const index: integer): tintegerset; +begin + checkindex(index); + result:= tintegerset(fitems[index]); +end; +{ +function tsetarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tsetarrayprop.getsize: integer; +begin + result:= sizeof(tintegerset); +end; + +function tsetarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +procedure tsetarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; +} +procedure tsetarrayprop.setitems(const index: integer; const Value: tintegerset); +begin + checkindex(index); + fitems[index]:= integer(value); + change(index); +end; + +procedure tsetarrayprop.writeitem(const index: integer; writer: twriter); +begin + writeset(writer,tintegerset(fitems[index]),ftypeinfo); +end; + +procedure tsetarrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= integer(readset(reader,ftypeinfo)); +end; +{ +procedure tsetarrayprop.getset(const index: integer; out value); +begin + checkindex(index); + system.move(fitems[index],value,fsize); +end; + +procedure tsetarrayprop.setset(const index: integer; const value); +begin + checkindex(index); + fillchar(fitems[index],sizeof(tintegerset),0); + system.move(value,fitems[index],fsize); +end; +} + +{ tpointerarrayprop } + +function tpointerarrayprop.checkstored(ancestor: tpersistent): boolean; +begin + result:= not (ancestor is tpointerarrayprop); + if not result then begin + with tpointerarrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + result:= not comparemem(@self.fitems[0],@fitems[0], + length(fitems)*sizeof(pointer)); + end; + end; + end; +end; + +function tpointerarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +procedure tpointerarrayprop.readitem(const index: integer; reader: treader); +begin +{$ifdef CPU64} + fitems[index]:= pointer(reader.ReadInt64); +{$else} + fitems[index]:= pointer(reader.ReadInteger); +{$endif} +end; + +procedure tpointerarrayprop.writeitem(const index: integer; writer: twriter); +begin +{$ifdef CPU64} + writer.writeinteger(int64(fitems[index])); +{$else} + writer.writeinteger(integer(fitems[index])); +{$endif} +end; + +procedure tpointerarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +function tpointerarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tpointerarrayprop.getsize: integer; +begin + result:= sizeof(pointer); +end; + +function tpointerarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +function tpointerarrayprop.getitems(const index: integer): pointer; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure tpointerarrayprop.setitems(const index: integer; const Value: pointer); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +procedure tpointerarrayprop.assign(source: tpersistent); +begin + if source is tpointerarrayprop then begin + fitems:= copy(tpointerarrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function tpointerarrayprop.propkind: arraypropkindty; +begin + result:= apk_pointer; +end; + +{ tdynarrayarrayprop } + +destructor tdynarrayarrayprop.destroy(); +begin + inherited; + internalsetcount(0); +end; + +procedure tdynarrayarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + internalsetcount(acount); + inherited; +end; + +{ tpersistentarrayprop } + +constructor tpersistentarrayprop.create(aitemclasstype: virtualpersistentclassty); +begin + fitemclasstype:= aitemclasstype; + inherited create; +end; + +destructor tpersistentarrayprop.destroy; +begin + include(fstate,aps_destroying); + setlength(linkedarrays,0); + clear; + inherited; + fobjectlinker.free; +end; + +function tpersistentarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +procedure tpersistentarrayprop.init(startindex, endindex: integer); +var + int1: integer; +begin + inherited; + for int1:= startindex to endindex do begin + createitem(int1,fitems[int1]); + end; +end; + +procedure tpersistentarrayprop.setcount1(acount: integer; doinit: boolean); +var + {lengthvorher,}int1: integer; + ar1: persistentarty; + pers1: tpersistent; +begin + if not (aps_destroying in fstate) then begin + checkcount(acount); + end; + int1:= length(fitems) - acount; + if int1 > 0 then begin + pers1:= fdestroyingitem; + ar1:= copy(fitems,acount,int1); + setlength(fitems,acount); //return new count + for int1:= high(ar1) downto 0 do begin + fdestroyingitem:= ar1[int1]; + ar1[int1].free; + end; + fdestroyingitem:= pers1; + end + else begin + setlength(fitems,acount); + end; + inherited; +end; + +procedure tpersistentarrayprop.readitem(const index: integer; reader: treader); +begin + //dummy +end; + +procedure tpersistentarrayprop.writeitem(const index: integer; writer: twriter); +begin + //dummy +end; + +function tpersistentarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tpersistentarrayprop.getsize: integer; +begin + result:= sizeof(tpersistent); +end; + +function tpersistentarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +procedure tpersistentarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + if fitemclasstype <> nil then begin + item:= fitemclasstype.create; + end + else begin + item:= nil; + end; +end; + +function tpersistentarrayprop.ispropertystored(index: integer): boolean; +begin + result:= fitems[index] <> nil; +end; + +procedure tpersistentarrayprop.readcollection(reader: treader); +var + int1,int2,int3: integer; + str1: string; +begin + with treader1(reader) do begin + readvalue; + int1:= 0; + while not EndOfList do begin + if NextValue in [vaInt8, vaInt16, vaInt32] then ReadInteger; + int2:= int1; + if nextvalue = vaident then begin + str1:= readident; + if str1 <> '' then begin + for int3:= 0 to count-1 do begin + if getcollectionname(int3) = str1 then begin + int2:= int3; + break; + end; + end; + end; + end; + ReadListBegin; + while not EndOfList do begin + if int2 <= high(fitems) then begin + treader1(reader).ReadProperty(getitems(int2)); + end + else begin + tbinaryobjectreader1(reader.driver).skipproperty; + end; + end; + ReadListEnd; + inc(int1); + end; + readlistend; + end; + itemsread:= true; +end; + +procedure tpersistentarrayprop.writecollection(writer: twriter); +var + int1,int2,int3: integer; + proppathvorher: string; + ancestorbefore: tpersistentarrayprop; + str1: string; + +begin + proppathvorher:= getfproppath(writer); + setfproppath(writer,''); + ancestorbefore:= tpersistentarrayprop(writer.ancestor); + try + with twriter1(writer) do begin + driver.begincollection; + for int1 := 0 to Count - 1 do begin + str1:= getcollectionname(int1); + if str1 <> '' then begin + writeident(str1); + end; + WriteListBegin; + ancestor:= nil; + if ancestorbefore <> nil then begin + int2:= int1; + if (str1 <> '') then begin + int2:= bigint; //needs ancestor name + for int3:= 0 to ancestorbefore.count-1 do begin + if ancestorbefore.getcollectionname(int3) = str1 then begin + int2:= int3; + break; + end; + end; + end; + if (int2 < ancestorbefore.count) then begin + ancestor:= ancestorbefore.fitems[int2]; + end; + end; + if ispropertystored(int1) then begin + twriter1(writer).WriteProperties(getitems(int1)); + end; + WriteListEnd; + end; + WriteListEnd; + end; + finally + setfproppath(writer,proppathvorher); + writer.Ancestor:= ancestorbefore; + end; +end; + +procedure tpersistentarrayprop.defineproperties(filer: tfiler); +begin + filer.DefineProperty('items',{$ifdef FPC}@{$endif}readcollection, + {$ifdef FPC}@{$endif}writecollection,count>0); +// inherited; + if itemsread and (filer is treader) then begin + itemsread:= false; + change(-1); + end; +end; + +procedure tpersistentarrayprop.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tpersistentarrayprop.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tpersistentarrayprop.objevent(const sender: iobjectlink; const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tpersistentarrayprop.getinstance: tobject; +begin + result:= self; +end; + +function tpersistentarrayprop._addref: integer; stdcall; +begin + result:= -1; +end; + +function tpersistentarrayprop._release: integer; stdcall; +begin + result:= -1; +end; + +function tpersistentarrayprop.QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; +begin + if GetInterface(IID, Obj) then begin + Result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; + +function tpersistentarrayprop.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(iobjectlink(self),{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tpersistentarrayprop.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tpersistentarrayprop.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tpersistentarrayprop.setlinkedvar(const source: tlinkedobject; + var dest: tlinkedobject; const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +function tpersistentarrayprop.getitems(const index: integer): tpersistent; +begin + checkindex(index); + result:= fitems[index]; +end; + +function tpersistentarrayprop.displayname(const index: integer): msestring; +begin + if fitemclasstype <> nil then begin + result:= msestring(PTypeInfo(fitemclasstype.ClassInfo)^.name); + end + else begin + result:= ''; + end; +end; + +procedure tpersistentarrayprop.add(const item: tpersistent); +begin + beginupdate; + setlength(fitems,high(fitems)+2); +// insertempty(length(fitems)); + fitems[high(fitems)]:= item; + setcount1(length(fitems),false); + endupdate; +end; + +function tpersistentarrayprop.add(): tpersistent; //returns added element +begin + count:= count+1; + result:= fitems[high(fitems)]; +end; + +function tpersistentarrayprop.indexof(const aitem: tpersistent): integer; //-1 if not found +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(fitems) do begin + if fitems[int1] = aitem then begin + result:= int1; + end; + end; +end; + +function tpersistentarrayprop.propkind: arraypropkindty; +begin + result:= apk_tpersistent; +end; + +procedure tpersistentarrayprop.assign(source: tpersistent); +var + int1: integer; +begin + if source is tpersistentarrayprop then begin + clear; + with tpersistentarrayprop(source) do begin + self.count:= count; + for int1:= 0 to count - 1 do begin + self.fitems[int1].assign(fitems[int1]); + end; + end; + end + else begin + inherited; + end; +end; + +class function tpersistentarrayprop.getitemclasstype: persistentclassty; +begin + result:= nil; //dummy +end; + +function tpersistentarrayprop.getcollectionname(const index: integer): string; +begin + result:= ''; +end; + +procedure tpersistentarrayprop.itemdestroyed(const aitem: tpersistent); +begin + if not (aps_destroying in fstate) and (aitem <> fdestroyingitem) then begin + if removeitem(pointerarty(fitems),aitem) >= 0 then begin + change(-1); + dosizechanged; + end; + end; +end; + +{ townedpersistentarrayprop } + +constructor townedpersistentarrayprop.create(const aowner: tobject; + aclasstype: ownedpersistentclassty); +begin + internalcreate(aowner,aclasstype); +end; + +procedure townedpersistentarrayprop.internalcreate(const aowner: tobject; + aclasstype: virtualpersistentclassty); +begin + fowner:= aowner; + inherited create(aclasstype); +end; + +procedure townedpersistentarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + if fitemclasstype <> nil then begin + item:= tpersistent(fitemclasstype.newinstance); + townedpersistent(item).create(fowner); + end + else begin + item:= nil; + end; +end; + +{ townedeventpersistentarrayprop } + +constructor townedeventpersistentarrayprop.create(const aowner: tobject; + aclasstype: ownedeventpersistentclassty); +begin + fowner:= aowner; + inherited create(aclasstype); +end; + +procedure townedeventpersistentarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + if fitemclasstype <> nil then begin + item:= ownedeventpersistentclassty(fitemclasstype).create(fowner); + end + else begin + item:= nil; + end; +end; + +{ tpersistonchangearrayprop } + +constructor tpersistonchangearrayprop.create(aclasstype: virtualpersistentclassty; + aonchange: notifyeventty); +begin + onchange1:= aonchange; + inherited create(aclasstype); +end; + +{ tstringlistarrayprop } + +procedure tstringlistarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tstringlist.create; +end; + +function tstringlistarrayprop.getitems(index: integer): tstringlist; +begin + checkindex(index); + result:= tstringlist(fitems[index]); +end; + +procedure tstringlistarrayprop.setitems(index: integer; + const Value: tstringlist); +begin + checkindex(index); + tstringlist(fitems[index]).assign(value); +end; + +{ tindexpersistentarrayprop } + +constructor tindexpersistentarrayprop.create(const aowner: tobject; + aclasstype: indexpersistentclassty); +begin + internalcreate(aowner,aclasstype); +end; + +procedure tindexpersistentarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + if fitemclasstype <> nil then begin + item:= indexpersistentclassty(fitemclasstype).create(fowner,self); + tindexpersistent(item).findex:= index; + end + else begin + item:= nil; + end; +end; + +procedure tindexpersistentarrayprop.change(const index: integer); +var + int1: integer; + item1: tindexpersistent; +begin + if (index < 0) and (fupdating = 0) then begin + for int1:= 0 to high(fitems) do begin + item1:= tindexpersistent(fitems[int1]); + if item1 <> nil then begin + item1.findex:= int1; + end; + end; + end; + inherited; +end; + +function tindexpersistentarrayprop.getidentnum(const index: integer): integer; +var + item1: tindexpersistent; +begin + item1:= tindexpersistent(fitems[index]); + if item1 <> nil then begin + result:= item1.fident; + end + else begin + result:= bigint; + end; +end; + +function tindexpersistentarrayprop.newident: integer; +begin + if aps_needsindexing in fstate then begin + result:= newidentnum(count,{$ifdef FPC}@{$endif}getidentnum); + end + else begin + result:= fident; + inc(fident); + end; +end; + +procedure tindexpersistentarrayprop.dosizechanged; +begin + if count = 0 then begin + exclude(fstate,aps_needsindexing); + fident:= 0; + end + else begin + if not (aps_needsindexing in fstate) then begin + fident:= count; + end; + end; + inherited; +end; + +procedure tindexpersistentarrayprop.writeorder(const writer: tstatwriter); +var + int1,int2,int3: integer; + ar1: integerarty; + bo1: boolean; +begin + if count > 0 then begin + setlength(ar1,count); + int2:= tindexpersistent(fitems[0]).fident; + bo1:= false; + for int1:= 0 to count -1 do begin + int3:= tindexpersistent(fitems[int1]).fident; + if int3 < int2 then begin + bo1:= true; + end; + ar1[int1]:= int3; + int2:= int3; + end; + if bo1 then begin + writer.writearray('order',ar1); + end; + end; +end; + +function tindexpersistentarrayprop.readorder( + const reader: tstatreader): integerarty; +var + ar1,ar2: integerarty; + int1: integer; +begin + result:= nil; + beginupdate; + try + ar1:= nil; + ar1:= reader.readarray('order',ar1); + if (ar1 <> nil) and (high(ar1) = high(fitems)) then begin + sortarray(ar1,ar2); + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> int1 then begin + exit; //invalid + end; + end; + reorderarray(ar2,pointerarty(fitems)); + for int1:= 0 to count -1 do begin + tindexpersistent(fitems[int1]).findex:= int1; + end; + result:= ar2; + end; + finally + endupdate; + end; +end; + +procedure tindexpersistentarrayprop.dostatread(const reader: tstatreader; + const aorder: boolean); +var + int1: integer; +begin + if reader.canstate then begin + beginupdate; + try + if aorder then begin + readorder(reader); + end; + for int1:= 0 to count -1 do begin + tindexpersistent(fitems[int1]).dostatread(reader); + end; + finally + endupdate; + end; + end; +end; + +procedure tindexpersistentarrayprop.dostatwrite(const writer: tstatwriter; + const aorder: boolean); +var + int1: integer; +begin + if writer.canstate then begin + for int1:= 0 to count -1 do begin + tindexpersistent(fitems[int1]).dostatwrite(writer); + end; + if aorder then begin + writeorder(writer); + end; + end; +end; + +procedure tindexpersistentarrayprop.add(const item: tindexpersistent); +begin + item.findex:= count; + inherited add(item); +end; + +function tindexpersistentarrayprop.getidents: integerarty; +var + int1: integer; +begin + setlength(result,count); + for int1:= 0 to high(fitems) do begin + result[int1]:= tindexpersistent(fitems[int1]).fident; + end; +end; + +function tindexpersistentarrayprop.originalorder: integerarty; +var + int1: integer; + ar1: integerarty; +begin + ar1:= getidents; + sortarray(ar1,result); + orderarray(result,pointerarty(fitems)); + for int1:= 0 to count -1 do begin + tindexpersistent(fitems[int1]).findex:= int1; + end; +end; + +function tindexpersistentarrayprop.getidentmap: integerarty; + var + int1,int2: integer; +begin + int2:= -1; + for int1:= 0 to high(fitems) do begin + with tindexpersistent(fitems[int1]) do begin + if fident > int2 then begin + int2:= fident; + end; + end; + end; + setlength(result,int2+1); + for int2:= 0 to high(result) do begin + result[int2]:= -1; + for int1:= 0 to high(fitems) do begin + with tindexpersistent(fitems[int1]) do begin + if fident = int2 then begin + result[int2]:= int1; + break; + end; + end; + end; + end; +end; + +procedure tindexpersistentarrayprop.clearorder; +var + int1: integer; +begin + fident:= count; + exclude(fstate,aps_needsindexing); + for int1:= 0 to fident - 1 do begin + with tindexpersistent(fitems[int1]) do begin + fident:= int1; + end; + end; +end; + +{ tindexpersistent } + +constructor tindexpersistent.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + findex:= -1; + fprop:= aprop; + inherited create(aowner); + fident:= fprop.newident; +end; + +procedure tindexpersistent.dostatread(const reader: tstatreader); +begin + //dummy +end; + +procedure tindexpersistent.dostatwrite(const writer: tstatwriter); +begin + //dummy +end; + +{ tmsecomponenlinktitem } + +destructor tmsecomponentlinkitem.destroy; +begin + item:= nil; + inherited; +end; + +procedure tmsecomponentlinkitem.setitem(const avalue: tmsecomponent); +begin + fprop.setlinkedvar(avalue,fitem); +end; + +{ tmsecomponentlinkarrayprop } + +constructor tmsecomponentlinkarrayprop.create( + const aitemclasstype: msecomponentlinkitemclassty); +begin + inherited create(aitemclasstype); +end; +{ +function tmsecomponentarrayprop.getitems(const index: integer): tmsecomponent; +begin + result:= tmsecomponent(inherited getitems(index)); +end; + +procedure tmsecomponentarrayprop.setitems(const index: integer; + const avalue: tmsecomponent); +begin + inherited; +end; +} +procedure tmsecomponentlinkarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + inherited; + tmsecomponentlinkitem(item).fprop:= self; +end; + +class function tmsecomponentlinkarrayprop.getitemclasstype: persistentclassty; +begin + result:= tmsecomponentlinkitem; +// result:= tmsecomponent; +end; +(* +{ tsubcomponentarrayprop } + +constructor tsubcomponentarrayprop.create(const aowner: tcomponent; + const aitemclasstype: subcomponentitemclassty); +begin + inherited create(aowner,aitemclasstype); +end; + +{ tsubcomponentitem } + +constructor tsubcomponentitem.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + inherited; + fitem:= createitem; + if not (csloading in tcomponent(aowner).componentstate) then begin + fitem.name:= getnumberedname(tcomponent(aowner),getnamebase); + end; +end; + +destructor tsubcomponentitem.destroy; +begin + inherited; + fitem.free; +end; + +function tsubcomponentitem.getnamebase: string; +begin + result:= 'item'; +end; +*) + +end. diff --git a/mseide-msegui/lib/common/kernel/msearrayutils.pas b/mseide-msegui/lib/common/kernel/msearrayutils.pas new file mode 100644 index 0000000..d9d855f --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msearrayutils.pas @@ -0,0 +1,3426 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msearrayutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msetypes,msestrings; +const + arrayminlenghtstep = 32; + +type + stringsortmodety = (sms_none,sms_upascii,sms_upiascii,sms_up,sms_upi); + pointercomparemethodty = function(l,r:pointer): integer of object; + pointercomparefuncty = function(l,r:pointer): integer; + + arraysortcomparety = function (const l,r): integer; + sortcomparemethodty = function (const l,r): integer of object; + sortcomparemethodarty = array of sortcomparemethodty; + indexsortcomparemethodty = function (const l,r: integer): integer of object; + + tvarrecarty = array of tvarrec; + +procedure deleteitem(var value; const typeinfo: pdynarraytypeinfo; + const aindex: integer); overload; + //value = array of type which needs no finalize +procedure arrayaddref(var dynamicarray); +procedure arraydecref(var dynamicarray); + //no finalize and freemem if refcount = 0 +procedure allocuninitedarray(count,itemsize: integer; out dynamicarray); + //does not init memory, dynamicarray must be nil! +procedure reallocuninitedarray(count,itemsize: integer; var dynamicarray); + //does not init memory, dynamicarray must be unique! +procedure freeuninitedarray(var dynamicarray); + //does not finalize items, dynamicarray must be unique! +function arrayrefcount(var dynamicarray): sizeint; +function arrayminhigh(arrays: array of pointer): integer; + //array of dynamicarray +function dynarrayelesize(const typinfo: pdynarraytypeinfo): sizeint; inline; +function dynarrayhigh(const value: pointer): sizeint; inline; +function dynarraylength(const value: pointer): sizeint; inline; +function incrementarraylength(var value: pointer; typeinfo: pdynarraytypeinfo; + increment: integer = 1): sizeint; overload; + //returns new length + +function additem(var value; const typeinfo: pdynarraytypeinfo; + //typeinfo of dynarray + var count: integer): boolean; overload; + //value = array of type, returns true if extended +function additemindex(var value; const typeinfo: pdynarraytypeinfo; + //typeinfo of dynarray + var count: integer): integer; overload; + //value = array of type, returns true if extended +function additempo(var value; const typeinfo: pdynarraytypeinfo; + //typeinfo of dynarray + var count: integer): pointer; overload; + //returns adress of new item + +function firstitem(const source: stringarty): string; overload; +function firstitem(const source: msestringarty): msestring; overload; + + //return true if extended +function additem(var dest: stringarty; const value: string; + var count: integer): boolean; overload; +function additem(var dest: stringararty; const value: stringarty; + var count: integer): boolean; overload; +function additem(var dest: msestringarty; const value: msestring; + var count: integer): boolean; overload; +function additem(var dest: msestringararty; const value: msestringarty; + var count: integer): boolean; overload; +function additem(var dest: lstringarty; const value: lstringty; + var count: integer): boolean; overload; +function additem(var dest: lmsestringarty; const value: lmsestringty; + var count: integer): boolean; overload; +function additem(var dest: int16arty; const value: int16; + var count: integer): boolean; overload; +function additem(var dest: integerarty; const value: integer; + var count: integer): boolean; overload; +function additem(var dest: longwordarty; const value: longword; + var count: integer): boolean; overload; +function additem(var dest: realarty; const value: real; + var count: integer): boolean; overload; +function additem(var dest: pointerarty; const value: pointer; + var count: integer): boolean; overload; +{$ifndef FPC} +function addpointeritem(var dest: pointerarty; const value: pointer; + var count: integer): boolean; +{$endif} +function additem(var dest: winidarty; const value: winidty; + var count: integer): boolean; overload; + +procedure additem(var dest: stringarty; const value: string); overload; +procedure additem(var dest: msestringarty; const value: msestring); overload; +procedure additem(var dest: doublemsestringarty; + const valuea,valueb: msestring); overload; +procedure additem(var dest: msestringararty; + const value: msestringarty); overload; +procedure additem(var dest: int16arty; const value: int16); overload; +procedure additem(var dest: integerarty; const value: integer); overload; +procedure additem(var dest: int64arty; const value: int64); overload; +procedure additem(var dest: card64arty; const value: card64); overload; +procedure additem(var dest: longwordarty; const value: longword); overload; +procedure additem(var dest: longboolarty; const value: longbool); overload; +procedure additem(var dest: booleanarty; const value: boolean); overload; +procedure additem(var dest: realarty; const value: real); overload; +procedure additem(var dest: pointerarty; const value: pointer); overload; +procedure additem(var dest: winidarty; const value: winidty); overload; +procedure deleteitem(var dest: stringarty; index: integer); overload; +procedure deleteitem(var dest: msestringarty; index: integer); overload; +procedure deleteitem(var dest: integerarty; index: integer); overload; +procedure deleteitem(var dest: int64arty; index: integer); overload; +procedure deleteitem(var dest: card64arty; index: integer); overload; +procedure deleteitem(var dest: booleanarty; index: integer); overload; +procedure deleteitem(var dest: realarty; index: integer); overload; +procedure deleteitem(var dest: complexarty; index: integer); overload; +procedure deleteitem(var dest: pointerarty; index: integer); overload; +procedure deleteitem(var dest: winidarty; index: integer); overload; +procedure insertitem(var dest: integerarty; index: integer; + value: integer); overload; +procedure insertitem(var dest: int64arty; index: integer; + value: int64); overload; +procedure insertitem(var dest: booleanarty; index: integer; + value: boolean); overload; +procedure insertitem(var dest: longwordarty; index: integer; + value: longword); overload; +procedure insertitem(var dest: realarty; index: integer; + value: realty); overload; +procedure insertitem(var dest: complexarty; index: integer; + value: complexty); overload; +procedure insertitem(var dest: pointerarty; index: integer; + value: pointer); overload; +procedure insertitem(var dest: winidarty; index: integer; value: winidty); overload; +procedure insertitem(var dest: stringarty; index: integer; value: string); overload; +procedure insertitem(var dest: msestringarty; index: integer; value: msestring); overload; + +procedure removeitems(var dest: pointerarty; const aitem: pointer); + //removes all matching items +function removeitem(var dest: pointerarty; const aitem: pointer): integer; + overload; + //returns removed index, -1 if none + +function finditem(const ar: pointerarty; const aitem: pointer): integer; + overload; + //-1 if none + +procedure moveitem(var dest; const sourceindex: integer; + destindex: integer; const itemsize: integer); overload; +procedure moveitem(var dest: pointerarty; const sourceindex: integer; + destindex: integer); overload; + +function removeitem(var dest: stringarty; const aitem: string): integer; + overload; + //returns removed index, -1 if none +function finditem(const ar: stringarty; const aitem: string): integer; + overload; + //-1 if none +procedure moveitem(var dest: stringarty; const sourceindex: integer; + destindex: integer); overload; + +function removeitem(var dest: msestringarty; const aitem: msestring): integer; + overload; + //returns removed index, -1 if none +function finditem(const ar: msestringarty; const aitem: msestring): integer; + overload; + //-1 if none +procedure moveitem(var dest: msestringarty; const sourceindex: integer; + destindex: integer); overload; + + +function removeitem(var dest: integerarty; const aitem: integer): integer; + overload; + //returns removed index, -1 if none +function finditem(const ar: integerarty; const aitem: integer): integer; + overload; //-1 if none +procedure moveitem(var dest: integerarty; const sourceindex: integer; + destindex: integer); overload; + +function adduniqueitem(var dest: pointerarty; const value: pointer): integer; + //returns index +function addnewitem(var dest: pointerarty; const value: pointer): integer; + //returns index, -1 if already existing + +function isequalarray(const a: integerarty; const b: integerarty): boolean; + +procedure minmax(const ar: realarty; out minval,maxval: realty); + +function stackarfunc(const ar1,ar2: integerarty): integerarty; +procedure stackarray(const source: stringarty; var dest: stringarty); overload; +procedure stackarray(const source: msestringarty; var dest: msestringarty); overload; +procedure stackarray(const source: integerarty; var dest: integerarty); overload; +procedure stackarray(const source: longwordarty; var dest: longwordarty); overload; +procedure stackarray(const source: pointerarty; var dest: pointerarty); overload; +procedure stackarray(const source: winidarty; var dest: winidarty); overload; +procedure stackarray(const source: realarty; var dest: realarty); overload; +procedure insertarray(const source: integerarty; var dest: integerarty); overload; +procedure insertarray(const source: realarty; var dest: realarty); overload; +function reversearray(const source: msestringarty): msestringarty; overload; +function reversearray(const source: integerarty): integerarty; overload; +function reversearray(const source: pointerarty): pointerarty; overload; +procedure removearrayduplicates(var value: pointerarty); +function packarray(source: pointerarty): pointerarty; overload; + //remove nil items +function packarray(source: msestringarty): msestringarty; overload; + //remove '' items + +procedure checkarrayindex(const value; const index: integer); + //value = dynamic array, exception bei ungueltigem index +procedure checkarrayindexcount(const count: int32; const index: int32); + +procedure splitcomplexar(const acomplex: complexarty; out re,im: realarty); + +function comparepointer(const l,r): integer; +function compareinteger(const l,r): integer; +function compareint64(const l,r): integer; +function comparecard64(const l,r): integer; +function comparerealty(const l,r): integer; +function compareasciistring(const l,r): integer; +function compareiasciistring(const l,r): integer; +function compareansistring(const l,r): integer; +function compareiansistring(const l,r): integer; +function comparemsestring(const l,r): integer; +function compareimsestring(const l,r): integer; + +function findarrayvalue(const item; const items; const itemsize: integer; + const count: integer; const compare: arraysortcomparety; + out foundindex: integer): boolean; overload; +function findarrayvalue(const item; const items; const itemsize: integer; + const index: integerarty; const compare: arraysortcomparety; + out foundindex: integer): boolean; overload; + //true if exact else next bigger + //for compare: l is item, r are tablevalues + //array must be sorted + +procedure quicksortpointer(const adata: ppointer; //-> array of pointer + const alength: int32; const acompare: pointercomparefuncty); + //position stable + +procedure mergesortarray(var asortlist; const aitemsize,alength: integer; + const acompare: arraysortcomparety; + out aindexlist: integerarty; const order: boolean); + //asortlist = array of type +procedure mergesort(var adata: pointerarty; const acount: integer; + const compare: pointercomparemethodty); overload; + +procedure mergesort(var adata: pointer; const aitemsize,acount: integer; + const acompare: sortcomparemethodty); overload; + //reallocates adata memory +procedure mergesort(const adata: pointer; const aitemsize,acount: integer; + const acompare: sortcomparemethodty; + out aindexlist: integerarty); overload; +procedure mergesort(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out aindexlist: integerarty; + var refindex: integer; out moved: boolean); overload; +procedure mergesort(const acount: integer; + const acompare: indexsortcomparemethodty; + out aindexlist: integerarty); overload; +procedure mergesort(const acount: integer; + const acompare: indexsortcomparemethodty; out aindexlist: integerarty; + var refindex: integer; out moved: boolean); overload; +procedure mergesortoffset(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out aoffsetlist: integerarty); overload; +procedure mergesortpointer(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out apointerlist: pointerarty); overload; + +function findarrayitem(const item; const ar; const itemsize: integer; + const compare: arraysortcomparety; + out foundindex: integer): boolean; overload; + //ar = sorted array of type + //true if exact else next bigger + //for compare: l is item, r are tablevalues +function findarrayitem(const item; const ar: pointerarty; + const compare: sortcomparemethodty; + out foundindex: integer): boolean; overload; + //ar = sorted array of type + //true if exact else next bigger + //for compare: l is item, r are tablevalues + +procedure sortarray(var sortlist; const itemsize: integer; + const compare: arraysortcomparety); overload; + //sortlist = array of type +procedure sortarray(var sortlist; const itemsize: integer; + const compare: arraysortcomparety; + out indexlist: integerarty); overload; + //sortlist = array of type +procedure sortarray(var dest: pointerarty; const compare: arraysortcomparety); overload; +procedure sortarray(var dest: pointerarty; const compare: arraysortcomparety; + out indexlist: integerarty); overload; +procedure sortarray(var dest: pointerarty); overload; //compares adresses +procedure sortarray(var dest: integerarty); overload; +procedure sortarray(var dest: integerarty; out indexlist: integerarty); overload; +procedure sortarray(var dest: longwordarty); overload; +procedure sortarray(var dest: longwordarty; out indexlist: integerarty); overload; +procedure sortarray(var dest: realarty); overload; +procedure sortarray(var dest: realarty; out indexlist: integerarty); overload; + +procedure sortarray(var dest: msestringarty; const compare: arraysortcomparety); overload; +procedure sortarray(var dest: msestringarty; const compare: arraysortcomparety; + out indexlist: integerarty); overload; +procedure sortarray(var dest: stringarty; const compare: arraysortcomparety); overload; +procedure sortarray(var dest: stringarty; const compare: arraysortcomparety; + out indexlist: integerarty); overload; + +procedure sortarray(var dest: msestringarty; + const sortmode: stringsortmodety = sms_up); overload; +procedure sortarray(var dest: msestringarty; const sortmode: stringsortmodety; + out indexlist: integerarty); overload; +procedure sortarray(var dest: stringarty; + const sortmode: stringsortmodety = sms_upascii); overload; +procedure sortarray(var dest: stringarty; + const sortmode: stringsortmodety; out indexlist: integerarty); overload; + +procedure orderarray(const sourceorderlist: integerarty; var sortlist; size: integer); overload; + //sortlist = array of type +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: pointerarty); overload; +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: integerarty); overload; +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: msestringarty); overload; +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: msestringararty); overload; +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: stringarty); overload; + +procedure reorderarray(const destorderlist: integerarty; + var sortlist; size: integer); overload; + //sortlist = array of type +procedure reorderarray(const destorderlist: integerarty; + var sortlist: pointerarty); overload; +procedure reorderarray(const destorderlist: integerarty; + var sortlist: integerarty); overload; +procedure reorderarray(const destorderlist: integerarty; + var sortlist: msestringarty); overload; +procedure reorderarray(const destorderlist: integerarty; + var sortlist: stringarty); overload; + +function cmparray(const a,b: msestringarty): boolean; + //true if equal + +function opentodynarraym(const items: array of msestring): msestringarty; +function opentodynarrays(const items: array of string): stringarty; +function opentodynarrayi(const items: array of integer): integerarty; +function opentodynarrayr(const items: array of realty): realarty; +function opentodynarraybo(const items: array of boolean): booleanarty; +function opentodynarrayby(const items: array of byte): bytearty; + +function dynarraytovararray(const avalue: int64arty): tvarrecarty; + +procedure copytore(const source: realarty; var dest: complexarty); +procedure copytoim(const source: realarty; var dest: complexarty); + +implementation +uses + rtlconsts,classes,sysutils,msereal,msesys{$ifndef FPC},classes_del{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure splitcomplexar(const acomplex: complexarty; out re,im: realarty); +var + int1: integer; +begin + re:= nil; //compiler warning + im:= nil; //compiler warning + int1:= length(acomplex); + if int1 > 0 then begin + allocuninitedarray(int1,sizeof(re[0]),re); + allocuninitedarray(int1,sizeof(im[0]),im); + for int1:= int1-1 downto 0 do begin + re[int1]:= acomplex[int1].re; + im[int1]:= acomplex[int1].im; + end; + end; +end; + +function aligntoptr(p: pointer): pointer; inline; +begin +{$ifdef FPC_REQUIRES_PROPER_ALIGNMENT} + result:= align(p,sizeof(p)); +{$else FPC_REQUIRES_PROPER_ALIGNMENT} + result:=p; +{$endif FPC_REQUIRES_PROPER_ALIGNMENT} +end; + +function DynArraySize(a: Pointer): sizeint; +{$ifdef FPC} +begin + result:= length(bytearty(a)); +end; +{$else} +asm + TEST EAX, EAX + JZ @@exit + MOV EAX, [EAX-4] +@@exit: +end; +{$endif} + +function incrementarraylength(var value: pointer; typeinfo: pdynarraytypeinfo; + increment: integer = 1): sizeint; + //returns new length +begin + result:= dynarraysize(value) + increment; + dynarraysetlength(value,typeinfo,1,@result); +end; + +function dynarrayelesize(const typinfo: pdynarraytypeinfo): sizeint; inline; +var + ti: pdynarraytypeinfo; +begin + ti:= typinfo; +{$ifdef FPC} + inc(pointer(ti),ord(pdynarraytypeinfo(ti)^.namelen)+2); + ti:= aligntoptr(ti); + result:= psizeint(ti)^; +// inc(pchar(ti),ord(ti^.namelen)); +// result:= ti^.elesize; +{$else} + inc(pchar(ti),length(ti^.name)); + result:= ti^.elsize; +{$endif} +end; + +function dynarrayhigh(const value: pointer): sizeint; inline; +begin + if value = nil then begin + result:= -1; + end + else begin + result:= (psizeint(value)-1)^; + end; +end; + +function dynarraylength(const value: pointer): sizeint; inline; +begin + if value = nil then begin + result:= 0; + end + else begin + result:= (psizeint(value)-1)^+1; + end; +end; + +function decrementarraylength(var value: pointer; const typeinfo: pdynarraytypeinfo; + decrement: integer = 1): sizeint; + //returns new length +begin + result:= dynarraysize(value) - decrement; + dynarraysetlength(value,typeinfo,1,@result); +end; + +function additem(var value; const typeinfo: pdynarraytypeinfo; + var count: integer): boolean; +var + int1: integer; +begin + result:= false; + int1:= high(pointerarty(value)) + 1; + if int1 <= count then begin + incrementarraylength(pointer(value),typeinfo,2*count+arrayminlenghtstep); +// incrementarraylength(pointer(value),typeinfo,count-int1+step); + result:= true; + end; + inc(count); +end; + +function additemindex(var value; const typeinfo: pdynarraytypeinfo; + var count: integer): integer; +var + int1: integer; +begin + int1:= high(pointerarty(value)) + 1; + if int1 <= count then begin + incrementarraylength(pointer(value),typeinfo,2*count+arrayminlenghtstep); +// incrementarraylength(pointer(value),typeinfo,count-int1+step); + end; + result:= count; + inc(count); +end; + +function additempo(var value; const typeinfo: pdynarraytypeinfo; + //typeinfo of dynarray + var count: integer): pointer; overload; + //returns adress of new item +var + int1: integer; +begin + int1:= high(pointerarty(value)) + 1; + if int1 <= count then begin + incrementarraylength(pointer(value),typeinfo,2*count+arrayminlenghtstep); + end; + result:= pointer(value) + count*dynarrayelesize(typeinfo); + inc(count); +end; + +procedure deleteitem(var value; const typeinfo: pdynarraytypeinfo; + const aindex: integer); + //value = array of type which needs no finalize +var + int1: integer; +begin + int1:= dynarrayelesize(pdynarraytypeinfo(typeinfo)); + move((pchar(value)+int1*(aindex+1))^,(pchar(value)+int1*aindex)^, + int1*(high(bytearty(value))-aindex)); + decrementarraylength(pointer(value),typeinfo); +end; + +procedure arrayaddref(var dynamicarray); +var + refpo: psizeint; +begin + if pointer(dynamicarray) <> nil then begin + refpo:= psizeint(pchar(dynamicarray)-2*sizeof(sizeint)); + if refpo^ >= 0 then begin + {$ifdef CPU64} + interlockedincrement64(refpo^); + {$else} + interlockedincrement(refpo^); + {$endif} + end; + end; +end; + +function arrayrefcount(var dynamicarray): sizeint; +begin + result:= 0; + if pointer(dynamicarray) <> nil then begin + result:= psizeint(pchar(dynamicarray)-2*sizeof(sizeint))^; + end; +end; + +function arrayminhigh(arrays: array of pointer): integer; + //array of dynamicarray +var + int1,int2: integer; +begin + result:= bigint; + for int1:= 0 to high(arrays) do begin + int2:= high(pointerarty(arrays[int1])); + if int1 < result then begin + result:= int2; + end; + end; + if result = bigint then begin + result:= -1; + end; +end; + +procedure arraydecref(var dynamicarray); +var + refpo: psizeint; +begin + if pointer(dynamicarray) <> nil then begin + refpo:= psizeint(pchar(dynamicarray)-2*sizeof(sizeint)); + if refpo^ > 0 then begin + {$ifdef CPU64} + interlockeddecrement64(refpo^); + {$else} + interlockeddecrement(refpo^); + {$endif} + end; + end; +end; + +procedure allocuninitedarray(count,itemsize: integer; out dynamicarray); + //does not init memory, dynamicarray must be nil! +var + po1: psizeint; +begin +{$warnings off} + if pointer(dynamicarray) <> nil then begin + raise exception.Create('allocunitedarray: dynamicarray not nil'); + end; + if count > 0 then begin + getmem(po1,count * itemsize + 2 * sizeof(sizeint)); + po1^:= 1; //refcount + {$ifdef FPC} + psizeint(pchar(po1)+sizeof(sizeint))^:= count - 1; //high + {$else} + psizeint(pchar(po1)+sizeof(sizeint))^:= count; //count + {$endif} + pointer(dynamicarray):= pointer(pchar(po1) + 2 * sizeof(sizeint)); + end; +end; +{$warnings on} + +procedure reallocuninitedarray(count,itemsize: integer; var dynamicarray); + //does not init memory, dynamicarray must be unique +var + po1: psizeint; +begin + po1:= pointer(dynamicarray); + if po1 <> nil then begin + po1:= pointer(pchar(po1) - 2 * sizeof(sizeint)); + if po1^ <> 1 then begin + raise exception.Create('reallocunitedarray: dynamicarray not unique'); + end; + end + else begin + allocuninitedarray(count,itemsize,dynamicarray); + exit; + end; + if count = 0 then begin + freemem(po1); + pointer(dynamicarray):= nil; + end + else begin + reallocmem(po1,count * itemsize + 2 * sizeof(sizeint)); + {$ifdef FPC} + psizeint(pchar(po1)+sizeof(sizeint))^:= count - 1; //high + {$else} + psizeint(pchar(po1)+sizeof(sizeint))^:= count; //count + {$endif} + pointer(dynamicarray):= pointer(pchar(po1) + 2 * sizeof(sizeint)); + end; +end; + +procedure freeuninitedarray(var dynamicarray); + //does not finalize items, dynamicarray must be unique! +var + po1: psizeint; +begin + po1:= pointer(dynamicarray); + if po1 <> nil then begin + po1:= pointer(pchar(po1) - 2 * sizeof(sizeint)); + if po1^ <> 1 then begin + raise exception.Create('reallocunitedarray: dynamicarray not unique'); + end; + freemem(po1); + pointer(dynamicarray):= nil; + end; +end; + +function firstitem(const source: stringarty): string; overload; +begin + if length(source) > 0 then begin + result:= source[0]; + end + else begin + result:= ''; + end; +end; + +function firstitem(const source: msestringarty): msestring; overload; +begin + if length(source) > 0 then begin + result:= source[0]; + end + else begin + result:= ''; + end; +end; + +function additem(var dest: stringarty; const value: string; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: stringararty; const value: stringarty; + var count: integer): boolean; overload; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: msestringarty; const value: msestring; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: msestringararty; const value: msestringarty; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: lstringarty; const value: lstringty; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: lmsestringarty; const value: lmsestringty; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; +function additem(var dest: int16arty; const value: int16; + var count: integer): boolean; overload; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: integerarty; const value: integer; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: longwordarty; const value: longword; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: realarty; const value: real; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: pointerarty; const value: pointer; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +{$ifndef FPC} +function addpointeritem(var dest: pointerarty; const value: pointer; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+step+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; +{$endif} + +function additem(var dest: winidarty; const value: winidty; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +procedure additem(var dest: stringarty; const value: string); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: msestringarty; const value: msestring); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: doublemsestringarty; + const valuea,valueb: msestring); +begin + setlength(dest,high(dest)+2); + with dest[high(dest)] do begin + a:= valuea; + b:= valueb; + end; +end; + +procedure additem(var dest: msestringararty; + const value: msestringarty); overload; +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: int16arty; const value: int16); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: integerarty; const value: integer); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: int64arty; const value: int64); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: card64arty; const value: card64); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: longwordarty; const value: longword); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: longboolarty; const value: longbool); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: booleanarty; const value: boolean); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: realarty; const value: real); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: pointerarty; const value: pointer); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: winidarty; const value: winidty); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure deleteitem(var dest: stringarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + dest[index]:= ''; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + pointer(dest[high(dest)]):= nil; + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: msestringarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + dest[index]:= ''; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + pointer(dest[high(dest)]):= nil; + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: integerarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: int64arty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: card64arty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: booleanarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: realarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: complexarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: pointerarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: winidarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure insertitem(var dest: integerarty; index: integer; value: integer); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: int64arty; index: integer; value: int64); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: booleanarty; index: integer; + value: boolean); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: longwordarty; index: integer; value: longword); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: realarty; index: integer; value: realty); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: complexarty; index: integer; value: complexty); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: pointerarty; index: integer; value: pointer); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: winidarty; index: integer; value: winidty); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: stringarty; index: integer; value: string); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + pointer(dest[index]):= nil; + dest[index]:= value; +end; + +procedure insertitem(var dest: msestringarty; index: integer; value: msestring); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + pointer(dest[index]):= nil; + dest[index]:= value; +end; + +procedure removeitems(var dest: pointerarty; const aitem: pointer); + //removes all matching items +var + int1,int2: integer; + ar1: pointerarty; +begin + setlength(ar1,length(dest)); + int2:= 0; + for int1:= 0 to high(dest) do begin + if dest[int1] <> aitem then begin + ar1[int2]:= dest[int1]; + inc(int2); + end; + end; + setlength(ar1,int2); + dest:= ar1; +end; + +function removeitem(var dest: pointerarty; const aitem: pointer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(dest) do begin + if dest[int1] = aitem then begin + result:= int1; + deleteitem(dest,int1); + break; + end; + end; +end; + +function isequalarray(const a: integerarty; const b: integerarty): boolean; +var + int1: integer; + po1,po2: pintegeraty; +begin + result:= pointer(a) = pointer(b); + if not result and (high(a) = high(b)) then begin + po1:= pointer(a); + po2:= pointer(b); + for int1:= high(a) downto 0 do begin + if po1^[int1] <> po2^[int1] then begin + exit; + end; + end; + result:= true; + end; +end; + +function finditem(const ar: pointerarty; const aitem: pointer): integer; + //-1 if none +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(ar) do begin + if ar[int1] = aitem then begin + result:= int1; + break; + end; + end; +end; + +procedure moveitem(var dest; const sourceindex: integer; + destindex: integer; const itemsize: integer); overload; +var + po1: pchar; +begin + if (pointer(dest) <> nil) and (destindex <> sourceindex) then begin + getmem(po1,itemsize); + move((pchar(dest)+sourceindex*itemsize)^,po1^,itemsize); + if destindex < sourceindex then begin + move((pchar(dest)+destindex*itemsize)^, + (pchar(dest)+(destindex+1)*itemsize)^, + (sourceindex-destindex)*itemsize); + end + else begin + move((pchar(dest)+(sourceindex+1)*itemsize)^, + (pchar(dest)+sourceindex*itemsize)^, + (destindex-sourceindex)*itemsize); + end; + move(po1^,(pchar(dest)+destindex*itemsize)^,itemsize); + freemem(po1); + end; +end; + +procedure moveitem(var dest: pointerarty; const sourceindex: integer; + destindex: integer); +var + po1: pointer; +begin + po1:= dest[sourceindex]; + deleteitem(dest,sourceindex); + insertitem(dest,destindex,po1); +end; + + +function removeitem(var dest: stringarty; const aitem: string): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(dest) do begin + if dest[int1] = aitem then begin + result:= int1; + deleteitem(dest,int1); + break; + end; + end; +end; + +function finditem(const ar: stringarty; const aitem: string): integer; + //-1 if none +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(ar) do begin + if ar[int1] = aitem then begin + result:= int1; + break; + end; + end; +end; + +procedure moveitem(var dest: stringarty; const sourceindex: integer; + destindex: integer); +var + po1: string; +begin + po1:= dest[sourceindex]; + deleteitem(dest,sourceindex); + insertitem(dest,destindex,po1); +end; + +function removeitem(var dest: msestringarty; const aitem: msestring): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(dest) do begin + if dest[int1] = aitem then begin + result:= int1; + deleteitem(dest,int1); + break; + end; + end; +end; + +function finditem(const ar: msestringarty; const aitem: msestring): integer; + //-1 if none +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(ar) do begin + if ar[int1] = aitem then begin + result:= int1; + break; + end; + end; +end; + +procedure moveitem(var dest: msestringarty; const sourceindex: integer; + destindex: integer); +var + po1: msestring; +begin + po1:= dest[sourceindex]; + deleteitem(dest,sourceindex); + insertitem(dest,destindex,po1); +end; + +function removeitem(var dest: integerarty; const aitem: integer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(dest) do begin + if dest[int1] = aitem then begin + result:= int1; + deleteitem(dest,int1); + break; + end; + end; +end; + +function finditem(const ar: integerarty; const aitem: integer): integer; + //-1 if none +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(ar) do begin + if ar[int1] = aitem then begin + result:= int1; + break; + end; + end; +end; + +procedure moveitem(var dest: integerarty; const sourceindex: integer; + destindex: integer); +var + int1: integer; +begin + int1:= dest[sourceindex]; + deleteitem(dest,sourceindex); + insertitem(dest,destindex,int1); +end; + +function adduniqueitem(var dest: pointerarty; const value: pointer): integer; + //returns index +var + int1: integer; +begin + for int1:= 0 to high(dest) do begin + if dest[int1] = value then begin + result:= int1; + exit; + end; + end; + result:= high(dest) + 1; + setlength(dest,result+1); + dest[result]:= value; +end; + +function addnewitem(var dest: pointerarty; const value: pointer): integer; + //returns index +var + int1: integer; +begin + for int1:= 0 to high(dest) do begin + if dest[int1] = value then begin + result:= -1; + exit; + end; + end; + result:= high(dest) + 1; + setlength(dest,result+1); + dest[result]:= value; +end; + +procedure minmax(const ar: realarty; out minval,maxval: realty); +var + int1: integer; + min1,max1: realty; +begin + min1:= bigreal; + max1:= emptyreal; + for int1:= high(ar) downto 0 do begin + if ar[int1] = emptyreal then begin + min1:= ar[int1]; + end + else begin + if (max1 = emptyreal) or (ar[int1] > max1) then begin + max1:= ar[int1]; + end; + if not (min1 = emptyreal) and (min1 > ar[int1]) then begin + min1:= ar[int1]; + end; + end; + end; + minval:= min1; + maxval:= max1; +end; + +function stackarfunc(const ar1,ar2: integerarty): integerarty; +begin + setlength(result,length(ar1) + length(ar2)); + move(ar1[0],result[0],length(ar1)*sizeof(ar1[0])); + move(ar2[0],result[length(ar1)],length(ar2)*sizeof(ar2[0])); +end; + +procedure stackarray(const source: stringarty; var dest: stringarty); +var + laengevorher: integer; + int1: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + for int1:= 0 to high(source) do begin + dest[laengevorher]:= source[int1]; + inc(laengevorher); + end; +end; + +procedure stackarray(const source: msestringarty; var dest: msestringarty); +var + laengevorher: integer; + int1: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + for int1:= 0 to high(source) do begin + dest[laengevorher]:= source[int1]; + inc(laengevorher); + end; +end; + +procedure stackarray(const source: integerarty; var dest: integerarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(source[0],dest[laengevorher],length(source)*sizeof(source[0])); +end; + +procedure stackarray(const source: longwordarty; var dest: longwordarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(source[0],dest[laengevorher],length(source)*sizeof(source[0])); +end; + +procedure stackarray(const source: pointerarty; var dest: pointerarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(source[0],dest[laengevorher],length(source)*sizeof(source[0])); +end; + +procedure stackarray(const source: winidarty; var dest: winidarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(source[0],dest[laengevorher],length(source)*sizeof(source[0])); +end; + +procedure insertarray(const source: integerarty; var dest: integerarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(dest[0],dest[length(source)],laengevorher*sizeof(dest[0])); + move(source[0],dest[0],length(source)*sizeof(source[0])); +end; + +procedure stackarray(const source: realarty; var dest: realarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(source[0],dest[laengevorher],length(source)*sizeof(source[0])); +end; + +procedure insertarray(const source: realarty; var dest: realarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(dest[0],dest[length(source)],laengevorher*sizeof(dest[0])); + move(source[0],dest[0],length(source)*sizeof(source[0])); +end; + +function reversearray(const source: msestringarty): msestringarty; +var + ar1: msestringarty; + int1,int2: integer; +begin +{$warnings off} + if pointer(source) = pointer(result) then begin + ar1:= copy(source); + end + else begin + ar1:= source; + end; + int2:= high(ar1); + setlength(result,int2+1); + for int1:= 0 to int2 do begin + result[int1]:= ar1[int2]; + dec(int2); + end; +end; +{$warnings on} + +function reversearray(const source: integerarty): integerarty; overload; +var + ar1: integerarty; + int1,int2: integer; +begin +{$warnings off} + if pointer(source) = pointer(result) then begin + ar1:= copy(source); + end + else begin + ar1:= source; + end; + int2:= high(ar1); + setlength(result,int2+1); + for int1:= 0 to int2 do begin + result[int1]:= ar1[int2]; + dec(int2); + end; +end; +{$warnings on} + +function reversearray(const source: pointerarty): pointerarty; overload; +var + ar1: pointerarty; + int1,int2: integer; +begin +{$warnings off} + if pointer(source) = pointer(result) then begin + ar1:= copy(source); + end + else begin + ar1:= source; + end; + int2:= high(ar1); + setlength(result,int2+1); + for int1:= 0 to int2 do begin + result[int1]:= ar1[int2]; + dec(int2); + end; +end; +{$warnings on} + +procedure removearrayduplicates(var value: pointerarty); +var + int1,int2: integer; +begin + for int1:= 0 to high(value) do begin //remove duplicates + if value[int1] <> nil then begin + for int2:= int1 + 1 to high(value) do begin + if value[int2] = value[int1] then begin + value[int2]:= nil + end; + end; + end; + end; + int2:= 0; + for int1:= 0 to high(value) do begin + if value[int1] <> nil then begin + value[int2]:= value[int1]; + inc(int2); + end; + end; + setlength(value,int2); +end; + +function packarray(source: pointerarty): pointerarty; //removes nil items +var + int1,int2: integer; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 0 to high(source) do begin + result[int2]:= source[int1]; + if source[int1] <> nil then begin + inc(int2); + end; + end; + setlength(result,int2); +end; + +function packarray(source: msestringarty): msestringarty; +var + int1,int2: integer; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 0 to high(source) do begin + result[int2]:= source[int1]; + if source[int1] <> '' then begin + inc(int2); + end; + end; + setlength(result,int2); +end; + +procedure checkarrayindex(const value; const index: integer); + //value = dynamic array, exception bei ungueltigem index +begin + if (index < 0) or (index > high(bytearty(value))) then begin + raise exception.Create('Invalid arrayindex: '+inttostr(index)+ ' max: ' + + inttostr(high(bytearty(value)))+'.'); + end; +end; + +procedure checkarrayindexcount(const count: int32; const index: int32); +begin + if (index < 0) or (index >= count) then begin + raise exception.Create('Invalid arrayindex: '+inttostr(index)+ ' max: ' + + inttostr(count-1)+'.'); + end; +end; + +type + sortinfoty = record + indexlist: integerarty; + sortlist: pchar; + compare: arraysortcomparety; + size: integer; + end; + +function findarrayvalue(const item; const items; + const itemsize: integer; const count: integer; + const compare: arraysortcomparety; + out foundindex: integer): boolean; + //true if exact else next bigger + //for compare: l is item, r are tablevalues +var + ilo,ihi:integer; + int1,int2: integer; +// bo1: boolean; +begin + foundindex:= count; + result:= false; + if foundindex > 0 then begin + ilo:= 0; + ihi:= foundindex - 1; +// bo1:= false; + while true do begin + int1:= (ilo + ihi) div 2; + int2:= compare(item,(pchar(items)+int1*itemsize)^); + if int2 >= 0 then begin //item <= pivot + if int2 = 0 then begin + result:= true; //found + end; + if ihi = ilo then begin + foundindex:= ihi + 1; + break; + end; + if ilo = int1 then begin + inc(ilo); + end + else begin + ilo:= int1; + end; + end + else begin //item > pivot + if ihi = ilo then begin + foundindex:= ihi; + break; + end; + ihi:= int1; + end; + end; + if result then begin + dec(foundindex); + end; + end; +end; + +function findarrayitem(const item; const ar; const itemsize: integer; + const compare: arraysortcomparety; + out foundindex: integer): boolean; + //ar = array of type + //true if exact else next bigger + //for compare: l is item, r are tablevalues +begin + result:= findarrayvalue(item,ar,itemsize,length(pointerarty(ar)), + compare,foundindex); +end; + +function findarrayvalue(const item; const items; const itemsize: integer; + const index: integerarty; + const compare: arraysortcomparety; + out foundindex: integer): boolean; + //true if exact else next bigger + //for compare: l is item, r are tablevalues +var + ilo,ihi:integer; + int1,int2: integer; +// bo1: boolean; +begin + foundindex:= length(index); + result:= false; + if foundindex > 0 then begin + ilo:= 0; + ihi:= foundindex - 1; +// bo1:= false; + while true do begin + int1:= (ilo + ihi) div 2; + int2:= compare(item,(pchar(items)+index[int1]*itemsize)^); + if int2 >= 0 then begin //item <= pivot + if int2 = 0 then begin + result:= true; //found + end; + if ihi = ilo then begin + foundindex:= ihi + 1; + break; + end; + if ilo = int1 then begin + inc(ilo); + end + else begin + ilo:= int1; + end; + end + else begin //item > pivot + if ihi = ilo then begin + foundindex:= ihi; + break; + end; + ihi:= int1; + end; + end; + if result then begin + dec(foundindex); + end; + end; +end; + +function findarrayitem(const item; const ar: pointerarty; + const compare: sortcomparemethodty; + out foundindex: integer): boolean; overload; + //ar = sorted array of type + //true if exact else next bigger + //for compare: l is item, r are tablevalues +var + ilo,ihi:integer; + int1,int2: integer; +// bo1: boolean; +begin + foundindex:= length(ar); + result:= false; + if foundindex > 0 then begin + ilo:= 0; + ihi:= foundindex - 1; +// bo1:= false; + while true do begin + int1:= (ilo + ihi) div 2; + int2:= compare(item,ar[int1]^); + if int2 >= 0 then begin //item <= pivot + if int2 = 0 then begin + result:= true; //found + end; + if ihi = ilo then begin + foundindex:= ihi + 1; + break; + end; + if ilo = int1 then begin + inc(ilo); + end + else begin + ilo:= int1; + end; + end + else begin //item > pivot + if ihi = ilo then begin + foundindex:= ihi; + break; + end; + ihi:= int1; + end; + end; + if result then begin + dec(foundindex); + end; + end; +end; + +function comparepointer(const l,r): integer; +var + pint1: ptrint; +begin + result:= 1; + pint1:= ptrint(l) - ptrint(r); + if pint1 < 0 then begin + result:= -1 + end + else begin + if pint1 = 0 then begin + result:= 0; + end; + end; +end; + +function compareinteger(const l,r): integer; +begin + result:= integer(l) - integer(r); +end; + +function compareint64(const l,r): integer; +begin + result:= int64(l) - int64(r); +end; + +function comparecard64(const l,r): integer; +begin + result:= card64(l) - card64(r); +end; + +procedure doquicksortpointer(const compare: pointercomparefuncty; + l, r: ppointer); +var + poi, poj: ppointer; + pop: ppointer; + po1: ppointer; + int1: integer; +begin + repeat + poi := l; + poj := r; + pop := pointer((ptruint(l) div 2 + ptruint(r) div 2) and pointeralignmask); + //pivot element + repeat + while true do begin + int1:= compare(poi^,pop^); + if int1 = 0 then begin + int1:= poi-pop; + end; + if int1 >= 0 then break; + inc(poi); + end; + while true do begin + int1:= compare(poj^,pop^); + if int1 = 0 then begin + int1:= poj-pop; + end; + if int1 <= 0 then break; + dec(poj); + end; + if poi <= poj then begin + po1:= poi^; //swap elementm + poi^:= poj^; + poj^:= po1; + if pop = poi then begin + pop:= poj + end + else begin + if pop = poj then begin + pop:= poi; + end; + end; + inc(poi); + dec(poj); + end; + until poi > poj; + if l < poj then begin + doquicksortpointer(compare,l, poj); + end; + l:= poi; + until poi >= r; +end; + +procedure quicksortpointer(const adata: ppointer; const alength: int32; + const acompare: pointercomparefuncty); +begin + if alength > 1 then begin + doquicksortpointer(acompare,adata,adata+alength-1); + end; +end; + +procedure mergesortarray(var asortlist; const aitemsize,alength: integer; + const acompare: arraysortcomparety; + out aindexlist: integerarty; const order: boolean); + //asortlist = array of type + //todo: optimize +var + ar1: integerarty; + step: integer; + l,r,d: pinteger; + stopl,stopr,stops: pinteger; + source,dest: pinteger; + int1: integer; + po1: pchar; +label + endstep; +begin + aindexlist:= nil; + if alength = 0 then begin + exit; + end; + po1:= pointer(asortlist); + allocuninitedarray(alength,sizeof(integer),ar1); + allocuninitedarray(alength,sizeof(integer),aindexlist); + for int1:= alength-1 downto 0 do begin + aindexlist[int1]:= int1; + end; + source:= pointer(aindexlist); + dest:= pointer(ar1); + step:= 1; + while step < alength do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source+step; + {$else} + r:= pointer(pchar(source)+step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + alength; + {$else} + stops:= pointer(pchar(source) + alength*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while acompare((po1+l^*aitemsize)^,(po1+r^*aitemsize)^) <= 0 do begin + //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while acompare((po1+l^*aitemsize)^,(po1+r^*aitemsize)^) > 0 do begin + //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(aindexlist) then begin + aindexlist:= ar1; + end; + if order then begin + orderarray(aindexlist,asortlist,aitemsize); + end; +end; + + +(* +procedure mergesort(var adata: pointerarty; const acount: integer; + const compare: pointercomparemethodty); + //todo: optimize +var + ar1: pointerarty; + step: integer; + l,r,d: ppointer; + stopl,stopr,stops: ppointer; + source,dest: ppointer; +label + endstep; +begin + allocuninitedarray(length(adata),sizeof(pointer),ar1); + source:= pointer(adata); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + r:= source + step; + stopl:= r; + stopr:= r+step; + stops:= source + acount; + if stopr > stops then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while compare(l^,r^) <= 0 do begin //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while compare(l^,r^) > 0 do begin //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + r:= l + step; + if r >= stops then begin + r:= stops-1; + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + stopr:= r + step; + if stopr > stops then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(adata) then begin + adata:= ar1; + end; +end; +*) + +procedure mergesort(const adata: pointer; const aitemsize,acount: integer; + const acompare: sortcomparemethodty; + out aindexlist: integerarty); + //todo: optimize +var + ar1: integerarty; + step: integer; + l,r,d: pinteger; + stopl,stopr,stops: pinteger; + source,dest: pinteger; + int1: integer; + po1: pchar; +label + endstep; +begin + aindexlist:= nil; + if acount = 0 then begin + exit; + end; + po1:= pointer(adata); + allocuninitedarray(acount,sizeof(integer),ar1); + allocuninitedarray(acount,sizeof(integer),aindexlist); + for int1:= acount-1 downto 0 do begin + aindexlist[int1]:= int1; + end; + source:= pointer(aindexlist); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source+step; + {$else} + r:= pointer(pchar(source)+step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + acount; + {$else} + stops:= pointer(pchar(source) + acount*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while acompare((po1+l^*aitemsize)^,(po1+r^*aitemsize)^) <= 0 do begin + //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while acompare((po1+l^*aitemsize)^,(po1+r^*aitemsize)^) > 0 do begin + //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(aindexlist) then begin + aindexlist:= ar1; + end; +end; + +procedure mergesortoffset(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out aoffsetlist: integerarty); + //todo: optimize +var + ar1: integerarty; + step: integer; + l,r,d: pinteger; + stopl,stopr,stops: pinteger; + source,dest: pinteger; + int1: integer; + po1: pchar; +label + endstep; +begin + aoffsetlist:= nil; + if acount = 0 then begin + exit; + end; + po1:= pointer(adata); + allocuninitedarray(acount,sizeof(integer),ar1); + allocuninitedarray(acount,sizeof(integer),aoffsetlist); + for int1:= acount-1 downto 0 do begin + aoffsetlist[int1]:= int1*asize; + end; + source:= pointer(aoffsetlist); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source+step; + {$else} + r:= pointer(pchar(source)+step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + acount; + {$else} + stops:= pointer(pchar(source) + acount*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while acompare((po1+l^{*asize})^,(po1+r^{*asize})^) <= 0 do begin + //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while acompare((po1+l^{*asize})^,(po1+r^{*asize})^) > 0 do begin + //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(aoffsetlist) then begin + aoffsetlist:= ar1; + end; +end; + +procedure mergesortpointer(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out apointerlist: pointerarty); + //todo: optimize +var + ar1: pointerarty; + step: integer; + l,r,d: ppointer; + stopl,stopr,stops: ppointer; + source,dest: ppointer; + int1: integer; +// po1: pchar; +label + endstep; +begin + apointerlist:= nil; + if acount = 0 then begin + exit; + end; +// po1:= pointer(adata); + allocuninitedarray(acount,sizeof(pointer),ar1); + allocuninitedarray(acount,sizeof(pointer),apointerlist); + for int1:= acount-1 downto 0 do begin + apointerlist[int1]:= pchar(adata)+int1*asize; + end; + source:= pointer(apointerlist); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source+step; + {$else} + r:= pointer(pchar(source)+step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + acount; + {$else} + stops:= pointer(pchar(source) + acount*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while acompare(({po1+}l^{*asize})^,({po1+}r^{*asize})^) <= 0 do begin + //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while acompare(({po1+}l^{*asize})^,({po1+}r^{*asize})^) > 0 do begin + //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(apointerlist) then begin + apointerlist:= ar1; + end; +end; + +procedure checkrefmoved(const aindexlist: integerarty; var refindex: integer; + out moved: boolean); +var + int1,int2,int3: integer; + bo1: boolean; +begin + int2:= refindex; + bo1:= false; + for int1:= high(aindexlist) downto 0 do begin + int3:= aindexlist[int1]; + if not bo1 then begin + bo1:= int3 <> int1; + end; + if int3 = int2 then begin + refindex:= int1; + if bo1 then begin + break; + end; + end; + end; + moved:= bo1; +end; + +procedure mergesort(var adata: pointer; const aitemsize,acount: integer; + const acompare: sortcomparemethodty); +var + ar1: integerarty; + ps,pd,po1: pointer; + int1: integer; +begin + mergesort(adata,aitemsize,acount,acompare,ar1); + pd:= getmem(aitemsize*acount); + po1:= pd; + ps:= adata; + for int1:= 0 to high(ar1) do begin + move((ps+ar1[int1])^,po1^,aitemsize); + inc(po1,aitemsize); + end; + freemem(ps); + adata:= pd; +end; + +procedure mergesort(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out aindexlist: integerarty; + var refindex: integer; out moved: boolean); +begin + mergesort(adata,asize,acount,acompare,aindexlist); + checkrefmoved(aindexlist,refindex,moved); +end; + +procedure mergesort(const acount: integer; + const acompare: indexsortcomparemethodty; out aindexlist: integerarty); + //todo: optimize +var + ar1: integerarty; + step: integer; + l,r,d: pinteger; + stopl,stopr,stops: pinteger; + source,dest: pinteger; + int1: integer; +label + endstep; +begin + aindexlist:= nil; + if acount = 0 then begin + exit; + end; + allocuninitedarray(acount,sizeof(integer),ar1); + allocuninitedarray(acount,sizeof(integer),aindexlist); + for int1:= acount-1 downto 0 do begin + aindexlist[int1]:= int1; + end; + source:= pointer(aindexlist); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source+step; + {$else} + r:= pointer(pchar(source)+step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + acount; + {$else} + stops:= pointer(pchar(source) + acount*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while acompare(l^,r^) <= 0 do begin + //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while acompare(l^,r^) > 0 do begin + //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(aindexlist) then begin + aindexlist:= ar1; + end; +end; + +procedure mergesort(const acount: integer; + const acompare: indexsortcomparemethodty; out aindexlist: integerarty; + var refindex: integer; out moved: boolean); overload; +begin + mergesort(acount,acompare,aindexlist); + checkrefmoved(aindexlist,refindex,moved); +end; + +procedure mergesort(var adata: pointerarty; const acount: integer; + const compare: pointercomparemethodty); +var + ar1: pointerarty; + step: integer; + l,r,d: ppointer; + stopl,stopr,stops: ppointer; + source,dest: ppointer; +label + endstep; +begin + allocuninitedarray(length(adata),sizeof(pointer),ar1); + source:= pointer(adata); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source + step; + {$else} + r:= pointer(pchar(source) + step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + acount; + {$else} + stops:= pointer(pchar(source) + acount*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while compare(l^,r^) <= 0 do begin //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while compare(l^,r^) > 0 do begin //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + if source <> pointer(adata) then begin + adata:= ar1; + end; +end; + +const + adsize = 2*sizeof(sizeint); + +function initorderbuffer(var sortlist; const size: integer; clear: boolean; + out destpo: pchar): boolean; +begin + if pointer(sortlist) = nil then begin + result:= false; + end + else begin + getmem(destpo,size*length(bytearty(sortlist))+adsize); + psizeint(destpo)^:= 1; //refcount + inc(destpo,sizeof(sizeint)); + psizeint(destpo)^:= pinteger(pchar(sortlist)-sizeof(sizeint))^; //length or high + inc(destpo,sizeof(sizeint)); + result:= true; + if clear then begin + fillchar(destpo^,size*length(bytearty(sortlist)),0); + end; + end; +end; + +procedure storebuffer(const asource: pchar; var sortlist); +var + po1: psizeint; +begin + po1:= psizeint(pchar(sortlist) - 2*sizeof(sizeint)); + dec(po1^); + if po1^ >= 0 then begin + if po1^ = 0 then begin + freemem(po1); + end + end + else begin + inc(po1^) //constant + end; + pointer(sortlist):= asource; +end; + +procedure orderarray(const sourceorderlist: integerarty; var sortlist; size: integer); + //sortlist = array of type +var + po2: pchar; + po3: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,size,false,po2) then begin + po3:= po2; + for int1:= 0 to high(sourceorderlist) do begin + move((pchar(sortlist)+sourceorderlist[int1] * size)^,po3^,size); + inc(po3,size); + end; + storebuffer(po2,sortlist); + end; +end; + +procedure reorderarray(const destorderlist: integerarty; var sortlist; size: integer); + //sortlist = array of type +var + po2: pchar; + po3: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,size,false,po2) then begin + po3:= pchar(sortlist); + for int1:= 0 to high(destorderlist) do begin + move(po3^,(po2+destorderlist[int1] * size)^,size); + inc(po3,size); + end; + storebuffer(po2,sortlist); + end; +end; + +procedure orderarray(const sourceorderlist: integerarty; var sortlist: pointerarty); +var + po2: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,sizeof(pointer),false,po2) then begin + for int1:= 0 to high(sourceorderlist) do begin + pointerarty(pointer(po2))[int1]:= sortlist[sourceorderlist[int1]]; + end; + storebuffer(po2,sortlist); + end; +end; + +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: integerarty); +var + po2: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,sizeof(integer),false,po2) then begin + for int1:= 0 to high(sourceorderlist) do begin + integerarty(pointer(po2))[int1]:= sortlist[sourceorderlist[int1]]; + end; + storebuffer(po2,sortlist); + end; +end; + +procedure reorderarray(const destorderlist: integerarty; var sortlist: pointerarty); +var + po2: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,sizeof(pointer),false,po2) then begin + for int1:= 0 to high(destorderlist) do begin + pointerarty(pointer(po2))[destorderlist[int1]]:= sortlist[int1]; + end; + storebuffer(po2,sortlist); + end; +end; + +procedure reorderarray(const destorderlist: integerarty; + var sortlist: integerarty); +var + po2: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,sizeof(integer),false,po2) then begin + for int1:= 0 to high(destorderlist) do begin + integerarty(pointer(po2))[destorderlist[int1]]:= sortlist[int1]; + end; + storebuffer(po2,sortlist); + end; +end; + +procedure orderarray(const sourceorderlist: integerarty; var sortlist: stringarty); +var + ar1: stringarty; + int1: integer; +begin + setlength(ar1,length(sourceorderlist)); + for int1:= 0 to high(sourceorderlist) do begin + ar1[int1]:= sortlist[sourceorderlist[int1]]; + end; + sortlist:= ar1; +end; + +procedure reorderarray(const destorderlist: integerarty; var sortlist: stringarty); +var + ar1: stringarty; + int1: integer; +begin + setlength(ar1,length(destorderlist)); + for int1:= 0 to high(destorderlist) do begin + ar1[destorderlist[int1]]:= sortlist[int1]; + end; + sortlist:= ar1; +end; + +procedure orderarray(const sourceorderlist: integerarty; var sortlist: msestringarty); +var + ar1: msestringarty; + int1: integer; +begin + setlength(ar1,length(sourceorderlist)); + for int1:= 0 to high(sourceorderlist) do begin + ar1[int1]:= sortlist[sourceorderlist[int1]]; + end; + sortlist:= ar1; +end; + +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: msestringararty); overload; +var + ar1: msestringararty; + int1: integer; +begin + setlength(ar1,length(sourceorderlist)); + for int1:= 0 to high(sourceorderlist) do begin + ar1[int1]:= sortlist[sourceorderlist[int1]]; + end; + sortlist:= ar1; +end; + +procedure reorderarray(const destorderlist: integerarty; var sortlist: msestringarty); +var + ar1: msestringarty; + int1: integer; +begin + setlength(ar1,length(destorderlist)); + for int1:= 0 to high(destorderlist) do begin + ar1[destorderlist[int1]]:= sortlist[int1]; + end; + sortlist:= ar1; +end; + +procedure sortarray(var sortlist; const itemsize: integer; + const compare: arraysortcomparety; + out indexlist: integerarty); +begin + mergesortarray(sortlist,itemsize,length(bytearty(sortlist)), + compare,indexlist,true); +end; + +procedure sortarray(var sortlist; const itemsize: integer; + const compare: arraysortcomparety); +var + indexlist: integerarty; +begin + sortarray(sortlist,itemsize,compare,indexlist); +end; + +procedure sortarray(var dest: pointerarty; const compare: arraysortcomparety; + out indexlist: integerarty); +begin + mergesortarray(dest,sizeof(pointer),length(dest),compare,indexlist,false); + orderarray(indexlist,dest); +end; + +procedure sortarray(var dest: pointerarty; const compare: arraysortcomparety); +var + ar1: pointerarty; + step: integer; + l,r,d: ppointer; + stopl,stopr,stops: ppointer; + sourcepo,destpo: ppointer; + acount: integer; +label + endstep; +begin + allocuninitedarray(length(dest),sizeof(pointer),ar1); + sourcepo:= pointer(dest); + destpo:= pointer(ar1); + step:= 1; + acount:= length(dest); + while step < acount do begin + d:= destpo; + l:= sourcepo; + {$ifdef FPC} + r:= sourcepo + step; + {$else} + r:= pointer(pchar(sourcepo) + step*sizeof(sourcepo^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= sourcepo + acount; + {$else} + stops:= pointer(pchar(sourcepo) + acount*sizeof(sourcepo^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while compare(l^,r^) <= 0 do begin //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while compare(l^,r^) > 0 do begin //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= sourcepo; //swap buffer + sourcepo:= destpo; + destpo:= d; + step:= step*2; + end; + if sourcepo <> pointer(dest) then begin + dest:= ar1; + end; +end; + +{ +procedure sortarray(var dest: pointerarty; const compare: arraysortcomparety); +var + indexlist: integerarty; +begin + sortarray(dest,compare,indexlist); +end; +} +procedure sortarray(var dest: msestringarty; const compare: arraysortcomparety; + out indexlist: integerarty); +begin + mergesortarray(dest,sizeof(pointer),length(dest),compare,indexlist,false); + orderarray(indexlist,dest); +end; + +procedure sortarray(var dest: msestringarty; const compare: arraysortcomparety); +var + indexlist: integerarty; +begin + sortarray(dest,compare,indexlist); +end; + +procedure sortarray(var dest: stringarty; const compare: arraysortcomparety; + out indexlist: integerarty); +begin + mergesortarray(dest,sizeof(pointer),length(dest),compare,indexlist,false); + orderarray(indexlist,dest); +end; + +procedure sortarray(var dest: stringarty; const compare: arraysortcomparety); +var + indexlist: integerarty; +begin + sortarray(dest,compare,indexlist); +end; + +procedure sortarray(var dest: pointerarty); +begin + sortarray(dest,sizeof(pointer),{$ifdef FPC}@{$endif}comparepointer); +end; + +procedure sortarray(var dest: integerarty); +begin + sortarray(dest,sizeof(integer),{$ifdef FPC}@{$endif}compareinteger); +end; + +procedure sortarray(var dest: integerarty; out indexlist: integerarty); +begin + sortarray(dest,sizeof(integer),{$ifdef FPC}@{$endif}compareinteger,indexlist); +end; + +function comparelongword(const l,r): integer; +begin + if longword(l) > longword(r) then begin + result:= 1; + end + else begin + if longword(l) < longword(r) then begin + result:= -1; + end + else begin + result:= 0; + end; + end; +end; + +procedure sortarray(var dest: longwordarty); +begin + sortarray(dest,sizeof(longword),{$ifdef FPC}@{$endif}comparelongword); +end; + +procedure sortarray(var dest: longwordarty; out indexlist: integerarty); +begin + sortarray(dest,sizeof(longword),{$ifdef FPC}@{$endif}comparelongword,indexlist); +end; + +function comparereal(const l,r): integer; +var + rea1: real; +begin + rea1:= real(l) - real(r); + if rea1 < 0 then begin + result:= -1; + end + else begin + if rea1 > 0 then begin + result:= 1; + end + else begin + result:= 0; + end; + end; +end; + +function comparerealty(const l,r): integer; +begin + result:= cmprealty(realty(l),realty(r)); +end; + +procedure sortarray(var dest: realarty); overload; +begin + sortarray(dest,sizeof(realty),{$ifdef FPC}@{$endif}comparerealty); +end; + +procedure sortarray(var dest: realarty; out indexlist: integerarty); overload; +begin + sortarray(dest,sizeof(realty),{$ifdef FPC}@{$endif}comparerealty,indexlist); +end; + +function comparemsestring(const l,r): integer; +begin +// {$ifdef FPC} +// result:= comparestr(msestring(l),msestring(r)); //!!!todo optimize +// {$else} + result:= msecomparestr(msestring(l),msestring(r)); +// {$endif} +end; + +function compareimsestring(const l,r): integer; +begin +// {$ifdef FPC} +// result:= comparetext(msestring(l),msestring(r)); +// {$else} + result:= msecomparetext(msestring(l),msestring(r)); +// {$endif} +end; +{ +function compareasciistring(const l,r): integer; +begin + result:= stringcomp(string(l),string(r)); +// result:= comparestr(ansistring(l),ansistring(r)); +end; + +function compareiasciistring(const l,r): integer; +begin + result:= stringicomp(string(l),string(r)); +// result:= comparetext(ansistring(l),ansistring(r)); +end; +} + +function compareasciistring(const l,r): integer; +var + by1: byte; + po1,po2: pchar; +begin + po1:= pointer(string(l)); + po2:= pointer(string(r)); + if po1 = nil then begin + if po2 = nil then begin + result:= 0; + exit; + end; + result:= -1; + exit; + end; + if po2 = nil then begin + result:= 1; + exit; + end; + while true do begin + by1:= byte(po1^)-byte(po2^); + if (by1 <> 0) or (po1^ = #0) or (po2^=#0) then begin + break; + end; + inc(po1); + inc(po2); + end; + result:= shortint(by1); +end; + +function compareiasciistring(const l,r): integer; +var + by1: byte; + po1,po2: pchar; +begin + po1:= pointer(string(l)); + po2:= pointer(string(r)); + if po1 = nil then begin + if po2 = nil then begin + result:= 0; + exit; + end; + result:= -1; + exit; + end; + if po2 = nil then begin + result:= 1; + exit; + end; + while true do begin + by1:= byte(upperchars[po1^])-byte(upperchars[po2^]); + if (by1 <> 0) or (po1^ = #0) or (po2^=#0) then begin + break; + end; + inc(po1); + inc(po2); + end; + result:= shortint(by1); +end; + +function compareansistring(const l,r): integer; +begin + result:= ansicomparestr(ansistring(l),ansistring(r)); +end; + +function compareiansistring(const l,r): integer; +begin + result:= ansicomparetext(ansistring(l),ansistring(r)); +end; + +procedure sortarray(var dest: msestringarty; + const sortmode: stringsortmodety = sms_up); +begin + setlength(dest,length(dest)); //refcount1 + case sortmode of + sms_up: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}comparemsestring); + sms_upi: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareimsestring); + end; +end; + +procedure sortarray(var dest: msestringarty; const sortmode: stringsortmodety; + out indexlist: integerarty); +begin + setlength(dest,length(dest)); //refcount1 + case sortmode of + sms_up: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}comparemsestring,indexlist); + sms_upi: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareimsestring,indexlist); + end; +end; + +procedure sortarray(var dest: stringarty; + const sortmode: stringsortmodety = sms_upascii); +begin + setlength(dest,length(dest)); //refcount1 + case sortmode of + sms_up: sortarray(pointerarty(dest),{$ifdef FPC}@{$endif}compareansistring); + sms_upi: sortarray(pointerarty(dest),{$ifdef FPC}@{$endif}compareiansistring); + sms_upascii: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareasciistring); + sms_upiascii: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareiasciistring); + end; +end; + +procedure sortarray(var dest: stringarty; const sortmode: stringsortmodety; + out indexlist: integerarty); +begin + setlength(dest,length(dest)); //refcount1 + case sortmode of + sms_up: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareansistring,indexlist); + sms_upi: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareiansistring,indexlist); + sms_upascii: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareasciistring,indexlist); + sms_upiascii: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareiasciistring,indexlist); + end; +end; + +function cmparray(const a,b: msestringarty): boolean; + //true if equal +var + int1: integer; +begin + result:= a = b; + if not result and (high(a) = high(b)) then begin + for int1:= 0 to high(a) do begin + if a[int1] <> b[int1] then begin + exit; + end; + end; + result:= true; + end; +end; + +function opentodynarraym(const items: array of msestring): msestringarty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function opentodynarrays(const items: array of string): stringarty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function opentodynarrayi(const items: array of integer): integerarty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function opentodynarrayr(const items: array of realty): realarty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function opentodynarraybo(const items: array of boolean): booleanarty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function opentodynarrayby(const items: array of byte): bytearty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function dynarraytovararray(const avalue: int64arty): tvarrecarty; +var + i1: integer; +begin + result:= nil; //compiler warning + allocuninitedarray(length(avalue),sizeof(result[0]),result); + for i1:= 0 to high(avalue) do begin + with result[i1] do begin + vtype:= vtint64; + vint64:= @avalue[i1]; + end; + end; +end; + +procedure copytore(const source: realarty; var dest: complexarty); +var + ps,pe: preal; + pd: pcomplexty; +begin + setlength(dest,length(source)); + if source <> nil then begin + ps:= pointer(source); + pe:= ps+length(dest); + pd:= pointer(dest); + repeat + pd^.re:= ps^; + inc(pd); + inc(ps); + until ps = pe; + end; +end; + +procedure copytoim(const source: realarty; var dest: complexarty); +var + ps,pe: preal; + pd: pcomplexty; +begin + setlength(dest,length(source)); + if source <> nil then begin + ps:= pointer(source); + pe:= ps+length(source); + pd:= pointer(preal(pointer(dest))+1); + repeat + pd^.re:= ps^; + inc(pd); + inc(ps); + until ps = pe; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseassistiveclient.pas b/mseide-msegui/lib/common/kernel/mseassistiveclient.pas new file mode 100644 index 0000000..0f99ebb --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseassistiveclient.pas @@ -0,0 +1,80 @@ +{ MSEgui Copyright (c) 2015-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseassistiveclient; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +interface +uses + msestrings,mseglob,mseinterfaces,msetypes,mseificompglob; +type + assistiveflagty = (asf_embedded,asf_container,asf_toplevel,asf_mainwindow, + asf_dummy, + asf_grid,asf_widgetgrid, + asf_gridcell, + asf_widgetcell, + asf_gridwidget, //implies iassistiveclientgridwidget + asf_datetime,asf_menu,asf_message,asf_popup, + asf_textedit,asf_graphicedit,asf_readonly, + asf_inplaceedit,asf_button,asf_dispwidget,asf_db, + asf_scrolllimit, + asf_focused,asf_disabled,asf_hasdropdown,asf_async); + assistiveflagsty = set of assistiveflagty; + + iassistiveclient = interface(inullinterface)[miid_iassistiveclient] + function getassistiveparent(): iassistiveclient; + function getinstance: tobject; + function getassistivewidget: tobject; //twidget, can be nil + function getassistivename(): msestring; + function getassistivecaption(): msestring; + function getassistivetext(): msestring; + function getassistivecaretindex(): int32; //-1 -> none + function getassistivehint(): msestring; + function getassistiveflags(): assistiveflagsty; + {$ifdef mse_with_ifi} + function getifidatalinkintf(): iifidatalink; //can be nil + {$endif} + end; + + assistivegridinfoty = record + colmin: int32; + colmax: int32; + rowmin: int32; + rowmax: int32; + end; + + iassistiveclientgrid = interface(iassistiveclient)[miid_iassistiveclientgrid] + function getassistivecellcaption(const acell: gridcoordty): msestring; + function getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring; + function getassistivefocusedcell(): gridcoordty; + function getassistivegridinfo(): assistivegridinfoty; + end; + + iassistiveclientedit = interface(iassistiveclient)[miid_iassistiveclientedit] + end; + + iassistiveclientdata = interface(iassistiveclient)[miid_iassistiveclientdata] + end; + + iassistiveclientgridwidget = interface(iassistiveclientdata) + [miid_iassistiveclientgridwidget] + function getassistivecolumncaption(): msestring; + end; + + iassistiveclientmenu = interface(iassistiveclient)[miid_iassistiveclientmenu] + function getassistiveselfcaption(): msestring; + function getassistiveselfname(): msestring; + function getassistiveselfhint(): msestring; + end; + +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/mseassistiveserver.pas b/mseide-msegui/lib/common/kernel/mseassistiveserver.pas new file mode 100644 index 0000000..798217d --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseassistiveserver.pas @@ -0,0 +1,104 @@ +{ MSEgui Copyright (c) 2015-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseassistiveserver; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseguiglob,mseglob,msestrings,mseinterfaces,mseact,mseshapes, + mseassistiveclient,msemenuwidgets,msegrids,msetypes,msegraphutils; + +type + + editinputmodety = (eim_insert,eim_overwrite); + edittextblockmodety = (etbm_delete,etbm_cut,etbm_copy,etbm_insert,etbm_paste); + assistiveoptionty = ( + aso_textfirst, + aso_nodefaultbutton, + aso_noreturnbutton, //do not execute button by return key + aso_returntogglevalue, //ttogglegtraphdataedit togglevalue by return key + aso_tabnavig,aso_widgetnavig,aso_nearestortho, + aso_menunavig,aso_gridnavig, + aso_noreturnkeymenuexecute, + aso_nomenumousemove, + aso_nogridmousemove, + aso_saverate,aso_savevolume, + aso_savelanguage,aso_savegender,aso_saveage, + aso_savepitch,aso_saverange, + aso_savecapitals,aso_savewordgap + ); + + assistiveoptionsty = set of assistiveoptionty; + assistivedbeventkindty = (adek_none,adek_bof,adek_eof); +const + defaultassistiveoptions = [aso_textfirst,aso_nodefaultbutton, + aso_returntogglevalue, + aso_tabnavig,aso_widgetnavig, + aso_menunavig,aso_gridnavig, + aso_noreturnkeymenuexecute, + aso_nomenumousemove,aso_nogridmousemove]; + +type + iassistiveserver = interface(inullinterface)[miid_iassistiveserver] + procedure doapplicationactivated(); + procedure doapplicationdeactivated(); + procedure dowindowactivated(const sender: iassistiveclient); + procedure dowindowdeactivated(const sender: iassistiveclient); + procedure dowindowclosed(const sender: iassistiveclient); + procedure doenter(const sender: iassistiveclient); + procedure doactivate(const sender: iassistiveclient); + procedure dodeactivate(const sender: iassistiveclient); + procedure doclientmouseevent(const sender: iassistiveclient; + const info: mouseeventinfoty); + procedure dofocuschanged(const sender: iassistiveclient; + const oldwidget,newwidget: iassistiveclient); + procedure dokeydown(const sender: iassistiveclient; + const info: keyeventinfoty); + procedure dochange(const sender: iassistiveclient); + procedure dodbvaluechanged(const sender: iassistiveclientdata); + procedure dodataentered(const sender: iassistiveclientdata); + procedure docellevent(const sender: iassistiveclientgrid; + const info: celleventinfoty); + procedure dogridbordertouched(const sender: iassistiveclientgrid; + const adirection: graphicdirectionty); + + procedure doeditcharenter(const sender: iassistiveclientedit; + const achar: msestring); + procedure doeditchardelete(const sender: iassistiveclientedit; + const achar: msestring); + procedure doeditwithdrawn(const sender: iassistiveclientedit); + procedure doeditindexmoved(const sender: iassistiveclientedit; + const aindex: int32); + procedure doeditinputmodeset(const sender: iassistiveclientedit; + const amode: editinputmodety); + procedure doedittextblock(const sender: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring); + procedure donavigbordertouched(const sender: iassistiveclient; + const adirection: graphicdirectionty); + procedure dotabordertouched(const sender: iassistiveclient; + const adown: boolean); + + procedure doactionexecute(const sender: iassistiveclient;//sender can be nil + const senderobj: tobject; const info: actioninfoty); + procedure doitementer(const sender: iassistiveclient; //sender can be nil + const items: shapeinfoarty; const aindex: integer); + procedure domenuactivated(const sender: iassistiveclientmenu); + procedure doitementer(const sender: iassistiveclientmenu;//sender can be nil + const items: menucellinfoarty; const aindex: integer); + procedure dodatasetevent(const sender: iassistiveclient; + const akind: assistivedbeventkindty; + const adataset: pointer); //tdataset +end; + +var + assistiveserver: iassistiveserver; + assistiveoptions: assistiveoptionsty; + +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/msebintree.pas b/mseide-msegui/lib/common/kernel/msebintree.pas new file mode 100644 index 0000000..ce03128 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msebintree.pas @@ -0,0 +1,870 @@ +{ MSEgui Copyright (c) 2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msebintree; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} +interface +type + tavlnode = class + private + fup: tavlnode; + fleft: tavlnode; + fright: tavlnode; + fbalance: integer; + public + destructor destroy; override; + property balance: integer read fbalance; + property up: tavlnode read fup; + property left: tavlnode read fleft; + property right: tavlnode read fright; + end; + + tintegeravlnode = class(tavlnode) + private + fkey: integer; + public + constructor create(const akey: integer); + property key: integer read fkey; + end; + + tint64avlnode = class(tavlnode) + protected + fkey: int64; + public + constructor create(const akey: int64); overload; + property key: int64 read fkey; + end; + + avlnodeclassty = class of tavlnode; + pavlnode = ^tavlnode; + + nodecomparefuncty = function(const left,right: tavlnode): integer; + nodeprocty = procedure(const anode: tavlnode) of object; + + tavltree = class + private + froot: tavlnode; + fcount: integer; +// fnodeclass: avlnodeclassty; +// procedure freenode(const anode: tavlnode); + protected + fcompare: nodecomparefuncty; + function parentpo(const anode: tavlnode): pavlnode; + procedure dobalance(const anode: tavlnode; const deleted: boolean); + procedure addnode(const anode: tavlnode); + function find(const aleft: tavlnode; out anode: tavlnode): boolean; + //true if exact + public + destructor destroy; override; + procedure clear; virtual;//frees the nodes + procedure removenode(const anode: tavlnode); //does not free node + procedure traverse(const aproc: nodeprocty); + property count: integer read fcount; + property root: tavlnode read froot; + end; + + integernodeprocty = procedure(const anode: tintegeravlnode) of object; + + tintegeravltree = class(tavltree) + public + constructor create; + function addnode(const akey: integer): tintegeravlnode; overload; + procedure addnode(const anode: tintegeravlnode); overload; + function find(const akey: integer; out anode: tintegeravlnode): boolean; overload; + procedure traverse(const aproc: integernodeprocty); + end; + + int64nodeprocty = procedure(const anode: tint64avlnode) of object; + + tint64avltree = class(tavltree) + public + constructor create; + function addnode(const akey: int64): tint64avlnode; overload; + function find(const akey: int64; out anode: tint64avlnode): boolean; overload; + procedure traverse(const aproc: int64nodeprocty); + end; + + tcachenode = class(tint64avlnode) + private + fprev: tcachenode; + fnext: tcachenode; + protected + fsize: integer; + end; + + tdatacachenode = class(tcachenode) + private + fdata: pointer; + public + constructor create(const akey: int64; const adata: pointer; const asize: integer); + destructor destroy; override; + property data: pointer read fdata; + property size: integer read fsize; + end; + + tcacheavltree = class(tint64avltree) + private + fsize: integer; + ffirst: tcachenode; + flast: tcachenode; + fmaxsize: integer; + procedure setmaxsize(const avalue: integer); + procedure checkbuffersize; + protected + procedure addnode(const anode: tcachenode); + function find(const akey: tcachenode; out anode: tcachenode): boolean; overload; + public + procedure clear; overload; override; + procedure removenode(const anode: tcachenode); //does not free node + property maxsize: integer read fmaxsize write setmaxsize; //0 -> no limit + property size: integer read fsize; + end; + + tdatacacheavltree = class(tcacheavltree) + public + function addnode(const akey: int64; const adata: pointer; + const asize: integer): tdatacachenode; + end; + + tstringcachenode = class(tcachenode) + private + fdata: string; + public + constructor create(const akey: int64; const adata: string); overload; + property data: string read fdata; + end; + + tstringcacheavltree = class(tcacheavltree) + public + function addnode(const akey: int64; + const adata: string): tstringcachenode; overload; + end; + +implementation +uses + sysutils; + +{ tavlnode } + +destructor tavlnode.destroy; +begin + fleft.free; + fright.free; +end; + +{ tavltree } + +destructor tavltree.destroy; +begin + clear; + inherited; +end; + +procedure tavltree.clear; +begin + fcount:= 0; + freeandnil(froot); +end; +{ +procedure tavltree.freenode(const anode: tavlnode); +begin + if anode <> nil then begin + freenode(anode.fleft); + freenode(anode.fright); + anode.free; + end; +end; +} +function tavltree.find(const aleft: tavlnode; out anode: tavlnode): boolean; +var + n1: tavlnode; + int1: integer; +begin + anode:= nil; + result:= false; + if froot <> nil then begin + n1:= froot; + while true do begin + int1:= fcompare(n1,aleft); + if int1 = 0 then begin //exact + anode:= n1; + result:= true; + break; + end; + if int1 > 0 then begin //too big + if n1.fleft = nil then begin + anode:= n1; + break; + end; + n1:= n1.fleft; + end + else begin //too small + if n1.fright = nil then begin + anode:= n1.fup; + if (anode <> nil) and (anode.fleft <> n1) then begin + anode:= nil; + end; + break; + end; + n1:= n1.fright; + end; + end; + end; +end; + +function tavltree.parentpo(const anode: tavlnode): pavlnode; +var + n1: tavlnode; +begin + n1:= anode.fup; + if n1 = nil then begin + result:= @froot; + end + else begin + if anode = n1.fleft then begin + result:= @n1.fleft; + end + else begin + result:= @n1.fright; + end; + end; +end; + +procedure tavltree.dobalance(const anode: tavlnode; const deleted: boolean); +var + n3,n4,n5: tavlnode; + po1: pavlnode; + + procedure initpointer; + begin + n5:= n4.fup; + po1:= parentpo(n4); + end; + +begin //balance + n3:= anode; + n5:= nil; //compiler warning + po1:= nil; + while true do begin + n4:= n3.fup; + if n4 = nil then begin + break; //root reached + end; + if (n4.fleft = n3) xor deleted then begin + if (n4.fbalance < 0) then begin //left heavy + initpointer; + if n4.fleft.fbalance > 0 then begin + //rotate left right + // A=n4 B + // / \ / \ + // C a C A=n4 + // / \ / \ / \ + // c B c b2 b1 a + // / \ + // b2 b1 + po1^:= n4.fleft.fright; //B -> top + po1^.fup:= n4.fup; //A.up -> B.up + n4.fleft.fright:= po1^.fleft; //b2 -> C.right + if n4.fleft.fright <> nil then begin + n4.fleft.fright.fup:= n4.fleft; //C -> b2.up + end; + po1^.fleft:= n4.fleft; //C -> B.left + n4.fleft.fup:= po1^; //B -> C.up + n4.fleft:= po1^.fright; //b1 -> A.left + if n4.fleft <> nil then begin + n4.fleft.fup:= n4; + end; + po1^.fright:= n4; //A -> B.right + n4.fup:= po1^; //B -> A.up + + //before A B C after A B C + // -2 +1 +1 0 0 -1 + // -2 0 +1 0 0 0 + // -2 -1 +1 +1 0 0 + if po1^.fbalance = 0 then begin //B + n4.fbalance:= 0; //A + po1^.fleft.fbalance:= 0; //C + end + else begin + if po1^.fbalance < 0 then begin //B + n4.fbalance:= 1; //A + po1^.fleft.fbalance:= 0; //C + end + else begin + n4.fbalance:= 0; //A + po1^.fleft.fbalance:= -1; //C + end; + end; + po1^.fbalance:= 0; + if not deleted then begin + exit; //new height compensated + end; + end + else begin + //rotate right A=n4 B + // / \ / \ + // B a c A=n4 + // / \ / \ + // c b b a + po1^:= n4.fleft; //B -> top + po1^.fup:= n4.fup; //A.up -> B.up + n4.fleft:= po1^.fright; //b -> A.left + po1^.fright:= n4; //A -> B.right + + //before A B after A B + // -2 -1 0 0 + // -2 0 -1 +1 + if po1^.fbalance = 0 then begin + n4.fbalance:= -1; + po1^.fbalance:= 1; + end + else begin + n4.fbalance:= 0; + po1^.fbalance:= 0; + end; + end; + po1^.fup:= n5; //up -> B.up + n4.fup:= po1^; //B -> A.up + if n4.fleft <> nil then begin + n4.fleft.fup:= n4; //A -> b1.up ¦ A -> b.up + end; + if (po1^.fbalance = 0) xor deleted then begin + exit; //B was unbalanced; + end; + n4:= po1^; + end + else begin + dec(n4.fbalance); + if (n4.fbalance = 0) xor deleted then begin + exit; + end; + end; + end + else begin + if (n4.fbalance > 0) then begin //right heavy + initpointer; + if n4.fright.fbalance < 0 then begin + //rotate right left + // A=n4 B + // / \ / \ + // a C A=n4 C + // / \ / \ / \ + // B c a b1 b2 c + // / \ + // b1 b2 + po1^:= n4.fright.fleft; //B -> top + po1^.fup:= n4.fup; //A.up -> B.up + n4.fright.fleft:= po1^.fright; //b2 -> C.left + if n4.fright.fleft <> nil then begin + n4.fright.fleft.fup:= n4.fright; //C -> b2.up + end; + po1^.fright:= n4.fright; //C -> B.right + n4.fright.fup:= po1^; //B -> C.up + n4.fright:= po1^.fleft; //b1 -> A.right + if n4.fright <> nil then begin + n4.fright.fup:= n4; + end; + po1^.fleft:= n4; //A -> B.left + n4.fup:= po1^; //B -> A.up + + //before A B C after A B C + // +2 +1 -1 -1 0 0 + // +2 0 -1 0 0 0 + // +2 -1 -1 0 0 1 + if po1^.fbalance = 0 then begin //B + n4.fbalance:= 0; //A + po1^.fright.fbalance:= 0; //C + end + else begin + if po1^.fbalance < 0 then begin //B + n4.fbalance:= 0; //A + po1^.fright.fbalance:= 1; //C + end + else begin + n4.fbalance:= -1; //A + po1^.fright.fbalance:= 0; //C + end; + end; + po1^.fbalance:= 0; + if not deleted then begin + exit; //new height compensated + end; + end + else begin + //rotate left A=n4 B + // / \ / \ + // a B A=n4 c + // / \ / \ + // b c a b + po1^:= n4.fright; //B -> top + po1^.fup:= n4.fup; //A.up -> B.up + n4.fright:= po1^.fleft; //b -> A.right + po1^.fleft:= n4; //A -> B.left + + //before A B after A B + // +2 +1 0 0 + // +2 0 +1 -1 + if po1^.fbalance = 0 then begin + n4.fbalance:= 1; + po1^.fbalance:= -1; + end + else begin + n4.fbalance:= 0; + po1^.fbalance:= 0; + end; + end; + po1^.fup:= n5; + n4.fup:= po1^; + if n4.fright <> nil then begin + n4.fright.fup:= n4; //A -> b1.up ¦ A -> b.up + end; + if (po1^.fbalance = 0) xor deleted then begin + exit; //B was unbalanced; + end; + n4:= po1^; + end + else begin + inc(n4.fbalance); + if (n4.fbalance = 0) xor deleted then begin + exit; + end; + end; + end; + { + if (n4.fbalance = 0) and (anode <> n3) then begin + exit; + end; + } + n3:= n4; + end; +end; + +procedure tavltree.addnode(const anode: tavlnode); +var + n1{,n2}: tavlnode; + +begin + inc(fcount); + if froot = nil then begin + froot:= anode; + end + else begin + n1:= froot; + while true do begin + if fcompare(anode,n1) >= 0 then begin + if n1.fright = nil then begin + n1.fright:= anode; + anode.fup:= n1; + if n1.fleft = nil then begin + dobalance(anode,false); + end + else begin + n1.fbalance:= 0; + end; + break; + end + else begin + n1:= n1.fright; + end; + end + else begin + if n1.fleft = nil then begin + n1.fleft:= anode; + anode.fup:= n1; + if n1.fright = nil then begin + dobalance(anode,false); + end + else begin + n1.fbalance:= 0; + end; + break; + end + else begin + n1:= n1.fleft; + end; + end; + end; + end; +end; + +procedure tavltree.removenode(const anode: tavlnode); + + procedure checkbalance; + begin + if anode.fup <> nil then begin + with anode.fup do begin + if anode = fright then begin + if (fleft.fleft = nil) and (fleft.fright = nil) or (fbalance < 0) then begin + dobalance(anode,true); + end + else begin + fbalance:= -1; + end; + end + else begin + if (fright.fleft = nil) and (fright.fright = nil) or (fbalance > 0) then begin + dobalance(anode,true); + end + else begin + fbalance:= 1; + end; + end; + end; + end; + end; + +var + n1,n2: tavlnode; + int1: integer; +begin + dec(fcount); + n1:= anode; + if (n1.fleft <> nil) and (n1.fright <> nil) then begin + n1:= n1.fright; + while n1.fleft <> nil do begin + n1:= n1.fleft; //find smallest in right branch + end; + int1:= anode.fbalance; //swap values + anode.fbalance:= n1.fbalance; + n1.fbalance:= int1; + parentpo(anode)^:= n1; + n2:= anode.fleft; + anode.fleft:= n1.fleft; + n1.fleft:= n2; + if n2 <> nil then begin + n2.fup:= n1; + end; + if n1.fup = anode then begin + anode.fright:= n1.fright; + n1.fright:= anode; + n1.fup:= anode.fup; + anode.fup:= n1; + end + else begin + parentpo(n1)^:= anode; + n2:= anode.fup; + anode.fup:= n1.fup; + n1.fup:= n2; + n2:= anode.fright; + anode.fright:= n1.fright; + n1.fright:= n2; + n2.fup:= n1; + end; + end; + if anode.fleft = nil then begin + if anode.fright <> nil then begin + checkbalance; + anode.fright.fup:= anode.fup; + end + else begin + if (anode.fup <> nil) then begin //leaf + with anode.fup do begin + if fleft = anode then begin + if (fright = nil) or (fright.fright <> nil) or (fright.fleft <> nil) or + (fbalance > 0) then begin + dobalance(anode,true); + end + else begin + fbalance:= 1; + end; + end + else begin + if (fleft = nil) or (fleft.fright <> nil) or (fleft.fleft <> nil) or + (fbalance < 0) then begin + dobalance(anode,true); + end + else begin + fbalance:= -1; + end; + end; + end; + end; + end; + parentpo(anode)^:= anode.fright; + end + else begin + checkbalance; + anode.fleft.fup:= anode.fup; + parentpo(anode)^:= anode.fleft; + end; + anode.fleft:= nil; + anode.fright:= nil; +end; + +procedure tavltree.traverse(const aproc: nodeprocty); +label + down; +var + n1: tavlnode; +begin + if froot <> nil then begin + n1:= froot; +down: + while n1.fleft <> nil do begin + n1:= n1.fleft; //find smallest leaf + end; + aproc(n1); + if (n1.fleft = nil) and (n1.fright <> nil) then begin + n1:= n1.fright; + goto down; + end; + while n1.fup <> nil do begin + if n1 = n1.fup.fleft then begin + n1:= n1.fup; + aproc(n1); + if n1.fright <> nil then begin + n1:= n1.fright; + goto down; + end; + end + else begin + n1:= n1.fup; + end; + end; + end; +end; + +{ tintegeravlnode } + +constructor tintegeravlnode.create(const akey: integer); +begin + fkey:= akey; + inherited create; +end; + +{ tintegeravltree } + +function compareintegeravl(const left,right: tavlnode): integer; +begin + result:= tintegeravlnode(left).fkey - tintegeravlnode(right).fkey; +end; + +constructor tintegeravltree.create; +begin +// fnodeclass:= tintegeravlnode; + fcompare:= {$ifdef FPC}@{$endif}compareintegeravl; + inherited; +end; + +function tintegeravltree.addnode(const akey: integer): tintegeravlnode; +begin + result:= tintegeravlnode.create(akey); + inherited addnode(result); +end; + +function tintegeravltree.find(const akey: integer; + out anode: tintegeravlnode): boolean; +var + n1: tintegeravlnode; +begin + n1:= tintegeravlnode.create(akey); + result:= find(n1,tavlnode(anode)); + n1.free; +end; + +procedure tintegeravltree.traverse(const aproc: integernodeprocty); +begin + inherited traverse(nodeprocty(aproc)); +end; + +procedure tintegeravltree.addnode(const anode: tintegeravlnode); +begin + inherited addnode(anode); +end; + +{ tint64avlnode } + +constructor tint64avlnode.create(const akey: int64); +begin + fkey:= akey; + inherited create; +end; + +{ tint64avltree } + +function compareint64avl(const left,right: tavlnode): integer; +var + lint1: int64; +begin + result:= 0; + lint1:= tint64avlnode(left).fkey - tint64avlnode(right).fkey; + if lint1 > 0 then begin + result:= 1; + end + else begin + if lint1 < 0 then begin + result:= -1; + end; + end; +end; + +constructor tint64avltree.create; +begin + fcompare:= {$ifdef FPC}@{$endif}compareint64avl; + inherited; +end; + +function tint64avltree.addnode(const akey: int64): tint64avlnode; +begin + result:= tint64avlnode.create(akey); + inherited addnode(result); +end; + +function tint64avltree.find(const akey: int64; + out anode: tint64avlnode): boolean; +var + n1: tint64avlnode; +begin + n1:= tint64avlnode.create(akey); + result:= find(n1,tavlnode(anode)); + n1.free; +end; + +procedure tint64avltree.traverse(const aproc: int64nodeprocty); +begin + inherited traverse(nodeprocty(aproc)); +end; + +{ tdatacachenode } + +constructor tdatacachenode.create(const akey: int64; const adata: pointer; + const asize: integer); +begin + fdata:= adata; + fsize:= asize; + inherited create(akey); +end; + +destructor tdatacachenode.destroy; +begin + if fsize > 0 then begin + freemem(fdata); + end; + inherited; +end; + +{ tcacheavltree } + +procedure tcacheavltree.checkbuffersize; +var + n1: tcachenode; +begin + if fmaxsize > 0 then begin + while (fsize > fmaxsize) and (fcount > 1) do begin + n1:= ffirst; + removenode(n1); + n1.free; + end; + end; +end; + +procedure tcacheavltree.addnode(const anode: tcachenode); +begin + fsize:= fsize + anode.fsize; + if ffirst = nil then begin + ffirst:= anode; + flast:= anode; + end + else begin + anode.fprev:= flast; + flast.fnext:= anode; + flast:= anode; + end; + inherited addnode(anode); + checkbuffersize; +end; + +function tcacheavltree.find(const akey: tcachenode; out anode: tcachenode): boolean; +begin + result:= inherited find(akey,tavlnode(anode)); + if result and (anode <> flast) then begin + if anode.fprev <> nil then begin + anode.fprev.fnext:= anode.fnext; + end + else begin + ffirst:= anode.fnext; + end; + if anode.fnext <> nil then begin + anode.fnext.fprev:= anode.fprev; + end; + flast.fnext:= anode; + anode.fprev:= flast; + anode.fnext:= nil; + flast:= anode; + end; +end; + +procedure tcacheavltree.clear; +begin + fsize:= 0; + ffirst:= nil; + flast:= nil; + inherited; +end; + +procedure tcacheavltree.removenode(const anode: tcachenode); +begin + fsize:= fsize - anode.fsize; + if fcount > 1 then begin + if anode = ffirst then begin + ffirst:= anode.fnext; + ffirst.fprev:= nil; + end + else begin + if anode = flast then begin + flast:= anode.fprev; + flast.fnext:= nil; + end; + end; + end + else begin + ffirst:= nil; + flast:= nil; + end; + anode.fprev:= nil; + anode.fnext:= nil; + inherited removenode(anode); +end; + +procedure tcacheavltree.setmaxsize(const avalue: integer); +begin + if fmaxsize <> avalue then begin + fmaxsize:= avalue; + checkbuffersize; + end; +end; + +{ tdatacacheavltree } + +function tdatacacheavltree.addnode(const akey: int64; const adata: pointer; + const asize: integer): tdatacachenode; +begin + result:= tdatacachenode.create(akey,adata,asize); + inherited addnode(result); +end; + +{ tstringcachenode } + +constructor tstringcachenode.create(const akey: int64; const adata: string); +begin + fdata:= adata; + fsize:= length(adata); + inherited create(akey); +end; + +{ tstringcacheavltree } + +function tstringcacheavltree.addnode(const akey: int64; + const adata: string): tstringcachenode; +begin + result:= tstringcachenode.create(akey,adata); + inherited addnode(result); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msebits.pas b/mseide-msegui/lib/common/kernel/msebits.pas new file mode 100644 index 0000000..e0ffedf --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msebits.pas @@ -0,0 +1,815 @@ +{ MSEgui Copyright (c) 1999-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msebits; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +//bitmanipulationhelpers +interface +uses + msetypes; + +type + bitnumty = 0..32; +const + twoexp32 = flo64(4294967296.0); + bytebits: array[0..8] of byte = ($01,$02,$04,$08,$10,$20,$40,$80,$00); + bytemask: array[0..8] of byte = ($00,$01,$03,$07,$0f,$1f,$3f,$7f,$ff); + bytebitsreverse: array[0..8] of byte = ($80,$40,$20,$10,$08,$04,$02,$01,$00); + + bits: array[bitnumty] of longword = ( + $00000001,$00000002,$00000004,$00000008, + $00000010,$00000020,$00000040,$00000080, + $00000100,$00000200,$00000400,$00000800, + $00001000,$00002000,$00004000,$00008000, + $00010000,$00020000,$00040000,$00080000, + $00100000,$00200000,$00400000,$00800000, + $01000000,$02000000,$04000000,$08000000, + $10000000,$20000000,$40000000,$80000000, + $00000000); + bitmask: array[bitnumty] of longword = ( + $00000000,$00000001,$00000003,$00000007, + $0000000f,$0000001f,$0000003f,$0000007f, + $000000ff,$000001ff,$000003ff,$000007ff, + $00000fff,$00001fff,$00003fff,$00007fff, + $0000ffff,$0001ffff,$0003ffff,$0007ffff, + $000fffff,$001fffff,$003fffff,$007fffff, + $00ffffff,$01ffffff,$03ffffff,$07ffffff, + $0fffffff,$1fffffff,$3fffffff,$7fffffff, + $ffffffff); + bitreverse: array[byte] of byte = ( + $00,$80,$40,$c0,$20,$a0,$60,$e0,$10,$90,$50,$d0,$30,$b0,$70,$f0, + $08,$88,$48,$c8,$28,$a8,$68,$e8,$18,$98,$58,$d8,$38,$b8,$78,$f8, + $04,$84,$44,$c4,$24,$a4,$64,$e4,$14,$94,$54,$d4,$34,$b4,$74,$f4, + $0c,$8c,$4c,$cc,$2c,$ac,$6c,$ec,$1c,$9c,$5c,$dc,$3c,$bc,$7c,$fc, + $02,$82,$42,$c2,$22,$a2,$62,$e2,$12,$92,$52,$d2,$32,$b2,$72,$f2, + $0a,$8a,$4a,$ca,$2a,$aa,$6a,$ea,$1a,$9a,$5a,$da,$3a,$ba,$7a,$fa, + $06,$86,$46,$c6,$26,$a6,$66,$e6,$16,$96,$56,$d6,$36,$b6,$76,$f6, + $0e,$8e,$4e,$ce,$2e,$ae,$6e,$ee,$1e,$9e,$5e,$de,$3e,$be,$7e,$fe, + $01,$81,$41,$c1,$21,$a1,$61,$e1,$11,$91,$51,$d1,$31,$b1,$71,$f1, + $09,$89,$49,$c9,$29,$a9,$69,$e9,$19,$99,$59,$d9,$39,$b9,$79,$f9, + $05,$85,$45,$c5,$25,$a5,$65,$e5,$15,$95,$55,$d5,$35,$b5,$75,$f5, + $0d,$8d,$4d,$cd,$2d,$ad,$6d,$ed,$1d,$9d,$5d,$dd,$3d,$bd,$7d,$fd, + $03,$83,$43,$c3,$23,$a3,$63,$e3,$13,$93,$53,$d3,$33,$b3,$73,$f3, + $0b,$8b,$4b,$cb,$2b,$ab,$6b,$eb,$1b,$9b,$5b,$db,$3b,$bb,$7b,$fb, + $07,$87,$47,$c7,$27,$a7,$67,$e7,$17,$97,$57,$d7,$37,$b7,$77,$f7, + $0f,$8f,$4f,$cf,$2f,$af,$6f,$ef,$1f,$9f,$5f,$df,$3f,$bf,$7f,$ff); + + intexp10ar: array[0..9] of integer = + (1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000); + int64exp10ar: array[0..19] of int64 = + (1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000, + 1000000000,10000000000,100000000000,1000000000000,10000000000000, + 100000000000000,1000000000000000,10000000000000000, + 100000000000000000,1000000000000000000); +type + int64recty = record + lsw: longword; + msw: longword; + end; + +function highestbit(value: longword): integer; +//0-> first, 31-> last($80000000), -1-> none ($00000000) +function lowestbit(value: longword): integer; +//0-> first, 31-> last($80000000), -1-> none ($00000000) +function nextpowerof2(const avalue: longword): longword; + +function highestbit64(value: qword): integer; +//0-> first, 63-> last($8000000000000000), -1-> none ($0000000000000000) +function lowestbit64(value: qword): integer; +//0-> first, 63-> last($8000000000000000), -1-> none ($0000000000000000) + +function replacebits(const new,old,mask: byte): byte; overload; +function replacebits(const new,old,mask: word): word; overload; +function replacebits(const new,old,mask: longword): longword; overload; +function replacebits1(var dest: byte; const value,mask: byte): boolean; overload; +function replacebits1(var dest: word; const value,mask: word): boolean; overload; +function replacebits1(var dest: longword; + const value,mask: longword): boolean; overload; + //true if modified +function bitschanged(const a,b,mask: byte): boolean; overload; +function bitschanged(const a,b,mask: word): boolean; overload; +function bitschanged(const a,b,mask: longword): boolean; overload; + +function setsinglebit(const new,old,mask: byte): byte; overload; +function setsinglebit(const new,old,mask: word): word; overload; +function setsinglebit(const new,old,mask: longword): longword; overload; +function setsinglebit(const new,old: byte; + const mask: array of byte): byte; overload; +function setsinglebit(const new,old: word; + const mask: array of word): word; overload; +function setsinglebit(const new,old: longword; + const mask: array of longword): longword; overload; +{$ifndef FPC} +function setsinglebitar8(const new,old: byte; + const mask: array of byte): byte; +function setsinglebitar16(const new,old: word; + const mask: array of word): word; +function setsinglebitar32(const new,old: longword; + const mask: array of longword): longword; +{$endif} + +function checkbit(const value: byte; const bitnum: integer): boolean; overload; +function checkbit(const value: word; const bitnum: integer): boolean; overload; +function checkbit(const value: longword; const bitnum: integer): boolean; overload; + +function updatebit(var dest: byte; bitnum: integer; value: boolean): boolean; overload; + //true if changed +function updatebit(var dest: word; bitnum: integer; value: boolean): boolean; overload; + //true if changed +function updatebit(var dest: longword; bitnum: integer; value: boolean):boolean; overload; + //true if changed +procedure updatebit1(var dest: byte; bitnum: integer; value: boolean); overload; +procedure updatebit1(var dest: word; bitnum: integer; value: boolean); overload; +procedure updatebit1(var dest: longword; bitnum: integer; value: boolean); overload; + +procedure setbit1(var dest: byte; bitnum: integer); overload; +procedure setbit1(var dest: word; bitnum: integer); overload; +procedure setbit1(var dest: longword; bitnum: integer); overload; +function setbit(const source: byte; bitnum: integer): byte; overload; +function setbit(const source: word; bitnum: integer): word; overload; +function setbit(const source: longword; bitnum: integer): longword; overload; + +procedure clearbit1(var dest: byte; bitnum: integer); overload; +procedure clearbit1(var dest: word; bitnum: integer); overload; +procedure clearbit1(var dest: longword; bitnum: integer); overload; +function clearbit(const source: byte; bitnum: integer): byte; overload; +function clearbit(const source: word; bitnum: integer): word; overload; +function clearbit(const source: longword; bitnum: integer): longword; overload; + +procedure togglebit1(var dest: byte; bitnum: integer); overload; +procedure togglebit1(var dest: word; bitnum: integer); overload; +procedure togglebit1(var dest: longword; bitnum: integer); overload; +function togglebit(const source: byte; bitnum: integer): byte; overload; +function togglebit(const source: word; bitnum: integer): word; overload; +function togglebit(const source: longword; bitnum: integer): longword; overload; + +function iszero(address: pointer; count: integer): boolean; + +function swapbytes(const value: word): word; overload; + //value and result at different adresses! +function swapbytes(const value: longword): longword; overload; + //value and result at different adresses! +procedure swapbytes1(var value: word); overload; +procedure swapbytes1(var value: longword); overload; + +function swapbits(const value: word): word; overload; + //value and result at different adresses! +function swapbits(const value: longword): longword; overload; + //value and result at different adresses! +procedure swapbits1(var value: word); overload; +procedure swapbits1(var value: longword); overload; + +procedure swaprgb1(var value: longword); +function swaprgb(const value: longword): longword; + +function roundint(const value: integer; const step: integer): integer; +procedure scaleexp101(var value: int64; const exp: integer); overload; +procedure scaleexp101(var value: integer; const exp: integer); overload; +procedure scaleexp101(var value: currency; const exp: integer); overload; +function scaleexp10(const value: int64; const exp: integer): int64; overload; +function scaleexp10(const value: integer; const exp: integer): integer; overload; +function scaleexp10(const value: currency; const exp: integer): currency; overload; + +implementation + +function updatebit(var dest: byte; bitnum: integer; value: boolean): boolean; +var + by1: byte; +begin + by1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; + result:= dest <> by1; +end; + +function updatebit(var dest: word; bitnum: integer; value: boolean): boolean; +var + wo1: word; +begin + wo1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; + result:= dest <> wo1; +end; + +function updatebit(var dest: longword; bitnum: integer; value: boolean): boolean; +var + wo1: longword; +begin + wo1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; + result:= dest <> wo1; +end; + +procedure updatebit1(var dest: byte; bitnum: integer; value: boolean); +//var +// by1: byte; +begin +// by1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; +end; + +procedure updatebit1(var dest: word; bitnum: integer; value: boolean); +//var +// wo1: word; +begin +// wo1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; +end; + +procedure updatebit1(var dest: longword; bitnum: integer; value: boolean); +//var +// wo1: longword; +begin +// wo1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; +end; + +procedure setbit1(var dest: byte; bitnum: integer); +begin + dest:= dest or bits[bitnum]; +end; + +procedure setbit1(var dest: word; bitnum: integer); +begin + dest:= dest or bits[bitnum]; +end; + +procedure setbit1(var dest: longword; bitnum: integer); +begin + dest:= dest or bits[bitnum]; +end; + +procedure clearbit1(var dest: byte; bitnum: integer); +begin + dest:= dest and not bits[bitnum]; +end; + +procedure clearbit1(var dest: word; bitnum: integer); +begin + dest:= dest and not bits[bitnum]; +end; + +procedure clearbit1(var dest: longword; bitnum: integer); +begin + dest:= dest and not bits[bitnum]; +end; + +procedure togglebit1(var dest: byte; bitnum: integer); +begin + dest:= dest xor byte(bits[bitnum]); +end; + +procedure togglebit1(var dest: word; bitnum: integer); +begin + dest:= dest xor word(bits[bitnum]); +end; + +procedure togglebit1(var dest: longword; bitnum: integer); +begin + dest:= dest xor bits[bitnum]; +end; + +function setbit(const source: byte; bitnum: integer): byte; +begin + result:= source or bits[bitnum]; +end; + +function setbit(const source: word; bitnum: integer): word; +begin + result:= source or bits[bitnum]; +end; + +function setbit(const source: longword; bitnum: integer): longword; +begin + result:= source or bits[bitnum]; +end; + +function clearbit(const source: byte; bitnum: integer): byte; +begin + result:= source and not bits[bitnum]; +end; + +function clearbit(const source: word; bitnum: integer): word; +begin + result:= source and not bits[bitnum]; +end; + +function clearbit(const source: longword; bitnum: integer): longword; +begin + result:= source and not bits[bitnum]; +end; + +function togglebit(const source: byte; bitnum: integer): byte; +begin + result:= source xor byte(bits[bitnum]); +end; + +function togglebit(const source: word; bitnum: integer): word; +begin + result:= source xor word(bits[bitnum]); +end; + +function togglebit(const source: longword; bitnum: integer): longword; +begin + result:= source xor bits[bitnum]; +end; + +function replacebits(const new,old,mask: byte): byte; +begin + result:= old and not mask or new and mask; +end; + +function replacebits(const new,old,mask: word): word; +begin + result:= old and not mask or new and mask; +end; + +function replacebits(const new,old,mask: longword): longword; +begin + result:= old and not mask or new and mask; +end; + +function replacebits1(var dest: byte; const value,mask: byte): boolean; +begin + result:= (dest xor value) and mask <> 0; + if result then begin + dest:= dest and not mask or value and mask + end; +end; + +function replacebits1(var dest: word; + const value,mask: word): boolean; overload; +begin + result:= (dest xor value) and mask <> 0; + if result then begin + dest:= dest and not mask or value and mask + end; +end; + +function replacebits1(var dest: longword; + const value,mask: longword): boolean; overload; +begin + result:= (dest xor value) and mask <> 0; + if result then begin + dest:= dest and not mask or value and mask + end; +end; + +function bitschanged(const a,b,mask: byte): boolean; overload; +begin + result:= (a xor b) and mask <> 0; +end; + +function bitschanged(const a,b,mask: word): boolean; overload; +begin + result:= (a xor b) and mask <> 0; +end; + +function bitschanged(const a,b,mask: longword): boolean; overload; +begin + result:= (a xor b) and mask <> 0; +end; + +function setsinglebit(const new,old,mask: byte): byte; overload; +var + v1: byte; +begin + if new and mask = 0 then begin + result:= new and not mask; + end + else begin + v1:= (old xor new) and mask; + if v1 = 0 then begin + result:= new; //no change + end + else begin + result:= (new and not mask) or + bits[lowestbit(v1 and new)]; + end; + end; +end; + +function setsinglebit(const new,old,mask: word): word; overload; +var + v1: word; +begin + if new and mask = 0 then begin + result:= new and not mask; + end + else begin + v1:= (old xor new) and mask; + if v1 = 0 then begin + result:= new; //no change + end + else begin + result:= (new and not mask) or + bits[lowestbit(v1 and new)]; + end; + end; +end; + +function setsinglebit(const new,old,mask: longword): longword; overload; +var + v1: longword; +begin + if new and mask = 0 then begin + result:= new and not mask; + end + else begin + v1:= (old xor new) and mask; + if v1 = 0 then begin + result:= new; //no change + end + else begin + result:= (new and not mask) or + bits[lowestbit(v1 and new)]; + end; + end; +end; + +function setsinglebit(const new,old: byte; + const mask: array of byte): byte; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; + +function setsinglebit(const new,old: word; + const mask: array of word): word; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; +{$ifndef FPC} +function setsinglebitar8(const new,old: byte; + const mask: array of byte): byte; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; +function setsinglebitar16(const new,old: word; + const mask: array of word): word; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; + +function setsinglebitar32(const new,old: longword; + const mask: array of longword): longword; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; +{$endif} +function setsinglebit(const new,old: longword; + const mask: array of longword): longword; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; + +function checkbit(const value: byte; const bitnum: integer): boolean; overload; +begin + result:= value and bits[bitnum] <> 0; +end; + +function checkbit(const value: word; const bitnum: integer): boolean; overload; +begin + result:= value and bits[bitnum] <> 0; +end; + +function checkbit(const value: longword; const bitnum: integer): boolean; overload; +begin + result:= value and bits[bitnum] <> 0; +end; + + + +function roundint(const value: integer; const step: integer): integer; +var + int1: integer; +begin + int1:= step div 2; + if value < 0 then begin + int1:= -int1; + end; + result:= ((value + int1) div step) * step; +end; + +function scaleexp10(const value: int64; const exp: integer): int64; +begin + if exp < 0 then begin + result:= value div int64exp10ar[-exp]; + end + else begin + result:= value * int64exp10ar[exp]; + end; +end; + +function scaleexp10(const value: integer; const exp: integer): integer; +begin + if exp < 0 then begin + result:= value div intexp10ar[-exp]; + end + else begin + result:= value * intexp10ar[exp]; + end; +end; + +function scaleexp10(const value: currency; const exp: integer): currency; +begin +//{$ifdef FPC} +// if exp < 0 then begin +// int64(result):= int64(value) div int64exp10ar[-exp]; +// end +// else begin +// int64(result):= int64(value) * int64exp10ar[exp]; +// end; +//{$else} + if exp < 0 then begin + pint64(@result)^:= pint64(@value)^ div int64exp10ar[-exp]; + end + else begin + pint64(@result)^:= pint64(@value)^ * int64exp10ar[exp]; + end; +//{$endif} +end; + +procedure scaleexp101(var value: int64; const exp: integer); +begin + if exp < 0 then begin + value:= value div int64exp10ar[-exp]; + end + else begin + value:= value * int64exp10ar[exp]; + end; +end; + +procedure scaleexp101(var value: integer; const exp: integer); +begin + if exp < 0 then begin + value:= value div intexp10ar[-exp]; + end + else begin + value:= value * intexp10ar[exp]; + end; +end; + +procedure scaleexp101(var value: currency; const exp: integer); +begin +//{$ifdef FPC} +// if exp < 0 then begin +// int64(value):= int64(value) div int64exp10ar[-exp]; +// end +// else begin +// int64(value):= int64(value) * int64exp10ar[exp]; +// end; +//{$else} + if exp < 0 then begin + pint64(@value)^:= pint64(@value)^ div int64exp10ar[-exp]; + end + else begin + pint64(@value)^:= pint64(@value)^ * int64exp10ar[exp]; + end; +//{$endif} +end; + +procedure swaprgb1(var value: longword); +var + by1: byte; +begin + by1:= byte(value); + pchar(@value)^:= (pchar(@value)+2)^; + byte((pchar(@value)+2)^):= by1; +end; + +function swaprgb(const value: longword): longword; +begin + result:= value; + pchar(@result)^:= (pchar(@value)+2)^; + byte((pchar(@result)+2)^):= byte(value); +end; + +//todo: optimize + +procedure swapbytes1(var value: word); overload; +var + wo1: word; +begin + wo1:= value; + (pchar(@value))^:= (pchar(@wo1)+1)^; + (pchar(@value)+1)^:= (pchar(@wo1))^; +end; + +procedure swapbytes1(var value: longword); overload; +var + ca1: longword; + po1,po2: pchar; +begin + ca1:= value; + po1:= @value; + po2:= pchar(@ca1)+3; + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; +end; + +function swapbytes(const value: word): word; overload; +begin + (pchar(@result))^:= (pchar(@value)+1)^; + (pchar(@result)+1)^:= (pchar(@value))^; +end; + +function swapbytes(const value: longword): longword; overload; +var + po1,po2: pchar; +begin + po1:= @result; + po2:= pchar(@value)+3; + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; +end; + +function swapbits(const value: word): word; overload; + //value and result at different adresses! +begin + pbyte(pchar(@result))^:= bitreverse[pbyte(pchar(@value)+1)^]; + pbyte(pchar(@result)+1)^:= bitreverse[pbyte(pchar(@value))^]; +end; + +function swapbits(const value: longword): longword; overload; + //value and result at different adresses! +var + po1,po2: pbyte; +begin + po1:= @result; + po2:= pbyte(pchar(@value)+3); + po1^:= bitreverse[po2^]; inc(po1); dec(po2); + po1^:= bitreverse[po2^]; inc(po1); dec(po2); + po1^:= bitreverse[po2^]; inc(po1); dec(po2); + po1^:= bitreverse[po2^]; +end; + +procedure swapbits1(var value: word); overload; +var + wo1: word; +begin + wo1:= value; + value:= swapbits(wo1); +end; + +procedure swapbits1(var value: longword); overload; +var + lwo1: longword; +begin + lwo1:= value; + value:= swapbits(lwo1); +end; + +function iszero(address: pointer; count: integer): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count - 1 do begin + if pbyte(address)^ <> 0 then begin + exit; + end; + inc(pbyte(address)); + end; + result:= true; +end; + +function highestbit(value: longword): integer; +//0-> first, 31-> last($80000000), -1-> none ($00000000) +begin + result:= -1; + while value <> 0 do begin + inc(result); + value:= value shr 1; + end; +end; + +function lowestbit(value: longword): integer; +//0-> first, 31-> last($80000000), -1-> none ($00000000) +begin + result:= -1; + if value <> 0 then begin + result:= 32; + while value <> 0 do begin + dec(result); + value:= value shl 1; + end; + end; +end; + +function nextpowerof2(const avalue: longword): longword; +var + int1: integer; +begin + int1:= highestbit(avalue); + if avalue - bits[int1] <> 0 then begin + result:= bits[int1+1]; + end + else begin + result:= avalue; + end; +end; + +function highestbit64(value: qword): integer; +//0-> first, 63-> last($8000000000000000), -1-> none ($0000000000000000) +begin + result:= -1; + while value <> 0 do begin + inc(result); + value:= value shr 1; + end; +end; + +function lowestbit64(value: qword): integer; +//0-> first, 63-> last($8000000000000000), -1-> none ($0000000000000000) +begin + result:= -1; + if value <> 0 then begin + result:= 64; + while value <> 0 do begin + dec(result); + value:= value shl 1; + end; + end; +end; + +function getmask(const mask: array of bitnumty): longword; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(mask) do begin + result:= result or bits[mask[int1]]; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msebucketlist.pas b/mseide-msegui/lib/common/kernel/msebucketlist.pas new file mode 100644 index 0000000..b179c35 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msebucketlist.pas @@ -0,0 +1,884 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msebucketlist; +// +// deprecated, use t*hashdatalist in msehash.pas instead +// +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msestrings; + +const + defaultbucketcount = $20; + defaultgrowstep = 8; + +type + datastatety = (ds_empty,ds_data); + bucketty = record + count: integer; + keys: array of ptruint; //0-> free + datapo: pointer; + end; + pbucketty = ^bucketty; + bucketarty = array of bucketty; + + tbucketlist = class + private + fbuckets: bucketarty; + fsize: integer; + fmask1: longword; + fcapacitystep: integer; + fstepbucket,fstepindex: integer; + procedure invalidkey; + function bucketindex(const key: ptruint): integer; + protected + fcount: integer; + procedure freedata(var data); virtual; + procedure initdata(var data); virtual; + function add(const key: ptruint; const data): pointer; //key <> 0 + //returns pointer to new data, @data can be nil -> data inited with 0 + function internalfind(const key: ptruint; var bucket,index: integer): boolean; + function find(const key: ptruint): pointer; + function next: pointer; + public + constructor create(recordsize: integer; abucketcount: integer = defaultbucketcount); + destructor destroy; override; + procedure clear; + function count: integer; + function delete(const key: ptruint): boolean; //true if found + end; + + datastringty = record + key: string; + data: pointer; + end; + pdatastringty = ^datastringty; + + stringbucketty = array of datastringty; + stringbucketpoty = ^stringbucketty; + stringbucketarty = array of stringbucketty; + + thashedstrings = class + private + fbuckets: stringbucketarty; + fmask: longword; + fcapacitystep: integer; + fcount: integer; + fstepbucket,fstepindex: integer; + function getbucketcount: integer; + procedure setbucketcount(const Value: integer); + function internalfind(const key: string): pdatastringty; overload; + function internalfind(const key: lstringty): pdatastringty; overload; + public + constructor create; + procedure clear; virtual; + procedure add(const key: string; data: pointer = pointer($ffffffff)); overload; + //nil nicht erlaubt + procedure add(const keys: array of string; + startindex: pointer = pointer($00000001)); overload; + //data = arrayindex + startindex + procedure delete(const key: lstringty); overload; virtual; + procedure delete(const key: string); overload; + function find(const key: string): pointer; overload; //casesensitive + function find(const key: lstringty): pointer; overload; //casesensitive + function findi(const key: string): pointer; overload; //caseinsensitive + function findi(const key: lstringty): pointer; overload; //caseinsensitive + property bucketcount: integer read getbucketcount write setbucketcount default defaultbucketcount; + property count: integer read fcount; + function next: pdatastringty; + end; + + msedatastringty = record + key: msestring; + data: pointer; + end; + pmsedatastringty = ^msedatastringty; + + msestringbucketty = array of msedatastringty; + pmsestringbucketty = ^msestringbucketty; + msestringbucketarty = array of msestringbucketty; + + thashedmsestrings = class + private + fcount: integer; + fbuckets: msestringbucketarty; + fmask: longword; + fcapacitystep: integer; + fstepbucket,fstepindex: integer; + function getbucketcount: integer; + procedure setbucketcount(const Value: integer); + function internalfind(const key: msestring): pmsedatastringty; + public + constructor create; + procedure clear; virtual; + procedure add(const key: msestring; data: pointer = pointer($ffffffff)); overload; + procedure add(const keys: array of msestring; + startindex: pointer = pointer($00000001)); + overload; //data = arrayindex + startindex + procedure delete(const key: msestring); virtual; + function find(const key: msestring): pointer; overload; + function find(const key: lmsestringty): pointer; overload; + function findi(const key: msestring): pointer; overload; + function findi(const key: lmsestringty): pointer; overload; + property bucketcount: integer read getbucketcount write setbucketcount default defaultbucketcount; + property count: integer read fcount; + function next: pmsedatastringty; + end; + + thashedmsestringobjects = class(thashedmsestrings) + public + destructor destroy; override; + procedure clear; override; + procedure add(const key: msestring; aobject: tobject); + procedure delete(const key: msestring); override; + function find(const key: msestring): tobject; overload; + function find(const key: lmsestringty): tobject; overload; + function findi(const key: msestring): tobject; overload; + function findi(const key: lmsestringty): tobject; overload; + end; + + thashedstringobjects = class(thashedstrings) + public + destructor destroy; override; + procedure clear; override; + procedure add(const key: string; aobject: tobject); + procedure delete(const key: lstringty); override; + function find(const key: string): tobject; overload; + function find(const key: lstringty): tobject; overload; + function findi(const key: string): tobject; overload; + function findi(const key: lstringty): tobject; overload; + end; + +implementation +uses + sysutils,msehash; + +function maxbitmask(value: longword): longword; +begin + if value = 0 then begin + result:= 0; + end + else begin + result:= $ffffffff; + while value and $80000000 = 0 do begin + result:= result shr 1; + value:= value shl 1; + end; + end; +end; + +{ tbucketlist } + +constructor tbucketlist.create(recordsize: integer; + abucketcount: integer = defaultbucketcount); +begin + fcapacitystep:= defaultgrowstep; + fsize:= recordsize; + fmask1:= maxbitmask(abucketcount-1); + setlength(fbuckets,fmask1+1); +end; + +destructor tbucketlist.destroy; +begin + clear; + inherited; +end; + +function tbucketlist.bucketindex(const key: ptruint): integer; +begin + if key = 0 then begin + invalidkey; + end; + result:= (key xor (key shr 4)) and fmask1; +end; + +procedure tbucketlist.clear; +var + int1,int2: integer; + po1: pchar; +begin + for int1:= 0 to high(fbuckets) do begin + with fbuckets[int1] do begin + po1:= datapo; + if po1 <> nil then begin + for int2:= 0 to high(keys) do begin + if keys[int2] <> 0 then begin + freedata(po1^); + end; + inc(po1,fsize); + end; + freemem(datapo); + datapo:= nil; + setlength(keys,0); + count:= 0; + end; + end; + end; + fcount:= 0; +end; + +procedure tbucketlist.freedata(var data); +begin + //dummy +end; + +function tbucketlist.count: integer; +begin + result:= fcount; +end; + +procedure tbucketlist.initdata(var data); +begin + //dummy +end; + +function tbucketlist.add(const key: ptruint; const data): pointer; +var + int1: integer; +begin + with fbuckets[bucketindex(key)] do begin + if count >= length(keys) then begin + int1:= length(keys); + setlength(keys,length(keys)+fcapacitystep); + reallocmem(datapo,length(keys)*fsize); + end + else begin + int1:= high(keys); + while keys[int1] <> 0 do begin + dec(int1); + end; + end; + keys[int1]:= key; + result:= pchar(datapo) + int1*fsize; + if @data = nil then begin + fillchar(result^,fsize,0); + end + else begin + move(data,result^,fsize); + end; + inc(count); + inc(fcount); + initdata(result^); + end; +end; + +function tbucketlist.internalfind(const key: ptruint; var bucket,index: integer): boolean; +var + int1: integer; +begin + result:= false; + bucket:= bucketindex(key); + with fbuckets[bucket] do begin + for int1:= 0 to high(keys) do begin + if keys[int1] = key then begin + index:= int1; + result:= true; + break; + end; + end; + end; +end; + +function tbucketlist.delete(const key: ptruint): boolean; + //true if found +var + bucket,index: integer; +begin + result:= internalfind(key,bucket,index); + if result then begin + with fbuckets[bucket] do begin + freedata((pchar(datapo) + index*fsize)^); + dec(count); + keys[index]:= 0; + dec(fcount); + end; + end; +end; + +procedure tbucketlist.invalidkey; +begin + raise exception.Create('Invalid keyvalue.'); +end; + +function tbucketlist.find(const key: ptruint): pointer; +var + bucket,index: integer; +begin + if internalfind(key,bucket,index) then begin + result:= pchar(fbuckets[bucket].datapo) + index*fsize; + end + else begin + result:= nil; + end; +end; + +function tbucketlist.next: pointer; +begin + result:= nil; + if fcount > 0 then begin + inc(fstepindex); + repeat + if fstepbucket >= length(fbuckets) then begin + fstepbucket:= 0; + fstepindex:= 0; + end; + with fbuckets[fstepbucket] do begin + if fstepindex >= length(keys) then begin + inc(fstepbucket); + fstepindex:= 0; + end + else begin + if keys[fstepindex] <> 0 then begin + result:= pchar(datapo) + fstepindex*fsize; + end + else begin + inc(fstepindex); + end; + end; + end; + until result <> nil; + end; +end; + +{ thashedstrings } + +constructor thashedstrings.create; +begin + fcapacitystep:= defaultgrowstep; + setbucketcount(defaultbucketcount); +end; + +procedure thashedstrings.add(const key: string; data: pointer = pointer($ffffffff)); +var + po: stringbucketpoty; + po1: pdatastringty; + int1: integer; + freefound: boolean; +begin + if data = nil then begin + raise exception.create('nil not allowed.'); + end; + inc(fcount); + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + freefound:= false; + for int1:= 0 to high(po^) do begin + if po1^.data = nil then begin + freefound:= true; + break; + end; + inc(po1) + end; + if not freefound then begin + int1:= length(po^); + setlength(po^,int1+fcapacitystep); + po1:= @po^[int1]; + end; + po1^.key:= key; + po1^.data:= data; +end; + +procedure thashedstrings.add(const keys: array of string; + startindex: pointer = pointer($00000001)); +var + ca1: longword; +begin + if ptruint(length(keys)) + ptruint(startindex) <= ptruint(length(keys)) then begin + raise exception.create('nil not allowed.'); + end; + for ca1:= 0 to high(keys) do begin + add(keys[ca1],pointer(ca1+ptruint(startindex))); + end; +end; + +procedure thashedstrings.clear; +var + int1: integer; +begin + for int1:= 0 to high(fbuckets) do begin + fbuckets[int1]:= nil; + end; + fcount:= 0; +end; + +function thashedstrings.internalfind(const key: string): pdatastringty; +var + po: stringbucketpoty; + po1: pdatastringty; + int1: integer; +begin + result:= nil; + if fcount > 0 then begin + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + for int1:= 0 to high(po^) do begin + if (po1^.data <> nil) and (po1^.key = key) then begin + result:= po1; + break; + end; + inc(po1) + end; + end; +end; + +function thashedstrings.internalfind(const key: lstringty): pdatastringty; +var + po: stringbucketpoty; + po1: pdatastringty; + int1,int2: integer; +begin + result:= nil; + if fcount > 0 then begin + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + for int1:= 0 to high(po^) do begin + if po1^.data <> nil then begin + int2:= length(po1^.key); + if int2 > 0 then begin + if int2 < key.len then begin + int2:= key.len; + end; + if strlcomp(key.po,pointer(po1^.key),int2) = 0 then begin + result:= po1; + break; + end; + end; + end; + inc(po1) + end; + end; +end; + +function thashedstrings.find(const key: lstringty): pointer; +var + po1: pdatastringty; +begin + po1:= internalfind(key); + if po1 <> nil then begin + result:= po1^.data; + end + else begin + result:= nil; + end; +end; + +function thashedstrings.find(const key: string): pointer; +var + po1: pdatastringty; +begin + po1:= internalfind(key); + if po1 <> nil then begin + result:= po1^.data; + end + else begin + result:= nil; + end; +end; + + +function thashedstrings.findi(const key: string): pointer; +begin + if fcount > 0 then begin + result:= find(struppercase(key)); + end + else begin + result:= nil; + end; +end; + +function thashedstrings.findi(const key: lstringty): pointer; +begin + if fcount > 0 then begin + result:= find(struppercase(key)); + end + else begin + result:= nil; + end; +end; + +procedure thashedstrings.delete(const key: lstringty); +var + po1: pdatastringty; +begin + while true do begin + po1:= internalfind(key); + if po1 = nil then begin + break; + end; + po1^.data:= nil; + dec(fcount); + end; +end; + +procedure thashedstrings.delete(const key: string); +var + lstr1: lstringty; +begin + lstr1.len:= length(key); + lstr1.po:= pointer(key); + delete(lstr1); +end; + +function thashedstrings.getbucketcount: integer; +begin + result:= length(fbuckets); +end; + +procedure thashedstrings.setbucketcount(const Value: integer); +begin + fmask:= maxbitmask(value-1); + setlength(fbuckets,fmask+1); +end; + +function thashedstrings.next: pdatastringty; +begin + result:= nil; + if fcount > 0 then begin + inc(fstepindex); + repeat + if fstepbucket > high(fbuckets) then begin + fstepbucket:= 0; + fstepindex:= 0; + end; + if fstepindex > high(fbuckets[fstepbucket]) then begin + inc(fstepbucket); + fstepindex:= 0; + end + else begin + if fbuckets[fstepbucket][fstepindex].data <> nil then begin + result:= @fbuckets[fstepbucket][fstepindex]; + end + else begin + inc(fstepindex); + end; + end; + until result <> nil; + end; +end; + +{ thashedmsestrings } + +constructor thashedmsestrings.create; +begin + fcapacitystep:= defaultgrowstep; + setbucketcount(defaultbucketcount); +end; + +procedure thashedmsestrings.add(const key: msestring; + data: pointer = pointer($ffffffff)); +var + po: pmsestringbucketty; + po1: pmsedatastringty; + int1: integer; + freefound: boolean; +begin + if data = nil then begin + raise exception.create('nil not allowed.'); + end; + inc(fcount); + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + freefound:= false; + for int1:= 0 to high(po^) do begin + if po1^.data = nil then begin + freefound:= true; + break; + end; + inc(po1) + end; + if not freefound then begin + int1:= length(po^); + setlength(po^,int1+fcapacitystep); + po1:= @po^[int1]; + end; + po1^.key:= key; + po1^.data:= data; +end; + +procedure thashedmsestrings.add(const keys: array of msestring; + startindex: pointer = pointer($00000001)); +var + ca1: longword; +begin + if longword(length(keys)) + ptruint(startindex) <= longword(length(keys)) then begin + raise exception.create('nil not alowed.'); + end; + for ca1:= 0 to high(keys) do begin + add(keys[ca1],pointer(ca1+ptruint(startindex))); + end; +end; + +procedure thashedmsestrings.clear; +var + int1: integer; +begin + for int1:= 0 to high(fbuckets) do begin + fbuckets[int1]:= nil; + end; + fcount:= 0; +end; + +function thashedmsestrings.internalfind(const key: msestring): pmsedatastringty; +var + po: pmsestringbucketty; + po1: pmsedatastringty; + int1: integer; +begin + result:= nil; + if fcount > 0 then begin + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + for int1:= 0 to high(po^) do begin + if (po1^.data <> nil) and (po1^.key = key) then begin + result:= po1; + break; + end; + inc(po1) + end; + end; +end; + +function thashedmsestrings.find(const key: lmsestringty): pointer; +var + po: pmsestringbucketty; + po1: pmsedatastringty; + int1,int2: integer; +begin + result:= nil; + if fcount > 0 then begin + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + for int1:= 0 to high(po^) do begin + if po1^.data <> nil then begin + int2:= length(po1^.key); + if int2 > 0 then begin + if int2 < key.len then begin + int2:= key.len; + end; + if msestrlcomp(key.po,pointer(po1^.key),int2) = 0 then begin + result:= po1^.data; + break; + end; + end; + end; + inc(po1) + end; + end; +end; + +function thashedmsestrings.find(const key: msestring): pointer; +var + po1: pmsedatastringty; +begin + po1:= internalfind(key); + if po1 <> nil then begin + result:= po1^.data; + end + else begin + result:= nil; + end; +end; + +function thashedmsestrings.findi(const key: lmsestringty): pointer; +begin + result:= find(struppercase(key)); +end; + +function thashedmsestrings.findi(const key: msestring): pointer; +begin + if fcount > 0 then begin + result:= find(struppercase(key)); + end + else begin + result:= nil; + end; +end; + +procedure thashedmsestrings.delete(const key: msestring); +var + po1: pmsedatastringty; +begin + repeat + po1:= internalfind(key); + if po1 <> nil then begin + dec(fcount); + po1^.data:= nil; + end; + until po1 = nil; +end; + +function thashedmsestrings.getbucketcount: integer; +begin + result:= length(fbuckets); +end; + +procedure thashedmsestrings.setbucketcount(const Value: integer); +begin + fmask:= maxbitmask(value-1); + setlength(fbuckets,fmask+1); +end; + +function thashedmsestrings.next: pmsedatastringty; +begin + result:= nil; + if fcount > 0 then begin + inc(fstepindex); + repeat + if fstepbucket > high(fbuckets) then begin + fstepbucket:= 0; + fstepindex:= 0; + end; + if fstepindex > high(fbuckets[fstepbucket]) then begin + inc(fstepbucket); + fstepindex:= 0; + end + else begin + if fbuckets[fstepbucket][fstepindex].data <> nil then begin + result:= @fbuckets[fstepbucket][fstepindex]; + end + else begin + inc(fstepindex); + end; + end; + until result <> nil; + end; +end; + +{ thashedstringobjects } + +destructor thashedstringobjects.destroy; +begin + clear; + inherited; +end; + +procedure thashedstringobjects.clear; +var + int1,int2: integer; +begin + for int1:= 0 to high(fbuckets) do begin + if fbuckets[int1] <> nil then begin + for int2:= 0 to high(fbuckets[int1]) do begin + if fbuckets[int1][int2].data <> nil then begin + tobject(fbuckets[int1][int2].data).free; + end; + end; + end; + fbuckets[int1]:= nil; + end; + fcount:= 0; +end; + +procedure thashedstringobjects.add(const key: string; aobject: tobject); +begin + inherited add(key,aobject); +end; + +procedure thashedstringobjects.delete(const key: lstringty); +var + po1: pdatastringty; +begin + repeat + po1:= internalfind(key); + if po1 <> nil then begin + tobject(po1^.data).Free; + po1^.data:= nil; + dec(fcount); + end; + until po1 = nil; +end; + +function thashedstringobjects.find(const key: string): tobject; +begin + result:= tobject(inherited find(key)); +end; + +function thashedstringobjects.find(const key: lstringty): tobject; +begin + result:= tobject(inherited find(key)); +end; + +function thashedstringobjects.findi(const key: string): tobject; +begin + result:= tobject(inherited findi(key)); +end; + +function thashedstringobjects.findi(const key: lstringty): tobject; +begin + result:= tobject(inherited findi(key)); +end; + +{ thashedmsestringobjects } + +destructor thashedmsestringobjects.destroy; +begin + clear; + inherited; +end; + +procedure thashedmsestringobjects.clear; +var + int1,int2: integer; +begin + for int1:= 0 to high(fbuckets) do begin + if fbuckets[int1] <> nil then begin + for int2:= 0 to high(fbuckets[int1]) do begin + if fbuckets[int1][int2].data <> nil then begin + tobject(fbuckets[int1][int2].data).free; + end; + end; + end; + fbuckets[int1]:= nil; + end; + fcount:= 0; +end; + +procedure thashedmsestringobjects.add(const key: msestring; aobject: tobject); +begin + inherited add(key,aobject); +end; + +procedure thashedmsestringobjects.delete(const key: msestring); +var + po1: pmsedatastringty; +begin + repeat + po1:= internalfind(key); + if po1 <> nil then begin + tobject(po1^.data).Free; + po1^.data:= nil; + dec(fcount); + end; + until po1 = nil; +end; + +function thashedmsestringobjects.find(const key: msestring): tobject; +begin + result:= tobject(inherited find(key)); +end; + +function thashedmsestringobjects.find(const key: lmsestringty): tobject; +begin + result:= tobject(inherited find(key)); +end; + +function thashedmsestringobjects.findi(const key: msestring): tobject; +begin + result:= tobject(inherited findi(key)); +end; + +function thashedmsestringobjects.findi(const key: lmsestringty): tobject; +begin + result:= tobject(inherited findi(key)); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseclasses.pas b/mseide-msegui/lib/common/kernel/mseclasses.pas new file mode 100644 index 0000000..774fdf3 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseclasses.pas @@ -0,0 +1,6100 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseclasses; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +{$ifndef mse_methodswap} + {$define mse_nomethodswap} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseglob,mseevent,msetypes,msestrings,sysutils,typinfo,mselist, + msegraphutils{$ifdef mse_with_ifi},mseifiglob{$endif} + {$ifndef FPC},classes_del{$endif}; + +{$if defined(FPC) and (fpc_fullversion >= 020403)} + {$define mse_fpc_2_4_3} +{$ifend} +{$if defined(FPC) and (fpc_fullversion >= 020400)} + {$define mse_fpc_2_4} +{$ifend} + +{$ifdef FPC} + {$ifdef mse_FPC_2_4} + {$define hascorbagetinterface} + {$endif} +const + s_ok = 0; +{$endif} + +const +{$ifdef linux} + {$ifdef CPU64} + platformtext = 'x86_64-linux'; + {$else} + {$ifdef CPUARM} + platformtext = 'arm-linux'; + {$else} + platformtext = 'i386-linux'; + {$endif} + {$endif} +{$else} + {$ifdef openbsd} + {$ifdef CPU64} + platformtext = 'x86_64-openbsd'; + {$else} + platformtext = 'i386-openbsd'; + {$endif} + {$else} + {$ifdef bsd} + {$ifdef CPU64} + platformtext = 'x86_64-bsd'; + {$else} + platformtext = 'i386-bsd'; + {$endif} + {$else} + {$ifdef cpu64} + platformtext = 'x86_64-win64'; + {$else} + platformtext = 'i386-win32'; + {$endif} + {$endif} + {$endif} +{$endif} + + moduleclassnamename = 'moduleclassname'; +// inheritedmoduleclassnamename = 'inheritedmoduleclassname'; + compilerdefaults = + '{$ifdef FPC}{$mode objfpc}{$h+}{$endif}'; + +type + tcomponentevent = class; + posteventoptionty = (peo_local,peo_first,peo_modaldefer); + posteventoptionsty = set of posteventoptionty; + + notifyeventty = procedure (const sender: tobject) of object; + componenteventty = procedure (const acomponent: tcomponent) of object; + checkeventty = function (const sender: tobject): boolean of object; + accepteventty = procedure (const sender: tobject; + var accept: boolean) of object; + eventeventty = procedure (const sender: tobject; + const aevent: tobjectevent) of object; + componenteventeventty = procedure (const sender: tobject; + const aevent: tcomponentevent) of object; + asynceventeventty = procedure (const sender: tobject; + var atag: integer) of object; + + booleanchangedeventty = procedure (const sender: tobject; + const avalue: boolean) of object; + stringchangedeventty = procedure (const sender: tobject; + const avalue: msestring) of object; + integerchangedeventty = procedure (const sender: tobject; + const avalue: integer) of object; + realchangedeventty = procedure (const sender: tobject; + const avalue: realty) of object; + + getintegereventty = function: integer of object; + getint64eventty = function: int64 of object; + getmsestringeventty = function: msestring of object; + getstringareventty = function: stringarty of object; + + updatestringeventty = procedure(const sender: tobject; + var avalue: msestring) of object; + updateansistringeventty = procedure(const sender: tobject; + var avalue: ansistring) of object; + updateintegereventty = procedure(const sender: tobject; + var avalue: integer) of object; + updateint64eventty = procedure(const sender: tobject; + var avalue: int64) of object; + updatepointereventty = procedure(const sender: tobject; + var avalue: pointer) of object; + updatebooleaneventty = procedure(const sender: tobject; + var avalue: boolean) of object; + updaterealeventty = procedure(const sender: tobject; + var avalue: real) of object; + updatedatetimeeventty = procedure(const sender: tobject; + var avalue: tdatetime) of object; + + setbooleaneventty = procedure(const sender: tobject; var avalue: boolean; + var accept: boolean) of object; + setstringeventty = procedure(const sender: tobject; var avalue: msestring; + var accept: boolean) of object; + setansistringeventty = procedure(const sender: tobject; var avalue: ansistring; + var accept: boolean) of object; + setintegereventty = procedure(const sender: tobject; var avalue: integer; + var accept: boolean) of object; + //equal parameters as setcoloreventty for tcoloredit! + setint64eventty = procedure(const sender: tobject; var avalue: int64; + var accept: boolean) of object; + setrealeventty = procedure(const sender: tobject; var avalue: realty; + var accept: boolean) of object; + setdatetimeeventty = procedure(const sender: tobject; var avalue: tdatetime; + var accept: boolean) of object; + + setbooleanindexeventty = procedure(const sender: tobject; var avalue: boolean; + var accept: boolean; const aindex: integer) of object; + setstringindexeventty = procedure(const sender: tobject; var avalue: msestring; + var accept: boolean; const aindex: integer) of object; + setansistringindexeventty = procedure(const sender: tobject; var avalue: ansistring; + var accept: boolean; const aindex: integer) of object; + setintegerindexeventty = procedure(const sender: tobject; var avalue: integer; + var accept: boolean; const aindex: integer) of object; + //equal parameters as setcoloreventty for tcoloredit! + setint64indexeventty = procedure(const sender: tobject; var avalue: int64; + var accept: boolean; const aindex: integer) of object; + setrealindexeventty = procedure(const sender: tobject; var avalue: realty; + var accept: boolean; const aindex: integer) of object; + setdatetimeindexeventty = procedure(const sender: tobject; var avalue: tdatetime; + var accept: boolean; const aindex: integer) of object; + + progresseventty = procedure(const sender: tobject; const avalue: real; + var acancel: boolean) of object; + + persistentarty = array of tpersistent; + persistentclassty = class of tpersistent; + + componentarty = array of tcomponent; + componentaty = array[0..0] of tcomponent; + pcomponentaty = ^componentaty; + + componentclassty = class of tcomponent; + + propinfopoarty = array of ppropinfo; + + tvirtualpersistent = class(tpersistent) + protected + procedure internalcreate; virtual; + public + constructor create; virtual; + end; + virtualpersistentclassty = class of tvirtualpersistent; + + townedpersistent = class(tvirtualpersistent) + protected + fowner: tobject; + public + constructor create(aowner: tobject); reintroduce; virtual; + property owner: tobject read fowner; + end; + + tlinkedobject = class; + + linkinfoty = record + source: pointer; //iobjectlink + dest: pointer; //iobjectlink + refcount: integer; + valuepo: pointer; + interfacetype: pointer; + end; + plinkinfoty = ^linkinfoty; + + linkinfoaty = array[0..0] of linkinfoty; + plinkinfoaty = ^linkinfoaty; + + plinkedobject = ^tlinkedobject; + tmsecomponent = class; + pmsecomponent = ^tmsecomponent; + pobjectlinker = ^tobjectlinker; + tlinkedpersistent = class; + plinkedpersistent = ^tlinkedpersistent; + + objectlinkprocty = procedure(const info: linkinfoty) of object; + objectlinkintfprocty = procedure(const alink: pointer) of object; + objectlinkfirstprocty = procedure(const info: linkinfoty; + var handled: boolean) of object; + objectlinkintffirstprocty = procedure(const alink: pointer; + var handled: boolean) of object; + + tobjectlinker = class(trecordlist) + private + fonevent: objectlinkeventty; + fownerintf: pointer; //iobjectlink; + finstancepo: pobjectlinker; + fnopack: integer; + procedure dopack; + procedure removelink(var item: linkinfoty; destroyed: boolean); + protected + function isempty(var item): boolean; override; +// function findsource(const item: linkinfoty): integer; + public + {$ifdef debugobjectlink} + debugon: boolean; + {$endif} + constructor create(const owner: iobjectlink; onevent: objectlinkeventty); + destructor destroy; override; + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); overload; + procedure link(const dest: tmsecomponent; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); overload; + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); overload; + //source = 1 -> dest destroyed + procedure unlink(const dest: tmsecomponent; valuepo: pointer = nil); overload; + function linkedobjects: objectarty; overload; + function linkedobjects(const ainterfacetype: pointer): objectarty; overload; + + procedure setlinkedvar(const linkintf: iobjectlink; + const source: iobjectlink; var dest: iobjectlink; + const ainterfacetype: pointer = nil); overload; + procedure setlinkedvar(const linkintf: iobjectlink; + const source: tlinkedobject; var dest: tlinkedobject; + const ainterfacetype: pointer = nil); overload; + procedure setlinkedvar(const linkintf: iobjectlink; + const source: tlinkedpersistent; + var dest: tlinkedpersistent; + const ainterfacetype: pointer = nil); overload; + procedure setlinkedvar(const linkintf: iobjectlink; + const source: tmsecomponent; var dest: tmsecomponent; + const ainterfacetype: pointer = nil); overload; + + procedure setlink(const linkintf: iobjectlink; + const source: tmsecomponent; var dest: tmsecomponent; + const ainterfacetype: pointer = nil); overload; + //no automatic nil setting + procedure sendevent(event: objecteventty); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + procedure forall(const proc: objectlinkprocty; + const ainterfacetype: pointer); overload; + procedure forall(const proc: objectlinkintfprocty; + const ainterfacetype: pointer); overload; + procedure forfirst(const proc: objectlinkfirstprocty; + const ainterfacetype: pointer); overload; + procedure forfirst(const proc: objectlinkintffirstprocty; + const ainterfacetype: pointer); overload; + end; + + tlinkedobject = class(tnullinterfacedobject,iobjectlink) + private + protected + fobjectlinker: tobjectlinker; + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); overload; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; + const event: objecteventty); virtual; + function getinstance: tobject; + public + destructor destroy; override; +// property objectlinker: tobjectlinker read getobjectlinker; + end; + + tlinkedrecordlist = class(trecordlist,iobjectlink) + protected + fobjectlinker: tobjectlinker; + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); overload; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; + const event: objecteventty); virtual; + function getinstance: tobject; + public + destructor destroy; override; + end; + +(* + tnullinterfacedobject = class(tobject,iunknown) + protected + function _addref: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + function _release: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + function queryinterface({$ifdef fpc_has_constref}constref{$else}const{$endif} + iid: tguid; out obj): hresult; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + end; +*) + tnullinterfacedpersistent = class(tvirtualpersistent,iunknown) + protected + {$ifdef FPC} + function _addref: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + function _release: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + function QueryInterface({$ifdef fpc_has_constref}constref{$else}const{$endif} + IID: TGUID; out Obj): HResult; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$endif} + end; + + toptionalpersistent = class(tnullinterfacedpersistent) + private + procedure writedummy(writer: twriter); + protected + procedure readdummy(reader: treader); + procedure defineproperties(filer : tfiler); override; + function isoptional: boolean; virtual; + end; + + tlinkedpersistent = class(tnullinterfacedpersistent,iobjectlink) + private + protected + fobjectlinker: tobjectlinker; + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; + const event: objecteventty); virtual; + function getinstance: tobject; virtual; + + public + destructor destroy; override; + procedure setlinkedvar(const source: iobjectlink; var dest: iobjectlink; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedpersistent; + var dest: tlinkedpersistent; + const linkintf: iobjectlink = nil); overload; + end; + + tlinkedoptionalpersistent = class(tlinkedpersistent) + private + procedure readdummy(reader: treader); + procedure writedummy(writer: twriter); + protected + procedure defineproperties(filer : tfiler); override; + function isoptional: boolean; virtual; + end; + + teventpersistent = class(tlinkedpersistent,ievent) + protected + procedure receiveevent(const event: tobjectevent); virtual; + public + end; + + townedeventpersistent = class(tlinkedpersistent) + protected + fowner: tobject; + public + constructor create(aowner: tobject); reintroduce; virtual; + property owner: tobject read fowner; + end; + + teventobject = class(tlinkedobject,ievent) + protected + procedure receiveevent(const event: tobjectevent); virtual; + public + end; + + componenteventstatety = (ces_processed,ces_callchildren); + componenteventstatesty = set of componenteventstatety; + + tcomponentevent = class(tobjectevent) + private + fsender: tobject; + public + state: componenteventstatesty; + tag: integer; + constructor create(const asender: tobject; const atag: integer = 0; + const callchildren: boolean = true); + overload; + property sender: tobject read fsender; + end; + + msecomponentstatety = (cs_ismodule,cs_beginreadproc,cs_endreadproc, + cs_loadedproc, + cs_inheritedloading,cs_noload,cs_tmpmodule, + cs_subcompref, //subcomponent can be referenced + //by component properties + cs_parentwidgetrect //info for designer, example ttabpage +// cs_skinloaded + {cs_hasskin,cs_noskin}{,cs_updateskinproc}); + msecomponentstatesty = set of msecomponentstatety; + + createprocty = procedure of object; + + skinoptionty = (sko_container); + skinoptionsty = set of skinoptionty; + + skinobjectkindty = (sok_component,sok_widget,sok_groupbox, + sok_simplebutton,sok_databutton,sok_slider, + sok_tabbar,sok_tabpage,sok_toolbar, + sok_splitter,sok_dispwidget, + sok_edit,sok_dataedit,sok_booleanedit, + sok_grid, + sok_mainmenu,sok_popupmenu,sok_mainmenuwidget, + sok_user); + + skininfoty = record + instance: tobject; + userkind: integer; + group: integer; + objectkind: skinobjectkindty; + options: skinoptionsty; + end; + + tmsecomponent = class(tcomponent,ievent + {$ifdef mse_with_ifi},iificommand,iificlient{$endif}) + private + fonbeforeupdateskin: notifyeventty; + fonafterupdateskin: notifyeventty; + procedure readmoduleclassname(reader: treader); + procedure writemoduleclassname(writer: twriter); + procedure beginread;// virtual; + procedure endread; + protected + fmsecomponentstate: msecomponentstatesty; + fobjectlinker: tobjectlinker; + factualclassname: pshortstring; + fancestorclassname: string; + fhelpcontext: msestring; + +{$ifdef mse_with_ifi} + fifiserverintf: iifiserver; + //iificlient + procedure setifiserverintf(const aintf: iifiserver); + function getdefaultifilink: iificlient; virtual; + function getifidatatype: listdatatypety virtual; + //iificommand + procedure executeificommand(var acommand: ificommandcodety); virtual; +{$endif} + + function getancestorclassname: string; + function getmsecomponentstate: msecomponentstatesty; + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + procedure dobeginread; virtual; + procedure doendread; virtual; + procedure readstate(reader: treader); override; + procedure loaded; override; + procedure validaterename(acomponent: tcomponent; + const curname, newname: string); override; + procedure setchildorder(child: tcomponent; order: integer); override; + procedure sendchangeevent(const aevent: objecteventty = oe_changed); + function linkcount: integer; + function candestroyevent(const event: tmethod): boolean; + function gethelpcontext: msestring; virtual; + + class function classskininfo: skininfoty; virtual; + function skininfo: skininfoty; virtual; + function hasskin: boolean; virtual; + function getcomponentinstance: tcomponent; + procedure getcompchildren(const proc: tgetchildproc; + const root: tcomponent); + + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); virtual; + procedure objevent(const sender: iobjectlink; + const event: objecteventty); virtual; + function getinstance: tobject; + function getcomponent: tcomponent; + //ievent + procedure receiveevent(const event: tobjectevent); virtual; + + procedure designselected(const selected: boolean); virtual; + procedure setlinkedvar(const source: iobjectlink; var dest: iobjectlink; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedpersistent; + var dest: tlinkedpersistent; + const linkintf: iobjectlink = nil); overload; + function getactualclassname: string; + class function getmoduleclassname: string; virtual; + class function hasresource: boolean; virtual; + procedure defineproperties(filer: tfiler); override; + procedure componentevent(const event: tcomponentevent); virtual; + procedure doasyncevent(var atag: integer); virtual; + procedure doafterload; virtual; + public + destructor destroy; override; + procedure writestate(writer: twriter); override; + procedure updateskin(const recursive: boolean = false); virtual; +// procedure removeskin(const recursive: boolean = false); virtual; + function loading: boolean; reintroduce; + //this hides FPC tcomponent.loading which is not Delphi compatible + {$ifdef FPC} + procedure setinline(value: boolean); + procedure setancestor(value: boolean); + {$endif} + procedure setsubcompref; + function canevent(const event: tmethod): boolean; + procedure setoptionalobject(const value: tpersistent; var instance; + createproc: createprocty); + procedure getoptionalobject(const instance: tobject; createproc: createprocty); + function getcorbainterface(const aintf: ptypeinfo; out obj) : boolean; +// function getcorbainterface(const aintf: tguid; out obj) : boolean; + procedure initnewcomponent(const ascale: real); virtual; + function checkowned(component: tcomponent): boolean; + //true if component is owned or self + function checkowner(component: tcomponent): boolean; + //true if component is owner or self + function rootowner: tcomponent; +// function rootcomponent: tcomponent; //rootowner or self + function getrootcomponentpath: componentarty; + function linkedobjects: objectarty; + //returns items of objeclinker and free notify list + + procedure sendcomponentevent(const event: tcomponentevent; + const destroyevent: boolean = true); + //event will be destroyed if not async + procedure sendrootcomponentevent(const event: tcomponentevent; + const destroyevent: boolean = true); + //event will be destroyed if not async + procedure asyncevent(atag: integer = 0; + const aoptions: posteventoptionsty = []); + //posts event for doasyncevent to self + procedure postcomponentevent(const event: tcomponentevent; + const aoptions: posteventoptionsty = []); + + property moduleclassname: string read getmoduleclassname; + property actualclassname: string read getactualclassname; + property msecomponentstate: msecomponentstatesty read fmsecomponentstate; + property onbeforeupdateskin: notifyeventty read fonbeforeupdateskin + write fonbeforeupdateskin; + property onafterupdateskin: notifyeventty read fonafterupdateskin + write fonafterupdateskin; + published + property helpcontext: msestring read gethelpcontext write fhelpcontext; + end; + + msecomponenteventty = procedure(const sender: tmsecomponent) of object; + msecomponentclassty = class of tmsecomponent; + msecomponentarty = array of tmsecomponent; + + tlinkedqueue = class(tpointerqueue,iobjectlink) + private + fobjectlinker: tobjectlinker; + fainstance: tobject; + fownsobjects: boolean; + function getitems(const index: integer): iobjectlink; + procedure setitems(const index: integer; const Value: iobjectlink); + procedure objectevent(const sender: tobject; const event: objecteventty); + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + protected + procedure finalizeitem(var item: pointer); override; + procedure linkdestroyed(const alink: iobjectlink); virtual; + public + constructor create(aownsobjects: boolean); + destructor destroy; override; + function destroying: boolean; + function add(const value: iobjectlink): integer; + procedure insert(const index: integer; const value: iobjectlink); reintroduce; + function getfirst: iobjectlink; + function getlast: iobjectlink; + procedure sendchangenotification(sender: tobject); + property items[const index: integer]: iobjectlink read getitems write setitems; default; + property ownsobjects: boolean read fownsobjects write fownsobjects; + end; + + tlinkedobjectqueue = class(tlinkedqueue,iobjectlink) + private + protected + function getitems(const index: integer): tlinkedobject; + procedure setitems(const index: integer; const Value: tlinkedobject); + public + function findobject(const aobject: tlinkedobject): integer; + //-1 if not found + function add(const value: tlinkedobject): integer; + procedure insert(const index: integer; const value: tlinkedobject); reintroduce; + function getfirst: tlinkedobject; + function getlast: tlinkedobject; + property items[const index: integer]: tlinkedobject read getitems write setitems; default; + end; + + tpersistentqueue = class(tlinkedqueue,iobjectlink) + private + function getitems(const index: integer): tlinkedpersistent; + procedure setitems(const index: integer; const Value: tlinkedpersistent); + protected + public + function findobject(const aobject: tlinkedpersistent): integer; + //-1 if not found + procedure add(const value: tlinkedpersistent); + procedure insert(const index: integer; const value: tlinkedpersistent); reintroduce; + function getfirst: tlinkedpersistent; + function getlast: tlinkedpersistent; + property items[const index: integer]: tlinkedpersistent read getitems write setitems; default; + end; + + tcomponentqueue = class(tlinkedqueue,iobjectlink) + private + function getitems(const index: integer): tmsecomponent; + procedure setitems(const index: integer; const Value: tmsecomponent); + protected + public + function findobject(const aobject: tmsecomponent): integer; + //-1 if not found + function add(const value: tmsecomponent): integer; + procedure insert(const index: integer; const value: tmsecomponent); reintroduce; + function getfirst: tmsecomponent; + function getlast: tmsecomponent; + property items[const index: integer]: tmsecomponent read getitems write setitems; default; + end; + + tobjectlinkrecordlist = class(trecordlist,iobjectlink) + private + protected + fobjectlinker: tobjectlinker; + procedure finalizerecord(var item); override; + procedure dounlink(var item); virtual; abstract; + procedure itemdestroyed(const sender: iobjectlink); virtual; abstract; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + public + constructor create(arecordsize: integer; aoptions: recordliststatesty = []); + destructor destroy; override; + end; + + objectdataty = record + size: integer; + data: array[0..0] of byte; + end; + pobjectdataty = ^objectdataty; + + tpersistenttemplate = class(tlinkedpersistent) + private + fonchange: notifyeventty; + protected + fowner: tmsecomponent; + procedure changed; + function getinfosize: integer; virtual; abstract; + function getinfoad: pointer; virtual; abstract; + procedure copyinfo(const source: tpersistenttemplate); virtual; + procedure assignto(dest: tpersistent); override; + procedure doassignto(dest: tpersistent); virtual; abstract; + public + constructor create(const owner: tmsecomponent; const onchange: notifyeventty); + reintroduce; virtual; + procedure assign(source: tpersistent); override; + end; + + templateclassty = class of tpersistenttemplate; + + ttemplatecontainer = class(tmsecomponent) + protected + ftemplate: tpersistent; + procedure assignto(dest: tpersistent); override; + function gettemplateclass: templateclassty; virtual; abstract; + procedure templatechanged(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + end; + + tnotifylist = class(tmethodlist) + public + procedure notify(const sender: tobject); + end; + + tmodulelist = class(tcomponentqueue) + protected + flocked: integer; + procedure ancestornotfound(Reader: TReader; const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent); + public + function findmodulebyname(const name: string): tcomponent; + procedure lock; + procedure unlock; + end; + + getchildreneventty = procedure (const sender: tmsecomponent; + const proc: tgetchildproc; const root: tcomponent) of object; + + twritermse = class(twriter) + private +// fgetchildrenbefore: getchildreneventty; + fancestorlookuplevel: integer; + fchildlevel: integer; + fnoancestor: boolean; //used for copy paste of inherited components + fmasterancestor: boolean; //used to restore field class in tpersistentfields + {$ifndef FPC} + FAncestors: TStringList; + fcurrentpos: integer; + fancestorpos: integer; + fsignaturewritten: boolean; + {$endif} + procedure DetermineAncestor(Component : TComponent); + procedure AddToAncestorList(Component: TComponent); + procedure DoFindAncestor(Component : TComponent); + protected + frootrootancestor: tcomponent; + frootroot: tcomponent; + function rootcompname(const acomp: tcomponent; + const aroot: tcomponent): string; overload; + function rootcompname(const acomp: tcomponent; + arootlevel: integer): string; overload; + procedure getchildren1(const acomp: tcomponent; + const proc: tgetchildproc; const aroot: tcomponent); + procedure WriteChildren(Component : TComponent); + procedure WriteComponentData(Instance: TComponent); + function getclassname(const aobj: tobject): shortstring; override; + public + constructor create(const stream: tstream; const bufsize: integer; + const anoancestor: boolean = false; + const amasterancestor: boolean = false); + destructor destroy; override; + procedure WriteComponent(Component: TComponent); + procedure writedescendent(const aroot: tcomponent; + const aancestor: tcomponent); + procedure writerootcomponent(aroot: tcomponent); + property masterancestor: boolean read fmasterancestor; + end; + + tobjectdatastream = class(tcustommemorystream) + public + constructor create(data: pobjectdataty); + function Write(const Buffer; Count: Longint): Longint; override; + end; + + setsplitpairty = record + oldenum,newenum: string + end; + setsplitinfoty = record + maintype: ptypeinfo; + splittype: ptypeinfo; + enums: array of setsplitpairty; + end; + + writerecordprocty = procedure(const writer: twriter; const data); + readrecordprocty = procedure(const reader: treader; var data); + +function ownscomponent(const owner: tcomponent; const child: tcomponent): boolean; +function ownernamepath(const acomponent: tcomponent): string; + //namepath from root to acomponent separated by '.' +function ownernamepath(const aroot: tcomponent; + const acomponent: tcomponent): string; + //namepath from aroot to acomponent separated by '.' + //excluding aroot +function namepathowner(const acomponent: tcomponent): string; + //namepath from acomponent to root separated by '.' +function getnumberedname(const acomp: tcomponent; + const namebase: string): string; +function ownercomponentpath(const acomponent: tcomponent): componentarty; + //componentpath from root to acomponent +function componentpathowner(const acomponent: tcomponent): componentarty; + //componentpath from acomponent to root +function rootcomponent(const acomponent: tcomponent): tcomponent; +procedure setcomponentorder(const owner: tcomponent; const anames: msestringarty); +function getcomponentchildren(const acomp: tcomponent; + const aroot: tcomponent; + const nestedowners: boolean = false; + const nestedparents: boolean = false): componentarty; +function getpropinfoar(const obj: tobject): propinfopoarty; overload; +function getpropinfoar(const atypeinfo: ptypeinfo): propinfopoarty; overload; + +procedure createobjectlinker(const owner: iobjectlink; onevent: objectlinkeventty; + var instance: tobjectlinker); + //sets finstancepo +procedure getoptionalobject(const componentstate: tcomponentstate; + const instance: tobject; createproc: createprocty); overload; +procedure getoptionalobject(const aowner: tcomponent; //can be nil + const instance: tobject; createproc: createprocty); overload; +procedure getoptionalobject(const componentstate: tcomponentstate; + var instance: tvirtualpersistent; + const aclass: virtualpersistentclassty); overload; +procedure setoptionalobject(const componentstate: tcomponentstate; + const value: tpersistent; var instance; + createproc: createprocty); overload; +procedure setoptionalobject(const aowner: tcomponent; //can be nil + const value: tpersistent; var instance; + createproc: createprocty); overload; +procedure setoptionalobject(const componentstate: tcomponentstate; + const value: tvirtualpersistent; var instance; + const aclass: virtualpersistentclassty); overload; +procedure setlinkedcomponent(const sender: iobjectlink; const source: tmsecomponent; + var instance: tmsecomponent; ainterfacetype: pointer = nil); + +function createmodule(aowner: tcomponent; instanceclass: msecomponentclassty; + var reference): tmsecomponent; +procedure registerobjectdata(datapo: pobjectdataty; + objectclass: tpersistentclass; name: string = ''); overload; +procedure registerobjectdata(datapo: pobjectdataty; + const objectclassname: string; const name: string = ''); overload; + //language overrides +procedure unregisterobjectdata(const objectclassname: string; const name: string = ''); + //language overrides +procedure resetchangedmodules; +procedure reloadchangedmodules; +procedure reloadmodules; + +procedure msebegingloballoading; //recursive +procedure mseendgloballoading; //calls notifygloballoading in level 0 + +procedure reloadmsecomponent(Instance: tmsecomponent); +function initmsecomponent(instance: tmsecomponent; rootancestor: tclass; + out needsloading: boolean): boolean; + //true if root and all inherited classes loaded +function initmsecomponent1(instance: tcomponent; rootancestor: tclass): boolean; + //true if root and all inherited classes loaded +function findancestorcomponent(const areader: treader; + const componentname: string): tcomponent; +procedure loadmsemodule(const instance: tmsecomponent; const rootancestor: tclass); +function findmoduledata(const aclassname: string; + out aparentclassname: string): pobjectdataty; + +function getfproppath(const writer:twriter): string; +procedure setfproppath(const writer:twriter; const value: string); + +procedure freecomponents(const acomponents: componentarty); + //uses freenotification +function copycomponent(const source: tcomponent; const aowner: tcomponent = nil; + const onfindancestor: tfindancestorevent = nil; + const onfindcomponentclass: tfindcomponentclassevent = nil; + const oncreatecomponent: tcreatecomponentevent = nil; + const onancestornotfound: tancestornotfoundevent = nil): tcomponent; + //copy by stream.writecomponent, readcomponent +procedure refreshancestor(var deletedcomps: componentarty; + const descendent,newancestor,oldancestor: tcomponent; + const revert: boolean; + const onfindancestor: tfindancestorevent = nil; + const onfindcomponentclass: tfindcomponentclassevent = nil; + const oncreatecomponent: tcreatecomponentevent = nil; + {$ifdef mse_nomethodswap} + const onsetmethodproperty: tsetmethodpropertyevent = nil; + const onwritemethodproperty: twritemethodpropertyevent = nil; + const newcomponent: pboolean = nil + {$else} + const onfindmethod: tfindmethodevent = nil; + const sourcemethodtab: pointer = nil; + const destmethodtab: pointer = nil + {$endif}); + +procedure initinline(const acomponent: tcomponent); + //sets inline, resets ancestor, sets ancestor of children +procedure checkinline(const acomponent: tcomponent); + //resets csancestor of csinline components +procedure initrootdescendent(const acomponent: tcomponent); + //clears csinline flags of acomoponent and children, + // sets csancestor +function issubcomponent(const root,child: tcomponent): boolean; +function fixupsetchildorder(const sender: tcomponent; + const child: tcomponent; const order: integer): boolean; + //true if handled +function findcomponentbynamepath(const namepath: string): tcomponent; +function findcomponentbynamepath(const namepath: string; + const root: tcomponent): tcomponent; +function findsubcomponentbynamepath(const namepath: string; + const root: tcomponent): tcomponent; + //name path does not contain root +function getlinkedcomponents(const acomponent: tcomponent): componentarty; + //returns items of free notify list + + +procedure lockfindglobalcomponent; //switch of findglobalcomponent +procedure unlockfindglobalcomponent; //switch on findglobalcomponent +function findglobalcomponentlocked: boolean; + +function getenumnames(const atypeinfo: ptypeinfo): msestringarty; +function getclasspropvalue(const instance: tobject; const apropname: string; + const aclass: tclass): tobject; +function getclasspropvalue(const instance: tobject; const apropname: string; + const aclass: tclass; out avalue: tobject): boolean; + + +procedure nosupportfor(const sender: tcomponent; const avalue: tcomponent; + const ainterface: ptypeinfo); +function getcorbainterface(const aobject: tobject; const aintf: ptypeinfo; + out obj) : boolean; +procedure checkcorbainterface(const sender: tcomponent; + const avalue: tcomponent; + const ainterface: ptypeinfo; out obj); +function isinterface(const actual: ptypeinfo; const wanted: ptypeinfo): boolean; +function isinterfaceornil(const actual: ptypeinfo; const wanted: ptypeinfo): boolean; + +function checkcanevent(const acomponent: tcomponent; + const event: tmethod): boolean; overload; +function checkcanevent(const event: tmethod): boolean; + {$ifdef FPC}inline;{$endif} overload; + +procedure readstringar(const reader: treader; out ar: stringarty); overload; +procedure readstringar(const reader: treader; out ar: msestringarty); overload; +procedure writestringar(const writer: twriter; const ar: stringarty); overload; +procedure writestringar(const writer: twriter; const ar: msestringarty); overload; +procedure readintar(const reader: treader; out ar: int32arty); +procedure readintar(const reader: treader; out ar: int16arty); +procedure writeintar(const writer: twriter; const ar: int32arty); +procedure writeintar(const writer: twriter; const ar: int16arty); +procedure readrecordar(const reader: treader; out ar; //array of type + const typeinfo: pdynarraytypeinfo; const readproc: readrecordprocty); +procedure writerecordar(const writer: twriter; const ar; //array of type + const typeinfo: pdynarraytypeinfo; const writeproc: writerecordprocty); + +function valuescaletorange(const reader: treader): real; + +function swapmethodtable(const instance: tobject; const newtable: pointer): pointer; + +function checkenumvalue(typeinfo : ptypeinfo;const name : string) : integer; + //exception on error +function readenum(const reader: treader; const atypeinfo: ptypeinfo): integer; +procedure writeenum(const writer: twriter; const value: integer; + const atypeinfo: ptypeinfo); +function readset(const reader: treader; const atypeinfo: ptypeinfo): tintegerset; +procedure writeset(const writer: twriter; const value: tintegerset; + const atypeinfo: ptypeinfo); +function readsplitset(const reader: treader; const info: setsplitinfoty; + out set1,set2: tintegerset): boolean; + //true if splitted +function setloading(const acomponent: tcomponent; const avalue: boolean): boolean; + //returns old value + +function alive(const acomponent: tcomponent): boolean; + +procedure componentexception(const acomponent: tcomponent; + const atext: msestring); +type + skineventty = procedure(const ainfo: skininfoty) of object; +var + oninitskinobject: skineventty; +//threadvar +// onstreaminggetchildren: getchildreneventty; + +function getcomponentlist(const acomponent: tcomponent): tfplist; +procedure clearcomponentlist(const acomponent: tcomponent); +procedure clearpastedcomponents; +procedure addpastedcomponentname(const acomp: tcomponent); +function findpastedcomponent(const origname: string): tcomponent; +function findpastedcomponentname(const comp: tcomponent): string; + +procedure copyvarrec(const source: tvarrec; const dest: pointer); +procedure matchparams(const aparam: array of const; + const defaults: array of const; const dest: array of pointer); + + +{$ifdef mse_debug} +procedure dumptextstream(const stream: tstream; const atext: string); +procedure dumpcomponent(const acomp: tcomponent; const atext: string = ''); +procedure dumpstreamcomponent(const acomp: tcomponent; const atext: string = ''); +procedure debugstreamout(const stream: tstream; const atext: string); +procedure debugbinstreamout(const acomp,aancestor: tcomponent; + const aonfindancestor: tfindancestorevent; const atext: string); +function debugstringarty(const astringar: stringarty): string; +function debugcompname(const acomponent: tcomponent): string; +function debugcompnames(const acomponents: componentarty): string; +function debugcomprootname(const acomponent: tcomponent): string; +function debugcomprootnames(const acomponents: componentarty): string; +{$endif} + +implementation +uses +{$ifdef debugobjectlink} + msegui,mseformatstr, +{$endif} + mseapplication, +{$ifdef mse_debug} + mseobjecttext, +{$endif} + msestream,msesys,msedatalist,msedatamodules,rtlconsts,msesysutils, + msearrayutils,msestreaming + {$ifdef mswindows} + ,windows +{$endif} +; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tpersistent1 = class(tpersistent); + tcomponent1 = class(tcomponent); + twriter1 = class(twriter); + treader1 = class(treader); +{$ifndef FPC} +const + filersignature : array[1..4] of char = 'TPF0'; +type +{$endif} +{ + tobjectdatastream = class(tcustommemorystream) + public + constructor create(data: pobjectdataty); + function Write(const Buffer; Count: Longint): Longint; override; + end; +} + objectdatainfoty = record + objectclass: tclass; + objectdata: pobjectdataty; + langobjectdata: pobjectdataty; + name: string; + changed: boolean; + end; + + pobjectdatainfoty = ^objectdatainfoty; + + tobjectdatainfolist = class(trecordlist) //todo: hashed or ordered list for speedup + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + procedure reload(const all: boolean); + public + constructor create; + function itempo(const index: integer): pobjectdatainfoty; + procedure add(const value: objectdatainfoty); + function find(aclass: tclass; aname: string): pobjectdatainfoty; overload; + function find(aclassname: string; aname: string): pobjectdatainfoty; overload; + procedure resetchanged; + procedure reloadchanged; + procedure reloadall; + end; + + tloadedlist = class(tcomponent) + protected + procedure notification(acomponent: tcomponent; operation: toperation); override; + end; + + trefreshwriter = class(twritermse) + protected + end; + +var + objectdatalist: tobjectdatainfolist; + fmodules: tmodulelist; + floadedlist: tloadedlist; + fmodulestoregister: msecomponentarty; + +{$ifdef mse_debug} +function debugstringarty(const astringar: stringarty): string; +begin + if astringar = nil then begin + result:= 'NIL'; + end + else begin + result:= concatstrings(astringar,','); + end; +end; + +function debugcompname(const acomponent: tcomponent): string; +begin + if acomponent = nil then begin + result:= 'NIL'; + end + else begin + result:= acomponent.name+'<'+acomponent.classname+'>'; + end; +end; + +function debugcompnames(const acomponents: componentarty): string; +var + int1: integer; +begin + if acomponents = nil then begin + result:= 'NIL'; + end + else begin + for int1:= 0 to high(acomponents) do begin + result:= result + debugcompname(acomponents[int1]) + ','; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; + end; +end; + +function debugcomprootname(const acomponent: tcomponent): string; +var + comp1: tcomponent; +begin + if acomponent = nil then begin + result:= 'NIL'; + end + else begin + comp1:= acomponent; + repeat + result:= comp1.name+'<'+comp1.classname+'>'+'.'+result; + comp1:= comp1.owner; + until comp1 = nil; + setlength(result,length(result)-1); + end; +end; + +function debugcomprootnames(const acomponents: componentarty): string; +var + int1: integer; +begin + if acomponents = nil then begin + result:= 'NIL'; + end + else begin + result:= ''; + for int1:= 0 to high(acomponents) do begin + result:= result + debugcomprootname(acomponents[int1]) + ','; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; + end; +end; + +procedure dumpcomponent(const acomp: tcomponent; const atext: string = ''); +var + indent: string; + + procedure dodump(const acomp: tcomponent); + var + int1: integer; + str1: string; + begin + str1:= settostring(ptypeinfo(typeinfo(tcomponentstate)), + integer(tintegerset(acomp.componentstate)),true); + debugwriteln(indent+acomp.name+' '+str1); + indent:= indent+' '; + for int1:= 0 to acomp.componentcount-1 do begin + dodump(acomp.components[int1]); + end; + setlength(indent,length(indent)-1); + end; + +begin + if atext = '' then begin + debugwriteln('*dumpcomp') + end + else begin + debugwriteln(atext); + end; + dodump(acomp); +end; + +procedure debugstreamout(const stream: tstream; const atext: string); +var + teststream: ttextstream; +begin + debugwriteln(atext); + teststream:= ttextstream.create; + stream.position:= 0; + teststream.size:= 0; + objectbinarytotextmse(stream,teststream); + teststream.position:= 0; + teststream.writetotext(output); + teststream.free; + flush(output); +end; + +procedure dumptextstream(const stream: tstream; const atext: string); +var + int1: integer; + str1: string; +begin + debugwriteln(atext); + int1:= stream.position; + stream.position:= 0; + setlength(str1,stream.size); + stream.readbuffer(pointer(str1)^,length(str1)); + debugwriteln(str1); + stream.position:= int1; +end; + +procedure debugbinstreamout(const acomp,aancestor: tcomponent; + const aonfindancestor: tfindancestorevent; const atext: string); +var + stream1: tmemorystream; + writer1: twritermse; +begin + stream1:= tmemorystream.create; + writer1:= twritermse.create(stream1,1024,false); + writer1.onfindancestor:= aonfindancestor; +// writer1.onfindancestor:= {$ifdef FPC}@{$endif}fdesigner.findancestor; + writer1.writedescendent(acomp,aancestor); + writer1.free; + debugstreamout(stream1,atext); + stream1.free; +end; + +procedure dumpstreamcomponent(const acomp: tcomponent; const atext: string = ''); +begin + debugbinstreamout(acomp,nil,nil,atext); +end; + +{$endif} + +function aligntoptr(p: pointer): pointer; inline; +begin +{$ifdef FPC_REQUIRES_PROPER_ALIGNMENT} + result:= align(p,sizeof(p)); +{$else FPC_REQUIRES_PROPER_ALIGNMENT} + result:=p; +{$endif FPC_REQUIRES_PROPER_ALIGNMENT} +end; + +procedure copyvarrec(const source: tvarrec; const dest: pointer); +begin + with source do begin + case vtype of + vtInteger: begin + pinteger(dest)^:= vinteger; + end; + vtBoolean: begin + system.pboolean(dest)^:= vboolean; + end; + vtChar: begin + pchar(dest)^:= vchar; + end; + vtExtended: begin + pextended(dest)^:= vextended^; + end; + vtString: begin + pshortstring(dest)^:= vstring^; + end; + vtPointer: begin + ppointer(dest)^:= vpointer; + end; + vtPChar: begin + ppchar(dest)^:= vpchar; + end; + vtObject: begin + pobject(dest)^:= vobject; + end; + vtClass: begin + pclass(dest)^:= vclass; + end; + vtWideChar: begin + pwidechar(dest)^:= vwidechar; + end; + vtPWideChar: begin + ppwidechar(dest)^:= vpwidechar; + end; + vtAnsiString: begin + pansistring(dest)^:= ansistring(vansistring); + end; + vtCurrency: begin + pcurrency(dest)^:= vcurrency^; + end; + vtVariant: begin + pvariant(dest)^:= vvariant^; + end; + vtInterface: begin + ppointer(dest)^:= vinterface; //reference counting? + end; + vtWideString: begin + pwidestring(dest)^:= widestring(vwidestring); + end; + vtInt64: begin + pint64(dest)^:= vint64^; + end; + vtQWord: begin + pqword(dest)^:= vqword^; + end; + vtUnicodeString: begin + punicodestring(dest)^:= unicodestring(vunicodestring); + end; + end; + end; +end; + +procedure matchparams(const aparam: array of const; + const defaults: array of const; const dest: array of pointer); +var + int1: integer; +begin + int1:= high(aparam); + if int1 > high(defaults) then begin + int1:= high(defaults); + end; + if int1 > high(dest) then begin + int1:= high(dest); + end; + for int1:= 0 to int1 do begin + if tvarrec(aparam[int1]).vtype = tvarrec(defaults[int1]).vtype then begin + copyvarrec(aparam[int1],dest[int1]); + end + else begin + copyvarrec(defaults[int1],dest[int1]); + end; + end; +end; + +function alive(const acomponent: tcomponent): boolean; + {$ifdef FPC}inline;{$endif} +begin + result:= (acomponent <> nil) and + not (csdestroying in acomponent.componentstate); +end; + +procedure componentexception(const acomponent: tcomponent; + const atext: msestring); +begin + raise exception.create(ansistring( + msestring(acomponent.name+':'+acomponent.classname+':'+ lineend) + + atext)); +end; + +function getfproppath(const writer:twriter): string; +begin +{$warnings off} + result:= twriter1(writer).fproppath; +{$warnings on} +end; + +procedure setfproppath(const writer:twriter; const value: string); +begin +{$warnings off} + twriter1(writer).fproppath:= value; +{$warnings on} +end; + +function modules: tmodulelist; +begin + if fmodules = nil then begin + fmodules:= tmodulelist.create(false); + end; + result:= fmodules; +end; + +function getcomponentlist(const acomponent: tcomponent): tfplist; +begin +{$warnings off} + with tcomponent1(acomponent) do begin +{$warnings on} + if fcomponents = nil then begin + fcomponents:= tfplist.create; + end; + result:= fcomponents; + end; +end; + +procedure clearcomponentlist(const acomponent: tcomponent); +begin +{$warnings off} + freeandnil(tcomponent1(acomponent).fcomponents); +{$warnings on} +end; + +type + pastedcompinfoty = record + comp: tcomponent; + origname: string; + end; +var + pastedcomps: array of pastedcompinfoty; + +procedure clearpastedcomponents; +begin + pastedcomps:= nil; +end; + +procedure addpastedcomponentname(const acomp: tcomponent); +begin + setlength(pastedcomps,high(pastedcomps)+2); + with pastedcomps[high(pastedcomps)] do begin + comp:= acomp; + origname:= comp.name; + end; +end; + +function findpastedcomponent(const origname: string): tcomponent; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(pastedcomps) do begin + if pastedcomps[int1].origname = origname then begin + result:= pastedcomps[int1].comp; + break; + end; + end; +end; + +function findpastedcomponentname(const comp: tcomponent): string; +var + int1: integer; +begin + result:= ''; + for int1:= 0 to high(pastedcomps) do begin + if pastedcomps[int1].comp = comp then begin + result:= pastedcomps[int1].origname; + break; + end; + end; +end; + +function setloading(const acomponent: tcomponent; const avalue: boolean): boolean; +begin + result:= csdesigning in acomponent.componentstate; +{$warnings off} + with tcomponent1(acomponent) do begin +{$warnings on} + if avalue then begin + include(fcomponentstate,csloading); + end + else begin + exclude(fcomponentstate,csloading); + end; + end; +end; + +procedure clearinline(const acomponent: tcomponent); +var + int1: integer; +begin + tmsecomponent(acomponent).setinline(false); + for int1:= 0 to acomponent.componentcount - 1 do begin + clearinline(acomponent.components[int1]); + end; +end; + +procedure initinline(const acomponent: tcomponent); + //sets inline, resets ancestor, sets ancestor of children + //clears inline of children +var + int1: integer; + comp1: tcomponent; +begin +{$warnings off} + with tcomponent1(acomponent) do begin +{$warnings on} + exclude(fcomponentstate,csancestor); + include(fcomponentstate,csinline); + end; + for int1:= 0 to acomponent.componentcount - 1 do begin + comp1:= acomponent.components[int1]; + tcomponent1(comp1).setancestor(true); +// clearinline(comp1); + end; +end; + +procedure checkinline(const acomponent: tcomponent); +var + int1: integer; + comp1: tcomponent1; +begin + if csinline in acomponent.componentstate then begin +{$warnings off} + with tcomponent1(acomponent) do begin +{$warnings on} + exclude(fcomponentstate,csancestor); + end; + for int1:= 0 to acomponent.componentcount - 1 do begin + comp1:= tcomponent1(acomponent.components[int1]); + comp1.setancestor(true); + clearinline(comp1); + end; + end + else begin + for int1:= 0 to acomponent.componentcount - 1 do begin + checkinline(acomponent.components[int1]); + end; + end; +end; + +procedure initrootdescendent(const acomponent: tcomponent); +begin + clearinline(acomponent); + tcomponent1(acomponent).setancestor(true); +end; + +function swapmethodtable(const instance: tobject; const newtable: pointer): pointer; +var + {$ifdef mswindows} + ca1: longword; + {$endif} + methodtabpo: ppointer; +begin + methodtabpo:= ppointer(pchar(instance.classtype)+vmtmethodtable); + {$ifdef mswindows} + virtualprotect(methodtabpo,sizeof(pointer),page_readwrite,{$ifdef FPC}@{$endif}ca1); + {$endif} + result:= methodtabpo^; + methodtabpo^:= newtable; + {$ifdef mswindows} + virtualprotect(methodtabpo,sizeof(pointer),ca1,nil); + {$endif} +end; + +procedure writeset(const writer: twriter; const value: tintegerset; + const atypeinfo: ptypeinfo); +var +{$ifndef FPC} + i: integer; +{$endif} + basetype: ptypeinfo; +begin + basetype:= gettypedata(atypeinfo)^.comptype{$ifndef FPC}^{$endif}; + with twriter1(writer) do begin + driver.writeset(longint(value),basetype); + end; +end; + +function checkenumvalue(typeinfo : ptypeinfo;const name : string) : integer; +begin + result:= getenumvalue(typeinfo,name); + if result < 0 then begin + raise exception.create('In valid enum name for '+typeinfo^.name+ + ': "'+name+'".'); + end; +end; + +function readenum(const reader: treader; const atypeinfo: ptypeinfo): integer; +begin + result:= getenumvalue(atypeinfo,reader.readident); + if result < 0 then begin + raise ereaderror.create(sinvalidpropertyvalue); + end; +end; + +procedure writeenum(const writer: twriter; const value: integer; + const atypeinfo: ptypeinfo); +begin + writer.writeident(getenumname(atypeinfo,value)); +end; + +function readset(const reader: treader; const atypeinfo: ptypeinfo): tintegerset; +begin + {$ifdef FPC} + reader.checkvalue(vaset); + result:= tintegerset(treader1(reader).driver.readset( + gettypedata(atypeinfo)^.comptype{$ifndef fpc}^{$endif})); + {$else} + result:= tintegerset(treader1(reader).readset(atypeinfo)); + {$endif} +end; + +function readsplitset(const reader: treader; const info: setsplitinfoty; + out set1,set2: tintegerset): boolean; + //true if splitted +var + int1,int2: integer; + str1: string; + po1,po2: ptypeinfo; +begin + reader.checkvalue(vaset); + set1:= []; + set2:= []; + result:= false; + with info do begin + while true do begin + po1:= gettypedata(maintype)^.comptype{$ifndef FPC}^{$endif}; + po2:= gettypedata(splittype)^.comptype{$ifndef FPC}^{$endif}; + str1:= reader.driver.readstr; + if str1 = '' then begin + break; + end; + int1:= getenumvalue(po1,str1); + if int1 >= 0 then begin + include(set1,int1); + end + else begin + for int2:= 0 to high(enums) do begin + if enums[int1].oldenum = str1 then begin + int1:= getenumvalue(po2,enums[int1].newenum); + if int1 >= 0 then begin + include(set2,int1); + end; + result:= true; + break; + end; + end; + end; + if int1 < 0 then begin + repeat + until reader.driver.readstr = ''; + raise ereaderror.create(sinvalidpropertyvalue); + end; + end; + end; +end; + +function checkcanevent(const acomponent: tcomponent; const event: tmethod): boolean; +begin + result:= (event.code <> nil) and (acomponent <> nil) and (event.data <> nil) and + (acomponent.componentstate * [csloading,csdesigning,csdestroying] = []); +end; + +function checkcanevent(const event: tmethod): boolean; +begin + result:= (event.code <> nil) and (event.data <> nil); +end; + +procedure writestringar(const writer: twriter; const ar: stringarty); +var + int1: integer; +begin + writer.writelistbegin; + for int1:= 0 to high(ar) do begin + writer.writestring(ar[int1]); + end; + writer.writelistend; +end; + +procedure writestringar(const writer: twriter; const ar: msestringarty); +var + int1: integer; +begin + writer.writelistbegin; + for int1:= 0 to high(ar) do begin + writer.writeunicodestring(ar[int1]); + end; + writer.writelistend; +end; + +procedure readstringar(const reader: treader; out ar: stringarty); +var + int1: integer; +begin + int1:= 0; + ar:= nil; + reader.readlistbegin; + while not reader.endoflist do begin + additem(ar,reader.readstring,int1); + end; + reader.readlistend; + setlength(ar,int1); +end; + +procedure readstringar(const reader: treader; out ar: msestringarty); +var + int1: integer; +begin + int1:= 0; + ar:= nil; + reader.readlistbegin; + while not reader.endoflist do begin + additem(ar,reader.readunicodestring,int1); + end; + reader.readlistend; + setlength(ar,int1); +end; + +procedure readintar(const reader: treader; out ar: int32arty); +var + i1: int32; +begin + i1:= 0; + ar:= nil; + reader.readlistbegin; + while not reader.endoflist do begin + additem(ar,reader.readinteger,i1); + end; + reader.readlistend; + setlength(ar,i1); +end; + +procedure readintar(const reader: treader; out ar: int16arty); +var + i1: int32; +begin + i1:= 0; + ar:= nil; + reader.readlistbegin; + while not reader.endoflist do begin + additem(ar,int16(reader.readinteger),i1); + end; + reader.readlistend; + setlength(ar,i1); +end; + +procedure writeintar(const writer: twriter; const ar: int32arty); +var + i1: int32; +begin + writer.writelistbegin; + for i1:= 0 to high(ar) do begin + writer.writeinteger(ar[i1]); + end; + writer.writelistend; +end; + +procedure writeintar(const writer: twriter; const ar: int16arty); +var + i1: int32; +begin + writer.writelistbegin; + for i1:= 0 to high(ar) do begin + writer.writeinteger(ar[i1]); + end; + writer.writelistend; +end; + +procedure readrecordar(const reader: treader; out ar; + const typeinfo: pdynarraytypeinfo; const readproc: readrecordprocty); +var + int1: integer; + lint1: sizeint; +begin + int1:= 0; + reader.readlistbegin; + while not reader.endoflist do begin + reader.readlistbegin; + readproc(reader,additempo(ar,typeinfo,int1)^); + reader.readlistend; + end; + reader.readlistend; + lint1:= int1; + dynarraysetlength(pointer(ar),typeinfo,1,@lint1); +end; + +procedure writerecordar(const writer: twriter; const ar; + const typeinfo: pdynarraytypeinfo; const writeproc: writerecordprocty); +var + int1,int2: integer; +begin + writer.writelistbegin; + int2:= dynarrayelesize(typeinfo); + for int1:= 0 to high(pointerarty(ar)) do begin + writer.writelistbegin; + writeproc(writer,(pointer(ar)+int2*int1)^); + writer.writelistend; + end; + writer.writelistend; +end; + +function valuescaletorange(const reader: treader): real; +begin + result:= reader.readfloat; + if result <> 0 then begin + result:= 1/result; + end; +end; + +procedure lockfindglobalcomponent; //switch of findglobalcomponent +begin + modules.lock; +end; + +procedure unlockfindglobalcomponent; //switch on findglobalcomponent +begin + modules.unlock; +end; + +function findglobalcomponentlocked: boolean; +begin + result:= modules.flocked <> 0; +end; + +function ownscomponent(const owner: tcomponent; const child: tcomponent): boolean; +var + comp1: tcomponent; +begin + result:= false; + comp1:= child; + while comp1 <> nil do begin + if comp1 = owner then begin + result:= true; + break; + end; + comp1:= comp1.owner; + end; +end; + +function ownernamepath(const acomponent: tcomponent): string; +var + comp: tcomponent; +begin + if acomponent = nil then begin + result:= '' + end + else begin + with acomponent do begin + result:= name; + comp:= owner; + while comp <> nil do begin + if comp.Name <> '' then begin + result:= comp.Name + '.' + result; + end; + comp:= comp.Owner; + end; + end; + end; +end; + +function ownernamepath(const aroot: tcomponent; + const acomponent: tcomponent): string; + //namepath from aroot to acomponent separated by '.' + //excluding aroot +var + comp: tcomponent; +begin + if acomponent = nil then begin + result:= '' + end + else begin + with acomponent do begin + result:= name; + comp:= owner; + while (comp <> nil) and (comp <> aroot) do begin + if comp.Name <> '' then begin + result:= comp.Name + '.' + result; + end; + comp:= comp.Owner; + end; + end; + end; +end; + +function namepathowner(const acomponent: tcomponent): string; + //namepath from acomponent to root separated by '.' +var + comp: tcomponent; +begin + if acomponent = nil then begin + result:= '' + end + else begin + with acomponent do begin + result:= name; + comp:= owner; + while comp <> nil do begin + if comp.Name <> '' then begin + result:= result + '.' + comp.Name; + end; + comp:= comp.Owner; + end; + end; + end; +end; + +function componentpathowner(const acomponent: tcomponent): componentarty; + //componentpath from acomponent to root +var + count: integer; + comp1: tcomponent; +begin + count:= 0; + if acomponent <> nil then begin + comp1:= acomponent; + repeat + {$ifndef FPC} + addpointeritem(pointerarty(result),pointer(comp1),count); + {$else} + additem(pointerarty(result),pointer(comp1),count); + {$endif} + comp1:= comp1.owner; + until comp1 = nil; + end; + setlength(result,count); +end; + +function ownercomponentpath(const acomponent: tcomponent): componentarty; + //componentpath from root to acomponent +begin + result:= componentarty(reversearray(pointerarty( + componentpathowner(acomponent)))); +end; + +function getnumberedname(const acomp: tcomponent; + const namebase: string): string; +var + int1: integer; +begin + int1:= 0; + repeat + result:= namebase+inttostr(int1); + until acomp.findcomponent(result) = nil; +end; + +function rootcomponent(const acomponent: tcomponent): tcomponent; +begin + result:= acomponent; + if result <> nil then begin + while result.owner <> nil do begin + result:= result.owner; + end; + end; +end; + +procedure setcomponentorder(const owner: tcomponent; const anames: msestringarty); +var + comp1: tcomponent; + int1: integer; +begin + for int1:= 0 to high(anames) do begin + comp1:= owner.findcomponent(ansistring(anames[int1])); +{$warnings off} + with tcomponent1(owner).fcomponents do begin +{$warnings on} + remove(comp1); + add(comp1); + end; + end; +end; + +{ trefreshwriter } + +type + tgetcomponentchildren = class + private + fcomp: tcomponent; + froot: tcomponent; + fnestedowners: boolean; + fnestedparents: boolean; + fchildren: componentarty; + fcount: integer; + fcurrroot: tcomponent; + function getchildrenar: componentarty; + protected + procedure childproc(child: tcomponent); + public + constructor create(const acomp: tcomponent; const aroot: tcomponent; + const nestedowners: boolean = false; + const nestedparents: boolean = false); + property children: componentarty read getchildrenar; + end; + +{ tgetcomponentchildren } + +constructor tgetcomponentchildren.create(const acomp: tcomponent; + const aroot: tcomponent; const nestedowners: boolean = false; + const nestedparents: boolean = false); +begin + fcomp:= acomp; + froot:= aroot; + fnestedowners:= nestedowners; + fnestedparents:= nestedparents; +end; + +procedure tgetcomponentchildren.childproc(child: tcomponent); +begin + additem(pointerarty(fchildren),child,fcount); + if fnestedparents then begin + tcomponent1(child).getchildren({$ifdef FPC}@{$endif}childproc,fcurrroot); + end; +end; + +function tgetcomponentchildren.getchildrenar: componentarty; +var + comp1: tcomponent; +begin + fchildren:= nil; + fcount:= 0; + if fnestedowners then begin + comp1:= fcomp; + while (comp1 <> froot) and (comp1 <> nil) do begin + fcurrroot:= comp1; + tcomponent1(fcomp).getchildren({$ifdef FPC}@{$endif}childproc,comp1); + comp1:= comp1.owner; + end; + end; + if froot <> nil then begin + fcurrroot:= froot; + tcomponent1(fcomp).getchildren({$ifdef FPC}@{$endif}childproc,froot); + end; + setlength(fchildren,fcount); + result:= fchildren; +end; + +function getcomponentchildren(const acomp: tcomponent; + const aroot: tcomponent; + const nestedowners: boolean = false; + const nestedparents: boolean = false): componentarty; +var + obj: tgetcomponentchildren; +// ev1: getchildreneventty; +begin +// ev1:= onstreaminggetchildren; +// try +// onstreaminggetchildren:= nil; + obj:= tgetcomponentchildren.create(acomp,aroot,nestedowners,nestedparents); + result:= obj.children; + obj.free; +// finally +// onstreaminggetchildren:= ev1; +// end; +end; + +function getlinkedcomponents(const acomponent: tcomponent): componentarty; +var + int1: integer; +begin + result:= nil; +{$warnings off} + with tcomponent1(acomponent) do begin +{$warnings on} + if ffreenotifies <> nil then begin + for int1:= 0 to ffreenotifies.count - 1 do begin + additem(pointerarty(result),ffreenotifies[int1]); + end; + end; + end; +end; + +function getpropinfoar(const atypeinfo: ptypeinfo): propinfopoarty; +var + po1: ptypedata; +begin + po1:= gettypedata(atypeinfo); + setlength(result,po1^.PropCount); + getpropinfos(atypeinfo,pointer(result)); +end; + +function getpropinfoar(const obj: tobject): propinfopoarty; +begin + if (obj <> nil) and (obj.classinfo <> nil) then begin + result:= getpropinfoar(obj.classinfo); + end + else begin + result:= nil; + end; +end; + +function getenumnames(const atypeinfo: ptypeinfo): msestringarty; +var + typedata1: ptypedata; + int1{,int2}: integer; +begin + typedata1:= gettypedata(atypeinfo); + with typedata1^ do begin + setlength(result,maxvalue-minvalue+1); + for int1:= 0 to high(result) do begin + result[int1]:= msestring(getenumname(atypeinfo,int1)); + end; + { + int2:= 0; + for int1:= MinValue to MaxValue do begin + result[int2]:= getenumname(atypeinfo,int1); + inc(int2); + end; + } + end; +end; + +function getclasspropvalue(const instance: tobject; const apropname: string; + const aclass: tclass): tobject; +var + po1: ppropinfo; + po2: ptypeinfo; +begin + result:= nil; + if instance <> nil then begin + po1:= getpropinfo(instance,apropname); + if (po1 <> nil) then begin + po2:= po1^.proptype; + if (po2^.kind = tkclass) and + (gettypedata(po2)^.classtype.inheritsfrom(aclass)) then begin + {$ifdef cpu64} + result:= tobject(ptruint(getint64prop(instance,po1))); + {$else} + result:= tobject(ptruint(getordprop(instance,po1))); + {$endif} + end; + end; + end; +end; + +function getclasspropvalue(const instance: tobject; const apropname: string; + const aclass: tclass; out avalue: tobject): boolean; +begin + avalue:= getclasspropvalue(instance,apropname,aclass); + result:= avalue <> nil; +end; + +type + tcomponentdestroyer = class(tcomponent) + private + fcomps: componentarty; + fcurrentcomponent: tcomponent; + protected + procedure notification(acomponent: tcomponent; + operation: toperation); override; + public + constructor create(const acomps: componentarty); reintroduce; + end; + +{ tcomponentdestroyer } + +constructor tcomponentdestroyer.create(const acomps: componentarty); +var + int1: integer; +begin + inherited create(nil); + fcomps:= copy(acomps); + for int1:= 0 to high(fcomps) do begin + fcomps[int1].freenotification(self); + end; + for int1:= 0 to high(fcomps) do begin + fcurrentcomponent:= fcomps[int1]; + fcurrentcomponent.free; + end; +end; + +procedure tcomponentdestroyer.notification(acomponent: tcomponent; + operation: toperation); +var + int1: integer; +begin + if (operation = opremove) and (acomponent <> fcurrentcomponent) then begin + for int1:= high(fcomps) downto 0 do begin + if fcomps[int1] = acomponent then begin + fcomps[int1]:= nil; + break; + end; + end; + end; + inherited; +end; + +procedure freecomponents(const acomponents: componentarty); + //uses freenotification +begin + tcomponentdestroyer.create(acomponents).free; +end; + +function copycomponent(const source: tcomponent; const aowner: tcomponent = nil; + const onfindancestor: tfindancestorevent = nil; + const onfindcomponentclass: tfindcomponentclassevent = nil; + const oncreatecomponent: tcreatecomponentevent = nil; + const onancestornotfound: tancestornotfoundevent = nil): tcomponent; + //copy by stream.writecomponent, readcomponent + + procedure copyflags(const source: tcomponent; const dest: tcomponent); + var + int1: integer; + comp1,comp2: tcomponent; + begin + for int1:= 0 to source.componentcount - 1 do begin + comp1:= source.components[int1]; + comp2:= dest.findcomponent(comp1.name); + if comp2 <> nil then begin + if csancestor in comp1.componentstate then begin + tcomponent1(comp2).setancestor(true); + end + else begin + copyflags(comp1,comp2); + end; + end; + end; + end; //copyflags + +var + stream: tmemorystream; + writer: twritermse; + reader: treader; + {$ifdef mse_debugcopycomponent} + debugstream: ttextstream; + {$endif} +begin + result:= tcomponent(source.NewInstance); + try + if csdesigning in source.componentstate then begin + tcomponent1(result).setdesigning(true); +// result.name:= source.name; + end; + result.Create(aowner); + stream:= tmemorystream.Create; + try + writer:= twritermse.Create(stream,4096,false); + try + writer.OnFindAncestor:= onfindancestor; + writer.Writerootcomponent(source); + finally + writer.Free; + end; + {$ifdef mse_debugcopycomponent} + debugstream:= ttextstream.create; + stream.position:= 0; + objectbinarytotextmse(stream,debugstream); + debugstream.position:= 0; + writeln(output,'***copycomponent source'); + dumpcomponent(source); + debugstream.writetotext(output); + flush(output); + {$endif} + stream.Position:= 0; + reader:= treader.Create(stream,4096); + try + reader.OnFindComponentClass:= onfindcomponentclass; + reader.OnCreateComponent:= oncreatecomponent; + reader.onancestornotfound:= onancestornotfound; +// reader.ancestor:= aancestor; + reader.ReadrootComponent(result); + if (source.owner = nil) and (csancestor in source.componentstate) then begin + tcomponent1(source).setancestor(true); + end + else begin + copyflags(source,result); + end; + finally + reader.free; + end; + {$ifdef mse_debugcopycomponent} + stream.clear; + writer:= twritermse.Create(stream,4096); + writer.Writerootcomponent(result); + writer.Free; + stream.position:= 0; + debugstream.clear; + objectbinarytotextmse(stream,debugstream); + debugstream.position:= 0; + writeln(output,'***copycomponent dest'); + dumpcomponent(result); + debugstream.writetotext(output); + flush(output); + debugstream.free; + {$endif} + finally + stream.Free; + end; + except + result.free; + raise; + end; + if source is tmsecomponent then begin + tmsecomponent(result).factualclassname:= tmsecomponent(source).factualclassname; + end; +end; + + +function issubcomponent(const root,child: tcomponent): boolean; +var + comp: tcomponent; +begin + result:= false; + comp:= child.Owner; + while comp <> nil do begin + if comp = root then begin + result:= true; + break; + end; + comp:= comp.Owner; + end; +end; + +function fixupsetchildorder(const sender: tcomponent; + const child: tcomponent; const order: integer): boolean; + //true if handled +begin + result:= false; + if (csloading in child.componentstate) and + (child.getparentcomponent = nil) and ownscomponent(sender,child) and + (child.owner.componentstate*[csreading,csinline] = [csreading,csinline]) and + (child.owner <> sender) then begin + //treader set root as parent istead of lookuproot. + tcomponent1(child.owner).setchildorder(child,order); + result:= true; + end; +end; + +function createmodule(aowner: tcomponent; instanceclass: msecomponentclassty; + var reference): tmsecomponent; +var + instance: tmsecomponent; +begin + instance := tmsecomponent(instanceclass.newinstance); + additem(pointerarty(fmodulestoregister),instance); +// fmodules.add(instance); //not before completely loaded, + //submodules call globalfixupreferences + if @reference <> nil then begin + tmsecomponent(reference):= instance; + end; + try + instance.create(aowner); + except + if @reference <> nil then begin + tcomponent(reference) := nil; + end; + raise; + end; + result:= instance; +end; + + +function findmoduledata(const aclassname: string; + out aparentclassname: string): pobjectdataty; +var + po1: pobjectdatainfoty; +begin + result:= nil; + aparentclassname:= ''; + po1:= objectdatalist.find(aclassname,''); + if po1 <> nil then begin + aparentclassname:= po1^.objectclass.classparent.classname; + result:= po1^.objectdata; + end; +end; + +procedure loadmodule(const instance: tcomponent; + const po1: pobjectdatainfoty; asinherited: boolean); +var + stream: tobjectdatastream; + reader: treader; + po2: pobjectdataty; +// intf: iobjectlink; +begin + po2:= po1^.langobjectdata; + if po2 = nil then begin + po2:= po1^.objectdata; + end; + stream:= tobjectdatastream.create(po2); + try + globalnamespace.beginwrite; + if asinherited then begin + reader := tasinheritedreader.create(stream, 4096,true); + end + else begin + reader := treader.create(stream, 4096); + end; + try + reader.onancestornotfound:= {$ifdef FPC}@{$endif}modules.ancestornotfound; + reader.readrootcomponent(instance); + finally + reader.free; + end; + finally + globalnamespace.endwrite; + stream.free; + end; + if floadedlist = nil then begin + floadedlist:= tloadedlist.create(nil); + end; + instance.freenotification(floadedlist); +end; + +const + skipmark = 'h71%z/ur'; + +type + trefresheventhandler = class(tcomponent) + private + fcomponentar: componentarty; + procedure onsetname(reader: treader; component: tcomponent; var aname: string); + procedure onerror(reader: treader; const message: string; var handled: boolean); + procedure doancestornotfound(reader: treader; const componentname: string; + componentclass: tpersistentclass; var component: tcomponent); + protected + procedure notification(acomponent: tcomponent; operation: toperation); + override; + public + destructor destroy; override; + end; + + trefreshexception = class(exception) + end; + +destructor trefresheventhandler.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fcomponentar) do begin + fcomponentar[int1].free; //FPC does not free the component + end; + inherited; +end; + +procedure trefresheventhandler.notification(acomponent: tcomponent; operation: toperation); +begin + if (operation = opremove) then begin + removeitem(pointerarty(fcomponentar),acomponent); + end; + inherited; +end; + +procedure trefresheventhandler.onerror(reader: treader; const message: string; + var handled: boolean); +begin + if message = skipmark then begin + handled:= true; + end; +end; + +procedure trefresheventhandler.onsetname(reader: treader; + component: tcomponent; var aname: string); +begin +exit; + if (component.owner <> nil) and ((csinline in component.owner.componentstate) and + not(csancestor in component.componentstate) or + (component.owner.findcomponent(aname) <> nil)) then begin + additem(pointerarty(fcomponentar),component); + component.freenotification(self); + raise trefreshexception.create(skipmark); //skip the component + end; +end; + +procedure trefresheventhandler.doancestornotfound(reader: treader; + const componentname: string; componentclass: tpersistentclass; + var component: tcomponent); +begin + if component = nil then begin + component:= tasinheritedreader(reader).existingcomp; + if (component = nil) then begin + if assigned(reader.oncreatecomponent) then begin + reader.oncreatecomponent(reader,tcomponentclass(componentclass),component); + end; + if component = nil then begin + component:= tcomponent(componentclass.newinstance); + {$warnings off} + with tcomponent1(component) do begin + {$warnings on} + fcomponentstate:= componentstate + [csloading,csancestor]; + end; + try + component.create(reader.owner); + except + component.free; + raise; + end; + end; + end; + end; +end; + + +type + tcomponentdeleter = class(tcomponent) + private + fdelcomponents: componentarty; + protected + procedure notification(acomponent: tcomponent; operation: toperation); override; + public + constructor create(const acomponents: componentarty); reintroduce; + end; + +{ tcomponentdeleter } + +constructor tcomponentdeleter.create(const acomponents: componentarty); +var + int1: integer; +begin + inherited create(nil); + fdelcomponents:= acomponents; + for int1:= 0 to high(fdelcomponents) do begin + if fdelcomponents[int1] <> nil then begin + fdelcomponents[int1].freenotification(self); + end; + end; +end; + +procedure tcomponentdeleter.notification(acomponent: tcomponent; + operation: toperation); +var + int1: integer; +begin + inherited; + if operation = opremove then begin + for int1:= 0 to high(fdelcomponents) do begin + if fdelcomponents[int1] = acomponent then begin + fdelcomponents[int1]:= nil; + end; + end; + end; +end; + +type + trefreshancestoreventhandler = class(trefresheventhandler) + private + fnonancestors: componentarty; + fsetancestorroot: tcomponent; + protected + procedure setchildancestor(child: tcomponent); + procedure setancestors(const acomponent: tcomponent); + procedure notification(acomponent: tcomponent; operation: toperation); + override; + end; + +procedure trefreshancestoreventhandler.notification(acomponent: tcomponent; + operation: toperation); +begin + if operation = opremove then begin + removeitem(pointerarty(fnonancestors),pointer(acomponent)); + end; + inherited; +end; + +procedure trefreshancestoreventhandler.setchildancestor(child: tcomponent); +begin + with tcomponent1(child) do begin + setancestor(true); + getchildren({$ifdef FPC}@{$endif}setchildancestor,fsetancestorroot); + end; +end; + +procedure trefreshancestoreventhandler.setancestors(const acomponent: tcomponent); +begin + fsetancestorroot:= acomponent.owner; + setchildancestor(acomponent); +end; + +procedure refreshancestor(var deletedcomps: componentarty; + const descendent,newancestor,oldancestor: tcomponent; + const revert: boolean; + const onfindancestor: tfindancestorevent = nil; + const onfindcomponentclass: tfindcomponentclassevent = nil; + const oncreatecomponent: tcreatecomponentevent = nil; + {$ifdef mse_nomethodswap} + const onsetmethodproperty: tsetmethodpropertyevent = nil; + const onwritemethodproperty: twritemethodpropertyevent = nil; + const newcomponent: system.pboolean = nil + {$else} + const onfindmethod: tfindmethodevent = nil; + const sourcemethodtab: pointer = nil; + const destmethodtab: pointer = nil + {$endif}); + +var + descendentroot: tcomponent; + newancestorroot: tcomponent; + oldancestorroot: tcomponent; + eventhandler: trefreshancestoreventhandler; + + procedure deletecomps(const adescendent,anewancestor,aoldancestor: tcomponent); + var + deleter: tcomponentdeleter; + descendentar,newancestorar,oldancestorar: componentarty; + int1,int2: integer; + comp1,comp2: tcomponent; + str1: string; + begin + descendentar:= getcomponentchildren(adescendent,descendentroot,true); + //nested components + deleter:= tcomponentdeleter.create(descendentar); + try + newancestorar:= getcomponentchildren(anewancestor,newancestorroot,true); + if not revert then begin + oldancestorar:= getcomponentchildren(aoldancestor,oldancestorroot,true); + end; + for int1:= 0 to high(descendentar) do begin + if descendentar[int1] <> nil then begin + str1:= descendentar[int1].name; + comp1:= nil; + for int2:= 0 to high(newancestorar) do begin + if newancestorar[int2].name = str1 then begin + comp1:= newancestorar[int2]; + break; + end; + end; + comp2:= nil; + if not revert then begin + for int2:= 0 to high(oldancestorar) do begin + if oldancestorar[int2].name = str1 then begin + comp2:= oldancestorar[int2]; + break; + end; + end; + end; + if ((comp1 = nil) or (finditem(pointerarty(deletedcomps),comp1) >= 0)) and + (revert or (comp2 <> nil)) then begin + additem(pointerarty(deletedcomps),pointer(descendentar[int1])); +// freedesigncomponent(descendentar[int1]); +// descendentar[int1].free; + end + else begin + if revert or (comp2 <> nil) then begin + deletecomps(descendentar[int1],comp1,comp2); + end + else begin + with tcomponent1(descendentar[int1]) do begin + if owner.componentstate * [csinline,csancestor] <> [] then begin + eventhandler.setancestors(descendentar[int1]); + end; + end; + end; + end; + end; + end; + if not revert then begin + with eventhandler do begin + for int1:= 0 to high(fnonancestors) do begin + tcomponent1(fnonancestors[int1]).setancestor(false); + end; + end; + end; + finally + deleter.free; + end; + end; + +var + nonancestors: componentarty; + stream1,stream2,stream4: tmemorystream; + writer: twritermse; + reader: tasinheritedreader; + inl: boolean; + int1,int2: integer; + intf1: iactivatorclient; +{$ifndef mse_nomethodswap} + tabbefore: pointer; +{$endif} + {$ifdef mse_debugrefresh} + comp1: tcomponent; + stream3: ttextstream; + {$endif} + +begin + descendentroot:= rootcomponent(descendent); + newancestorroot:= rootcomponent(newancestor); + oldancestorroot:= rootcomponent(oldancestor); + if not revert then begin + nonancestors:= getcomponentchildren(descendent,descendentroot,false,true); + //nested components + int2:= 0; + for int1:= 0 to high(nonancestors) do begin + if not (csancestor in nonancestors[int1].componentstate) then begin + nonancestors[int2]:= nonancestors[int1]; + inc(int2); + end; + end; + setlength(nonancestors,int2); + end; + +{$ifdef mse_debugrefresh} + if revert then begin + write('****revert '); + end + else begin + write('****refresh '); + end; + comp1:= descendentroot; + writeln('root: '+comp1.name+' descendent: '+ descendent.name + ' newancestor: '+ + newancestor.name + ' oldancestor: '+oldancestor.name); + dumpcomponent(descendent,'*descendent'); + dumpcomponent(newancestor,'*newancestor'); + dumpcomponent(oldancestor,'*oldancestor'); + stream3:= ttextstream.create; +{$endif} + + eventhandler:= trefreshancestoreventhandler.create(nil); + for int1:= 0 to high(nonancestors) do begin + nonancestors[int1].freenotification(eventhandler); + end; + eventhandler.fnonancestors:= nonancestors; + nonancestors:= nil; + stream1:= tmemorystream.Create; + stream2:= tmemorystream.Create; + stream4:= tmemorystream.Create; + + try + writer:= trefreshwriter.Create(stream1,4096,false); +{$ifdef mse_nomethodswap} + writer.onwritemethodproperty:= onwritemethodproperty; +{$else} + tabbefore:= nil; //compiler warning + if destmethodtab <> nil then begin + tabbefore:= swapmethodtable(descendent,destmethodtab); + end; +{$endif} + try + writer.OnFindAncestor:= onfindancestor; + writer.WriteDescendent(descendent,oldancestor); //changes from oldancestor + finally +{$ifndef mse_nomethodswap} + if destmethodtab <> nil then begin + swapmethodtable(descendent,tabbefore); + end; +{$endif} + writer.Free; + end; + +{$ifdef mse_debugrefresh} + stream1.position:= 0; + objectbinarytotextmse(stream1,stream3); + stream3.position:= 0; + writeln('**changes descendent->oldancestor'); + stream3.writetotext(output); +{$endif} + + writer:= twritermse.Create(stream2,4096,false,true); + inl:= csinline in newancestor.componentstate; + if csinline in descendent.componentstate then begin + tmsecomponent(newancestor).SetInline(true); + end; + +{$ifdef mse_nomethodswap} + writer.onwritemethodproperty:= onwritemethodproperty; +{$else} + if sourcemethodtab <> nil then begin + tabbefore:= swapmethodtable(newancestor,sourcemethodtab); + end; +{$endif} + + try + writer.OnFindAncestor:= onfindancestor; + writer.WriteDescendent(newancestor,descendent); + //new state before deactivate + writer.free; + {$ifdef mse_debugrefresh} + stream2.position:= 0; + stream3.setsize(0); + objectbinarytotextmse(stream2,stream3); + stream3.position:= 0; + writeln('**changes newancestor->descendent before deactivate'); + stream3.writetotext(output); + {$endif} + + if descendent is tactcomponent then begin + tactcomponent(descendent).deactivate(true); + end + else begin + if getcorbainterface(descendent,typeinfo(iactivatorclient),intf1) then begin + intf1.setactive(false); + end; + end; + + writer:= twritermse.Create(stream4,4096,false,true); + {$ifdef mse_nomethodswap} + writer.onwritemethodproperty:= onwritemethodproperty; + {$endif} + writer.WriteDescendent(newancestor,descendent); //new state after deactivate + finally + writer.free; + tmsecomponent(newancestor).SetInline(inl); +{$ifndef mse_nomethodswap} + if sourcemethodtab <> nil then begin + swapmethodtable(newancestor,tabbefore); + end; +{$endif} + end; + + {$ifdef mse_debugrefresh} + stream4.position:= 0; + stream3.setsize(0); + objectbinarytotextmse(stream4,stream3); + stream3.position:= 0; + writeln('**changes newancestor->descendent after deactivate'); + stream3.writetotext(output); + {$endif} + + stream1.Position:= 0; + stream2.Position:= 0; + stream4.Position:= 0; + + {$ifndef mse_nomethodswap} + if destmethodtab <> nil then begin + tabbefore:= swapmethodtable(descendent,destmethodtab); + end; + {$endif} + try + reader:= tasinheritedreader.create(stream2,4096,inl{false}); + //new state before deactivate + reader.OnFindComponentClass:= onfindcomponentclass; + reader.OnCreateComponent:= oncreatecomponent; + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= onsetmethodproperty; + {$else} + reader.onfindmethod:= onfindmethod; + {$endif} + reader.onancestornotfound:= + {$ifdef FPC}@{$endif}eventhandler.doancestornotfound; + {$ifdef mse_debugrefresh} + writeln('**reading changes newancestor->descendent before deactivate'); + {$endif} + reader.ReadRootComponent(descendent); //changes + if newcomponent <> nil then begin + newcomponent^:= reader.newcomp; + end; + reader.free; + + reader:= tasinheritedreader.create(stream4,4096,inl{false}); + //new state after deactivate + reader.OnFindComponentClass:= onfindcomponentclass; + reader.OnCreateComponent:= oncreatecomponent; + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= onsetmethodproperty; + {$else} + reader.onfindmethod:= onfindmethod; + {$endif} + reader.onancestornotfound:= + {$ifdef FPC}@{$endif}eventhandler.doancestornotfound; + {$ifdef mse_debugrefresh} + writeln('**reading changes newancestor->descendent after deactivate'); + {$endif} + reader.ReadRootComponent(descendent); //changes + + if not revert then begin + reader.free; + reader:= tasinheritedreader.create(stream1,4096,false); //restore old changes + reader.OnFindComponentClass:= onfindcomponentclass; + reader.OnCreateComponent:= oncreatecomponent; + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= onsetmethodproperty; + {$else} + reader.onfindmethod:= onfindmethod; + {$endif} + reader.onsetname:= {$ifdef FPC}@{$endif}eventhandler.onsetname; + reader.onerror:= {$ifdef FPC}@{$endif}eventhandler.onerror; + reader.onancestornotfound:= + {$ifdef FPC}@{$endif}eventhandler.doancestornotfound; + {$ifdef mse_debugrefresh} + writeln('**reading changes descendent->oldancestor'); + {$endif} + reader.ReadRootComponent(descendent); //changes descendent->oldancestor + end; + + {$ifdef mse_debugrefresh} + debugwriteln('**deleteldcomps before delete '+ + debugcomprootnames(deletedcomps)); + {$endif} + + finally + {$ifndef mse_nomethodswap} + if destmethodtab <> nil then begin + swapmethodtable(descendent,tabbefore); + end; + {$endif} + reader.free; + removefixupreferences(descendent,''); + end; + + finally + try + nonancestors:= eventhandler.fnonancestors; + deletecomps(descendent,newancestor,oldancestor); + {$ifdef mse_debugrefresh} + debugwriteln('**deleteldcomps after delete '+ + debugcomprootnames(deletedcomps)); + dumpcomponent(descendent,'**descendent'); + {$endif} + finally + stream1.Free; + stream2.Free; + stream4.Free; + + {$ifdef mse_debugrefresh} + stream3.free; + {$endif} + + eventhandler.free; + end; + end; + +end; + +type + globalloadinfoty = record + modules: msecomponentarty; + modulecount: integer; + end; + globalloadinfoarty = array of globalloadinfoty; + + tloadmoduletracker = class(tlinkedobject) + private + fgloballoadings: globalloadinfoarty; + fgloballevel: integer; + protected + procedure unlink(var ainfo: globalloadinfoty); + procedure objectevent(const sender: tobject; const event: objecteventty); + override; + public + constructor create; + procedure moduleloaded(const amodule: tmsecomponent); + procedure beginglobal; + procedure endglobal; + procedure notifyloading; + end; + +{ tloadmoduletracker } + +constructor tloadmoduletracker.create; +begin + setlength(fgloballoadings,16); +end; + +procedure tloadmoduletracker.moduleloaded(const amodule: tmsecomponent); +begin + with fgloballoadings[fgloballevel] do begin + if length(modules) <= modulecount then begin + setlength(modules,modulecount*2+16); + end; + modules[modulecount]:= amodule; + getobjectlinker.link(amodule); + inc(modulecount); + end; +end; + +procedure tloadmoduletracker.beginglobal; +begin + if length(fgloballoadings) >= fgloballevel then begin + setlength(fgloballoadings,fgloballevel*2+16); + end; + inc(fgloballevel); +end; + +procedure tloadmoduletracker.endglobal; +begin + unlink(fgloballoadings[fgloballevel]); + dec(fgloballevel); +end; + +procedure tloadmoduletracker.unlink(var ainfo: globalloadinfoty); +var + comp1: tmsecomponent; + int1: integer; +begin + with ainfo do begin + for int1:= 0 to modulecount-1 do begin + comp1:= modules[int1]; + if comp1 <> nil then begin + modules[int1]:= nil; + fobjectlinker.unlink(comp1); + end; + end; + modulecount:= 0; + end; +end; + +procedure tloadmoduletracker.objectevent(const sender: tobject; + const event: objecteventty); +var + int1,int2: integer; +begin + inherited; + if event = oe_destroyed then begin + for int1:= 0 to fgloballevel do begin + with fgloballoadings[int1] do begin + for int2:= 0 to modulecount-1 do begin + if modules[int2] = sender then begin + modules[int2]:= nil; + end; + end; + end; + end; + end; +end; + +procedure tloadmoduletracker.notifyloading; +var + comp1: tmsecomponent; + int1: integer; +begin + with fgloballoadings[fgloballevel] do begin + try + for int1:= modulecount - 1 downto 0 do begin + comp1:= modules[int1]; + if comp1 <> nil then begin + modules[int1]:= nil; + fobjectlinker.unlink(comp1); + comp1.doafterload; + end; + end; + finally + unlink(fgloballoadings[fgloballevel]); + end; + end; +end; + +var + moduleloadlevel: integer; + globalloadlevel: integer; + loadmoduletracker: tloadmoduletracker; + +procedure msebegingloballoading; +begin + inc(globalloadlevel); + if globalloadlevel = 1 then begin + begingloballoading; + end; +end; + +procedure mseendgloballoading; +begin + dec(globalloadlevel); + if globalloadlevel = 0 then begin + notifygloballoading; + endgloballoading; + loadmoduletracker.notifyloading; + end; +end; + +function initmsecomponent(instance: tmsecomponent; rootancestor: tclass; + out needsloading: boolean): boolean; +var + allloaded: boolean; + ancestorloaded: boolean; + loadlevel: integer; + + rootancestor1: tclass; + + procedure doload(const aclass: msecomponentclassty); + var + po1: pobjectdatainfoty; + begin + if (aclass <> rootancestor1) and (aclass <> tmsecomponent) then begin + if loadlevel > 0 then begin + include(instance.fmsecomponentstate,cs_inheritedloading); + end; + inc(loadlevel); + try + doload(msecomponentclassty(aclass.classparent)); + finally + dec(loadlevel); + if loadlevel = 0 then begin + exclude(instance.fmsecomponentstate,cs_inheritedloading); + end; + end; + po1:= nil; + if objectdatalist <> nil then begin + po1:= objectdatalist.find(aclass,instance.name); + if (po1 = nil) and (rootancestor <> nil) then begin + po1:= objectdatalist.find(aclass,''); + end; + end; + if (po1 <> nil) then begin + if not ancestorloaded then begin + ancestorloaded:= true; + inc(moduleloadlevel); + if (moduleloadlevel = 1) and (globalloadlevel = 0) then begin + begingloballoading; + end; + end; + loadmodule(instance,po1,false); + end + else begin + if aclass.hasresource then begin + allloaded:= false; + needsloading:= true; + end; + end; + end; + end; + +begin + loadlevel:= 0; + if (rootancestor = nil) then begin + rootancestor1:= instance.classtype.classparent; + end + else begin + rootancestor1:= rootancestor; + end; + ancestorloaded:= false; + needsloading:= false; + allloaded:= true; + try + loadmoduletracker.moduleloaded(instance); + doload(msecomponentclassty(instance.classtype)); + if finditem(pointerarty(fmodulestoregister),instance) >= 0 then begin + modules.add(tmsecomponent(instance)); + globalfixupreferences; + end; + if ancestorloaded and (moduleloadlevel = 1) and (globalloadlevel = 0) then begin + moduleloadlevel:= 0; //allow loading of forms in loaded procedure + notifygloballoading; + end; + finally + if ancestorloaded then begin + if moduleloadlevel > 0 then begin + dec(moduleloadlevel); + end; + if (moduleloadlevel = 0) and (globalloadlevel = 0) then begin + endgloballoading; + end; + end; + removeitem(pointerarty(fmodulestoregister),instance); + end; + if (moduleloadlevel = 0) and (globalloadlevel = 0) then begin + loadmoduletracker.notifyloading; + end; + result:= allloaded and ancestorloaded; +end; + +function initmsecomponent1(instance: tcomponent; rootancestor: tclass): boolean; + //true if root loaded +var + bo1: boolean; +begin + if instance is tmsecomponent then begin + result:= initmsecomponent(tmsecomponent(instance),rootancestor,bo1); + end + else begin + result:= false; + end; +end; + +procedure reloadmsecomponent(Instance: tmsecomponent); +var + po1: pobjectdatainfoty; + +begin + po1:= objectdatalist.find(instance.classtype,instance.name); + if po1 = nil then begin + po1:= objectdatalist.find(instance.classtype,''); + end; + loadmodule(instance,po1,true); +end; +(* +procedure registerclassproperties(aclass: tclass); +type + PFieldClassTable = ^TFieldClassTable; + TFieldClassTable = packed record + Count: Smallint; + {$ifdef FPC} + fClasses: array[0..8191] of TPersistentClass; + {$else} + fClasses: array[0..8191] of ^TPersistentClass; + {$endif} + end; + +{$ifdef FPC} + pfieldtable = ^tfieldtable; + TFieldTable = packed record + FieldCount: Word; + ClassTable: Pointer; + { Fields: array[Word] of TFieldInfo; Elements have variant size! } + end; + +function getfieldclasstable(aclass: tclass): pfieldclasstable; +begin + {$ifdef FPC} {$checkpointer off} {$endif} + result:= pfieldclasstable(PFieldTable((Pointer(aclass) + vmtFieldTable)^)^.classtable); + {$ifdef FPC} {$checkpointer default} {$endif} +end; +{$else} +function GetFieldClassTable(AClass: TClass): PFieldClassTable; assembler; +asm + MOV EAX,[EAX].vmtFieldTable + OR EAX,EAX + JE @@1 + MOV EAX,[EAX+2].Integer +@@1: +end; +{$endif} + +var + int1: integer; + fieldclasstab: pfieldclasstable; + +begin + {$ifdef FPC} {$checkpointer off} {$endif} + fieldclasstab:= getfieldclasstable(aclass); + if fieldclasstab <> nil then begin + with fieldclasstab^ do begin + for int1:= 0 to count - 1 do begin + {$ifdef FPC} + classes.registerclass(fclasses[int1]); + registerclassproperties(fclasses[int1]); + {$else} + classes.registerclass(fclasses[int1]^); + registerclassproperties(fclasses[int1]^); + {$endif} + //register classes of subproperties + end; + end; + end; +end; +*) +procedure loadmsemodule(const instance: tmsecomponent; + const rootancestor: tclass); +var + needsloading: boolean; + +begin + //try mse moduleloading + if not initmsecomponent(instance,rootancestor,needsloading) then begin + if needsloading {or not + initinheritedcomponent(instance,needsloading)} then begin + //try FPC module loading + mseerror(mse_resnotfound,instance); + end; + end; + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +function findancestorcomponent(const areader: treader; + const componentname: string): tcomponent; +var + comp1: tcomponent; +begin + result:= nil; + if csinline in areader.lookuproot.componentstate then begin + comp1:= areader.lookuproot; //check added component + while comp1 <> nil do begin + result:= comp1.findcomponent(componentname); + if result <> nil then begin + break; + end; + comp1:= comp1.owner; + end; + end; +end; + +{ tnotifylist } + +procedure tnotifylist.notify(const sender: tobject); +begin + factitem:= 0; + while (factitem < fcount) do begin + notifyeventty(getitempo(factitem)^)(sender); + inc(factitem); + end; +end; + + { tmodulelist} +{ +procedure tmodulelist.findmethod(Reader: TReader; const MethodName: string; + var Address: Pointer; var Error: Boolean); +var //does not work because method.data is not writable + comp1: tcomponent; + str1: string; + po1,po2: pchar; +begin + if error and (methodname <> '') then begin + po1:= pchar(pointer(methodname)); + po2:= strscan(po1,'.'); + if po2 <> nil then begin + setstring(str1,po1,po2-po1); + comp1:= findmodulebyname(str1); + if comp1 <> nil then begin + address:= comp1.MethodAddress(copy(methodname,po2-po1+2,bigint)) + end; + error:= address = nil; + end; + end; +end; +} +function tmodulelist.findmodulebyname(const name: string): tcomponent; +var + int1: integer; + comp1: tcomponent; +begin + result:= nil; + if (self <> nil) and (flocked = 0) then begin + for int1:= 0 to count - 1 do begin + comp1:= items[int1]; + if stricomp(pchar(comp1.name),pchar(name)) = 0 then begin + result:= comp1; + break; + end; + end; + end; +end; + +procedure tmodulelist.ancestornotfound(Reader: TReader; + const ComponentName: string; ComponentClass: TPersistentClass; + var Component: TComponent); +begin + component:= findancestorcomponent(reader,componentname); +end; + +procedure tmodulelist.lock; +begin + inc(flocked); +end; + +procedure tmodulelist.unlock; +begin + dec(flocked); +end; + +{ tloadedlist } + +procedure tloadedlist.notification(acomponent: tcomponent; + operation: toperation); +begin + inherited; + if operation = opremove then begin + removefixupreferences(acomponent,''); + end; +end; + +{ tobjectdatastream} + +constructor tobjectdatastream.create(data: pobjectdataty); +begin + inherited create; + {$ifdef FPC} {$checkpointer off} {$endif} + setpointer(@data^.data,data^.size); + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +function tobjectdatastream.Write(const Buffer; Count: Integer): Longint; +begin + result:= 0; + raise exception.Create('readonly.'); +end; + +{ tobjectdatainfolist} + +constructor tobjectdatainfolist.create; +begin + inherited create(sizeof(objectdatainfoty),[rels_needsfinalize,rels_needscopy]); +end; + +function tobjectdatainfolist.find(aclass: tclass; aname: string): pobjectdatainfoty; +var + int1: integer; +begin + aname:= uppercase(aname); + result:= pobjectdatainfoty(fdata); + for int1:= 0 to fcount -1 do begin + if (result^.objectclass = aclass) and ((aname = '') or (result^.name = aname)) then begin + exit; + end; + inc(result); + end; + result:= nil; +end; + +function tobjectdatainfolist.find(aclassname: string; aname: string): pobjectdatainfoty; +var + int1: integer; +begin + aname:= uppercase(aname); + aclassname:= uppercase(aclassname); + result:= pobjectdatainfoty(fdata); + for int1:= 0 to fcount -1 do begin + if (stringicompupper(result^.objectclass.classname,aclassname) = 0) and + ((aname = '') or (result^.name = aname)) then begin + exit; + end; + inc(result); + end; + result:= nil; +end; + +function tobjectdatainfolist.itempo(const index: integer): pobjectdatainfoty; +begin + result:= pobjectdatainfoty(getitempo(index)); +end; + +procedure tobjectdatainfolist.add(const value: objectdatainfoty); +begin + inherited add(value); +end; + +procedure tobjectdatainfolist.copyrecord(var item); +begin + with objectdatainfoty(item) do begin + reallocstring(name); + end; +end; + +procedure tobjectdatainfolist.finalizerecord(var item); +begin + finalize(objectdatainfoty(item)); +end; + +procedure tobjectdatainfolist.resetchanged; +var + int1: integer; + po1: pobjectdatainfoty; +begin + po1:= pobjectdatainfoty(fdata); + for int1:= 0 to count - 1 do begin + po1^.changed:= false; + inc(po1); + end; +end; + +procedure tobjectdatainfolist.reload(const all: boolean); +var + int1: integer; + int2: integer; + po1: pobjectdatainfoty; + comp1: tmsecomponent; +begin + if fmodules <> nil then begin + po1:= pobjectdatainfoty(fdata); + for int1:= 0 to count - 1 do begin + if all or po1^.changed then begin + for int2:= 0 to fmodules.count - 1 do begin + comp1:= fmodules[int2]; + with comp1 do begin + if (classtype = po1^.objectclass) and (po1^.name = '') or + (stringicompupper(name,po1^.name) = 0) then begin + comp1.name:= ''; + loadmodule(comp1,po1,true); + end; + end; + end; + po1^.changed:= false; + end; + inc(po1); + end; + end; +end; + +procedure tobjectdatainfolist.reloadchanged; +begin + reload(false); +end; + +procedure tobjectdatainfolist.reloadall; +begin + reload(true); +end; + +procedure registerobjectdata(datapo: pobjectdataty; + objectclass: tpersistentclass; name: string = ''); +var + info: objectdatainfoty; +begin + if objectdatalist = nil then begin + objectdatalist:= tobjectdatainfolist.create; + end; + fillchar(info,sizeof(info),0); + info.objectclass:= objectclass; + info.objectdata:= datapo; + info.name:= uppercase(name); + objectdatalist.add(info); + mclasses.registerclass(objectclass); +end; + +procedure registerobjectdata(datapo: pobjectdataty; + const objectclassname: string; const name: string = ''); +var + po1: pobjectdatainfoty; +begin + if objectdatalist <> nil then begin + po1:= objectdatalist.find(objectclassname,name); + if po1 <> nil then begin + po1^.langobjectdata:= datapo; + po1^.changed:= true; + end; + end; +end; + +procedure unregisterobjectdata(const objectclassname: string; const name: string = ''); +var + po1: pobjectdatainfoty; +begin + if objectdatalist <> nil then begin + po1:= objectdatalist.find(objectclassname,name); + if po1 <> nil then begin + po1^.langobjectdata:= nil; + po1^.changed:= true; + end; + end; +end; + +procedure resetchangedmodules; +begin + if objectdatalist <> nil then begin + objectdatalist.resetchanged; + end; +end; + +procedure reloadchangedmodules; +begin + if objectdatalist <> nil then begin + objectdatalist.reloadchanged; + end; +end; + +procedure reloadmodules; +begin + if objectdatalist <> nil then begin + objectdatalist.reloadall; + end; +end; + +procedure getoptionalobject(const componentstate: tcomponentstate; + const instance: tobject; createproc: createprocty); +begin + if (instance = nil) and (csreading in componentstate) then begin + createproc; + end; +end; + +procedure getoptionalobject(const aowner: tcomponent; + const instance: tobject; createproc: createprocty); +var + sta1: tcomponentstate; +begin + sta1:= []; + if aowner <> nil then begin + sta1:= aowner.componentstate; + end; + getoptionalobject(sta1,instance,createproc); +end; + +procedure getoptionalobject(const componentstate: tcomponentstate; + var instance: tvirtualpersistent; const aclass: virtualpersistentclassty); +begin + if (instance = nil) and (csreading{csloading} in componentstate) then begin + instance:= aclass.create; + end; +end; + +procedure setoptionalobject(const componentstate: tcomponentstate; + const value: tpersistent; var instance; createproc: createprocty); +begin + if value <> nil then begin + if tpersistent(instance) = nil then begin + createproc; + end; + if pointer(value) <> pointer(1) then begin + tpersistent(instance).assign(value); + end; + end + else begin + freeandnil(tpersistent(instance)); + end; +end; + +procedure setoptionalobject(const aowner: tcomponent; //can be nil + const value: tpersistent; var instance; + createproc: createprocty); overload; +var + sta1: tcomponentstate; +begin + sta1:= []; + if aowner <> nil then begin + sta1:= aowner.componentstate; + end; + setoptionalobject(sta1,value,instance,createproc); +end; + +procedure setoptionalobject(const componentstate: tcomponentstate; + const value: tvirtualpersistent; var instance; + const aclass: virtualpersistentclassty); +begin + if value <> nil then begin + if tpersistent(instance) = nil then begin + tvirtualpersistent(instance):= aclass.create; + end; + if pointer(value) <> pointer(1) then begin + tpersistent(instance).assign(value); + end; + end + else begin + freeandnil(tpersistent(instance)); + end; +end; + +procedure setlinkedcomponent(const sender: iobjectlink; + const source: tmsecomponent; + var instance: tmsecomponent; ainterfacetype: pointer = nil); +begin + if source <> nil then begin + sender.link(sender,ievent(source),@instance,ainterfacetype); + end; + if instance <> nil then begin + sender.unlink(sender,ievent(instance),@instance); + end; + instance:= source; +end; + +procedure createobjectlinker(const owner: iobjectlink; + onevent: objectlinkeventty; var instance: tobjectlinker); + //sets finstancepo +begin + if instance = nil then begin + instance:= tobjectlinker.create(owner,onevent); + instance.finstancepo:= @instance; + end; +end; + +{ townedpersistent } + +constructor townedpersistent.create(aowner: tobject); +begin + fowner:= aowner; + inherited create; +end; + +{ tobjectlinker } + +{$ifdef debugobjectlink} + + function intftext(aintf: iobjectlink): string; + var + obj1: tobject; + begin + result:= ''; + if odd(ptruint(aintf)) then begin + dec(pointer(aintf)); + end; + if aintf = nil then begin + result:= result+''; + end + else begin + if ptrint(aintf) = 1 then begin + result:= result + '<-1->'; + end + else begin + result:= result + hextostr(longword(aintf),8) + ' '; + obj1:= iobjectlink(aintf).getinstance; + result:= result + hextostr(longword(obj1),8); + if obj1 <> nil then begin + result:= result + ' '+obj1.classname; + end; + if obj1 is tcomponent then begin + result:= result+' '+tcomponent(obj1).Name; + end + else begin + if obj1 is twindow then begin + result:= result+' '+twindow(obj1).owner.Name; + end; + end + end; + end; + end; + +procedure getdebugtext(owner: tobjectlinker; const source,dest:iobjectlink; + valuepo: pointer); +begin + if rels_destroying in owner.fstate then begin + write('*'); + end + else begin + write(' '); + end; + write('v:'+ hextostr(longword(valuepo),8)); + write(' o:'+intftext(iobjectlink(owner.fownerintf))); + write(' s:'+intftext(source)); + write(' d:'+intftext(dest)); + writeln; +end; + +{$endif} + +constructor tobjectlinker.create(const owner: iobjectlink; + onevent: objectlinkeventty); +begin +{$ifdef debugobjectlink} + writeln('create o: ' + intftext(owner)); +{$endif} + pointer(fownerintf):= pointer(owner); + fonevent:= onevent; + inherited create(sizeof(linkinfoty)); +end; + +destructor tobjectlinker.destroy; +var + po1: pointer; + po2: plinkinfoty; + int1: integer; + {$ifndef FPC} + po3: pointer; + {$endif} +begin +{$ifdef debugobjectlink} + writeln('destroy o: ' + intftext(iobjectlink(fownerintf))); +{$endif} + include(fstate,rels_destroying); + po2:= datapo; + for int1:= 0 to count - 1 do begin + with po2^ do begin + po1:= dest; + if po1 <> nil then begin +{$ifdef debugobjectlink} + write('destrev');getdebugtext(self,iobjectlink(source), + iobjectlink(dest),valuepo); +{$endif} + dest:= nil; + if odd(ptruint(source)) then begin + iobjectlink(po1).objevent(iobjectlink(pchar(source)-1),oe_destroyed); + if valuepo <> nil then begin + pobject(valuepo)^:= nil; + end; + end + else begin + {$ifdef FPC} + iobjectlink(po1).unlink(iobjectlink(pointer(1)), + iobjectlink(source),valuepo); + {$else} + po3:= pointer(1); + iobjectlink(po1).unlink(iobjectlink(po3),iobjectlink(source),valuepo); + {$endif} + end; + end; + end; + inc(po2); + end; + pointer(fownerintf):= nil; + inherited; +end; + +procedure tobjectlinker.sendevent(event: objecteventty); +var + int1: integer; +begin + if event <> oe_destroyed then begin + inc(fnopack); + try + int1:= 0; + while int1 < count do begin + with plinkinfoaty(fdata)^[int1] do begin + if dest <> nil then begin + iobjectlink(dest).objevent(iobjectlink(fownerintf),event); + end; + end; + inc(int1); + end; + finally + dec(fnopack); + end; + end; +end; + +procedure tobjectlinker.dopack; +begin + if (fnopack = 0) and not (rels_destroying in fstate) then begin + pack; + if (count = 0) and (finstancepo <> nil) {$ifdef debugobjectlink} + and not debugon {$endif} then begin + freeandnil(finstancepo^); + end; + end; +end; + +procedure tobjectlinker.removelink(var item: linkinfoty; destroyed: boolean); +var + int1: integer; + po1: plinkinfoty; +begin + po1:= plinkinfoty(fdata); + for int1:= 0 to count - 1 do begin + with po1^ do begin + if (dest <> nil) and (dest = item.dest) and + (destroyed or + (valuepo = item.valuepo) and (source = item.source)) then begin + if (refcount = 0) or destroyed then begin + dest:= nil; + end + else begin + dec(refcount); + end; + end; + end; + inc(po1); + end; +end; + +procedure tobjectlinker.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +var + info: linkinfoty; + int1: integer; + po1: plinkinfoty; + bo1: boolean; +begin + if not (rels_destroying in fstate) then begin +{$ifdef debugobjectlink} + write('link ');getdebugtext(self,source,dest,valuepo); +{$endif} + fillchar(info,sizeof(info),0); + info.source:= pointer(source); + info.dest:= pointer(dest); + info.valuepo:= valuepo; + info.interfacetype:= ainterfacetype; + if not (once {and (findsource(info) >= 0)}) then begin + bo1:= false; + po1:= datapo; + for int1:= 0 to count - 1 do begin + with po1^ do begin + if (dest = info.dest) and (source = info.source) and + (valuepo = info.valuepo) and (interfacetype = info.interfacetype) then begin + inc(refcount); + bo1:= true; + break; + end + end; + inc(po1); + end; + if not bo1 then begin + add(info); + end; + if not odd(ptruint(source)) then begin //full link + dest.link(iobjectlink(pchar(dest)+1),source,valuepo,ainterfacetype); + //create backlink + source.objevent(dest,oe_connect); + end; + end; + end; +end; + +procedure tobjectlinker.link(const dest: tmsecomponent; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + if dest <> nil then begin + link(iobjectlink(fownerintf),ievent(dest),valuepo,ainterfacetype,once); + end; +end; + +procedure tobjectlinker.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +var + info: linkinfoty; +begin +{$ifdef debugobjectlink} + write('unlink');getdebugtext(self,source,dest,valuepo); +{$endif} + info.source:= pointer(source); + info.dest:= pointer(dest); + info.valuepo:= valuepo; + removelink(info,ptrint(source) = 1); + if not odd(ptruint(source)) then begin //full link + inc(fnopack); + dest.unlink(iobjectlink(pchar(dest)+1),source,valuepo); + //remove backlink + dec(fnopack); + end; + dopack; +end; + +procedure tobjectlinker.unlink(const dest: tmsecomponent; valuepo: pointer = nil); +begin + if dest <> nil then begin + unlink(iobjectlink(fownerintf),ievent(dest),valuepo); + end; +end; + +procedure tobjectlinker.setlinkedvar(const linkintf: iobjectlink; + const source: iobjectlink; + var dest: iobjectlink; + const ainterfacetype: pointer = nil); +var + ba: pointer; +begin + if source <> dest then begin + ba:= pointer(dest); + pointer(dest):= pointer(source); + if source <> nil then begin + link(linkintf,source,@dest,ainterfacetype); + end; + if ba <> nil then begin + unlink(linkintf,iobjectlink(ba),@dest); + end; + end; +end; + +procedure tobjectlinker.setlinkedvar(const linkintf: iobjectlink; + const source: tlinkedobject; var dest: tlinkedobject; + const ainterfacetype: pointer = nil); +var + ba: tlinkedobject; +begin + if source <> dest then begin + ba:= dest; + dest:= source; + if source <> nil then begin + link(linkintf,iobjectlink(source),@dest,ainterfacetype); + end; + if ba <> nil then begin + unlink(linkintf,iobjectlink(ba),@dest); + end; + end; +end; + +procedure tobjectlinker.setlinkedvar(const linkintf: iobjectlink; + const source: tlinkedpersistent; var dest: tlinkedpersistent; + const ainterfacetype: pointer = nil); +var + ba: tlinkedpersistent; +begin + if source <> dest then begin + ba:= dest; + dest:= source; + if source <> nil then begin + link(linkintf,iobjectlink(source),@dest,ainterfacetype); + end; + if ba <> nil then begin + unlink(linkintf,iobjectlink(ba),@dest); + end; + end; +end; + +procedure tobjectlinker.setlinkedvar(const linkintf: iobjectlink; + const source: tmsecomponent; var dest: tmsecomponent; + const ainterfacetype: pointer = nil); +var + ba: tmsecomponent; +begin + if source <> dest then begin + ba:= dest; + dest:= source; + if source <> nil then begin + link(linkintf,ievent(source),@dest,ainterfacetype); + end; + if ba <> nil then begin + unlink(linkintf,ievent(ba),@dest); + end; + end; +end; + +procedure tobjectlinker.setlink(const linkintf: iobjectlink; + const source: tmsecomponent; var dest: tmsecomponent; + const ainterfacetype: pointer = nil); overload; + //no automatic nil setting +var + ba: tmsecomponent; +begin + if source <> dest then begin + ba:= dest; + dest:= source; + if source <> nil then begin + link(linkintf,ievent(source),nil,ainterfacetype); + end; + if ba <> nil then begin + unlink(linkintf,ievent(ba),nil); + end; + end; +end; + +function tobjectlinker.isempty(var item): boolean; +begin + with linkinfoty(item) do begin + result:= dest = nil; + end; +end; + +procedure tobjectlinker.objevent(const sender: iobjectlink; + const event: objecteventty); +var + info: linkinfoty; +begin + if event = oe_destroyed then begin + inc(fnopack); + info.dest:= pointer(sender); + info.valuepo:= nil; + removelink(info,true); + end; + if assigned(fonevent) and not (rels_destroying in fstate) then begin + fonevent(sender.getinstance,event); + end; + if event = oe_destroyed then begin + dec(fnopack); + dopack; + end; +end; + +procedure tobjectlinker.forall(const proc: objectlinkprocty; + const ainterfacetype: pointer); +var + po1: plinkinfoty; + int1: integer; +begin + inc(fnopack); + try + for int1:= 0 to fcount - 1 do begin + po1:= @plinkinfoaty(fdata)^[int1]; + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) and + (ainterfacetype = po1^.interfacetype) then begin + proc(po1^); + end; + end; + finally + dec(fnopack); + end; +end; + +procedure tobjectlinker.forall(const proc: objectlinkintfprocty; + const ainterfacetype: pointer); +var + po1: plinkinfoty; + int1: integer; +begin + inc(fnopack); + try + for int1:= 0 to fcount - 1 do begin + po1:= @plinkinfoaty(fdata)^[int1]; + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) and + (ainterfacetype = po1^.interfacetype) then begin + proc(po1^.dest); + end; + end; + finally + dec(fnopack); + end; +end; + +procedure tobjectlinker.forfirst(const proc: objectlinkfirstprocty; + const ainterfacetype: pointer); +var + po1: plinkinfoty; + int1: integer; + bo1: boolean; +begin + inc(fnopack); + try + bo1:= false; + for int1:= 0 to fcount - 1 do begin + po1:= @plinkinfoaty(fdata)^[int1]; + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) and + (ainterfacetype = po1^.interfacetype) then begin + proc(po1^,bo1); + if bo1 then begin + break; + end; + end; + end; + finally + dec(fnopack); + end; +end; + +procedure tobjectlinker.forfirst(const proc: objectlinkintffirstprocty; + const ainterfacetype: pointer); +var + po1: plinkinfoty; + int1: integer; + bo1: boolean; +begin + inc(fnopack); + try + bo1:= false; + for int1:= 0 to fcount - 1 do begin + po1:= @plinkinfoaty(fdata)^[int1]; + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) and + (ainterfacetype = po1^.interfacetype) then begin + proc(po1^.dest,bo1); + if bo1 then begin + break; + end; + end; + end; + finally + dec(fnopack); + end; +end; + +function tobjectlinker.linkedobjects: objectarty; +var + po1: plinkinfoty; + int1: integer; +begin + result:= nil; + po1:= plinkinfoty(fdata); + for int1:= 0 to fcount - 1 do begin + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) then begin + additem(pointerarty(result),iobjectlink(po1^.dest).getinstance); + end; + inc(po1); + end; + removearrayduplicates(pointerarty(result)); +end; + +function tobjectlinker.linkedobjects( + const ainterfacetype: pointer): objectarty; +var + po1: plinkinfoty; + int1: integer; +begin + result:= nil; + po1:= plinkinfoty(fdata); + for int1:= 0 to fcount - 1 do begin + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) and + (po1^.interfacetype = ainterfacetype) then begin + additem(pointerarty(result),iobjectlink(po1^.dest).getinstance); + end; + inc(po1); + end; + removearrayduplicates(pointerarty(result)); +end; + +{ tlinkedobject } + +destructor tlinkedobject.destroy; +begin + inherited; + freeandnil(fobjectlinker); +end; + +function tlinkedobject.getobjectlinker: tobjectlinker; +begin + createobjectlinker(self,{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + result:= fobjectlinker; +end; + +procedure tlinkedobject.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tlinkedobject.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedobject.setlinkedvar(const source: tlinkedobject; + var dest: tlinkedobject; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedobject.link(const source,dest: iobjectlink; + valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tlinkedobject.unlink(const source,dest: iobjectlink; + valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tlinkedobject.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tlinkedobject.getinstance: tobject; +begin + result:= self; +end; + +{ tlinkedrecordlist } + +destructor tlinkedrecordlist.destroy; +begin + inherited; + freeandnil(fobjectlinker); +end; + +function tlinkedrecordlist.getobjectlinker: tobjectlinker; +begin + createobjectlinker(self,{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + result:= fobjectlinker; +end; + +procedure tlinkedrecordlist.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tlinkedrecordlist.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedrecordlist.setlinkedvar(const source: tlinkedobject; + var dest: tlinkedobject; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedrecordlist.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tlinkedrecordlist.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tlinkedrecordlist.objevent(const sender: iobjectlink; const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tlinkedrecordlist.getinstance: tobject; +begin + result:= self; +end; + +(* +{ tnullinterfacedobject } + +function tnullinterfacedobject._addref: integer; stdcall; +begin + result:= -1; +end; + +function tnullinterfacedobject._release: integer; stdcall; +begin + result:= -1; +end; + +function tnullinterfacedobject.queryinterface( + {$ifdef fpc_has_constref}constref{$else}const{$endif}iid: tguid; + out obj): hresult; stdcall; +begin + if getinterface(iid, obj) then begin + result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; +*) +{ tnullinterfacedpersistent } +{$ifdef FPC} +function tnullinterfacedpersistent._addref: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; +begin + result:= -1; +end; + +function tnullinterfacedpersistent._release: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; +begin + result:= -1; +end; + +function tnullinterfacedpersistent.QueryInterface( + {$ifdef fpc_has_constref}constref{$else}const{$endif} IID: TGUID; + out Obj): HResult; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; +begin + if GetInterface(IID, Obj) then begin + Result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; +{$endif} + +{ toptionalpersistent } + +procedure toptionalpersistent.readdummy(reader: treader); +begin + reader.readinteger; +end; + +procedure toptionalpersistent.writedummy(writer: twriter); +begin + writer.writeinteger(0); +end; + +procedure toptionalpersistent.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('dummy',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,(filer.ancestor = nil) and isoptional); + //in order to create optional instance +end; + +function toptionalpersistent.isoptional: boolean; +begin + result:= true; +end; + +{ tlinkedoptionalpersistent } + +procedure tlinkedoptionalpersistent.readdummy(reader: treader); +begin + reader.readinteger; +end; + +procedure tlinkedoptionalpersistent.writedummy(writer: twriter); +begin + writer.writeinteger(0); +end; + +procedure tlinkedoptionalpersistent.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('dummy',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,(filer.ancestor = nil) and isoptional); + //in order to create optional instance +end; + +function tlinkedoptionalpersistent.isoptional: boolean; +begin + result:= true; +end; + +{ tlinkedpersistent } + +destructor tlinkedpersistent.destroy; +begin + inherited; + freeandnil(fobjectlinker); +end; + +function tlinkedpersistent.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(iobjectlink(self),{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tlinkedpersistent.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tlinkedpersistent.setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedpersistent.setlinkedvar(const source: iobjectlink; var dest: iobjectlink; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedpersistent.setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedpersistent.setlinkedvar(const source: tlinkedpersistent; + var dest: tlinkedpersistent; const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedpersistent.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tlinkedpersistent.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tlinkedpersistent.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tlinkedpersistent.getinstance: tobject; +begin + result:= self; +end; + +{ teventobject } + +procedure teventobject.receiveevent(const event: tobjectevent); +begin + //dummy +end; + +{ tcomponentevent } + +constructor tcomponentevent.create(const asender: tobject; const atag: integer = 0; + const callchildren: boolean = true); +begin + inherited create(ek_component,nil); + fsender:= asender; + tag:= atag; + if callchildren then begin + state:= [ces_callchildren]; + end; +end; + + { tmsecomponent } + +destructor tmsecomponent.destroy; +begin + inherited; + freeandnil(fobjectlinker); +end; + +function tmsecomponent.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(ievent(self),{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tmsecomponent.initnewcomponent(const ascale: real); +begin + //dummy +end; + +function tmsecomponent.checkowned(component: tcomponent): boolean; +begin + result:= false; + while component <> nil do begin + if component = self then begin + result:= true; + break; + end; + component:= component.Owner; + end; +end; + +function tmsecomponent.checkowner(component: tcomponent): boolean; +var + comp1: tcomponent; +begin + result:= false; + comp1:= self; + while comp1 <> nil do begin + if comp1 = component then begin + result:= true; + break; + end; + comp1:= comp1.Owner; + end; +end; + +function tmsecomponent.rootowner: tcomponent; +begin + result:= owner; + if result <> nil then begin + while result.owner <> nil do begin + result:= result.Owner; + end; + end; +end; +{ +function tmsecomponent.rootcomponent: tcomponent; +begin + result:= rootowner; + if result = nil then begin + result:= self; + end; +end; +} +function tmsecomponent.getrootcomponentpath: componentarty; +var + count: integer; + comp: tcomponent; +begin + result:= nil; + count:= 0; + comp:= self; + while comp <> nil do begin + if length(result) <= count then begin + setlength(result,length(result)+32); + end; + result[count]:= comp; + inc(count); + comp:= comp.owner; + end; + setlength(result,count); +end; + +procedure tmsecomponent.setlinkedvar(const source: iobjectlink; + var dest: iobjectlink; const linkintf: iobjectlink = nil); +begin + if (fobjectlinker = nil) and (csdestroying in componentstate) then begin + dest:= source; + end + else begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(ievent(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; + end; +end; + +procedure tmsecomponent.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + if (fobjectlinker = nil) and (csdestroying in componentstate) then begin + dest:= source; + end + else begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(ievent(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; + end; +end; + +procedure tmsecomponent.setlinkedvar(const source: tlinkedobject; + var dest: tlinkedobject; const linkintf: iobjectlink = nil); +begin + if (fobjectlinker = nil) and (csdestroying in componentstate) then begin + dest:= source; + end + else begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(ievent(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; + end; +end; + +procedure tmsecomponent.setlinkedvar(const source: tlinkedpersistent; + var dest: tlinkedpersistent; const linkintf: iobjectlink = nil); +begin + if (fobjectlinker = nil) and (csdestroying in componentstate) then begin + dest:= source; + end + else begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(ievent(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; + end; +end; + +function tmsecomponent.linkcount: integer; +begin + if fobjectlinker = nil then begin + result:= 0; + end + else begin + result:= fobjectlinker.count; + end; +end; + +function tmsecomponent.canevent(const event: tmethod): boolean; +begin + result:= (event.code <> nil) and (event.data <> nil) and + (componentstate * [csloading,csdesigning,csdestroying] = []); +end; + +function tmsecomponent.candestroyevent(const event: tmethod): boolean; +begin + result:= (event.code <> nil) and (event.data <> nil) and + (componentstate * [csloading,csdesigning] = []); +end; + +procedure tmsecomponent.receiveevent(const event: tobjectevent); +var + int1: integer; +begin + case event.kind of + ek_async: begin + int1:= tasyncevent(event).tag; + doasyncevent(int1); + end; + ek_component: begin + sendcomponentevent(event as tcomponentevent,false); + end; + end; +end; + +procedure tmsecomponent.asyncevent(atag: integer = 0; + const aoptions: posteventoptionsty = []); +begin + application.postevent(tasyncevent.create(ievent(self),atag),aoptions); +end; + +procedure tmsecomponent.doasyncevent(var atag: integer); +begin + //dummy +end; + +procedure tmsecomponent.postcomponentevent(const event: tcomponentevent; + const aoptions: posteventoptionsty = []); +begin + event.create(event.kind,ievent(self)); + application.postevent(event,aoptions); +end; + +{$ifdef FPC} + +procedure tmsecomponent.setinline(value: boolean); +begin + if value then begin + include(fcomponentstate,csinline); + end + else begin + exclude(fcomponentstate,csinline); + end; +end; + +procedure tmsecomponent.setancestor(value: boolean); +begin + if value then begin + include(fcomponentstate,csancestor); + end + else begin + exclude(fcomponentstate,csancestor); + end; +end; + +{$endif FPC} + +{$ifdef hascorbagetinterface} +function getcorbainterface(const aobject: tobject; const aintf: ptypeinfo; + out obj) : boolean; +var + typedata1: ptypedata; + po1: pshortstring; +begin + pointer(obj):= nil; + result:= false; + if aobject <> nil then begin + typedata1:= gettypedata(aintf); + po1:= pshortstring( + ptruint(@typedata1^.rawintfunit)+length(typedata1^.rawintfunit)+1); + po1:= aligntoptr(pointer(po1)); + if po1^[0] <> #0 then begin + result:= aobject.getinterfacebystr(po1^,obj); //works in FPC 2.4+ + end + end; +end; + +{$else} + +function getcorbainterface(const aobject: tobject; const aintf: ptypeinfo; + out obj) : boolean; +var + intf1: pinterfaceentry; + typedata1: ptypedata; + po1: pshortstring; +begin +// result:= getinterface(aintf,obj); + typedata1:= gettypedata(aintf); + {$ifdef FPC} + po1:= pshortstring( + ptruint(@typedata1^.rawintfunit)+length(typedata1^.rawintfunit)+1); + if po1^[0] <> #0 then begin + intf1:= aobject.getinterfaceentrybystr(po1^); + end + else begin + intf1:= nil; + end; + {$else} + intf1:= aobject.getinterfaceentry(typedata1^.guid); + {$endif} + if intf1 <> nil then begin + {$ifdef FPC} + pointer(obj):= pointer(aobject) + intf1^.ioffset; + {$else} + pointer(obj):= pointer(integer(aobject) + intf1^.ioffset); + {$endif} + result:= true; + end + else begin + pointer(obj):= nil; + result:= false; + end; +end; +{$endif} //hascorbagetinterface + +procedure nosupportfor(const sender: tcomponent; const avalue: tcomponent; + const ainterface: ptypeinfo); +begin + raise exception.create(sender.name+': '+avalue.name+' does not provide '+ + ainterface^.name+'.'); +end; + +procedure checkcorbainterface(const sender: tcomponent; + const avalue: tcomponent; + const ainterface: ptypeinfo; out obj); +begin + if not getcorbainterface(avalue,ainterface,obj) then begin + nosupportfor(sender,avalue,ainterface); + end; +end; + +//function tmsecomponent.getcorbainterface(const aintf: tguid; out obj) : boolean; +function tmsecomponent.getcorbainterface(const aintf: ptypeinfo; + out obj) : boolean; +begin + result:= mseclasses.getcorbainterface(self,aintf,obj); +end; + +function isinterface(const actual: ptypeinfo; const wanted: ptypeinfo): boolean; +var + po1: ptypeinfo; +begin +{$ifdef FPC} + result:= (actual^.kind = tkinterfaceraw) and (wanted^.kind = tkinterfaceraw); + if result then begin + po1:= actual; + while po1 <> nil do begin + if po1 = wanted then begin + exit; + end; + po1:= gettypedata(po1)^.rawintfparent; + end; + result:= false; + end + else begin +{$endif} + result:= (actual^.kind = tkinterface) and (wanted^.kind = tkinterface); + if result then begin + po1:= actual; + while po1 <> nil do begin + if po1 = wanted then begin + exit; + end; + po1:= gettypedata(po1)^.intfparent{$ifndef FPC}^{$endif}; + end; + result:= false; + end; +{$ifdef FPC} + end; +{$endif} +end; + +function isinterfaceornil(const actual: ptypeinfo; const wanted: ptypeinfo): boolean; +begin + result:= (actual = nil) or isinterface(actual,wanted); +end; + +procedure tmsecomponent.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tmsecomponent.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tmsecomponent.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tmsecomponent.getinstance: tobject; +begin + result:= self; +end; + +function tmsecomponent.getcomponent: tcomponent; +begin + result:= self; +end; + +function tmsecomponent.getcomponentinstance: tcomponent; +begin + result:= self; +end; + +procedure tmsecomponent.getcompchildren(const proc: tgetchildproc; + const root: tcomponent); +var + int1: integer; + comp1: tcomponent; +begin + if root = self then begin + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if not (cssubcomponent in comp1.componentstyle) and + not comp1.hasparent or (comp1 is tmsedatamodule) then begin + proc(comp1); + end; + end; + end; +end; + +procedure tmsecomponent.componentevent(const event: tcomponentevent); +var + int1: integer; + comp1: tcomponent; +begin + with event do begin + if ces_callchildren in state then begin + for int1:= 0 to componentcount - 1 do begin + if ces_processed in state then begin + break; + end; + comp1:= components[int1]; + if comp1 is tmsecomponent then begin + tmsecomponent(comp1).componentevent(event); + end; + end; + end; + end; +end; + +procedure tmsecomponent.sendcomponentevent(const event: tcomponentevent; + const destroyevent: boolean); +begin + try + componentevent(event); + finally + if destroyevent then begin + event.Free1; + end; + end; +end; + +procedure tmsecomponent.sendrootcomponentevent(const event: tcomponentevent; + const destroyevent: boolean); +var + int1: integer; + ar1: componentarty; +begin + try + ar1:= getrootcomponentpath; + for int1:= high(ar1) downto 0 do begin + if ar1[int1] is tmsecomponent then begin + tmsecomponent(ar1[int1]).sendcomponentevent(event,false); + break; + end; + end; + finally + if destroyevent then begin + event.Free1; + end; + end; +end; + +procedure tmsecomponent.getoptionalobject(const instance: tobject; + createproc: createprocty); +begin + if not (cs_endreadproc in fmsecomponentstate) then begin + mseclasses.getoptionalobject(componentstate,instance,createproc); + end; +end; + +procedure tmsecomponent.setoptionalobject(const value: tpersistent; + var instance; createproc: createprocty); +begin + mseclasses.setoptionalobject(componentstate,value,instance,createproc); +end; + +procedure tmsecomponent.loaded; +begin + inherited; + include(fmsecomponentstate,cs_loadedproc); + try + sendchangeevent; + finally + exclude(fmsecomponentstate,cs_loadedproc); + end; +end; + +procedure tmsecomponent.beginread; +var + int1: integer; + comp1: tcomponent; +begin + include(fmsecomponentstate,cs_beginreadproc); + try + dobeginread; + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if (cssubcomponent in comp1.componentstyle) and + (comp1 is tmsecomponent) then begin + tmsecomponent(comp1).beginread; + end; + end; + finally + exclude(fmsecomponentstate,cs_beginreadproc); + end; +end; + +procedure tmsecomponent.endread; +var + int1: integer; + comp1: tcomponent; +begin + include(fmsecomponentstate,cs_endreadproc); + try + doendread; + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if (cssubcomponent in comp1.componentstyle) and + (comp1 is tmsecomponent) then begin + tmsecomponent(comp1).endread; + end; + end; + finally + exclude(fmsecomponentstate,cs_endreadproc); + end; +end; + +procedure tmsecomponent.readstate(reader: treader); +begin + beginread; + inherited; + endread; +end; + +procedure tmsecomponent.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tmsecomponent.sendchangeevent(const aevent: objecteventty = oe_changed); +begin + if (fobjectlinker <> nil) and not (csloading in componentstate) then begin + fobjectlinker.sendevent(aevent); + end; +end; + +procedure tmsecomponent.designselected(const selected: boolean); +begin + //dummy +end; + +function tmsecomponent.getancestorclassname: string; +begin + if fancestorclassname <> '' then begin + result:= fancestorclassname; + end + else begin + result:= getmoduleclassname; + end; +end; + +procedure tmsecomponent.readmoduleclassname(reader: treader); +begin + reader.ReadString; //dummy +end; + +procedure tmsecomponent.writemoduleclassname(writer: twriter); +begin + writer.writestring(getancestorclassname); +end; + +procedure tmsecomponent.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty(moduleclassnamename, + {$ifdef FPC}@{$endif}readmoduleclassname, + {$ifdef FPC}@{$endif}writemoduleclassname, + (cs_ismodule in fmsecomponentstate) and (filer.Root = self) and + ((filer.ancestor = nil) or + (tmsecomponent(filer.ancestor).getancestorclassname <> + getancestorclassname))); +end; + +function tmsecomponent.getactualclassname: string; +begin + if factualclassname <> nil then begin + result:= factualclassname^; + end + else begin + result:= classname; + end; +end; + +class function tmsecomponent.getmoduleclassname: string; +begin + result:= tmsecomponent.classname; +end; + +class function tmsecomponent.hasresource: boolean; +begin + result:= false; +end; + +(* +function setclassname(const instance: tobject; + const aclassname: pshortstring): pshortstring; +var + classnamepo: ppointer; + {$ifdef mswindows} + ca1: longword; + {$endif} +begin + if aclassname = nil then begin + result:= nil; + end + else begin + classnamepo:= ppointer(pchar(instance.classtype)+vmtclassname); + {$ifdef mswindows} + virtualprotect(classnamepo,sizeof(pointer),page_readwrite,{$ifdef FPC}@{$endif}ca1); + {$endif} + result:= classnamepo^; + classnamepo^:= aclassname; + {$ifdef mswindows} + virtualprotect(classnamepo,sizeof(pointer),ca1,nil); + {$endif} + end; +end; +*) + +procedure tmsecomponent.writestate(writer: twriter); +//var +// classnamebefore: pshortstring; +begin +// classnamebefore:= setclassname(self,factualclassname); +// try + if writer is twritermse then begin + twritermse(writer).writecomponentdata(self); + end + else begin + inherited; + end; +// finally +// setclassname(self,classnamebefore); +// end; +end; + +function tmsecomponent.gethelpcontext: msestring; +begin + result:= fhelpcontext; +end; + +class function tmsecomponent.classskininfo: skininfoty; +begin + fillchar(result,sizeof(result),0); + result.objectkind:= sok_component; +end; + +function tmsecomponent.skininfo: skininfoty; +begin + result:= classskininfo; + result.instance:= self; +end; + +function tmsecomponent.linkedobjects: objectarty; +begin + result:= objectarty(getlinkedcomponents(self)); + if fobjectlinker <> nil then begin + stackarray(pointerarty(fobjectlinker.linkedobjects),pointerarty(result)); + end; + removearrayduplicates(pointerarty(result)); +end; + +function tmsecomponent.loading: boolean; +begin + result:= csloading in componentstate; +end; + +procedure tmsecomponent.dobeginread; +begin + //dummy +end; + +procedure tmsecomponent.doendread; +begin + //dummy +end; + +procedure tmsecomponent.doafterload; +begin + //dummy +end; +{ +procedure tmsecomponent.getchildren1(const proc: tgetchildproc; + const root: tcomponent); +begin + //dummy +end; + +procedure tmsecomponent.getchildren(proc: tgetchildproc; root: tcomponent); +var + ev1: getchildreneventty; +begin + ev1:= onstreaminggetchildren; + if assigned(ev1) then begin + ev1(self,proc,root); + end + else begin + getchildren1(proc,root); + end; +end; +} +procedure tmsecomponent.updateskin(const recursive: boolean = false); +var + int1: integer; + comp1: tcomponent; + methodpo: ^skineventty; +begin + if componentstate*[csdesigning] = [] then begin + methodpo:= {$ifndef FPC}@{$endif}@oninitskinobject; + end + else begin +// methodpo:= {$ifndef FPC}@{$endif}@oninitskinobjectdesign; + exit; //do nothing + end; + if assigned(methodpo^) then begin + if recursive then begin + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if comp1 is tmsecomponent then begin + tmsecomponent(comp1).updateskin(true); + end; + end; + end; + if hasskin then begin +// if cs_skinloaded in fmsecomponentstate then begin +// removeskin; +// end; + if assigned(fonbeforeupdateskin) then begin + fonbeforeupdateskin(tobject(tmethod(methodpo^).data)); + end; + methodpo^(skininfo); +// include(fmsecomponentstate,cs_skinloaded); + if assigned(fonbeforeupdateskin) then begin + fonafterupdateskin(tobject(tmethod(methodpo^).data)); + end; + end; + end; +end; +(* +procedure tmsecomponent.removeskin(const recursive: boolean = false); +var + int1: integer; + comp1: tcomponent; + methodpo: ^skineventty; +begin + if componentstate*[csdesigning] = [] then begin + methodpo:= {$ifndef FPC}@{$endif}@onremoveskinobject; + end + else begin + methodpo:= {$ifndef FPC}@{$endif}@onremoveskinobjectdesign; + end; + if assigned(methodpo^) then begin + if recursive then begin + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if comp1 is tmsecomponent then begin + tmsecomponent(comp1).removeskin(true); + end; + end; + end; + if hasskin and (cs_skinloaded in fmsecomponentstate) then begin + methodpo^(skininfo); + exclude(fmsecomponentstate,cs_skinloaded); + end; + end; +end; +*) +function tmsecomponent.getmsecomponentstate: msecomponentstatesty; +begin + result:= fmsecomponentstate; +end; + +function tmsecomponent.hasskin: boolean; +begin + result:= true; +end; + +procedure tmsecomponent.validaterename(acomponent: tcomponent; + const curname: string; const newname: string); +begin + inherited; + if componentstate * [csdesigning,csreading,csloading,csdestroying] = + [csdesigning] then begin + if acomponent = nil then begin + acomponent:= self; + end; + designvalidaterename(acomponent,curname,newname); + end; +end; + +procedure tmsecomponent.setsubcompref; +begin + setsubcomponent(true); + include (fmsecomponentstate,cs_subcompref); +end; + +procedure tmsecomponent.setchildorder(child: tcomponent; order: integer); +var + int1,int2: integer; +begin + int2:= -1; + for int1:= 0 to componentcount-1 do begin + if not components[int1].hasparent then begin //number simple owned only + inc(int2); + if int2 = order then begin + child.componentindex:= int1; + break; + end; + end; + end; +end; + +{$ifdef mse_with_ifi} +procedure tmsecomponent.setifiserverintf(const aintf: iifiserver); +begin + fifiserverintf:= aintf; +end; +{ +function tmsecomponent.getifiserverintf: iifiserver; +begin + result:= fifiserverintf; +end; +} +procedure tmsecomponent.executeificommand(var acommand: ificommandcodety); +begin + //dummy +end; + +function tmsecomponent.getdefaultifilink: iificlient; +begin + result:= iificlient(self); +end; + +function tmsecomponent.getifidatatype: listdatatypety; +begin + result:= dl_none; +end; + +{$endif} + +{ tlinkedqueue } + +constructor tlinkedqueue.create(aownsobjects: boolean); +begin + fownsobjects:= aownsobjects; + fobjectlinker:= tobjectlinker.create(iobjectlink(self),{$ifdef FPC}@{$endif}objectevent); + inherited create; +end; + +destructor tlinkedqueue.destroy; +begin + include(fobjectlinker.fstate,rels_destroying); + inherited; + freeandnil(fobjectlinker); +end; + +function tlinkedqueue.destroying: boolean; +begin + result:= (fobjectlinker = nil) or (rels_destroying in fobjectlinker.fstate); +end; + +function tlinkedqueue.add(const value: iobjectlink): integer; +begin + result:= inherited add(pointer(value)); + fobjectlinker.link(iobjectlink(self),value); +end; + +function tlinkedqueue.getfirst: iobjectlink; +begin + result:= iobjectlink(inherited getfirst); + fobjectlinker.unlink(iobjectlink(self),result); +end; + +function tlinkedqueue.getlast: iobjectlink; +begin + result:= iobjectlink(inherited getlast); + fobjectlinker.unlink(iobjectlink(self),result); +end; + +function tlinkedqueue.getitems(const index: integer): iobjectlink; +begin + result:= iobjectlink(inherited getitems(index)); +end; + +procedure tlinkedqueue.insert(const index: integer; + const value: iobjectlink); +begin + inherited insert(index,pointer(value)); + fobjectlinker.link(iobjectlink(self),value); +end; + +procedure tlinkedqueue.setitems(const index: integer; + const Value: iobjectlink); +begin + fobjectlinker.unlink(iobjectlink(self),getitems(index)); + inherited setitems(index,pointer(value)); + fobjectlinker.link(iobjectlink(self),value); +end; + +procedure tlinkedqueue.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tlinkedqueue.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + fobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tlinkedqueue.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + fobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tlinkedqueue.objevent(const sender: iobjectlink; const event: objecteventty); +begin + fobjectlinker.objevent(sender,event); + if event = oe_destroyed then begin + linkdestroyed(sender); + inc(fnofinalize); + try + remove(pointer(sender)); + finally + dec(fnofinalize); + end; + end; +end; + +function tlinkedqueue.getinstance: tobject; +begin + result:= fainstance; +end; + +procedure tlinkedqueue.finalizeitem(var item: pointer); +begin + fobjectlinker.unlink(iobjectlink(self),iobjectlink(item)); + if fownsobjects then begin + iobjectlink(item).getinstance.Free; + end; + inherited; +end; + +procedure tlinkedqueue.sendchangenotification(sender: tobject); +begin + fainstance:= sender; + fobjectlinker.sendevent(oe_changed); + fainstance:= nil; +end; + +procedure tlinkedqueue.linkdestroyed(const alink: iobjectlink); +begin + //dummy +end; + +{ tlinkedobjectqueue } + +function tlinkedobjectqueue.add(const value: tlinkedobject): integer; +begin + result:= inherited add(iobjectlink(value)); +end; + +function tlinkedobjectqueue.getfirst: tlinkedobject; +begin + result:= tlinkedobject(inherited getfirst.getinstance); +end; + +function tlinkedobjectqueue.getlast: tlinkedobject; +begin + result:= tlinkedobject(inherited getlast.getinstance); +end; + +function tlinkedobjectqueue.getitems(const index: integer): tlinkedobject; +begin + result:= tlinkedobject(inherited getitems(index).getinstance); +end; + +procedure tlinkedobjectqueue.insert(const index: integer; + const value: tlinkedobject); +begin + inherited insert(index,iobjectlink(value)); +end; + +procedure tlinkedobjectqueue.setitems(const index: integer; + const Value: tlinkedobject); +begin + inherited setitems(index,iobjectlink(value)); +end; + +function tlinkedobjectqueue.findobject(const aobject: tlinkedobject): integer; +begin + result:= indexof(pointer(iobjectlink(aobject))); +end; + +{ tpersistentqueue } + +procedure tpersistentqueue.add(const value: tlinkedpersistent); +begin + inherited add(iobjectlink(value)); +end; + +function tpersistentqueue.getfirst: tlinkedpersistent; +begin + result:= tlinkedpersistent(inherited getfirst.getinstance); +end; + +function tpersistentqueue.getlast: tlinkedpersistent; +begin + result:= tlinkedpersistent(inherited getlast.getinstance); +end; + +function tpersistentqueue.getitems(const index: integer): tlinkedpersistent; +begin + result:= tlinkedpersistent(inherited getitems(index).getinstance); +end; + +procedure tpersistentqueue.insert(const index: integer; + const value: tlinkedpersistent); +begin + inherited insert(index,iobjectlink(value)); +end; + +procedure tpersistentqueue.setitems(const index: integer; + const Value: tlinkedpersistent); +begin + inherited setitems(index,iobjectlink(value)); +end; + +function tpersistentqueue.findobject(const aobject: tlinkedpersistent): integer; +begin + result:= indexof(pointer(iobjectlink(aobject))); +end; + +{ tcomponentqueue } + +function tcomponentqueue.add(const value: tmsecomponent): integer; +begin + result:= inherited add(ievent(value)); +end; + +function tcomponentqueue.getfirst: tmsecomponent; +begin + result:= tmsecomponent(inherited getfirst.getinstance); +end; + +function tcomponentqueue.getlast: tmsecomponent; +begin + result:= tmsecomponent(inherited getlast.getinstance); +end; + +function tcomponentqueue.getitems(const index: integer): tmsecomponent; +begin + result:= tmsecomponent(inherited getitems(index).getinstance); +end; + +procedure tcomponentqueue.insert(const index: integer; + const value: tmsecomponent); +begin + inherited insert(index,ievent(value)); +end; + +procedure tcomponentqueue.setitems(const index: integer; + const Value: tmsecomponent); +begin + inherited setitems(index,ievent(value)); +end; + +function tcomponentqueue.findobject(const aobject: tmsecomponent): integer; +begin + result:= indexof(pointer(ievent(aobject))); +end; + +{ tobjectlinkrecordlist } + +constructor tobjectlinkrecordlist.create(arecordsize: integer; aoptions: recordliststatesty = []); +begin + inherited create(arecordsize,aoptions+[rels_needsfinalize]); + fobjectlinker:= tobjectlinker.create(iobjectlink(self),nil); +end; + +destructor tobjectlinkrecordlist.destroy; +begin + inherited; + fobjectlinker.free; +end; + +procedure tobjectlinkrecordlist.finalizerecord(var item); +begin + dounlink(item) +end; + +function tobjectlinkrecordlist.getinstance: tobject; +begin + result:= self; +end; + +procedure tobjectlinkrecordlist.link(const source, dest: iobjectlink; valuepo, + ainterfacetype: pointer; once: boolean); +begin + fobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tobjectlinkrecordlist.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + fobjectlinker.objevent(sender,event); + if event = oe_destroyed then begin + itemdestroyed(sender); + end; +end; + +procedure tobjectlinkrecordlist.unlink(const source, dest: iobjectlink; + valuepo: pointer); +begin + fobjectlinker.unlink(source,dest,valuepo); +end; + +{ tvirtualpersistent } + +constructor tvirtualpersistent.create; +begin + inherited; + internalcreate; +end; + +procedure tvirtualpersistent.internalcreate; +begin + //dummy +end; + +{ townedeventpersistent } + +constructor townedeventpersistent.create(aowner: tobject); +begin + fowner:= aowner; + inherited create; +end; + +{ teventpersistent } + +procedure teventpersistent.receiveevent(const event: tobjectevent); +begin + //dummy +end; + +{ tpersistenttemplate } + +constructor tpersistenttemplate.create(const owner: tmsecomponent; + const onchange: notifyeventty); +begin + fowner:= owner; + fonchange:= onchange; +end; + +procedure tpersistenttemplate.changed; +begin + if assigned(fonchange) and not (csloading in fowner.componentstate) then begin + fonchange(self); + end; +end; + +procedure tpersistenttemplate.copyinfo(const source: tpersistenttemplate); +begin + //dummy +end; + +procedure tpersistenttemplate.assignto(dest: tpersistent); +begin + doassignto(dest); +end; + +procedure tpersistenttemplate.assign(source: tpersistent); +begin + if source is classtype then begin + move(tpersistenttemplate(source).getinfoad^,getinfoad^,getinfosize); + copyinfo(tpersistenttemplate(source)); + changed; + end + else begin + inherited; + end; +end; + +{ ttemplatecontainer } + +constructor ttemplatecontainer.create(aowner: tcomponent); +begin + ftemplate:= gettemplateclass.create(self,{$ifdef FPC}@{$endif}templatechanged); + inherited; +end; + +destructor ttemplatecontainer.destroy; +begin + inherited; + ftemplate.free; +end; + +procedure ttemplatecontainer.assignto(dest: tpersistent); +begin + tpersistent1(ftemplate).assignto(dest); +end; + +procedure ttemplatecontainer.templatechanged(const sender: tobject); +begin + sendchangeevent; +end; + +function findmodulebyname(const name: string): tcomponent; +begin + result:= modules.findmodulebyname(name); +end; + +function findcomponentbynamepath(const namepath: string): tcomponent; +var + ar1: stringarty; + int1: integer; +begin + result:= nil; + ar1:= splitstring(namepath,'.'); + if high(ar1) >= 0 then begin + result:= modules.findmodulebyname(ar1[0]); + for int1:= 1 to high(ar1) do begin + if result = nil then begin + break; + end; + result:= result.FindComponent(ar1[int1]); + end; + end; +end; + +function findcomponentbynamepath(const namepath: string; + const root: tcomponent): tcomponent; + //name path does not contain root +var + po1,po2: pchar; +// comp1: tcomponent; +begin + result:= nil; + if (root <> nil) and (namepath <> '') then begin + po1:= pchar(namepath); + po2:= po1; + while (po2^ <> '.') and (po2^ <> #0) do begin + inc(po2); + end; + if stringicomp(root.name,psubstr(po1,po2)) = 0 then begin + result:= root; + while po2^ <> #0 do begin + inc(po2); + po1:= po2; + while (po2^ <> '.') and (po2^ <> #0) do begin + inc(po2); + end; + result:= result.findcomponent(psubstr(po1,po2)); + if result = nil then begin + break; + end; + end; + end; + end; +end; + +function findsubcomponentbynamepath(const namepath: string; + const root: tcomponent): tcomponent; +var + po1,po2: pchar; + comp1: tcomponent; +begin + result:= nil; + if (root <> nil) and (namepath <> '') then begin + comp1:= root; + po1:= pchar(namepath); + po2:= po1; + while true do begin + po1:= po2; + while (po2^ <> '.') and (po2^ <> #0) do begin + inc(po2); + end; + result:= comp1.findcomponent(psubstr(po1,po2)); + if result = nil then begin + break; + end; + if po2^ = #0 then begin + break; + end; + inc(po2); + comp1:= result; + end; + end; +end; + +Type + TPosComponent = Class(TObject) + FPos : Integer; + FComponent : TComponent; + Constructor Create(APos : Integer; AComponent : TComponent); + end; + +Constructor TPosComponent.Create(APos : Integer; AComponent : TComponent); + +begin + FPos:=APos; + FComponent:=AComponent; +end; + +{ twritermse } + +constructor twritermse.create(const stream: tstream; const bufsize: integer; + const anoancestor: boolean = false; + const amasterancestor: boolean = false); +begin +// fgetchildrenbefore:= onstreaminggetchildren; +// onstreaminggetchildren:= @dogetchildren; + fnoancestor:= anoancestor; + fmasterancestor:= amasterancestor; + inherited create(stream,bufsize); +end; + +destructor twritermse.destroy; +begin + inherited; +// onstreaminggetchildren:= fgetchildrenbefore; +end; + +function twritermse.rootcompname(const acomp: tcomponent; + const aroot: tcomponent): string; +var + comp1: tcomponent; +begin + result:= acomp.name; + comp1:= acomp.owner; + while (comp1 <> aroot) and (comp1 <> nil) do begin + result:= comp1.name+'.'+result; + comp1:= comp1.owner; + end; +end; + +function twritermse.rootcompname(const acomp: tcomponent; + arootlevel: integer): string; +var + comp1: tcomponent; +begin + result:= acomp.name; + comp1:= acomp.owner; + while (arootlevel > 0) and (comp1 <> nil) do begin + result:= comp1.name+'.'+result; + comp1:= comp1.owner; + dec(arootlevel); + end; +end; + +// Used as argument for calls to TComponent.GetChildren: +procedure TWritermse.AddToAncestorList(Component: TComponent); +begin + FAncestors.AddObject(rootcompname(Component,fancestorlookuplevel), + TPosComponent.Create(FAncestors.Count,Component)); +end; + + +procedure TWritermse.DetermineAncestor(Component : TComponent); + +Var + I : Integer; + comp1: tcomponent; + int1: integer; +begin + // Should be set only when we write an inherited with children. + if Not Assigned(FAncestors) then begin + exit; + end; + comp1:= froot; + for int1:= fancestorlookuplevel-1 downto 0 do begin + comp1:= comp1.owner; + end; + if comp1 = nil then begin + comp1:= flookuproot; //should not happen + end; + I:=FAncestors.IndexOf(rootcompname(Component,comp1)); + If (I=-1) then + begin + FAncestor:=Nil; + FAncestorPos:=-1; + end + else begin + With TPosComponent(FAncestors.Objects[i]) do begin + FAncestor:=FComponent; + FAncestorPos:=FPos; + end; + end; +end; + +procedure TWritermse.DoFindAncestor(Component : TComponent); + +Var + C : TComponent; + +begin + if Assigned(FOnFindAncestor) then + if (Ancestor=Nil) or (Ancestor is TComponent) then + begin + C:=TComponent(Ancestor); + FOnFindAncestor(Self,Component,Component.Name,C,FRootAncestor); + Ancestor:=C; + end; + if frootrootancestor = nil then begin + frootrootancestor:= tcomponent(fancestor); + end; +end; + +procedure TWritermse.WriteComponent(Component: TComponent); + +var + SA : TPersistent; + SR, SRA : TComponent; +begin + SR:=FRoot; + SA:=FAncestor; + SRA:=FRootAncestor; + inc(fchildlevel); + Try +{$warnings off} + tcomponent1(Component).FComponentState:= + tcomponent1(Component).FComponentState+[csWriting]; +{$warnings on} + Try + if not fnoancestor or (csinline in component.componentstate) or + (fchildlevel > 1) then begin + // Possibly set ancestor. + DetermineAncestor(Component); + DoFindAncestor(Component); + // Mainly for IDE when a parent form had an ancestor renamed... + end; + tcomponent1(Component).WriteState(Self); + // Will call WriteComponentData. + {$ifdef FPC} + FDriver.EndList; + {$else} + writelistend; + {$endif} + Finally +{$warnings off} + tcomponent1(Component).FComponentState:= + tcomponent1(Component).FComponentState-[csWriting]; +{$warnings on} + end; + Finally + dec(fchildlevel); + FAncestor:=SA; + FRoot:=SR; + FRootAncestor:=SRA; + end; +end; + +procedure TWritermse.WriteChildren(Component : TComponent); + +Var + SRoot, SRootA : TComponent; + SList : TStringList; + SPos : Integer; + I : Integer; + ancestorlookuplevelbefore: integer; + rootrootancestorbefore: tcomponent; + +begin + // Write children list. + // While writing children, the ancestor environment must be saved + // This is recursive... + SRoot:=FRoot; + SRootA:=FRootAncestor; + SList:=FAncestors; + SPos:=FCurrentPos; + ancestorlookuplevelbefore:= fancestorlookuplevel; + rootrootancestorbefore:= frootrootancestor; + try + FAncestors:=Nil; + FCurrentPos:=0; + FAncestorPos:=-1; + if csInline in Component.ComponentState then + FRoot:=Component; + if (FAncestor is TComponent) then + begin + FAncestors:=TStringList.Create; + if csInline in TComponent(FAncestor).ComponentState then begin + FRootAncestor := TComponent(FAncestor); + if frootrootancestor <> frootancestor then begin + inc(fancestorlookuplevel); + end; + end; +// TComponent1(FAncestor).GetChildren(@AddToAncestorList,frootancestor); + GetChildren1(tcomponent(FAncestor),{$ifdef FPC}@{$endif}AddToAncestorList,frootancestor); + FAncestors.Sorted:=True; + end; + try +// tcomponent1(Component).GetChildren(@WriteComponent, FRoot); + GetChildren1(component,{$ifdef FPC}@{$endif}WriteComponent, FRoot); + Finally + If Assigned(Fancestors) then + For I:=0 to FAncestors.Count-1 do + FAncestors.Objects[i].Free; + FreeAndNil(FAncestors); + end; + finally + FAncestors:=Slist; + FRoot:=SRoot; + FRootAncestor:=SRootA; + FCurrentPos:=SPos; + FAncestorPos:=Spos; + fancestorlookuplevel:= ancestorlookuplevelbefore; + frootrootancestor:= rootrootancestorbefore; + end; +end; + +procedure TWritermse.WriteComponentData(Instance: TComponent); +var + Flags: TFilerFlags; +begin + Flags := []; + If (Assigned(FAncestor)) and //has ancestor + (not (csInline in Instance.ComponentState) or // no inline component + // .. or the inline component is inherited + (csAncestor in Instance.Componentstate) and (FAncestors <> nil)) then + Flags:=[ffInherited] + else If csInline in Instance.ComponentState then + Flags:=[ffInline]; + If (FAncestors<>Nil) and ((FCurrentPos<>FAncestorPos) or (FAncestor=Nil)) then + Include(Flags,ffChildPos); + FDriver.BeginComponent(Instance,Flags,FCurrentPos); + If (FAncestors<>Nil) then + Inc(FCurrentPos); + WriteProperties(Instance); + WriteListEnd; + // Needs special handling of ancestor. + If not IgnoreChildren then begin + WriteChildren(Instance); + end; +end; +{ +procedure twritermse.dogetchildren(const sender: tmsecomponent; + const proc: tgetchildproc; const aroot: tcomponent); +var + root1: tcomponent; + comp1,comp2: tcomponent; + int1: integer; +begin + comp1:= aroot; + if aroot = rootancestor then begin + comp2:= frootrootancestor; + int1:= fancestorlookuplevel; + try + while (comp1 <> nil) and (fancestorlookuplevel >= 0) do begin + tmsecomponent(sender).getchildren1(proc,comp1); + comp1:= comp1.owner; + dec(fancestorlookuplevel); + end; + finally + fancestorlookuplevel:= int1; + end; + end + else begin + comp2:= frootroot; + while comp1 <> nil do begin + tmsecomponent(sender).getchildren1(proc,comp1); + if comp1 = comp2 then begin + break; + end; + comp1:= comp1.owner; + end; + end; +end; +} +procedure twritermse.getchildren1(const acomp: tcomponent; + const proc: tgetchildproc; const aroot: tcomponent); + //support for added components to submodules +var +// root1: tcomponent; + comp1,comp2: tcomponent; + int1: integer; +begin + comp1:= aroot; + if aroot = rootancestor then begin + comp2:= frootrootancestor; + int1:= fancestorlookuplevel; + try + while (comp1 <> nil) and (fancestorlookuplevel >= 0) do begin + tcomponent1(acomp).getchildren(proc,comp1); + comp1:= comp1.owner; + dec(fancestorlookuplevel); + end; + finally + fancestorlookuplevel:= int1; + end; + end + else begin + comp2:= frootroot; + while comp1 <> nil do begin + tcomponent1(acomp).getchildren(proc,comp1); + if comp1 = comp2 then begin + break; + end; + comp1:= comp1.owner; + end; + end; +end; + +procedure twritermse.writedescendent(const aroot: tcomponent; + const aancestor: tcomponent); +begin + frootrootancestor:= aancestor; + frootroot:= aroot; + FRoot := ARoot; + FAncestor := AAncestor; + FRootAncestor := AAncestor; + FLookupRoot := ARoot; + + WriteComponent(ARoot); +// inherited writedescendent(aroot,aancestor); +end; + +procedure twritermse.writerootcomponent(aroot: tcomponent); +begin + writedescendent(aroot,nil); +end; + +function twritermse.getclassname(const aobj: tobject): shortstring; +begin + if aobj is tmsecomponent then begin + result:= tmsecomponent(aobj).actualclassname; + end + else begin + result:= inherited getclassname(aobj); + end; +end; + +initialization + loadmoduletracker:= tloadmoduletracker.create; +{$ifdef FPC} + registerinitcomponenthandler(tmsecomponent,@initmsecomponent1); +{$endif} + registerfindglobalcomponentproc({$ifdef FPC}@{$endif}findmodulebyname); +finalization + freeandnil(fmodules); + freeandnil(floadedlist); +{$ifdef FPC} +// unregisterinitcomponenthandler(tcomponent,@initmsecomponent); +{$endif} + unregisterfindglobalcomponentproc({$ifdef FPC}@{$endif}findmodulebyname); + loadmoduletracker.free; + freeandnil(objectdatalist); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts.pas b/mseide-msegui/lib/common/kernel/mseconsts.pas new file mode 100644 index 0000000..3a0e104 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts.pas @@ -0,0 +1,492 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseconsts; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +uses + msestockobjects,mseglob,msestrings,mseapplication,msetypes; + +type + stockcaptionaty = array[stockcaptionty] of msestring; + pstockcaptionaty = ^stockcaptionaty; + defaultmodalresulttextty = array[modalresultty] of msestring; + pdefaultmodalresulttextty = ^defaultmodalresulttextty; + defaultgeneratortextty = array[textgeneratorty] of textgeneratorfuncty; + pdefaultgeneratortextty = ^defaultgeneratortextty; + + langty = (la_none,la_en,la_de,la_ru,la_es,la_uzcyr,la_id,la_zh, + la_fr); + +const + langnames: array[langty] of string = ( + '','en','de','ru','es','uz_cyr','id','zh', + 'fr'); + + function modalresulttext(const index: modalresultty): msestring; + function modalresulttextnoshortcut(const index: modalresultty): msestring; + function stockcaptions(const index: stockcaptionty): msestring; + function stocktextgenerators(const index: textgeneratorty): textgeneratorfuncty; + function uc(const index: integer): msestring; //get user caption + + procedure registeruserlangconsts(name: string; + const caption: array of msestring); + procedure registerlangconsts(const name: string; + const stockcaptionpo: pstockcaptionaty; + const modalresulttextpo: pdefaultmodalresulttextty; + const modalresulttextnoshortcutpo: pdefaultmodalresulttextty; + const textgeneratorpo: pdefaultgeneratortextty); + function setlangconsts(const name: string): boolean; + //true if ok, no change otherwise + function getcurrentlangconstsname: string; + procedure setuserlangconsts(const name: string); + //called by setlangconsts automatically +type + langchangeprocty = procedure(const langname: ansistring); + + procedure registerlangchangeproc(const aproc: langchangeprocty); + procedure unregisterlangchangeproc(const aproc: langchangeprocty); + +implementation +uses + sysutils,msesysintf,msearrayutils,mseformatstr; + +type + langinfoty = record + name: string; + stockcaption: pstockcaptionaty; + modalresulttext: pdefaultmodalresulttextty; + modalresulttextnoshortcut: pdefaultmodalresulttextty; + textgenerator: pdefaultgeneratortextty; + end; + userlanginfoty = record + name: string; + caption: msestringarty; + end; + +var + langs: array of langinfoty; + lang: langinfoty; + langbefore: ansistring; + userlangs: array of userlanginfoty; + userlang: userlanginfoty; + langchangeprocs: array of langchangeprocty; + +const + en_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&Cancel', //mr_cancel + '&Abort', //mr_abort + '&OK', //mr_ok + '&Yes', //mr_yes + '&No', //mr_no + '&All', //mr_all + 'Yes &all', //mr_yesall + 'N&o all', //mr_noall + '&Ignore', //mr_ignore + '&Skip', //mr_skip + 'Skip a&ll', //mr_skipall + 'Co&ntinue' //mr_continue + ); + + en_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_esc + '', //mr_f10 + '', //mr_exception + 'Cancel', //mr_cancel + 'Abort', //mr_abort + 'OK', //mr_ok + 'Yes', //mr_yes + 'No', //mr_no + 'All', //mr_all + 'Yes all', //mr_yesall + 'No all', //mr_noall + 'Ignore', //mr_ignore + 'Skip', //mr_skip + 'Skip all', //mr_skipall + 'Continue' //mr_continue + ); + + en_stockcaption: stockcaptionaty = ( + '', //sc_none + 'is invalid', //sc_is_invalid + 'Format error', //sc_Format_error + 'Value is required', //sc_Value_is_required + 'Error', //sc_Error + 'Min', //sc_Min + 'Max', //sc_Max + 'Range error', //sc_Range_error + + '&Undo', //sc_Undohk /// /// + '&Redo', //sc_Redohk // // + '&Copy', //sc_Copyhk // hotkeys // + 'Cu&t', //sc_Cuthk // // + '&Paste', //sc_Pastehk // // hotkeys + 'Select &all', //sc_Select_allhk /// // + '&Insert Row', //sc_insert_rowhk /// // + '&Append Row', //sc_append_rowhk // hotkeys // + '&Delete Row', //sc_delete_rowhk /// /// + + '&Dir', //sc_Dirhk /// + '&Home', //sc_homehk // + '&Up', //sc_Uphk // + '&New dir', //sc_New_dirhk // hotkeys + '&Name', //sc_Namehk // + '&Show hidden files', //sc_Show_hidden_fileshk // + '&Filter', //sc_Filterhk /// + 'Save', //sc_save + 'Open', //sc_open + 'Name', //sc_name + 'Create new directory',//sc_create_new_directory + 'Back', //sc_back + 'Forward', //sc_forward + 'Up', //sc_up + 'File', //sc_file + 'exists, do you want to overwrite?', //sc_exists_overwrite + 'is modified. Save?', //sc_is_modified_save + 'WARNING', //sc_warningupper + 'ERROR', //sc_errorupper + 'Exception', //sc_exception + 'System', //sc_system + 'does not exist', //sc_does_not_exist + 'PASSWORD', //sc_passwordupper + 'Enter password', //sc_enterpassword + 'Invalid password!', //sc_invalidpassword + 'Can not read directory', //sc_can_not_read_directory + 'Graphic format not supported', //sc_graphic_not_supported + 'Graphic format error', //sc_graphic_format_error + 'MS Bitmap', //sc_MS_Bitmap + 'MS Icon', //sc_MS_Icon + 'JPEG Image', //sc_JPEG_Image + 'PNG Image', //sc_PNG_Image + 'XPM Image', //sc_XPM_Image + 'PNM Image', //sc_PNM_Image + 'TARGA Image', //sc_TARGA_image + 'TIFF Image', //sc_TIFF_image + 'All', //sc_All + 'Confirmation', //sc_Confirmation + 'Delete record?', //sc_Delete_record_question + 'Copy record?', //sc_Copy_record_question + 'Close page', //sc_close_page + 'First', //sc_first + 'Prior', //sc_prior + 'Next', //sc_next + 'Last', //sc_last + 'Append', //sc_append + 'Delete', //sc_delete + 'Edit', //sc_edit + 'Post', //sc_post + 'Cancel', //sc_cancel + 'Refresh', //sc_refresh + 'Edit filter', //sc_filter_filter + 'Edit filter minimum',//sc_edit_filter_min + 'Edit filter maximum',//sc_filter_edit_max + 'Reset filter', //sc_reset_filter + 'Filter on', //sc_filter_on + 'Search', //sc_search + 'Auto edit', //sc_auto_edit + 'Copy record', //sc_copy_record + 'Dialog', //sc_dialog + 'Insert', //sc_insert + 'Copy', //sc_copy + 'Paste', //sc_paste + 'Row insert', //sc_row_insert + 'Row append', //sc_row_append + 'Row delete', //sc_row_delete + 'Undo', //sc_undo + 'Redo', //sc_redo + 'Cut', //sc_cut + 'Select all', //sc_select_all + + 'Filter off', //sc_filter_off + 'Portrait', //sc_portrait print orientation + 'Landscape', //sc_landscape print orientation + 'Delete row?', //sc_Delete_row_question + 'selected rows?', //sc_selected_rows + 'Single item only', //sc_Single_item_only + 'Copy Cells', //sc_Copy_Cells + 'Paste Cells', //sc_Paste_Cells + 'Close', //sc_close + 'Maximize', //sc_maximize + 'Normalize', //sc_normalize + 'Minimize', //sc_minimize + 'Fix size', //sc_fix_size + 'Float', //sc_float + 'Stay on top', //sc_stay_on_top + 'Stay in background', //sc_stay_in_background + 'Lock children', //sc_lock_children + 'No lock', //sc_no_lock + 'Input', //sc_input + 'Button', //sc_button + 'On', //sc_on + 'Off', //sc_off + 'Left border', //sc_leftborder + 'Top border', //sc_topborder + 'Right border', //sc_rightborder + 'Bottom border', //sc_bottomborder + 'Begin of text', //sc_beginoftext + 'End of text', //sc_endoftext + 'Inputmode', //sc_inputmode + 'Overwrite', //sc_overwrite + 'Deleted', //sc_deleted + 'Copied', //sc_copied + 'Inserted', //sc_inserted + 'Pasted', //sc_pasted + 'Withdrawn', //sc_withdrawn + 'Window activated', //sc_windowactivated + 'Menu', //sc_menu + 'Beginning of file', //sc_bof + 'End of file', //sc_eof + 'Voice output', //sc_voiceoutput + 'Speak again', //sc_speakagain + 'First column', //sc_firstcol + 'First row', //sc_firstrow + 'Last column', //sc_lastcol + 'Last row', //sc_lastrow + 'Selection', //sc_selection + 'Speak path', //sc_speakpath + 'Disabled button', //sc_disabledbutton + 'First field', //sc_firstfield + 'Last field', //sc_lastfield + 'First element', //sc_firstelement + 'Last element', //sc_lastelement + 'Slower', //sc_slower + 'Faster', //sc_faster + 'Window', //sc_window + 'Area', //sc_area + 'Area activated', //sc_areaactivated + 'Volume down', //sc_volumedown + 'Volume up', //sc_volumeup + 'Cancel speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= 'Delete selected row?' + end + else begin + result:= 'Delete '+inttostrmse(vinteger)+' selected rows?'; + end; + end; +end; + +const + en_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); + +procedure setitem(var item: langinfoty; + const name: string; + const stockcaptionpo: pstockcaptionaty; + const modalresulttextpo: pdefaultmodalresulttextty; + const modalresulttextnoshortcutpo: pdefaultmodalresulttextty; + const textgeneratorpo: pdefaultgeneratortextty); +begin + item.name:= name; + item.stockcaption:= stockcaptionpo; + item.modalresulttext:= modalresulttextpo; + item.modalresulttextnoshortcut:= modalresulttextnoshortcutpo; + item.textgenerator:= textgeneratorpo; +end; + +procedure registerlangconsts(const name: string; + const stockcaptionpo: pstockcaptionaty; + const modalresulttextpo: pdefaultmodalresulttextty; + const modalresulttextnoshortcutpo: pdefaultmodalresulttextty; + const textgeneratorpo: pdefaultgeneratortextty); + + +var + int1: integer; +begin + for int1:= 0 to high(langs) do begin + if langs[int1].name = name then begin + setitem(langs[int1],name,stockcaptionpo,modalresulttextpo, + modalresulttextnoshortcutpo,textgeneratorpo); + exit; + end; + end; + setlength(langs,high(langs)+2); + setitem(langs[high(langs)],name,stockcaptionpo,modalresulttextpo, + modalresulttextnoshortcutpo,textgeneratorpo); +end; + +procedure registeruserlangconsts(name: string; + const caption: array of msestring); + procedure setitem(var item: userlanginfoty); + var + int1: integer; + begin + item.name:= name; + setlength(item.caption,length(caption)); + for int1:= 0 to high(caption) do begin + item.caption[int1]:= caption[int1]; + end; + end; + +var + int1: integer; +begin + name:= lowercase(name); + for int1:= 0 to high(userlangs) do begin + if userlangs[int1].name = name then begin + setitem(userlangs[int1]); + exit; + end; + end; + setlength(userlangs,high(userlangs)+2); + setitem(userlangs[high(userlangs)]); +end; + +procedure setuserlangconsts(const name: string); +var + int1: integer; +begin + if name = '' then begin + if high(userlangs) >= 0 then begin + userlang:= userlangs[0]; + end; + end + else begin + if name <> userlang.name then begin + for int1:= 0 to high(userlangs) do begin + if userlangs[int1].name = name then begin + userlang:= userlangs[int1]; + break; + end; + end; + end; + end; +end; + +function getcurrentlangconstsname: string; +begin + result:= lang.name; +end; + +function setlangconsts(const name: string): boolean; +var + int1: integer; + bo1: boolean; + str1: string; +begin + if name = '' then begin + str1:= lowercase(sys_getlangname); + if str1 = '' then begin + str1:= langnames[la_en]; + end; + end + else begin + str1:= lowercase(name); + end; + setuserlangconsts(str1); + result:= false; + bo1:= lang.name = ''; + if lang.name <> str1 then begin + for int1:= 0 to high(langs) do begin + if langs[int1].name = str1 then begin + lang:= langs[int1]; + result:= true; + break; + end; + end; + if bo1 then begin + if lang.name = '' then begin + setitem(lang,langnames[la_en],@en_stockcaption,@en_modalresulttext, + @en_modalresulttextnoshortcut,@en_textgenerator); +{ + with lang do begin + name:= langnames[la_en]; + stockcaption:= @en_stockcaption; + modalresulttext:= @en_modalresulttext; + modalresulttextnoshortcut:= @en_modalresulttextnoshortcut; + textgenerator:= @en_textgenerator; + end; +} + end; + end; + end; + if lowercase(str1) <> langbefore then begin + for int1:= 0 to high(langchangeprocs) do begin + langchangeprocs[int1](str1); + end; + application.langchanged; + end; +end; + +procedure checklang; +begin + if lang.name = '' then begin + setlangconsts(''); + end; +end; + +function uc(const index: integer): msestring; +begin + if userlang.name = '' then begin + setuserlangconsts(''); + end; + if (index < 0) or (index > high(userlang.caption)) then begin + raise exception.create('Invalid user caption index: '+inttostr(index)+'.'); + end; + result:= userlang.caption[index]; +end; + +function modalresulttext(const index: modalresultty): msestring; +begin + checklang; + result:= lang.modalresulttext^[index]; +end; + +function modalresulttextnoshortcut(const index: modalresultty): msestring; +begin + checklang; + result:= lang.modalresulttextnoshortcut^[index]; +end; + +function stocktextgenerators(const index: textgeneratorty): textgeneratorfuncty; +begin + checklang; + result:= lang.textgenerator^[index]; +end; + +function stockcaptions(const index: stockcaptionty): msestring; +begin + checklang; + result:= lang.stockcaption^[index]; +end; + +procedure registerlangchangeproc(const aproc: langchangeprocty); +begin + additem(pointerarty(langchangeprocs),{$ifndef FPC}@{$endif}aproc); +end; + +procedure unregisterlangchangeproc(const aproc: langchangeprocty); +begin + removeitem(pointerarty(langchangeprocs),{$ifndef FPC}@{$endif}aproc); +end; + +initialization + registerlangconsts(langnames[la_en],@en_stockcaption,@en_modalresulttext, + @en_modalresulttextnoshortcut,@en_textgenerator); + langbefore:= langnames[la_en]; +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_de.pas b/mseide-msegui/lib/common/kernel/mseconsts_de.pas new file mode 100644 index 0000000..ac2243b --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_de.pas @@ -0,0 +1,236 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseconsts_de; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseconsts; + +implementation +uses + msetypes{msestrings},sysutils,mseformatstr; +const + de_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&Abbrechen', //mr_cancel + '&Abbrechen', //mr_abort + '&OK', //mr_ok + '&Ja', //mr_yes + '&Nein', //mr_no + 'A&lle', //mr_all + 'Ja a&lle', //mr_yesall + 'N&ein alle', //mr_noall + '&Ignorieren', //mr_ignore + #0220'bers&pringen', //mr_skip + 'Alles '#0252'&berspringen', //mr_skipall + '&Fortfahren' //mr_continue + ); + + de_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + 'Abbrechen', //mr_cancel + 'Abbrechen', //mr_abort + 'OK', //mr_ok + 'Ja', //mr_yes + 'Nein', //mr_no + 'Alle', //mr_all + 'Ja alle', //mr_yesall + 'Nein alle', //mr_noall + 'Ignorieren', //mr_ignore + #0220'berspringen', //mr_skip + 'Alles '#0252'berspringen', //mr_skipall + 'Fortfahren' //mr_continue + ); + + de_stockcaption: stockcaptionaty = ( + '', //sc_none + 'ist ung'#0252'ltig', //sc_is_invalid + 'Format Fehler', //sc_Format_error + 'Wert wird ben'#0246'tigt', //sc_Value_is_required + 'Fehler', //sc_Error + 'Min', //sc_Min + 'Max', //sc_Max + 'Bereichs Fehler', //sc_Range_error + + '&R'#0252'ckg'#0228'ngig', //sc_Undohk /// /// + '&Redo', //sc_Redohk // // + '&Kopieren', //sc_Copyhk // hotkeys // + '&Ausschneiden', //sc_Cuthk // // + '&Einf'#0252'gen', //sc_Pastehk // // hotkeys + 'Alles &markieren', //sc_Select_allhk /// // + 'Zeile e&inf'#0252'gen', //sc_insert_rowhk /// // + 'Zeile a&nf'#0252'gen', //sc_append_rowhk // hotkeys // + 'Zeile &l'#0246'schen', //sc_delete_rowhk /// /// + + '&Dir', //sc_Dirhk /// + '&Home', //sc_homehk // + '&Auf', //sc_Uphk // + 'Dir &neu', //sc_New_dirhk // hotkeys + 'N&ame', //sc_Namehk // + '&Verst.Dat.anzeigen', //sc_Show_hidden_fileshk // + '&Filter', //sc_Filterhk /// + 'Speichern', //sc_save + #0214'ffnen', //sc_open + 'Name', //sc_name + 'Verzeichnis erstellen',//sc_create_new_directory + 'Zurück', //sc_back + 'Forw'#0228'rts', //sc_forward + 'Aufw'#0228'rts', //sc_up + 'Datei', //sc_file + 'existiert, wollen Sie '#0252'berschreiben?', //sc_exists_overwrite + 'wurde geändert, wollen Sie speichern?', //sc_is_modified_save + 'WARNUNG', //sc_warningupper + 'FEHLER', //sc_errorupper + 'Exception', //sc_exception + 'System', //sc_system + 'existiert nicht', //sc_does_not_exist + 'PASSWORT', //sc_passwordupper + 'Ppassworteingabe', //sc_enterpassword + 'Ung'#0252'ltiges Passwort!',//sc_invalidpassword + 'Verzeichnis kann nicht gelesen werden', //sc_can_not_read_directory + 'Grafik Format nicht unterst'#0252'tzt', //sc_graphic_not_supported + 'Grafik Format Fehler', //sc_graphic_format_error + 'MS Bitmap', //sc_MS_Icon + 'MS Icon', //sc_MS_Icon + 'JPEG Bild', //sc_JPEG_Image + 'PNG Bild', //sc_PNG_Image + 'XPM Bild', //sc_XPM_Image + 'PNM Bild', //sc_PNM_Image + 'TARGA Bild', //sc_TARGA_image + 'TIFF Bild', //sc_TIFF_image + 'Alle', //sc_All + 'Best'#0228'tigung', //sc_Confirmation + 'Datensatz l'#0246'schen?', //sc_Delete_record_question + 'Datensatz kopieren?', //sc_Copy_record_question + 'Seite schliessen', //sc_close_page + 'Erster', //sc_first + 'Vorheriger', //sc_prior + 'N'#0228'chster', //sc_next + 'Letzter', //sc_last + 'Anf'#0252'gen', //sc_append + 'L'#0246'schen', //sc_delete + 'Bearbeiten', //sc_edit + 'Eintragen', //sc_post + 'Verwerfen', //sc_cancel + 'Auffrischen', //sc_refresh + 'Filter bearbeiten', //sc_filter_filter + 'Filter Minimum bearbeiten',//sc_edit_filter_min + 'Filter Maximum bearbeiten',//sc_filter_edit_max + 'Filter r'#0252'ckstellen', //sc_reset_filter + 'Filter ein', //sc_filter_on + 'Suchen', //sc_search + 'Automatisch bearbeiten', //sc_auto_edit + 'Datensatz kopieren', //sc_copy_record + 'Dialog', //sc_dialog + 'Einf'#0252'gen', //sc_insert + 'Kopieren', //sc_copy + 'Einf'#0252'gen', //sc_paste + 'Zeile einf'#0252'gen', //sc_row_insert + 'Zeile anf'#0252'gen', //sc_row_append + 'Zeile l'#0246'schen', //sc_row_delete + 'R'#0252'ckg'#0228'ngig', //sc_undo + 'Wiederherstellen', //sc_redo + 'Ausschneiden', //sc_cut + 'Alles markieren', //sc_select_all + 'Filter aus', //sc_filter_off + 'Hochformat', //sc_portrait print orientation + 'Querformat', //sc_landscape print orientation + 'Zeile l'#0246'schen?', //sc_Delete_row_question + 'gew'#0228'hlte Zeilen', //sc_selected_rows + 'Nur Einzeleintrag erlaubt', //sc_Single_item_only + 'Zellen kopieren', //sc_Copy_Cells + 'Zellen einf'#0252'gen', //sc_Paste_Cells + 'Schliessen', //sc_close + 'Maximieren', //sc_maximize + 'Normalisieren', //sc_normalize + 'Minimieren', //sc_minimize + 'Feste Gr'#0246'sse', //sc_fix_size + 'Lösen', //sc_float + 'Im Fordergrund', //sc_stay_on_top + 'Im Hintergrund', //sc_stay_in_background + 'Blockiere Unterfenster', //sc_lock_children + 'Kein Blockieren', //sc_no_lock + 'Eingabe', //sc_input + 'Schaltfeld', //sc_button + 'Ein', //sc_on + 'Aus', //sc_off + 'Linker Rand', //sc_leftborder + 'Oberer Rand', //sc_topborder + 'Rechter Rand', //sc_rightborder + 'Unterer Rand', //sc_bottomborder + 'Text start', //sc_beginoftext + 'Text ende', //sc_endoftext + 'Eingabe Modus', //sc_inputmode + #$00DC'berschreiben', //sc_overwrite + 'Gel'#$00F6'scht', //sc_deleted + 'Kopiert', //sc_copied + 'Eingef'#$00FC'gt', //sc_inserted + 'Eingef'#$00FC'gt', //sc_pasted + 'R'#$00FC'ckg'#$00E4'ngig', //sc_withdrawn + 'Fenster aktiviert', //sc_windowactivated + 'Men'#$00FC, //sc_menu + 'Datei Beginn', //sc_bof + 'Datei Ende', //sc_eof + 'Sprachausgabe', //sc_voiceoutput + 'Wiederhole Sprachausgabe', //sc_speakagain + 'Erste Spalte', //sc_firstcol + 'Erste Zeile', //sc_firstrow + 'Letzte Spalte', //sc_lastcol + 'Letzte Zeile', //sc_lastrow + 'Auswahl', //sc_selection + 'Spreche Pfad', //sc_speakpath + 'Deaktiviertes Schaltfeld', //sc_disabledbutton + 'Erstes Feld', //sc_firstfield + 'Letztes Feld', //sc_lastfield + 'Erstes Element', //sc_firstelement + 'Letztes Element', //sc_lastelement + 'Langsamer', //sc_slower + 'Schneller', //sc_faster + 'Fenster', //sc_window + 'Bereich', //sc_area + 'Bereich aktiviert', //sc_areaactivated + 'Leiser', //sc_volumedown + 'Lauter', //sc_volumeup + 'Ansage abbrechen' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= 'Gew'#0228'hlte Zeile l'#0246'schen?'; + end + else begin + result:= inttostrmse(vinteger)+ + widestring(' gew'#0228'hlte Zeilen l'#0246'schen?'); + end; + end; +end; + +const + de_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_de],@de_stockcaption,@de_modalresulttext, + @de_modalresulttextnoshortcut,@de_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_es.pas b/mseide-msegui/lib/common/kernel/mseconsts_es.pas new file mode 100644 index 0000000..7165ea1 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_es.pas @@ -0,0 +1,238 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + Spanish translation by Julio Jimenez Borreguero. + +} +unit mseconsts_es; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseconsts; + +implementation +uses + msetypes{msestrings},sysutils,mseformatstr; +const + es_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&Cancelar', //mr_cancel + '&Abortar', //mr_abort + '&OK', //mr_ok + '&S'#0237, //mr_yes + '&No', //mr_no + '&Todo', //mr_all + '&S'#0237' &todo', //mr_yesall + 'N&o todo', //mr_noall + '&Ignorar', //mr_ignore + 'O&mitir', //mr_skip + 'Omitir &todo', //mr_skipall + 'Co&ntinuar' //mr_continue + ); + + es_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + 'Cancelar', //mr_cancel + 'Abortar', //mr_abort + 'OK', //mr_ok + 'S'#0237, //mr_yes + 'No', //mr_no + 'Todo', //mr_all + 'S'#$00ED' todo', //mr_yesall + 'No todo', //mr_noall + 'Ignorar', //mr_ignore + 'Omitir', //mr_skip + 'Omitir todo', //mr_skipall + 'Continuar' //mr_continue + ); + + es_stockcaption: stockcaptionaty = ( + '', //sc_none + 'es inv'#0225'lido', //sc_is_invalid + 'Error de formato', //sc_Format_error + 'Debe introducir un valor', //sc_Value_is_required + 'Error', //sc_Error + 'M'#0237'n.', //sc_Min + 'M'#0225'x.', //sc_Max + 'Error de rango', //sc_Range_error + + '&Deshacer', //sc_Undohk /// /// + '&Rehacer', //sc_Redohk // // + '&Copiar', //sc_Copyhk // hotkeys // + 'C&ortar', //sc_Cuthk // // + '&Pegar', //sc_Pastehk // // hotkeys + '&Select all', //sc_Select_allhk /// // + '&Insertar fila', //sc_insert_rowhk /// // + '&A'#0241'adir fila', //sc_append_rowhk // hotkeys // + '&Borrar fila', //sc_delete_rowhk /// /// + + '&Carpetas', //sc_Dir /// + '&Principal', //sc_home // + '&Subir un nivel', //sc_Up // + 'Crear carpeta', //sc_New_dir // hotkeys + 'N&ombre', //sc_Name // + '&Mostrar archivos ocultos', //sc_Show_hidden_files // + '&Filtro', //sc_Filter /// + 'Guardar', //sc_save + 'Abrir', //sc_open + 'Nombre', //sc_name1 + 'Crear una carpeta nueva', //sc_create_new_directory + 'Atr'#0225's', //sc_back + 'Adelante', //sc_forward + 'Arriba', //sc_up + 'Archivo', //sc_file + 'existe, '#0191'quiere sobreescribirlo?', //sc_exists_overwrite + 'ha sido modificado. '#0191'Guardar?', //sc_is_modified_save + 'ADVERTENCIA', //sc_warningupper + 'ERROR', //sc_errorupper + 'Excepci'#0243'n', //sc_exception + 'Sistema', //sc_system + 'no existe', //sc_does_not_exist + 'CONTRASE'#0209'A', //sc_passwordupper + 'Introduzca contrase'#0241'a', //sc_enterpassword + #0161'contrase'#0241'a incorrecta!', //sc_invalidpassword + 'No puedo leer la carpeta', //sc_can_not_read_directory + 'Formato gr'#0225'fico no soportado', //sc_graphic_not_supported + 'Error de formato gr'#0225'fico', //sc_graphic_format_error + 'Bitmap MS', //sc_MS_Icon + 'Icono MS', //sc_MS_Icon + 'Imagen JPEG', //sc_JPEG_Image + 'Imagen PNG', //sc_PNG_Image + 'Imagen XPM', //sc_XPM_Image + 'Imagen PNM', //sc_PNM_Image + 'Imagen TARGA', //sc_TARGA_image + 'Imagen TIFF', //sc_TIFF_image + 'Todo', //sc_All + 'Confirme', //sc_Confirmation + #0191'Borrar el registro?', //sc_Delete_record_question + #0191'Copiar el registro?', //sc_Copy_record_question + 'Cerrar p'#0225'gina', //sc_close_page + 'Primero', //sc_first + 'Anterior', //sc_prior + 'Siguiente', //sc_next + #0218'ltimo', //sc_last + 'A'#0241'adir', //sc_append + 'Borrar', //sc_delete + 'Editar', //sc_edit + 'Guardar', //sc_post + 'Cancelar', //sc_cancel + 'Refrescar', //sc_refresh + 'Filtro edici'#0243'n', //sc_filter_filter + 'Filtro edici'#0243'n m'#0237'nimo', //sc_edit_filter_min + 'Filtro edici'#0243'n m'#0225'ximo', //sc_filter_edit_max + 'Reiniciar filtro', //sc_reset_filter + 'Filtro activo', //sc_filter_on + 'Buscar', //sc_search + 'Edici'#0243'n autom'#0225'tica', //sc_autoedit + 'Copiar registro', //sc_copy_record + 'Di'#0225'logo', //sc_dialog + 'Insertar', //sc_insert + 'Copiar', //sc_copy + 'Pegar', //sc_paste + 'Insertar fila', //sc_row_insert + 'A'#0241'adir fila', //sc_row_append + 'Borrar fila', //sc_row_delete + 'Deshacer', //sc_undo + 'Rehacer', //sc_redo + 'Cortar', //sc_cut + 'Seleccionar todo', //sc_select_all + 'Filtro apagado', //sc_filter_off + 'Vertical', //sc_portrait print orientation + 'Apaisado', //sc_landscape print orientation + #0191'Borrar fila?', //sc_Delete_row_question + 'filas seleccionadas?', //sc_selected_rows + 'un elemento solamente', //sc_Single_item_only + 'Copiar Celdas', //sc_Copy_Cells + 'Pegar Celdas', //sc_Paste_Cells + 'Cerrar', //sc_close + 'Maximizar', //sc_maximize + 'Restaurar', //sc_normalize + 'Minimizar', //sc_minimize + 'Ajustar tama'#0241'o', //sc_fix_size + 'Flotar', //sc_float + 'Permanecer en el primer plano', //sc_stay_on_top + 'Permanecer en el fondo', //sc_stay_in_background + 'Bloquear hijas', //sc_lock_children + 'Sin bloquear', //sc_no_lock + 'Entrada', //sc_input + 'Bot'#0243'n', //sc_button + 'Encendido', //sc_on + 'Apagado', //sc_off + 'Borde izquierdo', //sc_leftborder + 'Borde superior', //sc_topborder + 'Borde derecho', //sc_rightborder + 'Borde inferior', //sc_bottomborder + 'Principio del texto', //sc_beginoftext + 'Fin del texto', //sc_endoftext + 'Modo entrada', //sc_inputmode + 'Sobrescribir', //sc_overwrite + 'Borrado', //sc_deleted + 'Copiado', //sc_copied + 'Insertado', //sc_inserted + 'Pegado', //sc_pasted + 'Retirado', //sc_withdrawn + 'Ventana activada', //sc_windowactivated + 'Men'#0250, //sc_menu + 'Principio del archivo', //sc_bof + 'Fin del archivo', //sc_eof + 'Salida de voz', //sc_voiceoutput + 'Hablar de nuevo', //sc_speakagain + 'Primera columna', //sc_firstcol + 'Primera fila', //sc_firstrow + #0218'ltima columna', //sc_lastcol + #0218'ltima fila', //sc_lastrow + 'Selecci'#0243'n', //sc_selection + 'Ruta de hablar', //sc_speakpath + 'Deshabilitar bot'#0243'n', //sc_disabledbutton + 'Primer campo', //sc_firstfield + #$00DA'ltimo campo', //sc_lastfield + 'Primer elemento', //sc_firstelement + #$00DA'ltimo elemento', //sc_lastelement + 'M'#$00E1's lento', //sc_slower + 'M'#$00E1's r'#$00E1'pido', //sc_faster + 'Ventana', //sc_window + #$00C1'rea', //sc_area + #$00C1'rea activada', //sc_areaactivated + 'Bajar volumen', //sc_volumedown + 'Subir volumen', //sc_volumeup + 'Cancelar habla' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= #0191'Borrar la fila seleccionada?' + end + else begin + result:= #0191'Borrar '+inttostrmse(vinteger)+' filas seleccionadas?'; + end; + end; +end; + +const + es_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_es],@es_stockcaption,@es_modalresulttext, + @es_modalresulttextnoshortcut,@es_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_fr.pas b/mseide-msegui/lib/common/kernel/mseconsts_fr.pas new file mode 100644 index 0000000..169a67c --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_fr.pas @@ -0,0 +1,277 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + French translation by Fabrice Michel Bouillerot. + UTF-8 Accented french characters + + À A grave +  A circumflex + Ä A diaresis + Æ AE Aesh Ash + È E grave + Ë E diaresis + É E acute + Ê E circumflex + Ë E diaresis + Î I circumflex + Ï I diaresis + Ô O circumflex + Ö O diaresis + Ù U grave + Û U circumflex + Ü U diaresis + à a grave + â a circumflex + ä a diaresis + æ aesc ash + è e grave + é e acute + ê e circumflex + ë e diaresis + î i circumflex + ï i diaresis + ô o circumflex + ö o diaresis + ù u grave + û u circumflex + ü u diaresis + ÿ y diaresis + Œ OE ethel + œ oe ethel + Ÿ Y diaresis + + ’ apostrophe +} +unit mseconsts_fr; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseconsts; + +implementation +uses + msetypes{msestrings},sysutils,mseformatstr; +const + fr_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&Effacer', //mr_cancel + '&Arr'#0234'ter',//mr_abort + '&Valider', //mr_ok + '&Oui', //mr_yes + '&Non', //mr_no + '&Tout', //mr_all + 'Oui &tout', //mr_yesall + 'A&ucun', //mr_noall + '&Ignorer', //mr_ignore + '&Passer', //mr_skip + 'Passer &tout', //mr_skipall + 'Co&ntinuer' //mr_continue + ); + + fr_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + 'Effacer', //mr_cancel + 'Arr'#0234'ter',//mr_abort + 'Valider', //mr_ok + 'Oui', //mr_yes + 'Non', //mr_no + 'Tout', //mr_all + 'Oui tout', //mr_yesall + 'Aucun', //mr_noall + 'Ignorer', //mr_ignore + 'Passer', //mr_skip + 'Passer tout', //mr_skipall + 'Continuer' //mr_continue + ); + + fr_stockcaption: stockcaptionaty = ( + '', //sc_none + 'est invalide', //sc_is_invalid + 'Erreur de format', //sc_Format_error + 'Valeur requise', //sc_Value_is_required + 'Erreur', //sc_Error + 'Min.', //sc_Min + 'Max.', //sc_Max + 'Erreur de rang', //sc_Range_error + + '&D'#0233'faire', //sc_Undo /// /// + '&Refaire', //sc_Redo // // + '&Copier', //sc_Copy // hotkeys // + 'C&ouper', //sc_Cut // // + 'Co&ller', //sc_Paste // // hotkeys + '&S'#0233'lectionner tout', //sc_Select_allhk /// // + '&Ins'#0233'rer ligne', //sc_insert_row /// // + '&Ajouter ligne', //sc_append_row // hotkeys // + '&Supprimer ligne', //sc_delete_row /// /// + + 'R'#0233'&pertoire', //sc_Dir /// + '&Racine', //sc_home // + '&Remonter', //sc_Up // + '&Nouveau r'#0233'pertoire', //sc_New_dir // hotkeys + 'N&om', //sc_Name // + '&Afficher fichiers cach'#0233's', //sc_Show_hidden_files // + '&Filtre', //sc_Filter /// + 'Sauver', //sc_save + 'Ouvrir', //sc_open + 'Nom', //sc_name1 + 'Cr'#0233'er un nouveau r'#0233'pertoire',//sc_create_new_directory + 'Arri'#0232're', //sc_back + 'Avant', //sc_forward + 'Dessus', //sc_up + 'Fichier', //sc_file + 'existe, Remplacer ?', //sc_exists_overwrite + 'modifi'#0233'. Enregistrer ?', //sc_is_modified_save + 'AVERTISSEMENT', //sc_warningupper + 'ERREUR', //sc_errorupper + 'Exception', //sc_exception + 'Syst'#0232'me', //sc_system + 'n'#8217'existe pas', //sc_does_not_exist + 'MOT DE PASSE', //sc_passwordupper + 'Entrer le mot de passe', //sc_enterpassword + 'Mot de passe invalide!', //sc_invalidpassword + 'Impossible de lire le r'#0233'pertoire', //sc_can_not_read_directory + 'Format graphique non support'#0233'', //sc_graphic_not_supported + 'Erreur de format graphique', //sc_graphic_format_error + 'Bitmap MS', //sc_MS_Icon + 'Icone MS', //sc_MS_Icon + 'Image JPEG', //sc_JPEG_Image + 'Image PNG', //sc_PNG_Image + 'Image XPM', //sc_XPM_Image + 'Image PNM', //sc_PNM_Image + 'Image TARGA', //sc_TARGA_image + 'Image TIFF', //sc_TIFF_image + 'Tous', //sc_All + 'Confirmer', //sc_Confirmation + 'Effacer l'#8217'enregistrement ?', //sc_Delete_record_question + 'Copier l'#8217'enregistrement ?', //sc_Copy_record_question + 'Fermer page', //sc_close_page + 'Premier', //sc_first + 'Pr'#0233'c'#0233'dent', //sc_prior + 'Suivant', //sc_next + 'Dernier', //sc_last + 'Ajouter', //sc_append + 'Supprimer', //sc_delete + #0201'diter', //sc_edit + 'Poster', //sc_post + 'Effacer', //sc_cancel + 'Rafra'#0238'chir', //sc_refresh + #0201'dition Filtre', //sc_filter_filter + #0201'dition Filtre Minimum', //sc_edit_filter_min + #0201'dition Filtre Maximum', //sc_filter_edit_max + 'R'#0233'initialiser le filtre', //sc_reset_filter + 'Filtre actif', //sc_filter_on + 'Rechercher', //sc_search + #0201'dition automatique', //sc_autoedit + 'Copier l'#08217'enregistrement', //sc_copy_record + 'Dialogue', //sc_dialog + 'Ins'#0233'rer', //sc_insert + 'Copier', //sc_copy + 'Coller', //sc_paste + 'Ins'#0233'rer ligne', //sc_row_insert + 'Ajouter ligne', //sc_row_append + 'Supprimer ligne', //sc_row_delete + 'D'#0233'faire', //sc_undo + 'Refaire', //sc_redo + 'Couper', //sc_cut + 'S'#0233'lectionner tout', //sc_select_all + 'Filtre inactif', //sc_filter_off + 'Portrait', //sc_portrait print orientation + 'Paysage', //sc_landscape print orientation + 'Supprimer ligne ?', //sc_Delete_row_question + 'Lignes s'#0233'lectionn'#0233'es', //sc_selected_rows + 'seulement un '#0233'l'#0233'ment', //sc_Single_item_only + 'Copier cellules', //sc_Copy_Cells + 'Coller cellules', //sc_Paste_Cells + 'Fermer', //sc_close + 'Maximiser', //sc_maximize + 'Normaliser', //sc_normalize + 'Minimiser', //sc_minimize + 'Taille fixe', //sc_fix_size + 'Flottant', //sc_float + 'Rester en avant', //sc_stay_on_top + 'Rester en arri'#0232're', //sc_stay_in_background + 'Bloquer les descendants', //sc_lock_children + 'Ne pas bloquer', //sc_no_lock + 'Entr'#0233'e', //sc_input + 'Boutton', //sc_button + 'Allum'#0233'', //sc_on + #0201'teint', //sc_off + 'Bord gauche', //sc_leftborder + 'Bord haut', //sc_topborder + 'Bord droit', //sc_rightborder + 'Bord bas', //sc_bottomborder + 'D'#0233'but du texte', //sc_beginoftext + 'Fin du texte', //sc_endoftext + 'Mode entr'#0233'e', //sc_inputmode + #0201'craser', //sc_overwrite + 'D'#0233'truit', //sc_deleted + 'Copie'#0233, //sc_copied + 'Inser'#0233, //sc_inserted + 'Coll'#0233, //sc_pasted + 'Retir'#0233, //sc_withdrawn + 'Fen'#0232'tre activ'#0233'e', //sc_windowactivated + 'Menu', //sc_menu + 'D'#0233'but du fichier', //sc_bof + 'Fin du fichier', //sc_eof + 'Sortie voix', //sc_voiceoutput + 'R'#0233'p'#0233'ter', //sc_speakagain + 'Premi'#0232're colonne', //sc_firstcol + 'Premi'#0232're ligne', //sc_firstrow + 'D'#0232'rni'#0232're colonne', //sc_lastcol + 'D'#0232'rni'#0232're ligne', //sc_lastrow + 'S'#0233'lection', //sc_selection + 'Chemin de speak', //sc_speakpath + 'D'#0233'sactiver le boutton', //sc_disabledbutton + 'Premier champ', //sc_firstfield + 'D'#0232'rnier champ', //sc_lastfield + 'Premier '#0233'lement', //sc_firstelement + 'D'#0232'rnier '#0233'lement', //sc_lastelement + 'Plus lent', //sc_slower + 'Plus rapide', //sc_faster + 'Fen'#0232'tre', //sc_window + 'Aire', //sc_area + 'Aire activ'#0233'e', //sc_areaactivated + 'Volume moins', //sc_volumedown + 'Volume plus', //sc_volumeup + 'Annuler speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= 'Effacer le fichier s'#0233'lectionn'#0233' ?' + end + else begin + result:= 'Effacer les '+inttostrmse(vinteger)+ + ' fichiers s'#0233'lectionn'#0233's ?'; + end; + end; +end; + +const + fr_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_fr],@fr_stockcaption,@fr_modalresulttext, + @fr_modalresulttextnoshortcut,@fr_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_id.pas b/mseide-msegui/lib/common/kernel/mseconsts_id.pas new file mode 100644 index 0000000..0c433ec --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_id.pas @@ -0,0 +1,235 @@ +{ MSEgui Copyright (c) 1999-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + Indonesia translation by Wahono. + +} +unit mseconsts_id; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +implementation +uses + mseconsts,msetypes{msestrings},sysutils,mseformatstr; + +const + id_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&Batal', //mr_cancel + '&Gagalkan', //mr_abort + '&OK', //mr_ok + '&Ya', //mr_yes + '&Tidak', //mr_no + '&Semua', //mr_all + 'Yes &all', //mr_yesall + 'Tid&ak Semua', //mr_noall + '&Abaikan', //mr_ignore + '&Skip', //mr_skip + 'Skip &all', //mr_skipall + 'Co&ntinue' //mr_continue + ); + + id_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + 'Gagal', //mr_cancel + 'Batal', //mr_abort + 'OK', //mr_ok + 'Ya', //mr_yes + 'Tidak', //mr_no + 'Semua', //mr_all + 'Yes all', //mr_yesall + 'Tidak Semua', //mr_noall + 'Abaikan', //mr_ignore + 'Skip', //mr_skip + 'Skip all', //mr_skipall + 'Continue' //mr_continue + ); + + id_stockcaption: stockcaptionaty = ( + '', //sc_none + 'adalah salah', //sc_is_invalid + 'Format salah', //sc_Format_error + 'Nilai dibutuhkan', //sc_Value_is_required + 'Salah', //sc_Error + 'Min', //sc_Min + 'Max', //sc_Max + 'Range salah', //sc_Range_error + '&Batal', //sc_Undohk /// + '&Redo', //sc_Redohk // // + '&Salin', //sc_Copyhk // hotkeys + 'Po&tong', //sc_Cuthk // + '&Tempel', //sc_Pastehk // + '&Select all', //sc_Select_allhk /// // + '&Sisipkan Baris', //sc_insert_rowhk + '&Tambah Baris', //sc_append_rowhk + '&Hapus Baris', //sc_delete_rowhk + '&Direktori', //sc_Dirhk /// + '&Home', //sc_homehk // + '&Naik', //sc_Uphk // + 'Dir &Baru', //sc_New_dirhk // hotkeys + '&Nama File', //sc_Namehk // + '&File tersembunyi', //sc_Show_hidden_fileshk // + '&Filter', //sc_Filterhk /// + 'Simpan', //sc_save + 'Buka', //sc_open + 'Nama', //sc_name + 'Buat Direktori Baru', //sc_create_new_directory + 'Back', //sc_back + 'Forward', //sc_forward + 'Up', //sc_up + 'File', //sc_file + 'sudah ada, akan ditimpa?', //sc_exists_overwrite + 'is modified. Save?', //sc_is_modified_save + 'PERINGATAN', //sc_warningupper + 'SALAH', //sc_errorupper + 'Exception', //sc_exception + 'System', //sc_system + 'tidak ada', //sc_does_not_exist + 'PASSWORD', //sc_passwordupper + 'Enter password', //sc_enterpassword + 'Invalid password!', //sc_invalidpassword + 'tidak dapat membaca direktori', //sc_can_not_read_directory + 'Format grafik tidak didukung', //sc_graphic_not_supported + 'Format grafik salah', //sc_graphic_format_error + 'MS Bitmap', //sc_MS_Bitmap + 'MS Icon', //sc_MS_Icon + 'JPEG Image', //sc_JPEG_Image + 'PNG Image', //sc_PNG_Image + 'XPM Image', //sc_XPM_Image + 'PNM Image', //sc_PNM_Image + 'TARGA Image', //sc_TARGA_image + 'TIFF Image', //sc_TIFF_image + 'Semua', //sc_All + 'Konfirmasi', //sc_Confirmation + 'Hapus Rekaman?', //sc_Delete_record_question + 'Salin record?', //sc_Copy_record_question + 'Tutup', //sc_close_page + 'Awal', //sc_first + 'Sebelum', //sc_prior + 'Sesudah', //sc_next + 'Akhir', //sc_last + 'Tambah', //sc_append + 'Hapus', //sc_delete + 'Rubah', //sc_edit + 'Simpan', //sc_post + 'Batal', //sc_cancel + 'Refresh', //sc_refresh + 'Rubah filter', //sc_filter_filter + 'Rubah filter minimum', //sc_edit_filter_min + 'Rubah filter maximum', //sc_filter_edit_max + 'Reset filter', //sc_reset_filter + 'Filter hidup', //sc_filter_on + 'Cari', //sc_search + 'Rubah Otomatis', //sc_autoedit + 'Salin record', //sc_copy_record + 'Dialog', //sc_dialog + 'Sisipkan', //sc_insert + 'Salin', //sc_copy + 'Paste', //sc_paste + 'Row insert', //sc_row_insert + 'Row append', //sc_row_append + 'Row delete', //sc_row_delete + 'Undo', //sc_undo + 'Redo', //sc_redo + 'Cut', //sc_cut + 'Select all', //sc_select_all + 'Filter mati', //sc_filter_off + 'Berdiri', //sc_portrait print orientation + 'Rebah', //sc_landscape print orientation + 'Hapus baris?', //sc_Delete_row_question + 'baris yang terpilih?', //sc_selected_rows + 'Hanya satu item', //sc_Single_item_only, + 'Salin Cell', //sc_Copy_Cells + 'Tempel Cell', //sc_Paste_Cells + 'Close', //sc_close + 'Maximize', //sc_maximize + 'Normalize', //sc_normalize + 'Minimize', //sc_minimize + 'Fix size', //sc_fix_size + 'Float', //sc_float + 'Stay on top', //sc_stay_on_top + 'Stay in background', //sc_stay_in_background + 'Lock children', //sc_lock_children + 'No lock', //sc_no_lock + 'Input', //sc_input + 'Button', //sc_button + 'On', //sc_on + 'Off', //sc_off + 'Left border', //sc_leftborder + 'Top border', //sc_topborder + 'Right border', //sc_rightborder + 'Bottom border', //sc_bottomborder + 'Begin of text', //sc_beginoftext + 'End of text', //sc_endoftext + 'Inputmode', //sc_inputmode + 'Overwrite', //sc_overwrite + 'Deleted', //sc_deleted + 'Copied', //sc_copied + 'Inserted', //sc_inserted + 'Pasted', //sc_pasted + 'Withdrawn', //sc_withdrawn + 'Window activated', //sc_windowactivated + 'Menu', //sc_menu + 'Beginning of file', //sc_bof + 'End of file', //sc_eof + 'Voice output', //sc_voiceoutput + 'Speak again', //sc_speakagain + 'First column', //sc_firstcol + 'First row', //sc_firstrow + 'Last column', //sc_lastcol + 'Last row', //sc_lastrow + 'Selection', //sc_selection + 'Speak path', //sc_speakpath + 'Disabled button', //sc_disabledbutton + 'First field', //sc_firstfield + 'Last field', //sc_lastfield + 'First element', //sc_firstelement + 'Last element', //sc_lastelement + 'Slower', //sc_slower + 'Faster', //sc_faster + 'Window', //sc_window + 'Area', //sc_area + 'Area activated', //sc_areaactivated + 'Volume down', //sc_volumedown + 'Volume up', //sc_volumeup + 'Cancel speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= 'Delete selected row?' + end + else begin + result:= 'Delete '+inttostrmse(vinteger)+' selected rows?'; + end; + end; +end; + +const + id_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_id],@id_stockcaption,@id_modalresulttext, + @id_modalresulttextnoshortcut,@id_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_ru.pas b/mseide-msegui/lib/common/kernel/mseconsts_ru.pas new file mode 100644 index 0000000..d3be879 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_ru.pas @@ -0,0 +1,280 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + Russian translation by IvankoB and AlexL. + +} + +unit mseconsts_ru; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + mseconsts,msetypes{msestrings},sysutils,mseformatstr; + +const + ru_modalresulttext: defaultmodalresulttextty = ( + '', //mr_none => Nichego + '', //mr_canclose => + //Mozhno zakryt` + '', //mr_windowclosed => + //Okno zakryto + '', //mr_windowdestroyed => + //Okno udaleno + '', //mr_escape + '', //mr_f10 + '', //mr_exception => + //Neozhidannaya situatsiya + '&'#1054#1090#1084#1077#1085#1080#1090#1100 , //mr_cancel => &Otmenit` + '&'#1055#1088#1077#1088#1074#1072#1090#1100 , //mr_abort => &Prervat` + '&'#1043#1086#1090#1086#1074#1086 , //mr_ok => &Gotovo + '&'#1044#1072 , //mr_yes => &Da + '&'#1053#1077#1090 , //mr_no => &Net + '&'#1042#1089#1077 , //mr_all => &Vse + 'Yes &all', //mr_yesall + #1053'&'#1080#1082#1072#1082#1080#1077 , //mr_noall => N&ikakie + #1053#1077#1074#1072'&'#1078#1085#1086, //mr_ignore => Neva&zhno + '&Skip', //mr_skip + 'Skip &all', //mr_skipall + 'Co&ntinue' //mr_continue +); + + ru_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + #1053#1077#1086#1078#1080#1076#1072#1085#1085#1072#1103' ' + + #1089#1080#1090#1091#1072#1094#1080#1103 , //mr_exception + #1054#1090#1084#1077#1085#1080#1090#1100 , //mr_cancel => Otmenit` + #1055#1088#1077#1088#1074#1072#1090#1100 , //mr_abort => Prervat` + #1043#1086#1090#1086#1074#1086 , //mr_ok => Gotovo + #1044#1072 , //mr_yes => Da + #1053#1077#1090 , //mr_no => Net + #1042#1089#1077 , //mr_all => Vse + 'Yes all', //mr_yesall + #1053#1080#1082#1072#1082#1080#1077 , //mr_noall => Nikakie + #1053#1077#1074#1072#1078#1085#1086, //mr_ignore => Nevazhno + 'Skip', //mr_skip + 'Skip all', //mr_skipall + 'Continue' //mr_continue + ); + + ru_stockcaption: stockcaptionaty = ( + '', //sc_none + '- '#1085#1077#1074#1077#1088#1085#1086 , //sc_is_invalid => - neverno + #1053#1077#1089#1086#1086#1090#1074#1077#1090#1089#1090#1074#1080#1077' '+ + #1092#1086#1088#1084#1072#1090#1091 , //sc_Format_error => + //Nesootvetstvie formatu + #1058#1088#1077#1073#1091#1077#1090#1089#1103' '+ + #1079#1085#1072#1095#1077#1085#1080#1077 , //sc_Value_is_required => + //Trebuetsya znachenie + #1054#1096#1080#1073#1082#1072 , //sc_Error => Oshibka + #1052#1080#1085'.' , //sc_Min => Min. + #1052#1072#1082#1089'.' , //sc_Max => Maks. + #1053#1077#1089#1086#1086#1090#1074#1077#1090#1089#1090#1074#1080#1077' '+ + #1076#1080#1072#1087#1072#1079#1086#1085#1091 , + //sc_Range_error => + //Nesootvetstvie diapazonu + + // hotkeys/// + #1042#1077#1088#1085#1091#1090#1100 , //sc_Undohk => Vernut` + 'П#1086#1074#1090#1086#1088', //sc_Redohk => Povtor// // + #1057#1082#1086#1087#1080#1088#1086#1074#1072#1090#1100 , + //sc_Copyhk => Skopirovat` + #1042#1099#1088#1077#1079#1072#1090#1100 , //sc_Cuthk => Vyrezat` + #1042#1089#1090#1072#1074#1080#1090#1100 , ///sc_Pastehk => Vstavit` + '&Select all', //sc_Select_allhk /// // + '&'#1042#1089#1090#1072#1074#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_insert_rowhk => Vstavit' stroku /// // + '&'#1044#1086#1073#1072#1074#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_append_rowhk => Dobavit' stroku // hotkeys // + '&'#1059#1076#1072#1083#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_delete_rowhk => Udalit' stroku/// /// + + // hotkeys/// + '&'#1050#1072#1090#1072#1083#1086#1075 , //sc_Dirhk => Katalog + '&'#1044#1086#1084'.', //sc_homehk => Dom. // + '&'#1042#1074#1077#1088#1093 , //sc_Uphk => Vverh + '&'#1053#1086#1074'. '#1082#1072#1090'-'#1075 , //sc_New_dirhk => Nov. kat-g + #1053#1072'&'#1079#1074#1072#1085#1080#1077 , //sc_Namehk => Nazvanie + + #1055#1086#1082#1072#1079'. &'#1089#1082#1088#1099#1090'. '+ + #1092#1072#1081#1083#1099 , //sc_Show_hidden_fileshk => + //Pokaz. skryt. faily + '&'#1060#1080#1083#1100#1090#1088 , ///sc_Filterhk => Fil`tr + + #1057#1086#1093#1088#1072#1085#1080#1090#1100 , //sc_save => Sohranit` + #1054#1090#1082#1088#1099#1090#1100 , //sc_open => Otkryt` + #1048#1084#1103, //sc_name + #1057#1086#1079#1076#1072#1090#1100' '#1085#1086#1074#1099#1081' '+ + #1082#1072#1090#1072#1083#1086#1075 , //sc_create_new_directory + 'Back', //sc_back + 'Forward', //sc_forward + 'Up', //sc_up + #1060#1072#1081#1083 , //sc_file + #1091#1078#1077' '#1077#1089#1090#1100', '+ + #1087#1077#1088#1077#1079#1072#1087#1080#1089#1072#1090#1100'?' , + //sc_exists_overwrite + #1073#1099#1083' '#1080#1079#1084#1077#1085#1105#1085'. '#1057#1086#1093#1088#1072#1085#1080#1090#1100'?', //sc_is_modified_save + #1055#1056#1045#1044#1059#1055#1056#1045#1046#1044#1045#1053#1048#1045 , + //sc_warningupper + #1054#1064#1048#1041#1050#1040 , //sc_errorupper + #1048#1089#1082#1083#1102#1095#1077#1085#1080#1077, //sc_exception + #1057#1080#1089#1090#1077#1084#1072, //sc_system + #1085#1077' '#1089#1091#1097#1077#1089#1090#1074#1091#1077#1090 , + //sc_does_not_exist + #1055#1072#1088#1086#1083#1100, //sc_passwordupper + #1042#1074#1077#1076#1080#1090#1077' '#1087#1072#1088#1086#1083#1100, //sc_enterpassword + #1053#1077#1074#1077#1088#1085#1099#1081' '#1087#1072#1088#1086#1083#1100'!', //sc_invalidpassword + #1053#1077' '#1091#1076#1072#1077#1090#1089#1103' '+ + #1087#1088#1086#1095#1077#1089#1090#1100' '+ + #1089#1086#1076#1077#1088#1078#1080#1084#1086#1077+ + ' '#1082#1072#1090#1072#1083#1086#1075#1072 , //sc_can_not_read_directory + #1043#1088#1072#1092#1080#1095#1077#1089#1082#1080#1081' '+ + #1092#1086#1088#1084#1072#1090' '#1085#1077' '+ + #1087#1086#1076#1076#1077#1088#1078#1080#1074#1072#1077#1090#1089#1103 , + //sc_graphic_not_supported + #1043#1088#1072#1092#1080#1095#1077#1089#1082#1080#1077' '+ + #1076#1072#1085#1085#1099#1077' '#1085#1077' '+ + #1089#1086#1086#1090#1074#1077#1090#1089#1090#1074#1091#1102#1090' '+ + #1092#1086#1088#1084#1072#1090#1091 , //sc_graphic_format_error + 'BMP-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_MS_Bitmap + 'ICO-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_MS_Icon + 'JPEG-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_JPEG_Image + 'PNG-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_PNG_Image + 'XPM-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_XPM_Image + 'PNM-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_PNM_Image + 'TARGA-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_TARGA_image + 'TIFF-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_TIFF_image + #1042#1089#1077 , //sc_All + #1055#1086#1076#1090#1074#1077#1088#1078#1076#1077#1085#1080#1077 , + //sc_Confirmation + #1059#1076#1072#1083#1080#1090#1100' '#1079#1072#1087#1080#1089#1100'?', + //sc_Delete_record_question + #1047#1072#1082#1088#1099#1090#1100#32#1089#1090#1088#1072#1085#1080#1094#1091, //sc_close_page + #1057#1085#1072#1095#1072#1083#1072, //sc_first + #1055#1088#1080#1086#1088, //sc_prior + #1044#1072#1083#1077#1077, //sc_next + #1053#1072#1079#1072#1076, //sc_last + #1044#1086#1073#1072#1074#1080#1090#1100, //sc_append + #1059#1076#1072#1083#1080#1090#1100, //sc_delete + #1055#1088#1072#1074#1080#1090#1100, //sc_edit + #1055#1086#1089#1083#1077, //sc_post + #1054#1090#1084#1077#1085#1072, //sc_cancel + #1054#1073#1085#1086#1074#1080#1090#1100, //sc_refresh + #1048#1079#1084#1077#1085#1080#1090#1100' '#1092#1080#1083#1100#1090#1088, //sc_filter_filter + #1048#1079#1084#1077#1085#1080#1090#1100' '#1084#1080#1085'. '#1092#1080#1083#1100#1090#1088 ,//sc_edit_filter_min + #1048#1079#1084#1077#1085#1080#1090#1100' '#1084#1072#1082#1089'. '#1092#1080#1083#1100#1090#1088, //sc_filter_edit_max + 'Reset filter', //sc_reset_filter + #1042#1082#1083'. '#1092#1080#1083#1100#1090#1088, //sc_filter_on + #1055#1086#1080#1089#1082, //sc_search + #1040#1074#1090#1086#1084#1072#1090'. '#1087#1088#1072#1074#1082#1072, //sc_autoedit + #1050#1086#1087#1080#1088#1086#1074#1072#1090#1100' '#1079#1072#1087#1080#1089#1100, //sc_copy_record + #1050#1086#1087#1080#1088#1086#1074#1072#1090#1100' '#1079#1072#1087#1080#1089#1100'?', //sc_Copy_record_question + #1044#1080#1072#1083#1086#1075, //sc_dialog + #1042#1089#1090#1072#1074#1080#1090#1100, //sc_insert + #1050#1086#1087#1080#1088#1086#1074#1072#1090#1100, //sc_copy + #1042#1089#1090#1072#1074#1080#1090#1100, //sc_paste + #1042#1089#1090#1072#1074#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_row_insert + #1044#1086#1073#1072#1074#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_row_append + #1059#1076#1072#1083#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_row_delete + #1054#1090#1084#1077#1085#1080#1090#1100, //sc_undo + #1055#1086#1074#1090#1086#1088#1080#1090#1100, //sc_redo + #1042#1099#1088#1077#1079#1072#1090#1100, //sc_cut + #1042#1099#1076#1077#1083#1080#1090#1100' '#1074#1089#1105, //sc_select_all + #1054#1090#1082#1083'. '#1092#1080#1083#1100#1090#1088, //sc_filter_off + #1040#1083#1100#1073#1086#1084#1085#1072#1103, //sc_portrait print orientation + #1050#1085#1080#1078#1085#1072#1103, //sc_landscape print orientation + #1059#1076#1072#1083#1080#1090#1100' '#1089#1090#1088#1086#1082#1091'?', //sc_Delete_row_question + #1074#1099#1073#1088#1072#1085#1085#1099#1077' '#1089#1090#1088#1086#1082#1080'?', //sc_selected_rows + #1058#1086#1083#1100#1082#1086' '#1087#1088#1086#1089#1090#1086#1081' '#1087#1091#1085#1082#1090, //sc_Single_item_only + #1050#1086#1087#1080#1088#1086#1074#1072#1090#1100' '#1103#1095#1077#1081#1082#1080, //sc_Copy_Cells + #1042#1089#1090#1072#1074#1080#1090#1100' '#1103#1095#1077#1081#1082#1080, //sc_Paste_Cells + 'Close', //sc_close + 'Maximize', //sc_maximize + 'Normalize', //sc_normalize + 'Minimize', //sc_minimize + 'Fix size', //sc_fix_size + 'Float', //sc_float + 'Stay on top', //sc_stay_on_top + 'Stay in background', //sc_stay_in_background + 'Lock children', //sc_lock_children + 'No lock', //sc_no_lock + 'Input', //sc_input + 'Button', //sc_button + 'On', //sc_on + 'Off', //sc_off + 'Left border', //sc_leftborder + 'Top border', //sc_topborder + 'Right border', //sc_rightborder + 'Bottom border', //sc_bottomborder + 'Begin of text', //sc_beginoftext + 'End of text', //sc_endoftext + 'Inputmode', //sc_inputmode + 'Overwrite', //sc_overwrite + 'Deleted', //sc_deleted + 'Copied', //sc_copied + 'Inserted', //sc_inserted + 'Pasted', //sc_pasted + 'Withdrawn', //sc_withdrawn + 'Window activated', //sc_windowactivated + 'Menu', //sc_menu + 'Beginning of file', //sc_bof + 'End of file', //sc_eof + 'Voice output', //sc_voiceoutput + 'Speak again', //sc_speakagain + 'First column', //sc_firstcol + 'First row', //sc_firstrow + 'Last column', //sc_lastcol + 'Last row', //sc_lastrow + 'Selection', //sc_selection + 'Speak path', //sc_speakpath + 'Disabled button', //sc_disabledbutton + 'First field', //sc_firstfield + 'Last field', //sc_lastfield + 'First element', //sc_firstelement + 'Last element', //sc_lastelement + 'Slower', //sc_slower + 'Faster', //sc_faster + 'Window', //sc_window + 'Area', //sc_area + 'Area activated', //sc_areaactivated + 'Volume down', //sc_volumedown + 'Volume up', //sc_volumeup + 'Cancel speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= #1059#1076#1072#1083#1080#1090#1100' '#1074#1099#1073#1088#1072#1085#1085#1091#1102' '#1089#1090#1088#1086#1082#1091'?' + end + else begin + result:= #1059#1076#1072#1083#1080#1090#1100' '+inttostrmse(vinteger)+' '#1074#1099#1073#1088#1072#1085#1085#1091#1102' '#1089#1090#1088#1086#1082#1091'?'; + end; + end; +end; + +const + ru_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_ru],@ru_stockcaption,@ru_modalresulttext, + @ru_modalresulttextnoshortcut,@ru_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_uzcyr.pas b/mseide-msegui/lib/common/kernel/mseconsts_uzcyr.pas new file mode 100644 index 0000000..ec3841c --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_uzcyr.pas @@ -0,0 +1,243 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + Uzbek-Cyrillic translation by IvankoB. + +} + + +unit mseconsts_uzcyr; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseconsts; + +implementation +uses + msetypes{msestrings},sysutils,mseformatstr; +const + uzcyr_modalresulttext: defaultmodalresulttextty = ( + '', //mr_none => Nichego + '', //mr_canclose => Mozhno zakryt` + '', //mr_windowclosed => Okno zakryto + '', //mr_windowdestroyed => Okno udaleno + '', //mr_escape + '', //mr_f10 + #1061#1072#1090#1086 , //mr_exception => Neozhidannaya situatsiya + '&'#1041#1077#1082#1086#1088' '#1179#1080#1083#1080#1096 , //mr_cancel => &Otmenit` + '&'#1059#1079#1080#1073' '#1179#1118#1081#1080#1096 , //mr_abort => &Prervat` + '&'#1058#1072#1081#1105#1088 , //mr_ok => &Gotovo + '&'#1202#1072 , //mr_yes => &Da + '&'#1049#1118#1082 , //mr_no => &Net + #1041#1072'&'#1088#1095#1072 , //mr_all => &Vse + 'Yes &all', //mr_yesall + #1202#1077'&'#1095' '#1073#1080#1088#1080 , //mr_noall => N&ikakie + '&'#1052#1072#1085' '#1101#1090#1080#1096, //mr_ignore => Neva&zhno + '&Skip', //mr_skip + 'Skip &all', //mr_skipall + 'Co&ntinue' //mr_continue + ); + + uzcyr_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + #1061#1072#1090#1086 , //mr_exception + #1041#1077#1082#1086#1088' '#1179#1080#1083#1080#1096 , //mr_cancel => Otmenit` + #1059#1079#1080#1073' '#1179#1118#1081#1080#1096 , //mr_abort => Prervat` + #1058#1072#1081#1105#1088 , //mr_ok => Gotovo + #1202#1072 , //mr_yes => Da + #1049#1118#1082 , //mr_no => Net + #1041#1072#1088#1095#1072 , //mr_all => Vse + 'Yes all', //mr_yesall + #1202#1077#1095' '#1073#1080#1088#1080 , //mr_noall => Nikakie + #1052#1072#1085' '#1101#1090#1080#1096, //mr_ignore => Nevazhno + 'Skip', //mr_skip + 'Skip all', //mr_skipall + 'Continue' //mr_continue + ); + + uzcyr_stockcaption: stockcaptionaty = ( + '', //sc_none + '- '#1085#1086#1072#1085#1080#1179 , //sc_is_invalid => - neverno + #1060#1086#1088#1084#1072#1090' '#1085#1086#1090#1118#1171#1088#1080 , + //sc_Format_error => Nesootvetstvie formatu + #1202#1077#1095' '#1085#1072#1088#1089#1072' '#1082#1077#1088#1072#1082' '#1101#1084#1072#1089 , + //sc_Value_is_required => Trebuetsya znachenie + #1053#1086#1090#1118#1171#1088#1080 , //sc_Error => Oshibka + #1052#1080#1085'.' , //sc_Min => Min. + #1052#1072#1082#1089'.' , //sc_Max => Maks. + #1053#1086#1090#1118#1171#1088#1080' '#1076#1080#1072#1087#1072#1079#1086#1085 , + //sc_Range_error => Nesootvetstvie diapazonu + + #1054#1083#1076#1080#1085#1075#1080 , //sc_Undohk => Vernut` + '&Redo', //sc_Redohk // // + #1050#1118#1095#1080#1088#1080#1096 , //sc_Copyhk // hotkeys=> Skopirovat` + #1054#1083#1080#1073' '#1090#1072#1096#1083#1072#1096 , //sc_Cuthk => Vyrezat` + #1025#1079#1080#1073' '#1179#1118#1081#1080#1096 , //sc_Pastehk => Vstavit` + '&Select all', //sc_Select_allhk /// // + '&Insert Row', //sc_insert_rowhk /// // + '&Append Row', //sc_append_rowhk // hotkeys // + '&Delete Row', //sc_delete_rowhk /// /// + + #1050#1072#1090#1072#1083#1086#1075 , //sc_Dirhk => Katalog + '&Home', //sc_homehk // + #1058#1077#1087#1087#1072#1075#1072 , //sc_Up => Vverh + #1071#1085#1075#1080' '#1082#1072#1090'.' , //sc_New_dir => Nov. kat-g + #1053#1086#1084#1080 , ///sc_Name => Nazvanie + #1041#1077#1088#1080#1090#1080#1083#1075#1072#1085' '#1092#1072#1081#1083#1072#1088#1085#1080' '#1179#1091#1088#1089#1072#1090#1080#1096 , //sc_Show_hidden_files => Pokaz. skryt. faily + #1060#1080#1083#1100#1090#1088 , //sc_Filter => Fil`tr + #1057#1072#1082#1083#1072#1096 , //sc_save => Sohranit` + #1054#1095#1080#1096 , //sc_open => Otkryt` + 'Name', //sc_name + 'Create new directory',//sc_create_new_directory + 'Back', //sc_back + 'Forward', //sc_forward + 'Up', //sc_up + 'File', //sc_file + 'exists, do you want to overwrite?', //sc_exists_overwrite + 'is modified. Save?', //sc_is_modified_save + 'WARNING', //sc_warningupper + 'ERROR', //sc_errorupper + 'Exception', //sc_exception + 'System', //sc_system + 'does not exist', //sc_does_not_exist + 'PASSWORD', //sc_passwordupper + 'Enter password', //sc_enterpassword + 'Invalid password!', //sc_invalidpassword + 'Can not read directory', //sc_can_not_read_directory + #1043#1088#1072#1092#1080#1082' '#1092#1086#1088#1084#1072#1090' '#1090#1072#1098#1084#1080#1085#1083#1072#1085#1084#1072#1075#1072#1085 , //sc_graphic_not_supported + #1053#1086#1090#1118#1171#1088#1080' '#1075#1088#1072#1092#1080#1082' '#1092#1086#1088#1084#1072#1090#1080 , //sc_graphic_format_error + 'BMP-'#1088#1072#1089#1084#1080 , //sc_MS_Bitmap + 'ICO-'#1088#1072#1089#1084#1080 , //sc_MS_Icon + 'JPEG-'#1088#1072#1089#1084#1080 , //sc_JPEG_Image + 'PNG-'#1088#1072#1089#1084#1080 , //sc_PNG_Image + 'XPM-'#1088#1072#1089#1084#1080 , //sc_XPM_Image + 'PNM-'#1088#1072#1089#1084#1080 , //sc_PNM_Image + 'TARGA-'#1088#1072#1089#1084#1080 , //sc_TARGA_image + 'TIFF-'#1088#1072#1089#1084#1080 , //sc_TIFF_image + #1041#1072#1088#1095#1072 , //sc_All + #1058#1072#1089#1076#1080#1179#1083#1072#1096 , //sc_Confirmation + #1025#1079#1091#1074#1085#1080' '#1118#1095#1080#1088#1080#1096, //sc_Delete_record_question + 'Copy record?', //sc_Copy_record_question + 'Close page', //sc_close_page + 'First', //sc_first + 'Prior', //sc_prior + 'Next', //sc_next + 'Last', //sc_last + 'Append', //sc_append + 'Delete', //sc_delete + 'Edit', //sc_edit + 'Post', //sc_post + 'Cancel', //sc_cancel + 'Refresh', //sc_refresh + 'Edit filter', //sc_filter_filter + 'Edit filter minimum',//sc_edit_filter_min + 'Edit filter maximum',//sc_filter_edit_max + 'Reset filter', //sc_reset_filter + 'Filter on', //sc_filter_on + 'Search', //sc_search + 'Auto edit', //sc_autoedit + 'Copy record', //sc_copy_record + 'Dialog', //sc_dialog + 'Insert', //sc_insert + 'Copy', //sc_copy + 'Paste', //sc_paste + 'Row insert', //sc_row_insert + 'Row append', //sc_row_append + 'Row delete', //sc_row_delete + 'Undo', //sc_undo + 'Redo', //sc_redo + 'Cut', //sc_cut + 'Select all', //sc_select_all + 'Filter off', //sc_filter_off + 'Portrait', //sc_portrait print orientation + 'Landscape', //sc_landscape print orientation + 'Delete row?', //sc_Delete_row_question + 'selected rows?', //sc_selected_rows + 'Single item only', //sc_Single_item_only + 'Copy Cells', //sc_Copy_Cells + 'Paste Cells', //sc_Paste_Cells + 'Close', //sc_close + 'Maximize', //sc_maximize + 'Normalize', //sc_normalize + 'Minimize', //sc_minimize + 'Fix size', //sc_fix_size + 'Float', //sc_float + 'Stay on top', //sc_stay_on_top + 'Stay in background', //sc_stay_in_background + 'Lock children', //sc_lock_children + 'No lock', //sc_no_lock + 'Input', //sc_input + 'Button', //sc_button + 'On', //sc_on + 'Off', //sc_off + 'Left border', //sc_leftborder + 'Top border', //sc_topborder + 'Right border', //sc_rightborder + 'Bottom border', //sc_bottomborder + 'Begin of text', //sc_beginoftext + 'End of text', //sc_endoftext + 'Inputmode', //sc_inputmode + 'Overwrite', //sc_overwrite + 'Deleted', //sc_deleted + 'Copied', //sc_copied + 'Inserted', //sc_inserted + 'Pasted', //sc_pasted + 'Withdrawn', //sc_withdrawn + 'Window activated', //sc_windowactivated + 'Menu', //sc_menu + 'Beginning of file', //sc_bof + 'End of file', //sc_eof + 'Voice output', //sc_voiceoutput + 'Speak again', //sc_speakagain + 'First column', //sc_firstcol + 'First row', //sc_firstrow + 'Last column', //sc_lastcol + 'Last row', //sc_lastrow + 'Selection', //sc_selection + 'Speak path', //sc_speakpath + 'Disabled button', //sc_disabledbutton + 'First field', //sc_firstfield + 'Last field', //sc_lastfield + 'First element', //sc_firstelement + 'Last element', //sc_lastelement + 'Slower', //sc_slower + 'Faster', //sc_faster + 'Window', //sc_window + 'Area', //sc_area + 'Area activated', //sc_areaactivated + 'Volume down', //sc_volumedown + 'Volume up', //sc_volumeup + 'Cancel speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= 'Delete selected row?' + end + else begin + result:= 'Delete '+inttostrmse(vinteger)+' selected rows?'; + end; + end; +end; + +const + uzcyr_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_uzcyr],@uzcyr_stockcaption,@uzcyr_modalresulttext, + @uzcyr_modalresulttextnoshortcut,@uzcyr_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_zh.pas b/mseide-msegui/lib/common/kernel/mseconsts_zh.pas new file mode 100644 index 0000000..1be2d21 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_zh.pas @@ -0,0 +1,242 @@ +{ MSEgui Copyright (c) 1999-2009 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + Chinese translation by liuzg2. + +} +unit mseconsts_zh; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseconsts; + +implementation +uses + msetypes{msestrings},sysutils,mseformatstr; +const + zh_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&C'#31163#24320, //mr_cancel + '&A'#21462#28040, //mr_abort + '&O'#30830#23450, //mr_ok + '&Y'#26159, //mr_yes + '&N'#21542, //mr_no + '&l'#25152#26377, //mr_all + 'Yes &all', //mr_yesall + #21462#28040#25152#26377, //mr_noall + '&g'#24573#30053, //mr_ignore + '&Skip', //mr_skip + 'Skip &all', //mr_skipall + 'Co&ntinue' //mr_continue + ); + + zh_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_esc + '', //mr_f10 + '', //mr_exception + #31163#24320, //mr_cancel + #21462#28040, //mr_abort + #30830#23450, //mr_ok + #26159, //mr_yes + #21542, //mr_no + #25152#26377, //mr_all + 'Yes all', //mr_yesall + #21462#28040#25152#26377, //mr_noall + #24573#30053, //mr_ignore + 'Skip', //mr_skip + 'Skip all', //mr_skipall + 'Continue' //mr_continue + ); + + zh_stockcaption: stockcaptionaty = ( + '', //sc_none + #26080#25928, //sc_is_invalid + #26684#24335#38169#35823, //sc_Format_error + #20540#19981#33021#20026#31354, //sc_Value_is_required + #38169#35823, //sc_Error + #26368#23567, //sc_Min + #26368#22823, //sc_Max + #28322#20986#38169#35823, //sc_Range_error + + '&u'#21462#28040, //sc_Undohk /// /// + '&Redo', //sc_Redohk // // + '&c'#22797#21046, //sc_Copyhk // hotkeys // + '&t'#21098#20999, //sc_Cuthk // // + '&p'#31896#36148, //sc_Pastehk // // hotkeys + '&Select all', //sc_Select_allhk /// // + '&I'#25554#20837#19968#34892, //sc_insert_rowhk /// // + '&A'#22686#21152#19968#34892, //sc_append_rowhk // hotkeys // + '&D'#21024#38500#25152#36873#34892, //sc_delete_rowhk /// /// + + '&D'#25991#20214#22841, //sc_Dirhk /// + '&Home', //sc_homehk // + '&U'#21521#19978, //sc_Uphk // + '&N'#26032#25991#20214#22841, //sc_New_dirhk // hotkeys + '&N'#25991#20214#21517, //sc_Namehk // + '&S'#26174#31034#38544#34255#25991#20214, //sc_Show_hidden_fileshk // + '&F'#20445#23384#31867#22411, //sc_Filterhk /// + #20445#23384, //sc_save + 'O'#25171#24320, //sc_open + #21517#31216, //sc_name + #26032#24314#25991#20214#22841, //sc_create_new_directory + 'Back', //sc_back + 'Forward', //sc_forward + 'Up', //sc_up + #25991#20214, //sc_file + #25991#20214#24050#32463#23384#22312#65292#26159#21542#35206#30422#65311, //sc_exists_overwrite + 'is modified. Save?', //sc_is_modified_save + + #35686#21578, //sc_warningupper + #38169#35823, //sc_errorupper + 'Exception', //sc_exception + 'System', //sc_system + #19981#23384#22312, //sc_does_not_exist + 'PASSWORD', //sc_passwordupper + 'Enter password', //sc_enterpassword + 'Invalid password!', //sc_invalidpassword + #25214#19981#21040#25991#20214#22841, //sc_can_not_read_directory + #22270#24418#26684#24335#19981#25903#25345,//sc_graphic_not_supported + #22270#24418#26684#24335#38169#35823, //sc_graphic_format_error + 'MS Bitmap', //sc_MS_Bitmap + 'MS Icon', //sc_MS_Icon + 'JPEG Image', //sc_JPEG_Image + 'PNG Image', //sc_PNG_Image + 'XPM Image', //sc_XPM_Image + 'PNM Image', //sc_PNM_Image + 'TARGA Image', //sc_TARGA_image + 'TIFF Image', //sc_TIFF_image + #25152#26377, //sc_All + #35777#26126, //sc_Confirmation + #21024#38500#35760#24405#65311, //sc_Delete_record_question + 'Copy record?', //sc_Copy_record_question + #20851#38381#39029, //sc_close_page + #31532#19968#26465, //sc_first + #21069#19968#26465, //sc_prior + #19979#19968#26465, //sc_next + #26368#21518, //sc_last + #22686#21152, //sc_append + #21024#38500, //sc_delete + #20462#25913, //sc_edit + #20445#23384, //sc_post + #31163#24320, //sc_cancel + #21047#26032, //sc_refresh + #32534#36753#22120#36807#28388, //sc_filter_filter + 'Edit filter minimum', //sc_edit_filter_min + 'Edit filter maximum', //sc_filter_edit_max + 'Reset filter', //sc_reset_filter + #36807#28388#24320#21551, //sc_filter_on + #26597#25214, //sc_search + 'Auto edit', //sc_autoedit + 'Copy record', //sc_copy_record + 'Dialog', //sc_dialog + #25554#20837, //sc_insert + 'Copy', //sc_copy + 'Paste', //sc_paste + 'Row insert', //sc_row_insert + 'Row append', //sc_row_append + 'Row delete', //sc_row_delete + 'Undo', //sc_undo + 'Redo', //sc_redo + 'Cut', //sc_cut + 'Select all', //sc_select_all + #36807#28388#20851#38381, //sc_filter_off + 'Portrait', //sc_portrait print orientation + 'Landscape', //sc_landscape print orientation + #30830#23450#21024#38500#27492#26465#35760#24405#21527#65311, + //sc_Delete_row_question + #30830#23450#21024#38500#25152#36873#35760#24405#21527#65311, + //sc_selected_rows + 'Single item only', //sc_Single_item_only + 'Copy Cells', //sc_Copy_Cells + 'Paste Cells', //sc_Paste_Cells + 'Close', //sc_close + 'Maximize', //sc_maximize + 'Normalize', //sc_normalize + 'Minimize', //sc_minimize + 'Fix size', //sc_fix_size + 'Float', //sc_float + 'Stay on top', //sc_stay_on_top + 'Stay in background', //sc_stay_in_background + 'Lock children', //sc_lock_children + 'No lock', //sc_no_lock + 'Input', //sc_input + 'Button', //sc_button + 'On', //sc_on + 'Off', //sc_off + 'Left border', //sc_leftborder + 'Top border', //sc_topborder + 'Right border', //sc_rightborder + 'Bottom border', //sc_bottomborder + 'Begin of text', //sc_beginoftext + 'End of text', //sc_endoftext + 'Inputmode', //sc_inputmode + 'Overwrite', //sc_overwrite + 'Deleted', //sc_deleted + 'Copied', //sc_copied + 'Inserted', //sc_inserted + 'Pasted', //sc_pasted + 'Withdrawn', //sc_withdrawn + 'Window activated', //sc_windowactivated + 'Menu', //sc_menu + 'Beginning of file', //sc_bof + 'End of file', //sc_eof + 'Voice output', //sc_voiceoutput + 'Speak again', //sc_speakagain + 'First column', //sc_firstcol + 'First row', //sc_firstrow + 'Last column', //sc_lastcol + 'Last row', //sc_lastrow + 'Selection', //sc_selection + 'Speak path', //sc_speakpath + 'Disabled button', //sc_disabledbutton + 'First field', //sc_firstfield + 'Last field', //sc_lastfield + 'First element', //sc_firstelement + 'Last element', //sc_lastelement + 'Slower', //sc_slower + 'Faster', //sc_faster + 'Window', //sc_window + 'Area', //sc_area + 'Area activated', //sc_areaactivated + 'Volume down', //sc_volumedown + 'Volume up', //sc_volumeup + 'Cancel speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= #30830#23450#21024#38500#27492#26465#35760#24405#21527#65311 + end + else begin + result:= #30830#23450#21024#38500#25152#36873#25321#30340' '+ + inttostrmse(vinteger)+' '#34892#35760#24405#21527#65311; + end; + end; +end; + +const + zh_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_zh],@zh_stockcaption,@zh_modalresulttext, + @zh_modalresulttextnoshortcut,@zh_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/msectypes.pas b/mseide-msegui/lib/common/kernel/msectypes.pas new file mode 100644 index 0000000..0f89825 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msectypes.pas @@ -0,0 +1,117 @@ +unit msectypes; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef FPC} + {$ifndef mswindows} +uses + msetypes; //for uint64 in kylix + {$endif} +{$endif} +//todo: win64 +type +// from bits/types.h + __S8_TYPE = shortint; + __U8_TYPE = byte; + __S16_TYPE = smallint; + __U16_TYPE = word; + __S32_TYPE = longint; + __U32_TYPE = longword; + __S64_TYPE = int64; + __U64_TYPE = uint64; + +{$ifndef CPU64} + __ULONGLONGWORD_TYPE = uint64; + __SLONGLONGWORD_TYPE = int64; + __SLONGWORD_TYPE = longint; + __ULONGWORD_TYPE = longword; + __SQUAD_TYPE = int64; + __UQUAD_TYPE = uint64; + __SWORD_TYPE = integer; + __UWORD_TYPE = longword; + __SLONG32_TYPE = integer; + __ULONG32_TYPE = longword; +{$else} + __ULONGLONGWORD_TYPE = uint64; + __SLONGLONGWORD_TYPE = int64; + __SLONGWORD_TYPE = int64; + __ULONGWORD_TYPE = uint64; + __SQUAD_TYPE = int64; + __UQUAD_TYPE = uint64; + __SWORD_TYPE = int64; + __UWORD_TYPE = uint64; + __SLONG32_TYPE = integer; + __ULONG32_TYPE = longword; +{$endif} + + cchar = char; + pcchar = ^cchar; + ppcchar = ^pcchar; + cuchar = byte; + pcuchar = ^cuchar; + ppcuchar = ^pcuchar; + culonglong = __ULONGLONGWORD_TYPE; + clonglong = __SLONGLONGWORD_TYPE; + culong = __ULONGWORD_TYPE; + pculong = ^culong; + clong = __SLONGWORD_TYPE; + pclong = ^clong; + cint = __S32_TYPE; + pcint = ^cint; + cuint = __U32_TYPE; + pcuint = ^cuint; + cshort = __S16_TYPE; + csshort = __S16_TYPE; + pcshort = ^cshort; + cushort = __U16_TYPE; + pcushort = ^cushort; + cint8 = __S8_TYPE; + pcint8 = ^cint8; + cuint8 = __U8_TYPE; + pcuint8 = ^cuint8; + cint16 = __S16_TYPE; + pcint16 = ^cint16; + cuint16 = __U16_TYPE; + pcuint16 = ^cuint16; + cint32 = __S32_TYPE; + pcint32 = ^cint32; + cuint32 = __U32_TYPE; + pcuint32 = ^cuint32; + cint64 = __SQUAD_TYPE; + pcint64 = ^cint64; + cuint64 = __UQUAD_TYPE; + pucint64 = ^cuint64; + + cbool = cint; + pcbool = pcint; + + cfloat = single; + pcfloat = ^cfloat; + cdouble = double; + pcdouble = ^cdouble; + + cenum = cint; + + wchar_t = cint32; + pwchar_t = ^wchar_t; + +{$ifdef cpu64} + size_t = cuint64; + off_t = cuint64; + ssize_t = cint64; + clock_t = cuint64; + time_t = cint64; +{$else} + size_t = cuint32; + off_t = cuint32; + ssize_t = cint32; + clock_t = culong; + time_t = clong; +{$endif} + psize_t = ^size_t; + poff_t = ^off_t; + pssize_t = ^ssize_t; + pclock_t = ^clock_t; + ptime_t = ^time_t; + +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/msedatamodules.pas b/mseide-msegui/lib/common/kernel/msedatamodules.pas new file mode 100644 index 0000000..1dbecf7 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msedatamodules.pas @@ -0,0 +1,511 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedatamodules; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,mseclasses,msetypes,msegraphutils,msestatfile,mseevent,mseapplication; + +type + datamoduleoptionty = (dmo_autoreadstat,dmo_delayedreadstat, + dmo_autowritestat,dmo_iconic); + datamoduleoptionsty = set of datamoduleoptionty; +const + defaultdatamoduleoptions = [dmo_autoreadstat,dmo_autowritestat]; + +type + tmsedatamodule = class(tactcomponent) + private + fsize: sizety; + foncreate: notifyeventty; + foncreated: notifyeventty; + fondestroy: notifyeventty; + fondestroyed: notifyeventty; + foptions: datamoduleoptionsty; + fstatfile: tstatfile; + fonloaded: notifyeventty; + fonasyncevent: asynceventeventty; + foneventloopstart: notifyeventty; + fonevent: eventeventty; + fonterminatequery: terminatequeryeventty; + fonterminated: notifyeventty; +// procedure writesize(writer: twriter); + fonidle: idleeventty; + factivatortarget: tactivator; + fonapplicationevent: applicationeventeventty; + procedure readsize(reader: treader); + { + procedure readsize_x(reader: treader); + procedure writesize_x(writer: twriter); + procedure readsize_y(reader: treader); + procedure writesize_y(writer: twriter); + } + procedure setstatfile(const avalue: tstatfile); + function getbounds_x: integer; + procedure setbounds_x(const avalue: integer); + function getbounds_y: integer; + procedure setbounds_y(const avalue: integer); + procedure setbounds_cx(const avalue: integer); + procedure setbounds_cy(const avalue: integer); + procedure setsize(const avalue: sizety); + procedure setoptions(const avalue: datamoduleoptionsty); + procedure setactivatortarget(const avalue: tactivator); + procedure setonapplicationeventty(const avalue: applicationeventeventty); + protected + procedure boundschanged; + procedure doterminated(const sender: tobject); + procedure doterminatequery(var terminate: boolean); + procedure getchildren(proc: tgetchildproc; + root: tcomponent); override; + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure defineproperties(filer: tfiler); override; + procedure dooncreate; virtual; + procedure readstate(reader: treader); override; + procedure doafterload; override; + procedure autoreadstat; + procedure loaded; override; + procedure doasyncevent(var atag: integer); override; + procedure doeventloopstart; virtual; + procedure doidle(var again: boolean); virtual; + procedure receiveevent(const event: tobjectevent); override; + procedure doapplicationevent(var aevent: tmseevent; + var handled: boolean) virtual; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); reintroduce; overload; + destructor destroy; override; + procedure afterconstruction; override; + procedure reload; + function hasparent: boolean; override; + function getparentcomponent: tcomponent; override; + procedure beforedestruction; override; + procedure freeinstance override; + property size: sizety read fsize write setsize; + published + property activatortarget: tactivator read factivatortarget + write setactivatortarget; + property options: datamoduleoptionsty read foptions write setoptions + default defaultdatamoduleoptions; + property bounds_x: integer read getbounds_x write setbounds_x stored false; + property bounds_y: integer read getbounds_y write setbounds_y stored false; + property bounds_cx: integer read fsize.cx write setbounds_cx; + property bounds_cy: integer read fsize.cy write setbounds_cy; + + property statfile: tstatfile read fstatfile write setstatfile; + property oncreate: notifyeventty read foncreate write foncreate; + property oncreated: notifyeventty read foncreated write foncreated; + property onloaded: notifyeventty read fonloaded write fonloaded; + property oneventloopstart: notifyeventty read foneventloopstart + write foneventloopstart; + property ondestroy: notifyeventty read fondestroy write fondestroy; + property ondestroyed: notifyeventty read fondestroyed write fondestroyed; + property onevent: eventeventty read fonevent write fonevent; + property onasyncevent: asynceventeventty read fonasyncevent write fonasyncevent; + property onterminatequery: terminatequeryeventty read fonterminatequery + write fonterminatequery; + property onterminated: notifyeventty read fonterminated + write fonterminated; + property onidle: idleeventty read fonidle write fonidle; + property onapplicationevent: applicationeventeventty + read fonapplicationevent write setonapplicationeventty; + end; + datamoduleclassty = class of tmsedatamodule; + msedatamodulearty = array of tmsedatamodule; + +function createmsedatamodule(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +implementation +uses + sysutils; + +type + tmsecomponent1 = class(tmsecomponent); + +function createmsedatamodule(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= datamoduleclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +{ tmsedatamodule } + +constructor tmsedatamodule.create(aowner: tcomponent); +begin + create(aowner,not (cs_noload in fmsecomponentstate)); +end; + +constructor tmsedatamodule.create(aowner: tcomponent; load: boolean); +begin + foptions:= defaultdatamoduleoptions; + include(fmsecomponentstate,cs_ismodule); + designinfo:= 100+(100 shl 16); + inherited create(aowner); + application.registeronterminated({$ifdef FPC}@{$endif}doterminated); + application.registeronterminate({$ifdef FPC}@{$endif}doterminatequery); + application.registeronidle({$ifdef FPC}@{$endif}doidle); + if load and not (csdesigning in componentstate) then begin + loadmsemodule(self,tmsedatamodule); + end; + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; +// autoreadstat; + if not load then begin + doafterload; + end; +end; + +destructor tmsedatamodule.destroy; +var + bo1: boolean; +begin + application.unregisteronterminated({$ifdef FPC}@{$endif}doterminated); + application.unregisteronterminate({$ifdef FPC}@{$endif}doterminatequery); + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + if not (csdesigning in componentstate) and + assigned(fonapplicationevent) then begin + application.unregisterapplicationeventhandler(@doapplicationevent); + end; + bo1:= csdesigning in componentstate; + inherited; //csdesigningflag is removed + if not bo1 and candestroyevent(tmethod(fondestroyed)) then begin + fondestroyed(self); + end; +end; + +procedure tmsedatamodule.afterconstruction; +begin + inherited; + if assigned(foncreated) then begin + foncreated(self); + end; +end; + +procedure tmsedatamodule.beforedestruction; +begin + if (fstatfile <> nil) and (dmo_autowritestat in foptions) and + not (csdesigning in componentstate) then begin + fstatfile.writestat; + end; + inherited; + if candestroyevent(tmethod(fondestroy)) then begin + fondestroy(self); + end; +end; + +procedure tmsedatamodule.reload; +begin + name:= ''; + reloadmsecomponent(self); +// doafterload; +end; + +procedure tmsedatamodule.dooncreate; +begin + if not (cs_inheritedloading in msecomponentstate) then begin + include(factstate,acs_dooncreatecalled); + if assigned(foncreate) then begin //csloading possibly set + foncreate(self); + end; + end; +end; + +procedure tmsedatamodule.doafterload; +begin + inherited; +// if (fstatfile <> nil) and +// (foptions*[dmo_autoreadstat,dmo_delayedreadstat] = +// [dmo_autoreadstat]) then begin +// fstatfile.readstat; +// end; + autoreadstat; + if canevent(tmethod(fonloaded)) then begin + fonloaded(self); + end; +end; + +procedure tmsedatamodule.loaded; +begin + if (factivatortarget <> nil) and not (csdesigning in componentstate) then begin + factivatortarget.activaterecursive; + end; + inherited; + application.postevent(tobjectevent.create(ek_loaded,ievent(self))); +end; + +procedure tmsedatamodule.freeinstance; +begin + if (factivatortarget <> nil) and not (csdesigning in componentstate) then begin + try + factivatortarget.deactivaterecursive; + finally + inherited; + end; + end + else begin + inherited; + end; +end; + +procedure tmsedatamodule.readstate(reader: treader); +begin + inherited; + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; +end; + +function tmsedatamodule.getparentcomponent: tcomponent; +begin + result:= owner; +end; + +function tmsedatamodule.hasparent: boolean; +begin + result:= getparentcomponent <> nil; +end; + +procedure tmsedatamodule.getchildren(proc: tgetchildproc; root: tcomponent); +var + int1: integer; + comp1: tcomponent; +begin + if root = self then begin + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if not (cssubcomponent in comp1.componentstyle) and + (comp1.getparentcomponent = self) then begin + proc(comp1); + end; + end; + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if not (cssubcomponent in comp1.componentstyle) and + not comp1.hasparent then begin + proc(comp1); + end; + end; + end; +end; + +class function tmsedatamodule.getmoduleclassname: string; +begin +// result:= tmsedatamodule.ClassName; + //bug in dcc32: tmsedatamodule is replaced by self + result:= 'tmsedatamodule'; +end; + +class function tmsedatamodule.hasresource: boolean; +begin + result:= self <> tmsedatamodule; +end; +{ +procedure tmsedatamodule.writesize(writer: twriter); +begin + with writer do begin + writelistbegin; + writeinteger(fsize.cx); + writeinteger(fsize.cy); + writelistend; + end; +end; +} +procedure tmsedatamodule.readsize(reader: treader); +begin + with reader do begin + readlistbegin; + fsize.cx:= readinteger; + fsize.cy:= readinteger; + readlistend; + end; +end; + +procedure tmsedatamodule.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('size',{$ifdef FPC}@{$endif}readsize,nil,false); +end; + +procedure tmsedatamodule.setstatfile(const avalue: tstatfile); +begin + setlinkedvar(avalue,tmsecomponent(fstatfile)); +end; + +procedure tmsedatamodule.doasyncevent(var atag: integer); +begin + if canevent(tmethod(fonasyncevent)) then begin + fonasyncevent(self,atag); + end; + inherited; +end; + +procedure tmsedatamodule.doeventloopstart; +begin + if (fstatfile <> nil) and not (csdesigning in componentstate) and + (foptions*[dmo_autoreadstat,dmo_delayedreadstat] = + [dmo_autoreadstat,dmo_delayedreadstat]) then begin + fstatfile.readstat; + end; + if canevent(tmethod(foneventloopstart)) then begin + foneventloopstart(self); + end; +end; + +procedure tmsedatamodule.doidle(var again: boolean); +begin + if canevent(tmethod(fonidle)) then begin + fonidle(again); + end; +end; + +procedure tmsedatamodule.receiveevent(const event: tobjectevent); +begin + if canevent(tmethod(fonevent)) then begin + fonevent(self,event); + end; + inherited; + if event.kind = ek_loaded then begin + doeventloopstart; + end; +end; + +procedure tmsedatamodule.doapplicationevent(var aevent: tmseevent; + var handled: boolean); +begin + if assigned(fonapplicationevent) then begin + fonapplicationevent(self,aevent,handled); + end; +end; + +procedure tmsedatamodule.doterminated(const sender: tobject); +begin + if canevent(tmethod(fonterminated)) then begin + fonterminated(sender); + end; +end; + +procedure tmsedatamodule.doterminatequery(var terminate: boolean); +begin + if canevent(tmethod(fonterminatequery)) then begin + fonterminatequery(terminate); + end; +end; + +procedure tmsedatamodule.boundschanged; +begin + designchanged; +end; + +function tmsedatamodule.getbounds_x: integer; +begin + result:= longrec(designinfo).lo; +end; + +procedure tmsedatamodule.setbounds_x(const avalue: integer); +var + rec: longrec; +begin + rec:= longrec(designinfo); + if rec.lo <> avalue then begin + rec.lo:= avalue; + designinfo:= longint(rec); + boundschanged; + end; +end; + +function tmsedatamodule.getbounds_y: integer; +begin + result:= longrec(designinfo).hi; +end; + +procedure tmsedatamodule.setbounds_y(const avalue: integer); +var + rec: longrec; +begin + rec:= longrec(designinfo); + if rec.hi <> avalue then begin + rec.hi:= avalue; + designinfo:= longint(rec); + boundschanged; + end; +end; + +procedure tmsedatamodule.setbounds_cx(const avalue: integer); +begin + if fsize.cx <> avalue then begin + fsize.cx:= avalue; + boundschanged; + end; +end; + +procedure tmsedatamodule.setbounds_cy(const avalue: integer); +begin + if fsize.cy <> avalue then begin + fsize.cy:= avalue; + boundschanged; + end; +end; + +procedure tmsedatamodule.setsize(const avalue: sizety); +begin + if (fsize.cx <> avalue.cx) or (fsize.cy <> avalue.cy) then begin + fsize:= avalue; + boundschanged; + end; +end; + +procedure tmsedatamodule.setoptions(const avalue: datamoduleoptionsty); +var + optionsbefore: datamoduleoptionsty; +begin + optionsbefore:= foptions; + foptions:= avalue; + if (dmo_iconic in avalue) xor (dmo_iconic in optionsbefore) then begin + boundschanged; + end; +end; + +procedure tmsedatamodule.autoreadstat; +begin + if (fstatfile <> nil) and not (csdesigning in componentstate) and + (foptions*[dmo_autoreadstat,dmo_delayedreadstat] = + [dmo_autoreadstat]) then begin + fstatfile.readstat; + end; +end; + +procedure tmsedatamodule.setactivatortarget(const avalue: tactivator); +begin + setlinkedvar(avalue,tmsecomponent(factivatortarget)); +end; + +procedure tmsedatamodule.setonapplicationeventty( + const avalue: applicationeventeventty); +begin + if not (csdesigning in componentstate) then begin + if assigned(avalue) then begin + if not assigned(fonapplicationevent) then begin + application.registerapplicationeventhandler(@doapplicationevent); + end; + end + else begin + if assigned(fonapplicationevent) then begin + application.unregisterapplicationeventhandler(@doapplicationevent); + end; + end; + end; + fonapplicationevent:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msedate.pas b/mseide-msegui/lib/common/kernel/msedate.pas new file mode 100644 index 0000000..efc64b2 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msedate.pas @@ -0,0 +1,84 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedate; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +const + unidatetimeoffset = -25569; + +function nowutc: tdatetime; +function nowlocal: tdatetime; +function maxdays(year: word; month: word): word; +function utctolocaltime(const value: tdatetime): tdatetime; +function localtimetoutc(const value: tdatetime): tdatetime; +function unixtodatetime(const value: longword): tdatetime; + +implementation +uses + msesysintf1,msesysintf; + +function nowutc: tdatetime; +begin + result:= sys_getutctime; +end; + +function nowlocal: tdatetime; +begin + result:= sys_getlocaltime; +end; + +function utctolocaltime(const value: tdatetime): tdatetime; +begin + result:= sys_utctolocaltime(value); +// result:= value + sys_localtimeoffset; +end; + +function localtimetoutc(const value: tdatetime): tdatetime; +begin + result:= sys_localtimetoutc(value); +// result:= value - sys_localtimeoffset; +end; + +function unixtodatetime(const value: longword): tdatetime; +begin + result:= value/(24.0*60*60) - unidatetimeoffset; +end; + +function maxdays(year: word; month: word): word; +begin + if month = 0 then begin + year:= year - 1; + month:= 12; + end; + if month = 14 then begin + year:= year + 1; + month:= 1; + end; + if month = 13 then begin + month:= 12; + end; + case month of + 1,3,5,7,8,10,12: + result:= 31; + 2: begin + if (year mod 4 = 0) and (not (year mod 100 = 0) or (year mod 400 = 0)) then + result:= 29 + else + result:= 28; + end; + else + result:= 30; + end; +end; + + +end. diff --git a/mseide-msegui/lib/common/kernel/msedrag.pas b/mseide-msegui/lib/common/kernel/msedrag.pas new file mode 100644 index 0000000..eb04868 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msedrag.pas @@ -0,0 +1,578 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedrag; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msegraphutils,mseevent,classes,mseclasses,mseglob,mseguiglob,msedragglob, + msegui,msetimer; +type + idragcontroller = interface(inullinterface) + function getwidget: twidget; + function getdragrect(const apos: pointty): rectty; + end; + +type + drageventty = procedure(const asender: tobject; const apos: pointty; + var adragobject: tdragobject; var processed: boolean) of object; + dragovereventty = procedure(const asender: tobject; const apos: pointty; + var adragobject: tdragobject; var accept: boolean; + var processed: boolean) of object; + dragendeventty = procedure(const asender: tobject; const apos: pointty; + var adragobject: tdragobject; const accepted: boolean; + var processed: boolean) of object; + + ttagdragobject = class(tdragobject) + private + protected + ftag: integer; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const tag: integer); + function tag: integer; + end; + + tobjectdragobject = class(tdragobject) + private + protected + fdata: tobject; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const dataobject: tobject); + property data: tobject read fdata; + end; + + tstringdragobject = class(tdragobject) + public + data: string; + end; + + dragstatety = (ds_clicked,ds_beginchecked,ds_cursorshapechanged, + ds_haddragobject); + dragstatesty = set of dragstatety; + +const + dragstates = [ds_clicked,ds_beginchecked,ds_haddragobject]; + sdndexpiretime = 5000000; //5s + dragmindist = 4; + +type + drageventsty = record + dragbegin: drageventty; + dragover: dragovereventty; + dragdrop: drageventty; + dragend: dragendeventty; + end; + + sysdndinfoty = record + dragobj: tdragobject; +// expiretime: longword; + end; + + dragoptionty = (do_child,do_nocursorshape,do_nearstart,do_mousewidget); + dragoptionsty = set of dragoptionty; + + tcustomdragcontroller = class(tlinkedpersistent,ievent) + private + ftimer: tsimpletimer; + foptions: dragoptionsty; + procedure initdraginfo(var info: draginfoty; + const eventkind: drageventkindty; const pos: pointty); + function checkcandragdrop(const pos: pointty; + out sysdndpending: boolean): twidget; + protected + fpickpos: pointty; + fpickrect: rectty; + fdragobject: tdragobject; + fstate: dragstatesty; + fintf: idragcontroller; + fsysdndobjects: array[0..3] of sysdndinfoty; + flastwidget: twidget; + procedure dokeypress(const sender: twidget; var info: keyeventinfoty) + virtual; + procedure doexpiresdnd(const sender: tobject); + function checkclickstate(const info: mouseeventinfoty): boolean; virtual; + function checksysdnd(const aaction: sysdndactionty; + const arect: rectty): boolean; virtual; + function canbegindrag: boolean; virtual; + //ievent + procedure receiveevent(const aevent: tobjectevent); virtual; + public + constructor create(const aintf: idragcontroller); reintroduce; + destructor destroy; override; + function active: boolean; + procedure enddrag; virtual; + procedure mouseevent(var info: mouseeventinfoty); virtual; + procedure clientmouseevent(var info: mouseeventinfoty); virtual; + procedure childormouseevent(const sender: twidget; + var info: mouseeventinfoty); virtual; + function beforedragevent(var info: draginfoty): boolean; virtual; abstract; + //true if processed + function afterdragevent(var info: draginfoty): boolean; virtual; abstract; + //true if processed + property pickpos: pointty read fpickpos; //clientorigin + property options: dragoptionsty read foptions + write foptions default []; + end; + + tdragcontroller = class(tcustomdragcontroller) + private + fonbefore,fonafter: drageventsty; + function dodragevent(const events: drageventsty; + var info: draginfoty): boolean; + public + function beforedragevent(var info: draginfoty): boolean; override; + //true if processed + function afterdragevent(var info: draginfoty): boolean; override; + //true if processed + published + property onbeforedragbegin: drageventty read fonbefore.dragbegin + write fonbefore.dragbegin; + property onbeforedragover: dragovereventty read fonbefore.dragover + write fonbefore.dragover; + property onbeforedragdrop: drageventty read fonbefore.dragdrop + write fonbefore.dragdrop; + property onbeforedragend: dragendeventty read fonbefore.dragend + write fonbefore.dragend; + property onafterdragbegin: drageventty read fonafter.dragbegin + write fonafter.dragbegin; + property onafterdragover: dragovereventty read fonafter.dragover + write fonafter.dragover; + property onafterdragdrop: drageventty read fonafter.dragdrop + write fonafter.dragdrop; + property onafterdragend: dragendeventty read fonafter.dragend + write fonafter.dragend; + property options; + end; + +function isobjectdrag(const dragobject: tdragobject; + objectclass: tclass): boolean; + +implementation +uses + msebits,msepointer,msekeyboard,msesysdnd,sysutils,msesysutils, + mseguiintf; +type +// tguiapplication1 = class(tguiapplication); + tdragobject1 = class(tdragobject); + +function isobjectdrag(const dragobject: tdragobject; + objectclass: tclass): boolean; +begin + result:= (dragobject is tobjectdragobject) and + (tobjectdragobject(dragobject).fdata is objectclass); +end; + +{ tcustomdragcontroller } + +constructor tcustomdragcontroller.create(const aintf: idragcontroller); +begin + fintf:= aintf; +end; + +destructor tcustomdragcontroller.destroy; +var + int1: integer; +begin + enddrag; + ftimer.free; + for int1:= 0 to high(fsysdndobjects) do begin + freeandnil(fsysdndobjects[int1]); + end; + inherited; +end; + +function tcustomdragcontroller.active: boolean; +begin + result:= ds_clicked in fstate; +end; + +procedure tcustomdragcontroller.doexpiresdnd(const sender: tobject); +var + int1: integer; +begin + for int1:= low(fsysdndobjects) to high(fsysdndobjects) do begin + freeandnil(fsysdndobjects[int1].dragobj); + end; + freeandnil(ftimer); +end; + +procedure tcustomdragcontroller.enddrag; +var + int1,int2: integer; + draginfo: draginfoty; + owner: twidget; + po1: pointty; +begin +// checksysdnd(sdnda_finished,nullrect); + if fdragobject <> nil then begin + owner:= fintf.getwidget(); + if dos_dropped in fdragobject.state then begin + po1:= translateclientpoint(fdragobject.droppos,nil,owner); + end + else begin + po1:= fdragobject.pickpos; + end; + initdraginfo(draginfo,dek_end,po1); + owner.dragevent(draginfo); + if dos_sysdroppending in tdragobject1(fdragobject).fstate then begin + int2:= 0; + for int1:= 0 to high(fsysdndobjects) do begin + if fsysdndobjects[int1].dragobj = nil then begin + int2:= int1; + break; + end; + end; + with fsysdndobjects[int2] do begin + if dragobj <> nil then begin + dragobj.destroy; + end; + tdragobject1(fdragobject).finstancepo:= @dragobj; + dragobj:= fdragobject; + if ftimer = nil then begin + ftimer:= tsimpletimer.create(sdndexpiretime,{$ifdef FPC}@{$endif}doexpiresdnd, + true,[to_single]); + end + else begin + ftimer.interval:= sdndexpiretime; + end; + end; + fdragobject:= nil; + end + else begin + fdragobject.free; + end; + end; + if ds_haddragobject in fstate then begin + if not (do_nocursorshape in foptions) then begin + application.cursorshape:= cr_default; + end; + end; + application.unregisteronkeypress(@dokeypress); + fstate:= fstate - dragstates; +end; + +procedure tcustomdragcontroller.dokeypress(const sender: twidget; + var info: keyeventinfoty); +begin + if active and (info.key = key_escape) then begin + enddrag; + include(info.eventstate,es_processed); + end; +end; + +function tcustomdragcontroller.checkcandragdrop(const pos: pointty; + out sysdndpending: boolean): twidget; +var + window: twindow; + pt1: pointty; + info: draginfoty; +begin + result:= nil; + window:= nil; + pt1:= translateclientpoint(pos,fintf.getwidget,nil); + if do_mousewidget in foptions then begin + result:= application.mousewidget; + if result <> nil then begin + window:= result.window; + end; + end + else begin + window:= application.windowatpos(pt1); + if window <> nil then begin + result:= window.owner.widgetatpos(translatewidgetpoint(pt1,nil,window.owner), + [ws_visible,ws_enabled]); + end; + end; + if window <> nil then begin + sysdndpending:= false; + if (flastwidget <> result) then begin + if (flastwidget <> nil) then begin + initdraginfo(info,dek_leavewidget, + translateclientpoint(pt1,nil,flastwidget)); + flastwidget.dragevent(info); + end; + setlinkedvar(result,tmsecomponent(flastwidget)); + end; + if result <> nil then begin + initdraginfo(info,dek_check,translateclientpoint(pt1,nil,result)); + result.dragevent(info); + if not info.accept then begin + result:= nil; + end; + end + end + else begin + sysdndpending:= checksysdnd(sdnda_check,mr(pt1,nullsize)); + end; +end; + +procedure tcustomdragcontroller.initdraginfo(var info: draginfoty; + const eventkind: drageventkindty; const pos: pointty); +begin + fillchar(info,sizeof(info),0); + info.eventkind:= eventkind; + info.pos:= pos; + info.clientpickpos:= fpickpos; + info.pickpos:= translateclientpoint(fpickpos,fintf.getwidget,nil); + info.dragobjectpo:= @fdragobject; + if (eventkind = dek_drop) and (fdragobject <> nil) then begin + include(tdragobject1(fdragobject).fstate,dos_dropped); + end; +end; + +function tcustomdragcontroller.checkclickstate( + const info: mouseeventinfoty): boolean; +begin + result:= info.shiftstate - [ss_left] = []; +end; + +procedure tcustomdragcontroller.clientmouseevent(var info: mouseeventinfoty); +var + owner: twidget; + widget1: twidget; + draginfo: draginfoty; + bo1: boolean; +begin + owner:= fintf.getwidget; + case info.eventkind of + {ek_clientmouseleave,ek_mouseleave}ek_mousecaptureend: begin + enddrag; + end; + ek_buttonpress: begin + if checkclickstate(info) then begin + fpickpos:= info.pos; + if do_nearstart in foptions then begin + fpickrect.x:= info.pos.x - dragmindist; + fpickrect.y:= info.pos.y - dragmindist; + fpickrect.cx:= 2 * dragmindist; + fpickrect.cy:= 2 * dragmindist; + end + else begin + fpickrect:= fintf.getdragrect(fpickpos); + end; + include(fstate,ds_clicked); + end; + end; + ek_buttonrelease: begin + try + if fdragobject <> nil then begin + fdragobject.droppos:= translateclientpoint(info.pos,owner,nil); + include(info.eventstate,es_processed); + widget1:= checkcandragdrop(info.pos,bo1); + if widget1 <> nil then begin + initdraginfo(draginfo,dek_drop, + translateclientpoint(info.pos,owner,widget1)); + widget1.dragevent(draginfo); + end + else begin + if bo1 then begin + include(tdragobject1(fdragobject).fstate,dos_sysdroppending); + end; + checksysdnd(sdnda_drop,nullrect); + end; + if flastwidget <> nil then begin + initdraginfo(draginfo,dek_leavewidget, + translateclientpoint(info.pos,owner,flastwidget)); + flastwidget.dragevent(draginfo); + setlinkedvar(nil,tmsecomponent(flastwidget)); + end; + end; + finally + enddrag; + end; + end; + ek_mousemove,ek_mousepark: begin + if checkclickstate(info) then begin + if (fstate * [ds_clicked,ds_beginchecked] = [ds_clicked]) and + (fdragobject = nil) and not pointinrect(info.pos,fpickrect) + {(distance(info.pos,fpickpos) > mindragdist)} then begin + include(fstate,ds_beginchecked); + if canbegindrag then begin + application.registeronkeypress({$ifdef FPC}@{$endif}dokeypress); + initdraginfo(draginfo,dek_begin,fpickpos); + owner.dragevent(draginfo); + checksysdnd(sdnda_begin,nullrect); + end; + end; + if (fdragobject <> nil) then begin + include(fstate,ds_haddragobject); + tdragobject1(fdragobject).feventintf:= ievent(self); + include(info.eventstate,es_processed); + if checkcandragdrop(info.pos,bo1) <> nil then begin + if not (do_nocursorshape in foptions) then begin + application.cursorshape:= cr_drag; + end; + fdragobject.acepted(translateclientpoint(info.pos,owner,nil)); + end + else begin + if not bo1 then begin + if not (do_nocursorshape in foptions) then begin + application.cursorshape:= cr_forbidden; + end; + fdragobject.refused(translateclientpoint(info.pos,owner,nil)); + end; + end; + end; + end + else begin + enddrag; + end; + end; + end; + if fdragobject = nil then begin + exclude(info.eventstate,es_drag); + end + else begin + include(info.eventstate,es_drag); + end; +end; + +procedure tcustomdragcontroller.mouseevent(var info: mouseeventinfoty); +var + po1: pointty; +begin + po1:= fintf.getwidget.clientwidgetpos; + subpoint1(info.pos,po1); + clientmouseevent(info); + addpoint1(info.pos,po1); +end; + +function tcustomdragcontroller.checksysdnd(const aaction: sysdndactionty; + const arect: rectty): boolean; +begin + result:= false; + if fdragobject <> nil then begin + result:= tdragobject1(fdragobject).checksysdnd(aaction,arect); + end; +end; + +procedure tcustomdragcontroller.receiveevent(const aevent: tobjectevent); +begin + if (fdragobject <> nil) and (aevent is tsysdndstatusevent) then begin + with tsysdndstatusevent(aevent) do begin + if ds_beginchecked in fstate then begin + if not (do_nocursorshape in foptions) then begin + if accept then begin + application.cursorshape:= cr_drag; + end + else begin + application.cursorshape:= cr_forbidden; + end; + end; + end; + end; + end; +end; + +procedure tcustomdragcontroller.childormouseevent(const sender: twidget; + var info: mouseeventinfoty); +var + widget1: twidget; + pt1: pointty; +begin + if es_child in info.eventstate then begin + widget1:= fintf.getwidget; + if sender <> widget1 then begin + if (do_child in foptions) and + (info.eventkind in [ek_buttonpress,ek_buttonrelease,ek_mousewheel, + ek_mousemove,ek_mousepark]) then begin + pt1:= info.pos; + translatewidgetpoint1(info.pos,sender,widget1); + try + mouseevent(info); + finally + info.pos:= pt1; + end; + end; + end + else begin + mouseevent(info); + end; + end + else begin + mouseevent(info); + end; +end; + +function tcustomdragcontroller.canbegindrag: boolean; +begin + result:= true; +end; + +{ tdragcontroller } + +function tdragcontroller.dodragevent(const events: drageventsty; + var info: draginfoty): boolean; +begin + with events,info do begin + result:= false; + case eventkind of + dek_begin: begin + if assigned(dragbegin) then begin + dragbegin(fintf.getwidget,pos,dragobjectpo^,result); + end; + end; + dek_check: begin + if assigned(dragover) then begin + dragover(fintf.getwidget,pos,dragobjectpo^,accept,result); + end; + end; + dek_drop: begin + if assigned(dragdrop) then begin + dragdrop(fintf.getwidget,pos,dragobjectpo^,result); + end; + end; + dek_end: begin + if assigned(dragend) then begin + dragend(fintf.getwidget,pos,dragobjectpo^,(dragobjectpo^ <> nil) and + (dos_dropped in dragobjectpo^.state),result); + end; + end; + end; + end; +end; + +function tdragcontroller.beforedragevent(var info: draginfoty): boolean; +begin + result:= dodragevent(fonbefore,info); +end; + +function tdragcontroller.afterdragevent(var info: draginfoty): boolean; +begin + result:= dodragevent(fonafter,info); +end; + +{ tobjectdragobject } + +constructor tobjectdragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; const dataobject: tobject); +begin + fdata:= dataobject; + inherited create(asender,instance,apickpos); +end; + +{ ttagdragobject } + +constructor ttagdragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; const tag: integer); +begin + ftag:= tag; + inherited create(asender,instance,apickpos); +end; + +function ttagdragobject.tag: integer; +begin + result:= ftag; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msedynload.pas b/mseide-msegui/lib/common/kernel/msedynload.pas new file mode 100644 index 0000000..e4ec1d8 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msedynload.pas @@ -0,0 +1,492 @@ +unit msedynload; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msesystypes,{$ifdef FPC}dynlibs,{$endif}{msestrings,}sysutils,msetypes{,msesys}; + +{$ifndef cpuarm}{$define set8087cw}{$endif} + +type + funcinfoty = record + n: string; //name + d: ppointer; //destination + end; + dynlibinfoty = record + libhandle: tlibhandle; + libname: filenamety; + refcount: integer; + inithooks: pointerarty; //array of dynlibprocty + deinithooks: pointerarty; //array of dynlibprocty + cw8087: word; //fpu control word after lib load + end; + dynlibprocty = procedure(const dynlib: dynlibinfoty); + dynloadcallbackty = procedure(const data: pointer); + + edynload = class(ecrashstatfile) + end; + +procedure initializelibinfo(var info: dynlibinfoty); +procedure finalizelibinfo(var info: dynlibinfoty); + +function initializedynlib(var info: dynlibinfoty; + const libnames: array of filenamety; + const libnamesdefault: array of filenamety; + const funcs: array of funcinfoty; + const funcsopt: array of funcinfoty; + const errormessage: msestring = ''; + const callback: dynloadcallbackty = nil; + const noexception: boolean = false; + const callbackdata: pointer = nil): boolean; + //called after lib load + //returns true if all funcsopt found +procedure releasedynlib(var info: dynlibinfoty; + const callback: dynloadcallbackty = nil; + const nodlunload: boolean = false; + const callbackdata: pointer = nil); + //called before lib unload +procedure regdynlibinit(var info: dynlibinfoty; const initproc: dynlibprocty); +procedure regdynlibdeinit(var info: dynlibinfoty; const initproc: dynlibprocty); + +procedure dynloadlock; +procedure dynloadunlock; + +function loadlib(const libnames: array of filenamety; out libname: filenamety; + const errormessage: msestring = ''; + const noexception: boolean = false): tlibhandle; + +function getprocaddresses(const lib: tlibhandle; + const procedures: array of funcinfoty; + const noexception: boolean = false; + const libname: msestring = ''): boolean; overload; +function getprocaddresses(const lib: tlibhandle; const anames: array of string; + const adest: array of ppointer; + const noexception: boolean = false; + const libname: msestring = ''): boolean; overload; +function getprocaddresses(const libinfo: dynlibinfoty; + const procedures: array of funcinfoty; + const noexception: boolean = false): boolean; overload; +function getprocaddresses(const libnames: array of msestring; + const procedures: array of funcinfoty; + const noexception: boolean = false): tlibhandle; overload; +function getprocaddresses(const libinfo: dynlibinfoty; + const anames: array of string; + const adest: array of ppointer; + const noexception: boolean = false): boolean; overload; +function getprocaddresses(const libnames: array of filenamety; + const anames: array of string; + const adest: array of ppointer; + const noexception: boolean = false): tlibhandle; overload; +function checkprocaddresses(const libnames: array of filenamety; + const anames: array of string; + const adest: array of ppointer): boolean; +function checkprocaddresses(const libnames: array of filenamety; + const procedures: array of funcinfoty): boolean; +function quotelibnames(const libnames: array of filenamety): msestring; + +implementation + +uses + msesysintf1{$ifdef linux},dl{$endif},msearrayutils,msestrings; + +function getprocaddresses(const lib: tlibhandle; + const procedures: array of funcinfoty; + const noexception: boolean = false; + const libname: msestring = ''): boolean; overload; +var + int1: integer; + mstr1: msestring; +begin + result:= true; + mstr1:= ''; + for int1:= 0 to high(procedures) do begin + with procedures[int1] do begin + {$ifdef FPC} + d^:= getprocedureaddress(lib,n); + {$else} + d^:= getprocaddress(lib,pansichar(n)); + {$endif} + if (d^ = nil) then begin + result:= false; + if not noexception then begin + if libname <> '' then begin + mstr1:= libname + lineend; + end; + mstr1:= mstr1 + 'Function "'+msestring(n)+'" not found.'; + raise edynload.create(ansistring(mstr1)); + end; + end; + end; + end; +end; + +function getprocaddresses(const lib: tlibhandle; const anames: array of string; + const adest: array of ppointer; + const noexception: boolean = false; + const libname: msestring = ''): boolean; +var + int1: integer; + mstr1: msestring; +begin + if high(anames) <> high(adest) then begin + raise exception.create('Invalid parameter.'); + end; + mstr1:= ''; + result:= true; + for int1:= 0 to high(anames) do begin + adest[int1]^:= getprocaddress(lib,pansichar(anames[int1])); + if (adest[int1]^ = nil) then begin + result:= false; + if not noexception then begin + if libname <> '' then begin + mstr1:= libname + lineend; + end; + mstr1:= mstr1 + 'Function "'+msestring(anames[int1])+'" not found.'; + raise exception.create(ansistring(mstr1)); + end; + end; + end; +end; + +function getprocaddresses(const libinfo: dynlibinfoty; + const procedures: array of funcinfoty; + const noexception: boolean = false): boolean; +begin + with libinfo do begin + result:= getprocaddresses(libhandle,procedures,noexception,libname); + end; +end; + +function getprocaddresses(const libnames: array of msestring; + const procedures: array of funcinfoty; + const noexception: boolean = false): tlibhandle; +var + str1: msestring; +begin + result:= loadlib(libnames,str1,'',noexception); + if result <> 0 then begin + if not getprocaddresses(result,procedures,noexception,str1) then begin + unloadlibrary(result); + result:= 0; + end; + end; +end; + +function getprocaddresses(const libinfo: dynlibinfoty; + const anames: array of string; + const adest: array of ppointer; + const noexception: boolean = false): boolean; overload; +begin + with libinfo do begin + result:= getprocaddresses(libhandle,anames,adest,noexception,libname); + end; +end; + +function loadlib(const libnames: array of filenamety; out libname: filenamety; + const errormessage: msestring = ''; + const noexception: boolean = false): tlibhandle; +var + int1: integer; + s1: string; +{$ifdef linux} + p1: pchar; + ar1: stringarty; +{$endif} +begin + result:= 0; + libname:= ''; +{$ifdef linux} + p1:= nil; +{$endif} + for int1:= 0 to high(libnames) do begin + {$ifdef FPC} + result:= loadlibrary(libnames[int1]); + {$else} + result:= loadlibrary(pansichar(string(libnames[int1]))); + {$endif} + if result <> 0 then begin + libname:= libnames[int1]; + break; + end; + {$ifdef linux} + p1:= dlerror(); + additem(ar1,string(p1)); + {$endif} + end; + if (result = 0) and not noexception then begin + s1:= ansistring(errormessage+ + 'Library '+quotelibnames(libnames)+' not found.'); + {$ifdef linux} + if ar1 <> nil then begin + s1:= s1+lineend+concatstrings(ar1,lineend); + end; + {$endif} + raise exception.create(s1); + end; +end; + +function getprocaddresses(const libnames: array of filenamety; + const anames: array of string; const adest: array of ppointer; + const noexception: boolean = false): tlibhandle; overload; +var + mstr1: filenamety; +begin + result:= loadlib(libnames,mstr1); + getprocaddresses(result,anames,adest,noexception); +end; + +function checkprocaddresses(const libnames: array of filenamety; + const anames: array of string; + const adest: array of ppointer): boolean; +var + int1: integer; +begin + for int1:= 0 to high(adest) do begin + adest[int1]^:= nil; + end; + result:= true; + try + getprocaddresses(libnames,anames,adest,true); + except + result:= false; + exit; + end; + for int1:= 0 to high(adest) do begin + if adest[int1]^ = nil then begin + result:= false; + break; + end; + end; +end; + +function checkprocaddresses(const libnames: array of filenamety; + const procedures: array of funcinfoty): boolean; +var + int1: integer; +begin + for int1:= 0 to high(procedures) do begin + procedures[int1].d^:= nil; + end; + result:= true; + try + getprocaddresses(libnames,procedures,true); + except + result:= false; + exit; + end; + for int1:= 0 to high(procedures) do begin + if procedures[int1].d^ = nil then begin + result:= false; + break; + end; + end; +end; + +function quotelibnames(const libnames: array of filenamety): msestring; +var + int1: integer; +begin + result:= ''; + for int1:= 0 to high(libnames) do begin + result:= result+'"'+libnames[int1]+'",'; + end; + if length(result) > 0 then begin + setlength(result,length(result)-1); + end; +end; + +{$ifndef FPC} +const + nilhandle = 0; + +Function UnloadLibrary(Lib : TLibHandle) : Boolean; +begin + result:= freelibrary(lib); +end; +{$endif} + +var + lock: mutexty; + +function adduniqueitem(var dest: pointerarty; const value: pointer): integer; + //returns index +var + int1: integer; +begin + for int1:= 0 to high(dest) do begin + if dest[int1] = value then begin + result:= int1; + exit; + end; + end; + result:= high(dest) + 1; + setlength(dest,result+1); + dest[result]:= value; +end; + +procedure regdynlibinit(var info: dynlibinfoty; const initproc: dynlibprocty); +begin + sys_mutexlock(lock); + adduniqueitem(info.inithooks,pointer({$ifndef FPC}@{$endif}initproc)); + sys_mutexunlock(lock); +end; + +procedure regdynlibdeinit(var info: dynlibinfoty; const initproc: dynlibprocty); +begin + sys_mutexlock(lock); + adduniqueitem(info.deinithooks,pointer({$ifndef FPC}@{$endif}initproc)); + sys_mutexunlock(lock); +end; + +function initializedynlib(var info: dynlibinfoty; + const libnames: array of filenamety; + const libnamesdefault: array of filenamety; + const funcs: array of funcinfoty; + const funcsopt: array of funcinfoty; + const errormessage: msestring = ''; + const callback: dynloadcallbackty = nil; + const noexception: boolean = false; + const callbackdata: pointer = nil): boolean; + //true if all funcsopt found +var + int1: integer; + {$ifdef set8087cw} + wo1: word; + {$endif} +begin + with info do begin + sys_mutexlock(lock); + try + result:= false; + if refcount = 0 then begin + if (high(libnames) >= 0) or (high(libnamesdefault) >= 0) then begin + {$ifdef set8087cw} + wo1:= get8087cw; + {$endif} + if (high(libnames) >= 0) then begin + libhandle:= loadlib(libnames,libname,errormessage,noexception); + end + else begin + libhandle:= loadlib(libnamesdefault,libname,errormessage,noexception); + end; + if libhandle <> nilhandle then begin + {$ifdef set8087cw} + cw8087:= get8087cw; + set8087cw(wo1); + {$endif} + try + result:= getprocaddresses(libhandle,funcs,noexception); + if not result then begin + if unloadlibrary(libhandle) then begin + libhandle:= nilhandle; + end; + exit; + end; + except + on e: exception do begin + e.message:= ansistring( + errormessage+'Library "'+libname+'": '+msestring(e.message)); + if unloadlibrary(libhandle) then begin + libhandle:= nilhandle; + end; + raise; + end; + end; + result:= getprocaddresses(libhandle,funcsopt,true); + end; + end + else begin + {$ifdef set8087cw} + cw8087:= get8087cw; //refresh + {$endif} + end; + if libhandle <> nilhandle then begin + inc(refcount); + for int1:= 0 to high(inithooks) do begin + dynlibprocty(inithooks[int1])(info); + end; + if ({$ifndef FPC}@{$endif}callback <> nil) then begin + callback(callbackdata); + end; + end; + end + else begin + inc(refcount); + end; + finally + sys_mutexunlock(lock); + end; + end; +end; + +procedure releasedynlib(var info: dynlibinfoty; + const callback: dynloadcallbackty = nil; + const nodlunload: boolean = false; + const callbackdata: pointer = nil); +var + int1: integer; +begin + with info do begin + sys_mutexlock(lock); + try + if refcount > 1 then begin + dec(refcount); + end + else begin + if refcount = 1 then begin //not initialized otherwise + try + if {$ifndef FPC}@{$endif}callback <> nil then begin + callback(callbackdata); + end; + for int1:= 0 to high(deinithooks) do begin + dynlibprocty(deinithooks[int1])(info); + end; + finally + if nodlunload then begin + dec(refcount); + end + else begin + if (libhandle = nilhandle) or unloadlibrary(libhandle) then begin + dec(refcount); + libhandle:= nilhandle; + end; + end; + end; + end; + end; + finally + sys_mutexunlock(lock); + end; + end; +end; + +procedure initializelibinfo(var info: dynlibinfoty); +begin + sys_mutexcreate(lock); + with info do begin + libname:= ''; + refcount:= 0; + libhandle:= 0; + end; +end; + +procedure finalizelibinfo(var info: dynlibinfoty); +begin + with info do begin + end; +end; + +procedure dynloadlock; +begin + sys_mutexlock(lock); +end; + +procedure dynloadunlock; +begin + sys_mutexunlock(lock); +end; + +initialization + sys_mutexcreate(lock); +finalization + sys_mutexdestroy(lock); +end. \ No newline at end of file diff --git a/mseide-msegui/lib/common/kernel/mseerr.pas b/mseide-msegui/lib/common/kernel/mseerr.pas new file mode 100644 index 0000000..13a5f33 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseerr.pas @@ -0,0 +1,61 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseerr; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +//helpers for errormessages +interface + +uses + SysUtils; + +type + eerror = class(exception) + protected + ferror: integer; + public + text: string; + constructor create(error: integer; atext: string; + const errortexts: array of string); + property error: integer read ferror; + end; + +implementation +uses + msetypes{msestrings}; + +{ eerror } + +constructor eerror.create(error: integer; atext: string; + const errortexts: array of string); +var + ch1: char; +begin + ferror:= error; + text:= atext; + if text = '' then begin + inherited create(errortexts[error]+'.'); + end + else begin + text:= errortexts[error]+ ' ' + text; + ch1:= text[length(text)]; + if (ch1 <> '.') and (ch1 <> c_return) and (ch1 <> c_linefeed) then begin + text:= text + '.'; + end; + inherited create(text); + end; +end; + +end. + + + + + diff --git a/mseide-msegui/lib/common/kernel/mseevent.pas b/mseide-msegui/lib/common/kernel/mseevent.pas new file mode 100644 index 0000000..4fb8cc2 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseevent.pas @@ -0,0 +1,440 @@ +{ MSEgui Copyright (c) 1999-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseevent; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + mselist,mseglob,msegraphutils,msekeyboard,msetypes,msestrings,msesystypes; + +const +// eta_timer = 1; //tags for userevents + eta_release = 2; + +type + eventkindty = (ek_none,ek_focusin,ek_focusout,ek_checkapplicationactive, + ek_enterwindow,ek_leavewindow, + ek_buttonpress,ek_buttonrelease,ek_mousewheel, + ek_mousemove,ek_mousepark, + ek_mouseenter,ek_mouseleave,ek_mousecaptureend, + ek_clientmouseenter,ek_clientmouseleave, + ek_expose,ek_configure,ek_reparent, + ek_terminate,ek_abort,ek_destroy,ek_show,ek_hide,ek_close, + ek_activate,ek_loaded, + ek_keypress,ek_keyrelease,ek_timer,ek_wakeup, + ek_release,{ek_releasedefer,}ek_closeform,ek_checkscreenrange, + ek_childscaled,ek_resize, + ek_dropdown,ek_async,ek_execute,ek_object,ek_component, + ek_asyncexec,ek_releaseobject, + ek_connect, + ek_dbedit,ek_dbupdaterowdata,ek_data,ek_objectdata,ek_childproc, + ek_dbinsert, //for tdscontroller + ek_sysdnd,ek_sysdndstatus, + ek_mse, + ek_user); +const + mouseregionevents = [ek_mousepark,ek_mouseenter,ek_mouseleave, + ek_mousecaptureend, + ek_clientmouseenter,ek_clientmouseleave]; + mouseposevents = [ek_buttonpress,ek_buttonrelease,ek_mousemove,ek_mousepark]; + waitignoreevents = [ek_keypress,ek_buttonpress,ek_mousewheel]; + +type + eventstatety = (es_processed,es_child,es_parent,es_preview,es_client, + es_transientfor, //mousewheel from upper modal window + es_local,es_broadcast,es_modal,es_drag,es_objectpicking, + es_reflected,es_nofocus,es_designcall); + eventstatesty = set of eventstatety; + + tmseevent = class(tnullinterfacedobject) + private + protected + fkind: eventkindty; + procedure internalfree1; virtual; + public + constructor create(const akind: eventkindty); + property kind: eventkindty read fkind; + procedure free1; //do nothing for ownedevents + end; + + eventarty = array of tmseevent; + eventaty = array[0..0] of tmseevent; + peventaty = ^eventaty; + + tstringevent = class(tmseevent) + private + fdata: ansistring; + public + constructor create(const adata: string); + property data: ansistring read fdata write fdata; + end; + + tobjectevent = class; + + ievent = interface(iobjectlink) + procedure receiveevent(const event: tobjectevent); + end; + + objeventstatety = (oes_islinked,oes_modaldeferred); + objeventstatesty = set of objeventstatety; + + tobjectevent = class(tmseevent,iobjectlink) + private + finterface: pointer; //ievent; + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + protected + fstate: objeventstatesty; + fmodallevel: integer; + public + constructor create(akind: eventkindty; const dest: ievent; + const modaldefer: boolean = false); + destructor destroy; override; + procedure deliver; + property modallevel: integer read fmodallevel; + end; + + tchildprocevent = class(tobjectevent) + public + prochandle: prochandlety; + execresult: integer; + data: pointer; + constructor create(const dest: ievent; const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); + end; + + tstringobjectevent = class(tobjectevent) + private + public + data: ansistring; + constructor create(const adata: ansistring; const dest: ievent); +// property data: ansistring read fdata write fdata; + end; + + tpointobjectevent = class(tobjectevent) + private + public + data: pointty; + constructor create(const adata: pointty; const dest: ievent); + // property data: pointty read fdata write fdata; + end; + + tuserevent = class(tobjectevent) + ftag: integer; + public + constructor create(const dest: ievent; tag: integer; + const amodaldefer: boolean = false); + property tag: integer read ftag; + end; + + tasyncevent = class(tuserevent) + constructor create(const dest: ievent; atag: integer; + const amodaldefer: boolean = false); + end; + + texecuteevent = class(tmseevent) + protected + procedure execute(); virtual; abstract; + public + constructor create(); + procedure deliver(); virtual; + end; + + tcustomeventqueue = class(tobjectqueue) + end; + + teventqueue = class(tcustomeventqueue) + private + fsem: semty; + fmutex: mutexty; + fdestroying: boolean; + public + constructor create(aownsobjects: boolean); + destructor destroy; override; + procedure lock(); + procedure unlock(); + procedure clear; override; + procedure post(event: tmseevent); + procedure post(const events: tcustomeventqueue); //transfer items + function wait(const timeoutus: integer = 0): tmseevent; + // -1 infinite, 0 no block, can return nil + end; + +implementation +uses + msesysintf1,mseapplication; +type + tapplication1 = class(tcustomapplication); + +{ tmseevent } + +constructor tmseevent.create(const akind: eventkindty); +begin + fkind:= akind; +end; + +procedure tmseevent.free1; +begin + if (self <> nil) then begin + internalfree1; + end; +end; + +procedure tmseevent.internalfree1; +begin + self.destroy; +end; + +{ tstringevent } + +constructor tstringevent.create(const adata: string); +begin + fdata:= adata; + inherited create(ek_data); +end; + +{ tobjectevent } + +constructor tobjectevent.create(akind: eventkindty; const dest: ievent; + const modaldefer: boolean = false); +{$ifndef FPC} +var + po1: pointer; +{$endif} +begin + finterface:= pointer(dest); + fmodallevel:= -1; +// if akind = ek_releasedefer then begin + if modaldefer then begin + include(fstate,oes_modaldeferred); + end; + if (finterface <> nil) then begin + if application.islockedthread() then begin + include(fstate,oes_islinked); + {$ifndef FPC} + po1:= pointer(1); + ievent(finterface).link(iobjectlink(po1),iobjectlink(self)); + {$else} + ievent(finterface).link(iobjectlink(pointer(1)),iobjectlink(self)); + {$endif} + end; + end; + inherited create(akind); +end; + +destructor tobjectevent.destroy; +{$ifndef FPC} +var + po1: pointer; +{$endif} +begin + if (fmodallevel >= 0) then begin + tapplication1(application).objecteventdestroyed(self); + end; + if (oes_islinked in fstate) and (finterface <> nil) then begin +{$ifndef FPC} + po1:= pointer(1); + ievent(finterface).unlink(iobjectlink(po1),iobjectlink(self)); +{$else} + ievent(finterface).unlink(iobjectlink(pointer(1)),iobjectlink(self)); +{$endif} + end; + inherited; +end; + +procedure tobjectevent.deliver; +begin + if finterface <> nil then begin + ievent(finterface).receiveevent(self); + end; +end; + +procedure tobjectevent.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + if event = oe_destroyed then begin + finterface:= nil; + end; +end; + +function tobjectevent.getinstance: tobject; +begin + result:= self; +end; + +procedure tobjectevent.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + //dummy +end; + +procedure tobjectevent.unlink(const source,dest: iobjectlink; + valuepo: pointer = nil); +begin + //dummy +end; + +{ tstringobjectevent } + +constructor tstringobjectevent.create(const adata: ansistring; const dest: ievent); +begin + data:= adata; + inherited create(ek_objectdata,dest); +end; + +{ tpointobjectevent } + +constructor tpointobjectevent.create(const adata: pointty; const dest: ievent); +begin + data:= adata; + inherited create(ek_objectdata,dest); +end; + +{ tuserevent } + +constructor tuserevent.create(const dest: ievent; tag: integer; + const amodaldefer: boolean = false); +begin + ftag:= tag; + inherited create(ek_user,dest,amodaldefer); +end; + +{ tasyncevent } + +constructor tasyncevent.create(const dest: ievent; atag: integer; + const amodaldefer: boolean = false); +begin + inherited; + fkind:= ek_async; +end; + +{ texecuteevent } + +constructor texecuteevent.create; +begin + inherited create(ek_asyncexec); +end; + +procedure texecuteevent.deliver; +begin + execute(); +end; + +{ teventqueue } + +constructor teventqueue.create(aownsobjects: boolean); +begin + sys_semcreate(fsem,0); + sys_mutexcreate(fmutex); + inherited; +end; + +destructor teventqueue.destroy; +begin + fdestroying:= true; + while sys_semcount(fsem) < 0 do begin + sys_sempost(fsem); + end; + sys_semdestroy(fsem); + sys_mutexdestroy(fmutex); + inherited; +end; + +procedure teventqueue.lock(); +begin + sys_mutexlock(fmutex); +end; + +procedure teventqueue.unlock(); +begin + sys_mutexunlock(fmutex); +end; + +procedure teventqueue.post(event: tmseevent); +begin + sys_mutexlock(fmutex); + if not fdestroying then begin + add(event); + end; + sys_mutexunlock(fmutex); + sys_sempost(fsem); +end; + +procedure teventqueue.post(const events: tcustomeventqueue); +begin + events.normalizering(); + sys_mutexlock(fmutex); + if not fdestroying then begin + tpointerlist(self).add(ppointer(pointer(events.fitems)),events.fcount); + end; + events.fcount:= 0; + sys_mutexunlock(fmutex); + sys_sempost(fsem); +end; + +function teventqueue.wait(const timeoutus: integer = 0): tmseevent; + + function get(out item: tmseevent): boolean; + begin + sys_mutexlock(fmutex); + item:= nil; + result:= not fdestroying; + if result then begin + if fcount > 0 then begin + item:= tmseevent(getfirst); + end; + end; + sys_mutexunlock(fmutex); + end; + +begin + if get(result) and (result = nil) then begin + if timeoutus = 0 then begin + if sys_semtrywait(fsem) then begin + get(result); + end; + end + else begin + if sys_semwait(fsem,0) = sye_ok then begin + get(result); + end; + end; + end; +end; + +procedure teventqueue.clear; +begin + if not fdestroying then begin + sys_mutexlock(fmutex); + inherited; + sys_mutexunlock(fmutex); + end + else begin + inherited; + end; +end; + +{ tchildprocevent } + +constructor tchildprocevent.create(const dest: ievent; + const aprochandle: prochandlety; const aexecresult: integer; + const adata: pointer); +begin + prochandle:= aprochandle; + execresult:= aexecresult; + data:= adata; + inherited create(ek_childproc,dest); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msefileutils.pas b/mseide-msegui/lib/common/kernel/msefileutils.pas new file mode 100644 index 0000000..e664998 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msefileutils.pas @@ -0,0 +1,2254 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefileutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msesysintf,msearrayutils,msedatalist,msesystypes,msesys,msebits,msetypes, + msestream,msestrings; + +type + filelistoptionty = (flo_sortname,flo_sorttime,flo_sortsize, + flo_sorttype,flo_casesensitive,flo_downsort); + filelistoptionsty = set of filelistoptionty; + filekindty = (fk_default,fk_file,fk_dir); + + filechangety = (fc_name,fc_attributes,fc_modtime,fc_accesstime,fc_ctime, + fc_size,fc_removed,fc_direntries,fc_force); + filechangesty = set of filechangety; + checkfileeventty = procedure (const sender: tobject; + const streaminfo: dirstreaminfoty; + const fileinfo: fileinfoty; + var accept: boolean) of object; + //default true + pathrelocateoptionty = (pro_preferenew,pro_onlynew,pro_rootpath); + pathrelocateoptionsty = set of pathrelocateoptionty; + +const + sortflags: filelistoptionsty = [flo_sortname,flo_sorttime,flo_sortsize]; + intermediatefileextension = '.tmp'; +type + filesortfuncty = function(const l,r: fileinfoty): integer of object; + + tcustomfiledatalist = class(tdynamicdatalist) + private + foptions: filelistoptionsty; + fsortfunc: filesortfuncty; + function getitems(index: integer): fileinfoty; + procedure setoptions(const Value: filelistoptionsty); + function sortname(const l,r: fileinfoty): integer; + function sorttime(const l,r: fileinfoty): integer; + function sortsize(const l,r: fileinfoty): integer; + protected + procedure freedata(var data); override; + procedure beforecopy(var data); override; + function compare(const l,r): integer; override; + public + constructor create; override; + function add(const value: fileinfoty): integer; + function adddirectory(const directoryname: filenamety; + ainfolevel: fileinfolevelty = fil_name; const amask: filenamearty = nil; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; overload; + //amask = nil -> all, true if ok + function adddirectory(const directoryname: filenamety; + ainfolevel: fileinfolevelty; const amask: filenamety; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; overload; + //amask = '' -> all, true if ok + {$ifndef FPC} + function adddirectory1(const directoryname: filenamety; + ainfolevel: fileinfolevelty = fil_name; const amask: filenamearty = nil; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; + //amask = nil -> all, true if ok + function adddirectory2(const directoryname: filenamety; + ainfolevel: fileinfolevelty; const amask: filenamety; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; + //amask = '' -> all, true if ok + {$endif} + function itempo(const index: integer): pfileinfoty; + //invalid after capacity change! + function indexof(const filename: filenamety): integer; + //case sensitive + function isdir(index: integer): boolean; + property items[index: integer]: fileinfoty read getitems; default; + property options: filelistoptionsty read foptions write setoptions default []; + end; + + tfiledatalist = class(tcustomfiledatalist) + published + property options; + end; + +function quotefilename(const name: filenamety): filenamety; overload; +function quotefilename(const directory,name: filenamety): filenamety; overload; +function quotefilename(const names: filenamearty): filenamety; overload; +function quotefilename(const names: array of filenamety): filenamety; overload; +procedure unquotefilename(const names: filenamety; + var result: filenamearty); overload; +function unquotefilename(const name: filenamety): filenamety; overload; +function extractrootpath(var names: filenamearty): filenamety; +function combinerootpath(const rootpath: filenamety; + const names: filenamearty): filenamearty; overload; +function combinerootpath(const rootpaths: filenamearty; + const name: filenamety): filenamearty; overload; + +function syscommandline(const acommandline: filenamety): filenamety; + //converts exec path to sys format +function filepath({const} directory: filenamety; {const} filename: filenamety; + kind: filekindty = fk_default; + relative: boolean = false): filenamety; overload; + //directory ignored if filename starts with root + //"~/....." expands to sys_getuserhomedir()/..... + //"^/....." expands to sys_getapphomedir()/..... + +function filepath({const} path: filenamety; + kind: filekindty = fk_default; + relative: boolean = false): filenamety; overload; +function relativepath(const path: filenamety; const root: filenamety = ''; + const kind: filekindty = fk_default): filenamety; + //root = '' -> currentdir +function relocatepath(const olddir,newdir: filenamety; + var apath: filenamety; + const options: pathrelocateoptionsty = []): boolean; +//searches file in newdir relative to olddir or in original position, +//updates apath, returns true if found +function isrelativepath(const path: filenamety): boolean; +function isrootdir(const path: filenamety): boolean; +function removelastpathsection(path: filenamety): filenamety; +function getlastpathsection(const path: filenamety): filenamety; +function removelastdir(path: filenamety; var newpath: filenamety): filenamety; +procedure splitfilepath(const path: filenamety; + out directory,filename: filenamety); overload; +procedure splitfilepath(const path: filenamety; + out directory,filename,fileext: filenamety); overload; +function splitfilepath(const path: filenamety): filenamearty; +function splitrootpath(const path: filenamety): filenamearty; +function mergerootpath(const segments: filenamearty): filenamety; + +function checkfilename(const filename,mask: filenamety; + casesensitive: boolean = false): boolean; overload; + //true if filename fits mask, maskchars: '*','?' +function checkfilename(const filename: filenamety; const mask: filenamearty; + casesensitive: boolean = false): boolean; overload; +function checkfilename(const filename: filenamety; + const dirstream: dirstreamty): boolean; overload; +function hasmaskchars(const filename: filenamety): boolean; +function issamefilename(const a,b: filenamety): boolean; +function issamefilepath(const a,b: filenamety): boolean; + +function filename(const path: filenamety): filenamety; +function filedir(const path: filenamety): filenamety; +function filenamebase(const path: filenamety): filenamety; //without ext +function fileext(const path: filenamety): filenamety; +function removefileext(const path: filenamety): filenamety; +function hasfileext(const path: filenamety): boolean; +function checkfileext(const path: filenamety; const extensions: array of filenamety): boolean; +function replacefileext(const path,newext: filenamety): filenamety; + +function tomsefilepath(const path: filenamety; + const quoted: boolean = false): filenamety; +procedure tomsefilepath1(var path: filenamety; const quoted: boolean = false); +function tosysfilepath(const path: filenamety; + const quoted: boolean = false): filenamety; +function tosysfilepath(const path: filenamearty; + const quoted: boolean = false): filenamearty; +procedure tosysfilepath1(var path: filenamety; const quoted: boolean = false); + +function searchfile(const filename: filenamety; dir: boolean = false; + const aoptions: dirstreamoptionsty = []): filenamety; overload; + //returns rootpath if file exists, '' otherwise +function searchfile(const afilename: filenamety; + const adirnames: array of filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamety; overload; + //returns directory of last occurence in dirs, '' if none + //afilename can be path and can have wildchars ('?','*'), + //adirnames can have wildchars ('?','*','**','***') + //'?' -> any char + //'*' -> any chars + //'**' -> 1..x directory levels + //'***' -> 0..x directory levels +function searchfile(const afilename: filenamety; const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamety; overload; + //returns directory, '' if none + //afilename must be simple filename and can have wildchars ('?','*'), + //adirname can have wildchars ('?','*','**','***') + +function searchfiles(const afilename: filenamety; + const adirnames: array of filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; overload; + //returns filepaths + //afilename can be path or quoted list of paths + //and can have wildchars ('?','*') example: '"a/*.pas" "b/*.pp"', + //adirnames can have wildchars ('?','*','**','***') +function searchfiles(const afilename: filenamety; + const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; overload; + //returns filepaths + //afilename must be simple filename or quoted list of simple filenames + //and can have wildchars ('?','*') example: '"*.pp" "*.pas"', + //adirname can have wildchars ('?','*','**','***') + +function searchfilenames(const afilename: filenamety; const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; + //returns filenames + //afilename must be simple filename or quoted list of simple filenames + //and can have wildchars ('?','*') example: '"*.pp" "*.pas"', + //empty -> all + +function dirhasentries(const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []): boolean; + +function findfile(filename: filenamety; //no const bcause of var path param + const dirnames: array of filenamety; + var path: filenamety): boolean; overload; + //no out because of caller side finalization + //true if found, path not touched if not found +function findfile(filename: filenamety; //no const bcause of var path param + var path: filenamety): boolean; overload; + //no out because of caller side finalization + //true if found, path not touched if not found +function findfile(const filename: filenamety; const dirnames: + array of filenamety): boolean; overload; +function findfile(const filename: filenamety): boolean; overload; +function finddir(const filename: filenamety): boolean; +function findfileordir(const filename: filenamety): boolean; +function uniquefilename(const path: filenamety): filenamety; + //adds numbers if necessary + +function isrootpath(const path: filenamety): boolean; +function copyfile(const oldfile,newfile: filenamety; + const canoverwrite: boolean = true): boolean; + //false if newfile exists and not canoverwrite +function trycopyfile(const oldfile,newfile: filenamety; + const canoverwrite: boolean = true): boolean; + //false on error or newfile exists and not canoverwrite +function renamefile(const oldname,newname: filenamety; + const canoverwrite: boolean = true): boolean; + //false if newname exists and not canoverwrite +function deletefile(const filename: filenamety): boolean; + //false if not existing +function trydeletefile(const filename: filenamety): boolean; + //false if not existing or not deleted +procedure createdir(const path: filenamety; + const rights: filerightsty = defaultdirrights); +procedure createdirpath(const path: filenamety; + const rights: filerightsty = defaultdirrights); +function deletedir(const path: filenamety): boolean; + //deletes files and directories recursively, false if not existing +function trydeletedir(const path: filenamety): boolean; + //deletes files and directories recursively, + // false if not existing or not deleted +function getcurrentdir: filenamety; deprecated; +function getcurrentdirmse: filenamety; +function setcurrentdir(const path: filenamety): filenamety; deprecated; +function setcurrentdirmse(const path: filenamety): filenamety; +function trysetcurrentdirmse(const path: filenamety): boolean; overload; +function trysetcurrentdirmse(const path: filenamety; + out pathbefore: msestring): boolean; overload; + +procedure clearfileinfo(var info: fileinfoty); +procedure initdirfileinfo(var info: fileinfoty; const aname: filenamety; + open: boolean = false); +function getfileinfo(const path: filenamety; var info: fileinfoty): boolean; + //false if not found +function getfilemodtime(const path: filenamety): tdatetime; + //empty date if not found + +function filesystemiscaseinsensitive: boolean; + +function compfileinfos(const info1,info2: fileinfoty): filechangesty; +function compfiletime(const a,b: tdatetime): integer; + //-1 if a < b, 0 if a = b, 1 if a > b + +function intermediatefilename(const aname: filenamety): filenamety; +function msegettempdir: filenamety; +function msegettempfilename(const aname: filenamety): filenamety; + +implementation +uses + sysutils,msedate,mseprocutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + quotechar = msechar('"'); + slashchar = msechar('/'); + dotchar = msechar('.'); + +type + checkmaskresultty = (cmr_correct,cmr_wrong,cmr_wrongfinished,cmr_correctfinished); +const + checkmaskfinished = cmr_wrongfinished; + +function msegettempdir: filenamety; +begin + result:= sys_gettempdir; +end; + +function msegettempfilename(const aname: filenamety): filenamety; +begin + result:= intermediatefilename(filepath(msegettempdir,aname,fk_file)); +end; + +function intermediatefilename(const aname: filenamety): filenamety; +var + fname1,fname2: filenamety; + int1: integer; +begin + fname1:= aname + intermediatefileextension + inttostrmse(getpid); + fname2:= fname1; + int1:= 0; + while findfile(fname2) do begin + inc(int1); + fname2:= fname1 + '_'+inttostrmse(int1); + end; + result:= fname2; +end; + +procedure commitstreamtransaction(const astream: tmsefilestream; + const aname: filenamety); +var + fname1: filenamety; +begin + astream.flush; + fname1:= astream.filename; + astream.close; + msefileutils.renamefile(fname1,aname); +end; + +function compfiletime(const a,b: tdatetime): integer; + //-1 if a < b, 0 if a = b, 1 if a > b +const + deltamin = 1/(24*60*60*1000); //1 ms + +var + rea1: real; +begin + result:= 0; + rea1:= a - b; + if rea1 < -deltamin then begin + result:= -1; + end + else begin + if rea1 > deltamin then begin + result:= 1; + end; + end; +end; + +function compfileinfos(const info1,info2: fileinfoty): filechangesty; +begin + result:= []; + if info1.name <> info2.name then include(result,fc_name); + if info1.extinfo1.attributes <> info2.extinfo1.attributes then include(result,fc_attributes); + if compfiletime(info1.extinfo1.modtime,info2.extinfo1.modtime) <> 0 then include(result,fc_modtime); + if compfiletime(info1.extinfo1.accesstime,info2.extinfo1.accesstime) <> 0 then include(result,fc_accesstime); + if compfiletime(info1.extinfo1.ctime,info2.extinfo1.ctime) <> 0 then include(result,fc_ctime); + if info1.extinfo1.size <> info2.extinfo1.size then include(result,fc_size); +end; + +procedure clearfileinfo(var info: fileinfoty); +begin + finalize(info); + fillchar(info,sizeof(info),0); +end; + +procedure initdirfileinfo(var info: fileinfoty; const aname: filenamety; open: boolean = false); +begin + clearfileinfo(info); + with info do begin + name:= aname; + if open then begin + state:= [fis_typevalid,fis_diropen]; + end + else begin + state:= [fis_typevalid]; + end; + extinfo1.filetype:= ft_dir; + end; +end; + +function getfileinfo(const path: filenamety; var info: fileinfoty): boolean; + //false if not found +begin + result:= sys_getfileinfo(path,info); +end; + +function getfilemodtime(const path: filenamety): tdatetime; + //empty date if not found +var + info1: fileinfoty; +begin + if getfileinfo(path,info1) then begin + result:= info1.extinfo1.modtime; + end + else begin + result:= emptydatetime; + end; +end; + +function copyfile(const oldfile,newfile: filenamety; + const canoverwrite: boolean = true): boolean; + //false if dest exists and not canoverwrite + //todo: remove race condition +begin + if not canoverwrite and findfile(newfile) then begin + result:= false; + end + else begin + result:= true; + syserror(sys_copyfile(oldfile,newfile), + 'Can not copy File "'+oldfile+'" to "'+newfile+'": '); + end; +end; + +function trycopyfile(const oldfile,newfile: filenamety; + const canoverwrite: boolean = true): boolean; + //false if dest exists and not canoverwrite +begin + //todo: remove race condition + if not canoverwrite and findfile(newfile) then begin + result:= false; + end + else begin + result:= sys_copyfile(oldfile,newfile) = sye_ok; + end; +end; + +function renamefile(const oldname,newname: filenamety; + const canoverwrite: boolean = true): boolean; + //false if newname exists and not canoverwrite +begin + if not canoverwrite and findfile(newname) then begin + result:= false; + end + else begin + result:= true; + syserror(sys_renamefile(oldname,newname), + 'Can not rename File "'+oldname+'" to "'+newname+'": '); + end; +end; + +function deletefile(const filename: filenamety): boolean; + //false if not existing +var + err: syserrorty; +begin + err:= sys_deletefile(filename); + result:= err = sye_ok; + if not result and findfile(filename) then begin + syserror(err,'Can not delete file "'+filename+'".'); + end; +end; + +function trydeletefile(const filename: filenamety): boolean; + //false if not existing or not deleted +begin + result:= sys_deletefile(filename) = sye_ok; +end; + +function deletefilesanddir(const path: filenamety): syserrorty; +var + ar1: filenamearty; + i1: int32; +begin + ar1:= searchfilenames('',path,[fa_all],[fa_dir]); + for i1:= 0 to high(ar1) do begin + result:= sys_deletefile(path+'/'+ar1[i1]); + if result <> sye_ok then begin + exit; + end; + end; + ar1:= searchfilenames('',path,[fa_dir]); + for i1:= 0 to high(ar1) do begin + result:= deletefilesanddir(path+'/'+ar1[i1]); + if result <> sye_ok then begin + exit; + end; + end; + result:= sys_deletedir(path); +end; + +function deletedir(const path: filenamety): boolean; + //deletes files and directories recursively, false if not existing +var + err: syserrorty; +begin + err:= deletefilesanddir(path); + result:= err = sye_ok; + if not result and finddir(path) then begin + syserror(err,'Can not delete dir "'+path+'". '); + end; +end; + +function trydeletedir(const path: filenamety): boolean; + //deletes files and directories recursively, + // false if not existing or not deleted +begin + result:= deletefilesanddir(path) = sye_ok; +end; + +procedure createdir(const path: filenamety; + const rights: filerightsty = defaultdirrights); +begin +// syserror(sys_createdir(tosysfilepath(path))); + syserror(sys_createdir(path,rights)); +end; + +procedure createdirpath(const path: filenamety; + const rights: filerightsty = defaultdirrights); +var + ar1: filenamearty; + mstr1: filenamety; + int1: integer; +begin + ar1:= splitrootpath(path); + mstr1:= ''; + for int1:= 0 to high(ar1) do begin + mstr1:= mstr1+slashchar+ar1[int1]; + if not finddir(mstr1) then begin + createdir(mstr1,rights); + end; + end; +end; + +function getcurrentdirmse: filenamety; +begin + result:= sys_getcurrentdir; +end; + +function getcurrentdir: filenamety; +begin + result:= getcurrentdirmse; +end; + +function setcurrentdirmse(const path: filenamety): filenamety; +var + error: syserrorty; +begin + result:= sys_getcurrentdir; + error:= sys_setcurrentdir(path); + if error <> sye_ok then begin + syserror(error,'Setcurrentdir "'+ path + quotechar+':'+lineend); + end; +end; + +function trysetcurrentdirmse(const path: filenamety; + out pathbefore: filenamety): boolean; +begin + pathbefore:= sys_getcurrentdir; + result:= sys_setcurrentdir(path) = sye_ok; +end; + +function trysetcurrentdirmse(const path: filenamety): boolean; +begin + result:= sys_setcurrentdir(path) = sye_ok; +end; + +function setcurrentdir(const path: filenamety): filenamety; +begin + result:= setcurrentdirmse(path); +end; + +function remquote(const path: filenamety): filenamety; +begin + if pmsechar(path)^ = quotechar then begin + result:= copy(path,2,bigint); + end + else begin + result:= path; + end; +end; + +procedure requote(var path: filenamety; const newvalue: filenamety); +begin + if pmsechar(path)^ = quotechar then begin + path:= quotechar + newvalue; + end + else begin + path:= newvalue; + end; +end; + +function isrootpath(const path: filenamety): boolean; +var + str1: filenamety; +begin + str1:= remquote(path); + tomsefilepath1(str1); + result:= (length(str1) > 0) and (str1[1] = slashchar); +end; + +procedure checkmask(s: pmsechar; mask: pmsechar; var result: checkmaskresultty); +var + po1: pmsechar; +begin + while true do begin + if s^ = #0 then begin + if mask^ = #0 then begin + result:= cmr_correctfinished; + break; + end; + end; + case mask^ of + '*': begin + po1:= mask + 1; + if po1^ = #0 then begin + result:= cmr_correctfinished; + break; + end; + while true do begin + checkmask(s,po1,result); + if (result = cmr_correctfinished) or (s^ = #0) then begin + break; + end; + inc(s); + result:= cmr_correct; + end; + break; + end; + '?': begin + if s^ = #0 then begin + result:= cmr_wrongfinished; + break; + end; + inc(s); + inc(mask); + end; + #0: begin + result:= cmr_wrongfinished; + break; + end; + else begin + if s^ = mask^ then begin + inc(s); + inc(mask); + continue; + end + else begin + result:= cmr_wrong; + break; + end; + end; + end; + end; +end; + +function internalcheckfilename(const filename,mask: filenamety): boolean; +var + checkresult: checkmaskresultty; +begin + checkresult:= cmr_correct; + checkmask(pmsechar(filename),pmsechar(mask),checkresult); + result:= checkresult = cmr_correctfinished; +end; + +function checkfilename(const filename,mask: filenamety; + casesensitive: boolean = false): boolean; + //'*' and '?' are possible maskchars +var + str1,str2: msestring; +begin + if casesensitive then begin + result:= internalcheckfilename(filename,mask); + end + else begin + str1:= mseuppercase(filename); + str2:= mseuppercase(mask); + result:= internalcheckfilename(str1,str2); + end; +end; + +function checkfilename(const filename: filenamety; const mask: filenamearty; + casesensitive: boolean = false): boolean; +var + str1,str2: msestring; + int1: integer; +begin + if mask = nil then begin + result:= true; + end + else begin + result:= false; + if casesensitive then begin + for int1:= 0 to high(mask) do begin + if internalcheckfilename(filename,mask[int1]) then begin + result:= true; + break; + end; + end; + end + else begin + str1:= mseuppercase(filename); + for int1:= 0 to high(mask) do begin + str2:= mseuppercase(mask[int1]); + if internalcheckfilename(str1,str2) then begin + result:= true; + break; + end; + end; + end; + end; +end; + +function checkfilename(const filename: filenamety; + const dirstream: dirstreamty): boolean; + //mask must be uppercase if case sensitive +var + str1{,str2}: msestring; + int1: integer; +begin + with dirstream,dirinfo do begin + if mask = nil then begin + result:= true; + end + else begin + result:= false; + if caseinsensitive then begin + str1:= mseuppercase(filename); + for int1:= 0 to high(mask) do begin + if internalcheckfilename(str1,mask[int1]) then begin + result:= true; + break; + end; + end; + end + else begin + for int1:= 0 to high(mask) do begin + if internalcheckfilename(filename,mask[int1]) then begin + result:= true; + break; + end; + end; + end; + end; + end; +end; + +function hasmaskchars(const filename: filenamety): boolean; +begin + if msestrscan(pmsechar(filename),msechar('*')) = nil then begin + result:= msestrscan(pmsechar(filename),msechar('?')) <> nil; + end + else begin + result:= true; + end; +end; + +function filesystemiscaseinsensitive: boolean; +begin + result:= sys_filesystemiscaseinsensitive; +end; + +function issamefilename(const a,b: filenamety): boolean; +begin + if filesystemiscaseinsensitive then begin + result:= msecomparetext(filepath(a),filepath(b)) = 0; + end + else begin + result:= filepath(a) = filepath(b); + end; +end; + +function issamefilepath(const a,b: filenamety): boolean; +begin + result:= issamefilename(filepath(a),filepath(b)); +end; + +function searchfile(const filename: filenamety;dir: boolean = false; + const aoptions: dirstreamoptionsty = []): filenamety; overload; + //returns rootpath if file exists, '' otherwise +begin + result:= filepath(filename); + if not (dir and finddir(result) or + not dir and findfile(result)) then begin + result:= ''; + end; +end; + +function searchfile(const afilename: filenamety; const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamety; +var + ar1{,ar2}: filenamearty; + int1: integer; + dirstream: dirstreamty; + fileinfo: fileinfoty; + recursive: boolean; + fna1: filenamety; +begin + result:= ''; + ar1:= nil; //compiler warning + fillchar(dirstream,sizeof(dirstream),0); + if hasmaskchars(adirname) then begin + recursive:= false; + ar1:= splitrootpath(adirname); + for int1:= 0 to high(ar1) do begin + if hasmaskchars(ar1[int1]) then begin + with dirstream,dirinfo do begin + if int1 > 0 then begin + dirname:= mergerootpath(copy(ar1,0,int1)); + end + else begin + dirname:= slashchar; + end; + if ar1[int1] = '***' then begin + deleteitem(ar1,int1); + result:= searchfile(afilename,mergerootpath(ar1), + ainclude,aexclude,aoptions); + if result <> '' then begin + break; + end; + insertitem(ar1,int1,'**'); + end; + mask:= copy(ar1,int1,1); + if mask[0] = '**' then begin + recursive:= true; + mask[0]:= '*'; + end; + include:= [fa_dir]; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + fna1:= ar1[int1]; + while sys_readdirstream(dirstream,fileinfo) do begin + if (fileinfo.name <> dotchar) and (fileinfo.name <> '..') then begin + ar1[int1]:= fileinfo.name; + result:= searchfile(afilename,mergerootpath(ar1),ainclude, + aexclude,aoptions); + if result <> '' then begin + break; + end; + if recursive then begin + insertitem(ar1,int1+1,'**'); + result:= searchfile(afilename,mergerootpath(ar1)); + if result <> '' then begin + break; + end; + deleteitem(ar1,int1+1); + end; + end; + end; + ar1[int1]:= fna1; + end; + sys_closedirstream(dirstream); + exit; + end; + end; + end + else begin + with dirstream,dirinfo do begin + dirname:= filepath(adirname,fk_file); + if afilename <> '' then begin + setlength(mask,1); + mask[0]:= afilename; + end; + include:= ainclude; + exclude:= aexclude; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + if sys_readdirstream(dirstream,fileinfo) then begin + result:= filepath(adirname,fk_dir); + end; + sys_closedirstream(dirstream); + end; + end; +end; + +function searchfile(const afilename: filenamety; + const adirnames: array of filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamety; + //returns directory of last occurence in adirnames, '' if none +var + int1: integer; + dir1,file1: filenamety; +begin + result:= ''; + file1:= trim(afilename); + if (file1 <> '') and (high(adirnames) < 0) then begin + splitfilepath(afilename,dir1,file1); + result:= searchfile(file1,dir1,ainclude,aexclude,aoptions); + end + else begin + for int1:= high(adirnames) downto 0 do begin + if afilename = '' then begin + dir1:= adirnames[int1]; + end + else begin + splitfilepath(filepath(adirnames[int1],afilename,fk_file,true),dir1,file1); + end; + result:= searchfile(file1,dir1,ainclude,aexclude,aoptions); + if result <> '' then begin + break; + end; + end; + end; +end; + +function searchfiles(const afilename: filenamety; const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; +var + ar1{,ar2}: filenamearty; + int1,int2: integer; + dirstream: dirstreamty; + fileinfo: fileinfoty; + recursive: boolean; + fna1: filenamety; +begin +// result:= ''; + result:= nil; + ar1:= nil; //compiler warning + fillchar(dirstream,sizeof(dirstream),0); + if hasmaskchars(adirname) then begin + recursive:= false; + ar1:= splitrootpath(adirname); + for int1:= 0 to high(ar1) do begin + if hasmaskchars(ar1[int1]) then begin + with dirstream,dirinfo do begin + if int1 > 0 then begin + dirname:= mergerootpath(copy(ar1,0,int1)); + end + else begin + dirname:= slashchar; + end; + if ar1[int1] = '***' then begin + deleteitem(ar1,int1); + stackarray(searchfiles(afilename,mergerootpath(ar1), + ainclude,aexclude,aoptions),result); + insertitem(ar1,int1,'**'); + end; + mask:= copy(ar1,int1,1); + if mask[0] = '**' then begin + recursive:= true; + mask[0]:= '*'; + end; + include:= [fa_dir]; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + fna1:= ar1[int1]; + while sys_readdirstream(dirstream,fileinfo) do begin + if (fileinfo.name <> dotchar) and (fileinfo.name <> '..') then begin + ar1[int1]:= fileinfo.name; + stackarray(searchfiles(afilename, + mergerootpath(ar1),ainclude,aexclude,aoptions),result); + if recursive then begin + insertitem(ar1,int1+1,'**'); + stackarray(searchfiles(afilename, + mergerootpath(ar1),ainclude,aexclude,aoptions),result); + deleteitem(ar1,int1+1); + end; + end; + end; + ar1[int1]:= fna1; + end; + sys_closedirstream(dirstream); + exit; + end; + end; + end + else begin + with dirstream,dirinfo do begin + dirname:= filepath(adirname,fk_file); + options:= aoptions; + if afilename <> '' then begin + unquotefilename(afilename,mask); +// setlength(mask,1); +// mask[0]:= afilename; + end; + include:= ainclude; + exclude:= aexclude; + infolevel:= fil_type; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + int2:= 0; + while sys_readdirstream(dirstream,fileinfo) do begin + if (fileinfo.extinfo1.filetype <> ft_dir) or + (fileinfo.name <> dotchar) and (fileinfo.name <> '..') then begin + if high(result) < int2 then begin + setlength(result,int2*2+16); + end; + result[int2]:= filepath(dirname,fileinfo.name); + inc(int2); + end; + end; + setlength(result,int2); + sys_closedirstream(dirstream); + end; + end; +end; + +function searchfilenames(const afilename: filenamety; const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; +var + int2: integer; + dirstream: dirstreamty; + fileinfo: fileinfoty; +begin + result:= nil; + fillchar(dirstream,sizeof(dirstream),0); + with dirstream,dirinfo do begin + dirname:= filepath(adirname,fk_file); + options:= aoptions; + if afilename <> '' then begin + unquotefilename(afilename,mask); +// setlength(mask,1); +// mask[0]:= afilename; + end; + include:= ainclude; + exclude:= aexclude; + infolevel:= fil_type; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + int2:= 0; + while sys_readdirstream(dirstream,fileinfo) do begin + if (fileinfo.extinfo1.filetype <> ft_dir) or + (fileinfo.name <> dotchar) and (fileinfo.name <> '..') then begin + if high(result) < int2 then begin + setlength(result,int2*2+16); + end; + result[int2]:= fileinfo.name; + inc(int2); + end; + end; + setlength(result,int2); + sys_closedirstream(dirstream); + end; +end; + +function searchfiles(const afilename: filenamety; + const adirnames: array of filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; +var + int1,i2: integer; + dir1,file1: filenamety; + ar1: filenamearty; +begin + result:= nil; + file1:= trim(afilename); + unquotefilename(file1,ar1); + if (file1 <> '') and (high(adirnames) < 0) then begin + for int1:= 0 to high(ar1) do begin + splitfilepath(ar1[int1],dir1,file1); + stackarray(searchfiles(file1,dir1,ainclude,aexclude,aoptions),result); + end; + end + else begin + for int1:= 0 to high(adirnames) do begin + if afilename = '' then begin + dir1:= adirnames[int1]; + stackarray(searchfiles(file1,dir1,ainclude,aexclude,aoptions),result); + end + else begin + for i2:= 0 to high(ar1) do begin + splitfilepath(filepath(adirnames[int1],ar1[int1],fk_file,true),dir1,file1); + stackarray(searchfiles(file1,dir1,ainclude,aexclude,aoptions),result); + end; + end; + end; + end; +end; + +function dirhasentries(const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []): boolean; +var + dirstream: dirstreamty; + fileinfo: fileinfoty; +begin + result:= false; + fillchar(dirstream,sizeof(dirstream),0); + with dirstream,dirinfo do begin + dirname:= filepath(adirname,fk_file); + include:= ainclude; + exclude:= aexclude; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + while sys_readdirstream(dirstream,fileinfo) do begin + if (fileinfo.name <> dotchar) and (fileinfo.name <> '..') then begin + result:= true; + break; + end; + end; + sys_closedirstream(dirstream); + end; +end; + +function findfile(filename: filenamety; + const dirnames: array of filenamety; var path: filenamety): boolean; + //true if found, path not touched if not found +var + fna1: filenamety; +begin + fna1:= searchfile(filename,dirnames); + if fna1 <> '' then begin + path:= fna1 + msefileutils.filename(filename); + result:= true; + end + else begin + result:= false; + end; +end; + +function findfile(filename: filenamety; //no const bcause of var path param + var path: filenamety): boolean; + //no out because of caller side finalization + //true if found, path not touched if not found +var + fna1: filenamety; +begin + fna1:= searchfile(filename); + if fna1 <> '' then begin + path:= fna1 + msefileutils.filename(filename); + result:= true; + end + else begin + result:= false; + end; +end; + +function findfile(const filename: filenamety; + const dirnames: array of filenamety): boolean; + //true if found +var + fna1: filenamety; +begin + result:= findfile(filename,dirnames,fna1); +end; + +function findfileordir(const filename: filenamety): boolean; +var + info: fileinfoty; +begin + result:= sys_getfileinfo(filename,info); +end; + +function findfile(const filename: filenamety): boolean; overload; +var + info: fileinfoty; +begin + result:= sys_getfileinfo(filename,info) and (info.extinfo1.filetype <> ft_dir); +end; + +function finddir(const filename: filenamety): boolean; +var + info: fileinfoty; +begin + result:= sys_getfileinfo(filename,info) and (info.extinfo1.filetype = ft_dir); +end; + +function quotefilename(const name: filenamety): filenamety; overload; +begin + if (findchar(name,msechar(' ')) = 0) or (name[1] = quotechar) then begin + result:= name; + end + else begin + result:= quotestring(name,quotechar); + end; +end; + +function quotefilename(const names: filenamearty): filenamety; overload; +var + int1: integer; +begin + result:= ''; + if length(names) = 1 then begin + result:= quotefilename(names[0]); + end + else begin + for int1:= 0 to high(names) do begin + if pointer(names[int1]) <> nil then begin + result:= result + quotestring(names[int1],quotechar) + ' '; + end; + end; + if length(result) > 0 then begin + setlength(result,length(result)-1); + end; + end; +end; + +function quotefilename(const names: array of filenamety): filenamety; overload; +begin + result:= quotefilename(opentodynarraym(names)); +end; + +function quotefilename(const directory,name: filenamety): filenamety; +var + ar1: filenamearty; + str1: filenamety; + int1: integer; +begin + unquotefilename(name,ar1); + str1:= unquotefilename(trim(directory)); + if str1 <> '' then begin + str1:= filepath(str1,fk_dir,true); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= filepath(str1+ar1[int1],fk_file,true); + end + end + else begin + for int1:= 0 to high(ar1) do begin + ar1[int1]:= filepath(ar1[int1],fk_file,true); + end; + end; + result:= quotefilename(ar1); +end; + +procedure unquotefilename(const names: filenamety; var result: filenamearty); +begin + if findchar(names,quotechar) <> 0 then begin + splitstringquoted(trim(names),result,quotechar); + end + else begin + setlength(result,1); + result[0]:= trim(names); + if result[0] = '' then begin + result:= nil; + end; + end; +end; + +function unquotefilename(const name: filenamety): filenamety; overload; +begin + result:= trim(name); + if (length(result) > 1) and + (result[1] = quotechar) and (result[length(result)] = quotechar) then begin + result:= copy(result,2,length(result)-2); + end; +end; + +function extractrootpath(var names: filenamearty): filenamety; +var + ch1: msechar; + int1,int2,int3: integer; + bo1: boolean; +begin + result:= ''; + if names <> nil then begin + int3:= 0; + bo1:= false; + for int2:= 1 to length(names[0]) do begin + ch1:= names[0][int2]; + for int1:= 1 to high(names) do begin + if names[int1][int2] <> ch1 then begin + bo1:= true; + break; + end; + end; + if bo1 then begin + break; + end; + if ch1 = slashchar then begin + int3:= int2; + end; + end; + result:= copy(names[0],1,int3); + names:= copy(names); + for int1:= 0 to high(names) do begin + names[int1]:= copy(names[int1],int3+1,bigint); + end; + end; +end; + +function combinerootpath(const rootpath: filenamety; const names: filenamearty): filenamearty; +var + int1: integer; + str1,str2: filenamety; +begin + str1:= filepath(rootpath,fk_dir,true); + setlength(result,length(names)); + for int1:= 0 to high(names) do begin + str2:= filepath(names[int1],fk_default,true); + if (length(str2) > 0) and (str2[1] = slashchar) then begin + result[int1]:= str2; + end + else begin + result[int1]:= str1 + str2 {$ifndef FPC}+''{$endif}; //delphi bug + end; + end; +end; + +function combinerootpath(const rootpaths: filenamearty; const name: filenamety): filenamearty; +var + int1: integer; +begin + setlength(result,length(rootpaths)); + for int1:= 0 to high(rootpaths) do begin + result[int1]:= filepath(rootpaths[int1],name,fk_default,true); + end; +end; + +function isrelativepath(const path: filenamety): boolean; +var + str1: filenamety; +begin + str1:= remquote(path); + result:= not ( + (length(str1) > 0) and ((str1[1] = '\') or (str1[1] = slashchar)) or + (length(str1) >= 1) and (str1[2] = ':') + ); +end; + +function isrootdir(const path: filenamety): boolean; +begin + result:= (path = slashchar) or (path = '\') or (path = '"/"') or (path = '"\"'); +end; + +procedure tomsefilepath1(var path: filenamety; const quoted: boolean = false); + + procedure doname(var path: filenamety); + var + str1: filenamety; + begin + str1:= remquote(path); + replacechar1(str1,msechar('\'),msechar(slashchar)); //calls uniquestring + if (length(str1) >= 2) and (str1[2] = ':'){ and (str1[3] = slashchar)} then begin + setlength(str1,length(str1)+1); + move(str1[1],str1[2],(length(str1)-1)*sizeof(msechar)); // 'c:x' -> 'cc:x' + pmsecharaty(str1)^[0]:= slashchar; // /c: + pmsecharaty(str1)^[1]:= str1[2];//charuppercase(str1[2]); + end; + requote(path,str1); + end; + +var + ar1: filenamearty; + int1: integer; + +begin //tomsefilepath1 + path:= trim(path); + if findchar(path,quotechar) <> 0 then begin + unquotefilename(path,ar1); + for int1:= 0 to high(ar1) do begin + doname(ar1[int1]); + end; + path:= quotefilename(ar1); + end + else begin + doname(path); + if quoted then begin + path:= quotefilename(path); + end; + end; +end; + +procedure tosysfilepath1(var path: filenamety; const quoted: boolean = false); +var + ar1: filenamearty; + int1: integer; +begin + path:= trim(path); + if findchar(path,quotechar) <> 0 then begin + unquotefilename(path,ar1); + for int1:= 0 to high(ar1) do begin + syserror(sys_tosysfilepath(ar1[int1])); + end; + path:= quotefilename(ar1); + end + else begin + if quoted then begin + path:= quotefilename(path); + end; + syserror(sys_tosysfilepath(path)); + end; +end; + +function tomsefilepath(const path: filenamety; + const quoted: boolean = false): filenamety; +begin + result:= path; + tomsefilepath1(result,quoted); +end; + +function tosysfilepath(const path: filenamety; + const quoted: boolean = false): filenamety; +begin + result:= path; + tosysfilepath1(result,quoted); +end; + +function tosysfilepath(const path: filenamearty; + const quoted: boolean = false): filenamearty; +var + i1: int32; +begin + setlength(result,length(path)); + for i1:= 0 to high(path) do begin + result[i1]:= tosysfilepath(path[i1],quoted); + end; +end; + +procedure syncpathdelim(const source: filenamety; var dest: filenamety; + kind: filekindty); +begin + if length(dest) > 0 then begin + if (length(dest) >= 3) and (length(dest) <= 4) and + (dest[1] = slashchar) and (dest[3] = ':') then begin + kind:= fk_dir; // /a: -> /a:/ + // /a:/ -> /a:/ + end; + if kind = fk_default then begin + if (length(source) > 0) and (source[length(source)] = slashchar) then begin + kind:= fk_dir; + end + else begin + kind:= fk_file; + end; + end; + case kind of + fk_dir: begin + if dest[length(dest)] <> slashchar then begin + dest:= dest + slashchar; + end; + end; + fk_file: begin + if (length(dest) > 1) and (dest[length(dest)] = slashchar) then begin + setlength(dest,length(dest) - 1); + end; + end; + end; + end; +end; + +function filepath({const} path: filenamety; + kind: filekindty = fk_default; relative: boolean = false): filenamety; overload; +var + ar1,ar2: filenamearty; + int1,int2: integer; + mstr1: filenamety; + bo1: boolean; +begin + mstr1:= unquotefilename(tomsefilepath(path)); + if (length(mstr1) > 1) and (mstr1[2] = slashchar) then begin + if mstr1[1] = '~' then begin + mstr1:= sys_getuserhomedir + copy(mstr1,2,bigint); + end + else begin + if mstr1[1] = '^' then begin + mstr1:= sys_getapphomedir + copy(mstr1,2,bigint); + end + end; + end; + if not relative and not isrootpath(mstr1) then begin + if mstr1 <> '' then begin + mstr1:= sys_getcurrentdir + slashchar + mstr1; + end + else begin + mstr1:= sys_getcurrentdir; + end; + end; + ar1:= nil; + splitstring(msestring(mstr1),msestringarty(ar1),msechar(slashchar)); + setlength(ar2,length(ar1)); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if ar1[int1] = '..' then begin + if (int2 > 1) or + (int2 = 1) and not ((length(ar2[0]) = 2) and (ar2[0][2] = ':')) then begin + dec(int2); + if ar2[int2] = '..' then begin //for relative path + inc(int2); + ar2[int2]:= ar1[int1]; + inc(int2); + end; + end + else begin + if relative then begin //if not relative ignore '..' if rootdir + ar2[int2]:= ar1[int1]; + inc(int2); + end; + end; + end + else begin + if (ar1[int1] <> dotchar) and (ar1[int1] <> '') then begin + ar2[int2]:= ar1[int1]; + inc(int2); + end; + end; + end; + result:= ''; + bo1:= (length(mstr1) > 0) and (mstr1[1] = slashchar); //rootpath + if bo1 and (int2 = 0) then begin + result:= slashchar; +// inc(int2); + end; + bo1:= not relative or bo1; + for int1:= 0 to int2 - 1 do begin + if bo1 then begin + result:= result + slashchar + ar2[int1]; + end + else begin + result:= result + ar2[int1]; //relative start + bo1:= true; + end; + end; + if relative and ((mstr1 = dotchar) or msestartsstr('./',mstr1)) and + not msestartsstr('../',result) then begin + result:= './' + result; + end; + syncpathdelim(mstr1,result,kind); + if msestartsstr('//',mstr1) then begin + result:= slashchar+result; //restore uncfilename + end; +end; + +function filepath({const} directory,filename: filenamety; kind: filekindty = fk_default; + relative: boolean = false): filenamety; overload; +begin + if not isrelativepath(filename) then begin + result:= filepath(filename,kind,relative); + end + else begin + result:= filepath(directory,fk_dir,relative); + result:= filepath(result + unquotefilename(filename),kind,relative); + tomsefilepath1(result); //really needed? + end; +end; + +function syscommandline(const acommandline: filenamety): filenamety; + //converts exec path to sys format +var + int1,int2,int3: integer; +begin + result:= ''; + int1:= 0; + int2:= 0; + int3:= 0; + if length(acommandline) > 0 then begin + int1:= 1; //start exe + if acommandline[1] = quotechar then begin + int1:= 2; + int2:= findchar(pmsechar(@acommandline[2]),quotechar);//end of exe + if int2 = 0 then begin + int2:= length(acommandline); + end + else begin + inc(int2); + end; + int3:= int2+1; //start of params + end + else begin + int2:= findchar(acommandline,' ');//end of exe + if int2 <= 0 then begin + int2:= length(acommandline); + end; + int3:= int2; + end; + end; + if int1 > 1 then begin //quoted + result:= quotechar+tosysfilepath(copy(acommandline,int1,int2-int1)) + + quotechar+ copy(acommandline,int3,bigint); + end + else begin + result:= tosysfilepath(copy(acommandline,int1,int2-int1)) + + copy(acommandline,int3,bigint); + end; +end; + +function relativepath(const path: filenamety; const root: filenamety = ''; + const kind: filekindty = fk_default): filenamety; + //root = '' -> currentdir +var + root1: filenamety; + str1,str2,str3: filenamety; + ar1,ar2,ar3:filenamearty; + int1,int2,int3: integer; +begin + if root = '' then begin + root1:= sys_getcurrentdir; + end + else begin + root1:= filepath(root,fk_dir); + end; + str1:= filepath(path); + ar3:= splitrootpath(str1); + if filesystemiscaseinsensitive then begin + str2:= mseuppercase(root1); + str3:= mseuppercase(str1); + ar2:= splitrootpath(str3); + end + else begin + str2:= root1; + str3:= str1; + ar2:= ar3; + end; + ar1:= splitrootpath(str2); + int2:= high(ar2); + if int2 > high(ar1) then begin + int2:= high(ar1); + end; + int3:= int2 + 1; + for int1:= 0 to int2 do begin + if ar1[int1] <> ar2[int1] then begin + int3:= int1; + break; + end; + end; + result:= ''; + for int1:= int3 to high(ar1) do begin + result:= result + '../'; + end; + for int1:= int3 to high(ar3) do begin + result:= result + ar3[int1] + slashchar; + end; + if int3 <= high(ar3) then begin + setlength(result,length(result)-1); //remove last slashchar + end; + if result = '' then begin + result:= dotchar; + end; + syncpathdelim(str1,result,kind); +end; + +function relocatepath(const olddir,newdir: filenamety; + var apath: filenamety; + const options: pathrelocateoptionsty = []): boolean; +//searches file in newdir relative to olddir if apath not found, updates +//apath to the new location if found +var + mstr1: filenamety; +begin + result:= true; + if options * [pro_preferenew,pro_onlynew] <> [] then begin + mstr1:= filepath(newdir,relativepath(apath,olddir)); + result:= findfile(mstr1); + if result then begin + apath:= mstr1; + end + else begin + if not (pro_onlynew in options) then begin + result:= findfile(apath); + end; + end; + end + else begin + if not findfile(apath) then begin + mstr1:= filepath(newdir,relativepath(apath,olddir)); + result:= findfile(mstr1); + if result then begin + apath:= mstr1; + end; + end; + end; + if pro_rootpath in options then begin + apath:= filepath(apath); + end; +end; + +procedure splitfilepath(const path: filenamety; + out directory,filename: filenamety); +var + str1: filenamety; +begin +// str1:= unquotefilename(filepath(path,fk_default,true)); + str1:= filepath(path,fk_default,true); + if (str1 = '') or (str1[length(str1)] = slashchar) then begin + directory:= str1; + filename:= ''; + end + else begin + directory:= removelastpathsection(str1); + if directory <> '' then begin + if directory = slashchar then begin //root + filename:= copy(str1,2,bigint); + end + else begin + if directory = '//' then begin //unc root + filename:= copy(str1,3,bigint); + end + else begin + directory:= directory + slashchar; + filename:= copy(str1,length(directory)+1,bigint); + end; + end; + end + else begin + filename:= str1; + end; + end; +end; + +procedure splitfilepath(const path: filenamety; + out directory,filename,fileext: filenamety); +var + fstr1: filenamety; + int1: integer; +begin + splitfilepath(path,directory,fstr1); + int1:= findlastchar(fstr1,dotchar); + if int1 > 1 then begin + filename:= copy(fstr1,1,int1-1); + fileext:= copy(fstr1,int1,bigint); + end + else begin + filename:= fstr1; + fileext:= ''; + end; +end; + +function splitfilepath(const path: filenamety): filenamearty; +var + str1: filenamety; +begin + str1:= unquotefilename(filepath(path,fk_file,true)); + result:= nil; + if str1 <> '' then begin + splitstring(str1,result,msechar(slashchar)); + if result[0] = '' then begin //root + result:= copy(result,1,bigint); + end; + end; +end; + +function splitrootpath(const path: filenamety): filenamearty; +var + str1: filenamety; +begin + str1:= unquotefilename(filepath(path,fk_file)); + result:= nil; + splitstring(str1,result,msechar(slashchar)); + result:= copy(result,1,bigint); +end; + +function mergerootpath(const segments: filenamearty): filenamety; +var + int1: integer; +begin + if segments = nil then begin + result:= slashchar; + end + else begin + result:= ''; + for int1:= 0 to high(segments) do begin + result:= result + slashchar + segments[int1]; + end; + end; +end; + +function filename(const path: filenamety): filenamety; +var + str1: filenamety; +begin + splitfilepath(path,str1,result); +end; + +function filedir(const path: filenamety): filenamety; +var + str1: filenamety; +begin + splitfilepath(path,result,str1); +end; + +function filenamebase(const path: filenamety): filenamety; //without ext +var + mstr1,mstr2: filenamety; +begin + splitfilepath(path,mstr1,result,mstr2); +end; + +function removefileext(const path: filenamety): filenamety; +var + str1: filenamety; + int1: integer; +begin + str1:= tomsefilepath(path); + int1:= findlastchar(str1,dotchar); + if (int1 > 1) and (findlastchar(str1,slashchar) < int1) then begin + result:= copy(str1,1,int1-1); + end + else begin + result:= str1; + end; +end; + +function hasfileext(const path: filenamety): boolean; +var + int1: integer; +begin + int1:= findlastchar(path,dotchar); + result:= (int1 > 1) and (findlastchar(path,slashchar) < int1); +end; + +function fileext(const path: filenamety): filenamety; +var + str1: filenamety; + int1: integer; +begin + str1:= filename(path); + int1:= findlastchar(str1,dotchar); + if int1 > 1 then begin + result:= copy(str1,int1+1,bigint); + end + else begin + result:= ''; + end; +end; + +function checkfileext(const path: filenamety; const extensions: array of filenamety): boolean; +var + int1: integer; + ext: filenamety; +begin + result:= false; + ext:= fileext(path); + if filesystemiscaseinsensitive then begin + ext:= mseuppercase(ext); + end; + for int1:= 0 to high(extensions) do begin + if filesystemiscaseinsensitive then begin + result:= ext = mseuppercase(extensions[int1]); + end + else begin + result:= ext = extensions[int1]; + end; + if result then begin + break; + end; + end; +end; + +function replacefileext(const path,newext: filenamety): filenamety; +begin + result:= removefileext(path); + if newext <> '' then begin + result:= result + dotchar + newext; + end; +end; + +function uniquefilename(const path: filenamety): filenamety; + //adds numbers if necessary +var + int1: integer; + dir,name,ext: filenamety; +begin + result:= path; + if findfileordir(path) then begin + int1:= 1; + splitfilepath(path,dir,name,ext); + repeat + result:= dir+name+inttostrmse(int1)+ext; + inc(int1); + until not findfileordir(result); + end; +end; + +function removelastpathsection(path: filenamety): filenamety; +var + int1: integer; +begin + int1:= findlastchar(path,msechar(slashchar)); + if (int1 > 1) then begin + result:= copy(path,1,int1-1); + if (int1 = 2) and (path[1] = slashchar) then begin + result:= slashchar + result; //UNC + end; + end + else begin + if int1 = 1 then begin + result:= slashchar; //root + end + else begin + result:= ''; + end; + end; +end; + +function getlastpathsection(const path: filenamety): filenamety; +var + fna1: filenamety; + int1,int2: integer; +// po1: pmsechar; +begin + result:= ''; + fna1:= filepath(path); + if fna1 <> '' then begin + int1:= length(fna1); + if fna1[int1] = slashchar then begin + dec(int1); //skip trailing slash + end; + int2:= int1; + while int2 > 0 do begin + if fna1[int2] = slashchar then begin + break; + end; + dec(int2); + end; + if (int2 <= 1) or (int2 = 2) and (fna1[1] = slashchar) then begin //UNC + result:= copy(fna1,1,int1); //all without trailing slash + exit; + end; + result:= copy(fna1,int2+1,int1-int2); + end; +end; + +function removelastdir(path: filenamety; var newpath: filenamety): filenamety; +begin + if (path = '') or isrootdir(path) then begin + newpath:= path; + result:= ''; + end + else begin + if path[length(path)] = slashchar then begin + newpath:= removelastpathsection(copy(path,1,length(path)-1)); + if newpath = slashchar then begin + result:= copy(path,length(newpath)+1,length(path)-length(newpath)-1); + end + else begin + result:= copy(path,length(newpath)+2,length(path)-length(newpath)-2); + end; + end + else begin + newpath:= removelastpathsection(path); + result:= copy(path,length(newpath)+2,length(path)-length(newpath)-1); + end; + if (newpath <> slashchar) and (newpath <> '//') then begin + newpath:= newpath + slashchar; + end; + end; +end; + +{ tcustomfiledatalist } + +constructor tcustomfiledatalist.create; +begin + inherited; + fsize:= sizeof(fileinfoty) +end; + +procedure tcustomfiledatalist.beforecopy(var data); +begin + stringaddref(fileinfoty(data).name); +end; + +procedure tcustomfiledatalist.freedata(var data); +begin + fileinfoty(data).name:= ''; +end; + +function tcustomfiledatalist.adddirectory(const directoryname: filenamety; + ainfolevel: fileinfolevelty = fil_name; const amask: filenamearty = nil; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false + ): boolean; + //amask = '' -> all, +var + dirstream: dirstreamty; + info: fileinfoty; + bo1,bo2: boolean; + err1: syserrorty; + ar1: filenamearty; + i1: int32; +begin + unquotefilename(directoryname,ar1); + fillchar(dirstream,sizeof(dirstream),0); + beginupdate(); + try + for i1:= 0 to high(ar1) do begin + with dirstream,dirinfo do begin + options:= aoptions; + dirname:= filepath(ar1[i1],fk_file); + mask:= amask; + include:= aincludeattrib; + exclude:= aexcludeattrib; + infolevel:= ainfolevel; + end; + err1:= sys_opendirstream(dirstream); + result:= err1 = sye_ok; + if not result then begin + if not noexception then begin + syserror(err1,quotechar+dirstream.dirinfo.dirname + '" '); + end + else begin + exit; + end; + end; + try + finalize(info); + fillchar(info,sizeof(info),0); + repeat + bo1:= sys_readdirstream(dirstream,info); + if bo1 then begin + if not ((info.extinfo1.filetype = ft_dir) and ((info.name = dotchar) or + (info.name = '..'))) then begin + bo2:= true; + if assigned(acheckproc) then begin + acheckproc(self,dirstream.dirinfo,info,bo2); + end; + if bo2 then begin + add(info); + end; + end; + end; + until not bo1; + finally + sys_closedirstream(dirstream); + end; + end; + finally + endupdate(); + end; +end; + +function tcustomfiledatalist.adddirectory(const directoryname: filenamety; + ainfolevel: fileinfolevelty; const amask: filenamety; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; + //amask = '' -> all +var + ar1: filenamearty; +begin + unquotefilename(amask,ar1); + result:= adddirectory(directoryname,ainfolevel,ar1, + aincludeattrib,aexcludeattrib,aoptions,acheckproc,noexception); +end; + +{$ifndef FPC} +function tcustomfiledatalist.adddirectory1(const directoryname: filenamety; + ainfolevel: fileinfolevelty = fil_name; const amask: filenamearty = nil; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; + //amask = nil -> all, true if ok +begin + result:= adddirectory(directoryname,ainfolevel,amask,aincludeattrib, + aexcludeattrib,aoptions,acheckproc,noexception); +end; + +function tcustomfiledatalist.adddirectory2(const directoryname: filenamety; + ainfolevel: fileinfolevelty; const amask: filenamety; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; + //amask = '' -> all, true if ok +begin + result:= adddirectory(directoryname,ainfolevel,amask,aincludeattrib, + aexcludeattrib,aoptions,acheckproc,noexception); +end; +{$endif} + +function tcustomfiledatalist.itempo(const index: integer): pfileinfoty; +begin + result:= pfileinfoty(getitempo(index)); +end; + +function tcustomfiledatalist.indexof(const filename: filenamety): integer; + //case sensitive +var + po1: pfileinfoty; + int1: integer; +begin + normalizering; + result:= -1; + po1:= pfileinfoty(fdatapo); + for int1:= 0 to count - 1 do begin + if po1^.name = filename then begin + result:= int1; + break; + end; + inc(po1); + end; +end; + +function tcustomfiledatalist.getitems(index: integer): fileinfoty; +begin + result:= itempo(index)^; +end; + +function tcustomfiledatalist.add(const value: fileinfoty): integer; +begin + result:= adddata(value); +end; + +procedure tcustomfiledatalist.setoptions(const Value: filelistoptionsty); +begin + if foptions <> value then begin + foptions:= filelistoptionsty( + {$ifdef FPC} + setsinglebit(longword(value),longword(foptions),longword(sortflags))); + {$else} + setsinglebit(byte(value),byte(foptions),byte(sortflags))); + {$endif} + + {$ifdef FPC} + case longword(foptions*sortflags) of + {$else} + case byte(foptions*sortflags) of + {$endif} + 1 shl byte(flo_sortname): begin + fsortfunc:= {$ifdef FPC}@{$endif}sortname; + end; + 1 shl byte(flo_sorttime): begin + fsortfunc:= {$ifdef FPC}@{$endif}sorttime; + end; + 1 shl byte(flo_sortsize): begin + fsortfunc:= {$ifdef FPC}@{$endif}sortsize; + end; + else begin + fsortfunc:= nil; + end; + end; + if assigned(fsortfunc) or (flo_sorttype in foptions) then begin + if sorted then begin + sort; + end + else begin + sorted:= true; + end + end + else begin + sorted:= false; + end; + end; +end; + +function tcustomfiledatalist.compare(const l,r): integer; +begin + if flo_sorttype in foptions then begin + result:= integer(fileinfoty(l).extinfo1.filetype) - + integer(fileinfoty(r).extinfo1.filetype); + end + else begin + result:= 0; + end; + if (result = 0) and assigned(fsortfunc) then begin + result:= fsortfunc(fileinfoty(l),fileinfoty(r)); + if result = 0 then begin + if flo_sortname in foptions then begin + result:= sorttime(fileinfoty(l),fileinfoty(r)); + end + else begin + result:= sortname(fileinfoty(l),fileinfoty(r)); + end; + end; + if flo_downsort in foptions then begin + result:= - result; + end; + end; +end; + +function tcustomfiledatalist.sortname(const l, r: fileinfoty): integer; +begin + if flo_casesensitive in foptions then begin +// {$ifdef FPC} +// result:= comparestr(l.name,r.name); //!!!!todo +// {$else} + result:= msecomparestr(l.name,r.name); +// {$endif} + end + else begin +// {$ifdef FPC} +// result:= comparetext(l.name,r.name); //!!!!todo +// {$else} + result:= msecomparetext(l.name,r.name); +// {$endif} + end; +end; + +function tcustomfiledatalist.sortsize(const l, r: fileinfoty): integer; +begin + if l.extinfo1.size > r.extinfo1.size then begin + result:= 1 + end + else begin + if l.extinfo1.size = r.extinfo1.size then begin + result:= 0; + end + else begin + result:= -1; + end; + end; +end; + +function tcustomfiledatalist.sorttime(const l, r: fileinfoty): integer; +begin + if l.extinfo1.modtime > r.extinfo1.modtime then begin + result:= 1 + end + else begin + if l.extinfo1.modtime = r.extinfo1.modtime then begin + result:= 0; + end + else begin + result:= -1; + end; + end; +end; + +function tcustomfiledatalist.isdir(index: integer): boolean; +begin + result:= fa_dir in itempo(index)^.extinfo1.attributes; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msefloattostr.pas b/mseide-msegui/lib/common/kernel/msefloattostr.pas new file mode 100644 index 0000000..072d23b --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msefloattostr.pas @@ -0,0 +1,621 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefloattostr; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msestrings,msetypes; + +const + expochar = msechar('E'); + +type + floatstringmodety = (fsm_default,fsm_fix,fsm_sci,fsm_engfix,fsm_engflo, + fsm_engsymfix,fsm_engsymflo); +// {$ifndef FPC} +// qword = int64; +// {$endif} + doublerecty = packed record //little endian + case integer of + 0: (by0,by1,by2,by3,by4,by5,by6,by7: byte); + 1: (wo0,wo1,wo2,wo3: word); + 2: (lwo0,lwo1: longword); + 3: (qwo0: qword); + end; + +function doubletostring(const value: double; const precision: integer = 0; + const mode: floatstringmodety = fsm_default; + const decimalsep: msechar = '.'; + const thousandsep: msechar = #0): msestring; + //precision <= 0 -> remove trailing 0 + //precision = 0 in fsm_default mode = maximal precision + +function tryintexp10(aexp: integer; out value: double): boolean; +function intexp10(aexp: integer): double; + +implementation +uses + sysutils; + +const + binexps: array[0..8] of double = (1e1,1e2,1e4,1e8,1e16,1e32,1e64,1e128,1e256); + binnegexps: array[0..8] of double = + (1e-1,1e-2,1e-4,1e-8,1e-16,1e-32,1e-64,1e-128,1e-256); + +type + expsymty = + // -8 -7 -6 -5 -4 -3 -2 -1 0 + (exs_yocto=-8,exs_zepto,exs_atto,exs_femto,exs_pico,exs_nano,exs_micro,exs_milli, +// 0 + exs_none, +// 1 2 3 4 5 6 7 8 + exs_kilo,exs_mega,exs_giga,exs_tera,exs_peta,exs_exa,exs_zetta,exs_yotta); + +const + expsyms: array[expsymty] of msechar = + ('y','z','a','f','p','n','u','m', + ' ', + 'k','M','G','T','P','E','Z','Y'); + +function tryintexp10(aexp: integer; out value: double): boolean; +var + do1: double; + int1,int2,int3: integer; +begin + result:= true; + if aexp = 0 then begin + value:= 1; + exit; + end; + do1:= 1; + int3:= 1; + int2:= abs(aexp); + if int2 <= $1ff then begin + if aexp < 0 then begin + for int1:= 0 to 8 do begin + if int2 and int3 <> 0 then begin + do1:= do1 * binnegexps[int1]; + end; + int3:= int3 shl 1; + end; + end + else begin + for int1:= 0 to 8 do begin + if int2 and int3 <> 0 then begin + do1:= do1 * binexps[int1]; + end; + int3:= int3 shl 1; + end; + end; + value:= do1; + end + else begin + result:= false; + end; +end; + +function intexp10(aexp: integer): double; +begin + if not tryintexp10(aexp,result) then begin + raise exception.create('Exponent overflow'); + end; +end; + +function doubletostring1(value: double; out msbcarry: boolean; + precision: integer; mode: floatstringmodety = fsm_default; + decimalsep: msechar = '.'; thousandsep: msechar = #0): msestring; + //format double: + // 1 11 52 + //|s| e | f | + +const + maxdigits = 17; + defaultprecision = maxdigits-2; + +type + bufferty = array[0..30] of msechar; + + function getfixoverflowvalue: msestring; + var + int1: integer; + begin +// if precision = 0 then begin + int1:= defaultprecision-1; + if precision < 0 then begin + int1:= -int1; + end; +// end +// else begin +// int1:= precision; +// end; + result:= doubletostring(value,int1,fsm_sci,decimalsep,thousandsep); + end; + + procedure checkcarry(start: byte; var dest: bufferty); + var + int1: integer; + begin + for int1:= start downto 1 do begin + if dest[int1] <= '9' then begin + break; + end; + dec(dest[int1],10); + inc(dest[int1-1]); //carry + end; + end; + +const +{$ifndef FPC} + lsbrounding = 2.2517998136852482e015; +{$else} +// lsbrounding = exp(51*ln(2)); + lsbrounding = flo64($0008000000000000); //2^51 +{$endif} + expo0max = 1-1/lsbrounding; + expo1max = 10-10/lsbrounding; + expo3max = 1000-1000/lsbrounding; + expmask = $7ff0; //for wo3 + halfexp = (1023-1) shl 4; //value >= 0.5 for wo3 +{$ifndef FPC} + exp2to10 = 0.30102999566398121; +{$else} + exp2to10 = ln(2)/ln(10); +{$endif} + exps: array[0..maxdigits] of double = + (1e0,1e1,1e2,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10, + 1e11,1e12,1e13,1e14,1e15,1e16,1e17 + ); + lsbroundings: array[0..maxdigits] of double = + (1e0/lsbrounding,1e1/lsbrounding,1e2/lsbrounding,1e3/lsbrounding, + 1e4/lsbrounding,1e5/lsbrounding,1e6/lsbrounding,1e7/lsbrounding, + 1e8/lsbrounding,1e9/lsbrounding,1e10/lsbrounding,1e11/lsbrounding, + 1e12/lsbrounding,1e13/lsbrounding,1e14/lsbrounding,1e15/lsbrounding, + 1e16/lsbrounding,1e17/lsbrounding + ); + +var + buffer: bufferty; + neg: boolean; + nan: boolean; + inf: boolean; + defaultmode: boolean; + exp: smallint; + do1: double; + int1,int2,int3,int4: integer; + lastindex,intdigits,leadingzeros,space,thousandsepcount: integer; + po1: pmsechar; + mode1: floatstringmodety; + preci: integer; + +begin + msbcarry:= false; + preci:= abs(precision); + with doublerecty(value) do begin + neg:= by7 and $80 <> 0; + by7:= by7 and $7f; //remove sign + {$ifndef FPC} + exp:= (wo3 and $7ff0) shr 4; + {$else} + exp:= (wo3 and %0111111111110000) shr 4; + {$endif} + nan:= false; + inf:= false; + if exp = 2047 then begin + if (lwo0 <> 0) or (lwo1 and $000fffff <> 0) then begin + nan:= true; + end + else begin + inf:= true; + end; + end; + end; + defaultmode:= mode = fsm_default; + if nan then begin + result:= 'Nan'; + end + else begin + if inf then begin + if neg then begin + result:= '-Inf'; + end + else begin + result:= '+Inf'; + end; + end + else begin + if exp = 0 then begin // value = 0 + if preci >= maxdigits then begin + preci:= maxdigits; + end; + case mode of + fsm_sci,fsm_engfix,fsm_engflo,fsm_engsymfix,fsm_engsymflo: begin + if preci = 0 then begin + if mode in [fsm_engsymfix,fsm_engsymflo] then begin + result:= '0 '; + end + else begin + result:= '0E+000'; + end; + exit; + end; + if mode in [fsm_engsymfix,fsm_engsymflo] then begin + int2:= preci+2; + end + else begin + int2:= preci+6; + end; + setlength(result,int2+1); + for int1:= 0 to int2 do begin + pmsecharaty(result)^[int1]:= '0'; + end; + if mode in [fsm_engsymfix,fsm_engsymflo] then begin + pmsecharaty(result)^[int2]:= ' '; + end + else begin + pmsecharaty(result)^[int2-4]:= expochar; + pmsecharaty(result)^[int2-3]:= '+'; + end; + end; + else begin //fix format + if (preci = 0) or defaultmode then begin + result:= '0'; + exit; + end + else begin + int2:= preci+1; + setlength(result,int2+1); + for int1:= 0 to int2 do begin + pmsecharaty(result)^[int1]:= '0'; + end; + end; + end; + end; + pmsecharaty(result)^[1]:= decimalsep; + exit; + end; + + exp:= exp - 1023; //value <> 0 + do1:= exp*exp2to10; + intdigits:= trunc(do1); + if defaultmode then begin + if preci = 0 then begin + preci:= maxdigits; + end; + if (value < 1e-6) or (value >= 1e15) then begin + mode:= fsm_sci; + end; + end; + + if mode >= fsm_sci then begin //exp format + if intdigits < 0 then begin + dec(intdigits); //trunk -> floor + end; + int3:= intdigits; + if mode in [fsm_engflo,fsm_engsymflo] then begin + do1:= value / intexp10(intdigits); + if do1 >= expo1max then begin + inc(intdigits); //correct overflow for precision correction + end; + end; + + if mode >= fsm_engfix then begin + if int3 < 0 then begin + int3:= int3 + ((-int3) mod 3) - 3; + end + else begin + int3:= int3 - (int3 mod 3); + end; + end; + if int3 < 0 then begin + do1:= intexp10(-int3); + do1:= value*do1; + end + else begin + do1:= intexp10(int3); + do1:= value/do1; + end; + if (mode < fsm_engfix) then begin //fsm_sci + if (do1 >= expo1max) then begin + do1:= do1 / exps[1]; + inc(int3); + end + else begin + if (do1 < exps[0]) then begin + do1:= do1 * exps[1]; + dec(int3); + end + end; + end + else begin //fsm_engfix,fsm_engflo,fsm_engsyfix,fsm_engsyflo + if (do1 >= expo3max) then begin + do1:= do1 / exps[3]; + inc(int3,3); + end + else begin + if (do1 < exps[0]) then begin + do1:= do1 * exps[3]; + dec(int3,3); + end + end; + end; +// if neg then begin +// do1:= -do1; +// end; + if mode in [fsm_engflo,fsm_engsymflo] then begin + if (intdigits = 0) and (int3 < 0)then begin + dec(intdigits); //trunc -> floor + end; + preci:= preci - intdigits + int3; + if preci < 0 then begin + preci:= 0; + end; + end; + if defaultmode and (precision = 0) then begin + mode1:= fsm_default; + end + else begin + mode1:= fsm_fix; + end; + int1:= preci; + if (precision < 0) or defaultmode and (precision = 0) then begin + int1:= -int1; + end; + result:= doubletostring1(do1,msbcarry,int1,mode1,decimalsep); //get mantissa digits + if msbcarry then begin + if mode1 = fsm_fix then begin + if (int1 <= 0) then begin //999.99-> 1000.00 -> 1000 (trimmed trailing 0) + if (mode >= fsm_engfix) then begin +// int4:= 3; +// if result[1] = '-' then begin +// inc(int4); +// end; + if length(result) > 3{int4} then begin + if precision > 0 then begin + setlength(result,length(result)-3+precision+1); + result[length(result)-precision]:= decimalsep; + end + else begin + setlength(result,length(result)-3); + end; + int3:= int3 + 3; //correct carry, 999.99-> 1000 -> 1 + end; + end + else begin + setlength(result,length(result)-1); + inc(int3); //correct carry, 9.9999-> 10 -> 1 + end; + end + else begin + if mode >= fsm_engfix then begin + if (length(result) >= 5) and (result[5] = decimalsep) then begin + pmsecharaty(result)^[4]:= result[4]; + pmsecharaty(result)^[3]:= result[3]; + pmsecharaty(result)^[2]:= result[2]; + pmsecharaty(result)^[1]:= decimalsep; + if (mode = fsm_engfix) or (mode = fsm_engsymfix) then begin + setlength(result,length(result)-3); //correct carry, 999.999-> 1000.000 -> 1.000 + end + else begin + setlength(result,length(result)-1); //correct carry, 999.999-> 1000.000 -> 1.00000 + end; + int3:= int3+3; + end + else begin + if (mode = fsm_engflo) or (mode = fsm_engsymflo) then begin + if length(result) > precision + 2 then begin + setlength(result,length(result)-1); //correct carry, 99.999-> 100.000 -> 100.00 + end; + end + end; + end + else begin + if length(result) > precision + 2 then begin + pmsecharaty(result)^[2]:= result[2]; + pmsecharaty(result)^[1]:= decimalsep; + setlength(result,length(result)-1); //correct carry, 9.999 ->10.000 -> 1.000 + inc(int3); + end; + end; + end; + end; + end; + if neg then begin + result:= '-'+result; + end; + int1:= int3 div 3; + if (mode >= fsm_engsymfix) and (int1 >= ord(low(expsymty))) and + (int1 <= ord(high(expsymty))) then begin + int2:= length(result)+1; + setlength(result,int2); + (pmsechar(pointer(result))+int2-1)^:= expsyms[expsymty(int1)]; + //exponent symbol + end + else begin + int2:= length(result)+5; + setlength(result,int2); + po1:= pmsechar(pointer(result))+int2; + if int3 < 0 then begin + (po1-4)^:= '-'; + end + else begin + (po1-4)^:= '+'; + end; + int3:= abs(int3); + for int1:= 0 to 2 do begin + dec(po1); + po1^:= msechar(ord('0')+(int3 mod 10)); + int3:= int3 div 10; + end; + (po1-2)^:= expochar; + end; + exit; + end; //exp format ^^^ + + if value > 999999999999999 then begin + result:= getfixoverflowvalue; + exit; + end; + lastindex:= intdigits + preci; //fix format + int1:= maxdigits - 1; + if defaultmode then begin + int1:= defaultprecision - 1; + end; + if lastindex > int1 then begin + preci:= preci - lastindex + int1; + if (preci < 0) then begin + result:= getfixoverflowvalue; + exit; + end; + lastindex:= int1; + end; + inc(lastindex); + buffer[0]:= '0'; //for carry + if intdigits < 0 then begin + do1:= value*exps[-intdigits]; + end + else begin + do1:= value/exps[intdigits]; //value 0.1..10 + end; + + if (exp = -1) and (do1 >= expo0max) then begin + exp:= 0; //fix for no int test + end; + + if lastindex >= 1 then begin //calculate numbers + for int1:= 1 to lastindex do begin + int2:= trunc(do1); + buffer[int1]:= msechar(int2+ord('0')); + checkcarry(int1,buffer); + do1:= frac(do1)*10; + end; + msbcarry:= buffer[0] = '0'; + if do1 > 0 then begin + do1:= do1 - 5 + lsbroundings[lastindex]; //round up lsb + if (do1 > 0) then begin + inc(buffer[lastindex]); + checkcarry(lastindex,buffer); + end; + end; + msbcarry:= msbcarry and (buffer[0] <> '0'); + if (precision < 0) or (defaultmode and (precision = 0)) then begin + int2:= lastindex - preci + 1; //remove trayling zeros + for int1:= lastindex downto int2 do begin + if (buffer[int1] <> '0') then begin + preci:= preci - lastindex + int1; + lastindex:= int1; + break; + end; + if int1 = int2 then begin + preci:= 0; + lastindex:= int1-1; + end; + end; + end; + end + else begin + lastindex:= 0; //single '0' + end; + + space:= 0; //update string + if neg then begin + inc(space); //add space for sign + end; + if preci > 0 then begin + inc(space); //add space for decimal separator + end; + + if exp < 0 then begin //<1, no int + space:= space + preci; + setlength(result,space+1); //add space for leading zero + po1:= pmsechar(pointer(result))+space; + if lastindex > space then begin + lastindex:= space; + end; + for int1:= lastindex downto 0 do begin + po1^:= buffer[int1]; + dec(po1); + end; + for int1:= space - lastindex - 1 downto 0 do begin + po1^:= '0'; //fill rest with '0' + dec(po1); + end; + if preci > 0 then begin + inc(po1,space - preci + 1); //decimal separator + (po1-1)^:= po1^; //move possible carry + po1^:= decimalsep; + end; + end + else begin //>1 with int + leadingzeros:= 0; + while buffer[leadingzeros] = '0' do begin + inc(leadingzeros); //remove leading '0' + end; + thousandsepcount:= 0; + if thousandsep <> #0 then begin + thousandsepcount:= (lastindex-leadingzeros-preci) div 3; + space:= space + thousandsepcount; + end; + space:= space + lastindex - leadingzeros; + setlength(result,space+1); + po1:= pmsechar(pointer(result)) + space; + if preci > 0 then begin + for int3:= lastindex downto lastindex - preci + 1 do begin + po1^:= buffer[int3]; //fract + dec(po1); + end; + po1^:= decimalsep; + dec(po1); + for int3:= lastindex - preci downto leadingzeros do begin + po1^:= buffer[int3]; //int + dec(po1); + end; + end + else begin + for int3:= lastindex downto leadingzeros do begin + po1^:= buffer[int3]; //int + dec(po1); + end; + end; + if thousandsepcount > 0 then begin + int3:= space-lastindex+leadingzeros; //first int char + int4:= space - preci; //last int char + if preci > 0 then begin + dec(int3); //thousand separator + dec(int4); + end; + po1:= pmsechar(pointer(result)) + int3 - thousandsepcount; + for int3:= int3 to space - preci - 3 do begin + po1^:= pmsecharaty(result)^[int3]; + inc(po1); + if (int3 - int4) mod 3 = 0 then begin + po1^:= thousandsep; + inc(po1); + end; + end; + end; + end; + if neg then begin + pmsechar(pointer(result))^:= '-'; + end; + end; + end; +end; + +function doubletostring(const value: double; const precision: integer = 0; + const mode: floatstringmodety = fsm_default; + const decimalsep: msechar = '.'; + const thousandsep: msechar = #0): msestring; +var + bo1: boolean; +begin + result:= doubletostring1(value,bo1,precision,mode,decimalsep,thousandsep); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseformatstr.pas b/mseide-msegui/lib/common/kernel/mseformatstr.pas new file mode 100644 index 0000000..be1bc67 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseformatstr.pas @@ -0,0 +1,5891 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseformatstr; //stringwandelroutinen 31.5.99 mse + +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +uses + classes,mclasses,msetypes,msestrings,SysUtils,msemacros,mseglob + {$ifndef FPC},classes_del{$endif}; +{$ifdef FPC}{$define hasqword}{$endif} +{$ifdef mswindows}{$define hasqword}{$endif} +type + dateconvertty = (dc_none,dc_tolocal,dc_toutc); + + TMonthNameArraymse = array[1..12] of msestring; + TWeekNameArraymse = array[1..7] of msestring; + + TFormatSettingsmse = record + CurrencyFormat: Byte; + NegCurrFormat: Byte; + ThousandSeparator: mseChar; + DecimalSeparator: mseChar; + CurrencyDecimals: Byte; + DateSeparator: mseChar; + TimeSeparator: mseChar; + ListSeparator: mseChar; + CurrencyString: msestring; + ShortDateFormat: msestring; + LongDateFormat: msestring; + TimeAMString: msestring; + TimePMString: msestring; + ShortTimeFormat: msestring; + LongTimeFormat: msestring; + ShortMonthNames: TMonthNameArraymse; + LongMonthNames: TMonthNameArraymse; + ShortDayNames: TWeekNameArraymse; + LongDayNames: TWeekNameArraymse; + TwoDigitYearCenturyWindow: Word; + end; + + tformatmacrolist = class(tmacrolist) + public + procedure addmac(const aname: msestring; const avalue: msestring; + const ahandler: macrohandlerty = nil); + end; + +var + DefaultFormatSettingsmse : TFormatSettingsmse = ( + CurrencyFormat: 1; + NegCurrFormat: 5; + ThousandSeparator: ','; + DecimalSeparator: '.'; + CurrencyDecimals: 2; + DateSeparator: '-'; + TimeSeparator: ':'; + ListSeparator: ','; + CurrencyString: '$'; + ShortDateFormat: 'd/m/y'; + LongDateFormat: 'dd" "mmmm" "yyyy'; + TimeAMString: 'AM'; + TimePMString: 'PM'; + ShortTimeFormat: 'hh:nn'; + LongTimeFormat: 'hh:nn:ss'; + ShortMonthNames: ('Jan','Feb','Mar','Apr','May','Jun', + 'Jul','Aug','Sep','Oct','Nov','Dec'); + LongMonthNames: ('January','February','March','April','May','June', + 'July','August','September','October','November', + 'December'); + ShortDayNames: ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); + LongDayNames: ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday', + 'Saturday'); + TwoDigitYearCenturyWindow: 50; + ); + +const +// noformatsettings = 14.5; //rtlversion + noformatsettings = 15; //rtlversion + fc_keinplatzchar = '*'; + nullen = '000000000000000000000000000000'; + msenullen = msestring('000000000000000000000000000000'); + msespace = msestring(' '); + +type + numbasety = (nb_bin,nb_oct,nb_dec,nb_hex); + +function lstring(const s: string; const minwidth: integer): string; +function rstring(const s: string; const minwidth: integer): string; + +{$warnings off} + // ${THEMACRO} checks formatmacros, macro name case sensitive +{$warnings on} + +function formatdatetimemse(const formatstr: msestring; const datetime: tdatetime; + const formatsettings: tformatsettingsmse): msestring; +// 'I' = ISO date, 'II' ISO datetime, 'III' ISO datetime + ms +function formatdatetimemse(const formatstr: msestring; + const datetime: tdatetime): msestring; +function formatdatetimemse(const datetime: tdatetime; formatstr: msestring; + const formatsettings: tformatsettingsmse): msestring; +// 'I' = ISO date, 'II' ISO datetime, 'III' ISO datetime + ms +function formatdatetimemse(const datetime: tdatetime; + const formatstr: msestring): msestring; + +function formatfloatmse(value: double; format: msestring; + const formatsettings: tformatsettingsmse; + const dot: boolean = false): msestring; overload; + //dot = true -> always '.' as decimal separator + //formatstring: + // formats for positive, negative and zero value can be separated by ; + // ' and " qoted text as is + // c -> currencyformat + // C -> currencyformat without currencyname + // + // + 0 or number digit + // |+ show defaultformatsettingsmse.thousandseparator + // ||+ defaultformatsettingsmse.decimalseparator or '.' if dot = true + // ||| removed if there are no fract digits + // |||+ 0 or number digit + // 0,.0 + // + // + space or number digit + // | + removed or number digit + // #.# + // + // + scientific notation with 'e' + // |+ remove '+' from positive exponent + // ||+++ 0 or exponent digit + // 0.0e-000 + // + // + show '+' of positive exponent + // 0.0e+ + // + // + scientific notation with 'E' + // 0.0E + // + // + engeneering notation with 'e', exponent = n*3 + // | + // 0.0f + // + // ++++++ mantissa - 1 digits max + // 0..000###f + // +++ mantissa - 1 digits min + // + // + engeneering notation with 'E', exponent = n*3 + // 0.0F + // + // + engeneering notation with metric system prefixes, exponent = n*3 + // | no space for 10^0 + // 0.0g + // + // + engeneering notation with metric system prefixes, exponent = n*3 + // | space for 10^0 + // 0.0G + // + // examples for value = 12345.678 + // '0.0' -> '12345.7' + // '0.000e -> '1.235e4' + // '0.000f -> '12.346e3' + // '0.000g -> '12.346k' + // '0.###f -> '12.35e3' + +function formatfloatmse(const value: double; const format: msestring; + const dot: boolean = false): msestring; overload; +function realtostrmse(const value: double; + const dot: boolean = false): msestring; +function realtytostrmse(const value: double; + const dot: boolean = false): msestring; + +function inttostr(const value: integer): string; +function inttostr(const value: longword): string; +function inttostr(const value: int64): string; +function inttostr(const value: qword): string; + +function inttostrmse(const value: integer): msestring; overload; +function inttostrmse(const value: longword): msestring; overload; +function inttostrmse(const value: int64): msestring; overload; +function inttostrmse(const value: qword): msestring; overload; + +function trystrtodouble(const s: lstringty; out value: double; + const decimalseparator: char): boolean; overload; +function trystrtodouble(const s: lmsestringty; out value: double; + const decimalseparator: msechar): boolean; overload; +function trystrtodouble(const s: string; out value: double; + const decimalseparator: char): boolean; overload; +function trystrtodouble(const s: msestring; out value: double; + const decimalseparator: msechar): boolean; overload; +function strtodouble(const s: string; + const decimalseparator: char): double; +function strtodouble(const s: msestring; + const decimalseparator: msechar): double; +function trystrtodouble(const s: string; out value: double): boolean; overload; +function trystrtodouble(const s: msestring; out value: double): boolean; overload; +function strtodouble(const s: string): double; +function strtodouble(const s: msestring): double; + +function realtostr(const value: double): string; //immer'.' als separator +function strtoreal(const s: string): double; //immer'.' als separator +function trystrtoreal(const s: string; out value: real): boolean; + //immer'.' als separator +function strtoreal(const s: msestring): double; //immer'.' als separator +function trystrtoreal(const s: msestring; out value: real): boolean; + //immer'.' als separator +function currencytostr(const avalue: currency): string; + //always '.' as as decimal separator +function currencytostrmse(const avalue: currency): msestring; + //always '.' as as decimal separator + +function trystrtorealty(const ein: msestring; out value: realty; + forcevalue: boolean = false): boolean; +function strtorealty(const ein: string; forcevalue: boolean = false): realty; +function strtorealty(const ein: msestring; forcevalue: boolean = false): realty; +function strtorealtydot(const ein: string): realty; +function strtorealtydot(const ein: msestring): realty; +function trystrtorealtydot(const ein: string; out value: realty): boolean; +function trystrtorealtydot(const ein: msestring; out value: realty): boolean; +//function realtytostr(const val: realty; const format: msestring = ''): msestring; +function realtytostr(const val: realty; const format: msestring = ''; + const scale: real = 1): msestring; + deprecated 'use realtytostring() instead'; + //use realtytostring() instead +function realtytostring(const val: realty; const format: msestring = ''; + const scale: real = 1): msestring; +function realtytostrrange(const val: realty; const format: msestring = ''; + const range: real = 1; + const offset: real = 0): msestring; +function realtytostrdot(const val: realty): string; +function realtytostrdotmse(const val: realty): msestring; + +function wordtostr(const avalue: longword): string; + +function bytetohex(const inp: byte): string; + //wandelt byte in zwei ascii hexzeichen +function wordtohex(const inp: word; lsbfirst: boolean = false): string; + //wandelt word in vier ascii hexzeichen + +function valtohex(const avalue: byte): string; overload; +function valtohex(const avalue: word): string; overload; +function valtohex(const avalue: longword): string; overload; +function valtohex(const avalue: qword): string; overload; + +function dectostr(const inp: integer; digits: integer): string; overload; + //leading zeroes if digits < 0 +function dectostr(const inp: int64; digits: integer): string; overload; + //leading zeroes if digits < 0 +function bintostr(inp: longword; digits: integer): string; overload; + //convert longword to binstring, digits = bit count +function bintostr(inp: qword; digits: integer): string; overload; + //convert longword to binstring, digits = bit count +function octtostr(inp: longword; digits: integer): string; overload; + //convert longword to octaltring, digits = octet count +function octtostr(inp: qword; digits: integer): string; overload; + //convert longword to octaltring, digits = octet count +function hextostr(inp: longword; + digits: integer = 2*sizeof(longword)): string; overload; + //convert longword to hexstring, digits = nibble count, 0 -> variable +function hextostr(inp: qword; + digits: integer = 2*sizeof(qword)): string; overload; + //convert qword to hexstring, digits = nibble count, 0 -> variable +function hextostr(const inp: pointer; + digits: integer = 2*sizeof(pointer)): string; overload; + //convert pointer to hexstring, digits = nibble count, 0 -> variable +function hextostrmse(inp: longword; + digits: integer = 2*sizeof(longword)): msestring; overload; + //convert longword to hexstring, digits = nibble count, 0 -> variable +function hextostrmse(inp: qword; + digits: integer = 2*sizeof(qword)): msestring; overload; + //convert qword to hexstring, digits = nibble count, 0 -> variable +function hextostrmse(const inp: pointer; + digits: integer = 2*sizeof(pointer)): msestring; overload; + //convert pointer to hexstring, digits = nibble count, 0 -> variable +function hextocstr(const inp: longword; stellen: integer): string; overload; + //convert longword to 0x..., digits = nibble count, 0 -> variable +function hextocstr(const inp: qword; stellen: integer): string; overload; + //convert longword to 0x..., digits = nibble count, 0 -> variable +function ptruinttocstr(inp: ptruint): string; overload; + //convert ptruint to 0x... +function qwordtocstr(inp: qword): string; overload; + //convert ptruint to 0x... +function intvaluetostr(const value: integer; const base: numbasety = nb_dec; + const bitcount: integer = 32): string; overload; +function intvaluetostr(const value: int64; const base: numbasety = nb_dec; + const bitcount: integer = 64): string; overload; + +function trystrtoptruint(const inp: string; out value: ptruint): boolean; +function strtoptruint(const inp: string): ptruint; + +function trystrtobin(const inp: string; out value: longword): boolean; +function strtobin(const inp: string): longword; +function trystrtooct(const inp: string; out value: longword): boolean; +function strtooct(const inp: string): longword; +function trystrtodec(const inp: string; out value: longword): boolean; +function strtodec(const inp: string): longword; +function trystrtohex(const inp: pchar; const len: int32; + out value: longword): boolean; +function trystrtohex(const inp: lstringty; out value: longword): boolean; +function trystrtohex(const inp: string; out value: longword): boolean; +function trystrtohex(const inp: msestring; out value: longword): boolean; +function strtohex(const inp: string): longword; +function strtohex(const inp: msestring): longword; + +function trystrtobin64(const inp: string; out value: qword): boolean; +function strtobin64(const inp: string): qword; +function trystrtooct64(const inp: string; out value: qword): boolean; +function strtooct64(const inp: string): qword; +function trystrtodec64(const inp: string; out value: qword): boolean; +function strtodec64(const inp: string): qword; +function trystrtohex64(const inp: string; out value: qword): boolean; +function strtohex64(const inp: string): qword; + + +function trystrtoint(const text: pchar; const len: int32; + out value: integer): boolean; +function trystrtoint(const text: lstringty; out value: integer): boolean; +function trystrtoint(const text: string; out value: integer): boolean; +function trystrtoint(const text: msestring; out value: integer): boolean; +function strtoint(const text: string): integer; +function strtoint(const text: msestring): integer; +function trystrtoint(const text: string; out value: longword): boolean; +function trystrtoint(const text: msestring; out value: longword): boolean; +function strtoint64(const text: string): int64; +function strtoint64(const text: msestring): int64; +function trystrtoint64(const text: lstringty; out value: int64): boolean; +function trystrtoint64(const text: string; out value: int64): boolean; +function trystrtoint64(const text: msestring; out value: int64): boolean; +function trystrtoqword(const text: string; out value: qword): boolean; +function trystrtoqword(const text: msestring; out value: qword): boolean; + +function trystrtointvalue(const inp: string; + out value: longword): boolean; overload; + //% prefix -> bin, & -> oct, # -> dez, $ -> hex 0x -> hex +function strtointvalue(const inp: string): longword; overload; +function trystrtointvalue(const text: msestring; base: numbasety; + out value: longword): boolean; overload; +function strtointvalue(const text: msestring; base: numbasety): longword; overload; + +function trystrtointvalue64(const inp: string; + out value: qword): boolean; overload; + //% prefix -> bin, & -> oct, # -> dez, $ -> hex 0x -> hex +function strtointvalue64(const inp: string): qword; overload; +function trystrtointvalue64(const text: msestring; base: numbasety; + out value: qword): boolean; overload; +function strtointvalue64(const text: msestring; base: numbasety): qword; overload; + + +function bytestrtostr(const inp: ansistring; base: numbasety = nb_hex; + spacechar: char = #0): string; + //wandelt bytefolge in ascii hexstring, spacechar #0 -> none +function bytestrtobin(const inp: ansistring; abstand: boolean): string; + //wandelt bytefolge in ascii binstring, + // letztes zeichen = anzahl gueltige bits in letztem byte +function bitmaske(const data: ansistring): integer; //anzahl gueltige bits in vorletztem byte +function bitcount(const data: ansistring): integer; //anzahl gueltige bits + +function bcdtostr(inp: byte): string; + //wandelt bcdwert in zwei ascii zeichen +function bytetobcd(inp: byte): word; + //wandelt byte in bcdwert +function bcdtobyte(inp: byte): byte; + //wandelt bcdbyte in byte +function strtobytestr(inp: string): ansistring; + //wandelt hex asciistring in bytefolge +function strtobinstr(inp: string): ansistring; + //wandelt bin asciistring in bytefolge +function strtobytes(const inp: string; out dest: bytearty): boolean; +//msb first, true if ok + +function inttostrlen(inp: integer; len: integer; + rechtsbuendig: boolean = true; fillchar: char = ' '): ansistring; + //wandelt integer in string fester laenge +function inttostrlenmse(inp: integer; len: integer; + rechtsbuendig: boolean = true; fillchar: msechar = ' '): msestring; +{ +function filename(inp: string): string; +//bringt filenamen ohne pfad und extension +function replaceext(inp,ext: string): string; +//ersetzt fileextension +} +function bcdtoint(inp: byte): integer; +function inttobcd(inp: integer): byte; + +function stringtotime(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function stringtotime(const avalue: msestring; + const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function trystringtotime(const text: msestring; + out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; +function trystringtotime(const text: msestring; + const aformat: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; + +function timetostring(const avalue: tdatetime; + const format: msestring = 't'): msestring; +function datetostring(const avalue: tdatetime; + const format: msestring = 'c'): msestring; +function stringtodate(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function stringtodate(const avalue: msestring; + const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function trystringtodate(const text: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; +function trystringtodate(const text: msestring; + const aformat: msestring; + out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; +function datetimetostring(const avalue: tdatetime; + const format: msestring = 'c'): msestring; +function stringtodatetime(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function stringtodatetime(const avalue: msestring; + const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function trystringtodatetime(const text: msestring; + out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; +function trystringtodatetime(const text: msestring; + aformat: msestring; + out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; +procedure checkdateconvert(const convert: dateconvertty; var value: tdatetime); +procedure checkdatereconvert(const convert: dateconvertty; var value: tdatetime); + +function timemse(const value: tdatetime): tdatetime; + //bringt timeanteil im mseformat + +function cstringtostring(inp: pchar): string; overload; +function cstringtostring(const inp: string): string; overload; +function cstringtostringvar(var inp: pchar): string; +function stringtocstring(const inp: msestring): string; overload; +function stringtocstring(const inp: pmsechar; + const count: integer): string; overload; +function stringtopascalstring(const value: msestring; + const maxlinelength: int32 = 0): string; + //0 -> no limit +function pascalstringtostring(const value: string): msestring; +function trypascalstringtostring(const value: string; + out res: msestring ): boolean; +function getpascalstring(var value: pchar): msestring; + +function encodebase64(const abinary: string; + const maxlinelength: integer = defaultbase64linelength): string; overload; +function encodebase64(const abinary: pbyte; acount: integer; + const maxlinelength: integer = defaultbase64linelength): string; overload; +function decodebase64(const atext: string): string; +function encodexmlstring(const value: msestring): msestring; + +{$ifndef FPC} +function TryStrToQWord(const S: string; out Value: QWord): Boolean; +{$endif} + +procedure msestrtotvarrec(const value: ansistring; out varrec: tvarrec); +procedure msestrtotvarrec(const value: msestring; out varrec: tvarrec); + +function tvarrectoansistring(const value: tvarrec): ansistring; +function tvarrectomsestring(const value: tvarrec): msestring; + +function formatmse(const fmt: msestring; const args: array of const): msestring; +function formatmse(const fmt: msestring; const args: array of const; + const formatsettings: tformatsettingsmse): msestring; + +function formatmacros: tformatmacrolist; +procedure clearformatmacros; + +{$ifdef FPC} + {$define withformatsettings} +{$endif} +{$ifdef mswindows} + {$define withformatsettings} +{$endif} + +var + defaultformatsettingsdot: tformatsettings; //mit '.' als dezitrenner + +const + charhex: array[0..15] of char = + ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); + charhexlower: array[0..15] of char = + ('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'); + hexchars: array[char] of byte = ( + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //0 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //1 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //2 + $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$80,$80,$80,$80,$80,$80, //3 + $80,$0A,$0B,$0C,$0D,$0E,$0F,$80,$80,$80,$80,$80,$80,$80,$80,$80, //4 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //5 + $80,$0a,$0b,$0c,$0d,$0e,$0f,$80,$80,$80,$80,$80,$80,$80,$80,$80, //6 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //7 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //8 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //9 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //a + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //b + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //c + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //d + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //e + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80);//f + + base64mask = $3f; + base64encoding: array[0..63] of char = ( +//0 1 2 3 4 5 6 7 8 9 a b c d e f + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', //00 + 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', //10 + 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', //20 + 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/');//30 + + base64decoding: array[0..255] of byte = ( +//0 1 2 3 4 5 6 7 8 9 a b c d e f + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //00 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //10 +// '+' '/' + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$3e,$ff,$ff,$ff,$3f, //20 +//'0','1','2','3','4','5','6','7','8','9', + $34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$ff,$ff,$ff,$ff,$ff,$ff, //30 +// 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O', + $ff,$00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e, //40 +//'P','Q','R','S','T','U','V','W','X','Y','Z', + $0f,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$ff,$ff,$ff,$ff,$ff, //50 +// 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', + $ff,$1a,$1b,$1c,$1d,$1e,$1f,$20,$21,$22,$23,$24,$25,$26,$27,$28, //60 +//'p','q','r','s','t','u','v','w','x','y','z', + $29,$2a,$2b,$2c,$2d,$2e,$2f,$30,$31,$32,$33,$ff,$ff,$ff,$ff,$ff, //70 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //80 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //90 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //a0 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //b0 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //c0 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //d0 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //e0 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff);//f0 + +implementation +uses + sysconst,msedate,msereal,Math,msefloattostr,msearrayutils,msesys,msebits, + formatfunc; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function lstring(const s: string; const minwidth: integer): string; +var + int1: integer; +begin + int1:= length(s); + if int1 < minwidth then begin + result:= s + charstring(' ',minwidth-int1); + end + else begin + result:= s; + end; +end; + +function rstring(const s: string; const minwidth: integer): string; +var + int1: integer; +begin + int1:= length(s); + if int1 < minwidth then begin + result:= charstring(' ',minwidth-int1) + s; + end + else begin + result:= s; + end; +end; + +function encodexmlstring(const value: msestring): msestring; +var + i1: int32; + ps,pe,pd,pde: pmsechar; + + procedure checkgrow(); + var + i1: ptrint; + p1: pmsechar; + begin + if pde - pd <= 5 then begin + p1:= pointer(result); + setlength(result,length(result) * 2); + i1:= pmsechar(pointer(result)) - p1; + pd:= pd+i1; + pde:= pde+i1; + end; + end; //checkgrow + +type + char4ty = array[0..3] of msechar; + pchar4ty = ^char4ty; + char5ty = array[0..4] of msechar; + pchar5ty = ^char5ty; + char6ty = array[0..5] of msechar; + pchar6ty = ^char6ty; + +begin + result:= ''; + if value <> '' then begin + ps:= pointer(value); + i1:= length(value); + pe:= ps + i1; + setlength(result,i1); + pd:= pointer(result); + pde:= pd+i1; + while ps < pe do begin + case ps^ of + '"': begin + checkgrow(); + pchar6ty(pd)^:= '"'; + inc(pd,5); + end; + '''': begin + checkgrow(); + pchar6ty(pd)^:= '''; + inc(pd,5); + end; + '<': begin + checkgrow(); + pchar4ty(pd)^:= '<'; + inc(pd,3); + end; + '>': begin + checkgrow(); + pchar4ty(pd)^:= '>'; + inc(pd,3); + end; + '&': begin + checkgrow(); + pchar5ty(pd)^:= '&'; + inc(pd,4); + end; + else begin + pd^:= ps^; + end; + end; + inc(ps); + inc(pd); + end; + setlength(result,pd-pmsechar(pointer(result))); + end; +end; + +var + fformatmacros: tformatmacrolist; + +function formatmse(const fmt: msestring; const args: array of const; + const formatsettings: tformatsettingsmse): msestring; +begin + result:= formatfunc.unicodeformat(fmt,args,formatsettings); +end; + +function formatmse(const fmt: msestring; const args: array of const): msestring; +begin + result:= formatmse(fmt,args,defaultformatsettingsmse); +end; + +function formatmacros: tformatmacrolist; +begin + if fformatmacros = nil then begin + fformatmacros:= tformatmacrolist.create( + [mao_curlybraceonly,mao_removeunknown]); + end; + result:= fformatmacros; +end; + +procedure checkformatmacros(var format: msestring); +begin + if (fformatmacros <> nil) and (findchar(format,'{') > 0) then begin + fformatmacros.expandmacros1(format); + end; +end; + +{$ifndef FPC} +function trystrtoqword(const s: string; out value: qword): boolean; +begin + result:= trystrtoint64(s,int64(value)); +end; + +function composedatetime(const adate: tdatetime; const atime: tdatetime): tdatetime; +begin + if date < 0 then begin + result := trunc(date) - abs(frac(time)); + end + else begin + result := trunc(date) + abs(frac(time)); + end; +end; +{$endif} + +//copied from FPC dati.inc + +function formatdatetimemse(const datetime: tdatetime; formatstr: msestring; + const formatsettings: tformatsettingsmse): msestring; +var + ResultLen: integer; + ResultBuffer: array[0..255] of msechar; + ResultCurrent: pmsechar; + + procedure StoreStr(Str: pmsechar; Len: integer); + begin + if ResultLen + Len < SizeOf(ResultBuffer) div 2 then begin + Move(Str^, ResultCurrent^, Len*sizeof(msechar)); + ResultCurrent := ResultCurrent + Len; + ResultLen := ResultLen + Len; + end ; + end ; + + procedure StoreString(const Str: msestring); + var Len: integer; + begin + Len := Length(Str); + if ResultLen + Len < SizeOf(ResultBuffer) div 2 then begin // strmove not safe + Move( pointer(Str)^,ResultCurrent^,Len*sizeof(msechar)); + ResultCurrent := ResultCurrent + Len; + ResultLen := ResultLen + Len; + end; + end; + + procedure StoreInt(Value, Digits: integer); + var S: msestring; Len: integer; + begin + S := IntToStrmse(Value); + Len := Length(S); + if Len < Digits then begin + S := copy(msestring('0000'), 1, Digits - Len) + S; + Len := Digits; + end ; + StoreStr(pmsechar(pointer(S)), Len); + end ; + +var + Year, Month, Day, DayOfWeek, Hour, Minute, Second, MilliSecond: word; + + procedure StoreFormat(const FormatStr: msestring); + var + Token,lastformattoken: msechar; + FormatCurrent: pmsechar; + FormatEnd: pmsechar; + Count: integer; + Clock12: boolean; + P: pmsechar; + tmp:integer; + + begin + with formatsettings do begin + FormatCurrent := Pmsechar(pointer(FormatStr)); + FormatEnd := FormatCurrent + Length(FormatStr); + Clock12 := false; + P := FormatCurrent; + while P < FormatEnd do begin + Token := charUpperCase(P^); + if (Token = '"') or (token = '''') then begin + P := P + 1; + while (P < FormatEnd) and (P^ <> Token) do + P := P + 1; + end + else if Token = 'A' then begin + if (mseStrLIComp(P, 'A/P', 3) = 0) or + (mseStrLIComp(P, 'AMPM', 4) = 0) or + (mseStrLIComp(P, 'AM/PM', 5) = 0) then begin + Clock12 := true; + break; + end ; + end ; + P := P + 1; + end ; + token:=#255; + lastformattoken:=' '; + while FormatCurrent < FormatEnd do + begin + Token := charUpperCase(FormatCurrent^); + Count := 1; + P := FormatCurrent + 1; + case Token of + '''', '"': begin + while (P < FormatEnd) and (p^ <> Token) do + P := P + 1; + P := P + 1; + Count := P - FormatCurrent; + StoreStr(FormatCurrent + 1, Count - 2); + end ; + 'A': begin + if mseStrLIComp(FormatCurrent, pmsechar(msestring('AMPM')), 4) = 0 then begin + Count := 4; + if Hour < 12 then StoreString(TimeAMString) + else StoreString(TimePMString); + end + else if mseStrLIComp(FormatCurrent, 'AM/PM', 5) = 0 then begin + Count := 5; + if Hour < 12 then StoreStr('am', 2) + else StoreStr('pm', 2); + end + else if mseStrLIComp(FormatCurrent, 'A/P', 3) = 0 then begin + Count := 3; + if Hour < 12 then StoreStr('a', 1) + else StoreStr('p', 1); + end + else +// Raise EConvertError.Create('Illegal character in format string'); + end ; + '/': StoreStr(@DateSeparator, 1); + ':': StoreStr(@TimeSeparator, 1); + ' ', 'C', 'D', 'H', 'I', 'M', 'N', 'S', 'T', 'Y','Z' : + begin + while (P < FormatEnd) and (charUpperCase(P^) = Token) do + P := P + 1; + Count := P - FormatCurrent; + case Token of + ' ': StoreStr(FormatCurrent, Count); + 'Y': begin + if Count>2 then + StoreInt(Year, 4) + else + StoreInt(Year mod 100, 2); + end; + 'M': begin + if lastformattoken='H' then + begin + if Count = 1 then + StoreInt(Minute, 0) + else + StoreInt(Minute, 2); + + end + else + begin + case Count of + 1: StoreInt(Month, 0); + 2: StoreInt(Month, 2); + 3: StoreString(ShortMonthNames[Month]); + 4: StoreString(LongMonthNames[Month]); + end; + end; + end; + 'D': begin + case Count of + 1: StoreInt(Day, 0); + 2: StoreInt(Day, 2); + 3: StoreString(ShortDayNames[DayOfWeek]); + 4: StoreString(LongDayNames[DayOfWeek]); + 5: StoreFormat(ShortDateFormat); + 6: StoreFormat(LongDateFormat); + end ; + end ; + 'H': begin + if Clock12 then begin + tmp:=hour mod 12; + if tmp=0 then tmp:=12; + if Count = 1 then StoreInt(tmp, 0) + else StoreInt(tmp, 2); + end + else begin + if Count = 1 then StoreInt(Hour, 0) + else StoreInt(Hour, 2); + end ; + end ; + 'N': begin + if Count = 1 then StoreInt(Minute, 0) + else StoreInt(Minute, 2); + end ; + 'S': begin + if Count = 1 then StoreInt(Second, 0) + else StoreInt(Second, 2); + end ; + 'Z': begin + if Count = 1 then StoreInt(MilliSecond, 0) + else StoreInt(MilliSecond, 3); + end ; + 'T': begin + if Count = 1 then StoreFormat(ShortTimeFormat) + else StoreFormat(LongTimeFormat); + end ; + 'C': begin + StoreFormat(ShortDateFormat); + if (Hour<>0) or (Minute<>0) or (Second<>0) then + begin + StoreString(' '); + StoreFormat(LongTimeFormat); + end; + end; + 'I': begin + case count of + 1: begin + StoreFormat('YYYY-MM-DD'); + end; + 2: begin + StoreFormat('YYYY-MM-DD"T"HH:MM:SS'); + end; + else begin + StoreFormat('YYYY-MM-DD"T"HH:MM:SS:ZZZ'); + end; + end; + end; + end; + lastformattoken:=token; + end; + else + StoreStr(@Token, 1); + end ; + FormatCurrent := FormatCurrent + Count; + end ; + end; + end ; + +begin + result:= ''; + if datetime = emptydatetime then begin + exit; + end; + + checkformatmacros(formatstr); + DecodeDateFully(DateTime, Year, Month, Day, DayOfWeek); + DecodeTime(DateTime, Hour, Minute, Second, MilliSecond); + ResultLen := 0; + ResultCurrent := @ResultBuffer[0]; + StoreFormat(FormatStr); +// ResultBuffer[ResultLen] := #0; +// result := StrPas(@ResultBuffer[0]); + setlength(result,resultlen); + move(resultbuffer,pointer(result)^,resultlen*sizeof(msechar)); + +end ; + +function formatdatetimemse(const datetime: tdatetime; + const formatstr: msestring): msestring; +begin + result:= formatdatetimemse(datetime,formatstr,defaultformatsettingsmse); +end; + +function formatdatetimemse(const formatstr: msestring; const datetime: tdatetime; + const formatsettings: tformatsettingsmse): msestring; +begin + result:= formatdatetimemse(datetime,formatstr,formatsettings); +end; + +function formatdatetimemse(const formatstr: msestring; + const datetime: tdatetime): msestring; +begin + result:= formatdatetimemse(datetime,formatstr,defaultformatsettingsmse); +end; + +(* +//copied from FPC sysstr.inc +//todo: optimize, use threadsave formatsettings + +Function FloatToTextFmt(Buffer: PmseChar; Value: Extended; format: PmseChar; + const formatsettings: tformatsettingsmse): Integer; + +Var + Digits: String[40]; { String Of Digits } + Exponent: String[8]; { Exponent strin } + FmtStart, FmtStop: PmseChar; { Start And End Of relevant part } + { Of format String } + ExpFmt, ExpSize: Integer; { Type And Length Of } + { exponential format chosen } + Placehold: Array[1..4] Of Integer; { Number Of placeholders In All } + { four Sections } + thousand: Boolean; { thousand separators? } + UnexpectedDigits: Integer; { Number Of unexpected Digits that } + { have To be inserted before the } + { First placeholder. } + DigitExponent: Integer; { Exponent Of First digit In } + { Digits Array. } + + { Find end of format section starting at P. False, if empty } + + Function GetSectionEnd(Var P: PmseChar): Boolean; + Var + C: mseChar; + SQ, DQ: Boolean; + Begin + Result := False; + SQ := False; + DQ := False; + C := P[0]; + While (C<>#0) And ((C<>';') Or SQ Or DQ) Do + Begin + Result := True; + Case C Of + #34: If Not SQ Then DQ := Not DQ; + #39: If Not DQ Then SQ := Not SQ; + End; + Inc(P); + C := P[0]; + End; + End; + + { Find start and end of format section to apply. If section doesn't exist, + use section 1. If section 2 is used, the sign of value is ignored. } + + Procedure GetSectionRange(section: Integer); + Var + Sec: Array[1..3] Of PmseChar; + SecOk: Array[1..3] Of Boolean; + Begin + Sec[1] := format; + SecOk[1] := GetSectionEnd(Sec[1]); + If section > 1 Then + Begin + Sec[2] := Sec[1]; + If Sec[2][0] <> #0 Then + Inc(Sec[2]); + SecOk[2] := GetSectionEnd(Sec[2]); + If section > 2 Then + Begin + Sec[3] := Sec[2]; + If Sec[3][0] <> #0 Then + Inc(Sec[3]); + SecOk[3] := GetSectionEnd(Sec[3]); + End; + End; + If Not SecOk[1] Then + FmtStart := Nil + Else + Begin + If Not SecOk[section] Then + section := 1 + Else If section = 2 Then + Value := -Value; { Remove sign } + If section = 1 Then FmtStart := format Else + Begin + FmtStart := Sec[section - 1]; + Inc(FmtStart); + End; + FmtStop := Sec[section]; + End; + End; + + { Find format section ranging from FmtStart to FmtStop. } + + Procedure GetFormatOptions; + Var + Fmt: PmseChar; + SQ, DQ: Boolean; + area: Integer; + Begin + SQ := False; + DQ := False; + Fmt := FmtStart; + ExpFmt := 0; + area := 1; + thousand := False; + Placehold[1] := 0; + Placehold[2] := 0; + Placehold[3] := 0; + Placehold[4] := 0; + While Fmt < FmtStop Do + Begin + Case Fmt[0] Of + #34: + Begin + If Not SQ Then + DQ := Not DQ; + Inc(Fmt); + End; + #39: + Begin + If Not DQ Then + SQ := Not SQ; + Inc(Fmt); + End; + Else + { This was 'if not SQ or DQ'. Looked wrong... } + If Not (SQ Or DQ) Then + Begin + Case Fmt[0] Of + '0': + Begin + Case area Of + 1: + area := 2; + 4: + Begin + area := 3; + Inc(Placehold[3], Placehold[4]); + Placehold[4] := 0; + End; + End; + Inc(Placehold[area]); + Inc(Fmt); + End; + + '#': + Begin + If area=3 Then + area:=4; + Inc(Placehold[area]); + Inc(Fmt); + End; + '.': + Begin + If area<3 Then + area:=3; + Inc(Fmt); + End; + ',': + Begin + thousand := True; + Inc(Fmt); + End; + 'e', 'E': + If ExpFmt = 0 Then + Begin + If (Fmt[0]='E') Then + ExpFmt:=1 + Else + ExpFmt := 3; + Inc(Fmt); + If (Fmt 0 Then + Begin + Inc(Fmt); + ExpSize := 0; + While (Fmt= '0') and (fmt^ <= '9') do +// (Fmt[0] In ['0'..'9']) Do + Begin + Inc(ExpSize); + Inc(Fmt); + End; + End; + End; + End + Else + Inc(Fmt); + Else { Case } + Inc(Fmt); + End; { Case } + End { Begin } + Else + Begin + Inc(Fmt) + End; + End; { Case } + End; { While .. Begin } + End; + + Procedure FloatToStr; + + Var + I, J, Exp, Width, Decimals, DecimalPoint, len: Integer; + + Begin + If ExpFmt = 0 Then + Begin + { Fixpoint } + Decimals:=Placehold[3]+Placehold[4]; + Width:=Placehold[1]+Placehold[2]+Decimals; + If (Decimals=0) Then + Str(Value:Width:0,Digits) + Else + Str(Value:Width+1:Decimals,Digits); + len:=Length(Digits); + { Find the decimal point } + If (Decimals=0) Then + DecimalPoint:=len+1 + Else + DecimalPoint:=len-Decimals; + { If value is very small, and no decimal places + are desired, remove the leading 0. } + If (Abs(Value) < 1) And (Placehold[2] = 0) Then + Begin + If (Placehold[1]=0) Then + Delete(Digits,DecimalPoint-1,1) + Else + Digits[DecimalPoint-1]:=' '; + End; + + { Convert optional zeroes to spaces. } + I:=len; + J:=DecimalPoint+Placehold[3]; + While (I>J) And (Digits[I]='0') Do + Begin + Digits[I] := ' '; + Dec(I); + End; + { If integer value and no obligatory decimal + places, remove decimal point. } + If (DecimalPoint < len) And (Digits[DecimalPoint + 1] = ' ') Then + Digits[DecimalPoint] := ' '; + { Convert spaces left from obligatory decimal point to zeroes. } + I:=DecimalPoint-Placehold[2]; + While (I Digits With Decimals + And adjusted Exponent. } + If Placehold[1]+Placehold[2]=0 Then + Placehold[1]:=1; + Decimals := Placehold[3] + Placehold[4]; + Width:=Placehold[1]+Placehold[2]+Decimals; + Str(Value:Width+8,Digits); + { Find and cut out exponent. Always the + last 6 characters in the string. + -> 0000E+0000 } + I:=Length(Digits)-5; + Val(Copy(Digits,I+1,5),Exp,J); + Exp:=Exp+1-(Placehold[1]+Placehold[2]); + Delete(Digits, I, 6); + { Str() always returns at least one digit after the decimal point. + If we don't want it, we have to remove it. } + If (Decimals=0) And (Placehold[1]+Placehold[2]<= 1) Then + Begin + If (Digits[4]>='5') Then + Begin + Inc(Digits[2]); + If (Digits[2]>'9') Then + Begin + Digits[2] := '1'; + Inc(Exp); + End; + End; + Delete(Digits, 3, 2); + DecimalPoint := Length(Digits) + 1; + End + Else + Begin + { Move decimal point at the desired position } + Delete(Digits, 3, 1); + DecimalPoint:=2+Placehold[1]+Placehold[2]; + If (Decimals<>0) Then + Insert('.',Digits,DecimalPoint); + End; + + { Convert optional zeroes to spaces. } + I := Length(Digits); + J := DecimalPoint + Placehold[3]; + While (I > J) And (Digits[I] = '0') Do + Begin + Digits[I] := ' '; + Dec(I); + End; + + { If integer number and no obligatory decimal paces, remove decimal point } + + If (DecimalPoint= 0 Then + Begin + If (ExpFmt In [1,3]) Then + Insert('+', Exponent, 1); + End + Else + Insert('-',Exponent,1); + If (ExpFmt<3) Then + Insert('E',Exponent,1) + Else + Insert('e',Exponent,1); + End; + DigitExponent:=DecimalPoint-2; + If (Digits[1]='-') Then + Dec(DigitExponent); + UnexpectedDigits:=DecimalPoint-1-(Placehold[1]+Placehold[2]); + End; + + Function PutResult: LongInt; + + Var + SQ, DQ: Boolean; + Fmt, Buf: PmseChar; + Dig, N: Integer; + + Begin + with formatsettings do begin + SQ := False; + DQ := False; + Fmt := FmtStart; + Buf := Buffer; + Dig := 1; + While (Fmt0) Then + Begin + { Everything unexpected is written before the first digit } + For N := 1 To UnexpectedDigits Do + Begin + Buf[0] := widechar(Digits[N]); + Inc(Buf); + If thousand And (Digits[N]<>'-') Then + Begin + If (DigitExponent Mod 3 = 0) And (DigitExponent>0) Then + Begin +// Buf[0] := widechar(ThousandSeparator); + Buf[0] := ThousandSeparator; + Inc(Buf); + End; + Dec(DigitExponent); + End; + End; + Inc(Dig, UnexpectedDigits); + End; + If (Digits[Dig]<>' ') Then + Begin + If (Digits[Dig]='.') Then + Buf[0] := DecimalSeparator +// Buf[0] := widechar(DecimalSeparator) + Else + Buf[0] := widechar(Digits[Dig]); + Inc(Buf); + If thousand And (DigitExponent Mod 3 = 0) And (DigitExponent > 0) Then + Begin +// Buf[0] := widechar(ThousandSeparator); + Buf[0] := ThousandSeparator; + Inc(Buf); + End; + End; + Inc(Dig); + Dec(DigitExponent); + Inc(Fmt); + End; + 'e', 'E': + Begin + If ExpFmt <> 0 Then + Begin + Inc(Fmt); + If Fmt < FmtStop Then + Begin +// If Fmt[0] In ['+', '-'] Then + If (Fmt[0] = '+') or (fmt[0] = '-') Then + Begin + Inc(Fmt, ExpSize); + For N:=1 To Length(Exponent) Do + Buf[N-1] := widechar(Exponent[N]); + Inc(Buf,Length(Exponent)); + ExpFmt:=0; + End; + Inc(Fmt); + End; + End + Else + Begin + { No legal exponential format. + Simply write the 'E' to the result. } + Buf[0] := Fmt[0]; + Inc(Buf); + Inc(Fmt); + End; + End; + Else { Case } + { Usual character } + If (Fmt[0]<>',') Then + Begin + Buf[0] := Fmt[0]; + Inc(Buf); + End; + Inc(Fmt); + End; { Case } + End + Else { IF } + Begin + { Character inside single or double quotes } + Buf[0] := Fmt[0]; + Inc(Buf); + Inc(Fmt); + End; + End; { Case } + End; { While .. Begin } +// Result:=PtrInt(Buf)-PtrInt(Buffer); + result:= buf - buffer; + end; + End; + +var + int1: integer; +begin + if value > 0 then begin + getsectionrange(1); + end + else begin + if (value < 0) then begin + getsectionrange(2) + end + else begin + getsectionrange(3); + end; + end; + if fmtstart = nil then begin + {$ifdef FPC} + result:= floattotext(pchar(buffer),value,ffgeneral,15,4); + {$else} + result:= floattotext(pchar(buffer),value,fvextended,ffgeneral,15,4); + {$endif} + end + else begin + getformatoptions; + if (expfmt = 0) and (abs(value) >= 1e18) then begin + {$ifdef FPC} + result:= floattotext(pchar(buffer),value,ffgeneral,15,4); + {$else} + result:= floattotext(pchar(buffer),value,fvextended,ffgeneral,15,4); + {$endif} + end + else begin + floattostr; + result:= putresult; + exit; + end; + end; + for int1:= result - 1 downto 0 do begin + pmsecharaty(buffer)^[int1]:= widechar(pcharaty(buffer)^[int1]); + //convert to msestring + end; +end; +*) + +function cstringtostringvar(var inp: pchar): string; + +const + quotechar = '"'; + escapechar = '\'; + +var + po1,po2: pchar; + int1,int2: integer; + ch1: char; + +begin + result:= ''; + if inp <> nil then begin + po1:= inp; + while true do begin + while (po1^ = ' ') do begin //first quote + inc(po1); + end; + if (po1^ <> quotechar) then begin + break; //end or no start quote + end; + inc(po1); + po2:= po1; //text + while true do begin + while (po1^ <> quotechar) and (po1^ <> escapechar) do begin + if (po1^ = #0) then begin + result:= ''; + inp:= nil; + exit; //error: no end quote + end; + inc(po1); + end; + int1:= po1-po2; //text length + int2:= length(result)+1; + setlength(result,length(result) + int1); + move(po2^,result[int2],int1); //add text + if po1^ = escapechar then begin + inc(po1); + case po1^ of + 'a': ch1:= #$07; + 'b': ch1:= #$08; + 'f': ch1:= #$0c; + 'n': ch1:= #$0a; + 'r': ch1:= #$0d; + 't': ch1:= #$09; + 'v': ch1:= #$0b; + '\': ch1:= '\'; + '''': ch1:= ''''; + '"': ch1:= '"'; + '?': ch1:= '?'; + '0'..'7': begin + po2:= po1; + for int1:= 0 to 2 do begin + if (po1^ < '0') or (po1^ > '7') then begin + break; + end; + inc(po1); + end; + ch1:= char(strtooct(psubstr(po2,po1))); + dec(po1); + end; + 'x','X': begin + inc(po1); + po2:= po1; + while (po1^ >= '0') and (po1^ <= '9') or + (po1^ >= 'a') and (po1^ <= 'f') or + (po1^ >= 'A') and (po1^ <= 'F') do begin + inc(po1); + end; + ch1:= char(strtohex(psubstr(po2,po1))); + dec(po1); + end; + else begin + ch1:= ' '; + end; + end; + result:= result + ch1; + inc(po1); + end + else begin + inc(po1); + break; + end; + po2:= po1; //past quote + end; + end; + inp:= po1; + end; +end; + +function cstringtostring(inp: pchar): string; +begin + result:= cstringtostringvar(inp); +end; + +function cstringtostring(const inp: string): string; +var + po1: pchar; +begin + po1:= pchar(inp); + result:= cstringtostringvar(po1); +end; + +function stringtocstring(const inp: pmsechar; + const count: integer): string; overload; +var + po1: pmsechar; + innum: boolean; + int1: integer; +begin + result:= '"'; + po1:= inp; + innum:= false; + for int1:= count - 1 downto 0 do begin +// if (po1^ < #$20) or (po1^ > #$ff) or (po1^ = #$7f) then begin + if (po1^ < #$20) or (po1^ >= #$7f) then begin + innum:= true; + if po1^ < #$100 then begin + result:= result + '\x'+hextostr(ord(po1^),2); + end + else begin + result:= result + '\x'+hextostr(ord(po1^),4); + end; + end + else begin + if po1^ = '"' then begin + result:= result + '\"'; + innum:= false; + end + else begin + if innum then begin + result:= result + '" "'+char(po1^); + innum:= false; + end + else begin + result:= result + char(po1^); + end; + end; + end; + inc(po1); + end; + result:= result + '"'; +end; + +function stringtocstring(const inp: msestring): string; +begin + result:= stringtocstring(pmsechar(pointer(inp)),length(inp)); +end; + +function stringtopascalstring(const value: msestring; + const maxlinelength: int32 = 0): string; +const + reserve = 32; +var + int1,int2,mle: integer; + i1: ptrint; + po1,ps,pse,pe: pchar; + p0: pointer; + ln,str1: string; + asciimode: boolean; +begin + if length(value) = 0 then begin + result:= ''''''; + end + else begin + ln:= lineend; + asciimode:= false; +// setlength(result,2+6*length(value)); +// // maxlength for single char: '#65535' = 2 + 6 + setlength(result,length(value)+reserve); + pe:= pointer(result)+length(result)-reserve; + po1:= pchar(pointer(result)); + ps:= po1; + mle:= maxlinelength-2; + if mle < 20 then begin + mle:= 20; + end; + pse:= ps+mle; +// int2:= 1; + for int1:= 1 to length(value) do begin + if maxlinelength > 0 then begin + if po1 >= pse then begin + if asciimode then begin + po1^:= ''''; + end + else begin + po1^:= ' '; + end; + inc(po1); + po1^:= '+'; + inc(po1); + move(pointer(ln)^,po1^,length(ln)); + inc(po1,length(ln)); + if asciimode then begin + po1^:= ''''; + inc(po1); + end; + ps:= po1; + pse:= ps+mle; + end; + end; + if po1 >= pe then begin + p0:= pointer(result); + setlength(result,length(result)*2+reserve); + i1:= pointer(result)-p0; + po1:= po1 + i1; + ps:= ps + i1; + pse:= pse + i1; + pe:= pointer(result)+length(result)-reserve; + end; + int2:= ord(value[int1]); + if (int2 >= 32) and (int2 < 127) then begin + if not asciimode then begin + asciimode:= true; + po1^:= ''''; + inc(po1); + end; + if char(int2) = '''' then begin + po1^:= ''''; //double quote + inc(po1); + end; + po1^:= char(int2); + inc(po1); + end + else begin + if asciimode then begin + asciimode:= false; + po1^:= ''''; + inc(po1); + end; + po1^:= '#'; + inc(po1); + str1:= '$'+hextostr(card32(int2),4); + move(pchar(pointer(str1))^,po1^,length(str1)); + inc(po1,length(str1)); + end; + end; + if asciimode then begin + po1^:= ''''; + inc(po1); + end; + setlength(result,po1-pchar(pointer(result))); + end; +end; + +function trypascalstringtostring(const value: string; + out res: msestring ): boolean; + +var + po1: pmsechar; + po2,po3: pmsechar; + int1: integer; + mstr1,source1: msestring; +begin + result:= false; + source1:= msestring(value); //assume locale encoding + setlength(res,length(source1)); //max length + po1:= pmsechar(pointer(res)); + po2:= pmsechar(source1); + while po2^ <> #0 do begin + case po2^ of + '#': begin + inc(po2); + if po2^ = '$' then begin + inc(po2); + po3:= po2; + while po2^ in ['0'..'9','a'..'f','A'..'F'] do begin + inc(po2); + end; + setstring(mstr1,po3,po2-po3); + po1^:= msechar(strtohex(mstr1)); + end + else begin + po3:= po2; + while (po2^ >= '0') and (po2^ <= '9') do begin + inc(po2); + end; + setstring(mstr1,po3,po2-po3); + po1^:= msechar(strtoint(mstr1)); + end; + inc(po1); + end; + '''': begin + inc(po2); //'..... + po3:= po2; + while (po2^ <> '''') and (po2^ <> #0) do begin + inc(po2) + end; + if po2^ <> #0 then begin + for int1:= 0 to po2 - po3 - 1 do begin //'abcd'...... + po1^:= msechar((po3+int1)^); + inc(po1); + end; + inc(po2); + if po2^ = '''' then begin //'abcd'? + po1^:= ''''; //'abcd'' + inc(po1); + end; + end + else begin + res:= ''; + exit; + end; + end; + ' ',c_tab: begin + inc(po2) + end + else begin + res:= ''; + exit; + end; + end; + end; + setlength(res,po1-pmsechar(pointer(res))); + result:= true; +end; + +function pascalstringtostring(const value: string): msestring; +begin + if not trypascalstringtostring(value,result) then begin + raise exception.Create('Invalid pascalstring: "'+value+'".'); + end; +end; + +function getpascalstring(var value: pchar): msestring; + +var + po2,po3: pchar; +// int1: integer; + str1: string; + charcount: integer; + + procedure addstring(const astr: msestring); + var + int1,int2: integer; + begin + int1:= length(astr); + int2:= charcount; + charcount:= charcount+int1; + if length(result) < charcount then begin + setlength(result,2*charcount+32); + end; + move(pointer(astr)^,(pmsechar(pointer(result))+int2)^,int1*sizeof(msechar)); + end; + +begin + result:= ''; + charcount:= 0; + po2:= value; + while po2^ <> #0 do begin + case po2^ of + '#': begin + inc(po2); + if po2^ = '$' then begin + inc(po2); + po3:= po2; + while po2^ in ['0'..'9','a'..'f','A'..'F'] do begin + inc(po2); + end; + setstring(str1,po3,po2-po3); + addstring(msechar(strtohex(str1))); + end + else begin + po3:= po2; + while (po2^ >= '0') and (po2^ <= '9') do begin + inc(po2); + end; + setstring(str1,po3,po2-po3); + addstring(msechar(strtoint(str1))); + end; + end; + '''': begin + inc(po2); //'..... + po3:= po2; + while (po2^ <> '''') and (po2^ <> #0) do begin + inc(po2) + end; + if po2^ <> #0 then begin + setstring(str1,po3,po2-po3); + addstring(msestring(str1)); + inc(po2); + if po2^ = '''' then begin //'abcd'? + addstring(''''); //'abcd'' + end; + end + else begin + result:= ''; + exit; + end; + end; + ' ',c_tab: begin + inc(po2) + end + else begin + break; + end; + end; + end; + setlength(result,charcount); + value:= po2; +end; + + +function encodebase64(const abinary: pbyte; acount: integer; + const maxlinelength: integer = defaultbase64linelength): string; + //todo: optimize +var + int1: integer; + ps,pe: pbyte; + pd,pline: pchar; + tail,linestep: integer; + by1: byte; +begin + result:= ''; + if acount > 0 then begin + int1:= ((acount+2) div 3)*4; + linestep:= maxlinelength and $fffffffc; //do not cut 4 char boundary + if maxlinelength > 0 then begin + if linestep = 0 then begin + linestep:= 4; + end; + int1:= int1 + 2*((int1+linestep-1)div linestep - 1); //return-linefeed + end; + setlength(result,int1); + ps:= abinary; + int1:= acount; + tail:= int1 mod 3; + pchar(pe):= pchar(ps)+int1-tail; + pd:= pointer(result); + if maxlinelength > 0 then begin + pline:= pd + linestep; + end + else begin + pline:= pointer(not ptruint(0)); + end; + while pchar(ps) < pchar(pe) do begin + if pd >= pline then begin + pd^:= c_return; + inc(pd); + pd^:= c_linefeed; + inc(pd); + pline:= pd+linestep; + end; + by1:= ps^; //s0 + pd^:= base64encoding[by1 shr 2]; //d0 + inc(ps); //s1 + inc(pd); //d1 + pd^:= base64encoding[((by1 shl 4) or (ps^ shr 4)) and base64mask]; + by1:= ps^ shl 2; + inc(ps); //s2 + inc(pd); //d2 + pd^:= base64encoding[(by1 or (ps^ shr 6)) and base64mask]; + inc(pd); //d3 + pd^:= base64encoding[ps^ and base64mask]; + inc(ps); + inc(pd); //d0 + end; + if tail > 0 then begin + if pd >= pline then begin + pd^:= c_return; + inc(pd); + pd^:= c_linefeed; + inc(pd); + end; + by1:= ps^; //s0 + pd^:= base64encoding[by1 shr 2]; //d0 + inc(pd); //d1 + pd^:= base64encoding[(by1 shl 4) and base64mask]; + if tail > 1 then begin + inc(ps); //s1 + pd^:= base64encoding[((by1 shl 4) or (ps^ shr 4)) and base64mask]; + inc(pd); //d2 + pd^:= base64encoding[(ps^ shl 2) and base64mask]; + end + else begin + inc(pd); //d2 + pd^:= '='; + end; + inc(pd); //d3 + pd^:= '='; + end; + end; +end; + +function encodebase64(const abinary: string; + const maxlinelength: integer = defaultbase64linelength): string; +begin + result:= encodebase64(pointer(abinary),length(abinary),maxlinelength); +end; + +function decodebase64(const atext: string): string; + //todo: optimize +label + endlab; +var + ps,pend: pchar; + pd: pbyte; + by1: byte; +begin + setlength(result,length(atext)); //>max + if atext <> '' then begin + ps:= pointer(atext); + pd:= pointer(result); + pend:= ps+length(atext); + while ps < pend do begin + by1:= base64decoding[ord(ps^)]; //s0 + while shortint(by1) < 0 do begin + inc(ps); + if (ps >= pend) or (char(by1) = '=') then begin + goto endlab; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= by1 shl 2; //d0 + inc(ps); + by1:= base64decoding[ord(ps^)]; //s1 + while shortint(by1) < 0 do begin + inc(ps); + if (ps >= pend) or (char(by1) = '=') then begin + goto endlab; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or (by1 shr 4); + inc(pd); //d1 + pd^:= by1 shl 4; + inc(ps); + by1:= base64decoding[ord(ps^)]; //s2 + while shortint(by1) < 0 do begin + inc(ps); + if (ps >= pend) or (char(by1) = '=') then begin + goto endlab; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or by1 shr 2; + inc(pd); //d2 + pd^:= by1 shl 6; + inc(ps); + by1:= base64decoding[ord(ps^)]; //s3 + while shortint(by1) < 0 do begin + inc(ps); + if (ps >= pend) or (char(by1) = '=') then begin + goto endlab; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or by1; + inc(pd); + inc(ps); //s0 + end; +endlab: + setlength(result,pchar(pointer(pd))-pchar(pointer(result))); + end; +end; + +procedure checkdateconvert(const convert: dateconvertty; var value: tdatetime); +begin + if value <> emptydatetime then begin + if convert = dc_toutc then begin + value:= localtimetoutc(value); + end + else begin + if convert = dc_tolocal then begin + value:= utctolocaltime(value); + end; + end; + end; +end; + +procedure checkdatereconvert(const convert: dateconvertty; var value: tdatetime); +begin + if value <> emptydatetime then begin + if convert = dc_tolocal then begin + value:= localtimetoutc(value); + end + else begin + if convert = dc_toutc then begin + value:= utctolocaltime(value); + end; + end; + end; +end; +(* +function stringtotime(const text: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +var + mstr1: msestring; + timesep: msechar; +begin + result:= true; + if text = ' ' then begin + if convert = dc_toutc then begin + value:= frac(nowutc); + end + else begin + value:= frac(nowlocal); + end; + end + else begin + if text = '' then begin + value:= emptydatetime; + end + else begin + timesep:= defaultformatsettingsmse.timeseparator; + if (countchars(text,timesep) = 0) and + (countchars(text,defaultformatsettingsmse.timeseparator) = 0) then begin + case length(text) of + 3,4: begin + mstr1:= copy(text,1,2)+timesep+copy(text,3,2); + end; + 5,6: begin + mstr1:= copy(text,1,2)+timesep+copy(text,3,2)+timesep+ + copy(text,5,2); + end; + else begin + mstr1:= text; + end; + end; + result:= sysutils.trystrtotime(mstr1,value); + end + else begin + result:= sysutils.trystrtotime(text,value); + end; + checkdateconvert(convert,value); + end; + end; +end; +*) +function timetostring(const avalue: tdatetime; const format: msestring = 't'): msestring; +begin + if avalue = emptydatetime then begin + result:= ''; + end + else begin + if format = '' then begin + result:= formatdatetimemse('t',avalue,defaultformatsettingsmse); + end + else begin + result:= formatdatetimemse(format,avalue,defaultformatsettingsmse); + end; + end; +end; + +function datetimetostring(const avalue: tdatetime; + const format: msestring = 'c'): msestring; +begin + if avalue = emptydatetime then begin + result:= ''; + end + else begin + if format = '' then begin + result:= formatdatetimemse('c',avalue,defaultformatsettingsmse); + end + else begin + result:= formatdatetimemse(format,avalue,defaultformatsettingsmse); + end; + end; +end; + +function datetostring(const avalue: tdatetime; + const format: msestring = 'c'): msestring; +begin + if avalue = emptydatetime then begin + result:= ''; + end + else begin + result:= datetimetostring(trunc(avalue),format); + end; +end; + +procedure formaterror(const value: string); +begin + raise exception.Create('Invalid value '''+value+'''.'); +end; + +procedure formaterror(const value: msestring); +begin + formaterror(ansistring(value)); +end; + +type + datetimeformattokenty = ( + dtft_default, // c shortdateformat + ' ' + longtimeformat + dtft_day, // d day of month + dtft_dayzero, // dd day of month (leading zero) + dtft_dayabbr, // ddd day of week (abbreviation) + dtft_dayfull, // dddd day of week (full) + dtft_shortdate, // ddddd shortdateformat + dtft_longdate, // dddddd longdateformat + dtft_month, // m month + dtft_monthzero, // mm month (leading zero) + dtft_monthabbr, // mmm month (abbreviation) + dtft_monthfull, // mmmm month (full) + dtft_year, // y year (2 digits) + dtft_yearzero, // yy year (two digits) + dtft_yearcentury, // yyyy year (with century) + dtft_hour, // h hour + dtft_hourzero, // hh hour (leading zero) + dtft_minute, // n minute + dtft_minutezero, // nn minute (leading zero) + dtft_second, // s second + dtft_secondzero, // ss second (leading zero) + dtft_shorttime, // t shorttimeformat + dtft_longtime, // tt longtimeformat + dtft_ampm, // ampm + dtft_amspm, // am/pm use 12 hour clock and + // display am and pm accordingly + dtft_ap, // a/p use 12 hour clock and display + // a and p accordingly + dtft_datesep, // / insert date seperator + dtft_timesep, // : insert time seperator + dtft_millisec // z milliseconds + ); + +dttokengroupty = (dttg_none,dttg_millisec,dttg_sec, + dttg_min,dttg_hour, + dttg_day,dttg_mon,dttg_year); +dttokeninfoty = record + token: datetimeformattokenty; + group: dttokengroupty; + chars: msestring; +end; + +const + tokeninfos: array[0..ord(high(datetimeformattokenty))] of dttokeninfoty = + ( //longest first + (token: dtft_default; group: dttg_none; chars: 'C'), //0 + (token: dtft_longdate; group: dttg_none; chars: 'DDDDDD'), //1 + (token: dtft_shortdate; group: dttg_none; chars: 'DDDDD'), //2 + (token: dtft_longtime; group: dttg_none; chars: 'TT'), //3 + (token: dtft_shorttime; group: dttg_none; chars: 'T'), //4 + (token: dtft_datesep; group: dttg_none; chars: '/'), //5 + (token: dtft_timesep; group: dttg_none; chars: ':'), //6 + + (token: dtft_amspm; group: dttg_none; chars: 'AM/PM'), //7 + (token: dtft_ampm; group: dttg_none; chars: 'AMPM'), + (token: dtft_dayfull; group: dttg_day; chars: 'DDDD'), + (token: dtft_monthfull; group: dttg_mon; chars: 'MMMM'), + (token: dtft_yearcentury; group: dttg_year; chars: 'YYYY'), + (token: dtft_ap; group: dttg_none; chars: 'A/P'), + (token: dtft_dayabbr; group: dttg_day; chars: 'DDD'), + (token: dtft_monthabbr; group: dttg_mon; chars: 'MMM'), + (token: dtft_dayzero; group: dttg_day; chars: 'DD'), + (token: dtft_monthzero; group: dttg_mon; chars: 'MM'), + (token: dtft_yearzero; group: dttg_year; chars: 'YY'), + (token: dtft_hourzero; group: dttg_hour; chars: 'HH'), + (token: dtft_minutezero; group: dttg_min; chars: 'NN'), + (token: dtft_secondzero; group: dttg_sec; chars: 'SS'), + (token: dtft_day; group: dttg_day; chars: 'D'), + (token: dtft_month; group: dttg_mon; chars: 'M'), + (token: dtft_year; group: dttg_year; chars: 'Y'), + (token: dtft_hour; group: dttg_hour; chars: 'H'), + (token: dtft_minute; group: dttg_min; chars: 'N'), + (token: dtft_second; group: dttg_sec; chars: 'S'), + (token: dtft_millisec; group: dttg_millisec; chars: 'Z') + ); + + startscan = 7; + +//todo: use format cache + +type + scaninfoty = record + index: integer; + group: dttokengroupty; + end; + +function comparescan(const l,r): integer; +begin + result:= scaninfoty(l).index - scaninfoty(r).index; +end; + +function trystringtodatetime(const text: msestring; + aformat: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; + procedure removequotes(var astring: msestring); + var + po1: pmsechar; + begin + uniquestring(astring); + po1:= pmsechar(astring); + while po1^ <> #0 do begin + case po1^ of + '"': begin + repeat + po1^:= ' '; + inc(po1) + until (po1^ = '"') or (po1^ = #0 ); + if po1^ <> #0 then begin + po1^:= ' '; + end; + end; + end; + case po1^ of + '''': begin + repeat + po1^:= ' '; + inc(po1) + until (po1^ = '''') or (po1^ = #0 ); + if po1^ <> #0 then begin + po1^:= ' '; + end; + end; + else begin + if (po1^ >= 'a') and (po1^ <= 'z') then begin + dec(po1^,ord('a')-ord('A')); + end; + inc(po1); + end; + end; + end; + end; //removequotes + + procedure expand(var astring: msestring; const ainfo: dttokeninfoty; + const substitute: msestring); + var + mstr1,mstr2: msestring; + int1,int2: integer; + begin + mstr1:= astring; + mstr2:= substitute; + removequotes(mstr2); + int2:= length(ainfo.chars); + int1:= 1; + while true do begin + int1:= mseposex(ainfo.chars,mstr1,int1); //no recursion + if int1 = 0 then begin + break; + end; + mstr1:= copy(mstr1,1,int1-1)+mstr2+copy(mstr1,int1+int2,bigint); + int1:= int1 + int2; + end; + astring:= mstr1; + end; //expand + +var + scanar: array of scaninfoty; + scanindex: integer; + + procedure scan(var astring: msestring; const ainfo: dttokeninfoty); + var + po1: pmsecharaty; + int1,int2,int3: integer; + begin + int1:= 1; + while true do begin + int1:= mseposex(ainfo.chars,astring,int1); //no recursion + if int1 = 0 then begin + break; + end; + with scanar[scanindex] do begin + index:= int1; + group:= ainfo.group; + end; + inc(scanindex); + po1:= @astring[int1]; + int3:= length(ainfo.chars); + for int2:= 0 to int3-1 do begin + po1^[int2]:= ' '; + end; + int1:= int1 + int3; + end; + end; //scan + +var + dateorder: array[0..2] of dttokengroupty; + { = (dttg_none,dttg_none,dttg_none); does not work in delphi} + + function finddateorder(const agroup: dttokengroupty): integer; + var + int1: integer; + begin + result:= -1; + for int1:= 0 to high(dateorder) do begin + if agroup = dateorder[int1] then begin + result:= int1; + break; + end; + end; + end; + +var + mstr1: msestring; + int1,int2,int3,int4,int5: integer; + dt1,dt2: tdatetime; + grouporder: array of dttokengroupty; + groupused: array[dttokengroupty] of boolean; + ar1: msestringarty; + datear,timear: integerarty; + po1,po2: pmsechar; + tisep: msechar; + year,month,defmonth,day,hour,minute,second,millisecond: word; + ispm,hasmonthname,hasdateformat,hastimeformat: boolean; + refdate: tdatetime; + defaultdateorder: array[0..2] of dttokengroupty; + { = (dttg_year,dttg_mon,dttg_day);} + +begin + checkformatmacros(aformat); + result:= false; + if text = '' then begin + value:= emptydatetime; + result:= true; + exit; + end + else begin + for int1:= 0 to high(dateorder) do begin + dateorder[int1]:= dttg_none; //delphi compatibility + end; + defaultdateorder[0]:= dttg_year; + defaultdateorder[1]:= dttg_mon; + defaultdateorder[2]:= dttg_day; + + if convert = dc_toutc then begin + refdate:= nowutc; + end + else begin + refdate:= nowlocal; + end; + if aformat = '' then begin + mstr1:= 'c'; + end + else begin + mstr1:= aformat; + end; + removequotes(mstr1); + expand(mstr1,tokeninfos[0],defaultformatsettingsmse.shortdateformat + ' ' + + defaultformatsettingsmse.longtimeformat); //c + expand(mstr1,tokeninfos[1],defaultformatsettingsmse.longdateformat); //dddddd + expand(mstr1,tokeninfos[2],defaultformatsettingsmse.shortdateformat);//ddddd + expand(mstr1,tokeninfos[3],defaultformatsettingsmse.longtimeformat); //tt + expand(mstr1,tokeninfos[4],defaultformatsettingsmse.shorttimeformat);//t + allocuninitedarray(length(mstr1),sizeof(scaninfoty{scanar[0]}),scanar); //max + //fpc 3.0 warning + scanindex:= 0; + for int1:= startscan to high(tokeninfos) do begin + scan(mstr1,tokeninfos[int1]); + end; + setlength(scanar,scanindex); + sortarray(scanar,sizeof(scanar[0]),@comparescan); + fillchar(groupused,sizeof(groupused),0); + allocuninitedarray(length(scanar),sizeof(scanar[0]),grouporder); //max + int2:= 0; + for int1:= 0 to high(scanar) do begin + with scanar[int1] do begin + if not groupused[group] then begin + groupused[group]:= true; + grouporder[int2]:= group; + inc(int2); + end; + end; + end; + setlength(grouporder,int2); + int2:= 0; + hastimeformat:= false; + for int1:= 0 to high(grouporder) do begin + if grouporder[int1] in [dttg_hour,dttg_min,dttg_sec,dttg_millisec] then begin + hastimeformat:= true; + end; + end; + hasdateformat:= false; + for int1:= 0 to high(grouporder) do begin + if grouporder[int1] in [dttg_year,dttg_mon,dttg_day] then begin + hasdateformat:= true; + dateorder[int2]:= grouporder[int1]; + inc(int2); + if int2 > high(dateorder) then begin + break; + end; + end; + end; + for int1:= 0 to high(dateorder)do begin + if dateorder[int1] = dttg_none then begin + break; + end; + for int2:= high(defaultdateorder) downto 0 do begin + if defaultdateorder[int2] = dateorder[int1] then begin + defaultdateorder[int2]:= dttg_none; + break; + end; + end; + end; + for int1:= high(dateorder) downto 0 do begin + if dateorder[int1] <> dttg_none then begin + break; + end; + for int2:= high(defaultdateorder) downto 0 do begin + if defaultdateorder[int2] <> dttg_none then begin + dateorder[int1]:= defaultdateorder[int2]; + defaultdateorder[int2]:= dttg_none; + break; + end; + end; + end; + + int2:= length(text); + if (int2 > 2) and isnumber(text) then begin + mstr1:= ''; + int1:= 1; + while int1 <= int2 do begin + mstr1:= mstr1+copy(text,int1,2)+' '; + int1:= int1 + 2; + end; + end + else begin + mstr1:= struppercase(text); + end; + setlength(ar1,length(mstr1)); //max + int2:= 0; + po1:= pmsechar(mstr1); + tisep:= defaultformatsettingsmse.timeseparator; + while po1^ <> #0 do begin //split numerals + case po1^ of + '0'..'9': begin + po2:= po1; + while (po1^ >= '0') and (po1^ <= '9') do begin + inc(po1); + end; + int3:= po1-po2; + setlength(ar1[int2],int3); + move(po2^,pointer(ar1[int2])^,int3*sizeof(msechar)); + inc(int2); + dec(po1); + end; + 'A','P': begin + setlength(ar1[int2],1); + ar1[int2]:= po1^; + inc(int2); + inc(po1); + if po1^ <> 'M' then begin + dec(po1) + end; + end; + else begin + if po1^ = tisep then begin + setlength(ar1[int2],1); + ar1[int2]:= ':'; + inc(int2); + end; + end; + end; + inc(po1); + end; + setlength(ar1,int2); + + month:= 0; //check month names + hasmonthname:= false; + for int1:= 1 to 12 do begin + if pos(struppercase(defaultformatsettingsmse.longmonthnames[int1]), + mstr1) <> 0 then begin + month:= int1; + hasmonthname:= true; + break; + end; + end; + if month = 0 then begin + for int1:= 1 to 12 do begin + if pos(struppercase(defaultformatsettingsmse.shortmonthnames[int1]), + mstr1) <> 0 then begin + month:= int1; + hasmonthname:= true; + break; + end; + end; + end; + + ispm:= false; //split date/time formats + setlength(datear,length(ar1)); //max + setlength(timear,length(ar1)); //max + int2:= 0; + int3:= 0; + for int1:= 0 to high(ar1) do begin + case ar1[int1][1] of + 'P': begin + ispm:= true; + end; + '0'..'9': begin + if (int1 > 0) and (ar1[int1-1][1] = ':') or + (int1 < high(ar1)) and (ar1[int1+1][1] = ':') then begin + timear[int3]:= int1; + inc(int3); + end + else begin + datear[int2]:= int1; + inc(int2); + end; + end; + end; + end; + + setlength(datear,int2); + setlength(timear,int3); + decodedate(refdate,year,defmonth,day); +// decodetime(refdate,hour,minute,second,millisecond); + if (high(timear) < 0) and not hasdateformat then begin + timear:= datear; //use entries for time + datear:= nil; + end; + case high(datear) of + -1: begin + end; + 0: begin + day:= strtoint(ar1[datear[0]]); + end; + 1: begin + if month = 0 then begin //no month name found + if finddateorder(dttg_mon) > finddateorder(dttg_day) then begin + day:= strtoint(ar1[datear[0]]); + month:= strtoint(ar1[datear[1]]); + end + else begin + day:= strtoint(ar1[datear[1]]); + month:= strtoint(ar1[datear[0]]); + end; + end + else begin + if finddateorder(dttg_year) > finddateorder(dttg_day) then begin + day:= strtoint(ar1[datear[0]]); + year:= strtoint(ar1[datear[1]]); + end + else begin + day:= strtoint(ar1[datear[1]]); + year:= strtoint(ar1[datear[0]]); + end; + end; + end; + else begin //>= 2 + for int1:= 0 to 2 do begin + mstr1:= ar1[datear[int1]]; + int2:= strtoint(mstr1); + case dateorder[int1] of + dttg_year: begin + if length(mstr1) <= 2 then begin + int3:= defaultformatsettingsmse.twodigityearcenturywindow; + int4:= year-int3; //window start + int5:= int4 div 100; //century + if (int3 <> 0) and ((int4 mod 100) > int2) then begin + inc(int5); + end; + int2:= int2 + int5 * 100; + end; + year:= int2; + end; + dttg_mon: begin + month:= int2; + end; + dttg_day: begin + day:= int2; + end; + end; + end; + end; + end; + if month = 0 then begin + month:= defmonth; //use current month + end; + int1:= high(timear); + if int1 >= 0 then begin + if int1 >= 3 then begin + millisecond:= strtoint(ar1[timear[3]]); + end + else begin + millisecond:= 0; + end; + if int1 >= 2 then begin + second:= strtoint(ar1[timear[2]]); + end + else begin + second:= 0; + end; + if int1 >= 1 then begin + minute:= strtoint(ar1[timear[1]]); + end + else begin + minute:= 0; + end; + hour:= strtoint(ar1[timear[0]]); + if ispm and (hour < 12) then begin + hour:= hour + 12; + end; + if high(datear) >= 0 then begin + if not tryencodedate(year,month,day,dt1) then begin + exit; + end; + if not tryencodetime(hour,minute,second,millisecond,dt2) then begin + exit; + end; + value:= composedatetime(dt1,dt2); + result:= true; + end + else begin + if not tryencodetime(hour,minute,second,millisecond,value) then begin + exit; + end; + result:= true; + end; + end + else begin + if (high(datear) >= 0) or hasmonthname then begin + if not tryencodedate(year,month,day,value) then begin + exit; + end; + result:= true; + end + else begin + if text = ' ' then begin + result:= true; + if hasdateformat and hastimeformat or + not(hasdateformat or hastimeformat) then begin + value:= refdate; + end + else begin + if hasdateformat then begin + value:= trunc(refdate); + end + else begin + value:= frac(refdate); + end; + end; + exit; + end; + end; + end; + end; + if result then begin + checkdateconvert(convert,value); + end; +end; + +function stringtodatetime(const avalue: msestring; const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtodatetime(avalue,aformat,result,convert) then begin + formaterror(avalue); + end; +end; + +function trystringtodatetime(const text: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +var + mstr1: msestring; + datsep: msechar; +begin + result:= true; + if text = '' then begin + value:= emptydatetime; + end + else begin + if text = ' ' then begin + if convert = dc_toutc then begin + value:= nowutc; + end + else begin + value:= nowlocal; + end; + end + else begin + datsep:= defaultformatsettingsmse.dateseparator; + if (countchars(text,datsep) = 0) and + (countchars(text,defaultformatsettingsmse.timeseparator) = 0) then begin + case length(text) of + 3,4: begin + mstr1:= copy(text,1,2)+datsep+copy(text,3,2); + end; + 5,6: begin + mstr1:= copy(text,1,2)+datsep+copy(text,3,2)+datsep+ + copy(text,5,2); + end; + else begin + mstr1:= text; + end; + end; + result:= trystrtodatetime(ansistring(mstr1),value); + end + else begin + result:= trystrtodatetime(ansistring(text),value); + end; + if result then begin + checkdateconvert(convert,value); + end; + end; + end; +end; + +function stringtodatetime(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtodatetime(avalue,result,convert) then begin + formaterror(avalue); + end; +end; + +function trystringtodate(const text: msestring; + const aformat: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +begin + if text = '' then begin + value:= emptydatetime; + result:= true; + end + else begin + result:= trystringtodatetime(text,aformat,value,convert); + if result then begin + value:= trunc(value); + end; + end; +end; + +function stringtodate(const avalue: msestring; + const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtodate(avalue,aformat,result,convert) then begin + formaterror(avalue); + end; +end; + +function trystringtodate(const text: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +begin + if text = '' then begin + value:= emptydatetime; + result:= true; + end + else begin + result:= trystringtodatetime(text,value,convert); + if result then begin + value:= trunc(value); + end; + end; +end; + +function stringtodate(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtodate(avalue,result,convert) then begin + formaterror(avalue); + end; +end; + +function trystringtotime(const text: msestring; + const aformat: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +var + mstr1: msestring; +begin + if text = '' then begin + value:= emptydatetime; + result:= true; + end + else begin + if aformat = '' then begin + mstr1:= 'tt'; + end + else begin + mstr1:= aformat; + end; + result:= trystringtodatetime(text,mstr1,value,convert); + if result then begin + value:= frac(value); + end; + end; +end; + +function stringtotime(const avalue: msestring; + const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtotime(avalue,aformat,result,convert) then begin + formaterror(avalue); + end; +end; + +function trystringtotime(const text: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +//var +// mstr1: msestring; +begin + if text = '' then begin + value:= emptydatetime; + result:= true; + end + else begin + result:= trystringtodatetime(text,value,convert); + if result then begin + value:= frac(value); + end; + end; +end; + +function stringtotime(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtotime(avalue,result,convert) then begin + formaterror(avalue); + end; +end; + +function timemse(const value: tdatetime): tdatetime; + //bringt timeanteil im mseformat +begin + result:= frac(value); +// if result = 0 then begin +// result:= nulltime; +// end; +end; + +function bcdtoint(inp: byte): integer; +begin + result:= ((inp and $f0) shr 4) * 10 + (inp and $0f); +end; + +function inttobcd(inp: integer): byte; +begin + result:= byte(((inp div 10) shl 4) + (inp mod 10)) +end; + +function formatfloatmse(value: double; format: msestring; + const formatsettings: tformatsettingsmse; + const dot: boolean = false): msestring; + +var + po1,po2: pmsechar; + expsign{,noexpsign}: boolean; + + procedure quote; + begin + case po2^ of + '''': begin //'quoted string + inc(po2); + while po2^ <> #0 do begin + if po2^ = '''' then begin + inc(po2); + if po2^ <> '''' then begin + break; + end; + end; + po1^:= po2^; + inc(po1); + inc(po2); + end; + end; + '"': begin //"quoted string + inc(po2); + while po2^ <> #0 do begin + if po2^ = '"' then begin + inc(po2); + if po2^ <> '"' then begin + break; + end; + end; + po1^:= po2^; + inc(po1); + inc(po2); + end; + end; + end; + end; + + procedure checkexp; + begin + if (po2+1)^ = '+' then begin + expsign:= true; + inc(po2); + end + else begin + if (po2+1)^ = '-' then begin + inc(po2); + end; + end; + end; + +var + int1,int2,int3: integer; + decimalsep,thousandsep: msechar; + intopt,intmust,fracmust,fracopt,expopt,expmust: integer; + decifound,doubledecifound,thousandfound,numberprinted,expofound, + engfound,engsymfound,engsymnospacefound: boolean; + mstr1: msestring; + format1: msestring; + mantissaend: integer; + ar1: array[0..2] of integer; //indexes positive, negative, zero + expchar: msechar; + bo1: boolean; + po3,po4: pmsechar; + +begin + result:= ''; + if value = emptyreal then begin + exit; + end; + checkformatmacros(format); + ar1[0]:= 0; + with formatsettings do begin + if dot then begin + decimalsep:= '.'; + end + else begin + decimalsep:= decimalseparator; + end; + bo1:= format = 'C'; + if (format = 'c') or bo1 then begin + if bo1 then begin + mstr1:= ''; + end + else begin + mstr1:= currencystring; + end; + if value < 0 then begin + case negcurrformat of + 0: begin + result:= '('+mstr1; + end; + 1: begin + result:= '-'+mstr1; + end; + 2: begin + result:= mstr1+'-'; + end; + 3: begin + result:= mstr1; + end; + 4,15: begin + result:= '('; + end; + 5,8: begin + result:= '-'; + end; + 9: begin + result:= '-'+mstr1+' '; + end; + 11: begin + result:= mstr1+' '; + end; + 12: begin + result:= mstr1+' -'; + end; + 14: begin + result:= '('+mstr1+' '; + end; + end; + end + else begin + case currencyformat of + 0: begin + result:= mstr1; + end; + 2: begin + result:= mstr1 + ' '; + end; + end; + end; + result:= result+doubletostring(abs(value),currencydecimals, + fsm_fix,decimalsep,thousandseparator); + if value < 0 then begin + case negcurrformat of + 0,14: begin + result:= result + ')'; + end; + 3,11: begin + result:= result + '-'; + end; + 4: begin + result:= result + mstr1 + ')'; + end; + 5: begin + result:= result + mstr1; + end; + 6: begin + result:= result + '-' + mstr1; + end; + 7: begin + result:= result + mstr1 + '-'; + end; + 8: begin + result:= result + ' ' + mstr1; + end; + 10: begin + result:= result + ' ' + mstr1 + '-'; + end; + 13: begin + result:= result + '- ' + mstr1; + end; + 15: begin + result:= result + ' ' + mstr1 + ')' + end; + end; + end + else begin + case currencyformat of + 1: begin + result:= result + mstr1; + end; + 3: begin + result:= result + ' ' + mstr1; + end; + end; + end; + exit; + end; + end; + expchar:= 'E'; + setlength(result,length(format)+50); //max + numberprinted:= false; + po1:= pmsechar(result); + po2:= pmsechar(format); + int1:= 0; //arrayindex + while po2^ <> #0 do begin + quote; + if po2^ = ';' then begin + ar1[int1]:= po2 - pmsechar(pointer(format)); + inc(int1); + if int1 = 3 then begin + break; + end; + end; + inc(po2); + end; + if int1 < 3 then begin + ar1[int1]:= length(format); + end; + if (value = 0) and (int1 >= 2) then begin + setlength(format1,ar1[2]-ar1[1]-1); + move((pmsechar(pointer(format))+ar1[1]+1)^,pmsechar(pointer(format1))^, + (ar1[2]-ar1[1]-1)*sizeof(msechar)); + po2:= pmsechar(format1); + end + else begin + if (value < 0) and (int1 >= 1) then begin + setlength(format1,ar1[1]-ar1[0]-1); + move((pmsechar(pointer(format))+ar1[0]+1)^,pmsechar(pointer(format1))^, + (ar1[1]-ar1[0]-1)*sizeof(msechar)); + po2:= pmsechar(format1); + end + else begin + setlength(format1,ar1[0]); + move((pmsechar(pointer(format)))^,pmsechar(pointer(format1))^, + (ar1[0])*sizeof(msechar)); + po2:= pmsechar(format1); + end; + end; + if format1 = '' then begin + result:= doubletostring(value,0,fsm_default,decimalsep); + end + else begin + if int1 > 0 then begin + value:= abs(value); //no sign + end; + po1:= pmsechar(result); + while po2^ <> #0 do begin + quote; + case po2^ of + #0: begin //was terminating quote + end; + ',','.','0','#': begin + intopt:= 0; + intmust:= 0; + fracopt:= 0; + fracmust:= 0; + expopt:= 0; + expmust:= 0; + decifound:= false; + doubledecifound:= false; + thousandfound:= false; + expofound:= false; + engfound:= false; + engsymfound:= false; + engsymnospacefound:= false; + expsign:= false; + while po2^ <> #0 do begin + case po2^ of + '.': begin + decifound:= true; + if (po2+1)^ = '.' then begin + doubledecifound:= true; + end; + end; + ',': begin + thousandfound:= true; + end; + 'e','E': begin + expofound:= true; + expchar:= po2^; + checkexp; + end; + 'f','F': begin + engfound:= true; + expchar:= msechar(ord(po2^)-1); + checkexp; + end; + 'g','G': begin + engsymfound:= true; + engfound:= true; + if po2^ = 'g' then begin + engsymnospacefound:= true; + end; + expchar:= msechar(ord(po2^)-2); + checkexp; + end; + '0': begin + if expofound or engfound then begin + inc(expmust); + end + else begin + if decifound then begin + inc(fracmust); + end + else begin + inc(intmust); + end; + end; + end; + '#': begin + if expofound or engfound then begin + inc(expopt); + end + else begin + if decifound then begin + inc(fracopt); + end + else begin + inc(intopt); + end; + end; + end + else begin + break; + end; + end; + inc(po2); + end; + if not numberprinted then begin + numberprinted:= true; + if thousandfound then begin + thousandsep:= formatsettings.thousandseparator; + end + else begin + thousandsep:= #0; + end; + if expofound then begin + mstr1:= doubletostring(value,fracmust+fracopt,fsm_sci,decimalsep, + thousandsep); + end + else begin + if engfound then begin + if engsymfound then begin + int1:= ord(fsm_engsymfix) - ord(fsm_engfix); + end + else begin + int1:= 0; + end; + if not doubledecifound then begin + mstr1:= doubletostring(value,fracopt+fracmust, + floatstringmodety(ord(fsm_engfix)+int1),decimalsep,thousandsep); + end + else begin + mstr1:= doubletostring(value,fracopt+fracmust, + floatstringmodety(ord(fsm_engflo)+int1),decimalsep,thousandsep); + if mstr1 <> '' then begin + po3:= pointer(mstr1); + if po3^ = '-' then begin + inc(po3); + end; + po4:= po3; + while (po3^ >= '0') and (po3^ <= '9') do begin + //no thousandsep possible + inc(po3); + end; + int1:= po3-po4-1; + fracmust:= fracmust-int1; + if fracmust < 0 then begin + fracopt:= fracopt+fracmust; + fracmust:= 0; + if fracopt < 0 then begin + fracopt:= 0; + end; + end; + end; + end; + end + else begin + if intopt+intmust+fracmust+fracopt = 0 then begin + mstr1:= doubletostring(value,0,fsm_default,decimalsep,thousandsep); + end + else begin + mstr1:= doubletostring(value,fracmust+fracopt,fsm_fix, + decimalsep,thousandsep); + end; + end; + end; + if expofound or engfound then begin //format exponent + if (length(mstr1) > 5) and (mstr1[length(mstr1)-4] = expochar) then begin + if {noexpsign or} not expsign then begin + int1:= length(mstr1)-3; + if mstr1[int1] = '+' then begin + delete(mstr1,int1,1); //remove exp sign + end; + end; + expmust:= expmust+expopt; + if expmust = 0 then begin + expmust:= 1; + end; + int2:= length(mstr1)-expmust+1; //last zero + int3:= length(mstr1)-2; //firstzero + for int1:= int3 to int2 do begin + if mstr1[int1] <> '0' then begin + int2:= int1; + break; + end; + end; + delete(mstr1,int3,int2-int3); //remove leading zeros end; + end; + end; + + int1:= findlastchar(mstr1,decimalsep)-1; //format mantissa + if int1 <= 0 then begin + int1:= length(mstr1); + end; + int2:= 1; + if mstr1[1] = '-' then begin + inc(int2); //firstnumber + end; + if (intmust = 0) and (mstr1[int2] = '0') then begin + delete(mstr1,int2,1); //remove first 0 + dec(int1); + end; + int3:= intmust - int1 + int2 - 1; + if thousandsep <> #0 then begin + int3:= int3 + (int1 + int2 - 1) div 4; + end; + if int3 > 0 then begin + insert(copy(msenullen,1,int3),mstr1,int2); //insert zeros + inc(int1,int3); + end; + int3:= intmust + intopt - int1 + int2 - 1; + if int3 > 0 then begin + insert(copy(msespace,1,int3),mstr1,1); //insert spaces + inc(int1,int3); + end; + int2:= int1 + fracmust+1; + mantissaend:= findchar(mstr1,expochar); //ok for exa + if (mantissaend > 0) and (mantissaend < length(mstr1)) then begin + //not exa + mstr1[mantissaend]:= expchar; + end + else begin + if (mantissaend = 0) and engsymfound then begin + mantissaend:= length(mstr1); + end; + end; + dec(mantissaend); + if mantissaend <= 0 then begin + mantissaend:= length(mstr1); + end; + for int3:= mantissaend downto int2 do begin + if (mstr1[int3] <> '0') then begin //remove traling zeros + int2:= int3; + break; + end; + end; + if engsymnospacefound and (mstr1 <> '') and + (mstr1[length(mstr1)] = ' ') then begin + setlength(mstr1,length(mstr1)-1); + end; + if int2 < length(mstr1) then begin + if mstr1[int2] = decimalsep then begin + dec(int2); + end; + delete(mstr1,int2+1,mantissaend-int2); + end; + move(pointer(mstr1)^,po1^,length(mstr1)*sizeof(msechar)); + inc(po1,length(mstr1)); + end; + end + else begin + po1^:= po2^; + inc(po1); + inc(po2); + end; + end; + end; + setlength(result,po1-pmsechar(result)); + end; +end; + +function formatfloatmse(const value: double; const format: msestring; + const dot: boolean = false): msestring; overload; +begin + result:= formatfloatmse(value,format,defaultformatsettingsmse,dot); +end; + +function realtostrmse(const value: double; + const dot: boolean = false): msestring; +var + sep: msechar; +begin + sep:= '.'; + if not dot then begin + sep:= defaultformatsettingsmse.decimalseparator; + end; + result:= doubletostring(value,0,fsm_default,sep); +end; + +function realtytostrmse(const value: double; + const dot: boolean = false): msestring; +begin + if value = emptyreal then begin + result:= ''; + end + else begin + result:= realtostrmse(value,dot); + end; +end; + +function inttostr(const value: integer): string; +var + buffer: array[0..22] of char; + int1,int2: integer; + lwo1,lwo2: longword; +begin + lwo1:= abs(value); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= char(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + if value < 0 then begin + buffer[int1]:= char('-'); + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(char)); +end; + +function inttostrmse(const value: integer): msestring; +var + buffer: array[0..22] of msechar; + int1,int2: integer; + lwo1,lwo2: longword; +begin + lwo1:= abs(value); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + if value < 0 then begin + buffer[int1]:= msechar('-'); + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(msechar)); +end; + +function inttostr(const value: longword): string; +var + buffer: array[0..22] of char; + int1,int2: integer; + lwo1,lwo2: longword; +begin + lwo1:= value; + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= char(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(char)); +end; + +function inttostrmse(const value: longword): msestring; +var + buffer: array[0..22] of msechar; + int1,int2: integer; + lwo1,lwo2: longword; +begin + lwo1:= value; + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(msechar)); +end; + +function inttostr(const value: int64): string; +var + buffer: array[0..22] of char; + int1,int2: integer; + lwo1,lwo2: qword; +begin + lwo1:= abs(value); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= char(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + if value < 0 then begin + buffer[int1]:= char('-'); + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(char)); +end; + +function inttostrmse(const value: int64): msestring; +var + buffer: array[0..22] of msechar; + int1,int2: integer; + lwo1,lwo2: qword; +begin + lwo1:= abs(value); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + if value < 0 then begin + buffer[int1]:= msechar('-'); + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(msechar)); +end; + +function inttostr(const value: qword): string; +var + buffer: array[0..22] of char; + int1,int2: integer; + lwo1,lwo2: qword; +begin + lwo1:= value; + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= char(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(char)); +end; + +function inttostrmse(const value: qword): msestring; +var + buffer: array[0..22] of msechar; + int1,int2: integer; + lwo1,lwo2: qword; +begin + lwo1:= value; + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(msechar)); +end; +{ +function formatfloatmse(const value: double; const format: msestring; + const dot: boolean = false): msestring; +var + int1: integer; +begin + setlength(result,length(format)+200); //max + int1:= floattotextfmt(pmsechar(result),value,pmsechar(format), + defaultformatsettingsmse); + setlength(result,int1); + if dot then begin +// replacechar1(result,widechar(decimalseparator),widechar('.')); + replacechar1(result,defaultformatsettingsmse.decimalseparator,widechar('.')); + end; +end; +} +function trystrtodouble(const s: lstringty; out value: double; + const decimalseparator: char): boolean; overload; +var + po1,decisep,mantstart,mantend: pchar; + pend: pchar; + neg,negexp: boolean; + mant,do1: double; + exp: integer; +begin + result:= false; + if s.len = 0 then begin + exit; + end; + pend:= s.po+s.len; + po1:= s.po; + while ((po1^ = ' ') or (po1^ = c_tab)) do begin + inc(po1); + if po1 = pend then begin + exit; + end; + end; + neg:= po1^ = '-'; + if po1^ = '+' then begin + inc(po1); + end; + if neg then begin + inc(po1); + end; + decisep:= nil; + mantstart:= po1; + mant:= 0; + exp:= 0; + while true do begin + case po1^ of + '0'..'9': begin + mant:= mant*10 + (byte(po1^)-byte('0')); + end; + 'e','E': begin + mantend:= po1; + inc(po1); + negexp:= po1^ = '-'; + if po1^ = '+' then begin + inc(po1); + end; + if negexp then begin + inc(po1); + end; + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; + while true do begin + case po1^ of + '0'..'9': begin + exp:= exp * 10 + (byte(po1^)-byte('0')); + end; + else begin + break; + end; + end; + inc(po1); + if po1 = pend then begin + break; + end; + end; + if negexp then begin + exp:= -exp; + end; + break; + end; + else begin + if po1^ = decimalseparator then begin + if decisep <> nil then begin + exit; + end; + decisep:= po1; + end + else begin + mantend:= po1; + break; + end; + end; + end; + inc(po1); + if po1 = pend then begin + mantend:= po1; + break; + end; + end; + if (mantstart = mantend) or (decisep = mantstart) and + (mantend-mantstart = 1) then begin + exit; //empty + end; + if decisep <> nil then begin + exp:= exp-(mantend-decisep)+1; + end; + while po1 <> pend do begin + if not((po1^ = ' ') or (po1^ = c_tab)) then begin + exit; + end; + inc(po1); + end; + if not tryintexp10(exp,do1) then begin + exit; + end; + do1:= mant * do1; + if neg then begin + do1:= -do1; + end; + value:= do1; + result:= true; +end; + +function trystrtodouble(const s: lmsestringty; out value: double; + const decimalseparator: msechar): boolean; overload; +var + po1,decisep,mantstart,mantend: pmsechar; + pend: pmsechar; + neg,negexp: boolean; + mant,do1: double; + exp: integer; +begin + result:= false; + if s.len = 0 then begin + exit; + end; + pend:= s.po+s.len; + po1:= s.po; + while ((po1^ = ' ') or (po1^ = c_tab)) do begin + inc(po1); + if po1 = pend then begin + exit; + end; + end; + neg:= po1^ = '-'; + if po1^ = '+' then begin + inc(po1); + end; + if neg then begin + inc(po1); + end; + decisep:= nil; + mantstart:= po1; + mant:= 0; + exp:= 0; + while true do begin + case po1^ of + '0'..'9': begin + mant:= mant*10 + (byte(po1^)-byte('0')); + end; + 'e','E': begin + mantend:= po1; + inc(po1); + negexp:= po1^ = '-'; + if po1^ = '+' then begin + inc(po1); + end; + if negexp then begin + inc(po1); + end; + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; + while true do begin + case po1^ of + '0'..'9': begin + exp:= exp * 10 + (byte(po1^)-byte('0')); + end; + else begin + break; + end; + end; + inc(po1); + if po1 = pend then begin + break; + end; + end; + if negexp then begin + exp:= -exp; + end; + break; + end; + else begin + if po1^ = decimalseparator then begin + if decisep <> nil then begin + exit; + end; + decisep:= po1; + end + else begin + mantend:= po1; + break; + end; + end; + end; + inc(po1); + if po1 = pend then begin + mantend:= po1; + break; + end; + end; + if (mantstart = mantend) or (decisep = mantstart) and + (mantend-mantstart = 1) then begin + exit; //empty + end; + if decisep <> nil then begin + exp:= exp-(mantend-decisep)+1; + end; + while po1 <> pend do begin + if not((po1^ = ' ') or (po1^ = c_tab)) then begin + exit; + end; + inc(po1); + end; + if not tryintexp10(exp,do1) then begin + exit; + end; + do1:= mant * do1; + if neg then begin + do1:= -do1; + end; + value:= do1; + result:= true; +end; + +function trystrtodouble(const s: string; out value: double; + const decimalseparator: char): boolean; overload; +var + lstr1: lstringty; +begin + lstr1.po:= pointer(s); + lstr1.len:= length(s); + result:= trystrtodouble(lstr1,value,decimalseparator); +end; + +function trystrtodouble(const s: msestring; out value: double; + const decimalseparator: msechar): boolean; overload; +var + lstr1: lmsestringty; +begin + lstr1.po:= pointer(s); + lstr1.len:= length(s); + result:= trystrtodouble(lstr1,value,decimalseparator); +end; + +function trystrtodouble(const s: string; out value: double): boolean; +begin + result:= trystrtodouble(s,value,defaultformatsettingsmse.decimalseparator); +end; + +function trystrtodouble(const s: msestring; out value: double): boolean; +begin + result:= trystrtodouble(s,value,defaultformatsettingsmse.decimalseparator); +end; + +function strtodouble(const s: string; + const decimalseparator: char): double; +begin + if not trystrtodouble(s,result,decimalseparator) then begin + raise EConvertError.CreateFmt(SInvalidFloat,[s]); + end; +end; + +function strtodouble(const s: msestring; + const decimalseparator: msechar): double; +begin + if not trystrtodouble(s,result,decimalseparator) then begin + raise EConvertError.CreateFmt(SInvalidFloat,[s]); + end; +end; + +function strtodouble(const s: string): double; +begin + result:= strtodouble(s,defaultformatsettingsmse.decimalseparator); +end; + +function strtodouble(const s: msestring): double; +begin + result:= strtodouble(s,defaultformatsettingsmse.decimalseparator); +end; + +function realToStr(const value: double): string; //immer'.' als separator +begin +{$ifdef withformatsettings} + result:= floattostr(value,defaultformatsettingsdot) +{$else} + result:= replacechar(floattostr(value),decimalseparator,'.'); +{$endif} +end; + +function StrToreal(const S: string): double; //immer'.' als separator +begin + result:= strtodouble(s,'.'); +end; + +function trystrtoreal(const s: string; out value: real): boolean; +begin + result:= trystrtodouble(s,double(value),'.'); +end; + +function StrToreal(const S: msestring): double; //immer'.' als separator +begin + result:= strtodouble(s,'.'); +end; + +function trystrtoreal(const s: msestring; out value: real): boolean; +begin + result:= trystrtodouble(s,double(value),'.'); +end; + +function realtytostring(const val: realty; const format: msestring = ''; + const scale: real = 1): msestring; +var + rea1: real; +begin + if val = emptyreal then begin + result:= emptyrealstring; + end + else begin + if scale <> 0 then begin + rea1:= val/scale; + end + else begin + rea1:= val; + end; + result:= formatfloatmse(rea1,format,defaultformatsettingsmse); + end; +end; + +function realtytostr(const val: realty; const format: msestring = ''; + const scale: real = 1): msestring; +begin + result:= realtytostring(val,format,scale); +end; + +function currencytostr(const avalue: currency): string; + //always '.' as as decimal separator +var + buffer: array[0..23] of char; + int1,int2: integer; + lwo1,lwo2: qword; +const + dotpos = high(buffer)-4; + +begin + lwo1:= abs(int64(avalue)); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + buffer[dotpos]:= '.'; + int1:= high(buffer); + while (lwo1 > 0) or (int1 >= dotpos-1) do begin + if int1 <> dotpos then begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + end; + dec(int1); + end; + if int64(avalue) < 0 then begin + buffer[int1]:= msechar('-'); + dec(int1); + end; + int2:= high(buffer); + while buffer[int2] = '0' do begin + dec(int2); + end; + if int2 = dotpos then begin + dec(int2); + end; + int2:= int2-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(char)); +end; + +function currencytostrmse(const avalue: currency): msestring; + //always '.' as as decimal separator +var + buffer: array[0..23] of msechar; + int1,int2: integer; + lwo1,lwo2: qword; +const + dotpos = high(buffer)-4; + +begin + lwo1:= abs(int64(avalue)); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + buffer[dotpos]:= '.'; + int1:= high(buffer); + while (lwo1 > 0) or (int1 >= dotpos-1) do begin + if int1 <> dotpos then begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + end; + dec(int1); + end; + if int64(avalue) < 0 then begin + buffer[int1]:= msechar('-'); + dec(int1); + end; + int2:= high(buffer); + while buffer[int2] = '0' do begin + dec(int2); + end; + if int2 = dotpos then begin + dec(int2); + end; + int2:= int2-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(msechar)); +end; + +function realtytostrrange(const val: realty; const format: msestring = ''; + const range: real = 1; const offset: real = 0): msestring; +var + rea1: real; +begin + if val = emptyreal then begin + result:= emptyrealstring; + end + else begin + if range <> 0 then begin + rea1:= val*range+offset; + end + else begin + rea1:= val; + end; + result:= formatfloatmse(rea1,format,defaultformatsettingsmse); + end; +end; + +const + expos: array[ord('A')..ord('z')] of shortint = + // A B C D E F G H I J K L M + ( 0, 0, 0, 0, 6*3, 0, 3*3, 0, 0, 0, 0, 0, 2*3, + // N O P Q R S T U V W X Y Z + 0, 0, 5*3, 0, 0, 0, 4*3, 0, 0, 0, 0, 8*3, 7*3, + //[ \ ] ^ _ ' + 0,0,0,0,0,0, + // a b c d e f g h i j k l m + -6*3, 0, 0, 0, 0,-5*3, 0, 0, 0, 0, 1*3, 0,-1*3, + // n o p q r s t u v w x y z + -3*3, 0,-4*3, 0, 0, 0, 0,-2*3, 0, 0, 0,-8*3,-7*3); + +function trystrtorealty(const ein: string; out value: realty; + forcevalue: boolean = false): boolean; +var + str1: string; + ch1: char; + sint1: shortint; +begin + str1:= trim(ein); + result:= true; + if not forcevalue and (str1 = emptyrealstring) then begin + value:= emptyreal; + end + else begin + removechar(str1,{$ifdef FPC}defaultformatsettingsmse.{$endif}thousandseparator); + if length(str1) > 0 then begin + ch1:= str1[length(str1)]; + if (ch1 >= 'A') and (ch1 <= 'z') then begin + sint1:= expos[ord(ch1)]; + if sint1 <> 0 then begin + setlength(str1,length(str1)-1); + str1:= str1 + 'E'+inttostr(sint1); + end; + end; + end; + result:= trystrtodouble(str1,double(value)); + end; +end; + +function trystrtorealty(const ein: msestring; out value: realty; + forcevalue: boolean = false): boolean; +var + str1: msestring; + ch1: msechar; + sint1: shortint; +begin + str1:= trim(ein); + result:= true; + if not forcevalue and (str1 = emptyrealstring) then begin + value:= emptyreal; + end + else begin + removechar(str1,{$ifdef FPC}defaultformatsettingsmse.{$endif}thousandseparator); + if length(str1) > 0 then begin + ch1:= str1[length(str1)]; + if (ch1 >= 'A') and (ch1 <= 'z') then begin + sint1:= expos[ord(ch1)]; + if sint1 <> 0 then begin + setlength(str1,length(str1)-1); + str1:= str1 + 'E'+inttostrmse(sint1); + end; + end; + end; + result:= trystrtodouble(str1,double(value)); + end; +end; + +function strtorealty(const ein: string; forcevalue: boolean = false): realty; +begin + if not trystrtorealty(ein,result,forcevalue) then begin + raise EConvertError.CreateFmt(SInvalidFloat,[ein]); + end; +end; + +function strtorealty(const ein: msestring; forcevalue: boolean = false): realty; +begin + if not trystrtorealty(ein,result,forcevalue) then begin + raise EConvertError.CreateFmt(SInvalidFloat,[ein]); + end; +end; + +function realtytostrdot(const val: realty): string; +begin + if val = emptyreal then begin + result:= emptyrealstring; + end + else begin + result:= ansistring(doubletostring(val)); +(* + {$ifdef withformatsettings} + result:= floattostr(val,defaultformatsettingsdot); + {$else} + result:= replacechar(floattostr(val),decimalseparator,'.'); + {$endif} + *) + end; +end; + +function realtytostrdotmse(const val: realty): msestring; +begin + if val = emptyreal then begin + result:= emptyrealstring; + end + else begin + result:= doubletostring(val); + end; +end; + +function strtorealtydot(const ein: string): realty; + +begin + if trim(ein) = emptyrealstring then begin + result:= emptyreal; + end + else begin + result:= strtodouble(ein,'.'); + end; +end; + +function strtorealtydot(const ein: msestring): realty; + +begin + if trim(ein) = emptyrealstring then begin + result:= emptyreal; + end + else begin + result:= strtodouble(ein,'.'); + end; +end; + +function trystrtorealtydot(const ein: string; out value: realty): boolean; +begin + result:= true; + if trim(ein) = emptyrealstring then begin + value:= emptyreal; + end + else begin + result:= trystrtodouble(ein,double(value),'.'); + end; +end; + +function trystrtorealtydot(const ein: msestring; out value: realty): boolean; +begin + result:= true; + if trim(ein) = emptyrealstring then begin + value:= emptyreal; + end + else begin + result:= trystrtodouble(ein,double(value),'.'); + end; +end; + +function bcdtostr(inp: byte): string; + //wandelt bcdwert in zwei ascii zeichen +begin + result:= char(byte(inp shr byte(4)) + ord('0'))+ + char(byte(inp and $0f) + ord('0')); +end; + +function bytetobcd(inp: byte): word; + //wandelt byte in bcdwert +begin + result:= (inp div 100 shl 8) or ((inp div 10) mod 10 shl 4) or (inp mod 10) +end; + +function bcdtobyte(inp: byte): byte; + //wandelt bcdbyte in byte +begin + result:= (inp shr 4)*10 + inp and $0f; +end; + +function wordtostr(const avalue: longword): string; +begin + str(avalue,result); +end; + +function bytetohex(const inp: byte): string; + //wandelt byte in zwei ascii hexzeichen +var + ch1,ch2: char; +begin + ch1:= char((inp shr 4) + byte('0')); + if ch1 > '9' then begin + ch1:= char(byte(ch1) + byte('A')-byte('0')-10); + end; + ch2:= char((inp and $0f) + byte('0')); + if ch2 > '9' then begin + ch2:= char(byte(ch2) + byte('A')-byte('0')-10); + end; + result:= ch1 + ch2; +end; + +function wordtohex(const inp: word; lsbfirst: boolean = false): string; + //wandelt word in vier ascii hexzeichen +begin + if lsbfirst then begin + result:= bytetohex(inp) + bytetohex(inp shr 8); + end + else begin + result:= bytetohex(inp shr 8) + bytetohex(inp); + end; +end; + +function valtohex(const avalue: byte): string; +begin + setlength(result,2); + pchar(pointer(result))^:= charhexlower[avalue shr 4]; + pchar(pchar(pointer(result))+1)^:= charhexlower[avalue and $f]; +end; + +function valtohex(const avalue: word): string; +begin + setlength(result,4); + pchar(pointer(result))^:= charhexlower[avalue shr 12]; + pchar(pchar(pointer(result))+1)^:= charhexlower[(avalue shr 8) and $f]; + pchar(pchar(pointer(result))+2)^:= charhexlower[(avalue shr 4) and $f]; + pchar(pchar(pointer(result))+3)^:= charhexlower[avalue and $f]; +end; + +function valtohex(const avalue: longword): string; +begin + setlength(result,8); + pchar(pointer(result))^:= charhexlower[avalue shr 28]; + pchar(pchar(pointer(result))+1)^:= charhexlower[(avalue shr 24) and $f]; + pchar(pchar(pointer(result))+2)^:= charhexlower[(avalue shr 20) and $f]; + pchar(pchar(pointer(result))+3)^:= charhexlower[(avalue shr 16) and $f]; + pchar(pchar(pointer(result))+4)^:= charhexlower[(avalue shr 12) and $f]; + pchar(pchar(pointer(result))+5)^:= charhexlower[(avalue shr 8) and $f]; + pchar(pchar(pointer(result))+6)^:= charhexlower[(avalue shr 4) and $f]; + pchar(pchar(pointer(result))+7)^:= charhexlower[avalue and $f]; +end; + +function valtohex(const avalue: qword): string; +begin + result:= valtohex(avalue shr 32)+valtohex(avalue); +end; + +function bytestrtostr(const inp: ansistring; base: numbasety = nb_hex; + spacechar: char = #0): string; + //wandelt bytefolge in ascii hexstring +var + int1: integer; +begin + result:= ''; + for int1:= 1 to length(inp) do begin + result:= result + intvaluetostr(byte(inp[int1]),base,8); + if (spacechar <> #0) and (int1 <> length(inp)) then begin + result:= result + spacechar; + end; + end; +end; + +function strtobytestr(inp: string): ansistring; + //wandelt hex asciistring in bytefolge +var + int1,int2, int3: integer; + str1: string; +begin + result:= ''; + removechar(inp,' '); + int2:= length(inp); + if int2 > 0 then begin + setlength(result,(int2+1) div 2); + setlength(str1,2); + int1:= 1; + int3:= 1; + while int1 <= int2 do begin + str1[1]:= inp[int1]; + inc(int1); + if int1 > int2 then begin + setlength(str1,1); + end + else begin + str1[2]:= inp[int1]; + end; + result[int3]:= char(strtohex(str1)); + inc(int1); + inc(int3); + end; + end; +end; + +function strtobytes(const inp: string; out dest: bytearty): boolean; +var + po1,po2: pchar; + int1: integer; + by1: shortint; +begin + result:= false; + int1:= length(inp)+1; + setlength(dest,int1 div 2); + po1:= @inp[int1]; + po2:= pchar(inp); + int1:= high(dest); + while po1 > po2 do begin + dec(po1); + by1:= hexchars[po1^]; + if by1 < 0 then begin + exit; + end; + dest[int1]:= by1; + + if po1 = po2 then begin + break; + end; + dec(po1); + by1:= hexchars[po1^]; + if by1 < 0 then begin + exit; + end; + dest[int1]:= dest[int1] or (by1 shl 4); + dec(int1); + end; + result:= true; +end; + +function bytestrtobin(const inp: ansistring; abstand: boolean): string; + //wandelt bytefolge in ascii binstring, + // letztes zeichen = anzahl gueltige bits in letztem byte +var + int1,int2,int3,int4: integer; +// str1: string; + by1,by2: byte; + +begin + result:= ''; + int2:= bitcount(inp)-1; + int3:= 1; + int4:= 0; + while int2 >= 0 do begin + by1:= byte(inp[int3]); + by2:= $01; + for int1:= 0 to 7 do begin + if by1 and by2 <> 0 then begin + result:= result + '1'; + end + else begin + result:= result + '0'; + end; + if int4+int1 >= int2 then begin + break; + end; + by2:= by2 shl 1; + end; + if int4+(int1 and $07) >= int2 then begin + break; + end; + if abstand then begin + result:= result + ' '; + end; + inc(int3); + inc(int4,8); + end; +end; + +function strtobinstr(inp: string): ansistring; + //wandelt bin asciistring in bytefolge, + // letztes byte = anzahl gueltige bits in vorletztem byte +var + int1,int2,int3: integer; + by1,by2: byte; + ch1: char; +begin + result:= ''; + removechar(inp,' '); + int1:= length(inp); + int3:= 1; + int2:= 0; + while int3 <= int1 do begin + by1:= 1; + by2:= 0; + for int2:= 0 to 7 do begin + if int3 + int2 > int1 then begin + break; + end; + ch1:= inp[int3+int2]; + if ch1 = '1' then begin + by2:= by2 or by1; + end + else begin + if ch1 <> '0' then begin + raise EConvertError.CreateFmt(SInvalidInteger,[inp]); + end; + end; + by1:= by1 shl 1; + end; + int3:= int3 + 8; + result:= result + char(by2); + end; + if length(result) > 0 then begin + result:= result + char(int2); + end; +end; + +function bitmaske(const data: ansistring): integer; +begin + if length(data) > 1 then begin + result:= byte(data[length(data)]); + if result > 8 then begin + result:= 8 + end; + end + else begin + result:= 0; + end; +end; + +function bitcount(const data: ansistring): integer; //anzahl gueltige bits +var + int1: integer; +begin + int1:= length(data); + if int1 > 1 then begin + result:= 8*(int1-2) + bitmaske(data); + end + else begin + result:= 0; + end; +end; + +function bintostr(inp: longword; digits: integer): string; + //convert longword to binstring, digits = bit count +var + int1: integer; +begin + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $1)); + inp:= inp shr 1; + end; +end; + +function bintostr(inp: qword; digits: integer): string; + //convert longword to binstring, digits = bit count +var + int1: integer; +begin + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $1)); + inp:= inp shr 1; + end; +end; + +function octtostr(inp: longword; digits: integer): string; + //convert longword to octaltring, digits = octet count +var + int1: integer; +begin + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $7)); + inp:= inp shr 3; + end; +end; + +function octtostr(inp: qword; digits: integer): string; + //convert longword to octaltring, digits = octet count +var + int1: integer; +begin + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $7)); + inp:= inp shr 3; + end; +end; + +function dectostr(const inp: integer; digits: integer): string; + //leading zeroes if digits < 0 +begin + result:= inttostr(abs(inp)); + if digits < 0 then begin + digits:= -digits; + if digits > length(nullen) then begin + digits:= length(nullen); + end; + result:= copy(nullen,1,digits-length(result)) + result; + end; + result:= copy(result,length(result)-digits+1,bigint); + if inp < 0 then begin + result:= '-' + result; + end; +end; + +function dectostr(const inp: int64; digits: integer): string; + //leading zeroes if digits < 0 +begin + result:= inttostr(abs(inp)); + if digits < 0 then begin + digits:= -digits; + if digits > length(nullen) then begin + digits:= length(nullen); + end; + result:= copy(nullen,1,digits-length(result)) + result; + end; + result:= copy(result,length(result)-digits+1,bigint); + if (inp < 0) and (result[1] <> '-') then begin + result:= '-' + result; + end; +end; + +function hextostr(inp: longword; digits: integer): string; + //wandelt longword in hexstring, stellen = anzahl nibbles +var + int1: integer; +begin + if digits = 0 then begin + digits:= (highestbit(inp)+4) div 4; + if digits = 0 then begin + digits:= 1; + end; + end; + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function hextostr(inp: qword; digits: integer): string; + //wandelt longword in hexstring, stellen = anzahl nibbles +var + int1: integer; +begin + if digits = 0 then begin + digits:= (highestbit64(inp)+4) div 4; + if digits = 0 then begin + digits:= 1; + end; + end; + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function hextostr(const inp: pointer; + digits: integer = 2*sizeof(pointer)): string; overload; + //convert pointer to hexstring, digits = nibble count +begin + result:= hextostr(ptruint(inp),digits); +end; + +function hextostrmse(inp: longword; digits: integer): msestring; + //wandelt longword in hexstring, stellen = anzahl nibbles +var + int1: integer; +begin + if digits = 0 then begin + digits:= (highestbit(inp)+4) div 4; + if digits = 0 then begin + digits:= 1; + end; + end; + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= msechar(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function hextostrmse(inp: qword; digits: integer): msestring; + //wandelt longword in hexstring, stellen = anzahl nibbles +var + int1: integer; +begin + if digits = 0 then begin + digits:= (highestbit64(inp)+4) div 4; + if digits = 0 then begin + digits:= 1; + end; + end; + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= msechar(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function hextostrmse(const inp: pointer; + digits: integer = 2*sizeof(pointer)): msestring; overload; + //convert pointer to hexstring, digits = nibble count +begin + result:= hextostrmse(ptruint(inp),digits); +end; + +function hextocstr(const inp: longword; stellen: integer): string; +begin + result:= '0x' + hextostr(inp, stellen); +end; + +function hextocstr(const inp: qword; stellen: integer): string; +begin + result:= '0x' + hextostr(inp, stellen); +end; + +function ptruinttocstr(inp: ptruint): string; + //convert ptrint to 0x... +var + int1: integer; +begin + result:= '0x'; + setlength(result,2+sizeof(ptrint)*2); + for int1:= length(result) downto 3 do begin + result[int1]:= char(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function qwordtocstr(inp: qword): string; + //convert qword to 0x... +var + int1: integer; +begin + result:= '0x'; + int1:= 8*2; +// if inp <= $ffffffff then begin +// int1:= 4*2; +// end; + setlength(result,2+int1); + for int1:= length(result) downto 3 do begin + result[int1]:= char(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function trystrtoint(const text: pchar; const len: int32; + out value: integer): boolean; +const + max = maxint div 10; +var + po1,pe: pchar; + neg: boolean; +begin + result:= false; + neg:= false; + value:= 0; + if len > 0 then begin + po1:= text; + pe:= po1 + len; + while ((po1^ = ' ') or (po1^ = c_tab)) and (po1 < pe) do begin + inc(po1); + end; + neg:= po1^ = char('-'); + if not neg then begin + if po1^ = '+' then begin + inc(po1); + end; + end + else begin + inc(po1); + end; + if po1 >= pe then begin + exit; + end; + while po1 < pe do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; +// if value < 0 then begin +// exit; +// end; + if card32(value) > max then begin + exit; + end; + value:= value * 10 + (byte(po1^) - byte('0')); + inc(po1); + end; + end; + if neg then begin + if (value < 0) and (value <> minint) then begin + exit; + end; + value:= -value; + end + else begin + if value < 0 then begin + exit; + end; + end; + result:= true; +end; + +function trystrtoint(const text: lstringty; out value: integer): boolean; +begin + result:= trystrtoint(text.po,text.len,value); +end; + +function trystrtoint(const text: string; out value: integer): boolean; +begin + result:= trystrtoint(pointer(text),length(text),value); +end; + +function strtoint(const text: string): integer; +begin + if not trystrtoint(pointer(text),length(text),result) then begin + raise EConvertError.CreateFmt(SInvalidInteger,[text]); + end; +end; + +function trystrtoint(const text: msestring; out value: integer): boolean; +const + max = maxint div 10; +var + po1: pmsechar; + neg: boolean; +begin + result:= false; + neg:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + neg:= po1^ = msechar('-'); + if not neg then begin + if po1^ = '+' then begin + inc(po1); + end; + end + else begin + inc(po1); + end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; +// if value < 0 then begin +// exit; +// end; + if card32(value) > max then begin + exit; + end; + value:= value * 10 + (word(po1^) - word('0')); + inc(po1); + end; + end; + if neg then begin + if (value < 0) and (value <> minint) then begin + exit; + end; + value:= -value; + end + else begin + if value < 0 then begin + exit; + end; + end; + result:= true; +end; + +function strtoint(const text: msestring): integer; +begin + if not trystrtoint(text,result) then begin + raise EConvertError.CreateFmt(SInvalidInteger,[string(text)]); + end; +end; + +function trystrtoint(const text: string; out value: longword): boolean; +const + max = $ffffffff div 10; +var + po1: pchar; +begin + result:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + if po1^ = '+' then begin + inc(po1); + end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; + if value > max then begin + exit; + end; + value:= value * longword(10) + longword(byte(po1^) - byte('0')); + inc(po1); + end; + end; + result:= true; +end; + +function trystrtoint(const text: msestring; out value: longword): boolean; +const + max = $ffffffff div 10; +var + po1: pmsechar; +// neg: boolean; +begin + result:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; +// neg:= po1^ = msechar('-'); +// if not neg then begin + if po1^ = '+' then begin + inc(po1); + end; +// end +// else begin +// inc(po1); +// end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; +// if value < 0 then begin +// exit; +// end; + if value > max then begin + exit; + end; + value:= value * longword(10) + longword(word(po1^) - word('0')); + inc(po1); + end; + end; +// if neg then begin +// if (value < 0) and (value <> minint) then begin +// exit; +// end; +// value:= -value; +// end +// else begin +// if value < 0 then begin +// exit; +// end; +// end; + result:= true; +end; + +function trystrtoint64(const text: lstringty; out value: int64): boolean; +const + max = maxint64 div 10; +var + po1,pe: pchar; + neg: boolean; +begin + result:= false; + neg:= false; + value:= 0; + if text.len > 0 then begin + po1:= text.po; + pe:= po1 + text.len; + while ((po1^ = ' ') or (po1^ = c_tab)) and (po1 < pe) do begin + inc(po1); + end; + neg:= po1^ = char('-'); + if not neg then begin + if po1^ = '+' then begin + inc(po1); + end; + end + else begin + inc(po1); + end; + if po1 >= pe then begin + exit; + end; + while po1 < pe do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; +// if value < 0 then begin +// exit; +// end; + if card64(value) > max then begin + exit; + end; + value:= value * 10 + (ord(po1^) - ord('0')); + inc(po1); + end; + end; + if neg then begin + if (value < 0) and (value <> $8000000000000000) then begin + exit; + end; + value:= -value; + end + else begin + if value < 0 then begin + exit; + end; + end; + result:= true; +end; + +function trystrtoint64(const text: string; out value: int64): boolean; +begin + result:= trystrtoint64(stringtolstring(text),value); +end; + +function strtoint64(const text: string): int64; +begin + if not trystrtoint64(text,result) then begin + raise EConvertError.CreateFmt(SInvalidInteger,[text]); + end; +end; + +function strtoint64(const text: msestring): int64; +begin + if not trystrtoint64(text,result) then begin + raise EConvertError.CreateFmt(SInvalidInteger,[string(text)]); + end; +end; + +function trystrtoint64(const text: msestring; out value: int64): boolean; +const + max = maxint64 div 10; +var + po1: pmsechar; + neg: boolean; +begin + result:= false; + neg:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + neg:= po1^ = msechar('-'); + if not neg then begin + if po1^ = '+' then begin + inc(po1); + end; + end + else begin + inc(po1); + end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; +// if value < 0 then begin +// exit; +// end; + if card64(value) > max then begin + exit; + end; + value:= value * 10 + (ord(po1^) - ord('0')); + inc(po1); + end; + end; + if neg then begin + if (value < 0) and (value <> $8000000000000000) then begin + exit; + end; + value:= -value; + end + else begin + if value < 0 then begin + exit; + end; + end; + result:= true; +end; + +function trystrtoqword(const text: string; out value: qword): boolean; +const + max = 1844674407370955161; +var + po1: pchar; + bo1: boolean; +begin + result:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; + if value > max then begin + exit; + end; + value:= value * 10; + bo1:= int64(value) < 0; + value:= value + (ord(po1^) - ord('0')); + if bo1 and (int64(value) >= 0) then begin + exit; + end; + inc(po1); + end; + end; + result:= true; +end; + +function trystrtoqword(const text: msestring; out value: qword): boolean; +const + max = 1844674407370955161; +var + po1: pmsechar; + bo1: boolean; +begin + result:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; + if value > max then begin + exit; + end; + value:= value * 10; + bo1:= int64(value) < 0; + value:= value + (ord(po1^) - ord('0')); + if bo1 and (int64(value) >= 0) then begin + exit; + end; + inc(po1); + end; + end; + result:= true; +end; + +function trystrtointvalue(const text: msestring; base: numbasety; + out value: longword): boolean; +var + str1: string; +begin + str1:= ansistring(trim(text)); + case base of + nb_bin: begin + result:= trystrtobin(str1,value); + end; + nb_oct: begin + result:= trystrtooct(str1,value); + end; + nb_hex: begin + result:= trystrtohex(str1,value); + end + else begin //nb_dec + result:= trystrtodec(str1,value); + end; + end; +end; + +function trystrtointvalue64(const text: msestring; base: numbasety; + out value: qword): boolean; overload; +var + str1: string; +begin + str1:= ansistring(trim(text)); + case base of + nb_bin: begin + result:= trystrtobin64(str1,value); + end; + nb_oct: begin + result:= trystrtooct64(str1,value); + end; + nb_hex: begin + result:= trystrtohex64(str1,value); + end + else begin //nb_dec + result:= trystrtodec64(str1,value); + end; + end; +end; + +function strtointvalue(const text: msestring; base: numbasety): longword; +begin + if not trystrtointvalue(text,base,result) then begin + formaterror(text); + end; +end; + +function strtointvalue64(const text: msestring; base: numbasety): qword; +begin + if not trystrtointvalue64(text,base,result) then begin + formaterror(text); + end; +end; + +function intvaluetostr(const value: integer; const base: numbasety = nb_dec; + const bitcount: integer = 32): string; +begin + case base of + nb_bin: begin + result:= bintostr(longword(value),abs(bitcount)); + end; + nb_oct: begin + result:= octtostr(longword(value),(abs(bitcount)+2) div 3); + end; + nb_hex: begin + result:= hextostr(longword(value),(abs(bitcount)+3) div 4); + end; + else begin //nb_dec + result:= dectostr(value,sign(bitcount)*(abs(bitcount)*100+331) div 332); + end; + end; +end; + +function intvaluetostr(const value: int64; const base: numbasety = nb_dec; + const bitcount: integer = 64): string; +begin + case base of + nb_bin: begin + result:= bintostr(uint64(value),abs(bitcount)); + end; + nb_oct: begin + result:= octtostr(uint64(value),(abs(bitcount)+2) div 3); + end; + nb_hex: begin + result:= hextostr(uint64(value),(abs(bitcount)+3) div 4); + end; + else begin //nb_dec + result:= dectostr(value,sign(bitcount)*(abs(bitcount)*100+331) div 332); + end; + end; +end; + +function strtobin1(const inp: string; out value: longword): boolean; + //wandelt 1..0-string in longword) +var + int1: integer; + lwo1: longword; +begin + result:= false; + if inp <> '' then begin + value:= 0; + lwo1:= 1; + for int1:= length(inp) downto 1 do begin + if inp[int1] = '1' then begin + value:= value + lwo1; + end + else begin + if inp[int1] <> '0' then begin + exit; + end; + end; + lwo1:= lwo1 shl 1; + end; + result:= true; + end; +end; + +function strtobin164(const inp: string; out value: qword): boolean; + //wandelt 1..0-string in longword) +var + int1: integer; + lwo1: qword; +begin + result:= false; + if inp <> '' then begin + value:= 0; + lwo1:= 1; + for int1:= length(inp) downto 1 do begin + if inp[int1] = '1' then begin + value:= value + lwo1; + end + else begin + if inp[int1] <> '0' then begin + exit; + end; + end; + lwo1:= lwo1 shl 1; + end; + result:= true; + end; +end; + +function trystrtobin(const inp: string; out value: longword): boolean; +begin + result:= strtobin1(inp,value); + if not result then begin + result:= trystrtointvalue(inp,value); + end; +end; + +function trystrtobin64(const inp: string; out value: qword): boolean; +begin + result:= strtobin164(inp,value); + if not result then begin + result:= trystrtointvalue64(inp,value); + end; +end; + +function strtobin(const inp: string): longword; + //wandelt 0..1-string in longword) +begin + if not trystrtobin(inp,result) then begin + formaterror(inp); + end; +end; + +function strtobin64(const inp: string): qword; + //wandelt 0..1-string in longword) +begin + if not trystrtobin64(inp,result) then begin + formaterror(inp); + end; +end; + +function strtooct1(const inp: string; out value: longword): boolean; +var + int1: integer; + ca1: longword; + ch1: char; +begin + result:= false; + if inp <> '' then begin + value:= 0; + ca1:= 0; + for int1:= length(inp) downto 1 do begin + ch1:= inp[int1]; + if (ch1 < '0') or (ch1 > '7') then begin + exit; + end; + value:= value + longword(((ord(ch1) - ord('0'))) shl ca1); + inc(ca1,3); + end; + result:= true; + end; +end; + +function strtooct164(const inp: string; out value: qword): boolean; +var + int1: integer; + ca1: longword; + ch1: char; +begin + result:= false; + if inp <> '' then begin + value:= 0; + ca1:= 0; + for int1:= length(inp) downto 1 do begin + ch1:= inp[int1]; + if (ch1 < '0') or (ch1 > '7') then begin + exit; + end; + value:= value + qword(((ord(ch1) - ord('0'))) shl ca1); + inc(ca1,3); + end; + result:= true; + end; +end; + +function trystrtooct(const inp: string; out value: longword): boolean; +begin + result:= strtooct1(inp,value); + if not result then begin + result:= trystrtointvalue(inp,value); + end; +end; + +function trystrtooct64(const inp: string; out value: qword): boolean; +begin + result:= strtooct164(inp,value); + if not result then begin + result:= trystrtointvalue64(inp,value); + end; +end; + +function strtooct(const inp: string): longword; + //wandelt 1..0-string in longword) +begin + if not trystrtooct(inp,result) then begin + formaterror(inp); + end; +end; + +function strtooct64(const inp: string): qword; + //wandelt 1..0-string in longword) +begin + if not trystrtooct64(inp,result) then begin + formaterror(inp); + end; +end; + +function strtodec1(const inp: string; out value: longword): boolean; +begin + result:= trystrtoint(inp,integer(value)); +end; + +function strtodec164(const inp: string; out value: qword): boolean; +begin + result:= trystrtoint64(inp,int64(value)); +end; + +function trystrtodec(const inp: string; out value: longword): boolean; +begin + result:= strtodec1(inp,value); + if not result then begin + result:= trystrtointvalue(inp,value); + end; +end; + +function trystrtodec64(const inp: string; out value: qword): boolean; +begin + result:= strtodec164(inp,value); + if not result then begin + result:= trystrtointvalue64(inp,value); + end; +end; + +function strtodec(const inp: string): longword; + //wandelt 0..9-string in longword) +begin + if not trystrtodec(inp,result) then begin + formaterror(inp); + end; +end; + +function strtodec64(const inp: string): qword; + //wandelt 0..9-string in longword) +begin + if not trystrtodec64(inp,result) then begin + formaterror(inp); + end; +end; + +function trystrtohex(const inp: pchar; const len: int32; + out value: longword): boolean; +var + po1,pe: pchar; + ch1: char; +begin + value:= 0; + result:= (len > 0) and (len <= 8); + if result then begin + po1:= inp; + pe:= po1+len; + while po1 < pe do begin + ch1:= po1^; + value:= value shl 4; + if (ch1 >= '0') and (ch1 <= '9') then begin + value:= value + ord(ch1) - ord('0'); + end + else begin + if (ch1 >= 'a') and (ch1 <= 'f') then begin + value:= value + ord(ch1) - (ord('a')-10); + end + else begin + if (ch1 >= 'A') and (ch1 <= 'F') then begin + value:= value + ord(ch1) - (ord('A')-10); + end + else begin + result:= false; + break; + end; + end; + end; + inc(po1); + end; + end; +// result:= trystrtoint('$'+inp,integer(value)); +end; + +function strtohex1(const inp: msestring; out value: longword): boolean; +var + po1: pmsechar; + ch1: msechar; + int1: integer; +begin + value:= 0; + int1:= length(inp); + result:= (int1 > 0) and (int1 <= 8); + if result then begin + po1:= pointer(inp); + while true do begin + ch1:= po1^; + if ch1 = #0 then begin + break; + end; + value:= value shl 4; + if (ch1 >= '0') and (ch1 <= '9') then begin + value:= value + ord(ch1) - ord('0'); + end + else begin + if (ch1 >= 'a') and (ch1 <= 'f') then begin + value:= value + ord(ch1) - (ord('a')-10); + end + else begin + if (ch1 >= 'A') and (ch1 <= 'F') then begin + value:= value + ord(ch1) - (ord('A')-10); + end + else begin + result:= false; + break; + end; + end; + end; + inc(po1); + end; + end; +end; + +function strtohex164(const inp: string; out value: qword): boolean; +var + po1: pchar; + ch1: char; + int1: integer; +begin + value:= 0; + int1:= length(inp); + result:= (int1 > 0) and (int1 <= 16); + if result then begin + po1:= pointer(inp); + while true do begin + ch1:= po1^; + if ch1 = #0 then begin + break; + end; + value:= value shl 4; + if (ch1 >= '0') and (ch1 <= '9') then begin + value:= value + ord(ch1) - ord('0'); + end + else begin + if (ch1 >= 'a') and (ch1 <= 'f') then begin + value:= value + ord(ch1) - (ord('a')-10); + end + else begin + if (ch1 >= 'A') and (ch1 <= 'F') then begin + value:= value + ord(ch1) - (ord('A')-10); + end + else begin + result:= false; + break; + end; + end; + end; + inc(po1); + end; + end; +// result:= trystrtoint64('$'+inp,int64(value)); +end; + +function trystrtohex(const inp: lstringty; out value: longword): boolean; +begin + result:= trystrtohex(inp.po,inp.len,value); +end; + +function trystrtohex(const inp: string; out value: longword): boolean; +begin + result:= trystrtohex(pointer(inp),length(inp),value); + if not result then begin + result:= trystrtointvalue(inp,value); + end; +end; + +function trystrtohex(const inp: msestring; out value: longword): boolean; +begin + result:= strtohex1(inp,value); + if not result then begin + result:= trystrtointvalue(ansistring(inp),value); + end; +end; + +function trystrtohex64(const inp: string; out value: qword): boolean; +begin + result:= strtohex164(inp,value); + if not result then begin + result:= trystrtointvalue64(inp,value); + end; +end; + +function strtohex(const inp: string): longword; +begin + if not trystrtohex(inp,result) then begin + formaterror(inp); + end; +end; + +function strtohex(const inp: msestring): longword; +begin + if not trystrtohex(inp,result) then begin + formaterror(inp); + end; +end; + +function strtohex64(const inp: string): qword; +begin + if not trystrtohex64(inp,result) then begin + formaterror(inp); + end; +end; + +function trystrtointvalue(const inp: string; out value: longword): boolean; +var + lint1: int64; +begin + result:= false; + if length(inp) > 0 then begin + case inp[1] of + '%': result:= strtobin1(copy(inp,2,length(inp)-1),value); + '&': result:= strtooct1(copy(inp,2,length(inp)-1),value); + '#': result:= strtodec1(copy(inp,2,length(inp)-1),value); + '$': result:= trystrtohex(copy(inp,2,length(inp)-1),value); + else begin + if (length(inp) > 2) and + ((inp[2] = 'x') or (inp[2] = 'X')) and (inp[1] = '0') then begin + result:= trystrtohex(copy(inp,3,length(inp)-2),value); + end + else begin + result:= trystrtoint64(inp,lint1); + if result then begin + value:= lint1; + end; + end; + end; + end; + end; +end; + +function trystrtointvalue64(const inp: string; out value: qword): boolean; +var + lint1: int64; +begin + result:= false; + if length(inp) > 0 then begin + case inp[1] of + '%': result:= strtobin164(copy(inp,2,length(inp)-1),value); + '&': result:= strtooct164(copy(inp,2,length(inp)-1),value); + '#': result:= strtodec164(copy(inp,2,length(inp)-1),value); + '$': result:= strtohex164(copy(inp,2,length(inp)-1),value); + else begin + if (length(inp) > 2) and + ((inp[2] = 'x') or (inp[2] = 'X')) and (inp[1] = '0') then begin + result:= strtohex164(copy(inp,3,length(inp)-2),value); + end + else begin + if (inp <> '') and (inp[1] = '-') then begin + result:= trystrtoint64(inp,lint1); + end + else begin + result:= trystrtoqword(inp,qword(lint1)); + end; + if result then begin + value:= lint1; + end; + end; + end; + end; + end; +end; + +function strtointvalue(const inp: string): longword; +begin + if not trystrtointvalue(inp,result) then begin + formaterror(inp); + end; +end; + +function strtointvalue64(const inp: string): qword; +begin + if not trystrtointvalue64(inp,result) then begin + formaterror(inp); + end; +end; + +//todo: 64bit + +function strtoptruint(const inp: string): ptruint; +begin + result:= strtointvalue(inp); +end; + +function trystrtoptruint(const inp: string; out value: ptruint): boolean; +begin + {$ifdef CPU64} + result:= trystrtointvalue64(inp,qword(value)); + {$else} + result:= trystrtointvalue(inp,longword(value)); + {$endif} +end; + +function inttostrlen(inp: integer; len: integer; + rechtsbuendig: boolean = true; fillchar: char = ' '): ansistring; + //wandelt integer in string fester laenge +var + int1: integer; +begin + result:= inttostr(inp); + int1:= length(result); + setlength(result,len); + if int1 < len then begin + if rechtsbuendig then begin + move(result[1],result[len-int1+1],int1); + system.fillchar(result[1],len-int1,fillchar); + end + else begin + system.fillchar(result[int1+1],len-int1,fillchar); + end; + end + else begin + if int1 > len then begin + system.fillchar(result[1],len,fc_keinplatzchar); + end; + end; +end; + +function inttostrlenmse(inp: integer; len: integer; + rechtsbuendig: boolean = true; fillchar: msechar = ' '): msestring; + //wandelt integer in string fester laenge +var + int1: integer; +begin + result:= inttostrmse(inp); + int1:= length(result); + setlength(result,len); + if int1 < len then begin + if rechtsbuendig then begin + move(result[1],result[len-int1+1],int1*sizeof(msechar)); + system.fillword(result[1],len-int1,card16(fillchar)); + end + else begin + system.fillword(result[int1+1],len-int1,card16(fillchar)); + end; + end + else begin + if int1 > len then begin + system.fillword(result[1],len,card16(msechar(fc_keinplatzchar))); + end; + end; +end; + +procedure msestrtotvarrec(const value: ansistring; out varrec: tvarrec); +begin + varrec.vtype:= vtansistring; + varrec.vansistring:= pointer(value); +end; + +procedure msestrtotvarrec(const value: msestring; out varrec: tvarrec); +begin +{$ifdef mse_hasvtunicodestring} + varrec.vtype:= vtunicodestring; + varrec.vunicodestring:= pointer(value); //msestringimplementation +{$else} + varrec.vtype:= vtwidestring; + varrec.vwidestring:= pointer(value); //msestringimplementation +{$endif} +end; + +function tvarrectoansistring(const value: tvarrec): ansistring; +begin + with value do begin + case vtype of + vtAnsiString: begin + result:= ansistring(VAnsiString); + end; + vtInteger: begin + result:= inttostr(VInteger); + end; + vtBoolean: begin + result:= booltostr(VBoolean); + end; + vtChar: begin + result:= VChar; + end; + vtWideChar: begin + result:= ansistring(VWideChar); + end; + vtExtended: begin + result:= ansistring(doubletostring(VExtended^)); + end; + vtString: begin + result:= VString^; + end; + vtPointer: begin + result:= hextostr(VPointer); + end; + vtPChar: begin + result:= VPChar; + end; + vtObject: begin + result:= hextostr(VObject); + end; + vtClass: begin + result:= hextostr(VClass); + end; + vtPWideChar: begin + result:= ansistring(unicodestring(VPWideChar)); + end; + vtCurrency: begin + result:= currtostr(VCurrency^); + end; + vtVariant: begin + result:= VVariant^; + end; + vtInterface: begin + result:= hextostr(VInterface); + end; + vtWideString: begin + result:= ansistring(widestring(VWideString)); + end; + vtInt64: begin + result:= inttostr(VInt64^); + end; + vtUnicodeString: begin + result:= ansistring(unicodestring(VUnicodeString)); + end; + vtQWord: begin + result:= inttostr(VQWord^); + end + else begin + result:= ''; + end; + end; + end; +end; + +function tvarrectomsestring(const value: tvarrec): msestring; +begin + with value do begin + case vtype of + vtUnicodeString: begin + result:= unicodestring(VUnicodeString); + end; + vtInteger: begin + result:= inttostrmse(VInteger); + end; + vtBoolean: begin + result:= msestring(booltostr(VBoolean)); + end; + vtChar: begin + result:= msestring(VChar); + end; + vtWideChar: begin + result:= VWideChar; + end; + vtExtended: begin + result:= doubletostring(VExtended^); + end; + vtString: begin + result:= msestring(VString^); + end; + vtPointer: begin + result:= msestring(hextostr(VPointer)); + end; + vtPChar: begin + result:= VPChar; + end; + vtObject: begin + result:= msestring(hextostr(VObject)); + end; + vtClass: begin + result:= msestring(hextostr(VClass)); + end; + vtPWideChar: begin + result:= unicodestring(VPWideChar); + end; + vtAnsiString: begin + result:= msestring(ansistring(VAnsiString)); + end; + vtCurrency: begin + result:= msestring(currtostr(VCurrency^)); + end; + vtVariant: begin + result:= VVariant^; + end; + vtInterface: begin + result:= msestring(hextostr(VInterface)); + end; + vtWideString: begin + result:= widestring(VWideString); + end; + vtInt64: begin + result:= inttostrmse(VInt64^); + end; + vtQWord: begin + result:= inttostrmse(VQWord^); + end + else begin + result:= ''; + end; + end; + end; +end; + +{ tformatmacrolist } + +procedure tformatmacrolist.addmac(const aname: msestring; + const avalue: msestring; const ahandler: macrohandlerty = nil); +begin + add([aname],[avalue],[ahandler]); +end; + +procedure clearformatmacros; +begin + freeandnil(fformatmacros); +end; + +initialization +{$ifndef FPC} + {$ifdef mswindows} + getlocaleformatsettings(0,defaultformatsettingsdot); + {$else} + defaultformatsettingsdot:= defaultformatsettings; + {$endif} +{$else} + defaultformatsettingsdot:= sysutils.defaultformatsettings; +{$endif} + defaultformatsettingsdot.DecimalSeparator:= '.'; +finalization + clearformatmacros; +end. diff --git a/mseide-msegui/lib/common/kernel/mseglob.pas b/mseide-msegui/lib/common/kernel/mseglob.pas new file mode 100644 index 0000000..1684665 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseglob.pas @@ -0,0 +1,185 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + classes,mclasses,mseerr,msetypes; +const + invalidaxis = -bigint; + defaultbase64linelength = 76; //todo: find better place + +type + listdatatypety = (dl_none,dl_integer,dl_int64,dl_currency, + dl_real,dl_realint,dl_realsum, + dl_datetime, + dl_pointer, + dl_ansistring,dl_msestring,dl_doublemsestring,dl_msestringint, + dl_complex,dl_rowstate,dl_custom); + listdatatypesty = set of listdatatypety; + + shortcutty = type word; + shortcutarty = array of shortcutty; + modalresultty = (mr_none,mr_canclose,mr_windowclosed,mr_windowdestroyed, + mr_escape,mr_f10, + mr_exception, + mr_cancel,mr_abort,mr_ok,mr_yes,mr_no,mr_all, + mr_yesall,mr_noall, + mr_ignore,mr_skip,mr_skipall,mr_continue); + pmodalresultty = ^modalresultty; + modalresultsty = set of modalresultty; + + inullinterface = interface + //no referencecount, only for fpc, not available in delphi + end; + +// {$ifdef FPC} +// tnullinterfacedobject = class(tobject) //not used +// end; +// {$else} + tnullinterfacedobject = class(tobject,iunknown) + protected + function _addref: integer; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} + + function _release: integer; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} + function queryinterface( + {$ifdef fpc_has_constref}constref{$else}const{$endif} + iid: tguid; out obj): hresult; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} + end; +// {$endif} + + objecteventty = (oe_destroyed,oe_connect,oe_disconnect, + oe_changed,oe_designchanged, + oe_activate,oe_deactivate,oe_fired,oe_dataready, + oe_bindfields,oe_releasefields); + objectlinkeventty = procedure(const sender: tobject; + const event: objecteventty) of object; + iobjectlink = interface(inullinterface) + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + //source = 1 -> dest destroyed + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + end; + + mseerrorty = (mse_ok,mse_resnotfound); + emse = class(eerror) + private + function geterror: mseerrorty; + public + constructor create(aerror: mseerrorty; atext: string); + property error: mseerrorty read geterror; + end; + +function fullcomponentname(component: tcomponent): string; + + +procedure mseerror(error: mseerrorty; text: string = ''); overload; +procedure mseerror(error: mseerrorty; sender: tobject; text: string = ''); overload; + +implementation +//uses +// mseclasses; +const + errortexts: array[mseerrorty] of string = + ('', + 'Resource not found' + ); + +function fullcomponentname(component: tcomponent): string; +begin + result:= component.name; + while component.owner <> nil do begin + component:= component.owner; + result:= component.name + '.' + result; + end; +end; + +procedure mseerror(error: mseerrorty; text: string); overload; +begin + if error = mse_ok then begin + exit; + end; + raise emse.create(error,text); +end; + +procedure mseerror(error: mseerrorty; sender: tobject; + text: string = ''); overload; +begin + if error = mse_ok then begin + exit; + end; + if sender <> nil then begin + text:= sender.classname + ' ' + text; + if sender is tcomponent then begin + text:= text + fullcomponentname(tcomponent(sender)); + end; + end; + mseerror(error,text); +end; + +{ tnullinterfacedobject } + +//{$ifndef fpc} +function tnullinterfacedobject._addref: integer; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} +begin + result:= -1; +end; + +function tnullinterfacedobject._release: integer; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} +begin + result:= -1; +end; + +function tnullinterfacedobject.QueryInterface( + {$ifdef fpc_has_constref}constref{$else}const{$endif} + IID: TGUID; out Obj): HResult; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} +begin + if getinterface(iid, obj) then begin + result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; +//{$endif} + +{ emse } + +constructor emse.create(aerror: mseerrorty; atext: string); +begin + inherited create(integer(aerror),atext,errortexts); +end; + +function emse.geterror: mseerrorty; +begin + result:= mseerrorty(ferror); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msegui.pas b/mseide-msegui/lib/common/kernel/msegui.pas new file mode 100644 index 0000000..ded4e48 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msegui.pas @@ -0,0 +1,22378 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegui; + +{$ifdef FPC} + {$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,sysutils,msegraphics,msetypes,mseact, + msestrings,mseerr,msegraphutils,mseapplication,msedragglob, + msepointer,mseevent,msekeyboard,mseclasses,mseglob,mseguiglob,mselist, + msesystypes,msethread,mseguiintf,{msesysdnd,}mseassistiveclient, + msebitmap,msearrayprops,msethreadcomp,mserichstring,msearrayutils + {$ifdef mse_with_ifi},mseifiglob,mseificompglob{$endif}; + +const + mseguiversiontext = '4.6.3'; + copyrighttext = 'Copyright 1999-2018'; + + defaultwidgetcolor = cl_default; + defaulttoplevelwidgetcolor = cl_background; + defaultfadecolor = cl_ltgray; + defaultfadecolor1 = cl_dkgray; + defaultfadeopacolor = cl_white; + hintdelaytime = 500000; //us + defaulthintshowtime = 3000000; //us + mouseparktime = 500000; //us + defaultdblclicktime = 400000; //us + mindragdist = 4; + + mousebuttons = [ss_left,ss_right,ss_middle]; + + //hintid values, user values > 0 + hintidnone = 0; + //internal ranges + hintidwidget = -1; + hintidframe = -100; + +type + + gdiregionty = record + gdi: pgdifunctionaty; + region: regionty; + end; + + frameskinoptionty = (fso_flat, + fso_noanim,fso_nomouseanim,fso_noclickanim,fso_nofocusanim, + fso_focusrect,fso_nofocusrect,fso_forcefocusrect, + fso_nodefaultrect,fso_noinnerrect, + fso_clientfacerect,fso_faceoverlay); + frameskinoptionsty = set of frameskinoptionty; + + frameskincontrolleroptionty = + (fsco_colorclient, //set colorclient in skincontroller + fsco_frameileftsize,fsco_frameirightsize, + fsco_frameitopsize,fsco_frameibottomsize, + //adjust clientsize in skincontroller by + //framei values + fsco_noclientsize); + //do not restore clientsize after frame size changes + frameskincontrolleroptionsty = set of frameskincontrolleroptionty; + + optionwidgetty = (ow_background,ow_top,ow_ultratop,ow_transientformain, + ow_noautosizing, //don't use, moved to optionswidget1 + ow_mousefocus,ow_tabfocus, + ow_parenttabfocus,ow_arrowfocus, + ow_arrowfocusin,ow_arrowfocusout, + ow_subfocus, //reflects focus to children + ow_focusbackonesc, + ow_keyreturntaborder, + //key_return and key_enter work like key_tab + ow_nosiblingshortcut, //do not react to shortcuts + //from siblings + ow_nochildshortcut, //do not propagate shortcuts to parent + ow_noparentshortcut, //do not react to shortcuts from parent + ow_canclosenil, // don't use, moved to optionswidget1 + ow_mousetransparent,ow_mousewheel, + ow_noscroll,ow_nochildpaintclip,ow_nochildclipsiblings, + ow_destroywidgets,ow_nohidewidgets, + ow_hinton,ow_hintoff,ow_disabledhint,ow_appinactivehint, + ow_multiplehint, + ow_timedhint + ); + optionswidgetty = set of optionwidgetty; + optionwidget1ty = ( + ow1_clientcxmin,ow1_clientcymin, + ow1_clientcxmax,ow1_clientcymax, + ow1_fontglyphheight, + //track font.glyphheight, + //create fonthighdelta and childscaled events + ow1_fontlineheight, + //track font.linespacing, + //create fonthighdelta and childscaled events + ow1_autoscale, //synchronizes bounds_cy or bonds_cx + //with fontheightdelta + ow1_autowidth,ow1_autoheight, + ow1_autosizeanright,ow1_noautosizeanright, + ow1_autosizeanbottom,ow1_noautosizeanbottom, + ow1_noparentwidthextend,ow1_noparentheightextend, + ow1_invisibleparentsizeextend, + ow1_canclosenil, //call canclose(nil) on exit + ow1_nocancloseifhidden, + ow1_modalcallonactivate,ow1_modalcallondeactivate, + //used in tactionwidget + ow1_noautosizing, //used in tdockcontroller + ow1_noclampinview, //used in doactivate() + ow1_noassistive + ); + +const + deprecatedoptionswidget= [ow_noautosizing,ow_canclosenil]; + invisibleoptionswidget = [ord(ow_noautosizing),ord(ow_canclosenil)]; + +type + optionswidget1ty = set of optionwidget1ty; + + optionskinty = (osk_skin,osk_noskin,osk_framebuttononly, + osk_noframe,osk_noface,osk_nooptions, + osk_container,osk_noclientsize, + osk_colorcaptionframe, + //use widget_colorcaptionframe independent of caption + osk_nocolorcaptionframe, + //don't use widget_colorcaptinframe independent of caption + osk_nopropleft,osk_noproptop, //used by tlayouter + osk_nopropwidth,osk_nopropheight, //used by tlayouter + osk_nopropfont, //used by tlayouter + osk_noalignx,osk_noaligny, //used by tlayouter + osk_nopaintref, //used by alignx()/aligny() + osk_nolayoutcx,osk_nolayoutcy //used by syncmaxaoutsize() + ); + optionsskinty = set of optionskinty; + + anchorty = (an_left,an_top,an_right,an_bottom); + anchorsty = set of anchorty; + + widgetstatety = (ws_visible,ws_enabled, + ws_active,ws_entered,ws_entering,ws_exiting,ws_focused, + ws_mouseinclient,ws_wantmousebutton,ws_wantmousemove, + //valid after call of updatemousestate only +// ws_wantmousewheel, + ws_wantmousefocus,ws_iswidget,ws_designing, + ws_opaque,ws_nopaint, + ws_lclicked,ws_mclicked,ws_rclicked, + ws_mousecaptured,ws_clientmousecaptured, + ws_newmousecapture, + ws_loadlock,ws_loadedproc,ws_showproc, + ws_minclientsizevalid, +// ws_showed,ws_hidden, //used in tcustomeventwidget + ws_destroying, + ws_staticframe,ws_staticface, + ws_isvisible + ); + widgetstatesty = set of widgetstatety; + widgetstate1ty = (ws1_childscaled,ws1_childrectchanged, + ws1_widgetrectsetting, + ws1_scaling,ws1_autoscaling,ws1_autosizing, + ws1_painting,ws1_updateopaque, + ws1_widgetregionvalid,ws1_rootvalid, + ws1_anchorsizing,ws1_anchorsetting,ws1_layoutplacing, + ws1_parentclientsizeinited, + ws1_parentupdating, //set while setparentwidget + ws1_isstreamed, //used by ttabwidget + ws1_scaled, //used in tcustomscalingwidget + ws1_forceclose, + ws1_noclipchildren,ws1_tryshrink, + ws1_noframewidgetshift,ws1_framemouse, + ws1_nodesignvisible,ws1_nodesignframe,ws1_nodesignhandles, + ws1_nodesigndelete,ws1_nodesignmove, + ws1_designactive,ws1_nodisabledclick,ws1_designwidget, + ws1_fakevisible,ws1_nominsize, + //used for report size calculations + ws1_onkeydowncalled + ); + widgetstates1ty = set of widgetstate1ty; + + framestatety = (fs_sbhorzon,fs_sbverton,fs_sbhorzfix,fs_sbvertfix, + fs_sbhorztop,fs_sbvertleft, + fs_sbleft,fs_sbtop,fs_sbright,fs_sbbottom, + fs_nowidget,fs_nosetinstance,fs_framemouse, + fs_disabled,fs_creating,fs_stateupdating, + fs_clientrectchanging, + fs_cancaptionsyncx,fs_cancaptionsyncy, + fs_drawfocusrect,fs_paintrectfocus, + fs_captionfocus,fs_captionhint, + fs_rectsvalid,fs_widgetregionchanging, + fs_widgetactive,fs_paintposinited,fs_needsmouseinvalidate, + fs_canclientextendx,fs_canclientextendy); + framestatesty = set of framestatety; + + hintflagty = (hfl_show,hfl_custom,{hfl_left,hfl_top,hfl_right,hfl_bottom,} + hfl_noautohidemove); + hintflagsty = set of hintflagty; + +const + defaultwidgetstates = [ws_visible,ws_enabled,ws_iswidget,ws_isvisible]; + defaultwidgetstatesinvisible = [ws_enabled,ws_iswidget]; + focusstates = [ws_visible,ws_enabled]; + defaultoptionswidget = [ow_mousefocus,ow_tabfocus,ow_arrowfocus,{ow_mousewheel,} + ow_destroywidgets{,ow_autoscale}]; +// defaultoptionswidget1 = [ow1_modalcallondeactivate]; + defaultoptionswidget1 = [ow1_autoscale]; + defaultoptionswidgetmousewheel = defaultoptionswidget + [ow_mousewheel]; + defaultoptionswidgetnofocus = defaultoptionswidget - + [ow_mousefocus,ow_tabfocus,ow_arrowfocus]; + defaultoptionswidgetsubfocus = defaultoptionswidget + [ow_subfocus]; + defaultoptionsskin = []; + defaultcontainerskinoptions = defaultoptionsskin + + [osk_container,osk_noclientsize]; + + defaultwidgetwidth = 50; + defaultwidgetheight = 50; + defaultanchors = [an_left,an_top]; + defaulthintflags = []; + +type + + framelocalpropty = (frl_levelo,frl_leveli,frl_framewidth,{frl_extraspace,} + frl_colorframe,frl_colorframeactive, + frl_colordkshadow,frl_colorshadow, + frl_colorlight,frl_colorhighlight, + frl_colordkwidth,frl_colorhlwidth, + frl_hiddenedges, + frl_fileft,frl_fitop,frl_firight,frl_fibottom, + frl_frameimagelist,frl_frameimageleft,frl_frameimagetop, + frl_frameimageright,frl_frameimagebottom, + frl_frameimageoffset,frl_frameimageoffset1, + frl_frameimageoffsetdisabled,frl_frameimageoffsetmouse, + frl_frameimageoffsetclicked, + frl_frameimageoffsetfocused,frl_frameimageoffsetactive, +{ + frl_frameimageoffsetactivemouse, + frl_frameimageoffsetactiveclicked, +} + frl_optionsskin, + frl_colorclient, + frl_nodisable); + framelocalpropsty = set of framelocalpropty; + + framelocalprop1ty = (frl1_framefacelist, + frl1_framefaceoffset,frl1_framefaceoffset1, + frl1_framefaceoffsetdisabled,frl1_framefaceoffsetmouse, + frl1_framefaceoffsetclicked, + frl1_framefaceoffsetfocused,frl1_framefaceoffsetactive, + { + frl1_framefaceoffsetactivemouse, + frl1_framefaceoffsetactiveclicked, + } + frl1_font,frl1_captiondist,frl1_captionoffset, + frl1_focusrectdist, + frl1_imagedist,frl1_imagedist1,frl1_imagedist2, + frl1_extraspace, + frl1_foleft,frl1_fotop,frl1_foright,frl1_fobottom, + frl1_colorglyph, //for menu template + frl1_colorpattern, + frl1_colorframedisabled,frl1_colorframemouse, + frl1_colorframeclicked,frl1_colorframedefault + ); + framelocalprops1ty = set of framelocalprop1ty; + + framestateflagty = (fsf_offset1,fsf_disabled,fsf_focused,fsf_active, + fsf_mouse,fsf_clicked,fsf_default); + framestateflagsty = set of framestateflagty; + +const + allframelocalprops: framelocalpropsty = + [frl_levelo,frl_leveli,frl_framewidth, + frl_colorframe,frl_colorframeactive, + frl_colordkshadow,frl_colorshadow, + frl_colorlight,frl_colorhighlight, + frl_colordkwidth,frl_colorhlwidth, + frl_hiddenedges, + frl_fileft,frl_fitop,frl_firight,frl_fibottom, + frl_frameimagelist,frl_frameimageleft,frl_frameimagetop, + frl_frameimageright,frl_frameimagebottom, + frl_frameimageoffset,frl_frameimageoffset1, + frl_frameimageoffsetdisabled,frl_frameimageoffsetmouse, + frl_frameimageoffsetclicked, + frl_frameimageoffsetfocused,frl_frameimageoffsetactive, +{ + frl_frameimageoffsetactivemouse, + frl_frameimageoffsetactiveclicked, +} + frl_optionsskin, + frl_colorclient, + frl_nodisable]; + allframelocalprops1: framelocalprops1ty = [ + frl1_framefacelist, + frl1_framefaceoffset,frl1_framefaceoffset1, + frl1_framefaceoffsetdisabled,frl1_framefaceoffsetmouse, + frl1_framefaceoffsetclicked, + frl1_framefaceoffsetfocused,frl1_framefaceoffsetactive, + { + frl1_framefaceoffsetactivemouse, + frl1_framefaceoffsetactiveclicked, + } + frl1_font,frl1_captiondist,frl1_captionoffset, + frl1_focusrectdist, + frl1_extraspace, + frl1_imagedist,frl1_imagedist1,frl1_imagedist2, + frl1_foleft,frl1_fotop,frl1_foright,frl1_fobottom, + frl1_colorglyph,frl1_colorpattern, + frl1_colorframedisabled,frl1_colorframemouse, + frl1_colorframeclicked,frl1_colorframedefault]; +type + facelocalpropty = (fal_options,fal_framei_left,fal_framei_top, + fal_framei_right,fal_framei_bottom, + fal_fadirection,fal_image, + fal_fapos,fal_facolor,fal_faopapos,fal_faopacolor, + fal_fatransparency, + fal_faopacity,fal_frameimagelist,fal_frameimageoffset); + facelocalpropsty = set of facelocalpropty; + +const + allfacelocalprops: facelocalpropsty = + [fal_options,fal_framei_left,fal_framei_top, + fal_framei_right,fal_framei_bottom, + fal_fadirection,fal_image, + fal_fapos,fal_facolor,fal_faopapos,fal_faopacolor, + fal_fatransparency, + fal_faopacity,fal_frameimagelist,fal_frameimageoffset]; +deprecatedfacelocalprops = [fal_fatransparency]; +invisiblefacelocalprops = [ord(fal_fatransparency)]; + +type + twidget = class; + widgetclassty = class of twidget; + tcustomframe = class; + + hintinfoty = record + flags: hintflagsty; + caption: captionty; + posrect: rectty; + placement: captionposty; + showtime: integer; + mouserefpos: pointty; + hintwidgetclass: widgetclassty; +// id: int32; + end; + + showhinteventty = procedure(const sender: tobject; var info: hintinfoty) of object; + + iframe = interface(inullinterface) + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getwidget: twidget; + function getwidgetrect: rectty; + function getframestateflags: framestateflagsty; + end; + + icaptionframe = interface(iframe) + function getcanvas(aorigin: originty = org_client): tcanvas; + function getframefont: tfont; + procedure setwidgetrect(const rect: rectty); + end; + + iscrollframe = interface(icaptionframe) + function widgetstate: widgetstatesty; + function getzoomrefframe: framety; + end; + + tfacelist = class; + + frameoffsetsty = record + offset: integer; + offset1: integer; + disabled: integer; + mouse: integer; + clicked: integer; + active: integer; + focused: integer; + { + activemouse: integer; + activeclicked: integer; + } + end; + + frameimageoffsetsty = record + offset: imagenrty; + offset1: imagenrty; + disabled: imagenrty; + mouse: imagenrty; + clicked: imagenrty; + active: imagenrty; + focused: imagenrty; + { + activemouse: imagenrty; + activeclicked: imagenrty; + } + end; + + framefaceoffsetsty = record + offset: facenrty; + offset1: facenrty; + disabled: facenrty; + mouse: facenrty; + clicked: facenrty; + active: facenrty; + focused: facenrty; + // activemouse: facenrty; +// activeclicked: facenrty; + end; + + baseframeinfoty = record + levelo: integer; + leveli: integer; + framewidth: integer; + colorframe: colorty; + colorframeactive: colorty; + colorframedisabled: colorty; + colorframemouse: colorty; + colorframeclicked: colorty; + colorframedefault: colorty; + hiddenedges: edgesty; + framecolors: framecolorinfoty; + colorclient: colorty; + innerframe: framety; + outerframe: framety; + focusrectdist: int32; + extraspace: int32; + imagedist: int32; + imagedist1: int32; + imagedist2: int32; + + colorglyph: colorty; //for menu template and scrollbar + colorpattern: colorty; //for scrollbar + + frameimage_left: integer; + frameimage_top: integer; + frameimage_right: integer; + frameimage_bottom: integer; + frameimage_offsets: frameimageoffsetsty; + + frameface_offsets: framefaceoffsetsty; + optionsskin: frameskinoptionsty; + + frameface_list: tfacelist; //not copied by move + frameimage_list: timagelist; // + end; + + captionframeinfoty = record + captiondist: integer; + captionoffset: integer; + font: toptionalfont; + end; + + frameinfoty = record + ba: baseframeinfoty; + capt: captionframeinfoty + end; + + widgetatposinfoty = record + pos: pointty; + mouseeventinfopo: pmouseeventinfoty; + parentstate,childstate: widgetstatesty + end; + + tframecomp = class; + + tcustomframe = class(toptionalpersistent,iimagelistinfo) + private + procedure setlevelo(const Value: integer); + function islevelostored: boolean; + procedure setleveli(const Value: integer); + function islevelistored: boolean; + procedure setframewidth(const Value: integer); + function isframewidthstored: boolean; + procedure setcolorframe(const Value: colorty); + function iscolorframestored: boolean; + procedure setcolorframeactive(const avalue: colorty); + function iscolorframeactivestored: boolean; + procedure setcolorframedisabled(const avalue: colorty); + function iscolorframedisabledstored: boolean; + procedure setcolorframemouse(const avalue: colorty); + function iscolorframemousestored: boolean; + procedure setcolorframeclicked(const avalue: colorty); + function iscolorframeclickedstored: boolean; + procedure setcolorframedefault(const avalue: colorty); + function iscolorframedefaultstored: boolean; + procedure setcolordkshadow(const avalue: colorty); + function iscolordkshadowstored: boolean; + procedure setcolorshadow(const avalue: colorty); + function iscolorshadowstored: boolean; + procedure setcolorlight(const avalue: colorty); + function iscolorlightstored: boolean; + procedure setcolorhighlight(const avalue: colorty); + function iscolorhighlightstored: boolean; + procedure setcolordkwidth(const avalue: integer); + function iscolordkwidthstored: boolean; + procedure setcolorhlwidth(const avalue: integer); + function iscolorhlwidthstored: boolean; + procedure sethiddenedges(const avalue: edgesty); + function ishiddenedgesstored: boolean; + + procedure setframei(const avalue: framety); + procedure setframei_bottom(const Value: integer); + function isfibottomstored: boolean; + procedure setframei_left(const Value: integer); + function isfileftstored: boolean; + procedure setframei_right(const Value: integer); + function isfirightstored: boolean; + procedure setframei_top(const Value: integer); + function isfitopstored: boolean; + + procedure setframeo(const avalue: framety); + procedure setframeo_bottom(const Value: integer); + function isfobottomstored: boolean; + procedure setframeo_left(const Value: integer); + function isfoleftstored: boolean; + procedure setframeo_right(const Value: integer); + function isforightstored: boolean; + procedure setframeo_top(const Value: integer); + function isfotopstored: boolean; + + procedure setframeimage_list(const avalue: timagelist); + function getimagelist: timagelist; + function isframeimage_liststored: boolean; + procedure setframeimage_left(const avalue: integer); + function isframeimage_leftstored: boolean; + procedure setframeimage_top(const avalue: integer); + function isframeimage_topstored: boolean; + procedure setframeimage_right(const avalue: integer); + function isframeimage_rightstored: boolean; + procedure setframeimage_bottom(const avalue: integer); + function isframeimage_bottomstored: boolean; + + procedure setframeimage_offset(const avalue: imagenrty); + function isframeimage_offsetstored: boolean; + procedure setframeimage_offset1(const avalue: imagenrty); + function isframeimage_offset1stored: boolean; + procedure setframeimage_offsetdisabled(const avalue: imagenrty); + function isframeimage_offsetdisabledstored: boolean; + procedure setframeimage_offsetmouse(const avalue: imagenrty); + function isframeimage_offsetmousestored: boolean; + procedure setframeimage_offsetclicked(const avalue: imagenrty); + function isframeimage_offsetclickedstored: boolean; + procedure setframeimage_offsetactive(const avalue: imagenrty); + function isframeimage_offsetactivestored: boolean; + procedure setframeimage_offsetfocused(const avalue: imagenrty); + function isframeimage_offsetfocusedstored: boolean; + procedure setframeface_list(const avalue: tfacelist); + function isframeface_liststored: boolean; + procedure setframeface_offset(const avalue: facenrty); + function isframeface_offsetstored: boolean; + procedure setframeface_offset1(const avalue: facenrty); + function isframeface_offset1stored: boolean; + procedure setframeface_offsetdisabled(const avalue: facenrty); + function isframeface_offsetdisabledstored: boolean; + procedure setframeface_offsetmouse(const avalue: facenrty); + function isframeface_offsetmousestored: boolean; + procedure setframeface_offsetclicked(const avalue: facenrty); + function isframeface_offsetclickedstored: boolean; + procedure setframeface_offsetactive(const avalue: facenrty); + function isframeface_offsetactivestored: boolean; + procedure setframeface_offsetfocused(const avalue: facenrty); + function isframeface_offsetfocusedstored: boolean; + procedure setoptionsskin(const avalue: frameskinoptionsty); + function isoptionsskinstored: boolean; + + procedure setcolorclient(const Value: colorty); + function iscolorclientstored: boolean; + procedure setfocusrectdist(const avalue: int32); + function isfocusrectdiststored: boolean; + procedure setextraspace(const avalue: int32); + function isextraspacestored: boolean; + procedure setimagedist(const avalue: int32); + function isimagediststored: boolean; + procedure setimagedist1(const avalue: int32); + function isimagedist1stored: boolean; + procedure setimagedist2(const avalue: int32); + function isimagedist2stored: boolean; + procedure settemplate(const avalue: tframecomp); + procedure setlocalprops(const avalue: framelocalpropsty); + procedure setlocalprops1(const avalue: framelocalprops1ty); + protected + ftemplate: tframecomp; + flocalprops: framelocalpropsty; + flocalprops1: framelocalprops1ty; + fintf: iframe; + fstate: framestatesty; + fwidth: framety; + fouterframe: framety; + fpaintframedelta: framety; + fpaintframe: framety; + finnerframe: framety; + fpaintrect: rectty; + fclientrect: rectty; //origin = fpaintrect.pos + finnerclientrect: rectty; //origin = fpaintrect.pos + fpaintposbefore: pointty; + fi: baseframeinfoty; + procedure defineproperties(filer: tfiler); override; + function isoptional: boolean; override; + procedure settemplateinfo(const ainfo: frameinfoty); virtual; + procedure setdisabled(const value: boolean); virtual; + procedure updateclientrect; virtual; + class function calcpaintframe(const afi: baseframeinfoty): framety; + class function calcinnerframe(const afi: baseframeinfoty): framety; + procedure calcrects; + procedure updaterects; virtual; + procedure internalupdatestate(); + procedure updatestate(); virtual; + procedure checkstate; + procedure poschanged; virtual; + procedure fontcanvaschanged; virtual; + procedure visiblechanged; virtual; + procedure getpaintframe(var frame: framety); virtual; + //additional space, (scrollbars,mainmenu...) + procedure dokeydown(var info: keyeventinfoty); virtual; + function checkfocusshortcut(var info: keyeventinfoty): boolean; virtual; + procedure parentfontchanged; virtual; + procedure dopaintfocusrect(const canvas: tcanvas; + const rect: rectty); virtual; + procedure updatewidgetstate; virtual; + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); virtual; + function needsactiveinvalidate: boolean; + function needsenabledinvalidate: boolean; + function needsfocusedinvalidate: boolean; + function needsmouseinvalidate: boolean; + function needsclickinvalidate: boolean; + function needsmouseenterinvalidate: boolean; + procedure activechanged; virtual; + procedure enabledchanged(); virtual; + procedure focusedchanged virtual; + function needsfocuspaint: boolean virtual; + function haspaintrectfocus(): boolean virtual; + function ishintarea(const apos: pointty; var aid: int32): boolean virtual; + procedure checkminscrollsize(var asize: sizety) virtual; + procedure checkminclientsize(var asize: sizety) virtual; + procedure checkminshrinksize(var asize: sizety) virtual; + procedure addscrollbarwidth(var asize: sizety) virtual; + procedure subscrollbarwidth(var asize: sizety) virtual; + procedure paintframeface(const canvas: tcanvas; const arect: rectty); + class procedure drawframe(const canvas: tcanvas; const rect2: rectty; + const afi: baseframeinfoty; const astate: framestateflagsty); + function actualcolorclient(): colorty virtual; + procedure internalpaintbackground(const canvas: tcanvas; + const arect: rectty; const clip: boolean; + const move: boolean) virtual; + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) virtual; + procedure updatehotkeys() virtual; + //iassistiveclient + function getassistivecaption(): msestring; virtual; + public + constructor create(const intf: iframe); reintroduce; + destructor destroy; override; + procedure checktemplate(const sender: tobject); virtual; + procedure assign(source: tpersistent); override; + procedure scale(const ascale: real); virtual; + procedure checkwidgetsize(var asize: sizety); virtual; + //extends to minimal size + procedure showhint(const aid: int32; var info: hintinfoty); virtual; + + procedure paintbackground(const canvas: tcanvas; + const arect: rectty; const clip: boolean; const move: boolean); + procedure paintoverlay(const canvas: tcanvas; const arect: rectty); + function pointinmask(const pos: pointty; const arect: rectty): boolean; + + function outerframedim: sizety; //widgetsize - framesize + function outerframecx: int32; + function outerframecy: int32; + function frameframedim: sizety; //widgetsize - (paintsize + paintframe) + function frameframecx: int32; + function frameframecy: int32; + function paintframedim: sizety; //widgetsize - paintsize + function paintframecx: int32; + function paintframecy: int32; + function innerframedim: sizety; //widgetsize - innersize + function innerframecx: int32; + function innerframecy: int32; + function outerframe: framety; + function paintframe: framety; + function paintframedelta: framety; //paintframe-outerframe + function innerframe: framety; + function cellframe: framety; //innerframe without paintframedelta + function pointincaption(const point: pointty): boolean; virtual; + //origin = widgetrect + procedure initgridframe; virtual; + procedure changedirection(const oldvalue: graphicdirectionty; + const newvalue: graphicdirectionty); + property intf: iframe read fintf; + property levelo: integer read fi.levelo write setlevelo + stored islevelostored default 0; + property leveli: integer read fi.leveli write setleveli + stored islevelistored default 0; + property framewidth: integer read fi.framewidth write setframewidth + stored isframewidthstored default 0; + property colorframe: colorty read fi.colorframe write setcolorframe + stored iscolorframestored default cl_default; + property colorframeactive: colorty read fi.colorframeactive + write setcolorframeactive + stored iscolorframeactivestored default cl_default; + property colorframedisabled: colorty read fi.colorframedisabled + write setcolorframedisabled + stored iscolorframedisabledstored default cl_default; + property colorframemouse: colorty read fi.colorframemouse + write setcolorframemouse + stored iscolorframemousestored default cl_default; + property colorframeclicked: colorty read fi.colorframeclicked + write setcolorframeclicked + stored iscolorframeclickedstored default cl_default; + property colorframedefault: colorty read fi.colorframedefault + write setcolorframedefault + stored iscolorframedefaultstored default cl_default; + + property colordkshadow: colorty read fi.framecolors.edges.shadow.effectcolor + write setcolordkshadow + stored iscolordkshadowstored default cl_default; + property colorshadow: colorty read fi.framecolors.edges.shadow.color + write setcolorshadow + stored iscolorshadowstored default cl_default; + property colorlight: colorty read fi.framecolors.edges.light.color + write setcolorlight + stored iscolorlightstored default cl_default; + property colorhighlight: colorty read fi.framecolors.edges.light.effectcolor + write setcolorhighlight + stored iscolorhighlightstored default cl_default; + property colordkwidth: integer read fi.framecolors.edges.shadow.effectwidth + write setcolordkwidth + stored iscolordkwidthstored default -1; + property colorhlwidth: integer read fi.framecolors.edges.light.effectwidth + write setcolorhlwidth + stored iscolorhlwidthstored default -1; + property hiddenedges: edgesty read fi.hiddenedges + write sethiddenedges default []; + + property framei: framety read fi.innerframe write setframei; + //does not set localprops + property framei_left: integer read fi.innerframe.left write setframei_left + stored isfileftstored default 0; + property framei_top: integer read fi.innerframe.top write setframei_top + stored isfitopstored default 0; + property framei_right: integer read fi.innerframe.right write setframei_right + stored isfirightstored default 0; + property framei_bottom: integer read fi.innerframe.bottom + write setframei_bottom + stored isfibottomstored default 0; + + property frameo: framety read fi.outerframe write setframeo; + //does not set localprops + property frameo_left: integer read fi.outerframe.left write setframeo_left + stored isfoleftstored default 0; + property frameo_top: integer read fi.outerframe.top write setframeo_top + stored isfotopstored default 0; + property frameo_right: integer read fi.outerframe.right write setframeo_right + stored isforightstored default 0; + property frameo_bottom: integer read fi.outerframe.bottom + write setframeo_bottom + stored isfobottomstored default 0; + + property frameimage_list: timagelist read fi.frameimage_list + write setframeimage_list stored isframeimage_liststored; + //imagenr 0 = topleft, 1 = left, 2 = bottomleft, 3 = bottom, + //4 = bottomright, 5 = right, 6 = topright, 7 = top + property frameimage_left: integer read fi.frameimage_left + write setframeimage_left + stored isframeimage_leftstored default 0; + property frameimage_top: integer read fi.frameimage_top + write setframeimage_top + stored isframeimage_topstored default 0; + property frameimage_right: integer read fi.frameimage_right + write setframeimage_right + stored isframeimage_rightstored default 0; + property frameimage_bottom: integer read fi.frameimage_bottom + write setframeimage_bottom + stored isframeimage_bottomstored default 0; + //added to imagelist size. + property frameimage_offset: imagenrty read fi.frameimage_offsets.offset + write setframeimage_offset + stored isframeimage_offsetstored default 0; + property frameimage_offset1: imagenrty read fi.frameimage_offsets.offset1 + write setframeimage_offset1 + stored isframeimage_offset1stored default 0; + //used for default button + property frameimage_offsetdisabled: imagenrty + read fi.frameimage_offsets.disabled + write setframeimage_offsetdisabled + stored isframeimage_offsetdisabledstored default 0; + property frameimage_offsetmouse: imagenrty + read fi.frameimage_offsets.mouse + write setframeimage_offsetmouse + stored isframeimage_offsetmousestored default 0; + property frameimage_offsetclicked: imagenrty + read fi.frameimage_offsets.clicked + write setframeimage_offsetclicked + stored isframeimage_offsetclickedstored default 0; + property frameimage_offsetactive: imagenrty + read fi.frameimage_offsets.active + write setframeimage_offsetactive + stored isframeimage_offsetactivestored default 0; + property frameimage_offsetfocused: imagenrty + read fi.frameimage_offsets.focused + write setframeimage_offsetfocused + stored isframeimage_offsetfocusedstored default 0; + property frameface_list: tfacelist read fi.frameface_list + write setframeface_list stored isframeface_liststored; + property frameface_offset: facenrty read fi.frameface_offsets.offset + write setframeface_offset + stored isframeface_offsetstored default 0; + property frameface_offset1: facenrty + read fi.frameface_offsets.offset1 + write setframeface_offset1 + stored isframeface_offset1stored default 0; + //used for default button + property frameface_offsetdisabled: facenrty + read fi.frameface_offsets.disabled + write setframeface_offsetdisabled + stored isframeface_offsetdisabledstored default 0; + property frameface_offsetmouse: facenrty + read fi.frameface_offsets.mouse + write setframeface_offsetmouse + stored isframeface_offsetmousestored default 0; + property frameface_offsetclicked: facenrty + read fi.frameface_offsets.clicked + write setframeface_offsetclicked + stored isframeface_offsetclickedstored default 0; + property frameface_offsetactive: facenrty + read fi.frameface_offsets.active + write setframeface_offsetactive + stored isframeface_offsetactivestored default 0; + property frameface_offsetfocused: facenrty + read fi.frameface_offsets.focused + write setframeface_offsetfocused + stored isframeface_offsetfocusedstored default 0; + property optionsskin: frameskinoptionsty read fi.optionsskin + write setoptionsskin stored isoptionsskinstored default []; + property focusrectdist: int32 read fi.focusrectdist + write setfocusrectdist + stored isfocusrectdiststored default 0; + property extraspace: int32 read fi.extraspace + write setextraspace + stored isextraspacestored default 0; + property imagedist: int32 read fi.imagedist + write setimagedist + stored isimagediststored default 0; + property imagedist1: int32 read fi.imagedist1 + write setimagedist1 + stored isimagedist1stored default 0; + property imagedist2: int32 read fi.imagedist2 + write setimagedist2 + stored isimagedist2stored default 0; + property colorclient: colorty read fi.colorclient write setcolorclient + stored iscolorclientstored default cl_default; + property localprops: framelocalpropsty read flocalprops + write setlocalprops {default []}; + property localprops1: framelocalprops1ty read flocalprops1 + write setlocalprops1 {default []}; + property template: tframecomp read ftemplate write settemplate; + end; + + tframe = class(tcustomframe) + published + property levelo; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_right; + property frameimage_top; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; + + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; + + property optionsskin; + + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + + property colorclient; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property localprops; //before template + property localprops1; //before template + property template; + end; + + tframetemplate = class; + + beforeframepaintbackgroundeventty = procedure (const sender: tcustomframe; + const canvas: tcanvas; const arect: rectty; + const clip: boolean; const move: boolean; + var handled: boolean) of object; + afterframepaintbackgroundeventty = procedure (const sender: tcustomframe; + const canvas: tcanvas; const arect: rectty; + const clip: boolean; const move: boolean) of object; + beforeframepaintoverlayeventty = procedure (const sender: tcustomframe; + const canvas: tcanvas; const arect: rectty; + var handled: boolean) of object; + afterframepaintoverlayeventty = procedure (const sender: tcustomframe; + const canvas: tcanvas; const arect: rectty) of object; + + beforeframetemplatepaintbackgroundeventty = + procedure (const sender: tframetemplate; const canvas: tcanvas; + const arect: rectty; const astate: framestateflagsty; + var handled: boolean) of object; + afterframetemplatepaintbackgroundeventty = + procedure (const sender: tframetemplate; const canvas: tcanvas; + const arect: rectty; const astate: framestateflagsty) of object; + beforeframetemplatepaintoverlayeventty = + procedure (const sender: tframetemplate; const canvas: tcanvas; + const arect: rectty; const astate: framestateflagsty; + var handled: boolean) of object; + afterframetemplatepaintoverlayeventty = + procedure (const sender: tframetemplate; const canvas: tcanvas; + const arect: rectty; const astate: framestateflagsty) of object; + + tframetemplate = class(tpersistenttemplate,iimagelistinfo) + private + foptionsskincontroller: frameskincontrolleroptionsty; + fclientsizeextend: sizety; + fonbeforepaintbackground: beforeframepaintbackgroundeventty; + fonafterpaintbackground: afterframepaintbackgroundeventty; + fonbeforepaintoverlay: beforeframepaintoverlayeventty; + fonafterpaintoverlay: afterframepaintoverlayeventty; + fonbeforetemplatepaintbackground: beforeframetemplatepaintbackgroundeventty; + fonaftertemplatepaintbackground: afterframetemplatepaintbackgroundeventty; + fonbeforetemplatepaintoverlay: beforeframetemplatepaintoverlayeventty; + fonaftertemplatepaintoverlay: afterframetemplatepaintoverlayeventty; + procedure setcolorclient(const Value: colorty); + procedure setcolorframe(const Value: colorty); + procedure setcolorframeactive(const avalue: colorty); + procedure setcolorframedisabled(const avalue: colorty); + procedure setcolorframemouse(const avalue: colorty); + procedure setcolorframeclicked(const avalue: colorty); + procedure setcolorframedefault(const avalue: colorty); + procedure setcolordkshadow(const avalue: colorty); + procedure setcolorshadow(const avalue: colorty); + procedure setcolorlight(const avalue: colorty); + procedure setcolorhighlight(const avalue: colorty); + procedure setcolordkwidth(const avalue: integer); + procedure setcolorhlwidth(const avalue: integer); + procedure setcolorglyph(const avalue: colorty); + procedure setcolorpattern(const avalue: colorty); + + procedure sethiddenedges(const avalue: edgesty); + + procedure setframei_bottom(const Value: integer); + procedure setframei_left(const Value: integer); + procedure setframei_right(const Value: integer); + procedure setframei_top(const Value: integer); + procedure setframeo_bottom(const Value: integer); + procedure setframeo_left(const Value: integer); + procedure setframeo_right(const Value: integer); + procedure setframeo_top(const Value: integer); + procedure setframewidth(const Value: integer); + procedure setextraspace(const avalue: integer); + procedure setimagedist(const avalue: integer); + procedure setimagedist1(const avalue: integer); + procedure setimagedist2(const avalue: integer); + procedure setleveli(const Value: integer); + procedure setlevelo(const Value: integer); + + procedure setframeimage_list(const avalue: timagelist); + function getimagelist: timagelist; + procedure setframeimage_left(const avalue: integer); + procedure setframeimage_top(const avalue: integer); + procedure setframeimage_right(const avalue: integer); + procedure setframeimage_bottom(const avalue: integer); + procedure setframeimage_offset(const avalue: imagenrty); + procedure setframeimage_offset1(const avalue: imagenrty); + procedure setframeimage_offsetdisabled(const avalue: imagenrty); + procedure setframeimage_offsetmouse(const avalue: imagenrty); + procedure setframeimage_offsetclicked(const avalue: imagenrty); + procedure setframeimage_offsetactive(const avalue: imagenrty); + procedure setframeimage_offsetfocused(const avalue: imagenrty); + + procedure setframeface_list(const avalue: tfacelist); + procedure setframeface_offset(const avalue: facenrty); + procedure setframeface_offset1(const avalue: facenrty); + procedure setframeface_offsetdisabled(const avalue: facenrty); + procedure setframeface_offsetmouse(const avalue: facenrty); + procedure setframeface_offsetclicked(const avalue: facenrty); + procedure setframeface_offsetactive(const avalue: facenrty); + procedure setframeface_offsetfocused(const avalue: facenrty); + + procedure setoptionsskin(const avalue: frameskinoptionsty); + function getfont: toptionalfont; + procedure setfont(const avalue: toptionalfont); + function isfontstored: boolean; + procedure setcaptiondist(const avalue: integer); + procedure setcaptionoffset(const avalue: integer); + procedure setfocusrectdist(const avalue: integer); + procedure fontchanged(const sender: tobject); + procedure readdummy(reader: treader); + procedure readimagedisttop(reader: treader); + procedure readimagedistbottom(reader: treader); + protected + fi: frameinfoty; +// fextraspace: integer; +// fimagedist: integer; +// fimagedist1: integer; +// fimagedist2: integer; + procedure doassignto(dest: tpersistent); override; + function getinfosize: integer; override; + function getinfoad: pointer; override; + procedure copyinfo(const source: tpersistenttemplate); override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(const owner: tmsecomponent; + const onchange: notifyeventty); override; + destructor destroy; override; + procedure paintbackground(const acanvas: tcanvas; const arect: rectty; + const astate: framestateflagsty = []); + //arect = paintrect + procedure paintoverlay(const acanvas: tcanvas; const arect: rectty; + const astate: framestateflagsty = []); + //arect = paintrect + procedure paintbackgroundframe(const acanvas: tcanvas; const arect: rectty; + const astate: framestateflagsty = []); + //arect = framerect + procedure paintoverlayframe(const acanvas: tcanvas; const arect: rectty; + const astate: framestateflagsty = []); + //arect = framerect + function paintframe: framety; + function innerframe: framety; + function paintframedim: sizety; + function innerframedim: sizety; + procedure createfont; + property framei: framety read fi.ba.innerframe; + property frameo: framety read fi.ba.outerframe; + property clientsizeextend: sizety read fclientsizeextend + write fclientsizeextend; + published + property levelo: integer read fi.ba.levelo write setlevelo default 0; + property leveli: integer read fi.ba.leveli write setleveli default 0; + property framewidth: integer read fi.ba.framewidth + write setframewidth default 0; + property colorframe: colorty read fi.ba.colorframe + write setcolorframe default cl_default; + property colorframeactive: colorty read fi.ba.colorframeactive + write setcolorframeactive default cl_default; + property colorframedisabled: colorty read fi.ba.colorframedisabled + write setcolorframedisabled default cl_default; + property colorframemouse: colorty read fi.ba.colorframemouse + write setcolorframemouse default cl_default; + property colorframeclicked: colorty read fi.ba.colorframeclicked + write setcolorframeclicked default cl_default; + property colorframedefault: colorty read fi.ba.colorframedefault + write setcolorframedefault default cl_default; + property colorglyph: colorty read fi.ba.colorglyph + write setcolorglyph default cl_default; + property colorpattern: colorty read fi.ba.colorpattern + write setcolorpattern default cl_default; + + property framei_left: integer read fi.ba.innerframe.left + write setframei_left default 0; + property framei_top: integer read fi.ba.innerframe.top + write setframei_top default 0; + property framei_right: integer read fi.ba.innerframe.right + write setframei_right default 0; + property framei_bottom: integer read fi.ba.innerframe.bottom + write setframei_bottom default 0; + + property frameo_left: integer read fi.ba.outerframe.left + write setframeo_left default 0; + property frameo_top: integer read fi.ba.outerframe.top + write setframeo_top default 0; + property frameo_right: integer read fi.ba.outerframe.right + write setframeo_right default 0; + property frameo_bottom: integer read fi.ba.outerframe.bottom + write setframeo_bottom default 0; + + property frameimage_list: timagelist read fi.ba.frameimage_list + write setframeimage_list; + //imagenr 0 = topleft, 1 = left, 2 = bottomleft, 3 = bottom, 4 = bottomright + //5 = right, 6 = topright, 7 = top + property frameimage_left: integer read fi.ba.frameimage_left + write setframeimage_left default 0; + property frameimage_top: integer read fi.ba.frameimage_top + write setframeimage_top default 0; + property frameimage_right: integer read fi.ba.frameimage_right + write setframeimage_right default 0; + property frameimage_bottom: integer read fi.ba.frameimage_bottom + write setframeimage_bottom default 0; + //added to imagelist size. + property frameimage_offset: imagenrty + read fi.ba.frameimage_offsets.offset + write setframeimage_offset default 0; + property frameimage_offset1: imagenrty + read fi.ba.frameimage_offsets.offset1 + write setframeimage_offset1 default 0; + property frameimage_offsetdisabled: imagenrty + read fi.ba.frameimage_offsets.disabled + write setframeimage_offsetdisabled default 0; + property frameimage_offsetmouse: imagenrty + read fi.ba.frameimage_offsets.mouse + write setframeimage_offsetmouse default 0; + property frameimage_offsetclicked: imagenrty + read fi.ba.frameimage_offsets.clicked + write setframeimage_offsetclicked default 0; + property frameimage_offsetactive: imagenrty + read fi.ba.frameimage_offsets.active + write setframeimage_offsetactive default 0; + property frameimage_offsetfocused: imagenrty + read fi.ba.frameimage_offsets.focused + write setframeimage_offsetfocused default 0; + property frameface_list: tfacelist read fi.ba.frameface_list + write setframeface_list; + property frameface_offset: facenrty + read fi.ba.frameface_offsets.offset + write setframeface_offset default 0; + property frameface_offset1: facenrty + read fi.ba.frameface_offsets.offset1 + write setframeface_offset1 default 0; + property frameface_offsetdisabled: facenrty + read fi.ba.frameface_offsets.disabled + write setframeface_offsetdisabled default 0; + property frameface_offsetmouse: facenrty + read fi.ba.frameface_offsets.mouse + write setframeface_offsetmouse default 0; + property frameface_offsetclicked: facenrty + read fi.ba.frameface_offsets.clicked + write setframeface_offsetclicked default 0; + property frameface_offsetactive: facenrty + read fi.ba.frameface_offsets.active + write setframeface_offsetactive default 0; + property frameface_offsetfocused: facenrty + read fi.ba.frameface_offsets.focused + write setframeface_offsetfocused default 0; + + //for tcaptionframe + property font: toptionalfont read getfont write setfont stored isfontstored; + //used in tmenu.itemframetemplate, itemframtemplateactive, + //tmainmenu.popupitemframetemplate, popupitemframetemplate also + property captiondist: integer read fi.capt.captiondist + write setcaptiondist default 0; //not used if font not set + property captionoffset: integer read fi.capt.captionoffset + write setcaptionoffset default 0; //not used if font not set + property fucusrectdist: int32 read fi.ba.focusrectdist + write setfocusrectdist default 0; + property extraspace: integer read fi.ba.extraspace + write setextraspace default 0; + property imagedist: integer read fi.ba.imagedist + write setimagedist default 0; + property imagedist1: integer read fi.ba.imagedist1 + write setimagedist1 default 0; + property imagedist2: integer read fi.ba.imagedist2 + write setimagedist2 default 0; + property colorclient: colorty read fi.ba.colorclient write setcolorclient + default cl_default; + property colordkshadow: colorty + read fi.ba.framecolors.edges.shadow.effectcolor + write setcolordkshadow default cl_default; + property colorshadow: colorty read fi.ba.framecolors.edges.shadow.color + write setcolorshadow default cl_default; + property colorlight: colorty read fi.ba.framecolors.edges.light.color + write setcolorlight default cl_default; + property colorhighlight: colorty + read fi.ba.framecolors.edges.light.effectcolor + write setcolorhighlight default cl_default; + property colordkwidth: integer + read fi.ba.framecolors.edges.shadow.effectwidth + write setcolordkwidth default -1; + property colorhlwidth: integer + read fi.ba.framecolors.edges.light.effectwidth + write setcolorhlwidth default -1; + property hiddenedges: edgesty read fi.ba.hiddenedges write sethiddenedges + default []; + property optionsskin: frameskinoptionsty read fi.ba.optionsskin + write setoptionsskin default []; + property optionsskincontroller: frameskincontrolleroptionsty + read foptionsskincontroller + write foptionsskincontroller default []; + property clientsizeextend_cx: int32 read fclientsizeextend.cx + write fclientsizeextend.cx default 0; + property clientsizeextend_cy: int32 read fclientsizeextend.cy + write fclientsizeextend.cy default 0; + property onbeforepaintbackground: beforeframepaintbackgroundeventty + read fonbeforepaintbackground write fonbeforepaintbackground; + property onafterpaintbackground: afterframepaintbackgroundeventty + read fonafterpaintbackground write fonafterpaintbackground; + property onbeforepaintoverlay: beforeframepaintoverlayeventty + read fonbeforepaintoverlay write fonbeforepaintoverlay; + property onafterpaintoverlay: afterframepaintoverlayeventty + read fonafterpaintoverlay write fonafterpaintoverlay; + + property onbeforetemplatepaintbackground: + beforeframetemplatepaintbackgroundeventty + read fonbeforetemplatepaintbackground + write fonbeforetemplatepaintbackground; + property onaftertemplatepaintbackground: + afterframetemplatepaintbackgroundeventty + read fonaftertemplatepaintbackground + write fonaftertemplatepaintbackground; + property onbeforetemplatepaintoverlay: + beforeframetemplatepaintoverlayeventty + read fonbeforetemplatepaintoverlay + write fonbeforetemplatepaintoverlay; + property onaftertemplatepaintoverlay: afterframetemplatepaintoverlayeventty + read fonaftertemplatepaintoverlay + write fonaftertemplatepaintoverlay; + + end; + + tframecomp = class(ttemplatecontainer) + private + function gettemplate: tframetemplate; + procedure settemplate(const Value: tframetemplate); + protected + function gettemplateclass: templateclassty; override; + public + published + property template: tframetemplate read gettemplate write settemplate; + end; + + tcustomface = class; + iface1 = interface(inullinterface) + function translatecolor(const acolor: colorty): colorty; + end; + iface = interface(iface1) + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + function getcomponentstate: tcomponentstate; + procedure widgetregioninvalid; + end; + + faceoptionty = (fao_alphafadeimage,fao_alphafadenochildren,fao_alphafadeall, + fao_alphaimage, + fao_fadeoverlay,fao_overlay); + faceoptionsty = set of faceoptionty; + + tfadecolorarrayprop = class(tcolorarrayprop) + public + constructor create; + end; + + tfadeopacolorarrayprop = class(tcolorarrayprop) + public + constructor create; + end; + + tfacebitmap = class(tmaskedbitmap) + private + fowner: tcustomface; + fpos: pointty; + procedure setx(const avalue: int32); + procedure sety(const avalue: int32); + procedure setpos(const avalue: pointty); + procedure setcenter(avalue: pointty); + function getcenter: pointty; + public + constructor create(const aowner: tcustomface); + //nil -> default + property pos: pointty read fpos write setpos; + property center: pointty read getcenter write setcenter; + published + property x: int32 read fpos.x write setx default 0; + property y: int32 read fpos.y write sety default 0; + end; + + faceinfoty = record + frameimage_offset: integer; + options: faceoptionsty; + framei: framety; + + frameimage_list: timagelist; //not copied by move + fade_direction: graphicdirectionty; + image: tfacebitmap; + fade_pos: trealarrayprop; + fade_color: tfadecolorarrayprop; + fade_opacity: colorty; + fade_opapos: trealarrayprop; + fade_opacolor: tfadeopacolorarrayprop; + end; + + + tfacecomp = class; + tcustomface = class(toptionalpersistent) + private + flocalprops: facelocalpropsty; + ftemplate: tfacecomp; + falphabuffer: tmaskedbitmap; + falphabufferdest: pointty; + procedure settemplateinfo(const ainfo: faceinfoty); + procedure setoptions(const avalue: faceoptionsty); + function isoptionsstored: boolean; + procedure setframei_left(const avalue: integer); + function isframei_leftstored(): boolean; + procedure setframei_top(const avalue: integer); + function isframei_topstored(): boolean; + procedure setframei_right(const avalue: integer); + function isframei_rightstored(): boolean; + procedure setframei_bottom(const avalue: integer); + function isframei_bottomstored(): boolean; + + procedure setimage(const value: tfacebitmap); + function isimagestored: boolean; + procedure setfade_color(const Value: tfadecolorarrayprop); + function isfacolorstored: boolean; + procedure setfade_pos(const Value: trealarrayprop); + function isfaposstored: boolean; + procedure setfade_direction(const Value: graphicdirectionty); + function isfadirectionstored: boolean; + procedure setfade_opacity(avalue: colorty); + function isfaopacitystored: boolean; + procedure setfade_opacolor(const Value: tfadeopacolorarrayprop); + function isfaopacolorstored: boolean; + procedure setfade_opapos(const Value: trealarrayprop); + function isfaopaposstored: boolean; + procedure setframeimage_list(const avalue: timagelist); + function isframeimage_liststored: boolean; + procedure setframeimage_offset(const avalue: integer); + function isframeimage_offsetstored: boolean; + procedure settemplate(const avalue: tfacecomp); + procedure setlocalprops(avalue: facelocalpropsty); + procedure readtransparency(reader: treader); + protected + fintf: iface; + fi: faceinfoty; + procedure dochange(const sender: tarrayprop; const index: integer); + procedure change; + procedure imagechanged(const sender: tobject); + procedure internalcreate; override; + procedure doalphablend(const canvas: tcanvas); + procedure defineproperties(filer: tfiler); override; + procedure internalpaint(const canvas: tcanvas; const arect: rectty); virtual; + public + constructor create; overload; override; + constructor create(const owner: twidget); reintroduce; overload; + //sets fowner.fframe + constructor create(const intf: iface); reintroduce; overload; + destructor destroy; override; + procedure checktemplate(const sender: tobject); + procedure assign(source: tpersistent); override; + procedure paint(const canvas: tcanvas; const arect: rectty); + property options: faceoptionsty read fi.options write setoptions + stored isoptionsstored default []; + property framei_left: integer read fi.framei.left write setframei_left + stored isframei_leftstored default 0; + property framei_top: integer read fi.framei.top write setframei_top + stored isframei_topstored default 0; + property framei_right: integer read fi.framei.right write setframei_right + stored isframei_rightstored default 0; + property framei_bottom: integer read fi.framei.bottom write setframei_bottom + stored isframei_bottomstored default 0; + + property image: tfacebitmap read fi.image write setimage + stored isimagestored; + property fade_pos: trealarrayprop read fi.fade_pos write setfade_pos + stored isfaposstored; + property fade_color: tfadecolorarrayprop read fi.fade_color + write setfade_color stored isfacolorstored; + property fade_direction: graphicdirectionty read fi.fade_direction + write setfade_direction + stored isfadirectionstored default gd_right ; + property fade_opacity: colorty read fi.fade_opacity + write setfade_opacity + stored isfaopacitystored default cl_none; + property fade_opapos: trealarrayprop read fi.fade_opapos + write setfade_opapos stored isfaopaposstored; + property fade_opacolor: tfadeopacolorarrayprop read fi.fade_opacolor + write setfade_opacolor stored isfaopacolorstored; + + property frameimage_list: timagelist read fi.frameimage_list + write setframeimage_list stored isframeimage_liststored; + //imagenr 0 = topleft, 1 = left, 2 = bottomleft, 3 = bottom, + // 4 = bottomright 5 = right, 6 = topright, 7 = top + property frameimage_offset: integer read fi.frameimage_offset + write setframeimage_offset + stored isframeimage_offsetstored default 0; + + property localprops: facelocalpropsty read flocalprops + write setlocalprops {default []}; + //before template + property template: tfacecomp read ftemplate write settemplate; + end; + + tface = class(tcustomface) + published + property options; + property image; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property fade_pos; + property fade_color; + property fade_opapos; + property fade_opacolor; + property fade_direction; + property fade_opacity; + property frameimage_list; + property frameimage_offset; + property localprops; //before template + property template; + end; + + tfacearrayprop = class(tpersistentarrayprop) + private + fintf: iface; + function getitems(const index: integer): tface; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aintf: iface); reintroduce; + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tface read getitems; default; + end; + + tfacelist = class(tmsecomponent,iface) + private + flist: tfacearrayprop; + findexlookup: msestring; + procedure setlist(const avalue: tfacearrayprop); + //iface + procedure invalidatewidget(); + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function translatecolor(const acolor: colorty): colorty; + function getclientrect: rectty; + function getcomponentstate: tcomponentstate; + procedure widgetregioninvalid; + procedure setindexlookup(const avalue: msestring); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure paint(const canvas: tcanvas; const aindex: int32; + const dest: rectty); + function lookup(const aindex: int32): int32; + published + property list: tfacearrayprop read flist write setlist; + property indexlookup: msestring read findexlookup write setindexlookup; + //array of int16 + end; + + beforefacepainteventty = procedure (const sender: tcustomface; + const canvas: tcanvas; const arect: rectty; + var handled: boolean) of object; + afterfacepainteventty = procedure (const sender: tcustomface; + const canvas: tcanvas; const arect: rectty) of object; + + tfacetemplate = class(tpersistenttemplate,iface1) + private + fi: faceinfoty; + fonbeforepaint: beforefacepainteventty; + fonafterpaint: afterfacepainteventty; + procedure setoptions(const avalue: faceoptionsty); + procedure setframei_left(const avalue: integer); + procedure setframei_top(const avalue: integer); + procedure setframei_right(const avalue: integer); + procedure setframei_bottom(const avalue: integer); + + procedure setfade_color(const Value: tfadecolorarrayprop); + procedure setfade_pos(const Value: trealarrayprop); + procedure setfade_opacolor(const Value: tfadeopacolorarrayprop); + procedure setfade_opapos(const Value: trealarrayprop); + procedure setfade_opacity(avalue: colorty); + procedure setfade_direction(const Value: graphicdirectionty); + procedure setimage(const Value: tfacebitmap); + procedure doimagechange(const sender: tobject); + procedure dochange(const sender: tarrayprop; const index: integer); + procedure setframeimage_list(const avalue: timagelist); + procedure setframeimage_offset(const avalue: integer); + procedure readtransparency(reader: treader); + protected + procedure doassignto(dest: tpersistent); override; + function getinfosize: integer; override; + function getinfoad: pointer; override; + procedure copyinfo(const source: tpersistenttemplate); override; + procedure internalcreate; override; + procedure defineproperties(filer: tfiler); override; + //iface1 + function translatecolor(const acolor: colorty): colorty; + public + constructor create(const owner: tmsecomponent; + const onchange: notifyeventty); override; + destructor destroy; override; + procedure paint(const canvas: tcanvas; const arect: rectty); + published + property options: faceoptionsty read fi.options write setoptions default []; + property framei_left: integer read fi.framei.left + write setframei_left default 0; + property framei_top: integer read fi.framei.top + write setframei_top default 0; + property framei_right: integer read fi.framei.right + write setframei_right default 0; + property framei_bottom: integer read fi.framei.bottom + write setframei_bottom default 0; + + property image: tfacebitmap read fi.image write setimage; + property fade_pos: trealarrayprop read fi.fade_pos write setfade_pos; + property fade_color: tfadecolorarrayprop read fi.fade_color + write setfade_color; + property fade_opapos: trealarrayprop read fi.fade_opapos + write setfade_opapos; + property fade_opacolor: tfadeopacolorarrayprop read fi.fade_opacolor + write setfade_opacolor; + property fade_direction: graphicdirectionty read fi.fade_direction + write setfade_direction default gd_right; + property fade_opacity: colorty read fi.fade_opacity + write setfade_opacity default cl_none; + + property frameimage_list: timagelist read fi.frameimage_list + write setframeimage_list; + //imagenr 0 = topleft, 1 = left, 2 = bottomleft, 3 = bottom, 4 = bottomright + //5 = right, 6 = topright, 7 = top + property frameimage_offset: integer read fi.frameimage_offset + write setframeimage_offset default 0; + property onbeforepaint: beforefacepainteventty read fonbeforepaint + write fonbeforepaint; + property onafterpaint: afterfacepainteventty read fonafterpaint + write fonafterpaint; + end; + + tfacecomp = class(ttemplatecontainer) + private + function gettemplate: tfacetemplate; + procedure settemplate(const Value: tfacetemplate); + protected + function gettemplateclass: templateclassty; override; + public + published + property template: tfacetemplate read gettemplate write settemplate; + end; + + mouseeventty = procedure (const sender: twidget; + var ainfo: mouseeventinfoty) of object; + mousewheeleventty = procedure (const sender: twidget; + var ainfo: mousewheeleventinfoty) of object; + keyeventty = procedure (const sender: twidget; + var ainfo: keyeventinfoty) of object; + shortcuteventty = procedure (const sender: twidget; var ainfo: keyeventinfoty; + const origin: twidget) of object; + painteventty = procedure (const sender: twidget; + const acanvas: tcanvas) of object; + pointeventty = procedure(const sender: twidget; + const apoint: pointty) of object; + widgeteventty = procedure(const sender: tobject; + const awidget: twidget) of object; + + widgetarty = array of twidget; + + twindow = class; + pwindow = ^twindow; + + windowinfoty = record + options: windowoptionsty; + initialwindowpos: windowposty; + transientfor: twindow; + groupleader: twindow; + icon,iconmask: pixmapty; + end; + + naviginfoty = record + sender: twidget; + direction: graphicdirectionty; + startingrect: rectty; + wraprect: rectty; + distance: integer; + nearest: twidget; + down: boolean; + hastarget: boolean; + end; + + twidgetfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + widgetfontclassty = class of twidgetfont; + + twidgetfontempty = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + widgetfontemptyclassty = class of twidgetfontempty; + + twidgetevent = class(tcomponentevent) + end; + + modallevelty = (ml_none,ml_application, //call eventloop + ml_window); //reflect window focus + + rootchangeflagty = (rcf_widgetregioninvalid,rcf_windowset,rcf_windowremove); + rootchangeflagsty = set of rootchangeflagty; + + widgetalignmodety = (wam_none,wam_start,wam_center,wam_end); + navigrequesteventty = procedure(const sender: twidget; + var ainfo: naviginfoty) of object; + twidget = class(tactcomponent,iscrollframe,iface,iassistiveclient) + private + fwidgetregion: gdiregionty; + frootpos: pointty; //position in rootwindow + fcursor: cursorshapety; + ftaborder: integer; + fminsize,fmaxsize: sizety; + fminclientsize: sizety; + fminscrollsize: sizety; + fminshrinksize: sizety; + ffocusedchild,ffocusedchildbefore: twidget; + ffontheight: integer; + fsetwidgetrectcount: integer; //for recursive setpos + fautosizelevel: byte; + + foptionsskin: optionsskinty; + fskingroup: integer; + fonnavigrequest: navigrequesteventty; + geframewidth: integer; + procedure invalidateparentminclientsize; + function getwidgets(const index: integer): twidget; + function dofindwidget(const awidgets: widgetarty; + aname: ansistring): twidget; + + procedure setpos(const Value: pointty); + procedure setsize(const Value: sizety); + procedure setbounds_x(const Value: integer); + procedure setbounds_y(const Value: integer); + procedure setbounds_cx(const Value: integer); + procedure setbounds_cy(const Value: integer); + procedure updatesizerange(value: integer; var dest: integer); overload; + procedure updatesizerange(const value: sizety; var dest: sizety); overload; + procedure setbounds_cxmax(const Value: integer); + procedure setbounds_cymax(const Value: integer); + procedure setbounds_cxmin(const Value: integer); + procedure setbounds_cymin(const Value: integer); + procedure setminsize(const avalue: sizety); + procedure setmaxsize(const avalue: sizety); + + procedure setcursor(const avalue: cursorshapety); + function getsize: sizety; + + function invalidateneeded: boolean; + procedure addopaquechildren(var region: gdiregionty); + procedure updatewidgetregion; + function isclientmouseevent(var info: mouseeventinfoty): boolean; + procedure internaldofocus; + procedure internaldodefocus; + procedure internaldoenter; + procedure internaldoexit; + procedure internaldoactivate; + procedure internaldodeactivate; + procedure internalkeydown(var info: keyeventinfoty); + + function clipcaret: rectty; //origin = pos + procedure reclipcaret; + procedure updatetaborder(awidget: twidget); + procedure settaborder(const Value: integer); + procedure parentfontchanged; + procedure setanchors(const Value: anchorsty); + + function getzorder: integer; + procedure setzorder(const value: integer); + + function getparentclientpos: pointty; + procedure setparentclientpos(const avalue: pointty); + + function getscreenpos: pointty; + procedure setscreenpos(const avalue: pointty); + + function getclientoffset: pointty; + function calcframewidth(arect: prectty): sizety; + + procedure readfontheight(reader: treader); + procedure writefontheight(writer: twriter); + procedure updatefontheight; + + procedure checkwidgetsize(var size: sizety); + //check size constraints + procedure setoptionsskin(const avalue: optionsskinty); + function getpaintsize: sizety; + procedure setpaintsize(const avalue: sizety); + function getframesize: sizety; + procedure setframesize(const avalue: sizety); + procedure setframewidth(const avalue: integer); + function getframeheight: integer; + procedure setframeheight(const avalue: integer); + function getpaintwidth: integer; + procedure setpaintwidth(const avalue: integer); + function getpaintheight: integer; + procedure setpaintheight(const avalue: integer); + protected + fwidgets: widgetarty; + fnoinvalidate: integer; + fwidgetupdating: integer; + foptionswidget: optionswidgetty; + foptionswidget1: optionswidget1ty; + fparentwidget: twidget; + fanchors: anchorsty; + fwidgetstate: widgetstatesty; + fwidgetstate1: widgetstates1ty; + fcolor: colorty; + fwindow: twindow; + fwidgetrect: rectty; + fparentclientsize: sizety; + fframe: tcustomframe; + fface: tcustomface; + ffont: twidgetfont; + ffontempty: twidgetfontempty; + fhint: msestring; + fdefaultfocuschild: twidget; + + procedure checksizes(); + function widgetminsize1: sizety; + //checks ws1_clientcxmin,ws1_clientcymin + function widgetmaxsize1: sizety; + //checks ws1_clientcxmin,ws1_clientcymin + function minclientsize: sizety; + function isdesignwidget(): boolean; virtual; + procedure setdesignwidget(); + //sets ws1_designwidget and removes ws_iswidget for self and children + procedure designmouseevent(var info: moeventinfoty; + capture: twidget); virtual; + procedure designkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); virtual; + + procedure defineproperties(filer: tfiler); override; + function gethelpcontext: msestring; override; + class function classskininfo: skininfoty; override; + function skininfo: skininfoty; override; + function hasskin: boolean; override; + + function navigstartrect: rectty; virtual; //origin = pos + function navigrect: rectty; virtual; //origin = pos + procedure navigrequest(var info: naviginfoty; + const nowrap: boolean = false); virtual; + function navigdistance(var info: naviginfoty; + const nowrap: boolean = false): integer; virtual; + + function nexttaborderoverride(const sender: twidget; + const down: boolean = false): twidget virtual; + + function getwidgetrects(const awidgets: array of twidget): rectarty; + procedure setwidgetrects(const awidgets: array of twidget; + const arects: rectarty); + + procedure updateroot; + procedure setcolor(const avalue: colorty); virtual; + function gethint: msestring; virtual; + procedure sethint(const Value: msestring); virtual; + function ishintstored: boolean; virtual; + function getshowhint: boolean; + procedure showhint(const aid: int32; var info: hintinfoty); virtual; + + function isgroupleader: boolean; virtual; + function needsfocuspaint: boolean; virtual; + function needsfocuspaintstate(): boolean; //checks ws_focused, ws_active + function getnoscroll(): boolean; virtual; + function getenabled: boolean; + procedure setenabled(const Value: boolean); virtual; + function getvisible: boolean; + procedure setvisible(const avalue: boolean); virtual; + function isvisible: boolean; //checks designing + function parentisvisible: boolean;//checks isvisible flags of ancestors + function parentvisible: boolean; //checks visible flags of ancestors + function updateopaque(const children: boolean; + const widgetregioncall: boolean): boolean; + //true if widgetregionchanged called + procedure dragstarted; virtual; //called by tapplication.dragstarted + //iscrollframe + function getzoomrefframe: framety; virtual; + //idragcontroller + function getdragrect(const apos: pointty): rectty; virtual; + //iface + procedure widgetregioninvalid; + //iframe + procedure setframeinstance(instance: tcustomframe); virtual; + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function getwidgetrect: rectty; + function getcomponentstate: tcomponentstate; + + function getframestateflags: framestateflagsty; virtual; + //igridcomp,itabwidget + function getwidget: twidget; + + function getframe: tcustomframe; + procedure setframe(const avalue: tcustomframe); + function getface: tcustomface; + procedure setface(const avalue: tcustomface); + + function getgdi: pgdifunctionaty; virtual; + procedure createwindow; virtual; + procedure objectchanged(const sender: tobject); virtual; + procedure objectevent(const sender: tobject; const event: objecteventty); override; + procedure receiveevent(const event: tobjectevent); override; + procedure setchildorder(child: tcomponent; order: integer); overload; override; + procedure setparentcomponent(value: tcomponent); override; + function clearparentwidget: twidget; + //returns old parentwidget + procedure setparentwidget(const Value: twidget); virtual; + procedure setlockedparentwidget(const avalue: twidget); + //sets ws_loadlock before setting, restores afterwards + procedure updatewindowinfo(var info: windowinfoty); virtual; + procedure windowcreated; virtual; + procedure setoptionswidget(const avalue: optionswidgetty); virtual; + procedure setoptionswidget1(const avalue: optionswidget1ty); virtual; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; + + procedure initparentclientsize; + function getcaretcliprect: rectty; virtual; //origin = clientrect.pos + procedure dobeginread; override; + procedure doendread; override; + procedure loaded; override; + procedure setdesigning(value: boolean; + setchildren : boolean = true); override; + + procedure updatemousestate(const info: mouseeventinfoty); virtual; + //updates fstate about mouseposition + procedure setclientclick; //grabs mouse and sets clickflags + procedure releasebuttonpressgrab(); + + procedure registerchildwidget(const child: twidget); virtual; + procedure unregisterchildwidget(const child: twidget); virtual; + function isfontstored: Boolean; + procedure setfont(const avalue: twidgetfont); + function getfont: twidgetfont; + function getfont1: twidgetfont; //no getoptionalobject + function isfontemptystored: Boolean; + procedure setfontempty(const avalue: twidgetfontempty); + function getfontempty: twidgetfontempty; + function getfontempty1: twidgetfontempty; //no getoptionalobject + function getframefont: tfont; + procedure fontchanged; virtual; + procedure fontcanvaschanged; virtual; + procedure updatecursorshape(apos: pointty){(force: boolean = false)}; + + procedure parentclientrectchanged; virtual; + procedure parentwidgetregionchanged(const sender: twidget); virtual; + procedure widgetregionchanged(const sender: twidget); virtual; + procedure scalebasechanged(const sender: twidget); virtual; //used by tlayouter + + {$ifdef mse_with_ifi} + procedure ifiwidgetstatechanged; + function getifiwidgetstate: ifiwidgetstatesty; virtual; + {$endif} + procedure cursorchanged; + procedure statechanged; virtual; //enabled,active,visible + // todo: + //use an universal state*changed() + //with state mask instead + procedure enabledchanged; virtual; + procedure activechanged; virtual; + procedure visiblepropchanged; virtual; + procedure visiblechanged; virtual; + procedure colorchanged; virtual; + procedure sizechanged; virtual; + procedure getautopaintsize(var asize: sizety); virtual; + procedure getautocellsize(const acanvas: tcanvas; + var asize: sizety); virtual; + procedure childclientrectchanged(const sender: twidget); virtual; + procedure childautosizechanged(const sender: twidget); virtual; + procedure poschanged; virtual; + procedure clientrectchanged; virtual; + procedure parentchanged; virtual; + procedure rootchanged(const aflags: rootchangeflagsty); virtual; + function getdefaultfocuschild: twidget; virtual; + //returns first focusable widget + procedure setdefaultfocuschild(const value: twidget); virtual; + function trycancelmodal(const newactive: twindow): boolean; virtual; + //called by twindow.internalactivate, true if accepted + procedure sortzorder; + + function needsdesignframe: boolean; virtual; + function getactface: tcustomface; virtual; + procedure dobeforepaint(const canvas: tcanvas); virtual; + procedure dopaint(const canvas: tcanvas); virtual; + procedure paintbackground(const canvas: tcanvas; + const arect: rectty); virtual; + procedure dopaintbackground(const canvas: tcanvas); virtual; + procedure doonpaintbackground(const canvas: tcanvas); virtual; + procedure dobeforepaintforeground(const canvas: tcanvas); virtual; + procedure dopaintforeground(const canvas: tcanvas); virtual; + procedure doonpaint(const canvas: tcanvas); virtual; + procedure paintoverlay(const canvas: tcanvas; + const arect: rectty); virtual; + procedure dopaintoverlay(const canvas: tcanvas); virtual; + procedure doafterpaint(const canvas: tcanvas); virtual; + + procedure doscroll(const dist: pointty); virtual; + procedure doscrolled(const dist: pointty); virtual; + + procedure doloaded() virtual; + procedure dohide() virtual; + procedure doshow() virtual; + procedure doactivate() virtual; + procedure doafteractivate() virtual; + procedure dodeactivate() virtual; + procedure doenter() virtual; + procedure doexit() virtual; + procedure dofocus() virtual; + procedure dodefocus() virtual; + procedure dochildfocused(const sender: twidget); virtual; + procedure dofocuschanged(const oldwidget,newwidget: twidget); virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty); virtual; + + function wantmousefocus(const info: mouseeventinfoty): boolean; + procedure reflectmouseevent(var info: mouseeventinfoty); + //posts mousevent to window under mouse + procedure mouseevent(var info: mouseeventinfoty); virtual; + procedure mousepreview(const sender: twidget; + var info: mouseeventinfoty); virtual; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); virtual; + procedure clientmouseevent(var info: mouseeventinfoty); virtual; + procedure mousewheelevent(var info: mousewheeleventinfoty); virtual; + + procedure dokeydown1(var info: keyeventinfoty); + //updates flags, calls dokeydown + procedure dokeydown(var info: keyeventinfoty); virtual; + //do not call dokeydown, call dokeydown1 + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); + virtual; + //called twice, first before dokeydown with es_preview set + function checkfocusshortcut(var info: keyeventinfoty): boolean; virtual; + procedure handlenavigkeys(var info: keyeventinfoty; + const nowrap: boolean = false); virtual; + procedure dokeydownaftershortcut(var info: keyeventinfoty); virtual; + procedure dokeyup(var info: keyeventinfoty); virtual; + + procedure dofontchanged(const sender: tobject); + procedure setfontheight; + procedure postchildscaled; + function verticalfontheightdelta: boolean; virtual; + procedure dofontheightdelta(var delta: integer); virtual; + procedure syncsinglelinefontheight(const lineheight: boolean = false; + const space: integer = 2); + + procedure setwidgetrect(const Value: rectty); + procedure internalsetwidgetrect(Value: rectty; + const windowevent: boolean); virtual; + function getclientpos: pointty; + function getclientsize: sizety; + procedure setclientsize(const asize: sizety); virtual; + //used in tscrollingwidget + function getclientwidth: integer; + procedure setclientwidth(const avalue: integer); + function getclientheight: integer; + procedure setclientheight(const avalue: integer); + function internalshow(const modallevel: modallevelty; + const transientfor: pwindow; //follow linkedvar state + const windowevent,nomodalforreset: boolean): modalresultty; virtual; + procedure internalhide(const windowevent: boolean); + function checksubfocus(const aactivate: boolean): boolean; virtual; + function getnextfocus: twidget; + function cantabfocus: boolean; + function getdisprect: rectty; virtual; + //origin pos, clamped in view by activate + + function getshrinkpriority: integer; virtual; //default 0 + procedure tryshrink(const aclientsize: sizety); virtual; + function calcminscrollsize: sizety; virtual; + function getminshrinkpos: pointty; virtual; + function calcminshrinksize: sizety; virtual; + function getcontainer: twidget; virtual; + function getchildwidgets(const index: integer): twidget; virtual; + + function getright: integer; //if placed in datamodule + procedure setright(const avalue: integer); + function getbottom: integer; + procedure setbottom(const avalue: integer); + function ownswindow1: boolean; //does not check winid + + procedure internalcreateframe; virtual; + procedure internalcreateface; virtual; + function getfontclass: widgetfontclassty; virtual; + function getfontemptyclass: widgetfontemptyclassty; virtual; + procedure internalcreatefont; virtual; + procedure internalcreatefontempty; virtual; + + function getclientrect: rectty; + function windowpo: pwindowty; + function canclose1: boolean; + + function getiassistiveclient(): iassistiveclient virtual; + //iassistiveclient + function getassistiveparent(): iassistiveclient virtual; + function getassistivewidget(): tobject virtual; + function getassistivename(): msestring virtual; + function getassistivecaption(): msestring virtual; + function getassistivetext(): msestring virtual; + function getassistivecaretindex(): int32 virtual; + function getassistivehint(): msestring virtual; + function getassistiveflags(): assistiveflagsty virtual; + {$ifdef mse_with_ifi} + function getifidatalinkintf(): iifidatalink virtual; + {$endif} + public + constructor create(aowner: tcomponent); overload; override; + constructor create(const aowner: tcomponent; + const aparentwidget: twidget); overload; + constructor create(const aowner: tcomponent; + const aparentwidget: twidget; + const aiswidget: boolean{ = true}); overload; + //uses setlockedparentwidget + constructor createandinit(const aowner: tcomponent; + const aparentwidget: twidget; + const aiswidget: boolean); overload; + //uses setlockedparentwidget + destructor destroy; override; + procedure afterconstruction; override; + procedure initnewcomponent(const ascale: real); override; + //called before inserting in parentwidget + procedure initnewwidget(const ascale: real); virtual; + //called after inserting in parentwidget + procedure createframe; + procedure createface; + procedure createfont; + procedure createfontempty; + procedure checkautosize(); + procedure updatehotkeys() virtual; + + function isloading: boolean; //checks ws_loadlock and csdestroing too + procedure beginupdate; //sets ws_loadlock and noinvalidate + procedure endupdate; + function canmouseinteract: boolean; //checks csdesigning and cssubcomponent + function canassistive(): boolean virtual; + function widgetstate: widgetstatesty; //iframe + property widgetstate1: widgetstates1ty read fwidgetstate1; + function hasparent: boolean; override; //tcomponent + function getparentcomponent: tcomponent; override; //tcomponent + function hascaret: boolean; + function canwindow: boolean; + //true if twindow allocated or not rootwidget destroying + function windowallocated: boolean; + //true if winid allocated and not loading and not destroying + function ownswindow: boolean; + //true if valid toplevelwindow with assigned winid + function updaterect: rectty; //invalidated area, origin = clientpos + + procedure beforeclosequery(var amodalresult: modalresultty); virtual; + //called on top level window + function canclose(const newfocus: twidget = nil): boolean; virtual; + function canparentclose(const newfocus: twidget): boolean; overload; + //window.focusedwidget is first checked if it is descendant + function forceclose: boolean; //newfocus=nil, sets ws1_forceclose, true if ok + function canparentclose: boolean; overload; + //newfocus = window.focusedwidget + function canfocus: boolean; virtual; + function setfocus(aactivate: boolean = true): boolean; virtual;//true if ok + procedure parentfocus; //sets focus to self or focusable parent + procedure nextfocus; //sets inputfocus to then next appropriate widget + function findtabfocus(const ataborder: integer): twidget; + //nil if can not focus + function firsttabfocus: twidget; + function lasttabfocus: twidget; + function nexttaborder(const down: boolean = false; + nowrap: boolean = false): twidget; + function focusback(const aactivate: boolean = true): boolean; virtual; + //false if focus not changed + + function parentcolor: colorty; + function actualcolor: colorty; virtual; + function actualopaquecolor: colorty; virtual; + function backgroundcolor: colorty; + function translatecolor(const acolor: colorty): colorty; + + procedure widgetevent(const event: twidgetevent); virtual; + procedure sendwidgetevent(const event: twidgetevent); + //event will be destroyed + + procedure release(const nomodaldefer: boolean=false); override; + function show(const modallevel: modallevelty; + const transientfor: twindow = nil): modalresultty; + overload; virtual; + function show(const modallevel: modallevelty; + const transientfor: twidget): modalresultty; overload; + function show(const modal: boolean = false; + const transientfor: twindow = nil): modalresultty; overload; + procedure endmodal; + procedure hide; + procedure activate(const abringtofront: boolean = true; + const aforce: boolean = false); virtual; + //show and setfocus + procedure bringtofront; + procedure sendtoback; + procedure stackunder(const predecessor: twidget); + procedure setchildorder(const achildren: widgetarty); overload; + //last is top, nil items ignored + + procedure paint(const canvas: tcanvas); virtual; + procedure update; virtual; + procedure scrollwidgets(const dist: pointty); + procedure scrollrect(const dist: pointty; const rect: rectty; + scrollcaret: boolean); //origin = paintrect.pos + procedure scroll(const dist: pointty); + //scrolls paintrect and widgets + procedure clampinview(const arect: rectty; + const bottomright: boolean = false); virtual; + //origin paintpos + + procedure getcaret; + procedure scrollcaret(const dist: pointty); + function mousecaptured: boolean; + function capturemouse(grab: boolean = true): boolean; + //true for new grab + procedure releasemouse(const grab: boolean = false); + function capturekeyboard: boolean; //true for new grab + procedure releasekeyboard; + procedure synctofontheight; virtual; + + procedure dragevent(var info: draginfoty); virtual; + procedure dolayout(const sender: twidget); virtual; + + procedure invalidatewidget; //invalidates whole widget + procedure invalidate; //invalidates clientrect + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + procedure invalidateframestate; + procedure invalidateframestaterect(const rect: rectty; + const aframe: tcustomframe; const org: originty = org_client); + function hasoverlappingsiblings(arect: rectty): boolean; //origin = pos + + function window: twindow; + function rootwidget: twidget; + function parentofcontainer: twidget; + //parentwidget.parentwidget if parentwidget has not ws_iswidget, + //parentwidget otherwise + property parentwidget: twidget read fparentwidget write setparentwidget; + function getrootwidgetpath: widgetarty; //root widget is last + function widgetcount: integer; + function parentwidgetindex: integer; + //index in parentwidget.widgets, -1 if none + function indexofwidget(const awidget: twidget): integer; + function checkdescendent(awidget: twidget): boolean; + //true if widget is descendent or self + function checkancestor(awidget: twidget): boolean; + //true if widget is ancestor or self + function containswidget(awidget: twidget): boolean; + + property widgets[const index: integer]: twidget read getwidgets; + function widgetatpos(var info: widgetatposinfoty): twidget; overload; + function widgetatpos(const pos: pointty): twidget; overload; + function widgetatpos(const pos: pointty; + const state: widgetstatesty): twidget; overload; + + property container: twidget read getcontainer; + function containeroffset: pointty; + function childrencount: integer; virtual; + function visiblechildrencount: integer; + property children[const index: integer]: twidget read getchildwidgets; + default; + //children of container + function findtagchild(const atag: integer; + const aclass: widgetclassty): twidget; + //returns first matching descendent + function findchild(const aname: ansistring): twidget; + //searches in container.widgets, case insensitive + function childatpos(const pos: pointty; + const clientorigin: boolean = true): twidget; virtual; + function gettaborderedwidgets: widgetarty; + function getvisiblewidgets: widgetarty; + function getcornerwidget(const side: graphicdirectionty; + const visibleonly: boolean): twidget; + function getsortxchildren(const banded: boolean = false): widgetarty; + //banded -> row,column order + function getsortychildren(const banded: boolean = false): widgetarty; + //banded -> column,row order + function getlogicalchildren: widgetarty; virtual; //children of container + procedure addlogicalchildren(var achildren: widgetarty); + function findlogicalchild(const aname: ansistring): twidget; + //case insensitive + + property focusedchild: twidget read ffocusedchild; + property focusedchildbefore: twidget read ffocusedchildbefore; + function enteredchild(): twidget; + + function mouseeventwidget(const info: mouseeventinfoty): twidget; + + procedure insertwidget(const awidget: twidget); overload; + procedure insertwidget(const awidget: twidget; + const apos: pointty); overload; virtual; + //widget can be child + + function iswidgetclick(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventtype = et_butonrelease, button is mb_left, + // clicked and pos in clientrect or in frame.caption if caption = true, + // origin = pos + function iswidgetdblclick(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventtype = et_butonrelease, button is mb_left, + // clicked and pos in clientrect or in frame.caption if caption = true, + // and timedlay to last buttonpress is short + // origin = pos + function iswidgetdblclicked(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventkind = ek_buttonrelease, button is mb_left, + // and pos in clientrect or in frame.caption if caption = true + // and timedelay to last buttonrelease is short + // origin = pos + function isclick(const info: mouseeventinfoty): boolean; + //true if eventkind = ek_buttonrelease, button is mb_left, + // clicked and pos in clientrect + function isdblclick(const info: mouseeventinfoty): boolean; + //true if eventtype = ek_buttonpress, button is mb_left, pos in clientrect + // and timedelay to last buttonpress is short + // origin = paintrect.pos + function isdblclicked(const info: mouseeventinfoty): boolean; + //true if eventkind in [ek_buttonpress,ek_buttonrelease], button is mb_left, + // and timedelay to last same buttonevent is short + function isleftbuttondown(const info: mouseeventinfoty): boolean; overload; + //true if eventkind = ek_buttonpress, button is mb_left, pos in clientrect + // origin = paintrect.pos + function isleftbuttondown(const info: mouseeventinfoty; + const akeyshiftstate: shiftstatesty): boolean; overload; + + function widgetmousepos(const ainfo: mouseeventinfoty): pointty; + //translates to widgetpos if necessary + + function rootpos: pointty; + function rootwidgetrect: rectty; + property screenpos: pointty read getscreenpos write setscreenpos; + + function clientpostowidgetpos(const apos: pointty): pointty; + function widgetpostoclientpos(const apos: pointty): pointty; + function widgetpostopaintpos(const apos: pointty): pointty; + function paintpostowidgetpos(const apos: pointty): pointty; + procedure scale(const ascale: real); virtual; + + property widgetrect: rectty read fwidgetrect write setwidgetrect; + function widgetscreenrect: rectty; //screen origin + function widgetclientrect: rectty; //origin = clientrect.pos + + property pos: pointty read fwidgetrect.pos write setpos; + property size: sizety read fwidgetrect.size write setsize; + property minsize: sizety read fminsize write setminsize; + function widgetminsize: sizety; + //calls checkwidgetsize and frame.checkwidgetsize + //checks ws1_clientcxmin,ws1_clientcymin + function widgetmaxsize: sizety; + //calls checkwidgetsize and frame.checkwidgetsize + //checks ws1_clientcxmin,ws1_clientcymin + + property maxsize: sizety read fmaxsize write setmaxsize; + function maxclientsize: sizety; virtual; + function minscrollsize: sizety; //uses cache + function minshrinksize: sizety; //uses cache + property bounds_x: integer read fwidgetrect.x write setbounds_x; + property bounds_y: integer read fwidgetrect.y write setbounds_y; + property bounds_cx: integer read fwidgetrect.cx write setbounds_cx + {default defaultwidgetwidth} stored true; + property bounds_cy: integer read fwidgetrect.cy write setbounds_cy + {default defaultwidgetheight} stored true; + property bounds_cxmin: integer read fminsize.cx + write setbounds_cxmin default 0; + property bounds_cymin: integer read fminsize.cy + write setbounds_cymin default 0; + property bounds_cxmax: integer read fmaxsize.cx + write setbounds_cxmax default 0; + property bounds_cymax: integer read fmaxsize.cy + write setbounds_cymax default 0; + + property left: integer read fwidgetrect.x write setbounds_x; + property right: integer read getright write setright; + //widgetrect.x + widgetrect.cx, sets cx if an_left is set + property top: integer read fwidgetrect.y write setbounds_y; + property bottom: integer read getbottom write setbottom; + //widgetrect.y + widgetrect.cy, sets cy if an_top is set + property width: integer read fwidgetrect.cx write setbounds_cx; + property height: integer read fwidgetrect.cy write setbounds_cy; + + procedure setclippedwidgetrect(arect: rectty); + //clips into parentwidget or workarea if no parentwidget + + property anchors: anchorsty read fanchors write setanchors + default defaultanchors; + property defaultfocuschild: twidget read getdefaultfocuschild + write setdefaultfocuschild; + + function framedim: sizety; //widgetrect.size - paintrect.size + function framedimnoscrollbar: sizety; + function clientframewidth: sizety; //widgetrect.size - clientrect.size + function innerclientframewidth: sizety; + //widgetrect.size - innerclientrect.size + function innerframewidth: sizety; + //clientrect.size - innerclientrect.size + function framerect: rectty; //origin = pos + function framepos: pointty; //origin = pos + property framesize: sizety read getframesize write setframesize; + //widget size - outer frame + property framewidth: integer read geframewidth write setframewidth; + property frameheight: integer read getframeheight write setframeheight; + function frameinnerrect: rectty; //origin = pos + + function paintrect: rectty; //origin = pos + function paintclientrect: rectty; //origin = clientrect + function paintpos: pointty; //origin = pos + property paintsize: sizety read getpaintsize write setpaintsize; + property paintwidth: integer read getpaintwidth write setpaintwidth; + property paintheight: integer read getpaintheight write setpaintheight; + function clippedpaintrect: rectty; //origin = pos, + //clipped by all parentpaintrects + function innerpaintrect: rectty; //origin = pos + + procedure setanchordwidgetsize(const asize: sizety); + //checks bottom-right anchors + function widgetsizerect: rectty; //pos = nullpoint + function paintsizerect: rectty; //pos = nullpoint + function clientsizerect: rectty; //pos = nullpoint + function containerclientsizerect: rectty; //pos = nullpoint + + property clientrect: rectty read getclientrect; //origin = paintrect.pos + procedure changeclientsize(const delta: sizety); //asynchronous + property clientsize: sizety read getclientsize write setclientsize; + property clientwidth: integer read getclientwidth write setclientwidth; + property clientheight: integer read getclientheight write setclientheight; + property clientpos: pointty read getclientpos; //origin = paintrect.pos; + function clientwidgetrect: rectty; //origin = pos + function clientwidgetpos: pointty; //origin = pos + function clientparentpos: pointty; //origin = parentwidget.pos + property parentclientpos: pointty read getparentclientpos + write setparentclientpos; + //origin = parentwidget.clientpos + function paintparentrect: rectty; //origin = parentwidget.pos + function paintparentpos: pointty; //origin = parentwidget.pos + function parentpaintpos: pointty; //origin = parentwidget.paintpos + //nullpoint if parent = nil + function refpos(const aorigin: originty): pointty; + + function paintrectparent: rectty; //origin = paintpos, + //nullrect if parent = nil, + function clientrectparent: rectty; //origin = paintpos, + //nullrect if parent = nil, + function innerparentrect: rectty; //origin = parentwidget.pos + function innerwidgetrect: rectty; //origin = pos + function innerclientrect: rectty; //origin = clientpos + function innerclientsize: sizety; + function innerclientpos: pointty; //origin = clientpos + function innerclientframe: framety; + function innerclientpaintpos: pointty; //origin = paintpos + function innerclientwidgetpos: pointty; //origin = pos + procedure innertopaintsize(var asize: sizety); + procedure outertopaintsize(var asize: sizety); + procedure painttowidgetsize(var asize: sizety); + procedure widgettopaintsize(var asize: sizety); + + property frame: tcustomframe read getframe write setframe; + property face: tcustomface read getface write setface; + + function getcanvas(aorigin: originty = org_client): tcanvas; + function showing: boolean; + //true if self and all ancestors visible and window allocated + function isenabled: boolean; + //true if self and all ancestors enabled + + function active: boolean; + function entered: boolean; + function activeentered: boolean; + //true if entered and window is regularactivewindow or inactivated + function activefocused(): boolean; + function focused: boolean; + function clicked: boolean; + + procedure changedirection(const avalue: graphicdirectionty; + var dest: graphicdirectionty); virtual; + procedure placexorder(const startx: integer; const dist: array of integer; + const awidgets: array of twidget; + const endmargin: integer = minint); + //origin = clientpos, endmargin by size adjust of widgets + //with [an_left,an_right], minint -> no change + procedure placeyorder(const starty: integer; const dist: array of integer; + const awidgets: array of twidget; + const endmargin: integer = minint); + //origin = clientpos, endmargin by size adjust of widgets + //with [an_top,an_bottom], minint -> no change + function alignx(const mode: widgetalignmodety; + const awidgets: array of twidget; + const glue: widgetalignmodety = wam_none; + const margin: integer = 0): integer; + //returns reference point, margin reference = clientrect + function aligny(const mode: widgetalignmodety; + const awidgets: array of twidget; + const glue: widgetalignmodety = wam_none; + const margin: integer = 0): integer; + //returns reference point, margin reference = clientrect + property optionswidget: optionswidgetty read foptionswidget + write setoptionswidget default defaultoptionswidget; + property optionswidget1: optionswidget1ty read foptionswidget1 + write setoptionswidget1 default defaultoptionswidget1; + property optionsskin: optionsskinty read foptionsskin + write setoptionsskin default []; + function actualcursor(const apos: pointty): cursorshapety; virtual; + //origin = pos + property cursor: cursorshapety read fcursor write setcursor + default cr_default; + property color: colorty read fcolor write setcolor + default defaultwidgetcolor; + property visible: boolean read getvisible write setvisible default true; + property enabled: boolean read getenabled write setenabled default true; + property taborder: integer read ftaborder write settaborder default 0; + property hint: msestring read gethint write sethint stored ishintstored; + property zorder: integer read getzorder write setzorder; + published + property onnavigrequest: navigrequesteventty read fonnavigrequest + write fonnavigrequest; + property skingroup: integer read fskingroup write fskingroup default 0; + property onbeforeupdateskin; + property onafterupdateskin; + end; + pwidget = ^twidget; + + windowstatety = (tws_posvalid,tws_sizevalid,tws_windowvisible, + tws_focusoutpending,tws_windowshowpending, + {tws_modal,}tws_modalfor,tws_modalcalling, + tws_needsdefaultpos, + tws_closing,tws_painting,tws_activating, + tws_globalshortcuts,tws_localshortcuts, + tws_buttonendmodal, + tws_grouphidden,tws_groupminimized,tws_groupmaximized, + tws_transientforminimized, + tws_grab,tws_activatelocked, + tws_canvasoverride,tws_destroying,tws_candefocus, + tws_raise,tws_lower); + windowstatesty = set of windowstatety; + + pmodalinfoty = ^modalinfoty; + modalinfoty = record + modalend: boolean; + modalwindowbefore: twindow; + level: integer; + parent: pmodalinfoty; + events: eventarty; //deferred events + end; + showinfoty = record + widget: twidget; + transientfor: twindow; + windowevent,nomodalforreset: boolean + end; + pshowinfoty = ^showinfoty; + + twindowevent = class(tmseevent) + private + public + fwinid: winidty; + constructor create(akind: eventkindty; winid: winidty); + end; + pwindowevent = ^twindowevent; + treparentevent = class(twindowevent) + public + fparent: winidty; + constructor create(akind: eventkindty; winid: winidty; + aparent: winidty); + end; + + twindow = class(teventobject,icanvas) + private + ffocuscount: longword; //for recursive setwidgetfocus + factivecount: longword; //for recursive activate,deactivate + factivating: integer; + ffocusing: integer; + fsizeerrorcount: integer; + fmoving: integer; + ffocusedwidget: twidget; + fenteredwidget: twidget; + fcaller: twidget; //used in twidget.doshortcut + fmodalinfopo: pmodalinfoty; + foptions: windowoptionsty; + ftransientfor: twindow; + ftransientforcount: integer; + fwindowpos: windowposty; + fwindowposbefore: windowposty; + fnormalwindowrect: rectty; + fcaption: msestring; + fscrollnotifylist: tnotifylist; + fsyscontainer: syswindowty; + fmodalwidget: twidget; + fmodallevel: integer; + fsysdragobject: tobject; //tsysmimedragobject; + + fopacity: realty; + procedure setcaption(const avalue: msestring); + procedure widgetdestroyed(widget: twidget); + + procedure showed; + procedure hidden; + procedure activated; + procedure deactivated; + procedure wmconfigured(const arect: rectty; const aorigin: pointty); + procedure windowdestroyed; + + function internalupdate: boolean; + //updates screen representation, false if nothing is painted + procedure deactivate; + function canactivate: boolean; + //icanvas + procedure gcneeded(const sender: tcanvas); +// function getmonochrome: boolean; + function getkind: bitmapkindty; + function getsize: sizety; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + + procedure checkrecursivetransientfor(const value: twindow); + procedure settransientfor(const Value: twindow; const windowevent: boolean); + procedure sizeconstraintschanged; + procedure setsizeconstraints(const amin,amax: sizety); + procedure createwindow; + procedure checkwindowid; + procedure checkwindow(windowevent: boolean); + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); virtual; + //nil if from application + procedure show(windowevent: boolean); + procedure hide(windowevent: boolean); + procedure setfocusedwidget(const widget: twidget); + procedure setmodalresult(const Value: modalresultty); + function getglobalshortcuts: boolean; + function getlocalshortcuts: boolean; + procedure setglobalshortcuts(const Value: boolean); + procedure setlocalshortcuts(const Value: boolean); + function getbuttonendmodal: boolean; + procedure setbuttonendmodal(const value: boolean); + + function getdecoratedwidgetrect: rectty; + procedure setdecoratedwidgetrect(const avalue: rectty); + function getdecoratedpos: pointty; + procedure setdecoratedpos(const avalue: pointty); + function getdecoratedsize: sizety; + procedure setdecoratedsize(const avalue: sizety); + function getdecoratedbounds_x: integer; + procedure setdecoratedbounds_x(const avalue: integer); + function getdecoratedbounds_y: integer; + procedure setdecoratedbounds_y(const avalue: integer); + function getdecoratedbounds_cx: integer; + procedure setdecoratedbounds_cx(const avalue: integer); + function getdecoratedbounds_cy: integer; + procedure setdecoratedbounds_cy(const avalue: integer); + procedure setcontainer(const avalue: winidty); + procedure containerwindestroyed(const aid: winidty); + procedure setsyscontainer(const avalue: syswindowty); + function getscreenpos: pointty; + procedure setscreenpos(const avalue: pointty); + function getmodalfor: boolean; + procedure setopacity(const avalue: realty); + protected + fstate: windowstatesty; + fgdi: pgdifunctionaty; + fwindow: windowty; + fcontainer: winidty; + fownerwidget: twidget; + fcanvas: tcanvas; + fasynccanvas: tcanvas; + fmodalresult: modalresultty; + fupdateregion: gdiregionty; + procedure setasynccanvas(const acanvas: tcanvas); + //used from treport + procedure releaseasynccanvas; + procedure processsysdnd(const event: twindowevent); //tsysdndevent + + function getwindowsize: windowsizety; + procedure setwindowsize(const value: windowsizety); + function getwindowpos: windowposty; + procedure setwindowpos(const Value: windowposty); + procedure invalidaterect(const arect: rectty; const sender: twidget = nil); + //clipped by paintrect of sender.parentwidget + procedure mouseparked; + procedure movewindowrect(const dist: pointty; const rect: rectty); virtual; + procedure checkmousewidget(const info: mouseeventinfoty; + var capture: twidget); + procedure dispatchmouseevent(var info: moeventinfoty; + capture: twidget); virtual; + procedure dispatchkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); virtual; + procedure sizechanged; virtual; + procedure poschanged; virtual; + procedure internalactivate(const windowevent: boolean; + const force: boolean = false); + procedure noactivewidget; + procedure lockactivate; + procedure unlockactivate; + procedure setzorder(const value: integer); + function topmodaltransientfor: twindow; + function beginmodal(const showinfo: pshowinfoty): boolean; overload; + //true if window destroyed + public + constructor create(const aowner: twidget; const agdi: pgdifunctionaty = nil); + //nil = platform default + destructor destroy; override; + procedure destroywindow; + procedure recreatewindow(); + procedure registeronscroll(const method: notifyeventty); + procedure unregisteronscroll(const method: notifyeventty); + + function beginmodal: boolean; overload;//true if window destroyed + procedure endmodal; + function modal: boolean; + function modalwindowbefore: twindow; + function transientforstackactive: boolean; + //true if the window is member of the active transient for stack + procedure activate(const force: boolean = false); + function active: boolean; + function deactivateintermediate: boolean; + //true if ok, sets app.finactivewindow + procedure reactivate(const force: boolean = false); + //clears app.finactivewindow + procedure update; + function candefocus: boolean; + procedure nofocus; + property focuscount: longword read ffocuscount; + function close: boolean; overload; //true if ok + function close(const amodalresult: modalresultty): boolean; + overload;//true if ok + procedure beginmoving; //lock window rect modification + procedure endmoving; + procedure bringtofront; + procedure bringtofrontlocal; + procedure sendtoback; + procedure sendtobacklocal; + procedure stackunder(const predecessor: twindow); + //stacking is performed in mainloop idle, nil means top + procedure stackover(const predecessor: twindow); + //stacking is performed in mainloop idle, nil means bottom + function stackedunder(const avisible: boolean = false): twindow; //nil if top + function stackedover(const avisible: boolean = false): twindow; + //nil if bottom + function hastransientfor: boolean; + function istransientfor(const base: twindow): boolean; + //base can be nil + function defaulttransientfor: twindow; + + function capturemouse: boolean; //true for new grab + procedure releasemouse; + function mousecaptured: boolean; + + procedure postkeyevent(const akey: keyty; + const ashiftstate: shiftstatesty = []; const release: boolean = false; + const achars: msestring = ''); + + function winid: winidty; + function haswinid: boolean; + function state: windowstatesty; + function visible: boolean; + function activating: boolean; //in internalactivate proc + function normalwindowrect: rectty; + property updateregion: regionty read fupdateregion.region; + function updaterect: rectty; + + procedure registermovenotification(sender: iobjectlink); + procedure unregistermovenotification(sender: iobjectlink); + + property options: windowoptionsty read foptions; + function ispopup: boolean; {$ifdef FPC}inline;{$endif} + property owner: twidget read fownerwidget; + property focusedwidget: twidget read ffocusedwidget; + function firstfocuswidget(): twidget; + function lastfocuswidget(): twidget; + property transientfor: twindow read ftransientfor; + property modalfor: boolean read getmodalfor; + property modalresult: modalresultty read fmodalresult write setmodalresult; + property buttonendmodal: boolean read getbuttonendmodal write setbuttonendmodal; + property globalshortcuts: boolean read getglobalshortcuts write setglobalshortcuts; + property localshortcuts: boolean read getlocalshortcuts write setlocalshortcuts; + property windowpos: windowposty read getwindowpos write setwindowpos; + property caption: msestring read fcaption write setcaption; + property container: winidty read fcontainer + write setcontainer default 0; + property syscontainer: syswindowty read fsyscontainer + write setsyscontainer default sywi_none; + + property screenpos: pointty read getscreenpos write setscreenpos; + property decoratedwidgetrect: rectty read getdecoratedwidgetrect + write setdecoratedwidgetrect; + property decoratedpos: pointty read getdecoratedpos + write setdecoratedpos; + property decoratedsize: sizety read getdecoratedsize + write setdecoratedsize; + property decoratedbounds_x: integer read getdecoratedbounds_x + write setdecoratedbounds_x; + property decoratedbounds_y: integer read getdecoratedbounds_y + write setdecoratedbounds_y; + property decoratedbounds_cx: integer read getdecoratedbounds_cx + write setdecoratedbounds_cx; + property decoratedbounds_cy: integer read getdecoratedbounds_cy + write setdecoratedbounds_cy; + property opacity: realty read fopacity write setopacity; + //default emptyreal -> undefined + end; + + windowarty = array of twindow; + pwindowarty = ^windowarty; + windowaty = array[0..0] of twindow; + pwindowaty = ^windowaty; + + windowchangeeventty = procedure(const oldwindow,newwindow: twindow) of object; + widgetchangeeventty = procedure(const oldwidget,newwidget: twidget) of object; + windoweventty = procedure(const awindow: twindow) of object; + winideventty = procedure(const awinid: winidty) of object; + booleaneventty = procedure(const avalue: boolean) of object; + + twindowrectevent = class(twindowevent) + private + public + frect: rectty; + forigin: pointty; + constructor create(akind: eventkindty; winid: winidty; + const rect: rectty; const aorigin: pointty); + end; + + tmouseevent = class(twindowevent) + private + ftimestamp: longword; + public + fpos: pointty; + fbutton: mousebuttonty; + fwheel: mousewheelty; + fshiftstate: shiftstatesty; + freflected: boolean; + property timestamp: longword read ftimestamp; //usec, 0 -> invalid + constructor create(const winid: winidty; const release: boolean; + const button: mousebuttonty; const wheel: mousewheelty; + const pos: pointty; const shiftstate: shiftstatesty; + atimestamp: longword; const reflected: boolean = false); + //button = none for mousemove + end; + + tmouseenterevent = class(tmouseevent) + public + constructor create(const winid: winidty; const pos: pointty; + const shiftstate: shiftstatesty; atimestamp: longword); + end; + + tkeyevent = class(twindowevent) + private + ftimestamp: longword; + public + fkey: keyty; + fkeynomod: keyty; + fchars: msestring; + fbutton: mousebuttonty; + fshiftstate: shiftstatesty; + fposted: boolean; + constructor create(const winid: winidty; const release: boolean; + const key,keynomod: keyty; const shiftstate: shiftstatesty; + const chars: msestring; const atimestamp: longword; + const posted: boolean = false); + //do not dispatch if active window is not winid + property timestamp: longword read ftimestamp; //usec + end; + + tresizeevent = class(tobjectevent) + public + size: sizety; + constructor create(const dest: ievent; const asize: sizety); + end; + + tguiapplication = class; + waitidleeventty = procedure(const sender: tguiapplication; var again: boolean) + of object; + helpeventty = procedure(const sender: tmsecomponent; + var handled: boolean) of object; + + syseventhandlereventty = procedure(const awindow: winidty; + var aevent: syseventty; var handled: boolean) of object; + + keyinfoty = record + key: keyty; + keynomod: keyty; + shiftstate: shiftstatesty; + end; + + guiappoptionty = (gao_forcezorder); + guiappoptionsty = set of guiappoptionty; + + keyinfoarty = array of keyinfoty; + tguiapplication = class(tcustomapplication) + private + fwindows: windowarty; + fwindowupdateindex: integer; + fgroupzorder: windowarty; + factivewindow: twindow; + flastactivewindow: twindow; + fwantedactivewindow: twindow; //set by twindow.activate if modal + finactivewindow: twindow; + ffocuslockwindow: twindow; + ffocuslocktransientfor: twindow; + fmouse: tmouse; + fcaret: tcaret; + fmousecapturewidget: twidget; + fmousewidget: twidget; + fmousewidgetpos: pointty; //last mousepos sent to widget + fmousehintwidget: twidget; + fkeyboardcapturewidget: twidget; + fclientmousewidget: twidget; + fhintedwidget: twidget; + fhintedid: int32; + fhintforwidget: twidget; + fhintinfo: hintinfoty; + fmainwindow: twindow; + fdblclicktime: integer; + fcursorshape: cursorshapety; + fwidgetcursorshape: cursorshapety; + fbuttonpresswidgetbefore: twidget; + fbuttonreleasewidgetbefore: twidget; + factmousewindow: twindow; + fdelayedmouseshift: pointty; + fmodalwindowbeforewaitdialog: twindow; + fonterminatebefore: threadcompeventty; + fexecuteaction: notifyeventty; + fidleaction: waitidleeventty; + feventlooping: integer; + fkeyhistory: keyinfoarty; + flastshiftstate: shiftstatesty; + flastkey: keyty; + flastbutton: mousebuttonty; + fkeyeventinfo: pkeyeventinfoty; + fmouseeventinfo: pmouseeventinfoty; + fmousewheeleventinfo: pmousewheeleventinfoty; + + fmousewheelfrequmin: real; + fmousewheelfrequmax: real; + fmousewheeldeltamin: real; + fmousewheeldeltamax: real; + fmousewheelaccelerationmax: real; + flastinputtimestamp: longword; + flastmousewheeltimestamp: longword; + flastmousewheeltimestampbefore: longword; + + fcurrmodalinfo: pmodalinfoty; + flooplevel: integer; + + fmousewheelsensitivity: real; + fhintwidgetclass: widgetclassty; + procedure invalidated; + function grabpointer(const aid: winidty): boolean; + function ungrabpointer: boolean; + procedure setmousewidget(const widget: twidget); + procedure setclientmousewidget(const widget: twidget; const apos: pointty); + procedure capturemouse(const sender: twidget; const grab: boolean); + //sender = nil for release + procedure activatehint; + procedure deactivatehint; + procedure hinttimer(const sender: tobject); + procedure internalshowhint(const sender: twidget; + const ahintwidget: twidget); + procedure setmainwindow(const Value: twindow); + procedure setcursorshape(const avalue: cursorshapety); + procedure setwidgetcursorshape(const avalue: cursorshapety); + function getwindows(const index: integer): twindow; + procedure dothreadterminated(const sender: tthreadcomp); + procedure dowaitidle(var again: boolean); + procedure dowaitidle1(var again: boolean); + function getforcezorder: boolean; + procedure setforcezorder(const avalue: boolean); + protected + flastshowmenuwidget: twidget; + foptionsgui: guiappoptionsty; + fgdilockcount: int32; + procedure sysevent(const awindow: winidty; var aevent: syseventty; + var handled: boolean); + procedure sethighrestimer(const avalue: boolean); override; + procedure dopostevent(const aevent: tmseevent); override; + procedure eventloop(const once: boolean = false); + //used in win32 wm_queryendsession and wm_entersizemove + procedure exitloop; //used in win32 cancelshutdown + procedure receiveevent(const event: tobjectevent); override; + procedure doafterrun; override; + procedure internalinitialize; override; + procedure internaldeinitialize; override; +// procedure dobeginthreadlock; override; +// procedure doendthreadlock; override; + procedure objecteventdestroyed(const sender: tobjectevent); override; + procedure dragstarted; //calls dragstarted of all known widgets + procedure internalpackwindowzorder(); virtual; + procedure zorderinvalid(); + public + constructor create(aowner: tcomponent); override; + procedure destroyforms; + property optionsgui: guiappoptionsty read foptionsgui + write foptionsgui default []; + property forcezorder: boolean read getforcezorder write setforcezorder; + procedure langchanged; override; + procedure settimer(const us: integer); override; + function findwindow(aid: winidty; out window: twindow): boolean; + procedure checkwindowrect(winid: winidty; var rect: rectty); + //callback from win32 wm_sizing + + function createform(instanceclass: widgetclassty; var reference): twidget; + procedure invalidate; //invalidates all registered forms + procedure processmessages; override; //handle with care! + function idle: boolean; override; + function modallevel: integer; override; + + function unlockall: integer override; + procedure relockall(count: integer) override; + procedure beginnoignorewaitevents; + procedure endnoignorewaitevents; + procedure beginwait(const aprocessmessages: boolean = false); override; + procedure endwait; override; + function waiting: boolean; + function waitescaped: boolean; override; + //true if escape pressed while waiting + + procedure resetwaitdialog; + function waitdialog(const athread: tthreadcomp = nil; const atext: msestring = ''; + const caption: msestring = ''; + const acancelaction: notifyeventty = nil; + const aexecuteaction: notifyeventty = nil; + const aidleaction: waitidleeventty = nil; + const acontinueaction: notifyeventty = nil): boolean; + //true if not canceled + procedure terminatewait; + procedure cancelwait; + function waitstarted: boolean; + function waitcanceled: boolean; + function waitterminated: boolean; + + procedure showexception(e: exception; const leadingtext: msestring = ''); override; + procedure showasyncexception(e: exception; const leadingtext: msestring = ''); + //messege posted in queue + procedure errormessage(const amessage: msestring); override; + + property hintwidgetclass: widgetclassty read fhintwidgetclass + write fhintwidgetclass; + procedure inithintinfo(var info: hintinfoty; const ahintedwidget: twidget); + //hint at mousepos + procedure initwidgethintinfo(var info: hintinfoty; + const ahintedwidget: twidget); + //hint at widgetrect + procedure showhint(const sender: twidget; const hint: msestring; + const aposrect: rectty; const aplacement: captionposty = cp_bottomleft; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags); + procedure showhint(const sender: twidget; const hint: msestring; + const apos: pointty; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags); + procedure showhint(const sender: twidget; const info: hintinfoty); + procedure showhint(const sender: twidget; const hint: msestring); + procedure showhint(const sender: twidget; const hintwidget: twidget; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags); + procedure hidehint; + procedure restarthint(const sender: twidget); + function hintedwidget: twidget; //last hinted widget + function activehintedwidget: twidget; //nil if no hint active + + procedure help(const sender: tmsecomponent); + procedure registerhelphandler(const ahandler: helpeventty); + procedure unregisterhelphandler(const ahandler: helpeventty); + function activehelpcontext: msestring; + //returns helpcontext of active widget, '' if none; + function mousehelpcontext: msestring; + //returns helpcontext of mouse widget, '' if none; + + function active: boolean; + procedure activate(); + function screenrect(const awindow: twindow = nil): rectty; + //nil -> virtualscreeen + function workarea(const awindow: twindow = nil): rectty; + //nil -> current active window + function ppmm(const awindow: twindow = nil): complexty; + //nil -> current active window, pixel per mm, + //result.re -> horizontal + //result.im -> vertical + property activewindow: twindow read factivewindow; + property lastactivewindow: twindow read flastactivewindow; + property inactivewindow: twindow read finactivewindow; + function normalactivewindow: twindow; + //active window or active window after closing modal stack if defined + function regularactivewindow: twindow; //first no transientfor window + function unreleasedactivewindow: twindow; + function activewidget: twidget; + function activerootwidget: twidget; + property lastshowmenuwidget: twidget read flastshowmenuwidget; + + function windowatpos(const pos: pointty): twindow; + function findwidget(const namepath: string; out awidget: twidget): boolean; + //false if invalid namepath, '' -> nil and true + procedure sortzorder(); + //window list is ordered by z, bottom first, top last, + //invisibles first + procedure packwindowzorder(); + + function windowar: windowarty; + function winidar: winidarty; + function windowcount: integer; + property windows[const index: integer]: twindow read getwindows; + function bottomwindow: twindow; + //lowest visible window in stackorder, calls sortzorder + function topwindow: twindow; + //highest visible window in stackorder, calls sortzorder + function candefocus(const caller: tobject = nil): boolean; override; + //checks candefocus of all windows expect caller + + procedure registeronkeypress(const method: keyeventty); + procedure unregisteronkeypress(const method: keyeventty); + procedure registeronshortcut(const method: keyeventty); + procedure unregisteronshortcut(const method: keyeventty); + procedure registeronwidgetactivechanged(const method: widgetchangeeventty); + procedure unregisteronwidgetactivechanged(const method: widgetchangeeventty); + procedure registeronwindowactivechanged(const method: windowchangeeventty); + procedure unregisteronwindowactivechanged(const method: windowchangeeventty); + procedure registeronwindowdestroyed(const method: windoweventty); + procedure unregisteronwindowdestroyed(const method: windoweventty); + procedure registeronwiniddestroyed(const method: winideventty); + procedure unregisteronwiniddestroyed(const method: winideventty); + procedure registeronapplicationactivechanged(const method: booleaneventty); + procedure unregisteronapplicationactivechanged(const method: booleaneventty); + procedure registersyseventhandler(const method: syseventhandlereventty); + procedure unregistersyseventhandler(const method: syseventhandlereventty); + + function terminate(const sender: twindow = nil): boolean; + //calls canclose of all windows except sender and terminatequery + //true if terminated + function terminating: boolean; + function deinitializing: boolean; + function shortcutting: boolean; //widget is in doshortcut procedure + property caret: tcaret read fcaret; + property mouse: tmouse read fmouse; + procedure mouseparkevent; //simulates mouseparkevent + procedure delayedmouseshift(const ashift: pointty); + procedure calcmousewheeldelta(var info: mousewheeleventinfoty; + const fmin,fmax,deltamin,deltamax: real); + function mousewheelacceleration(const avalue: real): real; overload; + function mousewheelacceleration(const avalue: integer): integer; overload; + procedure clearkeyhistory; //called by matching shortcut sequence + property keyhistory: keyinfoarty read fkeyhistory; + //does not contain modifier keys + property lastinputtimestamp: longword read flastinputtimestamp; + //microseconds + property lastshiftstate: shiftstatesty read flastshiftstate; + property lastkey: keyty read flastkey; + property lastbutton: mousebuttonty read flastbutton; + property mouseeventinfo: pmouseeventinfoty read fmouseeventinfo; + //nil if no mouse event processing + property mousewheeleventinfo: pmousewheeleventinfoty + read fmousewheeleventinfo; + //nil if no mousewheel event processing + property keyeventinfo: pkeyeventinfoty read fkeyeventinfo; + //nil if no key event processing + + property cursorshape: cursorshapety read fcursorshape write setcursorshape; + //persistent + property widgetcursorshape: cursorshapety read fwidgetcursorshape write + setwidgetcursorshape; + //removed by mouse widget change + procedure updatecursorshape; //restores cursorshape of mousewidget + property mousewidget: twidget read fmousewidget; + property clientmousewidget: twidget read fclientmousewidget; + property mousecapturewidget: twidget read fmousecapturewidget; + property keyboardcapturewidget: twidget read fkeyboardcapturewidget; + property mainwindow: twindow read fmainwindow write setmainwindow; + property thread: threadty read fthread; + + property buttonpresswidgetbefore: twidget read fbuttonpresswidgetbefore; + property buttonreleasewidgetbefore: twidget read fbuttonreleasewidgetbefore; + property dblclicktime: integer read fdblclicktime write fdblclicktime default + defaultdblclicktime; //us + property mousewheelsensitivity: real read fmousewheelsensitivity + write fmousewheelsensitivity; + property mousewheelfrequmin: real read fmousewheelfrequmin + write fmousewheelfrequmin; + property mousewheelfrequmax: real read fmousewheelfrequmax + write fmousewheelfrequmax; + property mousewheeldeltamin: real read fmousewheeldeltamin + write fmousewheeldeltamin; + property mousewheeldeltamax: real read fmousewheeldeltamax + write fmousewheeldeltamax; + property mousewheelaccelerationmax: real read fmousewheelaccelerationmax + write fmousewheelaccelerationmax; + end; + +function translatewidgetpoint(const point: pointty; + const source,dest: twidget): pointty; +procedure translatewidgetpoint1(var point: pointty; + const source,dest: twidget); +function translatewidgetrect(const rect: rectty; + const source,dest: twidget): rectty; + //translates from source widget to dest widget, to screen if dest = nil + //source = nil -> screen +function translatepaintpoint(const point: pointty; + const source,dest: twidget): pointty; +procedure translatepaintpoint1(var point: pointty; + const source,dest: twidget); +function translatepaintrect(const rect: rectty; + const source,dest: twidget): rectty; + //translates from source widget to dest widget, to screen if dest = nil + //source = nil -> screen +function translatewidgettopaintpoint(const point: pointty; + const source,dest: twidget): pointty; +procedure translatewidgettopaintpoint1(var point: pointty; + const source,dest: twidget); +function translatewidgettopaintrect(const rect: rectty; + const source,dest: twidget): rectty; + //translates from source widget to dest widget, to screen if dest = nil + //source = nil -> screen +function translateclientpoint(const point: pointty; + const source,dest: twidget): pointty; +procedure translateclientpoint1(var point: pointty; + const source,dest: twidget); +function translateclientrect(const rect: rectty; + const source,dest: twidget): rectty; + //translates from source client to dest client, to screen if dest = nil + //source = nil -> screen + +procedure sortwidgetsxorder(var awidgets: widgetarty; const parent: twidget = nil); +procedure sortwidgetsyorder(var awidgets: widgetarty; const parent: twidget = nil); + +procedure syncmaxautosize(const widgets: array of twidget); + //checks osk_nolayoutcx, osk_nolayoutcy +procedure syncpaintwidth(const awidgets: array of twidget; + const awidgetwidth: integer = -1); + //biggest if < 0 + //synchronizes paintwidth with paintwidth of largest outer framewidth + //(ex. largest caption) +procedure syncpaintheight(const awidgets: array of twidget; + const awidgetheight: integer = -1); + //biggest if < 0 + //synchronizes paintheight with paintheight of largest outer framewidth + //(ex. largest caption) + +function checkshortcut(var info: keyeventinfoty; + const caption: msestring; const checkalt: boolean): boolean; overload; +function checkshortcut(var info: keyeventinfoty; + const key: keyty; const shiftstate: shiftstatesty): boolean; overload; + +type + getwidgetintegerty = function(const awidget: twidget): integer; + getwidgetbooleanty = function(const awidget: twidget): boolean; + setwidgetintegerty = procedure(const awidget: twidget; const avalue: integer); + widgetaccessty = record + pos,size,stop,min,max,opos,osize,ostop,omin,omax: getwidgetintegerty; + setpos,setsize,setanchordsize,setstop,setmin,setmax, + setopos,setosize,setostop,setomin,setomax: setwidgetintegerty; + anchstop,oanchstop,anchboth,oanchboth: getwidgetbooleanty; + end; + pwidgetaccessty = ^widgetaccessty; + +function wbounds_x(const awidget: twidget): integer; +procedure wsetbounds_x(const awidget: twidget; const avalue: integer); +function wbounds_y(const awidget: twidget): integer; +procedure wsetbounds_y(const awidget: twidget; const avalue: integer); +function wbounds_cx(const awidget: twidget): integer; +procedure wsetbounds_cx(const awidget: twidget; const avalue: integer); +procedure wsetanchord_cx(const awidget: twidget; const avalue: integer); +function wbounds_cy(const awidget: twidget): integer; +procedure wsetbounds_cy(const awidget: twidget; const avalue: integer); +procedure wsetanchord_cy(const awidget: twidget; const avalue: integer); +function wstopx(const awidget: twidget): integer; +procedure wsetstopx(const awidget: twidget; const avalue: integer); +function wstopy(const awidget: twidget): integer; +procedure wsetstopy(const awidget: twidget; const avalue: integer); +function wanchstopx(const awidget: twidget): boolean; +function wanchstopy(const awidget: twidget): boolean; +function wanchbothx(const awidget: twidget): boolean; +function wanchbothy(const awidget: twidget): boolean; + +function wbounds_cxmin(const awidget: twidget): integer; +procedure wsetbounds_cxmin(const awidget: twidget; const avalue: integer); +function wbounds_cymin(const awidget: twidget): integer; +procedure wsetbounds_cymin(const awidget: twidget; const avalue: integer); +function wbounds_cxmax(const awidget: twidget): integer; +procedure wsetbounds_cxmax(const awidget: twidget; const avalue: integer); +function wbounds_cymax(const awidget: twidget): integer; +procedure wsetbounds_cymax(const awidget: twidget; const avalue: integer); + +const + widgetaccessx: widgetaccessty = ( + pos: {$ifdef FPC}@{$endif}wbounds_x; + size: {$ifdef FPC}@{$endif}wbounds_cx; + stop: {$ifdef FPC}@{$endif}wstopx; + min: {$ifdef FPC}@{$endif}wbounds_cxmin; + max: {$ifdef FPC}@{$endif}wbounds_cxmax; + opos: {$ifdef FPC}@{$endif}wbounds_y; + osize: {$ifdef FPC}@{$endif}wbounds_cy; + ostop: {$ifdef FPC}@{$endif}wstopy; + omin: {$ifdef FPC}@{$endif}wbounds_cymin; + omax: {$ifdef FPC}@{$endif}wbounds_cymax; + setpos: {$ifdef FPC}@{$endif}wsetbounds_x; + setsize: {$ifdef FPC}@{$endif}wsetbounds_cx; + setanchordsize: {$ifdef FPC}@{$endif}wsetanchord_cx; + setstop: {$ifdef FPC}@{$endif}wsetstopx; + setmin: {$ifdef FPC}@{$endif}wsetbounds_cxmin; + setmax: {$ifdef FPC}@{$endif}wsetbounds_cxmax; + setopos: {$ifdef FPC}@{$endif}wsetbounds_y; + setosize: {$ifdef FPC}@{$endif}wsetbounds_cy; + setostop: {$ifdef FPC}@{$endif}wsetstopy; + setomin: {$ifdef FPC}@{$endif}wsetbounds_cymin; + setomax: {$ifdef FPC}@{$endif}wsetbounds_cymax; + anchstop: {$ifdef FPC}@{$endif}wanchstopx; + oanchstop: {$ifdef FPC}@{$endif}wanchstopy; + anchboth: {$ifdef FPC}@{$endif}wanchbothx; + oanchboth: {$ifdef FPC}@{$endif}wanchbothy; + ); + widgetaccessy: widgetaccessty = ( + pos: {$ifdef FPC}@{$endif}wbounds_y; + size: {$ifdef FPC}@{$endif}wbounds_cy; + stop: {$ifdef FPC}@{$endif}wstopy; + min: {$ifdef FPC}@{$endif}wbounds_cymin; + max: {$ifdef FPC}@{$endif}wbounds_cymax; + opos: {$ifdef FPC}@{$endif}wbounds_x; + osize: {$ifdef FPC}@{$endif}wbounds_cx; + ostop: {$ifdef FPC}@{$endif}wstopx; + omin: {$ifdef FPC}@{$endif}wbounds_cxmin; + omax: {$ifdef FPC}@{$endif}wbounds_cxmax; + setpos: {$ifdef FPC}@{$endif}wsetbounds_y; + setsize: {$ifdef FPC}@{$endif}wsetbounds_cy; + setanchordsize: {$ifdef FPC}@{$endif}wsetanchord_cy; + setstop: {$ifdef FPC}@{$endif}wsetstopy; + setmin: {$ifdef FPC}@{$endif}wsetbounds_cymin; + setmax: {$ifdef FPC}@{$endif}wsetbounds_cymax; + setopos: {$ifdef FPC}@{$endif}wsetbounds_x; + setosize: {$ifdef FPC}@{$endif}wsetbounds_cx; + setostop: {$ifdef FPC}@{$endif}wsetstopx; + setomin: {$ifdef FPC}@{$endif}wsetbounds_cxmin; + setomax: {$ifdef FPC}@{$endif}wsetbounds_cxmax; + anchstop: {$ifdef FPC}@{$endif}wanchstopy; + oanchstop: {$ifdef FPC}@{$endif}wanchstopx; + anchboth: {$ifdef FPC}@{$endif}wanchbothy; + oanchboth: {$ifdef FPC}@{$endif}wanchbothx; + ); + +function application: tguiapplication; +function mousebuttontoshiftstate(button: mousebuttonty): shiftstatesty; +function isenterkey(const awidget: twidget; const key: keyty): boolean; +function isdblclick(const ainfo: mouseeventinfoty; + const abutton: mousebuttonty = mb_left): boolean; +function eatdblclick(var ainfo: mouseeventinfoty; + const abutton: mousebuttonty = mb_left): boolean; +function simulatemodalresult(const awidget: twidget; + const amodres: modalresultty): boolean; + +procedure beep; +procedure guibeep; +procedure enablewidgets(awidgets: array of twidget); +procedure disablewidgets(awidgets: array of twidget); +procedure showwidgets(awidgets: array of twidget); +procedure hidewidgets(awidgets: array of twidget); +function showmodalwidget(const aclass: widgetclassty): modalresultty; + +function getiassistiveclient(const awidget: twidget): iassistiveclient; + +procedure writewidgetnames(const writer: twriter; const ar: widgetarty); +function needswidgetnamewriting(const ar: widgetarty): boolean; overload; +function needswidgetnamewriting(const ar1,ar2: widgetarty): boolean; overload; + +procedure designeventloop; + +function getprocesswindow(const procid: integer): winidty; +function activateprocesswindow(const procid: integer; + const araise: boolean = true): boolean; + //true if ok +function combineframestateflags(const disabled,focused,active, + mouse,clicked: boolean): framestateflagsty; +function combineframestateflags( + const astate: shapestatesty): framestateflagsty; + +{$ifdef mse_debug} +procedure debugwindow(const atext: string; const awindow: twindow); +procedure debugwindow(const atext: string; const aid: winidty); +function debugwindow1(const atext: string; const aid: winidty): string; +procedure debugwindow(const atext: string; const aid1,aid2: winidty); +function checkwindowname(const aid: winidty; const aname: string): boolean; +function debugwidgetname(const awidget: twidget; const atext: string): string; +{$endif} + +implementation +uses + msesysintf,typinfo,msestreaming,msetimer,msebits,msewidgets, + mseshapes,msestockobjects,msefileutils,msedatalist,Math,msesysutils, + rtlconsts,{$ifndef FPC}classes_del,{$endif}mseformatstr, + mseprocutils,msesys,msesysdnd,mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + faceoptionsmask1: faceoptionsty = [fao_alphafadeimage,fao_alphafadenochildren, + fao_alphafadeall]; + faceoptionsmask2: faceoptionsty = [fao_alphaimage,fao_alphafadeimage]; +type + tcanvas1 = class(tcanvas); + tfadecolorarrayprop1 = class(tfadecolorarrayprop); + trealarrayprop1 = class(trealarrayprop); + tcaret1 = class(tcaret); + tobjectevent1 = class(tobjectevent); + tsysmimedragobject1 = class(tsysmimedragobject); + timagelist1 = class(timagelist); + +const + cancelwaittag = 823757; +type + tasyncmessageevent = class(tuserevent) + private + fmessage: msestring; + fcaption: msestring; + public + constructor create(const amessage: msestring; const acaption: msestring); + end; + + twidgetshowevent = class(tsynchronizeevent) + private + fwidget: twidget; + fmodalresult: modalresultty; + fmodallevel: modallevelty; + ftransientfor: twindow; + protected + procedure execute; override; + end; + + tcreatewindowevent = class(tsynchronizeevent) + private + fsender: twindow; + frect: rectty; + foptionspo: pinternalwindowoptionsty; + fwindowpo: pwindowty; + protected + procedure execute; override; + end; + + tdestroywindowevent = class(tsynchronizeevent) + private + fwindowpo: pwindowty; + protected + procedure execute; override; + end; + + tonkeyeventlist = class(tmethodlist) + protected + procedure dokeyevent(const sender: twidget; var info: keyeventinfoty); + end; + + tonwidgetchangelist = class(tmethodlist) + protected + procedure dowidgetchange(const oldwidget,newwidget: twidget); + end; + + tonwindowchangelist = class(tmethodlist) + protected + procedure dowindowchange(const oldwindow,newwindow: twindow); + end; + + tonwindoweventlist = class(tmethodlist) + protected + procedure doevent(const awindow: twindow); + end; + + tonwinideventlist = class(tmethodlist) + protected + procedure doevent(const awinid: winidty); + end; + + tonapplicationactivechangedlist = class(tmethodlist) + protected + procedure doevent(const activated: boolean); + end; + + tonhelpeventlist = class(tmethodlist) + protected + procedure doevent(const sender: tmsecomponent); + end; + + tonsyseventlist = class(tmethodlist) + protected + procedure doevent(const awindow: winidty; var aevent: syseventty; + var handled: boolean); + end; + + windowstackinfoty = record + lower,upper: twindow; + level: integer; + recursion: boolean; + end; + windowstackinfoarty = array of windowstackinfoty; + +const + keyhistorylen = 10; + +type + tinternalapplication = class(tguiapplication,imouse) + //avoid circular interface references + private + fonkeypresslist: tonkeyeventlist; + fonshortcutlist: tonkeyeventlist; + fonwidgetactivechangelist: tonwidgetchangelist; + fonwindowactivechangelist: tonwindowchangelist; + fonwindowdestroyedlist: tonwindoweventlist; + fonwiniddestroyedlist: tonwinideventlist; + fonapplicationactivechangedlist: tonapplicationactivechangedlist; + fonhelp: tonhelpeventlist; + fonsyseventlist: tonsyseventlist; + + fcaretwidget: twidget; + fmousewinid: winidty; + fdesigning: boolean; + fmodalwindow: twindow; + flockupdatewindowstack: twindow; + fhintwidget: twidget;//thintwidget; + fhinttimer: tsimpletimer; + fmouseparktimer: tsimpletimer; + fmouseparkeventinfo: mouseeventinfoty; + ftimestampbefore: longword; + flastbuttonpress: mousebuttonty; + flastbuttonpresstimestamp: longword; + flastbuttonrelease: mousebuttonty; + flastbuttonreleasetimestamp: longword; + fdoublemousepress,fdoublemouserelease: boolean; + fwindowstack: windowstackinfoarty; + ftimertick: boolean; + + procedure twindowdestroyed(const sender: twindow); + procedure windowdestroyed(aid: winidty); + procedure setwindowfocus(winid: winidty); + procedure unsetwindowfocus(winid: winidty); + procedure registerwindow(awindow: twindow); + procedure unregisterwindow(awindow: twindow); + procedure widgetdestroyed(const widget: twidget); + + procedure processexposeevent(event: twindowrectevent); + procedure processconfigureevent(event: twindowrectevent); + procedure processshowingevent(event: twindowevent); + procedure processmouseevent(event: tmouseevent); + procedure processkeyevent(event: tkeyevent); + procedure processleavewindow; + procedure processwindowcrossingevent(event: twindowevent); + + function getmousewinid: winidty; //for tmouse.setshape + procedure waitevent; + //application must be locked + procedure checkactivewindow; + function focusinpending: boolean; + procedure checkapplicationactive; + function winiddestroyed(const aid: winidty): boolean; + procedure eventloop(const once: boolean = false); + function beginmodal(const sender: twindow; + const showinfo: pshowinfoty): boolean; + //true if modalwindow destroyed + procedure endmodal(const sender: twindow); + procedure stackunder(const sender: twindow; const predecessor: twindow); + procedure stackover(const sender: twindow; const predecessor: twindow); + procedure checkwindowstack; + procedure updatewindowstack; + //reorders windowstack by ow_background,ow_top + procedure checkcursorshape; + + procedure mouseparktimer(const sender: tobject); + procedure removewindowevents(const awindow: winidty; + const aeventkind: eventkindty); + protected + procedure internalpackwindowzorder(); override; + function getevents: integer; override; + //application must be locked + //returns count of queued events + procedure dopostevent(const aevent: tmseevent); override; + procedure flushmousemove; + procedure doterminate(const shutdown: boolean); + procedure checkshortcut(const sender: twindow; const awidget: twidget; + var info: keyeventinfoty); + procedure doeventloop(const once: boolean); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + end; + +var + appinst: tinternalapplication; + +function combineframestateflags( + const disabled,focused,active,mouse,clicked: boolean): framestateflagsty; +begin + result:= []; + if disabled then include(result,fsf_disabled); + if focused then include(result,fsf_focused); + if active then include(result,fsf_active); + if mouse then include(result,fsf_mouse); + if clicked then include(result,fsf_clicked); +end; + +function combineframestateflags( + const astate: shapestatesty): framestateflagsty; +begin + result:= []; + if shs_disabled in astate then begin + include(result,fsf_disabled); + end; + if shs_focused in astate then begin + include(result,fsf_focused); + end; + if shs_active in astate then begin + include(result,fsf_active); + end; + if shs_mouse in astate then begin + include(result,fsf_mouse); + end; + if shs_clicked in astate then begin + include(result,fsf_clicked); + end; +end; + +function wbounds_x(const awidget: twidget): integer; +begin + result:= awidget.fwidgetrect.x; +end; + +procedure wsetbounds_x(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_x:= avalue; +end; + +function wbounds_cx(const awidget: twidget): integer; +begin + result:= awidget.fwidgetrect.cx; +end; + +procedure wsetbounds_cx(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cx:= avalue; +end; + +procedure wsetanchord_cx(const awidget: twidget; const avalue: integer); +begin + if not wanchbothx(awidget) then begin + awidget.setanchordwidgetsize(ms(avalue,awidget.bounds_cy)); + end; +end; + +function wbounds_y(const awidget: twidget): integer; +begin + result:= awidget.fwidgetrect.y; +end; + +procedure wsetbounds_y(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_y:= avalue; +end; + +function wbounds_cy(const awidget: twidget): integer; +begin + result:= awidget.fwidgetrect.cy; +end; + +procedure wsetanchord_cy(const awidget: twidget; const avalue: integer); +begin + if not wanchbothy(awidget) then begin + awidget.setanchordwidgetsize(ms(awidget.bounds_cx,avalue)); + end; +end; + +procedure wsetbounds_cy(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cy:= avalue; +end; + +function wstopx(const awidget: twidget): integer; +begin + result:= awidget.bounds_x + awidget.bounds_cx; +end; + +procedure wsetstopx(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cx:= avalue - awidget.bounds_x; +end; + +function wstopy(const awidget: twidget): integer; +begin + result:= awidget.bounds_y + awidget.bounds_cy; +end; + +procedure wsetstopy(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cy:= avalue - awidget.bounds_y; +end; + +function wanchstopx(const awidget: twidget): boolean; +begin + result:= an_right in awidget.anchors; +end; + +function wanchstopy(const awidget: twidget): boolean; +begin + result:= an_bottom in awidget.anchors; +end; + +function wanchbothx(const awidget: twidget): boolean; +var + an1: anchorsty; +begin + an1:= [an_left,an_right] * awidget.anchors; + result:= (an1 = []) or (an1 = [an_left,an_right]); +end; + +function wanchbothy(const awidget: twidget): boolean; +var + an1: anchorsty; +begin + an1:= [an_top,an_bottom] * awidget.anchors; + result:= (an1 = []) or (an1 = [an_top,an_bottom]); +end; + +function wbounds_cxmin(const awidget: twidget): integer; +begin + result:= awidget.fminsize.cx; +end; + +procedure wsetbounds_cxmin(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cxmin:= avalue; +end; + +function wbounds_cymin(const awidget: twidget): integer; +begin + result:= awidget.fminsize.cy; +end; + +procedure wsetbounds_cymin(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cymin:= avalue; +end; + +function wbounds_cxmax(const awidget: twidget): integer; +begin + result:= awidget.fmaxsize.cx; +end; + +procedure wsetbounds_cxmax(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cxmax:= avalue; +end; + +function wbounds_cymax(const awidget: twidget): integer; +begin + result:= awidget.fmaxsize.cy; +end; + +procedure wsetbounds_cymax(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cymax:= avalue; +end; + +function checkshortcut(var info: keyeventinfoty; const caption: msestring; + const checkalt: boolean): boolean; +begin + with info do begin + if (eventstate * [es_processed,es_modal,es_preview] = []) and + (not checkalt and (shiftstate -[ss_alt] = []) or (shiftstate = [ss_alt])) and + (length(info.chars) > 0) then begin + result:= isshortcut(info.chars[1],caption); + if result then begin + include(eventstate,es_processed); + end; + end + else begin + result:= false; + end; + end; +end; + +function checkshortcut(var info: keyeventinfoty; + const key: keyty; const shiftstate: shiftstatesty): boolean; +begin + result:= (key = info.key) and (shiftstate = info.shiftstate); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +procedure translatewidgetpoint1(var point: pointty; + const source,dest: twidget); + //translates from source widget to dest widget, to screen if dest = nil + //source = nil -> screen + +begin + if source <> nil then begin + addpoint1(point,source.screenpos); + end; + if dest <> nil then begin + subpoint1(point,dest.screenpos); + end; +end; + +function translatewidgetpoint(const point: pointty; + const source,dest: twidget): pointty; +begin + result:= point; + translatewidgetpoint1(result,source,dest); +end; + +function getprocesswindow(const procid: integer): winidty; +var + ar1: procidarty; +begin + ar1:= getallprocesschildren(procid); + result:= gui_pidtowinid(ar1); +end; + +function activateprocesswindow(const procid: integer; + const araise: boolean = true): boolean; + //true if ok +var + winid: winidty; +begin + result:= false; + winid:= getprocesswindow(procid); + if winid <> 0 then begin + if gui_showwindow(winid) = gue_ok then begin + if araise and (gui_raisewindow(winid) <> gue_ok) then begin + exit; + end; + if gui_setappfocus(winid) = gue_ok then begin + result:= true; + end; + end; + end; +end; + +function translatewidgetrect(const rect: rectty; + const source,dest: twidget): rectty; +begin + result:= rect; + translatewidgetpoint1(result.pos,source,dest); +end; + +function compx(const l,r): integer; +begin + result:= twidget(l).fwidgetrect.x - twidget(r).fwidgetrect.x; + if result = 0 then begin + result:= twidget(l).fwidgetrect.y - twidget(r).fwidgetrect.y; + end; +end; + +procedure sortwidgetsxorder(var awidgets: widgetarty; const parent: twidget = nil); +var + int1: integer; + ar1,ar2: integerarty; +begin + if parent = nil then begin + sortarray(pointerarty(awidgets),{$ifdef FPC}@{$endif}compx); + end + else begin + setlength(ar1,length(awidgets)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= translatewidgetpoint(awidgets[int1].pos,awidgets[int1],parent).x; + end; + sortarray(ar1,ar2); + orderarray(ar2,pointerarty(awidgets)); + end; +end; + +function compy(const l,r): integer; +begin + result:= twidget(l).fwidgetrect.y - twidget(r).fwidgetrect.y; + if result = 0 then begin + result:= twidget(l).fwidgetrect.x - twidget(r).fwidgetrect.x; + end; +end; + +procedure sortwidgetsyorder(var awidgets: widgetarty; const parent: twidget = nil); +var + int1: integer; + ar1,ar2: integerarty; +begin + if parent = nil then begin + sortarray(pointerarty(awidgets),{$ifdef FPC}@{$endif}compy); + end + else begin + setlength(ar1,length(awidgets)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= translatewidgetpoint(awidgets[int1].pos,awidgets[int1],parent).y; + end; + sortarray(ar1,ar2); + orderarray(ar2,pointerarty(awidgets)); + end; +end; + +procedure translatepaintpoint1(var point: pointty; + const source,dest: twidget); + //translates from source widget to dest widget, to screen if dest = nil + //source = nil -> screen + +begin + if source <> nil then begin + addpoint1(point,source.screenpos); + addpoint1(point,source.paintpos); + end; + if dest <> nil then begin + subpoint1(point,dest.screenpos); + subpoint1(point,dest.paintpos); + end; +end; + +function translatepaintpoint(const point: pointty; + const source,dest: twidget): pointty; +begin + result:= point; + translatepaintpoint1(result,source,dest); +end; + +function translatepaintrect(const rect: rectty; + const source,dest: twidget): rectty; +begin + result:= rect; + translatepaintpoint1(result.pos,source,dest); +end; + +procedure translatewidgettopaintpoint1(var point: pointty; + const source,dest: twidget); +begin + if source <> nil then begin + addpoint1(point,source.screenpos); + end; + if dest <> nil then begin + subpoint1(point,dest.screenpos); + subpoint1(point,dest.paintpos); + end; +end; + +function translatewidgettopaintpoint(const point: pointty; + const source,dest: twidget): pointty; +begin + result:= point; + translatewidgettopaintpoint1(result,source,dest); +end; + +function translatewidgettopaintrect(const rect: rectty; + const source,dest: twidget): rectty; +begin + result:= rect; + translatewidgettopaintpoint1(result.pos,source,dest); +end; + +procedure translateclientpoint1(var point: pointty; + const source,dest: twidget); + //translates from source client to dest client, to screen if dest = nil + //source = nil -> screen +begin + if source <> nil then begin + addpoint1(point,source.screenpos); + addpoint1(point,source.clientwidgetpos); + end; + if dest <> nil then begin + subpoint1(point,dest.screenpos); + subpoint1(point,dest.clientwidgetpos); + end; +end; + +function translateclientpoint(const point: pointty; + const source,dest: twidget): pointty; +begin + result:= point; + translateclientpoint1(result,source,dest); +end; + +function translateclientrect(const rect: rectty; + const source,dest: twidget): rectty; +begin + result:= rect; + translateclientpoint1(result.pos,source,dest); +end; + +procedure syncmaxautosize(const widgets: array of twidget); +var + size1,size2: sizety; + int1: integer; + rect1: rectty; + po1: pointty; +begin + size1:= nullsize; + for int1:= high(widgets) downto 0 do begin + with widgets[int1] do begin + size2:= clientsize; + getautopaintsize(size2); + if not (osk_nolayoutcx in optionsskin) then begin + if size2.cx > size1.cx then begin + size1.cx:= size2.cx; + end; + end; + if not (osk_nolayoutcy in optionsskin) then begin + if size2.cy > size1.cy then begin + size1.cy:= size2.cy; + end; + end; + end; + end; + for int1:= 0 to high(widgets) do begin + with widgets[int1] do begin + rect1:= fwidgetrect; + size2:= clientsize; + if not (osk_nolayoutcx in optionsskin) then begin + size2.cx:= size1.cx; + end; + if not (osk_nolayoutcy in optionsskin) then begin + size2.cy:= size1.cy; + end; + clientsize:= size2; + po1:= pos; + if an_right in fanchors then begin + dec(po1.x,fwidgetrect.cx-rect1.cx); + end; + if an_bottom in fanchors then begin + dec(rect1.y,fwidgetrect.cy-rect1.cy); + end; + pos:= po1; + end; + end; +end; + +procedure syncpaintwidth(const awidgets: array of twidget; + const awidgetwidth: integer = -1); +var + int1,int2,int3: integer; + widget1: twidget; +begin + if high(awidgets) >= 0 then begin + int2:= -bigint; + widget1:= awidgets[0]; //compiler warning + for int1:= 0 to high(awidgets) do begin //first widget first + with awidgets[int1] do begin + if fframe = nil then begin + int3:= 0; + end + else begin + int3:= fframe.fouterframe.left + fframe.fouterframe.right; + end; + end; + if int3 > int2 then begin + widget1:= awidgets[int1]; + int2:= int3; + end; + end; + if awidgetwidth >= 0 then begin + with widget1 do begin //biggest frame + if anchors * [an_left,an_right] = [an_right] then begin + bounds_x:= bounds_x - awidgetwidth + bounds_cx; + end; + bounds_cx:= awidgetwidth; + end; + end; + int2:= widget1.bounds_cx - int2; //min frame width + for int1:= high(awidgets) downto 0 do begin + with awidgets[int1] do begin + if fframe = nil then begin + int3:= 0; + end + else begin + int3:= fframe.fouterframe.left + fframe.fouterframe.right; + end; + int3:= int3 + int2; + if anchors * [an_left,an_right] = [an_right] then begin + bounds_x:= bounds_x - int3 + bounds_cx; + end; + bounds_cx:= int3; + end; + end; + end; +end; + +procedure syncpaintheight(const awidgets: array of twidget; + const awidgetheight: integer = -1); +var + int1,int2,int3: integer; + widget1: twidget; +begin + if high(awidgets) >= 0 then begin + int2:= -bigint; + widget1:= awidgets[0]; //compiler warning + for int1:= 0 to high(awidgets) do begin //first widget first + with awidgets[int1] do begin + if fframe = nil then begin + int3:= 0; + end + else begin + int3:= fframe.fouterframe.top + fframe.fouterframe.bottom; + end; + end; + if int3 > int2 then begin + widget1:= awidgets[int1]; + int2:= int3; + end; + end; + if awidgetheight >= 0 then begin + with widget1 do begin + if anchors * [an_top,an_bottom] = [an_bottom] then begin + bounds_y:= bounds_y - awidgetheight + bounds_cy; + end; + bounds_cy:= awidgetheight; + end; + end; + int2:= widget1.bounds_cy - int2; //min frame width + for int1:= high(awidgets) downto 0 do begin + with awidgets[int1] do begin + if fframe = nil then begin + int3:= 0; + end + else begin + int3:= fframe.fouterframe.top + fframe.fouterframe.bottom; + end; + int3:= int3 + int2; + if anchors * [an_top,an_bottom] = [an_bottom] then begin + bounds_y:= bounds_y - int3 + bounds_cy; + end; + bounds_cy:= int3; + end; + end; + end; +end; + +procedure beep; +begin + gui_beep; +end; + +procedure guibeep; +begin + gui_beep; +end; + +procedure disablewidgets(awidgets: array of twidget); +var + int1: integer; +begin + for int1:= 0 to high(awidgets) do begin + awidgets[int1].enabled:= false; + end; +end; + +procedure enablewidgets(awidgets: array of twidget); +var + int1: integer; +begin + for int1:= 0 to high(awidgets) do begin + awidgets[int1].enabled:= true; + end; +end; + +procedure showwidgets(awidgets: array of twidget); +var + int1: integer; +begin + for int1:= 0 to high(awidgets) do begin + awidgets[int1].visible:= false; + end; +end; + +procedure hidewidgets(awidgets: array of twidget); +var + int1: integer; +begin + for int1:= 0 to high(awidgets) do begin + awidgets[int1].visible:= false; + end; +end; + +function showmodalwidget(const aclass: widgetclassty): modalresultty; +var + widget1: twidget; +begin + widget1:= nil; + application.setlinkedvar(aclass.create(nil),tmsecomponent(widget1)); + try + result:= widget1.show(true); + finally + widget1.free; + end; +end; + +function getiassistiveclient(const awidget: twidget): iassistiveclient; +begin + result:= nil; + if awidget <> nil then begin + result:= awidget.getiassistiveclient(); + end; +end; + +procedure designeventloop; +begin + if appinst <> nil then begin + appinst.fdesigning:= true; + tinternalapplication(appinst).eventloop({nil}); + end; +end; + +function needswidgetnamewriting(const ar: widgetarty): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(ar) do begin + if ar[int1] <> nil then begin + result:= true; + break; + end; + end; +end; + +function needswidgetnamewriting(const ar1,ar2: widgetarty): boolean; +var + int1: integer; +begin + result:= high(ar1) <> high(ar2); + if not result then begin; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] = nil) or (ar2[int1] = nil) then begin + if (ar1[int1] <> ar2[int1]) then begin + result:= true; + break; + end; + end + else begin + if ar1[int1].name <> ar2[int1].name then begin + result:= true; + break; + end; + end; + end; + end; +end; + +procedure writewidgetnames(const writer: twriter; const ar: widgetarty); +var + int1: integer; +begin + writer.writelistbegin; + for int1:= 0 to high(ar) do begin + if ar[int1] <> nil then begin + writer.writestring(ar[int1].name); + end + else begin + writer.writestring(''); + end; + end; + writer.writelistend; +end; + +function application: tguiapplication; +begin + if appinst = nil then begin + tinternalapplication.create(nil); +// appinst.initialize; + end; + result:= appinst; +end; + +function mousebuttontoshiftstate(button: mousebuttonty): shiftstatesty; +begin + if button = mb_none then begin + result:= []; + end + else begin + result:= [shiftstatety(longword(ss_left) + + longword(button) - longword(mb_left))]; + end; +end; + +function isenterkey(const awidget: twidget; const key: keyty): boolean; +begin + result:= ((awidget = nil) or not + (ow_keyreturntaborder in awidget.optionswidget)) and + ({(key = key_enter) or} (key = key_return)); +end; + +function isdblclick(const ainfo: mouseeventinfoty; + const abutton: mousebuttonty = mb_left): boolean; +begin + with ainfo do begin + result:= (button = abutton) and (eventkind = ek_buttonpress) and + (ss_double in shiftstate); + end; +end; + +function eatdblclick(var ainfo: mouseeventinfoty; + const abutton: mousebuttonty = mb_left): boolean; +begin + result:= isdblclick(ainfo,abutton); + if result then begin + include(ainfo.eventstate,es_processed); + end; +end; + +function simulatemodalresult(const awidget: twidget; + const amodres: modalresultty): boolean; +begin + result:= awidget <> nil; + if result then begin + with awidget.window do begin + fmodalresult:= amodres; + try + result:= awidget.canclose(nil); + if result then begin + awidget.hide; + end; + finally + if fmodalresult = amodres then begin + fmodalresult:= mr_none; + end; + end; + end; + end + else begin + result:= false; + end; +end; + +procedure destroyregion(var region: gdiregionty); +var + info: drawinfoty; +begin + drawinfoinit(info); + with region do begin + if region <> 0 then begin + info.regionoperation.source:= region; + gdi_call(gdf_destroyregion,info,gdi); + region:= 0; + end; + end; +end; + +function createregion(const gdi: pgdifunctionaty): gdiregionty; overload; +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with info.regionoperation do begin + gdi_call(gdf_createemptyregion,info,gdi); + result.region:= dest; + result.gdi:= gdi; + end; +end; +{$warnings on} + +function createregion(const arect: rectty; + const gdi: pgdifunctionaty): gdiregionty; overload; +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with info.regionoperation do begin + rect:= arect; + drawinfoinit(info); + gdi_call(gdf_createrectregion,info,gdi); + result.region:= dest; + result.gdi:= gdi; + end; +end; +{$warnings on} + +function createregion(const rects: rectarty; + const gdi: pgdifunctionaty): gdiregionty; overload; +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with info.regionoperation do begin + rectscount:= length(rects); + if rectscount > 0 then begin + rectspo:= @rects[0]; + gdi_call(gdf_createrectsregion,info,gdi); + result.region:= dest; + result.gdi:= gdi; + end + else begin + result:= createregion(gdi); + end; + end; +end; +{$warnings on} + +procedure regmove(const region: gdiregionty; const dist: pointty); +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with region,info.regionoperation do begin + if region <> 0 then begin + source:= region; + rect.pos:= dist; + gdi_call(gdf_moveregion,info,gdi); + end; + end; +end; +{$warnings on} + +function regcliprect(const region: gdiregionty): rectty; +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with region,info.regionoperation do begin + if region <> 0 then begin + source:= region; + gdi_call(gdf_regionclipbox,info,gdi); + result:= rect; + end + else begin + result:= nullrect; + end; + end; +end; +{$warnings on} + +procedure regintersectrect(const region: gdiregionty; const arect: rectty); +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with region,info.regionoperation do begin + dest:= region; + rect:= arect; + gdi_call(gdf_regintersectrect,info,gdi); + end; +end; +{$warnings on} + +procedure regaddrect(const region: gdiregionty; const arect: rectty); +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with region,info.regionoperation do begin + dest:= region; + rect:= arect; + gdi_call(gdf_regaddrect,info,gdi); + end; +end; +{$warnings on} + +{ twidgetfont} + +class function twidgetfont.getinstancepo(owner: tobject): pfont; +begin + result:= @twidget(owner).ffont; +end; + +{ twidgetfontempty} + +class function twidgetfontempty.getinstancepo(owner: tobject): pfont; +begin + result:= @twidget(owner).ffontempty; +end; + +{ tresizeevent } + +constructor tresizeevent.create(const dest: ievent; const asize: sizety); +begin + inherited create(ek_resize,dest); + size:= asize; +end; + +{ tcustomframe } + +procedure initframeinfo(var info: baseframeinfoty); overload; +begin + with info do begin + colorclient:= cl_default; + colorframe:= cl_default; + colorframeactive:= cl_default; + colorframedisabled:= cl_default; + colorframemouse:= cl_default; + colorframeclicked:= cl_default; + colorframedefault:= cl_default; + colorglyph:= cl_default; + colorpattern:= cl_default; + initdefaultvalues(framecolors.edges); +{ + with framecolors.edges do begin + shadow.effectcolor:= cl_default; + shadow.color:= cl_default; + shadow.effectwidth:= -1; + light.color:= cl_default; + light.effectcolor:= cl_default; + light.effectwidth:= -1; + end; +} + end; +end; + +procedure initframeinfo(var info: captionframeinfoty); overload; +begin + //dummy +end; + +constructor tcustomframe.create(const intf: iframe); +var + ws1: widgetstates1ty; +begin + include(fstate,fs_creating); + fintf:= intf; + ws1:= fintf.getwidget.fwidgetstate1; + if ws1_noframewidgetshift in ws1 then begin + include(fstate,fs_nowidget); + end; + if ws1_framemouse in ws1 then begin + include(fstate,fs_framemouse); + end; + if not (fs_nosetinstance in fstate) then begin + fintf.setframeinstance(self); + end; + initframeinfo(fi); +end; + +destructor tcustomframe.destroy; +begin + if ftemplate <> nil then begin + fintf.getwidget.setlinkedvar(nil,tmsecomponent(ftemplate)); + end; + inherited; +end; + +function tcustomframe.pointinmask(const pos: pointty; + const arect: rectty): boolean; +var + rect1: rectty; + po1: pint16; +begin + result:= true; + if (fi.frameimage_list <> nil) and + fi.frameimage_list.hascornermask then begin + rect1:= arect; + with timagelist1(fi.frameimage_list) do begin + if (pos.x < fcornermaskmaxtopleft) and + (pos.y < rect1.y + length(cornermask_topleft)) then begin + //topleft + po1:= pointer(cornermask_topleft); + result:= pos.x >= rect1.x + po1[pos.y-rect1.y]; + end + else begin + if (pos.x < fcornermaskmaxbottomleft) and + (pos.y >= rect1.y + rect1.cy - + length(cornermask_bottomleft)) then begin + //bottomleft + po1:= pointer(cornermask_bottomleft); + result:= pos.x >= rect1.x + po1[rect1.y + rect1.cy - pos.y -1]; + end + else begin + if (pos.x >= rect1.x + rect1.cx - fcornermaskmaxbottomright) and + (pos.y >= rect1.y + rect1.cy - + length(cornermask_bottomright)) then begin + //bottomright + po1:= pointer(cornermask_bottomright); + result:= pos.x < rect1.x + rect1.cx - + po1[rect1.y + rect1.cy - pos.y -1]; + end + else begin + if (pos.x >= rect1.x + rect1.cx - fcornermaskmaxtopright) and + (pos.y < rect1.y + length(cornermask_topright)) then begin + //topright + po1:= pointer(cornermask_topright); + result:= pos.x < rect1.x + rect1.cx - + po1[pos.y-rect1.y]; + end; + end; + end; + end; + end; + end; +end; + +procedure tcustomframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); + +begin + checkstate; + with sender do begin + if not (ow_mousetransparent in foptionswidget) then begin + if pointinrect(info.pos,fpaintrect) and + pointinmask(info.pos, + deflaterect(mr(nullpoint,fintf.getwidgetrect.size),fouterframe)) then begin + fwidgetstate:= fwidgetstate + [ws_mouseinclient,ws_wantmousemove, + ws_wantmousebutton,ws_wantmousefocus]; + end + else begin + if (fs_framemouse in fstate) and + pointinrect(info.pos,mr(nullpoint,fintf.getwidgetrect.size)) then begin + fwidgetstate:= fwidgetstate + [ws_wantmousemove,ws_wantmousebutton]; + + end; + end; + end; + end; +end; + +function tcustomframe.needsactiveinvalidate: boolean; +begin + with fi do begin + result:= (frameimage_list <> nil) and (frameimage_offsetactive <> 0) or + (frameface_list <> nil) and (frameface_offsetactive <> 0) or + (fi.colorframedefault <> cl_default); + end; +end; + +function tcustomframe.needsenabledinvalidate: boolean; +begin + with fi do begin + result:= colorframedisabled <> cl_default; + end; +end; + +function tcustomframe.needsfocusedinvalidate: boolean; +begin + with fi do begin + result:= (frameimage_list <> nil) and (frameimage_offsetactive <> 0) or + (frameface_list <> nil) and (frameface_offsetfocused <> 0) or + (fi.colorframedefault <> cl_default);; + end; +end; + +function tcustomframe.needsmouseinvalidate: boolean; +begin + with fi do begin + result:= + (fs_needsmouseinvalidate in fstate) or + (frameimage_list <> nil) and + ((frameimage_offsetmouse <> 0) or (frameimage_offsetclicked <> 0)) or + (frameface_list <> nil) and + ((frameface_offsetmouse <> 0) or (frameface_offsetclicked <> 0)) or + (colorframeclicked <> cl_default) or + (colorframemouse <> cl_default); + end; +end; + +function tcustomframe.needsclickinvalidate: boolean; +begin + with fi do begin + result:= (frameimage_list <> nil) and (frameimage_offsets.clicked <> 0) or + (frameface_list <> nil) and (frameface_offsets.clicked <> 0) or + (colorframeclicked <> cl_default); + end; +end; + +function tcustomframe.needsmouseenterinvalidate: boolean; +begin + with fi do begin + result:= (frameimage_list <> nil) and (frameimage_offsets.mouse <> 0) or + (frameface_list <> nil) and (frameface_offsets.mouse <> 0) or + (colorframemouse <> cl_default); + end; +end; + +procedure tcustomframe.activechanged; +begin + if needsactiveinvalidate then begin + fintf.getwidget.invalidatewidget; + end; +end; + +procedure tcustomframe.enabledchanged(); +begin + if needsenabledinvalidate then begin + fintf.getwidget.invalidatewidget; + end; +end; + +procedure tcustomframe.focusedchanged; +begin + if needsfocusedinvalidate() then begin + fintf.getwidget.invalidatewidget(); + end; +end; + +function tcustomframe.needsfocuspaint: boolean; +begin + result:= fs_drawfocusrect in fstate; +end; + +function tcustomframe.haspaintrectfocus(): boolean; +begin + result:= not (fs_captionfocus in fstate); +end; + +function tcustomframe.ishintarea(const apos: pointty; var aid: int32): boolean; +begin + result:= pointinrect(apos,fpaintrect) or + (fs_captionhint in fstate) and pointincaption(apos); +end; + +function calcframestateoffs(const astate: framestateflagsty; + const offsets: frameoffsetsty): integer; +begin + with offsets do begin + result:= offset; + if fsf_offset1 in astate then begin + result:= result + offset1; + end; + if fsf_disabled in astate then begin + result:= result + disabled; + end; + if fsf_active in astate then begin + result:= result + active; + end; + if fsf_focused in astate then begin + result:= result + focused; + end; + if fsf_mouse in astate then begin + result:= result + mouse; + end; + if fsf_clicked in astate then begin + result:= result + clicked; + end; + { + else begin + if fsf_active in astate then begin + if fsf_clicked in astate then begin + result:= result + activeclicked; + end + else begin + if fsf_mouse in astate then begin + result:= result + activemouse; + end + else begin + result:= result + active; + end; + end; + end + else begin + if fsf_clicked in astate then begin + result:= result + clicked; + end + else begin + if fsf_mouse in astate then begin + result:= result + mouse; + end; + end; + end; + end; +} + end; +end; + +procedure tcustomframe.paintframeface(const canvas: tcanvas; + const arect: rectty); +var + faceoffs: int32; + rect1: rectty; + reg1: regionty; +begin + if fi.frameface_list <> nil then begin + faceoffs:= fi.frameface_list.lookup( + calcframestateoffs(fintf.getframestateflags, + frameoffsetsty(fi.frameface_offsets))); + if (faceoffs >= 0) and (faceoffs < fi.frameface_list.list.count) then begin + if fso_clientfacerect in optionsskin then begin + reg1:= canvas.copyclipregion; + rect1.x:= arect.x + fclientrect.x; + rect1.y:= arect.y + fclientrect.y; + rect1.cx:= arect.cx + fclientrect.cx - fpaintrect.cx; + rect1.cy:= arect.cy + fclientrect.cy - fpaintrect.cy; + canvas.intersectcliprect(arect); + fi.frameface_list.list[faceoffs].paint(canvas,rect1); + canvas.clipregion:= reg1; + end + else begin + fi.frameface_list.list[faceoffs].paint(canvas,arect); + end; + end; + end; +end; + +function tcustomframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_transparent; + end; +end; + +procedure tcustomframe.internalpaintbackground(const canvas: tcanvas; + const arect: rectty; const clip: boolean; const move: boolean); +var + rect1: rectty; + cl1: colorty; +begin + rect1:= deflaterect(arect,fpaintframe); + if clip then begin + canvas.intersectcliprect(rect1); + if (fi.frameimage_list <> nil) and + fi.frameimage_list.hascornermask then begin + fi.frameimage_list.clipcornermask(canvas, + deflaterect(arect,fouterframe),fi.hiddenedges); + end; + end; + cl1:= actualcolorclient; + if cl1 <> cl_transparent then begin + canvas.fillrect(rect1,cl1); + end; + if not (fso_faceoverlay in optionsskin) then begin + paintframeface(canvas,rect1); + end; + if move then begin + canvas.move(addpoint(fpaintrect.pos,fclientrect.pos)); + canvas.brushorigin:= nullpoint; + end; +end; + +procedure tcustomframe.paintbackground(const canvas: tcanvas; + const arect: rectty; const clip: boolean; + const move: boolean); +var + bo1: boolean; +begin + if (ftemplate <> nil) then begin + if assigned(tframetemplate(ftemplate.ftemplate). + fonbeforepaintbackground) then begin + bo1:= false; + tframetemplate(ftemplate.ftemplate).fonbeforepaintbackground( + self,canvas,arect,clip,move,bo1); + if not bo1 then begin + internalpaintbackground(canvas,arect,clip,move); + end; + end + else begin + internalpaintbackground(canvas,arect,clip,move); + end; + if assigned(tframetemplate(ftemplate.ftemplate). + fonafterpaintbackground) then begin + tframetemplate(ftemplate.ftemplate).fonafterpaintbackground( + self,canvas,arect,clip,move); + end; + end + else begin + internalpaintbackground(canvas,arect,clip,move); + end; +end; + +class procedure tcustomframe.drawframe(const canvas: tcanvas; + const rect2: rectty; const afi: baseframeinfoty; + const astate: framestateflagsty); +var + imageoffs: integer; + rect1: rectty; + col1: colorty; +// imagesize1: sizety; +begin + rect1:= rect2; + if afi.levelo <> 0 then begin + draw3dframe(canvas,rect1,afi.levelo,afi.framecolors.edges,afi.hiddenedges); + updateedgerect(rect1,abs(afi.levelo),afi.hiddenedges); + end; + if afi.framewidth > 0 then begin + col1:= afi.colorframe; + if (afi.colorframeclicked <> cl_default) and + (fsf_clicked in astate) then begin + col1:= afi.colorframeclicked; + end + else begin + if (afi.colorframemouse <> cl_default) and + (fsf_mouse in astate) then begin + col1:= afi.colorframemouse; + end + else begin + if (afi.colorframeactive <> cl_default) and + (fsf_active in astate) then begin + col1:= afi.colorframeactive; + end + else begin + if (afi.colorframedisabled <> cl_default) and + (fsf_disabled in astate) then begin + col1:= afi.colorframedisabled; + end + else begin + if (afi.colorframedefault <> cl_default) and + (fsf_default in astate) then begin + col1:= afi.colorframedefault; + end + end; + end; + end; + end; + if col1 = cl_default then begin + col1:= defaultframecolors.frame; + end; + canvas.drawframe(rect1,-afi.framewidth,col1,afi.hiddenedges); + updateedgerect(rect1,afi.framewidth,afi.hiddenedges); + end; + if afi.leveli <> 0 then begin + draw3dframe(canvas,rect1,afi.leveli,afi.framecolors.edges,afi.hiddenedges); + end; + if (afi.frameimage_list <> nil) then begin + imageoffs:= calcframestateoffs(astate,frameoffsetsty(afi.frameimage_offsets)); + drawimageframe(canvas,afi.frameimage_list,imageoffs,rect2,afi.hiddenedges); + end; +end; + +function tcustomframe.getassistivecaption(): msestring; +begin + result:= ''; +end; + +procedure tcustomframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); +begin + if fso_faceoverlay in optionsskin then begin + paintframeface(canvas,deflaterect(arect,fpaintframe)); + end; + drawframe(canvas,deflaterect(arect,fouterframe),fi,fintf.getframestateflags); +end; + +procedure tcustomframe.updatehotkeys(); +begin + //dummy +end; + +procedure tcustomframe.paintoverlay(const canvas: tcanvas; + const arect: rectty); +var + bo1: boolean; +begin + if (ftemplate <> nil) then begin + if assigned(tframetemplate(ftemplate.ftemplate). + fonbeforepaintoverlay) then begin + bo1:= false; + tframetemplate(ftemplate.ftemplate).fonbeforepaintoverlay( + self,canvas,arect,bo1); + if not bo1 then begin + internalpaintoverlay(canvas,arect); + end; + end + else begin + internalpaintoverlay(canvas,arect); + end; + if assigned(tframetemplate(ftemplate.ftemplate). + fonafterpaintoverlay) then begin + tframetemplate(ftemplate.ftemplate).fonafterpaintoverlay(self,canvas,arect); + end; + end + else begin + internalpaintoverlay(canvas,arect); + end; +end; + +procedure tcustomframe.dopaintfocusrect(const canvas: tcanvas; + const rect: rectty); +var + rect1: rectty; +begin + rect1:= deflaterect(rect,fpaintframe); + inflaterect1(rect1,-fi.focusrectdist); + drawfocusrect(canvas,rect1); +end; + +function tcustomframe.checkfocusshortcut(var info: keyeventinfoty): boolean; +begin + result:= false; +end; + +procedure tcustomframe.updatewidgetstate; +var + bo1: boolean; +begin + if (fi.colorframeactive <> cl_default) and (fi.framewidth <> 0) then begin + with fintf.getwidget do begin + bo1:= active; + if bo1 xor (fs_widgetactive in fstate) then begin + fintf.invalidatewidget; + if bo1 then begin + include(fstate,fs_widgetactive); + end + else begin + exclude(fstate,fs_widgetactive); + end; + end; + end; + end; +end; + +procedure tcustomframe.updateclientrect; +begin + fclientrect.size:= fpaintrect.size; + fclientrect.pos:= nullpoint; + finnerclientrect:= deflaterect(fclientrect,fi.innerframe); +end; + +class function tcustomframe.calcpaintframe(const afi: baseframeinfoty): framety; +var + int1: integer; +begin + result:= nullframe; + with result do begin + int1:= abs(afi.levelo) + afi.framewidth + abs(afi.leveli); + if not(edg_left in afi.hiddenedges) then begin + left:= int1; + end; + if not(edg_top in afi.hiddenedges) then begin + top:= int1; + end; + if not(edg_right in afi.hiddenedges) then begin + right:= int1; + end; + if not(edg_bottom in afi.hiddenedges) then begin + bottom:= int1; + end; + if afi.frameimage_list <> nil then begin + if not (edg_left in afi.hiddenedges) then begin + int1:= afi.frameimage_list.width + afi.frameimage_left; +// if int1 > left then begin + left:= int1; +// end; + end; + if not (edg_right in afi.hiddenedges) then begin + int1:= afi.frameimage_list.width + afi.frameimage_right; +// if int1 > right then begin + right:= int1; +// end; + end; + if not (edg_top in afi.hiddenedges) then begin + int1:= afi.frameimage_list.height + afi.frameimage_top; +// if int1 > top then begin + top:= int1; +// end; + end; + if not (edg_bottom in afi.hiddenedges) then begin + int1:= afi.frameimage_list.height + afi.frameimage_bottom; +// if int1 > bottom then begin + bottom:= int1; +// end; + end; + end; + end; +end; + +class function tcustomframe.calcinnerframe(const afi: baseframeinfoty): framety; +begin + result:= calcpaintframe(afi); + result.left:= result.left + afi.innerframe.left; + result.top:= result.top + afi.innerframe.top; + result.right:= result.right + afi.innerframe.right; + result.bottom:= result.bottom + afi.innerframe.bottom; +end; + +procedure tcustomframe.calcrects; +begin + fwidth:= calcpaintframe(fi); + fpaintframedelta:= nullframe; + getpaintframe(fpaintframedelta); + fpaintframe:= addframe(fpaintframedelta,fouterframe); + addframe1(fpaintframe,fwidth); + finnerframe:= addframe(fpaintframe,fi.innerframe); + fpaintrect.pos:= pointty(fpaintframe.topleft); + fpaintrect.size:= fintf.getwidgetrect.size; + fpaintrect.cx:= fpaintrect.cx - fpaintframe.left - fpaintframe.right; + fpaintrect.cy:= fpaintrect.cy - fpaintframe.top - fpaintframe.bottom; + if not (fs_paintposinited in fstate) then begin + fpaintposbefore:= fpaintrect.pos; + include(fstate,fs_paintposinited); + end; +end; + +procedure tcustomframe.updaterects; +begin + calcrects; +end; + +procedure tcustomframe.updatestate(); +var + po1: pointty; +begin + include(fstate,fs_rectsvalid); //avoid recursion + updaterects; + if not (fs_widgetregionchanging in fstate) then begin + if not (csreading in fintf.getcomponentstate) and + not (fs_nowidget in fstate) then begin + po1:= subpoint(fpaintrect.pos,fpaintposbefore); + fintf.scrollwidgets(po1); + end; + fpaintposbefore:= fpaintrect.pos; + updateclientrect; + include(fstate,fs_rectsvalid); + if not (fs_clientrectchanging in fstate) then begin + include(fstate,fs_clientrectchanging); + try + fintf.clientrectchanged; + finally + exclude(fstate,fs_clientrectchanging); + end; + end; + end + else begin + updateclientrect(); + include(fstate,fs_rectsvalid); + end; +end; + +procedure tcustomframe.internalupdatestate(); +begin + exclude(fstate,fs_rectsvalid); + if not (csloading in fintf.getcomponentstate) then begin + if not (fs_stateupdating in fstate) then begin + include(fstate,fs_stateupdating); + try + updatestate; + finally + exclude(fstate,fs_stateupdating); + end; + end; + end; + exclude(fstate,fs_creating); +end; + +procedure tcustomframe.checkstate; +begin + if not (fs_rectsvalid in fstate) then begin + updatestate; + end; +end; + +procedure tcustomframe.setlocalprops(const avalue: framelocalpropsty); +var + widget1: twidget; +begin + if flocalprops <> avalue then begin + flocalprops:= avalue; + if ftemplate <> nil then begin + settemplateinfo(ftemplate.template.fi); + end; + if not (frl_nodisable in flocalprops) then begin + widget1:= fintf.getwidget; + if not (csloading in widget1.componentstate) and not widget1.isenabled then begin + setdisabled(true); + end + else begin + setdisabled(false); + end; + end + else begin + setdisabled(false); + end; + end; +end; + +procedure tcustomframe.setlocalprops1(const avalue: framelocalprops1ty); +begin + if flocalprops1 <> avalue then begin + flocalprops1:= avalue; + if ftemplate <> nil then begin + settemplateinfo(ftemplate.template.fi); + end; + end; +end; + +procedure tcustomframe.setlevelo(const Value: integer); +begin + include(flocalprops,frl_levelo); + if fi.levelo <> value then begin + fi.levelo := Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setleveli(const Value: integer); +begin + include(flocalprops,frl_leveli); + if fi.leveli <> value then begin + fi.leveli := Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframewidth(const Value: integer); +begin + include(flocalprops,frl_framewidth); + if fi.framewidth <> value then begin + if value < 0 then begin + fi.framewidth:= 0; + end + else begin + fi.framewidth := Value; + end; + internalupdatestate; + end; +end; +{ +procedure tcustomframe.setextraspace(const avalue: integer); +begin + if fi.extraspace <> avalue then begin + include(flocalprops,frl_extraspace); + fi.extraspace:= avalue; + internalupdatestate; + end; +end; +} +procedure tcustomframe.setframei_left(const Value: integer); +begin + include(flocalprops,frl_fileft); + if fi.innerframe.left <> value then begin + fi.innerframe.left:= Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframei_top(const Value: integer); +begin + include(flocalprops,frl_fitop); + if fi.innerframe.top <> value then begin + fi.innerframe.top := Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframei_right(const Value: integer); +begin + include(flocalprops,frl_firight); + if fi.innerframe.right <> value then begin + fi.innerframe.right:= Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframei_bottom(const Value: integer); +begin + include(flocalprops,frl_fibottom); + if fi.innerframe.bottom <> value then begin + fi.innerframe.bottom:= Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframei(const avalue: framety); +begin + fi.innerframe:= avalue; + internalupdatestate; +end; + +procedure tcustomframe.setframeo_left(const Value: integer); +begin + include(flocalprops1,frl1_foleft); + if fi.outerframe.left <> value then begin + fi.outerframe.left:= Value; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setframeo_top(const Value: integer); +begin + include(flocalprops1,frl1_fotop); + if fi.outerframe.top <> value then begin + fi.outerframe.top:= Value; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setframeo_right(const Value: integer); +begin + include(flocalprops1,frl1_foright); + if fi.outerframe.right <> value then begin + fi.outerframe.right:= Value; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setframeo_bottom(const Value: integer); +begin + include(flocalprops1,frl1_fobottom); + if fi.outerframe.bottom <> value then begin + fi.outerframe.bottom:= Value; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setframeo(const avalue: framety); +begin + fi.outerframe:= avalue; + internalupdatestate; +end; + +procedure tcustomframe.setframeimage_list(const avalue: timagelist); +begin + include(flocalprops,frl_frameimagelist); + if fi.frameimage_list <> avalue then begin + fintf.getwidget.setlinkedvar(avalue,tmsecomponent(fi.frameimage_list)); + internalupdatestate; + end; +end; + +procedure tcustomframe.setfocusrectdist(const avalue: int32); +begin + include(flocalprops1,frl1_focusrectdist); + if fi.focusrectdist <> avalue then begin + fi.focusrectdist:= avalue; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setextraspace(const avalue: int32); +begin + include(flocalprops1,frl1_extraspace); + if fi.extraspace <> avalue then begin + fi.extraspace:= avalue; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setimagedist(const avalue: int32); +begin + include(flocalprops1,frl1_imagedist); + if fi.imagedist <> avalue then begin + fi.imagedist:= avalue; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setimagedist1(const avalue: int32); +begin + include(flocalprops1,frl1_imagedist1); + if fi.imagedist1 <> avalue then begin + fi.imagedist1:= avalue; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setimagedist2(const avalue: int32); +begin + include(flocalprops1,frl1_imagedist2); + if fi.imagedist2 <> avalue then begin + fi.imagedist2:= avalue; + internalupdatestate(); + end; +end; + +function tcustomframe.getimagelist: timagelist; +begin + result:= fi.frameimage_list; +end; + +procedure tcustomframe.setframeimage_left(const avalue: integer); +begin + include(flocalprops,frl_frameimageleft); + if fi.frameimage_left <> avalue then begin + fi.frameimage_left:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_right(const avalue: integer); +begin + include(flocalprops,frl_frameimageright); + if fi.frameimage_right <> avalue then begin + fi.frameimage_right:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_top(const avalue: integer); +begin + include(flocalprops,frl_frameimagetop); + if fi.frameimage_top <> avalue then begin + fi.frameimage_top:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_bottom(const avalue: integer); +begin + include(flocalprops,frl_frameimagebottom); + if fi.frameimage_bottom <> avalue then begin + fi.frameimage_bottom:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offset(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffset); + if fi.frameimage_offsets.offset <> avalue then begin + fi.frameimage_offsets.offset:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offset1(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffset1); + if fi.frameimage_offsets.offset1 <> avalue then begin + fi.frameimage_offsets.offset1:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetdisabled(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetdisabled); + if fi.frameimage_offsets.disabled <> avalue then begin + fi.frameimage_offsets.disabled:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetmouse(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetmouse); + if fi.frameimage_offsets.mouse <> avalue then begin + fi.frameimage_offsets.mouse:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetclicked(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetclicked); + if fi.frameimage_offsets.clicked <> avalue then begin + fi.frameimage_offsets.clicked:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetfocused(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetfocused); + if fi.frameimage_offsets.focused <> avalue then begin + fi.frameimage_offsets.focused:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetactive(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetactive); + if fi.frameimage_offsets.active <> avalue then begin + fi.frameimage_offsets.active:= avalue; + internalupdatestate; + end; +end; +{ +procedure tcustomframe.setframeimage_offsetactivemouse(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetactivemouse); + if fi.frameimage_offsets.activemouse <> avalue then begin + fi.frameimage_offsets.activemouse:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetactiveclicked(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetactiveclicked); + if fi.frameimage_offsets.activeclicked <> avalue then begin + fi.frameimage_offsets.activeclicked:= avalue; + internalupdatestate; + end; +end; +} +procedure tcustomframe.setframeface_list(const avalue: tfacelist); +begin + include(flocalprops1,frl1_framefacelist); + if fi.frameface_list <> avalue then begin + fintf.getwidget.setlinkedvar(avalue,tmsecomponent(fi.frameface_list)); + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offset(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffset); + if fi.frameface_offsets.offset <> avalue then begin + fi.frameface_offsets.offset:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offset1(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffset1); + if fi.frameface_offsets.offset1 <> avalue then begin + fi.frameface_offsets.offset1:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetdisabled(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetdisabled); + if fi.frameface_offsets.disabled <> avalue then begin + fi.frameface_offsets.disabled:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetmouse(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetmouse); + if fi.frameface_offsets.mouse <> avalue then begin + fi.frameface_offsets.mouse:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetclicked(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetclicked); + if fi.frameface_offsets.clicked <> avalue then begin + fi.frameface_offsets.clicked:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetfocused(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetfocused); + if fi.frameface_offsets.focused <> avalue then begin + fi.frameface_offsets.focused:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetactive(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetactive); + if fi.frameface_offsets.active <> avalue then begin + fi.frameface_offsets.active:= avalue; + internalupdatestate; + end; +end; +{ +procedure tcustomframe.setframeface_offsetactivemouse(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetactivemouse); + if fi.frameface_offsets.activemouse <> avalue then begin + fi.frameface_offsets.activemouse:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetactiveclicked(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetactiveclicked); + if fi.frameface_offsets.activeclicked <> avalue then begin + fi.frameface_offsets.activeclicked:= avalue; + internalupdatestate; + end; +end; +} +procedure tcustomframe.setoptionsskin(const avalue: frameskinoptionsty); +begin + include(flocalprops,frl_optionsskin); + if fi.optionsskin <> avalue then begin + fi.optionsskin:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setcolorclient(const value: colorty); +begin + include(flocalprops,frl_colorclient); + if fi.colorclient <> value then begin + fi.colorclient:= value; + fintf.invalidate; + end; +end; + +procedure tcustomframe.setcolorframe(const Value: colorty); +begin + include(flocalprops,frl_colorframe); + if fi.colorframe <> value then begin + fi.colorframe:= Value; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorframeactive(const avalue: colorty); +begin + include(flocalprops,frl_colorframeactive); + if fi.colorframeactive <> avalue then begin + fi.colorframeactive:= avalue; + fintf.invalidatewidget; + end; +end; + + +procedure tcustomframe.setcolorframedisabled(const avalue: colorty); +begin + include(flocalprops1,frl1_colorframedisabled); + if fi.colorframedisabled <> avalue then begin + fi.colorframedisabled:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorframemouse(const avalue: colorty); +begin + include(flocalprops1,frl1_colorframemouse); + if fi.colorframemouse <> avalue then begin + fi.colorframemouse:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorframeclicked(const avalue: colorty); +begin + include(flocalprops1,frl1_colorframeclicked); + if fi.colorframeclicked <> avalue then begin + fi.colorframeclicked:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorframedefault(const avalue: colorty); +begin + include(flocalprops1,frl1_colorframedefault); + if fi.colorframedefault <> avalue then begin + fi.colorframedefault:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolordkshadow(const avalue: colorty); +begin + include(flocalprops,frl_colordkshadow); + if fi.framecolors.edges.shadow.effectcolor <> avalue then begin + fi.framecolors.edges.shadow.effectcolor:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorshadow(const avalue: colorty); +begin + include(flocalprops,frl_colorshadow); + if fi.framecolors.edges.shadow.color <> avalue then begin + fi.framecolors.edges.shadow.color:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorlight(const avalue: colorty); +begin + include(flocalprops,frl_colorlight); + if fi.framecolors.edges.light.color <> avalue then begin + fi.framecolors.edges.light.color:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorhighlight(const avalue: colorty); +begin + include(flocalprops,frl_colorhighlight); + if fi.framecolors.edges.light.effectcolor <> avalue then begin + fi.framecolors.edges.light.effectcolor:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolordkwidth(const avalue: integer); +begin + include(flocalprops,frl_colordkwidth); + if fi.framecolors.edges.shadow.effectwidth <> avalue then begin + fi.framecolors.edges.shadow.effectwidth:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorhlwidth(const avalue: integer); +begin + include(flocalprops,frl_colorhlwidth); + if fi.framecolors.edges.light.effectwidth <> avalue then begin + fi.framecolors.edges.light.effectwidth:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.sethiddenedges(const avalue: edgesty); +begin + include(flocalprops,frl_hiddenedges); + if fi.hiddenedges <> avalue then begin + fi.hiddenedges:= avalue; + internalupdatestate; +// fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.settemplate(const avalue: tframecomp); +begin + fintf.getwidget.setlinkedvar(avalue,tmsecomponent(ftemplate)); +// if (avalue <> nil) and not (csloading in avalue.componentstate) then begin + if (avalue <> nil) and not (csreading in avalue.componentstate) then begin + assign(avalue); + end; +end; +{ +function tcustomframe.arepropsstored: boolean; +begin + result:= ftemplate = nil; +end; +} +procedure tcustomframe.settemplateinfo(const ainfo: frameinfoty); +begin + with fi do begin + if not (frl_levelo in flocalprops) then begin + levelo:= ainfo.ba.levelo; + end; + if not (frl_leveli in flocalprops) then begin + leveli:= ainfo.ba.leveli; + end; + if not (frl_framewidth in flocalprops) then begin + framewidth:= ainfo.ba.framewidth; + end; +// if not (frl_extraspace in flocalprops) then begin +// extraspace:= ainfo.extraspace; +// end; + if not (frl_colorframe in flocalprops) then begin + colorframe:= ainfo.ba.colorframe; + end; + if not (frl_colorframeactive in flocalprops) then begin + colorframeactive:= ainfo.ba.colorframeactive; + end; + if not (frl1_colorframedisabled in flocalprops1) then begin + colorframedisabled:= ainfo.ba.colorframedisabled; + end; + if not (frl1_colorframemouse in flocalprops1) then begin + colorframemouse:= ainfo.ba.colorframemouse; + end; + if not (frl1_colorframeclicked in flocalprops1) then begin + colorframeclicked:= ainfo.ba.colorframeclicked; + end; + if not (frl1_colorframedefault in flocalprops1) then begin + colorframedefault:= ainfo.ba.colorframedefault; + end; + with framecolors.edges do begin + if not (frl_colordkshadow in flocalprops) then begin + shadow.effectcolor:= ainfo.ba.framecolors.edges.shadow.effectcolor; + end; + if not (frl_colorshadow in flocalprops) then begin + shadow.color:= ainfo.ba.framecolors.edges.shadow.color; + end; + if not (frl_colorlight in flocalprops) then begin + light.color:= ainfo.ba.framecolors.edges.light.color; + end; + if not (frl_colorhighlight in flocalprops) then begin + light.effectcolor:= ainfo.ba.framecolors.edges.light.effectcolor; + end; + if not (frl_colordkwidth in flocalprops) then begin + shadow.effectwidth:= ainfo.ba.framecolors.edges.shadow.effectwidth; + end; + if not (frl_colorhlwidth in flocalprops) then begin + light.effectwidth:= ainfo.ba.framecolors.edges.light.effectwidth; + end; + end; + if not (frl_hiddenedges in flocalprops) then begin + hiddenedges:= ainfo.ba.hiddenedges; + end; + if not (frl_fileft in flocalprops) then begin + innerframe.left:= ainfo.ba.innerframe.left; + end; + if not (frl_fitop in flocalprops) then begin + innerframe.top:= ainfo.ba.innerframe.top; + end; + if not (frl_firight in flocalprops) then begin + innerframe.right:= ainfo.ba.innerframe.right; + end; + if not (frl_fibottom in flocalprops) then begin + innerframe.bottom:= ainfo.ba.innerframe.bottom; + end; + + if not (frl1_foleft in flocalprops1) then begin + outerframe.left:= ainfo.ba.outerframe.left; + end; + if not (frl1_fotop in flocalprops1) then begin + outerframe.top:= ainfo.ba.outerframe.top; + end; + if not (frl1_foright in flocalprops1) then begin + outerframe.right:= ainfo.ba.outerframe.right; + end; + if not (frl1_fobottom in flocalprops1) then begin + outerframe.bottom:= ainfo.ba.outerframe.bottom; + end; + + if not (frl_frameimagelist in flocalprops) then begin + fintf.getwidget.setlinkedvar(ainfo.ba.frameimage_list, + tmsecomponent(frameimage_list)); + end; + if not (frl_frameimageleft in flocalprops) then begin + frameimage_left:= ainfo.ba.frameimage_left; + end; + if not (frl_frameimageright in flocalprops) then begin + frameimage_right:= ainfo.ba.frameimage_right; + end; + if not (frl_frameimagetop in flocalprops) then begin + frameimage_top:= ainfo.ba.frameimage_top; + end; + if not (frl_frameimagebottom in flocalprops) then begin + frameimage_bottom:= ainfo.ba.frameimage_bottom; + end; + with frameimage_offsets do begin + if not (frl_frameimageoffset in flocalprops) then begin + offset:= ainfo.ba.frameimage_offsets.offset; + end; + if not (frl_frameimageoffsetdisabled in flocalprops) then begin + disabled:= ainfo.ba.frameimage_offsets.disabled; + end; + if not (frl_frameimageoffsetmouse in flocalprops) then begin + mouse:= ainfo.ba.frameimage_offsets.mouse; + end; + if not (frl_frameimageoffsetclicked in flocalprops) then begin + clicked:= ainfo.ba.frameimage_offsets.clicked; + end; + if not (frl_frameimageoffsetfocused in flocalprops) then begin + focused:= ainfo.ba.frameimage_offsets.focused; + end; + if not (frl_frameimageoffsetactive in flocalprops) then begin + active:= ainfo.ba.frameimage_offsets.active; + end; + { + if not (frl_frameimageoffsetactivemouse in flocalprops) then begin + activemouse:= ainfo.ba.frameimage_offsets.activemouse; + end; + if not (frl_frameimageoffsetactiveclicked in flocalprops) then begin + activeclicked:= ainfo.ba.frameimage_offsets.activeclicked; + end; + } + end; + + if not (frl1_framefacelist in flocalprops1) then begin + fintf.getwidget.setlinkedvar(ainfo.ba.frameface_list, + tmsecomponent(frameface_list)); + end; + with frameface_offsets do begin + if not (frl1_framefaceoffset in flocalprops1) then begin + offset:= ainfo.ba.frameface_offsets.offset; + end; + if not (frl1_framefaceoffsetdisabled in flocalprops1) then begin + disabled:= ainfo.ba.frameface_offsets.disabled; + end; + if not (frl1_framefaceoffsetmouse in flocalprops1) then begin + mouse:= ainfo.ba.frameface_offsets.mouse; + end; + if not (frl1_framefaceoffsetclicked in flocalprops1) then begin + clicked:= ainfo.ba.frameface_offsets.clicked; + end; + if not (frl1_framefaceoffsetfocused in flocalprops1) then begin + focused:= ainfo.ba.frameface_offsets.focused; + end; + if not (frl1_framefaceoffsetactive in flocalprops1) then begin + active:= ainfo.ba.frameface_offsets.active; + end; + { + if not (frl1_framefaceoffsetactivemouse in flocalprops1) then begin + activemouse:= ainfo.ba.frameface_offsets.activemouse; + end; + if not (frl1_framefaceoffsetactiveclicked in flocalprops1) then begin + activeclicked:= ainfo.ba.frameface_offsets.activeclicked; + end; + } + end; + + if not (frl1_focusrectdist in flocalprops1) then begin + focusrectdist:= ainfo.ba.focusrectdist; + end; + if not (frl1_extraspace in flocalprops1) then begin + extraspace:= ainfo.ba.extraspace; + end; + if not (frl1_imagedist in flocalprops1) then begin + imagedist:= ainfo.ba.imagedist; + end; + if not (frl1_imagedist1 in flocalprops1) then begin + imagedist1:= ainfo.ba.imagedist1; + end; + if not (frl1_imagedist2 in flocalprops1) then begin + imagedist2:= ainfo.ba.imagedist2; + end; + + if not (frl_optionsskin in flocalprops) then begin + optionsskin:= ainfo.ba.optionsskin; + end; + + if not (frl_colorclient in flocalprops) then begin + colorclient:= ainfo.ba.colorclient; + end; + end; + internalupdatestate; +end; + +procedure tcustomframe.getpaintframe(var frame: framety); +begin + //dummy +end; + +function tcustomframe.outerframedim: sizety; +begin + checkstate(); + result.cx:= fouterframe.left + fouterframe.right; + result.cy:= fouterframe.top + fouterframe.bottom; +end; + +function tcustomframe.outerframecx: int32; +begin + checkstate(); + result:= fouterframe.left + fouterframe.right; +end; + +function tcustomframe.outerframecy: int32; +begin + checkstate(); + result:= fouterframe.top + fouterframe.bottom; +end; + +function tcustomframe.frameframedim: sizety; +begin + checkstate(); + result.cx:= fouterframe.left + fwidth.left + fwidth.right + fouterframe.right; + result.cy:= fouterframe.top + fwidth.top + fwidth.bottom + fouterframe.bottom; +end; + +function tcustomframe.frameframecx: int32; +begin + checkstate(); + result:= fouterframe.left + fwidth.left + fwidth.right + fouterframe.right; +end; + +function tcustomframe.frameframecy: int32; +begin + checkstate(); + result:= fouterframe.top + fwidth.top + fwidth.bottom + fouterframe.bottom; +end; + +function tcustomframe.paintframedim: sizety; +begin + checkstate(); + result.cx:= fpaintframe.left + fpaintframe.right; + result.cy:= fpaintframe.top + fpaintframe.bottom; +end; + +function tcustomframe.paintframecx: int32; +begin + checkstate(); + result:= fpaintframe.left + fpaintframe.right; +end; + +function tcustomframe.paintframecy: int32; +begin + checkstate(); + result:= fpaintframe.top + fpaintframe.bottom; +end; + +function tcustomframe.innerframedim: sizety; +begin + checkstate(); + result.cx:= finnerframe.left + finnerframe.right; + result.cy:= finnerframe.top + finnerframe.bottom; +// result.cx:= fouterframe.left + fpaintframe.left + fi.innerframe.left + +// fpaintframe.right + fouterframe.right + fi.innerframe.right; +// result.cy:= fouterframe.top + fpaintframe.top + fi.innerframe.top + +// fpaintframe.bottom + fouterframe.bottom + fi.innerframe.bottom; +end; + +function tcustomframe.innerframecx: int32; +begin + checkstate(); + result:= finnerframe.left + finnerframe.right; +end; + +function tcustomframe.innerframecy: int32; +begin + checkstate(); + result:= finnerframe.top + finnerframe.bottom; +end; + +function tcustomframe.outerframe: framety; +begin + checkstate; + result:= fouterframe; +end; + +function tcustomframe.paintframe: framety; +begin + checkstate; + result:= fpaintframe; +// result:= addframe(fouterframe,fpaintframe); +end; + +function tcustomframe.paintframedelta: framety; +begin + result:= subframe(paintframe,fouterframe); +end; + +function tcustomframe.innerframe: framety; +begin + checkstate; + result:= finnerframe; +// result:= addframe(fouterframe,fpaintframe); +// addframe1(result,fi.innerframe); +end; + +procedure tcustomframe.checktemplate(const sender: tobject); +begin + if sender = ftemplate then begin + assign(tpersistent(sender)); + end; +end; + +procedure tcustomframe.assign(source: tpersistent); +begin + if source is tcustomframe then begin + if not (csdesigning in fintf.getcomponentstate) then begin + flocalprops:= allframelocalprops; + flocalprops1:= allframelocalprops1; + fi:= tcustomframe(source).fi; + internalupdatestate; + end; + end + else begin + inherited; + end; +end; + +procedure tcustomframe.dokeydown(var info: keyeventinfoty); +begin + //dummy +end; + +procedure tcustomframe.poschanged; +begin + //dummy +end; + +procedure tcustomframe.visiblechanged; +begin + //dummy +end; + +procedure tcustomframe.parentfontchanged; +begin + //dummy +end; + +procedure tcustomframe.setdisabled(const value: boolean); +begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_disabled),value); + with fi do begin + if (frameimage_list <> nil) and (frameimage_offsetdisabled <> 0) or + (frameface_list <> nil) and (frameface_offsetdisabled <> 0) then begin + fintf.getwidget.invalidatewidget; + end; + end; +end; + +function tcustomframe.pointincaption(const point: pointty): boolean; +begin + result:= false; //dummy +end; + +procedure tcustomframe.initgridframe; +begin + leveli:= 0; + levelo:= 0; + colorclient:= cl_transparent; +end; + +function tcustomframe.islevelostored: boolean; +begin + result:= (ftemplate = nil) or (frl_levelo in flocalprops); +end; + +function tcustomframe.islevelistored: boolean; +begin + result:= (ftemplate = nil) or (frl_leveli in flocalprops); +end; + +function tcustomframe.isframewidthstored: boolean; +begin + result:= (ftemplate = nil) or (frl_framewidth in flocalprops); +end; + +function tcustomframe.iscolorframestored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorframe in flocalprops); +end; + +function tcustomframe.iscolorframeactivestored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorframeactive in flocalprops); +end; + +function tcustomframe.iscolorframedisabledstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_colorframedisabled in flocalprops1); +end; + +function tcustomframe.iscolorframemousestored: boolean; +begin + result:= (ftemplate = nil) or (frl1_colorframemouse in flocalprops1); +end; + +function tcustomframe.iscolorframeclickedstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_colorframeclicked in flocalprops1); +end; + +function tcustomframe.iscolorframedefaultstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_colorframedefault in flocalprops1); +end; + +function tcustomframe.iscolordkshadowstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colordkshadow in flocalprops); +end; + +function tcustomframe.iscolorshadowstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorshadow in flocalprops); +end; + +function tcustomframe.iscolorlightstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorlight in flocalprops); +end; + +function tcustomframe.iscolorhighlightstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorhighlight in flocalprops); +end; + +function tcustomframe.iscolordkwidthstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colordkwidth in flocalprops); +end; + +function tcustomframe.iscolorhlwidthstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorhlwidth in flocalprops); +end; + +function tcustomframe.ishiddenedgesstored: boolean; +begin + result:= (ftemplate = nil) or (frl_hiddenedges in flocalprops); +end; + +function tcustomframe.isfibottomstored: boolean; +begin + result:= (ftemplate = nil) or (frl_fibottom in flocalprops); +end; + +function tcustomframe.isfileftstored: boolean; +begin + result:= (ftemplate = nil) or (frl_fileft in flocalprops); +end; + +function tcustomframe.isfirightstored: boolean; +begin + result:= (ftemplate = nil) or (frl_firight in flocalprops); +end; + +function tcustomframe.isfitopstored: boolean; +begin + result:= (ftemplate = nil) or (frl_fitop in flocalprops); +end; + +function tcustomframe.isfobottomstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_fobottom in flocalprops1); +end; + +function tcustomframe.isfoleftstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_foleft in flocalprops1); +end; + +function tcustomframe.isforightstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_foright in flocalprops1); +end; + +function tcustomframe.isfotopstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_fotop in flocalprops1); +end; + +function tcustomframe.isframeimage_liststored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_list <> nil) or + (frl_frameimagelist in flocalprops); +end; + +function tcustomframe.isframeimage_leftstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_left <> 0) or + (frl_frameimageleft in flocalprops); +end; + +function tcustomframe.isframeimage_rightstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_right <> 0) or + (frl_frameimageright in flocalprops); +end; + +function tcustomframe.isframeimage_topstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_top <> 0) or + (frl_frameimagetop in flocalprops); +end; + +function tcustomframe.isframeimage_bottomstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_bottom <> 0) or + (frl_frameimagebottom in flocalprops); +end; + +function tcustomframe.isframeimage_offsetstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.offset <> 0) or + (frl_frameimageoffset in flocalprops); +end; + +function tcustomframe.isframeimage_offset1stored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.offset1 <> 0) or + (frl_frameimageoffset1 in flocalprops); +end; + +function tcustomframe.isframeimage_offsetdisabledstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.disabled <> 0) or + (frl_frameimageoffsetdisabled in flocalprops); +end; + +function tcustomframe.isframeimage_offsetmousestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.mouse <> 0) or + (frl_frameimageoffsetmouse in flocalprops); +end; + +function tcustomframe.isframeimage_offsetclickedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.clicked <> 0) or + (frl_frameimageoffsetclicked in flocalprops); +end; + +function tcustomframe.isframeimage_offsetfocusedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.focused <> 0) or + (frl_frameimageoffsetfocused in flocalprops); +end; + +function tcustomframe.isframeimage_offsetactivestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.active <> 0) or + (frl_frameimageoffsetactive in flocalprops); +end; +{ +function tcustomframe.isframeimage_offsetactivemousestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.activemouse <> 0) or + (frl_frameimageoffsetactivemouse in flocalprops); +end; + +function tcustomframe.isframeimage_offsetactiveclickedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.activeclicked <> 0) or + (frl_frameimageoffsetactiveclicked in flocalprops); +end; +} +function tcustomframe.isframeface_liststored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_list <> nil) or + (frl1_framefacelist in flocalprops1); +end; + +function tcustomframe.isframeface_offsetstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.offset <> 0) or + (frl1_framefaceoffset in flocalprops1); +end; + +function tcustomframe.isframeface_offset1stored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.offset1 <> 0) or + (frl1_framefaceoffset1 in flocalprops1); +end; + +function tcustomframe.isframeface_offsetdisabledstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.disabled <> 0) or + (frl1_framefaceoffsetdisabled in flocalprops1); +end; + +function tcustomframe.isframeface_offsetmousestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.mouse <> 0) or + (frl1_framefaceoffsetmouse in flocalprops1); +end; + +function tcustomframe.isframeface_offsetclickedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.clicked <> 0) or + (frl1_framefaceoffsetclicked in flocalprops1); +end; + +function tcustomframe.isframeface_offsetfocusedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.focused <> 0) or + (frl1_framefaceoffsetfocused in flocalprops1); +end; + +function tcustomframe.isframeface_offsetactivestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.active <> 0) or + (frl1_framefaceoffsetactive in flocalprops1); +end; +{ +function tcustomframe.isframeface_offsetactivemousestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.activemouse <> 0) or + (frl1_framefaceoffsetactivemouse in flocalprops1); +end; + +function tcustomframe.isframeface_offsetactiveclickedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.activeclicked <> 0) or + (frl1_framefaceoffsetactiveclicked in flocalprops1); +end; +} +function tcustomframe.isoptionsskinstored: boolean; +begin + result:= (ftemplate = nil) or (frl_optionsskin in flocalprops); +end; + +function tcustomframe.iscolorclientstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorclient in flocalprops); +end; + +function tcustomframe.isfocusrectdiststored: boolean; +begin + result:= (ftemplate = nil) or (frl1_focusrectdist in flocalprops1); +end; + +function tcustomframe.isextraspacestored: boolean; +begin + result:= (ftemplate = nil) or (frl1_extraspace in flocalprops1); +end; + +function tcustomframe.isimagediststored: boolean; +begin + result:= (ftemplate = nil) or (frl1_imagedist in flocalprops1); +end; + +function tcustomframe.isimagedist1stored: boolean; +begin + result:= (ftemplate = nil) or (frl1_imagedist1 in flocalprops1); +end; + +function tcustomframe.isimagedist2stored: boolean; +begin + result:= (ftemplate = nil) or (frl1_imagedist2 in flocalprops1); +end; + +procedure tcustomframe.changedirection(const oldvalue: graphicdirectionty; + const newvalue: graphicdirectionty); +var + int1,int2: integer; + fra1: framety; +begin + int2:= ord(oldvalue)-ord(newvalue); + for int1:= 0 to 3 do begin + pintegeraty(@fra1)^[int1]:= + pintegeraty(@fi.innerframe)^[(int1+int2) and $3]; + end; + framei_left:= fra1.left; + framei_top:= fra1.top; + framei_right:= fra1.right; + framei_bottom:= fra1.bottom; + for int1:= 0 to 3 do begin + pintegeraty(@fra1)^[int1]:= + pintegeraty(@fi.outerframe)^[(int1+int2) and $3]; + end; + frameo_left:= fra1.left; + frameo_top:= fra1.top; + frameo_right:= fra1.right; + frameo_bottom:= fra1.bottom; +end; + +procedure tcustomframe.scale(const ascale: real); +begin + if ascale <> 1 then begin + with fi do begin + leveli:= round(leveli * ascale); + levelo:= round(levelo * ascale); + framewidth:= round(framewidth * ascale); + // extraspace:= round(extraspace * ascale); + framecolors.edges.shadow.effectwidth:= + round(framecolors.edges.shadow.effectwidth*ascale); + framecolors.edges.light.effectwidth:= + round(framecolors.edges.light.effectwidth*ascale); + framei_left:= round(framei_left * ascale); + framei_top:= round(framei_top * ascale); + framei_right:= round(framei_right * ascale); + framei_bottom:= round(framei_bottom * ascale); + focusrectdist:= round(focusrectdist * ascale); + end; + end; +end; + +procedure tcustomframe.fontcanvaschanged; +begin + //dummy +end; + +function tcustomframe.cellframe: framety; +begin + result.left:= finnerframe.left - fpaintframedelta.left; + result.top:= finnerframe.top - fpaintframedelta.top; + result.right:= finnerframe.right - fpaintframedelta.right; + result.bottom:= finnerframe.bottom - fpaintframedelta.bottom; +end; + +procedure tcustomframe.checkwidgetsize(var asize: sizety); +begin + //dummy +end; + +procedure tcustomframe.showhint(const aid: int32; var info: hintinfoty); +begin + //dummy +end; + +procedure tcustomframe.checkminscrollsize(var asize: sizety); +begin + //dummy +end; + +procedure tcustomframe.checkminclientsize(var asize: sizety); +begin + checkstate; + if not (fs_canclientextendx in fstate) or (asize.cx < fpaintrect.cx) then begin + asize.cx:= fpaintrect.cx; + end; + if not (fs_canclientextendy in fstate) or (asize.cy < fpaintrect.cy) then begin + asize.cy:= fpaintrect.cy; + end; +end; + +procedure tcustomframe.checkminshrinksize(var asize: sizety); +begin + //dummy +end; + +procedure tcustomframe.addscrollbarwidth(var asize: sizety); +begin + //dummy +end; + +procedure tcustomframe.subscrollbarwidth(var asize: sizety); +begin + //dummy +end; + +function tcustomframe.isoptional: boolean; +begin + result:= not fintf.getstaticframe; +end; + +procedure tcustomframe.defineproperties(filer: tfiler); +begin + filer.defineproperty('dummy',@readdummy,nil,false); + filer.defineproperty('frameimage_offsetactivemouse',@readdummy,nil,false); + filer.defineproperty('frameimage_offsetactiveclicked',@readdummy,nil,false); + filer.defineproperty('frameface_offsetactivemouse',@readdummy,nil,false); + filer.defineproperty('frameface_offsetactiveclicked',@readdummy,nil,false); + // inherited; //no dummy necessary because of localprops +end; + +{ tframetemplate } + +constructor tframetemplate.create(const owner: tmsecomponent; + const onchange: notifyeventty); +begin + initframeinfo(fi.ba); + initframeinfo(fi.capt); + inherited; +end; + +destructor tframetemplate.destroy; +begin + inherited; + fi.capt.font.free; +end; + +procedure tframetemplate.setcolorclient(const Value: colorty); +begin + fi.ba.colorclient:= Value; + changed; +end; + +procedure tframetemplate.setcolorframe(const Value: colorty); +begin + fi.ba.colorframe:= Value; + changed; +end; + +procedure tframetemplate.setcolorframeactive(const avalue: colorty); +begin + fi.ba.colorframeactive:= avalue; + changed; +end; + +procedure tframetemplate.setcolorframedisabled(const avalue: colorty); +begin + fi.ba.colorframedisabled:= avalue; + changed; +end; + +procedure tframetemplate.setcolorframemouse(const avalue: colorty); +begin + fi.ba.colorframemouse:= avalue; + changed; +end; + +procedure tframetemplate.setcolorframeclicked(const avalue: colorty); +begin + fi.ba.colorframeclicked:= avalue; + changed; +end; + +procedure tframetemplate.setcolorframedefault(const avalue: colorty); +begin + fi.ba.colorframedefault:= avalue; + changed; +end; + +procedure tframetemplate.setcolordkshadow(const avalue: colorty); +begin + fi.ba.framecolors.edges.shadow.effectcolor:= avalue; + changed; +end; + +procedure tframetemplate.setcolorshadow(const avalue: colorty); +begin + fi.ba.framecolors.edges.shadow.color:= avalue; + changed; +end; + +procedure tframetemplate.setcolorlight(const avalue: colorty); +begin + fi.ba.framecolors.edges.light.color:= avalue; + changed; +end; + +procedure tframetemplate.setcolorhighlight(const avalue: colorty); +begin + fi.ba.framecolors.edges.light.effectcolor:= avalue; + changed; +end; + +procedure tframetemplate.setcolordkwidth(const avalue: integer); +begin + fi.ba.framecolors.edges.shadow.effectwidth:= avalue; + changed; +end; + +procedure tframetemplate.setcolorhlwidth(const avalue: integer); +begin + fi.ba.framecolors.edges.light.effectwidth:= avalue; + changed; +end; + +procedure tframetemplate.setcolorglyph(const avalue: colorty); +begin + fi.ba.colorglyph:= avalue; + changed; +end; + +procedure tframetemplate.setcolorpattern(const avalue: colorty); +begin + fi.ba.colorpattern:= avalue; + changed; +end; + +procedure tframetemplate.sethiddenedges(const avalue: edgesty); +begin + fi.ba.hiddenedges:= avalue; + changed; +end; + +procedure tframetemplate.setframei_bottom(const Value: integer); +begin + fi.ba.innerframe.bottom := Value; + changed; +end; + +procedure tframetemplate.setframei_left(const Value: integer); +begin + fi.ba.innerframe.left := Value; + changed; +end; + +procedure tframetemplate.setframei_right(const Value: integer); +begin + fi.ba.innerframe.right := Value; + changed; +end; + +procedure tframetemplate.setframei_top(const Value: integer); +begin + fi.ba.innerframe.top := Value; + changed; +end; + +procedure tframetemplate.setframeo_bottom(const Value: integer); +begin + fi.ba.outerframe.bottom := Value; + changed; +end; + +procedure tframetemplate.setframeo_left(const Value: integer); +begin + fi.ba.outerframe.left := Value; + changed; +end; + +procedure tframetemplate.setframeo_right(const Value: integer); +begin + fi.ba.outerframe.right := Value; + changed; +end; + +procedure tframetemplate.setframeo_top(const Value: integer); +begin + fi.ba.outerframe.top := Value; + changed; +end; + +procedure tframetemplate.setframewidth(const Value: integer); +begin + fi.ba.framewidth := Value; + changed; +end; + +procedure tframetemplate.setextraspace(const avalue: integer); +begin + fi.ba.extraspace := avalue; + changed; +end; + +procedure tframetemplate.setimagedist(const avalue: integer); +begin + fi.ba.imagedist := avalue; + changed; +end; + +procedure tframetemplate.setimagedist1(const avalue: integer); +begin + fi.ba.imagedist1 := avalue; + changed; +end; + +procedure tframetemplate.setimagedist2(const avalue: integer); +begin + fi.ba.imagedist2 := avalue; + changed; +end; + +procedure tframetemplate.setleveli(const Value: integer); +begin + fi.ba.leveli := Value; + changed; +end; + +procedure tframetemplate.setlevelo(const Value: integer); +begin + fi.ba.levelo := Value; + changed; +end; + +procedure tframetemplate.setframeimage_list(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fi.ba.frameimage_list)); + changed; +end; + +function tframetemplate.getimagelist: timagelist; +begin + result:= fi.ba.frameimage_list; +end; + +procedure tframetemplate.setframeimage_left(const avalue: integer); +begin + fi.ba.frameimage_left:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_right(const avalue: integer); +begin + fi.ba.frameimage_right:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_top(const avalue: integer); +begin + fi.ba.frameimage_top:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_bottom(const avalue: integer); +begin + fi.ba.frameimage_bottom:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offset(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.offset:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offset1(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.offset1:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetdisabled(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.disabled:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetmouse(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.mouse:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetclicked(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.clicked:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetfocused(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.focused:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetactive(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.active:= avalue; + changed; +end; +{ +procedure tframetemplate.setframeimage_offsetactivemouse(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.activemouse:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetactiveclicked(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.activeclicked:= avalue; + changed; +end; +} +procedure tframetemplate.setframeface_list(const avalue: tfacelist); +begin + setlinkedvar(avalue,tmsecomponent(fi.ba.frameface_list)); + changed; +end; + +procedure tframetemplate.setframeface_offset(const avalue: facenrty); +begin + fi.ba.frameface_offsets.offset:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offset1(const avalue: facenrty); +begin + fi.ba.frameface_offsets.offset1:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetdisabled(const avalue: facenrty); +begin + fi.ba.frameface_offsets.disabled:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetmouse(const avalue: facenrty); +begin + fi.ba.frameface_offsets.mouse:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetclicked(const avalue: facenrty); +begin + fi.ba.frameface_offsets.clicked:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetfocused(const avalue: facenrty); +begin + fi.ba.frameface_offsets.focused:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetactive(const avalue: facenrty); +begin + fi.ba.frameface_offsets.active:= avalue; + changed; +end; +{ +procedure tframetemplate.setframeface_offsetactivemouse(const avalue: facenrty); +begin + fi.ba.frameface_offsets.activemouse:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetactiveclicked(const avalue: facenrty); +begin + fi.ba.frameface_offsets.activeclicked:= avalue; + changed; +end; +} +procedure tframetemplate.setoptionsskin(const avalue: frameskinoptionsty); +begin + fi.ba.optionsskin:= avalue; + changed; +end; + +function tframetemplate.getinfosize: integer; +begin +// result:= sizeof(fi.ba) - sizeof(fi.ba.frameface_list); + result:= ptruint(@fi.ba.frameface_list) - ptruint(@fi.ba); //copied by move +end; + +function tframetemplate.getinfoad: pointer; +begin + result:= @fi.ba; +end; + +procedure tframetemplate.doassignto(dest: tpersistent); +begin + if dest is tcustomframe then begin + with tcustomframe(dest) do begin + if (cs_loadedproc in fowner.msecomponentstate) or + (csloading in fintf.getcomponentstate) then begin +// if cs_updateskinproc in fintf.getmsecomponentstate then begin +// updatestate; +// end +// else begin + exclude(fstate,fs_paintposinited); +// end; + end; + settemplateinfo(self.fi); + end; +// with tcustomframe(dest) do begin +// fi:= self.fi; +// internalupdatestate; +// end; + end; +end; + +procedure tframetemplate.paintbackgroundframe(const acanvas: tcanvas; + const arect: rectty; const astate: framestateflagsty = []); +var + int1: integer; + +begin + if fi.ba.colorclient <> cl_transparent then begin + acanvas.fillrect(arect,fi.ba.colorclient); + end; + if fi.ba.frameface_list <> nil then begin + int1:= fi.ba.frameface_list.lookup( + calcframestateoffs(astate,frameoffsetsty(fi.ba.frameface_offsets))); + if (int1 >= 0){ and (int1 < fi.ba.frameface_list.list.count)} then begin + fi.ba.frameface_list.list[int1].paint(acanvas,arect); + end; + end; +end; + +procedure tframetemplate.paintoverlayframe(const acanvas: tcanvas; + const arect: rectty; const astate: framestateflagsty = []); +begin + tcustomframe.drawframe(acanvas,arect,fi.ba,astate); +end; + +procedure tframetemplate.paintbackground(const acanvas: tcanvas; + const arect: rectty; const astate: framestateflagsty = []); +var + bo1: boolean; +begin + if assigned(fonbeforetemplatepaintbackground) then begin + bo1:= false; + fonbeforetemplatepaintbackground(self,acanvas,arect,astate,bo1); + if bo1 then begin + paintbackgroundframe(acanvas, + inflaterect(arect,tcustomframe.calcpaintframe(fi.ba)),astate); + end; + if assigned(fonaftertemplatepaintbackground) then begin + fonaftertemplatepaintbackground(self,acanvas,arect,astate); + end; + end + else begin + paintbackgroundframe(acanvas, + inflaterect(arect,tcustomframe.calcpaintframe(fi.ba)),astate); + if assigned(fonaftertemplatepaintbackground) then begin + fonaftertemplatepaintbackground(self,acanvas,arect,astate); + end; + end; +end; + +procedure tframetemplate.paintoverlay(const acanvas: tcanvas; + const arect: rectty; const astate: framestateflagsty = []); +var + bo1: boolean; +begin + if assigned(fonbeforetemplatepaintoverlay) then begin + bo1:= false; + fonbeforetemplatepaintoverlay(self,acanvas,arect,astate,bo1); + if bo1 then begin + paintoverlayframe(acanvas, + inflaterect(arect,tcustomframe.calcpaintframe(fi.ba)),astate); + end; + if assigned(fonaftertemplatepaintoverlay) then begin + fonaftertemplatepaintoverlay(self,acanvas,arect,astate); + end; + end + else begin + paintoverlayframe(acanvas, + inflaterect(arect,tcustomframe.calcpaintframe(fi.ba)),astate); + if assigned(fonaftertemplatepaintoverlay) then begin + fonaftertemplatepaintoverlay(self,acanvas,arect,astate); + end; + end; +end; + +procedure tframetemplate.copyinfo(const source: tpersistenttemplate); +begin + with tframetemplate(source) do begin + setlinkedvar(frameimage_list,tmsecomponent(self.fi.ba.frameimage_list)); + setlinkedvar(frameface_list,tmsecomponent(fi.ba.frameface_list)); + if font <> nil then begin + self.createfont; + self.font.assign(font); + end + else begin + freeandnil(fi.capt.font); + end; + end; +end; + +procedure tframetemplate.readdummy(reader: treader); +begin + reader.readinteger(); +end; + +procedure tframetemplate.readimagedisttop(reader: treader); +begin + fi.ba.imagedist1:= reader.readinteger(); +end; + +procedure tframetemplate.readimagedistbottom(reader: treader); +begin + fi.ba.imagedist2:= reader.readinteger(); +end; + +procedure tframetemplate.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('imagedisttop',@readimagedisttop,nil,false); + filer.defineproperty('imagedistbottom',@readimagedistbottom,nil,false); + filer.defineproperty('frameimage_offsetactivemouse',@readdummy,nil,false); + filer.defineproperty('frameimage_offsetactiveclicked',@readdummy,nil,false); + filer.defineproperty('frameface_offsetactivemouse',@readdummy,nil,false); + filer.defineproperty('frameface_offsetactiveclicked',@readdummy,nil,false); +end; + +function tframetemplate.paintframe: framety; +begin + result:= tcustomframe.calcpaintframe(fi.ba); +end; + +function tframetemplate.innerframe: framety; +begin + result:= tcustomframe.calcinnerframe(fi.ba); +end; + +function tframetemplate.paintframedim: sizety; +var + fr1: framety; +begin + fr1:= tcustomframe.calcpaintframe(fi.ba); + result.cx:= fr1.left + fr1.right; + result.cy:= fr1.top + fr1.bottom; +end; + +function tframetemplate.innerframedim: sizety; +var + fr1: framety; +begin + fr1:= tcustomframe.calcinnerframe(fi.ba); + result.cx:= fr1.left + fr1.right; + result.cy:= fr1.top + fr1.bottom; +end; + +function tframetemplate.getfont: toptionalfont; +begin + fowner.getoptionalobject(fi.capt.font,{$ifdef FPC}@{$endif}createfont); + result:= fi.capt.font; +end; + +procedure tframetemplate.setfont(const avalue: toptionalfont); +begin + if fi.capt.font <> avalue then begin + fowner.setoptionalobject(avalue,fi.capt.font,{$ifdef FPC}@{$endif}createfont); + end; +end; + +procedure tframetemplate.setcaptiondist(const avalue: integer); +begin + fi.capt.captiondist:= avalue; + changed; +end; + +procedure tframetemplate.setcaptionoffset(const avalue: integer); +begin + fi.capt.captionoffset:= avalue; + changed; +end; + +procedure tframetemplate.setfocusrectdist(const avalue: integer); +begin + fi.ba.focusrectdist:= avalue; + changed; +end; + +procedure tframetemplate.createfont; +begin + if fi.capt.font = nil then begin + fi.capt.font:= toptionalfont.create; + fi.capt.font.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +procedure tframetemplate.fontchanged(const sender: tobject); +begin + changed; +end; + +function tframetemplate.isfontstored: boolean; +begin + result:= fi.capt.font <> nil; +end; + +{ tframecomp } + +function tframecomp.gettemplate: tframetemplate; +begin + result:= tframetemplate(ftemplate); +end; + +function tframecomp.gettemplateclass: templateclassty; +begin + result:= tframetemplate; +end; + +procedure tframecomp.settemplate(const Value: tframetemplate); +begin + ftemplate.Assign(value); +end; + + +{ tfacebitmap } + +constructor tfacebitmap.create(const aowner: tcustomface); +begin + fowner:= aowner; + inherited create(bmk_rgb); +end; + +procedure tfacebitmap.setx(const avalue: int32); +begin + if fpos.x <> avalue then begin + setpos(mp(avalue,fpos.y)); + end; +end; + +procedure tfacebitmap.sety(const avalue: int32); +begin + if fpos.y <> avalue then begin + setpos(mp(fpos.x,avalue)); + end; +end; + +procedure tfacebitmap.setpos(const avalue: pointty); +begin + if (avalue.x <> fpos.x) or (avalue.y <> fpos.y) then begin + if (fowner <> nil) then begin + if hasimage() then begin + if (alignment*[al_stretchx,al_stretchy, + al_tiled,al_fit,al_thumbnail] = []) then begin + fowner.fintf.invalidaterect(mr(fpos,fsize),org_paint); + fpos:= avalue; + fowner.fintf.invalidaterect(mr(fpos,fsize),org_paint); + end + else begin + fpos:= avalue; + change(); + end; + end + else begin + fpos:= avalue; + end; + end + else begin + fpos:= avalue; + change(); + end; + end; +end; + +function tfacebitmap.getcenter: pointty; +begin + result.x:= fpos.x - fsize.cx div 2; + result.y:= fpos.y - fsize.cy div 2; +end; + +procedure tfacebitmap.setcenter(avalue: pointty); +begin + avalue.x:= avalue.x - fsize.cx div 2; + avalue.y:= avalue.y - fsize.cy div 2; + pos:= avalue; +end; + +{ tcustomface } + +procedure tcustomface.internalcreate; +begin + fi.image:= tfacebitmap.create(self); + fi.image.onchange:= {$ifdef fpc}@{$endif}imagechanged; + fi.fade_pos:= trealarrayprop.create; + fi.fade_color:= tfadecolorarrayprop.create; + fi.fade_pos.link([fi.fade_color,fi.fade_pos]); + fi.fade_opapos:= trealarrayprop.create; + fi.fade_opacolor:= tfadeopacolorarrayprop.create; + fi.fade_opapos.link([fi.fade_opacolor,fi.fade_opapos]); + fi.fade_opacity:= cl_none; + fi.fade_pos.onchange:= {$ifdef fpc}@{$endif}dochange; + fi.fade_color.onchange:= {$ifdef fpc}@{$endif}dochange; + fi.fade_opapos.onchange:= {$ifdef fpc}@{$endif}dochange; + fi.fade_opacolor.onchange:= {$ifdef fpc}@{$endif}dochange; +end; + +constructor tcustomface.create; +begin + inherited; +// internalcreate; +end; + +constructor tcustomface.create(const owner: twidget); +begin + fintf:= iface(owner); + owner.fface:= self; + internalcreate; +end; + +constructor tcustomface.create(const intf: iface); +begin + fintf:= intf; + internalcreate; +end; + +destructor tcustomface.destroy; +begin + if ftemplate <> nil then begin + fintf.setlinkedvar(nil,tmsecomponent(ftemplate)); + end; + inherited; + fi.image.Free; + fi.fade_pos.Free; + fi.fade_color.free; + fi.fade_opapos.Free; + fi.fade_opacolor.free; + falphabuffer.Free; +end; + +procedure tcustomface.change; +begin + fintf.invalidatewidget(); //face can be element of frame (tcustomstepframe) +end; + +procedure updatefadearray(var fi: faceinfoty; const sender: tarrayprop); +var + ar1: integerarty; +begin + if sender = fi.fade_pos then begin + with trealarrayprop1(fi.fade_pos) do begin + if high(fitems) >= 0 then begin + sortarray(trealarrayprop1(fi.fade_pos).fitems,ar1); + fitems[0]:= 0; + if high(fitems) > 0 then begin + fitems[high(fitems)]:= 1; + end; + fi.fade_color.order(ar1); + end; + end; + end + else begin + if sender = fi.fade_opapos then begin + with trealarrayprop1(fi.fade_opapos) do begin + if high(fitems) >= 0 then begin + sortarray(trealarrayprop1(fi.fade_opapos).fitems,ar1); + fitems[0]:= 0; + if high(fitems) > 0 then begin + fitems[high(fitems)]:= 1; + end; + fi.fade_opacolor.order(ar1); + end; + end; + end; + end; +end; + +procedure tcustomface.dochange(const sender: tarrayprop; const index: integer); +begin + updatefadearray(fi,sender); + change; +end; + +procedure tcustomface.imagechanged(const sender: tobject); +begin + change; + if not (csloading in fintf.getcomponentstate) then begin + include(flocalprops,fal_image); + end; +end; + +procedure tcustomface.checktemplate(const sender: tobject); +begin + if sender = ftemplate then begin + assign(tpersistent(sender)); + end; +end; + +procedure tcustomface.assign(source: tpersistent); +begin + if source is tcustomface then begin + if not (csdesigning in fintf.getcomponentstate) then begin + flocalprops:= allfacelocalprops; + with tcustomface(source) do begin + self.fade_direction:= fade_direction; + self.fade_color:= fade_color; + self.fade_pos:= fade_pos; + self.fade_opacolor:= fade_opacolor; + self.fade_opapos:= fade_opapos; + self.fade_opacity:= fade_opacity; + self.image:= image; + self.options:= options; + self.framei_left:= framei_left; + self.framei_top:= framei_top; + self.framei_right:= framei_right; + self.framei_bottom:= framei_bottom; + end; + end; + end + else begin + inherited; + end; +end; + +procedure facepaint(const canvas: tcanvas; const arect: rectty; + const fi: faceinfoty; const fintf: iface1; + var falphabuffer: tmaskedbitmap; var falphabufferdest: pointty); + +var + rect,rect1: rectty; + + procedure createalphabuffer(const amasked: boolean); + begin + if falphabuffer = nil then begin + falphabuffer:= tmaskedbitmap.create(bmk_rgb); + end; + if amasked then begin + falphabuffer.options:= [bmo_masked,bmo_colormask]; + end; + falphabuffer.size:= rect1.size; + falphabufferdest:= rect1.pos; + falphabuffer.canvas.copyarea(canvas,rect1,nullpoint); + end; + +var + pixelscale: real; + vert: boolean; + alpha: boolean; + startpix,pixcount: integer; + + procedure calcfade(const fadepos: trealarrayprop; + const fadecolor: tcolorarrayprop; const bmp: tbitmap); + var + posar: realarty; + rgbs: array of rgbtriplety; + int1,int2: integer; + po1,pe: prgbtriplety; + pixelstep: real; + pixinc: integer; + curpix,nextpix: integer; + redsum,greensum,bluesum,lengthsum: real; + curnode,nextnode: integer; + rea1,rea2: real; + opar,opag,opab: int32; + co1: rgbtriplety; + col1,col2: prgbtriplety; + + begin + posar:= trealarrayprop1(fadepos).fitems; + with tfadecolorarrayprop(fadecolor) do begin + setlength(rgbs,length(fitems)); + for int1:= 0 to high(rgbs) do begin + rgbs[int1]:= colortorgb(fintf.translatecolor(fitems[int1])); + end; + if alpha then begin + po1:= pointer(rgbs); + pe:= po1+length(rgbs); + while po1 < pe do begin + po1^.red:= 255-po1^.red; + po1^.green:= 255-po1^.green; + po1^.blue:= 255-po1^.blue; + inc(po1); + end; + end; + end; + if fadecolor = fi.fade_opacolor then begin + co1:= colortorgb(fi.fade_opacity); + opar:= (co1.red * 256) div 255; + opag:= (co1.green * 256) div 255; + opab:= (co1.blue * 256) div 255; + end + else begin + opar:= 256; + opag:= 256; + opab:= 256; + end; + if high(rgbs) > 0 then begin + po1:= bmp.scanline[0]; + pixelstep:= 1/pixelscale; + pixinc:= sizeof(rgbtriplety); + if fi.fade_direction in [gd_up,gd_left] then begin //revert + if fi.fade_direction = gd_left then begin + startpix:= rect.x+rect.cx-rect1.x-rect1.cx; + end + else begin + startpix:= rect.y+rect.cy-rect1.y-rect1.cy; + end; + inc(po1,pixcount-1); + pixinc:= -pixinc; + end; + curnode:= 0; + int1:= 0; + while int1 < pixcount do begin + rea1:= (int1+startpix)*pixelstep + 0.000001; + if int1 = 0 then begin + while posar[curnode] < rea1 do begin + inc(curnode); + end; + dec(curnode); + end; + nextnode:= curnode; + rea1:= rea1 + pixelstep; + while (posar[nextnode] < rea1) and (nextnode < high(posar)) do begin + inc(nextnode); + end; + if nextnode > curnode+1 then begin //calc average + redsum:= 0; + greensum:= 0; + bluesum:= 0; + lengthsum:= 0; + for int2:= curnode to nextnode - 2 do begin //todo: optimize + rea1:= posar[int2+1] - posar[int2]; + redsum:= redsum + (rgbs[int2].red+rgbs[int2+1].red)*rea1; + greensum:= greensum + (rgbs[int2].green+rgbs[int2+1].green)*rea1; + bluesum:= bluesum + (rgbs[int2].blue+rgbs[int2+1].blue)*rea1; + lengthsum:= lengthsum + rea1; + end; + if lengthsum > 0 then begin + rea1:= 1/(2*lengthsum); + with po1^ do begin + red:= (round(redsum*rea1)*opar) div 256; + green:= (round(greensum*rea1)*opag) div 256; + blue:= (round(bluesum*rea1)*opab) div 256; + res:= 0; + end; + end + else begin + po1^:= rgbs[curnode]; + end; + dec(nextnode); + end + else begin + nextpix:= trunc(posar[nextnode]*pixelscale)-startpix; + if int1 = nextpix then begin + po1^:= rgbs[curnode]; + end + else begin + curpix:= trunc(posar[curnode]*pixelscale)-startpix; + if nextpix = curpix then begin + rea1:= 1; + end + else begin + rea1:= 1/(nextpix-curpix); + end; + if nextpix > pixcount then begin + nextpix:= pixcount; + end; + col1:= @rgbs[curnode]; + col2:= @rgbs[nextnode]; + for int2:= int1-curpix to nextpix-curpix-1 do begin + rea2:= rea1*int2; + with po1^ do begin + res:= 0; + red:= ((col1^.red + + round((col2^.red-col1^.red)*rea2))*opar) div 256; + green:= ((col1^.green + + round((col2^.green-col1^.green)*rea2))*opag) div 256; + blue:= ((col1^.blue + + round((col2^.blue-col1^.blue)*rea2))*opab) div 256; + end; + inc(pchar(po1),pixinc); + end; + dec(pchar(po1),pixinc); + int1:= nextpix-1; + end; + end; + curnode:= nextnode; + inc(int1); + inc(pchar(po1),pixinc); + end; + end + else begin //count = 1 + co1.red:= (rgbs[0].red*opar) div 256; + co1.green:= (rgbs[0].green*opag) div 256; + co1.blue:= (rgbs[0].blue*opag) div 256; + co1.res:= 0; + if vert then begin + bmp.canvas.drawline(nullpoint,makepoint(0,rect1.cy-1),colorty(co1)); + end + else begin + bmp.canvas.drawline(nullpoint,makepoint(rect1.cx-1,0),colorty(co1)); + end; + end; + end; //calcfade + +var + bmp: tmaskedbitmap; + reg1: regionty; + + procedure paintimage(const canvas: tcanvas); + begin + if fi.image.hasimage then begin + fi.image.paint(canvas,mr(addpoint(rect.pos,fi.image.fpos),rect.size)); + if fao_alphafadeimage in fi.options then begin + if falphabuffer <> nil then begin + falphabuffer.paint(canvas,falphabufferdest); + freeandnil(falphabuffer); + end; + end; + end; + if fi.frameimage_list <> nil then begin + if reg1 <> 0 then begin + canvas.clipregion:= reg1; + reg1:= 0; + end; + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset,arect.pos); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+1, + makerect(arect.x, + arect.y+fi.frameimage_list.height, + fi.frameimage_list.width, + arect.cy-2*fi.frameimage_list.height),[al_stretchy]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+2,arect,[al_bottom]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+3, + makerect(arect.x+fi.frameimage_list.width, + arect.y+arect.cy-fi.frameimage_list.height, + arect.cx-2*fi.frameimage_list.width, + fi.frameimage_list.height),[al_stretchx]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+4,arect, + [al_bottom,al_right]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+5, + makerect(arect.x+arect.cx-fi.frameimage_list.width, + arect.y+fi.frameimage_list.height, + fi.frameimage_list.width, + arect.cy-2*fi.frameimage_list.height),[al_stretchy]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+6,arect,[al_right]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+7, + makerect(arect.x+fi.frameimage_list.width,arect.y, + arect.cx-2*fi.frameimage_list.width, + fi.frameimage_list.height),[al_stretchx]); + end; + end; //paintimage +begin + reg1:= 0; + rect:= deflaterect(arect,fi.framei); + if intersectrect(rect,canvas.clipbox,rect1) or + testintersectrect(arect,canvas.clipbox) then begin + if (fi.frameimage_list <> nil) and + fi.frameimage_list.hascornermask then begin + reg1:= canvas.copyclipregion(); + fi.frameimage_list.clipcornermask(canvas,arect,[]); + end; + + alpha:= fi.options * faceoptionsmask1 <> []; + if fi.options * [fao_fadeoverlay,fao_alphaimage] = + [fao_fadeoverlay] then begin + paintimage(canvas); + end; + if (fi.fade_color.count > 0) and (rect1.cx > 0) and (rect1.cy > 0) then begin + if (fi.fade_color.count > 1) or + ((fi.fade_opacolor.count > 0) or (fi.fade_opacity <> cl_none)) and + (fi.options * faceoptionsmask1 = []) then begin + case fi.fade_direction of + gd_up,gd_down: begin + pixelscale:= rect.cy; + vert:= true; + startpix:= rect1.y-rect.y; + pixcount:= rect1.cy; + end + else begin //gd_right,gd_left + pixelscale:= rect.cx; + vert:= false; + startpix:= rect1.x-rect.x; + pixcount:= rect1.cx; + end; + end; + bmp:= tmaskedbitmap.create(bmk_rgb); + if vert then begin + bmp.size:= makesize(1,rect1.cy); + end + else begin + bmp.size:= makesize(rect1.cx,1); + end; + calcfade(fi.fade_pos,fi.fade_color,bmp); + if fi.options * faceoptionsmask1 = [] then begin + if fi.fade_opapos.count > 0 then begin + bmp.colormask:= true; + calcfade(fi.fade_opapos,fi.fade_opacolor,bmp.mask); + end + else begin + bmp.opacity:= fi.fade_opacity; + end; + bmp.paint(canvas,rect1,[al_stretchx,al_stretchy]); + end + else begin + createalphabuffer(true); + bmp.paint(falphabuffer.mask.canvas,makerect(nullpoint,rect1.size), + makerect(nullpoint,bmp.size),[al_stretchx,al_stretchy]); + end; + bmp.Free; + end + else begin //fade_color.count = 1 + if alpha then begin + if fao_alphaimage in fi.options then begin + createalphabuffer(true); + falphabuffer.mask.canvas.fillrect(mr(nullpoint,rect1.size), + invertcolor(tfadecolorarrayprop1(fi.fade_color).fitems[0])); + end + else begin + createalphabuffer(false); + falphabuffer.opacity:= + invertcolor(tfadecolorarrayprop1(fi.fade_color).fitems[0]); + end; + end + else begin + canvas.fillrect(rect1,tfadecolorarrayprop1(fi.fade_color).fitems[0]); + end; + end; + end + else begin //fade_color.count = 0 + if alpha then begin + if fao_alphaimage in fi.options then begin + createalphabuffer(true); + falphabuffer.mask.canvas.fillrect(mr(nullpoint,rect1.size), + invertcolor(fi.fade_opacity)); + end + else begin + createalphabuffer(false); + falphabuffer.opacity:= invertcolor(fi.fade_opacity); + end; + end; + end; + if fi.options * [fao_fadeoverlay,fao_alphaimage] = [] then begin + paintimage(canvas); + end; + if (fao_alphaimage in fi.options) and (falphabuffer <> nil) then begin + falphabuffer.mask.canvas.origin:= subpoint(rect.pos,rect1.pos); + paintimage(falphabuffer.mask.canvas); + falphabuffer.mask.canvas.origin:= nullpoint; + end; + end; + if reg1 <> 0 then begin + canvas.clipregion:= reg1; + end; +end; + +procedure tcustomface.internalpaint(const canvas: tcanvas; const arect: rectty); +begin + facepaint(canvas,arect,fi,fintf,falphabuffer,falphabufferdest); +end; + +(* +procedure tcustomface.internalpaint(const canvas: tcanvas; const arect: rectty); + +var + rect,rect1: rectty; + + procedure createalphabuffer(const amasked: boolean); + begin + if falphabuffer = nil then begin + falphabuffer:= tmaskedbitmap.create(bmk_rgb); + end; + if amasked then begin + falphabuffer.options:= [bmo_masked,bmo_colormask]; + end; + falphabuffer.size:= rect1.size; + falphabufferdest:= rect1.pos; + falphabuffer.canvas.copyarea(canvas,rect1,nullpoint); + end; + +var + pixelscale: real; + vert: boolean; + alpha: boolean; + startpix,pixcount: integer; + + procedure calcfade(const fadepos: trealarrayprop; + const fadecolor: tcolorarrayprop; const bmp: tbitmap); + var + posar: realarty; + rgbs: array of rgbtriplety; + int1,int2: integer; + po1,pe: prgbtriplety; + pixelstep: real; + pixinc: integer; + curpix,nextpix: integer; + redsum,greensum,bluesum,lengthsum: real; + curnode,nextnode: integer; + rea1,rea2: real; + opar,opag,opab: int32; + co1: rgbtriplety; + col1,col2: prgbtriplety; + + begin + posar:= trealarrayprop1(fadepos).fitems; + with tfadecolorarrayprop(fadecolor) do begin + setlength(rgbs,length(fitems)); + for int1:= 0 to high(rgbs) do begin + rgbs[int1]:= colortorgb(fintf.translatecolor(fitems[int1])); + end; + if alpha then begin + po1:= pointer(rgbs); + pe:= po1+length(rgbs); + while po1 < pe do begin + po1^.red:= 255-po1^.red; + po1^.green:= 255-po1^.green; + po1^.blue:= 255-po1^.blue; + inc(po1); + end; + end; + end; + if fadecolor = fi.fade_opacolor then begin + co1:= colortorgb(fade_opacity); + opar:= (co1.red * 256) div 255; + opag:= (co1.green * 256) div 255; + opab:= (co1.blue * 256) div 255; + end + else begin + opar:= 256; + opag:= 256; + opab:= 256; + end; + if high(rgbs) > 0 then begin + po1:= bmp.scanline[0]; + pixelstep:= 1/pixelscale; + pixinc:= sizeof(rgbtriplety); + if fi.fade_direction in [gd_up,gd_left] then begin //revert + if fi.fade_direction = gd_left then begin + startpix:= rect.x+rect.cx-rect1.x-rect1.cx; + end + else begin + startpix:= rect.y+rect.cy-rect1.y-rect1.cy; + end; + inc(po1,pixcount-1); + pixinc:= -pixinc; + end; + curnode:= 0; + int1:= 0; + while int1 < pixcount do begin + rea1:= (int1+startpix)*pixelstep + 0.000001; + if int1 = 0 then begin + while posar[curnode] < rea1 do begin + inc(curnode); + end; + dec(curnode); + end; + nextnode:= curnode; + rea1:= rea1 + pixelstep; + while (posar[nextnode] < rea1) and (nextnode < high(posar)) do begin + inc(nextnode); + end; + if nextnode > curnode+1 then begin //calc average + redsum:= 0; + greensum:= 0; + bluesum:= 0; + lengthsum:= 0; + for int2:= curnode to nextnode - 2 do begin //todo: optimize + rea1:= posar[int2+1] - posar[int2]; + redsum:= redsum + (rgbs[int2].red+rgbs[int2+1].red)*rea1; + greensum:= greensum + (rgbs[int2].green+rgbs[int2+1].green)*rea1; + bluesum:= bluesum + (rgbs[int2].blue+rgbs[int2+1].blue)*rea1; + lengthsum:= lengthsum + rea1; + end; + if lengthsum > 0 then begin + rea1:= 1/(2*lengthsum); + with po1^ do begin + red:= (round(redsum*rea1)*opar) div 256; + green:= (round(greensum*rea1)*opag) div 256; + blue:= (round(bluesum*rea1)*opab) div 256; + res:= 0; + end; + end + else begin + po1^:= rgbs[curnode]; + end; + dec(nextnode); + end + else begin + nextpix:= trunc(posar[nextnode]*pixelscale)-startpix; + if int1 = nextpix then begin + po1^:= rgbs[curnode]; + end + else begin + curpix:= trunc(posar[curnode]*pixelscale)-startpix; + if nextpix = curpix then begin + rea1:= 1; + end + else begin + rea1:= 1/(nextpix-curpix); + end; + if nextpix > pixcount then begin + nextpix:= pixcount; + end; + col1:= @rgbs[curnode]; + col2:= @rgbs[nextnode]; + for int2:= int1-curpix to nextpix-curpix-1 do begin + rea2:= rea1*int2; + with po1^ do begin + res:= 0; + red:= ((col1^.red + + round((col2^.red-col1^.red)*rea2))*opar) div 256; + green:= ((col1^.green + + round((col2^.green-col1^.green)*rea2))*opag) div 256; + blue:= ((col1^.blue + + round((col2^.blue-col1^.blue)*rea2))*opab) div 256; + end; + inc(pchar(po1),pixinc); + end; + dec(pchar(po1),pixinc); + int1:= nextpix-1; + end; + end; + curnode:= nextnode; + inc(int1); + inc(pchar(po1),pixinc); + end; + end + else begin //count = 1 + co1.red:= (rgbs[0].red*opar) div 256; + co1.green:= (rgbs[0].green*opag) div 256; + co1.blue:= (rgbs[0].blue*opag) div 256; + co1.res:= 0; + if vert then begin + bmp.canvas.drawline(nullpoint,makepoint(0,rect1.cy-1),colorty(co1)); + end + else begin + bmp.canvas.drawline(nullpoint,makepoint(rect1.cx-1,0),colorty(co1)); + end; + end; + end; //calcfade + +var + bmp: tmaskedbitmap; + reg1: regionty; + + procedure paintimage(const canvas: tcanvas); + begin + if fi.image.hasimage then begin + fi.image.paint(canvas,mr(addpoint(rect.pos,fi.image.fpos),rect.size)); + if fao_alphafadeimage in fi.options then begin + doalphablend(canvas); + end; + end; + if fi.frameimage_list <> nil then begin + if reg1 <> 0 then begin + canvas.clipregion:= reg1; + reg1:= 0; + end; + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset,arect.pos); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+1, + makerect(arect.x, + arect.y+fi.frameimage_list.height, + fi.frameimage_list.width, + arect.cy-2*fi.frameimage_list.height),[al_stretchy]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+2,arect,[al_bottom]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+3, + makerect(arect.x+fi.frameimage_list.width, + arect.y+arect.cy-fi.frameimage_list.height, + arect.cx-2*fi.frameimage_list.width, + fi.frameimage_list.height),[al_stretchx]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+4,arect, + [al_bottom,al_right]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+5, + makerect(arect.x+arect.cx-fi.frameimage_list.width, + arect.y+fi.frameimage_list.height, + fi.frameimage_list.width, + arect.cy-2*fi.frameimage_list.height),[al_stretchy]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+6,arect,[al_right]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+7, + makerect(arect.x+fi.frameimage_list.width,arect.y, + arect.cx-2*fi.frameimage_list.width, + fi.frameimage_list.height),[al_stretchx]); + end; + end; //paintimage +begin + reg1:= 0; + rect:= deflaterect(arect,fi.framei); + if intersectrect(rect,canvas.clipbox,rect1) or + testintersectrect(arect,canvas.clipbox) then begin + if (fi.frameimage_list <> nil) and + fi.frameimage_list.hascornermask then begin + reg1:= canvas.copyclipregion(); + fi.frameimage_list.clipcornermask(canvas,arect,[]); + end; + + alpha:= fi.options * faceoptionsmask1 <> []; + if options * [fao_fadeoverlay,fao_alphaimage] = [fao_fadeoverlay] then begin + paintimage(canvas); + end; + if (fi.fade_color.count > 0) and (rect1.cx > 0) and (rect1.cy > 0) then begin + if (fi.fade_color.count > 1) or + ((fi.fade_opacolor.count > 0) or (fi.fade_opacity <> cl_none)) and + (fi.options * faceoptionsmask1 = []) then begin + case fi.fade_direction of + gd_up,gd_down: begin + pixelscale:= rect.cy; + vert:= true; + startpix:= rect1.y-rect.y; + pixcount:= rect1.cy; + end + else begin //gd_right,gd_left + pixelscale:= rect.cx; + vert:= false; + startpix:= rect1.x-rect.x; + pixcount:= rect1.cx; + end; + end; + bmp:= tmaskedbitmap.create(bmk_rgb); + if vert then begin + bmp.size:= makesize(1,rect1.cy); + end + else begin + bmp.size:= makesize(rect1.cx,1); + end; + calcfade(fi.fade_pos,fi.fade_color,bmp); + if fi.options * faceoptionsmask1 = [] then begin + if fi.fade_opapos.count > 0 then begin + bmp.colormask:= true; + calcfade(fi.fade_opapos,fi.fade_opacolor,bmp.mask); + end + else begin + bmp.opacity:= fi.fade_opacity; + end; + bmp.paint(canvas,rect1,[al_stretchx,al_stretchy]); + end + else begin + createalphabuffer(true); + bmp.paint(falphabuffer.mask.canvas,makerect(nullpoint,rect1.size), + makerect(nullpoint,bmp.size),[al_stretchx,al_stretchy]); + end; + bmp.Free; + end + else begin //fade_color.count = 1 + if alpha then begin + if fao_alphaimage in fi.options then begin + createalphabuffer(true); + falphabuffer.mask.canvas.fillrect(mr(nullpoint,rect1.size), + invertcolor(tfadecolorarrayprop1(fi.fade_color).fitems[0])); + end + else begin + createalphabuffer(false); + falphabuffer.opacity:= + invertcolor(tfadecolorarrayprop1(fi.fade_color).fitems[0]); + end; + end + else begin + canvas.fillrect(rect1,tfadecolorarrayprop1(fi.fade_color).fitems[0]); + end; + end; + end + else begin //fade_color.count = 0 + if alpha then begin + if fao_alphaimage in fi.options then begin + createalphabuffer(true); + falphabuffer.mask.canvas.fillrect(mr(nullpoint,rect1.size), + invertcolor(fi.fade_opacity)); + end + else begin + createalphabuffer(false); + falphabuffer.opacity:= invertcolor(fi.fade_opacity); + end; + end; + end; + if options * [fao_fadeoverlay,fao_alphaimage] = [] then begin + paintimage(canvas); + end; + if (fao_alphaimage in fi.options) and (falphabuffer <> nil) then begin + falphabuffer.mask.canvas.origin:= subpoint(rect.pos,rect1.pos); + paintimage(falphabuffer.mask.canvas); + falphabuffer.mask.canvas.origin:= nullpoint; + end; + end; + if reg1 <> 0 then begin + canvas.clipregion:= reg1; + end; +end; +*) +procedure tcustomface.paint(const canvas: tcanvas; const arect: rectty); +var + bo1: boolean; +begin + if ftemplate <> nil then begin + if assigned(tfacetemplate(ftemplate.template).fonbeforepaint) then begin + bo1:= false; + tfacetemplate(ftemplate.template).fonbeforepaint(self,canvas,arect,bo1); + if not bo1 then begin + internalpaint(canvas,arect); + end; + end + else begin + internalpaint(canvas,arect); + end; + if assigned(tfacetemplate(ftemplate.template).fonafterpaint) then begin + tfacetemplate(ftemplate.template).fonafterpaint(self,canvas,arect); + end; + end + else begin + internalpaint(canvas,arect); + end; +end; + +procedure tcustomface.doalphablend(const canvas: tcanvas); +begin + if falphabuffer <> nil then begin + falphabuffer.paint(canvas,falphabufferdest); + freeandnil(falphabuffer); + end; +end; + +procedure tcustomface.setimage(const value: tfacebitmap); +begin + fi.image.assign(value); +end; + +procedure tcustomface.setoptions(const avalue: faceoptionsty); +var + optionsbefore: faceoptionsty; +begin + include(flocalprops,fal_options); + if avalue <> fi.options then begin + optionsbefore:= fi.options; + fi.options:= faceoptionsty( + setsinglebit(longword(avalue),longword(fi.options), + [longword(faceoptionsmask1),longword(faceoptionsmask2)])); + if fao_alphafadeall in (faceoptionsty( + {$ifdef FPC}longword{$else}byte{$endif}(optionsbefore) xor + {$ifdef FPC}longword{$else}byte{$endif}(fi.options))) then begin + fintf.widgetregioninvalid; + end; + change; + end; +end; + +procedure tcustomface.setframei_left(const avalue: integer); +begin + include(flocalprops,fal_framei_left); + if fi.framei.left <> avalue then begin + fi.framei.left:= avalue; + change; + end; +end; + +procedure tcustomface.setframei_top(const avalue: integer); +begin + include(flocalprops,fal_framei_top); + if fi.framei.top <> avalue then begin + fi.framei.top:= avalue; + change; + end; +end; + +procedure tcustomface.setframei_right(const avalue: integer); +begin + include(flocalprops,fal_framei_right); + if fi.framei.right <> avalue then begin + fi.framei.right:= avalue; + change; + end; +end; + +procedure tcustomface.setframei_bottom(const avalue: integer); +begin + include(flocalprops,fal_framei_bottom); + if fi.framei.bottom <> avalue then begin + fi.framei.bottom:= avalue; + change; + end; +end; + +procedure tcustomface.setfade_color(const Value: tfadecolorarrayprop); +begin + include(flocalprops,fal_facolor); + fi.fade_color.assign(Value); +end; + +procedure tcustomface.setfade_pos(const Value: trealarrayprop); +begin + include(flocalprops,fal_fapos); + fi.fade_pos.assign(Value); +end; + +procedure tcustomface.setfade_opacolor(const Value: tfadeopacolorarrayprop); +begin + include(flocalprops,fal_faopacolor); + fi.fade_opacolor.assign(Value); +end; + +procedure tcustomface.setfade_opapos(const Value: trealarrayprop); +begin + include(flocalprops,fal_faopapos); + fi.fade_opapos.assign(Value); +end; + +procedure tcustomface.setfade_direction(const Value: graphicdirectionty); +begin + include(flocalprops,fal_fadirection); + if fi.fade_direction <> value then begin + fi.fade_direction:= Value; + change; + end; +end; + +procedure tcustomface.setfade_opacity(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + include(flocalprops,fal_faopacity); + if fi.fade_opacity <> avalue then begin + fi.fade_opacity:= avalue; + change; + end; +end; + +procedure tcustomface.setframeimage_list(const avalue: timagelist); +begin + include(flocalprops,fal_frameimagelist); + if fi.frameimage_list <> avalue then begin + fintf.setlinkedvar(avalue,tmsecomponent(fi.frameimage_list)); + change; + end; +end; + +procedure tcustomface.setframeimage_offset(const avalue: integer); +begin + include(flocalprops,fal_frameimageoffset); + if fi.frameimage_offset <> avalue then begin + fi.frameimage_offset:= avalue; + change; + end; +end; + + +procedure tcustomface.settemplate(const avalue: tfacecomp); +begin + fintf.setlinkedvar(avalue,tmsecomponent(ftemplate)); + if (avalue <> nil) and not (csloading in avalue.componentstate) then begin + assign(avalue); + end; +end; + +procedure tcustomface.settemplateinfo(const ainfo: faceinfoty); +var + localbefore: facelocalpropsty; +begin + localbefore:= flocalprops; + if not (fal_facolor in flocalprops) then begin + fade_color:= ainfo.fade_color; + end; + if not (fal_fapos in flocalprops) then begin + fade_pos:= ainfo.fade_pos; + end; + if not (fal_faopacolor in flocalprops) then begin + fade_opacolor:= ainfo.fade_opacolor; + end; + if not (fal_faopapos in flocalprops) then begin + fade_opapos:= ainfo.fade_opapos; + end; + if not (fal_image in flocalprops) then begin + image:= ainfo.image; + end; + if not (fal_fadirection in flocalprops) then begin + fade_direction:= ainfo.fade_direction; + end; + if not (fal_faopacity in flocalprops) then begin + fade_opacity:= ainfo.fade_opacity; + end; + if not (fal_frameimagelist in flocalprops) then begin + fintf.setlinkedvar(ainfo.frameimage_list, + tmsecomponent(fi.frameimage_list)); + end; + if not (fal_frameimageoffset in flocalprops) then begin + fi.frameimage_offset:= ainfo.frameimage_offset; + end; + if not (fal_framei_left in flocalprops) then begin + fi.framei.left:= ainfo.framei.left; + end; + if not (fal_framei_top in flocalprops) then begin + fi.framei.top:= ainfo.framei.top; + end; + if not (fal_framei_right in flocalprops) then begin + fi.framei.right:= ainfo.framei.right; + end; + if not (fal_framei_bottom in flocalprops) then begin + fi.framei.bottom:= ainfo.framei.bottom; + end; + if not (fal_options in flocalprops) then begin + options:= ainfo.options; + end; + flocalprops:= localbefore; +end; + +procedure tcustomface.setlocalprops(avalue: facelocalpropsty); +begin + if flocalprops <> avalue then begin + if fal_fatransparency in avalue then begin + include(avalue,fal_faopacity); + end; + flocalprops:= avalue - deprecatedfacelocalprops; + if ftemplate <> nil then begin + settemplateinfo(ftemplate.template.fi); + end; + end; +end; + +function tcustomface.isoptionsstored: boolean; +begin + result:= (ftemplate = nil) or (fal_options in flocalprops); +end; + +function tcustomface.isframei_leftstored: boolean; +begin + result:= (ftemplate = nil) or (fal_framei_left in flocalprops); +end; + +function tcustomface.isframei_topstored: boolean; +begin + result:= (ftemplate = nil) or (fal_framei_top in flocalprops); +end; + +function tcustomface.isframei_rightstored: boolean; +begin + result:= (ftemplate = nil) or (fal_framei_right in flocalprops); +end; + +function tcustomface.isframei_bottomstored: boolean; +begin + result:= (ftemplate = nil) or (fal_framei_bottom in flocalprops); +end; + +function tcustomface.isimagestored: boolean; +begin + result:= (ftemplate = nil) or (fal_image in flocalprops); +end; + +function tcustomface.isfacolorstored: boolean; +begin + result:= (ftemplate = nil) or (fal_facolor in flocalprops); +end; + +function tcustomface.isfaposstored: boolean; +begin + result:= (ftemplate = nil) or (fal_fapos in flocalprops); +end; + +function tcustomface.isfaopacolorstored: boolean; +begin + result:= (ftemplate = nil) or (fal_faopacolor in flocalprops); +end; + +function tcustomface.isfaopaposstored: boolean; +begin + result:= (ftemplate = nil) or (fal_faopapos in flocalprops); +end; + +function tcustomface.isfadirectionstored: boolean; +begin + result:= (ftemplate = nil) or (fal_fadirection in flocalprops); +end; + +function tcustomface.isfaopacitystored: boolean; +begin + result:= (ftemplate = nil) or (fal_faopacity in flocalprops); +end; + +function tcustomface.isframeimage_liststored: boolean; +begin + result:= (ftemplate = nil) or (fal_frameimagelist in flocalprops); +end; + +function tcustomface.isframeimage_offsetstored: boolean; +begin + result:= (ftemplate = nil) or (fal_frameimageoffset in flocalprops); +end; + +procedure tcustomface.readtransparency(reader: treader); +begin + fade_opacity:= transparencytoopacity(reader.readinteger); +end; + +procedure tcustomface.defineproperties(filer: tfiler); +begin +// inherited; //no dummy necessary because of localprops + filer.defineproperty('dummy',@readdummy,nil,false); + filer.defineproperty('fade_transparency',@readtransparency,nil,false); +end; + +{ tfacetemplate } + +procedure tfacetemplate.internalcreate; +begin + fi.image:= tfacebitmap.create(nil); + fi.fade_pos:= trealarrayprop.Create; + fi.fade_color:= tfadecolorarrayprop.Create; + fi.fade_pos.link([fi.fade_color,fi.fade_pos]); + fi.fade_opapos:= trealarrayprop.Create; + fi.fade_opacolor:= tfadeopacolorarrayprop.Create; + fi.fade_opapos.link([fi.fade_opacolor,fi.fade_opapos]); + fi.fade_opacity:= cl_none; + fi.image.onchange:= {$ifdef FPC}@{$endif}doimagechange; + fi.fade_pos.onchange:= {$ifdef FPC}@{$endif}dochange; + fi.fade_color.onchange:= {$ifdef FPC}@{$endif}dochange; + fi.fade_opapos.onchange:= {$ifdef FPC}@{$endif}dochange; + fi.fade_opacolor.onchange:= {$ifdef FPC}@{$endif}dochange; +end; + +constructor tfacetemplate.create(const owner: tmsecomponent; + const onchange: notifyeventty); +begin + internalcreate; + inherited; +end; + +destructor tfacetemplate.destroy; +begin + inherited; + fi.image.Free; + fi.fade_pos.Free; + fi.fade_color.Free; + fi.fade_opapos.Free; + fi.fade_opacolor.Free; +end; + +procedure tfacetemplate.paint(const canvas: tcanvas; const arect: rectty); +var + bmp: tmaskedbitmap; + pt1: pointty; +begin + bmp:= nil; + facepaint(canvas,arect,fi,iface1(self),bmp,pt1); + bmp.free; +end; + +procedure tfacetemplate.setfade_direction(const Value: graphicdirectionty); +begin + fi.fade_direction:= Value; + changed; +end; + +procedure tfacetemplate.dochange(const sender: tarrayprop; const index: integer); +begin + updatefadearray(fi,sender); + changed; +end; + +procedure tfacetemplate.doimagechange(const sender: tobject); +begin + changed; +end; + +procedure tfacetemplate.setoptions(const avalue: faceoptionsty); +begin + fi.options:= faceoptionsty(setsinglebit(longword(avalue),longword(fi.options), + [longword(faceoptionsmask1),longword(faceoptionsmask2)])); + changed; +end; + +procedure tfacetemplate.setframei_left(const avalue: integer); +begin + fi.framei.left:= avalue; + changed; +end; + +procedure tfacetemplate.setframei_top(const avalue: integer); +begin + fi.framei.top:= avalue; + changed; +end; + +procedure tfacetemplate.setframei_right(const avalue: integer); +begin + fi.framei.right:= avalue; + changed; +end; + +procedure tfacetemplate.setframei_bottom(const avalue: integer); +begin + fi.framei.bottom:= avalue; + changed; +end; + +procedure tfacetemplate.setfade_color(const Value: tfadecolorarrayprop); +begin + fi.fade_color.Assign(Value); +end; + +procedure tfacetemplate.setfade_pos(const Value: trealarrayprop); +begin + fi.fade_pos.Assign(Value); +end; + +procedure tfacetemplate.setfade_opacolor(const Value: tfadeopacolorarrayprop); +begin + fi.fade_opacolor.Assign(Value); +end; + +procedure tfacetemplate.setfade_opapos(const Value: trealarrayprop); +begin + fi.fade_opapos.Assign(Value); +end; + +procedure tfacetemplate.setfade_opacity(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + fi.fade_opacity:= avalue; + changed; +end; + +procedure tfacetemplate.setimage(const Value: tfacebitmap); +begin + fi.image.assign(value); + changed; +end; + +procedure tfacetemplate.setframeimage_list(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fi.frameimage_list)); + changed; +end; + +procedure tfacetemplate.setframeimage_offset(const avalue: integer); +begin + fi.frameimage_offset:= avalue; + changed; +end; + +procedure tfacetemplate.doassignto(dest: tpersistent); +begin + if dest is tcustomface then begin + tcustomface(dest).settemplateinfo(fi); + end; +end; + +procedure tfacetemplate.copyinfo(const source: tpersistenttemplate); +begin + with tfacetemplate(source) do begin + self.setlinkedvar(frameimage_list,tmsecomponent(self.fi.frameimage_list)); + self.fi.image.assign(image); + self.fi.fade_pos.beginupdate; + self.fi.fade_color.beginupdate; + self.fi.fade_pos.assign(fade_pos); + self.fi.fade_color.assign(fade_color); + self.fi.fade_pos.endupdate(true); + self.fi.fade_color.endupdate; + end; +end; + +function tfacetemplate.getinfosize: integer; +begin + result:= sizeof(integer) + sizeof(fi.fade_direction); +end; + +function tfacetemplate.getinfoad: pointer; +begin + result:= @fi.fade_direction; +end; + +procedure tfacetemplate.readtransparency(reader: treader); +begin + fade_opacity:= transparencytoopacity(reader.readinteger); +end; + +procedure tfacetemplate.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('fade_transparency',@readtransparency,nil,false); +end; + +function tfacetemplate.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; +end; + +{ tfacecomp } + +function tfacecomp.gettemplate: tfacetemplate; +begin + result:= tfacetemplate(ftemplate); +end; + +procedure tfacecomp.settemplate(const Value: tfacetemplate); +begin + ftemplate.Assign(value); +end; + +function tfacecomp.gettemplateclass: templateclassty; +begin + result:= tfacetemplate; +end; + +{ tfacearrayprop } + +constructor tfacearrayprop.create(const aintf: iface); +begin + fintf:= aintf; +end; + +function tfacearrayprop.getitems(const index: integer): tface; +begin + result:= tface(inherited items[index]); +end; + +procedure tfacearrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tface.create(fintf); +end; + +class function tfacearrayprop.getitemclasstype: persistentclassty; +begin + result:= tface; +end; + +{ tfacelist } + +constructor tfacelist.create(aowner: tcomponent); +begin + flist:= tfacearrayprop.create(iface(self)); + inherited; +end; + +destructor tfacelist.destroy; +begin + inherited; + flist.free; +end; + +procedure tfacelist.paint(const canvas: tcanvas; const aindex: int32; + const dest: rectty); +begin + if (aindex >= 0) and (aindex <= high(flist.fitems)) then begin + tface(flist.fitems[aindex]).paint(canvas,dest); + end; +end; + +function tfacelist.lookup(const aindex: int32): int32; +begin + result:= aindex; + if findexlookup <> '' then begin + result:= -1; + if (aindex >= 0) and (aindex < length(findexlookup)) then begin + result:= pint16(findexlookup)[aindex]; + end; + end; +end; + +procedure tfacelist.setlist(const avalue: tfacearrayprop); +begin + flist.assign(avalue); +end; + +procedure tfacelist.invalidatewidget(); +begin + //dummy +end; + +procedure tfacelist.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + //dummy +end; + +function tfacelist.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; +end; + +function tfacelist.getclientrect: rectty; +begin + result:= nullrect; +end; + +function tfacelist.getcomponentstate: tcomponentstate; +begin + result:= componentstate; +end; + +procedure tfacelist.widgetregioninvalid; +begin + //dummy +end; + +procedure tfacelist.setindexlookup(const avalue: msestring); +begin + findexlookup:= avalue; +end; + +procedure tfacelist.objectevent(const sender: tobject; + const event: objecteventty); +var + int1: integer; + fa1: tcustomface; +begin + inherited; + if (event = oe_changed) and (sender is tfacecomp) then begin + for int1:= 0 to list.count - 1 do begin + fa1:= tcustomface(flist.fitems[int1]); + if fa1.template = sender then begin + fa1.checktemplate(sender); + end; + end; + end; +end; + +{ twidget } + +constructor twidget.create(aowner: tcomponent); +begin + fnoinvalidate:= 1; + fwidgetstate:= defaultwidgetstates; + foptionsskin:= defaultoptionsskin; + fanchors:= defaultanchors; + foptionswidget:= defaultoptionswidget; + foptionswidget1:= defaultoptionswidget1; + fwidgetrect.cx:= defaultwidgetwidth; + fwidgetrect.cy:= defaultwidgetheight; + fcolor:= defaultwidgetcolor; + inherited; +end; + +constructor twidget.create(const aowner: tcomponent; + const aparentwidget: twidget; const aiswidget: boolean{ = true}); +begin + create(aowner); + setlockedparentwidget(aparentwidget); + if not aiswidget then begin + exclude(fwidgetstate,ws_iswidget); + end; + if (aowner = nil) and (aparentwidget <> nil) and + (csdesigning in aparentwidget.componentstate) then begin + //for streamed widget + setdesignwidget(); + end; +end; + +constructor twidget.createandinit(const aowner: tcomponent; + const aparentwidget: twidget; const aiswidget: boolean); +begin + create(aowner,aparentwidget,aiswidget); + initnewcomponent(1); + initnewwidget(1); +end; + +constructor twidget.create(const aowner: tcomponent; + const aparentwidget: twidget); +begin + if aparentwidget <> nil then begin + parentwidget:= aparentwidget; + end; + create(aowner); +end; + +procedure twidget.afterconstruction; +begin + inherited; + fnoinvalidate:= 0; +end; + +destructor twidget.destroy; +var + widget1: twidget; + window1: twindow; +begin + include(fwidgetstate,ws_destroying); + if (appinst <> nil) then begin + appinst.widgetdestroyed(self); + end; + window1:= fwindow; + widget1:= fparentwidget; + while (window1 = nil) and (widget1 <> nil) do begin + window1:= widget1.fwindow; + widget1:= widget1.fparentwidget; + end; + if window1 <> nil then begin + window1.widgetdestroyed(self); + end; + if fwidgets <> nil then begin + if ow_destroywidgets in foptionswidget then begin + while length(fwidgets) > 0 do begin + with fwidgets[high(fwidgets)] do begin + if ws_iswidget in fwidgetstate then begin + free; + end + else begin + fparentwidget:= nil; + fwindow:= nil; + exclude(fwidgetstate1,ws1_rootvalid); + setlength(self.fwidgets,high(self.fwidgets)); + end; + end; + end; + end + else begin + while length(fwidgets) > 0 do begin + widget1:= fwidgets[high(fwidgets)]; + if not (ow_nohidewidgets in foptionswidget) then begin + widget1.visible:= false; + end; + widget1.parentwidget:= nil; + end; + end; + fwidgets:= nil; + end; + hide; + if fparentwidget <> nil then begin + clearparentwidget; + end; + inherited; + fwindow.Free; + ffont.free; + ffontempty.free; + fframe.free; + fface.free; +// inherited; + destroyregion(fwidgetregion); +end; + +procedure twidget.initnewcomponent(const ascale: real); +begin + inherited; + scale(ascale); +end; + +procedure twidget.initnewwidget(const ascale: real); +begin + synctofontheight; +end; + +procedure twidget.createframe; +begin + if fframe = nil then begin + internalcreateframe; + end; +end; + +procedure twidget.createface; +begin + if fface = nil then begin + internalcreateface; + end; +end; + +procedure twidget.createfont; +begin + if ffont = nil then begin + internalcreatefont; + end; +end; + +procedure twidget.createfontempty; +begin + if ffontempty = nil then begin + internalcreatefontempty; + end; +end; + +function twidget.widgetcount: integer; +begin + result:= length(fwidgets); +end; + +function twidget.getcontainer: twidget; +begin + result:= self; +end; + +function twidget.containeroffset: pointty; +var + widget1: twidget; +begin + widget1:= getcontainer; + if widget1 = self then begin + result:= nullpoint; + end + else begin + result:= widget1.fwidgetrect.pos; + end; +end; + +function twidget.childrencount: integer; +begin + result:= widgetcount; +end; + +function twidget.visiblechildrencount: integer; +var + i1,i2: int32; +begin + i2:= 0; + for i1:= 0 to childrencount - 1 do begin + if children[i1].visible then begin + inc(i2); + end; + end; + result:= i2; +end; + +function twidget.getwidgets(const index: integer): twidget; +begin + if (index < 0) or (index > high(fwidgets)) then begin + tlist.error(slistindexerror,index); + end; + result:= fwidgets[index]; //fwidgets can be nil -> exception +end; + +function twidget.indexofwidget(const awidget: twidget): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(fwidgets) do begin + if fwidgets[int1] = awidget then begin + result:= int1; + break; + end; + end; +end; + +procedure twidget.changedirection(const avalue: graphicdirectionty; + var dest: graphicdirectionty); +var + dir1: graphicdirectionty; + int1: integer; +begin + if fface <> nil then begin + fface.fade_direction:= rotatedirection(fface.fade_direction,avalue,dest); + end; + if fframe <> nil then begin + fframe.changedirection(avalue,dest); + end; + dir1:= dest; + dest := avalue; + if (componentstate * [csdesigning,csloading] = [csdesigning]) and + ((dir1 in [gd_right,gd_left]) xor (avalue in [gd_right,gd_left])) then begin + int1:= bounds_cy; + bounds_cy:= bounds_cx; + bounds_cx:= int1; + end; +end; + +procedure twidget.placexorder(const startx: integer; const dist: array of integer; + const awidgets: array of twidget; const endmargin: integer = minint); + //origin = clientpos, endmargin by size adjust of widgets + //with [an_left,an_right], minit -> no change +var + int1,int2,int3,int4,int5: integer; + size1: sizety; + widget1: twidget; + ar1: integerarty; + bo1: boolean; +begin +{$ifdef mse_debuglayout} + debugwriteln('**placexorder '+inttostr(bounds_cx)+' '+name); +{$endif} + if (high(awidgets) >= 0) then begin + widget1:= awidgets[0].fparentwidget; + if widget1 <> nil then begin + setlength(ar1,length(awidgets)); + int2:= startx + widget1.clientwidgetpos.x; + for int1:= 0 to high(awidgets) do begin + ar1[int1]:= int2; + if int1 <= high(dist) then begin + int5:= dist[int1]; + end + else begin + if high(dist) >= 0 then begin + int5:= dist[high(dist)]; + end + else begin + int5:= 0; + end; + end; + int2:= int2 + int5 + awidgets[int1].fwidgetrect.cx; + {$ifdef mse_debuglayout} + debugwriteln(' '+inttostr(ar1[int1])+' '+ + inttostr(awidgets[int1].bounds_cx)+' '+ + inttostr(ar1[int1]+awidgets[int1].bounds_cx)+' '+ + awidgets[int1].name); + {$endif} + end; + if endmargin <> minint then begin + int2:= ar1[high(awidgets)] + awidgets[high(awidgets)].fwidgetrect.cx + + endmargin - (widget1.paintrect.x + widget1.paintrect.cx); + end + else begin + int2:= 0; + end; + int4:= 0; + size1.cy:= 0; + {$ifdef mse_debuglayout} + debugwriteln(' marginsaldo '+inttostr(int2)); + {$endif} + for int1:= 0 to high(awidgets) do begin + with awidgets[int1] do begin + bo1:= ws1_layoutplacing in fwidgetstate1; + try + {$ifdef mse_debuglayout} + debugwriteln(' a '+inttostr(bounds_x)+' '+inttostr(bounds_cx)+' '+ + inttostr(bounds_x+bounds_cx)+' '+name); + {$endif} + include(fwidgetstate1,ws1_layoutplacing); + bounds_x:= ar1[int1] + int4; + if anchors * [an_left,an_right] = [an_left,an_right] then begin + int3:= bounds_cx; + size1.cx:= bounds_cx - int2; + if fframe <> nil then begin + fframe.checkwidgetsize(size1); + end; + bounds_cx:= size1.cx; + int3:= bounds_cx - int3; //delta + int2:= int2 + int3; + int4:= int4 + int3; + end; + {$ifdef mse_debuglayout} + debugwriteln(' b '+inttostr(bounds_x)+' '+inttostr(bounds_cx)+' '+ + inttostr(bounds_x+bounds_cx)+' '+name); + {$endif} + finally + if not bo1 then begin + exclude(fwidgetstate1,ws1_layoutplacing); + end; + end; + end; + end; + end; + end; +end; + +procedure twidget.placeyorder(const starty: integer; const dist: array of integer; + const awidgets: array of twidget; const endmargin: integer = minint); + //origin = clientpos, endmargin by size adjust of widgets + //with [an_top,an_bottom], minit -> no change +var + int1,int2,int3,int4,int5: integer; + size1: sizety; + widget1: twidget; + ar1: integerarty; + bo1: boolean; +begin + if (high(awidgets) >= 0) then begin + widget1:= awidgets[0].fparentwidget; + if widget1 <> nil then begin + setlength(ar1,length(awidgets)); + int2:= starty + widget1.clientwidgetpos.y; + for int1:= 0 to high(awidgets) do begin + ar1[int1]:= int2; + if int1 <= high(dist) then begin + int5:= dist[int1]; + end + else begin + if high(dist) >= 0 then begin + int5:= dist[high(dist)]; + end + else begin + int5:= 0; + end; + end; + int2:= int2 + int5 + awidgets[int1].fwidgetrect.cy; + end; + if endmargin <> minint then begin + int2:= ar1[high(awidgets)] + awidgets[high(awidgets)].fwidgetrect.cy + + endmargin - (widget1.paintrect.y + widget1.paintrect.cy); + end + else begin + int2:= 0; + end; + int4:= 0; + size1.cx:= 0; + for int1:= 0 to high(awidgets) do begin + with awidgets[int1] do begin + bo1:= ws1_layoutplacing in fwidgetstate1; + try + include(fwidgetstate1,ws1_layoutplacing); + bounds_y:= ar1[int1] + int4; + if anchors * [an_top,an_bottom] = [an_top,an_bottom] then begin + int3:= bounds_cy; + size1.cy:= bounds_cy - int2; + if fframe <> nil then begin + fframe.checkwidgetsize(size1); + end; + bounds_cy:= size1.cy; + int3:= bounds_cy - int3; //delta + int2:= int2 + int3; + int4:= int4 + int3; + end; + finally + if not bo1 then begin + exclude(fwidgetstate1,ws1_layoutplacing); + end; + end; + end; + end; + end; + end; +end; + +function twidget.getwidgetrects(const awidgets: array of twidget): rectarty; +var + int1: integer; +begin + setlength(result,length(awidgets)); + for int1:= 0 to high(result) do begin + with awidgets[int1] do begin + result[int1]:= widgetrect; + if parentwidget <> self then begin + translatewidgetpoint1(result[int1].pos,parentwidget,self); + end; + end; + end; +end; + +procedure twidget.setwidgetrects(const awidgets: array of twidget; + const arects: rectarty); +var + int1: integer; + rect1: rectty; +begin + for int1:= 0 to high(awidgets) do begin + with awidgets[int1] do begin + rect1:= arects[int1]; + if parentwidget <> self then begin + translatewidgetpoint1(rect1.pos,self,parentwidget); + end; + widgetrect:= rect1; + end; + end; +end; + +function twidget.alignx(const mode: widgetalignmodety; + const awidgets: array of twidget; + const glue: widgetalignmodety = wam_none; + const margin: integer = 0): integer; + + function getrefpoint(const awidget: twidget): integer; + begin + with awidget do begin + updateroot; + case mode of + wam_start: begin + result:= frootpos.x + framepos.x; + if (fframe <> nil) and not (osk_nopaintref in foptionsskin) then begin + with fframe do begin + checkstate(); + result:= result + fwidth.left; + end; + end; + end; + wam_center: begin + result:= frootpos.x + framepos.x + framesize.cx div 2; + end; + else begin //wam_end + result:= frootpos.x + framepos.x + awidget.framesize.cx; + if (fframe <> nil) and not (osk_nopaintref in foptionsskin) then begin + with fframe do begin + checkstate(); + result:= result - fwidth.right; + end; + end; + end; + end; + end; + end; //getrefpoint + + procedure doshift(const awidget: twidget; const amode: widgetalignmodety; + const ashift: integer; var arect: rectty); + begin + with awidget do begin + if (amode = wam_start) and (an_right in anchors) then begin + arect.cx:= arect.cx - ashift; + end; + if (amode = wam_end) and (an_left in anchors) then begin + arect.cx:= arect.cx + ashift; + end + else begin + arect.x:= arect.x + ashift; + end; + end; + end; //doshift + +var + ref,shift,int1,int2,int3: integer; + ar1: rectarty; + +begin + result:= 0; + if (high(awidgets) >= 0) then begin + beginupdate(); + try + ref:= getrefpoint(awidgets[0]); + with awidgets[0] do begin + if fparentwidget <> nil then begin + result:= ref - fparentwidget.frootpos.x + end + else begin + result:= ref; + end; + end; + ar1:= getwidgetrects(awidgets); + if (mode <> wam_none) and (high(awidgets) > 0) then begin + for int1:= 1 to high(awidgets) do begin + int3:= ref - getrefpoint(awidgets[int1]); + doshift(awidgets[int1],mode,int3,ar1[int1]); + end; + end; + if (glue <> wam_none) then begin + shift:= 0; + case glue of + wam_start: begin + int2:= bigint; + for int1:= 0 to high(awidgets) do begin + int3:= ar1[int1].x; + if int3 < int2 then begin + int2:= int3; + end; + end; + shift:= margin+clientwidgetpos.x-int2; + end; + wam_end: begin + int2:= -bigint; + for int1:= 0 to high(awidgets) do begin + with ar1[int1] do begin + int3:= x+cx; + end; + if int3 > int2 then begin + int2:= int3; + end; + end; + shift:= clientwidgetpos.x+clientwidth - margin - int2; + end; + else begin //wam_center + if length(awidgets) > 0 then begin + with awidgets[0] do begin + shift:= margin + ar1[0].x + framepos.x + (framesize.cx+1) div 2; + end; + shift:= clientwidgetpos.x + clientwidth div 2 - shift; + end; + end; + end; + if shift <> 0 then begin + result:= result+shift; + for int1:= 0 to high(awidgets) do begin + doshift(awidgets[int1],glue,shift,ar1[int1]); + end; + end; + end; + setwidgetrects(awidgets,ar1); + finally + endupdate(); + end; + end; +end; + +function twidget.aligny(const mode: widgetalignmodety; + const awidgets: array of twidget; + const glue: widgetalignmodety = wam_none; + const margin: integer = 0): integer; + + function getrefpoint(const awidget: twidget): integer; + begin + with awidget do begin + updateroot; + case mode of + wam_start: begin + result:= frootpos.y + framepos.y; + if (fframe <> nil) and not (osk_nopaintref in foptionsskin) then begin + with fframe do begin + checkstate(); + result:= result + fwidth.top; + end; + end; + end; + wam_center: begin + result:= frootpos.y + framepos.y + framesize.cy div 2; + end; + else begin //wam_end + result:= frootpos.y + framepos.y + awidget.framesize.cy; + if (fframe <> nil) and not (osk_nopaintref in foptionsskin) then begin + with fframe do begin + checkstate(); + result:= result - fwidth.bottom; + end; + end; + end; + end; + end; + end; //getrefpoint + + procedure doshift(const awidget: twidget; const amode: widgetalignmodety; + const ashift: integer; var arect: rectty); + begin + with awidget do begin + if (amode = wam_start) and (an_bottom in anchors) then begin + arect.cy:= arect.cy - ashift; + end; + if (amode = wam_end) and (an_top in anchors) then begin + arect.cy:= arect.cy + ashift; + end + else begin + arect.y:= arect.y + ashift; + end; + end; + end; //doshift + +var + ref,shift,int1,int2,int3: integer; + ar1: rectarty; + +begin + result:= 0; + if (high(awidgets) >= 0) then begin + beginupdate(); + try + ref:= getrefpoint(awidgets[0]); + with awidgets[0] do begin + if fparentwidget <> nil then begin + result:= ref - fparentwidget.frootpos.y + end + else begin + result:= ref; + end; + end; + ar1:= getwidgetrects(awidgets); + if (mode <> wam_none) and (high(awidgets) > 0) then begin + for int1:= 1 to high(awidgets) do begin + int3:= ref - getrefpoint(awidgets[int1]); + doshift(awidgets[int1],mode,int3,ar1[int1]); + end; + end; + if (glue <> wam_none) then begin + shift:= 0; + case glue of + wam_start: begin + int2:= bigint; + for int1:= 0 to high(awidgets) do begin + int3:= ar1[int1].y; + if int3 < int2 then begin + int2:= int3; + end; + end; + shift:= margin+clientwidgetpos.y-int2; + end; + wam_end: begin + int2:= -bigint; + for int1:= 0 to high(awidgets) do begin + with ar1[int1] do begin + int3:= y+cy; + end; + if int3 > int2 then begin + int2:= int3; + end; + end; + shift:= clientwidgetpos.y+clientheight - margin - int2; + end; + else begin //wam_center + if length(awidgets) > 0 then begin + with awidgets[0] do begin + shift:= margin + ar1[0].y + framepos.y + (framesize.cy+1) div 2; + end; + shift:= clientwidgetpos.y + clientheight div 2 - shift; + end; + end; + end; + if shift <> 0 then begin + result:= result+shift; + for int1:= 0 to high(awidgets) do begin + doshift(awidgets[int1],glue,shift,ar1[int1]); + end; + end; + end; + setwidgetrects(awidgets,ar1); + finally + endupdate(); + end; + end; +end; + +function twidget.getchildwidgets(const index: integer): twidget; +begin + result:= getwidgets(index); +end; + +function compzorder(const l,r): integer; +begin + result:= 0; + if ow_background in twidget(l).foptionswidget then dec(result); + if ow_top in twidget(l).foptionswidget then inc(result); + if ow_background in twidget(r).foptionswidget then inc(result); + if ow_top in twidget(r).foptionswidget then dec(result); +end; + +procedure twidget.sortzorder; +begin + if not isloading then begin + sortarray(pointerarty(fwidgets),{$ifdef FPC}@{$endif}compzorder); + invalidatewidget; + end; +end; + +procedure twidget.registerchildwidget(const child: twidget); +var + flags: rootchangeflagsty; +begin + if indexofwidget(child) >= 0 then begin + guierror(gue_alreadyregistered,self,':'+child.name); + end; + setlength(fwidgets,high(fwidgets)+2); + fwidgets[high(fwidgets)]:= child; + flags:= [rcf_widgetregioninvalid]; + if child.fwindow <> fwindow then begin + flags:= flags + [rcf_windowremove,rcf_windowset]; + end; + child.rootchanged(flags); +// child.updateopaque(true); //for cl_parent + if not isloading then begin + child.updateopaque(true,false); //for cl_parent + child.ftaborder:= high(fwidgets); + sortzorder; + updatetaborder(child); + if child.isvisible then begin + widgetregionchanged(child); + if focused and not child.isloading then begin + checksubfocus(false); + end; + end; + end; +end; + +procedure twidget.unregisterchildwidget(const child: twidget); +begin + if fwidgets <> nil then begin + removeitem(pointerarty(fwidgets),child); + end; + if ffocusedchild = child then begin + ffocusedchild:= nil; + end; + if ffocusedchildbefore = child then begin + ffocusedchildbefore:= nil; + end; + if fdefaultfocuschild = child then begin + fdefaultfocuschild:= nil; + end; + child.rootchanged([rcf_widgetregioninvalid]); + if not isloading then begin + updatetaborder(nil); + if child.isvisible then begin + widgetregionchanged(child); + end; + end; +end; + +procedure twidget.setcolor(const avalue: colorty); +begin + if fcolor <> avalue then begin + fcolor:= avalue; + if not (csloading in componentstate) then begin + colorchanged; + end; + end; +end; + +function twidget.clearparentwidget: twidget; + //returns old parentwidget +begin + result:= fparentwidget; + fparentwidget:= nil; + fwindow:= nil; + result.unregisterchildwidget(self); +end; + +procedure twidget.setparentwidget(const Value: twidget); +var + newpos: pointty; + updatingbefore: boolean; +begin + if fparentwidget <> value then begin + updatingbefore:= ws1_parentupdating in fwidgetstate1; + include(fwidgetstate1,ws1_parentupdating); + try + if entered and (fwindow <> nil) then begin + window.nofocus; + if fwindow.focusedwidget <> nil then begin + exit; + end; + end; + if (value <> nil) then begin + if value = self then begin + raise exception.create('Recursive parent.'); + end; + if (fwindow <> nil) and ownswindow1 then begin + newpos:= translatewidgetpoint(fwidgetrect.pos,nil,value); +// fwindow.fownerwidget:= nil; + freeandnil(fwindow); + end + else begin + newpos:= fwidgetrect.pos; + end; + end + else begin + newpos:= addpoint(rootwidget.fwidgetrect.pos,rootpos); + fcolor:= translatecolor(fcolor); + end; + + if fparentwidget <> nil then begin + clearparentwidget; + end; + if fparentwidget <> nil then begin + exit; //interrupt + end; + fparentwidget:= Value; + fwidgetrect.pos:= newpos; + if fparentwidget <> nil then begin + fparentwidget.registerchildwidget(self); + if not (csloading in componentstate) and + not (ws_loadlock in fwidgetstate) then begin + fparentclientsize:= fparentwidget.minclientsize; + parentclientrectchanged; + end; + end + else begin + if visible and not (ws_destroying in fwidgetstate) and + not (csdestroying in componentstate) then begin + window.show(false); + end; + end; + if not isloading then begin + fontchanged; + colorchanged; + enabledchanged; //-> statechanged + parentchanged; + end; + finally + if not updatingbefore then begin + exclude(fwidgetstate1,ws1_parentupdating); + end; + end; + end; +end; + +procedure twidget.setlockedparentwidget(const avalue: twidget); +var + bo1: boolean; +begin + bo1:= ws_loadlock in fwidgetstate; + include(fwidgetstate,ws_loadlock); + try + setparentwidget(avalue); + finally + if not bo1 then begin + exclude(fwidgetstate,ws_loadlock); + end; + end; +end; + +procedure twidget.checkwidgetsize(var size: sizety); +var + si1: sizety; +begin + si1:= widgetminsize1(); + if si1.cx > 0 then begin + if size.cx < si1.cx then begin + size.cx:= si1.cx; + end; + end; + if si1.cy > 0 then begin + if size.cy < si1.cy then begin + size.cy:= si1.cy; + end; + end; + si1:= widgetmaxsize1(); + if si1.cx > 0 then begin + if size.cx > si1.cx then begin + size.cx:= si1.cx; + end; + end; + if si1.cy > 0 then begin + if size.cy > si1.cy then begin + size.cy:= si1.cy; + end; + end; +end; + +procedure twidget.checksizes(); +begin + if not (ws_minclientsizevalid in fwidgetstate) then begin + include(fwidgetstate,ws_minclientsizevalid); //avoid recursion + + fminscrollsize:= calcminscrollsize; //first + if fframe <> nil then begin + fframe.checkminscrollsize(fminscrollsize); + end; + fminclientsize:= fminscrollsize; + fminshrinksize:= calcminshrinksize(); + if fframe <> nil then begin + fframe.checkminclientsize(fminclientsize); + fframe.checkminshrinksize(fminshrinksize); + end + else begin + fminclientsize:= fwidgetrect.size; + end; + end; +end; + +function twidget.widgetminsize1: sizety; +begin + result:= fminsize; + if fframe <> nil then begin + with fframe do begin + if ow1_clientcxmin in foptionswidget1 then begin + result.cx:= result.cx + fpaintframe.left + fpaintframe.right; + end; + if ow1_clientcymin in foptionswidget1 then begin + result.cy:= result.cy + fpaintframe.left + fpaintframe.right; + end; + end; + end; +end; + +function twidget.widgetmaxsize1: sizety; +begin + result:= fmaxsize; + if fframe <> nil then begin + with fframe do begin + if (fmaxsize.cx > 0) and (ow1_clientcxmax in foptionswidget1) then begin + result.cx:= result.cx + fpaintframe.left + fpaintframe.right; + end; + if (fmaxsize.cy > 0) and (ow1_clientcymax in foptionswidget1) then begin + result.cy:= result.cy + fpaintframe.left + fpaintframe.right; + end; + end; + end; +end; + +function twidget.minclientsize: sizety; +begin + checksizes(); + result:= fminclientsize; +end; + +function twidget.minshrinksize: sizety; +begin + checksizes(); + result:= fminshrinksize; +end; + +function twidget.minscrollsize: sizety; +begin + checksizes(); + result:= fminscrollsize; +end; + +function twidget.calcminshrinksize: sizety; +begin + result:= widgetminsize1(); +{ + if fframe <> nil then begin + fframe.checkminshrinksize(result); + end; +} +end; + +procedure twidget.internalsetwidgetrect(value: rectty; + const windowevent: boolean); + + procedure checkwidgetregionchanged(var achanged: boolean); + var + bo1: boolean; + begin + if achanged then begin + achanged:= false; + if (fparentwidget <> nil) then begin + if fframe <> nil then begin + exclude(fframe.fstate,fs_rectsvalid); + bo1:= fs_widgetregionchanging in fframe.fstate; + include(fframe.fstate,fs_widgetregionchanging); + end; + try + fparentwidget.widgetregionchanged(self); //new position + finally + if fframe <> nil then begin + if not bo1 then begin + exclude(fframe.fstate,fs_widgetregionchanging); + end; + end; + end; + end; + end; + end; //checkwidgetregionchanged + + procedure movewidgetregion(const awidget: twidget; const dist: pointty); + var + int1: integer; + begin + with awidget do begin + if (ws1_widgetregionvalid in fwidgetstate1) then begin + regmove(fwidgetregion,dist); + end; + for int1:= 0 to high(fwidgets) do begin + movewidgetregion(fwidgets[int1],dist); + end; + end; + end; //movewidgetregion + +var + bo1,bo2,poscha,sizecha: boolean; + int1,int2,int3: integer; + setcountbefore: integer; + size1,size2: sizety; + ar1: widgetarty; + ar2,ar3: integerarty; + autosizecha: boolean; + autosi: sizety; + simi,sima: sizety; + rect1: rectty; +begin + autosizecha:= false; + if not (csloading in fcomponentstate) and (fparentwidget <> nil) then begin + if (fanchors * [an_left,an_right] = []) or + (fanchors * [an_top,an_bottom] = []) then begin + //instead of calling parentclientrectchanged() + rect1:= fparentwidget.clientwidgetrect; + if fanchors * [an_left,an_right] = [] then begin + value.x:= rect1.x; + value.cx:= rect1.cx; + end; + if fanchors * [an_top,an_bottom] = [] then begin + value.y:= rect1.y; + value.cy:= rect1.cy; + end; + end; + end; + if ([ow1_autowidth,ow1_autoheight]*foptionswidget1 <> []) and + not (csloading in componentstate) then begin + if not windowevent then begin + checkwidgetsize(value.size); + end; + size1:= value.size; + if fframe <> nil then begin + subsize1(size1,fframe.paintframedim); + end; + getautopaintsize(size1); + if fframe <> nil then begin + addsize1(size1,fframe.paintframedim); + end; + subsize1(size1,value.size); + size2:= value.size; + if not (ow1_autowidth in foptionswidget1) then begin + size1.cx:= 0; + end; + if not (ow1_autoheight in foptionswidget1) then begin + size1.cy:= 0; + end; + autosizecha:= (size1.cx <> 0) or (size1.cy <> 0); + inc(value.cx,size1.cx); + if (ow1_autosizeanright in foptionswidget1) and + not (an_right in fanchors) then begin + dec(value.x,size1.cx); + end; + inc(value.cy,size1.cy); + if (ow1_autosizeanbottom in foptionswidget1) and + not (an_bottom in fanchors) then begin + dec(value.y,size1.cy); + end; + autosi:= value.size; + if not windowevent then begin + checkwidgetsize(value.size); + end; + if (an_right in fanchors) and not + (ow1_noautosizeanright in foptionswidget1) then begin + dec(value.x,value.cx-size2.cx); + end; + if (an_bottom in fanchors) and not + (ow1_noautosizeanbottom in foptionswidget1) then begin + dec(value.y,value.cy-size2.cy); + end; + if ownswindow and windowevent and not (csloading in componentstate) then begin + simi:= widgetminsize1(); + sima:= widgetmaxsize1(); + if ow1_autowidth in foptionswidget1 then begin + simi.cx:= value.cx; + sima.cx:= value.cx; + end; + if ow1_autoheight in foptionswidget1 then begin + simi.cy:= value.cy; + sima.cy:= value.cy; + end; + fwindow.setsizeconstraints(simi,sima); + end; + end + else begin + if not windowevent then begin + checkwidgetsize(value.size); + end; + end; + poscha:= (value.x <> fwidgetrect.x) or (value.y <> fwidgetrect.y); + sizecha:= (value.cx <> fwidgetrect.cx) or (value.cy <> fwidgetrect.cy); + bo1:= (isvisible or (ws1_fakevisible in fwidgetstate1)) and (poscha or sizecha); + bo2:= bo1; //backup because of checkwidgetregionchanged + if bo1 and (fparentwidget <> nil) then begin + invalidatewidget; //old position + end; + if poscha then begin + if (fparentwidget <> nil) and ((fwidgetrect.x <> value.x) or + (fwidgetrect.y <> value.y)) then begin + include(fparentwidget.fwidgetstate1,ws1_childrectchanged); + end; + if fparentwidget <> nil then begin + movewidgetregion(self,subpoint(value.pos,fwidgetrect.pos)); + end; + fwidgetrect.x:= value.x; + fwidgetrect.y:= value.y; + rootchanged([]); + end; + if sizecha then begin + inc(fsetwidgetrectcount); + setcountbefore:= fsetwidgetrectcount; + if (componentstate * [csloading,csdesigning] = []) and + ((value.cx < fwidgetrect.cx) or (value.cy < fwidgetrect.cy)) then begin + int2:= 0; + setlength(ar1,length(fwidgets)); + for int1:= 0 to high(ar1) do begin + if ws1_tryshrink in fwidgets[int1].fwidgetstate1 then begin + ar1[int2]:= fwidgets[int1]; + inc(int2); + end; + end; + if int2 > 0 then begin + setlength(ar1,int2); + setlength(ar2,int2); + for int1:= 0 to int2-1 do begin + ar2[int1]:= ar1[int1].getshrinkpriority; + end; + sortarray(ar2,ar3); + orderarray(ar3,pointerarty(ar1)); + size1:= value.size; + if fframe <> nil then begin + subsize1(size1,fframe.paintframedim); + end; + if fframe <> nil then begin + fframe.checkminscrollsize(size1); + end; + size2:= clientsize; + if (size2.cx > size1.cx) or (size2.cy > size1.cy) then begin + int3:= 0; + repeat + exclude(fwidgetstate1,ws1_childrectchanged); + for int1:= int2-1 downto 0 do begin + ar1[int1].tryshrink(size1); + end; + inc(int3); + until not(ws1_childrectchanged in fwidgetstate1) or (int3 >= 4); + //emergency brake + end; + end; + end; + if (fparentwidget <> nil) and ((fwidgetrect.cx <> value.cx) or + (fwidgetrect.cy <> value.cy)) then begin + include(fparentwidget.fwidgetstate1,ws1_childrectchanged); + end; + fwidgetrect.cx:= value.cx; + fwidgetrect.cy:= value.cy; + invalidateparentminclientsize; + exclude(fwidgetstate,ws_minclientsizevalid); + if not (csloading in componentstate) then begin + checkwidgetregionchanged(bo1); + sizechanged; + if fsetwidgetrectcount <> setcountbefore then begin + if poscha and not (csloading in componentstate) then begin + poschanged; + end; + exit; + end; + end + else begin + if fframe <> nil then begin + exclude(fframe.fstate,fs_rectsvalid); + end; + end; + end; + checkwidgetregionchanged(bo1); + if poscha and not (csloading in componentstate) then begin + poschanged; + end; + if ownswindow1 then begin + if not (windowevent and (fwindow.windowpos in windowmaximizedstates)) then begin + fwindow.fnormalwindowrect:= fwidgetrect; + end; + if bo2 and (tws_windowvisible in fwindow.fstate) then begin + fwindow.checkwindow(windowevent); + end; + end; + if autosizecha and (fwidgetrect.cx = autosi.cx) and + (fwidgetrect.cy = autosi.cy) and (fautosizelevel < 6) then begin + //emergency break + inc(fautosizelevel); + try + internalsetwidgetrect(fwidgetrect,windowevent); + finally + dec(fautosizelevel); + end; + end; +end; + +procedure twidget.setwidgetrect(const Value: rectty); +var + bo1: boolean; +begin + bo1:= ws1_widgetrectsetting in fwidgetstate1; + include(fwidgetstate1,ws1_widgetrectsetting); + try + internalsetwidgetrect(value,false); + finally + if not bo1 then begin + exclude(fwidgetstate1,ws1_widgetrectsetting); + end; + end; +end; + +function twidget.getwidgetrect: rectty; +begin + result:= fwidgetrect; +end; + +function twidget.getright: integer; +begin + result:= fwidgetrect.x + fwidgetrect.cx; +end; + +procedure twidget.setright(const avalue: integer); +begin + if an_left in fanchors then begin + bounds_cx:= avalue - fwidgetrect.x; + end + else begin + bounds_x:= avalue - bounds_cx; + end; +end; + +function twidget.getbottom: integer; +begin + result:= fwidgetrect.y + fwidgetrect.cy; +end; + +procedure twidget.setbottom(const avalue: integer); +begin + if an_top in fanchors then begin + bounds_cy:= avalue - fwidgetrect.y; + end + else begin + bounds_y:= avalue - bounds_cy; + end; +end; + +procedure twidget.setsize(const Value: sizety); +var + rect1: rectty; +begin + rect1.pos:= fwidgetrect.pos; + rect1.size:= value; + internalsetwidgetrect(rect1,false); +end; + +procedure twidget.setpos(const Value: pointty); +var + rect1: rectty; +begin + rect1.size:= fwidgetrect.size; + rect1.pos:= value; + internalsetwidgetrect(rect1,false); +end; + +procedure twidget.setbounds_x(const Value: integer); +var + rect1: rectty; +begin + if fwidgetrect.x <> value then begin + rect1:= fwidgetrect; + rect1.x:= value; + internalsetwidgetrect(rect1,false); + end; +end; + +procedure twidget.setbounds_y(const Value: integer); +var + rect1: rectty; +begin + if fwidgetrect.y <> value then begin + rect1:= fwidgetrect; + rect1.y:= value; + internalsetwidgetrect(rect1,false); + end; +end; + +procedure twidget.setbounds_cx(const Value: integer); +var + rect1: rectty; +begin + if fwidgetrect.cx <> value then begin + rect1:= fwidgetrect; + if value < 0 then begin + rect1.cx:= 0; + end + else begin + rect1.cx:= value; + end; + internalsetwidgetrect(rect1,false); + end; +end; + +procedure twidget.setbounds_cy(const Value: integer); +var + rect1: rectty; +begin + if fwidgetrect.cy <> value then begin + rect1:= fwidgetrect; + if value < 0 then begin + rect1.cy:= 0; + end + else begin + rect1.cy:= value; + end; + internalsetwidgetrect(rect1,false); + end; +end; + +procedure twidget.updatesizerange(value: integer; var dest: integer); +begin + if dest <> value then begin + if value < 0 then begin + value:= 0; + end; + dest:= Value; + if value > 0 then begin + setwidgetrect(fwidgetrect); + end; + if not (csloading in componentstate) and ownswindow1 then begin + fwindow.sizeconstraintschanged; + end; + end; +end; + +procedure twidget.updatesizerange(const value: sizety; var dest: sizety); +begin + updatesizerange(value.cx,dest.cx); + updatesizerange(value.cy,dest.cy); +end; + +procedure twidget.setbounds_cxmin(const Value: integer); +begin + updatesizerange(value,fminsize.cx); +end; + +procedure twidget.setbounds_cymin(const Value: integer); +begin + updatesizerange(value,fminsize.cy); +end; + +procedure twidget.setbounds_cxmax(const Value: integer); +begin + updatesizerange(value,fmaxsize.cx); +end; + +procedure twidget.setbounds_cymax(const Value: integer); +begin + updatesizerange(value,fmaxsize.cy); +end; + +procedure twidget.setminsize(const avalue: sizety); +begin + updatesizerange(avalue,fminsize); +end; + +procedure twidget.setmaxsize(const avalue: sizety); +begin + updatesizerange(avalue,fmaxsize); +end; + +procedure twidget.dobeginread; +begin + if fframe <> nil then begin + exclude(fframe.fstate,fs_paintposinited); + end; + exclude(fwidgetstate1,ws1_parentclientsizeinited); + inherited; +end; + +procedure twidget.doendread; +begin + if fframe <> nil then begin + fframe.calcrects; //rects must be valid for parentfontchanged + end; + inherited; +end; + +procedure twidget.initparentclientsize; +var + int1: integer; +begin + if not (ws1_parentclientsizeinited in fwidgetstate1) then begin + include(fwidgetstate1,ws1_parentclientsizeinited); + if fparentwidget <> nil then begin + fparentclientsize:= fparentwidget.minclientsize; + end + else begin + fparentclientsize:= fwidgetrect.size; + end; + int1:= high(fwidgets); + while int1 >= 0 do begin //keep track of deleted widgets + if int1 <= high(fwidgets) then begin + fwidgets[int1].initparentclientsize; + end; + dec(int1); + end; + { + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].initparentclientsize; + end; + } + end; +end; + +procedure twidget.loaded; +begin + include(fwidgetstate,ws_loadedproc); + try + exclude(fwidgetstate1,ws1_widgetregionvalid); + initparentclientsize; + inherited; + doloaded; + sortzorder; + updatetaborder(nil); + parentfontchanged; + if ffont <> nil then begin + fontchanged; + end; +// if not (ws1_parentclientsizeinited in fwidgetstate1) then begin +// initparentclientsize; +// end; + sizechanged; + poschanged; + colorchanged; + enabledchanged; //-> statechanged + parentchanged; + visiblepropchanged; + if ownswindow1 and (ws_visible in fwidgetstate) and + (componentstate * [csloading,csinline] = []) then begin + fwindow.show(false); + end; + if showing then begin + doshow; + end; + finally + exclude(fwidgetstate,ws_loadedproc); + end; + updateskin; + if ws1_childscaled in fwidgetstate1 then begin + appinst.postevent(tobjectevent.create(ek_childscaled,ievent(self)), + [peo_local]); + end; +end; + +procedure twidget.setdesigning(value: boolean; + setchildren : boolean = true); +begin + if value then begin + include(fwidgetstate,ws_designing); //for widgetatpos condition + end + else begin + exclude(fwidgetstate,ws_designing); + end; + inherited; +end; + +function twidget.updateopaque(const children: boolean; + const widgetregioncall: boolean): boolean; + //true if widgetregionchanged called +var + bo1,bo2: boolean; + int1: integer; +begin + result:= false; + bo1:= ws_opaque in fwidgetstate; + if isvisible then begin + include(fwidgetstate,ws_isvisible); + if (fparentwidget = nil) or (fwidgetstate * [ws_nopaint] = []) and + (actualcolor <> cl_transparent) then begin + include(fwidgetstate,ws_opaque); + end + else begin + exclude(fwidgetstate,ws_opaque); + end; + end + else begin + fwidgetstate:= fwidgetstate - [ws_opaque,ws_isvisible]; + end; + if (bo1 <> (ws_opaque in fwidgetstate)) and (fparentwidget <> nil) + and not fparentwidget.isloading then begin + if widgetregioncall then begin + fparentwidget.widgetregionchanged(self); + end + else begin + bo2:= ws1_updateopaque in fwidgetstate1; + include(fwidgetstate1,ws1_updateopaque); + try + fparentwidget.widgetregionchanged(self); + finally + if not bo2 then begin + exclude(fwidgetstate1,ws1_updateopaque); + end; + end; + end; + result:= true; + end; + if children then begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].updateopaque(children,false); + end; + end; +end; + +procedure twidget.colorchanged; +var + int1: integer; +begin + updateopaque(true,false); + invalidatewidget; + for int1:= 0 to widgetcount - 1 do begin + with widgets[int1] do begin + if fcolor = cl_parent then begin + colorchanged; + end; + end; + end; +end; + +{$ifdef mse_with_ifi} + +function twidget.getifiwidgetstate: ifiwidgetstatesty; +begin + result:= [iws_loaded]; + if acs_releasing in factstate then begin + include(result,iws_releasing); + end; + if csdestroying in componentstate then begin + include(result,iws_releasing); + include(result,iws_destroying); + end; + if ws_visible in fwidgetstate then begin + include(result,iws_visible); + end; + if ws_enabled in fwidgetstate then begin + include(result,iws_enabled); + end; + if ws_entered in fwidgetstate then begin + include(result,iws_entered); + end; + if ws_focused in fwidgetstate then begin + include(result,iws_focused); + end; + if ws_active in fwidgetstate then begin + include(result,iws_active); + end; +end; + +procedure twidget.ifiwidgetstatechanged; +begin + if fifiserverintf <> nil then begin + fifiserverintf.statechanged(iificlient(self),getifiwidgetstate); + end; +end; + +{$endif} + +procedure twidget.statechanged; +begin + if fframe <> nil then begin + fframe.updatewidgetstate; + end; +{$ifdef mse_with_ifi} + ifiwidgetstatechanged; +{$endif} + if (fparentwidget <> nil) and fparentwidget.focused and canfocus then begin + fparentwidget.checksubfocus(false); + end; +end; + +procedure twidget.enabledchanged; +var + int1: integer; + bo1: boolean; +begin + bo1:= isenabled; + if not bo1 then begin + if focused then begin + window.setfocusedwidget(nil); + end; + end; + if fframe <> nil then begin + if bo1 or not (frl_nodisable in fframe.flocalprops) then begin + fframe.setdisabled(not bo1); + end; + end; + for int1:= 0 to widgetcount - 1 do begin + widgets[int1].enabledchanged; + end; + statechanged; + if (frame <> nil) then begin + fframe.enabledchanged(); + end; +end; + +procedure twidget.activechanged; +begin + statechanged; + if (ws_focused in fwidgetstate) and needsfocuspaint then begin + invalidatewidget; + end; + if (frame <> nil) then begin + fframe.activechanged; + end; +end; + +procedure twidget.visiblepropchanged; +begin + if fframe <> nil then begin + fframe.visiblechanged; + end; +end; + +procedure twidget.visiblechanged; +begin + updateopaque(false,false); + statechanged; +end; + +procedure twidget.poschanged; +begin + if fframe <> nil then begin + fframe.poschanged; + end; + if ownswindow1 then begin + fwindow.poschanged; + end; +end; + +procedure twidget.sizechanged; +var + bo1: boolean; +begin + if fframe <> nil then begin + with fframe do begin + bo1:= fs_stateupdating in fstate; + exclude(fstate,fs_stateupdating); + try + fframe.internalupdatestate(); + finally + if bo1 then begin + include(fstate,fs_stateupdating); + end; + end; + end; + end + else begin + clientrectchanged; + end; + if ownswindow1 then begin + fwindow.sizechanged; + end; +end; + +function twidget.getminshrinkpos: pointty; +begin + result:= fwidgetrect.pos; +// addpoint1(result,fminshrinkposoffset); +end; + +function twidget.getshrinkpriority: integer; +begin + result:= 0; +end; + +procedure twidget.tryshrink(const aclientsize: sizety); +begin + //dummy +end; + +function twidget.calcminscrollsize: sizety; +var + int1,int2: integer; + anch: anchorsty; + indent: framety; + clientorig: pointty; + pt1: pointty; + minsi: sizety; +begin + result:= nullsize; + if fframe <> nil then begin + indent:= fframe.fi.innerframe; + clientorig.x:= -fframe.fpaintrect.x-fframe.fclientrect.x; + clientorig.y:= -fframe.fpaintrect.y-fframe.fclientrect.y; + end + else begin + indent:= nullframe; + clientorig:= nullpoint; + end; + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1],fwidgetrect do begin + if (visible or (ow1_invisibleparentsizeextend in foptionswidget1)) and + not(ws1_nominsize in fwidgetstate1) or + (csdesigning in componentstate) then begin + pt1:= getminshrinkpos; + minsi:= minshrinksize; + if not (ow1_noparentwidthextend in foptionswidget1) then begin + anch:= fanchors * [an_left,an_right]; + if anch = [an_right] then begin + int2:= fparentclientsize.cx - x + indent.left - clientorig.x; + end + else begin + if anch = [] then begin + int2:= minsi.cx; + end + else begin + if anch = [an_left,an_right] then begin + int2:= fparentclientsize.cx - cx + minsi.cx; + end + else begin //[an_left] + int2:= clientorig.x + pt1.x + cx + indent.right; + end; + end; + end; + if int2 > result.cx then begin + result.cx:= int2; + end; + end; + + if not (ow1_noparentheightextend in foptionswidget1) then begin + anch:= fanchors * [an_top,an_bottom]; + if anch = [an_bottom] then begin + int2:= fparentclientsize.cy - y + indent.top - clientorig.y; + end + else begin + if anch = [] then begin + int2:= minsi.cy; + end + else begin + if anch = [an_top,an_bottom] then begin + int2:= fparentclientsize.cy - cy + minsi.cy; + end + else begin //[an_top] + int2:= clientorig.y + pt1.y + cy + indent.bottom; + end; + end; + end; + if int2 > result.cy then begin + result.cy:= int2; + end; + end; + end; + end; + end; +{ + if fframe <> nil then begin + fframe.checkminscrollsize(result); + end; +} +end; + +procedure twidget.childclientrectchanged(const sender: twidget); +begin + //dummy +end; + +procedure twidget.parentclientrectchanged; +var + size1,delta: sizety; + anch: anchorsty; + rect1: rectty; + int1: integer; + +begin + if ([csloading,csdestroying]*componentstate = []) and (fparentwidget <> nil) and + not (ws1_anchorsizing in fwidgetstate1) then begin + if ws1_scaling in fparentwidget.fwidgetstate1 then begin + fparentclientsize:= fparentwidget.minclientsize; + end + else begin + int1:= 0; //loopcount + repeat + size1:= fparentwidget.minclientsize(); + rect1:= fwidgetrect; + delta:= subsize(size1,fparentclientsize); + if ws1_anchorsetting in fwidgetstate1 then begin + delta:= nullsize; + exclude(fwidgetstate1,ws1_anchorsetting); + end; + anch:= fanchors * [an_left,an_right]; + if anch <> [an_left] then begin + if (anch = [an_left,an_right]) then begin + inc(rect1.cx,delta.cx); + end + else begin + if anch = [an_right] then begin + inc(rect1.x,delta.cx); + end + else begin + if anch = [] then begin + if fparentwidget <> nil then begin + rect1.x:= fparentwidget.clientwidgetpos.x; + rect1.cx:= fparentwidget.clientsize.cx; + end; + end; + end; + end; + end; + anch:= fanchors * [an_top,an_bottom]; + if anch <> [an_top] then begin + if (anch = [an_top,an_bottom]) then begin + inc(rect1.cy,delta.cy); + end + else begin + if anch = [an_bottom] then begin + inc(rect1.y,delta.cy); + end + else begin + if anch = [] then begin + if fparentwidget <> nil then begin + rect1.y:= fparentwidget.clientwidgetpos.y; + rect1.cy:= fparentwidget.clientsize.cy; + end; + end; + end; + end; + end; + fparentclientsize:= size1; + include(fwidgetstate1, ws1_anchorsizing); + try + setwidgetrect(rect1); + finally + exclude(fwidgetstate1, ws1_anchorsizing); + end; + inc(int1); + until sizeisequal(size1,fparentwidget.minclientsize) or (int1 > 5); + end; + end; +end; + +procedure twidget.widgetregioninvalid; +begin + exclude(fwidgetstate1,ws1_widgetregionvalid); + if not (ws_opaque in fwidgetstate) and (fparentwidget <> nil) then begin + fparentwidget.widgetregioninvalid; + end; +end; + +procedure twidget.clientrectchanged; +var + int1: integer; +begin + exclude(fwidgetstate,ws_minclientsizevalid); + widgetregioninvalid(); + if isvisible then begin + invalidatewidget; + reclipcaret; + end; + if (ws_loadedproc in fwidgetstate) then begin + parentclientrectchanged; + end + else begin + checkautosize; + end; + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1] do begin + if ([csloading,csdestroying] * componentstate = []) then begin + parentclientrectchanged(); + end; + end; + end; + if ([csloading,csdestroying] * componentstate = []) and + (fparentwidget <> nil) then begin + fparentwidget.childclientrectchanged(self); + end; +end; + +procedure twidget.widgetevent(const event: twidgetevent); +var + int1: integer; +begin + with event do begin + if ces_callchildren in state then begin + for int1:= 0 to high(fwidgets) do begin + if ces_processed in state then begin + break; + end; + fwidgets[int1].widgetevent(event); + end; + end; + end; +end; + +procedure twidget.sendwidgetevent(const event: twidgetevent); + //event will be destroyed +begin + try + widgetevent(event); + finally + event.Free1; + end; +end; + +procedure twidget.release(const nomodaldefer: boolean=false); +begin + if ownswindow1 then begin + window.endmodal; + end; + inherited; +end; + +procedure twidget.dobeforepaint(const canvas: tcanvas); +begin + //dummy +end; + +procedure twidget.dobeforepaintforeground(const canvas: tcanvas); +begin + //dummy +end; + +procedure twidget.dopaintforeground(const canvas: tcanvas); +begin + //dummy +end; + +procedure twidget.dopaintbackground(const canvas: tcanvas); +var + colorbefore: colorty; + face1: tcustomface; +begin + if frame <> nil then begin + colorbefore:= canvas.color; + canvas.color:= actualcolor; + fframe.paintbackground(canvas,makerect(nullpoint,fwidgetrect.size),true,true); + canvas.color:= colorbefore; + end; + if not canvas.clipregionisempty then begin + face1:= getactface; + if face1 <> nil then begin + if not (fao_overlay in face1.options) then begin + if fframe <> nil then begin + fframe.checkstate(); + canvas.remove(fframe.fclientrect.pos); + face1.paint(canvas,makerect(nullpoint,fframe.fpaintrect.size)); + canvas.move(fframe.fclientrect.pos); + end + else begin + face1.paint(canvas,makerect(nullpoint,fwidgetrect.size)); + end; + end; + end; + doonpaintbackground(canvas); + end; +end; + +procedure twidget.paintbackground(const canvas: tcanvas; + const arect: rectty); +var + colorbefore: colorty; + face1: tcustomface; + actcolor,col1: colorty; + pt1: pointty; +begin + canvas.save(); + actcolor:= actualcolor; + if (ws_opaque in fwidgetstate) or (actcolor <> cl_transparent) then begin + col1:= actcolor; + if actcolor = cl_transparent then begin + col1:= cl_background; //no parent + end; + canvas.fillrect(arect,col1); + end; + pt1:= canvas.origin; + if frame <> nil then begin + colorbefore:= canvas.color; + canvas.color:= actualcolor; + fframe.paintbackground(canvas,arect,true,true); + canvas.color:= colorbefore; + end; + if not canvas.clipregionisempty then begin + face1:= getactface; + if face1 <> nil then begin + if not (fao_overlay in face1.options) then begin + if fframe <> nil then begin + fframe.checkstate(); + canvas.remove(fframe.fclientrect.pos); + face1.paint(canvas,makerect(nullpoint, + subsize(arect.size,fframe.paintframedim))); + canvas.move(fframe.fclientrect.pos); + end + else begin + face1.paint(canvas,arect); + end; + end; + end; + end; + canvas.origin:= pt1; //no shift to paintrect +end; + +procedure twidget.doonpaintbackground(const canvas: tcanvas); +begin + //dummy +end; + +procedure twidget.dopaint(const canvas: tcanvas); +begin + dopaintbackground(canvas); + if not canvas.clipregionisempty then begin + dobeforepaintforeground(canvas); + dopaintforeground(canvas); + end; +end; + +procedure twidget.doonpaint(const canvas: tcanvas); +begin + //dummy +end; + +procedure twidget.dopaintoverlay(const canvas: tcanvas); +var + face1: tcustomface; +begin + face1:= getactface; + if face1 <> nil then begin + if fao_overlay in face1.options then begin + if fframe <> nil then begin + canvas.move(fframe.fpaintrect.pos); + face1.paint(canvas,makerect(nullpoint,fwidgetrect.size)); + canvas.remove(fframe.fpaintrect.pos); + end + else begin + face1.paint(canvas,makerect(nullpoint,fwidgetrect.size)); + end; + end; + end; + if fframe <> nil then begin + fframe.paintoverlay(canvas,makerect(nullpoint,fwidgetrect.size)); + end; +end; + +procedure twidget.paintoverlay(const canvas: tcanvas; + const arect: rectty); +var + face1: tcustomface; +begin + canvas.restore(); + face1:= getactface; + if face1 <> nil then begin + if fao_overlay in face1.options then begin + if fframe <> nil then begin + face1.paint(canvas,deflaterect(arect,fframe.paintframe)); + end + else begin + face1.paint(canvas,arect); + end; + end; + end; + if fframe <> nil then begin + fframe.paintoverlay(canvas,arect); + end; +end; + +function twidget.isgroupleader: boolean; +begin + result:= false; +end; + +function twidget.needsfocuspaint(): boolean; +begin + result:= (fframe <> nil) and fframe.needsfocuspaint; +end; + +function twidget.needsfocuspaintstate(): boolean; +begin + result:= needsfocuspaint() and (fwidgetstate * [ws_focused,ws_active] = + [ws_focused,ws_active]); +end; + +function twidget.getshowhint: boolean; +begin + result:= (ow_hinton in foptionswidget) or + not (ow_hintoff in foptionswidget) and + ((fparentwidget = nil) or fparentwidget.getshowhint); +end; + +procedure twidget.showhint(const aid: int32; var info: hintinfoty); +var + mstr1: msestring; +begin + if getshowhint and not(csdesigning in componentstate) then begin + if (aid <= hintidframe) and (fframe <> nil) then begin + fframe.showhint(aid,info); + end + else begin + mstr1:= hint; + if mstr1 <> '' then begin + info.caption:= mstr1; + end; + end; + end; +end; + +procedure twidget.doafterpaint(const canvas: tcanvas); +begin + if needsfocuspaintstate() then begin + if fframe <> nil then begin + fframe.dopaintfocusrect(canvas,makerect(nullpoint,fwidgetrect.size)); + end + else begin + drawfocusrect(canvas,makerect(nullpoint,fwidgetrect.size)); + end; + end; +end; + +function twidget.needsdesignframe: boolean; +begin + result:= + (ws_iswidget in fwidgetstate) and + not (ws1_nodesignframe in fwidgetstate1) and + (owner <> nil) and //no frame for toplevel + ( + ((fwidgetrect.cx = 0) or (fwidgetrect.cy = 0)) or + ( + ( + (fcolor = cl_transparent) or + (fparentwidget <> nil) and + (colortopixel(actualopaquecolor) = + colortopixel(fparentwidget.actualopaquecolor{backgroundcolor})) + ) and + ((fframe = nil) or + (fframe.fi.leveli = 0) and (fframe.fi.levelo = 0) and + ((fframe.fi.framewidth = 0) or (frame.fi.colorframe = cl_transparent)) + ) + ) + ); +end; + +procedure twidget.paint(const canvas: tcanvas); +label + endlab; +var + int1,int2: integer; + saveindex: integer; + actcolor: colorty; + col1: colorty; + reg1: gdiregionty; + rect1: rectty; + widget1: twidget; + bo1,bo2: boolean; + face1: tcustomface; + obj1: tobject; +begin + bo2:= ws1_painting in fwidgetstate1; + include(fwidgetstate1,ws1_painting); + canvas.save; + rect1.pos:= nullpoint; + rect1.size:= fwidgetrect.size; + canvas.intersectcliprect(rect1); + if canvas.clipregionisempty then begin + goto endlab; + end; + canvas.save; + if not (ws_nopaint in fwidgetstate) then begin + canvas.brushorigin:= nullpoint; + actcolor:= actualcolor; + saveindex:= canvas.save; + dobeforepaint(canvas); + if (high(fwidgets) >= 0) and + not (ws1_noclipchildren in fwidgetstate1) then begin + updatewidgetregion; + canvas.subclipregion(fwidgetregion.region); + end; + bo1:= not canvas.clipregionisempty; + if bo1 then begin + if (ws_opaque in fwidgetstate) or (actcolor <> cl_transparent) then begin + col1:= actcolor; + if actcolor = cl_transparent then begin + col1:= cl_background; //no parent + end; + canvas.fillrect(rect1,col1); + end; + {$ifdef mse_slowdrawing} + sleep(500); + {$endif} + canvas.font:= getfont; + canvas.color:= actcolor; + canvas.drawinfopo:= nil; + obj1:= canvas.target; + canvas.target:= self; + dopaint(canvas); + if not canvas.clipregionisempty then begin + doonpaint(canvas); + end; + canvas.target:= obj1; + end; + canvas.restore(saveindex); + if bo1 then begin + face1:= getactface; + if (face1 <> nil) and (fao_alphafadenochildren in face1.fi.options) then begin + canvas.move(paintpos); + face1.doalphablend(canvas); + canvas.remove(paintpos); + end; + end; + end + else begin + updatewidgetregion; + end; + if (widgetcount > 0) then begin + if (fframe <> nil) and not (ow_nochildpaintclip in foptionswidget) then begin + fframe.checkstate; + canvas.intersectcliprect(fframe.fpaintrect); + end; + rect1:= canvas.clipbox; + for int1:= 0 to widgetcount-1 do begin + widget1:= twidget(fwidgets[int1]); + with widget1 do begin + if isvisible and testintersectrect(rect1,fwidgetrect) then begin + saveindex:= canvas.save; + if not (ow_nochildclipsiblings in self.foptionswidget) then begin + for int2:= int1 + 1 to self.widgetcount - 1 do begin + with self.fwidgets[int2],tcanvas1(canvas) do begin + if visible and testintersectrect(widget1.fwidgetrect,fwidgetrect) then begin + //clip higher level siblings + if (ws_opaque in fwidgetstate) then begin + subcliprect(fwidgetrect); + end + else begin + reg1:= msegui.createregion(self.window.fgdi); + addopaquechildren(reg1); + subclipregion(reg1.region); + msegui.destroyregion(reg1); + end; + end; + end; + end; + end; + if not canvas.clipregionisempty then begin + canvas.move(fwidgetrect.pos); + paint(canvas); + end; + canvas.restore(saveindex); + end; + end; + end; + end; + canvas.restore; + canvas.brushorigin:= nullpoint; + face1:= getactface; + if (face1 <> nil) and (fao_alphafadeall in face1.fi.options) then begin + canvas.move(paintpos); + fface.doalphablend(canvas); + canvas.remove(paintpos); + end; + dopaintoverlay(canvas); + if (csdesigning in componentstate) and needsdesignframe then begin + canvas.dashes:= #2#3; + canvas.drawrect(makerect(0,0,fwidgetrect.cx-1,fwidgetrect.cy-1),cl_black); + canvas.dashes:= ''; + end; + doafterpaint(canvas); +endlab: + canvas.restore; + if not bo2 then begin + exclude(fwidgetstate1,ws1_painting); + end; +end; + +procedure twidget.parentwidgetregionchanged(const sender: twidget); +begin + //dummy +end; + +procedure twidget.widgetregionchanged(const sender: twidget); +var + int1: integer; +begin + if not (csdestroying in componentstate) then begin + widgetregioninvalid; + if sender = nil then begin + invalidate; + end + else begin + invalidaterect(sender.fwidgetrect,org_widget); + end; + if componentstate * [csloading,csdestroying] = [] then begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].parentwidgetregionchanged(sender); + end; + end; + end; +end; + +procedure twidget.addopaquechildren(var region: gdiregionty); +var + int1: integer; + widget: twidget; + rect1: rectty; +begin + if not ((fface <> nil) and (fao_alphafadeall in fface.fi.options)) then begin + updateroot; + if ws_isvisible in fwidgetstate then begin + rect1:= paintrect; + for int1:= 0 to widgetcount - 1 do begin + widget:= twidget(fwidgets[int1]); + if ws_opaque in widget.fwidgetstate then begin + regaddrect(region,moverect(intersectrect(rect1,widget.fwidgetrect), + frootpos)); + end + else begin + widget.addopaquechildren(region); + end; + end; + end; + end; +end; + +procedure twidget.updatewidgetregion; +begin + if not (ws1_widgetregionvalid in fwidgetstate1) then begin + destroyregion(fwidgetregion); + if widgetcount > 0 then begin + fwidgetregion:= createregion(window.fgdi); + addopaquechildren(fwidgetregion); +{ + if fframe <> nil then begin + frame.checkstate; + regintersectrect(fwidgetregion,makerect(fframe.fpaintrect.x+frootpos.x, + fframe.fpaintrect.y+frootpos.y, + fframe.fpaintrect.cx,fframe.fpaintrect.cy)); + end + else begin + regintersectrect(fwidgetregion,makerect(frootpos,fwidgetrect.size)); + end; +} + end; + include(fwidgetstate1,ws1_widgetregionvalid); + end; +end; + +function twidget.getgdi: pgdifunctionaty; +begin + result:= getdefaultgdifuncs; +end; + +procedure twidget.createwindow; +begin + twindow.create(self,getgdi); //sets fwindow +end; + +procedure twidget.updateroot; +begin + if not (ws1_rootvalid in fwidgetstate1) then begin + if fparentwidget <> nil then begin + fwindow:= fparentwidget.window; + frootpos:= addpoint(fparentwidget.rootpos,fwidgetrect.pos); + end + else begin + frootpos:= nullpoint; + if (fwindow = nil) and not (ws_destroying in fwidgetstate) then begin + createwindow; + invalidatewidget; + if (ws_visible in fwidgetstate) and + (componentstate * [csloading,csinline,csdestroying] = []) then begin + fwindow.show(false); + if not (ws_loadedproc in fwidgetstate) then begin + include(fwidgetstate1,ws1_rootvalid); + doshow(); + end; + end; + end; + end; + include(fwidgetstate1,ws1_rootvalid); + end; +end; + +procedure twidget.rootchanged(const aflags: rootchangeflagsty); +var + int1: integer; +begin + if fparentwidget <> nil then begin + fwindow:= nil; + end; + fwidgetstate1:= fwidgetstate1 - [{ws1_widgetregionvalid,}ws1_rootvalid]; + if rcf_widgetregioninvalid in aflags then begin + exclude(fwidgetstate1,ws1_widgetregionvalid); + end; + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].rootchanged(aflags); + end; +end; + +procedure twidget.parentchanged; +var + int1: integer; +begin + if not (ws_loadedproc in fwidgetstate) then begin + updateopaque(false,false); + parentfontchanged; + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1] do begin + parentchanged; + end; + end; + end; +end; + +function twidget.ownswindow1: boolean; +begin + result:= (fwindow <> nil) and (fwindow.fownerwidget = self); +end; + +function twidget.windowallocated: boolean; +begin + result:= (fwindow <> nil) and fwindow.haswinid and + (componentstate * [csloading,csdestroying] = []); + +end; + +function twidget.ownswindow: boolean; +begin + result:= (fwindow <> nil) and (fwindow.fownerwidget = self) and + (fwindow.fwindow.id <> 0); +end; + +function twidget.updaterect: rectty; //invalidated area, origin = clientpos +begin + result:= window.updaterect; + translateclientpoint1(result.pos,rootwidget,self); +end; + +function twidget.window: twindow; +begin + updateroot; + result:= fwindow; +end; + +function twidget.rootpos: pointty; +begin + updateroot; + result:= frootpos; +end; + +function twidget.rootwidgetrect: rectty; +begin + updateroot; + result.pos:= frootpos; + result.size:= fwidgetrect.size; +end; +function twidget.getscreenpos: pointty; +begin + updateroot; + result:= addpoint(frootpos,fwindow.screenpos); +end; + +procedure twidget.setscreenpos(const avalue: pointty); +begin + updateroot; + fwindow.screenpos:= subpoint(avalue,frootpos); +end; + +function twidget.clientpostowidgetpos(const apos: pointty): pointty; +begin + result:= addpoint(apos,clientwidgetpos); +end; + +function twidget.widgetpostoclientpos(const apos: pointty): pointty; +begin + result:= subpoint(apos,clientwidgetpos); +end; + +function twidget.widgetpostopaintpos(const apos: pointty): pointty; +begin + result:= subpoint(apos,paintpos); +end; + +function twidget.paintpostowidgetpos(const apos: pointty): pointty; +begin + result:= addpoint(apos,paintpos); +end; + +function twidget.rootwidget: twidget; +var + wi1,wi2: twidget; +begin + wi1:= self; + repeat + wi2:= wi1; + wi1:= wi2.fparentwidget; + until wi1 = nil; + result:= wi2; +end; + +function twidget.parentofcontainer: twidget; +var + widget1: twidget; +begin + result:= fparentwidget; + if (fparentwidget <> nil) then begin + widget1:= fparentwidget.fparentwidget; + if (widget1 <> nil) and not (ws_iswidget in result.fwidgetstate) then begin + result:= widget1; + end; + end; +end; + +function twidget.calcframewidth(arect: prectty): sizety; +begin + if fframe <> nil then begin + fframe.checkstate; + with arect^ do begin + result.cx:= fwidgetrect.cx - cx; + result.cy:= fwidgetrect.cy - cy; + end; + end + else begin + result:= nullsize; + end; +end; + +function twidget.framedim: sizety; + //widgetrect.size - paintrect.size +begin + {$ifdef FPC} {$checkpointer off} {$endif} + result:= calcframewidth(@fframe.fpaintrect); + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +function twidget.framedimnoscrollbar: sizety; +begin + result:= framedim(); + if fframe <> nil then begin + fframe.addscrollbarwidth(result); + end; +end; + +function twidget.clientframewidth: sizety; + //widgetrect.size - clientrect.size +begin + {$ifdef FPC} {$checkpointer off} {$endif} + result:= calcframewidth(@fframe.fclientrect); + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +function twidget.innerclientframewidth: sizety; + //widgetrect.size - innerclientrect.size +begin + {$ifdef FPC} {$checkpointer off} {$endif} + result:= calcframewidth(@fframe.finnerclientrect); + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +function twidget.innerframewidth: sizety; +begin + if frame <> nil then begin + fframe.checkstate; + result.cx:= fframe.fclientrect.cx - fframe.finnerclientrect.cx; + result.cy:= fframe.fclientrect.cy - fframe.finnerclientrect.cy; + end + else begin + result:= nullsize; + end; +end; + +function twidget.framerect: rectty; +begin + if fframe <> nil then begin + fframe.checkstate; + result.pos:= pointty(fframe.fouterframe.topleft); + result.size:= framesize; + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.framepos: pointty; +begin + if fframe <> nil then begin + fframe.checkstate; + result:= pointty(fframe.fouterframe.topleft); + end + else begin + result:= nullpoint; + end; +end; + +function twidget.frameinnerrect: rectty; +begin + if fframe <> nil then begin + fframe.checkstate; + result:= inflaterect(fframe.fpaintrect,fframe.fpaintframedelta); + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.paintrect: rectty; +begin + if fframe <> nil then begin + fframe.checkstate; + result:= fframe.fpaintrect; + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.paintclientrect: rectty; //origin = clientrect +begin + if fframe <> nil then begin + fframe.checkstate; + result.x:= -fframe.fclientrect.x; + result.y:= -fframe.fclientrect.y; + result.size:= fframe.fpaintrect.size; + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.clippedpaintrect: rectty; //origin = pos, cliped by all parentpaintrects +var + po1: pointty; + widget1: twidget; +begin + result:= paintrect; + po1:= nullpoint; + widget1:= self; + while widget1.fparentwidget <> nil do begin + subpoint1(po1,widget1.fwidgetrect.pos); + widget1:= widget1.fparentwidget; + if not intersectrect(result,moverect(widget1.paintrect,po1),result) then begin + break; + end; + end; +end; + +function twidget.paintpos: pointty; +begin + if fframe <> nil then begin + fframe.checkstate; + result:= fframe.fpaintrect.pos; + end + else begin + result:= nullpoint; + end; +end; + +function twidget.innerpaintrect: rectty; //origin = pos +begin + if fframe <> nil then begin + result:= deflaterect(fframe.fpaintrect,fframe.fi.innerframe); + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.widgetsizerect: rectty; //pos = nullpoint +begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; +end; + +function twidget.paintsizerect: rectty; //pos = nullpoint +begin + result.pos:= nullpoint; + result.size:= paintsize; +end; + +function twidget.clientsizerect: rectty; //pos = nullpoint +begin + result.pos:= nullpoint; + result.size:= clientsize; +end; + +function twidget.containerclientsizerect: rectty; //pos = nullpoint +begin + result.pos:= nullpoint; + result.size:= container.clientsize; +end; + +function twidget.getclientrect: rectty; +begin + if fframe <> nil then begin + with fframe do begin + checkstate; + result:= fclientrect; + end; + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.windowpo: pwindowty; +begin + window.checkwindowid; + result:= @fwindow.fwindow; +end; + +function twidget.innerclientpos: pointty; +begin + if frame <> nil then begin + with frame do begin + checkstate; + result:= pointty(fi.innerframe.topleft); + end; + end + else begin + result:= nullpoint; + end; +end; + +function twidget.innerclientsize: sizety; +begin + if frame <> nil then begin + with frame do begin + checkstate; + result:= finnerclientrect.size; + end; + end + else begin + result:= fwidgetrect.size; + end; +end; + +function twidget.innerclientrect: rectty; +begin + if frame <> nil then begin + with frame do begin + checkstate; + result:= makerect(pointty(fi.innerframe.topleft),finnerclientrect.size); + end; + end + else begin + result:= clientrect; + end; +end; + +function twidget.innerparentrect: rectty; //origin = parentwidget.pos +begin + result:= innerwidgetrect; + addpoint1(result.pos,fwidgetrect.pos); +end; + +function twidget.innerwidgetrect: rectty; +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result.pos:= addpoint(fpaintrect.pos,finnerclientrect.pos); + result.size:= finnerclientrect.size; + end; + end + else begin + result:= clientrect; + end; +end; + +procedure twidget.internalcreateframe; +begin + tframe.create(iscrollframe(self)); +end; + +function twidget.invalidateneeded: boolean; +begin + result:= showing and (fnoinvalidate = 0) and + not (csloading in componentstate); + if result then begin + updateroot; + end; +end; + +procedure twidget.invalidatewidget; //invalidates the whole widget +begin + if invalidateneeded then begin + fwindow.invalidaterect(makerect(frootpos,fwidgetrect.size),self); + end; +end; + +procedure twidget.invalidate; //invalidates the clientarea +begin + if invalidateneeded then begin + if fframe <> nil then begin + fwindow.invalidaterect(makerect(addpoint(frootpos,fframe.fpaintrect.pos), + fframe.fpaintrect.size),self); + end + else begin + fwindow.invalidaterect(makerect(frootpos,fwidgetrect.size),self); + end; + end; +end; + +procedure twidget.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +var + rect1,rect2: rectty; + po1: prectty; +begin + if invalidateneeded then begin + updateroot; + rect1:= rect; + rect2.pos:= nullpoint; + rect2.size:= fwidgetrect.size; + po1:= @rect2; + case org of + org_paint: begin + if fframe <> nil then begin + inc(rect1.x,fframe.fpaintrect.pos.x); + inc(rect1.y,fframe.fpaintrect.pos.y); + po1:= @fframe.fpaintrect; + end; + end; + org_client: begin + if fframe <> nil then begin + inc(rect1.x,fframe.fclientrect.pos.x); + inc(rect1.x,fframe.fpaintrect.pos.x); + inc(rect1.y,fframe.fclientrect.pos.y); + inc(rect1.y,fframe.fpaintrect.pos.y); + po1:= @fframe.fpaintrect; + end; + end; + org_inner: begin + if fframe <> nil then begin + inc(rect1.x,fframe.finnerclientrect.pos.x); + inc(rect1.y,fframe.finnerclientrect.pos.y); + inc(rect1.x,fframe.fpaintrect.pos.x); + inc(rect1.y,fframe.fpaintrect.pos.y); + po1:= @fframe.fpaintrect; + end; + end; + end; + if not noclip then begin + msegraphutils.intersectrect(rect1,po1^,rect1); + end; + inc(rect1.x,frootpos.x); + inc(rect1.y,frootpos.y); + fwindow.invalidaterect(rect1,self); + end; +end; + +procedure twidget.invalidateframestaterect(const rect: rectty; + const aframe: tcustomframe; const org: originty = org_client); +begin + if (fframe = nil) or (fframe.fi.frameimage_list = nil) then begin + invalidaterect(rect,org,true); + end + else begin + invalidaterect(inflaterect(rect,aframe.innerframe),org,true); +// invalidatewidget; + end; +end; + +procedure twidget.invalidateframestate(); +begin + if (fframe = nil) or ((fframe.fi.frameimage_list = nil) and + (fframe.fi.colorframedefault = cl_default)) then begin + invalidate(); + end + else begin + invalidatewidget(); + end; +end; + +function twidget.hasoverlappingsiblings(arect: rectty): boolean; +var + int1: integer; + widget1: twidget; +begin + result:= false; + if (fparentwidget <> nil) and showing then begin + updateroot; + addpoint1(arect.pos,fwidgetrect.pos); + for int1:= high(fparentwidget.fwidgets) downto 0 do begin + widget1:= fparentwidget.fwidgets[int1]; + if widget1 = self then begin + break; + end; + if intersectrect(widget1.fwidgetrect,arect,arect) and + widget1.showing then begin + result:= true; + exit; + end; + end; + result:= fparentwidget.hasoverlappingsiblings(arect); + end; +end; + +procedure twidget.internalcreateface; +begin + tface.create(self); +end; + +function twidget.widgetatpos(var info: widgetatposinfoty): twidget; +var + int1: integer; + astate: widgetstatesty; + ainfo: mouseeventinfoty; +begin + result:= nil; + with info do begin + if (pos.x < 0) or (pos.y < 0) or (pos.x >= fwidgetrect.cx) or + (pos.y >= fwidgetrect.cy) then begin + exit; + end + else begin + if info.mouseeventinfopo = nil then begin + fillchar(ainfo,sizeof(ainfo),0); + ainfo.pos:= info.pos; + updatemousestate(ainfo); + end + else begin + updatemousestate(info.mouseeventinfopo^); + end; + astate:= fwidgetstate; + if isvisible then begin + include(astate,ws_visible); + end; + if csdesigning in componentstate then begin + include(astate,ws_enabled); + end; + if parentstate * astate <> parentstate then begin + exit; + end; + end; + if (frame = nil) or (ow_nochildpaintclip in foptionswidget) or + pointinrect(pos,fframe.fpaintrect) then begin + for int1:= widgetcount - 1 downto 0 do begin + with widgets[int1] do begin + subpoint1(info.pos,fwidgetrect.pos); + if info.mouseeventinfopo <> nil then begin + info.mouseeventinfopo^.pos:= info.pos; + end; + result:= widgetatpos(info); + addpoint1(info.pos,fwidgetrect.pos); + if info.mouseeventinfopo <> nil then begin + info.mouseeventinfopo^.pos:= info.pos; + end; + if result <> nil then begin + exit; + end; + end; + end; + end; + if childstate * astate = childstate then begin + result:= self; + end; + end; +end; + +function twidget.widgetatpos(const pos: pointty): twidget; +var + info: widgetatposinfoty; +begin + fillchar(info,sizeof(info),0); + info.pos:= pos; + result:= widgetatpos(info); +end; + +function twidget.childatpos(const pos: pointty; const clientorigin: boolean = true): twidget; +var + widget1: twidget; + po1: pointty; + int1: integer; + +begin + widget1:= container; + result:= nil; + po1:= pos; + if clientorigin then begin + addpoint1(po1,clientwidgetpos); + end; + if widget1 <> self then begin + translatewidgetpoint1(po1,self,widget1); + end; + with widget1 do begin + for int1:= high(fwidgets) downto 0 do begin + with fwidgets[int1] do begin + if isvisible and pointinrect(po1,fwidgetrect) then begin + result:= widget1.fwidgets[int1]; + break; + end; + end; + end; + end; +end; + +function compxbanded(const l,r): integer; +begin + result:= (twidget(l).fwidgetrect.y + twidget(l).fwidgetrect.cy) - + twidget(r).fwidgetrect.y - 1; + if result >= 0 then begin + result:= -((twidget(r).fwidgetrect.y + twidget(r).fwidgetrect.cy) - + twidget(l).fwidgetrect.y - 1); + if result <= 0 then begin + result:= twidget(l).fwidgetrect.x - twidget(r).fwidgetrect.x; + end; + end; +end; + +function twidget.getsortxchildren(const banded: boolean = false): widgetarty; +//var +// int1: integer; +begin + result:= copy(container.fwidgets); + if banded then begin + sortarray(pointerarty(result),{$ifdef FPC}@{$endif}compxbanded); + end + else begin + sortwidgetsxorder(result); + end; +end; + +function compybanded(const l,r): integer; +begin + result:= (twidget(l).fwidgetrect.x + twidget(l).fwidgetrect.cx) - + twidget(r).fwidgetrect.x - 1; + if result >= 0 then begin + result:= -((twidget(r).fwidgetrect.x + twidget(r).fwidgetrect.cx) - + twidget(l).fwidgetrect.x - 1); + if result <= 0 then begin + result:= twidget(l).fwidgetrect.y - twidget(r).fwidgetrect.y; + end; + end; +end; + +function twidget.getsortychildren(const banded: boolean = false): widgetarty; +begin + result:= copy(container.fwidgets); + if banded then begin + sortarray(pointerarty(result),{$ifdef FPC}@{$endif}compybanded); + end + else begin + sortwidgetsyorder(result); + end; +end; + +function twidget.widgetatpos(const pos: pointty; const state: widgetstatesty): twidget; +var + info: widgetatposinfoty; +begin + fillchar(info,sizeof(info),0); + info.pos:= pos; + info.parentstate:= state; + info.childstate:= state; + result:= widgetatpos(info); +end; + +function twidget.getlogicalchildren: widgetarty; //children of container +var + int1,int2: integer; +begin + with container do begin + setlength(result,length(fwidgets)); + int2:= 0; + for int1:= 0 to high(result) do begin + result[int2]:= fwidgets[int1]; + if ws_iswidget in result[int2].fwidgetstate then begin + inc(int2); + end; + end; + setlength(result,int2); + end; +end; + +procedure twidget.addlogicalchildren(var achildren: widgetarty); +begin + stackarray(pointerarty(getlogicalchildren),pointerarty(achildren)); +end; + +function twidget.findlogicalchild(const aname: ansistring): twidget; +begin + result:= dofindwidget(getlogicalchildren,aname); +end; + +function twidget.enteredchild(): twidget; +var + i1: int32; +begin + result:= nil; + with container do begin + for i1:= 0 to high(fwidgets) do begin + if ws_entered in fwidgets[i1].fwidgetstate then begin + result:= fwidgets[i1]; + break; + end; + end; + end; +end; + +function twidget.mouseeventwidget(const info: mouseeventinfoty): twidget; +var + findinfo: widgetatposinfoty; +begin + fillchar(findinfo,sizeof(findinfo),0); + with findinfo do begin + pos:= info.pos; + mouseeventinfopo:= @info; + parentstate:= [ws_enabled,ws_isvisible]; + case info.eventkind of + ek_buttonpress,ek_buttonrelease: begin + childstate:= [ws_enabled,ws_isvisible,ws_wantmousebutton]; + end; + ek_mousemove,ek_mousepark: begin + childstate:= [ws_enabled,ws_isvisible,ws_wantmousemove]; + end; + ek_mousewheel: begin + childstate:= [ws_enabled,ws_isvisible{,ws_wantmousewheel}]; + end; + end; + end; + result:= widgetatpos(findinfo); +end; + +procedure twidget.updatemousestate(const info: mouseeventinfoty); +begin + fwidgetstate:= fwidgetstate - + [ws_mouseinclient,ws_wantmousebutton,ws_wantmousemove,ws_wantmousefocus]; + if fframe <> nil then begin + fframe.updatemousestate(self,info); + end + else begin + if not (ow_mousetransparent in foptionswidget) then begin + if (info.pos.x >= 0) and (info.pos.x < fwidgetrect.cx) and + (info.pos.y >= 0) and (info.pos.y < fwidgetrect.cy) then begin + fwidgetstate:= fwidgetstate + + [ws_mouseinclient,ws_wantmousebutton,ws_wantmousemove,ws_wantmousefocus]; + end; + end; + end; +end; + +function twidget.getclientoffset: pointty; +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= addpoint(fpaintrect.pos,fclientrect.pos); + end; + end + else begin + result:= nullpoint; + end; +end; + +function twidget.isclientmouseevent(var info: mouseeventinfoty): boolean; +begin + with info do begin + if not (es_processed in eventstate) or + (info.eventkind = ek_mousemove) then begin + updatemousestate(info); + if [ws_mouseinclient,ws_clientmousecaptured] * fwidgetstate <> [] then begin + if (appinst.fclientmousewidget <> self) and not (es_child in eventstate) then begin + //call updaterootwidget + appinst.setclientmousewidget(self,info.pos); + end; + result:= true; + if fframe <> nil then begin + subpoint1(pos,getclientoffset); + end; + end + else begin + appinst.setclientmousewidget(nil,nullpoint); + result:= false; + end; + end + else begin + result:= false; + end; + end; +end; + +function twidget.wantmousefocus(const info: mouseeventinfoty): boolean; +begin + result:= not (es_nofocus in info.eventstate) and {not focused and} + (ws_wantmousefocus in fwidgetstate)and + (ow_mousefocus in foptionswidget) and canfocus; +{ + if result and focused then begin + activate; + result:= false; + end; +} +end; + +procedure twidget.mouseevent(var info: mouseeventinfoty); + + procedure doclientmouseevent; + begin + include(info.eventstate,es_client); + try + clientmouseevent(info); + if canassistive() {and (ws_iswidget in widgetstate)} then begin + assistiveserver.doclientmouseevent(getiassistiveclient(),info); + end; + finally + exclude(info.eventstate,es_client); + end; + end; //doclientmouseevent + +var + clientoffset: pointty; + wi1: twidget; +begin + exclude(fwidgetstate,ws_newmousecapture); + if info.eventstate * [es_child,es_processed] = [] then begin + include(info.eventstate,es_child); + try + childmouseevent(self,info); + finally + exclude(info.eventstate,es_child); + end; + end; + with info do begin + if not (eventkind in mouseregionevents) then begin + if not (ss_left in shiftstate) and + not((eventkind = ek_buttonrelease) and (button = mb_left)) then begin + exclude(fwidgetstate,ws_lclicked); + end; + if not (ss_middle in shiftstate) and + not((eventkind = ek_buttonrelease) and (button = mb_middle)) then begin + exclude(fwidgetstate,ws_mclicked); + end; + if not (ss_right in shiftstate) and + not((eventkind = ek_buttonrelease) and (button = mb_right)) then begin + exclude(fwidgetstate,ws_rclicked); + end; + end; + if not (es_processed in info.eventstate) then begin + clientoffset:= nullpoint; + case eventkind of + ek_mousemove,ek_mousepark: begin + if isclientmouseevent(info) then begin + doclientmouseevent; + clientoffset:= getclientoffset; + end; + end; + ek_mousecaptureend: begin + if ws_clientmousecaptured in fwidgetstate then begin + doclientmouseevent; + end; + end; + ek_clientmouseleave: begin + if (fframe <> nil) and frame.needsmouseenterinvalidate() then begin + invalidatewidget; + end; + if appinst.fmousewidget = self then begin + if fparentwidget <> nil then begin + fparentwidget.updatecursorshape(addpoint(appinst.fmousewidgetpos, + fparentwidget.fwidgetrect.pos)) {(true)}; + end + else begin + appinst.widgetcursorshape:= cr_default; + end; + end; + doclientmouseevent; + end; + ek_clientmouseenter: begin + if (fframe <> nil) and fframe.needsmouseenterinvalidate() then begin + invalidatewidget; + end; + updatecursorshape(info.pos){(true)}; + doclientmouseevent; + end; + ek_buttonpress: begin + if button = mb_left then begin + include(fwidgetstate,ws_lclicked); + if (fframe <> nil) and fframe.needsclickinvalidate() then begin + invalidatewidget; + end; + end; + if button = mb_middle then begin + include(fwidgetstate,ws_mclicked); + end; + if button = mb_right then begin + include(fwidgetstate,ws_rclicked); + end; + if appinst.fmousecapturewidget <> self then begin + include(fwidgetstate,ws_newmousecapture); + end; + appinst.capturemouse(self,true); + if isclientmouseevent(info) then begin + include(fwidgetstate,ws_clientmousecaptured); + doclientmouseevent; + clientoffset:= getclientoffset; + end; + { + wi1:= self; + repeat + with wi1 do begin + if wantmousefocus(info) then begin + if focused then begin + activate; + end + else begin + setfocus; + end; + break; + end; + end; + wi1:= wi1.parentwidget; + until wi1 = nil; + } + end; + ek_buttonrelease: begin + if (button = mb_left) and (fframe <> nil) and + fframe.needsclickinvalidate() then begin + invalidatewidget; + end; + if isclientmouseevent(info) then begin + doclientmouseevent; + clientoffset:= getclientoffset; + end; + end; + end; + addpoint1(pos,clientoffset); + end; + case eventkind of + ek_buttonpress: begin + wi1:= self; + repeat + with wi1 do begin + if wantmousefocus(info) then begin + if focused then begin + activate; + end + else begin + setfocus; + end; + break; + end; + end; + wi1:= wi1.parentwidget; + until wi1 = nil; + end; + ek_buttonrelease: begin + if button = mb_left then begin + exclude(fwidgetstate,ws_lclicked); + end; + if button = mb_middle then begin + exclude(fwidgetstate,ws_mclicked); + end; + if button = mb_right then begin + exclude(fwidgetstate,ws_rclicked); + end; + if (appinst <> nil) and ((shiftstate - mousebuttontoshiftstate(button)) * + mousebuttons = []) and + (appinst.fmousecapturewidget = self) then begin + if not (ws_mousecaptured in fwidgetstate) then begin + appinst.capturemouse(nil,false); + end + else begin + fwidgetstate:= fwidgetstate - [ws_clientmousecaptured]; + // appinst.ungrabpointer; ???? + end; + end; + end; + end; + end; +end; + +procedure twidget.mousepreview(const sender: twidget; + var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + if (fparentwidget <> nil) and (self <> window.fmodalwidget) then begin + fparentwidget.mousepreview(sender,info); + end; + end; +end; + +procedure twidget.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + if (fparentwidget <> nil) and (self <> window.fmodalwidget) then begin + fparentwidget.childmouseevent(sender,info); + end; + end; +end; + + +procedure twidget.domousewheelevent(var info: mousewheeleventinfoty); +begin + //dummy +end; + +procedure twidget.mousewheelevent(var info: mousewheeleventinfoty); +var + bo1: boolean; + pt1: pointty; +begin + with info do begin + if not (es_processed in eventstate) then begin + if ow_mousewheel in foptionswidget then begin + domousewheelevent(info); + end; + if not (es_processed in eventstate) and (fparentwidget <> nil) and + (self <> window.fmodalwidget) then begin + pt1:= self.pos; + addpoint1(pos,pt1); + bo1:= es_child in eventstate; + try + include(eventstate,es_child); + fparentwidget.mousewheelevent(info); + finally + subpoint1(pos,pt1); + if not bo1 then begin + exclude(eventstate,es_child); + end; + end; + end; + end; + end; +end; + +procedure twidget.setclientclick; +begin + appinst.capturemouse(self,true); + fwidgetstate:= fwidgetstate + [ws_lclicked,ws_clientmousecaptured]; +end; + +procedure twidget.releasebuttonpressgrab(); +begin + if appinst.fmousecapturewidget = self then begin + appinst.ungrabpointer(); + end; +end; + +procedure twidget.clientmouseevent(var info: mouseeventinfoty); +begin + //dummy +end; + +function twidget.getclientpos: pointty; +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= fclientrect.pos; + end + end + else begin + result:= nullpoint; + end; +end; + +function twidget.getclientsize: sizety; +begin + if fframe <> nil then begin + with fframe do begin + checkstate; + result:= fclientrect.size; + end; + end + else begin + result:= fwidgetrect.size; + end; +end; + +procedure twidget.changeclientsize(const delta: sizety); //asynchronouse +begin + application.postevent(tresizeevent.create(ievent(self),delta)); +end; + +procedure twidget.setanchordwidgetsize(const asize: sizety); +var + rect1: rectty; +begin + rect1.pos:= fwidgetrect.pos; + rect1.size:= asize; + if fanchors * [an_left,an_right] = [an_right] then begin + rect1.x:= rect1.x - rect1.cx + fwidgetrect.cx; + end; + if fanchors * [an_top,an_bottom] = [an_bottom] then begin + rect1.y:= rect1.y - rect1.cy + fwidgetrect.cy; + end; + widgetrect:= rect1; +end; + +procedure twidget.setclientsize(const asize: sizety); +begin + setanchordwidgetsize(addsize(asize,clientframewidth)); +end; + +function twidget.getclientwidth: integer; +begin + result:= getclientsize.cx; +end; + +procedure twidget.setclientwidth(const avalue: integer); +begin + setclientsize(makesize(avalue,getclientsize.cy)); +end; + +function twidget.getclientheight: integer; +begin + result:= getclientsize.cy; +end; + +procedure twidget.setclientheight(const avalue: integer); +begin + setclientsize(makesize(getclientsize.cx,avalue)); +end; + +function twidget.getpaintsize: sizety; +begin + if fframe <> nil then begin + fframe.checkstate; + result:= fframe.fpaintrect.size; + end + else begin + result:= fwidgetrect.size; + end; +end; + +procedure twidget.setpaintsize(const avalue: sizety); +begin + setanchordwidgetsize(addsize(avalue,framedim)); +end; + +function twidget.getframesize: sizety; +begin + if fframe <> nil then begin + fframe.checkstate; + with fframe.fouterframe do begin + result.cx:= fwidgetrect.cx - left - right; + result.cy:= fwidgetrect.cy - top - bottom; + end; + end + else begin + result:= fwidgetrect.size; + end; +end; + +procedure twidget.setframesize(const avalue: sizety); +var + si1: sizety; +begin + si1:= avalue; + if fframe <> nil then begin +// fframe.checkstate; + with fframe.fouterframe do begin + si1.cx:= si1.cx + left + right; + si1.cy:= si1.cy + top + bottom; + end; + end; + setanchordwidgetsize(si1); +end; + +procedure twidget.setframewidth(const avalue: integer); +begin + setframesize(ms(avalue,getframesize.cy)); +end; + +procedure twidget.setframeheight(const avalue: integer); +begin + setframesize(ms(getframesize.cx,avalue)); +end; + +procedure twidget.setpaintwidth(const avalue: integer); +begin + setpaintsize(ms(avalue,getpaintsize.cy)); +end; + +procedure twidget.setpaintheight(const avalue: integer); +begin + setpaintsize(ms(getpaintsize.cx,avalue)); +end; + +function twidget.getframeheight: integer; +begin + result:= getframesize.cy; +end; + +function twidget.getpaintwidth: integer; +begin + result:= getpaintsize.cx; +end; + +function twidget.getpaintheight: integer; +begin + result:= getpaintsize.cy; +end; + +function twidget.clientwidgetrect: rectty; //origin = pos +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= fclientrect; + addpoint1(result.pos,fpaintrect.pos); + end + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.widgetclientrect: rectty; //origin = clientrect.pos +begin + result.size:= fwidgetrect.size; + if fframe <> nil then begin + with frame do begin + checkstate; + result.x:= fpaintrect.x-fclientrect.x; + result.y:= fpaintrect.y-fclientrect.y; + end + end + else begin + result.pos:= nullpoint; + end; +end; + +function twidget.widgetscreenrect: rectty; //screen origin +begin + result.size:= fwidgetrect.size; + result.pos:= screenpos; +end; + +function twidget.clientwidgetpos: pointty; +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= addpoint(fpaintrect.pos,fclientrect.pos); + end + end + else begin + result:= nullpoint; + end; +end; + +function twidget.innerclientpaintpos: pointty; //origin = paintpos +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= fframe.finnerclientrect.pos; + end; + end + else begin + result:= nullpoint; + end; +end; + +function twidget.innerclientwidgetpos: pointty; //origin = pos +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= addpoint(fpaintrect.pos,fframe.finnerclientrect.pos); + end; + end + else begin + result:= nullpoint; + end; +end; + +procedure twidget.innertopaintsize(var asize: sizety); +begin + if fframe <> nil then begin + with fframe do begin + asize.cx:= asize.cx + framei_left + framei_right; + asize.cy:= asize.cy + framei_top + framei_bottom; + end; + end; +end; + +procedure twidget.outertopaintsize(var asize: sizety); +begin + if fframe <> nil then begin + with fframe do begin + asize.cx:= asize.cx + frameo_left + frameo_right; + asize.cy:= asize.cy + frameo_top + frameo_bottom; + end; + end; +end; + +procedure twidget.painttowidgetsize(var asize: sizety); +begin + if fframe <> nil then begin + with fframe do begin + checkstate; + asize.cx:= asize.cx + fpaintframe.left + fpaintframe.right; + asize.cy:= asize.cy + fpaintframe.top + fpaintframe.bottom; + end; + end; +end; + +procedure twidget.widgettopaintsize(var asize: sizety); +begin + if fframe <> nil then begin + with fframe do begin + checkstate; + asize.cx:= asize.cx - (fpaintframe.left + fpaintframe.right); + asize.cy:= asize.cy - (fpaintframe.top + fpaintframe.bottom); + end; + end; +end; + +function twidget.clientparentpos: pointty; + //origin = parentwidget.pos +begin + result:= addpoint(fwidgetrect.pos,clientwidgetpos); +end; + +function twidget.refpos(const aorigin: originty): pointty; +begin + case aorigin of + org_screen: begin + result:= screenpos; + end; + org_widget: begin + result:= pos; + end; + org_client: begin + result:= parentclientpos; + end; + org_inner: begin + result:= addpoint(parentclientpos,innerclientpos); + end; + else begin + result:= nullpoint; + end; + end; +end; + +function twidget.paintparentrect: rectty; //origin = parentwidget.pos +begin + result:= paintrect; + addpoint1(result.pos,fwidgetrect.pos); +end; + +function twidget.paintparentpos: pointty; //origin = parentwidget.pos +begin + result:= addpoint(fwidgetrect.pos,paintpos); +end; + +function twidget.parentpaintpos: pointty; //origin = parentwidget.paintpos + //nullpoint if parent = nil +begin + if fparentwidget = nil then begin + result:= nullpoint; + end + else begin + result:= subpoint(fwidgetrect.pos,fparentwidget.paintpos); + end; +end; + +function twidget.paintrectparent: rectty; //origin = paintpos, + //nullrect if parent = nil, +begin + if fparentwidget = nil then begin + result:= nullrect; + end + else begin + result:= fparentwidget.paintrect; + subpoint1(result.pos,paintparentpos); + end; +end; + +function twidget.clientrectparent: rectty; //origin = paintpos, + //nullrect if parent = nil, +begin + if fparentwidget = nil then begin + result:= nullrect; + end + else begin + result:= fparentwidget.clientwidgetrect; + subpoint1(result.pos,paintparentpos); + end; +end; + +function twidget.getparentclientpos: pointty; //origin = parentwidget.clientpos +begin + result:= fwidgetrect.pos; + if fparentwidget <> nil then begin + subpoint1(result,fparentwidget.clientwidgetpos); + end; +end; + +procedure twidget.setparentclientpos(const avalue: pointty); +begin + if fparentwidget <> nil then begin + pos:= addpoint(avalue,fparentwidget.clientwidgetpos); + end + else begin + pos:= avalue; + end; +end; + +function twidget.checkdescendent(awidget: twidget): boolean; +begin + result:= false; + while awidget <> nil do begin + if awidget = self then begin + result:= true; + break; + end; + awidget:= awidget.fparentwidget; + end; +end; + +function twidget.checkancestor(awidget: twidget): boolean; + //true if widget is ancestor or self +var + widget1: twidget; +begin + result:= false; + if awidget <> nil then begin + widget1:= self; + while widget1 <> nil do begin + if widget1 = awidget then begin + result:= true; + break; + end; + widget1:= widget1.fparentwidget; + end; + end; +end; + +function twidget.canfocus: boolean; +begin + result:= (fwidgetstate * focusstates = focusstates) and + (componentstate*[csdesigning,csdestroying] = []) and + not releasing and + ((fparentwidget = nil) or fparentwidget.canfocus); +end; + +function twidget.checksubfocus(const aactivate: boolean): boolean; +var + widget1: twidget; +begin + result:= false; + if (ow_subfocus in foptionswidget) then begin + widget1:= ffocusedchild; + if widget1 = nil then begin + widget1:= ffocusedchildbefore; + end; + if (widget1 = nil) or (not widget1.canfocus) then begin + widget1:= defaultfocuschild; + end; + if (widget1 <> nil) and widget1.canfocus then begin + widget1.setfocus(aactivate); + result:= checkdescendent(window.ffocusedwidget); + end; + end; +end; + +function twidget.setfocus(aactivate: boolean = true): boolean; +begin + if not canfocus then begin + guierror(gue_cannotfocus,self); + end; + result:= checksubfocus(aactivate); + if not result then begin + window.setfocusedwidget(self); + //call updaterootwidget + if aactivate then begin + window.activate; + end; + result:= window.ffocusedwidget = self; + end; +end; + +procedure twidget.parentfocus; +var + widget1: twidget; +begin + widget1:= self; + while widget1 <> nil do begin + if widget1.canfocus then begin + widget1.setfocus(false); + break; + end; + widget1:= widget1.fparentwidget; + end; +end; + +function twidget.cantabfocus: boolean; +var + int1: integer; +begin + result:= (ow_tabfocus in foptionswidget) and + (fwidgetstate * focusstates = focusstates); + if result and (ow_subfocus in foptionswidget) then begin + for int1:= 0 to high(fwidgets) do begin + if fwidgets[int1].cantabfocus then begin + exit; + end; + end; + result:= false; + end; +end; + +function twidget.firsttabfocus: twidget; +var + ar1: widgetarty; + int1: integer; +begin + result:= nil; + ar1:= gettaborderedwidgets; + for int1:= 0 to high(ar1) do begin + if ar1[int1].cantabfocus then begin + result:= ar1[int1]; + break; + end; + end; +end; + +function twidget.lasttabfocus: twidget; +var + ar1: widgetarty; + int1: integer; +begin + result:= nil; + ar1:= gettaborderedwidgets; + for int1:= high(ar1) downto 0 do begin + if ar1[int1].cantabfocus then begin + result:= ar1[int1]; + break; + end; + end; +end; + +function twidget.findtabfocus(const ataborder: integer): twidget; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fwidgets) do begin + if (fwidgets[int1].ftaborder = ataborder) then begin + if fwidgets[int1].cantabfocus then begin + result:= fwidgets[int1]; + end; + break; + end; + end; +end; + +function twidget.nexttaborderoverride(const sender: twidget; + const down: boolean = false): twidget; +begin + result:= nil; + if fparentwidget <> nil then begin + result:= fparentwidget.nexttaborderoverride(sender,down); + end; +end; + +function twidget.nexttaborder(const down: boolean = false; + nowrap: boolean = false): twidget; +label + doreturn; +var + int1: integer; +begin + result:= nexttaborderoverride(self,down); + if (result = nil) and (fparentwidget <> nil) and + not (csdestroying in fparentwidget.componentstate) then begin + int1:= ftaborder; + if down then begin + repeat + dec(int1); + with fparentwidget do begin + if int1 < 0 then begin + if (ow_parenttabfocus in foptionswidget) and + (fparentwidget <> nil) then begin + result:= nexttaborder(down); + if result <> nil then begin + goto doreturn; + end; + end; + if nowrap then begin + exit; + end; + int1:= high(fwidgets); + end; + result:= findtabfocus(int1); + end; + until (result <> nil) or (int1 = ftaborder); + end + else begin + repeat + inc(int1); + with fparentwidget do begin + if int1 >= widgetcount then begin + if (ow_parenttabfocus in foptionswidget) and + (fparentwidget <> nil) then begin + result:= nexttaborder(down,nowrap); + if result <> nil then begin + goto doreturn; + end; + end; + if nowrap then begin + exit; + end; + int1:= 0; + end; + result:= findtabfocus(int1); + end; + until (result <> nil) or (int1 = ftaborder); + end; + end; + +doreturn: + if (result <> nil) and (ow_parenttabfocus in result.foptionswidget) then begin + if down then begin + result:= result.container.lasttabfocus; + end + else begin + result:= result.container.firsttabfocus; + end; + end; +end; + +procedure twidget.doenter; +begin + //dummy +end; + +procedure twidget.internaldoenter; +begin +{$ifdef mse_debugwidgetfocus} + if not (ws_entered in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!*+internaldoenter new ')); + end + else begin + debugwriteln(debugwidgetname(self,'**+internaldoenter ')); + end; +{$endif} + if not (ws_entered in fwidgetstate) then begin + include(fwidgetstate,ws_entering); + try + if fparentwidget <> nil then begin + with fparentwidget do begin + // if ffocusedchildbefore <> self then begin + ffocusedchildbefore:= ffocusedchild; + // end; + ffocusedchild:= self; + end; + end; + include(fwidgetstate,ws_entered); + if (canassistive()) and (ws_iswidget in widgetstate) then begin + assistiveserver.doenter(getiassistiveclient()); + end; + doenter; + if needsfocuspaint then begin + invalidatewidget; + end; + finally + exclude(fwidgetstate,ws_entering); + end; + end; +end; + +procedure twidget.doexit; +begin + //dummy +end; + +procedure twidget.internaldoexit; +begin +{$ifdef mse_debugwidgetfocus} + if (ws_entered in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!*-internaldoexit new ')); + end + else begin + debugwriteln(debugwidgetname(self,'**-internaldoexit ')); + end; +{$endif} + if ws_entered in fwidgetstate then begin + include(fwidgetstate,ws_exiting); + try + ffocusedchildbefore:= ffocusedchild; + ffocusedchild:= nil; + exclude(fwidgetstate,ws_entered); + if needsfocuspaint then begin + invalidatewidget; + end; + if (ow1_canclosenil in foptionswidget1) then begin + if not canclose(nil) then begin + exit; + end; + end; + doexit; + finally + exclude(fwidgetstate,ws_exiting); + end; + end; +end; + +procedure twidget.dofocus; +begin + //dummy +end; + +procedure twidget.internaldofocus; + {$ifdef mse_with_ifi} +var + lwo1: longword; + {$endif} +begin +{$ifdef mse_debugwidgetfocus} + if not (ws_focused in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!***+internaldofocus new ')); + end + else begin + debugwriteln(debugwidgetname(self,'****+internaldofocus ')); + end; +{$endif} + if not (ws_focused in fwidgetstate) then begin + include(fwidgetstate,ws_focused); + {$ifdef mse_with_ifi} + lwo1:= window.focuscount; + {$endif} + dofocus; + {$ifdef mse_with_ifi} + if lwo1 = window.focuscount then begin + ifiwidgetstatechanged; + end; + {$endif} + if fparentwidget <> nil then begin + fparentwidget.dochildfocused(self); + end; + if fframe <> nil then begin + fframe.focusedchanged(); + end; + end; +end; + +procedure twidget.dodefocus; +begin + //dummy +end; + +procedure twidget.dochildfocused(const sender: twidget); +begin + //dummy +end; + +procedure twidget.dofocuschanged(const oldwidget,newwidget: twidget); +var + int1: integer; +begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].dofocuschanged(oldwidget,newwidget); + end; +end; + +procedure twidget.internaldodefocus; + {$ifdef mse_with_ifi} +var + lwo1: longword; + {$endif} +begin +{$ifdef mse_debugwidgetfocus} + if (ws_focused in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!***-internaldodefocus new ')); + end + else begin + debugwriteln(debugwidgetname(self,'****-internaldodefocus')); + end; +{$endif} + if ws_focused in fwidgetstate then begin + exclude(fwidgetstate,ws_focused); + {$ifdef mse_with_ifi} + lwo1:= window.focuscount; + {$endif} + dodefocus; + {$ifdef mse_with_ifi} + if lwo1 = window.focuscount then begin + ifiwidgetstatechanged; + end; + {$endif} + if fframe <> nil then begin + fframe.focusedchanged(); + end; + end; +end; + +function twidget.focusback(const aactivate: boolean = true): boolean; +begin + if fparentwidget <> nil then begin + with fparentwidget do begin + if (ffocusedchildbefore <> nil) and (ffocusedchildbefore <> self) and + (ffocusedchildbefore.canfocus) then begin + ffocusedchildbefore.setfocus(aactivate); + result:= true; + end + else begin + result:= focusback(aactivate); + end; + end; + end + else begin + result:= false; + end; +end; + +procedure twidget.internaldoactivate; +begin +{$ifdef mse_debugwidgetfocus} + if not (ws_active in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!**+internaldoactivate new ')); + end + else begin + debugwriteln(debugwidgetname(self,'***+internaldoactivate ')); + end; +{$endif} + if not (ws_active in fwidgetstate) then begin + include(fwidgetstate,ws_active); + doactivate; + if canassistive() then begin + assistiveserver.doactivate(getiassistiveclient()); + end; + doafteractivate(); + end; +end; + +procedure twidget.internaldodeactivate; +begin +{$ifdef mse_debugwidgetfocus} + if (ws_active in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!**-internaldodeactivate new ')); + end + else begin + debugwriteln(debugwidgetname(self,'***-internaldodeactivate ')); + end; +{$endif} + if ws_active in fwidgetstate then begin + exclude(fwidgetstate,ws_active); + dodeactivate; + if canassistive() then begin + assistiveserver.dodeactivate(getiassistiveclient()); + end; + end; +end; + +procedure twidget.doloaded; +begin + //dummy +end; + +procedure twidget.dohide; +var + int1: integer; +begin + visiblechanged; + if appinst.fmousecapturewidget = self then begin + releasemouse; + end; + if appinst.fmousewidget = self then begin + appinst.setmousewidget(nil); + end; + if appinst.fhintforwidget = self then begin + appinst.hidehint; + end; + { + if (window.focusedwidget = self) and + (fparentwidget <> nil) and fparentwidget.visible then begin +// (fwindow.visible or not (ws_visible in fwidgetstate)) then begin + nextfocus; + end; + } + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1] do begin + if ws_visible in fwidgetstate then begin + dohide; + end; + end; + end; +end; + +procedure twidget.internalhide(const windowevent: boolean); +var + bo1,bo2: boolean; +begin + bo1:= ws_visible in fwidgetstate; + bo2:= false; + if showing then begin + if bo1 and not (csdestroying in componentstate) then begin + updateroot; + window.invalidaterect(makerect(frootpos,fwidgetrect.size),self); + //invalidate old position and size + end; + exclude(fwidgetstate,ws_visible); + dohide; + end + else begin + exclude(fwidgetstate,ws_visible); + bo2:= updateopaque(false,true); + end; + if ws_visible in fwidgetstate then begin + exit; //show called + end; + if bo1 then begin + if not bo2 and (fparentwidget <> nil) and + not (csdestroying in fparentwidget.componentstate) and + not fparentwidget.isloading then begin + fparentwidget.widgetregionchanged(self); + end; + if ownswindow1 then begin + fwindow.hide(windowevent); + end; + if (fwindow <> nil) and (fparentwidget<> nil) and + not (csdestroying in fparentwidget.componentstate) and + checkdescendent(fwindow.focusedwidget) then begin + nextfocus; + if (fwindow <> nil) and checkdescendent(fwindow.focusedwidget) then begin + show; //defocus was not possible + end; + end; + end; +end; + +procedure twidget.hide; +begin + internalhide(false); +end; + +procedure twidget.doshow; +var + int1: integer; +begin + if not (ws_loadedproc in fwidgetstate) then begin + visiblechanged; + for int1:= 0 to widgetcount - 1 do begin + with widgets[int1] do begin + if not (csloading in componentstate) and //doshow from loaded pending + (fwidgetstate * [ws_visible,ws_showproc] = [ws_visible]) then begin + doshow(); + end; + end; + end; + end; +end; + +function twidget.internalshow(const modallevel: modallevelty; + const transientfor: pwindow; //follow linked var state + const windowevent,nomodalforreset: boolean): modalresultty; +var + bo1,bo2: boolean; + modaltransientfor: twindow; +// w1: twidget; + info: showinfoty; +begin + if modallevel = ml_application then begin + modaltransientfor:= nil; + info.transientfor:= nil; + if transientfor^ = nil then begin + setlinkedvar(fwindow.defaulttransientfor,tlinkedobject(info.transientfor)); + modaltransientfor:= info.transientfor; +// transientfor:= fwindow.defaulttransientfor; +// modaltransientfor:= transientfor; + end + else begin + setlinkedvar(transientfor^,tlinkedobject(info.transientfor)); + end; + info.widget:= nil; + setlinkedvar(self,tmsecomponent(info.widget)); + try +// info.transientfor:= transientfor; + info.windowevent:= windowevent; + info.nomodalforreset:= nomodalforreset; + if window.beginmodal(@info) or (info.widget = nil) then begin + result:= mr_windowdestroyed; + exit; + end; + if modaltransientfor <> nil then begin + window.settransientfor(nil,false); + end; + finally + if info.widget <> nil then begin //else self is destroyed + setlinkedvar(nil,tlinkedobject(info.transientfor)); + setlinkedvar(nil,tmsecomponent(info.widget)); + end; + end; + end + else begin + bo1:= not showing; + updateroot; //create window + if fparentwidget <> nil then begin + if not (csdesigning in componentstate) then begin + include(fwidgetstate,ws_showproc); + try + fparentwidget.show(modallevel,transientfor^); + finally + exclude(fwidgetstate,ws_showproc); + end; + end; + end; + include(fwidgetstate,ws_visible); + if bo1 then begin + if not updateopaque(false,true) and (fparentwidget <> nil) then begin + fparentwidget.widgetregionchanged(self); + end; + end; + if ownswindow1 then begin + bo2:= transientfor^ = window; +// if transientfor = window then begin +// transientfor:= nil; +// end; + if not bo2 and (transientfor^ <> nil) and (modallevel = ml_window) then begin + include(fwindow.fstate,tws_modalfor); + end + else begin + if not nomodalforreset then begin + exclude(fwindow.fstate,tws_modalfor); + end; + end; + fwindow.show(windowevent); + if not nomodalforreset and not bo2 then begin + fwindow.settransientfor(transientfor^,windowevent); + end; + if bo1 then begin + doshow; + end; + if (modallevel = ml_window) and (fwindow.modalfor) and + fwindow.ftransientfor.active then begin + fwindow.activate; + end; + end + else begin + if bo1 then begin + doshow; + end; + end; + end; // ml_application + if fwindow <> nil then begin + result:= fwindow.fmodalresult; + end + else begin + result:= mr_none; + end; +end; + +function twidget.show(const modallevel: modallevelty; + const transientfor: twindow = nil): modalresultty; +var + event: twidgetshowevent; +begin + if (modallevel = ml_application) and not application.ismainthread then begin + event:= twidgetshowevent.create(false); + event.fwidget:= self; + event.fmodallevel:= modallevel; +// event.ftransientfor:= transientfor^; dangerouse becouse of lifetime + try + synchronizeevent(event); + result:= event.fmodalresult; + finally + event.free; + end; + end + else begin + result:= internalshow(modallevel,@transientfor,false,false); + end; +end; + +function twidget.show(const modallevel: modallevelty; + const transientfor: twidget): modalresultty; +begin + if transientfor = nil then begin + result:= show(modallevel,twindow(nil)); + end + else begin + result:= show(modallevel,transientfor.window); + end; +end; + +function twidget.show(const modal: boolean = false; + const transientfor: twindow = nil): modalresultty; +begin + if modal then begin + result:= show(ml_application,transientfor); + end + else begin + result:= show(ml_none,transientfor); + end; +end; + +procedure twidget.endmodal; +begin + if window.fmodalwidget = self then begin + fwindow.endmodal; + end; +end; + +procedure twidget.clampinview(const arect: rectty; const bottomright: boolean); +var + rect1: rectty; +begin + if fparentwidget <> nil then begin + rect1:= arect; + addpoint1(rect1.pos,subpoint(paintparentpos,fparentwidget.paintpos)); + fparentwidget.clampinview(rect1,bottomright); + end; +end; + +procedure twidget.doactivate; +var + rect1: rectty; +begin + if (fparentwidget <> nil) and + not (ow1_noclampinview in foptionswidget1) then begin + rect1:= getdisprect; + if rect1.x < 0 then begin + rect1.cx:= rect1.cx + rect1.x; + rect1.x:= 0; + end; + if rect1.x + rect1.cx > fwidgetrect.cx then begin + rect1.cx:= fwidgetrect.cx - rect1.x; + end; + if rect1.y < 0 then begin + rect1.cy:= rect1.cy + rect1.y; + rect1.y:= 0; + end; + if rect1.y + rect1.cy > fwidgetrect.cy then begin + rect1.cy:= fwidgetrect.cy - rect1.y; + end; + addpoint1(rect1.pos,fwidgetrect.pos); + subpoint1(rect1.pos,fparentwidget.paintpos); + fparentwidget.clampinview(rect1,false); + end; + activechanged; +end; + +procedure twidget.doafteractivate(); +begin + //dummy +end; + +procedure twidget.dodeactivate; +begin + activechanged; +end; + +function twidget.navigdistance(var info: naviginfoty; + const nowrap: boolean = false): integer; +const + distweighting = 10; + wrapweighting = 1; + orthoweightingwrap = 10; + orthoweighting = 300; + orthoweightingoverlap = 1; +var + dist: integer; + srect,drect: rectty; + sstart,send,dstart,dend: integer; + i1: int32; + +begin + with info do begin + drect:= navigrect; + addpoint1(drect.pos,rootpos); + srect:= startingrect; + if direction in [gd_right,gd_left] then begin + sstart:= srect.y; + dstart:= drect.y; + send:= srect.y + srect.cy; + dend:= drect.y + drect.cy; + result:= (drect.y + dend - srect.y - send) div 2; + dist:= drect.x - srect.x; + if direction = gd_right then begin + if dist > 0 then begin + i1:= dist - srect.cx; + if (i1 > 0) and (i1 < dist) then begin + dist:= i1; + end; + end; + end + else begin //gd_left + if dist < 0 then begin + i1:= dist + drect.cx; + if (i1 < 0) and (i1 > dist) then begin + dist:= i1; + end; + end; + end; + end + else begin + sstart:= srect.x; + send:= srect.x + srect.cx; + dstart:= drect.x; + dend:= drect.x + drect.cx; + result:= drect.x - srect.x; + dist:= (drect.y + drect.cy div 2) - (srect.y + srect.cy div 2); + end; + result:= abs(result); + if direction in [gd_left,gd_up] then begin + dist:= -dist; + end; + if dist <= 0 then begin + if nowrap then begin + result:= bigint; + exit; + end; + result:= result div orthoweightingwrap; + if direction in [gd_right,gd_left] then begin + dist:= dist + wraprect.cx; + if direction = gd_left then begin + dist:= dist-drect.cx + end; + end + else begin + dist:= dist + wraprect.cy; + end; + dist:= dist * wrapweighting; + result:= result*orthoweightingwrap; + end + else begin +// if (dstart >= sstart) and (dend <= send) or +// (sstart >= dstart) and (send <= dend) then begin + if (dstart >= sstart) and (dstart < send) or + (dend > sstart) and (dend <= send) or + (sstart >= dstart) and (sstart < dend) or + (send > dstart) and (send <= dend) then begin + result:= result * orthoweightingoverlap; + end + else begin + result:= result * orthoweighting; + end; + end; + dist:= dist * distweighting; + if dist < 0 then begin + dist:= bigint div 2; + end; + result:= result + dist; + end; +end; + +function twidget.navigrect: rectty; +begin + result:= paintrect; + if fframe <> nil then begin + inflaterect1(result,fframe.paintframedelta); + end; +end; + +function twidget.navigstartrect: rectty; +begin + result:= navigrect; +end; + +{$ifdef mse_debugnavigdistance} +var + navigrequestlevel: int32; +{$endif} + +procedure twidget.navigrequest(var info: naviginfoty; + const nowrap: boolean = false); +var + int1,int2: integer; + widget1,widget2,wi3: twidget; + bo1: boolean; + rect1,rect2: rectty; +{$ifdef mse_debugnavigdistance} + wi1: twidget; +{$endif} +begin +{$ifdef mse_debugnavigdistance} + inc(navigrequestlevel); + debugwriteln( + debugwidgetname(self,charstring(' ',navigrequestlevel-1)+ + inttostr(navigrequestlevel)+ + '**navigrequest:')+ debugwidgetname(info.sender,' sender ')); +{$endif} + with info do begin + if not down and (ow_arrowfocusout in foptionswidget) and + (fparentwidget <> nil) then begin + widget1:= sender; + sender:= self; + fparentwidget.navigrequest(info); + sender:= widget1; + end; + down:= true; + wi3:= nearest; + {$ifdef mse_debugnavigdistance} + wi1:= nearest; + {$endif} + for int1:= 0 to widgetcount - 1 do begin + widget1:= twidget(fwidgets[int1]); + if (widget1 <> info.sender) and (ow_arrowfocus in widget1.foptionswidget) + and widget1.canfocus then begin + widget2:= nearest; + bo1:= hastarget; + hastarget:= false; + if ow_arrowfocusin in widget1.foptionswidget then begin + widget1.navigrequest(info); + end; + if (nearest = widget2) and not hastarget then begin + hastarget:= true; + int2:= widget1.navigdistance(info,nowrap); + if int2 < distance then begin + nearest:= widget1; + distance:= int2; + end; + {$ifdef mse_debugnavigdistance} + if nearest <> wi1 then begin + debugwrite(' *'); + wi1:= nearest; + end + else begin + debugwrite(' '); + end; + debugwriteln(inttostr(int1)+charstring(' ',navigrequestlevel-1)+ + 'navigdistance '+ + inttostr(int2)+' '+inttostr(distance)+' '+ + debugwidgetname(widget1,' ')+' '+ + debugwidgetname(nearest,'nearest')); + {$endif} + end; + hastarget:= hastarget or bo1; + end; + end; + if (nearest <> wi3) and (nearest <> nil) then begin + rect1:= nearest.navigrect(); + translatewidgetpoint1(rect1.pos,nearest,nil); + rect2:= sender.navigrect(); + translatewidgetpoint1(rect2.pos,sender,nil); + case direction of + gd_up: begin + if rect1.y = rect2.y then begin + nearest:= wi3; //restore + end; + end; + gd_down: begin + if rect1.y + rect1.cy = rect2.y + rect2.cy then begin + nearest:= wi3; //restore + end; + end; + gd_right: begin + if rect1.x = rect2.x then begin + nearest:= wi3; //restore + end; + end; + gd_left: begin + if rect1.x + rect1.cx = rect2.x + rect2.cx then begin + nearest:= wi3; //restore + end; + end; + end; + end; + end; + if canevent(tmethod(fonnavigrequest)) then begin + fonnavigrequest(self,info); + end; +{$ifdef mse_debugnavigdistance} + dec(navigrequestlevel); +{$endif} +end; + +procedure twidget.dokeydown(var info: keyeventinfoty); +var + bo1: boolean; +begin + if fframe <> nil then begin + fframe.dokeydown(info); + end; + with info do begin + if not (es_processed in eventstate) then begin + if (key = key_escape) and (shiftstate = []) and + (ow_focusbackonesc in foptionswidget) then begin + if focusback then begin + include(eventstate,es_processed); + end; + end; + if not (es_processed in eventstate) then begin + if (fparentwidget <> nil) and + (self <> window.fmodalwidget) then begin + bo1:= es_child in eventstate; + include(eventstate,es_child); + fparentwidget.dokeydown1(info); + if not bo1 then begin + exclude(eventstate,es_child); + end; + end; + end; + end; + end; +end; + +procedure twidget.handlenavigkeys(var info: keyeventinfoty; + const nowrap: boolean = false); + + procedure expandwraprect(var wraprect: rectty; const awidget: twidget); + var + i1: int32; + widget1: twidget; + begin + for i1:= 0 to high(awidget.fwidgets) do begin + widget1:= awidget.fwidgets[i1]; + with widget1 do begin + if (ow_arrowfocus in widget1.foptionswidget) and visible then begin + combinerect1(wraprect,rootwidgetrect); + if ow_arrowfocusin in widget1.foptionswidget then begin + expandwraprect(wraprect,widget1); + end; + end; + end; + end; + end; + +var + naviginfo: naviginfoty; + widget1: twidget; + shiftstate1: shiftstatesty; + b1: boolean; + pt1,pt2: pointty; +begin + with info do begin + shiftstate1:= shiftstate * shiftstatesmask; + if not (es_processed in eventstate) then begin + if (ow_keyreturntaborder in foptionswidget) and + ({(key = key_enter) or} (key = key_return)) and + (shiftstate1 - [ss_shift] = []) then begin + include(eventstate,es_processed); + widget1:= nexttaborder(ss_shift in shiftstate1,nowrap); + if widget1 <> nil then begin + widget1.setfocus; + end; + end + else begin + if (shiftstate1 = []) or + (shiftstate1 = [ss_shift]) and (key = key_backtab) then begin + include(eventstate,es_processed); + with naviginfo do begin + direction:= gd_none; + case key of + key_tab,key_backtab: begin + widget1:= nexttaborder(key = key_backtab,nowrap or + (aso_tabnavig in assistiveoptions)); + if widget1 <> nil then begin + widget1.setfocus; + end + else begin + if canassistive() then begin + assistiveserver.dotabordertouched(getiassistiveclient(), + key = key_backtab); + end; + end; + end; + key_right: direction:= gd_right; + key_up: direction:= gd_up; + key_left: direction:= gd_left; + key_down: direction:= gd_down; + else begin + exclude(eventstate,es_processed); + end; + end; + if direction <> gd_none then begin + if fparentwidget <> nil then begin + distance:= bigint; + nearest:= nil; + sender:= self; + down:= false; + startingrect:= navigstartrect; + addpoint1(startingrect.pos,rootpos); + widget1:= fparentwidget; + wraprect:= widget1.rootwidgetrect; + while (ow_arrowfocusout in widget1.foptionswidget) and + (widget1.fparentwidget <> nil) do begin + widget1:= widget1.fparentwidget; //todo: position shift + combinerect1(wraprect,widget1.rootwidgetrect); + end; + expandwraprect(wraprect,widget1); + fparentwidget.navigrequest(naviginfo, + nowrap or + (assistiveoptions*[aso_widgetnavig,aso_nearestortho] = + [aso_widgetnavig,aso_nearestortho])); + if nearest <> nil then begin + b1:= false; + if assistiveoptions*[aso_widgetnavig,aso_nearestortho] = + [aso_widgetnavig] then begin + pt1:= rootpos; + pt2:= nearest.rootpos; + case direction of + gd_left: begin + b1:= pt1.x <= pt2.x; + end; + gd_up: begin + b1:= pt1.y <= pt2.y; + end; + gd_right: begin + b1:= pt1.x >= pt2.x; + end; + gd_down: begin + b1:= pt1.y >= pt2.y; + end; + end; + if b1 and (canassistive()) then begin + assistiveserver.donavigbordertouched(getiassistiveclient(), + direction); + end; + end; + if not b1 then begin + nearest.setfocus(); + end; + end + else begin + if canassistive() then begin + assistiveserver.donavigbordertouched(getiassistiveclient(),direction); + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure twidget.dokeydownaftershortcut(var info: keyeventinfoty); +var + bo1: boolean; +begin + with info do begin + handlenavigkeys(info); + if not (es_processed in info.eventstate) and (fparentwidget <> nil) and + (self <> window.fmodalwidget) then begin + bo1:= es_child in eventstate; + include(eventstate,es_child); + fparentwidget.dokeydownaftershortcut(info); + if not bo1 then begin + exclude(eventstate,es_child); + end; + end; + end; +end; + +procedure twidget.dokeydown1(var info: keyeventinfoty); +var + b1: boolean; + w1: twidget; +begin + b1:= canassistive() {and (ws_iswidget in widgetstate)}; + if b1 then begin + w1:= nil; + setlinkedvar(self,tmsecomponent(w1)); //destroy check + end; + try + exclude(fwidgetstate1,ws1_onkeydowncalled); + dokeydown(info); + if b1 and (w1 <> nil) then begin + assistiveserver.dokeydown(getiassistiveclient(),info); + end; + finally + if b1 and (w1 <> nil) then begin //destroy check + setlinkedvar(nil,tmsecomponent(w1)); + end; + end; +end; + +procedure twidget.internalkeydown(var info: keyeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + include(info.eventstate,es_preview); + include(appinst.fstate,aps_shortcutting); + window.fcaller:= nil; + try + doshortcut(info,self); + finally + exclude(info.eventstate,es_preview); + exclude(appinst.fstate,aps_shortcutting); + end; + end; + if not (es_processed in info.eventstate) then begin + dokeydown1(info); + end; + if not (es_processed in info.eventstate) then begin + include(appinst.fstate,aps_shortcutting); + try + doshortcut(info,self); + finally + exclude(appinst.fstate,aps_shortcutting); + end; + end; + if not (es_processed in info.eventstate) then begin + dokeydownaftershortcut(info); + end; +end; + +procedure twidget.dokeyup(var info: keyeventinfoty); +begin + if not (es_processed in info.eventstate) and (fparentwidget <> nil) and + (self <> window.fmodalwidget) then begin + fparentwidget.dokeyup(info); + end; +end; + +procedure twidget.dolayout(const sender: twidget); +begin + if fparentwidget <> nil then begin + fparentwidget.dolayout(sender); + end; +end; + +procedure twidget.updatecursorshape(apos: pointty); +var + widget: twidget; + cursor1: cursorshapety; +begin + widget:= self; + repeat + cursor1:= widget.fcursor; + if cursor1 = cr_default then begin + cursor1:= widget.actualcursor(apos); + end; + addpoint1(apos,widget.fwidgetrect.pos); + widget:= widget.fparentwidget; + until not (cursor1 in [cr_default,cr_parent]) or (widget = nil); + if (widget = nil) and (cursor1 in [cr_default,cr_parent]) then begin + cursor1:= cr_arrow; + end; + appinst.fwidgetcursorshape:= cursor1; +end; + +procedure twidget.cursorchanged; +begin + if not (csloading in componentstate) and (appinst <> nil) and + checkdescendent(appinst.fclientmousewidget) then begin + appinst.fclientmousewidget.updatecursorshape(appinst.fmousewidgetpos); + end; +end; + +procedure twidget.setcursor(const avalue: cursorshapety); +begin + if fcursor <> avalue then begin + fcursor:= avalue; + cursorchanged; + end; +end; + +function twidget.actualcursor(const apos: pointty): cursorshapety; +begin + result:= fcursor; +end; + +function twidget.containswidget(awidget: twidget): boolean; +var + int1: integer; +begin + result:= false; + if awidget <> nil then begin + for int1:= 0 to widgetcount-1 do begin + if twidget(fwidgets[int1]) = awidget then begin + result:= true; + break; + end; + end; + end; +end; + +function twidget.iswidgetclick(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventtype = et_butonrelease, button is mb_left, + // clicked and pos in clientrect or in frame.caption if caption = true, + // origin = pos +begin + with info do begin + result:= (button = mb_left) and (ws_lclicked in fwidgetstate) and + (eventkind = ek_buttonrelease) and + (pointinrect(pos,paintrect) or + caption and (fframe <> nil) and fframe.pointincaption(info.pos)); + end; +end; + +function twidget.iswidgetdblclick(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventtype = et_butonrelease, button is mb_left, + // clicked and pos in clientrect or in frame.caption if caption = true, + // and timedlay to last buttonpress is short + // origin = pos +begin + with info do begin + result:= (button = mb_left) and + (eventkind = ek_buttonpress) and (ss_double in shiftstate) and + (appinst.fbuttonpresswidgetbefore = self) and + (pointinrect(pos,paintrect) or + caption and (fframe <> nil) and fframe.pointincaption(info.pos)) + end; +end; + +function twidget.iswidgetdblclicked(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventkind = ek_buttonrelease, button is mb_left, + // and pos in clientrect or in frame.caption if caption = true + // and timedelay to last buttonrelease is short + // origin = pos +begin + with info do begin + result:= (button = mb_left) and (ss_double in shiftstate) and + ({(eventkind = ek_buttonpress) and (appinst.fbuttonpresswidgetbefore = self) or} + (eventkind = ek_buttonrelease) and + (appinst.fbuttonreleasewidgetbefore = self)) and + (pointinrect(pos,paintrect) or + caption and (fframe <> nil) and fframe.pointincaption(info.pos)); + end; +end; + +function twidget.isclick(const info: mouseeventinfoty): boolean; + //true if eventkind = ek_buttonrelease, button is mb_left, + // clicked and pos in clientrect +begin + with info do begin + result:= (ws_lclicked in fwidgetstate) and (eventkind = ek_buttonrelease) and + (button = mb_left) and pointinrect(pos,clientrect); + end; +end; + +function twidget.isdblclick(const info: mouseeventinfoty): boolean; + //true if eventtype = ek_buttonpress, button is mb_left, pos in clientrect + // and timedelay to last buttonpress is short + // origin = paintrect.pos +begin + with info do begin + result:= (button = mb_left) and pointinrect(pos,clientrect) and + (eventkind = ek_buttonpress) and (ss_double in shiftstate) and + (appinst.fbuttonpresswidgetbefore = self); + end; +end; + +function twidget.isdblclicked(const info: mouseeventinfoty): boolean; + //true if eventkind in [ek_buttonpress,ek_buttonrelease], button is mb_left, + // and timedelay to last same buttonevent is short +begin + with info do begin + result:= (button = mb_left) and (ss_double in shiftstate) and + ((eventkind = ek_buttonpress) and (appinst.fbuttonpresswidgetbefore = self) or + (eventkind = ek_buttonrelease) and (appinst.fbuttonreleasewidgetbefore = self)); + end; +end; + +function twidget.isleftbuttondown(const info: mouseeventinfoty): boolean; +begin + with info do begin + result:= (eventkind = ek_buttonpress) and + (button = mb_left) and pointinrect(pos,clientrect); + end; +end; + +function twidget.isleftbuttondown(const info: mouseeventinfoty; + const akeyshiftstate: shiftstatesty): boolean; +begin + with info do begin + result:= (eventkind = ek_buttonpress) and + (button = mb_left) and pointinrect(pos,clientrect) and ( + shiftstate*keyshiftstatesmask = akeyshiftstate); + end; +end; +{ +function twidget.eatwidgetclick(var info: mouseeventinfoty; + const caption: boolean = false): boolean; +begin + result:= iswidgetclick(info,caption); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +function twidget.eatclick(var info: mouseeventinfoty): boolean; +begin + result:= isclick(info); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +function twidget.eatdblclick(var info: mouseeventinfoty): boolean; +begin + result:= isdblclick(info); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +function twidget.eatdblclicked(var info: mouseeventinfoty): boolean; +begin + result:= isdblclicked(info); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +function twidget.eatleftbuttondown(var info: mouseeventinfoty): boolean; +begin + result:= isleftbuttondown(info); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +function twidget.eatleftbuttondown(var info: mouseeventinfoty; + const akeyshiftstate: shiftstatesty): boolean; +begin + result:= isleftbuttondown(info,akeyshiftstate); + if result then begin + include(info.eventstate,es_processed); + end; +end; +} +function twidget.widgetmousepos(const ainfo: mouseeventinfoty): pointty; + //transaltes to widgetpos if necessary +begin + result:= ainfo.pos; + if es_client in ainfo.eventstate then begin + addpoint1(result,clientwidgetpos); + end; +end; + +function twidget.getrootwidgetpath: widgetarty; +var + count: integer; + widget: twidget; +begin + result:= nil; + count:= 0; + widget:= self; + while widget <> nil do begin + if length(result) <= count then begin + setlength(result,length(result)+32); + end; + result[count]:= widget; + inc(count); + widget:= widget.fparentwidget; + end; + setlength(result,count); +end; + +function twidget.checkfocusshortcut(var info: keyeventinfoty): boolean; +begin + if (fframe <> nil) then begin + result:= fframe.checkfocusshortcut(info) and canfocus; + end + else begin + result:= false; + end; +end; + +procedure twidget.doshortcut(var info: keyeventinfoty; const sender: twidget); + //sender = nil -> broadcast top down +var + int1,int2: integer; + caller1: twidget; +begin + if not (es_processed in info.eventstate) and + (fwidgetstate * [ws_visible, ws_enabled] = + [ws_visible,ws_enabled]) then begin + if (sender <> nil) and (sender.fparentwidget = self) then begin + //neighbors first + int2:= indexofwidget(sender); + for int1:= int2 + 1 to widgetcount - 1 do begin + with widgets[int1] do begin + if not (ow_nosiblingshortcut in foptionswidget) then begin + doshortcut(info,nil); + if es_processed in info.eventstate then begin + break; + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + for int1:= 0 to int2 - 1 do begin + with widgets[int1] do begin + if not (ow_nosiblingshortcut in foptionswidget) then begin + doshortcut(info,nil); + if es_processed in info.eventstate then begin + break; + end; + end; + end; + end; + end; + end + else begin + //children + caller1:= window.fcaller; + for int1:= 0 to widgetcount - 1 do begin + if widgets[int1] <> caller1 then begin + with widgets[int1] do begin + if not (ow_noparentshortcut in foptionswidget) then begin + doshortcut(info,nil); + end; + end; + if (es_processed in info.eventstate) then begin + break; + end; + end; + end; + end; + if not (es_processed in info.eventstate) and (sender <> nil) then begin + //parent + if (fparentwidget <> nil) and not (ow_nochildshortcut in foptionswidget) and + (self <> fwindow.fmodalwidget) then begin + fwindow.fcaller:= self; + fparentwidget.doshortcut(info,sender); + end + else begin + window.doshortcut(info,sender) + end; + end; + if not (es_processed in info.eventstate) and canfocus and + checkfocusshortcut(info)then begin + setfocus; + include(info.eventstate,es_processed); + end; + end; +end; + +function twidget.showing: boolean; +begin + result:= isvisible and + ( + (fparentwidget = nil) and ((fwindow <> nil) and + (tws_windowvisible in fwindow.fstate)) or + (fparentwidget <> nil) and fparentwidget.showing + ); +end; + +function twidget.isenabled: boolean; +var + wi1: twidget; +begin + wi1:= self; + repeat + result:= ws_enabled in wi1.fwidgetstate; + wi1:= wi1.fparentwidget; + until not result or (wi1 = nil); +end; + +function twidget.active: boolean; +begin + result:= ws_active in fwidgetstate; +end; + +function twidget.entered: boolean; +begin + result:= ws_entered in fwidgetstate; +end; + +function twidget.activeentered: boolean; +begin + result:= entered and ((appinst.regularactivewindow = window) or + (appinst.finactivewindow = window)); +end; + +function twidget.activefocused: boolean; +begin + result:= (ws_active in fwidgetstate) and (window.focusedwidget = self); +end; + +function twidget.focused: boolean; +begin + result:= ws_focused in fwidgetstate; +end; + +function twidget.clicked: boolean; +begin + result:= ws_lclicked in fwidgetstate; +end; + +function twidget.isvisible: boolean; +begin + result:= ((ws_visible in fwidgetstate) or + ((csdesigning in componentstate) and + not (ws1_nodesignvisible in fwidgetstate1))) and + not (csdestroying in componentstate); +end; + +function twidget.parentisvisible: boolean; //checks visible flags of ancestors +var + widget1: twidget; +begin + result:= true; + widget1:= fparentwidget; + while widget1 <> nil do begin + if not widget1.isvisible then begin + result:= false; + break; + end; + widget1:= widget1.fparentwidget; + end; +end; + +function twidget.parentvisible: boolean; //checks visible flags of ancestors +var + widget1: twidget; +begin + result:= true; + widget1:= fparentwidget; + while widget1 <> nil do begin + if not (ws_visible in widget1.fwidgetstate) then begin + result:= false; + break; + end; + widget1:= widget1.fparentwidget; + end; +end; + +function twidget.getvisible: boolean; +begin + result:= ws_visible in fwidgetstate; +end; + +procedure twidget.setvisible(const avalue: boolean); +begin + if (not (csloading in componentstate) or not avalue) and + (avalue <> getvisible) then begin + if avalue then begin + if parentisvisible then begin + if window.modalfor then begin + show(ml_window,fwindow.ftransientfor); + end + else begin + show(ml_none,fwindow.ftransientfor); + end; + end + else begin + include(fwidgetstate,ws_visible); + end; + end + else begin + hide; + end; + if (ws1_fakevisible in fwidgetstate1) then begin + if not updateopaque(false,true) and (fparentwidget <> nil) then begin + fparentwidget.widgetregionchanged(self); + end; + end; + if not (csdestroying in componentstate) then begin + visiblepropchanged; + end; + end + else begin + if avalue then begin + include(fwidgetstate,ws_visible); + end + else begin + exclude(fwidgetstate,ws_visible); + if not (csloading in componentstate) and ownswindow and + (tws_windowvisible in fwindow.fstate) then begin + gui_hidewindow(fwindow.fwindow.id); + end; + end; + end; +end; + +function twidget.getenabled: boolean; +begin + result:= ws_enabled in fwidgetstate; +end; + +procedure twidget.setenabled(const Value: boolean); +begin + if value <> getenabled then begin + if value then begin + include(fwidgetstate,ws_enabled); + end + else begin + exclude(fwidgetstate,ws_enabled); +// if window.focusedwidget = self then begin + if checkdescendent(window.focusedwidget) then begin + nextfocus; + end; + end; + if not (csloading in componentstate) then begin + enabledchanged; + end; + end; +end; + +function twidget.actualcolor: colorty; +begin + if (fcolor <> cl_parent) and (fcolor <> cl_default) then begin + result:= fcolor; + end + else begin + if fparentwidget <> nil then begin + result:= fparentwidget.actualcolor; + end + else begin + result:= cl_background; + end; + end; +end; + +function twidget.actualopaquecolor: colorty; +begin + if (fcolor <> cl_parent) and (fcolor <> cl_default) and + (fcolor <> cl_transparent)then begin + result:= fcolor; + end + else begin + if fparentwidget <> nil then begin + result:= fparentwidget.actualopaquecolor; + end + else begin + result:= cl_background; + end; + end; +end; + +function twidget.parentcolor: colorty; +begin + if (fcolor <> cl_parent) and (fcolor <> cl_default) then begin + result:= fcolor; + end + else begin + if fparentwidget <> nil then begin + result:= fparentwidget.parentcolor; + end + else begin + result:= cl_background; + end; + end; +end; + +function twidget.backgroundcolor: colorty; +begin + if (fframe = nil) or (fframe.actualcolorclient = cl_transparent) then begin + if fparentwidget = nil then begin + result:= actualopaquecolor; + end + else begin + if (fcolor <> cl_parent) and (fcolor <> cl_default) and + (fcolor <> cl_transparent) then begin + result:= fcolor; + end + else begin + result:= fparentwidget.backgroundcolor; + end; + end; + end + else begin + result:= fframe.actualcolorclient(); + end; +end; + +function twidget.translatecolor(const acolor: colorty): colorty; +begin + if acolor = cl_default then begin + result:= actualcolor; + end + else begin + if acolor = cl_parent then begin + result:= parentcolor; + end + else begin + result:= acolor; + end; + end; +end; + +function twidget.getsize: sizety; +begin + result:= fwidgetrect.size; +end; + +function twidget.clipcaret: rectty; + //origin = pos +var + widget1: twidget; + po1: pointty; +begin + result:= moverect(getcaretcliprect,clientwidgetpos); + widget1:= self; + po1:= nullpoint; + while widget1 <> nil do begin + msegraphutils.intersectrect(result,removerect(widget1.paintrect,po1),result); + addpoint1(po1,widget1.fwidgetrect.pos); + widget1:= widget1.fparentwidget; + end; +end; + +procedure twidget.reclipcaret; +begin + if hascaret then begin + with appinst,fcaret,fcaretwidget do begin + cliprect:= moverect(clipcaret,subpoint(fcaretwidget.frootpos,origin)); + end; + end; +end; + +function twidget.hascaret: boolean; +begin + result:= (appinst <> nil) and checkdescendent(appinst.fcaretwidget) +end; + +function twidget.canwindow: boolean; +begin + result:= (fwindow <> nil) and + not (csdestroying in fwindow.fownerwidget.componentstate) or + (fwindow = nil) and not (csdestroying in rootwidget.componentstate); +end; + +procedure twidget.getcaret; +begin + if (appinst <> nil) then begin + appinst.caret.link(window.fcanvas,addpoint(frootpos,clientwidgetpos), + removerect(clipcaret,clientwidgetpos)); + appinst.fcaretwidget:= self; + end; +end; + +function twidget.mousecaptured: boolean; +begin + result:= application.mousecapturewidget = self; +end; + +function twidget.capturemouse(grab: boolean = true): boolean; +begin + result:= false; + if appinst <> nil then begin + result:= appinst.fmousecapturewidget <> self; + appinst.capturemouse(self,grab); + include(fwidgetstate,ws_mousecaptured); + end; +end; + +procedure twidget.releasemouse(const grab: boolean = false); +begin + if (appinst <> nil) and (appinst.fmousecapturewidget = self) then begin + exclude(fwidgetstate,ws_mousecaptured); + appinst.capturemouse(nil,grab); + end; +end; + +function twidget.capturekeyboard: boolean; +begin + result:= false; + if appinst <> nil then begin + result:= appinst.fkeyboardcapturewidget <> self; + appinst.fkeyboardcapturewidget:= self; + end; +end; + +procedure twidget.releasekeyboard; +begin + if (appinst <> nil) and (appinst.fkeyboardcapturewidget = self) then begin + appinst.fkeyboardcapturewidget:= nil; + end; +end; + +procedure twidget.dragevent(var info: draginfoty); +var + po1: pointty; +begin + if fparentwidget <> nil then begin + po1:= subpoint(clientparentpos,fparentwidget.clientwidgetpos); + addpoint1(info.pos,po1); + fparentwidget.dragevent(info); + subpoint1(info.pos,po1); + end; +end; + +procedure twidget.doscroll(const dist: pointty); +begin + //dummy +end; + +procedure twidget.doscrolled(const dist: pointty); +begin + //dummy +end; + +procedure twidget.scrollwidgets(const dist: pointty); + procedure movereg(const awidget: twidget); + var + int1: integer; + begin + with awidget do begin + if ws1_widgetregionvalid in fwidgetstate1 then begin + regmove(fwidgetregion,dist); + end; + for int1:= 0 to high(fwidgets) do begin + movereg(fwidgets[int1]); + end; + end; + end; +var + int1: integer; + widget1: twidget; +begin + if (dist.x <> 0) or (dist.y <> 0) then begin + if ws1_widgetregionvalid in fwidgetstate1 then begin + regmove(fwidgetregion,dist); + end; + widget1:= self; + while not (ws_opaque in widget1.fwidgetstate) and + (widget1.parentwidget <> nil) do begin + widget1:= widget1.parentwidget; + exclude(widget1.fwidgetstate1,ws1_widgetregionvalid); + end; + for int1:= 0 to widgetcount - 1 do begin + widget1:= fwidgets[int1]; + movereg(widget1); + with widget1 do begin + addpoint1(fwidgetrect.pos,dist); + addpoint1(frootpos,dist); + rootchanged([]); + end; + if appinst.fcaretwidget = widget1 then begin + widget1.reclipcaret; + end; + end; +// widgetregioninvalid; + if fwindow <> nil then begin + fwindow.fscrollnotifylist.notify(self); + end; + end; +end; + +procedure twidget.scrollcaret(const dist: pointty); +begin + if hascaret then begin + tcaret1(appinst.fcaret).scroll(dist,appinst.fcaretwidget <> self); + reclipcaret; + end; +end; + +function twidget.getnoscroll(): boolean; +begin + result:= ow_noscroll in foptionswidget; +end; + +procedure twidget.scrollrect(const dist: pointty; const rect: rectty; + scrollcaret: boolean); + //origin = paintrect.pos +var + rect1,rect2: rectty; + ahascaret: boolean; + + procedure doinvalidate; + begin + fwindow.invalidaterect(intersectrect(rect1,rect2)); + end; + +begin + if (dist.x = 0) and (dist.y = 0) or not showing then begin + exit; + end; + if (fwindow <> nil) {and canpaint} then begin + ahascaret:= hascaret; + if ahascaret then begin + tcaret1(appinst.fcaret).remove; + end; + rect1:= rect; + if fframe <> nil then begin + inc(rect1.x,fframe.fpaintrect.x); + inc(rect1.y,fframe.fpaintrect.y); //widget origin + end; + if getnoscroll() or{and not} + (csdesigning in componentstate) or //restore grid + (tws_painting in fwindow.fstate) or + (abs(dist.x) >= rect.cx) or (abs(dist.y) > rect1.cy) then begin + invalidaterect(rect1,org_widget); + end + else begin + update; + msegraphutils.intersectrect(rect1,clippedpaintrect,rect1); + if hasoverlappingsiblings(rect1) then begin + invalidaterect(rect1,org_widget); + end + else begin + rect2:= rect1; //backup for invalidate + addpoint1(rect2.pos,frootpos); + msegraphutils.intersectrect(rect1,removerect(rect1,dist),rect1); + addpoint1(rect1.pos,frootpos); + fwindow.movewindowrect(dist,rect1); + rect1.y:= rect2.y; + rect1.cy:= rect2.cy; + if dist.x < 0 then begin + rect1.cx:= -dist.x; + rect1.x:= rect2.x + rect2.cx - rect1.cx; + doinvalidate; + end + else begin + if dist.x > 0 then begin + rect1.x:= rect2.x; + rect1.cx:= dist.x; + doinvalidate; + end; + end; + rect1.x:= rect2.x; + rect1.cx:= rect2.cx; + if dist.y < 0 then begin + rect1.cy:= -dist.y; + rect1.y:= rect2.y + rect2.cy - rect1.cy; + doinvalidate; + end + else begin + if dist.y > 0 then begin + rect1.y:= rect2.y; + rect1.cy:= dist.y; + doinvalidate; + end; + end; + end; + end; + if ahascaret then begin + if scrollcaret then begin + tcaret1(appinst.fcaret).scroll(dist,appinst.fcaretwidget <> self); + reclipcaret; + end; + tcaret1(appinst.fcaret).restore; + end; + if (appinst.factmousewindow = fwindow) then begin + with appinst.fmouseparkeventinfo do begin + if pointinrect(pos, + makerect(addpoint(addpoint(rootpos,paintpos),rect.pos),rect.size)) then begin + //replay last mousepos + appinst.eventlist.insert(0,tmouseevent.create(fwindow.winid,false, + mb_none,mw_none,pos,shiftstate,0)); + end; + end; + end; + end; +end; + +procedure twidget.scroll(const dist: pointty); +var + rect1: rectty; +begin + if (dist.x = 0) and (dist.y = 0) then begin + exit; + end; + doscroll(dist); + rect1.pos:= nullpoint; + if fframe <> nil then begin + rect1.size:= fframe.fpaintrect.size; + end + else begin + rect1.size:= fwidgetrect.size; + end; + scrollrect(dist,rect1,true); + scrollwidgets(dist); + doscrolled(dist); +end; + +procedure twidget.update; +begin + if showing then begin + window.update; + end; +end; + +procedure twidget.settaborder(const Value: integer); +begin + if ftaborder <> value then begin + ftaborder := Value; + if (fparentwidget <> nil) then begin + fparentwidget.updatetaborder(self); + end; + end; +end; + +function comparetaborder(const l,r): Integer; +begin + result:= twidget(l).ftaborder - twidget(r).ftaborder; +end; + +function twidget.gettaborderedwidgets: widgetarty; +begin + result:= copy(fwidgets); + sortarray(pointerarty(result),{$ifdef FPC}@{$endif}comparetaborder); +end; + +function twidget.getvisiblewidgets: widgetarty; +var + int1,int2: integer; +begin + setlength(result,length(fwidgets)); + int2:= 0; + for int1:= 0 to high(fwidgets) do begin + if fwidgets[int1].isvisible then begin + result[int2]:= fwidgets[int1]; + inc(int2); + end; + end; + setlength(result,int2); +end; + +function twidget.getcornerwidget(const side: graphicdirectionty; + const visibleonly: boolean): twidget; +var + i1,i2: int32; + po1,pe: pwidget; +begin + result:= nil; + case side of + gd_left: begin + i1:= maxint; + po1:= pointer(fwidgets); + pe:= po1 + length(fwidgets); + while po1 < pe do begin + with po1^ do begin + if not visibleonly or visible then begin + if fwidgetrect.x < i1 then begin + result:= po1^; + i1:= fwidgetrect.x; + end; + end; + end; + inc(po1); + end; + end; + gd_up: begin + i1:= maxint; + po1:= pointer(fwidgets); + pe:= po1 + length(fwidgets); + while po1 < pe do begin + with po1^ do begin + if not visibleonly or visible then begin + if fwidgetrect.y < i1 then begin + result:= po1^; + i1:= fwidgetrect.y; + end; + end; + end; + inc(po1); + end; + end; + gd_right: begin + i1:= minint; + po1:= pointer(fwidgets); + pe:= po1 + length(fwidgets); + while po1 < pe do begin + with po1^ do begin + if not visibleonly or visible then begin + i2:= fwidgetrect.x + fwidgetrect.cx; + if i2 > i1 then begin + result:= po1^; + i1:= i2; + end; + end; + end; + inc(po1); + end; + end; + gd_down: begin + i1:= minint; + po1:= pointer(fwidgets); + pe:= po1 + length(fwidgets); + while po1 < pe do begin + with po1^ do begin + if not visibleonly or visible then begin + i2:= fwidgetrect.y + fwidgetrect.cy; + if i2 > i1 then begin + result:= po1^; + i1:= i2; + end; + end; + end; + inc(po1); + end; + end; + end; +end; + +procedure twidget.updatetaborder(awidget: twidget); +var + int1: integer; + sortlist: widgetarty; + +begin + sortlist:= nil; //compiler warning + if not isloading then begin + if awidget <> nil then begin + for int1:= 0 to widgetcount - 1 do begin + if twidget(fwidgets[int1]) <> awidget then begin + with twidget(fwidgets[int1]) do begin + if ftaborder >= awidget.ftaborder then begin + inc(ftaborder); + end; + end; + end; + end; + end; + sortlist:= gettaborderedwidgets; + + for int1:= 0 to high(sortlist) do begin + twidget(sortlist[int1]).ftaborder:= int1; + end; + end; +end; + +function twidget.getparentcomponent: tcomponent; +begin + result:= parentofcontainer; + if result = nil then begin +// result:= owner; + end + else begin + if (csdesigning in componentstate) and + not(csdesigning in result.componentstate) then begin + result:= nil; //parentwidget is designer + end; + end +end; + +function twidget.hasparent: boolean; +begin + result:= getparentcomponent <> nil; +end; + +procedure twidget.setparentcomponent(value: tcomponent); +begin + if value is twidget then begin + twidget(value).insertwidget(self,fwidgetrect.pos); + end + else begin +// value.insertcomponent(self); + end; +end; + +procedure twidget.setchildorder(child: tcomponent; order: integer); +//var +// comp1: tcomponent; +begin + if not fixupsetchildorder(self,child,order) then begin + with container do begin + if order > high(fwidgets) then begin + inherited setchildorder(child,order-length(fwidgets)); + end; + if removeitem(pointerarty(fwidgets),child) >= 0 then begin + if order < 0 then begin + order:= 0; + end; + if order > length(fwidgets) then begin + order:= length(fwidgets); + end; + insertitem(pointerarty(fwidgets),order,child); + end; + end; + end; +end; + +procedure twidget.getchildren(proc: tgetchildproc; root: tcomponent); +var + int1: integer; + widget: twidget; +begin + for int1:= 0 to high(fwidgets) do begin + widget:= fwidgets[int1]; + if (ws_iswidget in widget.fwidgetstate) and + (widget.owner = root) then begin + proc(widget); + end; + end; +end; + +function twidget.getcanvas(aorigin: originty = org_client): tcanvas; +begin + with tcanvas1(window.fcanvas) do begin + fstate:= fstate - changedmask; //state invalid + end; + result:= fwindow.fasynccanvas; + with result do begin + if active then begin + reset; + save; + end; + font:= getfont; + origin:= rootpos; + case aorigin of + org_widget,org_screen: begin + clipregion:= createregion(makerect(nullpoint,fwidgetrect.size)); + if aorigin = org_screen then begin + remove(screenpos); + end; + end + else begin //org_client,org_inner + clipregion:= createregion(paintrect); + if aorigin = org_client then begin + move(clientwidgetpos); + end + else begin + move(innerclientwidgetpos); + end; + end; + end; + end; +end; + +procedure twidget.updatewindowinfo(var info: windowinfoty); +begin + //dummy +end; + +procedure twidget.windowcreated; +begin + //dummy +end; + +procedure twidget.setfontheight; +begin + if not (csloading in componentstate) then begin + if ow1_fontglyphheight in foptionswidget1 then begin + ffontheight:= getfont.glyphheight; + end; + if ow1_fontlineheight in foptionswidget1 then begin + ffontheight:= getfont.lineheight; + end; + end; +end; + +procedure twidget.setoptionswidget(const avalue: optionswidgetty); +{$ifndef FPC} +const + mask: optionswidgetty = [ow_hinton,ow_hintoff]; +{$endif} +var + value,delta: optionswidgetty; + opt1: optionswidget1ty; +begin + if avalue <> foptionswidget then begin + if csreading in componentstate then begin + opt1:= optionswidget1; + if ow_noautosizing in avalue then begin //don't use deprecated flags + opt1:= opt1 + [ow1_noautosizing]; + end; + if ow_canclosenil in avalue then begin + include(opt1,ow1_canclosenil); + end; + optionswidget1:= opt1; + end; + + value:= optionswidgetty(setsinglebit(longword(avalue), + longword(foptionswidget), + {$ifdef FPC} + longword([ow_hinton,ow_hintoff]))); + {$else} + longword(mask))); + {$endif} + + delta:= optionswidgetty(longword(value) xor longword(foptionswidget)); + foptionswidget:= value - deprecatedoptionswidget; + if (delta * [ow_background,ow_top] <> []) then begin + if fparentwidget <> nil then begin + fparentwidget.sortzorder; + end + else begin + if ownswindow then begin + appinst.updatewindowstack; + end; + end; + end; + { + if delta * [ow_fontlineheight,ow_fontglyphheight] <> [] then begin + updatefontheight; + end; + } + end; +end; + +procedure twidget.setoptionswidget1(const avalue: optionswidget1ty); +{$ifndef FPC} +const + mask1: optionswidget1ty = [ow1_fontglyphheight,ow1_fontlineheight]; + mask2: optionswidget1ty = [ow1_autosizeanright,ow1_noautosizeanright]; + mask3: optionswidget1ty = [ow1_autosizeanbottom,ow1_noautosizeanbottom]; +{$endif} +var + value,delta: optionswidget1ty; +begin +{$ifdef FPC} + value:= optionswidget1ty(setsinglebit(longword(avalue),longword(foptionswidget1), + [longword([ow1_fontglyphheight,ow1_fontlineheight]), + longword([ow1_autosizeanright,ow1_noautosizeanright]), + longword([ow1_autosizeanbottom,ow1_noautosizeanbottom])])); +{$else} + value:= optionswidget1ty(setsinglebitar16(word(avalue),word(foptionswidget1), + [word(mask1),word(mask2),word(mask3)])); +{$endif} + delta:= optionswidget1ty({$ifdef FPC}longword{$else}word{$endif}(value) xor + {$ifdef FPC}longword{$else}word{$endif}(foptionswidget1)); + if delta <> [] then begin + foptionswidget1:= value; + if delta * [ow1_fontlineheight,ow1_fontglyphheight] <> [] then begin + updatefontheight; + end; + if delta * avalue * [ow1_autowidth,ow1_autoheight] <> [] then begin + checkautosize; + end; + if (delta * [ow1_clientcxmin,ow1_clientcxmax, + ow1_clientcymin,ow1_clientcymax] <> []) and + not (csloading in componentstate) then begin + exclude(fwidgetstate,ws_minclientsizevalid); + if ownswindow1 then begin + fwindow.sizeconstraintschanged(); + end; + internalsetwidgetrect(fwidgetrect,false); + end; + end; +end; + +procedure twidget.objectchanged(const sender: tobject); +begin + if fface <> nil then begin + fface.checktemplate(sender); + end; + if fframe <> nil then begin + fframe.checktemplate(sender); + end; +end; + +procedure twidget.objectevent(const sender: tobject; const event: objecteventty); +begin + inherited; + if (event = oe_changed) then begin + objectchanged(sender); + end; +end; + +procedure twidget.receiveevent(const event: tobjectevent); +begin + inherited; + case event.kind of + ek_activate: begin + window.activate; + end; + ek_childscaled: begin + exclude(fwidgetstate1,ws1_childscaled); + dolayout(nil); + end; + ek_resize: begin + clientsize:= addsize(clientsize,tresizeevent(event).size); + end; + end; +end; + +procedure twidget.beforeclosequery(var amodalresult: modalresultty); + //called on top level window +begin + //dummy +end; + +function twidget.canclose(const newfocus: twidget = nil): boolean; +var + int1: integer; +begin + result:= true; + for int1:= 0 to widgetcount - 1 do begin + result:= widgets[int1].canclose(newfocus); + if not result then begin + break; + end; + end; +end; + +function twidget.canparentclose(const newfocus: twidget): boolean; + //window.focusedwidget is first checked +begin + try + if checkdescendent(window.focusedwidget) then begin + result:= window.focusedwidget.canclose(newfocus); + if not result then begin + exit; + end; + end; + result:= canclose(newfocus); + except + result:= false; + application.handleexception; + end; +end; + +function twidget.forceclose: boolean; +var + bo1: boolean; +begin + bo1:= ws1_forceclose in fwidgetstate1; + include(fwidgetstate1,ws1_forceclose); + try + result:= canparentclose(nil); + finally + if not bo1 then begin + exclude(fwidgetstate1,ws1_forceclose); + end; + end; +end; + +function twidget.canparentclose: boolean; +begin + result:= canparentclose(window.focusedwidget); +end; + +function twidget.getcaretcliprect: rectty; + //origin = clientrect.pos +begin + result:= makerect(nullpoint,clientsize); +end; + +procedure twidget.dofontchanged(const sender: tobject); +begin + if not (ws1_scaling in fwidgetstate1) then begin + fontchanged; + end; +end; + +procedure twidget.fontchanged; +var + int1: integer; +begin + if componentstate * [csdestroying,csloading] = [] then begin + invalidate; + if not (ws_loadedproc in fwidgetstate) then begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].parentfontchanged; + end; + end; + updatefontheight; + end; +end; + +function twidget.verticalfontheightdelta: boolean; +begin + result:= false; +end; + +procedure twidget.dofontheightdelta(var delta: integer); +var + bo1: boolean; +begin + if ow1_autoscale in foptionswidget1 then begin + bo1:= ws1_autoscaling in fwidgetstate1; + include(fwidgetstate1,ws1_autoscaling); + try + with fwidgetrect do begin + if verticalfontheightdelta then begin + if fanchors * [an_left,an_right] = [an_right] then begin + setwidgetrect(makerect(x-delta,y,cx+delta,cy)); + end + else begin + if fanchors * [an_left,an_right] = [an_left] then begin + bounds_cx:= cx + delta; + end + end; + end + else begin + if fanchors * [an_top,an_bottom] = [an_bottom] then begin + setwidgetrect(makerect(x,y-delta,cx,cy+delta)); + end + else begin + if fanchors * [an_top,an_bottom] = [an_top] then begin + bounds_cy:= cy + delta; + end; + end; + end; + end; + finally + if not bo1 then begin + exclude(fwidgetstate1,ws1_autoscaling); + end; + end; + end; +end; + +procedure twidget.postchildscaled; +begin + if not (ws1_childscaled in fwidgetstate1) then begin + include(fwidgetstate1,ws1_childscaled); + if not (csloading in componentstate) then begin + appinst.postevent(tobjectevent.create( + ek_childscaled,ievent(self)),[peo_local]); + end; + end; +end; + +procedure twidget.updatefontheight; +var + int1: integer; +begin + if not (csloading in componentstate) and + (foptionswidget1 * [ow1_fontglyphheight,ow1_fontlineheight] <> []) then begin + int1:= ffontheight; + if ow1_fontglyphheight in foptionswidget1 then begin + ffontheight:= getfont.glyphheight; + end + else begin + ffontheight:= getfont.lineheight; + end; + if (int1 <> 0) and not (ws1_scaling in fwidgetstate1) then begin + int1:= ffontheight - int1; + if int1 <> 0 then begin + dofontheightdelta(int1); + if (int1 <> 0) and (fparentwidget <> nil) then begin + fparentwidget.postchildscaled; + end; + end; + end; + end; +end; + +procedure twidget.readfontheight(reader: treader); +begin + ffontheight:= reader.ReadInteger; +end; + +procedure twidget.writefontheight(writer: twriter); +begin + writer.writeinteger(ffontheight); +end; + +procedure twidget.defineproperties(filer: tfiler); +var + bo1: boolean; +begin + inherited; + if filer.ancestor <> nil then begin + bo1:= twidget(filer.ancestor).ffontheight <> ffontheight; + end + else begin + bo1:= foptionswidget1 * [ow1_fontglyphheight,ow1_fontlineheight] <> []; + end; + filer.DefineProperty('reffontheight',{$ifdef FPC}@{$endif}readfontheight, + {$ifdef FPC}@{$endif}writefontheight,bo1); +end; + +procedure twidget.parentfontchanged; +begin + if ffont = nil then begin + fontchanged; + end; + if fframe <> nil then begin + fframe.parentfontchanged; + end; +end; + +procedure twidget.reflectmouseevent(var info: mouseeventinfoty); +var + id: winidty; + po1: pointty; + window1: twindow; +begin + with info do begin + if not (eventkind in mouseregionevents) then begin + po1:= translatewidgetpoint(pos,self,nil); + id:= gui_windowatpos(po1); + if (id = 0) or not appinst.findwindow(id,window1) then begin + window1:= fwindow; + end; + subpoint1(po1,window1.fownerwidget.fwidgetrect.pos); + appinst.eventlist.insert(0,tmouseevent.create(window1.winid, + eventkind = ek_buttonrelease,button,mw_none,po1,shiftstate,info.timestamp, + true)); + end; + end; +end; + +function twidget.getnextfocus: twidget; +var + widget1: twidget; + int1,int2: integer; +begin + result:= nexttaborder; + if (result = self) or (result = nil) then begin + result:= nil; + if fparentwidget <> nil then begin + int2:= parentwidgetindex; + for int1:= int2+1 to fparentwidget.widgetcount - 1 do begin + widget1:= twidget(fparentwidget.fwidgets[int1]); + if widget1.canfocus and (ws_iswidget in widget1.fwidgetstate) then begin + result:= widget1; + break; + end; + end; + if result = nil then begin + for int1:= int2 - 1 downto 0 do begin + widget1:= twidget(fparentwidget.fwidgets[int1]); + if widget1.canfocus and (ws_iswidget in widget1.fwidgetstate) then begin + result:= widget1; + break; + end; + end; + if result = nil then begin + if fparentwidget.canfocus then begin + result:= fparentwidget; + end + else begin + result:= fparentwidget.getnextfocus; + end; + exit; + end; + end; + end; + end; +end; + +procedure twidget.nextfocus; +begin + window.setfocusedwidget(getnextfocus); +end; + +function twidget.getdisprect: rectty; //origin parentwidget.pos, + //clamped in view by activate +begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; +end; + +function twidget.getdefaultfocuschild: twidget; //returns first focusable widget +var + tabord: integer; + int1: integer; + widget1: twidget; +begin + if (fdefaultfocuschild <> nil) and fdefaultfocuschild.canfocus then begin + result:= fdefaultfocuschild; + end + else begin + result:= nil; + end; + if result = nil then begin + tabord:= bigint; + with container do begin + for int1:= 0 to widgetcount - 1 do begin + widget1:= twidget(fwidgets[int1]); + with widget1 do begin + if (ftaborder < tabord) and (ow_tabfocus in foptionswidget) and canfocus then begin + result:= widget1; + tabord:= ftaborder; + end; + end; + end; + end; + if result = nil then begin + result:= container; + if result = self then begin + result:= nil; + end; + end; + end; +end; + +procedure twidget.setdefaultfocuschild(const value: twidget); +begin + fdefaultfocuschild:= value; +end; + +function twidget.trycancelmodal(const newactive: twindow): boolean; + //called by twindow.internalactivate, true if accepted +begin + result:= false; +end; + +function twidget.parentwidgetindex: integer; +begin + if fparentwidget = nil then begin + result:= -1; + end + else begin + result:= fparentwidget.IndexOfwidget(self); + end; +end; + +procedure twidget.invalidateparentminclientsize; +begin + if fparentwidget <> nil then begin + exclude(fparentwidget.fwidgetstate,ws_minclientsizevalid); + end; +end; + +procedure twidget.setanchors(const Value: anchorsty); +begin + if fanchors <> value then begin + fanchors:= Value; + if not (csloading in componentstate) then begin + invalidateparentminclientsize; + include(fwidgetstate1,ws1_anchorsetting); + try + parentclientrectchanged; + finally + exclude(fwidgetstate1,ws1_anchorsetting); + end; + end; + end; +end; + +function twidget.getzorder: integer; +begin + result:= 0; //!!!!todo +end; + +procedure twidget.setzorder(const value: integer); +begin //!!!!todo + if ownswindow1 then begin + window.setzorder(value); + end; +end; + +function twidget.getfontclass: widgetfontclassty; +begin + result:= twidgetfont; +end; + +function twidget.getfontemptyclass: widgetfontemptyclassty; +begin + result:= twidgetfontempty; +end; + +procedure twidget.internalcreatefont; +begin + if ffont = nil then begin + ffont:= getfontclass.create; + end; + ffont.onchange:= {$ifdef FPC}@{$endif}dofontchanged; +end; + +procedure twidget.internalcreatefontempty; +begin + if ffontempty = nil then begin + ffontempty:= getfontemptyclass.create; + end; + ffontempty.onchange:= {$ifdef FPC}@{$endif}dofontchanged; +end; + +procedure twidget.syncsinglelinefontheight(const lineheight: boolean = false; + const space: integer = 2); +var + int1: integer; +begin + if lineheight then begin + int1:= getfont.lineheight; + end + else begin + int1:= getfont.glyphheight; + end; + if verticalfontheightdelta then begin + if fframe = nil then begin + bounds_cx:= bounds_cx + int1 + space - paintsize.cx + end + else begin + bounds_cx:= bounds_cx + int1 + fframe.framei_left + + fframe.framei_right - paintsize.cx; + end; + end + else begin + if fframe = nil then begin + bounds_cy:= bounds_cy + int1 + space - paintsize.cy + end + else begin + bounds_cy:= bounds_cy + int1 + fframe.framei_top + + fframe.framei_bottom - paintsize.cy; + end; + end; +end; + +procedure twidget.synctofontheight; +begin + setfontheight; +end; + +function twidget.getfont1: twidgetfont; +var + widget1: twidget; +begin + widget1:= self; + repeat + result:= widget1.ffont; + if result <> nil then begin + exit; + end; + widget1:= widget1.fparentwidget; + until widget1 = nil; + result:= stockobjects.fonts[stf_default]; +end; + +function twidget.getfont: twidgetfont; +begin + getoptionalobject(ffont,{$ifdef FPC}@{$endif}internalcreatefont); + result:= getfont1; +end; + +function twidget.getframefont: tfont; +begin + if fparentwidget <> nil then begin + result:= fparentwidget.getfont1; + end + else begin + result:= stockobjects.fonts[stf_default]; + end; +end; + +function twidget.isfontstored: Boolean; +begin + result:= ffont <> nil; +end; + +function twidget.isfontemptystored: Boolean; +begin + result:= ffontempty <> nil; +end; + +procedure twidget.setfont(const avalue: twidgetfont); +begin + if avalue <> ffont then begin + setoptionalobject(avalue,ffont,{$ifdef FPC}@{$endif}internalcreatefont); + fontchanged; + end; +end; + +function twidget.getfontempty1: twidgetfontempty; +var + widget1: twidget; +begin + widget1:= self; + repeat + result:= widget1.ffontempty; + if result <> nil then begin + exit; + end; + widget1:= widget1.fparentwidget; + until widget1 = nil; +{$warnings off} + result:= twidgetfontempty(stockobjects.fonts[stf_empty]); +{$warnings on} +end; + +function twidget.getfontempty: twidgetfontempty; +begin + getoptionalobject(ffontempty,{$ifdef FPC}@{$endif}internalcreatefontempty); + result:= getfontempty1; +end; + +procedure twidget.setfontempty(const avalue: twidgetfontempty); +begin + if avalue <> ffontempty then begin + setoptionalobject(avalue,ffontempty, + {$ifdef FPC}@{$endif}internalcreatefontempty); + fontchanged; + end; +end; + +function twidget.getframe: tcustomframe; +begin + getoptionalobject(fframe,{$ifdef FPC}@{$endif}internalcreateframe); + result:= fframe; +end; + +procedure twidget.setframe(const avalue: tcustomframe); +begin + if (ws_staticframe in fwidgetstate) then begin + if (avalue <> nil) and (pointer(avalue) <> pointer(1)) then begin + fframe.assign(avalue); + end; + end + else begin + setoptionalobject(avalue,fframe,{$ifdef FPC}@{$endif}internalcreateframe); + if (componentstate*[csloading,csdestroying] = []) then begin + clientrectchanged; + end; + end; +end; + +function twidget.getface: tcustomface; +begin + getoptionalobject(fface,{$ifdef FPC}@{$endif}internalcreateface); + result:= fface; +end; + +procedure twidget.setface(const avalue: tcustomface); +begin + if (ws_staticface in fwidgetstate) then begin + if (avalue <> nil) and (pointer(avalue) <> pointer(1)) then begin + fface.assign(avalue); + end; + end + else begin + setoptionalobject(avalue,fface,{$ifdef FPC}@{$endif}internalcreateface); + end; + invalidate; +end; + +function twidget.getcomponentstate: tcomponentstate; +begin + result:= componentstate; +end; + +function twidget.getframestateflags: framestateflagsty; +begin + result:= combineframestateflags(not isenabled,ws_focused in fwidgetstate, + ws_active in fwidgetstate, + appinst.clientmousewidget = self,ws_lclicked in fwidgetstate); +end; + +procedure twidget.setframeinstance(instance: tcustomframe); +begin + fframe:= instance; +end; + +procedure twidget.setstaticframe(value: boolean); +begin + if value then begin + include(fwidgetstate,ws_staticframe); + end + else begin + exclude(fwidgetstate,ws_staticframe); + end; +end; + +function twidget.getstaticframe: boolean; +begin + result:= ws_staticframe in fwidgetstate; +end; + +function twidget.isloading: boolean; +begin + result:= ([csloading,csdestroying] * componentstate <> []) or + (ws_loadlock in fwidgetstate); +end; + +function twidget.widgetstate: widgetstatesty; +begin + result:= fwidgetstate; +end; + +procedure twidget.insertwidget(const awidget: twidget; const apos: pointty); +begin + if (awidget.fparentwidget <> nil) and (awidget.fparentwidget <> self) then begin + awidget.fparentwidget.unregisterchildwidget(awidget); + awidget.fparentwidget:= nil; + end; + if not (csloading in componentstate) then begin + awidget.fparentclientsize:= clientsize; + end; + if awidget.ownswindow1 then begin + awidget.fwidgetrect.pos:= addpoint(screenpos,apos); + end + else begin + awidget.fwidgetrect.pos:= apos; + end; + awidget.parentwidget:= self; +end; + +procedure twidget.insertwidget(const awidget: twidget); +begin + insertwidget(awidget,awidget.fwidgetrect.pos); +end; + +function twidget.getwidget: twidget; +begin + result:= self; +end; + +procedure twidget.activate(const abringtofront: boolean = true; + const aforce: boolean = false); +begin + if abringtofront then begin + window.bringtofront; + end; + if window.modalfor then begin + show(ml_window,window.transientfor); + end + else begin + show(ml_none,window.transientfor); + end; + if aforce then begin + gui_setwindowfocus(window.winid); + end; + if not checkdescendent(window.ffocusedwidget) then begin + setfocus; + end + else begin + fwindow.ffocusedwidget.setfocus; //activate + end; +end; + +procedure twidget.bringtofront; +begin + if fparentwidget <> nil then begin + with fparentwidget do begin + if fwidgets[high(fwidgets)] <> self then begin + removeitem(pointerarty(fwidgets),self); + additem(pointerarty(fwidgets),self); + sortzorder; + end; + end; + end + else begin + window.bringtofront; + end; +end; + +procedure twidget.sendtoback; +begin + if fparentwidget <> nil then begin + with fparentwidget do begin + if fwidgets[0] <> self then begin + removeitem(pointerarty(fwidgets),self); + insertitem(pointerarty(fwidgets),0,pointer(self)); + sortzorder; + end; + end; +// invalidate; + end + else begin + window.sendtoback; + end; +end; + +procedure twidget.stackunder(const predecessor: twidget); +var + int1: integer; +begin + if fparentwidget <> nil then begin + with fparentwidget do begin + removeitem(pointerarty(fwidgets),self); + int1:= indexofwidget(predecessor); + if int1 >0 then begin + int1:= 0; + end; + insertitem(pointerarty(fwidgets),int1,pointer(self)); + end; + invalidate; + end + else begin + window.stackunder(predecessor.window); + end; +end; + +procedure twidget.setchildorder(const achildren: widgetarty); //last is top +var + int1,int2,int3: integer; +begin + int2:= high(fwidgets); + for int1:= high(achildren) downto 0 do begin + if achildren[int1] <> nil then begin + for int3:= int2 downto 0 do begin + if fwidgets[int3] = achildren[int1] then begin + moveitem(pointerarty(fwidgets),int3,int2); + dec(int2); + break; + end; + end; + end; + end; + sortzorder; +end; + +function twidget.gethint: msestring; +begin + result:= fhint; +end; + +procedure twidget.sethint(const Value: msestring); +begin + fhint:= value; +end; + +function twidget.ishintstored: boolean; +begin + result:= fhint <> ''; +end; + +function twidget.findtagchild(const atag: integer; + const aclass: widgetclassty): twidget; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fwidgets) do begin + if (fwidgets[int1].tag = atag) and + ((aclass = nil) or (fwidgets[int1] is aclass)) then begin + result:= fwidgets[int1]; + exit; + end; + end; + if result = nil then begin + for int1:= 0 to high(fwidgets) do begin + result:= fwidgets[int1].findtagchild(atag,aclass); + if result <> nil then begin + exit; + end; + end; + end; +end; + +function twidget.dofindwidget(const awidgets: widgetarty; + aname: ansistring): twidget; +var + int1: integer; +begin + result:= nil; + aname:= struppercase(aname); + for int1:= 0 to high(awidgets) do begin + if stringicompupper(awidgets[int1].name,aname) = 0 then begin + result:= awidgets[int1]; + break; + end; + end; +end; + +function twidget.findchild(const aname: ansistring): twidget; +begin + result:= dofindwidget(container.fwidgets,aname); +end; + +function twidget.gethelpcontext: msestring; +var + widget1: twidget; +begin + result:= fhelpcontext; + if result = '' then begin + if componentstate * [csloading,cswriting,csdesigning] = [] then begin + widget1:= fparentwidget; + while widget1 <> nil do begin + result:= widget1.fhelpcontext; + if result <> '' then begin + break; + end; + widget1:= widget1.fparentwidget; + end; + end; + end; +end; + +class function twidget.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_widget; +end; + +procedure twidget.getautopaintsize(var asize: sizety); +begin + painttowidgetsize(asize); + checkwidgetsize(asize); + widgettopaintsize(asize); +end; + +procedure twidget.getautocellsize(const acanvas: tcanvas; + var asize: sizety); +begin + getautopaintsize(asize); + painttowidgetsize(asize); +end; + +procedure twidget.checkautosize(); +begin + if ([csloading,csdestroying] * componentstate = []) and + not (ws1_autosizing in fwidgetstate1)then begin + include(fwidgetstate1,ws1_autosizing); + try + if ([ow1_autowidth,ow1_autoheight]*foptionswidget1 <> []) then begin + internalsetwidgetrect(fwidgetrect,false); + end + else begin + if fparentwidget <> nil then begin + fparentwidget.childautosizechanged(self); + end; + end; + finally + exclude(fwidgetstate1,ws1_autosizing); + end; + end; +end; + +procedure twidget.updatehotkeys(); +begin + if fframe <> nil then begin + fframe.updatehotkeys(); + end; +end; + +procedure twidget.childautosizechanged(const sender: twidget); +begin + //dummy +end; + +procedure twidget.scale(const ascale: real); +var + int1: integer; + rect1: rectty; +begin + include(fwidgetstate1,ws1_scaling); + try + rect1:= fwidgetrect; + if fframe <> nil then begin + fframe.scale(ascale); + end; + if ffont <> nil then begin + ffont.scale(ascale); + end; + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].scale(ascale); + end; + with rect1 do begin + x:= round(x*ascale); + y:= round(y*ascale); + cx:= round(cx*ascale); + cy:= round(cy*ascale); + end; + with fminsize do begin + cx:= round(cx*ascale); + cy:= round(cy*ascale); + end; + with fmaxsize do begin + cx:= round(cx*ascale); + cy:= round(cy*ascale); + end; + widgetrect:= rect1; + finally + exclude(fwidgetstate1,ws1_scaling); + end; +end; + +function twidget.widgetminsize: sizety; +begin + result:= nullsize; + checkwidgetsize(result); + if fframe <> nil then begin + fframe.checkwidgetsize(result); + end; +end; + +function twidget.widgetmaxsize: sizety; +begin + result.cx:= bigint; + result.cy:= bigint; + checkwidgetsize(result); + if fframe <> nil then begin + fframe.checkwidgetsize(result); + end; + if result.cx = bigint then begin + result.cx:= 0; + end; + if result.cy = bigint then begin + result.cy:= 0; + end; +end; + +function twidget.maxclientsize: sizety; +begin + result:= clientsize; +end; + +procedure twidget.fontcanvaschanged; +var + int1: integer; +begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].fontcanvaschanged; + end; + if frame <> nil then begin + fframe.fontcanvaschanged; + end; + checkautosize; +end; + +function twidget.getactface: tcustomface; +begin + result:= fface; +end; + +function twidget.getdragrect(const apos: pointty): rectty; +begin + with result do begin + x:= apos.x - mindragdist; + y:= apos.y - mindragdist; + cx:= 2 * mindragdist; + cy:= 2 * mindragdist; + end; +end; + +procedure twidget.setoptionsskin(const avalue: optionsskinty); +{$ifndef FPC} +const + mask1: optionsskinty = [osk_skin,osk_noskin]; + mask2: optionsskinty = [osk_colorcaptionframe,osk_nocolorcaptionframe]; +{$endif} +var + {opt1,opt2,}valuebefore: optionsskinty; +begin + valuebefore:= foptionsskin; +// opt1:= optionsskinty(setsinglebit( +// {$ifdef FPC}longword{$else}word{$endif}(avalue), +// {$ifdef FPC}longword{$else}word{$endif}(foptionsskin), +// {$ifdef FPC}longword{$else}word{$endif}(mask1))); +// opt2:= optionsskinty(setsinglebit( +// {$ifdef FPC}longword{$else}word{$endif}(avalue), +// {$ifdef FPC}longword{$else}word{$endif}(foptionsskin), +// {$ifdef FPC}longword{$else}word{$endif}(mask2))); +// foptionsskin:= avalue - (mask1+mask2) + opt1*mask1 + opt2*mask2; + +{$ifdef FPC} + foptionsskin:= optionsskinty(setsinglebit( + longword(avalue),longword(foptionsskin), + [longword([osk_skin,osk_noskin]), + longword([osk_colorcaptionframe,osk_nocolorcaptionframe])])); +{$else} + foptionsskin:= optionsskinty(setsinglebitar16( + word(avalue),word(foptionsskin), + [word(mask1),word(mask2)])); +{$endif} + if (optionsskinty({$ifdef FPC}longword{$else}word{$endif}(valuebefore) xor + {$ifdef FPC}longword{$else}word{$endif}(avalue)) * + [osk_nopropwidth,osk_nopropheight] <> []) and (fparentwidget <> nil) then begin + fparentwidget.scalebasechanged(self); //for tlayouter + end; +end; + +function twidget.skininfo: skininfoty; +var + widget1: twidget; +begin + result:= inherited skininfo; + if osk_container in foptionsskin then begin + include(result.options,sko_container); + end; + widget1:= self; + repeat + result.group:= widget1.fskingroup; + if result.group <> 0 then begin + break; + end; + widget1:= widget1.parentwidget; + until widget1 = nil; +end; + +function twidget.hasskin: boolean; +begin + result:= true; + if not (osk_skin in foptionsskin) then begin + if osk_noskin in foptionsskin then begin + result:= false; + end + else begin + if fparentwidget <> nil then begin + result:= fparentwidget.hasskin; + end; + end; + end; +end; + +function twidget.innerclientframe: framety; +begin + if fframe = nil then begin + result:= nullframe; + end + else begin + result:= fframe.fi.innerframe; + end; +end; + +procedure twidget.scalebasechanged(const sender: twidget); +begin + //dummy +end; + +procedure twidget.setclippedwidgetrect(arect: rectty); +var + rect1: rectty; +begin + if parentwidget = nil then begin + rect1:= application.workarea(window); + if not rectinrect(inflaterect(arect,2),rect1) then begin + clipinrect1(arect,rect1); + gui_setdecoratedwindowrect(window.winid,arect,rect1); + widgetrect:= rect1; + end + else begin + widgetrect:= arect; + end; + end + else begin + clipinrect1(arect,fparentwidget.widgetsizerect); + widgetrect:= arect; + end; +end; + +procedure twidget.dragstarted; +var + int1: integer; +begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].dragstarted; + end; +end; + +function twidget.canmouseinteract: boolean; +begin + result:= not (csdesigning in componentstate) or + (cssubcomponent in componentstyle); +end; + +function twidget.canclose1: boolean; +begin + result:= canclose; +end; + +function twidget.getiassistiveclient(): iassistiveclient; +begin + result:= iassistiveclient(self); +end; + +function twidget.canassistive(): boolean; +begin + result:= (assistiveserver <> nil) and + not (ow1_noassistive in foptionswidget1) and + not (csdesigning in componentstate); +end; + +function twidget.getassistiveparent(): iassistiveclient; +begin + result:= nil; + if fparentwidget <> nil then begin + result:= fparentwidget.getiassistiveclient(); + end; +end; + +function twidget.getassistivewidget: tobject; +begin + result:= self; +end; + +procedure twidget.beginupdate; +begin + if fwidgetupdating = 0 then begin + include(fwidgetstate,ws_loadlock); + inc(fnoinvalidate); + end; + inc(fwidgetupdating); +end; + +procedure twidget.endupdate; +begin + dec(fwidgetupdating); + if fwidgetupdating = 0 then begin + exclude(fwidgetstate,ws_loadlock); + dec(fnoinvalidate); + widgetregionchanged(nil); + end; +end; + +function twidget.getzoomrefframe: framety; +begin + result:= innerclientframe; +end; + +procedure twidget.designmouseevent(var info: moeventinfoty; capture: twidget); +begin + if fparentwidget <> nil then begin + fparentwidget.designmouseevent(info,capture); + end; +end; + +procedure twidget.designkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); +begin + if fparentwidget <> nil then begin + fparentwidget.designkeyevent(eventkind,info); + end; +end; + +function twidget.isdesignwidget: boolean; +begin + result:= (csdesigning in componentstate) or + (ws1_designwidget in fwidgetstate1); +end; + +procedure twidget.setdesignwidget(); +var + i1: int32; +begin + include(fwidgetstate1,ws1_designwidget); + for i1:= 0 to high(fwidgets) do begin + fwidgets[i1].setdesignwidget(); + end; +end; + +function twidget.getassistivename: msestring; +begin + result:= msestring(name); +end; + +function twidget.getassistivecaption(): msestring; +begin + if fframe <> nil then begin + result:= fframe.getassistivecaption(); + end + else begin + result:= ''; + end; +end; + +function twidget.getassistivetext(): msestring; +begin + result:= ''; +end; + +function twidget.getassistivecaretindex(): int32; +begin + result:= -1; +end; + +function twidget.getassistivehint(): msestring; +begin + result:= hint; +end; + +function twidget.getassistiveflags(): assistiveflagsty; +begin + result:= []; + if not (ws_iswidget in fwidgetstate) then begin + include(result,asf_embedded); + end; + if osk_container in foptionsskin then begin + include(result,asf_container); + end; + if focused then begin + include(result,asf_focused); + end; + if not isenabled then begin + include(result,asf_disabled); + end; + if ownswindow then begin + include(result,asf_toplevel); + end; + if window = application.mainwindow then begin + include(result,asf_mainwindow); + end; +end; + +function twidget.getifidatalinkintf(): iifidatalink; +begin + result:= nil; +end; + +{ twindow } + +constructor twindow.create(const aowner: twidget; const agdi: pgdifunctionaty); +begin + fgdi:= agdi; + if fgdi = nil then begin + fgdi:= getdefaultgdifuncs; + end; + fownerwidget:= aowner; + fownerwidget.fwindow:= self; + fcanvas:= creategdicanvas(fgdi,bmk_rgb,self,icanvas(self)); + fasynccanvas:= creategdicanvas(fgdi,bmk_rgb,self,icanvas(self)); + fscrollnotifylist:= tnotifylist.create; + fopacity:= emptyreal; + inherited create; + fownerwidget.rootchanged([rcf_windowset]); //nil all references +end; + +destructor twindow.destroy; +begin + include(fstate,tws_destroying); + freeandnil(fsysdragobject); + container:= 0; + appinst.twindowdestroyed(self); + if ftransientfor <> nil then begin + dec(ftransientfor.ftransientforcount); + end; + if fownerwidget <> nil then begin + fownerwidget.rootchanged([rcf_windowremove]); + end; + destroywindow; + fcanvas.free; + fasynccanvas.free; + inherited; + destroyregion(fupdateregion); + fscrollnotifylist.free; +end; + +procedure twindow.setasynccanvas(const acanvas: tcanvas); +begin + include(fstate,tws_canvasoverride); + acanvas.initflags(fasynccanvas); + fownerwidget.fontcanvaschanged; +end; + +procedure twindow.releaseasynccanvas; +begin + if tws_canvasoverride in fstate then begin + exclude(fstate,tws_canvasoverride); + fasynccanvas.initflags(fasynccanvas); + end; +end; + +procedure twindow.setsizeconstraints(const amin,amax: sizety); +begin + if fwindow.id <> 0 then begin + guierror(gui_setsizeconstraints( + fwindow.id,amin,amax)); + end; +end; + +procedure twindow.sizeconstraintschanged; +begin + setsizeconstraints(fownerwidget.widgetminsize1(), + fownerwidget.widgetmaxsize1()); +end; + +function twindow.haswinid: boolean; +begin + result:= fwindow.id <> 0; +end; + +procedure twindow.createwindow; +var + gc: gcty; + aoptions: windowinfoty; + aoptions1: internalwindowoptionsty; + event: tcreatewindowevent; +begin + if fwindow.id = 0 then begin + fnormalwindowrect:= fownerwidget.fwidgetrect; + fillchar(aoptions,sizeof(aoptions),0); + fillchar(aoptions1,sizeof(aoptions1),0); + aoptions.groupleader:= application.mainwindow; + aoptions.initialwindowpos:= fwindowpos; + aoptions.transientfor:= ftransientfor; + fownerwidget.updatewindowinfo(aoptions); + foptions:= aoptions.options; + fwindowpos:= aoptions.initialwindowpos; + fwindowposbefore:= fwindowpos; + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(tws_needsdefaultpos),fwindowpos = wp_default); + with aoptions do begin + buttonendmodal:= wo_buttonendmodal in options; + aoptions1.options:= options; + aoptions1.pos:= fwindowpos; + if transientfor <> ftransientfor then begin + checkrecursivetransientfor(transientfor); + setlinkedvar(transientfor,tlinkedobject(ftransientfor)); + if transientfor <> nil then begin + inc(ftransientfor.ftransientforcount); + aoptions1.transientfor:= transientfor.winid; + end; + end; + aoptions1.icon:= icon; + aoptions1.iconmask:= iconmask; + end; + if (aoptions.groupleader <> nil) and + aoptions.groupleader.fownerwidget.isgroupleader then begin + aoptions1.setgroup:= true; + if aoptions.groupleader <> self then begin + aoptions1.groupleader:= aoptions.groupleader.fwindow.id; + //do not create winid + end; + end; + if application.ismainthread then begin + fcanvas.updatewindowoptions(aoptions1); + guierror(gui_createwindow(fownerwidget.fwidgetrect,aoptions1,fwindow),self); + end + else begin //needed for win32 + event:= tcreatewindowevent.create(false); + with event do begin + fsender:= self; + frect:= fownerwidget.widgetrect; + foptionspo:= @aoptions1; + fwindowpo:= @self.fwindow; + synchronizeevent(event); + free; + end; + if fwindow.id = 0 then begin + abort; + end; + end; + sizeconstraintschanged; + fstate:= fstate - [tws_posvalid,tws_sizevalid]; + fillchar(gc,sizeof(gcty),0); + gc.paintdevicesize:= fownerwidget.fwidgetrect.size; + gc.kind:= bmk_rgb; //todo: what about depht 8? + gdierror(fcanvas.creategc(fwindow.id,gck_screen,gc),self); + gc.paintdevicesize:= fownerwidget.fwidgetrect.size; + fcanvas.linktopaintdevice(fwindow.id,gc{,fowner.fwidgetrect.size},nullpoint); + gdierror(fasynccanvas.creategc(fwindow.id,gck_screen,gc),self); + fasynccanvas.linktopaintdevice(fwindow.id,gc,{fowner.fwidgetrect.size,}nullpoint); + if appinst <> nil then begin + tinternalapplication(application).registerwindow(self); + end; + if fcaption <> '' then begin + gui_setwindowcaption(fwindow.id,fcaption); + end; + if fopacity <> emptyreal then begin + gui_setwindowopacity(fwindow.id,fopacity); + end; + fownerwidget.windowcreated; + end + else begin + guierror(gue_illegalstate,self); + end; +end; + +procedure twindow.destroywindow; +begin + releasemouse; + if appinst <> nil then begin + if appinst.caret.islinkedto(fcanvas) then begin + appinst.caret.hide; + end; + appinst.unregisterwindow(self); + end; + fcanvas.unlink; + fasynccanvas.unlink; + if fwindow.id <> 0 then begin + appinst.windowdestroyed(fwindow.id); + end; +// if application.ismainthread then begin +// if fdestroyevent <> nil then begin +// tdestroywindowevent(fdestroyevent).fwindowpo:= nil; +// end; + gui_destroywindow(fwindow); +// end +// else begin +// if fdestroyevent = nil then begin +// fdestroyevent:= tdestroywindowevent.create(false); +// tdestroywindowevent(fdestroyevent).fwindowpo:= @fwindow; +// synchronizeevent(tdestroywindowevent(fdestroyevent)); +// freeandnil(fdestroyevent); +// end; +// end; + fillchar(fwindow,sizeof(fwindow),0); + exclude(fstate,tws_windowvisible); +end; + +procedure twindow.recreatewindow(); +var + b1: boolean; +begin + b1:= visible; + destroywindow(); + createwindow(); + if b1 then begin + show(false); + end; +end; + +procedure twindow.windowdestroyed; +begin + fwindow.id:= 0; + destroywindow; +end; + +procedure twindow.checkwindowid; +begin + checkwindow(false); +end; + +procedure twindow.checkwindow(windowevent: boolean); +begin + if (appinst <> nil) and (aps_inited in appinst.fstate) then begin + if fwindow.id = 0 then begin + createwindow; + end + else begin + if fstate * [tws_posvalid,tws_sizevalid] <> + [tws_posvalid,tws_sizevalid] then begin + if not windowevent and not (tws_needsdefaultpos in fstate) and + (fmoving <= 0) and (windowpos in [wp_normal,wp_default]) then begin + if not (wo_embedded in foptions) then begin + fnormalwindowrect:= fownerwidget.fwidgetrect; + {$ifdef mse_debugconfigure} + with fnormalwindowrect do begin + if visible then begin + debugwindow('*checkwin visible '+ + inttostr(x)+' '+inttostr(y)+' '+inttostr(cx)+' '+inttostr(cy)+' ', + fwindow.id); + end + else begin + debugwindow('*checkw. invis. '+ + inttostr(x)+' '+inttostr(y)+' '+inttostr(cx)+' '+inttostr(cy)+' ', + fwindow.id); + end; + end; + {$endif} + appinst.removewindowevents(fwindow.id,ek_configure); + guierror(gui_reposwindow(fwindow.id,fnormalwindowrect),self); + end; + fstate:= fstate + [tws_posvalid,tws_sizevalid]; + end; + end; + end; + end; +end; + +function twindow.activating: boolean; //in internalactivate proc +begin + result:= factivating > 0; +end; + +procedure twindow.internalactivate(const windowevent: boolean; + const force: boolean = false); + + procedure setwinfoc; + var + window1: twindow; + focustransientforbefore: twindow; + begin + focustransientforbefore:= appinst.ffocuslocktransientfor; + if (ftransientfor <> nil) and (force or (appinst.ffocuslockwindow = nil)) and + (wo_popup in foptions) then begin + appinst.ffocuslockwindow:= self; + window1:= ftransientfor; + repeat + if window1 = appinst.ffocuslocktransientfor then begin + break; + end; + window1:= window1.ftransientfor; + until window1 = nil; + if window1 = nil then begin + if appinst.ffocuslocktransientfor <> ftransientfor then begin + appinst.ffocuslocktransientfor:= ftransientfor; + exclude(appinst.fstate,aps_restorelocktransientfor); + end; + end; + end + else begin + if not ispopup then begin + appinst.ffocuslocktransientfor:= nil; + end; + end; + if (appinst.ffocuslockwindow <> nil) and + (appinst.ffocuslocktransientfor <> nil) then begin + if (focustransientforbefore <> appinst.ffocuslocktransientfor) or + (aps_restorelocktransientfor in appinst.fstate) then begin + exclude(appinst.fstate,aps_restorelocktransientfor); + guierror(gui_setwindowfocus(appinst.ffocuslocktransientfor.winid),self); + end; + end + else begin + if (appinst.ffocuslockwindow = nil) or + (appinst.ffocuslockwindow = self) then begin + guierror(gui_setwindowfocus(fwindow.id),self); + end; + end; + end; + +var + activecountbefore: longword; + activewindowbefore: twindow; + widgetar: widgetarty; + int1: integer; + b1,b2: boolean; + window1: twindow; + widget1: twidget; + +begin +{$ifdef mse_debugwindowfocus} + debugwindow('*internalactivate ',fwindow.id); + debugwrite(' modalwindow '); + if appinst.fmodalwindow = nil then begin + debugwriteln(' NIL'); + end + else begin + debugwriteln(appinst.fmodalwindow.fownerwidget.name); + end; +{$endif} + inc(factivating); + try + if appinst.finactivewindow = self then begin + appinst.finactivewindow:= nil; + end; + activewindowbefore:= nil; + setlinkedvar(appinst.factivewindow,tlinkedobject(activewindowbefore)); + show(windowevent); + widgetar:= nil; //compilerwarning + if activewindowbefore <> self then begin + b1:= force or (appinst.fmodalwindow = nil) or (appinst.fmodalwindow = self) or + (ftransientfor = appinst.fmodalwindow); + if b1 then begin + if hastransientfor then begin + window1:= topmodaltransientfor; + if window1 <> nil then begin + window1.internalactivate(false,force); + exit; + end; + end; + if (ffocusedwidget = nil) and fownerwidget.canfocus and (ffocusing = 0) then begin + fownerwidget.setfocus(true); + if windowevent and force and not active then begin + internalactivate(true,true); //call by setfocus was without force + end; + exit; + end; + b2:= activewindowbefore <> nil; + if b2 then begin + b1:= tws_activating in activewindowbefore.fstate; + include(fstate,tws_activating); + try + activewindowbefore.deactivate; + finally + if not b1 and (activewindowbefore <> nil) then begin + exclude(activewindowbefore.fstate,tws_activating); + end; + end; + end; + if appinst.factivewindow = nil then begin + if not (ws_active in fownerwidget.fwidgetstate) then begin + inc(factivecount); + activecountbefore:= factivecount; + appinst.factivewindow:= self; + appinst.flastactivewindow:= self; + appinst.checkapplicationactive(); + if not (tws_activatelocked in fstate) then begin + if fownerwidget.canassistive() then begin + assistiveserver.dowindowactivated( + self.fownerwidget.getiassistiveclient()); + end; + if ffocusedwidget <> nil then begin + widgetar:= ffocusedwidget.getrootwidgetpath; + for int1:= high(widgetar) downto 0 do begin + widgetar[int1].internaldoactivate; + if factivecount <> activecountbefore then begin + exit; + end; + end; + end; + end; + gui_setimefocus(fwindow); + if not windowevent then begin + setwinfoc; + end + else begin + if appinst.ffocuslockwindow <> self then begin + appinst.ffocuslockwindow:= nil; + appinst.ffocuslocktransientfor:= nil; + end + else begin + if appinst.ffocuslocktransientfor <> nil then begin + guierror(gui_setwindowfocus(appinst.ffocuslocktransientfor.winid),self); + end; + end; + end; + end; + end; + appinst.fonwindowactivechangelist.dowindowchange(activewindowbefore,self); + if activecountbefore = factivecount then begin + if activewindowbefore = nil then begin + widget1:= nil; + end + else begin + widget1:= activewindowbefore.focusedwidget; + end; + appinst.fonwidgetactivechangelist.dowidgetchange(widget1, + self.focusedwidget); + end; + end + else begin + appinst.fwantedactivewindow:= self; + end; + end + else begin + setwinfoc; + end; + finally + dec(factivating); + setlinkedvar(nil,tlinkedobject(activewindowbefore)); + end; +{$ifdef mse_debugwindowfocus} + debugwindow('-internalactivate ',fwindow.id); +{$endif} +end; + +procedure twindow.noactivewidget; +var + widget: twidget; + activecountbefore: longword; +begin + if ffocusedwidget <> nil then begin + inc(factivecount); + activecountbefore:= factivecount; + widget:= ffocusedwidget; + while widget <> nil do begin + widget.internaldodeactivate; + if factivecount <> activecountbefore then begin + exit; + end; + widget:= widget.fparentwidget; + end; + end + else begin + fownerwidget.internaldodeactivate; + end; +end; + +procedure twindow.lockactivate; +begin + noactivewidget; + include(fstate,tws_activatelocked); +end; + +procedure twindow.unlockactivate; +begin + exclude(fstate,tws_activatelocked); +end; + +procedure twindow.deactivate; +var + activecountbefore: longword; + widget1: twidget; +begin + if appinst.ffocuslockwindow = self then begin + appinst.ffocuslockwindow:= nil; + end; + if ws_active in fownerwidget.fwidgetstate then begin + noactivewidget; + if appinst.factivewindow = self then begin + inc(factivecount); + activecountbefore:= factivecount; + if not (tws_activating in fstate) then begin + appinst.fonwindowactivechangelist.dowindowchange(appinst.factivewindow,nil); + end; + if factivecount = activecountbefore then begin + if fownerwidget.canassistive() then begin + assistiveserver.dowindowdeactivated(self.fownerwidget.getiassistiveclient()); + end; + widget1:= nil; + if appinst.factivewindow <> nil then begin + widget1:= appinst.factivewindow.focusedwidget; + end; + try + if not (tws_activating in fstate) then begin + appinst.fonwidgetactivechangelist.dowidgetchange(widget1,nil); + end; + finally + if factivecount = activecountbefore then begin + appinst.factivewindow:= nil; + gui_unsetimefocus(fwindow); + end; + end; + end; + end; + end + else begin + if appinst.factivewindow = self then begin + appinst.factivewindow:= nil; //should never happen + end; + end; +end; + +function twindow.deactivateintermediate: boolean; +begin + appinst.finactivewindow:= self; + try + deactivate; + finally + if appinst.factivewindow = self then begin + if appinst.finactivewindow = self then begin + appinst.finactivewindow:= nil; + end; + result:= false; + end + else begin + result:= true; + end; + end; +end; + +procedure twindow.reactivate(const force: boolean = false); //clears appinst.finactivewindow +begin + appinst.finactivewindow:= nil; + activate(force); + include(appinst.fstate,aps_needsupdatewindowstack); +end; + +procedure twindow.hide(windowevent: boolean); +var + int1,int2: integer; + window1: twindow; + bo1: boolean; + mini1: boolean; + mydesktop: integer; +begin + releasemouse; + fstate:= fstate - [tws_posvalid,tws_sizevalid,tws_windowshowpending]; +{$ifdef mse_debugconfigure} + if windowevent then begin + debugwindow('*hide windowevent ',fwindow.id); + end + else begin + debugwindow('*hide no windowevent ',fwindow.id); + end; +{$endif} + if not(ws_visible in fownerwidget.fwidgetstate) then begin + mini1:= windowpos = wp_minimized; + if not mini1 then begin + exclude(fstate,tws_modalfor); + end; + if fwindow.id <> 0 then begin + if tws_windowvisible in fstate then begin + exclude(fstate,tws_transientforminimized); + if not windowevent or (appinst.factivewindow = self) then begin + endmodal; + end; + if (fsyscontainer <> sywi_none) or (fcontainer <> 0) then begin + exclude(fstate,tws_windowvisible); + if not windowevent then begin + if (fsyscontainer <> sywi_none) then begin + gui_hidesysdock(fwindow); + end + else begin + gui_hidewindow(fwindow.id); + end; + end; + end + else begin + if (application.fmainwindow = self) and not appinst.terminated then begin + mydesktop:= gui_getwindowdesktop(fwindow.id); + bo1:= gui_grouphideminimizedwindows; + application.sortzorder; + with appinst do begin + setlength(fgroupzorder,length(fwindows)); + int2:= 0; + for int1:= 0 to high(fwindows) do begin + with fwindows[int1] do begin + if (tws_windowvisible in fstate) and + (gui_getwindowdesktop(fwindow.id) = mydesktop) then begin + //don't touch invisible windows or other desktops + fgroupzorder[int2]:= fwindows[int1]; + inc(int2); + end; + end; + end; + if int2 = 1 then begin + fgroupzorder:= nil; //only me + end + else begin + setlength(fgroupzorder,int2); + end; + end; + + fstate:= fstate - [tws_windowvisible,tws_groupmaximized]; + include(fstate,tws_grouphidden); + include(fstate,tws_groupminimized); + if fwindowposbefore = wp_maximized then begin + include(fstate,tws_groupmaximized); + end; + appinst.flockupdatewindowstack:= self; + //lock z-order manipulation until show + + for int1:= 0 to high(appinst.fwindows) do begin + window1:= appinst.fwindows[int1]; + {$ifdef mse_debugwindowfocus} + if (window1.fwindow.id <> 0) and ((window1 = self) or + gui_windowvisible(window1.fwindow.id)) then begin + if window1 = self then begin + debugwrite('* '); + end; + debugwindow('groupminimized ',window1.fwindow.id); + end; + {$endif} + if (window1 <> self) and (window1.fwindow.id <> 0) and + gui_windowvisible(window1.fwindow.id) and + (gui_getwindowdesktop(window1.fwindow.id) = mydesktop) then begin + with window1 do begin + include(fstate,tws_grouphidden); + if tws_windowvisible in fstate then begin + include(fstate,tws_groupminimized); + end; + if windowpos = wp_maximized then begin + include(fstate,tws_groupmaximized); + end + else begin + exclude(fstate,tws_groupmaximized); + end; + gui_setwindowstate(winid,wsi_minimized,false); + if bo1 or (wo_notaskbar in foptions) then begin + gui_hidewindow(winid); + end; + end; + end; + end; + {$ifdef mse_debugwindowfocus} + for int1:= 0 to high(appinst.fgroupzorder) do begin + debugwriteln(' groupzorder '+appinst.fgroupzorder[int1].fownerwidget.name); + end; + {$endif} + if bo1 then begin + gui_minimizeapplication; + end; + end + else begin + exclude(fstate,tws_windowvisible); + if mini1 and (tws_modalfor in fstate) and (ftransientfor <> nil) and + ftransientfor.visible then begin + ftransientfor.windowpos:= wp_minimized; + include(fstate,tws_transientforminimized); + end; + end; + if not windowevent then begin + exclude(fstate,tws_grouphidden); + gui_hidewindow(fwindow.id); + end; + end; + end; + end; + if not fownerwidget.visible and (fownerwidget.canassistive()) then begin + assistiveserver.dowindowdeactivated(self.fownerwidget.getiassistiveclient()); + end; + end; +end; + +procedure twindow.show(windowevent: boolean); +var + int1: integer; + window1: twindow; + size1: windowsizety; + {bo1,}bo2: boolean; + mydesktop: integer; +begin + if (ow_transientformain in fownerwidget.foptionswidget) and + (ftransientfor = nil) and (application.mainwindow <> nil) and + (application.mainwindow <> self) then begin + checkwindowid(); + settransientfor(application.mainwindow,false); + end; + if windowevent then begin + {$ifdef mse_debugconfigure} + debugwindow('*show windowevent ',fwindow.id); + {$endif} + exclude(fstate,tws_windowshowpending); + checkwindowid; //check position + end; + if (ws_visible in fownerwidget.fwidgetstate) then begin + if not visible then begin + if not windowevent then begin + include(fstate,tws_windowshowpending); + end; + include(fstate,tws_windowvisible); + checkwindowid; + {$ifdef mse_debugwindowfocus} + debugwindow('*show ',fwindow.id); + {$endif} + with appinst do begin + if flockupdatewindowstack = self then begin + flockupdatewindowstack:= nil; //enable z-order handling + fwindowstack:= nil; //remove pending + end; + end; + if (fstate * [tws_transientforminimized,tws_modalfor] = + [tws_transientforminimized,tws_modalfor]) and + (ftransientfor <> nil) then begin +// ftransientfor.fowner.internalshow(ml_none,nil,false,true); + ftransientfor.fownerwidget.internalshow(ml_none, + @ftransientfor.ftransientfor,false,true); + end; + exclude(fstate,tws_transientforminimized); + if not (csdesigning in fownerwidget.ComponentState) then begin + if (fsyscontainer <> sywi_none) or (fcontainer <> 0) then begin + if not windowevent then begin + if (fsyscontainer <> sywi_none) then begin + gui_showsysdock(fwindow); + end + else begin + gui_showwindow(fwindow.id); + end; + end; + end + else begin + include(appinst.fstate,aps_needsupdatewindowstack); + if not windowevent then begin + case fwindowpos of + wp_maximized: begin + size1:= wsi_maximized; + end; + wp_fullscreen: begin + size1:= wsi_fullscreen; + end; + wp_fullscreenvirt: begin + size1:= wsi_fullscreenvirt; + end + else begin + size1:= wsi_normal; + end; + end; + gui_setwindowstate(winid,size1,true); + if (fwindowpos = wp_normal) and not (tws_needsdefaultpos in fstate) and + not (wo_embedded in foptions) then begin + gui_reposwindow(fwindow.id,fnormalwindowrect); + end; + fstate:= fstate-[tws_posvalid,tws_sizevalid]; + //possibly wrong window pos because of KDE bug with staticgravity + end; + exclude(fstate,tws_grouphidden); + exclude(fstate,tws_groupminimized); +// bo1:= gui_grouphideminimizedwindows; + mydesktop:= gui_getwindowdesktop(fwindow.id); + bo2:= false; + if not ispopup and not (tws_modalfor in fstate) and + (fmodallevel = 0) then begin + for int1:= 0 to high(appinst.fwindows) do begin + window1:= appinst.fwindows[int1]; + if window1 <> self then begin + with window1 do begin + if (tws_grouphidden in fstate) and (fwindow.id <> 0) and + (gui_getwindowdesktop(fwindow.id) = mydesktop) then begin + size1:= wsi_minimized; + if tws_groupminimized in fstate then begin + size1:= wsi_normal; + if tws_groupmaximized in fstate then begin + size1:= wsi_maximized; + end; + end; + {$ifdef mse_debugwindowfocus} + debugwindow('groupshow '+ + getenumname(typeinfo(windowsizety),integer(size1))+' ',fwindow.id); + {$endif} + if fwindow.id <> 0 then begin + gui_setwindowstate(fwindow.id,size1,true); + end; + bo2:= true; + exclude(fstate,tws_grouphidden); + exclude(fstate,tws_groupminimized); + end; + end; + end; + end; + end; + if (fwindowposbefore = wp_maximized) and + (windowpos <> wp_maximized) then begin + //necessary for win32 show desktop + gui_setwindowstate(winid,wsi_maximized,true); + end; + if {bo1 and} bo2 then begin + window1:= nil; //compiler warning + activate; + with appinst do begin + if fgroupzorder <> nil then begin +// removeitem(pointerarty(fgroupzorder),window1); +// additem(pointerarty(fgroupzorder),window1); + {$ifdef mse_debuggrouprestore} + debugwriteln('*** grouprestorezorder '+fowner.name); + {$endif} + flockupdatewindowstack:= nil; //enable z-order handling + for int1:= 0 to high(fgroupzorder) do begin + if fgroupzorder[int1] = self then begin + moveitem(pointerarty(fgroupzorder),int1,high(fgroupzorder)); + //probably focused, bring to front + break; + end; + end; + fwindowstack:= nil; + setlength(fwindowstack,high(fgroupzorder)); + window1:= fgroupzorder[0]; //lowest + for int1:= 1 to high(fgroupzorder) do begin + if fgroupzorder[int1] = self then begin + moveitem(pointerarty(fgroupzorder),int1,high(fgroupzorder)); + //probably focused, bring to front + end; + {$ifdef mse_debuggrouprestore} + debugwriteln(' '+inttostr(int1)+' '+window1.fowner.name+' '+ + fgroupzorder[int1].fowner.name); + {$endif} + fwindowstack[int1-1].upper:= fgroupzorder[int1]; + fwindowstack[int1-1].lower:= window1; + window1:= fgroupzorder[int1]; + end; + include(fstate,aps_needsupdatewindowstack); + end; + end; + end; + end; + end; + end; + end; +end; + +function twindow.beginmodal(const showinfo: pshowinfoty): boolean; +var + pt1: pointty; + event1: tmouseevent; + win1: winidty; + focusedwidgetbefore: twidget; + window1: twindow; +begin + fmodalresult:= mr_none; + with appinst do begin + deactivatehint; + if (fmousecapturewidget <> nil) and + not ((showinfo <> nil) and + (fmousecapturewidget = showinfo^.widget)) then begin + fmousecapturewidget.releasemouse; + releasemouse; + end; + if fmodalwindow = nil then begin + fwantedactivewindow:= nil; //init for lowest level + end; + focusedwidgetbefore:= nil; + setlinkedvar(ffocusedwidget,tmsecomponent(focusedwidgetbefore)); + try + appinst.cursorshape:= cr_default; + win1:= fmousewinid; + processleavewindow; + fmousewinid:= win1; + result:= beginmodal(self,showinfo); + if (fmodalwindow = nil) then begin + if not (aps_cancelloop in appinst.fstate) then begin + window1:= fwantedactivewindow; + if (window1 = self) or (window1 = nil) and + (focusedwidgetbefore <> nil) then begin + focusedwidgetbefore.parentfocus; + end; + if appinst.active then begin + if fwantedactivewindow <> nil then begin + fwantedactivewindow:= nil; + window1.activate; + end; + end; + end; + end + else begin + if fmodalwindow = fwantedactivewindow then begin + fwantedactivewindow:= nil; + end; + if appinst.active and not (aps_cancelloop in appinst.fstate) then begin + fmodalwindow.activate; + end; + exclude(fmodalwindow.fstate,tws_focusoutpending); + end; + finally + setlinkedvar(nil,tmsecomponent(focusedwidgetbefore)); + end; + if appinst.modallevel = 1 then begin + exclude(appinst.fstate,aps_cancelloop); + end; + if (factivewindow <> nil) and not factivewindow.fownerwidget.releasing then begin + pt1:= mouse.pos; + if pointinrect(pt1,factivewindow.fownerwidget.fwidgetrect) then begin + event1:= tmouseevent.create(factivewindow.winid,false,mb_none,mw_none, + subpoint(pt1,factivewindow.fownerwidget.fwidgetrect.pos), + appinst.lastshiftstate,0,false); + try + appinst.processmouseevent(event1); //simulate mousemove + finally + event1.free1; + end; + end; + end; + end; +end; + +function twindow.beginmodal: boolean; //true if destroyed +begin + result:= beginmodal(nil); +end; + +procedure twindow.endmodal; +begin + appinst.endmodal(self); +end; + +procedure twindow.poschanged; +begin + exclude(fstate,tws_posvalid); + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; +end; + +procedure twindow.sizechanged; +begin + exclude(fstate,tws_sizevalid); + tcanvas1(fcanvas).updatesize(fownerwidget.fwidgetrect.size); + tcanvas1(fasynccanvas).updatesize(fownerwidget.fwidgetrect.size); + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; +end; + +procedure twindow.wmconfigured(const arect: rectty; const aorigin: pointty); +const + maxsizeerrorcount = 4; +var + rect1: rectty; +begin +{$ifdef mse_debugconfigure} + debugwindow('*wmconfigured '+ + inttostr(aorigin.x)+' '+inttostr(aorigin.y)+'|'+ + inttostr(arect.x)+' '+inttostr(arect.y)+ + ' '+inttostr(arect.cx)+' '+inttostr(arect.cy)+' ',fwindow.id); + +{$endif} + if (tws_windowshowpending in fstate) and visible and + gui_windowvisible(fwindow.id) then begin + exclude(fstate,tws_windowshowpending); + end; + rect1:= arect; + if not (wo_embedded in foptions) then begin + addpoint1(rect1.pos,aorigin); + end; + if not (wo_embedded in foptions) and (not visible or + (tws_windowshowpending in fstate)) then begin + //do not accept changes by hiding window (kwin bugs) + if not rectisequal(fownerwidget.fwidgetrect,rect1) then begin + fstate:= fstate - [tws_posvalid,tws_sizevalid]; + end; + end + else begin + if (fstate*[tws_posvalid,tws_sizevalid] <> [tws_posvalid,tws_sizevalid]) and + (windowpos <> wp_maximized) and not (wo_embedded in foptions) then begin + checkwindow(false); + end + else begin + // if tws_needsdefaultpos in fstate then begin + // fnormalwindowrect:= fowner.fwidgetrect; + // end; + fstate:= (fstate + [tws_posvalid,tws_sizevalid]) - [tws_needsdefaultpos]; + if not rectisequal(rect1,fownerwidget.fwidgetrect) then begin + if fsizeerrorcount < maxsizeerrorcount then begin + fownerwidget.checkwidgetsize(rect1.size); + end; + fownerwidget.internalsetwidgetrect(rect1,true); + if pointisequal(rect1.pos,fownerwidget.fwidgetrect.pos) then begin + include(fstate,tws_posvalid); + end; + if sizeisequal(arect.size,fownerwidget.fwidgetrect.size) then begin + include(fstate,tws_sizevalid); + fsizeerrorcount:= 0; + end + else begin + if fsizeerrorcount < maxsizeerrorcount then begin + inc(fsizeerrorcount); + gui_reposwindow(fwindow.id,rect1); + end; + end; + end; + fwindowposbefore:= windowpos; + if not (fwindowposbefore in [wp_minimized]+windowmaximizedstates) then begin + fnormalwindowrect:= fownerwidget.fwidgetrect; + end; + end; + end; +end; + +function twindow.internalupdate: boolean; //false if nothing is painted +var + bo1: boolean; + bmp: tbitmap; + rect1: rectty; + po1: pointty; + reg1: regionty; +begin + result:= false; + if (ws_visible in fownerwidget.fwidgetstate) and (fupdateregion.region <> 0) then begin + checkwindow(false); //ev. reposition window + fcanvas.reset; + fcanvas.clipregion:= fupdateregion.region; //canvas owns the region + { + bo1:= appinst.caret.islinkedto(fcanvas) and + testintersectrect(fcanvas.clipbox,appinst.caret.rootcliprect); + } + bo1:= false; + if appinst.caret.islinkedto(fcanvas) and appinst.fcaret.active and + testintersectrect(fcanvas.clipbox,appinst.caret.rootcliprect) then begin + reg1:= fcanvas.copyclipregion; + fcanvas.regintersectrect(reg1,appinst.caret.rootcliprect); + bo1:= not fcanvas.regionisempty(reg1); + fcanvas.destroyregion(reg1); + if bo1 then begin + tcaret1(appinst.fcaret).remove; + end; + end; + include(fstate,tws_painting); + if flushgdi then begin + try + fupdateregion.region:= 0; + result:= true; + fownerwidget.paint(fcanvas); + finally + if bo1 then begin + tcaret1(appinst.fcaret).restore; + end; + fcanvas.endpaint; + end; + end + else begin + bmp:= tbitmap.create(bmk_rgb,fgdi); + try + if intersectrect(fcanvas.clipbox, + makerect(nullpoint,fownerwidget.widgetrect.size),rect1) then begin + bmp.size:= rect1.size; + bmp.canvas.clipregion:= bmp.canvas.createregion(fupdateregion.region); + po1.x:= -rect1.x; + po1.y:= -rect1.y; + tcanvas1(bmp.canvas).setcliporigin(po1); + bmp.canvas.origin:= nullpoint; + fupdateregion.region:= 0; + result:= true; + fownerwidget.paint(bmp.canvas); + bmp.paint(fcanvas,rect1); + end + else begin + fupdateregion.region:= 0; + end; + finally + bmp.Free; + if bo1 then begin + tcaret1(appinst.fcaret).restore; + end; + end; + end; + exclude(fstate,tws_painting); + end; +end; + +procedure twindow.mouseparked; +var + info: moeventinfoty; +begin + info.mouse:= appinst.fmouseparkeventinfo; + info.mouse.eventkind:= ek_mousepark; + exclude(info.mouse.eventstate,es_processed); + dispatchmouseevent(info,appinst.fmousecapturewidget); +end; + +procedure twindow.checkmousewidget(const info: mouseeventinfoty; + var capture: twidget); +begin + if capture = nil then begin + capture:= fownerwidget.mouseeventwidget(info); + if (fmodalwidget <> nil) and + not fmodalwidget.checkdescendent(capture) then begin + capture:= fmodalwidget; + end; + if (capture = nil) and (tws_grab in fstate) then begin + capture:= fmodalwidget; + if capture = nil then begin + capture:= fownerwidget; + end; + end; + end; + appinst.setmousewidget(capture); +end; + +procedure twindow.dispatchmouseevent(var info: moeventinfoty; capture: twidget); +var + posbefore: pointty; + mousecapturewidgetbefore: twidget; + int1: integer; + po1: peventaty; + self1: tlinkedobject; +begin + if not (es_designcall in info.mouse.eventstate) then begin + //no "inherited" call from designmouseevent + if info.mouse.eventkind = ek_mousewheel then begin + capture:= fownerwidget.mouseeventwidget(info.mouse); + if (capture = nil) and (ftransientfor <> nil) then begin + include(info.mouse.eventstate,es_transientfor); + subpoint1(info.mouse.pos,subpoint( + ftransientfor.fownerwidget.pos,fownerwidget.pos)); + ftransientfor.dispatchmouseevent(info,capture); + exit; + end; + end + else begin + checkmousewidget(info.mouse,capture); + end; + end; + if capture <> nil then begin + if not (es_designcall in info.mouse.eventstate) and + capture.isdesignwidget() then begin + include(info.mouse.eventstate,es_designcall); + capture.designmouseevent(info,capture); + exclude(info.mouse.eventstate,es_designcall); + if es_processed in info.mouse.eventstate then begin + exit; + end; + end; + mousecapturewidgetbefore:= appinst.fmousecapturewidget; + self1:= nil; + setlinkedvar(self,self1); //for destroy check + try + with capture do begin +// absposbefore:= info.mouse.pos; + subpoint1(info.mouse.pos,rootpos); + posbefore:= info.mouse.pos; + appinst.fmousewidgetpos:= posbefore; + appinst.fdelayedmouseshift:= nullpoint; + if info.mouse.eventkind = ek_mousewheel then begin + mousewheelevent(info.wheel); + end + else begin + mousepreview(capture,info.mouse); + if self1 = nil then begin + exit; + end; + if not (es_processed in info.mouse.eventstate) then begin + if (info.mouse.eventkind = ek_buttonpress) and + (tws_buttonendmodal in fstate) and + (fmodalwidget = capture) then begin + endmodal; + exit; + end; + mouseevent(info.mouse); + if self1 = nil then begin + exit; + end; + end; + if (info.mouse.eventkind = ek_buttonpress) and ispopup and + self.fownerwidget.visible and + (ow_mousefocus in self.fownerwidget.foptionswidget) and + not (csdestroying in self.fownerwidget.componentstate) and + not (acs_releasing in self.fownerwidget.factstate) then begin + activate; //possibly not done by windowmanager + end; + end; + if self1 = nil then begin + exit; + end; + posbefore:= subpoint(info.mouse.pos,posbefore); + addpoint1(posbefore,appinst.fdelayedmouseshift); + if (posbefore.x <> 0) or (posbefore.y <> 0) then begin + gui_flushgdi; + with appinst do begin + getevents; + po1:= peventaty(eventlist.datapo); + for int1:= 0 to eventlist.count -1 do begin + if (po1^[int1] <> nil) and (po1^[int1].kind = ek_mousemove) then begin + freeandnil(po1^[int1]); //remove invalid events + end; + end; + mouse.move(posbefore); + end; + end; + end; + with info.mouse do begin + if (eventkind = ek_buttonrelease) and + (appinst.fmousecapturewidget = nil) and + (mousecapturewidgetbefore <> nil) then begin + exclude(eventstate,es_processed); + eventkind:= ek_mousemove; + pos:= translatewidgetpoint(application.mouse.pos,nil,fownerwidget); +// pos:= addpoint(absposbefore,posbefore); + dispatchmouseevent(info,nil); //immediate mouseenter + eventkind:= ek_buttonrelease; + end; + end; + finally + if self1 <> nil then begin + setlinkedvar(nil,self1); + end; + end; + end; +end; + +procedure twindow.dispatchkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); +var + widget1: twidget; +begin + if appinst.fkeyboardcapturewidget <> nil then begin + widget1:= appinst.fkeyboardcapturewidget; + end + else begin + widget1:= ffocusedwidget; + end; + if widget1 <> nil then begin + if widget1.isdesignwidget() then begin + widget1.designkeyevent(eventkind,info); + if es_processed in info.eventstate then begin + exit; + end; + end; + case eventkind of + ek_keypress: widget1.internalkeydown(info); + ek_keyrelease: widget1.dokeyup(info); + end; + end + else begin + if eventkind = ek_keypress then begin + include(info.eventstate,es_preview); + try + doshortcut(info,fownerwidget); + finally + exclude(info.eventstate,es_preview); + end; + doshortcut(info,fownerwidget); + end; + end; +end; + +procedure twindow.setfocusedwidget(const widget: twidget); +var + focuscountbefore: longword; + focusedwidgetbefore: twidget; + widget1: twidget; + widgetar: widgetarty; + int1,int2,int3: integer; + bo1: boolean; + ass1,ass2: iassistiveclient; +begin + widgetar:= nil; //compiler warning + if (ffocusedwidget <> widget) and ((fmodalwidget = nil) or (widget = nil) or + fmodalwidget.checkdescendent(widget)) then begin + if widget <> nil then begin + inc(ffocusing); + end; + try + inc(ffocuscount); + focuscountbefore:= ffocuscount; + focusedwidgetbefore:= nil; + setlinkedvar(ffocusedwidget,tmsecomponent(focusedwidgetbefore)); + widget1:= ffocusedwidget; + if widget1 <> nil then begin + if not (csdestroying in widget1.componentstate) then begin + bo1:= tws_candefocus in fstate; + try + include(fstate,tws_candefocus); + if not widget1.canclose(widget) then begin + exit; + end; + finally + if not bo1 then begin + exclude(fstate,tws_candefocus); + end; + end; + if (ffocuscount <> focuscountbefore) then begin + exit; + end; + ffocusedwidget:= nil; + widget1.internaldodefocus; + if ffocuscount <> focuscountbefore then begin + exit; + end; + end + else begin + ffocusedwidget:= nil; + end; + while (widget1 <> nil) and (widget1 <> widget) and + not widget1.checkdescendent(widget) do begin + fenteredwidget:= widget1.fparentwidget; + if not (csdestroying in widget1.componentstate) then begin + widget1.internaldodeactivate; + if ffocuscount <> focuscountbefore then begin + exit; + end; + widget1.internaldoexit; + if ffocuscount <> focuscountbefore then begin + exit; + end; + end; + widget1:= fenteredwidget; + end; + end; + if (widget <> nil) and not widget.canfocus then begin + exit; + end; + ffocusedwidget:= widget; + if widget <> nil then begin + widgetar:= widget.getrootwidgetpath; //new focus + int2:= length(widgetar); + int3:= int2; + bo1:= appinst.factivewindow = self; + if widget1 <> nil then begin + if widget1.checkancestor(fenteredwidget) then begin + widget1:= fenteredwidget; + end; + for int1:= 0 to high(widgetar) do begin + if widgetar[int1] = widget1 then begin + int2:= int1; //common ancestor + break; + end; + end; + if bo1 then begin + int3:= length(widgetar); + for int1:= int2 to high(widgetar) do begin + if widgetar[int1].active then begin + int3:= int1; + break; + end; + end; + end; + end; + for int1:= int3-1 downto 0 do begin + if int1 < int2 then begin + fenteredwidget:= widgetar[int1]; + fenteredwidget.internaldoenter; + if ffocuscount <> focuscountbefore then begin + exit; + end; + if int1 = 0 then begin + widgetar[int1].internaldofocus(); + if ffocuscount <> focuscountbefore then begin + exit; + end; + end; + end; + if bo1 then begin + widgetar[int1].internaldoactivate(); + end; + if ffocuscount <> focuscountbefore then begin + exit; + end; + end; +// ffocusedwidget.internaldofocus; + end + else begin + fenteredwidget:= nil; + end; + if fownerwidget.canassistive() then begin + ass1:= nil; + if focusedwidgetbefore <> nil then begin + ass1:= focusedwidgetbefore.getiassistiveclient(); + end; + ass2:= nil; + if focusedwidget <> nil then begin + ass2:= focusedwidget.getiassistiveclient(); + end; + assistiveserver.dofocuschanged(fownerwidget.getiassistiveclient(), + ass1,ass2); + end; + fownerwidget.dofocuschanged(focusedwidgetbefore,ffocusedwidget); + if (appinst.factivewindow = self) and + (focuscount = focuscountbefore) then begin + appinst.fonwidgetactivechangelist.dowidgetchange( + focusedwidgetbefore,ffocusedwidget); + end; + finally + if widget <> nil then begin + dec(ffocusing); + end; + setlinkedvar(nil,tmsecomponent(focusedwidgetbefore)); + end; + end; +end; + +procedure twindow.invalidaterect(const arect: rectty; + const sender: twidget = nil); +var + rect1: rectty; +begin + if (arect.cx > 0) or (arect.cy > 0) then begin + rect1:= intersectrect(arect,mr(nullpoint,fownerwidget.fwidgetrect.size)); + if (sender <> nil) and (sender.fparentwidget <> nil) then begin + rect1:= intersectrect(rect1,moverect(sender.fparentwidget.paintrect, + sender.fparentwidget.rootpos)); + end; + if fupdateregion.region = 0 then begin + fupdateregion:= createregion(rect1,fgdi); + end + else begin + regaddrect(fupdateregion,rect1); + end; + if appinst <> nil then begin + appinst.invalidated; + end; + end; +end; + +procedure twindow.doshortcut(var info: keyeventinfoty; const sender: twidget); +begin + if not (es_broadcast in info.eventstate) then begin + if not (es_processed in info.eventstate) then begin + if fmodallevel > 0 then begin + include(info.eventstate,es_modal); + end; + try + include(info.eventstate,es_local); + try + appinst.fonshortcutlist.dokeyevent(sender,info); + finally + exclude(info.eventstate,es_local); + end; + if not (es_processed in info.eventstate) and + not (tws_localshortcuts in fstate) then begin + appinst.checkshortcut(self,sender,info); + end; + finally + exclude(info.eventstate,es_modal); + end; + end; + end + else begin + if tws_globalshortcuts in fstate then begin + fcaller:= nil; + fownerwidget.doshortcut(info,nil); + end; + end; +end; + +procedure twindow.gcneeded(const sender: tcanvas); +begin + createwindow; +end; +{ +function twindow.getmonochrome: boolean; +begin + result:= false; +end; +} +function twindow.getkind: bitmapkindty; +begin + result:= bmk_rgb; +end; + +procedure twindow.update; +var + int1: integer; + event: twindowrectevent; +begin + if appinst <> nil then begin + if appinst.ismainthread() then begin //avoid possible deadlock in getevents() + gui_flushgdi; + appinst.getevents; + for int1:= 0 to appinst.eventlist.count - 1 do begin + event:= twindowrectevent(appinst.eventlist[int1]); + if (event <> nil) and (event.kind = ek_expose) and + (event.fwinid = fwindow.id) then begin + invalidaterect(event.frect); + appinst.eventlist[int1]:= nil; + event.free1; + end; + end; + end; + internalupdate; + gui_flushgdi; + end; +end; + +procedure twindow.movewindowrect(const dist: pointty; const rect: rectty); +begin + tcanvas1(fcanvas).movewindowrect(dist,rect); +// gui_movewindowrect(fwindow.id,dist,rect); +end; + +function twindow.getsize: sizety; +begin + result:= fownerwidget.getsize; +end; + +function twindow.close: boolean; +begin + if fmodalresult = mr_none then begin + fmodalresult:= mr_windowclosed; + end; + fownerwidget.beforeclosequery(fmodalresult); + result:= (fmodalresult <> mr_none) and fownerwidget.canparentclose(nil); + if result then begin + deactivate; + fownerwidget.hide; + destroywindow; + end + else begin + fmodalresult:= mr_none; + end; +end; + +procedure twindow.bringtofront(); +var + int1: integer; +begin +{$ifdef mse_debugzorder} + debugwriteln('****bringtofront**** "'+fownerwidget.name+'"'); +{$endif} + with appinst do begin + for int1:= high(fwindowstack) downto 0 do begin + if fwindowstack[int1].lower = self then begin + deleteitem(fwindowstack,typeinfo(windowstackinfoarty),int1); + end; + end; + gui_raisewindow(winid,wo_popup in self.foptions); + include(fstate,aps_needsupdatewindowstack); + end; +end; + +procedure twindow.sendtoback(); +var + int1: integer; +begin +{$ifdef mse_debugzorder} + debugwriteln('****sendtoback**** "'+fownerwidget.name+'"'); +{$endif} + with appinst do begin + for int1:= high(fwindowstack) downto 0 do begin + if fwindowstack[int1].upper = self then begin + deleteitem(fwindowstack,typeinfo(windowstackinfoarty),int1); + end; + end; + gui_lowerwindow(winid); + include(fstate,aps_needsupdatewindowstack); + end; +end; + +procedure twindow.bringtofrontlocal; +begin +{$ifdef mse_debugzorder} + debugwriteln('****bringtofrontlocal**** "'+fownerwidget.name+'"'); +{$endif} + include(fstate,tws_raise); + exclude(fstate,tws_lower); + include(appinst.fstate,aps_needsupdatewindowstack); +end; + +procedure twindow.sendtobacklocal; +begin +{$ifdef mse_debugzorder} + debugwriteln('****sendtobacklocal**** "'+fownerwidget.name+'"'); +{$endif} + include(fstate,tws_lower); + exclude(fstate,tws_raise); + include(appinst.fstate,aps_needsupdatewindowstack); +end; + +procedure twindow.stackunder(const predecessor: twindow); +begin + if (predecessor <> self) then begin + appinst.stackunder(self,predecessor); + include(appinst.fstate,aps_needsupdatewindowstack); + end; +end; + +procedure twindow.stackover(const predecessor: twindow); +var + ar1: windowarty; +begin + ar1:= nil; //compiler warning + if predecessor = nil then begin + appinst.sortzorder; + ar1:= appinst.windowar; + if high(ar1) >= 0 then begin + stackunder(ar1[0]); + end; + end + else begin + if (predecessor <> self) and (predecessor <> nil) then begin + appinst.stackover(self,predecessor); + include(appinst.fstate,aps_needsupdatewindowstack); + end; + end; +end; + +function twindow.stackedover(const avisible: boolean = false): twindow; //nil if top +var + ar1: windowarty; + int1,int2: integer; +begin + appinst.sortzorder; + ar1:= appinst.windowar; + result:= nil; + int2:= -1; + for int1:= high(ar1) downto 1 do begin + if ar1[int1] = self then begin + int2:= int1-1; + break; + end; + end; + if int2 >= 0 then begin + if avisible then begin + for int1:= int2 downto 0 do begin + if ar1[int1].visible then begin + result:= ar1[int1]; + break; + end; + end; + end + else begin + result:= ar1[int2]; + end; + end; +end; + +function twindow.stackedunder(const avisible: boolean = false): twindow; + //nil if bottom +var + ar1: windowarty; + int1,int2: integer; +begin + appinst.sortzorder; + ar1:= appinst.windowar; + result:= nil; + int2:= -1; + for int1:= 0 to high(ar1)-1 do begin + if ar1[int1] = self then begin + int2:= int1+1; + break; + end; + end; + if int2 >= 0 then begin + if avisible then begin + for int1:= int2 to high(ar1) do begin + if ar1[int1].visible then begin + result:= ar1[int1]; + break; + end; + end; + end + else begin + result:= ar1[int2]; + end; + end; +end; + +function twindow.hastransientfor: boolean; +begin + result:= ftransientforcount > 0; +end; + +function twindow.istransientfor(const base: twindow): boolean; +var + w1: twindow; +begin + result:= ftransientfor <> nil; + if result and (base <> nil) then begin + w1:= ftransientfor; + while w1 <> nil do begin + if w1 = base then begin + exit; + end; + w1:= w1.ftransientfor; + end; + result:= false; + end; +end; + +function twindow.capturemouse: boolean; +begin + result:= not (tws_grab in fstate); + if appinst.grabpointer(winid) then begin + include(fstate,tws_grab); + end; +end; + +procedure twindow.releasemouse; +begin + if tws_grab in fstate then begin + exclude(fstate,tws_grab); + appinst.ungrabpointer; + end; +end; + +function twindow.mousecaptured: boolean; +begin + result:= tws_grab in fstate; +end; + +procedure twindow.checkrecursivetransientfor(const value: twindow); +var + window1: twindow; +begin + window1:= value; + while window1 <> nil do begin + if window1 = self then begin + guierror(gue_recursivetransientfor); + end; + window1:= window1.ftransientfor; + end; +end; + +procedure twindow.settransientfor(const Value: twindow; + const windowevent: boolean); +begin + if not windowevent then begin + if value = nil then begin + exclude(fstate,tws_modalfor); + end; + if ftransientfor <> value then begin + checkrecursivetransientfor(value); + if ftransientfor <> nil then begin + dec(ftransientfor.ftransientforcount); + end; + setlinkedvar(value,tlinkedobject(ftransientfor)); + if ftransientfor <> nil then begin + inc(ftransientfor.ftransientforcount); + end; + include(appinst.fstate,aps_needsupdatewindowstack); + if fwindow.id <> 0 then begin + if value <> nil then begin + gui_settransientfor(fwindow,value.winid); + end + else begin + gui_settransientfor(fwindow,0); + end; + end; + end; + end; +end; + +function twindow.winid: winidty; +begin + checkwindowid; + result:= fwindow.id; +end; + +procedure twindow.hidden; +begin + if tws_windowvisible in fstate then begin + fownerwidget.internalhide(true); + end; +end; + +procedure twindow.showed; +var + wi1: twindow; +begin + exclude(fstate,tws_windowshowpending); + if not (tws_windowvisible in fstate) then begin + wi1:= nil; + fownerwidget.internalshow(ml_none,@wi1,true,true); + end; +end; + +procedure twindow.activated; +begin + internalactivate(true); +end; + +procedure twindow.deactivated; +begin + deactivate; +end; + +function twindow.canactivate: boolean; +begin + result:= (appinst <> nil) and (appinst.fmodalwindow = nil) or + (appinst.fmodalwindow = self); +end; + +procedure twindow.activate(const force: boolean = false); +begin + if fownerwidget.visible and (force or not active) and + not (tws_focusoutpending in fstate)then begin + internalactivate(false); + end; +end; + +function twindow.active: boolean; +begin + result:= appinst.factivewindow = self; +end; + +procedure twindow.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + if fwindow.id <> 0 then begin + gui_setwindowcaption(fwindow.id,fcaption); + end; +end; + +procedure twindow.widgetdestroyed(widget: twidget); +var + widget1: twidget; +begin + if fmodalwidget = widget then begin + fmodalwidget:= nil; + end; + if ffocusedwidget = widget then begin + widget1:= widget; + repeat + widget1:= widget1.parentwidget; + until (widget1 = nil) or widget1.canfocus; + setfocusedwidget(widget1); + end; +end; + +function twindow.state: windowstatesty; +begin + result:= fstate; +end; + +procedure twindow.registermovenotification(sender: iobjectlink); +begin + getobjectlinker.link(iobjectlink(self),sender); +end; + +procedure twindow.unregistermovenotification(sender: iobjectlink); +begin + if (self <> nil) and (fobjectlinker <> nil) then begin + fobjectlinker.unlink(iobjectlink(self),sender); + end; +end; + +function twindow.close(const amodalresult: modalresultty): boolean; + //true if ok +begin + fmodalresult:= amodalresult; + result:= false; + if (amodalresult <> mr_none) {and (tws_modal in fstate)} then begin + result:= close(); + end; +end; + +procedure twindow.setmodalresult(const Value: modalresultty); +begin + fmodalresult:= Value; + if (value <> mr_none) {and (tws_modal in fstate)} then begin + close(); + end; +end; + +function twindow.candefocus: boolean; +var + b1: boolean; +begin + b1:= tws_candefocus in fstate; + include(fstate,tws_candefocus); + try + result:= (ffocusedwidget = nil) or ffocusedwidget.canclose(nil); + finally; + if not b1 then begin + exclude(fstate,tws_candefocus); + end; + end; +end; + +procedure twindow.nofocus; +begin + setfocusedwidget(nil); +end; + +function twindow.getglobalshortcuts: boolean; +begin + result:= tws_globalshortcuts in fstate; +end; + +procedure twindow.setglobalshortcuts(const Value: boolean); +begin + updatebit({$ifdef FPC}longword{$else} + longword{$endif}(fstate),ord(tws_globalshortcuts),value); +end; + +function twindow.getlocalshortcuts: boolean; +begin + result:= tws_localshortcuts in fstate; +end; + +procedure twindow.setlocalshortcuts(const Value: boolean); +begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(tws_localshortcuts),value); +end; + +function twindow.visible: boolean; +begin + result:= fownerwidget.visible and (tws_windowvisible in fstate) and + (fwindow.id <> 0) and (gui_getwindowsize(fwindow.id) <> wsi_minimized); +end; + +function twindow.normalwindowrect: rectty; +begin + result:= fnormalwindowrect; +end; + +function twindow.getbuttonendmodal: boolean; +begin + result:= tws_buttonendmodal in fstate; +end; + +procedure twindow.setbuttonendmodal(const value: boolean); +begin + if value then begin + include(fstate,tws_buttonendmodal); + end + else begin + exclude(fstate,tws_buttonendmodal); + end; +end; + +procedure twindow.setzorder(const value: integer); +begin + if value = 0 then begin //!!!!todo + gui_lowerwindow(winid); + end + else begin + gui_raisewindow(winid); + end; +end; + +function twindow.getwindowsize: windowsizety; +begin + result:= gui_getwindowsize(winid); +end; + +procedure twindow.setwindowsize(const value: windowsizety); +begin + gui_setwindowstate(winid,value,true); +end; + +function twindow.getwindowpos: windowposty; +var + asize: windowsizety; +begin + if fwindow.id = 0 then begin + result:= fwindowpos; + end + else begin + inc(fmoving); + asize:= gui_getwindowsize(winid); + dec(fmoving); + case asize of + wsi_minimized: begin + result:= wp_minimized; + end; + wsi_maximized: begin + result:= wp_maximized; + end; + wsi_fullscreen: begin + result:= wp_fullscreen; + end; + wsi_fullscreenvirt: begin + result:= wp_fullscreenvirt; + end; + else begin //wsi_normal + if fwindowpos in [wp_minimized,wp_screencentered, + wp_transientforcentered,wp_mainwindowcentered] + + windowmaximizedstates then begin + result:= wp_normal; + end + else begin + result:= fwindowpos; + end; + end; + end; + end; +end; + +procedure twindow.setwindowpos(const Value: windowposty); +var + rect1,rect2: rectty; + bo1: boolean; + wpo1: windowposty; + window1: twindow; +begin + wpo1:= getwindowpos; + if wpo1 <> value then begin + bo1:= (tws_windowvisible in fstate) or (wpo1 = wp_minimized); + window1:= nil; + if value in [wp_screencentered, + wp_transientforcentered,wp_mainwindowcentered] then begin + window1:= nil; + if value = wp_mainwindowcentered then begin + window1:= application.mainwindow; + end; + if window1 = nil then begin + window1:= transientfor; + if window1 = nil then begin + window1:= appinst.activewindow; + if window1 = nil then begin + window1:= self; + end; + end; + end; + end; + case value of + wp_screencentered,wp_screencenteredvirt, + wp_transientforcentered,wp_mainwindowcentered: begin + checkwindowid(); + rect1:= fnormalwindowrect; + gui_setwindowstate(winid,wsi_normal,bo1); + case value of + wp_screencenteredvirt: begin + rect2:= appinst.screenrect(nil); + end; + wp_screencentered: begin + rect2:= appinst.workarea(window1); + end; + else begin + rect2:= window1.fownerwidget.widgetrect; + end; + end; + with fownerwidget do begin + rect1.x:= rect2.x + (rect2.cx - rect1.cx) div 2; + rect1.y:= rect2.y + (rect2.cy - rect1.cy) div 2; + widgetrect:= rect1; + end; + end; + wp_minimized: begin + gui_setwindowstate(winid,wsi_minimized,bo1); + end; + wp_maximized: begin + gui_setwindowstate(winid,wsi_maximized,bo1); + end; + wp_fullscreen: begin + gui_setwindowstate(winid,wsi_fullscreen,bo1); + end; + wp_fullscreenvirt: begin + gui_setwindowstate(winid,wsi_fullscreenvirt,bo1); + end + else begin + gui_setwindowstate(winid,wsi_normal,bo1); + end; + end; + end; + fwindowpos:= value; + fwindowposbefore:= fwindowpos; + if (wpo1 in [wp_fullscreen,wp_fullscreenvirt]) and + (value = wp_normal) then begin + gui_reposwindow(fwindow.id,fnormalwindowrect); + //needed for win32 + end; +end; + +function twindow.updaterect: rectty; +begin + result:= fcanvas.regionclipbox(fupdateregion.region); +end; + +function twindow.defaulttransientfor: twindow; +begin + result:= nil; + if appinst.fmodalwindow = nil then begin + if appinst.fwantedactivewindow <> nil then begin + result:= appinst.fwantedactivewindow; + end + else begin + result:= appinst.factivewindow; + end; + end + else begin + result:= appinst.fmodalwindow; + end; + if result = self then begin + result:= nil; + end; +end; + +function twindow.ispopup: boolean; +begin + result:= wo_popup in foptions; +end; + +function twindow.firstfocuswidget(): twidget; +var + w1,w2: twidget; + i1,i2: int32; +begin + result:= fownerwidget; + if result.canfocus then begin + while ow_subfocus in result.optionswidget do begin + w2:= nil; + i2:= bigint; + for i1:= 0 to high(result.fwidgets) do begin + w1:= result.fwidgets[i1]; + if (w1.ftaborder < i2) and w1.canfocus then begin + w2:= w1; + i2:= w1.ftaborder; + end; + end; + if w2 = nil then begin + break; + end; + result:= w2; + end; + end; +end; + +function twindow.lastfocuswidget(): twidget; +var + w1,w2: twidget; + i1,i2: int32; +begin + result:= fownerwidget; + if result.canfocus then begin + while ow_subfocus in result.optionswidget do begin + w2:= nil; + i2:= -1; + for i1:= high(result.fwidgets) downto 0 do begin + w1:= result.fwidgets[i1]; + if (w1.ftaborder > i2) and w1.canfocus then begin + w2:= w1; + i2:= w1.ftaborder; + end; + end; + if w2 = nil then begin + break; + end; + result:= w2; + end; + end; +end; + +procedure twindow.postkeyevent(const akey: keyty; + const ashiftstate: shiftstatesty = []; const release: boolean = false; + const achars: msestring = ''); +begin + application.postevent(tkeyevent.create(winid,release,akey,akey, + ashiftstate,achars,timestamp,true)); +end; + +procedure twindow.beginmoving; +begin + inc(fmoving); +end; + +procedure twindow.endmoving; +begin + dec(fmoving); + if fmoving = 0 then begin + checkwindow(false); + end; +end; + +procedure twindow.registeronscroll(const method: notifyeventty); +begin + fscrollnotifylist.add(tmethod(method)); +end; + +procedure twindow.unregisteronscroll(const method: notifyeventty); +begin + fscrollnotifylist.remove(tmethod(method)); +end; + +function twindow.getdecoratedwidgetrect: rectty; +begin + guierror(gui_getdecoratedwindowrect(winid,result)); +end; + +procedure twindow.setdecoratedwidgetrect(const avalue: rectty); +var + rect1: rectty; +begin + guierror(gui_setdecoratedwindowrect(winid,avalue,rect1)); +end; + +function twindow.getdecoratedpos: pointty; +begin + result:= decoratedwidgetrect.pos; +end; + +procedure twindow.setdecoratedpos(const avalue: pointty); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.pos:= avalue; + decoratedwidgetrect:= rect1; +end; + +function twindow.getdecoratedsize: sizety; +begin + result:= decoratedwidgetrect.size; +end; + +procedure twindow.setdecoratedsize(const avalue: sizety); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.size:= avalue; + decoratedwidgetrect:= rect1; +end; + +function twindow.getdecoratedbounds_x: integer; +begin + result:= decoratedwidgetrect.x; +end; + +procedure twindow.setdecoratedbounds_x(const avalue: integer); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.x:= avalue; + decoratedwidgetrect:= rect1; +end; + +function twindow.getdecoratedbounds_y: integer; +begin + result:= decoratedwidgetrect.y; +end; + +procedure twindow.setdecoratedbounds_y(const avalue: integer); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.y:= avalue; + decoratedwidgetrect:= rect1; +end; + +function twindow.getdecoratedbounds_cx: integer; +begin + result:= decoratedwidgetrect.cx; +end; + +procedure twindow.setdecoratedbounds_cx(const avalue: integer); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.cx:= avalue; + decoratedwidgetrect:= rect1; +end; + +function twindow.getdecoratedbounds_cy: integer; +begin + result:= decoratedwidgetrect.cy; +end; + +procedure twindow.setdecoratedbounds_cy(const avalue: integer); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.cy:= avalue; + decoratedwidgetrect:= rect1; +end; + +procedure twindow.setcontainer(const avalue: winidty); +begin + syscontainer:= sywi_none; + if fcontainer <> 0 then begin + application.unregisteronwiniddestroyed({$ifdef FPC}@{$endif}containerwindestroyed); + end; + fcontainer:= avalue; + if fcontainer <> 0 then begin + application.registeronwiniddestroyed({$ifdef FPC}@{$endif}containerwindestroyed); + try + include(foptions,wo_embedded); + guierror(gui_reparentwindow(winid,fcontainer,fownerwidget.pos)); + except + container:= 0; + raise; + end; + end + else begin + exclude(foptions,wo_embedded); + if (fwindow.id <> 0) and not (tws_destroying in fstate) then begin + guierror(gui_reparentwindow(winid,0,fownerwidget.pos)); + end; + end; +end; + +procedure twindow.containerwindestroyed(const aid: winidty); +begin + if aid = fcontainer then begin + container:= 0; + end; +end; + +procedure twindow.setsyscontainer(const avalue: syswindowty); +begin + if avalue <> fsyscontainer then begin + if (fsyscontainer <> sywi_none) and (fwindow.id <> 0) then begin + {$ifdef mswindows} + gui_docktosyswindow(fwindow,sywi_none); + {$else} + destroywindow(); //above code does not work with newer wm's + {$endif} + fsyscontainer:= sywi_none; + container:= 0; + if not (tws_destroying in fstate) then begin + {$ifndef mswindows} + createwindow(); + {$endif} + if avalue = sywi_none then begin + if fownerwidget.visible then begin + gui_showwindow(winid); + end; + end; + end; + end; + if avalue <> sywi_none then begin + if fwindow.id = 0 then begin + createwindow; + end; + include(foptions,wo_embedded); + guierror(gui_docktosyswindow(fwindow,avalue)); + fsyscontainer:= avalue; + end; + end; +end; + +function twindow.getscreenpos: pointty; +var + rect1: rectty; +begin + if not (wo_embedded in foptions) then begin + result:= fownerwidget.pos; + end + else begin + guierror(gui_getwindowrect(winid,rect1)); + result:= rect1.pos; + end; +end; + +procedure twindow.setscreenpos(const avalue: pointty); +var + pt1: pointty; +begin + if not (wo_embedded in foptions) then begin + fownerwidget.pos:= avalue; + end + else begin + pt1:= screenpos; + pt1.x:= avalue.x - pt1.x + fownerwidget.bounds_x; + pt1.y:= avalue.y - pt1.y + fownerwidget.bounds_y; + fownerwidget.pos:= pt1; + end; +end; + +function twindow.modal: boolean; +begin + result:= fmodallevel > 0; +end; + +function twindow.modalwindowbefore: twindow; +begin + result:= nil; + if fmodalinfopo <> nil then begin + result:= fmodalinfopo^.modalwindowbefore; + end; +end; + +function twindow.getmodalfor: boolean; +begin + result:= tws_modalfor in fstate; +end; + +procedure twindow.setopacity(const avalue: realty); +begin + if fopacity <> avalue then begin + fopacity:= avalue; + if fwindow.id <> 0 then begin + gui_setwindowopacity(fwindow.id,fopacity); + end; + end; +end; + +function twindow.topmodaltransientfor: twindow; +var + int1: integer; + window1,window2: twindow; +begin + result:= nil; + with appinst do begin + window1:= self; + while (window1 <> nil) and window1.hastransientfor do begin + window2:= nil; + for int1:= 0 to high(fwindows) do begin + if fwindows[int1].ftransientfor = window1 then begin + window2:= fwindows[int1]; + if tws_modalfor in window2.fstate then begin + result:= window2; + end; + if window2 = self then begin + window2:= nil; //recursion + end; + break; + end; + end; + window1:= window2; + end; + end; +end; + +function twindow.transientforstackactive: boolean; +var + window1,window2: twindow; +begin + result:= false; + window1:= appinst.activewindow; + window2:= window1; + if (window1 <> nil) and (window1.ftransientfor <> nil) then begin + while window1 <> nil do begin + if window1 = self then begin + result:= true; + break; + end; + window1:= window1.ftransientfor; + end; + end; + if ftransientfor <> nil then begin + window1:= self; + while window1 <> nil do begin + if window1 = window2 then begin + result:= true; + break; + end; + window1:= window1.ftransientfor; + end; + end; +end; + +procedure twindow.getcanvasimage(const bgr: boolean; var aimage: maskedimagety); +begin + //dummy +end; + +procedure twindow.processsysdnd(const event: twindowevent); +var + wi1: twidget; +// obj1: tsysmimedragobject; + info: draginfoty; + bo1: boolean; +begin + if wo_sysdnd in foptions then begin + with tsysdndevent(event) do begin + if fdndkind = dek_leavesysdnd then begin + freeandnil(fsysdragobject); + end + else begin + subpoint1(fpos,fownerwidget.pos); + wi1:= fownerwidget.widgetatpos(fpos,[ws_visible,ws_enabled]); + if (wi1 = nil) and + (fownerwidget.fwidgetstate*[ws_visible,ws_enabled] = + [ws_visible,ws_enabled]) then begin + wi1:= fownerwidget; + end; + if wi1 <> nil then begin + if fsysdragobject = nil then begin + tsysmimedragobject.create(nil,tdragobject(fsysdragobject),nullpoint, + fformats,fformatistext,factions); + end; + with tsysmimedragobject1(fsysdragobject) do begin + if (fformats <> tsysdndevent(event).fformats) or + (fformatistext <> tsysdndevent(event).fformatistext) or + (fformatindex > high(fformats)) then begin + //missed dek_leave + fformats:= tsysdndevent(event).fformats; + fformatistext:= tsysdndevent(event).fformatistext; + fformatindex:= -1; + end; + factions:= tsysdndevent(event).factions; + end; + fillchar(info,sizeof(info),0); + with info do begin + eventkind:= fdndkind; + pos:= translateclientpoint(fpos,owner,wi1); + dragobjectpo:= @fsysdragobject; + end; + try + wi1.dragevent(info); + finally + if fdndkind = dek_drop then begin + gui_sysdnd(sdnda_finished,isysdnd(tsysmimedragobject(fsysdragobject)), + nullrect,bo1); + end + else begin + if info.accept then begin + gui_sysdnd(sdnda_accept,isysdnd(tsysmimedragobject(fsysdragobject)) + ,nullrect,bo1); + end + else begin + gui_sysdnd(sdnda_reject,isysdnd(tsysmimedragobject(fsysdragobject)), + nullrect,bo1); + end; + end; + // obj1.free; + end; + end; + end; + end; + end; +end; + +{ tonkeyeventlist} + +procedure tonkeyeventlist.dokeyevent(const sender: twidget; var info: keyeventinfoty); +begin + factitem:= 0; + while factitem < fcount do begin + if es_processed in info.eventstate then begin + break; + end; + keyeventty(getitempo(factitem)^)(sender,info); + inc(factitem); + end; +end; + +{ tonwidgetchangelist} + +procedure tonwidgetchangelist.dowidgetchange(const oldwidget,newwidget: twidget); +begin + factitem:= 0; + while factitem < fcount do begin + widgetchangeeventty(getitempo(factitem)^)(oldwidget,newwidget); + inc(factitem); + end; +end; + +{ tonwindowchangelist} + +procedure tonwindowchangelist.dowindowchange(const oldwindow,newwindow: twindow); +begin + factitem:= 0; + while factitem < fcount do begin + windowchangeeventty(getitempo(factitem)^)(oldwindow,newwindow); + inc(factitem); + end; +end; + + {tonwindoweventlist} + +procedure tonwindoweventlist.doevent(const awindow: twindow); +begin + factitem:= 0; + while factitem < fcount do begin + windoweventty(getitempo(factitem)^)(awindow); + inc(factitem); + end; +end; + + {tonwinideventlist} + +procedure tonwinideventlist.doevent(const awinid: winidty); +begin + factitem:= 0; + while factitem < fcount do begin + winideventty(getitempo(factitem)^)(awinid); + inc(factitem); + end; +end; + +{ tonapplicationactivechangedlist } + +procedure tonapplicationactivechangedlist.doevent(const activated: boolean); +begin + factitem:= 0; + while factitem < fcount do begin + booleaneventty(getitempo(factitem)^)(activated); + inc(factitem); + end; +end; + +{ tonhelpeventlist } + +procedure tonhelpeventlist.doevent (const sender: tmsecomponent); +var + bo1: boolean; +begin + factitem:= 0; + bo1:= false; + while (factitem < fcount) and not bo1 do begin + helpeventty(getitempo(factitem)^)(sender,bo1); + inc(factitem); + end; +end; + +{ tonsyseventlist } + +procedure tonsyseventlist.doevent(const awindow: winidty; + var aevent: syseventty; var handled: boolean); +//var +// bo1: boolean; +begin + factitem:= 0; + while (factitem < fcount) and not handled do begin + syseventhandlereventty(getitempo(factitem)^)(awindow,aevent,handled); + inc(factitem); + end; +end; + +{ twindowevent } + +constructor twindowevent.create(akind: eventkindty; winid: winidty); +begin + inherited create(akind); + fwinid:= winid; +end; + +{ twindowrectevent } + +constructor twindowrectevent.create(akind: eventkindty; winid: winidty; + const rect: rectty; const aorigin: pointty); +begin + inherited create(akind,winid); + frect:= rect; + forigin:= aorigin; +end; + +{ tmouseevent } + +constructor tmouseevent.create(const winid: winidty; const release: boolean; + const button: mousebuttonty; const wheel: mousewheelty; + const pos: pointty; const shiftstate: shiftstatesty; + atimestamp: longword; const reflected: boolean = false); +var + eventkind1: eventkindty; +begin + if (atimestamp = 0) and (button <> mb_none) then begin + inc(atimestamp); + end; + ftimestamp:= atimestamp; + if wheel = mw_none then begin + if button = mb_none then begin + eventkind1:= ek_mousemove; + end + else begin + if release then begin + eventkind1:= ek_buttonrelease; + end + else begin + eventkind1:= ek_buttonpress; + end; + end; + end + else begin + eventkind1:= ek_mousewheel; + end; + inherited create(eventkind1,winid); + fbutton:= button; + fwheel:= wheel; + fpos:= pos; + fshiftstate:= shiftstate; + freflected:= reflected; +end; + +{ tkeyevent } + +constructor tkeyevent.create(const winid: winidty; const release: boolean; + const key,keynomod: keyty; const shiftstate: shiftstatesty; + const chars: msestring; const atimestamp: longword; + const posted: boolean = false); +var + eventkind1: eventkindty; +begin + if release then begin + eventkind1:= ek_keyrelease; + end + else begin + eventkind1:= ek_keypress; + end; + inherited create(eventkind1,winid); + fkeynomod:= keynomod; + fkey:= key; + fchars:= chars; + fshiftstate:= shiftstate; + ftimestamp:= atimestamp; + fposted:= posted; +end; + +{ tinternalapplication } + +constructor tinternalapplication.create(aowner: tcomponent); +begin + appinst:= self; +// inherited; + fdblclicktime:= defaultdblclicktime; +// inherited; + fonkeypresslist:= tonkeyeventlist.create; + fonshortcutlist:= tonkeyeventlist.create; + fonwidgetactivechangelist:= tonwidgetchangelist.create; + fonwindowactivechangelist:= tonwindowchangelist.create; + fonwindowdestroyedlist:= tonwindoweventlist.create; + fonwiniddestroyedlist:= tonwinideventlist.create; + fonapplicationactivechangedlist:= tonapplicationactivechangedlist.create; + fonhelp:= tonhelpeventlist.create; + fonsyseventlist:= tonsyseventlist.create; +// fwindows:= tpointerlist.create; + fcaret:= tcaret.create; + fmouse:= tmouse.create(imouse(self)); + fhinttimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}hinttimer, + false,[to_single]); + fmouseparktimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}mouseparktimer, + false,[to_single]); + inherited; +// initialize; +end; + +destructor tinternalapplication.destroy; +begin + destroyforms; + fmouseparktimer.free; + fhinttimer.free; + fhintwidget.free; + freeandnil(fcaret); + fmouse.free; +// deinitialize; + inherited; +// fwindows.free; + fonkeypresslist.free; + fonshortcutlist.free; + fonwidgetactivechangelist.free; + fonwindowactivechangelist.free; + fonwindowdestroyedlist.free; + fonwiniddestroyedlist.free; + fonapplicationactivechangedlist.free; + fonhelp.free; + fonsyseventlist.free; +end; + +procedure tinternalapplication.twindowdestroyed(const sender: twindow); +var + int1: integer; +begin + fonwindowdestroyedlist.doevent(sender); + for int1:= high(fwindowstack) downto 0 do begin + with fwindowstack[int1] do begin + if (lower = sender) or (upper = sender) then begin + deleteitem(fwindowstack,typeinfo(windowstackinfoarty),int1); +// lower:= nil; + end; + end; + end; + for int1:= high(fgroupzorder) downto 0 do begin + if fgroupzorder[int1] = sender then begin + deleteitem(pointerarty(fgroupzorder),int1); + end; + end; + if factivewindow = sender then begin + factivewindow:= nil; + end; + if flastactivewindow = sender then begin + flastactivewindow:= nil; + end; + if finactivewindow = sender then begin + finactivewindow:= nil; + end; + if fwantedactivewindow = sender then begin + fwantedactivewindow:= nil; + end; + if factmousewindow = sender then begin + factmousewindow:= nil; + end; + if fmainwindow = sender then begin + fmainwindow:= nil; + end; + if ffocuslockwindow = sender then begin + ffocuslockwindow:= nil; + end; + if ffocuslocktransientfor = sender then begin + ffocuslockwindow:= nil; + end; + if flockupdatewindowstack = sender then begin + flockupdatewindowstack:= nil; + end; +end; + +function tinternalapplication.getmousewinid: winidty; +begin + result:= fmousewinid; + if (result <> 0) then begin + exit; + end; + if fmousecapturewidget <> nil then begin +// result:= fmousecapturewidget.window.winid; + result:= fmousecapturewidget.window.fwindow.id; + //do not trigger checkwindow, there could be a pending + //configure event + exit; + end; + if activewindow <> nil then begin + result:= activewindow.fwindow.id; + exit; + end; + if (mainwindow <> nil) and (mainwindow.visible) then begin + result:= mainwindow.fwindow.id; + exit; + end; +end; + +procedure tinternalapplication.processexposeevent(event: twindowrectevent); +var + window: twindow; + parentid: winidty; + pt1: pointty; +begin + with event do begin + if findwindow(fwinid,window) then begin + window.invalidaterect(frect); + end + else begin + if not winiddestroyed(fwinid) then begin + parentid:= gui_getparentwindow(fwinid); //embedded or destroyed window + if parentid <> 0 then begin + if findwindow(parentid,window) and + (gui_getwindowpos(fwinid,pt1) = gue_ok) then begin + addpoint1(frect.pos,pt1); + window.invalidaterect(frect); + end; + end; + end; + end; + end; +end; + +procedure tinternalapplication.processshowingevent(event: twindowevent); +var + window: twindow; +begin + if findwindow(event.fwinid,window) then begin + if event.kind = ek_show then begin + if window.windowpos in windowmaximizedstates then begin + window.fstate:= window.fstate + [tws_posvalid,tws_sizevalid]; + //do not override changing to normal state by window manager + end; + window.showed; + end + else begin + window.hidden; + end; + end; +end; + +procedure tinternalapplication.processconfigureevent(event: twindowrectevent); +var + window: twindow; +begin + with event do begin + if findwindow(fwinid,window) then begin + window.wmconfigured(frect,forigin); + end; + end; +end; + +procedure tinternalapplication.processleavewindow; +begin + fmouseparktimer.enabled:= false; + factmousewindow:= nil; + if fmousecapturewidget = nil then begin + setmousewidget(nil); + widgetcursorshape:= cr_default; + fhintedwidget:= nil; +// cursorshape:= cr_default; + end + else begin + if (fclientmousewidget <> nil) and + not (ws_clientmousecaptured in fclientmousewidget.fwidgetstate) then begin + setclientmousewidget(nil,nullpoint); + end; + end; + fmousewinid:= 0; +end; + +procedure tinternalapplication.processwindowcrossingevent(event: twindowevent); +var + window: twindow; +// info: mouseeventinfoty; +begin + if findwindow(event.fwinid,window) then begin + if event.kind = ek_leavewindow then begin + processleavewindow; + end + else begin + fmousewinid:= event.fwinid; + end; + end; +end; + +procedure tinternalapplication.mouseparktimer(const sender: tobject); +begin + if (factmousewindow <> nil) and ((fmodalwindow = nil) or + (fmodalwindow = factmousewindow)) then begin + factmousewindow.mouseparked; + end; +end; + +procedure tinternalapplication.processmouseevent(event: tmouseevent); +var + window,window1: twindow; + info: moeventinfoty; + shift: shiftstatesty; + abspos: pointty; + int1: integer; + bo1: boolean; + widget1: twidget; + pt1: pointty; + hintid1: int32; +begin + try + with event do begin + if findwindow(fwinid,window) then begin + if window.hastransientfor then begin + window1:= window.topmodaltransientfor; + if window1 <> nil then begin + fpos.x:= fpos.x + window.fownerwidget.bounds_x - + window1.fownerwidget.bounds_x; + fpos.y:= fpos.y + window.fownerwidget.bounds_y - + window1.fownerwidget.bounds_y; + window:= window1; + end; + end; + fillchar(info,sizeof(info),0); + with info.mouse do begin + timestamp:= ftimestamp; + serial:= application.getserial(); + if freflected then begin + include(eventstate,es_reflected); + end; + if kind = ek_enterwindow then begin + eventkind:= ek_mousemove; + end + else begin + eventkind:= kind; + end; + shift:= []; + if kind = ek_mousewheel then begin + fmousewheeleventinfo:= @info; + info.wheel.wheel:= fwheel; + calcmousewheeldelta(info.wheel,fmousewheelfrequmin,fmousewheelfrequmax, + fmousewheeldeltamin,fmousewheeldeltamax); + if ftimestamp <> 0 then begin + flastmousewheeltimestampbefore:= flastmousewheeltimestamp; + flastmousewheeltimestamp:= ftimestamp; + end; + end + else begin + fmouseeventinfo:= @info; + button:= fbutton; + case button of + mb_left: shift:= [ss_left]; + mb_middle: shift:= [ss_middle]; + mb_right: shift:= [ss_right]; + end; + end; + if eventkind = ek_buttonpress then begin + shiftstate:= fshiftstate + shift; + end + else begin + shiftstate:= fshiftstate - shift; + end; + pos:= fpos; + abspos:= addpoint(window.fownerwidget.screenpos,pos); + // abspos:= addpoint(window.fownerwidget.fwidgetrect.pos,pos); + end; + + if (fmodalwindow <> nil) and (window <> fmodalwindow) and + not window.istransientfor(fmodalwindow) then begin + addpoint1(info.mouse.pos, + subpoint(window.screenpos,fmodalwindow.screenpos)); + window:= fmodalwindow; + end; + if (fmousecapturewidget <> nil) and + (fmousecapturewidget.window <> window) then begin + addpoint1(info.mouse.pos,subpoint(window.fownerwidget.fwidgetrect.pos, + fmousecapturewidget.fwindow.fownerwidget.fwidgetrect.pos)); + window:= fmousecapturewidget.fwindow; + end; + if (fmousecapturewidget = nil) and (aps_mousecaptured in fstate) and + (event.fshiftstate * mousebuttons = []) then begin + ungrabpointer; + end; + if (fhintwidget <> nil) and + (fhintinfo.flags*[{hfl_custom,}hfl_noautohidemove] = [{hfl_custom}]) and + ( + (info.mouse.eventkind = ek_buttonpress) or + (info.mouse.eventkind = ek_buttonrelease) or + (info.mouse.eventkind = ek_mousemove) and + (distance(fhintinfo.mouserefpos,abspos) > 3) + ) then begin + bo1:= window = fhintwidget.window; + deactivatehint; + if bo1 then begin + exit; //widow is destroyed + end; + end; + fmouseparkeventinfo:= info.mouse; + factmousewindow:= window; + fmouseparktimer.interval:= mouseparktime; + fmouseparktimer.enabled:= true; + if ftimestamp <> 0 then begin + if (fbutton <> mb_none) then begin + //test reflected event + if kind = ek_buttonpress then begin + if flastbuttonpresstimestamp = ftimestamp then begin + flastbuttonpresstimestamp:= ftimestampbefore; + end; + end + else begin + if kind = ek_buttonrelease then begin + if flastbuttonreleasetimestamp = ftimestamp then begin + flastbuttonreleasetimestamp:= ftimestampbefore; + end; + end; + end; + end; + if kind in [ek_buttonpress,ek_buttonrelease] then begin + int1:= bigint; + if (kind = ek_buttonpress) then begin + if (flastbuttonpresstimestamp <> 0) and (fbutton = flastbuttonpress) then begin + int1:= ftimestamp - flastbuttonpresstimestamp; + end; + end + else begin + if (flastbuttonreleasetimestamp <> 0) and + (fbutton = flastbuttonrelease) then begin + int1:= ftimestamp - flastbuttonreleasetimestamp; + end; + end; + if (int1 >= 0) and (int1 < fdblclicktime) then begin + include(info.mouse.shiftstate,ss_double); + if (kind = ek_buttonpress) then begin + if fdoublemousepress then begin + include(info.mouse.shiftstate,ss_triple); + end; + fdoublemousepress:= true; + end + else begin + if fdoublemouserelease then begin + include(info.mouse.shiftstate,ss_triple); + end; + fdoublemouserelease:= true; + end; + end + else begin + fdoublemousepress:= false; + fdoublemouserelease:= false; + end; + flastbutton:= fbutton; + end; + end; + flastshiftstate:= info.mouse.shiftstate; + window.dispatchmouseevent(info,fmousecapturewidget); + if (ftimestamp <> 0) and (fbutton <> mb_none) then begin + if kind = ek_buttonpress then begin + fbuttonpresswidgetbefore:= fmousewidget; + ftimestampbefore:= flastbuttonpresstimestamp; + flastbuttonpress:= fbutton; + flastbuttonpresstimestamp:= ftimestamp; + end + else begin + if kind = ek_buttonrelease then begin + fbuttonreleasewidgetbefore:= fmousewidget; + ftimestampbefore:= flastbuttonreleasetimestamp; + flastbuttonrelease:= fbutton; + flastbuttonreleasetimestamp:= ftimestamp; + end; + end; + end; + if not (hfl_custom in fhintinfo.flags) then begin + widget1:= fmousewidget; + // widget1:= fmousehintwidget; + if widget1 <> nil then begin + widget1:= widget1.widgetatpos(info.mouse.pos); + //search diabled child + end; + hintid1:= hintidwidget; + while (widget1 <> nil) and + ((ow_mousetransparent in widget1.foptionswidget) or + not widget1.isvisible or + not (widget1.enabled or (ow_disabledhint in widget1.foptionswidget)) + ) do begin + widget1:= widget1.parentwidget; + end; + if widget1 <> nil then begin + if widget1.fframe <> nil then begin + with widget1.fframe do begin + checkstate; + pt1:= translatewidgetpoint(abspos,nil,widget1); + if not ishintarea(pt1,hintid1) then begin + widget1:= nil; + end; + end; + end; + end; + if kind in [ek_buttonpress,ek_buttonrelease] then begin + deactivatehint; //cancel possible hint + end; + if (widget1 <> fhintedwidget) or (hintid1 <> fhintedid) then begin + if (widget1 <> fhintwidget) and + (fhintedwidget <> nil) or (fhintwidget = nil) then begin + deactivatehint; + fhintedwidget:= widget1; + if fhintedwidget <> nil then begin + fhintedid:= hintid1; + fhinttimer.interval:= hintdelaytime; + fhinttimer.enabled:= true; + end; + end; + end + else begin + if (fhintedwidget <> nil) and (fhintwidget = nil) and + (kind = ek_mousemove) then begin + fhinttimer.interval:= hintdelaytime; + if (ow_multiplehint in fhintedwidget.foptionswidget) and + (distance(fhintinfo.mouserefpos,abspos) > 3) then begin + fhinttimer.enabled:= true; + end; + end; + end; + end; + end + else begin + ungrabpointer; + end; + end; + finally + if event.timestamp <> 0 then begin + flastinputtimestamp:= event.timestamp; + end; + fmouseeventinfo:= nil; + fmousewheeleventinfo:= nil; + end; +end; + +procedure tinternalapplication.processkeyevent(event: tkeyevent); +var + window1: twindow; + widget1: twidget; + info: keyeventinfoty; + shift: shiftstatesty; +begin +{$ifdef mse_debugkey} + debugwriteln('*'+getenumname(typeinfo(eventkindty),ord(event.kind))+ + ' "'+ansistring(event.fchars)+'" '+inttostr(ord(event.fkey))); +{$endif} + try + fkeyeventinfo:= @info; + exclude(fstate,aps_clearkeyhistory); + with event do begin + if findwindow(fwinid,window1) then begin + fillchar(info,sizeof(info),0); + with info do begin + eventkind:= fkind; + timestamp:= event.timestamp; + serial:= application.getserial(); + key:= fkey; + keynomod:= fkeynomod; + case key of + key_shift: shift:= [ss_shift]; + key_alt: shift:= [ss_alt]; + key_control: shift:= [ss_ctrl]; + else shift:= []; + end; + if (fkey = key_decimal) and (fchars = '.') then begin + chars:= defaultformatsettingsmse.decimalseparator; + end + else begin + chars:= fchars; + end; + if kind = ek_keypress then begin + shiftstate:= fshiftstate + shift; + end + else begin + shiftstate:= fshiftstate - shift; + end; + flastshiftstate:= shiftstate; + flastkey:= key; + try + if fkeyboardcapturewidget <> nil then begin + window1:= fkeyboardcapturewidget.window; + widget1:= fkeyboardcapturewidget; + end + else begin + window1:= factivewindow; + if window1 <> nil then begin + widget1:= factivewindow.ffocusedwidget; + end + else begin + widget1:= nil; //compiler warning + end; + end; + if window1 <> nil then begin + fmouseparkeventinfo.shiftstate:= shiftstatesty( + replacebits({$ifdef FPC}longword{$else}word{$endif}(shiftstate), + {$ifdef FPC}longword{$else}word{$endif}(fmouseparkeventinfo.shiftstate), + {$ifdef FPC}longword{$else}word{$endif}(keyshiftstatesmask))); + if kind = ek_keypress then begin + fonkeypresslist.dokeyevent(widget1,info); + end; + if not (es_processed in eventstate) and + (not fposted or (fwinid = window1.winid)) then begin + window1.dispatchkeyevent(kind,info); + end; + end; + finally + if (eventkind = ek_keypress) and (key <> key_shift) and + (key <> key_control) and (key <> key_alt) then begin + if length(fkeyhistory) < keyhistorylen then begin + setlength(fkeyhistory,high(fkeyhistory)+2); + end; + if aps_clearkeyhistory in fstate then begin + fkeyhistory:= nil; + end + else begin + move(fkeyhistory[0],fkeyhistory[1],high(fkeyhistory)*sizeof(keyinfoty)); + with fkeyhistory[0] do begin + key:= info.key; + keynomod:= info.keynomod; + shiftstate:= info.shiftstate; + end; + end; + end; + end; + end; + end; + end; + finally + if event.timestamp <> 0 then begin + flastinputtimestamp:= event.timestamp; + end; + exclude(fstate,aps_clearkeyhistory); + fkeyeventinfo:= nil; + end; +end; + +function tinternalapplication.getevents: integer; +var + ev1: tmseevent; +begin + gdi_lock; + if ismainthread then begin //otherwise events of gui_getevent() of mainthread + while gui_hasevent do begin //could be eaten + ev1:= gui_getevent; + if ev1 <> nil then begin + eventlist.add(ev1); + end; + end; + end; + result:= eventlist.count; + gdi_unlock; +end; + +procedure tinternalapplication.waitevent; +begin +{$ifdef mse_debuggdisync} + checkgdiunlocked; +{$endif} + include(fstate,aps_waiting); + while gui_hasevent do begin + eventlist.add(gui_getevent); + end; + if eventlist.count = 0 then begin + incidlecount; + eventlist.add(gui_getevent); + end; + fstate:= fstate - [aps_waiting,aps_woken]; +end; + +procedure tinternalapplication.flushmousemove; +var + int1: integer; + event: tmseevent; +begin + gui_flushgdi; + getevents; + for int1:= 0 to eventlist.count - 1 do begin + event:= tmseevent(eventlist[int1]); + if (event <> nil) and (event.kind = ek_mousemove) then begin + event.free1; + eventlist[int1]:= nil; + end; + end; +end; + +procedure tinternalapplication.windowdestroyed(aid: winidty); +var + int1: integer; + event : tmseevent; +begin + fonwiniddestroyedlist.doevent(aid); + if not terminated then begin + for int1:= 0 to getevents - 1 do begin + event:= tmseevent(eventlist[int1]); + if (event is twindowevent) and (twindowevent(event).fwinid = aid) then begin + { + case event.kind of + ek_focusin: tcaret1(fcaret).restore; + ek_focusout: tcaret1(fcaret).remove; + end; + } + event.Free1; + eventlist[int1]:= nil; + end; + end; + end; + fmouse.windowdestroyed(aid); + if aid = fmousewinid then begin + fmousewinid:= 0; + end; +end; + +procedure tinternalapplication.setwindowfocus(winid: winidty); +var + window: twindow; +begin + if findwindow(winid,window) and (window.fstate*[tws_grouphidden] = []) then begin + try +{$ifdef mse_debugwindowfocus} + debugwriteln('setwindowfocus '+window.fownerwidget.name+' '+hextostr(winid,8)); +{$endif} + exclude(window.fstate,tws_focusoutpending); + if (fmodalwindow = nil) or (fmodalwindow = window) then begin + if wo_noactivate in window.options then begin + if window.transientfor <> nil then begin + gui_setwindowfocus(window.transientfor.winid); + end + else begin + if activewindow <> nil then begin + gui_setwindowfocus(activewindow.winid); + end; + end; + end + else begin + window.activated; + end; + end + else begin + if fmodalwindow.fwindow.id <> 0 then begin +{$ifdef mse_debugwindowfocus} + debugwriteln('call trycancelmodal '+window.fownerwidget.name+' '+hextostr(winid,8)); +{$endif} +{$warnings on} + if {$ifdef mswindows}false{$else} + fmodalwindow.fownerwidget.trycancelmodal(window) + {$endif} then begin +{$warnings off} + {$ifdef mse_debugwindowfocus} + debugwriteln('trycancelmodal true '+window.fownerwidget.name+' '+hextostr(winid,8)); + {$endif} + include(appinst.fstate,aps_cancelloop); + appinst.ffocuslockwindow:= nil; + appinst.ffocuslocktransientfor:= nil; + window.internalactivate(true,true); //force focus + end + else begin + if not fmodalwindow.visible then begin + gui_showwindow(fmodalwindow.fwindow.id); + end; + if ffocuslockwindow <> nil then begin //reactivate modal window + if ffocuslocktransientfor <> nil then begin + gui_setwindowfocus(ffocuslocktransientfor.winid); + end; + end + else begin + gui_setwindowfocus(fmodalwindow.fwindow.id); + end; + gui_raisewindow(fmodalwindow.fwindow.id,wo_popup in fmodalwindow.options); + end; + end; + end; + finally + if not (aps_focused in fstate) then begin + include(fstate,aps_focused); + tcaret1(fcaret).restore; + end; + end; + end{$ifndef mse_debugwindowfocus};{$endif} +{$ifdef mse_debugwindowfocus} + else begin + if not findwindow(winid,window) then begin + debugwriteln('setwindowfocus '+hextostr(winid,8)+' not found'); + end + else begin + debugwriteln('setwindowfocus '+window.fownerwidget.name+' '+ + hextostr(winid,8)+' grouphidden'); + end; + end; +{$endif} + +end; + +procedure tinternalapplication.unsetwindowfocus(winid: winidty); +var + window: twindow; +begin + if aps_focused in fstate then begin + exclude(fstate,aps_focused); + tcaret1(fcaret).remove; + end; + if findwindow(winid,window) then begin +{$ifdef mse_debugwindowfocus} + debugwriteln('unsetwindowfocus '+window.fownerwidget.name+' '+ + hextostr(winid,8)); +{$endif} + exclude(window.fstate,tws_focusoutpending); + if (ffocuslockwindow <> nil) and (factivewindow <> nil) and + (window = ffocuslocktransientfor) then begin + ffocuslockwindow:= nil; + factivewindow.deactivated; + end + else begin + window.deactivated; + end; + end; +end; + +procedure tinternalapplication.registerwindow(awindow: twindow); +begin + lock; + try + if finditem(pointerarty(fwindows),awindow) >= 0 then begin + guierror(gue_alreadyregistered,awindow.fownerwidget.name); + end; + additem(pointerarty(fwindows),awindow); + zorderinvalid(); + {$ifdef mse_debugzorder} + debugwindow('**registerwindow**',awindow); + {$endif} + finally + unlock; + end; +end; + +procedure tinternalapplication.unregisterwindow(awindow: twindow); +var + int1: integer; +begin + lock; + try + {$ifdef mse_debugzorder} + debugwindow('**unregisterwindow**',awindow); + {$endif} + int1:= removeitem(pointerarty(fwindows),awindow); + if (int1 >= 0) and (int1 <= fwindowupdateindex) then begin + dec(fwindowupdateindex); + end; + if awindow.fwindow.id = fmousewinid then begin + fmousewinid:= 0; + end; + finally + unlock; + end; +end; + +procedure tinternalapplication.doterminate(const shutdown: boolean); +begin + if fonterminatequerylist.doterminatequery then begin + if shutdown then begin + include(fstate,aps_terminated); + end + else begin + terminated:= true; + end; + end + else begin + if shutdown then begin + gui_cancelshutdown; + end; + end; +end; + +procedure tinternalapplication.checkshortcut(const sender: twindow; + const awidget: twidget; var info: keyeventinfoty); +var + int1: integer; +begin + include(info.eventstate,es_broadcast); + try + for int1:= high(fwindows) downto 0 do begin + if fwindows[int1] <> sender then begin + fwindows[int1].doshortcut(info,awidget); + if (es_processed in info.eventstate) then begin + break; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + appinst.fonshortcutlist.dokeyevent(awidget,info); + end; + finally + exclude(info.eventstate,es_broadcast); + end; +end; + +procedure tinternalapplication.checkactivewindow; +var + int1: integer; +begin + if factivewindow = nil then begin + if (fmainwindow <> nil) then begin + fmainwindow.fownerwidget.activate; + end + else begin + for int1:= 0 to high(fwindows) do begin + with fwindows[int1].fownerwidget do begin + if visible then begin + activate; + break; + end; + end; + end; + if (factivewindow = nil) and (high(fwindows) >= 0) then begin + fwindows[0].fownerwidget.activate; + end; + end; + end; +end; + +function tinternalapplication.focusinpending: boolean; +var + po1: ^tmseevent; + int1: integer; +begin + gui_flushgdi(true); + getevents; + po1:= pointer(eventlist.datapo); + result:= false; + for int1:= 0 to eventlist.count - 1 do begin + if (po1^ <> nil) and (po1^.kind = ek_focusin) then begin + result:= true; + break; + end; + inc(po1); + end; +end; + +procedure tinternalapplication.checkapplicationactive(); +var + bo1: boolean; +begin + bo1:= (activewindow <> nil) or focusinpending; +{$ifdef mse_debugwindowfocus} + if bo1 then begin + debugwriteln('checkapplicationactive true'); + end + else begin + debugwriteln('checkapplicationactive false'); + end; +{$endif} + if bo1 xor (aps_active in fstate) then begin + if bo1 then begin + include(fstate,aps_active); + end + else begin + exclude(fstate,aps_active); + hidehint; + end; + fonapplicationactivechangedlist.doevent(bo1); + if assistiveserver <> nil then begin + if aps_active in fstate then begin + assistiveserver.doapplicationactivated(); + end + else begin + assistiveserver.doapplicationdeactivated(); + end; + end; + end; +end; + +function tinternalapplication.winiddestroyed(const aid: winidty): boolean; +type + windoweventaty = array[0..0] of twindowevent; + pwindoweventaty = ^windoweventaty; +var + int1: integer; + po1: pwindoweventaty; +begin + result:= false; + getevents; + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + if po1^[int1] <> nil then begin + with po1^[int1] do begin + if (kind = ek_destroy) and (fwinid = aid) then begin + result:= true; + break; + end; + end; + end; + end; +end; + +{$ifdef mse_debug} +procedure debugwindow(const atext: string; const awindow: twindow); +var + str1: string; +begin + if awindow <> nil then begin + str1:= atext+hextostr(awindow.fwindow.id)+' '; + str1:= str1+awindow.owner.name; + end + else begin + str1:= str1+'NIL'; + end; + debugwriteln(str1); +end; + +function debugwindow1(const atext: string; const aid: winidty): string; +var + window1: twindow; +begin + result:= atext+hextostr(aid)+' '; + if appinst.findwindow(aid,window1) then begin + result:= result+window1.owner.name; + end + else begin + result:= result+'NIL'; + end; +end; + +procedure debugwindow(const atext: string; const aid: winidty); +begin + debugwriteln(debugwindow1(atext,aid)); +end; + +procedure debugwindow(const atext: string; const aid1,aid2: winidty); +var + str1: string; + window1: twindow; +begin + str1:= atext+hextostr(aid1)+' '; + if appinst.findwindow(aid1,window1) then begin + str1:= str1+window1.owner.name; + end + else begin + str1:= str1+'NIL'; + end; + str1:= str1+','+hextostr(aid2)+' '; + if appinst.findwindow(aid2,window1) then begin + str1:= str1+window1.owner.name; + end + else begin + str1:= str1+'NIL'; + end; + debugwriteln(str1); +end; + +function checkwindowname(const aid: winidty; const aname: string): boolean; +var + window1: twindow; +begin + result:= appinst.findwindow(aid,window1) and + (window1.fownerwidget.name = aname); +end; + +function debugwidgetname(const awidget: twidget; const atext: string): string; +begin + result:= ''; + if atext <> '' then begin + result:= atext+' '; + end; + if awidget <> nil then begin + result:= result + awidget.name; + end + else begin + result:= result + 'NIL'; + end; +end; + +{$endif} + +procedure tinternalapplication.removewindowevents(const awindow: winidty; + const aeventkind: eventkindty); +var + po1: pwindowevent; + int1: integer; +begin + getevents; + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin + with po1^ do begin + if (kind = ek_configure) and (fwinid = awindow) then begin + po1^.free; + po1^:= nil; + end; + end; + end; + inc(po1); + end; +end; + +procedure tinternalapplication.eventloop(const once: boolean = false); + + function checkiflast(const akind: eventkindty): boolean; + var + po1,po2: ^twindowevent; + int1: integer; + begin + po2:= nil; + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + //check if last + if po1^ <> nil then begin + with po1^ do begin + if (kind = akind) then begin + if po2 <> nil then begin + freeandnil(po2^); + end; + po2:= po1; + end; + end; + end; + inc(po1); + end; + result:= po2 = nil; + end; + + function canuievent: boolean; + begin + result:= not once or (fwaitcount = 0) {or (aps_processmessages in fstate)}; + if not result and (fmousewidget <> nil) then begin + capturemouse(nil,false); + setmousewidget(nil); + end; + end; //canuievent + +var + event: tmseevent; + int1: integer; + bo1,bo2,bo3: boolean; + window: twindow; + id1: winidty; + po1: ^twindowevent; + po2: pmodalinfoty; + waitcountbefore: integer; + ar1: integerarty; + ar2: eventarty; + modalinfo: modalinfoty; + +begin //eventloop + if aps_looplocked in fstate then begin + exit; + end; + if not ismainthread then begin + raise exception.create('Eventloop must be in main thread.'); + end; + + inc(flooplevel); + if fcurrmodalinfo = nil then begin + fillchar(modalinfo,sizeof(modalinfo),0); + fcurrmodalinfo:= @modalinfo; + end; + try + ftimertick:= false; + waitcountbefore:= fwaitcount; + if not once then begin + fwaitcount:= 0; + end; + checkcursorshape; + while not ((fcurrmodalinfo <> nil) and fcurrmodalinfo^.modalend) and + not terminated and (fstate * [aps_exitloop,aps_cancelloop] = []) do begin + //main eventloop + try + if ((fcurrmodalinfo = nil) or (high(fcurrmodalinfo^.events) < 0)) and + (getevents = 0) then begin + checkwindowstack; + int1:= 0; + repeat + bo1:= false; + fwindowupdateindex:= 0; + while fwindowupdateindex <= high(fwindows) do begin + try + bo1:= fwindows[fwindowupdateindex].internalupdate or bo1; + except + handleexception(self); + end; + inc(fwindowupdateindex); + end; + inc(int1); + until not bo1 and not terminated or (int1 > 8); //no more to paint + exclude(fstate,aps_invalidated); + if terminated or (aps_exitloop in fstate) then begin + break; + end; + if not gui_hasevent then begin + try +// if (fcurrmodalinfo{amodalwindow} = nil) and + if (fcurrmodalinfo^.level = 0) and + not (aps_activewindowchecked in fstate) then begin + include(fstate,aps_activewindowchecked); + checkactivewindow; + end; + ftimertick:= false; + msetimer.tick(self); //tick called in every idle + except + handleexception(self); + end; + if not gui_hasevent then begin + try + doidle; + except + handleexception(self); + end; + end; + if terminated then begin + break; + end; + if (aps_needsupdatewindowstack in fstate) and + application.active then begin + updatewindowstack; + exclude(fstate,aps_needsupdatewindowstack); + end + else begin + checkwindowstack; + end; + checkcursorshape; + if once then begin + break; + end; + if gui_hasevent or not (aps_invalidated in fstate) then begin + waitevent; + end; + end; + end; + if terminated then begin + break; + end; + getevents; + if {(fcurrmodalinfo <> nil) and} (high(fcurrmodalinfo^.events) >= 0) then begin + event:= fcurrmodalinfo^.events[0]; + tobjectevent1(event).fmodallevel:= -1; + deleteitem(pointerarty(fcurrmodalinfo^.events),0); + end + else begin + event:= tmseevent(eventlist.getfirst); + end; + if event <> nil then begin + try + try + bo1:= false; + fonapplicationeventlist.doevent(event,bo1); + if not bo1 then begin + case event.kind of + ek_timer: begin + ftimertick:= true; + end; + ek_show,ek_hide: begin + {$ifdef mse_debugwindowfocus} + if event.kind = ek_show then begin + debugwindow('ek_show ',twindowevent(event).fwinid); + end + else begin + debugwindow('ek_hide ',twindowevent(event).fwinid); + end; + {$endif} + processshowingevent(twindowevent(event)); + end; + ek_close: begin + if findwindow(twindowevent(event).fwinid,window) then begin + if (fmodalwindow = nil) or (fmodalwindow = window) then begin + window.close; + end + else begin + fmodalwindow.fownerwidget.canclose(nil); + end; + end; + end; + ek_destroy: begin + if findwindow(twindowevent(event).fwinid,window) then begin + window.windowdestroyed; + end; + windowdestroyed(twindowevent(event).fwinid); + end; + ek_terminate: begin + doterminate(true); + end; + ek_focusin: begin + {$ifdef mse_debugwindowfocus} + debugwindow('ek_focusin ',twindowevent(event).fwinid); + {$endif} + getevents; + bo1:= true; + id1:= twindowevent(event).fwinid; + po1:= pointer(eventlist.datapo); + bo3:= false; + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin //find last focusin + with po1^ do begin + case kind of + ek_focusin: begin + bo3:= false; + id1:= fwinid; + end; + ek_focusout: begin + bo3:= true; + if fwinid = twindowevent(event).fwinid then begin + id1:= 0; + end; + end; + end; + end; + end; + inc(po1); + end; + bo2:= id1 = twindowevent(event).fwinid; //last focus is current window + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin + with po1^ do begin + if (kind = ek_destroy) and + (fwinid = twindowevent(event).fwinid) then begin + bo1:= false; + end; + if bo2 then begin //last focus is current window + if kind in [ek_focusin,ek_focusout] then begin + {$ifdef mse_debugwindowfocus} + debugwindow(' '+getenumname(typeinfo(eventkindty),ord(kind))+ + ' deleted',twindowevent(event).fwinid); + {$endif} + freeandnil(po1^); //ignore + end; + end + else begin + if (kind = ek_focusout) and + (fwinid = twindowevent(event).fwinid) then begin + {$ifdef mse_debugwindowfocus} + debugwindow(' spurious ek_focusout deleted ', + twindowevent(event).fwinid); + {$endif} + bo1:= false; + freeandnil(po1^); + //spurious focus, for instance minimize window group on windows + if bo3 and (factivewindow <> nil) then begin + unsetwindowfocus(factivewindow.fwindow.id); + postevent(tmseevent.create(ek_checkapplicationactive)); + end; + break; + end; + end; + end; + end; + inc(po1); + end; + include(fstate,aps_needsupdatewindowstack); + if bo1 then begin + setwindowfocus(twindowevent(event).fwinid); + checkapplicationactive; + end; + {$ifdef mse_debugwindowfocus} + if not bo1 then begin + debugwriteln(' ek_focusin ignored'); + end; + {$endif} + end; + ek_focusout: begin + {$ifdef mse_debugwindowfocus} + debugwindow('ek_focusout '+hextostr(event)+' ', + twindowevent(event).fwinid); + {$endif} + getevents; + po1:= pointer(@eventlist.datapo^[eventlist.count-1]); + bo1:= true; + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin + with po1^ do begin + case kind of + ek_focusin: begin + {$ifdef mse_debugwindowfocus} + debugwindow(' ek_focusout ignored ',twindowevent(event).fwinid); + {$endif} + bo1:= false; //ignore the event + break; + end; + ek_focusout: begin + break; + end; + end; + end; + end; + dec(po1); + end; + if bo1 then begin + unsetwindowfocus(twindowevent(event).fwinid); + postevent(tmseevent.create(ek_checkapplicationactive)); + end + else begin + include(fstate,aps_restorelocktransientfor); + end; + end; + ek_checkapplicationactive: begin + if checkiflast(ek_checkapplicationactive) then begin + checkapplicationactive; + end; + end; + ek_expose: begin + zorderinvalid(); + processexposeevent(twindowrectevent(event)); + end; + ek_configure: begin + zorderinvalid(); + id1:= twindowrectevent(event).fwinid; + getevents; + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin + //use last configure event for the window + with twindowrectevent(po1^) do begin + if (kind = ek_configure) and (fwinid = id1) then begin + event.free; + event:= po1^; + po1^:= nil; + end; + end; + end; + end; + processconfigureevent(twindowrectevent(event)); + end; + ek_enterwindow: begin + if fmousewinid <> twindowevent(event).fwinid then begin + //there can be an additional enterwindow by mouse click + processwindowcrossingevent(twindowevent(event)); + if canuievent and (event is tmouseenterevent) then begin + processmouseevent(tmouseenterevent(event)); + end; + end; + end; + ek_leavewindow: begin + getevents; + ar1:= nil; + po1:= pointer(eventlist.datapo); + bo1:= true; + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin + with po1^ do begin + if kind in [ek_enterwindow,ek_leavewindow] then begin + additem(ar1,int1); + end; + if (kind = ek_enterwindow) and (fwinid = twindowevent(event).fwinid) then begin + bo1:= false; + //spurious leavewindow + break; + end; + end; + end; + inc(po1); + end; + if bo1 then begin + processwindowcrossingevent(twindowevent(event)) + end + else begin + po1:= pointer(eventlist.datapo); + for int1:= 0 to high(ar1) do begin + freeandnil(pobjectaty(po1)^[ar1[int1]]); + end; + end; + end; + ek_mousemove: begin + if checkiflast(ek_mousemove) and canuievent then begin + processmouseevent(tmouseevent(event)); + end; + end; + ek_buttonpress,ek_buttonrelease,ek_mousewheel: begin + if canuievent then begin + processmouseevent(tmouseevent(event)); + end; + end; + ek_keypress,ek_keyrelease: begin + if canuievent then begin + processkeyevent(tkeyevent(event)); + end; + end; + ek_asyncexec: begin + texecuteevent(event).deliver; + end; + ek_sysdnd: begin + if findwindow(tsysdndevent(event).fwinid,window) then begin + window.processsysdnd(tsysdndevent(event)); + end; + end; + else begin + if event is tobjectevent then begin + with tobjectevent(event) do begin + // if fcurrmodalinfo = nil then begin + // int1:= -modallevel; + // end + // else begin + int1:= fcurrmodalinfo^.level-modallevel; + // end; + if (int1 > 0) and (modallevel >= 0) then begin + po2:= fcurrmodalinfo^.parent; + for int1:= int1 - 2 downto 0 do begin + po2:= po2^.parent; + end; + additem(pointerarty(po2^.events),event); + event:= nil; + end + else begin + deliver; + end; + end; + end; + end; + end; + end; + finally + event.free1; + end; + except + handleexception(self); + end; + checkcursorshape; + end; + except + end; + end; + exclude(fstate,aps_exitloop); + fwaitcount:= waitcountbefore; + if fwaitcount > 0 then begin + mouse.shape:= cr_wait; + end; + checkcursorshape; + + if {(fcurrmodalinfo <> nil) and} (fcurrmodalinfo^.parent <> nil) then begin + stackarray(pointer(fcurrmodalinfo^.events), + pointerarty(fcurrmodalinfo^.parent^.events)); + end + else begin +// if fcurrmodalinfo <> nil then begin + ar2:= fcurrmodalinfo^.events; + fcurrmodalinfo^.events:= nil; +// end +// else begin +// ar2:= nil; +// end; + for int1:= 0 to high(ar2) do begin + if ar2[int1] is tobjectevent then begin + with tobjectevent1(ar2[int1]) do begin + fmodallevel:= -1; + free1; + end; + end + else begin + ar2[int1].free; + end; + end; + end; + finally + dec(flooplevel); + if fcurrmodalinfo = @modalinfo then begin + fcurrmodalinfo:= nil; + end; + end; +end; + +function tinternalapplication.beginmodal(const sender: twindow; + const showinfo: pshowinfoty): boolean; + //true if modalwindow destroyed +var + window1: twindow; + bo1: boolean; + modalwidgetbefore,focusedwidgetbefore: twidget; + modalinfo: modalinfoty; + modalinfobefore: pmodalinfoty; + p1,pe: ^tmseevent; +begin + result:= false; + exclude(fstate,aps_cancelloop); + window1:= nil; + if (factivewindow <> nil) and (factivewindow <> sender) then begin + setlinkedvar(factivewindow,tlinkedobject(window1)); + bo1:= tws_modalcalling in window1.fstate; + include(window1.fstate,tws_modalcalling); + end; + modalwidgetbefore:= nil; + focusedwidgetbefore:= nil; + fillchar(modalinfo,sizeof(modalinfo),0); + if fcurrmodalinfo <> nil then begin + modalinfo.parent:= fcurrmodalinfo; + modalinfo.level:= fcurrmodalinfo^.level+1; + end + else begin + modalinfo.level:= 1; + end; + fcurrmodalinfo:= @modalinfo; + if fmodalwindow <> nil then begin + setlinkedvar(fmodalwindow,tlinkedobject(modalinfo.modalwindowbefore)); + end; + modalinfobefore:= sender.fmodalinfopo; + sender.fmodalinfopo:= @modalinfo; + setlinkedvar(sender,tlinkedobject(fmodalwindow)); + + try + with sender do begin + inc(fmodallevel); + end; + if showinfo <> nil then begin + with showinfo^ do begin + setlinkedvar(widget.window.fmodalwidget,tmsecomponent(modalwidgetbefore)); + if (factivewindow = sender) and (sender.ffocusedwidget <> nil) and + not widget.checkdescendent(sender.ffocusedwidget) then begin + setlinkedvar(sender.ffocusedwidget, + tmsecomponent(focusedwidgetbefore)); + end; + widget.internalshow(ml_none,@transientfor,windowevent,nomodalforreset); + if fstate * [aps_cancelloop,aps_exitloop] <> [] then begin + exit; + end; + widget.activate; + setlinkedvar(sender.fmodalwidget,tmsecomponent(modalwidgetbefore)); + sender.fmodalwidget:= widget; + end; + end; + sender.activate; + if fstate * [aps_cancelloop,aps_exitloop] = [] then begin + try + eventloop; + finally + with showinfo^ do begin + if (widget <> nil) then begin + widget.window.fmodalwidget:= modalwidgetbefore; + end; + end; + if (window1 <> nil) then begin + try + if not (aps_cancelloop in fstate) then begin + if (focusedwidgetbefore <> nil) then begin + focusedwidgetbefore.activate(true,false); + end; + if appinst.active and (appinst.fwantedactivewindow = nil) then begin + p1:= pointer(eventlist.datapo); + pe:= p1 + eventlist.count; + while p1 < pe do begin + if p1^ <> nil then begin + with p1^ do begin + if (kind = ek_focusout) and + (window1.fwindow.id = twindowevent(p1^).fwinid) then begin + include(window1.fstate,tws_focusoutpending); + {$ifdef mse_debugwindowfocus} + debugwindow('focusoutpending ',window1); + {$endif} + break; + end; + end; + end; + inc(p1); + end; + window1.activate(); + end; + end; + finally + if (window1 <> nil) and not bo1 then begin + exclude(window1.fstate,tws_modalcalling); + end; + end; + end; + end; + end; + finally + setlinkedvar(nil,tlinkedobject(window1)); + setlinkedvar(nil,tmsecomponent(modalwidgetbefore)); + setlinkedvar(nil,tmsecomponent(focusedwidgetbefore)); + exclude(fstate,aps_exitloop); + if fmodalwindow <> nil then begin + fmodalwindow.fmodalinfopo:= modalinfobefore{nil}; + end + else begin + result:= true; + end; + if modalinfo.modalwindowbefore <> nil then begin + setlinkedvar(modalinfo.modalwindowbefore,tlinkedobject(fmodalwindow)); + setlinkedvar(nil,tlinkedobject(modalinfo.modalwindowbefore)); + end + else begin + if fmodalwindow <> nil then begin + setlinkedvar(nil,tlinkedobject(fmodalwindow)); + //no lower modalwindow alive + end; + end; + fcurrmodalinfo:= modalinfo.parent; + end; +end; + +procedure tinternalapplication.endmodal(const sender: twindow); +begin + with sender do begin + if fmodallevel > 0 then begin + if not appinst.terminated and (fmodalinfopo <> nil) then begin + fmodalinfopo^.modalend:= true; + end; + dec(fmodallevel); + end; + end; +end; + +{$ifdef mse_debugzorder} +function debugwindowinfo(const awindow: twindow): string; +begin + if awindow = nil then begin + result:= 'nil'; + end + else begin + if awindow = application.activewindow then begin + result:= 'A'; + if awindow.modal then begin + result:= result+'M'; + end; + end + else begin + result:= ''; + end; + result:= result+'"'+awindow.fownerwidget.name+':'+ + awindow.fownerwidget.classname+'"'; + end; +end; + +procedure printwindowstackinfo(const ar3: windowarty); overload; +var + int1: integer; +begin + for int1:= 0 to high(ar3) do begin + if ar3[int1].fownerwidget.visible then begin + debugwrite(inttostr(int1)+'+ '); + end + else begin + debugwrite(inttostr(int1)+'- '); + end; + debugwriteln(debugwindowinfo(ar3[int1])+' transientfor:'+ + debugwindowinfo(ar3[int1].ftransientfor)); + end; +end; + +procedure printwindowstackinfo(const ar3: windowstackinfoarty); overload; +var + int1: integer; +begin + for int1:= 0 to high(ar3) do begin + debugwriteln(debugwindowinfo(ar3[int1].lower)+' '+ + debugwindowinfo(ar3[int1].upper)); + end; +end; + +{$endif} + +procedure tinternalapplication.stackunder(const sender: twindow; + const predecessor: twindow); +begin +{$ifdef mse_debugzorder} + debugwriteln('****stackunder**** '+debugwindowinfo(sender)+' '+ + debugwindowinfo(predecessor)); +{$endif} + setlength(fwindowstack,high(fwindowstack)+2); + with fwindowstack[high(fwindowstack)] do begin + lower:= sender; + upper:= predecessor; + end; +end; + +procedure tinternalapplication.stackover(const sender: twindow; + const predecessor: twindow); +begin +{$ifdef mse_debugzorder} + debugwriteln('****stackover**** '+debugwindowinfo(sender)+' '+ + debugwindowinfo(predecessor)); +{$endif} + setlength(fwindowstack,high(fwindowstack)+2); + with fwindowstack[high(fwindowstack)] do begin + lower:= predecessor; + upper:= sender; + end; +end; + +function cmpwindowstack(const l,r): integer; +begin + result:= windowstackinfoty(l).level - windowstackinfoty(r).level; +end; + +procedure tinternalapplication.checkwindowstack; + + function findlevel(var item: windowstackinfoty): integer; + var + int1: integer; + begin + with item do begin + if (level = 0) and (lower <> nil) and not recursion then begin + if upper = nil then begin + result:= -bigint; + end + else begin + result:= 1; //not found upper + recursion:= true; + for int1:= 0 to high(fwindowstack) do begin + with fwindowstack[int1] do begin + if lower = item.upper then begin + result:= findlevel(fwindowstack[int1]) + 1; + break; + end; + end; + end; + recursion:= false; + end; + end + else begin + result:= level; + end; + level:= result; + end; + end; + +var + int1: integer; +begin + if (fwindowstack <> nil) and (flockupdatewindowstack = nil) then begin + include(fstate,aps_looplocked); //no windows sizing callbacks + try + if not nozorderhandling then begin + {$ifdef mse_debugzorder} + debugwriteln('****checkwindowstack**** fwindowstack'); + printwindowstackinfo(fwindowstack); + {$endif} + for int1:= 0 to high(fwindowstack) do begin + findlevel(fwindowstack[int1]); + end; + sortarray(fwindowstack,sizeof(windowstackinfoty), + {$ifdef FPC}@{$endif}cmpwindowstack); + {$ifdef mse_debugzorder} + debugwriteln('..... after sort'); + printwindowstackinfo(fwindowstack); + {$endif} + if gui_canstackunder then begin + for int1:= 0 to high(fwindowstack) do begin + with fwindowstack[int1] do begin + if lower <> nil then begin + if (upper = nil) then begin + gui_raisewindow(lower.winid); + end + else begin + // if int1 = 0 then begin + // gui_raisewindow(upper.winid); + // end; + gui_stackunderwindow(lower.winid,upper.winid); + end; + end; + end; + end; + end + else begin + for int1:= high(fwindowstack) downto 0 do begin + with fwindowstack[int1] do begin + if (lower <> nil) then begin + gui_raisewindow(fwindowstack[int1].lower.winid); + end; + end; + end; + for int1:= 0 to high(fwindowstack) do begin //raise top level window + with fwindowstack[int1] do begin + if lower <> nil then begin + if upper <> nil then begin + gui_raisewindow(fwindowstack[int1].upper.winid); + end; + break; + end; + end; + end; + end; + zorderinvalid(); + end; + fwindowstack:= nil; + finally + exclude(fstate,aps_looplocked); + end; + end; +end; + +function compwindowzorder(const l,r): integer; +const + raiseweight = 1 shl 1; + lowerweight = raiseweight; + backgroundweight = 1 shl 2; + topweight = backgroundweight; +// popupweight = 1 shl 4; + modalweight = 1 shl 5; +// transientforcountweight = 1 shl 6; +// transientfornotnilweight = 1 shl 7; + transientforactiveweight = 1 shl 8; + transientforweight = 1 shl 9; + invisibleweight = 1 shl 10; + popupweight = 1 shl 11; + ultratopweight = 1 shl 12; +var + window1: twindow; +{$ifdef mse_debugzorder} + ch1: char; +{$endif} +label + endlab; +begin + result:= 0; + if (tws_windowvisible in twindow(l).fstate) and + (twindow(l).syscontainer = sywi_none) then begin + if not (tws_windowvisible in twindow(r).fstate) or + (twindow(r).syscontainer <> sywi_none) then begin + inc(result,invisibleweight); + end + end + else begin + if (tws_windowvisible in twindow(r).fstate) and + (twindow(r).syscontainer = sywi_none)then begin + dec(result,invisibleweight); + end + else begin + goto endlab; //both invisible -> no change in order + end; + end; + if (result = 0) and + ((twindow(l).syscontainer <> sywi_none) or + (twindow(r).syscontainer <> sywi_none) or + (twindow(l).fcontainer <> 0) or + (twindow(r).fcontainer <> 0)) then begin + goto endlab; //don't change order of embedded windows + end; + if tws_raise in twindow(l).fstate then begin + inc(result,raiseweight); + end; + if tws_raise in twindow(r).fstate then begin + dec(result,raiseweight); + end; + if tws_lower in twindow(l).fstate then begin + dec(result,lowerweight); + end; + if tws_lower in twindow(r).fstate then begin + inc(result,lowerweight); + end; + if ow_background in twindow(l).fownerwidget.foptionswidget then begin + dec(result,backgroundweight); + end; + if ow_top in twindow(l).fownerwidget.foptionswidget then begin + inc(result,topweight); + end; + if ow_ultratop in twindow(l).fownerwidget.foptionswidget then begin + inc(result,ultratopweight); + end; + if ow_background in twindow(r).fownerwidget.foptionswidget then begin + inc(result,backgroundweight); + end; + if ow_top in twindow(r).fownerwidget.foptionswidget then begin + dec(result,topweight); + end; + if ow_ultratop in twindow(r).fownerwidget.foptionswidget then begin + dec(result,ultratopweight); + end; + if twindow(l).ispopup then begin + inc(result,popupweight); + end; + if twindow(r).ispopup then begin + dec(result,popupweight); + end; + if twindow(l).fmodallevel > 0 then begin + inc(result,modalweight); + end; + if twindow(r).fmodallevel > 0 then begin + dec(result,modalweight); + end; + if twindow(l).transientforstackactive then begin + inc(result,transientforactiveweight); + end; + if twindow(r).transientforstackactive then begin + dec(result,transientforactiveweight); + end; + { +// if twindow(l).transientforstackactive then begin + if twindow(l).ftransientfor <> nil then begin + inc(result,transientfornotnilweight); + end; + if twindow(l).ftransientforcount > 0 then begin + inc(result,transientforcountweight); + end; +// end; +// if twindow(r).transientforstackactive then begin + if twindow(r).ftransientfor <> nil then begin + dec(result,transientfornotnilweight); + end; + if twindow(r).ftransientforcount > 0 then begin + dec(result,transientforcountweight); + end; +// end; +} + window1:= twindow(l); + while window1.ftransientfor <> nil do begin + if window1.ftransientfor = twindow(r) then begin + inc(result,transientforweight); + goto endlab; + end; + window1:= window1.ftransientfor; + end; + window1:= twindow(r); + while window1.ftransientfor <> nil do begin + if window1.ftransientfor = twindow(l) then begin + dec(result,transientforweight); + goto endlab; + end; + window1:= window1.ftransientfor; + end; +endlab: +{$ifdef mse_debugzorder} + if result < 0 then begin + ch1:= '-'; + end + else begin + ch1:= ' '; + end; + debugwindow('.'+ch1+hextostr(longword(abs(result)),4)+ + ' tract:'+bintostr(ord(twindow(l).transientforstackactive),1)+':'+ + bintostr(ord(twindow(r).transientforstackactive),1)+ + ' trforco:'+inttostr(twindow(l).ftransientforcount)+':'+ + inttostr(twindow(r).ftransientforcount)+ + ' l:',twindow(l).winid, + twindow(r).winid); +{$endif} +end; + +procedure tinternalapplication.updatewindowstack; +var + ar3,ar4: windowarty; + int1,int2: integer; + bo1: boolean; +begin + if flockupdatewindowstack = nil then begin + exclude(fstate,aps_zordervalid); //possible missing configure events + checkwindowstack; + sortzorder; + ar3:= windowar; //refcount 1 + {$ifdef mse_debugzorder} + debugwriteln('*****updatewindowstack***** current order'); + printwindowstackinfo(ar3); + {$endif} + ar4:= copy(ar3); + sortarray(ar3,sizeof(ar3[0]),{$ifdef FPC}@{$endif}compwindowzorder); + for int1:= 0 to high(ar3) do begin + with ar3[int1] do begin + fstate:= fstate - [tws_raise,tws_lower]; + //reset bringtofrontlocal/sendtobacklocal + end; + end; + int2:= -1; + {$ifdef mse_debugzorder} + debugwriteln('++++ after sort'); + printwindowstackinfo(ar3); + {$endif} + for int1:= 0 to high(ar4) do begin + if ar3[int1] <> ar4[int1] then begin + int2:= int1; //invalid stackorder + break; + end; + end; + if int2 >= 0 then begin + {$ifdef mse_debugzorder} + debugwriteln('++++ invalid stackorder ' + inttostr(int2) + + ' high(ar3) ' + inttostr(high(ar3))); + {$endif} + if gui_canstackunder then begin + bo1:= true; + for int1:= int2+1 to high(ar3) do begin + if ar4[int1] <> ar3[int1-1] then begin + bo1:= false; + break; + end; + end; + if bo1 then begin //single local raise + {$ifdef mse_debugzorder} + debugwriteln('++++ single local raise'); + {$endif} + gui_stackoverwindow(ar4[int2].winid,ar4[high(ar4)].winid); + fwindowstack:= nil; + zorderinvalid(); + exit; + end; + end; + inc(int2); + for int1:= high(ar3) downto int2 do begin + if not (tws_windowvisible in ar3[int1-1].fstate) then begin + break; + end; + stackunder(ar3[int1-1],ar3[int1]); + end; + checkwindowstack; + end; + end; +end; + +procedure tinternalapplication.internalpackwindowzorder(); +var + int1: integer; +begin + updatewindowstack(); //handle pending; + sortzorder(); + if high(fwindows) > 1 then begin + setlength(fwindowstack,length(fwindows)); + for int1:= 0 to high(fwindowstack) - 1 do begin + with fwindowstack[int1] do begin + lower:= fwindows[int1]; + upper:= fwindows[int1+1]; + end; + end; + { + with fwindowstack[high(fwindowstack)] do begin + lower:= fwindows[high(fwindowstack)]; + upper:= nil; + end; + } + end; +end; + +procedure tinternalapplication.widgetdestroyed(const widget: twidget); +begin + if fmousecapturewidget = widget then begin + capturemouse(nil,false); + end; + if fkeyboardcapturewidget = widget then begin + fkeyboardcapturewidget:= nil; + end; + if fcaretwidget = widget then begin + caret.hide; + fcaretwidget:= nil; + end; + if fmousewidget = widget then begin + setmousewidget(nil); + end; + if fmousehintwidget = widget then begin + fmousehintwidget:= nil; + end; + if fhintforwidget = widget then begin + deactivatehint; + end; + if fhintedwidget = widget then begin + fhintedwidget:= nil; + end; + if flastshowmenuwidget = widget then begin + flastshowmenuwidget:= nil; + end; + if fclientmousewidget = widget then begin + fclientmousewidget:= nil; + end; + if fbuttonpresswidgetbefore = widget then begin + fbuttonpresswidgetbefore:= nil; + end; + if fbuttonreleasewidgetbefore = widget then begin + fbuttonreleasewidgetbefore:= nil; + end; +end; + +procedure tinternalapplication.checkcursorshape; +begin + if terminated then begin + fmouse.shape:= cr_default; + end + else begin + if not waiting then begin + if fcursorshape = cr_default then begin + fmouse.shape:= fwidgetcursorshape; + end + else begin + fmouse.shape:= fcursorshape; + end; + end + else begin + fmouse.shape:= cr_wait; + end; + end; +end; + +procedure tinternalapplication.dopostevent(const aevent: tmseevent); +begin + gui_postevent(aevent); +end; + +procedure tinternalapplication.doeventloop(const once: boolean); +begin + eventloop(once); +end; + +{ tguiapplication } + +constructor tguiapplication.create(aowner: tcomponent); +begin + fwidgetcursorshape:= cr_default; + fmousewheelsensitivity:= 1; + fmousewheelfrequmin:= 1; + fmousewheelfrequmax:= 100; + fmousewheeldeltamin:= 0.05; + fmousewheeldeltamax:= 30; + fmousewheelaccelerationmax:= 30; + fhintwidgetclass:= thintwidget; + gui_registergdi; + inherited; +end; + +procedure getmseguiarguments(); +var + ar1: msestringarty; + int1,int2: integer; + + procedure deleteitem(); + begin + deletecommandlineargument(int1-int2); + inc(int2); + end; //deleteitem + +begin + ar1:= getcommandlinearguments; + int2:= 0; + for int1:= 1 to high(ar1) do begin + if ar1[int1] = '--TOPLEVELRAISE' then begin + toplevelraise:= true; + deleteitem(); + noreconfigurewmwindow:= true; + norestackwindow:= true; + continue; + end; + if ar1[int1] = '--NOZEROLINES' then begin + zerolineworkaround:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--NOZORDERHANDLING' then begin + nozorderhandling:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--NORESTACKWINDOW' then begin + norestackwindow:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--RESTACKWINDOW' then begin + norestackwindow:= false; + deleteitem(); + continue; + end; + if ar1[int1] = '--NORECONFIGUREWMWINDOW' then begin + noreconfigurewmwindow:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--RECONFIGUREWMWINDOW' then begin + noreconfigurewmwindow:= false; + deleteitem(); + continue; + end; + if ar1[int1] = '--STACKMODEBELOWWORKAROUND' then begin + stackmodebelowworkaround:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--NOSTACKMODEBELOWWORKAROUND' then begin + stackmodebelowworkaround:= false; + deleteitem(); + continue; + end; + if ar1[int1] = '--NOSTATICGRAVITY' then begin + nostaticgravity:= true; + deleteitem(); + continue; + end; + { + if ar1[int1] = '--EXABUG' then begin + //workaround for radeon EXA pixmap bug, slows down drawing! + exabug:= true; + deleteitem(); + continue; + end; + } + { + if ar1[int1] = '--NOCREATESTATICGRAVITY' then begin + nocreatestaticgravity:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--CREATESTATICGRAVITY' then begin + nocreatestaticgravity:= false; + deleteitem(); + continue; + end; + } + end; +end; + +procedure tguiapplication.internalinitialize; +begin + with tinternalapplication(self) do begin + fdesigning:= false; + getmseguiarguments(); + guierror(gui_init,self); + msetimer.init(); + msegraphics.init(); + end; +end; + +procedure tguiapplication.internaldeinitialize; +begin + with tinternalapplication(self) do begin + if fcaret <> nil then begin + fcaret.link(nil,nullpoint,nullrect); + end; + msegraphics.deinit(); + lock(); + gui_flushgdi(); + flusheventbuffer(); + getevents(); + eventlist.clear(); + unlock(); + gui_deinit(); + msetimer.deinit(); + end; + inherited; +end; + +procedure tguiapplication.destroyforms; +begin + while componentcount > 0 do begin + components[componentcount-1].free; //destroy loaded forms + end; + while high(fwindows) >= 0 do begin + fwindows[high(fwindows)].fownerwidget.free; + end; +end; + +procedure tguiapplication.checkwindowrect(winid: winidty; var rect: rectty); +var + window: twindow; +begin + if findwindow(winid,window) then begin + window.fownerwidget.checkwidgetsize(rect.size); + end; +end; + +procedure tguiapplication.setclientmousewidget(const widget: twidget; + const apos: pointty); +var + info: mouseeventinfoty; +begin + if fclientmousewidget <> widget then begin + fillchar(info,sizeof(info),0); + if (fclientmousewidget <> nil) and + not (csdestroying in fclientmousewidget.componentstate) then begin +// exclude(fclientmousewidget.fwidgetstate,ws_mouseinclient); + info.eventkind:= ek_clientmouseleave; + fclientmousewidget.mouseevent(info); + end; + fclientmousewidget:= widget; + if widget <> nil then begin + info.eventkind:= ek_clientmouseenter; + info.pos:= apos; + widget.mouseevent(info); + end; + end; +end; + +procedure tguiapplication.setmousewidget(const widget: twidget); +var + info: mouseeventinfoty; + widget1: twidget; +begin + widget1:= fmousewidget; + fmousewidget:= widget; + if (fclientmousewidget <> nil) and (fclientmousewidget <> widget) then begin + setclientmousewidget(nil,nullpoint); + end; + if widget1 <> widget then begin + if (widget1 <> nil) and + not (csdestroying in widget1.componentstate) then begin + fillchar(info,sizeof(info),0); + info.eventkind:= ek_mouseleave; + widget1.mouseevent(info); + end; + if widget <> nil then begin + finalize(info); + fillchar(info,sizeof(info),0); + info.eventkind:= ek_mouseenter; + widget.mouseevent(info); + end; + end; +end; + +function tguiapplication.grabpointer(const aid: winidty): boolean; +var + int1: integer; +begin + for int1:= 0 to high(fwindows) do begin + with fwindows[int1] do begin + if fwindow.id <> aid then begin + exclude(fstate,tws_grab); + end; + end; + end; + {$ifdef nograbpointer} + result:= true; + {$else} + result:= gui_grabpointer(aid) = gue_ok; + {$endif} + if result then begin + include(fstate,aps_mousecaptured); + end + else begin + exclude(fstate,aps_mousecaptured); + end; +end; + +function tguiapplication.ungrabpointer: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(fwindows) do begin + if tws_grab in fwindows[int1].fstate then begin + exit; + end; + end; + gui_ungrabpointer; + exclude(fstate,aps_mousecaptured); + result:= true; +end; + +procedure tguiapplication.capturemouse(const sender: twidget; + const grab: boolean); +var + widget: twidget; + info: mouseeventinfoty; +begin + if fmousecapturewidget <> sender then begin + if (fmousecapturewidget <> nil) and + not (csdestroying in fmousecapturewidget.componentstate) then begin + widget:= fmousecapturewidget; + fmousecapturewidget:= sender; + fillchar(info,sizeof(info),0); + info.eventkind:= ek_mousecaptureend; + widget.mouseevent(info); + if fmousecapturewidget <> sender then begin + exit; + end; + widget.fwidgetstate:= widget.fwidgetstate - + [ws_lclicked,ws_mclicked,ws_rclicked, + ws_mousecaptured,ws_clientmousecaptured]; + if sender <> nil then begin + fwidgetcursorshape:= cr_default; //give up cursor shape + end; + end + else begin + fmousecapturewidget:= sender; + end; + if fmousecapturewidget <> nil then begin + if grab then begin + grabpointer(fmousecapturewidget.window.winid); + end; + setmousewidget(fmousecapturewidget); + end + else begin + if not grab then begin + ungrabpointer; + end; + end; + end; +end; + +function tguiapplication.createform(instanceclass: widgetclassty; + var reference): twidget; +begin + result:= twidget(mseclasses.createmodule(self,instanceclass,reference)); +end; + +procedure tguiapplication.eventloop(const once: boolean = false); + //used in win32 wm_queryendsession and wm_entersizemove +begin + inc(feventlooping); + try + tinternalapplication(self).eventloop(once); + finally + dec(feventlooping); + end; +end; + +procedure tguiapplication.exitloop; //used in win32 cancelshutdown +begin + include(fstate,aps_exitloop); +end; + +procedure tguiapplication.processmessages; +begin + gui_flushgdi; + sys_schedyield; + inherited; +end; + +procedure tguiapplication.invalidated; +begin +// if not (aps_invalidated in fstate) then begin + include(fstate,aps_invalidated); + wakeupmainthread; +// end; +end; + +procedure tguiapplication.showasyncexception(e: exception; + const leadingtext: msestring = ''); +var + mstr1: msestring; +begin + mstr1:= leadingtext + e.Message; + postevent(tasyncmessageevent.create(mstr1,'Exception')); +end; + +procedure tguiapplication.showexception(e: exception; + const leadingtext: msestring = ''); +var + mstr1: msestring; +begin + if not (e is eabort) then begin + if not ismainthread then begin + showasyncexception(e,leadingtext); + end + else begin + mstr1:= leadingtext + e.Message; + showmessage(mstr1,sc(sc_exception){$ifdef FPC},0,lineend+ + getexceptiontext(exceptobject, + exceptaddr,exceptframecount,exceptframes){$endif}); + end; + end; +end; + +procedure tguiapplication.errormessage(const amessage: msestring); +begin + showerror(amessage); +end; + +function tguiapplication.active: boolean; +begin + result:= aps_active in fstate; +end; + +procedure tguiapplication.activate(); +begin + if flastactivewindow <> nil then begin + flastactivewindow.activate(); + end + else begin + if fmainwindow <> nil then begin + fmainwindow.activate(); + end + else begin + if fwindows <> nil then begin + fwindows[0].activate(); + end; + end; + end; +end; + +function tguiapplication.findwindow(aid: winidty; out window: twindow): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(fwindows) do begin + if fwindows[int1].fwindow.id = aid then begin + window:= fwindows[int1]; + result:= true; + exit; + end; + end; + window:= nil; +end; + +function tguiapplication.screenrect(const awindow: twindow = nil): rectty; +var + id: winidty; +begin + id:= 0; + if awindow <> nil then begin + id:= awindow.winid; + end; + result:= gui_getscreenrect(id); +end; + +function tguiapplication.workarea(const awindow: twindow = nil): rectty; +var + id: winidty; +begin + id:= 0; + if awindow = nil then begin + if factivewindow <> nil then begin + id:= factivewindow.winid; + end; + end + else begin + id:= awindow.winid; + end; + result:= gui_getworkarea(id); +end; + +function tguiapplication.ppmm(const awindow: twindow = nil): complexty; +var + id: winidty; +begin + id:= 0; + if awindow = nil then begin + if factivewindow <> nil then begin + id:= factivewindow.winid; + end; + end + else begin + id:= awindow.winid; + end; + gui_getppmm(id,result.re,result.im); +end; + +function tguiapplication.normalactivewindow: twindow; +begin + result:= fwantedactivewindow; + if result = nil then begin + result:= factivewindow; + end; +end; + +function tguiapplication.regularactivewindow: twindow; +begin + result:= factivewindow; + while (result <> nil) and (result.ftransientfor <> nil) do begin + result:= result.ftransientfor; + end; +end; + +function tguiapplication.unreleasedactivewindow: twindow; +begin + result:= factivewindow; + while (result <> nil) and (result.fownerwidget.releasing or + not result.fownerwidget.visible) do begin + result:= result.ftransientfor; + end; +end; + +function tguiapplication.activewidget: twidget; +begin + if factivewindow <> nil then begin + result:= factivewindow.ffocusedwidget; + end + else begin + result:= nil; + end; +end; + +function tguiapplication.activerootwidget: twidget; +begin + if factivewindow <> nil then begin + result:= factivewindow.fownerwidget; + end + else begin + result:= nil; + end; +end; + +function tguiapplication.windowatpos(const pos: pointty): twindow; +var + id: winidty; +begin + id:= gui_windowatpos(pos); + if id <> 0 then begin + findwindow(id,result); + end + else begin + result:= nil; + end; +end; + +function tguiapplication.findwidget(const namepath: string; + out awidget: twidget): boolean; + //false if invalid namepath, '' -> nil and true + //last name = '' -> widget.container +var + str1: string; + bo1: boolean; +begin + result:= true; + awidget:= nil; + if namepath <> '' then begin + bo1:= namepath[length(namepath)] = '.'; + if bo1 then begin + str1:= copy(namepath,1,length(namepath)-1); + end + else begin + str1:= namepath; + end; + awidget:= twidget(findcomponentbynamepath(str1)); + if not (awidget is twidget) then begin + result:= false; + awidget:= nil; + end + else begin + if bo1 then begin + awidget:= awidget.container; + end; + end; + end; +end; + +function tguiapplication.windowar: windowarty; +begin + setlength(result,length(fwindows)); + if result <> nil then begin + move(fwindows[0],result[0],length(result)*sizeof(pointer)); + end; +end; + +function tguiapplication.winidar: winidarty; +var + ar1: windowarty; + int1: integer; +begin + ar1:= windowar; + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= ar1[int1].winid; + end; +end; + +function tguiapplication.getwindows(const index: integer): twindow; +begin + checkarrayindex(fwindows,index); + result:= fwindows[index]; +end; + +function tguiapplication.windowcount: integer; +begin + result:= length(fwindows); +end; + +function cmpwindowvisibility(const l,r): integer; +begin + if (tws_windowvisible in twindow(l).fstate) and + (twindow(l).syscontainer = sywi_none) then begin + if (tws_windowvisible in twindow(r).fstate) and + (twindow(r).syscontainer = sywi_none) then begin + result:= 0; + end + else begin + result:= 1; + end; + end + else begin + if (tws_windowvisible in twindow(r).fstate) and + (twindow(r).syscontainer = sywi_none) then begin + result:= -1; + end + else begin + result:= 0; + end + end; +end; + +procedure tguiapplication.sortzorder(); + //top is last, invisibles and sycontainer windows first +var + ar1: winidarty; + ar2,ar3: integerarty; +begin + ar1:= nil; //compiler warning +{$ifdef mse_debugzorder} + if aps_zordervalid in fstate then begin + debugwriteln('* sortzorder valid'); + end + else begin + debugwrite('* sortzorder'); + end; +{$endif} + if not (aps_zordervalid in fstate) then begin + ar1:= winidar; + {$ifdef mse_debugzorder} + debugwriteln(' n='+inttostr(length(ar1))); + {$endif} + if high(ar1) >= 0 then begin + gui_getzorder(ar1,ar2); + sortarray(ar2,ar3); + orderarray(ar3,pointerarty(fwindows)); + sortarray(pointerarty(fwindows),{$ifdef FPC}@{$endif}cmpwindowvisibility); + end; + include(fstate,aps_zordervalid); + end; +end; + +procedure tguiapplication.packwindowzorder(); +begin + internalpackwindowzorder(); +end; + + +function tguiapplication.bottomwindow: twindow; + //lowest visible window in stackorder, calls sortzorder +var + int1: integer; +begin + sortzorder; + result:= nil; + for int1:= 0 to windowcount-1 do begin + if windows[int1].visible then begin + result:= windows[int1]; + break; + end; + end; +end; + +function tguiapplication.topwindow: twindow; + //highest visible window in stackorder, calls sortzorder +var + int1: integer; +begin + sortzorder; + result:= nil; + for int1:= windowcount-1 downto 0 do begin + if windows[int1].visible then begin + result:= windows[int1]; + break; + end; + end; +end; + +procedure tguiapplication.internalshowhint(const sender: twidget; + const ahintwidget: twidget); +var + window1: twindow; + widgetclass1: widgetclassty; +begin + fhintforwidget:= sender; + with tinternalapplication(self),fhintinfo do begin + window1:= nil; + if (sender <> nil) and ((activewindow = nil) or + (activewindow = sender.window) and activewindow.modal) then begin + window1:= sender.window; + end; + if ahintwidget = nil then begin + if hintwidgetclass <> nil then begin + widgetclass1:= hintwidgetclass; + end + else begin + widgetclass1:= fhintwidgetclass; + end; + if widgetclass1.inheritsfrom(tcustomhintwidget) then begin + fhintwidget:= hintwidgetclassty(widgetclass1).create( + nil,window1,fhintinfo,sender); + end + else begin + fhintwidget:= widgetclass1.create(nil); + end; + end + else begin + fhintwidget:= ahintwidget; + end; + {$ifdef mse_debugzorder} + debugwriteln('** showhint '+tinternalapplication(self).fhintinfo.caption+' '+ + debugwindowinfo(fhintedwidget.window)); + {$endif} + fhintwidget.show(ml_none,window1); + if showtime <> 0 then begin + fhinttimer.interval:= showtime; + fhinttimer.enabled:= true; + end; + end; +end; + +procedure tguiapplication.inithintinfo(var info: hintinfoty; + const ahintedwidget: twidget); +begin + finalize(info); + fillchar(info,sizeof(info),0); + with info do begin + flags:= defaulthintflags; + if (ahintedwidget <> nil) and + (ow_timedhint in ahintedwidget.foptionswidget) then begin + showtime:= defaulthintshowtime; + end + else begin + showtime:= 0; + end; + mouserefpos:= fmouse.pos; + if ahintedwidget <> nil then begin + posrect.pos:= translateclientpoint(mouserefpos,nil,ahintedwidget); + end + else begin + posrect.pos:= mouserefpos + end;; + posrect.cx:= 24; + posrect.cy:= 24; + placement:= cp_bottomleft; + end; +end; + +procedure tguiapplication.initwidgethintinfo(var info: hintinfoty; + const ahintedwidget: twidget); +begin + inithintinfo(info,ahintedwidget); + if ahintedwidget <> nil then begin + info.posrect:= ahintedwidget.widgetrect; + translatewidgetpoint1(info.posrect.pos,ahintedwidget.parentwidget,nil); + end; +end; + +procedure tguiapplication.showhint(const sender: twidget; const hint: msestring; + const aposrect: rectty; const aplacement: captionposty = cp_bottomleft; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags + ); +begin + deactivatehint; + fhintedwidget:= sender; + with fhintinfo do begin + mouserefpos:= fmouse.pos; + flags:= aflags; + caption:= hint; + if ashowtime < 0 then begin + if ow_timedhint in sender.foptionswidget then begin + showtime:= defaulthintshowtime; + end + else begin + showtime:= 0; + end; + end + else begin + showtime:= ashowtime; + end; + posrect:= aposrect; + if sender <> nil then begin + translateclientpoint1(posrect.pos,sender,nil); + end; + placement:= aplacement; + end; + internalshowhint(sender,nil); +end; + +procedure tguiapplication.showhint(const sender: twidget; const hint: msestring; + const apos: pointty; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags + ); +begin + showhint(sender,hint,makerect(apos,nullsize),cp_bottomleft,ashowtime,aflags); +end; + +procedure tguiapplication.showhint(const sender: twidget; + const info: hintinfoty); +begin + with info do begin + if (hfl_show in flags) or (caption <> '') then begin + showhint(sender,caption,posrect,placement,showtime,flags); + end; + end; +end; + +procedure tguiapplication.showhint(const sender: twidget; + const hint: msestring); +var + info: hintinfoty; +begin + inithintinfo(info,sender); + info.caption:= hint; + showhint(sender,info); +end; + +procedure tguiapplication.showhint(const sender: twidget; + const hintwidget: twidget; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags); +begin + deactivatehint; + fhintedwidget:= sender; + inithintinfo(fhintinfo,sender); + with fhintinfo do begin + flags:= aflags; + if ashowtime >= 0 then begin + showtime:= ashowtime; + end; + end; + internalshowhint(sender,hintwidget); +end; + +procedure tguiapplication.hidehint; +begin + deactivatehint; +end; + +function tguiapplication.hintedwidget: twidget; +begin + result:= fhintedwidget; +end; + +function tguiapplication.activehintedwidget: twidget; +begin + if tinternalapplication(self).fhintwidget = nil then begin + result:= nil; + end + else begin + result:= fhintedwidget; + end; +end; + +procedure tguiapplication.help(const sender: tmsecomponent); +begin + with tinternalapplication(self) do begin + fonhelp.doevent(sender); + end; +end; + +procedure tguiapplication.registerhelphandler(const ahandler: helpeventty); +begin + tinternalapplication(self).fonhelp.add(tmethod(ahandler)); +end; + +procedure tguiapplication.unregisterhelphandler(const ahandler: helpeventty); +begin + tinternalapplication(self).fonhelp.remove(tmethod(ahandler)); +end; + +function tguiapplication.activehelpcontext: msestring; +begin + if activewidget = nil then begin + result:= ''; + end + else begin + result:= activewidget.helpcontext; + end; +end; + +function tguiapplication.mousehelpcontext: msestring; +begin + if mousewidget = nil then begin + result:= ''; + end + else begin + result:= mousewidget.helpcontext; + end; +end; + +procedure tguiapplication.activatehint; +begin + deactivatehint; + if (fhintedwidget <> nil) and + ((factivewindow <> nil) or + (ow_appinactivehint in fhintedwidget.optionswidget) and + (fhintedwidget.window.syscontainer <> sywi_none)) then begin + inithintinfo(fhintinfo,fhintedwidget); + fhintedwidget.showhint(fhintedid,fhintinfo); + with fhintinfo do begin + if (hfl_show in flags) or (caption <> '') then begin + translateclientpoint1(posrect.pos,fhintedwidget,nil); + internalshowhint(fhintedwidget,nil); + end; + end; + end; +end; + +procedure tguiapplication.deactivatehint; +begin + with tinternalapplication(self) do begin + freeandnil(fhintwidget); + fhinttimer.enabled:= false; + finalize(fhintinfo); + fhintinfo.flags:= []; + fhintforwidget:= nil; + end; +end; + +procedure tguiapplication.hinttimer(const sender: tobject); +begin + with tinternalapplication(self) do begin + if fhintwidget = nil then begin + activatehint; + end + else begin + deactivatehint; + end; + end; +end; + +procedure tguiapplication.setmainwindow(const Value: twindow); +var + int1: integer; + id: winidty; +begin + fmainwindow:= value; + if value <> nil then begin + if value.fownerwidget.isgroupleader and value.haswinid then begin + id:= value.winid; + for int1:= 0 to high(fwindows) do begin + with fwindows[int1] do begin + if fwindow.id <> 0 then begin + gui_setwindowgroup(fwindow.id,id); + end; + end; + end; + end; + end; +end; + +procedure tguiapplication.dragstarted; //calls dragstarted of all known widgets +var + int1: integer; +begin + for int1:= 0 to high(fwindows) do begin + fwindows[int1].fownerwidget.dragstarted; + end; +end; + +procedure tguiapplication.mouseparkevent; //simulates mouseparkevent +begin + if fmousewidget <> nil then begin + fmousewidget.window.mouseparked; + end; +end; + +procedure tguiapplication.registeronkeypress(const method: keyeventty); +begin + tinternalapplication(self).fonkeypresslist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronkeypress(const method: keyeventty); +begin + tinternalapplication(self).fonkeypresslist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronshortcut(const method: keyeventty); +begin + tinternalapplication(self).fonshortcutlist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronshortcut(const method: keyeventty); +begin + tinternalapplication(self).fonshortcutlist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronwidgetactivechanged( + const method: widgetchangeeventty); +begin + tinternalapplication(self).fonwidgetactivechangelist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronwidgetactivechanged( + const method: widgetchangeeventty); +begin + tinternalapplication(self).fonwidgetactivechangelist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronwindowactivechanged( + const method: windowchangeeventty); +begin + tinternalapplication(self).fonwindowactivechangelist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronwindowactivechanged( + const method: windowchangeeventty); +begin + tinternalapplication(self).fonwindowactivechangelist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronwindowdestroyed( + const method: windoweventty); +begin + tinternalapplication(self).fonwindowdestroyedlist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronwindowdestroyed( + const method: windoweventty); +begin + tinternalapplication(self).fonwindowdestroyedlist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronwiniddestroyed(const method: winideventty); +begin + tinternalapplication(self).fonwiniddestroyedlist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronwiniddestroyed( + const method: winideventty); +begin + tinternalapplication(self).fonwiniddestroyedlist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronapplicationactivechanged( + const method: booleaneventty); +begin + tinternalapplication(self).fonapplicationactivechangedlist.add( + tmethod(method)); +end; + +procedure tguiapplication.unregisteronapplicationactivechanged( + const method: booleaneventty); +begin + tinternalapplication(self).fonapplicationactivechangedlist.remove( + tmethod(method)); +end; + +procedure tguiapplication.registersyseventhandler( + const method: syseventhandlereventty); +begin + tinternalapplication(self).fonsyseventlist.add(tmethod(method)); +end; + +procedure tguiapplication.unregistersyseventhandler( + const method: syseventhandlereventty); +begin + tinternalapplication(self).fonsyseventlist.remove(tmethod(method)); +end; + +procedure tguiapplication.updatecursorshape; + //restores cursorshape of mousewidget +begin + if fclientmousewidget <> nil then begin + fclientmousewidget.updatecursorshape(fmousewidgetpos){(true)}; + end + else begin + widgetcursorshape:= cr_default; + end; +end; + +procedure tguiapplication.setcursorshape(const avalue: cursorshapety); +begin + if fcursorshape <> avalue then begin + fcursorshape:= avalue; //wanted shape + if not waiting then begin + if fthread <> sys_getcurrentthread then begin + mouse.shape:= fcursorshape; //show new cursor immediately + end + else begin + if avalue = cr_default then begin + updatecursorshape; + end; + end; + end; + end; +end; + +procedure tguiapplication.setwidgetcursorshape(const avalue: cursorshapety); +begin + if fwidgetcursorshape <> avalue then begin + fwidgetcursorshape:= avalue; + if (avalue = cr_default) and (fclientmousewidget <> nil) then begin + fclientmousewidget.updatecursorshape(fmousewidgetpos); + end; + end; +end; + +procedure tguiapplication.beginwait(const aprocessmessages: boolean = false); +begin + lock; + try + if fwaitcount = 0 then begin + gui_resetescapepressed; + end; + inc(fwaitcount); + mouse.shape:= cr_wait; + inherited; + finally + unlock; + end; +end; + +procedure tguiapplication.endwait; +var + int1: integer; + po1: ^tmseevent; +begin + lock; + try + if fwaitcount > 0 then begin + dec(fwaitcount); + if (fwaitcount = 0) and (fnoignorewaitevents = 0) then begin + with tinternalapplication(self) do begin + getevents; + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + if (po1^ <> nil) and (po1^.kind in waitignoreevents) then begin + freeandnil(po1^); + end; + inc(po1); + end; + checkcursorshape; + end; + end; + end; + finally + unlock; + end; +end; + +function tguiapplication.waiting: boolean; +begin + result:= fwaitcount > 0; +end; + +function tguiapplication.waitescaped: boolean; +begin + lock; + result:= waiting; + if result then begin + result:= gui_escapepressed; + if not result then begin + tinternalapplication(self).getevents; + result:= gui_escapepressed; + end; + end; + unlock; +end; + +procedure tguiapplication.langchanged; +begin + inherited; + invalidate; +end; + +function tguiapplication.candefocus(const caller: tobject = nil): boolean; +var + int1: integer; +begin + result:= true; + for int1:= 0 to high(fwindows) do begin + if (fwindows[int1] <> caller) and not fwindows[int1].candefocus then begin + result:= false; + break; + end; + end; +end; + +function tguiapplication.terminating: boolean; +begin + result:= aps_terminating in fstate; +end; + +function tguiapplication.deinitializing: boolean; +begin + result:= aps_deinitializing in fstate; +end; + +function tguiapplication.terminate(const sender: twindow = nil): boolean; +var + int1: integer; +begin + result:= false; + include(fstate,aps_terminating); + try + int1:= 0; + while int1 <= high(fwindows) do begin + if (fwindows[int1] <> sender) and + not fwindows[int1].fownerwidget.canparentclose(nil) then begin + exit; + end; + inc(int1); + end; + tinternalapplication(self).doterminate(false); + finally + exclude(fstate,aps_terminating); + end; + result:= terminated; +end; + +procedure tguiapplication.delayedmouseshift(const ashift: pointty); +begin + addpoint1(fdelayedmouseshift,ashift); +end; + +procedure tguiapplication.calcmousewheeldelta(var info: mousewheeleventinfoty; + const fmin,fmax,deltamin,deltamax: real); +var + frequ: real; +begin + if (flastmousewheeltimestamp <> 0) and + (flastmousewheeltimestamp <> info.timestamp) then begin + frequ:= 1000000/(info.timestamp-flastmousewheeltimestamp); //Hz + if frequ > fmax then begin + frequ:= fmax; + end; + if frequ < fmin then begin + frequ:= fmin; + end; + info.delta:= (frequ*(deltamax-deltamin)+(deltamin*fmax-deltamax*fmin))/ + (fmax-fmin); + end + else begin + info.delta:= deltamin; + end; + if info.wheel = mw_down then begin + info.delta:= - info.delta; + end; + info.delta:= info.delta * fmousewheelsensitivity; +end; + +function tguiapplication.mousewheelacceleration(const avalue: real): real; +var + info: mousewheeleventinfoty; +begin + info.timestamp:= flastmousewheeltimestamp + flastmousewheeltimestamp - + flastmousewheeltimestampbefore; + info.wheel:= mw_up; + calcmousewheeldelta(info,fmousewheelfrequmin,fmousewheelfrequmax,1, + fmousewheelaccelerationmax); + result:= avalue * info.delta; +end; + +function tguiapplication.mousewheelacceleration(const avalue: integer): integer; +begin + result:= round(mousewheelacceleration(avalue*1.0)); +end; + +procedure tguiapplication.clearkeyhistory; +begin + include(fstate,aps_clearkeyhistory); +end; + +procedure tguiapplication.invalidate; +var + int1: integer; +begin + for int1:= 0 to high(fwindows) do begin + fwindows[int1].fownerwidget.invalidate; + end; +end; + +procedure tguiapplication.restarthint(const sender: twidget); +begin + with tinternalapplication(self) do begin + if fhintedwidget = sender then begin + deactivatehint; + fhinttimer.interval:= hintdelaytime; + fhinttimer.enabled:= true; + end; + end; +end; + +procedure tguiapplication.receiveevent(const event: tobjectevent); +begin + if (event.kind = ek_user) then begin + with tuserevent(event) do begin + case tag of + cancelwaittag: begin + cancelwait; + end + else begin + if event is tasyncmessageevent then begin + with tasyncmessageevent(event) do begin + showmessage(fmessage,fcaption); + end; + end; + end; + end; + end; + end; + inherited; +end; + +procedure tguiapplication.dowaitidle(var again: boolean); +begin + with tinternalapplication(self) do begin + if fmodalwindow <> fmodalwindowbeforewaitdialog then begin //wait for message window + unregisteronidle({$ifdef FPC}@{$endif}dowaitidle); + processmessages; + fexecuteaction(self); + end; + end; +end; + +procedure tguiapplication.dowaitidle1(var again: boolean); +begin + if fstate * [aps_waitok,aps_waitcanceled,aps_waitidlelock] = [] then begin + include(fstate,aps_waitidlelock); + fidleaction(self,again); + if fstate * [aps_waitok,aps_waitcanceled] = [] then begin + registeronidle({$ifdef FPC}@{$endif}dowaitidle1); +// again:= true; + exclude(fstate,aps_waitidlelock); + end; + end; +end; + +function tguiapplication.waitdialog(const athread: tthreadcomp = nil; + const atext: msestring = ''; + const caption: msestring = ''; + const acancelaction: notifyeventty = nil; + const aexecuteaction: notifyeventty = nil; + const aidleaction: waitidleeventty = nil; + const acontinueaction: notifyeventty = nil): boolean; +var +// res1: modalresultty; + wo1: longword; +begin + if not ismainthread then begin + raise exception.create('Waitdialog must be called from main thread.'); + end; + result:= false; + wo1:= exceptioncount; + if not (aps_waitstarted in fstate) then begin + with tinternalapplication(self) do begin + fmodalwindowbeforewaitdialog:= fmodalwindow; + resetwaitdialog; + include(fstate,aps_waitstarted); + fexecuteaction:= aexecuteaction; + fidleaction:= aidleaction; + if assigned(aexecuteaction) then begin + registeronidle({$ifdef FPC}@{$endif}dowaitidle); + end; + if assigned(aidleaction) then begin + registeronidle({$ifdef FPC}@{$endif}dowaitidle1); + end; + try + if athread <> nil then begin + fonterminatebefore:= athread.onterminate; + athread.onterminate:= {$ifdef FPC}@{$endif}dothreadterminated; + athread.run; + end; + if assigned(acontinueaction) then begin + repeat + until showmessage(atext,caption,[mr_continue,mr_cancel],mr_continue,[],0, + [acontinueaction,acancelaction]) in [mr_cancel,mr_continue]; + end + else begin + repeat + until showmessage(atext,caption,[mr_cancel],mr_cancel,[],0, + [acancelaction]) = mr_cancel; + end; + if wo1 <> exceptioncount then begin + sysutils.abort; + end; + result:= aps_waitok in fstate; + if not result then begin + include(fstate,aps_waitcanceled); + end + else begin + include(fstate,aps_waitterminated); + end; + if athread <> nil then begin + athread.terminate; + athread.waitfor; + end; + finally + unregisteronidle({$ifdef FPC}@{$endif}dowaitidle); + unregisteronidle({$ifdef FPC}@{$endif}dowaitidle1); + exclude(fstate,aps_waitstarted); + if athread <> nil then begin + athread.onterminate:= fonterminatebefore; + end; + end; + end; + end; +end; + +procedure tguiapplication.cancelwait; +begin + if not ismainthread then begin + postevent(tuserevent.create(ievent(self),cancelwaittag)); + end + else begin + with tinternalapplication(self) do begin + if not waitcanceled and (fmodalwindow <> fmodalwindowbeforewaitdialog) and + (fmodalwindow <> nil) then begin + fmodalwindow.modalresult:= mr_cancel; + end; + end; + end; +end; + +procedure tguiapplication.terminatewait; +begin + lock; + include(fstate,aps_waitok); + cancelwait; + unlock; +end; + +procedure tguiapplication.resetwaitdialog; +begin + lock; + fstate:= fstate - [aps_waitstarted,aps_waitcanceled,aps_waitterminated, + aps_waitok,aps_waitidlelock]; + unlock; +end; + +function tguiapplication.waitstarted: boolean; +begin + lock; + result:= aps_waitstarted in fstate; + unlock; +end; + +function tguiapplication.waitcanceled: boolean; +begin + lock; + result:= aps_waitcanceled in fstate; + unlock; +end; + +function tguiapplication.waitterminated: boolean; +begin + lock; + result:= aps_waitterminated in fstate; + unlock; +end; + +procedure tguiapplication.dothreadterminated(const sender: tthreadcomp); +begin + if not waitcanceled then begin + terminatewait; + end; + if assigned(fonterminatebefore) then begin + fonterminatebefore(sender); + end; +end; + +procedure tguiapplication.sysevent(const awindow: winidty; + var aevent: syseventty; var handled: boolean); +begin + tinternalapplication(self).fonsyseventlist.doevent(awindow,aevent,handled); +end; + +procedure tguiapplication.sethighrestimer(const avalue: boolean); +begin + guierror(gui_sethighrestimer(avalue)); +end; + +procedure tguiapplication.dopostevent(const aevent: tmseevent); +begin + if feventlooping = 0 then begin + gui_postevent(aevent); + end + else begin + eventlist.add(aevent); + end; +end; + +procedure tguiapplication.settimer(const us: integer); +begin + if us <= 0 then begin + inherited; + end + else begin + gui_settimer(us); + end; +end; + +procedure tguiapplication.doafterrun; +begin + if not (apo_noautodestroymodules in foptions) then begin + destroyforms(); //zeos lib unloads libraries -> + //forms must be destroyed before unit finalization + end; +end; + +function tguiapplication.idle: boolean; +begin + result:= inherited idle and not gui_hasevent; +end; + +function tguiapplication.shortcutting: boolean; +begin + result:= aps_shortcutting in fstate; +end; + +function tguiapplication.modallevel: integer; +begin + result:= -1; + if flooplevel > 0 then begin + result:= 0; + if fcurrmodalinfo <> nil then begin + result:= fcurrmodalinfo^.level; + end; + end; +end; + +threadvar + gdilocks: int32; + +function tguiapplication.unlockall: integer; +begin + gdilocks:= gdilocks + gdi_unlockall(); + inherited; +end; + +procedure tguiapplication.relockall(count: integer); +begin + inherited; + gdi_relockall(gdilocks); +end; + +procedure tguiapplication.objecteventdestroyed(const sender: tobjectevent); +var + po1: pmodalinfoty; + int1: integer; +begin + if sender.modallevel >= 0 then begin + lock; + po1:= fcurrmodalinfo; + while po1 <> nil do begin + for int1:= high(po1^.events) downto 0 do begin + if po1^.events[int1] = sender then begin + po1^.events[int1]:= nil; + end; + end; + po1:= po1^.parent; + end; + unlock; + end; +end; + +procedure tguiapplication.beginnoignorewaitevents; +begin + interlockedincrement(fnoignorewaitevents); +end; + +procedure tguiapplication.endnoignorewaitevents; +begin + interlockeddecrement(fnoignorewaitevents); +end; + +procedure tguiapplication.internalpackwindowzorder; +begin + //dummy +end; + +procedure tguiapplication.zorderinvalid(); +begin + exclude(fstate,aps_zordervalid); + if gao_forcezorder in foptionsgui then begin + {$ifdef mse_debugzorder} + debugwriteln('*needsupdatewindowstack'); + {$endif} + include(fstate,aps_needsupdatewindowstack); + end; +end; + +function tguiapplication.getforcezorder: boolean; +begin + result:= gao_forcezorder in foptionsgui; +end; + +procedure tguiapplication.setforcezorder(const avalue: boolean); +begin + if avalue then begin + optionsgui:= optionsgui + [gao_forcezorder]; + end + else begin + optionsgui:= optionsgui - [gao_forcezorder]; + end; +end; + +{ tasyncmessageevent } + +constructor tasyncmessageevent.create(const amessage: msestring; + const acaption: msestring); +begin + fmessage:= amessage; + fcaption:= acaption; + inherited create(ievent(application),0); +end; + +{ tmousenterevent } + +constructor tmouseenterevent.create(const winid: winidty; const pos: pointty; + const shiftstate: shiftstatesty; atimestamp: longword); +begin + inherited create(winid,false,mb_none,mw_none,pos,shiftstate,atimestamp); + fkind:= ek_enterwindow; +end; + +{ twidgetshowevent } + +procedure twidgetshowevent.execute; +begin + fmodalresult:= fwidget.show(fmodallevel,ftransientfor); +end; + +{ tcreatewindowevent } + +procedure tcreatewindowevent.execute; +begin + fsender.fcanvas.updatewindowoptions(foptionspo^); + guierror(gui_createwindow(frect,foptionspo^,fwindowpo^),fsender); +end; + +{ tdestroywindowevent } + +procedure tdestroywindowevent.execute; +begin + if fwindowpo <> nil then begin + gui_destroywindow(fwindowpo^); + end; +end; + +{ tfadecolorarrayprop } + +constructor tfadecolorarrayprop.create; +begin + inherited; + fvaluedefault:= defaultfadecolor; +end; + +{ tfadeopacolorarrayprop } + +constructor tfadeopacolorarrayprop.create; +begin + inherited; + fvaluedefault:= defaultfadeopacolor; +end; + +{ treparentevent } + +constructor treparentevent.create(akind: eventkindty; winid: winidty; + aparent: winidty); +begin + fparent:= aparent; + inherited create(ek_reparent,winid); +end; + +initialization + registerapplicationclass(tinternalapplication); +end. diff --git a/mseide-msegui/lib/common/kernel/mseguiglob.pas b/mseide-msegui/lib/common/kernel/mseguiglob.pas new file mode 100644 index 0000000..b7f0905 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseguiglob.pas @@ -0,0 +1,431 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseguiglob; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + classes,mclasses,msegraphutils,msetypes,msekeyboard,mseerr,mseevent,msestrings, + mseglob; +{$ifdef FPC} + +{$endif} + +type + unicharty = longword; + + originty = (org_screen,org_widget,org_paint,org_client,org_inner); + captionposty = (cp_center,cp_rightbottom,cp_right,{cp_rightcenter,}cp_righttop, + cp_topright,cp_top,{cp_topcenter,}cp_topleft, + cp_lefttop,cp_left,{cp_leftcenter,}cp_leftbottom, + cp_bottomleft,cp_bottom,{cp_bottomcenter,}cp_bottomright + ); +const + rightcaptionpos = [cp_rightbottom,cp_right,{cp_rightcenter,}cp_righttop]; + bottomcaptionpos = [cp_bottomleft,cp_bottom,{cp_bottomcenter,}cp_bottomright]; +type + imageposty = (ip_center,ip_centervert, //ip_center -> ip_centerhorz + ip_rightbottom,ip_right,{ip_rightcenter,}ip_righttop, + ip_topright,ip_top,{ip_topcenter,}ip_topleft, + ip_lefttop,ip_left,{ip_leftcenter,}ip_leftbottom, + ip_bottomleft,ip_bottom,{ip_bottomcenter,}ip_bottomright + ); +const + horzimagepos = [ip_center,ip_rightbottom,ip_right,{ip_rightcenter,}ip_righttop, + ip_lefttop,ip_left,{ip_leftcenter,}ip_leftbottom]; + vertimagepos = [ip_centervert,ip_topright,ip_top,{ip_topcenter,}ip_topleft, + ip_bottomleft,ip_bottom,{ip_bottomcenter,}ip_bottomright]; + rightimagepos = [ip_rightbottom,ip_right,ip_righttop]; + bottomimagepos = [ip_bottomleft,ip_bottom,ip_bottomright]; +type + mousebuttonty = (mb_none,mb_left,mb_right,mb_middle); + mousewheelty = (mw_none,mw_up,mw_down); + + shiftstatety = (ss_none,ss_shift,ss_alt,ss_ctrl,ss_left,ss_right,ss_middle, + ss_double,ss_triple, + ss_repeat, //repeat keydown + ss_second); //right modifier keys, numpad + shiftstatesty = set of shiftstatety; + clipboardbufferty = (cbb_clipboard,cbb_primary); +const + keyshiftstatesmask = [ss_shift,ss_alt,ss_ctrl]; + keyshiftstatesrepeatmask = keyshiftstatesmask + [ss_repeat]; + buttonshiftstatesmask = [ss_left,ss_right,ss_middle,ss_double,ss_triple]; + shiftstatesmask = [ss_shift,ss_alt,ss_ctrl,ss_left,ss_right,ss_middle]; + shiftstatesrepeatmask = shiftstatesmask + [ss_repeat]; + +type + mouseeventinfoty = record //same layout as mousewheeleventinfoty! + eventkind: eventkindty; + shiftstate: shiftstatesty; + pos: pointty; + eventstate: eventstatesty; + timestamp: longword; //usec, 0 -> invalid + serial: card32; //0 -> invalid + button: mousebuttonty; + end; + pmouseeventinfoty = ^mouseeventinfoty; + + mousewheeleventinfoty = record //same layout as mouseeventinfoty! + eventkind: eventkindty; + shiftstate: shiftstatesty; + pos: pointty; + eventstate: eventstatesty; + timestamp: longword; //usec, 0 -> invalid + serial: card32; //0 -> invalid + wheel: mousewheelty; + delta: real; + end; + pmousewheeleventinfoty = ^mousewheeleventinfoty; + + moeventinfoty = record + case integer of + 0: (mouse: mouseeventinfoty); + 1: (wheel: mousewheeleventinfoty); + end; + + keyeventinfoty = record + eventkind: eventkindty; + key,keynomod: keyty; + chars: msestring; + shiftstate: shiftstatesty; + eventstate: eventstatesty; + timestamp: longword; //usec + serial: card32; //0 -> invalid + end; + pkeyeventinfoty = ^keyeventinfoty; + + stockfontty = (stf_default, //0 numbers used in tskincontroller + stf_empty, //1 + stf_unicode, //2 + stf_menu, //3 + stf_message, //4 + stf_hint, //5 + stf_report, //6 + stf_proportional,//7 + stf_fixed, //8 + stf_helvetica, //9 + stf_roman, //10 + stf_courier); //11 + defaultfontnamesty = array[stockfontty] of string; + +type + windowoptionty = (wo_popup,wo_message, + wo_desktop,wo_dock,wo_toolbar,wo_menu, + wo_utility,wo_splash,wo_dialog,wo_dropdownmenu, + wo_popupmenu,wo_tooltip,wo_notification,wo_combo, + wo_dnd, + wo_noframe, //uses motif hints on linux + wo_noactivate,wo_overrideredirect, + wo_embedded, + wo_buttonendmodal,wo_groupleader, + wo_taskbar, //win32 only + wo_notaskbar, + wo_windowcentermessage, //showmessage centered in window + wo_sysdnd //activate system drag and drop (xdnd on Linux) + ); + windowoptionsty = set of windowoptionty; + windowtypeoptionty = wo_popup..wo_dnd; + +const + windowtypeoptions = [wo_popup,wo_message, + wo_desktop,wo_dock,wo_toolbar,wo_menu, + wo_utility,wo_splash,wo_dialog,wo_dropdownmenu, + wo_popupmenu,wo_tooltip,wo_notification,wo_combo, + wo_dnd]; + noframewindowtypes = [wo_popup,wo_splash,wo_dropdownmenu,wo_popupmenu, + wo_tooltip,wo_combo,wo_noframe,wo_overrideredirect]; +type + windowposty = (wp_normal,wp_screencentered,wp_screencenteredvirt, + wp_transientforcentered,wp_mainwindowcentered, + wp_minimized,wp_maximized,wp_default, + wp_fullscreen,wp_fullscreenvirt); + windowsizety = (wsi_normal,wsi_minimized,wsi_maximized, + wsi_fullscreen,wsi_fullscreenvirt); +const + windowmaximizedstates = [wp_maximized,wp_fullscreen,wp_fullscreenvirt]; + +type + syswindowty = (sywi_none,sywi_tray); + + paintdevicety = ptruint; + fontty = ptruint; + regionty = ptruint; + pixmapty = ptruint; + windowpty = array[0..7] of pointer; + windowty = record + id: winidty; + platformdata: windowpty; + end; + pwindowty = ^windowty; + + internalwindowoptionspty = array[0..3] of pointer; //buffer + + internalwindowoptionsty = record + parent: winidty; + options: windowoptionsty; + pos: windowposty; + transientfor: winidty; + setgroup: boolean; + groupleader: winidty; + icon,iconmask: pixmapty; + platformdata: internalwindowoptionspty; + end; + pinternalwindowoptionsty = ^internalwindowoptionsty; + +const + defaultppmm = 3; //3 pixel per mm + sizingtol = 2; //+- pixel + sizingwidth = 2*sizingtol; + +const + captiontoimagepos: array[captionposty] of imageposty = ( + //cp_center,cp_rightbottom,cp_right, + ip_center,ip_lefttop, ip_left, + //{cp_rightcenter,}cp_righttop, + {ip_leftcenter,} ip_leftbottom, + //cp_topright, cp_top, cp_topcenter, cp_topleft, + ip_bottomleft,ip_bottom,{ip_bottomcenter,}ip_bottomright, + //cp_lefttop, cp_left, cp_leftcenter, cp_leftbottom, + ip_rightbottom,ip_right,{ip_rightcenter,}ip_righttop, + //cp_bottomleft,cp_bottom,cp_bottomcenter,cp_bottomright + ip_topright, ip_top, {ip_topcenter,} ip_topleft + ); + imagetocaptionpos: array[imageposty] of captionposty = ( + //ip_center,ip_centervert,ip_rightbottom,ip_right, + cp_center,cp_center, cp_lefttop, cp_left, + //{ip_rightcenter,}ip_righttop, + {cp_leftcenter,} cp_leftbottom, + //ip_topright, ip_top, ip_topcenter, ip_topleft, + cp_bottomleft,cp_bottom,{cp_bottomcenter,}cp_bottomright, + //ip_lefttop, ip_left, {ip_leftcenter,} ip_leftbottom, + cp_rightbottom,cp_right,{cp_rightcenter,}cp_righttop, + //ip_bottomleft,ip_bottom,ip_bottomcenter,ip_bottomright + cp_topright, cp_top, {cp_topcenter,} cp_topleft + ); + + swapcaptionpos: array[captionposty] of captionposty = + (//cp_center,cp_rightbottom,cp_right,cp_rightcenter,cp_righttop, + cp_center,cp_leftbottom,cp_left,{cp_leftcenter,}cp_lefttop, + //cp_topright,cp_top,cp_topcenter,cp_topleft, + cp_bottomright,cp_bottom,{cp_bottomcenter,}cp_bottomleft, + //cp_lefttop,cp_left,cp_leftcenter,cp_leftbottom, + cp_righttop,cp_right,{cp_rightcenter,}cp_rightbottom, + //cp_bottomleft,cp_bottom,cp_bottomcenter,cp_bottomright + cp_topleft,cp_top,{cp_topcenter,}cp_topright + ); + simplecaptionpos: array[captionposty] of captionposty = + (//cp_center,cp_rightbottom,cp_right,cp_rightcenter,cp_righttop, + cp_center,cp_right, cp_right,{cp_right,} cp_right, + //cp_topright,cp_top,cp_topcenter,cp_topleft, + cp_top, cp_top,{cp_top,} cp_top, + //cp_lefttop,cp_left,cp_leftcenter,cp_leftbottom, + cp_left, cp_left,{cp_left,} cp_left, + //cp_bottomleft,cp_bottom,cp_bottomcenter,cp_bottomright + cp_bottom, cp_bottom, {cp_bottom,} cp_bottom + ); + + swapimagepos: array[imageposty] of imageposty = + (//ip_center,ip_centervert,ip_rightbottom,ip_right,ip_rightcenter,ip_righttop, + ip_centervert,ip_center,ip_leftbottom,ip_left,{ip_leftcenter,}ip_lefttop, + //ip_topright, ip_top, ip_topcenter,ip_topleft, + ip_bottomright,ip_bottom,{ip_bottomcenter,}ip_bottomleft, + //ip_lefttop, ip_left, ip_leftcenter,ip_leftbottom, + ip_righttop,ip_right,{ip_rightcenter,}ip_rightbottom, + //ip_bottomleft,ip_bottom,ip_bottomcenter,ip_bottomright + ip_topleft,ip_top,{ip_topcenter,}ip_topright + ); + simpleimagepos: array[imageposty] of imageposty = + (//ip_center,ip_centervert,ip_rightbottom,ip_right,ip_rightcenter,ip_righttop, + ip_center,ip_centervert, ip_right, ip_right,{ip_right,}ip_right, + //ip_topright,ip_top,ip_topcenter,ip_topleft, + ip_top, ip_top,{ip_top,} ip_top, + //ip_lefttop,ip_left,ip_leftcenter,ip_leftbottom, + ip_left, ip_left,{ip_left,}ip_left, + //ip_bottomleft,ip_bottom,ip_bottomcenter,ip_bottomright + ip_bottom, ip_bottom,{ip_bottom,}ip_bottom + ); + +type + sysdndactionty = (sdnda_reject,sdnda_accept,sdnda_finished, + sdnda_begin,sdnda_check,sdnda_drop,sdnda_destroyed); + dndactionty = (dnda_copy,dnda_move,dnda_link,dnda_ask,dnda_private); + dndactionsty = set of dndactionty; +const + firstdndaction = dnda_copy; +type + isysdnd = interface(iobjectlink) + procedure cancelsysdnd; + function getformats: msestringarty; + function getformatistext: booleanarty; + function getactions: dndactionsty; + function geteventintf: ievent; + function convertmimedata(const atypeindex: integer): string; + function convertmimetext(const atypeindex: integer): msestring; + end; + +type + guierrorty = (gue_ok,gue_error, + gue_alreadyregistered,gue_notregistered, + gue_postevent,gue_timer, + gue_createwindow,gue_resizewindow,gue_destroywindow, + gue_windoworder,gue_windownotfound, + gue_windowfocus,gue_illegalstate, + gue_recursivemodal,gue_notmodaltop, +// gue_creategc,gue_createprintergc,gue_createmetafilegc, + gue_destroygc, + gue_show,gue_hide,gue_modalwindow, + gue_init,gue_deinit,gue_thread, + gue_nodisplay,gue_nocolormap,gue_notruecolor,gue_flushgdi, + gue_cannotfocus,gue_invalidwidget, + gue_cursor,gue_rootwidget, + gue_inputmanager,gue_inputcontext,gue_timerlist, + {gue_resnotfound,}gue_capturemouse,gue_mousepos, + gue_registerclass,gue_scroll,gue_clipboard, + gue_recursivetransientfor,gue_notlocked, + gue_characterencoding,gue_invalidstream,gue_invalidcanvas, + gue_notimplemented,gue_notsupported,gue_getchildren,gue_reparent, + gue_docktosyswindow, + gue_notraywindow,gue_sendevent,gue_noshelllib, + gue_noglx,gue_novisual,gue_rendercontext, + gue_nodragpending,gue_index,gue_lockcounterror + ); + + egui = class(eerror) + private + function geterror: guierrorty; + public + constructor create(aerror: guierrorty; atext: string); + property error: guierrorty read geterror; + end; + +const + E_NOINTERFACE = longword($80004002); +var + zerolineworkaround: boolean; + //use one pixel line width instead of 0-line, new X11 servers don't + //draw 0-line endpixels reliable + nozorderhandling: boolean; + norestackwindow: boolean; + stackmodebelowworkaround: boolean; + noreconfigurewmwindow: boolean; + toplevelraise: boolean; + nostaticgravity: boolean; +// exabug: boolean; +// nocreatestaticgravity: boolean; + +procedure guierror(error: guierrorty; text: string = ''); overload; +procedure guierror(error: guierrorty; sender: tobject; + text: string = ''); overload; + +implementation + +uses + mseclasses,msestreaming{,mseapplication,msegui,mseguiintf}; + +const + errortexts: array[guierrorty] of string = + ('','Error', + 'Already registered', + 'Not registered', + 'Can not post event', + 'Can not set timer', + 'Can not create window', + 'Can not resize window', + 'Can not destroy window', + 'Can not set window order', + 'Window not found', + 'Can not set window focus', + 'Illegal state', + 'Recursive modal', + 'Not modal top', + 'Can not destroy gc', + 'Can not show window', + 'Can not hide window', + 'Can not show modal window', + 'Init failed', + 'Deinit failed', + 'Can not create thread', + 'Can not connect to display', + 'Can not create colormap', + 'Color mode must be "TrueColor", "DirectColor" or 8 bit "PseudoColor"', + 'Can not flush gdi', + 'Can not focus', + 'Invalid widget', + 'Can not create cursor', + 'Invalid rootwidget', + 'Invalid inputmanager', + 'Invalid inputcontext', + 'Corrupted timerlist', +{ 'Resource not found',} + 'Can not capture mouse', + 'Can not set mouse pos', + 'Can not register class', + 'Can not scroll window', + 'Clipboard error', + 'Recursive transientfor window', + 'Application not locked', + 'Error in character encoding', + 'Invalid stream', + 'Invalid canvas', + 'Not implemented.', + 'Not supported.', + 'Can not get children.', + 'Can not reparent window.', + 'Can not dock to syswindow.', + 'No tray window.', + 'Can not send event.', + 'Problem with shell library.', + 'GLX extension not supported.', + 'Could not find visual.', + 'Could not create a rendering context.', + 'No drag operation pending.', + 'Invalid index.', + 'Lock count error.' + ); + + +procedure guierror(error: guierrorty; text: string); overload; +begin + if error = gue_ok then begin + exit; + end; + raise egui.create(error,text); +end; + +procedure guierror(error: guierrorty; sender: tobject; + text: string = ''); overload; +begin + if error = gue_ok then begin + exit; + end; + if sender <> nil then begin + text:= sender.classname + ' ' + text; + if sender is tcomponent then begin + text:= text + fullcomponentname(tcomponent(sender)); + end; + end; + guierror(error,text); +end; + +{ egui } + +constructor egui.create(aerror: guierrorty; atext: string); +begin + inherited create(integer(aerror),atext,errortexts); +end; + +function egui.geterror: guierrorty; +begin + result:= guierrorty(ferror); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseguiinifini.pas b/mseide-msegui/lib/common/kernel/mseguiinifini.pas new file mode 100644 index 0000000..40abddd --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseguiinifini.pas @@ -0,0 +1,19 @@ +{ MSEgui Copyright (c) 2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseguiinifini; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + msegui,mseapplication; +initialization + application.initialize(); +finalization +end. diff --git a/mseide-msegui/lib/common/kernel/mseguiintf.inc b/mseide-msegui/lib/common/kernel/mseguiintf.inc new file mode 100644 index 0000000..e618b32 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseguiintf.inc @@ -0,0 +1,228 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +function gui_init: guierrorty; +function gui_deinit: guierrorty; +procedure gui_cancelshutdown; +procedure GUI_DEBUGBEGIN; export; +procedure GUI_DEBUGEND; export; + +function gui_registergdi: guierrorty; +function gui_setmainthread: guierrorty; //set mainthread to currentthread +function gui_sethighrestimer(const avalue: boolean): guierrorty; +function gui_grouphideminimizedwindows: boolean; //true for win32 + +//application has to be locked for all following calls +function gui_postevent(event: tmseevent): guierrorty; +function gui_settimer(us: longword): guierrorty; + //send et_timer event after delay of us (micro seconds) + +procedure gui_disconnectmaineventqueue(); //called by application.lock() +procedure gui_connectmaineventqueue(); //called by application.unlock() +function gui_addpollfd(var id: int32; const afd: int32; + const aflags: pollflagsty; + const acallback: pollcallbackty = nil; + const adata: pointer = nil): guierrorty; +function gui_removepollfd(const id: int32): guierrorty; +function gui_setpollfdactive(const id: int32; + const aactive: boolean): guierrorty; + +function gui_hasevent: boolean; //false if no event pending +function gui_getevent: tmseevent; //can be nil +function gui_escapepressed: boolean; +procedure gui_resetescapepressed; + + +function gui_createwindow(const rect: rectty; + var options: internalwindowoptionsty; + var awindow: windowty): guierrorty; +function gui_destroywindow(var awindow: windowty): guierrorty; + //id can be 0 +function gui_getrootwindow(id: winidty = 0): winidty; +function gui_getparentwindow(const awindow: winidty): winidty; +function gui_reparentwindow(const child: winidty; const parent: winidty; + const pos: pointty): guierrorty; +function gui_getchildren(const id: winidty; out children: winidarty): guierrorty; + +function gui_showsysdock(var awindow: windowty): guierrorty; +function gui_hidesysdock(var awindow: windowty): guierrorty; + +function gui_docktosyswindow(var child: windowty; + const akind: syswindowty): guierrorty; + //hides window +//function gui_undockfromsyswindow(var child: windowty): guierrorty; + //hides window + +function gui_traymessage(var awindow: windowty; const message: msestring; + out messageid: longword; + const timeoutms: longword = 0): guierrorty; +function gui_canceltraymessage(var awindow: windowty; + const messageid: longword): guierrorty; +function gui_settrayicon(var awindow: windowty; + const icon,mask: pixmapty): guierrorty; +function gui_settrayhint(var awindow: windowty; + const hint: msestring): guierrorty; + +//function gui_creategc(paintdevice: paintdevicety; const akind: gckindty; +// var gc: gcty; const aprintername: msestring = ''): guierrorty; +//function gui_destroygc(winid: winidty; var gc: gcty): guierrorty; +function gui_flushgdi(const synchronize: boolean = false): guierrorty; +function gui_showwindow(id: winidty): guierrorty; +function gui_hidewindow(id: winidty): guierrorty; +function gui_raisewindow(id: winidty; const topmost: boolean = false): guierrorty; + //windows only +function gui_lowerwindow(id: winidty; const topmost: boolean = false): guierrorty; + //windows only +function gui_stackunderwindow(id: winidty; predecessor: winidty): guierrorty; +function gui_stackoverwindow(id: winidty; predecessor: winidty): guierrorty; +function gui_canstackunder: boolean; //no way found to change stacking order in KDE +function gui_getzorder(const ids: winidarty; out zorders: integerarty): guierrorty; + //topevel -> highest, numbers have not to be contiguous + +function gui_getwindowrect(id: winidty; out rect: rectty): guierrorty; + //screen coordinates +function gui_getwindowpos(id: winidty; out pos: pointty): guierrorty; + //parent window coordinates +function gui_getwindowsize(id: winidty): windowsizety; +function gui_getwindowdesktop(const id: winidty): integer; +function gui_windowvisible(id: winidty): boolean; +function gui_setwindowstate(id: winidty; size: windowsizety; + visible: boolean): guierrorty; +function gui_setwindowcaption(id: winidty; + const caption: msestring): guierrorty; +function gui_setwindowicon(id: winidty; const icon,mask: pixmapty): guierrorty; +function gui_setwindowopacity(id: winidty; const opacity: real): guierrorty; + //empytyreal -> undefined, 0.0-> transparent, 1.1 -> opaque + +function gui_setsizeconstraints(id: winidty; const min,max: sizety): guierrorty; +function gui_reposwindow(id: winidty; const rect: rectty): guierrorty; +function gui_getdecoratedwindowrect(id: winidty; out arect: rectty): guierrorty; +function gui_setdecoratedwindowrect(id: winidty; const rect: rectty; + out clientrect: rectty): guierrorty; +function gui_setembeddedwindowrect(id: winidty; const rect: rectty): guierrorty; +function gui_setwindowfocus(id: winidty): guierrorty; +function gui_setimefocus(var awindow: windowty): guierrorty; +function gui_unsetimefocus(var awindow: windowty): guierrorty; +{ +function gui_windowgetfocus(var awindow: windowty): guierrorty; +function gui_windowloosefocus(var awindow: windowty): guierrorty; +} +function gui_setappfocus(id: winidty): guierrorty; +function gui_minimizeapplication: guierrorty; +function gui_setwindowgroup(id: winidty; group: winidty): guierrorty; +function gui_settransientfor(var awindow: windowty; + const transientfor: winidty): guierrorty; +function gui_movewindowrect(id: winidty; const dist: pointty; + const rect: rectty): guierrorty; +function gui_windowatpos(const pos: pointty): winidty; +function gui_getscreenrect(const id: winidty): rectty; //0 -> virtual screen +function gui_getworkarea(id: winidty): rectty; +procedure gui_getppmm(id: winidty; out appmmwidth,appmmheight: flo64); + //0.0 if not supported + +function gui_setapplicationicon(const icon,mask: pixmapty): guierrorty; +function gui_pidtowinid(const pids: procidarty): winidty; + +function gui_setcursorshape(winid: winidty; shape: cursorshapety): guierrorty; +function gui_getpointerpos: pointty; +function gui_setpointerpos(const pos: pointty): guierrorty; +function gui_movepointer(const dist: pointty): guierrorty; +function gui_grabpointer(id: winidty): guierrorty; +function gui_ungrabpointer: guierrorty; + +function gui_getpixel(const id: winidty; const pos: pointty; + out pixel: pixelty): guierrorty; +function gui_rgbtopixel(rgb: longword): pixelty; +function gui_pixeltorgb(pixel: pixelty): longword; +function gui_graytopixel(gray: byte): pixelty; +function gui_pixeltogray(pixel: pixelty): byte; +//function gui_rgbtocolormappixel(rgb: longword): pixelty; + //neutralizes color in 8bit coler depth +function gui_initcolormap: guierrorty; + +function gui_regiontorects(const aregion: regionty): rectarty; +//procedure gui_changegc(var drawinfo: drawinfoty; const values: gcvaluesty); + +function gui_getdefaultfontnames: defaultfontnamesty; + +function gui_createpixmap(const size: sizety; winid: winidty = 0; + kind: bitmapkindty = bmk_rgb; copyfrom: pixmapty = 0): pixmapty; overload; +function gui_freepixmap(pixmap: pixmapty): gdierrorty; +function gui_getpixmapinfo(var info: pixmapinfoty): gdierrorty; +function gui_createbitmapfromdata(const size: sizety; datapo: pbyte; + msbitfirst: boolean = false; dwordaligned: boolean = false; + bottomup: boolean = false): pixmapty; +function gui_pixmaptoimage(pixmap: pixmapty; out image: imagety; + gchandle: longword): gdierrorty; + //gchandle is used on win32 to select bitmap out of devicecontext, + //can be 0 +function gui_imagetopixmap(const image: imagety; out pixmap: pixmapty; + gchandle: longword): gdierrorty; + //gchandle is used on win32 to select bitmap out of devicecontext, + //can be 0 +function gui_allocimagemem(length: integer): plongwordaty; +procedure gui_freeimagemem(data: plongwordaty); + +//procedure gui_copyarea(var drawinfo: drawinfoty); + +procedure gui_beep; +function gui_copytoclipboard(const value: msestring; + const buffer: clipboardbufferty): guierrorty; +function gui_pastefromclipboard(out value: msestring; + const buffer: clipboardbufferty): guierrorty; +function gui_canpastefromclipboard(const buffer: clipboardbufferty): boolean; + +function gui_sysdnd(const action: sysdndactionty; + const aintf: isysdnd; const arect: rectty; + out aresult: boolean): guierrorty; + //aintf = nil for read actions +function gui_sysdndreaddata(var adata: string; + const typeindex: integer): guierrorty; +function gui_sysdndreadtext(var atext: msestring; + const typeindex: integer): guierrorty; + +function gui_getgdifuncs: pgdifunctionaty; + +(* +procedure gdi_creategc(var drawinfo: drawinfoty); +procedure gdi_destroygc(var drawinfo: drawinfoty); +procedure gdi_changegc(var drawinfo: drawinfoty); +procedure gdi_drawlines(var drawinfo: drawinfoty); +procedure gdi_drawlinesegments(var drawinfo: drawinfoty); +procedure gdi_drawellipse(var drawinfo: drawinfoty); +procedure gdi_drawarc(var drawinfo: drawinfoty); +procedure gdi_fillrect(var drawinfo: drawinfoty); +procedure gdi_fillellipse(var drawinfo: drawinfoty); +procedure gdi_fillarc(var drawinfo: drawinfoty); +procedure gdi_fillpolygon(var drawinfo: drawinfoty); +procedure gdi_drawstring16(var drawinfo: drawinfoty); +procedure gdi_setcliporigin(var drawinfo: drawinfoty); +procedure gdi_createemptyregion(var drawinfo: drawinfoty); +procedure gdi_createrectregion(var drawinfo: drawinfoty); +procedure gdi_createrectsregion(var drawinfo: drawinfoty); +procedure gdi_destroyregion(var drawinfo: drawinfoty); +procedure gdi_copyregion(var drawinfo: drawinfoty); +procedure gdi_moveregion(var drawinfo: drawinfoty); +procedure gdi_regionisempty(var drawinfo: drawinfoty); +procedure gdi_regionclipbox(var drawinfo: drawinfoty); +procedure gdi_regsubrect(var drawinfo: drawinfoty); +procedure gdi_regsubregion(var drawinfo: drawinfoty); +procedure gdi_regaddrect(var drawinfo: drawinfoty); +procedure gdi_regaddregion(var drawinfo: drawinfoty); +procedure gdi_regintersectrect(var drawinfo: drawinfoty); +procedure gdi_regintersectregion(var drawinfo: drawinfoty); +procedure gdi_copyarea(var drawinfo: drawinfoty); +procedure gdi_fonthasglyph(var drawinfo: drawinfoty); +procedure gdi_getfont(var drawinfo: drawinfoty); +procedure gdi_getfonthighres(var drawinfo: drawinfoty); +procedure gdi_freefontdata(var drawinfo: drawinfoty); +procedure gdi_gettext16width(var drawinfo: drawinfoty); +procedure gdi_getchar16widths(var drawinfo: drawinfoty); +procedure gdi_getfontmetrics(var drawinfo: drawinfoty); +*) diff --git a/mseide-msegui/lib/common/kernel/mseguithreadcomp.pas b/mseide-msegui/lib/common/kernel/mseguithreadcomp.pas new file mode 100644 index 0000000..7d4889f --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseguithreadcomp.pas @@ -0,0 +1,37 @@ +{ MSEgui Copyright (c) 2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseguithreadcomp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msethreadcomp,msegui,msetypes{msestrings}; +type + tguithreadcomp = class(tthreadcomp) + private + fdialogtext: msestring; + fdialogcaption: msestring; + public + function runwithwaitdialog: boolean; + //true if not canceled + published + property dialogtext: msestring read fdialogtext write fdialogtext; + property dialogcaption: msestring read fdialogcaption write fdialogcaption; + end; + +implementation + +{ tguithreadcomp } + +function tguithreadcomp.runwithwaitdialog: boolean; +begin + result:= application.waitdialog(self,fdialogtext,fdialogcaption); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseinterfaces.pas b/mseide-msegui/lib/common/kernel/mseinterfaces.pas new file mode 100644 index 0000000..6e0637b --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseinterfaces.pas @@ -0,0 +1,133 @@ +{ MSEgui Copyright (c) 2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseinterfaces; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +//Interface UID's for MSEide+MSEgui +type + mseinterfacenumbers = ( +min_iformdesigner, +min_idbeditfieldlink, +min_idbevent, +min_isqlpropertyeditor, +min_imasterlink, +min_imselocate, +min_idbdata, +min_idbeditinfo, +min_ireccontrol, +min_ipersistentfieldsinfo, +min_idatasetsum, +min_ifieldcomponent, +min_imsefield, +min_igetdscontroller, +min_idbcontroller, +min_ilookupbufferfieldinfo, +min_idbparaminfo, +min_idbcolinfo, +min_iblobconnection, +min_igridwidget, +min_iimagelistinfo, +//min_iimagelistinfo, +min_iifilink, +min_iifiexeclink, +min_iififormlink, +min_iifidialoglink, +min_iifidatalink, +min_iifigridlink, +min_iififieldinfo, +min_iififieldsource, +min_iififieldlinksource, +min_iifidataconnection, +min_iifidbdataconnection, +min_iificlient, +min_iificommand, +min_iifitxaction, +min_iifimodulelink, +min_iactionlink, +min_iactivatorclient, +min_istatfile, +min_ibandparent, +min_idocktarget, +min_itabpage, +min_iassistiveclient, +min_iassistiveserver, +min_irecordfield, +min_irecordvaluefield, +min_idockcontroller, +min_iassistiveclientgrid, +min_iassistiveclientmenu, +min_irichstringprop, +min_iassistiveclientedit, +min_iassistiveclientdata, +min_iassistiveclientgridwidget, +min_igriddatalink +); + +const + miid_iformdesigner = 'AA.mse';{0} + miid_idbeditfieldlink = 'gA.mse';{1} + miid_idbevent = 'QA.mse';{2} + miid_isqlpropertyeditor = 'wA.mse';{3} + miid_imasterlink = 'IA.mse';{4} + miid_imselocate = 'oA.mse';{5} + miid_idbdata = 'YA.mse';{6} + miid_idbeditinfo = '4A.mse';{7} + miid_ireccontrol = 'EA.mse';{8} + miid_ipersistentfieldsinfo = 'kA.mse';{9} + miid_idatasetsum = 'UA.mse';{10} + miid_ifieldcomponent = '0A.mse';{11} + miid_imsefield = 'MA.mse';{12} + miid_igetdscontroller = 'sA.mse';{13} + miid_idbcontroller = 'cA.mse';{14} + miid_ilookupbufferfieldinfo = '8A.mse';{15} + miid_idbparaminfo = 'CA.mse';{16} + miid_idbcolinfo = 'iA.mse';{17} + miid_iblobconnection = 'SA.mse';{18} + miid_igridwidget = 'yA.mse';{19} + miid_iimagelistinfo = 'KA.mse';{20} +// miid_iimagelistinfo = 'qA.mse';{21} + miid_iifilink = 'aA.mse';{22} + miid_iifiexeclink = '6A.mse';{23} + miid_iififormlink = 'GA.mse';{24} + miid_iifidialoglink = 'mA.mse';{25} + miid_iifidatalink = 'WA.mse';{26} + miid_iifigridlink = '2A.mse';{27} + miid_iififieldinfo = 'OA.mse';{28} + miid_iififieldsource = 'uA.mse';{29} + miid_iififieldlinksource = 'eA.mse';{30} + miid_iifidataconnection = '+A.mse';{31} + miid_iifidbdataconnection = 'BA.mse';{32} + miid_iificlient = 'hA.mse';{33} + miid_iificommand = 'RA.mse';{34} + miid_iifitxaction = 'xA.mse';{35} + miid_iifimodulelink = 'JA.mse';{36} + miid_iactionlink = 'pA.mse';{37} + miid_iactivatorclient = 'ZA.mse';{38} + miid_istatfile = '5A.mse';{39} + miid_ibandparent = 'FA.mse';{40} + miid_idocktarget = 'lA.mse';{41} + miid_itabpage = 'VA.mse';{42} + miid_idbdispfieldlink = '1A.mse';{43} + miid_iassistiveclient = 'NA.mse';{44} + miid_iassistiveserver = 'tA.mse';{45} + miid_irecordfield = 'dA.mse';{46} + miid_irecordvaluefield = '9A.mse';{47} + miid_idockcontroller = 'DA.mse';{48} + miid_iassistiveclientgrid = 'jA.mse';{49} + miid_iassistiveclientmenu = 'TA.mse';{50} + miid_irichstringprop = 'zA.mse';{51} + miid_iassistiveclientedit = 'LA.mse';{52} + miid_iassistiveclientdata = 'rA.mse';{53} + miid_iassistiveclientgridwidget = + 'bA.mse';{54} + miid_iggriddatalink = '7A.mse';{55} +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/msekeyboard.pas b/mseide-msegui/lib/common/kernel/msekeyboard.pas new file mode 100644 index 0000000..a3c9127 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msekeyboard.pas @@ -0,0 +1,327 @@ +{ MSEgui Copyright (c) 1999-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msekeyboard; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msetypes{,msestrings}; +type + keyty = ( + key_none = $0000, + key_Space = $0020, // 7 bit printable ASCII +{$ifdef FPC}{$notes off}{$endif} + key_Any = Key_Space, +{$ifdef FPC}{$notes on}{$endif} + key_Exclam = $0021, + key_QuoteDbl = $0022, + key_NumberSign = $0023, + key_Dollar = $0024, + key_Percent = $0025, + key_Ampersand = $0026, + key_Apostrophe = $0027, + key_ParenLeft = $0028, + key_ParenRight = $0029, + key_Asterisk = $002a, + key_Plus = $002b, + key_Comma = $002c, + key_Minus = $002d, + key_Period = $002e, + key_Slash = $002f, + key_0 = $0030, + key_1 = $0031, + key_2 = $0032, + key_3 = $0033, + key_4 = $0034, + key_5 = $0035, + key_6 = $0036, + key_7 = $0037, + key_8 = $0038, + key_9 = $0039, + key_Colon = $003a, + key_Semicolon = $003b, + key_Less = $003c, + key_Equal = $003d, + key_Greater = $003e, + key_Question = $003f, + key_At = $0040, + key_A = $0041, + key_B = $0042, + key_C = $0043, + key_D = $0044, + key_E = $0045, + key_F = $0046, + key_G = $0047, + key_H = $0048, + key_I = $0049, + key_J = $004a, + key_K = $004b, + key_L = $004c, + key_M = $004d, + key_N = $004e, + key_O = $004f, + key_P = $0050, + key_Q = $0051, + key_R = $0052, + key_S = $0053, + key_T = $0054, + key_U = $0055, + key_V = $0056, + key_W = $0057, + key_X = $0058, + key_Y = $0059, + key_Z = $005a, + key_BracketLeft = $005b, + key_Backslash = $005c, + key_BracketRight = $005d, + key_AsciiCircum = $005e, + key_Underscore = $005f, + key_QuoteLeft = $0060, + key_BraceLeft = $007b, + key_Bar = $007c, + key_BraceRight = $007d, + key_AsciiTilde = $007e, + + // Latin 1 codes adapted from X: keysymdef.h,v 1.21 94/08/28 16:17:06 + + key_nobreakspace = $00a0, + key_exclamdown = $00a1, + key_cent = $00a2, + key_sterling = $00a3, + key_currency = $00a4, + key_yen = $00a5, + key_brokenbar = $00a6, + key_section = $00a7, + key_diaeresis = $00a8, + key_copyright = $00a9, + key_ordfeminine = $00aa, + key_guillemotleft = $00ab, // left angle quotation mark + key_notsign = $00ac, + key_hyphen = $00ad, + key_registered = $00ae, + key_macron = $00af, + key_degree = $00b0, + key_plusminus = $00b1, + key_twosuperior = $00b2, + key_threesuperior = $00b3, + key_acute = $00b4, + key_mu = $00b5, + key_paragraph = $00b6, + key_periodcentered = $00b7, + key_cedilla = $00b8, + key_onesuperior = $00b9, + key_masculine = $00ba, + key_guillemotright = $00bb, // right angle quotation mark + key_onequarter = $00bc, + key_onehalf = $00bd, + key_threequarters = $00be, + key_questiondown = $00bf, + key_Agrave = $00c0, + key_Aacute = $00c1, + key_Acircumflex = $00c2, + key_Atilde = $00c3, + key_Adiaeresis = $00c4, + key_Aring = $00c5, + key_AE = $00c6, + key_Ccedilla = $00c7, + key_Egrave = $00c8, + key_Eacute = $00c9, + key_Ecircumflex = $00ca, + key_Ediaeresis = $00cb, + key_Igrave = $00cc, + key_Iacute = $00cd, + key_Icircumflex = $00ce, + key_Idiaeresis = $00cf, + key_ETH = $00d0, + key_Ntilde = $00d1, + key_Ograve = $00d2, + key_Oacute = $00d3, + key_Ocircumflex = $00d4, + key_Otilde = $00d5, + key_Odiaeresis = $00d6, +// key_multiply = $00d7, -> key_asterisk + key_Ooblique = $00d8, + key_Ugrave = $00d9, + key_Uacute = $00da, + key_Ucircumflex = $00db, + key_Udiaeresis = $00dc, + key_Yacute = $00dd, + key_THORN = $00de, + key_ssharp = $00df, + key_agrave_lower = $00e0, + key_aacute_lower = $00e1, + key_acircumflex_lower = $00e2, + key_atilde_lower = $00e3, + key_adiaeresis_lower = $00e4, + key_aring_lower = $00e5, + key_ae_lower = $00e6, + key_ccedilla_lower = $00e7, + key_egrave_lower = $00e8, + key_eacute_lower = $00e9, + key_ecircumflex_lower = $00ea, + key_ediaeresis_lower = $00eb, + key_igrave_lower = $00ec, + key_iacute_lower = $00ed, + key_icircumflex_lower = $00ee, + key_idiaeresis_lower = $00ef, + key_eth_lower = $00f0, + key_ntilde_lower = $00f1, + key_ograve_lower = $00f2, + key_oacute_lower = $00f3, + key_ocircumflex_lower = $00f4, + key_otilde_lower = $00f5, + key_odiaeresis_lower = $00f6, + key_division = $00f7, + key_oslash = $00f8, + key_ugrave_lower = $00f9, + key_uacute_lower = $00fa, + key_ucircumflex_lower = $00fb, + key_udiaeresis_lower = $00fc, + key_yacute_lower = $00fd, + key_thorn_lower = $00fe, + key_ydiaeresis = $00ff, + + key_Escape = $0100, // misc keys + key_Tab = $0101, + key_Backtab = $0102, + key_Backspace = $0103, + key_Return = $0104, + // key_Enter = $0105, -> key_return + key_Insert = $0106, + key_Delete = $0107, + key_Pause = $0108, + key_Print = $0109, + key_SysReq = $010a, + key_Home = $0110, // cursor movement + key_End = $0111, + key_Left = $0112, + key_Up = $0113, + key_Right = $0114, + key_Down = $0115, + key_Prior = $0116, + Key_PageUp = Key_Prior, + key_Next = $0117, + Key_PageDown = Key_Next, + key_clear = $0118, + key_decimal = $0119, + + key_Shift = $0120, // modifiers + key_Control = $0121, + key_Meta = $0122, + key_Alt = $0123, + key_CapsLock = $0124, + key_NumLock = $0125, + key_ScrollLock = $0126, + key_AltGr = $0127, + key_F1 = $0130, // function keys + key_F2 = $0131, + key_F3 = $0132, + key_F4 = $0133, + key_F5 = $0134, + key_F6 = $0135, + key_F7 = $0136, + key_F8 = $0137, + key_F9 = $0138, + key_F10 = $0139, + key_F11 = $013a, + key_F12 = $013b, + key_F13 = $013c, + key_F14 = $013d, + key_F15 = $013e, + key_F16 = $013f, + key_F17 = $0140, + key_F18 = $0141, + key_F19 = $0142, + key_F20 = $0143, + key_F21 = $0144, + key_F22 = $0145, + key_F23 = $0146, + key_F24 = $0147, + key_F25 = $0148, // F25 .. F35 only on X11 + key_F26 = $0149, + key_F27 = $014a, + key_F28 = $014b, + key_F29 = $014c, + key_F30 = $014d, + key_F31 = $014e, + key_F32 = $014f, + key_F33 = $0150, + key_F34 = $0151, + key_F35 = $0152, + key_Super = $0153, // extra keys +// key_Super_R = $0154, + key_Menu = $0155, + key_Hyper = $0156, +// key_Hyper_R = $0157, + key_Help = $0158, + +// key_wheelup = $1800, +// key_wheeldown = $1801, + + key_unknown = $ffff + ); +const + key_modpad = $0800; //ored for shortcut in taction + key_modshift = $2000; + key_modctrl = $4000; + key_modshiftctrl = $6000; + key_modalt = $8000; + key_modshiftalt = $a000; + key_modpadshift = $2000 or key_modpad; + key_modpadctrl = $4000 or key_modpad; + key_modpadshiftctrl = $6000 or key_modpad; + key_modpadalt = $8000 or key_modpad; + key_modpadshiftalt = $a000 or key_modpad; + + padcharkeynames: array[key_asterisk..key_slash] of msestring = + ('Asterisk','Plus','Comma','Minus','Period','Slash'); + padspecialkeynames: array[key_decimal..key_decimal] of msestring = + ('Decimal'); + misckeynames: array[key_escape..key_sysreq] of msestring = + ('Escape','Tab','Backtab','Backspace','Return','Enter', + 'Insert','Delete','Pause','Print','SysReq'); + cursorkeynames: array[key_home..key_pagedown] of msestring = + ('Home','End','Left','Up','Right','Down','PageUp','PageDown'); + shortmisckeynames: array[key_escape..key_sysreq] of msestring = + ('Esc','Tab','Backtab','Back','Ret','Enter', + 'Ins','Del','Pause','Print','SysReq'); + shortcursorkeynames: array[key_home..key_pagedown] of msestring = + ('Home','End','Left','Up','Right','Down','PgUp','PgDown'); +type + specialshortcutty = (sso_menu,sso_help,sso_clear); +const + specialkeys: array[specialshortcutty] of keyty = (key_menu,key_help,key_clear); + specialkeynames: array[specialshortcutty] of msestring = ('Menu','Help','Clear'); + spacekeyname = 'Space'; + +function keytomsechar(key: keyty): msechar; //only 0..9, a..z + +implementation + +function keytomsechar(key: keyty): msechar; +begin + if (key >= key_0) and (key <= key_9) then begin + result:= msechar(ord(msechar('0')) + ord(key)-ord(key_0)); + end + else begin + if (key >= key_a) and (key <= key_z) then begin + result:= msechar(ord(msechar('a')) + ord(key)-ord(key_a)); + end + else begin + result:= #0; + end; + end; +end; + +end. + + + diff --git a/mseide-msegui/lib/common/kernel/mselibc.pas b/mseide-msegui/lib/common/kernel/mselibc.pas new file mode 100644 index 0000000..cd6bee5 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mselibc.pas @@ -0,0 +1,3282 @@ +unit mselibc; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + {$ifdef FPC}initc,{$endif}msectypes{$ifndef FPC},msetypes{$endif}; + +//todo: remove not used definitions, use msectypes + +const +{$ifdef FPC} + clib = 'c'; + threadslib = 'pthread'; +{$else} + clib = 'libc.so.6'; + threadslib = 'libpthread.so.0'; +{$endif} + +{$ifdef linux} + shmlib = 'rt'; +{$else} + shmlib = clib; +{$endif} + +{$packrecords c} + +type + +//from bits/typesizes.h + +{$ifdef linux} + __dev_t = __UQUAD_TYPE; +{$else} + __dev_t = cuint32; +{$endif} + __uid_t = __U32_TYPE; + __gid_t = __U32_TYPE; + __ino_t = __ULONGWORD_TYPE; + __ino64_t = __UQUAD_TYPE; + __mode_t = __U32_TYPE; + __nlink_t = __UWORD_TYPE; + __off_t = __SLONGWORD_TYPE; + __off64_t = __SQUAD_TYPE; + __pid_t = __S32_TYPE; + __rlim_t = __ULONGWORD_TYPE; + __rlim64_t = __UQUAD_TYPE; + __blkcnt_t = __SLONGWORD_TYPE; + __blkcnt64_t = __SQUAD_TYPE; + __fsblkcnt_t = __ULONGWORD_TYPE; + __fsblkcnt64_t = __UQUAD_TYPE; + __fsfilcnt_t = __ULONGWORD_TYPE; + __fsfilcnt64_t = __UQUAD_TYPE; + __id_t = __U32_TYPE; + __clock_t = __SLONGWORD_TYPE; +{$ifdef linux} + __time_t = __SLONGWORD_TYPE; +{$else} + {$ifdef CPU64} + __time_t = cint64; + {$else} + __time_t = cint32; + {$endif} +{$endif} + __useconds_t = __U32_TYPE; + __suseconds_t = __SLONGWORD_TYPE; + __daddr_t = __S32_TYPE; + __swblk_t = __SLONGWORD_TYPE; + __key_t = __S32_TYPE; + __clockid_t = __S32_TYPE; + __timer_t = pointer; //void *; + __blksize_t = __SLONGWORD_TYPE; + __fsid_t = record + __val: array[0..1] of longint; + end; +// __struct { int __val[2]; }; + __ssize_t = __SWORD_TYPE; + + __fd_mask = __ULONGWORD_TYPE; //dWord; + {$ifdef CPU64} + __ipc_pid_t = integer; + {$else} + __ipc_pid_t = word; + {$endif} + __caddr_t = ^char; + +type + __ptr_t = Pointer; + P__ptr_t = ^__ptr_t; + ptrdiff_t = Integer; + __long_double_t = Extended; + P__long_double_t = ^__long_double_t; +// size_t = longword; + Psize_t = ^size_t; +// UInt64 = 0..High(Int64); // Must be unsigned. + wchar_t = widechar; + Pwchar_t = ^wchar_t; + PPwchar_t = ^Pwchar_t; + PPByte = ^PByte; + PPPChar = ^PPChar; + + __u_char = byte; + __u_short = word; + __u_int = dword; + __u_long = dword; + __u_quad_t = qword; + __quad_t = int64; + + __int8_t = char; + __uint8_t = byte; + __int16_t = smallint; + __uint16_t = word; + __int32_t = longint; + __uint32_t = dword; + __int64_t = Int64; + __uint64_t = Qword; + + __qaddr_t = __quad_t; +// __dev_t = __u_quad_t; +// __uid_t = __u_int; +// __gid_t = __u_int; +// __ino_t = __u_long; +// __mode_t = __u_int; +// __nlink_t = __u_int; +// __off_t = longint; + __loff_t = __quad_t; +// __pid_t = longint; +// __ssize_t = longint; +// __rlim_t = __u_long; +// __rlim64_t = __u_quad_t; +// __id_t = __u_int; +// __fsid_t = record +// __val : array[0..1] of longint; +// end; + +{ + __daddr_t = longint; + __caddr_t = char; + __time_t = longint; + __useconds_t = dword; + __suseconds_t = longint; + __swblk_t = longint; + __clock_t = longint; + __clockid_t = longint; + __timer_t = longint; + __fd_mask = dWord; +} + int64_t = Int64; + uint8_t = byte; + + uint16_t = word; + uint32_t = dword; + uint64_t = qword; + int_least8_t = char; + int_least16_t = smallint; + int_least32_t = longint; + int_least64_t = int64; + uint_least8_t = byte; + uint_least16_t = word; + uint_least32_t = dword; + uint_least64_t = qword; + + int_fast8_t = shortint; + int_fast16_t = longint; + int_fast32_t = longint; + int_fast64_t = int64; + uint_fast8_t = byte; + + uint_fast16_t = dword; + uint_fast32_t = dword; + uint_fast64_t = qword; + +// intptr_t = longint; +// uintptr_t = dword; + intptr_t = ptrint; + uintptr_t = ptruint; + intmax_t = Int64; + uintmax_t = QWord; + + timespec = record + tv_sec: __time_t; + tv_nsec: clong; + end; + + TTimeSpec = timespec; + PTimeSpec = ^TTimeSpec; + +//ioctrl +const + TCGETS = $5401; + TCSETS = $5402; + TCSETSW = $5403; + TCSETSF = $5404; + TCGETA = $5405; + TCSETA = $5406; + TCSETAW = $5407; + TCSETAF = $5408; + TCSBRK = $5409; + TCXONC = $540A; + TCFLSH = $540B; + TIOCEXCL = $540C; + TIOCNXCL = $540D; + TIOCSCTTY = $540E; + TIOCGPGRP = $540F; + TIOCSPGRP = $5410; + TIOCOUTQ = $5411; + TIOCSTI = $5412; + TIOCGWINSZ = $5413; + TIOCSWINSZ = $5414; + TIOCMGET = $5415; + TIOCMBIS = $5416; + TIOCMBIC = $5417; + TIOCMSET = $5418; + TIOCGSOFTCAR = $5419; + TIOCSSOFTCAR = $541A; + FIONREAD = $541B; + TIOCINQ = FIONREAD; + TIOCLINUX = $541C; + TIOCCONS = $541D; + TIOCGSERIAL = $541E; + TIOCSSERIAL = $541F; + TIOCPKT = $5420; + FIONBIO = $5421; + TIOCNOTTY = $5422; + TIOCSETD = $5423; + TIOCGETD = $5424; + TCSBRKP = $5425; + TIOCTTYGSTRUCT = $5426; + TIOCSBRK = $5427; + TIOCCBRK = $5428; + TIOCGSID = $5429; + +const + FIONCLEX = $5450; + FIOCLEX = $5451; + FIOASYNC = $5452; + TIOCSERCONFIG = $5453; + TIOCSERGWILD = $5454; + TIOCSERSWILD = $5455; + TIOCGLCKTRMIOS = $5456; + TIOCSLCKTRMIOS = $5457; + TIOCSERGSTRUCT = $5458; + TIOCSERGETLSR = $5459; + TIOCSERGETMULTI = $545A; + TIOCSERSETMULTI = $545B; + TIOCMIWAIT = $545C; + TIOCGICOUNT = $545D; + TIOCGHAYESESP = $545E; + TIOCSHAYESESP = $545F; + TIOCPKT_DATA = 0; + TIOCPKT_FLUSHREAD = 1; + TIOCPKT_FLUSHWRITE = 2; + TIOCPKT_STOP = 4; + TIOCPKT_START = 8; + TIOCPKT_NOSTOP = 16; + TIOCPKT_DOSTOP = 32; + TIOCSER_TEMT = $01; + +const + {$ifdef linux} + EPERM = 1; + ENOENT = 2; + ESRCH = 3; + EINTR = 4; + EIO = 5; + ENXIO = 6; + E2BIG = 7; + ENOEXEC = 8; + EBADF = 9; + ECHILD = 10; + EAGAIN = 11; + ENOMEM = 12; + EACCES = 13; + EFAULT = 14; + ENOTBLK = 15; + EBUSY = 16; + EEXIST = 17; + EXDEV = 18; + ENODEV = 19; + ENOTDIR = 20; + EISDIR = 21; + EINVAL = 22; + ENFILE = 23; + EMFILE = 24; + ENOTTY = 25; + ETXTBSY = 26; + EFBIG = 27; + ENOSPC = 28; + ESPIPE = 29; + EROFS = 30; + EMLINK = 31; + EPIPE = 32; + EDOM = 33; + ERANGE = 34; + EDEADLK = 35; + ENAMETOOLONG = 36; + ENOLCK = 37; + ENOSYS = 38; + ENOTEMPTY = 39; + ELOOP = 40; + EWOULDBLOCK = EAGAIN; + ENOMSG = 42; + EIDRM = 43; + ECHRNG = 44; + EL2NSYNC = 45; + EL3HLT = 46; + EL3RST = 47; + ELNRNG = 48; + EUNATCH = 49; + ENOCSI = 50; + EL2HLT = 51; + EBADE = 52; + EBADR = 53; + EXFULL = 54; + ENOANO = 55; + EBADRQC = 56; + EBADSLT = 57; + EDEADLOCK = EDEADLK; + EBFONT = 59; + ENOSTR = 60; + ENODATA = 61; + ETIME = 62; + ENOSR = 63; + ENONET = 64; + ENOPKG = 65; + EREMOTE = 66; + ENOLINK = 67; + EADV = 68; + ESRMNT = 69; + ECOMM = 70; + EPROTO = 71; + EMULTIHOP = 72; + EDOTDOT = 73; + EBADMSG = 74; + EOVERFLOW = 75; + ENOTUNIQ = 76; + EBADFD = 77; + EREMCHG = 78; + ELIBACC = 79; + ELIBBAD = 80; + ELIBSCN = 81; + ELIBMAX = 82; + ELIBEXEC = 83; + EILSEQ = 84; + ERESTART = 85; + ESTRPIPE = 86; + EUSERS = 87; + ENOTSOCK = 88; + EDESTADDRREQ = 89; + EMSGSIZE = 90; + EPROTOTYPE = 91; + ENOPROTOOPT = 92; + EPROTONOSUPPORT = 93; + ESOCKTNOSUPPORT = 94; + EOPNOTSUPP = 95; + EPFNOSUPPORT = 96; + EAFNOSUPPORT = 97; + EADDRINUSE = 98; + EADDRNOTAVAIL = 99; + ENETDOWN = 100; + ENETUNREACH = 101; + ENETRESET = 102; + ECONNABORTED = 103; + ECONNRESET = 104; + ENOBUFS = 105; + EISCONN = 106; + ENOTCONN = 107; + ESHUTDOWN = 108; + ETOOMANYREFS = 109; + ETIMEDOUT = 110; + ECONNREFUSED = 111; + EHOSTDOWN = 112; + EHOSTUNREACH = 113; + EALREADY = 114; + EINPROGRESS = 115; + ESTALE = 116; + EUCLEAN = 117; + ENOTNAM = 118; + ENAVAIL = 119; + EISNAM = 120; + EREMOTEIO = 121; + EDQUOT = 122; + ENOMEDIUM = 123; + EMEDIUMTYPE = 124; + + {$else} + + EPERM = 1; //* Operation not permitted */ + ENOENT = 2; //* No such file or directory */ + ESRCH = 3; //* No such process */ + EINTR = 4; //* Interrupted system call */ + EIO = 5; //* Input/output error */ + ENXIO = 6; //* Device not configured */ + E2BIG = 7; //* Argument list too long */ + ENOEXEC = 8; //* Exec format error */ + EBADF = 9; //* Bad file descriptor */ + ECHILD = 10; //* No child processes */ + EDEADLK = 11; //* Resource deadlock avoided */ + //* 11 was EAGAIN */ + ENOMEM = 12; //* Cannot allocate memory */ + EACCES = 13; //* Permission denied */ + EFAULT = 14; //* Bad address */ +{$ifndef _POSIX_SOURCE} + ENOTBLK = 15; //* Block device required */ +{$endif} + EBUSY = 16; //* Device busy */ + EEXIST = 17; //* File exists */ + EXDEV = 18; //* Cross-device link */ + ENODEV = 19; //* Operation not supported by device */ + ENOTDIR = 20; //* Not a directory */ + EISDIR = 21; //* Is a directory */ + EINVAL = 22; //* Invalid argument */ + ENFILE = 23; //* Too many open files in system */ + EMFILE = 24; //* Too many open files */ + ENOTTY = 25; //* Inappropriate ioctl for device */ +{$ifndef _POSIX_SOURCE} + ETXTBSY = 26; //* Text file busy */ +{$endif} + EFBIG = 27; //* File too large */ + ENOSPC = 28; //* No space left on device */ + ESPIPE = 29; //* Illegal seek */ + EROFS = 30; //* Read-only filesystem */ + EMLINK = 31; //* Too many links */ + EPIPE = 32; //* Broken pipe */ + +//* math software */ + EDOM = 33; //* Numerical argument out of domain */ + ERANGE = 34; //* Result too large */ + +//* non-blocking and interrupt i/o */ + EAGAIN = 35; //* Resource temporarily unavailable */ +{$ifndef _POSIX_SOURCE} + EWOULDBLOCK = EAGAIN; //* Operation would block */ + EINPROGRESS = 36; //* Operation now in progress */ + EALREADY = 37; //* Operation already in progress */ + +//* ipc/network software -- argument errors */ + ENOTSOCK = 38; //* Socket operation on non-socket */ + EDESTADDRREQ = 39; //* Destination address required */ + EMSGSIZE = 40; //* Message too long */ + EPROTOTYPE = 41; //* Protocol wrong type for socket */ + ENOPROTOOPT = 42; //* Protocol not available */ + EPROTONOSUPPORT = 43; //* Protocol not supported */ + ESOCKTNOSUPPORT = 44; //* Socket type not supported */ + EOPNOTSUPP = 45; //* Operation not supported */ + ENOTSUP = EOPNOTSUPP; //* Operation not supported */ + EPFNOSUPPORT = 46; //* Protocol family not supported */ + EAFNOSUPPORT = 47; //* Address family not supported by protocol family */ + EADDRINUSE = 48; //* Address already in use */ + EADDRNOTAVAIL = 49; //* Can't assign requested address */ + +//* ipc/network software -- operational errors */ + ENETDOWN = 50; //* Network is down */ + ENETUNREACH = 51; //* Network is unreachable */ + ENETRESET = 52; //* Network dropped connection on reset */ + ECONNABORTED = 53; //* Software caused connection abort */ + ECONNRESET = 54; //* Connection reset by peer */ + ENOBUFS = 55; //* No buffer space available */ + EISCONN = 56; //* Socket is already connected */ + ENOTCONN = 57; //* Socket is not connected */ + ESHUTDOWN = 58; //* Can't send after socket shutdown */ + ETOOMANYREFS = 59; //* Too many references: can't splice */ + ETIMEDOUT = 60; //* Operation timed out */ + ECONNREFUSED = 61; //* Connection refused */ + + ELOOP = 62; //* Too many levels of symbolic links */ +{$endif /* _POSIX_SOURCE */} + ENAMETOOLONG = 63; //* File name too long */ + +//* should be rearranged */ +{$ifndef _POSIX_SOURCE} + EHOSTDOWN = 64; //* Host is down */ + EHOSTUNREACH = 65; //* No route to host */ +{$endif /* _POSIX_SOURCE */} + ENOTEMPTY = 66; //* Directory not empty */ + +//* quotas & mush */ +{$ifndef _POSIX_SOURCE} + EPROCLIM = 67; //* Too many processes */ + EUSERS = 68; //* Too many users */ + EDQUOT = 69; //* Disc quota exceeded */ + +//* Network File System */ + ESTALE = 70; //* Stale NFS file handle */ + EREMOTE = 71; //* Too many levels of remote in path */ + EBADRPC = 72; //* RPC struct is bad */ + ERPCMISMATCH = 73; //* RPC version wrong */ + EPROGUNAVAIL = 74; //* RPC prog. not avail */ + EPROGMISMATCH = 75; //* Program version wrong */ + EPROCUNAVAIL = 76; //* Bad procedure for program */ +{$endif /* _POSIX_SOURCE */} + + ENOLCK = 77; //* No locks available */ + ENOSYS = 78; //* Function not implemented */ + +{$ifndef _POSIX_SOURCE} + EFTYPE = 79; //* Inappropriate file type or format */ + EAUTH = 80; //* Authentication error */ + ENEEDAUTH = 81; //* Need authenticator */ + EIDRM = 82; //* Identifier removed */ + ENOMSG = 83; //* No message of desired type */ + EOVERFLOW = 84; //* Value too large to be stored in data type */ + ECANCELED = 85; //* Operation canceled */ + EILSEQ = 86; //* Illegal byte sequence */ + ENOATTR = 87; //* Attribute not found */ + + EDOOFUS = 88; //* Programming error */ +{$endif /* _POSIX_SOURCE */} + + EBADMSG = 89; //* Bad message */ + EMULTIHOP = 90; //* Multihop attempted */ + ENOLINK = 91; //* Link has been severed */ + EPROTO = 92; //* Protocol error */ + +{$ifndef _POSIX_SOURCE} + ENOTCAPABLE = 93; //* Capabilities insufficient */ + ECAPMODE = 94; //* Not permitted in capability mode */ + ENOTRECOVERABLE = 95; //* State not recoverable */ + EOWNERDEAD = 96; //* Previous owner died */ +{$endif /* _POSIX_SOURCE */} + +{$ifndef _POSIX_SOURCE} + ELAST = 96; //* Must be equal largest errno */ +{$endif /* _POSIX_SOURCE */} + +{$endif} + + +{$ifdef linux} + O_ACCMODE = $00003; + O_RDONLY = $00000; + O_WRONLY = $00001; + O_RDWR = $00002; + O_CREAT = $00040;//&00100; + O_EXCL = $00080;//&00200; + O_NOCTTY = $00100;//&00400; + O_TRUNC = $00200;//&01000; + O_APPEND = $00400;//&02000; + O_NONBLOCK = $00800;//&04000; + O_NDELAY = O_NONBLOCK; + O_SYNC = $01000;//&010000; + O_FSYNC = O_SYNC; + O_ASYNC = $02000;//&020000; + O_CLOEXEC = $80000; + + O_DIRECT = $04000;//&0040000; + O_DIRECTORY = $10000;//&0200000; + O_NOFOLLOW = $20000;//&0400000; + + O_DSYNC = O_SYNC; + O_RSYNC = O_SYNC; + + O_LARGEFILE = $08000;//&0100000; + +{$else} + O_RDONLY = $0000; //* open for reading only */ + O_WRONLY = $0001; //* open for writing only */ + O_RDWR = $0002; //* open for reading and writing */ + O_ACCMODE = $0003; //* mask for above modes */ + + O_NONBLOCK = $0004; //* no delay */ + O_APPEND = $0008; //* set append mode */ + O_SHLOCK = $0010; //* open with shared file lock */ + O_EXLOCK = $0020; //* open with exclusive file lock */ + O_ASYNC = $0040; //* signal pgrp when data ready */ + O_FSYNC = $0080; //* synchronous writes */ + O_SYNC = $0080; //* POSIX synonym for O_FSYNC */ + O_NOFOLLOW = $0100; //* don't follow symlinks */ + O_CREAT = $0200; //* create if nonexistent */ + O_TRUNC = $0400; //* truncate to zero length */ + O_EXCL = $0800; //* error if already exists */ + +//* Defined by POSIX 1003.1; BSD default, but must be distinct from O_RDONLY. */ + O_NOCTTY = $8000; //* don't assign controlling terminal */ + +//* Attempt to bypass buffer cache */ + O_DIRECT = $00010000; + +//* Defined by POSIX Extended API Set Part 2 */ + O_DIRECTORY = $00020000; //* Fail if not directory */ + O_EXEC = $00040000; //* Open for execute only */ + +//* Defined by POSIX 1003.1-2008; BSD default, but reserve for future use. */ + O_TTY_INIT = $00080000; //* Restore default termios attributes */ + + O_CLOEXEC = $00100000; + +{$endif} + +{$ifdef linux} + F_DUPFD = 0; + F_GETFD = 1; + F_SETFD = 2; + F_GETFL = 3; + F_SETFL = 4; + + F_GETLK = 5; + F_SETLK = 6; + F_SETLKW = 7; + + F_GETLK64 = 12; + F_SETLK64 = 13; + F_SETLKW64 = 14; + + F_SETOWN = 8; + F_GETOWN = 9; + + F_SETSIG = 10; + F_GETSIG = 11; + + F_SETLEASE = 1024; + F_GETLEASE = 1025; + F_NOTIFY = 1026; + + FD_CLOEXEC = 1; + F_RDLCK = 0; + F_WRLCK = 1; + F_UNLCK = 2; + F_EXLCK = 4; + F_SHLCK = 8; + +{$else} + + F_DUPFD = 0; //* duplicate file descriptor */ + F_GETFD = 1; //* get file descriptor flags */ + F_SETFD = 2; //* set file descriptor flags */ + F_GETFL = 3; //* get file status flags */ + F_SETFL = 4; //* set file status flags */ + F_GETOWN = 5; //* get SIGIO/SIGURG proc/pgrp */ + F_SETOWN = 6; //* set SIGIO/SIGURG proc/pgrp */ + F_OGETLK = 7; //* get record locking information */ + F_OSETLK = 8; //* set record locking information */ + F_OSETLKW = 9; //* F_SETLK; wait if blocked */ + F_DUP2FD = 10; //* duplicate file descriptor to arg */ + F_GETLK = 11; //* get record locking information */ + F_SETLK = 12; //* set record locking information */ + F_SETLKW = 13; //* F_SETLK; wait if blocked */ + F_SETLK_REMOTE = 14; //* debugging support for remote locks */ + F_READAHEAD = 15; //* read ahead */ + F_RDAHEAD = 16; //* Darwin compatible read ahead */ + F_DUPFD_CLOEXEC = 17; //* Like F_DUPFD, but FD_CLOEXEC is set */ + F_DUP2FD_CLOEXEC = 18; //* Like F_DUP2FD, but FD_CLOEXEC is set */ + +//* file descriptor flags (F_GETFD, F_SETFD) */ + FD_CLOEXEC = 1; //* close-on-exec flag */ + +//* record locking flags (F_GETLK, F_SETLK, F_SETLKW) */ + F_RDLCK = 1; //* shared or read lock */ + F_UNLCK = 2; //* unlock */ + F_WRLCK = 3; //* exclusive or write lock */ + F_UNLCKSYS = 4; //* purge locks for a given system ID */ + F_CANCEL = 5; //* cancel an async lock request */ + F_WAIT = $010; //* Wait until lock is granted */ + F_FLOCK = $020; //* Use flock(2) semantics for lock */ + F_POSIX = $040; //* Use POSIX semantics for lock */ + F_REMOTE = $080; //* Lock owner is remote NFS client */ + F_NOINTR = $100; //* Ignore signals when waiting */ +{$endif} + +{$ifndef linux} + EVFILT_READ = (-1); + EVFILT_WRITE = (-2); + EVFILT_AIO = (-3); //* attached to aio requests */ + EVFILT_VNODE = (-4); //* attached to vnodes */ + EVFILT_PROC = (-5); //* attached to struct proc */ + EVFILT_SIGNAL = (-6); //* attached to struct proc */ + EVFILT_TIMER = (-7); //* timers */ +//* EVFILT_NETDEV = (-8); / no longer supported */ + EVFILT_FS = (-9); //* filesystem events */ + EVFILT_LIO = (-10); //* attached to lio requests */ + EVFILT_USER = (-11); //* User events */ + EVFILT_SYSCOUNT = 11; + + EV_ADD = $0001; //* add event to kq (implies enable) */ + EV_DELETE = $0002; //* delete event from kq */ + EV_ENABLE = $0004; //* enable event */ + EV_DISABLE = $0008; //* disable event (not reported) */ + +//* flags */ + EV_ONESHOT = $0010; //* only report one occurrence */ + EV_CLEAR = $0020; //* clear event state after reporting */ + EV_RECEIPT = $0040; //* force EV_ERROR on success, data=0 */ + EV_DISPATCH = $0080; //* disable event after reporting */ + + EV_SYSFLAGS = $F000; //* reserved by system */ + EV_DROP = $1000; //* note should be dropped */ + EV_FLAG1 = $2000; //* filter-specific flag */ + +//* returned values */ + EV_EOF = $8000; //* EOF detected */ + EV_ERROR = $4000; //* error, data contains errno */ + + NOTE_FFNOP = $00000000; //* ignore input fflags */ + NOTE_FFAND = $40000000; //* AND fflags */ + NOTE_FFOR = $80000000; //* OR fflags */ + NOTE_FFCOPY = $c0000000; //* copy fflags */ + NOTE_FFCTRLMASK = $c0000000; //* masks for operations */ + NOTE_FFLAGSMASK = $00ffffff; + + NOTE_TRIGGER = $01000000; //* Cause the event to be triggered for output. */ + +//* data/hint flags for EVFILT_{READ|WRITE}, shared with userspace + NOTE_LOWAT = $0001; //* low water mark */ + +//* data/hint flags for EVFILT_VNODE, shared with userspace + NOTE_DELETE = $0001; //* vnode was removed */ + NOTE_WRITE = $0002; //* data contents changed */ + NOTE_EXTEND = $0004; //* size increased */ + NOTE_ATTRIB = $0008; //* attributes changed */ + NOTE_LINK = $0010; //* link count changed */ + NOTE_RENAME = $0020; //* vnode was renamed */ + NOTE_REVOKE = $0040; //* vnode access was revoked */ + + +//* data/hint flags for EVFILT_PROC, shared with userspace + NOTE_EXIT = $80000000; //* process exited */ + NOTE_FORK = $40000000; //* process forked */ + NOTE_EXEC = $20000000; //* process exec'd */ + NOTE_PCTRLMASK = $f0000000; //* mask for hint bits */ + NOTE_PDATAMASK = $000fffff; //* mask for pid */ + +//* additional flags for EVFILT_PROC */ + NOTE_TRACK = $00000001; //* follow across forks */ + NOTE_TRACKERR = $00000002; //* could not track child */ + NOTE_CHILD = $00000004; //* am a child process */ + +type + kevent_t = record + ident: uintptr_t; //* identifier for this event */ + filter: cshort; //* filter for event */ + flags: cushort; + fflags: cuint; + data: intptr_t; + udata: pointer; //* opaque user data identifier */ + end; + pkevent_t = ^kevent_t; + + function kqueue(): cint; cdecl; external clib name 'kqueue'; + function kevent(kq: cint; changelist: pkevent_t; nchanges: cint; + eventlist: pkevent_t; nevents: cint; timeout: ptimespec): cint; + cdecl; external clib name 'kevent'; + const +{$endif} + + LOCK_SH = 1; + LOCK_EX = 2; + LOCK_NB = 4; + LOCK_UN = 8; + + LOCK_MAND = 32; + LOCK_READ = 64; + LOCK_WRITE = 128; + LOCK_RW = 192; + + DN_ACCESS = $00000001; + DN_MODIFY = $00000002; + DN_CREATE = $00000004; + DN_DELETE = $00000008; + DN_RENAME = $00000010; + DN_ATTRIB = $00000020; + DN_MULTISHOT = $80000000; + + __S_ISUID = $800; + __S_ISGID = $400; + __S_ISVTX = $200; + __S_IREAD = $100; + __S_IWRITE = $80; + __S_IEXEC = $40; + + S_ISUID = __S_ISUID; + S_ISGID = __S_ISGID; + S_ISVTX = __S_ISVTX; + + S_IRUSR = __S_IREAD; + S_IWUSR = __S_IWRITE; + S_IXUSR = __S_IEXEC; + S_IRWXU = (__S_IREAD or __S_IWRITE) or __S_IEXEC; + + S_IREAD = S_IRUSR; + S_IWRITE = S_IWUSR; + S_IEXEC = S_IXUSR; + + S_IRGRP = S_IRUSR shr 3; + S_IWGRP = S_IWUSR shr 3; + S_IXGRP = S_IXUSR shr 3; + S_IRWXG = S_IRWXU shr 3; + S_IROTH = S_IRGRP shr 3; + S_IWOTH = S_IWGRP shr 3; + S_IXOTH = S_IXGRP shr 3; + S_IRWXO = S_IRWXG shr 3; + + +const + __FD_SETSIZE = 1024; + __NFDBITS = 8 * sizeof(__fd_mask); + +type +// __key_t = longint; +// __ipc_pid_t = word; +// __blksize_t = longint; +// __blkcnt_t = longint; +// __blkcnt64_t = __quad_t; +// __fsblkcnt_t = __u_long; +// __fsblkcnt64_t = __u_quad_t; +// __fsfilcnt_t = __u_long; +// __fsfilcnt64_t = __u_quad_t; +// __ino64_t = __u_quad_t; +// __off64_t = __loff_t; + __t_scalar_t = longint; + __t_uscalar_t = dword; + __intptr_t = longint; + __socklen_t = dword; + TFileDescriptor = integer; + +{$ifdef CPU64} + P_stat = ^_stat; + PStat = ^_stat; + + {$ifdef linux} + _stat = packed record + st_dev: culong; + st_ino: culong; + st_nlink: culong; + + st_mode: cuint; + st_uid: cuint; + st_gid: cuint; + __pad0: cuint; + st_rdev: culong; + st_size: clong; + st_blksize: clong; + st_blocks: clong; //* Number 512-byte blocks allocated. */ + + st_atime: culong; + st_atime_nsec: culong; + st_mtime: culong; + st_mtime_nsec: culong; + st_ctime: culong; + st_ctime_nsec: culong; + __unused: array[0..2] of clong; + end; + + {$else} //bsd + ino_t = cuint32; + mode_t = cuint16; + n_link_t = cuint16; + uid_t = cuint32; + gid_t = cuint32; + off_t = cint64; + blkcnt_t = cint64; + blksize_t = cuint32; + fflags_t = cuint32; + + _stat = packed record + st_dev: __dev_t; //* inode's device */ + st_ino: ino_t; //* inode's number */ + st_mode: mode_t; //* inode protection mode */ + st_nlink: n_link_t; //* number of hard links */ + st_uid: uid_t; //* user ID of the file's owner */ + st_gid: gid_t; //* group ID of the file's group */ + st_rdev: __dev_t; //* device type */ + st_atime: culong; //* time of last access */ + st_atime_nsec: culong; + st_mtime: culong; //* time of last data modification */ + st_mtime_nsec: culong; + st_ctime: culong; //* time of last file status change */ + st_ctime_nsec: culong; + st_size: off_t; //* file size, in bytes */ + st_blocks: blkcnt_t; //* blocks allocated for file */ + st_blksize: blksize_t; //* optimal blocksize for I/O */ + st_flags: fflags_t; //* user defined flags for file */ + st_gen: cuint32; //* file generation number */ + st_lspare: cint32; + st_birthtim: timespec; //* time of file creation */ + {$ifndef cpu64} + pad: array[0..15-sizeof(timespec)] of byte; + {$endif} + (* + /* + * Explicitly pad st_birthtim to 16 bytes so that the size of + * struct stat is backwards compatible. We use bitfields instead + * of an array of chars so that this doesn't require a C99 compiler + * to compile if the size of the padding is 0. We use 2 bitfields + * to cover up to 64 bits on 32-bit machines. We assume that + * CHAR_BIT is 8... + */ + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); + *) + end; +{$endif} //bsd + + + P_stat64 = ^_stat64; + Pstat64 = ^_stat64; + _stat64 = _stat; +{$else} //cpu32 + + P_stat = ^_stat; + PStat = ^_stat; + {$ifdef linux} + _stat = packed record //probably wrong, not used + st_dev : __dev_t; + __pad1 : word; + __align_pad1 : word; + st_ino : __ino_t; + st_mode : __mode_t; + st_nlink : __nlink_t; + st_uid : __uid_t; + st_gid : __gid_t; + st_rdev : __dev_t; + __pad2 : word; + __align_pad2 : word; + st_size : __off_t; + st_blksize : __blksize_t; + st_blocks : __blkcnt_t; + st_atim: timespec;// __time_t; +// st_atime_nsec : longword; + st_mtim: timespec;// __time_t; +// st_mtime_nsec: longword; + st_ctim: timespec;// __time_t; +// st_ctime_nsec: longword; + __unused4 : dword; + __unused5 : dword; + end; + {$endif} + P_stat64 = ^_stat64; + Pstat64 = ^_stat64; +{$ifndef cpuarm} + {$ifdef linux} + _stat64 = packed record + st_dev: culonglong; // 0 + __pad0: array[0..3] of byte; // 8 + __st_ino: culong; //12 + st_mode: cuint; //16 + st_nlink: cuint; //20 + st_uid: culong; //24 + st_gid: culong; //28 + st_rdev: culonglong; //32 + __pad3: array[0..3] of byte; //40 + st_size: clonglong; //44 + st_blksize: culong; //52 + st_blocks: culonglong; //56 + st_atime: culong; //64 + st_atime_nsec: culong; //68 + st_mtime: culong; //72 + st_mtime_nsec: cuint; //76 + st_ctime: culong; //80 + st_ctime_nsec: culong; //84 + st_ino: culonglong; //88 + //96 + end; + {$else} //bsd + ino_t = cuint32; + mode_t = cuint16; + n_link_t = cuint16; + uid_t = cuint32; + gid_t = cuint32; + off_t = cint64; + blkcnt_t = cint64; + blksize_t = cuint32; + fflags_t = cuint32; + + _stat = packed record + st_dev: __dev_t; //* inode's device */ + st_ino: ino_t; //* inode's number */ + st_mode: mode_t; //* inode protection mode */ + st_nlink: n_link_t; //* number of hard links */ + st_uid: uid_t; //* user ID of the file's owner */ + st_gid: gid_t; //* group ID of the file's group */ + st_rdev: __dev_t; //* device type */ + st_atime: culong; //* time of last access */ + st_atime_nsec: culong; + st_mtime: culong; //* time of last data modification */ + st_mtime_nsec: culong; + st_ctime: culong; //* time of last file status change */ + st_ctime_nsec: culong; + st_size: off_t; //* file size, in bytes */ + st_blocks: blkcnt_t; //* blocks allocated for file */ + st_blksize: blksize_t; //* optimal blocksize for I/O */ + st_flags: fflags_t; //* user defined flags for file */ + st_gen: cuint32; //* file generation number */ + st_lspare: cint32; + st_birthtim: timespec; //* time of file creation */ + {$ifndef cpu64} + pad: array[0..15-sizeof(timespec)] of byte; + {$endif} + (* + /* + * Explicitly pad st_birthtim to 16 bytes so that the size of + * struct stat is backwards compatible. We use bitfields instead + * of an array of chars so that this doesn't require a C99 compiler + * to compile if the size of the padding is 0. We use 2 bitfields + * to cover up to 64 bits on 32-bit machines. We assume that + * CHAR_BIT is 8... + */ + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); + *) + end; + _stat64 = _stat; + {$endif} //bsd +{$else} //cpuarm for raspberry pi + _stat64 = packed record + st_dev: culonglong; //* Device. */ + st_ino: culonglong; //* File serial number. */ + st_mode: cuint; //* File mode. */ + st_nlink: cuint; //* Link count. */ + st_uid: cuint; //* User ID of the file's owner. */ + st_gid: cuint; //* Group ID of the file's group. */ + st_rdev: culonglong; //* Device number, if device. */ + __pad1: culonglong; + st_size: clonglong; //* Size of file, in bytes. */ + st_blksize: cint; //* Optimal block size for I/O. */ + __pad2: cint; + st_blocks: clonglong; //* Number 512-byte blocks allocated. */ + st_atime: cint; //* Time of last access. */ + st_atime_nsec: cuint; + st_mtime: cint; //* Time of last modification. */ + st_mtime_nsec: cuint; + st_ctime: cint; //* Time of last status change. */ + st_ctime_nsec: cuint; + __unused4: cuint; + __unused5: cuint; + end; +{$endif} //cpuarm +{$endif} //cpu32 + + __fd_set = record + fds_bits: packed array[0..(__FD_SETSIZE div __NFDBITS)-1] of __fd_mask; + end; + TFdSet = __fd_set; + PFdSet = ^TFdSet; + + +Const + stdin = 0; + stdout = 1; + stderr = 2; + + +Type + + u_char = __u_char; + u_short = __u_short; + u_int = __u_int; + u_long = __u_long; + quad_t = __quad_t; + u_quad_t = __u_quad_t; + fsid_t = __fsid_t; + loff_t = __loff_t; + ino64_t = __ino64_t; + dev_t = __dev_t; + {$ifdef linux} + ino_t = __ino_t; + gid_t = __gid_t; + mode_t = __mode_t; + uid_t = __uid_t; + off_t = __off_t; + blksize_t = __blksize_t; + blkcnt_t = __blkcnt_t; + {$endif} + nlink_t = __nlink_t; + off64_t = __off64_t; + pid_t = __pid_t; + id_t = __id_t; + ssize_t = __ssize_t; + daddr_t = __daddr_t; + caddr_t = __caddr_t; + key_t = __key_t; + useconds_t = __useconds_t; + suseconds_t = __suseconds_t; + ulong = dword; + ushort = word; + uint = dword; + int8_t = char; + int16_t = smallint; + int32_t = longint; + u_int8_t = byte; + u_int16_t = word; + u_int32_t = dword; + register_t = longint; + fsblkcnt_t = __fsblkcnt_t; + fsfilcnt_t = __fsfilcnt_t; + blkcnt64_t = __blkcnt64_t; + fsblkcnt64_t = __fsblkcnt64_t; + fsfilcnt64_t = __fsfilcnt64_t; + + P__key_t = ^__key_t; + P__ipc_pid_t = ^__ipc_pid_t; + P__blksize_t = ^__blksize_t; + P__blkcnt_t = ^__blkcnt_t; + P__blkcnt64_t = ^__blkcnt64_t; + P__fsblkcnt_t = ^__fsblkcnt_t; + P__fsblkcnt64_t = ^__fsblkcnt64_t; + P__fsfilcnt_t = ^__fsfilcnt_t; + P__fsfilcnt64_t = ^__fsfilcnt64_t; + P__ino64_t = ^__ino64_t; + P__off64_t = ^__off64_t; + P__t_scalar_t = ^__t_scalar_t; + P__t_uscalar_t = ^__t_uscalar_t; + P__intptr_t = ^__intptr_t; + P__socklen_t = ^__socklen_t; + + + Pu_char = ^u_char; + Pu_short = ^u_short; + Pu_int = ^u_int; + Pu_long = ^u_long; + Pquad_t = ^quad_t; + Pu_quad_t = ^u_quad_t; + Pfsid_t = ^fsid_t; + Ploff_t = ^loff_t; + Pino_t = ^ino_t; + Pino64_t = ^ino64_t; + Pdev_t = ^dev_t; + Pgid_t = ^gid_t; + Pmode_t = ^mode_t; + Pnlink_t = ^nlink_t; + Puid_t = ^uid_t; + Poff_t = ^off_t; + Poff64_t = ^off64_t; + Ppid_t = ^pid_t; + Pssize_t = ^ssize_t; + Pdaddr_t = ^daddr_t; + Pcaddr_t = ^caddr_t; + Pkey_t = ^key_t; + Puseconds_t = ^useconds_t; + Psuseconds_t = ^suseconds_t; + Pulong = ^ulong; + Pushort = ^ushort; + Puint = ^uint; + Pint8_t = ^int8_t; + Pint16_t = ^int16_t; + Pint32_t = ^int32_t; + Pu_int8_t = ^u_int8_t; + Pu_int16_t = ^u_int16_t; + Pu_int32_t = ^u_int32_t; + Pregister_t = ^register_t; + Pblksize_t = ^blksize_t; + Pblkcnt_t = ^blkcnt_t; + Pfsblkcnt_t = ^fsblkcnt_t; + Pfsfilcnt_t = ^fsfilcnt_t; + Pblkcnt64_t = ^blkcnt64_t; + Pfsblkcnt64_t = ^fsblkcnt64_t; + Pfsfilcnt64_t = ^fsfilcnt64_t; + + P__qaddr_t = ^__qaddr_t; + P__dev_t = ^__dev_t; + P__uid_t = ^__uid_t; + P__gid_t = ^__gid_t; + P__ino_t = ^__ino_t; + P__mode_t = ^__mode_t; + P__nlink_t = ^__nlink_t; + P__off_t = ^__off_t; + P__loff_t = ^__loff_t; + P__pid_t = ^__pid_t; + P__ssize_t = ^__ssize_t; + P__rlim_t = ^__rlim_t; + P__rlim64_t = ^__rlim64_t; + P__id_t = ^__id_t; + P__fsid_t = ^__fsid_t; + P__daddr_t = ^__daddr_t; + P__caddr_t = ^__caddr_t; + P__time_t = ^__time_t; + P__useconds_t = ^__useconds_t; + P__suseconds_t = ^__suseconds_t; + P__swblk_t = ^__swblk_t; + P__clock_t = ^__clock_t; + P__clockid_t = ^__clockid_t; + P__timer_t = ^__timer_t; + +const +{$ifdef linux} + __LC_CTYPE = 0; + __LC_NUMERIC = 1; + __LC_TIME = 2; + __LC_COLLATE = 3; + __LC_MONETARY = 4; + __LC_MESSAGES = 5; + __LC_ALL = 6; + __LC_PAPER = 7; + __LC_NAME = 8; + __LC_ADDRESS = 9; + __LC_TELEPHONE = 10; + __LC_MEASUREMENT = 11; + __LC_IDENTIFICATION = 12; + + LC_CTYPE = __LC_CTYPE; + LC_NUMERIC = __LC_NUMERIC; + LC_TIME = __LC_TIME; + LC_COLLATE = __LC_COLLATE; + LC_MONETARY = __LC_MONETARY; + LC_MESSAGES = __LC_MESSAGES; + LC_ALL = __LC_ALL; + LC_PAPER = __LC_PAPER; + LC_NAME = __LC_NAME; + LC_ADDRESS = __LC_ADDRESS; + LC_TELEPHONE = __LC_TELEPHONE; + LC_MEASUREMENT = __LC_MEASUREMENT; + LC_IDENTIFICATION = __LC_IDENTIFICATION; + + ABDAY_1 = (__LC_TIME shl 16); + ABDAY_2 = (ABDAY_1)+1; + ABDAY_3 = (ABDAY_1)+2; + ABDAY_4 = (ABDAY_1)+3; + ABDAY_5 = (ABDAY_1)+4; + ABDAY_6 = (ABDAY_1)+5; + ABDAY_7 = (ABDAY_1)+6; + DAY_1 = (ABDAY_1)+7; + DAY_2 = (ABDAY_1)+8; + DAY_3 = (ABDAY_1)+9; + DAY_4 = (ABDAY_1)+10; + DAY_5 = (ABDAY_1)+11; + DAY_6 = (ABDAY_1)+12; + DAY_7 = (ABDAY_1)+13; + ABMON_1 = (ABDAY_1)+14; + ABMON_2 = (ABDAY_1)+15; + ABMON_3 = (ABDAY_1)+16; + ABMON_4 = (ABDAY_1)+17; + ABMON_5 = (ABDAY_1)+18; + ABMON_6 = (ABDAY_1)+19; + ABMON_7 = (ABDAY_1)+20; + ABMON_8 = (ABDAY_1)+21; + ABMON_9 = (ABDAY_1)+22; + ABMON_10 = (ABDAY_1)+23; + ABMON_11 = (ABDAY_1)+24; + ABMON_12 = (ABDAY_1)+25; + MON_1 = (ABDAY_1)+26; + MON_2 = (ABDAY_1)+27; + MON_3 = (ABDAY_1)+28; + MON_4 = (ABDAY_1)+29; + MON_5 = (ABDAY_1)+30; + MON_6 = (ABDAY_1)+31; + MON_7 = (ABDAY_1)+32; + MON_8 = (ABDAY_1)+33; + MON_9 = (ABDAY_1)+34; + MON_10 = (ABDAY_1)+35; + MON_11 = (ABDAY_1)+36; + MON_12 = (ABDAY_1)+37; + AM_STR = (ABDAY_1)+38; + PM_STR = (ABDAY_1)+39; + D_T_FMT = (ABDAY_1)+40; + D_FMT = (ABDAY_1)+41; + T_FMT = (ABDAY_1)+42; + T_FMT_AMPM = (ABDAY_1)+43; + ERA = (ABDAY_1)+44; + __ERA_YEAR = (ABDAY_1)+45; + ERA_D_FMT = (ABDAY_1)+46; + ALT_DIGITS = (ABDAY_1)+47; + ERA_D_T_FMT = (ABDAY_1)+48; + ERA_T_FMT = (ABDAY_1)+49; + _NL_TIME_ERA_NUM_ENTRIES = (ABDAY_1)+50; + _NL_TIME_ERA_ENTRIES = (ABDAY_1)+51; + _NL_WABDAY_1 = (ABDAY_1)+52; + _NL_WABDAY_2 = (ABDAY_1)+53; + _NL_WABDAY_3 = (ABDAY_1)+54; + _NL_WABDAY_4 = (ABDAY_1)+55; + _NL_WABDAY_5 = (ABDAY_1)+56; + _NL_WABDAY_6 = (ABDAY_1)+57; + _NL_WABDAY_7 = (ABDAY_1)+58; + _NL_WDAY_1 = (ABDAY_1)+59; + _NL_WDAY_2 = (ABDAY_1)+60; + _NL_WDAY_3 = (ABDAY_1)+61; + _NL_WDAY_4 = (ABDAY_1)+62; + _NL_WDAY_5 = (ABDAY_1)+63; + _NL_WDAY_6 = (ABDAY_1)+64; + _NL_WDAY_7 = (ABDAY_1)+65; + _NL_WABMON_1 = (ABDAY_1)+66; + _NL_WABMON_2 = (ABDAY_1)+67; + _NL_WABMON_3 = (ABDAY_1)+68; + _NL_WABMON_4 = (ABDAY_1)+69; + _NL_WABMON_5 = (ABDAY_1)+70; + _NL_WABMON_6 = (ABDAY_1)+71; + _NL_WABMON_7 = (ABDAY_1)+72; + _NL_WABMON_8 = (ABDAY_1)+73; + _NL_WABMON_9 = (ABDAY_1)+74; + _NL_WABMON_10 = (ABDAY_1)+75; + _NL_WABMON_11 = (ABDAY_1)+76; + _NL_WABMON_12 = (ABDAY_1)+77; + _NL_WMON_1 = (ABDAY_1)+78; + _NL_WMON_2 = (ABDAY_1)+79; + _NL_WMON_3 = (ABDAY_1)+80; + _NL_WMON_4 = (ABDAY_1)+81; + _NL_WMON_5 = (ABDAY_1)+82; + _NL_WMON_6 = (ABDAY_1)+83; + _NL_WMON_7 = (ABDAY_1)+84; + _NL_WMON_8 = (ABDAY_1)+85; + _NL_WMON_9 = (ABDAY_1)+86; + _NL_WMON_10 = (ABDAY_1)+87; + _NL_WMON_11 = (ABDAY_1)+88; + _NL_WMON_12 = (ABDAY_1)+89; + _NL_WAM_STR = (ABDAY_1)+90; + _NL_WPM_STR = (ABDAY_1)+91; + _NL_WD_T_FMT = (ABDAY_1)+92; + _NL_WD_FMT = (ABDAY_1)+93; + _NL_WT_FMT = (ABDAY_1)+94; + _NL_WT_FMT_AMPM = (ABDAY_1)+95; + _NL_WERA_YEAR = (ABDAY_1)+96; + _NL_WERA_D_FMT = (ABDAY_1)+97; + _NL_WALT_DIGITS = (ABDAY_1)+98; + _NL_WERA_D_T_FMT = (ABDAY_1)+99; + _NL_WERA_T_FMT = (ABDAY_1)+100; + _NL_TIME_WEEK_NDAYS = (ABDAY_1)+101; + _NL_TIME_WEEK_1STDAY = (ABDAY_1)+102; + _NL_TIME_WEEK_1STWEEK = (ABDAY_1)+103; + _NL_TIME_FIRST_WEEKDAY = (ABDAY_1)+104; + _NL_TIME_FIRST_WORKDAY = (ABDAY_1)+105; + _NL_TIME_CAL_DIRECTION = (ABDAY_1)+106; + _NL_TIME_TIMEZONE = (ABDAY_1)+107; + _DATE_FMT = (ABDAY_1)+108; + _NL_W_DATE_FMT = (ABDAY_1)+109; + _NL_TIME_CODESET = (ABDAY_1)+110; + _NL_NUM_LC_TIME = (ABDAY_1)+111; + _NL_COLLATE_NRULES = (__LC_COLLATE shl 16); + _NL_COLLATE_RULESETS = (_NL_COLLATE_NRULES)+1; + _NL_COLLATE_TABLEMB = (_NL_COLLATE_NRULES)+2; + _NL_COLLATE_WEIGHTMB = (_NL_COLLATE_NRULES)+3; + _NL_COLLATE_EXTRAMB = (_NL_COLLATE_NRULES)+4; + _NL_COLLATE_INDIRECTMB = (_NL_COLLATE_NRULES)+5; + _NL_COLLATE_GAP1 = (_NL_COLLATE_NRULES)+6; + _NL_COLLATE_GAP2 = (_NL_COLLATE_NRULES)+7; + _NL_COLLATE_GAP3 = (_NL_COLLATE_NRULES)+8; + _NL_COLLATE_TABLEWC = (_NL_COLLATE_NRULES)+9; + _NL_COLLATE_WEIGHTWC = (_NL_COLLATE_NRULES)+10; + _NL_COLLATE_EXTRAWC = (_NL_COLLATE_NRULES)+11; + _NL_COLLATE_INDIRECTWC = (_NL_COLLATE_NRULES)+12; + _NL_COLLATE_SYMB_HASH_SIZEMB = (_NL_COLLATE_NRULES)+13; + _NL_COLLATE_SYMB_TABLEMB = (_NL_COLLATE_NRULES)+14; + _NL_COLLATE_SYMB_EXTRAMB = (_NL_COLLATE_NRULES)+15; + _NL_COLLATE_COLLSEQMB = (_NL_COLLATE_NRULES)+16; + _NL_COLLATE_COLLSEQWC = (_NL_COLLATE_NRULES)+17; + _NL_COLLATE_CODESET = (_NL_COLLATE_NRULES)+18; + _NL_NUM_LC_COLLATE = (_NL_COLLATE_NRULES)+19; + _NL_CTYPE_CLASS = (__LC_CTYPE shl 16); + _NL_CTYPE_TOUPPER = (_NL_CTYPE_CLASS)+1; + _NL_CTYPE_GAP1 = (_NL_CTYPE_CLASS)+2; + _NL_CTYPE_TOLOWER = (_NL_CTYPE_CLASS)+3; + _NL_CTYPE_GAP2 = (_NL_CTYPE_CLASS)+4; + _NL_CTYPE_CLASS32 = (_NL_CTYPE_CLASS)+5; + _NL_CTYPE_GAP3 = (_NL_CTYPE_CLASS)+6; + _NL_CTYPE_GAP4 = (_NL_CTYPE_CLASS)+7; + _NL_CTYPE_GAP5 = (_NL_CTYPE_CLASS)+8; + _NL_CTYPE_GAP6 = (_NL_CTYPE_CLASS)+9; + _NL_CTYPE_CLASS_NAMES = (_NL_CTYPE_CLASS)+10; + _NL_CTYPE_MAP_NAMES = (_NL_CTYPE_CLASS)+11; + _NL_CTYPE_WIDTH = (_NL_CTYPE_CLASS)+12; + _NL_CTYPE_MB_CUR_MAX = (_NL_CTYPE_CLASS)+13; + _NL_CTYPE_CODESET_NAME = (_NL_CTYPE_CLASS)+14; + CODESET = _NL_CTYPE_CODESET_NAME; + _NL_CTYPE_TOUPPER32 = (_NL_CTYPE_CODESET_NAME)+1; + _NL_CTYPE_TOLOWER32 = (_NL_CTYPE_CODESET_NAME)+2; + _NL_CTYPE_CLASS_OFFSET = (_NL_CTYPE_CODESET_NAME)+3; + _NL_CTYPE_MAP_OFFSET = (_NL_CTYPE_CODESET_NAME)+4; + _NL_CTYPE_INDIGITS_MB_LEN = (_NL_CTYPE_CODESET_NAME)+5; + _NL_CTYPE_INDIGITS0_MB = (_NL_CTYPE_CODESET_NAME)+6; + _NL_CTYPE_INDIGITS1_MB = (_NL_CTYPE_CODESET_NAME)+7; + _NL_CTYPE_INDIGITS2_MB = (_NL_CTYPE_CODESET_NAME)+8; + _NL_CTYPE_INDIGITS3_MB = (_NL_CTYPE_CODESET_NAME)+9; + _NL_CTYPE_INDIGITS4_MB = (_NL_CTYPE_CODESET_NAME)+10; + _NL_CTYPE_INDIGITS5_MB = (_NL_CTYPE_CODESET_NAME)+11; + _NL_CTYPE_INDIGITS6_MB = (_NL_CTYPE_CODESET_NAME)+12; + _NL_CTYPE_INDIGITS7_MB = (_NL_CTYPE_CODESET_NAME)+13; + _NL_CTYPE_INDIGITS8_MB = (_NL_CTYPE_CODESET_NAME)+14; + _NL_CTYPE_INDIGITS9_MB = (_NL_CTYPE_CODESET_NAME)+15; + _NL_CTYPE_INDIGITS_WC_LEN = (_NL_CTYPE_CODESET_NAME)+16; + _NL_CTYPE_INDIGITS0_WC = (_NL_CTYPE_CODESET_NAME)+17; + _NL_CTYPE_INDIGITS1_WC = (_NL_CTYPE_CODESET_NAME)+18; + _NL_CTYPE_INDIGITS2_WC = (_NL_CTYPE_CODESET_NAME)+19; + _NL_CTYPE_INDIGITS3_WC = (_NL_CTYPE_CODESET_NAME)+20; + _NL_CTYPE_INDIGITS4_WC = (_NL_CTYPE_CODESET_NAME)+21; + _NL_CTYPE_INDIGITS5_WC = (_NL_CTYPE_CODESET_NAME)+22; + _NL_CTYPE_INDIGITS6_WC = (_NL_CTYPE_CODESET_NAME)+23; + _NL_CTYPE_INDIGITS7_WC = (_NL_CTYPE_CODESET_NAME)+24; + _NL_CTYPE_INDIGITS8_WC = (_NL_CTYPE_CODESET_NAME)+25; + _NL_CTYPE_INDIGITS9_WC = (_NL_CTYPE_CODESET_NAME)+26; + _NL_CTYPE_OUTDIGIT0_MB = (_NL_CTYPE_CODESET_NAME)+27; + _NL_CTYPE_OUTDIGIT1_MB = (_NL_CTYPE_CODESET_NAME)+28; + _NL_CTYPE_OUTDIGIT2_MB = (_NL_CTYPE_CODESET_NAME)+29; + _NL_CTYPE_OUTDIGIT3_MB = (_NL_CTYPE_CODESET_NAME)+30; + _NL_CTYPE_OUTDIGIT4_MB = (_NL_CTYPE_CODESET_NAME)+31; + _NL_CTYPE_OUTDIGIT5_MB = (_NL_CTYPE_CODESET_NAME)+32; + _NL_CTYPE_OUTDIGIT6_MB = (_NL_CTYPE_CODESET_NAME)+33; + _NL_CTYPE_OUTDIGIT7_MB = (_NL_CTYPE_CODESET_NAME)+34; + _NL_CTYPE_OUTDIGIT8_MB = (_NL_CTYPE_CODESET_NAME)+35; + _NL_CTYPE_OUTDIGIT9_MB = (_NL_CTYPE_CODESET_NAME)+36; + _NL_CTYPE_OUTDIGIT0_WC = (_NL_CTYPE_CODESET_NAME)+37; + _NL_CTYPE_OUTDIGIT1_WC = (_NL_CTYPE_CODESET_NAME)+38; + _NL_CTYPE_OUTDIGIT2_WC = (_NL_CTYPE_CODESET_NAME)+39; + _NL_CTYPE_OUTDIGIT3_WC = (_NL_CTYPE_CODESET_NAME)+40; + _NL_CTYPE_OUTDIGIT4_WC = (_NL_CTYPE_CODESET_NAME)+41; + _NL_CTYPE_OUTDIGIT5_WC = (_NL_CTYPE_CODESET_NAME)+42; + _NL_CTYPE_OUTDIGIT6_WC = (_NL_CTYPE_CODESET_NAME)+43; + _NL_CTYPE_OUTDIGIT7_WC = (_NL_CTYPE_CODESET_NAME)+44; + _NL_CTYPE_OUTDIGIT8_WC = (_NL_CTYPE_CODESET_NAME)+45; + _NL_CTYPE_OUTDIGIT9_WC = (_NL_CTYPE_CODESET_NAME)+46; + _NL_CTYPE_TRANSLIT_TAB_SIZE = (_NL_CTYPE_CODESET_NAME)+47; + _NL_CTYPE_TRANSLIT_FROM_IDX = (_NL_CTYPE_CODESET_NAME)+48; + _NL_CTYPE_TRANSLIT_FROM_TBL = (_NL_CTYPE_CODESET_NAME)+49; + _NL_CTYPE_TRANSLIT_TO_IDX = (_NL_CTYPE_CODESET_NAME)+50; + _NL_CTYPE_TRANSLIT_TO_TBL = (_NL_CTYPE_CODESET_NAME)+51; + _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN = (_NL_CTYPE_CODESET_NAME)+52; + _NL_CTYPE_TRANSLIT_DEFAULT_MISSING = (_NL_CTYPE_CODESET_NAME)+53; + _NL_CTYPE_TRANSLIT_IGNORE_LEN = (_NL_CTYPE_CODESET_NAME)+54; + _NL_CTYPE_TRANSLIT_IGNORE = (_NL_CTYPE_CODESET_NAME)+55; + _NL_CTYPE_EXTRA_MAP_1 = (_NL_CTYPE_CODESET_NAME)+56; + _NL_CTYPE_EXTRA_MAP_2 = (_NL_CTYPE_CODESET_NAME)+57; + _NL_CTYPE_EXTRA_MAP_3 = (_NL_CTYPE_CODESET_NAME)+58; + _NL_CTYPE_EXTRA_MAP_4 = (_NL_CTYPE_CODESET_NAME)+59; + _NL_CTYPE_EXTRA_MAP_5 = (_NL_CTYPE_CODESET_NAME)+60; + _NL_CTYPE_EXTRA_MAP_6 = (_NL_CTYPE_CODESET_NAME)+61; + _NL_CTYPE_EXTRA_MAP_7 = (_NL_CTYPE_CODESET_NAME)+62; + _NL_CTYPE_EXTRA_MAP_8 = (_NL_CTYPE_CODESET_NAME)+63; + _NL_CTYPE_EXTRA_MAP_9 = (_NL_CTYPE_CODESET_NAME)+64; + _NL_CTYPE_EXTRA_MAP_10 = (_NL_CTYPE_CODESET_NAME)+65; + _NL_CTYPE_EXTRA_MAP_11 = (_NL_CTYPE_CODESET_NAME)+66; + _NL_CTYPE_EXTRA_MAP_12 = (_NL_CTYPE_CODESET_NAME)+67; + _NL_CTYPE_EXTRA_MAP_13 = (_NL_CTYPE_CODESET_NAME)+68; + _NL_CTYPE_EXTRA_MAP_14 = (_NL_CTYPE_CODESET_NAME)+69; + _NL_NUM_LC_CTYPE = (_NL_CTYPE_CODESET_NAME)+70; + __INT_CURR_SYMBOL = (__LC_MONETARY shl 16); + __CURRENCY_SYMBOL = (__INT_CURR_SYMBOL)+1; + __MON_DECIMAL_POINT = (__INT_CURR_SYMBOL)+2; + __MON_THOUSANDS_SEP = (__INT_CURR_SYMBOL)+3; + __MON_GROUPING = (__INT_CURR_SYMBOL)+4; + __POSITIVE_SIGN = (__INT_CURR_SYMBOL)+5; + __NEGATIVE_SIGN = (__INT_CURR_SYMBOL)+6; + __INT_FRAC_DIGITS = (__INT_CURR_SYMBOL)+7; + __FRAC_DIGITS = (__INT_CURR_SYMBOL)+8; + __P_CS_PRECEDES = (__INT_CURR_SYMBOL)+9; + __P_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+10; + __N_CS_PRECEDES = (__INT_CURR_SYMBOL)+11; + __N_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+12; + __P_SIGN_POSN = (__INT_CURR_SYMBOL)+13; + __N_SIGN_POSN = (__INT_CURR_SYMBOL)+14; + _NL_MONETARY_CRNCYSTR = (__INT_CURR_SYMBOL)+15; + __INT_P_CS_PRECEDES = (__INT_CURR_SYMBOL)+16; + __INT_P_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+17; + __INT_N_CS_PRECEDES = (__INT_CURR_SYMBOL)+18; + __INT_N_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+19; + __INT_P_SIGN_POSN = (__INT_CURR_SYMBOL)+20; + __INT_N_SIGN_POSN = (__INT_CURR_SYMBOL)+21; + _NL_MONETARY_DUO_INT_CURR_SYMBOL = (__INT_CURR_SYMBOL)+22; + _NL_MONETARY_DUO_CURRENCY_SYMBOL = (__INT_CURR_SYMBOL)+23; + _NL_MONETARY_DUO_INT_FRAC_DIGITS = (__INT_CURR_SYMBOL)+24; + _NL_MONETARY_DUO_FRAC_DIGITS = (__INT_CURR_SYMBOL)+25; + _NL_MONETARY_DUO_P_CS_PRECEDES = (__INT_CURR_SYMBOL)+26; + _NL_MONETARY_DUO_P_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+27; + _NL_MONETARY_DUO_N_CS_PRECEDES = (__INT_CURR_SYMBOL)+28; + _NL_MONETARY_DUO_N_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+29; + _NL_MONETARY_DUO_INT_P_CS_PRECEDES = (__INT_CURR_SYMBOL)+30; + _NL_MONETARY_DUO_INT_P_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+31; + _NL_MONETARY_DUO_INT_N_CS_PRECEDES = (__INT_CURR_SYMBOL)+32; + _NL_MONETARY_DUO_INT_N_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+33; + _NL_MONETARY_DUO_P_SIGN_POSN = (__INT_CURR_SYMBOL)+34; + _NL_MONETARY_DUO_N_SIGN_POSN = (__INT_CURR_SYMBOL)+35; + _NL_MONETARY_DUO_INT_P_SIGN_POSN = (__INT_CURR_SYMBOL)+36; + _NL_MONETARY_DUO_INT_N_SIGN_POSN = (__INT_CURR_SYMBOL)+37; + _NL_MONETARY_UNO_VALID_FROM = (__INT_CURR_SYMBOL)+38; + _NL_MONETARY_UNO_VALID_TO = (__INT_CURR_SYMBOL)+39; + _NL_MONETARY_DUO_VALID_FROM = (__INT_CURR_SYMBOL)+40; + _NL_MONETARY_DUO_VALID_TO = (__INT_CURR_SYMBOL)+41; + _NL_MONETARY_CONVERSION_RATE = (__INT_CURR_SYMBOL)+42; + _NL_MONETARY_DECIMAL_POINT_WC = (__INT_CURR_SYMBOL)+43; + _NL_MONETARY_THOUSANDS_SEP_WC = (__INT_CURR_SYMBOL)+44; + _NL_MONETARY_CODESET = (__INT_CURR_SYMBOL)+45; + _NL_NUM_LC_MONETARY = (__INT_CURR_SYMBOL)+46; + __DECIMAL_POINT = (__LC_NUMERIC shl 16); + RADIXCHAR = __DECIMAL_POINT; + __THOUSANDS_SEP = (__DECIMAL_POINT)+1; + THOUSEP = __THOUSANDS_SEP; + __GROUPING = (__THOUSANDS_SEP)+1; + _NL_NUMERIC_DECIMAL_POINT_WC = (__THOUSANDS_SEP)+2; + _NL_NUMERIC_THOUSANDS_SEP_WC = (__THOUSANDS_SEP)+3; + _NL_NUMERIC_CODESET = (__THOUSANDS_SEP)+4; + _NL_NUM_LC_NUMERIC = (__THOUSANDS_SEP)+5; + __YESEXPR = (__LC_MESSAGES shl 16); + __NOEXPR = ((__LC_MESSAGES shl 16))+1; + __YESSTR = ((__LC_MESSAGES shl 16))+2; + __NOSTR = ((__LC_MESSAGES shl 16))+3; + _NL_MESSAGES_CODESET = ((__LC_MESSAGES shl 16))+4; + _NL_NUM_LC_MESSAGES = ((__LC_MESSAGES shl 16))+5; + _NL_PAPER_HEIGHT = (__LC_PAPER shl 16); + _NL_PAPER_WIDTH = (_NL_PAPER_HEIGHT)+1; + _NL_PAPER_CODESET = (_NL_PAPER_HEIGHT)+2; + _NL_NUM_LC_PAPER = (_NL_PAPER_HEIGHT)+3; + _NL_NAME_NAME_FMT = (__LC_NAME shl 16); + _NL_NAME_NAME_GEN = (_NL_NAME_NAME_FMT)+1; + _NL_NAME_NAME_MR = (_NL_NAME_NAME_FMT)+2; + _NL_NAME_NAME_MRS = (_NL_NAME_NAME_FMT)+3; + _NL_NAME_NAME_MISS = (_NL_NAME_NAME_FMT)+4; + _NL_NAME_NAME_MS = (_NL_NAME_NAME_FMT)+5; + _NL_NAME_CODESET = (_NL_NAME_NAME_FMT)+6; + _NL_NUM_LC_NAME = (_NL_NAME_NAME_FMT)+7; + _NL_ADDRESS_POSTAL_FMT = (__LC_ADDRESS shl 16); + _NL_ADDRESS_COUNTRY_NAME = (_NL_ADDRESS_POSTAL_FMT)+1; + _NL_ADDRESS_COUNTRY_POST = (_NL_ADDRESS_POSTAL_FMT)+2; + _NL_ADDRESS_COUNTRY_AB2 = (_NL_ADDRESS_POSTAL_FMT)+3; + _NL_ADDRESS_COUNTRY_AB3 = (_NL_ADDRESS_POSTAL_FMT)+4; + _NL_ADDRESS_COUNTRY_CAR = (_NL_ADDRESS_POSTAL_FMT)+5; + _NL_ADDRESS_COUNTRY_NUM = (_NL_ADDRESS_POSTAL_FMT)+6; + _NL_ADDRESS_COUNTRY_ISBN = (_NL_ADDRESS_POSTAL_FMT)+7; + _NL_ADDRESS_LANG_NAME = (_NL_ADDRESS_POSTAL_FMT)+8; + _NL_ADDRESS_LANG_AB = (_NL_ADDRESS_POSTAL_FMT)+9; + _NL_ADDRESS_LANG_TERM = (_NL_ADDRESS_POSTAL_FMT)+10; + _NL_ADDRESS_LANG_LIB = (_NL_ADDRESS_POSTAL_FMT)+11; + _NL_ADDRESS_CODESET = (_NL_ADDRESS_POSTAL_FMT)+12; + _NL_NUM_LC_ADDRESS = (_NL_ADDRESS_POSTAL_FMT)+13; + _NL_TELEPHONE_TEL_INT_FMT = (__LC_TELEPHONE shl 16); + _NL_TELEPHONE_TEL_DOM_FMT = (_NL_TELEPHONE_TEL_INT_FMT)+1; + _NL_TELEPHONE_INT_SELECT = (_NL_TELEPHONE_TEL_INT_FMT)+2; + _NL_TELEPHONE_INT_PREFIX = (_NL_TELEPHONE_TEL_INT_FMT)+3; + _NL_TELEPHONE_CODESET = (_NL_TELEPHONE_TEL_INT_FMT)+4; + _NL_NUM_LC_TELEPHONE = (_NL_TELEPHONE_TEL_INT_FMT)+5; + _NL_MEASUREMENT_MEASUREMENT = (__LC_MEASUREMENT shl 16); + _NL_MEASUREMENT_CODESET = (_NL_MEASUREMENT_MEASUREMENT)+1; + _NL_NUM_LC_MEASUREMENT = (_NL_MEASUREMENT_MEASUREMENT)+2; + _NL_IDENTIFICATION_TITLE = (__LC_IDENTIFICATION shl 16); + _NL_IDENTIFICATION_SOURCE = (_NL_IDENTIFICATION_TITLE)+1; + _NL_IDENTIFICATION_ADDRESS = (_NL_IDENTIFICATION_TITLE)+2; + _NL_IDENTIFICATION_CONTACT = (_NL_IDENTIFICATION_TITLE)+3; + _NL_IDENTIFICATION_EMAIL = (_NL_IDENTIFICATION_TITLE)+4; + _NL_IDENTIFICATION_TEL = (_NL_IDENTIFICATION_TITLE)+5; + _NL_IDENTIFICATION_FAX = (_NL_IDENTIFICATION_TITLE)+6; + _NL_IDENTIFICATION_LANGUAGE = (_NL_IDENTIFICATION_TITLE)+7; + _NL_IDENTIFICATION_TERRITORY = (_NL_IDENTIFICATION_TITLE)+8; + _NL_IDENTIFICATION_AUDIENCE = (_NL_IDENTIFICATION_TITLE)+9; + _NL_IDENTIFICATION_APPLICATION = (_NL_IDENTIFICATION_TITLE)+10; + _NL_IDENTIFICATION_ABBREVIATION = (_NL_IDENTIFICATION_TITLE)+11; + _NL_IDENTIFICATION_REVISION = (_NL_IDENTIFICATION_TITLE)+12; + _NL_IDENTIFICATION_DATE = (_NL_IDENTIFICATION_TITLE)+13; + _NL_IDENTIFICATION_CATEGORY = (_NL_IDENTIFICATION_TITLE)+14; + _NL_IDENTIFICATION_CODESET = (_NL_IDENTIFICATION_TITLE)+15; + _NL_NUM_LC_IDENTIFICATION = (_NL_IDENTIFICATION_TITLE)+16; + _NL_NUM = (_NL_IDENTIFICATION_TITLE)+17; + +const + ERA_YEAR = __ERA_YEAR; + INT_CURR_SYMBOL = __INT_CURR_SYMBOL; + CURRENCY_SYMBOL = __CURRENCY_SYMBOL; + MON_DECIMAL_POINT = __MON_DECIMAL_POINT; + MON_THOUSANDS_SEP = __MON_THOUSANDS_SEP; + MON_GROUPING = __MON_GROUPING; + POSITIVE_SIGN = __POSITIVE_SIGN; + NEGATIVE_SIGN = __NEGATIVE_SIGN; + INT_FRAC_DIGITS = __INT_FRAC_DIGITS; + FRAC_DIGITS = __FRAC_DIGITS; + P_CS_PRECEDES = __P_CS_PRECEDES; + P_SEP_BY_SPACE = __P_SEP_BY_SPACE; + N_CS_PRECEDES = __N_CS_PRECEDES; + N_SEP_BY_SPACE = __N_SEP_BY_SPACE; + P_SIGN_POSN = __P_SIGN_POSN; + N_SIGN_POSN = __N_SIGN_POSN; + INT_P_CS_PRECEDES = __INT_P_CS_PRECEDES; + INT_P_SEP_BY_SPACE = __INT_P_SEP_BY_SPACE; + INT_N_CS_PRECEDES = __INT_N_CS_PRECEDES; + INT_N_SEP_BY_SPACE = __INT_N_SEP_BY_SPACE; + INT_P_SIGN_POSN = __INT_P_SIGN_POSN; + INT_N_SIGN_POSN = __INT_N_SIGN_POSN; + DECIMAL_POINT = __DECIMAL_POINT; + THOUSANDS_SEP = __THOUSANDS_SEP; + GROUPING = __GROUPING; + YESSTR = __YESSTR; + NOSTR = __NOSTR; +{$else} //bsd + LC_ALL = 0; + LC_COLLATE = 1; + LC_CTYPE = 2; + LC_MONETARY = 3; + LC_NUMERIC = 4; + LC_TIME = 5; + LC_MESSAGES = 6; + + _LC_LAST = 7; //* marks end */ + + CODESET = 0; //* codeset name */ + D_T_FMT = 1; //* string for formatting date and time */ + D_FMT = 2; //* date format string */ + T_FMT = 3; //* time format string */ + T_FMT_AMPM = 4; //* a.m. or p.m. time formatting string */ + AM_STR = 5; //* Ante Meridian affix */ + PM_STR = 6; //* Post Meridian affix */ + +//* week day names */ + DAY_1 = 7; + DAY_2 = 8; + DAY_3 = 9; + DAY_4 = 10; + DAY_5 = 11; + DAY_6 = 12; + DAY_7 = 13; + +//* abbreviated week day names */ + ABDAY_1 = 14; + ABDAY_2 = 15; + ABDAY_3 = 16; + ABDAY_4 = 17; + ABDAY_5 = 18; + ABDAY_6 = 19; + ABDAY_7 = 20; + +//* month names */ + MON_1 = 21; + MON_2 = 22; + MON_3 = 23; + MON_4 = 24; + MON_5 = 25; + MON_6 = 26; + MON_7 = 27; + MON_8 = 28; + MON_9 = 29; + MON_10 = 30; + MON_11 = 31; + MON_12 = 32; + +//* abbreviated month names */ + ABMON_1 = 33; + ABMON_2 = 34; + ABMON_3 = 35; + ABMON_4 = 36; + ABMON_5 = 37; + ABMON_6 = 38; + ABMON_7 = 39; + ABMON_8 = 40; + ABMON_9 = 41; + ABMON_10 = 42; + ABMON_11 = 43; + ABMON_12 = 44; + + ERA = 45; //* era description segments */ + ERA_D_FMT = 46; //* era date format string */ + ERA_D_T_FMT = 47; //* era date and time format string */ + ERA_T_FMT = 48; //* era time format string */ + ALT_DIGITS = 49; //* alternative symbols for digits */ + + RADIXCHAR = 50; //* radix char */ + DECIMAL_POINT = RADIXCHAR; + MON_DECIMAL_POINT = RADIXCHAR; + THOUSEP = 51; //* separator for thousands */ + THOUSANDS_SEP = THOUSEP; + MON_THOUSANDS_SEP = THOUSEP; + + YESEXPR = 52; //* affirmative response expression */ + NOEXPR = 53; //* negative response expression */ + +//#if __BSD_VISIBLE || __XSI_VISIBLE <= 500 + YESSTR = 54; //* affirmative response for yes/no queries */ + NOSTR = 55; //* negative response for yes/no queries */ +//#endif + + CRNCYSTR = 56; //* currency symbol */ + CURRENCY_SYMBOL = CRNCYSTR; + +//#if __BSD_VISIBLE + D_MD_ORDER = 57; //* month/day order (local extension) */ +//#endif + +//* standalone months forms for %OB */ + ALTMON_1 = 58; + ALTMON_2 = 59; + ALTMON_3 = 60; + ALTMON_4 = 61; + ALTMON_5 = 62; + ALTMON_6 = 63; + ALTMON_7 = 64; + ALTMON_8 = 65; + ALTMON_9 = 66; + ALTMON_10 = 67; + ALTMON_11 = 68; + ALTMON_12 = 69; + +{$endif} +type + Pnl_item = ^nl_item; + nl_item = longint; + +function nl_langinfo(__item: nl_item):Pchar; cdecl; external clib name 'nl_langinfo'; + +type + Psched_param = ^sched_param; + sched_param = record + __sched_priority : longint; + end; + __sched_param = sched_param; + P__sched_param = ^__sched_param; + TSchedParam = __sched_param; + PSchedParam = ^TSchedParam; + +//pthread +type + TStartRoutine = function (_para1:pointer): integer; cdecl;// pthread_create + Ppthread_condattr_t = ^pthread_condattr_t; + pthread_condattr_t = record + __dummy : longint; + end; + TPthreadCondattr = pthread_condattr_t; + PPthreadCondattr = ^TPthreadCondattr; +Const + PTHREAD_CREATE_JOINABLE = 0; + PTHREAD_CREATE_DETACHED = 1; + + PTHREAD_INHERIT_SCHED = 0; + PTHREAD_EXPLICIT_SCHED = 1; + + PTHREAD_SCOPE_SYSTEM = 0; + PTHREAD_SCOPE_PROCESS = 1; + + PTHREAD_MUTEX_TIMED_NP = 0; + PTHREAD_MUTEX_RECURSIVE_NP = 1; + PTHREAD_MUTEX_ERRORCHECK_NP = 2; + PTHREAD_MUTEX_ADAPTIVE_NP = 3; + PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP; + PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP; + PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP; + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL; + PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_ADAPTIVE_NP; + + PTHREAD_PROCESS_PRIVATE = 0; + PTHREAD_PROCESS_SHARED = 1; + + PTHREAD_RWLOCK_PREFER_READER_NP = 0; + PTHREAD_RWLOCK_PREFER_WRITER_NP = 1; + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP = 2; + PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_WRITER_NP; + + PTHREAD_ONCE_INIT = 0; +type + P_pthread_fastlock = ^_pthread_fastlock; + _pthread_fastlock = record + __status : longint; + __spinlock : longint; + end; + Ppthread_mutexattr_t = ^pthread_mutexattr_t; + + pthread_mutexattr_t = record + case integer of + 0:( __mutexkind : longint); + 1:(buffer: pointer); + end; + + Ppthread_t = ^pthread_t; + pthread_t = culong; + P_pthread_descr = ^_pthread_descr; + _pthread_descr = pointer; // Opaque type. + + P__pthread_attr_s = ^__pthread_attr_s; + __pthread_attr_s = record + __detachstate : longint; + __schedpolicy : longint; + __schedparam : __sched_param; + __inheritsched : longint; + __scope : longint; + __guardsize : size_t; + __stackaddr_set : longint; + __stackaddr : pointer; + __stacksize : size_t; + end; + pthread_attr_t = __pthread_attr_s; + Ppthread_attr_t = ^pthread_attr_t; + +const + __SIZEOF_SEM_T = {$ifdef CPU64}32{$else}16{$endif}; +type +//semaphore + Psem_t = ^sem_t; + sem_t = array[0..__SIZEOF_SEM_T-1] of byte; + { + sem_t = record + __sem_lock : _pthread_fastlock; + __sem_value : longint; + __sem_waiting : _pthread_descr; + end; + } + TSemaphore = sem_t; + PSemaphore = ^TSemaphore; + + Psigval = ^sigval; + sigval = record + case longint of + 0 : ( sival_int : cint ); + 1 : ( sival_ptr : pointer ); + end; + sigval_t = sigval; + Psigval_t = ^sigval_t; + +const + __SI_MAX_SIZE = 128; + {$ifdef CPU64} + __SI_PAD_SIZE = ((__SI_MAX_SIZE div sizeof (cint)) - 4); + {$else} + __SI_PAD_SIZE = ((__SI_MAX_SIZE div sizeof (cint)) - 3); + {$endif} +type + _si_pad = packed array[0..__SI_PAD_SIZE-1] of cint; + + // Borland compatibility types moved here, needed for siginfo + _si_sigchld = record + si_pid: __pid_t; + si_uid: __uid_t; + si_status: cint; + si_utime: __clock_t; + si_stime: __clock_t; + end; + + _si_kill = record + si_pid: __pid_t; + si_uid: __uid_t; + end; + + _si_sigfault = record + si_addr: Pointer; + end; + _si_sigpoll = record + si_band: clong; + si_fd: cint; + end; + _si_timer = record + _timer1: longword; + _timer2: longword; + end; + _si_rt = record + si_pid: __pid_t; + si_uid: __uid_t; + si_sigval: sigval_t; + end; + Psiginfo = ^_siginfo; + _siginfo = record + si_signo : cint; + si_errno : cint; + si_code : cint; + Case integer of + 0: (_pad: _si_pad); + 1: (_kill: _si_kill); + 2: (_timer: _si_timer); + 3: (_rt: _si_rt); + 4: (_sigchld: _si_sigchld); + 5: (_sigfault: _si_sigfault); + 6: (_sigpoll: _si_sigpoll); + end; + siginfo_t = _siginfo; + Psiginfo_t = ^siginfo_t; + Tsiginfo_t = siginfo_t; + + TSigActionHandlerEx = procedure(Signal: Integer; SignalInfo: PSigInfo; + P: Pointer); cdecl; + TRestoreHandler = procedure; cdecl; + +type + P__sig_atomic_t = ^__sig_atomic_t; + __sig_atomic_t = longint; +Const + _SIGSET_NWORDS = 1024 div (8 * (sizeof(dword))); +const +{$ifdef linux} + SA_NOCLDSTOP = 1; + SA_NOCLDWAIT = 2; + SA_SIGINFO = 4; + SA_ONSTACK = $08000000; + SA_RESTART = $10000000; + SA_NODEFER = $40000000; + SA_RESETHAND = $80000000; + + SA_INTERRUPT = $20000000; + SA_NOMASK = SA_NODEFER; + SA_ONESHOT = SA_RESETHAND; + SA_STACK = SA_ONSTACK; +{$else} + SA_ONSTACK = $0001; //* take signal on signal stack */ + SA_RESTART = $0002; //* restart system call on signal return */ + SA_RESETHAND = $0004; //* reset to SIG_DFL when taking signal */ + SA_NODEFER = $0010; //* don't mask the signal we're delivering */ + SA_NOCLDWAIT = $0020; //* don't keep zombies around */ + SA_SIGINFO = $0040; //* signal handler with SA_SIGINFO args */ +{$endif} + +type + P__sigset_t = ^__sigset_t; + __sigset_t = record + __val : array[0..(_SIGSET_NWORDS)-1] of dword; + end; + sigset_t = __sigset_t; + Psigset_t = ^sigset_t; + TSigset = __sigset_t; + PSigset = ^TSigset; + + TSigActionEx = packed record + sa_sigaction: TSigActionHandlerEx; + sa_mask: __sigset_t; + sa_flags: Integer; + sa_restorer: TRestoreHandler; + end; +type + __sighandler_t = procedure(SigNum: Integer); cdecl; + TSignalHandler = __sighandler_t; + P_sigaction = ^_sigaction; + _sigaction = record // Renamed, avoid conflict with sigaction function + case integer of + 1: (sa_handler : __sighandler_t; + sa_mask : __sigset_t; + sa_flags : longint; + sa_restorer : procedure ;cdecl; + ); + // Kylix compatibility + 2: (__sigaction_handler: __sighandler_t); + end; + TSigAction = _sigaction; + PSigAction = ^TSigAction; + __sigaction = _sigaction; + TSigActionHandler = procedure(Signal: Integer); cdecl; + +const + __S_IFMT = $F000; + __S_IFDIR = $4000; + __S_IFCHR = $2000; + __S_IFBLK = $6000; + __S_IFREG = $8000; + __S_IFIFO = $1000; + __S_IFLNK = $A000; + __S_IFSOCK = $C000; + + S_IFMT = __S_IFMT; + S_IFDIR = __S_IFDIR; + S_IFCHR = __S_IFCHR; + S_IFBLK = __S_IFBLK; + S_IFREG = __S_IFREG; + S_IFIFO = __S_IFIFO; + S_IFLNK = __S_IFLNK; + S_IFSOCK = __S_IFSOCK; + +function sigaction(__sig:longint; Const act: _sigaction; + Var oldact: _sigaction):longint; + cdecl;external clib name 'sigaction'; overload; +function sigaction(__sig: longint; Action: PSigAction; + OldAction: PSigAction): Integer; + cdecl;external clib name 'sigaction'; overload; + +//function m_sigprocmask(__how:longint; var SigSet : TSigSet; +// var oldset: Tsigset):longint;cdecl;external clib name 'sigprocmask'; +//function m_sigismember(var SigSet : TSigSet; SigNum : Longint):longint;cdecl;external clib name 'sigismember'; + +const + __SIZEOF_PTHREAD_MUTEX_T = {$ifdef CPU64}40{$else}24{$endif}; +type + Ppthread_mutex_t = ^pthread_mutex_t; + pthread_mutex_t = array[0..__SIZEOF_PTHREAD_MUTEX_T-1] of byte; +{ + pthread_mutex_t = record + __m_reserved : longint; + __m_count : longint; + __m_owner : _pthread_descr; + __m_kind : longint; + __m_lock : _pthread_fastlock; + end; +} + DIR = record end; + __dirstream = DIR; + PDIR = ^DIR; + + TDirectoryStream = DIR; + PDirectoryStream = ^TDirectoryStream; + + Ptimeval = ^timeval; + timeval = record + tv_sec : __time_t; + tv_usec : __suseconds_t; + end; + TTimeVal = timeval; + timezone = record + tz_minuteswest: Integer; + tz_dsttime: Integer; + end; + ptimezone = ^timezone; + + P__timezone_ptr_t = ^__timezone_ptr_t; + __timezone_ptr_t = ^timezone; + + passwd = record + pw_name: pcchar; //* user name */ + pw_passwd: pcchar; //* encrypted password */ + pw_uid: uid_t; //* user uid */ + pw_gid: gid_t; //* user gid */ + pw_change: time_t; //* password change time */ + pw_class: pcchar; //* user access class */ + pw_gecos: pcchar; //* Honeywell login info */ + pw_dir: pcchar; //* home directory */ + pw_shell: pcchar; //* default shell */ + pw_expire: time_t; //* account expiration */ + pw_fields: cint; //* internal: fields filled in */ + end; + ppasswd = ^passwd; + pppasswd = ^ppasswd; + +function getpid:__pid_t;cdecl;external clib name 'getpid'; +function getuid(): uid_t cdecl;external clib name 'getuid'; +function geteuid(): uid_t cdecl;external clib name 'geteuid'; + //function cuserid (_string: pcchar): pcchar; cdecl; external clib name 'cuserid'; + //not available on freebsd +function sscanf(__s:Pchar; __format:Pchar; args:array of const):longint;cdecl;external clib name 'sscanf'; +function sched_yield:longint;cdecl;external clib name 'sched_yield'; +function usleep(__useconds:__useconds_t):longint;cdecl;external clib name 'usleep'; +{$ifdef linux} +function __errno_location: PInteger; cdecl;external clib name '__errno_location'; +{$else} +function __errno_location: PInteger; cdecl;external clib name '__error'; +{$endif} +function strerror_r(__errnum:longint; __buf:Pchar; __buflen:size_t):Pchar;cdecl;external clib name 'strerror_r'; + +var + getpwuid_r: function(uid: uid_t; pwd: ppasswd; buffer: pchar; bufsize: size_t; + _result: pppasswd): cint cdecl; + cuserid: function(_string: pcchar): pcchar cdecl; + +//termios +const + NCCS = 32; +type + Pcc_t = ^cc_t; + cc_t = char; + + Pspeed_t = ^speed_t; + speed_t = dword; + + Ptcflag_t = ^tcflag_t; + tcflag_t = dword; + + Ptermios = ^termios; + termios = record + c_iflag : tcflag_t; + c_oflag : tcflag_t; + c_cflag : tcflag_t; + c_lflag : tcflag_t; + c_line : cc_t; + c_cc : array[0..(NCCS)-1] of cc_t; + c_ispeed : speed_t; + c_ospeed : speed_t; + end; + +const + DT_UNKNOWN = 0; + DT_FIFO = 1; + DT_CHR = 2; + DT_DIR = 4; + DT_BLK = 6; + DT_REG = 8; + DT_LNK = 10; + DT_SOCK = 12; + DT_WHT = 14; +type + Pdirent64 = ^dirent64; +{$ifdef linux} + dirent64 = record + d_ino : __ino64_t; + d_off : __off64_t; + d_reclen : word; + d_type : byte; + d_name : array[0..255] of char; + end; +{$else} + dirent64 = record + d_fileno: cuint32; //* file number of entry */ + d_reclen: cuint16; //* length of this record */ + d_type: cuint8; //* file type, see below */ + d_namlen: cuint8; //* length of string in d_name */ + d_name: array[0..255] of char; //* name must be no longer than this */ + end; +{$endif} + + PPDirEnt64 = ^PDirEnt64; + + time_t = __time_t; + Ptime_t = ^time_t; + + Ptm = ^tm; + tm = record + tm_sec : longint; + tm_min : longint; + tm_hour : longint; + tm_mday : longint; + tm_mon : longint; + tm_year : longint; + tm_wday : longint; + tm_yday : longint; + tm_isdst : longint; + case boolean of + false : (tm_gmtoff : longint;tm_zone : Pchar); + true : (__tm_gmtoff : longint;__tm_zone : Pchar); + end; + TMutexAttribute = pthread_mutexattr_t; + PMutexAttribute = ^TMutexAttribute; + +function pthread_mutexattr_init(var __attr: pthread_mutexattr_t):longint;cdecl; external threadslib; +function pthread_mutexattr_settype(var __attr: pthread_mutexattr_t; Kind: Integer): Integer; cdecl;external threadslib; +function pthread_mutexattr_destroy(var __attr: pthread_mutexattr_t):longint;cdecl; external threadslib; +function __mkdir(__path:Pchar; __mode:__mode_t):longint;cdecl; + external clib name 'mkdir'; +function fcntl(__fd: cint; __cmd: cint; args: array of const): cint; + cdecl; external clib name 'fcntl'; overload; +function fcntl(__fd: cint; __cmd: cint): cint; + cdecl; varargs; external clib name 'fcntl'; overload; +function open(__file:Pchar; __oflag: cint; args:array of const): cint; + cdecl; external clib name 'open'; overload; +function open(__file:Pchar; __oflag: cint): cint; + cdecl; varargs; external clib name 'open'; overload; +function __close(Handle: cint): cint; cdecl;external clib name 'close'; +{$ifdef linux} +function ftruncate64(handle: cint; size: cint64): cint; cdecl; + external clib name 'ftruncate64'; +{$else} +function ftruncate64(handle: cint; size: cint64): cint; cdecl; + external clib name 'ftruncate'; +{$endif} +//from unistd.h +//* Values for the second argument to access. +// These may be OR'd together. */ +const + R_OK = 4; //* Test for read permission. */ + W_OK = 2; //* Test for write permission. */ + X_OK = 1; //* Test for execute permission. */ + F_OK = 0; //* Test for existence. */ + +//* Test for access to NAME using the real UID and real GID. */ +function access(__name: pchar; __type: cint): cint; + cdecl; external clib name 'access'; + +function fsync(__fd: cint): cint; cdecl; external clib name 'fsync'; +function dup(__fd: cint): cint; cdecl; external clib name 'dup'; +function dup2(__fd: cint; __fd2: cint):longint; cdecl; external clib name 'dup2'; +function __read(Handle: cint; var Buffer; Count: size_t): ssize_t; + cdecl; external clib name 'read'; +function __write(Handle: cint; const Buffer; Count: size_t): ssize_t; + cdecl; external clib name 'write'; + +function chmod(__file: pchar;__mode: __mode_t): cint; + cdecl; external clib name 'chmod'; +function fchmod(__fd: cint;__mode: __mode_t): cint; + cdecl; external clib name 'fchmod'; + +function sem_init(__sem:Psem_t; __pshared: cint; __value: cuint): cint; + cdecl; external threadslib name 'sem_init'; overload; +function sem_init(var __sem: sem_t; __pshared: cint; __value: cuint): cint; + cdecl; external threadslib name 'sem_init'; overload; +function sem_destroy(var __sem: sem_t): cint; + cdecl; external threadslib name 'sem_destroy'; +function sem_post(var __sem: sem_t): cint; + cdecl; external threadslib name 'sem_post'; +function sem_wait(var __sem: sem_t): cint; + cdecl; external threadslib name 'sem_wait'; +function sem_trywait(var __sem: sem_t): cint; + cdecl; external threadslib name 'sem_trywait'; +function sem_getvalue(var __sem: sem_t; __sval:Plongint):longint;cdecl;external threadslib name 'sem_getvalue'; + +Const + PTHREAD_CANCEL_ENABLE = 0; + PTHREAD_CANCEL_DISABLE = 1; + + PTHREAD_CANCEL_DEFERRED = 0; + PTHREAD_CANCEL_ASYNCHRONOUS = 1; + + PTHREAD_CANCELED = Pointer(-1); + PTHREAD_BARRIER_SERIAL_THREAD = -1; + + NONRECURSIVE = 0; + {$ifdef linux} + RECURSIVE = 1; + {$else} + RECURSIVE = 2; + {$endif} + +function pthread_setcanceltype(__type:longint; var __oldtype:longint):longint; + cdecl; external threadslib; overload; +function pthread_setcanceltype(__type:longint; __oldtype:Plongint):longint; + cdecl;external threadslib name 'pthread_setcanceltype'; overload; +function pthread_setcancelstate(__state:longint;__oldstate:Plongint):longint; + cdecl;external threadslib name 'pthread_setcancelstate'; +function pthread_equal(__thread1:pthread_t; __thread2:pthread_t):longint; + cdecl;external threadslib name 'pthread_equal'; +function pthread_self:pthread_t;cdecl;external threadslib name 'pthread_self'; + +const + _STAT_VER_LINUX_OLD = 1; + _STAT_VER_KERNEL = 1; + _STAT_VER_SVR4 = 2; +{$ifdef CPU64} + _STAT_VER_LINUX = 1; +{$else} + _STAT_VER_LINUX = 3; +{$endif} + _STAT_VER = _STAT_VER_LINUX; + +{$ifdef linux} + +function __fxstat(__ver:longint; __fildes:longint; __stat_buf:Pstat):longint; + cdecl;external clib name '__fxstat'; +function __xstat(__ver:longint; __filename:Pchar; __stat_buf:Pstat):longint; + cdecl;external clib name '__xstat'; +function __lxstat(__ver:longint; __filename:Pchar; __stat_buf:Pstat):longint; + cdecl;external clib name '__lxstat'; +{$ifndef CPU64} +function __fxstat64(__ver:longint; __fildes:longint; __stat_buf:Pstat64):longint; + cdecl;external clib name '__fxstat64'; +function __xstat64(__ver:longint; __filename:Pchar; __stat_buf:Pstat64):longint; + cdecl;external clib name '__xstat64'; +function __lxstat64(__ver:longint; __filename:Pchar; __stat_buf:Pstat64):longint; + cdecl;external clib name '__lxstat64'; +{$endif} +function stat(__file:Pchar; __buf:Pstat):longint; +function fstat(__fd:longint; __buf:Pstat):longint; + +function stat64(__file:Pchar; __buf:Pstat64):longint; +function fstat64(__fd:longint; __buf:Pstat64):longint; +function lstat(__file:Pchar; __buf:Pstat):longint; +function lstat64(__file:Pchar; __buf:Pstat64):longint; +{$else} //linux +function stat(__file:Pchar; __buf:Pstat):longint; cdecl; + external clib name 'stat'; +function fstat(__fd:longint; __buf:Pstat):longint; cdecl; + external clib name 'fstat'; +function stat64(__file:Pchar; __buf:Pstat64):longint; cdecl; + external clib name 'stat'; +function fstat64(__fd:longint; __buf:Pstat64):longint; cdecl; + external clib name 'fstat'; +function lstat(__file:Pchar; __buf:Pstat):longint; cdecl; + external clib name 'lstat'; +function lstat64(__file:Pchar; __buf:Pstat64):longint; cdecl; + external clib name 'lstat'; +{$endif} //not linux + +function flock(fd: cint; operation: cint): cint; cdecl; + external clib name 'flock'; + +function S_ISDIR(mode : __mode_t) : boolean; + +//function fchmod(__fd: longint; __mode:__mode_t):longint;cdecl;external clib name 'fchmod'; +function __rename(__old: Pchar; __new:Pchar):longint;cdecl;external clib name 'rename'; +function unlink(__name: Pchar): longint;cdecl;external clib name 'unlink'; +function rmdir(__name: Pchar): longint;cdecl;external clib name 'rmdir'; +function getcwd(__buf: Pchar; __size:size_t):Pchar;cdecl;external clib name 'getcwd'; +function getenv(__name: Pchar): Pchar; cdecl; external clib name 'getenv'; +function setenv(envname: pchar; envval: pchar; + overwrite: cint): cint; cdecl; external clib name 'setenv'; +function putenv(astring: Pchar): longint; cdecl; external clib name 'putenv'; +function unsetenv(envname: pchar): cint; cdecl; external clib name 'unsetenv'; + +function __chdir(__path:Pchar):longint;cdecl;external clib name 'chdir'; +function opendir(__name:Pchar):PDIR;cdecl;external clib name 'opendir'; +function closedir(__dirp:PDIR):longint;cdecl;external clib name 'closedir'; + +var + environ : ppchar; cvar; external; + +type + TUnixTime = tm; + PUnixTime = ^TUnixTime; + TTime_T = Time_t; +function __time(var __timer : ttime_t):time_t;cdecl; + external clib name 'time'; overload; +function __time(__timer:Ptime_t):time_t; + cdecl;external clib name 'time'; overload; +function timelocal(var __tp: tm):time_t;cdecl;external clib name 'timelocal'; +function setlocale(__category:longint; __locale:Pchar):Pchar;cdecl; + external clib name 'setlocale'; +var + clock_gettime: function(clk_id: cint; tp: ptimespec): cint; cdecl; + +const +{$ifdef linux} + CLOCK_REALTIME = 0; + CLOCK_MONOTONIC = 1; + CLOCK_PROCESS_CPUTIME_ID = 2; + CLOCK_THREAD_CPUTIME_ID = 3; +{$else} + CLOCK_REALTIME = 0; + CLOCK_VIRTUAL = 1; + CLOCK_PROF = 2; + CLOCK_MONOTONIC = 4; + CLOCK_UPTIME = 5; //* FreeBSD-specific. */ + CLOCK_UPTIME_PRECISE = 7; //* FreeBSD-specific. */ + CLOCK_UPTIME_FAST = 8; //* FreeBSD-specific. */ + CLOCK_REALTIME_PRECISE = 9; //* FreeBSD-specific. */ + CLOCK_REALTIME_FAST = 10; //* FreeBSD-specific. */ + CLOCK_MONOTONIC_PRECISE = 11; //* FreeBSD-specific. */ + CLOCK_MONOTONIC_FAST = 12; //* FreeBSD-specific. */ + CLOCK_SECOND = 13; //* FreeBSD-specific. */ + CLOCK_THREAD_CPUTIME_ID = 14; + CLOCK_PROCESS_CPUTIME_ID = 15; +{$endif} + TIMER_ABSTIME = 1; + +const + SIG_ERR = (-1); + SIG_DFL = (0); + SIG_IGN = (1); + {$ifdef linux} + SIG_HOLD = (2); + {$else} + SIG_HOLD = (3); + {$endif} + {$ifdef linux} + SIGHUP = 1; + SIGINT = 2; + SIGQUIT = 3; + SIGILL = 4; + SIGTRAP = 5; + SIGABRT = 6; + SIGIOT = 6; + SIGBUS = 7; + SIGFPE = 8; + SIGKILL = 9; + SIGUSR1 = 10; + SIGSEGV = 11; + SIGUSR2 = 12; + SIGPIPE = 13; + SIGALRM = 14; + SIGTERM = 15; + SIGSTKFLT = 16; + SIGCHLD = 17; + SIGCLD = SIGCHLD; + SIGCONT = 18; + SIGSTOP = 19; + SIGTSTP = 20; + SIGTTIN = 21; + SIGTTOU = 22; + SIGURG = 23; + SIGXCPU = 24; + SIGXFSZ = 25; + SIGVTALRM = 26; + SIGPROF = 27; + SIGWINCH = 28; + SIGIO = 29; + SIGPOLL = SIGIO; + SIGPWR = 30; + SIGSYS = 31; + SIGUNUSED = 31; + _NSIG = 64; +{$else} + SIGHUP = 1; //* hangup */ + SIGINT = 2; //* interrupt */ + SIGQUIT = 3; //* quit */ + SIGILL = 4; //* illegal instr. (not reset when caught) */ + SIGTRAP = 5; //* trace trap (not reset when caught) */ + SIGABRT = 6; //* abort() */ + SIGIOT = SIGABRT; //* compatibility */ + SIGEMT = 7; //* EMT instruction */ + SIGFPE = 8; //* floating point exception */ + SIGKILL = 9; //* kill (cannot be caught or ignored) */ + SIGBUS = 10; //* bus error */ + SIGSEGV = 11; //* segmentation violation */ + SIGSYS = 12; //* non-existent system call invoked */ + SIGPIPE = 13; //* write on a pipe with no one to read it */ + SIGALRM = 14; //* alarm clock */ + SIGTERM = 15; //* software termination signal from kill */ + SIGURG = 16; //* urgent condition on IO channel */ + SIGSTOP = 17; //* sendable stop signal not from tty */ + SIGTSTP = 18; //* stop signal from tty */ + SIGCONT = 19; //* continue a stopped process */ + SIGCHLD = 20; //* to parent on child stop or exit */ + SIGTTIN = 21; //* to readers pgrp upon background tty read */ + SIGTTOU = 22; //* like TTIN if (tp->t_local<OSTOP) */ + SIGIO = 23; //* input/output possible signal */ + SIGXCPU = 24; //* exceeded CPU time limit */ + SIGXFSZ = 25; //* exceeded file size limit */ + SIGVTALRM = 26; //* virtual time alarm */ + SIGPROF = 27; //* profiling time alarm */ + SIGWINCH = 28; //* window size changes */ + SIGINFO = 29; //* information request */ + SIGUSR1 = 30; //* user defined signal 1 */ + SIGUSR2 = 31; //* user defined signal 2 */ + SIGTHR = 32; //* reserved by thread library. */ + SIGLWP = SIGTHR; + SIGLIBRT = 33; //* reserved by real-time library. */ +{$endif} +type + Psighandler_t = ^sighandler_t; + sighandler_t = __sighandler_t; + + __itimer_which = ( + ITIMER_REAL, // := 0, + ITIMER_VIRTUAL,// := 1, + ITIMER_PROF // := 2 + ); + + Pitimerval = ^itimerval; + itimerval = record + it_interval : timeval; + it_value : timeval; + end; + + P__itimer_which_t = ^__itimer_which_t; + __itimer_which_t = __itimer_which; + +function setitimer(__which: __itimer_which_t; __new:Pitimerval; + __old:Pitimerval):longint;cdecl;external clib name 'setitimer'; +type + wint_t = longword; + __mbstate_t = record + count: Integer; + case { __value } Integer of + 0: (__wch: wint_t); + 1: (__wchb: packed array[0..4 - 1] of Char); + end; + mbstate_t = __mbstate_t; + Pmbstate_t = ^mbstate_t; + +function mbsnrtowcs(__dst:Pwchar_t; __src:PPchar; __nmc:size_t; __len:size_t; __ps:Pmbstate_t):size_t;cdecl;external clib name 'mbsnrtowcs'; + +const + POLLIN = $001; + POLLPRI = $002; + POLLOUT = $004; + + POLLRDNORM = $040; + POLLRDBAND = $080; + POLLWRNORM = $100; + POLLWRBAND = $200; + + POLLMSG = $400; + + POLLERR = $008; + POLLHUP = $010; + POLLNVAL = $020; +type + Pnfds_t = ^nfds_t; + nfds_t = dword; + + Ppollfd = ^pollfd; + pollfd = record + fd : longint; + events : smallint; + revents : smallint; + end; +function poll(__fds: Ppollfd; __nfds:nfds_t; __timeout:longint): cint + cdecl external clib name 'poll'; +function ppoll (__fds: ppollfd;__nfds: nfds_t; __timeout: ptimespec; + __ss: p__sigset_t): cint + cdecl external clib name 'ppoll'; +const +{$ifdef linux} + SIG_BLOCK = 0; + SIG_UNBLOCK = 1; + SIG_SETMASK = 2; +{$else} + SIG_BLOCK = 1; //* block specified signal set */ + SIG_UNBLOCK = 2; //* unblock specified signal set */ + SIG_SETMASK =3; //* set specified signal set */ +{$endif} + +function signal(__sig:longint; __handler:__sighandler_t):__sighandler_t; + cdecl; external clib name 'signal'; +function sigemptyset(var SigSet : TSigSet):longint; + cdecl; external clib name 'sigemptyset'; +function sigfillset(var SigSet : TSigSet):longint; + cdecl; external clib name 'sigfillset'; +function sigaddset(var SigSet : TSigSet; SigNum : Longint):longint; + cdecl; external clib name 'sigaddset'; +function sigdelset(var SigSet : TSigSet; SigNum : Longint):longint; + cdecl; external clib name 'sigdelset'; +function sigismember(var SigSet : TSigSet; SigNum : Longint):longint; + cdecl; external clib name 'sigismember'; +function sigprocmask(__how: cint; sigset: p__sigset_t; + oldset: p__sigset_t):longint; + cdecl; external clib name 'sigprocmask'; +function pthread_sigmask(__how: cint; __newmask: p__sigset_t; + __oldmask: p__sigset_t):longint; cdecl; + external threadslib name 'pthread_sigmask'; + +function kill(__pid:__pid_t; __sig:longint):longint;cdecl; + external clib name 'kill'; +{$ifdef linux} +function getpt:longint;cdecl;external clib name 'getpt'; +{$else} +function posix_openpt(oflag: cint):longint; cdecl; + external clib name 'posix_openpt'; +function getpt(): longint; +{$endif} +function grantpt(__fd:longint):longint;cdecl;external clib name 'grantpt'; +function unlockpt(__fd:longint):longint;cdecl;external clib name 'unlockpt'; +{$ifdef linux} +function ptsname_r(__fd:longint; __buf:Pchar; __buflen:size_t):longint;cdecl;external clib name 'ptsname_r'; +{$else} +function ptsname(fildes: cint): pchar; cdecl; external clib name 'ptsname'; +function ptsname_r(__fd:longint; __buf:Pchar; __buflen:size_t):longint; +{$endif} + +const + VINTR = 0; + VQUIT = 1; + VERASE = 2; + VKILL = 3; + VEOF = 4; + VTIME = 5; + VMIN = 6; + VSWTC = 7; + VSTART = 8; + VSTOP = 9; + VSUSP = 10; + VEOL = 11; + VREPRINT = 12; + VDISCARD = 13; + VWERASE = 14; + VLNEXT = 15; + VEOL2 = 16; + + IGNBRK = $0000001; + BRKINT = $0000002; + IGNPAR = $0000004; + PARMRK = $0000008; + INPCK = $0000010; + ISTRIP = $0000020; + INLCR = $0000040; + IGNCR = $0000080; + ICRNL = $0000100; + IUCLC = $0000200; + IXON = $0000400; + IXANY = $0000800; + IXOFF = $0001000; + IMAXBEL = $0002000; + + OPOST = $0000001; + OLCUC = $0000002; + ONLCR = $0000004; + OCRNL = $0000008; + ONOCR = $0000010; + ONLRET = $0000020; + OFILL = $0000040; + OFDEL = $0000080; + + NLDLY = $0000040; + NL0 = $0000000; + NL1 = $0000100; + CRDLY = $0000600; + CR0 = $0000000; + CR1 = $0000200; + CR2 = $0000400; + CR3 = $0000600; + TABDLY = $0001800; + TAB0 = $0000000; + TAB1 = $0000800; + TAB2 = $0001000; + TAB3 = $0001800; + BSDLY = $0002000; + BS0 = $0000000; + BS1 = $0002000; + FFDLY = $0080000; + FF0 = $0000000; + FF1 = $0010000; + + VTDLY = $0004000; + VT0 = $0000000; + VT1 = $0004000; + + XTABS = $0001800; + + CBAUD = $000100F; + B0 = $0000000; + B50 = $0000001; + B75 = $0000002; + B110 = $0000003; + B134 = $0000004; + B150 = $0000005; + B200 = $0000006; + B300 = $0000007; + B600 = $0000008; + B1200 = $0000009; + B1800 = $000000A; + B2400 = $000000B; + B4800 = $000000C; + B9600 = $000000D; + B19200 = $000000E; + B38400 = $000000F; + + EXTA = B19200; + EXTB = B38400; + + CSIZE = $0000030; + CS5 = $0000000; + CS6 = $0000010; + CS7 = $0000010; + CS8 = $0000030; + CSTOPB = $0000040; + CREAD = $0000080; + PARENB = $0000100; + PARODD = $0000200; + HUPCL = $0000400; + CLOCAL = $0000800; + + CBAUDEX = $0001000; + + B57600 = $0001001; + B115200 = $0001002; + B230400 = $0001003; + B460800 = $0001004; + B500000 = $0001005; + B576000 = $0001006; + B921600 = $0001007; + B1000000 = $0001008; + B1152000 = $0001009; + B1500000 = $000100A; + B2000000 = $000100B; + B2500000 = $000100C; + B3000000 = $000100D; + B3500000 = $000100E; + B4000000 = $000100F; + + CIBAUD = $100F0000; + CRTSCTS = $80000000; + + ISIG = $0000001; + ICANON = $0000002; + + XCASE = $0000004; + + ECHO = $0000008; + ECHOE = $0000010; + ECHOK = $0000020; + ECHONL = $0000040; + NOFLSH = $0000080; + TOSTOP = $0000100; + + ECHOCTL = $0000200; + ECHOPRT = $0000400; + ECHOKE = $0000800; + FLUSHO = $0001000; + PENDIN = $0004000; + + IEXTEN = $0010000; + + + + TCOOFF = 0; + TCOON = 1; + TCIOFF = 2; + TCION = 3; + TCIFLUSH = 0; + TCOFLUSH = 1; + TCIOFLUSH = 2; + TCSANOW = 0; + TCSADRAIN = 1; + TCSAFLUSH = 2; + {$ifdef bsd} + SIGRTMIN = 65; + SIGRTMAX = 126; + {$else} +function SIGRTMIN(): cint; cdecl; external clib name '__libc_current_sigrtmin'; +function SIGRTMAX(): cint; cdecl; external clib name '__libc_current_sigrtmax'; + {$endif} +function ioctl(__fd: cint; __request:dword; args: array of const): cint; + cdecl;external clib name 'ioctl'; overload; +function ioctl(__fd: cint; __request: cuint; args: pointer): cint; + cdecl;external clib name 'ioctl'; overload; +function cfsetispeed(var __termios_p: termios; __speed:speed_t): cint; + cdecl;external clib name 'cfsetispeed'; +function cfsetospeed(var __termios_p: termios; __speed:speed_t): cint; + cdecl;external clib name 'cfsetospeed'; +function isatty(__fd: cint): cint; cdecl; external clib name 'isatty'; +function ttyname(__fd: cint): pchar; cdecl; external clib name 'ttyname'; +function ttyname_r(__fd: cint; buf: pchar; buflen: size_t): cint; + cdecl; external clib name 'ttyname_r'; + +const + TIOCM_LE = $001; + TIOCM_DTR = $002; + TIOCM_RTS = $004; + TIOCM_ST = $008; + TIOCM_SR = $010; + TIOCM_CTS = $020; + TIOCM_CAR = $040; + TIOCM_RNG = $080; + TIOCM_DSR = $100; + TIOCM_CD = TIOCM_CAR; + TIOCM_RI = TIOCM_RNG; + N_TTY = 0; + N_SLIP = 1; + N_MOUSE = 2; + N_PPP = 3; + N_STRIP = 4; + N_AX25 = 5; + N_X25 = 6; + N_6PACK = 7; + N_MASC = 8; + N_R3964 = 9; + N_PROFIBUS_FDL = 10; + N_IRDA = 11; + N_SMSBLOCK = 12; + N_HDLC = 13; + N_SYNC_PPP = 14; + N_HCI = 15; + +function gettimeofday(var __tv: timeval; var _tz: timezone):longint; + cdecl;external clib name 'gettimeofday'; overload; +function gettimeofday(var __tv: timeval; __tz:__timezone_ptr_t):longint; + cdecl;external clib name 'gettimeofday'; overload; +function pthread_kill(__thread:pthread_t; __signo:longint):longint; + cdecl;external threadslib name 'pthread_kill'; +const + WNOHANG = 1; + WUNTRACED = 2; + __WALL = $40000000; + __WCLONE = $80000000; +function waitpid(__pid:__pid_t; __stat_loc:Plongint; __options:longint):__pid_t; + cdecl;external clib name 'waitpid'; overload; +function waitpid(__pid:__pid_t; var __stat_loc:longint; + __options:longint):__pid_t; + cdecl;external clib name 'waitpid'; overload; + +function WEXITSTATUS(status: cint): cint; +function WTERMSIG(status: cint): cint; +function WIFEXITED(status: cint): boolean; +function WIFSIGNALED(status: cint): boolean; + +function __system(__command:Pchar):longint;cdecl;external clib name 'system'; +type + TPipeDescriptors = {packed} record + ReadDes: Integer; + WriteDes: Integer; + end; + PPipeDescriptors = ^TPipeDescriptors; + + TPipes = Array[0..1] of longint; + PPipes = ^TPipes; + +function pipe(var __pipedes: TPipes):longint; + cdecl; external clib name 'pipe'; overload; +function pipe(var PipeDes: TPipeDescriptors): Integer; cdecl; + external clib name 'pipe'; overload; +function pipe2(var PipeDes: TPipeDescriptors; flags: cint): Integer; cdecl; + external clib name 'pipe2'; + +function vfork: __pid_t; cdecl; external clib name 'vfork'; +function fork: __pid_t; cdecl; external clib name 'fork'; +function setsid: __pid_t; cdecl; external clib name 'setsid'; +function getsid(pid: __pid_t): __pid_t; cdecl; external clib name 'getsid'; +function setpgid(__pid:__pid_t; __pgid:__pid_t):longint; cdecl; + external clib name 'setpgid'; +function getpgid(pid: __pid_t): __pid_t; cdecl; external clib name 'getpgid'; + +const + EXIT_FAILURE = 1; + EXIT_SUCCESS = 0; + +procedure _exit (__status : longint); cdecl; external clib name '_exit'; +function execl(__path:Pchar; __arg:Pchar):longint; + cdecl;varargs;external clib name 'execl'; overload; +function execl(__path:Pchar; __arg:Pchar; args:array of const):longint; + cdecl;external clib name 'execl'; overload; +function execv (__path: pcchar; __argv: ppchar): cint; + cdecl;external clib name 'execv'; +function execve(__path: pcchar; __argv: ppchar; __envp:ppchar): cint; + cdecl;external clib name 'execve'; + +Type + error_t = Integer; + +function errno : error_t; +procedure free(__ptr:pointer);cdecl;external clib name 'free'; + +type + Psa_family_t = ^sa_family_t; + sa_family_t = word; + SunB = record + s_b1, + s_b2, + s_b3, + s_b4: u_char; + end; + + SunW = record + s_w1, + s_w2: u_short; + end; + in_addr = record + case Integer of + 0: (S_un_b: SunB); + 1: (S_un_w: SunW); + 2: (S_addr: u_long); + end; + TInAddr = in_addr; + PInAddr = ^TInAddr; + {$ifdef linux} + sockaddr = {packed} record + case Integer of + 0: (sa_family: sa_family_t; + sa_data: packed array[0..13] of Byte); + 1: (sin_family: sa_family_t; + sin_port: u_short; + sin_addr: TInAddr; + sin_zero: packed array[0..7] of Byte); + end; + {$else} + sockaddr = record + sa_len: byte; //* total length */ + case integer of + 0: (sa_family: sa_family_t; //* address family */ + sa_data: packed array[0..13] of Byte); //* actually longer; address value */ + 1: (sin_family: sa_family_t; + sin_port: u_short; + sin_addr: TInAddr; + sin_zero: packed array[0..7] of Byte); + end; + {$endif} + + TSockAddr = sockaddr; + PSockAddr = ^TSockAddr; + + sockaddr_in = sockaddr; + Psockaddr_in = ^sockaddr; + TSockAddrIn = sockaddr_in; + PSockAddrIn = ^TSockAddrIn; + Pin_port_t = ^in_port_t; + in_port_t = uint16_t; + + Pin6_addr = ^in6_addr; + in6_addr = record + case longint of + 0 : ( in6_u : record + case longint of + 0 : ( u6_addr8 : array[0..15] of uint8_t ); + 1 : ( u6_addr16 : array[0..7] of uint16_t ); + 2 : ( u6_addr32 : array[0..3] of uint32_t ); + end;); + 1 : (case Integer of + 0: (s6_addr: packed array [0..16-1] of __uint8_t); + 1: (s6_addr16: packed array [0..8-1] of uint16_t); + 2: (s6_addr32: packed array [0..4-1] of uint32_t); + ); + end; + + + Psockaddr_in6 = ^sockaddr_in6; + sockaddr_in6 = record + sin6_family: sa_family_t; + sin6_port : in_port_t; + sin6_flowinfo : uint32_t; + sin6_addr : in6_addr; + sin6_scope_id : uint32_t; + end; +Const + PF_UNSPEC = 0; + PF_LOCAL = 1; + PF_UNIX = PF_LOCAL; + PF_FILE = PF_LOCAL; + PF_INET = 2; + PF_AX25 = 3; + PF_IPX = 4; + PF_APPLETALK = 5; + PF_NETROM = 6; + PF_BRIDGE = 7; + PF_ATMPVC = 8; + PF_X25 = 9; + PF_INET6 = 10; + PF_ROSE = 11; + PF_DECnet = 12; + PF_NETBEUI = 13; + PF_SECURITY = 14; + PF_KEY = 15; + PF_NETLINK = 16; + PF_ROUTE = PF_NETLINK; + PF_PACKET = 17; + PF_ASH = 18; + PF_ECONET = 19; + PF_ATMSVC = 20; + PF_SNA = 22; + PF_IRDA = 23; + PF_PPPOX = 24; + PF_WANPIPE = 25; + PF_BLUETOOTH = 31; + PF_MAX = 32; + AF_UNSPEC = PF_UNSPEC; + AF_LOCAL = PF_LOCAL; + AF_UNIX = PF_UNIX; + AF_FILE = PF_FILE; + AF_INET = PF_INET; + AF_AX25 = PF_AX25; + AF_IPX = PF_IPX; + AF_APPLETALK = PF_APPLETALK; + AF_NETROM = PF_NETROM; + AF_BRIDGE = PF_BRIDGE; + AF_ATMPVC = PF_ATMPVC; + AF_X25 = PF_X25; + AF_INET6 = PF_INET6; + AF_ROSE = PF_ROSE; + AF_DECnet = PF_DECnet; + AF_NETBEUI = PF_NETBEUI; + AF_SECURITY = PF_SECURITY; + AF_KEY = PF_KEY; + AF_NETLINK = PF_NETLINK; + AF_ROUTE = PF_ROUTE; + AF_PACKET = PF_PACKET; + AF_ASH = PF_ASH; + AF_ECONET = PF_ECONET; + AF_ATMSVC = PF_ATMSVC; + AF_SNA = PF_SNA; + AF_IRDA = PF_IRDA; + AF_PPPOX = PF_PPPOX; + AF_WANPIPE = PF_WANPIPE; + AF_BLUETOOTH = PF_BLUETOOTH; + AF_MAX = PF_MAX; + SOL_RAW = 255; + SOL_DECNET = 261; + SOL_X25 = 262; + SOL_PACKET = 263; + SOL_ATM = 264; + SOL_AAL = 265; + SOL_IRDA = 266; + SOMAXCONN = 128; + +type +{$ifdef FPC} + __socket_type = ( + SOCK_STREAM := 1, + SOCK_DGRAM := 2, + SOCK_RAW := 3, + SOCK_RDM := 4, + SOCK_SEQPACKET := 5, + SOCK_PACKET := 10 + ); + {$else} + __socket_type = type cenum; +const + SOCK_STREAM = 1; + SOCK_DGRAM = 2; + SOCK_RAW = 3; + SOCK_RDM = 4; + SOCK_SEQPACKET = 5; + SOCK_PACKET = 10; +type + {$endif} + TSocket = longint; + SOCKLEN_T = __socklen_t; + PSOCKLEN_T = ^SOCKLEN_T; + + Paddrinfo = ^addrinfo; + addrinfo = record + ai_flags : longint; + ai_family : longint; + ai_socktype : longint; + ai_protocol : longint; + ai_addrlen : socklen_t; + ai_addr : Psockaddr; + ai_canonname : Pchar; + ai_next : Paddrinfo; + end; + PPaddrinfo = ^Paddrinfo; + +const + SOL_SOCKET = 1; + SO_DEBUG = 1; + SO_REUSEADDR = 2; + SO_TYPE = 3; + SO_ERROR = 4; + SO_DONTROUTE = 5; + SO_BROADCAST = 6; + SO_SNDBUF = 7; + SO_RCVBUF = 8; + SO_KEEPALIVE = 9; + SO_OOBINLINE = 10; + SO_NO_CHECK = 11; + SO_PRIORITY = 12; + SO_LINGER = 13; + SO_BSDCOMPAT = 14; + SO_PASSCRED = 16; + SO_PEERCRED = 17; + SO_RCVLOWAT = 18; + SO_SNDLOWAT = 19; + SO_RCVTIMEO = 20; + SO_SNDTIMEO = 21; + SO_SECURITY_AUTHENTICATION = 22; + SO_SECURITY_ENCRYPTION_TRANSPORT = 23; + SO_SECURITY_ENCRYPTION_NETWORK = 24; + SO_BINDTODEVICE = 25; + SO_ATTACH_FILTER = 26; + SO_DETACH_FILTER = 27; + SO_PEERNAME = 28; + SO_TIMESTAMP = 29; + SCM_TIMESTAMP = SO_TIMESTAMP; + SO_ACCEPTCONN = 30; + +function socket(__domain:longint; __type:longint; __protocol:longint):longint; + cdecl;external clib name 'socket'; overload; +{$ifdef FPC} +function socket(__domain: Integer; __type: __socket_type; + __protocol: Integer): TSocket; + cdecl;external clib name 'socket'; overload; +{$endif} +function shutdown(__fd:longint; __how:longint):longint;cdecl;external clib name 'shutdown'; +function connect(__fd:longint; const __addr: sockaddr; + __len:socklen_t):longint;cdecl;external clib name 'connect'; overload; +function connect(__fd:longint; __addr:Psockaddr; + __len:socklen_t):longint;cdecl;external clib name 'connect'; overload; +{$ifdef linux} +function __libc_sa_len(__af: sa_family_t): Integer; cdecl;external clib name '__libc_sa_len'; +{$else} + //use len field of FreeBSD struct +{$endif} +function bind(__fd:longint; __addr:Psockaddr; __len:socklen_t):longint;cdecl;external clib name 'bind'; +//function SA_LEN(const buf): longword; // Untyped buffer; this is *unsafe*. +function listen(__fd:longint; __n:longint):longint;cdecl;external clib name 'listen'; +function accept(__fd:longint; __addr:Psockaddr; __addr_len:Psocklen_t):longint;cdecl;external clib name 'accept'; +function isfdtype(__fd:longint; __fdtype:longint):longint;cdecl;external clib name 'isfdtype'; +function setsockopt(__fd:longint; __level:longint; __optname:longint; __optval:pointer; __optlen:socklen_t):longint;cdecl;external clib name 'setsockopt'; +function getaddrinfo(__name:Pchar; __service:Pchar; __req:Paddrinfo; __pai:PPaddrinfo):longint;cdecl;external clib name 'getaddrinfo'; +function htons(__hostshort:uint16_t):uint16_t;cdecl;external clib name 'htons'; +procedure freeaddrinfo(__ai:Paddrinfo);cdecl;external clib name 'freeaddrinfo'; +function ntohs(__netshort:uint16_t):uint16_t;cdecl;external clib name 'ntohs'; + +function gai_strerror(__ecode:longint):Pchar;cdecl;external clib name 'gai_strerror'; +function syscall(SysNo: Longint): Integer; cdecl; varargs; + external clib name 'syscall'; + + +const + recursiveconst = PTHREAD_MUTEX_RECURSIVE; +// libcmodulename = 'c'; +const + NR_sendfile = 187; + __SIZEOF_PTHREAD_COND_T = {$ifdef CPU64}48{$else}48{$endif}; +type + tcondvar = array[0..__SIZEOF_PTHREAD_COND_T-1] of byte; + +function gettimeofday(__tv:Ptimeval; __tz:ptimezone):longint;cdecl; + external clib name 'gettimeofday'; overload; +function msetcgetattr(filedes: longint; + var msetermios: termios{ty}): longint; + cdecl;external clib name 'tcgetattr'; +function msetcsetattr(filedes: longint; when: longint; + var msetermios: termios{ty}): longint; + cdecl;external clib name 'tcsetattr'; +function tcdrain(filedes: longint): longint;cdecl;external clib name 'tcdrain'; +function tcflush(filedes: longint; queue_selector: longint): longint; + cdecl;external clib name 'tcflush'; + +function pthread_create(__thread:Ppthread_t; __attr:Ppthread_attr_t; + __start_routine:TStartRoutine; __arg:pointer):longint;cdecl; + external threadslib name 'pthread_create'; +function pthread_join(__th:pthread_t; __thread_return:Ppointer):longint;cdecl; + external threadslib name 'pthread_join'; +function pthread_detach(__th:pthread_t):longint;cdecl; + external threadslib name 'pthread_detach'; +function pthread_cancel(__thread: pthread_t):longint; + cdecl;external threadslib name 'pthread_cancel'; + +function pthread_attr_init(var __attr: pthread_attr_t):longint;cdecl; + external threadslib name 'pthread_attr_init'; + +function pthread_cond_init(var Cond: TCondVar; + CondAttr: PPthreadCondattr): Integer; cdecl; + external threadslib name 'pthread_cond_init'; +function pthread_cond_destroy(var Cond: TCondVar): Integer; cdecl; + external threadslib name 'pthread_cond_destroy'; +function pthread_cond_wait(var Cond: TCondVar; + var Mutex: pthread_mutex_t): Integer; cdecl; + external threadslib name 'pthread_cond_wait'; +function pthread_cond_timedwait(var Cond: TCondVar; + var Mutex: pthread_mutex_t; AbsTime: pTimeSpec): Integer; cdecl; + external threadslib name 'pthread_cond_timedwait'; +function pthread_cond_broadcast(var Cond: TCondVar): Integer; cdecl; + external threadslib name 'pthread_cond_broadcast'; +function pthread_cond_signal(var Cond: TCondVar): Integer; cdecl; + external threadslib name 'pthread_cond_signal'; +function sem_timedwait(var __sem: TSemaphore; __abstime: ptimespec): Integer; cdecl; + external threadslib name 'sem_timedwait'; + + +function pthread_mutex_init(__mutex: Ppthread_mutex_t; + __mutex_attr: Ppthread_mutexattr_t): longint; cdecl; + external threadslib name 'pthread_mutex_init'; +function pthread_mutex_destroy(var Mutex: pthread_mutex_t): Integer; cdecl; + external threadslib name 'pthread_mutex_destroy'; +function pthread_mutex_lock(var Mutex: pthread_mutex_t): Integer; cdecl; + external threadslib name 'pthread_mutex_lock'; +function pthread_mutex_trylock(var Mutex: pthread_mutex_t): Integer; cdecl; + external threadslib name 'pthread_mutex_trylock'; +function pthread_mutex_unlock(var Mutex: pthread_mutex_t): Integer; cdecl; + external threadslib name 'pthread_mutex_unlock'; + +{$ifdef linux} +function readdir64_r(__dirp:PDIR; __entry:Pdirent64; + __result:PPdirent64):longint;cdecl;external clib name 'readdir64_r'; +{$else} +function readdir64_r(__dirp:PDIR; __entry:Pdirent64; + __result:PPdirent64):longint;cdecl;external clib name 'readdir_r'; +{$endif} +function localtime_r(__timer:Ptime_t; __tp:Ptm):Ptm;cdecl; + external clib name 'localtime_r'; + +const +//* Protections are chosen from these bits, OR'd together. The +// implementation does not necessarily support PROT_EXEC or PROT_WRITE +// without PROT_READ. The only guarantees are that no writing will be +// allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ + PROT_READ = $1; //* Page can be read. */ + PROT_WRITE = $2; //* Page can be written. */ + PROT_EXEC = $4; //* Page can be executed. */ + PROT_NONE = $0; //* Page can not be accessed. */ + PROT_GROWSDOWN = $01000000; //* Extend change to start of + //growsdown vma (mprotect only). */ + PROT_GROWSUP = $02000000; //* Extend change to start of + //growsup vma (mprotect only). */ + +//* Sharing types (must choose one and only one of these). */ + MAP_SHARED = $01; //* Share changes. */ + MAP_PRIVATE = $02; //* Changes are private. */ + MAP_TYPE = $0f; //* Mask for type of mapping. */ + +//* Other flags. */ + MAP_FIXED = $10; //* Interpret addr exactly. */ + MAP_FILE = 0; + MAP_ANONYMOUS = $20; //* Don't use a file. */ +//* When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. */ + MAP_HUGE_SHIFT = 26; + MAP_HUGE_MASK = $3f; + + MAP_FAILED = pointer(ptrint(-1)); + +function shm_open(name: pcchar; oflag: cint; mode: mode_t): cint; cdecl; + external shmlib name 'shm_open'; +function shm_unlink(name: pcchar): cint; cdecl; + external shmlib name 'shm_unlink'; +function mmap(addr: pointer; lengthint: size_t; prot: cint; flags: cint; + fd: cint; offset: off_t): pointer; cdecl; + external clib name 'mmap'; +function munmap(addr: pointer; length: size_t): cint; cdecl; + external clib name 'munmap'; + +procedure initlibc(); + +implementation +uses + msedynload{,msesys}; +{$ifndef linux} +function getpt(): longint; +begin + result:= posix_openpt(O_RDWR); +end; + +function ptsname_r(__fd:longint; __buf:Pchar; __buflen:size_t):longint; +var + ps,pd,pend: pcchar; +begin + result:= -1; + if __buf = nil then begin + __errno_location()^:= EINVAL; + end + else begin + PS:= PTSNAME(__FD); + IF PS <> NIL THEN BEGIN + PD:= __BUF; + PEND:= PD + __BUFLEN; + WHILE pd < PEND do begin + pd^:= ps^; + if ps^ = #0 then begin + break; + end; + inc(pd); + inc(ps); + end; + if (pd >= pend) then begin + __errno_location()^:= ERANGE; + end + else begin + result:= 0; + end; + end; + end; +end; + +{$endif} + +function WEXITSTATUS(status: cint): cint; +begin + result:=(status and $ff00) shr 8; +end; + +function WTERMSIG(status: cint): cint; +begin + result:= status and $7f; +end; + +function WIFEXITED(status: cint): boolean; +begin + result:= status and $7f = 0; +end; + +function WIFSIGNALED(status: cint): boolean; +begin + result:= (status and $7f <> $7f) and (status and $7f <> 0); +end; + +function errno: error_t; +begin + result:=__errno_location()^; +end; +{ +function SA_LEN(const Buf): longword; // Untyped buffer; this is *unsafe*. + +begin + Result:=__libc_sa_len(PSockAddr(@Buf)^.sa_family); +end; +} +function S_ISDIR(mode: __mode_t) : boolean; +begin + result:= mode and __S_IFDIR = __S_IFDIR; +end; + +{$ifdef linux} + +function stat(__file:Pchar; __buf: Pstat): longint; +begin + result:= __xstat(_STAT_VER,__file,__buf); +end; + +function fstat(__fd:longint; __buf: Pstat): longint; +begin + result:= __fxstat(_STAT_VER,__fd,__buf); +end; + +function lstat(__file:Pchar; __buf: Pstat): longint; +begin + result:= __lxstat(_STAT_VER,__file,__buf); +end; + +function stat64(__file:Pchar; __buf:Pstat64):longint; +begin +{$ifdef CPU64} + result:= __xstat(_STAT_VER,__file,__buf); +{$else} + result:= __xstat64(_STAT_VER,__file,__buf); +{$endif} +end; + +function fstat64(__fd:longint; __buf:Pstat64):longint; +begin +{$ifdef CPU64} + result:= __fxstat(_STAT_VER,__fd,__buf); +{$else} + result:= __fxstat64(_STAT_VER,__fd,__buf); +{$endif} +end; + +function lstat64(__file:Pchar; __buf:Pstat64):longint; +begin +{$ifdef CPU64} + result:= __lxstat(_STAT_VER,__file,__buf); +{$else} + result:= __lxstat64(_STAT_VER,__file,__buf); +{$endif} +end; + +{$endif} //linux + +var + rtlibinfo: dynlibinfoty; + +procedure initlib; +const + funcs: array[0..2] of funcinfoty = ( + (n: 'clock_gettime'; d: @clock_gettime), //0 + (n: 'getpwuid_r'; d: @getpwuid_r), //1 + (n: 'cuserid'; d: @cuserid) //2 + ); +begin + try + initializedynlib(rtlibinfo,['librt.so.1','librt.so','libc.so.6'],[], + [],funcs); + except + end; +end; + +var + inited: boolean; + +procedure initlibc(); +begin + if not inited then begin + inited:= true; + initializelibinfo(rtlibinfo); + initlib(); + end; +end; + +initialization + initlibc(); +finalization + finalizelibinfo(rtlibinfo); +end. diff --git a/mseide-msegui/lib/common/kernel/msemacros.pas b/mseide-msegui/lib/common/kernel/msemacros.pas new file mode 100644 index 0000000..431623a --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msemacros.pas @@ -0,0 +1,1096 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msemacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msestrings,mselist,msearrayutils,msetypes,msestat,msedatalist,mclasses, + mseclasses,msearrayprops; + +type + tmacrolist = class; + macrohandlerty = function(const sender: tmacrolist; + const params: msestringarty): msestring; + macrohandlerarty = array of macrohandlerty; + + macroinfoty = record + name,value: msestring; + handler: macrohandlerty; + expandlevel: integer; + end; + pmacroinfoty = ^macroinfoty; + macroinfoarty = array of macroinfoty; + macroinfoaty = array[0..0] of macroinfoty; + pmacroinfoaty = ^macroinfoaty; + + macrooptionty = (mao_caseinsensitive,mao_curlybraceonly,mao_removeunknown); + macrooptionsty = set of macrooptionty; + + tmacrolist = class(torderedrecordlist,istatupdatevalue) + private + foptions: macrooptionsty; + fpredefined: macroinfoarty; + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + function compare(const l,r): integer; + function getcomparefunc: sortcomparemethodty; override; + procedure setrec(const index: integer; const avalue: msestring); + function getrec(const index: integer): msestring; + procedure resetexpandlevel; + function getvalue(const aname: msestring; var aexpandlevel: integer; + out found: pmacroinfoty): msestring; + function callhandler(const aname: msestring;const aparams: msestringarty; + var aexpandlevel: integer; out found: pmacroinfoty): msestring; + //istatupdatevalue + procedure statreadvalue(const aname: msestring; const reader: tstatreader); + procedure statwritevalue(const aname: msestring; const writer: tstatwriter); + procedure internalexpandmacros(var avalue: msestring; expandlevel: integer; + var refindex: integerarty); + public + constructor create(const aoptions: macrooptionsty); + constructor create(const aoptions: macrooptionsty; + const apredefined: array of macroinfoty); + function find(const aname: msestring; + out item: pmacroinfoty): boolean; + //true if found; + function itembyname(const aname: msestring): pmacroinfoty; + function itempo(const index: integer): pmacroinfoty; + procedure add(const avalue: tmacrolist); overload; + procedure add(const avalue: macroinfoty); overload; + procedure add(const avalue: macroinfoarty); overload; + procedure add(const names,values: array of msestring; + const handler: array of macrohandlerty); overload; + + procedure expandmacros1(var avalue: msestring); + function expandmacros(const avalue: msestring): msestring; + procedure expandmacros1(var avalue: msestring; + var refindex: integerarty); + procedure expandmacros1(var avalues: msestringarty); + function asarray: macroinfoarty; + function asarray(const addnames: array of msestring; + const addvalues: array of msestring): macroinfoarty; + procedure asarray(out names,values: msestringarty; + out handler: macrohandlerarty); + procedure setasarray(const avalue: macroinfoarty); + procedure setasarray(const names,values: msestringarty; + const handler: macrohandlerarty); + property options: macrooptionsty read foptions write foptions; + + procedure setpredefined(const avalue: array of macroinfoty); + procedure setpredefined(const avalue: array of macroinfoarty); + property predefined: macroinfoarty read fpredefined write fpredefined; + //appended by setasarray procedures + end; + + tmacroproperty = class; + tmacrostringlist = class(tmsestringdatalist) + private + fmacros: tmacroproperty; + function gettext: msestring; + procedure settext(const avalue: msestring); + procedure readstrings(reader: treader); +// procedure writestrings(writer: twriter); + procedure setmacros(const avalue: tmacroproperty); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create; override; + destructor destroy; override; + procedure assign(source: tpersistent); override; + function expandmacros(atext: msestring): msestring; + property text: msestring read gettext write settext; + published + property macros: tmacroproperty read fmacros write setmacros; + end; + + tstringlistmacroitem = class; + + tstringlistmacro = class(tmacrostringlist) + private + fowner: tmacrostringlist; + protected + procedure dochange; override; + public + constructor create(const aowner: tmacrostringlist); reintroduce; + end; + + tstringlistmacroitem = class(townedpersistent) + private + fname: msestring; + fvalue: tstringlistmacro; + factive: boolean; + procedure setvalue(const avalue: tstringlistmacro); + procedure setactive(const avalue: boolean); + protected + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure assign(source: tpersistent); override; + published + property name: msestring read fname write fname; + property value: tstringlistmacro read fvalue write setvalue; + property active: boolean read factive write setactive default true; + end; + + tmacroproperty = class(townedpersistentarrayprop) + private + foptions: macrooptionsty; + function getitems(const aindex: integer): tstringlistmacroitem; + procedure setitems(const aindex: integer; + const avalue: tstringlistmacroitem); + protected + procedure dochange(const aindex: integer); override; + public + constructor create(const aowner: tmacrostringlist); reintroduce; + property items[const aindex: integer]: tstringlistmacroitem read getitems + write setitems; default; + function itembyname(const aname: msestring): tstringlistmacroitem; + function itembynames(const anames: array of msestring): tstringlistmacroitem; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + published + property options: macrooptionsty read foptions write foptions + default [mao_caseinsensitive]; + end; + +//function expandmacros(const value: msestring; const macros:macroinfoarty; +// const caseinsensitive: boolean = true): msestring; overload; +function initmacros(const amacros: array of macroinfoty): macroinfoarty; +function initmacros(const anames,avalues: array of msestring; + const ahandler: array of macrohandlerty): macroinfoarty; +function initmacros(const anames,avalues: array of msestringarty; + const ahandler: array of macrohandlerarty): macroinfoarty; +function initmacros(const amacros: array of macroinfoarty): macroinfoarty; + +function expandmacros(const value: msestring; const macros: macroinfoarty; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +function expandmacros(const value: msestring; + const anames,avalues: array of msestring; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +function expandmacros1(const value: msestring; + const anames,avalues: array of msestring; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; + +function expandmacros2(const value: msestring; + const anames,avalues: array of msestring; + const ahandler: array of macrohandlerty; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; + +implementation +uses + msestream,sysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function initmacros(const amacros: array of macroinfoty): macroinfoarty; +var + int1: integer; +begin + setlength(result,length(amacros)); + for int1:= 0 to high(amacros) do begin + result[int1]:= amacros[int1]; + end; +end; + +function initmacros(const anames,avalues: array of msestring; + const ahandler: array of macrohandlerty): macroinfoarty; +var + int1: integer; +begin + setlength(result,length(anames)); + for int1:= 0 to high(result) do begin + with result[int1] do begin + name:= anames[int1]; + if int1 <= high(avalues) then begin + value:= avalues[int1]; + end; + if int1 <= high(ahandler) then begin + handler:= ahandler[int1]; + end; + end; + end; +end; + +function initmacros(const anames,avalues: array of msestringarty; + const ahandler: array of macrohandlerarty): macroinfoarty; +var + int1,int2,int3: integer; +begin + int3:= 0; + for int1:= 0 to high(anames) do begin + int3:= int3 + length(anames[int1]); + end; + setlength(result,int3); + int3:= 0; + for int1:= 0 to high(anames) do begin + for int2:= 0 to high(anames[int1]) do begin + with result[int3] do begin + name:= anames[int1,int2]; + if int2 <= high(avalues[int1]) then begin + value:= avalues[int1,int2]; + end; + if int2 <= high(ahandler[int1]) then begin + handler:= ahandler[int1,int2]; + end; + end; + inc(int3); + end; + end; +end; + +function initmacros(const amacros: array of macroinfoarty): macroinfoarty; +var + int1,int2,int3: integer; +begin + int2:= 0; + for int1:= 0 to high(amacros) do begin + int2:= int2 + length(amacros[int1]); + end; + setlength(result,int2); + for int1:= high(amacros) downto 0 do begin + for int3:= high(amacros[int1]) downto 0 do begin + dec(int2); + result[int2]:= amacros[int1][int3]; + end; + end; +end; + +function expandmacros(const value: msestring; const macros:macroinfoarty; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +var + list: tmacrolist; +begin + list:= tmacrolist.create(options); + try + list.add(macros); + result:= value; + list.expandmacros1(result); + finally + list.free; + end; +end; + +function expandmacros(const value: msestring; + const anames,avalues: array of msestring; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +begin + result:= expandmacros(value,initmacros(anames,avalues,[]),options); +end; + +function expandmacros1(const value: msestring; + const anames,avalues: array of msestring; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +begin + result:= expandmacros(value,initmacros(anames,avalues,[]),options); +end; + +function expandmacros2(const value: msestring; + const anames,avalues: array of msestring; + const ahandler: array of macrohandlerty; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +begin + result:= expandmacros(value,initmacros(anames,avalues,ahandler),options); +end; + +{ +function expandmacrosstr(const value: msestring; + const anames,avalues: array of msestring; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +begin + result:= expandmacros(value,initmacros(anames,avalues,[]),options); +end; +} +{ +function expandmacros(const value: msestring; const macros:macroinfoarty; + const caseinsensitive: boolean = true): msestring; +var + list: tmacrolist; +begin + list:= tmacrolist.create([mao_caseinsensitive]); + try + list.add(macros); + result:= value; + list.expandmacros(result); + finally + list.free; + end; +end; +} +{ tmacrolist } + +constructor tmacrolist.create(const aoptions: macrooptionsty); +begin + foptions:= aoptions; + inherited create(sizeof(macroinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +constructor tmacrolist.create(const aoptions: macrooptionsty; + const apredefined: array of macroinfoty); +begin + create(aoptions); + predefined:= initmacros(apredefined); + add(fpredefined); +end; + +function tmacrolist.itempo(const index: integer): pmacroinfoty; +begin + result:= pmacroinfoty(getitempo(index)); +end; + +procedure tmacrolist.add(const avalue: macroinfoty); +var + info: macroinfoty; +begin + if mao_caseinsensitive in foptions then begin + info.name:= struppercase(avalue.name); + info.value:= avalue.value; + info.handler:= avalue.handler; + inherited add(info); + end + else begin + inherited add(avalue); + end; +end; + +procedure tmacrolist.add(const avalue: macroinfoarty); +var + int1: integer; +begin + sorted:= false; + for int1:= 0 to high(avalue) do begin + add(avalue[int1]); + end; +end; + +procedure tmacrolist.add(const avalue: tmacrolist); +begin + add(avalue.asarray); +end; + +procedure tmacrolist.add(const names,values: array of msestring; + const handler: array of macrohandlerty); +var + int1: integer; + ar1: macroinfoarty; +begin + setlength(ar1,length(names)); + for int1:= 0 to high(names) do begin + ar1[int1].name:= names[int1]; + if int1 <= high(values) then begin + ar1[int1].value:= values[int1]; + end; + if int1 <= high(handler) then begin + ar1[int1].handler:= handler[int1]; + end; + end; + add(ar1); +end; + +procedure tmacrolist.resetexpandlevel; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + pmacroinfoaty(fdata)^[int1].expandlevel:= bigint; + end; +end; + +function tmacrolist.getvalue(const aname: msestring; + var aexpandlevel: integer; + out found: pmacroinfoty): msestring; +var + info: macroinfoty; + int1: integer; +begin + if mao_caseinsensitive in foptions then begin + info.name:= struppercase(aname); + end + else begin + info.name:= aname; + end; + if internalfind(info,int1) then begin + found:= @pmacroinfoaty(fdata)^[int1]; + with found^ do begin + result:= value; + int1:= expandlevel; + expandlevel:= aexpandlevel; + aexpandlevel:= int1; + end; + end + else begin + result:= ''; + aexpandlevel:= bigint+1; + end; +end; + +function tmacrolist.find(const aname: msestring; + out item: pmacroinfoty): boolean; + //true if found; +var + info: macroinfoty; + int1: integer; +begin + if mao_caseinsensitive in foptions then begin + info.name:= struppercase(aname); + end + else begin + info.name:= aname; + end; + result:= internalfind(info,int1); + if result then begin + item:= @pmacroinfoaty(fdata)^[int1]; + end + else begin + item:= nil; + end; +end; + +function tmacrolist.itembyname(const aname: msestring): pmacroinfoty; +begin + if not find(aname,result) then begin + raise exception.create(ansistring('Macroitem "'+aname+'" not found')); + end; +end; + +function tmacrolist.callhandler(const aname: msestring; + const aparams: msestringarty; var aexpandlevel: integer; + out found: pmacroinfoty): msestring; + +var +// info: macroinfoty; + int1: integer; + +begin +{ + if mao_caseinsensitive in foptions then begin + info.name:= struppercase(aname); + end + else begin + info.name:= aname; + end; + if internalfind(info,int1) then begin +} + if find(aname,found) then begin +// found:= @pmacroinfoaty(fdata)^[int1]; + with found^ do begin + if handler <> nil then begin + result:= handler(self,aparams); + end + else begin + result:= value; + end; + int1:= expandlevel; + expandlevel:= aexpandlevel; + aexpandlevel:= int1; + end; + end + else begin +// found:= nil; + result:= ''; + aexpandlevel:= bigint+1; //not found + end; +end; + +function tmacrolist.compare(const l, r): integer; +begin + result:= msestrcomp(pmsechar(macroinfoty(l).name), + pmsechar(macroinfoty(r).name)); +end; + +function tmacrolist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}compare; +end; + +procedure tmacrolist.copyrecord(var item); +begin + with macroinfoty(item) do begin + stringaddref(name); + stringaddref(value); + end; +end; + +procedure tmacrolist.finalizerecord(var item); +begin + finalize(macroinfoty(item)); +end; + +procedure tmacrolist.internalexpandmacros(var avalue: msestring; + expandlevel: integer; var refindex: integerarty); + +var + start: pmsechar; + + function checkmacrostart(po: pmsechar): pmsechar; + begin + if mao_curlybraceonly in foptions then begin + repeat + result:= msestrscan(po,msechar('{')); + if result <> nil then begin + if (result = start) then begin + result:= nil; + end + else begin + dec(result); + if result^ = '$' then begin + break; + end; + inc(po); //next curlybrace + end; + end; + until result = nil; + end + else begin + result:= msestrscan(po,msechar('$')) + end; + end; //checkmacrostart + +var + int1,int2,int3,int4: integer; + po1,po2,po3,po4,po5: pmsechar; + str1,str2,str3: msestring; + ar1: msestringarty; + found: pmacroinfoty; + +begin + if avalue <> '' then begin + found:= nil; + str1:= avalue; //copy + po2:= pmsechar(str1); + start:= po2; + po1:= checkmacrostart(po2); + if po1 <> nil then begin + avalue:= ''; + while true do begin + if expandlevel = 0 then begin + resetexpandlevel; + end; + addstringsegment(avalue,po2,po1); + po2:= po1+1; + if (po2)^ = '{' then begin + inc(po2); + int1:= 0; + while po2^ <> #0 do begin + if po2^ = '"' then begin //skip quoted + inc(po2); + while po2^ <> #0 do begin + if po2^ = '"' then begin + break; + end; + inc(po2); + end; + end; + if po2^ = '{' then begin + inc(int1); + end; + if po2^ = '}' then begin + dec(int1); + if int1 < 0 then begin + break; + end; + end; + inc(po2); + end; + if po2^ <> #0 then begin + po3:= po1+2; + str2:= stringsegment(po3,po2); + inc(po2) + end + else begin + addstringsegment(avalue,po1,pmsechar(str1)+length(str1)); + //append the rest for missing } + exit; + end; + end + else begin + po2:= po1; + repeat + inc(po2); + until not ((po2^ = '_') or + (po2^ >= 'a') and (po2^ <= 'z') or + (po2^ >= 'A') and (po2^ <= 'Z') or + (po2^ >= '0') and (po2^ <= '9')); + po3:= po1+1; + str2:= stringsegment(po3,po2); + end; + //po1 = macro def start, po2 = macro def end + if str2 <> '' then begin //macro name + int1:= expandlevel+1; + po4:= po2-1; + if po4^ = '}' then begin + dec(po4); + if (po4)^ = ')' then begin + po5:= po3; + while (po5 < po4) and (po5^ <> '(') do begin + inc(po5); + end; + if po5 < po4 then begin + setlength(str2,po5-po3); + str3:= stringsegment(po5+1,po4); + ar1:= splitstringquoted(str3,',','"'); + for int2:= 0 to high(ar1) do begin + internalexpandmacros(ar1[int2],expandlevel+1,integerarty(nil^)); + end; + int1:= expandlevel+1; + str3:= callhandler(str2,ar1,int1,found); + end + else begin + int1:= bigint+1; //not found + end; + end + else begin + str3:= getvalue(str2,int1,found); + end; + end + else begin + str3:= getvalue(str2,int1,found); + end; + if int1 <= expandlevel then begin + str3:= '!!R*'+str2+'*R!!'; + end + else begin + internalexpandmacros(str3,expandlevel+1,integerarty(nil^)); + end; + if found <> nil then begin + found^.expandlevel:= bigint; //can be reused + end; + if @refindex <> nil then begin + int4:= (po2-po1); + int3:= length(str3) - int4; + int4:= length(avalue) + int4; + for int2:= high(refindex) downto 0 do begin + if refindex[int2] >= int4 then begin + refindex[int2]:= refindex[int2] + int3; + end; + end; + end; + avalue:= avalue + str3; + end + else begin + int1:= bigint+1; + end; + if (int1 > bigint) and not (mao_removeunknown in foptions) then begin + avalue:= avalue + stringsegment(po1,po2); + end; + if po2^ = #0 then begin + break; + end; + po1:= checkmacrostart(po2); + if po1 = nil then begin + addstringsegment(avalue,po2,pmsechar(str1)+length(str1)); + //locks str1 + break; + end; + end; + end; + end; +end; + +procedure tmacrolist.expandmacros1(var avalue: msestring; + var refindex: integerarty); +begin + internalexpandmacros(avalue,0,refindex); +end; + +procedure tmacrolist.expandmacros1(var avalue: msestring); +var + ar1: integerarty; +begin + ar1:= nil; + expandmacros1(avalue,ar1); +end; + +function tmacrolist.expandmacros(const avalue: msestring): msestring; +begin + result:= avalue; + expandmacros1(result); +end; + +procedure tmacrolist.expandmacros1(var avalues: msestringarty); +var + int1: integer; +begin + setlength(avalues,length(avalues)); + for int1:= 0 to high(avalues) do begin + expandmacros1(avalues[int1]); + end; +end; + +procedure tmacrolist.statreadvalue(const aname: msestring; + const reader: tstatreader); +begin + clear; + reader.readrecordarray(aname,@setcount,@setrec); +end; + +procedure tmacrolist.statwritevalue(const aname: msestring; + const writer: tstatwriter); +begin + writer.writerecordarray(aname,count,@getrec); +end; + +function tmacrolist.getrec(const index: integer): msestring; +begin + with itempo(index)^ do begin + result:= encoderecord([name,value]); + end; +end; + +procedure tmacrolist.setrec(const index: integer; const avalue: msestring); +begin + with itempo(index)^ do begin + handler:= nil; + decoderecord(avalue,[@name,@value],'SS'); + end; +end; + +function tmacrolist.asarray: macroinfoarty; +var + po1: pmacroinfoaty; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to count - 1 do begin + result[int1]:= po1^[int1]; + end; +end; + +function tmacrolist.asarray(const addnames: array of msestring; + const addvalues: array of msestring): macroinfoarty; +var + int1,int2,int3: integer; +begin + result:= asarray(); + int1:= length(addnames); + if int1 > length(addvalues) then begin + int1:= length(addvalues); + end; + int2:= length(result); + setlength(result,int2+int1); + int3:= 0; + for int1:= int2 to high(result) do begin + result[int1].name:= addnames[int3]; + result[int1].value:= addvalues[int3]; + inc(int3); + end; +end; + +procedure tmacrolist.asarray(out names, values: msestringarty; + out handler: macrohandlerarty); +var + po1: pmacroinfoaty; + int1: integer; +begin + setlength(names,count); + setlength(values,count); + setlength(handler,count); + po1:= datapo; + for int1:= 0 to count - 1 do begin + names[int1]:= po1^[int1].name; + values[int1]:= po1^[int1].value; + handler[int1]:= po1^[int1].handler; + end; +end; + +procedure tmacrolist.setasarray(const avalue: macroinfoarty); +begin + clear(); + add(fpredefined); + add(avalue); +end; + +procedure tmacrolist.setasarray(const names: msestringarty; + const values: msestringarty; const handler: macrohandlerarty); +begin + clear(); + add(fpredefined); + add(names,values,handler); +end; + +procedure tmacrolist.setpredefined(const avalue: array of macroinfoty); +begin + fpredefined:= initmacros(avalue); +end; + +procedure tmacrolist.setpredefined(const avalue: array of macroinfoarty); +begin + fpredefined:= initmacros(avalue); +end; + +{ tmacrostringlist } + +constructor tmacrostringlist.create; +begin + fmacros:= tmacroproperty.create(self); + inherited; +end; + +destructor tmacrostringlist.destroy; +begin + inherited; + fmacros.free; +end; + +function tmacrostringlist.expandmacros(atext: msestring): msestring; +var + ar1: macroinfoarty; + int1: int32; +begin + result:= atext; + if fmacros.count <> 0 then begin + setlength(ar1,fmacros.count); +// po3:= fmacros.datapo; + for int1:= 0 to high(ar1) do begin + with fmacros[int1] do begin + ar1[int1].name:= name; + if active then begin + ar1[int1].value:= value.text; + end + else begin + ar1[int1].value:= ''; + end; +// value:= po3^.b; +// name:= po3^.a; +// value:= po3^.b; + end; +// inc(po3); + end; + result:= msemacros.expandmacros(result,ar1,fmacros.foptions); + end; +end; + +function tmacrostringlist.gettext: msestring; +var + int1,int2: integer; + po1: pmsestring; + po2: pmsechar; + mstr1: msestring; +// po3: pdoublemsestringty; +begin + result:= ''; + if count > 0 then begin + normalizering; + int2:= 0; + po1:= pointer(fdatapo); + for int1:= 0 to count - 1 do begin + inc(int2,length(pmsestringaty(po1)^[int1])); + end; + mstr1:= lineend; + setlength(result,int2+(count-1)*length(mstr1)); + if result <> '' then begin + int2:= 0; + po2:= pmsechar(result); + for int1:= 0 to count - 2 do begin + move(po1^[1],po2^,length(po1^)*sizeof(msechar)); + inc(po2,length(po1^)); + move(mstr1[1],po2^,length(mstr1)*sizeof(msechar)); + inc(po2,length(mstr1)); + inc(po1); + end; + move(po1^[1],po2^,length(po1^)*sizeof(msechar)); //last line + end; + result:= expandmacros(result); + end; +end; + +procedure tmacrostringlist.settext(const avalue: msestring); +begin + asarray:= breaklines(avalue); +end; + +procedure tmacrostringlist.readstrings(reader: treader); +var + ar1: stringarty; + int1: integer; + bo1: boolean; +begin + reader.readlistbegin; + while not reader.endoflist do begin + additem(ar1,reader.readstring); + end; + reader.readlistend; + bo1:= true; + for int1:= 0 to high(ar1) do begin + if not checkutf8(ar1[int1]) then begin + bo1:= false; + break; + end; + end; + clear; + if bo1 then begin + for int1:= 0 to high(ar1) do begin + add(utf8tostringansi(ar1[int1])); + end; + end + else begin + for int1:= 0 to high(ar1) do begin + add(msestring(ar1[int1])); + end; + end; +end; + +procedure tmacrostringlist.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Strings',{$ifdef FPC}@{$endif}readstrings, + nil{@writestrings},false); +end; + +procedure tmacrostringlist.setmacros(const avalue: tmacroproperty); +begin + fmacros.assign(avalue); +end; + +procedure tmacrostringlist.assign(source: tpersistent); +begin + beginupdate; + try + inherited; + if source is tmacrostringlist then begin + fmacros.assign(tmacrostringlist(source).macros); + end; + finally + endupdate; + end; +end; + +{ tmacroproperty } + +constructor tmacroproperty.create(const aowner: tmacrostringlist); +begin + fowner:= aowner; + foptions:= [mao_caseinsensitive]; + inherited create(aowner,tstringlistmacroitem); +end; + +procedure tmacroproperty.dochange(const aindex: integer); +begin + inherited; + tmacrostringlist(fowner).dochange; +end; + +function tmacroproperty.getitems(const aindex: integer): tstringlistmacroitem; +begin + result:= tstringlistmacroitem(inherited getitems(aindex)); +end; + +procedure tmacroproperty.setitems(const aindex: integer; + const avalue: tstringlistmacroitem); +begin + inherited; +end; + +class function tmacroproperty.getitemclasstype: persistentclassty; +begin + result:= tstringlistmacroitem; +end; + +function tmacroproperty.itembyname( + const aname: msestring): tstringlistmacroitem; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fitems) do begin + if tstringlistmacroitem(fitems[int1]).name = aname then begin + result:= tstringlistmacroitem(fitems[int1]); + break; + end; + end; + if result = nil then begin + raise exception.create('Macro "'+ansistring(aname)+'" not found.'); + end; +end; + +function tmacroproperty.itembynames( + const anames: array of msestring): tstringlistmacroitem; +var + int1: integer; +begin + result:= nil; + if length(anames) > 0 then begin + result:= itembyname(anames[0]); + for int1:= 1 to high(anames) do begin + result:= result.value.macros.itembyname(anames[int1]); + end; + end; +end; + +{ tstringlistmacro } + +constructor tstringlistmacro.create(const aowner: tmacrostringlist); +begin + fowner:= aowner; + inherited create; +end; + +procedure tstringlistmacro.dochange; +begin + inherited; + fowner.dochange; +end; + +{ tstringlistmacroitem } + +constructor tstringlistmacroitem.create(aowner: tobject); +begin + factive:= true; + fvalue:= tstringlistmacro.create(tmacrostringlist(aowner)); + inherited; +end; + +destructor tstringlistmacroitem.destroy; +begin + fvalue.free; + inherited; +end; + +procedure tstringlistmacroitem.setvalue(const avalue: tstringlistmacro); +begin + fvalue.assign(avalue); +end; + +procedure tstringlistmacroitem.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + factive:= avalue; + tmacrostringlist(fowner).dochange; + end; +end; + +procedure tstringlistmacroitem.assign(source: tpersistent); +begin + if source is tstringlistmacroitem then begin + with tstringlistmacroitem(source) do begin + self.name:= name; + self.value:= value; + self.active:= active; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msemenus.pas b/mseide-msegui/lib/common/kernel/msemenus.pas new file mode 100644 index 0000000..a65a9ef --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msemenus.pas @@ -0,0 +1,2436 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msemenus; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +uses + mseact,msegui,msearrayprops,mseclasses,msegraphutils, + msedrawtext,msegraphics,mseevent,mseglob,mseguiglob,mseshapes,mserichstring, + msetypes,msestrings,classes,mclasses,msekeyboard,msebitmap, + mseassistiveclient{$ifdef mse_with_ifi},mseificompglob{$endif}; + +type + menuoptionty = (mo_noinsert,mo_stopinsert,mo_insertfirst, + mo_noseparator, + mo_forceseparator, //do not set mao_optional + mo_singleregion,mo_shortcutright,mo_commonwidth, + mo_activate,{mo_noanim,}mo_mainarrow,mo_updateonidle); + menuoptionsty = set of menuoptionty; +const + defaultmenuoptions = [mo_shortcutright]; + defaultmainmenuoptions = defaultmenuoptions + [mo_updateonidle]; + defaultmenuactoptions = [mao_shortcutcaption]; + +type + menuinfoarty = array of actioninfoty; + tmenuitem = class; + + menuitemeventty = procedure(const sender: tmenuitem) of object; + menuitemprocty = procedure(const sender: tmenuitem); + + tmenuitems = class(tpersistentarrayprop,ievent) + private + fowner: tmenuitem; + function getmenuitems(index: integer): tmenuitem; + procedure setmenuitems(index: integer; const Value: tmenuitem); + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure dosizechanged; override; + procedure dochange(const aindex: integer); override; + procedure receiveevent(const event: tobjectevent); + public + constructor create(const aowner: tmenuitem); + class function getitemclasstype: persistentclassty; override; + function hasvisibleitem: boolean; + procedure sort; + procedure assign(source: tpersistent); override; + function insert(const index: integer; + const aitem: tmenuitem): integer overload; + //aitem is owned, returns index of new item + //if index > count -> index:= count + function insert(const index: integer; + const aitems: tmenuitems): integer overload; + //items are copied, returns index of first new item + //if index > count -> index:= count + function insert(const index: integer; const captions: array of msestring; + //if index > count -> index:= count + const options: array of menuactionoptionsty; + const states: array of actionstatesty; + const onexecutes: array of notifyeventty): integer overload; + //returns index of first new item + procedure insertseparator(const index: integer; + const aoptional: boolean = false); + //if index > count -> index:= count + property items[index: integer]: tmenuitem read getmenuitems + write setmenuitems; default; + function itembyname(const name: ansistring): tmenuitem; + function itemindexbyname(const name: ansistring): integer; + end; + + tmenufont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tmenufontactive = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tcustommenu = class; + + imenuitem = interface(ievent) + procedure setstate(const avalue: actionstatesty); + function getstate: actionstatesty; + end; + + tmenuitem = class(teventpersistent,iactionlink,imenuitem,iimagelistinfo, + iassistiveclientmenu) + private + fparentmenu: tmenuitem; + fonchange: menuitemeventty; + fname: string; +// fgroup: integer; + fsource: imenuitem; + fcoloractive: colorty; + fcolorglyphactive: colorty; + function getsubmenu: tmenuitems; + procedure setsubmenu(const Value: tmenuitems); + procedure setcaption(const avalue: captionty); + function iscaptionstored: Boolean; + procedure setstate(const avalue: actionstatesty); + function getstate: actionstatesty; + function isstatestored: Boolean; + + procedure resetradiobuttons(); + procedure actionchanged; + procedure checksubmenu; + function getitems(const index: integer): tmenuitem; + procedure setitems(const index: integer; const Value: tmenuitem); + procedure setaction(const avalue: tcustomaction); + function isonexecutestored: Boolean; + function isonbeforeexecutestored: Boolean; + function isonafterexecutestored: Boolean; + function isshortcutstored: Boolean; + procedure setshortcut(const avalue: shortcutty); + function isshortcut1stored: Boolean; + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + function getshortcut: shortcutty; + function getshortcut1: shortcutty; + procedure setshortcut1(const avalue: shortcutty); + procedure setonexecute(const avalue: notifyeventty); + procedure setonbeforeexecute(const avalue: accepteventty); + procedure setonafterexecute(const avalue: notifyeventty); + procedure setoptions(const avalue: menuactionoptionsty); + function istagstored: Boolean; + procedure settag(const avalue: integer); + function isgroupstored: Boolean; + procedure setgroup(const avalue: integer); + function getchecked: boolean; + procedure setchecked(const avalue: boolean); + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getimagelist: timagelist; + procedure setimagelist(const avalue: timagelist); + function isimageliststored: boolean; + procedure setimagenr(const avalue: imagenrty); + function isimagenrstored: boolean; + procedure setimagenrdisabled(const avalue: imagenrty); + function isimagenrdisabledstored: boolean; + procedure setcolor(const avalue: colorty); + function iscolorstored: boolean; + procedure setcolorglyph(const avalue: colorty); + function iscolorglyphstored: boolean; + + function getfont: tmenufont; + function getfontactive: tmenufontactive; + procedure setfont(const avalue: tmenufont); + procedure setfontactive(const avalue: tmenufontactive); + function isfontstored: boolean; + function isfontactivestored: boolean; + procedure dofontchanged(const sender: tobject); + procedure sethint(const avalue: msestring); + function ishintstored: boolean; + procedure setcoloractive(const avalue: colorty); + function getcheckedtag: integer; + procedure setcheckedtag(const avalue: integer); + procedure readshortcut(reader: treader); + procedure readshortcut1(reader: treader); + procedure readsc(reader: treader); + procedure writesc(writer: twriter); + procedure readsc1(reader: treader); + procedure writesc1(writer: twriter); + procedure setcolorglyphactive(const avalue: colorty); + protected + finfo: actioninfoty; + fowner: tcustommenu; + fsubmenu: tmenuitems; + ffont: tmenufont; + ffontactive: tmenufontactive; + factiveitem: int32; //for iassistiveclient + function getactiveitem(out aitem: tmenuitem): boolean; + procedure updatecaption; + procedure defineproperties(filer: tfiler); override; + procedure befexec; + function doexec: boolean; + + function getiassistiveclient(): iassistiveclientmenu virtual; + //iassistiveclient + function getassistiveparent(): iassistiveclient; + function getassistivewidget(): tobject; + function getassistivename(): msestring; virtual; + function getassistivecaption(): msestring; virtual; + function getassistivetext(): msestring; virtual; + function getassistivecaretindex(): int32; virtual; + function getassistivehint(): msestring; virtual; + function getassistiveflags(): assistiveflagsty; virtual; + {$ifdef mse_with_ifi} + function getifidatalinkintf(): iifidatalink; virtual; + {$endif} + function getassistiveselfcaption(): msestring; + function getassistiveselfname(): msestring; + function getassistiveselfhint(): msestring; + + //iactionlink + function getactioninfopo: pactioninfoty; + function loading: boolean; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure receiveevent(const event: tobjectevent); override; + function internalexecute(async: boolean): boolean; + function canshowhint: boolean; + public + constructor create(const parentmenu: tmenuitem = nil; + const aowner: tcustommenu = nil); reintroduce; + destructor destroy; override; + procedure assign(source: tpersistent); override; + procedure beginload; + procedure endload; + procedure doupdate; + procedure updatehotkeys(); + procedure doshortcut(var info: keyeventinfoty); + function count: integer; + function hasvisibleitem: boolean; + function parentmenu: tmenuitem; + function actualcolor: colorty; + function actualcoloractive: colorty; + function actualcolorglyph: colorty; + function actualcolorglyphactive: colorty; + property owner: tcustommenu read fowner; //can be nil + function execute: boolean; //true if onexecute fired + function asyncexecute: boolean; + function canactivate: boolean; + function canshow: boolean; + procedure createfont; + procedure createfontactive; + property onchange: menuitemeventty read fonchange write fonchange; + property items[const index: integer]: tmenuitem read getitems + write setitems; default; + function itembyname(const name: string): tmenuitem; + function itembynames(const names: array of string): tmenuitem; + procedure deleteitembynames(const names: array of string); + function index: integer; //-1 if no parent menu + property checkedtag: integer read getcheckedtag write setcheckedtag; + //-1 if none checked + property checked: boolean read getchecked write setchecked; + property enabled: boolean read getenabled write setenabled; + property visible: boolean read getvisible write setvisible; + property tagpo: pointer read finfo.tagpo write finfo.tagpo; + property tagpointer: pointer read finfo.tagpo write finfo.tagpo; + deprecated 'Use tagpo instead'; + property shortcuts: shortcutarty read finfo.shortcut write setshortcuts; + property shortcuts1: shortcutarty read finfo.shortcut1 write setshortcuts1; + published + property action: tcustomaction read finfo.action write setaction; + property submenu: tmenuitems read getsubmenu write setsubmenu; + property caption: captionty read finfo.captiontext write setcaption + stored iscaptionstored; + property hint: msestring read finfo.hint write sethint stored ishintstored; + property name: string read fname write fname; + property state: actionstatesty read finfo.state write setstate + stored isstatestored default []; + property options: menuactionoptionsty read finfo.options + write setoptions default defaultmenuactoptions; + property shortcut: shortcutty read getshortcut write setshortcut + stored false default 0; + property shortcut1: shortcutty read getshortcut1 write setshortcut1 + stored false default 0; + property tag: integer read finfo.tag write settag stored istagstored default 0; + property group: integer read finfo.group write setgroup + stored isgroupstored default 0; + property imagelist: timagelist read getimagelist write setimagelist + stored isimageliststored; + property imagenr: imagenrty read finfo.imagenr write setimagenr + stored isimagenrstored default -1; + property imagenrdisabled: imagenrty read finfo.imagenrdisabled + write setimagenrdisabled + stored isimagenrdisabledstored default -2; + property color: colorty read finfo.color write setcolor + stored iscolorstored default cl_default; + property coloractive: colorty read fcoloractive write setcoloractive + default cl_default; + //cl_default maps to cl_parent, cl_normal maps to color property + property colorglyph: colorty read finfo.colorglyph write setcolorglyph + stored iscolorglyphstored default cl_default; + //cl_default maps to cl_glyph + property colorglyphactive: colorty read fcolorglyphactive + write setcolorglyphactive default cl_default; + //cl_default maps to cl_glyph + property font: tmenufont read getfont write setfont stored isfontstored; + property fontactive: tmenufontactive read getfontactive write setfontactive + stored isfontactivestored; + property onexecute: notifyeventty read finfo.onexecute + write setonexecute stored isonexecutestored; + property onbeforeexecute: accepteventty read finfo.onbeforeexecute + write setonbeforeexecute stored isonbeforeexecutestored; + property onafterexecute: notifyeventty read finfo.onafterexecute + write setonafterexecute stored isonafterexecutestored; + end; + + pmenuitem = ^tmenuitem; + + menueventty = procedure(const sender: tcustommenu) of object; + + tmenuframetemplate = class(tframetemplate) + public + constructor create(const owner: tmsecomponent; const onchange: notifyeventty); + override; + published + property levelo default 1; + end; + + menutemplatety = record + frame: tframecomp; + face: tfacecomp; + itemframe: tframecomp; + itemface: tfacecomp; + itemframeactive: tframecomp; + itemfaceactive: tfacecomp; + separatorframe: tframecomp; + checkboxframe: tframecomp; + end; + + tcustommenu = class(tmsecomponent) + private + fmenu: tmenuitem; + fonupdate: menueventty; + ftransient: boolean; + fexecitem: tmenuitem; + foptions: menuoptionsty; + ftemplate: menutemplatety; + procedure setmenu(const Value: tmenuitem); + procedure setframetemplate(const avalue: tframecomp); + procedure setfacetemplate(const avalue: tfacecomp); + procedure setitemframetemplate(const avalue: tframecomp); + procedure setitemfacetemplate(const avalue: tfacecomp); + procedure setitemframetemplateactive(const avalue: tframecomp); + procedure setitemfacetemplateactive(const avalue: tfacecomp); + procedure setoptions(const avalue: menuoptionsty); + procedure setseparatorframetemplate(const avalue: tframecomp); + procedure setcheckboxframetemplate(const avalue: tframecomp); + protected + ftransientfor: twidget; + fmouseinfopo: pmouseeventinfoty; + procedure settransientfor(const awidget: twidget); + procedure doidle(var again: boolean); + procedure readstate(reader: treader); override; + procedure loaded; override; + procedure setexecitem(const avalue: tmenuitem); + property execitem: tmenuitem write setexecitem; + procedure assigntemplate(const source: tcustommenu); + procedure templateevent(const sender: tobject; + const event: objecteventty; var template: menutemplatety); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function gettemplatefont(const sender: tmenuitem): tmenufont; virtual; + function gettemplatefontactive( + const sender: tmenuitem): tmenufontactive; virtual; + public + constructor create(aowner: tcomponent); overload; override; + constructor createtransient(const atransientfor: twidget; + const amouseinfopo: pmouseeventinfoty); overload; + destructor destroy; override; + function checkexec: boolean; + procedure assign(source: tpersistent); override; + procedure doshortcut(var info: keyeventinfoty); + procedure doupdate; + procedure updatehotkeys(); + function count: integer; + function transientfor: twidget; + function mouseinfopo: pmouseeventinfoty; + function shortcutseparator: msechar; + class function getshortcutseparator(const ainstance: tcustommenu): msechar; + property menu: tmenuitem read fmenu write setmenu; + property frametemplate: tframecomp read ftemplate.frame write setframetemplate; + property facetemplate: tfacecomp read ftemplate.face write setfacetemplate; + property itemframetemplate: tframecomp read ftemplate.itemframe + write setitemframetemplate; + property itemfacetemplate: tfacecomp read ftemplate.itemface + write setitemfacetemplate; + property itemframetemplateactive: tframecomp read ftemplate.itemframeactive + write setitemframetemplateactive; + property itemfacetemplateactive: tfacecomp read ftemplate.itemfaceactive + write setitemfacetemplateactive; + property separatorframetemplate: tframecomp + read ftemplate.separatorframe + write setseparatorframetemplate; + property checkboxframetemplate: tframecomp read ftemplate.checkboxframe + write setcheckboxframetemplate; + property template: menutemplatety read ftemplate; + property options: menuoptionsty read foptions write setoptions + default defaultmenuoptions; + property onupdate: menueventty read fonupdate write fonupdate; + end; + + tmenu = class(tcustommenu) + published + property options; + property onupdate; + property frametemplate; + property facetemplate; + property itemframetemplate; + property itemfacetemplate; + property itemframetemplateactive; + property itemfacetemplateactive; + property separatorframetemplate; + property checkboxframetemplate; + property menu; //last + end; + + tpopupmenu = class(tmenu) + private + protected + class function classskininfo: skininfoty; override; + public + function show(const atransientfor: twidget; + const pos: graphicdirectionty): tmenuitem; overload; + function show(const atransientfor: twidget; + var mouseinfo: mouseeventinfoty): tmenuitem; overload; + function show(const atransientfor: twidget; + const pos: pointty): tmenuitem; overload; + //returns selected item, nil if none + class function additems(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty; + const captions: array of msestring; + //if index > count -> index:= count + const aoptions: array of menuactionoptionsty; + const states: array of actionstatesty; + const onexecutes: array of notifyeventty; + const aseparator: boolean = true; + const optionalseparator: boolean = true): integer; overload; + //returs index of first added item + class function additems(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty; const items: tmenuitems; + const aseparator: boolean = true; const first: boolean = false; + const optionalseparator: boolean = true): integer; overload; + //returs index of first added item + class function additems(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty; const items: tcustommenu{; + const aseparator: boolean = true}): integer; overload; + //returs index of first added item + end; + + tcustommainmenu = class(tcustommenu) + private + fpopuptemplate: menutemplatety; + procedure setpopupframetemplate(const avalue: tframecomp); + procedure setpopupfacetemplate(const avalue: tfacecomp); + procedure setpopupitemframetemplate(const avalue: tframecomp); + procedure setpopupitemfacetemplate(const avalue: tfacecomp); + procedure setpopupitemframetemplateactive(const avalue: tframecomp); + procedure setpopupitemfacetemplateactive(const avalue: tfacecomp); + procedure setpopupseparatorframetemplate(const avalue: tframecomp); + procedure setpopupcheckboxframetemplate(const avalue: tframecomp); + protected + class function classskininfo: skininfoty; override; + procedure menuchanged(const sender: tmenuitem); + function gettemplatefont(const sender: tmenuitem): tmenufont; override; + function gettemplatefontactive( + const sender: tmenuitem): tmenufontactive; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property popuptemplate: menutemplatety read fpopuptemplate; + published + property options default defaultmainmenuoptions; + property popupframetemplate: tframecomp read fpopuptemplate.frame + write setpopupframetemplate; + property popupfacetemplate: tfacecomp read fpopuptemplate.face + write setpopupfacetemplate; + property popupitemframetemplate: tframecomp read fpopuptemplate.itemframe + write setpopupitemframetemplate; + property popupitemfacetemplate: tfacecomp read fpopuptemplate.itemface + write setpopupitemfacetemplate; + property popupitemframetemplateactive: tframecomp read fpopuptemplate.itemframeactive + write setpopupitemframetemplateactive; + property popupitemfacetemplateactive: tfacecomp read fpopuptemplate.itemfaceactive + write setpopupitemfacetemplateactive; + property popupseparatorframetemplate: tframecomp + read fpopuptemplate.separatorframe + write setpopupseparatorframetemplate; + property popupcheckboxframetemplate: tframecomp + read fpopuptemplate.checkboxframe + write setpopupcheckboxframetemplate; + end; + + tmainmenu = class(tcustommainmenu) + published + property options; + property onupdate; + property frametemplate; + property facetemplate; + property itemframetemplate; + property itemfacetemplate; + property itemframetemplateactive; + property itemfacetemplateactive; + property separatorframetemplate; + property checkboxframetemplate; + + property popupframetemplate; + property popupfacetemplate; + property popupitemframetemplate; + property popupitemfacetemplate; + property popupitemframetemplateactive; + property popupitemfacetemplateactive; + property popupseparatorframetemplate; + property popupcheckboxframetemplate; + property menu; //last + end; + + twidgetmainmenu = class(tcustommainmenu) + published + property Name stored true; + property options; + property onupdate; +// property frametemplate; +// property facetemplate; + property itemframetemplate; + property itemfacetemplate; + property itemframetemplateactive; + property itemfacetemplateactive; + property separatorframetemplate; + property checkboxframetemplate; + + property popupframetemplate; + property popupfacetemplate; + property popupitemframetemplate; + property popupitemfacetemplate; + property popupitemframetemplateactive; + property popupitemfacetemplateactive; + property popupseparatorframetemplate; + property popupcheckboxframetemplate; + property menu; //last + end; +procedure freetransientmenu(var amenu: tcustommenu); + +implementation +uses + sysutils,msestockobjects,rtlconsts,msebits,msemenuwidgets,msedatalist, + mseactions,msestreaming,msearrayutils,msesysutils; +type + tapplication1 = class(tguiapplication) + end; + +procedure freetransientmenu(var amenu: tcustommenu); +begin + if (amenu <> nil) and amenu.ftransient then begin + freeandnil(amenu); + end; +end; + +{ tmenuframetemplate } + +constructor tmenuframetemplate.create(const owner: tmsecomponent; + const onchange: notifyeventty); +begin + inherited; + fi.ba.levelo:= 1; +end; + +{ tcustommenu } + +constructor tcustommenu.create(aowner: tcomponent); +begin + foptions:= defaultmenuoptions; + inherited; +// include(fmsecomponentstate,cs_hasskin); + fmenu:= tmenuitem.create(nil,self); +end; + +constructor tcustommenu.createtransient(const atransientfor: twidget; + const amouseinfopo: pmouseeventinfoty); +begin + create(nil); + ftransient:= true; + settransientfor(atransientfor); + fmouseinfopo:= amouseinfopo; + updateskin; +end; + +destructor tcustommenu.destroy; +begin + if mo_updateonidle in foptions then begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + fmenu.Free; + inherited; +end; + +function tcustommenu.count: integer; +begin + result:= fmenu.count; +end; + +procedure tcustommenu.setmenu(const Value: tmenuitem); +begin + fmenu.assign(Value); +end; + +procedure tcustommenu.doidle(var again: boolean); +begin + doupdate; +end; + +procedure tcustommenu.readstate(reader: treader); +begin + fmenu.beginload; + inherited; +end; + +procedure tcustommenu.loaded; +begin + fmenu.endload; + inherited; + updateskin; +end; + +procedure tcustommenu.setexecitem(const avalue: tmenuitem); +begin + fexecitem:= avalue; +end; + +function tcustommenu.checkexec: boolean; +begin + result:= fexecitem <> nil; + if result then begin + result:= fexecitem.doexec; +// result:= doactionexecute(fexecitem,fexecitem.finfo,true, +// mao_nocandefocus in fexecitem.options); + end; + fexecitem:= nil; +end; + +procedure tcustommenu.doupdate; +begin + fexecitem:= nil; + fmenu.doupdate; + if canevent(tmethod(fonupdate)) then begin + fonupdate(self); + end; +end; + +procedure tcustommenu.updatehotkeys(); +begin + if fmenu <> nil then begin + fmenu.updatehotkeys(); + end; +end; + +procedure tcustommenu.doshortcut(var info: keyeventinfoty); +begin + fmenu.doshortcut(info); +end; + +procedure tcustommenu.assign(source: tpersistent); +begin + if source is tcustommenu then begin + with tcustommenu(source) do begin + self.onupdate:= onupdate; + self.foptions:= options; + self.fmenu.Assign(fmenu); + end; + end + else begin + inherited; + end; +end; + +function tcustommenu.transientfor: twidget; +begin + result:= ftransientfor; +end; + +function tcustommenu.mouseinfopo: pmouseeventinfoty; +begin + result:= fmouseinfopo; +end; + +function tcustommenu.shortcutseparator: msechar; +begin + if mo_shortcutright in foptions then begin + result:= c_tab; + end + else begin + result:= ' '; + end; +end; + +class function tcustommenu.getshortcutseparator( + const ainstance: tcustommenu): msechar; +begin + if ainstance = nil then begin + result:= c_tab; + end + else begin + result:= ainstance.shortcutseparator; + end; +end; + +procedure tcustommenu.setframetemplate(const avalue: tframecomp); +begin + if avalue <> ftemplate.frame then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.frame)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setfacetemplate(const avalue: tfacecomp); +begin + if avalue <> ftemplate.face then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.face)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setitemframetemplate(const avalue: tframecomp); +begin + if avalue <> ftemplate.itemframe then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.itemframe)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setitemfacetemplate(const avalue: tfacecomp); +begin + if avalue <> ftemplate.itemface then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.itemface)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setitemframetemplateactive(const avalue: tframecomp); +begin + if avalue <> ftemplate.itemframeactive then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.itemframeactive)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setitemfacetemplateactive(const avalue: tfacecomp); +begin + if avalue <> ftemplate.itemfaceactive then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.itemfaceactive)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setseparatorframetemplate(const avalue: tframecomp); +begin + if avalue <> ftemplate.separatorframe then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.separatorframe)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setcheckboxframetemplate(const avalue: tframecomp); +begin + if avalue <> ftemplate.checkboxframe then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.checkboxframe)); + sendchangeevent; + end; +end; + +procedure tcustommenu.settransientfor(const awidget: twidget); +begin + ftransientfor:= awidget; + tapplication1(application).flastshowmenuwidget:= awidget; +end; + +procedure tcustommenu.templateevent(const sender: tobject; + const event: objecteventty; var template: menutemplatety); +begin + case event of + oe_changed,oe_destroyed: begin + if (sender = template.face) or (sender = ftemplate.frame) or + (sender = template.itemface) or (sender = ftemplate.itemframe) or + (sender = template.itemfaceactive) or + (sender = template.itemframeactive) or + (sender = template.separatorframe) or + (sender = template.checkboxframe) then begin + if event = oe_destroyed then begin + if sender = template.face then begin + template.face:= nil; + end; + if sender = template.frame then begin + template.frame:= nil; + end; + if sender = template.itemface then begin + template.itemface:= nil; + end; + if sender = template.itemframe then begin + template.itemframe:= nil; + end; + if sender = template.itemframeactive then begin + template.itemframeactive:= nil; + end; + if sender = template.separatorframe then begin + template.separatorframe:= nil; + end; + if sender = template.checkboxframe then begin + template.checkboxframe:= nil; + end; + end; + sendchangeevent; + end; + end; + end; +end; + +procedure tcustommenu.objectevent(const sender: tobject; + const event: objecteventty); +begin + templateevent(sender,event,ftemplate); + inherited; +end; + +procedure tcustommenu.assigntemplate(const source: tcustommenu); +begin + ftemplate:= source.ftemplate; +end; + +procedure tcustommenu.setoptions(const avalue: menuoptionsty); +var + optionsbefore,delta: menuoptionsty; +begin + if avalue <> foptions then begin + optionsbefore:= foptions; + foptions:= avalue; + delta:= menuoptionsty( + {$ifdef FPC}longword{$else}byte{$endif}(optionsbefore) xor + {$ifdef FPC}longword{$else}byte{$endif}(foptions)); + if not (csreading in componentstate) and + (mo_shortcutright in delta) then begin + fmenu.updatecaption; + end; + if mo_updateonidle in delta then begin + if (mo_updateonidle in foptions) and + not (csdesigning in componentstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doidle); + end + else begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + end; + sendchangeevent; + end; +end; + +function tcustommenu.gettemplatefont(const sender: tmenuitem): tmenufont; +begin + result:= nil; + if itemframetemplate <> nil then begin +{$warnings off} + result:= tmenufont(itemframetemplate.template.font); +{$warnings on} + end; +{ + if result = nil then begin + result:= tmenufont(pointer(stockobjects.fonts[stf_menu])); + end; +} +end; + +function tcustommenu.gettemplatefontactive( + const sender: tmenuitem): tmenufontactive; +begin + result:= nil; + if itemframetemplateactive <> nil then begin + result:= tmenufontactive(pointer(itemframetemplateactive.template.font)); + end; +end; + +{ tmenufont } + +class function tmenufont.getinstancepo(owner: tobject): pfont; +begin + result:= @(tmenuitem(owner).ffont); +end; + +{ tmenufontactive } + +class function tmenufontactive.getinstancepo(owner: tobject): pfont; +begin + result:= @(tmenuitem(owner).ffontactive); +end; + +{ tmenuitem } + +constructor tmenuitem.create(const parentmenu: tmenuitem = nil; + const aowner: tcustommenu = nil); +begin + fparentmenu:= parentmenu; + if fparentmenu <> nil then begin + fowner:= fparentmenu.fowner; + end + else begin + fowner:= aowner; + end; + initactioninfo(finfo,defaultmenuactoptions); + finfo.color:= cl_default; + finfo.colorglyph:= cl_default; + fcoloractive:= cl_default; + fcolorglyphactive:= cl_default; + inherited create; +end; + +destructor tmenuitem.destroy; +begin +// if fsubmenu <> nil then begin +// fsubmenu.count:= 0; +// end; + if (fparentmenu <> nil) then begin + fparentmenu.fsubmenu.itemdestroyed(self); + end; + fsubmenu.free; + if (fowner = nil) or not fowner.ftransient then begin + ffont.free; + ffontactive.free; + end; + inherited destroy; +end; + +function tmenuitem.count: integer; +begin + if fsubmenu = nil then begin + result:= 0; + end + else begin + result:= fsubmenu.count; + end; +end; + +function tmenuitem.hasvisibleitem: boolean; +begin + result:= (fsubmenu <> nil) and fsubmenu.hasvisibleitem; +end; + +function tmenuitem.getsubmenu: tmenuitems; +begin + if fsubmenu = nil then begin + fsubmenu:= tmenuitems.create(self); + end; + result:= fsubmenu; +end; + +procedure tmenuitem.setsubmenu(const Value: tmenuitems); +begin + if value = nil then begin + freeandnil(fsubmenu); + end + else begin + getsubmenu.Assign(value); + end; +end; + +function tmenuitem.parentmenu: tmenuitem; +begin + result:= fparentmenu; +end; + +procedure tmenuitem.setcaption(const avalue: captionty); +begin + setactioncaption(iactionlink(self),avalue); +end; + +function tmenuitem.iscaptionstored: Boolean; +begin + result:= isactioncaptionstored(finfo); +end; + +procedure tmenuitem.sethint(const avalue: msestring); +begin + setactionhint(iactionlink(self),avalue); +end; + +function tmenuitem.ishintstored: boolean; +begin + result:= isactionhintstored(finfo); +end; + +procedure tmenuitem.setstate(const avalue: actionstatesty); +begin + setactionstate(iactionlink(self),avalue); +end; + +function tmenuitem.isstatestored: Boolean; +begin + result:= isactionstatestored(finfo); +end; + +function tmenuitem.isshortcutstored: Boolean; +begin + result:= isactionshortcutstored(finfo); +end; + +procedure tmenuitem.setshortcut(const avalue: shortcutty); +begin + setactionshortcut(iactionlink(self),avalue); +end; + +function tmenuitem.isshortcut1stored: Boolean; +begin + result:= isactionshortcut1stored(finfo); +end; + +function tmenuitem.getshortcut: shortcutty; +begin + result:= getsimpleshortcut(finfo); +end; + +function tmenuitem.getshortcut1: shortcutty; +begin + result:= getsimpleshortcut1(finfo); +end; + +procedure tmenuitem.setshortcuts(const avalue: shortcutarty); +begin + setactionshortcuts(iactionlink(self),avalue); +end; + +procedure tmenuitem.setshortcuts1(const avalue: shortcutarty); +begin + setactionshortcuts1(iactionlink(self),avalue); +end; + +procedure tmenuitem.setshortcut1(const avalue: shortcutty); +begin + setactionshortcut1(iactionlink(self),avalue); +end; + +function tmenuitem.istagstored: Boolean; +begin + result:= isactiontagstored(finfo); +end; + +procedure tmenuitem.settag(const avalue: integer); +begin + setactiontag(iactionlink(self),avalue); +end; + +function tmenuitem.isgroupstored: Boolean; +begin + result:= isactiongroupstored(finfo); +end; + +procedure tmenuitem.setgroup(const avalue: integer); +begin + setactiongroup(iactionlink(self),avalue); +end; + +procedure tmenuitem.setoptions(const avalue: menuactionoptionsty); +begin + setactionoptions(iactionlink(self),avalue); +end; + +procedure tmenuitem.setonexecute(const avalue: notifyeventty); +begin + setactiononexecute(iactionlink(self),avalue, + (fowner <> nil) and (csloading in fowner.componentstate)); +end; + +procedure tmenuitem.setonbeforeexecute(const avalue: accepteventty); +begin + setactiononbeforeexecute(iactionlink(self),avalue, + (fowner <> nil) and (csloading in fowner.componentstate)); +end; + +procedure tmenuitem.setonafterexecute(const avalue: notifyeventty); +begin + setactiononafterexecute(iactionlink(self),avalue, + (fowner <> nil) and (csloading in fowner.componentstate)); +end; + +function tmenuitem.isonexecutestored: Boolean; +begin + result:= isactiononexecutestored(finfo); +end; + +function tmenuitem.isonbeforeexecutestored: Boolean; +begin + result:= isactiononbeforeexecutestored(finfo); +end; + +function tmenuitem.isonafterexecutestored: Boolean; +begin + result:= isactiononafterexecutestored(finfo); +end; + +procedure tmenuitem.setcoloractive(const avalue: colorty); +begin + if avalue <> fcoloractive then begin + fcoloractive:= avalue; + actionchanged; + end; +end; + +procedure tmenuitem.setcolorglyphactive(const avalue: colorty); +begin + if avalue <> fcolorglyphactive then begin + fcolorglyphactive:= avalue; + actionchanged(); + end; +end; + +function tmenuitem.getitems(const index: integer): tmenuitem; +begin + checksubmenu; + result:= fsubmenu.items[index]; +end; + +procedure tmenuitem.setitems(const index: integer; const Value: tmenuitem); +begin + checksubmenu; + fsubmenu.items[index]:= value; +end; + +function tmenuitem.itembyname(const name: string): tmenuitem; +begin + if fsubmenu = nil then begin + result:= nil; + end + else begin + result:= fsubmenu.itembyname(name); + end; +end; + +function tmenuitem.itembynames(const names: array of string): tmenuitem; +var + int1: integer; + sub1: tmenuitems; +begin + result:= self; + for int1:= 0 to high(names) do begin + sub1:= result.fsubmenu; + if sub1 = nil then begin + break; + end; + result:= sub1.itembyname(names[int1]); + if result = nil then begin + break; + end; + end; +end; + +procedure tmenuitem.deleteitembynames(const names: array of string); +var + item1: tmenuitem; +begin + item1:= itembynames(names); + if item1 <> nil then begin + item1.fparentmenu.submenu.delete(item1.index); + end; +end; + +function tmenuitem.index: integer; //-1 if no parent menu +begin + if fparentmenu = nil then begin + result:= -1; + end + else begin + result:= fparentmenu.fsubmenu.indexof(self); + end; +end; + +procedure tmenuitem.checksubmenu; +begin + if fsubmenu = nil then begin + tlist.Error({$ifndef FPC}@{$endif}SListIndexError, 0); + end; +end; + +procedure tmenuitem.befexec; +begin + if [mao_checkbox,mao_radiobutton] * finfo.options <> [] then begin + if mao_checkbox in finfo.options then begin + checked:= not checked; + end + else begin + checked:= true; + end; + end; +end; + +function tmenuitem.doexec: boolean; +begin + result:= doactionexecute(self,finfo,true, + mao_nocandefocus in finfo.options,@befexec); +end; + +function tmenuitem.getiassistiveclient(): iassistiveclientmenu; +begin + result:= iassistiveclientmenu(self); +end; + +function tmenuitem.getassistiveparent(): iassistiveclient; +begin + result:= nil; + if fparentmenu <> nil then begin + result:= fparentmenu.getiassistiveclient(); + end; +end; + +function tmenuitem.getassistivewidget(): tobject; +begin + result:= nil; +end; + +function tmenuitem.internalexecute(async: boolean): boolean; +begin + result:= canactivate {and assigned(finfo.onexecute)}; + if result then begin + if async then begin + result:= doexec; +// finfo.onexecute(self); + end + else begin + fowner.execitem:= self; + end; + end; +end; + +function tmenuitem.execute: boolean; +begin + result:= internalexecute(false); +end; + +function tmenuitem.asyncexecute: boolean; +begin + result:= canactivate {and assigned(finfo.onexecute)}; + if result then begin + if fsource <> nil then begin + application.postevent(tobjectevent.create(ek_execute,fsource)); + end + else begin + application.postevent(tobjectevent.create(ek_execute,ievent(self))); + end; + end; +end; + +procedure tmenuitem.receiveevent(const event: tobjectevent); +begin + if event.kind = ek_execute then begin + internalexecute(true); + end; +end; + +procedure tmenuitem.setaction(const avalue: tcustomaction); +begin + linktoaction(iactionlink(self),avalue,finfo); +end; + +function tmenuitem.getactioninfopo: pactioninfoty; +begin + result:= @finfo; +end; + +function tmenuitem.loading: boolean; +begin + result:= (fowner <> nil) and (csloading in fowner.componentstate); +end; + +function tmenuitem.shortcutseparator: msechar; +begin + if fowner <> nil then begin + result:= fowner.shortcutseparator; + end + else begin + result:= c_tab; + end; +end; + +procedure tmenuitem.calccaptiontext(var ainfo: actioninfoty); +begin + mseactions.calccaptiontext(ainfo,shortcutseparator); +end; + +procedure tmenuitem.beginload; +var + int1: integer; +begin + actionbeginload(iactionlink(self)); + for int1:= 0 to count - 1 do begin + items[int1].beginload; + end; +end; + +procedure tmenuitem.endload; +var + int1: integer; +begin + actionendload(iactionlink(self)); + for int1:= 0 to count - 1 do begin + items[int1].endload; + end; +end; + +procedure tmenuitem.doupdate; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + items[int1].doupdate; + end; + if finfo.action <> nil then begin + finfo.action.doupdate; + end; +end; + +procedure tmenuitem.updatehotkeys(); +var + i1: int32; +begin + calccaptiontext(finfo); + for i1:= 0 to count - 1 do begin + items[i1].updatehotkeys(); + end; +end; + +function tmenuitem.canactivate: boolean; +begin + result:= (finfo.state * [as_disabled,as_invisible] = []) and + (finfo.options * [mao_separator] = []); +end; + +function tmenuitem.canshow: boolean; +var + int1: integer; +begin + result:= false; + if enabled and (fsubmenu <> nil) then begin + for int1:= 0 to fsubmenu.count - 1 do begin + if not (as_invisible in fsubmenu[int1].finfo.state) then begin + result:= true; + break; + end; + end; + end; +end; + +procedure tmenuitem.doshortcut(var info: keyeventinfoty); +var + int1: integer; +begin + if doactionshortcut(self,finfo,info,@befexec) then begin + actionchanged; + end + else begin + for int1:= 0 to count -1 do begin + if (es_processed in info.eventstate) then begin + break; + end; + fsubmenu[int1].doshortcut(info); + end; + end; +end; + +procedure tmenuitem.assign(source: tpersistent); +var + action1: tcustomaction; +begin + if source is tmenuitem then begin + fsource:= imenuitem(tmenuitem(source)); + action1:= finfo.action; + with tmenuitem(source) do begin + self.finfo:= finfo; + self.finfo.action:= action1; + self.action:= finfo.action; + self.submenu:= fsubmenu; + self.fcoloractive:= fcoloractive; + if self.fowner.ftransient then begin + self.ffont:= font; + self.ffontactive:= fontactive; + end + else begin + self.font:= font; + self.fontactive:= fontactive; + end; + end; + end; +end; + +function tmenuitem.getchecked: boolean; +begin + result:= as_checked in finfo.state; +end; + +procedure tmenuitem.resetradiobuttons(); +var + int1: integer; + item1: tmenuitem; +begin + if (mao_radiobutton in finfo.options) and (fparentmenu <> nil) then begin + for int1:= 0 to fparentmenu.count-1 do begin + item1:= fparentmenu[int1]; + with item1 do begin + if (mao_radiobutton in finfo.options) and (item1 <> self) and + (finfo.group = self.finfo.group) then begin + setactionchecked(iactionlink(item1),false); + end; + end; + end; + end; +end; + +procedure tmenuitem.setchecked(const avalue: boolean); +begin + if (as_checked in finfo.state) <> avalue then begin + if avalue then begin + resetradiobuttons(); + end; +{ + if avalue and (mao_radiobutton in finfo.options) and (fparentmenu <> nil) then begin + for int1:= 0 to fparentmenu.count-1 do begin + item1:= fparentmenu[int1]; + with item1 do begin + if (mao_radiobutton in finfo.options) and (item1 <> self) and + (finfo.group = self.finfo.group) then begin + setactionchecked(iactionlink(item1),false); + end; + end; + end; + end; +} + setactionchecked(iactionlink(self),avalue); + end; +end; + +procedure tmenuitem.actionchanged; +const + mask: actionstatesty = [as_checked]; +var + state1: actionstatesty; +begin + if as_checked in finfo.state then begin + resetradiobuttons(); + end; + if assigned(fonchange) then begin + fonchange(self); + end; + if (fparentmenu <> nil) and assigned(fparentmenu.fonchange) then begin + fparentmenu.fonchange(self); + end; + if ([mao_checkbox,mao_radiobutton] * finfo.options <> []) and + (fsource <> nil) and (fowner <> nil) and (fowner.ftransient) then begin + state1:= fsource.getstate; + state1:= actionstatesty( + replacebits(longword(state),longword(state1),longword(mask))); + fsource.setstate(state1); + end; +end; + +function tmenuitem.getenabled: boolean; +begin + result:= not (as_disabled in finfo.state); +end; + +procedure tmenuitem.setenabled(const avalue: boolean); +begin + if avalue then begin + state:= state - [as_disabled]; + end + else begin + state:= state + [as_disabled]; + end; +end; + +function tmenuitem.getvisible: boolean; +begin + result:= not (as_invisible in finfo.state); +end; + +procedure tmenuitem.setvisible(const avalue: boolean); +begin + if avalue then begin + state:= state - [as_invisible]; + end + else begin + state:= state + [as_invisible]; + end; +end; + +function tmenuitem.getimagelist: timagelist; +begin + result:= timagelist(finfo.imagelist); +end; + +procedure tmenuitem.setimagelist(const avalue: timagelist); +begin + setactionimagelist(iactionlink(self),avalue); +end; + +function tmenuitem.isimageliststored: Boolean; +begin + result:= isactionimageliststored(finfo); +end; + +procedure tmenuitem.setimagenr(const avalue: imagenrty); +begin + setactionimagenr(iactionlink(self),avalue); +end; + +function tmenuitem.isimagenrstored: Boolean; +begin + result:= isactionimagenrstored(finfo); +end; + +procedure tmenuitem.setimagenrdisabled(const avalue: imagenrty); +begin + setactionimagenrdisabled(iactionlink(self),avalue); +end; + +function tmenuitem.isimagenrdisabledstored: Boolean; +begin + result:= isactionimagenrdisabledstored(finfo); +end; + +procedure tmenuitem.setcolor(const avalue: colorty); +begin + setactioncolor(iactionlink(self),avalue); +end; + +function tmenuitem.iscolorstored: Boolean; +begin + result:= isactioncolorstored(finfo); +end; + +procedure tmenuitem.setcolorglyph(const avalue: colorty); +begin + setactioncolorglyph(iactionlink(self),avalue); +end; + +function tmenuitem.iscolorglyphstored: Boolean; +begin + result:= isactioncolorglyphstored(finfo); +end; + +function tmenuitem.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +function tmenuitem.isfontactivestored: boolean; +begin + result:= ffontactive <> nil; +end; + +procedure tmenuitem.dofontchanged(const sender: tobject); +begin + actionchanged; +end; + +procedure tmenuitem.createfont; +begin + if ffont = nil then begin + ffont:= tmenufont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}dofontchanged; + end; +end; + +procedure tmenuitem.createfontactive; +begin + if ffontactive = nil then begin + ffontactive:= tmenufontactive.create; + ffontactive.onchange:= {$ifdef FPC}@{$endif}dofontchanged; + end; +end; + +function tmenuitem.getfont: tmenufont; +begin + getoptionalobject(fowner,ffont,{$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= nil; + if (fowner <> nil) then begin + result:= fowner.gettemplatefont(self); + end; + if (result = nil) then begin + if fparentmenu <> nil then begin + result:= fparentmenu.getfont; + end + else begin + result:= tmenufont(pointer(stockobjects.fonts[stf_menu])); + end; + end; + end; +end; + +function tmenuitem.getfontactive: tmenufontactive; +begin + getoptionalobject(fowner,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + if ffontactive <> nil then begin + result:= ffontactive; + end + else begin + result:= nil; + if (fowner <> nil) then begin + result:= fowner.gettemplatefontactive(self); + end; + if result = nil then begin + result:= tmenufontactive(pointer(ffont)); + if result = nil then begin + if fparentmenu <> nil then begin + result:= fparentmenu.getfontactive; + end + else begin + result:= tmenufontactive(pointer(stockobjects.fonts[stf_menu])); + end; + end; + end; + end; +end; + +procedure tmenuitem.setfont(const avalue: tmenufont); +begin + if avalue <> ffont then begin + setoptionalobject(fowner,avalue,ffont, + {$ifdef FPC}@{$endif}createfont); + actionchanged; + end; +end; + +procedure tmenuitem.setfontactive(const avalue: tmenufontactive); +begin + if avalue <> ffontactive then begin + setoptionalobject(fowner,avalue,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + actionchanged; + end; +end; + +procedure tmenuitem.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_changed) and (sender = finfo.imagelist) then begin + actionchanged; + end; +end; + +function tmenuitem.canshowhint: boolean; +var + item1: tmenuitem; +begin + result:= false; + if finfo.hint <> '' then begin + result:= true; + item1:= self; + while item1 <> nil do begin + if item1.options * [mao_showhint,mao_noshowhint] <> []then begin + if mao_noshowhint in item1.options then begin + result:= false; + end; + break; + end; + item1:= item1.fparentmenu; + end; + end; +end; + +procedure tmenuitem.readshortcut(reader: treader); +begin + shortcut:= translateshortcut(reader.readinteger); +end; + +procedure tmenuitem.readshortcut1(reader: treader); +begin + shortcut1:= translateshortcut(reader.readinteger); +end; + +procedure tmenuitem.readsc(reader: treader); +begin + shortcuts:= readshortcutarty(reader); +end; + +procedure tmenuitem.writesc(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut); +end; + +procedure tmenuitem.readsc1(reader: treader); +begin + shortcuts1:= readshortcutarty(reader); +end; + +procedure tmenuitem.writesc1(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut1); +end; + +procedure tmenuitem.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('shortcut',{$ifdef FPC}@{$endif}readshortcut,nil,false); + filer.defineproperty('shortcut1',{$ifdef FPC}@{$endif}readshortcut1,nil,false); + filer.defineproperty('sc',{$ifdef FPC}@{$endif}readsc, + {$ifdef FPC}@{$endif}writesc, + isactionshortcutstored(finfo) and + ((filer.ancestor = nil) and (finfo.shortcut <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(finfo.shortcut, + tmenuitem(filer.ancestor).shortcuts)))); + filer.defineproperty('sc1',{$ifdef FPC}@{$endif}readsc1, + {$ifdef FPC}@{$endif}writesc1, + isactionshortcut1stored(finfo) and + ((filer.ancestor = nil) and (finfo.shortcut1 <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(finfo.shortcut, + tmenuitem(filer.ancestor).shortcuts)))); +end; + +procedure tmenuitem.updatecaption; +var + int1: integer; +begin + mseactions.calccaptiontext(finfo,shortcutseparator); + for int1:= 0 to count - 1 do begin + fsubmenu[int1].updatecaption; + end; +end; + +function tmenuitem.actualcolor: colorty; +begin + result:= finfo.color; + if (result = cl_default) or (result = cl_parent) then begin + if fparentmenu = nil then begin + result:= cl_transparent; + end + else begin + result:= fparentmenu.actualcolor; + end; + end; +end; + +function tmenuitem.actualcoloractive: colorty; +begin + result:= fcoloractive; + if (result = cl_default) or (result = cl_parent) then begin + if fparentmenu = nil then begin + result:= actualcolor; + end + else begin + result:= fparentmenu.actualcoloractive; + end; + end + else begin + if result = cl_normal then begin + result:= actualcolor; + end; + end; +end; + +function tmenuitem.actualcolorglyph: colorty; +begin + result:= finfo.colorglyph; + if (result = cl_default) or (result = cl_parent) then begin + if fparentmenu <> nil then begin + result:= fparentmenu.actualcolorglyph; + end + else begin + result:= cl_default; + end; + end; +end; + +function tmenuitem.actualcolorglyphactive: colorty; +begin + result:= fcolorglyphactive; + if (result = cl_default) or (result = cl_parent) then begin + if fparentmenu <> nil then begin + result:= fparentmenu.actualcolorglyphactive; + end + else begin + result:= cl_default; + end; + end; +end; + +function tmenuitem.getstate: actionstatesty; +begin + result:= finfo.state; +end; + +function tmenuitem.getcheckedtag: integer; +var + int1: integer; +begin + result:= -1; + if fparentmenu <> nil then begin + with fparentmenu.fsubmenu do begin + for int1:= 0 to high(fitems) do begin + with tmenuitem(fitems[int1]) do begin + if (mao_radiobutton in finfo.options) and (finfo.group = self.finfo.group) and + checked then begin + result:= finfo.tag; + break; + end; + end; + end; + end; + end; +end; + +procedure tmenuitem.setcheckedtag(const avalue: integer); +var + int1: integer; +begin + if fparentmenu <> nil then begin + with fparentmenu.fsubmenu do begin + for int1:= 0 to high(fitems) do begin + with tmenuitem(fitems[int1]) do begin + if (mao_radiobutton in finfo.options) and + (finfo.group = self.finfo.group) then begin + if finfo.tag = avalue then begin + checked:= true; + break; + end + else begin + checked:= false; + end; + end; + end; + end; + end; + end; +end; + +function tmenuitem.getactiveitem(out aitem: tmenuitem): boolean; +begin + result:= (factiveitem >= 0) and (fsubmenu <> nil) and + (factiveitem < fsubmenu.count); + if result then begin + aitem:= fsubmenu[factiveitem]; + end; +end; + +function tmenuitem.getassistivename: msestring; +var + item1: tmenuitem; +begin + if getactiveitem(item1) then begin + result:= msestring(item1.fname); + end + else begin + result:= ''; + end; + if (result = '') and (fowner <> nil) then begin + result:= msestring(fowner.name); + end; +end; + +function tmenuitem.getassistivecaption(): msestring; +var + item1: tmenuitem; +begin + if getactiveitem(item1) then begin + result:= item1.finfo.captiontext; + end + else begin + result:= ''; + end; +end; + +function tmenuitem.getassistivetext(): msestring; +begin + result:= ''; +end; + +function tmenuitem.getassistivecaretindex(): int32; +begin + result:= -1; +end; + +function tmenuitem.getassistivehint(): msestring; +var + item1: tmenuitem; +begin + if getactiveitem(item1) then begin + result:= item1.finfo.hint; + end + else begin + result:= ''; + end; +end; + +function tmenuitem.getassistiveflags(): assistiveflagsty; +begin + result:= [asf_menu]; +end; + +function tmenuitem.getifidatalinkintf(): iifidatalink; +begin + result:= nil; +end; + +function tmenuitem.getassistiveselfcaption(): msestring; +begin + result:= caption; +end; + +function tmenuitem.getassistiveselfname(): msestring; +begin + result:= msestring(name); +end; + +function tmenuitem.getassistiveselfhint(): msestring; +begin + result:= hint; +end; + +{ tmenuitems } + +constructor tmenuitems.create(const aowner: tmenuitem); +begin + fowner:= aowner; + inherited create(tmenuitem); +end; + +class function tmenuitems.getitemclasstype: persistentclassty; +begin + result:= tmenuitem; +end; + +procedure tmenuitems.assign(source: tpersistent); +var + int1: integer; +begin + if source is tmenuitems then begin + with tmenuitems(source) do begin + self.count:= count; + for int1:= 0 to count - 1 do begin + self.setmenuitems(int1,getmenuitems(int1)); + end; + end; + end + else begin + inherited; + end; +end; + +procedure tmenuitems.createitem(const index: integer; var item: tpersistent); +begin + item:= tmenuitem.create(fowner,fowner.fowner); +end; + +procedure tmenuitems.receiveevent(const event: tobjectevent); +begin + if event.kind = ek_release then begin + destroy; + end; +end; + +procedure tmenuitems.dosizechanged; +begin + inherited; + { too dangerous because of runtime submenu clear in with statement. + if count = 0 then begin + tmenuitem(fowner).fsubmenu:= nil; + fowner:= nil; + application.postevent(tobjectevent.create(ek_release,ievent(self))); + end; + } +end; + +procedure tmenuitems.dochange(const aindex: integer); +var + int1: integer; +begin + if aindex = -1 then begin + for int1:= 0 to count - 1 do begin + items[int1].actionchanged; + end; + end; + if fowner <> nil then begin + fowner.actionchanged; + end; + inherited; +end; + +function tmenuitems.getmenuitems(index: integer): tmenuitem; +begin + result:= tmenuitem(getitems(index)); +end; + +function tmenuitems.insert(const index: integer; const aitem: tmenuitem): integer; +var + int1: integer; +begin + int1:= index; + if index > count then begin + int1:= count; + end; + result:= int1; + beginupdate; + try + insertempty(int1); + aitem.fparentmenu:= fowner; + aitem.fowner:= fowner.fowner; + fitems[int1]:= aitem; + finally + endupdate; + end; +end; + +procedure tmenuitems.insertseparator(const index: integer; + const aoptional: boolean = false); +var + item1: tmenuitem; + opt1: menuactionoptionsty; +begin + item1:= tmenuitem.create; + opt1:= [mao_separator]; + if aoptional then begin + opt1:= [mao_separator,mao_optional]; + end; + item1.options:= item1.options + opt1; + insert(index,item1); +end; + +function tmenuitems.insert(const index: integer; + const aitems: tmenuitems): integer; +var + int1,int2: integer; + item1: tmenuitem; +begin + int1:= index; + if index > count then begin + int1:= count; + end; + result:= int1; + beginupdate; + try + for int2:= 0 to aitems.count - 1 do begin + item1:= tmenuitem.create; + insert(int1,item1); + item1.assign(aitems[int2]); + inc(int1); + end; + finally + endupdate; + end; +end; + +function tmenuitems.insert(const index: integer; + const captions: array of msestring; + //if index > count -> index:= count + const options: array of menuactionoptionsty; + const states: array of actionstatesty; + const onexecutes: array of notifyeventty): integer; +var + int1,int2,int3: integer; + item1: tmenuitem; +begin + int1:= -1; + if high(captions) > int1 then begin + int1:= high(captions); + end; + if high(options) > int1 then begin + int1:= high(options); + end; + if high(states) > int1 then begin + int1:= high(states); + end; + if high(onexecutes) > int1 then begin + int1:= high(onexecutes); + end; + if index > count then begin + int3:= count; + end + else begin + int3:= index; + end; + result:= int3; + beginupdate; + try + for int2:= 0 to int1 do begin + item1:= tmenuitem.create; + if int2 <= high(captions) then begin + item1.caption:= captions[int2]; + end; + if int2 <= high(options) then begin + item1.options:= options[int2]; + end; + if int2 <= high(states) then begin + item1.state:= states[int2]; + end; + if int2 <= high(onexecutes) then begin + item1.onexecute:= onexecutes[int2]; + end; + insert(int3,item1); + inc(int3); + end; + finally + endupdate; + end; +end; + +procedure tmenuitems.setmenuitems(index: integer; const Value: tmenuitem); +begin + tmenuitem(getitems(index)).assign(value); +end; + +function tmenuitems.itemindexbyname(const name: ansistring): integer; +var + int1: integer; + po1: pmenuitem; +begin + result:= -1; + po1:= pointer(fitems); + for int1:= 0 to high(fitems) do begin + if (po1^.fname = name) or + (po1^.finfo.action <> nil) and (po1^.finfo.action.Name = name) then begin + result:= int1; + break; + end; + inc(po1); + end; +end; + +function tmenuitems.itembyname(const name: ansistring): tmenuitem; +var + int1: integer; +begin + int1:= itemindexbyname(name); + if int1 < 0 then begin + result:= nil; + end + else begin + result:= tmenuitem(fitems[int1]); + end; +end; + +function comparemenuitem(const l,r): integer; +begin + result:= msecomparetext(tmenuitem(l).finfo.caption1.text, + tmenuitem(r).finfo.caption1.text); +end; + +procedure tmenuitems.sort; +begin + sortarray(pointerarty(fitems),@comparemenuitem); + dochange(-1); +end; + +function tmenuitems.hasvisibleitem: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count - 1 do begin + if not (as_invisible in tmenuitem(fitems[int1]).finfo.state) then begin + result:= true; + break; + end; + end; +end; + +{ tpopupmenu } + +class function tpopupmenu.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_popupmenu; +end; + +function tpopupmenu.show(const atransientfor: twidget; + const pos: graphicdirectionty): tmenuitem; +begin + settransientfor(atransientfor); + try + doupdate; + result:= showpopupmenu(fmenu,ftransientfor,pos,self); + checkexec; + finally + settransientfor(nil); + end; +end; + +function tpopupmenu.show(const atransientfor: twidget; + var mouseinfo: mouseeventinfoty): tmenuitem; +begin + settransientfor(atransientfor); + fmouseinfopo:= @mouseinfo; + try + doupdate; + result:= showpopupmenu(fmenu,ftransientfor,mouseinfo.pos,self); + include(mouseinfo.eventstate,es_processed); + checkexec; + finally + settransientfor(nil); + fmouseinfopo:= nil; + end; +end; + +function tpopupmenu.show(const atransientfor: twidget; + const pos: pointty): tmenuitem; +begin + settransientfor(atransientfor); + try + doupdate; + result:= showpopupmenu(fmenu,ftransientfor,pos,self); + checkexec; + finally + settransientfor(nil); + end; +end; + +class function tpopupmenu.additems(var amenu: tpopupmenu; + const atransientfor: twidget; + var mouseinfo: mouseeventinfoty; + const captions: array of msestring; + //if index > count -> index:= count + const aoptions: array of menuactionoptionsty; + const states: array of actionstatesty; + const onexecutes: array of notifyeventty; + const aseparator: boolean = true; + const optionalseparator: boolean = true): integer; +begin + if amenu = nil then begin + amenu:= tpopupmenu.createtransient(atransientfor,@mouseinfo); + end; + if aseparator{ and amenu.menu.hasvisibleitem} then begin + amenu.menu.submenu.insertseparator(bigint,optionalseparator); + end; + result:= amenu.menu.submenu.insert(bigint,captions,aoptions,states,onexecutes); +end; + +class function tpopupmenu.additems(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty; const items: tmenuitems; + const aseparator: boolean = true; + const first: boolean = false; + const optionalseparator: boolean = true): integer; +begin + if amenu = nil then begin + amenu:= tpopupmenu.createtransient(atransientfor,@mouseinfo); + end; + result:= -1; //compiler warning + if items <> nil then begin +// aseparator:= aseparator and items.hasvisibleitem and +// amenu.menu.hasvisibleitem; + if first then begin + result:= amenu.menu.submenu.insert(0,items); + if aseparator then begin + amenu.menu.submenu.insertseparator(items.count,optionalseparator); + end; + end + else begin + if aseparator then begin + amenu.menu.submenu.insertseparator(bigint,optionalseparator); + end; + result:= amenu.menu.submenu.insert(bigint,items); + end; + end; +end; + +class function tpopupmenu.additems(var amenu: tpopupmenu; + const atransientfor: twidget; var mouseinfo: mouseeventinfoty; + const items: tcustommenu): integer; +var + bo1: boolean; + widget1: twidget; + items1: tmenuitems; +begin + items.fmouseinfopo:= @mouseinfo; + widget1:= items.ftransientfor; + items.settransientfor(atransientfor); + try + items.doupdate; + finally + items.settransientfor(widget1); + end; + bo1:= (amenu = nil) or amenu.ftransient; + items1:= nil; + if items.fmenu.visible then begin + items1:= items.fmenu.fsubmenu; + end; + result:= additems(amenu,atransientfor,mouseinfo,items1, + not (mo_noseparator in items.foptions),mo_insertfirst in items.foptions, + not (mo_forceseparator in items.foptions)); + if bo1 then begin + amenu.fmenu.enabled:= items.fmenu.enabled; + amenu.foptions:= items.foptions; + amenu.assigntemplate(items); + amenu.fmenu.ffont:= items.fmenu.ffont; + amenu.fmenu.ffontactive:= items.fmenu.ffontactive; + amenu.fmenu.color:= items.fmenu.color; + amenu.fmenu.coloractive:= items.fmenu.coloractive; + end; +end; + +{ tcustommainmenu } + +constructor tcustommainmenu.create(aowner: tcomponent); +begin + inherited; + include(foptions,mo_updateonidle); + if not (csdesigning in componentstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doidle); + end; + fmenu.onchange:= {$ifdef FPC}@{$endif}menuchanged; +end; + +destructor tcustommainmenu.destroy; +begin + inherited; +end; + +procedure tcustommainmenu.setpopupframetemplate(const avalue: tframecomp); +begin + if avalue <> fpopuptemplate.frame then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.frame)); + end; +end; + +procedure tcustommainmenu.setpopupfacetemplate(const avalue: tfacecomp); +begin + if avalue <> fpopuptemplate.face then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.face)); + end; +end; + +procedure tcustommainmenu.setpopupitemframetemplate(const avalue: tframecomp); +begin + if avalue <> fpopuptemplate.itemframe then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.itemframe)); + end; +end; + +procedure tcustommainmenu.setpopupitemfacetemplate(const avalue: tfacecomp); +begin + if avalue <> fpopuptemplate.itemface then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.itemface)); + end; +end; + +procedure tcustommainmenu.setpopupitemframetemplateactive( + const avalue: tframecomp); +begin + if avalue <> fpopuptemplate.itemframeactive then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.itemframeactive)); + end; +end; + +procedure tcustommainmenu.setpopupitemfacetemplateactive( + const avalue: tfacecomp); +begin + if avalue <> fpopuptemplate.itemfaceactive then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.itemfaceactive)); + end; +end; + +procedure tcustommainmenu.setpopupseparatorframetemplate( + const avalue: tframecomp); +begin + if avalue <> fpopuptemplate.separatorframe then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.separatorframe)); + end; +end; + +procedure tcustommainmenu.setpopupcheckboxframetemplate( + const avalue: tframecomp); +begin + if avalue <> fpopuptemplate.checkboxframe then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.checkboxframe)); + end; +end; + +class function tcustommainmenu.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_mainmenu; +end; + +procedure tcustommainmenu.menuchanged(const sender: tmenuitem); +begin + if (fobjectlinker <> nil) and not (csloading in componentstate) then begin + fobjectlinker.sendevent(oe_changed); + end; +end; + +function tcustommainmenu.gettemplatefont(const sender: tmenuitem): tmenufont; +begin + if (sender.fparentmenu <> nil) and (sender.fparentmenu <> fmenu) then begin + //in popup + result:= nil; + if popupitemframetemplate <> nil then begin +{$warnings off} + result:= tmenufont(popupitemframetemplate.template.font); +{$warnings on} + end; +(* + if result = nil then begin +{$warnings off} + result:= tmenufont(pointer(stockobjects.fonts[stf_menu])); +{$warnings on} + end; +*) + end + else begin + result:= inherited gettemplatefont(sender); + end; +end; + +function tcustommainmenu.gettemplatefontactive( + const sender: tmenuitem): tmenufontactive; +begin + if sender.fparentmenu <> fmenu then begin //in popup + result:= nil; + if popupitemframetemplateactive <> nil then begin + result:= tmenufontactive(pointer(popupitemframetemplateactive.template.font)); + end; + end + else begin + result:= inherited gettemplatefontactive(sender); + end; +end; + +procedure tcustommainmenu.objectevent(const sender: tobject; + const event: objecteventty); +begin + templateevent(sender,event,fpopuptemplate); + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msenogui.pas b/mseide-msegui/lib/common/kernel/msenogui.pas new file mode 100644 index 0000000..f4e8561 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msenogui.pas @@ -0,0 +1,219 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msenogui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + sysutils,classes,mclasses,mseapplication,mseevent,msesystypes, + msetypes,msestrings; +type + tnoguiapplication = class(tcustomapplication) + private + feventsem: semty; + fmodallevel: integer; + protected + procedure dopostevent(const aevent: tmseevent); override; + procedure doeventloop(const once: boolean); override; + function nextevent: tmseevent; + procedure dobeforerun; override; + procedure doafterrun; override; + procedure internalinitialize; override; + procedure internaldeinitialize; override; + procedure sethighrestimer(const avalue: boolean); override; + function getevents: integer; override; + //application must be locked + //returns count of queued events + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure destroymodules(); + function modallevel: integer; override; + procedure showexception(e: exception; const leadingtext: msestring = ''); + override; + procedure errormessage(const amessage: msestring); override; + procedure settimer(const us: integer); override; + end; + +function application: tnoguiapplication; + +implementation +uses + msesysutils,msesysintf1,msetimer,msenoguiintf,msethread; +var + appinst: tnoguiapplication; + +function application: tnoguiapplication; +begin + if appinst = nil then begin + tnoguiapplication.create(nil); +// appinst.initialize; + end; + result:= appinst; +end; + +{ tnoguiapplication } + +constructor tnoguiapplication.create(aowner: tcomponent); +begin + fmodallevel:= -1; + appinst:= self; + sys_semcreate(feventsem,0); + inherited; +end; + +destructor tnoguiapplication.destroy; +begin + destroymodules(); + inherited; +// deinitialize; + sys_semdestroy(feventsem); +end; + +procedure tnoguiapplication.dopostevent(const aevent: tmseevent); +begin + eventlist.add(aevent); + sys_sempost(feventsem); +end; + +procedure tnoguiapplication.showexception(e: exception; + const leadingtext: msestring = ''); +begin + writestderr('EXCEPTION: '); + writestderr(ansistring(leadingtext)+e.message,true); +end; + +procedure tnoguiapplication.errormessage(const amessage: msestring); +begin + writestderr('ERROR: '); + writestderr(ansistring(amessage),true); +end; + +procedure tnoguiapplication.settimer(const us: integer); +begin + if us <= 0 then begin + inherited; + end + else begin + nogui_settimer(us); + end; +end; + +procedure tnoguiapplication.doeventloop(const once: boolean); +var + event1: tmseevent; + bo1: boolean; +begin +// lock; +// try + inc(fmodallevel); + while not terminated do begin + if eventlist.count = 0 then begin + try + doidle; + except + handleexception(self); + end; + if once then begin + break; + end; + end; + event1:= nextevent; + try + bo1:= false; + fonapplicationeventlist.doevent(event1,bo1); + if not bo1 then begin + case event1.kind of + ek_timer: begin + tick(self); + end; + ek_terminate: begin + terminated:= true; + end; + ek_asyncexec: begin + texecuteevent(event1).deliver; + end; + else begin + if event1 is tobjectevent then begin + with tobjectevent(event1) do begin + deliver; + end; + end; + end; + end; + end; + except + handleexception(self); + end; + event1.free1; //do not destroy synchronizeevent + end; + dec(fmodallevel); +// finally +// unlock; +// end; +end; + +function tnoguiapplication.nextevent: tmseevent; +begin + nogui_waitevent; +// sys_semwait(feventsem,0); + result:= tmseevent(eventlist.getfirst); +end; + +procedure tnoguiapplication.dobeforerun; +begin + if running then begin + raise exception.create('Already running.'); + end; +end; + +procedure tnoguiapplication.internalinitialize; +begin + nogui_init(@feventsem); + msetimer.init; +end; + +procedure tnoguiapplication.internaldeinitialize; +begin + msetimer.deinit; + nogui_deinit; +end; + +procedure tnoguiapplication.destroymodules(); +begin + while componentcount > 0 do begin + components[componentcount-1].free; //destroy loaded modules + end; +end; + +procedure tnoguiapplication.doafterrun; +begin + if not (apo_noautodestroymodules in foptions) then begin + destroymodules(); + end; +end; + +function tnoguiapplication.modallevel: integer; +begin + result:= fmodallevel; +end; + +procedure tnoguiapplication.sethighrestimer(const avalue: boolean); +begin + //dummy +end; + +function tnoguiapplication.getevents: integer; +begin + result:= eventlist.count; +end; + +initialization + registerapplicationclass(tnoguiapplication); +end. diff --git a/mseide-msegui/lib/common/kernel/msenoguiintf.inc b/mseide-msegui/lib/common/kernel/msenoguiintf.inc new file mode 100644 index 0000000..88fdcb3 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msenoguiintf.inc @@ -0,0 +1,4 @@ +procedure nogui_init(const asempo: psemty); +procedure nogui_deinit; +procedure nogui_waitevent; +procedure nogui_settimer(us: longword); diff --git a/mseide-msegui/lib/common/kernel/mseobjecttext.pas b/mseide-msegui/lib/common/kernel/mseobjecttext.pas new file mode 100644 index 0000000..2028307 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseobjecttext.pas @@ -0,0 +1,1646 @@ +{ + This file is part of the Free Component Library (FCL) + Copyright (c) 1999-2000 by Michael Van Canneyt and Florian Klaempfl + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. + + Modified 2010-2013 by Martin Schreiber +} +unit mseobjecttext; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses; + +procedure objectbinarytotextmse(input, output: tstream); +procedure objecttexttobinarymse(input, output: tstream); + +implementation +uses + sysutils,rtlconsts,msestrings,msetypes,msereal,msefloattostr; +{$ifdef FPC} {$define CLASSESINLINE} {$endif} +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifndef FPC} +type + unicodestring = widestring; +resourcestring + SerrInvalidPropertyType = 'Invalid property type from streamed property: %d'; + SParExpected = 'Wrong token type: %s expected'; + SParInvalidFloat = 'Invalid floating point number: %s'; + SParInvalidInteger = 'Invalid integer number: %s'; + SParUnterminatedString = 'Unterminated string'; + SParWrongTokenType = 'Wrong token type: %s expected but %s found'; + SParWrongTokenSymbol = 'Wrong token symbol: %s expected but %s found'; + SParLocInfo = ' (at %d,%d, stream offset %.8x)'; + SParUnterminatedBinValue = 'Unterminated byte value'; +{$endif} + +const + toemptyfloat = Char(6); + ParseBufSize = 4096; + LastSpecialToken = 6; + + TokNames : array[0..LastSpecialToken] of string = + ( + 'EOF', + 'Symbol', + 'String', + 'Integer', + 'Float', + 'WideString', + 'EmptyFloat' + ); + +type +{ TParser } + + TParser = class(TObject) + private + fStream : TStream; + fBuf : pchar; + fBufLen : integer; + fPos : integer; + fDeltaPos : integer; + fFloatType : char; + fSourceLine : integer; + fToken : char; + fEofReached : boolean; + fLastTokenStr : string; + fLastTokenWStr : unicodestring; + function GetTokenName(aTok : char) : string; + procedure LoadBuffer; + procedure CheckLoadBuffer; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + procedure ProcessChar; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function IsNumber : boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function IsHexNum : boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function IsAlpha : boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function IsAlphaNum : boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function GetHexValue(c : char) : byte; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function GetAlphaNum : string; + procedure HandleNewLine; + procedure SkipBOM; + procedure SkipSpaces; + procedure SkipWhitespace; + procedure HandleEof; + procedure HandleAlphaNum; + procedure HandleNumber; + procedure HandleHexNumber; + function HandleQuotedString : string; + procedure HandleDecimalCharacter(var ascii : boolean; + out WideChr: widechar; out StringChr: char); + procedure HandleString; + procedure HandleMinus; + procedure HandleUnknown; + public + constructor Create(Stream: TStream); + destructor Destroy; override; + procedure CheckToken(T: Char); + procedure CheckTokenSymbol(const S: string); + procedure Error(const Ident: string); + procedure ErrorFmt(const Ident: string; const Args: array of const); + procedure ErrorStr(const Message: string); + procedure HexToBinary(Stream: TStream); + function NextToken: Char; + function SourcePos: Longint; + function TokenComponentIdent: string; +{$ifndef FPUNONE} + function TokenFloat: Extended; +{$endif} + function TokenInt: Int64; + function TokenString: string; + function TokenWideString: unicodestring; + function TokenSymbolIs(const S: string): Boolean; + property FloatType: Char read fFloatType; + property SourceLine: Integer read fSourceLine; + property Token: Char read fToken; + end; + +{ Object conversion routines } + +type + TObjectTextEncoding = ( + oteDFM, + oteLFM + ); + CharToOrdFuncty = Function(var charpo: Pointer): Cardinal; + +function CharToOrd(var P: Pointer): Cardinal; +begin + result:= ord(pchar(P)^); + inc(pchar(P)); +end; + +function WideCharToOrd(var P: Pointer): Cardinal; +begin + result:= ord(pwidechar(P)^); + inc(pwidechar(P)); +end; + +function Utf8ToOrd(var P:Pointer): Cardinal; +begin + // Should also check for illegal utf8 combinations + Result := Ord(PChar(P)^); + Inc(pbyte(P)); + if (Result and $80) <> 0 then + if (Ord(Result) and $e0) = $c0 then begin + Result := ((Result and $1f) shl 6) + or (ord(PChar(P)^) and $3f); + Inc(pbyte(P)); + end else if (Ord(Result) and $f0) = $e0 then begin + Result := ((Result and $1f) shl 12) + or ((ord(PChar(P)^) and $3f) shl 6) + or (ord((PChar(P)+1)^) and $3f); + Inc(pbyte(P),2); + end else begin + Result := ((ord(Result) and $1f) shl 18) + or ((ord(PChar(P)^) and $3f) shl 12) + or ((ord((PChar(P)+1)^) and $3f) shl 6) + or (ord((PChar(P)+2)^) and $3f); + Inc(pbyte(P),3); + end; +end; + +procedure ObjectBinaryToText1(Input, Output: TStream; + Encoding: TObjectTextEncoding); + + procedure OutStr(const s: String); + begin + if s <> '' then + Output.Write(pointer(s)^, Length(s)); + end; + + procedure OutLn(const s: String); + begin + OutStr(s + LineEnd); + end; + + procedure Outchars(P, LastP : Pointer; CharToOrdFunc: CharToOrdFuncty; + UseBytes: boolean = false); + + var + res, NewStr: String; + w: Cardinal; + InString, NewInString: Boolean; + begin + if p = nil then begin + res:= ''''''; + end + else + begin + res := ''; + InString := False; + while ptruint(P) < ptruint(LastP) do + begin + NewInString := InString; + w := CharToOrdfunc(P); + if w = ord('''') then + begin //quote char + if not InString then + NewInString := True; + NewStr := ''''''; + end + else if (Ord(w) >= 32) and ((Ord(w) < 127) or (UseBytes and (Ord(w)<256))) then + begin //printable ascii or bytes + if not InString then + NewInString := True; + NewStr := char(w); + end + else + begin //ascii control chars, non ascii + if InString then + NewInString := False; + NewStr := '#' + IntToStr(w); + end; + if NewInString <> InString then + begin + NewStr := '''' + NewStr; + InString := NewInString; + end; + res := res + NewStr; + end; + if InString then + res := res + ''''; + end; + OutStr(res); + end; + + procedure OutString(const s: String); + begin + OutChars(Pointer(S),PChar(S)+Length(S),@CharToOrd,Encoding=oteLFM); + end; + + procedure OutWString(const W: WideString); + begin + OutChars(Pointer(W),pwidechar(W)+Length(W),@WideCharToOrd); + end; + + procedure OutUString(const W: UnicodeString); + begin + OutChars(Pointer(W),pwidechar(W)+Length(W),@WideCharToOrd); + end; + + procedure OutUtf8Str(const s: String); + begin + if Encoding=oteLFM then + OutChars(Pointer(S),PChar(S)+Length(S),@CharToOrd) + else + OutChars(Pointer(S),PChar(S)+Length(S),@Utf8ToOrd); + end; + +{$ifndef FPC} + function readbyte: byte; + begin + input.readbuffer(result,sizeof(result)); + end; +{$endif} + + function ReadWord : word; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + Result:=Input.ReadWord; + Result:=LEtoN(Result); + {$else} + input.ReadBuffer(result,sizeof(result)); + {$endif} + end; + + function ReadDWord : longword; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + Result:=Input.ReadDWord; + Result:=LEtoN(Result); + {$else} + input.ReadBuffer(result,sizeof(result)); + {$endif} + end; + + function ReadQWord : qword; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + Input.ReadBuffer(Result,sizeof(Result)); + Result:=LEtoN(Result); + {$else} + input.ReadBuffer(result,sizeof(result)); + {$endif} + end; +(* +{$ifndef FPUNONE} + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + function ExtendedToDouble(e : pointer) : double; + var mant : qword; + exp : smallint; + sign : boolean; + d : qword; + begin + {$ifdef FPC} + move(pbyte(e)[0],mant,8); //mantissa : bytes 0..7 + move(pbyte(e)[8],exp,2); //exponent and sign: bytes 8..9 + mant:=LEtoN(mant); + exp:=LetoN(word(exp)); + sign:=(exp and $8000)<>0; + if sign then exp:=exp and $7FFF; + case exp of + 0 : mant:=0; //if denormalized, value is too small for double, + //so it's always zero + $7FFF : exp:=2047 //either infinity or NaN + else + begin + dec(exp,16383-1023); + if (exp>=-51) and (exp<=0) then //can be denormalized + begin + mant:=mant shr (-exp); + exp:=0; + end + else + if (exp<-51) or (exp>2046) then //exponent too large. + begin + Result:=0; + exit; + end + else //normalized value + mant:=mant shl 1; //hide most significant bit + end; + end; + d:=word(exp); + d:=d shl 52; + + mant:=mant shr 12; + d:=d or mant; + if sign then d:=d or $8000000000000000; + Result:=pdouble(@d)^; + {$else} + result:= extended(e^); + {$endif} + end; + {$ENDIF} +{$endif} +*) + function ReadInt(ValueType: TValueType): Int64; overload; + begin + result:= 0; + case ValueType of + vaInt8: Result := ShortInt({$ifdef FPC}Input.{$endif}ReadByte); + vaInt16: Result := SmallInt(ReadWord); + vaInt32: Result := LongInt(ReadDWord); + vaInt64: Result := Int64(ReadQWord); + end; + end; + + function ReadInt: Int64; overload; + begin + Result := ReadInt(TValueType({$ifdef FPC}Input.{$endif}ReadByte)); + end; + +{$ifndef FPUNONE} + function ReadExtended : extended; + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + var ext : array[0..9] of byte; + {$ENDIF} + begin + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + Input.ReadBuffer(ext[0],10); + Result:=ExtendedToDouble(@(ext[0])); + {$ELSE} + Input.ReadBuffer(Result,sizeof(Result)); + {$ENDIF} + end; +{$endif} + + function ReadSStr: String; + var + len: Byte; + begin + len := {$ifdef FPC}Input.{$endif}ReadByte; + SetLength(Result, len); + if (len > 0) then + Input.ReadBuffer(Result[1], len); + end; + + function ReadLStr: String; + var + len: DWord; + begin + len := ReadDWord; + SetLength(Result, len); + if (len > 0) then + Input.ReadBuffer(Result[1], len); + end; + + function ReadWStr: WideString; + var + len: DWord; + {$IFDEF ENDIAN_BIG} + i : integer; + {$ENDIF} + begin + len := ReadDWord; + SetLength(Result, len); + if (len > 0) then + begin + Input.ReadBuffer(Pointer(@Result[1])^, len*2); + {$IFDEF ENDIAN_BIG} + for i:=1 to len do + Result[i]:=widechar(SwapEndian(word(Result[i]))); + {$ENDIF} + end; + end; + + function ReadUStr: UnicodeString; + var + len: DWord; + {$IFDEF ENDIAN_BIG} + i : integer; + {$ENDIF} + begin + len := ReadDWord; + SetLength(Result, len); + if (len > 0) then + begin + Input.ReadBuffer(Pointer(@Result[1])^, len*2); + {$IFDEF ENDIAN_BIG} + for i:=1 to len do + Result[i]:=widechar(SwapEndian(word(Result[i]))); + {$ENDIF} + end; + end; + + procedure processstring(const valuetype: tvaluetype); + begin + case valuetype of + vastring: begin + outstring(readsstr); + end; + valstring: begin + outstring(readlstr); + end; + vautf8string: begin + oututf8str(readlstr); + end; + vawstring: begin + outwstring(readwstr); + end; + vaustring: begin + outustring(readustr); + end; + end; + end; //processstring + + procedure ReadPropList(indent: String); + + procedure ProcessValue(ValueType: TValueType; Indent: String); + + procedure ProcessBinary; + var + ToDo, DoNow, i: LongInt; + lbuf: array[0..31] of Byte; + s: String; + begin + ToDo := ReadDWord; + OutLn('{'); + while ToDo > 0 do begin + DoNow := ToDo; + if DoNow > 32 then DoNow := 32; + Dec(ToDo, DoNow); + s := Indent + ' '; + Input.ReadBuffer(lbuf, DoNow); + for i := 0 to DoNow - 1 do + s := s + IntToHex(lbuf[i], 2); + OutLn(s); + end; + OutLn(indent + '}'); + end; + + var + s: String; +{ len: LongInt; } + IsFirst: Boolean; +{$ifndef FPUNONE} + ext: Extended; +{$endif} + + begin + case ValueType of + vaList: begin + OutStr('('); + IsFirst := True; + while True do begin + ValueType := TValueType({$ifdef FPC}Input.{$endif}ReadByte); + if ValueType = vaNull then break; + if IsFirst then begin + OutLn(''); + IsFirst := False; + end; + OutStr(Indent + ' '); + ProcessValue(ValueType, Indent + ' '); + end; + OutLn(Indent + ')'); + end; + vaInt8: OutLn(IntToStr(ShortInt({$ifdef FPC}Input.{$endif}ReadByte))); + vaInt16: OutLn( IntToStr(SmallInt(ReadWord))); + vaInt32: OutLn(IntToStr(LongInt(ReadDWord))); + vaInt64: OutLn(IntToStr(Int64(ReadQWord))); +{$ifndef FPUNONE} + vaExtended: begin + ext:=ReadExtended; + if ext = emptyreal then begin + s:= '-Inf'; + end + else begin + s:= ansistring(doubletostring(ext,0,fsm_default,'.')); +// Str(ext,S);// Do not use localized strings. + end; + OutLn(S); + end; +{$endif} + vaString: begin + OutString(ReadSStr); + OutLn(''); + end; + vaIdent: OutLn(ReadSStr); + vaFalse: OutLn('False'); + vaTrue: OutLn('True'); + vaBinary: ProcessBinary; + vaSet: begin + OutStr('['); + IsFirst := True; + while True do begin + s := ReadSStr; + if Length(s) = 0 then break; + if not IsFirst then OutStr(', '); + IsFirst := False; + OutStr(s); + end; + OutLn(']'); + end; + vaLString: + begin + OutString(ReadLStr); + OutLn(''); + end; + vaWString: + begin + OutWString(ReadWStr); + OutLn(''); + end; + {$ifdef FPC} + vaUString: + begin + OutuString(ReaduStr); + OutLn(''); + end; + {$endif} + vaNil: + OutLn('nil'); + vaNull: + OutLn('null'); + vaCollection: begin + OutStr('<'); + while {$ifdef FPC}Input.{$endif}ReadByte <> 0 do begin + OutLn(Indent); + Input.Seek(-1, soFromCurrent); + OutStr(indent + ' item'); + ValueType:= TValueType({$ifdef FPC}Input.{$endif}ReadByte); + case valuetype of + vaInt8,vaInt16,vaInt32: begin + OutStr('[' + IntToStr(ReadInt(ValueType)) + ']'); + valuetype:= tvaluetype({$ifdef fpc}input.{$endif}readbyte); + end; + vaident: begin + outstr('['+readsstr+']'); + valuetype:= tvaluetype({$ifdef fpc}input.{$endif}readbyte); + end; + end; + if valuetype <> valist then begin + raise ereaderror.createfmt(serrinvalidpropertytype, + [ord(valuetype)]); + end; + OutLn(''); + ReadPropList(indent + ' '); + OutStr(indent + ' end'); + end; + OutLn('>'); + end; + {vaSingle: begin OutLn('!!Single!!'); exit end; + vaCurrency: begin OutLn('!!Currency!!'); exit end; + vaDate: begin OutLn('!!Date!!'); exit end;} + vaUTF8String: begin + OutUtf8Str(ReadLStr); + OutLn(''); + end; + else + Raise EReadError.CreateFmt(SErrInvalidPropertyType,[Ord(ValueType)]); + end; + end; + + begin + while {$ifdef FPC}Input.{$endif}ReadByte <> 0 do begin + Input.Seek(-1, soFromCurrent); + OutStr(indent + ReadSStr + ' = '); + ProcessValue(TValueType({$ifdef FPC}Input.{$endif}ReadByte), Indent); + end; + end; + + procedure ReadObject(indent: String); + var + b: Byte; + ObjClassName, ObjName: String; + ChildPos: LongInt; + begin + childpos:= 0; + // Check for FilerFlags + b := {$ifdef FPC}Input.{$endif}ReadByte; + if (b and $f0) = $f0 then begin + if (b and 2) <> 0 then ChildPos := ReadInt; + end else begin + b := 0; + Input.Seek(-1, soFromCurrent); + end; + + ObjClassName := ReadSStr; + ObjName := ReadSStr; + + OutStr(Indent); + if (b and 1) <> 0 then OutStr('inherited') + else + if (b and 4) <> 0 then OutStr('inline') + else OutStr('object'); + OutStr(' '); + if ObjName <> '' then + OutStr(ObjName + ': '); + OutStr(ObjClassName); + if (b and 2) <> 0 then OutStr('[' + IntToStr(ChildPos) + ']'); + OutLn(''); + + ReadPropList(indent + ' '); + + while {$ifdef FPC}Input.{$endif}ReadByte <> 0 do begin + Input.Seek(-1, soFromCurrent); + ReadObject(indent + ' '); + end; + OutLn(indent + 'end'); + end; + +type + PLongWord = ^LongWord; +const + signature: PChar = 'TPF0'; + +begin + if {$ifdef FPC}Input.{$endif}ReadDWord <> PLongWord(Pointer(signature))^ then + raise EReadError.Create('Illegal stream image' {###SInvalidImage}); + ReadObject(''); +end; + +procedure ObjectBinaryToText(Input, Output: TStream); +begin + ObjectBinaryToText1(Input,Output,oteDFM); +end; + +procedure ObjectTextToBinary(Input, Output: TStream); +var + parser: TParser; + + {$ifndef FPC} + procedure Writebyte(b : byte); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + output.WriteBuffer(b,sizeof(b)); + end; + {$endif} + + procedure WriteWord(w : word); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + w:=NtoLE(w); + Output.WriteWord(w); + {$else} + output.WriteBuffer(w,sizeof(w)); + {$endif} + end; + + procedure WriteDWord(lw : longword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + lw:=NtoLE(lw); + Output.WriteDWord(lw); + {$else} + output.WriteBuffer(lw,sizeof(lw)); + {$endif} + end; + + procedure WriteQWord(qw : qword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + qw:=NtoLE(qw); + Output.WriteBuffer(qw,sizeof(qword)); + {$else} + output.WriteBuffer(qw,sizeof(qw)); + {$endif} + end; +{$ifndef FPUNONE} +(* + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + procedure DoubleToExtended(d : double; e : pointer); + var mant : qword; + exp : smallint; + sign : boolean; + begin + {$ifdef FPC} + mant:=(qword(d) and $000FFFFFFFFFFFFF) shl 12; + exp :=(qword(d) shr 52) and $7FF; + sign:=(qword(d) and $8000000000000000)<>0; + case exp of + 0 : begin + if mant<>0 then //denormalized value: hidden bit is 0. normalize it + begin + exp:=16383-1022; + while (mant and $8000000000000000)=0 do + begin + dec(exp); + mant:=mant shl 1; + end; + dec(exp); //don't shift, most significant bit is not hidden in extended + end; + end; + 2047 : exp:=$7FFF //either infinity or NaN + else + begin + inc(exp,16383-1023); + mant:=(mant shr 1) or $8000000000000000; //unhide hidden bit + end; + end; + if sign then exp:=exp or $8000; + mant:=NtoLE(mant); + exp:=NtoLE(word(exp)); + move(mant,pbyte(e)[0],8); //mantissa : bytes 0..7 + move(exp,pbyte(e)[8],2); //exponent and sign: bytes 8..9 + {$else} + extended(E^):= d; + {$endif} + end; + {$ENDIF} +*) + procedure WriteExtended(e : extended); + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + var ext : array[0..9] of byte; + {$ENDIF} + begin + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + DoubleToExtended(e,@(ext[0])); + Output.WriteBuffer(ext[0],10); + {$ELSE} + Output.WriteBuffer(e,sizeof(e)); + {$ENDIF} + end; +{$endif} + + procedure WriteString(s: String); + var size : byte; + begin + if length(s)>255 then size:=255 + else size:=length(s); + {$ifdef FPC}Output.{$endif}WriteByte(size); + if Length(s) > 0 then + Output.WriteBuffer(s[1], size); + end; + + procedure WriteLString(Const s: String); + begin + WriteDWord(Length(s)); + if Length(s) > 0 then + Output.WriteBuffer(s[1], Length(s)); + end; + + procedure WriteWString(Const s: unicodestring); + var len : longword; + {$IFDEF ENDIAN_BIG} + i : integer; + ws : unicodestring; + {$ENDIF} + begin + len:=Length(s); + WriteDWord(len); + if len > 0 then + begin + {$IFDEF ENDIAN_BIG} + setlength(ws,len); + for i:=1 to len do + ws[i]:=widechar(SwapEndian(word(s[i]))); + Output.WriteBuffer(ws[1], len*sizeof(widechar)); + {$ELSE} + Output.WriteBuffer(s[1], len*sizeof(widechar)); + {$ENDIF} + end; + end; + + procedure WriteInteger(value: Int64); + begin + if (value >= -128) and (value <= 127) then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaInt8)); + {$ifdef FPC}Output.{$endif}WriteByte(byte(value)); + end else if (value >= -32768) and (value <= 32767) then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaInt16)); + WriteWord(word(value)); + {$ifdef FPC} + end else if (value >= -2147483648) and (value <= 2147483647) then begin + {$else} + end else if (value+2147483648>=0) and (value-2147483647<=0) then begin + {$endif} + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaInt32)); + WriteDWord(longword(value)); + end else begin + {$ifdef FPC}Output.{$endif}WriteByte(ord(vaInt64)); + WriteQWord(qword(value)); + end; + end; + + + procedure ProcessWideString(const left : unicodestring); + var ws : unicodestring; + begin + ws:=left+parser.TokenWideString; + while parser.NextToken = '+' do + begin + parser.NextToken; // Get next string fragment + if not (parser.Token in [toString,toWString]) then + parser.CheckToken(toWString); + ws:=ws+parser.TokenWideString; + end; + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaustring)); + WriteWString(ws); + end; + + procedure processstring; + var + s: string; + begin + s:= parser.TokenString; + while parser.NextToken = '+' do begin + parser.NextToken; // Get next string fragment + case parser.Token of + toString: begin + s:= s + parser.TokenString; + end; + toWString: begin + ProcessWideString(unicodestring(s)); + exit; + end + else begin + parser.CheckToken(toString); + end; + end; + end; + if (length(S)>255) then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaLString)); + WriteLString(S); + end + else begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaString)); + WriteString(s); + end; + end; + + procedure ProcessProperty; forward; + + procedure ProcessValue; + var +{$ifndef FPUNONE} + flt: Extended; +{$endif} +// s: String; + stream: TMemoryStream; + begin + case parser.Token of + toInteger: + begin + WriteInteger(parser.TokenInt); + parser.NextToken; + end; +{$ifndef FPUNONE} + toFloat: + begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaExtended)); + flt := Parser.TokenFloat; + WriteExtended(flt); + parser.NextToken; + end; + toemptyfloat: + begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaExtended)); + WriteExtended(emptyreal); + parser.NextToken; + end; +{$endif} + toString: + begin + processstring; + end; + toWString: + ProcessWideString(''); + toSymbol: begin + if CompareText(parser.TokenString, 'True') = 0 then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaTrue)); + end + else begin + if CompareText(parser.TokenString, 'False') = 0 then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaFalse)); + end + else begin + if CompareText(parser.TokenString, 'nil') = 0 then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaNil)); + end + else begin +// (* + if CompareText(parser.TokenString, 'null') = 0 then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaNull)); + end + else begin +// *) + if CompareText(parser.TokenString, 'NegInf') = 0 then begin + //preliminary, will be removed + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaExtended)); + Writeextended(emptyreal); + end + else begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaIdent)); + WriteString(parser.TokenComponentIdent); + end; +// { + end; +// } + end; + end; + end; + Parser.NextToken; + end; + // Set + '[': + begin + parser.NextToken; + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaSet)); + if parser.Token <> ']' then + while True do + begin + parser.CheckToken(toSymbol); + WriteString(parser.TokenString); + parser.NextToken; + if parser.Token = ']' then + break; + parser.CheckToken(','); + parser.NextToken; + end; + {$ifdef FPC}Output.{$endif}WriteByte(0); + parser.NextToken; + end; + // List + '(': + begin + parser.NextToken; + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaList)); + while parser.Token <> ')' do + ProcessValue; + {$ifdef FPC}Output.{$endif}WriteByte(0); + parser.NextToken; + end; + // Collection + '<': + begin + parser.NextToken; + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaCollection)); + while parser.Token <> '>' do + begin + parser.CheckTokenSymbol('item'); + parser.NextToken; + if parser.token = '[' then begin + parser.nexttoken; + if parser.token = tosymbol then begin //item name + {$ifdef fpc}output.{$endif}writebyte(ord(vaident)); + writestring(parser.tokencomponentident); + end; + parser.nexttoken; + parser.checktoken(']'); + parser.nexttoken; + end; + // ConvertOrder + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaList)); + while not parser.TokenSymbolIs('end') do + ProcessProperty; + parser.NextToken; // Skip 'end' + {$ifdef FPC}Output.{$endif}WriteByte(0); + end; + {$ifdef FPC}Output.{$endif}WriteByte(0); + parser.NextToken; + end; + // Binary data + '{': + begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaBinary)); + stream := TMemoryStream.Create; + try + parser.HexToBinary(stream); + WriteDWord(stream.Size); + Output.WriteBuffer(Stream.Memory^, stream.Size); + finally + stream.Free; + end; + parser.NextToken; + end; + else + parser.Error(SInvalidProperty); + end; + end; + + procedure ProcessProperty; + var + name: String; + begin + // Get name of property + parser.CheckToken(toSymbol); + name := parser.TokenString; + while True do begin + parser.NextToken; + if parser.Token <> '.' then break; + parser.NextToken; + parser.CheckToken(toSymbol); + name := name + '.' + parser.TokenString; + end; + WriteString(name); + parser.CheckToken('='); + parser.NextToken; + ProcessValue; + end; + + procedure ProcessObject; + var + Flags: Byte; + ObjectName, ObjectType: String; + ChildPos: Integer; + begin + childpos:= 0; + if parser.TokenSymbolIs('OBJECT') then + Flags :=0 { IsInherited := False } + else begin + if parser.TokenSymbolIs('INHERITED') then + Flags := 1 { IsInherited := True; } + else begin + parser.CheckTokenSymbol('INLINE'); + Flags := 4; + end; + end; + parser.NextToken; + parser.CheckToken(toSymbol); + ObjectName := ''; + ObjectType := parser.TokenString; + parser.NextToken; + if parser.Token = ':' then begin + parser.NextToken; + parser.CheckToken(toSymbol); + ObjectName := ObjectType; + ObjectType := parser.TokenString; + parser.NextToken; + if parser.Token = '[' then begin + parser.NextToken; + ChildPos := parser.TokenInt; + parser.NextToken; + parser.CheckToken(']'); + parser.NextToken; + Flags := Flags or 2; + end; + end; + if Flags <> 0 then begin + {$ifdef FPC}Output.{$endif}WriteByte($f0 or Flags); + if (Flags and 2) <> 0 then + WriteInteger(ChildPos); + end; + WriteString(ObjectType); + WriteString(ObjectName); + + // Convert property list + while not (parser.TokenSymbolIs('END') or + parser.TokenSymbolIs('OBJECT') or + parser.TokenSymbolIs('INHERITED') or + parser.TokenSymbolIs('INLINE')) do + ProcessProperty; + {$ifdef FPC}Output.{$endif}WriteByte(0); // Terminate property list + + // Convert child objects + while not parser.TokenSymbolIs('END') do ProcessObject; + parser.NextToken; // Skip end token + {$ifdef FPC}Output.{$endif}WriteByte(0); // Terminate property list + end; + +const + signature: PChar = 'TPF0'; +begin + parser := TParser.Create(Input); + try + Output.WriteBuffer(signature[0], 4); + ProcessObject; + finally + parser.Free; + end; +end; + +procedure objectbinarytotextmse(input, output: tstream); +begin + objectbinarytotext(input,output); +end; +(* +procedure objectbinarytotextmse(input, output: tstream); + //workaround for FPC bug with localized float strings +{$ifdef FPC} +var + ch1: char; +{$endif} +begin + {$ifdef FPC} + ch1:= defaultformatsettings.decimalseparator; + defaultformatsettings.decimalseparator:= '.'; + try + objectbinarytotext(input,output); + finally + defaultformatsettings.decimalseparator:= ch1; + end; + {$else} + objectbinarytotext(input,output); + {$endif} +end; +*) +procedure objecttexttobinarymse(input, output: tstream); +begin + objecttexttobinary(input,output); +end; + +{ tparser } + +function TParser.GetTokenName(aTok: char): string; +begin + if ord(aTok) <= LastSpecialToken then + Result:=TokNames[ord(aTok)] + else Result:=aTok; +end; + +procedure TParser.LoadBuffer; +var + BytesRead: integer; +begin + BytesRead := FStream.Read(FBuf^, ParseBufSize); + if BytesRead = 0 then + begin + FEofReached := True; + Exit; + end; + FBuf[BytesRead] := #0; + Inc(FDeltaPos, BytesRead); + FPos := 0; + FBufLen := BytesRead; +end; + +procedure TParser.CheckLoadBuffer; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + if fBuf[fPos]=#0 then LoadBuffer; +end; + +procedure TParser.ProcessChar; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + fLastTokenStr:=fLastTokenStr+fBuf[fPos]; + inc(fPos); + CheckLoadBuffer; +end; + +function TParser.IsNumber: boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + Result:=fBuf[fPos] in ['0'..'9']; +end; + +function TParser.IsHexNum: boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + Result:=fBuf[fPos] in ['0'..'9','A'..'F','a'..'f']; +end; + +function TParser.IsAlpha: boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + Result:=fBuf[fPos] in ['_','A'..'Z','a'..'z']; +end; + +function TParser.IsAlphaNum: boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + Result:=IsAlpha or IsNumber; +end; + +function TParser.GetHexValue(c: char): byte; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + result:= 0; + case c of + '0'..'9' : Result:=ord(c)-$30; + 'A'..'F' : Result:=ord(c)-$37; //-$41+$0A + 'a'..'f' : Result:=ord(c)-$57; //-$61+$0A + end; +end; + +function TParser.GetAlphaNum: string; +begin + if not IsAlpha then + ErrorFmt(SParExpected,[GetTokenName(toSymbol)]); + Result:=''; + while IsAlphaNum do + begin + Result:=Result+fBuf[fPos]; + inc(fPos); + CheckLoadBuffer; + end; +end; + +procedure TParser.HandleNewLine; +begin + if fBuf[fPos]=#13 then //CR + begin + inc(fPos); + CheckLoadBuffer; + if fBuf[fPos]=#10 then inc(fPos); //CR LF + end + else inc(fPos); //LF + inc(fSourceLine); + fDeltaPos:=-(fPos-1); +end; + +procedure TParser.SkipBOM; +var + i : integer; + bom : string[3]; + backup : integer; +begin + i:=1; + bom:=' '; + backup:=fPos; + while (fBuf[fPos] in [#$BB,#$BF,#$EF]) and (i<=3) do + begin + bom[i]:=fBuf[fPos]; + inc(fPos); + inc(i); + end; + if (bom<>(#$EF+#$BB+#$BF)) then + fPos:=backup; +end; + +procedure TParser.SkipSpaces; +begin + while fBuf[fPos] in [' ',#9] do + inc(fPos); +end; + +procedure TParser.SkipWhitespace; +begin + while true do + begin + CheckLoadBuffer; + case fBuf[fPos] of + ' ',#9 : SkipSpaces; + #10,#13 : HandleNewLine + else break; + end; + end; +end; + +procedure TParser.HandleEof; +begin + fToken:=toEOF; + fLastTokenStr:=''; +end; + +procedure TParser.HandleAlphaNum; +begin + fLastTokenStr:=GetAlphaNum; + fToken:=toSymbol; +end; + +procedure TParser.HandleNumber; +type + floatPunct = (fpDot,fpE); + floatPuncts = set of floatPunct; +var + allowed : floatPuncts; +begin + fLastTokenStr:=''; + while IsNumber do + ProcessChar; + fToken:=toInteger; + if (fBuf[fPos] in ['.','e','E']) then + begin + fToken:=toFloat; + allowed:=[fpDot,fpE]; + while (fBuf[fPos] in ['.','e','E','0'..'9']) do + begin + case fBuf[fPos] of + '.' : if fpDot in allowed then Exclude(allowed,fpDot) else break; + 'E','e' : if fpE in allowed then + begin + allowed:=[]; + ProcessChar; + if (fBuf[fPos] in ['+','-']) then ProcessChar; + if not (fBuf[fPos] in ['0'..'9']) then + ErrorFmt(SParInvalidFloat,[fLastTokenStr+fBuf[fPos]]); + end + else break; + end; + ProcessChar; + end; + end; + if (fBuf[fPos] in ['s','S','d','D','c','C']) then //single, date, currency + begin + fFloatType:=fBuf[fPos]; + inc(fPos); + fToken:=toFloat; + end + else fFloatType:=#0; +end; + +procedure TParser.HandleHexNumber; +var valid : boolean; +begin + fLastTokenStr:='$'; + inc(fPos); + CheckLoadBuffer; + valid:=false; + while IsHexNum do + begin + valid:=true; + ProcessChar; + end; + if not valid then + ErrorFmt(SParInvalidInteger,[fLastTokenStr]); + fToken:=toInteger; +end; + +function TParser.HandleQuotedString: string; +begin + Result:=''; + inc(fPos); + CheckLoadBuffer; + while true do + begin + case fBuf[fPos] of + #0 : ErrorStr(SParUnterminatedString); + #13,#10 : ErrorStr(SParUnterminatedString); + '''' : begin + inc(fPos); + CheckLoadBuffer; + if fBuf[fPos]<>'''' then exit; + end; + end; + Result:=Result+fBuf[fPos]; + inc(fPos); + CheckLoadBuffer; + end; +end; + +procedure TParser.HandleDecimalCharacter(var ascii: boolean; out + WideChr: widechar; out StringChr: char); +var i : integer; +begin + inc(fPos); + CheckLoadBuffer; + // read a word number + i:=0; + while IsNumber and (ihigh(word) then i:=0; + if i>127 then ascii:=false; + WideChr:=widechar(word(i)); + if i<256 then + StringChr:=chr(i) + else + StringChr:=#0; +end; + +procedure TParser.HandleString; +var ascii : boolean; + s: string; + w: WideChar; + c: char; +begin + fLastTokenWStr:=''; + fLastTokenStr:=''; + ascii:=true; + while true do + begin + case fBuf[fPos] of + '''' : + begin + // avoid conversions, + // On some systems conversion from ansistring to widestring and back + // to ansistring does not give the original ansistring. + // See bug http://bugs.freepascal.org/view.php?id=15841 + s:=HandleQuotedString; + fLastTokenWStr:=fLastTokenWStr+unicodestring(s); + fLastTokenStr:=fLastTokenStr+s; + end; + '#' : + begin + HandleDecimalCharacter(ascii,w,c); + fLastTokenWStr:=fLastTokenWStr+w; + fLastTokenStr:=fLastTokenStr+c; + end; + else break; + end; + end; + if ascii then + fToken:=Classes.toString + else + fToken:=toWString; +end; + +procedure TParser.HandleMinus; +var + str1: string; +begin + inc(fPos); + CheckLoadBuffer; + if IsNumber then begin + HandleNumber; + fLastTokenStr:='-'+fLastTokenStr; + end + else begin + if isalpha then begin + str1:= getalphanum; + ftoken:= toemptyfloat; + flasttokenstr:= '-'+str1; + if stringicompupper(str1,'INF') <> 0 then begin + ErrorFmt(SParInvalidFloat,[fLastTokenStr+fBuf[fPos]]); + end; + end + else begin + fToken:='-'; + fLastTokenStr:=fToken; + end; + end; +end; + +procedure TParser.HandleUnknown; +begin + fToken:=fBuf[fPos]; + fLastTokenStr:=fToken; + inc(fPos); +end; + +constructor TParser.Create(Stream: TStream); +begin + fStream:=Stream; + GetMem(fbuf,ParseBufSize+1); + fBufLen:=0; + fPos:=0; + fDeltaPos:=1; + fSourceLine:=1; + fEofReached:=false; + fLastTokenStr:=''; + fLastTokenWStr:=''; + fFloatType:=#0; + fToken:=#0; + LoadBuffer; + SkipBom; + NextToken; +end; + +destructor TParser.Destroy; +begin + fStream.Position:=SourcePos; + FreeMem(fBuf); +end; + +procedure TParser.CheckToken(T: Char); +begin + if fToken<>T then + ErrorFmt(SParWrongTokenType,[GetTokenName(T),GetTokenName(fToken)]); +end; + +procedure TParser.CheckTokenSymbol(const S: string); +begin + CheckToken(toSymbol); + if CompareText(fLastTokenStr,S)<>0 then + ErrorFmt(SParWrongTokenSymbol,[s,fLastTokenStr]); +end; + +procedure TParser.Error(const Ident: string); +begin + ErrorStr(Ident); +end; + +procedure TParser.ErrorFmt(const Ident: string; const Args: array of const); +begin + ErrorStr(Format(Ident,Args)); +end; + +procedure TParser.ErrorStr(const Message: string); +begin + raise EParserError.CreateFmt(Message+SParLocInfo,[SourceLine,fPos+fDeltaPos,SourcePos]); +end; + +procedure TParser.HexToBinary(Stream: TStream); +var outbuf : array[0..ParseBufSize-1] of byte; + b : byte; + i : integer; +begin + i:=0; + SkipWhitespace; + while IsHexNum do + begin + b:=(GetHexValue(fBuf[fPos]) shl 4); + inc(fPos); + CheckLoadBuffer; + if not IsHexNum then + Error(SParUnterminatedBinValue); + b:=b or GetHexValue(fBuf[fPos]); + inc(fPos); + outbuf[i]:=b; + inc(i); + if i>=ParseBufSize then + begin + Stream.WriteBuffer(outbuf[0],i); + i:=0; + end; + SkipWhitespace; + end; + if i>0 then + Stream.WriteBuffer(outbuf[0],i); + NextToken; +end; + +function TParser.NextToken: Char; + +begin + SkipWhiteSpace; + if fEofReached then + HandleEof + else + case fBuf[fPos] of + '_','A'..'Z','a'..'z' : HandleAlphaNum; + '$' : HandleHexNumber; + '-' : HandleMinus; + '0'..'9' : HandleNumber; + '''','#' : HandleString + else + HandleUnknown; + end; + Result:=fToken; +end; + +function TParser.SourcePos: Longint; +begin + Result:=fStream.Position-fBufLen+fPos; +end; + +function TParser.TokenComponentIdent: string; +begin + if fToken<>toSymbol then + ErrorFmt(SParExpected,[GetTokenName(toSymbol)]); + CheckLoadBuffer; + while fBuf[fPos]='.' do + begin + ProcessChar; + fLastTokenStr:=fLastTokenStr+GetAlphaNum; + end; + Result:=fLastTokenStr; +end; + +{$ifndef FPUNONE} +Function TParser.TokenFloat: Extended; + +var +{$ifdef FPC} + errcode : word; +{$else} + errcode: integer; +{$endif} + +begin + Val(fLastTokenStr,Result,errcode); + if errcode<>0 then + ErrorFmt(SParInvalidFloat,[fLastTokenStr]); +end; +{$endif} + +Function TParser.TokenInt: Int64; +begin + if not TryStrToInt64(fLastTokenStr,Result) then begin + {$ifdef FPC} + if not tryStrToQWord(fLastTokenStr,qword(result)) then begin + //second chance for malformed files + ErrorFmt(SParInvalidInteger,[fLastTokenStr]); + end; + {$else} + ErrorFmt(SParInvalidInteger,[fLastTokenStr]); + {$endif} + end; +end; + +function TParser.TokenString: string; +begin + case fToken of + toWString : Result:= ansistring(fLastTokenWStr); + toFloat : if fFloatType<>#0 then + Result:=fLastTokenStr+fFloatType + else Result:=fLastTokenStr + else + Result:=fLastTokenStr; + end; +end; + +function TParser.TokenWideString: unicodestring; +begin + if fToken=toWString then + Result:=fLastTokenWStr + else + Result:= unicodestring(fLastTokenStr); +end; + +function TParser.TokenSymbolIs(const S: string): Boolean; +begin + Result:=(fToken=toSymbol) and (CompareText(fLastTokenStr,S)=0); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msepipestream.pas b/mseide-msegui/lib/common/kernel/msepipestream.pas new file mode 100644 index 0000000..7c47711 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msepipestream.pas @@ -0,0 +1,953 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepipestream; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msestream,msethread,msesystypes,classes,mclasses,msebits,mseclasses, + msetypes; + +type + + pr_piperesultty = (pr_empty,pr_data,pr_line); + + tpipewriter = class(ttextstream) + private + fconnected: boolean; + function gethandle: integer; + protected + procedure sethandle(value: integer); override; + function dowrite(const buffer; count: longint): longint; virtual; + public + constructor create; reintroduce; +// destructor destroy; override; +{$ifdef FPC} + function Write(const Buffer; Count: Longint): Longint; override; overload; +{$endif} + procedure connect(const ahandle: integer); //does not own handle +// function releasehandle: filehandlety; virtual; + property handle: integer read gethandle write sethandle; //owns handle + end; + + tpipereader = class; + + pipereadereventty = procedure(const sender: tpipereader) of object; + + //todo: no thread.kill, single thread for all pipreaders + bufferty = array[0..defaultbuflen-1] of char; + + pipereaderoptionty = (pro_nolock); + pipereaderoptionsty = set of pipereaderoptionty; + + tpipereader = class(tpipewriter) + private + fpipebuffer: string; + fdatastatus: pr_piperesultty; + foninputavailable: pipereadereventty; + fonpipebroken: pipereadereventty; + finputcond: condty; + fwritehandle: integer; + foverloadsleepus: integer; + foptions: pipereaderoptionsty; + function checkdata: pr_piperesultty; + procedure clearpipebuffer; + function getresponseflag: boolean; + procedure setresponseflag(const Value: boolean); + procedure setwritehandle(const Value: integer); + protected + fthread: tsemthread; //simulate nonblocking pipes on windows + fmsbuf: bufferty; + fmsbufcount: integer; + fowner: tmsecomponent; + function execthread(thread: tmsethread): integer; virtual; + procedure sethandle(value: integer); override; + procedure setbuflen(const Value: integer); override; + function doread(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean = false): boolean; virtual; + //true of no error + function readbytes(var buf): integer; override; + procedure doinputavailable; + procedure dochange; virtual; + function readbuf: string; + public + constructor create; + destructor destroy; override; + + function releasehandle: filehandlety override; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + //no seek, result always 0 + function readdatastring: string; override; + procedure appenddatastring(var adata: string; var acount: sizeint); + + function readbuffer: string; //does not try to get additional data + function readuln(var value: string): boolean; + function readuln(var value: string; out hasmoredata: boolean): boolean; + //bringt auch unvollstaendige zeilen, false wenn unvollstaendig + //no decoding + function readstrln(var value: string): boolean; override; + //bringt nur vollstaendige zeilen, sonst false + //no decoding + procedure clear; override; + procedure terminate(const noclosehandle: boolean = false); + procedure terminateandwait(const noclosehandle: boolean = false); + procedure waitfor; + function waitforresponse(timeoutusec: integer = 0; + resetflag: boolean = true): boolean; + //false if timeout or error + function active: boolean; //true if handle set and not eof or error + property responseflag: boolean read getresponseflag write setresponseflag; + property text: string read fpipebuffer; + property writehandle: integer read fwritehandle write setwritehandle; + property overloadsleepus: integer read foverloadsleepus + write foverloadsleepus default -1; + //checks application.checkoverload before calling oninputavaliable + //if >= 0 + property options: pipereaderoptionsty read foptions + write foptions default []; + property oninputavailable: pipereadereventty read foninputavailable + write foninputavailable; + property onpipebroken: pipereadereventty read fonpipebroken + write fonpipebroken; + property owner: tmsecomponent read fowner; +end; + + tpipereadercomp = class(tmsecomponent) + private + fpipereader: tpipereader; + function getoninputavailable: pipereadereventty; + function getonpipebroken: pipereadereventty; + procedure setoninputavailable(const Value: pipereadereventty); + procedure setonpipebroken(const Value: pipereadereventty); + function getoverloadsleepus: integer; + procedure setoverloadsleepus(const avalue: integer); + function getopions: pipereaderoptionsty; + procedure setoptions(const avalue: pipereaderoptionsty); + function getencoding: charencodingty; + procedure setencoding(const avalue: charencodingty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property pipereader: tpipereader read fpipereader; + published + property options: pipereaderoptionsty read getopions + write setoptions default []; + property encoding: charencodingty read getencoding write setencoding + default ce_locale; + property overloadsleepus: integer read getoverloadsleepus + write setoverloadsleepus default -1; + //checks application.checkoverload before calling oninputavaliable + //if >= 0 + property oninputavailable: pipereadereventty read getoninputavailable write setoninputavailable; + property onpipebroken: pipereadereventty read getonpipebroken write setonpipebroken; + end; + + tpipereaderpers = class(tpersistent) + private + fpipereader: tpipereader; + function getoninputavailable: pipereadereventty; + function getonpipebroken: pipereadereventty; + procedure setoninputavailable(const Value: pipereadereventty); + procedure setonpipebroken(const Value: pipereadereventty); + function getoverloadsleepus: integer; + procedure setoverloadsleepus(const avalue: integer); + function getopions: pipereaderoptionsty; + procedure setoptions(const avalue: pipereaderoptionsty); + function getencoding: charencodingty; + procedure setencoding(const avalue: charencodingty); + public + constructor create(const aowner: tmsecomponent); + destructor destroy; override; + property pipereader: tpipereader read fpipereader; + published + property options: pipereaderoptionsty read getopions + write setoptions default []; + property encoding: charencodingty read getencoding write setencoding + default ce_locale; + property overloadsleepus: integer read getoverloadsleepus + write setoverloadsleepus default -1; + //checks application.checkoverload before calling oninputavaliable + //if >= 0 + property oninputavailable: pipereadereventty read getoninputavailable write setoninputavailable; + property onpipebroken: pipereadereventty read getonpipebroken write setonpipebroken; + end; + + tpipewriterpers = class(tpersistent) + private + fpipewriter: tpipewriter; + function getencoding: charencodingty; + procedure setencoding(const avalue: charencodingty); + public + constructor create(const aowner: tmsecomponent); + destructor destroy; override; + property pipewriter: tpipewriter read fpipewriter; + published + property encoding: charencodingty read getencoding write setencoding + default ce_locale; + end; + +{$ifdef UNIX} +function readfilenonblock(const handle: thandle; var buf; const acount: integer; + const nonblocked: boolean): integer; //-1 on error +{$endif} + +implementation +uses + {$ifdef UNIX}mselibc, {$else}windows, {$endif} + mseapplication,msesysintf1,msesysintf,sysutils,msesysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tpipewriter } + +constructor tpipewriter.create; +begin + inherited create(invalidfilehandle); +end; +{ +destructor tpipewriter.destroy; +begin + sethandle(invalidfilehandle); + inherited; +end; +} +{ +function tpipewriter.releasehandle: filehandlety; +begin + result:= handle; + fhandle:= invalidfilehandle; +end; +} +procedure tpipewriter.connect(const ahandle: integer); +begin + handle:= ahandle; + if ahandle <> invalidfilehandle then begin + fconnected:= true; + end; +end; + +procedure tpipewriter.sethandle(value: integer); +begin + if fconnected then begin + fhandle:= invalidfilehandle; + fconnected:= false; + end; + inherited; + bufoffset:= nil; +end; + +function tpipewriter.dowrite(const buffer; count: longint): longint; +begin + result:= inherited write(buffer,count); +end; + +function tpipewriter.gethandle: integer; +begin + result:= inherited handle; +end; + +{$ifdef FPC} +function tpipewriter.Write(const Buffer; Count: Longint): Longint; +begin + result:= dowrite(buffer,count); +end; +{$endif} + +{ tpipereader } + +constructor tpipereader.create; +begin + sys_condcreate(finputcond); + fwritehandle:= invalidfilehandle; + foverloadsleepus:= -1; + inherited; + include(fstate,tss_notopen); +end; + +destructor tpipereader.destroy; +begin + terminateandwait; + writehandle:= invalidfilehandle; + inherited; + sys_conddestroy(finputcond); +end; + +function tpipereader.releasehandle: filehandlety; +begin + terminateandwait(true); + freeandnil(fthread); + writehandle:= invalidfilehandle; + result:= inherited releasehandle(); +end; + +procedure tpipereader.sethandle(value: integer); +begin + if handle <> invalidfilehandle then begin + terminateandwait; + end; + freeandnil(fthread); + inherited; + if value <> invalidfilehandle then begin + writehandle:= invalidfilehandle; + fstate:= fstate - [tss_notopen,tss_eof,tss_error,tss_pipeactive]; + fmsbufcount:= 0; + fthread:= tsemthread.create({$ifdef FPC}@{$endif}execthread); + end; +end; + +procedure tpipereader.setwritehandle(const Value: integer); +begin + if fwritehandle <> invalidfilehandle then begin + sys_closefile(fwritehandle); + end; + fwritehandle := Value; +end; + +procedure tpipereader.terminate(const noclosehandle: boolean = false); +var + by1: byte; +begin + if fthread <> nil then begin + fthread.terminate; + if fthread.running then begin + fthread.sempost; + if fwritehandle <> invalidfilehandle then begin + by1:= 0; + sys_write(fwritehandle,@by1,1); //wake up thread + end + else begin +// inherited sethandle(invalidfilehandle); + {$ifdef unix} + pthread_kill(fthread.id,sigio); + {$endif} + end; + writehandle:= invalidfilehandle; + end; + end; + if not noclosehandle then begin + inherited sethandle(invalidfilehandle); + end; + include(fstate,tss_notopen); +end; + +procedure tpipereader.terminateandwait(const noclosehandle: boolean = false); +begin + if fthread <> nil then begin + terminate(noclosehandle); + application.waitforthread(fthread); + end; +end; + +procedure tpipereader.waitfor; +begin + if fthread <> nil then begin + application.waitforthread(fthread); + end; +end; + +procedure tpipereader.setbuflen(const Value: integer); +begin + if value < defaultbuflen then begin + inherited setbuflen(defaultbuflen); + end + else begin + inherited; + end; +end; + +{$ifdef UNIX} +function readfilenonblock(const handle: thandle; var buf; const acount: integer; + const nonblocked: boolean): integer; //-1 on error +begin + if nonblocked then begin + setfilenonblock(handle,true); + end; + result:= sys_read(handle,@buf,acount); + if nonblocked then begin + if (result < 0) and (sys_getlasterror = EAGAIN) then begin + result:= 0; + end; + setfilenonblock(handle,false); + end; +end; +{$endif} + +function tpipereader.doread(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean = false): boolean; +begin +{$ifdef mswindows} + readcount:= sys_read(Handle,@buf,acount); + if readcount < 0 then begin + result:= false; + end; +// result:= fileRead(Handle,buf,acount) +{$else} + readcount:= readfilenonblock(handle,buf,acount, + nonblocked and not (tss_unblocked in fstate)); +{$endif} + result:= readcount >= 0; + if not result then begin + readcount:= 0; + end; +end; + +function tpipereader.execthread(thread: tmsethread): integer; +var + int1: integer; + {$ifdef unix} + info: pollfd; + {$endif} +begin + fthread:= tsemthread(thread); + {$ifdef unix} + info.fd:= handle; + info.events:= pollin; + {$endif} + with fthread do begin + while not terminated and not (tss_error in fstate) do begin + {$ifdef unix} + if (poll(@info,1,-1) > 0) and not terminated then begin + {$else} + if true then begin + {$endif} + int1:= sys_read(Handle,@fmsBuf,sizeof(fmsbuf)); + if not terminated then begin + if {$ifdef mswindows}int1 < 0{$else}(int1 <= 0){$endif} then begin + //on win32 int1 can be 0 + include(fstate,tss_error); //broken pipe + end + else begin + fmsbufcount:= int1; + end; + if (int1 > 0) or (tss_error in fstate) then begin + include(fstate,tss_pipeactive); + doinputavailable; + if not terminated and not (tss_error in fstate) then begin + semwait; + end; + end; + end; + end; + end; + include(fstate,tss_eof); + end; + result:= 0; +end; + +function tpipereader.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin + inherited seek(offset,origin); + result:= 0; +end; + +procedure tpipereader.doinputavailable; +var + needslock: boolean; +begin + if (tss_haslink in fstate) or + assigned(foninputavailable) or assigned(fonpipebroken) then begin + if foverloadsleepus >= 0 then begin + while not fthread.terminated and application.checkoverload(-1) do begin + sleepus(foverloadsleepus); + end; + end; + needslock:= not (pro_nolock in foptions) and not fthread.terminated; + if needslock then begin + application.lock; + end; + try + if not fthread.terminated then begin + if assigned(foninputavailable) then begin + foninputavailable(self); + end; + if eof and assigned(fonpipebroken) then begin + fonpipebroken(self); + end; + dochange; + end; + finally + if needslock then begin + application.unlock; + end; + end; + end; + sys_condlock(finputcond); + include(fstate,tss_response); + sys_condbroadcast(finputcond); + sys_condunlock(finputcond); +end; + +procedure tpipereader.clearpipebuffer; +begin + fpipebuffer:= ''; + fdatastatus:= pr_empty; +end; + +function tpipereader.readbytes(var buf): integer; + + procedure getmorebytes; +{$ifdef mswindows} + var + int1: integer; +{$endif} + begin + {$ifdef mswindows} + if peeknamedpipe(handle,nil,0,nil,@int1,nil) and (int1 > 0) then begin + if int1 > sizeof(fmsbuf) then begin + int1:= sizeof(fmsbuf); + end; + if not doread(fmsbuf,int1,fmsbufcount) then begin + fstate:= fstate + [tss_error,tss_eof]; + end; + end + else begin + fmsbufcount:= 0; + end; + {$else} + if not doread(fmsbuf,sizeof(fmsbuf),fmsbufcount,true) then begin + fstate:= fstate + [tss_error,tss_eof]; //broken pipe + end; + {$endif} + if fmsbufcount = 0 then begin + exclude(fstate,tss_pipeactive); + fthread.sempost; + end + else begin + include(fstate,tss_pipeactive); + end; + end; + +begin + result:= fmsbufcount; + if result > 0 then begin + move(fmsbuf,buf,fmsbufcount); + getmorebytes; + end + else begin + if sys_getcurrentthread = fthread.id then begin //check again fore more + include(fstate,tss_pipeactive); + if fthread.semcount > 0 then begin + fthread.semwait; //reset semaphore + end; + getmorebytes; + result:= fmsbufcount; + if result > 0 then begin + move(fmsbuf,buf,fmsbufcount); + getmorebytes; + end; + end; + if tss_error in fstate then begin + include(fstate,tss_eof); + end; + end; +end; + +function tpipereader.readbuf: string; +var + int1: integer; +begin + if bufoffset <> nil then begin + int1:= bufend-bufoffset; + setlength(result,int1); + move(bufoffset^,result[1],int1); + bufoffset:= nil; + end + else begin + result:= ''; + end; +end; + +function tpipereader.readbuffer: string; +var + int1: integer; +begin + result:= readbuf; + if fmsbufcount > 0 then begin + int1:= length(result); + setlength(result,int1+fmsbufcount); + move(fmsbuf,result[int1+1],fmsbufcount); + fmsbufcount:= 0; + exclude(fstate,tss_pipeactive); + fthread.sempost; + end; +end; + +function tpipereader.readdatastring: string; +var + int1: integer; + len1: sizeint; +begin + result:= readbuffer; + len1:= length(result); + while true do begin + int1:= readbytes(fbuffer^); + if int1 > 0 then begin + len1:= len1+int1; + if len1 > length(result) then begin + setlength(result,2*len1); + end; + move(fbuffer^,result[len1-int1+1],int1); + end + else begin + break; + end; + end; + setlength(result,len1); +end; + +procedure tpipereader.appenddatastring(var adata: string; var acount: sizeint); +var + len1: sizeint; + i1: int32; +begin + i1:= 0; + if bufoffset <> nil then begin + i1:= bufend - bufoffset; + end; + len1:= acount + i1 + fmsbufcount; + if len1 > length(adata) then begin + setlength(adata,2*len1); + end; + if bufoffset <> nil then begin + move(bufoffset^,(pointer(adata)+acount)^,i1); + bufoffset:= nil; + end; + move(fmsbuf,(pointer(adata)+acount+i1)^,fmsbufcount); + fmsbufcount:= 0; + + repeat + {$ifdef mswindows} + if peeknamedpipe(handle,nil,0,nil,@i1,nil) and (i1 > 0) then begin + if len1+i1 > length(adata) then begin + setlength(adata,2*(len1+i1)); + end; + if not doread((pointer(adata)+len1)^,i1,i1) then begin + fstate:= fstate + [tss_error,tss_eof]; + end; + end + else begin + break; + end; + {$else} + if len1 >= length(adata) then begin + setlength(adata,2*len1+64); + end; + i1:= length(adata) - len1; //fill current buffer + if not doread((pointer(adata)+len1)^,i1,i1,true) then begin + fstate:= fstate + [tss_error,tss_eof]; //broken pipe + end; + if i1 = 0 then begin + break; + end; + {$endif} + len1:= len1 + i1; + until fstate * [tss_error,tss_eof] <> []; + acount:= len1; + exclude(fstate,tss_pipeactive); + fthread.sempost; +end; + +function tpipereader.checkdata: pr_piperesultty; +var + str1: string; + bo1: boolean; +begin + if not (tss_error in fstate) and + ((bufend <> bufoffset) or (tss_pipeactive in fstate) or + (sys_getcurrentthread = fthread.id)) then begin + bo1:= inherited readstrln(str1); + fpipebuffer:= fpipebuffer + str1; + if bo1 then begin + fdatastatus:= pr_line; + end + else begin + if str1 <> '' then begin + fdatastatus:= pr_data; + end; + if not (tss_error in fstate) then begin + exclude(fstate,tss_eof); + end; + bufoffset:= nil; //neu laden + end; + result:= fdatastatus; + end + else begin + result:= pr_empty; + end; +end; + +function tpipereader.readuln(var value: string; + out hasmoredata: boolean): boolean; +begin + value:= ''; + result:= false; +// if (tss_pipeactive in fstate) or (fdatastatus <> pr_empty) then begin + repeat + if fdatastatus = pr_empty then begin + checkdata; + end; + value:= value + fpipebuffer; + result:= fdatastatus = pr_line; + clearpipebuffer; + checkdata; + until result or (fdatastatus = pr_empty); +// end; + hasmoredata:= fdatastatus <> pr_empty; +end; + +function tpipereader.readuln(var value: string): boolean; +var + b1: boolean; +begin + result:= readuln(value,b1); +end; + +function tpipereader.readstrln(var value: string): boolean; +begin + case checkdata of + pr_line: begin + result:= true; + value:= fpipebuffer; + clearpipebuffer; + end; + else begin + result:= false; + value:= ''; + end; + end; +end; + +procedure tpipereader.clear; +begin + clearpipebuffer; + bufoffset:= nil; +end; + +function tpipereader.waitforresponse(timeoutusec: integer = 0; + resetflag: boolean = true): boolean; + //false if timeout or error +begin + sys_condlock(finputcond); + result:= responseflag; + if not result then begin + if not eof then begin + result:= sys_condwait(finputcond,timeoutusec) = sye_ok; + end; + end; + if result and resetflag then begin + responseflag:= false; + end; + sys_condunlock(finputcond); +end; + +function tpipereader.getresponseflag: boolean; +begin + result:= tss_response in fstate; +end; + +procedure tpipereader.setresponseflag(const Value: boolean); +begin + updatebit({$ifdef FPC}longword{$else}byte{$endif}(fstate),ord(tss_response),value); +end; + +function tpipereader.active: boolean; +begin + result:= (handle <> invalidfilehandle) and (fstate * [tss_error,tss_eof] = []); +end; + +procedure tpipereader.dochange; +begin + //dummy +end; + +{ tpipereadercomp } + +constructor tpipereadercomp.create(aowner: tcomponent); +begin + fpipereader:= tpipereader.create; + fpipereader.fowner:= self; + inherited; +end; + +destructor tpipereadercomp.destroy; +begin + fpipereader.free; + inherited; +end; + +function tpipereadercomp.getoninputavailable: pipereadereventty; +begin + result:= fpipereader.foninputavailable; +end; + +function tpipereadercomp.getonpipebroken: pipereadereventty; +begin + result:= fpipereader.fonpipebroken; +end; + +procedure tpipereadercomp.setoninputavailable( + const Value: pipereadereventty); +begin + fpipereader.foninputavailable:= value; +end; + +procedure tpipereadercomp.setonpipebroken(const Value: pipereadereventty); +begin + fpipereader.fonpipebroken:= value; +end; + +function tpipereadercomp.getoverloadsleepus: integer; +begin + result:= fpipereader.overloadsleepus; +end; + +procedure tpipereadercomp.setoverloadsleepus(const avalue: integer); +begin + fpipereader.overloadsleepus:= avalue; +end; + +function tpipereadercomp.getopions: pipereaderoptionsty; +begin + result:= fpipereader.options; +end; + +procedure tpipereadercomp.setoptions(const avalue: pipereaderoptionsty); +begin + fpipereader.options:= avalue; +end; + +function tpipereadercomp.getencoding: charencodingty; +begin + result:= fpipereader.encoding; +end; + +procedure tpipereadercomp.setencoding(const avalue: charencodingty); +begin + fpipereader.encoding:= avalue; +end; + +{ tpipereaderpers } + +constructor tpipereaderpers.create(const aowner: tmsecomponent); +begin + fpipereader:= tpipereader.create; + fpipereader.fowner:= aowner; + inherited create; +end; + +destructor tpipereaderpers.destroy; +begin + fpipereader.free; + inherited; +end; + +function tpipereaderpers.getoninputavailable: pipereadereventty; +begin + result:= fpipereader.foninputavailable; +end; + +function tpipereaderpers.getonpipebroken: pipereadereventty; +begin + result:= fpipereader.fonpipebroken; +end; + +procedure tpipereaderpers.setoninputavailable( + const Value: pipereadereventty); +begin + fpipereader.foninputavailable:= value; +end; + +procedure tpipereaderpers.setonpipebroken(const Value: pipereadereventty); +begin + fpipereader.fonpipebroken:= value; +end; + +function tpipereaderpers.getoverloadsleepus: integer; +begin + result:= fpipereader.overloadsleepus; +end; + +procedure tpipereaderpers.setoverloadsleepus(const avalue: integer); +begin + fpipereader.overloadsleepus:= avalue; +end; + +function tpipereaderpers.getopions: pipereaderoptionsty; +begin + result:= fpipereader.options; +end; + +procedure tpipereaderpers.setoptions(const avalue: pipereaderoptionsty); +begin + fpipereader.options:= avalue; +end; + +function tpipereaderpers.getencoding: charencodingty; +begin + result:= fpipereader.encoding; +end; + +procedure tpipereaderpers.setencoding(const avalue: charencodingty); +begin + fpipereader.encoding:= avalue; +end; + +{ tpipewriterpers } + +constructor tpipewriterpers.create(const aowner: tmsecomponent); +begin + fpipewriter:= tpipewriter.create; + inherited create; +end; + +destructor tpipewriterpers.destroy; +begin + fpipewriter.free; + inherited; +end; + +function tpipewriterpers.getencoding: charencodingty; +begin + result:= fpipewriter.encoding; +end; + +procedure tpipewriterpers.setencoding(const avalue: charencodingty); +begin + fpipewriter.encoding:= avalue; +end; + +{$ifdef UNIX} +var + sigpipebefore: tsignalhandler; +initialization + sigpipebefore:= signal(sigpipe,tsignalhandler(sig_ign)); +finalization + signal(sigpipe,sigpipebefore); +{$endif} + +end. + diff --git a/mseide-msegui/lib/common/kernel/msepointer.pas b/mseide-msegui/lib/common/kernel/msepointer.pas new file mode 100644 index 0000000..4249dd9 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msepointer.pas @@ -0,0 +1,585 @@ +{ MSEgui Copyright (c) 1999-2009 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepointer; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msegraphics,msegraphutils,msetimer,msetypes,mseglob; + +const + defaultcaretblinkperiodetime = 1000000; //us + defaultsizingmargin = 3; +type + + cursorshapety = (cr_default,cr_parent, + cr_none,cr_arrow,cr_cross,cr_wait,cr_ibeam, + cr_sizever,cr_sizehor,cr_sizebdiag,cr_sizefdiag,cr_sizeall, + cr_splitv,cr_splith,cr_pointinghand,cr_forbidden,cr_drag, + cr_topleftcorner,cr_bottomleftcorner, + cr_bottomrightcorner,cr_toprightcorner, + cr_res0,cr_res1,cr_res2,cr_res3,cr_res4,cr_res5,cr_res6,cr_res7, + cr_user); + + sizingkindty = (sik_none,sik_right,sik_topright,sik_top,sik_topleft, + sik_left,sik_bottomleft,sik_bottom,sik_bottomright); +const + sizingcursors: array[sizingkindty] of cursorshapety = + (cr_default,cr_sizehor,cr_toprightcorner,cr_sizever,cr_topleftcorner, + cr_sizehor,cr_bottomleftcorner,cr_sizever,cr_bottomrightcorner); +type + imouse = interface(inullinterface) + function getmousewinid: winidty; + end; + + tmouse = class + private + fshape: cursorshapety; + fwinid: winidty; + fintf: imouse; + procedure setshape(const Value: cursorshapety); + function getpos: pointty; + procedure setpos(const Value: pointty); + public + constructor create(mouseintf: imouse); + procedure move(const dist: pointty); + procedure windowdestroyed(const id: winidty); + property shape: cursorshapety read fshape write setshape; + property pos: pointty read getpos write setpos; + end; + + caretstatety = (cas_active,cas_on,cas_showed); + caretstatesty = set of caretstatety; + + tcaret = class(tnullinterfacedobject{,icaret}) + private + fcanvas: tcanvas; + fcliprect: rectty; + fbounds: rectty; + forigin: pointty; + fstate: caretstatesty; + ftimer: tsimpletimer; + fbackup: tsimplebitmap; + fcaret: tsimplebitmap; + fvisible: integer; + function getheight: integer; + procedure setheight(const Value: integer); + function getpos: pointty; + procedure setpos(const Value: pointty); + function getsize: sizety; + procedure setsize(const Value: sizety); + function getwidth: integer; + procedure setwidth(const Value: integer); + function getx: integer; + procedure setx(const Value: integer); + function gety: integer; + procedure sety(const Value: integer); + function getbounds: rectty; + procedure setbounds(const value: rectty); + function getperiodetime: integer; + procedure setperiodetime(const Value: integer); + procedure updatestate; + procedure restart; + procedure timerevent(const sender: tobject); + function getcliprect: rectty; + procedure setcliprect(const Value: rectty); //no restart of timer + protected + procedure scroll(const dist: pointty; const scrollorigin: boolean); + public + constructor create{(out intf: pointer)}; + destructor destroy; override; + procedure link(canvas: tcanvas; const origin: pointty; + const acliprect: rectty); + function islinkedto(canvas: tcanvas): boolean; + + procedure remove; //recursive + procedure restore; //recursive + procedure hide; //stops timer + procedure show; //restarts timer + procedure move(const dist: pointty); + function active: boolean; + function visible: boolean; + + property origin: pointty read forigin; + property bounds: rectty read getbounds write setbounds; + property cliprect: rectty read getcliprect write setcliprect; + property rootcliprect: rectty read fcliprect; + property x: integer read getx write setx; + property y: integer read gety write sety; + property pos: pointty read getpos write setpos; + property width: integer read getwidth write setwidth; + property height: integer read getheight write setheight; + property size: sizety read getsize write setsize; + property periodetime: integer read getperiodetime write setperiodetime; + end; + +function calcsizingkind(const apos: pointty; const arect: rectty; + const margin: integer = defaultsizingmargin): sizingkindty; +function adjustsizingrect(const arect: rectty; const kind: sizingkindty; + const offset: pointty; const cxmin,cxmax,cymin,cymax: integer): rectty; + +implementation +uses + mseguiintf,msebitmap; + +function calcsizingkind(const apos: pointty; const arect: rectty; + const margin: integer = defaultsizingmargin): sizingkindty; +var + margin2,distright,disttop,distleft,distbottom: integer; +begin + result:= sik_none; + distright:= abs(apos.x - (arect.x+arect.cx)); + disttop:= abs(apos.y - (arect.y)); + distleft:= abs(apos.x - (arect.x)); + distbottom:= abs(apos.y - (arect.y+arect.cy)); + margin2:= 2 * margin; + if disttop < margin then begin + if distleft < margin2 then begin + result:= sik_topleft; + end + else begin + if distright < margin2 then begin + result:= sik_topright; + end + else begin + result:= sik_top; + end; + end; + end + else begin + if distbottom < margin then begin + if distleft < margin2 then begin + result:= sik_bottomleft; + end + else begin + if distright < margin2 then begin + result:= sik_bottomright; + end + else begin + result:= sik_bottom; + end; + end; + end + else begin + if distleft < margin then begin + if disttop < margin2 then begin + result:= sik_topleft; + end + else begin + if distbottom < margin2 then begin + result:= sik_bottomleft; + end + else begin + result:= sik_left; + end; + end + end + else begin + if distright < margin then begin + if disttop < margin2 then begin + result:= sik_topright; + end + else begin + if distbottom < margin2 then begin + result:= sik_bottomright; + end + else begin + result:= sik_right; + end; + end; + end; + end; + end; + end; +end; + +function adjustsizingrect(const arect: rectty; const kind: sizingkindty; + const offset: pointty; const cxmin,cxmax,cymin,cymax: integer): rectty; + procedure adjustright; + begin + result.cx:= result.cx + offset.x; + if (cxmax > 0) and (result.cx > cxmax) then begin + result.cx:= cxmax; + end; + if result.cx < cxmin then begin + result.cx:= cxmin; + end; + end; + procedure adjusttop; + var + int1: integer; + begin + int1:= offset.y; + if (cymax <> 0) and (result.cy - int1 > cymax) then begin + int1:= result.cy - cymax; + end; + if result.cy - int1 < cymin then begin + int1:= result.cy - cymin; + end; + result.y:= result.y + int1; + result.cy:= result.cy - int1; + end; + procedure adjustleft; + var + int1: integer; + begin + int1:= offset.x; + if (cxmax <> 0) and (result.cx - int1 > cxmax) then begin + int1:= result.cx - cxmax; + end; + if result.cx - int1 < cxmin then begin + int1:= result.cx - cxmin; + end; + result.x:= result.x + int1; + result.cx:= result.cx - int1; + end; + procedure adjustbottom; + begin + result.cy:= result.cy + offset.y; + if (cymax > 0) and (result.cy > cymax) then begin + result.cy:= cymax; + end; + if result.cy < cymin then begin + result.cy:= cymin; + end; + end; +begin + result:= arect; + case kind of + sik_right: adjustright; + sik_topright: begin adjusttop; adjustright end; + sik_top: adjusttop; + sik_topleft: begin adjusttop; adjustleft end; + sik_left: adjustleft; + sik_bottomleft: begin adjustbottom; adjustleft end; + sik_bottom: adjustbottom; + sik_bottomright: begin adjustbottom; adjustright end; + end; +end; + +{ tmouse } + +constructor tmouse.create(mouseintf: imouse); +begin + fintf:= mouseintf; +// fwinid:= winidty(-1); +end; + +function tmouse.getpos: pointty; +begin + result:= gui_getpointerpos; +end; + +procedure tmouse.setpos(const Value: pointty); +begin + if not pointisequal(value,getpos) then begin + gui_setpointerpos(value); + end; +end; + +procedure tmouse.move(const dist: pointty); +begin + if (dist.x <> 0) or (dist.y <> 0) then begin + gui_movepointer(dist); + end; +end; + +procedure tmouse.setshape(const Value: cursorshapety); +var + id1: winidty; +begin + id1:= fintf.getmousewinid; + if (fshape <> value) or (id1 <> fwinid) then begin + fwinid:= id1; + fshape := Value; + gui_setcursorshape(id1,value); + end; +end; + +procedure tmouse.windowdestroyed(const id: winidty); +begin + if id = fwinid then begin + fwinid:= winidty(-1); + end; +end; + +{ tcaret } + +constructor tcaret.create{(out intf: pointer)}; +begin +// intf:= pointer(icaret(self)); + ftimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}timerevent,false,[]); + fbackup:= tbitmap.create(bmk_rgb); //getcanvasimage possibly used by opengl window + fcaret:= tbitmap.create(bmk_rgb); //getcanvasimage possibly used by opengl window + periodetime:= defaultcaretblinkperiodetime; +end; + +destructor tcaret.destroy; +begin + remove; + ftimer.free; + fbackup.free; + fcaret.free; + inherited; +end; + +function tcaret.getperiodetime: integer; +begin + result:= ftimer.interval * 2; +end; + +procedure tcaret.setperiodetime(const Value: integer); +begin + ftimer.interval:= value div 2; +end; + +function tcaret.getbounds: rectty; +begin + result:= fbounds; + subpoint1(result.pos,forigin); +end; + +procedure tcaret.setbounds(const value: rectty); +begin + if (value.x + forigin.x <> fbounds.x) or (value.y + forigin.y <> fbounds.y) or + (value.cx <> fbounds.cx) or (value.cy <> fbounds.cy) then begin + remove; + if not sizeisequal(fbounds.size,value.size) then begin + fbackup.size:= value.size; + fcaret.size:= value.size; + if not fcaret.isempty then begin + fcaret.init(cl_white); + end; + end; + fbounds:= value; + addpoint1(fbounds.pos,forigin); + restore; + end; +end; + +function tcaret.getpos: pointty; +begin + result:= getbounds.pos; +end; + +procedure tcaret.setpos(const Value: pointty); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.pos:= value; + setbounds(rect1); +end; + +function tcaret.getx: integer; +begin + result:= getbounds.pos.x; +end; + +procedure tcaret.setx(const Value: integer); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.pos.x:= value; + setbounds(rect1); +end; + +function tcaret.gety: integer; +begin + result:= getbounds.pos.y; +end; + +procedure tcaret.sety(const Value: integer); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.pos.y:= value; + setbounds(rect1); +end; + +function tcaret.getsize: sizety; +begin + result:= fbounds.size; +end; + +procedure tcaret.setsize(const Value: sizety); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.size:= value; + setbounds(rect1); +end; + +function tcaret.getwidth: integer; +begin + result:= fbounds.cx; +end; + +procedure tcaret.setwidth(const Value: integer); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.cx:= value; + setbounds(rect1); +end; + +function tcaret.getheight: integer; +begin + result:= fbounds.cy; +end; + +procedure tcaret.setheight(const Value: integer); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.cy:= value; + setbounds(rect1); +end; + +procedure tcaret.updatestate; +begin + if fcanvas <> nil then begin + if (fvisible > 0) and + (([cas_on,cas_active] * fstate = [cas_on,cas_active])) and + not (cas_showed in fstate) then begin + //display caret + if not fcaret.isempty then begin + fcanvas.save; + fcanvas.origin:= nullpoint; + fcanvas.clipregion:= fcanvas.createregion(fcliprect); + fbackup.canvas.copyarea(fcanvas,fbounds,nullpoint); + fcanvas.copyarea(fcaret.canvas,makerect(nullpoint,fbounds.size), + fbounds.pos,rop_xor); + fcanvas.restore; + end; + include(fstate,cas_showed); + end + else begin + if (cas_showed in fstate) then begin + if not fcaret.isempty then begin + //remove caret + fcanvas.save; + fcanvas.origin:= nullpoint; + fcanvas.clipregion:= fcanvas.createregion(fcliprect); + fcanvas.copyarea(fbackup.canvas,makerect(nullpoint, + fbounds.size),fbounds.pos); + fcanvas.restore; + exclude(fstate,cas_showed); + end; + end; + end; + end; +end; + +procedure tcaret.restart; +begin + updatestate; + ftimer.interval:= ftimer.interval; + ftimer.enabled:= true; +end; + +procedure tcaret.timerevent(const sender: tobject); +begin + fstate:= caretstatesty({$ifdef FPC}longword{$else}byte{$endif}(fstate) xor byte(1 shl byte(cas_on))); + updatestate; +end; + +procedure tcaret.remove; +begin + dec(fvisible); + updatestate; +end; + +procedure tcaret.restore; +begin + inc(fvisible); + updatestate; +end; + +procedure tcaret.hide; +begin + fstate:= fstate - [cas_on,cas_active]; + ftimer.enabled:= false; + updatestate; +end; + +procedure tcaret.show; +begin + fstate:= fstate + [cas_on,cas_active]; + restart; +end; + +procedure tcaret.link(canvas: tcanvas; const origin: pointty; + const acliprect: rectty); +begin + hide; + fcanvas:= canvas; + forigin:= origin; + fbounds.pos:= origin; + fcliprect:= moverect(acliprect,origin); + if fcanvas = nil then begin + fstate:= []; + end + else begin + fstate:= [cas_active]; + end; +end; + +function tcaret.getcliprect: rectty; +begin + result:= removerect(fcliprect,forigin); +end; + +procedure tcaret.setcliprect(const Value: rectty); +begin + remove; + fcliprect:= moverect(value,forigin); + restore; +end; + + +function tcaret.islinkedto(canvas: tcanvas): boolean; +begin + result:= (fcanvas <> nil) and (fcanvas = canvas); +end; + +procedure tcaret.scroll(const dist: pointty; const scrollorigin: boolean); +begin + remove; + addpoint1(fbounds.pos,dist); + if scrollorigin then begin + addpoint1(forigin,dist); + addpoint1(fcliprect.pos,dist); + end; + restore; +end; + +procedure tcaret.move(const dist: pointty); +begin + pos:= addpoint(pos,dist); +end; + +function tcaret.active: boolean; +begin + result:= cas_active in fstate; +end; + +function tcaret.visible: boolean; +begin + result:= fvisible > 0; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseprocmonitor.inc b/mseide-msegui/lib/common/kernel/mseprocmonitor.inc new file mode 100644 index 0000000..d073d8e --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseprocmonitor.inc @@ -0,0 +1,22 @@ +{ MSEgui Copyright (c) 2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +type + iprocmonitor = interface(inullinterface) + procedure processdied(const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); + end; + +function pro_listentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor; const adata: pointer): boolean; + //false on error, limited to 63 items on windows +procedure pro_unlistentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor); +procedure pro_killzombie(const aprochandle: prochandlety); + diff --git a/mseide-msegui/lib/common/kernel/msereal.pas b/mseide-msegui/lib/common/kernel/msereal.pas new file mode 100644 index 0000000..c0bd46c --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msereal.pas @@ -0,0 +1,178 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msereal; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes{,classes,mclasses},msestrings; + +const + emptyrealstring = ''; //stringsymbol for empty realty + bigreal = 1e38; + +function cmprealty(const a,b: realty): integer; +//function emptyreal: realty; +function isemptyreal(const val: realty): boolean; {$ifdef FPC}inline;{$endif} + deprecated; + //use x = emptyreal instead +function candiv(const val: realty): boolean; //true if not 0.0 or empty: + +function addrealty(const a,b: realty): realty; //result = a - b +function subrealty(const a,b: realty): realty; //result = a + b +function mulrealty(const a,b: realty): realty; //result = a * b + +function applyrange(const avalue: realty; const arange: real; + const astart: real): realty; +function reapplyrange(const avalue: realty; const arange: real; + const astart: real): realty; +function expscale(const value: real; const min: real; const max: real): real; + +implementation +uses + sysutils,{msesys,}sysconst; + +const +{$ifdef FPC_DOUBLE_HILO_SWAPPED} + co1: array[0..7] of byte = (0,0,$f0,$ff,$0,0,0,0); //- inf +{$else} + co1: array[0..7] of byte = ($0,0,0,0,0,0,$f0,$ff); //- inf +{$endif} + +function expscale(const value: real; const min: real; const max: real): real; +var + mi,ma: real; +begin + mi:= ln(min); + ma:= ln(max); + result:= exp(value*(ma-mi)+mi); +end; + +function applyrange(const avalue: realty; const arange: real; + const astart: real): realty; +begin + if (avalue = emptyreal) or (arange = 0) then begin + result:= avalue; + end + else begin + result:= avalue * arange - astart; + end; +end; + +function reapplyrange(const avalue: realty; const arange: real; + const astart: real): realty; +begin + if (avalue = emptyreal) or (arange = 0) then begin + result:= avalue; + end + else begin + result:= (avalue-astart) / arange; + end; +end; + +function addrealty(const a,b: realty): realty; //result = a - b +begin + if a = emptyreal then begin + result:= b; + end + else begin + if b = emptyreal then begin + result:= a; + end + else begin + result:= a + b; + end; + end; +end; + +function subrealty(const a,b: realty): realty; //result = a + b +begin + if a = emptyreal then begin + if b = emptyreal then begin + result:= emptyreal; + end + else begin + result:= -b; + end; + end + else begin + if b = emptyreal then begin + result:= a; + end + else begin + result:= a - b; + end; + end; +end; + +function mulrealty(const a,b: realty): realty; //result = a * b +begin + if not (a = emptyreal) and not (b = emptyreal) then begin + result:= a * b; + end + else begin + result:= emptyreal; + end; +end; + +function isemptyreal(const val: realty): boolean; //true wenn leer +begin + result:= val = emptyreal; +end; + +{ +function emptyreal: realty; +begin + move(co1,result,sizeof(realty)); +// doublepo:= @co1; +// result:= doublepo^; +end; + +function isemptyreal(const val: realty): boolean; //true wenn leer +begin + result:= comparemem(@val,@co1,sizeof(realty)) +end; +} +function candiv(const val: realty): boolean; //true if not 0.0 or empty: +begin + result:= (val <> 0.0) and not comparemem(@val,@co1,sizeof(realty)); +end; + +function cmprealty(const a,b: realty): integer; + //-1 wenn a < b, 0 wenn a = b, 1 wenn a > b +begin + if b = emptyreal then begin + result:= 1; + if a = emptyreal then begin + result:= 0; + end; + end + else begin + if a = emptyreal then begin + result:= -1; + end + else begin + if a > b then begin + result:= 1; + end + else begin + if a < b then begin + result:= -1; + end + else begin + result:= 0; + end; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mserichstring.pas b/mseide-msegui/lib/common/kernel/mserichstring.pas new file mode 100644 index 0000000..3c2472e --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mserichstring.pas @@ -0,0 +1,1577 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mserichstring; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + sysutils,msetypes,msekeyboard,mseevent,msedatalist,msegraphutils, + {classes,}mclasses,msestrings,mseglob,mseinterfaces; + +const + fsboldmask = $01; + fsitalicmask = $02; + fsunderlinemask = $04; + fsstrikeoutmask = $08; + +type + newinfoty = (ni_bold=ord(fs_bold),ni_italic=ord(fs_italic), + ni_underline=ord(fs_underline),ni_strikeout=ord(fs_strikeout), + ni_selected=ord(fs_selected),ni_blank=ord(fs_blank), + //same order as in fontstylety + ni_fontcolor,ni_colorbackground,ni_delete); + newinfosty = set of newinfoty; + +const + fonthandleflags = [ni_bold,ni_italic]; + fontlayoutflags = [ni_bold,ni_italic,ni_blank]; + fontstyleflags = [ni_bold,ni_italic,ni_underline,ni_strikeout,ni_selected, + ni_blank]; + +type + charstylety = record + fontcolor,colorbackground: colorty; //bits inversed, 0 -> not set + fontstyle: fontstylesty; + end; + pcharstylety = ^charstylety; + + charstylearty = array of charstylety; + + formatinfoty = record + index: integer; //0-> from first char + newinfos: newinfosty; + style: charstylety; + end; + + pformatinfoty = ^formatinfoty; + formatinfoarty = array of formatinfoty; + pformatinfoarty = ^formatinfoarty; + + richflagty = (rf_noparagraph); + richflagsty = set of richflagty; + + richstringty = record + text: msestring; + format: formatinfoarty; + flags: richflagsty; + end; + + prichstringty = ^richstringty; + richstringarty = array of richstringty; + + richstringaty = array[0..0] of richstringty; + prichstringaty = ^richstringaty; + + updaterichstringeventty = procedure(const sender: tobject; + var avalue: richstringty) of object; + + irichstringprop = interface(inullinterface)[miid_irichstringprop] + function getrichvalue: richstringty; + procedure setrichvalue(const avalue: richstringty); + end; + + trichstringdatalist = class(tmsestringdatalist) + private + fposition: pointty; + function Getformats(index: integer): formatinfoarty; + procedure Setformats(index: integer; const Value: formatinfoarty); + procedure setnoparagraphs(index: integer; const avalue: boolean); + function getrichitems(index: integer): richstringty; + procedure setrichitems(index: integer; const Value: richstringty); + function getrichitemspo(index: integer): prichstringty; + procedure setasarray(const data: richstringarty); + function getasarray: richstringarty; + procedure setasmsestringarray(const data: msestringarty); + function getasmsestringarray: msestringarty; + protected + function getnoparagraphs(index: integer): boolean; override; + procedure freedata(var data); override; //gibt daten frei + procedure aftercopy(var data); override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + public + constructor create; override; + procedure insert(const index: integer; const item: msestring); override; + function add(const value: msestring): integer; override; + function add(const avalue: msestring; + const anoparagraph: boolean): integer; override; + function nextword(out value: lmsestringty): boolean; + //true bei new line + function getformatpo(index: integer): pformatinfoarty; + function getparagraph(const index: integer; + const aseparator: msestring = ''): msestring; + + property formats[index: integer]: formatinfoarty read Getformats write Setformats; + property noparagraphs[index : integer]: boolean read getnoparagraphs + write setnoparagraphs; + property richitems[index: integer]: richstringty read getrichitems write setrichitems; + property richitemspo[index: integer]: prichstringty read getrichitemspo; + property position: pointty read fposition write fposition; + //x = 0 fuer zeilenbeginn + property asarray: richstringarty read getasarray write setasarray; + property asmsestringarray: msestringarty read getasmsestringarray + write setasmsestringarray; + end; + + tcharstyledatalist = class(tdatalist) + private + function Getitems(index: integer): charstylety; + procedure Setitems(index: integer; const Value: charstylety); + public + constructor create; override; + procedure clear; override; + function add(const value: charstylety): integer; overload; + function add(style: fontstylesty = []; fontcolor: pcolorty = nil; + colorbackground: pcolorty = nil): integer; overload; + function add(const value: string): integer; overload; + //'bius' fontcolor colorbackground + property items[index: integer]: charstylety read Getitems write Setitems; + default; + end; + +const + emptyrichstring: richstringty = (text: ''; format: nil; flags: []); + richlineend: richstringty = (text: lineend; format: nil; flags: []); + +function charstyletocolor(const color: colorty): colorty; +function colortocharstyle(const color: colorty): colorty; + +function setfontcolor1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; color: colorty): boolean; + //true if changed +function setfontcolor(const formats: formatinfoarty; aindex: integer; + len: halfinteger; color: colorty): formatinfoarty; +function setcolorbackground1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): boolean; + //true if changed +function setcolorbackground(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): formatinfoarty; + +function updatefontstyle1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyle: fontstylety; aset: boolean): boolean; + //true if changed +function updatefontstyle(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyle: fontstylety; aset: boolean): formatinfoarty; +function updatefontstyle1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyles: fontstylesty; aset: boolean): boolean; + //true if changed +function updatefontstyle(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyles: fontstylesty; aset: boolean): formatinfoarty; + +function setcharstyle1(var formats: formatinfoarty; aindex,len: halfinteger; + const style: charstylety): boolean; + //true if changed +function setcharstyle(const formats: formatinfoarty; aindex,len: halfinteger; + const style: charstylety): formatinfoarty; +function getcharstyle(const formats: formatinfoarty; + const aindex: integer): charstylety; //zero based +function getfontstyle(const formats: formatinfoarty; + const aindex: integer): fontstylesty; //zero based + +procedure setselected1(var text: richstringty; start,len: halfinteger); +function setselected(const text: richstringty; + start,len: halfinteger): richstringty; + +function isequalrichstring(const a,b: richstringty): boolean; +function isemptyrichstring(const value: richstringty): boolean; +function isequalformat(const a,b: formatinfoarty): boolean; +function isequalformatinfo(const a,b: formatinfoty): boolean; + +procedure richdelete(var value: richstringty; aindex,count: integer); +procedure richinsert(const source: msestring; var value: richstringty; + aindex: integer); +function richcopy(const source: richstringty; index, count: halfinteger): richstringty; +function richconcat(const a,b: richstringty): richstringty; overload; +function richconcat(const a: richstringty; const b: msestring; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none): richstringty; overload; +function richconcat(const a: msestring; const b: richstringty; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none): richstringty; overload; +procedure richconcat1(var dest: richstringty; const b: richstringty); overload; +procedure richconcat1(var dest: richstringty; const b: msestring; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none); overload; + + +procedure additem(const value: richstringty; var dest: richstringarty; + var count: integer; step: integer = 32); overload; +function splitrichstring(const avalue: richstringty; const separator: msechar): richstringarty; +function breakrichlines(const source: richstringty): richstringarty; + +procedure captiontorichstring(const caption: captionty; var dest: richstringty); +//procedure captiontorichstring(const caption: captionty; out result: richstringty); +function richstringtocaption(const caption: richstringty): captionty; +function isshortcut(key: keyty; const caption: msestring): boolean; overload; +function isshortcut(key: msechar; const caption: msestring): boolean; overload; +//function checkshortcut(var info: keyeventinfoty; +// const caption: richstringty; const checkalt: boolean): boolean; overload; + //moved to msegui +//function checkshortcut(var info: keyeventinfoty; +// const key: keyty; const shiftstate: shiftstatesty): boolean; overload; + +function expandtabs(const s: richstringty; const tabcharcount: integer): richstringty; + +procedure writerichstring(const writer: twriter; const value: richstringty); +function readrichstring(const reader: treader): richstringty; + +{$ifdef FPC} +function richformatinfotostring(const aformat: formatinfoty): ansistring; +{$endif} + +var + hotkeyfontstylesadd: fontstylesty; //default [fs_underline] + hotkeyfontstylesremove: fontstylesty; //default [] + hotkeycolor: colorty; //default cl_none + hotkeycolorbackground: colorty; //default cl_none + +implementation +uses + typinfo,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tpoorstringdatalist1 = class(tpoorstringdatalist); + +{$ifdef FPC} +function richformatinfotostring(const aformat: formatinfoty): ansistring; +begin + with aformat do begin + result:= inttostr(index)+' '+settostring(ptypeinfo(typeinfo(newinfosty)), + integer(newinfos),true)+ + ' ' + settostring(ptypeinfo(typeinfo(fontstylesty)), + integer(style.fontstyle),true); + end; +end; +{$endif} + +procedure writerichstring(const writer: twriter; const value: richstringty); +var + i1: int32; +begin + if value.format = nil then begin + writer.writeunicodestring(value.text); + end + else begin + writer.writelistbegin(); + writer.writeunicodestring(value.text); + writer.writelistbegin(); + for i1:= 0 to high(value.format) do begin + writer.writelistbegin(); + with value.format[i1] do begin + writer.writeinteger(index); + writer.writeset(card32(newinfos),typeinfo(newinfos)); + writer.writeinteger(int32(style.fontcolor)); + writer.writeinteger(int32(style.colorbackground)); + writer.writeset(card32(style.fontstyle),typeinfo(style.fontstyle)); + end; + writer.writelistend(); + end; + writer.writelistend(); + writer.writelistend(); + end; +end; + +function readrichstring(const reader: treader): richstringty; +var + i1: int32; +begin + if not reader.beginoflist then begin + result.format:= nil; + result.text:= reader.readunicodestring(); + end + else begin + reader.readlistbegin(); + result.text:= reader.readunicodestring(); + reader.readlistbegin(); + result.format:= nil; + i1:= 0; + while reader.beginoflist() do begin + reader.readlistbegin(); + msearrayutils.additem(result.format,typeinfo(result.format),i1); + with result.format[i1-1] do begin + index:= reader.readinteger(); + newinfos:= newinfosty(reader.readset(typeinfo(newinfos))); + style.fontcolor:= reader.readinteger(); + style.colorbackground:= reader.readinteger(); + style.fontstyle:= fontstylesty(reader.readset(typeinfo(style.fontstyle))); + end; + reader.readlistend(); + end; + setlength(result.format,i1); + reader.readlistend(); + reader.readlistend(); + end; +end; + +function splitrichstring(const avalue: richstringty; const separator: msechar): richstringarty; +var + int1: integer; + ar1: integerarty; +begin + ar1:= getcharpos(avalue.text,separator); + setlength(result,high(ar1)+2); + if ar1 = nil then begin + result[0].text:= avalue.text; + result[0].format:= copy(avalue.format); + end + else begin + result[0]:= richcopy(avalue,1,ar1[0]-1); + for int1:= 0 to high(ar1) - 1 do begin + result[int1+1]:= richcopy(avalue,ar1[int1]+1,ar1[int1+1]-ar1[int1]-1); + end; + result[high(result)]:= richcopy(avalue,ar1[high(ar1)]+1,bigint); + end; +end; + +function breakrichlines(const source: richstringty): richstringarty; +var + int1,int2: integer; +begin + result:= splitrichstring(source,c_linefeed); + for int1:= 0 to high(result) do begin + int2:= length(result[int1].text); + if (int2 > 0) and (result[int1].text[int2] = c_return) then begin + setlength(result[int1].text,int2-1); + end; + end; +end; + +procedure captiontorichstring(const caption: captionty; var dest: richstringty); +var + int1: integer; + ch1: msechar; + po1: pmsechar; + + procedure sethotstyle(); + begin + with dest do begin + updatefontstyle1(format,po1-pmsechar(pointer(text)),1, + hotkeyfontstylesadd,true); + updatefontstyle1(format,po1-pmsechar(pointer(text)),1, + hotkeyfontstylesremove,false); + if hotkeycolor <> cl_none then begin + setfontcolor1(format,po1-pmsechar(pointer(text)),1,hotkeycolor); + end; + if hotkeycolorbackground <> cl_none then begin + setcolorbackground1(format,po1-pmsechar(pointer(text)),1, + hotkeycolorbackground); + end; + end; + end;//sethotstyle + +begin + with dest do begin + setlength(text,length(caption)); //max + format:= nil; + po1:= pointer(text); + int1:= 1; + while int1 <= length(caption) do begin + ch1:= caption[int1]; + if (ch1 = '&') {and (format = nil)} then begin + if caption[int1+1] = '&' then begin + po1^:= ch1; + inc(int1); + if caption[int1+1] = '&' then begin //there is a trailing #0 + sethotstyle(); + inc(int1); + end; + inc(po1); + end + else begin + sethotstyle(); + end; + end + else begin + po1^:= ch1; + inc(po1); + end; + inc(int1); + end; + setlength(text,po1-pmsechar(pointer(text))); + end; +end; + +function richstringtocaption(const caption: richstringty): captionty; + function checkhotkey(const astyle: charstylety): boolean; + begin + result:= (astyle.fontstyle * hotkeyfontstylesadd = hotkeyfontstylesadd) and + (astyle.fontstyle * hotkeyfontstylesremove = []) and + ((hotkeycolor = cl_none) or (astyle.fontcolor = hotkeycolor)) and + ((hotkeycolorbackground = cl_none) or + (astyle.colorbackground = hotkeycolorbackground)); + ; + end;//checkhotkey + +var + int1: integer; + po1: pmsechar; + ch1: msechar; +begin + with caption do begin + setlength(result,length(text)*2+1); + po1:= pmsechar(pointer(result)); + for int1:= 1 to length(text) do begin +// if fs_underline in getfontstyle(format,int1-1) then begin + if checkhotkey(getcharstyle(format,int1-1)) then begin + po1^:= '&'; + inc(po1); + end; + ch1:= text[int1]; + po1^:= ch1; + inc(po1); + if (ch1 = '&') then begin + po1^:= ch1; + inc(po1); + end; + end; + if checkhotkey(getcharstyle(format,length(text))) then begin + po1^:= '&'; + inc(po1); + end; + end; + setlength(result,po1-pmsechar(pointer(result))); +end; + +function isshortcut(key: msechar; const caption: msestring): boolean; +var + p1: pmsechar; +begin + result:= false; + if caption <> '' then begin + p1:= pointer(caption); + while p1^ <> #0 do begin + if p1^ = '&' then begin + inc(p1); + if (p1^ <> '&') and (p1^ <> ' ') then begin + result:= msecomparetext(p1^,key) = 0; + break; + end; + end; + inc(p1); + end; + end; +{ + with caption do begin + if (format = nil) or (format[0].index >= length(text)) or (length(key) < 1) then begin + result:= false; + end + else begin + result:= mseuppercase(text[format[0].index+1]) = mseuppercase(key); +// result:= charuppercase(text[format[0].index+1]) = charuppercase(key); + end; + end; + } +end; +{ +function isshortcut(key: msechar; const caption: richstringty): boolean; +begin + with caption do begin + if (format = nil) or (format[0].index >= length(text)) or (length(key) < 1) then begin + result:= false; + end + else begin + result:= mseuppercase(text[format[0].index+1]) = mseuppercase(key); +// result:= charuppercase(text[format[0].index+1]) = charuppercase(key); + end; + end; +end; +} +function isshortcut(key: keyty; const caption: msestring): boolean; +begin + result:= isshortcut(keytomsechar(key),caption); +end; + +procedure insertfontinfo(var infoar: formatinfoarty; aindex: integer); +begin + setlength(infoar,length(infoar)+1); + if aindex > 0 then begin + move(infoar[aindex-1],infoar[aindex], + (length(infoar)-aindex)*sizeof(formatinfoty)); + infoar[aindex].newinfos:= []; + end + else begin + move(infoar[aindex],infoar[aindex+1], + (length(infoar)-aindex-1)*sizeof(formatinfoty)); + fillchar(infoar[0],sizeof(formatinfoty),0); + end; +end; + +function getnewfontinfo(var fontinfoar: formatinfoarty; aindex: integer; + out num: integer): pformatinfoty; +var + int1,int2: integer; +begin + int1:= 0; + if length(fontinfoar) = 0 then begin + insertfontinfo(fontinfoar,0); + end + else begin + int2:= high(fontinfoar); + while int1 <= int2 do begin + with fontinfoar[int1] do begin + if index >= aindex then begin + if index > aindex then begin + insertfontinfo(fontinfoar,int1); + end; + break; + end; + end; + inc(int1); + end; + if int1 > int2 then begin + insertfontinfo(fontinfoar,int1); + end; + end; + result:= @fontinfoar[int1]; + result^.index:= aindex; + num:= int1; +end; + +procedure packfontformats(var formats: formatinfoarty); +var + int1,int2: integer; + focopo,bacopo: colorty; + fontstyles,fontstylesdelta: fontstylesty; +begin + int2:= 0; + int1:= 0; + focopo:= 0; + bacopo:= 0; + fontstyles:= []; + while int1 < length(formats) do begin + with formats[int1] do begin + if not(ni_delete in newinfos) then begin + if style.fontcolor = focopo then begin + exclude(newinfos,ni_fontcolor); + end + else begin + include(newinfos,ni_fontcolor); + end; + if style.colorbackground = bacopo then begin + exclude(newinfos,ni_colorbackground); + end + else begin + include(newinfos,ni_colorbackground); + end; + fontstylesdelta:= fontstylesty( + {$ifdef FPC}longword{$else}byte{$endif}(fontstyles) xor + {$ifdef FPC}longword{$else}byte{$endif}(style.fontstyle)); + newinfos:= newinfos - + newinfosty(not + {$ifdef FPC}longword({$else} + word(byte{$endif}(fontstylesdelta))) * fontstyleflags + + newinfosty( + {$ifdef FPC}longword({$else} + word(byte{$endif}(fontstylesdelta))) * fontstyleflags; + if ni_fontcolor in newinfos then begin + focopo:= style.fontcolor; + end; + if ni_colorbackground in newinfos then begin + bacopo:= style.colorbackground; + end; + fontstyles:= fontstylesty({$ifdef FPC}longword{$else}byte{$endif}(fontstyles) xor + {$ifdef FPC}longword{$else}byte{$endif}(fontstylesdelta) and + {$ifdef FPC}longword({$else}byte(word{$endif}(newinfos))); + if newinfos <> [] then begin + if int1 <> int2 then begin + formats[int2]:= formats[int1]; + end; + inc(int2); + end; + end; + end; + inc(int1); + end; + if int1 <> int2 then begin + setlength(formats,int2); + end; +end; + +function setfontinfolen(var formats: formatinfoarty; aindex: integer; len: halfinteger; + const astyle: charstylety; flags: newinfosty): boolean; + //true wenn geaendert + + function updatestyle(var style: charstylety): boolean; + var + afontstyle: fontstylesty; + begin + result:= false; +// style.newinfos:= newinfos+flags; + if ni_fontcolor in flags then begin + result:= result or (style.fontcolor <> astyle.fontcolor); + style.fontcolor:= astyle.fontcolor; + end; + if ni_colorbackground in flags then begin + result:= result or (style.colorbackground <> astyle.colorbackground); + style.colorbackground:= astyle.colorbackground; + end; + afontstyle:= style.fontstyle; + style.fontstyle:= style.fontstyle - + fontstylesty({$ifdef FPC}longword({$else} + byte(word{$endif}(flags * fontstyleflags))) + + astyle.fontstyle * fontstylesty( + {$ifdef FPC}longword({$else}byte(word{$endif}(flags))); + result:= result or (afontstyle <> style.fontstyle); + end; + +var + int1,int2: integer; + isempty: boolean; + lastnum: integer; + bo1: boolean; + +begin + result:= false; + isempty:= length(formats) = 0; + if len > 0 then begin + int2:= high(formats); + getnewfontinfo(formats,aindex,int1); + getnewfontinfo(formats,aindex + len,lastnum); + for int1:= int1 to lastnum - 1 do begin + bo1:= updatestyle(formats[int1].style); + result:= result or bo1; + end; + if result or (high(formats) > int2) then begin + packfontformats(formats); + end; + end; + result:= result and not (isempty and (length(formats) = 0)); +end; + +function charstyletocolor(const color: colorty): colorty; +begin + if color = 0 then begin + result:= cl_default; + end + else begin + result:= not(color); + end; +end; + +function colortocharstyle(const color: colorty): colorty; +begin + if color = cl_default then begin + result:= 0; + end + else begin + result:= not(color); + end; +end; + +function setfontcolor1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): boolean; + //true if changed +var + style: charstylety; +begin + style.fontcolor:= not color; + result:= setfontinfolen(formats,aindex,len,style,[ni_fontcolor]); +end; + +function setfontcolor(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): formatinfoarty; +begin + result:= copy(formats); + setfontcolor1(result,aindex,len,color); +end; + +function setcolorbackground1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): boolean; + //true if changed +var + style: charstylety; +begin + style.colorbackground:= not color; + result:= setfontinfolen(formats,aindex,len,style,[ni_colorbackground]); +end; + +function setcolorbackground(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): formatinfoarty; +begin + result:= copy(formats); + setcolorbackground1(result,aindex,len,color); +end; + +procedure setselected1(var text: richstringty; start,len: halfinteger); +begin + updatefontstyle1(text.format,0,bigint,fs_selected,false); + updatefontstyle1(text.format,start,len,fs_selected,true); +end; + +function setselected(const text: richstringty; + start,len: halfinteger): richstringty; +begin + result:= text; + setlength(result.format,length(result.format)); + setselected1(result,start,len); +end; + +function updatefontstyle1(var formats: formatinfoarty; aindex: integer; len: halfinteger; + astyles: fontstylesty; aset: boolean): boolean; + //true if changed +var + style: charstylety; + newinfos: newinfosty; +begin + if aset then begin + style.fontstyle:= astyles; + end + else begin + style.fontstyle:= []; + end; + newinfos:= newinfosty({$ifdef FPC}longword({$else}word(byte{$endif}(astyles))); + result:= setfontinfolen(formats,aindex,len,style,newinfos); +end; + +function updatefontstyle1(var formats: formatinfoarty; aindex: integer; len: halfinteger; + astyle: fontstylety; aset: boolean): boolean; + //true if changed +begin + result:= updatefontstyle1(formats,aindex,len,[astyle],aset); +end; + +function updatefontstyle(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyles: fontstylesty; aset: boolean): formatinfoarty; +begin + result:= copy(formats); + updatefontstyle1(result,aindex,len,astyles,aset); +end; + +function updatefontstyle(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyle: fontstylety; aset: boolean): formatinfoarty; +begin + result:= updatefontstyle(formats,aindex,len,[astyle],aset); +end; + +function setcharstyle1(var formats: formatinfoarty; + aindex,len: halfinteger; const style: charstylety): boolean; + //true if changed +begin + result:= setfontinfolen(formats,aindex,len,style, + [ni_fontcolor,ni_colorbackground,ni_bold,ni_italic,ni_underline, + ni_strikeout,ni_blank]); +end; + +function setcharstyle(const formats: formatinfoarty; + aindex,len: halfinteger; const style: charstylety): formatinfoarty; +begin + result:= copy(formats); + setcharstyle1(result,aindex,len,style); +end; + +function getcharstyle(const formats: formatinfoarty; + const aindex: integer): charstylety; +var + int1: integer; + foundindex: integer; +begin + if length(formats) > 0 then begin + foundindex:= -1; + for int1:= 0 to high(formats) do begin + with formats[int1] do begin + if index > aindex then begin + foundindex:= int1; + break; + end; + end; + end; + if foundindex >= 0 then begin + if foundindex > 0 then begin + result:= formats[foundindex-1].style; + end + else begin + fillchar(result,sizeof(charstylety),0); + end; + end + else begin + result:= formats[high(formats)].style; + end + end + else begin + fillchar(result,sizeof(charstylety),0); + end; +end; + +function getfontstyle(const formats: formatinfoarty; + const aindex: integer): fontstylesty; +var + int1: integer; + foundindex: integer; +begin + result:= []; + if formats <> nil then begin + foundindex:= -1; + for int1:= 0 to high(formats) do begin + with formats[int1] do begin + if index > aindex then begin + foundindex:= int1; + break; + end; + end; + end; + if foundindex >= 0 then begin + if foundindex > 0 then begin + result:= formats[foundindex-1].style.fontstyle; + end; + end + else begin + result:= formats[high(formats)].style.fontstyle; + end + end; +end; + +function isequalformatinfo(const a,b: formatinfoty): boolean; +begin + result:= (a.index = b.index) and (a.newinfos = b.newinfos) and + (a.style.fontcolor = b.style.fontcolor) and + (a.style.colorbackground = b.style.colorbackground) and + (a.style.fontstyle = b.style.fontstyle); +end; + +function isequalformat(const a,b: formatinfoarty): boolean; +var + int1: integer; +begin + if pointer(a) = pointer(b) then begin + result:= true; + exit; + end; + result:= length(a) = length(b); + if result then begin + for int1:= 0 to high(a) do begin + if not isequalformatinfo(a[int1],b[int1]) then begin + result:= false; + break; + end; + end; +// result:= comparemem(pointer(a),pointer(b),length(a)*sizeof(fontinfoty)); + end; +end; + +function isequalrichstring(const a,b: richstringty): boolean; +begin + result:= (a.text = b.text) and isequalformat(a.format,b.format); +end; + +function isemptyrichstring(const value: richstringty): boolean; +begin + result:= (value.text = '') and (value.format = nil) and (value.flags = []); +end; + +procedure richdelete(var value: richstringty; aindex,count: integer); +var + int1: integer; + needspack,all: boolean; +begin + if (aindex > 0) then begin + delete(value.text,aindex,count); + if length(value.format) > 0 then begin + setlength(value.format,length(value.format)); //unique + needspack:= false; + all:= count >= bigint; + dec(aindex); + for int1:= 0 to high(value.format) do begin + with value.format[int1] do begin + if index >= aindex then begin + index:= index - count; + if all or (index < aindex) then begin + needspack:= true; + newinfos:= [ni_delete]; + end; + end; + end; + end; + if needspack then begin + packfontformats(value.format); + end; + end; + end; +end; + +procedure formatinsertchars(var format: formatinfoarty; const aindex: integer; + const count: integer); +var + int1: integer; +begin + setlength(format,length(format)); //unique + for int1:= 0 to high(format) do begin + with format[int1] do begin + if index >= aindex then begin + index:= index + count; + end; + end; + end; +end; + +function expandtabs(const s: richstringty; const tabcharcount: integer): richstringty; +var + int1,int2,int3,int4: integer; +begin + int1:= tabcharcount; + if int1 <= 0 then begin + int1:= 1; + end; + setlength(result.text,length(s.text)*int1); //max + result.format:= copy(s.format); + int2:= 1; + for int1:= 1 to length(s.text) do begin + if s.text[int1] = c_tab then begin + if tabcharcount > 0 then begin + int3:= tabcharcount - ((int2-1) mod tabcharcount) - 1; + formatinsertchars(result.format,int2,int3); + for int4:= 0 to int3 do begin + result.text[int2]:= ' '; + inc(int2); + end; + end; + end + else begin + result.text[int2]:= s.text[int1]; + inc(int2); + end; + end; + setlength(result.text,int2-1); +end; + +procedure richinsert(const source: msestring; var value: richstringty; aindex: integer); +begin + insert(source,value.text,aindex); + formatinsertchars(value.format,aindex,length(source)); +end; + +function richcopy(const source: richstringty; index, count: halfinteger): richstringty; +var + int1,int2: integer; + startindex,endindex: integer; + res: richstringty; +begin + if count = 0 then begin + result:= emptyrichstring; + end + else begin + res.text:= copy(source.text,index,count); + res.format:= nil; + if length(source.format) > 0 then begin + startindex:= -1; + endindex:= -1; + for int1:= 0 to high(source.format) do begin + if source.format[int1].index >= index then begin + startindex:= int1; + break; + end; + end; + if startindex < 0 then begin + int1:= 0; + end + else begin + int1:= startindex; + end; + for int1:= int1 to high(source.format) do begin + if source.format[int1].index >= index + count then begin + endindex:= int1; + break; + end; + end; + if startindex > 0 then begin + dec(startindex); + end + else begin + startindex:= 0; + end; + if endindex >= 0 then begin + res.format:= copy(source.format,startindex,endindex-startindex); + end + else begin + res.format:= copy(source.format,startindex,bigint); + end; + if length(res.format) > 0 then begin + with res.format[0] do begin + newinfos:= []; + if style.fontcolor <> 0 then include(newinfos,ni_fontcolor); + if style.colorbackground <> 0 then include(newinfos,ni_colorbackground); + if fs_bold in style.fontstyle then include(newinfos,ni_bold); + if fs_italic in style.fontstyle then include(newinfos,ni_italic); + if fs_underline in style.fontstyle then include(newinfos,ni_underline); + if fs_strikeout in style.fontstyle then include(newinfos,ni_strikeout); + if fs_selected in style.fontstyle then include(newinfos,ni_selected); + end; + for int1:= 0 to high(res.format) do begin + int2:= res.format[int1].index - index + 1; + if int2 < 0 then begin + int2:= 0; + end; + res.format[int1].index:= int2; + end; + end; + end; + result:= res; + end; +end; + +function richconcat(const a,b: richstringty): richstringty; +var + i1,i2,i3: integer; + res: richstringty; +begin + res.format:= a.format; + res.text:= a.text + b.text; + i2:= length(res.format); + i3:= length(a.text); + setlength(res.format,i2 + length(b.format)); + for i1:= 0 to high(b.format) do begin + with res.format[i1+i2] do begin + index:= b.format[i1].index + i3; + newinfos:= b.format[i1].newinfos; + style:= b.format[i1].style; + end; + end; + result:= res; +end; + +function richconcat(const a: richstringty; const b: msestring; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none): richstringty; +var + rstr1: richstringty; +begin + if (fontstyle <> []) or (fontcolor <> cl_none) or + (colorbackground <> cl_none) then begin + setlength(rstr1.format,1); + with rstr1.format[0] do begin + index:= 0; + if fontstyle <> [] then begin + style.fontstyle:= fontstyle; + newinfos:= fontstyleflags; + end; + if fontcolor <> cl_none then begin + style.fontcolor:= not fontcolor; + include(newinfos,ni_fontcolor); + end; + if colorbackground <> cl_none then begin + style.colorbackground:= not colorbackground; + include(newinfos,ni_colorbackground); + end; + end + end + else begin + rstr1.format:= nil; + end; + rstr1.text:= b; + result:= richconcat(a,rstr1); +end; + +function richconcat(const a: msestring; const b: richstringty; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none): richstringty; overload; +var + rstr1: richstringty; +begin + if (fontstyle <> []) or (fontcolor <> cl_none) or + (colorbackground <> cl_none) then begin + setlength(rstr1.format,1); + with rstr1.format[0] do begin + index:= 0; + if fontstyle <> [] then begin + style.fontstyle:= fontstyle; + newinfos:= fontstyleflags; + end; + if fontcolor <> cl_none then begin + style.fontcolor:= not fontcolor; + include(newinfos,ni_fontcolor); + end; + if colorbackground <> cl_none then begin + style.colorbackground:= not colorbackground; + include(newinfos,ni_colorbackground); + end; + end + end + else begin + rstr1.format:= nil; + end; + rstr1.text:= a; + result:= richconcat(rstr1,b); +end; + +procedure richconcat1(var dest: richstringty; const b: richstringty); +begin + dest:= richconcat(dest,b); +end; + +procedure richconcat1(var dest: richstringty; const b: msestring; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none); +begin + dest:= richconcat(dest,b,fontstyle,fontcolor,colorbackground); +end; + +{ +function uniqueformatinfoarty(const value: formatinfoarty): formatinfoarty; +begin + result:= value; + setlength(result,length(result)); +end; + +function uniquerichstringty(const value: richstringty): richstringty; +begin + result:= value; + setlength(result.format,length(result.format)); +end; +} +procedure additem(const value: richstringty; var dest: richstringarty; + var count: integer; step: integer = 32); +begin + if length(dest) <= count then begin + setlength(dest,count+step); + end; + dest[count]:= value; + inc(count); +end; + +{ tcharstyledatalist } + +constructor tcharstyledatalist.create; +begin + inherited; + fsize:= sizeof(charstylety); +end; + +function tcharstyledatalist.add(const value: charstylety): integer; +begin + result:= adddata(value); +end; + +function tcharstyledatalist.add(style: fontstylesty = []; fontcolor: pcolorty = nil; + colorbackground: pcolorty = nil): integer; +var + value: charstylety; +begin + value.fontstyle:= style; + if fontcolor = nil then begin + value.fontcolor:= 0; + end + else begin + value.fontcolor:= not fontcolor^; + end; + if colorbackground = nil then begin + value.colorbackground:= 0; + end + else begin + value.colorbackground:= not colorbackground^; + end; +// value.colorbackground:= colorbackground; + result:= add(value); +end; + +function tcharstyledatalist.add(const value: string): integer; + + function getcolor(const name: string): colorty; +// var +// col1: colorty; +// int1,int2: integer; +// po1: pcolorty; + begin + if name = '' then begin + result:= 0; + end + else begin + result:= not stringtocolor(name); + (* + col1:= stringtocolor(name); + for int1:= 0 to high(fcolors) do begin + if fcolors[int1] = col1 then begin + result:= @fcolors[int1]; + exit; + end; + end; + po1:= pointer(fcolors); + for int1:= 1 to length(fcolors) do begin + for int2:= 0 to fcount-1 do begin + with pcharstylety(getitempo(int2))^{licharstylearty(fdaten^)[int2]} do begin + if fontcolor = po1 then begin + fontcolor:= pointer(int1); + end; + if colorbackground = po1 then begin + colorbackground:= pointer(int1); + end; + end; + end; + inc(po1); + end; + setlength(fcolors,length(fcolors)+1); + po1:= pointer(fcolors); + for int1:= 1 to length(fcolors) do begin + for int2:= 0 to fcount-1 do begin + with pcharstylety(getitempo(int2))^{licharstylearty(fdaten^)[int2]} do begin + if fontcolor = pointer(int1) then begin + fontcolor:= po1; + end; + if colorbackground = pointer(int1) then begin + colorbackground:= po1; + end; + end; + end; + inc(po1); + end; + fcolors[high(fcolors)]:= col1; + result:= @fcolors[high(fcolors)]; + *) + end; + end; + +var + lstr1: lstringty; + str1,str2,str3: string; + st: charstylety; +begin + fillchar(st,sizeof(charstylety),0); + stringtolstring(value,lstr1); + nextquotedstring(lstr1,str1); + nextword(lstr1,str2); + nextword(lstr1,str3); + str1:= struppercase(str1); + if strlscan(pointer(str1),'B',length(str1)) <> nil then begin + include(st.fontstyle,fs_bold); + end; + if strlscan(pointer(str1),'I',length(str1)) <> nil then begin + include(st.fontstyle,fs_italic); + end; + if strlscan(pointer(str1),'U',length(str1)) <> nil then begin + include(st.fontstyle,fs_underline); + end; + if strlscan(pointer(str1),'S',length(str1)) <> nil then begin + include(st.fontstyle,fs_strikeout); + end; + st.fontcolor:= getcolor(str2); + st.colorbackground:= getcolor(str3); + result:= add(st); +end; + +function tcharstyledatalist.Getitems(index: integer): charstylety; +begin + internalgetdata(index,result); +// checkindex(index); +// result:= licharstylearty(fdaten^)[index]; +end; + +procedure tcharstyledatalist.Setitems(index: integer; const Value: charstylety); +begin + internalsetdata(index,value); +// checkindex(index); +// licharstylearty(fdaten^)[index]:= value; +end; + +procedure tcharstyledatalist.clear; +begin + inherited; +// fcolors:= nil; +end; + +{ trichstringdatalist } + +constructor trichstringdatalist.create; +begin + inherited; + fsize:= sizeof(richstringty); +end; + +procedure trichstringdatalist.freedata(var data); +begin + inherited; + richstringty(data).format:= nil; +end; + +procedure trichstringdatalist.aftercopy(var data); +begin + inherited; + reallocarray(richstringty(data).format,sizeof(richstringty(data).format[0])); +end; + +function trichstringdatalist.add(const value: msestring): integer; +var + ristr1: richstringty; +begin + ristr1.text:= value; + ristr1.format:= nil; + ristr1.flags:= []; + result:= adddata(ristr1); +end; + +function trichstringdatalist.add(const avalue: msestring; + const anoparagraph: boolean): integer; +begin + result:= inherited add(avalue,anoparagraph); + if anoparagraph then begin + noparagraphs[result]:= true; + end; +end; + +procedure trichstringdatalist.insert(const index: integer; const item: msestring); +var + ristr1: richstringty; +begin + ristr1.text:= item; + ristr1.format:= nil; + ristr1.flags:= []; + insertdata(index,ristr1); +end; + +function trichstringdatalist.compare(const l,r): integer; +begin + result:= msecomparestr(richstringty(l).text,richstringty(r).text); +end; + +function trichstringdatalist.getformatpo(index: integer): pformatinfoarty; +begin + checkindex(index); + result:= @prichstringty(fdatapo+index*sizeof(richstringty))^.format; +end; + +function trichstringdatalist.getparagraph(const index: integer; + const aseparator: msestring = ''): msestring; +var + int1,int2: integer; + start{,stop}: integer; +begin + start:= index; + while start >= 0 do begin + int2:= start; + checkindex(int2); + if not (rf_noparagraph in + prichstringty(fdatapo+int2*sizeof(richstringty))^.flags) then begin + break; + end; + dec(start); + end; + int2:= start; + checkindex(int2); + result:= prichstringty(fdatapo+int2*sizeof(richstringty))^.text; + for int1:= start+1 to count-1 do begin + int2:= int1; + checkindex(int2); + with prichstringty(fdatapo+int2*sizeof(richstringty))^ do begin + if not (rf_noparagraph in flags) then begin + break; + end; + result:= result + aseparator + text; + end; + end; +end; + +function trichstringdatalist.Getformats(index: integer): formatinfoarty; +begin + checkindex(index); + result:= prichstringty(fdatapo+index*sizeof(richstringty))^.format; +end; + +procedure trichstringdatalist.Setformats(index: integer; + const Value: formatinfoarty); +begin + checkindex(index); +// prichstringty(fdatapo+index*sizeof(richstringty))^.format:= uniqueformatinfoarty(value); + prichstringty(fdatapo+index*sizeof(richstringty))^.format:= copy(value); +end; + +function trichstringdatalist.getnoparagraphs(index: integer): boolean; +begin + checkindex(index); + result:= rf_noparagraph in + prichstringty(fdatapo+index*sizeof(richstringty))^.flags; +end; + +procedure trichstringdatalist.setnoparagraphs(index: integer; + const avalue: boolean); +begin + checkindex(index); + if avalue then begin + include(prichstringty(fdatapo+index*sizeof(richstringty))^.flags, + rf_noparagraph); + end + else begin + exclude(prichstringty(fdatapo+index*sizeof(richstringty))^.flags, + rf_noparagraph); + end; +end; + +function trichstringdatalist.getrichitems(index: integer): richstringty; +begin + checkindex(index); + result:= prichstringty(fdatapo+index*sizeof(richstringty))^; +end; + +procedure trichstringdatalist.setrichitems(index: integer; const Value: richstringty); +var + po1: prichstringty; +begin + checkindex(index); + po1:= prichstringty(fdatapo+index*sizeof(richstringty)); + po1^.text:= value.text; + po1^.format:= copy(value.format); +// prichstringty(fdatapo+index*sizeof(richstringty))^:= uniquerichstringty(value); +end; + +function trichstringdatalist.getrichitemspo(index: integer): prichstringty; +begin + checkindex(index); + result:= prichstringty(fdatapo+index*sizeof(richstringty)); +end; + +procedure trichstringdatalist.setasarray(const data: richstringarty); +begin + internalsetasarray(pointer(data),sizeof(richstringty),length(data)); +end; + +function trichstringdatalist.getasarray: richstringarty; +begin + result:= nil; + allocuninitedarray(fcount,sizeof(result[0]),result); +// setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(richstringty)); +end; + +procedure trichstringdatalist.setasmsestringarray(const data: msestringarty); +var + po1: prichstringty; + int1: integer; + s1: integer; +begin + newbuffer(length(data),true,true); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.text:= data[int1]; + po1^.format:= nil; + po1^.flags:= []; + inc(pchar(po1),s1); + end; + change(-1); +end; + +function trichstringdatalist.getasmsestringarray: msestringarty; +var + po1: prichstringty; + int1: integer; +begin + setlength(result,fcount); + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.text; + inc(po1); + end; +end; + +function trichstringdatalist.nextword(out value: lmsestringty): boolean; +var + po1: pmsechar; + int1: integer; +begin + if fposition.Y >= fcount then begin + result:= false; + value.po:= nil; + value.len:= 0; + end + else begin + with prichstringty(fdatapo+fposition.y*sizeof(richstringty))^ do begin + int1:= length(text) - fposition.X; + if int1 > 0 then begin + value.po:= msestrlnscan(@text[fposition.x+1],' ',int1); + end + else begin + value.po:= nil; + end; + if value.po = nil then begin + result:= true; + value.len:= 0; + inc(fposition.Y); + fposition.X:= 0; + end + else begin + result:= false; + int1:= length(text)-(value.po - pmsechar(pointer(text))); + po1:= msestrlscan(value.po,' ',int1); + if po1 = nil then begin + value.len:= int1; + end + else begin + value.len:= po1-value.po; + end; + fposition.X:= (value.po - pmsechar(pointer(text))) + value.len; + end; + end; + end; +end; +{ +procedure trichstringdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + if source is tpoorstringdatalist then begin + tpoorstringdatalist1(source).assigntodata(self); + end + else begin + inherited; + end; + end; +end; +} +procedure trichstringdatalist.setstatdata(const index: integer; const value: msestring); +var + po1: prichstringty; +begin + po1:= getitempo(index); + po1^.text:= value; + po1^.format:= nil; +end; + +function trichstringdatalist.getstatdata(const index: integer): msestring; +begin + result:= items[index]; +end; + +initialization + hotkeyfontstylesadd:= [fs_underline]; + hotkeyfontstylesremove:= []; + hotkeycolor:= cl_none; + hotkeycolorbackground:= cl_none; +end. diff --git a/mseide-msegui/lib/common/kernel/mserttistat.pas b/mseide-msegui/lib/common/kernel/mserttistat.pas new file mode 100644 index 0000000..c9aa449 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mserttistat.pas @@ -0,0 +1,1446 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mserttistat; +{$ifdef FPC} + {$mode objfpc}{$h+} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,msestat,msestatfile,msestrings,typinfo,msetypes, + msehash,msemacros; + +type + objectinfoty = record + obj: tobject; + prefix: string; + end; + objectinfoarty = array of objectinfoty; + + getobjecteventty = procedure(const sender: tobject; + var aobject: tobject) of object; + getobjectseventty = procedure(const sender: tobject; + var aobjects: objectinfoarty) of object; + +{$M+} //toptions and toptionsclass needs RTTI + + toptions = class(tobject) + protected + function gett: tobject; virtual; + function gettexp: tobject; virtual; + procedure dostatupdate(const filer: tstatfiler); virtual; + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure change() virtual; + public + destructor destroy; override; + procedure readstat(const reader: tstatreader; const prefix: string); + procedure writestat(const writer: tstatwriter; const prefix: string); + {$ifdef mse_with_ifi} + procedure storevalues(const asource: tmsecomponent; + const prefix: string = '') virtual; + procedure loadvalues(const adest: tmsecomponent; + const prefix: string = '') virtual; + {$endif} + procedure expandmacros(const amacrolist: tmacrolist); overload; + procedure expandmacros(const macros: macroinfoarty; + const options: macrooptionsty = + [mao_caseinsensitive]); overload; + procedure expandmacros(const anames,avalues: array of msestring; + const options: macrooptionsty = + [mao_caseinsensitive]); overload; + end; + + tcustomrttistat = class(tmsecomponent,istatfile) + private + fstatfile: tstatfile; + fstatvarname: msestring; + fongetobject: getobjecteventty; + fongetobjects: getobjectseventty; + fonstatupdate: statupdateeventty; + fonstatread: statreadeventty; + fonstatwrite: statwriteeventty; + fonstatbeforeread: notifyeventty; + fonstatafterread: notifyeventty; + {$ifdef mse_with_ifi} + ftargets: tpointeransistringhashdatalist; + {$endif} + fstatpriority: integer; + procedure setstatfile(const avalue: tstatfile); + protected + function getobj(out aobj: objectinfoarty): boolean; + {$ifdef mse_with_ifi} + function findtarget(const aname: string): tobject; + procedure scantargets(const aroot: tcomponent); + {$endif} + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + procedure readstat(const areader: tstatreader); + procedure writestat(const awriter: tstatwriter); + {$ifdef mse_with_ifi} + procedure valuestoobj(const sourceroot: tcomponent); + //reads values from components with matching property-component names + //or statvarnames + procedure objtovalues(const destroot: tcomponent); + //writes values to components with matching property-component names + //or statvarnames + {$endif} + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read fstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property ongetobject: getobjecteventty read fongetobject write fongetobject; + property ongetobjects: getobjectseventty read fongetobjects + write fongetobjects; + property onstatupdate: statupdateeventty read fonstatupdate + write fonstatupdate; + property onstatread: statreadeventty read fonstatread + write fonstatread; + property onstatwrite: statwriteeventty read fonstatwrite + write fonstatwrite; + property onstatbeforeread: notifyeventty read fonstatbeforeread + write fonstatbeforeread; + property onstatafterread: notifyeventty read fonstatafterread + write fonstatafterread; + end; + + trttistat = class(tcustomrttistat) + protected + published + property statfile; + property statvarname; + property statpriority; + property ongetobject; + property ongetobjects; + property onstatupdate; + property onstatread; + property onstatwrite; + property onstatbeforeread; + property onstatafterread; + end; + +function opentodynarray(const objs: array of tobject; + const prefixes: array of string): objectinfoarty; +function getmsestringar(const aobj: tobject; + const aprop: ppropinfo): msestringarty; +procedure setmsestringar(const aobj: tobject; const aprop: ppropinfo; + const avalue: msestringarty); +procedure addobjectinfoitem(var dest: objectinfoarty; const aobj: tobject; + const aprefix: string = ''); + +{$ifdef mse_with_ifi} +procedure objecttovalues(const source: tobject; const dest: tmsecomponent; + const prefix: string = ''); +procedure valuestoobject(const source: tmsecomponent; const dest: tobject; + const prefix: string = ''); +{$endif} +function dupplicateobject(const source: tobject): tobject; +function dupplicateobjects(const source: objectarty): objectarty; + +implementation +uses + {$ifdef mse_with_ifi}mseificompglob,{$endif}msedatalist,sysutils,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + dynarraysetter = procedure(const avalue: pointerarty) of object; + //dummy type + dynarraygetter = function: pointerarty of object; + //dummy type + +procedure addobjectinfoitem(var dest: objectinfoarty; const aobj: tobject; + const aprefix: string = ''); +begin + setlength(dest,high(dest)+2); + with dest[high(dest)] do begin + obj:= aobj; + prefix:= aprefix; + end; +end; + +function opentodynarray(const objs: array of tobject; + const prefixes: array of string): objectinfoarty; +var + int1: integer; +begin + setlength(result,length(objs)); + for int1:= 0 to high(result) do begin + with result[int1] do begin + obj:= objs[int1]; + if int1 <= high(prefixes) then begin + prefix:= prefixes[int1]; + end; + end; + end; +end; +{$ifndef FPC} +const + ptmask = $FF000000; + ptfield = $FF000000; + ptvirtual = $FE000000; +{$endif} + +function getdynarray(const aobj: tobject; const aprop: ppropinfo): pointer; +var + getterkind: integer; + meth1: tmethod; +begin +{$ifdef FPC} + getterkind:= (aprop^.propprocs) and 3; +{$else} + getterkind:= ptruint(aprop^.getproc) and ptmask; +{$endif} + case getterkind of + ptfield: begin + {$ifdef FPC} + result:= ppointer(pointer(aobj) + ptruint(aprop^.getproc))^; + {$else} + result:= ppointer(pchar(aobj) + (ptruint(aprop^.getproc) and not ptmask))^; + {$endif} + exit; + end; + ptvirtual: begin + {$ifdef FPC} + meth1.code:= ppointer(pointer(aobj.classtype) + + ptruint(aprop^.getproc))^; + {$else} + meth1.code:= ppointer(pchar(aobj) + smallint(ptrint(aprop^.getproc)))^; + {$endif} + end; + {$ifdef FPC} + ptstatic: begin + {$else} + else begin + {$endif} + meth1.code:= aprop^.getproc; + end; + {$ifdef FPC} + else begin + result:= nil; + exit; + end; + {$endif} + end; + meth1.data:= aobj; + result:= pointer(dynarraygetter(meth1)()); +end; + +function setdynarray(const aobj: tobject; const aprop: ppropinfo; + const avalue: pointer): pointer; + // returns valuebefore for finalize +var + setterkind: integer; + meth1: tmethod; +begin +{$ifdef FPC} + setterkind:= (aprop^.propprocs shr 2) and 3; +{$else} + setterkind:= ptruint(aprop^.setproc) and ptmask; +{$endif} + result:= nil; + case setterkind of + ptfield: begin + arrayaddref((@avalue)^); + result:= getdynarray(aobj,aprop); + {$ifdef FPC} + ppointer(pointer(aobj) + ptruint(aprop^.setproc))^:= avalue; + {$else} + ppointer(pchar(aobj) + (ptruint(aprop^.setproc) and not ptmask))^:= avalue; + {$endif} + exit; + end; + ptvirtual: begin + {$ifdef FPC} + meth1.code:= ppointer(pointer(aobj.classtype) + + ptruint(aprop^.setproc))^; + {$else} + meth1.code:= ppointer(pchar(aobj) + smallint(ptrint(aprop^.setproc)))^; + {$endif} + end; + {$ifdef FPC} + ptstatic: begin + {$else} + else begin + {$endif} + meth1.code:= aprop^.setproc; + end; + {$ifdef FPC} + else begin + result:= nil; + exit; + end; + {$endif} + end; + meth1.data:= aobj; + dynarraysetter(meth1)(avalue); +end; + +function getintegerar(const aobj: tobject; const aprop: ppropinfo): integerarty; +begin + result:= integerarty(getdynarray(aobj,aprop)); +end; + +{$notes off} //avoid "never used" +procedure setintegerar(const aobj: tobject; const aprop: ppropinfo; + const avalue: integerarty); +var + ar1: integerarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes on} + +function getint64ar(const aobj: tobject; const aprop: ppropinfo): int64arty; +begin + result:= int64arty(getdynarray(aobj,aprop)); +end; + +{$notes off} //avoid "never used" +procedure setint64ar(const aobj: tobject; const aprop: ppropinfo; + const avalue: int64arty); +var + ar1: int64arty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes off} + +function getrealar(const aobj: tobject; const aprop: ppropinfo): realarty; +begin + result:= realarty(getdynarray(aobj,aprop)); +end; + +procedure setrealar(const aobj: tobject; const aprop: ppropinfo; + const avalue: realarty); +var + ar1: realarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; + +function getmsestringar(const aobj: tobject; + const aprop: ppropinfo): msestringarty; +begin + result:= msestringarty(getdynarray(aobj,aprop)); +end; + +function getwidestringar(const aobj: tobject; + const aprop: ppropinfo): widestringarty; +begin + result:= widestringarty(getdynarray(aobj,aprop)); +end; + +{$notes off} //avoid "never used" +procedure setmsestringar(const aobj: tobject; const aprop: ppropinfo; + const avalue: msestringarty); +var + ar1: msestringarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes on} + +{$notes off} //avoid "never used" +procedure setwidestringar(const aobj: tobject; const aprop: ppropinfo; + const avalue: widestringarty); +var + ar1: widestringarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes on} + +function getstringar(const aobj: tobject; + const aprop: ppropinfo): stringarty; +begin + result:= stringarty(getdynarray(aobj,aprop)); +end; + +{$notes off} //avoid "never used" +procedure setstringar(const aobj: tobject; const aprop: ppropinfo; + const avalue: stringarty); +var + ar1: stringarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes on} + +function getbooleanar(const aobj: tobject; + const aprop: ppropinfo): booleanarty; +begin + result:= booleanarty(getdynarray(aobj,aprop)); +end; + +{$notes off} //avoid "never used" +procedure setbooleanar(const aobj: tobject; const aprop: ppropinfo; + const avalue: booleanarty); +var + ar1: booleanarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes on} + +procedure readobjectstat(const reader: tstatreader; const aobj: objectinfoty); +var + ar1: propinfopoarty; + po1: ppropinfo; + po2: ptypeinfo; + po3: ptypedata; + int1: integer; + obj1: tobject; + info1: objectinfoty; +// intf1: istatfile; +// intar: integerarty; +// realar: realarty; + mstr1: msestring; +begin + with aobj do begin + ar1:= getpropinfoar(obj); + for int1 := 0 to high(ar1) do begin + po1:= ar1[int1]; + with po1^ do begin + mstr1:= msestring(prefix+name); + case proptype^.kind of + tkInteger,tkChar,tkEnumeration,tkWChar,tkSet: begin + setordprop(obj,po1,reader.readinteger(mstr1,getordprop(obj,po1))); + end; + tkint64: begin + setint64prop(obj,po1,reader.readint64(mstr1,getint64prop(obj,po1))); + end; + tkfloat: begin + setfloatprop(obj,po1,reader.readreal(mstr1,getfloatprop(obj,po1), + emptyreal,1e300)); + end; + {$ifdef FPC} + tkbool: begin + setordprop(obj,po1, +// ord(longbool(reader.readboolean(mstr1,getordprop(obj,po1) <> 0)))); + ord(reader.readboolean(mstr1,getordprop(obj,po1) <> 0))); + end; + {$endif} + tkwstring: begin + setwidestrprop(obj,po1,reader.readmsestring( + mstr1,getwidestrprop(obj,po1))); + end; + {$ifdef FPC} + tkustring: begin + setunicodestrprop(obj,po1,reader.readmsestring( + mstr1,getunicodestrprop(obj,po1))); + end; + {$endif} + {$ifdef FPC}tkastring,{$endif}tklstring,tkstring: begin + setstrprop(obj,po1,reader.readbinarystring(mstr1,getstrprop(obj,po1))); + end; + //how to reach fpc_DecRef? + tkdynarray: begin + {$ifdef FPC} + po2:= pointer(gettypedata(proptype)^.eltype2); + //wrong define in ttypedata + {$else} + po2:= gettypedata(proptype^)^.eltype2^; + {$endif} + po3:= gettypedata(po2); + case po2^.kind of + tkinteger: begin + setintegerar(obj,po1,reader.readarray(mstr1,getintegerar(obj,po1))); + end; + tkint64: begin + setint64ar(obj,po1,reader.readarray(mstr1,getint64ar(obj,po1))); + end; + tkfloat: begin + if po3^.floattype = ftdouble then begin + setrealar(obj,po1,reader.readarray(mstr1,getrealar(obj,po1))); + end; + end; + tkwstring: begin + setwidestringar(obj,po1,reader.readarray(mstr1,getwidestringar(obj,po1))); + end; + {$ifdef FPC}tkastring{$else}tklstring{$endif}: begin + setstringar(obj,po1,reader.readarray(mstr1,getstringar(obj,po1))); + end; + {$ifdef FPC} + tkustring: begin + setmsestringar(obj,po1,reader.readarray(mstr1,getmsestringar(obj,po1))); + end; + {$endif} + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + setbooleanar(obj,po1,reader.readarray(mstr1,getbooleanar(obj,po1))); + end; + end; + end; + tkclass: begin + obj1:= tobject(ptruint(getordprop(obj,po1))); + if obj1 is tdatalist then begin + reader.readdatalist(mstr1,tdatalist(obj1)); + end + else begin + info1.obj:= obj1; + info1.prefix:= aobj.prefix; + readobjectstat(reader,info1); + end; + end; + end; + end; + end; + end; +end; + +procedure writeobjectstat(const writer: tstatwriter; const aobj: objectinfoty); +var + ar1: propinfopoarty; + po1: ppropinfo; + po2: ptypeinfo; + po3: ptypedata; + int1: integer; + obj1: tobject; + mstr1: msestring; + info1: objectinfoty; +begin + with aobj do begin + ar1:= getpropinfoar(obj); + for int1 := 0 to high(ar1) do begin + po1:= ar1[int1]; + with po1^ do begin + mstr1:= msestring(prefix+name); + case proptype^.kind of + tkInteger,tkChar,tkEnumeration,tkWChar,tkSet: begin + writer.writeinteger(mstr1,getordprop(obj,po1)); + end; + tkint64: begin + writer.writeint64(mstr1,getint64prop(obj,po1)); + end; + tkfloat: begin + writer.writereal(mstr1,getfloatprop(obj,po1)); + end; + {$ifdef FPC} + tkbool: begin + writer.writeboolean(mstr1,getordprop(obj,po1) <> 0); + end; + tkustring: begin + writer.writemsestring(mstr1,getunicodestrprop(obj,po1)); + end; + {$endif} + tkwstring: begin + writer.writemsestring(mstr1,getwidestrprop(obj,po1)); + end; + {$ifdef FPC}tkastring,{$endif}tklstring,tkstring: begin + writer.writebinarystring(mstr1,getstrprop(obj,po1)); + end; + tkdynarray: begin + {$ifdef FPC} + po2:= pointer(gettypedata(proptype)^.eltype2); + //wrong define in ttypedata + {$else} + po2:= gettypedata(proptype^)^.eltype2^; + {$endif} + po3:= gettypedata(po2); + case po2^.kind of + tkinteger: begin + writer.writearray(mstr1,getintegerar(obj,po1)); + end; + tkint64: begin + writer.writearray(mstr1,getint64ar(obj,po1)); + end; + tkfloat: begin + if po3^.floattype = ftdouble then begin + writer.writearray(mstr1,getrealar(obj,po1)); + end; + end; + {$ifdef FPC}tkastring{$else}tklstring{$endif}: begin + writer.writearray(mstr1,getstringar(obj,po1)); + end; + {$ifdef FPC} + tkustring: begin + writer.writearray(mstr1,getmsestringar(obj,po1)); + end; + {$endif} + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + writer.writearray(mstr1,getbooleanar(obj,po1)); + end; + end; + end; + tkclass: begin + obj1:= tobject(ptruint(getordprop(obj,po1))); + if obj1 is tdatalist then begin + writer.writedatalist(mstr1,tdatalist(obj1)); + end + else begin + info1.obj:= obj1; + info1.prefix:= aobj.prefix; + writeobjectstat(writer,info1); + end; + end; + end; + end; + end; + end; +end; + +{$ifdef mse_with_ifi} +type + findtargetty = function(const aname: string): tobject of object; + +procedure valuestoobject(const dest: objectinfoty; + const findtarget: findtargetty); +var + comp1: tobject; + ar1: propinfopoarty; + po1,po4: ppropinfo; + po2: ptypeinfo; + int1: integer; + intf1: iifidatalink; + obj1: tobject; + info1: objectinfoty; + bo1: boolean; + list1: tdatalist; +begin + obj1:= nil; + ar1:= getpropinfoar(dest.obj); + for int1 := 0 to high(ar1) do begin + po1:= ar1[int1]; + with po1^ do begin + bo1:= true; + if po1^.proptype^.kind = tkclass then begin + obj1:= tobject(ptruint(getordprop(dest.obj,po1))); + if not (obj1 is tdatalist) then begin + bo1:= false; + info1.obj:= obj1; + info1.prefix:= dest.prefix; + valuestoobject(info1,findtarget); + end; + end; + if bo1 then begin + comp1:= findtarget(dest.prefix+name); + if (comp1 <> nil) and + mseclasses.getcorbainterface(comp1,typeinfo(iifidatalink), + intf1) then begin + po4:= intf1.getvalueprop; + if po4 <> nil then begin + case proptype^.kind of + tkInteger,tkChar,tkEnumeration,tkWChar,tkSet: begin + if po4^.proptype^.kind in + [tkInteger,tkChar,tkEnumeration,tkWChar,tkSet] then begin + setordprop(dest.obj,po1,getordprop(comp1,po4)); + end + else begin + if po4^.proptype^.kind in [tkustring] then begin + setordprop(dest.obj,po1,ord(pmsechar(getunicodestrprop(comp1,po4))^)); + end + else begin + if po4^.proptype^.kind in [tkastring,tklstring,tkstring] then begin + setordprop(dest.obj,po1,ord(pchar(getstrprop(comp1,po4))^)); + end; + end; + end; + end; + tkint64: begin + if po4^.proptype^.kind in + [tkint64] then begin + setint64prop(dest.obj,po1,getint64prop(comp1,po4)); + end; + end; + tkfloat: begin + if po4^.proptype^.kind in + [tkfloat] then begin + setfloatprop(dest.obj,po1,getfloatprop(comp1,po4)); + end; + end; + {$ifdef FPC} + tkbool: begin + if po4^.proptype^.kind in + [tkbool] then begin + setordprop(dest.obj,po1,getordprop(comp1,po4)); + end; + end; + tkustring: begin + if po4^.proptype^.kind in [tkustring] then begin + setunicodestrprop(dest.obj,po1,getunicodestrprop(comp1,po4)); + end; + end; + {$endif} + tkwstring: begin + {$ifdef FPC} + if po4^.proptype^.kind = tkustring then begin + setwidestrprop(dest.obj,po1,getunicodestrprop(comp1,po4)); + end; + {$else} + if po4^.proptype^.kind = tkwstring then begin + setwidestrprop(dest.obj,po1,getwidestrprop(comp1,po4)); + end; + {$endif} + end; + tkastring,tklstring,tkstring: begin + if po4^.proptype^.kind = tkustring then begin + setstrprop(dest.obj,po1,ansistring(getunicodestrprop(comp1,po4))); + end + else begin + if po4^.proptype^.kind in [tkastring,tklstring,tkstring] then begin + setstrprop(dest.obj,po1,getstrprop(comp1,po4)); + end; + end; + end; + tkclass: begin + list1:= intf1.getgriddata; + if list1 <> nil then begin + tdatalist(obj1).assign(list1); + end; + end; + tkdynarray: begin + list1:= intf1.getgriddata; + if list1 <> nil then begin + {$ifdef FPC} + po2:= pointer(gettypedata(proptype)^.eltype2); + //wrong define in ttypedata + {$else} + po2:= gettypedata(proptype^)^.eltype2^; + {$endif} + case po2^.kind of + tkinteger: begin + if list1 is tintegerdatalist then begin + setintegerar(dest.obj,po1,tintegerdatalist(list1).asarray); + end; + end; + tkint64: begin + if list1 is tint64datalist then begin + setint64ar(dest.obj,po1,tint64datalist(list1).asarray); + end; + end; + tkfloat: begin + if list1 is trealdatalist then begin + setrealar(dest.obj,po1,trealdatalist(list1).asarray); + end; + end; + {$ifdef FPC}tkustring{$else}tkwstring{$endif}: begin + if list1 is tpoorstringdatalist then begin + setmsestringar(dest.obj,po1,tpoorstringdatalist(list1).asarray); + end; + end; + {$ifdef FPC}tkastring{$else}tklstring{$endif}: begin + if list1 is tansistringdatalist then begin + setstringar(dest.obj,po1,tansistringdatalist(list1).asarray); + end; + end; + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + if list1 is tintegerdatalist then begin + setbooleanar(dest.obj,po1,tintegerdatalist(list1).asbooleanarray); + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure objecttovalues(const source: objectinfoty; + const findtarget: findtargetty); +var + comp1: tobject; + ar1: propinfopoarty; + po1,po4: ppropinfo; + po2: ptypeinfo; + po3: ptypedata; + int1: integer; + i2: int32; + intf1: iifidatalink; + obj1: tobject; + list1: tdatalist; + bo1: boolean; + info1: objectinfoty; +begin + obj1:= nil; + ar1:= getpropinfoar(source.obj); + for int1 := 0 to high(ar1) do begin + po1:= ar1[int1]; + with po1^ do begin + bo1:= true; + if po1^.proptype^.kind = tkclass then begin + obj1:= tobject(ptruint(getordprop(source.obj,po1))); + if not (obj1 is tdatalist) then begin + bo1:= false; + info1.obj:= obj1; + info1.prefix:= source.prefix; + objecttovalues(info1,findtarget); + end; + end; + if bo1 then begin + comp1:= findtarget(source.prefix+name); + if (comp1 <> nil) and + mseclasses.getcorbainterface(comp1,typeinfo(iifidatalink), + intf1) then begin + po4:= intf1.getvalueprop; + if po4 <> nil then begin + case proptype^.kind of + tkInteger,tkChar,tkEnumeration,tkWChar,tkSet: begin + if po4^.proptype^.kind in + [tkInteger,tkChar,tkEnumeration,tkWChar,tkSet] then begin + setordprop(comp1,po4,getordprop(source.obj,po1)); + end + else begin + if proptype^.kind in [tkchar,tkwchar] then begin + if po4^.proptype^.kind in [tkastring,tklstring,tkstring] then begin + setstrprop(comp1,po4,char(getordprop(source.obj,po1))); + end + else begin + if po4^.proptype^.kind in [tkustring] then begin + setunicodestrprop(comp1,po4,widechar(getordprop(source.obj,po1))); + end; + end; + end; + end; + end; + tkint64: begin + if po4^.proptype^.kind in + [tkint64] then begin + setint64prop(comp1,po4,getint64prop(source.obj,po1)); + end; + end; + tkfloat: begin + if po4^.proptype^.kind in + [tkfloat] then begin + setfloatprop(comp1,po4,getfloatprop(source.obj,po1)); + end; + end; + {$ifdef FPC} + tkbool: begin + if po4^.proptype^.kind in + [tkbool] then begin + setordprop(comp1,po4,getordprop(source.obj,po1)); + end; + end; + tkustring: begin + if po4^.proptype^.kind in [tkustring] then begin + setunicodestrprop(comp1,po4,getunicodestrprop(source.obj,po1)); + end; + end; + {$endif} + tkwstring: begin + {$ifdef FPC} + if po4^.proptype^.kind = tkustring then begin + setunicodestrprop(comp1,po4,getwidestrprop(source.obj,po1)); + end; + {$else} + if po4^.proptype^.kind = tkwstring then begin + setwidestrprop(comp1,po4,getwidestrprop(source.obj,po1)); + end; + {$endif} + end; + tkastring,tklstring,tkstring: begin + if po4^.proptype^.kind = tkustring then begin + setunicodestrprop(comp1,po4,unicodestring(getstrprop(source.obj,po1))); + end + else begin + if po4^.proptype^.kind in [tkastring,tklstring,tkstring] then begin + setstrprop(comp1,po4,getstrprop(source.obj,po1)); + end; + end; + end; + tkdynarray: begin + list1:= intf1.getgriddata; + if list1 <> nil then begin + {$ifdef FPC} + po2:= pointer(gettypedata(proptype)^.eltype2); + //wrong define in ttypedata + {$else} + po2:= gettypedata(proptype^)^.eltype2^; + {$endif} + po3:= gettypedata(po2); + list1.beginupdate(); + try + i2:= list1.count; + case po2^.kind of + tkinteger: begin + if list1 is tintegerdatalist then begin + tintegerdatalist(list1).asarray:= getintegerar(source.obj,po1); + end; + end; + tkint64: begin + if list1 is tint64datalist then begin + tint64datalist(list1).asarray:= getint64ar(source.obj,po1); + end; + end; + tkfloat: begin + if (po3^.floattype = ftdouble) and (list1 is trealdatalist) then begin + trealdatalist(list1).asarray:= getrealar(source.obj,po1); + end; + end; + {$ifdef FPC}tkustring{$else}tkwstring{$endif}: begin + if list1 is tpoorstringdatalist then begin + tpoorstringdatalist(list1).asarray:= getmsestringar(source.obj,po1); + end; + end; + {$ifdef FPC}tkastring{$else}tklstring{$endif}: begin + if list1 is tansistringdatalist then begin + tansistringdatalist(list1).asarray:= getstringar(source.obj,po1); + end; + end; + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + if list1 is tintegerdatalist then begin + tintegerdatalist(list1).asbooleanarray:= getbooleanar(source.obj,po1); + end; + end; + end; + if (i2 > list1.count) and list1.facultative then begin + list1.count:= i2; + end; + finally + list1.endupdate(); + end; + end; + end; + tkclass: begin + list1:= intf1.getgriddata; + if list1 <> nil then begin + list1.assign(tdatalist(obj1)); + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function dupplicateobject(const source: tobject): tobject; +var + ar1: propinfopoarty; + po1: ppropinfo; + po2: ptypeinfo; + int1: integer; + obj1: tobject; +begin + result:= source.classtype.create(); + ar1:= getpropinfoar(source); + for int1 := 0 to high(ar1) do begin + po1:= ar1[int1]; + with po1^ do begin + case po1^.proptype^.kind of + tkclass: begin + obj1:= tobject(ptruint(getordprop(source,po1))); + setordprop(result,po1,ptruint(obj1)); + end; + tkInteger,tkChar,tkEnumeration,tkWChar,tkSet,tkbool: begin + setordprop(result,po1,getordprop(source,po1)); + end; + tkint64: begin + setint64prop(result,po1,getint64prop(source,po1)); + end; + tkfloat: begin + setfloatprop(result,po1,getfloatprop(source,po1)); + end; + tkustring: begin + setunicodestrprop(result,po1,getunicodestrprop(source,po1)); + end; + tkwstring: begin + setwidestrprop(result,po1,getwidestrprop(source,po1)); + end; + tkastring,tklstring,tkstring: begin + setstrprop(result,po1,getstrprop(source,po1)); + end; + tkdynarray: begin + po2:= pointer(gettypedata(proptype)^.eltype2); + //wrong define in ttypedata + case po2^.kind of + tkinteger: begin + setintegerar(result,po1,getintegerar(source,po1)); + end; + tkint64: begin + setint64ar(result,po1,getint64ar(source,po1)); + end; + tkfloat: begin + setrealar(result,po1,getrealar(source,po1)); + end; + tkustring: begin + setmsestringar(result,po1,getmsestringar(source,po1)); + end; + tkastring: begin + setstringar(result,po1,getstringar(source,po1)); + end; + tkbool: begin + setbooleanar(result,po1,getbooleanar(source,po1)); + end; + end; + end; + end; + end; + end; +end; + +function dupplicateobjects(const source: objectarty): objectarty; +var + i1: int32; +begin + setlength(result,length(source)); + for i1:= 0 to high(result) do begin + result[i1]:= dupplicateobject(source[i1]); + end; +end; + +type + tfindtarg = class + private + fowner: tmsecomponent; + function findcomponenttarget(const aname: string): tobject; + end; + +function tfindtarg.findcomponenttarget(const aname: string): tobject; +begin + result:= fowner.findcomponent(aname); +end; + +procedure valuestoobject(const source: tmsecomponent; const dest: tobject; + const prefix: string = ''); +var + findtarg: tfindtarg; + objinfo: objectinfoty; +begin + objinfo.obj:= dest; + objinfo.prefix:= prefix; + findtarg:= tfindtarg.create(); + try + findtarg.fowner:= source; + valuestoobject(objinfo,@findtarg.findcomponenttarget); + finally + findtarg.destroy(); + end; +end; + +procedure objecttovalues(const source: tobject; const dest: tmsecomponent; + const prefix: string = ''); +var + findtarg: tfindtarg; + objinfo: objectinfoty; +begin + objinfo.obj:= source; + objinfo.prefix:= prefix; + findtarg:= tfindtarg.create(); + try + findtarg.fowner:= dest; + objecttovalues(objinfo,@findtarg.findcomponenttarget); + finally + findtarg.destroy(); + end; +end; + +{$endif} + +{ tcustomrttistat } + +procedure tcustomrttistat.statreading; +var + ar1: objectinfoarty; + intf1: istatfile; + int1: integer; +begin + if assigned(fonstatbeforeread) then begin + fonstatbeforeread(self); + end; + if getobj(ar1) then begin + for int1:= 0 to high(ar1) do begin + if mseclasses.getcorbainterface(ar1[int1].obj,typeinfo(istatfile), + intf1) then begin + intf1.statreading; + end; + end; + end; +end; + +procedure tcustomrttistat.statread; +var + ar1: objectinfoarty; + intf1: istatfile; + int1: integer; +begin + if assigned(fonstatafterread) then begin + fonstatafterread(self); + end; + if getobj(ar1) then begin + for int1:= 0 to high(ar1) do begin + if mseclasses.getcorbainterface(ar1[int1].obj,typeinfo(istatfile), + intf1) then begin + intf1.statread; + end; + end; + end; +end; + +function tcustomrttistat.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +function tcustomrttistat.getobj(out aobj: objectinfoarty): boolean; +var + obj1: tobject; + int1: integer; +begin + obj1:= nil; + aobj:= nil; + if assigned(fongetobject) then begin + fongetobject(self,obj1); + end; + if assigned(fongetobjects) then begin + fongetobjects(self,aobj); + end; + result:= (obj1 <> nil) or (aobj <> nil); + if obj1 <> nil then begin + for int1:= 0 to high(aobj) do begin + if aobj[int1].obj = obj1 then begin + exit; + end; + end; + setlength(aobj,high(aobj)+2); + aobj[high(aobj)].obj:= obj1; + end; +end; + +procedure tcustomrttistat.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tcustomrttistat.dostatread(const reader: tstatreader); +var + obj1: objectinfoarty; + intf1: istatfile; + int1: integer; +begin + if getobj(obj1) then begin + for int1:= 0 to high(obj1) do begin + readobjectstat(reader,obj1[int1]); + with obj1[int1] do begin + if mseclasses.getcorbainterface(obj,typeinfo(istatfile),intf1) then begin + intf1.dostatread(reader); + end; + if obj is toptions then begin + toptions(obj).dostatread(reader); + toptions(obj).change(); + end; + end; + end; + end; + if assigned(fonstatupdate) then begin + fonstatupdate(self,reader); + end; + if assigned(fonstatread) then begin + fonstatread(self,reader); + end; +end; + +procedure tcustomrttistat.dostatwrite(const writer: tstatwriter); +var + obj1: objectinfoarty; + int1: integer; + intf1: istatfile; +begin + if getobj(obj1) then begin + for int1:= 0 to high(obj1) do begin + with obj1[int1] do begin + if obj is toptions then begin + toptions(obj).dostatwrite(writer); + end; + if mseclasses.getcorbainterface(obj1[int1].obj,typeinfo(istatfile), + intf1) then begin + intf1.dostatwrite(writer); + end; + end; + writeobjectstat(writer,obj1[int1]); + end; + end; + if assigned(fonstatupdate) then begin + fonstatupdate(self,writer); + end; + if assigned(fonstatwrite) then begin + fonstatwrite(self,writer); + end; +end; + +procedure tcustomrttistat.readstat(const areader: tstatreader); +begin + dostatread(areader); +end; + +procedure tcustomrttistat.writestat(const awriter: tstatwriter); +begin + dostatwrite(awriter); +end; + +{$ifdef mse_with_ifi} + +function tcustomrttistat.findtarget(const aname: string): tobject; +begin + ftargets.find(aname,pointer(result)); +end; + +procedure tcustomrttistat.scantargets(const aroot: tcomponent); + procedure addcomps(const acomp: tcomponent; prefix: string); + var + intf1: istatfile; + str1: string; + int1: integer; + begin + if acomp <> aroot then begin + if prefix <> '' then begin + prefix:= prefix + '_'; + end; + prefix:= prefix + acomp.name; + end; + for int1:= 0 to acomp.componentcount - 1 do begin + addcomps(acomp.components[int1],prefix); + end; + if (acomp <> aroot) and mseclasses.getcorbainterface(acomp, + typeinfo(istatfile),intf1) then begin + str1:= ansistring(intf1.getstatvarname); + if str1 = '' then begin + str1:= prefix; + end; + ftargets.add(str1,acomp); + end; + end; //addcomps + +begin + ftargets:= tpointeransistringhashdatalist.create; + addcomps(aroot,''); +end; + +procedure tcustomrttistat.valuestoobj(const sourceroot: tcomponent); +var + obj1: objectinfoarty; + int1: integer; +begin + if getobj(obj1) then begin + scantargets(sourceroot); + try + for int1:= 0 to high(obj1) do begin + valuestoobject(obj1[int1],{$ifdef FPC}@{$endif}findtarget); + end; + finally + freeandnil(ftargets); + end; + end; +end; + +procedure tcustomrttistat.objtovalues(const destroot: tcomponent); +var + obj1: objectinfoarty; + int1: integer; +begin + if getobj(obj1) then begin + scantargets(destroot); + try + for int1:= 0 to high(obj1) do begin + objecttovalues(obj1[int1],{$ifdef FPC}@{$endif}findtarget); + end; + finally + freeandnil(ftargets); + end; + end; +end; + +{$endif} + +function tcustomrttistat.getstatpriority: integer; +begin + result:= fstatpriority; +end; + + +{ trttistat } + +{ toptions } + +destructor toptions.destroy; +begin + gett.free; + gettexp.free; + inherited; +end; + +procedure toptions.readstat(const reader: tstatreader; const prefix: string); +var + info1: objectinfoty; +begin + info1.obj:= self; + info1.prefix:= prefix; + readobjectstat(reader,info1); + dostatread(reader); + change(); +end; + +procedure toptions.writestat(const writer: tstatwriter; + const prefix: string); +var + info1: objectinfoty; +begin + info1.obj:= self; + info1.prefix:= prefix; + dostatwrite(writer); + writeobjectstat(writer,info1); +end; + +{$ifdef mse_with_ifi} +procedure toptions.storevalues(const asource: tmsecomponent; + const prefix: string = ''); +begin + valuestoobject(asource,self,prefix); + change(); +end; + +procedure toptions.loadvalues(const adest: tmsecomponent; + const prefix: string = ''); +begin + objecttovalues(self,adest,prefix); +end; +{$endif} + +procedure toptions.dostatread(const reader: tstatreader); +begin + //dummy +end; + +procedure toptions.dostatwrite(const writer: tstatwriter); +begin + //dummy +end; + +procedure toptions.change(); +begin + //dummy +end; + +procedure toptions.dostatupdate(const filer: tstatfiler); +begin + if filer.iswriter then begin + dostatwrite(tstatwriter(filer)); + end + else begin + dostatread(tstatreader(filer)); + end; +end; + +procedure toptions.expandmacros(const amacrolist: tmacrolist); +var + ar1: propinfopoarty; + int1,int2: integer; + po1: ptypedata; + mstr1: msestring; + ar2: msestringarty; + t,texp: tobject; +begin + t:= gett; + texp:= gettexp; + if (t <> nil) and (texp <> nil) then begin + ar1:= getpropinfoar(t); + for int1:= 0 to high(ar1) do begin + po1:= gettypedata(ar1[int1]^.proptype{$ifndef FPC}^{$endif}); + case ar1[int1]^.proptype^.kind of + {$ifdef FPC} + tkustring: begin + mstr1:= getunicodestrprop(t,ar1[int1]); + amacrolist.expandmacros1(mstr1); + setunicodestrprop(texp,ar1[int1],mstr1); + {$else} + tkwstring: begin + mstr1:= getwidestrprop(t,ar1[int1]); + amacrolist.expandmacros(mstr1); + setwidestrprop(texp,ar1[int1],mstr1); + {$endif} + end; + tkdynarray: begin + {$ifdef FPC} + if ptypeinfo(pointer(po1^.eltype2))^.kind = tkustring then begin + //wrong define in ttypedata + {$else} + if po1^.eltype2^^.kind = tkwstring then begin + {$endif} + ar2:= copy(getmsestringar(t,ar1[int1])); + for int2:= 0 to high(ar2) do begin + amacrolist.expandmacros1(ar2[int2]); + end; + setmsestringar(texp,ar1[int1],ar2); + end; + end; + end; + end; + end; +end; + +procedure toptions.expandmacros(const macros: macroinfoarty; + const options: macrooptionsty = + [mao_caseinsensitive]); +var + list: tmacrolist; +begin + list:= tmacrolist.create(options); + try + list.add(macros); + expandmacros(list); + finally + list.free; + end; +end; + +procedure toptions.expandmacros(const anames,avalues: array of msestring; + const options: macrooptionsty = + [mao_caseinsensitive]); +begin + expandmacros(initmacros(anames,avalues,[]),options); +end; + +function toptions.gett: tobject; +begin + result:= nil; +end; + +function toptions.gettexp: tobject; +begin + result:= nil; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msescrollbar.pas b/mseide-msegui/lib/common/kernel/msescrollbar.pas new file mode 100644 index 0000000..1d1bc58 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msescrollbar.pas @@ -0,0 +1,1921 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msescrollbar; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface + +uses + mseguiglob,msegraphics,msegraphutils,msetimer,mseevent,mseshapes, + classes,mclasses,msetypes,msegui,mseclasses,mseglob; + +const + defaultscrollbarwidth = 15; + defaultpagesizeconst = 0.1; + defaultpagesize: real = defaultpagesizeconst; + defaultbuttonminlength = 11;//8; + defaultscrollbarcolorpattern = cl_scrollbarpattern; + defaultscrollbarcolorpatternclicked = cl_scrollbarpatternclicked; + repeatdelaytime = 500000; //0.5s + repeatrepeattime = 100000; //0.1 s + +type + + scrollbarareaty = (sbbu_down,sbbu_move,sbbu_up,sba_start,sba_end); +// buttonareaty = (bbu_down,bbu_move,bbu_up); +const + scrollbarclicked = ord(sba_end) + 1; +// areafrombuttonarea: array[buttonareaty] of scrollbarareaty = +// (sbbu_down,sbbu_move,sbbu_up); + +type + scrollbaroptionty = (sbo_thumbtrack,sbo_clicktovalue, + sbo_moveauto,sbo_showauto,sbo_show, + sbo_opposite,sbo_valuekeys,sbo_noarrowkeys,sbo_nopagekeys, + sbo_noreflectedclick{, + sbo_flat,sbo_noanim}); + //sbo_valuekeys -> pageup = valueincrement + scrollbaroptionsty = set of scrollbaroptionty; + +const + firstbutton = sbbu_down; + lastbutton = sbbu_up; + defaultscrollbaroptions = [sbo_moveauto,sbo_showauto]; + +type + tcustomscrollbar = class; + + scrolleventty = (sbe_none,sbe_valuechanged,sbe_setvalue, + sbe_stepup,sbe_stepdown, + sbe_pageup,sbe_pagedown,sbe_wheelup,sbe_wheeldown, + sbe_thumbposition,sbe_thumbtrack); + + iscrollbar = interface(inullinterface) + function getwidget: twidget; + function translatecolor(const acolor: colorty): colorty; + procedure invalidaterect(const rect: rectty; const org: originty; + const noclip: boolean = false); + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); + end; + + scrollbardrawinfoty = record + frame: tframe; + outerrect: rectty; + dim: rectty; + scrollrect: rectty; +// buttonareas: array[buttonareaty] of rectty; + areas: array[scrollbarareaty] of shapeinfoty; + end; + + scrollbarstatety = (scs_mousecaptured,scs_streampagesize); + scrollbarstatesty = set of scrollbarstatety; + + beforescrollbareventty = procedure(const sender: tcustomscrollbar; + var akind: scrolleventty; var avalue: real) of object; + scrollbareventty = procedure(const sender: tcustomscrollbar; + const akind: scrolleventty; const avalue: real) of object; + //avalue = step or value + tcustomscrollbar = class(tnullinterfacedpersistent,iframe,iface) + private + forg: originty; +// fdim: rectty; + fdirection: graphicdirectionty; + fcolor: colorty; + fcolorpattern: colorty; + fcolorpatternclicked: colorty; + fvalue: real; + fbuttonlength: integer; + fpagesize: real; + fstepsize: real; + fclickedarea: scrollbarareaty; + frepeater: tsimpletimer; + fpickoffset: integer; + fpickpos: pointty; + fscrollrange: integer; + fbuttonminlength: integer; + fwidth: integer; +// ffacebutton: tface; +// ffaceendbutton: tface; +// fframebutton: tframe; +// fframeendbutton1: tframe; +// fframeendbutton2: tframe; + fface: tface; + fface1: tface; + fface2: tface; + fondimchanged: proceventty; + fbuttonendlength: integer; + fpaintedbutton: scrollbarareaty; + fonbeforeevent: beforescrollbareventty; + fonafterevent: scrollbareventty; + fstepctrlfact: real; + fstepshiftfact: real; + fwheelsensitivity: real; + procedure updatedim; + procedure setdirection(const avalue: graphicdirectionty); + procedure setcolor(const avalue: colorty); + procedure setcolorglyph(const avalue: colorty); + procedure invalidatepos; + procedure invalidateclickedarea; + procedure setvalue(Value: real); + procedure setbuttonlength(const avalue: integer); + procedure setpagesize(avalue: real); + function findarea(const point: pointty): scrollbarareaty; + procedure timer(const sender: tobject); + function dobuttoncommand: boolean; + procedure thumbtrack(var pos: pointty); + procedure setdim(const arect: rectty); + procedure setbuttonminlength(const avalue: integer); + procedure setwidth(const avalue: integer); + procedure setindentstart(const avalue: integer); + procedure setindentend(const avalue: integer); + function getstepsize: real; + procedure dodimchanged; + function clickedareaisvalid: boolean; + procedure setcolorpattern(const avalue: colorty); + procedure setcolorpatternclicked(const avalue: colorty); + function getface(): tface; + procedure setface(const avalue: tface); + function getfacebutton: tface; + procedure setfacebutton(const avalue: tface); + function getfaceendbutton: tface; + procedure setfaceendbutton(const avalue: tface); + procedure setbuttonendlength(const avalue: integer); + function getframebutton: tframe; + procedure setframebutton(const avalue: tframe); + function getframeendbutton1: tframe; + procedure setframeendbutton1(const avalue: tframe); + function getframeendbutton2: tframe; + procedure setframeendbutton2(const avalue: tframe); + procedure readstepsize(reader: treader); + procedure writestepsize(writer: twriter); + procedure readstepctrlfact(reader: treader); + procedure writestepctrlfact(writer: twriter); + procedure readstepshiftfact(reader: treader); + procedure writestepshiftfact(writer: twriter); + procedure readpagesize(reader: treader); + procedure writepagesize(writer: twriter); + procedure readwheelsensitivity(reader: treader); + procedure writewheelsensitivity(writer: twriter); + function getdisabled: boolean; + procedure setdisabled(const avalue: boolean); + function getface1: tface; + procedure setface1(const avalue: tface); + function getface2: tface; + procedure setface2(const avalue: tface); + function getframe: tframe; + procedure setframe(const avalue: tframe); + protected + fstate: scrollbarstatesty; + fintf: iscrollbar; + foptions: scrollbaroptionsty; + fdrawinfo: scrollbardrawinfoty; + findentstart,findentend: integer; + //iface + function translatecolor(const acolor: colorty): colorty; + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + procedure widgetregioninvalid; + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getwidget: twidget; + function getwidgetrect: rectty; + function getframestateflags: framestateflagsty; + function getfocused: boolean; + procedure setfocused(const avalue: boolean); + function getshiftfact(ashiftstate: shiftstatesty; out fact: real): boolean; + //false if not valid + procedure setoptions(const avalue: scrollbaroptionsty); virtual; + procedure invalidate; + procedure dosetvalue(); + procedure dostep(akind: scrolleventty; astep: real); + procedure dothumbevent(const aevent: scrolleventty); + function dostepup(const ashiftstate: shiftstatesty): boolean; + function dostepdown(const ashiftstate: shiftstatesty): boolean; + procedure defineproperties(filer: tfiler); override; + function actualcolorpattern: colorty; + function actualcolorpatternclicked: colorty; +// function getbuttonarea(const apos: pointty): buttonareaty; //-1 -> none + public + tag: integer; + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); reintroduce; virtual; + destructor destroy; override; + + procedure createface(); + procedure createface1(); + procedure createface2(); + procedure createfacebutton; + procedure createfaceendbutton; + procedure createframe; + procedure createframebutton; + procedure createframeendbutton1; + procedure createframeendbutton2; + + procedure checktemplate(const sender: tobject); + procedure paint(const canvas: tcanvas; + const acolor: colorty = cl_none); virtual; + //color <> cl_none -> flat paint for grid cell + function wantmouseevent(const apos: pointty): boolean; + function buttonmoving(): boolean; //true if position button clicked + procedure mouseevent(var info: mouseeventinfoty); + procedure mousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean = false); + procedure keydown(var info: keyeventinfoty); + procedure enter(); + procedure exit(); + property focused: boolean read getfocused write setfocused; + //does not invalidate + property disabled: boolean read getdisabled write setdisabled; + //does not invalidate + function clicked: boolean; + procedure activechanged; + + procedure stepup; + procedure stepdown; + procedure pageup; + procedure pagedown; + procedure wheelup(const shiftstate: shiftstatesty = []); + procedure wheeldown(const shiftstate: shiftstatesty = []); + + property direction: graphicdirectionty read fdirection write setdirection + default gd_right; + property value: real read fvalue write setvalue; + property dim: rectty read fdrawinfo.dim write setdim; + + property width: integer read fwidth write setwidth default defaultscrollbarwidth; + property indentstart: integer read findentstart write setindentstart default 0; + property indentend: integer read findentend write setindentend default 0; + // 0 default behavior (width ident if horz and vert visible), < 0 no ident + property options: scrollbaroptionsty read foptions write setoptions + default defaultscrollbaroptions; + property stepsize: real read getstepsize write fstepsize stored false; + //default = 0 -> pagesize /10 + property stepctrlfact: real read fstepctrlfact + write fstepctrlfact stored false; + //default = 0 -> no ctrl step + property stepshiftfact: real read fstepshiftfact + write fstepshiftfact stored false; + //default = 0 -> no shift step + property pagesize: real read fpagesize write setpagesize stored false; + //default = defaultpagesize + property wheelsensitivity: real read fwheelsensitivity + write fwheelsensitivity stored false; + //default = 1 + property buttonlength: integer read fbuttonlength + write setbuttonlength default 0; + //0 -> proportional -1 -> square + property buttonminlength: integer read fbuttonminlength + write setbuttonminlength default defaultbuttonminlength; + property buttonendlength: integer read fbuttonendlength + write setbuttonendlength default 0; + //0 -> square, -1 -> no endbuttons + property face: tface read getface write setface; + property face1: tface read getface1 write setface1; + property face2: tface read getface2 write setface2; + property facebutton: tface read getfacebutton write setfacebutton; + property faceendbutton: tface read getfaceendbutton write setfaceendbutton; + property frame: tframe read getframe write setframe; + property framebutton: tframe read getframebutton write setframebutton; + property frameendbutton1: tframe read getframeendbutton1 + write setframeendbutton1; + property frameendbutton2: tframe read getframeendbutton2 + write setframeendbutton2; + property color: colorty read fcolor write setcolor default cl_default; + property colorpattern: colorty read fcolorpattern + write setcolorpattern default cl_default; + //cl_none -> no pattern + property colorpatternclicked: colorty read fcolorpatternclicked + write setcolorpatternclicked default cl_default; + //cl_none -> no pattern + property colorglyph: colorty read fdrawinfo.areas[sbbu_down].ca.colorglyph + write setcolorglyph default cl_default; + //cl_none -> no no glyph + property onbeforeevent: beforescrollbareventty read fonbeforeevent + write fonbeforeevent; + property onafterevent: scrollbareventty read fonafterevent + write fonafterevent; + end; + + tcustomnomoveautoscrollbar = class(tcustomscrollbar) + protected + procedure setoptions(const avalue: scrollbaroptionsty); override; + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + property options default defaultscrollbaroptions-[sbo_moveauto]; + end; + + + tnopagesizescrollbar = class(tcustomscrollbar) + published + property options; + property width; + property indentstart; + property indentend; + property stepctrlfact; + property stepshiftfact; + property wheelsensitivity; + property buttonlength; + property buttonminlength; + property buttonendlength; + property face; + property face1; + property face2; + property facebutton; + property faceendbutton; + property frame; + property framebutton; + property frameendbutton1; + property frameendbutton2; + property color; + property colorpattern; + property colorpatternclicked; + property colorglyph; + property onbeforeevent; + property onafterevent; + end; + + tscrollbar = class(tnopagesizescrollbar) + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property pagesize; + property stepsize; + end; + + tnomoveautonopagesizescrollbar = class(tcustomnomoveautoscrollbar) + published + property options; + property width; + property indentstart; + property indentend; + property stepctrlfact; + property stepshiftfact; + property wheelsensitivity; + property buttonlength; + property buttonminlength; + property buttonendlength; + property face; + property face1; + property face2; + property facebutton; + property faceendbutton; + property frame; + property framebutton; + property frameendbutton1; + property frameendbutton2; + property color; + property colorpattern; + property colorpatternclicked; + property colorglyph; + property onbeforeevent; + property onafterevent; + end; + + tnomoveautoscrollbar = class(tnomoveautonopagesizescrollbar) + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property stepsize; + property pagesize; + end; + +implementation + +uses + msestockobjects,sysutils,msekeyboard,msebits,msepointer,mseact; +type + twidget1 = class(twidget); +{ +const + buttonareatoscrollbararea: array[buttonareaty] of scrollbarareaty = + (sbbu_down,sbbu_move,sbbu_up); +} +{ tcustomscrollbar } + +constructor tcustomscrollbar.create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); +var + bu1: scrollbarareaty; +begin + foptions:= defaultscrollbaroptions; + fintf:= intf; + forg:= org; + fcolor:= cl_default; + fcolorpattern:= cl_default; + fcolorpatternclicked:= cl_default; + fdrawinfo.areas[sbbu_down].ca.colorglyph:= cl_default; + fdrawinfo.areas[sbbu_up].ca.colorglyph:= cl_default; + fclickedarea:= scrollbarareaty(-1); + fbuttonminlength:= defaultbuttonminlength; + fwidth:= defaultscrollbarwidth; + fondimchanged:= ondimchanged; + fpagesize:= defaultpagesize; + fwheelsensitivity:= 1; + for bu1:= low(scrollbarareaty) to high(scrollbarareaty) do begin + fdrawinfo.areas[bu1].color:= cl_transparent; + end; +end; + +procedure tcustomscrollbar.updatedim; +var + width1,scrolllength,buttonlength1: integer; + bu1: scrollbarareaty; + endblen: integer; + minblen: integer; + quadblen: integer; + + procedure checkscrolllength(const alength: integer); + var + int1: integer; + begin + scrolllength:= alength - endblen - endblen; + if (fbuttonlength < 0) then begin + int1:= scrolllength div 2; + if int1 < quadblen then begin + quadblen:= int1; + end; + end; + if scrolllength < 2 * minblen then begin + endblen:= (alength - 2 * minblen) div 2; + if endblen < minblen then begin + endblen:= alength div 4; + minblen:= endblen; + end; + if endblen < quadblen then begin + quadblen:= endblen; + end; + scrolllength:= alength - endblen - endblen; + end; + end; //checkscrollength +{ + procedure updatebutton(const button: scrollbarareaty); + var + po1: pshapeinfoty; + begin + po1:= @fdrawinfo.areas[scrollbarareaty(button)]; + frameskinoptionstoshapestate(po1^.frame,po1^); + end; //updatebutton +} +var + i1: int32; + +begin + scrolllength:= 0; + with fdrawinfo,dim do begin + dim:= outerrect; + if frame <> nil then begin + deflaterect1(dim,frame.innerframe); + end; + minblen:= fbuttonminlength; + areas[sbbu_up].ca.imagelist:= stockobjects.glyphs; + areas[sbbu_down].ca.imagelist:= stockobjects.glyphs; + areas[sbbu_down].imagenrdisabled:= -2; //grayed + areas[sbbu_move].imagenrdisabled:= -2; //grayed + areas[sbbu_up].imagenrdisabled:= -2; //grayed + if fdirection in [gd_right,gd_left] then begin + width1:= cy; + end + else begin + width1:= cx; + end; + quadblen:= width1; + if fbuttonendlength < 0 then begin + endblen:= 0; + end + else begin + if fbuttonendlength = 0 then begin + endblen:= width1; + end + else begin + endblen:= fbuttonendlength; + end; + end; + if fdirection in [gd_right,gd_left] then begin + checkscrolllength(cx); + scrollrect.x:= x + endblen; + scrollrect.y:= y; + scrollrect.cx:= scrolllength; + scrollrect.cy:= width1; + for bu1:= low(scrollbarareaty) to high(scrollbarareaty) do begin + areas[bu1].ca.dim.y:= y; + areas[bu1].ca.dim.cy:= width1; + end; + areas[sbbu_down].ca.dim.cx:= endblen; + areas[sbbu_up].ca.dim.cx:= endblen; + if fdirection = gd_right then begin + areas[sbbu_up].ca.imagenr:= ord(stg_arrowrightsmall); + areas[sbbu_down].ca.imagenr:= ord(stg_arrowleftsmall); + end + else begin + areas[sbbu_down].ca.imagenr:= ord(stg_arrowrightsmall); + areas[sbbu_up].ca.imagenr:= ord(stg_arrowleftsmall); + end; + end + else begin + checkscrolllength(cy); + scrollrect.x:= x; + scrollrect.y:= y + endblen; + scrollrect.cx:= width1; + scrollrect.cy:= scrolllength; + for bu1:= low(scrollbarareaty) to high(scrollbarareaty) do begin + areas[bu1].ca.dim.x:= x; + areas[bu1].ca.dim.cx:= width1; + end; + areas[sbbu_down].ca.dim.cy:= endblen; + areas[sbbu_up].ca.dim.cy:= endblen; + if fdirection = gd_down then begin + areas[sbbu_up].ca.imagenr:= ord(stg_arrowdownsmall); + areas[sbbu_down].ca.imagenr:= ord(stg_arrowupsmall); + end + else begin + areas[sbbu_down].ca.imagenr:= ord(stg_arrowdownsmall); + areas[sbbu_up].ca.imagenr:= ord(stg_arrowupsmall); + end; + end; + if fbuttonlength < 0 then begin + buttonlength1:= quadblen; + end + else begin + if fbuttonlength > 0 then begin + buttonlength1:= fbuttonlength; + end + else begin + buttonlength1:= round(pagesize * scrolllength); + end; + end; + if buttonlength1 < minblen then begin + buttonlength1:= minblen; + end; + if fbuttonlength > 0 then begin + i1:= scrolllength div 2; + if buttonlength1 > i1 then begin + buttonlength1:= i1; + end; + end; + if fdirection in [gd_right,gd_left] then begin + areas[sbbu_move].ca.dim.cx:= buttonlength1; + end + else begin + areas[sbbu_move].ca.dim.cy:= buttonlength1; + end; + fscrollrange:= scrolllength - buttonlength1; + case fdirection of + gd_right: begin + areas[sbbu_down].ca.dim.x:= x; + areas[sbbu_up].ca.dim.x:= x + cx - endblen; + areas[sbbu_move].ca.dim.x:= x + endblen + round(fvalue * fscrollrange); + areas[sba_start].ca.dim.x:= x + endblen; + areas[sba_start].ca.dim.cx:= areas[sbbu_move].ca.dim.x - + areas[sba_start].ca.dim.x; + areas[sba_end].ca.dim.x:= areas[sbbu_move].ca.dim.x + + areas[sbbu_move].ca.dim.cx; + areas[sba_end].ca.dim.cx:= areas[sbbu_up].ca.dim.x - areas[sba_end].ca.dim.x; + end; + gd_left: begin + areas[sbbu_up].ca.dim.x:= x; + areas[sbbu_down].ca.dim.x:= x + cx - endblen; + areas[sbbu_move].ca.dim.x:= x + cx - (endblen + round(fvalue * fscrollrange)) - + buttonlength1; + areas[sba_start].ca.dim.x:= areas[sbbu_move].ca.dim.x + + areas[sbbu_move].ca.dim.cx; + areas[sba_start].ca.dim.cx:= areas[sbbu_down].ca.dim.x - + areas[sba_start].ca.dim.x; + areas[sba_end].ca.dim.x:= x + endblen; + areas[sba_end].ca.dim.cx:= areas[sbbu_move].ca.dim.x - + areas[sba_end].ca.dim.x; + end; + gd_down: begin + areas[sbbu_down].ca.dim.y:= y; + areas[sbbu_up].ca.dim.y:= y + cy - endblen; + areas[sbbu_move].ca.dim.y:= y + endblen + round(fvalue * fscrollrange); + areas[sba_start].ca.dim.y:= y + endblen; + areas[sba_start].ca.dim.cy:= areas[sbbu_move].ca.dim.y - + areas[sba_start].ca.dim.y; + areas[sba_end].ca.dim.y:= areas[sbbu_move].ca.dim.y + + areas[sbbu_move].ca.dim.cy; + areas[sba_end].ca.dim.cy:= areas[sbbu_up].ca.dim.y - areas[sba_end].ca.dim.y; + end; + gd_up: begin + areas[sbbu_up].ca.dim.y:= y; + areas[sbbu_down].ca.dim.y:= y + cy - endblen; + areas[sbbu_move].ca.dim.y:= y + cy - (endblen + round(fvalue * fscrollrange)) - + buttonlength1; + areas[sba_start].ca.dim.y:= areas[sbbu_move].ca.dim.y + + areas[sbbu_move].ca.dim.cy; + areas[sba_start].ca.dim.cy:= areas[sbbu_down].ca.dim.y - + areas[sba_start].ca.dim.y; + areas[sba_end].ca.dim.y:= y + endblen; + areas[sba_end].ca.dim.cy:= areas[sbbu_move].ca.dim.y - + areas[sba_end].ca.dim.y; + end; + end; + end; +end; + +function tcustomscrollbar.findarea(const point: pointty): scrollbarareaty; +var + ar1: scrollbarareaty; +begin + result:= scrollbarareaty(-1); + for ar1:= low(scrollbarareaty) to high(scrollbarareaty) do begin + if pointinshape(point,fdrawinfo.areas[ar1]) then begin + result:= ar1; + break; + end; + end; +end; + +procedure tcustomscrollbar.invalidate; +begin + updatedim; + fintf.invalidaterect(fdrawinfo.outerrect,forg); +end; + +procedure tcustomscrollbar.invalidatepos; +begin + updatedim; + fintf.invalidaterect(fdrawinfo.scrollrect,forg); +end; + +function tcustomscrollbar.clickedareaisvalid: boolean; +begin + result:= (shortint(fclickedarea) >= 0) and + (shortint(fclickedarea) < scrollbarclicked); +end; + +procedure tcustomscrollbar.invalidateclickedarea; +begin + if clickedareaisvalid then begin + fintf.invalidaterect(fdrawinfo.areas[fclickedarea].ca.dim,forg); + end; +end; + +procedure tcustomscrollbar.setdim(const arect: rectty); +begin + fdrawinfo.outerrect:= arect; +// fdim:= arect; + invalidate; +end; + +procedure tcustomscrollbar.setbuttonlength(const avalue: integer); +begin + if fbuttonlength <> avalue then begin + fbuttonlength := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setbuttonendlength(const avalue: integer); +begin + if avalue <> fbuttonendlength then begin + fbuttonendlength := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setbuttonminlength(const avalue: integer); +begin + if fbuttonminlength <> avalue then begin + fbuttonminlength:= avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setwidth(const avalue: integer); +begin + if fwidth <> avalue then begin + fwidth := avalue; + dodimchanged; + end; +end; + +procedure tcustomscrollbar.setindentstart(const avalue: integer); +begin + if findentstart <> avalue then begin + findentstart := avalue; + dodimchanged; + end; +end; + +procedure tcustomscrollbar.setindentend(const avalue: integer); +begin + if findentend <> avalue then begin + findentend := avalue; + dodimchanged; + end; +end; + +procedure tcustomscrollbar.setdirection(const avalue: graphicdirectionty); +begin + if fdirection <> avalue then begin + fdirection := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setcolor(const avalue: colorty); +begin + if fcolor <> avalue then begin + fcolor := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setcolorglyph(const avalue: colorty); +begin + if fdrawinfo.areas[sbbu_down].ca.colorglyph <> avalue then begin + fdrawinfo.areas[sbbu_down].ca.colorglyph:= avalue; + fdrawinfo.areas[sbbu_up].ca.colorglyph:= avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setcolorpattern(const avalue: colorty); +begin + if fcolorpattern <> avalue then begin + fcolorpattern := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setcolorpatternclicked(const avalue: colorty); +begin + if fcolorpatternclicked <> avalue then begin + fcolorpatternclicked := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.paint(const canvas: tcanvas; + const acolor: colorty = cl_none); +var + col1: colorty; + statebefore: shapestatesty; +begin + with canvas,self.fdrawinfo do begin + save(); + if acolor = cl_none then begin + col1:= fcolor; + end + else begin + col1:= acolor; + end; + col1:= fintf.translatecolor(col1); + canvas.fillrect(dim,col1); + if frame <> nil then begin + frame.paintbackground(canvas,outerrect,true,false); + end; + if fface <> nil then begin + fface.paint(canvas,fdrawinfo.scrollrect); + end; + if fface1 <> nil then begin + fface1.paint(canvas,areas[sba_start].ca.dim); + end; + if fface2 <> nil then begin + fface2.paint(canvas,areas[sba_end].ca.dim); + end; + fpaintedbutton:= firstbutton; + while fpaintedbutton <= lastbutton do begin + if acolor <> cl_none then begin + with areas[fpaintedbutton] do begin + statebefore:= state; + state:= state - [shs_mouse,shs_clicked]; + end; + end; +// fillrect(areas[fpaintedbutton].ca.dim,col1); +// areas[fpaintedbutton].color:= col1; + drawtoolbutton(canvas,areas[fpaintedbutton]); + if acolor <> cl_none then begin + areas[fpaintedbutton].state:= statebefore; + end; + inc(fpaintedbutton); + end; + if fface = nil then begin + colorbackground:= col1; + brush:= stockobjects.bitmaps[stb_dens50]; + if fface1 = nil then begin + if fclickedarea = sba_start then begin + color:= actualcolorpatternclicked(); + end + else begin + color:= actualcolorpattern(); + end; + if color <> cl_none then begin + fillrect(areas[sba_start].ca.dim,cl_brushcanvas); + end + else begin +// fillrect(areas[sba_start].ca.dim,col1); + end; + end; + if fface2 = nil then begin + if fclickedarea = sba_end then begin + color:= actualcolorpatternclicked(); + end + else begin + color:= actualcolorpattern(); + end; + if color <> cl_none then begin + fillrect(areas[sba_end].ca.dim,cl_brushcanvas); + end + else begin +// fillrect(areas[sba_end].ca.dim,col1); + end; + end; + end; + restore; + if frame <> nil then begin + frame.paintoverlay(canvas,outerrect); + end; + end; +end; + +procedure tcustomscrollbar.setvalue(Value: real); +begin + if value < 0 then begin + value:= 0; + end + else begin + if value > 1 then begin + value:= 1; + end; + end; + if fvalue <> value then begin + fvalue := Value; + invalidatepos; + fintf.scrollevent(self,sbe_valuechanged); + end; +end; + +procedure tcustomscrollbar.setpagesize(avalue: real); +begin + if avalue < 0 then begin + avalue:= 0; + end; + if avalue > 1 then begin + avalue:= 1; + end; + if fpagesize <> avalue then begin + fpagesize:= avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.dodimchanged; +begin + if assigned(fondimchanged) then begin + fondimchanged; + end; + invalidate; +end; + +procedure tcustomscrollbar.setoptions(const avalue: scrollbaroptionsty); +var + aoptions: scrollbaroptionsty; +const + mask: scrollbaroptionsty = [sbo_showauto,sbo_show]; +begin + aoptions:= scrollbaroptionsty(setsinglebit( + {$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(foptions), + {$ifdef FPC}longword{$else}word{$endif}(mask))); + if aoptions <> foptions then begin + foptions:= aoptions; + dodimchanged; + end; +end; + +function tcustomscrollbar.getstepsize: real; +begin + if fstepsize = 0 then begin + result:= fpagesize / 10; + end + else begin + result:= fstepsize; + end; +end; + +function tcustomscrollbar.dobuttoncommand: boolean; +begin + result:= true; + case fclickedarea of + sbbu_up: begin + result:= dostepup(application.lastshiftstate*keyshiftstatesmask); + end; + sbbu_down: begin + dostepdown(application.lastshiftstate*keyshiftstatesmask); + end; + sba_start: begin + pagedown; + end; + sba_end: begin + pageup; + end; + else begin + result:= false; + end; + end; +end; + +procedure tcustomscrollbar.thumbtrack(var pos: pointty); +var + apos: integer; +begin + if fscrollrange <> 0 then begin + case fdirection of + gd_right: apos:= pos.x + fpickoffset; + gd_up: apos:= fpickoffset - pos.y; + gd_left: apos:= fpickoffset - pos.x; + else apos:= pos.y + fpickoffset; //gd_down + end; + value:= apos / fscrollrange; + end; +end; + +function tcustomscrollbar.wantmouseevent(const apos: pointty): boolean; +begin + result:= (fclickedarea <> scrollbarareaty(-1)) or + (findarea(apos) <> scrollbarareaty(-1)); +end; + +function tcustomscrollbar.buttonmoving(): boolean; +begin + result:= fclickedarea = sbbu_move; +end; + +procedure tcustomscrollbar.mouseevent(var info: mouseeventinfoty); + + procedure releasebutton(const cancel: boolean); + begin + if scs_mousecaptured in fstate then begin + exclude(fstate,scs_mousecaptured); + fintf.getwidget.releasemouse; + end; + freeandnil(frepeater); + if clickedareaisvalid then begin + exclude(fdrawinfo.areas[fclickedarea].state,shs_clicked); + invalidateclickedarea; + end; + if (fclickedarea = sbbu_move) and not cancel then begin + thumbtrack(info.pos); + fintf.scrollevent(self,sbe_thumbposition); + dothumbevent(sbe_thumbposition); + end; + fclickedarea:= scrollbarareaty(-1); + end; + +var + isclicktovalue: boolean; + + procedure mousemove(ar1: scrollbarareaty); + var + ar2: scrollbarareaty; + begin + if ord(ar1) >= 0 then begin + application.widgetcursorshape:= cr_arrow; + end; + if clickedareaisvalid then begin + if (ar1 <> fclickedarea) and (fclickedarea <> sbbu_move) and + ((frepeater = nil) or + not (fclickedarea in[sba_start,sba_end])) then begin + releasebutton(false); + fclickedarea:= scrollbarareaty(scrollbarclicked); + end; + if (fclickedarea = sbbu_move) then begin + ar1:= sbbu_move;{scrollbarareaty(-1);} + if (info.eventkind = ek_mousemove) or isclicktovalue then begin + thumbtrack(info.pos); + if sbo_thumbtrack in foptions then begin + fintf.scrollevent(self,sbe_thumbtrack); + dothumbevent(sbe_thumbtrack); + end; + end; + include(info.eventstate,es_processed); + end; + end; + for ar2:= firstbutton to lastbutton do begin + with fdrawinfo,areas[ar2] do begin + if (ar2 = ar1) then begin + if not (shs_mouse in state) then begin + include(state,shs_mouse); + fintf.invalidaterect(dim,forg); + end; + end + else begin + if shs_mouse in state then begin + exclude(state,shs_mouse); + fintf.invalidaterect(dim,forg); + end; + end; + end; + end; + end; + +var + ar1: scrollbarareaty; +begin + if (info.eventkind in mouseposevents) and (info.shiftstate * + (keyshiftstatesmask + [ss_middle,ss_right]) = []) and + not (info.button in [mb_right,mb_middle]) then begin + ar1:= findarea(info.pos); + if (ar1 = scrollbarareaty(-1)) and clickedareaisvalid then begin + ar1:= scrollbarareaty(scrollbarclicked); + end; + end + else begin + ar1:= scrollbarareaty(-1); + end; + if ar1 <> scrollbarareaty(-1) then begin + include(info.eventstate,es_processed); + end; + if (info.eventkind = ek_clientmouseleave) and (forg = org_client) or + (info.eventkind = ek_mouseleave) and (forg = org_widget) then begin + releasebutton(true); + mousemove(scrollbarareaty(-1)); + end + else begin + case info.eventkind of + ek_mousemove,ek_mousepark: begin + mousemove(ar1); + if fclickedarea = scrollbarareaty(-1) then begin + exclude(info.eventstate,es_processed); + end; + end; + ek_buttonpress: begin + if (info.button = mb_left) and + (not(sbo_noreflectedclick in foptions) or + not (es_reflected in info.eventstate)) then begin + + isclicktovalue:= (ar1 in [sba_start,sba_end,sbbu_move]) and + ((info.shiftstate * keyshiftstatesmask = [ss_ctrl]) or + (sbo_clicktovalue in foptions)); + if isclicktovalue then begin + ar1:= sbbu_move; + end; + fclickedarea:= ar1; + if clickedareaisvalid then begin + include(fdrawinfo.areas[fclickedarea].state,shs_clicked); + with fintf.getwidget do begin + if not mousecaptured then begin + capturemouse(true); + include(fstate,scs_mousecaptured); + end; + end; + end; + invalidateclickedarea; + if dobuttoncommand then begin + frepeater:= tsimpletimer.create(repeatdelaytime, + {$ifdef FPC}@{$endif}timer,true,[to_single]); + end + else begin + if fclickedarea = sbbu_move then begin + fpickpos:= info.pos; + if isclicktovalue then begin + with fdrawinfo.areas[sbbu_move].ca.dim do begin + case fdirection of + gd_right: fpickoffset:=-fdrawinfo.areas[sba_start].ca.dim.x - + cx div 2; + gd_up: fpickoffset:= fdrawinfo.areas[sba_start].ca.dim.cy + y + + cy div 2; + gd_left: fpickoffset:= fdrawinfo.areas[sba_start].ca.dim.cx + x + + cx div 2; + gd_down: fpickoffset:= -fdrawinfo.areas[sba_start].ca.dim.y - + cy div 2 ; + end; + end; + end + else begin + with fdrawinfo.areas[sbbu_move].ca.dim do begin + case fdirection of + gd_right: fpickoffset:= x - info.pos.x - + fdrawinfo.areas[sba_start].ca.dim.x; + gd_up: fpickoffset:= fdrawinfo.areas[sba_start].ca.dim.cy + + info.pos.y; + gd_left: fpickoffset:= fdrawinfo.areas[sba_start].ca.dim.cx + + info.pos.x; + gd_down: fpickoffset:= y - info.pos.y - + fdrawinfo.areas[sba_start].ca.dim.y; + end; + end; + end; + if isclicktovalue then begin + mousemove(ar1); + end; + end; + end; + end; + end; + ek_buttonrelease: begin + if info.button = mb_left then begin + releasebutton(false); + end; + end; + end; + end; +end; + +procedure tcustomscrollbar.mousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean = false); +begin + with info do begin + include(eventstate,es_processed); + if (wheel = mw_down) xor (fdirection in [gd_right,gd_down]) then begin + if (fstepctrlfact <> 0) or (fstepshiftfact <> 0) then begin + wheeldown(shiftstate); + end + else begin + if (ss_ctrl in shiftstate) xor pagingreversed then begin + pagedown; + end + else begin + wheeldown; + end; + end; + end + else begin + if (fstepctrlfact <> 0) or (fstepshiftfact <> 0) then begin + wheelup(shiftstate); + end + else begin + if (ss_ctrl in shiftstate) xor pagingreversed then begin + pageup; + end + else begin + wheelup; + end; + end; + end; + end; +end; + +function tcustomscrollbar.getshiftfact(ashiftstate: shiftstatesty; + out fact: real): boolean; + //false if not valid +begin + fact:= 1; + ashiftstate:= ashiftstate * shiftstatesmask; + result:= ashiftstate = []; + if not result then begin + if (ashiftstate = [ss_ctrl]) and (fstepctrlfact <> 0) then begin + fact:= fstepctrlfact; + result:= true; + end + else begin + if (ashiftstate = [ss_shift]) and (fstepshiftfact <> 0) then begin + fact:= fstepshiftfact; + result:= true; + end + end; + end; +end; + +function tcustomscrollbar.dostepup(const ashiftstate: shiftstatesty): boolean; +var + fact1: real; +begin + result:= getshiftfact(ashiftstate,fact1); + if result then begin + dostep(sbe_stepup,stepsize*fact1); + end; +end; //dostepup + +function tcustomscrollbar.dostepdown(const ashiftstate: shiftstatesty): boolean; +var + fact1: real; +begin + result:= getshiftfact(ashiftstate,fact1); + if result then begin + dostep(sbe_stepdown,-stepsize*fact1); + end; +end; + +procedure tcustomscrollbar.keydown(var info: keyeventinfoty); + + procedure dopageup; + begin + if info.shiftstate * shiftstatesmask = [ss_ctrl] then begin + value:= 1; + end + else begin + pageup; + end; + end; //dopageup + + procedure dopagedown; + begin + if info.shiftstate * shiftstatesmask = [ss_ctrl] then begin + value:= 0; + end + else begin + pagedown; + end; + end; //dopagedown + +var + bo1: boolean; + +begin + with info do begin + if not (es_processed in eventstate) then begin + if (not (sbo_noarrowkeys in foptions) or + (key <> key_left) and (key <> key_right) and + (key <> key_up) and (key <> key_down)) and + (not (sbo_nopagekeys in foptions) or + (key <> key_pageup) and (key <> key_pagedown)) then begin + bo1:= true; + if sbo_valuekeys in foptions then begin + case info.key of + key_pageup: dopageup; + key_pagedown: dopagedown; + key_up: bo1:= dostepup(info.shiftstate); + key_down: bo1:= dostepdown(info.shiftstate); + else begin + bo1:= false; + end; + end; + end + else begin + case fdirection of + gd_right: begin + case info.key of + key_right: bo1:= dostepup(info.shiftstate); + key_left: bo1:= dostepdown(info.shiftstate); + key_pageup: dopageup; + key_pagedown: dopagedown; + else begin + bo1:= false; + end; + end; + end; + gd_up: begin + case info.key of + key_up: bo1:= dostepdown(info.shiftstate); + key_down: bo1:= dostepup(info.shiftstate); + key_pageup: dopageup; + key_pagedown: dopagedown; + else begin + bo1:= false; + end; + end; + end; + gd_left: begin + case info.key of + key_right: bo1:= dostepdown(info.shiftstate); + key_left: bo1:= dostepup(info.shiftstate); + key_pageup: dopageup; + key_pagedown: dopagedown; + else begin + bo1:= false; + end; + end; + end; + gd_down: begin + case info.key of + key_down: bo1:= dostepup(info.shiftstate); + key_up: bo1:= dostepdown(info.shiftstate); + key_pageup: dopagedown; + key_pagedown: dopageup; + else begin + bo1:= false; + end; + end; + end; + end; + end; + if bo1 then begin + include(eventstate,es_processed); + end; + end; + end; + end; +end; + +procedure tcustomscrollbar.dosetvalue(); +begin + fintf.scrollevent(self,sbe_setvalue); +end; + +procedure tcustomscrollbar.dostep(akind: scrolleventty; astep: real); +begin + if assigned(fonbeforeevent) then begin + fonbeforeevent(self,akind,astep); + end; + if akind <> sbe_none then begin + if sbo_moveauto in foptions then begin + value:= fvalue + astep; + dosetvalue(); + end; + fintf.scrollevent(self,akind); + if assigned(fonafterevent) then begin + fonafterevent(self,akind,astep); + end; + end; +end; + +procedure tcustomscrollbar.dothumbevent(const aevent: scrolleventty); +begin + dosetvalue(); + if assigned(fonafterevent) then begin + fonafterevent(self,aevent,value); + end; +end; + +procedure tcustomscrollbar.pagedown; +begin + dostep(sbe_pagedown,-pagesize); +end; + +procedure tcustomscrollbar.pageup; +begin + dostep(sbe_pageup,pagesize); +end; + +procedure tcustomscrollbar.wheeldown(const shiftstate: shiftstatesty = []); +var + fact1: real; +begin + getshiftfact(shiftstate,fact1); + dostep(sbe_wheeldown, + -application.mousewheelacceleration(stepsize)* + fwheelsensitivity*fact1); +end; + +procedure tcustomscrollbar.wheelup(const shiftstate: shiftstatesty = []); +var + fact1: real; +begin + getshiftfact(shiftstate,fact1); + dostep(sbe_wheelup, + application.mousewheelacceleration(stepsize)* + fwheelsensitivity*fact1); +end; + +procedure tcustomscrollbar.stepdown; +begin + dostep(sbe_stepdown,-stepsize); +end; + +procedure tcustomscrollbar.stepup; +begin + dostep(sbe_stepup,stepsize); +end; + +destructor tcustomscrollbar.destroy; +begin + freeandnil(frepeater); + inherited; + fface.free(); + fface1.free(); + fface2.free(); + fdrawinfo.areas[sbbu_move].face.free; + fdrawinfo.areas[sbbu_up].face.free; + fdrawinfo.frame.free; + fdrawinfo.areas[sbbu_down].frame.free; + fdrawinfo.areas[sbbu_move].frame.free; + fdrawinfo.areas[sbbu_up].frame.free; +// ffacebutton.free; +// ffaceendbutton.free; +// fframebutton.free; +// fframeendbutton1.free; +// fframeendbutton2.free; +end; + +procedure tcustomscrollbar.timer(const sender: tobject); +begin + dobuttoncommand; + with tsimpletimer(sender) do begin + if singleshot then begin + singleshot:= false; + interval:= repeatrepeattime; + enabled:= true; + end; + end; +end; + +procedure tcustomscrollbar.enter; +begin + with fdrawinfo,areas[sbbu_move] do begin + include(state,shs_focused); + fintf.invalidaterect(ca.dim,forg); + end; +end; + +procedure tcustomscrollbar.exit; +begin + with fdrawinfo,areas[sbbu_move] do begin + exclude(fdrawinfo.areas[sbbu_move].state,shs_focused); + fintf.invalidaterect(ca.dim,forg); + end; +end; + +function tcustomscrollbar.getfocused: boolean; +begin + result:= shs_focused in fdrawinfo.areas[sbbu_move].state; +end; + +procedure tcustomscrollbar.setfocused(const avalue: boolean); +begin + if avalue then begin + include(fdrawinfo.areas[sbbu_move].state,shs_focused); + end + else begin + exclude(fdrawinfo.areas[sbbu_move].state,shs_focused); + end; +end; + +function tcustomscrollbar.getdisabled: boolean; +begin + result:= shs_disabled in fdrawinfo.areas[sbbu_move].state; +end; + +procedure tcustomscrollbar.setdisabled(const avalue: boolean); +begin + if avalue then begin + include(fdrawinfo.areas[sbbu_down].state,shs_disabled); + include(fdrawinfo.areas[sbbu_move].state,shs_disabled); + include(fdrawinfo.areas[sbbu_up].state,shs_disabled); + end + else begin + exclude(fdrawinfo.areas[sbbu_down].state,shs_disabled); + exclude(fdrawinfo.areas[sbbu_move].state,shs_disabled); + exclude(fdrawinfo.areas[sbbu_up].state,shs_disabled); + end; +end; + +procedure tcustomscrollbar.createfacebutton; +begin + if fdrawinfo.areas[sbbu_move].face = nil then begin + fdrawinfo.areas[sbbu_move].face:= tface.create(iface(fintf.getwidget)); + end; +end; + +procedure tcustomscrollbar.createface; +begin + if fface = nil then begin + fface:= tface.create(iface(self)); + end; +end; + +procedure tcustomscrollbar.createface1(); +begin + if fface1 = nil then begin + fface1:= tface.create(iface(self)); + end; +end; + +procedure tcustomscrollbar.createface2(); +begin + if fface2 = nil then begin + fface2:= tface.create(iface(self)); + end; +end; + +function tcustomscrollbar.getface: tface; +begin + fintf.getwidget.getoptionalobject(fface, + {$ifdef FPC}@{$endif}createface); + result:= fface; +end; + +procedure tcustomscrollbar.setface(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fface, + {$ifdef FPC}@{$endif}createface); + invalidate; +// fface.assign(avalue); +end; + +function tcustomscrollbar.getface1: tface; +begin + fintf.getwidget.getoptionalobject(fface1, + {$ifdef FPC}@{$endif}createface1); + result:= fface1; +end; + +procedure tcustomscrollbar.setface1(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fface1, + {$ifdef FPC}@{$endif}createface1); + invalidate; +end; + +function tcustomscrollbar.getface2: tface; +begin + fintf.getwidget.getoptionalobject(fface2, + {$ifdef FPC}@{$endif}createface2); + result:= fface2; +end; + +procedure tcustomscrollbar.setface2(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fface2, + {$ifdef FPC}@{$endif}createface2); + invalidate; +end; + +function tcustomscrollbar.getfacebutton: tface; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.areas[sbbu_move].face, + {$ifdef FPC}@{$endif}createfacebutton); + result:= tface(fdrawinfo.areas[sbbu_move].face); +end; + +procedure tcustomscrollbar.setfacebutton(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.areas[sbbu_move].face, + {$ifdef FPC}@{$endif}createfacebutton); + invalidate; +end; + +procedure tcustomscrollbar.createfaceendbutton; +begin + if fdrawinfo.areas[sbbu_up].face = nil then begin + fdrawinfo.areas[sbbu_up].face:= tface.create(iface(fintf.getwidget)); + fdrawinfo.areas[sbbu_down].face:= fdrawinfo.areas[sbbu_up].face; + end; +end; + +function tcustomscrollbar.getfaceendbutton: tface; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.areas[sbbu_up].face, + {$ifdef FPC}@{$endif}createfaceendbutton); + result:= tface(fdrawinfo.areas[sbbu_up].face); +end; + +procedure tcustomscrollbar.setfaceendbutton(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.areas[sbbu_up].face, + {$ifdef FPC}@{$endif}createfaceendbutton); + invalidate; +end; + +procedure tcustomscrollbar.createframe; +begin + if fdrawinfo.frame = nil then begin + fdrawinfo.frame:= tframe.create(iframe(self)); + end; +end; + +procedure tcustomscrollbar.createframebutton; +begin + if fdrawinfo.areas[sbbu_move].frame = nil then begin + fdrawinfo.areas[sbbu_move].frame:= tframe.create(iframe(self)); + end; +end; + +function tcustomscrollbar.getframe: tframe; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.frame,@createframe); + result:= tframe(fdrawinfo.frame); +end; + +procedure tcustomscrollbar.setframe(const avalue: tframe); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.frame,@createframe); + invalidate; +end; + +function tcustomscrollbar.getframebutton: tframe; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.areas[sbbu_move].frame, + {$ifdef FPC}@{$endif}createframebutton); + result:= tframe(fdrawinfo.areas[sbbu_move].frame); +end; + +procedure tcustomscrollbar.setframebutton(const avalue: tframe); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.areas[sbbu_move].frame, + {$ifdef FPC}@{$endif}createframebutton); + invalidate; +end; + +procedure tcustomscrollbar.createframeendbutton1; +begin + if fdrawinfo.areas[sbbu_down].frame = nil then begin + fdrawinfo.areas[sbbu_down].frame:= tframe.create(iframe(self)); + end; +end; + +function tcustomscrollbar.getframeendbutton1: tframe; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.areas[sbbu_down].frame, + {$ifdef FPC}@{$endif}createframeendbutton1); + result:= tframe(fdrawinfo.areas[sbbu_down].frame); +end; + +procedure tcustomscrollbar.setframeendbutton1(const avalue: tframe); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.areas[sbbu_down].frame, + {$ifdef FPC}@{$endif}createframeendbutton1); + invalidate; +end; + +procedure tcustomscrollbar.createframeendbutton2; +begin + if fdrawinfo.areas[sbbu_up].frame = nil then begin + fdrawinfo.areas[sbbu_up].frame:= tframe.create(iframe(self)); + end; +end; + +function tcustomscrollbar.getframeendbutton2: tframe; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.areas[sbbu_up].frame, + {$ifdef FPC}@{$endif}createframeendbutton2); + result:= tframe(fdrawinfo.areas[sbbu_up].frame); +end; + +procedure tcustomscrollbar.setframeendbutton2(const avalue: tframe); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.areas[sbbu_up].frame, + {$ifdef FPC}@{$endif}createframeendbutton2); + invalidate; +end; + +function tcustomscrollbar.clicked: boolean; +begin + result:= fclickedarea <> scrollbarareaty(-1); +end; + +procedure tcustomscrollbar.checktemplate(const sender: tobject); +begin + if fface <> nil then begin + fface.checktemplate(sender); + end; + if fface1 <> nil then begin + fface1.checktemplate(sender); + end; + if fface2 <> nil then begin + fface2.checktemplate(sender); + end; + if fdrawinfo.areas[sbbu_move].face <> nil then begin + fdrawinfo.areas[sbbu_move].face.checktemplate(sender); + end; + if fdrawinfo.areas[sbbu_down].face <> nil then begin + fdrawinfo.areas[sbbu_down].face.checktemplate(sender); + end; + if fdrawinfo.areas[sbbu_move].frame <> nil then begin + fdrawinfo.areas[sbbu_move].frame.checktemplate(sender); + end; + if fdrawinfo.areas[sbbu_down].frame <> nil then begin + fdrawinfo.areas[sbbu_down].frame.checktemplate(sender); + end; + if fdrawinfo.areas[sbbu_up].frame <> nil then begin + fdrawinfo.areas[sbbu_up].frame.checktemplate(sender); + end; +end; + +procedure tcustomscrollbar.setframeinstance(instance: tcustomframe); +begin + //dummy +end; + +procedure tcustomscrollbar.setstaticframe(value: boolean); +begin + //dummy +end; + +function tcustomscrollbar.getstaticframe: boolean; +begin + result:= false; +end; + +procedure tcustomscrollbar.scrollwidgets(const dist: pointty); +begin + //dumy +end; + +procedure tcustomscrollbar.clientrectchanged; +begin + invalidate; +end; + +function tcustomscrollbar.getcomponentstate: tcomponentstate; +begin + result:= fintf.getwidget.componentstate; +end; + +function tcustomscrollbar.getmsecomponentstate: msecomponentstatesty; +begin + result:= fintf.getwidget.msecomponentstate; +end; + +procedure tcustomscrollbar.invalidatewidget; +begin + invalidate; +end; + +procedure tcustomscrollbar.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + invalidate; +end; + +function tcustomscrollbar.getwidget: twidget; +begin + result:= fintf.getwidget; +end; + +function tcustomscrollbar.getwidgetrect: rectty; +begin + result:= fdrawinfo.outerrect; +// result:= fdim; +end; + +function tcustomscrollbar.getframestateflags: framestateflagsty; +begin + with fdrawinfo.areas[fpaintedbutton],fintf.getwidget do begin + result:= combineframestateflags(not isenabled,focused,active, + shs_mouse in state, shs_clicked in state); + end; +end; + +procedure tcustomscrollbar.activechanged; +begin + if (fdrawinfo.areas[sbbu_down].frame <> nil) or + (fdrawinfo.areas[sbbu_move].frame <> nil) or + (fdrawinfo.areas[sbbu_up].frame <> nil) then begin + invalidate; + end; +end; + +procedure tcustomscrollbar.readstepsize(reader: treader); +begin + stepsize:= reader.readfloat; +end; + +procedure tcustomscrollbar.writestepsize(writer: twriter); +begin + writer.writefloat(stepsize); +end; + +procedure tcustomscrollbar.readstepctrlfact(reader: treader); +begin + stepctrlfact:= reader.readfloat; +end; + +procedure tcustomscrollbar.writestepctrlfact(writer: twriter); +begin + writer.writefloat(stepctrlfact); +end; + +procedure tcustomscrollbar.readstepshiftfact(reader: treader); +begin + stepshiftfact:= reader.readfloat; +end; + +procedure tcustomscrollbar.writestepshiftfact(writer: twriter); +begin + writer.writefloat(stepshiftfact); +end; + +procedure tcustomscrollbar.readpagesize(reader: treader); +begin + pagesize:= reader.readfloat; +end; + +procedure tcustomscrollbar.writepagesize(writer: twriter); +begin + writer.writefloat(pagesize); +end; + +procedure tcustomscrollbar.readwheelsensitivity(reader: treader); +begin + wheelsensitivity:= reader.readfloat; +end; + +procedure tcustomscrollbar.writewheelsensitivity(writer: twriter); +begin + writer.writefloat(wheelsensitivity); +end; + +procedure tcustomscrollbar.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('stepsize',@readstepsize,@writestepsize, + (scs_streampagesize in fstate) and + ((filer.ancestor = nil) and (fstepsize <> 0) or + (filer.ancestor <> nil) and + (tcustomscrollbar(filer.ancestor).fstepsize <> fstepsize))); + filer.defineproperty('stepctrlfact',@readstepctrlfact,@writestepctrlfact, + (filer.ancestor = nil) and (fstepctrlfact <> 0) or + (filer.ancestor <> nil) and + (tcustomscrollbar(filer.ancestor).fstepctrlfact <> fstepctrlfact)); + filer.defineproperty('stepshiftfact',@readstepshiftfact,@writestepshiftfact, + (filer.ancestor = nil) and (fstepshiftfact <> 0) or + (filer.ancestor <> nil) and + (tcustomscrollbar(filer.ancestor).fstepshiftfact <> fstepshiftfact)); + filer.defineproperty('pagesize',@readpagesize,@writepagesize, + (scs_streampagesize in fstate) and + ((filer.ancestor = nil) and (fpagesize <> defaultpagesize) or + (filer.ancestor <> nil) and + (tcustomscrollbar(filer.ancestor).fpagesize <> fpagesize))); + filer.defineproperty('wheelsensitivity',@readwheelsensitivity,@writewheelsensitivity, + (filer.ancestor = nil) and (fwheelsensitivity <> 1) or + (filer.ancestor <> nil) and + (tcustomscrollbar(filer.ancestor).fwheelsensitivity <> fwheelsensitivity)); +end; + +function tcustomscrollbar.actualcolorpattern: colorty; +begin + result:= fcolorpattern; + if result = cl_default then begin + result:= cl_scrollbarpattern; + end; +end; + +function tcustomscrollbar.actualcolorpatternclicked: colorty; +begin + result:= fcolorpatternclicked; + if result = cl_default then begin + result:= cl_scrollbarpatternclicked; + end; +end; +{ +function tcustomscrollbar.getbuttonarea(const apos: pointty): buttonareaty; +var + bu1: buttonareaty; +begin + result:= buttonareaty(-1); //none + for bu1:= low(buttonareaty) to high(buttonareaty) do begin + if pointinrect(apos,fdrawinfo.buttonareas[bu1]) then begin + result:= bu1; + break; + end; + end; +end; +} +function tcustomscrollbar.translatecolor(const acolor: colorty): colorty; +begin + result:= fintf.translatecolor(acolor); +end; + +function tcustomscrollbar.getclientrect: rectty; +begin + result:= fintf.getwidget.clientrect; +end; + +procedure tcustomscrollbar.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + twidget1(fintf.getwidget).setlinkedvar(source,dest,linkintf); +end; + +procedure tcustomscrollbar.widgetregioninvalid; +begin + twidget1(fintf.getwidget).widgetregioninvalid; +end; + +{ tcustomnomoveautoscrollbar } + +constructor tcustomnomoveautoscrollbar.create(intf: iscrollbar; + org: originty; ondimchanged: proceventty); +begin + inherited; + foptions:= defaultscrollbaroptions-[sbo_moveauto]; +end; + +procedure tcustomnomoveautoscrollbar.setoptions( + const avalue: scrollbaroptionsty); +begin + inherited setoptions(avalue - [sbo_moveauto]); +end; + +{ tscrollbar } + +constructor tscrollbar.create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); +begin + inherited; + include(fstate,scs_streampagesize); +end; + +{ tnomoveautoscrollbar } + +constructor tnomoveautoscrollbar.create(intf: iscrollbar; + org: originty = org_client; ondimchanged: proceventty = nil); +begin + inherited; + include(fstate,scs_streampagesize); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseshapes.pas b/mseide-msegui/lib/common/kernel/mseshapes.pas new file mode 100644 index 0000000..bf39356 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseshapes.pas @@ -0,0 +1,1700 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseshapes; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msegraphics,msegraphutils,mseguiglob,msegui,mseevent,mserichstring,msebitmap, + msetypes,mseact,msestrings,msedrawtext; + +type + buttonoptionty = (bo_executeonclick,bo_executeonkey,bo_executeonshortcut, + bo_executedefaultonenterkey, + bo_asyncexecute, + bo_focusonshortcut,bo_focusonactionshortcut, + //for tcustombutton + bo_updateonidle, + bo_shortcutcaption,bo_altshortcut, + {bo_flat,bo_noanim,bo_nofocusrect,bo_nodefaultrect,} + bo_nodefaultframeactive, + bo_coloractive, + bo_ellipsemouse, //mouse area is elliptical + bo_nocandefocus,bo_candefocuswindow, //check own window only + bo_radioitem, //for tdatabutton + bo_radioitemcol, + bo_cantoggle, //for tbooleaneditradio + bo_resetcheckedonrowexit, + //used in tdatabutton + bo_reversed, //for tbooleanedit + bo_noassistivedisabled + ); + buttonoptionsty = set of buttonoptionty; + +const + defaultbuttonoptions = [bo_executeonclick,bo_executeonkey, + bo_executeonshortcut,bo_executedefaultonenterkey]; + + menuarrowwidth = 8; + menuarrowwidthhorz = 15; + menucheckboxwidth = 13; + menucheckboxheight = 13; + defaultshapecaptiondist = 2; + defaultshapefocusrectdist = 1; + defaultcaptiontextflags = [tf_left,tf_xcentered,tf_ycentered]; + +// styleactionstates: actionstatesty = [as_shortcutcaption,as_radiobutton]; +type + buttonedgety = (bedg_none,bedg_right,bedg_top,bedg_left,bedg_bottom); + + tagmouseprocty = procedure (const tag: integer; + const info: mouseeventinfoty) of object; + + captioninfoty = record + dim: rectty; + caption: richstringty; + font: tfont; + textflags: textflagsty; + imagepos: imageposty; + captiondist: integer; + imagenr: imagenrty; + colorglyph: colorty; + imagelist: timagelist; + imagedist: integer; + imagedist1: integer; //left or top + imagedist2: integer; //right or bottom + captionclipped: boolean; + end; + + shapeinfoty = record + ca: captioninfoty; + focusrectdist: integer; + state: shapestatesty; + tabpos: integer; + group: integer; + color: colorty; + coloractive: colorty; + facetemplate: tfacetemplate; + imagenrdisabled: integer; //-2 -> grayed + imagecheckedoffset: integer; + face: tcustomface; + frame: tcustomframe; + checkboxframe: tframetemplate; + mouseframe: framety; + tag: integer; + doexecute: tagmouseprocty; + end; + pshapeinfoty = ^shapeinfoty; + + shapeinfoarty = array of shapeinfoty; + pshapeinfoarty = ^shapeinfoarty; + + getbuttonhintty = function(const aindex: integer): msestring of object; + getbuttonhintposty = function(const aindex: integer): rectty of object; + +procedure updateedgerect(var arect: rectty; const awidth: integer; + const hiddenedges: edgesty); +procedure draw3dframe(const canvas: tcanvas; const arect: rectty; + level: integer; colorinfo: edgecolorpairinfoty; + const hiddenedges: edgesty); +procedure drawimageframe(const canvas: tcanvas; const imagelist: timagelist; + const imageoffs: int32; const dest: rectty; + const hiddenedges: edgesty); +procedure drawfocusrect(const canvas: tcanvas; const arect: rectty); +procedure drawtoolbutton(const canvas: tcanvas; var info: shapeinfoty); +procedure drawbutton(const canvas: tcanvas; const info: shapeinfoty); +procedure drawmenubutton(const canvas: tcanvas; var info: shapeinfoty; + const innerframe: pframety = nil); +procedure drawtab(const canvas: tcanvas; var info: shapeinfoty; + const innerframe: pframety = nil); +function updatemouseshapestate(var info: shapeinfoty; + const mouseevent: mouseeventinfoty; + const widget: twidget; const aframe: tcustomframe; + const infoarpo: pshapeinfoarty = nil; + const canclick: boolean = true): boolean; overload; +function updatemouseshapestate(var infos: shapeinfoarty; + const mouseevent: mouseeventinfoty; + const widget: twidget; var focuseditem: integer; + const aframe: tcustomframe = nil): boolean; overload; + //true on change, calls widget.invalidaterect +function getmouseshape(const infos: shapeinfoarty): integer; + //returns shape index under mouse, -1 if none +function updatewidgetshapestate(var info: shapeinfoty; const widget: twidget; + const adisabled: boolean = false; +// const ainvisible: boolean = false; + const aframe: tcustomframe = nil): boolean; +function findshapeatpos(const infoar: shapeinfoarty; const apos: pointty; + const rejectstates: shapestatesty = + [shs_disabled,shs_invisible]): integer; +function pointinshape(const pos: pointty; const info: shapeinfoty): boolean; +procedure initshapeinfo(var ainfo: shapeinfoty); + +procedure actioninfotoshapeinfo(var actioninfo: actioninfoty; + var shapeinfo: shapeinfoty); overload; +procedure actioninfotoshapeinfo(const sender: twidget; + var actioninfo: actioninfoty; var shapeinfo: shapeinfoty; + const aoptions: buttonoptionsty); +procedure frameskinoptionstoshapestate(const aframe: tcustomframe; + var dest: shapeinfoty{shapestatesty}); +function shapestatetoframestate(const aindex: integer; + const ashapes: shapeinfoarty): framestateflagsty; + +procedure checkbuttonhint(const awidget: twidget; info: mouseeventinfoty; + var hintedbutton: integer; const cells: shapeinfoarty; + const getbuttonhint: getbuttonhintty; + const gethintpos: getbuttonhintposty); + +procedure drawcaption(const acanvas: tcanvas; var ainfo: captioninfoty); +procedure initcaptioninfo(var ainfo: captioninfoty); +function calccaptionsize(const acanvas: tcanvas; const ainfo: captioninfoty; + const captionframe: pframety = nil): sizety; + +//var +// animatemouseenter: boolean = true; + +implementation +uses + classes,msestockobjects,msebits,sysutils,mseassistiveserver; +type + twidget1 = class(twidget); + tframe1 = class(tcustomframe); +var + buttontab: tcustomtabulators; + +procedure frameskinoptionstoshapestate(const aframe: tcustomframe; + var dest: shapeinfoty{shapestatesty}); +begin + if aframe <> nil then begin + updatebit(longword(dest.state),ord(shs_flat),fso_flat in aframe.optionsskin); + updatebit(longword(dest.state),ord(shs_noanimation),fso_noanim in aframe.optionsskin); + updatebit(longword(dest.state),ord(shs_nomouseanimation), + fso_nomouseanim in aframe.optionsskin); + updatebit(longword(dest.state),ord(shs_noclickanimation), + fso_noclickanim in aframe.optionsskin); + updatebit(longword(dest.state),ord(shs_nofocusanimation), + fso_nofocusanim in aframe.optionsskin); + updatebit(longword(dest.state),ord(shs_showfocusrect), + not(fso_nofocusrect in aframe.optionsskin)); + updatebit(longword(dest.state),ord(shs_showdefaultrect), + not (fso_nodefaultrect in aframe.optionsskin)); + updatebit(longword(dest.state),ord(shs_noinnerrect), + fso_noinnerrect in aframe.optionsskin); + if shs_noinnerrect in dest.state then begin + dest.mouseframe:= aframe.frameo; + end + else begin + dest.mouseframe:= nullframe; + end; + if aframe = dest.frame then begin + addframe1(dest.mouseframe,aframe.paintframe); + end; + end + else begin + dest.state:= (dest.state - [shs_flat,shs_noanimation,shs_nomouseanimation, + shs_noclickanimation,shs_nofocusanimation, + shs_noinnerrect]) + + [shs_showfocusrect,shs_showdefaultrect]; + dest.mouseframe:= nullframe; + end; +end; + +procedure checkbuttonhint(const awidget: twidget; info: mouseeventinfoty; + var hintedbutton: integer; const cells: shapeinfoarty; + const getbuttonhint: getbuttonhintty; + const gethintpos: getbuttonhintposty); +var + int1: integer; + mstr1: msestring; +begin + if (info.eventkind = ek_clientmouseleave) then begin + if hintedbutton >= 0 then begin + application.hidehint; + end; + hintedbutton:= -1; + exit; + end; + int1:= getmouseshape(cells); + if (info.eventkind in [ek_buttonpress,ek_buttonrelease]) then begin + if hintedbutton >= 0 then begin + application.hidehint; + hintedbutton:= -(hintedbutton+3); + end + else begin + if int1 >= 0 then begin + hintedbutton:= -(int1+3); + end; + end; + exit; + end; + if (info.eventkind in [ek_mousemove,ek_mousepark]) and + not (csdesigning in awidget.componentstate) then begin + if (int1 >= 0) then begin + if (int1 <> hintedbutton) and (-(int1+3) <> hintedbutton) then begin + if twidget1(awidget).getshowhint and ((info.eventkind = ek_mousepark) or + (hintedbutton >= 0)) + {(application.activehintedwidget = awidget)} then begin + if cells[int1].state * [shs_separator,shs_clicked] = [] then begin + hintedbutton:= int1; + mstr1:= getbuttonhint(int1); + if (mstr1 <> '') and application.active then begin + application.showhint(awidget,mstr1,gethintpos(int1), + cp_bottomleft,-1,[hfl_noautohidemove]); + end + else begin + application.hidehint; + end; + end; + end + else begin + application.hidehint; + end; + end; + end + else begin + if hintedbutton >= 0 then begin + application.hidehint; + hintedbutton:= -1; + end; + end; + end; +end; + +procedure actioninfotoshapeinfo(var actioninfo: actioninfoty; + var shapeinfo: shapeinfoty); +begin + with actioninfo do begin + actionstatestoshapestates(actioninfo,shapeinfo.state); + shapeinfo.ca.caption:= caption1; + shapeinfo.ca.imagelist:= timagelist(imagelist); + shapeinfo.ca.imagenr:= imagenr; + shapeinfo.imagenrdisabled:= imagenrdisabled; + shapeinfo.ca.colorglyph:= colorglyph; + shapeinfo.color:= color; + shapeinfo.imagecheckedoffset:= imagecheckedoffset; + shapeinfo.group:= group; + end; +end; + +procedure actioninfotoshapeinfo(const sender: twidget; + var actioninfo: actioninfoty; var shapeinfo: shapeinfoty; + const aoptions: buttonoptionsty); +var + statebefore: actionstatesty; +begin + if not (csloading in sender.componentstate) then begin + with actioninfo do begin + statebefore:= state; + if (sender.enabled) <> not (as_disabled in state) then begin + if not (as_disabled in state) or + not (as_syncdisabledlocked in state) and + (not (bo_noassistivedisabled in aoptions) or + not sender.canassistive() and + not (csdesigning in sender.componentstate)) then begin + sender.enabled:= not(as_disabled in state); + end; + end; + if (sender.visible) <> not (as_invisible in state) then begin + sender.visible:= not(as_invisible in state); + end; + state:= statebefore; //restore localflag + actioninfotoshapeinfo(actioninfo,shapeinfo); + updatewidgetshapestate(shapeinfo,sender,as_disabled in state, + twidget1(sender).fframe); + //update shs_disabled by isenabled + sender.invalidate; + end; + end; +end; + +procedure initcaptioninfo(var ainfo: captioninfoty); +begin + with ainfo do begin + captiondist:= defaultshapecaptiondist; + textflags:= defaultcaptiontextflags; +// textflags:= [tf_default]; + end; +end; + +procedure initshapeinfo(var ainfo: shapeinfoty); +begin + with ainfo do begin + initcaptioninfo(ainfo.ca); + focusrectdist:= defaultshapefocusrectdist; + end; +end; + +procedure setchecked(var info: shapeinfoty; const value: boolean; + const widget: twidget); +begin + with info do begin + if value xor (shs_checked in state) then begin + widget.invalidaterect(ca.dim); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(info.state), + ord(shs_checked),value); + end; + end; +end; + +function updatewidgetshapestate(var info: shapeinfoty; const widget: twidget; + const adisabled: boolean = false; + const aframe: tcustomframe = nil): boolean; +var + statebefore: shapestatesty; + rect1: rectty; +begin + with info do begin + statebefore:= state; + updatebit(longword(state),ord(shs_disabled),not widget.isenabled or adisabled); + updatebit(longword(state),ord(shs_focused),widget.active); + result:= state <> statebefore; + if result then begin + rect1:= ca.dim; + if (aframe <> nil) and tframe1(aframe).needsactiveinvalidate then begin + inflaterect1(rect1,aframe.innerframe); + end; + if shs_widgetorg in state then begin + widget.invalidaterect(rect1,org_widget); + end + else begin + widget.invalidaterect(rect1); + end; + end; + end; +end; + +procedure updateshapemoveclick(const infoarpo: pshapeinfoarty; value: boolean); +var + int1: integer; +begin + if infoarpo <> nil then begin + for int1:= 0 to high(infoarpo^) do begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(infoarpo^[int1].state), + ord(shs_moveclick),value); + end; + end; +end; + +function pointinshape(const pos: pointty; const info: shapeinfoty): boolean; +begin + if shs_ellipsemouse in info.state then begin + result:= pointinellipse(pos,deflaterect(info.ca.dim,info.mouseframe)); + end + else begin + result:= pointinrect(pos,deflaterect(info.ca.dim,info.mouseframe)); + end; + if result and (info.frame <> nil) then begin + result:= info.frame.pointinmask(pos,info.ca.dim); + end; +end; + +function updatemouseshapestate(var info: shapeinfoty; + const mouseevent: mouseeventinfoty; + const widget: twidget; const aframe: tcustomframe; + const infoarpo: pshapeinfoarty = nil; + const canclick: boolean = true): boolean; + //true on change +var + statebefore: shapestatesty; + int1: integer; + po1: pshapeinfoty; + bo1: boolean; +// rect1: rectty; + +begin + result:= false; + bo1:= (widget = nil) or widget.isenabled; + with info,mouseevent do begin + statebefore:= state; + if es_drag in eventstate then begin + state:= state - [shs_mouse,shs_clicked]; + updateshapemoveclick(infoarpo,false); + end + else begin + if not (shs_invisible in state) and bo1 then begin + case eventkind of + ek_clientmouseleave,ek_mouseleave: begin + if (eventkind = ek_mouseleave) or not (shs_widgetorg in state) then begin + state:= state - [shs_mouse,shs_clicked]; + end; + end; + ek_mousemove,ek_mousepark: begin +// if pointinrect(pos,ca.dim) then begin + if pointinshape(pos,info) then begin + state:= state + [shs_mouse]; + if (ss_left in shiftstate) and + (state * [shs_disabled,shs_moveclick] = [shs_moveclick]) then begin + state:= state + [shs_clicked]; + end; + end + else begin + state:= state - [shs_mouse,shs_clicked]; + end; + end; + ek_buttonrelease: begin + if button = mb_left then begin + updateshapemoveclick(infoarpo,false); + exclude(state,shs_moveclick); + if not (shs_disabled in state) or + (widget <> nil) and (csdesigning in widget.componentstate) then begin + if state * [shs_clicked,shs_checkbox,shs_radiobutton] = + [shs_clicked,shs_checkbox] then begin + setchecked(info,not (shs_checked in state),widget); + end; + if state * [shs_clicked,shs_radiobutton] = + [shs_clicked,shs_radiobutton] then begin + if [shs_checked,shs_checkbox] * state = + [shs_checked,shs_checkbox] then begin + setchecked(info,false,widget); + end + else begin + if (infoarpo <> nil) then begin + for int1:= 0 to high(infoarpo^) do begin + po1:= @infoarpo^[int1]; + if (po1 <> @info) and (po1^.group = info.group) and + (shs_radiobutton in po1^.state) then begin + setchecked(po1^,false,widget); + end; + end; + setchecked(info,true,widget); + end; + end; + end; + if {(eventkind = ek_buttonrelease) and} (shs_clicked in state) and + assigned(doexecute) then begin + state:= state - [shs_clicked]; + result:= true; //state can be invalid after execute + if widget <> nil then begin //info can be invalid after execute + if (aframe <> nil) and tframe1(aframe).needsmouseinvalidate then begin + widget.invalidaterect(inflaterect(ca.dim,aframe.innerframe)); + end + else begin + widget.invalidaterect(ca.dim); + end; + twidget1(widget).releasebuttonpressgrab(); + end; + doexecute(tag,mouseevent); + exit; + end; + end; + state:= state - [shs_clicked]; + end; + end; + ek_buttonpress: begin + if canclick and (button = mb_left) and + (not(shs_disabled in state) or + (widget <> nil) and (csdesigning in widget.componentstate) and + not (ws1_nodisabledclick in twidget1(widget).fwidgetstate1)) + and pointinshape(pos,info) then begin + state:= state + [shs_clicked,shs_moveclick]; + updateshapemoveclick(infoarpo,true); + end; + end; + end; + end + else begin + state:= state - [shs_mouse,shs_clicked]; + end; + end; + result:= result or (state <> statebefore); + if result and (widget <> nil) then begin + if (aframe <> nil) and tframe1(aframe).needsmouseinvalidate then begin + widget.invalidaterect(inflaterect(ca.dim,aframe.innerframe)); + end + else begin + widget.invalidaterect(ca.dim); + end; + end; + end; +end; + +function updatemouseshapestate(var infos: shapeinfoarty; + const mouseevent: mouseeventinfoty; + const widget: twidget; var focuseditem: integer; + const aframe: tcustomframe = nil): boolean; +var + int1,i2: integer; +begin + result:= false; + i2:= focuseditem; + focuseditem:= -1; //none + for int1:= 0 to high(infos) do begin + result:= updatemouseshapestate(infos[int1],mouseevent,widget, + aframe,@infos) or result; + if shs_mouse in infos[int1].state then begin + focuseditem:= int1; + if i2 <> int1 then begin + { necessary? + if (focuseditem >= 0) and (focuseditem <= high(infos)) then begin + widget.invalidaterect(infos[focuseditem].ca.dim); + end; + } + if (int1 >= 0) and (assistiveserver <> nil) then begin + assistiveserver.doitementer(getiassistiveclient(widget),infos,int1); + end; + end; + end; + end; +end; + +function getmouseshape(const infos: shapeinfoarty): integer; + //returns shape index under mouse, -1 if none +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(infos) do begin + if shs_mouse in infos[int1].state then begin + result:= int1; + break; + end; + end; +end; + +function findshapeatpos(const infoar: shapeinfoarty; const apos: pointty; + const rejectstates: shapestatesty = + [shs_disabled,shs_invisible]): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(infoar) do begin + with infoar[int1] do begin + if (state * rejectstates = []) and pointinrect(apos,ca.dim) then begin + result:= int1; + break; + end; + end; + end; +end; + +function shapestatetoframestate(const aindex: integer; + const ashapes: shapeinfoarty): framestateflagsty; +var + state1: shapestatesty; +begin + result:= []; + if aindex <= high(ashapes) then begin + state1:= ashapes[aindex].state; + if shs_disabled in state1 then begin + include(result,fsf_disabled); + end; + if [shs_active{,shs_focused}] * state1 <> [] then begin + include(result,fsf_active); + end; + if shs_mouse in state1 then begin + include(result,fsf_mouse); + end; + if shs_clicked in state1 then begin + include(result,fsf_clicked); + end; + end; +end; + +procedure updateedgerect(var arect: rectty; const awidth: integer; + const hiddenedges: edgesty); +begin + if not (edg_right in hiddenedges) then begin + dec(arect.cx,awidth); + end; + if not (edg_top in hiddenedges) then begin + inc(arect.y,awidth); + dec(arect.cy,awidth); + end; + if not (edg_left in hiddenedges) then begin + inc(arect.x,awidth); + dec(arect.cx,awidth); + end; + if not (edg_bottom in hiddenedges) then begin + dec(arect.cy,awidth); + end; +end; + +procedure draw3dframe(const canvas: tcanvas; + const arect: rectty; level: integer; + colorinfo: edgecolorpairinfoty; const hiddenedges: edgesty); +//todo: optimize + +type + cornerinfoty = record + col1,col2: colorty; + w1,w2: integer; + end; + pcornerinfoty = ^cornerinfoty; + +var + poly: array[0..5] of pointty; + + procedure drawcorner(const cornerinfo: cornerinfoty; + const firstoff,lastoff,startoff,stopoff: boolean; + const topleft: boolean); + + procedure calculatepoly(w: integer); + begin + poly[3].x:= poly[2].x - w; + poly[3].y:= poly[2].y + w; + poly[4].x:= poly[1].x + w; + poly[4].y:= poly[3].y; + poly[5].x:= poly[4].x; + poly[5].y:= poly[0].y - w; + if (w = 1) and topleft then begin + dec(poly[0].y); + dec(poly[2].x); + end; + if startoff then begin + if topleft then begin + poly[0].y:= arect.y + arect.cy; + if w = 1 then begin + dec(poly[0].y); + end; + end + else begin + poly[0].y:= arect.y; + end; + poly[5].y:= poly[0].y; + end; + if stopoff then begin + if topleft then begin + poly[2].x:= arect.x + arect.cx; + if w = 1 then begin + dec(poly[2].x); + end; + end + else begin + poly[2].x:= arect.x; + end; + poly[3].x:= poly[2].x; + end; + + if firstoff then begin + if topleft then begin + poly[1].x:= arect.x; + poly[4].x:= poly[1].x; + end + else begin + poly[1].x:= arect.x+arect.cx; + if w = 1 then begin + dec(poly[1].x); + end; + poly[4].x:= poly[1].x; + end; + poly[0]:= poly[1]; + poly[5]:= poly[4]; + end; + if lastoff then begin + if topleft then begin + poly[1].y:= arect.y; + poly[4].y:= poly[1].y; + end + else begin + poly[4].y:= arect.y+arect.cy; + if w = 1 then begin + dec(poly[4].y); + end; + poly[1].y:= poly[4].y; + end; + poly[2]:= poly[1]; + poly[3]:= poly[4]; + end; + end; //calculatepoly + + begin + with canvas,cornerinfo do begin + calculatepoly(w1); + if w1 > 0 then begin + if w1 = 1 then begin + drawlines(poly,false,col1,0,3); + end + else begin + fillpolygon(poly,col1); + end; + end; + if w2 > 0 then begin + poly[0]:= poly[5]; + poly[1]:= poly[4]; + poly[2]:= poly[3]; + calculatepoly(w2); + if w2 = 1 then begin + drawlines(poly,false,col2,0,3); + end + else begin + fillpolygon(poly,col2); + end; + end; + end; + end; + +var + lightcorner,shadowcorner: cornerinfoty; + down: boolean; + int1: integer; + po1: pcornerinfoty; +begin + if (level = 0) or (arect.cx = 0) or (arect.cy = 0) then begin + exit; + end; + with colorinfo do begin + if shadow.effectcolor = cl_default then begin + shadow.effectcolor:= defaultframecolors.edges.shadow.effectcolor; + end; + if shadow.color = cl_default then begin + shadow.color:= defaultframecolors.edges.shadow.color; + end; + if light.color = cl_default then begin + light.color:= defaultframecolors.edges.light.color; + end; + if light.effectcolor = cl_default then begin + light.effectcolor:= defaultframecolors.edges.light.effectcolor; + end; + if shadow.effectwidth < 0 then begin + shadow.effectwidth:= defaultframecolors.edges.shadow.effectwidth; + end; + if light.effectwidth < 0 then begin + light.effectwidth:= defaultframecolors.edges.light.effectwidth; + end; + end; + if level < 0 then begin + down:= true; + level:= -level; + end + else begin + down:= false; + end; + + with lightcorner,colorinfo.light do begin + int1:= abs(effectwidth); + if int1 > level then begin + col1:= effectcolor; + w1:= level; + w2:= 0; + end + else begin + if (effectwidth < 0){ xor down} then begin + col1:= effectcolor; + col2:= color; + w1:= int1; + w2:= level - int1; + end + else begin + col1:= color; + col2:= effectcolor; + w1:= level - int1; + w2:= int1; + end; + end; + end; + with shadowcorner,colorinfo.shadow do begin + int1:= abs(effectwidth); + if int1 > level then begin + col1:= color; + w1:= level; + w2:= 0; + end + else begin + if level - int1 < 1 then begin //reduce dkshadow + int1:= level - 1; + end; + if (effectwidth < 0){ xor down} then begin + col1:= effectcolor; + col2:= color; + w1:= int1; + w2:= level-int1; + end + else begin + col1:= color; + col2:= effectcolor; + w1:= level-int1; + w2:= int1; + end; + end; + end; + + with arect do begin + if hiddenedges * [edg_left,edg_top] <> [edg_left,edg_top] then begin + poly[0].x:= x; + poly[0].y:= y + cy; + poly[1]:= pos; + poly[2].x:= x + cx; + poly[2].y:= y; + + if down then begin //topleft + po1:= @shadowcorner; + end + else begin + po1:= @lightcorner; + if (level > 2) and (hiddenedges * [edg_left,edg_top] = []) then begin + canvas.drawline(pos,makepoint(pos.x+level-1,pos.y+level-1), + colorinfo.light.effectcolor); + end; + end; + drawcorner(po1^,edg_left in hiddenedges,edg_top in hiddenedges, + edg_bottom in hiddenedges,edg_right in hiddenedges,true); + if not down and (level > 2) and + (hiddenedges * [edg_left,edg_top] = []) then begin + canvas.drawline(pos,makepoint(pos.x+level-1,pos.y+level-1), + colorinfo.light.effectcolor); + end; + end; + if hiddenedges * [edg_right,edg_bottom] <> [edg_right,edg_bottom] then begin + poly[0].x:= x + cx - level; + poly[0].y:= y + level - 1; + poly[1].x:= poly[0].x; + poly[1].y:= y + cy - level; + poly[2].x:= x + level; + poly[2].y:= poly[1].y; + + if down then begin //bottomright + po1:= @lightcorner; + end + else begin + po1:= @shadowcorner; + end; + drawcorner(po1^,edg_right in hiddenedges,edg_bottom in hiddenedges, + edg_top in hiddenedges,edg_left in hiddenedges,false); + end; + end; +end; + +procedure drawimageframe(const canvas: tcanvas; const imagelist: timagelist; + const imageoffs: int32; const dest: rectty; + const hiddenedges: edgesty); +var + imagesize1: sizety; + rect1: rectty; +begin + if (imageoffs >= -8) and (imagelist.bitmap.hasimage) then begin + imagesize1:= imagelist.size; + if not (edg_left in hiddenedges) then begin + imagelist.paintlookup(canvas,imageoffs+0,dest.pos); //topleft + rect1.x:= dest.x; + rect1.y:= dest.y + imagesize1.cy; + rect1.cx:= imagesize1.cx; + rect1.cy:= dest.cy - imagesize1.cy -imagesize1.cy; + imagelist.paintlookup(canvas,imageoffs+1,rect1,[al_stretchy]); //left + if edg_bottom in hiddenedges then begin + imagelist.paintlookup(canvas,imageoffs+2, + mp(rect1.x,rect1.y+rect1.cy)); //bottomleft + end; + end; + if not (edg_bottom in hiddenedges) then begin + rect1.x:= dest.x; + rect1.y:= dest.y + dest.cy - imagesize1.cy; + imagelist.paintlookup(canvas,imageoffs+2,rect1.pos); //bottomleft + rect1.x:= dest.x + imagesize1.cx; + rect1.cy:= imagesize1.cy; + rect1.cx:= dest.cx - imagesize1.cx -imagesize1.cx; + imagelist.paintlookup(canvas,imageoffs+3,rect1,[al_stretchx]); //bottom + if edg_right in hiddenedges then begin + imagelist.paintlookup(canvas,imageoffs+4, + mp(rect1.x+rect1.cx,rect1.y)); //bottomright + end; + end; + if not (edg_right in hiddenedges) then begin + rect1.x:= dest.x + dest.cx - imagesize1.cx; + rect1.y:= dest.y + dest.cy - imagesize1.cy; + imagelist.paintlookup(canvas,imageoffs+4,rect1.pos); //bottomright + rect1.y:= dest.y + imagesize1.cy; + rect1.cx:= imagesize1.cx; + rect1.cy:= dest.cy - imagesize1.cy - imagesize1.cy; + imagelist.paintlookup(canvas,imageoffs+5,rect1,[al_stretchy]); //right + if edg_top in hiddenedges then begin + imagelist.paintlookup(canvas,imageoffs+6,mp(rect1.x,dest.y)); + //topright + end; + end; + if not (edg_top in hiddenedges) then begin + rect1.x:= dest.x + dest.cx - imagesize1.cx; + rect1.y:= dest.y; + imagelist.paintlookup(canvas,imageoffs+6,rect1.pos); //topright + rect1.x:= dest.x + imagesize1.cx; + rect1.cy:= imagesize1.cy; + rect1.cx:= dest.cx - imagesize1.cx - imagesize1.cx; + imagelist.paintlookup(canvas,imageoffs+7,rect1,[al_stretchx]); //top + if edg_left in hiddenedges then begin + imagelist.paintlookup(canvas,imageoffs+0,mp(dest.x,dest.y)); + //topleft + end; + end; + end; +end; + +procedure drawfocusrect(const canvas: tcanvas; const arect: rectty); +begin + canvas.drawxorframe(arect,-1,stockobjects.bitmaps[stb_block1]); +end; + +function drawbuttonframe(const canvas: tcanvas; const info: shapeinfoty; + out clientrect: rectty; + const hiddenedges: edgesty = []): boolean; + //true if clientrect not empty +var + level: integer; + col1: colorty; + rect1: rectty; +begin + result:= false; + with canvas,info do begin + if shs_separator in state then begin + if not (shs_flat in state) then begin + draw3dframe(canvas,ca.dim,-1,defaultframecolors.edges,[]); + end; + end + else begin + if shs_flat in state then begin + level:= 0; + end + else begin + level:= 1; + end; + if not (shs_noanimation in state) then begin + if not (shs_nomouseanimation in state) and + (shs_mouse in state) and not (shs_disabled in state) or + (state * [shs_nofocusanimation,shs_focused,shs_focusanimation] = + [shs_focused,shs_focusanimation]) then begin + inc(level); + end; + if not (shs_noclickanimation in state) and (shs_clicked in state) or + (state * [shs_checked,shs_checkbutton] = + [shs_checked,shs_checkbutton]) then begin + level:= -1; + end; + end; + clientrect:= ca.dim; + if (state * [shs_focused,shs_showdefaultrect] = + [shs_focused,shs_showdefaultrect]) or + (state * [shs_disabled,shs_default] = [shs_default]) then begin + if not (aso_nodefaultbutton in assistiveoptions) then begin + //no default button if assisted + canvas.drawframe(clientrect,-1,cl_buttondefaultrect); + inflaterect1(clientrect,-1); + end; + end; + rect1:= clientrect; + if (clientrect.cx > 0) and (clientrect.cy > 0) then begin + col1:= color; + if shs_active in state then begin + col1:= coloractive; + end; + if col1 <> cl_transparent then begin + fillrect(clientrect,col1); + end; + if facetemplate <> nil then begin + facetemplate.paint(canvas,clientrect); + end + else begin + if face <> nil then begin + face.paint(canvas,clientrect); + end; + end; + end; + draw3dframe(canvas,rect1,level,defaultframecolors.edges,hiddenedges); + end; + inflaterect1(clientrect,-abs(level),hiddenedges); + result:= (clientrect.cx > 0) and (clientrect.cy > 0); + end; +end; + +function adjustimagerect(const canvas: tcanvas; const info: captioninfoty; + var arect: rectty; out aalign: alignmentsty): rectty; +var + pos: imageposty; + i1,i2: integer; + rect1,rect2: rectty; +begin + result:= arect; + with info do begin + pos:= simpleimagepos[imagepos]; + if pos in (vertimagepos) then begin +// if result.cx < imagelist.width then begin + i1:= result.cx - imagelist.width; + if i1 < 0 then begin + dec(i1); + end; +// end; + inc(result.x,imagedist1 + (i1 - imagedist1 - imagedist2) div 2); + result.cx:= imagelist.width; + end + else begin + i1:= result.cy - imagelist.height; + if i1 < 0 then begin + dec(i1); + end; + inc(result.y,imagedist1 + (i1 - imagedist1 - imagedist2) div 2); + result.cy:= imagelist.height; + end; + + case pos of + ip_right: begin + aalign:= [al_right]; + case imagepos of + ip_righttop: begin + result.y:= arect.y + imagedist1; + end; + ip_rightbottom: begin + result.y:= arect.cy - imagedist2 - imagelist.height; + end; + end; + dec(result.cx,imagedist); + end; + ip_left: begin + aalign:= []; + case imagepos of + ip_lefttop: begin + result.y:= arect.y + imagedist1; + end; + ip_leftbottom: begin + result.y:= arect.cy - imagedist2 - imagelist.height; + end; + end; + inc(result.x,imagedist); + dec(result.cx,imagedist); + end; + ip_bottom: begin + aalign:= [al_bottom]; + case imagepos of + ip_bottomleft: begin + result.x:= arect.x + imagedist1; + end; + ip_bottomright: begin + result.x:= arect.cx - imagedist2 - imagelist.width; + end; + end; + dec(result.cy,imagedist); + end; + ip_top: begin + aalign:= []; + case imagepos of + ip_topleft: begin + result.x:= arect.x + imagedist1; + end; + ip_topright: begin + result.x:= arect.cx - imagedist2 - imagelist.width; + end; + end; + inc(result.y,imagedist); + dec(result.cy,imagedist); + end; + ip_center: begin + aalign:= [al_xcentered,al_ycentered]; + inc(result.x,imagedist); + end; + ip_centervert: begin + aalign:= [al_xcentered,al_ycentered]; + inc(result.y,imagedist); + end; + end; + i1:= imagelist.width + imagedist; + i2:= imagelist.height + imagedist; + case pos of + ip_right: begin + dec(arect.cx,i1); + end; + ip_left: begin + inc(arect.x,i1); + dec(arect.cx,i1); + end; + ip_top: begin + inc(arect.y,i2); + dec(arect.cy,i2); + end; + ip_bottom: begin + dec(arect.cy,i2); + end; + end; + if (tf_glueimage in info.textflags) and + not (pos in [ip_center,ip_centervert]) then begin + rect1:= arect; + if pos in (vertimagepos) then begin + rect1.cy:= rect1.cy - captiondist; + rect2:= textrect(canvas,caption,rect1,textflags,font); + i1:= rect1.cy - rect2.cy; + if i1 > 0 then begin + if tf_ycentered in textflags then begin + i1:= i1 div 2; + if pos in bottomimagepos then begin + result.y:= result.y - i1; + end + else begin + result.y:= result.y + i1; + end; + end + else begin + if tf_bottom in textflags then begin + if not (pos in bottomimagepos) then begin + result.y:= result.y + i1 - imagedist; + end; + end + else begin + if pos in bottomimagepos then begin + result.y:= result.y - i1 + imagedist; + end; + end; + end; + end; + end + else begin + rect1.cx:= rect1.cx - captiondist; + rect2:= textrect(canvas,caption,rect1,textflags,font); + i1:= rect1.cx - rect2.cx; + if i1 > 0 then begin + if tf_xcentered in textflags then begin + i1:= i1 div 2; + if pos in rightimagepos then begin + result.x:= result.x - i1; + end + else begin + result.x:= result.x + i1; + end; + end + else begin + if tf_right in textflags then begin + if not (pos in rightimagepos) then begin + result.x:= result.x + i1 - imagedist; + end; + end + else begin + if pos in rightimagepos then begin + result.x:= result.x - i1 + imagedist; + end; + end; + end; + end; + end; + end; + end; +end; + +function drawbuttonimage(const canvas: tcanvas; const info: shapeinfoty; + var arect: rectty): boolean; +var + align1: alignmentsty; + rect1: rectty; + int1: integer; + reg1: regionty; + co1: colorty; +begin + co1:= 0; + with canvas,info do begin + if (ca.imagelist <> nil) then begin + reg1:= canvas.copyclipregion; + canvas.intersectcliprect(arect); + result:= true; + rect1:= adjustimagerect(canvas,info.ca,arect,align1); + if shs_disabled in state then begin + int1:= imagenrdisabled; + if int1 = -2 then begin + int1:= ca.imagenr; + include(align1,al_grayed); + end; + end + else begin + int1:= ca.imagenr; + end; + if (shs_checked in state) and (int1 >= 0) then begin + inc(int1,imagecheckedoffset); + end; + if state*[shs_focuscolor,shs_focused] = + [shs_focuscolor,shs_focused] then begin + canvas.fillrect(rect1,cl_selectedtextbackground); + co1:= cl_selectedtext; + end + else begin + if ca.colorglyph <> cl_none then begin + co1:= ca.colorglyph; + if co1 = cl_default then begin + co1:= cl_glyph; + end; + end; + end; + ca.imagelist.paint(canvas,int1,rect1,align1,co1); + canvas.clipregion:= reg1; + end + else begin + result:= false; + end; + end; +end; + +procedure drawbuttoncaption(const canvas: tcanvas; const info: shapeinfoty; + const arect: rectty; const pos: imageposty; const outerrect: prectty); +var + textflags: textflagsty; + rect1: rectty; + tab1: tcustomtabulators; +begin + with canvas,info do begin + tab1:= nil; + if ca.caption.text <> '' then begin + rect1:= arect; + if info.frame <> nil then begin + deflaterect1(rect1,info.frame.framei); + end; + textflags:= ca.textflags + [tf_clipi]; + case pos of + ip_left,ip_lefttop,ip_leftbottom: begin + if tf_right in textflags then begin + dec(rect1.x,ca.captiondist); + end + else begin + inc(rect1.x,ca.captiondist); + dec(rect1.cx,ca.captiondist); + end; + if countchars(ca.caption.text,msechar(c_tab)) = 1 then begin + tab1:= buttontab; + tab1[0].pos:= info.tabpos / defaultppmm; + end; + end; + ip_right,ip_righttop,ip_rightbottom: begin + if textflags * [tf_right,tf_xcentered] = [] then begin + inc(rect1.x,ca.captiondist); + end; + dec(rect1.cx,ca.captiondist); + end; + ip_top,ip_topleft,ip_topright: begin + if tf_bottom in textflags then begin + dec(rect1.y,ca.captiondist); + end + else begin + inc(rect1.y,ca.captiondist); + dec(rect1.cy,ca.captiondist); + end; + end; + ip_bottom,ip_bottomleft,ip_bottomright: begin + if textflags * [tf_bottom,tf_ycentered] = [] then begin + inc(rect1.y,ca.captiondist); + end; + dec(rect1.cy,ca.captiondist); + end; + end; + if shs_disabled in state then begin + include(textflags,tf_grayed); + end; + if outerrect <> nil then begin + exclude(textflags,tf_clipi); + include(textflags,tf_clipo); + drawtext(canvas,ca.caption,rect1,outerrect^,textflags,ca.font,tab1); + end + else begin + drawtext(canvas,ca.caption,rect1,arect,textflags,ca.font,tab1); + end; + end; + end; +end; + +procedure drawbutton(const canvas: tcanvas; const info: shapeinfoty); +var + rect1,rect2: rectty; +// pos: captionposty; + pos1: imageposty; +begin + if not (shs_invisible in info.state) and + drawbuttonframe(canvas,info,rect1) then begin + rect2:= rect1; + drawbuttonimage(canvas,info,rect1); + with canvas,info do begin + if state * [shs_focused,shs_showfocusrect] = + [shs_focused,shs_showfocusrect] then begin + drawfocusrect(canvas,inflaterect(rect2,-focusrectdist)); + end; + pos1:= info.ca.imagepos; + if info.ca.imagelist = nil then begin + if tf_right in ca.textflags then begin + pos1:= ip_right; + end + else begin + if (tf_left in ca.textflags) or + (info.ca.textflags * [tf_xcentered,tf_xjustify] = []) then begin + pos1:= ip_left; + end + else begin + if tf_bottom in info.ca.textflags then begin + pos1:= ip_bottom; + end + else begin + if (tf_top in info.ca.textflags) or + (info.ca.textflags * [tf_ycentered] = []) then begin + pos1:= ip_top; + end; + end; + end; + end; + end; + drawbuttoncaption(canvas,info,rect1,pos1,nil); + end; + end; +end; + +procedure drawcaption(const acanvas: tcanvas; var ainfo: captioninfoty); +var + rect1,rect2: rectty; + align1: alignmentsty; + info1: drawtextinfoty; +begin + with ainfo do begin + rect2:= ainfo.dim; + if ainfo.imagelist <> nil then begin + rect1:= adjustimagerect(acanvas,ainfo,rect2,align1); + if colorglyph <> cl_none then begin + imagelist.paint(acanvas,imagenr,rect1,align1,colorglyph); + end; + end; + case imagepos of + ip_left{,ip_leftcenter}: begin + inc(rect2.x,captiondist); + dec(rect2.cx,captiondist); + end; + ip_right{,ip_rightcenter}: begin + dec(rect2.cx,captiondist); + end; + ip_top{,ip_topcenter}: begin + inc(rect2.y,captiondist); + dec(rect2.cy,captiondist); + end; + ip_bottom{,ip_bottomcenter}: begin + dec(rect2.cy,captiondist); + end; + end; + info1.text:= caption; + info1.dest:= rect2; + info1.flags:= textflags - [tf_clipo]; + info1.font:= font; + info1.tabulators:= nil; + drawtext(acanvas,info1); + captionclipped:= (info1.res.cx > rect2.cx) or (info1.res.cy > rect2.cy); + //drawtext(acanvas,caption,rect2,textflags,font); + end; +end; + +function calccaptionsize(const acanvas: tcanvas; + const ainfo: captioninfoty; const captionframe: pframety = nil): sizety; +var + int1: integer; + vertdist: boolean; +begin + with ainfo do begin + result:= textrect(acanvas,caption,textflags,font).size; + if captionframe <> nil then begin + with captionframe^ do begin + result.cx:= result.cx + left + right; + result.cy:= result.cy + top + bottom; + end; + end; + vertdist:= imagepos in vertimagepos; + if vertdist then begin + inc(result.cy,captiondist); + end + else begin + inc(result.cx,captiondist); + end; + if imagelist <> nil then begin + with imagelist do begin + if vertdist then begin + int1:= width + imagedist1 + imagedist2; + if int1 > result.cx then begin + result.cx:= int1; + end; + int1:= height + imagedist; + if imagepos = ip_centervert then begin + int1:= int1 + imagedist; + if int1 > result.cx then begin + result.cy:= int1; + end; + end + else begin + result.cy:= result.cy + int1; + end; + end + else begin + int1:= height + imagedist1 + imagedist2; + if int1 > result.cy then begin + result.cy:= int1; + end; + int1:= width + imagedist; + if imagepos = ip_center then begin + int1:= int1 + imagedist; + if int1 > result.cx then begin + result.cx:= int1; + end; + end + else begin + result.cx:= result.cx + int1; + end; + end; + end; + end; + end; +end; + +procedure drawtoolbutton(const canvas: tcanvas; var info: shapeinfoty); +var + rect1: rectty; + frame1: framety; + co0,co1,co2,co3: colorty; +begin + if not (shs_invisible in info.state) then begin +// frameskinoptionstoshapestate(info.frame,info); + if info.frame <> nil then begin + frameskinoptionstoshapestate(info.frame,info); + canvas.save(); + co1:= info.color; + co2:= info.coloractive; + co3:= tframe1(info.frame).actualcolorclient; + if shs_active in info.state then begin + co0:= co2; + info.coloractive:= cl_transparent; + end + else begin + co0:= co1; + info.color:= cl_transparent; + end; + if co0 <> cl_transparent then begin + if co3 = cl_transparent then begin + tframe1(info.frame).fi.colorclient:= co0; + end; + end; + info.frame.paintbackground(canvas,info.ca.dim,true,false); + frame1:= info.frame.paintframe; + if not (fso_noinnerrect in info.frame.optionsskin) then begin + addframe1(frame1,info.frame.frameo); + end; + { + if not (fso_noinnerrect in info.frame.optionsskin) then begin + frame1:= info.frame.innerframe; + end + else begin + frame1:= info.frame.paintframe; + end; + } + deflaterect1(info.ca.dim,frame1); + end; + if drawbuttonframe(canvas,info,rect1) then begin + info.ca.imagepos:= ip_center; + drawbuttonimage(canvas,info,rect1{,cp_center}); + end; + if info.frame <> nil then begin + canvas.restore(); + inflaterect1(info.ca.dim,frame1); + info.frame.paintoverlay(canvas,info.ca.dim); + if co3 = cl_transparent then begin + info.color:= co1; + info.coloractive:= co2; + tframe1(info.frame).fi.colorclient:= co3; + end; + end; + end; +end; + +function drawbuttoncheckbox(const canvas: tcanvas; const info: shapeinfoty; + var arect: rectty; const pos: imageposty = ip_left): boolean; +var + rect1,rect2: rectty; + align1: alignmentsty; + int1: integer; + co1: colorty; + framestates: framestateflagsty; + size1: sizety; + widthextend: int32; +begin + framestates:= []; + result:= [shs_checkbox,shs_radiobutton] * info.state <> []; + if result then begin + rect1:= arect; + int1:= menucheckboxheight; + widthextend:= menucheckboxwidth; + if info.checkboxframe <> nil then begin + with info.checkboxframe do begin + if fso_flat in optionsskin then begin + dec(int1,2); + dec(widthextend,2); + end; + size1:= innerframedim; + widthextend:= widthextend + frameo_left + frameo_right + size1.cx; + int1:= int1 + size1.cy + frameo_top + frameo_bottom; + end; + end; + rect1.cx:= widthextend; + if int1 < arect.cy then begin + rect1.cy:= int1; + rect1.y:= rect1.y + (arect.cy - int1) div 2; + end; + if pos <> ip_left then begin + inc(rect1.x,arect.cx-rect1.cx); + end; + if info.checkboxframe <> nil then begin + framestates:= combineframestateflags(info.state); + deflaterect1(rect1,info.checkboxframe.frameo); + info.checkboxframe.paintbackgroundframe(canvas,rect1,framestates); + rect2:= deflaterect(rect1,info.checkboxframe.innerframe); + end + else begin + rect2:= rect1; + end; + if (info.checkboxframe = nil) or + not (fso_flat in info.checkboxframe.optionsskin) then begin + draw3dframe(canvas,rect2,-1,defaultframecolors.edges,[]); + end; + if pos = ip_left then begin + inc(arect.x,widthextend); + end; + dec(arect.cx,widthextend); + if shs_checked in info.state then begin + if shs_disabled in info.state then begin + align1:= [al_xcentered,al_ycentered,al_grayed]; + end + else begin + align1:= [al_xcentered,al_ycentered]; + end; + if shs_radiobutton in info.state then begin + int1:= ord(stg_checkedradio); + end + else begin + int1:= ord(stg_checked); + end; + co1:= info.ca.colorglyph; + if (info.checkboxframe <> nil) and + (info.checkboxframe.colorglyph <> cl_default) then begin + co1:= info.checkboxframe.colorglyph; + end; + stockobjects.glyphs.paint(canvas,int1,rect2,align1,co1); + end; + if info.checkboxframe <> nil then begin + info.checkboxframe.paintoverlayframe(canvas,rect1,framestates); + end; + end; +end; + +procedure drawmenuarrow(const canvas: tcanvas; const info: shapeinfoty; + var rect: rectty); +var + alignment: alignmentsty; + int1: integer; + glyph1: stockglyphty; + rect1: rectty; +begin + glyph1:= stg_arrowrightsmall; + if shs_horz in info.state then begin + glyph1:= stg_arrowdownsmall; + int1:= menuarrowwidthhorz; + end + else begin + int1:= menuarrowwidth; + end; + alignment:= [al_xcentered,al_ycentered]; + if shs_disabled in info.state then begin + include(alignment,al_grayed); + inc(int1); + end; + with rect1 do begin + x:= rect.x + rect.cx - int1; + cx:= int1; + y:= rect.y; + cy:= rect.cy; + end; + stockobjects.glyphs.paint(canvas,ord(glyph1),rect1,alignment, + info.ca.colorglyph); + dec(rect.cx,int1); +end; + +procedure drawmenubutton(const canvas: tcanvas; var info: shapeinfoty; + const innerframe: pframety = nil); +var + rect1: rectty; +begin + if not (shs_invisible in info.state) and + drawbuttonframe(canvas,info,rect1) then begin + info.ca.imagepos:= ip_left; + drawbuttonimage(canvas,info,rect1{,cp_left}); + if (shs_menuarrow in info.state) then begin +// if (ss_submenu in info.state) then begin + drawmenuarrow(canvas,info,rect1); + end; + drawbuttoncheckbox(canvas,info,rect1,ip_right); + if innerframe <> nil then begin + deflaterect1(rect1,innerframe^); + end; + drawbuttoncaption(canvas,info,rect1,ip_left,nil); + end; +end; + +procedure drawtab(const canvas: tcanvas; var info: shapeinfoty; + const innerframe: pframety = nil); +var + rect1,rect2,rect3: rectty; + pos1: imageposty; + frame1: framety; + edges1: edgesty; + +begin + with canvas,info do begin + if not (shs_invisible in state) then begin + if frame <> nil then begin + //todo: optimize, move settings to tcustomstepframe updatestate + rect3:= ca.dim; + if not (fso_noinnerrect in frame.optionsskin) then begin + deflaterect1(ca.dim,frame.frameo); + end; + canvas.save; + frame.paintbackground(canvas,info.ca.dim,true,false); + frame1:= frame.paintframe; + deflaterect1(ca.dim,frame1); + frameskinoptionstoshapestate(frame,info); + end; + if shs_opposite in state then begin + if shs_vert in state then begin + edges1:= [edg_left]; + end + else begin + edges1:= [edg_top]; + end; + end + else begin + if shs_vert in state then begin + edges1:= [edg_right]; + end + else begin + edges1:= [edg_bottom]; + end; + end; + if drawbuttonframe(canvas,info,rect1,edges1) then begin + if ca.imagepos = ip_right then begin + pos1:= ip_right; + end + else begin + pos1:= ip_left; + end; + rect2:= rect1; + drawbuttonimage(canvas,info,rect1); + drawbuttoncheckbox(canvas,info,rect1,pos1); + if state * [shs_focused,shs_showfocusrect] = + [shs_focused,shs_showfocusrect] then begin + drawfocusrect(canvas,inflaterect(rect2,-focusrectdist)); + end; + rect2:= rect1; //outerframe + if innerframe <> nil then begin + deflaterect1(rect1,innerframe^); + end; + drawbuttoncaption(canvas,info,rect1,pos1,@rect2); + end; + if frame <> nil then begin + canvas.restore(); + inflaterect1(info.ca.dim,frame1); + frame.paintoverlay(canvas,info.ca.dim); + ca.dim:= rect3; + end; + end; + end; +end; + +initialization + buttontab:= tcustomtabulators.create; + buttontab.add(0,tak_left); +finalization + buttontab.free; +end. diff --git a/mseide-msegui/lib/common/kernel/mseskin.pas b/mseide-msegui/lib/common/kernel/mseskin.pas new file mode 100644 index 0000000..eb15d18 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseskin.pas @@ -0,0 +1,4385 @@ +{ MSEgui Copyright (c) 2008-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseskin; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseclasses,msegui,msescrollbar,mseedit, + msegraphics,msegraphutils,msebitmap,msestockobjects, + msetabs,msetoolbar,msedataedits,msemenus,msearrayprops,msegraphedits, + msesimplewidgets,mseshapes, + msegrids,msewidgets,msetypes,mseglob,msestrings,msedrawtext,mseguiglob; + +type + scrollbarskininfoty = record + svwidth: int32; //-2 -> default + svcolor: colorty; + svcolorpattern: colorty; + svcolorpatternclicked: colorty; + svcolorglyph: colorty; + svbuttonendlength: int32; //-2 -> default + svbuttonlength: int32; //-2 -> default + svbuttonminlength: int32; //-2 -> default + svindentstart: int32; //0 -> default + svindentend: int32; //0 -> default + svface: tfacecomp; + svface1: tfacecomp; + svface2: tfacecomp; + svfacebu: tfacecomp; + svfaceendbu: tfacecomp; + svframe: tframecomp; + svframebu: tframecomp; + svframeendbu1: tframecomp; + svframeendbu2: tframecomp; + end; + widgetcolorinfoty = record + svcolor: colorty; + svcolorcaptionframe: colorty; + end; + pwidgetcolorinfoty = ^widgetcolorinfoty; + widgetskininfoty = record + svface: tfacecomp; + svframe: tframecomp; + end; + containerskininfoty = record + svwidget: widgetskininfoty; +// face: tfacecomp; +// frame: tframecomp; + end; + groupboxskininfoty = record + svwidget: widgetskininfoty; +// face: tfacecomp; +// frame: tframecomp; + end; + toolbarskininfoty = record + svwidget: widgetskininfoty; +// face: tfacecomp; +// frame: tframecomp; + svbuttonface: tfacecomp; + svbuttonfacechecked: tfacecomp; + svbuttonframe: tframecomp; + svbuttonframechecked: tframecomp; + svbuttonframesep: tframecomp; + end; + gridpropskininfoty = record + svface: tfacecomp; + svframe: tframecomp; + end; + gridskininfoty = record + svwidget: widgetskininfoty; +// face: tfacecomp; +// frame: tframecomp; + svfixrows: gridpropskininfoty; + svfixcols: gridpropskininfoty; + svdatacols: gridpropskininfoty; + end; + buttonskininfoty = record + svcolor: colorty; + svwidget: widgetskininfoty; + svfont: toptionalfont; + svoptionsadd: buttonoptionsty; + svoptionsremove: buttonoptionsty; + end; + sliderskininfoty = record + svcolor: colorty; + svwidget: widgetskininfoty; + svsb_vert: scrollbarskininfoty; + svsb_horz: scrollbarskininfoty; + end; + stepbuttonskininfoty = record + svcolor: colorty; + svface: tfacecomp; + svframe: tframecomp; + end; + framebuttonskininfoty = record + svcolor: colorty; + svcolorglyph: colorty; + svface: tfacecomp; + svframe: tframecomp; + end; + tabsskininfoty = record + svcolor: colorty; + svcoloractive: colorty; + svframe: tframecomp; + svface: tfacecomp; + svfaceactive: tfacecomp; + svshift: integer; + svsedge_level: int32; + svsedge_colordkshadow: colorty; + svsedge_colorshadow: colorty; + svsedge_colorlight: colorty; + svsedge_colorhighlight: colorty; + svsedge_colordkwidth: int32; + svsedge_colorhlwidth: int32; + svsedge_imagelist: timagelist; + svsedge_imageoffset: int32; + svsedge_imagepaintshift: int32; + end; + tabbarskininfoty = record + svwidgethorz: widgetskininfoty; + svwidgetvert: widgetskininfoty; + svwidgethorzopo: widgetskininfoty; + svwidgetvertopo: widgetskininfoty; + svtabhorz: tabsskininfoty; + svtabvert: tabsskininfoty; + svtabhorzopo: tabsskininfoty; + svtabvertopo: tabsskininfoty; + end; + tabpageskininfoty = record + svwidget: widgetskininfoty; + svcolortab: colorty; + svcoloractivetab: colorty; + svfacetab: tfacecomp; + svfaceactivetab: tfacecomp; + svfonttab: tfontcomp; + svfontactivetab: tfontcomp; + end; + menuskininfoty = record + svface: tfacecomp; + svframe: tframecomp; + svitemface: tfacecomp; + svitemframe: tframecomp; + svitemfaceactive: tfacecomp; + svitemframeactive: tframecomp; + svfont: tfontcomp; + svfontactive: tfontcomp; + svseparatorframe: tframecomp; + svcheckboxframe: tframecomp; +// options: skinmenuoptionsty; + end; + mainmenuskininfoty = record + svmain: menuskininfoty; + svpopup: menuskininfoty; + end; + mainmenuwidgetskininfoty = record + svwidget: widgetskininfoty; + svmenu: mainmenuskininfoty; + end; + dispwidgetskininfoty = record + svwidget: widgetskininfoty; + svcolor: widgetcolorinfoty; + end; + editskininfoty = record + svwidget: widgetskininfoty; + svempty_text: msestring; + svempty_textflags: textflagsty; + svempty_textcolor: colorty; + svempty_textcolorbackground: colorty; + svempty_fontstyle: fontstylesty; + svempty_color: colorty; + end; + dataeditskininfoty = record + svedit: editskininfoty; + end; + graphdataeditskininfoty = record + svwidget: widgetskininfoty; + end; + booleaneditskininfoty = record + svgraphdataedit: graphdataeditskininfoty; + svoptionsadd: buttonoptionsty; + svoptionsremove: buttonoptionsty; + end; + splitterskininfoty = record + svwidget: widgetskininfoty; + svcolor: widgetcolorinfoty; + svcolorgrip: colorty; + svgrip: stockbitmapty; + end; + + + tskincolor = class(tvirtualpersistent) + private + fcolor: colorty; + frgb: colorty; + frgbbefore: colorty; + procedure setcolor(const avalue: colorty); + public + constructor create; override; + published + property color: colorty read fcolor write setcolor default cl_none; + property rgb: colorty read frgb write frgb; + end; + + tskincolors = class(tpersistentarrayprop) + private + fframecolors: framecolorinfoty; + fframecolorsbefore: framecolorinfoty; + feditfontcolors: editfontcolorinfoty; + feditfontcolorsbefore: editfontcolorinfoty; + public + constructor create; + class function getitemclasstype: persistentclassty; override; + procedure setcolors; + procedure restorecolors; + published + property colordkshadow: colorty read fframecolors.edges.shadow.effectcolor + write fframecolors.edges.shadow.effectcolor default cl_default; + property colorshadow: colorty read fframecolors.edges.shadow.color + write fframecolors.edges.shadow.color default cl_default; + property colorlight: colorty read fframecolors.edges.light.color + write fframecolors.edges.light.color default cl_default; + property colorhighlight: colorty read fframecolors.edges.light.effectcolor + write fframecolors.edges.light.effectcolor default cl_default; + property colordkwidth: integer read fframecolors.edges.shadow.effectwidth + write fframecolors.edges.shadow.effectwidth default -1; + property colorhlwidth: integer read fframecolors.edges.light.effectwidth + write fframecolors.edges.light.effectwidth default -1; + property colorframe: colorty read fframecolors.frame + write fframecolors.frame default cl_default; + property edittext: colorty read feditfontcolors.text + write feditfontcolors.text default cl_default; + property edittextbackground: colorty read feditfontcolors.textbackground + write feditfontcolors.textbackground default cl_default; + property editselectedtext: colorty read feditfontcolors.selectedtext + write feditfontcolors.selectedtext default cl_default; + property editselectedtextbackground: colorty + read feditfontcolors.selectedtextbackground + write feditfontcolors.selectedtextbackground default cl_default; + end; + + tskinfontalias = class(townedpersistent) + private + fname: string; + falias: string; + fmode: fontaliasmodety; + fheight: integer; + fwidth: integer; + foptions: fontoptionsty; + fancestor: string; + fxscale: real; + ftemplate: tfontcomp; + procedure settemplate(const avalue: tfontcomp); + public + constructor create(aowner: tobject); override; + published + property name: string read fname write fname; + property alias: string read falias write falias; + property ancestor: string read fancestor write fancestor; + property mode: fontaliasmodety read fmode write fmode + default fam_overwrite; + property height: integer read fheight write fheight default 0; + property width: integer read fwidth write fwidth default 0; + property options: fontoptionsty read foptions write foptions default []; + property xscale: real read fxscale write fxscale; + property template: tfontcomp read ftemplate write settemplate; + end; + + tcustomskincontroller = class; + + tskinfontaliass = class(townedpersistentarrayprop) + public + constructor create(const aowner: tcustomskincontroller); reintroduce; + class function getitemclasstype: persistentclassty; override; + procedure setfontalias; + end; + + createprocty = procedure of object; + + beforeskinupdateeventty = procedure(const sender: tcustomskincontroller; + const ainfo: skininfoty; var handled: boolean) of object; + skincontrollereventty = procedure(const sender: tcustomskincontroller; + const ainfo: skininfoty) of object; + + tskinextender = class(tmsecomponent) + private + fmaster: tcustomskincontroller; + procedure setmaster(const avalue: tcustomskincontroller); + protected + procedure doactivate; virtual; + procedure dodeactivate; virtual; + public + destructor destroy; override; + procedure updateskin(const ainfo: skininfoty; var handled: boolean); + reintroduce; virtual; + procedure removeskin(const ainfo: skininfoty; var handled: boolean); virtual; + published + property master: tcustomskincontroller read fmaster write setmaster; + end; + + skinextenderarty = array of tskinextender; + + tskinfont = class(tlinkedpersistent) + private + { + fcolor: colorty; + fshadow_color: colorty; + fshadow_shiftx: integer; + fshadow_shifty: integer; + fgloss_color: colorty; + fgloss_shiftx: integer; + fgloss_shifty: integer; + fgrayed_color: colorty; + fgrayed_colorshadow: colorty; + fgrayed_shiftx: integer; + fgrayed_shifty: integer; + fextraspace: integer; + fstyle: fontstylesty; + fcolorbackground: colorty; + } + ftemplate: tfontcomp; + procedure settemplate(const avalue: tfontcomp); + public +// constructor create; + procedure updatefont(const adest: tfont); + published + { + property color: colorty read fcolor write fcolor default cl_default; + property colorbackground: colorty read fcolorbackground + write fcolorbackground default cl_default; + property shadow_color: colorty read fshadow_color + write fshadow_color default cl_default; + property shadow_shiftx: integer read fshadow_shiftx write + fshadow_shiftx default 1; + property shadow_shifty: integer read fshadow_shifty write + fshadow_shifty default 1; + + property gloss_color: colorty read fgloss_color + write fgloss_color default cl_default; + property gloss_shiftx: integer read fgloss_shiftx write + fgloss_shiftx default -1; + property gloss_shifty: integer read fgloss_shifty write + fgloss_shifty default -1; + + property grayed_color: colorty read fgrayed_color + write fgrayed_color default cl_default; + property grayed_colorshadow: colorty read fgrayed_colorshadow + write fgrayed_colorshadow default cl_default; + property grayed_shiftx: integer read fgrayed_shiftx write + fgrayed_shiftx default 1; + property grayed_shifty: integer read fgrayed_shifty write + fgrayed_shifty default 1; + + property extraspace: integer read fextraspace write fextraspace default 0; + property style: fontstylesty read fstyle write fstyle default []; + } + property template: tfontcomp read ftemplate write settemplate; + end; + + groupinfoty = record + min: integer; + max: integer; + end; + groupinfoarty = array of groupinfoty; + + tcustomskincontroller = class(tmsecomponent) + private + fonbeforeupdate: beforeskinupdateeventty; + fonafterupdate: skincontrollereventty; + fonactivate: notifyeventty; + fondeactivate: notifyeventty; + fcolors: tskincolors; + ffontalias: tskinfontaliass; + fupdating: integer; + factive: boolean; + factivedesign: boolean; + fisactive: boolean; +// fremoving: boolean; + fskinfonts: array[stockfontty] of tskinfont; + fgroupinfo: groupinfoarty; + fgroups: string; + forder: integer; + fhotkey_fontstylesadd: fontstylesty; + fhotkey_fontstylesremove: fontstylesty; + fhotkey_color: colorty; + fhotkey_colorbackground: colorty; + procedure setactive(const avalue: boolean); + procedure setcolors(const avalue: tskincolors); + procedure setfontalias(const avalue: tskinfontaliass); + function getextenders: integer; + procedure setextenders(const avalue: integer); + procedure readextendernames(reader: treader); + procedure writeextendernames(writer: twriter); + procedure readactivedesign(reader: treader); +// procedure setactivedesign(const avalue: boolean); + function getskinfont(const aindex: integer): tskinfont; + procedure setskinfont(const aindex: integer; const avalue: tskinfont); + procedure setgroups(const avalue: string); + procedure checkactive; + procedure sethotkey_fontstylesadd(const avalue: fontstylesty); + procedure sethotkey_fontstylesremove(const avalue: fontstylesty); + procedure sethotkey_colorbackground(const avalue: colorty); + procedure sethotkey_color(const avalue: colorty); + procedure checkhotkey(); + protected + fextendernames: stringarty; + fextenders: skinextenderarty; + fhashotkey: boolean; + function getextendernames: stringarty; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure updateorder; + procedure registerextender(const aextender: tskinextender); + procedure unregisterextender(const aextender: tskinextender); + + procedure doactivate; virtual; + procedure dodeactivate; virtual; + procedure loaded; override; + procedure defineproperties(filer: tfiler); override; + + procedure setfacetemplate(const face: tfacecomp; + const dest: tcustomface); + procedure setframetemplate(const frame: tframecomp; + const dest: tcustomframe); + + procedure setwidgetface(const instance: twidget; const aface: tfacecomp); +// procedure setwidgetfacetemplate(const instance: twidget; +// const aface: tfacecomp);//no face nil test + procedure setwidgetframe(const instance: twidget; const aframe: tframecomp); +// procedure setwidgetframetemplate(const instance: twidget; +// const aframe: tframecomp); //no fram nil check + procedure setwidgetskin(const instance: twidget; + const ainfo: widgetskininfoty); +// procedure setwidgetskintemplate(const instance: twidget; +// const ainfo: widgetskininfoty); + //overrides nil frame and face + procedure setgroupboxskin(const instance: tgroupbox; + const ainfo: groupboxskininfoty); + procedure setgridpropskin(const instance: tgridprop; + const ainfo: gridpropskininfoty); + procedure setgridskin(const instance: tcustomgrid; + const ainfo: gridskininfoty); + procedure seteditskin(const instance: tcustomedit; + const ainfo: editskininfoty); + procedure setdataeditskin(const instance: tdataedit; + const ainfo: dataeditskininfoty); + procedure setgraphdataeditskin(const instance: tgraphdataedit; + const ainfo: graphdataeditskininfoty); + procedure setwidgetfont(const instance: twidget; const afont: tfont); + procedure setwidgetcolor(const instance: twidget; const acolor: colorty); + function setwidgetcolorcaptionframe( + const awidget: twidget; const acolor: colorty): boolean; + procedure setscrollbarskin(const instance: tcustomscrollbar; + const ainfo: scrollbarskininfoty); + procedure setstepbuttonskin(const instance: tcustomstepframe; + const ainfo: stepbuttonskininfoty); + procedure setframebuttonskin(const instance: tframebutton; + const ainfo: framebuttonskininfoty); + procedure settabsskin(const instance: tcustomtabbar; + const ainfo: tabsskininfoty); + procedure setpopupmenuskin(const instance: tpopupmenu; + const ainfo: menuskininfoty); + procedure setmainmenuskin(const instance: tcustommainmenu; + const ainfo: mainmenuskininfoty); + + procedure handlewidget(const askin: skininfoty; + const acolor: pwidgetcolorinfoty = nil); virtual; + procedure handlecontainer(const ainfo: skininfoty); virtual; + procedure handlegroupbox(const ainfo: skininfoty); virtual; + procedure handlesimplebutton(const ainfo: skininfoty); virtual; + procedure handledatabutton(const ainfo: skininfoty); virtual; + procedure handleslider(const ainfo: skininfoty); virtual; + procedure handleuserobject(const ainfo: skininfoty); virtual; + procedure handletabbar(const ainfo: skininfoty); virtual; + procedure handletabpage(const ainfo: skininfoty); virtual; + procedure handletoolbar(const ainfo: skininfoty); virtual; + procedure handlesplitter(const ainfo: skininfoty); virtual; + procedure handledispwidget(const ainfo: skininfoty); virtual; + procedure handleedit(const ainfo: skininfoty); virtual; + procedure handledataedit(const ainfo: skininfoty); virtual; + procedure handlebooleanedit(const ainfo: skininfoty); virtual; + procedure handlemainmenu(const ainfo: skininfoty); virtual; + procedure handlepopupmenu(const ainfo: skininfoty); virtual; + procedure handlemainmenuwidget(const ainfo: skininfoty); virtual; + procedure handlegrid(const ainfo: skininfoty); virtual; + procedure updateskin1(const ainfo: skininfoty; const remove: boolean); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure updateskin(const ainfo: skininfoty); reintroduce; + // procedure removeskin(const ainfo: skininfoty); +// property removing: boolean read fremoving; + published + property order: integer read forder write forder default 0; //first! + //higher order executed first + property active: boolean read factive write setactive default false; +// property activedesign: boolean read factivedesign +// write setactivedesign default false; + //removed, too dangerous + property extenders: integer read getextenders write setextenders; + //hook for object inspector + property groups: string read fgroups write setgroups; + //format [[..]{,[..]}] + //empty -> all + property onbeforeupdate: beforeskinupdateeventty read fonbeforeupdate + write fonbeforeupdate; + property onafterupdate: skincontrollereventty read fonafterupdate + write fonafterupdate; + property onactivate: notifyeventty read fonactivate write fonactivate; + property ondeactivate: notifyeventty read fondeactivate write fondeactivate; + property colors: tskincolors read fcolors write setcolors; + property fontalias: tskinfontaliass read ffontalias write setfontalias; + + property font_default: tskinfont index ord(stf_default) //0 + read getskinfont write setskinfont; + property font_empty: tskinfont index ord(stf_empty) //1 + read getskinfont write setskinfont; + property font_unicode: tskinfont index ord(stf_unicode) //2 + read getskinfont write setskinfont; + property font_menu: tskinfont index ord(stf_menu) //3 + read getskinfont write setskinfont; + property font_message: tskinfont index ord(stf_message) //4 + read getskinfont write setskinfont; + property font_hint: tskinfont index ord(stf_hint) //5 + read getskinfont write setskinfont; + property font_report: tskinfont index ord(stf_report) //6 + read getskinfont write setskinfont; + property font_proportional: tskinfont index ord(stf_proportional) //7 + read getskinfont write setskinfont; + property font_fixed: tskinfont index ord(stf_fixed) //8 + read getskinfont write setskinfont; + property font_helvetica: tskinfont index ord(stf_helvetica) //9 + read getskinfont write setskinfont; + property font_roman: tskinfont index ord(stf_roman) //10 + read getskinfont write setskinfont; + property font_courier: tskinfont index ord(stf_courier) //11 + read getskinfont write setskinfont; + + property hotkey_fontstylesadd: fontstylesty read fhotkey_fontstylesadd + write sethotkey_fontstylesadd default []; + property hotkey_fontstylesremove: fontstylesty read fhotkey_fontstylesremove + write sethotkey_fontstylesremove default []; + property hotkey_color: colorty read fhotkey_color write sethotkey_color + default cl_default; + property hotkey_colorbackground: colorty read fhotkey_colorbackground + write sethotkey_colorbackground default cl_default; + end; + + tskincontroller = class(tcustomskincontroller) + private + fsb_horz: scrollbarskininfoty; + fsb_vert: scrollbarskininfoty; + fgroupbox: groupboxskininfoty; + fgrid: gridskininfoty; + fbutton: buttonskininfoty; + fdatabutton: buttonskininfoty; + fslider: sliderskininfoty; + fstepbutton: stepbuttonskininfoty; + fframebutton: framebuttonskininfoty; + fcontainer: containerskininfoty; + fwidgetcolor: widgetcolorinfoty; + ftabbar: tabbarskininfoty; + ftabpage: tabpageskininfoty; + ftoolbar_horz: toolbarskininfoty; + ftoolbar_vert: toolbarskininfoty; + fpopupmenu: menuskininfoty; + fmainmenu: mainmenuskininfoty; + fmainmenuwidget: mainmenuwidgetskininfoty; + fdispwidget: dispwidgetskininfoty; + fedit: editskininfoty; + fdataedit: dataeditskininfoty; + fbooleanedit: booleaneditskininfoty; + fsplitter: splitterskininfoty; + + procedure setsb_vert_face(const avalue: tfacecomp); + procedure setsb_vert_face1(const avalue: tfacecomp); + procedure setsb_vert_face2(const avalue: tfacecomp); + procedure setsb_vert_facebutton(const avalue: tfacecomp); + procedure setsb_vert_faceendbutton(const avalue: tfacecomp); + procedure setsb_vert_frame(const avalue: tframecomp); + procedure setsb_vert_framebutton(const avalue: tframecomp); + procedure setsb_vert_frameendbutton1(const avalue: tframecomp); + procedure setsb_vert_frameendbutton2(const avalue: tframecomp); + procedure setsb_horz_face(const avalue: tfacecomp); + procedure setsb_horz_face1(const avalue: tfacecomp); + procedure setsb_horz_face2(const avalue: tfacecomp); + procedure setsb_horz_facebutton(const avalue: tfacecomp); + procedure setsb_horz_faceendbutton(const avalue: tfacecomp); + procedure setsb_horz_frame(const avalue: tframecomp); + procedure setsb_horz_framebutton(const avalue: tframecomp); + procedure setsb_horz_frameendbutton1(const avalue: tframecomp); + procedure setsb_horz_frameendbutton2(const avalue: tframecomp); + + procedure setgroupbox_face(const avalue: tfacecomp); + procedure setgroupbox_frame(const avalue: tframecomp); + + procedure setgrid_face(const avalue: tfacecomp); + procedure setgrid_frame(const avalue: tframecomp); + procedure setgrid_fixrows_face(const avalue: tfacecomp); + procedure setgrid_fixrows_frame(const avalue: tframecomp); + procedure setgrid_fixcols_face(const avalue: tfacecomp); + procedure setgrid_fixcols_frame(const avalue: tframecomp); + procedure setgrid_datacols_face(const avalue: tfacecomp); + procedure setgrid_datacols_frame(const avalue: tframecomp); + + procedure setbutton_face(const avalue: tfacecomp); + procedure setbutton_frame(const avalue: tframecomp); + function getbutton_font: toptionalfont; + procedure setbutton_font(const avalue: toptionalfont); + + procedure setdatabutton_face(const avalue: tfacecomp); + procedure setdatabutton_frame(const avalue: tframecomp); + function getdatabutton_font: toptionalfont; + procedure setdatabutton_font(const avalue: toptionalfont); + + procedure setslider_face(const avalue: tfacecomp); + procedure setslider_frame(const avalue: tframecomp); + procedure setssb_vert_face(const avalue: tfacecomp); + procedure setssb_vert_face1(const avalue: tfacecomp); + procedure setssb_vert_face2(const avalue: tfacecomp); + procedure setssb_vert_facebutton(const avalue: tfacecomp); + procedure setssb_vert_faceendbutton(const avalue: tfacecomp); + procedure setssb_vert_frame(const avalue: tframecomp); + procedure setssb_vert_framebutton(const avalue: tframecomp); + procedure setssb_vert_frameendbutton1(const avalue: tframecomp); + procedure setssb_vert_frameendbutton2(const avalue: tframecomp); + procedure setssb_horz_face(const avalue: tfacecomp); + procedure setssb_horz_face1(const avalue: tfacecomp); + procedure setssb_horz_face2(const avalue: tfacecomp); + procedure setssb_horz_facebutton(const avalue: tfacecomp); + procedure setssb_horz_faceendbutton(const avalue: tfacecomp); + procedure setssb_horz_frame(const avalue: tframecomp); + procedure setssb_horz_framebutton(const avalue: tframecomp); + procedure setssb_horz_frameendbutton1(const avalue: tframecomp); + procedure setssb_horz_frameendbutton2(const avalue: tframecomp); + + procedure setframebutton_face(const avalue: tfacecomp); + procedure setframebutton_frame(const avalue: tframecomp); + + procedure setstepbutton_face(const avalue: tfacecomp); + procedure setstepbutton_frame(const avalue: tframecomp); + + procedure setsplitter_face(const avalue: tfacecomp); + procedure setsplitter_frame(const avalue: tframecomp); + + procedure setdispwidget_face(const avalue: tfacecomp); + procedure setdispwidget_frame(const avalue: tframecomp); + + procedure setedit_face(const avalue: tfacecomp); + procedure setedit_frame(const avalue: tframecomp); + + procedure setdataedit_face(const avalue: tfacecomp); + procedure setdataedit_frame(const avalue: tframecomp); + + procedure setbooleanedit_face(const avalue: tfacecomp); + procedure setbooleanedit_frame(const avalue: tframecomp); + + procedure setcontainer_face(const avalue: tfacecomp); + procedure setcontainer_frame(const avalue: tframecomp); + + procedure settabbar_horz_tab_edge_imagelist(const avalue: timagelist); + procedure settabbar_horz_face(const avalue: tfacecomp); + procedure settabbar_horz_frame(const avalue: tframecomp); + procedure settabbar_horz_tab_frame(const avalue: tframecomp); + procedure settabbar_horz_tab_face(const avalue: tfacecomp); + procedure settabbar_horz_tab_faceactive(const avalue: tfacecomp); + procedure settabbar_vert_tab_edge_imagelist(const avalue: timagelist); + procedure settabbar_vert_face(const avalue: tfacecomp); + procedure settabbar_vert_frame(const avalue: tframecomp); + procedure settabbar_vert_tab_frame(const avalue: tframecomp); + procedure settabbar_vert_tab_face(const avalue: tfacecomp); + procedure settabbar_vert_tab_faceactive(const avalue: tfacecomp); + + procedure settabbar_horzopo_tab_edge_imagelist(const avalue: timagelist); + procedure settabbar_horzopo_face(const avalue: tfacecomp); + procedure settabbar_horzopo_frame(const avalue: tframecomp); + procedure settabbar_horzopo_tab_frame(const avalue: tframecomp); + procedure settabbar_horzopo_tab_face(const avalue: tfacecomp); + procedure settabbar_horzopo_tab_faceactive(const avalue: tfacecomp); + procedure settabbar_vertopo_tab_edge_imagelist(const avalue: timagelist); + procedure settabbar_vertopo_face(const avalue: tfacecomp); + procedure settabbar_vertopo_frame(const avalue: tframecomp); + procedure settabbar_vertopo_tab_frame(const avalue: tframecomp); + procedure settabbar_vertopo_tab_face(const avalue: tfacecomp); + procedure settabbar_vertopo_tab_faceactive(const avalue: tfacecomp); + + procedure settabpage_face(const avalue: tfacecomp); + procedure settabpage_facetab(const avalue: tfacecomp); + procedure settabpage_faceactivetab(const avalue: tfacecomp); + procedure settabpage_frame(const avalue: tframecomp); + procedure settabpage_fonttab(const avalue: tfontcomp); + procedure settabpage_fontactivetab(const avalue: tfontcomp); + + procedure settoolbar_horz_face(const avalue: tfacecomp); + procedure settoolbar_horz_frame(const avalue: tframecomp); + procedure settoolbar_horz_buttonface(const avalue: tfacecomp); + procedure settoolbar_horz_buttonfacechecked(const avalue: tfacecomp); + procedure settoolbar_horz_buttonframe(const avalue: tframecomp); + procedure settoolbar_horz_buttonframechecked(const avalue: tframecomp); + procedure settoolbar_horz_buttonframesep(const avalue: tframecomp); + procedure settoolbar_vert_face(const avalue: tfacecomp); + procedure settoolbar_vert_frame(const avalue: tframecomp); + procedure settoolbar_vert_buttonface(const avalue: tfacecomp); + procedure settoolbar_vert_buttonfacechecked(const avalue: tfacecomp); + procedure settoolbar_vert_buttonframe(const avalue: tframecomp); + procedure settoolbar_vert_buttonframechecked(const avalue: tframecomp); + procedure settoolbar_vert_buttonframesep(const avalue: tframecomp); + + + procedure setpopupmenu_face(const avalue: tfacecomp); + procedure setpopupmenu_frame(const avalue: tframecomp); + procedure setpopupmenu_itemface(const avalue: tfacecomp); + procedure setpopupmenu_itemframe(const avalue: tframecomp); + procedure setpopupmenu_itemfaceactive(const avalue: tfacecomp); + procedure setpopupmenu_itemframeactive(const avalue: tframecomp); + procedure setpopupmenu_font(const avalue: tfontcomp); + procedure setpopupmenu_fontactive(const avalue: tfontcomp); + procedure setpopupmenu_separatorframe(const avalue: tframecomp); + procedure setpopupmenu_checkboxframe(const avalue: tframecomp); + + procedure setmainmenu_face(const avalue: tfacecomp); + procedure setmainmenu_frame(const avalue: tframecomp); + procedure setmainmenu_itemface(const avalue: tfacecomp); + procedure setmainmenu_itemframe(const avalue: tframecomp); + procedure setmainmenu_itemfaceactive(const avalue: tfacecomp); + procedure setmainmenu_itemframeactive(const avalue: tframecomp); + procedure setmainmenu_font(const avalue: tfontcomp); + procedure setmainmenu_fontactive(const avalue: tfontcomp); + procedure setmainmenu_separatorframe(const avalue: tframecomp); + procedure setmainmenu_checkboxframe(const avalue: tframecomp); + procedure setmainmenu_popupface(const avalue: tfacecomp); + procedure setmainmenu_popupframe(const avalue: tframecomp); + procedure setmainmenu_popupitemface(const avalue: tfacecomp); + procedure setmainmenu_popupitemframe(const avalue: tframecomp); + procedure setmainmenu_popupitemfaceactive(const avalue: tfacecomp); + procedure setmainmenu_popupitemframeactive(const avalue: tframecomp); + procedure setmainmenu_popupfont(const avalue: tfontcomp); + procedure setmainmenu_popupfontactive(const avalue: tfontcomp); + procedure setmainmenu_popupseparatorframe(const avalue: tframecomp); + procedure setmainmenu_popupcheckboxframe(const avalue: tframecomp); + + procedure setmainmenuwidget_face(const avalue: tfacecomp); + procedure setmainmenuwidget_frame(const avalue: tframecomp); + procedure setmainmenuwidget_itemface(const avalue: tfacecomp); + procedure setmainmenuwidget_itemframe(const avalue: tframecomp); + procedure setmainmenuwidget_itemfaceactive(const avalue: tfacecomp); + procedure setmainmenuwidget_itemframeactive(const avalue: tframecomp); + procedure setmainmenuwidget_font(const avalue: tfontcomp); + procedure setmainmenuwidget_fontactive(const avalue: tfontcomp); + procedure setmainmenuwidget_separatorframe(const avalue: tframecomp); + procedure setmainmenuwidget_checkboxframe(const avalue: tframecomp); + procedure setmainmenuwidget_popupface(const avalue: tfacecomp); + procedure setmainmenuwidget_popupframe(const avalue: tframecomp); + procedure setmainmenuwidget_popupitemface(const avalue: tfacecomp); + procedure setmainmenuwidget_popupitemframe(const avalue: tframecomp); + procedure setmainmenuwidget_popupitemfaceactive(const avalue: tfacecomp); + procedure setmainmenuwidget_popupitemframeactive(const avalue: tframecomp); + procedure setmainmenuwidget_popupfont(const avalue: tfontcomp); + procedure setmainmenuwidget_popupfontactive(const avalue: tfontcomp); + procedure setmainmenuwidget_popupseparatorframe(const avalue: tframecomp); + procedure setmainmenuwidget_popupcheckboxframe(const avalue: tframecomp); + protected + procedure handlewidget(const askin: skininfoty; + const acolor: pwidgetcolorinfoty = nil); override; + procedure handlecontainer(const ainfo: skininfoty); override; + procedure handlegroupbox(const ainfo: skininfoty); override; + procedure handlesimplebutton(const ainfo: skininfoty); override; + procedure handledatabutton(const ainfo: skininfoty); override; + procedure handleslider(const ainfo: skininfoty); override; + procedure handletabbar(const ainfo: skininfoty); override; + procedure handletabpage(const ainfo: skininfoty); override; + procedure handletoolbar(const ainfo: skininfoty); override; + procedure handlesplitter(const ainfo: skininfoty); override; + procedure handledispwidget(const ainfo: skininfoty); override; + procedure handleedit(const ainfo: skininfoty); override; + procedure handledataedit(const ainfo: skininfoty); override; + procedure handlebooleanedit(const ainfo: skininfoty); override; + procedure handlemainmenu(const ainfo: skininfoty); override; + procedure handlepopupmenu(const ainfo: skininfoty); override; + procedure handlemainmenuwidget(const ainfo: skininfoty); override; + procedure handlegrid(const ainfo: skininfoty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure createbutton_font; + procedure createdatabutton_font; + published + property sb_horz_width: int32 read fsb_horz.svwidth + write fsb_horz.svwidth default -2; + property sb_horz_color: colorty + read fsb_horz.svcolor + write fsb_horz.svcolor default cl_default; + property sb_horz_colorpattern: colorty + read fsb_horz.svcolorpattern + write fsb_horz.svcolorpattern default cl_default; + property sb_horz_colorpatternclicked: colorty + read fsb_horz.svcolorpatternclicked + write fsb_horz.svcolorpatternclicked default cl_default; + property sb_horz_colorglyph: colorty + read fsb_horz.svcolorglyph + write fsb_horz.svcolorglyph default cl_default; + property sb_horz_buttonendlength: int32 read fsb_horz.svbuttonendlength + write fsb_horz.svbuttonendlength default -2; + property sb_horz_buttonlength: int32 read fsb_horz.svbuttonlength + write fsb_horz.svbuttonlength default -2; + property sb_horz_buttonminlength: int32 read fsb_horz.svbuttonminlength + write fsb_horz.svbuttonminlength default -2; + property sb_horz_indentstart: int32 read fsb_horz.svindentstart + write fsb_horz.svindentstart default 0; + property sb_horz_indentend: int32 read fsb_horz.svindentend + write fsb_horz.svindentend default 0; + property sb_horz_face: tfacecomp read fsb_horz.svface + write setsb_horz_face; + property sb_horz_face1: tfacecomp read fsb_horz.svface1 + write setsb_horz_face1; + property sb_horz_face2: tfacecomp read fsb_horz.svface2 + write setsb_horz_face2; + property sb_horz_facebutton: tfacecomp read fsb_horz.svfacebu + write setsb_horz_facebutton; + property sb_horz_faceendbutton: tfacecomp read fsb_horz.svfaceendbu + write setsb_horz_faceendbutton; + property sb_horz_frame: tframecomp read fsb_horz.svframe + write setsb_horz_frame; + property sb_horz_framebutton: tframecomp read fsb_horz.svframebu + write setsb_horz_framebutton; + property sb_horz_frameendbutton1: tframecomp read fsb_horz.svframeendbu1 + write setsb_horz_frameendbutton1; + property sb_horz_frameendbutton2: tframecomp read fsb_horz.svframeendbu2 + write setsb_horz_frameendbutton2; + + property sb_vert_width: int32 read fsb_vert.svwidth + write fsb_vert.svwidth default -2; + property sb_vert_color: colorty read fsb_vert.svcolor + write fsb_vert.svcolor default cl_default; + property sb_vert_colorpattern: colorty read fsb_vert.svcolorpattern + write fsb_vert.svcolorpattern default cl_default; + property sb_vert_colorpatternclicked: colorty + read fsb_vert.svcolorpatternclicked + write fsb_vert.svcolorpatternclicked default cl_default; + property sb_vert_colorglyph: colorty + read fsb_vert.svcolorglyph + write fsb_vert.svcolorglyph default cl_default; + property sb_vert_buttonendlength: int32 read fsb_vert.svbuttonendlength + write fsb_vert.svbuttonendlength default -2; + property sb_vert_buttonlength: int32 read fsb_vert.svbuttonlength + write fsb_vert.svbuttonlength default -2; + property sb_vert_buttonminlength: int32 read fsb_vert.svbuttonminlength + write fsb_vert.svbuttonminlength default -2; + property sb_vert_indentstart: int32 read fsb_vert.svindentstart + write fsb_vert.svindentstart default 0; + property sb_vert_indentend: int32 read fsb_vert.svindentend + write fsb_vert.svindentend default 0; + property sb_vert_face: tfacecomp read fsb_vert.svface + write setsb_vert_face; + property sb_vert_face1: tfacecomp read fsb_vert.svface1 + write setsb_vert_face1; + property sb_vert_face2: tfacecomp read fsb_vert.svface2 + write setsb_vert_face2; + property sb_vert_facebutton: tfacecomp read fsb_vert.svfacebu + write setsb_vert_facebutton; + property sb_vert_faceendbutton: tfacecomp read fsb_vert.svfaceendbu + write setsb_vert_faceendbutton; + property sb_vert_frame: tframecomp read fsb_vert.svframe + write setsb_vert_frame; + property sb_vert_framebutton: tframecomp read fsb_vert.svframebu + write setsb_vert_framebutton; + property sb_vert_frameendbutton1: tframecomp read fsb_vert.svframeendbu1 + write setsb_vert_frameendbutton1; + property sb_vert_frameendbutton2: tframecomp read fsb_vert.svframeendbu2 + write setsb_vert_frameendbutton2; + + property stepbutton_color: colorty read fstepbutton.svcolor + write fstepbutton.svcolor default cl_default; + property stepbutton_frame: tframecomp read fstepbutton.svframe + write setstepbutton_frame; + property stepbutton_face: tfacecomp read fstepbutton.svface + write setstepbutton_face; + + property widget_color: colorty read fwidgetcolor.svcolor + write fwidgetcolor.svcolor default cl_default; + property widget_colorcaptionframe: colorty + read fwidgetcolor.svcolorcaptionframe + write fwidgetcolor.svcolorcaptionframe default cl_default; + //overrides widget_color for widgets with frame caption + + property splitter_color: colorty read fsplitter.svcolor.svcolor + write fsplitter.svcolor.svcolor default cl_default; + property splitter_colorcaptionframe: colorty + read fsplitter.svcolor.svcolorcaptionframe + write fsplitter.svcolor.svcolorcaptionframe default cl_default; + //overrides widget_color for widgets with frame caption + property splitter_colorgrip: colorty read fsplitter.svcolorgrip + write fsplitter.svcolorgrip default cl_default; + property splitter_grip: stockbitmapty read fsplitter.svgrip + write fsplitter.svgrip default stb_default; + property splitter_face: tfacecomp read fsplitter.svwidget.svface + write setsplitter_face; + property splitter_frame: tframecomp read fsplitter.svwidget.svframe + write setsplitter_frame; + + property dispwidget_color: colorty read fdispwidget.svcolor.svcolor + write fdispwidget.svcolor.svcolor default cl_default; + property dispwidget_colorcaptionframe: colorty + read fdispwidget.svcolor.svcolorcaptionframe + write fdispwidget.svcolor.svcolorcaptionframe default cl_default; + //overrides widget_color for widgets with frame caption + property dispwidget_face: tfacecomp read fdispwidget.svwidget.svface + write setdispwidget_face; + property dispwidget_frame: tframecomp read fdispwidget.svwidget.svframe + write setdispwidget_frame; + + property dataedit_face: tfacecomp read fdataedit.svedit.svwidget.svface + write setdataedit_face; + property dataedit_frame: tframecomp read fdataedit.svedit.svwidget.svframe + write setdataedit_frame; + property dataedit_empty_text: msestring read fdataedit.svedit.svempty_text + write fdataedit.svedit.svempty_text; + property dataedit_empty_color: colorty read fdataedit.svedit.svempty_color + write fdataedit.svedit.svempty_color default cl_default; + property dataedit_empty_fontstyle: fontstylesty + read fdataedit.svedit.svempty_fontstyle + write fdataedit.svedit.svempty_fontstyle default []; + property dataedit_empty_textflags: textflagsty + read fdataedit.svedit.svempty_textflags + write fdataedit.svedit.svempty_textflags default []; + property dataedit_empty_textcolor: colorty + read fdataedit.svedit.svempty_textcolor + write fdataedit.svedit.svempty_textcolor default cl_default; + property dataedit_empty_textcolorbackground: colorty + read fdataedit.svedit.svempty_textcolorbackground + write fdataedit.svedit.svempty_textcolorbackground default cl_default; + + property edit_face: tfacecomp read fedit.svwidget.svface + write setedit_face; + property edit_frame: tframecomp read fedit.svwidget.svframe + write setedit_frame; + property edit_empty_text: msestring read fedit.svempty_text + write fedit.svempty_text; + property edit_empty_color: colorty read fedit.svempty_color + write fedit.svempty_color default cl_default; + property edit_empty_fontstyle: fontstylesty + read fedit.svempty_fontstyle + write fedit.svempty_fontstyle default []; + property edit_empty_textflags: textflagsty + read fedit.svempty_textflags + write fedit.svempty_textflags default []; + property edit_empty_textcolor: colorty + read fedit.svempty_textcolor + write fedit.svempty_textcolor default cl_default; + property edit_empty_textcolorbackground: colorty + read fedit.svempty_textcolorbackground + write fedit.svempty_textcolorbackground default cl_default; + + property booleanedit_face: tfacecomp + read fbooleanedit.svgraphdataedit.svwidget.svface + write setbooleanedit_face; + property booleanedit_frame: tframecomp + read fbooleanedit.svgraphdataedit.svwidget.svframe + write setbooleanedit_frame; + property booleanedit_optionsadd: buttonoptionsty + read fbooleanedit.svoptionsadd + write fbooleanedit.svoptionsadd default[]; + property booleanedit_optionsremove: buttonoptionsty + read fbooleanedit.svoptionsremove + write fbooleanedit.svoptionsremove default[]; + + property container_face: tfacecomp read fcontainer.svwidget.svface + write setcontainer_face; + property container_frame: tframecomp read fcontainer.svwidget.svframe + write setcontainer_frame; + property groupbox_face: tfacecomp read fgroupbox.svwidget.svface + write setgroupbox_face; + property groupbox_frame: tframecomp read fgroupbox.svwidget.svframe + write setgroupbox_frame; + + property grid_face: tfacecomp read fgrid.svwidget.svface write setgrid_face; + property grid_frame: tframecomp read fgrid.svwidget.svframe + write setgrid_frame; + property grid_fixrows_face: tfacecomp read fgrid.svfixrows.svface + write setgrid_fixrows_face; + property grid_fixrows_frame: tframecomp read fgrid.svfixrows.svframe + write setgrid_fixrows_frame; + property grid_fixcols_face: tfacecomp read fgrid.svfixcols.svface + write setgrid_fixcols_face; + property grid_fixcols_frame: tframecomp read fgrid.svfixcols.svframe + write setgrid_fixcols_frame; + property grid_datacols_face: tfacecomp read fgrid.svdatacols.svface + write setgrid_datacols_face; + property grid_datacols_frame: tframecomp read fgrid.svdatacols.svframe + write setgrid_datacols_frame; + + property button_color: colorty read fbutton.svcolor write fbutton.svcolor + default cl_default; + property button_face: tfacecomp read fbutton.svwidget.svface + write setbutton_face; + property button_frame: tframecomp read fbutton.svwidget.svframe + write setbutton_frame; + property button_font: toptionalfont read getbutton_font write setbutton_font; + property button_optionsadd: buttonoptionsty read fbutton.svoptionsadd + write fbutton.svoptionsadd default[]; + property button_optionsremove: buttonoptionsty read fbutton.svoptionsremove + write fbutton.svoptionsremove default[]; + + property databutton_color: colorty read fdatabutton.svcolor + write fdatabutton.svcolor default cl_default; + property databutton_face: tfacecomp read fdatabutton.svwidget.svface + write setdatabutton_face; + property databutton_frame: tframecomp read fdatabutton.svwidget.svframe + write setdatabutton_frame; + property databutton_font: toptionalfont read getdatabutton_font + write setdatabutton_font; + property databutton_optionsadd: buttonoptionsty + read fdatabutton.svoptionsadd + write fdatabutton.svoptionsadd default[]; + property databutton_optionsremove: buttonoptionsty + read fbooleanedit.svoptionsremove + write fdatabutton.svoptionsremove default[]; + + property slider_color: colorty read fslider.svcolor + write fslider.svcolor default cl_default; + property slider_face: tfacecomp read fslider.svwidget.svface + write setslider_face; + property slider_frame: tframecomp read fslider.svwidget.svframe + write setslider_frame; + + property slider_sb_horz_width: int32 read fslider.svsb_horz.svwidth + write fslider.svsb_horz.svwidth default -2; + property slider_sb_horz_color: colorty + read fslider.svsb_horz.svcolor + write fslider.svsb_horz.svcolor default cl_default; + property slider_sb_horz_colorpattern: colorty + read fslider.svsb_horz.svcolorpattern + write fslider.svsb_horz.svcolorpattern default cl_default; + property slider_sb_horz_colorpatternclicked: colorty + read fslider.svsb_horz.svcolorpatternclicked + write fslider.svsb_horz.svcolorpatternclicked default cl_default; + property slider_sb_horz_colorglyph: colorty + read fslider.svsb_horz.svcolorglyph + write fslider.svsb_horz.svcolorglyph default cl_default; + property slider_sb_horz_buttonendlength: int32 + read fslider.svsb_horz.svbuttonendlength + write fslider.svsb_horz.svbuttonendlength default -2; + property slider_sb_horz_buttonlength: int32 + read fslider.svsb_horz.svbuttonlength + write fslider.svsb_horz.svbuttonlength default -2; + property slider_sb_horz_buttonminlength: int32 + read fslider.svsb_horz.svbuttonminlength + write fslider.svsb_horz.svbuttonminlength default -2; + property slider_sb_horz_indentstart: int32 + read fslider.svsb_horz.svindentstart + write fslider.svsb_horz.svindentstart default 0; + property slider_sb_horz_indentend: int32 read fslider.svsb_horz.svindentend + write fslider.svsb_horz.svindentend default 0; + property slider_sb_horz_face: tfacecomp + read fslider.svsb_horz.svface + write setssb_horz_face; + property slider_sb_horz_face1: tfacecomp + read fslider.svsb_horz.svface1 + write setssb_horz_face1; + property slider_sb_horz_face2: tfacecomp + read fslider.svsb_horz.svface2 + write setssb_horz_face2; + property slider_sb_horz_facebutton: tfacecomp + read fslider.svsb_horz.svfacebu + write setssb_horz_facebutton; + property slider_sb_horz_faceendbutton: tfacecomp + read fslider.svsb_horz.svfaceendbu + write setssb_horz_faceendbutton; + property slider_sb_horz_frame: tframecomp + read fslider.svsb_horz.svframe + write setssb_horz_frame; + property slider_sb_horz_framebutton: tframecomp + read fslider.svsb_horz.svframebu + write setssb_horz_framebutton; + property slider_sb_horz_frameendbutton1: tframecomp + read fslider.svsb_horz.svframeendbu1 + write setssb_horz_frameendbutton1; + property slider_sb_horz_frameendbutton2: tframecomp + read fslider.svsb_horz.svframeendbu2 + write setssb_horz_frameendbutton2; + + property slider_sb_vert_width: int32 read fslider.svsb_vert.svwidth + write fslider.svsb_vert.svwidth default -2; + property slider_sb_vert_color: colorty + read fslider.svsb_vert.svcolor + write fslider.svsb_vert.svcolor default cl_default; + property slider_sb_vert_colorpattern: colorty + read fslider.svsb_vert.svcolorpattern + write fslider.svsb_vert.svcolorpattern default cl_default; + property slider_sb_vert_colorpatternclicked: colorty + read fslider.svsb_vert.svcolorpatternclicked + write fslider.svsb_vert.svcolorpatternclicked default cl_default; + property slider_sb_vert_colorglyph: colorty + read fslider.svsb_vert.svcolorglyph + write fslider.svsb_vert.svcolorglyph default cl_default; + property slider_sb_vert_buttonendlength: int32 + read fslider.svsb_vert.svbuttonendlength + write fslider.svsb_vert.svbuttonendlength default -2; + property slider_sb_vert_buttonlength: int32 + read fslider.svsb_vert.svbuttonlength + write fslider.svsb_vert.svbuttonlength default -2; + property slider_sb_vert_buttonminlength: int32 + read fslider.svsb_vert.svbuttonminlength + write fslider.svsb_vert.svbuttonminlength default -2; + property slider_sb_vert_indentstart: int32 + read fslider.svsb_vert.svindentstart + write fslider.svsb_horz.svindentstart default 0; + property slider_sb_vert_indentend: int32 read fslider.svsb_vert.svindentend + write fslider.svsb_vert.svindentend default 0; + property slider_sb_vert_face: tfacecomp + read fslider.svsb_vert.svface + write setssb_vert_face; + property slider_sb_vert_face1: tfacecomp + read fslider.svsb_vert.svface1 + write setssb_vert_face1; + property slider_sb_vert_face2: tfacecomp + read fslider.svsb_vert.svface2 + write setssb_vert_face2; + property slider_sb_vert_facebutton: tfacecomp + read fslider.svsb_vert.svfacebu + write setssb_vert_facebutton; + property slider_sb_vert_faceendbutton: tfacecomp + read fslider.svsb_vert.svfaceendbu + write setssb_vert_faceendbutton; + property slider_sb_vert_frame: tframecomp + read fslider.svsb_vert.svframe + write setssb_vert_frame; + property slider_sb_vert_framebutton: tframecomp + read fslider.svsb_vert.svframebu + write setssb_vert_framebutton; + property slider_sb_vert_frameendbutton1: tframecomp + read fslider.svsb_vert.svframeendbu1 + write setssb_vert_frameendbutton1; + property slider_sb_vert_frameendbutton2: tframecomp + read fslider.svsb_vert.svframeendbu2 + write setssb_vert_frameendbutton2; + + + property framebutton_color: colorty read fframebutton.svcolor + write fframebutton.svcolor default cl_default; + property framebutton_colorglyph: colorty read fframebutton.svcolorglyph + write fframebutton.svcolorglyph default cl_default; + property framebutton_face: tfacecomp read fframebutton.svface + write setframebutton_face; + property framebutton_frame: tframecomp read fframebutton.svframe + write setframebutton_frame; + + property tabbar_horz_face: tfacecomp read ftabbar.svwidgethorz.svface + write settabbar_horz_face; + property tabbar_horz_frame: tframecomp read ftabbar.svwidgethorz.svframe + write settabbar_horz_frame; + property tabbar_horz_tab_color: colorty read ftabbar.svtabhorz.svcolor + write ftabbar.svtabhorz.svcolor default cl_default; + property tabbar_horz_tab_coloractive: colorty + read ftabbar.svtabhorz.svcoloractive + write ftabbar.svtabhorz.svcoloractive default cl_default; + property tabbar_horz_tab_frame: tframecomp read ftabbar.svtabhorz.svframe + write settabbar_horz_tab_frame; + property tabbar_horz_tab_face: tfacecomp read ftabbar.svtabhorz.svface + write settabbar_horz_tab_face; + property tabbar_horz_tab_faceactive: tfacecomp + read ftabbar.svtabhorz.svfaceactive + write settabbar_horz_tab_faceactive; + property tabbar_horz_tab_shift: integer read ftabbar.svtabhorz.svshift + write ftabbar.svtabhorz.svshift default defaulttabshift; + property tabbar_horz_tab_edge_level: int32 + read ftabbar.svtabhorz.svsedge_level + write ftabbar.svtabhorz.svsedge_level default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property tabbar_horz_tab_edge_colordkshadow: colorty + read ftabbar.svtabhorz.svsedge_colordkshadow + write ftabbar.svtabhorz.svsedge_colordkshadow default cl_default; + property tabbar_horz_tab_edge_colorshadow: colorty + read ftabbar.svtabhorz.svsedge_colorshadow + write ftabbar.svtabhorz.svsedge_colorshadow default cl_default; + property tabbar_horz_tab_edge_colorlight: colorty + read ftabbar.svtabhorz.svsedge_colorlight + write ftabbar.svtabhorz.svsedge_colorlight default cl_default; + property tabbar_horz_tab_edge_colorhighlight: colorty + read ftabbar.svtabhorz.svsedge_colorhighlight + write ftabbar.svtabhorz.svsedge_colorhighlight default cl_default; + property tabbar_horz_tab_edge_colordkwidth: int32 + read ftabbar.svtabhorz.svsedge_colordkwidth + write ftabbar.svtabhorz.svsedge_colordkwidth default -1; + //-1 = default + property tabbar_horz_tab_edge_colorhlwidth: int32 + read ftabbar.svtabhorz.svsedge_colorhlwidth + write ftabbar.svtabhorz.svsedge_colorhlwidth default -1; + //-1 = default + property tabbar_horz_tab_edge_imagelist: timagelist + read ftabbar.svtabhorz.svsedge_imagelist + write settabbar_horz_tab_edge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property tabbar_horz_tab_edge_imageoffset: int32 + read ftabbar.svtabhorz.svsedge_imageoffset + write ftabbar.svtabhorz.svsedge_imageoffset default 0; + property tabbar_horz_tab_edge_imagepaintshift: int32 + read ftabbar.svtabhorz.svsedge_imagepaintshift + write ftabbar.svtabhorz.svsedge_imagepaintshift default 0; + + property tabbar_horzopo_face: tfacecomp read ftabbar.svwidgethorzopo.svface + write settabbar_horzopo_face; + property tabbar_horzopo_frame: tframecomp + read ftabbar.svwidgethorzopo.svframe + write settabbar_horzopo_frame; + property tabbar_horzopo_tab_color: colorty read ftabbar.svtabhorzopo.svcolor + write ftabbar.svtabhorzopo.svcolor default cl_default; + property tabbar_horzopo_tab_coloractive: colorty + read ftabbar.svtabhorzopo.svcoloractive + write ftabbar.svtabhorzopo.svcoloractive default cl_default; + property tabbar_horzopo_tab_frame: tframecomp + read ftabbar.svtabhorzopo.svframe + write settabbar_horzopo_tab_frame; + property tabbar_horzopo_tab_face: tfacecomp read ftabbar.svtabhorzopo.svface + write settabbar_horzopo_tab_face; + property tabbar_horzopo_tab_faceactive: tfacecomp + read ftabbar.svtabhorzopo.svfaceactive + write settabbar_horzopo_tab_faceactive; + property tabbar_horzopo_tab_shift: integer read ftabbar.svtabhorzopo.svshift + write ftabbar.svtabhorzopo.svshift default defaulttabshift; + property tabbar_horzopo_tab_edge_level: int32 + read ftabbar.svtabhorzopo.svsedge_level + write ftabbar.svtabhorzopo.svsedge_level default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property tabbar_horzopo_tab_edge_colordkshadow: colorty + read ftabbar.svtabhorzopo.svsedge_colordkshadow + write ftabbar.svtabhorzopo.svsedge_colordkshadow default cl_default; + property tabbar_horzopo_tab_edge_colorshadow: colorty + read ftabbar.svtabhorzopo.svsedge_colorshadow + write ftabbar.svtabhorzopo.svsedge_colorshadow default cl_default; + property tabbar_horzopo_tab_edge_colorlight: colorty + read ftabbar.svtabhorzopo.svsedge_colorlight + write ftabbar.svtabhorzopo.svsedge_colorlight default cl_default; + property tabbar_horzopo_tab_edge_colorhighlight: colorty + read ftabbar.svtabhorzopo.svsedge_colorhighlight + write ftabbar.svtabhorzopo.svsedge_colorhighlight default cl_default; + property tabbar_horzopo_tab_edge_colordkwidth: int32 + read ftabbar.svtabhorzopo.svsedge_colordkwidth + write ftabbar.svtabhorzopo.svsedge_colordkwidth default -1; + //-1 = default + property tabbar_horzopo_tab_edge_colorhlwidth: int32 + read ftabbar.svtabhorzopo.svsedge_colorhlwidth + write ftabbar.svtabhorzopo.svsedge_colorhlwidth default -1; + //-1 = default + property tabbar_horzopo_tab_edge_imagelist: timagelist + read ftabbar.svtabhorzopo.svsedge_imagelist + write settabbar_horzopo_tab_edge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property tabbar_horzopo_tab_edge_imageoffset: int32 + read ftabbar.svtabhorzopo.svsedge_imageoffset + write ftabbar.svtabhorzopo.svsedge_imageoffset default 0; + property tabbar_horzopo_tab_edge_imagepaintshift: int32 + read ftabbar.svtabhorzopo.svsedge_imagepaintshift + write ftabbar.svtabhorzopo.svsedge_imagepaintshift default 0; + + property tabbar_vert_face: tfacecomp read ftabbar.svwidgetvert.svface + write settabbar_vert_face; + property tabbar_vert_frame: tframecomp read ftabbar.svwidgetvert.svframe + write settabbar_vert_frame; + property tabbar_vert_tab_color: colorty read ftabbar.svtabvert.svcolor + write ftabbar.svtabvert.svcolor + default cl_default; + property tabbar_vert_tab_coloractive: colorty + read ftabbar.svtabvert.svcoloractive + write ftabbar.svtabvert.svcoloractive default cl_default; + property tabbar_vert_tab_frame: tframecomp read ftabbar.svtabvert.svframe + write settabbar_vert_tab_frame; + property tabbar_vert_tab_face: tfacecomp read ftabbar.svtabvert.svface + write settabbar_vert_tab_face; + property tabbar_vert_tab_faceactive: tfacecomp + read ftabbar.svtabvert.svfaceactive + write settabbar_vert_tab_faceactive; + property tabbar_vert_tab_shift: integer read ftabbar.svtabvert.svshift + write ftabbar.svtabvert.svshift default defaulttabshift; + property tabbar_vert_tab_edge_level: int32 + read ftabbar.svtabvert.svsedge_level + write ftabbar.svtabvert.svsedge_level default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property tabbar_vert_tab_edge_colordkshadow: colorty + read ftabbar.svtabvert.svsedge_colordkshadow + write ftabbar.svtabvert.svsedge_colordkshadow default cl_default; + property tabbar_vert_tab_edge_colorshadow: colorty + read ftabbar.svtabvert.svsedge_colorshadow + write ftabbar.svtabvert.svsedge_colorshadow default cl_default; + property tabbar_vert_tab_edge_colorlight: colorty + read ftabbar.svtabvert.svsedge_colorlight + write ftabbar.svtabvert.svsedge_colorlight default cl_default; + property tabbar_vert_tab_edge_colorhighlight: colorty + read ftabbar.svtabvert.svsedge_colorhighlight + write ftabbar.svtabvert.svsedge_colorhighlight default cl_default; + property tabbar_vert_tab_edge_colordkwidth: int32 + read ftabbar.svtabvert.svsedge_colordkwidth + write ftabbar.svtabvert.svsedge_colordkwidth default -1; + //-1 = default + property tabbar_vert_tab_edge_colorhlwidth: int32 + read ftabbar.svtabvert.svsedge_colorhlwidth + write ftabbar.svtabvert.svsedge_colorhlwidth default -1; + //-1 = default + property tabbar_vert_tab_edge_imagelist: timagelist + read ftabbar.svtabvert.svsedge_imagelist + write settabbar_vert_tab_edge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property tabbar_vert_tab_edge_imageoffset: int32 + read ftabbar.svtabvert.svsedge_imageoffset + write ftabbar.svtabvert.svsedge_imageoffset default 0; + property tabbar_vert_tab_edge_imagepaintshift: int32 + read ftabbar.svtabvert.svsedge_imagepaintshift + write ftabbar.svtabvert.svsedge_imagepaintshift default 0; + + property tabbar_vertopo_face: tfacecomp read ftabbar.svwidgetvertopo.svface + write settabbar_vertopo_face; + property tabbar_vertopo_frame: tframecomp + read ftabbar.svwidgetvertopo.svframe + write settabbar_vertopo_frame; + property tabbar_vertopo_tab_color: colorty read ftabbar.svtabvertopo.svcolor + write ftabbar.svtabvertopo.svcolor default cl_default; + property tabbar_vertopo_tab_coloractive: colorty + read ftabbar.svtabvertopo.svcoloractive + write ftabbar.svtabvertopo.svcoloractive default cl_default; + property tabbar_vertopo_tab_frame: tframecomp + read ftabbar.svtabvertopo.svframe + write settabbar_vertopo_tab_frame; + property tabbar_vertopo_tab_face: tfacecomp + read ftabbar.svtabvertopo.svface + write settabbar_vertopo_tab_face; + property tabbar_vertopo_tab_faceactive: tfacecomp + read ftabbar.svtabvertopo.svfaceactive + write settabbar_vertopo_tab_faceactive; + property tabbar_vertopo_tab_shift: integer read ftabbar.svtabvertopo.svshift + write ftabbar.svtabvertopo.svshift default defaulttabshift; + property tabbar_vertopo_tab_edge_level: int32 + read ftabbar.svtabvertopo.svsedge_level + write ftabbar.svtabvertopo.svsedge_level default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property tabbar_vertopo_tab_edge_colordkshadow: colorty + read ftabbar.svtabvertopo.svsedge_colordkshadow + write ftabbar.svtabvertopo.svsedge_colordkshadow default cl_default; + property tabbar_vertopo_tab_edge_colorshadow: colorty + read ftabbar.svtabvertopo.svsedge_colorshadow + write ftabbar.svtabvertopo.svsedge_colorshadow default cl_default; + property tabbar_vertopo_tab_edge_colorlight: colorty + read ftabbar.svtabvertopo.svsedge_colorlight + write ftabbar.svtabvertopo.svsedge_colorlight default cl_default; + property tabbar_vertopo_tab_edge_colorhighlight: colorty + read ftabbar.svtabvertopo.svsedge_colorhighlight + write ftabbar.svtabvertopo.svsedge_colorhighlight default cl_default; + property tabbar_vertopo_tab_edge_colordkwidth: int32 + read ftabbar.svtabvertopo.svsedge_colordkwidth + write ftabbar.svtabvertopo.svsedge_colordkwidth default -1; + //-1 = default + property tabbar_vertopo_tab_edge_colorhlwidth: int32 + read ftabbar.svtabvertopo.svsedge_colorhlwidth + write ftabbar.svtabvertopo.svsedge_colorhlwidth default -1; + //-1 = default + property tabbar_vertopo_tab_edge_imagelist: timagelist + read ftabbar.svtabvertopo.svsedge_imagelist + write settabbar_vertopo_tab_edge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property tabbar_vertopo_tab_edge_imageoffset: int32 + read ftabbar.svtabvertopo.svsedge_imageoffset + write ftabbar.svtabvertopo.svsedge_imageoffset default 0; + property tabbar_vertopo_tab_edge_imagepaintshift: int32 + read ftabbar.svtabvertopo.svsedge_imagepaintshift + write ftabbar.svtabvertopo.svsedge_imagepaintshift default 0; + + property toolbar_horz_face: tfacecomp read ftoolbar_horz.svwidget.svface + write settoolbar_horz_face; + property toolbar_horz_frame: tframecomp read ftoolbar_horz.svwidget.svframe + write settoolbar_horz_frame; + property toolbar_horz_buttonface: tfacecomp read ftoolbar_horz.svbuttonface + write settoolbar_horz_buttonface; + property toolbar_horz_buttonframe: tframecomp + read ftoolbar_horz.svbuttonframe + write settoolbar_horz_buttonframe; + property toolbar_horz_buttonframesep: tframecomp + read ftoolbar_horz.svbuttonframesep + write settoolbar_horz_buttonframesep; + property toolbar_vert_face: tfacecomp read ftoolbar_vert.svwidget.svface + write settoolbar_vert_face; + property toolbar_vert_frame: tframecomp read ftoolbar_vert.svwidget.svframe + write settoolbar_vert_frame; + property toolbar_vert_buttonface: tfacecomp read ftoolbar_vert.svbuttonface + write settoolbar_vert_buttonface; + property toolbar_vert_buttonframe: tframecomp + read ftoolbar_vert.svbuttonframe + write settoolbar_vert_buttonframe; + property toolbar_vert_buttonframesep: tframecomp + read ftoolbar_vert.svbuttonframesep + write settoolbar_vert_buttonframesep; + + property tabpage_face: tfacecomp read ftabpage.svwidget.svface + write settabpage_face; + property tabpage_frame: tframecomp read ftabpage.svwidget.svframe + write settabpage_frame; + property tabpage_colortab: colorty read ftabpage.svcolortab + write ftabpage.svcolortab default cl_default; + property tabpage_coloractive: colorty read ftabpage.svcoloractivetab + write ftabpage.svcoloractivetab default cl_default; + property tabpage_facetab: tfacecomp read ftabpage.svfacetab + write settabpage_facetab; + property tabpage_faceactivetab: tfacecomp read ftabpage.svfaceactivetab + write settabpage_faceactivetab; + property tabpage_fonttab: tfontcomp read ftabpage.svfonttab + write settabpage_fonttab; + property tabpage_fontactivetab: tfontcomp read ftabpage.svfontactivetab + write settabpage_fontactivetab; +{ + property popupmenu_options: skinmenuoptionsty read fpopupmenu.options + write fpopupmenu.options default []; +} + property popupmenu_face: tfacecomp read fpopupmenu.svface + write setpopupmenu_face; + property popupmenu_frame: tframecomp read fpopupmenu.svframe + write setpopupmenu_frame; + property popupmenu_itemface: tfacecomp read fpopupmenu.svitemface + write setpopupmenu_itemface; + property popupmenu_itemframe: tframecomp read fpopupmenu.svitemframe + write setpopupmenu_itemframe; + property popupmenu_itemfaceactive: tfacecomp read fpopupmenu.svitemfaceactive + write setpopupmenu_itemfaceactive; + property popupmenu_itemframeactive: tframecomp + read fpopupmenu.svitemframeactive write setpopupmenu_itemframeactive; + property popupmenu_font: tfontcomp read fpopupmenu.svfont + write setpopupmenu_font; + property popupmenu_fontactive: tfontcomp + read fpopupmenu.svfontactive + write setpopupmenu_fontactive; + property popupmenu_separatorframe: tframecomp read + fpopupmenu.svseparatorframe write setpopupmenu_separatorframe; + property popupmenu_checkboxframe: tframecomp read fpopupmenu.svcheckboxframe + write setpopupmenu_checkboxframe; +{ + property mainmenu_options: skinmenuoptionsty read fmainmenu.ma.options + write fmainmenu.ma.options default []; +} + property mainmenu_face: tfacecomp read fmainmenu.svmain.svface + write setmainmenu_face; + property mainmenu_frame: tframecomp read fmainmenu.svmain.svframe + write setmainmenu_frame; + property mainmenu_itemface: tfacecomp read fmainmenu.svmain.svitemface + write setmainmenu_itemface; + property mainmenu_itemframe: tframecomp read fmainmenu.svmain.svitemframe + write setmainmenu_itemframe; + property mainmenu_itemfaceactive: tfacecomp + read fmainmenu.svmain.svitemfaceactive + write setmainmenu_itemfaceactive; + property mainmenu_itemframeactive: tframecomp + read fmainmenu.svmain.svitemframeactive + write setmainmenu_itemframeactive; + property mainmenu_font: tfontcomp read fmainmenu.svmain.svfont + write setmainmenu_font; + property mainmenu_fontactive: tfontcomp read fmainmenu.svmain.svfontactive + write setmainmenu_fontactive; + property mainmenu_separatorframe: tframecomp + read fmainmenu.svmain.svseparatorframe + write setmainmenu_separatorframe; + property mainmenu_checkboxframe: tframecomp + read fmainmenu.svmain.svcheckboxframe + write setmainmenu_checkboxframe; + + property mainmenu_popupface: tfacecomp read fmainmenu.svpopup.svface + write setmainmenu_popupface; + property mainmenu_popupframe: tframecomp read fmainmenu.svpopup.svframe + write setmainmenu_popupframe; + property mainmenu_popupitemface: tfacecomp read fmainmenu.svpopup.svitemface + write setmainmenu_popupitemface; + property mainmenu_popupitemframe: tframecomp + read fmainmenu.svpopup.svitemframe + write setmainmenu_popupitemframe; + property mainmenu_popupitemfaceactive: tfacecomp + read fmainmenu.svpopup.svitemfaceactive + write setmainmenu_popupitemfaceactive; + property mainmenu_popupitemframeactive: tframecomp + read fmainmenu.svpopup.svitemframeactive + write setmainmenu_popupitemframeactive; + property mainmenu_popupfont: tfontcomp read fmainmenu.svpopup.svfont + write setmainmenu_popupfont; + property mainmenu_popupfontactive: tfontcomp + read fmainmenu.svpopup.svfontactive + write setmainmenu_popupfontactive; + property mainmenu_popupseparatorframe: tframecomp + read fmainmenu.svpopup.svseparatorframe + write setmainmenu_popupseparatorframe; + property mainmenu_popupcheckboxframe: tframecomp + read fmainmenu.svpopup.svcheckboxframe + write setmainmenu_popupcheckboxframe; + + property mainmenuwidget_face: tfacecomp read fmainmenuwidget.svwidget.svface + write setmainmenuwidget_face; + property mainmenuwidget_frame: tframecomp + read fmainmenuwidget.svwidget.svframe + write setmainmenuwidget_frame; + property mainmenuwidget_itemface: tfacecomp read fmainmenuwidget.svmenu.svmain.svitemface + write setmainmenuwidget_itemface; + property mainmenuwidget_itemframe: tframecomp read fmainmenuwidget.svmenu.svmain.svitemframe + write setmainmenuwidget_itemframe; + property mainmenuwidget_itemfaceactive: tfacecomp + read fmainmenuwidget.svmenu.svmain.svitemfaceactive + write setmainmenuwidget_itemfaceactive; + property mainmenuwidget_itemframeactive: tframecomp + read fmainmenuwidget.svmenu.svmain.svitemframeactive + write setmainmenuwidget_itemframeactive; + property mainmenuwidget_font: tfontcomp read fmainmenuwidget.svmenu.svmain.svfont + write setmainmenuwidget_font; + property mainmenuwidget_fontactive: tfontcomp read fmainmenuwidget.svmenu.svmain.svfontactive + write setmainmenuwidget_fontactive; + property mainmenuwidget_separatorframe: tframecomp + read fmainmenuwidget.svmenu.svmain.svseparatorframe + write setmainmenuwidget_separatorframe; + property mainmenuwidget_checkboxframe: tframecomp + read fmainmenuwidget.svmenu.svmain.svcheckboxframe + write setmainmenuwidget_checkboxframe; + + property mainmenuwidget_popupface: tfacecomp read fmainmenuwidget.svmenu.svpopup.svface + write setmainmenuwidget_popupface; + property mainmenuwidget_popupframe: tframecomp read fmainmenuwidget.svmenu.svpopup.svframe + write setmainmenuwidget_popupframe; + property mainmenuwidget_popupitemface: tfacecomp read fmainmenuwidget.svmenu.svpopup.svitemface + write setmainmenuwidget_popupitemface; + property mainmenuwidget_popupitemframe: tframecomp + read fmainmenuwidget.svmenu.svpopup.svitemframe + write setmainmenuwidget_popupitemframe; + property mainmenuwidget_popupitemfaceactive: tfacecomp + read fmainmenuwidget.svmenu.svpopup.svitemfaceactive + write setmainmenuwidget_popupitemfaceactive; + property mainmenuwidget_popupitemframeactive: tframecomp + read fmainmenuwidget.svmenu.svpopup.svitemframeactive + write setmainmenuwidget_popupitemframeactive; + property mainmenuwidget_popupfont: tfontcomp read fmainmenuwidget.svmenu.svpopup.svfont + write setmainmenuwidget_popupfont; + property mainmenuwidget_popupfontactive: tfontcomp + read fmainmenuwidget.svmenu.svpopup.svfontactive + write setmainmenuwidget_popupfontactive; + property mainmenuwidget_popupseparatorframe: tframecomp + read fmainmenuwidget.svmenu.svpopup.svseparatorframe + write setmainmenuwidget_popupseparatorframe; + property mainmenuwidget_popupcheckboxframe: tframecomp + read fmainmenuwidget.svmenu.svpopup.svcheckboxframe + write setmainmenuwidget_popupcheckboxframe; + end; + + skincontrollerarty = array of tcustomskincontroller; + + tskinhandler = class + protected + factiveskincontroller: skincontrollerarty; + procedure setactive(const sender: tcustomskincontroller; + var controllerar: skincontrollerarty; + const handleproc: skineventty; var handlevar: skineventty{; + const removeproc: skineventty; var removevar: skineventty}); + procedure updateactive(const sender: tcustomskincontroller); virtual; + procedure doactivate(const sender: tcustomskincontroller); virtual; + procedure dodeactivate(const sender: tcustomskincontroller); virtual; + procedure updateskin1(const ainfo: skininfoty; + const controllerar: skincontrollerarty); +// procedure removeskin1(const ainfo: skininfoty; +// const controllerar: skincontrollerarty); + procedure updateskin(const ainfo: skininfoty); +// procedure removeskin(const ainfo: skininfoty); + end; + +//function activeskincontroller: skincontrollerarty; +//function activeskincontrollerdesign: skincontrollerarty; +procedure setskinhandler(const avalue: tskinhandler); + +implementation +uses + msetabsglob,sysutils,mseapplication,msearrayutils,msefont,msesplitter, + msemenuwidgets,mserichstring; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + tframe1 = class(tcustomframe); + tcustomframe1 = class(tcustomframe); + ttabs1 = class(ttabs); + tmenuitem1 = class(tmenuitem); +var + fhandler: tskinhandler; + +procedure setskinhandler(const avalue: tskinhandler); +begin + fhandler.free; + fhandler:= avalue; +end; +{ +function activeskincontroller: skincontrollerarty; +begin + result:= factiveskincontroller; +end; + +function activeskincontrollerdesign: skincontrollerarty; +begin + result:= factiveskincontrollerdesign; +end; +} +{ tskincolor } + +constructor tskincolor.create; +begin + fcolor:= cl_none; +end; + +procedure tskincolor.setcolor(const avalue: colorty); +begin + if not isvalidmapcolor(avalue) then begin + raise exception.create('Invalid map color.'); + end; + fcolor:= avalue; +end; + +{ tskincolors } + +constructor tskincolors.create; +begin + with fframecolors,edges do begin + light.color:= cl_default; + light.effectcolor:= cl_default; + light.effectwidth:= -1; + shadow.color:= cl_default; + shadow.effectcolor:= cl_default; + shadow.effectwidth:= -1; + frame:= cl_default; + end; + with feditfontcolors do begin + text:= cl_default; + textbackground:= cl_default; + selectedtext:= cl_default; + selectedtextbackground:= cl_default; + end; + inherited create(tskincolor); +end; + +class function tskincolors.getitemclasstype: persistentclassty; +begin + result:= tskincolor; +end; + +procedure tskincolors.setcolors; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tskincolor(fitems[int1]) do begin + frgbbefore:= colorty(colortorgb(color)); + setcolormapvalue(fcolor,frgb); + end; + end; + fframecolorsbefore:= defaultframecolors; + with fframecolors.edges.light do begin + if color <> cl_default then begin + defaultframecolors.edges.light.color:= color; + end; + if effectcolor <> cl_default then begin + defaultframecolors.edges.light.effectcolor:= effectcolor; + end; + if effectwidth <> -1 then begin + defaultframecolors.edges.light.effectwidth:= effectwidth; + end; + end; + with fframecolors.edges.shadow do begin + if color <> cl_default then begin + defaultframecolors.edges.shadow.color:= color; + end; + if effectcolor <> cl_default then begin + defaultframecolors.edges.shadow.effectcolor:= effectcolor; + end; + if effectwidth <> -1 then begin + defaultframecolors.edges.shadow.effectwidth:= effectwidth; + end; + end; + if fframecolors.frame <> cl_default then begin + defaultframecolors.frame:= fframecolors.frame; + end; + feditfontcolorsbefore:= defaulteditfontcolors; + if feditfontcolors.text <> cl_default then begin + defaulteditfontcolors.text:= feditfontcolors.text; + end; + if feditfontcolors.textbackground <> cl_default then begin + defaulteditfontcolors.textbackground:= feditfontcolors.textbackground; + end; + if feditfontcolors.selectedtext <> cl_default then begin + defaulteditfontcolors.selectedtext:= feditfontcolors.selectedtext; + end; + if feditfontcolors.selectedtextbackground <> cl_default then begin + defaulteditfontcolors.selectedtextbackground:= + feditfontcolors.selectedtextbackground; + end; +end; + +procedure tskincolors.restorecolors; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tskincolor(fitems[int1]) do begin + setcolormapvalue(fcolor,frgbbefore); + end; + end; + defaultframecolors:= fframecolorsbefore; + defaulteditfontcolors:= feditfontcolorsbefore; +end; + +{ tskinfontaliass } + +constructor tskinfontaliass.create(const aowner: tcustomskincontroller); +begin + inherited create(aowner,tskinfontalias); +end; + +class function tskinfontaliass.getitemclasstype: persistentclassty; +begin + result:= tskinfontalias; +end; + +procedure tskinfontaliass.setfontalias; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tskinfontalias(fitems[int1]) do begin + if fancestor <> '' then begin + registerfontalias(alias,name,mode,height,width,options,xscale, + ancestor,template); + end + else begin + registerfontalias(alias,name,mode,height,width,options,xscale, + defaultfontalias,template); + end; + end; + end; +end; + +{ tcustomskincontroller } + +constructor tcustomskincontroller.create(aowner: tcomponent); +var + fo1: stockfontty; +begin + fcolors:= tskincolors.create; + ffontalias:= tskinfontaliass.create(self); + for fo1:= low(stockfontty) to high(stockfontty) do begin + fskinfonts[fo1]:= tskinfont.create; + end; + fhotkey_color:= cl_default; + fhotkey_colorbackground:= cl_default; + inherited; +end; + +destructor tcustomskincontroller.destroy; +var + fo1: stockfontty; +begin + active:= false; + inherited; + fcolors.free; + ffontalias.free; + for fo1:= low(stockfontty) to high(stockfontty) do begin + fskinfonts[fo1].free; + end; +end; + +procedure tcustomskincontroller.doactivate; +var + int1: integer; + fo1: stockfontty; +begin + fcolors.setcolors; + ffontalias.setfontalias; + for fo1:= low(stockfontty) to high(stockfontty) do begin + fskinfonts[fo1].updatefont(stockobjects.fonts[fo1]); + end; + checkhotkey(); + if canevent(tmethod(fonactivate)) then begin + fonactivate(self); + end; + updateorder; + for int1:= 0 to high(fextenders) do begin + fextenders[int1].doactivate; + end; +end; + +procedure tcustomskincontroller.dodeactivate; +var + int1: integer; +begin + if canevent(tmethod(fondeactivate)) then begin + fondeactivate(self); + end; + updateorder; + for int1:= 0 to high(fextenders) do begin + fextenders[int1].dodeactivate; + end; +end; + +procedure tcustomskincontroller.loaded; +begin + inherited; + if factive and not (csdesigning in componentstate) then begin + doactivate; + end; +end; + +procedure tcustomskincontroller.checkactive; +var + bo1: boolean; +begin + factivedesign:= factivedesign and factive; + bo1:= factive and (factivedesign or not (csdesigning in componentstate)); + if (fisactive <> bo1) and (fhandler <> nil) then begin + fisactive:= bo1; + if not (csloading in componentstate) and not fisactive then begin + dodeactivate; + fhandler.dodeactivate(self); + end; + fhandler.updateactive(self); + if not (csloading in componentstate) and fisactive then begin + doactivate; + fhandler.doactivate(self); + end; + end; +end; + +procedure tcustomskincontroller.sethotkey_fontstylesadd( + const avalue: fontstylesty); +begin + fhotkey_fontstylesadd:= avalue; + checkhotkey(); +end; + +procedure tcustomskincontroller.sethotkey_fontstylesremove( + const avalue: fontstylesty); +begin + fhotkey_fontstylesremove:= avalue; + checkhotkey(); +end; + +procedure tcustomskincontroller.sethotkey_color(const avalue: colorty); +begin + fhotkey_color:= avalue; + checkhotkey(); +end; + +procedure tcustomskincontroller.sethotkey_colorbackground( + const avalue: colorty); +begin + fhotkey_colorbackground:= avalue; + checkhotkey(); +end; + +procedure tcustomskincontroller.checkhotkey(); +begin + fhashotkey:= false; + if factive and + (factivedesign or not (csdesigning in componentstate)) then begin + if fhotkey_fontstylesadd <> [] then begin + hotkeyfontstylesadd:= fhotkey_fontstylesadd; + fhashotkey:= true; + end; + if fhotkey_fontstylesremove <> [] then begin + hotkeyfontstylesremove:= fhotkey_fontstylesremove; + fhashotkey:= true; + end; + if fhotkey_color <> cl_default then begin + hotkeycolor:= fhotkey_color; + fhashotkey:= true; + end; + if fhotkey_colorbackground <> cl_default then begin + hotkeycolorbackground:= fhotkey_colorbackground; + fhashotkey:= true; + end; + end; +end; + +procedure tcustomskincontroller.setactive(const avalue: boolean); +begin + factive:= avalue; + checkactive; +end; +{ +procedure tcustomskincontroller.setactivedesign(const avalue: boolean); +begin + factivedesign:= avalue; + checkactive; +end; +} +procedure tcustomskincontroller.updateskin1(const ainfo: skininfoty; + const remove: boolean); +label + endlab; +var + bo1,bo2: boolean; + int1: integer; +begin + if factive then begin +// fremoving:= remove; + bo1:= false; + if assigned(fonbeforeupdate) then begin + fonbeforeupdate(self,ainfo,bo1); + end; + if not bo1 then begin + if fupdating = 0 then begin + inc(fupdating); + try + bo2:= false; + for int1:= 0 to high(fextenders) do begin + fextenders[int1].updateskin(ainfo,bo2); + end; + finally + dec(fupdating); + end; + if bo2 then begin + goto endlab; + end; + end; + case ainfo.objectkind of //todo: use table + sok_widget: begin + handlewidget(ainfo); + end; + sok_splitter: begin + handlesplitter(ainfo); + end; + sok_dispwidget: begin + handledispwidget(ainfo); + end; + sok_edit: begin + handleedit(ainfo); + end; + sok_dataedit: begin + handledataedit(ainfo); + end; + sok_booleanedit: begin + handlebooleanedit(ainfo); + end; + sok_groupbox: begin + handlegroupbox(ainfo); + end; + sok_simplebutton: begin + handlesimplebutton(ainfo); + end; + sok_databutton: begin + handledatabutton(ainfo); + end; + sok_slider: begin + handleslider(ainfo); + end; + sok_tabbar: begin + handletabbar(ainfo); + end; + sok_tabpage: begin + handletabpage(ainfo); + end; + sok_toolbar: begin + handletoolbar(ainfo); + end; + sok_mainmenu: begin + handlemainmenu(ainfo); + end; + sok_popupmenu: begin + handlepopupmenu(ainfo); + end; + sok_mainmenuwidget: begin + handlemainmenuwidget(ainfo); + end; + sok_grid: begin + handlegrid(ainfo); + end; + sok_user: begin + handleuserobject(ainfo); + end; + end; + if (sko_container in ainfo.options) and + (ainfo.instance is twidget) then begin + handlecontainer(ainfo); + end; + end; +endlab: + if assigned(fonafterupdate) then begin + fonafterupdate(self,ainfo); + end; + end; +end; + +procedure tcustomskincontroller.updateskin(const ainfo: skininfoty); +begin + updateskin1(ainfo,false); +end; +{ +procedure tcustomskincontroller.removeskin(const ainfo: skininfoty); +begin + updateskin1(ainfo,true); +end; +} +procedure tcustomskincontroller.handlewidget(const askin: skininfoty; + const acolor: pwidgetcolorinfoty = nil); +begin + //dummy +end; + +procedure tcustomskincontroller.setfacetemplate(const face: tfacecomp; + const dest: tcustomface); +begin + if (face <> nil) and (dest.template = nil) then begin + dest.template:= face; + end; +end; + +procedure tcustomskincontroller.setframetemplate(const frame: tframecomp; + const dest: tcustomframe); +begin + if (frame <> nil) and (dest.template = nil) then begin + dest.template:= frame; + end; +end; + +procedure tcustomskincontroller.setwidgetface(const instance: twidget; + const aface: tfacecomp); +begin + with instance do begin + if (aface <> nil) and (optionsskin * + [osk_framebuttononly,osk_noface] = []) then begin + createface; + if face.template = nil then begin + face.template:= aface; + end; + end; + end; +end; +{ +procedure tcustomskincontroller.setwidgetfacetemplate(const instance: twidget; + const aface: tfacecomp); +begin + with instance do begin + if (aface <> nil) and not (osk_framebuttononly in optionsskin) then begin + createface; + face.template:= aface; + end; + end; +end; +} +procedure tcustomskincontroller.setwidgetframe(const instance: twidget; + const aframe: tframecomp); +var + size1: sizety; + col1: colorty; + frame1: framety; + opt1: frameskincontrolleroptionsty; +begin + with twidget1(instance) do begin + if (aframe <> nil) and (optionsskin * + [osk_framebuttononly,osk_noframe] = []) then begin + if fframe = nil then begin + createframe; + include(tcustomframe1(fframe).fstate,fs_paintposinited); + end; + if frame.template <> nil then begin + exit; + end; + col1:= frame.colorclient; + size1:= clientsize; + addsize1(size1,aframe.template.clientsizeextend); + with tframe1(frame).fpaintframedelta do begin + size1.cx:= size1.cx + left + right; + size1.cy:= size1.cy + top + bottom; + end; + frame1:= innerclientframe; + fframe.template:= aframe; + opt1:= aframe.template.optionsskincontroller; + if not (fsco_colorclient in opt1) then begin +// tframe1(frame).fi.colorclient:= col1; //restore + frame.colorclient:= col1; + end; + with tframe1(frame).fi.innerframe do begin + if fsco_frameirightsize in opt1 then begin + size1.cx:= size1.cx + right - frame1.right; + end; + if fsco_frameileftsize in opt1 then begin + size1.cx:= size1.cx + left - frame1.left; + end; + if fsco_frameitopsize in opt1 then begin + size1.cy:= size1.cy + top - frame1.top; + end; + if fsco_frameibottomsize in opt1 then begin + size1.cy:= size1.cy + bottom - frame1.bottom; + end; + end; + with tframe1(frame).fpaintframedelta do begin + size1.cx:= size1.cx - left - right; + size1.cy:= size1.cy - top - bottom; + end; + if not (osk_noclientsize in optionsskin) and + not (fsco_noclientsize in opt1) then begin + clientsize:= size1; //same clientsize as before + end; + end; + end; +end; +{ +procedure tcustomskincontroller.setwidgetframetemplate(const instance: twidget; + const aframe: tframecomp); //no frame nil check +var + size1: sizety; + col1: colorty; +begin + with twidget1(instance) do begin + if (aframe <> nil) and not (osk_framebuttononly in optionsskin) then begin + if fframe = nil then begin + createframe; + include(tcustomframe1(fframe).fstate,fs_paintposinited); + end; + if frame.template = nil then begin + col1:= frame.colorclient; + size1:= clientsize; + frame.template:= aframe; + frame.colorclient:= col1; + clientsize:= size1; //same clientsize as before + end; + end; + end; +end; +} +procedure tcustomskincontroller.setwidgetskin(const instance: twidget; + const ainfo: widgetskininfoty); +begin + setwidgetface(instance,ainfo.svface); + setwidgetframe(instance,ainfo.svframe); +// if fhashotkey then begin +// instance.updatehotkeys(); +// end; +end; +{ +procedure tcustomskincontroller.setwidgetskintemplate(const instance: twidget; + const ainfo: widgetskininfoty); +begin + setwidgetfacetemplate(instance,ainfo.fa); + setwidgetframetemplate(instance,ainfo.fra); +end; +} +procedure tcustomskincontroller.setgroupboxskin(const instance: tgroupbox; + const ainfo: groupboxskininfoty); +begin + setwidgetskin(instance,ainfo.svwidget); +// setwidgetface(instance,ainfo.face); +// setwidgetframetemplate(instance,ainfo.frame); +end; + +procedure tcustomskincontroller.setgridpropskin(const instance: tgridprop; + const ainfo: gridpropskininfoty); +begin + if ainfo.svface <> nil then begin + with instance do begin + createface; + setfacetemplate(ainfo.svface,face); + end; + end; + if ainfo.svframe <> nil then begin + with instance do begin + createframe; + setframetemplate(ainfo.svframe,frame); + end; + end; +end; + +procedure tcustomskincontroller.setgridskin(const instance: tcustomgrid; + const ainfo: gridskininfoty); +var + int1{,int2}: integer; +begin + setwidgetskin(instance,ainfo.svwidget); +// setwidgetface(instance,ainfo.face); +// setwidgetframetemplate(instance,ainfo.frame); + with ainfo do begin + for int1:= -1 downto -instance.fixrows.count do begin + setgridpropskin(instance.fixrows[int1],ainfo.svfixrows); + end; + for int1:= -1 downto -instance.fixcols.count do begin + setgridpropskin(instance.fixcols[int1],ainfo.svfixcols); + end; + for int1:= 0 to instance.datacols.count - 1 do begin + setgridpropskin(instance.datacols[int1],ainfo.svdatacols); + end; + end; +end; + +procedure tcustomskincontroller.seteditskin(const instance: tcustomedit; + const ainfo: editskininfoty); +begin + setwidgetskin(instance,ainfo.svwidget); + with instance do begin + if (ainfo.svempty_text <> '') and (empty_text = '') and + (eo_defaulttext in empty_options) then begin + empty_text:= ainfo.svempty_text; + end; + if (ainfo.svempty_textflags <> []) and + not(tf_force in empty_textflags) then begin + empty_textflags:= ainfo.svempty_textflags; + end; + if (ainfo.svempty_textcolor <> cl_default) and + (empty_textcolor = cl_none) then begin + empty_textcolor:= ainfo.svempty_textcolor; + end; + if (ainfo.svempty_textcolorbackground <> cl_default) and + (empty_textcolorbackground = cl_none) then begin + empty_textcolorbackground:= ainfo.svempty_textcolor; + end; + if (ainfo.svempty_fontstyle <> []) and + not(fs_force in empty_fontstyle) then begin + empty_fontstyle:= ainfo.svempty_fontstyle; + end; + if (ainfo.svempty_color <> cl_default) and + (empty_color = cl_none) then begin + empty_color:= ainfo.svempty_color; + end; + end; +end; + +procedure tcustomskincontroller.setdataeditskin(const instance: tdataedit; + const ainfo: dataeditskininfoty); +begin + seteditskin(instance,ainfo.svedit); +end; + +procedure tcustomskincontroller.setgraphdataeditskin( + const instance: tgraphdataedit; const ainfo: graphdataeditskininfoty); +begin + setwidgetskin(instance,ainfo.svwidget); +// setwidgetface(instance,ainfo.face); +// setwidgetframetemplate(instance,ainfo.frame); +end; + +procedure tcustomskincontroller.setwidgetfont(const instance: twidget; + const afont: tfont); +begin + if afont <> nil then begin + with twidget1(instance) do begin + if ffont = nil then begin + createfont; + ffont.assign(afont); + end; + end; + end; +end; + +procedure tcustomskincontroller.setwidgetcolor(const instance: twidget; + const acolor: colorty); +begin + if (acolor <> cl_default) and + not (osk_framebuttononly in instance.optionsskin) and + (instance.color = cl_default) then begin + instance.color:= acolor; + end; +end; + +function tcustomskincontroller.setwidgetcolorcaptionframe( + const awidget: twidget; const acolor: colorty): boolean; +begin + result:= false; + with twidget1(awidget) do begin + if (osk_colorcaptionframe in optionsskin) or + not (osk_nocolorcaptionframe in optionsskin) and + (fframe is tcustomcaptionframe) and + (tcustomcaptionframe(fframe).caption <> '') then begin + setwidgetcolor(awidget,acolor); + result:= true; + end + end; +end; + +procedure tcustomskincontroller.setstepbuttonskin( + const instance: tcustomstepframe; + const ainfo: stepbuttonskininfoty); +begin + with instance,ainfo do begin + if (colorbutton = cl_default) and + (svcolor <> cl_default) then begin + colorbutton:= svcolor; + end; + if svframe <> nil then begin + instance.createbuttonframe; + setframetemplate(svframe,buttonframe); + end; + if svface <> nil then begin + instance.createbuttonface; + setfacetemplate(svface,buttonface); + end; + end; +end; + +procedure tcustomskincontroller.setframebuttonskin(const instance: tframebutton; + const ainfo: framebuttonskininfoty); +begin + with instance,ainfo do begin + if (svcolor <> cl_default) and (color = cl_default) then begin + color:= svcolor; + end; + if (svcolorglyph <> cl_default) and (colorglyph = cl_default) then begin + colorglyph:= svcolorglyph; + end; + if (svface <> nil) {and (face = nil)} then begin + createface; + setfacetemplate(svface,face); +// face.template:= fa; + end; + if (svframe <> nil) {and (frame = nil)} then begin + createframe; + setframetemplate(svframe,frame); +// frame.template:= fra; + end; + end; +end; + +procedure tcustomskincontroller.setscrollbarskin( + const instance: tcustomscrollbar; + const ainfo: scrollbarskininfoty); +begin + with instance,ainfo do begin + if svwidth <> -2 then begin + width:= svwidth; + end; + if (svcolor <> cl_default) and (color = cl_default) then begin + color:= svcolor; + end; + if (svcolorpattern <> cl_default) and (colorpattern = cl_default) then begin + colorpattern:= svcolorpattern; + end; + if (svcolorpatternclicked <> cl_default) and + (colorpatternclicked = cl_default) then begin + colorpatternclicked:= svcolorpatternclicked; + end; + if svcolorglyph <> cl_default then begin + colorglyph:= svcolorglyph; + end; + if svbuttonendlength <> -2 then begin + buttonendlength:= svbuttonendlength; + end; + if svbuttonlength <> -2 then begin + buttonlength:= svbuttonlength; + end; + if svbuttonminlength <> -2 then begin + buttonminlength:= svbuttonminlength; + end; + if svindentstart <> 0 then begin + indentstart:= svindentstart; + end; + if svindentend <> 0 then begin + indentend:= svindentend; + end; + if (svface <> nil) then begin + createface(); + setfacetemplate(svface,face); + end; + if (svface1 <> nil) then begin + createface1(); + setfacetemplate(svface1,face1); + end; + if (svface2 <> nil) then begin + createface2(); + setfacetemplate(svface2,face2); + end; + if (svfacebu <> nil) {and (facebutton = nil)} then begin + createfacebutton; + setfacetemplate(svfacebu,facebutton); +// facebutton.template:= facebu; + end; + if (svfaceendbu <> nil) {and (faceendbutton = nil)} then begin + createfaceendbutton; + setfacetemplate(svfaceendbu,faceendbutton); +// faceendbutton.template:= faceendbu; + end; + if (svframe <> nil) {and (framebutton = nil)} then begin + createframe; + setframetemplate(svframe,frame); +// framebutton.template:= framebu; + end; + if (svframebu <> nil) {and (framebutton = nil)} then begin + createframebutton; + setframetemplate(svframebu,framebutton); +// framebutton.template:= framebu; + end; + if (svframeendbu1 <> nil) {and (frameendbutton1 = nil)} then begin + createframeendbutton1; + setframetemplate(svframeendbu1,frameendbutton1); +// frameendbutton1.template:= frameendbu1; + end; + if (svframeendbu2 <> nil) {and (frameendbutton2 = nil)} then begin + createframeendbutton2; + setframetemplate(svframeendbu2,frameendbutton2); +// frameendbutton2.template:= frameendbu2; + end; + end; +end; + +procedure tcustomskincontroller.settabsskin(const instance: tcustomtabbar; + const ainfo: tabsskininfoty); +var + int1: integer; +begin + with ttabs1(instance.tabs) do begin + inc(fskinupdating); + beginupdate; + try + if (ainfo.svshift <> defaulttabshift) and + (shift = defaulttabshift) then begin + shift:= ainfo.svshift; + end; + if (ainfo.svsedge_level <> defaultedgelevel) and + (edge_level = defaultedgelevel) then begin + edge_level:= ainfo.svsedge_level; + end; + if (ainfo.svsedge_colordkshadow <> cl_default) and + (edge_colordkshadow = cl_default) then begin + edge_colordkshadow:= ainfo.svsedge_colordkshadow; + end; + if (ainfo.svsedge_colorshadow <> cl_default) and + (edge_colorshadow = cl_default) then begin + edge_colorshadow:= ainfo.svsedge_colorshadow; + end; + if (ainfo.svsedge_colorlight <> cl_default) and + (edge_colorlight = cl_default) then begin + edge_colorlight:= ainfo.svsedge_colorlight; + end; + if (ainfo.svsedge_colorhighlight <> cl_default) and + (edge_colorhighlight = cl_default) then begin + edge_colorhighlight:= ainfo.svsedge_colorhighlight; + end; + if (ainfo.svsedge_colordkwidth <> -1) and + (edge_colordkwidth = -1) then begin + edge_colordkwidth:= ainfo.svsedge_colordkwidth; + end; + if (ainfo.svsedge_colorhlwidth <> -1) and + (edge_colorhlwidth = -1) then begin + edge_colorhlwidth:= ainfo.svsedge_colorhlwidth; + end; + if (ainfo.svsedge_imagelist <> nil) and + (edge_imagelist = nil) then begin + edge_imagelist:= ainfo.svsedge_imagelist; + end; + if (ainfo.svsedge_imageoffset <> 0) and + (edge_imageoffset = -1) then begin + edge_imageoffset:= ainfo.svsedge_imageoffset; + end; + if (ainfo.svsedge_imagepaintshift <> 0) and + (edge_imagepaintshift = 0) then begin + edge_imagepaintshift:= ainfo.svsedge_imagepaintshift; + end; + + if {(frame = nil) and} (ainfo.svframe <> nil) then begin + createframe; + setframetemplate(ainfo.svframe,frame); +// frame.template:= ainfo.frame; + end; + if {(face = nil) and} (ainfo.svface <> nil) then begin + createface; + setfacetemplate(ainfo.svface,face); +// face.template:= ainfo.face; + end; + if {(faceactive = nil) and} (ainfo.svfaceactive <> nil) then begin + createfaceactive; + setfacetemplate(ainfo.svfaceactive,faceactive); +// faceactive.template:= ainfo.faceactive; + end; + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if (ainfo.svcolor <> cl_default) and (color = cl_default) then begin + color:= ainfo.svcolor; + end; + if (ainfo.svcoloractive <> cl_default) and + (coloractive = cl_default) then begin + coloractive:= ainfo.svcoloractive; + end; + end; + end; + finally + endupdate; + dec(fskinupdating); + end; + end; +end; + +procedure tcustomskincontroller.setpopupmenuskin(const instance: tpopupmenu; + const ainfo: menuskininfoty); +begin + with instance do begin + { + if smo_noanim in ainfo.options then begin + options:= options + [mo_noanim]; + end + else begin + options:= options - [mo_noanim]; + end; + } + if (ainfo.svface <> nil) and (facetemplate = nil) then begin + facetemplate:= ainfo.svface; + end; + if (ainfo.svframe <> nil) and (frametemplate = nil) then begin + frametemplate:= ainfo.svframe; + end; + if (ainfo.svitemface <> nil) and (itemfacetemplate = nil) then begin + itemfacetemplate:= ainfo.svitemface; + end; + if (ainfo.svitemframe <> nil) and (itemframetemplate = nil) then begin + itemframetemplate:= ainfo.svitemframe; + end; + if (ainfo.svitemfaceactive <> nil) and + (itemfacetemplateactive = nil) then begin + itemfacetemplateactive:= ainfo.svitemfaceactive; + end; + if (ainfo.svitemframeactive <> nil) and + (itemframetemplateactive = nil) then begin + itemframetemplateactive:= ainfo.svitemframeactive; + end; + if menu <> nil then begin + with tmenuitem1(menu) do begin; + if (ainfo.svfont <> nil) and + ((ffont = nil) or (ffont.template = nil)) then begin + createfont(); + ffont.template:= ainfo.svfont; + end; + if (ainfo.svfontactive <> nil) and + ((ffontactive = nil) or (ffontactive.template = nil)) then begin + createfontactive(); + ffontactive.template:= ainfo.svfontactive; + end; + end; + end; + if (ainfo.svseparatorframe <> nil) and + (separatorframetemplate = nil) then begin + separatorframetemplate:= ainfo.svseparatorframe; + end; + if (ainfo.svcheckboxframe <> nil) and + (checkboxframetemplate = nil) then begin + checkboxframetemplate:= ainfo.svcheckboxframe; + end; + end; + if fhashotkey then begin + instance.updatehotkeys(); + end; +end; + +procedure tcustomskincontroller.setmainmenuskin(const instance: tcustommainmenu; + const ainfo: mainmenuskininfoty); +var + i1,i2: int32; +begin +{$warnings off} + setpopupmenuskin(tpopupmenu(instance),ainfo.svmain); +{$warnings on} + with instance,ainfo do begin + if (svpopup.svface <> nil) and (popupfacetemplate = nil) then begin + popupfacetemplate:= svpopup.svface; + end; + if (svpopup.svframe <> nil) and (popupframetemplate = nil) then begin + popupframetemplate:= svpopup.svframe; + end; + if (svpopup.svitemface <> nil) and (popupitemfacetemplate = nil) then begin + popupitemfacetemplate:= svpopup.svitemface; + end; + if (svpopup.svitemframe <> nil) and (popupitemframetemplate = nil) then begin + popupitemframetemplate:= svpopup.svitemframe; + end; + if (svpopup.svitemfaceactive <> nil) and + (popupitemfacetemplateactive = nil) then begin + popupitemfacetemplateactive:= svpopup.svitemfaceactive; + end; + if (svpopup.svitemframeactive <> nil) and + (popupitemframetemplateactive = nil) then begin + popupitemframetemplateactive:= svpopup.svitemframeactive; + end; + if (svpopup.svseparatorframe <> nil) and + (popupseparatorframetemplate = nil) then begin + popupseparatorframetemplate:= svpopup.svseparatorframe; + end; + if (svpopup.svcheckboxframe <> nil) and + (popupcheckboxframetemplate = nil) then begin + popupcheckboxframetemplate:= svpopup.svcheckboxframe; + end; + if menu <> nil then begin + if svpopup.svfont <> nil then begin + for i1:= 0 to menu.count-1 do begin + with tmenuitem1(menu[i1]) do begin; + for i2:= 0 to submenu.count - 1 do begin + with tmenuitem1(submenu[i2]) do begin; + if ((ffont = nil) or (ffont.template = nil)) then begin + createfont(); + ffont.template:= svpopup.svfont; + end; + end; + end; + end; + end; + end; + if svpopup.svfontactive <> nil then begin + for i1:= 0 to menu.count-1 do begin + with tmenuitem1(menu[i1]) do begin; + for i2:= 0 to submenu.count - 1 do begin + with tmenuitem1(submenu[i2]) do begin; + if ((ffontactive = nil) or (ffontactive.template = nil)) then begin + createfontactive(); + ffontactive.template:= svpopup.svfontactive; + end; + end; + end; + end; + end; + end; + end; + end; + if fhashotkey then begin + instance.updatehotkeys(); + end; +end; + +procedure tcustomskincontroller.setcolors(const avalue: tskincolors); +begin + fcolors.assign(avalue); +end; + +procedure tcustomskincontroller.setfontalias(const avalue: tskinfontaliass); +begin + ffontalias.assign(avalue); +end; + +procedure tcustomskincontroller.handlegroupbox(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlesimplebutton(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handledatabutton(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handleslider(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handleuserobject(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlecontainer(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handletabbar(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handletabpage(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handleedit(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handledispwidget(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handledataedit(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlebooleanedit(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlemainmenu(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlepopupmenu(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlemainmenuwidget(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlegrid(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handletoolbar(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlesplitter(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.updateorder; +begin + updateclientorder(fextendernames,pointerarty(fextenders), + {$ifdef FPC}@{$endif}getextendernames); +end; + +function tcustomskincontroller.getextendernames: stringarty; +var + int1: integer; +begin + setlength(result,length(fextenders)); + for int1:= 0 to high(result) do begin + result[int1]:= getclientname(fextenders[int1],int1); + end; +end; + +function tcustomskincontroller.getextenders: integer; +begin + result:= length(fextenders); +end; + +procedure tcustomskincontroller.setextenders(const avalue: integer); +begin + //dummy +end; + +procedure tcustomskincontroller.readextendernames(reader: treader); +begin + readstringar(reader,fextendernames); +end; + +procedure tcustomskincontroller.writeextendernames(writer: twriter); +begin + writestringar(writer,getextendernames); +end; + +procedure tcustomskincontroller.readactivedesign(reader: treader); +begin + reader.readboolean; //dummy +end; + +procedure tcustomskincontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('extendernames',{$ifdef FPC}@{$endif}readextendernames, + {$ifdef FPC}@{$endif}writeextendernames,high(fextenders) >= 0); + filer.defineproperty('activedesign',{$ifdef FPC}@{$endif}readactivedesign,nil, + false); +end; + +procedure tcustomskincontroller.registerextender(const aextender: tskinextender); +begin + additem(pointerarty(fextenders),aextender); +end; + +procedure tcustomskincontroller.unregisterextender(const aextender: tskinextender); +begin + removeitem(pointerarty(fextenders),aextender); +end; + +procedure tcustomskincontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + if event = oe_destroyed then begin + removeitem(pointerarty(fextenders),sender); + end; + inherited; +end; + +function tcustomskincontroller.getskinfont(const aindex: integer): tskinfont; +begin + result:= fskinfonts[stockfontty(aindex)]; +end; + +procedure tcustomskincontroller.setskinfont(const aindex: integer; + const avalue: tskinfont); +begin + fskinfonts[stockfontty(aindex)].assign(avalue); +end; + +procedure tcustomskincontroller.setgroups(const avalue: string); +var + ar1: stringarty; + ar2: groupinfoarty; + int1,int2: integer; +begin + if avalue = '' then begin + fgroupinfo:= nil; + end + else begin + ar1:= splitstring(avalue,','); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin +// int2:= msestrings.strscan(ar1[int1],'.'); + int2:= msestrings.findchar(ar1[int1],'.'); + if int2 > 0 then begin + ar2[int1].min:= strtoint(copy(ar1[int1],1,int2-1)); + if ar1[int1][int2+1] <> '.' then begin + raise exception.create('Invalid groups format'); + end; + ar2[int1].max:= strtoint(copy(ar1[int1],int2+2,bigint)); + end + else begin + ar2[int1].min:= strtoint(ar1[int1]); + ar2[int1].max:= ar2[int1].min; + end; + end; + fgroupinfo:= ar2; + end; + fgroups:= avalue; +end; + +{ tskincontroller } + +procedure inittabsskininfo(var info: tabsskininfoty); +begin + info.svcolor:= cl_default; + info.svcoloractive:= cl_default; + info.svshift:= defaulttabshift; + info.svsedge_level:= defaultedgelevel; + info.svsedge_colordkshadow:= cl_default; + info.svsedge_colorshadow:= cl_default; + info.svsedge_colorlight:= cl_default; + info.svsedge_colorhighlight:= cl_default; + info.svsedge_colordkwidth:= -1; + info.svsedge_colorhlwidth:= -1; +end; + +procedure initscrollbarskininfo(var ascrollbar: scrollbarskininfoty); +begin + with ascrollbar do begin + svwidth:= -2; + svcolor:= cl_default; + svcolorpattern:= cl_default; + svcolorpatternclicked:= cl_default; + svcolorglyph:= cl_default; + svbuttonendlength:= -2; + svbuttonlength:= -2; + svbuttonminlength:= -2; +// svindentstart:= -2; //default 0 +// svindentend:= -2; + end; +end; + +constructor tskincontroller.create(aowner: tcomponent); +begin + fwidgetcolor.svcolor:= cl_default; + fwidgetcolor.svcolorcaptionframe:= cl_default; + fstepbutton.svcolor:= cl_default; + + initscrollbarskininfo(fsb_horz); + initscrollbarskininfo(fsb_vert); + + fsplitter.svcolor.svcolor:= cl_default; + fsplitter.svcolor.svcolorcaptionframe:= cl_default; + fsplitter.svcolorgrip:= cl_default; + fsplitter.svgrip:= stb_default; + + fdispwidget.svcolor.svcolor:= cl_default; + fdispwidget.svcolor.svcolorcaptionframe:= cl_default; + + fedit.svempty_color:= cl_default; + fedit.svempty_textcolor:= cl_default; + fedit.svempty_textcolorbackground:= cl_default; + + fdataedit.svedit.svempty_color:= cl_default; + fdataedit.svedit.svempty_textcolor:= cl_default; + fdataedit.svedit.svempty_textcolorbackground:= cl_default; + + fbutton.svcolor:= cl_default; + fdatabutton.svcolor:= cl_default; + fslider.svcolor:= cl_default; + initscrollbarskininfo(fslider.svsb_horz); + initscrollbarskininfo(fslider.svsb_vert); + fframebutton.svcolor:= cl_default; + fframebutton.svcolorglyph:= cl_default; + inittabsskininfo(ftabbar.svtabhorz); + inittabsskininfo(ftabbar.svtabvert); + inittabsskininfo(ftabbar.svtabhorzopo); + inittabsskininfo(ftabbar.svtabvertopo); +{ + ftabbar.svtabhorz.svcolor:= cl_default; + ftabbar.svtabhorz.svcoloractive:= cl_default; + ftabbar.svtabhorz.svshift:= defaulttabshift; + ftabbar.svtabvert.svcolor:= cl_default; + ftabbar.svtabvert.svcoloractive:= cl_default; + ftabbar.svtabvert.svshift:= defaulttabshift; + ftabbar.svtabhorzopo.svcolor:= cl_default; + ftabbar.svtabhorzopo.svcoloractive:= cl_default; + ftabbar.svtabhorzopo.svshift:= defaulttabshift; + ftabbar.svtabvertopo.svcolor:= cl_default; + ftabbar.svtabvertopo.svcoloractive:= cl_default; + ftabbar.svtabvertopo.svshift:= defaulttabshift; +} + ftabpage.svcolortab:= cl_default; + ftabpage.svcoloractivetab:= cl_default; + inherited; +end; + +destructor tskincontroller.destroy; +begin + inherited; + fbutton.svfont.free; +end; + +procedure tskincontroller.setsplitter_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsplitter.svwidget.svface)); +end; + +procedure tskincontroller.setsplitter_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsplitter.svwidget.svframe)); +end; + +procedure tskincontroller.setdispwidget_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdispwidget.svwidget.svface)); +end; + +procedure tskincontroller.setdispwidget_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdispwidget.svwidget.svframe)); +end; + +procedure tskincontroller.setedit_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fedit.svwidget.svface)); +end; + +procedure tskincontroller.setedit_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fedit.svwidget.svframe)); +end; + +procedure tskincontroller.setdataedit_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdataedit.svedit.svwidget.svface)); +end; + +procedure tskincontroller.setdataedit_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdataedit.svedit.svwidget.svframe)); +end; + +procedure tskincontroller.setbooleanedit_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent( + fbooleanedit.svgraphdataedit.svwidget.svface)); +end; + +procedure tskincontroller.setbooleanedit_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent( + fbooleanedit.svgraphdataedit.svwidget.svframe)); +end; + +procedure tskincontroller.setcontainer_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fcontainer.svwidget.svface)); +end; + +procedure tskincontroller.setcontainer_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fcontainer.svwidget.svframe)); +end; + +procedure tskincontroller.settabbar_horz_tab_edge_imagelist( + const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorz.svsedge_imagelist)); +end; + +procedure tskincontroller.settabbar_vert_tab_edge_imagelist( + const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvert.svsedge_imagelist)); +end; + +procedure tskincontroller.settabbar_horzopo_tab_edge_imagelist( + const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorzopo.svsedge_imagelist)); +end; + +procedure tskincontroller.settabbar_vertopo_tab_edge_imagelist( + const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvertopo.svsedge_imagelist)); +end; + +procedure tskincontroller.setsb_vert_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svface)); +end; + +procedure tskincontroller.setsb_vert_face1(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svface1)); +end; + +procedure tskincontroller.setsb_vert_face2(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svface2)); +end; + +procedure tskincontroller.setsb_vert_facebutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svfacebu)); +end; + +procedure tskincontroller.setsb_vert_faceendbutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svfaceendbu)); +end; + +procedure tskincontroller.setsb_vert_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svframe)); +end; + +procedure tskincontroller.setsb_vert_framebutton(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svframebu)); +end; + +procedure tskincontroller.setsb_vert_frameendbutton1(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svframeendbu1)); +end; + +procedure tskincontroller.setsb_vert_frameendbutton2(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svframeendbu2)); +end; + +procedure tskincontroller.setsb_horz_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svface)); +end; + +procedure tskincontroller.setsb_horz_face1(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svface1)); +end; + +procedure tskincontroller.setsb_horz_face2(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svface2)); +end; + +procedure tskincontroller.setsb_horz_facebutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svfacebu)); +end; + +procedure tskincontroller.setsb_horz_faceendbutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svfaceendbu)); +end; + +procedure tskincontroller.setsb_horz_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svframe)); +end; + +procedure tskincontroller.setsb_horz_framebutton(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svframebu)); +end; + +procedure tskincontroller.setsb_horz_frameendbutton1(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svframeendbu1)); +end; + +procedure tskincontroller.setsb_horz_frameendbutton2(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svframeendbu2)); +end; + +procedure tskincontroller.setgroupbox_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgroupbox.svwidget.svface)); +end; + +procedure tskincontroller.setgroupbox_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgroupbox.svwidget.svframe)); +end; + +procedure tskincontroller.setgrid_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svwidget.svface)); +end; + +procedure tskincontroller.setgrid_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svwidget.svframe)); +end; + +procedure tskincontroller.setgrid_fixrows_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svfixrows.svface)); +end; + +procedure tskincontroller.setgrid_fixrows_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svfixrows.svframe)); +end; + +procedure tskincontroller.setgrid_fixcols_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svfixcols.svface)); +end; + +procedure tskincontroller.setgrid_fixcols_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svfixcols.svframe)); +end; + +procedure tskincontroller.setgrid_datacols_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svdatacols.svface)); +end; + +procedure tskincontroller.setgrid_datacols_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svdatacols.svframe)); +end; + +procedure tskincontroller.setbutton_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fbutton.svwidget.svface)); +end; + +procedure tskincontroller.setbutton_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fbutton.svwidget.svframe)); +end; + +procedure tskincontroller.setdatabutton_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdatabutton.svwidget.svface)); +end; + +procedure tskincontroller.setdatabutton_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdatabutton.svwidget.svframe)); +end; + +procedure tskincontroller.setslider_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svwidget.svface)); +end; + +procedure tskincontroller.setslider_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svwidget.svframe)); +end; + +procedure tskincontroller.setssb_vert_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svface)); +end; + +procedure tskincontroller.setssb_vert_face1(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svface1)); +end; + +procedure tskincontroller.setssb_vert_face2(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svface2)); +end; + +procedure tskincontroller.setssb_vert_facebutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svfacebu)); +end; + +procedure tskincontroller.setssb_vert_faceendbutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svfaceendbu)); +end; + +procedure tskincontroller.setssb_vert_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svframe)); +end; + +procedure tskincontroller.setssb_vert_framebutton(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svframebu)); +end; + +procedure tskincontroller.setssb_vert_frameendbutton1(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svframeendbu1)); +end; + +procedure tskincontroller.setssb_vert_frameendbutton2(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svframeendbu2)); +end; + +procedure tskincontroller.setssb_horz_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svface)); +end; + +procedure tskincontroller.setssb_horz_face1(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svface1)); +end; + +procedure tskincontroller.setssb_horz_face2(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svface2)); +end; + +procedure tskincontroller.setssb_horz_facebutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svfacebu)); +end; + +procedure tskincontroller.setssb_horz_faceendbutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svfaceendbu)); +end; + +procedure tskincontroller.setssb_horz_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svframe)); +end; + +procedure tskincontroller.setssb_horz_framebutton(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svframebu)); +end; + +procedure tskincontroller.setssb_horz_frameendbutton1(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svframeendbu1)); +end; + +procedure tskincontroller.setssb_horz_frameendbutton2(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svframeendbu2)); +end; + +procedure tskincontroller.setframebutton_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fframebutton.svface)); +end; + +procedure tskincontroller.setframebutton_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fframebutton.svframe)); +end; + +procedure tskincontroller.setstepbutton_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fstepbutton.svface)); +end; + +procedure tskincontroller.setstepbutton_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fstepbutton.svframe)); +end; + +procedure tskincontroller.settabbar_horz_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgethorz.svface)); +end; + +procedure tskincontroller.settabbar_horz_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgethorz.svframe)); +end; + +procedure tskincontroller.settabbar_horz_tab_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorz.svface)); +end; + +procedure tskincontroller.settabbar_horz_tab_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorz.svframe)); +end; + +procedure tskincontroller.settabbar_horz_tab_faceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorz.svfaceactive)); +end; + +procedure tskincontroller.settabbar_vert_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgetvert.svface)); +end; + +procedure tskincontroller.settabbar_vert_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgetvert.svframe)); +end; + +procedure tskincontroller.settabbar_vert_tab_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvert.svface)); +end; + +procedure tskincontroller.settabbar_vert_tab_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvert.svframe)); +end; + +procedure tskincontroller.settabbar_vert_tab_faceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvert.svfaceactive)); +end; + +procedure tskincontroller.settabbar_horzopo_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgethorzopo.svface)); +end; + +procedure tskincontroller.settabbar_horzopo_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgethorzopo.svframe)); +end; + +procedure tskincontroller.settabbar_horzopo_tab_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorzopo.svface)); +end; + +procedure tskincontroller.settabbar_horzopo_tab_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorzopo.svframe)); +end; + +procedure tskincontroller.settabbar_horzopo_tab_faceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorzopo.svfaceactive)); +end; + +procedure tskincontroller.settabbar_vertopo_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgetvertopo.svface)); +end; + +procedure tskincontroller.settabbar_vertopo_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgetvertopo.svframe)); +end; + +procedure tskincontroller.settabbar_vertopo_tab_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvertopo.svface)); +end; + +procedure tskincontroller.settabbar_vertopo_tab_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvertopo.svframe)); +end; + +procedure tskincontroller.settabbar_vertopo_tab_faceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvertopo.svfaceactive)); +end; + +procedure tskincontroller.settabpage_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svwidget.svface)); +end; + +procedure tskincontroller.settabpage_facetab(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svfacetab)); +end; + +procedure tskincontroller.settabpage_faceactivetab(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svfaceactivetab)); +end; + +procedure tskincontroller.settabpage_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svwidget.svframe)); +end; + +procedure tskincontroller.settabpage_fonttab(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svfonttab)); +end; + +procedure tskincontroller.settabpage_fontactivetab(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svfontactivetab)); +end; + +procedure tskincontroller.settoolbar_horz_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svwidget.svface)); +end; + +procedure tskincontroller.settoolbar_horz_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svwidget.svframe)); +end; + +procedure tskincontroller.settoolbar_horz_buttonface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svbuttonface)); +end; + +procedure tskincontroller.settoolbar_horz_buttonfacechecked( + const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svbuttonfacechecked)); +end; + +procedure tskincontroller.settoolbar_horz_buttonframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svbuttonframe)); +end; + +procedure tskincontroller.settoolbar_horz_buttonframechecked( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svbuttonframechecked)); +end; + +procedure tskincontroller.settoolbar_horz_buttonframesep( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svbuttonframesep)); +end; + +procedure tskincontroller.settoolbar_vert_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svwidget.svface)); +end; + +procedure tskincontroller.settoolbar_vert_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svwidget.svframe)); +end; + +procedure tskincontroller.settoolbar_vert_buttonface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svbuttonface)); +end; + +procedure tskincontroller.settoolbar_vert_buttonfacechecked( + const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svbuttonfacechecked)); +end; + +procedure tskincontroller.settoolbar_vert_buttonframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svbuttonframe)); +end; + +procedure tskincontroller.settoolbar_vert_buttonframechecked( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svbuttonframechecked)); +end; + +procedure tskincontroller.settoolbar_vert_buttonframesep( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svbuttonframesep)); +end; + +procedure tskincontroller.setpopupmenu_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svface)); +end; + +procedure tskincontroller.setpopupmenu_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svframe)); +end; + +procedure tskincontroller.setpopupmenu_itemface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svitemface)); +end; + +procedure tskincontroller.setpopupmenu_itemframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svitemframe)); +end; + +procedure tskincontroller.setpopupmenu_itemfaceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svitemfaceactive)); +end; + +procedure tskincontroller.setpopupmenu_itemframeactive( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svitemframeactive)); +end; + +procedure tskincontroller.setpopupmenu_font(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svfont)); +end; + +procedure tskincontroller.setpopupmenu_fontactive(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svfontactive)); +end; + +procedure tskincontroller.setpopupmenu_separatorframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svseparatorframe)); +end; + +procedure tskincontroller.setpopupmenu_checkboxframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svcheckboxframe)); +end; + +procedure tskincontroller.setmainmenu_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svface)); +end; + +procedure tskincontroller.setmainmenu_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svframe)); +end; + +procedure tskincontroller.setmainmenu_itemface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svitemface)); +end; + +procedure tskincontroller.setmainmenu_itemframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svitemframe)); +end; + +procedure tskincontroller.setmainmenu_itemfaceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svitemfaceactive)); +end; + +procedure tskincontroller.setmainmenu_itemframeactive(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svitemframeactive)); +end; + +procedure tskincontroller.setmainmenu_font(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svfont)); +end; + +procedure tskincontroller.setmainmenu_fontactive(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svfontactive)); +end; + +procedure tskincontroller.setmainmenu_separatorframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svseparatorframe)); +end; + +procedure tskincontroller.setmainmenu_checkboxframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svcheckboxframe)); +end; + +procedure tskincontroller.setmainmenu_popupface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svface)); +end; + +procedure tskincontroller.setmainmenu_popupframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svframe)); +end; + +procedure tskincontroller.setmainmenu_popupitemface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svitemface)); +end; + +procedure tskincontroller.setmainmenu_popupitemframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svitemframe)); +end; + +procedure tskincontroller.setmainmenu_popupitemfaceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svitemfaceactive)); +end; + +procedure tskincontroller.setmainmenu_popupitemframeactive(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svitemframeactive)); +end; + +procedure tskincontroller.setmainmenu_popupfont(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svfont)); +end; + +procedure tskincontroller.setmainmenu_popupfontactive(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svfontactive)); +end; + +procedure tskincontroller.setmainmenu_popupseparatorframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svseparatorframe)); +end; + +procedure tskincontroller.setmainmenu_popupcheckboxframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svcheckboxframe)); +end; + +procedure tskincontroller.setmainmenuwidget_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svwidget.svface)); +end; + +procedure tskincontroller.setmainmenuwidget_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svwidget.svframe)); +end; + +procedure tskincontroller.setmainmenuwidget_itemface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svitemface)); +end; + +procedure tskincontroller.setmainmenuwidget_itemframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svitemframe)); +end; + +procedure tskincontroller.setmainmenuwidget_itemfaceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svitemfaceactive)); +end; + +procedure tskincontroller.setmainmenuwidget_itemframeactive(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svitemframeactive)); +end; + +procedure tskincontroller.setmainmenuwidget_font(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svfont)); +end; + +procedure tskincontroller.setmainmenuwidget_fontactive(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svfontactive)); +end; + +procedure tskincontroller.setmainmenuwidget_separatorframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svseparatorframe)); +end; + +procedure tskincontroller.setmainmenuwidget_checkboxframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svcheckboxframe)); +end; + +procedure tskincontroller.setmainmenuwidget_popupface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svface)); +end; + +procedure tskincontroller.setmainmenuwidget_popupframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svframe)); +end; + +procedure tskincontroller.setmainmenuwidget_popupitemface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svitemface)); +end; + +procedure tskincontroller.setmainmenuwidget_popupitemframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svitemframe)); +end; + +procedure tskincontroller.setmainmenuwidget_popupitemfaceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svitemfaceactive)); +end; + +procedure tskincontroller.setmainmenuwidget_popupitemframeactive(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svitemframeactive)); +end; + +procedure tskincontroller.setmainmenuwidget_popupfont(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svfont)); +end; + +procedure tskincontroller.setmainmenuwidget_popupfontactive( + const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent( + fmainmenuwidget.svmenu.svpopup.svfontactive)); +end; + +procedure tskincontroller.setmainmenuwidget_popupseparatorframe( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent( + fmainmenuwidget.svmenu.svpopup.svseparatorframe)); +end; + +procedure tskincontroller.setmainmenuwidget_popupcheckboxframe( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent( + fmainmenuwidget.svmenu.svpopup.svcheckboxframe)); +end; + +procedure tskincontroller.handlewidget(const askin: skininfoty; + const acolor: pwidgetcolorinfoty); +var + int1: integer; + wi1: twidget1; + co1,co2: colorty; +begin + if acolor = nil then begin + co1:= fwidgetcolor.svcolor; + co2:= fwidgetcolor.svcolorcaptionframe + end + else begin + co1:= acolor^.svcolor; + if co1 = cl_default then begin + co1:= fwidgetcolor.svcolor; + end; + co2:= acolor^.svcolorcaptionframe; + if co2 = cl_default then begin + co2:= fwidgetcolor.svcolorcaptionframe; + end; + end; + wi1:= twidget1(askin.instance); + with wi1 do begin + if fframe <> nil then begin + if fframe is tcustomscrollframe then begin + setscrollbarskin(tcustomscrollframe(fframe).sbvert,fsb_vert); + setscrollbarskin(tcustomscrollframe(fframe).sbhorz,fsb_horz); + end + else begin + if fframe is tcustombuttonframe then begin + with tcustombuttonframe(fframe) do begin + for int1:= 0 to buttons.count - 1 do begin + setframebuttonskin(buttons[int1],fframebutton); + end; + end; + end + else begin + if fframe is tcustomstepframe then begin + setstepbuttonskin(tcustomstepframe(fframe),fstepbutton); + end; + end; + end; + end; + if not setwidgetcolorcaptionframe(wi1,co2) then begin + setwidgetcolor(wi1,co1); + end; + if fhashotkey then begin + updatehotkeys(); + end; + end; +end; + +procedure tskincontroller.handlegroupbox(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setgroupboxskin(tgroupbox(ainfo.instance),fgroupbox); +end; + +procedure tskincontroller.handlesimplebutton(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setwidgetcolor(twidget(ainfo.instance),fbutton.svcolor); + setwidgetskin(twidget(ainfo.instance),fbutton.svwidget); + setwidgetfont(twidget(ainfo.instance),fbutton.svfont); + with tsimplebutton(ainfo.instance) do begin + if not (osk_nooptions in optionsskin) then begin + if fbutton.svoptionsadd <> [] then begin + options:= options + fbutton.svoptionsadd; + end; + if fbutton.svoptionsremove <> [] then begin + options:= options - fbutton.svoptionsremove; + end; + end; + end; +end; + +procedure tskincontroller.handledatabutton(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setwidgetcolor(twidget(ainfo.instance),fdatabutton.svcolor); + setwidgetskin(twidget(ainfo.instance),fdatabutton.svwidget); + setwidgetfont(twidget(ainfo.instance),fdatabutton.svfont); + with tcustomdatabutton(ainfo.instance) do begin + if not (osk_nooptions in optionsskin) then begin + if fdatabutton.svoptionsadd <> [] then begin + options:= options + fdatabutton.svoptionsadd; + end; + if fdatabutton.svoptionsremove <> [] then begin + options:= options - fdatabutton.svoptionsremove; + end; + end; + end; +end; + +procedure tskincontroller.handleslider(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setwidgetcolor(twidget(ainfo.instance),fslider.svcolor); + setwidgetskin(twidget(ainfo.instance),fslider.svwidget); + with tcustomslider(ainfo.instance) do begin + if direction in [gd_left,gd_right] then begin + setscrollbarskin(scrollbar,fslider.svsb_horz); + end + else begin + setscrollbarskin(scrollbar,fslider.svsb_vert); + end; + end; +end; + +procedure tskincontroller.handlecontainer(const ainfo: skininfoty); +begin + setwidgetskin(twidget(ainfo.instance),fcontainer.svwidget); +end; + +procedure tskincontroller.createbutton_font; +begin + if fbutton.svfont = nil then begin + fbutton.svfont:= toptionalfont.create; + end; +end; + +procedure tskincontroller.setbutton_font(const avalue: toptionalfont); +begin + setoptionalobject(avalue,fbutton.svfont,{$ifdef FPC}@{$endif}createbutton_font); +end; + +function tskincontroller.getbutton_font: toptionalfont; +begin + getoptionalobject(fbutton.svfont,{$ifdef FPC}@{$endif}createbutton_font); + result:= fbutton.svfont; +end; + +procedure tskincontroller.createdatabutton_font; +begin + if fdatabutton.svfont = nil then begin + fdatabutton.svfont:= toptionalfont.create; + end; +end; + +procedure tskincontroller.setdatabutton_font(const avalue: toptionalfont); +begin + setoptionalobject(avalue,fdatabutton.svfont, + {$ifdef FPC}@{$endif}createbutton_font); +end; + +function tskincontroller.getdatabutton_font: toptionalfont; +begin + getoptionalobject(fdatabutton.svfont,{$ifdef FPC}@{$endif}createbutton_font); + result:= fdatabutton.svfont; +end; + +procedure tskincontroller.handletabbar(const ainfo: skininfoty); +var + ta1: tcustomtabbar; +begin + handlewidget(ainfo); + ta1:= tcustomtabbar(ainfo.instance); + if tabo_vertical in ta1.options then begin + if tabo_opposite in ta1.options then begin + setwidgetskin(ta1,ftabbar.svwidgetvertopo); + settabsskin(ta1,ftabbar.svtabvertopo); + end + else begin + setwidgetskin(ta1,ftabbar.svwidgetvert); + settabsskin(ta1,ftabbar.svtabvert); + end; + end + else begin + if tabo_opposite in ta1.options then begin + setwidgetskin(ta1,ftabbar.svwidgethorzopo); + settabsskin(ta1,ftabbar.svtabhorzopo); + end + else begin + setwidgetskin(ta1,ftabbar.svwidgethorz); + settabsskin(ta1,ftabbar.svtabhorz); + end; + end; + setstepbuttonskin(ta1.frame,fstepbutton); +end; + +procedure tskincontroller.handletabpage(const ainfo: skininfoty); +var + intf1: itabpage; + font1: tfont; +begin + handlewidget(ainfo); + setwidgetskin(twidget(ainfo.instance),ftabpage.svwidget); + if {((ftabpage.svcolortab <> cl_default) or + (ftabpage.svcoloractivetab <> cl_default)) and} + twidget(ainfo.instance).getcorbainterface(typeinfo(itabpage), + intf1) then begin + if (ftabpage.svcolortab <> cl_default) and + (intf1.getcolortab = cl_default) then begin + intf1.setcolortab(ftabpage.svcolortab); + end; + if (ftabpage.svcoloractivetab <> cl_default) and + (intf1.getcoloractivetab = cl_default) then begin + intf1.setcoloractivetab(ftabpage.svcoloractivetab); + end; + if (ftabpage.svfacetab <> nil) and (intf1.getfacetab() = nil) then begin + intf1.setfacetab(ftabpage.svfacetab); + end; + if (ftabpage.svfaceactivetab <> nil) and + (intf1.getfaceactivetab() = nil) then begin + intf1.setfaceactivetab(ftabpage.svfaceactivetab); + end; + if (ftabpage.svfonttab <> nil) then begin + font1:= intf1.getfonttab(); + if font1 = nil then begin + intf1.setfonttab(tfont(pointer(1))); //create font + font1:= intf1.getfonttab(); + end; + if font1.template = nil then begin + font1.template:= ftabpage.svfonttab; + end; + end; + if (ftabpage.svfontactivetab <> nil) then begin + font1:= intf1.getfontactivetab(); + if font1 = nil then begin + intf1.setfontactivetab(tfont(pointer(1))); //create font + font1:= intf1.getfontactivetab(); + end; + if font1.template = nil then begin + font1.template:= ftabpage.svfontactivetab; + end; + end; + end; +end; + +procedure tskincontroller.handletoolbar(const ainfo: skininfoty); +var + tb1: tcustomtoolbar; +begin + handlewidget(ainfo); + tb1:= tcustomtoolbar(ainfo.instance); + if ftoolbar_horz.svbuttonframesep <> nil then begin + with tb1.buttons do begin + createframesephorz(); + setframetemplate(ftoolbar_horz.svbuttonframesep,framesephorz); + end; + end; + if ftoolbar_vert.svbuttonframesep <> nil then begin + with tb1.buttons do begin + createframesepvert(); + setframetemplate(ftoolbar_vert.svbuttonframesep,framesepvert); + end; + end; + if tb1.width >= tb1.height then begin + setwidgetskin(tb1,ftoolbar_horz.svwidget); + setstepbuttonskin(tb1.frame,fstepbutton); + if ftoolbar_horz.svbuttonface <> nil then begin + with tb1.buttons do begin + createface(); + setfacetemplate(ftoolbar_horz.svbuttonface,face); + end; + end; + if ftoolbar_horz.svbuttonfacechecked <> nil then begin + with tb1.buttons do begin + createfacechecked(); + setfacetemplate(ftoolbar_horz.svbuttonfacechecked,facechecked); + end; + end; + if ftoolbar_horz.svbuttonframe <> nil then begin + with tb1.buttons do begin + createframe(); + setframetemplate(ftoolbar_horz.svbuttonframe,frame); + end; + end; + if ftoolbar_horz.svbuttonframechecked <> nil then begin + with tb1.buttons do begin + createframechecked(); + setframetemplate(ftoolbar_horz.svbuttonframechecked,framechecked); + end; + end; + end + else begin + setwidgetskin(tb1,ftoolbar_vert.svwidget); + setstepbuttonskin(tb1.frame,fstepbutton); + if ftoolbar_vert.svbuttonface <> nil then begin + with tb1.buttons do begin + createface(); + setfacetemplate(ftoolbar_vert.svbuttonface,face); + end; + end; + if ftoolbar_vert.svbuttonfacechecked <> nil then begin + with tb1.buttons do begin + createfacechecked(); + setfacetemplate(ftoolbar_vert.svbuttonfacechecked,facechecked); + end; + end; + if ftoolbar_vert.svbuttonframe <> nil then begin + with tb1.buttons do begin + createframe(); + setframetemplate(ftoolbar_vert.svbuttonframe,frame); + end; + end; + if ftoolbar_vert.svbuttonframechecked <> nil then begin + with tb1.buttons do begin + createframechecked(); + setframetemplate(ftoolbar_vert.svbuttonframechecked,framechecked); + end; + end; + end; +end; + +procedure tskincontroller.handlesplitter(const ainfo: skininfoty); +begin + handlewidget(ainfo,@fsplitter.svcolor); + setwidgetskin(twidget(ainfo.instance),fsplitter.svwidget); + with fsplitter,tcustomsplitter(ainfo.instance) do begin + if (svcolorgrip <> cl_default) and (colorgrip = cl_default) then begin + colorgrip:= svcolorgrip; + end; + if (svgrip <> stb_default) and (grip = stb_default) then begin + grip:= svgrip; + end; + end; +end; + +procedure tskincontroller.handledispwidget(const ainfo: skininfoty); +begin + handlewidget(ainfo,@fdispwidget.svcolor); + setwidgetskin(twidget(ainfo.instance),fdispwidget.svwidget); +end; + +procedure tskincontroller.handleedit(const ainfo: skininfoty); +begin + handlewidget(ainfo); + seteditskin(tcustomedit(ainfo.instance),fedit); +end; + +procedure tskincontroller.handledataedit(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setdataeditskin(tdataedit(ainfo.instance),fdataedit); +end; + +procedure tskincontroller.handlebooleanedit(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setwidgetskin(twidget(ainfo.instance),fbooleanedit.svgraphdataedit.svwidget); + with tcustombooleanedit(ainfo.instance) do begin + if not (osk_nooptions in optionsskin) then begin + if fbooleanedit.svoptionsadd <> [] then begin + options:= options + fbooleanedit.svoptionsadd; + end; + if fbooleanedit.svoptionsremove <> [] then begin + options:= options - fbooleanedit.svoptionsremove; + end; + end; + end; +// setgraphdataeditskin(tgraphdataedit(ainfo.instance),fbooleanedit); +end; + +procedure tskincontroller.handlemainmenu(const ainfo: skininfoty); +begin + setmainmenuskin(tcustommainmenu(ainfo.instance),fmainmenu); +end; + +procedure tskincontroller.handlepopupmenu(const ainfo: skininfoty); +begin + setpopupmenuskin(tpopupmenu(ainfo.instance),fpopupmenu); +end; + +procedure tskincontroller.handlemainmenuwidget(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setwidgetskin(twidget(ainfo.instance),fmainmenuwidget.svwidget); + setmainmenuskin(tmainmenuwidget(ainfo.instance).menu,fmainmenuwidget.svmenu); +end; + +procedure tskincontroller.handlegrid(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setgridskin(tcustomgrid(ainfo.instance),fgrid); +end; + +{ tskinfontalias } + +constructor tskinfontalias.create(aowner: tobject); +begin + fmode:= fam_overwrite; + fxscale:= 1; + inherited; +end; + +procedure tskinfontalias.settemplate(const avalue: tfontcomp); +begin + tcustomskincontroller(fowner).setlinkedvar(avalue,tmsecomponent(ftemplate)); +end; + +{ tskinextender } + +destructor tskinextender.destroy; +begin + master:= nil; //unlink + inherited; +end; + +procedure tskinextender.setmaster(const avalue: tcustomskincontroller); +begin + if fmaster <> nil then begin + fmaster.unregisterextender(self); + end; + setlinkedvar(avalue,tmsecomponent(fmaster)); + if avalue <> nil then begin + avalue.registerextender(self); + end; +end; + +procedure tskinextender.doactivate; +begin + //dummy +end; + +procedure tskinextender.dodeactivate; +begin + //dummy +end; + +procedure tskinextender.updateskin(const ainfo: skininfoty; + var handled: boolean); +begin + //dummy +end; + +procedure tskinextender.removeskin(const ainfo: skininfoty; + var handled: boolean); +begin + //dummy +end; + +{ tskinfont } +(* +constructor tskinfont.create; +begin +{ + fcolor:= cl_default; + fcolorbackground:= cl_default; + fshadow_color:= cl_default; + fshadow_shiftx:= 1; + fshadow_shifty:= 1; + fgloss_color:= cl_default; + fgloss_shiftx:= -1; + fgloss_shifty:= -1; + fgrayed_color:= cl_default; + fgrayed_colorshadow:= cl_default; + fgrayed_shiftx:= 1; + fgrayed_shifty:= 1; +} +end; +*) +procedure tskinfont.updatefont(const adest: tfont); +begin + if ftemplate <> nil then begin + with adest do begin + if template = nil then begin + template:= ftemplate; + end; + { + if fcolor <> cl_default then begin + color:= fcolor; + end; + if fcolorbackground <> cl_default then begin + colorbackground:= fcolorbackground; + end; + if fshadow_color <> cl_default then begin + shadow_color:= fshadow_color; + end; + if fshadow_shiftx <> 1 then begin + shadow_shiftx:= fshadow_shiftx; + end; + if fshadow_shifty <> 1 then begin + shadow_shifty:= fshadow_shifty; + end; + if fgloss_color <> cl_default then begin + gloss_color:= fgloss_color; + end; + if fgloss_shiftx <> -1 then begin + gloss_shiftx:= fgloss_shiftx; + end; + if fgloss_shifty <> -1 then begin + gloss_shifty:= fgloss_shifty; + end; + if fgrayed_color <> cl_default then begin + grayed_color:= fgrayed_color; + end; + if fgrayed_colorshadow <> cl_default then begin + grayed_colorshadow:= fgrayed_colorshadow; + end; + if fgrayed_shiftx <> 1 then begin + grayed_shiftx:= fgrayed_shiftx; + end; + if fgrayed_shifty <> 1 then begin + grayed_shifty:= fgrayed_shifty; + end; + if fextraspace <> 0 then begin + extraspace:= extraspace; + end; + if fstyle <> [] then begin + style:= fstyle; + end; + } + end; + end; +end; + +procedure tskinfont.settemplate(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(ftemplate)); +end; + +{ tskinhandler } + +procedure tskinhandler.updateskin1(const ainfo: skininfoty; + const controllerar: skincontrollerarty); +var + int1,int2: integer; +begin + for int1:= 0 to high(controllerar) do begin + if controllerar[int1].fgroupinfo = nil then begin + controllerar[int1].updateskin(ainfo); + end + else begin + for int2:= 0 to high(controllerar[int1].fgroupinfo) do begin + with controllerar[int1].fgroupinfo[int2] do begin + if (ainfo.group >= min) and (ainfo.group <= max) then begin + controllerar[int1].updateskin(ainfo); + break; + end; + end; + end; + end; + end; +end; +{ +procedure tskinhandler.removeskin1(const ainfo: skininfoty; + const controllerar: skincontrollerarty); +var + int1,int2: integer; +begin + for int1:= 0 to high(controllerar) do begin + if controllerar[int1].fgroupinfo = nil then begin + controllerar[int1].removeskin(ainfo); + end + else begin + for int2:= 0 to high(controllerar[int1].fgroupinfo) do begin + with controllerar[int1].fgroupinfo[int2] do begin + if (ainfo.group >= min) and (ainfo.group <= max) then begin + controllerar[int1].removeskin(ainfo); + break; + end; + end; + end; + end; + end; +end; +} +procedure tskinhandler.updateskin(const ainfo: skininfoty); +begin + updateskin1(ainfo,factiveskincontroller); +end; +{ +procedure tskinhandler.removeskin(const ainfo: skininfoty); +begin + removeskin1(ainfo,factiveskincontroller); +end; +} +function comparecontroller(const l,r): integer; +begin + result:= tcustomskincontroller(r).order-tcustomskincontroller(l).order; +end; + +procedure tskinhandler.setactive(const sender: tcustomskincontroller; + var controllerar: skincontrollerarty; + const handleproc: skineventty; var handlevar: skineventty{; + const removeproc: skineventty; var removevar: skineventty}); +begin + with sender do begin + if fisactive then begin + adduniqueitem(pointerarty(controllerar),sender); + sortarray(pointerarty(controllerar),@comparecontroller) + end + else begin + removeitem(pointerarty(controllerar),sender); + end; + if controllerar <> nil then begin + handlevar:= handleproc; +// removevar:= removeproc; + end + else begin + handlevar:= nil; +// removevar:= nil; + end; + end; +end; + +procedure tskinhandler.updateactive(const sender: tcustomskincontroller); +begin + setactive(sender,factiveskincontroller, + {$ifdef FPC}@{$endif}updateskin,oninitskinobject{, + @removeskin,onremoveskinobject}); +end; + +procedure tskinhandler.doactivate(const sender: tcustomskincontroller); +begin + //dummy +end; + +procedure tskinhandler.dodeactivate(const sender: tcustomskincontroller); +begin + //dummy +end; + +initialization + setskinhandler(tskinhandler.create); +finalization + freeandnil(fhandler); +end. diff --git a/mseide-msegui/lib/common/kernel/msesocketintf.inc b/mseide-msegui/lib/common/kernel/msesocketintf.inc new file mode 100644 index 0000000..4c7b6b6 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesocketintf.inc @@ -0,0 +1,49 @@ +{ MSEgui Copyright (c) 1999-2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +function soc_getaddrerrortext(aerror: integer): string; +function soc_geterrortext(aerror: integer): string; + +function soc_open(const kind: socketkindty; const nonblock: boolean; + out handle: integer): syserrorty; +function soc_shutdown(const handle: integer; + const kind: socketshutdownkindty): syserrorty; +function soc_close(const handle: integer): syserrorty; +function soc_connect(const handle: integer; + const addr: socketaddrty; const timeoutms: integer): syserrorty; +function soc_bind(const handle: integer; + const addr: socketaddrty): syserrorty; +function soc_listen(const handle: integer; + const maxconnections: integer): syserrorty; +function soc_accept(const handle: integer; const nonblock: boolean; out conn: integer; + out addr: socketaddrty; const timeoutms: integer): syserrorty; +function soc_urltoaddr(var addr: socketaddrty): syserrorty; +function soc_getaddr(const addr: socketaddrty): string; + //address bytes +function soc_getport(const addr: socketaddrty): integer; +function soc_setnonblock(const handle: integer; + const nonblock: boolean): syserrorty; +function soc_read(const fd: longint; const buf: pointer; + const nbytes: longword; out readbytes: integer; + const timeoutms: integer): syserrorty; + //atimeoutms < 0 -> nonblocked, + //result = 0 -> no data, < 0 - error +function soc_write(const fd: longint; buf: pointer; + nbytes: longword; out writebytes: integer; + const timeoutms: integer): syserrorty; +function soc_setrxtimeout(const handle: integer; const ms: integer): syserrorty; +function soc_settxtimeout(const handle: integer; const ms: integer): syserrorty; + +function soc_poll(const handle: integer; const kind: pollkindsty; + const timeoutms: longword; + out pollres: pollkindsty): syserrorty; + //0 -> no timeout + //for blocking mode + + diff --git a/mseide-msegui/lib/common/kernel/msesonames.pas b/mseide-msegui/lib/common/kernel/msesonames.pas new file mode 100644 index 0000000..f54ff21 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesonames.pas @@ -0,0 +1,50 @@ +{ MSEgui Copyright (c) 2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesonames; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes; +{$ifdef mswindows} +//const +// sqlite3lib: array[0..0] of filenamety = ('sqlite3.dll'); +// postgreslib: array[0..0] of filenamety = ('libpq.dll'); +// mysqllib: array[0..0] of filenamety = ('libmysql.dll'); +// sslnames: array[0..1] of filenamety = ('ssleay32.dll','libssl32.dll'); +// sslutilnames: array[0..0] of filenamety = ('libeay32.dll'); +// fbembedlib: array[0..0] of filenamety = ('fbembed.dll'); +// fbcgdslib: array[0..1] of filenamety = ('fbclient.dll','gds32.dll'); +{$else} +const + xrendernames: array[0..1] of filenamety = ('libXrender.so.1','libXrender.so'); + xrandrnames: array[0..1] of filenamety = ('libXrandr.so.2','libXrandr.so'); + xftnames: array[0..1] of filenamety = ('libXft.so.2','libXft.so'); + icenames: array[0..1] of filenamety = ('libICE.so.6','libICE.so'); + smnames: array[0..1] of filenamety = ('libSM.so.6','libSM.so'); + +// sqlite3lib: array[0..1] of filenamety = ('libsqlite3.so.0','libsqlite3.so'); +// postgreslib: array[0..2] of filenamety = ('libpq.so.5.1','libpq.so.5','libpq.so'); +// mysqllib: array[0..2] of filenamety = ('libmysqlclient.so.16', +// 'libmysqlclient.so.15','libmysqlclient.so'); +// sslnames: array[0..4] of filenamety = ( +// 'libssl.so.1.0.0','libssl.so.0.9.8','libssl.so.0.9.7','libssl.so.0.9.6', +// 'libssl.so'); +// sslutilnames: array[0..4] of filenamety = ( +// 'libcrypto.so.1.0.0','libcrypto.so.0.9.8','libcrypto.so.0.9.7','libcrypto.so.0.9.6', +// 'libcrypto.so'); +// fbembedlib: array[0..2] of filenamety = ('libfbembed.so.2','libfbembed.so.1', +// 'libfbembed.so'); +// fbcgdslib: array[0..3] of filenamety = ('libfbclient.so.2','libfbclient.so.1', +// 'libfbclient.so','libgds.so'); +{$endif} + +implementation + +end. diff --git a/mseide-msegui/lib/common/kernel/msestat.pas b/mseide-msegui/lib/common/kernel/msestat.pas new file mode 100644 index 0000000..6ad8842 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestat.pas @@ -0,0 +1,2054 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestat; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,mselist,msestream,mseglob,msereal,msetypes, + msestrings,mseinterfaces, + msehash,msedatalist,msesys,mseeditglob; + +const + defaultstatfilename = 'status.sta'; +type + tstatreader = class; + tstatwriter = class; + + statreadeventty = procedure (const reader: tstatreader) of object; + statwriteeventty = procedure (const writer: tstatwriter) of object; + + istatfile = interface(iobjectlink)[miid_istatfile] + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + end; + + istatupdatevalue = interface(inullinterface) + procedure statreadvalue(const aname: msestring; const reader: tstatreader); + procedure statwritevalue(const aname: msestring; const writer: tstatwriter); + end; + statfileroptionty = (sfro_nodata,sfro_nooptions,sfro_nostate); + statfileroptionsty = set of statfileroptionty; + + tstatfiler = class + private + fstream: ttextstream; + fownsstream: boolean; + fiswriter: boolean; + flistlevel: integer; + foptions: statfileroptionsty; + protected + fcurrentsection: msestring; + public + constructor create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); + destructor destroy; override; + function varname(const intf: istatfile): msestring; + function arrayname(const name: msestring; index: integer): msestring; + function iswriter: boolean; + property stream: ttextstream read fstream; + + procedure setsection(const name: msestring); + property currentsection: msestring read fcurrentsection; + procedure updatevalue(const name: msestring; var value: boolean); overload; + procedure updatevalue(const name: msestring; var value: byte); overload; + procedure updatevalue(const name: msestring; var value: word); overload; + procedure updatevalue(const name: msestring; var value: integer; + const min: integer = -(maxint)-1; const max: integer = maxint); overload; + procedure updatevalue(const name: msestring; var value: real; + const min: real = -bigreal; const max: real = bigreal); overload; + procedure updatevalue(const name: msestring; var value: string); overload; + procedure updatebinaryvalue(const name: msestring; var value: string); + procedure updatevalue(const name: msestring; var value: msestring); overload; + procedure updatevalue(const name: msestring; var value: tdatalist); overload; + procedure updatevalue(const name: msestring; var value: stringarty); overload; + procedure updatevalue(const name: msestring; var value: msestringarty); overload; + procedure updatevalue(const name: msestring; var value: longboolarty); overload; + procedure updatevalue(const name: msestring; var value: integerarty); overload; + procedure updatevalue(const name: msestring; var value: int64arty); overload; + procedure updatevalue(const name: msestring; var value: realarty); overload; + procedure updatevalue(const name: msestring; var value: complexarty); overload; + + procedure updatevalue(const name: msestring; const intf: istatupdatevalue); overload; + procedure updatestat(const intf: istatfile); + procedure updatememorystatstream(const name: msestring; const streamname: msestring); + function beginlist(const name: msestring = ''): boolean; virtual; abstract; + function endlist: boolean; virtual; abstract; + property options: statfileroptionsty read foptions write foptions; + function candata: boolean; + function canstate: boolean; + function canoptions: boolean; + end; + + sectionty = record + fileposition: integer; + names: tpointermsestringhashdatalist; + count: integer; + values: msestringarty; + end; + psectionty = ^sectionty; + sectionarty = array of sectionty; + + recsetcounteventty = procedure(const acount: integer) of object; + recsetcountevent1ty = procedure(const acount: integer); + recstoreeventty = procedure(const aindex: integer; const avalue: msestring) of object; + recstoreevent1ty = procedure(const aindex: integer; const avalue: msestring); + + tstatreader = class(tstatfiler) + private + fsectionlist: tpointermsestringhashdatalist; + fsections: sectionarty; + fsectioncount: integer; + factsection: psectionty; + factitem: integer; + fliststart: integerarty; + fstatend: integer; + procedure checkrealrange(var value: realty; const min,max: realty); + procedure checkintegerrange(var value: integer; const min,max: integer); + procedure checkint64range(var value: int64; const min,max: int64); + protected + procedure readdata; + function findvar(const name: msestring; var value: msestring): boolean; + overload; //true if ok + function findvar(const name: msestring; var value: msestring; + out isarray: boolean): boolean; overload; //true if ok + public + constructor create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); overload; + constructor create(const filename: filenamety; + const aencoding: charencodingty = ce_utf8); overload; + destructor destroy; override; + function sections: msestringarty; + function hassection(const name: msestring): boolean; //true if found + function findsection(const name: msestring): boolean; + //switch section, true if found + function checkvar(const name: msestring): boolean; //true if found + function streamdata: string; //returns data after [-] + function streamtext: msestring; //returns text after [-] + + function readboolean(const name: msestring; const default: boolean = false): boolean; + function readbyte(const name: msestring; const default: byte = 0): byte; + function readword(const name: msestring; const default: word = 0): word; + function readinteger(const name: msestring; const default: integer = 0; + const min: integer = -(maxint)-1; const max: integer = maxint): integer; + function readint64(const name: msestring; const default: int64 = 0; + const min: int64 = -(maxint64)-1; const max: int64 = maxint64): int64; + function readreal(const name: msestring; const default: real = 0; + const min: real = -bigreal; const max: real = bigreal; + const acceptempty: boolean = false): realty; + function readstring(const name: msestring; const default: string): string; + function readbinarystring(const name: msestring; const default: string): string; + function readmsestring(const name: msestring; const default: msestring): msestring; + procedure readdatalist(const name: msestring; const value: tdatalist); + function readarray(const name: msestring; const default: stringarty): stringarty; overload; + function readarray(const name: msestring; const default: msestringarty): msestringarty; overload; + function readarray(const name: msestring; const default: widestringarty): widestringarty; overload; + function readarray(const name: msestring; const default: integerarty): integerarty; overload; + function readarray(const name: msestring; const default: int64arty): int64arty; overload; + function readarray(const name: msestring; const default: booleanarty): booleanarty; overload; + function readarray(const name: msestring; const default: longboolarty): longboolarty; overload; + function readarray(const name: msestring; + const default: realarty): realarty; overload; + function readarray(const name: msestring; + const default: complexarty): complexarty; overload; + function readlistitem: msestring; + + procedure readrecord(const name: msestring; const values: array of pointer; + const default: array of const); + procedure readrecordarray(const name: msestring; + setcount: recsetcounteventty; store: recstoreeventty); overload; + procedure readrecordarray(const name: msestring; + setcount: recsetcountevent1ty; store: recstoreevent1ty); overload; + //setcount(0) on error + function beginlist(const name: msestring = ''): boolean; override; + function endlist: boolean; override; + + procedure readvalue(const name: msestring; const intf: istatupdatevalue); + procedure readstat(const intf: istatfile); + procedure readmemorystatstream(const name: msestring; const streamname: msestring); + end; + + recgetrecordeventty = function(const index: integer): msestring of object; + recgetrecordevent1ty = function(const index: integer): msestring; + + tstatwriter = class(tstatfiler) + protected + procedure writeval(const name: msestring; const avalue: msestring); + procedure writemultival(const name: msestring; const avalue: msestring); + procedure writemultilistval(const avalue: msestring); + procedure writelistval(const avalue: msestring); + public + constructor create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); overload; + constructor create(const filename: filenamety; + const aencoding: charencodingty = ce_utf8; + const atransaction: boolean = true); overload; + + procedure writesection(const name: msestring); + procedure writeboolean(const name: msestring; const value: boolean); + procedure writebyte(const name: msestring; const value: byte); + procedure writeword(const name: msestring; const value: word); + procedure writeinteger(const name: msestring; const value: integer); + procedure writeint64(const name: msestring; const value: int64); + procedure writereal(const name: msestring; const value: real); + procedure writestring(const name: msestring; const value: string); + procedure writebinarystring(const name: msestring; const value: string); + procedure writemsestring(const name: msestring; const value: msestring); +// procedure writemsestrings(const name: msestring; const value: msestring); +// //handles linebreaks, 'ar' is multiline name extension + procedure writedatalist(const name: msestring; const value: tdatalist); + procedure writearray(const name: msestring; const value: stringarty); overload; + procedure writearray(const name: msestring; const value: msestringarty); overload; + procedure writearray(const name: msestring; const value: integerarty); overload; + procedure writearray(const name: msestring; const value: int64arty); overload; + procedure writearray(const name: msestring; const value: booleanarty); overload; + procedure writearray(const name: msestring; const value: longboolarty); overload; + procedure writearray(const name: msestring; const value: realarty); overload; + procedure writearray(const name: msestring; const value: complexarty); overload; + + procedure writelistitem(const value: msestring); overload; + procedure writelistitem(const value: integer); overload; + procedure writelistitem(const value: realty); overload; + procedure writelistitem(const value: complexty); overload; + + procedure writerecord(const name: msestring; const values: array of const); + procedure writerecordarray(const name: msestring; const count: integer; + get: recgetrecordeventty); overload; + procedure writerecordarray(const name: msestring; const count: integer; + get: recgetrecordevent1ty); overload; + function beginlist(const name: msestring = ''): boolean; override; + function endlist: boolean; override; + + procedure writevalue(const name: msestring; const intf: istatupdatevalue); + procedure writestat(const intf: istatfile); + procedure writememorystatstream(const name: msestring; + const streamname: msestring); + procedure streamdata(const adata: string); + procedure streamtext(const atext: msestring); + end; + + tmemorytextstream = class; + + streaminfoty = record + name: msestring; + data: pointer; + size: integer; + stream: tmemorytextstream; + end; + + tmemorystreams = class; + + tmemorytextstream = class(ttextstream) + private + fname: msestring; + fowner: tmemorystreams; +// findex: integer; + public + constructor create(aowner: tmemorystreams; const name: msestring; + const aopenmode: fileopenmodety; var info: streaminfoty); reintroduce; + destructor destroy; override; + end; + + tmemorystreams = class + private + fstreams: array of streaminfoty; + function findname(const name: msestring): integer; + procedure internaldelete(index: integer); + public + destructor destroy; override; + function open(const streamname: msestring; + const aopenmode: fileopenmodety): ttextstream; + procedure delete(const name: msestring); + function findfiles(const aname: msestring): msestringarty; + end; + +procedure deletememorystatstream(const streamname: msestring); +function memorystatstreams: tmemorystreams; + +function canstatvalue(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; +function canstatstate(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; +function canstatoptions(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; + +procedure readstringar(const reader: treader; out avalue: stringarty); +procedure writestringar(const writer: twriter; const avalue: stringarty); + +function writestat(const asource: array of statwriteeventty; + const section: msestring): string; +procedure readstat(const adest: array of statreadeventty; + const atext: string; const section: msestring); +implementation +uses + sysutils,mseformatstr,msefileutils,msearrayutils,msesystypes; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdatalist1 = class(tdatalist); + tmemorystreamcracker = class(tcustommemorystream) + private + fcapacity: longint; + end; + +procedure readstringar(const reader: treader; out avalue: stringarty); +var + int1: integer; +begin + reader.readlistbegin; + int1:= 0; + while not reader.endoflist do begin + additem(avalue,reader.readstring,int1); + end; + reader.readlistend; + setlength(avalue,int1); +end; + +procedure writestringar(const writer: twriter; const avalue: stringarty); +var + int1: integer; +begin + writer.writelistbegin; + for int1:= 0 to high(avalue) do begin + writer.writestring(avalue[int1]); + end; + writer.writelistend; +end; + +function writestat(const asource: array of statwriteeventty; + const section: msestring): string; +var + stream1: ttextstringbufferstream; + writer1: tstatwriter = nil; + int1: integer; +begin + stream1:= ttextstringbufferstream.create(''); + try + writer1:= tstatwriter.create(stream1); + writer1.setsection(section); + for int1:= 0 to high(asource) do begin + asource[int1](writer1); + end; + result:= stream1.data; + finally + stream1.destroy(); + writer1.free(); + end; +end; + +procedure readstat(const adest: array of statreadeventty;const atext: string; + const section: msestring); +var + stream1: ttextstringbufferstream; + reader1: tstatreader = nil; + int1: integer; +begin + stream1:= ttextstringbufferstream.create(atext); + try + reader1:= tstatreader.create(stream1); + reader1.setsection(section); + for int1:= 0 to high(adest) do begin + adest[int1](reader1); + end; + finally + stream1.destroy(); + reader1.free(); + end; +end; + +function canstatvalue(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; +begin + result:= (oe1_savevalue in editoptions) and stat.candata; +end; + +function canstatstate(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; +begin + result:= (oe1_savestate in editoptions) and stat.canstate; +end; + +function canstatoptions(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; +begin + result:= (oe1_saveoptions in editoptions) and stat.canoptions; +end; + +var + fmemorystatstreams: tmemorystreams; + +function memorystatstreams: tmemorystreams; +begin + if fmemorystatstreams = nil then begin + fmemorystatstreams:= tmemorystreams.create; + end; + result:= fmemorystatstreams; +end; + +procedure deletememorystatstream(const streamname: msestring); +begin + if fmemorystatstreams <> nil then begin + fmemorystatstreams.delete(streamname); + end; +end; + +{ tstatfiler } + +constructor tstatfiler.create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); +begin + fstream:= astream; + if fstream <> nil then begin + fstream.encoding:= aencoding; + end; +end; + +function tstatfiler.arrayname(const name: msestring; index: integer): msestring; +begin + result:= name + '_'+inttostrmse(index); +end; + +destructor tstatfiler.destroy; +begin + if fownsstream then begin + fstream.free; + end; + inherited; +end; + +function tstatfiler.iswriter: boolean; +begin + result:= fiswriter; +end; + +procedure tstatfiler.setsection(const name: msestring); +begin + if fiswriter then begin + tstatwriter(self).writesection(name); + end + else begin + tstatreader(self).findsection(name); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: boolean); +begin + if fiswriter then begin + tstatwriter(self).writeboolean(name,value); + end + else begin + value:= tstatreader(self).readboolean(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: byte); +begin + if fiswriter then begin + tstatwriter(self).writebyte(name,value); + end + else begin + value:= tstatreader(self).readbyte(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: word); +begin + if fiswriter then begin + tstatwriter(self).writeword(name,value); + end + else begin + value:= tstatreader(self).readword(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: tdatalist); +begin + if fiswriter then begin + tstatwriter(self).writedatalist(name,value); + end + else begin + tstatreader(self).readdatalist(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: integer; const min, max: integer); +begin + if fiswriter then begin + tstatwriter(self).writeinteger(name,value); + end + else begin + value:= tstatreader(self).readinteger(name,value,min,max); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: real; const min, max: real); +begin + if fiswriter then begin + tstatwriter(self).writereal(name,value); + end + else begin + value:= tstatreader(self).readreal(name,value,min,max); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: integerarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: int64arty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: longboolarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: realarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: complexarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: stringarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: msestringarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: string); +begin + if fiswriter then begin + tstatwriter(self).writestring(name,value); + end + else begin + value:= tstatreader(self).readstring(name,value); + end; +end; + +procedure tstatfiler.updatebinaryvalue(const name: msestring; var value: string); +begin + if fiswriter then begin + tstatwriter(self).writebinarystring(name,value); + end + else begin + value:= tstatreader(self).readbinarystring(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: msestring); +begin + if fiswriter then begin + tstatwriter(self).writemsestring(name,value); + end + else begin + value:= tstatreader(self).readmsestring(name,value); + end; +end; + +procedure tstatfiler.updatestat(const intf: istatfile); +begin + if fiswriter then begin + tstatwriter(self).writestat(intf); + end + else begin + intf.statreading; + try + tstatreader(self).readstat(intf); + finally + intf.statread; + end; + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; const intf: istatupdatevalue); +begin + if fiswriter then begin + tstatwriter(self).writevalue(name,intf); + end + else begin + tstatreader(self).readvalue(name,intf); + end; +end; + +procedure tstatfiler.updatememorystatstream(const name: msestring; const streamname: msestring); +begin + if iswriter then begin + tstatwriter(self).writememorystatstream(name,streamname); + end + else begin + tstatreader(self).readmemorystatstream(name,streamname); + end; +end; +{ +procedure tstatfiler.updatestatfile(const name: msestring; const statfile: tstatfile); +begin + if iswriter then begin + tstatwriter(self).writestatfile(name,statfile); + end + else begin + tstatreader(self).readstatfile(name,statfile); + end; +end; +} +function tstatfiler.varname(const intf: istatfile): msestring; +begin + result:= intf.getstatvarname; + if result = '' then begin + result:= msestring(ownernamepath(tcomponent(intf.getinstance))); + end; +end; + +function tstatfiler.candata: boolean; +begin + result:= not (sfro_nodata in foptions); +end; + +function tstatfiler.canstate: boolean; +begin + result:= not (sfro_nostate in foptions); +end; + +function tstatfiler.canoptions: boolean; +begin + result:= not (sfro_nooptions in foptions); +end; + +{ tstatreader } + +constructor tstatreader.create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); +begin + inherited; + fsectionlist:= tpointermsestringhashdatalist.create; + readdata; +end; + +constructor tstatreader.create(const filename: filenamety; + const aencoding: charencodingty = ce_utf8); +var + stream1: ttextstream; +begin + fownsstream:= true; + stream1:= ttextstream.Create(filename,fm_read); +// stream1.encoding:= aencoding; + create(stream1,aencoding); +end; + +destructor tstatreader.destroy; +var + int1: integer; +begin + inherited; + for int1:= 0 to fsectioncount - 1 do begin + fsections[int1].names.Free; + end; + fsectionlist.Free; +end; + +procedure tstatreader.readdata; +var + str1: msestring; + int1: integer; +begin + if fstream <> nil then begin + str1:= ''; + while not fstream.eof do begin + while not fstream.eof and not((length(str1) > 0) and (str1[1] = '[')) do begin + try + fstream.readln(str1); + except + on ecrashstatfile do begin + raise; + end; + else begin + exit; + end; + end; + end; + if not fstream.eof then begin + int1:= findchar(str1,msechar(']')); + if int1 > 0 then begin + if int1 = 2 then begin + fstatend:= fstream.position; + exit; + end; + if fsectioncount >= length(fsections) then begin + setlength(fsections,length(fsections)*2+16); + end; + inc(fsectioncount); + fsectionlist.add(copy(str1,2,int1-2),pointer(ptruint(fsectioncount))); + with fsections[fsectioncount-1] do begin + fileposition:= fstream.position; + names:= tpointermsestringhashdatalist.create; + count:= 0; + while fstream.readln(str1) do begin + if (length(str1) > 0) and (str1[1] = '[') then begin + break; + end; + if count >= length(values) then begin + setlength(values,length(values)+16); + end; + inc(count); + if (length(str1) > 0) and (str1[1] <> ' ') and (str1[1] <> '+') then begin + int1:= findchar(str1,msechar('=')); + if int1 > 0 then begin + names.add(copy(str1,1,int1-1),pointer(ptruint(count))); + values[count-1]:= copy(str1,int1+1,bigint); + end + else begin + values[count-1]:= str1; + end; + end + else begin + values[count-1]:= str1; + end; + end; + end; + end + else begin + str1:= ''; + end; + end; + end; + end; +end; + +function tstatreader.findvar(const name: msestring; + var value: msestring): boolean; +var + int1,int2,int3: integer; + ch1: msechar; +begin + if factsection <> nil then begin + with factsection^ do begin + if flistlevel = 0 then begin + factitem:= ptruint(names.find(name)); + if factitem = 0 then begin + result:= false; + end + else begin + dec(factitem); + value:= values[factitem]; + int1:= factitem+1; //check multiline + while (int1 <= high(values)) and (values[int1] <> '') and + (values[int1][1] = '+') do begin + value:= value+lineend+copy(values[int1],2,bigint); + inc(int1); + end; + result:= true; + end; + end + else begin + result:= false; + for int1:= fliststart[flistlevel] to high(values) do begin +// for int1:= fliststart[flistlevel] to high(values) do begin + if length(values[int1]) > flistlevel then begin + ch1:= values[int1][flistlevel+1]; + if ch1 = ')' then begin + break; + end; + if ch1 <> ' ' then begin + int2:= findchar(values[int1],msechar('=')); + if (int2 = flistlevel+length(name)+1) and + (msestrlcomp(pmsechar(values[int1])+flistlevel, + pmsechar(name),length(name)) = 0) then begin + factitem:= int1; + value:= copy(values[int1],int2+1,bigint); + int3:= int1+1; //check multiline + while (int3 <= high(values)) and (length(values[int1]) > flistlevel) and + (values[int3][flistlevel+1] = '+') do begin + value:= value+lineend+copy(values[int3],flistlevel+2,bigint); + inc(int3); + end; + result:= true; + break; + end; + end; + end; + end; + end; + end; + end + else begin + result:= false; + end; +end; + +function tstatreader.findvar(const name: msestring; var value: msestring; + out isarray: boolean): boolean; +begin + result:= findvar(name,value); + isarray:= false; + if result then begin + with factsection^ do begin + if (factitem < count - 1) and (length(values[factitem+1]) > flistlevel) and + (values[factitem+1][flistlevel+1] = ' ') then begin + isarray:= true; + end; + end; + end; +end; + +function tstatreader.checkvar(const name: msestring): boolean; +begin + result:= (factsection <> nil) and (factsection^.names.find(name) <> nil); +end; + +function tstatreader.readboolean(const name: msestring; const default: boolean = false): boolean; +begin + result:= readinteger(name,integer(default)) <> 0; +end; + +function tstatreader.readbyte(const name: msestring; const default: byte = 0): byte; +begin + result:= readinteger(name,default); +end; + +function tstatreader.readword(const name: msestring; const default: word = 0): word; +begin + result:= readinteger(name,default); +end; + +procedure tstatreader.checkintegerrange(var value: integer; const min,max: integer); +begin + if max < min then begin //unsigned + if longword(value) > longword(max) then begin + value:= max; + end + else begin + if longword(value) < longword(min) then begin + value:= min; + end; + end; + end + else begin + if value > max then begin + value:= max; + end + else begin + if value < min then begin + value:= min; + end; + end; + end; +end; + +procedure tstatreader.checkint64range(var value: int64; const min,max: int64); +begin + if max < min then begin //unsigned + {$ifdef FPC} + if qword(value) > qword(max) then begin + value:= max; + end + else begin + if qword(value) < qword(min) then begin + value:= min; + end; + end; + {$else} + //delphi has no unsigned 64 bit type + {$endif} + end + else begin + if value > max then begin + value:= max; + end + else begin + if value < min then begin + value:= min; + end; + end; + end; +end; + +function tstatreader.readinteger(const name: msestring; const default: integer = 0; + const min: integer = -(maxint)-1; const max: integer = maxint): integer; +var + str1: msestring; +begin + if not findvar(name,str1) then begin + result:= default; + end + else begin + if trystrtoint(str1,result) then begin + checkintegerrange(result,min,max); + end + else begin + result:= default; + end; + end; +end; + +function tstatreader.readint64(const name: msestring; const default: int64 = 0; + const min: int64 = -(maxint64)-1; const max: int64 = maxint64): int64; +var + str1: msestring; +begin + if not findvar(name,str1) then begin + result:= default; + end + else begin + if trystrtoint64(str1,result) then begin + checkint64range(result,min,max); + end + else begin + result:= default; + end; + end; +end; + +procedure tstatreader.checkrealrange(var value: realty; const min,max: realty); +begin + if cmprealty(value,max) > 0 then begin + value:= max; + end + else begin + if cmprealty(value,min) < 0 then begin + value:= min; + end; + end; +end; + +function tstatreader.readreal(const name: msestring; const default: real = 0; + const min: real = -bigreal; const max: real = bigreal; + const acceptempty: boolean = false): realty; +var + str1: msestring; +begin + if not findvar(name,str1) then begin + result:= default; + end + else begin + if (str1 = '') and acceptempty then begin + result:= emptyreal; + end + else begin + if trystrtorealtydot(str1,result) then begin + checkrealrange(result,min,max); + end + else begin + result:= default; + end; + end; + end; +end; + +function tstatreader.readstring(const name: msestring; const default: string): string; +var + str1: msestring; +begin + if not findvar(name,str1) then begin + result:= default; + end + else begin + result:= ansistring(str1); + end; +end; + +function tstatreader.readbinarystring(const name: msestring; + const default: string): string; +var + mstr1: msestring; +begin + if not findvar(name,mstr1) then begin + result:= default; + end + else begin + result:= decodebase64(ansistring(mstr1)); + end; +end; + +function tstatreader.readmsestring(const name: msestring; + const default: msestring): msestring; +begin + result:= ''; //compilerwarning + if not findvar(name,result) then begin + result:= default; + end; +end; +(* +function tstatreader.readmsestrings(const name: msestring; + const default: msestring): msestring; +var + ar1: msestringarty; +begin + ar1:= readarray(name+'ar',msestringarty(nil){ar1}); + if high(ar1) >= 0 then begin + result:= concatstrings(ar1,lineend); + end + else begin + result:= readmsestring(name,default); + end; +end; +*) +function tstatreader.readlistitem: msestring; +var + int1,int2: integer; + slen: integer; + po1: pmsecharaty; + bo1: boolean; +begin + result:= ''; + bo1:= false; + while factitem < factsection^.count - 1 do begin + po1:= pointer(factsection^.values[factitem+1]); + slen:= length(msestring(pointer(po1))); + if slen <= flistlevel then begin + exit; + end; + for int1:= 0 to flistlevel-1 do begin + if (po1^[int1] <> ' ') then begin + exit; + end; + end; + if po1^[flistlevel] = '+' then begin + result:= result+lineend; + end + else begin + if bo1 or (po1^[flistlevel] <> ' ') then begin + exit; + end; + end; + int2:= length(result); + int1:= slen-flistlevel-1; + setlength(result,int2+int1); + move(po1^[flistlevel+1],pmsecharaty(pointer(result))^[int2], + int1*sizeof(msechar)); + bo1:= true; + inc(factitem); + end; +end; + +procedure tstatreader.readdatalist(const name: msestring; + const value: tdatalist); +var + str1: msestring; + int1: integer; +begin + if findvar(name,str1) then begin + try + value.beginupdate; + try + if trystrtoint(str1,int1) then begin + tdatalist1(value).readstate(self,int1,name); + tdatalist1(value).readappendix(self,name); + end; + finally + value.endupdate; + end; + except + end; + end; +end; + +function tstatreader.hassection(const name: msestring): boolean; +begin + result:= fsectionlist.find(name) <> nil; +end; + +function tstatreader.findsection(const name: msestring): boolean; +var + int1: integer; +begin + flistlevel:= 0; + int1:= ptruint(fsectionlist.find(name)); + if int1 = 0 then begin + factsection:= nil; + fcurrentsection:= ''; + end + else begin + factsection:= @fsections[int1-1]; + fcurrentsection:= name; + end; + result:= int1 <> 0; +end; + +procedure tstatreader.readstat(const intf: istatfile); +begin + if intf <> nil then begin + findsection(varname(intf)); + intf.dostatread(self); + end; +end; + +procedure tstatreader.readvalue(const name: msestring; const intf: istatupdatevalue); +begin + if intf <> nil then begin + intf.statreadvalue(name,self); + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: msestringarty): msestringarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2)then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + result[int1]:= readlistitem; + end; + end + else begin + result:= default; + setlength(result,length(result)); + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: widestringarty): widestringarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + result[int1]:= readlistitem; + end; + end + else begin + result:= default; + setlength(result,length(result)); + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: stringarty): stringarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + result[int1]:= ansistring(readlistitem); + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: integerarty): integerarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not trystrtoint(readlistitem,result[int1]) then begin + result:= default; + break; + end; + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: int64arty): int64arty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not trystrtoint64(readlistitem,result[int1]) then begin + result:= default; + break; + end; + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: longboolarty): longboolarty; +var + str1: msestring; + int1,int2,int3: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not trystrtoint(readlistitem,int3) then begin + result:= default; + break; + end; + result[int1]:= longbool(int3); + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: booleanarty): booleanarty; +var + str1: msestring; + int1,int2,int3: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not trystrtoint(readlistitem,int3) then begin + result:= default; + break; + end; + result[int1]:= boolean(int3); + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: realarty): realarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not trystrtorealtydot(readlistitem,result[int1]) then begin + result:= default; + break; + end; + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: complexarty): complexarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not decoderecord( + readlistitem,[@result[int1].re,@result[int1].im],'rr') then begin + result:= default; + break; + end; + end; + end + else begin + result:= default; + end; +end; + +procedure tstatreader.readrecord(const name: msestring; const values: array of pointer; + const default: array of const); +var + str1: msestring; + str2: string; +begin + str2:= getrecordtypechars(default); + if length(str2) > length(values) then begin + setlength(str2,length(values)); + end; + if not findvar(name,str1) or not decoderecord(str1,values,str2) then begin + copyvariantarray(default,values); + end; +end; + +procedure tstatreader.readrecordarray(const name: msestring; + setcount: recsetcounteventty; store: recstoreeventty); +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + try + if assigned(setcount) then begin + setcount(int2); + end; + if assigned(store) then begin + for int1:= 0 to int2-1 do begin + store(int1,readlistitem); + end; + end; + except + if assigned(setcount) then begin + setcount(0); + end; + end; + end + else begin + if assigned(setcount) then begin + setcount(0); + end; + end; +end; + +procedure tstatreader.readrecordarray(const name: msestring; + setcount: recsetcountevent1ty; store: recstoreevent1ty); +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + try + if assigned(setcount) then begin + setcount(int2); + end; + if assigned(store) then begin + for int1:= 0 to int2-1 do begin + store(int1,readlistitem); + end; + end; + except + if assigned(setcount) then begin + setcount(0); + end; + end; + end + else begin + if assigned(setcount) then begin + setcount(0); + end; + end; +end; + +function tstatreader.beginlist(const name: msestring = ''): boolean; +var + str1: msestring; +begin + result:= false; + if factsection <> nil then begin + if (name <> '') and not findvar(name,str1) then begin + exit; + end; + inc(flistlevel); + inc(factitem); + with factsection^ do begin + if (high(values) >= factitem) and (length(values[factitem]) > flistlevel) and + (values[factitem][flistlevel+1] = '(') then begin + result:= true; + if high(fliststart) <= flistlevel then begin + setlength(fliststart,flistlevel+16); + end; + fliststart[flistlevel]:= factitem; + end + else begin + dec(flistlevel); + dec(factitem); + end; + end; + end; +end; + +function tstatreader.endlist: boolean; +var + int1: integer; +begin + result:= false; + if (factsection <> nil) and (flistlevel > 0) then begin + with factsection^ do begin + for int1:= fliststart[flistlevel] to high(values) do begin + if (length(values[int1]) > flistlevel) and + (values[int1][flistlevel+1] = ')') then begin + result:= true; + factitem:= int1; + break; + end; + end; + end; + dec(flistlevel); + end; +end; + +procedure tstatreader.readmemorystatstream(const name, streamname: msestring); +var + ar1: msestringarty; + stream1: ttextstream; +begin + ar1:= readarray(name,msestringarty(nil)); + if high(ar1) >= 0 then begin + stream1:= nil; + try + try + stream1:= memorystatstreams.open(streamname,fm_read); + stream1.encoding:= fstream.encoding; + stream1.size:= 0; + stream1.writemsestrings(ar1); + finally + stream1.Free; + end; + except + end; + end + else begin + memorystatstreams.delete(streamname); + end; +end; + +function tstatreader.sections: msestringarty; +var + int1: integer; +begin + setlength(result,fsectionlist.count); + for int1:= 0 to high(result) do begin + result[int1]:= fsectionlist.next^.data.key; + end; +end; + +function tstatreader.streamdata: string; +begin + result:= ''; + if fstatend > 0 then begin + fstream.position:= fstatend; + result:= fstream.readdatastring; + end; +end; + +function tstatreader.streamtext: msestring; +begin + result:= ''; + if fstatend > 0 then begin + fstream.position:= fstatend; + result:= fstream.readmsedatastring; + end; +end; + +{ +procedure tstatreader.readstatfile(const name: msestring; const statfile: tstatfile); +var + stream: ttextstream; + ar1: msestringarty; +begin + ar1:= readarray(name,msestringarty(nil)); + stream:= ttextstream.Create; + try + stream.writemsestrings(ar1); + stream.Position:= 0; + statfile.readstat(stream); + finally + stream.Free; + end; +end; +} +{ tstatwriter } + +constructor tstatwriter.create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); +begin + fiswriter:= true; + inherited; +end; + +constructor tstatwriter.create(const filename: filenamety; + const aencoding: charencodingty = ce_utf8; + const atransaction: boolean = true); +var + stream1: ttextstream; +begin + fownsstream:= true; + if atransaction then begin + stream1:= ttextstream.Createtransaction(filename); + end + else begin + stream1:= ttextstream.Create(filename,fm_create); + end; + create(stream1,aencoding); +end; + +procedure tstatwriter.writesection(const name: msestring); +begin + fcurrentsection:= name; + fstream.writeln(msestring('[')+name+msestring(']')); + flistlevel:= 0; +end; + +procedure tstatwriter.writestat(const intf: istatfile); +begin + if (intf <> nil) and (fstream <> nil) then begin + writesection(varname(intf)); + intf.dostatwrite(self); + end; +end; + +procedure tstatwriter.writevalue(const name: msestring; const intf: istatupdatevalue); +begin + if intf <> nil then begin + intf.statwritevalue(name,self); + end; +end; + +procedure tstatwriter.writeval(const name: msestring; const avalue: msestring); +begin + fstream.writeln(charstring(msechar(' '),flistlevel)+name+'='+avalue); +end; + +procedure tstatwriter.writemultival(const name: msestring; const avalue: msestring); +var + ar1: msestringarty; + int1: integer; +begin + if avalue = '' then begin + fstream.writeln(charstring(msechar(' '),flistlevel)+name+'='); + end + else begin + ar1:= breaklines(avalue); + fstream.writeln(charstring(msechar(' '),flistlevel)+name+'='+ar1[0]); + for int1:= 1 to high(ar1) do begin + fstream.writeln(charstring(msechar(' '),flistlevel)+'+'+ar1[int1]); + end; + end; +end; + +procedure tstatwriter.writeinteger(const name: msestring; const value: integer); +begin + writeval(name,inttostrmse(value)); +end; + +procedure tstatwriter.writeint64(const name: msestring; const value: int64); +begin + writeval(name,inttostrmse(value)); +end; + +procedure tstatwriter.writeboolean(const name: msestring; const value: boolean); +begin + writeinteger(name,integer(value)); +end; + +procedure tstatwriter.writebyte(const name: msestring; const value: byte); +begin + writeinteger(name,value); +end; + +procedure tstatwriter.writeword(const name: msestring; const value: word); +begin + writeinteger(name,value); +end; + +procedure tstatwriter.writereal(const name: msestring; const value: real); +begin + writeval(name,msestring(realtytostrdot(value))); +end; + +procedure tstatwriter.writestring(const name: msestring; const value: string); +begin + writeval(name,msestring(value)); +end; + +procedure tstatwriter.writebinarystring(const name: msestring; + const value: string); +begin + writemsestring(name,msestring(encodebase64(value,76))); +end; + +procedure tstatwriter.writemsestring(const name: msestring; + const value: msestring); +begin + writemultival(name,value); +end; +(* +procedure tstatwriter.writemsestrings(const name: msestring; + const value: msestring); +var + ar1: msestringarty; +begin + writemsestring(name,value); +{ + ar1:= breaklines(value); + if high(ar1) > 0 then begin + writearray(name+'ar',ar1); + end + else begin + writeval(name,value); + end; +} +end; +*) +procedure tstatwriter.writerecord(const name: msestring; + const values: array of const); +begin + writemsestring(name,encoderecord(values)); +end; + +procedure tstatwriter.writerecordarray(const name: msestring; const count: integer; + get: recgetrecordeventty); +var + int1: integer; +begin + writeinteger(name,count); + for int1:= 0 to count - 1 do begin + writelistval(get(int1)); + end; +end; + +procedure tstatwriter.writerecordarray(const name: msestring; const count: integer; + get: recgetrecordevent1ty); +var + int1: integer; +begin + writeinteger(name,count); + for int1:= 0 to count - 1 do begin + writelistval(get(int1)); + end; +end; + +procedure tstatwriter.writemultilistval(const avalue: msestring); +var + ar1: msestringarty; + int1: integer; +begin + ar1:= breaklines(avalue); + if ar1 <> nil then begin + fstream.writeln(charstring(msechar(' '),flistlevel+1)+ar1[0]); + for int1:= 1 to high(ar1) do begin + fstream.writeln(charstring(msechar(' '),flistlevel)+'+'+ar1[int1]); + end; + end; +end; + +procedure tstatwriter.writelistval(const avalue: msestring); +var + po1: pmsechar; +begin + po1:= pointer(avalue); + if po1 <> nil then begin + while (po1^ <> c_linefeed) and (po1^ <> #0) do begin + inc(po1); + end; + if po1^ <> #0 then begin + writemultilistval(avalue); + exit; + end; + end; + fstream.writeln(charstring(msechar(' '),flistlevel+1)+avalue) +end; + +procedure tstatwriter.writelistitem(const value: msestring); +begin + writelistval(value); +end; + +procedure tstatwriter.writelistitem(const value: integer); +begin + writelistval(inttostrmse(value)); +end; + +procedure tstatwriter.writelistitem(const value: realty); +begin + writelistval(msestring(realtytostrdot(value))); +end; + +procedure tstatwriter.writelistitem(const value: complexty); +begin + writelistval(encoderecord([value.re,value.im])); +end; + +procedure tstatwriter.writedatalist(const name: msestring; const value: tdatalist); +begin + tdatalist1(value).writestate(self,name); + tdatalist1(value).writeappendix(self,name); +end; + +procedure tstatwriter.writearray(const name: msestring; const value: msestringarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(value[int1]); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: stringarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(msestring(value[int1])); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: integerarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(value[int1]); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: int64arty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(value[int1]); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: longboolarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(integer(value[int1])); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: booleanarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(integer(value[int1])); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: realarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(value[int1]); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: complexarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(value[int1]); + end; +end; + +function tstatwriter.beginlist(const name: msestring = ''): boolean; +begin + result:= true; + if name <> '' then begin + writestring(name,''); + end; + inc(flistlevel); + fstream.writeln(charstring(msechar(' '),flistlevel)+'('); +end; + +function tstatwriter.endlist: boolean; +begin + if flistlevel > 0 then begin + result:= true; + fstream.writeln(charstring(msechar(' '),flistlevel)+')'); + dec(flistlevel); + end + else begin + result:= false; + end; +end; + +procedure tstatwriter.writememorystatstream(const name,streamname: msestring); +var + stream1: ttextstream; + ar1: msestringarty; +begin + ar1:= nil; //compiler warning + stream1:= memorystatstreams.open(streamname,fm_read); + try + stream1.encoding:= fstream.encoding; + if stream1.Size > 0 then begin + ar1:= stream1.readmsestrings; + writearray(name,ar1); + end; + finally + stream1.Free; + end; +end; + +procedure tstatwriter.streamdata(const adata: string); +begin + writesection(''); + fstream.write(adata); +end; + +procedure tstatwriter.streamtext(const atext: msestring); +begin + writesection(''); + fstream.write(atext); +end; + +{ +procedure tstatwriter.writestatfile(const name: msestring; const statfile: tstatfile); +var + stream: ttextstream; + ar1: msestringarty; +begin + stream:= ttextstream.Create; + try + statfile.writestat(stream); + stream.position:= 0; + ar1:= stream.readmsestrings; + writearray(name,ar1); + finally + stream.Free; + end; +end; +} +{ tmemorytextstream } + +constructor tmemorytextstream.create(aowner: tmemorystreams; const name: msestring; + const aopenmode: fileopenmodety; var info: streaminfoty); +begin + fowner:= aowner; + fname:= name; + info.name:= name; + info.stream:= self; + inherited create; + if info.size > 0 then begin + if aopenmode <> fm_create then begin + {$ifdef mswindows} + {$ifndef FPC} + fmemorystream.SetSize(info.size); + move(info.data^,fmemorystream.memory^,info.size); + //on delphi memory is not on normal heap + freemem(info.data); + {$else} +{$warnings off} + tmemorystreamcracker(fmemorystream).setpointer(info.data,info.size); +{$warnings on} +{$warnings off} + tmemorystreamcracker(fmemorystream).fcapacity:= info.size; +{$warnings on} + {$endif} + {$else} +{$warnings off} + tmemorystreamcracker(fmemorystream).setpointer(info.data,info.size); +{$warnings on} +{$warnings off} + tmemorystreamcracker(fmemorystream).fcapacity:= info.size; +{$warnings on} + {$endif} + end + else begin + freemem(info.data); + end; + end; + info.data:= nil; + info.size:= 0; +end; + +destructor tmemorytextstream.destroy; +var + int1: integer; +begin + flushbuffer; + int1:= fowner.findname(fname); + if int1 >= 0 then begin + with fowner.fstreams[int1] do begin + size:= self.Size; +{$ifdef mswindows} + {$ifndef FPC} + getmem(data,size); + move(fmemorystream.memory^,data^,size); + //on delphi memory is not on normal heap + {$else} + data:= fmemorystream.memory; +{$warnings off} + tmemorystreamcracker(fmemorystream).setpointer(nil,0); +{$warnings on} + reallocmem(data,size); + {$endif} +{$else} + data:= fmemorystream.memory; +{$warnings off} + tmemorystreamcracker(fmemorystream).setpointer(nil,0); +{$warnings on} + reallocmem(data,size); +{$endif} + stream:= nil; + end; + end; + inherited; +end; + +{ tmemorystreams } + +procedure tmemorystreams.internaldelete(index: integer); +begin + if index >= 0 then begin + with fstreams[index] do begin + freeandnil(stream); + if data <> nil then begin + freemem(data); + data:= nil; + end; + size:= 0; + name:= ''; + end; + end; +end; + +procedure tmemorystreams.delete(const name: msestring); +begin + internaldelete(findname(name)); +end; + +destructor tmemorystreams.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fstreams) do begin + internaldelete(int1); + end; + inherited; +end; + +function tmemorystreams.findname(const name: msestring): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(fstreams) do begin + if fstreams[int1].name = name then begin + result:= int1; + break; + end; + end; +end; + +function tmemorystreams.open(const streamname: msestring; + const aopenmode: fileopenmodety): ttextstream; +var + int1: integer; +begin + if streamname = '' then begin + raise exception.Create('Invalid memory stream name.'); + end; + int1:= findname(streamname); + if (int1 >= 0) and (fstreams[int1].stream <> nil) then begin + raise exception.Create(ansistring('Memorystream '''+ + streamname+''' allready open.')); + end; + if int1 < 0 then begin + int1:= findname(''); + if int1 < 0 then begin + int1:= length(fstreams); + setlength(fstreams,int1+1); + end; + end; + result:= tmemorytextstream.create(self,streamname,aopenmode,fstreams[int1]); +end; + +function tmemorystreams.findfiles(const aname: msestring): msestringarty; +var + ar1: msestringarty; + int1,int2: integer; +begin + ar1:= nil; + int2:= 0; + splitstringquoted(aname,ar1); + setlength(result,length(fstreams)); //max + for int1:= 0 to high(result) do begin + if checkfilename(fstreams[int1].name,ar1) then begin + result[int2]:= fstreams[int1].name; + inc(int2); + end; + end; + setlength(result,int2); +end; + +initialization +finalization + fmemorystatstreams.free; +end. diff --git a/mseide-msegui/lib/common/kernel/msestatfile.pas b/mseide-msegui/lib/common/kernel/msestatfile.pas new file mode 100644 index 0000000..33aca68 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestatfile.pas @@ -0,0 +1,843 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestatfile; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,msestat,mseapplication,msetypes,msestrings,mseclasses,msestream, + mseglob,msearrayprops; + +type + statupdateeventty = procedure(const sender: tobject; + const filer: tstatfiler) of object; + statreadeventty = procedure(const sender: tobject; + const reader: tstatreader) of object; + statwriteeventty = procedure(const sender: tobject; + const writer: tstatwriter) of object; + + statfileoptionty = (sfo_memory,sfo_deletememorydata, //delete after read + sfo_createpath, + sfo_transaction, //use intermedate file and rename + sfo_savedata,sfo_autoreadstat,sfo_autowritestat, + sfo_activatorread,sfo_activatorwrite, + sfo_nodata,sfo_nostate,sfo_nooptions); + statfileoptionsty = set of statfileoptionty; +const + defaultstatfileoptions = [sfo_activatorread,sfo_activatorwrite,sfo_transaction]; + +type + tstatfile = class; + statfilemissingeventty = procedure (const sender: tstatfile; + const afilename: filenamety; + var astream: ttextstream; var aretry: boolean) of object; + statfilemodety = (sfm_inactive,sfm_reading,sfm_writing); + + statclientinfoty = record + intf: istatfile; + priority: integer; + end; + pstatclientinfoty = ^statclientinfoty; + statclientarty = array of statclientinfoty; + + statfilestatety = (stfs_reading); + statfilestatesty = set of statfilestatety; + + tstatfile = class(tactcomponent,istatfile) + private + ffilename: filenamety; + ffiledir: filenamety; + floadedfile: filenamety; + + fstatvarname: msestring; + fonstatupdate: statupdateeventty; + fonstatread: statreadeventty; + fonstatwrite: statwriteeventty; + fonstatbeforeread: notifyeventty; + fonstatafterread: notifyeventty; + fonstatbeforewrite: notifyeventty; + fonstatafterwrite: notifyeventty; + areader: tstatreader; + awriter: tstatwriter; + aclients: statclientarty; + aclientcount: integer; + foptions: statfileoptionsty; + fencoding: charencodingty; + fstatfile: tstatfile; + fsavedmemoryfiles: msestring; + fonfilemissing: statfilemissingeventty; + fcryptohandler: tcustomcryptohandler; + fnext: tstatfile; + fstatpriority: integer; + procedure dolinkstatread(const info: linkinfoty); + procedure dolinkstatreading(const info: linkinfoty); + procedure dolinkstatreaded(const info: linkinfoty); + procedure dolinkstatwrite(const info: linkinfoty); + procedure setstatfile(const Value: tstatfile); + procedure setfilename(const avalue: filenamety); + procedure setfiledir(const avalue: filenamety); +// procedure setoptions(avalue: statfileoptionsty); + procedure setcryptohandler(const avalue: tcustomcryptohandler); + function getmode: statfilemodety; + procedure setnext(const avalue: tstatfile); + procedure internalreadstat; + procedure internalwritestat; + protected + fstate: statfilestatesty; + procedure objevent(const sender: iobjectlink; + const event: objecteventty); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure updateoptions(const afiler: tstatfiler); + function defaultfile(const adirs: filenamearty): filenamety; + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + procedure initnewcomponent(const ascale: real); override; + procedure readstat(const stream: ttextstream = nil); overload; + procedure readstat(const afilename: filenamety); overload; //disk file + procedure readstat(const aname: msestring; + const statreader: tstatreader); overload; + procedure writestat(const stream: ttextstream = nil); overload; + procedure writestat(const afilename: filenamety); overload; //disk file + procedure writestat(const aname: msestring; + const statwriter: tstatwriter); overload; + procedure updatestat(const aname: msestring; const statfiler: tstatfiler); + property mode: statfilemodety read getmode; + published + property filename: filenamety read ffilename write setfilename nodefault; + property filedir: filenamety read ffiledir write setfiledir; + property encoding: charencodingty read fencoding write fencoding + default ce_utf8; + property options: statfileoptionsty read foptions write foptions + default defaultstatfileoptions; + property statfile: tstatfile read fstatfile write setstatfile; + //filename is stored in linked statfile, dostatread and dostatwrite are + //called by linked statfile + property savedmemoryfiles: msestring read fsavedmemoryfiles write + fsavedmemoryfiles; + //use quotes for several filenames '"file1.sta" "file2.sta*"', + //'*' and '?' wildcards supported. + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property cryptohandler: tcustomcryptohandler read fcryptohandler + write setcryptohandler; + property activator; + property next: tstatfile read fnext write setnext; + property onstatupdate: statupdateeventty read fonstatupdate write fonstatupdate; + property onstatread: statreadeventty read fonstatread write fonstatread; + property onstatwrite: statwriteeventty read fonstatwrite write fonstatwrite; + property onstatbeforewrite: notifyeventty read fonstatbeforewrite + write fonstatbeforewrite; + property onstatafterwrite: notifyeventty read fonstatafterwrite + write fonstatafterwrite; + property onstatbeforeread: notifyeventty read fonstatbeforeread + write fonstatbeforeread; + property onstatafterread: notifyeventty read fonstatafterread + write fonstatafterread; + property onfilemissing: statfilemissingeventty read fonfilemissing + write fonfilemissing; + end; + + tstatfileitem = class(tmsecomponentlinkitem) + private + function getstatfile: tstatfile; + procedure setstatfile(const avalue: tstatfile); + published + property statfile: tstatfile read getstatfile write setstatfile; + end; + + tstatfilearrayprop = class(tmsecomponentlinkarrayprop) + private + function getitems(const index: integer): tstatfileitem; + public + constructor create; + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tstatfileitem read getitems; default; + end; + +procedure setstatfilevar(const sender: istatfile; const source: tstatfile; + var instance: tstatfile); +implementation +uses + msesystypes,msesys,msefileutils,sysutils,msearrayutils; + +procedure setstatfilevar(const sender: istatfile; const source: tstatfile; + var instance: tstatfile); +var + int1: integer; +begin + if source <> instance then begin + if (instance <> nil) and (stfs_reading in instance.fstate) then begin + for int1:= 0 to high(instance.aclients) do begin + with instance.aclients[int1] do begin + if intf = sender then begin + intf:= nil; + end; + end; + end; + end; + if (source <> nil) and (stfs_reading in source.fstate) then begin + setlength(source.aclients,high(source.aclients)+2); + source.aclients[high(source.aclients)].intf:= sender; + end; + end; + setlinkedcomponent(sender,source,tmsecomponent(instance),typeinfo(istatfile)); +end; + +{ tstatfile } + +constructor tstatfile.create(aowner: tcomponent); +begin +// ffilename:= defaultstatfilename; + fencoding:= ce_utf8; + foptions:= defaultstatfileoptions; + inherited; +end; + +procedure tstatfile.initnewcomponent(const ascale: real); +begin + ffilename:= defaultstatfilename; +end; + +procedure tstatfile.dostatread(const reader: tstatreader); +var + ar1,ar2: stringarty; + ar3: msestringarty; + stream1: ttextstream; + int1: integer; + reader1: tstatreader; +begin + ar1:= nil; //compiler warning + ar2:= nil; //compiler warning + if reader <> areader then begin + if not (sfo_memory in foptions) then begin + if sfo_savedata in foptions then begin + reader1:= areader; + areader:= reader; + try + internalreadstat; + finally; + areader:= reader1; + end; + end + else begin + filename:= reader.readmsestring('filename',ffilename); + end; + end + else begin + if sfo_savedata in foptions then begin + stream1:= memorystatstreams.open(ffilename,fm_read); + try + ar2:= stream1.readstrings; + finally + stream1.free; + end; + ar1:= reader.readarray('data',ar2); + stream1:= memorystatstreams.open(ffilename,fm_create); + try + stream1.writestrings(ar1); + finally + stream1.free; + end; + if sfo_autoreadstat in foptions then begin + readstat; + end; + end; + end; +// statread; + end + else begin + if fsavedmemoryfiles <> '' then begin + ar3:= reader.readarray('savedmemoryfiles',msestringarty(nil)); + for int1:= 0 to high(ar3) do begin + reader.readmemorystatstream(ar3[int1],ar3[int1]); + end; + end; + if assigned(fonstatupdate) then begin + fonstatupdate(self,reader); + end; + if assigned(fonstatread) then begin + fonstatread(self,reader); + end; + end; +end; + +procedure tstatfile.dostatwrite(const writer: tstatwriter); +var + ar1: stringarty; + ar3: msestringarty; + stream1: ttextstream; + int1: integer; + writer1: tstatwriter; +begin + ar1:= nil; //compiler warning + if (writer <> awriter) then begin + if not (sfo_memory in foptions) then begin + if sfo_savedata in foptions then begin + writer1:= awriter; + awriter:= writer; + try + internalwritestat; + finally; + awriter:= writer1; + end; + end + else begin + writer.writemsestring('filename',ffilename); + end; + end + else begin + if sfo_savedata in foptions then begin + if sfo_autowritestat in foptions then begin + writestat; + end; + stream1:= memorystatstreams.open(ffilename,fm_read); + try + ar1:= stream1.readstrings; + finally + stream1.free; + end; + writer.writearray('data',ar1); + end; + end; +// if ffilename <> '' then begin +// writestat; +// end; + end + else begin + if fsavedmemoryfiles <> '' then begin + ar3:= memorystatstreams.findfiles(fsavedmemoryfiles); + writer.writearray('savedmemoryfiles',ar3); + for int1:= 0 to high(ar3) do begin + writer.writememorystatstream(ar3[int1],ar3[int1]); + end; + end; + if assigned(fonstatupdate) then begin + fonstatupdate(self,writer); + end; + if assigned(fonstatwrite) then begin + fonstatwrite(self,writer); + end; + end; +end; + +function tstatfile.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tstatfile.dolinkstatread(const info: linkinfoty); +begin + areader.readstat(istatfile(info.dest)); +end; + +procedure tstatfile.dolinkstatreading(const info: linkinfoty); +begin + with pstatclientinfoty(additempo(aclients,typeinfo(statclientarty), + aclientcount))^ do begin + intf:= istatfile(info.dest); + priority:= intf.getstatpriority; + end; + istatfile(info.dest).statreading; +end; + +procedure tstatfile.objevent(const sender: iobjectlink; + const event: objecteventty); +var + int1: integer; +begin + if event = oe_destroyed then begin + for int1:= 0 to high(aclients) do begin + if aclients[int1].intf = sender then begin + aclients[int1].intf:= nil; + end; + end; + end; + inherited; +end; + +procedure tstatfile.dolinkstatreaded(const info: linkinfoty); +begin + istatfile(info.dest).statread; +end; + +procedure tstatfile.updateoptions(const afiler: tstatfiler); +var + opt1: statfileroptionsty; +begin + opt1:= afiler.options; + if sfo_nodata in foptions then begin + include(opt1,sfro_nodata); + end; + if sfo_nostate in foptions then begin + include(opt1,sfro_nostate); + end; + if sfo_nooptions in foptions then begin + include(opt1,sfro_nooptions); + end; + afiler.options:= opt1; +end; + +function tstatfile.defaultfile(const adirs: filenamearty): filenamety; +begin + if high(adirs) >= 0 then begin + result:= filepath(adirs[0],ffilename); + end + else begin + result:= filepath(ffilename); + end; +end; + +function cmpclients(const l,r): integer; +begin + result:= statclientinfoty(r).priority - statclientinfoty(l).priority; + //highest priority first +end; + +procedure tstatfile.internalreadstat; +var + int1: integer; +begin + if assigned(fonstatread) or assigned(fonstatupdate) or + (fsavedmemoryfiles <> '') then begin + areader.readstat(istatfile(self)); + end; + if fobjectlinker <> nil then begin + aclients:= nil; + aclientcount:= 0; + fobjectlinker.forall({$ifdef FPC}@{$endif}dolinkstatreading, + typeinfo(istatfile)); + setlength(aclients,aclientcount); + sortarray(aclients,sizeof(statclientinfoty),@cmpclients); + include(fstate,stfs_reading); + try + int1:= 0; + while int1 <= high(aclients) do begin + with aclients[int1] do begin + if intf <> nil then begin + areader.readstat(intf); + end; + end; + inc(int1); + end; +// fobjectlinker.forall({$ifdef FPC}@{$endif}dolinkstatread, +// typeinfo(istatfile)); + finally + exclude(fstate,stfs_reading); + aclients:= nil; + fobjectlinker.forall({$ifdef FPC}@{$endif}dolinkstatreaded, + typeinfo(istatfile)); + end; +// if assigned(fonstatafterread) then begin +// fonstatafterread(self); +// end; + end; +end; + +procedure tstatfile.readstat(const stream: ttextstream = nil); +var + stream1: ttextstream; + ar1: filenamearty; + by1: boolean; +begin + if stfs_reading in fstate then begin + exit; + end; + if assigned(fonstatbeforeread) then begin + fonstatbeforeread(self); + end; + stream1:= stream; + try + if (stream1 = nil) and (filename <> '') then begin + if sfo_memory in foptions then begin + floadedfile:= ''; + stream1:= memorystatstreams.open(ffilename,fm_read); + end + else begin + by1:= false; + repeat + unquotefilename(ffiledir,ar1); + if not findfile(ffilename,ar1,floadedfile) then begin + floadedfile:= ffilename; + end; + if ttextstream.trycreate(stream1,floadedfile,fm_read) <> sye_ok then begin + floadedfile:= defaultfile(ar1); + if assigned(fonfilemissing) then begin + fonfilemissing(self,floadedfile,stream1,by1); + if stream1 <> nil then begin + floadedfile:= ''; + end; + end; + end; + until (stream1 <> nil) or not by1; + if stream1 = nil then begin + floadedfile:= ''; + end; + end; + end; + if (fcryptohandler <> nil) and (stream1 <> nil) then begin + stream1.cryptohandler:= fcryptohandler; + end; + areader:= tstatreader.create(stream1,fencoding); + updateoptions(areader); + try + internalreadstat; + finally + freeandnil(areader); +// areader.free; + end; + finally + if stream = nil then begin + stream1.Free; + if (stream1 <> nil) and (foptions * [sfo_memory,sfo_deletememorydata] = + [sfo_memory,sfo_deletememorydata]) then begin + memorystatstreams.delete(ffilename); + end; + end + else begin + if (fcryptohandler <> nil) and (stream1 <> nil) then begin + stream1.cryptohandler:= nil; + end; + end; + end; + if fnext <> nil then begin + fnext.readstat(nil); + end; + if assigned(fonstatafterread) then begin + fonstatafterread(self); + end; +end; + +procedure tstatfile.readstat(const afilename: filenamety); +var + stream1: ttextstream; +begin + stream1:= ttextstream.create(afilename,fm_read); + try + stream1.encoding:= fencoding; + readstat(stream1); + finally + stream1.free; + end; +end; + +procedure tstatfile.writestat(const afilename: filenamety); +var + stream1: ttextstream; + fname1: filenamety; +begin + fname1:= afilename; + if sfo_transaction in foptions then begin + stream1:= ttextstream.createtransaction(fname1); + end + else begin + stream1:= ttextstream.create(fname1,fm_create); + end; + try + stream1.encoding:= fencoding; + writestat(stream1); + finally + stream1.free; + end; +end; + +procedure tstatfile.statreading; +begin + //dummy +end; + +procedure tstatfile.statread; +begin + //dummy +end; + +procedure tstatfile.dolinkstatwrite(const info: linkinfoty); +begin + awriter.writestat(istatfile(info.dest)); +end; + +procedure tstatfile.internalwritestat; +begin + if assigned(fonstatwrite) or assigned(fonstatupdate) or + (fsavedmemoryfiles <> '') then begin + awriter.writestat(istatfile(self)); + end; + if fobjectlinker <> nil then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}dolinkstatwrite,typeinfo(istatfile)); + end; +end; + +procedure tstatfile.writestat(const stream: ttextstream = nil); +var + stream1: ttextstream; + ar1: filenamearty; +// fname1: filenamety; + bo1: boolean; +begin + if assigned(fonstatbeforewrite) then begin + fonstatbeforewrite(self); + end; + if fnext <> nil then begin + fnext.writestat(nil); + end; + stream1:= stream; + if (stream1 = nil) and (filename <> '') then begin + if sfo_memory in foptions then begin + stream1:= memorystatstreams.open(ffilename,fm_create); + end + else begin + if floadedfile = '' then begin + unquotefilename(ffiledir,ar1); + if not findfile(ffilename,ar1,floadedfile) then begin + floadedfile:= defaultfile(ar1); + end; + if (sfo_createpath in foptions) and not findfile(floadedfile) then begin + createdirpath(msefileutils.filedir(floadedfile)); + end; + end; + try + if sfo_transaction in foptions then begin + stream1:= ttextstream.createtransaction(floadedfile); + end + else begin + stream1:= ttextstream.Create(floadedfile,fm_create); + end; + except + floadedfile:= ''; + raise; + end; + end; +// stream1.encoding:= fencoding; + end; + if stream1 = nil then begin + exit; + end; + try + if (fcryptohandler <> nil) then begin + stream1.cryptohandler:= fcryptohandler; + end; + awriter:= tstatwriter.create(stream1,fencoding); + updateoptions(awriter); + bo1:= false; + try + if (stream1.handle <> invalidfilehandle) and + not stream1.usewritebuffer then begin + bo1:= true; + stream1.usewritebuffer:= true; + end; + internalwritestat; +// if assigned(fonstatafterwrite) then begin +// fonstatafterwrite(self); +// end; + finally + freeandnil(awriter); + if bo1 then begin + stream1.usewritebuffer:= false; + end; + end; + finally + if stream = nil then begin + stream1.Free; + end + else begin + if (fcryptohandler <> nil) then begin + stream1.cryptohandler:= nil; + end; + end; + end; + if assigned(fonstatafterwrite) then begin + fonstatafterwrite(self); + end; +end; + +procedure tstatfile.setstatfile(const Value: tstatfile); +var + sf: tstatfile; +begin + if fstatfile <> value then begin + if value <> nil then begin + sf:= value; + while sf <> nil do begin + if sf = self then begin + raise exception.Create(name+': Recursive statfile'); + end; + sf:= sf.fstatfile; + end; + end; + setstatfilevar(istatfile(self),value,fstatfile); + end; +end; + +procedure tstatfile.setfilename(const avalue: filenamety); +begin + floadedfile:= ''; + ffilename:= avalue; +end; + +procedure tstatfile.setfiledir(const avalue: filenamety); +begin + floadedfile:= ''; + ffiledir:= avalue; +end; +{ +procedure tstatfile.setoptions(avalue: statfileoptionsty); +begin + if not (sfo_memory in avalue) then begin + exclude(avalue,sfo_savedata); + end; + foptions:= avalue; +end; +} +procedure tstatfile.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = activator) and not (csdesigning in componentstate) then begin + case event of + oe_activate: begin + if sfo_activatorwrite in foptions then begin + readstat; + end; + end; + oe_deactivate: begin + if sfo_activatorwrite in foptions then begin + writestat; + end; + end; + end; + end; +end; + +procedure tstatfile.readstat(const aname: msestring; + const statreader: tstatreader); +var + stream: ttextstream; + ar1: msestringarty; +begin + ar1:= statreader.readarray(aname,msestringarty(nil)); + stream:= ttextstream.Create; + stream.encoding:= fencoding; + try + stream.writemsestrings(ar1); + stream.Position:= 0; + readstat(stream); + finally + stream.Free; + end; +end; + +procedure tstatfile.writestat(const aname: msestring; + const statwriter: tstatwriter); +var + stream: ttextstream; + ar1: msestringarty; +begin + stream:= ttextstream.Create; + stream.encoding:= ce_utf8; + try + writestat(stream); + stream.position:= 0; + ar1:= stream.readmsestrings; + statwriter.writearray(aname,ar1); + finally + stream.Free; + end; +end; + +procedure tstatfile.updatestat(const aname: msestring; + const statfiler: tstatfiler); +begin + if statfiler.iswriter then begin + writestat(aname,tstatwriter(statfiler)); + end + else begin + readstat(aname,tstatreader(statfiler)); + end; +end; + +procedure tstatfile.setcryptohandler(const avalue: tcustomcryptohandler); +begin + setlinkedvar(avalue,tmsecomponent(fcryptohandler)); +end; + +function tstatfile.getmode: statfilemodety; +begin + result:= sfm_inactive; + if areader <> nil then begin + result:= sfm_reading; + end + else begin + if awriter <> nil then begin + result:= sfm_writing; + end; + end; +end; + +procedure tstatfile.setnext(const avalue: tstatfile); +var + sf: tstatfile; +begin + if fnext <> avalue then begin + if avalue <> nil then begin + sf:= avalue; + while sf <> nil do begin + if sf = self then begin + raise exception.Create(name+': Recursive next statfile'); + end; + sf:= sf.fnext; + end; + end; + setlinkedvar(avalue,tmsecomponent(fnext)); + end; +end; + +function tstatfile.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tstatfileitem } + +function tstatfileitem.getstatfile: tstatfile; +begin + result:= tstatfile(item); +end; + +procedure tstatfileitem.setstatfile(const avalue: tstatfile); +begin + item:= avalue; +end; + +{ tstatfilearrayprop } + +constructor tstatfilearrayprop.create; +begin + inherited create(tstatfileitem); +end; + +function tstatfilearrayprop.getitems(const index: integer): tstatfileitem; +begin + result:= tstatfileitem(inherited getitems(index)); +end; + +class function tstatfilearrayprop.getitemclasstype: persistentclassty; +begin + result:= tstatfileitem; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msestockobjects.mfm b/mseide-msegui/lib/common/kernel/msestockobjects.mfm new file mode 100644 index 0000000..fb627bd --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestockobjects.mfm @@ -0,0 +1,285 @@ +object stockdata: tstockdata + bounds_cx = 188 + bounds_cy = 85 + left = 129 + top = 57 + moduleclassname = 'tmsedatamodule' + object glyphs: timagelist + width = 15 + height = 15 + options = [bmo_monochrome, bmo_masked] + count = 84 + left = 32 + top = 40 + image = { + 00000000030000009600000096000000B80B0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000800000000002000000000000000000FF81FFC07F8001000000 + 0300000000001803000001818040408003000180030000000000B80370000181 + 80404480078003C003FE0F000000F001F8000181804044800FC007E003FC0700 + 0000E000F8000181BE405F801FE00FF003F803000000F001F800018180404480 + 0FF01FE003F001000000B803700001818040448007F83FC003E0000000001803 + 00000181804040800300008003400000000000000000FF81FFC07F8001000000 + 0300000000000000000000000000008000000000020000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000002000000020000080080011000004 + 08000200000060002000300000800C00130000040E8003008808E00070003800 + 7F800E00170000840FE00300DC1DE001F8003C003E800F001F601BE40FF80300 + 8808E000FC0138001C800E0017601B840FE00300000060000000300008800C00 + 130000040E800300000020000000200000800800110000040800020000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000080000000000000000000000000000 + 00000000001C000000000000700000000000C06030C011000038000010000408 + 700000000000E0E038F017000070000070001C08700000000C0070C01D301EFC + 1FE00000F0017C08FE83FF011E0038800F181CFC1FC00100F007FC09FE83FF01 + 3F601C0007181F0000C00000F0017C08FE83FF817FE00E800F18000000600600 + 70001C08700000C0FFC007C01D1000FC1F3003001000040870000000008003E0 + 383000FC1F9801000000000070000000000001603060000000CC000000000000 + 0000000000000000008000000060000000000000000000000000000000000000 + 0030000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000004000000000000000000000000000000000000 + 000EFF1F780038000280190000000000000000000007060CFC00280006000600 + 000000000000000080030C06860128000E0006000000000000F80300C0011803 + 030328001E0006800400000000400000E000B001030328003E000600030001C0 + 00E00000C000A000030328007E0006C00F8003C000F001009801A00003036C00 + 3E0006000300010000F803003003A0008601C6001E0006800400000000000000 + 6006A000FC0383010E0006000000000000000000C00CA0007887010306000600 + 00000000000000008001E00000CEFF0702801900000000000000000000030000 + 0004000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FE0FFF87FFC3 + FF01000000000000000000000000FF9FFFCFFFE7FF0300000000000000000000 + 0000039801CC0066000300000000000000000000000003988DCDC06600030000 + 07C0070000F8030000000398DDCDE0661C030E800D600CE003080200F0070398 + F9CC70663E0311C01820082002080200E003039871CC38663E03114010200820 + 02080200C0010398F9CC1C663E0311C0182008200208020080000398DDCD0E66 + 1C030E800D600CE003080200F00703988DCD06660003000007C0070000F80300 + 0000039801CC00660003000000000000000000000000FF9FFFCFFFE7FF030000 + 00000000000000000000FE0FFF87FFC3FF010000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000F80F000000001000000000000200000000040400 + 08080000200038000000040002000010040802000808400070006C0008000400 + 02400420021001000808A000D800C600080004000280024001A0000008081001 + 8C0183013E803FE03F000180004000000808A000D800C6000800040002800240 + 01A000000808400070006C000800040002400420021001000808000020003800 + 000004000200001004080200F80F000000001000000000000200000000040400 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000020000000000000000103021000180300 + 800040007000000000E0FFC0C10F0E70001803004001A000D800FE80FFC060F0 + F13F3EF001180300200210018C014400418031FCFDFFFEF007180300F0070802 + 0603280022001BF0F13F3EF0011803000000FC07FF07100014000EC0C10F0E70 + 0018030000000000000000000800040001030210001803000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000C000000000000000000000000000000000000000C + 004000E0E38363E0FF0000000000000000000006608060E0C1C33150900000E4 + 1FE60F0000040006500451E0E3E3104994FC7F0000E60F000154000358095AE0 + F7F3B1499404400000000000075280034F0A4FA0E3BAFB4890045CE41F000000 + 1F52E001410A490041101FC89FF44B0000E60F007F52D801410A510000000E08 + 80F44B0000E60F001F51F601410A610041001F0880F44BE41F00000007D1B901 + 4F0A4FA0E3823BC89F045C0000000000815054015809D8E0F7C3710880044000 + 00E60F0080005201500450E1E3E3E0C89FFC7FE41FE60F0000006901600060E2 + C173C009800000000000000000002401000000E4E33380F8FF00000000000000 + 000020010000000000000000000000000000000000000000000000F0FFFFFFFF + FFFFFFFFFFFF3F0000000000FF87FFF3A8A8A8A8A8A8A8A8A7A72700FC03AA8A + FFCFFFF7FFFFFFFFFFFFFFFFFFFF3F000402048401CC00F6FFFFFFFFFFFFFFFF + FFFF3F00040208820DCC06F6FFFFFFFF7D7D7DFF23232300E41F10811DCC0EF6 + 000000FF000000FF848404002412A08039CC1CF6FFFFFFFFFFFFFFFFFFFF3F00 + 2412008071CC38F6000000FFA7A7A7FFA8A828002412A080E1CC70F6000000FF + DCDCDCFFF7F73700FC130080C1CDE0F6272727FF878787FFFFFF3F002010A080 + 81CDC0F6FFFFFFFFE0E0E0FFABAB2B002010008001CC00F6FFFFFFFF474747FF + 2C2C2C00E01FA080FFCFFFF7ABABABFFFFFFFFFFFFFF3F0000000000FF87FFF3 + FFFFFFFFFFFFFFFF0000000000000000000000A061616161F7F7F7FF22222200 + 000000FF000000FF303030FFFFFFFFFF27272700878787FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF3F005A5A5AFF000000FF000000FFC4C4C4FFFFFF3F00474747FF + 2F2F2FFFF8F8F8FF414141FF05050500B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF3F00FFFFFFFF000000FFA7A7A7FFA8A8A8A803030300BCBCBCBCF4F4F4FF + BABABAFFB7B7B7FFC5C50500FFFFFFFF272727FF878787FFFFFFFFFFFFFF3F00 + FFFFFFFFFFFFFFFFB2B2B2FF5F5F5FFF11111100AEAEAEFFFFFFFFFF525252FF + 3A3A3AFFFFFF3F00F2F2F2FF343434FF181818FFFFFFFFFFFFFF3F00FFFFFFFF + FFFFFFFFFFFFFFFF000000FFA7A72700A8A8A8A8000000000707070763636363 + 9C9C1C00A0A0A0A0B2B2B2B2FFFFFFFF272727FF87870700FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFF3F000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000080 + 0000000002000000000000000000FF81FFC07F80010000000300000000001803 + 000001818040408003000180030000000000B8037000018180404480078003C0 + 03FE0F000000F001F8000181804044800FC007E003FC07000000E000F8000181 + BE405F801FE00FF003F803000000F001F8000181804044800FF01FE003F00100 + 0000B803700001818040448007F83FC003E00000000018030000018180404080 + 0300008003400000000000000000FF81FFC07F80010000000300000000000000 + 0000000000000080000000000200000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000020000000200000800800110000040800020000006000 + 2000300000800C00130000040E8003008808E000700038007F800E0017000084 + 0FE00300DC1DE001F8003C003E800F001F601BE40FF803008808E000FC013800 + 1C800E0017601B840FE00300000060000000300008800C00130000040E800300 + 0000200000002000008008001100000408000200000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000008000000000000000000000000000000000000001C0000 + 00000000700000000000C06030C011000038000010000408700000000000E0E0 + 38F017000070000070001C08700000000C0070C01D301EFC1FE00000F0017C08 + FE83FF011E0038800F181CFC1FC00100F007FC09FE83FF013F601C0007181F00 + 00C00000F0017C08FE83FF817FE00E800F1800000060060070001C08700000C0 + FFC007C01D1000FC1F3003001000040870000000008003E0383000FC1F980100 + 0000000070000000000001603060000000CC0000000000000000000000000000 + 0080000000600000000000000000000000000000000000000030000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000004000000000000000000000000000000000000000EFF1F78003800 + 0280190000000000000000000007060CFC002800060006000000000000000000 + 80030C06860128000E0006000000000000F80300C0011803030328001E000680 + 0400000000400000E000B001030328003E000600030001C000E00000C000A000 + 030328007E0006C00F8003C000F001009801A00003036C003E00060003000100 + 00F803003003A0008601C6001E00068004000000000000006006A000FC038301 + 0E0006000000000000000000C00CA00078870103060006000000000000000000 + 8001E00000CEFF07028019000000000000000000000300000004000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FE0FFF87FFC3FF01000000000000 + 000000000000FF9FFFCFFFE7FF03000000000000000000000000039801CC0066 + 000300000000000000000000000003988DCDC0660003000007C0070000F80300 + 00000398DDCDE0661C030E800D600CE003080200F0070398F9CC70663E0311C0 + 1820082002080200E003039871CC38663E0311401020082002080200C0010398 + F9CC1C663E0311C0182008200208020080000398DDCD0E661C030E800D600CE0 + 03080200F00703988DCD06660003000007C0070000F803000000039801CC0066 + 0003000000000000000000000000FF9FFFCFFFE7FF0300000000000000000000 + 0000FE0FFF87FFC3FF0100000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000F80F0000000010000000000002000000000404000808000020003800 + 0000040002000010040802000808400070006C00080004000240042002100100 + 0808A000D800C600080004000280024001A00000080810018C0183013E803FE0 + 3F000180004000000808A000D800C600080004000280024001A0000008084000 + 70006C0008000400024004200210010008080000200038000000040002000010 + 04080200F80F0000000010000000000002000000000404000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000200000000000000001030210001803008000400070000000 + 00E0FFC0C10F0E70001803004001A000D800FE80FFC060F0F13F3EF001180300 + 200210018C014400418031FCFDFFFEF007180300F00708020603280022001BF0 + F13F3EF0011803000000FC07FF07100014000EC0C10F0E700018030000000000 + 0000000008000400010302100018030000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000C000000000000000000000000000000000000000C004000E0E38363E0 + FF0000000000000000000006608060E0C1C33150900000E41FE60F0000040006 + 500451E0E3E3104994FC7F0000E60F000154000358095AE0F7F3B14994044000 + 00000000075280034F0A4FA0E3BAFB4890045CE41F0000001F52E001410A4900 + 41101FC89FF44B0000E60F007F52D801410A510000000E0880F44B0000E60F00 + 1F51F601410A610041001F0880F44BE41F00000007D1B9014F0A4FA0E3823BC8 + 9F045C0000000000815054015809D8E0F7C371088004400000E60F0080005201 + 500450E1E3E3E0C89FFC7FE41FE60F0000006901600060E2C173C00980000000 + 0000000000002401000000E4E33380F8FF000000000000000000200100000000 + 00000000000000000000000000000000000000F0FFFFFFFFFFFFFFFFFFFF3F00 + 00000000FF87FFF3FFFFFFFFFFFFFFFFFFFF3F00FC03AA8AFFCFFFF7FFFFFFFF + FFFFFFFFFFFF3F000402048401CC00F6FFFFFFFFFFFFFFFFFFFF3F0004020882 + 0DCC06F6FFFFFFFFFFFFFFFFFFFF3F00E41F10811DCC0EF6FFFFFFFFFFFFFFFF + FFFF3F002412A08039CC1CF6FFFFFFFFFFFFFFFFFFFF3F002412008071CC38F6 + FFFFFFFFFFFFFFFFFFFF3F002412A080E1CC70F6FFFFFFFFFFFFFFFFFFFF3F00 + FC130080C1CDE0F6FFFFFFFFFFFFFFFFFFFF3F002010A08081CDC0F6FFFFFFFF + FFFFFFFFFFFF3F002010008001CC00F6FFFFFFFFFFFFFFFFFFFF3F00E01FA080 + FFCFFFF7FFFFFFFFFFFFFFFFFFFF3F0000000000FF87FFF3FFFFFFFFFFFFFFFF + FFFF3F0000000000000000F0FFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF3F00 + } + end + object mseicon: tbitmapcomp + bitmap.transparentcolor = -2147483642 + bitmap.image = { + 00000000000000001800000018000000A8080000000000000000000000000000 + 0000000000000000000000000000000000000000ECECEC01EBEBEB01E9E9E901 + E8E8E801E7E7E701E6E6E601E5E5E501E3E3E301E1DEDD02E0E0E001DFDFDF01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01EBEBEB01E9E9E901E8E8E801 + E7E7E701E6E6E601E5E5E501E3E3E301D78C6C01D67E5901E1A49001E5A79501 + E3A29001E3A59301DE9D8701D3775001D8B3A401D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01EBEBEB01E9E9E901E2C8BD01 + DFC1B401E6E6E601E7D2CB01E7B2A301DA846101FDF9F701D56D4401E0644301 + DF604001D9603A01DD8B6A01F0CDBE01D97D5D01DFAA9B01DAC4BE01D5D5D501 + D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01EBEBEB01E9E9E901D99C8101 + E7B39C01D7835F01E18C7001E4775A01D6683F01FFFEFE01F4DDD301D14A1E01 + D22A0001DF927301FFFFFF01E6AA9101D8522C01DF725501DF937D01DCB4A901 + D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01EBEBEB01E9E9E901E0C2B501 + ECC1B001FEFBFA01E4A38901D35F3501CF3A0E01EBBBA801FFFFFF01E5A68D01 + D04B2001FAEFEA01FFFFFF01DA805D01D4270001D7381101DD5E3E01DF876F01 + D8A08C01D0836101CFA89701D0D0D001ECECEC01EBEBEB01E9E9E901EBC3B701 + D97E5A01FFFFFF02FFFEFE01E0937601D15E3301FEFCFB01FBF3EF01D05D3201 + FFFFFF02D4623C01D45F3801D1481D01D2290001D4613701E29E8301EECBBA01 + CFA79501D0D0D001ECECEC01EBEBEB01EBD5CF01EA9D8801DB613B01E5A58C01 + FFFFFF03D5684301DD866801F8E8E101CF502701D9725101E0947901CF4D2301 + D7795501D0512701DB815F01FBF1ED01FBF3EF01D4744D01D5BFB701D0D0D001 + ECECEC01EBEBEB01ECB7A701E6795C01D3441901CE4B1F01ECBCAA01FFFFFF02 + D3643F01A25F4D01CB5A3701AF47370124E6E00168978D01D0391801D56C4601 + F7E4DC01FFFFFF01FFFDFD01D66E4701DB6D4E01DBA59601D0D0D001ECECEC01 + EDD9D301EA9B8501E0583601D6704901EEC4B401D0572C01E29A8101E5A28B01 + 7B907C010EFFF901639A9701679692010EFFF90130D7D101D6644301FFFFFF03 + DE8D6E01D2300701DB543201DD8D7701D4C1BB01ECECEC01EDC5BA01E7836901 + DA3C1601D1471E01D5633D01CE4A2001D03A1701D03C1C017A7F7A0117F4EE01 + 976E7001D6797C019E6B6D01A1505001B94B3801E7AC9801FFFFFF01E7AC9501 + D13C1801D4250201D73A1301DD795E01D8B0A501ECECEC01E6A58F01D8694201 + D5663E01DE8B6C01E8B09B01F0CEBF01F6E2D901DA806001CE1C1501C2272E01 + D7B5B801D5FFFE01D6A4A8013DC7C40114F8F201B15A4501D1552E01D35F3801 + D9755301DC866501DB826001D56B4301D6907901ECECEC01D0653701F5DFD501 + FFFFFF05D566470130D6D20124E4E001D0737D01D6D6D801D855610151ADAD01 + 16F6F101B6473201E1987C01FFFFFF02FEFAF901EBBCA901D7764F01D78D7501 + ECECEC01E9A28D01D7603701D7704A01F2D4C701FFFFFF02E7AC9701D13C2301 + 19F2EC010EFFF901A249570174808B016D8B9201C9202501C35C4101D5593C01 + D0552E01D5634101D76B4701D14E2501D12E0401DC5D3C01DB9A8801ECECEC01 + EDAF9D01E3674701D4270001D0381101D45F3901D25D3601D25F3801CD532701 + C3282401B44B4001B8433E010EFFF902B3634E01FDF9F701FFFFFF01F5DBD101 + D45F3A01D3270A01D4220301D4270001DC604001DB9D8B01ECECEC01EDB8A901 + E5725401D4270001D4230301D1351301DD856701FDF7F501D25F3801E0907701 + F4DCD101D86C4F01965A6101A8474701D3573401FEFDFC01FFFFFF02FEFDFC01 + E0937701D1451D01D4270001DD694C01DAA59601ECECEC01EDC5BA01E7836901 + DA3C1601D1330B01DF927501FFFFFF01E5A18901D66B4801FFFFFF02F1CFC101 + D1251101DA7E5E01D4633F01D2603B01FAF0EC01FFFFFF03ECC0AE01D4502601 + DD795E01D8B0A501ECECEC01EDD9D301EA9B8501DB573001DC836101FFFFFF01 + FEFBFA01D25C3401F3D6CB01FFFFFF02DE876C01CF240B01E49F8701FEFCFB01 + DB7C5C01D0552C01DA7B5A01E29B8101EDC3B201F5DFD601E4A68C01D6795901 + D4C1BB01ECECEC01EBEBEB01E9B09D01D97F5901FEFBFA01F4DCD201DB826001 + D35F3701FFFFFF02EFC7B901D0542C01D0562F01D9735301FFFFFF02D76D4901 + D51E0601D3240401D02A0201D2441901D5684201D89A8601D0D0D001ECECEC01 + EBEBEB01E2B3A201D6744C01D6633B01D1390D01CF2F0601E9B49F01FFFFFF01 + E6A68F01D1431F01E0927601DC7E5F01D24C2901FDF8F601FFFFFF01DE8A6B01 + D4220401D4240201D4270001DD5E3D01DE917C01D6C0B901D0D0D001ECECEC01 + EBEBEB01E9E9E901EBC3B701E8907801E05B3901D1512601F8E6DF01D5684201 + D22E0D01D13A1601F7E6DF01E0937701D1280701E5A58D01FFFFFF01E8B29C01 + D1290101D4270001DC573501DE876F01DAB3A701D1D1D101D0D0D001ECECEC01 + EBEBEB01E9E9E901E8E8E801EABEB101E7907801D9623C01D2542801D4270001 + D4250201D12D0701E8B29B01D1522801D4220301D35A3101FEFDFC01F0D0C201 + D23A0E01DD5E3E01DF876F01DCAFA201D3D3D301D1D1D101D0D0D001ECECEC01 + EBEBEB01E9E9E901E8E8E801E7E7E701E9C2B601E89C8601E4775A01DE573501 + D93B1501D4270001CF431601D2270001D4270001D22F0501E3A08601EABBA701 + D9674501DF937D01DCB4A901D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01 + EBEBEB01E9E9E901E8E8E801E7E7E701E6E6E601E7D2CB01E7B2A301E6978101 + E4806501E26F5101E0644401DF604001DF634301E06D4F01D66F4801D6785201 + DDA39101DAC4BE01D5D5D501D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01 + EBEBEB01E9E9E901E8E8E801E7E7E701E6E6E601E5E5E501E3E3E301E5D1CB01 + E5BEB201E5B0A101E5A79501E3A29001E3A59301E2AD9D01DEB1A201DAC1B801 + D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301D1D1D101D0D0D001 + } + left = 32 + top = 8 + end +end diff --git a/mseide-msegui/lib/common/kernel/msestockobjects.pas b/mseide-msegui/lib/common/kernel/msestockobjects.pas new file mode 100644 index 0000000..2029c98 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestockobjects.pas @@ -0,0 +1,544 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestockobjects; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msegraphics,mseglob,msegui,msebitmap,msegraphutils,mseclasses, + msestrings,msedatamodules,mseguiglob; + +const + boxsize = 11; //for treelistitem expand box + checkboxsize = 13; //for listitem checkbox + +type + + stockbitmapty = (stb_default,stb_none, + stb_dens0,stb_dens10,stb_dens25, + stb_dens50,stb_dens75,stb_dens90,stb_dens100, + stb_block2,stb_block3,stb_block4, + stb_hatchup3,stb_hatchup4,stb_hatchup5, + stb_hatchdown3,stb_hatchdown4,stb_hatchdown5, + stb_crosshatch3,stb_crosshatch4,stb_crosshatch5,stb_crosshatch6 + ); +const + stb_block1 = stb_dens50; + +type + stockglyphty = ( //order fix! + // 0 1 2 + stg_none,stg_checked,stg_checkedradio, + // 3 4 5 + stg_box,stg_boxexpanded,stg_boxexpand, + // 6 7 8 9 + stg_arrowright,stg_arrowup,stg_arrowleft,stg_arrowdown, + // 10 + stg_ellipse, + // 11 12 13 14 + stg_arrowrightsmall,stg_arrowupsmall,stg_arrowleftsmall,stg_arrowdownsmall, + // 15 16 + stg_arrowfirstsmall,stg_arrowlastsmall, + // 17 + stg_ellipsesmall, + // 18 19 20 21 22 + stg_dbfirst,stg_dbprior,stg_dbnext,stg_dblast,stg_dbinsert, + // 23 24 25 26 27 + stg_dbdelete,stg_dbedit,stg_dbpost,stg_dbcancel,stg_dbrefresh, + // 28 29 30 31 32 + stg_dbfilter,stg_dbfiltermin,stg_dbfiltermax,stg_dbfilteron,stg_dbfind, + // 33 34 35 36 + stg_dbfilteroff,stg_dbindbrowse,stg_dbindedit,stg_dbindinsert, + // 37 38 39 40 + stg_dot,stg_dotsmall,stg_arrowtopsmall,stg_arrowbottomsmall, + // 41 42 43 44 + stg_checkbox,stg_checkboxchecked,stg_checkboxchildchecked,stg_checkboxradio, + // 45 46 47 + stg_circlesmall,stg_circle,stg_circlebig, + // 48 49 50 + stg_squaresmall,stg_square,stg_squarebig, + // 51 52 53 + stg_diamondsmall,stg_diamond,stg_diamondbig, + // 54 55 56 + stg_crosssmall,stg_cross,stg_crossbig, + // 57 58 59 + stg_diagsmall,stg_diag,stg_diagbig, + // 60 61 62 + stg_triasmall,stg_tria,stg_triabig, + // 63 64 65 + stg_triatopsmall,stg_triatop,stg_triatopbig, + // add by Alexandre Minoshi + // 66 67 68 69 70 + stg_mmprev, stg_mmnext, stg_mmplay, stg_mmpause, stg_mmplayandpause, + // 71 + stg_mmclear, + // 72 73 + stg_sound, stg_soundoff, + // 74 75 76 77 78 79 + stg_fullscreen, stg_settings, stg_save, stg_rename, stg_list, stg_listbold, + // 80 81 82 + stg_doublesquare,stg_dbfilterclear,stg_checkboxparentnotchecked, + // 83 + stg_checkboxchildnotchecked + ); + +const + firsttracesymbol = stg_circlesmall; + lasttracesymbol = stg_triatopbig; + +type + stockcaptionty = (sc_none,sc_is_invalid,sc_Format_error,sc_Value_is_required, + sc_Error,sc_Min,sc_Max,sc_Range_error, + sc_Undohk,sc_Redohk,sc_copyhk,sc_cuthk,sc_pastehk, + sc_select_allhk, + sc_insert_rowhk,sc_append_rowhk,sc_delete_rowhk, + sc_Dirhk,sc_Homehk,sc_Uphk,sc_New_dirhk,sc_Namehk, + sc_Show_hidden_fileshk,sc_Filterhk, + sc_Save,sc_Open, + sc_name,sc_create_new_directory, + sc_back,sc_forward,sc_up, + sc_file,sc_exists_overwrite,sc_is_modified_save, + sc_warningupper,sc_errorupper,sc_exception,sc_system, + sc_does_not_exist, + sc_passwordupper,sc_enterpassword,sc_invalidpassword, + sc_can_not_read_directory, + sc_graphic_format_not_supported,sc_graphic_format_error, + sc_MS_Bitmap,sc_MS_Icon,sc_JPEG_Image,sc_PNG_Image, + sc_XPM_Image,sc_PNM_Image,sc_TARGA_image,sc_TIFF_image, + sc_All, + sc_Confirmation,sc_Delete_record_question, + sc_Copy_record_question, + sc_close_page, +{ + dbnavigbuttonty = (dbnb_first,dbnb_prior,dbnb_next,dbnb_last,dbnb_insert, + dbnb_delete,dbnb_edit, + dbnb_post,dbnb_cancel,dbnb_refresh, + dbnb_filter,dbnb_filtermin,dbnb_filtermax,dbnb_filteronoff,dbnb_find, + dbnb_autoedit,dbnb_copyrecord,dbnb_dialog); +} + sc_first,sc_prior,sc_next,sc_last, + sc_append,sc_delete,sc_edit,sc_post,sc_cancel,sc_refresh, + sc_edit_filter,sc_edit_filter_min,sc_edit_filter_max, + sc_reset_filter, + sc_filter_on,sc_search,sc_auto_edit,sc_copy_record, + sc_dialog, + sc_insert,sc_copy,sc_paste, + sc_row_insert,sc_row_append,sc_row_delete, + sc_undo,sc_redo,sc_cut,sc_select_all, + + sc_filter_off, + sc_portrait,sc_landscape, + sc_Delete_row_question,sc_selected_rows, + sc_Single_item_only,sc_Copy_Cells,sc_Paste_Cells, + sc_close,sc_maximize,sc_normalize,sc_minimize,sc_fix_size, + sc_float,sc_stay_on_top,sc_stay_in_background, + sc_lock_children,sc_no_lock, + sc_input,sc_button,sc_on,sc_off, + sc_leftborder,sc_topborder,sc_rightborder,sc_bottomborder, + sc_beginoftext,sc_endoftext,sc_inputmode,sc_overwrite, + sc_deleted,sc_copied,sc_inserted,sc_pasted,sc_withdrawn, + sc_windowactivated,sc_menu, + sc_bof,sc_eof, + sc_voiceoutput,sc_speakagain, + sc_firstcol,sc_firstrow,sc_lastcol,sc_lastrow, + sc_selection,sc_speakpath,sc_disabledbutton, + sc_firstfield,sc_lastfield, + sc_firstelement,sc_lastelement,sc_slower,sc_faster, + sc_window,sc_area,sc_areaactivated, + sc_volumedown,sc_volumeup,sc_cancelspeech + ); + textgeneratorfuncty = function(const params: array of const): msestring; + textgeneratorty = (tg_delete_n_selected_rows); + + tstockobjects = class + private + fbitmaps: array[stockbitmapty] of tbitmap; + ffonts: array[stockfontty] of twidgetfont; +// fmodalresulttext: array[modalresultty] of msestring; +// fmodalresulttextnoshortcut: array[modalresultty] of msestring; + fglyphs: timagelist; + ffontaliasregistered: boolean; + function getbitmaps(index: stockbitmapty): tbitmap; + function getfonts(index: stockfontty): twidgetfont; + function getmodalresulttext(index: modalresultty): msestring; + function getmodalresulttextnoshortcut(index: modalresultty): msestring; + function getglyphs: timagelist; + procedure fontchanged(const sender: tobject); + function getmseicon: tmaskedbitmap; + function getcaptions(index: stockcaptionty): msestring; + function gettextgenerator(index: textgeneratorty): textgeneratorfuncty; + procedure setmseicon(const avalue: tmaskedbitmap); + public + constructor create; + destructor destroy; override; + procedure paintglyph(const canvas: tcanvas; const glyph: stockglyphty; + const rect: rectty; const grayed: boolean = false; + const color: colorty = cl_glyph; + aalignment: alignmentsty = [al_ycentered,al_xcentered]); + property bitmaps[index: stockbitmapty]: tbitmap read getbitmaps; + property fonts[index: stockfontty]: twidgetfont read getfonts; + property modalresulttext[index: modalresultty]: msestring + read getmodalresulttext; + property modalresulttextnoshortcut[index: modalresultty]: msestring + read getmodalresulttextnoshortcut; + property captions[index: stockcaptionty]: msestring read getcaptions; + property textgenerators[index: textgeneratorty]: textgeneratorfuncty + read gettextgenerator; + property glyphs: timagelist read getglyphs; + property mseicon: tmaskedbitmap read getmseicon write setmseicon; + end; + +type + tstockdata = class(tmsedatamodule) + glyphs: timagelist; + mseicon: tbitmapcomp; + end; + +function stockobjects: tstockobjects; +function sc(const acaption: stockcaptionty): msestring; + +procedure init; +procedure deinit; + +implementation + +uses + sysutils,msestockobjects_mfm,msesysintf1,mseguiintf,typinfo,mseconsts,msefont; +//const +// defaultfontheight = 14; +// defaultfontheight = 26; + +type + twidget1 = class(twidget); + +var + stockdata: tstockdata; + stockobjs: tstockobjects; +// fontheight: integer; + +const + {$ifdef mswindows} + b_none: array[0..0] of byte = ($00); //1*1 + b_0: array[0..0] of byte = ($00); //1*1 + b_10: array[0..3] of byte = ($01,$00,$08,$00); //6*4 + b_25: array[0..1] of byte = ($01,$04); //4*2 + b_50: array[0..1] of byte = ($01,$02); //2*2 + b_75: array[0..1] of byte = ($0e,$0b); //4*2 + b_90: array[0..3] of byte = ($3e,$3f,$37,$3f); //6*4 + b_100: array[0..0] of byte = ($01); //1*1 + b_block2: array[0..3] of byte = ($03,$03,$0c,$0c); //4*4 + b_block3: array[0..5] of byte = ($07,$07,$07,$38,$38,$38); //6*6 + b_block4: array[0..7] of byte = ($0f,$0f,$0f,$0f,$f0,$f0,$f0,$f0); //8*8 + b_hatchup3: array[0..2] of byte = ($04,$02,$01); //3*3 + b_hatchup4: array[0..3] of byte = ($08,$04,$02,$01); //4*4 + b_hatchup5: array[0..4] of byte = ($10,$08,$04,$02,$01); //5*5 + b_hatchdown3: array[0..2] of byte = ($01,$02,$04); //3*3 + b_hatchdown4: array[0..3] of byte = ($01,$02,$04,$08); //4*4 + b_hatchdown5: array[0..4] of byte = ($01,$02,$04,$08,$10); //5*5 + b_crosshatch3: array[0..2] of byte = ($05,$02,$05); //3*3 + b_crosshatch4: array[0..3] of byte = ($08,$05,$02,$05); //4*4 + b_crosshatch5: array[0..4] of byte = ($11,$0a,$04,$0a,$11); //5*5 + b_crosshatch6: array[0..5] of byte = ($20,$11,$0a,$04,$0a,$11); //6*6 + + //win98 can not use patternbrush < 8*8 + + b_none_98: array[0..7] of byte = ($00,$00,$00,$00,$00,$00,$00,$00); //8*8 + b_0_98: array[0..7] of byte = ($00,$00,$00,$00,$00,$00,$00,$00); //8*8 + b_10_98: array[0..15] of byte = ($41,$00,$00,$00,$08,$02,$00,$00, + $41,$00,$00,$00,$08,$02,$00,$00); //12*8 + b_25_98: array[0..7] of byte = ($11,$44,$11,$44,$11,$44,$11,$44); //8*8 + b_50_98: array[0..7] of byte = ($55,$aa,$55,$aa,$55,$aa,$55,$aa); //8*8 + b_75_98: array[0..7] of byte = ($ee,$bb,$ee,$bb,$ee,$bb,$ee,$bb); //8*8 + b_90_98: array[0..15] of byte = ($be,$0f,$ff,$0f,$f7,$0d,$ff,$0f, + $be,$0f,$ff,$0f,$f7,$0d,$ff,$0f); //12*8 + b_100_98: array[0..7] of byte = ($ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff); //8*8 + b_block2_98: array[0..7] of byte = ($33,$33,$cc,$cc,$33,$33,$cc,$cc); //8*8 + b_block3_98: array[0..23] of byte = ($c7,$01,$c7,$01,$c7,$01, + $38,$0e,$38,$0e,$38,$0e, //12*12 + $c7,$01,$c7,$01,$c7,$01, + $38,$0e,$38,$0e,$38,$0e); + b_block4_98: array[0..7] of byte = ($0f,$0f,$0f,$0f,$f0,$f0,$f0,$f0); //8*8 + b_hatchup3_98: array[0..23] of byte = ($24,$09,$92,$04,$49,$02, + $24,$09,$92,$04,$49,$02, + $24,$09,$92,$04,$49,$02, + $24,$09,$92,$04,$49,$02); //12*12 + b_hatchup4_98: array[0..7] of byte = ($88,$44,$22,$11,$88,$44,$22,$11); //8*8 + b_hatchup5_98: array[0..19] of byte = ($10,$02,$08,$01,$84,$00,$42,$00,$21,$00, + $10,$02,$08,$01,$84,$00,$42,$00,$21,$00); //10*10 + b_hatchdown3_98: array[0..17] of byte = ($49,$00,$92,$00,$24,$01, + $49,$00,$92,$00,$24,$01, + $49,$00,$92,$00,$24,$01); //9*9 + b_hatchdown4_98: array[0..7] of byte = ($11,$22,$44,$88,$11,$22,$44,$88); //8*8 + b_hatchdown5_98: array[0..19] of byte = ($21,$00,$42,$00,$84,$00,$08,$01,$10,$02, + $21,$00,$42,$00,$84,$00,$08,$01,$10,$02); //10*10 + b_crosshatch3_98: array[0..23] of byte = ($6d,$01,$92,$00,$6d,$01, + $6d,$01,$92,$00,$6d,$01, + $6d,$01,$92,$00,$6d,$01, + $6d,$01,$92,$00,$6d,$01); //12*12 + b_crosshatch4_98: array[0..7] of byte = ($88,$55,$22,$55,$88,$55,$22,$55); //8*8 + b_crosshatch5_98: array[0..19] of byte = ($31,$02,$4a,$01,$84,$00,$4a,$01,$31,$02, + $31,$02,$4a,$01,$84,$00,$4a,$01,$31,$02); //10*10 + b_crosshatch6_98: array[0..23] of byte = ($20,$08,$51,$04,$8a,$02,$04,$01,$8a,$02,$51,$04, + $20,$08,$51,$04,$8a,$02,$04,$01,$8a,$02,$51,$04); //12*12 + + {$else} + b_none: array[0..0] of byte = ($00); //1*1 + b_0: array[0..0] of byte = ($00); //1*1 + b_10: array[0..3] of byte = ($01,$00,$08,$00); //6*4 + b_25: array[0..1] of byte = ($01,$04); //4*2 + b_50: array[0..1] of byte = ($01,$02); //2*2 + b_75: array[0..1] of byte = ($0e,$0b); //4*2 + b_90: array[0..3] of byte = ($3e,$3f,$37,$3f); //6*4 + b_100: array[0..0] of byte = ($01); //1*1 + b_block2: array[0..3] of byte = ($03,$03,$0c,$0c); //4*4 + b_block3: array[0..5] of byte = ($07,$07,$07,$38,$38,$38); //6*6 + b_block4: array[0..7] of byte = ($0f,$0f,$0f,$0f,$f0,$f0,$f0,$f0); //8*8 + b_hatchup3: array[0..2] of byte = ($04,$02,$01); //3*3 + b_hatchup4: array[0..3] of byte = ($08,$04,$02,$01); //4*4 + b_hatchup5: array[0..4] of byte = ($10,$08,$04,$02,$01); //5*5 + b_hatchdown3: array[0..2] of byte = ($01,$02,$04); //3*3 + b_hatchdown4: array[0..3] of byte = ($01,$02,$04,$08); //4*4 + b_hatchdown5: array[0..4] of byte = ($01,$02,$04,$08,$10); //5*5 + b_crosshatch3: array[0..2] of byte = ($05,$02,$05); //3*3 + b_crosshatch4: array[0..3] of byte = ($08,$05,$02,$05); //4*4 + b_crosshatch5: array[0..4] of byte = ($11,$0a,$04,$0a,$11); //5*5 + b_crosshatch6: array[0..5] of byte = ($20,$11,$0a,$04,$0a,$11); //6*6 + {$endif} + +function stockobjects: tstockobjects; +begin + if stockobjs = nil then begin + stockobjs:= tstockobjects.create; + application.initialize; //stockdata needs initialized application + end; + result:= stockobjs; +end; + +function sc(const acaption: stockcaptionty): msestring; +begin + result:= stockobjects.captions[acaption]; +end; + +procedure init; +begin +// deinit; + if stockdata = nil then begin + stockdata:= tstockdata.create(nil,true); + end; +end; + +procedure deinit; +begin + freeandnil(stockobjs); + freeandnil(stockdata); +end; + +{ tstockobjects } + +constructor tstockobjects.create; +begin + //dummy +end; + +destructor tstockobjects.destroy; +var + bmps: stockbitmapty; + fonts1: stockfontty; +begin + for bmps:= low(stockbitmapty) to high(stockbitmapty) do begin + fbitmaps[bmps].free; + end; + for fonts1:= low(stockfontty) to high(stockfontty) do begin + ffonts[fonts1].Free; + end; + fglyphs.Free; + inherited; +end; + +function tstockobjects.getbitmaps(index: stockbitmapty): tbitmap; +begin + if fbitmaps[index] = nil then begin + fbitmaps[index]:= tbitmap.create(bmk_mono); + {$ifdef mswindows} + if iswin98 then begin + case index of //must be >= 8*8 for win98 + stb_default,stb_none: fbitmaps[index].loaddata(makesize(8,8),@b_none_98); + stb_dens0: fbitmaps[index].loaddata(makesize(8,8),@b_0_98); + stb_dens10: fbitmaps[index].loaddata(makesize(12,8),@b_10_98); + stb_dens25: fbitmaps[index].loaddata(makesize(8,8),@b_25_98); + stb_dens50: fbitmaps[index].loaddata(makesize(8,8),@b_50_98); + stb_dens75: fbitmaps[index].loaddata(makesize(8,8),@b_75_98); + stb_dens90: fbitmaps[index].loaddata(makesize(12,8),@b_90_98); + stb_dens100: fbitmaps[index].loaddata(makesize(8,8),@b_100_98); + stb_block2: fbitmaps[index].loaddata(makesize(8,8),@b_block2_98); + stb_block3: fbitmaps[index].loaddata(makesize(12,12),@b_block3_98); + stb_block4: fbitmaps[index].loaddata(makesize(8,8),@b_block4_98); + stb_hatchup3: fbitmaps[index].loaddata(makesize(12,12),@b_hatchup3_98); + stb_hatchup4: fbitmaps[index].loaddata(makesize(8,8),@b_hatchup4_98); + stb_hatchup5: fbitmaps[index].loaddata(makesize(10,10),@b_hatchup5_98); + stb_hatchdown3: fbitmaps[index].loaddata(makesize(9,9),@b_hatchdown3_98); + stb_hatchdown4: fbitmaps[index].loaddata(makesize(8,8),@b_hatchdown4_98); + stb_hatchdown5: fbitmaps[index].loaddata(makesize(10,10),@b_hatchdown5_98); + stb_crosshatch3: fbitmaps[index].loaddata(makesize(9,9),@b_crosshatch3_98); + stb_crosshatch4: fbitmaps[index].loaddata(makesize(8,8),@b_crosshatch4_98); + stb_crosshatch5: fbitmaps[index].loaddata(makesize(10,10),@b_crosshatch5_98); + stb_crosshatch6: fbitmaps[index].loaddata(makesize(12,12),@b_crosshatch6_98); + end; + end + else begin + case index of + stb_default,stb_none: fbitmaps[index].loaddata(makesize(1,1),@b_none); + stb_dens0: fbitmaps[index].loaddata(makesize(1,1),@b_0); + stb_dens10: fbitmaps[index].loaddata(makesize(6,4),@b_10); + stb_dens25: fbitmaps[index].loaddata(makesize(4,2),@b_25); + stb_dens50: fbitmaps[index].loaddata(makesize(2,2),@b_50); + stb_dens75: fbitmaps[index].loaddata(makesize(4,2),@b_75); + stb_dens90: fbitmaps[index].loaddata(makesize(6,4),@b_90); + stb_dens100: fbitmaps[index].loaddata(makesize(1,1),@b_100); + stb_block2: fbitmaps[index].loaddata(makesize(4,4),@b_block2); + stb_block3: fbitmaps[index].loaddata(makesize(6,6),@b_block3); + stb_block4: fbitmaps[index].loaddata(makesize(8,8),@b_block4); + stb_hatchup3: fbitmaps[index].loaddata(makesize(3,3),@b_hatchup3); + stb_hatchup4: fbitmaps[index].loaddata(makesize(4,4),@b_hatchup4); + stb_hatchup5: fbitmaps[index].loaddata(makesize(5,5),@b_hatchup5); + stb_hatchdown3: fbitmaps[index].loaddata(makesize(3,3),@b_hatchdown3); + stb_hatchdown4: fbitmaps[index].loaddata(makesize(4,4),@b_hatchdown4); + stb_hatchdown5: fbitmaps[index].loaddata(makesize(5,5),@b_hatchdown5); + stb_crosshatch3: fbitmaps[index].loaddata(makesize(3,3),@b_crosshatch3); + stb_crosshatch4: fbitmaps[index].loaddata(makesize(4,4),@b_crosshatch4); + stb_crosshatch5: fbitmaps[index].loaddata(makesize(5,5),@b_crosshatch5); + stb_crosshatch6: fbitmaps[index].loaddata(makesize(6,6),@b_crosshatch6); + end; + end; + {$else} + case index of + stb_default,stb_none: fbitmaps[index].loaddata(makesize(1,1),@b_none); + stb_dens0: fbitmaps[index].loaddata(makesize(1,1),@b_0); + stb_dens10: fbitmaps[index].loaddata(makesize(6,4),@b_10); + stb_dens25: fbitmaps[index].loaddata(makesize(4,2),@b_25); + stb_dens50: fbitmaps[index].loaddata(makesize(2,2),@b_50); + stb_dens75: fbitmaps[index].loaddata(makesize(4,2),@b_75); + stb_dens90: fbitmaps[index].loaddata(makesize(6,4),@b_90); + stb_dens100: fbitmaps[index].loaddata(makesize(1,1),@b_100); + stb_block2: fbitmaps[index].loaddata(makesize(4,4),@b_block2); + stb_block3: fbitmaps[index].loaddata(makesize(6,6),@b_block3); + stb_block4: fbitmaps[index].loaddata(makesize(8,8),@b_block4); + stb_hatchup3: fbitmaps[index].loaddata(makesize(3,3),@b_hatchup3); + stb_hatchup4: fbitmaps[index].loaddata(makesize(4,4),@b_hatchup4); + stb_hatchup5: fbitmaps[index].loaddata(makesize(5,5),@b_hatchup5); + stb_hatchdown3: fbitmaps[index].loaddata(makesize(3,3),@b_hatchdown3); + stb_hatchdown4: fbitmaps[index].loaddata(makesize(4,4),@b_hatchdown4); + stb_hatchdown5: fbitmaps[index].loaddata(makesize(5,5),@b_hatchdown5); + stb_crosshatch3: fbitmaps[index].loaddata(makesize(3,3),@b_crosshatch3); + stb_crosshatch4: fbitmaps[index].loaddata(makesize(4,4),@b_crosshatch4); + stb_crosshatch5: fbitmaps[index].loaddata(makesize(5,5),@b_crosshatch5); + stb_crosshatch6: fbitmaps[index].loaddata(makesize(6,6),@b_crosshatch6); + end; + {$endif} + end; + result:= fbitmaps[index]; +end; + +procedure tstockobjects.fontchanged(const sender: tobject); +var + int1: integer; +begin + with application do begin + for int1:= 0 to windowcount - 1 do begin + with twidget1(windows[int1].owner) do begin + fontchanged; + end; + end; + end; +end; + +function tstockobjects.getfonts(index: stockfontty): twidgetfont; +var + fo1: stockfontty; + str1: string; +begin + if not ffontaliasregistered then begin + for fo1:= low(stockfontty) to high(stockfontty) do begin + case fo1 of + stf_default: begin + str1:= ''; + end; + else begin + str1:= 'stf_default'; + end; + end; + registerfontalias(getenumname(typeinfo(stockfontty),ord(fo1)), + gui_getdefaultfontnames[fo1],fam_nooverwrite,0,0,[],1.0,str1); + end; + ffontaliasregistered:= true; + end; + if ffonts[index] = nil then begin + ffonts[index]:= twidgetfont.create; + ffonts[index].name:= getenumname(typeinfo(stockfontty),ord(index)); + ffonts[index].onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; + result:= ffonts[index]; +end; + +function tstockobjects.getglyphs: timagelist; +begin + result:= stockdata.glyphs; +end; + +function tstockobjects.getmseicon: tmaskedbitmap; +begin + result:= stockdata.mseicon.bitmap; +end; + +procedure tstockobjects.setmseicon(const avalue: tmaskedbitmap); +begin + stockdata.mseicon.bitmap.assign(avalue); +end; + +function tstockobjects.getmodalresulttext(index: modalresultty): msestring; +begin + result:= mseconsts.modalresulttext(index); +// result:= fmodalresulttext[index]; +end; + +function tstockobjects.getmodalresulttextnoshortcut(index: modalresultty): msestring; +begin + result:= mseconsts.modalresulttextnoshortcut(index); +// result:= fmodalresulttextnoshortcut[index]; +end; + +function tstockobjects.getcaptions(index: stockcaptionty): msestring; +begin + result:= stockcaptions(index); +end; + +function tstockobjects.gettextgenerator(index: textgeneratorty): textgeneratorfuncty; +begin + result:= stocktextgenerators(index); +end; + +procedure tstockobjects.paintglyph(const canvas: tcanvas; + const glyph: stockglyphty; const rect: rectty; + const grayed: boolean = false; const color: colorty = cl_glyph; + aalignment: alignmentsty = [al_ycentered,al_xcentered]); +var + colorbefore: colorty; +begin + colorbefore:= canvas.color; + canvas.color:= color; + if grayed then begin + aalignment:= aalignment + [al_grayed]; + end; + glyphs.paint(canvas,integer(glyph),rect,aalignment,color); + canvas.color:= colorbefore; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msestockobjects_mfm.pas b/mseide-msegui/lib/common/kernel/msestockobjects_mfm.pas new file mode 100644 index 0000000..0cf3919 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestockobjects_mfm.pas @@ -0,0 +1,448 @@ +unit msestockobjects_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msestockobjects; + +const + objdata: record size: integer; data: array[0..8604] of byte end = + (size: 8605; data: ( + 84,80,70,48,10,116,115,116,111,99,107,100,97,116,97,9,115,116,111,99, + 107,100,97,116,97,9,98,111,117,110,100,115,95,99,120,3,188,0,9,98, + 111,117,110,100,115,95,99,121,2,85,4,108,101,102,116,3,129,0,3,116, + 111,112,2,57,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,14,116,109,115,101,100,97,116,97,109,111,100,117,108,101,0,10,116,105, + 109,97,103,101,108,105,115,116,6,103,108,121,112,104,115,5,119,105,100,116, + 104,2,15,6,104,101,105,103,104,116,2,15,7,111,112,116,105,111,110,115, + 11,14,98,109,111,95,109,111,110,111,99,104,114,111,109,101,10,98,109,111, + 95,109,97,115,107,101,100,0,5,99,111,117,110,116,2,84,4,108,101,102, + 116,2,32,3,116,111,112,2,40,5,105,109,97,103,101,10,164,23,0,0, + 0,0,0,0,3,0,0,0,150,0,0,0,150,0,0,0,184,11,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,128,0,0,0,0,2,0,0,0,0,0,0,0,0,0,255,129, + 255,192,127,128,1,0,0,0,3,0,0,0,0,0,24,3,0,0,1,129, + 128,64,64,128,3,0,1,128,3,0,0,0,0,0,184,3,112,0,1,129, + 128,64,68,128,7,128,3,192,3,254,15,0,0,0,240,1,248,0,1,129, + 128,64,68,128,15,192,7,224,3,252,7,0,0,0,224,0,248,0,1,129, + 190,64,95,128,31,224,15,240,3,248,3,0,0,0,240,1,248,0,1,129, + 128,64,68,128,15,240,31,224,3,240,1,0,0,0,184,3,112,0,1,129, + 128,64,68,128,7,248,63,192,3,224,0,0,0,0,24,3,0,0,1,129, + 128,64,64,128,3,0,0,128,3,64,0,0,0,0,0,0,0,0,255,129, + 255,192,127,128,1,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,128,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0, + 0,128,8,0,17,0,0,4,8,0,2,0,0,0,96,0,32,0,48,0, + 0,128,12,0,19,0,0,4,14,128,3,0,136,8,224,0,112,0,56,0, + 127,128,14,0,23,0,0,132,15,224,3,0,220,29,224,1,248,0,60,0, + 62,128,15,0,31,96,27,228,15,248,3,0,136,8,224,0,252,1,56,0, + 28,128,14,0,23,96,27,132,15,224,3,0,0,0,96,0,0,0,48,0, + 8,128,12,0,19,0,0,4,14,128,3,0,0,0,32,0,0,0,32,0, + 0,128,8,0,17,0,0,4,8,0,2,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,28,0,0,0,0,0,0,112,0,0,0, + 0,0,192,96,48,192,17,0,0,56,0,0,16,0,4,8,112,0,0,0, + 0,0,224,224,56,240,23,0,0,112,0,0,112,0,28,8,112,0,0,0, + 12,0,112,192,29,48,30,252,31,224,0,0,240,1,124,8,254,131,255,1, + 30,0,56,128,15,24,28,252,31,192,1,0,240,7,252,9,254,131,255,1, + 63,96,28,0,7,24,31,0,0,192,0,0,240,1,124,8,254,131,255,129, + 127,224,14,128,15,24,0,0,0,96,6,0,112,0,28,8,112,0,0,192, + 255,192,7,192,29,16,0,252,31,48,3,0,16,0,4,8,112,0,0,0, + 0,128,3,224,56,48,0,252,31,152,1,0,0,0,0,0,112,0,0,0, + 0,0,1,96,48,96,0,0,0,204,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,128,0,0,0,96,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,14,255,31,120,0,56,0, + 2,128,25,0,0,0,0,0,0,0,0,0,0,7,6,12,252,0,40,0, + 6,0,6,0,0,0,0,0,0,0,0,0,128,3,12,6,134,1,40,0, + 14,0,6,0,0,0,0,0,0,248,3,0,192,1,24,3,3,3,40,0, + 30,0,6,128,4,0,0,0,0,64,0,0,224,0,176,1,3,3,40,0, + 62,0,6,0,3,0,1,192,0,224,0,0,192,0,160,0,3,3,40,0, + 126,0,6,192,15,128,3,192,0,240,1,0,152,1,160,0,3,3,108,0, + 62,0,6,0,3,0,1,0,0,248,3,0,48,3,160,0,134,1,198,0, + 30,0,6,128,4,0,0,0,0,0,0,0,96,6,160,0,252,3,131,1, + 14,0,6,0,0,0,0,0,0,0,0,0,192,12,160,0,120,135,1,3, + 6,0,6,0,0,0,0,0,0,0,0,0,128,1,224,0,0,206,255,7, + 2,128,25,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,15,255,135,255,195, + 255,1,0,0,0,0,0,0,0,0,0,0,0,0,255,159,255,207,255,231, + 255,3,0,0,0,0,0,0,0,0,0,0,0,0,3,152,1,204,0,102, + 0,3,0,0,0,0,0,0,0,0,0,0,0,0,3,152,141,205,192,102, + 0,3,0,0,7,192,7,0,0,248,3,0,0,0,3,152,221,205,224,102, + 28,3,14,128,13,96,12,224,3,8,2,0,240,7,3,152,249,204,112,102, + 62,3,17,192,24,32,8,32,2,8,2,0,224,3,3,152,113,204,56,102, + 62,3,17,64,16,32,8,32,2,8,2,0,192,1,3,152,249,204,28,102, + 62,3,17,192,24,32,8,32,2,8,2,0,128,0,3,152,221,205,14,102, + 28,3,14,128,13,96,12,224,3,8,2,0,240,7,3,152,141,205,6,102, + 0,3,0,0,7,192,7,0,0,248,3,0,0,0,3,152,1,204,0,102, + 0,3,0,0,0,0,0,0,0,0,0,0,0,0,255,159,255,207,255,231, + 255,3,0,0,0,0,0,0,0,0,0,0,0,0,254,15,255,135,255,195, + 255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,248,15,0,0,0,0,16,0, + 0,0,0,0,2,0,0,0,0,4,4,0,8,8,0,0,32,0,56,0, + 0,0,4,0,2,0,0,16,4,8,2,0,8,8,64,0,112,0,108,0, + 8,0,4,0,2,64,4,32,2,16,1,0,8,8,160,0,216,0,198,0, + 8,0,4,0,2,128,2,64,1,160,0,0,8,8,16,1,140,1,131,1, + 62,128,63,224,63,0,1,128,0,64,0,0,8,8,160,0,216,0,198,0, + 8,0,4,0,2,128,2,64,1,160,0,0,8,8,64,0,112,0,108,0, + 8,0,4,0,2,64,4,32,2,16,1,0,8,8,0,0,32,0,56,0, + 0,0,4,0,2,0,0,16,4,8,2,0,248,15,0,0,0,0,16,0, + 0,0,0,0,2,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0, + 0,0,0,0,1,3,2,16,0,24,3,0,128,0,64,0,112,0,0,0, + 0,224,255,192,193,15,14,112,0,24,3,0,64,1,160,0,216,0,254,128, + 255,192,96,240,241,63,62,240,1,24,3,0,32,2,16,1,140,1,68,0, + 65,128,49,252,253,255,254,240,7,24,3,0,240,7,8,2,6,3,40,0, + 34,0,27,240,241,63,62,240,1,24,3,0,0,0,252,7,255,7,16,0, + 20,0,14,192,193,15,14,112,0,24,3,0,0,0,0,0,0,0,0,0, + 8,0,4,0,1,3,2,16,0,24,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,64,0,224, + 227,131,99,224,255,0,0,0,0,0,0,0,0,0,0,6,96,128,96,224, + 193,195,49,80,144,0,0,228,31,230,15,0,0,4,0,6,80,4,81,224, + 227,227,16,73,148,252,127,0,0,230,15,0,1,84,0,3,88,9,90,224, + 247,243,177,73,148,4,64,0,0,0,0,0,7,82,128,3,79,10,79,160, + 227,186,251,72,144,4,92,228,31,0,0,0,31,82,224,1,65,10,73,0, + 65,16,31,200,159,244,75,0,0,230,15,0,127,82,216,1,65,10,81,0, + 0,0,14,8,128,244,75,0,0,230,15,0,31,81,246,1,65,10,97,0, + 65,0,31,8,128,244,75,228,31,0,0,0,7,209,185,1,79,10,79,160, + 227,130,59,200,159,4,92,0,0,0,0,0,129,80,84,1,88,9,216,224, + 247,195,113,8,128,4,64,0,0,230,15,0,128,0,82,1,80,4,80,225, + 227,227,224,200,159,252,127,228,31,230,15,0,0,0,105,1,96,0,96,226, + 193,115,192,9,128,0,0,0,0,0,0,0,0,0,36,1,0,0,0,228, + 227,51,128,248,255,0,0,0,0,0,0,0,0,0,32,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,255,135,255,243, + 168,168,168,168,168,168,168,168,167,167,39,0,252,3,170,138,255,207,255,247, + 255,255,255,255,255,255,255,255,255,255,63,0,4,2,4,132,1,204,0,246, + 255,255,255,255,255,255,255,255,255,255,63,0,4,2,8,130,13,204,6,246, + 255,255,255,255,125,125,125,255,35,35,35,0,228,31,16,129,29,204,14,246, + 0,0,0,255,0,0,0,255,132,132,4,0,36,18,160,128,57,204,28,246, + 255,255,255,255,255,255,255,255,255,255,63,0,36,18,0,128,113,204,56,246, + 0,0,0,255,167,167,167,255,168,168,40,0,36,18,160,128,225,204,112,246, + 0,0,0,255,220,220,220,255,247,247,55,0,252,19,0,128,193,205,224,246, + 39,39,39,255,135,135,135,255,255,255,63,0,32,16,160,128,129,205,192,246, + 255,255,255,255,224,224,224,255,171,171,43,0,32,16,0,128,1,204,0,246, + 255,255,255,255,71,71,71,255,44,44,44,0,224,31,160,128,255,207,255,247, + 171,171,171,255,255,255,255,255,255,255,63,0,0,0,0,0,255,135,255,243, + 255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,160, + 97,97,97,97,247,247,247,255,34,34,34,0,0,0,0,255,0,0,0,255, + 48,48,48,255,255,255,255,255,39,39,39,0,135,135,135,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,90,90,90,255,0,0,0,255, + 0,0,0,255,196,196,196,255,255,255,63,0,71,71,71,255,47,47,47,255, + 248,248,248,255,65,65,65,255,5,5,5,0,182,182,182,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,0,0,0,255, + 167,167,167,255,168,168,168,168,3,3,3,0,188,188,188,188,244,244,244,255, + 186,186,186,255,183,183,183,255,197,197,5,0,255,255,255,255,39,39,39,255, + 135,135,135,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 178,178,178,255,95,95,95,255,17,17,17,0,174,174,174,255,255,255,255,255, + 82,82,82,255,58,58,58,255,255,255,63,0,242,242,242,255,52,52,52,255, + 24,24,24,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,0,0,0,255,167,167,39,0,168,168,168,168,0,0,0,0, + 7,7,7,7,99,99,99,99,156,156,28,0,160,160,160,160,178,178,178,178, + 255,255,255,255,39,39,39,255,135,135,7,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,128,0,0,0,0,2,0,0,0,0,0,0,0,0,0,255,129, + 255,192,127,128,1,0,0,0,3,0,0,0,0,0,24,3,0,0,1,129, + 128,64,64,128,3,0,1,128,3,0,0,0,0,0,184,3,112,0,1,129, + 128,64,68,128,7,128,3,192,3,254,15,0,0,0,240,1,248,0,1,129, + 128,64,68,128,15,192,7,224,3,252,7,0,0,0,224,0,248,0,1,129, + 190,64,95,128,31,224,15,240,3,248,3,0,0,0,240,1,248,0,1,129, + 128,64,68,128,15,240,31,224,3,240,1,0,0,0,184,3,112,0,1,129, + 128,64,68,128,7,248,63,192,3,224,0,0,0,0,24,3,0,0,1,129, + 128,64,64,128,3,0,0,128,3,64,0,0,0,0,0,0,0,0,255,129, + 255,192,127,128,1,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,128,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0, + 0,128,8,0,17,0,0,4,8,0,2,0,0,0,96,0,32,0,48,0, + 0,128,12,0,19,0,0,4,14,128,3,0,136,8,224,0,112,0,56,0, + 127,128,14,0,23,0,0,132,15,224,3,0,220,29,224,1,248,0,60,0, + 62,128,15,0,31,96,27,228,15,248,3,0,136,8,224,0,252,1,56,0, + 28,128,14,0,23,96,27,132,15,224,3,0,0,0,96,0,0,0,48,0, + 8,128,12,0,19,0,0,4,14,128,3,0,0,0,32,0,0,0,32,0, + 0,128,8,0,17,0,0,4,8,0,2,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,28,0,0,0,0,0,0,112,0,0,0, + 0,0,192,96,48,192,17,0,0,56,0,0,16,0,4,8,112,0,0,0, + 0,0,224,224,56,240,23,0,0,112,0,0,112,0,28,8,112,0,0,0, + 12,0,112,192,29,48,30,252,31,224,0,0,240,1,124,8,254,131,255,1, + 30,0,56,128,15,24,28,252,31,192,1,0,240,7,252,9,254,131,255,1, + 63,96,28,0,7,24,31,0,0,192,0,0,240,1,124,8,254,131,255,129, + 127,224,14,128,15,24,0,0,0,96,6,0,112,0,28,8,112,0,0,192, + 255,192,7,192,29,16,0,252,31,48,3,0,16,0,4,8,112,0,0,0, + 0,128,3,224,56,48,0,252,31,152,1,0,0,0,0,0,112,0,0,0, + 0,0,1,96,48,96,0,0,0,204,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,128,0,0,0,96,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,14,255,31,120,0,56,0, + 2,128,25,0,0,0,0,0,0,0,0,0,0,7,6,12,252,0,40,0, + 6,0,6,0,0,0,0,0,0,0,0,0,128,3,12,6,134,1,40,0, + 14,0,6,0,0,0,0,0,0,248,3,0,192,1,24,3,3,3,40,0, + 30,0,6,128,4,0,0,0,0,64,0,0,224,0,176,1,3,3,40,0, + 62,0,6,0,3,0,1,192,0,224,0,0,192,0,160,0,3,3,40,0, + 126,0,6,192,15,128,3,192,0,240,1,0,152,1,160,0,3,3,108,0, + 62,0,6,0,3,0,1,0,0,248,3,0,48,3,160,0,134,1,198,0, + 30,0,6,128,4,0,0,0,0,0,0,0,96,6,160,0,252,3,131,1, + 14,0,6,0,0,0,0,0,0,0,0,0,192,12,160,0,120,135,1,3, + 6,0,6,0,0,0,0,0,0,0,0,0,128,1,224,0,0,206,255,7, + 2,128,25,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,15,255,135,255,195, + 255,1,0,0,0,0,0,0,0,0,0,0,0,0,255,159,255,207,255,231, + 255,3,0,0,0,0,0,0,0,0,0,0,0,0,3,152,1,204,0,102, + 0,3,0,0,0,0,0,0,0,0,0,0,0,0,3,152,141,205,192,102, + 0,3,0,0,7,192,7,0,0,248,3,0,0,0,3,152,221,205,224,102, + 28,3,14,128,13,96,12,224,3,8,2,0,240,7,3,152,249,204,112,102, + 62,3,17,192,24,32,8,32,2,8,2,0,224,3,3,152,113,204,56,102, + 62,3,17,64,16,32,8,32,2,8,2,0,192,1,3,152,249,204,28,102, + 62,3,17,192,24,32,8,32,2,8,2,0,128,0,3,152,221,205,14,102, + 28,3,14,128,13,96,12,224,3,8,2,0,240,7,3,152,141,205,6,102, + 0,3,0,0,7,192,7,0,0,248,3,0,0,0,3,152,1,204,0,102, + 0,3,0,0,0,0,0,0,0,0,0,0,0,0,255,159,255,207,255,231, + 255,3,0,0,0,0,0,0,0,0,0,0,0,0,254,15,255,135,255,195, + 255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,248,15,0,0,0,0,16,0, + 0,0,0,0,2,0,0,0,0,4,4,0,8,8,0,0,32,0,56,0, + 0,0,4,0,2,0,0,16,4,8,2,0,8,8,64,0,112,0,108,0, + 8,0,4,0,2,64,4,32,2,16,1,0,8,8,160,0,216,0,198,0, + 8,0,4,0,2,128,2,64,1,160,0,0,8,8,16,1,140,1,131,1, + 62,128,63,224,63,0,1,128,0,64,0,0,8,8,160,0,216,0,198,0, + 8,0,4,0,2,128,2,64,1,160,0,0,8,8,64,0,112,0,108,0, + 8,0,4,0,2,64,4,32,2,16,1,0,8,8,0,0,32,0,56,0, + 0,0,4,0,2,0,0,16,4,8,2,0,248,15,0,0,0,0,16,0, + 0,0,0,0,2,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0, + 0,0,0,0,1,3,2,16,0,24,3,0,128,0,64,0,112,0,0,0, + 0,224,255,192,193,15,14,112,0,24,3,0,64,1,160,0,216,0,254,128, + 255,192,96,240,241,63,62,240,1,24,3,0,32,2,16,1,140,1,68,0, + 65,128,49,252,253,255,254,240,7,24,3,0,240,7,8,2,6,3,40,0, + 34,0,27,240,241,63,62,240,1,24,3,0,0,0,252,7,255,7,16,0, + 20,0,14,192,193,15,14,112,0,24,3,0,0,0,0,0,0,0,0,0, + 8,0,4,0,1,3,2,16,0,24,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,64,0,224, + 227,131,99,224,255,0,0,0,0,0,0,0,0,0,0,6,96,128,96,224, + 193,195,49,80,144,0,0,228,31,230,15,0,0,4,0,6,80,4,81,224, + 227,227,16,73,148,252,127,0,0,230,15,0,1,84,0,3,88,9,90,224, + 247,243,177,73,148,4,64,0,0,0,0,0,7,82,128,3,79,10,79,160, + 227,186,251,72,144,4,92,228,31,0,0,0,31,82,224,1,65,10,73,0, + 65,16,31,200,159,244,75,0,0,230,15,0,127,82,216,1,65,10,81,0, + 0,0,14,8,128,244,75,0,0,230,15,0,31,81,246,1,65,10,97,0, + 65,0,31,8,128,244,75,228,31,0,0,0,7,209,185,1,79,10,79,160, + 227,130,59,200,159,4,92,0,0,0,0,0,129,80,84,1,88,9,216,224, + 247,195,113,8,128,4,64,0,0,230,15,0,128,0,82,1,80,4,80,225, + 227,227,224,200,159,252,127,228,31,230,15,0,0,0,105,1,96,0,96,226, + 193,115,192,9,128,0,0,0,0,0,0,0,0,0,36,1,0,0,0,228, + 227,51,128,248,255,0,0,0,0,0,0,0,0,0,32,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,255,135,255,243, + 255,255,255,255,255,255,255,255,255,255,63,0,252,3,170,138,255,207,255,247, + 255,255,255,255,255,255,255,255,255,255,63,0,4,2,4,132,1,204,0,246, + 255,255,255,255,255,255,255,255,255,255,63,0,4,2,8,130,13,204,6,246, + 255,255,255,255,255,255,255,255,255,255,63,0,228,31,16,129,29,204,14,246, + 255,255,255,255,255,255,255,255,255,255,63,0,36,18,160,128,57,204,28,246, + 255,255,255,255,255,255,255,255,255,255,63,0,36,18,0,128,113,204,56,246, + 255,255,255,255,255,255,255,255,255,255,63,0,36,18,160,128,225,204,112,246, + 255,255,255,255,255,255,255,255,255,255,63,0,252,19,0,128,193,205,224,246, + 255,255,255,255,255,255,255,255,255,255,63,0,32,16,160,128,129,205,192,246, + 255,255,255,255,255,255,255,255,255,255,63,0,32,16,0,128,1,204,0,246, + 255,255,255,255,255,255,255,255,255,255,63,0,224,31,160,128,255,207,255,247, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,255,135,255,243, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,0,0,0,240, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,11,116,98,105,116,109, + 97,112,99,111,109,112,7,109,115,101,105,99,111,110,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,8,0, + 0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,168,8,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,236,236,236,1,235,235,235, + 1,233,233,233,1,232,232,232,1,231,231,231,1,230,230,230,1,229,229,229, + 1,227,227,227,1,225,222,221,2,224,224,224,1,223,223,223,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,209,209,209, + 1,208,208,208,1,236,236,236,1,235,235,235,1,233,233,233,1,232,232,232, + 1,231,231,231,1,230,230,230,1,229,229,229,1,227,227,227,1,215,140,108, + 1,214,126,89,1,225,164,144,1,229,167,149,1,227,162,144,1,227,165,147, + 1,222,157,135,1,211,119,80,1,216,179,164,1,215,215,215,1,214,214,214, + 1,213,213,213,1,212,212,212,1,211,211,211,1,209,209,209,1,208,208,208, + 1,236,236,236,1,235,235,235,1,233,233,233,1,226,200,189,1,223,193,180, + 1,230,230,230,1,231,210,203,1,231,178,163,1,218,132,97,1,253,249,247, + 1,213,109,68,1,224,100,67,1,223,96,64,1,217,96,58,1,221,139,106, + 1,240,205,190,1,217,125,93,1,223,170,155,1,218,196,190,1,213,213,213, + 1,212,212,212,1,211,211,211,1,209,209,209,1,208,208,208,1,236,236,236, + 1,235,235,235,1,233,233,233,1,217,156,129,1,231,179,156,1,215,131,95, + 1,225,140,112,1,228,119,90,1,214,104,63,1,255,254,254,1,244,221,211, + 1,209,74,30,1,210,42,0,1,223,146,115,1,255,255,255,1,230,170,145, + 1,216,82,44,1,223,114,85,1,223,147,125,1,220,180,169,1,212,212,212, + 1,211,211,211,1,209,209,209,1,208,208,208,1,236,236,236,1,235,235,235, + 1,233,233,233,1,224,194,181,1,236,193,176,1,254,251,250,1,228,163,137, + 1,211,95,53,1,207,58,14,1,235,187,168,1,255,255,255,1,229,166,141, + 1,208,75,32,1,250,239,234,1,255,255,255,1,218,128,93,1,212,39,0, + 1,215,56,17,1,221,94,62,1,223,135,111,1,216,160,140,1,208,131,97, + 1,207,168,151,1,208,208,208,1,236,236,236,1,235,235,235,1,233,233,233, + 1,235,195,183,1,217,126,90,1,255,255,255,2,255,254,254,1,224,147,118, + 1,209,94,51,1,254,252,251,1,251,243,239,1,208,93,50,1,255,255,255, + 2,212,98,60,1,212,95,56,1,209,72,29,1,210,41,0,1,212,97,55, + 1,226,158,131,1,238,203,186,1,207,167,149,1,208,208,208,1,236,236,236, + 1,235,235,235,1,235,213,207,1,234,157,136,1,219,97,59,1,229,165,140, + 1,255,255,255,3,213,104,67,1,221,134,104,1,248,232,225,1,207,80,39, + 1,217,114,81,1,224,148,121,1,207,77,35,1,215,121,85,1,208,81,39, + 1,219,129,95,1,251,241,237,1,251,243,239,1,212,116,77,1,213,191,183, + 1,208,208,208,1,236,236,236,1,235,235,235,1,236,183,167,1,230,121,92, + 1,211,68,25,1,206,75,31,1,236,188,170,1,255,255,255,2,211,100,63, + 1,162,95,77,1,203,90,55,1,175,71,55,1,36,230,224,1,104,151,141, + 1,208,57,24,1,213,108,70,1,247,228,220,1,255,255,255,1,255,253,253, + 1,214,110,71,1,219,109,78,1,219,165,150,1,208,208,208,1,236,236,236, + 1,237,217,211,1,234,155,133,1,224,88,54,1,214,112,73,1,238,196,180, + 1,208,87,44,1,226,154,129,1,229,162,139,1,123,144,124,1,14,255,249, + 1,99,154,151,1,103,150,146,1,14,255,249,1,48,215,209,1,214,100,67, + 1,255,255,255,3,222,141,110,1,210,48,7,1,219,84,50,1,221,141,119, + 1,212,193,187,1,236,236,236,1,237,197,186,1,231,131,105,1,218,60,22, + 1,209,71,30,1,213,99,61,1,206,74,32,1,208,58,23,1,208,60,28, + 1,122,127,122,1,23,244,238,1,151,110,112,1,214,121,124,1,158,107,109, + 1,161,80,80,1,185,75,56,1,231,172,152,1,255,255,255,1,231,172,149, + 1,209,60,24,1,212,37,2,1,215,58,19,1,221,121,94,1,216,176,165, + 1,236,236,236,1,230,165,143,1,216,105,66,1,213,102,62,1,222,139,108, + 1,232,176,155,1,240,206,191,1,246,226,217,1,218,128,96,1,206,28,21, + 1,194,39,46,1,215,181,184,1,213,255,254,1,214,164,168,1,61,199,196, + 1,20,248,242,1,177,90,69,1,209,85,46,1,211,95,56,1,217,117,83, + 1,220,134,101,1,219,130,96,1,213,107,67,1,214,144,121,1,236,236,236, + 1,208,101,55,1,245,223,213,1,255,255,255,5,213,102,71,1,48,214,210, + 1,36,228,224,1,208,115,125,1,214,214,216,1,216,85,97,1,81,173,173, + 1,22,246,241,1,182,71,50,1,225,152,124,1,255,255,255,2,254,250,249, + 1,235,188,169,1,215,118,79,1,215,141,117,1,236,236,236,1,233,162,141, + 1,215,96,55,1,215,112,74,1,242,212,199,1,255,255,255,2,231,172,151, + 1,209,60,35,1,25,242,236,1,14,255,249,1,162,73,87,1,116,128,139, + 1,109,139,146,1,201,32,37,1,195,92,65,1,213,89,60,1,208,85,46, + 1,213,99,65,1,215,107,71,1,209,78,37,1,209,46,4,1,220,93,60, + 1,219,154,136,1,236,236,236,1,237,175,157,1,227,103,71,1,212,39,0, + 1,208,56,17,1,212,95,57,1,210,93,54,1,210,95,56,1,205,83,39, + 1,195,40,36,1,180,75,64,1,184,67,62,1,14,255,249,2,179,99,78, + 1,253,249,247,1,255,255,255,1,245,219,209,1,212,95,58,1,211,39,10, + 1,212,34,3,1,212,39,0,1,220,96,64,1,219,157,139,1,236,236,236, + 1,237,184,169,1,229,114,84,1,212,39,0,1,212,35,3,1,209,53,19, + 1,221,133,103,1,253,247,245,1,210,95,56,1,224,144,119,1,244,220,209, + 1,216,108,79,1,150,90,97,1,168,71,71,1,211,87,52,1,254,253,252, + 1,255,255,255,2,254,253,252,1,224,147,119,1,209,69,29,1,212,39,0, + 1,221,105,76,1,218,165,150,1,236,236,236,1,237,197,186,1,231,131,105, + 1,218,60,22,1,209,51,11,1,223,146,117,1,255,255,255,1,229,161,137, + 1,214,107,72,1,255,255,255,2,241,207,193,1,209,37,17,1,218,126,94, + 1,212,99,63,1,210,96,59,1,250,240,236,1,255,255,255,3,236,192,174, + 1,212,80,38,1,221,121,94,1,216,176,165,1,236,236,236,1,237,217,211, + 1,234,155,133,1,219,87,48,1,220,131,97,1,255,255,255,1,254,251,250, + 1,210,92,52,1,243,214,203,1,255,255,255,2,222,135,108,1,207,36,11, + 1,228,159,135,1,254,252,251,1,219,124,92,1,208,85,44,1,218,123,90, + 1,226,155,129,1,237,195,178,1,245,223,214,1,228,166,140,1,214,121,89, + 1,212,193,187,1,236,236,236,1,235,235,235,1,233,176,157,1,217,127,89, + 1,254,251,250,1,244,220,210,1,219,130,96,1,211,95,55,1,255,255,255, + 2,239,199,185,1,208,84,44,1,208,86,47,1,217,115,83,1,255,255,255, + 2,215,109,73,1,213,30,6,1,211,36,4,1,208,42,2,1,210,68,25, + 1,213,104,66,1,216,154,134,1,208,208,208,1,236,236,236,1,235,235,235, + 1,226,179,162,1,214,116,76,1,214,99,59,1,209,57,13,1,207,47,6, + 1,233,180,159,1,255,255,255,1,230,166,143,1,209,67,31,1,224,146,118, + 1,220,126,95,1,210,76,41,1,253,248,246,1,255,255,255,1,222,138,107, + 1,212,34,4,1,212,36,2,1,212,39,0,1,221,94,61,1,222,145,124, + 1,214,192,185,1,208,208,208,1,236,236,236,1,235,235,235,1,233,233,233, + 1,235,195,183,1,232,144,120,1,224,91,57,1,209,81,38,1,248,230,223, + 1,213,104,66,1,210,46,13,1,209,58,22,1,247,230,223,1,224,147,119, + 1,209,40,7,1,229,165,141,1,255,255,255,1,232,178,156,1,209,41,1, + 1,212,39,0,1,220,87,53,1,222,135,111,1,218,179,167,1,209,209,209, + 1,208,208,208,1,236,236,236,1,235,235,235,1,233,233,233,1,232,232,232, + 1,234,190,177,1,231,144,120,1,217,98,60,1,210,84,40,1,212,39,0, + 1,212,37,2,1,209,45,7,1,232,178,155,1,209,82,40,1,212,34,3, + 1,211,90,49,1,254,253,252,1,240,208,194,1,210,58,14,1,221,94,62, + 1,223,135,111,1,220,175,162,1,211,211,211,1,209,209,209,1,208,208,208, + 1,236,236,236,1,235,235,235,1,233,233,233,1,232,232,232,1,231,231,231, + 1,233,194,182,1,232,156,134,1,228,119,90,1,222,87,53,1,217,59,21, + 1,212,39,0,1,207,67,22,1,210,39,0,1,212,39,0,1,210,47,5, + 1,227,160,134,1,234,187,167,1,217,103,69,1,223,147,125,1,220,180,169, + 1,212,212,212,1,211,211,211,1,209,209,209,1,208,208,208,1,236,236,236, + 1,235,235,235,1,233,233,233,1,232,232,232,1,231,231,231,1,230,230,230, + 1,231,210,203,1,231,178,163,1,230,151,129,1,228,128,101,1,226,111,81, + 1,224,100,68,1,223,96,64,1,223,99,67,1,224,109,79,1,214,111,72, + 1,214,120,82,1,221,163,145,1,218,196,190,1,213,213,213,1,212,212,212, + 1,211,211,211,1,209,209,209,1,208,208,208,1,236,236,236,1,235,235,235, + 1,233,233,233,1,232,232,232,1,231,231,231,1,230,230,230,1,229,229,229, + 1,227,227,227,1,229,209,203,1,229,190,178,1,229,176,161,1,229,167,149, + 1,227,162,144,1,227,165,147,1,226,173,157,1,222,177,162,1,218,193,184, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,209,209,209,1,208,208,208,1,4,108,101,102,116,2,32,3,116,111,112, + 2,8,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstockdata,''); +end. diff --git a/mseide-msegui/lib/common/kernel/msestream.pas b/mseide-msegui/lib/common/kernel/msestream.pas new file mode 100644 index 0000000..98725d3 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestream.pas @@ -0,0 +1,3172 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestream; +{$ifdef FPC} + {$if defined(FPC) and (fpc_fullversion >= 020501)} + {$define mse_fpc_2_6} + {$ifend} + {$ifdef mse_fpc_2_6} + {$define mse_hasvtunicodestring} + {$endif} +{$endif} + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,sysutils,msestrings,msetypes,msethread,msesystypes,msesys, + msereal,mseevent,mseclasses,mseglob{,mseformatstr}; + +const + defaultfilerights = [s_irusr,s_iwusr,s_irgrp,s_iwgrp,s_iroth,s_iwoth]; + defaultdirrights = [s_irusr,s_iwusr,s_ixusr,s_irgrp,s_iwgrp, + s_ixgrp,s_iroth,s_iwoth,s_ixoth]; +type + + tmsefilestream = class; + + cryptoclientstatety = (ccs_open); + cryptoclientstatesty = set of cryptoclientstatety; + cryptohandlerdataty = array[0..32] of pointer; + + tcustomcryptohandler = class; + cryptoclientinfoty = record + stream: tmsefilestream; + link: tcustomcryptohandler; + linkindex: integer; +// chainend: tcustomcryptohandler; +// chainendindex: integer; + { + linkbuf: pbyte; + linkbufsize: integer; + linkbuflength: integer; + linkbufpos: integer; + } + state: cryptoclientstatesty; + handlerdata: cryptohandlerdataty; + end; + pcryptoclientinfoty = ^cryptoclientinfoty; + cryptoclientinfoarty = array of cryptoclientinfoty; + + tcustomcryptohandler = class(tmsecomponent) + private + fclients: cryptoclientinfoarty; + fchain: tcustomcryptohandler; + procedure setchain(const avalue: tcustomcryptohandler); + protected + fchainend: tcustomcryptohandler; + procedure flush(var aclient: cryptoclientinfoty); overload; virtual; + procedure flushchain(var aclient: cryptoclientinfoty); + procedure writeerror(var aclient: cryptoclientinfoty); + procedure readerror(var aclient: cryptoclientinfoty); + procedure finalizeclient(var aclient: cryptoclientinfoty); virtual; + function checkopen(const aindex: integer): pcryptoclientinfoty; + procedure connect(const aclient: tmsefilestream; + const alink: tcustomcryptohandler; const aindex: integer; + out endhandler: tcustomcryptohandler; out endindex: integer); + procedure disconnect({const aclient: tmsefilestream; + const alink: tcustomcryptohandler} + const aindex: integer); + procedure open(var aclient: cryptoclientinfoty); virtual; + procedure close(var aclient: cryptoclientinfoty); virtual; + function read(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; virtual; + function write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; virtual; + function seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; virtual; + function getsize(var aclient: cryptoclientinfoty): int64; virtual; + function getclient(const astream: tmsefilestream): pcryptoclientinfoty; +// function getopenclient(const astream: tmsefilestream): pcryptoclientinfoty; + public + destructor destroy; override; + procedure flush(const astream: tmsefilestream); overload; + function encrypt(const adata: string; const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; + overload; + function encrypt(const adata: pointer; adatalength: integer; + const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; + overload; + function decrypt(const adata: string; const base64: boolean = false): string; + function encrypttext(const atext: msestring; + const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; + function decrypttext(const adata: string; + const base64: boolean = false): msestring; + published + property chain: tcustomcryptohandler read fchain write setchain; + end; + + {$warnings off} + tmsefilestream = class(thandlestream) + private + ffilename: filenamety; + fopenmode: fileopenmodety; + ffilerights: filerightsty; + ftransactionname: filenamety; + fcryptohandler: tcustomcryptohandler; + fendhandler: tcustomcryptohandler; + fendindex: integer; + fismemorystream: boolean; +// function getmemory: pointer; + procedure checkmemorystream; + procedure setcryptohandler(const avalue: tcustomcryptohandler); + function getfilerights: filerightsty; + procedure setfilerights(const avalue: filerightsty); + function getcapacity: ptrint; + protected + fmemorystream: tmemorystream; + procedure setcapacity(const avalue: ptrint); virtual; + procedure sethandle(value: integer); virtual; + procedure closehandle(const ahandle: integer); virtual; + constructor internalcreate(const afilename: filenamety; + const aopenmode: fileopenmodety; + const accessmode: fileaccessmodesty; + const rights: filerightsty; + out error: syserrorty); overload; + function getsize: int64; override; + function inheritedgetsize: int64; + function inheritedread(var buffer; count: longint): longint; + function inheritedwrite(const buffer; count: longint): longint; + function inheritedseek(const offset: int64; + origin: tseekorigin): int64; + function getmemory: pointer; override; + public + constructor create(const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const rights: filerightsty = defaultfilerights); overload; + constructor createtransaction(const afilename: filenamety; + rights: filerightsty = defaultfilerights); overload; + constructor createtempfile(const prefix: filenamety; + out afilename: filenamety); + constructor create(ahandle: integer); overload; virtual; //allways called + constructor create; overload; + //memorystream + constructor create(const aopenmode: fileopenmodety); overload; + //memorystream + constructor createstringcopy(const adata: string); //implies fm_read + destructor destroy; override; + class function trycreate(out ainstance: tmsefilestream; + const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const rights: filerightsty = defaultfilerights): syserrorty; + function releasehandle(): filehandlety override; + function read(var buffer; count: longint): longint; override; + function write(const buffer; count: longint): longint; override; + function seek(const offset: int64; origin: tseekorigin): int64; override; + function readdatastring: string; override; + //read available data + procedure writedatastring(const value: rawbytestring); override; + function isopen: boolean; + property filename: filenamety read ffilename; + property openmode: fileopenmodety read fopenmode; + property transactionname: filenamety read ftransactionname; + function close: boolean; //false on commit error + procedure cancel; //calls close without commit, removes intermediate file + procedure flushbuffer; virtual; + procedure flush; virtual; + + procedure setsize(const newsize: int64); override; + property ismemorystream: boolean read fismemorystream; + procedure clear; virtual; //only for memorystream + property capacity: ptrint read getcapacity write setcapacity; + //only for memorystream +// property memory: pointer read getmemory; //only for memorystream + property filerights: filerightsty read getfilerights write setfilerights; + property cryptohandler: tcustomcryptohandler read fcryptohandler + write setcryptohandler; + end; + {$warnings on} + +const + defaultbuflen = 2048; + minbuflen = 256; + +type + textstreamstatety = (tss_eof,tss_error,tss_notopen,tss_pipeactive,tss_response, + tss_nosigio,tss_unblocked,tss_haslink); + textstreamstatesty = set of textstreamstatety; + + charencodingty = (ce_locale,ce_utf8,ce_ascii,ce_iso8859_1); + //ce_ascii -> 7Bit, + //string and msestrings -> pascalstrings + + tcustombufstream = class(tmsefilestream) + private + finternalbuffer: string; + fbuflen: integer; + fcachedposition: int64; + + fusewritebuffer: boolean; + procedure setusewritebuffer(const avalue: boolean); + function getbufpo: pchar; + protected + fwriting: boolean; + fbuffer: pchar; + bufoffset, bufend: pchar; + fstate: textstreamstatesty; +// procedure setcapacity(const avalue: ptrint); override; + function getnotopen: boolean; + procedure setbuflen(const Value: integer); virtual; + function geteof: boolean; + function readbytes(var buf): integer; virtual; + //reads max. buflen bytes + procedure fillbuffer(); + procedure checkbuffer(); + procedure internalwritebuffer(const buffer; count: longint); + public + constructor create(ahandle: integer); override; + constructor createdata(const adata: rawbytestring); + procedure clear; override; //only for memorystream + + procedure setsize(const newsize: int64); override; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + + procedure flushbuffer; override; + + property buflen: integer read fbuflen write setbuflen default defaultbuflen; + property usewritebuffer: boolean read fusewritebuffer + write setusewritebuffer default false; + property eof: boolean read geteof; + property bufpo: pchar read getbufpo; + procedure skip(const adist: integer); //skips characters + end; + + tbufstream = class(tcustombufstream) + public + end; + + eolflagty = (eolf_linefeed,eolf_returnlinefeed); + eolflagsty = set of eolflagty; + eolstylety = (eol_default,eol_system,eol_unix,eol_windows); + + ttextstream = class(tcustombufstream) + private + fposvorher: int64; + fsearchabortpo: pboolean; + fsearchlinestartpos: longword; + fsearchlinenumber: longword; + fsearchpos: longword; + fsearchfoundpos: longword; + fsearchtext: string; + fsearchtextlower: string; + fsearchtextupper: string; + fsearchoptions: searchoptionsty; + fsearchtextvalid: boolean; + feolstyle: eolstylety; + procedure setsearchtext(const Value: string); + function getmsesearchtext: msestring; + procedure setmsesearchtext(const avalue: msestring); + procedure setsearchoptions(const Value: searchoptionsty); + procedure seteolstyle(const avalue: eolstylety); + protected + fencoding: charencodingty; + feolflags: eolflagsty; + feol: string; + feolm: msestring; + function encode(const value: msestring): string; + function decode(const value: string): msestring; + public + constructor create(ahandle: integer); override; + class function trycreate(out ainstance: ttextstream; + const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const rights: filerightsty = defaultfilerights): syserrorty; + procedure return; //setzt filepointer auf letzte readln position + + procedure writestr(const value: string); //no encoding + procedure writestrln(const value: string); //no encoding + function readstrln(var value: string): boolean; overload; virtual; + //not out, variable address will be checked for nil + //no encoding + procedure writetotext(var dest: text); //no encoding + + procedure write(const value: string); reintroduce; overload; + procedure write(const value: msestring); reintroduce; overload; + procedure write(const value: real); reintroduce; overload; + procedure write(const value: integer); reintroduce; overload; + procedure write(const value: boolean); reintroduce; overload; + procedure write(const values: array of const); reintroduce; overload; + + procedure writeln; overload; + procedure writeln(const value: string); overload; virtual; + procedure writeln(const value: msestring); overload; + procedure writeln(const value: real); overload; + procedure writeln(const value: integer); overload; + procedure writeln(const value: boolean); overload; + procedure writeln(const value: msestringarty); overload; + procedure writeln(const value: stringarty); overload; + procedure writeln(const values: array of const); overload; + + function readln: boolean; overload; + function readln(var value: string): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(var value: msestring): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(out value: integer): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(out value: boolean): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(out value: real): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(out value: msestringarty): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(out value: stringarty): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + + procedure writestrings(const value: stringarty); + procedure writemsestrings(const value: msestringarty); + function readstrings: stringarty; + function readmsestrings: msestringarty; + function readmsedatastring: msestring; //returns remainig data + function readstring(const default: string): string; + //liest string, bringt defaultwert bei fehler + function readinteger(default: integer; min: integer = minint; + max: integer = maxint): integer; + //liest integer, bringt defaultwert bei fehler + function readboolean(default: boolean): boolean; + //liest boolean, bringt defaultwert bei fehler + function readreal(default: real; min: real = -bigreal; + max: real = bigreal): real; + //liest double, bringt defaultwert bei fehler + // begrenzt wert auf min..max + function findnext(const substring: string): boolean; + //positioiniert filepointer auf erstes vorkommen von substring, true wenn gefunden + //wenn nicht gefunden wird filepointer nicht veraendert + //performance verbesserungswuerdig!! + function linecount: integer; + //zaehlt ab aktueller position anzahl linefeeds bis eof + + procedure resetsearch; + function searchnext: boolean; //true wenn gefunden + property nativesearchtext: string read fsearchtext write setsearchtext; + property msesearchtext: msestring read getmsesearchtext + write setmsesearchtext; + property searchoptions: searchoptionsty read fsearchoptions + write setsearchoptions; + property searchpos: longword read fsearchpos write fsearchpos; + property searchfoundpos: longword read fsearchfoundpos; + property searchlinestartpos: longword read fsearchlinestartpos + write fsearchlinestartpos; + property searchlinenumber: longword read fsearchlinenumber + write fsearchlinenumber; + property searchabortpo: pboolean read fsearchabortpo write fsearchabortpo; + + property notopen: boolean read getnotopen; + property encoding: charencodingty read fencoding write fencoding + default ce_locale; + function foundeolstyle: eolstylety; //found by readln + property eolstyle: eolstylety read feolstyle + write seteolstyle default eol_default; + //for writeln, eol_default -> eol_system + end; + + ttextdatastream = class(ttextstream) + private + fquotechar: msechar; + fseparator: msechar; + fforcequote: boolean; + public + constructor create(ahandle: integer); override; + function readcsvstring(out value: msestring): boolean; + //true if lineend + function readcsvvalues(out values: msestringarty): boolean; + //true if lineend + + procedure writerecord(const fields: array of const); overload; + procedure writerecord(const fields: msestringarty); overload; + procedure writerecord(const fields: stringarty); overload; + procedure writerecord(const fields: integerarty); overload; + procedure writerecord(const fields: realarty); overload; + procedure writerecord(const fields: int64arty); overload; + procedure writerecord(const fields: booleanarty); overload; + function readrecord(fields: array of pointer; types: string): boolean; //true if no error + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real + property separator: msechar read fseparator write fseparator default ','; + property quotechar: msechar read fquotechar write fquotechar default '"'; + property forcequote: boolean read fforcequote write fforcequote default false; + end; + + tresourcefilestream = class(tmsefilestream) + public + procedure WriteResourceHeader(resourcetyp: word; + const ResName: string; out FixupInfo: Integer); + end; + + tcryptfilestream = class(tfilestream) //seek nicht erlaubt! + //used to obfuscate ini files, obsolete + private + seed: word; + schluesseln: boolean; + procedure krypt16(var buffer; count: integer); + + public + constructor Create(const aFileName: string; Mode: Word); + + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + //buffer wird veraendert! + end; + + tstringcopystream = class(tmemorystream) + private + fdata: string; + protected + function getmemory: pointer; override; + public + constructor create(const adata: string); + destructor destroy; override; + function readdatastring: string; override; + function write(const Buffer; Count: Longint): Longint; override; + end; + + ttextstringcopystream = class(ttextdatastream) + private + fdata: string; + protected + function getmemory: pointer; override; + public + constructor create(const adata: string); + destructor destroy; override; + function write(const Buffer; Count: Longint): Longint; override; + end; + + tmemorycopystream = class(tmemorystream) + private + protected + public + constructor create(const adata: pointer; const asize: integer); + destructor destroy; override; + function write(const Buffer; Count: Longint): Longint; override; + end; + + tstringbufferstream = class(tmemorystream) + private + fdata: string; + function getdata: string; + protected + function realloc(var newcapacity: ptrint): pointer; override; + public + constructor create(const adata: string); + property data: string read getdata; + end; + + ttextstringbufferstream = class(ttextdatastream) + private + function getdata: string; + public + constructor create(const adata: string; + const aopenmode: fileopenmodety = fm_create); + property data: string read getdata; + end; + +function getnextbufferline(var data: pchar; len: integer): string; + //data = nil -> fertig +function getbufferline(const data: pchar; linenr,len: integer): string; + //1. zeile = 0 +function getkeystring(const data: pchar; len: integer; name: string): string; + //bringt nach '=' folgenden text +procedure setfilenonblock(handle: integer; value: boolean); + +procedure copyvariantarray(const source: array of const; const dest: array of pointer); + +function getrecordtypechars(const fields: array of const): string; + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real + +function encodestring(const value: msestring; + const encoding: charencodingty = ce_utf8): string; +function decodestring(const value: string; + const encoding: charencodingty = ce_utf8): msestring; + +function encoderecord(const fields: array of const; + forcequote: boolean = false; const quotechar: msechar = '"'; + const separator: msechar = ','): msestring; +function decoderecord(const value: msestring; + const fields: array of pointer; const types: string; + const quotechar: msechar = '"'; + const separator: msechar = ','): boolean; overload; + // types: + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real + +function readstreamdatastring(const astream: tstream): string; + //reads from current pos to eof +function readfiledatastring(const afilename: filenamety): string; +function tryreadfiledatastring(const afilename: filenamety; + out adata: string): syserrorty; +procedure writefiledatastring(const afilename: filenamety; const adata: string); +function trywritefiledatastring(const afilename: filenamety; + const adata: string): syserrorty; + +implementation +uses + msefileutils,msebits,{msegui,}sysconst,msesysutils, + msesysintf1,msesysintf,mseformatstr,msefloattostr, + msedatalist,mseapplication,msearrayutils, + {$ifdef UNIX} mselibc, + {$else} windows, + {$endif} + rtlconsts; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ + tmemorystreamcracker = class(tcustommemorystream) + private + FCapacity: Longint; + end; +} +{$ifdef FPC} +type + pboolean = ^boolean; +{$endif} + + {$ifdef MSWINDOWS} + + {$else} + + {$ifdef FPC} //bug in bfcntlh.inc + { +const + O_ACCMODE = $3; + O_RDONLY = $0; + O_WRONLY = $1; + O_RDWR = $2; + O_CREAT = $40; + O_EXCL = $80; + O_NOCTTY = $100; + O_TRUNC = $200; + O_APPEND = $400; + O_NONBLOCK = $800; + O_NDELAY = O_NONBLOCK; + O_SYNC = $1000; + O_FSYNC = O_SYNC; + O_ASYNC = $2000; + + O_DIRECT = $4000; + O_DIRECTORY = $10000; + O_NOFOLLOW = $20000; + + O_DSYNC = O_SYNC; + O_RSYNC = O_SYNC; + + O_LARGEFILE = $8000; + } + {$endif} + {$endif} +const + windowseol = #$0d#$0a; + unixeol = #$0a; + +{$ifdef mswindows} + syseol = windowseol; +{$else} + syseol = unixeol; +{$endif} + +(* + windowseol: array[0..1] of char = (#$0d,#$0a); + unixeol: array[0..0] of char = (#$0a); + + {$ifdef mswindows} + syseol: array[0..1] of char = (#$0d,#$0a); + {$else} + syseol: array[0..0] of char = (#$0a); + {$endif} +*) +const + kryptsignatur = $9617ae3c; +type + tstream1 = class(tstream); + tmemorystream1 = class(tmemorystream); + +function readfiledatastring(const afilename: filenamety): string; +var + stream1: tmsefilestream; +begin + stream1:= tmsefilestream.create(afilename); + try + result:= stream1.readdatastring; + finally + stream1.free; + end; +end; + +function tryreadfiledatastring(const afilename: filenamety; + out adata: string): syserrorty; +var + stream1: tmsefilestream; +begin + adata:= ''; + result:= tmsefilestream.trycreate(stream1,afilename); + if result = sye_ok then begin + try + adata:= stream1.readdatastring; + except + result:= sye_read; + end; + stream1.free; + end; +end; + +procedure writefiledatastring(const afilename: filenamety; const adata: string); +var + stream1: tmsefilestream; +begin + stream1:= tmsefilestream.create(afilename,fm_create); + try + stream1.writedatastring(adata); + finally + stream1.free; + end; +end; + +function trywritefiledatastring(const afilename: filenamety; + const adata: string): syserrorty; +var + stream1: tmsefilestream; +begin + result:= tmsefilestream.trycreate(stream1,afilename,fm_create); + if result = sye_ok then begin + try + stream1.writedatastring(adata); + except + result:= sye_write; + end; + stream1.free; + end; +end; + +function readstreamdatastring(const astream: tstream): string; + //reads from current pos to eof +var + size1: ptrint; + pos1: ptrint; + lint1,lint2: ptrint; +begin + size1:= astream.size-astream.position; + if size1 < 256 then begin + size1:= 256; + end; + setlength(result,size1+1); + pos1:= 0; + while true do begin + lint1:= size1-pos1; + lint2:= astream.read((pchar(pointer(result))+pos1)^,lint1+1); + pos1:= pos1+lint2; + if lint2 <= lint1 then begin + setlength(result,pos1); + break; + end; + size1:= size1 * 2; + setlength(result,size1+1); + end; +end; + +procedure streamerror; +begin + syserror(syelasterror,'Streamerror: '); +end; + + {$ifdef UNIX} +procedure setfilenonblock(handle: integer; value: boolean); +var + int1: integer; +begin + int1:= fcntl(handle,f_getfl,[0]); + if int1 = -1 then begin + streamerror; + end; + if value then begin + int1:= int1 or o_nonblock; + end + else begin + int1:= int1 and not o_nonblock; + end; + if fcntl(handle,f_setfl,[int1]) = -1 then begin + streamerror; + end; +end; + {$else} +procedure setfilenonblock(handle: integer; value: boolean); +begin + raise exception.Create('nonblock not supported'); +end; + {$endif} + +function getnextbufferline(var data: pchar; len: integer): string; + //data = nil -> fertig +var + po1: pchar; + int1: integer; +begin + result:= ''; + po1:= data; + int1:= len; + po1:= strlscan(po1,c_linefeed,int1); + if po1 <> nil then begin + int1:= po1-data; + dec(int1); + if (po1+int1)^ = c_return then begin + dec(int1); + end; + if int1 > 0 then begin + setlength(result,int1); + move(data^,result[1],int1) + end; + inc(po1); + end; + data:= po1; +end; + +function getbufferline(const data: pchar; linenr,len: integer): string; + //1. zeile = 0 +var + po1: pchar; + int1: integer; +begin + result:= ''; + po1:= data; + for int1:= 0 to linenr do begin + result:= getnextbufferline(po1,len-(po1-data)); + end; +end; + +function getkeystring(const data: pchar; len: integer; name: string): string; + //bringt nach '=' folgenden text +var + po1: pchar; +begin + result:= ''; + po1:= data; + name:= name+'='; + while po1 <> nil do begin + result:= getnextbufferline(po1,len-(po1-data)); + if pos(name,result) = 1 then begin + result:= copy(result,length(name)+1,length(result)); + break; + end; + end; +end; + +function encodestring(const value: msestring; + const encoding: charencodingty = ce_utf8): string; +begin + case encoding of + ce_ascii: begin + result:= stringtopascalstring(value); + end; + ce_utf8: begin + result:= stringtoutf8ansi(value); + end; + ce_iso8859_1: begin + result:= stringtolatin1(value); + end; + else begin //ce_locale + result:= ansistring(value); + end; + end; +end; + +function decodestring(const value: string; + const encoding: charencodingty = ce_utf8): msestring; +begin + case encoding of + ce_ascii: begin + result:= pascalstringtostring(value); + end; + ce_utf8: begin + result:= utf8tostringansi(value); + end; + ce_iso8859_1: begin + result:= latin1tostring(value); + end; + else begin //ce_ansi or current locale + result:= msestring(value); + end; + end; +end; + +function encoderecord(const fields: array of const; + forcequote: boolean = false; const quotechar: msechar = '"'; + const separator: msechar = ','): msestring; +var + int1: integer; + mstr1: msestring; + first: boolean; + seps: msestring; +begin + first:= true; + seps:= msechar(c_return) + msestring(c_linefeed) + msestring(quotechar) + separator; + result:= ''; + for int1:= 0 to high(fields) do begin + mstr1:= ''; + with tvarrec(fields[int1]) do begin + case vtype of + vtInteger: mstr1:= inttostrmse(VInteger); + vtBoolean: if VBoolean then mstr1:= 'T' else mstr1:= 'F'; + vtChar: mstr1:= msestring(VChar); + vtExtended: if not (vextended^ = emptyreal) then begin + mstr1:= doubletostring(VExtended^); + end; + vtString: mstr1:= msestring(VString^); + vtWideChar: mstr1:= VWideChar; + vtPChar: mstr1:= msestring(string(VPChar)); + vtPWideChar: mstr1:= msestring(VPWideChar); + vtAnsiString: mstr1:= msestring(ansistring(VAnsiString)); + vtCurrency: mstr1:= currencytostrmse(VCurrency^); + vtWideString: mstr1:= msestring(VWideString); + {$ifdef mse_hasvtunicodestring} + vtunicodeString: mstr1:= msestring(VunicodeString); + {$endif} + vtInt64: mstr1:= inttostrmse(VInt64^); + end; + end; +// escapechars(mstr1); + if (mstr1 <> '') and (quotechar <> #0) then begin + if forcequote or (findchars(mstr1,seps) <> 0) then begin + mstr1:= quotestring(mstr1,quotechar); + end; + end; + if not first then begin + result:= result + separator + mstr1; + end + else begin + result:= result + mstr1; + end; + first:= false; + end; +end; + +procedure copyvariantarray(const source: array of const; const dest: array of pointer); +var + int1,int2: integer; +begin + int2:= high(source); + if int2 > high(dest) then begin + int2:= high(dest); + end; + for int1:= 0 to int2 do begin + case source[int1].vtype of + vtInteger: pinteger(dest[int1])^:= source[int1].vinteger; + vtBoolean: pboolean(dest[int1])^:= source[int1].VBoolean; + vtChar: pchar(dest[int1])^:= source[int1].VChar; + vtExtended: preal(dest[int1])^:= source[int1].VExtended^; + vtString: pshortstring(dest[int1])^:= source[int1].VString^; + vtWideChar: pwidechar(dest[int1])^:= source[int1].VWideChar; + vtPChar: ppchar(dest[int1])^:= source[int1].VPChar; + vtPWideChar: ppwidechar(dest[int1])^:= source[int1].VPwideChar; + vtAnsiString: pansistring(dest[int1])^:= ansistring(source[int1].VAnsiString); + vtCurrency: pcurrency(dest[int1])^:= source[int1].Vcurrency^; + vtwidestring: pmsestring(dest[int1])^:= msestring(source[int1].VwideString); + {$ifdef mse_hasvtunicodestring} + vtunicodestring: pmsestring(dest[int1])^:= msestring(source[int1].VunicodeString); + {$endif} + vtInt64: pint64(dest[int1])^:= source[int1].Vint64^; + end; + end; +end; + +function getrecordtypechars(const fields: array of const): string; + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real +var + int1: integer; + ch1: char; +begin + setlength(result,length(fields)); + for int1:= 0 to high(fields) do begin + ch1:= ' '; + case fields[int1].VType of + vtboolean: begin + ch1:= 'b'; + end; + vtinteger: begin + ch1:= 'i'; + end; + vtint64: begin + ch1:= 'I'; + end; + vtansistring: begin + ch1:= 's'; + end; + {$ifdef mse_hasvtunicodestring} + vtunicodestring, + {$endif} + vtwidestring: begin + ch1:= 'S'; + end; + vtextended: begin + ch1:= 'r'; + end; + end; + result[int1+1]:= ch1; + end; +end; + +function decoderecord(const value: msestring; + const fields: array of pointer; const types: string; + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real + const quotechar: msechar = '"'; + const separator: msechar = ','): boolean; +var + ar1: msestringarty; + int1: integer; +begin + result:= true; + ar1:= nil; + if quotechar <> #0 then begin + splitstringquoted(value,ar1,quotechar,separator); + end + else begin + splitstring(value,ar1,separator); + end; + for int1:= 0 to length(types) - 1 do begin + if int1 > high(fields) then begin + result:= false; + break; + end; + if int1 > high(ar1) then begin + break; + end; +// unescapechars(ar1[int1]); + if fields[int1] <> nil then begin + case types[int1+1] of + ' ': begin + end; + 'b': begin + if ar1[int1] = 'T' then begin + pboolean(fields[int1])^:= true; + end + else begin + pboolean(fields[int1])^:= false; + end; + end; + 'i': begin + result:= result and trystrtoint(ar1[int1],pinteger(fields[int1])^); + end; + 'I': begin + result:= result and trystrtoint64(ar1[int1],pint64(fields[int1])^); + end; + 'r': begin + if ar1[int1] = '' then begin + preal(fields[int1])^:= emptyreal; + end + else begin + result:= result and trystrtoreal(ar1[int1],preal(fields[int1])^); + end; + end; + 's': begin + pstring(fields[int1])^:= ansistring(ar1[int1]); + end; + 'S': begin + pmsestring(fields[int1])^:= ar1[int1]; + end; + else begin + result:= false; + end; + end; + end; + end; +end; + +{ tmsefilestream } + +constructor tmsefilestream.create(ahandle: integer); //allways called +begin + ffilerights:= defaultfilerights; + inherited create(ahandle); +end; + +constructor tmsefilestream.create; +begin + if fmemorystream = nil then begin + fmemorystream:= tmemorystream.create; + end; + fismemorystream:= true; + create(invalidfilehandle); +end; + +constructor tmsefilestream.create(const aopenmode: fileopenmodety); +begin + fopenmode:= aopenmode; + create; +end; + +constructor tmsefilestream.createstringcopy(const adata: string); +begin + fmemorystream:= tstringcopystream.create(adata); + create(fm_read); +end; + +constructor tmsefilestream.internalcreate(const afilename: filenamety; + const aopenmode: fileopenmodety; + const accessmode: fileaccessmodesty; + const rights: filerightsty; + out error: syserrorty); +var + ahandle: integer; +begin + ffilename:= filepath(afilename); + fopenmode:= aopenmode; + if openmode = fm_append then begin + error:= sys_openfile(ffilename,fm_readwrite,accessmode,rights,ahandle); + if error <> sye_ok then begin + error:= sys_openfile(ffilename,fm_create,accessmode,rights,ahandle); + end; + end + else begin + error:= sys_openfile(ffilename,aopenmode,accessmode,rights,ahandle); + end; + create(ahandle); + if error = sye_ok then begin + if aopenmode = fm_append then begin + position:= size; + end; + end + else begin + end; +end; + +class function tmsefilestream.trycreate(out ainstance: tmsefilestream; + const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const rights: filerightsty = defaultfilerights): syserrorty; +begin + ainstance:= internalcreate(afilename,aopenmode,accessmode,rights,result); + if result <> sye_ok then begin + freeandnil(ainstance); + (* + {$ifdef FPC} + freeandnil(self); + {$else} + application.releaseobject(self); + {$endif} + *) + end; +end; + +function tmsefilestream.releasehandle(): filehandlety; +begin + flushbuffer(); + result:= inherited releasehandle(); +end; + +constructor tmsefilestream.create(const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const Rights: filerightsty = defaultfilerights); + //!!!!todo linux lock +var + mstr1: msestring; + error: syserrorty; +begin + internalcreate(afilename,aopenmode,accessmode,rights,error); + if error <> sye_ok then begin + mstr1:= ffilename; + ffilename:= ''; + if aopenmode in [fm_create,fm_append] then begin +{$ifdef FPC} + raise EFCreateError.CreateFmt(SFCreateError+lineend+'%s',[mstr1, + sys_geterrortext(mselasterror)]); +{$else} + + {$if rtlversion > 14.1} + raise EFCreateError.CreateResFmt(@SFCreateErrorEx, + [mstr1, sys_geterrortext(mselasterror)]); + {$else} + raise EFCreateError.CreateResFmt(@SFCreateError, + [mstr1, sys_geterrortext(mselasterror)]); + {$ifend} +{$endif} + end + else begin +{$ifdef FPC} + raise EFCreateError.CreateFmt(SFopenError+lineend+'%s',[mstr1, + sys_geterrortext(mselasterror)]); +{$else} + {$if rtlversion > 14.1} + raise EFOpenError.CreateResFmt(@SFOpenErrorEx, + [mstr1,sys_geterrortext(mselasterror)]); + {$else} + raise EFOpenError.CreateResFmt(@SFOpenError, + [mstr1,sys_geterrortext(mselasterror)]); + {$ifend} +{$endif} + end; + end; +end; + +constructor tmsefilestream.createtransaction(const afilename: filenamety; + rights: filerightsty = defaultfilerights); +begin + if afilename = '' then begin + raise exception.create('No transaction name.'); + end; + ftransactionname:= afilename; + create(intermediatefilename(afilename),fm_create,[fa_denywrite],rights); +end; + +constructor tmsefilestream.createtempfile(const prefix: filenamety; + out afilename: filenamety); +begin + application.lock; + try + create(intermediatefilename(msegettempdir+prefix),fm_create,[], + [msesys.s_irusr,msesys.s_iwusr]); + afilename:= filename; + finally + application.unlock; + end; +end; + +destructor tmsefilestream.Destroy; +begin + close; + cryptohandler:= nil; + inherited Destroy; + fmemorystream.Free; +end; + +procedure tmsefilestream.closehandle(const ahandle: integer); +begin + sys_closefile(ahandle); +end; + +procedure tmsefilestream.sethandle(value: integer); +begin + if value <> handle then begin + if handle <> invalidfilehandle then begin + flushbuffer; + closehandle(handle); + end; + fhandle:= value; + end; +end; + +function tmsefilestream.close: boolean; //false on commit error +begin + result:= true; + if fendhandler <> nil then begin + with fendhandler do begin + if ccs_open in fclients[fendindex].state then begin + try + close(fclients[fendindex]); + except + application.handleexception; + end; + end; + end; + end; + if (handle <> invalidfilehandle) and (ftransactionname <> '') and + (ffilename <> '') then begin + flush; + sethandle(invalidfilehandle); + result:= sys_renamefile(ffilename,ftransactionname) = sye_ok; + end + else begin + sethandle(invalidfilehandle); + end; + ffilename:= ''; + ftransactionname:= ''; +end; + +procedure tmsefilestream.cancel; +var + fstr1: filenamety; +begin + if (ftransactionname <> '') and (ffilename <> '') then begin + fstr1:= ffilename; + ftransactionname:= ''; + close; + sys_deletefile(fstr1); + end + else begin + close; + end; +end; + +procedure tmsefilestream.flush; +begin + if fendhandler <> nil then begin + fendhandler.flushchain(fendhandler.fclients[fendindex]); + end; + flushbuffer; + if handle <> invalidfilehandle then begin + syserror(sys_flushfile(handle)); + end; +end; + +function tmsefilestream.isopen: boolean; +begin + result:= handle <> invalidfilehandle; +end; + +function tmsefilestream.Read(var Buffer; Count: longint): Longint; +begin +// if fmemorystream <> nil then begin +// result:= fmemorystream.Read(buffer,count); +// end +// else begin + if fendhandler <> nil then begin + with fendhandler do begin + result:= read(checkopen(fendindex)^,buffer,count); + end; + end + else begin + result:= inheritedread(buffer,count); + end; +// end; +end; + +function tmsefilestream.Write(const Buffer; Count: longint): Longint; +begin +// if fmemorystream <> nil then begin +// result:= fmemorystream.Write(Buffer,count); +// end +// else begin + if fendhandler <> nil then begin + with fendhandler do begin + result:= write(checkopen(fendindex)^,buffer,count); + end; + end + else begin + result:= inheritedwrite(buffer,count); + end; +// end; +end; + +function tmsefilestream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin +// if fmemorystream <> nil then begin +// result:= fmemorystream.Seek(offset,origin); +// end +// else begin + if fendhandler <> nil then begin + with fendhandler do begin + result:= seek(checkopen(fendindex)^,offset,origin); + end; + end + else begin + result:= inheritedseek(offset,origin); + end; +// end; +end; + +function tmsefilestream.getsize: int64; +begin + if fendhandler <> nil then begin + with fendhandler do begin + result:= getsize(checkopen(fendindex)^); + end; + end + else begin + result:= inherited getsize; + end; +end; + +function tmsefilestream.readdatastring: string; +var + int1,int2,int3: sizeint; + lint1,lint2: int64; +begin + if fcryptohandler = nil then begin + if fmemorystream <> nil then begin + result:= fmemorystream.readdatastring; + end + else begin + result:= inherited readdatastring; + end; + end + else begin + if fmemorystream <> nil then begin + lint1:= fmemorystream.size; + end + else begin + lint1:= position; + lint2:= inheritedseek(0,soend); //file size + inheritedseek(lint1,sobeginning); + lint1:= lint2-lint1; + end; + setlength(result,lint1-position); + if result = '' then begin + setlength(result,256); //possibly buffered block + end; + int1:= 0; + while true do begin + int3:= length(result)-int1; + if int3 <= 0 then begin + break; + end; + int2:= read((pchar(pointer(result))+int1)^,int3); + int1:= int1 + int2; + if int2 < int3 then begin + break; + end; + setlength(result,length(result)*2); //grow buffer + end; + setlength(result,int1); + end; +end; + +procedure tmsefilestream.writedatastring(const value: rawbytestring); +begin + if (value <> '') or (fcryptohandler <> nil) then begin + writebuffer(pointer(value)^,length(value)); + end; +end; + +procedure tmsefilestream.SetSize(const NewSize: Int64); +begin + if fmemorystream <> nil then begin + fmemorystream.SetSize(newsize); + end + else begin + inherited; + end; +end; + +{ +function tmsefilestream.getmemory: pointer; +begin + result:= fmemorystream.memory; +end; +} +procedure tmsefilestream.checkmemorystream; +begin + if fmemorystream = nil then begin + raise exception.create('Must be memory stream.'); + end; +end; + +procedure tmsefilestream.clear; +begin + checkmemorystream; + fmemorystream.clear; +end; + +procedure tmsefilestream.flushbuffer; +begin + //dummy +end; + +procedure tmsefilestream.setcryptohandler(const avalue: tcustomcryptohandler); +begin +// if fcryptohandler <> nil then begin +// fcryptohandler.disconnect(self,nil); +// end; + if fendhandler <> nil then begin + try + fendhandler.disconnect(fendindex); + except + application.handleexception; + end; + fendhandler:= nil; + end; + fcryptohandler:= avalue; + if fcryptohandler <> nil then begin + fcryptohandler.connect(self,nil,-1,fendhandler,fendindex); + end; +end; + +function tmsefilestream.inheritedread(var buffer; count: longint): longint; +begin + if fmemorystream <> nil then begin + result:= fmemorystream.Read(buffer,count); + end + else begin + result:= sys_read(fhandle,@buffer,count); + end; + if result < 0 then begin + result:= 0; + end; +end; + +function tmsefilestream.inheritedwrite(const buffer; count: longint): longint; +begin + if fmemorystream <> nil then begin + result:= fmemorystream.Write(Buffer,count); + end + else begin + result:= sys_write(fhandle,@buffer,count); + end; + if result < 0 then begin + result:= 0; + end; +end; + +function tmsefilestream.inheritedseek(const offset: int64; + origin: tseekorigin): int64; +begin + if fmemorystream <> nil then begin + result:= fmemorystream.Seek(offset,origin); + end + else begin + result:= inherited seek(offset,origin); + end; +end; + +function tmsefilestream.inheritedgetsize: int64; +begin + result:= inherited getsize; +end; + +function tmsefilestream.getmemory: pointer; +begin + if fmemorystream <> nil then begin + result:= fmemorystream.memory; + end + else begin + result:= inherited getmemory; + end; +end; + +function tmsefilestream.getfilerights: filerightsty; +var + stat1: fileinfoty; +begin + if (fhandle <> invalidfilehandle) and sys_getfdinfo(fhandle,stat1) then begin + result:= fileattributestofilerights(stat1.extinfo1.attributes); + end + else begin + result:= ffilerights; + end; +end; + +procedure tmsefilestream.setfilerights(const avalue: filerightsty); +begin + ffilerights:= avalue; + if fhandle <> invalidfilehandle then begin + sys_setfdrights(fhandle,avalue,ffilename); + end; +end; + +function tmsefilestream.getcapacity: ptrint; +begin + checkmemorystream(); + result:= fmemorystream.capacity; +end; + +procedure tmsefilestream.setcapacity(const avalue: ptrint); +begin + checkmemorystream(); + fmemorystream.capacity:= avalue; +end; + +{ tresourcefilestream} + +procedure TresourcefileStream.WriteResourceHeader(resourcetyp: word; + const ResName: string; out FixupInfo: Integer); +var + HeaderSize: Integer; + Header: array[0..79] of Char; +begin + Byte((@Header[0])^) := $FF; + Word((@Header[1])^) := resourcetyp; + HeaderSize := StrLen(StrUpper(StrPLCopy(pchar(@Header[3]), ResName, 63))) + 10; + Word((@Header[HeaderSize - 6])^) := $1030; + Longint((@Header[HeaderSize - 4])^) := 0; + WriteBuffer(Header, HeaderSize); + FixupInfo := Position; +end; + +{ tcustombufstream } + +constructor tcustombufstream.Create(AHandle: integer); +begin +// bufoffset:= nil; + buflen:= defaultbuflen; + inherited; +end; + +constructor tcustombufstream.createdata(const adata: rawbytestring); +begin + create; + writedatastring(adata); + position:= 0; +end; + +procedure tcustombufstream.flushbuffer; +var + po1: pointer; +begin + if fwriting then begin + fwriting:= false; + if bufoffset <> nil then begin + po1:= bufoffset; + bufoffset:= nil; + internalwritebuffer(fbuffer^,po1-fbuffer); + end; + end; +end; + +procedure tcustombufstream.fillbuffer(); +begin + if ismemorystream then begin + bufoffset:= bufend; + end + else begin + bufend:= fbuffer + readbytes(fbuffer^); + bufoffset:= fbuffer; + end; +end; + +procedure tcustombufstream.checkbuffer(); +begin + if ismemorystream then begin + bufoffset:= fmemorystream.memory + fmemorystream.position1; + bufend:= fmemorystream.memory + fmemorystream.size1; + end + else begin + if bufoffset = nil then begin //buffer ungueltig + fillbuffer(); + end; + end; +end; + +procedure tcustombufstream.internalwritebuffer(const buffer; count: longint); +var + int1: integer; +begin + int1:= inherited write(buffer,count); + if not ismemorystream and (int1 >= 0) and (fcachedposition >= 0) then begin + fcachedposition:= fcachedposition + int1; + end; + if int1 <> count then begin + raise ewriteerror.create(swriteerror); + end; +end; + +function tcustombufstream.write(const buffer; count: longint): integer; +begin + if ismemorystream then begin + result:= inherited write(buffer,count); + end + else begin + if fusewritebuffer then begin + result:= count; + if fwriting and (bufoffset <> nil) then begin + if buflen - (bufoffset - fbuffer) < count then begin + flushbuffer; + end; + end; + if (bufoffset = nil) then begin + if (buflen > count) then begin + move(buffer,fbuffer^,count); + bufoffset:= fbuffer+count; + fwriting:= true; + end + else begin + result:= inherited write(buffer,count); + if (result >= 0) and (fcachedposition >= 0) then begin + fcachedposition:= fcachedposition + result; + end; + end; + end + else begin + if buflen - (bufoffset - fbuffer) >= count then begin + move(buffer,bufoffset^,count); + bufoffset:= bufoffset+count; + fwriting:= true; + end + else begin + result:= inherited write(buffer,count); + if (result >= 0) and (fcachedposition >= 0) then begin + fcachedposition:= fcachedposition + result; + end; + end; + end + end + else begin + result:= inherited write(buffer,count); + if (result >= 0) and (fcachedposition >= 0) then begin + fcachedposition:= fcachedposition + result; + end; + end; + end; +end; +{ +function tcustombufstream.Write(const Buffer; Count: Integer): Longint; +begin + flushbuffer; + bufoffset:= nil; + result:= inherited write(buffer,count); +end; +} + +procedure tcustombufstream.setbuflen(const Value: integer); +begin + if (fbuflen <> value) and not ismemorystream then begin + flushbuffer; + fbuflen:= value; + if fbuflen < minbuflen then begin + fbuflen:= minbuflen; + end; + setlength(finternalbuffer,fbuflen); + fbuffer:= pointer(finternalbuffer); + bufoffset:= nil; + end; +end; + +function tcustombufstream.readbytes(var buf): integer; +begin + result:= inherited read(buf,fbuflen); + if result > 0 then begin + exclude(fstate,tss_eof); + if not ismemorystream and (fcachedposition >= 0) then begin + fcachedposition:= fcachedposition + result; + end; + end; +end; + +function tcustombufstream.geteof: boolean; +begin + result:= fstate * [tss_eof,tss_notopen,tss_error] <> []; +end; + +function tcustombufstream.getnotopen: boolean; +begin + result:= tss_notopen in fstate; +end; + +procedure tcustombufstream.setusewritebuffer(const avalue: boolean); +begin + if not ismemorystream then begin + flushbuffer; + fusewritebuffer:= avalue; + end; +end; + +function tcustombufstream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin + if ismemorystream then begin + result:= inherited seek(offset,origin); + if (origin <> socurrent) or (offset <> 0) then begin + exclude(fstate,tss_eof); + end; + end + else begin + if (origin = sobeginning) and (bufoffset <> nil) and + (fcryptohandler = nil) then begin + // result:= inherited seek(0,socurrent); + result:= fcachedposition; + if result >= 0 then begin + result:= seek(offset-result+(bufend-bufoffset),socurrent); + end; + end + else begin + if (origin = socurrent) and (offset = 0) then begin + result:= fcachedposition; + // result:= inherited seek(offset,origin); + if (bufoffset <> nil) and (result >= 0) then begin + result:= result + (bufoffset-bufend); + end; + end + else begin + flushbuffer; + if (origin = socurrent) and (bufoffset <> nil) then begin + if (offset < fbuffer - bufoffset) or + (offset >= bufend-bufoffset) then begin + result:= inherited seek(offset-(bufend-bufoffset),origin); + fcachedposition:= result; + bufoffset:= nil; + end + else begin + bufoffset:= bufoffset + offset; + result:= inherited seek(0,socurrent); + fcachedposition:= result; + if result >= 0 then begin + result:= result + (bufoffset-bufend); + end; + end; + end + else begin + result:= inherited seek(offset,origin); + fcachedposition:= result; + bufoffset:= nil; + end; + exclude(fstate,tss_eof); + end; + end; + end; +end; + +procedure tcustombufstream.skip(const adist: integer); +begin + seek(adist,socurrent); +end; + +function tcustombufstream.Read(var Buffer; Count: Longint): Longint; + +//var +// int1: integer; +label + endlab; +begin + if ismemorystream then begin + result:= inherited read(buffer,count); + if result > 0 then begin + exclude(fstate,tss_eof); + end; + goto endlab; + end + else begin + flushbuffer; + if bufoffset = nil then begin + if count >= buflen then begin + result:= inherited read(buffer,count); + if result > 0 then begin + exclude(fstate,tss_eof); + if fcachedposition >= 0 then begin + fcachedposition:= fcachedposition + result; + end; + end; + goto endlab; + end + else begin + fillbuffer; + if bufend = fbuffer then begin + result:= 0; + goto endlab; + end; + end; + end; + result:= bufend-bufoffset; + if result > count then begin + result:= count; + end; + move(bufoffset^,buffer,result); + inc(bufoffset,result); + if result < count then begin + bufoffset:= nil; + if not eof then begin + result:= result + read((pchar(@buffer)+result)^,count-result); + end; + end; + endlab: + if result < count then begin + include(fstate,tss_eof); + end; + end; +end; + +procedure tcustombufstream.clear; +begin + inherited; + fstate:= []; + bufoffset:= nil; + bufend:= nil; +end; + +function tcustombufstream.getbufpo: pchar; +var + int1: integer; +begin + if not ismemorystream and + ((bufoffset = nil) or (bufoffset = bufend)) then begin + int1:= readbytes(fbuffer^); + if int1 > 0 then begin + bufend:= fbuffer + int1; + bufoffset:= fbuffer; + end; + end; + result:= bufoffset; +end; + +procedure tcustombufstream.setsize(const newsize: int64); +begin + if not ismemorystream then begin + flushbuffer; + if fcachedposition > newsize then begin + fcachedposition:= newsize; + end; + bufoffset:= nil; + end; + inherited; +end; + +{ tbufstream } + + +{ ttextstream } + +constructor ttextstream.create(ahandle: integer); +begin + eolstyle:= eol_default; + inherited; +end; + +function ttextstream.readstrln(var value: string): boolean; + //true wenn zeile vollstaendig + +var + {int1,}int2,int3: integer; + gefunden: boolean; + po1,po2,pe: pchar; + +begin + if (tss_eof in fstate) then begin + raise EInOutError.Create(sendoffile); + end; + flushbuffer; + gefunden:= false; + if @value <> nil then begin + setlength(value,0); + end; + checkbuffer(); + fposvorher:= position{ + (bufend - bufoffset)}; + repeat + po1:= nil; + po2:= bufoffset; + pe:= bufend; + while po2 < pe do begin + if po2^ = c_linefeed then begin + include(feolflags,eolf_linefeed); + po1:= po2; + break; + end; + if (po2^ = c_return) then begin + po1:= po2; + break; + end; + inc(po2); + end; + if po1 <> nil then begin + gefunden:= true; + end + else begin + po1:= bufend; + end; + if @value <> nil then begin + int2:= po1-bufoffset; + if int2 > 0 then begin + int3:= length(value); + setlength(value,int3+int2); + move(bufoffset^,value[int3+1],int2); //anhaengen + end; + end; + if po1 = bufend then begin //noch nicht gefunden + fillbuffer; + end; + until gefunden or (bufoffset = bufend); + + if gefunden then begin + bufoffset:= po1; + end + else begin + bufoffset:= bufend; + end; + + if bufoffset < bufend then begin + inc(bufoffset); + if (bufoffset-1)^ = c_return then begin //return-linefeed entfernen + if bufoffset = bufend then begin + fillbuffer; + end; + if bufoffset < bufend then begin + if bufoffset^ = c_linefeed then begin + include(feolflags,eolf_returnlinefeed); + inc(bufoffset); + if bufoffset = bufend then begin + fillbuffer; + end; + end; + end; + end; + end; + if ismemorystream then begin + fmemorystream.position:= bufoffset-fmemorystream.memory; + end; + result:= gefunden; + updatebit({$ifdef FPC}longword{$else}byte{$endif}(fstate), + ord(tss_eof),not result); +end; + +procedure ttextstream.return; +begin + position:= fposvorher; +end; + +procedure ttextstream.writestr(const value: string); +begin + writebuffer(value[1],length(value)); +end; + +function ttextstream.encode(const value: msestring): string; +begin + result:= msestream.encodestring(value,fencoding); +end; + +function ttextstream.decode(const value: string): msestring; +begin + result:= msestream.decodestring(value,fencoding); +end; + +procedure ttextstream.write(const value: string); +begin + if fencoding = ce_locale then begin + writestr(value); + end + else begin + writestr(encode(msestring(value))); + end; +end; + +procedure ttextstream.write(const value: msestring); +begin + writestr(encode(value)); +end; + +procedure ttextstream.write(const value: real); +begin + write(realtostr(value)); +end; + +procedure ttextstream.write(const value: integer); +begin + write(inttostr(value)); +end; + +procedure ttextstream.write(const value: boolean); +begin + write(booltostr(value)); +end; + +procedure ttextstream.write(const values: array of const); +var + int1: integer; +begin + for int1:= 0 to high(values) do begin + with tvarrec(values[int1]) do begin + case vtype of + vtInteger: write(VInteger); +// vtBoolean : (VBoolean: Boolean); + vtChar: write(string(VChar)); + vtWideChar: write(msestring(VWideChar)); + vtExtended: write(VExtended^); + vtString: write(VString^); +// vtPointer : (VPointer: Pointer); + vtPChar: write(string(VPChar)); +// vtObject : (VObject: TObject); +// vtClass : (VClass: TClass); + vtPWideChar: write(msestring(VPWideChar)); + vtAnsiString: write(string(VAnsiString)); + vtCurrency: write(VCurrency^); + vtVariant: write(msestring(VVariant^)); +// vtInterface : (VInterface: Pointer); + vtWideString: write(msestring(widestring(VWideString))); +// vtInt64 : (VInt64: PInt64); + vtUnicodeString: write(msestring(unicodestring(VUnicodeString))); +// vtQWord : (VQWord: PQWord); + end; + end; + end; +end; + +procedure ttextstream.writeln(const values: array of const); +begin + write(values); + write(feol); +end; + +procedure ttextstream.writestrln(const value: string); +begin + write(value); + write(feol); +end; + +procedure ttextstream.writeln; +begin + write(feol); +end; + +procedure ttextstream.writeln(const value: string); +begin + write(value); + write(feol); +end; + +procedure ttextstream.writeln(const value: msestring); +begin + write(value); + write(feolm); +end; + +procedure ttextstream.writeln(const value: real); +begin + writestrln(realtostr(value)); +end; + +procedure ttextstream.writeln(const value: integer); +begin + writestrln(inttostr(value)); +end; + +procedure ttextstream.writeln(const value: boolean); +begin + writestrln(booltostr(value)); +end; + +procedure ttextstream.writeln(const value: msestringarty); +var + int1: integer; +begin + writeln(length(value)); + for int1:= 0 to high(value) do begin + writeln(value[int1]); + end; +end; + +procedure ttextstream.writeln(const value: stringarty); +var + int1: integer; +begin + writeln(length(value)); + for int1:= 0 to high(value) do begin + writeln(string(value[int1])); + end; +end; + +function ttextstream.readln: boolean; +var + str1: string; +begin + result:= readstrln(str1); +end; + +function ttextstream.readln(var value: string): boolean; +begin + result:= readstrln(value); + if fencoding <> ce_locale then begin + value:= ansistring(decode(value)); + end; +end; + +function ttextstream.readln(var value: msestring): boolean; +var + str1: string; +begin + result:= readstrln(str1); + value:= decode(str1); +end; + +function ttextstream.readln(out value: integer): boolean; +var + str1: string; +begin + result:= readstrln(str1); + value:= strtoint(str1); +end; + +function ttextstream.readln(out value: boolean): boolean; +var + str1: string; +begin + result:= readstrln(str1); + value:= strtobool(str1); +end; + +function ttextstream.readln(out value: real): boolean; +var + str1: string; +begin + result:= readstrln(str1); + value:= strtoreal(str1); +end; + +function ttextstream.readln(out value: msestringarty): boolean; +var + str1: string; + mstr1: msestring; + int1: integer; +begin + result:= readstrln(str1); + if result then begin + int1:= strtoint(str1); + end + else begin + int1:= 0; + end; + setlength(value,int1); + for int1:= 0 to int1-1 do begin + if not result then begin + exit; + end; + result:= readln(mstr1); + value[int1]:= mstr1; + end; +end; + +function ttextstream.readln(out value: stringarty): boolean; +var + str1: string; + int1: integer; +begin + result:= readstrln(str1); + if result then begin + int1:= strtoint(str1); + end + else begin + int1:= 0; + end; + setlength(value,int1); + for int1:= 0 to int1-1 do begin + if not result then begin + exit; + end; + result:= readln(str1); + value[int1]:= str1; + end; +end; + +function ttextstream.readinteger(default: integer; min: integer = minint; + max: integer = maxint): integer; + //liest integer, bringt defaultwert bei fehler +begin + try + readln(result); + if (result < min) then begin + result:= min; + end + else begin + if result > max then begin + result:= max; + end; + end; + except + result:= default; + end; +end; + +function ttextstream.readboolean(default: boolean): boolean; + //liest boolean, bringt defaultwert bei fehler +begin + try + readln(result); + except + result:= default; + end; +end; + +function ttextstream.readreal(default: real; min: real = -bigreal; + max: real = bigreal): real; +begin + try + readln(result); + if (result < min) then begin + result:= min; + end + else begin + if result > max then begin + result:= max; + end; + end; + except + result:= default; + end; +end; + +function ttextstream.readstring(const default: string): string; +begin + try + readln(result); + except + result:= default; + end; +end; + +function ttextstream.findnext(const substring: string): boolean; +var + buffer: string; + int1,len,posstart,posvorher: integer; +begin + len:= length(substring); + result:= false; + posstart:= position; + if len > 0 then begin + setlength(buffer,len); + while true do begin + posvorher:= position; + int1:= read(buffer[1],len); + if int1 < len then begin + position:= posstart; + break; + end; + if buffer = substring then begin + position:= posvorher; + result:= true; + break; + end; + int1:= pos(substring[1],buffer); + if int1 > 0 then begin + position:= posvorher + int1; + end; + end; + end; +end; + +function ttextstream.linecount: integer; +var + po1: ^string; +begin + result:= 0; + po1:= nil; + while readln(string(po1^)) do begin + inc(result); + end; +end; + +function ttextstream.foundeolstyle: eolstylety; +begin + result:= eol_default; + if eolf_linefeed in feolflags then begin + result:= eol_unix; + end; + if eolf_returnlinefeed in feolflags then begin + result:= eol_windows; + end; +end; + +procedure ttextstream.resetsearch; +begin + fsearchlinestartpos:= 0; + fsearchlinenumber:= 0; + fsearchpos:= 0; + fsearchfoundpos:= 0; +end; + +procedure ttextstream.setsearchtext(const Value: string); +begin + fsearchtext := Value; + fsearchtextvalid:= false; +end; + +function ttextstream.getmsesearchtext: msestring; +begin + result:= decode(fsearchtext); +end; + +procedure ttextstream.setmsesearchtext(const avalue: msestring); +begin + setsearchtext(encode(avalue)); +end; + +procedure ttextstream.setsearchoptions(const Value: searchoptionsty); +begin + fsearchoptions := Value; + fsearchtextvalid:= false; +end; + +procedure ttextstream.seteolstyle(const avalue: eolstylety); +begin + case avalue of + eol_unix: begin + feol:= unixeol; + end; + eol_windows: begin + feol:= windowseol; + end; + else begin + feol:= syseol; + end; + end; + feolm:= msestring(feol); +end; + +function ttextstream.searchnext: boolean; +var + bo1: boolean; + ca1: longword; + str1: string; +begin + Position:= fsearchpos; + bo1:= true; + if (so_caseinsensitive in fsearchoptions) and not fsearchtextvalid then begin + fsearchtextupper:= ansiuppercase(fsearchtext); + fsearchtextlower:= ansilowercase(fsearchtext); + fsearchtextvalid:= true; + end; + repeat + if not bo1 then begin + fsearchlinestartpos:= position; + fsearchpos:= fsearchlinestartpos; + inc(fsearchlinenumber); + end + else begin + bo1:= false; + end; +// readln(str1); + readstrln(str1); //no encoding + if so_caseinsensitive in fsearchoptions then begin + ca1:= stringsearch(fsearchtextupper,str1,1,fsearchoptions,fsearchtextlower); + end + else begin + ca1:= stringsearch(fsearchtext,str1,1,fsearchoptions,''); + end; + until (ca1 <> 0) or eof or ((fsearchabortpo <> nil) and fsearchabortpo^); + if ca1 <> 0 then begin + fsearchfoundpos:= fsearchpos + ca1 - 1; + result:= true; + end + else begin + result:= false; + fsearchfoundpos:= Position; + end; + fsearchpos:= fsearchfoundpos + longword(length(fsearchtext)); +end; + +function ttextstream.readstrings: stringarty; +var + int1: integer; + str1: string; +begin + int1:= 0; + result:= nil; + while not eof do begin + if not readln(str1) and (str1 = '') then begin + break; + end; + additem(result,str1,int1); + end; + setlength(result,int1); +end; + +function ttextstream.readmsestrings: msestringarty; +var + int1: integer; + mstr1: msestring; +begin + int1:= 0; + result:= nil; + while not eof do begin + if not readln(mstr1) and (mstr1 = '') then begin + break; + end; + additem(result,mstr1,int1); + end; + setlength(result,int1); +end; + +function ttextstream.readmsedatastring: msestring; //returns remainig data +begin + result:= decode(readdatastring); +end; + +procedure ttextstream.writestrings(const value: stringarty); +var + int1: integer; +begin + for int1:= 0 to high(value) do begin + writeln(string(value[int1])); + end; +end; + +procedure ttextstream.writemsestrings(const value: msestringarty); +var + int1: integer; +begin + for int1:= 0 to high(value) do begin + writeln(value[int1]); + end; +end; + +procedure ttextstream.writetotext(var dest: text); +var + str1: string; +begin + while not eof do begin + readstrln(str1); + system.writeln(dest,str1); + end; +end; + +class function ttextstream.trycreate(out ainstance: ttextstream; + const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const rights: filerightsty = defaultfilerights): syserrorty; +begin + result:= inherited trycreate(tmsefilestream(ainstance),afilename,aopenmode, + accessmode,rights); +end; + +{ ttextdatastream } + +constructor ttextdatastream.create(ahandle: integer); +begin + fseparator:= ','; + fquotechar:= '"'; + inherited; +end; + +procedure ttextdatastream.writerecord(const fields: array of const); +begin + writeln(encoderecord(fields,fforcequote,fquotechar,fseparator)); +end; + +procedure ttextdatastream.writerecord(const fields: msestringarty); +var + ar1: varrecarty; + int1: integer; +begin + setlength(ar1,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + {$ifdef mse_hasvtunicodestring} + vtype:= vtunicodestring; + vunicodestring:= pointer(fields[int1]); + {$else} + vtype:= vtwidestring; + vwidestring:= pointer(fields[int1]); + {$endif} + end; + end; + writerecord(ar1); +end; + +procedure ttextdatastream.writerecord(const fields: stringarty); +var + ar1: varrecarty; + int1: integer; +begin + setlength(ar1,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + vtype:= vtansistring; + vansistring:= pointer(fields[int1]); + end; + end; + writerecord(ar1); +end; + +procedure ttextdatastream.writerecord(const fields: integerarty); +var + ar1: varrecarty; + int1: integer; +begin + setlength(ar1,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + vtype:= vtinteger; + vinteger:= fields[int1]; + end; + end; + writerecord(ar1); +end; + +procedure ttextdatastream.writerecord(const fields: realarty); +var + ar1: varrecarty; + ar2: array of extended; + int1: integer; +// ext1: extended; +begin + setlength(ar1,length(fields)); + setlength(ar2,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + ar2[int1]:= fields[int1]; + vtype:= vtextended; + vextended:= @ar2[int1]; + end; + end; + writerecord(ar1); +end; + +procedure ttextdatastream.writerecord(const fields: int64arty); +var + ar1: varrecarty; + int1: integer; +begin + setlength(ar1,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + vtype:= vtint64; + vint64:= @fields[int1]; + end; + end; + writerecord(ar1); +end; + +procedure ttextdatastream.writerecord(const fields: booleanarty); +var + ar1: varrecarty; + int1: integer; +begin + setlength(ar1,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + vtype:= vtboolean; + vboolean:= fields[int1]; + end; + end; + writerecord(ar1); +end; + +function ttextdatastream.readcsvstring(out value: msestring): boolean; +var + mstr2: msestring; +begin + result:= readln(value); + if odd(countchars(value,fquotechar)) then begin + while not eof do begin + result:= readln(mstr2); + value:= value+lineend+mstr2; + if odd(countchars(mstr2,fquotechar)) then begin + break; + end; + end; + end; +end; + +function ttextdatastream.readrecord(fields: array of pointer; types: string): boolean; + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real +var + mstr1: msestring; +begin + result:= false; + if not (not readcsvstring(mstr1) and (mstr1 = '') and eof) then begin + //check terminating linefeed + result:= decoderecord(mstr1,fields,types,fquotechar,fseparator); + end; +end; + +function ttextdatastream.readcsvvalues(out values: msestringarty): boolean; +var + mstr1: msestring; +begin + result:= readcsvstring(mstr1); + splitstringquoted(mstr1,values,fquotechar,fseparator); +end; + +{ tcryptfilestream } + +constructor tcryptfilestream.Create(const aFileName: string; Mode: Word); +const + schluessel = $51b2; +var + wo1: word; + int1: integer; +begin + inherited; + if mode = fmcreate then begin + int1:= integer(kryptsignatur); + writebuffer(int1,4); + randomize; + repeat + wo1:= random($ffff); + until wo1 <> 0; + seed:= wo1; + wo1:= wo1 xor schluessel; + writebuffer(wo1,2); + end + else begin + readbuffer(int1,4); + if int1 <> integer(kryptsignatur) then begin + raise exception.create(afilename + ' falsches Dateiformat!'); + end; + readbuffer(seed,2); + seed:= seed xor schluessel; + end; + schluesseln:= true; +end; + +function tcryptfilestream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin + result:= 0; //compiler warning + raise exception.create('seek nicht erlaubt!'); +end; + +procedure tcryptfilestream.krypt16(var buffer; count: integer); +const + crcpolynom = $a001; +var + int1,int2: integer; + bo1: boolean; + bytepo: ^byte; +begin + bytepo:= @buffer; + for int2:= count-1 downto 0 do begin + for int1:= 0 to 7 do begin + bo1:= odd(seed); + seed:= seed shr 1; + if bo1 then begin + seed:= seed xor crcpolynom; + end; + end; + bytepo^:= bytepo^ xor seed; + inc(bytepo); + end; +end; + +function tcryptfilestream.Read(var Buffer; Count: Integer): Longint; +begin + result:= inherited read(buffer,count); + if schluesseln then begin + krypt16(buffer,result); + end; +end; + +function tcryptfilestream.Write(const Buffer; Count: Integer): Longint; +var + po: pointer; +begin + if schluesseln then begin + po:= @byte(buffer); + krypt16(po^,count); + end; + result:= inherited write(buffer,count); +end; + +{ tstringcopystream } + +constructor tstringcopystream.create(const adata: string); +begin + fdata:= adata; + inherited create({fm_create}); + if adata <> '' then begin + setpointer(pointer(adata),length(adata)); + end; +end; + +destructor tstringcopystream.destroy; +begin + setpointer(nil,0); + inherited; +end; + +function tstringcopystream.write(const Buffer; Count: Longint): Longint; +begin + result:= 0; +end; + +function tstringcopystream.readdatastring: string; +begin + if position = 0 then begin + result:= fdata; + end + else begin + result:= inherited readdatastring; + end; +end; + +function tstringcopystream.getmemory: pointer; +begin + result:= pointer(fdata); +end; + +{ ttextstringcopystream } + +constructor ttextstringcopystream.create(const adata: string); +begin + fdata:= adata; + inherited create(fm_read); + if adata <> '' then begin + tmemorystream1(fmemorystream).setpointer(pointer(adata),length(adata)); + end; +end; + +destructor ttextstringcopystream.destroy; +begin + tmemorystream1(fmemorystream).setpointer(nil,0); + inherited; +end; + +function ttextstringcopystream.write(const Buffer; Count: Longint): Longint; +begin + result:= 0; +end; + +function ttextstringcopystream.getmemory: pointer; +begin + result:= pointer(fdata); +end; + +{ tmemorycopystream } + +constructor tmemorycopystream.create(const adata: pointer; const asize: integer); +begin + inherited create; + setpointer(adata,asize); +end; + +destructor tmemorycopystream.destroy; +begin + setpointer(nil,0); + inherited; +end; + +function tmemorycopystream.write(const Buffer; Count: Longint): Longint; +begin + result:= 0; +end; + +{ tcustomcryptohandler } + +destructor tcustomcryptohandler.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + chain:= nil; + with fclients[int1] do begin + if (stream <> nil) then begin + if link = nil then begin + with stream do begin + fcryptohandler:= nil; + fendhandler:= nil; +// fcryptoindex:= -1; + end; + end + else begin + link.fchain:= nil; + end; + finalizeclient(fclients[int1]); +// stream:= nil; + end; + end; + end; + inherited; +end; + +procedure tcustomcryptohandler.finalizeclient(var aclient: cryptoclientinfoty); +begin + with aclient do begin + stream:= nil; + end; +end; + +procedure tcustomcryptohandler.connect(const aclient: tmsefilestream; + const alink: tcustomcryptohandler; + const aindex: integer; + out endhandler: tcustomcryptohandler; out endindex: integer); +var + int1,int2,int3: integer; +// ha1: tcustomcryptohandler; +begin + int3:= high(fclients); + int2:= int3+1; + for int1:= 0 to int3 do begin + if fclients[int1].stream = nil then begin + int2:= int1; + break; + end; + end; + if int2 > int3 then begin + setlength(fclients,int2+1); + end; + endindex:= int2; + endhandler:= self; + fillchar(fclients[int2],sizeof(fclients[0]),0); + with fclients[int2] do begin + stream:= aclient; + link:= alink; + linkindex:= aindex; +// state:= []; + end; + if fchain <> nil then begin + fchain.connect(aclient,self,int2,endhandler,endindex); + end; +end; + +procedure tcustomcryptohandler.disconnect({const aclient: tmsefilestream; + const alink: tcustomcryptohandler;} const aindex: integer); +var + po1: pcryptoclientinfoty; +// int1: integer; +begin + po1:= @fclients[aindex]; + with po1^ do begin + if ccs_open in state then begin + close(po1^); + end; + if link <> nil then begin + link.disconnect(linkindex); + end; + finalizeclient(po1^); + end; +(* + if alink = nil then begin + po1:= @fclients[aclient.fcryptoindex]; + with po1^ do begin + if ccs_open in state then begin + close(po1^); + end; + stream:= nil; + end; + fendhandler:= nil; +// aclient.fcryptoindex:= -1; + end + else begin + for int1:= 0 to high(fclients) do begin + with fclients[int1] do begin + if stream = aclient then begin + finalizeclient(fclients[int1]); +// stream:= nil; + end; + end; + end; + if fchain <> nil then begin + fchain.disconnect(aclient,self); + end; + end; + *) +end; + +function tcustomcryptohandler.read(var aclient: cryptoclientinfoty; var buffer; + count: longint): longint; +begin + with aclient do begin + if link = nil then begin + result:= stream.inheritedread(buffer,count); + end + else begin + result:= link.read(link.fclients[linkindex],buffer,count); + end; + end; +end; + +function tcustomcryptohandler.write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; +begin + with aclient do begin + if link = nil then begin + result:= stream.inheritedwrite(buffer,count); + end + else begin + result:= link.write(link.fclients[linkindex],buffer,count); + end; + end; +end; + +function tcustomcryptohandler.seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; +begin + with aclient do begin + if link = nil then begin + result:= stream.inheritedseek(offset,origin); + end + else begin + result:= link.seek(link.fclients[linkindex],offset,origin); + end; + end; +end; + +function tcustomcryptohandler.getsize(var aclient: cryptoclientinfoty): int64; +begin + with aclient do begin + if link = nil then begin + result:= stream.inheritedgetsize; + end + else begin + result:= link.getsize(link.fclients[linkindex]); + end; + end; +end; + +procedure tcustomcryptohandler.open(var aclient: cryptoclientinfoty); +begin + with aclient do begin + include(state,ccs_open); + if link <> nil then begin + link.open(link.fclients[linkindex]); + end; + end; +end; + +procedure tcustomcryptohandler.close(var aclient: cryptoclientinfoty); +begin + with aclient do begin + exclude(state,ccs_open); + if link <> nil then begin + link.close(link.fclients[linkindex]); + end; + end; +end; + +function tcustomcryptohandler.checkopen( + const aindex: integer): pcryptoclientinfoty; +begin + result:= @fclients[aindex]; + with result^ do begin + if not (ccs_open in state) then begin + self.open(result^); + end; + end; +end; + +function tcustomcryptohandler.encrypt(const adata: pointer; + adatalength: integer; const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; +var + stream1: tmsefilestream; +// str1: string; +begin + stream1:= tmsefilestream.create(fm_write); + try + stream1.cryptohandler:= self; + stream1.write(adata^,adatalength); + stream1.cryptohandler:= nil; //flush + with stream1.fmemorystream do begin + if base64 then begin + result:= encodebase64(memory,size,maxlinelength); + end + else begin + setlength(result,size); + move(memory^,pointer(result)^,length(result)); + end; + end; + finally + stream1.free; + end; +end; + +function tcustomcryptohandler.decrypt(const adata: string; + const base64: boolean = false): string; +var + stream1: ttextstringcopystream; + int1: integer; +begin + if base64 then begin + stream1:= ttextstringcopystream.create(decodebase64(adata)); + end + else begin + stream1:= ttextstringcopystream.create(adata); + end; + try + stream1.cryptohandler:= self; + setlength(result,length(adata)); + int1:= stream1.read(pointer(result)^,length(result)); + setlength(result,int1); + finally + stream1.free; + end; +end; + +function tcustomcryptohandler.encrypt(const adata: string; + const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; +begin + result:= encrypt(pointer(adata),length(adata),base64,maxlinelength); +end; + +function tcustomcryptohandler.encrypttext(const atext: msestring; + const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; +begin + result:= encrypt(stringtoutf8ansi(atext),base64,maxlinelength); +end; + +function tcustomcryptohandler.decrypttext(const adata: string; + const base64: boolean = false): msestring; +begin + result:= utf8tostringansi(decrypt(adata,base64)); +end; + +procedure tcustomcryptohandler.setchain(const avalue: tcustomcryptohandler); + + procedure removechain(const ha: tcustomcryptohandler; + const stre: tmsefilestream); + var + int1: integer; + begin + if ha <> nil then begin + with ha do begin + for int1:= 0 to high(fclients) do begin + with fclients[int1] do begin + if stream = stre then begin + stream:= nil; + end; + end; + end; + removechain(ha.chain,stre); + end; + end; + end; + +var + ha1: tcustomcryptohandler; + int1: integer; +begin + ha1:= avalue; + while ha1 <> nil do begin + if ha1 = self then begin + componentexception(self,'Recursive handler chain.'); + end; + ha1:= ha1.chain; + end; + if fchain <> nil then begin + with fchain do begin + for int1:= 0 to high(fclients) do begin + with fclients[int1] do begin + if (stream <> nil) and (link = self) then begin + removechain(fchain,stream); + stream:= nil; + end; + end; + end; + end; + end; + setlinkedvar(avalue,tmsecomponent(fchain)); +end; + +function tcustomcryptohandler.getclient( + const astream: tmsefilestream): pcryptoclientinfoty; +var + ha1: tcustomcryptohandler; + int1: integer; +begin + result:= nil; + ha1:= astream.fendhandler; + int1:= astream.fendindex; + while ha1 <> nil do begin + if ha1 = self then begin + result:= @fclients[int1]; + break; + end; + with ha1.fclients[int1] do begin + ha1:= link; + int1:= linkindex; + end; + end; + if result = nil then begin + componentexception(self,'Client stream not found.'); + end; +end; + +procedure tcustomcryptohandler.writeerror(var aclient: cryptoclientinfoty); +begin + raise ewriteerror.create(swriteerror); +end; + +procedure tcustomcryptohandler.readerror(var aclient: cryptoclientinfoty); +begin + raise ereaderror.create(sreaderror); +end; + +procedure tcustomcryptohandler.flush(var aclient: cryptoclientinfoty); +begin + //dummy +end; + +procedure tcustomcryptohandler.flushchain(var aclient: cryptoclientinfoty); +begin + if ccs_open in aclient.state then begin + flush(aclient); + with aclient do begin + if link <> nil then begin + link.flush(link.fclients[linkindex]); + end; + end; + end; +end; + +procedure tcustomcryptohandler.flush(const astream: tmsefilestream); +var + po1: pcryptoclientinfoty; +begin + po1:= getclient(astream); + if ccs_open in po1^.state then begin + flush(po1^); + end; +end; + +{ tstringbufferstream } + +constructor tstringbufferstream.create(const adata: string); +begin + inherited create(); + fdata:= adata; + setpointer(pointer(fdata),length(fdata)); +end; + +function tstringbufferstream.getdata: string; +begin + capacity:= size; + result:= fdata; +end; + +function tstringbufferstream.realloc(var newcapacity: ptrint): pointer; +begin + if newcapacity > length(fdata) then begin + newcapacity:= 2*newcapacity + 256; + end; + setlength(fdata,newcapacity); + result:= pointer(fdata); +end; + +{ ttextstringbufferstream } + +constructor ttextstringbufferstream.create(const adata: string; + const aopenmode: fileopenmodety = fm_create); +begin + fmemorystream:= tstringbufferstream.create(adata); + inherited create(aopenmode); +end; + +function ttextstringbufferstream.getdata: string; +begin + result:= tstringbufferstream(fmemorystream).data; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msestreaming.pas b/mseide-msegui/lib/common/kernel/msestreaming.pas new file mode 100644 index 0000000..f2c2bbf --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestreaming.pas @@ -0,0 +1,370 @@ +{ MSEgui Copyright (c) 1999-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestreaming; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msetypes,msegraphutils,mseglob; + +type + tasinheritedreader = class; + tasinheritedobjectreader = class(tbinaryobjectreader) + protected +// freader: tasinheritedreader; + procedure findexistingcomponent(child: tcomponent); + public + procedure begincomponent(var flags: tfilerflags; var achildpos: integer; + var compclassname, compname: string); override; + public + constructor create(const areader: tasinheritedreader; const stream: tstream; + const bufsize: integer); + end; + + tasinheritedreader = class(treader) + private + fnewcomp: boolean; + protected + fforceinherited: boolean; + fexistingcomp: tcomponent; + fexistingcompname: string; + function createdriver(stream: tstream; + bufsize: integer): tabstractobjectreader; override; + public + constructor Create(Stream: TStream; BufSize: Integer; + const forceinherited: boolean); + property existingcomp: tcomponent read fexistingcomp; + property newcomp: boolean read fnewcomp write fnewcomp; + end; + +function readshortcutarty(const reader: treader): shortcutarty; +procedure writeshortcutarty(const writer: twriter; const avalue: shortcutarty); +function readrealty(const reader: treader): realty; +//procedure writerealty(const writer: twriter; const value: realty); +function readrectty(const reader: treader): rectty; +procedure writerectty(const writer: twriter; const avalue: rectty); +function readmethod(const reader: treader): tmethod; + +function readrecordcount(const obj: tpersistent; + const recordsize: integer; const stream: tstream): integer; + //erzeugt exception bei ungueltiger laenge; +procedure readrecords(const count,size: integer; const stream: tstream; out data); +procedure writerecords(const count,size: integer; const stream: tstream; const data); + +procedure assignpersistent(source,dest: tpersistent); + //uebertraegt alle published eigenschaften +procedure assigncomponent(source,dest: tcomponent); + //uebertraegt alle published eigenschaften +procedure writecomponentmse(const astream: tstream; const acomp: tcomponent); + +implementation +uses + sysutils,msereal,mseact,mseclasses,msestrings; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +type + tcomponent1 = class(tcomponent); + +{ +function findexistingcomponent(const aname: string; + const aclassname: string; + const areader: tasinheritedreader): boolean; +var + comp1: tcomponent; + ar1: componentarty; + int1: integer; +begin + areader.fexistingcomp:= nil; + comp1:= areader.parent; + if comp1 = nil then begin + comp1:= areader.lookuproot; + end; + if comp1 <> nil then begin + ar1:= getcomponentchildren(comp1,areader.root,true); + for int1:= 0 to high(ar1) do begin + if (ar1[int1].name = aname) and (ar1[int1].classname = aclassname) then begin + areader.fexistingcomp:= ar1[int1]; + break; + end; + end; + end; + result:= areader.fexistingcomp <> nil; +// result:= (areader.lookuproot = nil) or +// (areader.lookuproot.findcomponent(aname) <> nil); +end; +} + +{ tasinheritedobjectreader } + +constructor tasinheritedobjectreader.create(const areader: tasinheritedreader; + const stream: tstream; const bufsize: integer); +begin + freader:= areader; + inherited create(stream,bufsize); +end; + +procedure tasinheritedobjectreader.findexistingcomponent(child: tcomponent); +begin + if (tasinheritedreader(freader).fexistingcomp = nil) and + (stringicompupper(child.name, + tasinheritedreader(freader).fexistingcompname) = 0) then begin + tasinheritedreader(freader).fexistingcomp:= child; + end; +end; + +procedure tasinheritedobjectreader.begincomponent(var flags: tfilerflags; + var achildpos: Integer; var compclassName, compname: string); +var + comp1: tcomponent; +begin + inherited; + tasinheritedreader(freader).fexistingcomp:= nil; + if (tasinheritedreader(freader).lookuproot = nil) or + tasinheritedreader(freader).fforceinherited then begin + include(flags,ffinherited); + end + else begin + comp1:= freader.parent; + tasinheritedreader(freader).fexistingcomp:= nil; + tasinheritedreader(freader).fexistingcompname:= struppercase(compname); + while (tasinheritedreader(freader).fexistingcomp = nil) and (comp1 <> nil) do begin + tcomponent1(freader.parent).getchildren( + {$ifdef FPC}@{$endif}findexistingcomponent,comp1); + if comp1 = freader.root then begin + break; + end; + comp1:= comp1.owner; + end; + if tasinheritedreader(freader).fexistingcomp = nil then begin + tasinheritedreader(freader).fexistingcomp:= freader.lookuproot.findcomponent(compname); + end; + exclude(flags,ffinherited); + if tasinheritedreader(freader).fexistingcomp <> nil then begin + include(flags,ffinherited); + end; + end; +end; + +{ tasinheritedreader } + +constructor tasinheritedreader.Create(Stream: TStream; BufSize: Integer; + const forceinherited: boolean); +begin + fforceinherited:= forceinherited; + inherited create(stream,bufsize); +end; + +function tasinheritedreader.createdriver(stream: tstream; + bufsize: integer): tabstractobjectreader; +begin + result:= tasinheritedobjectreader.create(self,stream, bufsize); +end; + +type + treader1 = class(treader); + twriter1 = class(twriter); + +procedure writecomponentmse(const astream: tstream; const acomp: tcomponent); +var + writer1: twritermse; +begin + writer1:= twritermse.create(astream,4096,false); + try + writer1.writerootcomponent(acomp); + finally + writer1.free; + end; +end; + +function readshortcutarty(const reader: treader): shortcutarty; +var + int1: integer; +begin + reader.readlistbegin; + setlength(result,reader.readinteger); + for int1:= 0 to high(result) do begin + result[int1]:= reader.readinteger; + translateshortcut1(result[int1]); + end; + reader.readlistend; +end; + +procedure writeshortcutarty(const writer: twriter; const avalue: shortcutarty); +var + int1: integer; +begin + writer.writelistbegin; + writer.writeinteger(length(avalue)); + for int1:= 0 to high(avalue) do begin + writer.writeinteger(avalue[int1]); + end; + writer.writelistend; +end; + +function readrealty(const reader: treader): realty; +begin + with reader do begin + if nextvalue = valist then begin + readlistbegin; + result:= readfloat; + if readboolean then begin + result:= emptyreal; + end; + readlistend; + end + else begin + result:= readfloat; + end; + end; +end; + +procedure writerealty(const writer: twriter; const value: realty); +begin + with writer do begin + if value = emptyreal then begin + writelistbegin; + writefloat(0.0); + writeboolean(true); + writelistend; + end + else begin + writefloat(value); + end; + end; +end; + +function readrectty(const reader: treader): rectty; +begin + with reader,result do begin + readlistbegin; + x:= readinteger; + y:= readinteger; + cx:= readinteger; + cy:= readinteger; + readlistend; + end; +end; + +procedure writerectty(const writer: twriter; const avalue: rectty); +begin + with writer,avalue do begin + writelistbegin; + writeinteger(x); + writeinteger(y); + writeinteger(cx); + writeinteger(cy); + writelistend; + end; +end; + +function readmethod(const reader: treader): tmethod; +var + str1: string; +begin + with treader1(reader) do begin + if nextvalue = vanil then begin + result.code:= nil; + result.data:= nil; + readident; + end + else begin + str1:= readident; + result.code:= findmethod(root,str1); + result.data:= root; + end; + end; +end; + +function readrecordcount(const obj: tpersistent; + const recordsize: integer; const stream: tstream): integer; + //erzeugt exception bei ungueltiger laenge; +var + bytecount: longint; +begin + stream.ReadBuffer(bytecount,sizeof(bytecount)); + if bytecount mod recordsize <> 0 then begin + raise ereaderror.Create(obj.GetNamePath+' readrecorderror.'); + end; + result:= bytecount div recordsize; +end; + +procedure readrecords(const count,size: integer; const stream: tstream; out data); +begin + stream.ReadBuffer(data,count*size); +end; + +procedure writerecords(const count,size: integer; const stream: tstream; const data); +var + bytecount: longint; +begin + bytecount:= count*size; + stream.WriteBuffer(bytecount,sizeof(bytecount)); + stream.WriteBuffer(data,bytecount); +end; + +procedure assignpersistent(source,dest: tpersistent); +var + writer: twritermse; + reader: treader; + stream: tmemorystream; +begin + writer:= nil; + reader:= nil; + stream:= tmemorystream.Create; + try + writer:= twritermse.Create(stream,1024,false); + writer.WriteListBegin; +{$warnings off} + twriter1(writer).WriteProperties(source); +{$warnings on} + writer.WriteListEnd; + freeandnil(writer); + stream.Position:= 0; + reader:= treader.Create(stream,1024); + reader.ReadListBegin; + while not reader.endoflist do begin + treader1(reader).Readproperty(dest); + end; + finally + reader.free; + writer.free; + stream.Free; + end; +end; + +procedure assigncomponent(source,dest: tcomponent); +var + stream1: tmemorystream; +begin + stream1:= tmemorystream.Create; + try + writecomponentmse(stream1,source); + stream1.Position:= 0; + stream1.ReadComponent(dest); + finally + stream1.Free; + end; +end; +end. diff --git a/mseide-msegui/lib/common/kernel/msestrings.pas b/mseide-msegui/lib/common/kernel/msestrings.pas new file mode 100644 index 0000000..4d763af --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestrings.pas @@ -0,0 +1,6254 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestrings; +{$ifdef FPC} + {$if defined(FPC) and (fpc_fullversion >= 020501)} + {$define mse_fpc_2_6} + {$ifend} + {$if defined(FPC) and (fpc_fullversion >= 020300)} + {$define mse_fpc_2_3} + {$ifend} + + {$ifdef mse_fpc_2_6} + {$define mse_hasvtunicodestring} + {$endif} + {$ifdef mse_fpc_2_3} + {$define mse_unicodestring} + {$endif} + {$if fpc_fullversion >= 030000} + {$define hascodepage} + {$endif} +{$endif} + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msetypes{$ifdef FPC},strings{$endif},typinfo,sysutils; +{$ifdef FPC} + {$ifndef mse_nounicodestring} + {$if defined(FPC) and (fpc_fullversion >= 020300)} + {$define mse_unicodestring} + {$ifend} + {$endif} + {$ifndef mse_unicodestring} + {$ifdef FPC_WINLIKEWIDESTRING} + {$define msestringsarenotrefcounted} + {$endif} + {$endif} +{$else} + {$ifdef mswindows} + {$define msestringsarenotrefcounted} + {$endif} +{$endif} + +type + stringposty = (sp_left,sp_center,sp_right); + utfoptionty = (uto_storeinvalid); //store invalid utf8 chars in private area + utfoptionsty = set of utfoptionty; + +const + utf16privatebase = $f800; //used to store invalid utf8 chars in filenamety + utf16private = utf16privatebase + 0; + //prefix for private area codepoint, following word is low byte + utf16invalid = utf16privatebase + 1; + //prefix for invalid utf8 byte, following word is data byte + + utferrorchar = char('?'); //single byte only + + {$ifdef mse_unicodestring} + msestringtypekind = tkustring; + {$else} + msestringtypekind = tkwstring; + {$endif} + defaultdelimchars = ' '+c_tab+c_return+c_linefeed; + defaultmsedelimchars = msestring(defaultdelimchars); + +type + doublestringty = record + a,b: string; + end; + pdoublestringty = ^doublestringty; + doublestringarty = array of doublestringty; + + doublemsestringty = record + a,b: msestring; + end; + pdoublemsestringty = ^doublemsestringty; + doublemsestringarty = array of doublemsestringty; + doublemsestringaty = array[0..0] of doublemsestringty; + pdoublemsestringaty = ^doublemsestringaty; + +const + upperchars: array[char] of char = ( + #$00,#$01,#$02,#$03,#$04,#$05,#$06,#$07,#$08,#$09,#$0a,#$0b,#$0c,#$0d,#$0e,#$0f, + #$10,#$11,#$12,#$13,#$14,#$15,#$16,#$17,#$18,#$19,#$1a,#$1b,#$1c,#$1d,#$1e,#$1f, + #$20,#$21,#$22,#$23,#$24,#$25,#$26,#$27,#$28,#$29,#$2a,#$2b,#$2c,#$2d,#$2e,#$2f, + #$30,#$31,#$32,#$33,#$34,#$35,#$36,#$37,#$38,#$39,#$3a,#$3b,#$3c,#$3d,#$3e,#$3f, + #$40,#$41,#$42,#$43,#$44,#$45,#$46,#$47,#$48,#$49,#$4a,#$4b,#$4c,#$4d,#$4e,#$4f, + #$50,#$51,#$52,#$53,#$54,#$55,#$56,#$57,#$58,#$59,#$5a,#$5b,#$5c,#$5d,#$5e,#$5f, + #$60,'A' ,'B' ,'C' ,'D' ,'E' ,'F' ,'G' ,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O' , + 'P' ,'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' ,'X' ,'Y' ,'Z' ,#$7b,#$7c,#$7d,#$7e,#$7f, + #$80,#$81,#$82,#$83,#$84,#$85,#$86,#$87,#$88,#$89,#$8a,#$8b,#$8c,#$8d,#$8e,#$8f, + #$90,#$91,#$92,#$93,#$94,#$95,#$96,#$97,#$98,#$99,#$9a,#$9b,#$9c,#$9d,#$9e,#$9f, + #$a0,#$a1,#$a2,#$a3,#$a4,#$a5,#$a6,#$a7,#$a8,#$a9,#$aa,#$ab,#$ac,#$ad,#$ae,#$af, + #$b0,#$b1,#$b2,#$b3,#$b4,#$b5,#$b6,#$b7,#$b8,#$b9,#$ba,#$bb,#$bc,#$bd,#$be,#$bf, + #$c0,#$c1,#$c2,#$c3,#$c4,#$c5,#$c6,#$c7,#$c8,#$c9,#$ca,#$cb,#$cc,#$cd,#$ce,#$cf, + #$d0,#$d1,#$d2,#$d3,#$d4,#$d5,#$d6,#$d7,#$d8,#$d9,#$da,#$db,#$dc,#$dd,#$de,#$df, + #$e0,#$e1,#$e2,#$e3,#$e4,#$e5,#$e6,#$e7,#$e8,#$e9,#$ea,#$eb,#$ec,#$ed,#$ee,#$ef, + #$f0,#$f1,#$f2,#$f3,#$f4,#$f5,#$f6,#$f7,#$f8,#$f9,#$fa,#$fb,#$fc,#$fd,#$fe,#$ff); + + lowerchars: array[char] of char = ( + #$00,#$01,#$02,#$03,#$04,#$05,#$06,#$07,#$08,#$09,#$0a,#$0b,#$0c,#$0d,#$0e,#$0f, + #$10,#$11,#$12,#$13,#$14,#$15,#$16,#$17,#$18,#$19,#$1a,#$1b,#$1c,#$1d,#$1e,#$1f, + #$20,#$21,#$22,#$23,#$24,#$25,#$26,#$27,#$28,#$29,#$2a,#$2b,#$2c,#$2d,#$2e,#$2f, + #$30,#$31,#$32,#$33,#$34,#$35,#$36,#$37,#$38,#$39,#$3a,#$3b,#$3c,#$3d,#$3e,#$3f, + #$40,'a' ,'b' ,'c' ,'d' ,'e' ,'f' ,'g' ,'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o' , + 'p' ,'q' ,'r' ,'s' ,'t' ,'u' ,'v' ,'w' ,'x' ,'y' ,'z' ,#$5b,#$5c,#$5d,#$5e,#$5f, + #$60,#$61,#$62,#$63,#$64,#$65,#$66,#$67,#$68,#$69,#$6a,#$6b,#$6c,#$6d,#$6e,#$6f, + #$70,#$71,#$72,#$73,#$74,#$75,#$76,#$77,#$78,#$79,#$7a,#$7b,#$7c,#$7d,#$7e,#$7f, + #$80,#$81,#$82,#$83,#$84,#$85,#$86,#$87,#$88,#$89,#$8a,#$8b,#$8c,#$8d,#$8e,#$8f, + #$90,#$91,#$92,#$93,#$94,#$95,#$96,#$97,#$98,#$99,#$9a,#$9b,#$9c,#$9d,#$9e,#$9f, + #$a0,#$a1,#$a2,#$a3,#$a4,#$a5,#$a6,#$a7,#$a8,#$a9,#$aa,#$ab,#$ac,#$ad,#$ae,#$af, + #$b0,#$b1,#$b2,#$b3,#$b4,#$b5,#$b6,#$b7,#$b8,#$b9,#$ba,#$bb,#$bc,#$bd,#$be,#$bf, + #$c0,#$c1,#$c2,#$c3,#$c4,#$c5,#$c6,#$c7,#$c8,#$c9,#$ca,#$cb,#$cc,#$cd,#$ce,#$cf, + #$d0,#$d1,#$d2,#$d3,#$d4,#$d5,#$d6,#$d7,#$d8,#$d9,#$da,#$db,#$dc,#$dd,#$de,#$df, + #$e0,#$e1,#$e2,#$e3,#$e4,#$e5,#$e6,#$e7,#$e8,#$e9,#$ea,#$eb,#$ec,#$ed,#$ee,#$ef, + #$f0,#$f1,#$f2,#$f3,#$f4,#$f5,#$f6,#$f7,#$f8,#$f9,#$fa,#$fb,#$fc,#$fd,#$fe,#$ff); + +type + lstringty = record + po: pchar; + len: integer; + end; + plstringty = ^lstringty; + + lmsestringty = record + po: pmsechar; + len: integer; + end; + plmsestringty = ^lmsestringty; + + lstringarty = array of lstringty; + lmsestringarty = array of lmsestringty; + + stringheaderty = packed record +{$ifdef hascodepage} + CodePage: TSystemCodePage; + ElementSize: Word; + {$ifdef CPU64} { align fields } + Dummy: DWord; + {$endif CPU64} +{$endif} + ref: sizeint; + len: sizeint; + end; + + pstringheaderty = ^stringheaderty; + +const + emptylstring: lstringty = (po: nil; len: 0); + emptywstring: lmsestringty = (po: nil; len: 0); + +type + tmemorystringstream = class(tmemorystream) + //has room for stringheader + protected + procedure SetCapacity(NewCapacity: PtrInt) override; + function getcapacity: ptrint override; + function getmemory: pointer; override; + Function GetSize : Int64; Override; + function GetPosition: Int64; Override; + public + constructor create; + procedure SetSize({$ifdef CPU64}const{$endif CPU64} NewSize: PtrInt); override; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + procedure destroyasstring(out data: string); + //calls destroy, not possible to use as destructor in FPC + end; + + searchoptionty = (so_caseinsensitive,so_wholeword,so_wordstart,so_backward); + searchoptionsty = set of searchoptionty; + +procedure trimright1(var s: string); overload; +procedure trimright1(var s: msestring); overload; + +function removechar(const source: string; a: char): string; overload; +function removechar(const source: msestring; a: msechar): msestring; overload; +procedure removechar1(var dest: string; a: char); overload; +procedure removechar1(var dest: msestring; a: msechar); overload; + //removes all a +function printableascii(const source: string): string; overload; + //removes all nonprintablechars and ' ' +function printableascii(const source: msestring): msestring; overload; + //removes all nonprintablechars and ' ' + +function replacechar(const source: string; old,new: char): string; overload; +function replacechar(const source: msestring; old,new: msechar): msestring; overload; +procedure replacechar1(var dest: string; old,new: char); overload; +procedure replacechar1(var dest: msestring; old,new: msechar); overload; + //replaces old by new +function stringfromchar(achar: char; count : integer): string; overload; +function stringfromchar(achar: msechar; count : integer): msestring; overload; + +function replacetext(const source: string; index: integer; + a: string): string; overload; +function replacetext(const source: msestring; index: integer; + a: msestring): msestring; overload; +procedure replacetext1(var dest: string; index: integer; + const a: string); overload; +procedure replacetext1(var dest: msestring; index: integer; const a: msestring); overload; + +procedure addstringsegment(var dest: msestring; const a,b: pmsechar); + //add text from a^ to (b-1)^ to dest +function stringsegment(a,b: pchar): string; +function stringsegment(a,b: pmsechar): msestring; + +function lstringtostring(const value: lmsestringty): msestring; overload; +function lstringtostring(const value: pmsechar; + const len: integer): msestring; overload; +function lstringtostring(const value: lstringty): string; overload; +function lstringtostring(const value: pchar; + const len: integer): string; overload; +procedure stringtolstring(const value: string; + var{out} res: lstringty); inline; //todo!!!!! fpbug 3221 +procedure stringtolstring(const value: msestring; + var{out} res: lmsestringty); inline; +function stringtolstring(const value: string): lstringty; inline; +function stringtolstring(const value: msestring): lmsestringty; inline; +function lstringartostringar(const value: lstringarty): stringarty; + +procedure nextword(const value: msestring; out res: lmsestringty); overload; +procedure nextword(const value: string; out res: lstringty); overload; +procedure nextword(var value: lmsestringty; out res: lmsestringty); overload; +procedure nextword(var value: lstringty; out res: lstringty); overload; +procedure nextword(var value: lstringty; out res: string); overload; +function nextword(var start: pchar): string; overload; +function nextword(var start: pmsechar): msestring; overload; + +function nextquotedstring(var value: lstringty; out res: string): boolean; + //false wenn kein quote vorhanden +procedure lstringgoback(var value: lstringty; const res: lstringty); +function issamelstring(const value: lmsestringty; const key: msestring; + caseinsensitive: boolean = false): boolean; overload; + //nur ascii caseinsens. +function issamelstring(const value: lstringty; const key: string; + caseinsensitive: boolean = false): boolean; overload; + //nur ascii caseinsens. +function lstringcomp(const a,b: lstringty): integer; overload; +function lstringcomp(const a: lstringty; const b: string): integer; overload; +function lstringicomp(const a,b: lstringty): integer; overload; + //ascii case insensitive +function lstringicomp(const a: lstringty; const b: string): integer; overload; + //ascii case insensitive +function lstringicompupper(const a,upper: lstringty): integer; overload; + //ascii case insensitive, upper must be uppercase +function lstringicompupper(const a: lstringty; const upper: string): integer; overload; + //ascii case insensitive, upper must be uppercase + +function stringcomp(const a,b: string): integer; +function stringicomp(const a,b: string): integer; + //ascii case insensitive +function stringicompupper(const a,upstr: string): integer; + //ascii case insensitive, b must be uppercase + +function msestringcomp(const a,b: msestring): integer; +function msestringicomp(const a,b: msestring): integer; + //ascii case insensitive +function msestringicompupper(const a,upstr: msestring): integer; + //ascii case insensitive, upstr must be uppercase + +function comparestrlen(const S1,S2: string): integer; + //case sensitiv, beruecksichtigt nur s1 laenge +function msecomparestrlen(const S1,S2: msestring): integer; + //case sensitiv, beruecksichtigt nur s1 laenge + +function msecomparestr(const S1, S2: msestring): Integer + {$ifdef FPC} inline; {$endif} + //case sensitive +function msecomparetext(const S1, S2: msestring): Integer + {$ifdef FPC} inline; {$endif} + //case insensitive +function msecomparestrnatural(const S1, S2: msestring): Integer + {$ifdef FPC} inline; {$endif} + //case sensitive +function msecomparetextnatural(const S1, S2: msestring): Integer + {$ifdef FPC} inline; {$endif} + //case insensitive +function mseCompareTextlen(const S1, S2: msestring): Integer; + //case insensitiv, beruecksichtigt nur s1 laenge +function mseCompareTextlenupper(const S1, S2: msestring): Integer; + //case insensitiv, checks length s1 only, s1 must be uppercase +function msepartialcomparetext(const s1,s2: msestring): integer; + //case insensitive, checks s1 lenght only +function msepartialcomparestr(const s1,s2: msestring): integer; + //case sensitive, checks s1 lenght only + +function mseissamestrlen(const apartstring,astring: msestring): boolean; +function mseissametextlen(const apartstring,astring: msestring): boolean; + //case insensitive + +function encodesearchoptions(const caseinsensitive: boolean = false; + const wholeword: boolean = false; + const wordstart: boolean = false; + const backward: boolean = false): searchoptionsty; +function msestringsearch(const substring,s: msestring; start: integer; + const options: searchoptionsty; + const substringupcase: msestring = ''): integer; overload; +function stringsearch(const substring,s: string; start: integer; + const options: searchoptionsty; + const substringupcase: string = ''): integer; overload; +function replacestring(const s: msestring; oldsub: msestring; + const newsub: msestring; + const options: searchoptionsty = []): msestring; overload; +function replacestring(const s: string; oldsub: string; + const newsub: string; + const options: searchoptionsty = []): string; overload; + +procedure addeditchars(const source: msestring; var buffer: msestring; + var cursorpos: integer); + //cursorpos nullbased +function processeditchars(var value: msestring; stripcontrolchars: boolean): integer; + //bringt offset durch backspace +function mseextractprintchars(const value: msestring): msestring; + +function findchar(const str: string; achar: char): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findchar(const str: string; const astart: integer; + achar: char): integer; overload; +function findchar(const str: msestring; achar: msechar): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findchar(const str: msestring; const astart: integer; + achar: msechar): integer; overload; +function findchar(const str: pchar; achar: char): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findchar(const str: pmsechar; achar: msechar): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findchars(const str: string; const achars: string): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findchars(const str: msestring; const achars: msestring): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findlastchar(const str: string; achar: char): integer; overload; + //bringt index des letzten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findlastchar(const str: msestring; achar: msechar): integer; overload; + //bringt index des letzten vorkommens von zeichen in string, 0 wenn nicht gefunden +function countchars(const str: string; achar: char): integer; overload; +function countchars(const str: msestring; achar: msechar): integer; overload; +function getcharpos(const str: msestring; achar: msechar): integerarty; + +function strscan(const Str: PChar; Chr: Char): PChar; overload; +//function strscan(const str: string; chr: char): integer; overload; + //use findchar() +function strscan(const str: lmsestringty; const chr: msechar): pmsechar; overload; +function msestrscan(const Str: PmseChar; Chr: mseChar): PmseChar; overload; +//function msestrscan(const str: msestring; chr: msechar): integer; overload; + //use findchar() +procedure mseskipspace(var str: pmsechar); {$ifdef FPC} inline; {$endif} +procedure skipspace(var str: pchar); {$ifdef FPC} inline; {$endif} + +function StrLScan(const Str: PChar; Chr: Char; len: integer): PChar; +function mseStrLScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; + +function StrNScan(const Str: PChar; Chr: Char): PChar; +function StrLNScan(const Str: PChar; Chr: Char; len: integer): PChar; +function mseStrNScan(const Str: PmseChar; Chr: mseChar): PmseChar; +function mseStrLNScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; + +function StrRScan(const Str: PChar; Chr: Char): PChar; +function StrLRScan(const Str: PChar; Chr: Char; len: integer): PChar; +function mseStrRScan(const Str: PmseChar; Chr: mseChar): PmseChar; overload; +function msestrrscan(const str: msestring; chr: msechar): integer; overload; +function mseStrLRScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; + +function mseStrLNRScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; + +function StrLComp(const Str1, Str2: PChar; len: integer): Integer; + +function mseStrComp(const Str1, Str2: PmseChar): Integer; +function mseStrLComp(const Str1, Str2: PmseChar; len: integer): Integer; +function mseStrLIComp(const Str1, upstr: PmseChar; len: integer): Integer; + //ascii caseinsensitive, upstr muss upcase sein +function StrLIComp(const Str1, upstr: PChar; len: integer): Integer; + //ascii caseinsensitive, upstr muss upcase sein +function StrIComp(const Str1, upstr: PChar): Integer; + //ascii caseinsensitive, upstr muss upcase sein + +function startsstr(substring,s: pchar): boolean; overload; +function startsstr(const substring,s: string): boolean; overload; +function msestartsstr(substring,s: pmsechar): boolean; overload; +function msestartsstr(const substring,s: msestring): boolean; overload; + +function msestartsstrcaseinsensitive(substring,s: pmsechar): boolean; + //substring must be uppercase, ASCII caseinsensitve + +function isnullstring(const s: ansistring): boolean; +function isemptystring(const s: pchar): boolean; overload; +function isemptystring(const s: pmsechar): boolean; overload; +function isnamechar(achar: char): boolean; overload; +function isnamechar(achar: msechar): boolean; overload; + //true if achar in 'a'..'z','A'..'Z','0'..'9','_'; +function isnumber(const s: string): boolean; overload; +function isnumber(const s: msestring): boolean; overload; + //true if all characters in '0'..'9' + +function strlcopy(const str: pchar; len: integer): ansistring; + //nicht nullterminiert +function msestrlcopy(const str: pmsechar; len: integer): msestring; + //nicht nullterminiert +function psubstr(const start,stop: pchar): string; overload; +function psubstr(const start,stop: pmsechar): msestring; overload; +function singleline(const start: pchar): string; overload; +function singleline(const start: pmsechar): msestring; overload; + +function msePosEx(const SubStr, S: msestring; Offset: longword = 1): Integer; + +function mselowercase(const s: msestring): msestring; overload; +function mselowercase(const s: msestringarty): msestringarty; overload; +function mseuppercase(const s: msestring): msestring; overload; +function mseuppercase(const s: msestringarty): msestringarty; overload; + +//ascii only +function charuppercase(const c: char): char; overload; + {$ifdef FPC} inline; {$endif} +function charuppercase(const c: msechar): msechar; overload; + {$ifdef FPC} inline; {$endif} +function struppercase(const s: string): string; overload; +function struppercase(const s: msestring): msestring; overload; +function struppercase(const s: lmsestringty): msestring; overload; +function struppercase(const s: lstringty): string; overload; +procedure struppercase1(var s: msestring); overload; + +function charlowercase(const c: char): char; overload; +function charlowercase(const c: msechar): msechar; overload; +function strlowercase(const s: string): string; overload; +function strlowercase(const s: msestring): msestring; overload; +function strlowercase(const s: lmsestringty): msestring; overload; +function strlowercase(const s: lstringty): string; overload; +procedure strlowercase1(var s: msestring); overload; + +//ascii only + +function mseremspace(const s: msestring): msestring; + //entfernt alle space und steuerzeichen +function removelinebreaks(const s: msestring): msestring; + //replaces linebreaks with space +function removelineterminator(const s: msestring): msestring; +procedure removetabterminator(var s: msestring); +function stripescapesequences(avalue: msestring): msestring; + +procedure stringaddref(var str: ansistring); overload; +procedure stringaddref(var str: msestring); overload; +procedure stringsafefree(var str: string; const onlyifunique: boolean); +procedure stringsafefree(var str: msestring; const onlyifunique: boolean); + +procedure reallocstring(var value: ansistring); overload; + //macht datenkopie ohne free +procedure reallocstring(var value: msestring); overload; + //macht datenkopie ohne free +procedure reallocarray(var value; elementsize: integer); overload; + //macht datenkopie ohne free +procedure resizearray(var value; newlength, elementsize: integer); + //ohne finalize + +function lineatindex(const value: msestring; const index: int32): msestring; +procedure wordatindex(const value: msestring; const index: integer; + out first,pastlast: pmsechar; + const delimchars: msestring; + const nodelimstrings: array of msestring); overload; + //index = 0..length(value)-1 +function wordatindex(const value: msestring; const index: integer; + const delimchars: msestring; + const nodelimstrings: array of msestring): msestring; overload; +function checkkeyword(const aname: string; const anames; //stringaty + const ahigh: integer): cardinal; overload; + //scans from 1 to ahigh, 0 -> unknown +function checkkeyword(const aname: msestring; const anames; //msestringaty + const ahigh: integer): cardinal; overload; +function checkkeyword(const aname: pchar; const anames; //stringaty + const ahigh: integer): cardinal; overload; + //scans from 1 to ahigh, 0 -> unknown +function checkkeyword(const aname: pmsechar; const anames; //msestringaty + const ahigh: integer): cardinal; overload; + +function quotestring(value: string; quotechar: char; + const force: boolean = true; + const separator: char = ' '): string; overload; +function quotestring(value: msestring; quotechar: msechar; + const force: boolean = true; + const separator: msechar = ' '): msestring; overload; +function quoteescapedstring(value: string; quotechar: char; + const force: boolean = true; + const separator: char = ' '): string; overload; +function quoteescapedstring(value: msestring; quotechar: msechar; + const force: boolean = true; + const separator: msechar = ' '): msestring; overload; +function unquotestring(value: string; quotechar: char): string; overload; +function unquotestring(value: msestring; quotechar: msechar): msestring; overload; +function extractquotedstr(const value: msestring): msestring; + //entfernt vorhandene paare ' und " + +function checkfirstchar(const value: string; achar: char): pchar; + //nil wenn erster char nicht space <> achar, ^achar sonst +function firstline(const atext: msestring): msestring; +function lastline(const atext: msestring): msestring; +procedure textdim(const atext: msestring; out firstx,lastx,y: integer); + +function shrinkpathellipse(var value: msestring): boolean; +function shrinkstring(const value: msestring; maxcharcount: integer): msestring; +procedure extendstring(var value: string; const mincharcount: integer); +procedure extendstring(var value: msestring; const mincharcount: integer); + +function nullstring(const count: integer): string; +function charstring(ch: char; count: integer): string; overload; +function charstring(ch: msechar; count: integer): msestring; overload; +function countleadingchars(const str: msestring; char: msechar): integer; overload; +function countleadingchars(const str: string; char: char): integer; overload; + //-1 = leer +function fitstring(const source: msestring; const len: integer; + const pos: stringposty = sp_left; + const cutchar: msechar = #0; + const padchar: msechar = ' '): msestring; + //cutchar = 0 -> no cutchar + +function breaklines(const source: string): stringarty; overload; +function breaklines(const source: msestring): msestringarty; overload; +function breaklines(const source: msestring; + maxlength: integer): msestringarty; overload; + +procedure splitstring(source: string; + var dest: stringarty; separator: char = c_tab; + trim: boolean = false); overload; +procedure splitstring(source: msestring; + var dest: msestringarty; separator: msechar = c_tab; + trim: boolean = false); overload; + //length(dest) = 0 -> es werden die noetigen stellen erzeugt + // sonst length(dest) <= length(dest uebergeben), + // ganzer rest im letzten string, falls mehr vorhandene teile als + // uebergebene strings +function splitstring(source: string; separator: char = c_tab; + trim: boolean = false): stringarty; overload; +function splitstring(source: msestring; separator: msechar = c_tab; + trim: boolean = false): msestringarty; overload; +function splitstringquoted(source: string; separator: char = c_tab; + quotechar: char = '"'; + atrim: boolean = false): stringarty; overload; +function splitstringquoted(source: msestring; separator: msechar = c_tab; + quotechar: msechar = '"'; + atrim: boolean = false): msestringarty; overload; + +procedure splitstringquoted(const source: string; out dest: stringarty; + quotechar: char = '"'; separator: char = #0); overload; +procedure splitstringquoted(const source: msestring; out dest: msestringarty; + quotechar: msechar = '"'; separator: msechar = #0); overload; + //separator = #0 -> ' ' and c_tab for separators + +function concatstrings(const source: msestringarty; + const separator: msestring = ' '; + const quotechar: msechar = #0; //#0 -> no quote + const force: boolean = false): msestring; overload; + +function concatstrings(const source: stringarty; + const separator: string = ' '; + const quotechar: char = #0; //#0 -> no quote + const force: boolean = false): string; overload; + +function parsecommandline(const s: pchar): stringarty; overload; +function parsecommandline(const s: pmsechar): msestringarty; overload; +function parsecommandline(const s: string): stringarty; overload; +function parsecommandline(const s: msestring): msestringarty; overload; + +function rs(const resstring: ansistring): msestring; + //converts resourcestring, + // resourcesstring unit must be compiled with {$codepage utf8} +function stringtoutf8(const value: msestring; + const options: utfoptionsty = []): utf8string; +function stringtoutf8ansi(const value: msestring; + const options: utfoptionsty = []): ansistring; +function stringtoutf8(const value: pmsechar; + const count: integer; + const options: utfoptionsty = []): utf8string; +function stringtoutf8ansi(const value: pmsechar; + const count: integer; + const options: utfoptionsty = []): ansistring; +function utf8tostring(const value: pchar; const alength: integer; + const options: utfoptionsty = []): msestring; +function utf8tostring(const value: pchar; + const options: utfoptionsty = []): msestring; +function utf8tostring(const value: lstringty; + const options: utfoptionsty = []): msestring; +function utf8tostring(const value: utf8string; + const options: utfoptionsty = []): msestring; +function utf8tostringansi(const value: ansistring; + const options: utfoptionsty = []): msestring; +function checkutf8(const value: utf8string): boolean; + //true if valid utf8 +function checkutf8ansi(const value: ansistring): boolean; + //true if valid utf8 +function stringtolatin1(const value: msestring): string; +function latin1tostring(const value: string): msestring; +function ucs4tostring(achar: dword): msestring; +function getucs4char(const value: msestring; const aindex: int32): ucs4char; + //returns surrogatevalue if index between high and low codeunit + +function getasciichar(const source: msechar; out dest: char): boolean; + {$ifdef FPC} inline; {$endif} + //true if valid; +function getansichar(const source: msechar; out dest: char): boolean; + {$ifdef FPC} inline; {$endif} + //true if valid; + +function ansistringof(const value: tbytes): ansistring; + +type +// getkeystringfuncty = function (const index: integer; +// var astring: msestring): boolean of object; + //false if no value + getkeystringfuncty = function (const index: integer): msestring of object; + + locatestringoptionty = (lso_casesensitive,lso_posinsensitive,lso_exact, + lso_nodown,lso_noup,lso_noexact, + lso_filterisuppercase); + locatestringoptionsty = set of locatestringoptionty; + +function locatestring(const afilter: msestring; + const getkeystringfunc: getkeystringfuncty; + const options: locatestringoptionsty; + const count: integer; var aindex: integer): boolean; + //true if found + +function getmsestringprop(const ainstance: tobject; + const apropinfo: ppropinfo): msestring; +procedure setmsestringprop(const ainstance: tobject; + const apropinfo: ppropinfo; const avalue: msestring); +function treader_readmsestring(const areader: treader): msestring; +procedure twriter_writemsestring(awriter: twriter; const avalue: msestring); + +implementation +uses + msearrayutils{,msesysintf}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +type + tmemorystream1 = class(tmemorystream); + +function getmsestringprop(const ainstance: tobject; + const apropinfo: ppropinfo): msestring; +begin +{$ifdef mse_unicodestring} + result:= GetunicodestrProp(ainstance,apropinfo); +{$else} + result:= GetwidestrProp(ainstance,apropinfo); +{$endif} +end; + +procedure twriter_writemsestring(awriter: twriter; const avalue: msestring); +begin +{$ifdef mse_unicodestring} + awriter.writeunicodestring(avalue); +{$else} + awriter.writewidestring(avalue); //msestringimplementation +{$endif} +end; + +procedure setmsestringprop(const ainstance: tobject; + const apropinfo: ppropinfo; const avalue: msestring); +begin +{$ifdef mse_unicodestring} + setunicodestrprop(ainstance,apropinfo,avalue); +{$else} + setwidestrprop(ainstance,apropinfo,avalue); +{$endif} +end; + +function treader_readmsestring(const areader: treader): msestring; +begin +{$ifdef mse_unicodestring} + result:= areader.Readunicodestring; //msestringimplementation +{$else} + result:= areader.Readwidestring; //msestringimplementation +{$endif} +end; + +function locatestring(const afilter: msestring; const getkeystringfunc: getkeystringfuncty; + const options: locatestringoptionsty; + const count: integer; var aindex: integer): boolean; + //true if found +type + locateinfoty = record + filter: msestring; + casesensitive: boolean; + posinsensitive: boolean; + exact: boolean; + result: boolean; + end; + +var + locateinfo: locateinfoty; + +// index1: integer; + + procedure check(index1: integer); + var + str1: msestring; + int1: integer; + + procedure checkexactpos; + var + int2: integer; + begin + result:= (int1 > 0) and ((int1 = 1) or (str1[int1] = ' ')); + if result then begin + int2:= int1 + length(locateinfo.filter); + result:= (int2 = length(str1)) or (str1[int2] = ' '); + end; + end; //checkexactpos + + + begin + str1:= getkeystringfunc(index1); + with locateinfo do begin + if exact then begin + if casesensitive then begin + if posinsensitive then begin + int1:= pos(filter,str1); + checkexactpos; + end + else begin + result:= msecomparestr(filter,str1) = 0; + end; + end + else begin + if posinsensitive then begin + int1:= pos(filter,mseuppercase(str1)); + checkexactpos; + end + else begin + result:= msecomparetext(filter,str1) = 0; + end; + end; + end + else begin + if casesensitive then begin + if posinsensitive then begin + result:= pos(filter,str1) > 0; + end + else begin + result:= msecomparestrlen(filter,str1) = 0; + end; + end + else begin + if posinsensitive then begin + result:= pos(filter,mseuppercase(str1)) > 0; + end + else begin + result:= msecomparetextlen(filter,str1) = 0; + end; + end; + end; + if result then begin + aindex:= index1; + end; + end; + end; //check + +var + int1,int2: integer; +begin + if afilter = '' then begin + result:= count > 0; + if result then begin + if not (lso_nodown in options) then begin + aindex:= 0; + end + else begin + if aindex >= count then begin + aindex:= count-1; + end; + end; + end; + end + else begin + with locateinfo do begin + posinsensitive:= lso_posinsensitive in options; + casesensitive:= lso_casesensitive in options; + filter:= afilter; + if not casesensitive and not (lso_filterisuppercase in options) then begin + filter:= mseuppercase(filter); + end; + result:= false; + int1:= aindex; + if not (lso_noup in options) then begin + if int1 < 0 then begin + int1:= 0; + end; + end; + if not (lso_nodown in options) then begin + if int1 >= count then begin + int1:= count - 1; + end; + end; + if int1 >= 0 then begin + if not (lso_noexact in options) then begin //search whole filtertext + exact:= true; + for int2:= int1 to count - 1 do begin + check(int2); + if result or (lso_noup in options) then begin + break; + end; + end; + if not result then begin + if not (lso_nodown in options) then begin + for int2:= int1-1 downto 0 do begin + check(int2); + if result then begin + break; + end; + end; + end; + end; + end; + if not result and not (lso_exact in options) then begin + //search partial filter text + exact:= false; + for int2:= int1 to count - 1 do begin + check(int2); + if result or (lso_noup in options) then begin + break; + end; + end; + if not result and not (lso_nodown in options) then begin + for int2:= int1 - 1 downto 0 do begin + check(int2); + if result then begin + break; + end; + end; + end; + end; + end; + end; + result:= locateinfo.result; + end; +end; + +procedure dostringtoutf8(const value: pmsechar; + var count: integer; const dest: pointer; + const options: utfoptionsty); +var + ps,pe: pcard16; + pd: pcard8; + ca1: card16; + + procedure store3(); inline; + begin + pd^:= (ca1 shr 12) or $e0; + inc(pd); + pd^:= (ca1 shr 6) and $3f or $80; + inc(pd); + pd^:= ca1 and $3f or $80; + end; //store3 + +begin + pd:= dest; + ps:= pointer(value); + pe:= ps + count; + while ps < pe do begin + ca1:= ps^; + inc(ps); + if ca1 < $80 then begin //1 byte + pd^:= ca1; + end + else begin + if ca1 < $0800 then begin //2byte + pd^:= (ca1 shr 6) or $c0; + inc(pd); + pd^:= (ca1 and $3f) or $80; + end + else begin + if ca1 < $d800 then begin + store3(); + end + else begin + if (ca1 > $dbff) then begin //3 byte + if (uto_storeinvalid in options) then begin + if ca1 = utf16private then begin + ca1:= ca1 or ps^; + store3(); + inc(ps); + end + else begin + if ca1 = utf16invalid then begin + pd^:= ps^; + inc(ps); + end + else begin + store3(); //should not happen + end; + end; + end + else begin + store3(); + end; + end + else begin //surrogate pair + if (ca1 >= $dc00) or (ps = pe) then begin + //missing high or low surrogate + pd^:= card8(utferrorchar); + end; + if ps^ and $fc00 <> $dc00 then begin //invalid low surrogate + pd^:= card8(utferrorchar); + end + else begin + ca1:= ca1 - card16($d800 - $0040); + pd^:= (ca1 shr 8) or $f0; + inc(pd); + pd^:= (ca1 shr 2) and $3f or $80; + inc(pd); + pd^:= ((ca1 shl 4) and $30 or (ps^ shr 6) and $0f) or $80; + inc(pd); + pd^:= ps^ and $3f or $80; + inc(ps); + end; + end; + end; + end; + end; + inc(pd); + end; + count:= pd - pcard8(dest); +end; + +function stringtoutf8(const value: pmsechar; + const count: integer; + const options: utfoptionsty = []): utf8string; +var + i1: int32; +begin + i1:= count; + setlength(result,i1*3); //max + dostringtoutf8(value,i1,pointer(result),options); + setlength(result,i1); +end; + +function stringtoutf8ansi(const value: pmsechar; + const count: integer; + const options: utfoptionsty = []): ansistring; +var + i1: int32; +begin + i1:= count; + setlength(result,i1*3); //max + dostringtoutf8(value,i1,pointer(result),options); + setlength(result,i1); +end; + +function stringtoutf8(const value: msestring; + const options: utfoptionsty = []): utf8string; +var + i1: int32; +begin + i1:= length(value); + setlength(result,i1*3); //max + dostringtoutf8(pointer(value),i1,pointer(result),options); + setlength(result,i1); +end; + +function stringtoutf8ansi(const value: msestring; + const options: utfoptionsty = []): ansistring; +var + i1: int32; +begin + i1:= length(value); + setlength(result,i1*3); //max + dostringtoutf8(pointer(value),i1,pointer(result),options); + setlength(result,i1); +end; + +function utf8tostring(const value: pchar; const alength: integer; + const options: utfoptionsty = []): msestring; +var + by1: card8; + wo1: card16; + pc,pe: pcard8; + pd,pde: pcard16; + storeinvalid: boolean; + p1: pointer; + + procedure seterror(); inline; + begin + if storeinvalid then begin + pd^:= utf16invalid; + inc(pd); + pd^:= by1; + end + else begin + pd^:= card16(utferrorchar); + end; + end; + +begin + storeinvalid:= uto_storeinvalid in options; + setlength(result,alength); //max + pd:= pcard16(pointer(result)); + pde:= pd+alength; + pc:= pointer(value); + pe:= pc+alength; + while pc < pe do begin + by1:= pc^; + inc(pc); + if by1 < $80 then begin //1 byte + pd^:= by1; + end + else begin + if by1 < $e0 then begin //2 byte + if (pc < pe) and (pc^ and $c0 = $80) then begin + wo1:= ((by1 and $1f) shl word(6)) or (pc^ and $3f); + if storeinvalid and (wo1 >= utf16privatebase) and + (wo1 < utf16privatebase + 256) then begin + pd^:= utf16private; + wo1:= wo1 and $00ff; + inc(pd); + end; + pd^:= wo1; + if pd^ < $80 then begin + seterror(); //overlong + end; + inc(pc); + end + else begin + seterror(); + end; + end + else begin + if (by1 < $f0) then begin //3byte + if (pe - pc >= 1) and (pc^ and $c0 = $80) and + ((pc+1)^ and $c0 = $80) then begin + pd^:= (by1 shl word(12)) or + (pc^ and $3f) shl word(6) or ((pc+1)^ and $3f); + if pd^ < $0800 then begin + seterror(); //overlong + end; + inc(pc,2); + end + else begin + seterror(); + end; + end + else begin + if (by1 < $f8) then begin //4byte + if (pe - pc >= 2) and (pc^ and $c0 = $80) and ((pc+1)^ and $c0 = $80) and + ((pc+2)^ and $c0 = $80) then begin + if ((by1 <= $e0) and (pc^ < $90)) then begin //overlong + seterror(); //overlong; + end + else begin + pd^:= (((by1 and $07) shl word(8)) or + ((pc^ and $3f) shl word(2)) or + ((pc+1)^ and $30 shr word(4))) + + (word($d800) - word($10000 shr 10)); + inc(pd); + pd^:= (((pc+1)^ and $0f) shl word(6)) or + ((pc+2)^ and $3f) or word($dc00); + end; + inc(pc,3); + end + else begin + seterror(); + end; + end + else begin + seterror(); + end; + end; + end; + end; + if (pd >= pde) and (pc < pe) then begin //pd should never be bigger than pde, + //there is at most one inc(pd) in loop + p1:= pointer(result); + setlength(result,length(result) + length(result) div 3 + 16); + pointer(pd):= pointer(pd)+(pointer(result)-p1); + pde:= pcard16(pointer(result))+length(result); + end; + inc(pd); + end; + setlength(result,pd-pcard16(pointer(result))); +end; + +function utf8tostring(const value: utf8string; + const options: utfoptionsty = []): msestring; +begin + result:= utf8tostring(pointer(value),length(value),options); +end; + +function utf8tostringansi(const value: ansistring; + const options: utfoptionsty = []): msestring; +begin + result:= utf8tostring(pointer(value),length(value),options); +end; + +function rs(const resstring: ansistring): msestring; + //converts resourcestring, + // resourcesstring unit must be compiled with {$codepage utf8} +begin + result:= utf8tostring(pointer(resstring),length(resstring),[]); +end; + + +function utf8tostring(const value: pchar; + const options: utfoptionsty = []): msestring; +begin + result:= utf8tostring(value,strlen(value),options); +end; + +function utf8tostring(const value: lstringty; + const options: utfoptionsty = []): msestring; +begin + result:= utf8tostring(value.po,value.len,options); +end; + +function docheckutf8(const value: pointer; const count: int32): boolean; + //null terminated +var + po1: pbyte; +begin + result:= true; + if count > 0 then begin + po1:= value; + while po1^ <> $00 do begin + if po1^ >= $80 then begin //2 bytes + if po1^ < $e0 then begin + if po1^ and $1e = 0 then begin + result:= false; //overlong + exit; + end; + inc(po1); + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + end + else begin + if po1^ < $f0 then begin //3 bytes + inc(po1); + if (po1^ and $20 = 0) and ((po1-1)^ and $0f = 0) then begin + result:= false; //overolong + exit; + end; + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + inc(po1); + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + end + else begin + if po1^ < $f8 then begin //4 bytes + inc(po1); + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + if (po1^ and $30 = 0) and ((po1-1)^ and $07 = 0) then begin + result:= false; //overolong + exit; + end; + inc(po1); + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + inc(po1); + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + end + else begin + result:= false; + exit; + end; + end; + end; + end; + inc(po1); + end; + if pointer(po1) <> value + count then begin + result:= false; //#0 in string + end; + end; +end; + +function checkutf8(const value: utf8string): boolean; + //true if valid utf8 +begin + result:= docheckutf8(pointer(value),length(value)); +end; + +function checkutf8ansi(const value: ansistring): boolean; + //true if valid utf8 +begin + result:= docheckutf8(pointer(value),length(value)); +end; + +function stringtolatin1(const value: msestring): string; +var + int1: integer; +begin + setlength(result,length(value)); + for int1:= 0 to length(result)-1 do begin + (pchar(pointer(result))+int1)^:= + char(word((pmsechar(pointer(value))+int1)^)); + end; +end; + +function latin1tostring(const value: string): msestring; +var + int1: integer; +begin + setlength(result,length(value)); + for int1:= 0 to length(result)-1 do begin + (pmsechar(pointer(result))+int1)^:= + msechar(byte((pchar(pointer(value))+int1)^)); + end; +end; + +function ucs4tostring(achar: dword): msestring; +begin + if achar < $10000 then begin + setlength(result,1); + pmsechar(pointer(result))^:= msechar(achar); + end + else begin + setlength(result,2); + achar:= achar - $10000; + pmsechar(pointer(result))^:= + msechar(word((achar shr 10) and $3ff or $d800)); + (pmsechar(pointer(result))+1)^:= msechar(word(achar) and $3ff or $dc00); + end; +end; + +function getucs4char(const value: msestring; const aindex: int32): ucs4char; + //returns surrogatevalue if index between high and low codeunit +begin + result:= 0; + if (aindex > 0) and (aindex <= length(value)) then begin + result:= ord(value[aindex]); + if result and $fc00 = $d800 then begin + result:= ((result - $d800) shl 10) + ord(value[aindex+1]) - $dc00 + $10000; + end + else begin + if (result and $fc00 = $dc00) and (aindex > 1) then begin + result:= result - $dc00 + ((ord(value[aindex-1]) - $d800) shl 10) + $10000; + end; + end; + end; +end; + +function getasciichar(const source: msechar; out dest: char): boolean; + //true if valid; +begin + result:= source < #128; + dest:= char(byte(source)); +end; + +function getansichar(const source: msechar; out dest: char): boolean; + //true if valid; +begin + result:= source < #256; + dest:= char(byte(source)); +end; + +function psubstr(const start,stop: pchar): string; +var + int1: integer; +begin + int1:= stop-start; + if (int1 < 0) or (start = nil) or (stop = nil) then begin + result:= ''; + end + else begin + setlength(result,int1); + move(start^,result[1],int1); + end; +end; + +function ansistringof(const value: tbytes): ansistring; +begin + setlength(result,length(value)); + move(pointer(value)^,pointer(result)^,length(result)); +end; + +function psubstr(const start,stop: pmsechar): msestring; +var + int1: integer; +begin + int1:= stop-start; + if (int1 < 0) or (start = nil) or (stop = nil) then begin + result:= ''; + end + else begin + setlength(result,int1); + move(start^,result[1],int1*sizeof(msechar)); + end; +end; + +function singleline(const start: pchar): string; +var + po1: pchar; +begin + if start = nil then begin + result:= ''; + end + else begin + po1:= start; + while po1^ <> #0 do begin + if (po1^ = c_linefeed) or (po1^ = c_return) then begin + break; + end; + inc(po1); + end; + result:= psubstr(start,po1); + end; +end; + +function singleline(const start: pmsechar): msestring; +var + po1: pmsechar; +begin + if start = nil then begin + result:= ''; + end + else begin + po1:= start; + while po1^ <> msechar(#0) do begin + if (po1^ = msechar(c_linefeed)) or (po1^ = msechar(c_return)) then begin + break; + end; + inc(po1); + end; + result:= psubstr(start,po1); + end; +end; + +function concatstrings(const source: msestringarty; + const separator: msestring = ' '; const quotechar: msechar = #0; + const force: boolean = false): msestring; +var + int1: integer; + sepchar: msechar; +begin + if source = nil then begin + result:= ''; + end + else begin + if quotechar = #0 then begin + result:= source[0]; + for int1:= 1 to high(source) do begin + result:= result + separator + source[int1]; + end; + end + else begin + sepchar:= pmsechar(separator)^; + result:= quotestring(source[0],quotechar,force); + for int1:= 1 to high(source) do begin + result:= result + separator + + quotestring(source[int1],quotechar,force,sepchar); + end; + end; + end; +end; + +function concatstrings(const source: stringarty; + const separator: string = ' '; const quotechar: char = #0; + const force: boolean = false): string; +var + int1: integer; + sepchar: char; +begin + if source = nil then begin + result:= ''; + end + else begin + if quotechar = #0 then begin + result:= source[0]; + for int1:= 1 to high(source) do begin + result:= result + separator + source[int1]; + end; + end + else begin + sepchar:= pchar(separator)^; + result:= quotestring(source[0],quotechar,force); + for int1:= 1 to high(source) do begin + result:= result + separator + + quotestring(source[int1],quotechar,force,sepchar); + end; + end; + end; +end; + +procedure stringaddref(var str: ansistring); +var + po1: psizeint; +begin + if pointer(str) <> nil then begin + po1:= pointer(str)-2*sizeof(sizeint); + if po1^ >= 0 then begin + inc(po1^); + end; + end; +end; + +procedure stringaddref(var str: msestring); +{$ifndef msestringsarenotrefcounted} +var + po1: psizeint; +{$endif} +begin + if pointer(str) <> nil then begin +{$ifndef msestringsarenotrefcounted} + po1:= pointer(str)-2*sizeof(sizeint); + if po1^ >= 0 then begin + inc(po1^); + end; +{$else} + reallocstring(str); //delphi and FPC 2.2 + //widestrings are not refcounted on win32 +{$endif} + end; +end; + +procedure stringsafefree(var str: string; const onlyifunique: boolean); +var + po1: psizeint; +begin + if pointer(str) <> nil then begin + po1:= pointer(str)-2*sizeof(sizeint); + if (po1^ >= 0) and (not onlyifunique or (po1^ = 1)) then begin + fillchar(pointer(str)^,length(str)*sizeof(str[1]),0); + str:= ''; + end; + end; +end; + +procedure stringsafefree(var str: msestring; const onlyifunique: boolean); +var + po1: psizeint; +begin + if pointer(str) <> nil then begin + po1:= pointer(str)-2*sizeof(sizeint); + if (po1^ >= 0) and (not onlyifunique or (po1^ = 1)) then begin + fillchar(pointer(str)^,length(str)*sizeof(str[1]),0); + str:= ''; + end; + end; +end; + +procedure splitstringquoted(const source: string; out dest: stringarty; + quotechar: char = '"'; separator: char = #0); +var + po1,po2: pchar; + count: integer; + str1: string; + + procedure addsubstring; + var + int1: integer; + begin + if po1 <> po2 then begin + int1:= length(str1); + setlength(str1,int1+(po1-po2)); + move(po2^,str1[int1+1],(po1-po2)*sizeof(char)); + end; + end; + +begin + dest:= nil; + po1:= pointer(source); + if po1 <> nil then begin + count:= 0; + while po1^ <> #0 do begin + if separator = #0 then begin + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + end + else begin + while true do begin + if po1^ = quotechar then begin + break; + end; + po2:= po1; + while (po1^ <> separator) and (po1^ <> #0) do begin + inc(po1); + end; + setstring(str1,po2,po1-po2); + additem(dest,str1,count); + if po1^ <> #0 then begin + inc(po1); + end + else begin + setlength(dest,count); + exit; + end; + end; + end; + str1:= ''; + if po1^ <> quotechar then begin + po2:= po1; + while (po1^ <> quotechar) and (po1^ <> ' ') and (po1^ <> c_tab) and (po1^ <> #0) do begin + inc(po1); + end; + addsubstring; + end + else begin + while po1^ <> #0 do begin + inc(po1); //po1^ = quotechar + po2:= po1; + while (po1^ <> quotechar) and (po1^ <> #0) do begin + inc(po1); + end; + if po1^ <> #0 then begin // ? + if (po1+1)^ = quotechar then begin// "....""... + inc(po1); // ? + addsubstring; // "....""... + end + else begin // ? + addsubstring; // "....".... + inc(po1); // ? + // "....".... + // "...."..,.. + if (separator <> #0) then begin + while (po1^ <> #0) and (po1^ <> separator) do begin + inc(po1); + end; + // ? + // "...."..,.. + if po1^ = separator then begin + inc(po1); + end; + // ? + // "...."..,.. + end; + break; + end; + end; + end; + end; + additem(dest,str1,count); + end; + setlength(dest,count); + end; +end; + +procedure splitstringquoted(const source: msestring; out dest: msestringarty; + quotechar: msechar = '"'; separator: msechar = #0); +var + po1,po2: pmsechar; + count: integer; + str1: msestring; + + procedure addsubstring; + var + int1: integer; + begin + if po1 <> po2 then begin + int1:= length(str1); + setlength(str1,int1+(po1-po2)); + move(po2^,str1[int1+1],(po1-po2)*sizeof(msechar)); + end; + end; + +begin + dest:= nil; + po1:= pointer(source); + if po1 <> nil then begin + count:= 0; + while po1^ <> #0 do begin + if separator = #0 then begin + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + end + else begin + while true do begin + if po1^ = quotechar then begin + break; + end; + po2:= po1; + while (po1^ <> separator) and (po1^ <> #0) do begin + inc(po1); + end; + setstring(str1,po2,po1-po2); + additem(dest,str1,count); + if po1^ <> #0 then begin + inc(po1); + end + else begin + setlength(dest,count); + exit; + end; + end; + end; + str1:= ''; + if po1^ <> quotechar then begin + po2:= po1; + while (po1^ <> quotechar) and (po1^ <> ' ') and (po1^ <> c_tab) and (po1^ <> #0) do begin + inc(po1); + end; + addsubstring; + end + else begin + while po1^ <> #0 do begin + inc(po1); //po1^ = quotechar + po2:= po1; + while (po1^ <> quotechar) and (po1^ <> #0) do begin + inc(po1); + end; + if po1^ <> #0 then begin // ? + if (po1+1)^ = quotechar then begin// "....""... + inc(po1); // ? + addsubstring; // "....""... + end + else begin // ? + addsubstring; // "....".... + inc(po1); // ? + // "....".... + // "...."..,.. + if (separator <> #0) then begin + while (po1^ <> #0) and (po1^ <> separator) do begin + inc(po1); + end; + // ? + // "...."..,.. + if po1^ = separator then begin + inc(po1); + end; + // ? + // "...."..,.. + end; + break; + end; + end; + end; + end; + additem(dest,str1,count); + end; + setlength(dest,count); + end; +end; + +function breaklines(const source: string): stringarty; +var + int1,int2: integer; +begin + result:= nil; + splitstring(source,result,c_linefeed); + for int1:= 0 to high(result) do begin + int2:= length(result[int1]); + if (int2 > 0) and (result[int1][int2] = c_return) then begin + setlength(result[int1],int2-1); + end; + end; +end; + +function breaklines(const source: msestring): msestringarty; +var + int1,int2: integer; +begin + result:= nil; + splitstring(source,result,c_linefeed); + for int1:= 0 to high(result) - 1 do begin + while true do begin + int2:= length(result[int1]); + if (int2 > 0) and (result[int1][int2] = c_return) then begin + setlength(result[int1],int2-1); + end + else begin + break; + end; + end; + end; +end; + +function breaklines(const source: msestring; maxlength: integer): msestringarty; +var + charindex,charindexbefore,rowindex,lineend,lastbreak: integer; + int1,int2,len: integer; + po1: pmsechar; + mch1: msechar; + bo1: boolean; +begin + len:= length(source); + setlength(result,len div 10 + 1); + if source <> '' then begin + if maxlength <= 0 then begin + maxlength:= 1; + end; + rowindex:= 0; + charindex:= 1; + while charindex <= length(source) do begin + if rowindex > high(result) then begin + setlength(result,length(result)*2); + end; + charindexbefore:= charindex; + charindex:= length(source); + lineend:= 0; + lastbreak:= 0; + int2:= 1; + bo1:= false; + for int1:= charindexbefore to len do begin + mch1:= source[int1]; + if bo1 and ((mch1 = ' ') or (mch1 = c_tab)) then begin + lineend:= int1; + charindex:= int1; + end; + if mch1 = c_return then begin + lineend:= int1; + charindex:= int1; + if source[charindex+1] = c_linefeed then begin + inc(charindex); + end; + break; + end; + if mch1 = c_linefeed then begin + lineend:= int1; + charindex:= int1; + break; + end; + if (int2 <= maxlength) and ((mch1 = c_softhyphen) or (mch1 = '-') or + (mch1 = ' ') or (mch1 = c_tab)) then begin + lastbreak:= int1; + end; + if bo1 then begin + break; + end; + if mch1 <> c_softhyphen then begin + inc(int2); + end; + if int2 > maxlength then begin + charindex:= int1; + if int1 = len then begin + lineend:= int1 + 1; + end; + bo1:= true; + end; + end; + inc(charindex); + if lineend = 0 then begin + if int2 <= maxlength then begin + lineend:= charindex; + end + else begin + lineend:= lastbreak; + if lineend = 0 then begin + lineend:= charindex; + end + else begin + charindex:= lineend + 1; + mch1:= source[lineend]; + if (mch1 = c_softhyphen) or (mch1 = '-') then begin + inc(lineend); + end; + end; + end; + end; + setlength(result[rowindex],lineend-charindexbefore); //max + po1:= pointer(result[rowindex]); + if po1 <> nil then begin + for int1:= charindexbefore to lineend - 1 do begin + po1^:= source[int1]; + if po1^ <> c_softhyphen then begin + inc(po1); + end; + end; + if source[lineend-1] = c_softhyphen then begin + inc(po1); + end; + setlength(result[rowindex],po1-pmsechar(result[rowindex])); + end; + inc(rowindex); + end; + setlength(result,rowindex); + end; +end; + +function fitstring(const source: msestring; const len: integer; + const pos: stringposty = sp_left; + const cutchar: msechar = #0; + const padchar: msechar = ' '): msestring; + //cutchar = 0 -> no cutchar + procedure pad(const dest: pmsechar; const count: integer); + var + int1: integer; + ch1: msechar; + begin + ch1:= padchar; + for int1:= 0 to count-1 do begin + {$ifdef FPC} + dest[int1]:= ch1; + {$else} + pmsecharaty(dest)^[int1]:= ch1; + {$endif} + end; + end; + +var + copylen,padlen: integer; + int1: integer; +begin //fitstring + if (length(source) > len) and (cutchar <> #0) then begin + result:= charstring(cutchar,len); + end + else begin + setlength(result,len); + if len > 0 then begin + copylen:= length(source); + padlen:= len - copylen; + if padlen < 0 then begin + copylen:= len; + padlen:= 0; + end; + case pos of + sp_center: begin + int1:= padlen div 2; + move((pmsechar(pointer(source))+(length(source)-copylen) div 2)^, + (pmsechar(pointer(result))+int1)^,copylen*sizeof(msechar)); + pad(pointer(result),int1); + pad(pmsechar(pointer(result))+int1+copylen,len-copylen-int1); + end; + sp_right: begin + move((pmsechar(pointer(source))+length(source)-copylen)^, + (pmsechar(pointer(result))+padlen)^,copylen*sizeof(msechar)); + pad(pmsechar(pointer(result)),padlen); + end; + else begin //sp_left + move(pointer(source)^,pointer(result)^,copylen*sizeof(msechar)); + pad(pmsechar(pointer(result))+copylen,padlen); + end; + end; + end; + end; +end; + +procedure splitstring(source: string; + var dest: stringarty; separator: char = c_tab; + trim: boolean = false); + // dest = [] -> length(dest) = anzahl vorhandene teile + // sonst length(dest) <= length(dest uebergeben), + // ganzer rest im letzten string, fallse mehr vorhandene teile als + // uebergebene strings +var + int2,int3: integer; + po,po1,po2: pchar; + all: boolean; + bo1: boolean; + +begin + all:= length(dest) = 0; + if all then begin + int2:= countchars(source,separator); + setlength(dest,int2+1); //maximale zahl + end + else begin + for int2:= 0 to length(dest)-1 do begin + dest[int2]:= ''; + end; + end; + po:= pchar(source); + int3:= length(source); + bo1:= false; + for int2:= 0 to length(dest) - 1 do begin + if int3 <= 0 then begin + if bo1 and (int2 < length(dest)) then begin + setlength(dest,int2+1); //leerer schluss + end + else begin + setlength(dest,int2); + end; + break; + end; + po2:= po; + po1:= strlscan(po,separator,int3); + if (po1 = nil) or (int2 = high(dest)) then begin + po1:= po + int3; //rest + bo1:= false; + end + else begin + bo1:= true; + end; + if trim then begin + po:= strnscan(po,' '); + end; + if po <> nil then begin + if trim then begin + dest[int2]:= trimright(strlcopy(po,po1-po)); + end + else begin + dest[int2]:= strlcopy(po,po1-po); + end; + end; + if trim and (separator = ' ') then begin + po1:= strlnscan(po1,separator,int3); + if po1 = nil then begin + int3:= 0; + end; + end + else begin + inc(po1); + end; + int3:= int3 - (po1 - po2); + //verbrauchte stringlaenge + po:= po1; + end; +end; + +procedure splitstring(source: msestring; + var dest: msestringarty; separator: msechar = c_tab; + trim: boolean = false); + // dest = [] -> length(dest) = anzahl vorhandene teile + // sonst length(dest) <= length(dest uebergeben), + // ganzer rest im letzten string, fallse mehr vorhandene teile als + // uebergebene strings +var + int2,int3: integer; + po,po1,po2: pmsechar; + all: boolean; + bo1: boolean; + +begin + all:= length(dest) = 0; + if all then begin + int2:= countchars(source,separator); + setlength(dest,int2+1); //maximale zahl + end + else begin + for int2:= 0 to length(dest)-1 do begin + dest[int2]:= ''; + end; + end; + po:= pmsechar(source); + int3:= length(source); + bo1:= false; + for int2:= 0 to length(dest) - 1 do begin + if int3 <= 0 then begin + if bo1 and (int2 < length(dest)) then begin + setlength(dest,int2+1); //leerer schluss + end + else begin + setlength(dest,int2); + end; + break; + end; + po2:= po; + po1:= msestrlscan(po,separator,int3); + if (po1 = nil) or (int2 = high(dest)) then begin + po1:= po + int3; //rest + bo1:= false; + end + else begin + bo1:= true; + end; + if trim then begin + po:= msestrnscan(po,' '); + end; + if po <> nil then begin + if trim then begin + dest[int2]:= trimright(msestrlcopy(po,po1-po)); + end + else begin + dest[int2]:= msestrlcopy(po,po1-po); + end; + end; + if trim and (separator = ' ') then begin + po1:= msestrlnscan(po1,separator,int3); + if po1 = nil then begin + int3:= 0; + end; + end + else begin + inc(po1); + end; + int3:= int3 - (po1 - po2); + //verbrauchte stringlaenge + po:= po1; + end; +end; + +function splitstring(source: string; separator: char = c_tab; + trim: boolean = false): stringarty; +begin + result:= nil; + splitstring(source,result,separator,trim); +end; + +function splitstring(source: msestring; separator: msechar = c_tab; + trim: boolean = false): msestringarty; +begin + result:= nil; + splitstring(source,result,separator,trim); +end; + +function splitstringquoted(source: string; separator: char = c_tab; + quotechar: char = '"'; + atrim: boolean = false): stringarty; +var + int1: integer; +begin + splitstringquoted(source,result,quotechar,separator); + if atrim then begin + for int1:= 0 to high(result) do begin + result[int1]:= trim(result[int1]); + end; + end; +end; + +function splitstringquoted(source: msestring; separator: msechar = c_tab; + quotechar: msechar = '"'; + atrim: boolean = false): msestringarty; overload; +var + int1: integer; +begin + splitstringquoted(source,result,quotechar,separator); + if atrim then begin + for int1:= 0 to high(result) do begin + result[int1]:= trim(result[int1]); + end; + end; +end; + +function stringfromchar(achar: char; count : integer): string; +var + int1: integer; +begin + setlength(result,count); + for int1:= 1 to count do begin + result[int1]:= achar; + end; +end; + +function stringfromchar(achar: msechar; count : integer): msestring; +var + int1: integer; +begin + setlength(result,count); + for int1:= 1 to count do begin + result[int1]:= achar; + end; +end; + +function parsecommandline(const s: pchar): stringarty; +var + po1,po2: pchar; + count: integer; + str1: string; + + procedure addsubstring; + var + int1,int2: integer; + begin + {$ifdef FPC}{$checkpointer off}{$endif} + int1:= po1-po2; + int2:= length(str1); + setlength(str1,int2+int1); + move(po2^,str1[int2+1],int1); + po2:= po1; + {$ifdef FPC}{$checkpointer default}{$endif} + end; + +begin + result:= nil; + count:= 0; + if s <> nil then begin + {$ifdef FPC}{$checkpointer off}{$endif} + po1:= s; + while (po1^ <> #0) and (po1^ = ' ') do begin + inc(po1); + end; + if po1^ <> #0 then begin + po2:= po1; + str1:= ''; + while true do begin + case po1^ of + ' ',#0: begin + addsubstring; + additem(result,str1,count); + str1:= ''; + while (po1^ <> #0) and (po1^ = ' ') do begin + inc(po1); + end; + if po1^ = #0 then begin + break; + end; + po2:= po1; + end; + '"': begin + addsubstring; + po2:= po1 + 1; + repeat + inc(po1); + case po1^ of + '"': begin + addsubstring; + inc(po1); + inc(po2); + break; + end; + { + '\': begin + if (po1+1)^ = '"' then begin + addsubstring; + inc(po1); + inc(po2); + end; + end; + } + end; + until po1^ = #0; + end; + { + '\': begin + if ((po1+1)^ < ' ') or ((po1+1)^ in ['"','\']) then begin + addsubstring; + inc(po1); + if po1^ = #0 then begin + break; + end; + inc(po1); + inc(po2); + end + else begin + inc(po1); + end; + end; + } + else begin + inc(po1); + end; + end; + end; + end; + {$ifdef FPC}{$checkpointer default}{$endif} + setlength(result,count); + end; +end; + +function parsecommandline(const s: pmsechar): msestringarty; +var + po1,po2: pmsechar; + count: integer; + str1: msestring; + + procedure addsubstring; + var + int1,int2: integer; + begin + {$ifdef FPC}{$checkpointer off}{$endif} + int1:= po1-po2; + int2:= length(str1); + setlength(str1,int2+int1); + move(po2^,str1[int2+1],int1*sizeof(msechar)); + po2:= po1; + {$ifdef FPC}{$checkpointer default}{$endif} + end; + +begin + result:= nil; + count:= 0; + if s <> nil then begin + {$ifdef FPC}{$checkpointer off}{$endif} + po1:= s; + while (po1^ <> #0) and (po1^ = ' ') do begin + inc(po1); + end; + if po1^ <> #0 then begin + po2:= po1; + str1:= ''; + while true do begin + case po1^ of + ' ',#0: begin + addsubstring; + additem(result,str1,count); + str1:= ''; + while (po1^ <> #0) and (po1^ = ' ') do begin + inc(po1); + end; + if po1^ = #0 then begin + break; + end; + po2:= po1; + end; + '"': begin + addsubstring; + po2:= po1 + 1; + repeat + inc(po1); + case po1^ of + '"': begin + addsubstring; + inc(po1); + inc(po2); + break; + end; + { + '\': begin + if (po1+1)^ = '"' then begin + addsubstring; + inc(po1); + inc(po2); + end; + end; + } + end; + until po1^ = #0; + end; + { + '\': begin + if ((po1+1)^ < ' ') or ((po1+1)^ in ['"','\']) then begin + addsubstring; + inc(po1); + if po1^ = #0 then begin + break; + end; + inc(po1); + inc(po2); + end + else begin + inc(po1); + end; + end; + } + else begin + inc(po1); + end; + end; + end; + end; + {$ifdef FPC}{$checkpointer default}{$endif} + setlength(result,count); + end; +end; + +function parsecommandline(const s: string): stringarty; +begin + result:= parsecommandline(pchar(s)); +end; + +function parsecommandline(const s: msestring): msestringarty; +begin + result:= parsecommandline(pmsechar(s)); +end; + +procedure trimright1(var s: string); overload; +var + po1,po2: pchar; +begin + if s <> '' then begin + po1:= pointer(s); + po2:= po1+length(s)-1; + while (po2^ <= ' ') do begin + dec(po2); + if po2 < po1 then begin + break; + end; + end; + setlength(s,po2-po1+1); + end; +end; + +procedure trimright1(var s: msestring); overload; +var + po1,po2: pmsechar; +begin + if s <> '' then begin + po1:= pointer(s); + po2:= po1+length(s)-1; + while (po2^ <= ' ') do begin + dec(po2); + if po2 < po1 then begin + break; + end; + end; + setlength(s,po2-po1+1); + end; +end; + +function printableascii(const source: string): string; + //removes all nonprintablechars and ' ' +var + int1,int2: integer; + ca1: char; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 0 to length(source)-1 do begin + ca1:= pcharaty(source)^[int1]; + if (ca1 > ' ') and (ca1 < #127) then begin + pcharaty(result)^[int2]:= ca1; + inc(int2); + end; + end; + setlength(result,int2); +end; + +function printableascii(const source: msestring): msestring; + //removes all nonprintablechars and ' ' +var + int1,int2: integer; + ca1: msechar; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 0 to length(source)-1 do begin + ca1:= pmsecharaty(source)^[int1]; + if (ca1 > ' ') and (ca1 < #127) then begin + pmsecharaty(result)^[int2]:= ca1; + inc(int2); + end; + end; + setlength(result,int2); +end; + +function removechar(const source: string; a: char): string; + //removes all a +var + int1,int2: integer; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 1 to length(source) do begin + if source[int1] <> a then begin + pcharaty(result)^[int2]:= source[int1]; + inc(int2); + end; + end; + setlength(result,int2); +end; + +procedure removechar1(var dest: string; a: char); + //removes all a +begin + dest:= removechar(dest,a); +end; + +function removechar(const source: msestring; a: msechar): msestring; + //removes all a +var + int1,int2: integer; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 1 to length(source) do begin + if source[int1] <> a then begin + pmsecharaty(result)^[int2]:= source[int1]; + inc(int2); + end; + end; + setlength(result,int2); +end; + +procedure removechar1(var dest: msestring; a: msechar); + //removes all a +begin + dest:= removechar(dest,a); +end; + +function replacechar(const source: string; old,new: char): string; + //replaces a by b +begin + result:= source; + replacechar1(result,old,new); +end; +{ +procedure replacechar1(var dest: string; a,b: char); + //replaces a by b +var + int1: integer; +begin + uniquestring(dest); + for int1:= 0 to length(dest)-1 do begin + if pcharaty(dest)^[int1] = a then begin + pcharaty(dest)^[int1]:= b; + end; + end; +end; +} +procedure replacechar1(var dest: string; old,new: char); + //replaces a by b +var + pd,pe: pchar; +begin + uniquestring(dest); + pd:= pointer(dest); + pe:= pd + length(dest); + while pd < pe do begin + if pd^ = old then begin + pd^:= new; + end; + inc(pd); + end; +end; + +function replacechar(const source: msestring; old,new: msechar): msestring; + //replaces a by b +begin + result:= source; + replacechar1(result,old,new); +end; +{ +procedure replacechar1(var dest: msestring; a,b: msechar); + //replaces a by b +var + int1: integer; +begin + uniquestring(dest); + for int1:= 0 to length(dest)-1 do begin + if pmsecharaty(dest)^[int1] = a then begin + pmsecharaty(dest)^[int1]:= b; + end; + end; +end; +} + +procedure replacechar1(var dest: msestring; old,new: msechar); + //replaces a by b +var + pd,pe: pmsechar; +begin + uniquestring(dest); + pd:= pointer(dest); + pe:= pd + length(dest); + while pd < pe do begin + if pd^ = old then begin + pd^:= new; + end; + inc(pd); + end; +end; + +procedure replacetext1(var dest: string; index: integer; const a: string); + //dest will be extended with spaces if necessary +var + int1,int2: integer; +begin + uniquestring(dest); + if length(dest) < index + length(a) then begin + int1:= length(dest); + setlength(dest,index+length(a)-1); + for int2:= int1 to index - 2 do begin + pcharaty(dest)^[int2]:= ' '; + end; + end; + dec(index); + int1:= length(a); + if index < 0 then begin + int1:= int1 + index; + index:= 0; + end; + for int2:= 0 to int1-1 do begin + pcharaty(dest)^[int2+index]:= pcharaty(a)^[int2]; + end; +end; + +function replacetext(const source: string; index: integer; a: string): string; +begin + result:= source; + replacetext1(result,index,a); +end; + +procedure replacetext1(var dest: msestring; index: integer; const a: msestring); + //dest will be extended with spaces if necessary +var + int1,int2: integer; +begin + uniquestring(dest); + if length(dest) < index + length(a) then begin + int1:= length(dest); + setlength(dest,index+length(a)-1); + for int2:= int1 to index - 2 do begin + pmsecharaty(dest)^[int2]:= ' '; + end; + end; + dec(index); + int1:= length(a); + if index < 0 then begin + int1:= int1 + index; + index:= 0; + end; + for int2:= 0 to int1-1 do begin + pmsecharaty(dest)^[int2+index]:= pmsecharaty(a)^[int2]; + end; +end; + +function replacetext(const source: msestring; index: integer; a: msestring): msestring; +begin + result:= source; + replacetext1(result,index,a); +end; + +procedure addstringsegment(var dest: msestring; const a,b: pmsechar); +var + int1,int2: integer; +begin + int1:= length(dest); + int2:= b-a; + setlength(dest,int1 + int2); + move(a^,dest[int1+1],int2*sizeof(msechar)); +end; + +function stringsegment(a,b: pchar): string; +var + int1: integer; +begin + int1:= b - a; + setlength(result,int1); + move(a^,result[1],int1*sizeof(char)); +end; + +function stringsegment(a,b: pmsechar): msestring; +var + int1: integer; +begin + int1:= b - a; + setlength(result,int1); + move(a^,result[1],int1*sizeof(msechar)); +end; + +function countleadingchars(const str: msestring; char: msechar): integer; +var + int1: integer; + po1,po2: pmsechar; +begin + int1:= length(str); + if int1 > 0 then begin + po1:= pointer(str); + po2:= msestrlnscan(po1,' ',int1); + if po2 = nil then begin + result:= int1; + end + else begin + result:= po2-po1; + end; + end + else begin + result:= -1; //leer + end; +end; + +function countleadingchars(const str: string; char: char): integer; +var + int1: integer; + po1,po2: pchar; +begin + int1:= length(str); + if int1 > 0 then begin + po1:= pointer(str); + po2:= strlnscan(po1,' ',int1); + if po2 = nil then begin + result:= int1; + end + else begin + result:= po2-po1; + end; + end + else begin + result:= -1; //leer + end; +end; + +function nullstring(const count: integer): string; +begin + if count > 0 then begin + setlength(result,count); + fillchar(pointer(result)^,count,#0 ); + end + else begin + result:= ''; + end; +end; + +function charstring(ch: char; count: integer): string; overload; +begin + if count > 0 then begin + setlength(result,count); + for count:= count - 1 downto 0 do begin + (pchar(pointer(result)) + count)^:= ch; + // result[count]:= ch; + end; + end + else begin + result:= ''; + end; +end; + +function charstring(ch: msechar; count: integer): msestring; overload; +begin + if count > 0 then begin + setlength(result,count); + for count:= count - 1 downto 0 do begin + (pmsechar(pointer(result)) + count)^:= ch; + // result[count]:= ch; + end; + end + else begin + result:= ''; + end; +end; +{ +function posmse(substring: pmsechar; const s: lmsestringty): pmsechar; +var + po1: pmsechar; + int1: integer; +begin + if (substring <> nil) and (substring^ <> #0) and + (s.po <> nil) and (s.len > 0) then begin + result:= msestrlscan(s.po,substring^,s.len); + int1:= s.len - (s.po-result) - 1; + if result <> nil then begin + po1:= result; + while (substring^ <> #0) and (int1 > 0) do begin + dec(int1); + inc(substring); + inc(po1); + if po1^ <> substring^ then begin + break; + end; + end; + if po1^ <> #0 then begin + result:= nil; + end; + end; + end + else begin + result:= nil; + end; +end; +} +{ +function msestrpos(const substr: msestring; const s: msestring): integer; +var + po1,po2,po3,po4: pmsechar; +begin + po3:= pmsechar(substr); + if po3^ <> #0 then begin + po4:= pmsechar(s); + repeat + while (po4^ <> #0) and (po4^ <> po3^) do begin + inc(po4); + end; + po1:= po3; + po2:= po4; + while (po1^ <> #0) and (po1^ = po2^) do begin + inc(po1); + inc(po2); + end; + if po1^ = #0 then begin + result:= po4 - pmsechar(s) + 1; + exit; + end; + inc(po4); + until po2^ = #0; + end; + result:= 0; +end; + +function msetextpos1(const substrlower,substrupper: msestring; const s: msestring): integer; +var + po1l,po1u,po2,po3l,po3u,po4: pmsechar; +begin + po3l:= pmsechar(substrlower); + po3u:= pmsechar(substrupper); + if po3l^ <> #0 then begin + po4:= pmsechar(s); + repeat + while (po4^ <> #0) and (po4^ <> po3l^) and (po4^ <> po3u^) do begin + inc(po4); + end; + po1l:= po3l; + po1u:= po3u; + po2:= po4; + while (po1l^ <> #0) and ((po1l^ = po2^) or (po1u^ = po2^)) do begin + inc(po1l); + inc(po1u); + inc(po2); + end; + if po1l^ = #0 then begin + result:= po4 - pmsechar(s) + 1; + exit; + end; + inc(po4); + until po2^ = #0; + end; + result:= 0; +end; + + +function msetextpos(const substr: msestring; const s: msestring): integer; + //substr has to be uppercase +begin + result:= msetextpos1(mseuppercase(substr),mseuppercase(substr),s); +end; +} + +function charuppercase(const c: char): char; +begin + result:= upperchars[c]; +end; + +function charuppercase(const c: msechar): msechar; +begin + if c < #$100 then begin + result:= msechar(byte(upperchars[char(byte(c))])); + end + else begin + result:= c; + end; +end; + +function struppercase(const s: string): string; overload; +var + int1,int2: integer; +begin + int1:= length(s); + setlength(result,int1); + for int2:= int1 - 1 downto 0 do begin + pcharaty(result)^[int2]:= upperchars[pcharaty(s)^[int2]]; + end; +end; + +function struppercase(const s: msestring): msestring; overload; +var + ch1: msechar; + int1: integer; + po1,po2: pmsecharaty; +begin + setlength(result,length(s)); + po1:= pointer(s); + po2:= pointer(result); + for int1:= length(s) - 1 downto 0 do begin + ch1:= po1^[int1]; + if (ch1 >= 'a') and (ch1 <= 'z') then begin + inc(ch1,ord('A') - ord('a')); + end; + po2^[int1]:= ch1; + end; +end; + +procedure struppercase1(var s: msestring); overload; +var + ch1: msechar; + int1: integer; + po1: pmsecharaty; +begin + po1:= pointer(s); + for int1:= 0 to length(s) - 1 do begin + ch1:= po1^[int1]; + if (ch1 >= 'a') and (ch1 <= 'z') then begin + inc(ch1,ord('A') - ord('a')); + end; + po1^[int1]:= ch1; + end; +end; + +function struppercase(const s: lmsestringty): msestring; overload; +var + Ch1: msechar; + int1: Integer; + Source, Dest: Pmsechar; +begin + int1:= s.len; + setlength(result,int1); + Source := s.po; + Dest := Pointer(Result); + while int1 > 0 do begin + Ch1 := Source^; + if (Ch1 >= 'a') and (Ch1 <= 'z') then Dec(Ch1, 32); + Dest^ := Ch1; + Inc(Source); + Inc(Dest); + Dec(int1); + end; +end; + +function struppercase(const s: lstringty): string; overload; +var + int1: integer; +begin + setlength(result,s.len); + for int1:= 0 to s.len - 1 do begin + pcharaty(result)^[int1]:= upperchars[pcharaty(s.po)^[int1]]; + end; +end; + +function charlowercase(const c: char): char; +begin + result:= lowerchars[c]; +end; + +function charlowercase(const c: msechar): msechar; +begin + if ord(c) < $100 then begin + result:= msechar(lowerchars[char(c)]); + end + else begin + result:= c; + end; +end; + +function strlowercase(const s: string): string; overload; +var + int1,int2: integer; +begin + int1:= length(s); + setlength(result,int1); + for int2:= int1 - 1 downto 0 do begin + pcharaty(result)^[int2]:= lowerchars[pcharaty(s)^[int2]]; + end; +end; + +function strlowercase(const s: msestring): msestring; overload; +var + ch1: msechar; + int1: integer; + po1,po2: pmsecharaty; +begin + setlength(result,length(s)); + po1:= pointer(s); + po2:= pointer(result); + for int1:= length(s) - 1 downto 0 do begin + ch1:= po1^[int1]; + if (ch1 >= 'A') and (ch1 <= 'Z') then begin + inc(ch1,ord('a') - ord('A')); + end; + po2^[int1]:= ch1; + end; +end; + +procedure strlowercase1(var s: msestring); overload; +var + ch1: msechar; + int1: integer; + po1: pmsecharaty; +begin + po1:= pointer(s); + for int1:= 0 to length(s) - 1 do begin + ch1:= po1^[int1]; + if (ch1 >= 'A') and (ch1 <= 'Z') then begin + inc(ch1,ord('a') - ord('A')); + end; + po1^[int1]:= ch1; + end; +end; + +function strlowercase(const s: lmsestringty): msestring; overload; +var + Ch1: msechar; + int1: Integer; + Source, Dest: Pmsechar; +begin + int1:= s.len; + setlength(result,int1); + Source := s.po; + Dest := Pointer(Result); + while int1 > 0 do begin + Ch1 := Source^; + if (Ch1 >= 'A') and (Ch1 <= 'Z') then Dec(Ch1, 32); + Dest^ := Ch1; + Inc(Source); + Inc(Dest); + Dec(int1); + end; +end; + +function strlowercase(const s: lstringty): string; overload; +var + int1: integer; +begin + setlength(result,s.len); + for int1:= 0 to s.len - 1 do begin + pcharaty(result)^[int1]:= lowerchars[pcharaty(s.po)^[int1]]; + end; +end; + +function lstringtostring(const value: lmsestringty): msestring; overload; +begin + setlength(result,value.len); + move(value.po^,result[1],value.len*sizeof(msechar)); +end; + +function lstringtostring(const value: pmsechar; + const len: integer): msestring; overload; +begin + setlength(result,len); + move(value^,result[1],len*sizeof(msechar)); +end; + +function lstringtostring(const value: lstringty): string; overload; +begin + setlength(result,value.len); + move(value.po^,result[1],value.len*sizeof(char)); +end; + +function lstringtostring(const value: pchar; + const len: integer): string; overload; +begin + setlength(result,len); + move(value^,result[1],len*sizeof(char)); +end; + +procedure stringtolstring(const value: string; var{out} res: lstringty); +begin + res.po:= pointer(value); + res.len:= length(value); +end; + +procedure stringtolstring(const value: msestring; var{out} res: lmsestringty); + inline; +begin + res.po:= pointer(value); + res.len:= length(value); +end; + +function stringtolstring(const value: string): lstringty; inline; +begin + result.po:= pointer(value); + result.len:= length(value); +end; + +function stringtolstring(const value: msestring): lmsestringty; inline; +begin + result.po:= pointer(value); + result.len:= length(value); +end; + +function lstringartostringar(const value: lstringarty): stringarty; +var + int1: integer; +begin + setlength(result,length(value)); + for int1:= 0 to high(value) do begin + with value[int1] do begin + setstring(result[int1],po,len); + end; + end; +end; + +procedure nextword(const value: msestring; out res: lmsestringty); overload; +var + po1: pmsechar; +begin + res.po:= msestrlscan(pointer(value),' ',length(value)); + res.len:= length(value)-(res.po-pointer(value)); + po1:= msestrlnscan(res.po,' ',res.len); + if po1 <> nil then begin + res.len:= po1-res.po; + end; +end; + +procedure nextword(const value: string; out res: lstringty); overload; +var + po1: pchar; +begin + res.po:= strlnscan(pointer(value),' ',length(value)); + res.len:= length(value)-(res.po-pointer(value)); + po1:= strlscan(res.po,' ',res.len); + if po1 <> nil then begin + res.len:= po1-res.po; + end; +end; + +procedure nextword(var value: lmsestringty; out res: lmsestringty); overload; +var + po1: pmsechar; + int1: integer; +begin + res.po:= msestrlnscan(value.po,' ',value.len); + if res.po = nil then begin + int1:= value.len; + end + else begin + int1:= res.po-value.po; + end; + res.len:= value.len-int1; + po1:= msestrlscan(res.po,' ',res.len); + if po1 <> nil then begin + res.len:= po1-res.po; + end; + int1:= int1 + res.len; + inc(value.po,int1); + dec(value.len,int1); +end; + +procedure nextword(var value: lstringty; out res: lstringty); overload; +var + po1: pchar; + int1: integer; +begin + res.po:= strlnscan(value.po,' ',value.len); + if res.po = nil then begin + int1:= value.len; + end + else begin + int1:= res.po-value.po; + end; + res.len:= value.len-int1; + po1:= strlscan(res.po,' ',res.len); + if po1 <> nil then begin + res.len:= po1-res.po; + end; + int1:= int1 + res.len; + inc(value.po,int1); + dec(value.len,int1); +end; + +procedure nextword(var value: lstringty; out res: string); overload; +var + lstr1: lstringty; +begin + nextword(value,lstr1); + setstring(res,lstr1.po,lstr1.len); +end; + +function nextword(var start: pchar): string; +var + po1,po2: pchar; +begin + po1:= start; + while (po1^ = ' ') and (po1^ <> #0) do begin + inc(po1); + end; + po2:= po1; + while (po2^ <> ' ') and (po2^ <> #0) do begin + inc(po2); + end; + setlength(result,po2-po1); + move(po1^,pchar(pointer(result))^,pchar(pointer(po2))-pchar(pointer(po1))); + start:= po2; +end; + +function nextword(var start: pmsechar): msestring; +var + po1,po2: pmsechar; +begin + po1:= start; + while (po1^ = ' ') and (po1^ <> #0) do begin + inc(po1); + end; + po2:= po1; + while (po2^ <> ' ') and (po2^ <> #0) do begin + inc(po2); + end; + setlength(result,po2-po1); + move(po1^,pmsechar(pointer(result))^,pchar(pointer(po2))-pchar(pointer(po1))); + start:= po2; +end; + +procedure lstringgoback(var value: lstringty; const res: lstringty); +begin + dec(value.po,res.len); + inc(value.len,res.len); +end; + +function nextquotedstring(var value: lstringty; out res: string): boolean; +var + po1: pchar; + int1,int2,int3: integer; +begin + result:= false; + res:= ''; + po1:= strlnscan(value.po,' ',value.len); + if po1 = nil then begin + int1:= value.len; + end + else begin + int1:= po1-value.po; + end; + if (po1 <> nil) and (po1^ = '''') then begin + result:= true; + inc(po1); + int2:= 0; + int3:= value.len-int1; + setlength(res,int3); //maximum + while po1^ <> #0 do begin + if po1^ <> '''' then begin + inc(int2); + res[int2]:= po1^; + end + else begin + inc(po1); + if po1^ = '''' then begin + inc(int2); + res[int2]:= po1^; + end + else begin + break; + end; + end; + inc(po1); + end; + setlength(res,int2); + int1:= po1-value.po; + end; + inc(value.po,int1); + dec(value.len,int1); +end; + +function shrinkpathellipse(var value: msestring): boolean; +const + ellipsis = '...' + pathdelim; +var + po1,po2: pmsechar; + int1,int2: integer; +begin + result:= false; + int1:= pos(ellipsis,value); + if int1 = 0 then begin + int1:= pos(pathdelim,value); + if int1 > 0 then begin + inc(int1); //ellipsenstart + int2:= int1; //ellipsenend; + end + else exit; //shrink unmoeglich + end + else begin + int2:= int1 + length(ellipsis); + end; + po1:= @value[int2]; //ende ellipse + po2:= msestrlscan(po1,pathdelim,length(value)-int2); + if po2 <> nil then begin + inc(po2); + value:= copy(value,1,int1-1) + ellipsis + copy(value,int2 + (po2-po1),bigint); + result:= true; + end; +end; + +function shrinkstring(const value: msestring; maxcharcount: integer): msestring; +begin + result:= value; + repeat + until (length(result) <= maxcharcount) or not shrinkpathellipse(result); +end; + +procedure extendstring(var value: string; const mincharcount: integer); +var + int1: integer; +begin + int1:= length(value); + if int1 < mincharcount then begin + setlength(value,mincharcount); + for int1:= int1 to mincharcount do begin + pchar(pointer(value))[int1]:= ' '; + end; + end; +end; + +procedure extendstring(var value: msestring; const mincharcount: integer); +var + int1: integer; +begin + int1:= length(value); + if int1 < mincharcount then begin + setlength(value,mincharcount); + for int1:= int1 to mincharcount do begin + pmsechar(pointer(value))[int1]:= ' '; + end; + end; +end; + +function checkfirstchar(const value: string; achar: char): pchar; + //nil wenn erster char nicht space <> achar, ^achar sonst +begin + result:= strlnscan(pointer(value),' ',length(value)); + if result <> nil then begin + if result^ <> achar then begin + result:= nil; + end; + end; +end; + +function lastline(const atext: msestring): msestring; +var + po1: pmsechar; + int1: integer; +begin + po1:= msestrlrscan(pmsechar(atext),c_linefeed,length(atext)); + if po1 = nil then begin + result:= atext; + end + else begin + inc(po1); + int1:= length(atext)-(po1-pmsechar(pointer(atext))); + setlength(result,int1); + move(po1^,pointer(result)^,int1*sizeof(msechar)); +// result:= po1; + end; +end; + +function firstline(const atext: msestring): msestring; +var + po1: pmsechar; +begin + if atext <> '' then begin + po1:= pointer(atext); + while (po1^ <> c_linefeed) and (po1^ <> #0) do begin + inc(po1); + end; + if (po1 > pointer(atext)) and ((po1-1)^ = c_return) then begin + dec(po1); + end; + result:= psubstr(pmsechar(pointer(atext)),po1); + end + else begin + result:= ''; + end; +end; +{ +function firstline(atext: msestring): msestring; +var + po1: pmsechar; +begin + po1:= msestrlscan(pmsechar(atext),c_linefeed,length(atext)); + if po1 = nil then begin + result:= atext; + end + else begin + dec(po1); + if po1 >= @atext[1] then begin + if po1^ <> c_return then begin + inc(po1); + end; + end + else begin + inc(po1); + end; + setlength(result,po1-pmsechar(@atext[1])); + move(po1^,result[1],length(result)*sizeof(result[1])); + end; +end; +} +procedure textdim(const atext: msestring; out firstx,lastx,y: integer); +begin + Y:= countchars(atext,c_linefeed); + if Y = 0 then begin + firstx:= length(atext); + lastx:= firstx; + end + else begin + lastx:= length(lastline(atext)); + firstx:= length(firstline(atext)); + end; +end; + +function encodesearchoptions(const caseinsensitive: boolean = false; + const wholeword: boolean = false; + const wordstart: boolean = false; + const backward: boolean = false): searchoptionsty; +begin + result:= []; + if caseinsensitive then include(result,so_caseinsensitive); + if wholeword then include(result,so_wholeword); + if wordstart then include(result,so_wordstart); + if backward then include(result,so_backward); +end; + +function quotestring(value: string; quotechar: char; + const force: boolean = true; + const separator: char = ' '): string; overload; +var + ps,pd,pe: pchar; +begin + if force or (findchar(value,quotechar) > 0) or + (separator <> #0) and (findchar(value,separator) > 0)then begin + setlength(result,length(value)*2+2); //max + pd:= pchar(pointer(result)); + pd^:= quotechar; + inc(pd); + if value <> '' then begin + ps:= pchar(pointer(value)); + pe:= ps+length(value); + while ps < pe do begin + pd^:= ps^; + inc(pd); + if ps^ = quotechar then begin + pd^:= quotechar; + inc(pd); + end; + inc(ps); + end; + end; + pd^:= quotechar; + inc(pd); + setlength(result,pd-pchar(pointer(result))); + end + else begin + result:= value; + end; +end; + +function quotestring(value: msestring; quotechar: msechar; + const force: boolean = true; + const separator: msechar = ' '): msestring; overload; +var + ps,pd,pe: pmsechar; +begin + if force or (findchar(value,quotechar) > 0) or + (separator <> #0) and (findchar(value,separator) > 0) then begin + setlength(result,length(value)*2+2); //max + pd:= pmsechar(pointer(result)); + pd^:= quotechar; + inc(pd); + if value <> '' then begin + ps:= pmsechar(pointer(value)); + pe:= ps+length(value); + while ps < pe do begin + pd^:= ps^; + inc(pd); + if ps^ = quotechar then begin + pd^:= quotechar; + inc(pd); + end; + inc(ps); + end; + end; + pd^:= quotechar; + inc(pd); + setlength(result,pd-pmsechar(pointer(result))); + end + else begin + result:= value; + end; +end; + +function unquotestring(value: string; quotechar: char): string; overload; +var + ps,pd,pe: pchar; +begin + result:= value; + if (value <> '') and (value[1] = quotechar) then begin + ps:= pchar(pointer(value)); + pe:= ps + length(value); + setlength(result,length(value)); //unique, max + pd:= pchar(pointer(result)); + while ps < pe do begin + if ps^ = quotechar then begin + inc(ps); + end; + pd^:= ps^; + inc(ps); + inc(pd); + end; + if ps > pe then begin + dec(pd); //remove trailing quote + end; + setlength(result,pd-pchar(pointer(result))); + end; +end; + +function unquotestring(value: msestring; + quotechar: msechar): msestring; +var + ps,pd,pe: pmsechar; +begin + result:= value; + if (value <> '') and (value[1] = quotechar) then begin + ps:= pmsechar(pointer(value)); + pe:= ps + length(value); + setlength(result,length(value)); //unique, max + pd:= pmsechar(pointer(result)); + while ps < pe do begin + if ps^ = quotechar then begin + inc(ps); + end; + pd^:= ps^; + inc(ps); + inc(pd); + end; + if ps > pe then begin + dec(pd); //remove trailing quote + end; + setlength(result,pd-pmsechar(pointer(result))); + end; +end; + + +const + escapechar = '\'; + +function quoteescapedstring(value: string; quotechar: char; + const force: boolean = true; + const separator: char = ' '): string; +var + ps,pd,pe: pchar; +begin + if force or (findchar(value,quotechar) > 0) or + (separator <> #0) and (findchar(value,separator) > 0) then begin + setlength(result,length(value)*2+2); //max + pd:= pchar(pointer(result)); + pd^:= quotechar; + inc(pd); + if value <> '' then begin + ps:= pchar(pointer(value)); + pe:= ps+length(value); + while ps < pe do begin + pd^:= ps^; + if ps^ = quotechar then begin + pd^:= escapechar; + inc(pd); + pd^:= quotechar; + end; + if ps^ = escapechar then begin + inc(pd); + pd^:= escapechar; + end; + inc(pd); + inc(ps); + end; + end; + pd^:= quotechar; + inc(pd); + setlength(result,pd-pchar(pointer(result))); + end + else begin + result:= value; + end; +end; + +function quoteescapedstring(value: msestring; quotechar: msechar; + const force: boolean = true; + const separator: msechar = ' '): msestring; +var + ps,pd,pe: pmsechar; +begin + if force or (findchar(value,quotechar) > 0) or + (separator <> #0) and (findchar(value,separator) > 0) then begin + setlength(result,length(value)*2+2); //max + pd:= pmsechar(pointer(result)); + pd^:= quotechar; + inc(pd); + if value <> '' then begin + ps:= pmsechar(pointer(value)); + pe:= ps+length(value); + while ps < pe do begin + pd^:= ps^; + if ps^ = quotechar then begin + pd^:= escapechar; + inc(pd); + pd^:= quotechar; + end; + if ps^ = escapechar then begin + inc(pd); + pd^:= escapechar; + end; + inc(pd); + inc(ps); + end; + end; + pd^:= quotechar; + inc(pd); + setlength(result,pd-pmsechar(pointer(result))); + end + else begin + result:= value; + end; +end; + +function extractquotedstr(const value: msestring): msestring; + //entfernt vorhandene paare ' und " +begin + if (value <> '') and ((value[1] = '"') or (value[1] = '''')) then begin + result:= unquotestring(value,value[1]); + end + else begin + result:= value; + end; +end; + +function lineatindex(const value: msestring; const index: int32): msestring; +var + po1,po2,ps,pe: pmsechar; +begin + if value <> '' then begin + ps:= pointer(value); + pe:= ps + length(value); + po1:= ps + index; + po2:= po1; + if (po1^ = c_linefeed) and (po1 > ps) then begin + dec(po1); + end; + if (po1^ = c_return) and (po1 > ps) then begin + dec(po1); + end; + while (po1^ <> c_linefeed) and (po1 > ps) do begin + dec(po1); + end; + if po1^ = c_linefeed then begin + inc(po1); + end; + while not ((po2^ = c_return) or (po2^ = c_linefeed)) and (po2 < pe) do begin + inc(po2); + end; + result:= psubstr(po1,po2); + end + else begin + result:= ''; + end; +end; + +procedure wordatindex(const value: msestring; const index: integer; + out first,pastlast: pmsechar; + const delimchars: msestring; + const nodelimstrings: array of msestring); + + function checkdelimchars(achar: msechar): boolean; + var + po1: pmsechar; + begin + po1:= pmsechar(delimchars); + result:= false; + while po1^ <> #0 do begin + if po1^ = achar then begin + result:= true; + break; + end; + inc(po1); + end; + end; + + function checknodelimstringsdown(var po1: pmsechar; var int1: integer): boolean; + var + {bo1,}bo2: boolean; + int2,int3,int4: integer; + po2: pmsechar; + begin + result:= true; + for int2:= high(nodelimstrings) downto 0 do begin + po2:= po1; + int4:= length(nodelimstrings[int2])-1; + int3:= int1 - int4; + if int3 >= 0 then begin + bo2:= true; + for int3:= int4 downto 0 do begin + if (pmsechar(pointer(nodelimstrings[int2]))+int3)^ <> po2^ then begin + bo2:= false; + break; + end; + dec(po2); + end; + if bo2 then begin + inc(po2); + result:= false; + int1:= int1 - (po1 - po2); + po1:= po2; + break; + end; + end; + end; + end; + + function checknodelimstringsup(var po1: pmsechar; var int3: integer): boolean; + var + int1,int2: integer; + bo1: boolean; + po2: pmsechar; + begin + result:= true; + for int2:= high(nodelimstrings) downto 0 do begin + bo1:= true; + po2:= po1; + for int1:= 0 to length(nodelimstrings[int2]) - 1 do begin + if po2^ <> (pmsechar(pointer(nodelimstrings[int2]))+int1)^ then begin + bo1:= false; + break; + end; + inc(po2); + end; + if bo1 then begin + dec(po2); + int3:= int3 - (po1 - po2); + po1:= po2; + result:= false; + break; + end; + end; + end; + +var + int1: integer; + po1: pmsechar; +// bo1{,bo2}: boolean; +begin + first:= nil; + pastlast:= nil; + if (index >= 0) and (index < length(value)) then begin + first:= pmsechar(pointer(value)) + index; + po1:= first; + int1:= index; + while int1 >= 0 do begin + if checkdelimchars(po1^) and checknodelimstringsdown(po1,int1) then begin + if po1 = first then begin + first:= nil; + exit; + end; + break; + end; + dec(po1); + dec(int1); + end; + pastlast:= first + 1; + first:= po1 + 1; + int1:= length(value) - index - 2; + while int1 >= 0 do begin + if checkdelimchars(pastlast^) and checknodelimstringsup(pastlast,int1) then begin + break; + end; + inc(pastlast); + dec(int1); + end; + end; +end; + +function wordatindex(const value: msestring; const index: integer; + const delimchars: msestring; + const nodelimstrings: array of msestring): msestring; +var + po1,po2: pmsechar; +begin + wordatindex(value,index,po1,po2,delimchars,nodelimstrings); + result:= copy(msestring(po1),1,po2-po1); +end; + +function checkkeyword(const aname: string; const anames; + const ahigh: integer): cardinal; +var + int1: integer; + po1: pchar; +begin + result:= 0; + po1:= pchar(pointer(aname)); + if po1 <> nil then begin + for int1:= 1 to ahigh do begin + if strcomp(po1,pchar(pointer(stringaty(anames)[int1]))) = 0 then begin + result:= int1; + break; + end; + end; + end; +end; + +function checkkeyword(const aname: msestring; const anames; + const ahigh: integer): cardinal; +var + int1: integer; + po1: pmsechar; +begin + result:= 0; + po1:= pmsechar(pointer(aname)); + if po1 <> nil then begin + for int1:= 1 to ahigh do begin + if msestrcomp(po1,pmsechar(pointer(stringaty(anames)[int1]))) = 0 then begin + result:= int1; + break; + end; + end; + end; +end; + +function checkkeyword(const aname: pchar; const anames; + const ahigh: integer): cardinal; +var + int1: integer; + po1: pchar; +begin + result:= 0; + po1:= aname; + if po1 <> nil then begin + for int1:= 1 to ahigh do begin + if strcomp(po1,pchar(pointer(stringaty(anames)[int1]))) = 0 then begin + result:= int1; + break; + end; + end; + end; +end; + +function checkkeyword(const aname: pmsechar; const anames; + const ahigh: integer): cardinal; +var + int1: integer; + po1: pmsechar; +begin + result:= 0; + po1:= aname; + if po1 <> nil then begin + for int1:= 1 to ahigh do begin + if msestrcomp(po1,pmsechar(pointer(stringaty(anames)[int1]))) = 0 then begin + result:= int1; + break; + end; + end; + end; +end; + +//todo: optimise +function msestringsearch(const substring,s: msestring; start: integer; + const options: searchoptionsty; + const substringupcase: msestring = ''): integer; +var + int1,int2: integer; + ch1,ch2: msechar; + str1,str2: msestring; + opt1: searchoptionsty; + slen,sublen: int32; + +begin + result:= 0; + if (length(substring) = 0) or (length(s) = 0) then begin + exit; + end; + sublen:= length(substring); + slen:= length(s); + if so_backward in options then begin //backward search + if start <= 0 then begin + exit; + end; + if start > slen then begin + start:= slen; + end; + if options * [so_wholeword,so_wordstart] <> [] then begin + opt1:= options - [so_wholeword,so_wordstart]; + result:= start; + repeat + result:= msestringsearch(substring,s,result,opt1,substringupcase); + if result <> 0 then begin + if (result = slen) or not isnamechar(s[result+1]) then begin + if not (so_wholeword in options) then begin + break; //so_wordstart + end; + if (result - length(substring) > 0) then begin + break; + end + else begin + if not isnamechar(s[result - length(substring)]) then begin + break; //io + end + else begin + dec(result); //kein ganzes wort + end; + end; + end + else begin + dec(result); + end; + end + else begin + break; + end; + until result < 1; + if result < 1 then begin + result:= 0; + end; + end + else begin + if so_caseinsensitive in options then begin + if substringupcase = '' then begin + str1:= mseuppercase(substring); + str2:= mselowercase(substring); + end + else begin + str1:= substringupcase; + str2:= substring; + end; + ch2:= str1[sublen]; + ch1:= str2[sublen]; + for int1:= start downto sublen do begin + if (s[int1] = ch1) or (s[int1] = ch2) then begin + result:= int1-sublen; + for int2:= sublen downto 1 do begin + if (s[result+int2] <> str1[int2]) and + (s[result+int2] <> str2[int2]) then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + result:= result+sublen-1; + break; + end; + end + end + else begin + ch1:= substring[sublen]; //casesensitive + for int1:= start downto sublen do begin + if s[int1] = ch1 then begin + result:= int1-sublen; + for int2:= sublen downto 1 do begin + if s[result+int2] <> substring[int2] then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + result:= result+sublen-1; + break; + end; + end + end; + end; + end + else begin //not backward + if options * [so_wholeword,so_wordstart] <> [] then begin + opt1:= options - [so_wholeword,so_wordstart]; + result:= start; + repeat + result:= msestringsearch(substring,s,result,opt1,substringupcase); + if result <> 0 then begin + if (result = 1) or not isnamechar(s[result-1]) then begin + if not (so_wholeword in options) then begin + break; //so_wordstart + end; + if result + sublen > slen then begin + break; + end + else begin + if not isnamechar(s[result + sublen]) then begin + break; //io + end + else begin + inc(result); //kein ganzes wort + end; + end; + end + else begin + inc(result); + end; + end + else begin + break; + end; + until result > slen; + if result > slen then begin + result:= 0; + end; + end + else begin + if so_caseinsensitive in options then begin + if substringupcase = '' then begin + str1:= mseuppercase(substring); + str2:= mselowercase(substring); + end + else begin + str1:= substringupcase; + str2:= substring; + end; + ch2:= str1[1]; + ch1:= str2[1]; + for int1:= start to slen do begin + if (s[int1] = ch1) or (s[int1] = ch2) then begin + result:= int1-1; + for int2:= 1 to sublen do begin + if (s[result+int2] <> str1[int2]) and + (s[result+int2] <> str2[int2]) then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + break; + end; + end + end + else begin + ch1:= substring[1]; + for int1:= start to slen do begin + if s[int1] = ch1 then begin + result:= int1-1; + for int2:= 1 to sublen do begin + if s[result+int2] <> substring[int2] then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + break; + end; + end + end; + end; + end; //not backward +end; + +//todo: optimise +function stringsearch(const substring,s: ansistring; start: integer; + const options: searchoptionsty; + const substringupcase: ansistring = ''): integer; +var + int1,int2: integer; + ch1,ch2: char; + str1,str2: ansistring; + opt1: searchoptionsty; + slen,sublen: int32; + +begin + result:= 0; + if (length(substring) = 0) or (length(s) = 0) then begin + exit; + end; + sublen:= length(substring); + slen:= length(s); + if so_backward in options then begin //backward search + if start <= 0 then begin + exit; + end; + if start > slen then begin + start:= slen; + end; + if options * [so_wholeword,so_wordstart] <> [] then begin + opt1:= options - [so_wholeword,so_wordstart]; + result:= start; + repeat + result:= stringsearch(substring,s,result,opt1,substringupcase); + if result <> 0 then begin + if (result = slen) or not isnamechar(s[result+1]) then begin + if not (so_wholeword in options) then begin + break; //so_wordstart + end; + if (result - length(substring) > 0) then begin + break; + end + else begin + if not isnamechar(s[result - length(substring)]) then begin + break; //io + end + else begin + dec(result); //kein ganzes wort + end; + end; + end + else begin + dec(result); + end; + end + else begin + break; + end; + until result < 1; + if result < 1 then begin + result:= 0; + end; + end + else begin + if so_caseinsensitive in options then begin + if substringupcase = '' then begin + str1:= uppercase(substring); + str2:= lowercase(substring); + end + else begin + str1:= substringupcase; + str2:= substring; + end; + ch2:= str1[sublen]; + ch1:= str2[sublen]; + for int1:= start downto sublen do begin + if (s[int1] = ch1) or (s[int1] = ch2) then begin + result:= int1-sublen; + for int2:= sublen downto 1 do begin + if (s[result+int2] <> str1[int2]) and + (s[result+int2] <> str2[int2]) then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + result:= result+sublen-1; + break; + end; + end + end + else begin + ch1:= substring[sublen]; //casesensitive + for int1:= start downto sublen do begin + if s[int1] = ch1 then begin + result:= int1-sublen; + for int2:= sublen downto 1 do begin + if s[result+int2] <> substring[int2] then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + result:= result+sublen-1; + break; + end; + end + end; + end; + end + else begin //not backward + if options * [so_wholeword,so_wordstart] <> [] then begin + opt1:= options - [so_wholeword,so_wordstart]; + result:= start; + repeat + result:= stringsearch(substring,s,result,opt1,substringupcase); + if result <> 0 then begin + if (result = 1) or not isnamechar(s[result-1]) then begin + if not (so_wholeword in options) then begin + break; //so_wordstart + end; + if result + sublen > slen then begin + break; + end + else begin + if not isnamechar(s[result + sublen]) then begin + break; //io + end + else begin + inc(result); //kein ganzes wort + end; + end; + end + else begin + inc(result); + end; + end + else begin + break; + end; + until result > slen; + if result > slen then begin + result:= 0; + end; + end + else begin + if so_caseinsensitive in options then begin + if substringupcase = '' then begin + str1:= uppercase(substring); + str2:= lowercase(substring); + end + else begin + str1:= substringupcase; + str2:= substring; + end; + ch2:= str1[1]; + ch1:= str2[1]; + for int1:= start to slen do begin + if (s[int1] = ch1) or (s[int1] = ch2) then begin + result:= int1-1; + for int2:= 1 to sublen do begin + if (s[result+int2] <> str1[int2]) and + (s[result+int2] <> str2[int2]) then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + break; + end; + end + end + else begin + ch1:= substring[1]; + for int1:= start to slen do begin + if s[int1] = ch1 then begin + result:= int1-1; + for int2:= 1 to sublen do begin + if s[result+int2] <> substring[int2] then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + break; + end; + end + end; + end; + end; //not backward +end; + +function replacestring(const s: msestring; oldsub: msestring; + const newsub: msestring; + const options: searchoptionsty = []): msestring; +var + po1,po2,po3,poend: pmsechar; +// pold: pmsechar; + oldhigh,newhigh: integer; + int1,int2: integer; + ch1: msechar; + bo1,bo2,bo3: boolean; + s1: msestring; +begin + int1:= length(s); + if (int1 = 0) or (length(oldsub) = 0) then begin + result:= s; + exit; + end; + oldhigh:= length(oldsub)-1; + newhigh:= length(newsub)-1; + po1:= pointer(s); + poend:= po1; + if so_caseinsensitive in options then begin + s1:= mseuppercase(s); + po3:= pointer(s1); + oldsub:= mseuppercase(oldsub); + end + else begin + po3:= po1; + end; + inc(poend,int1-oldhigh); + if length(newsub) > length(oldsub) then begin + int1:= (int1 div length(oldsub) + 1) * length(newsub); + end; + setlength(result,int1); //max + po2:= pointer(result); + ch1:= oldsub[1]; + bo2:= options*[so_wholeword,so_wordstart] = []; + bo3:= not (so_wholeword in options); + while po1 < poend do begin + bo1:= po3^ = ch1; + if bo1 then begin + for int2:= 0 to oldhigh do begin + if (po3+int2)^ <> (pmsechar(pointer(oldsub))+int2)^ then begin + bo1:= false; + break; + end; + end; + bo1:= bo1 and (bo2 or + (bo3 or not isnamechar((po1+length(oldsub))^)) and + ((po1=pointer(s)) or not isnamechar((po1-1)^))); + if bo1 then begin + for int2:= 0 to newhigh do begin + po2^:= (pmsechar(pointer(newsub))+int2)^; + inc(po2); + end; + inc(po1,oldhigh); + inc(po3,oldhigh); + dec(po2); + end + else begin + po2^:= po1^; + end; + end + else begin + po2^:= po1^; + end; + inc(po1); + inc(po2); + inc(po3); + end; + inc(poend,oldhigh); + while po1 < poend do begin + po2^:= po1^; + inc(po1); + inc(po2); + end; + setlength(result,po2 - pmsechar(pointer(result))); +end; + +function replacestring(const s: string; oldsub: string; + const newsub: string; + const options: searchoptionsty = []): string; +var + po1,po2,po3,poend: pchar; +// pold: pchar; + oldhigh,newhigh: integer; + int1,int2: integer; + ch1: char; + bo1,bo2,bo3: boolean; + s1: string; +begin + int1:= length(s); + if (int1 = 0) or (length(oldsub) = 0) then begin + result:= s; + exit; + end; + oldhigh:= length(oldsub)-1; + newhigh:= length(newsub)-1; + po1:= pointer(s); + poend:= po1; + if so_caseinsensitive in options then begin + s1:= uppercase(s); + po3:= pointer(s1); + oldsub:= uppercase(oldsub); + end + else begin + po3:= po1; + end; + inc(poend,int1-oldhigh); + if length(newsub) > length(oldsub) then begin + int1:= (int1 div length(oldsub) + 1) * length(newsub); + end; + setlength(result,int1); //max + po2:= pointer(result); + ch1:= oldsub[1]; + bo2:= options*[so_wholeword,so_wordstart] = []; + bo3:= not (so_wholeword in options); + while po1 < poend do begin + bo1:= po3^ = ch1; + if bo1 then begin + for int2:= 0 to oldhigh do begin + if (po3+int2)^ <> (pchar(pointer(oldsub))+int2)^ then begin + bo1:= false; + break; + end; + end; + bo1:= bo1 and (bo2 or + (bo3 or not isnamechar((po1+length(oldsub))^)) and + ((po1=pointer(s)) or not isnamechar((po1-1)^))); + if bo1 then begin + for int2:= 0 to newhigh do begin + po2^:= (pchar(pointer(newsub))+int2)^; + inc(po2); + end; + inc(po1,oldhigh); + inc(po3,oldhigh); + dec(po2); + end + else begin + po2^:= po1^; + end; + end + else begin + po2^:= po1^; + end; + inc(po1); + inc(po2); + inc(po3); + end; + inc(poend,oldhigh); + while po1 < poend do begin + po2^:= po1^; + inc(po1); + inc(po2); + end; + setlength(result,po2 - pchar(pointer(result))); +end; + +function msePosEx(const SubStr, S: msestring; Offset: longword = 1): Integer; +//todo: optimize +var + I,X: Integer; + Len, LenSubStr: Integer; +begin + if Offset = 1 then + Result := Pos(SubStr, S) + else + begin + I := Offset; + LenSubStr := Length(SubStr); + Len := Length(S) - LenSubStr + 1; + while I <= Len do + begin + if S[I] = SubStr[1] then + begin + X := 1; + while (X < LenSubStr) and (S[I + X] = SubStr[X + 1]) do + Inc(X); + if (X = LenSubStr) then + begin + Result := I; + exit; + end; + end; + Inc(I); + end; + Result := 0; + end; +end; + +procedure reallocstring(var value: ansistring); + //macht datenkopie ohne free +var + po1: pointer; + int1: sizeint; +begin + po1:= pointer(value); + if po1 <> nil then begin + int1:= length(value); + pointer(value):= nil; + if int1 > 0 then begin + setlength(value,int1); + move(po1^,pointer(value)^,int1); + end; + end; +end; + +procedure reallocstring(var value: msestring); + //macht datenkopie ohne free +var + po1: pointer; + int1: sizeint; +begin + po1:= pointer(value); + if po1 <> nil then begin + int1:= length(value); + pointer(value):= nil; + if int1 > 0 then begin + setlength(value,int1); + move(po1^,pointer(value)^,int1*sizeof(msechar)); + end; + end; +end; + +procedure reallocarray(var value; elementsize: integer); overload; + //macht datenkopie ohne free +var + po1,po2: ^sizeint; + lwo1: longword; +begin + if pointer(value) <> nil then begin + lwo1:= length(bytearty(value))*elementsize + 2*sizeof(sizeint); + getmem(po1,lwo1); + po1^:= 1; //refcount + inc(po1); + po2:= pointer(value); + dec(po2); + move(po2^,po1^,lwo1-sizeof(sizeint)); //size+data + inc(po1); + pointer(value):= po1; + end; +end; + +procedure resizearray(var value; newlength, elementsize: integer); +var + po1: ^sizeint; + lwo1,lwo2: longword; +begin + if pointer(value) <> nil then begin + po1:= pointer(value); + lwo1:= newlength*elementsize; + if po1 <> nil then begin + dec(po1); + {$ifdef FPC} + lwo2:= (po1^+1)*longword(elementsize); + {$else} + lwo2:= po1^*longword(elementsize); + {$endif} + dec(po1); + end + else begin + lwo2:= 0; + end; + if lwo1 = 0 then begin + dispose(po1); + pointer(value):= nil; + end + else begin + reallocmem(po1,lwo1 + 2*sizeof(sizeint)); + inc(po1); + {$ifdef FPC} + po1^:= newlength-1; + {$else} + po1^:= newlength; + {$endif} + inc(po1); + pointer(value):= po1; + if lwo1 > lwo2 then begin + fillchar((pchar(po1)+lwo2)^,lwo1-lwo2,0); + end; + end; + end; +end; + +procedure removereturn(var avalue: msestring; var aindex: integer); +var + s,d: pmsechar; +begin + if avalue <> '' then begin + s:= pmsechar(avalue); + d:= s; + while s^ <> #0 do begin + if s^ <> msechar(c_return) then begin + d^:= s^; + inc(d); + end + else begin + if d - pmsechar(pointer(avalue)) < aindex then begin + dec(aindex); + end; + end; + inc(s); + end; + setlength(avalue,d-pmsechar(pointer(avalue))); + if aindex < 0 then begin + aindex:= 0; + end; + end; +end; + +procedure addeditchars(const source: msestring; var buffer: msestring; + var cursorpos: integer); + //cursorpos nullbased +var + s,d: pmsechar; + len1: integer; + ch1: msechar; + int1,int2: integer; + i: integer; + hasreturn: boolean; +begin + hasreturn:= false; + len1:= length(buffer); + i:= cursorpos; + if i > len1 then begin + i:= len1; + end; + int1:= len1; + int2:= cursorpos + length(source); + if int1 < int2 then begin + int1:= int2; + end; + setlength(buffer,int1); //refcount one + s:= pmsechar(source); + d:= pmsechar(buffer); + while true do begin + ch1:= s^; + if ch1 = #0 then begin + if s - pmsechar(pointer(source)) >= length(source) then begin + break; + end + else begin + ch1:= #$2400; //unicode null glyph + end; + end; + case ch1 of + c_backspace: begin + if i > 0 then begin + dec(i); + dec(len1,2); + end; + end; + c_return: begin + i:= 0; + hasreturn:= true; + end; + else begin + (d+i)^:= ch1; + inc(i); + if i > len1 then begin + len1:= i; + end; + end; + end; + inc(s); + end; + setlength(buffer,len1); + if hasreturn then begin + removereturn(buffer,i); + end; + cursorpos:= i; +end; + +function processeditchars(var value: msestring; stripcontrolchars: boolean): integer; + //bringt -anzahl rueckwaerts gefressene zeichen, + // -grosse zahl bei c_return +var + int1,int2,int3: integer; + str1: msestring; + ch1: msechar; + hasreturn: boolean; +begin + hasreturn:= false; + setlength(str1,length(value)); + int2:= 0; + int3:= 1; + for int1:= 1 to length(value) do begin + ch1:= value[int1]; + if ch1 = c_return then begin + int2:= -bigint div 2; + int3:= 1; + hasreturn:= true; + end + else begin + if ch1 = c_backspace then begin + dec(int3); + if int3 <= 0 then begin + dec(int2); + inc(int3); + end; + end + else begin + if ch1 = #0 then begin + ch1:= #$2400; //unicode null glyph + end; + if not stripcontrolchars or (ord(ch1) >= ord(' ')) or (ch1 = c_tab) then begin + (pmsechar(pointer(str1))+int3)^:= ch1; + inc(int3); + end; + end; + end; + end; + setlength(str1,int3-1); + if hasreturn then begin + int1:= -1; + removereturn(str1,int1); + end; + result:= int2; + value:= str1; +end; + +function mseextractprintchars(const value: msestring): msestring; +var + int1,int2: integer; + ch1: msechar; +begin + setlength(result,length(value)); + int2:= 0; + for int1:= 1 to length(value) do begin + ch1:= value[int1]; + if (ch1 >= ' ') and (ch1 <> c_delete) then begin + pmsecharaty(pointer(result))^[int2]:= ch1; + inc(int2); + end; + end; + setlength(result,int2); +end; + +function countchars(const str: string; achar: char): integer; +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = achar then begin + inc(result); + end; + end; +end; + +function countchars(const str: msestring; achar: msechar): integer; +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = achar then begin + inc(result); + end; + end; +end; + +function getcharpos(const str: msestring; achar: msechar): integerarty; +var + count: integer; + int1: integer; +begin + result:= nil; + count:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = achar then begin + additem(result,int1,count); + end; + end; + setlength(result,count); +end; + +function findchar(const str: string; achar: char): integer; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +function findchar(const str: string; const astart: integer; achar: char): integer; overload; +var + int1: integer; +begin + result:= 0; + for int1:= astart to length(str) do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +function findchar(const str: msestring; achar: msechar): integer; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +function findchar(const str: msestring; const astart: integer; + achar: msechar): integer; overload; +var + int1: integer; +begin + result:= 0; + for int1:= astart to length(str) do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +function findchar(const str: pchar; achar: char): integer; + //bringt erstes vorkommens von zeichen in string, 0 wenn nicht gefunden +var + po1: pchar; +begin + result:= 0; + if str <> nil then begin + po1:= str; + while po1^ <> #0 do begin + if po1^ = achar then begin + result:= (po1-pchar(pointer(str)))+1; + break; + end; + inc(po1); + end; + end; +end; + +function findchar(const str: pmsechar; achar: msechar): integer; + //bringt erstes vorkommens von zeichen in string, 0 wenn nicht gefunden +var + po1: pmsechar; +begin + result:= 0; + if str <> nil then begin + po1:= str; + while po1^ <> #0 do begin + if po1^ = achar then begin + result:= (po1-pmsechar(pointer(str)))+1; + break; + end; + inc(po1); + end; + end; +end; + +function findchars(const str: string; const achars: string): integer; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; + po1: pchar; +begin + result:= 0; + po1:= pchar(str); + while po1^ <> #0 do begin + for int1:= 1 to length(achars) do begin + if achars[int1] = po1^ then begin + result:= po1-pchar(str)+1; + exit; + end; + end; + inc(po1); + end; +end; + +function findchars(const str: msestring; const achars: msestring): integer; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; + po1: pmsechar; +begin + result:= 0; + po1:= pmsechar(str); + while po1^ <> #0 do begin + for int1:= 1 to length(achars) do begin + if achars[int1] = po1^ then begin + result:= po1-pmsechar(str)+1; + exit; + end; + end; + inc(po1); + end; +end; + +function findlastchar(const str: string; achar: char): integer; + //bringt index des letzten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; +begin + result:= 0; + for int1:= length(str) downto 1 do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +function findlastchar(const str: msestring; achar: msechar): integer; + //bringt index des letzten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; +begin + result:= 0; + for int1:= length(str) downto 1 do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +procedure mseskipspace(var str: pmsechar); {$ifdef FPC}inline;{$endif} +begin + while str^ = ' ' do begin + inc(str); + end; +end; + +procedure skipspace(var str: pchar); {$ifdef FPC}inline;{$endif} +begin + while str^ = ' ' do begin + inc(str); + end; +end; + +function StrLScan(const Str: PChar; Chr: Char; len: integer): PChar; +var + int1: integer; + po1: pcharaty; +begin + result:= nil; + if str <> nil then begin + po1:= pointer(str); + for int1:= 0 to len - 1 do begin + if po1^[int1] = chr then begin + result:= @(po1^[int1]); + break; + end; + end; + end; +end; + +function mseStrLScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; +var + int1: integer; + po1: pmsecharaty; +begin + result:= nil; + if str <> nil then begin + po1:= pointer(str); + for int1:= 0 to len - 1 do begin + if po1^[int1] = chr then begin + result:= @(po1^[int1]); + break; + end; + end; + end; +end; + +function StrLNScan(const Str: PChar; Chr: Char; len: integer): PChar; +var + int1: integer; + po1: pcharaty; +begin + result:= nil; + if str <> nil then begin + po1:= pointer(str); + for int1:= 0 to len - 1 do begin + if po1^[int1] <> chr then begin + result:= @(po1^[int1]); + break; + end; + end; + end; +end; + +function mseStrLNScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; +var + int1: integer; + po1: pmsecharaty; +begin + result:= nil; + if str <> nil then begin + po1:= pointer(str); + for int1:= 0 to len - 1 do begin + if po1^[int1] <> chr then begin + result:= @(po1^[int1]); + break; + end; + end; + end; +end; +{ +function strscan(const str: string; chr: char): integer; overload; +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = chr then begin + result:= int1; + break; + end; + end; +end; + +function msestrscan(const str: msestring; chr: msechar): integer; overload; +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = chr then begin + result:= int1; + break; + end; + end; +end; +} +function StrScan(const Str: PChar; Chr: Char): PChar; +var + po1: pchar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + if po1^ = chr then begin + result:= po1; + break; + end; + inc(po1); + end; + end; +end; + +function strscan(const str: lmsestringty; const chr: msechar): pmsechar; overload; +var + int1: integer; + po1: pmsechar; +begin + po1:= str.po; + for int1:= 0 to str.len-1 do begin + if (po1+int1)^ = chr then begin + result:= po1+int1; + exit; + end; + end; + result:= nil; +end; + +function mseStrScan(const Str: PmseChar; Chr: mseChar): Pmsechar; +var + po1: pmsechar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + if po1^ = chr then begin + result:= po1; + break; + end; + inc(po1); + end; + end; +end; + +function StrNScan(const Str: PChar; Chr: Char): PChar; +var + po1: pchar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + if po1^ <> chr then begin + result:= po1; + break; + end; + inc(po1); + end; + end; +end; + +function mseStrNScan(const Str: PmseChar; Chr: mseChar): Pmsechar; +var + po1: pmsechar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + if po1^ <> chr then begin + result:= po1; + break; + end; + inc(po1); + end; + end; +end; + +function StrRScan(const Str: PChar; Chr: Char): PChar; +var + po1: pchar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + inc(po1); + end; + while po1 > str do begin + dec(po1); + if po1^ = chr then begin + result:= po1; + break; + end; + end; + end; +end; + +function mseStrRScan(const Str: PmseChar; Chr: mseChar): PmseChar; +var + po1: pmsechar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + inc(po1); + end; + while po1 > str do begin + dec(po1); + if po1^ = chr then begin + result:= po1; + break; + end; + end; + end; +end; + +function msestrrscan(const str: msestring; chr: msechar): integer; +var + int1: integer; +begin + result:= 0; + for int1:= length(str) downto 1 do begin + if str[int1] = chr then begin + result:= int1; + break; + end; + end; +end; + +function StrLRScan(const Str: PChar; Chr: Char; len: integer): PChar; +var + po1: pchar; +begin + result:= nil; + if str <> nil then begin + po1:= str+len; + while po1 > str do begin + dec(po1); + if po1^ = chr then begin + result:= po1; + break; + end; + end; + end; +end; + +function mseStrLRScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; +var + po1: pmsechar; +begin + result:= nil; + if str <> nil then begin + po1:= str+len; + while po1 > str do begin + dec(po1); + if po1^ = chr then begin + result:= po1; + break; + end; + end; + end; +end; + +function mseStrLNRScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; +var + po1: pmsechar; +begin + result:= nil; + if str <> nil then begin + po1:= str+len; + while po1 > str do begin + dec(po1); + if po1^ <> chr then begin + result:= po1; + break; + end; + end; + end; +end; + +function mseStrComp(const Str1, Str2: PmseChar): Integer; +var + po1,po2: pmsechar; + wo1: word; +begin + po1:= str1; + po2:= str2; + if po1 <> po2 then begin + repeat + wo1:= word(po1^) - word(po2^); + if po2^ = #0 then begin + break; + end; + inc(po1); + inc(po2); + until (wo1 <> 0); + result:= smallint(wo1); + end + else begin + result:= 0; + end; +end; + +function StrLComp(const Str1, Str2: PChar; len: integer): Integer; +var + po1,po2: pchar; + by1: byte; +begin + by1:= 0; + if len > 0 then begin + po1:= str1; + po2:= str2; + repeat + by1:= byte(po1^) - byte(po2^); + if po2^ = #0 then begin + break; + end; + inc(po1); + inc(po2); + dec(len); + until (len <= 0) or (by1 <> 0); + end; + result:= shortint(by1); +end; + +function mseStrLComp(const Str1, Str2: PmseChar; len: integer): Integer; +var + po1,po2: pmsechar; + wo1: word; +begin + wo1:= 0; + if len > 0 then begin + po1:= str1; + po2:= str2; + repeat + wo1:= word(po1^) - word(po2^); + if po2^ = #0 then begin + break; + end; + inc(po1); + inc(po2); + dec(len); + until (len <= 0) or (wo1 <> 0); + end; + result:= smallint(wo1); +end; + +function StrLIComp(const Str1, upstr: PChar; len: integer): Integer; + //ascii caseinsensitive, str2 muss upcase sein +var + po1,po2: pcharaty; + int1: integer; + by1: byte; +begin + by1:= 0; + if not((len = 0) or (str1 = upstr)) then begin + po1:= pointer(str1); + po2:= pointer(upstr); + for int1:= 0 to len - 1 do begin + by1:= ord(upperchars[po1^[int1]])-ord(po2^[int1]); + if (by1 <> 0) then begin + break; + end; + end; + end; + result:= shortint(by1); +end; + +function StrIComp(const Str1, upstr: PChar): Integer; + //ascii caseinsensitive, upstr muss upcase sein +var + po1,po2: pchar; + by1: byte; +begin + by1:= 0; + if str1 <> upstr then begin + po1:= pointer(str1); + po2:= pointer(upstr); + repeat + by1:= ord(upperchars[po1^])-ord(po2^); + inc(po1); + inc(po2); + until (by1 <> 0) or (po1^ = #0); + end; + result:= shortint(by1); +end; + +function mseStrLIComp(const Str1, upstr: PmseChar; len: integer): Integer; + //ascii caseinsensitive, str2 muss upcase sein +var + po1,po2: pmsecharaty; + int1: integer; + ch1: msechar; + wo1: word; +begin + wo1:= 0; + if not((len = 0) or (str1 = upstr)) then begin + po1:= pointer(str1); + po2:= pointer(upstr); + for int1:= 0 to len - 1 do begin + ch1:= po1^[int1]; + if (ch1 >= 'a') and (ch1 <= 'z') then begin + inc(ch1,ord('A')-ord('a')); + end; + wo1:= ord(ch1)-ord(po2^[int1]); + if (wo1 <> 0) then begin + break; + end; + end; + end; + result:= smallint(wo1); +end; + +function issamelstring(const value: lmsestringty; const key: msestring; + caseinsensitive: boolean = false): boolean; + //nur ascii caseinsens., key muss upcase sein +begin + if caseinsensitive then begin + result:= msestrlicomp(value.po,pointer(key),value.len) = 0; + end + else begin + result:= msestrlcomp(value.po,pointer(key),value.len) = 0; + end; +end; + +function issamelstring(const value: lstringty; const key: string; + caseinsensitive: boolean = false): boolean; + //nur ascii caseinsens., key muss upcase sein +begin + if caseinsensitive then begin + result:= strlicomp(value.po,pointer(key),value.len) = 0; + end + else begin + result:= strlcomp(value.po,pointer(key),value.len) = 0; + end; +end; + +function minhigh(const a,b: lstringty): integer; overload; +begin + if a.len < b.len then begin + result:= a.len; + end + else begin + result:= b.len; + end; + dec(result); +end; + +function minhigh(const a: lstringty; const b: string): integer; overload; +begin + if a.len < length(b) then begin + result:= a.len; + end + else begin + result:= length(b); + end; + dec(result); +end; + +function minhigh(const a,b: string): integer; overload; +begin + if length(a) < length(b) then begin + result:= length(a); + end + else begin + result:= length(b); + end; + dec(result); +end; + +function minhigh(const a,b: msestring): integer; overload; +begin + if length(a) < length(b) then begin + result:= length(a); + end + else begin + result:= length(b); + end; + dec(result); +end; + +function lstringcomp(const a,b: lstringty): integer; +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(b.po); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(po1^[int1]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - b.len; + end + else begin + result:= shortint(by1); + end; +end; + +function lstringcomp(const a: lstringty; const b: string): integer; +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(b); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(po1^[int1]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - length(b); + end + else begin + result:= shortint(by1); + end; +end; + +function lstringicompupper(const a,upper: lstringty): integer; + //case insensitive, upper must be uppercase +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(upper.po); + by1:= 0; + for int1:= 0 to minhigh(a,upper) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - upper.len; + end + else begin + result:= shortint(by1); + end; +end; + +function lstringicompupper(const a: lstringty; const upper: string): integer; overload; + //ansi case insensitive, upper must be uppercase +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(upper); + by1:= 0; + for int1:= 0 to minhigh(a,upper) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - length(upper); + end + else begin + result:= shortint(by1); + end; +end; + +function lstringicomp(const a,b: lstringty): integer; + //case insensitive +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(b.po); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(upperchars[po2^[int1]]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - b.len; + end + else begin + result:= shortint(by1); + end; +end; + +function lstringicomp(const a: lstringty; const b: string): integer; + //case insensitive, +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(b); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(upperchars[po2^[int1]]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - length(b); + end + else begin + result:= shortint(by1); + end; +end; + +{ +function stringcomp(const a,b: string): integer; +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a); + po2:= pointer(b); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(po1^[int1]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= length(a) - length(b); + end + else begin + result:= shortint(by1); + end; +end; + +function stringicomp(const a,b: string): integer; + //case insensitive +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a); + po2:= pointer(b); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(upperchars[po2^[int1]]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= length(a) - length(b); + end + else begin + result:= shortint(by1); + end; +end; +} + +function stringcomp(const a,b: string): integer; +var + by1: byte; + po1,po2: pchar; +begin + po1:= pointer(a); + po2:= pointer(b); + if po1 = nil then begin + if po2 = nil then begin + result:= 0; + exit; + end; + result:= -1; + exit; + end; + if po2 = nil then begin + result:= 1; + exit; + end; + while true do begin + by1:= byte(po1^)-byte(po2^); + if (by1 <> 0) or (po1^ = #0) or (po2^=#0) then begin + break; + end; + inc(po1); + inc(po2); + end; + result:= shortint(by1); +end; + +function stringicomp(const a,b: string): integer; +var + by1: byte; + po1,po2: pchar; +begin + po1:= pointer(a); + po2:= pointer(b); + if po1 = nil then begin + if po2 = nil then begin + result:= 0; + exit; + end; + result:= -1; + exit; + end; + if po2 = nil then begin + result:= 1; + exit; + end; + while true do begin + by1:= byte(upperchars[po1^])-byte(upperchars[po2^]); + if (by1 <> 0) or (po1^ = #0) or (po2^=#0) then begin + break; + end; + inc(po1); + inc(po2); + end; + result:= shortint(by1); +end; + +function stringicompupper(const a,upstr: string): integer; + //case insensitive, b must be uppercase +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a); + po2:= pointer(upstr); + by1:= 0; + for int1:= 0 to minhigh(a,upstr) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= length(a) - length(upstr); + end + else begin + result:= shortint(by1); + end; +end; + +function msestringcomp(const a,b: msestring): integer; +var + int1: integer; + wo1: word; + po1,po2: pmsecharaty; +begin + po1:= pointer(a); + po2:= pointer(b); + wo1:= 0; + for int1:= 0 to minhigh(a,b) do begin + wo1:= word(po1^[int1]) - word(po2^[int1]); + if wo1 <> 0 then begin + break; + end; + end; + if wo1 = 0 then begin + result:= length(a) - length(b); + end + else begin + result:= smallint(wo1); + end; +end; + +function msestringicomp(const a,b: msestring): integer; + //ascii case insensitive +var + int1: integer; + wo1: word; + ch1,ch2: msechar; + po1,po2: pmsecharaty; +begin + po1:= pointer(a); + po2:= pointer(b); + wo1:= 0; + for int1:= 0 to minhigh(a,b) do begin + ch1:= po1^[int1]; + if (ch1 >= 'a') and (ch1 <= 'z') then begin + inc(ch1,ord('A')-ord('a')); + end; + ch2:= po2^[int1]; + if (ch2 >= 'a') and (ch2 <= 'z') then begin + inc(ch2,ord('A')-ord('a')); + end; + wo1:= word(ch1) - word(ch2); + if wo1 <> 0 then begin + break; + end; + end; + if wo1 = 0 then begin + result:= length(a) - length(b); + end + else begin + result:= smallint(wo1); + end; +end; + +function msestringicompupper(const a,upstr: msestring): integer; + //case insensitive, b must be uppercase +var + int1: integer; + wo1: word; + ch1: msechar; + po1,po2: pmsecharaty; +begin + po1:= pointer(a); + po2:= pointer(upstr); + wo1:= 0; + for int1:= 0 to minhigh(a,upstr) do begin + ch1:= po1^[int1]; + if (ch1 >= 'a') and (ch1 <= 'z') then begin + inc(ch1,ord('A')-ord('a')); + end; + wo1:= word(ch1) - word(po2^[int1]); + if wo1 <> 0 then begin + break; + end; + end; + if wo1 = 0 then begin + result:= length(a) - length(upstr); + end + else begin + result:= smallint(wo1); + end; +end; + +function isnullstring(const s: ansistring): boolean; +var + int1: integer; +begin + result:= true; + for int1:= 1 to length(s) do begin + if s[int1] <> #0 then begin + result:= false; + break; + end; + end; +end; + +function isemptystring(const s: pchar): boolean; +begin + result:= (s = nil) or (s^ = char(0)); +end; + +function isemptystring(const s: pmsechar): boolean; +begin + result:= (s = nil) or (s^ = msechar(0)); +end; + +function isnamechar(achar: char): boolean; + //true if achar in 'a'..'z','A'..'Z','0'..'9','_'; +begin + result:= (achar >= 'a') and (achar <= 'z') or (achar >= 'A') and (achar <= 'Z') or + (achar >= '0') and (achar <= '9') or (achar = '_'); +end; + +function isnamechar(achar: msechar): boolean; + //true if achar in 'a'..'z','A'..'Z','0'..'9','_'; +begin + result:= (achar >= 'a') and (achar <= 'z') or (achar >= 'A') and (achar <= 'Z') or + (achar >= '0') and (achar <= '9') or (achar = '_'); +end; + +function isnumber(const s: string): boolean; +var + int1: integer; + ch1: char; +begin + if s = '' then begin + result:= false; + end + else begin + result:= true; + for int1:= length(s)-1 downto 0 do begin + ch1:= (pchar(pointer(s))+int1)^; + if (ch1 < '0') or (ch1 > '9') then begin + result:= false; + break; + end; + end; + end; +end; + +function isnumber(const s: msestring): boolean; +var + int1: integer; + ch1: msechar; +begin + if s = '' then begin + result:= false; + end + else begin + result:= true; + for int1:= length(s)-1 downto 0 do begin + ch1:= (pmsechar(pointer(s))+int1)^; + if (ch1 < '0') or (ch1 > '9') then begin + result:= false; + break; + end; + end; + end; +end; + +function startsstr(substring: pchar; s: pchar): boolean; +begin + result:= substring = s; + if not result then begin + if (substring <> nil) and (s <> nil) then begin + while (substring^ = s^) and (substring^ <> #0) do begin + inc(substring); + inc(s); + end; + result:= substring^= #0; + end + else begin + result:= isemptystring(substring) and isemptystring(s); + end; + end; +end; + +function StartsStr(const substring,s: string): boolean; +begin + result:= startsstr(pchar(substring),pchar(s)); +end; + +function msestartsstr(substring: pmsechar; s: pmsechar): boolean; +begin + result:= substring = s; + if not result then begin + if (substring <> nil) and (s <> nil) then begin + while (substring^ = s^) and (substring^ <> #0) do begin + inc(substring); + inc(s); + end; + result:= substring^= #0; + end + else begin + result:= isemptystring(substring) and isemptystring(s); + end; + end; +end; + +function msestartsstrcaseinsensitive(substring: pmsechar; s: pmsechar): boolean; +begin + result:= substring = s; + if not result then begin + if (substring <> nil) and (s <> nil) then begin + while (substring^ = charuppercase(s^)) and (substring^ <> #0) do begin + inc(substring); + inc(s); + end; + result:= substring^= #0; + end + else begin + result:= isemptystring(substring) and isemptystring(s); + end; + end; +end; + +function mseStartsStr(const substring,s: msestring): boolean; +begin + result:= msestartsstr(pmsechar(substring),pmsechar(s)); +end; + +function strlcopy(const str: pchar; len: integer): ansistring; + //nicht nullterminiert +begin + setlength(result,len); + move(str^,result[1],len*sizeof(char)); +end; + +function msestrlcopy(const str: pmsechar; len: integer): msestring; + //nicht nullterminiert +begin + setlength(result,len); + move(str^,result[1],len*sizeof(msechar)); +end; + +function comparestrlen(const S1,S2: string): integer; + //case sensitiv, beruecksichtigt nur s1 laenge +begin + if (length(s1) = 0) or (pointer(s1) = pointer(s2)) then begin + result:= 0; + exit; + end; + if length(s2) = 0 then begin + result:= 1; + exit; + end + else begin + result:= strlcomp(pointer(s1),pointer(s2),length(s1)); + end; +end; + +function msecomparestrlen(const S1,S2: msestring): integer; + //case sensitiv, beruecksichtigt nur s1 laenge +begin + if (length(s1) = 0) or (pointer(s1) = pointer(s2)) then begin + result:= 0; + exit; + end; + if length(s2) = 0 then begin + result:= 1; + exit; + end + else begin + result:= msestrlcomp(pointer(s1),pointer(s2),length(s1)); + end; +end; + +function msecomparestr(const S1, S2: msestring): Integer; +begin +{$ifdef FPC} + result:= unicodecomparestr(s1,s2); +// {$ifdef mswindows} +// if iswin95 then begin +// result:= comparestr(s1,s2); +// end +// else begin +// result:= unicodecomparestr(s1,s2); +// end; +// {$else} +// result:= unicodecomparestr(s1,s2); +// {$endif} +{$else} + result:= widecomparestr(s1,s2); +{$endif} +end; + +function msecomparetext(const S1, S2: msestring): Integer; +begin +{$ifdef FPC} +// {$ifdef mswindows} +// if iswin95 then begin +// result:= comparetext(s1,s2); +// end +// else begin +// result:= unicodecomparetext(s1,s2); +// end; +// {$else} + result:= unicodecomparetext(s1,s2); +// {$endif} +{$else} + result:= widecomparetext(s1,s2); +{$endif} +end; + +function comparenatural(const s1,s2: msestring; + const caseinsensitive: boolean): int32; +var + p1,p2: pmsechar; + pa,pb: pmsechar; + i1,ia,ib: int32; + si0,si1,si2: sizeint; + c1,c2: msechar; + b1: boolean; +begin + b1:= false; + if (s1 <> '') and (s2 <> '') and (pointer(s1) <> pointer(s2)) then begin + p1:= pmsechar(pointer(s1)) + (length(s1) - 1); + pa:= p1; + while pa >= pointer(s1) do begin + if (pa^ > '9') or (pa^ < '0') then begin + break; + end; + dec(pa); + end; + if pa <> p1 then begin + p2:= pmsechar(pointer(s2)) + (length(s2) - 1); + pb:= p2; + while pb >= pointer(s2) do begin + if (pb^ > '9') or (pb^ < '0') then begin + break; + end; + dec(pb); + end; + if pb <> p2 then begin + si0:= pa - pmsechar(pointer(s1)); + if si0 = pb - pmsechar(pointer(s2)) then begin + inc(si0); + i1:= 1; + ia:= 0; + while p1 > pa do begin + ia:= ia + i1 * (card16(p1^)-card16('0')); + i1:= i1 * 10; + dec(p1); + end; + i1:= 1; + ib:= 0; + while p2 > pb do begin + ib:= ib + i1 * (card16(p2^)-card16('0')); + i1:= i1 * 10; + dec(p2); + end; + si1:= length(s1); + si2:= length(s2); + (psizeint(pointer(s1))-1)^:= si0; + (psizeint(pointer(s2))-1)^:= si0; + inc(pa); + c1:= pa^; + pa^:= #0; + inc(pb); + c2:= pb^; + pb^:= #0; + if caseinsensitive then begin + result:= msecomparetext(s1,s2); + end + else begin + result:= msecomparestr(s1,s2); + end; + if result = 0 then begin + result:= ia - ib; + end; + (psizeint(pointer(s1))-1)^:= si1; + (psizeint(pointer(s2))-1)^:= si2; + pa^:= c1; + pb^:= c2; + b1:= true; + end; + end; + end; + end; + if not b1 then begin + if caseinsensitive then begin + result:= msecomparetext(s1,s2); + end + else begin + result:= msecomparestr(s1,s2); + end; + end; +end; + +function msecomparestrnatural(const S1, S2: msestring): Integer; + //case sensitive +begin + result:= comparenatural(s1,s2,false); +end; + +function msecomparetextnatural(const S1, S2: msestring): Integer; + //case insensitive +begin + result:= comparenatural(s1,s2,true); +end; + +function mseCompareTextlen(const S1, S2: msestring): Integer; + //case insensitiv, beruecksichtigt nur s1 laenge +var + str1: msestring; +begin + str1:= copy(s2,1,length(s1)); //todo: optimize + result:= msecomparetext(s1,str1); +end; + +function msepartialcomparestr(const s1,s2: msestring): integer; +var + mstr1: msestring; +begin + mstr1:= copy(s2,1,length(s1)); + result:= msecomparestr(s1,mstr1); + if (result <> 0) and (length(s2) > length(s1)) then begin + if msecomparestr(s1+'A',mstr1+'Z') < + msecomparestr(s1+'Z',mstr1+'A') then begin + result:= 0; + end; + end; +end; + +function msepartialcomparetext(const s1,s2: msestring): integer; +var + mstr1: msestring; +begin + mstr1:= copy(s2,1,length(s1)); + result:= msecomparetext(s1,mstr1); + if (result <> 0) and (length(s2) > length(s1)) then begin + if msecomparetext(s1+'A',mstr1+'Z') < + msecomparetext(s1+'Z',mstr1+'A') then begin + result:= 0; + end; + end; +end; + +function mseCompareTextlenupper(const S1, S2: msestring): Integer; + //case insensitiv, checks length s1 only, s1 must be uppercase +var + str1: msestring; +begin + str1:= mseuppercase(copy(s2,1,length(s1))); //todo: optimize + result:= msecomparestr(s1,str1); +end; + +function mseissamestrlen(const apartstring,astring: msestring): boolean; +var + po1,po2: pmsechar; +begin + result:= pointer(apartstring) = pointer(astring); + if not result then begin + po1:= pmsechar(apartstring); + po2:= pmsechar(astring); + while po1^ <> #0 do begin + if po1^ <> po2^ then begin + exit; + end; + inc(po1); + inc(po2); + end; + end; + result:= true; +end; + +function mseissametextlen(const apartstring,astring: msestring): boolean; + //case insensitive +begin + result:= mseissamestrlen(mseuppercase(apartstring),mseuppercase(astring)); +end; + +function mselowercase(const s: msestring): msestring; +begin +{$ifdef FPC} +// {$ifdef mswindows} +// if iswin95 then begin +// result:= lowercase(s); +// end +// else begin +// result:= unicodelowercase(s); +// end; +// {$else} + result:= unicodelowercase(s); +// {$endif} +{$else} + result:= widelowercase(s); +{$endif} +end; + +function mseuppercase(const s: msestring): msestring; +begin +{$ifdef FPC} +// {$ifdef mswindows} +// if iswin95 then begin +// result:= ansiuppercase(s); +// end +// else begin +// result:= unicodeuppercase(s); +// end; +// {$else} + result:= unicodeuppercase(s); +// {$endif} +{$else} + result:= wideuppercase(s); +{$endif} +end; + +function mselowercase(const s: msestringarty): msestringarty; +var + int1: integer; +begin + setlength(result,length(s)); + for int1:= high(s) downto 0 do begin + result[int1]:= mselowercase(s[int1]); + end; +end; + +function mseuppercase(const s: msestringarty): msestringarty; +var + int1: integer; +begin + setlength(result,length(s)); + for int1:= high(s) downto 0 do begin + result[int1]:= mseuppercase(s[int1]); + end; +end; + +function msestartstr(const atext: msestring; trenner: msechar): msestring; +var + po1: pmsechar; +begin + po1:= msestrlscan(pmsechar(atext),trenner,length(atext)); + if po1 = nil then begin + result:= atext; + end + else begin + result:= copy(atext,1,po1-pmsechar(atext)); + end; +end; + +function mseremspace(const s: msestring): msestring; +var + int1,int2: integer; + ch: msechar; +begin + int2:= 0; + setlength(result,length(s)); + for int1:= 1 to length(s) do begin + ch:= s[int1]; + if ch > ' ' then begin + inc(int2); + pmsecharaty(result)^[int2]:= ch; + end; + end; + setlength(result,int2); +end; + +function removelinebreaks(const s: msestring): msestring; + //replaces linebreaks with space +begin + result:= concatstrings(breaklines(s),' '); +end; + +function removelineterminator(const s: msestring): msestring; +var + int1: integer; +begin + int1:= length(s); + if int1 > 0 then begin + if s[int1] = c_linefeed then begin + dec(int1); + end; + if (int1 > 0) and (s[int1] = c_return) then begin + dec(int1); + end; + end; + result:= copy(s,1,int1); +end; + +procedure removetabterminator(var s: msestring); +var + int1: integer; +begin + int1:= length(s); + if (int1 > 0) and (s[int1] = c_tab) then begin + setlength(s,int1-1); + end; +end; + +function stripescapesequences(avalue: msestring): msestring; +label + lab1; +var + s,d,e: pmsechar; +begin + if avalue <> '' then begin + setlength(result,length(avalue)); + s:= pointer(avalue); + d:= pointer(result); + e:= s+length(avalue); + while s < e do begin + if s^ = c_esc then begin + inc(s); + case s^ of + '[': begin + inc(s); + if (s^ >= '0') and (s^ <= '9') then begin + inc(s); +lab1: + while (s^ >= '0') and (s^ <= '9') do begin + inc(s); + end; + if s^ = ';' then begin + inc(s); + goto lab1; //multiple attributes + end; + if not (char(word(s^)) in ['n','h','l','H','A','B','C','D', + 'f','r','g','K','J','i','m']) then begin + dec(s); + end; + end + else begin + if not (char(word(s^)) in ['c','s','u','r','g','K','J','i','m']) then begin + dec(s); + end; + end; + end; + else begin + if not (char(word(s^)) in ['c','(',')','7','8','D','M','H']) then begin + dec(s); + end; + end; + end; + end + else begin + d^:= s^; + inc(d); + end; + inc(s); + end; + setlength(result,d-pmsechar(pointer(result))); + end + else begin + result:= ''; + end; +end; + + +{ tmemorystringstream } +const + stringheadersize = sizeof(stringheaderty); + +constructor tmemorystringstream.create; +//var +// header: stringheaderty; +begin + inherited; + setcapacity(0); + fposition:= stringheadersize; +// fillchar(header,sizeof(header),0); +// writebuffer(header,sizeof(header)); +end; + +procedure tmemorystringstream.SetCapacity(NewCapacity: PtrInt); +begin + inherited setcapacity(newcapacity + stringheadersize); +end; + +function tmemorystringstream.getcapacity: ptrint; +begin + result:= inherited getcapacity - stringheadersize; +end; + +function tmemorystringstream.Seek(const Offset: Int64; + Origin: TSeekOrigin): Int64; +begin + Case Word(Origin) of + soFromBeginning : FPosition:=Offset+stringheadersize; + soFromEnd : FPosition:=FSize+Offset; + soFromCurrent : FPosition:=FPosition+Offset; + end; + Result:=FPosition; + {$IFDEF DEBUG} + if Result < stringheadersize then + raise Exception.Create('TCustomMemoryStream'); + {$ENDIF} +end; + +function tmemorystringstream.getmemory: pointer; +begin + result:= fmemory + stringheadersize; +end; + +function tmemorystringstream.GetSize: Int64; +begin + result:= fsize - stringheadersize; +end; + +function tmemorystringstream.GetPosition: Int64; +begin + result:= fposition - stringheadersize; +end; + +procedure tmemorystringstream.SetSize( + {$ifdef CPU64}const{$endif CPU64} NewSize: PtrInt); +begin + inherited setsize(newsize + stringheadersize); +end; + +procedure tmemorystringstream.destroyasstring(out data: string); +var + ch1: char; +begin + data:= ''; //decref + if size > 0 then begin + with pstringheaderty(fmemory)^ do begin + {$ifdef hascodepage} + codepage:= cp_acp; + elementsize:= 1; + {$ifdef cpu64} + dummy:= 0; + {$endif} + {$endif} + ref:= 1; + len:= size; + end; + ch1:= #0; + position:= size; + writebuffer(ch1,sizeof(ch1)); + pointer(data):= memory; //pointer(ptruint(memory) + sizeof(stringheaderty)); + setpointer(nil,0); + end; + // destroy; //destroy does not free memory??? + free(); +end; + +end. + + diff --git a/mseide-msegui/lib/common/kernel/msesys.pas b/mseide-msegui/lib/common/kernel/msesys.pas new file mode 100644 index 0000000..ae43418 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesys.pas @@ -0,0 +1,569 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesys; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + {$ifdef mswindows}windows,{$endif}mseerr,msetypes,msestrings,msesystypes, + sysutils + {$ifdef FPC},dynlibs{$endif}; + +type + internalthreadprocty = function(): integer of object; + + procitemty = record + pid,ppid: procidty; + children: procidarty; + end; + procitemarty = array of procitemty; + + threadinfoty = record + id: threadty; + threadproc: internalthreadprocty; + stacksize: ptruint; + platformdata: array[0..3] of pointer; + end; + + socketkindty = (sok_local,sok_inet,sok_inet6); + socketshutdownkindty = (ssk_rx,ssk_tx,ssk_both); + pollkindty = (poka_read,poka_write,poka_except); + pollkindsty = set of pollkindty; + + + socketaddrty = record + kind: socketkindty; + url: filenamety; + port: integer; + size: integer; + platformdata: array[0..32] of longword; + end; + +type + fileopenmodety = (fm_none,fm_read,fm_write,fm_readwrite,fm_create,fm_append); + fileaccessmodety = (fa_denywrite,fa_denyread); + fileaccessmodesty = set of fileaccessmodety; + filerightty = (s_irusr,s_iwusr,s_ixusr, + s_irgrp,s_iwgrp,s_ixgrp, + s_iroth,s_iwoth,s_ixoth, + s_isuid,s_isgid,s_isvtx); + filerightsty = set of filerightty; + filetypety = (ft_unknown,ft_dir,ft_blk,ft_chr,ft_reg,ft_lnk,ft_sock,ft_fifo); + fileattributety = (fa_rusr,fa_wusr,fa_xusr, + fa_rgrp,fa_wgrp,fa_xgrp, + fa_roth,fa_woth,fa_xoth, + fa_suid,fa_sgid,fa_svtx, + fa_dir, + fa_archive,fa_compressed,fa_encrypted,fa_hidden, + fa_offline,fa_reparsepoint,fa_sparsefile,fa_system, + fa_temporary, + fa_all); + fileattributesty = set of fileattributety; + accessmodety = (am_read,am_write,am_execute,am_exist); + accessmodesty = set of accessmodety; + + pollflagty = (pf_in, //POLLIN = $001; + pf_pri, //POLLPRI = $002; + pf_out, //POLLOUT = $004; + pf_err, //POLLERR = $008; + pf_hup, //POLLHUP = $010; + pf_nval //POLLNVAL = $020; + ); + pollflagsty = set of pollflagty; + ppollflagsty = ^pollflagsty; + pollcallbackty = procedure(const aflags: pollflagsty; + const adata: pointer) of object; + + +const + filerightattributes = [fa_rusr,fa_wusr,fa_xusr, + fa_rgrp,fa_wgrp,fa_xgrp, + fa_roth,fa_woth,fa_xoth, + fa_suid,fa_sgid,fa_svtx]; +type + ext1fileinfoty = record + filetype: filetypety; + attributes: fileattributesty; + size: int64; + modtime: tdatetime; + accesstime: tdatetime; + ctime: tdatetime; + end; + + ext2fileinfoty = record + id: int64; + owner: longword; + group: longword; + end; + + fileinfostatety = (fis_typevalid,fis_extinfo1valid,fis_extinfo2valid, + fis_diropen,fis_hasentry); + fileinfostatesty = set of fileinfostatety; + + fileinfoty = record + name: filenamety; + state: fileinfostatesty; + extinfo1: ext1fileinfoty; + extinfo2: ext2fileinfoty; + end; + pfileinfoty = ^fileinfoty; + + fileinfolevelty = (fil_name,fil_type, //fa_dir and fa_hidden + fil_ext1,fil_ext2); + dirstreamoptionty = (dso_casesensitive,dso_caseinsensitive); + //platform default if empty, + // same layout as filelistviewoptionty + dirstreamoptionsty = set of dirstreamoptionty; + + dirstreaminfoty = record + dirname: filenamety; + mask: filenamearty; + include,exclude: fileattributesty; + infolevel: fileinfolevelty; + options: dirstreamoptionsty; + caseinsensitive: boolean; + end; + + dirstreampty = array[0..7] of pointer; + dirstreamty = record +// checkcallback: dirstreamcheckeventty; + dirinfo: dirstreaminfoty; + platformdata: dirstreampty; + end; + + esys = class(eerror) + private + function geterror: syserrorty; + public + constructor create(aerror: syserrorty; atext: string); + property error: syserrorty read geterror; + end; + +var + defaultprintcommand: msestring; + +function fileattributestofilerights( + const attributes: fileattributesty): filerightsty; + +procedure checkdirstreamdata(var adata: dirstreamty); + +procedure syserror(const error: syserrorty; const text: msestring = ''); overload; +procedure syserror(const error: syserrorty; + const sender: tobject; text: msestring = ''); overload; + +function syelasterror: syserrorty; //returns sye_lasterror, sets mselasterror +function syeseterror(aerror: integer): syserrorty; + //if aerror <> 0 -> returns sye_lasterror, sets mselasterror, + // returns sye_ok otherwise +function syesetextendederror(const aerrormessage: msestring): syserrorty; +function buildsyserrormessage(const error: syserrorty; + const text: msestring = ''): msestring; +function buildsyserrormessage(const error: syserrorty; const sender: tobject; + text: msestring = ''): msestring; + +function getcommandlinearguments: msestringarty; + //refcount of result = 1 +function getcommandlineargument(const index: integer): msestring; +procedure deletecommandlineargument(const index: integer); + //index 1..argumentcount-1, no action otherwise + +{$ifdef FPC} +function getexceptiontext(obj: tobject; addr: pointer; framecount: longint; + frames: ppointer): msestring; +{$endif} +threadvar + mselasterror: integer; + mselasterrormessage: msestring; + +procedure saveformatsettings; +procedure initdefaultformatsettings; + //initialization order is wrong, FPC bug? +implementation +uses + classes,mclasses,msesysintf1,msesysintf,msearrayutils, + mseglob,msesysutils,mseformatstr; +{$ifdef FPC} + {$ifdef MSWINDOWS} +Procedure CatchUnhandledException (Obj : TObject; Addr: Pointer; + FrameCount: Longint; Frames: PPointer); + external name 'FPC_BREAK_UNHANDLED_EXCEPTION'; + //[public,alias:'FPC_BREAK_UNHANDLED_EXCEPTION']; + {$endif} +{$endif} + +function fileattributestofilerights( + const attributes: fileattributesty): filerightsty; +begin + result:= filerightsty(attributes*filerightattributes); +end; + +procedure checkdirstreamdata(var adata: dirstreamty); +var + int1: integer; +begin + with adata.dirinfo do begin + caseinsensitive:= sys_filesystemiscaseinsensitive; + if dso_caseinsensitive in options then begin + caseinsensitive:= true; + end; + if dso_casesensitive in options then begin + caseinsensitive:= false; + end; + if caseinsensitive then begin + setlength(mask,length(mask)); //unique + for int1:= 0 to high(mask) do begin + mask[int1]:= mseuppercase(mask[int1]); + end; + end; + end; +end; + +const + errortexts: array[syserrorty] of string = + ('','','','Busy','Dirstream','Network error','Write error','Read error', + 'Thread error', + 'Mutex error', + 'Semaphore error', + 'Condition error', + 'Time out', + 'Copy file error', + 'Can not create directory', + 'No console', + 'Not implemented', + 'Socket address error', + 'Socket error', + 'File is directory.' + ); + +var + commandlineargs: msestringarty; + +procedure initcommandlineargs; +begin + if commandlineargs = nil then begin + commandlineargs:= sys_getcommandlinearguments; + end; +end; + +function getcommandlineargument(const index: integer): msestring; +begin + initcommandlineargs; + if index > high(commandlineargs) then begin + result:= ''; + end + else begin + result:= commandlineargs[index]; + end; +end; + +function getcommandlinearguments: msestringarty; +begin + initcommandlineargs; + result:= copy(commandlineargs); +end; + +procedure deletecommandlineargument(const index: integer); +begin + initcommandlineargs; + if (index > 0) and (index <= high(commandlineargs)) then begin + deleteitem(commandlineargs,index); + end; +end; + +function syeseterror(aerror: integer): syserrorty; + //if aerror <> 0 -> returns sye_lasterror, sets mselasterror, + // returns sye_ok othrewise +begin + if aerror <> 0 then begin + result:= sye_lasterror; + mselasterror:= aerror; + end + else begin + result:= sye_ok; + end; +end; + +function syesetextendederror(const aerrormessage: msestring): syserrorty; +begin + mselasterrormessage:= aerrormessage; + result:= sye_extendederror; +end; + +function syelasterror: syserrorty; //returns sye_lasterror, sets mselasterror +begin + result:= sye_lasterror; + mselasterror:= sys_getlasterror; +end; + +function buildsyserrormessage(const error: syserrorty; + const text: msestring = ''): msestring; +begin + result:= ''; + if error = sye_lasterror then begin + result:= text + msestring(sys_geterrortext(mselasterror)); + end + else begin + if error = sye_extendederror then begin + result:= text + mselasterrormessage; + end + else begin + result:= text; + end; + end; +end; + +function buildsyserrormessage(const error: syserrorty; const sender: tobject; + text: msestring = ''): msestring; +begin + result:= ''; + if error <> sye_ok then begin + if sender <> nil then begin + text:= msestring(sender.classname) + ' ' + text; + if sender is tcomponent then begin + text:= text + msestring(fullcomponentname(tcomponent(sender))); + end; + end; + result:= buildsyserrormessage(error,text); + end; +end; + +procedure syserror(const error: syserrorty; const text: msestring); overload; +begin + if error = sye_ok then begin + exit; + end; + raise esys.create(error,ansistring(buildsyserrormessage(error,text))); +end; + +procedure syserror(const error: syserrorty; const sender: tobject; + text: msestring = ''); overload; +begin + if error = sye_ok then begin + exit; + end; + esys.create(error,ansistring(buildsyserrormessage(error,sender,text))); +{ + if sender <> nil then begin + text:= sender.classname + ' ' + text; + if sender is tcomponent then begin + text:= text + fullcomponentname(tcomponent(sender)); + end; + end; + syserror(error,text); +} +end; + +{ esys } + +constructor esys.create(aerror: syserrorty; atext: string); +begin + inherited create(integer(aerror),atext,errortexts); +end; + +function esys.geterror: syserrorty; +begin + result:= syserrorty(ferror); +end; + +var + defaultformatset: boolean = false; + +procedure initdefaultformatsettings; +var + int1: integer; +begin + if not defaultformatset then begin + defaultformatset:= true; + defaultformatsettingsmse.CurrencyFormat:= + {$ifdef FPC}defaultformatsettings.{$endif}CurrencyFormat; + defaultformatsettingsmse.NegCurrFormat:= + {$ifdef FPC}defaultformatsettings.{$endif}NegCurrFormat; + defaultformatsettingsmse.ThousandSeparator:= widechar( + {$ifdef FPC}defaultformatsettings.{$endif}ThousandSeparator); + defaultformatsettingsmse.DecimalSeparator:= widechar( + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator); + defaultformatsettingsmse.CurrencyDecimals:= + {$ifdef FPC}defaultformatsettings.{$endif}CurrencyDecimals; + defaultformatsettingsmse.DateSeparator:= widechar( + {$ifdef FPC}defaultformatsettings.{$endif}DateSeparator); + defaultformatsettingsmse.TimeSeparator:= widechar( + {$ifdef FPC}defaultformatsettings.{$endif}TimeSeparator); + defaultformatsettingsmse.ListSeparator:= widechar( + {$ifdef FPC}defaultformatsettings.{$endif}ListSeparator); + defaultformatsettingsmse.CurrencyString:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}CurrencyString); + defaultformatsettingsmse.ShortDateFormat:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}ShortDateFormat); + defaultformatsettingsmse.LongDateFormat:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}LongDateFormat); + defaultformatsettingsmse.TimeAMString:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}TimeAMString); + defaultformatsettingsmse.TimePMString:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}TimePMString); + defaultformatsettingsmse.ShortTimeFormat:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}ShortTimeFormat); + defaultformatsettingsmse.LongTimeFormat:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}LongTimeFormat); + for int1:= low(tmonthnamearraymse) to high(tmonthnamearraymse) do begin + defaultformatsettingsmse.ShortMonthNames[int1]:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}ShortMonthNames[int1]); + end; + for int1:= low(tmonthnamearraymse) to high(tmonthnamearraymse) do begin + defaultformatsettingsmse.LongMonthNames[int1]:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}LongMonthNames[int1]); + end; + for int1:= low(tweeknamearraymse) to high(tweeknamearraymse) do begin + defaultformatsettingsmse.ShortDayNames[int1]:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}ShortDayNames[int1]); + end; + for int1:= low(tweeknamearraymse) to high(tweeknamearraymse) do begin + defaultformatsettingsmse.LongDayNames[int1]:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}LongDayNames[int1]); + end; + defaultformatsettingsmse.TwoDigitYearCenturyWindow:= + {$ifdef FPC}defaultformatsettings.{$endif}TwoDigitYearCenturyWindow; + end; +end; + +procedure saveformatsettings; +var + int1: integer; +begin + {$ifdef FPC}defaultformatsettings.{$endif}CurrencyFormat:= + defaultformatsettingsmse.CurrencyFormat; + {$ifdef FPC}defaultformatsettings.{$endif}NegCurrFormat:= + defaultformatsettingsmse.NegCurrFormat; + {$ifdef FPC}defaultformatsettings.{$endif}ThousandSeparator:= + char(defaultformatsettingsmse.ThousandSeparator); + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator:= + char(defaultformatsettingsmse.DecimalSeparator); + {$ifdef FPC}defaultformatsettings.{$endif}CurrencyDecimals:= + defaultformatsettingsmse.CurrencyDecimals; + {$ifdef FPC}defaultformatsettings.{$endif}DateSeparator:= + char(defaultformatsettingsmse.DateSeparator); + {$ifdef FPC}defaultformatsettings.{$endif}TimeSeparator:= + char(defaultformatsettingsmse.TimeSeparator); + {$ifdef FPC}defaultformatsettings.{$endif}ListSeparator:= + char(defaultformatsettingsmse.ListSeparator); + {$ifdef FPC}defaultformatsettings.{$endif}CurrencyString:= + ansistring(defaultformatsettingsmse.CurrencyString); + {$ifdef FPC}defaultformatsettings.{$endif}ShortDateFormat:= + ansistring(defaultformatsettingsmse.ShortDateFormat); + {$ifdef FPC}defaultformatsettings.{$endif}LongDateFormat:= + ansistring(defaultformatsettingsmse.LongDateFormat); + {$ifdef FPC}defaultformatsettings.{$endif}TimeAMString:= + ansistring(defaultformatsettingsmse.TimeAMString); + {$ifdef FPC}defaultformatsettings.{$endif}TimePMString:= + ansistring(defaultformatsettingsmse.TimePMString); + {$ifdef FPC}defaultformatsettings.{$endif}ShortTimeFormat:= + ansistring(defaultformatsettingsmse.ShortTimeFormat); + {$ifdef FPC}defaultformatsettings.{$endif}LongTimeFormat:= + ansistring(defaultformatsettingsmse.LongTimeFormat); + for int1:= low(tmonthnamearraymse) to high(tmonthnamearraymse) do begin + {$ifdef FPC}defaultformatsettings.{$endif}ShortMonthNames[int1]:= + ansistring(defaultformatsettingsmse.ShortMonthNames[int1]); + end; + for int1:= low(tmonthnamearraymse) to high(tmonthnamearraymse) do begin + {$ifdef FPC}defaultformatsettings.{$endif}LongMonthNames[int1]:= + ansistring(defaultformatsettingsmse.LongMonthNames[int1]); + end; + for int1:= low(tweeknamearraymse) to high(tweeknamearraymse) do begin + {$ifdef FPC}defaultformatsettings.{$endif}ShortDayNames[int1]:= + ansistring(defaultformatsettingsmse.ShortDayNames[int1]); + end; + for int1:= low(tweeknamearraymse) to high(tweeknamearraymse) do begin + {$ifdef FPC}defaultformatsettings.{$endif}LongDayNames[int1]:= + ansistring(defaultformatsettingsmse.LongDayNames[int1]); + end; + {$ifdef FPC}defaultformatsettings.{$endif}TwoDigitYearCenturyWindow:= + defaultformatsettingsmse.TwoDigitYearCenturyWindow; +end; + +{$ifdef FPC} + + {$ifopt S+} + {$define STACKCHECK_WAS_ON} + {$S-} + {$endif OPT S } + +function getexceptionstack(obj: tobject; addr: pointer; framecount: longint; + frames: ppointer): msestring; +Var + i: longint; +begin + if Obj is exception then begin + result:= msestring(Exception(Obj).ClassName)+' : '+ + msestring(Exception(Obj).Message)+ lineend; + end + else begin + result:= 'Exception object '+msestring(Obj.ClassName)+ + ' is not of class Exception.'+lineend; + end; + result:= result + msestring(BackTraceStrFunc(Addr))+lineend; + if (FrameCount>0) then begin + for i:=0 to FrameCount-1 do begin + result:= result+msestring(BackTraceStrFunc(Frames[i]))+lineend; + end; + end; +end; + +function getexceptiontext(obj: tobject; addr: pointer; framecount: longint; + frames: ppointer): msestring; +begin + result:= 'An exception occurred at $'+ + hextostrmse(Addr)+' :' + lineend; + result:= result + getexceptionstack(obj,addr,framecount,frames); +end; + +procedure listexceptionstack(Obj: TObject; Addr:Pointer; FrameCount: Longint; + Frames: PPointer); +begin + debugwriteln(ansistring(getexceptionstack(obj,addr,framecount,frames))); +end; + +Procedure CatchUnhandledExcept(Obj : TObject; Addr: Pointer; FrameCount: Longint; + Frames: PPointer); +begin + {$ifdef MSWINDOWS} + if getstdhandle(std_error_handle) <= 0 then begin + catchunhandledexception(obj,addr,framecount,frames); + end + else begin + {$endif} + debugWriteln('An unhandled exception occurred at $'+ + HexStr(Ptrint(Addr),sizeof(PtrInt)*2)+' :'); + listexceptionstack(obj,addr,framecount,frames); + {$ifdef MSWINDOWS} + end; + {$endif} +end; + +{$ifdef mse_debugexception} +procedure raisepro(obj: tobject; addr: pointer; framecount: longint; + frames: ppointer); +begin + debugWriteln('An exception occurred at $'+ + HexStr(Ptrint(Addr),sizeof(PtrInt)*2)+' :'); + listexceptionstack(obj,addr,framecount,frames); +end; +{$endif} + +initialization + exceptproc:= @catchunhandledexcept; +{$ifdef mse_debugexception} + raiseproc:= @raisepro; + raisemaxframecount:= 100; +{$endif} +{$else} //fpc +initialization +{$endif} //delphi + initdefaultformatsettings; +end. diff --git a/mseide-msegui/lib/common/kernel/msesysintf.inc b/mseide-msegui/lib/common/kernel/msesysintf.inc new file mode 100644 index 0000000..4623d0b --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesysintf.inc @@ -0,0 +1,92 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +function sys_gettimeus: longword; + //systemtime in microseconds, origin undefined +function sys_getpid: procidty; +function sys_getprocesses: procitemarty; +function sys_terminateprocess(const proc: prochandlety): syserrorty; +function sys_killprocess(const proc: prochandlety): syserrorty; + +function sys_threadcreate(var info: threadinfoty): syserrorty; +function sys_threadwaitfor(var info: threadinfoty): syserrorty; +function sys_threaddestroy(var info: threadinfoty): syserrorty; +function sys_threadschedyield: syserrorty; +function sys_getcurrentthread: threadty; +function sys_issamethread(const a,b: threadty): boolean; +function sys_getapplicationpath: filenamety; +function sys_getcommandlinearguments: msestringarty; +procedure sys_getenvvars(out names: msestringarty; out values: msestringarty); +function sys_getenv(const aname: msestring; out avalue: msestring): boolean; + //true if found +function sys_setenv(const aname: msestring; + const avalue: msestring): syserrorty; +function sys_unsetenv(const aname: msestring): syserrorty; + +function sys_filesystemiscaseinsensitive: boolean; +function sys_tosysfilepath(var path: filenamety): syserrorty; + + //all filenames below are in mseformat! +function sys_getcurrentdir: filenamety; +function sys_getapphomedir: filenamety; +function sys_getuserhomedir: filenamety; +function sys_getusername: msestring; +function sys_gettempdir: filenamety; +function sys_setcurrentdir(const dirname: filenamety): syserrorty; +function sys_copyfile(const oldfile,newfile: filenamety): syserrorty; +function sys_deletefile(const filename: filenamety): syserrorty; +function sys_deletedir(const filename: filenamety): syserrorty; +function sys_renamefile(const oldname,newname: filenamety): syserrorty; +function sys_createdir(const path: msestring; + const rights: filerightsty): syserrorty; + +function sys_openfile(const path: filenamety; const openmode: fileopenmodety; + const accessmode: fileaccessmodesty; + const rights: filerightsty; out handle: integer): syserrorty; +function sys_closefile(const handle: integer): syserrorty; +function sys_flushfile(const handle: integer): syserrorty; +function sys_dup(const source: integer; out dest: integer): syserrorty; +function sys_truncatefile(const handle: integer; const size: int64): syserrorty; + +function sys_access(const path: filenamety; + const accessmodes: accessmodesty): syserrorty; +function sys_setfilerights(const path: filenamety; + const rights: filerightsty): syserrorty; +function sys_setfdrights(const fd: longint; + const rights: filerightsty; + const filename: filenamety = ''): syserrorty; + //filename necessary on windows +function sys_read(fd: longint; buf: pointer; nbytes: longword): integer; +function sys_write(fd: longint; buf: pointer; nbytes: longword): integer; +function sys_errorout(const atext: string): syserrorty; +function sys_stdin: integer; +function sys_stdout: integer; +function sys_stderr: integer; + +function sys_getfileinfo(const path: filenamety; var info: fileinfoty): boolean; +function sys_getfdinfo(const fd: longint; var info: fileinfoty): boolean; +function sys_opendirstream(var stream: dirstreamty): syserrorty; +function sys_closedirstream(var stream: dirstreamty): syserrorty; +function sys_readdirstream(var stream: dirstreamty; + var info: fileinfoty): boolean; + //true if valid + +procedure sys_usleep(const us: longword); +procedure sys_schedyield; + +function sys_getutctime: tdatetime; +function sys_getlocaltime: tdatetime; +function sys_localtimeoffset: tdatetime; +function sys_getlangname: string; +function sys_getprintcommand: msestring; +(* +function sys_utctolocaltime(const value: tdatetime): tdatetime; +function sys_localtimetoutc(const value: tdatetime): tdatetime; +*) diff --git a/mseide-msegui/lib/common/kernel/msesysintf1.inc b/mseide-msegui/lib/common/kernel/msesysintf1.inc new file mode 100644 index 0000000..5f8953f --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesysintf1.inc @@ -0,0 +1,49 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +function sys_getlasterror: integer; +procedure sys_setlasterror(const avalue: integer); +function sys_geterrortext(aerror: integer): string; + +function sys_mutexcreate(out mutex: mutexty): syserrorty; +function sys_mutexdestroy(var mutex: mutexty): syserrorty; +function sys_mutexlock(var mutex: mutexty): syserrorty; +function sys_mutextrylock(var mutex: mutexty): syserrorty; + //sye_ok if calling thread has lock, sye_busy if already locked by other thread +function sys_mutexunlock(var mutex: mutexty): syserrorty; + +function sys_semcreate(out sem: semty; count: integer): syserrorty; +function sys_semdestroy(var sem: semty): syserrorty; +//function sys_semreset(var sem: semty): syserrorty; //call from single thread! +function sys_sempost(var sem: semty): syserrorty; +function sys_semwait(var sem: semty; timeoutusec: integer): syserrorty; + //timeoutusec <= 0 -> no timeout + //sye_ok -> semaphore signaled + //sye_timeout -> timeout + //sye_semaphore -> error +function sys_semtrywait(var sem: semty): boolean; +function sys_semcount(var sem: semty): integer; + +function sys_condcreate(out cond: condty): syserrorty; +function sys_conddestroy(var cond: condty): syserrorty; +function sys_condlock(var cond: condty): syserrorty; +function sys_condunlock(var cond: condty): syserrorty; +function sys_condsignal(var cond: condty): syserrorty; +function sys_condbroadcast(var cond: condty): syserrorty; +function sys_condwait(var cond: condty; timeoutusec: integer): syserrorty; + //timeoutusec = 0 -> no timeout + //sye_ok -> condition signaled + //sye_timeout -> timeout + //sye_cond -> error + +function sys_utctolocaltime(const value: tdatetime): tdatetime; +function sys_localtimetoutc(const value: tdatetime): tdatetime; + + diff --git a/mseide-msegui/lib/common/kernel/msesystypes.pas b/mseide-msegui/lib/common/kernel/msesystypes.pas new file mode 100644 index 0000000..5c585d0 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesystypes.pas @@ -0,0 +1,47 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesystypes; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,sysutils; +type + {$ifndef FPC} + tlibhandle = thandle; + {$endif} + threadty = ptruint; + procidty = ptrint; + pprocidty = ^procidty; + procidarty = array of procidty; //same item size as winidarty! + prochandlety = type ptrint; + pprochandlety = ^prochandlety; + + mutexty = array[0..9] of pointer; + semty = array[0..7] of pointer; + psemty = ^semty; + condty = array[0..31] of pointer; + + syserrorty = (sye_ok,sye_lasterror,sye_extendederror,sye_busy,sye_dirstream, + sye_network,sye_write,sye_read, + sye_thread,sye_mutex,sye_semaphore,sye_cond,sye_timeout, + sye_copyfile,sye_createdir,sye_noconsole,sye_notimplemented, + sye_sockaddr,sye_socket,sye_isdir + ); + + ecrashstatfile = class(exception) + end; + +const + invalidprocid = -1; + invalidprochandle = -1; + invalidfilehandle = -1; + +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/msesysutils.pas b/mseide-msegui/lib/common/kernel/msesysutils.pas new file mode 100644 index 0000000..ddea3e0 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesysutils.pas @@ -0,0 +1,404 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesysutils; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +uses + mclasses,sysutils,msesystypes; + +type + eoserror = class(exception) + public + error: integer; + constructor create(const leadingtext: string = ''); overload; + constructor create(const errno: integer; const leadingtext: string = ''); overload; + //shows getlasterror + end; + + einternalerror = class(exception) + end; + +{$ifdef mswindows} +type + timeval = record + tv_sec: longword; + tv_usec: longword; + end; +{$endif} + +function stdinputhandle: integer; +function stdoutputhandle: integer; +function stderrorhandle: integer; +procedure writestdout(value: string; newline: boolean = false); +procedure writestderr(value: string; newline: boolean = false); +procedure errorhalt(errortext: string; exitcode: integer = 1); +procedure debugwrite(const value: string); +procedure debugwriteln(const value: string); +procedure debugwritestack(const acount: integer = 30); +procedure debugout(const sender: tcomponent; const atext: ansistring); overload; +procedure debugout(const sender: tobject; const atext: ansistring); overload; +procedure debugoutstart(out ts: longword; + const sender: tcomponent; const atext: ansistring); overload; +procedure debugoutend(const ts: longword; + const sender: tcomponent; const atext: ansistring); overload; +procedure internalerror(const text: string); + +function getlasterror: integer; +function getlasterrortext: string; +function syserrortext(const aerror: syserrorty): string; + //returns getlasterortext for sye_lasterror + +function later(ref,act: longword): boolean; + //true if act > ref, with overflowcorrection +function laterorsame(ref,act: longword): boolean; + //true if act >= ref, with overflowcorrection + +procedure sleepus(const us: longword); +procedure waitus(us: integer); +function timestamp: longword; //us, 0 never reported +function timestep(us: longword): longword; //bringt aktzeit + us +function timeout(time: longword): boolean; + +function createguidstring: string; + +procedure reallocmemandinit(var p: pointer; const newsize: sizeint); + +implementation +uses +{$ifdef mswindows} + windows, +{$else} + mselibc, +{$endif} + msesysintf1,msesysintf,msestrings,mseformatstr,msetypes,msesys, + typinfo; + +function createguidstring: string; +var + id: tguid; +begin + createguid(id); + result:= guidtostring(id); +end; + +{ eoserror } + +constructor eoserror.create(const errno: integer; const leadingtext: string = ''); +begin + error:= errno; + inherited create(leadingtext + 'OSError ' + inttostr(error) + ': ' + + sys_geterrortext(error)); +end; + +constructor eoserror.create(const leadingtext: string); +begin + create(getlasterror,leadingtext); +end; + +function timestamp: longword; +begin + result:= sys_gettimeus; + if result = 0 then begin + result:= 1; + end; +end; + + {$ifdef UNIX} +{ +function timestamp: longword; +var + t1: timeval; +begin + gettimeofday(t1,ptimezone(nil)^); + result:= t1.tv_sec * 1000000 + t1.tv_usec; + if result = 0 then begin + result:= 1; + end; +end; +} +procedure waitus(us: integer); +var + time: longword; +begin + time:= timestep(us); + repeat + until timeout(time); +end; + +{$endif unix} + +{$ifdef mswindows} +{ +function timestamp: longword; +begin + result:= gettickcount * 1000; + if result = 0 then begin + result:= 1; + end; +end; +} +procedure waitperformancecounter(time: int64); +var + time1: int64; + len: longword; + +begin + if queryperformancecounter(time1) then begin + len:= time1 + time; + repeat + queryperformancecounter(time1); + until integer(dword(time1)-len) > 0; //rollup + end; +end; + +procedure waitus(us: integer); +var + freq: int64; +begin + if us > 0 then begin + queryperformancefrequency(freq); + waitperformancecounter((freq*us) div 1000000); + end; +end; + +{$endif} + +function timestep(us: longword): longword; //bringt aktzeit + us +begin + result:= timestamp + us; +end; + +function timeout(time: longword): boolean; +begin + result:= laterorsame(time,timestamp); +end; + +function later(ref,act: longword): boolean; +var + ca1: longword; +begin + ca1:= act-ref; + result:= integer(ca1) > 0; +// result:= integer(act-ref) > 0; //FPC bug 4768 +end; + +function laterorsame(ref,act: longword): boolean; +var + ca1: longword; +begin + ca1:= act-ref; + result:= integer(ca1) >= 0; +// result:= integer(act-ref) > 0; //FPC bug 4768 +end; + +procedure sleepus(const us: longword); +begin + sys_usleep(us); +end; + +{$ifdef mswindows} +function stdinputhandle: integer; +begin + result:= getstdhandle(std_input_handle); + if result <= 0 then begin + result:= invalidfilehandle; + end; +end; + +function stdoutputhandle: integer; +begin + result:= getstdhandle(std_output_handle); + if result <= 0 then begin + result:= invalidfilehandle; + end; +end; + +function stderrorhandle: integer; +begin + result:= getstdhandle(std_error_handle); + if result <= 0 then begin + result:= invalidfilehandle; + end; +end; + +{$else} + +function stdinputhandle: integer; +begin + result:= 0; +end; + +function stdoutputhandle: integer; +begin + result:= 1; +end; + +function stderrorhandle: integer; +begin + result:= 2; +end; + +{$endif} +procedure writestdout(value: string; newline: boolean = false); + {$ifdef mswindows} +var + ca1: longword; + {$endif} +begin + if newline then begin + value:= value + lineend; + end; + {$ifdef UNIX} + sys_write(1,pointer(value),length(value)); + {$else} + if getstdhandle(std_output_handle) <= 0 then begin + allocconsole; + end; + writefile(getstdhandle(std_output_handle),pointer(value)^,length(value),ca1,nil); + {$endif} +end; + +procedure writestderr(value: string; newline: boolean = false); + {$ifdef mswindows} +var + ca1: longword; + {$endif} +begin + if newline then begin + value:= value + lineend; + end; + {$ifdef UNIX} + sys_write(2,pointer(value),length(value)); + {$else} + if getstdhandle(std_error_handle) <= 0 then begin + allocconsole; + end; + writefile(getstdhandle(std_error_handle),pointer(value)^,length(value),ca1,nil); + {$endif} +end; + +procedure debugwrite(const value: string); +begin + writestderr(value,false); +end; + +procedure debugwriteln(const value: string); +begin + writestderr(value,true); +end; + +procedure debugwritestack(const acount: integer = 30); +var + int1: integer; +begin +{$ifdef FPC} + int1:= raisemaxframecount; + raisemaxframecount:= acount; + try + raise exception.create(''); + except + debugwriteln(ansistring(getexceptiontext(exceptobject, + exceptaddr,exceptframecount,exceptframes))); + end; + raisemaxframecount:= int1; +{$endif} +end; + +procedure debugout(const sender: tcomponent; const atext: ansistring); +begin + if sender = nil then begin + debugwriteln('NIL '+atext); + end + else begin + debugwriteln(hextostr(ptruint(sender),8)+' '+ + sender.name+':'+sender.classname+' '+atext); + end; +end; + +procedure debugout(const sender: tobject; const atext: ansistring); +begin + if sender = nil then begin + debugwriteln('NIL '+atext); + end + else begin + debugwriteln(hextostr(ptruint(sender),8)+' '+ + sender.classname+' '+atext); + end; +end; + +procedure debugoutstart(out ts: longword; + const sender: tcomponent; const atext: ansistring); +begin + ts:= timestamp; + debugout(sender,'*start '+atext); +end; + +procedure debugoutend(const ts: longword; + const sender: tcomponent; const atext: ansistring); +begin + debugout(sender,ansistring('**end '+formatfloatmse( + (timestamp-ts)/1000000,'0.000000')+'s '+ + msestring(atext))); +end; + +procedure internalerror(const text: string); +begin + raise einternalerror.create('Internal error '+text); +end; + +procedure errorhalt(errortext: string; exitcode: integer = 1); +begin + writestderr(errortext,true); + halt(exitcode); +end; + +function getlasterror: integer; +begin + result:= sys_getlasterror; +end; + +function getlasterrortext: string; +var + int1: integer; +begin + int1:= sys_getlasterror; + result:= inttostr(int1) + ': ' + sys_geterrortext(int1); +end; + +function syserrortext(const aerror: syserrorty): string; + //returns getlasterortext for sye_lasterror +begin + case aerror of + sye_lasterror: begin + result:= getlasterrortext(); + end; + else begin + result:= getenumname(typeinfo(syserrorty),integer(aerror)); + end; + end; +end; + +procedure reallocmemandinit(var p: pointer; const newsize: sizeint); +var + oldsize: ptrint; +begin + oldsize:= 0; + if p <> nil then begin + oldsize:= memsize(p); + end; + reallocmem(p,newsize); + fillchar((p+oldsize)^,newsize-oldsize,0); +end; + +end. + diff --git a/mseide-msegui/lib/common/kernel/msethread.pas b/mseide-msegui/lib/common/kernel/msethread.pas new file mode 100644 index 0000000..d44a8d2 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msethread.pas @@ -0,0 +1,478 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msethread; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +uses + {$ifdef FPC}{$ifdef UNIX}cthreads,{$endif}classes{$else}Classes{$endif}, + mseclasses,mselist,mseevent,msesystypes,msesys,msetypes,sysutils; + +{$ifndef FPC} +const + DefaultStackSize = 4*1024*1024; +{$endif} +type + tmsethread = class; + + threadprocty = function(thread: tmsethread): integer of object; + + threadstatety = (ts_started,ts_running,ts_terminated,ts_freeonterminate, + ts_norun); //no run by create() + threadstatesty = set of threadstatety; + + tmsethread = class + protected + finfo: threadinfoty; + fthreadproc: threadprocty; + fexecresult: integer; + fstate: threadstatesty; + fwaitforsem: semty; + function internalthreadproc: integer; + function getrunning: boolean; + function getterminated: boolean; + function getfreeonterminate: boolean; + procedure setfreeonterminate(const avalue: boolean); + function execute(thread: tmsethread): integer; virtual; + procedure run(); virtual; + public + constructor create; overload; + constructor create(const afreeonterminate: boolean; + const astacksizekb: integer = 0); overload; + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); overload; virtual; + destructor destroy; override; + procedure afterconstruction; override; + function waitfor: integer; virtual; + procedure terminate; virtual; + procedure kill; //killing a running thread will loose resources! + property running: boolean read getrunning; + property terminated: boolean read getterminated; + property id: threadty read finfo.id; + property freeonterminate: boolean read getfreeonterminate + write setfreeonterminate; + //do not change the value if the thread is running + end; + + tmutexthread = class(tmsethread) + protected + fmutex: mutexty; + public + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); override; + destructor destroy; override; + function lock: boolean; //true if ok + procedure unlock; + end; + + tsemthread = class(tmutexthread) + protected + fsem: semty; + public + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); override; + destructor destroy; override; + function semwait(const atimeoutus: integer = 0): boolean; + function sempost: boolean; //true if not destroyed + function semtrywait: boolean; + function semcount: integer; + end; + + teventthread = class(tsemthread) + protected + feventlist: teventqueue; + public + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); overload; override; + destructor destroy(); override; + procedure terminate(); override; + procedure postevent(event: tmseevent); + procedure clearevents(); + function waitevent(const timeoutus: integer = -1): tmseevent; + // -1 infinite, 0 no block + function eventcount(): integer; + property eventlist: teventqueue read feventlist; + end; + + tsynchronizeevent = class(texecuteevent) + protected + fsem: semty; + fsuccess: boolean; + fexceptionclass: exceptclass; + fexceptionmessage: string; + fquiet: boolean; + procedure internalfree1; override; + public + constructor create(const aquiet: boolean); + //quiet -> show no exceptions + destructor destroy; override; + procedure deliver; override; + function waitfor: boolean; + property quiet: boolean read fquiet; + property success: boolean read fsuccess; + property exeptionclass: exceptclass read fexceptionclass; + property exceptionmessage: string read fexceptionmessage; + end; + +function synchronizeevent(const aevent: tsynchronizeevent; + const aoptions: posteventoptionsty = []): boolean; + //true if not aborted, does not free aevent + +implementation + +uses + msesysintf1,msesysintf,mseapplication; + +function synchronizeevent(const aevent: tsynchronizeevent; + const aoptions: posteventoptionsty = []): boolean; + //true if not aborted, does not free aevent +var + int1: integer; +begin + if not application.terminated then begin + if application.ismainthread then begin + try + aevent.execute; + result:= true; + except + if not aevent.quiet then begin + raise; + end; + result:= false; + end; + end + else begin + result:= false; + int1:= application.unlockall; + try + application.postevent(aevent,aoptions); + result:= aevent.waitfor and aevent.success; + //wait until main eventloop calls tevent.free1 + finally + application.relockall(int1); + end; + end; + end; +end; + +procedure createthread(var info: threadinfoty); +begin + syserror(sys_threadcreate(info)); +end; + +{ tsynchronizeevent } + +constructor tsynchronizeevent.create(const aquiet: boolean); +begin + fquiet:= aquiet; + sys_semcreate(fsem,0); + inherited create; +end; + +destructor tsynchronizeevent.destroy; +begin + sys_semdestroy(fsem); + inherited; +end; + +procedure tsynchronizeevent.deliver; +begin + try + inherited; +// execute; + fsuccess:= true; + except + on e: exception do begin + fexceptionclass:= exceptclass(e.classinfo); + fexceptionmessage:= e.message; + if not fquiet then begin +// sys_sempost(fsem); + raise; + end; + end; + end; +// sys_sempost(fsem); +end; + +function tsynchronizeevent.waitfor: boolean; +begin + result:= sys_semwait(fsem,0) = sye_ok; +end; + +procedure tsynchronizeevent.internalfree1; +begin + sys_sempost(fsem); //no inherited, don't free in main eventloop +end; + +{ tmsethread } + +constructor tmsethread.create; +begin + create(false); +end; + +constructor tmsethread.create(const afreeonterminate: boolean; + const astacksizekb: integer = 0); +begin + create({$ifdef FPC}@{$endif}execute,afreeonterminate,astacksizekb); +end; + +constructor tmsethread.create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); +begin + sys_semcreate(fwaitforsem,0); + fthreadproc:= athreadproc; +// fstate:= [ts_running,ts_started]; + if afreeonterminate then begin + include(fstate,ts_freeonterminate); + end; + with finfo do begin + if astacksizekb = 0 then begin + stacksize:= defaultstacksize; + end + else begin + stacksize:= astacksizekb * 1024; + end; + threadproc:= {$ifdef FPC}@{$endif}internalthreadproc; + end; +{ + if not (ts_norun in fstate) then begin + run(); + end; +} +end; + +procedure tmsethread.afterconstruction; +begin + if not (ts_norun in fstate) then begin + run(); + end; + if ts_freeonterminate in fstate then begin + sys_sempost(fwaitforsem); + end; +end; + +procedure tmsethread.run(); +begin + fstate:= fstate + [ts_running,ts_started]; + createthread(finfo); +end; + +destructor tmsethread.destroy; +begin + if finfo.id <> 0 then begin + terminate; + waitfor; + sys_threadwaitfor(finfo); + kill; + end; + inherited; +end; + +procedure tmsethread.terminate; +begin + include(fstate,ts_terminated); +end; + +function tmsethread.waitfor: integer; +begin + if ts_started in fstate then begin + if ts_freeonterminate in fstate then begin + raise exception.create('No waitfor() if ts_freeonterminate set.'); + end; + exclude(fstate,ts_started); + sys_semwait(fwaitforsem,0); + end; + result:= fexecresult; +end; + +procedure tmsethread.kill; +begin + if (self <> nil) and (finfo.id <> 0) then begin + exclude(fstate,ts_running); + sys_threaddestroy(finfo); + finfo.id:= 0; + sys_semdestroy(fwaitforsem); + end; +end; + +function tmsethread.getrunning: boolean; +begin + result:= ts_running in fstate; +end; + +function tmsethread.getterminated: boolean; +begin + result:= ts_terminated in fstate; +end; + +function tmsethread.execute(thread: tmsethread): integer; +begin + result:= 0; +end; + +function tmsethread.internalthreadproc: integer; +var + info1: threadinfoty; +begin + try + result:= fthreadproc(self); + except + result:= -1; + application.handleexception(self); + end; + fexecresult:= result; + exclude(fstate,ts_running); + if not freeonterminate then begin + sys_sempost(fwaitforsem); + end + else begin + sys_semwait(fwaitforsem,0); + info1:= finfo; + finfo.id:= 0; + free(); + sys_threaddestroy(info1); + end; +end; + +function tmsethread.getfreeonterminate: boolean; +begin + result:= ts_freeonterminate in fstate; +end; + +procedure tmsethread.setfreeonterminate(const avalue: boolean); +begin + if avalue then begin + include(fstate,ts_freeonterminate); + sys_semtrywait(fwaitforsem); //remove possible afterconstruction post + end + else begin + exclude(fstate,ts_freeonterminate); + end; +end; + +{ tmutexthread } + +constructor tmutexthread.create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); +begin + syserror(sys_mutexcreate(fmutex),self); + inherited; +end; + +destructor tmutexthread.destroy; +begin + inherited; + sys_mutexdestroy(fmutex); +end; + +function tmutexthread.lock: boolean; +begin + result:= sys_mutexlock(fmutex) = sye_ok; +end; + +procedure tmutexthread.unlock; +begin + sys_mutexunlock(fmutex); +end; + +{ teventthread } + +constructor teventthread.create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); +begin + feventlist:= teventqueue.create(true); + inherited; +end; + +destructor teventthread.destroy; +begin + inherited; + feventlist.Free; +end; + +function teventthread.eventcount: integer; +begin + feventlist.lock(); + result:= feventlist.count; + feventlist.unlock(); +end; + +procedure teventthread.postevent(event: tmseevent); +begin + feventlist.post(event); +end; + +procedure teventthread.terminate; +begin + inherited; + postevent(tmseevent.create(ek_terminate)); +end; + +function teventthread.waitevent(const timeoutus: integer = -1): tmseevent; +begin + result:= feventlist.wait(timeoutus); + if (result <> nil) and (result.kind = ek_terminate) then begin + freeandnil(result); + end; +end; + +procedure teventthread.clearevents(); +begin + feventlist.clear; +end; + +{ tsemthread } + +constructor tsemthread.create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); +begin + sys_semcreate(fsem,0); + inherited; +end; + +destructor tsemthread.destroy; +begin + terminate; + sys_semdestroy(fsem); + inherited; +end; + +function tsemthread.semcount: integer; +begin + result:= sys_semcount(fsem); +end; + +function tsemthread.sempost: boolean; +begin + result:= sys_sempost(fsem) = sye_ok; +end; + +function tsemthread.semtrywait: boolean; +begin + result:= sys_semtrywait(fsem); +end; + +function tsemthread.semwait(const atimeoutus: integer = 0): boolean; +begin + result:= sys_semwait(fsem,atimeoutus) = sye_ok; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msethreadcomp.pas b/mseide-msegui/lib/common/kernel/msethreadcomp.pas new file mode 100644 index 0000000..4e62fd7 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msethreadcomp.pas @@ -0,0 +1,227 @@ +{ MSEgui Copyright (c) 1999-2009 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msethreadcomp; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseclasses,msethread,classes,mclasses,mseevent,msetypes,msestrings,mseapplication; + +type + tthreadcomp = class; + threadcompeventty = procedure(const sender: tthreadcomp) of object; + threadcompoption = (tco_autorelease); + threadcompoptionsty = set of threadcompoption; + + tthreadcomp = class(tactcomponent) + private + fthread: teventthread; + fonstart: threadcompeventty; + fonterminate: threadcompeventty; + fonexecute: threadcompeventty; + factive: boolean; + fdatapo: pointer; + foptions: threadcompoptionsty; + fstacksizekb: integer; + fonterminated: threadcompeventty; + function getthread: teventthread; + function getterminated: boolean; + function threadproc(sender: tmsethread): integer; + procedure terminateandwait; + function getactive: boolean; + procedure doterminated; + protected + procedure setactive(const Value: boolean); override; + procedure loaded; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + property datapo: pointer read fdatapo; + procedure run(const adatapo: pointer = nil); + procedure terminate; + procedure waitfor; //does unlock,relock before waiting + + function lock: boolean; + procedure unlock; + procedure postevent(event: tmseevent); + function waitevent(const timeoutus: integer = -1): tmseevent; + // -1 infinite, 0 no block + + property thread: teventthread read getthread; + property terminated: boolean read getterminated; + + published + property options: threadcompoptionsty read foptions write foptions default []; + property stacksizekb: integer read fstacksizekb write fstacksizekb default 0; + property active: boolean read getactive write setactive default false; + property onstart: threadcompeventty read fonstart write fonstart; + property onexecute: threadcompeventty read fonexecute write fonexecute; + property onterminate: threadcompeventty read fonterminate write fonterminate; + property onterminated: threadcompeventty read fonterminated write fonterminated; + //runs in main thread + end; + +implementation +uses + sysutils{,mseapplication},msesystypes,msesys; + +{ tthreadcomp } + +constructor tthreadcomp.create(aowner: tcomponent); +begin + inherited; +end; + +destructor tthreadcomp.destroy; +begin + terminateandwait; + inherited; +end; + +procedure tthreadcomp.terminateandwait; +begin + if fthread <> nil then begin + terminate; + waitfor; + end; + fthread.free; + fthread:= nil; +end; + +procedure tthreadcomp.run(const adatapo: pointer = nil); +begin + terminateandwait; + factive:= true; + fdatapo:= adatapo; +// fthread:= teventthread.create({$ifdef FPC}@{$endif}threadproc,false, +// fstacksizekb); + fthread:= teventthread(teventthread.newinstance); + fthread.create({$ifdef FPC}@{$endif}threadproc,false, + fstacksizekb); +end; + +function tthreadcomp.lock: boolean; +begin + result:= thread.lock; +end; + +procedure tthreadcomp.unlock; +begin + thread.unlock; +end; + +function tthreadcomp.threadproc(sender: tmsethread): integer; +begin +// fthread:= teventthread(sender); + try + if assigned(fonstart) then begin + application.lock; + try + fonstart(self); + finally + application.unlock; + end; + end; + if assigned(fonexecute) then begin + fonexecute(self); + end; + if assigned(fonterminate) then begin + application.lock; + try + fonterminate(self); + finally + application.unlock; + end; + end; + if assigned(fonterminated) then begin + application.synchronize({$ifdef FPC}@{$endif}doterminated); + end; + result:= 0; + finally + if tco_autorelease in foptions then begin + release; + end; + end; +end; + +function tthreadcomp.getthread: teventthread; +begin + if fthread = nil then begin + syserror(sye_thread,self); + end; + result:= fthread; +end; + +function tthreadcomp.getterminated: boolean; +begin + result:= thread.terminated; +end; + +procedure tthreadcomp.terminate; +begin + if fthread <> nil then begin + fthread.terminate; + end; +end; + +procedure tthreadcomp.waitfor; +begin + if fthread <> nil then begin + application.waitforthread(thread); + end; +end; + +procedure tthreadcomp.postevent(event: tmseevent); +begin + thread.postevent(event); +end; + +function tthreadcomp.waitevent(const timeoutus: integer = -1): tmseevent; +begin + result:= thread.waitevent(timeoutus); +end; + +function tthreadcomp.getactive: boolean; +begin + result:= factive; +end; + +procedure tthreadcomp.loaded; +begin + inherited; + if not (csdesigning in componentstate) and factive and (fthread = nil) then begin + run; + end; +end; + +procedure tthreadcomp.setactive(const Value: boolean); +begin + if factive <> value then begin + factive:= value; + if not value then begin + terminateandwait; + end + else begin + if componentstate * [csloading,csdesigning] = [] then begin + run; + end; + end; + end; +end; + +procedure tthreadcomp.doterminated; +begin + fonterminated(self); +end; + +end. + diff --git a/mseide-msegui/lib/common/kernel/msetimer.pas b/mseide-msegui/lib/common/kernel/msetimer.pas new file mode 100644 index 0000000..fc3f588 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msetimer.pas @@ -0,0 +1,1426 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msetimer; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +uses + classes,mclasses,msetypes,mseevent,mseclasses,mseglob; + +type + timeroptionty = (to_single, //single shot + to_leak, //do not catch up missed timeouts + to_highres, //call application.beginhighrestimer/ + //endhighrestimer, necessary on windows in order + //to get 1ms jitter + to_absolute, //use absolute time (timestamp()) for to_single + //disabled for ttimer + to_autostart);//set enabled for to_single by setting interval, + //disabled for ttimer + timeroptionsty = set of timeroptionty; + + tsimpletimer = class(tnullinterfacedobject) + private + fenabled: boolean; + finterval: longword; + fontimer: notifyeventty; + foptions: timeroptionsty; +// fpending: boolean; + procedure setenabled(const Value: boolean); + procedure setinterval(const avalue: longword); + function getsingleshot: boolean; + procedure setsingleshot(const avalue: boolean); + procedure setoptions(const avalue: timeroptionsty); + function gethighres: boolean; + procedure sethighres(const avalue: boolean); + function getleak: boolean; + procedure setleak(const avalue: boolean); + protected + procedure dotimer; virtual; + public + constructor create(const interval: longword = 0; + const ontimer: notifyeventty = nil; + const active: boolean = false; + const aoptions: timeroptionsty = []); + //activates timer + destructor destroy; override; + procedure firependingandstop; + procedure fireandstop; + procedure fire; + procedure restart; + property interval: longword read finterval write setinterval; + //in microseconds, max +2000 seconds + //restarts timer if enabled + //0 -> fire once in mainloop idle + property options: timeroptionsty read foptions write setoptions; + property singleshot: boolean read getsingleshot write setsingleshot; + property highres: boolean read gethighres write sethighres; + property leak: boolean read getleak write setleak; + property ontimer: notifyeventty read fontimer write fontimer; + property enabled: boolean read fenabled write setenabled default true; + //last! + end; + + trepeater = class(tsimpletimer) + private + finterval2: longword; + protected + procedure dotimer; override; + public + constructor create(const adelay: longword; const ainterval: longword; + const aontimer: notifyeventty); + end; + + ttimer = class(tmsecomponent) + private + ftimer: tsimpletimer; + fenabled: boolean; //for design +// foptions: timeroptionsty; + fontimer: notifyeventty; + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function getinterval: integer; + procedure setinterval(avalue: integer); + function getontimer: notifyeventty; + procedure setontimer(const Value: notifyeventty); + function getoptions: timeroptionsty; + procedure setoptions(const avalue: timeroptionsty); + function getsingleshot: boolean; + procedure setsingleshot(const avalue: boolean); + procedure dotimer(const sender: tobject); + protected + procedure doasyncevent(var atag: integer); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure restart; + procedure firependingandstop; + procedure fireandstop; + procedure fire; + property singleshot: boolean read getsingleshot write setsingleshot; + published + property interval: integer read getinterval write setinterval default 1000000; + //in microseconds, max 2000 seconds + //restarts timer if enabled + //0 -> fire once in main loop idle + property options: timeroptionsty read getoptions write setoptions default []; + property ontimer: notifyeventty read fontimer write fontimer; + property enabled: boolean read getenabled write setenabled default false; + //last! + end; + +const + defaultanimtick = 100000; //microseconds + +type + animkindty = (ank_single,ank_sawtooth,ank_triangle); + animoptionty = (ano_enabled, + ano_autodestroy //animitem destroyed if enable set to false + //or ank_single terminates + ); + animoptionsty = set of animoptionty; + + tanimtimer = class; + tanimitem = class; + + animtickeventty = procedure(const sender: tanimitem; + const avalue: flo64) of object; + animstatety = (ans_down,ans_finished); + animstatesty = set of animstatety; + + tanimitem = class(tlinkedobject) + private + fontick: animtickeventty; + fonstart: notifyeventty; + fonstop: notifyeventty; + procedure setenabled(const avalue: boolean); + procedure settickus(const avalue: int32); + procedure setkind(const avalue: animkindty); + procedure setoptions(const avalue: animoptionsty); + function getdown: boolean; + procedure setdown(const avalue: boolean); + function getvalue: flo64; + protected + fowner: tobject; + ftimer: tanimtimer; + fenabled: boolean; + fref: card32; + fnexttick: card32; + ftickus: int32; + ftickref: card32; + fkind: animkindty; + fstate: animstatesty; + foptions: animoptionsty; + finterval: flo64; + ftime: flo64; + procedure tick(); virtual; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure settimer(const atimer: tanimtimer); + procedure setnexttick(); + procedure setnexttick1(); + public + constructor create(const aowner: iobjectlink; const atimer: tanimtimer; + const aontick: animtickeventty; + const ainterval: flo64; //seconds + const akind: animkindty = ank_single; + const aoptions: animoptionsty = [ano_enabled]; + const atickus: int32 = 0); //0 = default + constructor create(const aowner: tmsecomponent; const atimer: tanimtimer; + const aontick: animtickeventty; + const ainterval: flo64; //seconds + const akind: animkindty = ank_single; + const aoptions: animoptionsty = [ano_enabled]; + const atickus: int32 = 0); //0 = default + destructor destroy(); override; + procedure reset(); + procedure restart(); + property kind: animkindty read fkind write setkind; + property options: animoptionsty read foptions write setoptions; + property enabled: boolean read fenabled write setenabled; + property tickus: int32 read ftickus write settickus default 0; + property time: flo64 read ftime write ftime; + property down: boolean read getdown write setdown; + property value: flo64 read getvalue; + property interval: flo64 read finterval write finterval; //seconds + property timer: tanimtimer read ftimer write settimer; + property ontick: animtickeventty read fontick write fontick; + property onstart: notifyeventty read fonstart write fonstart; + property onstop: notifyeventty read fonstop write fonstop; + end; + panimitem = ^tanimitem; + animitemarty = array of tanimitem; + + tanimtimer = class(tmsecomponent) + private + ftouched: boolean; + function gettickus: int32; + procedure settickus(const avalue: int32); + function gethighres: boolean; + procedure sethighres(const avalue: boolean); + procedure setenabled(const avalue: boolean); + protected + fenabledcount: int32; + fitems: animitemarty; + ftimer: tsimpletimer; + fenabled: boolean; + procedure dotimer(const sender: tobject); + procedure add(const aitem: tanimitem); + procedure remove(const aitem: tanimitem); + procedure itemenabled(const avalue: boolean); + procedure checkenabled(); + procedure loaded() override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property enabledcount: int32 read fenabledcount; + published + property tickus: int32 read gettickus write settickus default defaultanimtick; + property highres: boolean read gethighres write sethighres default false; + property enabled: boolean read fenabled write setenabled default false; + end; + + tanimitemcomp = class(tmsecomponent) + private + fitem: tanimitem; + fenabled: boolean; + function getkind: animkindty; + procedure setkind(const avalue: animkindty); + function getoptions: animoptionsty; + procedure setoptions(const avalue: animoptionsty); + function gettimer: tanimtimer; + procedure settimer(const avalue: tanimtimer); + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function gettickus: int32; + procedure settickus(const avalue: int32); + function gettime: flo64; + procedure settime(const avalue: flo64); + function getontick: animtickeventty; + procedure setontick(const avalue: animtickeventty); + function getonstop: notifyeventty; + procedure setonstop(const avalue: notifyeventty); + function getinterval: flo64; + procedure setinterval(const avalue: flo64); + function getonstart: notifyeventty; + procedure setonstart(const avalue: notifyeventty); + function getdown: boolean; + procedure setdown(const avalue: boolean); + protected + procedure loaded() override; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure reset(); + procedure restart(); + property time: flo64 read gettime write settime; + property down: boolean read getdown write setdown; + published + property kind: animkindty read getkind write setkind default ank_single; +// property options: animoptionsty read getoptions write setoptions; + property interval: flo64 read getinterval write setinterval; //seconds + property enabled: boolean read getenabled write setenabled default false; + property timer: tanimtimer read gettimer write settimer; + property tickus: int32 read gettickus write settickus default 0; + property ontick: animtickeventty read getontick write setontick; + property onstart: notifyeventty read getonstart write setonstart; + property onstop: notifyeventty read getonstop write setonstop; + end; + +procedure tick(sender: tobject); +procedure init; +procedure deinit; + +implementation +uses + msesysintf1,msesysintf,SysUtils,mseapplication,msesystypes,msesysutils, + msearrayutils, + mseformatstr{$ifndef mswindows},mselibc{$endif}; + +const + enabletimertag = 8346320; + +type + tapplication1 = class(tcustomapplication); + ptimerinfoty = ^timerinfoty; + timerinfoty = record + nexttime: longword; + interval: longword; + prevpo,nextpo: ptimerinfoty; + ontimer: proceventty; + options: timeroptionsty + {$ifdef mse_debugtimer} + ;checked: boolean + {$endif} + end; + +var + first: ptimerinfoty; + mutex: mutexty; +{$ifdef mse_debugtimer} + timeitemcount: integer; + +procedure checktimer; +var + int1: integer; + po1,po2: ptimerinfoty; +begin + int1:= 0; + po1:= first; + while po1 <> nil do begin + inc(int1); + if po1^.checked then begin + raise exception.create('Recursion in timer list.'); + end; + po1^.checked := true; + if (po1^.nextpo <> nil) and (po1^.nextpo^.prevpo <> po1) then begin + raise exception.create('Invalid back link in timer list'); + end; + po1:= po1^.nextpo; + end; + if int1 <> timeitemcount then begin + raise exception.create('Invalid timer item count.'); + end; + po1:= first; + while po1 <> nil do begin + po1^.checked:= false; + po1:= po1^.nextpo; + end; +end; +{$endif} + +var + timeraccesscount: integer; + +procedure extract(po: ptimerinfoty); + //mutex has to be locked +begin + if not application.ismainthread then begin + inc(timeraccesscount); + end; + if first = po then begin + first:= po^.nextpo; + if first <> nil then begin + first^.prevpo:= nil; + end; + end; + if po^.prevpo <> nil then begin + po^.prevpo^.nextpo:= po^.nextpo; + end; + if po^.nextpo <> nil then begin + po^.nextpo^.prevpo:= po^.prevpo; + end; +{$ifdef mse_debugtimer} + dec(timeitemcount); + checktimer; + inc(timeitemcount); +{$endif} +end; + +procedure insert(po: ptimerinfoty); //mutex has to be locked +var + po1,po2: ptimerinfoty; + ca1: longword; +begin + if not application.ismainthread then begin + inc(timeraccesscount); + end; + ca1:= po^.nexttime; + po2:= po; + po1:= po^.nextpo; + if po1 = nil then begin + po1:= first; + end; +// while (po1 <> nil) and (integer(po1^.nexttime-ca1) < 0) do begin //todo!!!!!: FPC bug 4768 + while (po1 <> nil) and later(po1^.nexttime,ca1) do begin + po2:= po1; + po1:= po1^.nextpo; + end; + if po1 = nil then begin //last + if po2 = po then begin //single + po^.prevpo:= nil; + first:= po; + end + else begin //last + po^.prevpo:= po2; + po2^.nextpo:= po; + end; + po^.nextpo:= nil; + end + else begin + if po1^.prevpo = nil then begin //first + po^.prevpo:= nil; + po1^.prevpo:= po; + first:= po; + po^.nextpo:= po1; + end + else begin + po^.prevpo:= po1^.prevpo; + po^.prevpo^.nextpo:= po; + po1^.prevpo:= po; + po^.nextpo:= po1; + end; + end; +{$ifdef mse_debugtimer} + checktimer; +{$endif} +end; + +procedure killtimertick(aontimer: proceventty); +var + po1{,po2}: ptimerinfoty; +begin + sys_mutexlock(mutex); + po1:= first; + while po1 <> nil do begin + if issamemethod(tmethod(po1^.ontimer),tmethod(aontimer)) then begin + po1^.ontimer:= nil; + end; + po1:= po1^.nextpo; + end; + sys_mutexunlock(mutex); +end; + +procedure starttimer(const reftime: longword); +var + int1: integer; +begin + int1:= first^.nexttime-reftime; + application.settimer(int1); +end; + +procedure settimertick(ainterval: integer; + const aontimer: proceventty; const aoptions: timeroptionsty); +var + po: ptimerinfoty; + time: longword; +begin + new(po); + sys_mutexlock(mutex); + {$ifdef mse_debugtimer} + inc(timeitemcount); +{$endif} + time:= sys_gettimeus; + if to_absolute in aoptions then begin + ainterval:= ainterval - time; + if integer(ainterval) < 0 then begin + ainterval:= 0; //on idle + end; + end; + fillchar(po^,sizeof(timerinfoty),0); + with po^ do begin + nexttime:= time + longword(ainterval); + interval:= ainterval; + options:= aoptions; + if ainterval = 0 then begin + include(options,to_leak); //on idle + end; +// if to_single in aoptions{ainterval < 0} then begin +// interval:= 0; +// end; + ontimer:= aontimer; + end; + insert(po); + if first = po then begin + starttimer(time); + end + else begin + if later(first^.nexttime,time) then begin + application.postevent(tmseevent.create(ek_timer)); + //timerevent is possibly lost + end; + end; + sys_mutexunlock(mutex); +end; + +var + timebefore: longword; + +procedure tick(sender: tobject); +var + time: longword; + ca1: longword; + po,po2: ptimerinfoty; + ontimer: proceventty; + int1: integer; + timeraccesscountbefore: integer; +label + endlab; +begin + sys_mutexlock(mutex); + tapplication1(application).resettimertrigger; + if first <> nil then begin +{$ifdef mse_debugtimer} + checktimer; +{$endif} + time:= sys_gettimeus; + inc(timeraccesscount); + timeraccesscountbefore:= timeraccesscount; + ca1:= time-timebefore; + timebefore:= time; + if integer(ca1) < 0 then begin //clock has been changed + po:= first; + while po <> nil do begin + po^.nexttime:= po^.nexttime + ca1; //shift timeouts + po:= po^.nextpo; + end; + end; + po:= first; + while (po <> nil) and laterorsame(po^.nexttime,time) do begin + extract(po); + ontimer:= po^.ontimer; + po2:= po^.nextpo; + if (to_single in po^.options) or not assigned(ontimer) then begin + //single shot or killed, remove item + dispose(po); + {$ifdef mse_debugtimer} + dec(timeitemcount); + {$endif} + if assigned(ontimer) then begin + sys_mutexunlock(mutex); + try + ontimer; + except + application.handleexception(sender); + end; + sys_mutexlock(mutex); + if timeraccesscount <> timeraccesscountbefore then begin + goto endlab; //processmessages called + end; + end; + end + else begin + if to_leak in po^.options then begin + int1:= 1; + inc(po^.nexttime,po^.interval); + if later(po^.nexttime,time) then begin + po^.nexttime:= time + po^.interval; + end; + end + else begin + int1:= 0; + repeat + inc(int1); + inc(po^.nexttime,po^.interval) + until later(time,po^.nexttime); + end; + insert(po); + for int1:= int1 - 1 downto 0 do begin + if assigned(po^.ontimer) then begin + sys_mutexunlock(mutex); + try + po^.ontimer; + except + application.handleexception(sender); + end; + sys_mutexlock(mutex); + if timeraccesscount <> timeraccesscountbefore then begin + goto endlab; //processmessages called, + // tick leak possible for current item + end; + end; + end; + end; + po:= po2; + end; + if first <> nil then begin + starttimer(time); + end; + end; +endlab: +{$ifdef mse_debugtimer} + checktimer; +{$endif} + sys_mutexunlock(mutex); +end; + +procedure init; +begin + sys_mutexcreate(mutex); +end; + +procedure deinit; +var + po1,po2: ptimerinfoty; +begin + sys_mutexlock(mutex); + po1:= first; + while po1 <> nil do begin + po2:= po1; + po1:= po1^.nextpo; + dispose(po2); + end; + first:= nil; + sys_mutexunlock(mutex); + sys_mutexdestroy(mutex); +end; + +{ tsimpletimer } + +constructor tsimpletimer.create(const interval: longword; + const ontimer: notifyeventty; const active: boolean; + const aoptions: timeroptionsty); +begin + finterval:= interval; + fontimer:= ontimer; + foptions:= aoptions; + setenabled(active); +end; + +destructor tsimpletimer.destroy; +begin + enabled:= false; + inherited; +end; + +procedure tsimpletimer.dotimer; +begin + if (to_single in foptions) {or (finterval = 0)} then begin + fenabled:= false; + end; +// if finterval <= 0 then begin +// fenabled:= false; +// end; + if assigned(fontimer) then begin + fontimer(self); + end; +end; + +procedure tsimpletimer.setenabled(const Value: boolean); +begin + if fenabled <> value then begin + sys_mutexlock(mutex); + fenabled:= Value; + if not value then begin + if to_highres in foptions then begin + application.endhighrestimer(); + end; + killtimertick({$ifdef FPC}@{$endif}dotimer); + end + else begin + if to_highres in foptions then begin + application.beginhighrestimer(); + end; + settimertick(finterval,{$ifdef FPC}@{$endif}dotimer,foptions); + end; + sys_mutexunlock(mutex); + end; +end; + +procedure tsimpletimer.setinterval(const avalue: longword); +begin + if not (to_absolute in foptions) and (avalue > 2000000000) then begin + raise exception.create('Invalid timer interval ' + inttostr(avalue)); + end; + finterval:= avalue; + if fenabled then begin + sys_mutexlock(mutex); + killtimertick({$ifdef FPC}@{$endif}dotimer); + settimertick(finterval,{$ifdef FPC}@{$endif}dotimer,foptions); + sys_mutexunlock(mutex); + end + else begin + if foptions * [to_single,to_autostart] = [to_single,to_autostart] then begin + enabled:= true; + end; + end; +end; + +procedure tsimpletimer.firependingandstop; +begin + if fenabled then begin + enabled:= false; + dotimer; + end; +end; + +procedure tsimpletimer.fireandstop; +begin + enabled:= false; + dotimer; +end; + +procedure tsimpletimer.fire; +begin + if assigned(fontimer) then begin //do not clear fenabled + fontimer(self); + end; +end; + +procedure tsimpletimer.restart; +begin + interval:= interval; + enabled:= true; +end; + +function tsimpletimer.getsingleshot: boolean; +begin + result:= to_single in foptions; +end; + +procedure tsimpletimer.setsingleshot(const avalue: boolean); +begin + if avalue then begin + options:= options + [to_single]; + end + else begin + options:= options - [to_single]; + end; +end; + +procedure tsimpletimer.setoptions(const avalue: timeroptionsty); +var + opt1: timeroptionsty; +begin + opt1:= foptions >< avalue; + if opt1 <> [] then begin + foptions:= avalue; + if enabled then begin + if to_highres in opt1 then begin + if to_highres in avalue then begin + application.beginhighrestimer(); + end + else begin + application.endhighrestimer(); + end; + end; + end; + end; +end; + +function tsimpletimer.gethighres: boolean; +begin + result:= to_highres in foptions; +end; + +procedure tsimpletimer.sethighres(const avalue: boolean); +begin + if avalue then begin + options:= foptions + [to_highres]; + end + else begin + options:= foptions - [to_highres]; + end; +end; + +function tsimpletimer.getleak: boolean; +begin + result:= to_leak in foptions; +end; + +procedure tsimpletimer.setleak(const avalue: boolean); +begin + if avalue then begin + options:= foptions + [to_leak]; + end + else begin + options:= foptions - [to_leak]; + end; +end; + +{ ttimer } + +constructor ttimer.create(aowner: tcomponent); +begin + ftimer:= tsimpletimer.create(1000000,{$ifdef FPC}@{$endif}dotimer,false,[]); + inherited; +end; + +destructor ttimer.destroy; +begin + ftimer.Free; + inherited; +end; + +function ttimer.getenabled: boolean; +begin + if csdesigning in componentstate then begin + result:= fenabled; + end + else begin + result:= ftimer.enabled; + end; +end; + +procedure ttimer.setenabled(const avalue: boolean); +begin + if not (csdesigning in componentstate) then begin + if not application.ismainthread then begin + sys_mutexlock(mutex); + fenabled:= avalue; + if avalue and not ftimer.enabled then begin + asyncevent(enabletimertag); //win32 settimer must be in mainthread + sys_mutexunlock(mutex); + end + else begin + sys_mutexunlock(mutex); + ftimer.enabled:= avalue; + end; + end + else begin + ftimer.enabled:= avalue; + end; + end + else begin + fenabled:= avalue; + end; +end; + +procedure ttimer.doasyncevent(var atag: integer); +begin + if fenabled and (atag = enabletimertag) then begin + ftimer.enabled:= true; + end; +end; + +function ttimer.getinterval: integer; +begin + result:= ftimer.interval; +end; + +procedure ttimer.setinterval(avalue: integer); +begin + if avalue < 0 then begin + include(ftimer.foptions,to_single); + avalue:= -avalue; + end; + if not application.ismainthread and ftimer.enabled then begin + enabled:= false; + ftimer.interval:= avalue; //win32 settimer must be in main thread + enabled:= true; + end + else begin + ftimer.interval:= avalue; + end; +end; + +function ttimer.getontimer: notifyeventty; +begin + result:= ftimer.ontimer; +end; + +procedure ttimer.setontimer(const Value: notifyeventty); +begin + ftimer.ontimer:= value; +end; + +procedure ttimer.restart; +begin + interval:= ftimer.interval; + enabled:= true; +end; + +procedure ttimer.firependingandstop; +begin + ftimer.firependingandstop; +end; + +procedure ttimer.fireandstop; +begin + ftimer.fireandstop; +end; + +procedure ttimer.fire; +begin + ftimer.fire; +end; + +function ttimer.getoptions: timeroptionsty; +begin + result:= ftimer.options; +end; + +procedure ttimer.setoptions(const avalue: timeroptionsty); +begin + ftimer.options:= avalue - [to_autostart,to_absolute]; +end; + +function ttimer.getsingleshot: boolean; +begin + result:= ftimer.singleshot; +end; + +procedure ttimer.setsingleshot(const avalue: boolean); +begin + ftimer.singleshot:= avalue; +end; + +procedure ttimer.dotimer(const sender: tobject); +begin + if canevent(tmethod(fontimer)) then begin + fontimer(self); + end; +end; + +{ trepeater } + +constructor trepeater.create(const adelay: longword; const ainterval: longword; + const aontimer: notifyeventty); +begin + finterval2:= ainterval; + inherited create(adelay,aontimer,true,[]); +end; + +procedure trepeater.dotimer; +begin + if finterval <> finterval2 then begin + interval:= finterval2; + end; + inherited; +end; + +{ tanimitem } + +constructor tanimitem.create(const aowner: iobjectlink; + const atimer: tanimtimer; + const aontick: animtickeventty; + const ainterval: flo64; + const akind: animkindty = ank_single; + const aoptions: animoptionsty = [ano_enabled]; + const atickus: int32 = 0); +begin + ftickus:= atickus; + fontick:= aontick; + finterval:= ainterval; + fkind:= akind; + foptions:= aoptions; + if aowner <> nil then begin + fowner:= aowner.getinstance(); + getobjectlinker.link(iobjectlink(self),aowner); + end; + settimer(atimer); + inherited create(); + enabled:= ano_enabled in aoptions; +end; + +constructor tanimitem.create(const aowner: tmsecomponent; + const atimer: tanimtimer; + const aontick: animtickeventty; + const ainterval: flo64; + const akind: animkindty = ank_single; + const aoptions: animoptionsty = [ano_enabled]; + const atickus: int32 = 0); +var + ev1: ievent; +begin + ev1:= nil; + if aowner <> nil then begin + ev1:= ievent(aowner); + end; + create(ev1,atimer,aontick,ainterval,akind,aoptions,atickus); +end; + +destructor tanimitem.destroy(); +begin + settimer(nil); + inherited; +end; + +procedure tanimitem.reset(); +begin + ftime:= 0; + fstate:= fstate - [ans_down,ans_finished]; +end; + +procedure tanimitem.restart(); +begin + reset(); + if enabled then begin + if assigned(fonstart) then begin + fonstart(self); + end; + end + else begin + enabled:= true; + end; +end; + +procedure tanimitem.setnexttick(); +begin + fref:= timebefore; + setnexttick1; +end; + +procedure tanimitem.setnexttick1(); +begin + if ftickus = 0 then begin + fnexttick:= timebefore+ftimer.tickus; + end + else begin + fnexttick:= timebefore+ftickus; + end; +end; + +function tanimitem.getvalue: flo64; +begin + if (fkind = ank_triangle) and (ans_down in fstate) then begin + result:= 1-ftime; + end + else begin + result:= ftime; + end; +end; + +procedure tanimitem.tick(); +var + c1: card32; + b1: boolean; +begin + if (ftickus = 0) or (ftickus = ftimer.tickus) or + laterorsame(fnexttick,timebefore) then begin + c1:= timebefore-fref; +// if int32(c1) >= 0 then begin + if finterval > 0 then begin + ftime:= ftime + (c1/1000000)/finterval; //seconds + end; + b1:= false; + while ftime > 1 do begin + if fkind = ank_single then begin + b1:= true; + ftime:= 1; + break; + end; + ftime:= ftime-1; + fstate:= fstate >< [ans_down]; + end; + fref:= timebefore; + setnexttick1(); + if assigned(fontick) then begin + fontick(self,getvalue); + end; + if b1 then begin + enabled:= false; + include(fstate,ans_finished); + end; +// end +// else begin + setnexttick1; +// end; + end; +end; + +procedure tanimitem.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_destroyed) then begin + if sender = ftimer then begin + ftimer:= nil; + end; + if sender = fowner then begin + destroy(); + end; + end; +end; + +procedure tanimitem.setenabled(const avalue: boolean); +begin + if fenabled <> avalue then begin + if not avalue or not(ans_finished in fstate) then begin + fenabled:= avalue; + if ftimer <> nil then begin + ftimer.itemenabled(avalue); + end; + if not enabled then begin + if assigned(fonstop) then begin + fonstop(self); + end; + if ano_autodestroy in foptions then begin + destroy(); + end; + end + else begin + if assigned(fonstart) then begin + fonstart(self); + end; + fref:= timebefore; + fnexttick:= fref; + tick(); //immediately + end; + end; + end; +end; + +procedure tanimitem.settickus(const avalue: int32); +begin + if ftickus <> avalue then begin + ftickus:= avalue; + setnexttick(); + end; +end; + +procedure tanimitem.setkind(const avalue: animkindty); +begin + fkind:= avalue; +end; + +procedure tanimitem.setoptions(const avalue: animoptionsty); +begin + foptions:= avalue; +end; + +function tanimitem.getdown: boolean; +begin + result:= ans_down in fstate; +end; + +procedure tanimitem.setdown(const avalue: boolean); +begin + if avalue then begin + include(fstate,ans_down); + end + else begin + exclude(fstate,ans_down); + end; +end; + +procedure tanimitem.settimer(const atimer: tanimtimer); +begin + if ftimer <> atimer then begin + if ftimer <> nil then begin + ftimer.remove(self); + end; + ftimer:= atimer; + if ftimer <> nil then begin + ftimer.add(self); + end; + end; +end; + +{ tanimtimer } + +constructor tanimtimer.create(aowner: tcomponent); +begin + ftimer:= tsimpletimer.create(defaultanimtick,@dotimer,false,[to_leak]); + inherited; +end; + +destructor tanimtimer.destroy; +begin + enabled:= false; + ftimer.free; + inherited; +end; + +function tanimtimer.gettickus: int32; +begin + result:= ftimer.interval; +end; + +procedure tanimtimer.settickus(const avalue: int32); +begin + ftimer.interval:= avalue; +end; + +function tanimtimer.gethighres: boolean; +begin + result:= ftimer.highres; +end; + +procedure tanimtimer.sethighres(const avalue: boolean); +begin + ftimer.highres:= avalue; +end; + +procedure tanimtimer.setenabled(const avalue: boolean); +begin + fenabled:= avalue; + if not (csreading in componentstate) then begin + checkenabled(); + end; +end; + +procedure tanimtimer.dotimer(const sender: tobject); +var + p1,pe: panimitem; + i1: int32; +label + loopstart; +begin + i1:= 0; + while i1 < 8 do begin //emergency brake +loopstart: + if fenabledcount > 0 then begin + p1:= pointer(fitems); + pe:= p1+high(fitems); + while p1 <= pe do begin + if p1^.enabled then begin + ftouched:= false; + p1^.tick(); + if ftouched then begin + goto loopstart; + end; + end; + inc(p1); + end; + break; + end + else begin + break; + end; + inc(i1); + end; +end; + +procedure tanimtimer.add(const aitem: tanimitem); +begin + if addnewitem(pointerarty(fitems),aitem) >= 0 then begin + ftouched:= true; + aitem.getobjectlinker.link(self); + if aitem.enabled then begin + itemenabled(true); + end; + end; +end; + +procedure tanimtimer.remove(const aitem: tanimitem); +begin + if removeitem(pointerarty(fitems),aitem) >= 0 then begin + ftouched:= true; + aitem.getobjectlinker.unlink(self); + if aitem.enabled then begin + itemenabled(false); + end; + end; +end; + +procedure tanimtimer.itemenabled(const avalue: boolean); +begin + if avalue then begin + inc(fenabledcount); + checkenabled(); + end + else begin + dec(fenabledcount); + if fenabledcount <= 0 then begin + ftimer.enabled:= false; + end; + end; +end; + +procedure tanimtimer.checkenabled(); +var + p1,pe: panimitem; +begin + if fenabled and (fenabledcount > 0) then begin + if not ftimer.enabled then begin + p1:= pointer(fitems); + pe:= p1+high(fitems); + while p1 <= pe do begin + if p1^.enabled then begin + p1^.setnexttick(); + end; + inc(p1); + end; + ftimer.enabled:= true; + end; + end + else begin + ftimer.enabled:= false; + end; +end; + +procedure tanimtimer.loaded(); +begin + inherited; + checkenabled(); +end; + +{ tanimitemcomp } + +constructor tanimitemcomp.create(aowner: tcomponent); +begin + fitem:= tanimitem.create(self,nil,nil,1.0,ank_single,[],0); + inherited; +end; + +destructor tanimitemcomp.destroy(); +begin + fitem.free; + inherited; +end; + +function tanimitemcomp.getkind: animkindty; +begin + result:= fitem.kind; +end; + +procedure tanimitemcomp.setkind(const avalue: animkindty); +begin + fitem.kind:= avalue; +end; + +function tanimitemcomp.getoptions: animoptionsty; +begin + result:= fitem.options; +end; + +procedure tanimitemcomp.setoptions(const avalue: animoptionsty); +begin + fitem.options:= avalue - [ano_autodestroy]; +end; + +function tanimitemcomp.gettimer: tanimtimer; +begin + result:= fitem.timer; +end; + +procedure tanimitemcomp.settimer(const avalue: tanimtimer); +begin + fitem.timer:= avalue; +end; + +function tanimitemcomp.getenabled: boolean; +begin + result:= fenabled; +end; + +procedure tanimitemcomp.setenabled(const avalue: boolean); +begin + fenabled:= avalue; + if not (csreading in componentstate) then begin + fitem.enabled:= avalue; + end; +end; + +function tanimitemcomp.gettickus: int32; +begin + result:= fitem.tickus; +end; + +procedure tanimitemcomp.settickus(const avalue: int32); +begin + fitem.tickus:= avalue; +end; + +function tanimitemcomp.gettime: flo64; +begin + result:= fitem.time; +end; + +procedure tanimitemcomp.settime(const avalue: flo64); +begin + fitem.time:= avalue; +end; + +function tanimitemcomp.getontick: animtickeventty; +begin + result:= fitem.ontick; +end; + +procedure tanimitemcomp.setontick(const avalue: animtickeventty); +begin + fitem.ontick:= avalue; +end; + +function tanimitemcomp.getonstart: notifyeventty; +begin + result:= fitem.onstart; +end; + +procedure tanimitemcomp.setonstart(const avalue: notifyeventty); +begin + fitem.onstart:= avalue; +end; + +function tanimitemcomp.getdown: boolean; +begin + result:= fitem.down; +end; + +procedure tanimitemcomp.setdown(const avalue: boolean); +begin + fitem.down:= avalue; +end; + +function tanimitemcomp.getonstop: notifyeventty; +begin + result:= fitem.onstop; +end; + +procedure tanimitemcomp.setonstop(const avalue: notifyeventty); +begin + fitem.onstop:= avalue; +end; + +function tanimitemcomp.getinterval: flo64; +begin + result:= fitem.interval; +end; + +procedure tanimitemcomp.setinterval(const avalue: flo64); +begin + fitem.interval:= avalue; +end; + +procedure tanimitemcomp.reset(); +begin + fitem.reset; +end; + +procedure tanimitemcomp.restart(); +begin + fitem.restart(); +end; + +procedure tanimitemcomp.loaded(); +begin + inherited; + if fenabled then begin + fitem.enabled:= true; + end; +end; + +initialization +{$ifndef mswindows} + initlibc(); //clock_gettime must be inited +{$endif} + timebefore:= sys_gettimeus; +end. diff --git a/mseide-msegui/lib/common/kernel/msetmpmodules.pas b/mseide-msegui/lib/common/kernel/msetmpmodules.pas new file mode 100644 index 0000000..787013e --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msetmpmodules.pas @@ -0,0 +1,100 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msetmpmodules; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses; + +procedure beginloadtmpmodule; +procedure endloadtmpmodule; +procedure addtmpmodule(const amodule: tmsecomponent); + +function createtmpmodule(const aclassname: string; + const aobjdata: tstream; + const onloaded: msecomponenteventty = nil): tmsecomponent; + +implementation +uses + sysutils,mseapplication; +type + tmsecomponent1 = class(tmsecomponent); + +var + ftmpmodules: tmodulelist; + +function createtmpmodule(const aclassname: string; + const aobjdata: tstream; + const onloaded: msecomponenteventty = nil): tmsecomponent; +var + class1: tpersistentclass; +begin + class1:= findclass(aclassname); + if not class1.inheritsfrom(tmsecomponent) then begin + raise exception.create('Class "'+aclassname+ + '" must inherit from tmsecomponent.'); + end; + result:= tmsecomponent(class1.newinstance); + with tmsecomponent1(result) do begin + fmsecomponentstate:= fmsecomponentstate + [cs_noload,cs_tmpmodule]; + try + beginloadtmpmodule; + try + create(nil); //destoyed by modulelist + exclude(fmsecomponentstate,cs_noload); + aobjdata.readcomponent(result); + if assigned(onloaded) then begin + onloaded(result); + end; + addtmpmodule(result); + finally + endloadtmpmodule; + end; + except + result.free; + raise; + end; + end; +end; + +function findtmpmodulebyname(const name: string): tcomponent; +begin + result:= ftmpmodules.findmodulebyname(name); +end; + +procedure beginloadtmpmodule; +begin + lockfindglobalcomponent; + ftmpmodules.unlock; + begingloballoading; +end; + +procedure endloadtmpmodule; +begin + endgloballoading; + ftmpmodules.lock; + unlockfindglobalcomponent; +end; + +procedure addtmpmodule(const amodule: tmsecomponent); +begin + ftmpmodules.add(amodule); + globalfixupreferences; + notifygloballoading; + tmsecomponent1(amodule).doafterload; +end; + +initialization + ftmpmodules:= tmodulelist.create(true); + ftmpmodules.lock; + registerfindglobalcomponentproc({$ifdef FPC}@{$endif}findtmpmodulebyname); +finalization + freeandnil(ftmpmodules); +end. diff --git a/mseide-msegui/lib/common/kernel/msetypes.pas b/mseide-msegui/lib/common/kernel/msetypes.pas new file mode 100644 index 0000000..aaea3be --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msetypes.pas @@ -0,0 +1,532 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msetypes; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + SysUtils; + +type +{$ifdef FPC} + {$ifndef mse_nounicodestring} + {$if defined(FPC) and (fpc_fullversion >= 020300)} + {$define mse_unicodestring} + {$ifend} + {$endif} + {$ifndef mse_unicodestring} + {$ifdef FPC_WINLIKEWIDESTRING} + {$define msestringsarenotrefcounted} + {$endif} + {$endif} +{$else} + {$ifdef mswindows} + {$define msestringsarenotrefcounted} + {$endif} +{$endif} + +{$ifdef FPC} + {$if defined(FPC) and (fpc_fullversion >= 020300)} + {$define mse_fpc_2_3_0} + {$ifend} + {$if defined(FPC) and (fpc_fullversion >= 020402)} + {$define mse_fpc_2_4_2} + {$ifend} + + {$ifdef mse_fpc_2_3_0}{$define longwordbyteset}{$endif} + + {$ifdef longwordbyteset} + byteset = byte; + wordset = word; + longwordset = longword; + {$else} + byteset = longword; + wordset = longword; + longwordset = longword; + {$endif} +{$else} + byteset = byte; + wordset = word; + longwordset = longword; +{$endif} + + //MSElang types + card8 = byte; + pcard8 = ^card8; + card8arty = array of card8; + pcard8arty = ^card8arty; + card8ararty = array of card8arty; + pcard8ararty = ^card8ararty; + card16 = word; + pcard16 = ^card16; + card16arty = array of card16; + pcard16arty = ^card16arty; + card16ararty = array of card16arty; + pcard16ararty = ^card16ararty; + card32 = longword; + pcard32 = ^card32; + card32arty = array of card32; + pcard32arty = ^card32arty; + card32ararty = array of card32arty; + pcard32ararty = ^card32ararty; + card64 = qword; + pcard64 = ^card64; + card64arty = array of card64; + pcard64arty = ^card64arty; + card64ararty = array of card64arty; + pcard64ararty = ^card64ararty; + int8 = shortint; + pint8 = ^int8; + int8arty = array of int8; + pint8arty = ^int8arty; + int8ararty = array of int8arty; + pint8ararty = ^int8ararty; + int16 = smallint; + pint16 = ^int16; + int16arty = array of int16; + pint16arty = ^int16arty; + int16ararty = array of int16arty; + pint16ararty = ^int16ararty; + int32 = integer; + pint32 = ^int32; + int32arty = array of int32; + pint32arty = ^int32arty; + int32ararty = array of int32arty; + pint32ararty = ^int32ararty; +// int64 = int64; +// pint64 = ^int64; + int64arty = array of int64; + pint64arty = ^int64arty; + int64ararty = array of int64arty; + pint64ararty = ^int64ararty; + + flo32 = single; + pflo32 = ^flo32; + flo32arty = array of flo32; + pflo32arty = ^flo32arty; + flo32ararty = array of flo32arty; + pflo32ararty = ^flo32ararty; + + flo64 = double; + pflo64 = ^flo64; + flo64arty = array of flo64; + pflo64arty = ^flo64arty; + flo64ararty = array of flo64arty; + pflo64ararty = ^flo64ararty; + + float32 = single; //todo: remove + pfloat32 = ^float32; + float32arty = array of float32; + pfloat32arty = ^float32arty; + float64 = double; + pfloat64 = ^float64; + float64arty = array of float64; + pfloat64arty = ^float64arty; + float = float64; + pfloat = ^float; + floatarty = array of float; + pfloatarty = ^floatarty; + + uint8 = byte; + puint8 = ^uint8; + uint16 = word; + puint16 = ^uint16; + uint32 = longword; + puint32 = ^uint32; + uint64 = qword; + puint64 = ^uint64; + sint8 = shortint; + psint8 = ^sint8; + sint16 = smallint; + psint16 = ^sint16; + sint32 = integer; + psint32 = ^sint32; + sint64 = int64; + psint64 = ^sint64; + + char8 = char; + pchar8 = ^char8; + char16 = unicodechar; + pchar16 = ^char16; + char32 = ucs4char; + pchar32 = ^char32; + +{$ifndef FPC} //delphi + {$ifndef mswindows} + uint64 = type int64; //kylix + {$endif} + DWord = Longword; + pdword = ^dword; + SizeInt = Longint; + psizeint = ^sizeint; + SizeUInt = DWord; + psizeuint = ^sizeuint; + plongbool = ^longbool; + ppdouble = ^pdouble; + + PtrInt = Longint; + PPtrInt = ^PtrInt; + PtrUInt = DWord; + PPtrUInt = ^PtrUInt; + ValSInt = Longint; + ValUInt = Cardinal; + qword = uint64; + pqword = ^qword; + size_t = dword; + unicodestring = widestring; + unicodechar = widechar; + WINBOOL = longbool; +{$else} + {$ifndef mse_fpc_2_4_2} + ppdouble = ^pdouble; + {$endif} +{$endif} + {$ifdef VER2_2_0} + PPtrUInt = ^PtrUInt; + {$endif} + + ppsizeint = ^psizeint; + ppppointer = ^pppointer; + preal = ^real; + realty = type double; + prealty = ^realty; + + datetimekindty = (dtk_date,dtk_time,dtk_datetime); + dayofweekty = (dw_sun,dw_mon,dw_tue,dw_wed,dw_thu,dw_fri,dw_sat); + +const + maxdatasize = $7fffffff; + {$ifdef mswindows} + pathdelim = '\'; + lineend = #$0d#$0a; + {$else} + pathdelim = '/'; + lineend = #$0a; + {$endif} + + c_dle = #$10; + c_stx = #$02; + c_etx = #$03; + c_linefeed = #$0a; + c_formfeed = #$0c; + c_return = #$0d; + c_tab = #$09; + c_backspace = #$08; + c_esc = #$1b; + c_delete = #$7f; + c_softhyphen = #$ad; + +type + {$ifdef mse_unicodestring} + msestring = unicodestring; + msechar = unicodechar; + pmsechar = punicodechar; + {$else} + msestring = widestring; + msechar = widechar; + pmsechar = pwidechar; + {$endif} + + pmsestring = ^msestring; + msestringarty = array of msestring; + pmsestringarty = ^msestringarty; + msestringaty = array[0..0] of msestring; + pmsestringaty = ^msestringaty; + msestringararty = array of msestringarty; + + widestringarty = array of widestring; +// charaty = array[0..maxdatasize-1] of char; +// pcharaty = ^charaty; + msecharaty = array[0..maxdatasize div sizeof(msechar)-1] of msechar; + pmsecharaty = ^msecharaty; + captionty = msestring; + filenamety = msestring; + pfilenamety = ^filenamety; + filenamearty = msestringarty; + filenamechar = msechar; + pfilenamechar = ^filenamechar; + +const +{$ifndef FPC} + emptyreal = -1/0; +{$else} + emptyreal = real(-1/0); + emptydouble = double(-1/0); + emptyfloat64 = float64(-1/0); +{$endif} + emptydatetime = emptyreal; + +// emptytime = 0.0; +// nulltime = 1.0; //fuer tdateeditmse +// emptydate = 0.0; + maxint64 = $7fffffffffffffff; + minint = low(integer); + bigint = maxint div 2; + nullmethod: tmethod = (code: nil; data: nil); +{$ifdef cpu64} + pointeralignmask = ptruint($ffffffffffffffff) - $7; +{$else} + pointeralignmask = ptruint($ffffffff) - $3; +{$endif} + +type + halfinteger = -bigint..bigint; + posinteger = 0..maxint; + + pobject = ^tobject; + pmethod = ^tmethod; + + booleanarty = array of boolean; + pbooleanarty = ^booleanarty; + longboolarty = array of longbool; + bytearty = array of byte; + pbytearty = ^bytearty; + wordarty = array of word; + pwordarty = ^wordarty; + smallintarty = array of smallint; + psmallintarty = ^smallintarty; + longwordarty = array of longword; + plongwordarty = ^longwordarty; + integerarty = array of integer; + pintegerarty = ^integerarty; + cardinalarty = array of cardinal; + pcardinalarty = ^cardinalarty; + pointerarty = array of pointer; + ppointerarty = ^pointerarty; + pointerararty = array of pointerarty; + objectarty = array of tobject; + pobjectarty = ^objectarty; + classarty = array of tclass; + pclassarty = ^classarty; + + realarty = array of realty; + prealarty = ^realarty; + realararty = array of realarty; + + singlearty = array of single; + singlepoarty = array of psingle; + psinglearty = ^singlearty; + singleararty = array of singlearty; + + doublearty = array of double; + doublepoarty = array of pdouble; + pdoublearty = ^doublearty; + doubleararty = array of doublearty; + + currencyarty = array of currency; + pcurrencyarty = ^currencyarty; + datetimearty = array of tdatetime; + pdatetimearty = ^datetimearty; + datetimeaty = array[0..0] of tdatetime; + pdatetimeaty = ^datetimeaty; + ptrintarty = array of ptrint; + pptrintarty = ^ptrintarty; + ptruintarty = array of ptruint; + pptruintarty = ^ptruintarty; + qwordarty = array of qword; + pqwordarty = ^qwordarty; + + pdatetime = ^tdatetime; + ppvariant = ^pvariant; + + complexty = record re,im: real; end; + pcomplexty = ^complexty; + complexarty = array of complexty; + pcomplexarty = ^complexarty; + complexararty = array of complexarty; + stringarty = array of string; + pstringarty = ^stringarty; + stringararty = array of stringarty; + pstringararty = ^stringararty; + ansistringarty = array of ansistring; + pansistringarty = ^ansistringarty; + ansistringararty = array of ansistringarty; + pansistringararty = ^ansistringararty; + + pointeraty = array[0..0] of pointer; + ppointeraty = ^pointeraty; + charpoaty = array[0..0] of pchar; + pcharpoaty = ^charpoaty; + byteaty = array[0..0] of byte; + pbyteaty = ^byteaty; + wordaty = array[0..0] of word; + pwordaty = ^wordaty; + integeraty = array[0..0] of integer; + pintegeraty = ^integeraty; + longwordaty = array[0..0] of longword; + plongwordaty = ^longwordaty; + cardinalaty = array[0..0] of cardinal; + pcardinalaty = ^cardinalaty; + longboolaty = array[0..0] of longbool; + qwordaty = array[0..0] of qword; + pqwordaty = ^qwordaty; + plongboolaty = ^longboolaty; + ptrintaty = array[0..0] of ptrint; + pptrintaty = ^ptrintaty; + ptruintaty = array[0..0] of ptruint; + pptruintaty = ^ptruintaty; + complexaty = array[0..0] of complexty; + pcomplexaty = ^complexaty; + + methodaty = array[0..0] of tmethod; + pmethodaty = ^methodaty; + stringaty = array[0..0] of string; + pstringaty = ^stringaty; + widestringaty = array[0..0] of widestring; + pwidestringaty = ^widestringaty; + ansistringaty = array[0..0] of ansistring; + pansistringaty = ^ansistringaty; + + charaty = array[0..0] of char; + pcharaty = ^charaty; + + widecharaty = array[0..0] of widechar; + pwidecharaty = ^widecharaty; + + objectaty = array[0..0] of tobject; + pobjectaty = ^objectaty; + + procty = procedure; + proceventty = procedure of object; + proceventarty = array of proceventty; + tageventtyty = procedure (const tag: integer) of object; + + integerararty = array of integerarty; + + varrecarty = array of tvarrec; + + gridcoordty = record + col,row: integer; + end; + gridcoordarty = array of gridcoordty; + + gridsizety = record + colcount,rowcount: integer; + end; + + gridrectty = record + case integer of + 0:( + col,row: integer; + colcount,rowcount: integer; + ); + 1:( + pos: gridcoordty; + size: gridsizety; + ) + end; + +// winidty = cardinal; + winidty = type ptruint; //used in published event properties + winidarty = array of winidty; + winidaty = array[0..0] of winidty; + pwinidaty = ^winidaty; + winidararty = array of winidarty; + filehandlety = longint; + + procedurety = procedure; + +const + nullcomplex: complexty = (re: 0; im: 0); + bigdatetime = 401768.99999; //2999-12-31 + +function mergevarrec(a,b: array of const): varrecarty; +function issamemethod(const method1,method2: tmethod): boolean; +function isemptydatetime(const avalue: tdatetime): boolean; + {$ifdef FPC}inline;{$endif} deprecated; + //use x = emptydatetime instead +//function emptydatetime: tdatetime; +function makecomplex(const are: real; aim: real): complexty; + {$ifdef FPC} inline; {$endif} +function mc(const are: real; aim: real): complexty; + {$ifdef FPC} inline; {$endif} +//procedure splitcomplexar(const acomplex: complexarty; out re,im: realarty); + +implementation +//uses +// msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +(* +const +{$ifdef FPC_DOUBLE_HILO_SWAPPED} + co1: array[0..7] of byte = (0,0,$f0,$ff,$0,0,0,0); //- inf +{$else} + co1: array[0..7] of byte = ($0,0,0,0,0,0,$f0,$ff); //- inf +{$endif} +*) +{ +function emptydatetime: tdatetime; +begin + result:= tdatetime(co1); +end; +} +function isemptydatetime(const avalue: tdatetime): boolean; +begin + result:= avalue = emptydatetime; +// result:= avalue = real(co1); +end; + +function mergevarrec(a,b: array of const): varrecarty; +begin + setlength(result,length(a)); + if result <> nil then begin + move(a[0],result[0],length(a)*sizeof(tvarrec)); + end; + if high(b) >= 0 then begin + setlength(result,high(result) + high(b) + 2); + move(b[0],result[length(a)],length(b)*sizeof(tvarrec)); + end; +end; + +function issamemethod(const method1,method2: tmethod): boolean; +begin + result:= (method1.Code = method2.code) and (method1.Data = method2.Data); +end; + +function makecomplex(const are: real; aim: real): complexty; +begin + result.re:= are; + result.im:= aim; +end; + +function mc(const are: real; aim: real): complexty; +begin + result.re:= are; + result.im:= aim; +end; + +end. + + + + + + + + + + diff --git a/mseide-msegui/lib/common/kernel/mseunicodeps.pas b/mseide-msegui/lib/common/kernel/mseunicodeps.pas new file mode 100644 index 0000000..48b9316 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseunicodeps.pas @@ -0,0 +1,581 @@ +unit mseunicodeps; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +uses + msetypes,msestrings; + +type + unicodepagety = (ucp_00,ucp_01,ucp_02,ucp_03,ucp_04,ucp_05,ucp_06, + ucp_1e, + ucp_20,ucp_21,ucp_22,ucp_23,ucp_25,ucp_26); + encodingty = record + codepage: integer; + name: string; + glyphnames: string; + end; + encodingsty = array[unicodepagety] of encodingty; + +const + nl = lineend; + encodings: encodingsty = ( + ( + codepage: $00; + name: 'E00'; //latin1 + glyphnames: +'/uni0000 /uni0001 /uni0002 /uni0003 /uni0004 /uni0005 /uni0006 /uni0007 '+nl+ //00 +'/uni0008 /uni0009 /uni000A /uni000B /uni000C /uni000D /uni000E /uni000F '+nl+ //08 +'/uni0010 /uni0011 /uni0012 /uni0013 /uni0014 /uni0015 /uni0016 /uni0017 '+nl+ //10 +'/uni0018 /uni0019 /uni001A /uni001B /uni001C /uni001D /uni001E /uni001F '+nl+ //18 +'/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle '+nl+ //20 +'/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash '+nl+ //28 +'/zero /one /two /three /four /five /six /seven '+nl+ //30 +'/eight /nine /colon /semicolon /less /equal /greater /question '+nl+ //38 +'/at /A /B /C /D /E /F /G '+nl+ //40 +'/H /I /J /K /L /M /N /O '+nl+ //48 +'/P /Q /R /S /T /U /V /W '+nl+ //50 +'/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore '+nl+ //58 +'/grave /a /b /c /d /e /f /g '+nl+ //60 +'/h /i /j /k /l /m /n /o '+nl+ //68 +'/p /q /r /s /t /u /v /w '+nl+ //70 +'/x /y /z /braceleft /bar /braceright /asciitilde /uni007F '+nl+ //78 +'/uni0080 /uni0081 /uni0082 /uni0083 /uni0084 /uni0085 /uni0086 /uni0087 '+nl+ //80 +'/uni0088 /uni0089 /uni008A /uni008B /uni008C /uni008D /uni008E /uni008F '+nl+ //88 +'/uni0090 /uni0091 /uni0092 /uni0093 /uni0094 /uni0095 /uni0096 /uni0097 '+nl+ //90 +'/uni0098 /uni0099 /uni009A /uni009B /uni009C /uni009D /uni009E /uni009F '+nl+ //98 +'/uni00A0 /exclamdown /cent /sterling /currency /yen /brokenbar /section '+nl+ //A0 +'/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /uni00AD /registered /macron '+nl+ //A8 +'/degree /plusminus /uni00B2 /uni00B3 /acute /uni00B5 /paragraph /periodcentered '+nl+ //B0 +'/cedilla /uni00B9 /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown '+nl+ //B8 +'/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla '+nl+ //C0 +'/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis '+nl+ //C8 +'/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply '+nl+ //D0 +'/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls '+nl+ //D8 +'/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla '+nl+ //E0 +'/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis '+nl+ //E8 +'/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide '+nl+ //F0 +'/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis '+nl //F8 + ), + ( + codepage: $01; + name: 'E01'; //latin extended A + glyphnames: +'/Amacron /amacron /Abreve /abreve /Aogonek /aogonek /Cacute /cacute '+nl+ //00 +'/Ccircumflex /ccircumflex /Cdotaccent /cdotaccent /Ccaron /ccaron /Dcaron /dcaron '+nl+ //08 +'/Dcroat /dcroat /Emacron /emacron /Ebreve /ebreve /Edotaccent /edotaccent '+nl+ //10 +'/Eogonek /eogonek /Ecaron /ecaron /Gcircumflex /gcircumflex /Gbreve /gbreve '+nl+ //18 +'/Gdotaccent /gdotaccent /Gcommaaccent /gcommaaccent /Hcircumflex /hcircumflex /Hbar /hbar '+nl+ //20 +'/Itilde /itilde /Imacron /imacron /Ibreve /ibreve /Iogonek /iogonek '+nl+ //28 +'/Idotaccent /dotlessi /IJ /ij /Jcircumflex /jcircumflex /Kcommaaccent /kcommaaccent '+nl+ //30 +'/kgreenlandic /Lacute /lacute /Lcommaaccent /lcommaaccent /Lcaron /lcaron /Ldot '+nl+ //38 +'/ldot /Lslash /lslash /Nacute /nacute /Ncommaaccent /ncommaaccent /Ncaron '+nl+ //40 +'/ncaron /napostrophe /Eng /eng /Omacron /omacron /Obreve /obreve '+nl+ //48 +'/Ohungarumlaut /ohungarumlaut /OE /oe /Racute /racute /Rcommaaccent /rcommaaccent '+nl+ //50 +'/Rcaron /rcaron /Sacute /sacute /Scircumflex /scircumflex /Scedilla /scedilla '+nl+ //58 +'/Scaron /scaron /Tcommaaccent /tcommaaccent /Tcaron /tcaron /Tbar /tbar '+nl+ //60 +'/Utilde /utilde /Umacron /umacron /Ubreve /ubreve /Uring /uring '+nl+ //68 +'/Uhungarumlaut /uhungarumlaut /Uogonek /uogonek /Wcircumflex /wcircumflex /Ycircumflex /ycircumflex '+nl+ //70 +'/Ydieresis /Zacute /zacute /Zdotaccent /zdotaccent /Zcaron /zcaron /longs '+nl+ //78 +'/uni0180 /uni0181 /uni0182 /uni0183 /uni0184 /uni0185 /uni0186 /uni0187 '+nl+ //80 +'/uni0188 /uni0189 /uni018A /uni018B /uni018C /uni018D /uni018E /uni018F '+nl+ //88 +'/uni0190 /uni0191 /florin /uni0193 /uni0194 /uni0195 /uni0196 /uni0197 '+nl+ //90 +'/uni0198 /uni0199 /uni019A /uni019B /uni019C /uni019D /uni019E /uni019F '+nl+ //98 +'/Ohorn /ohorn /uni01A2 /uni01A3 /uni01A4 /uni01A5 /uni01A6 /uni01A7 '+nl+ //A0 +'/uni01A8 /uni01A9 /uni01AA /uni01AB /uni01AC /uni01AD /uni01AE /Uhorn '+nl+ //A8 +'/uhorn /uni01B1 /uni01B2 /uni01B3 /uni01B4 /uni01B5 /uni01B6 /uni01B7 '+nl+ //B0 +'/uni01B8 /uni01B9 /uni01BA /uni01BB /uni01BC /uni01BD /uni01BE /uni01BF '+nl+ //B8 +'/uni01C0 /uni01C1 /uni01C2 /uni01C3 /uni01C4 /uni01C5 /uni01C6 /uni01C7 '+nl+ //C0 +'/uni01C8 /uni01C9 /uni01CA /uni01CB /uni01CC /uni01CD /uni01CE /uni01CF '+nl+ //C8 +'/uni01D0 /uni01D1 /uni01D2 /uni01D3 /uni01D4 /uni01D5 /uni01D6 /uni01D7 '+nl+ //D0 +'/uni01D8 /uni01D9 /uni01DA /uni01DB /uni01DC /uni01DD /uni01DE /uni01DF '+nl+ //D8 +'/uni01E0 /uni01E1 /uni01E2 /uni01E3 /uni01E4 /uni01E5 /Gcaron /gcaron '+nl+ //E0 +'/uni01E8 /uni01E9 /uni01EA /uni01EB /uni01EC /uni01ED /uni01EE /uni01EF '+nl+ //E8 +'/uni01F0 /uni01F1 /uni01F2 /uni01F3 /uni01F4 /uni01F5 /uni01F6 /uni01F7 '+nl+ //F0 +'/uni01F8 /uni01F9 /Aringacute /aringacute /AEacute /aeacute /Oslashacute /oslashacute '+nl //F8 + ), + ( + codepage: $02; + name: 'E02'; //latin extended B + glyphnames: +'/uni0200 /uni0201 /uni0202 /uni0203 /uni0204 /uni0205 /uni0206 /uni0207 '+nl+ //00 +'/uni0208 /uni0209 /uni020A /uni020B /uni020C /uni020D /uni020E /uni020F '+nl+ //08 +'/uni0210 /uni0211 /uni0212 /uni0213 /uni0214 /uni0215 /uni0216 /uni0217 '+nl+ //10 +'/Scommaaccent /scommaaccent /uni021A /uni021B /uni021C /uni021D /uni021E /uni021F '+nl+ //18 +'/uni0220 /uni0221 /uni0222 /uni0223 /uni0224 /uni0225 /uni0226 /uni0227 '+nl+ //20 +'/uni0228 /uni0229 /uni022A /uni022B /uni022C /uni022D /uni022E /uni022F '+nl+ //28 +'/uni0230 /uni0231 /uni0232 /uni0233 /uni0234 /uni0235 /uni0236 /uni0237 '+nl+ //30 +'/uni0238 /uni0239 /uni023A /uni023B /uni023C /uni023D /uni023E /uni023F '+nl+ //38 +'/uni0240 /uni0241 /uni0242 /uni0243 /uni0244 /uni0245 /uni0246 /uni0247 '+nl+ //40 +'/uni0248 /uni0249 /uni024A /uni024B /uni024C /uni024D /uni024E /uni024F '+nl+ //48 +'/uni0250 /uni0251 /uni0252 /uni0253 /uni0254 /uni0255 /uni0256 /uni0257 '+nl+ //50 +'/uni0258 /uni0259 /uni025A /uni025B /uni025C /uni025D /uni025E /uni025F '+nl+ //58 +'/uni0260 /uni0261 /uni0262 /uni0263 /uni0264 /uni0265 /uni0266 /uni0267 '+nl+ //60 +'/uni0268 /uni0269 /uni026A /uni026B /uni026C /uni026D /uni026E /uni026F '+nl+ //68 +'/uni0270 /uni0271 /uni0272 /uni0273 /uni0274 /uni0275 /uni0276 /uni0277 '+nl+ //70 +'/uni0278 /uni0279 /uni027A /uni027B /uni027C /uni027D /uni027E /uni027F '+nl+ //78 +'/uni0280 /uni0281 /uni0282 /uni0283 /uni0284 /uni0285 /uni0286 /uni0287 '+nl+ //80 +'/uni0288 /uni0289 /uni028A /uni028B /uni028C /uni028D /uni028E /uni028F '+nl+ //88 +'/uni0290 /uni0291 /uni0292 /uni0293 /uni0294 /uni0295 /uni0296 /uni0297 '+nl+ //90 +'/uni0298 /uni0299 /uni029A /uni029B /uni029C /uni029D /uni029E /uni029F '+nl+ //98 +'/uni02A0 /uni02A1 /uni02A2 /uni02A3 /uni02A4 /uni02A5 /uni02A6 /uni02A7 '+nl+ //A0 +'/uni02A8 /uni02A9 /uni02AA /uni02AB /uni02AC /uni02AD /uni02AE /uni02AF '+nl+ //A8 +'/uni02B0 /uni02B1 /uni02B2 /uni02B3 /uni02B4 /uni02B5 /uni02B6 /uni02B7 '+nl+ //B0 +'/uni02B8 /uni02B9 /uni02BA /uni02BB /afii57929 /afii64937 /uni02BE /uni02BF '+nl+ //B8 +'/uni02C0 /uni02C1 /uni02C2 /uni02C3 /uni02C4 /uni02C5 /circumflex /caron '+nl+ //C0 +'/uni02C8 /uni02C9 /uni02CA /uni02CB /uni02CC /uni02CD /uni02CE /uni02CF '+nl+ //C8 +'/uni02D0 /uni02D1 /uni02D2 /uni02D3 /uni02D4 /uni02D5 /uni02D6 /uni02D7 '+nl+ //D0 +'/breve /dotaccent /ring /ogonek /tilde /hungarumlaut /uni02DE /uni02DF '+nl+ //D8 +'/uni02E0 /uni02E1 /uni02E2 /uni02E3 /uni02E4 /uni02E5 /uni02E6 /uni02E7 '+nl+ //E0 +'/uni02E8 /uni02E9 /uni02EA /uni02EB /uni02EC /uni02ED /uni02EE /uni02EF '+nl+ //E8 +'/uni02F0 /uni02F1 /uni02F2 /uni02F3 /uni02F4 /uni02F5 /uni02F6 /uni02F7 '+nl+ //F0 +'/uni02F8 /uni02F9 /uni02FA /uni02FB /uni02FC /uni02FD /uni02FE /uni02FF '+nl //F8 + ), + ( + codepage: $03; + name: 'E03'; //greek + glyphnames: +'/gravecomb /acutecomb /uni0302 /tildecomb /uni0304 /uni0305 /uni0306 /uni0307 '+nl+ //00 +'/uni0308 /hookabovecomb /uni030A /uni030B /uni030C /uni030D /uni030E /uni030F '+nl+ //08 +'/uni0310 /uni0311 /uni0312 /uni0313 /uni0314 /uni0315 /uni0316 /uni0317 '+nl+ //10 +'/uni0318 /uni0319 /uni031A /uni031B /uni031C /uni031D /uni031E /uni031F '+nl+ //18 +'/uni0320 /uni0321 /uni0322 /dotbelowcomb /uni0324 /uni0325 /uni0326 /uni0327 '+nl+ //20 +'/uni0328 /uni0329 /uni032A /uni032B /uni032C /uni032D /uni032E /uni032F '+nl+ //28 +'/uni0330 /uni0331 /uni0332 /uni0333 /uni0334 /uni0335 /uni0336 /uni0337 '+nl+ //30 +'/uni0338 /uni0339 /uni033A /uni033B /uni033C /uni033D /uni033E /uni033F '+nl+ //38 +'/uni0340 /uni0341 /uni0342 /uni0343 /uni0344 /uni0345 /uni0346 /uni0347 '+nl+ //40 +'/uni0348 /uni0349 /uni034A /uni034B /uni034C /uni034D /uni034E /uni034F '+nl+ //48 +'/uni0350 /uni0351 /uni0352 /uni0353 /uni0354 /uni0355 /uni0356 /uni0357 '+nl+ //50 +'/uni0358 /uni0359 /uni035A /uni035B /uni035C /uni035D /uni035E /uni035F '+nl+ //58 +'/uni0360 /uni0361 /uni0362 /uni0363 /uni0364 /uni0365 /uni0366 /uni0367 '+nl+ //60 +'/uni0368 /uni0369 /uni036A /uni036B /uni036C /uni036D /uni036E /uni036F '+nl+ //68 +'/uni0370 /uni0371 /uni0372 /uni0373 /uni0374 /uni0375 /uni0376 /uni0377 '+nl+ //70 +'/uni0378 /uni0379 /uni037A /uni037B /uni037C /uni037D /uni037E /uni037F '+nl+ //78 +'/uni0380 /uni0381 /uni0382 /uni0383 /tonos /dieresistonos /Alphatonos /anoteleia '+nl+ //80 +'/Epsilontonos /Etatonos /Iotatonos /uni038B /Omicrontonos /uni038D /Upsilontonos /Omegatonos '+nl+ //88 +'/iotadieresistonos /Alpha /Beta /Gamma /Delta /Epsilon /Zeta /Eta '+nl+ //90 +'/Theta /Iota /Kappa /Lambda /Mu /Nu /Xi /Omicron '+nl+ //98 +'/Pi /Rho /uni03A2 /Sigma /Tau /Upsilon /Phi /Chi '+nl+ //A0 +'/Psi /Omega /Iotadieresis /Upsilondieresis /alphatonos /epsilontonos /etatonos /iotatonos '+nl+ //A8 +'/upsilondieresistonos /alpha /beta /gamma /delta /epsilon /zeta /eta '+nl+ //B0 +'/theta /iota /kappa /lambda /mu /nu /xi /omicron '+nl+ //B8 +'/pi /rho /sigma1 /sigma /tau /upsilon /phi /chi '+nl+ //C0 +'/psi /omega /iotadieresis /upsilondieresis /omicrontonos /upsilontonos /omegatonos /uni03CF '+nl+ //C8 +'/uni03D0 /theta1 /Upsilon1 /uni03D3 /uni03D4 /phi1 /omega1 /uni03D7 '+nl+ //D0 +'/uni03D8 /uni03D9 /uni03DA /uni03DB /uni03DC /uni03DD /uni03DE /uni03DF '+nl+ //D8 +'/uni03E0 /uni03E1 /uni03E2 /uni03E3 /uni03E4 /uni03E5 /uni03E6 /uni03E7 '+nl+ //E0 +'/uni03E8 /uni03E9 /uni03EA /uni03EB /uni03EC /uni03ED /uni03EE /uni03EF '+nl+ //E8 +'/uni03F0 /uni03F1 /uni03F2 /uni03F3 /uni03F4 /uni03F5 /uni03F6 /uni03F7 '+nl+ //F0 +'/uni03F8 /uni03F9 /uni03FA /uni03FB /uni03FC /uni03FD /uni03FE /uni03FF '+nl //F8 + ), + ( + codepage: $04; + name: 'E04'; //cyrillic + glyphnames: +'/uni0400 /afii10023 /afii10051 /afii10052 /afii10053 /afii10054 /afii10055 /afii10056 '+nl+ //00 +'/afii10057 /afii10058 /afii10059 /afii10060 /afii10061 /uni040D /afii10062 /afii10145 '+nl+ //08 +'/afii10017 /afii10018 /afii10019 /afii10020 /afii10021 /afii10022 /afii10024 /afii10025 '+nl+ //10 +'/afii10026 /afii10027 /afii10028 /afii10029 /afii10030 /afii10031 /afii10032 /afii10033 '+nl+ //18 +'/afii10034 /afii10035 /afii10036 /afii10037 /afii10038 /afii10039 /afii10040 /afii10041 '+nl+ //20 +'/afii10042 /afii10043 /afii10044 /afii10045 /afii10046 /afii10047 /afii10048 /afii10049 '+nl+ //28 +'/afii10065 /afii10066 /afii10067 /afii10068 /afii10069 /afii10070 /afii10072 /afii10073 '+nl+ //30 +'/afii10074 /afii10075 /afii10076 /afii10077 /afii10078 /afii10079 /afii10080 /afii10081 '+nl+ //38 +'/afii10082 /afii10083 /afii10084 /afii10085 /afii10086 /afii10087 /afii10088 /afii10089 '+nl+ //40 +'/afii10090 /afii10091 /afii10092 /afii10093 /afii10094 /afii10095 /afii10096 /afii10097 '+nl+ //48 +'/uni0450 /afii10071 /afii10099 /afii10100 /afii10101 /afii10102 /afii10103 /afii10104 '+nl+ //50 +'/afii10105 /afii10106 /afii10107 /afii10108 /afii10109 /uni045D /afii10110 /afii10193 '+nl+ //58 +'/uni0460 /uni0461 /afii10146 /afii10194 /uni0464 /uni0465 /uni0466 /uni0467 '+nl+ //60 +'/uni0468 /uni0469 /uni046A /uni046B /uni046C /uni046D /uni046E /uni046F '+nl+ //68 +'/uni0470 /uni0471 /afii10147 /afii10195 /afii10148 /afii10196 /uni0476 /uni0477 '+nl+ //70 +'/uni0478 /uni0479 /uni047A /uni047B /uni047C /uni047D /uni047E /uni047F '+nl+ //78 +'/uni0480 /uni0481 /uni0482 /uni0483 /uni0484 /uni0485 /uni0486 /uni0487 '+nl+ //80 +'/uni0488 /uni0489 /uni048A /uni048B /uni048C /uni048D /uni048E /uni048F '+nl+ //88 +'/afii10050 /afii10098 /uni0492 /uni0493 /uni0494 /uni0495 /uni0496 /uni0497 '+nl+ //90 +'/uni0498 /uni0499 /uni049A /uni049B /uni049C /uni049D /uni049E /uni049F '+nl+ //98 +'/uni04A0 /uni04A1 /uni04A2 /uni04A3 /uni04A4 /uni04A5 /uni04A6 /uni04A7 '+nl+ //A0 +'/uni04A8 /uni04A9 /uni04AA /uni04AB /uni04AC /uni04AD /uni04AE /uni04AF '+nl+ //A8 +'/uni04B0 /uni04B1 /uni04B2 /uni04B3 /uni04B4 /uni04B5 /uni04B6 /uni04B7 '+nl+ //B0 +'/uni04B8 /uni04B9 /uni04BA /uni04BB /uni04BC /uni04BD /uni04BE /uni04BF '+nl+ //B8 +'/uni04C0 /uni04C1 /uni04C2 /uni04C3 /uni04C4 /uni04C5 /uni04C6 /uni04C7 '+nl+ //C0 +'/uni04C8 /uni04C9 /uni04CA /uni04CB /uni04CC /uni04CD /uni04CE /uni04CF '+nl+ //C8 +'/uni04D0 /uni04D1 /uni04D2 /uni04D3 /uni04D4 /uni04D5 /uni04D6 /uni04D7 '+nl+ //D0 +'/uni04D8 /afii10846 /uni04DA /uni04DB /uni04DC /uni04DD /uni04DE /uni04DF '+nl+ //D8 +'/uni04E0 /uni04E1 /uni04E2 /uni04E3 /uni04E4 /uni04E5 /uni04E6 /uni04E7 '+nl+ //E0 +'/uni04E8 /uni04E9 /uni04EA /uni04EB /uni04EC /uni04ED /uni04EE /uni04EF '+nl+ //E8 +'/uni04F0 /uni04F1 /uni04F2 /uni04F3 /uni04F4 /uni04F5 /uni04F6 /uni04F7 '+nl+ //F0 +'/uni04F8 /uni04F9 /uni04FA /uni04FB /uni04FC /uni04FD /uni04FE /uni04FF '+nl //F8 + ), + ( + codepage: $05; + name: 'E05'; //cyrillic supplement + glyphnames: +'/uni0500 /uni0501 /uni0502 /uni0503 /uni0504 /uni0505 /uni0506 /uni0507 '+nl+ //00 +'/uni0508 /uni0509 /uni050A /uni050B /uni050C /uni050D /uni050E /uni050F '+nl+ //08 +'/uni0510 /uni0511 /uni0512 /uni0513 /uni0514 /uni0515 /uni0516 /uni0517 '+nl+ //10 +'/uni0518 /uni0519 /uni051A /uni051B /uni051C /uni051D /uni051E /uni051F '+nl+ //18 +'/uni0520 /uni0521 /uni0522 /uni0523 /uni0524 /uni0525 /uni0526 /uni0527 '+nl+ //20 +'/uni0528 /uni0529 /uni052A /uni052B /uni052C /uni052D /uni052E /uni052F '+nl+ //28 +'/uni0530 /uni0531 /uni0532 /uni0533 /uni0534 /uni0535 /uni0536 /uni0537 '+nl+ //30 +'/uni0538 /uni0539 /uni053A /uni053B /uni053C /uni053D /uni053E /uni053F '+nl+ //38 +'/uni0540 /uni0541 /uni0542 /uni0543 /uni0544 /uni0545 /uni0546 /uni0547 '+nl+ //40 +'/uni0548 /uni0549 /uni054A /uni054B /uni054C /uni054D /uni054E /uni054F '+nl+ //48 +'/uni0550 /uni0551 /uni0552 /uni0553 /uni0554 /uni0555 /uni0556 /uni0557 '+nl+ //50 +'/uni0558 /uni0559 /uni055A /uni055B /uni055C /uni055D /uni055E /uni055F '+nl+ //58 +'/uni0560 /uni0561 /uni0562 /uni0563 /uni0564 /uni0565 /uni0566 /uni0567 '+nl+ //60 +'/uni0568 /uni0569 /uni056A /uni056B /uni056C /uni056D /uni056E /uni056F '+nl+ //68 +'/uni0570 /uni0571 /uni0572 /uni0573 /uni0574 /uni0575 /uni0576 /uni0577 '+nl+ //70 +'/uni0578 /uni0579 /uni057A /uni057B /uni057C /uni057D /uni057E /uni057F '+nl+ //78 +'/uni0580 /uni0581 /uni0582 /uni0583 /uni0584 /uni0585 /uni0586 /uni0587 '+nl+ //80 +'/uni0588 /uni0589 /uni058A /uni058B /uni058C /uni058D /uni058E /uni058F '+nl+ //88 +'/uni0590 /uni0591 /uni0592 /uni0593 /uni0594 /uni0595 /uni0596 /uni0597 '+nl+ //90 +'/uni0598 /uni0599 /uni059A /uni059B /uni059C /uni059D /uni059E /uni059F '+nl+ //98 +'/uni05A0 /uni05A1 /uni05A2 /uni05A3 /uni05A4 /uni05A5 /uni05A6 /uni05A7 '+nl+ //A0 +'/uni05A8 /uni05A9 /uni05AA /uni05AB /uni05AC /uni05AD /uni05AE /uni05AF '+nl+ //A8 +'/afii57799 /afii57801 /afii57800 /afii57802 /afii57793 /afii57794 /afii57795 /afii57798 '+nl+ //B0 +'/afii57797 /afii57806 /uni05BA /afii57796 /afii57807 /afii57839 /afii57645 /afii57841 '+nl+ //B8 +'/afii57842 /afii57804 /afii57803 /afii57658 /uni05C4 /uni05C5 /uni05C6 /uni05C7 '+nl+ //C0 +'/uni05C8 /uni05C9 /uni05CA /uni05CB /uni05CC /uni05CD /uni05CE /uni05CF '+nl+ //C8 +'/afii57664 /afii57665 /afii57666 /afii57667 /afii57668 /afii57669 /afii57670 /afii57671 '+nl+ //D0 +'/afii57672 /afii57673 /afii57674 /afii57675 /afii57676 /afii57677 /afii57678 /afii57679 '+nl+ //D8 +'/afii57680 /afii57681 /afii57682 /afii57683 /afii57684 /afii57685 /afii57686 /afii57687 '+nl+ //E0 +'/afii57688 /afii57689 /afii57690 /uni05EB /uni05EC /uni05ED /uni05EE /uni05EF '+nl+ //E8 +'/afii57716 /afii57717 /afii57718 /uni05F3 /uni05F4 /uni05F5 /uni05F6 /uni05F7 '+nl+ //F0 +'/uni05F8 /uni05F9 /uni05FA /uni05FB /uni05FC /uni05FD /uni05FE /uni05FF '+nl //F8 + ), + ( + codepage: $06; + name: 'E06'; //arabic + glyphnames: +'/uni0600 /uni0601 /uni0602 /uni0603 /uni0604 /uni0605 /uni0606 /uni0607 '+nl+ //00 +'/uni0608 /uni0609 /uni060A /uni060B /afii57388 /uni060D /uni060E /uni060F '+nl+ //08 +'/uni0610 /uni0611 /uni0612 /uni0613 /uni0614 /uni0615 /uni0616 /uni0617 '+nl+ //10 +'/uni0618 /uni0619 /uni061A /afii57403 /uni061C /uni061D /uni061E /afii57407 '+nl+ //18 +'/uni0620 /afii57409 /afii57410 /afii57411 /afii57412 /afii57413 /afii57414 /afii57415 '+nl+ //20 +'/afii57416 /afii57417 /afii57418 /afii57419 /afii57420 /afii57421 /afii57422 /afii57423 '+nl+ //28 +'/afii57424 /afii57425 /afii57426 /afii57427 /afii57428 /afii57429 /afii57430 /afii57431 '+nl+ //30 +'/afii57432 /afii57433 /afii57434 /uni063B /uni063C /uni063D /uni063E /uni063F '+nl+ //38 +'/afii57440 /afii57441 /afii57442 /afii57443 /afii57444 /afii57445 /afii57446 /afii57470 '+nl+ //40 +'/afii57448 /afii57449 /afii57450 /afii57451 /afii57452 /afii57453 /afii57454 /afii57455 '+nl+ //48 +'/afii57456 /afii57457 /afii57458 /uni0653 /uni0654 /uni0655 /uni0656 /uni0657 '+nl+ //50 +'/uni0658 /uni0659 /uni065A /uni065B /uni065C /uni065D /uni065E /uni065F '+nl+ //58 +'/afii57392 /afii57393 /afii57394 /afii57395 /afii57396 /afii57397 /afii57398 /afii57399 '+nl+ //60 +'/afii57400 /afii57401 /afii57381 /uni066B /uni066C /afii63167 /uni066E /uni066F '+nl+ //68 +'/uni0670 /uni0671 /uni0672 /uni0673 /uni0674 /uni0675 /uni0676 /uni0677 '+nl+ //70 +'/uni0678 /afii57511 /uni067A /uni067B /uni067C /uni067D /afii57506 /uni067F '+nl+ //78 +'/uni0680 /uni0681 /uni0682 /uni0683 /uni0684 /uni0685 /afii57507 /uni0687 '+nl+ //80 +'/afii57512 /uni0689 /uni068A /uni068B /uni068C /uni068D /uni068E /uni068F '+nl+ //88 +'/uni0690 /afii57513 /uni0692 /uni0693 /uni0694 /uni0695 /uni0696 /uni0697 '+nl+ //90 +'/afii57508 /uni0699 /uni069A /uni069B /uni069C /uni069D /uni069E /uni069F '+nl+ //98 +'/uni06A0 /uni06A1 /uni06A2 /uni06A3 /afii57505 /uni06A5 /uni06A6 /uni06A7 '+nl+ //A0 +'/uni06A8 /uni06A9 /uni06AA /uni06AB /uni06AC /uni06AD /uni06AE /afii57509 '+nl+ //A8 +'/uni06B0 /uni06B1 /uni06B2 /uni06B3 /uni06B4 /uni06B5 /uni06B6 /uni06B7 '+nl+ //B0 +'/uni06B8 /uni06B9 /afii57514 /uni06BB /uni06BC /uni06BD /uni06BE /uni06BF '+nl+ //B8 +'/uni06C0 /uni06C1 /uni06C2 /uni06C3 /uni06C4 /uni06C5 /uni06C6 /uni06C7 '+nl+ //C0 +'/uni06C8 /uni06C9 /uni06CA /uni06CB /uni06CC /uni06CD /uni06CE /uni06CF '+nl+ //C8 +'/uni06D0 /uni06D1 /afii57519 /uni06D3 /uni06D4 /afii57534 /uni06D6 /uni06D7 '+nl+ //D0 +'/uni06D8 /uni06D9 /uni06DA /uni06DB /uni06DC /uni06DD /uni06DE /uni06DF '+nl+ //D8 +'/uni06E0 /uni06E1 /uni06E2 /uni06E3 /uni06E4 /uni06E5 /uni06E6 /uni06E7 '+nl+ //E0 +'/uni06E8 /uni06E9 /uni06EA /uni06EB /uni06EC /uni06ED /uni06EE /uni06EF '+nl+ //E8 +'/uni06F0 /uni06F1 /uni06F2 /uni06F3 /uni06F4 /uni06F5 /uni06F6 /uni06F7 '+nl+ //F0 +'/uni06F8 /uni06F9 /uni06FA /uni06FB /uni06FC /uni06FD /uni06FE /uni06FF '+nl //F8 + ), + ( + codepage: $1E; + name: 'E1E'; //latin extended additional + glyphnames: +'/uni1E00 /uni1E01 /uni1E02 /uni1E03 /uni1E04 /uni1E05 /uni1E06 /uni1E07 '+nl+ //00 +'/uni1E08 /uni1E09 /uni1E0A /uni1E0B /uni1E0C /uni1E0D /uni1E0E /uni1E0F '+nl+ //08 +'/uni1E10 /uni1E11 /uni1E12 /uni1E13 /uni1E14 /uni1E15 /uni1E16 /uni1E17 '+nl+ //10 +'/uni1E18 /uni1E19 /uni1E1A /uni1E1B /uni1E1C /uni1E1D /uni1E1E /uni1E1F '+nl+ //18 +'/uni1E20 /uni1E21 /uni1E22 /uni1E23 /uni1E24 /uni1E25 /uni1E26 /uni1E27 '+nl+ //20 +'/uni1E28 /uni1E29 /uni1E2A /uni1E2B /uni1E2C /uni1E2D /uni1E2E /uni1E2F '+nl+ //28 +'/uni1E30 /uni1E31 /uni1E32 /uni1E33 /uni1E34 /uni1E35 /uni1E36 /uni1E37 '+nl+ //30 +'/uni1E38 /uni1E39 /uni1E3A /uni1E3B /uni1E3C /uni1E3D /uni1E3E /uni1E3F '+nl+ //38 +'/uni1E40 /uni1E41 /uni1E42 /uni1E43 /uni1E44 /uni1E45 /uni1E46 /uni1E47 '+nl+ //40 +'/uni1E48 /uni1E49 /uni1E4A /uni1E4B /uni1E4C /uni1E4D /uni1E4E /uni1E4F '+nl+ //48 +'/uni1E50 /uni1E51 /uni1E52 /uni1E53 /uni1E54 /uni1E55 /uni1E56 /uni1E57 '+nl+ //50 +'/uni1E58 /uni1E59 /uni1E5A /uni1E5B /uni1E5C /uni1E5D /uni1E5E /uni1E5F '+nl+ //58 +'/uni1E60 /uni1E61 /uni1E62 /uni1E63 /uni1E64 /uni1E65 /uni1E66 /uni1E67 '+nl+ //60 +'/uni1E68 /uni1E69 /uni1E6A /uni1E6B /uni1E6C /uni1E6D /uni1E6E /uni1E6F '+nl+ //68 +'/uni1E70 /uni1E71 /uni1E72 /uni1E73 /uni1E74 /uni1E75 /uni1E76 /uni1E77 '+nl+ //70 +'/uni1E78 /uni1E79 /uni1E7A /uni1E7B /uni1E7C /uni1E7D /uni1E7E /uni1E7F '+nl+ //78 +'/Wgrave /wgrave /Wacute /wacute /Wdieresis /wdieresis /uni1E86 /uni1E87 '+nl+ //80 +'/uni1E88 /uni1E89 /uni1E8A /uni1E8B /uni1E8C /uni1E8D /uni1E8E /uni1E8F '+nl+ //88 +'/uni1E90 /uni1E91 /uni1E92 /uni1E93 /uni1E94 /uni1E95 /uni1E96 /uni1E97 '+nl+ //90 +'/uni1E98 /uni1E99 /uni1E9A /uni1E9B /uni1E9C /uni1E9D /uni1E9E /uni1E9F '+nl+ //98 +'/uni1EA0 /uni1EA1 /uni1EA2 /uni1EA3 /uni1EA4 /uni1EA5 /uni1EA6 /uni1EA7 '+nl+ //A0 +'/uni1EA8 /uni1EA9 /uni1EAA /uni1EAB /uni1EAC /uni1EAD /uni1EAE /uni1EAF '+nl+ //A8 +'/uni1EB0 /uni1EB1 /uni1EB2 /uni1EB3 /uni1EB4 /uni1EB5 /uni1EB6 /uni1EB7 '+nl+ //B0 +'/uni1EB8 /uni1EB9 /uni1EBA /uni1EBB /uni1EBC /uni1EBD /uni1EBE /uni1EBF '+nl+ //B8 +'/uni1EC0 /uni1EC1 /uni1EC2 /uni1EC3 /uni1EC4 /uni1EC5 /uni1EC6 /uni1EC7 '+nl+ //C0 +'/uni1EC8 /uni1EC9 /uni1ECA /uni1ECB /uni1ECC /uni1ECD /uni1ECE /uni1ECF '+nl+ //C8 +'/uni1ED0 /uni1ED1 /uni1ED2 /uni1ED3 /uni1ED4 /uni1ED5 /uni1ED6 /uni1ED7 '+nl+ //D0 +'/uni1ED8 /uni1ED9 /uni1EDA /uni1EDB /uni1EDC /uni1EDD /uni1EDE /uni1EDF '+nl+ //D8 +'/uni1EE0 /uni1EE1 /uni1EE2 /uni1EE3 /uni1EE4 /uni1EE5 /uni1EE6 /uni1EE7 '+nl+ //E0 +'/uni1EE8 /uni1EE9 /uni1EEA /uni1EEB /uni1EEC /uni1EED /uni1EEE /uni1EEF '+nl+ //E8 +'/uni1EF0 /uni1EF1 /Ygrave /ygrave /uni1EF4 /uni1EF5 /uni1EF6 /uni1EF7 '+nl+ //F0 +'/uni1EF8 /uni1EF9 /uni1EFA /uni1EFB /uni1EFC /uni1EFD /uni1EFE /uni1EFF '+nl //F8 + ), + ( + codepage: $20; + name: 'E20'; //punctuation, currency + glyphnames: +'/uni2000 /uni2001 /uni2002 /uni2003 /uni2004 /uni2005 /uni2006 /uni2007 '+nl+ //00 +'/uni2008 /uni2009 /uni200A /uni200B /afii61664 /afii301 /afii299 /afii300 '+nl+ //08 +'/uni2010 /uni2011 /figuredash /endash /emdash /afii00208 /uni2016 /underscoredbl '+nl+ //10 +'/quoteleft /quoteright /quotesinglbase /quotereversed /quotedblleft /quotedblright /quotedblbase /uni201F '+nl+ //18 +'/dagger /daggerdbl /bullet /uni2023 /onedotenleader /twodotenleader /ellipsis /uni2027 '+nl+ //20 +'/uni2028 /uni2029 /uni202A /uni202B /afii61573 /afii61574 /afii61575 /uni202F '+nl+ //28 +'/perthousand /uni2031 /minute /second /uni2034 /uni2035 /uni2036 /uni2037 '+nl+ //30 +'/uni2038 /guilsinglleft /guilsinglright /uni203B /exclamdbl /uni203D /uni203E /uni203F '+nl+ //38 +'/uni2040 /uni2041 /uni2042 /uni2043 /fraction /uni2045 /uni2046 /uni2047 '+nl+ //40 +'/uni2048 /uni2049 /uni204A /uni204B /uni204C /uni204D /uni204E /uni204F '+nl+ //48 +'/uni2050 /uni2051 /uni2052 /uni2053 /uni2054 /uni2055 /uni2056 /uni2057 '+nl+ //50 +'/uni2058 /uni2059 /uni205A /uni205B /uni205C /uni205D /uni205E /uni205F '+nl+ //58 +'/uni2060 /uni2061 /uni2062 /uni2063 /uni2064 /uni2065 /uni2066 /uni2067 '+nl+ //60 +'/uni2068 /uni2069 /uni206A /uni206B /uni206C /uni206D /uni206E /uni206F '+nl+ //68 +'/uni2070 /uni2071 /uni2072 /uni2073 /uni2074 /uni2075 /uni2076 /uni2077 '+nl+ //70 +'/uni2078 /uni2079 /uni207A /uni207B /uni207C /uni207D /uni207E /uni207F '+nl+ //78 +'/uni2080 /uni2081 /uni2082 /uni2083 /uni2084 /uni2085 /uni2086 /uni2087 '+nl+ //80 +'/uni2088 /uni2089 /uni208A /uni208B /uni208C /uni208D /uni208E /uni208F '+nl+ //88 +'/uni2090 /uni2091 /uni2092 /uni2093 /uni2094 /uni2095 /uni2096 /uni2097 '+nl+ //90 +'/uni2098 /uni2099 /uni209A /uni209B /uni209C /uni209D /uni209E /uni209F '+nl+ //98 +'/uni20A0 /colonmonetary /uni20A2 /franc /lira /uni20A5 /uni20A6 /peseta '+nl+ //A0 +'/uni20A8 /uni20A9 /afii57636 /dong /Euro /uni20AD /uni20AE /uni20AF '+nl+ //A8 +'/uni20B0 /uni20B1 /uni20B2 /uni20B3 /uni20B4 /uni20B5 /uni20B6 /uni20B7 '+nl+ //B0 +'/uni20B8 /uni20B9 /uni20BA /uni20BB /uni20BC /uni20BD /uni20BE /uni20BF '+nl+ //B8 +'/uni20C0 /uni20C1 /uni20C2 /uni20C3 /uni20C4 /uni20C5 /uni20C6 /uni20C7 '+nl+ //C0 +'/uni20C8 /uni20C9 /uni20CA /uni20CB /uni20CC /uni20CD /uni20CE /uni20CF '+nl+ //C8 +'/uni20D0 /uni20D1 /uni20D2 /uni20D3 /uni20D4 /uni20D5 /uni20D6 /uni20D7 '+nl+ //D0 +'/uni20D8 /uni20D9 /uni20DA /uni20DB /uni20DC /uni20DD /uni20DE /uni20DF '+nl+ //D8 +'/uni20E0 /uni20E1 /uni20E2 /uni20E3 /uni20E4 /uni20E5 /uni20E6 /uni20E7 '+nl+ //E0 +'/uni20E8 /uni20E9 /uni20EA /uni20EB /uni20EC /uni20ED /uni20EE /uni20EF '+nl+ //E8 +'/uni20F0 /uni20F1 /uni20F2 /uni20F3 /uni20F4 /uni20F5 /uni20F6 /uni20F7 '+nl+ //F0 +'/uni20F8 /uni20F9 /uni20FA /uni20FB /uni20FC /uni20FD /uni20FE /uni20FF '+nl //F8 + ), + ( + codepage: $21; + name: 'E21'; //letterlike symbols + glyphnames: +'/uni2100 /uni2101 /uni2102 /uni2103 /uni2104 /afii61248 /uni2106 /uni2107 '+nl+ //00 +'/uni2108 /uni2109 /uni210A /uni210B /uni210C /uni210D /uni210E /uni210F '+nl+ //08 +'/uni2110 /Ifraktur /uni2112 /afii61289 /uni2114 /uni2115 /afii61352 /uni2117 '+nl+ //10 +'/weierstrass /uni2119 /uni211A /uni211B /Rfraktur /uni211D /prescription /uni211F '+nl+ //18 +'/uni2120 /uni2121 /trademark /uni2123 /uni2124 /uni2125 /uni2126 /uni2127 '+nl+ //20 +'/uni2128 /uni2129 /uni212A /uni212B /uni212C /uni212D /estimated /uni212F '+nl+ //28 +'/uni2130 /uni2131 /uni2132 /uni2133 /uni2134 /aleph /uni2136 /uni2137 '+nl+ //30 +'/uni2138 /uni2139 /uni213A /uni213B /uni213C /uni213D /uni213E /uni213F '+nl+ //38 +'/uni2140 /uni2141 /uni2142 /uni2143 /uni2144 /uni2145 /uni2146 /uni2147 '+nl+ //40 +'/uni2148 /uni2149 /uni214A /uni214B /uni214C /uni214D /uni214E /uni214F '+nl+ //48 +'/uni2150 /uni2151 /uni2152 /onethird /twothirds /uni2155 /uni2156 /uni2157 '+nl+ //50 +'/uni2158 /uni2159 /uni215A /oneeighth /threeeighths /fiveeighths /seveneighths /uni215F '+nl+ //58 +'/uni2160 /uni2161 /uni2162 /uni2163 /uni2164 /uni2165 /uni2166 /uni2167 '+nl+ //60 +'/uni2168 /uni2169 /uni216A /uni216B /uni216C /uni216D /uni216E /uni216F '+nl+ //68 +'/uni2170 /uni2171 /uni2172 /uni2173 /uni2174 /uni2175 /uni2176 /uni2177 '+nl+ //70 +'/uni2178 /uni2179 /uni217A /uni217B /uni217C /uni217D /uni217E /uni217F '+nl+ //78 +'/uni2180 /uni2181 /uni2182 /uni2183 /uni2184 /uni2185 /uni2186 /uni2187 '+nl+ //80 +'/uni2188 /uni2189 /uni218A /uni218B /uni218C /uni218D /uni218E /uni218F '+nl+ //88 +'/arrowleft /arrowup /arrowright /arrowdown /arrowboth /arrowupdn /uni2196 /uni2197 '+nl+ //90 +'/uni2198 /uni2199 /uni219A /uni219B /uni219C /uni219D /uni219E /uni219F '+nl+ //98 +'/uni21A0 /uni21A1 /uni21A2 /uni21A3 /uni21A4 /uni21A5 /uni21A6 /uni21A7 '+nl+ //A0 +'/arrowupdnbse /uni21A9 /uni21AA /uni21AB /uni21AC /uni21AD /uni21AE /uni21AF '+nl+ //A8 +'/uni21B0 /uni21B1 /uni21B2 /uni21B3 /uni21B4 /carriagereturn /uni21B6 /uni21B7 '+nl+ //B0 +'/uni21B8 /uni21B9 /uni21BA /uni21BB /uni21BC /uni21BD /uni21BE /uni21BF '+nl+ //B8 +'/uni21C0 /uni21C1 /uni21C2 /uni21C3 /uni21C4 /uni21C5 /uni21C6 /uni21C7 '+nl+ //C0 +'/uni21C8 /uni21C9 /uni21CA /uni21CB /uni21CC /uni21CD /uni21CE /uni21CF '+nl+ //C8 +'/arrowdblleft /arrowdblup /arrowdblright /arrowdbldown /arrowdblboth /uni21D5 /uni21D6 /uni21D7 '+nl+ //D0 +'/uni21D8 /uni21D9 /uni21DA /uni21DB /uni21DC /uni21DD /uni21DE /uni21DF '+nl+ //D8 +'/uni21E0 /uni21E1 /uni21E2 /uni21E3 /uni21E4 /uni21E5 /uni21E6 /uni21E7 '+nl+ //E0 +'/uni21E8 /uni21E9 /uni21EA /uni21EB /uni21EC /uni21ED /uni21EE /uni21EF '+nl+ //E8 +'/uni21F0 /uni21F1 /uni21F2 /uni21F3 /uni21F4 /uni21F5 /uni21F6 /uni21F7 '+nl+ //F0 +'/uni21F8 /uni21F9 /uni21FA /uni21FB /uni21FC /uni21FD /uni21FE /uni21FF '+nl //F8 + ), + ( + codepage: $22; + name: 'E22'; //mathematical operators + glyphnames: +'/universal /uni2201 /partialdiff /existential /uni2204 /emptyset /uni2206 /gradient '+nl+ //00 +'/element /notelement /uni220A /suchthat /uni220C /uni220D /uni220E /product '+nl+ //08 +'/uni2210 /summation /minus /uni2213 /uni2214 /uni2215 /uni2216 /asteriskmath '+nl+ //10 +'/uni2218 /uni2219 /radical /uni221B /uni221C /proportional /infinity /orthogonal '+nl+ //18 +'/angle /uni2221 /uni2222 /uni2223 /uni2224 /uni2225 /uni2226 /logicaland '+nl+ //20 +'/logicalor /intersection /union /integral /uni222C /uni222D /uni222E /uni222F '+nl+ //28 +'/uni2230 /uni2231 /uni2232 /uni2233 /therefore /uni2235 /uni2236 /uni2237 '+nl+ //30 +'/uni2238 /uni2239 /uni223A /uni223B /similar /uni223D /uni223E /uni223F '+nl+ //38 +'/uni2240 /uni2241 /uni2242 /uni2243 /uni2244 /congruent /uni2246 /uni2247 '+nl+ //40 +'/approxequal /uni2249 /uni224A /uni224B /uni224C /uni224D /uni224E /uni224F '+nl+ //48 +'/uni2250 /uni2251 /uni2252 /uni2253 /uni2254 /uni2255 /uni2256 /uni2257 '+nl+ //50 +'/uni2258 /uni2259 /uni225A /uni225B /uni225C /uni225D /uni225E /uni225F '+nl+ //58 +'/notequal /equivalence /uni2262 /uni2263 /lessequal /greaterequal /uni2266 /uni2267 '+nl+ //60 +'/uni2268 /uni2269 /uni226A /uni226B /uni226C /uni226D /uni226E /uni226F '+nl+ //68 +'/uni2270 /uni2271 /uni2272 /uni2273 /uni2274 /uni2275 /uni2276 /uni2277 '+nl+ //70 +'/uni2278 /uni2279 /uni227A /uni227B /uni227C /uni227D /uni227E /uni227F '+nl+ //78 +'/uni2280 /uni2281 /propersubset /propersuperset /notsubset /uni2285 /reflexsubset /reflexsuperset '+nl+ //80 +'/uni2288 /uni2289 /uni228A /uni228B /uni228C /uni228D /uni228E /uni228F '+nl+ //88 +'/uni2290 /uni2291 /uni2292 /uni2293 /uni2294 /circleplus /uni2296 /circlemultiply '+nl+ //90 +'/uni2298 /uni2299 /uni229A /uni229B /uni229C /uni229D /uni229E /uni229F '+nl+ //98 +'/uni22A0 /uni22A1 /uni22A2 /uni22A3 /uni22A4 /perpendicular /uni22A6 /uni22A7 '+nl+ //A0 +'/uni22A8 /uni22A9 /uni22AA /uni22AB /uni22AC /uni22AD /uni22AE /uni22AF '+nl+ //A8 +'/uni22B0 /uni22B1 /uni22B2 /uni22B3 /uni22B4 /uni22B5 /uni22B6 /uni22B7 '+nl+ //B0 +'/uni22B8 /uni22B9 /uni22BA /uni22BB /uni22BC /uni22BD /uni22BE /uni22BF '+nl+ //B8 +'/uni22C0 /uni22C1 /uni22C2 /uni22C3 /uni22C4 /dotmath /uni22C6 /uni22C7 '+nl+ //C0 +'/uni22C8 /uni22C9 /uni22CA /uni22CB /uni22CC /uni22CD /uni22CE /uni22CF '+nl+ //C8 +'/uni22D0 /uni22D1 /uni22D2 /uni22D3 /uni22D4 /uni22D5 /uni22D6 /uni22D7 '+nl+ //D0 +'/uni22D8 /uni22D9 /uni22DA /uni22DB /uni22DC /uni22DD /uni22DE /uni22DF '+nl+ //D8 +'/uni22E0 /uni22E1 /uni22E2 /uni22E3 /uni22E4 /uni22E5 /uni22E6 /uni22E7 '+nl+ //E0 +'/uni22E8 /uni22E9 /uni22EA /uni22EB /uni22EC /uni22ED /uni22EE /uni22EF '+nl+ //E8 +'/uni22F0 /uni22F1 /uni22F2 /uni22F3 /uni22F4 /uni22F5 /uni22F6 /uni22F7 '+nl+ //F0 +'/uni22F8 /uni22F9 /uni22FA /uni22FB /uni22FC /uni22FD /uni22FE /uni22FF '+nl //F8 + ), + ( + codepage: $23; + name: 'E23'; //technical symbols + glyphnames: +'/uni2300 /uni2301 /house /uni2303 /uni2304 /uni2305 /uni2306 /uni2307 '+nl+ //00 +'/uni2308 /uni2309 /uni230A /uni230B /uni230C /uni230D /uni230E /uni230F '+nl+ //08 +'/revlogicalnot /uni2311 /uni2312 /uni2313 /uni2314 /uni2315 /uni2316 /uni2317 '+nl+ //10 +'/uni2318 /uni2319 /uni231A /uni231B /uni231C /uni231D /uni231E /uni231F '+nl+ //18 +'/integraltp /integralbt /uni2322 /uni2323 /uni2324 /uni2325 /uni2326 /uni2327 '+nl+ //20 +'/uni2328 /angleleft /angleright /uni232B /uni232C /uni232D /uni232E /uni232F '+nl+ //28 +'/uni2330 /uni2331 /uni2332 /uni2333 /uni2334 /uni2335 /uni2336 /uni2337 '+nl+ //30 +'/uni2338 /uni2339 /uni233A /uni233B /uni233C /uni233D /uni233E /uni233F '+nl+ //38 +'/uni2340 /uni2341 /uni2342 /uni2343 /uni2344 /uni2345 /uni2346 /uni2347 '+nl+ //40 +'/uni2348 /uni2349 /uni234A /uni234B /uni234C /uni234D /uni234E /uni234F '+nl+ //48 +'/uni2350 /uni2351 /uni2352 /uni2353 /uni2354 /uni2355 /uni2356 /uni2357 '+nl+ //50 +'/uni2358 /uni2359 /uni235A /uni235B /uni235C /uni235D /uni235E /uni235F '+nl+ //58 +'/uni2360 /uni2361 /uni2362 /uni2363 /uni2364 /uni2365 /uni2366 /uni2367 '+nl+ //60 +'/uni2368 /uni2369 /uni236A /uni236B /uni236C /uni236D /uni236E /uni236F '+nl+ //68 +'/uni2370 /uni2371 /uni2372 /uni2373 /uni2374 /uni2375 /uni2376 /uni2377 '+nl+ //70 +'/uni2378 /uni2379 /uni237A /uni237B /uni237C /uni237D /uni237E /uni237F '+nl+ //78 +'/uni2380 /uni2381 /uni2382 /uni2383 /uni2384 /uni2385 /uni2386 /uni2387 '+nl+ //80 +'/uni2388 /uni2389 /uni238A /uni238B /uni238C /uni238D /uni238E /uni238F '+nl+ //88 +'/uni2390 /uni2391 /uni2392 /uni2393 /uni2394 /uni2395 /uni2396 /uni2397 '+nl+ //90 +'/uni2398 /uni2399 /uni239A /uni239B /uni239C /uni239D /uni239E /uni239F '+nl+ //98 +'/uni23A0 /uni23A1 /uni23A2 /uni23A3 /uni23A4 /uni23A5 /uni23A6 /uni23A7 '+nl+ //A0 +'/uni23A8 /uni23A9 /uni23AA /uni23AB /uni23AC /uni23AD /uni23AE /uni23AF '+nl+ //A8 +'/uni23B0 /uni23B1 /uni23B2 /uni23B3 /uni23B4 /uni23B5 /uni23B6 /uni23B7 '+nl+ //B0 +'/uni23B8 /uni23B9 /uni23BA /uni23BB /uni23BC /uni23BD /uni23BE /uni23BF '+nl+ //B8 +'/uni23C0 /uni23C1 /uni23C2 /uni23C3 /uni23C4 /uni23C5 /uni23C6 /uni23C7 '+nl+ //C0 +'/uni23C8 /uni23C9 /uni23CA /uni23CB /uni23CC /uni23CD /uni23CE /uni23CF '+nl+ //C8 +'/uni23D0 /uni23D1 /uni23D2 /uni23D3 /uni23D4 /uni23D5 /uni23D6 /uni23D7 '+nl+ //D0 +'/uni23D8 /uni23D9 /uni23DA /uni23DB /uni23DC /uni23DD /uni23DE /uni23DF '+nl+ //D8 +'/uni23E0 /uni23E1 /uni23E2 /uni23E3 /uni23E4 /uni23E5 /uni23E6 /uni23E7 '+nl+ //E0 +'/uni23E8 /uni23E9 /uni23EA /uni23EB /uni23EC /uni23ED /uni23EE /uni23EF '+nl+ //E8 +'/uni23F0 /uni23F1 /uni23F2 /uni23F3 /uni23F4 /uni23F5 /uni23F6 /uni23F7 '+nl+ //F0 +'/uni23F8 /uni23F9 /uni23FA /uni23FB /uni23FC /uni23FD /uni23FE /uni23FF '+nl //F8 + ), + ( + codepage: $25; + name: 'E25'; //box drawing + glyphnames: +'/SF100000 /uni2501 /SF110000 /uni2503 /uni2504 /uni2505 /uni2506 /uni2507 '+nl+ //00 +'/uni2508 /uni2509 /uni250A /uni250B /SF010000 /uni250D /uni250E /uni250F '+nl+ //08 +'/SF030000 /uni2511 /uni2512 /uni2513 /SF020000 /uni2515 /uni2516 /uni2517 '+nl+ //10 +'/SF040000 /uni2519 /uni251A /uni251B /SF080000 /uni251D /uni251E /uni251F '+nl+ //18 +'/uni2520 /uni2521 /uni2522 /uni2523 /SF090000 /uni2525 /uni2526 /uni2527 '+nl+ //20 +'/uni2528 /uni2529 /uni252A /uni252B /SF060000 /uni252D /uni252E /uni252F '+nl+ //28 +'/uni2530 /uni2531 /uni2532 /uni2533 /SF070000 /uni2535 /uni2536 /uni2537 '+nl+ //30 +'/uni2538 /uni2539 /uni253A /uni253B /SF050000 /uni253D /uni253E /uni253F '+nl+ //38 +'/uni2540 /uni2541 /uni2542 /uni2543 /uni2544 /uni2545 /uni2546 /uni2547 '+nl+ //40 +'/uni2548 /uni2549 /uni254A /uni254B /uni254C /uni254D /uni254E /uni254F '+nl+ //48 +'/SF430000 /SF240000 /SF510000 /SF520000 /SF390000 /SF220000 /SF210000 /SF250000 '+nl+ //50 +'/SF500000 /SF490000 /SF380000 /SF280000 /SF270000 /SF260000 /SF360000 /SF370000 '+nl+ //58 +'/SF420000 /SF190000 /SF200000 /SF230000 /SF470000 /SF480000 /SF410000 /SF450000 '+nl+ //60 +'/SF460000 /SF400000 /SF540000 /SF530000 /SF440000 /uni256D /uni256E /uni256F '+nl+ //68 +'/uni2570 /uni2571 /uni2572 /uni2573 /uni2574 /uni2575 /uni2576 /uni2577 '+nl+ //70 +'/uni2578 /uni2579 /uni257A /uni257B /uni257C /uni257D /uni257E /uni257F '+nl+ //78 +'/upblock /uni2581 /uni2582 /uni2583 /dnblock /uni2585 /uni2586 /uni2587 '+nl+ //80 +'/block /uni2589 /uni258A /uni258B /lfblock /uni258D /uni258E /uni258F '+nl+ //88 +'/rtblock /ltshade /shade /dkshade /uni2594 /uni2595 /uni2596 /uni2597 '+nl+ //90 +'/uni2598 /uni2599 /uni259A /uni259B /uni259C /uni259D /uni259E /uni259F '+nl+ //98 +'/filledbox /H22073 /uni25A2 /uni25A3 /uni25A4 /uni25A5 /uni25A6 /uni25A7 '+nl+ //A0 +'/uni25A8 /uni25A9 /H18543 /H18551 /filledrect /uni25AD /uni25AE /uni25AF '+nl+ //A8 +'/uni25B0 /uni25B1 /triagup /uni25B3 /uni25B4 /uni25B5 /uni25B6 /uni25B7 '+nl+ //B0 +'/uni25B8 /uni25B9 /triagrt /uni25BB /triagdn /uni25BD /uni25BE /uni25BF '+nl+ //B8 +'/uni25C0 /uni25C1 /uni25C2 /uni25C3 /triaglf /uni25C5 /uni25C6 /uni25C7 '+nl+ //C0 +'/uni25C8 /uni25C9 /lozenge /circle /uni25CC /uni25CD /uni25CE /H18533 '+nl+ //C8 +'/uni25D0 /uni25D1 /uni25D2 /uni25D3 /uni25D4 /uni25D5 /uni25D6 /uni25D7 '+nl+ //D0 +'/invbullet /invcircle /uni25DA /uni25DB /uni25DC /uni25DD /uni25DE /uni25DF '+nl+ //D8 +'/uni25E0 /uni25E1 /uni25E2 /uni25E3 /uni25E4 /uni25E5 /openbullet /uni25E7 '+nl+ //E0 +'/uni25E8 /uni25E9 /uni25EA /uni25EB /uni25EC /uni25ED /uni25EE /uni25EF '+nl+ //E8 +'/uni25F0 /uni25F1 /uni25F2 /uni25F3 /uni25F4 /uni25F5 /uni25F6 /uni25F7 '+nl+ //F0 +'/uni25F8 /uni25F9 /uni25FA /uni25FB /uni25FC /uni25FD /uni25FE /uni25FF '+nl //F8 + ), + ( + codepage: $26; + name: 'E26'; //miscellaneous symbols + glyphnames: +'/uni2600 /uni2601 /uni2602 /uni2603 /uni2604 /uni2605 /uni2606 /uni2607 '+nl+ //00 +'/uni2608 /uni2609 /uni260A /uni260B /uni260C /uni260D /uni260E /uni260F '+nl+ //08 +'/uni2610 /uni2611 /uni2612 /uni2613 /uni2614 /uni2615 /uni2616 /uni2617 '+nl+ //10 +'/uni2618 /uni2619 /uni261A /uni261B /uni261C /uni261D /uni261E /uni261F '+nl+ //18 +'/uni2620 /uni2621 /uni2622 /uni2623 /uni2624 /uni2625 /uni2626 /uni2627 '+nl+ //20 +'/uni2628 /uni2629 /uni262A /uni262B /uni262C /uni262D /uni262E /uni262F '+nl+ //28 +'/uni2630 /uni2631 /uni2632 /uni2633 /uni2634 /uni2635 /uni2636 /uni2637 '+nl+ //30 +'/uni2638 /uni2639 /smileface /invsmileface /sun /uni263D /uni263E /uni263F '+nl+ //38 +'/female /uni2641 /male /uni2643 /uni2644 /uni2645 /uni2646 /uni2647 '+nl+ //40 +'/uni2648 /uni2649 /uni264A /uni264B /uni264C /uni264D /uni264E /uni264F '+nl+ //48 +'/uni2650 /uni2651 /uni2652 /uni2653 /uni2654 /uni2655 /uni2656 /uni2657 '+nl+ //50 +'/uni2658 /uni2659 /uni265A /uni265B /uni265C /uni265D /uni265E /uni265F '+nl+ //58 +'/spade /uni2661 /uni2662 /club /uni2664 /heart /diamond /uni2667 '+nl+ //60 +'/uni2668 /uni2669 /musicalnote /musicalnotedbl /uni266C /uni266D /uni266E /uni266F '+nl+ //68 +'/uni2670 /uni2671 /uni2672 /uni2673 /uni2674 /uni2675 /uni2676 /uni2677 '+nl+ //70 +'/uni2678 /uni2679 /uni267A /uni267B /uni267C /uni267D /uni267E /uni267F '+nl+ //78 +'/uni2680 /uni2681 /uni2682 /uni2683 /uni2684 /uni2685 /uni2686 /uni2687 '+nl+ //80 +'/uni2688 /uni2689 /uni268A /uni268B /uni268C /uni268D /uni268E /uni268F '+nl+ //88 +'/uni2690 /uni2691 /uni2692 /uni2693 /uni2694 /uni2695 /uni2696 /uni2697 '+nl+ //90 +'/uni2698 /uni2699 /uni269A /uni269B /uni269C /uni269D /uni269E /uni269F '+nl+ //98 +'/uni26A0 /uni26A1 /uni26A2 /uni26A3 /uni26A4 /uni26A5 /uni26A6 /uni26A7 '+nl+ //A0 +'/uni26A8 /uni26A9 /uni26AA /uni26AB /uni26AC /uni26AD /uni26AE /uni26AF '+nl+ //A8 +'/uni26B0 /uni26B1 /uni26B2 /uni26B3 /uni26B4 /uni26B5 /uni26B6 /uni26B7 '+nl+ //B0 +'/uni26B8 /uni26B9 /uni26BA /uni26BB /uni26BC /uni26BD /uni26BE /uni26BF '+nl+ //B8 +'/uni26C0 /uni26C1 /uni26C2 /uni26C3 /uni26C4 /uni26C5 /uni26C6 /uni26C7 '+nl+ //C0 +'/uni26C8 /uni26C9 /uni26CA /uni26CB /uni26CC /uni26CD /uni26CE /uni26CF '+nl+ //C8 +'/uni26D0 /uni26D1 /uni26D2 /uni26D3 /uni26D4 /uni26D5 /uni26D6 /uni26D7 '+nl+ //D0 +'/uni26D8 /uni26D9 /uni26DA /uni26DB /uni26DC /uni26DD /uni26DE /uni26DF '+nl+ //D8 +'/uni26E0 /uni26E1 /uni26E2 /uni26E3 /uni26E4 /uni26E5 /uni26E6 /uni26E7 '+nl+ //E0 +'/uni26E8 /uni26E9 /uni26EA /uni26EB /uni26EC /uni26ED /uni26EE /uni26EF '+nl+ //E8 +'/uni26F0 /uni26F1 /uni26F2 /uni26F3 /uni26F4 /uni26F5 /uni26F6 /uni26F7 '+nl+ //F0 +'/uni26F8 /uni26F9 /uni26FA /uni26FB /uni26FC /uni26FD /uni26FE /uni26FF '+nl //F8 + ) + ); +{ + undefmap: encodingty = ( + codepage: -1; + name: 'Exx'; + glyphnames: +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //00 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //08 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //10 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //18 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //20 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //28 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //30 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //38 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //40 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //48 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //50 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //58 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //60 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //68 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //70 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //78 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //80 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //88 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //90 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //98 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //a0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //a8 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //b0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //b8 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //c0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //c8 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //d0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //d8 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //e0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //e8 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //f0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl //f8 + ); +} +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/mseuniintf.inc b/mseide-msegui/lib/common/kernel/mseuniintf.inc new file mode 100644 index 0000000..3020fe1 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseuniintf.inc @@ -0,0 +1,12 @@ +{ MSEgui Copyright (c) 1999-2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +function uni_getfontwithglyph(var drawinfo: drawinfoty): boolean; + diff --git a/mseide-msegui/lib/common/kernel/msevariants.pas b/mseide-msegui/lib/common/kernel/msevariants.pas new file mode 100644 index 0000000..b81c0b8 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msevariants.pas @@ -0,0 +1,86 @@ +{ MSEgui Copyright (c) 2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msevariants; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msetypes,msestrings; +type + variantarty = array of variant; + variantaty = array[0..0] of variant; + pvariantaty = ^variantaty; + variantararty = array of variantarty; + vardataaty = array[0..0] of tvardata; + pvardataaty = ^vardataaty; + +function mseVarTypeIsValidArrayType(const aVarType: TVarType): Boolean; +function mseVarArrayCreate(const Bounds: PVarArrayBoundArray; Dims : SizeInt; + aVarType: TVarType): Variant; +function vartomsestring(const avalue: variant): msestring; + +implementation +uses + variants,varutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function vartomsestring(const avalue: variant): msestring; +begin + result:= ''; + if not varisnull(avalue) then begin + result:= avalue; + end; +end; + +//allow int64 arrays + +function mseVarTypeIsValidArrayType(const aVarType: TVarType): Boolean; + begin + Result:=aVarType in [varSmallInt,varInteger, +{$ifndef FPUNONE} + varSingle,varDouble,varDate, +{$endif} + varCurrency,varOleStr,varDispatch,varError,varBoolean, + varVariant,varUnknown,varShortInt,varByte,varWord,varLongWord, + varint64]; + end; + +function mseVarArrayCreate(const Bounds: PVarArrayBoundArray; + Dims : SizeInt; aVarType: TVarType): Variant; + var + p : pvararray; + begin + if not(mseVarTypeIsValidArrayType(aVarType)) then + VarArrayCreateError; + finalize(Result); + + p:=SafeArrayCreate(aVarType,Dims,Bounds^); + + if not(assigned(p)) then + VarArrayCreateError; + + TVarData(Result).vType:=aVarType or varArray; + TVarData(Result).vArray:=p; + end; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/mseguiintf.pas b/mseide-msegui/lib/common/kernel/windows/mseguiintf.pas new file mode 100644 index 0000000..f14618c --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/mseguiintf.pas @@ -0,0 +1,3531 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseguiintf; //i386-win32 + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} + +interface +uses + windows,messages,mseapplication,msetypes,msegraphutils,msesys, + mseevent,msepointer,mseguiglob,msegraphics, + msethread,mseformatstr,{msesysintf,}msestrings,msesystypes,msewinglob; + +type + syseventty = record + hwnd: hwnd; + umsg: uint; + wparam: wparam; + lparam: lparam; + lresult: lresult; + end; + +const +// pixel0 = $000000; +// pixel1 = $ffffff; + pixel0 = $ffffff; //select colorbackground + pixel1 = $000000; //select colorforeground + +{$ifdef FPC} +{$include ..\mseguiintf.inc} +{$else} +{$include mseguiintf.inc} +{$endif} + +function getapplicationwindow: hwnd; +procedure recttowinrect(const rect: rectty); overload; +procedure recttowinrect(po: prectty; count: integer); overload; +procedure winrecttorect(const rect: rectty); overload; +procedure winrecttorect(po: prectty; count: integer); overload; +function mrect(aleft,atop,aright,abottom: integer): trect; +function createbitmapdata(const size: sizety; const kind: bitmapkindty; + out data: pointer): hbitmap; + +procedure beginsdndwrite(const athread: threadty); +procedure endsdndwrite; +function nestedwindowproc(): boolean; //window frame clicked + +{$ifdef mse_debuggdi} +var + pixmapcount: integer; + fontcount: integer; + windowcount: integer; + regioncount: integer; + gccount: integer; +{$endif} + +implementation +//todo: 19.10.03 rasterops for textout +uses + sysutils,mselist,msekeyboard,msebits,msearrayutils,msesysutils,msegui, + msesystimer,msegdi32gdi,msesysintf1,msedynload,msewindnd,msebitmap + {$ifdef mse_debugzorder},typinfo{$endif} ; + +type + + trayinfoty = record + end; + win32windowdty = record + trayinfo: trayinfoty; + istaskbar: boolean; + end; + win32windowty = record + case integer of + 0: (d: win32windowdty;); + 1: (_bufferspace: windowpty;); + end; + + wndextrainfoty = record + flags: longword; + stylebackup: longword; +// l,t,r,b: integer; + end; +{$ifndef FPC} + winbool = bool; +{$endif} + +const + MAPVK_VK_TO_VSC = 0; + flagsoffs = 0*sizeof(integer); //for setwindowlong + stylebackupoffs = 1*sizeof(integer); +// loffs = 2*sizeof(integer); +// toffs = 3*sizeof(integer); +// roffs = 4*sizeof(integer); +// boffs = 5*sizeof(integer); + + widgetclassname = 'msetoplevelwidget'; + childwidgetclassname = 'msechildwidget'; + wndextrabytes = sizeof(wndextrainfoty); + + mouseidletime = 100; //milliseconds + { + cursorshapety = (cr_default,cr_none,cr_arrow,cr_cross,cr_wait,cr_ibeam, + cr_sizever,cr_sizehor,cr_sizebdiag,cr_sizefdiag,cr_sizeall, + cr_splitv,cr_splith,cr_pointinghand,cr_forbidden, + cr_topleftcorner,cr_bottomleftcorner, + cr_bottomrightcorner,cr_toprightcorner, + cr_res0,cr_res1,cr_res2,cr_res3,cr_res4,cr_res5,cr_res6,cr_res7, + cr_user); + } + {$ifdef FPC} + IDC_ARROW = pchar(32512); + IDC_IBEAM = pchar(32513); + IDC_WAIT = pchar(32514); + IDC_CROSS = pchar(32515); + IDC_UPARROW = pchar(32516); + IDC_SIZE = pchar(32640); + IDC_ICON = pchar(32641); + IDC_SIZENWSE = pchar(32642); + IDC_SIZENESW = pchar(32643); + IDC_SIZEWE = pchar(32644); + IDC_SIZENS = pchar(32645); + IDC_SIZEALL = pchar(32646); + IDC_NO = pchar(32648); + IDC_HAND = pchar(32649); + IDC_APPSTARTING = pchar(32650); + IDC_HELP = pchar(32651); + + VK_LWIN = 91; + VK_RWIN = 92; + {$endif} + + VK_OEM_PLUS = $BB; // '+' any country + VK_OEM_COMMA = $BC; // ',' any country + VK_OEM_MINUS = $BD; // '-' any country + VK_OEM_PERIOD = $BE; // '.' any coun {$endif} + + standardcursors: array[cursorshapety] of pchar{makeintresource} = + (idc_arrow,idc_arrow,idc_arrow,idc_arrow, + idc_cross,idc_wait,idc_ibeam, + idc_sizens,idc_sizewe,idc_sizenesw,idc_sizenwse,idc_sizeall, + idc_arrow,idc_arrow,idc_hand,idc_no, + idc_arrow, //cr_drag + idc_sizenwse,idc_sizenesw, + idc_sizenwse,idc_sizenesw, + idc_arrow,idc_arrow,idc_arrow,idc_arrow, + idc_arrow,idc_arrow,idc_arrow,idc_arrow, + idc_arrow); +{ // |not dest and source + rasteropty = ( rop_clear, rop_and, rop_andnot, rop_copy, + // |not source and dest + rop_notand, rop_nop, rop_xor, rop_or, + rop_nor, rop_notxor, rop_not, rop_ornot, + rop_notcopy, rop_notor, rop_nand, rop_set); + + source 1 1 0 0 + dest 1 0 1 0 + result x x x x code = result + 1 + copy 1 1 0 0 + 1 = 13 + and 1 0 0 0 + 1 = 9 + } + + + col0: tagrgbquad = (rgbblue: $ff; rgbgreen: $ff; rgbred: $ff; rgbreserved: $00); + col1: tagrgbquad = (rgbblue: 0; rgbgreen: 0; rgbred: 0; rgbreserved: $00); +// col0: tagrgbquad = (rgbblue: 0; rgbgreen: 0; rgbred: 0); +// col1: tagrgbquad = (rgbblue: $ff; rgbgreen: $ff; rgbred: $ff); + + MONITOR_DEFAULTTONULL = 0; + MONITOR_DEFAULTTOPRIMARY = 1; + MONITOR_DEFAULTTONEAREST = 2; + SM_XVIRTUALSCREEN = 76; + SM_YVIRTUALSCREEN = 77; + SM_CXVIRTUALSCREEN = 78; + SM_CYVIRTUALSCREEN = 79; + +type + hmonitor = thandle; + tMONITORINFO = record + cbSize: DWORD ; + rcMonitor: tRECT ; + rcWork: tRECT; + dwFlags: DWORD; + end; + pmonitorinfo = ^tmonitorinfo; + +{$ifdef FPC} +type + TKeyboardState = array[0..255] of Byte; +{$else} +function GetCharacterPlacementW(DC: HDC; p2: PWideChar; p3, p4: Integer; + var p5: TGCPResultsw; p6: DWORD): DWORD; stdcall; + external gdi32 name 'GetCharacterPlacementW'; + +{$endif} + +var + canshutdown: integer; + widgetclass: atom; + childwidgetclass: atom; + applicationwindow: winidty; + desktopwindow: hwnd; + eventlist: tobjectqueue; +// timer: longword; + mouseidletimer: ptruint; + mainthread: threadty; + mousewindow: hwnd; + lastfocuswindow: hwnd; + groupleaderwindow: hwnd; + mousecursor: hcursor; + keystate: tkeyboardstate; + charbuffer: msestring; + shiftstate: shiftstatesty; + primarybuffer: msestring; + + cursors: array[cursorshapety] of longword; + +type + tapplication1 = class(tguiapplication); + tsimplebitmap1 = class(tsimplebitmap); + tcanvas1 = class(tcanvas); +{ + gdimonochromebitmapinfoty = packed record + bmiheader: tbitmapinfoheader; + bmicolors: array[0..1] of trgbquad; + end; +} + gdibitmapinfoty = packed record + bmiheader: tbitmapinfoheader; + bmicolors: array[0..255] of trgbquad; //maximum size + end; + + bitmapinfoty = packed record + bmiheader: bitmapinfoheader; + col0: longword; + col1: longword; + end; + +{$ifdef FPC} +function GetNextWindow(hWnd: HWND; uCmd: UINT): HWND; stdcall; + external user32 name 'GetWindow'; +function winScrollWindowEx(hWnd: HWND; dx, dy: Integer; + prcScroll, prcClip: PRect; + hrgnUpdate: HRGN; prcUpdate: PRect; flags: UINT): BOOL; stdcall; + external user32 name 'ScrollWindowEx'; + +function PeekMessage(var lpMsg: TMsg; hWnd: HWND; + wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL; stdcall; + external user32 name 'PeekMessageA'; +function TranslateMessage(const lpMsg: TMsg): BOOL; stdcall; + external user32 name 'TranslateMessage'; +function DispatchMessage(const lpMsg: TMsg): Longint; stdcall; + external user32 name 'DispatchMessageA'; +{$endif} + +function GetMonitorInfo(hmomitor: hmonitor; lpmu: pmonitorinfo): BOOL; stdcall; + external user32 name 'GetMonitorInfoA'; +function MonitorFromWindow(hwnd: HWND; dwFlags: DWORD): HMONITOR; stdcall; + external user32 name 'MonitorFromWindow'; + +type +{$ifndef FPC} + POINT = tpoint; + RECT = trect; + {$endif} + HIMC = DWORD; + tagCOMPOSITIONFORM = record + dwStyle: DWORD; + ptCurrentPos: POINT; + rcArea: RECT; + end; + COMPOSITIONFORM = tagCOMPOSITIONFORM; + PCOMPOSITIONFORM = ^COMPOSITIONFORM; + NPCOMPOSITIONFORM = ^COMPOSITIONFORM; + LPCOMPOSITIONFORM = ^COMPOSITIONFORM; + +const +// bit field for IMC_SETCOMPOSITIONWINDOW, IMC_SETCANDIDATEWINDOW + CFS_DEFAULT = $0000; + CFS_RECT = $0001; + CFS_POINT = $0002; + CFS_FORCE_POSITION = $0020; + CFS_CANDIDATEPOS = $0040; + CFS_EXCLUDE = $0080; + +var + hasimm32: boolean; + ImmGetContext: function(_hwnd: HWND): HIMC; stdcall; + ImmReleaseContext: function(_hwnd: HWND; _himc: HIMC): BOOL; stdcall; + ImmSetCompositionWindow: function(_himc: HIMC; + lpCompForm: LPCOMPOSITIONFORM): BOOL; stdcall; + + haslayeredwindows: boolean; + SetLayeredWindowAttributes: + function(_hwnd: HWND; crKey: COLORREF; bAlpha: BYTE; + dwFLAGS: DWORD): BOOL; stdcall; +{ + UpdateLayeredWindow: + function(_hwnd: HWND; hdcDst: HDC; pptDst: pPOINT; psize: pSIZE; + hdcSrc: HDC; pptSrc: pPOINT; crKey: COLORREF; + pblend: pBLENDFUNCTION; dwFlags: DWORD): BOOL; stdcall; +} +function getapplicationwindow: hwnd; +begin + result:= applicationwindow; +end; + +{$ifndef FPC} +type + _NOTIFYICONDATAA = record + cbSize: DWORD; + Wnd: HWND; + uID: UINT; + uFlags: UINT; + uCallbackMessage: UINT; + hIcon: HICON; + szTip: array [0..63] of Char; + end; + _NOTIFYICONDATA = _NOTIFYICONDATAA; + + _NOTIFYICONDATAW = record + cbSize: DWORD; + Wnd: HWND; + uID: UINT; + uFlags: UINT; + uCallbackMessage: UINT; + hIcon: HICON; + szTip: array [0..63] of Word; + end; + TNotifyIconDataA = _NOTIFYICONDATAA; + TNotifyIconDataW = _NOTIFYICONDATAW; + TNotifyIconData = TNotifyIconDataA; + NOTIFYICONDATAA = _NOTIFYICONDATAA; + NOTIFYICONDATAW = _NOTIFYICONDATAW; + NOTIFYICONDATA = NOTIFYICONDATAA; + PNotifyIconDataA = ^TNotifyIconDataA; + PNotifyIconDataW = ^TNotifyIconDataW; + PNotifyIconData = PNotifyIconDataA; + +function Shell_NotifyIconA(dwMessage: DWORD; lpData: PNotifyIconDataA): BOOL; + external 'shell32.dll' name 'Shell_NotifyIconA'; +function Shell_NotifyIconW(dwMessage: DWORD; lpData: PNotifyIconDataW): BOOL; + external 'shell32.dll' name 'Shell_NotifyIconW'; +{$endif} +{ +var + Shell_NotifyIconA: function (dwMessage: DWORD; lpData: PNotifyIconDataA): BOOL; + Shell_NotifyIconW: function (dwMessage: DWORD; lpData: PNotifyIconDataW): BOOL; + + shellinterfaceerror: guierrorty = gue_noshelllib; + shellinterfacechecked: boolean; + +function checkshellinterface: guierrorty; +var + bo1: boolean; +begin + if (shellinterfaceerror <> gue_ok) and not shellinterfacechecked then begin + shellinterfacechecked:= true; + if iswin95 then begin + bo1:= checkprocaddresses(['shell32.dll'], + ['Shell_NotifyIconA' + ], + [@Shell_NotifyIconA + ]); + end + else begin + bo1:= checkprocaddresses(['shell32.dll'], + ['Shell_NotifyIconW' + ], + [@Shell_NotifyIconW + ]); + end; + if bo1 then begin + shellinterfaceerror:= gue_ok; + end; + end; + result:= shellinterfaceerror; +end; +} + +procedure useproc; //no "not used" message +begin + if (childwidgetclass = 0) and (desktopwindow = 0) then begin + end; +end; + +function checkshellinterface: guierrorty; +begin + result:= gue_ok; +end; + +function mrect(aleft,atop,aright,abottom: integer): trect; +begin + with result do begin + left:= aleft; + top:= atop; + right:= aright; + bottom:= abottom; + end; +end; + +function gui_sethighrestimer(const avalue: boolean): guierrorty; +begin + if setmmtimer(avalue) then begin + result:= gue_ok; + end + else begin + result:= gue_timer; + end; +end; + +function gui_grouphideminimizedwindows: boolean; +begin + result:= true; +end; + +function gui_setimefocus(var awindow: windowty): guierrorty; +begin + result:= gue_ok; +end; + +function gui_unsetimefocus(var awindow: windowty): guierrorty; +begin + result:= gue_ok; +end; + +function gui_regiontorects(const aregion: regionty): rectarty; +var + int1: integer; + po1: prgndata; + po2: prect; +begin + result:= nil; + if aregion <> 0 then begin + int1:= getregiondata(aregion,0,nil); + getmem(po1,int1); + if getregiondata(aregion,int1,po1) <> 0 then begin + setlength(result,po1^.rdh.ncount); + po2:= @po1^.buffer; + for int1:= 0 to high(result) do begin + with result[int1],po2^ do begin + x:= left; + y:= top; + cx:= right - left; + cy:= bottom - top; + end; + inc(po2); + end; + end; + freemem(po1); + end; +end; + +function gui_getdefaultfontnames: defaultfontnamesty; +begin + result:= gdi32getdefaultfontnames; +end; + +function gui_canstackunder: boolean; +begin + result:= true; +end; + +procedure gui_cancelshutdown; +begin + if canshutdown <> 0 then begin + tapplication1(application).exitloop; + end; + canshutdown:= 0; +end; + +function gui_copytoclipboard(const value: msestring; + const buffer: clipboardbufferty): guierrorty; + //todo: copy msechars to clipboard, win95? +var + mem: thandle; + po1: pchar; + po2: pwidechar; + str1: string; +begin + if buffer = cbb_primary then begin + result:= gue_ok; + primarybuffer:= value; + end + else begin + result:= gue_clipboard; + if openclipboard(0) then begin + if emptyclipboard then begin + if iswin95 then begin + str1:= ansistring(value); + mem:= globalalloc(GMEM_MOVEABLE or GMEM_DDESHARE,length(str1)+1); //nullterminator + if mem <> 0 then begin + po1:= globallock(mem); + if po1 <> nil then begin + move(pchar(str1)^,po1^,length(str1)+1); + globalunlock(mem); + if setclipboarddata(cf_text,longword(mem)) <> 0 then begin + result:= gue_ok; + end; + end + else begin + globalfree(mem); + end; + end; + end + else begin + mem:= globalalloc(GMEM_MOVEABLE or GMEM_DDESHARE,(length(value)+1)*2); + //nullterminator + if mem <> 0 then begin + po2:= globallock(mem); + if po2 <> nil then begin + move(pwidechar(value)^,po2^,(length(value)+1)*2); + globalunlock(mem); + if setclipboarddata(cf_unicodetext,longword(mem)) <> 0 then begin + result:= gue_ok; + end; + end + else begin + globalfree(mem); + end; + end; + end; + end; + closeclipboard; + end; + end; +end; + +function gui_canpastefromclipboard( + const buffer: clipboardbufferty): boolean; +begin + if buffer = cbb_primary then begin + result:= primarybuffer <> ''; + end + else begin + result:= isclipboardformatavailable(cf_text); + end; +end; + +function gui_sysdnd(const action: sysdndactionty; + const aintf: isysdnd; const arect: rectty; + out aresult: boolean): guierrorty; +begin + result:= sysdnd(action,aintf,arect,aresult); +end; + +function gui_sysdndreaddata(var adata: string; + const typeindex: integer): guierrorty; +begin + result:= sysdndreaddata(adata,typeindex); +end; + +function gui_sysdndreadtext(var atext: msestring; + const typeindex: integer): guierrorty; +begin + result:= sysdndreadtext(atext,typeindex); +end; + +function gui_pastefromclipboard(out value: msestring; + const buffer: clipboardbufferty): guierrorty; +var //todo: get msechars from clipboard, win95? + data: thandle; + po1: pointer; + str1: string; +begin + result:= gue_clipboard; + if buffer = cbb_primary then begin + value:= primarybuffer; + if value <> '' then begin + result:= gue_ok; + end; + end + else begin + value:= ''; + if openclipboard(0) then begin + if iswin95 then begin + data:= getclipboarddata(cf_text); + end + else begin + data:= getclipboarddata(cf_unicodetext); + end; + closeclipboard; + if data <> 0 then begin + po1:= globallock(data); + if po1 <> nil then begin + if iswin95 then begin + setlength(str1,globalsize(data)); + if length(str1) > 0 then begin + move(po1^,str1[1],length(str1)); + result:= gue_ok; + setlength(str1,length(pchar(str1))); + end; + value:= msestring(str1); + end + else begin + setlength(value,globalsize(data) div 2); + if length(value) > 0 then begin + move(po1^,value[1],length(value)*2); + result:= gue_ok; + setlength(value,length(pwidechar(value))); + if (value <> '') and (value[length(value)] = #$0d) then begin + setlength(value,length(value)-1); + end; + end; + end; + globalunlock(data); + end; + end; + end; + end; +end; + +function gui_getwindowsize(id: winidty): windowsizety; +var + placement: twindowplacement; +begin + case getwindowlong(id,flagsoffs) of + 1: begin + result:= wsi_fullscreen; + end; + 2: begin + result:= wsi_fullscreenvirt; + end; + else begin + result:= wsi_normal; + placement.length:= sizeof(placement); + if getwindowplacement(id,{$ifndef FPC}@{$endif}placement) then begin + case placement.showcmd of + sw_showmaximized: result:= wsi_maximized; + sw_showminimized: result:= wsi_minimized; + end; + end; + end; + end; +end; + +function gui_getwindowdesktop(const id: winidty): integer; +begin + result:= 0; //todo +end; + +function gui_windowvisible(id: winidty): boolean; +begin + result:= iswindowvisible(id); +end; + +function gui_setwindowstate(id: winidty; size: windowsizety; + visible: boolean): guierrorty; +var + int1,int2: integer; + wo1: longword; +// placement: twindowplacement; +begin + result:= gue_ok; + int1:= getwindowlong(id,flagsoffs); + int2:= 0; + if size in [wsi_fullscreen,wsi_fullscreenvirt] then begin + case size of + wsi_fullscreen: int2:= 1; + wsi_fullscreenvirt: int2:= 2; + end; + if int1 <> int2 then begin + setwindowlong(id,flagsoffs,int2); + if int1 = 0 then begin + wo1:= getwindowlong(id,gwl_style); + setwindowlong(id,stylebackupoffs,wo1); + wo1:= wo1 and not + (ws_border or ws_dlgframe or ws_overlapped or ws_thickframe) or (ws_popup); + setwindowlong(id,gwl_style,wo1); + end; + if size = wsi_fullscreen then begin + setwindowpos(id,0,0,0,getsystemmetrics(sm_cxscreen), + getsystemmetrics(sm_cyscreen), + swp_framechanged {or swp_nomove or swp_nosize} + or swp_nozorder or swp_noownerzorder or swp_noactivate); + end + else begin + setwindowpos(id,0,getsystemmetrics(sm_xvirtualscreen), + getsystemmetrics(sm_yvirtualscreen), + getsystemmetrics(sm_cxvirtualscreen), + getsystemmetrics(sm_cyvirtualscreen), + swp_framechanged {or swp_nomove or swp_nosize} + or swp_nozorder or swp_noownerzorder or swp_noactivate); + end; + end; + if visible then begin + showwindow(id,sw_shownoactivate); + end; + end + else begin + if int1 <> 0 then begin + wo1:= getwindowlong(id,stylebackupoffs); + setwindowlong(id,gwl_style,getwindowlong(id,stylebackupoffs)); + setwindowpos(id,0,0,0,0,0, + swp_framechanged or swp_nomove or swp_nosize or swp_nozorder or + swp_noownerzorder or swp_noactivate); + setwindowlong(id,flagsoffs,int2); + end; + case size of + wsi_maximized: begin + int1:= sw_maximize; + end; + wsi_minimized: begin + int1:= sw_minimize; + end; + else begin + int1:= sw_shownoactivate; + end; + end; + if visible or (size = wsi_minimized) then begin + showwindow(id,int1); + end; + end; +end; + +function gui_getpointerpos: pointty; +begin + windows.getcursorpos(tpoint(result)); +end; + +function gui_setpointerpos(const pos: pointty): guierrorty; +begin + if windows.SetCursorPos(pos.x,pos.y) then begin + result:= gue_ok; + end + else begin + result:= gue_mousepos; + end; +end; + +function gui_movepointer(const dist: pointty): guierrorty; +var + po1: tpoint; +begin + result:= gue_mousepos; + if windows.getcursorpos(po1) then begin + if windows.setcursorpos(po1.x+dist.x,po1.y+dist.y) then begin + result:= gue_ok; + end; + end; +end; + +function gui_grabpointer(id: winidty): guierrorty; +begin + setcapture(id); + if getcapture = id then begin +{$ifdef mse_debugwindowfocus} + debugwindow('grabpointer OK ',id); +{$endif} + result:= gue_ok; + end + else begin +{$ifdef mse_debugwindowfocus} + debugwindow('grabpointer error ',id); +{$endif} + result:= gue_capturemouse; + end; +end; + +function gui_ungrabpointer: guierrorty; +begin +{$ifdef mse_debugwindowfocus} + debugwriteln('ungrabpointer'); +{$endif} + releasecapture; + result:= gue_ok; +end; + +function gui_createpixmap(const size: sizety; winid: winidty = 0; + kind: bitmapkindty = bmk_rgb; + copyfrom: pixmapty = 0): pixmapty; + //copyfrom does not work if selected in dc! +var + dc,dc1: hdc; + po1: pointer; +begin + po1:= nil; + case kind of + bmk_mono: begin + result:= createbitmap(size.cx,size.cy,1,1,nil); + end; + bmk_gray: begin + result:= createbitmapdata(size,kind,po1); +// result:= createbitmap(size.cx,size.cy,1,8,nil); + end + else begin + dc:= getdc(winid); + result:= createcompatiblebitmap(dc,size.cx,size.cy); + releasedc(winid,dc); + end; + end; +{$ifdef mse_debuggdi} + if result <> 0 then begin + inc(pixmapcount); + end; +{$endif} + if (result <> 0) and (copyfrom <> 0) then begin + dc:= createcompatibledc(0); + dc1:= createcompatibledc(0); + selectobject(dc,result); + selectobject(dc1,copyfrom); + bitblt(dc,0,0,size.cx,size.cy,dc1,0,0,srccopy); + deletedc(dc); + deletedc(dc1); + { + dc:= getdc(winid); + fillchar(bitmapinfo,sizeof(bitmapinfo),0); + bitmapinfo.bmiHeader.bisize:= sizeof(bitmapinfo.bmiheader); + if getdibits(dc,copyfrom,0,size.cy,nil, + windows.bitmapinfo(pointer(@bitmapinfo)^),dib_rgb_colors) <> 0 then begin + with bitmapinfo.bmiHeader do begin + if bisizeimage = 0 then begin + if monochrome then begin + bisizeimage:= ((size.cx+31) div 32) * 4 * size.cy; + end + else begin + bisizeimage:= size.cx*size.cy*4; + end; + end; + po1:= pointer(localalloc(LMEM_FIXED,bisizeimage)); + getdibits(dc,copyfrom,0,size.cy,po1, + windows.bitmapinfo(pointer(@bitmapinfo)^),dib_rgb_colors); + setdibits(dc,result,0,size.cy,po1, + windows.bitmapinfo(pointer(@bitmapinfo)^),dib_rgb_colors); + localfree(longword(po1)); + end; + end; + releasedc(winid,dc); + } + end; +end; + +procedure initbitmapinfo(kind: bitmapkindty; bottomup: boolean; + const size: sizety; const setpalette: boolean; + out bitmapinfo: gdibitmapinfoty); +var + lwo1: longword; +begin + fillchar(bitmapinfo,sizeof(bitmapinfo),0); + with bitmapinfo.bmiHeader do begin + bisize:= sizeof(tbitmapinfoheader); + biwidth:= size.cx; + if bottomup then begin + biheight:= size.cy; + end + else begin + biheight:= -size.cy; + end; + biplanes:= 1; + case kind of + bmk_mono: begin + bibitcount:= 1; + bitmapinfo.bmicolors[0]:= col0; + bitmapinfo.bmicolors[1]:= col1; + // bitmapinfo.bmicolors[0]:= col0; + // bitmapinfo.bmicolors[1]:= col1; + end; + bmk_gray: begin + bibitcount:= 8; + if setpalette then begin + for lwo1:= 0 to high(bitmapinfo.bmicolors) do begin + bitmapinfo.bmicolors[lwo1]:= + rgbquad(lwo1 or (lwo1 shl 8) or (lwo1 shl 16)); + end; + end + else begin + biclrused:= 1; + bitmapinfo.bmicolors[0]:= col0;; + end; + end; + else begin + bibitcount:= 32; + end; + end; + end; +end; + +function createbitmapdata(const size: sizety; const kind: bitmapkindty; + out data: pointer): hbitmap; +var + info: gdibitmapinfoty; +begin + initbitmapinfo(kind,false,size,true,info); + result:= createdibsection(0,bitmapinfo((@info)^),dib_rgb_colors,data,0,0); +end; + +function gui_createbitmapfromdata(const size: sizety; datapo: pbyte; + msbitfirst: boolean = false; dwordaligned: boolean = false; + bottomup: boolean = false): pixmapty; +var + po1,po2: pbyte; + bytesperline: integer; + int1,int2,int3: integer; + bitmapinfo: gdibitmapinfoty; + dc: hdc; + +begin + {$ifdef FPC}{$checkpointer off}{$endif} + bytesperline:= ((size.cx+31) div 32)*4; + int3:= bytesperline*size.cy; //total bytecount + po1:= pointer(localalloc(LMEM_FIXED,int3)); + fillchar(po1^,int3,0); + if dwordaligned then begin + move(datapo^,po1^,int3); + end + else begin + int2:= (size.cx+7) div 8; //source bytesperline + po2:= po1; + for int1:= 0 to size.cy - 1 do begin + move(datapo^,po2^,int2); + inc(po2,bytesperline); + inc(datapo,int2); + end; + end; + if not msbitfirst then begin + po2:= po1; + for int1:= 0 to int3-1 do begin + po2^:= bitreverse[po2^]; + inc(po2); + end; + end; + initbitmapinfo(bmk_mono,bottomup,size,true,bitmapinfo); + result:= createbitmap(size.cx,size.cy,1,1,nil); + dc:= getdc(0); + setdibits(dc,result,0,size.cy,po1,windows.bitmapinfo(pointer(@bitmapinfo)^),dib_rgb_colors); + releasedc(0,dc); + localfree(ptruint(po1)); +// localfree(longword(po1)); + {$ifdef FPC}{$checkpointer default}{$endif} +end; + +function gui_freepixmap(pixmap: pixmapty): gdierrorty; +begin + if not deleteobject(pixmap) then begin + result:= gde_freepixmap; + end + else begin +{$ifdef mse_debuggdi} + dec(pixmapcount); +{$endif} + result:= gde_ok; + end; +end; + +function gui_getpixmapinfo(var info: pixmapinfoty): gdierrorty; +var + bmp: bitmap; +begin + with info do begin + if getobject(handle,sizeof(bmp),@bmp) = 0 then begin + result:= gde_pixmap; + end + else begin + result:= gde_ok; + size.cx:= bmp.bmwidth; + size.cy:= bmp.bmheight; + depth:= bmp.bmbitspixel; + end; + end; +end; + +procedure transformimageformat(const image: imagety; inverse: boolean = true); +var + po1: pbyte; + int1: integer; +begin + {$ifdef FPC}{$checkpointer off}{$endif} +// if image.monochrome then begin + if image.kind = bmk_mono then begin + po1:= pointer(image.pixels); + if inverse then begin + for int1:= 0 to image.length*4-1 do begin + po1^:= not bitreverse[po1^]; + inc(po1); + end; + end + else begin + for int1:= 0 to image.length*4-1 do begin + po1^:= bitreverse[po1^]; + inc(po1); + end; + end; + end; + {$ifdef FPC}{$checkpointer default}{$endif} + { + else begin + for int1:= 0 to high(image.pixels) do begin + swaprgb1(image.pixels[int1]); + end; + end; + } +end; + +var + imagememalloc: integer; + +function gui_allocimagemem(length: integer): plongwordaty; +begin + if length = 0 then begin + result:= nil; + end + else begin + inc(imagememalloc); + result:= pointer(localalloc(LMEM_FIXED,length*sizeof(longword))); + //getdibits, setdeibits do not work with normal heap + if result = nil then begin + raise exception.Create('Out of memory.'); + end; + end; +end; + +procedure gui_freeimagemem(data: plongwordaty); +begin + dec(imagememalloc); + localfree(ptruint(data)); +end; + +function gui_pixmaptoimage(pixmap: pixmapty; out image: imagety; + gchandle: longword): gdierrorty; +var + info: pixmapinfoty; + bitmapinfo: gdibitmapinfoty; + dc: hdc; + int1: integer; +// bmp1,bmpbefore: hbitmap; + kind1: bitmapkindty; + +begin +{ + if gchandle <> 0 then begin + bmp1:= createcompatiblebitmap(gchandle,0,0); + bmpbefore:= selectobject(gchandle,bmp1); + end + else begin + bmp1:= 0; //compiler warning + end; +} + if gchandle <> 0 then begin + dc:= gchandle; + end + else begin + dc:= getdc(0); + end; + info.handle:= pixmap; + result:= gui_getpixmapinfo(info); + if result = gde_ok then begin + result:= gde_image; + case info.depth of + 1: begin + kind1:= bmk_mono; + end; + 8: begin + kind1:= bmk_gray; + end; + else begin + kind1:= bmk_rgb; + end; + end; + initbitmapinfo(kind1,false,info.size,false,bitmapinfo); + allocimage(image,info.size,kind1); +// dc:= getdc(0); + int1:= getdibits(dc,pixmap,0,info.size.cy,image.pixels, + pbitmapinfo(@bitmapinfo)^,dib_rgb_colors); +// releasedc(0,dc); + if int1 <> 0 then begin + transformimageformat(image); + result:= gde_ok; + end; + end; + if gchandle = 0 then begin + releasedc(0,dc); + end; + { + if gchandle <> 0 then begin + selectobject(gchandle,bmpbefore); +// selectobject(gchandle,pixmap); + deleteobject(bmp1); + end; + } +end; + +function gui_getpixel(const id: winidty; const pos: pointty; + out pixel: pixelty): guierrorty; +var + dc: hdc; +begin + result:= gue_error; + dc:= getdc(id); + pixel:= windows.getpixel(dc,pos.x,pos.y); + releasedc(id,dc); + if pixel <> clr_invalid then begin + result:= gue_ok; + end; +end; + +function gui_imagetopixmap(const image: imagety; out pixmap: pixmapty; + gchandle: longword): gdierrorty; +var + int1: integer; + bitmapinfo: gdibitmapinfoty; + dc: hdc; +// bmp1,bmpbefore: hbitmap; +begin +// bmp1:= 0; //compiler warning + result:= gde_pixmap; + if gchandle <> 0 then begin + dc:= gchandle; + end + else begin + dc:= getdc(0); + end; + { + if gchandle <> 0 then begin + bmp1:= createcompatiblebitmap(gchandle,0,0); + bmpbefore:= selectobject(gchandle,bmp1); + end; + } + pixmap:= gui_createpixmap(image.size,0,image.kind); + if pixmap <> 0 then begin + transformimageformat(image,false); //setdibits reverses image!?!?! + initbitmapinfo(image.kind,false,image.size,true,bitmapinfo); +// dc:= getdc(0); + int1:= setdibits(dc,pixmap,0,image.size.cy,image.pixels, + tbitmapinfo(pbitmapinfo(@bitmapinfo)^),dib_rgb_colors); +// releasedc(0,dc); + transformimageformat(image,false); //restore orginal bitorder + if int1 <> 0 then begin + result:= gde_ok; + end; + end; + if gchandle <> 0 then begin + deleteobject(selectobject(gchandle,pixmap)); + end + else begin + releasedc(0,dc); + end; +{ + if gchandle <> 0 then begin +// selectobject(gchandle,bmpbefore); + selectobject(gchandle,pixmap); + deleteobject(bmp1); + end; +} +end; + +function gui_setwindowfocus(id: winidty): guierrorty; +begin +// setforegroundwindow(applicationwindow); + setforegroundwindow(id); + setfocus(id); + result:= gue_ok; +end; + +function gui_setappfocus(id: winidty): guierrorty; +var + selfthread,otherthread: threadty; +begin + result:= gue_error; + selfthread:= threadty(getcurrentthreadid); + otherthread:= threadty(getwindowthreadprocessid(id,nil)); + if otherthread <> 0 then begin + if attachthreadinput(selfthread,otherthread,true) then begin + if windows.setfocus(id) <> 0 then begin + result:= gue_ok; + end; + attachthreadinput(selfthread,otherthread,false) + end; + end; +end; + +function gui_minimizeapplication: guierrorty; +begin + result:= gue_ok; + if iswindowvisible(applicationwindow) then begin + showwindow(applicationwindow,sw_minimize); + end; +end; + +const + curwidth = 32; + curheight = 32; + curlength = ((curwidth+15) div 16)*2*curheight; + curdragxor: array[0..curlength-1] of byte = + ( + $00,$00,$00,$00, + $40,$00,$00,$00, + $60,$00,$00,$00, + $70,$00,$00,$00, + $78,$00,$00,$00, + $7c,$00,$00,$00, + $7e,$00,$00,$00, + $7f,$00,$00,$00, + $7f,$80,$00,$00, + $7f,$80,$00,$00, + $7f,$00,$00,$00, + $7e,$00,$00,$00, + $6e,$00,$00,$00, + $46,$00,$00,$00, + $06,$Fc,$00,$00, + $03,$7c,$00,$00, + $03,$7c,$00,$00, + $05,$bc,$00,$00, + $05,$bc,$00,$00, + $06,$7c,$00,$00, + $07,$Fc,$00,$00, + $07,$Fc,$00,$00, + $07,$Fc,$00,$00, + $07,$Fc,$00,$00, + $07,$Fc,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00); + curdragand: array[0..curlength-1] of byte = + ( + $3f,$ff,$ff,$ff, + $1f,$ff,$ff,$ff, + $0f,$ff,$ff,$ff, + $07,$ff,$ff,$ff, + $03,$ff,$ff,$ff, + $01,$ff,$ff,$ff, + $00,$ff,$ff,$ff, + $00,$7f,$ff,$ff, + $00,$3f,$ff,$ff, + $00,$1f,$ff,$ff, + $00,$0f,$ff,$ff, + $00,$ff,$ff,$ff, + $00,$ff,$ff,$ff, + $10,$01,$ff,$ff, + $30,$01,$ff,$ff, + $70,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $ff,$ff,$ff,$ff, + $ff,$ff,$ff,$ff, + $ff,$ff,$ff,$ff, + $ff,$ff,$ff,$ff, + $ff,$ff,$ff,$ff, + $ff,$ff,$ff,$ff + ); + +function gui_setcursorshape(winid: winidty; shape: cursorshapety): guierrorty; +var + cursor: hcursor; +begin + case shape of + cr_none: begin + cursor:= 0; + end; + cr_drag: begin + if cursors[cr_drag] = 0 then begin + cursors[cr_drag]:= createcursor(hinstance,0,0,curwidth,curheight, + @curdragand,@curdragxor); + end; + cursor:= cursors[cr_drag]; + end; + else begin + cursor:= windows.LoadCursor(0,standardcursors[shape]); + end; + end; + windows.SetCursor(cursor); + mousecursor:= cursor; + result:= gue_ok; +end; +{ +procedure killtimer; +begin + if timer <> 0 then begin + windows.killtimer(0,timer); + timer:= 0; + end; +end; + +procedure TimerProc(hwnd: hwnd; uMsg: longword; idEvent: longword; + dwTime: longword); stdcall; +begin + killtimer; + eventlist.add(tmseevent.create(ek_timer)); +end; + +function gui_settimer(us: longword): guierrorty; + //send et_timer event after delay or us (micro seconds) +begin + killtimer; + timer:= windows.settimer(0,0,us div 1000,@timerproc); + if timer = 0 then begin + result:= gue_timer; + end + else begin + result:= gue_ok; + end; +end; +} +function gui_settimer(us: longword): guierrorty; + //send et_timer event after delay or us (micro seconds) +begin + result:= setsystimer(us); +end; + +procedure gui_beep; +begin + windows.MessageBeep($ffffffff); +end; + +procedure winrecttorect(const rect: rectty); overload; +begin + dec(pinteger(@rect.cx)^,rect.x); + dec(pinteger(@rect.cy)^,rect.y); +end; + +procedure winrecttorect(po: prectty; count: integer); overload; +begin + while count > 0 do begin + dec(po^.cx,po^.x); + dec(po^.cy,po^.y); + inc(po); + dec(count); + end; +end; + +procedure recttowinrect(const rect: rectty); overload; +begin + inc(pinteger(@rect.cx)^,rect.x); + inc(pinteger(@rect.cy)^,rect.y); +end; + +procedure recttowinrect(po: prectty; count: integer); overload; +begin + while count > 0 do begin + inc(po^.cx,po^.x); + inc(po^.cy,po^.y); + inc(po); + dec(count); + end; +end; +{ +function gui_creategc(paintdevice: paintdevicety; const akind: gckindty; + var gc: gcty; const aprintername: msestring = ''): guierrorty; +begin + result:= gdi32creategc(paintdevice,akind,gc,aprintername); +end; +} +function gui_flushgdi(const synchronize: boolean = false): guierrorty; +begin + gui_hasevent; //dispachevents + gdiflush; + result:= gue_ok; +end; + +procedure windowdestroyed(id: winidty); +begin + if mousewindow = id then begin + mousewindow:= 0; + end; + if lastfocuswindow = id then begin + lastfocuswindow:= 0; + end; + if groupleaderwindow = id then begin + groupleaderwindow:= 0; + end; +end; + +type + setwindowownerinfoty = record + oldowner,newowner: winidty; + end; + psetwindowownerinfoty = ^setwindowownerinfoty; + +function setwindowowner(id: hwnd; param: lparam): winbool; stdcall; + +begin + with psetwindowownerinfoty(ptruint(param))^ do begin + {$ifdef cpu64} + if getwindowlongptr(id,gwlp_hwndparent) = oldowner then begin + setwindowlongptr(id,gwlp_hwndparent,newowner); + end; + {$else} + if getwindowlong(id,gwl_hwndparent) = oldowner then begin + setwindowlong(id,gwl_hwndparent,newowner); + end; + {$endif} + end; + result:= true; +end; + +function gui_destroywindow(var awindow: windowty): guierrorty; +var + ico1: hicon; +// id1: winidty; + info: setwindowownerinfoty; +begin + with awindow do begin + if id <> 0 then begin +{$ifdef mse_debugwindowdestroy} + debugwindow('*gui_destroywindow ',awindow.id); +{$endif} + ico1:= sendmessage(id,wm_seticon,icon_big,0); + if ico1 <> 0 then begin + destroyicon(ico1); + end; + info.oldowner:= id; + {$ifdef cpu64} + info.newowner:= getwindowlongptr(id,gwlp_hwndparent); + {$else} + info.newowner:= getwindowlong(id,gwl_hwndparent); + {$endif} + enumwindows(@setwindowowner,ptruint(@info)); + //do not destroy children + if windows.DestroyWindow(id) then begin +{$ifdef mse_debuggdi} + dec(windowcount); +{$endif} + result:= gue_ok; + end + else begin //foreign thread + if windows.postthreadmessage(mainthread,destroymessage,id,0) then begin + result:= gue_ok; + end + else begin + result:= gue_destroywindow; + end; + end; + windowdestroyed(id); + end; + end; +end; + +function gui_showwindow(id: winidty): guierrorty; +begin + windows.showwindow(id,sw_shownoactivate); + result:= gue_ok; +end; + +function gui_hidewindow(id: winidty): guierrorty; +begin + windows.showwindow(id,sw_hide); + result:= gue_ok; +end; + +function gui_raisewindow(id: winidty; + const topmost: boolean = false): guierrorty; +var + w1: hwnd; +begin +{$ifdef mse_debugzorder} + if hwndtopmost then begin + debugwindow('gui_raisewindow topmost ',id); + end + else begin + debugwindow('gui_raisewindow ',id); + end; +{$endif} + if topmost then begin + w1:= hwnd_topmost; + end + else begin + w1:= hwnd_top; + end; + windows.SetWindowPos(id,w1,0,0,0,0,swp_noactivate or swp_nomove or + swp_noownerzorder or swp_nosize); + result:= gue_ok; +end; + +function gui_lowerwindow(id: winidty; const topmost: boolean): guierrorty; +var + w1: hwnd; +begin +{$ifdef mse_debugzorder} + if topmost then begin + debugwindow('gui_lowerwindow topmost ',id); + end + else begin + debugwindow('gui_lowerwindow ',id); + end; +{$endif} + if topmost then begin + w1:= hwnd_notopmost; + end + else begin + w1:= hwnd_bottom; + end; + windows.SetWindowPos(id,w1,0,0,0,0,swp_noactivate or swp_nomove or + swp_noownerzorder or swp_nosize); + result:= gue_ok; +end; + +function gui_stackunderwindow(id: winidty; predecessor: winidty): guierrorty; +begin +{$ifdef mse_debugzorder} + debugwindow('gui_stackunderwindow ',id,predecessor); +{$endif} + if id <> predecessor then begin + windows.SetWindowPos(id,predecessor,0,0,0,0,swp_noactivate or swp_nomove or + swp_noownerzorder or swp_nosize); + end; + result:= gue_ok; +end; + +function gui_stackoverwindow(id: winidty; predecessor: winidty): guierrorty; +var + id1: winidty; +begin +{$ifdef mse_debugzorder} + debugwindow('gui_stackoverwindow ',id,predecessor); +{$endif} + if id <> predecessor then begin + id1:= windows.GetWindow(predecessor,gw_hwndprev); + if id1 = 0 then begin + id1:= hwnd_top; + end; + windows.SetWindowPos(id,id1,0,0,0,0,swp_noactivate or swp_nomove or + swp_noownerzorder or swp_nosize); + end; + result:= gue_ok; +end; + +function gui_getzorder(const ids: winidarty; out zorders: integerarty): guierrorty; + //topevel -> highest, numbers must not be contiguous +var + int1,foundcount: integer; + id1: winidty; +begin + setlength(zorders,length(ids)); + foundcount:= 0; + id1:= gettopwindow(0); + while (foundcount <= high(ids)) and (id1 <> 0) do begin + for int1:= 0 to high(ids) do begin + if ids[int1] = id1 then begin + zorders[int1]:= -foundcount; + inc(foundcount); + break; + end; + end; + id1:= getnextwindow(id1,gw_hwndnext); + end; + if foundcount - 1 = high(ids) then begin + result:= gue_ok + end + else begin + result:= gue_windownotfound; + end; +{$ifdef mse_debugzorder} + debugwriteln('gui_getzorder '+getenumname(typeinfo(result),ord(result))); + for int1:= 0 to high(ids) do begin + debugwindow(inttostr(zorders[int1])+' ',ids[int1]); + end; +{$endif} +end; + +function gui_setwindowcaption(id: winidty; const caption: msestring): guierrorty; + procedure setcap(const id: winidty); + var + str1: string; + begin + if iswin95 then begin + str1:= ansistring(caption); + if windows.SetWindowTextA(id,pchar(str1)) then begin + result:= gue_ok; + end + end + else begin + if windows.SetWindowTextW(id,pwidechar(caption)) then begin + result:= gue_ok; + end + end; + end; +begin + result:= gue_error; + setcap(id); + if (id = groupleaderwindow) and (result = gue_ok) then begin + setcap(applicationwindow); + end; +end; + +function composeicon(const icon,mask: pixmapty): hicon; +var + iconinfo1: iconinfo; + maskbmp,iconbmp: hbitmap; + dc1,dc2,dc3: hdc; + bmpinfo: bitmapinfo; + bru1: hbrush; + rect1: trect; + info: pixmapinfoty; + mask1: pixmapty; + bmp1: tbitmap; +label + endlab; +begin + result:= 0; + if icon <> 0 then begin + mask1:= mask; + if mask1 <> 0 then begin + info.handle:= mask1; + if (gui_getpixmapinfo(info) = gde_ok) and (info.depth <> 1) then begin + bmp1:= tbitmap.create(bmk_mono); + try + bmp1.handle:= mask1; + bmp1.colorbackground:= cl_black; + bmp1.kind:= bmk_mono; + mask1:= bmp1.handle; + bmp1.releasehandle; + finally + bmp1.free; + end; + end; + end; + fillchar(bmpinfo,sizeof(bmpinfo),0); + with bmpinfo.bmiHeader do begin + bisize:= sizeof(bmpinfo.bmiheader); + dc1:= createcompatibledc(0); + if getdibits(dc1,icon,0,0,nil,bmpinfo,dib_rgb_colors) <> 0 then begin + dc2:= createcompatibledc(0); + maskbmp:= createbitmap(biwidth,biheight,1,1,nil); + selectobject(dc1,maskbmp); + if mask1 = 0 then begin + bru1:= createsolidbrush(0); + rect1.Left:= 0; + rect1.top:= 0; + rect1.right:= biwidth; + rect1.bottom:= 0; + fillrect(dc1,rect1,bru1); + deleteobject(bru1); + end + else begin + selectobject(dc2,mask1); //should not be selected in another dc + bitblt(dc1,0,0,biwidth,biheight,dc2,0,0,rasterops3[rop_copy]); + deletedc(dc2); + dc2:= createcompatibledc(0); + end; + end + else begin + deletedc(dc1); + goto endlab; + end; + dc3:= createcompatibledc(0); + selectobject(dc3,icon); //should not be selected in another dc + iconbmp:= createcompatiblebitmap(dc3,biwidth,biheight); + selectobject(dc2,iconbmp); + bitblt(dc2,0,0,biwidth,biheight,dc3,0,0,rasterops3[rop_copy]); + deletedc(dc3); + bitblt(dc2,0,0,biwidth,biheight,dc1,0,0,rasterops3[rop_notand]); + //icon out of mask1 -> 0; + deletedc(dc1); + deletedc(dc2); + with iconinfo1 do begin + ficon:= true; + xhotspot:= 0; + yhotspot:= 0; + hbmmask:= maskbmp; + hbmcolor:= iconbmp; + end; + result:= createiconindirect(iconinfo1); + deleteobject(maskbmp); + deleteobject(iconbmp); + end; +endlab: + if (mask1 <> mask) and (mask1 <> 0) then begin + deleteobject(mask1); + end; + end + else begin + result:= 0; + end; +end; + +function gui_setwindowicon(id: winidty; const icon,mask: pixmapty): guierrorty; +var + ico,ico1: hicon; +begin + result:= gue_error; + if icon <> 0 then begin + ico:= composeicon(icon,mask); + if ico = 0 then begin + exit; + end; + end + else begin + ico:= 0; + end; + ico1:= sendmessage(id,wm_seticon,icon_big,ico); + if ico1 <> 0 then begin + destroyicon(ico1); + end; + result:= gue_ok; +end; + +function gui_setwindowopacity(id: winidty; const opacity: real): guierrorty; +var + lo1: LONG; + f1: flo64; +begin + result:= gue_notsupported; + if haslayeredwindows then begin + lo1:= getwindowlong(id,gwl_exstyle); + if opacity = emptyreal then begin + lo1:= lo1 and not(ws_ex_layered); + setwindowlong(id,gwl_exstyle,lo1); + end + else begin + lo1:= lo1 or ws_ex_layered; + setwindowlong(id,gwl_exstyle,lo1); + f1:= opacity; + if f1 < 0 then begin + f1:= 0; + end + else begin + if f1 > 1 then begin + f1:= 1; + end; + end; + setlayeredwindowattributes(id,0,round(255*f1),LWA_ALPHA); + end; + result:= gue_ok; + end; +end; + +function gui_setapplicationicon(const icon,mask: pixmapty): guierrorty; +begin + result:= gui_setwindowicon(applicationwindow,icon,mask); +end; + +type + pidinfoty = record + pids: procidarty; + winid: winidty; + end; + ppidinfoty = ^pidinfoty; + +function checkproc(awinid: hwnd; po: ptrint): bool; stdcall; +var + pid: integer; + int1: integer; +begin + result:= true; + if getwindowlong(awinid,gwl_style) and windows.ws_visible <> 0 then begin + getwindowthreadprocessid(awinid,@pid); + with ppidinfoty(po)^ do begin + for int1:= 0 to high(pids) do begin + if pids[int1] = pid then begin + result:= false; + winid:= awinid; + break; + end; + end; + end; + end; +end; + +function gui_pidtowinid(const pids: procidarty): winidty; +var + info: pidinfoty; +begin + info.pids:= pids; + info.winid:= 0; + enumwindows(@checkproc,ptrint(@info)); + result:= info.winid; +end; + +function gui_rgbtopixel(rgb: longword): pixelty; +begin + result:= swaprgb(rgb); +end; + +function gui_pixeltorgb(pixel: pixelty): longword; +begin + result:= swaprgb(pixel); +end; + +function gui_graytopixel(gray: byte): pixelty; +var + lwo1: longword; +begin + lwo1:= gray; + result:= lwo1 or (lwo1 shl 8) or (lwo1 shl 16); +end; + +function gui_pixeltogray(pixel: pixelty): byte; +begin + result:= ((pixel and $ff) + ((pixel and $ff00) shr 8) + + ((pixel and $ff0000) shr 16)) div 3; +end; + +function winmousekeyflagstoshiftstate(keys: longword): shiftstatesty; +begin + result:= []; + if keys and mk_control <> 0 then begin + include(result,ss_ctrl); + end; + if keys and mk_lbutton <> 0 then begin + include(result,ss_left); + end; + if keys and mk_mbutton <> 0 then begin + include(result,ss_middle); + end; + if keys and mk_rbutton <> 0 then begin + include(result,ss_right); + end; + if keys and mk_shift <> 0 then begin + include(result,ss_shift); + end; + if getkeystate(vk_menu) < 0 then begin + include(result,ss_alt); + end; +end; + +function shiftstatetowinmousekeyflags(shiftstate: shiftstatesty): longword; +begin + result:= 0; + if ss_ctrl in shiftstate then begin + result:= result or mk_control; + end; + if ss_left in shiftstate then begin + result:= result or mk_lbutton; + end; + if ss_middle in shiftstate then begin + result:= result or mk_mbutton; + end; + if ss_right in shiftstate then begin + result:= result or mk_rbutton; + end; + if ss_shift in shiftstate then begin + result:= result or mk_shift; + end; +end; + +function winmousepostopoint(pos: longword): pointty; +begin + result.x:= smallint(loword(pos)); + result.y:= smallint(hiword(pos)); +end; + +function pointtowinmousepos(pos: pointty): longword; +begin + result:= word(pos.x) + (word(pos.y) shl 16); +end; + +function winkeytokey(key: longword; lparam: longword; + var shift: shiftstatesty): keyty; +var + second: boolean; +begin + second:= mapvirtualkey(key,mapvk_vk_to_vsc) <> (lparam shr 16) and $1ff; + + case key of + vk_back: result:= key_backspace; + vk_tab: begin + if ss_shift in shift then begin + result:= key_backtab; + end + else begin + result:= key_tab; + end; + end; + vk_clear: result:= key_clear; + vk_return: begin + result:= key_return; + if second then begin + include(shiftstate,ss_second); + end; + end; + vk_shift: begin + result:= key_shift; + if second then begin + include(shiftstate,ss_second); + end; + end; + vk_control: begin + result:= key_control; + if second then begin + include(shiftstate,ss_second); + end; + end; + vk_menu: begin + result:= key_alt; + if second then begin + include(shiftstate,ss_second); + end; + end; + vk_pause: result:= key_pause; + vk_capital: result:= key_capslock; + vk_escape: result:= key_escape; + vk_space: result:= key_space; + vk_prior: result:= key_pageup; + vk_next: result:= key_pagedown; + vk_end: result:= key_end; + vk_home: result:= key_home; + vk_left: result:= key_left; + vk_up: result:= key_up; + vk_right: result:= key_right; + vk_down: result:= key_down; + // vk_select: result:= key_select; + vk_execute: result:= key_sysreq; + vk_snapshot: result:= key_print; + vk_insert: result:= key_insert; + vk_delete: result:= key_delete; + vk_help: result:= key_help; + longword('0')..longword('9'): result:= keyty(key); + longword('A')..longword('Z'): result:= keyty(key); + vk_lwin: result:= key_super; + vk_rwin: begin + result:= key_super; + include(shiftstate,ss_second); + end; + vk_apps: result:= key_menu; + vk_oem_plus: result:= key_plus; + vk_oem_comma: result:= key_comma; + vk_oem_minus: result:= key_minus; + vk_oem_period: result:= key_period; + vk_numpad0..vk_numpad9: begin + result:= keyty(longword(key_0) + key - vk_numpad0); + include(shiftstate,ss_second); + end; + vk_add: begin + result:= key_plus; + include(shiftstate,ss_second); + end; + vk_separator: begin + result:= key_comma; + include(shiftstate,ss_second); + end; + vk_subtract: begin + result:= key_minus; + include(shiftstate,ss_second); + end; + vk_decimal: begin + result:= key_decimal; + include(shiftstate,ss_second); + end; + vk_multiply: begin + result:= key_asterisk; + include(shiftstate,ss_second); + end; + vk_divide: begin + result:= key_slash; + include(shiftstate,ss_second); + end; + vk_f1..vk_f24: result:= keyty(longword(key_f1) + key - vk_f1); + vk_numlock: result:= key_numlock; + vk_scroll: result:= key_scrolllock; + + else begin + result:= key_unknown; + end; + end; +end; + +function winkeystatetoshiftstate(keystate: longword): shiftstatesty; +begin + result:= []; + if $20000000 and keystate <> 0 then begin + include(result,ss_alt); + end; + if getkeystate(vk_shift) < 0 then begin + include(result,ss_shift); + end; + if getkeystate(vk_control) < 0 then begin + include(result,ss_ctrl); + end; + if getkeystate(vk_lbutton) < 0 then begin + include(result,ss_left); + end; + if getkeystate(vk_mbutton) < 0 then begin + include(result,ss_middle); + end; + if getkeystate(vk_rbutton) < 0 then begin + include(result,ss_right); + end; +end; + +function wheelkeystatetoshiftstate(keystate: longword): shiftstatesty; +var + wo1: word; +begin + result:= []; + wo1:= loword(keystate); + if mk_control and wo1 <> 0 then begin + include(result,ss_ctrl); + end; + if mk_lbutton and wo1 <> 0 then begin + include(result,ss_left); + end; + if mk_mbutton and wo1 <> 0 then begin + include(result,ss_middle); + end; + if mk_rbutton and wo1 <> 0 then begin + include(result,ss_right); + end; + if mk_shift and wo1 <> 0 then begin + include(result,ss_shift); + end; + if getkeystate(vk_menu) < 0 then begin + include(result,ss_alt); + end; +end; + +function windowvisible(handle: hwnd): boolean; +var + rect1: trect; +begin + windows.getclientrect(handle,rect1); + result:= iswindowvisible(handle) and + not ((rect1.Left = 0) and (rect1.Top = 0) + and (rect1.Bottom = 0) and (rect1.Right = 0)) and + (gui_getwindowsize(handle) <> wsi_minimized); +end; + +procedure checkmousewindow(window: hwnd; const pos: pointty); forward; + +procedure mouseidleproc(ahwnd: hwnd; uMsg: longword; idEvent: ptruint; + dwTime: longword); stdcall; +var + po1: tpoint; + win1: hwnd; +begin + windows.KillTimer(0,mouseidletimer); + mouseidletimer:= 0; + if mousewindow <> 0 then begin + if windows.GetCursorPos(po1) then begin + win1:= windowfrompoint(po1); + if (win1 <> mousewindow) and (getparent(win1) <> mousewindow) then begin + eventlist.add(twindowevent.create(ek_leavewindow,mousewindow)); + end + else begin + if windows.screentoclient(mousewindow,po1) then begin + checkmousewindow(mousewindow,pointty(po1)); + end; + end; + end; + end; +end; + +procedure killmouseidletimer(restart: boolean = false); +begin + if mouseidletimer <> 0 then begin + windows.KillTimer(0,mouseidletimer); + end; + if restart then begin + mouseidletimer:= windows.settimer(0,0,mouseidletime,@mouseidleproc); + end + else begin + mouseidletimer:= 0; + end; +end; + +procedure checkmousewindow(window: hwnd; const pos: pointty); +var + rect1: trect; +begin + killmouseidletimer(true); + if (window <> 0) then begin + windows.getclientrect(window,rect1); + if (pos.x < 0) or (pos.x >= rect1.Right) or (pos.y < 0) or + (pos.y > rect1.Bottom) then begin + window:= 0; + end + end; + if mousewindow <> window then begin + if mousewindow <> 0 then begin + eventlist.add(twindowevent.create(ek_leavewindow,mousewindow)); + end; + if window <> 0 then begin + eventlist.add(twindowevent.create(ek_enterwindow,window)); + end; + mousewindow:= window; + end + else begin + if mousecursor <> 0 then begin + windows.SetCursor(mousecursor); //possible missed et_exitwindow + end; + end; +end; + +function gui_movewindowrect(id: winidty; const dist: pointty; + const rect: rectty): guierrorty; +var + rect1,rect2: rectty; +begin + rect1:= rect; + recttowinrect(rect1); + if iswin95 then begin + rect2.x:= -32000; //trect + rect2.y:= -32000; + rect2.cx:= 32000; + rect2.cy:= 32000; + end + else begin + rect2.x:= -100000; //trect + rect2.y:= -100000; + rect2.cx:= 100000; + rect2.cy:= 100000; + end; + {$ifdef FPC} + winscrollwindowex(id,dist.x,dist.y,@rect1,@rect2,0,nil,sw_invalidate); + {$else} + scrollwindowex(id,dist.x,dist.y,@rect1,@rect2,0,nil,sw_invalidate); + {$endif} + result:= gue_ok; +end; + +procedure getframe(const outerrect,innerrect: trect; out frame: framety); +var + int1: integer; +begin + int1:= (outerrect.Right - outerrect.Left - innerrect.Right + + innerrect.left) div 2; //i hope so + with frame do begin + left:= int1; + bottom:= int1; + right:= int1; + top:= outerrect.Bottom - outerrect.top - + innerrect.Bottom + innerrect.Top - int1; + end; +end; + +function getclientrect(hwnd: hwnd; windowrect: prectty = nil): rectty; + //screen origin +var + rect1,rect2: trect; + frame: framety; +begin + if windows.GetWindowRect(hwnd,rect1) then begin + if windows.getclientrect(hwnd,rect2) then begin + getframe(rect1,rect2,frame); + if windowrect = nil then begin + result.x:= rect1.left + frame.left; + result.y:= rect1.top + frame.top; + result.size:= sizety(rect2.BottomRight); + end + else begin + with windowrect^ do begin + result.x:= x + frame.left; + result.y:= y + frame.top; + result.cx:= cx - frame.left - frame.right; + result.cy:= cy - frame.top - frame.bottom; + end; + end; + end + else begin + result:= nullrect; + end; + end + else begin + result:= nullrect; + end; +end; + +procedure getwindowrectpa(id: winidty; out rect: rectty; out origin: pointty); + //parent origin +var +// rect1: rectty; + win1: winidty; +begin + rect:= getclientrect(id); + win1:= getancestor(id,ga_parent); + if win1 <> 0 then begin + origin:= getclientrect(win1).pos; + subpoint1(rect.pos,origin); + end + else begin + origin:= nullpoint; + end; +end; + +function gui_getwindowrect(id: winidty; out rect: rectty): guierrorty; + //screen origin +begin + rect:= getclientrect(id); + result:= gue_ok; +end; + +function gui_getwindowpos(id: winidty; out pos: pointty): guierrorty; +var + rect1: trect; +begin + result:= gue_error; + if windows.GetWindowRect(id,rect1) then begin + pos.x:= rect1.left; + pos.y:= rect1.top; + result:= gue_ok; + end; +end; + +var + configuredwindow: winidty; + +procedure postconfigureevent(const id: winidty); +var + rect1: rectty; + pt1: pointty; +begin + configuredwindow:= id; + if gui_getwindowsize(id) <> wsi_minimized then begin + getwindowrectpa(id,rect1,pt1); + {$ifdef mse_debugconfigure} + debugwindow('*postconfigureevent x:'+inttostr(rect1.x)+' y:'+inttostr(rect1.y)+ + ' cx:'+inttostr(rect1.cx)+' cy:'+inttostr(rect1.cy)+ + ' ox:'+inttostr(pt1.x)+' oy:'+inttostr(pt1.y)+' ',id); + {$endif} + eventlist.add(twindowrectevent.create(ek_configure,id, + rect1,pt1)); + end + else begin + eventlist.add(twindowevent.create(ek_hide,id)); + end; +end; + +function gui_reposwindow(id: winidty; const rect: rectty): guierrorty; +var + rect1,rect2: trect; + arect: rectty; + frame: framety; +begin + result:= gue_resizewindow; + if windows.getwindowrect(id,rect1) then begin + if windows.GetclientRect(id,rect2) then begin + getframe(rect1,rect2,frame); + arect:= inflaterect(rect,frame); + {$ifdef mse_debugconfigure} + debugwindow('*reposwindow rect x:'+inttostr(rect.x)+' y:'+inttostr(rect.y)+ + ' cx:'+inttostr(rect.cx)+' cy:'+inttostr(rect.cy)+' ',id); + debugwriteln(' setwindowpos x:'+inttostr(arect.x)+' y:'+inttostr(arect.y)+ + ' cx:'+inttostr(arect.cx)+' cy:'+inttostr(arect.cy)+ + ' ancestor:'+inttostr(getancestor(id,ga_parent))+ + ' root:'+inttostr(getancestor(id,ga_root))); + {$endif} + configuredwindow:= 0; + if windows.SetWindowPos(id,0,arect.x,arect.y,arect.cx,arect.cy, + swp_nozorder or swp_noactivate) then begin + {$ifdef mse_debugconfigure} + windows.getwindowrect(id,@arect); + winrecttorect(arect); + debugwriteln(' getwindowpos x:'+inttostr(arect.x)+' y:'+inttostr(arect.y)+ + ' cx:'+inttostr(arect.cx)+' cy:'+inttostr(arect.cy)); + {$endif} + result:= gue_ok; + end; + end; + if configuredwindow <> id then begin + postconfigureevent(id); + end; + end; +end; + +function gui_getdecoratedwindowrect(id: winidty; out arect: rectty): guierrorty; +begin + if windows.getwindowrect(id,trect(arect)) then begin + winrecttorect(arect); + result:= gue_ok; + end + else begin + result:= gue_error; + end; +end; + +function gui_setdecoratedwindowrect(id: winidty; const rect: rectty; + out clientrect: rectty): guierrorty; +//var +// rect1: rectty; +begin + result:= gue_resizewindow; + clientrect:= rect; + if windows.SetWindowPos(id,0,rect.x,rect.y,rect.cx,rect.cy, + swp_nozorder or swp_noactivate) then begin + clientrect:= getclientrect(id); + result:= gue_ok; + end +end; + +function gui_setembeddedwindowrect(id: winidty; const rect: rectty): guierrorty; +begin + result:= gue_resizewindow; + if windows.SetWindowPos(id,0,rect.x,rect.y,rect.cx,rect.cy, + swp_nozorder or swp_noactivate) then begin + result:= gue_ok; + end +end; + +var + mousewheelpos: integer; + sizingwindow: hwnd; + eventlooping: integer; + escapepressed: boolean; + +function nestedwindowproc(): boolean; //window frame clicked +begin + result:= eventlooping > 0; +end; + +procedure gui_wakeup; +begin + windows.postmessage(applicationwindow,wakeupmessage,0,0); +// windows.postthreadmessage(mainthread,wakeupmessage,0,0); +end; + +function gui_postevent(event: tmseevent): guierrorty; +//var +// int1: integer; +begin + if windows.postmessage(applicationwindow,msemessage,ptruint(event),0) then begin + result:= gue_ok; + end + else begin + result:= gue_postevent; + end; +{ + if eventlooping > 0 then begin + result:= gue_ok; + eventlist.add(event); //threadmessages are lost while window sizing + end + else begin + result:= gue_postevent; + for int1:= 0 to 15 do begin + if windows.postthreadmessage(mainthread,msemessage,longword(event),0) then begin + result:= gue_ok; + break; + end; + sys_threadschedyield; + end; + end; + } +end; + +function gui_escapepressed: boolean; +begin + result:= escapepressed; +end; + +procedure gui_resetescapepressed; +begin + escapepressed:= false; +end; + +function WindowProc(ahWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; + + function checkbutton(const amessage: UINT): mousebuttonty; + begin + result:= mb_none; + case amessage of + wm_lbuttondown,wm_lbuttonup: result:= mb_left; + wm_mbuttondown,wm_mbuttonup: result:= mb_middle; + wm_rbuttondown,wm_rbuttonup: result:= mb_right; + end; + end; + + procedure inittraycallback(const reposition: boolean; out cursorpos: pointty; + out shiftstate: uint); + var + rect1: rectty; + pt1: pointty; + begin + shiftstate:= 0; + if getkeystate(vk_control) < 0 then begin + shiftstate:= shiftstate or mk_control; + end; + if getkeystate(vk_shift) < 0 then begin + shiftstate:= shiftstate or mk_shift; + end; + if getkeystate(vk_lbutton) < 0 then begin + shiftstate:= shiftstate or mk_lbutton; + end; + if getkeystate(vk_mbutton) < 0 then begin + shiftstate:= shiftstate or mk_mbutton; + end; + if getkeystate(vk_rbutton) < 0 then begin + shiftstate:= shiftstate or mk_rbutton; + end; + + windows.getcursorpos(tpoint(pt1)); + gui_getwindowrect(ahwnd,rect1); + {$ifdef mse_debugconfigure} + debugwindow('*inittraycallback ',ahwnd); + debugwriteln(' cursor x:'+inttostr(pt1.x)+' y:'+inttostr(pt1.y)); + {$endif} + cursorpos.x:= rect1.cx div 2; + cursorpos.y:= rect1.cy div 2; + if reposition then begin + gui_reposwindow(ahwnd,makerect(pt1.x-cursorpos.x,pt1.y-cursorpos.y, + rect1.cx,rect1.cy)); + //shift widget center to mousepos +// setforegroundwindow(applicationwindow); + end; + end; + +const + wheelstep = 120; +var + rect1,rect2,rect3: rectty; + pt1{,pt2}: pointty; + size1: sizety; + button: mousebuttonty; + key1: keyty; + str1: string; +// int1: integer; + bo1: boolean; + sysevent: syseventty; + shiftstate1: uint; + imc: himc; + imminfo: compositionform; + ev1: tmseevent; +label + nodefwindowproclab; +begin + if application.ismainthread then begin + sysevent.hwnd:= ahwnd; + sysevent.umsg:= msg; + sysevent.wparam:= wparam; + sysevent.lparam:= lparam; + sysevent.lresult:= 0; + bo1:= false; + tapplication1(application).sysevent(ahwnd,sysevent,bo1); + if bo1 then begin + result:= sysevent.lresult; + exit; + end; + end; + result:= 1; + case msg of + msemessage: begin + eventlist.add(tmseevent(wparam)); + exit; + end; + wakeupmessage: begin + eventlist.add(nil); + exit; + end; + timermessage: begin + eventlist.add(tmseevent.create(ek_timer)); + exit; + end; + traycallbackmessage: begin + case lparam and $ffff of + wm_lbuttondown,wm_mbuttondown,wm_rbuttondown: begin + inittraycallback(true,pt1,shiftstate1); + windowproc(ahwnd,lparam and $ffff,shiftstate1,pointtowinmousepos(pt1)); + end; + wm_lbuttonup,wm_mbuttonup,wm_rbuttonup: begin + inittraycallback(true,pt1,shiftstate1); + windowproc(ahwnd,lparam and $ffff,shiftstate1,pointtowinmousepos(pt1)); + end; + end; + end; + wm_ime_char: begin + if iswin95 then begin + str1:= char(wparam); + if wparam and $ff00 <> 0 then begin + str1:= char(wparam shr 8) + str1; + end; + charbuffer:= charbuffer + msestring(str1); + end + else begin + charbuffer:= charbuffer + ucs4tostring(wparam); + end; + eventlist.add(tkeyevent.create(ahwnd,false,key_none,key_none,shiftstate, + charbuffer,timestamp)); + charbuffer:= ''; + end; + wm_close: begin + if ahwnd = applicationwindow then begin + eventlist.add(tmseevent.create(ek_terminate)); + end + else begin + eventlist.add(twindowevent.create(ek_close,ahwnd)); + result:= 0; + end; + exit; + end; + wm_queryendsession: begin + canshutdown:= 1; + eventlist.add(tmseevent.create(ek_terminate)); + tapplication1(application).eventloop; + result:= canshutdown; + exit; + end; + wm_destroy: begin + {$ifdef mse_debugwindowfocus} + debugwindow('wm_destroy ',ahwnd); + {$endif} + {$ifdef mse_debugwindowdestroy} + debugwindow('*wm_destroy ',ahwnd); + {$endif} + windowdestroyed(ahwnd); + eventlist.add(twindowevent.create(ek_destroy,ahwnd)); + end; + wm_setfocus: begin + if (ahwnd = applicationwindow) and (lastfocuswindow <> 0) then begin + {$ifdef mse_debugwindowfocus} + debugwindow('wm_setfocus applicationwindow ',ahwnd); + {$endif} + if windowvisible(lastfocuswindow) then begin + setfocus(lastfocuswindow); + end + else begin + if application.activewindow <> nil then begin + setfocus(application.activewindow.winid); + end + else begin + if application.mainwindow <> nil then begin + setfocus(application.mainwindow.winid); + end; + end; + end; + end + else begin + if windowvisible(ahwnd) then begin + {$ifdef mse_debugwindowfocus} + debugwindow('wm_setfocus ',ahwnd); + {$endif} + lastfocuswindow:= ahwnd; + eventlist.add(twindowevent.create(ek_focusin,ahwnd)); + end{$ifndef mse_debugwindowfocus};{$endif} + {$ifdef mse_debugwindowfocus} + else begin + debugwindow('wm_setfocus invisible ',ahwnd); + end; + {$endif} + end; + end; + wm_killfocus: begin + ev1:= twindowevent.create(ek_focusout,ahwnd); + eventlist.add(ev1); + {$ifdef mse_debugwindowfocus} + debugwindow('wm_killfocus '+hextostr(ev1)+' ',ahwnd); + {$endif} + end; + wm_paint: begin + if getupdaterect(ahwnd,trect(rect1),false) then begin + winrecttorect(rect1); + eventlist.add(twindowrectevent.create(ek_expose,ahwnd,rect1,nullpoint)); +// exit; + end; + end; + wm_entersizemove: begin + sizingwindow:= ahwnd; + end; + wm_exitsizemove: begin + sizingwindow:= 0; + end; + wm_sizing: begin + rect1:= rectty(prect(lparam)^); + winrecttorect(rect1); + rect2:= getclientrect(ahwnd,@rect1); + rect3:= rect2; + application.checkwindowrect(ahwnd,rect2); + size1:= subsize(rect3.size,rect2.size); + if (wparam = wmsz_topleft) or (wparam = wmsz_left) or + (wparam = wmsz_bottomleft) then begin + inc(rect1.x,size1.cx); + end; + dec(rect1.cx,size1.cx); + if (wparam = wmsz_topleft) or (wparam = wmsz_top) or + (wparam = wmsz_topright) then begin + inc(rect1.y,size1.cy); + end; + dec(rect1.cy,size1.cy); + recttowinrect(rect1); + rect2:= rectty(prect(lparam)^); + rectty(prect(lparam)^):= rect1; + if not rectisequal(rect2,rectty(prect(lparam)^)) then begin + exit; + end; + end; + wm_move,wm_size: begin + postconfigureevent(ahwnd); + end; + wm_queryopen: begin + eventlist.add(twindowevent.create(ek_show,ahwnd)); + end; + wm_windowposchanged: begin + with pwindowpos(lparam)^ do begin + if swp_hidewindow and flags <> 0 then begin + {$ifdef mse_debugwindowfocus} + debugwindow('wm_windowposchanged hide ',ahwnd); + {$endif} + eventlist.add(twindowevent.create(ek_hide,ahwnd)); + end; + if (swp_showwindow and flags <> 0) and (gui_getwindowsize(ahwnd) <> wsi_minimized) then begin + {$ifdef mse_debugwindowfocus} + debugwindow('wm_windowposchanged show ',ahwnd); + {$endif} + eventlist.add(twindowevent.create(ek_show,ahwnd)); + end; + if (((swp_nomove or swp_nosize) and flags <> (swp_nomove or swp_nosize)) or + (flags and swp_nozorder = 0)) and + windowvisible(ahwnd) then begin + postconfigureevent(ahwnd); +// getwindowrectpa(ahwnd,rect1,pt1); +// eventlist.add(twindowrectevent.create(ek_configure,ahwnd,rect1,pt1)); + result:= 0; + exit; + end; + end; + end; + wm_mousewheel: begin + if mousewindow <> 0 then begin + shiftstate:= wheelkeystatetoshiftstate(wparam); + pt1:= winmousepostopoint(lparam); + subpoint1(pt1,getclientrect(mousewindow).pos); + inc(mousewheelpos,smallint(hiword(wparam))); + while mousewheelpos >= wheelstep do begin + eventlist.add(tmouseevent.create(mousewindow,false,mb_none,mw_up,pt1, + winmousekeyflagstoshiftstate(wparam),timestamp)); + dec(mousewheelpos,wheelstep); + end; + while mousewheelpos <= -wheelstep do begin + eventlist.add(tmouseevent.create(mousewindow,false,mb_none,mw_down,pt1, + winmousekeyflagstoshiftstate(wparam),timestamp)); + inc(mousewheelpos,wheelstep); + end; + result:= 0; + exit; + end; + end; + wm_mousemove, + wm_lbuttondown,wm_mbuttondown,wm_rbuttondown, + wm_lbuttonup,wm_mbuttonup,wm_rbuttonup: begin + pt1:= winmousepostopoint(lparam); + checkmousewindow(ahwnd,pt1); + button:= checkbutton(msg); + eventlist.add(tmouseevent.create(ahwnd, + (msg = wm_lbuttonup) or (msg = wm_mbuttonup) or (msg = wm_rbuttonup), + button,mw_none,pt1, + winmousekeyflagstoshiftstate(wparam),timestamp)); + result:= 0; + exit; + end; + wm_keydown,wm_syskeydown: begin + shiftstate:= winkeystatetoshiftstate(lparam); + if lparam and $40000000 <> 0 then begin + include(shiftstate,ss_repeat); + end; + key1:= winkeytokey(wparam,lparam,shiftstate); + if key1 = key_escape then begin + escapepressed:= true; + end; + eventlist.add(tkeyevent.create(ahwnd,false,key1,key1,shiftstate, + charbuffer,timestamp)); + charbuffer:= ''; + if (shiftstate = []) and (key1 = key_f10) then begin + goto nodefwindowproclab; //no windows menu activation + end; + end; + wm_keyup,wm_syskeyup: begin + shiftstate:= winkeystatetoshiftstate(lparam); + key1:= winkeytokey(wparam,lparam,shiftstate); + if charbuffer <> '' then begin + eventlist.add(tkeyevent.create(ahwnd,false,key_none,key_none,shiftstate, + charbuffer,timestamp)); + charbuffer:= ''; + end; + eventlist.add(tkeyevent.create(ahwnd,true,key1,key1,shiftstate,'',timestamp)); + end; + wm_ime_startcomposition: begin + if hasimm32 and (application.activewidget <> nil) and + application.activewidget.hascaret then begin + imc:= immgetcontext(ahwnd); + fillchar(imminfo,sizeof(imminfo),0); + with imminfo,application do begin + dwstyle:= cfs_point; + ptcurrentpos.x:= caret.pos.x + caret.origin.x; + ptcurrentpos.y:= caret.pos.y + caret.origin.y{ + caret.size.cy}; +// ptcurrentpos.x:= caret.pos.x + activewidget.rootpos.x; +// ptcurrentpos.y:= activewidget.rootpos.y + activewidget.bounds_cy; + immsetcompositionwindow(imc,@imminfo); + end; + immreleasecontext(ahwnd,imc); + end; + end; + end; + if iswin95 then begin + result:= defwindowproca(ahwnd,msg,wparam,lparam); + end + else begin + result:= defwindowprocw(ahwnd,msg,wparam,lparam); + end; +nodefwindowproclab: + if ahwnd = sizingwindow then begin + inc(eventlooping); + try + tapplication1(application).eventloop(true); + finally + dec(eventlooping); + end; + end; +end; + +function childWindowProc(ahWnd: HWND; Msg: UINT; wParam: WPARAM; + lParam: LPARAM): LRESULT; stdcall; +var + parent: hwnd; + pt1: pointty; + rect1: trect; + rect2: rectty; +begin + parent:= getparent(ahwnd); + case msg of + wm_destroy: begin + windowdestroyed(ahwnd); + eventlist.add(twindowevent.create(ek_destroy,ahwnd)); + end; + wm_mousemove, + wm_lbuttondown,wm_mbuttondown,wm_rbuttondown, + wm_lbuttonup,wm_mbuttonup,wm_rbuttonup, + wm_mousewheel: begin + getwindowrect(ahwnd,rect1); + rect2:= getclientrect(parent); + pt1.x:= rect1.left - rect2.x; + pt1.y:= rect1.top - rect2.y; + pt1:= addpoint(winmousepostopoint(lparam),pt1); + result:= windowproc(parent,msg,wparam,pointtowinmousepos(pt1)); + exit; + end; + end; + if iswin95 then begin + result:= defwindowproca(ahwnd,msg,wparam,lparam); + end + else begin + result:= defwindowprocw(ahwnd,msg,wparam,lparam); + end; +end; + +var + sdndthread: threadty; + +procedure beginsdndwrite(const athread: threadty); +begin + application.lock; + sdndthread:= athread; + application.unlock; +end; + +procedure endsdndwrite; +begin + application.lock; + sdndthread:= 0; + application.unlock; +end; + +procedure dispatchevents; +var + msg,msg1: tmsg; + str1: string; +begin + if eventlooping > 0 then begin + exit; + end; + if iswin95 then begin + while peekmessagea(msg,0,0,0,pm_remove) do begin + if sdndthread <> 0 then begin + postthreadmessagea(sdndthread,msg.message,msg.wparam,msg.lparam); + end; + with msg do begin + case message of + destroymessage: begin + windows.destroywindow(msg.wparam); + end; + wm_keydown,wm_keyup,wm_syskeydown,wm_syskeyup: begin + translatemessage(msg); + str1:= ''; + while peekmessagea(msg1,msg.hwnd,wm_char,wm_char,pm_remove) do begin + str1:= str1 + char(msg1.wparam); + end; + while peekmessagea(msg1,msg.hwnd,wm_syschar,wm_syschar,pm_remove) do begin + str1:= str1 + char(msg1.wparam); + end; + charbuffer:= charbuffer + msestring(str1); + dispatchmessagea(msg); + end + else begin + dispatchmessagea(msg); + end; + end; + end; + end; + end + else begin + while peekmessagew(msg,0,0,0,pm_remove) do begin + if sdndthread <> 0 then begin + postthreadmessagew(sdndthread,msg.message,msg.wparam,msg.lparam); + end; + with msg do begin + case message of + destroymessage: begin + {$ifdef mse_debugwindowdestroy} + debugwindow('*destroymessage ',msg.wparam); + {$endif} + windows.destroywindow(msg.wparam); + end; + wm_keydown,wm_keyup,wm_syskeydown,wm_syskeyup: begin + translatemessage(msg); + while peekmessagew(msg1,msg.hwnd,wm_char,wm_char,pm_remove) do begin + charbuffer:= charbuffer + msechar(msg1.wparam); + end; + while peekmessagew(msg1,msg.hwnd,wm_syschar,wm_syschar,pm_remove) do begin + charbuffer:= charbuffer + msechar(msg1.wparam); + end; + dispatchmessagew(msg); + end + else begin + dispatchmessagew(msg); + end; + end; + end; + end; + end; +end; + +function gui_hasevent: boolean; +begin + dispatchevents; + result:= eventlist.count > 0; +end; + +function gui_getevent: tmseevent; +begin + result:= nil; + while true do begin + dispatchevents; + if eventlist.count > 0 then begin + result:= tmseevent(eventlist.getfirst); + break; + end + else begin + if not application.unlock then begin + guierror(gue_notlocked); + end; + windows.waitmessage; + application.lock; + end; + end; +end; + +procedure gui_disconnectmaineventqueue(); //called by application.lock() +begin + //dummy +end; + +procedure gui_connectmaineventqueue(); //called by application.unlock() +begin + //dummy +end; + +function gui_addpollfd(var id: int32; const afd: int32; + const aflags: pollflagsty; + const acallback: pollcallbackty = nil; + const adata: pointer = nil): guierrorty; +begin + result:= gue_notimplemented; +end; + +function gui_removepollfd(const id: int32): guierrorty; +begin + result:= gue_notimplemented; +end; + +function gui_setpollfdactive(const id: int32; + const aactive: boolean): guierrorty; +begin + result:= gue_notimplemented; +end; + +function createapphandle(out id: winidty): guierrorty; +var + str1: string; + menu1: hmenu; +begin + str1:= ansistring(application.applicationname); + id:= windows.CreateWindow(widgetclassname,pchar(str1), + WS_POPUP or WS_CAPTION or WS_CLIPSIBLINGS or + WS_SYSMENU or WS_MINIMIZEBOX,0,0,0,0,0,0,hinstance,nil); +{$ifdef mse_debugwindowdestroy} + debugwindow('ceateapphandle ',id); +{$endif} + menu1:= getsystemmenu(id,false); + deletemenu(menu1,sc_maximize,mf_bycommand); + deletemenu(menu1,sc_size,mf_bycommand); + deletemenu(menu1,sc_move,mf_bycommand); + showwindow(id,sw_shownoactivate); + +// id:= windows.CreateWindowex(ws_ex_appwindow,widgetclassname,pchar(str1), +// ws_overlappedwindow,0,0,0,0,0,0,hinstance,nil); + if id = 0 then begin + result:= gue_createwindow; + end + else begin + result:= gue_ok; + end; +end; + +function gui_settransientfor(var awindow: windowty; + const transientfor: winidty): guierrorty; +begin + with awindow,win32windowty(platformdata).d do begin + if not istaskbar then begin + {$ifdef cpu64} + setwindowlongptr(id,gwlp_hwndparent,transientfor); + //no taskbar widget if called! + {$else} + setwindowlong(id,gwl_hwndparent,transientfor); //no taskbar widget if called! + {$endif} +// transientfor can be destroyed + end; + end; + result:= gue_ok; +end; + +function gui_windowatpos(const pos: pointty): winidty; +begin + result:= windowfrompoint(tpoint(pos)); +end; + +function gui_setsizeconstraints(id: winidty; const min,max: sizety): guierrorty; +begin + result:= gue_ok; //nothing to do on win32 +end; + +function gui_setwindowgroup(id: winidty; group: winidty): guierrorty; +begin + result:= gue_ok; +end; + +function gui_createwindow(const rect: rectty; + var options: internalwindowoptionsty; + var awindow: windowty): guierrorty; +var + windowstyle,windowstyleex,ca2: longword; + rect1: rectty; + classname: string; + ownerwindow: winidty; +begin + fillchar(awindow,sizeof(awindow),0); + with awindow,win32windowty(awindow.platformdata).d,options do begin + ownerwindow:= applicationwindow; + windowstyleex:= 0; + { + if wo_popup in options then begin //does not work in win2000 + windowstyleex:= windowstyleex or ws_ex_noactivate; + end; + } + if wo_notaskbar in options then begin + showwindow(applicationwindow,sw_hide); + end; + if options * noframewindowtypes <> [] then begin + windowstyle:= ws_popup; +// windowstyleex:= windowstyleex or ws_ex_toolwindow; + end + else begin + if wo_message in options then begin + windowstyle:= ws_overlappedwindow; + windowstyleex:= windowstyleex or ws_ex_toolwindow; + end + else begin + windowstyle:= ws_overlappedwindow; + if wo_taskbar in options then begin + istaskbar:= true; + windowstyleex:= windowstyleex or ws_ex_appwindow; + showwindow(applicationwindow,sw_hide); + ownerwindow:= 0; + end; + end; + if wo_embedded in options then begin + windowstyle:= ws_child; + end; + end; + if pos = wp_default then begin + rect1.x:= integer(cw_usedefault); + rect1.y:= integer(cw_usedefault); + rect1.cx:= integer(cw_usedefault); + rect1.cy:= integer(cw_usedefault); + end + else begin + rect1:= rect; + end; + windowstyle:= windowstyle or ws_clipchildren; + if (transientfor <> 0) or (options * [wo_popup,wo_message,wo_notaskbar] <> []) then begin + if transientfor <> 0 then begin + ownerwindow:= transientfor; + end; + id:= windows.CreateWindowex(windowstyleex,widgetclassname,nil,windowstyle, + rect1.x,rect1.y,rect1.cx,rect1.cy,ownerwindow{transientfor},0,hinstance,nil); + if transientfor = 0 then begin +{$ifdef mse_debugzorder} + debugwriteln('gui_createwindow hwnd_top '+hextostr(id)); +{$endif} + setwindowpos(id,hwnd_top,0,0,0,0,swp_noactivate or swp_nomove or + swp_nosize or swp_noownerzorder); + end; + end + else begin + if parent <> 0 then begin + ca2:= parent; + windowstyle:= ws_child; + classname:= childwidgetclassname; + end + else begin + ca2:= ownerwindow; + classname:= widgetclassname; + end; + id:= windows.CreateWindowex(windowstyleex,pchar(classname),nil, + windowstyle,rect1.x,rect1.y,rect1.cx,rect1.cy,ca2,0,hinstance,nil); + if setgroup and (groupleader = 0) or (wo_groupleader in options) then begin + groupleaderwindow:= id; + end; + end; + if id = 0 then begin + result:= gue_createwindow; + end + else begin +{$ifdef mse_debugwindowdestroy} + debugwindow('gui_createwindow ',id); +{$endif} +{$ifdef mse_debuggdi} + inc(windowcount); +{$endif} + if not (pos = wp_default) and (parent = 0) then begin + result:= gui_reposwindow(id,rect); + end + else begin + result:= gue_ok; + end; + end; + if icon <> 0 then begin + gui_setwindowicon(id,icon,iconmask); + if (groupleaderwindow = id) then begin + gui_setwindowicon(applicationwindow,icon,iconmask); + end; + end; + if wo_sysdnd in options then begin + regsysdndwindow(id); + end; + end; +end; + +function gui_getrootwindow(id: winidty = 0): winidty; +begin + result:= 0; +end; + +function gui_getparentwindow(const awindow: winidty): winidty; +begin +// result:= getparent(awindow); + result:= getancestor(awindow,ga_parent); +end; + +function gui_reparentwindow(const child: winidty; const parent: winidty; + const pos: pointty): guierrorty; +var + rect1: rectty; +begin + result:= gue_reparent; + if setparent(child,parent) <> 0 then begin + if parent = 0 then begin + result:= gui_getwindowrect(child,rect1); + if result = gue_ok then begin + rect1.pos:= pos; + result:= gui_reposwindow(child,rect1); + end; + end + else begin + if setwindowpos(child,0,pos.x,pos.y,0,0,swp_nosize or swp_nozorder or + swp_noownerzorder or swp_noactivate) then begin + result:= gue_ok; + end; + end; + end; +end; + +type + enumchildinfoty = record + childlist: winidarty; + count: integer; + parent: winidty; + end; + penumchildinfoty = ^enumchildinfoty; + +function getchildren(child: hwnd; data: lparam): winbool; stdcall; +begin + with penumchildinfoty(data)^ do begin + if gui_getparentwindow(child) = parent then begin + additem(childlist,winidty(child),count); + end; + end; + result:= true; +end; + +function gui_getchildren(const id: winidty; out children: winidarty): guierrorty; +var + info: enumchildinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + parent:= id; + enumchildwindows(id,@getchildren,ptruint(@info)); + setlength(childlist,count); + children:= childlist; + end; + result:= gue_ok; +end; + +function gui_setmainthread: guierrorty; //set mainthread to currentthread +begin + mainthread:= threadty(getcurrentthreadid); + result:= gue_ok; +end; + +function gui_getscreenrect(const id: winidty): rectty; //0 -> virtual screen +var + info: tmonitorinfo; +begin + info.cbsize:= sizeof(info); + if (id = 0) or not getmonitorinfo(monitorfromwindow(id,monitor_defaulttonearest), + @info) then begin + result.x:= getsystemmetrics(sm_xvirtualscreen); + result.y:= getsystemmetrics(sm_yvirtualscreen); + result.cx:= getsystemmetrics(sm_cxvirtualscreen); + result.cy:= getsystemmetrics(sm_cyvirtualscreen); + if result.cx = 0 then begin + result.cx:= getsystemmetrics(sm_cxscreen) + end; + if result.cy = 0 then begin + result.cy:= getsystemmetrics(sm_cyscreen) + end; + end + else begin + result:= rectty(info.rcmonitor); + winrecttorect(result); + end; +end; + +function gui_getworkarea(id: winidty): rectty; +var + info: tmonitorinfo; +begin +// if systemparametersinfo(spi_getworkarea,0,@result,0) then begin + info.cbsize:= sizeof(info); + if getmonitorinfo(monitorfromwindow(id,monitor_defaulttonearest), + @info) then begin + result:= rectty(info.rcwork); + winrecttorect(result); + end + else begin + result:= nullrect; + end; +end; + +procedure gui_getppmm(id: winidty; out appmmwidth,appmmheight: flo64); + //0.0 if not supported +var + dc: hdc; +begin + appmmwidth:= 0; + appmmheight:= 0; + dc:= getdc(id); + if dc <> 0 then begin + appmmwidth:= getdevicecaps(dc,logpixelsx) / 25.4; + appmmheight:= getdevicecaps(dc,logpixelsy) / 25.4; + releasedc(id,dc); + end; +end; + +const + NIF_MESSAGE = $00000001; + NIF_ICON = $00000002; + NIF_TIP = $00000004; + NIF_STATE = $00000008; + NIF_INFO = $00000010; + NIF_GUID = $00000020; + + NIIF_NONE = $00000000; + NIIF_INFO = $00000001; + NIIF_WARNING = $00000002; + NIIF_ERROR = $00000003; + NIIF_USER = $00000004; + NIIF_NOSOUND = $00000010; + NIIF_LARGE_ICON = $00000010; + NIIF_RESPECT_QUIET_TIME = $00000080; + NIIF_ICON_MASK = $0000000F; + + NIM_ADD = $00000000; + NIM_MODIFY = $00000001; + NIM_DELETE = $00000002; + NIM_SETFOCUS = $00000003; + NIM_SETVERSION = $00000004; + +type + iconunionty = record + case boolean of + false: (uTimeout: UINT); + true: (uVersion: UINT); // Used with Shell_NotifyIcon flag NIM_SETVERSION. + end; + NOTIFYICONDATAW_2 = record + cbSize: DWORD; + Wnd: HWND; + uID: UINT; + uFlags: UINT; + uCallbackMessage: UINT; + hIcon: HICON; + szTip: array [0..127] of widechar; + dwState: DWORD; + dwStateMask: DWORD; + szInfo: array[0..255] of widechar; + u: iconunionty; + szInfoTitle: array[0..63] of widechar; + dwInfoFlags: DWORD; + end; + +function traycommand(var child: windowty; + const command: integer; const flags: integer = 0; + const CallbackMessage: UINT = 0; + const Icon: HICON = 0; + const Tip: msestring = ''; + const State: DWORD = 0; + const StateMask: DWORD = 0; + const Info: msestring = ''; + const Timeout: UINT = 0; + const Version: UINT = 0; + const InfoTitle: msestring = ''; + const InfoFlags: DWORD = 0): guierrorty; + +// traycommand(child,command,flags,0,0,'',0,0,'',0,0,'',0); + + procedure movestr(const source: msestring; var dest; const acount: integer); + var + int1: integer; + begin + int1:= length(source); + if int1 > acount then begin + int1:= acount; + end; + move(source[1],dest,int1*sizeof(widechar)); + end; + +var +// dataa: notifyicondataa; + dataw: notifyicondataw_2; +// int1: integer; +begin + result:= checkshellinterface; + if result = gue_ok then begin + result:= gue_notraywindow; + if iswin95 then begin + end + else begin + fillchar(dataw,sizeof(dataw),0); + with dataw do begin + cbsize:= sizeof(dataw); + wnd:= child.id; + uflags:= flags; + uCallbackMessage:= CallbackMessage; + hIcon:= Icon; + movestr(tip,szTip,sizeof(szTip)); + dwState:= State; + dwStateMask:= StateMask; + movestr(Info,szInfo,256); + if command = nim_setversion then begin + u.uVersion:= version; + end + else begin + u.uTimeout:= Timeout; + end; + movestr(InfoTitle,szInfoTitle,64); + dwInfoFlags:= InfoFlags; + end; + if shell_notifyiconw(command,@dataw) then begin + result:= gue_ok; + end; + end; + end; +end; + +function docktotray(var child: windowty): guierrorty; +begin + result:= traycommand(child,nim_add,nif_message,traycallbackmessage); + if result = gue_ok then begin + result:= traycommand(child,nim_setversion,0,0,0,'',0,0,'',0,0); + end; +end; + +function undockfromtray(var child: windowty): guierrorty; +begin + result:= traycommand(child,nim_delete); +end; + +function gui_showsysdock(var awindow: windowty): guierrorty; +begin + result:= gui_hidewindow(awindow.id); +end; + +function gui_hidesysdock(var awindow: windowty): guierrorty; +begin + result:= gui_hidewindow(awindow.id); +end; + +function gui_docktosyswindow(var child: windowty; + const akind: syswindowty): guierrorty; +var + rect1: rectty; + pt1: pointty; +begin + gui_hidewindow(child.id); + if akind = sywi_none then begin + result:= undockfromtray(child); + getwindowrectpa(child.id,rect1,pt1); + result:= gui_reparentwindow(child.id,0,subpoint(rect1.pos,pt1)); + end + else begin + result:= gue_windownotfound; + case akind of + sywi_tray: begin + result:= docktotray(child); + end; + end; + end; +end; +{ +function gui_undockfromsyswindow(var child: windowty): guierrorty; + //hides window +begin + gui_hidewindow(child.id); + result:= undockfromtray(child); +end; +} +function gui_traymessage(var awindow: windowty; const message: msestring; + out messageid: longword; + const timeoutms: longword = 0): guierrorty; +var + int1: integer; +begin + messageid:= 1; + int1:= timeoutms; + if timeoutms = 0 then begin + int1:= bigint; + end; + result:= traycommand(awindow,nim_modify,nif_info,0,0,'',0,0, + message,int1,0,'',0); +end; + +function gui_canceltraymessage(var awindow: windowty; + const messageid: longword): guierrorty; +begin + result:= traycommand(awindow,nim_modify,nif_info,0,0,'',0,0, + '',0,0,'',0); +end; + +function gui_settrayicon(var awindow: windowty; + const icon,mask: pixmapty): guierrorty; +var + ico{,ico1}: hicon; +begin + ico:= 0; + if icon <> 0 then begin + ico:= composeicon(icon,mask); + if ico = 0 then begin + exit; + end; + end; + result:= traycommand(awindow,nim_modify,nif_icon,0,ico); +end; + +function gui_settrayhint(var awindow: windowty; + const hint: msestring): guierrorty; +begin + result:= traycommand(awindow,nim_modify,nif_tip,0,0,hint); +end; + +function gui_initcolormap: guierrorty; +begin + result:= gue_ok; //dummy +end; + +function gui_init: guierrorty; +const +// classstyle = cs_owndc; //not possible with layered windows + classstyle = 0; + childclassstyle = 0; +var + classinfow: twndclassw; + classinfoa: twndclassa; +// hres1: hresult; + +begin + mousewindow:= 0; + mousecursor:= 0; + applicationwindow:= 0; + fillchar(keystate,sizeof(keystate),0); + shiftstate:= []; + charbuffer:= ''; + gui_setmainthread; + eventlist:= tobjectqueue.create(true); + desktopwindow:= getdesktopwindow; + + msegdi32gdi.init; + + fillchar(classinfoa,sizeof(classinfoa),0); + if iswin95 then begin + with classinfoa do begin + lpszclassname:= childwidgetclassname; + lpfnwndproc:= @childwindowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= childclassstyle; + cbwndextra:= wndextrabytes; + end; + childwidgetclass:= registerclassa(classinfoa); + fillchar(classinfoa,sizeof(classinfoa),0); + with classinfoa do begin + lpszclassname:= widgetclassname; + lpfnwndproc:= @windowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= classstyle; + cbwndextra:= wndextrabytes; + end; + widgetclass:= registerclassa(classinfoa); + end + else begin + fillchar(classinfow,sizeof(classinfow),0); + with classinfow do begin + lpszclassname:= childwidgetclassname; + lpfnwndproc:= @childwindowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= childclassstyle; + cbwndextra:= wndextrabytes; +// hbrbackground:= getstockobject(hollow_brush); + end; + childwidgetclass:= registerclassw(classinfow); + fillchar(classinfow,sizeof(classinfow),0); + with classinfow do begin + lpszclassname:= widgetclassname; + lpfnwndproc:= @windowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= classstyle; + cbwndextra:= wndextrabytes; + end; + widgetclass:= registerclassw(classinfow); + end; + if widgetclass = 0 then begin + result:= gue_registerclass; + end + else begin + result:= gue_ok; + end; + if applicationallocated then begin + createapphandle(applicationwindow); + end; + systimerinit(eventlist,applicationwindow); +end; + +function gui_deinit: guierrorty; +var + acursor: cursorshapety; + +begin + primarybuffer:= ''; + windnddeinit; + systimerdeinit; +// killtimer; + killmouseidletimer; + if applicationwindow <> 0 then begin + destroywindow(applicationwindow); + applicationwindow:= 0; + end; + freeandnil(eventlist); + unregisterclass(widgetclassname,hinstance); + widgetclass:= 0; + + msegdi32gdi.deinit; + + result:= gue_ok; + mainthread:= 0; + mousewindow:= 0; + mousecursor:= 0; + for acursor:= low(acursor) to high(acursor) do begin + if cursors[acursor] <> 0 then begin + destroycursor(cursors[acursor]); + cursors[acursor]:= 0; + end; + end; +end; + +function gui_getgdifuncs: pgdifunctionaty; +begin + result:= gdi32getgdifuncs; +end; + +procedure GUI_DEBUGBEGIN; +begin +// setactivewindow(0); +end; + +procedure GUI_DEBUGEND; +begin +end; + +function gui_registergdi: guierrorty; +begin + registergdi(gdi32getgdifuncs); + result:= gue_ok; +end; + +procedure initlibs; +begin + hasimm32:= checkprocaddresses(['Imm32.dll'], + ['ImmGetContext', + 'ImmReleaseContext', + 'ImmSetCompositionWindow'], + [@ImmGetContext, + @ImmReleaseContext, + @ImmSetCompositionWindow]); + haslayeredwindows:= checkprocaddresses(['User32.dll'], + ['SetLayeredWindowAttributes'], + [@SetLayeredWindowAttributes]); +end; + +initialization + initlibs; + gdi32initdefaultfont; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msenoguiintf.pas b/mseide-msegui/lib/common/kernel/windows/msenoguiintf.pas new file mode 100644 index 0000000..d88a16d --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msenoguiintf.pas @@ -0,0 +1,167 @@ +{ MSEgui Copyright (c) 1999-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msenoguiintf; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msesystypes; + +{$include ..\msenoguiintf.inc} + +implementation +uses + windows,{$ifndef FPC}messages,{$endif}msesysintf1,msesysintf,msenogui,mseevent, + mseapplication; +type + tapplication1 = class(tnoguiapplication); +const + widgetclassname = 'msenonguiwindow'; +var + widgetclass: atom; + sempo: psemty; + applicationwindow: hwnd; + timer: cardinal; + timerevent: boolean; + terminated: boolean; + +procedure killtimer; +begin + if timer <> 0 then begin + windows.killtimer(0,timer); + timer:= 0; + end; +end; + +procedure nogui_settimer(us: cardinal); +begin + killtimer; + timer:= windows.settimer(applicationwindow,0,us div 1000,nil); +end; + +function WindowProc(ahWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; +begin + if ahwnd = applicationwindow then begin + result:= 0; + case msg of + wm_timer: begin + timerevent:= true; + end; + wm_close,wm_destroy: begin + terminated:= true; + end; + else begin + result:= 1; + end; + end; + end + else begin + result:= 1; + end; + if result <> 0 then begin + if iswin95 then begin + result:= defwindowproca(ahwnd,msg,wparam,lparam); + end + else begin + result:= defwindowprocw(ahwnd,msg,wparam,lparam); + end; + end; +end; + +procedure nogui_waitevent; + procedure checkevents; + begin + if timerevent then begin + timerevent:= false; + application.postevent(tmseevent.create(ek_timer)); + end; + if terminated then begin + timerevent:= false; + application.postevent(tmseevent.create(ek_terminate)); + end; + end; + +var + msg1: {$ifdef FPC}msg{$else}tmsg{$endif}; + +begin + with tapplication1(application) do begin + include(fstate,aps_waiting); + checkevents; + while eventlist.count = 0 do begin + application.unlock; + with win32semty(sempo^) do begin + if interlockeddecrement(semacount) < 0 then begin + msgwaitformultipleobjects(1,{$ifdef FPC}@{$endif}event, + false,infinite,qs_allinput); + end; + end; + application.lock; + if iswin95 then begin + while peekmessagea(msg1,0,0,0,pm_remove) do begin + dispatchmessagea(msg1); + end; + end + else begin + while peekmessagew(msg1,0,0,0,pm_remove) do begin + dispatchmessagew(msg1); + end; + end; + checkevents; + end; + fstate:= fstate -[aps_waiting,aps_woken]; + end; +end; + +procedure nogui_init(const asempo: psemty); +const + classstyle = cs_owndc; +var + classinfow: twndclassw; + classinfoa: twndclassa; + str1: string; +begin + sempo:= asempo; + if iswin95 then begin + fillchar(classinfoa,sizeof(classinfoa),0); + with classinfoa do begin + lpszclassname:= widgetclassname; + lpfnwndproc:= @windowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= classstyle; +// cbwndextra:= wndextrabytes; + end; + widgetclass:= registerclassa(classinfoa); + end + else begin + fillchar(classinfow,sizeof(classinfow),0); + with classinfow do begin + lpszclassname:= widgetclassname; + lpfnwndproc:= @windowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= classstyle; +// cbwndextra:= wndextrabytes; + end; + widgetclass:= registerclassw(classinfow); + end; + str1:= application.applicationname; + applicationwindow:= windows.CreateWindowex(ws_ex_appwindow,widgetclassname,pchar(str1), + ws_overlappedwindow,0,0,0,0,0,0,hinstance,nil); +end; + +procedure nogui_deinit; +begin + killtimer; + destroywindow(applicationwindow); + applicationwindow:= 0; + unregisterclass(widgetclassname,hinstance); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/windows/mseprocmonitor.pas b/mseide-msegui/lib/common/kernel/windows/mseprocmonitor.pas new file mode 100644 index 0000000..7b35546 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/mseprocmonitor.pas @@ -0,0 +1,182 @@ +{ MSEgui Copyright (c) 2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseprocmonitor; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + msesystypes,mseglob; +{$ifdef FPC} + {$include ..\mseprocmonitor.inc} +{$else} + {$include mseprocmonitor.inc} +{$endif} + +implementation +uses + msethread,msetypes,windows,sysutils,msearrayutils,mseapplication; +type + handlearty = array of thandle; + + tprocmonitor = class(tmutexthread) + private + fwakeupevent: thandle; + fhandles: handlearty; + fcallbacks: array of iprocmonitor; + fdata: pointerarty; +// fcount: integer; + procedure wakeup; + public + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); override; + destructor destroy; override; + function listentoprocess(const prochandle: prochandlety; + const dest: iprocmonitor; + const data: pointer): boolean; + procedure unlistentoprocess(const prochandle: prochandlety; + const dest: iprocmonitor); + function execute(thread: tmsethread): integer; override; + end; + +var + monitor: tprocmonitor; + +procedure checkinit; +begin + if monitor = nil then begin + monitor:= tprocmonitor.create; + end; +end; + +function pro_listentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor; + const adata: pointer): boolean; +begin + checkinit; + result:= monitor.listentoprocess(aprochandle,adest,adata); +end; + +procedure pro_unlistentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor); +begin + if monitor <> nil then begin + monitor.unlistentoprocess(aprochandle,adest); + end; +end; + +{ tprocmonitor } + +constructor tprocmonitor.create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); +begin + fwakeupevent:= createevent(nil,false,false,nil); + setlength(fhandles,1); + fhandles[0]:= fwakeupevent; + inherited; +end; + +destructor tprocmonitor.destroy; +begin + terminate; + setevent(fwakeupevent); + inherited; + closehandle(fwakeupevent); +end; + +procedure tprocmonitor.wakeup; +begin + setevent(fwakeupevent); +end; + +function tprocmonitor.execute(thread: tmsethread): integer; +var +// event: tmseevent; + int1: integer; + handles1: handlearty; + handle1: thandle; + execresult1: integer; +begin + with tprocmonitor(thread) do begin + repeat + lock; + handles1:= copy(fhandles); + unlock; + int1:= waitformultipleobjects(length(handles1), + pwohandlearray(handles1),false,INFINITE); + if not terminated then begin + int1:= int1 - wait_object_0; + if (int1 > 0) and (int1 <= high(handles1)) then begin + handle1:= fhandles[int1]; + getexitcodeprocess(handle1,longword(execresult1)); + lock; + for int1:= high(fhandles) downto 1 do begin + if fhandles[int1] = handle1 then begin + fcallbacks[int1-1].processdied(handle1,execresult1,fdata[int1-1]); +// application.postevent(tchildprocevent.create(fcallbacks[int1-1],handle1, +// execresult1,fdata[int1-1])); + deleteitem(pointerarty(fcallbacks),int1-1); + deleteitem(fhandles,typeinfo(handlearty),int1); + deleteitem(fdata,int1-1); + end; + end; + closehandle(handle1); + unlock; + end; + end; + until terminated; + end; + result:= 0; +end; + +function tprocmonitor.listentoprocess(const prochandle: prochandlety; + const dest: iprocmonitor; const data: pointer): boolean; +begin + result:= false; + lock; + if length(fhandles) < maximum_wait_objects then begin + setlength(fhandles,high(fhandles)+2); + fhandles[high(fhandles)]:= prochandle; + setlength(fcallbacks,high(fhandles)); + fcallbacks[high(fcallbacks)]:= dest; + setlength(fdata,high(fhandles)); + fdata[high(fdata)]:= data; + result:= true; + end; + wakeup; + unlock; +end; + +procedure tprocmonitor.unlistentoprocess(const prochandle: prochandlety; + const dest: iprocmonitor); +var + int1: integer; +begin + lock; + for int1:= high(fcallbacks) downto 0 do begin + if (fcallbacks[int1] = dest) and (fhandles[int1+1] = cardinal(prochandle)) then begin + deleteitem(pointerarty(fcallbacks),int1); + deleteitem(fhandles,typeinfo(handlearty),int1+1); + deleteitem(fdata,int1); + end; + end; + wakeup; + unlock; +end; + +procedure pro_killzombie(const aprochandle: prochandlety); +begin + closehandle(aprochandle); +end; + +initialization +finalization + freeandnil(monitor); +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msesocketintf.pas b/mseide-msegui/lib/common/kernel/windows/msesocketintf.pas new file mode 100644 index 0000000..e46c4c6 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msesocketintf.pas @@ -0,0 +1,426 @@ +{ MSEgui Copyright (c) 1999-2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesocketintf; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msesystypes,msesys; +{$include ..\msesocketintf.inc} + +implementation +uses + {$ifdef FPC}winsock2{$else}winsock2_del{$endif},sysutils,msestrings,msetypes; +type + paddrinfo = ^addrinfo; + addrinfo = record + ai_flags: longint; + ai_family: longint; + ai_socktype: longint; + ai_protocol: longint; + ai_addrlen: size_t; + ai_addr: psockaddr; + ai_canonname: pchar; + ai_next: paddrinfo; + end; + ppaddrinfo= ^paddrinfo; + + datarecty = record + //dummy + end; + + win32sockadty = record + case integer of + 0: (addr: sockaddr_in); + 1: (addr6: sockaddr_in6); + end; + + win32sockaddrty = record + ad: win32sockadty; + platformdata: array[7..32] of longword; + end; + +//function getaddrinfo(__name:Pchar; __service:Pchar; __req:Paddrinfo; +// __pai:PPaddrinfo):longint; stdcall;external WINSOCK2_DLL name 'getaddrinfo'; +//procedure freeaddrinfo(__ai:Paddrinfo); stdcall;external WINSOCK2_DLL name 'freeaddrinfo'; + +function setsocketerror: syserrorty; +begin + result:= sye_socket; + mselasterror:= wsagetlasterror; +end; + +function checkerror(const aerror: integer): syserrorty; +begin + if aerror = 0 then begin + result:= sye_ok; + end + else begin + result:= setsocketerror; + end; +end; + +function sa_len(const family: integer): integer; +begin + case family of + af_inet: begin + result:= sizeof(tsockaddrin); +// result:= sizeof(tsockaddrin.sin_family) + sizeof(tsockaddrin.sin_port) + +// sizeof(tinaddr); + end; + af_inet6: begin + result:= sizeof(tsockaddrin6); +// result:= sizeof(tsockaddrin6.sin6_family) + sizeof(tsockaddrin6.sin6_port) + +// sizeof(tsockaddrin6.sin6_flowinfo) + +// sizeof(tin6addr); + end; + else begin + result:= 0; + end; + end; +end; + +function soc_geterrortext(aerror: integer): string; +begin + result:= inttostr(aerror); +end; + +function soc_getaddrerrortext(aerror: integer): string; +begin + result:= inttostr(aerror); +end; + +function soc_open(const kind: socketkindty; const nonblock: boolean; + out handle: integer): syserrorty; +var + af1: integer; + type1: integer; +// protocol1: integer; + +begin + result:= sye_ok; + type1:= sock_stream; + case kind of + sok_inet: begin + af1:= af_inet; + end; + sok_inet6: begin + af1:= af_inet6; + end; + else begin + result:= sye_notimplemented; + exit; + end; + end; + handle:= socket(af1,type1,ipproto_tcp); + if handle = integer(invalid_socket) then begin + handle:= invalidfilehandle; + result:= setsocketerror; + end + else begin + result:= soc_setnonblock(handle,nonblock); + end; +end; + +function soc_shutdown(const handle: integer; + const kind: socketshutdownkindty): syserrorty; +begin + result:= checkerror(shutdown(handle,ord(kind))); +end; + +function soc_close(const handle: integer): syserrorty; +begin + if closesocket(handle) <> 0 then begin + result:= setsocketerror; + end + else begin + result:= sye_ok; + end; +end; + +function soc_bind(const handle: integer; + const addr: socketaddrty): syserrorty; +begin + if addr.kind in [sok_inet,sok_inet6] then begin + with win32sockaddrty(addr.platformdata) do begin + result:= checkerror(bind(handle,@ad,sa_len(ad.addr.sin_family))); + end; + end + else begin + result:= sye_notimplemented; + end; +end; + +function soc_connect(const handle: integer; const addr: socketaddrty; + const timeoutms: integer): syserrorty; +var +// str1: string; + int1{,int2}: integer; + pollres: pollkindsty; +begin + result:= sye_ok; + with addr do begin + if kind = sok_local then begin + result:= sye_notimplemented; + end + else begin + with win32sockaddrty(platformdata) do begin + int1:= sa_len(ad.addr.sa_family); + if connect(handle,ad.addr,int1) <> 0 then begin + if wsagetlasterror = wsaewouldblock then begin + result:= soc_poll(handle,[poka_write,poka_except],timeoutms,pollres); + if (result = sye_ok) and (poka_except in pollres) then begin +// connect(handle,ad.addr,int1); + result:= setsocketerror; + end; + end + else begin + result:= setsocketerror; + end; + end; + end; + end; + end; +end; + +function soc_read(const fd: longint; const buf: pointer; + const nbytes: longword; out readbytes: integer; + const timeoutms: integer): syserrorty; +var + pollres: pollkindsty; +// err: integer; +begin + result:= sye_ok; + if timeoutms >= 0 then begin + result:= soc_poll(fd,[poka_read],timeoutms,pollres); + end; + if result = sye_ok then begin + readbytes:= recv(fd,buf^,nbytes,0); + if readbytes < 0 then begin + result:= setsocketerror; + end; + end + else begin + readbytes:= -1; + end; +end; + +function soc_write(const fd: longint; buf: pointer; + nbytes: longword; out writebytes: integer; + const timeoutms: integer): syserrorty; +var //todo: correct timeout value for multiple runs + int1,int2: integer; + pollres: pollkindsty; +begin + writebytes:= -1; + int2:= 0; + repeat + result:= soc_poll(fd,[poka_write],timeoutms,pollres); + if result <> sye_ok then begin + exit; + end; + int1:= send(fd,buf,nbytes,0); + if int1 <= 0 then begin + writebytes:= int1; + break; + end; + inc(int2,int1); + inc(pchar(buf),int1); + dec(nbytes,int1); + until integer(nbytes) <= 0; + if nbytes = 0 then begin + result:= sye_ok; + writebytes:= int2; + end + else begin + result:= setsocketerror; + end; +end; + +function soc_listen(const handle: integer; const maxconnections: integer): syserrorty; +begin + result:= checkerror(listen(handle,maxconnections)); +end; + +function soc_accept(const handle: integer; const nonblock: boolean; + out conn: integer; out addr: socketaddrty; + const timeoutms: integer): syserrorty; +var + pollres: pollkindsty; +begin + result:= soc_poll(handle,[poka_read],timeoutms,pollres); + if result = sye_ok then begin + addr.size:= sizeof(win32sockadty); + conn:= accept(handle,@addr.platformdata,@addr.size); + if conn = -1 then begin + result:= syelasterror; + end + else begin + result:= soc_setnonblock(conn,nonblock); + end; + end; +end; + +function soc_urltoaddr(var addr: socketaddrty): syserrorty; +//todo: name resolution, inet6 +var + str1: string; + int1,int2,int3: integer; + ar1: stringarty; + bo1: boolean; +begin + result:= sye_sockaddr; + with addr,win32sockaddrty(platformdata) do begin + if kind = sok_inet then begin + str1:= ansistring(url); + ar1:= splitstring(str1,'.'); + if high(ar1) = 3 then begin + bo1:= true; + int2:= 0; + for int1:= 0 to 3 do begin + try + int3:= strtoint(ar1[int1]); + except + bo1:= false; + break; + end; + if (int3 < 0) or (int3 > 255) then begin + bo1:= false; + break; + end; + int2:= (int2 shl 8) or int3; + end; + if bo1 then begin + fillchar(ad,sizeof(ad),0); + with ad.addr do begin + sin_family:= af_inet; + sin_port:= htons(port); + sin_addr.s_addr:= htonl(int2); + end; + size:= sizeof(ad.addr); + result:= sye_ok; + end; + end; + end; + end; +end; + +function soc_getaddr(const addr: socketaddrty): string; +begin + result:= ''; //todo +end; + +function soc_getport(const addr: socketaddrty): integer; +begin + result:= 0; //todo +end; + +function soc_setnonblock(const handle: integer; const nonblock: boolean): syserrorty; +var + int1: u_long; +begin + result:= sye_ok; + if nonblock then begin + int1:= 1; + end + else begin + int1:= 0; + end; + if ioctlsocket(tsocket(handle),longint(fionbio),pu_long(@int1)) <> 0 then begin + result:= setsocketerror; + end; +end; + +function soc_setrxtimeout(const handle: integer; const ms: integer): syserrorty; +begin + result:= sye_notimplemented; +end; + +function soc_settxtimeout(const handle: integer; const ms: integer): syserrorty; +begin + result:= sye_notimplemented; +end; + +function soc_poll(const handle: integer; const kind: pollkindsty; + const timeoutms: longword; + out pollres: pollkindsty): syserrorty; + //0 -> no timeout + //for blocking mode +var + rset,wset,eset: tfdset; + prset,pwset,peset: pfdset; + ti: timeval; + pti: ptimeval; + int1: integer; +begin + pollres:= []; + if timeoutms <> 0 then begin + ti.tv_sec:= timeoutms div 1000; + ti.tv_usec:= (timeoutms mod 1000) * 1000; + pti:= @ti; + end + else begin + pti:= nil; + end; + if poka_read in kind then begin + fd_zero(rset); + fd_set(handle,rset); + prset:= @rset; + end + else begin + prset:= nil; + end; + if poka_write in kind then begin + fd_zero(wset); + fd_set(handle,wset); + pwset:= @wset; + end + else begin + pwset:= nil; + end; + if poka_except in kind then begin + fd_zero(eset); + fd_set(handle,eset); + peset:= @eset; + end + else begin + peset:= nil; + end; + int1:= select(0,prset,pwset,peset,pti); + if int1 > 0 then begin + if (poka_read in kind) and fd_isset(handle,rset) then begin + include(pollres,poka_read); + end; + if (poka_write in kind) and fd_isset(handle,wset) then begin + include(pollres,poka_write); + end; + if (poka_except in kind) and fd_isset(handle,eset) then begin + include(pollres,poka_except); + end; + result:= sye_ok; + end + else begin + if int1 = 0 then begin + result:= sye_timeout; + end + else begin + result:= setsocketerror; + end; + end; +end; + +var + wsadata: twsadata; + +initialization + wsastartup((2 shl 8) or 2,wsadata); +finalization + wsacleanup; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msesysintf.pas b/mseide-msegui/lib/common/kernel/windows/msesysintf.pas new file mode 100644 index 0000000..2a3833e --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msesysintf.pas @@ -0,0 +1,1999 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesysintf; //i386-win32 + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msesys,{msethread,}msetypes,msesystypes,msestrings,windows,msectypes; + +{$include ..\msesysintf.inc} + +type + NTSTATUS = longword; + +const + ASFW_ANY = dword(-1); + //PROCESSINFOCLASS + ProcessBasicInformation = 0; + ProcessDebugPort = 7; + ProcessWow64Information = 26; + ProcessImageFileName = 27; + ProcessBreakOnTermination = 29; + +var + AllowSetForegroundWindow: function(dwProcessId: DWORD):WINBOOL; stdcall; + +function procidfromprochandle(const ahandle: prochandlety): procidty; + +implementation +uses + sysutils,msebits,msefileutils,{msedatalist,}dateutils, + msesystimer,msearrayutils,msesysintf1,msedynload; + +//todo: correct unicode implementation, long filepaths, stubs for win95 +type +{$packrecords c} + PROCESS_BASIC_INFORMATION = record + Reserved1: PVOID; + PebBaseAddress: pointer;//PPEB; + Reserved2: array[0..1] of PVOID; + UniqueProcessId: ULONG_PTR; + Reserved3: PVOID; + end; + pPROCESS_BASIC_INFORMATION = ^PROCESS_BASIC_INFORMATION; + +var + ZwQueryInformationProcess: function(ProcessHandle: HANDLE; + ProcessInformationClass: cint{PROCESSINFOCLASS}; + ProcessInformation: PVOID; + ProcessInformationLength: ULONG; + ReturnLength: PULONG): NTSTATUS; stdcall; + NtQueryInformationProcess: function( + ProcessHandle: HANDLE; + ProcessInformationClass: cint{PROCESSINFOCLASS}; + ProcessInformation: PVOID; + ProcessInformationLength: cULONG; + ReturnLength: PULONG): NTSTATUS; stdcall; + GetProcessId: function(Process: HANDLE): DWORD; stdcall; + +function procidfromprochandle(const ahandle: prochandlety): procidty; +var + info: PROCESS_BASIC_INFORMATION; + len1: culong; +begin + result:= invalidprocid; + if getprocessid <> nil then begin + result:= getprocessid(ahandle); + end + else begin + if NtQueryInformationProcess <> nil then begin + if NtQueryInformationProcess(ahandle,processbasicinformation,@info, + sizeof(info),@len1) = 0 then begin + result:= info.uniqueprocessid; + end; + end + else begin + if ZwQueryInformationProcess <> nil then begin + if ZwQueryInformationProcess(ahandle,processbasicinformation,@info, + sizeof(info),@len1) = 0 then begin + result:= info.uniqueprocessid; + end; + end; + end; + end; +end; + +var + apphomedir: filenamety; + userhomedir: filenamety; + +const + FILE_ATTRIBUTE_ENCRYPTED = $0040; + FILE_ATTRIBUTE_REPARSE_POINT = $0400; + FILE_ATTRIBUTE_SPARSE_FILE = $0200; + {$ifdef FPC} + FILE_ATTRIBUTE_OFFLINE = $00001000; + {$endif} + filetimeoffset = -109205.0; + +type + win32threadinfoty = record //64bit + handle: thandle; //8 + platformdata: array[1..3] of pointer; + end; + + winfileinfoty = record + dwFileAttributes: DWORD; + ftCreationTime: TFileTime; + ftLastAccessTime: TFileTime; + ftLastWriteTime: TFileTime; + end; + winfilesizety = record + nFileSizeHigh: DWORD; + nFileSizeLow: DWORD; + end; + winfilenameaty = array[0..MAX_PATH - 1] of Char; + pwinfilenameaty = ^winfilenameaty; + WIN32_FIND_DATAA = record + winfo: winfileinfoty; + wsize: winfilesizety; + dwReserved0: DWORD; + dwReserved1: DWORD; + cFileName: winfilenameaty; + cAlternateFileName: array[0..13] of Char; + end; + pwin32_find_dataa = ^win32_find_dataa; + WIN32_FIND_DATAW = record + winfo: winfileinfoty; + wsize: winfilesizety; + dwReserved0: DWORD; + dwReserved1: DWORD; + cFileName: array[0..MAX_PATH - 1] of WideChar; + cAlternateFileName: array[0..13] of WideChar; + end; + pwin32_find_dataw = ^win32_find_dataw; + + BY_HANDLE_FILE_INFORMATION = record + winfo: winfileinfoty; + dwVolumeSerialNumber: DWORD; + wsize: winfilesizety; + nNumberOfLinks: DWORD; + nFileIndexHigh: DWORD; + nFileIndexLow: DWORD; + end; + + dirstreamwin32ty = record //64bit + handle: thandle; //8 + finddatapo: pwin32_find_dataw; //8 + last: boolean; //4 + drivenum: integer; //for root directory //4 total 24 + {$ifdef cpu64} //platformdata = 64 + platformdata: array[3..7] of pointer; + {$else} + platformdata: array[4..7] of pointer; + {$endif} + end; + +const + TH32CS_SNAPHEAPLIST = $00000001; + TH32CS_SNAPPROCESS = $00000002; + TH32CS_SNAPTHREAD = $00000004; + TH32CS_SNAPMODULE = $00000008; + TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST or TH32CS_SNAPPROCESS or + TH32CS_SNAPTHREAD or TH32CS_SNAPMODULE; + TH32CS_INHERIT = $80000000; +type + {$ifndef FPC} + LONG = integer; + {$endif} + PROCESSENTRY32 = record + dwSize: DWORD; + cntUsage: DWORD; + th32ProcessID: DWORD; + th32DefaultHeapID: pointer; + th32ModuleID: DWORD; + cntThreads: DWORD; + th32ParentProcessID: DWORD; + pcPriClassBase: LONG; + dwFlags: DWORD; + szExeFile: array[0..MAX_PATH-1] of char; + end; + PPROCESSENTRY32 = ^PROCESSENTRY32; + +function CreateToolhelp32Snapshot(dwFlags: dword; th32ProcessId: dword): thandle; + stdcall; external kernel32 name 'CreateToolhelp32Snapshot'; +function Process32First(hSnapshot: thandle; lppe: PPROCESSENTRY32): BOOL; + stdcall; external kernel32 name 'Process32First'; +function Process32Next(hSnapshot: thandle; lppe: PPROCESSENTRY32): BOOL; + stdcall; external kernel32 name 'Process32Next'; +function GetFileInformationByHandle(hFile: THandle; + var lpFileInformation: By_Handle_File_Information): BOOL; + stdcall; external 'kernel32' name 'GetFileInformationByHandle'; + +var + GetLongPathNameW: function(lpszShortPath: LPCWSTR; lpszLongPath: LPCWSTR; + cchBuffer: DWORD):DWORD; stdcall; + +function sys_getpid: procidty; +begin + result:= getcurrentprocessid; +end; + +function sys_terminateprocess(const proc: prochandlety): syserrorty; +begin + result:= sye_notimplemented; +end; + +function sys_killprocess(const proc: prochandlety): syserrorty; +begin + result:= sye_ok; + if not windows.terminateprocess(proc,0) then begin + result:= syelasterror; + end; +end; + +function sys_stdin: integer; +begin + result:= getstdhandle(std_input_handle); +end; + +function sys_stdout: integer; +begin + result:= getstdhandle(std_output_handle); +end; + +function sys_stderr: integer; +begin + result:= getstdhandle(std_error_handle); +end; + +function sys_getprintcommand: msestring; +begin + result:= defaultprintcommand; + if result = '' then begin + result:= 'gswin32c.exe -dNOPAUSE -sDEVICE=mswinpr2 -'; + end; +end; + +{ +function sys_towupper(char: msechar): msechar; +begin + result:= windows.charupperw(ord(char)); //win95? +end; + +function sys_toupper(char: char): char; +begin + result:= windows.charupper(ord(char)); +end; +} + +function sys_getprocesses: procitemarty; +var + int1: integer; + th: thandle; + info: processentry32; +begin + result:= nil; + th:= createtoolhelp32snapshot(th32cs_snapprocess,0); + int1:= 0; + if th <> invalid_handle_value then begin + info.dwsize:= sizeof(info); + if process32first(th,@info) then begin + repeat + additem(result,typeinfo(procitemarty),int1); + with result[int1-1] do begin + pid:= info.th32processid; + ppid:= info.th32parentprocessid; + end; + until not process32next(th,@info); + end; + closehandle(th); + setlength(result,int1); + end; +end; + +procedure sys_schedyield; +begin + windows.sleep(0); +end; + +procedure sys_usleep(const us: cardinal); +begin + windows.sleep(us div 1000); +end; + +function sys_getapplicationpath: filenamety; +const + bufsize = 1024; +var + int1: integer; + str1: string; +begin + setlength(str1,bufsize); + int1:= getmodulefilename(hinstance,@str1[1],bufsize-1); + setlength(str1,int1); + result:= tomsefilepath(msestring(str1)); +end; + +function sys_getcommandlinearguments: msestringarty; +begin + {$ifdef FPC}{$checkpointer off}{$endif} + result:= parsecommandline(msestring(cmdline)); //todo: use unicode + {$ifdef FPC}{$checkpointer default}{$endif} +end; + +procedure sys_getenvvars(out names: msestringarty; out values: msestringarty); +var + po0,po1,po2,po3: pmsechar; + po0a,po1a,po2a,po3a: pchar; + str1: ansistring; +begin + if iswin95 then begin + po0a:= getenvironmentstringsa(); + po1a:= po0a; + while po1a^ <> #0 do begin + po2a:= po1a; + while po2a^ <> #0 do begin + inc(po2a); + end; + po3a:= po1a; + while (po3a^ <> '=') and (po3a < po2a) do begin + inc(po3a); + end; + str1:= psubstr(po1a,po3a); + oemtoansibuff(pointer(str1),pointer(str1),length(str1)); + additem(names,msestring(str1)); + str1:= psubstr(po3a+1,po2a); + oemtoansibuff(pointer(str1),pointer(str1),length(str1)); + additem(values,msestring(str1)); + po1a:= po2a+1; + end; + freeenvironmentstringsa(po0a); + end + else begin + po0:= getenvironmentstringsw(); + po1:= po0; + while po1^ <> #0 do begin + po2:= po1; + while po2^ <> #0 do begin + inc(po2); + end; + po3:= po1; + while (po3^ <> '=') and (po3 < po2) do begin + inc(po3); + end; + additem(names,psubstr(po1,po3)); + additem(values,psubstr(po3+1,po2)); + po1:= po2+1; + end; + freeenvironmentstringsw(po0); + end; +end; + +function sys_getenv(const aname: msestring; out avalue: msestring): boolean; + //true if found +var + str1,str2: string; + lwo1: longword; +begin + avalue:= ''; + if iswin95 then begin + str2:= ansistring(aname); + lwo1:= getenvironmentvariablea(pchar(str2),nil,0); + result:= lwo1 > 0; + if result then begin + if lwo1 > 1 then begin + setlength(str1,lwo1-1); + lwo1:= getenvironmentvariablea(pchar(str2),pointer(str1),lwo1); + result:= lwo1 > 0; + setlength(str1,lwo1); + avalue:= msestring(str1); + end; + end; + end + else begin + lwo1:= getenvironmentvariablew(pmsechar(aname),nil,0); + result:= lwo1 > 0; + if result then begin + if lwo1 > 1 then begin + setlength(avalue,lwo1-1); + lwo1:= getenvironmentvariablew(pmsechar(aname),pointer(avalue),lwo1); + result:= lwo1 > 0; + setlength(avalue,lwo1); + end; + end; + end; +end; + +function sys_setenv(const aname: msestring; const avalue: msestring): syserrorty; +begin + result:= sye_ok; + if iswin95 then begin + if not setenvironmentvariablea(pchar(ansistring(aname)), + pchar(ansistring(avalue))) then begin + result:= syelasterror; + end; + end + else begin + if not setenvironmentvariablew(pmsechar(aname), + pmsechar(avalue)) then begin + result:= syelasterror; + end; + end; +end; + +function sys_unsetenv(const aname: msestring): syserrorty; +begin + result:= sye_ok; + if iswin95 then begin + if not setenvironmentvariablea(pchar(ansistring(aname)),nil) then begin + result:= syelasterror; + end; + end + else begin + if not setenvironmentvariablew(pmsechar(aname),nil) then begin + result:= syelasterror; + end; + end; +end; + +function winfilepath(dirname,filename: msestring): msestring; +begin + replacechar1(dirname,msechar('/'),msechar('\')); + replacechar1(filename,msechar('/'),msechar('\')); + if (length(dirname) >= 3) and (dirname[1] = '\') and (dirname[3] = ':') then begin + dirname[1]:= dirname[2]; // '/c:' -> 'c:\' + dirname[2]:= ':'; + dirname[3]:= '\'; + if (length(dirname) > 3) and (dirname[4] = '\') then begin + move(dirname[5],dirname[4],(length(dirname) - 4)*sizeof(msechar)); + setlength(dirname,length(dirname) - 1); + end; + end; + if filename <> '' then begin + if dirname = '' then begin + result:= '.\'+filename; + end + else begin + if dirname[length(dirname)] <> '\' then begin + result:= dirname + '\' + filename; + end + else begin + result:= dirname + filename; + end; + end; + end + else begin + result:= dirname; + end; +end; + +function sys_filesystemiscaseinsensitive: boolean; +begin + result:= true; +end; + +function sys_tosysfilepath(var path: msestring): syserrorty; +begin + path:= winfilepath(path,''); + result:= sye_ok; +end; + +function sys_read(fd:longint; buf:pointer; nbytes: dword): integer; +begin + result:= -1; //compilerwarning; + if not windows.readfile(fd,buf^,nbytes,dword(result),nil) then begin + result:= -1; + end; + { + if nbytes > 0 then begin + repeat + if not windows.readfile(fd,buf^,nbytes,dword(result),nil) then begin + result:= -1; + end; + until result <> 0; + end + else begin + result:= 0; + end; + } +end; + +function sys_write(fd:longint; buf:pointer; nbytes: dword): integer; +begin + result:= -1; //compilerwarning; + if nbytes > 0 then begin + repeat + if not windows.WriteFile(fd,buf^,nbytes,dword(result),nil) then begin + result:= -1; + end; + until result <> 0; + end + else begin + result:= 0; + end; +end; + +function sys_errorout(const atext: string): syserrorty; +var + ca1: cardinal; +begin + if length(atext) > 0 then begin + if isconsole then begin + if windows.writefile(getstdhandle(std_input_handle),pchar(atext)^, + length(atext),ca1,nil) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + result:= sye_noconsole; + end; + end + else begin + result:= sye_ok; + end; +end; + +function sys_openfile(const path: msestring; const openmode: fileopenmodety; + const accessmode: fileaccessmodesty; + const rights: filerightsty; out handle: integer): syserrorty; +const + openmodes: array[fileopenmodety] of cardinal = +// fm_none,fm_read, fm_write, fm_readwrite, + (0, generic_read,generic_write,generic_read or generic_write, +// fm_create, fm_append + generic_read or generic_write,generic_read or generic_write); +var + ca1: cardinal; + str1: string; + mstr2: msestring; + +begin + if not (fa_denyread in accessmode) then begin + ca1:= file_share_read; + end + else begin + ca1:= 0; + end; + if not (fa_denywrite in accessmode) then begin + ca1:= ca1 or file_share_write; + end; + + mstr2:= winfilepath(path,''); + if iswin95 then begin + str1:= ansistring(mstr2); + if openmode = fm_Create then begin + handle:= CreateFilea(PChar(str1),openmodes[openmode], //todo: rights -> securityattributes + ca1, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + end + else begin + handle:= CreateFilea(PChar(str1),openmodes[openmode], + ca1, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + end; + end + else begin + if openmode = fm_Create then begin + handle:= CreateFilew(PmseChar(mstr2),openmodes[openmode], //todo: rights -> securityattributes + ca1, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + end + else begin + handle:= CreateFilew(PmseChar(mstr2),openmodes[openmode], + ca1, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + end; + end; + if handle = invalidfilehandle then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function sys_closefile(const handle: integer): syserrorty; +begin + if (handle = invalidfilehandle) or closehandle(handle) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function sys_flushfile(const handle: integer): syserrorty; +begin + if flushfilebuffers(handle) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function sys_dup(const source: integer; out dest: integer): syserrorty; +begin + result:= sye_notimplemented; +end; + +const + invalid_set_file_pointer = dword(-1); + +function sys_truncatefile(const handle: integer; const size: int64): syserrorty; +var + res: dword; + lo1: clong; +begin + result:= sye_ok; + lo1:= size shr 32; + res:= setfilepointer(handle,size,@lo1,file_begin); + if (res = invalid_set_file_pointer) and (getlasterror <> no_error) then begin + result:= syelasterror; + end; +end; + +function sys_poll(const handle: integer; const kind: pollkindsty; + const timeoutms: longword): syserrorty; + //0 -> no timeout + //for blocking mode +begin + result:= sye_notimplemented; +end; + +function sys_copyfile(const oldfile,newfile: msestring): syserrorty; +var + str1,str2: string; +begin + if iswin95 then begin + str1:= ansistring(winfilepath(oldfile,'')); + str2:= ansistring(winfilepath(newfile,'')); + if windows.copyfilea(pchar(str1),pchar(str2),false) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + if windows.copyfilew(pmsechar(winfilepath(oldfile,'')), + pmsechar(winfilepath(newfile,'')),false) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end; +end; + +function sys_renamefile(const oldname,newname: filenamety): syserrorty; +var + str1,str2: string; +begin + if iswin95 then begin + str1:= ansistring(winfilepath(oldname,'')); + str2:= ansistring(winfilepath(newname,'')); + if windows.copyfilea(pchar(str1),pchar(str2),false) then begin + if windows.deletefilea(pchar(str1)) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + result:= syelasterror; + end; + end + else begin + if windows.movefileexw(pmsechar(winfilepath(oldname,'')), + pmsechar(winfilepath(newname,'')),movefile_replace_existing) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end; +end; + +function sys_deletefile(const filename: filenamety): syserrorty; +var + str1: string; +begin + if iswin95 then begin + str1:= ansistring(winfilepath(filename,'')); + if windows.deletefilea(pchar(str1)) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + if windows.deletefilew(pmsechar(winfilepath(filename,''))) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end; +end; + +function sys_deletedir(const filename: filenamety): syserrorty; +var + str1: string; +begin + if iswin95 then begin + str1:= ansistring(winfilepath(filename,'')); + if windows.removedirectorya(pchar(str1)) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + if windows.removedirectoryw(pmsechar(winfilepath(filename,''))) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end; +end; + + +function sys_createdir(const path: msestring; + const rights: filerightsty): syserrorty; +var + str1: string; + str2: msestring; + bo1: boolean; +begin + if iswin95 then begin + str1:= ansistring(winfilepath(path,'')); + bo1:= windows.createdirectorya(pchar(str1),nil); + //todo: rights -> securityattributes + end + else begin + str2:= winfilepath(path,''); + bo1:= windows.createdirectoryw(pmsechar(str2),nil); + //todo: rights -> securityattributes + end; + if bo1 then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function sys_gettimeus: longword; +begin + result:= systimerus; +// result:= gettickcount * 1000; +end; +{ +function sys_getlastsyserror: integer; +begin + result:= getlasterror; +end; +} +{$ifdef FPC} + +function threadexec(infopo : pointer) : ptrint; +begin +//result:= 0; +//exit; + threadinfoty(infopo^).id:= threadty(getcurrentthreadid); + result:= threadinfoty(infopo^).threadproc(); + endthread(); +end; + +{$else} + +function threadexec(infopo: pointer): integer; stdcall; +begin + threadinfoty(infopo^).id:= threadty(getcurrentthreadid); + result:= threadinfoty(infopo^).threadproc(); +end; + +{$endif} + +function sys_threadcreate(var info: threadinfoty): syserrorty; +begin +{$ifdef FPC} + with info,win32threadinfoty(platformdata) do begin + handle:= beginthread(@threadexec,@info,id,stacksize); + if handle = 0 then begin + result:= sye_thread; + end + else begin + result:= sye_ok; + end; + end; +{$else} + ismultithread:= true; + with info,win32threadinfoty(platformdata) do begin + handle:= windows.CreateThread(nil,info.stacksize,@threadexec,@info,0,id); + if handle = 0 then begin + result:= sye_thread; + id:= 0; + end + else begin + result:= sye_ok; + end; + end; +{$endif} +end; + +function sys_threadwaitfor(var info: threadinfoty): syserrorty; +begin + with info,win32threadinfoty(platformdata) do begin + if waitforsingleobject(handle,infinite) = wait_object_0 then begin + result:= sye_ok; + end + else begin + result:= sye_thread; + end; + end; +end; + +function sys_getcurrentthread: threadty; +begin + result:= threadty(getcurrentthreadid); +end; + +function sys_issamethread(const a,b: threadty): boolean; +begin + result:= a = b; +end; + +function sys_threaddestroy(var info: threadinfoty): syserrorty; +var + ca1: cardinal; +begin + result:= sye_ok; + with win32threadinfoty(info.platformdata) do begin + if getexitcodethread(handle,ca1) then begin + if ca1 = still_active then begin + terminatethread(handle,exitcode); + end; + end; + closehandle(handle); + end; +end; + +function sys_threadschedyield: syserrorty; +begin + result:= sye_ok; + windows.sleep(0); +end; + +function filetimetotime(const wtime: tfiletime): tdatetime; +begin + with wtime do begin + if (dwLowDateTime = 0) and (dwhighdatetime = 0) then begin + result:= 0; + end + else begin + result:= (dwhighdatetime*twoexp32 + dwLowDateTime) / + (24.0*60.0*60.0*1000000.0*10.0) + filetimeoffset; + end; + end; +end; + +function sys_getutctime: tdatetime; +var + ft1: tfiletime; +begin + getsystemtimeasfiletime(ft1); + result:= filetimetotime(ft1); +end; + +var + lastlocaltime: integer; + gmtoff: real; + +function sys_localtimeoffset: tdatetime; +var + tinfo: time_zone_information; + int1: integer; +begin + with tinfo do begin + {$ifdef FPC} + case gettimezoneinformation(@tinfo) of + {$else} + case gettimezoneinformation(tinfo) of + {$endif} + time_zone_id_unknown: int1:= bias; + time_zone_id_standard: int1:= bias + standardbias; + time_zone_id_daylight: int1:= bias + daylightbias; + else int1:= 0; + end; + end; + result:= -int1 / (24*60.0); +end; + +function sys_getlocaltime: tdatetime; +var + ft1: tfiletime; + lint1: int64; + lwo1: longword; +begin + getsystemtimeasfiletime(ft1); + lint1:= (int64(ft1.dwhighdatetime) shl 32) + ft1.dwlowdatetime; + lwo1:= lint1 div 10000000; //seconds + if lwo1 <> longword(lastlocaltime) then begin + lastlocaltime:= lwo1; + gmtoff:= sys_localtimeoffset; + end; + {$ifdef FPC} + result:= real(lint1)/(24.0*60.0*60.0*1000000.0*10.0) + filetimeoffset + gmtoff; + {$else} + result:= lint1/(24.0*60.0*60.0*1000000.0*10.0) + filetimeoffset + gmtoff; + {$endif} +end; +{ +function sys_getlocaltime: tdatetime; +var + ti1: tsystemtime; +begin + getlocaltime(ti1); + result:= systemtimetodatetime(ti1); +end; +} +(* +function sys_localtimeoffset: tdatetime; +var + ti1,ti2: tfiletime; +begin + ti1.dwhighdatetime:= $40000000; + ti1.dwlowdatetime:= 0; + {$ifdef FPC} + filetimetolocalfiletime(@ti1,@ti2); + {$else} + filetimetolocalfiletime(ti1,ti2); + {$endif} + ti2.dwhighdatetime:= ti2.dwhighdatetime - $40000000; + result:= int64(ti2) / (24*60*60*1e7); //100ns +end; +*) +{ +function sys_localtimeoffset: tdatetime; +var + info: _time_zone_information; +begin + if gettimezoneinformation(info) = $ffffffff then begin + result:= 0; + end + else begin + result:= - info.Bias / (24.0*60.0); //does not check daylightsaving + end; +end; +} +function sys_getlangname: string; +type + langty = + (L_AFRIKAANS,L_ALBANIAN,L_ARABIC,L_ARMENIAN,L_ASSAMESE, + L_AZERI,L_BASQUE,L_BELARUSIAN,L_BENGALI,L_BULGARIAN, + L_CATALAN,L_CHINESE,L_CROATIAN,L_CZECH,L_DANISH, + L_DIVEHI,L_DUTCH,L_ENGLISH,L_ESTONIAN,L_FAEROESE, + L_FARSI,L_FINNISH,L_FRENCH,L_GALICIAN,L_GEORGIAN, + L_GERMAN,L_GREEK,L_GUJARATI,L_HEBREW,L_HINDI, + L_HUNGARIAN,L_ICELANDIC,L_INDONESIAN,L_ITALIAN, + L_JAPANESE,L_KANNADA,L_KASHMIRI,L_KAZAK,L_KONKANI, + L_KOREAN,L_KYRGYZ,L_LATVIAN,L_LITHUANIAN,L_MACEDONIAN, + L_MALAY,L_MALAYALAM,L_MANIPURI,L_MARATHI,L_MONGOLIAN, + L_NEPALI,L_NORWEGIAN,L_ORIYA,L_POLISH,L_PORTUGUESE, + L_PUNJABI,L_ROMANIAN,L_RUSSIAN,L_SANSKRIT,L_SERBIAN, + L_SINDHI,L_SLOVAK,L_SLOVENIAN,L_SPANISH,L_SWAHILI, + L_SWEDISH,L_SYRIAC,L_TAMIL,L_TATAR,L_TELUGU,L_THAI, + L_TURKISH,L_UKRAINIAN,L_URDU,L_UZBEK,L_VIETNAMESE); + + langinfoty = record + lang: word; name: string; + end; +const +{$ifndef FPC} + LANG_AFRIKAANS = $36; + LANG_ALBANIAN = $1c; + LANG_ARABIC = $01; + LANG_ARMENIAN = $2b; + LANG_ASSAMESE = $4d; + LANG_AZERI = $2c; + LANG_BASQUE = $2d; + LANG_BELARUSIAN = $23; + LANG_BENGALI = $45; + LANG_BULGARIAN = $02; + LANG_CATALAN = $03; + LANG_CHINESE = $04; + LANG_CROATIAN = $1a; + LANG_CZECH = $05; + LANG_DANISH = $06; + LANG_DIVEHI = $65; + LANG_DUTCH = $13; + LANG_ENGLISH = $09; + LANG_ESTONIAN = $25; + LANG_FAEROESE = $38; + LANG_FARSI = $29; + LANG_FINNISH = $0b; + LANG_FRENCH = $0c; + LANG_GALICIAN = $56; + LANG_GEORGIAN = $37; + LANG_GERMAN = $07; + LANG_GREEK = $08; + LANG_GUJARATI = $47; + LANG_HEBREW = $0d; + LANG_HINDI = $39; + LANG_HUNGARIAN = $0e; + LANG_ICELANDIC = $0f; + LANG_INDONESIAN = $21; + LANG_ITALIAN = $10; + LANG_JAPANESE = $11; + LANG_KANNADA = $4b; + LANG_KASHMIRI = $60; + LANG_KAZAK = $3f; + LANG_KONKANI = $57; + LANG_KOREAN = $12; + LANG_KYRGYZ = $40; + LANG_LATVIAN = $26; + LANG_LITHUANIAN = $27; + LANG_MACEDONIAN = $2f; + LANG_MALAY = $3e; + LANG_MALAYALAM = $4c; + LANG_MANIPURI = $58; + LANG_MARATHI = $4e; + LANG_MONGOLIAN = $50; + LANG_NEPALI = $61; + LANG_NORWEGIAN = $14; + LANG_ORIYA = $48; + LANG_POLISH = $15; + LANG_PORTUGUESE = $16; + LANG_PUNJABI = $46; + LANG_ROMANIAN = $18; + LANG_RUSSIAN = $19; + LANG_SANSKRIT = $4f; + LANG_SERBIAN = $1a; + LANG_SINDHI = $59; + LANG_SLOVAK = $1b; + LANG_SLOVENIAN = $24; + LANG_SPANISH = $0a; + LANG_SWAHILI = $41; + LANG_SWEDISH = $1d; + LANG_SYRIAC = $5a; + LANG_TAMIL = $49; + LANG_TATAR = $44; + LANG_TELUGU = $4a; + LANG_THAI = $1e; + LANG_TURKISH = $1f; + LANG_UKRAINIAN = $22; + LANG_URDU = $20; + LANG_UZBEK = $43; + LANG_VIETNAMESE = $2a; + +function PRIMARYLANGID(LangId: WORD): WORD; +begin + PRIMARYLANGID := LangId and $3FF; +end; + +const +{$endif} + + langs: array[langty] of langinfoty = ( + (lang: LANG_AFRIKAANS; name: 'af'), + (lang: LANG_ALBANIAN; name: 'sq'), + (lang: LANG_ARABIC; name: 'ar'), + (lang: LANG_ARMENIAN; name: 'hy'), + (lang: LANG_ASSAMESE; name: 'as'), + (lang: LANG_AZERI; name: 'az'), + (lang: LANG_BASQUE; name: 'eu'), + (lang: LANG_BELARUSIAN; name: 'be'), + (lang: LANG_BENGALI; name: 'bn'), + (lang: LANG_BULGARIAN; name: 'bg'), + (lang: LANG_CATALAN; name: 'ca'), + (lang: LANG_CHINESE; name: 'zh'), + (lang: LANG_CROATIAN; name: 'hr'), + (lang: LANG_CZECH; name: 'cs'), + (lang: LANG_DANISH; name: 'da'), + (lang: LANG_DIVEHI; name: 'dv'), + (lang: LANG_DUTCH; name: 'nl'), + (lang: LANG_ENGLISH; name: 'en'), + (lang: LANG_ESTONIAN; name: 'et'), + (lang: LANG_FAEROESE; name: 'fo'), + (lang: LANG_FARSI; name: 'fa'), + (lang: LANG_FINNISH; name: 'fi'), + (lang: LANG_FRENCH; name: 'fr'), + (lang: LANG_GALICIAN; name: 'gl'), + (lang: LANG_GEORGIAN; name: 'ka'), + (lang: LANG_GERMAN; name: 'de'), + (lang: LANG_GREEK; name: 'el'), + (lang: LANG_GUJARATI; name: 'gu'), + (lang: LANG_HEBREW; name: 'he'), + (lang: LANG_HINDI; name: 'hi'), + (lang: LANG_HUNGARIAN; name: 'hu'), + (lang: LANG_ICELANDIC; name: 'is'), + (lang: LANG_INDONESIAN; name: 'id'), + (lang: LANG_ITALIAN; name: 'it'), + (lang: LANG_JAPANESE; name: 'ja'), + (lang: LANG_KANNADA; name: 'kn'), + (lang: LANG_KASHMIRI; name: '??'), + (lang: LANG_KAZAK; name: 'kk'), + (lang: LANG_KONKANI; name: 'kok'), + (lang: LANG_KOREAN; name: 'ko'), + (lang: LANG_KYRGYZ; name: 'ky'), + (lang: LANG_LATVIAN; name: 'lv'), + (lang: LANG_LITHUANIAN; name: 'lt'), + (lang: LANG_MACEDONIAN; name: 'mk'), + (lang: LANG_MALAY; name: 'ms'), + (lang: LANG_MALAYALAM; name: 'ml'), + (lang: LANG_MANIPURI; name: '??'), + (lang: LANG_MARATHI; name: 'mr'), + (lang: LANG_MONGOLIAN; name: 'mn'), + (lang: LANG_NEPALI; name: 'ne'), + (lang: LANG_NORWEGIAN; name: 'no'), + (lang: LANG_ORIYA; name: 'or'), + (lang: LANG_POLISH; name: 'pl'), + (lang: LANG_PORTUGUESE; name: 'pt'), + (lang: LANG_PUNJABI; name: 'pa'), + (lang: LANG_ROMANIAN; name: 'ro'), + (lang: LANG_RUSSIAN; name: 'ru'), + (lang: LANG_SANSKRIT; name: 'sa'), + (lang: LANG_SERBIAN; name: 'sr'), + (lang: LANG_SINDHI; name: '??'), + (lang: LANG_SLOVAK; name: 'sk'), + (lang: LANG_SLOVENIAN; name: 'sl'), + (lang: LANG_SPANISH; name: 'es'), + (lang: LANG_SWAHILI; name: 'sw'), + (lang: LANG_SWEDISH; name: 'sv'), + (lang: LANG_SYRIAC; name: 'syr'), + (lang: LANG_TAMIL; name: 'ta'), + (lang: LANG_TATAR; name: 'tt'), + (lang: LANG_TELUGU; name: 'te'), + (lang: LANG_THAI; name: 'th'), + (lang: LANG_TURKISH; name: 'tr'), + (lang: LANG_UKRAINIAN; name: 'uk'), + (lang: LANG_URDU; name: 'ur'), + (lang: LANG_UZBEK; name: 'uz'), + (lang: LANG_VIETNAMESE; name: 'vi')); +var + id: word; + l1: langty; +begin + result:= ''; + id:= primarylangid(getuserdefaultlangid); + for l1:= low(langty) to high(langty) do begin + if langs[l1].lang = id then begin + result:= langs[l1].name; + break; + end; + end; +end; + +procedure winfileinfotofileinfo(const winfo: winfileinfoty; + const wsize: winfilesizety; var info: fileinfoty); +begin + with winfo,info,extinfo1 do begin + if file_attribute_directory and dwfileattributes <> 0 then begin + info.extinfo1.filetype:= ft_dir; + end + else begin + info.extinfo1.filetype:= ft_reg; + end; + state:= state + [fis_typevalid,fis_extinfo1valid]; + if filetype = ft_dir then begin + attributes:= [fa_dir]; + end + else begin + attributes:= []; + end; + if file_attribute_archive and dwfileattributes <> 0 then begin + include(attributes,fa_archive); + end; + if file_attribute_compressed and dwfileattributes <> 0 then begin + include(attributes,fa_compressed); + end; + if file_attribute_encrypted and dwfileattributes <> 0 then begin + include(attributes,fa_encrypted); + end; + if file_attribute_hidden and dwfileattributes <> 0 then begin + include(attributes,fa_hidden); + end; + if file_attribute_offline and dwfileattributes <> 0 then begin + include(attributes,fa_offline); + end; + attributes:= attributes + [fa_rusr,fa_xusr,fa_rgrp,fa_xgrp,fa_roth,fa_xoth]; + if file_attribute_readonly and dwfileattributes = 0 then begin + attributes:= attributes + [fa_wusr,fa_wgrp,fa_woth]; + end; + if file_attribute_reparse_point and dwfileattributes <> 0 then begin + include(attributes,fa_reparsepoint); + end; + if file_attribute_sparse_file and dwfileattributes <> 0 then begin + include(attributes,fa_sparsefile); + end; + if file_attribute_system and dwfileattributes <> 0 then begin + include(attributes,fa_system); + end; + if file_attribute_temporary and dwfileattributes <> 0 then begin + include(attributes,fa_temporary); + end; + with int64recty(size) do begin + lsw:= wsize.nfilesizelow; + msw:= wsize.nfilesizehigh; + end; + modtime:= filetimetotime(ftlastwritetime); + accesstime:= filetimetotime(ftlastaccesstime); + ctime:= filetimetotime(ftcreationtime); + end; +end; + +function rembackslash(po: pchar): pchar; +begin + result:= po; + while result^ = '\' do begin + inc(result); + end; +end; + +//todo: network errormessages +function networkerror(const aerror: longword): syserrorty; +var + wo1,wo2: dword; + buffer1,buffer2: array[0..1024] of msechar; +begin + if aerror = error_extended_error then begin + wo1:= wnetgetlasterrorw({$ifdef FPC}@{$endif}wo2,@buffer1,1024,@buffer2,1024); + if wo1 = no_error then begin + result:= syesetextendederror(pmsechar(@buffer2)+': '+ + pmsechar(@buffer1)); + end + else begin + result:= sye_network; + end; + end + else begin + result:= syeseterror(aerror); + end; +end; + +function findservers(const resource: pnetresource; var names: msestringarty): syserrorty; +var + wo1: longword; + handle: thandle; + po1: pnetresource; + ca1,ca2: cardinal; +begin + result:= sye_network; + wo1:= wnetopenenum(resource_globalnet,resourcetype_disk,0,resource,handle); + if wo1 <> no_error then begin + result:= networkerror(wo1); + exit; + end; + getmem(po1,sizeof(tnetresource)); + ca2:= sizeof(tnetresource); + wo1:= 0; //compilerwarning + repeat + while true do begin + ca1:= 1; + wo1:= wnetenumresource(handle,ca1,po1,ca2); + if wo1 = error_more_data then begin + reallocmem(po1,ca2); + end + else begin + break; + end; + end; + if wo1 = no_error then begin + if (po1^.dwtype = resourcetype_disk) and + (po1^.dwdisplaytype = resourcedisplaytype_server) and + (po1^.lpRemoteName <> nil) then begin + setlength(names,high(names)+2); + names[high(names)]:= rembackslash(po1^.lpRemoteName); + result:= sye_ok; + end + else begin + if po1^.dwUsage and resourceusage_container <> 0 then begin + if findservers(po1,names) = sye_ok then begin + result:= sye_ok; + end; + end + end; + end + else begin + result:= networkerror(wo1); + end; + until wo1 <> no_error; + wnetcloseenum(handle); + freemem(po1); +// result:= sye_ok; +end; + +function findserver(const name: string; var resource: pnetresource): syserrorty; + +var + wo1: longword; + handle: thandle; + ca1,ca2: cardinal; + po1: pnetresource; +begin + result:= sye_network; + wo1:= wnetopenenum(resource_globalnet,resourcetype_disk,0,resource,handle); + resource:= nil; + if wo1 <> no_error then begin + result:= networkerror(wo1); + exit; + end; + getmem(po1,sizeof(tnetresource)); + ca2:= sizeof(tnetresource); + wo1:= 0; //compilerwarning + repeat + while true do begin + ca1:= 1; + wo1:= wnetenumresource(handle,ca1,po1,ca2); + if wo1 = error_more_data then begin + reallocmem(po1,ca2); + end + else begin + break; + end; + end; + if wo1 = no_error then begin + if (po1^.dwtype = resourcetype_disk) and (po1^.lpremotename <> nil) and + (strcomp(pchar(name),rembackslash(po1^.lpremotename)) = 0) then begin + resource:= po1; + result:= sye_ok; + break; + end + else begin + if po1^.dwUsage and resourceusage_container <> 0 then begin + resource:= po1; + result:= findserver(name,resource); + end + end; + end + else begin + result:= networkerror(wo1); + end; + until (wo1 <> no_error) or (result = sye_ok); + wnetcloseenum(handle); + if resource <> po1 then begin + freemem(po1); + end; +end; + +function sys_opendirstream(var stream: dirstreamty): syserrorty; +var + wo1: longword; + int1: integer; +begin + with stream,dirinfo,dirstreamwin32ty(platformdata) do begin + checkdirstreamdata(stream); + result:= sye_ok; + if dirname <> '/' then begin + if msestartsstr('//',dirname) then begin //UNC + if length(dirname) = 2 then begin + finddatapo:= nil; + result:= findservers(nil,msestringarty(finddatapo)); + if finddatapo <> nil then begin + result:= sye_ok; + end; + drivenum:= -3; //network root + handle:= 0; + { + wo1:= wnetopenenum(resource_globalnet,resourcetype_disk,0,nil,handle); + if wo1 <> no_error then begin + result:= sye_dirstream; + end; + } + exit; + end + else begin + if countchars(dirname,msechar('/')) = 2 then begin //list shares + drivenum:= -2; + finddatapo:= nil; + result:= findserver(copy(ansiuppercase(ansistring(dirname)),3,bigint), + pnetresource(finddatapo)); + if finddatapo <> nil then begin + result:= sye_ok; + end; + if result = sye_ok then begin + wo1:= wnetopenenum(resource_globalnet,resourcetype_disk,0, + pnetresource(finddatapo),handle); + if wo1 <> no_error then begin + result:= networkerror(wo1); + end; + freemem(finddatapo); + end; + exit; + end; + end; + end; + drivenum:= -1; + last:= true; + new(finddatapo); + if iswin95 then begin + handle:= findfirstfilea(pchar(string(winfilepath(stream.dirinfo.dirname,'*'))), + {$ifdef FPC} + lpwin32_find_data(finddatapo)); + {$else} + _win32_find_dataa(pointer(finddatapo)^)); + {$endif} + end + else begin + handle:= findfirstfilew(pmsechar(winfilepath(stream.dirinfo.dirname,'*')), + {$ifdef FPC} + lpwin32_find_dataw(finddatapo)); + {$else} + _win32_find_dataw(finddatapo^)); + {$endif} + end; + if handle = invalid_handle_value then begin + int1:= getlasterror; + if int1 <> error_file_not_found then begin + dispose(finddatapo); + setlasterror(int1); + result:= syelasterror; + end; + end + else begin + last:= false; + end; + end; + end; +end; + +function sys_closedirstream(var stream: dirstreamty): syserrorty; +begin + with dirstreamwin32ty(stream.platformdata) do begin + case drivenum of + -3: begin + finalize(msestringarty(finddatapo)); + end; + -2: begin + wnetcloseenum(handle); + end; + -1: begin + dispose(finddatapo); + if handle <> invalid_handle_value then begin + windows.findclose(handle); + end; + end; + end; + end; + result:= sye_ok; +end; + +function sys_readdirstream(var stream: dirstreamty; var info: fileinfoty): boolean; + + procedure checkinfo; + begin + result:= ((fa_all in stream.dirinfo.include) or + (info.extinfo1.attributes * stream.dirinfo.include <> [])) and + (info.extinfo1.attributes * stream.dirinfo.exclude = []) and + checkfilename(info.name,stream); + end; + +var + ca1,ca2: cardinal; + wo1: longword; + po1: pnetresource; + po2: pchar; + +begin + with stream,dirinfo,dirstreamwin32ty(platformdata),finddatapo^,winfo do begin + result:= false; + if (include <> []) and not (fa_all in exclude) then begin + case drivenum of + -3: begin //network root + info.state:= [fis_typevalid,fis_extinfo1valid]; + info.extinfo1.attributes:= [fa_dir]; + info.extinfo1.filetype:= ft_dir; + if integer(handle) <= high(msestringarty(finddatapo)) then begin + repeat + info.name:= msestringarty(finddatapo)[handle]; + checkinfo; + inc(handle); + until result or (integer(handle) > high(msestringarty(finddatapo))); + end; + end; + -2: begin //network share + info.state:= [fis_typevalid,fis_extinfo1valid]; + info.extinfo1.attributes:= [fa_dir]; + info.extinfo1.filetype:= ft_dir; + getmem(po1,sizeof(tnetresource)); + fillchar(po1^,sizeof(tnetresource),0); + ca2:= sizeof(tnetresource); + wo1:= 0; //compilerwarning + repeat + while true do begin + ca1:= 1; + wo1:= wnetenumresource(handle,ca1,po1,ca2); + if wo1 = error_more_data then begin + reallocmem(po1,ca2); + end + else begin + break; + end; + end; + if wo1 = no_error then begin + po2:= strrscan(po1^.lpRemoteName,'\'); + if po2 <> nil then begin + info.name:= msestring( + copy(po1^.lpRemoteName,po2-po1^.lpRemoteName+2,bigint)); + checkinfo; + end + else begin + break; + end; + end + else begin + break; + end; + until result; + freemem(po1); + end; + -1: begin //local root dir + if not last then begin + repeat + if iswin95 then begin + info.name:= pwinfilenameaty(@cfilename)^; + end + else begin + info.name:= cfilename; + end; +{ + if file_attribute_directory and dwfileattributes <> 0 then begin + info.extinfo1.filetype:= ft_dir; + end + else begin + info.extinfo1.filetype:= ft_reg; + end; +} + winfileinfotofileinfo(winfo,wsize,info); + if infolevel = fil_ext2 then begin + //read security level + end; + checkinfo; + if iswin95 then begin + last:= not findnextfilea(handle, + {$ifdef FPC} + lpwin32_find_data(finddatapo)); + {$else} + _win32_find_dataa(pointer(finddatapo)^)); + {$endif} + end + else begin + last:= not findnextfilew(handle, + {$ifdef FPC} + lpwin32_find_dataw(finddatapo)); + {$else} + _win32_find_dataw(finddatapo^)); + {$endif} + end; + until result or last; + end; + end + else begin + ca1:= getlogicaldrives; + info.extinfo1.filetype:= ft_dir; + info.state:= info.state + [fis_typevalid,fis_extinfo1valid]; + info.extinfo1.attributes:= [fa_dir]; + while (drivenum < 32) and not result do begin + if ca1 and bits[drivenum] <> 0 then begin + setlength(info.name,2); + info.name[1]:= msechar(ord('A') + drivenum); + info.name[2]:= ':'; + checkinfo; + end; + inc(drivenum); + end; + end; + end; + end; + end; +end; + +function sys_getfileinfo(const path: filenamety; var info: fileinfoty): boolean; +var + handle: integer; + wstr1: filenamety; + finddata: win32_find_dataw; + lwo1: longword; +begin + clearfileinfo(info); + wstr1:= tosysfilepath(path); + if iswin95 then begin + handle:= findfirstfilea(pchar(string(wstr1)), + {$ifdef FPC}@win32_find_dataa + {$else}twin32finddataa{$endif}(pointer(@finddata)^)); + end + else begin + handle:= findfirstfilew(pmsechar(wstr1), + {$ifdef FPC}@finddata + {$else}twin32finddataw(finddata){$endif}); + end; + if thandle(handle) <> invalid_handle_value then begin + with win32_find_dataw(finddata) do begin +{ + if winfo.dwfileattributes and file_attribute_directory <> 0 then begin + info.extinfo1.filetype:= ft_dir; + end + else begin + info.extinfo1.filetype:= ft_reg; + end; +} + winfileinfotofileinfo(winfo,wsize,info); + if iswin95 then begin + info.name:= pwinfilenameaty(@cfilename)^; + end + else begin + info.name:= cfilename; + end; + end; + windows.findclose(handle); + result:= true; + end + else begin //possibly a drive name + if iswin95 then begin + lwo1:= getfileattributes(pchar(string(wstr1))); + end + else begin + lwo1:= getfileattributesw(pmsechar(wstr1)); + end; + if lwo1 = $ffffffff then begin + result:= false; + end + else begin + if lwo1 and file_attribute_directory <> 0 then begin + info.extinfo1.filetype:= ft_dir; + end + else begin + info.extinfo1.filetype:= ft_reg; + end; + result:= true; + end; + end; +end; + +function sys_getfdinfo(const fd: longint; var info: fileinfoty): boolean; +var + info1: by_handle_file_information; +begin + clearfileinfo(info); + result:= getfileinformationbyhandle(fd,info1); + if result then begin + winfileinfotofileinfo(info1.winfo,info1.wsize,info); + end; +end; + +function sys_setfdrights(const fd: longint; + const rights: filerightsty; + const filename: filenamety = ''): syserrorty; +var //todo: use security attributes + info1: by_handle_file_information; + fname: filenamety; + bo1: boolean; + { + fmap: thandle; + pmem: pointer; + abuf: array[0..max_path] of char; + wbuf: array[0..max_path] of widechar; + dwo1: dword; + } +begin + if getfileinformationbyhandle(fd,info1) then begin + if s_iwusr in rights then begin + info1.winfo.dwfileattributes:= info1.winfo.dwfileattributes and + not file_attribute_readonly; + end + else begin + info1.winfo.dwfileattributes:= info1.winfo.dwfileattributes or + file_attribute_readonly; + end; + { + fmap:= createfilemapping(fd,nil,page_readonly,0,1,nil); + if fmap = 0 then begin + result:= syelasterror(); + end + else begin + pmem:= mapviewoffile(fmap,file_map_read,0,0,1); + if pmem = nil then begin + result:= syelasterror(); + end + else begin + if iswin95 then begin + dwo1:= getmappedfilenamea(getcurrentprocess(),pmem,@abuf,max_path); + end + else begin + dwo1:= getmappedfilenamew(getcurrentprocess(),pmem,@wbuf,max_path); + end; + if dwo1 = 0 then begin + result:= syelasterror(); + end + else begin + + end; + unmapviewoffile(pmem); + end; + closehandle(fmap); + end; + //how to set file attributes from handle on pre XP? + } + fname:= tosysfilepath(filename); + if iswin95 then begin + bo1:= setfileattributesa(pchar(string(fname)),info1.winfo.dwfileattributes); + end + else begin + bo1:= setfileattributesw(pwidechar(fname),info1.winfo.dwfileattributes); + end; + if not bo1 then begin + result:= syelasterror(); + end + else begin + result:= sye_ok; + end; + end + else begin + result:= syelasterror(); + end; +end; + +function sys_access(const path: filenamety; + const accessmodes: accessmodesty): syserrorty; +begin + result:= sye_notimplemented; +end; + +function sys_setfilerights(const path: filenamety; + const rights: filerightsty): syserrorty; +var + fname: filenamety; + dwo1: dword; + bo1: boolean; +begin + fname:= tosysfilepath(path); + if iswin95 then begin + dwo1:= getfileattributesa(pchar(string(fname))); + end + else begin + dwo1:= getfileattributesw(pwidechar(fname)); + end; + if dwo1 = 0 then begin + result:= syelasterror(); + end + else begin + if s_iwusr in rights then begin + dwo1:= dwo1 and not file_attribute_readonly; + end + else begin + dwo1:= dwo1 or file_attribute_readonly; + end; + if iswin95 then begin + bo1:= setfileattributesa(pchar(string(fname)),dwo1); + end + else begin + bo1:= setfileattributesw(pwidechar(fname),dwo1); + end; + if not bo1 then begin + result:= syelasterror(); + end + else begin + result:= sye_ok; + end; + end; +end; +{ +function sys_setfdrights(const rights: filerightsty; + const fd: longint): syserrorty; +begin +end; +} +function sys_getcurrentdir: msestring; +var + ca1: cardinal; + str1: string; +begin + if iswin95 then begin + repeat + ca1:= getcurrentdirectorya(0,nil); + setlength(str1,ca1-1); + until (ca1 < 2) or (getcurrentdirectorya(ca1,@str1[1]) = ca1-1); + result:= msestring(str1); + end + else begin + repeat + ca1:= getcurrentdirectoryw(0,nil); + setlength(result,ca1-1); + until (ca1 < 2) or (getcurrentdirectoryw(ca1,@result[1]) = ca1-1); + end; + tomsefilepath1(result); +end; + +function sys_getapphomedir: filenamety; +begin + result:= apphomedir; +end; + +function sys_getuserhomedir: filenamety; +begin + result:= userhomedir; +end; + +function sys_getusername: msestring; +var + s1: ansistring; + ms1: msestring; + i1: DWORD; +begin + result:= ''; + i1:= 256; + if iswin95 then begin + setlength(s1,i1); + if getusernamea(pointer(s1),@i1) then begin + setlength(s1,i1-1); + result:= msestring(s1); + end; + end + else begin + setlength(ms1,i1); + if getusernamew(pointer(ms1),@i1) then begin + setlength(ms1,i1-1); + result:= ms1; + end; + end; +end; + + +function sys_gettempdir: filenamety; +var + int1: integer; + fna1: filenamety; +// po1: pfilenamechar; +begin + setlength(fna1,max_path+10); + fna1[1]:= #0; + int1:= gettemppathw(length(fna1),pointer(fna1)); + if int1 > length(fna1) then begin + setlength(result,int1); + int1:= gettemppathw(length(fna1),pointer(fna1)); + end; + if assigned(getlongpathnamew) then begin + setlength(result,max_path+10); + int1:= getlongpathnamew(pointer(fna1),pointer(result),length(result)); + if int1 > length(result) then begin + setlength(result,int1); + int1:= getlongpathnamew(pointer(fna1),pointer(result),length(result)); + end; + setlength(result,int1); + end + else begin + setlength(fna1,int1); + result:= fna1; + end; + tomsefilepath1(result); +end; + +function sys_setcurrentdir(const dirname: filenamety): syserrorty; +var + str1: string; +begin + if iswin95 then begin + str1:= ansistring(tosysfilepath(dirname)); + if not setcurrentdirectorya(pchar(str1)) then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; + end + else begin + if not setcurrentdirectoryw(pmsechar(tosysfilepath(dirname))) then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; + end; +end; + +const + CSIDL_PROGRAMS = $0002; { %SYSTEMDRIVE%\Program Files } + CSIDL_PERSONAL = $0005; { %USERPROFILE%\My Documents } + CSIDL_FAVORITES = $0006; { %USERPROFILE%\Favorites } + CSIDL_STARTUP = $0007; { %USERPROFILE%\Start menu\Programs\Startup } + CSIDL_RECENT = $0008; { %USERPROFILE%\Recent } + CSIDL_SENDTO = $0009; { %USERPROFILE%\Sendto } + CSIDL_STARTMENU = $000B; { %USERPROFILE%\Start menu } + CSIDL_MYMUSIC = $000D; { %USERPROFILE%\Documents\My Music } + CSIDL_MYVIDEO = $000E; { %USERPROFILE%\Documents\My Videos } + CSIDL_DESKTOPDIRECTORY = $0010; { %USERPROFILE%\Desktop } + CSIDL_NETHOOD = $0013; { %USERPROFILE%\NetHood } + CSIDL_TEMPLATES = $0015; { %USERPROFILE%\Templates } + CSIDL_COMMON_STARTMENU = $0016; { %PROFILEPATH%\All users\Start menu } + CSIDL_COMMON_PROGRAMS = $0017; { %PROFILEPATH%\All users\Start menu\Programs } + CSIDL_COMMON_STARTUP = $0018; { %PROFILEPATH%\All users\Start menu\Programs\Startup } + CSIDL_COMMON_DESKTOPDIRECTORY = $0019; { %PROFILEPATH%\All users\Desktop } + CSIDL_APPDATA = $001A; { %USERPROFILE%\Application Data (roaming) } + CSIDL_PRINTHOOD = $001B; { %USERPROFILE%\Printhood } + CSIDL_LOCAL_APPDATA = $001C; { %USERPROFILE%\Local Settings\Application Data (non roaming) } + CSIDL_COMMON_FAVORITES = $001F; { %PROFILEPATH%\All users\Favorites } + CSIDL_INTERNET_CACHE = $0020; { %USERPROFILE%\Local Settings\Temporary Internet Files } + CSIDL_COOKIES = $0021; { %USERPROFILE%\Cookies } + CSIDL_HISTORY = $0022; { %USERPROFILE%\Local settings\History } + CSIDL_COMMON_APPDATA = $0023; { %PROFILESPATH%\All Users\Application Data } + CSIDL_WINDOWS = $0024; { %SYSTEMROOT% } + CSIDL_SYSTEM = $0025; { %SYSTEMROOT%\SYSTEM32 (may be system on 95/98/ME) } + CSIDL_PROGRAM_FILES = $0026; { %SYSTEMDRIVE%\Program Files } + CSIDL_MYPICTURES = $0027; { %USERPROFILE%\My Documents\My Pictures } + CSIDL_PROFILE = $0028; { %USERPROFILE% } + CSIDL_PROGRAM_FILES_COMMON = $002B; { %SYSTEMDRIVE%\Program Files\Common } + CSIDL_COMMON_TEMPLATES = $002D; { %PROFILEPATH%\All Users\Templates } + CSIDL_COMMON_DOCUMENTS = $002E; { %PROFILEPATH%\All Users\Documents } + CSIDL_COMMON_ADMINTOOLS = $002F; { %PROFILEPATH%\All Users\Start Menu\Programs\Administrative Tools } + CSIDL_ADMINTOOLS = $0030; { %USERPROFILE%\Start Menu\Programs\Administrative Tools } + CSIDL_COMMON_MUSIC = $0035; { %PROFILEPATH%\All Users\Documents\my music } + CSIDL_COMMON_PICTURES = $0036; { %PROFILEPATH%\All Users\Documents\my pictures } + CSIDL_COMMON_VIDEO = $0037; { %PROFILEPATH%\All Users\Documents\my videos } + CSIDL_CDBURN_AREA = $003B; { %USERPROFILE%\Local Settings\Application Data\Microsoft\CD Burning } + CSIDL_PROFILES = $003E; { %PROFILEPATH% } + + CSIDL_FLAG_CREATE = $8000; { (force creation of requested folder if it doesn't exist yet) } + +type + SHGetFolderPathW = function (hwndowner: HWND; nFolder: integer; hToken: thandle; + dwFlags: DWORD; pszPath: LPTSTR): HRESULT; stdcall; +procedure doinit; +var + libhandle: thandle; + po1: SHGetFolderPathW; + buffer: array[0..max_path] of widechar; +// int1: integer; + +begin + gmtoff:= sys_localtimeoffset; + po1:= nil; //compiler warning + libhandle:= loadlibrary('shell32.dll'); + if libhandle <> 0 then begin + {$ifdef FPC}pointer(po1){$else}po1{$endif}:= + getprocaddress(libhandle,'SHGetFolderPathW'); + if not assigned(po1) then begin + freelibrary(libhandle); + libhandle:= loadlibrary('shfolder.dll'); + if libhandle <> 0 then begin + {$ifdef FPC}pointer(po1){$else}po1{$endif}:= + getprocaddress(libhandle,'SHGetFolderPathW'); + end; + end; + end; + if libhandle <> 0 then begin + if assigned(po1) then begin + if po1(0,CSIDL_APPDATA or CSIDL_FLAG_CREATE,0,0,@buffer) = 0 then begin + apphomedir:= filepath(buffer,fk_file); + end; + if po1(0,CSIDL_PROFILE or CSIDL_FLAG_CREATE,0,0,@buffer) = 0 then begin + userhomedir:= filepath(buffer,fk_file); + end; + end; + freelibrary(libhandle); + end; + checkprocaddresses(['kernel32.dll'], + ['GetLongPathNameW'], + [{$ifndef FPC}@{$endif}@GetLongPathNameW]); + checkprocaddresses(['user32.dll'], + ['AllowSetForegroundWindow'], + [{$ifndef FPC}@{$endif}@AllowSetForegroundWindow]); + checkprocaddresses(['ntdll.dll'],['ZwQueryInformationProcess'], + [@ZwQueryInformationProcess]); + checkprocaddresses(['ntdll.dll'],['NtQueryInformationProcess'], + [@NtQueryInformationProcess]); + checkprocaddresses(['kernel32.dll'],['GetProcessId'], + [@GetProcessId]); +end; +{ +procedure initformatsettings; +begin + thousandseparatormse:= thousandseparator; + decimalseparatormse:= decimalseparator; + dateseparatormse:= dateseparator; + timeseparatormse:= timeseparator; +end; +} +initialization +{$ifdef FPC} +// winwidestringalloc:= false; + {$endif} +// initformatsettings; + doinit; +//iswin95:= true; +//iswin98:= true; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msesysintf1.pas b/mseide-msegui/lib/common/kernel/windows/msesysintf1.pas new file mode 100644 index 0000000..2b05eb0 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msesysintf1.pas @@ -0,0 +1,577 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesysintf1; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$if fpc_fullversion >= 30001} + {$define hascompareoptions} +{$endif} +interface +uses + msesystypes; +var + iswin95: boolean; + iswin98: boolean; + cancleartype: boolean; + +{$include ..\msesysintf1.inc} + +type + win32semty = record //64 bit + event: thandle; //8 + semacount: integer; //4 + destroyed: integer; //4 total 16 + {$ifdef cpu64} //semty = 64 + platformdata: array[2..7] of pointer; + {$else} + platformdata: array[3..7] of pointer; + {$endif} + end; + +implementation +uses + windows,sysutils,dateutils,msedynload; + +type + {$ifdef FPC} + PCRITICAL_SECTION_DEBUG = ^CRITICAL_SECTION_DEBUG; + //bug in struct.inc + CRITICAL_SECTION = record + DebugInfo : PCRITICAL_SECTION_DEBUG; + LockCount : LONG; + RecursionCount : LONG; + OwningThread : HANDLE; + LockSemaphore : HANDLE; + Reserved : DWORD; + end; + {$endif} + win32mutexty = record //64bit + mutex: trtlcriticalsection; //40 bytes + trycount: integer; //4 + lockco: integer; //4 + owningth: threadty; //8 total 56 + {$ifdef cpu64} //mutexty = 80 + platformdata: array[7..9] of pointer; // 24 + {$else} + platformdata: array[7..7] of pointer; + {$endif} + end; + + condeventsty = (ce_signal,ce_broadcast); + win32condty = record //64bit + events: array[condeventsty] of thandle; //16 + waiterscountlock: trtlcriticalsection; //40 + mutex: trtlcriticalsection; //40 total 100 + waiterscount: integer; //4 + {$ifdef cpu64} //condty = 256 + platformdata: array[25..63] of cardinal; // 156 + {$else} + platformdata: array[15..31] of pointer; + {$endif} + end; + +var + TryEnterCriticalSection: function ( + var lpCriticalSection: TRTLCriticalSection): BOOL; stdcall; + +function sys_getlasterror: Integer; +begin + result:= windows.GetLastError; +end; + +procedure sys_setlasterror(const avalue: integer); +begin + windows.setlasterror(avalue); +end; + +function sys_geterrortext(aerror: integer): string; +const + maxlen = 1024; +var + int1: integer; +begin + setlength(result,maxlen); + int1:= formatmessage(format_message_from_system,nil,aerror,0,pchar(result),maxlen,nil); + setlength(result,int1); +end; + +function sys_mutexcreate(out mutex: mutexty): syserrorty; +begin + with win32mutexty(mutex) do begin + windows.initializecriticalsection(mutex); + trycount:= 0; + lockco:= 0; + owningth:= 0; + end; + result:= sye_ok; +end; + +function sys_mutexdestroy(var mutex: mutexty): syserrorty; +begin + result:= sye_ok; + windows.deletecriticalsection(win32mutexty(mutex).mutex); +end; + +function lockmutex(var mutex: mutexty; const noblock: boolean): syserrorty; +var +// bo1: boolean; + id: threadty; +begin + with win32mutexty(mutex) do begin + if not iswin95 then begin + if noblock then begin + if not tryentercriticalsection(mutex) then begin + result:= sye_busy; + exit; + end; + end + else begin + windows.entercriticalsection(mutex); + end; + end + else begin + while interlockedincrement(trycount) > 1 do begin + interlockeddecrement(trycount); + windows.sleep(0); + end; + id:= threadty(windows.getcurrentthreadid); + if noblock and not((lockco = 0) or (owningth = id)) then begin + interlockeddecrement(trycount); + result:= sye_busy; + exit; + end; + inc(lockco); + interlockeddecrement(trycount); + windows.entercriticalsection(mutex); + owningth:= id; + end; + end; + result:= sye_ok; +end; + +function sys_mutexlock(var mutex: mutexty): syserrorty; +begin + result:= lockmutex(mutex,false); +end; + +function sys_mutextrylock(var mutex: mutexty): syserrorty; +begin + result:= lockmutex(mutex,true); +end; + +function sys_mutexunlock(var mutex: mutexty): syserrorty; +begin + with win32mutexty(mutex) do begin + if iswin95 then begin + while interlockedincrement(trycount) > 1 do begin + interlockeddecrement(trycount); + windows.sleep(0); + end; + dec(lockco); + if lockco = 0 then begin + owningth:= 0; + end; + interlockeddecrement(trycount); + end; + windows.leavecriticalsection(mutex); + end; + result:= sye_ok; +end; + +function sys_semcreate(out sem: semty; count: integer): syserrorty; +begin + fillchar(sem,sizeof(sem),0); + with win32semty(sem) do begin + semacount:= count; + event:= createevent(nil,false,false,nil); + result:= sye_ok; + end; +end; + +function sempost1(var sem: semty): syserrorty; +begin + with win32semty(sem) do begin + if interlockedincrement(semacount) <= 0 then begin + setevent(event); + end; + result:= sye_ok; + end; +end; + +function sys_sempost(var sem: semty): syserrorty; +begin + with win32semty(sem) do begin + if destroyed <> 0 then begin + result:= sye_semaphore; + exit; + end; + end; + result:= sempost1(sem); +end; + +function sys_semdestroy(var sem: semty): syserrorty; +var + int1: integer; + +begin + with win32semty(sem) do begin + int1:= interlockedincrement(destroyed); + if int1 = 1 then begin + while semacount < 0 do begin + sempost1(sem); + end; + closehandle(event); + end; + end; + result:= sye_ok; +end; + +function sys_semwait(var sem: semty; timeoutusec: integer): syserrorty; +var + int1: integer; +begin + result:= sye_semaphore; + with win32semty(sem) do begin + if destroyed <> 0 then begin + exit; + end; + if interlockeddecrement(semacount) < 0 then begin + if timeoutusec <= 0 then begin + timeoutusec:= integer(infinite); + end + else begin + timeoutusec:= timeoutusec div 1000; + end; + int1:= waitforsingleobject(event,timeoutusec); + if int1 = wait_object_0 then begin + result:= sye_ok; + end + else begin + if int1 = wait_timeout then begin + result:= sye_timeout; + end; + end; + end + else begin + result:= sye_ok; + end; + end; +end; + +function sys_semcount(var sem: semty): integer; +begin + with win32semty(sem) do begin + result:= semacount; + if result < 0 then begin + result:= 0; + end; + end; +end; + +function sys_semtrywait(var sem: semty): boolean; +begin + with win32semty(sem) do begin + if destroyed <> 0 then begin + result:= false; + exit; + end; + result:= semacount > 0; + if result then begin + result:= interlockeddecrement(semacount) >= 0; + if not result then begin + interlockeddecrement(semacount); + end; + end; + end; +end; + +function sys_condcreate(out cond: condty): syserrorty; +begin + with win32condty(cond) do begin + waiterscount:= 0; + windows.initializecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + windows.initializecriticalsection({$ifdef FPC}@{$endif}mutex); + events[ce_signal]:= createevent(nil,false,false,nil); + events[ce_broadcast]:= createevent(nil,true,false,nil); + end; + result:= sye_ok; +end; + +function sys_conddestroy(var cond: condty): syserrorty; +begin + with win32condty(cond) do begin + closehandle(events[ce_signal]); + closehandle(events[ce_broadcast]); + windows.deletecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + windows.deletecriticalsection({$ifdef FPC}@{$endif}mutex); + end; + result:= sye_ok; +end; + +function sys_condlock(var cond: condty): syserrorty; +begin + with win32condty(cond) do begin + windows.entercriticalsection({$ifdef FPC}@{$endif}mutex); + end; + result:= sye_ok; +end; + +function sys_condunlock(var cond: condty): syserrorty; +begin + with win32condty(cond) do begin + windows.leavecriticalsection({$ifdef FPC}@{$endif}mutex); + end; + result:= sye_ok; +end; + +function sys_condsignal(var cond: condty): syserrorty; +var + bo1: boolean; +begin + with win32condty(cond) do begin + windows.entercriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + bo1:= waiterscount > 0; + windows.leavecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + if bo1 then begin + setevent(events[ce_signal]); + end; + end; + result:= sye_ok; +end; + +function sys_condbroadcast(var cond: condty): syserrorty; +var + bo1: boolean; +begin + with win32condty(cond) do begin + windows.entercriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + bo1:= waiterscount > 0; + windows.leavecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + if bo1 then begin + setevent(events[ce_broadcast]); + end; + end; + result:= sye_ok; +end; + +function sys_condwait(var cond: condty; timeoutusec: integer): syserrorty; + //timeoutusec = 0 -> no timeout + //sye_ok -> condition signaled + //sye_timeout -> timeout + //sye_cond -> error +var + int1: integer; + bo1: boolean; + +begin + result:= sye_cond; + with win32condty(cond) do begin + windows.entercriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + inc(waiterscount); + windows.leavecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + windows.leavecriticalsection({$ifdef FPC}@{$endif}mutex); + if timeoutusec = 0 then begin + timeoutusec:= integer(infinite); + end + else begin + timeoutusec:= timeoutusec div 1000; + end; + int1:= waitformultipleobjects(2,@events,false,timeoutusec); + windows.entercriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + dec(waiterscount); + bo1:= (int1 = wait_object_0 + ord(ce_broadcast)) and (waiterscount = 0); + windows.leavecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + if bo1 then begin + resetevent(events[ce_broadcast]); + end; + if int1 = wait_timeout then begin + result:= sye_timeout; + end + else begin + if (int1 < wait_abandoned_0) or (int1 > wait_abandoned_0 + 1) then begin + result:= sye_ok; + end; + end; + windows.entercriticalsection({$ifdef FPC}@{$endif}mutex); + end; +end; + +function localtimeshift(value: tdatetime; const tolocal: boolean) : integer; + //todo: optimize + function systitodatetime(const ayear: word; const systi: systemtime): tdatetime; + var + wo1,wo2,wo3: word; + dt1: tdatetime; + int1: integer; + begin + with systi do begin + dt1:= encodedate(ayear,wmonth,1); + wo1:= dayoftheweek(dt1); + if wo1 = 7 then begin + wo1:= 0; //0 -> so + end; + wo2:= wday; //n't occurence + wo3:= 0; //compiler warning + for int1:= 1 to daysinamonth(ayear,wmonth) do begin + if wo1 = wdayofweek then begin + wo3:= int1; + dec(wo2); + if wo2 = 0 then begin + break; + end; + end; + wo1:= (wo1 + 1) mod 7; + end; + result:= encodedate(ayear,wmonth,wo3) + encodetime(whour,wminute,0,0); + end; + end; + +var + tinfo: time_zone_information; + year: word; + stddate,dldate: tdatetime; + bo1: boolean; +begin + {$ifdef FPC} + if gettimezoneinformation(@tinfo) = time_zone_id_invalid then begin + {$else} + if gettimezoneinformation(tinfo) = time_zone_id_invalid then begin + {$endif} + result:= 0; + end + else begin + with tinfo do begin + result:= bias; + if tolocal then begin + value:= incminute(value,-bias); //->localtime + end; + if (standarddate.wmonth <> daylightdate.wmonth) and (value > 0) then begin + try + year:= yearof(value); + stddate:= systitodatetime(year,standarddate); + dldate:= systitodatetime(year,daylightdate); + if stddate > dldate then begin + bo1:= (value >= dldate) and (value < stddate); + end + else begin + bo1:= (value <= dldate) and (value > stddate); + end; + if bo1 then begin + result:= result + daylightbias; + end + else begin + result:= result + standardbias; + end; + except + end; + end; + end; + end; + if tolocal then begin + result:= -result; + end; +end; + +function sys_utctolocaltime(const value: tdatetime): tdatetime; +begin + result:= incminute(value,localtimeshift(value,true)); +// result:= value + sys_localtimeoffset; //todo +end; + +function sys_localtimetoutc(const value: tdatetime): tdatetime; +begin + result:= incminute(value,localtimeshift(value,false)); +// result:= value - sys_localtimeoffset; //todo +end; + +{$ifdef FPC} +function DoCompareStringA(const s1, s2: unicodestring; Flags: DWORD): PtrInt; + var + a1, a2: AnsiString; + begin + a1:=ansistring(s1); + a2:=ansistring(s2); + SetLastError(0); + Result:=CompareStringA(LOCALE_USER_DEFAULT,Flags,pchar(a1), + length(a1),pchar(a2),length(a2))-2; + end; + +function DoCompareStringW(const s1, s2: unicodestring; Flags: DWORD): PtrInt; + begin + SetLastError(0); + Result:=CompareStringW(LOCALE_USER_DEFAULT,Flags,pwidechar(s1), + length(s1),pwidechar(s2),length(s2))-2; + if GetLastError=0 then + Exit; + if GetLastError=ERROR_CALL_NOT_IMPLEMENTED then // Win9x case + Result:=DoCompareStringA(s1, s2, Flags); + if GetLastError<>0 then + RaiseLastOSError; + end; + {$ifdef hascompareoptions} +function win32compareunicodestring(const s1, s2 : unicodestring; + options : tcompareoptions): ptrint; +var + flags: dword; +begin + flags:= 0; + if coignorecase in options then begin + flags:= norm_ignorecase; + end; + result:= docomparestringw(s1, s2, flags); +end; + {$else} +function Win32CompareUnicodeString(const s1, s2 : unicodestring) : PtrInt; + begin + Result:=DoCompareStringW(s1, s2, 0); + end; + +function Win32CompareTextunicodeString(const s1, s2 : unicodestring) : PtrInt; + begin + Result:=DoCompareStringW(s1, s2, NORM_IGNORECASE); + end; + {$endif} +{$endif} + +procedure doinit; +var + info: osversioninfo; + int1: integer; + +begin +{$ifdef FPC} + {$ifdef hascompareoptions} + widestringmanager.CompareUnicodeStringProc:=@win32CompareUnicodeString; + {$else} + widestringmanager.CompareUnicodeStringProc:=@win32CompareUnicodeString; + widestringmanager.CompareTextUnicodeStringProc:=@win32CompareTextUnicodeString; + {$endif} +{$endif} + + info.dwOSVersionInfoSize:= sizeof(info); + if getversionex(info) then begin + with info do begin + int1:= dwmajorversion*1000+dwminorversion; + cancleartype:= int1 >= 5001; + iswin95:= dwPlatformId = ver_platform_win32_windows; + if iswin95 then begin + iswin98:= (dwMajorVersion >= 4) or + (dwMajorVersion = 4) and (dwminorVersion > 0); + end; + end; + end; + checkprocaddresses(['kernel32.dll'], + ['TryEnterCriticalSection'], + [{$ifndef FPC}@{$endif}@TryEnterCriticalSection]); + +end; + +initialization + doinit; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msesystimer.pas b/mseide-msegui/lib/common/kernel/windows/msesystimer.pas new file mode 100644 index 0000000..700f201 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msesystimer.pas @@ -0,0 +1,198 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesystimer; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseguiglob,mselist,msetypes,windows; + +function setsystimer(us: longword): guierrorty; + //send et_timer event after delay or us (micro seconds) +procedure systimerinit(const aeventlist: tobjectqueue; const apphandle: hwnd); +procedure systimerdeinit; +function systimerus: longword; +function setmmtimer(const avalue: boolean): boolean; + +implementation +uses + msewinglob,mseevent,msesys,msedynload{,mseguiintf},msedate; + +const + MMSYSERR_NOERROR = 0; + + TIME_ONESHOT = 0; { program timer for single event } + TIME_PERIODIC = 1; { program for continuous periodic event } + TIME_CALLBACK_FUNCTION = $0000; { callback is function } + TIME_CALLBACK_EVENT_SET = $0010; { callback is event - use SetEvent } + TIME_CALLBACK_EVENT_PULSE = $0020; { callback is event - use PulseEvent } + +type + MMRESULT = Longint; + PTimeCaps = ^TTimeCaps; + timecaps_tag = record + wPeriodMin: UINT; { minimum period supported } + wPeriodMax: UINT; { maximum period supported } + end; + TTimeCaps = timecaps_tag; + TIMECAPS = timecaps_tag; + TFNTimeCallBack = procedure(uTimerID, uMessage: UINT; + dwUser, dw1, dw2: DWORD) stdcall; +var + timeKillEvent: function (uTimerID: UINT): MMRESULT; stdcall; + timeGetDevCaps: function (lpTimeCaps: PTimeCaps; + uSize: UINT): MMRESULT; stdcall; + timeBeginPeriod: function (uPeriod: UINT): MMRESULT; stdcall; + timeEndPeriod: function (uPeriod: UINT): MMRESULT; stdcall; + timeSetEvent: function (uDelay, uResolution: UINT; + lpFunction: TFNTimeCallBack; dwUser: DWORD; uFlags: UINT): MMRESULT; stdcall; + timeGetTime: function: DWORD; stdcall; + +var + eventlist: tobjectqueue; + applicationhandle: hwnd; + + timer: longword; + mmtimer: mmresult; + usemmtimer: boolean = false; + hasmmtimer: boolean = false; + mmtimerchecked: boolean = false; +// mmtimershift: longword; + ticaps: ttimecaps; +// perfref: qword; +// perffrequ: qword; + +function checkmmtimer: boolean; +begin + result:= hasmmtimer; + if not result and not mmtimerchecked then begin + mmtimerchecked:= true; + hasmmtimer:= checkprocaddresses(['winmm.dll'], + ['timeKillEvent', + 'timeGetDevCaps', + 'timeBeginPeriod', + 'timeEndPeriod', + 'timeSetEvent', + 'timeGetTime'], + [{$ifndef FPC}@{$endif}@timeKillEvent, + {$ifndef FPC}@{$endif}@timeGetDevCaps, + {$ifndef FPC}@{$endif}@timeBeginPeriod, + {$ifndef FPC}@{$endif}@timeEndPeriod, + {$ifndef FPC}@{$endif}@timeSetEvent, + {$ifndef FPC}@{$endif}@timeGetTime]); + result:= hasmmtimer and + (timegetdevcaps(@ticaps,sizeof(timecaps)) = MMSYSERR_NOERROR); + end; +end; + +function setmmtimer(const avalue: boolean): boolean; +begin + result:= true; + if avalue then begin + if not usemmtimer then begin + result:= checkmmtimer; + if result then begin + usemmtimer:= true; + timebeginperiod(ticaps.wperiodmin); + end; + end; + end + else begin + if usemmtimer then begin + timeendperiod(ticaps.wperiodmin); + usemmtimer:= false; + end; + end; +end; + +function systimerus: longword; +begin + if usemmtimer then begin + result:= timegettime() * 1000; + end + else begin + result:= gettickcount * 1000; + end; +end; + +procedure killtimer; +begin + if timer <> 0 then begin + windows.killtimer(0,timer); + timer:= 0; + end; + if mmtimer <> 0 then begin + timekillevent(mmtimer); + mmtimer:= 0; + end; +end; + +procedure TimerProc(hwnd: hwnd; uMsg: longword; idEvent: ptruint; + dwTime: longword); stdcall; +begin + killtimer; + eventlist.add(tmseevent.create(ek_timer)); +end; + +procedure mmtimerproc(uTimerID, uMessage: UINT; + dwUser, dw1, dw2: DWORD); stdcall; +begin + killtimer; + windows.postmessage(applicationhandle,timermessage,0,0); +end; + +function setsystimer(us: longword): guierrorty; +var + ms: longword; +begin + killtimer; + if usemmtimer then begin + ms:= us div 1000; + if ms < ticaps.wperiodmin then begin + ms:= ticaps.wperiodmin; + end; + mmtimer:= timesetevent(ms,1,@mmtimerproc,0,time_oneshot); + //1ms resolution + if mmtimer = 0 then begin + result:= gue_timer; + end + else begin + result:= gue_ok; + end; + end + else begin + timer:= windows.settimer(0,0,us div 1000,@timerproc); + if timer = 0 then begin + result:= gue_timer; + end + else begin + result:= gue_ok; + end; + end; +end; + +procedure systimerdeinit; +begin + killtimer; + eventlist:= nil; +end; + +procedure systimerinit(const aeventlist: tobjectqueue; const apphandle: hwnd); +begin + eventlist:= aeventlist; + applicationhandle:= apphandle; +end; + +initialization +finalization + if usemmtimer then begin + timeendperiod(ticaps.wperiodmin); + usemmtimer:= false; + end; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/mseuniintf.pas b/mseide-msegui/lib/common/kernel/windows/mseuniintf.pas new file mode 100644 index 0000000..e7524c8 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/mseuniintf.pas @@ -0,0 +1,27 @@ +{ MSEgui Copyright (c) 1999-2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseuniintf; //i386-win32 +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics; + +{$include ..\mseuniintf.inc} + +implementation +uses + mseguiintf; + +function uni_getfontwithglyph(var drawinfo: drawinfoty): boolean; +begin + result:= false; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msewindnd.pas b/mseide-msegui/lib/common/kernel/windows/msewindnd.pas new file mode 100644 index 0000000..b788a7d --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msewindnd.pas @@ -0,0 +1,1048 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msewindnd; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + windows,msetypes,msegui,mseguiintf,mseguiglob,msegraphutils,msestrings, + mseclasses,activex,mseglob,msedragglob; + +type + {$ifndef FPC} + WINOLEAPI = HResult; + HMetaFilePict = Pointer; + OleChar = WChar; + HALFPARAM = WORD; + HALFLRESULT = WORD; + LPOLESTR = ^OLECHAR; + tmessage = tmsg; + const + WM_QUIT = 18; + WM_USER = 1024; +type + {$endif} + + TagSTGMEDIUM = Record + Tymed : DWord; + Case Integer Of + 0: (dummy: pointer; + PUnkForRelease: Pointer {IUnknown}); + 1: (HBITMAP : hBitmap); + 2: (HMETAFILEPICT : hMetaFilePict); + 3: (HENHMETAFILE : hEnhMetaFile); + 4: (HGLOBAL : hGlobal); + 5: (lpszFileName : LPOLESTR); + 6: (pstm : Pointer{IStream}); + 7: (pstg : Pointer{IStorage}); + End; + USTGMEDIUM = TagSTGMEDIUM; + STGMEDIUM = USTGMEDIUM; + TStgMedium = TagSTGMEDIUM; + PStgMedium = ^TStgMedium; + + IDropSource = interface(IUnknown) + ['{00000121-0000-0000-C000-000000000046}'] + function QueryContinueDrag(fEscapePressed: BOOL; + grfKeyState: DWORD):HResult;StdCall; + function GiveFeedback(dwEffect: DWORD): HResult;StdCall; + end; + + ienumformatetc = interface(iunknown)['{00000103-0000-0000-c000-000000000046}'] + function next(celt: ulong; out rgelt: formatetc; + pceltfetched:pulong = nil): hresult; stdcall; + function skip(celt: ulong): hresult; stdcall; + function reset: hresult; stdcall; + function clone(out penum: ienumformatetc): hresult; stdcall; + end; + + idataobject = interface (iunknown) ['{0000010e-0000-0000-c000-000000000046}'] + function getdata(const formatetcin: formatetc; + out medium: stgmedium): hresult; stdcall; + function getdatahere(const pformatetc: formatetc; + var medium: stgmedium): hresult; stdcall; + function querygetdata(const pformatetc: formatetc): hresult; stdcall; + function getcanonicalformatetc(const pformatetcin: formatetc; + out pformatetcout: formatetc): hresult; stdcall; + function setdata (const pformatetc: formatetc; + const medium:stgmedium; frelease: bool): hresult; stdcall; + function enumformatetc(dwdirection : dword; + out enumformatetcpara: ienumformatetc): hresult; stdcall; + function dadvise(const formatetc : formatetc; advf: dword; + const advsink: iadvisesink; + out dwconnection: dword): hresult; stdcall; + function dunadvise(dwconnection: dword): hresult; stdcall; + function enumdadvise(out enumadvise: ienumstatdata): hresult; stdcall; + end; + + idroptarget = interface(iunknown) ['{00000122-0000-0000-c000-000000000046}'] + function dragenter(const dataobj: idataobject; grfkeystate: dword; + pt: tpoint; var dweffect: dword): hresult; stdcall; + function dragover(grfkeystate: dword; pt: tpoint; + var dweffect: dword): hresult; stdcall; + function dragleave: hresult;stdcall; + function drop(const dataobj: idataobject; grfkeystate: dword; pt: tpoint; + var dweffect: dword):hresult; stdcall; + end; + +function RegisterDragDrop(hwnd:HWND; pDropTarget: IDropTarget): WINOLEAPI; + stdcall; external 'ole32.dll' name 'RegisterDragDrop'; +function RevokeDragDrop(hwnd:HWND):WINOLEAPI; + stdcall; external 'ole32.dll' name 'RevokeDragDrop'; +function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource; + dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI; + stdcall; external 'ole32.dll' name 'DoDragDrop'; +procedure ReleaseStgMedium(var _para1:STGMEDIUM);stdcall; + external 'ole32.dll' name 'ReleaseStgMedium'; + +procedure regsysdndwindow(const awindow: winidty); +procedure windnddeinit; +function sysdnd(const action: sysdndactionty; + const aintf: isysdnd; const arect: rectty; + out aresult: boolean): guierrorty; +function sysdndreaddata(var adata: string; + const typeindex: integer): guierrorty; +function sysdndreadtext(var atext: msestring; + const typeindex: integer): guierrorty; +//todo: scrolling + +implementation +uses + msethread,msesysutils,sysutils,mseevent,msesysdnd; +type + sdndeventkindty = (sdndk_regwindow,sdndk_unregwindow,sdndk_reject,sdndk_accept, + sdndk_finished,sdndk_readdataortext, + sdndk_writebegin,sdndk_writecheck,sdndk_writeend); + + tsdndevent = class(tmseevent) + private + fsdndkind: sdndeventkindty; + fwinid: winidty; + factions: dndactionsty; + fintf: isysdnd; + frect: rectty; + findex: integer; + fdatapo: pstring; + ftextpo: pmsestring; + public + property sdndkind: sdndeventkindty read fsdndkind; + constructor create(const akind: sdndeventkindty; + const awinid: winidty = 0; + const aactions: dndactionsty = []; + const aintf: isysdnd = nil; + const arect: prectty = nil; + const aindex: integer = -1; + const adatapo: pstring = nil; + const atextpo: pmsestring = nil); + end; + + tdataobject = class(tlinkedobject,idataobject,idropsource) + private + fcheckpending: integer; + protected + fdata: stringarty; + ftext: msestringarty; + findex: integer; + fintf: isysdnd; + factions: dndactionsty; + ftargetactions: dndactionsty; + fformats: msestringarty; + fformatistext: booleanarty; + fcformats: integerarty; + fdrop: boolean; + fcancel: boolean; + ffinished: boolean; + function checkformat(const aformat: formatetc): hresult; + function getdatasize(out apo: pointer): integer; + function dogetdata(var medium: stgmedium): hresult; + procedure begindrag(const aevent: tsdndevent); + + //idataobject + function getdata(const formatetcin: formatetc; + out medium: stgmedium): hresult; stdcall; + function getdatahere(const pformatetc: formatetc; + var medium: stgmedium): hresult; stdcall; + function querygetdata(const pformatetc: formatetc): hresult; stdcall; + function getcanonicalformatetc(const pformatetcin : formatetc; + out pformatetcout: formatetc): hresult; stdcall; + function setdata (const pformatetc: formatetc; + const medium: stgmedium; frelease: bool): hresult; stdcall; + function enumformatetc(dwdirection: dword; + out enumformatetcpara: ienumformatetc): hresult; stdcall; + function dadvise(const formatetc: formatetc; advf: dword; + const advsink: iadvisesink; out dwconnection: dword): hresult; stdcall; + function dunadvise(dwconnection: dword): hresult; stdcall; + function enumdadvise(out enumadvise: ienumstatdata): hresult; stdcall; + //idropsource + function querycontinuedrag(fescapepressed: bool; + grfkeystate: dword):hresult; stdcall; + function givefeedback(dweffect: dword): hresult; stdcall; + end; + + writestatety = (ws_active,{ws_cancel,ws_drop,}ws_checking); + writestatesty = set of writestatety; + + oleformatarty = array of tformatetc; + tsysdndhandler = class(teventthread,idroptarget) + protected + fdragwinid: winidty; + fdataobject: idataobject; + foleformats: oleformatarty; + fformats: msestringarty; + fformatistext: booleanarty; + fdata: tdataobject; +// fdestaction: dndactionsty; + fwritestate: writestatesty; + function execute(thread: tmsethread): integer; override; + function getwinid(const apos: pointty): winidty; + procedure clearformats; + procedure writecheck(const aactions: dndactionsty; var aresult: boolean); + + //iunknown + function queryinterface({$ifdef fpc_has_constref}constref{$else}const{$endif} + iid: tguid; out obj): hresult; virtual; stdcall; + function _addref: integer; stdcall; + function _release: integer; stdcall; + //idroptarget + function dragenter(const dataobj: idataobject; grfkeystate: dword; + pt: tpoint; var dweffect: dword): hresult; stdcall; + function dragover(grfkeystate: dword; pt: tpoint; + var dweffect: dword): hresult; stdcall; + function dragleave: hresult; stdcall; + function drop(const dataobj: idataobject; grfkeystate: dword; pt: tpoint; + var dweffect: dword):hresult; stdcall; + public + constructor create; + destructor destroy; override; + procedure terminate; override; + procedure postevent(event: tsdndevent; const aquit: boolean); + function waitevent(const timeoutus: integer = -1): tsdndevent; + procedure regsysdndwindow(const awindow: winidty); + end; + + tenumformatetc = class(tinterfacedobject,ienumformatetc) + private + fdataobj: tdataobject; + findex: integer; + protected + function next(celt: ulong; out rgelt: formatetc; + pceltfetched:pulong = nil): hresult; stdcall; + function skip(celt: ulong): hresult; stdcall; + function reset: hresult; stdcall; + function clone(out penum: ienumformatetc): hresult; stdcall; + public + constructor create(const adataobj: tdataobject); + end; + +const + timeout = 500000; //us + predefclipboardnames: array[1..16] of msestring = ( + 'CF_TEXT', //1 + 'CF_BITMAP', //2 + 'CF_METAFILEPICT',//3 + 'CF_SYLK', //4 + 'CF_DIF', //5 + 'CF_TIFF', //6 + 'CF_OEMTEXT', //7 + 'CF_DIB', //8 + 'CF_PALETTE', //9 + 'CF_PENDATA', //10 + 'CF_RIFF', //11 + 'CF_WAVE', //12 + 'CF_UNICODETEXT', //13 + 'CF_ENHMETAFILE', //14 + 'CF_HDROP', //15 + 'CF_LOCALE' //16 + ); + +var + cannotole: boolean; + sysdndhandler: tsysdndhandler; + +function winactiontoaction(const aaction: dword): dndactionsty; +begin + result:= []; + if aaction and dropeffect_copy <> 0 then begin + include(result,dnda_copy); + end; + if aaction and dropeffect_move <> 0 then begin + include(result,dnda_move); + end; + if aaction and dropeffect_link <> 0 then begin + include(result,dnda_link); + end; +end; + +function actiontowinaction(const aaction: dndactionsty): dword; +begin + result:= 0; + if dnda_copy in aaction then begin + result:= result or dropeffect_copy; + end; + if dnda_move in aaction then begin + result:= result or dropeffect_move; + end; + if dnda_link in aaction then begin + result:= result or dropeffect_link; + end; +end; + +function wintoshiftstate(const aflags: longword): shiftstatesty; +const + mk_alt = $20; //who knows... +begin + result:= []; + if aflags and mk_control <> 0 then begin + include(result,ss_ctrl); + end; + if aflags and mk_shift <> 0 then begin + include(result,ss_shift); + end; + if aflags and mk_alt <> 0 then begin + include(result,ss_alt); + end; + if aflags and mk_lbutton <> 0 then begin + include(result,ss_left); + end; + if aflags and mk_mbutton <> 0 then begin + include(result,ss_middle); + end; + if aflags and mk_rbutton <> 0 then begin + include(result,ss_right); + end; +end; + +function sysdnd(const action: sysdndactionty; + const aintf: isysdnd; const arect: rectty; + out aresult: boolean): guierrorty; +var + act1: dndactionsty; +begin + aresult:= false; + if (sysdndhandler = nil) then begin + result:= gue_nodragpending; + end + else begin + result:= gue_ok; + if aintf <> nil then begin + act1:= aintf.getactions; + end; + with sysdndhandler do begin + case action of + sdnda_reject: begin + postevent(tsdndevent.create(sdndk_reject),false); + end; + sdnda_accept: begin + postevent(tsdndevent.create(sdndk_accept,0,act1),false); + end; + sdnda_finished: begin + postevent(tsdndevent.create(sdndk_finished),true); + end; + sdnda_begin: begin + postevent(tsdndevent.create(sdndk_writebegin,0,act1,aintf),true); + semwait; + end; + sdnda_check: begin + writecheck(act1,aresult); + end; + sdnda_drop,sdnda_destroyed: begin + if action = sdnda_drop then begin + fdata.fdrop:= true; //dndthread in blocking dodragdrop + end + else begin + fdata.fcancel:= true; //dndthread in blocking dodragdrop + end; + postevent(tsdndevent.create(sdndk_writeend,0,act1,aintf), + action = sdnda_destroyed); + end; + else begin + result:= gue_notimplemented; + end; + end; + end; + end; +end; + +function sysdndreaddata(var adata: string; + const typeindex: integer): guierrorty; +begin + if (sysdndhandler = nil) then begin + result:= gue_nodragpending; + end + else begin + result:= gue_ok; + with sysdndhandler do begin + postevent(tsdndevent.create(sdndk_readdataortext,0,[],nil,nil, + typeindex,@adata,nil),false); + semwait; + end; + end; +end; + +function sysdndreadtext(var atext: msestring; + const typeindex: integer): guierrorty; +begin + if (sysdndhandler = nil) then begin + result:= gue_nodragpending; + end + else begin + result:= gue_ok; + with sysdndhandler do begin + postevent(tsdndevent.create(sdndk_readdataortext,0,[],nil,nil, + typeindex,nil,@atext),false); + semwait; + end; + end; +end; + +procedure regsysdndwindow(const awindow: winidty); +begin + if (sysdndhandler = nil) and not cannotole then begin + sysdndhandler:= tsysdndhandler.create; + sysdndhandler.semwait; + if cannotole then begin + freeandnil(sysdndhandler); + exit; + end; + end; + sysdndhandler.regsysdndwindow(awindow); +end; + +procedure windnddeinit; +begin + freeandnil(sysdndhandler); +end; + + +{ tenumformatetc } + +constructor tenumformatetc.create(const adataobj: tdataobject); +begin + fdataobj:= adataobj; +end; + +function tenumformatetc.next(celt: ulong; out rgelt: formatetc; + pceltfetched: pulong = nil): hresult; stdcall; +var + int1: integer; + po1: pformatetc; +begin + int1:= celt; + if int1 + findex > high(fdataobj.fcformats) then begin + int1:= length(fdataobj.fcformats) - findex; + end; + if int1 < 0 then begin + int1:= 0; + end; + po1:= @rgelt; + if int1 < celt then begin + result:= s_false; + end + else begin + result:= s_ok; + end; + for int1:= 0 to int1-1 do begin + fillchar(po1^,sizeof(po1^),0); + with po1^ do begin + cfformat:= fdataobj.fcformats[findex]; + tymed:= tymed_hglobal; + end; + inc(findex); + inc(po1); + end; +end; + +function tenumformatetc.skip(celt: ulong): hresult; stdcall; +begin + result:= s_ok; + findex:= findex + celt; + if findex > high(fdataobj.fcformats) then begin + findex:= length(fdataobj.fcformats); + result:= s_false; + end; +end; + +function tenumformatetc.reset: hresult; stdcall; +begin + findex:= 0; + result:= s_ok; +end; + +function tenumformatetc.clone(out penum: ienumformatetc): hresult; stdcall; +var + inst: tenumformatetc; +begin + inst:= tenumformatetc.create(fdataobj); + inst.findex:= findex; + penum:= ienumformatetc(inst); + result:= s_ok; +end; + +{ tsdndevent } + +constructor tsdndevent.create(const akind: sdndeventkindty; + const awinid: winidty = 0; + const aactions: dndactionsty = []; + const aintf: isysdnd = nil; + const arect: prectty = nil; + const aindex: integer = -1; + const adatapo: pstring = nil; + const atextpo: pmsestring = nil); + +begin + fsdndkind:= akind; + fwinid:= awinid; + factions:= aactions; + fintf:= aintf; + if arect = nil then begin + frect:= nullrect; + end + else begin + frect:= arect^; + end; + findex:= aindex; + fdatapo:= adatapo; + ftextpo:= atextpo; + inherited create(ek_mse); +end; + +{ tdataobject } + +function tdataobject.checkformat(const aformat: formatetc): hresult; +var + int1: integer; +begin + result:= dv_e_formatetc; + findex:= -1; + for int1:= 0 to high(fcformats) do begin + if fcformats[int1] = aformat.cfformat then begin + findex:= int1; + result:= s_ok; + break; + end; + end; +end; + +function tdataobject.getdatasize(out apo: pointer): integer; +begin + application.lock; + if fformatistext[findex] then begin + if ftext[findex] = '' then begin + if fintf <> nil then begin + ftext[findex]:= fintf.convertmimetext(findex); + end; + end; + result:= length(ftext[findex]) * sizeof(msechar); + apo:= pointer(ftext[findex]); + end + else begin + if fdata[findex] = '' then begin + if fintf <> nil then begin + fdata[findex]:= fintf.convertmimedata(findex); + end; + end; + result:= length(fdata[findex]); + apo:= pointer(fdata[findex]); + end; + application.unlock; +end; + +function tdataobject.dogetdata(var medium: stgmedium): hresult; +var + po1,po2: pointer; + int1: integer; +begin + if medium.tymed <> tymed_hglobal then begin + result:= dv_e_tymed; + end + else begin + po1:= globallock(medium.hglobal); + if po1 = nil then begin + result:= e_unexpected; + end + else begin + int1:= getdatasize(po2); + if globalsize(medium.hglobal) < int1 then begin + result:= stg_e_mediumfull; + end + else begin + move(po2^,po1^,int1); + medium.punkforrelease:= nil; + result:= s_ok; + end; + globalunlock(medium.hglobal); + end; + end; +end; + +function tdataobject.getdata(const formatetcin: formatetc; + out medium: stgmedium): hresult; stdcall; +var + po1: pointer; +begin + result:= checkformat(formatetcin); + if result = s_ok then begin + medium.tymed:= tymed_hglobal; + medium.hglobal:= globalalloc(gmem_moveable,getdatasize(po1)); + if medium.hglobal = 0 then begin + result:= e_outofmemory; + end + else begin + result:= dogetdata(medium); + end; + end; +end; + +function tdataobject.getdatahere(const pformatetc: formatetc; + var medium: stgmedium): hresult; stdcall; +begin + result:= checkformat(pformatetc); + if result = s_ok then begin + result:= dogetdata(medium); + end; +end; + +function tdataobject.querygetdata( + const pformatetc: formatetc): hresult; stdcall; +begin + result:= checkformat(pformatetc); +end; + +function tdataobject.getcanonicalformatetc(const pformatetcin: formatetc; + out pformatetcout: formatetc): hresult; stdcall; +begin + pformatetcout:= pformatetcin; + pformatetcout.ptd:= nil; + result:= data_s_sameformatetc; +end; + +function tdataobject.setdata(const pformatetc: formatetc; + const medium: stgmedium; frelease: bool): hresult; stdcall; +begin + result:= e_notimpl; +end; + +function tdataobject.enumformatetc(dwdirection: dword; + out enumformatetcpara: ienumformatetc): hresult; stdcall; +begin + if dwdirection = datadir_set then begin + result:= e_notimpl; + end + else begin + result:= s_ok; + enumformatetcpara:= tenumformatetc.create(self); + end; +end; + +function tdataobject.dadvise(const formatetc: formatetc; advf: dword; + const advsink: iadvisesink; + out dwconnection: dword): hresult; stdcall; +begin + result:= e_notimpl; +end; + +function tdataobject.dunadvise(dwconnection: dword): hresult; stdcall; +begin + result:= ole_e_advisenotsupported; +end; + +function tdataobject.enumdadvise( + out enumadvise: ienumstatdata): hresult; stdcall; +begin + enumadvise:= nil; + result:= ole_e_advisenotsupported; +end; + +function getclipformatid(const aname: msestring): integer; +var + int1: integer; +begin + result:= 0; + for int1:= low(predefclipboardnames) to high(predefclipboardnames) do begin + if predefclipboardnames[int1] = aname then begin + result:= int1; + break; + end; + end; + if result = 0 then begin + result:= registerclipboardformatw(pwidechar(pmsechar(aname))); + end; +end; + +procedure tdataobject.begindrag(const aevent: tsdndevent); +var + int1: integer; +begin + getobjectlinker.setlinkedvar(iobjectlink(self),aevent.fintf, + iobjectlink(fintf)); + ftext:= nil; + fdata:= nil; + fcheckpending:= 0; + fdrop:= false; + fcancel:= false; + ffinished:= false; + factions:= fintf.getactions; + fformats:= fintf.getformats; + fformatistext:= fintf.getformatistext; + setlength(fformatistext,length(fformats)); + setlength(ftext,length(fformats)); + setlength(fdata,length(fformats)); + fcformats:= nil; + setlength(fcformats,length(fformats)); + for int1:= 0 to high(fformats) do begin + fcformats[int1]:= getclipformatid(fformats[int1]); + end; +end; + +function tdataobject.querycontinuedrag(fescapepressed: bool; + grfkeystate: dword): hresult; stdcall; +begin + application.lock; + result:= s_ok; + if (fintf = nil) or fcancel then begin + result:= dragdrop_s_cancel; + ffinished:= true; + end + else begin + if fdrop then begin + result:= dragdrop_s_drop; + ffinished:= true; + end; + end; + application.unlock; +end; + +function tdataobject.givefeedback(dweffect: dword): hresult; stdcall; +begin + if interlockeddecrement(fcheckpending) >= 0 then begin + application.lock; + if fintf <> nil then begin + ftargetactions:= winactiontoaction(dweffect); + application.postevent(tsysdndstatusevent.create( + fintf.geteventintf,ftargetactions <> [])); + end; + application.unlock; + end + else begin + interlockedincrement(fcheckpending); + end; + result:= s_ok; +end; + +{ tsysdndhandler } + +constructor tsysdndhandler.create; +begin + fdata:= tdataobject.create; + inherited create; +end; + +destructor tsysdndhandler.destroy; +begin + fdata.free; + inherited; +end; + +procedure tsysdndhandler.clearformats; +var + int1: integer; +begin + for int1:= 0 to high(foleformats) do begin + if foleformats[int1].ptd <> nil then begin + cotaskmemfree(foleformats[int1].ptd); + end; + end; + foleformats:= nil; + fformats:= nil; +end; + +procedure tsysdndhandler.postevent(event: tsdndevent; const aquit: boolean); +begin + inherited postevent(event); + if aquit then begin + postthreadmessage(id,wm_quit,0,0); //wakeup thread, cancel dodragdrop + end + else begin + postthreadmessage(id,wm_user,0,0); //wakeup thread + end; +end; + +procedure tsysdndhandler.terminate; +begin + inherited; + postthreadmessage(id,wm_quit,0,0); //wakeup thread +// postthreadmessage(id,wm_user,0,0); //wakeup thread +end; + +function tsysdndhandler.execute(thread: tmsethread): integer; +var + hres1: hresult; + ev1: tsdndevent; + int1: integer; + msg: tmessage; + medium: tstgmedium; + po1: pointer; + lwo1: longword; +begin + hres1:= oleinitialize(nil); + cannotole:= not((hres1 = s_ok) or (hres1 = s_false)); + sempost; + if not cannotole then begin + repeat + try + int1:= integer(getmessage({$ifdef FPC}@{$endif}msg,0,0,0)); + if int1 <> -1 then begin + translatemessage({$ifdef FPC}@{$endif}msg); + dispatchmessage({$ifdef FPC}@{$endif}msg); + end; + repeat + ev1:= tsdndevent(waitevent(0)); + if ev1 <> nil then begin + case ev1.sdndkind of + sdndk_regwindow: begin + registerdragdrop(ev1.fwinid,idroptarget(self)); + end; + sdndk_unregwindow: begin + revokedragdrop(ev1.fwinid); + end; + sdndk_finished: begin + fdataobject:= nil; + clearformats; + end; + sdndk_readdataortext: begin + if (ev1.findex >= 0) and (ev1.findex <= high(foleformats)) and + (fdataobject <> nil) then begin + fillchar(medium,sizeof(medium),0); + with medium do begin + tymed:= tymed_hglobal; + if fdataobject.getdata(foleformats[ev1.findex], + medium) = s_ok then begin + int1:= globalsize(hglobal); + po1:= globallock(hglobal); + if ev1.ftextpo <> nil then begin + setlength(ev1.ftextpo^,(int1+1) div 2); + move(po1^,ev1.ftextpo^[1],int1); + end + else begin + setlength(ev1.fdatapo^,int1); + move(po1^,ev1.fdatapo^[1],int1); + end; + globalunlock(hglobal); + releasestgmedium(medium); + end; + end; + end; + sempost; + end; + sdndk_writebegin: begin + clearformats; +// fcheckpending:= 0; + fwritestate:= [ws_active]; + fdata.begindrag(ev1); + sempost; +// dodragdrop(idataobject(fdata),idropsource(self), +// actiontowinaction(ev1.factions),@lwo1); + end; + sdndk_writecheck: begin + if ws_active in fwritestate then begin + if fdata.fintf = nil then begin + sempost; + end + else begin + include(fwritestate,ws_checking); + sempost; + beginsdndwrite(id); + hres1:= dodragdrop(idataobject(fdata),idropsource(fdata), + actiontowinaction(fdata.factions),@lwo1); //blocking + exclude(fwritestate,ws_checking); + endsdndwrite; +// application.lock; +// try +// if (fdata.fintf <> nil) and fdata.ffinished then begin +// fdata.fintf.cancelsysdnd; +// end; +// finally +// application.unlock; +// end; + end; + end; + end; + end; + ev1.free; + end; + until (ev1 = nil) or terminated; + except + application.handleexception; + end; + until terminated; + clearformats; + oleuninitialize; + end; + result:= 0; +end; + +procedure tsysdndhandler.regsysdndwindow(const awindow: winidty); +begin + postevent(tsdndevent.create(sdndk_regwindow,awindow),false); +end; + +function tsysdndhandler._addref: integer; stdcall; +begin + result:= -1; +end; + +function tsysdndhandler._release: integer; stdcall; +begin + result:= -1; +end; + +function tsysdndhandler.queryinterface( + {$ifdef fpc_has_constref}constref{$else}const{$endif} iid: tguid; + out obj): hresult; stdcall; +begin + if getinterface(iid, obj) then begin + result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; + +function tsysdndhandler.dragenter(const dataobj: idataobject; + grfkeystate: dword; pt: tpoint; var dweffect: dword): hresult; stdcall; +const + chunkcount = 16; +var + ev1: tsdndevent; + effect1: dword; + enumformat: ienumformatetc; + count1: integer; + lwo1: longword; + int1,int2: integer; + buffer: array[0..max_path] of msechar; +begin + fdragwinid:= getwinid(pointty(pt)); + effect1:= dropeffect_none; + clearevents; + if fdragwinid <> 0 then begin + fdataobject:= dataobj; + clearformats; + if fdataobject.enumformatetc(datadir_get,enumformat) = s_ok then begin + setlength(foleformats,chunkcount); + count1:= 0; + lwo1:= 0; + while enumformat.next(chunkcount,foleformats[count1],@lwo1) = s_ok do begin + setlength(foleformats,length(foleformats)+chunkcount); + count1:= count1 + lwo1; + end; + count1:= count1 + lwo1; + setlength(foleformats,count1); + setlength(fformats,length(foleformats)); + for int1:= 0 to high(fformats) do begin + with foleformats[int1] do begin + int2:= getclipboardformatnamew(cfformat,@buffer,max_path); + if int2 > 0 then begin + fformats[int1]:= buffer; + end + else begin + if (cfformat >= low(predefclipboardnames)) and + (cfformat <= high(predefclipboardnames)) then begin + fformats[int1]:= predefclipboardnames[cfformat]; + end; + end; + end; + end; + application.postevent(tsysdndevent.create(dek_check,fdragwinid,pointty(pt), + wintoshiftstate(grfkeystate),false,fformats,fformatistext, + winactiontoaction(dweffect))); + ev1:= waitevent(timeout); + if (ev1 <> nil) and (ev1.sdndkind = sdndk_accept) then begin + effect1:= actiontowinaction(ev1.factions) + end; + ev1.free; + end; + end; + dweffect:= effect1; + result:= s_ok; +end; + +function tsysdndhandler.dragover(grfkeystate: dword; pt: tpoint; + var dweffect: dword): hresult; stdcall; +var + ev1: tsdndevent; + effect1: dword; +begin + effect1:= dropeffect_none; + if fdragwinid <> 0 then begin + application.postevent(tsysdndevent.create(dek_check,fdragwinid,pointty(pt), + wintoshiftstate(grfkeystate),false,fformats,fformatistext, + winactiontoaction(dweffect))); + ev1:= waitevent(timeout); + if (ev1 <> nil) and (ev1.sdndkind = sdndk_accept) then begin + effect1:= actiontowinaction(ev1.factions) + end; + ev1.free; + end; + dweffect:= effect1; + result:= s_ok; +end; + +function tsysdndhandler.dragleave: hresult; stdcall; +begin + if fdragwinid <> 0 then begin + application.postevent(tsysdndevent.create(dek_leavesysdnd,fdragwinid, + nullpoint,[],false,nil,nil,[])); + fdataobject:= nil; + fdragwinid:= 0; + clearformats; + end; + result:= s_ok; +end; + +function tsysdndhandler.drop(const dataobj: idataobject; grfkeystate: dword; + pt: tpoint; var dweffect: dword): hresult; stdcall; +begin + if fdragwinid <> 0 then begin + application.postevent(tsysdndevent.create(dek_drop,fdragwinid,pointty(pt), + wintoshiftstate(grfkeystate),false,fformats,fformatistext, + winactiontoaction(dweffect))); + end; + result:= s_ok; +end; + +function tsysdndhandler.getwinid(const apos: pointty): winidty; +var + window1: twindow; +begin + result:= 0; + application.lock; + window1:= application.windowatpos(apos); + if (window1 <> nil) and window1.haswinid then begin //do not create winid + result:= window1.winid; + end; + application.unlock; +end; + +function tsysdndhandler.waitevent(const timeoutus: integer = -1): tsdndevent; +begin + result:= tsdndevent(inherited waitevent(timeoutus)); +end; + +procedure tsysdndhandler.writecheck(const aactions: dndactionsty; + var aresult: boolean); +begin + if not (ws_checking in fwritestate) then begin + postevent(tsdndevent.create(sdndk_writecheck,0,aactions),false); + semwait; + end; + aresult:= fdata.ftargetactions * aactions <> []; + interlockedincrement(fdata.fcheckpending); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msewinglob.pas b/mseide-msegui/lib/common/kernel/windows/msewinglob.pas new file mode 100644 index 0000000..264514f --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msewinglob.pas @@ -0,0 +1,24 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msewinglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + windows{$ifndef FPC},messages{$endif}; + +const + msemessage = wm_user + $3694; + wakeupmessage = msemessage + 1; + destroymessage = msemessage + 2; + traycallbackmessage = msemessage + 3; + timermessage = msemessage + 4; + +implementation +end. diff --git a/mseide-msegui/lib/common/math/msefft.pas b/mseide-msegui/lib/common/math/msefft.pas new file mode 100644 index 0000000..2de9c78 --- /dev/null +++ b/mseide-msegui/lib/common/math/msefft.pas @@ -0,0 +1,287 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msefft; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseclasses,msetypes,msefftw; + +type + + fftstatety = (ffs_inited,ffs_windowvalid); + fftstatesty = set of fftstatety; + + windowfuncty = (wf_rectangular,wf_hann,wf_hamming); + + tfft = class(tmsecomponent) + private + fplan: fftw_plan; + finpreal: pdouble; + finpcomplex: pcomplexty; + foutreal: pdouble; + foutcomplex: pcomplexty; + finprealar: realarty; + finpcomplexar: complexarty; + fn: integer; + fnout: integer; + fwindowdata: doublearty; + fwindowfunc: windowfuncty; + fwindowfuncpar0: double; + fwindowfuncpar1: double; + procedure setinpreal(const avalue: realarty); + procedure setinpcomplex(const avalue: complexarty); + function getoutreal: realarty; + function getoutcomplex: complexarty; + procedure setwindowfunc(const avalue: windowfuncty); + procedure setwindowfuncpar0(const avalue: double); + procedure setwindowfuncpar1(const avalue: double); + protected + fstate: fftstatesty; + procedure checkwindowfunc; + procedure checkinit; + procedure resetwindowdata; + public + destructor destroy; override; + procedure clear; + property inpreal: realarty write setinpreal; + property inpcomplex: complexarty write setinpcomplex; + property outreal: realarty read getoutreal; + property outcomplex: complexarty read getoutcomplex; + published + property windowfunc: windowfuncty read fwindowfunc + write setwindowfunc default wf_rectangular; + property windowfuncpar0: double read fwindowfuncpar0 + write setwindowfuncpar0; + property windowfuncpar1: double read fwindowfuncpar1 + write setwindowfuncpar1; + end; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tfft } + +destructor tfft.destroy; +begin + clear; + if ffs_inited in fstate then begin + releasefftw; + end; + inherited; +end; + +procedure tfft.clear; +begin + if ffs_inited in fstate then begin + if fplan <> nil then begin + fftw_destroy_plan(fplan); + fplan:= nil; + end; + fftw_freemem(pointer(finpreal)); + fftw_freemem(pointer(finpcomplex)); + fftw_freemem(pointer(foutreal)); + fftw_freemem(pointer(foutcomplex)); + fn:= 0; + resetwindowdata; + end; +end; + +procedure tfft.checkwindowfunc; +var + nminus1: double; + int1: integer; +begin + if not (ffs_windowvalid in fstate) then begin + nminus1:= fn-1; + setlength(fwindowdata,fn); + case fwindowfunc of + wf_hann: begin + for int1:= 0 to high(fwindowdata) do begin + fwindowdata[int1]:= 0.5 * (1-cos((2*pi*int1)/nminus1)); + end; + end; + wf_hamming: begin + for int1:= 0 to high(fwindowdata) do begin + fwindowdata[int1]:= 0.54 - 0.46 * cos((2*pi*int1)/nminus1); + end; + end; + else begin + for int1:= 0 to high(fwindowdata) do begin + fwindowdata[int1]:= 1; + end; + end; + end; + include(fstate,ffs_windowvalid); + end; +end; + +function tfft.getoutreal: realarty; +var + po1: pcomplexty; + int1: integer; + do1: double; + po2: pdouble; +begin + checkinit; + if (finpcomplexar <> nil) then begin + if (foutcomplex <> nil) then begin + clear; + end; + if fn <> (length(finpcomplexar)-1)*2 then begin + clear; + end; //frequ -> time + if fplan = nil then begin + fn:= (length(finpcomplexar)-1)*2; + fftw_getmem(pointer(finpcomplex),(fn div 2 + 1) * sizeof(complexty)); + fftw_getmem(pointer(foutreal),fn * sizeof(double)); + fplan:= fftw_plan_dft_c2r_1d(fn,finpcomplex,foutreal,[fftw_estimate]); + end; + move(pointer(finpcomplexar)^,finpcomplex^,(fn div 2 + 1)*sizeof(complexty)); + fftw_execute(fplan); + setlength(result,fn); + move(foutreal^,pointer(result)^,fn*sizeof(double)); + end + else begin //time -> frequ + if (foutreal <> nil) then begin + clear; + end; + if fn <> length(finprealar) then begin + clear; + end; + result:= nil; + if finprealar <> nil then begin + if fplan = nil then begin + fn:= length(finprealar); + fftw_getmem(pointer(finpreal),fn * sizeof(double)); + fftw_getmem(pointer(foutcomplex),(fn div 2 + 1) * sizeof(complexty)); + fplan:= fftw_plan_dft_r2c_1d(fn,finpreal,foutcomplex,[fftw_estimate]); + end; + move(pointer(finprealar)^,finpreal^,fn*sizeof(double)); + if fwindowfunc <> wf_rectangular then begin + checkwindowfunc; + po2:= finpreal; + for int1:= 0 to high(fwindowdata) do begin + po2^:= po2^ * fwindowdata[int1]; + inc(po2); + end; + end; + fftw_execute(fplan); + setlength(result,fn div 2 + 1); + po1:= foutcomplex; + do1:= fn/2; + for int1:= 0 to high(result) do begin + result[int1]:= sqrt(po1^.re*po1^.re+po1^.im*po1^.im)/do1; + inc(po1); + end; + result[0]:= result[0]/2; //dc + end; + end; + fnout:= length(result); +end; + +function tfft.getoutcomplex: complexarty; +begin + checkinit; + if (foutreal <> nil) then begin + clear; + end; + if (finpcomplexar <> nil) then begin + if fn <> length(finpcomplexar) then begin + clear; + end; + end + else begin + if fn <> length(finprealar) then begin + clear; + end; + end; + result:= nil; //todo +end; + +procedure tfft.setinpreal(const avalue: realarty); +begin + if finpcomplexar <> nil then begin + clear; + finpcomplexar:= nil; + end; + finprealar:= avalue; +end; + +procedure tfft.setinpcomplex(const avalue: complexarty); +begin + if finprealar <> nil then begin + clear; + finprealar:= nil; + end; + finpcomplexar:= avalue; +end; + +procedure tfft.checkinit; +begin + if not (ffs_inited in fstate) then begin + initializefftw([]); + include(fstate,ffs_inited); + end; +end; + +procedure tfft.setwindowfunc(const avalue: windowfuncty); +begin + if avalue <> fwindowfunc then begin + fwindowfunc:= avalue; + resetwindowdata; + end; +end; + +procedure tfft.setwindowfuncpar0(const avalue: double); +begin + if avalue <> fwindowfuncpar0 then begin + fwindowfuncpar0:= avalue; + resetwindowdata; + end; +end; + +procedure tfft.setwindowfuncpar1(const avalue: double); +begin + if avalue <> fwindowfuncpar1 then begin + fwindowfuncpar1:= avalue; + resetwindowdata; + end; +end; + +procedure tfft.resetwindowdata; +begin + fwindowdata:= nil; + exclude(fstate,ffs_windowvalid); +end; + +end. diff --git a/mseide-msegui/lib/common/math/msefftw.pas b/mseide-msegui/lib/common/math/msefftw.pas new file mode 100644 index 0000000..d1c5dd1 --- /dev/null +++ b/mseide-msegui/lib/common/math/msefftw.pas @@ -0,0 +1,233 @@ +unit msefftw; +{ + FFTW - Fastest Fourier Transform in the West library + + This interface unit is (C) 2005 by Daniel Mantione + member of the Free Pascal development team. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This file carries, as a independend work calling a well + documented binary interface, the Free Pascal LGPL license + with static linking exception. + + Note that the FFTW library itself carries the GPL license + and can therefore not be used in non-GPL software. + + Modified 2010 by Martin Schreiber +} + +interface +{$ifdef FPC} +{$mode objfpc}{$h+}{$interfaces corba} +{$MACRO on} +{$INLINE on} +{$endif} +uses + msetypes,msestrings; + +const +{$ifdef mswindows} + fftwlib: array[0..1] of filenamety = ('fftw3.dll','libfftw3-3.dll'); +{$else} + fftwlib: array[0..1] of filenamety = ('libfftw3.so.3','libfftw3.so'); +{$endif} + +{$IFDEF Unix} +//const +// fftwlib = 'fftw3f'; +{$ELSE} +//const +// fftwlib = 'libfftw3f'; +{$ENDIF} + +type // complex_single=record + // re,im:single; + // end; + // Pcomplex_single=^complex_single; + + fftw_plan = type pointer; + + fftw_sign = (fftw_forward = -1, fftw_backward = 1); + + fftw_flag = (fftw_measure, {generated optimized algorithm} + fftw_destroy_input, {default} + fftw_unaligned, {data is unaligned} + fftw_conserve_memory, {needs no explanation} + fftw_exhaustive, {search optimal algorithm} + fftw_preserve_input, {don't overwrite input} + fftw_patient, {generate highly optimized alg.} + fftw_estimate); {don't optimize, just use an alg.} + fftw_flagset = set of fftw_flag; + +var +{Complex to complex transformations.} +fftw_plan_dft_1d: function(n: cardinal; i,o: Pcomplexty; + sign: fftw_sign; flags: fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_2d: function(nx,ny: cardinal; i,o: Pcomplexty; + sign: fftw_sign; flags: fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_3d: function(nx,ny,nz: cardinal; i,o: Pcomplexty; + sign: fftw_sign; flags: fftw_flagset): fftw_plan; cdecl; + +fftw_plan_dft: function(rank: cardinal; n: Pcardinal; i,o: Pcomplexty; + sign: fftw_sign; flags: fftw_flagset): fftw_plan; cdecl; + +{Real to complex transformations.} +fftw_plan_dft_r2c_1d: function(n: cardinal; i:Pdouble; o: Pcomplexty; + flags:fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_r2c_2d: function(nx,ny: cardinal; i: Pdouble; o:Pcomplexty; + flags:fftw_flagset):fftw_plan; cdecl; +fftw_plan_dft_r2c_3d: function(nx,ny,nz: cardinal; i: Psingle; o: Pcomplexty; + flags: fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_r2c: function(rank:cardinal;n:Pcardinal;i:Psingle;o:Pcomplexty; + flags:fftw_flagset):fftw_plan; cdecl; + +{Complex to real transformations.} +fftw_plan_dft_c2r_1d: function(n: cardinal; i: Pcomplexty; o: Pdouble; + flags:fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_c2r_2d: function(nx,ny:cardinal; i: Pcomplexty; o:Pdouble; + flags: fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_c2r_3d: function(nx,ny,nz: cardinal; i: Pcomplexty; o: Pdouble; + flags: fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_c2r: function(rank: cardinal; n:Pcardinal; i:Pcomplexty; o: Pdouble; + flags: fftw_flagset):fftw_plan; cdecl; + + +fftw_destroy_plan: procedure(plan: fftw_plan); cdecl; +fftw_execute: procedure(plan: fftw_plan); cdecl; + +//{$calling register} {Back to normal!} +procedure fftw_getmem(var p: pointer; size: sizeint); +procedure fftw_freemem(var p: pointer);{$ifdef FPC}inline;{$endif} + +procedure initializefftw(const sonames: array of filenamety); + //[] = default +procedure releasefftw; + +implementation +uses + msedynload,msesys,sysutils; + +var + libinfo: dynlibinfoty; + +//{$ifndef Windows} +//{$LINKLIB fftw3f} +//{$endif} + +{Required libraries by libfftw3} +{ $LINKLIB gcc} +{ $LINKLIB c} +{ $LINKLIB m} + +{Better don't use fftw_malloc and fftw_free, but provide Pascal replacements.} + +{$IF defined(cpui386) or defined(cpupowerpc)} + {$DEFINE align:=16} +//{$ENDIF} +{$IFEND} + +procedure fftw_getmem(var p:pointer; size: sizeint); + +{$IFDEF align} +var + originalptr:pointer; +begin + { We allocate additional "align-1" bytes to be able to align. + And we allocate additional "SizeOf(Pointer)" to always have space to store + the value of the original pointer. } + getmem(originalptr,size + align-1 + SizeOf(Pointer)); + ptruint(p):=(ptruint(originalptr) + SizeOf(Pointer)); + ptruint(p):=(ptruint(p)+align-1) and not (align-1); + PPointer(ptruint(ptruint(p) - SizeOf(Pointer)))^:= originalptr; +{$ELSE} +begin + getmem(p,size); +{$ENDIF} +end; + +procedure fftw_freemem(var p: pointer); {$ifdef FPC}inline;{$endif} + +begin + if p <> nil then begin +{$IFDEF align} + freemem(PPointer(ptruint(ptruint(p) - SizeOf(Pointer)))^); +{$ELSE} + freemem(p); +{$ENDIF} + p:= nil; + end; +end; + +{$ifndef FPC} +var + funcs: array[0..13] of funcinfoty = ( + (n: 'fftw_plan_dft_1d'; d: nil), + (n: 'fftw_plan_dft_2d'; d: nil), + (n: 'fftw_plan_dft_3d'; d: nil), + (n: 'fftw_plan_dft'; d: nil), + (n: 'fftw_plan_dft_r2c_1d'; d: nil), + (n: 'fftw_plan_dft_r2c_2d'; d: nil), + (n: 'fftw_plan_dft_r2c_3d'; d: nil), + (n: 'fftw_plan_dft_r2c'; d: nil), + (n: 'fftw_plan_dft_c2r_1d'; d: nil), + (n: 'fftw_plan_dft_c2r_2d'; d: nil), + (n: 'fftw_plan_dft_c2r_3d'; d: nil), + (n: 'fftw_plan_dft_c2r'; d: nil), + (n: 'fftw_destroy_plan'; d: nil), + (n: 'fftw_execute'; d: nil)); +{$endif} +procedure initializefftw(const sonames: array of filenamety); + //[] = default +{$ifdef FPC} +const + funcs: array[0..13] of funcinfoty = ( + (n: 'fftw_plan_dft_1d'; d: @fftw_plan_dft_1d), + (n: 'fftw_plan_dft_2d'; d: @fftw_plan_dft_2d), + (n: 'fftw_plan_dft_3d'; d: @fftw_plan_dft_3d), + (n: 'fftw_plan_dft'; d: @fftw_plan_dft), + (n: 'fftw_plan_dft_r2c_1d'; d: @fftw_plan_dft_r2c_1d), + (n: 'fftw_plan_dft_r2c_2d'; d: @fftw_plan_dft_r2c_2d), + (n: 'fftw_plan_dft_r2c_3d'; d: @fftw_plan_dft_r2c_3d), + (n: 'fftw_plan_dft_r2c'; d: @fftw_plan_dft_r2c), + (n: 'fftw_plan_dft_c2r_1d'; d: @fftw_plan_dft_c2r_1d), + (n: 'fftw_plan_dft_c2r_2d'; d: @fftw_plan_dft_c2r_2d), + (n: 'fftw_plan_dft_c2r_3d'; d: @fftw_plan_dft_c2r_3d), + (n: 'fftw_plan_dft_c2r'; d: @fftw_plan_dft_c2r), + (n: 'fftw_destroy_plan'; d: @fftw_destroy_plan), + (n: 'fftw_execute'; d: @fftw_execute)); +{$endif} +const + errormessage = 'Can not load FFTW library. '; +begin +{$ifndef FPC} + funcs[0].d:= @fftw_plan_dft_1d; + funcs[1].d:= @fftw_plan_dft_2d; + funcs[2].d:= @fftw_plan_dft_3d; + funcs[3].d:= @fftw_plan_dft; + funcs[4].d:= @fftw_plan_dft_r2c_1d; + funcs[5].d:= @fftw_plan_dft_r2c_2d; + funcs[6].d:= @fftw_plan_dft_r2c_3d; + funcs[7].d:= @fftw_plan_dft_r2c; + funcs[8].d:= @fftw_plan_dft_c2r_1d; + funcs[9].d:= @fftw_plan_dft_c2r_2d; + funcs[1].d:= @fftw_plan_dft_c2r_3d; + funcs[11].d:= @fftw_plan_dft_c2r; + funcs[12].d:= @fftw_destroy_plan; + funcs[13].d:= @fftw_execute; +{$endif} + + initializedynlib(libinfo,sonames,fftwlib,funcs,[],errormessage); +end; + +procedure releasefftw; +begin + releasedynlib(libinfo); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/math/msefilter.pas b/mseide-msegui/lib/common/math/msefilter.pas new file mode 100644 index 0000000..3ba962e --- /dev/null +++ b/mseide-msegui/lib/common/math/msefilter.pas @@ -0,0 +1,1253 @@ +{ MSEgui Copyright (c) 2010-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +// +// experimental +// + +unit msefilter; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseclasses,msedatalist,classes,mclasses,msetypes,msesignal,msearrayprops, + msereal; +type + + tdoublefiltercomp = class; + + tsections = class(tintegerarrayprop) + protected + fowner: tdoublefiltercomp; + function calccoeffcount: integer; + procedure dochange(const aindex: integer); override; +// procedure updatecoeffcount; + public + constructor create(const aowner: tdoublefiltercomp); + end; + + tdoublefiltercomp = class(tdoublezcomp) + private + fsections: tsections; + procedure setcoeff(const avalue: tdatalist); + procedure setsections(const avalue: tsections); + protected + fcoeff: tdatalist; + fcoeffchecking: boolean; + procedure coeffchanged(const sender: tdatalist; + const aindex: integer); override; + procedure createcoeff; virtual; abstract; + procedure zcountchanged; override; + procedure checkcoeffs; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property sections: tsections read fsections write setsections; + //array of coeffcount + end; + +// >---+-->(z)---+-->(z)---+-->(z)---+ +// b0 b1 b2 bN-1 +// +---------+---------+---------+---> +// + tsigfir = class(tdoublefiltercomp) + private + function getcoeff: trealcoeff; + procedure setcoeff(const avalue: trealcoeff); + protected + procedure createcoeff; override; +// procedure processinout(const acount: integer; +// var ainp,aoutp: pdouble); override; +// function getzcount: integer; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + published + property coeff: trealcoeff read getcoeff write setcoeff; + end; +// +---------+---------+---------+---> +// | -a1 -a2 -aN-1 +// +---(z)<--+---(z)<--+---(z)<--+ +// b0 b1 b2 bN-1 +// >---+---------+---------+---------+ +// + tsigiir = class(tdoublefiltercomp) + private + fcoeffsetting: boolean; + forigcoeff: tcomplexdatalist; + function getcoeff: tcomplexcoeff; + procedure setcoeff(const avalue: tcomplexcoeff); + procedure origcoeffchanged(const sender: tobject); + procedure setorigcoeff(const avalue: tcomplexdatalist); + protected + procedure createcoeff; override; + procedure checkcoeffs; override; + procedure defineproperties(filer: tfiler); override; +// procedure processinout(const acount: integer; +// var ainp,aoutp: pdouble); override; +// function getzcount: integer; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + property origcoeff: tcomplexdatalist read forigcoeff write setorigcoeff; + published + property coeff: tcomplexcoeff read getcoeff write setcoeff; + end; + + sigfilterkindty = (sfk_lp1bilinear,sfk_lp1impulseinvariant, + sfk_lp2bilinear,sfk_bp2bilinear,sfk_bs2bilinear); + sigfilteroptionty = (sfo_passgainfix,sfo_noprewarp); + sigfilteroptionsty = set of sigfilteroptionty; + + tsigfilter = class(tsigmultiinpout) //todo: speed optimized prewarp + private + ffrequencypo: psigvaluety; + ffrequfactpo: psigvaluety; + fqfactorpo: psigvaluety; + famplitudepo: psigvaluety; + fgain: double; + fz1: double; + fz2: double; + fb0: double; + fb1: double; + fb2: double; + fa1: double; + fa2: double; + ffrequency: tdoubleinputconn; + fqfactor: tdoubleinputconn; + fkind: sigfilterkindty; + foptions: sigfilteroptionsty; + famplitude: tdoubleinputconn; + ffrequfact: tdoubleinputconn; + procedure setfrequency(const avalue: tdoubleinputconn); + procedure setqfactor(const avalue: tdoubleinputconn); + procedure setkind(const avalue: sigfilterkindty); + procedure setoptions(const avalue: sigfilteroptionsty); + procedure setamplitude(const avalue: tdoubleinputconn); + procedure setfrequfact(const avalue: tdoubleinputconn); + protected + procedure sighandlerlp1inv(const ainfo: psighandlerinfoty); + procedure sighandlerlp1bi(const ainfo: psighandlerinfoty); + procedure sighandlerlp2bi(const ainfo: psighandlerinfoty); + procedure sighandlerb2bi; + procedure sighandlerbp2bi(const ainfo: psighandlerinfoty); + procedure sighandlerbs2bi(const ainfo: psighandlerinfoty); + + //isigclient + function getinputar: inputconnarty; override; + function gethandler: sighandlerprocty; override; + procedure initmodel; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + published + property frequency: tdoubleinputconn read ffrequency + write setfrequency; + property frequfact: tdoubleinputconn read ffrequfact write setfrequfact; + property qfactor: tdoubleinputconn read fqfactor + write setqfactor; + property amplitude: tdoubleinputconn read famplitude + write setamplitude; + property kind: sigfilterkindty read fkind write setkind + default sfk_lp1bilinear; + property options: sigfilteroptionsty read foptions + write setoptions default []; + end; + + tfilterbanksection = class(townedpersistent) + private + ffrequfact: tdoubleinputconn; + fqfactor: tdoubleinputconn; + famplitude: tdoubleinputconn; + procedure setfrequfact(const avalue: tdoubleinputconn); + procedure setqfactor(const avalue: tdoubleinputconn); + procedure setamplitude(const avalue: tdoubleinputconn); + public + constructor create(aowner: tobject); override; + destructor destroy; override; + published + property frequfact: tdoubleinputconn read ffrequfact + write setfrequfact; + property qfactor: tdoubleinputconn read fqfactor + write setqfactor; + property amplitude: tdoubleinputconn read famplitude + write setamplitude; + end; + + tfilterbanksections = class(townedpersistentarrayprop) + private + protected + procedure getinputar(var inputs: inputconnarty); + procedure dosizechanged; override; + public + constructor create(const aowner: tcomponent); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + published + end; + + filterinfoty = record + ffrequfactpo: psigvaluety; + fqfactorpo: psigvaluety; + famplitudepo: psigvaluety; + fa1: double; + fa2: double; + fb0: double; + fb1: double; + fb2: double; + z1: double; + z2: double; + end; + pfilterinfoty = ^filterinfoty; + filterinfoarty = array of filterinfoty; + + tsigfilterbank = class(tsigmultiinpout) //todo: speed optimized prewarp + private + fsections: tfilterbanksections; + ffrequency: tdoubleinputconn; + foptions: sigfilteroptionsty; + finfos: filterinfoarty; + finfohigh: integer; + fz1: double; + fz2: double; + ffrequencypo: psigvaluety; + famplitudepo: psigvaluety; + fbaseamplitudepo: psigvaluety; + famplitude: tdoubleinputconn; + fbaseamplitude: tdoubleinputconn; + procedure setfrequency(const avalue: tdoubleinputconn); + procedure setoptions(const avalue: sigfilteroptionsty); + procedure setsections(const avalue: tfilterbanksections); + procedure setamplitude(const avalue: tdoubleinputconn); + procedure setbaseamplitude(const avalue: tdoubleinputconn); + protected + //isigclient + procedure initmodel; override; + function getinputar: inputconnarty; override; + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; override; + published + property frequency: tdoubleinputconn read ffrequency write setfrequency; + property amplitude: tdoubleinputconn read famplitude write setamplitude; + property baseamplitude: tdoubleinputconn read fbaseamplitude + write setbaseamplitude; + property options: sigfilteroptionsty read foptions + write setoptions default []; + property sections: tfilterbanksections read fsections write setsections; + end; + +implementation +uses + sysutils,math,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdoubleinputconn1 = class(tdoubleinputconn); + tcomplexdatalist1 = class(tcomplexdatalist); + +{ tdoublefiltercomp } + +constructor tdoublefiltercomp.create(aowner: tcomponent); +begin + fsections:= tsections.create(self); + createcoeff; + inherited; +end; + +destructor tdoublefiltercomp.destroy; +begin + inherited; + fcoeff.free; + fsections.free; +end; + +procedure tdoublefiltercomp.zcountchanged; +begin + inherited; + fcoeff.count:= fzcount; +end; + +procedure tdoublefiltercomp.setcoeff(const avalue: tdatalist); +begin + fcoeff.assign(avalue); +end; + +procedure tdoublefiltercomp.coeffchanged(const sender: tdatalist; + const aindex: integer); +begin + if not fcoeffchecking and (aindex < 0) then begin + fcoeffchecking:= true; + try + sender.count:= fzcount; + checkcoeffs; + finally + fcoeffchecking:= false; + end; +// setzcount(sender.count); +// fsections.updatecoeffcount; + end; +end; + +procedure tdoublefiltercomp.setsections(const avalue: tsections); +begin + fsections.assign(avalue); +end; + +procedure tdoublefiltercomp.checkcoeffs; +begin + //dummy +end; + +{ tsigfir } + +procedure tsigfir.createcoeff; +begin + fcoeff:= trealcoeff.create(self); + trealcoeff(fcoeff).defaultzero:= true; + trealcoeff(fcoeff).min:= -bigreal; +end; + +function tsigfir.getcoeff: trealcoeff; +begin + result:= trealcoeff(fcoeff); +end; + +procedure tsigfir.setcoeff(const avalue: trealcoeff); +begin + inherited setcoeff(avalue); +end; +(* +procedure tsigfir.processinout(const acount: integer; var ainp, aoutp: pdouble); +var //todo: optimize + int1,int2,int3: integer; + ar1: doublearty; + i,o: double; + po1: pdouble; + inp1,outp1: pdouble; + startindex1,endindex1,endindex2: integer; +begin + if fzcount > 0 then begin + inp1:= ainp; + outp1:= aoutp; + for int1:= acount-1 downto 0 do begin + po1:= fcoeff.datapo; + i:= ainp^; + startindex1:= fzindex; + for int3:= 0 to high(fsections.fitems) do begin + endindex1:= startindex1 + fsections.fitems[int3] - 1; + if endindex1 > fzhigh then begin + endindex2:= endindex1-fzhigh-1; + endindex1:= fzhigh; + end + else begin + endindex2:= -1; + end; + + fdoublez[startindex1]:= i; + o:= 0; + for int2:= startindex1 to endindex1 do begin + o:= o + fdoublez[int2] * po1^; + inc(po1); + end; + for int2:= 0 to endindex2 do begin + o:= o + fdoublez[int2] * po1^; + inc(po1); + end; + startindex1:= startindex1 + fsections.fitems[int3]; + if startindex1 >= fzcount then begin + startindex1:= startindex1 - fzcount; + end; + i:= o; + end; + outp1^:= o; + dec(fzindex); + if fzindex < 0 then begin + fzindex:= fzhigh; + end; + inc(outp1); + inc(inp1); + end; + ainp:= inp1; + aoutp:= outp1; + end + else begin + inc(ainp,acount); + inc(aoutp,acount); + end; +end; +*) +function tsigfir.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigfir.sighandler(const ainfo: psighandlerinfoty); +var //todo: optimize + {int1,}int2,int3: integer; +// ar1: doublearty; + i,o: double; + po1: pdouble; +// inp1,outp1: pdouble; + startindex1,endindex1,endindex2: integer; +begin + po1:= fcoeff.datapo; + i:= finput.value; + o:= 0; + startindex1:= fzindex; //ringbuffer + for int3:= 0 to high(fsections.fitems) do begin + endindex1:= startindex1 + fsections.fitems[int3] - 1; + if endindex1 > fzhigh then begin + endindex2:= endindex1-fzhigh-1; + endindex1:= fzhigh; + end + else begin + endindex2:= -1; + end; + + fdoublez[startindex1]:= i; + o:= 0; + for int2:= startindex1 to endindex1 do begin + o:= o + fdoublez[int2] * po1^; + inc(po1); + end; + for int2:= 0 to endindex2 do begin + o:= o + fdoublez[int2] * po1^; + inc(po1); + end; + startindex1:= startindex1 + fsections.fitems[int3]; + if startindex1 >= fzcount then begin + startindex1:= startindex1 - fzcount; + end; + i:= o; + end; + foutputpo^:= o; + dec(fzindex); + if fzindex < 0 then begin + fzindex:= fzhigh; + end; +end; +{ +function tsigfir.getzcount: integer; +var + int1,int2,int3: integer; +begin + result:= 0; + int3:= 0; + for int1:= 0 to fsections.count -1 do begin + for int2:= 0 to fsections[int1]-1 do begin + if int3 >= coeff.count then begin + exit; + end; + if coeff[int3] = 0 then begin + inc(result); + inc(int3); + end + else begin + int3:= int3 + fsections[int1]-int2; + break; + end; + end; + end; +end; +} +{ tsigiir } + +constructor tsigiir.create(aowner: tcomponent); +begin + forigcoeff:= tcomplexdatalist.create; + forigcoeff.onchange:= @origcoeffchanged; + inherited; +end; + +destructor tsigiir.destroy; +begin + inherited; + forigcoeff.free; +end; + +procedure tsigiir.createcoeff; +begin + fcoeff:= tcomplexcoeff.create(self); + tcomplexcoeff(fcoeff).defaultzero:= true; + tcomplexcoeff(fcoeff).min:= -bigreal; +end; + +function tsigiir.getcoeff: tcomplexcoeff; +begin + result:= tcomplexcoeff(fcoeff); +end; + +procedure tsigiir.setcoeff(const avalue: tcomplexcoeff); +begin + inherited setcoeff(avalue); +end; + +procedure tsigiir.origcoeffchanged(const sender: tobject); +var + int1,int2: integer; + norm: double; + ps,pd: pcomplexty; +begin + if not fcoeffsetting then begin + ps:= forigcoeff.datapo; + pd:= fcoeff.datapo; + for int1:= 0 to fsections.count-1 do begin + norm:= ps^.re; + if norm = 0 then begin + ps^.re:= 1.0; + norm:= 1.0; + end; + for int2:= 0 to fsections.fitems[int1]-1 do begin + pd^.re:= ps^.re/norm; + pd^.im:= ps^.im/norm; + inc(ps); + inc(pd); + end; + end; + end; +end; + +procedure tsigiir.setorigcoeff(const avalue: tcomplexdatalist); +begin + forigcoeff.assign(avalue); +end; + +procedure tsigiir.defineproperties(filer: tfiler); +begin + inherited; + tcomplexdatalist1(forigcoeff).defineproperties('origcoeff',filer); +end; + +(* +procedure tsigiir.processinout(const acount: integer; var ainp: pdouble; + var aoutp: pdouble); +var + int1,int2,int3: integer; + inp1,outp1: pdouble; + i,o: double; + po0: pcomplexty; + po1: pcomplexty; //todo: optimize +begin + if fzcount > 0 then begin + inp1:= ainp; + outp1:= aoutp; + po0:= fcoeff.datapo; + for int1:= acount-1 downto 0 do begin + po1:= po0; + i:= inp1^; + o:= i*po1^.im+fdoublez[0]; + int3:= 0; + for int2:= 1 to fzhigh do begin + inc(po1); + if int2 = fsections.fitems[int3] then begin + i:= o; + o:= i*po1^.im+fdoublez[int2]; + end + else begin + fdoublez[int2-1]:= fdoublez[int2] + i*po1^.im - o*po1^.re; + end; + end; + outp1^:= o; + inc(outp1); + inc(inp1); + end; + ainp:= inp1; + aoutp:= outp1; + end + else begin + inc(ainp,acount); + inc(aoutp,acount); + end; +end; +*) +function tsigiir.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigiir.sighandler(const ainfo: psighandlerinfoty); +var + {int1,}int2,int3,int4: integer; +// inp1,outp1: pdouble; + i,o: double; + po1: pcomplexty; //todo: optimize +begin + po1:= fcoeff.datapo; + i:= finput.value; + o:= i*po1^.im+fdoublez[0]; + int3:= 0; + int4:= fsections.fitems[0]; + for int2:= 1 to fzhigh do begin + inc(po1); + if int2 = int4 then begin //next section + inc(int3); + int4:= int4 + fsections.fitems[int3]; + i:= o; + o:= i*po1^.im+fdoublez[int2]; + end + else begin + fdoublez[int2-1]:= fdoublez[int2] + i*po1^.im - o*po1^.re; + end; + end; + foutputpo^:= o; +end; + +procedure tsigiir.checkcoeffs; +var + int1,int2: integer; + po1: pcomplexty; +begin + int2:= 0; + po1:= fcoeff.datapo; + for int1:= 0 to fsections.count-1 do begin + po1[int2].re:= 1.0; + int2:= int2 + fsections.fitems[int1]; + end; + if not fcoeffsetting then begin + fcoeffsetting:= true; + try + forigcoeff.assign(fcoeff); + finally + fcoeffsetting:= false; + end; + end; +end; + +{ +function tsigiir.getzcount: integer; +var + int1,int2,int3: integer; +begin + result:= 0; + int3:= 0; + for int1:= 0 to fsections.count -1 do begin + for int2:= 0 to fsections[int1]-1 do begin + if int3 >= coeff.count then begin + exit; + end; + if coeff[int3].im = 0 then begin + inc(result); + inc(int3); + end + else begin + int3:= int3 + fsections[int1]-int2; + break; + end; + end; + end; +end; +} +{ tsections } + +constructor tsections.create(const aowner: tdoublefiltercomp); +begin + fowner:= aowner; + inherited create; +end; + +function tsections.calccoeffcount: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(fitems) do begin + result:= result + fitems[int1]; + end; +end; + +procedure tsections.dochange(const aindex: integer); +begin + fowner.setzcount(calccoeffcount); +end; +{ +procedure tsections.updatecoeffcount; +var + int1: integer; +begin + if not (csloading in fowner.componentstate) then begin + int1:= fowner.zcount-calccoeffcount; + if int1 <> 0 then begin + beginupdate; + try + if int1 > 0 then begin //add + if fitems = nil then begin + setlength(fitems,1); + end; + fitems[high(fitems)]:= fitems[high(fitems)] + int1; + end + else begin + while int1 < 0 do begin //remove + fitems[high(fitems)]:= fitems[high(fitems)] + int1; + if fitems[high(fitems)] > 0 then begin + break; + end; + int1:= fitems[high(fitems)]; + setlength(fitems,high(fitems)); + end; + end; + finally + endupdate; + end; + end; + end; +end; +} +{ tsigfilter } + +constructor tsigfilter.create(aowner: tcomponent); +begin + ffrequency:= tdoubleinputconn.create(self,isigclient(self)); + ffrequency.name:= 'frequeny'; + ffrequency.value:= 0.01; + ffrequfact:= tdoubleinputconn.create(self,isigclient(self)); + ffrequfact.name:= 'frequfact'; + ffrequfact.value:= 1; + fqfactor:= tdoubleinputconn.create(self,isigclient(self)); + fqfactor.name:= 'qfactor'; + fqfactor.value:= 1; + famplitude:= tdoubleinputconn.create(self,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitude.value:= 1; + inherited; +end; + +function tsigfilter.gethandler: sighandlerprocty; +begin + case fkind of + sfk_lp1impulseinvariant: begin + result:= {$ifdef FPC}@{$endif}sighandlerlp1inv; + end; + sfk_lp2bilinear: begin + result:= {$ifdef FPC}@{$endif}sighandlerlp2bi; + end; + sfk_bp2bilinear: begin + result:= {$ifdef FPC}@{$endif}sighandlerbp2bi; + end; + sfk_bs2bilinear: begin + result:= {$ifdef FPC}@{$endif}sighandlerbs2bi; + end; + else begin //sfk_lp1bilinear + result:= {$ifdef FPC}@{$endif}sighandlerlp1bi; + end; + end; +end; + +// +---------+---------+---------+---> o +// | -a1 -a2 -aN-1 +// +---(z)<--+---(z)<--+---(z)<--+ +// b0 b1 b2 bN-1 +// i >---+---------+---------+---------+ +// + +procedure tsigfilter.sighandlerlp1inv(const ainfo: psighandlerinfoty); +var + i,o,do1: double; + int1: integer; +begin + if (ffrequencypo^.changed <> []) or (ffrequfactpo^.changed <> []) then begin + exclude(ffrequencypo^.changed,sic_value); + exclude(ffrequfactpo^.changed,sic_value); + do1:= ffrequencypo^.value*ffrequfactpo^.value; + if do1 > 0 then begin + fb0:= 2*pi*do1; + fa1:= exp(-fb0); + end; + end; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + o:= i*fb0 + fz1; + foutputpo^:= o*famplitudepo^.value; + fz1:= o*fa1; +end; + +procedure tsigfilter.sighandlerlp1bi(const ainfo: psighandlerinfoty); +var + i,o: double; + do1: double; + int1: integer; +begin + if (ffrequencypo^.changed <> []) or (ffrequfactpo^.changed <> []) then begin + exclude(ffrequencypo^.changed,sic_value); + exclude(ffrequfactpo^.changed,sic_value); + do1:= ffrequencypo^.value*ffrequfactpo^.value; + if do1 > 0 then begin + do1:= 2*pi*do1; + fb0:= do1/(do1+2); + fb1:= fb0; + fa1:= (do1-2)/(do1+2); + end; + end; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + o:= i*fb0 + fz1; + foutputpo^:= o*famplitudepo^.value; + fz1:= i*fb1-fa1*o; +end; + +procedure tsigfilter.sighandlerlp2bi(const ainfo: psighandlerinfoty); +var + QfT_4,fT2_4,den: double; + i,o,do1: double; + int1: integer; +begin + if (ffrequencypo^.changed <> []) or (ffrequfactpo^.changed <> []) or + (fqfactorpo^.changed <> []) then begin + exclude(ffrequencypo^.changed,sic_value); + exclude(ffrequfactpo^.changed,sic_value); + exclude(fqfactorpo^.changed,sic_value); + do1:= ffrequencypo^.value*ffrequfactpo^.value; + if do1 > 0 then begin +// if (fqfactorpo^ <> fqfactorbefore) or (do1 <> ffrequencybefore) then begin +// ffrequencybefore:= do1; +// fqfactorbefore:= fqfactorpo^; + fT2_4:= do1*2*pi; // fT + if not (sfo_noprewarp in foptions) then begin + fT2_4:= 2*tan(0.5*fT2_4); + end; + if sfo_passgainfix in foptions then begin + fgain:= 1; + end + else begin + fgain:= (1/sqrt(sqrt(2)))/sqrt(fqfactorpo^.value); + end; + QfT_4:= 4/(fqfactorpo^.value*fT2_4); // 4/(Q*fT) + fT2_4:= 4/(fT2_4*fT2_4); // 4/fT^2 + den:= 1 + QfT_4 + fT2_4; // 1 + 4/(Q*fT) + 4/fT^2 + fb0:= fgain/den; + fb1:= 2*fb0; + fb2:= fb0; + fa1:= 2*(1-fT2_4)/den; + fa2:= (1-QfT_4+fT2_4)/den; + end; + end; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + o:= fz1+i*fb0; + fz1:= fz2-o*fa1+i*fb1; + fz2:= i*fb2-o*fa2; + foutputpo^:= o*famplitudepo^.value; +end; + +procedure tsigfilter.sighandlerb2bi; +var + fT,QfT_4,fT2_4,den,do1: double; +begin + if (ffrequencypo^.changed <> []) or (ffrequfactpo^.changed <> []) or + (fqfactorpo^.changed <> []) then begin + exclude(ffrequencypo^.changed,sic_value); + exclude(ffrequfactpo^.changed,sic_value); + exclude(fqfactorpo^.changed,sic_value); + do1:= ffrequencypo^.value*ffrequfactpo^.value; + if do1 > 0 then begin +// do1:= ffrequencypo^*ffrequfactpo^; +// if do1 > 0 then begin +// if (fqfactorpo^ <> fqfactorbefore) or (do1 <> ffrequencybefore) then begin +// ffrequencybefore:= do1; +// fqfactorbefore:= fqfactorpo^; + fT:= do1*2*pi; // fT + if not (sfo_noprewarp in foptions) then begin + fT:= 2*tan(0.5*fT); + end; + if (sfo_passgainfix in foptions) or (fkind = sfk_bs2bilinear) then begin + fgain:= 4/(fT*fqfactorpo^.value); + end + else begin + fgain:= 4/(fT*sqrt(fqfactorpo^.value)); + end; + QfT_4:= 4/(fqfactorpo^.value*fT); // 4/(Q*fT) + fT2_4:= 4/(fT*fT); // 4/fT^2 + den:= 1 + QfT_4 + fT2_4; // 1 + 4/(Q*fT) + 4/fT^2 + fb0:= fgain/den; + fb1:= 0; + fb2:= -fb0; + fa1:= 2*(1-fT2_4)/den; + fa2:= (1-QfT_4+fT2_4)/den; + end; + end; +end; + +procedure tsigfilter.sighandlerbp2bi(const ainfo: psighandlerinfoty); +var + i,o: double; + int1: integer; +begin + sighandlerb2bi; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + o:= fz1+i*fb0; + fz1:= fz2-o*fa1+i*fb1; + fz2:= i*fb2-o*fa2; + foutputpo^:= o*famplitudepo^.value; +end; + +procedure tsigfilter.sighandlerbs2bi(const ainfo: psighandlerinfoty); +var + i,o: double; + int1: integer; +begin + sighandlerb2bi; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + o:= fz1+i*fb0; + fz1:= fz2-o*fa1+i*fb1; + fz2:= i*fb2-o*fa2; + foutputpo^:= (i-o)*famplitudepo^.value; +end; + +procedure tsigfilter.clear; +begin + inherited; +// ffrequencybefore:= -1; +// fqfactorbefore:= -1; +end; + +procedure tsigfilter.initmodel; +begin +// finppo:= @tdoubleinputconn1(finput).fvalue; + ffrequencypo:= @tdoubleinputconn1(ffrequency).fv; + ffrequfactpo:= @tdoubleinputconn1(ffrequfact).fv; + fqfactorpo:= @tdoubleinputconn1(fqfactor).fv; + famplitudepo:= @tdoubleinputconn1(famplitude).fv; + inherited; +end; + +procedure tsigfilter.setfrequency(const avalue: tdoubleinputconn); +begin + ffrequency.assign(avalue); +end; + +function tsigfilter.getinputar: inputconnarty; +begin + setlength(result,4); + result[0]:= ffrequency; + result[1]:= ffrequfact; + result[2]:= fqfactor; + result[3]:= famplitude; + stackarray(pointerarty(inherited getinputar),pointerarty(result)); +end; + +procedure tsigfilter.setqfactor(const avalue: tdoubleinputconn); +begin + fqfactor.assign(avalue); +end; + +procedure tsigfilter.setkind(const avalue: sigfilterkindty); +begin + if fkind <> avalue then begin + lock; + fkind:= avalue; + modelchange; + unlock; + end; +end; + +procedure tsigfilter.setoptions(const avalue: sigfilteroptionsty); +begin + if foptions <> avalue then begin + lock; + foptions:= avalue; + modelchange; + unlock; + end; +end; + +procedure tsigfilter.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +procedure tsigfilter.setfrequfact(const avalue: tdoubleinputconn); +begin + ffrequfact.assign(avalue); +end; + +{ tfilterbanksection } + +constructor tfilterbanksection.create(aowner: tobject); +begin + inherited; + ffrequfact:= tdoubleinputconn.create(nil,isigclient(tsigfilterbank(aowner))); + ffrequfact.name:= 'frequfact'; + ffrequfact.value:= 1; + fqfactor:= tdoubleinputconn.create(nil,isigclient(tsigfilterbank(aowner))); + fqfactor.name:= 'qfactor'; + fqfactor.value:= 1; + famplitude:= tdoubleinputconn.create(nil,isigclient(tsigfilterbank(aowner))); + famplitude.name:= 'amplitude'; + famplitude.value:= 1; +end; + +destructor tfilterbanksection.destroy; +begin + ffrequfact.free; + fqfactor.free; + famplitude.free; + inherited; +end; + +procedure tfilterbanksection.setfrequfact(const avalue: tdoubleinputconn); +begin + ffrequfact.assign(avalue); +end; + +procedure tfilterbanksection.setqfactor(const avalue: tdoubleinputconn); +begin + fqfactor.assign(avalue); +end; + +procedure tfilterbanksection.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +{ tfilterbanksections } + +constructor tfilterbanksections.create(const aowner: tcomponent); +begin + inherited create(aowner,tfilterbanksection); +end; + +procedure tfilterbanksections.getinputar(var inputs: inputconnarty); +var + int1,int2{,int3}: integer; +begin + int1:= length(inputs); + setlength(inputs,int1+count*3); + for int2:= 0 to count - 1 do begin + with tfilterbanksection(fitems[int2]) do begin + inputs[int1]:= ffrequfact; + inc(int1); + inputs[int1]:= fqfactor; + inc(int1); + inputs[int1]:= famplitude; + inc(int1); + end; + end; +end; + +procedure tfilterbanksections.dosizechanged; +begin + inherited; + tsigfilterbank(fowner).modelchange; +end; + +class function tfilterbanksections.getitemclasstype: persistentclassty; +begin + result:= tfilterbanksection; +end; + +{ tsigfilterbank } + +constructor tsigfilterbank.create(aowner: tcomponent); +begin + fsections:= tfilterbanksections.create(self); + ffrequency:= tdoubleinputconn.create(nil,isigclient(self)); + ffrequency.name:= 'frequency'; + ffrequency.value:= 0.01; + famplitude:= tdoubleinputconn.create(nil,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitude.value:= 1; + fbaseamplitude:= tdoubleinputconn.create(nil,isigclient(self)); + fbaseamplitude.name:= 'baseamplitude'; + fbaseamplitude.value:= 1; + inherited; +end; + +destructor tsigfilterbank.destroy; +begin + inherited; + fsections.free; + ffrequency.free; + famplitude.free; + fbaseamplitude.free; +end; + +procedure tsigfilterbank.setsections(const avalue: tfilterbanksections); +begin + fsections.assign(avalue); +end; + +procedure tsigfilterbank.setfrequency(const avalue: tdoubleinputconn); +begin + ffrequency.assign(avalue); +end; + +procedure tsigfilterbank.setoptions(const avalue: sigfilteroptionsty); +begin + if foptions <> avalue then begin + lock; + foptions:= avalue; + modelchange; + unlock; + end; +end; + +function tsigfilterbank.getinputar: inputconnarty; +begin + result:= inherited getinputar; + setlength(result,high(result)+4); + result[high(result)-2]:= ffrequency; + result[high(result)-1]:= famplitude; + result[high(result)]:= fbaseamplitude; + fsections.getinputar(result); +end; + +function tsigfilterbank.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigfilterbank.sighandler(const ainfo: psighandlerinfoty); + + procedure setupparams(const asection: pfilterinfoty); + var + fT,QfT_4,fT2_4,den,do1,fgain: double; + begin + with asection^ do begin + exclude(ffrequfactpo^.changed,sic_value); + exclude(fqfactorpo^.changed,sic_value); + do1:= ffrequencypo^.value*ffrequfactpo^.value; + if do1 > 0 then begin + fT:= do1*2*pi; // fT + if not (sfo_noprewarp in foptions) then begin + fT:= 2*tan(0.5*fT); + end; +// if (sfo_passgainfix in foptions) or (fkind = sfk_bs2bilinear) then begin + fgain:= 4/(fT*fqfactorpo^.value); +// end +// else begin +// fgain:= 4/(fT*sqrt(fqfactorpo^.value)); +// end; + QfT_4:= 4/(fqfactorpo^.value*fT); // 4/(Q*fT) + fT2_4:= 4/(fT*fT); // 4/fT^2 + den:= 1 + QfT_4 + fT2_4; // 1 + 4/(Q*fT) + 4/fT^2 + fb0:= fgain/den; + fb1:= 0; + fb2:= -fb0; + fa1:= 2*(1-fT2_4)/den; + fa2:= (1-QfT_4+fT2_4)/den; + end; + end; + end; //setupparams() + +var + i,o,ot: double; + int1: integer; + po1: pfilterinfoty; +begin + if (ffrequencypo^.changed <> []) then begin + exclude(ffrequencypo^.changed,sic_value); + po1:= pointer(finfos); + for int1:= finfohigh downto 0 do begin + setupparams(po1); + inc(po1); + end; + end; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + ot:= 0; + po1:= pointer(finfos); + for int1:= finfohigh downto 0 do begin + with po1^ do begin + if (ffrequfactpo^.changed <> []) or (fqfactorpo^.changed <> []) then begin + setupparams(po1); + end; + o:= i*fb0+fz1*fb1+fz2*fb2-z1*fa1-z2*fa2; + z2:= z1; + z1:= o; + ot:= ot+o*famplitudepo^.value; + end; + inc(po1); + end; + fz2:= fz1; + fz1:= i; + foutputpo^:= (i*fbaseamplitudepo^.value+ot)*famplitudepo^.value; +end; + +procedure tsigfilterbank.initmodel; +var + int1: integer; +begin + inherited; + ffrequencypo:= @tdoubleinputconn1(ffrequency).fv; + famplitudepo:= @tdoubleinputconn1(famplitude).fv; + fbaseamplitudepo:= @tdoubleinputconn1(fbaseamplitude).fv; + setlength(finfos,fsections.count); + finfohigh:= high(finfos); + for int1:= finfohigh downto 0 do begin + with finfos[int1],tfilterbanksection(fsections.fitems[int1]) do begin + ffrequfactpo:= @tdoubleinputconn1(ffrequfact).fv; + fqfactorpo:= @tdoubleinputconn1(fqfactor).fv; + famplitudepo:= @tdoubleinputconn1(famplitude).fv; + end; + end; +end; + +procedure tsigfilterbank.clear; +var + int1: integer; +begin + inherited; + fz1:= 0; + fz2:= 0; + for int1:= high(finfos) downto 0 do begin + with finfos[int1] do begin + z1:= 0; + z2:= 0; + end; + end; +end; + +procedure tsigfilterbank.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +procedure tsigfilterbank.setbaseamplitude(const avalue: tdoubleinputconn); +begin + fbaseamplitude.assign(avalue); +end; + +end. diff --git a/mseide-msegui/lib/common/math/mselfsr.pas b/mseide-msegui/lib/common/math/mselfsr.pas new file mode 100644 index 0000000..0bf92b2 --- /dev/null +++ b/mseide-msegui/lib/common/math/mselfsr.pas @@ -0,0 +1,45 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mselfsr; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes; + +//32 bit lfsr x^32+x^30+x^26+x^25+1 + +function lfsr32(var sr: card32): card32; +procedure lfsr321(var sr: card32); + +implementation +const + feedbacktable: array[0..255] of byte = ( + 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0, + 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1, + 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0, + 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1, + 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1, + 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0, + 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1, + 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0 + ); + +function lfsr32(var sr: card32): card32; +begin + sr:= feedbacktable[sr shr 24] + (sr shl 1); + result:= sr; +end; + +procedure lfsr321(var sr: card32); +begin + sr:= feedbacktable[sr shr 24] + (sr shl 1); +end; + +end. diff --git a/mseide-msegui/lib/common/math/msenoise.pas b/mseide-msegui/lib/common/math/msenoise.pas new file mode 100644 index 0000000..8799dd1 --- /dev/null +++ b/mseide-msegui/lib/common/math/msenoise.pas @@ -0,0 +1,115 @@ +{ MSEgui Copyright (c) 2013-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msenoise; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes; +const + defaultmwcseedw = 521288629; + defaultmwcseedz = 362436069; +type + mwcinfoty = record + fw,fz: card32; //call checkmwcseed() after init + end; + + tmwcnoisegen = class + private + fw: card32; + fz: card32; + public + constructor create; + procedure init(const w: card32 = 0; const z: card32 = 0); + function next: card32; + end; + +function mwcnoise(var state: mwcinfoty): card32; overload; +function mwcnoise: card32; overload; +procedure mwcnoiseinit(const w: card32 = 0; const z: card32 = 0); +procedure checkmwcseed(var w: card32; var z: card32); + //0 -> use random +procedure checkmwcseed(var state: mwcinfoty); + +implementation + +var + fw: card32 = defaultmwcseedw; //"random" seed + fz: card32 = defaultmwcseedz; //"random" seed + +procedure checkmwcseed(var w: card32; var z: card32); +begin + if w = 0 then begin + w:= random($9068fffe)+1; + end + else begin + if w mod $9068ffff = 0 then begin + w:= (w xor $ffffffff) mod $9068ffff; + end; + end; + if z = 0 then begin + z:= random($464ffffe)+1; + end + else begin + if z mod $464fffff = 0 then begin + z:= (z xor $ffffffff) mod $464fffff; + end; + end; +end; + +procedure checkmwcseed(var state: mwcinfoty); +begin + checkmwcseed(state.fw,state.fz); +end; + +procedure mwcnoiseinit(const w: card32 = 0; const z: card32 = 0); +begin + fw:= w; + fz:= z; + checkmwcseed(fw,fz); +end; + +function mwcnoise: card32; +begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + result:= fz shl 16 + fw; +end; + +function mwcnoise(var state: mwcinfoty): card32; +begin + with state do begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + result:= fz shl 16 + fw; + end; +end; + +{ tmwcnoisegen } + +constructor tmwcnoisegen.create; +begin + init; +end; + +procedure tmwcnoisegen.init(const w: card32 = 0; const z: card32 = 0); +begin + fw:= w; + fz:= z; + checkmwcseed(fw,fz); +end; + +function tmwcnoisegen.next: card32; +begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + result:= fz shl 16 + fw; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesigaudio.pas b/mseide-msegui/lib/common/math/msesigaudio.pas new file mode 100644 index 0000000..bb09fd7 --- /dev/null +++ b/mseide-msegui/lib/common/math/msesigaudio.pas @@ -0,0 +1,499 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesigaudio; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseaudio,msesignal,classes,mclasses,msethread,msetypes,msestrings; + +const + defaultblocksize = 1000; + +type + tsigoutaudio = class; + + tsigaudioout = class(tcustomaudioout) + private + protected + fsigout: tsigoutaudio; + fblocksize: integer; + fbuffer: bytearty; + function threadproc(sender: tmsethread): integer; override; + procedure run; override; + procedure stop; override; + procedure initnames; override; + public + constructor create(const aowner: tsigoutaudio); reintroduce; + published + property blocksize: integer read fblocksize write fblocksize + default defaultblocksize; + property active; + property server; + property dev; + property appname; + property streamname; +// property channels; + property format; + property rate; + property latency; + property stacksizekb; +// property onsend; +// property onerror; + + end; + + tsigoutaudio = class(tsigmultiinp) + private + faudio: tsigaudioout; + fbuffer: doublearty; + fbufpo: pdouble; + procedure setaudio(const avalue: tsigaudioout); + protected + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property audio: tsigaudioout read faudio write setaudio; + end; + +implementation +uses + msesysintf,msepulsesimple,sysutils{$ifndef FPC},classes_del{$endif}; + +{ tsigaudioout } + +constructor tsigaudioout.create(const aowner: tsigoutaudio); +begin + fblocksize:= defaultblocksize; + fsigout:= aowner; + inherited create(aowner); + setsubcomponent(true); +end; + +type + convertinfoty = record + source: pdouble; + dest: pointer; + valuehigh: integer; + end; + convertprocty = procedure(var info: convertinfoty); + +procedure convert8(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + pbyte(dest)^:= $80+round(do1*$7f); + inc(source); + inc(pbyte(dest)); + end; + end; +end; + +procedure convert16(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + psmallint(dest)^:= round(do1*$7fff); + inc(source); + inc(psmallint(dest)); + end; + end; +end; + +procedure convert24(var info: convertinfoty); +var + int1: integer; + do1: double; + int2: integer; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + int2:= round(do1*$7fffff); + {$ifdef FPC} + pbyte(dest)[0]:= pbyte(@int2)[0]; + pbyte(dest)[1]:= pbyte(@int2)[1]; + pbyte(dest)[2]:= pbyte(@int2)[2]; + {$else} + pchar(dest)[0]:= pchar(@int2)[0]; + pchar(dest)[1]:= pchar(@int2)[1]; + pchar(dest)[2]:= pchar(@int2)[2]; + {$endif} + inc(source); + inc(pbyte(dest),3); + end; + end; +end; + +procedure convert32(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + pinteger(dest)^:= round(do1*$7fffffff); + inc(source); + inc(pinteger(dest)); + end; + end; +end; + +procedure convert32f(var info: convertinfoty); +var + int1: integer; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + psingle(dest)^:= source^; + inc(source); + inc(psingle(dest)); + end; + end; +end; + +procedure convert2432(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + pinteger(dest)^:= round(do1*$7fffff); + inc(source); + inc(pinteger(dest)); + end; + end; +end; + +procedure convert16swap(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + psmallint(dest)^:= swapendian(smallint(round(do1*$7fff))); + inc(source); + inc(psmallint(dest)); + end; + end; +end; + +procedure convert24swap(var info: convertinfoty); +var + int1: integer; + do1: double; + int2: integer; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + int2:= round(do1*$7fffff); + {$ifdef FPC} + pbyte(dest)[0]:= pbyte(@int2)[2]; + pbyte(dest)[1]:= pbyte(@int2)[1]; + pbyte(dest)[2]:= pbyte(@int2)[0]; + {$else} + pchar(dest)[0]:= pchar(@int2)[2]; + pchar(dest)[1]:= pchar(@int2)[1]; + pchar(dest)[2]:= pchar(@int2)[0]; + {$endif} + inc(source); + inc(pbyte(dest),3); + end; + end; +end; + +procedure convert32swap(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + pinteger(dest)^:= swapendian(integer(round(do1*$7fffffff))); + inc(source); + inc(pinteger(dest)); + end; + end; +end; + +procedure convert32fswap(var info: convertinfoty); +var + int1: integer; + si1: single; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + {$ifdef FPC} + si1:= single(source^); + {$else} + si1:= source^; + {$endif} + plongword(dest)^:= swapendian(longword(plongword(@si1)^)); + inc(source); + inc(psingle(dest)); + end; + end; +end; + +procedure convert2432swap(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + pinteger(dest)^:= swapendian(integer(round(do1*$7fffff))); + inc(source); + inc(pinteger(dest)); + end; + end; +end; + +function tsigaudioout.threadproc(sender: tmsethread): integer; +var +// data: pointer; + int1: integer; + datasize1,blocksize1,bufferlength1,valuehigh1: integer; + controller1: tsigcontroller; +// po1: pointer; +// po2: pdouble; +// do1: double; + convert: convertprocty; + info: convertinfoty; +begin + result:= 0; + controller1:= fsigout.controller; + if controller1 <> nil then begin + factive:= true; + datasize1:= samplebuffersizematrix[fformat]; + blocksize1:= fblocksize; + valuehigh1:= fsigout.inputs.count*blocksize1; + bufferlength1:= datasize1*valuehigh1; + dec(valuehigh1); + info.valuehigh:= valuehigh1; + setlength(fbuffer,bufferlength1); + case fformat of + sfm_u8,sfm_8alaw,sfm_8ulaw: begin + convert:= @convert8; + end; + sfm_s16{$ifdef endian_little},sfm_s16le{$else},sfm_s16be{$endif}: begin + convert:= @convert16; + end; + sfm_s24{$ifdef endian_little},sfm_s24le{$else},sfm_s24be{$endif}: begin + convert:= @convert24; + end; + sfm_s32{$ifdef endian_little},sfm_s32le{$else},sfm_s32be{$endif}: begin + convert:= @convert32; + end; + sfm_f32{$ifdef endian_little},sfm_f32le{$else},sfm_f32be{$endif}: begin + convert:= @convert32f; + end; + smf_s2432{$ifdef endian_little},smf_s2432le{$else},smf_s2432be{$endif}: begin + convert:= @convert2432; + end; + {$ifdef endian_little} + sfm_s16be: begin + convert:= @convert16swap; + end; + sfm_s24be: begin + convert:= @convert24swap; + end; + sfm_s32be: begin + convert:= @convert32swap; + end; + sfm_f32be: begin + convert:= @convert32fswap; + end; + smf_s2432be: begin + convert:= @convert2432swap; + end; + {$else} + sfm_s16le: begin + convert:= @convert16swap; + end; + sfm_s24le: begin + convert:= @convert24swap; + end; + sfm_s32le: begin + convert:= @convert32swap; + end; + sfm_f32le: begin + convert:= @convert32fswap; + end; + smf_s2432le: begin + convert:= @convert2432swap; + end; + {$endif} + else begin + exit; + end; + end; + + while not sender.terminated do begin + controller1.lock; + try + fsigout.fbufpo:= pointer(fsigout.fbuffer); + controller1.step(blocksize1); + info.source:= pointer(fsigout.fbuffer); + info.dest:= pointer(fbuffer); + convert(info); + finally + controller1.unlock; + end; + if pa_simple_write(fpulsestream,pointer(fbuffer), + bufferlength1,@int1) <> 0 then begin + doerror(int1); + break; + end; + end; + end; +end; + +procedure tsigaudioout.run; +var + int1: integer; +begin + int1:= fsigout.inputs.count; + channels:= int1; + setlength(fsigout.fbuffer,int1*fblocksize); + inherited; +end; + +procedure tsigaudioout.stop; +begin + inherited; + fsigout.fbufpo:= nil; +end; + +procedure tsigaudioout.initnames; +begin + inherited; + if fstreamname = '' then begin + fstreamname:= msestring(fsigout.name); + end; +end; + +{ tsigoutaudio } + +constructor tsigoutaudio.create(aowner: tcomponent); +begin + faudio:= tsigaudioout.create(self); + inherited; +// finputs:= taudioinpconnarrayprop.create(self); +end; + +destructor tsigoutaudio.destroy; +begin + faudio.free; + inherited; +// finputs.free; +end; +{ +procedure tsigoutaudio.setinputs(const avalue: taudioinpconnarrayprop); +begin + finputs.assign(avalue); +end; +} +procedure tsigoutaudio.setaudio(const avalue: tsigaudioout); +begin + faudio.assign(avalue); +end; + +function tsigoutaudio.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigoutaudio.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; +begin + if fbufpo <> nil then begin + for int1:= 0 to finphigh do begin + fbufpo^:= finps[int1]^.value; + inc(fbufpo); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesigfft.pas b/mseide-msegui/lib/common/math/msesigfft.pas new file mode 100644 index 0000000..aadbb85 --- /dev/null +++ b/mseide-msegui/lib/common/math/msesigfft.pas @@ -0,0 +1,483 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +// +// experimental +// + +unit msesigfft; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msesignal,msefft,classes,mclasses,msetypes,mseglob; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + + tbufferdoublesigcomp = class; + + sigbuffereventty = procedure of object; + + tbufferdoubleoutputconn = class(tdoubleoutputconn) + private + fonoutputburst: sigoutbursteventty; + procedure setsamplecount(avalue: integer); + protected + fsignal: doublearty; + fsamplecount: integer; + findex: integer; + procedure clear; + property samplecount: integer read fsamplecount + write setsamplecount default 1; + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); override; + published + property onoutputburst: sigoutbursteventty read fonoutputburst + write fonoutputburst; + end; + + tbufferdoubleinputconn = class(tdoubleinputconn) + private + fonsigbufferfull: sigbuffereventty; + procedure setsamplecount(avalue: integer); + protected + foutput: tbufferdoubleoutputconn; + fsignal: doublearty; + fsamplecount: integer; + findex: integer; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure clear; + property samplecount: integer read fsamplecount + write setsamplecount default 1; + public + constructor create(const aowner: tbufferdoublesigcomp; + const aonsigbufferfull: sigbuffereventty); reintroduce; + end; + + tbufferdoublesigcomp = class(tdoublesigcomp) + private + finput: tbufferdoubleinputconn; + foutput: tbufferdoubleoutputconn; + procedure setoutput(const avalue: tbufferdoubleoutputconn); + procedure setinput(const avalue: tbufferdoubleinputconn); + function getonoutputburst: sigoutbursteventty; + procedure setonoutputburst(const avalue: sigoutbursteventty); + protected + procedure sigbufferfull; virtual; + //isigclient + function getinputar: inputconnarty; override; + function getoutputar: outputconnarty; override; + function gethandler: sighandlerprocty; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property output: tbufferdoubleoutputconn read foutput write setoutput; + published + property input: tbufferdoubleinputconn read finput write setinput; + property onoutputburst: sigoutbursteventty read getonoutputburst + write setonoutputburst; + end; + + tsigfft = class(tbufferdoublesigcomp) + private + ffft: tfft; + fsamplecount: integer; + procedure setsamplecount(avalue: integer); + function getwindowfunc: windowfuncty; + procedure setwindowfunc(const avalue: windowfuncty); + function getwindowfuncpar0: double; + procedure setwindowfuncpar0(const avalue: double); + function getwindowfuncpar1: double; + procedure setwindowfuncpar1(const avalue: double); + protected + procedure sigbufferfull; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property samplecount: integer read fsamplecount + write setsamplecount default 256; + property windowfunc: windowfuncty read getwindowfunc + write setwindowfunc default wf_rectangular; + property windowfuncpar0: double read getwindowfuncpar0 + write setwindowfuncpar0; + property windowfuncpar1: double read getwindowfuncpar1 + write setwindowfuncpar1; + end; + + tsigsamplerfft = class; + samplerffteventty = procedure(const sender: tsigsamplerfft; + const abuffer: samplerbufferty) of object; + + tsigsamplerfft = class(tsigsampler) + private + ffft: tfft; + fonfft: samplerffteventty; + function getwindowfunc: windowfuncty; + procedure setwindowfunc(const avalue: windowfuncty); + function getwindowfuncpar0: double; + procedure setwindowfuncpar0(const avalue: double); + function getwindowfuncpar1: double; + procedure setwindowfuncpar1(const avalue: double); + protected + ffftbuffer: samplerbufferty; + faveragecount: int32; + procedure dobufferfull; override; + procedure initmodel; override; + procedure updateoptions(var avalue: sigsampleroptionsty); override; + procedure setoptions(const avalue: sigsampleroptionsty) override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear override; + procedure clearaverage(); + property averagecount: int32 read faveragecount; + published + property windowfunc: windowfuncty read getwindowfunc + write setwindowfunc default wf_rectangular; + property windowfuncpar0: double read getwindowfuncpar0 + write setwindowfuncpar0; + property windowfuncpar1: double read getwindowfuncpar1 + write setwindowfuncpar1; + property onfft: samplerffteventty read fonfft write fonfft; + end; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tbufferdoubleinputconn } + +constructor tbufferdoubleinputconn.create(const aowner: tbufferdoublesigcomp; + const aonsigbufferfull: sigbuffereventty); +begin + samplecount:= 1; + fonsigbufferfull:= aonsigbufferfull; + foutput:= aowner.foutput; + inherited create(aowner,isigclient(aowner)); +end; + +procedure tbufferdoubleinputconn.sighandler(const ainfo: psighandlerinfoty); +begin + fsignal[findex]:= fv.value; + inc(findex); + if findex = fsamplecount then begin + findex:= 0; + fonsigbufferfull; + with foutput do begin + findex:= 0; + if assigned(fonoutputburst) then begin + fonoutputburst(self,realarty(fsignal)); + end; + end; + end; + with foutput do begin + fvalue:= fsignal[findex]; + inc(findex); + if findex = fsamplecount then begin + dec(findex); + end; + end; +end; + +procedure tbufferdoubleinputconn.clear; +begin +end; + +procedure tbufferdoubleinputconn.setsamplecount(avalue: integer); +begin + if avalue < 1 then begin + avalue:= 1; + end; + fsamplecount:= avalue; + findex:= 0; + setlength(fsignal,avalue); +end; + +{ tbufferdoubleoutputconn } + +constructor tbufferdoubleoutputconn.create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); +begin + samplecount:= 1; + inherited; +end; + +procedure tbufferdoubleoutputconn.clear; +begin +end; + +procedure tbufferdoubleoutputconn.setsamplecount(avalue: integer); +begin + if avalue < 1 then begin + avalue:= 1; + end; + fsamplecount:= avalue; + findex:= 0; + setlength(fsignal,avalue); +end; + +{ tbufferdoublesigcomp } + +constructor tbufferdoublesigcomp.create(aowner: tcomponent); +begin + foutput:= tbufferdoubleoutputconn.create(self,isigclient(self),false); + finput:= tbufferdoubleinputconn.create(self,{$ifdef FPC}@{$endif}sigbufferfull); + inherited; +end; + +function tbufferdoublesigcomp.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}finput.sighandler; +end; + +procedure tbufferdoublesigcomp.setoutput(const avalue: tbufferdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +procedure tbufferdoublesigcomp.setinput(const avalue: tbufferdoubleinputconn); +begin + finput.assign(avalue); +end; + +function tbufferdoublesigcomp.getinputar: inputconnarty; +begin + setlength(result,1); + result[0]:= finput; +end; + +function tbufferdoublesigcomp.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +procedure tbufferdoublesigcomp.sigbufferfull; +begin + //dummy +end; + +procedure tbufferdoublesigcomp.clear; +begin + inherited; + finput.clear; + foutput.clear; +end; + +function tbufferdoublesigcomp.getonoutputburst: sigoutbursteventty; +begin + result:= foutput.onoutputburst; +end; + +procedure tbufferdoublesigcomp.setonoutputburst(const avalue: sigoutbursteventty); +begin + foutput.onoutputburst:= avalue; +end; + +{ tsigfft } + +constructor tsigfft.create(aowner: tcomponent); +begin + ffft:= tfft.create(nil); + inherited; + samplecount:= 256; +end; + +destructor tsigfft.destroy; +begin + ffft.free; + inherited; +end; + +procedure tsigfft.setsamplecount(avalue: integer); +begin + if avalue < 2 then begin + avalue:= 2; + end; + if fsamplecount <> avalue then begin + fsamplecount:= avalue; + finput.samplecount:= avalue; + foutput.samplecount:= avalue div 2 + 1; + end; +end; + +procedure tsigfft.sigbufferfull; +begin + ffft.inpreal:= realarty(finput.fsignal); + foutput.fsignal:= doublearty(ffft.outreal); +end; + +function tsigfft.getwindowfunc: windowfuncty; +begin + result:= ffft.windowfunc; +end; + +procedure tsigfft.setwindowfunc(const avalue: windowfuncty); +begin + ffft.windowfunc:= avalue; +end; + +function tsigfft.getwindowfuncpar0: double; +begin + result:= ffft.windowfuncpar0; +end; + +procedure tsigfft.setwindowfuncpar0(const avalue: double); +begin + ffft.windowfuncpar0:= avalue; +end; + +function tsigfft.getwindowfuncpar1: double; +begin + result:= ffft.windowfuncpar1; +end; + +procedure tsigfft.setwindowfuncpar1(const avalue: double); +begin + ffft.windowfuncpar1:= avalue; +end; + +{ tsigsamplerfft } + +constructor tsigsamplerfft.create(aowner: tcomponent); +begin + inherited; + ffft:= tfft.create(nil); +end; + +destructor tsigsamplerfft.destroy; +begin + ffft.free; + inherited; +end; + +procedure tsigsamplerfft.clear; +begin + inherited; + clearaverage(); +end; + +procedure tsigsamplerfft.clearaverage(); +begin + faveragecount:= 0; +end; + +function tsigsamplerfft.getwindowfunc: windowfuncty; +begin + result:= ffft.windowfunc; +end; + +procedure tsigsamplerfft.setwindowfunc(const avalue: windowfuncty); +begin + ffft.windowfunc:= avalue; +end; + +function tsigsamplerfft.getwindowfuncpar0: double; +begin + result:= ffft.windowfuncpar0; +end; + +procedure tsigsamplerfft.setwindowfuncpar0(const avalue: double); +begin + ffft.windowfuncpar0:= avalue; +end; + +function tsigsamplerfft.getwindowfuncpar1: double; +begin + result:= ffft.windowfuncpar1; +end; + +procedure tsigsamplerfft.setwindowfuncpar1(const avalue: double); +begin + ffft.windowfuncpar1:= avalue; +end; + +procedure tsigsamplerfft.dobufferfull; +var + i1: int32; + f1,f2: flo64; + p1,p2,pe: pflo64; + ar1: realarty; +begin + inherited; + if sso_fftmag in options then begin + if sso_average in options then begin + for i1:= 0 to high(ffftbuffer) do begin + ffft.inpreal:= realarty(fsigbuffer[i1]); + if faveragecount = 0 then begin + ffftbuffer[i1]:= doublearty(ffft.outreal); + end + else begin + f1:= faveragecount; + f2:= faveragecount+1; + p1:= @ffftbuffer[i1][0]; + ar1:= ffft.outreal; + p2:= @ar1[0]; + pe:= p1 + length(ffftbuffer[i1]); + while p1 < pe do begin + p1^:= (p1^*f1+p2^)/f2; + inc(p1); + inc(p2); + end; + end; + end; + inc(faveragecount); + end + else begin + for i1:= 0 to high(ffftbuffer) do begin + ffft.inpreal:= realarty(fsigbuffer[i1]); + ffftbuffer[i1]:= doublearty(ffft.outreal); + end; + end; + if assigned(fonfft) then begin + fonfft(self,ffftbuffer); + end; + end; +end; + +procedure tsigsamplerfft.initmodel; +//var +// int1: integer; +begin + inherited; + ffftbuffer:= nil; + setlength(ffftbuffer,inputs.count); + faveragecount:= 0; +end; + +procedure tsigsamplerfft.updateoptions(var avalue: sigsampleroptionsty); +begin + //dummy +end; + +procedure tsigsamplerfft.setoptions(const avalue: sigsampleroptionsty); +begin + if (avalue >< foptions) * [sso_average] <> [] then begin + clearaverage(); + end; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesigfftgui.pas b/mseide-msegui/lib/common/math/msesigfftgui.pas new file mode 100644 index 0000000..59a8687 --- /dev/null +++ b/mseide-msegui/lib/common/math/msesigfftgui.pas @@ -0,0 +1,156 @@ +{ MSEgui Copyright (c) 20010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +// +// experimental +// + +unit msesigfftgui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msesignal,msechart,classes,mclasses,msesigfft,msegui,msegraphutils,msemenus, + msegraphics,mseguiglob,mseclasses,msetypes; + +type + tsigscopefft = class; + tscopesamplerfft = class(tsigsamplerfft) + private + fscope: tsigscopefft; + protected + procedure dobufferfull; override; + public + constructor create(const aowner: tsigscopefft); reintroduce; + end; + + tsigscopefft = class(tchart) + private + fsampler: tscopesamplerfft; + ffftfirst: integer; + ffftcount: integer; + fslave: tsigscopefft; + procedure setsampler(const avalue: tscopesamplerfft); + procedure setslave(const avalue: tsigscopefft); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property sampler: tscopesamplerfft read fsampler write setsampler; + property fftfirst: integer read ffftfirst write ffftfirst default 0; + property fftcount: integer read ffftcount write ffftcount default 0; + //0 -> all + property slave: tsigscopefft read fslave write setslave; + end; + +implementation +uses + sysutils; + +{ tsigscopefft } + +constructor tsigscopefft.create(aowner: tcomponent); +begin + fsampler:= tscopesamplerfft.create(self); + inherited; +end; + +destructor tsigscopefft.destroy; +begin + fsampler.free; + inherited; +end; + +procedure tsigscopefft.setsampler(const avalue: tscopesamplerfft); +begin + fsampler.assign(avalue); +end; + +procedure tsigscopefft.setslave(const avalue: tsigscopefft); +var + slave1: tsigscopefft; +begin + slave1:= avalue; + while slave1 <> nil do begin + if slave1 = self then begin + raise exception.create(name+': recursive slave '+avalue.name+'.'); + end; + slave1:= slave1.slave; + end; + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fslave)); +end; + +{ tscopesamplerfft } + +constructor tscopesamplerfft.create(const aowner: tsigscopefft); +begin + fscope:= aowner; + inherited create(aowner); + setsubcomponent(true); + name:= 'sampler'; +end; + +procedure tscopesamplerfft.dobufferfull; + + procedure handleslave(const asampler: tscopesamplerfft; + const asig,afft: samplerbufferty); + //todo: optimize slave handling, no additional buffer copy + var + buf1: samplerbufferty; + int1: integer; + int2: integer; + begin + with asampler do begin + if sso_fftmag in options then begin + with fscope do begin + if (ffftfirst = 0) and (ffftcount = 0) then begin + buf1:= afft; + end + else begin + int2:= ffftcount; + if int2 = 0 then begin + int2:= bigint; + end; + setlength(buf1,length(afft)); + for int1:= 0 to high(buf1) do begin + buf1[int1]:= copy(afft[int1],fftfirst,int2); + end; + end; + end; + end + else begin + buf1:= copy(asig); + end; + lockapplication; + try + with fscope.traces do begin + for int1:= 0 to high(buf1) do begin + if int1 >= count then begin + break; + end; + items[int1].ydata:= realarty(buf1[int1]); + end; + end; + finally + unlockapplication; + end; + end; + end; //handleslave() +var + slave: tsigscopefft; +begin + inherited; + slave:= self.fscope; + while slave <> nil do begin + handleslave(slave.fsampler,fsigbuffer,ffftbuffer); + slave:= slave.slave; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesiggui.pas b/mseide-msegui/lib/common/math/msesiggui.pas new file mode 100644 index 0000000..b3d0e54 --- /dev/null +++ b/mseide-msegui/lib/common/math/msesiggui.pas @@ -0,0 +1,2028 @@ +{ MSEgui Copyright (c) 2011-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesiggui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msegraphedits,msesignal,mseguiglob,mseevent,msechartedit, + msetypes, + msechart,mseclasses,msefft,msewidgets,msegraphics,msegraphutils,msedial, + msesplitter,msegui,msestat,msestatfile,msestrings,msestockobjects, + msemenus,mseact,msedataedits,msereal,mseedit; + +type + sigeditoptionty = (sieo_exp,sieo_expzero); + sigeditoptionsty = set of sigeditoptionty; + +const + defaultffttableeditoptions = [ceo_noinsert,ceo_nodelete]; + defaultkeywidth = 8; + defaultenvsplitteroptions = defaultsplitteroptions+[spo_hmove,spo_hprop]; + defaultsigkeyboardoptions = [sieo_exp]; + +type + + tsigslider = class(tslider,isigclient) + private + foutput: tdoubleoutputconn; + foutputpo: pdouble; + fcontroller: tsigcontroller; + fsigclientinfo: sigclientinfoty; + fontransformvalue: sigineventty; + fmin: real; + fmax: real; + foptions: sigeditoptionsty; + procedure setoutput(const avalue: tdoubleoutputconn); + procedure setcontroller(const avalue: tsigcontroller); + procedure setmin(const avalue: real); + procedure setmax(const avalue: real); + procedure setoptions(const avalue: sigeditoptionsty); + protected + fsigvalue: real; + procedure updatesigvalue; + procedure dochange; override; + procedure sighandler(const ainfo: psighandlerinfoty); + //isigclient + procedure initmodel; + procedure sigtick; virtual; + function getinputar: inputconnarty; + function getoutputar: outputconnarty; + function gethandler: sighandlerprocty; + function getzcount: integer; + procedure clear; + procedure modelchange; + function getsigcontroller: tsigcontroller; + function getsigclientinfopo: psigclientinfoty; + function getsigoptions: sigclientoptionsty; + procedure lock; + procedure unlock; + public + constructor create(aowner: tcomponent); override; + property output: tdoubleoutputconn read foutput write setoutput; + published + property controller: tsigcontroller read fcontroller write setcontroller; + property ontransformvalue: sigineventty read fontransformvalue + write fontransformvalue; + property min: real read fmin write setmin; + property max: real read fmax write setmax; + property options: sigeditoptionsty read foptions write setoptions default []; + end; + + tsigrealedit = class(trealedit,isigclient) + private + foutput: tdoubleoutputconn; + foutputpo: pdouble; + fcontroller: tsigcontroller; + fontransformvalue: sigineventty; + foptions: sigeditoptionsty; + fsigclientinfo: sigclientinfoty; +// foffset: real; + procedure setoutput(const avalue: tdoubleoutputconn); + procedure setcontroller(const avalue: tsigcontroller); + procedure setoptions(const avalue: sigeditoptionsty); +// procedure setoffset(const avalue: real); + protected + fsigvalue: real; + foutmin: real; + foutmax: real; + procedure setoutmin(const avalue: real); + procedure setoutmax(const avalue: real); + procedure setvaluemin(const avalue: realty); override; + procedure setvaluemax(const avalue: realty); override; + + procedure updatesigvalue; + procedure dochange; override; + procedure sighandler(const ainfo: psighandlerinfoty); + //isigclient + procedure initmodel; + procedure sigtick; virtual; + function getinputar: inputconnarty; + function getoutputar: outputconnarty; + function gethandler: sighandlerprocty; + function getzcount: integer; + procedure clear; + procedure modelchange; + function getsigcontroller: tsigcontroller; + function getsigclientinfopo: psigclientinfoty; + function getsigoptions: sigclientoptionsty; + procedure lock; + procedure unlock; + public + constructor create(aowner: tcomponent); override; + property output: tdoubleoutputconn read foutput write setoutput; + published + property controller: tsigcontroller read fcontroller write setcontroller; + property ontransformvalue: sigineventty read fontransformvalue + write fontransformvalue; +// property offset: real read foffset write setoffset; + property outmin: real read foutmin write setoutmin; + property outmax: real read foutmax write setoutmax; + property options: sigeditoptionsty read foptions write setoptions default []; + end; + + sigkeyinfoty = record + sigvalue: double; + eventvalue: double; + key: integer; + pressed: boolean; + timestamp: longword; + outpo: pdouble; + trigoutpo: pdouble; + end; + sigkeyinfoarty = array of sigkeyinfoty; + + tsigkeyboard = class(trealgraphdataedit,isigclient) + private + foutput: tdoubleoutconnarrayprop; + ftrigout: tdoubleoutconnarrayprop; + fcontroller: tsigcontroller; + fsigclientinfo: sigclientinfoty; + fontransformvalue: sigineventty; + fmin: real; + foptions: sigeditoptionsty; + fkeywidth: integer; + fkey: integer; + flastkey: integer; + fkeypressed: boolean; + foutputcount: integer; + foutputhigh: integer; + procedure setoutput(const avalue: tdoubleoutconnarrayprop); + procedure settrigout(const avalue: tdoubleoutconnarrayprop); + procedure setcontroller(const avalue: tsigcontroller); + procedure setmin(const avalue: real); + procedure setoptions(const avalue: sigeditoptionsty); + procedure setkeywidth(const avalue: integer); + procedure setoutputcount(const avalue: integer); + protected + fdummy: double; + fkeyinfos: sigkeyinfoarty; + procedure updatesigvalue(const akey: integer; const apressed: boolean); + procedure dochange; override; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure doexit; override; + + //isigclient + procedure initmodel; + procedure sigtick; virtual; + function getinputar: inputconnarty; + function getoutputar: outputconnarty; + function gethandler: sighandlerprocty; + function getzcount: integer; + procedure clear; + procedure modelchange; + function getsigcontroller: tsigcontroller; + function getsigclientinfopo: psigclientinfoty; + function getsigoptions: sigclientoptionsty; + procedure lock; + procedure unlock; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property output: tdoubleoutconnarrayprop read foutput write setoutput; + property trigout: tdoubleoutconnarrayprop read ftrigout write settrigout; + //1 -> key down, -1 key up, 0 none + published + property keywidth: integer read fkeywidth write setkeywidth default defaultkeywidth; + property controller: tsigcontroller read fcontroller write setcontroller; + property ontransformvalue: sigineventty read fontransformvalue + write fontransformvalue; + property min: real read fmin write setmin; +// property max: real read fmax write setmax; + property options: sigeditoptionsty read foptions write setoptions + default defaultsigkeyboardoptions; + property outputcount: integer read foutputcount write setoutputcount default 1; + end; + + optionwavetablety = (owt_rotate,owt_mirror,owt_nodc); + optionswavetablety = set of optionwavetablety; + + twavetableedit = class(torderedxychartedit) + private + fwave: tsigwavetable; + fsamplecount: integer; + foptionswave: optionswavetablety; + procedure setwave(const avalue: tsigwavetable); + procedure setsamplecount(const avalue: integer); + procedure setoptionswave(const avalue: optionswavetablety); + protected + procedure sample; + procedure dochange; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property samplecount: integer read fsamplecount + write setsamplecount default defaultsamplecount; + property wave: tsigwavetable read fwave write setwave; + property optionswave: optionswavetablety read foptionswave + write setoptionswave default []; + end; + + optionfuncteditty = (ofe_rotate,ofe_mirror); + optionsfuncteditty = set of optionfuncteditty; + + tfuncttableedit = class(torderedxychartedit) + private + ffunct: tsigfuncttable; + foptionsfunct: optionsfuncteditty; + procedure setfunct(const avalue: tsigfuncttable); + procedure setoptionsfunct(const avalue: optionsfuncteditty); + protected + procedure dochange; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property funct: tsigfuncttable read ffunct write setfunct; + property optionsfunct: optionsfuncteditty read foptionsfunct + write setoptionsfunct default []; + end; + + ffteditoptionty = (feo_exp); + ffteditoptionsty = set of ffteditoptionty; +const + defaultffteditoptions = [feo_exp]; + +type + tffttableedit = class(txserieschartedit) + private + fwave: tsigwavetable; + fsamplecount: integer; + ffft: tfft; + ffft_harmonicscount: integer; + ffft_options: ffteditoptionsty; + ffft_expmin: real; + ffft_max: real; + procedure setwave(const avalue: tsigwavetable); + procedure setsamplecount(const avalue: integer); + procedure setfft_harmonicscount(const avalue: integer); + procedure setfft_options(const avalue: ffteditoptionsty); + procedure setfft_expmin(const avalue: real); + procedure setfft_max(const avalue: real); + protected + procedure sample; + procedure dochange; override; + procedure doclear; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property samplecount: integer read fsamplecount + write setsamplecount default defaultsamplecount; + property fft_harmonicscount: integer read ffft_harmonicscount + write setfft_harmonicscount default defaultharmonicscount; + property fft_options: ffteditoptionsty read ffft_options + write setfft_options default defaultffteditoptions; + property fft_expmin: real read ffft_expmin write setfft_expmin; + property fft_max: real read ffft_max write setfft_max; + property wave: tsigwavetable read fwave write setwave; + property options default defaultffttableeditoptions; + end; + + tenvelopeedit = class; + + tenvelopechartedit = class(tcustomorderedxychartedit) + protected + fenvelope: tenvelopeedit; + procedure dochange; override; + procedure domarkerchange; override; + procedure drawcrosshaircursor(const canvas: tcanvas; + const center: pointty); override; + public + constructor create(aowner: tcomponent); override; + published + property traces; + property colorchart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; +// property statfile; +// property statvarname; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property ondataentered; + property onsetvalue; + property activetrace; + property optionsedit; + property snapdist; + property options; + property onchange; + end; + + tenvelopesplitter = class(tcustomsplitter) + public + constructor create(aowner: tcomponent); override; + published + property options default defaultenvsplitteroptions; + property shrinkpriority; +// property linkleft; +// property linktop; +// property linkright; +// property linkbottom; + + property grip; + property colorgrip; +// property statfile; +// property statvarname; + property onupdatelayout; + end; + + tenvelopeedit = class(tpublishedwidget,istatfile) + private + fstatvarname: msestring; + fstatfile: tstatfile; + fattack: tenvelopechartedit; + fdecay: tenvelopechartedit; + frelease: tenvelopechartedit; + fsplitter1: tenvelopesplitter; + fsplitter2: tenvelopesplitter; +// finnerframebefore: framety; + fenvelope: tsigenvelope; + fupdating: integer; + factivetrace: integer; + fmenustart: integer; + fstatpriority: integer; + procedure setenvelope(const avalue: tsigenvelope); + procedure setattack(const avalue: tenvelopechartedit); + procedure setdecay(const avalue: tenvelopechartedit); + procedure setrelease(const avalue: tenvelopechartedit); + procedure setsplitter1(const avalue: tenvelopesplitter); + procedure setsplitter2(const avalue: tenvelopesplitter); + procedure setstatfile(const avalue: tstatfile); + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; virtual; + procedure statread; virtual; + function getstatvarname: msestring; + function getstatpriority: integer; + procedure setactivetrace(avalue: integer); + protected + procedure updatelayout; + procedure clientrectchanged; override; + procedure dochange; + procedure updatevalues; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + procedure doafterpopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure beginupdate; + procedure endupdate; + published + property attack: tenvelopechartedit read fattack write setattack; + property decay: tenvelopechartedit read fdecay write setdecay; + property release: tenvelopechartedit read frelease write setrelease; + property splitter1: tenvelopesplitter read fsplitter1 write setsplitter1; + property splitter2: tenvelopesplitter read fsplitter2 write setsplitter2; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property envelope: tsigenvelope read fenvelope write setenvelope; + property optionswidget default defaultoptionswidgetmousewheel; + property activetrace: integer read factivetrace + write setactivetrace default 0; + end; +(* + tenvelopeedit1 = class(torderedxychartedit) + private + fenvelope: tsigenvelope; + procedure setenvelope(const avalue: tsigenvelope); + protected + procedure updatevalues; + procedure dochange; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property envelope: tsigenvelope read fenvelope write setenvelope; + end; +*) + tsigscope = class; + tscopesampler = class(tsigsampler) + private + fscope: tsigscope; + protected + procedure dobufferfull; override; + public + constructor create(const aowner: tsigscope); reintroduce; + end; + + tsigscope = class(tchart) + private + fsampler: tscopesampler; + procedure setsampler(const avalue: tscopesampler); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property sampler: tscopesampler read fsampler write setsampler; + end; + +implementation +uses + math,msekeyboard,msebits,msesysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsigcontroller1 = class(tsigcontroller); + tsigenvelope1 = class(tsigenvelope); + tdoubleoutputconn1 = class(tdoubleoutputconn); + +{ tsigrealedit } + +constructor tsigrealedit.create(aowner: tcomponent); +begin + foutput:= tdoubleoutputconn.create(self,isigclient(self),true); + inherited; + fvalue:= 0; + fvaluedefault:= 0; + fvaluemin:= -bigreal; + foutmax:= 1; +end; + +procedure tsigrealedit.setoutput(const avalue: tdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +procedure tsigrealedit.setcontroller(const avalue: tsigcontroller); +begin + setsigcontroller(getobjectlinker,isigclient(self),avalue,fcontroller); +end; + +procedure tsigrealedit.setoptions(const avalue: sigeditoptionsty); +begin + if options <> avalue then begin + foptions:= avalue; + updatesigvalue; + end; +end; + +procedure tsigrealedit.initmodel; +begin + foutputpo:= @foutput.value; +end; + +function tsigrealedit.getinputar: inputconnarty; +begin + result:= nil; +end; + +function tsigrealedit.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +function tsigrealedit.getzcount: integer; +begin + result:= 0; +end; + +procedure tsigrealedit.clear; +begin + //dummy +end; + +procedure tsigrealedit.modelchange; +begin + //dummy +end; + +function tsigrealedit.getsigcontroller: tsigcontroller; +begin + result:= fcontroller; +end; + +procedure tsigrealedit.updatesigvalue; +var + do1: double; +begin + if componentstate * [csdesigning,csloading] = [] then begin + if (sieo_exp in foptions) and (foutmin > 0) and (foutmax > 0) then begin + if (sieo_expzero in foptions) and (fvalue <= 0) then begin + do1:= 0; + end + else begin + do1:= foutmin*exp(fvalue*(ln(foutmax)-ln(foutmin))); + end; + end + else begin + do1:= fvalue*(foutmax-foutmin)+foutmin; + end; + if canevent(tmethod(fontransformvalue)) then begin + fontransformvalue(self,real(do1)); + end; + lock; + try + fsigvalue:= do1; + if fcontroller <> nil then begin + tsigcontroller1(fcontroller).execevent(isigclient(self)); + end; + finally + unlock; + end; + end; +end; + +procedure tsigrealedit.dochange; +begin + inherited; + updatesigvalue; +end; + +procedure tsigrealedit.sighandler(const ainfo: psighandlerinfoty); +begin + foutputpo^:= fsigvalue; +end; + +function tsigrealedit.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigrealedit.setoutmin(const avalue: real); +begin + foutmin:= avalue; + updatesigvalue; +end; + +procedure tsigrealedit.setoutmax(const avalue: real); +begin + foutmax:= avalue; + updatesigvalue; +end; + +function tsigrealedit.getsigclientinfopo: psigclientinfoty; +begin + result:= @fsigclientinfo; +end; + +procedure tsigrealedit.sigtick; +begin + //dummy +end; + +function tsigrealedit.getsigoptions: sigclientoptionsty; +begin + result:= []; +end; + +procedure tsigrealedit.lock; +begin + if fcontroller <> nil then begin + fcontroller.lock; + end; +end; + +procedure tsigrealedit.unlock; +begin + if fcontroller <> nil then begin + fcontroller.unlock; + end; +end; +{ +procedure tsigrealedit.setoffset(const avalue: real); +begin + foffset:= avalue; + updatesigvalue; +end; +} +procedure tsigrealedit.setvaluemin(const avalue: realty); +begin + inherited; + updatesigvalue; +end; + +procedure tsigrealedit.setvaluemax(const avalue: realty); +begin + inherited; + updatesigvalue; +end; + +{ tsigslider } + +constructor tsigslider.create(aowner: tcomponent); +begin + foutput:= tdoubleoutputconn.create(self,isigclient(self),true); + fmax:= 1; + inherited; +end; + +procedure tsigslider.setcontroller(const avalue: tsigcontroller); +begin + setsigcontroller(getobjectlinker,isigclient(self),avalue,fcontroller); +end; + +procedure tsigslider.initmodel; +begin + foutputpo:= @tdoubleoutputconn1(foutput).fvalue; +end; + +function tsigslider.getinputar: inputconnarty; +begin + result:= nil; +end; + +function tsigslider.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +function tsigslider.getzcount: integer; +begin + result:= 0; +end; + +procedure tsigslider.clear; +begin + //dummy +end; + +procedure tsigslider.setoutput(const avalue: tdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +procedure tsigslider.modelchange; +begin + //dummy +end; + +function tsigslider.getsigcontroller: tsigcontroller; +begin + result:= fcontroller; +end; + +procedure tsigslider.updatesigvalue; +var + do1: double; +begin + if componentstate * [csdesigning,csloading] = [] then begin + if (sieo_exp in foptions) and (fmin > 0) and (fmax > 0) then begin + if (sieo_expzero in foptions) and (fvalue <= 0) then begin + do1:= 0; + end + else begin + do1:= fmin*exp(fvalue*(ln(fmax)-ln(fmin))); + end; + end + else begin + do1:= fvalue*(fmax-fmin)+fmin; + end; + if canevent(tmethod(fontransformvalue)) then begin + fontransformvalue(self,real(do1)); + end; + lock; + try + fsigvalue:= do1; + if fcontroller <> nil then begin + tsigcontroller1(fcontroller).execevent(isigclient(self)); + end; + finally + unlock; + end; + end; +end; + +procedure tsigslider.dochange; +begin + inherited; + updatesigvalue; +end; + +procedure tsigslider.sighandler(const ainfo: psighandlerinfoty); +begin + foutputpo^:= fsigvalue; +end; + +function tsigslider.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigslider.setmin(const avalue: real); +begin + fmin:= avalue; + updatesigvalue; +end; + +procedure tsigslider.setmax(const avalue: real); +begin + fmax:= avalue; + updatesigvalue; +end; + +procedure tsigslider.setoptions(const avalue: sigeditoptionsty); +begin + if options <> avalue then begin + foptions:= avalue; + updatesigvalue; + end; +end; + +function tsigslider.getsigclientinfopo: psigclientinfoty; +begin + result:= @fsigclientinfo; +end; + +procedure tsigslider.sigtick; +begin + //dummy +end; + +function tsigslider.getsigoptions: sigclientoptionsty; +begin + result:= []; +end; + +procedure tsigslider.lock; +begin + if fcontroller <> nil then begin + fcontroller.lock; + end; +end; + +procedure tsigslider.unlock; +begin + if fcontroller <> nil then begin + fcontroller.unlock; + end; +end; + +{ tsigkeyboard } + +constructor tsigkeyboard.create(aowner: tcomponent); +begin + foptions:= defaultsigkeyboardoptions; + fkey:= -1; + ftrigout:= tdoubleoutconnarrayprop.create(self,'trigout',isigclient(self),true); +// ftrigout.name:= 'trigout'; + foutput:= tdoubleoutconnarrayprop.create(self,'output',isigclient(self),true); + fmin:= 0.001; +// fmax:= 1; + fkeywidth:= defaultkeywidth; + inherited; + outputcount:= 1; +end; + +destructor tsigkeyboard.destroy; +begin + ftrigout.free; + foutput.free; + inherited; +end; + +procedure tsigkeyboard.setcontroller(const avalue: tsigcontroller); +begin + setsigcontroller(getobjectlinker,isigclient(self),avalue,fcontroller); +end; + +procedure tsigkeyboard.initmodel; +var + int1: integer; + ti1: longword; +begin + ti1:= timestamp; + for int1:= 0 to foutputhigh do begin + with fkeyinfos[int1] do begin + timestamp:= ti1; + eventvalue:= 0; + sigvalue:= fmin; + key:= -1; + if int1 < output.count then begin + outpo:= @tdoubleoutputconn1(output[int1]).fvalue; + end + else begin + outpo:= @fdummy; + end; + if int1 < trigout.count then begin + trigoutpo:= @tdoubleoutputconn1(trigout[int1]).fvalue; + end + else begin + trigoutpo:= @fdummy; + end; + end; + end; +end; + +function tsigkeyboard.getinputar: inputconnarty; +begin + result:= nil; +end; + +function tsigkeyboard.getoutputar: outputconnarty; +var + int1,int2: integer; +begin + setlength(result,foutput.count+ftrigout.count); + int2:= foutput.count; + for int1:= 0 to int2-1 do begin + result[int1]:= foutput[int1]; + end; + for int1:= 0 to ftrigout.count - 1 do begin + result[int1+int2]:= ftrigout[int1]; + end; +end; + +function tsigkeyboard.getzcount: integer; +begin + result:= 0; +end; + +procedure tsigkeyboard.clear; +begin + //dummy +end; + +procedure tsigkeyboard.setoutput(const avalue: tdoubleoutconnarrayprop); +begin + foutput.assign(avalue); +end; + +procedure tsigkeyboard.settrigout(const avalue: tdoubleoutconnarrayprop); +begin + ftrigout.assign(avalue); +end; + +procedure tsigkeyboard.modelchange; +begin + //dummy +end; + +function tsigkeyboard.getsigcontroller: tsigcontroller; +begin + result:= fcontroller; +end; + +procedure tsigkeyboard.updatesigvalue(const akey: integer; + const apressed: boolean); +var + do1,do2: double; + int1,int2: integer; + ind1,oldest: integer; + ti1,ti2: longword; +begin + if foutputcount > 0 then begin + ind1:= -1; + ti1:= timestamp; + ti2:= 0; + oldest:= 0; + lock; + try + for int1:= 0 to foutputhigh do begin + with fkeyinfos[int1] do begin + int2:= ti1 - timestamp; + if int2 > ti2 then begin + ti2:= int2; + oldest:= int1; + end; + if key = akey then begin + ind1:= int1; + end; + end; + end; + if ind1 < 0 then begin + ind1:= oldest; + end; + with fkeyinfos[ind1] do begin + key:= akey; + timestamp:= ti1; + pressed:= apressed; + if not apressed then begin + do1:= sigvalue; + do2:= -1; + end + else begin + do2:= 1; + if (sieo_exp in foptions) then begin + do1:= intpower(2.0,key div 12) * chromaticscale[key mod 12] * fmin; + end + else begin + do1:= fkey/12.0 + fmin; + end; + end; + if canevent(tmethod(fontransformvalue)) then begin + fontransformvalue(self,real(do1)); + end; + sigvalue:= do1; + eventvalue:= do2; + end; + if fcontroller <> nil then begin + tsigcontroller1(fcontroller).execevent(isigclient(self)); + end; + finally + unlock; //todo: single event for current output only + end; + end; +end; + +procedure tsigkeyboard.dochange; +begin + inherited; + updatesigvalue(-1,false); +end; + +procedure tsigkeyboard.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; +begin + if foutputcount > 0 then begin +// ainfo^.dest^:= fkeyinfos[0].sigvalue; + for int1:= 0 to foutputhigh do begin + with fkeyinfos[int1] do begin + outpo^:= sigvalue; + trigoutpo^:= eventvalue; + eventvalue:= 0; + end; + end; + end; +end; + +function tsigkeyboard.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigkeyboard.setmin(const avalue: real); +var + int1: integer; +begin + lock; + fmin:= avalue; + for int1:= 0 to foutputhigh do begin + with fkeyinfos[int1] do begin + if sigvalue < fmin then begin + sigvalue:= fmin; + end; + end; + end; + updatesigvalue(-1,false); + unlock; +end; +{ +procedure tsigkeyboard.setmax(const avalue: real); +begin + fmax:= avalue; + updatesigvalue; +end; +} +procedure tsigkeyboard.setoptions(const avalue: sigeditoptionsty); +begin + if options <> avalue then begin + lock; + foptions:= avalue; + updatesigvalue(-1,false); + unlock; + end; +end; + +function tsigkeyboard.getsigclientinfopo: psigclientinfoty; +begin + result:= @fsigclientinfo; +end; + +procedure tsigkeyboard.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; const arect: rectty); +var +// pt1: pointty; + ar1: segmentarty; + int1,int2,int3,int4: integer; + rect1: rectty; +begin + setlength(ar1,arect.cx div fkeywidth + 1); + int2:= arect.y + arect.cy; + int3:= arect.x; + for int1:= 0 to high(ar1) do begin + with(ar1[int1]) do begin + a.x:= int3; + a.y:= arect.y; + b.x:= int3; + b.y:= int2; + end; + inc(int3,fkeywidth); + end; + canvas.drawlinesegments(ar1,colorglyph); + int4:= (fkeywidth*2+1) div 3 + 1; //width of black keys + rect1.x:= arect.x + (fkeywidth - int4 div 2); + rect1.y:= arect.y; + rect1.cx:= int4+1; + rect1.cy:= arect.cy div 2; + for int1:= 0 to high(ar1) do begin + int3:= int1 mod 7; + if (int3 <> 2) and (int3 <> 6) then begin + canvas.fillrect(rect1,colorglyph); + end; + inc(rect1.x,fkeywidth); + end; +end; + +procedure tsigkeyboard.setkeywidth(const avalue: integer); +begin + if avalue <> fkeywidth then begin + fkeywidth:= avalue; + if fkeywidth < 4 then begin + fkeywidth:= 4; + end; + invalidate; + end; +end; + +const + whitekeys: array[0..6] of integer = (0,2,4,5,7,9,11); + blackkeys: array[0..6] of integer = (-1,1,3,-1,6,8,10); + +procedure tsigkeyboard.clientmouseevent(var info: mouseeventinfoty); +var + keybefore: integer; + keynumber,key: integer; + rect1: rectty; +begin + keybefore:= fkey; + if not (csdesigning in componentstate) and + (info.eventkind in mouseposevents) then begin + if (ss_left in info.shiftstate) or fkeypressed then begin + rect1:= innerclientrect; + if pointinrect(info.pos,rect1) then begin + if info.pos.y >= rect1.y + rect1.cy div 2 then begin //white keys + keynumber:= (info.pos.x - rect1.x) div fkeywidth; + key:= whitekeys[keynumber mod 7]; + end + else begin + keynumber:= (info.pos.x - rect1.x + fkeywidth div 2) div fkeywidth; + key:= blackkeys[keynumber mod 7]; + if key < 0 then begin + keynumber:= (info.pos.x - rect1.x) div fkeywidth; + key:= whitekeys[keynumber mod 7]; + end; + end; + fkey:= (keynumber div 7)*12+key; + flastkey:= fkey; + end + else begin + if not fkeypressed then begin + fkey:= -1; + end; + end; + end + else begin + if not fkeypressed then begin + fkey:= -1; + end; + end; + end + else begin + if not fkeypressed and + (info.eventkind in [ek_mouseleave,ek_clientmouseleave]) then begin + fkey:= -1; + end; + end; + if keybefore <> fkey then begin + include(info.eventstate,es_processed); + if fkey = -1 then begin + updatesigvalue(keybefore,false); + end + else begin + if keybefore >= 0 then begin + updatesigvalue(keybefore,false); + end; + updatesigvalue(fkey,true); + end; + end + else begin + inherited; + end; +end; + +procedure tsigkeyboard.dokeydown(var info: keyeventinfoty); +begin + if (info.key = key_space) and not (ss_repeat in info.shiftstate) and + (flastkey <> fkey) then begin + fkey:= flastkey; + include(info.eventstate,es_processed); + fkeypressed:= true; + updatesigvalue(fkey,true); + end + else begin + inherited; + end; +end; + +procedure tsigkeyboard.dokeyup(var info: keyeventinfoty); +begin + if (info.key = key_space) and + not (ss_repeat in info.shiftstate) and (fkey >= 0) then begin + include(info.eventstate,es_processed); + updatesigvalue(fkey,false); + fkey:= -1; + fkeypressed:= false; + end + else begin + inherited; + end; +end; + +procedure tsigkeyboard.doexit; +begin + fkeypressed:= false; + inherited; +end; + +procedure tsigkeyboard.sigtick; +begin + //dummy +end; + +function tsigkeyboard.getsigoptions: sigclientoptionsty; +begin + result:= []; +end; + +procedure tsigkeyboard.setoutputcount(const avalue: integer); +begin + foutputcount:= avalue; + foutputhigh:= avalue-1; + output.count:= avalue; + trigout.count:= avalue; + setlength(fkeyinfos,avalue); +end; + +procedure tsigkeyboard.lock; +begin + if fcontroller <> nil then begin + fcontroller.lock; + end; +end; + +procedure tsigkeyboard.unlock; +begin + if fcontroller <> nil then begin + fcontroller.unlock; + end; +end; + +{ twavetableedit } + +constructor twavetableedit.create(aowner: tcomponent); +begin + fsamplecount:= defaultsamplecount; + inherited; + fwave:= tsigwavetable.create(self); + fwave.name:= 'wave'; + fwave.setsubcomponent(true); +end; + +destructor twavetableedit.destroy; +begin + fwave.free; + inherited; +end; + +procedure twavetableedit.setwave(const avalue: tsigwavetable); +begin + fwave.assign(avalue); +end; + +procedure twavetableedit.sample; + + function intpol(const ax: double): double; + var + int1,int2: integer; + rea1: real; + begin + int2:= -1; + for int1:= 0 to high(fvalue) do begin + if fvalue[int1].re >= ax then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + result:= fvalue[high(fvalue)].im; + end + else begin + result:= fvalue[int2].im; + if int2 > 0 then begin + rea1:= fvalue[int2].re-fvalue[int2-1].re; + if rea1 = 0 then begin + rea1:= 0.5; + end + else begin + rea1:= (fvalue[int2].re-ax)/rea1; + end; + result:= result + (fvalue[int2-1].im - result) * rea1; + end; + end; + end; //intpol + +var + ar1: doublearty; + int1,int2,int3: integer; + sampco,start: integer; + do1: double; +begin + if foptionswave * [owt_rotate,owt_mirror] = [] then begin + sampco:= fsamplecount; + start:= 0; + end + else begin + sampco:= (fsamplecount+1) div 2; + start:= fsamplecount div 2; + end; + setlength(ar1,fsamplecount); + if (sampco > 0) and (high(fvalue) >= 0) then begin + do1:= 1/sampco; + for int1:= 0 to sampco - 1 do begin + ar1[int1+start]:= intpol(do1*int1); + end; + end; + int2:= fsamplecount and 1; //odd + int3:= start+start+int2-1; + if owt_rotate in foptionswave then begin + for int1:= start+int2 to int3 do begin + ar1[int3-int1]:= - ar1[int1]; + end; + end + else begin + if owt_mirror in foptionswave then begin + for int1:= start+int2 to int3 do begin + ar1[int3-int1]:= ar1[int1]; + end; + end; + end; + if (owt_nodc in foptionswave) and (ar1 <> nil) then begin + do1:= 0; + for int1:= 0 to high(ar1) do begin + do1:= do1 + ar1[int1]; + end; + do1:= do1 / length(ar1); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= ar1[int1] - do1;; + end; + end; + fwave.table:= ar1; +end; + +procedure twavetableedit.dochange; +begin + sample; + inherited; +end; + +procedure twavetableedit.setsamplecount(const avalue: integer); +begin + if avalue <> fsamplecount then begin + fsamplecount:= avalue; + if not (csloading in componentstate) then begin + dochange; + end; + end; +end; + +procedure twavetableedit.setoptionswave(const avalue: optionswavetablety); +const + mask: optionswavetablety = [owt_rotate,owt_mirror]; +begin + if foptionswave <> avalue then begin + foptionswave:= optionswavetablety(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptionswave), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + if not (csloading in componentstate) then begin + dochange; + end; + end; +end; + +{ tfuncttableedit } + +constructor tfuncttableedit.create(aowner: tcomponent); +begin + inherited; + ffunct:= tsigfuncttable.create(self); + ffunct.name:= 'funct'; + ffunct.setsubcomponent(true); +end; + +destructor tfuncttableedit.destroy; +begin + ffunct.free; + inherited; +end; + +procedure tfuncttableedit.setfunct(const avalue: tsigfuncttable); +begin + ffunct.assign(avalue); +end; + +procedure tfuncttableedit.dochange; +var + ar1: complexarty; + int1,int2: integer; +begin + if ofe_rotate in foptionsfunct then begin + int2:= length(fvalue); + setlength(ar1,int2*2); + for int1:= 0 to high(fvalue) do begin + ar1[int2+int1]:= fvalue[int1]; + with ar1[int2-int1-1] do begin + re:= -fvalue[int1].re; + im:= -fvalue[int1].im; + end; + end; + ffunct.table:= ar1; + end + else begin + if ofe_mirror in foptionsfunct then begin + int2:= length(fvalue); + setlength(ar1,int2*2); + for int1:= 0 to high(fvalue) do begin + ar1[int2+int1]:= fvalue[int1]; + with ar1[int2-int1-1] do begin + re:= -fvalue[int1].re; + im:= fvalue[int1].im; + end; + end; + ffunct.table:= ar1; + end + else begin + ffunct.table:= fvalue; + end; + end; + inherited; +end; + +procedure tfuncttableedit.setoptionsfunct(const avalue: optionsfuncteditty); +const + mask: optionsfuncteditty = [ofe_rotate,ofe_mirror]; +begin + if foptionsfunct <> avalue then begin + foptionsfunct:= optionsfuncteditty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptionsfunct), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + if not (csloading in componentstate) then begin + dochange; + end; + end; +end; + +{ tffttableedit } + +constructor tffttableedit.create(aowner: tcomponent); +begin + fsamplecount:= defaultsamplecount; + ffft_options:= defaultffteditoptions; + ffft_expmin:= 0.001; //-60dB + ffft_max:= 1; + inherited; + ffft:= tfft.create(nil); + fwave:= tsigwavetable.create(self); + fwave.name:= 'wave'; + fwave.setsubcomponent(true); + fft_harmonicscount:= defaultharmonicscount; + options:= defaultffttableeditoptions; +end; + +destructor tffttableedit.destroy; +begin + fwave.free; + ffft.free; + inherited; +end; + +procedure tffttableedit.setwave(const avalue: tsigwavetable); +begin + fwave.assign(avalue); +end; + +procedure tffttableedit.sample; +const + scale1 = 1/2; +var + ar1: complexarty; + int1,int2: integer; + rea1,rea2,rea3: real; +begin + setlength(ar1,fsamplecount div 2 + 1); + int2:= high(fvalue); + if int2 >= high(ar1) then begin + int2:= high(ar1)-1; + end; + rea3:= ffft_max*scale1; + if (feo_exp in ffft_options) and (ffft_expmin > 0) and (ffft_max > 0) then begin + rea1:= ln(ffft_max) - ln(ffft_expmin); + for int1:= 0 to int2 do begin + rea2:= fvalue[int1]; + if rea2 > 0 then begin + ar1[int1+1].im:= exp((rea2-1)*rea1)*rea3; + end; + end; + end + else begin + for int1:= 1 to int2 do begin + ar1[int1].im:= fvalue[int1-1]*rea3; + end; + end; + ffft.inpcomplex:= ar1; + fwave.table:= doublearty(ffft.outreal); +end; + +procedure tffttableedit.dochange; +begin + sample; + inherited; +end; + +procedure tffttableedit.setsamplecount(const avalue: integer); +begin + if avalue <> fsamplecount then begin + fsamplecount:= avalue; + sample; + end; +end; + +procedure tffttableedit.setfft_harmonicscount(const avalue: integer); +begin + ffft_harmonicscount:= avalue; + setlength(fvalue,avalue); + change; +end; + +procedure tffttableedit.doclear; +begin + fvalue:= nil; + setlength(fvalue,ffft_harmonicscount); +end; + +procedure tffttableedit.setfft_options(const avalue: ffteditoptionsty); +begin + if ffft_options <> avalue then begin + ffft_options:= avalue; + change; + end; +end; + +procedure tffttableedit.setfft_expmin(const avalue: real); +begin + if avalue <> ffft_expmin then begin + ffft_expmin:= avalue; + change; + end; +end; + +procedure tffttableedit.setfft_max(const avalue: real); +begin + if avalue <> ffft_max then begin + ffft_max:= avalue; + change; + end; +end; + +{ tenvelopeedit1 } +(* +constructor tenvelopeedit1.create(aowner: tcomponent); +begin + inherited; + xdials.count:= 1; + with xdials[0] do begin + markers.count:= 2; + with markers[0] do begin //loop start + value:= 0; + color:= cl_red; + options:= [dmo_ordered,dmo_savevalue]; + end; + with markers[1] do begin //decay + value:= 1; + color:= cl_green; + options:= [dmo_ordered,dmo_savevalue]; + end; + end; + fenvelope:= tsigenvelope.create(self); + fenvelope.name:= 'envelope'; + fenvelope.setsubcomponent(true); +end; + +destructor tenvelopeedit1.destroy; +begin + fenvelope.free; + inherited; +end; + +procedure tenvelopeedit1.setenvelope(const avalue: tsigenvelope); +begin + fenvelope.assign(avalue); +end; + +procedure tenvelopeedit1.dochange; +begin + inherited; + updatevalues; +end; + +procedure tenvelopeedit1.updatevalues; +begin + with fenvelope do begin + beginupdate; + values:= activetraceitem.xydata; + if xdials.count > 0 then begin + with xdials[0] do begin + if markers.count > 0 then begin + loopstart:= markers[0].value; + end + else begin + loopstart:= 0; + end; + if markers.count > 1 then begin + decaystart:= markers[1].value; + end + else begin + decaystart:= 1; + end + end; + end; + endupdate; + end; +end; +*) +{ tenvelopeedit } + +constructor tenvelopeedit.create(aowner: tcomponent); +const + splitterwidth = 4; +var + int1: integer; +begin + include(fwidgetstate1,ws1_noframewidgetshift); + inherited; + optionswidget:= defaultoptionswidgetmousewheel; + fenvelope:= tsigenvelope.create(self); + fenvelope.setsubcomponent(true); + fenvelope.name:= 'envelope'; + fattack:= tenvelopechartedit.create(self,self,false); + fdecay:= tenvelopechartedit.create(self,self,false); + frelease:= tenvelopechartedit.create(self,self,false); + fsplitter1:= tenvelopesplitter.create(self,self,false); + fsplitter2:= tenvelopesplitter.create(self,self,false); + width:= 3*30+2*splitterwidth; + int1:= (fwidgetrect.cx - splitterwidth*2) div 3; + fattack.bounds_cx:= int1; + fdecay.bounds_cx:= int1; + frelease.bounds_cx:= int1; + fsplitter1.bounds_cx:= splitterwidth; + fsplitter2.bounds_cx:= splitterwidth; + fsplitter1.bounds_x:= fattack.bounds_x + fattack.bounds_cx; + fsplitter2.bounds_x:= fsplitter1.bounds_x + fsplitter1.bounds_cx + + fdecay.bounds_cx; + updatelayout; + fsplitter1.linkleft:= fattack; + fsplitter1.linkright:= fdecay; + fsplitter2.linkleft:= fdecay; + fsplitter2.linkright:= frelease; + + with fdecay do begin + xdials.count:= 1; + xdials[0].markers.count:= 1; + with xdials[0].markers[0] do begin + value:= 10; + color:= cl_red; + options:= [dmo_savevalue]; + end; + end; + fattack.xrange:= 0.1; + fdecay.xrange:= 10; + frelease.xrange:= 1; +end; + +destructor tenvelopeedit.destroy; +begin + fattack.free; + fdecay.free; + frelease.free; + fenvelope.free; + inherited; +end; + +procedure tenvelopeedit.setattack(const avalue: tenvelopechartedit); +begin + fattack.assign(avalue); +end; + +procedure tenvelopeedit.setdecay(const avalue: tenvelopechartedit); +begin + fdecay.assign(avalue); +end; + +procedure tenvelopeedit.setrelease(const avalue: tenvelopechartedit); +begin + frelease.assign(avalue); +end; + +procedure tenvelopeedit.setsplitter1(const avalue: tenvelopesplitter); +begin + fsplitter1.assign(avalue); +end; + +procedure tenvelopeedit.setsplitter2(const avalue: tenvelopesplitter); +begin + fsplitter2.assign(avalue); +end; + +procedure tenvelopeedit.updatelayout; +var + rect1: rectty; + rect2: rectty; +// fr1,fr2: framety; +begin + rect1:= innerwidgetrect; + with rect1 do begin + rect2.pos:= pos; + rect2.cy:= cy; + rect2.cx:= fattack.bounds_cx - x + fattack.bounds_x; + fattack.widgetrect:= rect2; + rect2.x:= fsplitter1.bounds_x; + rect2.cx:= fsplitter1.bounds_cx; + fsplitter1.widgetrect:= rect2; + rect2.x:= fsplitter2.bounds_x; + rect2.cx:= fsplitter2.bounds_cx; + fsplitter2.widgetrect:= rect2; + rect2.x:= fsplitter1.bounds_x+fsplitter1.bounds_cx; + rect2.cx:= fdecay.bounds_cx; + fdecay.widgetrect:= rect2; + rect2.x:= fsplitter2.bounds_x+fsplitter2.bounds_cx; + rect2.cx:= cx - rect2.x; + frelease.widgetrect:= rect2; + end; +end; + +procedure tenvelopeedit.clientrectchanged; +begin + inherited; + updatelayout; +end; + +procedure tenvelopeedit.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tenvelopeedit.dostatread(const reader: tstatreader); +var + mstr1: msestring; +begin + mstr1:= reader.varname(istatfile(self)); + beginupdate; + try + if reader.findsection(mstr1+'.0') then begin + fattack.dostatread(reader); + end; + if reader.findsection(mstr1+'.1') then begin + fsplitter1.dostatread(reader); + end; + if reader.findsection(mstr1+'.2') then begin + fdecay.dostatread(reader); + end; + if reader.findsection(mstr1+'.3') then begin + fsplitter2.dostatread(reader); + end; + if reader.findsection(mstr1+'.4') then begin + frelease.dostatread(reader); + end; + finally + endupdate; + end; +end; + +procedure tenvelopeedit.dostatwrite(const writer: tstatwriter); +var + mstr1: msestring; +begin + mstr1:= writer.varname(istatfile(self)); + writer.writesection(mstr1+'.0'); + fattack.dostatwrite(writer); + writer.writesection(mstr1+'.1'); + fsplitter1.dostatwrite(writer); + writer.writesection(mstr1+'.2'); + fdecay.dostatwrite(writer); + writer.writesection(mstr1+'.3'); + fsplitter2.dostatwrite(writer); + writer.writesection(mstr1+'.4'); + frelease.dostatwrite(writer); +end; + +procedure tenvelopeedit.statreading; +begin + fattack.statreading; + fdecay.statreading; + frelease.statreading; + fsplitter1.statreading; + fsplitter2.statreading; +end; + +procedure tenvelopeedit.statread; +begin + fattack.statread; + fdecay.statread; + frelease.statread; + fsplitter1.statread; + fsplitter2.statread; +end; + +function tenvelopeedit.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tenvelopeedit.updatevalues; + + procedure setva(const aindex: integer); + begin + with fenvelope do begin + attack_values[aindex]:= fattack.traces[aindex].xydata; + with fdecay do begin + decay_values[aindex]:= traces[aindex].xydata; + if xdials.count > 0 then begin + with xdials[0] do begin + if markers.count > 0 then begin + if markers[0].value < start+range then begin + loopstart[aindex]:= markers[0].value; + end + else begin + loopstart[aindex]:= -1; + end; + end + else begin + loopstart[aindex]:= -1; + end; + end; + end; + end; + release_values[aindex]:= frelease.traces[aindex].xydata; + end; + end; //setva() + +begin + fenvelope.beginupdate; + setva(0); + setva(1); + fenvelope.endupdate; +end; + +procedure tenvelopeedit.dochange; +begin + if fupdating >= 0 then begin + updatevalues; + end; +end; + +procedure tenvelopeedit.setenvelope(const avalue: tsigenvelope); +begin + fenvelope.assign(avalue); +end; + +procedure tenvelopeedit.beginupdate; +begin + inc(fupdating); +end; + +procedure tenvelopeedit.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + dochange; + end; +end; + +procedure tenvelopeedit.setactivetrace(avalue: integer); +begin + if avalue < 0 then begin + avalue:= 0; + end; + if avalue > 1 then begin + avalue:= 1; + end; + factivetrace:= avalue; + fattack.activetrace:= avalue; + fdecay.activetrace:= avalue; + frelease.activetrace:= avalue; +end; + +procedure tenvelopeedit.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +var + st1: actionstatesarty; +begin + inherited; + setlength(st1,2); + st1[factivetrace]:= [as_checked]; + fmenustart:= tpopupmenu.additems(amenu,self,mouseinfo,['Main Trace','Secondary Trace'], + [[mao_radiobutton],[mao_radiobutton]],st1,[]); +end; + +procedure tenvelopeedit.doafterpopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + inherited; + if amenu.menu.submenu[fmenustart].checked then begin + activetrace:= 0; + end + else begin + activetrace:= 1; + end; +end; + +function tenvelopeedit.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tenvelopechartedit } + +constructor tenvelopechartedit.create(aowner: tcomponent); +begin + fenvelope:= tenvelopeedit(aowner); + if csdesigning in aowner.componentstate then begin + setdesigning(true); + end; + inherited create(nil); + setsubcomponent(true); + traces.count:= 2; + traces.options:= traces.options + [cto_stockglyphs]; +// traces.image_list:= stockobjects.glyphs; + with traces[0] do begin + imagenr:= ord(stg_circlesmall); + end; + with traces[1]do begin + imagenr:= ord(stg_squaresmall); + color:= cl_red; + end; + with frame do begin + optionsscroll:= optionsscroll + + [oscr_zoomheight,oscr_zoomwidth,oscr_drag,oscr_mousewheel]; + zoomwidthstep:= 1.5; + end; +end; + +procedure tenvelopechartedit.dochange; +begin + inherited; + fenvelope.dochange; +end; + +procedure tenvelopechartedit.domarkerchange; +begin + inherited; + fenvelope.dochange; +end; + +procedure tenvelopechartedit.drawcrosshaircursor(const canvas: tcanvas; + const center: pointty); + procedure drawyline(const dest: tenvelopechartedit; + const sourceoptions,destoptions: sigenveloperangeoptionsty); + var + co1: complexty; + pt1: pointty; + begin + co1:= tracecoordxy(0,center); + if (sero_exp in sourceoptions) xor (sero_exp in destoptions) then begin + if (sero_exp in sourceoptions) then begin + tsigenvelope1(fenvelope.fenvelope).exptolin(double(co1.im)); + end + else begin + tsigenvelope1(fenvelope.fenvelope).lintoexp(double(co1.im)); + end; + end; + pt1:= dest.chartcoordxy(0,co1); + canvas.drawvect(subpoint( + makepoint(dest.paintparentpos.x-paintparentpos.x,pt1.y),clientpos), + gd_right,dest.paintsize.cx); + end; //drawyline + +begin + inherited; + canvas.save; + canvas.clipregion:= 0; + with fenvelope,fenvelope do begin + if self = fattack then begin + drawyline(fdecay,attack_options,decay_options); + drawyline(frelease,attack_options,release_options); + end + else begin + if self = fdecay then begin + drawyline(fattack,decay_options,attack_options); + drawyline(frelease,decay_options,release_options); + end + else begin //release + drawyline(fattack,release_options,attack_options); + drawyline(fdecay,release_options,decay_options); + end; + end; + end; + canvas.restore; +end; + +{ tenvelopesplitter } + +constructor tenvelopesplitter.create(aowner: tcomponent); +begin + if csdesigning in aowner.componentstate then begin + setdesigning(true); + end; + inherited; //owner needed because of csreading and csloading +// inherited create(nil); + options:= defaultenvsplitteroptions; + setsubcomponent(true); +end; + +{ tscopesampler } + +constructor tscopesampler.create(const aowner: tsigscope); +begin + fscope:= aowner; + inherited create(aowner); + setsubcomponent(true); + name:= 'sampler'; +end; + +procedure tscopesampler.dobufferfull; +var + buf1: samplerbufferty; + int1: integer; +begin + inherited; + buf1:= copy(fsigbuffer); + lockapplication; + try + with fscope.traces do begin + for int1:= 0 to high(buf1) do begin + if int1 >= count then begin + break; + end; + items[int1].ydata:= realarty(buf1[int1]); + end; + end; + finally + unlockapplication; + end; +end; + +{ tsigscope } + +constructor tsigscope.create(aowner: tcomponent); +begin + fsampler:= tscopesampler.create(self); + inherited; +end; + +destructor tsigscope.destroy; +begin + fsampler.free; + inherited; +end; + +procedure tsigscope.setsampler(const avalue: tscopesampler); +begin + fsampler.assign(avalue); +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesigmidi.pas b/mseide-msegui/lib/common/math/msesigmidi.pas new file mode 100644 index 0000000..fe1af9d --- /dev/null +++ b/mseide-msegui/lib/common/math/msesigmidi.pas @@ -0,0 +1,1213 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesigmidi; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msesignal,classes,mclasses,msemidi,msetypes,mseclasses,msedatamodules, + msearrayprops,msehash,msesercomm; +const + defaultmidiattackvalueoptions = [vso_exp,vso_null]; + defaultmidiattackvaluemin = 0.1; //20 dB + defaultmidireleasevalueoptions = []; + defaultmidireleasevaluemin = 0; + defaultmidipressurevalueoptions = []; + defaultmidipressurevaluemin = 0; + defaultmidivaluemax = 1; + paramscale = 1/127; //0..1 + defaultconnectorname = 'midiconn'; + channelmaxcount = 16; + channelmask = channelmaxcount - 1; + +type + tsigmidisource = class; + + tsigmidiconnector = class(tsigeventconnector) + private + ffrequout: tdoubleoutputconn; +// ffrequoutpo: pdouble; + ftrigout: tdoubleoutputconn; + // ftrigoutpo: pdouble; + ffrequ_min: double; + fattack: doublescaleinfoty; + fpressure: doublescaleinfoty; + frelease: doublescaleinfoty; + fsource: tsigmidisource; + fchannel: integer; + fattackout: tdoubleoutputconn; + fpressureout: tdoubleoutputconn; + freleaseout: tdoubleoutputconn; + fattackoutlin: tdoubleoutputconn; + ffrequoutlin: tdoubleoutputconn; + fpressureoutlin: tdoubleoutputconn; + freleaseoutlin: tdoubleoutputconn; + procedure setfrequout(const avalue: tdoubleoutputconn); + procedure settrigout(const avalue: tdoubleoutputconn); + procedure setsource(const avalue: tsigmidisource); + procedure setchannel(const avalue: integer); + procedure setattack_min(const avalue: double); + procedure setattack_max(const avalue: double); + procedure setattack_options(const avalue: valuescaleoptionsty); + procedure setpressure_min(const avalue: double); + procedure setpressure_max(const avalue: double); + procedure setpressure_options(const avalue: valuescaleoptionsty); + procedure setrelease_min(const avalue: double); + procedure setrelease_max(const avalue: double); + procedure setrelease_options(const avalue: valuescaleoptionsty); + procedure setattackout(const avalue: tdoubleoutputconn); + procedure setpressureout(const avalue: tdoubleoutputconn); + procedure setreleaseout(const avalue: tdoubleoutputconn); + procedure setattackoutlin(const avalue: tdoubleoutputconn); + procedure setfrequoutlin(const avalue: tdoubleoutputconn); + procedure setpressureoutlin(const avalue: tdoubleoutputconn); + procedure setreleaseoutlin(const avalue: tdoubleoutputconn); + protected + ftrigvalue: double; +// procedure initmodel; override; + procedure sighandler(const ainfo: psighandlerinfoty); + function getoutputar: outputconnarty; override; + function gethandler: sighandlerprocty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure midievent(const ainfo: midieventinfoty); + property frequout: tdoubleoutputconn read ffrequout write setfrequout; + property frequoutlin: tdoubleoutputconn read ffrequoutlin + write setfrequoutlin; + property trigout: tdoubleoutputconn read ftrigout write settrigout; + property attackout: tdoubleoutputconn read fattackout write setattackout; + property attackoutlin: tdoubleoutputconn read fattackoutlin + write setattackoutlin; + property pressureout: tdoubleoutputconn read fpressureout + write setpressureout; + property pressureoutlin: tdoubleoutputconn read fpressureoutlin + write setpressureoutlin; + property releaseout: tdoubleoutputconn read freleaseout write setreleaseout; + property releaseoutlin: tdoubleoutputconn read freleaseoutlin + write setreleaseoutlin; + published + property frequ_min: double read ffrequ_min write ffrequ_min; + property attack_min: double read fattack.min write setattack_min; + property attack_max: double read fattack.max write setattack_max; + property attack_options: valuescaleoptionsty read fattack.options + write setattack_options default defaultmidiattackvalueoptions; + + property pressure_min: double read fpressure.min write setpressure_min; + property pressure_max: double read fpressure.max write setpressure_max; + property pressure_options: valuescaleoptionsty read fpressure.options + write setpressure_options default defaultmidipressurevalueoptions; + + property release_min: double read frelease.min write setrelease_min; + property release_max: double read frelease.max write setrelease_max; + property release_options: valuescaleoptionsty read frelease.options + write setrelease_options default defaultmidireleasevalueoptions; + + property source: tsigmidisource read fsource write setsource; + property channel: integer read fchannel write setchannel default 0; + end; + sigmidiconnectorarty = array of tsigmidiconnector; + + channelinfoty = record + + end; + + sigmidisourcestatety = (smss_patchvalid); + sigmidisourcestatesty = set of sigmidisourcestatety; + + pconnectioninfoty = ^connectioninfoty; + connectioninfoty = record + dest: tsigmidiconnector; + prev: pconnectioninfoty; + next: pconnectioninfoty; + key: byte; + active: boolean; + end; + connectioninfoarty = array of connectioninfoty; + + sigchannelinfoty = record + connections: connectioninfoarty; + first,last: pconnectioninfoty; + end; + + sigchannelinfoarty = array of sigchannelinfoty; + + patchinfoty = record + channel: integer; + track: integer; + notemin: integer; + notemax: integer; + midichannel: midichannelty; + end; + ppatchinfoty = ^patchinfoty; + + patchty = record + info: patchinfoty; + index: integer; + end; + ppatchty = ^patchty; + patchdataty = record + header: ptruintdataty; + data: patchty; + end; + patchhashdataty = record + header: hashheaderty; + data: patchdataty; + end; + ppatchhashdataty = ^patchhashdataty; + + tmidipatch = class(townedpersistent) + private + finfo: patchinfoty; + procedure setchannel(const avalue: integer); + procedure settrack(const avalue: integer); + procedure setnotemin(const avalue: integer); + procedure setnotemax(const avalue: integer); + procedure setmidichannel(const avalue: midichannelty); + protected + procedure changed; + public + constructor create(aowner: tobject); override; + published + property channel: integer read finfo.channel write setchannel default 0; + property track: integer read finfo.track write settrack default -1; + //-1 -> all + property midichannel: midichannelty read finfo.midichannel + write setmidichannel default mic_0; + property notemin: integer read finfo.notemin write setnotemin default 0; + property notemax: integer read finfo.notemax write setnotemax default 127; + end; + + tmidipatches = class(townedpersistentarrayprop) + protected + public + constructor create(const aowner: tsigmidisource); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + end; + + tpatchinfolist = class(tptruinthashdatalist) + private + findexresult: integer; + fnote: byte; + fnoterange: integer; + procedure checkeventindex(const aitem: phashdataty; var accept: boolean); + protected + function getrecordsize(): int32 override; + public +// constructor create; + function add(const apatch: tmidipatch): ppatchhashdataty; + function geteventindex(const aevent: midieventinfoty): integer; + end; + + mididecodestatety = (mds_start,mds_readbytes,mds_eventcomplete); + + tsigmidisource = class(tmidisource,icommclient) + private + fconnections: sigmidiconnectorarty; + fpatches: tmidipatches; + fpatchpanel: tpatchinfolist; + fsercomm: tcustomcommcomp; + fserverintf: icommserver; + fdecodestate: mididecodestatety; + fbytecount: integer; + fbyteindex: integer; + fnextstate: mididecodestatety; + procedure setpatches(const avalue: tmidipatches); + procedure setsercomm(const avalue: tcustomcommcomp); + protected + fbytebuffer: array[0..15] of byte; + fsigstate: sigmidisourcestatesty; + fchannels: sigchannelinfoarty; + procedure registerconnector(const avalue: tsigmidiconnector); + procedure unregisterconnector(const avalue: tsigmidiconnector); + procedure dotrackevent; override; + procedure updatepatch; + procedure patchchanged; + //icommclient + procedure setcommserverintf(const aintf: icommserver); + procedure dorxchange(const areader: tcommreader); + public + constructor create(avalue: tcomponent); override; + destructor destroy; override; + published + property patches: tmidipatches read fpatches write setpatches; + property sercomm: tcustomcommcomp read fsercomm write setsercomm; + end; + + tsigmidimulticonnector = class; + getvoiceclasseventty = procedure(const sender: tobject; + var avoiceclass: datamoduleclassty) of object; + initvoiceeventty = procedure(const sender: tsigmidimulticonnector; + const aindex: integer; const avoice: tmsedatamodule) of object; + + tdoubleoutmultiinpconn = class(tdoubleoutputconn) + private + finputs: tdoubleinpconnarrayprop; + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); override; + destructor destroy; override; + property inputs: tdoubleinpconnarrayprop read finputs; + end; + + tmidiconnoutputarrayprop = class(tdoubleoutconnarrayprop) + private + function getitems(const index: integer): tdoubleoutmultiinpconn; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + public + property items[const index: integer]: tdoubleoutmultiinpconn + read getitems; default; + end; + + tsigmidimulticonnector = class(tdoublesigcomp,isigclient) + private + fongetvoiceclass: getvoiceclasseventty; + fconnectorname: string; + finputcount: integer; + fpendinginputcount: integer; +// foutputcount: integer; + fvoices: msedatamodulearty; + fconnectors: sigmidiconnectorarty; + foninitvoice: initvoiceeventty; + foutputs: tmidiconnoutputarrayprop; + finps: sigvaluepoarty; + fouts: doublepoarty; + foutputhigh,finputhigh: integer; + fsource: tsigmidisource; + fchannel: integer; + function getitems(const index: integer): tmsedatamodule; + procedure setitems(const index: integer; const avalue: tmsedatamodule); + procedure setinputcount(const avalue: integer); + function getoutputcount: integer; + procedure setoutputcount(const avalue: integer); + procedure setsource(const avalue: tsigmidisource); + procedure updatesource; + procedure setchannel(const avalue: integer); + protected + procedure doinitvoice(const aindex: integer); + procedure loaded; override; + //isigclient + procedure initmodel; override; + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + function getinputar: inputconnarty; override; + function getoutputar: outputconnarty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property items[const index: integer]: tmsedatamodule read getitems + write setitems; default; + property outputs: tmidiconnoutputarrayprop read foutputs; + published + property inputcount: integer read finputcount write setinputcount default 0; + property outputcount: integer read getoutputcount + write setoutputcount default 0; + property source: tsigmidisource read fsource write setsource; + property channel: integer read fchannel write setchannel default 0; + property connectorname: string read fconnectorname write fconnectorname; + //'' -> defaultconnectorname + property ongetvoiceclass: getvoiceclasseventty read fongetvoiceclass + write fongetvoiceclass; + property oninitvoice: initvoiceeventty read foninitvoice write foninitvoice; + end; + +implementation +uses + math,msearrayutils,sysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsigcontroller1 = class(tsigcontroller); + tdoubleoutputconn1 = class(tdoubleoutputconn); + tdoubleinputconn1 = class(tdoubleinputconn); + +{ tsigmidiconnector } + +constructor tsigmidiconnector.create(aowner: tcomponent); +begin + initscale(defaultmidiattackvaluemin,defaultmidivaluemax, + defaultmidiattackvalueoptions,fattack); + initscale(defaultmidireleasevaluemin,defaultmidivaluemax, + defaultmidireleasevalueoptions,frelease); + initscale(defaultmidipressurevaluemin,defaultmidivaluemax, + defaultmidipressurevalueoptions,fpressure); + ffrequ_min:= 0.001; + ffrequout:= tdoubleoutputconn.create(self,isigclient(self),true); + ffrequout.name:= 'frequout'; + ffrequoutlin:= tdoubleoutputconn.create(self,isigclient(self),true); + ffrequoutlin.name:= 'frequoutlin'; + ftrigout:= tdoubleoutputconn.create(self,isigclient(self),true); + ftrigout.name:= 'trigout'; + fattackout:= tdoubleoutputconn.create(self,isigclient(self),true); + fattackout.name:= 'attackout'; + fattackoutlin:= tdoubleoutputconn.create(self,isigclient(self),true); + fattackoutlin.name:= 'attackoutlin'; + fpressureout:= tdoubleoutputconn.create(self,isigclient(self),true); + fpressureout.name:= 'pressureout'; + fpressureoutlin:= tdoubleoutputconn.create(self,isigclient(self),true); + fpressureoutlin.name:= 'pressureoutlin'; + freleaseout:= tdoubleoutputconn.create(self,isigclient(self),true); + freleaseout.name:= 'releaseout'; + freleaseoutlin:= tdoubleoutputconn.create(self,isigclient(self),true); + freleaseoutlin.name:= 'releaseoutlin'; + inherited; +end; + +destructor tsigmidiconnector.destroy; +begin + source:= nil; + inherited; +end; + +procedure tsigmidiconnector.sighandler(const ainfo: psighandlerinfoty); +//var +// int1: integer; +begin + //dummy +// ftrigoutpo^:= ftrigvalue; +end; + +function tsigmidiconnector.getoutputar: outputconnarty; +begin + setlength(result,9); + result[0]:= ftrigout; + result[1]:= ffrequout; + result[2]:= ffrequoutlin; + result[3]:= fattackout; + result[4]:= fattackoutlin; + result[5]:= fpressureout; + result[6]:= fpressureoutlin; + result[7]:= freleaseout; + result[8]:= freleaseoutlin; +end; + +function tsigmidiconnector.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigmidiconnector.setfrequout(const avalue: tdoubleoutputconn); +begin + ffrequout.assign(avalue); +end; + +procedure tsigmidiconnector.settrigout(const avalue: tdoubleoutputconn); +begin + ftrigout.assign(avalue); +end; + +procedure tsigmidiconnector.midievent(const ainfo: midieventinfoty); +begin + lock; + try + with ainfo do begin + case kind of + mmk_notepressure: begin + fpressure.value:= par2*paramscale; + tdoubleoutputconn1(fpressureoutlin).fvalue:= fpressure.value; + tdoubleoutputconn1(fpressureout).fvalue:= scalevalue(fpressure); + end; + mmk_noteon: begin + tdoubleoutputconn1(ffrequoutlin).fvalue:= par1*paramscale; + tdoubleoutputconn1(ffrequout).fvalue:= intpower(2.0,par1 div 12) * + chromaticscale[par1 mod 12] * ffrequ_min; + if par2 = 0 then begin + ftrigvalue:= -1; + frelease.value:= 0; + tdoubleoutputconn1(freleaseoutlin).fvalue:= frelease.value; + tdoubleoutputconn1(freleaseout).fvalue:= scalevalue(frelease); + end + else begin + ftrigvalue:= 1; + fattack.value:= par2*paramscale; + tdoubleoutputconn1(fattackoutlin).fvalue:= fattack.value; + tdoubleoutputconn1(fattackout).fvalue:= scalevalue(fattack); + end; + tdoubleoutputconn1(ftrigout).fvalue:= ftrigvalue; + end; + mmk_noteoff: begin + ftrigvalue:= -1; + frelease.value:= par2*paramscale; + tdoubleoutputconn1(freleaseoutlin).fvalue:= frelease.value; + tdoubleoutputconn1(freleaseout).fvalue:= scalevalue(frelease); + end; + end; + end; + if fcontroller <> nil then begin + tsigcontroller1(fcontroller).execevent(isigclient(self)); + end; + finally + unlock; + end; +end; + +procedure tsigmidiconnector.setsource(const avalue: tsigmidisource); +begin + if fsource <> avalue then begin + if fsource <> nil then begin + fsource.unregisterconnector(self); + end; + fsource:= avalue; + if fsource <> nil then begin + fsource.registerconnector(self); + end; + end; +end; + +procedure tsigmidiconnector.setchannel(const avalue: integer); +begin + if fchannel <> avalue then begin + fchannel:= avalue; + if fsource <> nil then begin + fsource.patchchanged; + end; + end; +end; + +procedure tsigmidiconnector.setattack_min(const avalue: double); +begin + fattack.min:= avalue; + updatescale(fattack); +end; + +procedure tsigmidiconnector.setattack_max(const avalue: double); +begin + fattack.max:= avalue; + updatescale(fattack); +end; + +procedure tsigmidiconnector.setattack_options(const avalue: valuescaleoptionsty); +begin + fattack.options:= avalue; + updatescale(fattack); +end; + +procedure tsigmidiconnector.setpressure_min(const avalue: double); +begin + fpressure.min:= avalue; + updatescale(fpressure); +end; + +procedure tsigmidiconnector.setpressure_max(const avalue: double); +begin + fpressure.max:= avalue; + updatescale(fpressure); +end; + +procedure tsigmidiconnector.setpressure_options(const avalue: valuescaleoptionsty); +begin + fpressure.options:= avalue; + updatescale(fpressure); +end; + +procedure tsigmidiconnector.setrelease_min(const avalue: double); +begin + frelease.min:= avalue; + updatescale(frelease); +end; + +procedure tsigmidiconnector.setrelease_max(const avalue: double); +begin + frelease.max:= avalue; + updatescale(frelease); +end; + +procedure tsigmidiconnector.setrelease_options(const avalue: valuescaleoptionsty); +begin + frelease.options:= avalue; + updatescale(frelease); +end; + +procedure tsigmidiconnector.setattackout(const avalue: tdoubleoutputconn); +begin + fattackout.assign(avalue); +end; + +procedure tsigmidiconnector.setpressureout(const avalue: tdoubleoutputconn); +begin + fpressureout.assign(avalue); +end; + +procedure tsigmidiconnector.setreleaseout(const avalue: tdoubleoutputconn); +begin + freleaseout.assign(avalue); +end; + +procedure tsigmidiconnector.setattackoutlin(const avalue: tdoubleoutputconn); +begin + fattackoutlin.assign(avalue); +end; + +procedure tsigmidiconnector.setfrequoutlin(const avalue: tdoubleoutputconn); +begin + ffrequoutlin.assign(avalue); +end; + +procedure tsigmidiconnector.setpressureoutlin(const avalue: tdoubleoutputconn); +begin + fpressureoutlin.assign(avalue); +end; + +procedure tsigmidiconnector.setreleaseoutlin(const avalue: tdoubleoutputconn); +begin + freleaseoutlin.assign(avalue); +end; + +{ tsigmidisource } + +constructor tsigmidisource.create(avalue: tcomponent); +begin + fpatches:= tmidipatches.create(self); + fpatchpanel:= tpatchinfolist.create; + inherited; +end; + +destructor tsigmidisource.destroy; +var + int1: integer; +begin + sercomm:= nil; + for int1:= 0 to high(fconnections) do begin + fconnections[int1].fsource:= nil; + end; + inherited; + fpatchpanel.free; + fpatches.free; +end; + +procedure tsigmidisource.patchchanged; +begin + exclude(fsigstate,smss_patchvalid); +end; + +procedure tsigmidisource.registerconnector(const avalue: tsigmidiconnector); +begin + additem(pointerarty(fconnections),avalue); + patchchanged; +end; + +procedure tsigmidisource.unregisterconnector(const avalue: tsigmidiconnector); +begin + removeitem(pointerarty(fconnections),avalue); + patchchanged; +end; + +procedure tsigmidisource.dotrackevent; +var + int1: integer; + po1: pconnectioninfoty; + by1: byte; +begin + inherited; + if not (smss_patchvalid in fsigstate) then begin + updatepatch; + end; + if ftrackevent.event.kind in [mmk_noteon,mmk_noteoff,mmk_notepressure] then begin + by1:= 0; //compiler warning + int1:= fpatchpanel.geteventindex(ftrackevent.event); + if int1 >= 0 then begin + with fchannels[int1] do begin + if connections <> nil then begin + po1:= first; + if po1 <> last then begin + by1:= ftrackevent.event.par1; + repeat + if po1^.key = by1 then begin + break; + end; + po1:= po1^.next; + until po1 = nil; + if po1 = nil then begin + po1:= last; + while po1 <> nil do begin + if not po1^.active then begin + break; + end; + po1:= po1^.prev; + end; + end; + if po1 <> first then begin + if po1 = nil then begin + po1:= last; + end; + if po1^.prev <> nil then begin + po1^.prev^.next:= po1^.next; + end; + if (po1^.next <> nil) then begin + po1^.next^.prev:= po1^.prev; + end; + first^.prev:= po1; + po1^.next:= first; + first:= po1; + if po1 = last then begin + last:= po1^.prev; + end; + po1^.prev:= nil; + end; + end; + po1^.key:= by1; + po1^.active:= (ftrackevent.event.kind = mmk_noteon) and + (ftrackevent.event.par2 <> 0) or + (ftrackevent.event.kind = mmk_notepressure); + po1^.dest.midievent(ftrackevent.event); + end; + end; + end; + end; +end; + +procedure tsigmidisource.updatepatch; +var + int1,int2: integer; + destlist: tpointerptruinthashdatalist; + patch1: tmidipatch; +// po1: ppatchty; + po2: pointer; +begin + fchannels:= nil; + fpatchpanel.clear; + destlist:= tpointerptruinthashdatalist.create; + int2:= 0; + for int1:= 0 to high(fconnections) do begin + if not destlist.addunique(fconnections[int1].channel,pointer(ptrint(int2))) then begin + inc(int2); + end; + end; + setlength(fchannels,int2); + for int1:= 0 to high(fconnections) do begin + with fchannels[ptruint(destlist.find(fconnections[int1].channel))] do begin + int2:= high(connections)+1; + setlength(connections,int2+1); + connections[int2].dest:= fconnections[int1]; + end; + end; + for int1:= 0 to fpatches.count - 1 do begin + patch1:= tmidipatch(fpatches.fitems[int1]); + if destlist.find(patch1.channel,po2) then begin + fpatchpanel.add(patch1)^.data.data.index:= ptrint(po2); + end; + end; + destlist.free; + for int2:= 0 to high(fchannels) do begin + with fchannels[int2] do begin + first:= nil; + last:= nil; + if high(connections) >= 0 then begin + first:= @connections[0]; + last:= @connections[high(connections)]; + for int1:= 0 to high(connections) do begin + with connections[int1] do begin +// dest:= fconnections[int1]; + if int1 < high(connections) then begin + next:= @connections[int1+1]; + end; + if int1 > 0 then begin + prev:= @connections[int1-1]; + end; + end; + end; + end; + end; + end; + include(fsigstate,smss_patchvalid); +end; + +procedure tsigmidisource.setpatches(const avalue: tmidipatches); +begin + fpatches.assign(avalue); +end; + +procedure tsigmidisource.setsercomm(const avalue: tcustomcommcomp); +begin + if fsercomm <> avalue then begin + setcomcomp(icommclient(self),avalue,fsercomm); + end; +end; + +procedure tsigmidisource.setcommserverintf(const aintf: icommserver); +begin + fserverintf:= aintf; +end; + +procedure tsigmidisource.dorxchange(const areader: tcommreader); + + procedure readbytes(const acount : integer; const nextstate: mididecodestatety); + begin + fbytecount:= acount; + fnextstate:= nextstate; + fdecodestate:= mds_readbytes; + fbyteindex:= 0; + end; //readbytes() + +var + po1: pchar; +begin + with ftrackevent.event do begin + while true do begin + po1:= areader.bufpo; + if po1 = nil then begin + break; + end; + if fdecodestate = mds_readbytes then begin + if po1 >= #$80 then begin + fdecodestate:= mds_start; //cancel byte read + end + else begin + if fbytecount > 0 then begin + fbytebuffer[fbyteindex]:= byte(po1^); + inc(fbyteindex); + if fbyteindex = fbytecount then begin + fdecodestate:= fnextstate; + end; + end; + areader.skip(1); + end; + end; + if fdecodestate <> mds_readbytes then begin + case fdecodestate of + mds_start: begin + if po1^ >= #$80 then begin //commandstart + fillchar(ftrackevent,sizeof(ftrackevent),0); + kind:= midimessagetable[(byte(po1^) shr 4) and $7]; + if kind in midichannelmessages then begin + channel:= byte(po1^) and $0f; + readbytes(midiparcount[kind],mds_eventcomplete); + end + else begin + end; + areader.skip(1); + end + else begin + areader.skip(1); + end; + end; + mds_eventcomplete: begin + ftrackevent.event.par1:= fbytebuffer[0]; + ftrackevent.event.par2:= fbytebuffer[1]; + readbytes(midiparcount[kind],mds_eventcomplete); + //prepare for next event with same state + dotrackevent; + end; + else begin + areader.skip(1); + end; + end; + end; + end; + end; +end; + +{ tdoubleoutmultiinpconn } + +constructor tdoubleoutmultiinpconn.create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); +begin + finputs:= tdoubleinpconnarrayprop.create(asigintf); + inherited; +end; + +destructor tdoubleoutmultiinpconn.destroy; +begin + finputs.free; + inherited; +end; + +{ tmidiconnoutputarrayprop } + +function tmidiconnoutputarrayprop.getitems(const index: integer): + tdoubleoutmultiinpconn; +begin + result:= tdoubleoutmultiinpconn(inherited getitems(index)); +end; + +procedure tmidiconnoutputarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tdoubleoutmultiinpconn.create(fowner,fsigintf,feventdriven); + tdoubleoutputconn(item).name:= fname+inttostr(index); +end; + +{ tsigmidimulticonnector } + +constructor tsigmidimulticonnector.create(aowner: tcomponent); +begin + foutputs:= tmidiconnoutputarrayprop.create(self,'output', + isigclient(self),false); + inherited; +end; + +destructor tsigmidimulticonnector.destroy; +begin + inputcount:= 0; + foutputs.free; + inherited; +end; + +function tsigmidimulticonnector.getitems(const index: integer): tmsedatamodule; +begin + checkarrayindex(fvoices,index); + result:= fvoices[index]; +end; + +procedure tsigmidimulticonnector.setitems(const index: integer; + const avalue: tmsedatamodule); +begin + checkarrayindex(fvoices,index); + fvoices[index].assign(avalue); +end; + +procedure tsigmidimulticonnector.doinitvoice(const aindex: integer); +begin + lock; + try + with fconnectors[aindex] do begin + channel:= self.fchannel; + source:= self.fsource; + end; + if assigned(foninitvoice) then begin + foninitvoice(self,aindex,fvoices[aindex]); + end; + finally + unlock; + end; +end; + +procedure tsigmidimulticonnector.setinputcount(const avalue: integer); +var + int1: integer; + class1: datamoduleclassty; + str1: string; + voice1: tmsedatamodule; + conn1: tcomponent; +begin + if finputcount <> avalue then begin + if csloading in componentstate then begin + fpendinginputcount:= avalue; + end + else begin + if csdesigning in componentstate then begin + finputcount:= avalue; + end + else begin + lock; + try + if avalue <> finputcount then begin + if avalue < finputcount then begin + for int1:= finputcount-1 downto avalue do begin + fvoices[int1].free; + dec(finputcount); + end; + end + else begin + if not assigned(fongetvoiceclass) then begin + raise exception.create('ongetvoiceclass not assigned.'); + end; + class1:= nil; + fongetvoiceclass(self,class1); + if class1 = nil then begin + raise exception.create('Voiceclass not set.'); + end; + str1:= fconnectorname; + if str1 = '' then begin + str1:= defaultconnectorname; + end; + setlength(fvoices,avalue); //max + setlength(fconnectors,avalue); //max + for int1:= 0 to foutputs.count - 1 do begin + foutputs[int1].inputs.count:= avalue; //max + end; + for int1:= finputcount to avalue - 1 do begin + voice1:= class1.create(nil); + conn1:= voice1.findcomponent(str1); + if not (conn1 is tsigmidiconnector) then begin + voice1.free; + raise exception.create('tmidiconnector "'+str1+'" not found.'); + end; + fvoices[int1]:= voice1; + fconnectors[int1]:= tsigmidiconnector(conn1); + inc(finputcount); + doinitvoice(int1); + end; + end; + end; + finally + setlength(fvoices,finputcount); + setlength(fconnectors,finputcount); + for int1:= 0 to foutputs.count - 1 do begin + foutputs[int1].inputs.count:= finputcount; + end; + unlock; + end; + end; + end; + end; +end; + +procedure tsigmidimulticonnector.initmodel; +var + int1,int2,int3: integer; +begin + setlength(fouts,foutputs.count); + setlength(finps,finputcount*foutputs.count); + finputhigh:= finputcount-1; + foutputhigh:= foutputs.count-1; + int3:= 0; + for int1:= 0 to foutputhigh do begin + with foutputs[int1] do begin + fouts[int1]:= @fvalue; + for int2:= 0 to finputhigh do begin + finps[int3]:= @tdoubleinputconn1(inputs[int2]).fv; + inc(int3); + end; + end; + end; + inherited; +end; + +function tsigmidimulticonnector.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigmidimulticonnector.sighandler(const ainfo: psighandlerinfoty); +var + int1,int2: integer; + po1: ppdouble; + do1: double; +begin + po1:= ppdouble(finps); + if po1 <> nil then begin + for int1:= 0 to foutputhigh do begin + do1:= 0; + for int2:= finputhigh downto 0 do begin + do1:= do1 + po1^^; + inc(po1); + end; + fouts[int1]^:= do1; + end; + { + if fouts <> nil then begin + ainfo^.dest^:= ppdouble(fouts)^^; + end; + } + end; +end; + +function tsigmidimulticonnector.getinputar: inputconnarty; +var + int1,int2,int3: integer; +begin + setlength(result,finputcount*foutputs.count); + int3:= 0; + for int1:= 0 to foutputs.count - 1 do begin + with foutputs[int1] do begin + for int2:= 0 to finputcount - 1 do begin + result[int3]:= inputs[int2]; + inc(int3); + end; + end; + end; +end; + +function tsigmidimulticonnector.getoutputar: outputconnarty; +begin + result:= outputconnarty(copy(foutputs.fitems)); +end; + +function tsigmidimulticonnector.getoutputcount: integer; +begin + result:= foutputs.count; +end; + +procedure tsigmidimulticonnector.setoutputcount(const avalue: integer); +begin + foutputs.count:= avalue; +end; + +procedure tsigmidimulticonnector.setsource(const avalue: tsigmidisource); +begin + if avalue <> fsource then begin + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fsource)); + updatesource; + end; +end; + +procedure tsigmidimulticonnector.updatesource; +var + int1: integer; +begin + lock; + try + for int1:= 0 to high(fconnectors) do begin + with fconnectors[int1] do begin + channel:= self.fchannel; + source:= self.fsource; + end; + end; + finally + unlock; + end; +end; + +procedure tsigmidimulticonnector.setchannel(const avalue: integer); +begin + if fchannel <> avalue then begin + fchannel:= avalue; + updatesource; + end; +end; + +procedure tsigmidimulticonnector.loaded; +begin + inherited; + lock; + try + inputcount:= fpendinginputcount; + finally + unlock; + end; +end; + +{ tmidipatches } + +constructor tmidipatches.create(const aowner: tsigmidisource); +begin + inherited create(aowner,tmidipatch); +end; + +class function tmidipatches.getitemclasstype: persistentclassty; +begin + result:= tmidipatch; +end; + +{ tmidipatch } + +constructor tmidipatch.create(aowner: tobject); +begin + finfo.track:= -1; + finfo.notemax:= 127; + inherited; +end; + +procedure tmidipatch.changed; +begin + tsigmidisource(fowner).patchchanged; +end; + +procedure tmidipatch.setchannel(const avalue: integer); +begin + if finfo.channel <> avalue then begin + finfo.channel:= avalue and channelmask; + changed; + end; +end; + +procedure tmidipatch.setmidichannel(const avalue: midichannelty); +begin + if finfo.midichannel <> avalue then begin + finfo.midichannel:= avalue; + changed; + end; +end; + +procedure tmidipatch.settrack(const avalue: integer); +begin + if finfo.track <> avalue then begin + finfo.track:= avalue; + changed; + end; +end; + +procedure tmidipatch.setnotemin(const avalue: integer); +begin + if finfo.notemin <> avalue then begin + finfo.notemin:= avalue; + changed; + end; +end; + +procedure tmidipatch.setnotemax(const avalue: integer); +begin + if finfo.notemax <> avalue then begin + finfo.notemax:= avalue; + changed; + end; +end; + +{ tpatchinfolist } +{ +constructor tpatchinfolist.create; +begin + inherited create(sizeof(patchty)); +end; +} +function tpatchinfolist.getrecordsize(): int32; +begin + result:= sizeof(patchhashdataty); +end; + +function tpatchinfolist.add(const apatch: tmidipatch): ppatchhashdataty; +begin + with apatch do begin + result:= ppatchhashdataty(inherited add((track shl 5) or ord(midichannel))); + result^.data.data.info:= finfo; + end; +end; + +function tpatchinfolist.geteventindex(const aevent: midieventinfoty): integer; +var + puint1: ptruint; +begin + findexresult:= -1; + fnote:= aevent.par1 and $7f; + fnoterange:= bigint; + puint1:= (aevent.track shl 5) or aevent.channel; + internalfind(puint1,{$ifdef FPC}@{$endif}checkeventindex); + if findexresult = -1 then begin + puint1:= puint1 or ($ffffffff shl 5); //-1 + internalfind(puint1,{$ifdef FPC}@{$endif}checkeventindex); + end; + result:= findexresult; +end; + +procedure tpatchinfolist.checkeventindex(const aitem: phashdataty; + var accept: boolean); +var + int1: integer; +begin + with ppatchhashdataty(aitem)^.data.data,info do begin + if (fnote >= notemin) and (fnote <= notemax) then begin + int1:= notemax - notemin; + if int1 < fnoterange then begin + findexresult:= index; + fnoterange:= int1; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesignal.pas b/mseide-msegui/lib/common/math/msesignal.pas new file mode 100644 index 0000000..6891a0b --- /dev/null +++ b/mseide-msegui/lib/common/math/msesignal.pas @@ -0,0 +1,4991 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +// +// todo: optimize for realtime, remove the OOP approach where +// it degrades performance, use SSE. +// + +unit msesignal; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msedatalist,mseclasses,classes,mclasses,msetypes,msearrayprops,mseevent,msehash, + msesystypes,msereal,msetimer,mseglob; + +const + defaultsamplefrequ = 44100; //Hz + defaultstepcount = 4096; + defaultenvelopesubsampling = 8; + defaulttickdiv = 200; + defaultsamplecount = 4096; + defaultharmonicscount = 16; + functionsegmentcount = 32; +{$ifdef FPC} + semitoneln = ln(2)/12; + chromaticscale: array[0..12] of double = + (1.0,exp(1*semitoneln),exp(2*semitoneln),exp(3*semitoneln),exp(4*semitoneln), + exp(5*semitoneln),exp(6*semitoneln),exp(7*semitoneln),exp(8*semitoneln), + exp(9*semitoneln),exp(10*semitoneln),exp(11*semitoneln),2.0); +{$else} + semitoneln = 5.77622650467e-2; + chromaticscale: array[0..12] of double = + (1.0,1.05946309436,1.12246204831,1.189207115, + 1.2599210499,1.33483985417,1.41421356237,1.49830707688, + 1.58740105197,1.6817928179283051,1.78179743628,1.88774862536,2.0); +{$endif} + +type + siginchangeflagty = (sic_value,sic_stream); + siginchangeflagsty = set of siginchangeflagty; + psiginchangeflagsty = ^siginchangeflagsty; +const + siginchangeresetflags = [sic_value]; + +type + sigsampleroptionty = (sso_fulltick,sso_negtrig,sso_autorun, + sso_fftmag,sso_average); //used by tsigsamplerfft + sigsampleroptionsty = set of sigsampleroptionty; + +const + defaultsigsampleroptions = [sso_fulltick]; +type + tcustomsigcomp = class; + tdoublesigcomp = class; + tsigcontroller = class; + + tcustomsigcomp = class(tmsecomponent) + protected + fupdating: integer; + procedure coeffchanged(const sender: tdatalist; + const aindex: integer); virtual; + procedure update; virtual; + public + procedure beginupdate; + procedure endupdate; + end; + + tsigcomp = class(tcustomsigcomp) + + end; + + tdoubleinputconn = class; + tdoubleoutputconn = class; + + inputconnarty = array of tdoubleinputconn; + outputconnarty = array of tdoubleoutputconn; + + psighandlerinfoty = ^sighandlerinfoty; + sighandlerprocty = procedure(const ainfo: psighandlerinfoty) of object; + + psiginfoty = ^siginfoty; + sigclientinfoty = record + infopo: psiginfoty; + end; + psigclientinfoty = ^sigclientinfoty; + + sigclientoptionty = (sco_tick,sco_fulltick); + sigclientoptionsty = set of sigclientoptionty; + + isigclient = interface(ievent) + procedure initmodel; + procedure clear; + function getinputar: inputconnarty; + function getoutputar: outputconnarty; + function gethandler: sighandlerprocty; + function getzcount: integer; + function getcomponent: tcomponent; + procedure modelchange; + function getsigcontroller: tsigcontroller; + function getsigclientinfopo: psigclientinfoty; + function getsigoptions: sigclientoptionsty; + {$ifdef FPC} + procedure sigtick; + {$else} + procedure sigtick(); + {$endif} + end; + sigclientintfarty = array of isigclient; + + tdoublesigcomp = class(tsigcomp,isigclient) + private + fsigclientinfo: sigclientinfoty; + procedure setcontroller(const avalue: tsigcontroller); + protected + fcontroller: tsigcontroller; + procedure modelchange; + procedure loaded; override; + procedure lock; + procedure unlock; + + //isigclient + procedure initmodel; virtual; + procedure sigtick; virtual; + function getinputar: inputconnarty; virtual; + function getoutputar: outputconnarty; virtual; + function gethandler: sighandlerprocty; virtual; abstract; + function getzcount: integer; virtual; + function getsigcontroller: tsigcontroller; + function getsigclientinfopo: psigclientinfoty; + function getsigoptions: sigclientoptionsty; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; virtual; + procedure lockapplication; //releases controller lock, can not be nested, + //call from locked signal thread only + procedure unlockapplication;//acquires controller lock + published + property controller: tsigcontroller read fcontroller write setcontroller; + end; + + tsigconn = class(tmsecomponent) + //no solution found to link to streamed tpersistent or tobject, + //fork of classes.pp necessary. :-( + end; + + tdoubleconn = class(tsigconn) + protected + fsigintf: isigclient; + function getcontroller: tsigcontroller; + procedure lock; + procedure unlock; + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient); reintroduce; virtual; + property controller: tsigcontroller read getcontroller; + end; + + valuescaleoptionty = (vso_exp,vso_null); //out:= 0 for inp <= 0 + valuescaleoptionsty = set of valuescaleoptionty; + doublescaleinfoty = record + value: double; + min: double; + max: double; + options: valuescaleoptionsty; + gain,offset: double; + end; + + doubleinputconnarty = array of tdoubleinputconn; + + outputconnstatety = (ocs_eventdriven); + outputconnstatesty = set of outputconnstatety; + + tdoubleoutputconn = class(tdoubleconn) + private + function geteventdriven: boolean; + procedure seteventdriven(const avalue: boolean); + protected + fstate: outputconnstatesty; + fdestinations: doubleinputconnarty; + fvalue: double; + property eventdriven: boolean read geteventdriven write seteventdriven; + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); + reintroduce; virtual; + property value: double read fvalue write fvalue; + end; + +// siginpoptionty = (sio_exp); +// siginpoptionsty = set of siginpoptionty; + + inpscaleinfoty = record + offset: double; + gain: double; + hasscale: boolean; + hasmin: boolean; + hasmax: boolean; + isexp: boolean; + end; + + sigvaluety = record + value: double; + changed: siginchangeflagsty; + end; + psigvaluety = ^sigvaluety; + sigvaluepoarty = array of psigvaluety; + + tdoubleinputconn = class(tdoubleconn) + private + fsource: tdoubleoutputconn; + foffset: double; + fgain: double; + fmin: realty; + fmax: realty; + fexpstart: realty; + fexpend: realty; +// foptions: siginpoptionsty; + procedure setsource(const avalue: tdoubleoutputconn); + procedure setoffset(const avalue: double); + procedure setgain(const avalue: double); + procedure setvalue(const avalue: double); virtual; + procedure setmin(const avalue: realty); + procedure setmax(const avalue: realty); + procedure setexpstart(const avalue: realty); + procedure setexpend(const avalue: realty); + protected + fsca: inpscaleinfoty; + fv: sigvaluety; + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient); override; + destructor destroy; override; + published + property source: tdoubleoutputconn read fsource write setsource; + property offset: double read foffset write setoffset; + property gain: double read fgain write setgain; + property min: realty read fmin write setmin; + property max: realty read fmax write setmax; + property expstart: realty read fexpstart write setexpstart; + property expend: realty read fexpend write setexpend; + property value: double read fv.value write setvalue; +// property options: siginpoptionsty read foptions write setoptions; + end; + + tlimitinputconn = class(tdoubleinputconn) + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient); override; + //deafault min = 0, default max = 1 + end; + + tchangedoubleinputconn = class(tdoubleinputconn) + private + fonchange: notifyeventty; + protected + procedure setvalue(const avalue: double); override; + public + constructor create(const aowner: tcomponent; const asigintf: isigclient; + const aonchange: notifyeventty); reintroduce; + end; + + sighandlerinfoty = record +// dest: pdouble; + discard: boolean; + end; + + siginfopoarty = array of psiginfoty; + signahdlerprocty = procedure(siginfo: psiginfoty); + + siginfostatety = (sis_checked,sis_eventchecked,sis_touched, + sis_input,sis_output, + sis_eventoutput,sis_eventinput,sis_fulltick,sis_sighandler); + siginfostatesty = set of siginfostatety; + + inputstatety = (ins_checked,ins_recursive); + inputstatesty = set of inputstatety; + + inputinfoty = record + input: tdoubleinputconn; + source: psiginfoty; + state: inputstatesty; + end; + inputinfoarty = array of inputinfoty; + + sigdestinfoty = record + outputindex: integer; + destinput: tdoubleinputconn; + end; + sigdestinfoarty = array of sigdestinfoty; + + siginfoty = record + intf: isigclient; + options: sigclientoptionsty; + handler: sighandlerprocty; + zcount: integer; + inputs: inputinfoarty; + outputs: outputconnarty; + destinations: sigdestinfoarty; + eventdestinations: siginfopoarty; + state: siginfostatesty; + prev: siginfopoarty; + connectedcount: integer; + next: siginfopoarty; + end; + siginfoarty = array of siginfoty; + + destinfoty = record + source: pdouble; + dest: pdouble; + min: double; + max: double; + sca: inpscaleinfoty; + end; + destinfoarty = array of destinfoty; + + sighandlernodeinfoty = record + handlerinfo: sighandlerinfoty; + handler: sighandlerprocty; +// firstdest: destinfoty; + dest: destinfoarty; + desthigh: integer; + end; + psighandlernodeinfoty = ^sighandlernodeinfoty; + sighandlernodeinfoarty = array of sighandlernodeinfoty; + + tsigconnection = class(tdoublesigcomp) + end; + + sigineventty = procedure(const sender: tobject; + var sig: real) of object; + siginbursteventty = procedure(const sender: tobject; + var sig: realarty) of object; + sigincomplexeventty = procedure(const sender: tobject; + var sig: complexty) of object; + sigincomplexbursteventty = procedure(const sender: tobject; + var sig: complexarty) of object; + + tsigin = class(tsigconnection) + private + foutput: tdoubleoutputconn; + foutputpo: pdouble; + fvalue: double; + finp: doublearty; + foninput: sigineventty; + foninputburst: siginbursteventty; + finpindex: integer; + procedure setvalue(const avalue: double); + protected + function getoutputar: outputconnarty; override; + //isigclient + procedure initmodel; override; + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure siginput(const asource: doublearty); + procedure clear; override; + property output: tdoubleoutputconn read foutput; + published + property value: double read fvalue write setvalue; + property oninput: sigineventty read foninput write foninput; + property oninputburst: siginbursteventty read foninputburst write foninputburst; + end; + + sigouteventty = procedure(const sender: tobject; + const sig: real) of object; + sigoutbursteventty = procedure(const sender: tobject; + const sig: realarty) of object; + + tsigout = class(tsigconnection) + private + finput: tdoubleinputconn; + finputpo: psigvaluety; + fonoutput: sigouteventty; + fvalue: double; + fonoutputburst: sigoutbursteventty; + foutp: doublearty; + foutpindex: integer; + fbuffersize: integer; + procedure setinput(const avalue: tdoubleinputconn); + function getinput: tdoubleinputconn; + procedure setbuffersize(const avalue: integer); + function getvalue: double; + protected + function getinputar: inputconnarty; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; override; + procedure sigoutput1(var adest: doublearty); //returns a data copy + function sigoutput: doublearty; + property value: double read getvalue; + published + property input: tdoubleinputconn read getinput write setinput; + property buffersize: integer read fbuffersize + write setbuffersize default 0; + property onoutput: sigouteventty read fonoutput write fonoutput; + property onoutputburst: sigoutbursteventty read fonoutputburst + write fonoutputburst; + end; + + trealcoeff = class(trealdatalist) + protected + fowner: tcustomsigcomp; + procedure doitemchange(const aindex: integer); override; + public + constructor create(const aowner: tcustomsigcomp); reintroduce; + end; + + tcomplexcoeff = class(tcomplexdatalist) + protected + fowner: tcustomsigcomp; + procedure doitemchange(const aindex: integer); override; + public + constructor create(const aowner: tcustomsigcomp); reintroduce; + end; + + tdoublezcomp = class(tdoublesigcomp) //single input, single output + private + procedure setinput(const avalue: tdoubleinputconn); + procedure setoutput(const avalue: tdoubleoutputconn); + protected + fzcount: integer; + fzhigh: integer; + fdoublez: doublearty; + fzindex: integer; + finputindex: integer; + fdoubleinputdata: doubleararty; + finput: tdoubleinputconn; + foutput: tdoubleoutputconn; + foutputpo: pdouble; + function getinputar: inputconnarty; override; + function getoutputar: outputconnarty; override; + procedure setzcount(const avalue: integer); + function getzcount: integer; override; + procedure zcountchanged; virtual; + procedure initmodel; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; override; + property zcount: integer read getzcount default 0; + property output: tdoubleoutputconn read foutput write setoutput; + published + property input: tdoubleinputconn read finput write setinput; + end; + + tdoubleinpconnarrayprop = class(tpersistentarrayprop) + private + fsigintf: isigclient; + function getitems(const index: integer): tdoubleinputconn; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure dosizechanged; override; + public + constructor create(const asigintf: isigclient); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + property items[const index: integer]: tdoubleinputconn read getitems; default; + end; + + tdoubleoutconnarrayprop = class(tpersistentarrayprop) + private + function getitems(const index: integer): tdoubleoutputconn; + protected + fsigintf: isigclient; + fname: string; + fowner: tcomponent; + feventdriven: boolean; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure dosizechanged; override; + public + constructor create(const aowner: tcomponent; const aname: string; + const asigintf: isigclient; const aeventdriven: boolean); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + property items[const index: integer]: tdoubleoutputconn read getitems; default; + end; + + tsigmultiinp = class(tdoublesigcomp) + private + finputs: tdoubleinpconnarrayprop; + procedure setinputs(const avalue: tdoubleinpconnarrayprop); + protected + finps: sigvaluepoarty; + finphigh: integer; + function getinputar: inputconnarty; override; + procedure initmodel; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property inputs: tdoubleinpconnarrayprop read finputs write setinputs; + end; + + tsigsampler = class; + samplerbufferty = array of doublearty; + samplerbufferfulleventty = procedure(const sender: tsigsampler; + const abuffer: samplerbufferty) of object; + + tsigsampler = class(tsigmultiinp) + private + fbufferlength: integer; + fbufpo: integer; + ftrigger: tchangedoubleinputconn; + ftriggerlevel: tchangedoubleinputconn; + fonbufferfull: samplerbufferfulleventty; + ftimer: tsimpletimer; + frefreshus: integer; + procedure setbufferlength(const avalue: integer); + procedure settrigger(const avalue: tchangedoubleinputconn); + procedure settriggerlevel(const avalue: tchangedoubleinputconn); + procedure setrefreshus(const avalue: integer); + protected + foptions: sigsampleroptionsty; + fnegtrig: boolean; + fstarted: boolean; + fstartpending: boolean; + fpretrigger: boolean; + frunning: boolean; + fsigbuffer: samplerbufferty; + procedure setoptions(const avalue: sigsampleroptionsty) virtual; + procedure updateoptions(var avalue: sigsampleroptionsty); virtual; + procedure dotimer(const sender: tobject); + procedure dotriggerchange(const sender: tobject); + procedure dobufferfull; virtual; + procedure loaded; override; + procedure checkautostart; + //isigclient + function getsigoptions: sigclientoptionsty; override; + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure initmodel; override; + function getinputar: inputconnarty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; override; + procedure start; + published + property bufferlength: integer read fbufferlength + write setbufferlength default defaultsamplecount; + property trigger: tchangedoubleinputconn read ftrigger write settrigger; + property triggerlevel: tchangedoubleinputconn read ftriggerlevel + write settriggerlevel; + property options: sigsampleroptionsty read foptions + write setoptions default defaultsigsampleroptions; + property onbufferfull: samplerbufferfulleventty read fonbufferfull + write fonbufferfull; + property refreshus: integer read frefreshus write setrefreshus default -1; + //micro seconds, -1 -> off, 0 -> on idle + end; + + tsigmultiinpout = class(tsigmultiinp) + private + //local variables +// dar: doublearty; +// pdar: doublepoarty; + procedure setoutput(const avalue: tdoubleoutputconn); + protected + foutput: tdoubleoutputconn; + foutputpo: pdouble; + function getoutputar: outputconnarty; override; + procedure initmodel; override; + public + constructor create(aowner: tcomponent); override; +// destructor destroy; override; + property output: tdoubleoutputconn read foutput write setoutput; + end; + + tsigadd = class(tsigmultiinpout) + protected +// procedure processinout(const acount: integer; +// var ainp: doublepoarty; var aoutp: pdouble); override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + end; + + tsigdelay = class(tsigadd) + private + protected + fz: double; + function getzcount: integer; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + procedure clear; override; + end; + + tcustomsigdelay = class(tsigadd) + private + fdelay: integer; + finppo: integer; + procedure setdelay(const avalue: integer); + protected + fz: doublearty; + procedure initmodel; override; + function getzcount: integer; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + + property delay: integer read fdelay write setdelay default 1; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + end; + + tsigdelayn = class(tcustomsigdelay) + published + property delay; + end; + + tsigdelayvar = class(tcustomsigdelay) + private + fdelayinp: tdoubleinputconn; + fdelayinppo: pdouble; + function getdelaymax: integer; + procedure setdelaymax(const avalue: integer); + procedure setdelayinp(const avalue: tdoubleinputconn); + protected + function getinputar: inputconnarty; override; + procedure initmodel; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + published + property delaymax: integer read getdelaymax write setdelaymax default 1; + property delay: tdoubleinputconn read fdelayinp write setdelayinp; + end; + + tdoublesigoutcomp = class(tdoublesigcomp) + private + procedure setoutput(const avalue: tdoubleoutputconn); + procedure seteventdriven(const avalue: boolean); + protected + foutput: tdoubleoutputconn; + foutputpo: pdouble; + feventdriven: boolean; + function getoutputar: outputconnarty; override; + procedure initmodel; override; + property eventdriven: boolean read feventdriven write seteventdriven; + public + constructor create(aowner: tcomponent); override; + property output: tdoubleoutputconn read foutput write setoutput; + published + end; + + tdoublesiginoutcomp = class(tdoublesigoutcomp) + private + procedure setinput(const avalue: tdoubleinputconn); + protected + finput: tdoubleinputconn; + finputpo: psigvaluety; + function getinputar: inputconnarty; override; + public + constructor create(aowner: tcomponent); override; + published + property input: tdoubleinputconn read finput write setinput; + end; + + tsigconnector = class(tdoublesiginoutcomp) + protected + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + end; + + ttrigconnector = class(tsigconnector) + public + constructor create(aowner: tcomponent); override; + end; + + tsigeventconnector = class(tdoublesigcomp) + end; + + sigwavetableoptionty = (siwto_intpol); + sigwavetableoptionsty = set of sigwavetableoptionty; + + tsigwavetable = class(tdoublesigoutcomp) + private + ffrequency: tdoubleinputconn; + ffrequfact: tdoubleinputconn; + fphase: tdoubleinputconn; + famplitude: tdoubleinputconn; + ftable: doublearty; + ftablelength: integer; + ftime: double; + ffrequencypo: psigvaluety; + ffrequfactpo: psigvaluety; + fphasepo: psigvaluety; + famplitudepo: psigvaluety; + foninittable: siginbursteventty; + foptions: sigwavetableoptionsty; + fmaster: tsigwavetable; + procedure setfrequency(const avalue: tdoubleinputconn); + procedure setfrequfact(const avalue: tdoubleinputconn); + procedure setphase(const avalue: tdoubleinputconn); + procedure setamplitude(const avalue: tdoubleinputconn); + procedure settable(const avalue: doublearty); + procedure setoptions(const avalue: sigwavetableoptionsty); + procedure setmaster(const avalue: tsigwavetable); + protected + procedure checktable; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure sighandlerintpol(const ainfo: psighandlerinfoty); + procedure objectevent(const sender: tobject; const event: objecteventty); override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure initmodel; override; + function getinputar: inputconnarty; override; + function getzcount: integer; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property table: doublearty read ftable write settable; + published + property master: tsigwavetable read fmaster write setmaster; + property frequency: tdoubleinputconn read ffrequency write setfrequency; + property frequfact: tdoubleinputconn read ffrequfact write setfrequfact; + property phase: tdoubleinputconn read fphase write setphase; + property amplitude: tdoubleinputconn read famplitude write setamplitude; + property oninittable: siginbursteventty read foninittable write foninittable; + property options: sigwavetableoptionsty read foptions + write setoptions default []; + end; + + functionnodety = record + xend: double; + offs: double; + ramp: double; + end; + functionnodearty = array of functionnodety; + functionsegmentty = record + defaultnode: functionnodety; + nodes: functionnodearty; + end; + pfunctionsegmentty = ^functionsegmentty; + functionsegmentsty = array[0..functionsegmentcount-1] of functionsegmentty; + + tsigfuncttable = class(tsigmultiinpout) + private + famplitude: tdoubleinputconn; + foninittable: sigincomplexbursteventty; + ftable: complexarty; + fsegments: functionsegmentsty; + finpmin: double; + finpmax: double; + finpfact: double; //map input value to segmentindex + famplitudepo: psigvaluety; + fmaster: tsigfuncttable; + procedure setamplitude(const avalue: tdoubleinputconn); + procedure settable(const avalue: complexarty); + procedure setmaster(const avalue: tsigfuncttable); + protected + procedure checktable; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure objectevent(const sender: tobject; const event: objecteventty); override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure initmodel; override; + function getinputar: inputconnarty; override; + function getzcount: integer; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property table: complexarty read ftable write settable; + //must be ordered by re values + published + property master: tsigfuncttable read fmaster write setmaster; + property amplitude: tdoubleinputconn read famplitude write setamplitude; + property oninittable: sigincomplexbursteventty read foninittable + write foninittable; + end; + + tsigmult = class(tsigmultiinpout) + protected +// procedure processinout(const acount: integer; +// var ainp: doublepoarty; var aoutp: pdouble); override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + end; + + sigenveloperangeoptionty = (sero_exp,sero_mix); + sigenveloperangeoptionsty = set of sigenveloperangeoptionty; + + sigenvelopeoptionty = (seo_eventoutput,seo_negtrig,seo_nozero); + sigenvelopeoptionsty = set of sigenvelopeoptionty; + envproginfoty = record + startval: double; + ramp: double; + starttime: integer; + endtime: integer; + offset,scale: double; + isexp: boolean; + maxeventdelay: integer; + end; + envproginfoarty = array of envproginfoty; + + envelopeinfoty = record + floopstart: real; + floopstartindex: integer; + floopendindex: integer; + freleasestart: real; + fattack_values: complexarty; + attack_valuespo: pcomplexarty; + fdecay_values: complexarty; + decay_valuespo: pcomplexarty; + frelease_values: complexarty; + release_valuespo: pcomplexarty; + fprog: envproginfoarty; + findex: integer; + findexhigh: integer; + fdest: double; + + fcurrval: double; + fcurrvalbefore: double; + fcurrisexp: boolean; + fattackval: double; + fattackramp: double; + freleaseindex: integer; + freleaseval: double; + freleaseramp: double; + floopindex: integer; + floopval: double; + floopramp: double; + end; + + tsigenvelope = class(tdoublesigoutcomp) + private + ftrigger: tchangedoubleinputconn; + famplitudepo: psigvaluety; + fmixpo: psigvaluety; + + fhasmix: boolean; + ftime: integer; + foptions: sigenvelopeoptionsty; + ftimescale: real; +// fscale: real; +// foffset: real; + fmin: real; + fmax: real; + finfos: array [0..1] of envelopeinfoty; + feventthreshold: real; + + fattack_options: sigenveloperangeoptionsty; + fdecay_options: sigenveloperangeoptionsty; + frelease_options: sigenveloperangeoptionsty; + fmaster: tsigenvelope; + famplitude: tdoubleinputconn; + fmix: tlimitinputconn; + fattack_maxeventtime: real; + fdecay_maxeventtime: real; + frelease_maxeventtime: real; + function getattack_values(const index: integer): complexarty; + procedure setattack_values(const index: integer; const avalue: complexarty); + function getdecay_values(const index: integer): complexarty; + procedure setdecay_values(const index: integer; const avalue: complexarty); + function getrelease_values(const index: integer): complexarty; + procedure setrelease_values(const index: integer; const avalue: complexarty); + function getloopstart(const index: integer): real; + procedure setloopstart(const index: integer; const avalue: real); + + procedure settrigger(const avalue: tchangedoubleinputconn); + procedure setmin(const avalue: real); + procedure setmax(const avalue: real); + procedure setoptions(const avalue: sigenvelopeoptionsty); + procedure setattack_options(const avalue: sigenveloperangeoptionsty); + procedure setdecay_options(const avalue: sigenveloperangeoptionsty); + procedure setrelease_options(const avalue: sigenveloperangeoptionsty); + procedure setmaster(const avalue: tsigenvelope); + procedure setamplitude(const avalue: tdoubleinputconn); + procedure dosync; + procedure setmix(const avalue: tlimitinputconn); + procedure setsubsampling(avalue: integer); + protected + fattackpending: boolean; + freleasepending: boolean; + ffinished: boolean; + fsubsampling: integer; + fsamplecount: integer; + feventtime: integer; + fmaxeventdelay: integer; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure updatevalues(var ainfo: envelopeinfoty); + procedure updatevalueindex(const aindex: integer); + procedure updatevaluesx; + + procedure objectevent(const sender: tobject; const event: objecteventty); override; + procedure initmodel; override; + function getinputar: inputconnarty; override; + function getzcount: integer; override; + function gethandler: sighandlerprocty; override; + procedure dotriggerchange(const sender: tobject); + procedure update; override; + procedure lintoexp(var avalue: double); + procedure exptolin(var avalue: double); + procedure checkindex(const index: integer); + function getsigoptions: sigclientoptionsty; override; + public + constructor create(aowner: tcomponent); override; + procedure start; + procedure stop; + property attack_values[const index: integer]: complexarty + read getattack_values write setattack_values; + property decay_values[const index: integer]: complexarty + read getdecay_values write setdecay_values; + property release_values[const index: integer]: complexarty + read getrelease_values write setrelease_values; + property loopstart[const index: integer]: real + read getloopstart write setloopstart; + //<0 -> inactive + published + property master: tsigenvelope read fmaster write setmaster; + property trigger: tchangedoubleinputconn read ftrigger write settrigger; + //1 -> start, -1 -> stop + property amplitude: tdoubleinputconn read famplitude write setamplitude; + property mix: tlimitinputconn read fmix write setmix; + property options: sigenvelopeoptionsty read foptions + write setoptions default []; + property timescale: real read ftimescale write ftimescale; //default 1s + property subsampling: integer read fsubsampling write setsubsampling + default defaultenvelopesubsampling; + property min: real read fmin write setmin; + property max: real read fmax write setmax; + property eventthreshold: real read feventthreshold write feventthreshold; + property attack_options: sigenveloperangeoptionsty read fattack_options + write setattack_options default []; + property attack_maxeventtime: real read fattack_maxeventtime + write fattack_maxeventtime; //default 0 + property decay_options: sigenveloperangeoptionsty read fdecay_options + write setdecay_options default [sero_exp]; + property decay_maxeventtime: real read fdecay_maxeventtime + write fdecay_maxeventtime; //default 0 + property release_options: sigenveloperangeoptionsty read frelease_options + write setrelease_options default [sero_exp]; + property release_maxeventtime: real read frelease_maxeventtime + write frelease_maxeventtime; //default 0 + end; + + sigcontrollerstatety = (scs_modelvalid,scs_hastick); + sigcontrollerstatesty = set of sigcontrollerstatety; + + tsiginfohash = class(tpointerptruinthashdatalist) + end; + + beforestepeventty = procedure(const sender: tsigcontroller; + var acount: integer; var handled: boolean) of object; + afterstepeventty = procedure(const sender: tsigcontroller; + const acount: integer) of object; + sigcontrolleroptionty = (sico_freerun,sico_autorun); + sigcontrolleroptionsty = set of sigcontrolleroptionty; + + tsigcontroller = class(tmsecomponent) + private + finphash: tsiginfohash; + foutphash: tsiginfohash; +// fvaluedummy: double; + fmutex: mutexty; + flockcount: integer; + flockapplocks: integer; + fticktime: integer; + ftickdiv: integer; + fonbeforetick: notifyeventty; + fonaftertick: notifyeventty; + fonbeforestep: beforestepeventty; + fonbeforeupdatemodel: notifyeventty; + fonafterupdatemodel: notifyeventty; + fonafterstep: afterstepeventty; + fsamplefrequ: real; + foptions: sigcontrolleroptionsty; + fstepcount: integer; + ftimer: tsimpletimer; + procedure settickdiv(const avalue: integer); + procedure setonbeforetick(const avalue: notifyeventty); + procedure setonaftertick(const avalue: notifyeventty); + procedure setoptions(const avalue: sigcontrolleroptionsty); + procedure setsamplefrequ(const avalue: real); + function getfreerun: boolean; + procedure setfreerun(const avalue: boolean); + function getautorun: boolean; + procedure setautorun(const avalue: boolean); + procedure setstepcount(const avalue: integer); + protected + fstate: sigcontrollerstatesty; + fclients: sigclientintfarty; + fticks: proceventarty; + finfos: siginfoarty; + finputnodes: siginfopoarty; +// foutputnodes: siginfopoarty; + fexecinfo: sighandlernodeinfoarty; + fexechigh: integer; + {$ifdef mse_debugsignal} + procedure debugnodeinfo(const atext: string; const anode: psiginfoty); + procedure debugpointer(const atext: string; const apointer: pointer); + {$endif} + procedure addclient(const aintf: isigclient); + procedure removeclient(const aintf: isigclient); + procedure updatemodel; + function findinplink(const dest,source: psiginfoty): integer; + procedure internalstep; + procedure loaded; override; + function findinp(const aconn: tsigconn): psiginfoty; + function findoutp(const aconn: tsigconn): psiginfoty; + procedure internalexecevent(const ainfopo: psiginfoty); + procedure dispatcheventoutput(const ainfopo: psiginfoty); + procedure execevent(const aintf: isigclient); //must be locked + procedure checktick; + procedure dotick; + function getnodenamepath(const aintf: isigclient): string; + procedure checkoptions(); + procedure stopautorun; + procedure doidle(var again: boolean); + procedure doautotick(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure lockapplication; //releases controller lock, can not be nested + //call from locked signal thread only + procedure unlockapplication;//acquires controller lock + procedure modelchange; + procedure checkmodel; + procedure step(acount: integer=1); + procedure clear; + procedure lock; + procedure unlock; + property freerun: boolean read getfreerun write setfreerun; + property autorun: boolean read getautorun write setautorun; + published + property options: sigcontrolleroptionsty read foptions + write setoptions default []; + property stepcount: integer read fstepcount + write setstepcount default defaultstepcount; + property samplefrequ: real read fsamplefrequ write setsamplefrequ; + //default 44100 + property tickdiv: integer read ftickdiv write settickdiv + default defaulttickdiv; + property onbeforetick: notifyeventty read fonbeforetick + write setonbeforetick; + property onaftertick: notifyeventty read fonaftertick + write setonaftertick; + property onbeforestep: beforestepeventty read fonbeforestep + write fonbeforestep; + property onafterstep: afterstepeventty read fonafterstep + write fonafterstep; + + property onbeforeupdatemodel: notifyeventty read fonbeforeupdatemodel + write fonbeforeupdatemodel; //application.locked + property onafterupdatemodel: notifyeventty read fonafterupdatemodel + write fonafterupdatemodel; //application.locked + end; + +procedure createsigbuffer(var abuffer: doublearty; const asize: integer); +procedure createsigarray(out abuffer: doublearty; const asize: integer); +procedure setsourceconn(const sender: tmsecomponent; + const avalue: tdoubleoutputconn; var dest: tdoubleoutputconn); +procedure setsigcontroller(const linker: tobjectlinker; + const intf: isigclient; + const source: tsigcontroller; var dest: tsigcontroller); +procedure initscale(const amin,amax: double; const aoptions: valuescaleoptionsty; + out ainfo: doublescaleinfoty); +procedure updatescale(var ainfo: doublescaleinfoty); +function scalevalue(const ainfo: doublescaleinfoty): double; + +implementation +uses + sysutils,mseformatstr,msesysutils,msesysintf1,mseapplication,msearrayutils, + msesys,msebits; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tmsecomponent1 = class(tmsecomponent); + +procedure initscale(const amin,amax: double; const aoptions: valuescaleoptionsty; + out ainfo: doublescaleinfoty); +begin + with ainfo do begin + min:= amin; + max:= amax; + options:= aoptions; + updatescale(ainfo); + end; +end; + +procedure updatescale(var ainfo: doublescaleinfoty); +begin + with ainfo do begin + if (vso_exp in options) and (min > 0) and (max > 0) then begin + offset:= ln(min); + gain:= ln(max)-ln(min); + end + else begin + offset:= min; + gain:= max-min; + end; + end; +end; + +function scalevalue(const ainfo: doublescaleinfoty): double; +begin + with ainfo do begin + if (vso_null in options) and (value <= 0) then begin + result:= 0; + end + else begin + result:= value*gain+offset; + if vso_exp in options then begin + result:= exp(result); + end; + end; + end; +end; + +procedure createsigbuffer(var abuffer: doublearty; const asize: integer); +begin + if (length(abuffer) < asize) or + (psizeint(pchar(pointer(abuffer))-2*sizeof(sizeint))^ > 1) then begin + abuffer:= nil; + allocuninitedarray(asize,sizeof(double),abuffer); + end + else begin + setlength(abuffer,asize); + end; +end; + +procedure createsigarray(out abuffer: doublearty; const asize: integer); +begin + abuffer:= nil; + allocuninitedarray(asize,sizeof(double),abuffer); +end; + +procedure setsourceconn(const sender: tmsecomponent; + const avalue: tdoubleoutputconn; var dest: tdoubleoutputconn); +begin + if dest <> nil then begin + if csdestroying in dest.componentstate then begin + dest.fdestinations:= nil; + end + else begin + removeitem(pointerarty(dest.fdestinations),sender); + end; + end; + tmsecomponent1(sender).setlinkedvar(avalue,tmsecomponent(dest)); + if dest <> nil then begin + additem(pointerarty(dest.fdestinations),sender); + end; +end; + +{ trealcoeff } + +constructor trealcoeff.create(const aowner: tcustomsigcomp); +begin + fowner:= aowner; + inherited create; +end; + +procedure trealcoeff.doitemchange(const aindex: integer); +begin + fowner.coeffchanged(self,aindex); + inherited; +end; + +{ tcomplexcoeff } + +constructor tcomplexcoeff.create(const aowner: tcustomsigcomp); +begin + fowner:= aowner; + inherited create; +end; + +procedure tcomplexcoeff.doitemchange(const aindex: integer); +begin + fowner.coeffchanged(self,aindex); + inherited; +end; + +{ tcustomsigcomp } + +procedure tcustomsigcomp.coeffchanged(const sender: tdatalist; + const aindex: integer); +begin + //dummy +end; + +procedure tcustomsigcomp.update; +begin + //dummy +end; + +procedure tcustomsigcomp.beginupdate; +begin + inc(fupdating); +end; + +procedure tcustomsigcomp.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + update; + end; +end; + +{ tdoublconn } + +constructor tdoubleconn.create(const aowner: tcomponent; + const asigintf: isigclient); +begin + fsigintf:= asigintf; + inherited create(aowner); + setsubcomponent(true); +end; + +//{$ifndef FPC} +function tdoubleconn.getcontroller: tsigcontroller; +begin + result:= fsigintf.getsigcontroller; +end; + +procedure tdoubleconn.lock; +var + cont1: tsigcontroller; +begin + cont1:= fsigintf.getsigcontroller; + if cont1 <> nil then begin + cont1.lock; + end; +end; + +procedure tdoubleconn.unlock; +var + cont1: tsigcontroller; +begin + cont1:= fsigintf.getsigcontroller; + if cont1 <> nil then begin + cont1.unlock; + end; +end; +//{$endif} + +{ tdoubleoutputconn } + +constructor tdoubleoutputconn.create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); +begin + inherited create(aowner,asigintf); + if aeventdriven then begin + include(fstate,ocs_eventdriven); + end; + include (fmsecomponentstate,cs_subcompref); + name:= 'output'; +end; + +function tdoubleoutputconn.geteventdriven: boolean; +begin + result:= ocs_eventdriven in fstate; +end; + +procedure tdoubleoutputconn.seteventdriven(const avalue: boolean); +begin + if avalue then begin + include(fstate,ocs_eventdriven); + end + else begin + exclude(fstate,ocs_eventdriven); + end; +end; +{ +procedure tdoubleoutputconn.setsig1(var asource: doublearty); +var + int1: integer; +begin + int1:= high(fdestinations); + if int1 = 0 then begin + fdestinations[0].setsig1(asource); + end + else begin + for int1:= 0 to int1 do begin + fdestinations[int1].setsig(asource); + end; + end; +end; + +procedure tdoubleoutputconn.setsig(const asource: doublearty); +var + int1: integer; +begin + for int1:= 0 to high(fdestinations) do begin + fdestinations[int1].setsig(asource); + end; +end; +} +{ tdoubleinputconn } + +constructor tdoubleinputconn.create(const aowner: tcomponent; + const asigintf: isigclient); +begin + fgain:= 1; + fmin:= emptyreal; + fmax:= emptyreal; + fexpstart:= emptyreal; + fexpend:= emptyreal; + fv.changed:= siginchangeresetflags; + inherited; + name:= 'input'; +end; + +destructor tdoubleinputconn.destroy; +begin + source:= nil; + inherited; +end; + +procedure tdoubleinputconn.setsource(const avalue: tdoubleoutputconn); +begin + if fsource <> avalue then begin + setsourceconn(self,avalue,fsource); + fsigintf.modelchange; + end; +end; + +procedure tdoubleinputconn.setoffset(const avalue: double); +begin + lock; + foffset:= avalue; + unlock; +end; + +procedure tdoubleinputconn.setgain(const avalue: double); +begin + lock; + fgain:= avalue; + unlock; +end; + +procedure tdoubleinputconn.setvalue(const avalue: double); +begin + lock; + fv.value:= avalue; + include(fv.changed,sic_value); + unlock; +end; + +procedure tdoubleinputconn.setmin(const avalue: realty); +begin + lock; + fmin:= avalue; + unlock; +end; + +procedure tdoubleinputconn.setmax(const avalue: realty); +begin + lock; + fmax:= avalue; + unlock; +end; + +procedure tdoubleinputconn.setexpstart(const avalue: realty); +begin + lock; + fexpstart:= avalue; + unlock; +end; + +procedure tdoubleinputconn.setexpend(const avalue: realty); +begin + lock; + fexpend:= avalue; + unlock; +end; +{ +procedure tdoubleinputconn.setoptions(const avalue: siginpoptionsty); +begin + lock; + foptions:= avalue; + unlock; +end; +} +{ +procedure tdoubleinputconn.setsig1(var asource: doublearty); +begin + fowner.setsig1(self,asource); +end; + +procedure tdoubleinputconn.setsig(const asource: doublearty); +begin + fowner.setsig(self,asource); +end; +} +{ tdoublesigcomp } + +constructor tdoublesigcomp.create(aowner: tcomponent); +begin + inherited; +end; + +destructor tdoublesigcomp.destroy; +begin + controller:= nil; + clear; + inherited; +end; + +procedure tdoublesigcomp.clear; +begin + //dummy +end; +(* +procedure tdoublesigcomp.setsig1(const sender: tdoubleinputconn; + var asource: doublearty); +begin + //dummy +end; + +procedure tdoublesigcomp.setsig(const sender: tdoubleinputconn; + const asource: doublearty); +begin + //dummy +end; +*) +procedure setsigcontroller(const linker: tobjectlinker; + const intf: isigclient; + const source: tsigcontroller; var dest: tsigcontroller); +begin + if dest <> nil then begin + dest.removeclient(intf); + end; + linker.setlinkedvar(intf,source,tmsecomponent(dest)); + if dest <> nil then begin + dest.addclient(intf); + end; +end; + +procedure tdoublesigcomp.setcontroller(const avalue: tsigcontroller); +begin + setsigcontroller(getobjectlinker,isigclient(self),avalue,fcontroller); +end; + +procedure tdoublesigcomp.modelchange; +begin + if ([csdestroying,csloading]*componentstate = []) then begin + if (fcontroller <> nil) then begin + if ([csdestroying,csloading]*fcontroller.componentstate = []) then begin + fcontroller.lock; + fcontroller.modelchange; + fcontroller.unlock; + end; + end + end; +end; + +function tdoublesigcomp.getinputar: inputconnarty; +begin + result:= nil; +end; + +function tdoublesigcomp.getoutputar: outputconnarty; +begin + result:= nil; +end; + +procedure tdoublesigcomp.loaded; +begin + inherited; + modelchange; + update; +end; + +procedure tdoublesigcomp.initmodel; +begin + //dummy +end; + +function tdoublesigcomp.getzcount: integer; +begin + result:= 0; +end; + +function tdoublesigcomp.getsigcontroller: tsigcontroller; +begin + result:= fcontroller; +end; + +procedure tdoublesigcomp.lock; +begin + if fcontroller <> nil then begin + fcontroller.lock; + end; +end; + +procedure tdoublesigcomp.unlock; +begin + if fcontroller <> nil then begin + fcontroller.unlock; + end; +end; + +function tdoublesigcomp.getsigclientinfopo: psigclientinfoty; +begin + result:= @fsigclientinfo; +end; + +procedure tdoublesigcomp.sigtick; +begin + //dummy +end; + +function tdoublesigcomp.getsigoptions: sigclientoptionsty; +begin + result:= []; +end; + +procedure tdoublesigcomp.lockapplication; +begin + if fcontroller <> nil then begin + fcontroller.lockapplication; + end; +end; + +procedure tdoublesigcomp.unlockapplication; +begin + if fcontroller <> nil then begin + fcontroller.unlockapplication; + end; +end; + +{ tdoublezcomp } + +constructor tdoublezcomp.create(aowner: tcomponent); +begin + fzhigh:= -1; + finput:= tdoubleinputconn.create(self,isigclient(self)); + foutput:= tdoubleoutputconn.create(self,isigclient(self),false); + inherited; +end; + +destructor tdoublezcomp.destroy; +begin + inherited; +end; + +procedure tdoublezcomp.zcountchanged; +begin + //dummy +end; + +procedure tdoublezcomp.clear; +begin + inherited; + fdoubleinputdata:= nil; + finputindex:= 0; + fillchar(pointer(fdoublez)^,fzcount*sizeof(double),0); + fzindex:= 0; +end; +{ +procedure tdoublezcomp.setsig(const source: doublearty); +begin + if finputindex > high(fdoubleinputdata) then begin + setlength(fdoubleinputdata,finputindex+1); + end; + fdoubleinputdata[finputindex]:= source; + inc(finputindex); +end; + +procedure tdoublezcomp.updatesig(var inout: doublearty); +var + po1,po2: pdouble; +begin + po1:= pointer(inout); + po2:= po1; + processinout(length(inout),po1,po2); +end; + +procedure tdoublezcomp.getsig1(var dest: doublearty); +var + int1,int3: integer; + po1,po2: pdouble; +begin + int3:= 0; + for int1:= 0 to finputindex-1 do begin + int3:= int3 + high(fdoubleinputdata[int1]); + end; + int3:= int3 + finputindex; + createsigbuffer(dest,int3); + po2:= pointer(dest); + for int1:= 0 to finputindex-1 do begin + po1:= pointer(fdoubleinputdata[int1]); + processinout(length(fdoubleinputdata[int1]),po1,po2); + end; + for int1:= 0 to finputindex-1 do begin + fdoubleinputdata[int1]:= nil; + end; + finputindex:= 0; +end; + +function tdoublezcomp.getsig: doublearty; +begin + getsig1(result); +end; + +procedure tdoublezcomp.setsig1(const sender: tdoubleinputconn; + var asource: doublearty); +var + po1,po2: pdouble; +begin + po1:= pointer(asource); + po2:= po1; + processinout(length(asource),po1,po2); + foutput.setsig1(asource); +end; + +procedure tdoublezcomp.setsig(const sender: tdoubleinputconn; + const asource: doublearty); +var + int1: integer; + ar1: doublearty; + po1,po2: pdouble; +begin + int1:= length(asource); + createsigarray(ar1,int1); + po1:= pointer(asource); + po2:= pointer(ar1); + processinout(int1,po1,po2); + foutput.setsig1(ar1); +end; +} +procedure tdoublezcomp.setzcount(const avalue: integer); +begin + if fzcount <> avalue then begin + if avalue < 0 then begin + raise exception.create('Invalid coeffcount.'); + end; + clear; + fzcount:= avalue; + fzhigh:= avalue - 1; + setlength(fdoublez,avalue); + zcountchanged; + end; +end; + +procedure tdoublezcomp.setinput(const avalue: tdoubleinputconn); +begin + finput.assign(avalue); +end; + +procedure tdoublezcomp.setoutput(const avalue: tdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +function tdoublezcomp.getinputar: inputconnarty; +begin + setlength(result,1); + result[0]:= finput; +end; + +function tdoublezcomp.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +procedure tdoublezcomp.initmodel; +begin + inherited; + foutputpo:= @foutput.fvalue; +end; + +function tdoublezcomp.getzcount: integer; +begin + result:= fzcount; +end; + +{ tsigout } + +constructor tsigout.create(aowner: tcomponent); +begin + finput:= tdoubleinputconn.create(self,isigclient(self)); + finputpo:= @finput; + inherited; +end; + +destructor tsigout.destroy; +begin + inherited; +end; + +procedure tsigout.setinput(const avalue: tdoubleinputconn); +begin + finput.assign(avalue); +end; + +function tsigout.getinput: tdoubleinputconn; +begin + result:= finput; +end; +{ +procedure tsigout.setsig1(const sender: tdoubleinputconn; + var asource: doublearty); +begin + foutp:= asource; + if assigned(fonoutput) then begin + fonoutput(self,foutp); + end; +end; + +procedure tsigout.setsig(const sender: tdoubleinputconn; + const asource: doublearty); +begin + foutp:= asource; + if assigned(fonoutput) then begin + fonoutput(self,foutp); + end; +end; +} +function tsigout.getinputar: inputconnarty; +begin + setlength(result,1); + result[0]:= finput; +end; + +function tsigout.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigout.sighandler(const ainfo: psighandlerinfoty); +var + po1: psizeint; +begin + fvalue:= finputpo^.value; + if assigned(fonoutput) then begin + fonoutput(self,fvalue); + end; + if fbuffersize > 0 then begin + if foutpindex = fbuffersize then begin + foutpindex:= 0; + end; + po1:= psizeint(pchar(foutp)-2*sizeof(sizeint)); + if po1^ > 1 then begin //new buffer necessary + dec(po1^); //no thread safety + (* + {$ifdef CPU64} + interlockeddecrement64(po1^); + {$else} + interlockeddecrement(po1^); + {$endif} + if po1^ = 0 then begin + freemem(po1); + end; + *) + getmem(po1,fbuffersize * sizeof(double) + 2 * sizeof(sizeint)); + po1^:= 1; //refcount + inc(po1); + {$ifdef FPC} + po1^:= fbuffersize - 1; //high + {$else} + po1^:= fbuffersize; //count + {$endif} + inc(po1); + if foutpindex > 0 then begin + move(foutp[0],po1^,foutpindex*sizeof(double)); + end; + pointer(foutp):= po1; + end; + foutp[foutpindex]:= fvalue; + inc(foutpindex); + if foutpindex = fbuffersize then begin +// foutpindex:= 0; + if assigned(fonoutputburst) then begin + fonoutputburst(self,realarty(foutp)); + end; + end; + end; +end; + +procedure tsigout.sigoutput1(var adest: doublearty); +var + po1: psizeint; +begin + if foutpindex > 0 then begin + if adest = nil then begin + getmem(po1,foutpindex * sizeof(double) + 2 * sizeof(sizeint)); + po1^:= 1; //referencount; + inc(po1); + {$ifdef FPC} + po1^:= foutpindex-1; //high + {$else} + po1^:= foutpindex; //length + {$endif} + inc(po1); + pointer(adest):= po1; + end + else begin + po1:= psizeint(pchar(adest)-2*sizeof(sizeint)); + if po1^ = 1 then begin + {$ifdef FPC} + if psizeint(pchar(po1)+1*sizeof(sizeint))^ < foutpindex - 1 then begin + {$else} + if psizeint(pchar(po1)+1*sizeof(sizeint))^ < foutpindex then begin + {$endif} + freemem(po1); //new buffer + getmem(po1,foutpindex * sizeof(double) + 2 * sizeof(sizeint)); + po1^:= 1; //referencount; + inc(po1); + {$ifdef FPC} + po1^:= foutpindex-1; //high + {$else} + po1^:= foutpindex; //length + {$endif} + inc(po1); + pointer(adest):= po1; + end + else begin //reduce buffer + {$ifdef FPC} + if psizeint(pchar(po1)+1*sizeof(sizeint))^ > foutpindex - 1 then begin + {$else} + if psizeint(pchar(po1)+1*sizeof(sizeint))^ > foutpindex then begin + {$endif} + reallocmem(po1,foutpindex * sizeof(double) + 2 * sizeof(sizeint)); + pointer(adest):= pchar(po1)+2*sizeof(sizeint); + end; + end; + end + else begin + getmem(po1,foutpindex * sizeof(double) + 2 * sizeof(sizeint)); //new buffer + po1^:= 1; //referencount; + inc(po1); + {$ifdef FPC} + po1^:= foutpindex-1; //high + {$else} + po1^:= foutpindex; //length + {$endif} + inc(po1); + pointer(adest):= po1; + end; + end; + move(foutp[0],adest[0],foutpindex*sizeof(double)); + end + else begin + adest:= nil; + end; +end; + +function tsigout.sigoutput: doublearty; +begin + sigoutput1(result); +end; + +procedure tsigout.setbuffersize(const avalue: integer); +begin + if fbuffersize <> avalue then begin + fbuffersize:= avalue; + clear; + end; +end; + +procedure tsigout.clear; +begin + inherited; + setlength(foutp,fbuffersize); + foutpindex:= 0; +end; + +function tsigout.getvalue: double; +begin + lock; + result:= fvalue; + unlock; +end; + +{ tsigin } + +constructor tsigin.create(aowner: tcomponent); +begin + foutput:= tdoubleoutputconn.create(self,isigclient(self),false); + inherited; +end; + +destructor tsigin.destroy; +begin + inherited; +end; + +procedure tsigin.siginput(const asource: doublearty); +var + int1,int2,int3: integer; + po1: psizeint; +begin + int1:= length(finp); + if int1 = 0 then begin + finp:= asource; + end + else begin + int1:= int1 - finpindex; + if int1 > 0 then begin + setlength(finp,length(finp)); //unique reference + move(finp[finpindex],finp[0],int1*sizeof(double)); + end; + finpindex:= 0; + if asource <> finp then begin + int2:= length(asource); + int3:= int1+int2; + po1:= psizeint(pchar(finp)-2*sizeof(sizeint)); + if po1^ <> 1 then begin + dec(po1^); //no thread safety + getmem(po1,int3*sizeof(double)+2*sizeof(sizeint)); + po1^:= 1; + move(finp[0],(pchar(po1)+2*sizeof(sizeint))^,int1*sizeof(double)); + end + else begin + {$ifdef FPC} + if psizeint(pchar(po1)+sizeof(sizeint))^ <> int3-1 then begin + {$else} + if psizeint(pchar(po1)+sizeof(sizeint))^ <> int3 then begin + {$endif} + reallocmem(po1,int3*sizeof(double)+2*sizeof(sizeint)); + end; + end; + inc(po1); + {$ifdef FPC} + po1^:= int3-1; //high + {$else} + po1^:= int3; //length + {$endif} + inc(po1); + pointer(finp):= po1; + move(asource[0],finp[int1],int2*sizeof(double)); + end; + end; +// foutput.setsig(asource); +end; +{ +procedure tsigin.setsig1(var asource: doublearty); +begin + foutput.setsig1(asource); +end; +} +function tsigin.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +function tsigin.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigin.sighandler(const ainfo: psighandlerinfoty); +begin + if finpindex <= high(finp) then begin + fvalue:= finp[finpindex]; + inc(finpindex); + end + else begin + if assigned(foninputburst) then begin + foninputburst(self,realarty(finp)); + finpindex:= 0; + if finp <> nil then begin + fvalue:= finp[0]; + inc(finpindex); + end; + end; + end; + if assigned(foninput) then begin + foninput(self,real(fvalue)); + end; + foutputpo^:= fvalue; +end; + +procedure tsigin.clear; +begin + inherited; + finp:= nil; + finpindex:= 0; +end; + +procedure tsigin.setvalue(const avalue: double); +begin + lock; + fvalue:= avalue; + unlock; +end; + +procedure tsigin.initmodel; +begin + inherited; + foutputpo:= @foutput.value; +end; + +{ tsigmultiinp } + +constructor tsigmultiinp.create(aowner: tcomponent); +begin +// foutput:= tdoubleoutputconn.create(self); + inherited; + finputs:= tdoubleinpconnarrayprop.create(self); +end; + +destructor tsigmultiinp.destroy; +begin + inherited; + finputs.free; +end; +(* +procedure tsigmultiinp.clear; +//var +// int1: integer; +begin + dar:= nil; + pdar:= nil; +// finpdatacount:= 0; + inherited; + { + for int1:= 0 to high(finputs.fitems) do begin + tdoubleinputconn(finputs.fitems[int1]).fbuffer:= nil; + end; + } +end; +*) + +procedure tsigmultiinp.setinputs(const avalue: tdoubleinpconnarrayprop); +begin + finputs.assign(avalue); +end; + +{ +procedure tsigmultiinp.setsig(const sender: tdoubleinputconn; + const asource: doublearty); +begin + dar:= copy(asource); + setsig1(sender,dar); +end; + +procedure tsigmultiinp.setsig1(const sender: tdoubleinputconn; + var asource: doublearty); +var + int1,int2,int3: integer; + po1: pdouble; +begin +//todo: optimize + stackarray(realarty(asource),realarty(sender.fbuffer)); + if not sender.fhasdata then begin + sender.fhasdata:= true; + inc(finpdatacount); + if finpdatacount >= finputs.count then begin + int2:= bigint; + setlength(pdar,finputs.count); + for int1:= 0 to high(finputs.fitems) do begin + with tdoubleinputconn(finputs.fitems[int1]) do begin + int3:= high(fbuffer); + if int3 < int2 then begin + int2:= int3; + end; + pdar[int1]:= pointer(fbuffer); + end; + end; + inc(int2); +// createsigbuffer(asource,int2); + po1:= pointer(asource); + processinout(int2,pdar,po1); + for int1:= 0 to high(finputs.fitems) do begin + with tdoubleinputconn(finputs.fitems[int1]) do begin + if length(fbuffer) <= int2 then begin + fbuffer:= nil; + fhasdata:= false; + dec(finpdatacount); + end + else begin + move(fbuffer[int2],fbuffer[0],(length(fbuffer)-int2)*sizeof(double)); + end; + end; + end; + foutput.setsig1(asource); + end; + end; +end; +} +function tsigmultiinp.getinputar: inputconnarty; +begin + result:= inputconnarty(finputs.fitems); +end; + +procedure tsigmultiinp.initmodel; +var + int1: integer; +begin + finphigh:= finputs.count-1; + setlength(finps,finphigh+1); + for int1:= 0 to finphigh do begin + finps[int1]:= @tdoubleinputconn(finputs.fitems[int1]).value; + end; +end; + +{ tsigmultiinpout } + +constructor tsigmultiinpout.create(aowner: tcomponent); +begin + foutput:= tdoubleoutputconn.create(self,isigclient(self),false); + inherited; +end; + +procedure tsigmultiinpout.setoutput(const avalue: tdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +function tsigmultiinpout.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +procedure tsigmultiinpout.initmodel; +begin + inherited; + foutputpo:= @foutput.value; +end; + +{ tdoublesigoutcomp } + +constructor tdoublesigoutcomp.create(aowner: tcomponent); +begin + foutput:= tdoubleoutputconn.create(self,isigclient(self),feventdriven); + inherited; +end; + +procedure tdoublesigoutcomp.setoutput(const avalue: tdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +function tdoublesigoutcomp.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +procedure tdoublesigoutcomp.initmodel; +begin + inherited; + foutputpo:= @foutput.value; +end; + +procedure tdoublesigoutcomp.seteventdriven(const avalue: boolean); +begin + if feventdriven <> avalue then begin + feventdriven:= avalue; + foutput.eventdriven:= avalue; + modelchange; + end; +end; + +{ tdoubleinpconnarrayprop } + +constructor tdoubleinpconnarrayprop.create(const asigintf: isigclient); +begin + fsigintf:= asigintf; + inherited create(nil); +end; + +procedure tdoubleinpconnarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tdoubleinputconn.create(nil,fsigintf); +end; + +function tdoubleinpconnarrayprop.getitems(const index: integer): tdoubleinputconn; +begin + result:= tdoubleinputconn(inherited getitems(index)); +end; + +procedure tdoubleinpconnarrayprop.dosizechanged; +begin + inherited; + fsigintf.modelchange; +end; + +class function tdoubleinpconnarrayprop.getitemclasstype: persistentclassty; +begin + result:= tdoubleinputconn; +end; + +{ tdoubleoutconnarrayprop } + +constructor tdoubleoutconnarrayprop.create(const aowner: tcomponent; + const aname: string; const asigintf: isigclient; + const aeventdriven: boolean); +begin + fsigintf:= asigintf; + fowner:= aowner; + fname:= aname; + feventdriven:= aeventdriven; + inherited create(nil); +end; + +procedure tdoubleoutconnarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tdoubleoutputconn.create(fowner,fsigintf,feventdriven); + tdoubleoutputconn(item).name:= fname+inttostr(index); +end; + +function tdoubleoutconnarrayprop.getitems( + const index: integer): tdoubleoutputconn; +begin + result:= tdoubleoutputconn(inherited getitems(index)); +end; + +procedure tdoubleoutconnarrayprop.dosizechanged; +begin + inherited; + fsigintf.modelchange; +end; + +class function tdoubleoutconnarrayprop.getitemclasstype: persistentclassty; +begin + result:= tdoubleoutputconn; +end; + +{ tsigadd } + +function tsigadd.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigadd.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + foutputpo^:= do1; +end; + +{ tsigdelay } + +function tsigdelay.getzcount: integer; +begin + result:= 1; +end; + +function tsigdelay.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigdelay.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + foutputpo^:= fz; + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + fz:= do1; +end; + +procedure tsigdelay.clear; +begin + fz:= 0; +end; + +{ tcustomsigdelay } + +constructor tcustomsigdelay.create(aowner: tcomponent); +begin + fdelay:= 1; + inherited; +end; + +procedure tcustomsigdelay.initmodel; +begin + inherited; + finppo:= 0; + setlength(fz,fdelay); +end; + +procedure tcustomsigdelay.clear; +begin + inherited; + fillchar(fz[0],sizeof(fz[0])*length(fz),0); +end; + +function tcustomsigdelay.getzcount: integer; +begin + result:= fdelay; +end; + +function tcustomsigdelay.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tcustomsigdelay.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; + po1: pdouble; + do1: double; +begin + if fdelay = 0 then begin + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + foutputpo^:= do1; + end + else begin + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + po1:= @fz[finppo]; + foutputpo^:= po1^; + po1^:= do1; + inc(finppo); + if finppo = fdelay then begin + finppo:= 0; + end; + end; +end; + +procedure tcustomsigdelay.setdelay(const avalue: integer); +begin + if fdelay <> avalue then begin + lock; + modelchange; + fdelay:= avalue; + unlock; + end; +end; + +{ tsigdelayvar } + +constructor tsigdelayvar.create(aowner: tcomponent); +begin + inherited; + fdelayinp:= tdoubleinputconn.create(self,isigclient(self)); +end; + +function tsigdelayvar.getdelaymax: integer; +begin + result:= inherited delay; +end; + +procedure tsigdelayvar.setdelaymax(const avalue: integer); +begin + inherited delay:= avalue; +end; + +procedure tsigdelayvar.setdelayinp(const avalue: tdoubleinputconn); +begin + fdelayinp.assign(avalue); +end; + +function tsigdelayvar.getinputar: inputconnarty; +begin + result:= inherited getinputar; + setlength(result,high(result)+2); + result[high(result)]:= fdelayinp; +end; + +function tsigdelayvar.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigdelayvar.sighandler(const ainfo: psighandlerinfoty); +var + int1,int2: integer; + po1: pdouble; + do1: double; +begin + if fdelay = 0 then begin + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + foutputpo^:= do1; + end + else begin + po1:= @fz[finppo]; + po1^:= 0; + for int1:= 0 to finphigh do begin + po1^:= po1^ + finps[int1]^.value; + end; + do1:= fdelayinppo^; + if do1 < 0 then begin + do1:= 0; + end; + if do1 >= fdelay then begin + do1:= fdelay; + end; + int1:= finppo-trunc(do1); + if int1 < 0 then begin + int1:= int1 + fdelay; + end; + if int1 = 0 then begin + int2:= fdelay-1; + end + else begin + int2:= int1-1; + end; + do1:= frac(do1); + foutputpo^:= fz[int1]*(1-do1) + fz[int2]*do1; + inc(finppo); + if finppo = fdelay then begin + finppo:= 0; + end; + end; +end; + +procedure tsigdelayvar.initmodel; +begin + fdelayinppo:= @fdelayinp.value; + inherited; +end; + +{ tsigdelayvar } + +{ tsigmult } +{ +procedure tsigmult.processinout(const acount: integer; var ainp: doublepoarty; + var aoutp: pdouble); +var + int1,int2: integer; + rea1: real; +begin + for int1:= 0 to acount - 1 do begin + rea1:= 1; + for int2:= 0 to high(ainp) do begin + rea1:= rea1 * ainp[int2]^; + inc(ainp[int2]); + end; + aoutp^:= rea1; + inc(aoutp); + end; +end; +} +function tsigmult.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigmult.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + do1:= 1; + for int1:= 0 to finphigh do begin + do1:= do1 * finps[int1]^.value; + end; + foutputpo^:= do1; +end; + +{ tsigcontroller } + +constructor tsigcontroller.create(aowner: tcomponent); +begin + fsamplefrequ:= defaultsamplefrequ; + fstepcount:= defaultstepcount; + ftickdiv:= defaulttickdiv; + syserror(sys_mutexcreate(fmutex),self); + finphash:= tsiginfohash.create; + foutphash:= tsiginfohash.create; + inherited; +end; + +destructor tsigcontroller.destroy; +begin + stopautorun(); + inherited; + finphash.free; + foutphash.free; + sys_mutexdestroy(fmutex); +end; + +procedure tsigcontroller.addclient(const aintf: isigclient); +begin + lock; + adduniqueitem(pointerarty(fclients),pointer(aintf)); + modelchange; + unlock; +end; + +procedure tsigcontroller.removeclient(const aintf: isigclient); +begin + lock; + removeitem(pointerarty(fclients),pointer(aintf)); + modelchange; + unlock; +end; + +procedure tsigcontroller.modelchange; +begin + exclude(fstate,scs_modelvalid); +end; + +function tsigcontroller.findinp(const aconn: tsigconn): psiginfoty; +begin + result:= finphash.find(ptruint(aconn)); +end; + +function tsigcontroller.findoutp(const aconn: tsigconn): psiginfoty; +begin + result:= foutphash.find(ptruint(aconn)); +end; + + {$ifdef mse_debugsignal} +procedure tsigcontroller.debugnodeinfo(const atext: string; + const anode: psiginfoty); +var + str1: string; +begin + if anode = nil then begin + str1:= ''; + end + else begin + str1:= getnodenamepath(anode^.intf) + + ' conncount: '+inttostr(anode^.connectedcount); + end; + debugwriteln(atext+str1); +end; + +procedure tsigcontroller.debugpointer(const atext: string; + const apointer: pointer); +begin + debugwriteln(atext+hextostr(apointer)); +end; +{$endif} + +function tsigcontroller.findinplink(const dest,source: psiginfoty): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(dest^.inputs) do begin + if dest^.inputs[int1].source = source then begin + result:= int1; + break; + end; + end; +end; +//{$checkpointer on} + +procedure tsigcontroller.updatemodel; +{$ifdef mse_debugsignal} +var + indent: string; +{$endif} + + procedure resetchecked; + var + int1,int2: integer; + begin + for int1:= 0 to high(finfos) do begin + with finfos[int1] do begin + exclude(state,sis_checked); + for int2:= 0 to high(inputs) do begin + exclude(inputs[int2].state,ins_checked); + end; + end; + end; + end; //resetchecked + +var + visited: pointerarty; + + procedure checkrecursion(const anode: psiginfoty); + var + int1,int2: integer; + po1: psiginfoty; + visitedbefore: pointerarty; + {$ifdef mse_debugsignal} + indentbefore: string; + {$endif} + begin + {$ifdef mse_debugsignal} + indentbefore:= indent; + indent:= indent+' '; + debugnodeinfo(indent+'node ',anode); + {$endif} + additem(visited,anode); + visitedbefore:= visited; + with anode^ do begin + for int1:= 0 to high(destinations) do begin + visited:= visitedbefore; + po1:= findinp(destinations[int1].destinput); + int2:= findinplink(po1,anode); + if finditem(visited,po1) >= 0 then begin + if zcount = 0 then begin + raise exception.create('No Z-delay in recursion node '+ + getnodenamepath(intf)+ + ' -> '+getnodenamepath(po1^.intf)+'.'); + end + else begin + include(po1^.inputs[int2].state,ins_recursive); + dec(po1^.connectedcount); + end; + end + else begin + include(po1^.inputs[int2].state,ins_checked); + checkrecursion(po1); + end; + end; + end; + visited:= visitedbefore; + {$ifdef mse_debugsignal} + indent:= indentbefore; + {$endif} + end; //checkrecursion + +var + execorder: siginfopoarty; + execindex: integer; + + procedure processcalcorder(const anode: psiginfoty); + var + int1: integer; + po1: psiginfoty; + {$ifdef mse_debugsignal} + indentbefore: string; + {$endif} + begin + {$ifdef mse_debugsignal} + indentbefore:= indent; + indent:= indent+' '; + debugnodeinfo(inttostr(execindex)+indent+'calcnode ',anode); + {$endif} + if execindex > high(execorder) then begin + internalerror('SIG20100916-0'); + end; + execorder[execindex]:= anode; + inc(execindex); + with anode^ do begin + state:= state + [sis_checked,sis_sighandler]; + for int1:= 0 to high(next) do begin + po1:= next[int1]; + {$ifdef mse_debugsignal} + debugnodeinfo(indent+' dest '+booltostr(sis_checked in po1^.state)+' ',po1); + {$endif} + if not (sis_checked in po1^.state) then begin + if not (ins_recursive in po1^.inputs[findinplink(po1,anode)].state) then begin + dec(po1^.connectedcount); + if po1^.connectedcount <= 0 then begin + processcalcorder(po1); + end; + end; + end; + end; + end; + {$ifdef mse_debugsignal} + indent:= indentbefore; + {$endif} + end; //processcalcorder() + + procedure updatesca(const ainput: tdoubleinputconn; var sca: inpscaleinfoty); + var + a,b: double; + begin + sca.offset:= ainput.offset; + sca.gain:= ainput.gain; + sca.hasmin:= not (ainput.min = emptyreal); + sca.hasmax:= not (ainput.max = emptyreal); + sca.isexp:= (ainput.expstart > 0) and (ainput.expend > 0) and + (ainput.expend > ainput.expstart); + if sca.isexp then begin + b:= ln(ainput.expstart); + a:= ln(ainput.expend) - b; + sca.offset:= b+a*sca.offset; + sca.gain:= a*sca.gain; + end; + sca.hasscale:= sca.hasmin or sca.hasmax or sca.isexp or + (sca.offset <> 0) or (sca.gain <> 1); + end; //updatesca() + + procedure initinput(const ainput: tdoubleinputconn); + begin + with ainput do begin + updatesca(ainput,fsca); + fv.changed:= [sic_value]; + end; + end; //initinput() + + procedure updatedestinfo(const ainput: tdoubleinputconn; + const asource: pdouble; var ainfo: destinfoty); + begin + with ainfo do begin + source:= asource; + dest:= @ainput.fv.value; + min:= ainput.min; + max:= ainput.max; + sca:= ainput.fsca; +// updatesca(ainput,sca); + end; + end; //updatedestinfo + + function isopeninput(const ainputs: inputinfoarty): boolean; + var + int1: integer; + begin + result:= true; + for int1:= 0 to high(ainputs) do begin + with ainputs[int1] do begin + if (source <> nil) then begin + result:= false; + break; + end; + end; + end; + end; + + procedure touchnode(const anode: psiginfoty); + var + int1: integer; + begin + with anode^ do begin + include(state,sis_touched); + for int1:= 0 to high(next) do begin + if not (sis_touched in next[int1]^.state) then begin + touchnode(next[int1]); + end; + end; + end; + end; + + function isopenoutput(const aoutputs: outputconnarty): boolean; + var + int1: integer; + begin + result:= true; + for int1:= 0 to high(aoutputs) do begin + with aoutputs[int1] do begin + if not (ocs_eventdriven in fstate) and (fdestinations <> nil) then begin + result:= false; + break; + end; + end; + end; + end; + +var + int1,int2,int3,int4: integer; + po1,po2: psiginfoty; + inputnodecount: integer; + notconnectedcount: integer; +// fulltickcount: integer; +// outputnodecount: integer; +// recursivenodecount: integer; +// ar1,ar2: siginfopoarty; + ar3: inputconnarty; +begin + if assigned(fonbeforeupdatemodel) then begin + application.lock; + try + fonbeforeupdatemodel(self); + finally + application.unlock; + end; + end; + finfos:= nil; + finphash.clear; + foutphash.clear; + fticks:= nil; + finputnodes:= nil; +// foutputnodes:= nil; + fexecinfo:= nil; +// outputnodecount:= 0; + inputnodecount:= 0; + notconnectedcount:= 0; +// fulltickcount:= 0; + setlength(finfos,length(fclients)); +{$ifdef mse_debugsignal} + debugwriteln('**updatemodel '+name); + debugwriteln('*get info'); +{$endif} + + for int1:= 0 to high(fclients) do begin //get basic info + po1:= @finfos[int1]; + po1^.options:= fclients[int1].getsigoptions; + if sco_tick in po1^.options then begin + setlength(fticks,high(fticks)+2); + {$ifdef FPC} + fticks[high(fticks)]:= @fclients[int1].sigtick; + {$else} + fticks[high(fticks)]:= nil;//fclients[int1].sigtick; //todo:!!! + {$endif} + end; + fclients[int1].getsigclientinfopo^.infopo:= po1; + with po1^ do begin + intf:= fclients[int1]; + handler:= intf.gethandler; + intf.initmodel; + intf.clear; + zcount:= intf.getzcount; + {$ifdef mse_debugsignal} + debugwriteln('client '+getnodenamepath(intf)); + {$endif} + ar3:= fclients[int1].getinputar; + setlength(inputs,length(ar3)); + for int2:= 0 to high(ar3) do begin + inputs[int2].input:= ar3[int2]; + end; + outputs:= fclients[int1].getoutputar; + destinations:= nil; + for int2:= 0 to high(inputs) do begin + {$ifdef mse_debugsignal} + debugpointer(' inp ',inputs[int2].input); + {$endif} + finphash.add(ptruint(inputs[int2].input),po1); + initinput(inputs[int2].input); + end; + for int2:= 0 to high(outputs) do begin + {$ifdef mse_debugsignal} + debugpointer(' outp ',outputs[int2]); + {$endif} + foutphash.add(ptruint(outputs[int2]),po1); + with outputs[int2] do begin + if ocs_eventdriven in fstate then begin + include(po1^.state,sis_eventoutput); + end; + int3:= length(po1^.destinations); + setlength(po1^.destinations,int3+length(fdestinations)); + for int4:= 0 to high(fdestinations) do begin + with po1^.destinations[int3+int4] do begin + outputindex:= int2; + destinput:= fdestinations[int4]; + end; + end; +// stackarray(pointerarty(fdestinations),pointerarty(po1^.destinations)); + {$ifdef mse_debugsignal} + for int3:= 0 to high(fdestinations) do begin + debugpointer(' dest ',fdestinations[int3]); + end; + {$endif} + end; + end; + end; + end; + +{$ifdef mse_debugsignal} + debugwriteln('*link items'); +{$endif} + for int1:= 0 to high(fclients) do begin //link the items + po1:= @finfos[int1]; + with po1^ do begin + if not (sis_checked in state) then begin + {$ifdef mse_debugsignal} + debugnodeinfo('node ',po1); + {$endif} + include(state,sis_checked); + for int2:= 0 to high(outputs) do begin + with outputs[int2] do begin + for int3:= 0 to high(fdestinations) do begin + {$ifdef mse_debugsignal} + debugpointer('lookup inp ',fdestinations[int3]); + {$endif} + po2:= findinp(fdestinations[int3]); + {$ifdef mse_debugsignal} + debugnodeinfo(' ',po2); + {$endif} + if po2 = nil then begin + raise exception.create( + 'Destination not found. Controller: '+self.name+ ', Node: '+ + getnodenamepath(fclients[int1]) + + ', Dest: '+fdestinations[int3].fsigintf.getcomponent.name+'.'); + end; + if not (ocs_eventdriven in fstate) then begin + if finditem(pointerarty(po2^.prev),po1) < 0 then begin + inc(po2^.connectedcount); + {$ifdef mse_debugsignal} + debugnodeinfo(' new link ',po2); + {$endif} + additem(pointerarty(po2^.prev),po1); + additem(pointerarty(po1^.next),po2); + end; + for int4:= 0 to high(po2^.inputs) do begin + if po2^.inputs[int4].input = fdestinations[int3] then begin + with po2^.inputs[int4] do begin + source:= po1; + include(input.fv.changed,sic_stream); + end; + break; + end; + end; + end; + end; + end; + end; + end; + end; + end; + +{$ifdef mse_debugsignal} + debugwriteln('*check input/output'); +{$endif} + for int1:= 0 to high(fclients) do begin + po1:= @finfos[int1]; + with po1^ do begin +// state:= []; + if not isopenoutput(outputs) then begin + include(state,sis_output); + end + else begin + {$ifdef mse_debugsignal} + debugnodeinfo(' output node ',po1); + {$endif} + end; + if not isopeninput(inputs) then begin + include(state,sis_input); + end + else begin + if sis_output in state then begin + additem(pointerarty(finputnodes),po1,inputnodecount); + touchnode(po1); + {$ifdef mse_debugsignal} + debugnodeinfo(' input node ',po1); + {$endif} + end + else begin + inc(notconnectedcount); + {$ifdef mse_debugsignal} + debugnodeinfo(' not connected node ',po1); + {$endif} + end; + end; + end; + end; + +{$ifdef mse_debugsignal} + debugwriteln('*check event connections'); +{$endif} + for int1:= 0 to high(finfos) do begin + with finfos[int1] do begin + if not (sis_eventchecked in state) then begin + for int2:= 0 to high(outputs) do begin + with outputs[int2] do begin + for int3:= 0 to high(fdestinations) do begin + po2:= findinp(fdestinations[int3]); + if not (sis_input in po2^.state) then begin + {$ifdef mse_debugsignal} + debugnodeinfo('event source ',@finfos[int1]); + debugpointer(' lookup inp ',fdestinations[int3]); + debugnodeinfo(' event ',po2); + {$endif} + if sis_eventchecked in po2^.state then begin + raise exception.create( + 'Recursive event connection: '+self.name+ ', Node: '+ + getnodenamepath(finfos[int1].intf) + + ', Dest: '+getnodenamepath(po2^.intf)+'.'); + end; + adduniqueitem(pointerarty(eventdestinations),po2); + include(po2^.state,sis_eventinput); + include(state,sis_eventchecked); + end; + end; + end; + end; + end; + end; + end; + +{$ifdef mse_debugsignal} + debugwriteln('*check recursive without inputs'); +{$endif} + for int1:= 0 to high(fclients) do begin + po1:= @finfos[int1]; + with po1^ do begin + if state * [sis_input,sis_output,sis_touched,sis_eventchecked] = [sis_output] then begin + additem(pointerarty(finputnodes),po1,inputnodecount); + {$ifdef mse_debugsignal} + debugnodeinfo(' recursive circle start ',po1); + {$endif} + touchnode(po1); + end + else begin + if (state * [sis_input,sis_output,sis_touched] = []) and + (sco_fulltick in options) then begin + include(state,sis_fulltick); + additem(pointerarty(finputnodes),po1,inputnodecount); + dec(notconnectedcount); + {$ifdef mse_debugsignal} + debugnodeinfo(' fulltick ',po1); + {$endif} + touchnode(po1); + end; + end; + end; + end; + + setlength(finputnodes,inputnodecount); + +{$ifdef mse_debugsignal} + debugwriteln('*check recursion'); +{$endif} + + for int1:= 0 to high(finputnodes) do begin //check recursion + {$ifdef mse_debugsignal} + debugnodeinfo('input ',finputnodes[int1]); + {$endif} + if not (sis_fulltick in finputnodes[int1]^.state) then begin + visited:= nil; + checkrecursion(finputnodes[int1]); + end; + end; + +{$ifdef mse_debugsignal} + debugwriteln('*processcalcorder'); +{$endif} + setlength(execorder,length(finfos)); + execindex:= 0; +// resetchecked; + for int1:= 0 to high(finputnodes) do begin + {$ifdef mse_debugsignal} + debugnodeinfo('input ',finputnodes[int1]); + {$endif} + resetchecked; + processcalcorder(finputnodes[int1]); + end; + +{$ifdef mse_debugsignal} + debugwriteln('*execorder '+inttostr(length(execorder))+' '+inttostr(execindex)); + for int1:= 0 to high(execorder) do begin + debugnodeinfo(' ',execorder[int1]); + end; + for int1:= 0 to high(finfos) do begin + po1:= @finfos[int1]; + with po1^ do begin + if connectedcount <> 0 then begin + debugnodeinfo('! '+inttostr(connectedcount)+ ' ',po1); + end; + end; + end; +{$endif} + if execindex+notconnectedcount <> length(execorder) then begin + internalerror('SIG20100916-2'); //unprocessed nodes + end; + setlength(fexecinfo,execindex); + fexechigh:= execindex-1; + for int1:= 0 to high(fexecinfo) do begin + po1:= execorder[int1]; + with fexecinfo[int1] do begin + handler:= po1^.handler; + desthigh:= high(po1^.destinations); +// handlerinfo.dest:= @fvaluedummy; + if length(po1^.destinations) > 0 then begin + setlength(dest,desthigh+1); + for int2:= 0 to desthigh do begin + int3:= po1^.destinations[int2].outputindex; + updatedestinfo(po1^.destinations[int2].destinput, + @po1^.outputs[int3].fvalue,dest[int2]); + end; + end; + (* + handler:= po1^.handler; + desthigh:= high(po1^.destinations)-1; + handlerinfo.dest:= @fvaluedummy; + if length(po1^.destinations) > 0 then begin + int3:= po1^.destinations[0].outputindex; + updatedestinfo(po1^.destinations[0].destinput,handlerinfo.dest,firstdest); + //setup hasscale + if (int3 = 0) and (desthigh < 0) or not firstdest.sca.hasscale then begin + handlerinfo.dest:= @po1^.destinations[0].destinput.fv.value; + end; + if int3 = 0 then begin //setup again with correct dest + updatedestinfo(po1^.destinations[0].destinput,handlerinfo.dest,firstdest); + end + else begin + updatedestinfo(po1^.destinations[0].destinput, + @po1^.outputs[int3].fvalue,firstdest); + end; + + setlength(dest,desthigh+1); + for int2:= 0 to desthigh do begin + int3:= po1^.destinations[int2+1].outputindex; + if int3 > 0 then begin //additional output + updatedestinfo(po1^.destinations[int2+1].destinput, + @po1^.outputs[int3].fvalue,dest[int2]); + end + else begin + updatedestinfo(po1^.destinations[int2+1].destinput,handlerinfo.dest, + dest[int2]); + end; + end; + end; + *) + end; + end; + include(fstate,scs_modelvalid); + clear; + checktick; +{$ifdef mse_debugsignal} + debugwriteln('*execute event start nodes'); +{$endif} + po1:= pointer(finfos); + for int1:= 0 to high(finfos) do begin + if (po1^.state * [sis_eventoutput,sis_eventinput] = [sis_eventoutput]) and + not (sco_fulltick in po1^.options) then begin + {$ifdef mse_debugsignal} + debugnodeinfo(' exec ',po1); + {$endif} + internalexecevent(po1); + end; + inc(po1); + end; + if assigned(fonafterupdatemodel) then begin + application.lock; + try + fonafterupdatemodel(self); + finally + application.unlock; + end; + end; +end; + +//{$checkpointer default} +procedure tsigcontroller.internalstep; +var + int1,int2: integer; + po1: psighandlernodeinfoty; +begin + po1:= pointer(fexecinfo); + for int1:= 0 to fexechigh do begin + po1^.handler(psighandlerinfoty(po1)); + if not po1^.handlerinfo.discard then begin + { + with po1^.firstdest do begin + if sca.hasscale then begin + dest^:= source^*sca.gain+sca.offset; + if sca.isexp then begin + dest^:= exp(dest^); + end; + if sca.hasmin and (dest^ < min) then begin + dest^:= min; + end; + if sca.hasmax and (dest^ > max) then begin + dest^:= max; + end; + end; + end; + } + for int2:= 0 to po1^.desthigh do begin + with po1^.dest[int2] do begin + dest^:= source^; + if sca.hasscale then begin + dest^:= dest^*sca.gain+sca.offset; + if sca.isexp then begin + dest^:= exp(dest^); + end; + if sca.hasmin and (dest^ < min) then begin + dest^:= min; + end; + if sca.hasmax and (dest^ > max) then begin + dest^:= max; + end; + end; + end; + end; + end; + inc(po1); + end; +end; + +procedure tsigcontroller.step(acount: integer); +var + int1: integer; + bo1: boolean; +begin + if not (scs_modelvalid in fstate) then begin + updatemodel; + end; + bo1:= false; + if assigned(fonbeforestep) then begin + fonbeforestep(self,acount,bo1); + end; + if not bo1 then begin + if scs_hastick in fstate then begin + fticktime:= fticktime + acount; + while fticktime > 0 do begin + dotick; + dec(fticktime,ftickdiv); + end; + end; + lock; + try + for int1:= acount-1 downto 0 do begin + internalstep; + end; + finally + unlock; + end; + if assigned(fonafterstep) then begin + fonafterstep(self,acount); + end; + end; +end; + +procedure tsigcontroller.checkmodel; +begin + if not (scs_modelvalid in fstate) then begin + updatemodel; + end; +end; + +procedure tsigcontroller.loaded; +begin + inherited; + modelchange(); + checkoptions(); +end; + +procedure tsigcontroller.clear; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + fclients[int1].clear; + end; +end; + +procedure tsigcontroller.lock; +begin + sys_mutexlock(fmutex); + inc(flockcount); +end; + +procedure tsigcontroller.unlock; +begin + dec(flockcount); + sys_mutexunlock(fmutex); +end; + +procedure tsigcontroller.internalexecevent(const ainfopo: psiginfoty); +var +// po1: psiginfoty; + handlerinfo: sighandlerinfoty; +// do1: double; + int1: integer; +begin + with ainfopo^ do begin + if not (sis_sighandler in state) then begin +// handlerinfo.dest:= @do1; + handler(@handlerinfo); + for int1:= 0 to high(destinations) do begin + with destinations[int1] do begin + with destinput do begin + include(fv.changed,sic_value); + fv.value:= outputs[outputindex].fvalue*fsca.gain+fsca.offset; + if fsca.isexp then begin + fv.value:= exp(fv.value); + end; + if fsca.hasmin and (fv.value < min) then begin + fv.value:= min; + end; + if fsca.hasmax and (fv.value > max) then begin + fv.value:= max; + end; + end; + end; + end; + for int1:= 0 to high(eventdestinations) do begin + internalexecevent(eventdestinations[int1]); + end; + end; + end; +end; + +procedure tsigcontroller.dispatcheventoutput(const ainfopo: psiginfoty); +var +// po1: psiginfoty; +// handlerinfo: sighandlerinfoty; + int1: integer; +begin + with ainfopo^ do begin + for int1:= 0 to high(destinations) do begin + with destinations[int1] do begin + with destinput do begin + include(fv.changed,sic_value); + fv.value:= outputs[outputindex].fvalue*fsca.gain+fsca.offset; + if fsca.isexp then begin + fv.value:= exp(fv.value); + end; + if fsca.hasmin and (fv.value < min) then begin + fv.value:= min; + end; + if fsca.hasmax and (fv.value > max) then begin + fv.value:= max; + end; + end; + end; + end; + for int1:= 0 to high(eventdestinations) do begin + internalexecevent(eventdestinations[int1]); + end; + end; +end; + +procedure tsigcontroller.execevent(const aintf: isigclient); +begin +// lock; + checkmodel; +// try + internalexecevent(aintf.getsigclientinfopo^.infopo); +// finally +// unlock; +// end; +end; + +procedure tsigcontroller.settickdiv(const avalue: integer); +begin + ftickdiv:= avalue; + if ftickdiv <= 0 then begin + ftickdiv:= 0; + end; +end; + +procedure tsigcontroller.checktick; +begin + if (fticks <> nil) or assigned(fonbeforetick) or assigned(fonaftertick) then begin + include(fstate,scs_hastick); + end + else begin + exclude(fstate,scs_hastick); + end; +end; + +procedure tsigcontroller.dotick; +var + int1: integer; +begin + if assigned(fonbeforetick) then begin + fonbeforetick(self); + end; + for int1:= high(fticks) downto 0 do begin + fticks[int1]; + end; + if assigned(fonaftertick) then begin + fonaftertick(self); + end; +end; + +procedure tsigcontroller.setonbeforetick(const avalue: notifyeventty); +begin + fonbeforetick:= avalue; + checktick; +end; + +procedure tsigcontroller.setonaftertick(const avalue: notifyeventty); +begin + fonaftertick:= avalue; + checktick; +end; + +procedure tsigcontroller.lockapplication; +var + int1: integer; +begin + flockapplocks:= flockcount; + for int1:= flockcount - 1 downto 0 do begin + unlock; + end; + application.lock; +end; + +procedure tsigcontroller.unlockapplication; +var + int1: integer; +begin + application.unlock; + for int1:= flockapplocks - 1 downto 0 do begin + lock; + end; +end; + +function tsigcontroller.getnodenamepath(const aintf: isigclient): string; +begin + result:= ownernamepath(aintf.getcomponent); +end; + +procedure tsigcontroller.setoptions(const avalue: sigcontrolleroptionsty); +begin + if foptions <> avalue then begin + foptions:= sigcontrolleroptionsty(setsinglebit(longword(avalue), + longword(foptions),longword([sico_freerun,sico_autorun]))); + if not (csloading in componentstate) then begin + checkoptions(); + end; + end; +end; + +procedure tsigcontroller.setsamplefrequ(const avalue: real); +begin + if fsamplefrequ <> avalue then begin + fsamplefrequ:= avalue; + end; +end; + +procedure tsigcontroller.checkoptions; +begin + stopautorun(); + if not (csdesigning in componentstate) then begin + if (fstepcount > 0) and (fsamplefrequ > 0) then begin + if sico_freerun in foptions then begin + application.registeronidle(@doidle); + end + else begin + if sico_autorun in foptions then begin + ftimer:= tsimpletimer.create(round(1000000.0*fstepcount/fsamplefrequ), + @doautotick,true,[to_leak]); + end; + end; + end; + end; +end; + +function tsigcontroller.getfreerun: boolean; +begin + result:= sico_freerun in options; +end; + +procedure tsigcontroller.setfreerun(const avalue: boolean); +begin + if avalue then begin + options:= options + [sico_freerun]; + end + else begin + options:= options - [sico_freerun]; + end; +end; + +procedure tsigcontroller.stopautorun; +begin + application.unregisteronidle(@doidle); + freeandnil(ftimer); +end; + +function tsigcontroller.getautorun: boolean; +begin + result:= sico_autorun in options; +end; + +procedure tsigcontroller.setautorun(const avalue: boolean); +begin + if avalue then begin + options:= options + [sico_autorun]; + end + else begin + options:= options - [sico_autorun]; + end; +end; + +procedure tsigcontroller.setstepcount(const avalue: integer); +begin + if fstepcount <> avalue then begin + fstepcount:= avalue; + if not (csloading in componentstate) then begin + checkoptions(); + end; + end; +end; + +procedure tsigcontroller.doautotick(const sender: tobject); +begin + step(fstepcount); +end; + +procedure tsigcontroller.doidle(var again: boolean); +begin + step(fstepcount); + again:= true; +end; + +{ tsigwavetable } + +constructor tsigwavetable.create(aowner: tcomponent); +begin + inherited; + ffrequency:= tdoubleinputconn.create(self,isigclient(self)); + ffrequency.name:= 'frequency'; + ffrequency.fv.value:= 0.01; + ffrequfact:= tdoubleinputconn.create(self,isigclient(self)); + ffrequfact.name:= 'frequfact'; + ffrequfact.fv.value:= 1; + fphase:= tdoubleinputconn.create(self,isigclient(self)); + fphase.name:= 'phase'; + famplitude:= tdoubleinputconn.create(self,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitude.fv.value:= 1; +end; + +procedure tsigwavetable.setfrequency(const avalue: tdoubleinputconn); +begin + ffrequency.assign(avalue); +end; + +procedure tsigwavetable.setfrequfact(const avalue: tdoubleinputconn); +begin + ffrequfact.assign(avalue); +end; + +procedure tsigwavetable.setphase(const avalue: tdoubleinputconn); +begin + fphase.assign(avalue); +end; + +procedure tsigwavetable.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +function tsigwavetable.gethandler: sighandlerprocty; +begin + if siwto_intpol in foptions then begin + result:= {$ifdef FPC}@{$endif}sighandlerintpol; + end + else begin + result:= {$ifdef FPC}@{$endif}sighandler; + end; +end; + +procedure tsigwavetable.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; +begin + int1:= trunc((ftime+fphasepo^.value)*ftablelength) mod ftablelength; + if int1 < 0 then begin + int1:= int1 + ftablelength; + end; + foutputpo^:= ftable[int1] * famplitudepo^.value; + ftime:= frac(ftime+ffrequencypo^.value*ffrequfactpo^.value); +end; + +procedure tsigwavetable.sighandlerintpol(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + do1:= (ftime+fphasepo^.value)*ftablelength; + int1:= trunc(do1) mod ftablelength; + if int1 < 0 then begin + int1:= int1 + ftablelength; + end; + foutputpo^:= (ftable[int1] + + (ftable[(int1+1) mod ftablelength] - ftable[int1]) * + ((do1-int1)/ftablelength) + ) * famplitudepo^.value; + ftime:= frac(ftime+ffrequencypo^.value*ffrequfactpo^.value); +end; + + +procedure tsigwavetable.settable(const avalue: doublearty); +begin + ftable:= avalue; + checktable; +end; + +procedure tsigwavetable.clear; +begin + inherited; + lock; + try + if canevent(tmethod(foninittable)) then begin + foninittable(self,realarty(ftable)); + end; + checktable; + finally + unlock; + end; +end; + +procedure tsigwavetable.checktable; +begin + lock; + try + ftime:= 0; + if ftable = nil then begin + setlength(ftable,1); + end; + ftablelength:= length(ftable); + sendchangeevent; + finally + unlock; + end; +end; + +procedure tsigwavetable.initmodel; +begin + ffrequencypo:= @ffrequency.fv; + ffrequfactpo:= @ffrequfact.fv; + fphasepo:= @fphase.fv; + famplitudepo:= @famplitude.fv; + inherited; +end; + +function tsigwavetable.getinputar: inputconnarty; +begin + setlength(result,4); + result[0]:= ffrequency; + result[1]:= ffrequfact; + result[2]:= fphase; + result[3]:= famplitude; +end; + +function tsigwavetable.getzcount: integer; +begin + result:= 1; +end; + +procedure tsigwavetable.setoptions(const avalue: sigwavetableoptionsty); +begin + if avalue <> foptions then begin + foptions:= avalue; + if fcontroller <> nil then begin + fcontroller.modelchange; + end; + end; +end; + +procedure tsigwavetable.setmaster(const avalue: tsigwavetable); +var + tab1: tsigwavetable; +begin + if avalue <> fmaster then begin + tab1:= avalue; + while tab1 <> nil do begin + if tab1 = self then begin + raise exception.create('Recursive master.'); + end; + tab1:= tab1.master; + end; + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fmaster)); + if avalue <> nil then begin + table:= avalue.table; + end; + end; +end; + +procedure tsigwavetable.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_changed) and (sender <> nil) and (sender = master) then begin + table:= master.table; + end; +end; + +{ tsigfuncttable } + +constructor tsigfuncttable.create(aowner: tcomponent); +begin + inherited; + famplitude:= tdoubleinputconn.create(self,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitudepo:= @famplitude.fv; +// finput:= tdoubleinputconn.create(self,isigclient(self)); +// finput.name:= 'input'; +end; +{ +procedure tsigfuncttable.setinput(const avalue: tdoubleinputconn); +begin + finput.assign(avalue); +end; +} +procedure tsigfuncttable.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +function tsigfuncttable.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigfuncttable.initmodel; +begin + inherited; +end; + +function tsigfuncttable.getinputar: inputconnarty; +begin + setlength(result,1); +// result[0]:= finput; + result[0]:= famplitude; + stackarray(pointerarty(inherited getinputar),pointerarty(result)); +end; + +function tsigfuncttable.getzcount: integer; +begin + result:= 1; +end; + +procedure tsigfuncttable.clear; +begin + inherited; + lock; + try + if canevent(tmethod(foninittable)) then begin + foninittable(self,ftable); + end; + checktable; + finally + unlock; + end; +end; + +procedure tsigfuncttable.settable(const avalue: complexarty); +begin + ftable:= avalue; + checktable; +end; + +procedure tsigfuncttable.sighandler(const ainfo: psighandlerinfoty); +var + int1,int2: integer; + do1: double; +begin + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + if do1 <= finpmin then begin + with fsegments[0].defaultnode do begin + foutputpo^:= (offs + do1 * ramp)*famplitudepo^.value; + end; + exit; + end + else begin + if do1 >= finpmax then begin + with fsegments[functionsegmentcount-1] do begin + if nodes <> nil then begin + with nodes[high(nodes)] do begin + foutputpo^:= (offs + do1 * ramp)*famplitudepo^.value; + end; + end + else begin + with defaultnode do begin + foutputpo^:= (offs + do1 * ramp)*famplitudepo^.value; + end; + end; + end; + exit; + end + else begin + int1:= trunc((do1-finpmin)*finpfact); + end; + end; + with fsegments[int1] do begin + if do1 <= defaultnode.xend then begin + with defaultnode do begin + foutputpo^:= (offs + do1 * ramp)*famplitudepo^.value; + end; + end + else begin + for int2:= 0 to high(nodes) do begin + with nodes[int2] do begin + if do1 <= xend then begin + foutputpo^:= (offs + do1 * ramp)*famplitudepo^.value; + break; + end; + end; + end; + end; + end; +end; + +procedure tsigfuncttable.checktable; + procedure calc(const index: integer; out node: functionnodety); + var + den1: double; + begin + if index = high(ftable) then begin + if index = 0 then begin + den1:= 0; + end + else begin + den1:= ftable[index].re - ftable[index-1].re; + end; + end + else begin + den1:= ftable[index+1].re - ftable[index].re; + end; + with node do begin + if index >= high(ftable) then begin + xend:= bigreal; + end + else begin + xend:= ftable[index+1].re; + end; + if den1 = 0 then begin + offs:= ftable[index].im; + ramp:= 0; + end + else begin + if index = high(ftable) then begin + ramp:= (ftable[index].im - ftable[index-1].im)/den1; + end + else begin + ramp:= (ftable[index+1].im - ftable[index].im)/den1; + end; + offs:= ftable[index].im - ftable[index].re*ramp; + end; + end; + end; +var + int1,int2: integer; + ar1: booleanarty; + po1: pfunctionsegmentty; +begin + lock; + try + finalize(fsegments); + fillchar(fsegments,sizeof(fsegments),0); + finpmin:= 0; + finpmax:= 0; + finpfact:= 0; + if high(ftable) >= 0 then begin + finpmin:= bigreal; + finpmax:= -bigreal; + for int1:= 0 to high(ftable) do begin + with ftable[int1] do begin + if (int1 > 0) and (re < ftable[int1-1].re) then begin + raise exception.create('Invalid table order'); + end; + if re < finpmin then begin + finpmin:= re; + end; + if re > finpmax then begin + finpmax:= re; + end; + end; + end; + finpfact:= finpmax-finpmin; + if finpfact > 0 then begin + finpfact:= functionsegmentcount/finpfact; + end + else begin + finpfact:= 0; + end; + setlength(ar1,functionsegmentcount); + for int1:= 0 to high(ftable) do begin + int2:= trunc((ftable[int1].re-finpmin)*finpfact); + if int2 >= functionsegmentcount then begin + int2:= functionsegmentcount-1; + end; + if int2 < 0 then begin + int2:= 0; + end; + with fsegments[int2] do begin + if ar1[int2] or (int2 > 0) then begin //multiple nodes + setlength(nodes,high(nodes)+2); + calc(int1,nodes[high(nodes)]); + end + else begin + calc(int1,defaultnode); + end; + ar1[int2]:= true; + end; + end; + po1:= @fsegments[0]; + for int1:= 1 to high(fsegments) do begin + if po1^.nodes = nil then begin + fsegments[int1].defaultnode:= po1^.defaultnode; + end + else begin + fsegments[int1].defaultnode:= po1^.nodes[high(po1^.nodes)]; + end; + inc(po1); + end; + end; + sendchangeevent; + finally + unlock; + end; +end; + +procedure tsigfuncttable.setmaster(const avalue: tsigfuncttable); +var + tab1: tsigfuncttable; +begin + if avalue <> fmaster then begin + tab1:= avalue; + while tab1 <> nil do begin + if tab1 = self then begin + raise exception.create('Recursive master.'); + end; + tab1:= tab1.master; + end; + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fmaster)); + if avalue <> nil then begin + table:= avalue.table; + end; + end; +end; + +procedure tsigfuncttable.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_changed) and (sender <> nil) and (sender = master) then begin + table:= master.table; + end; +end; + +{ tsigenvelope } + +constructor tsigenvelope.create(aowner: tcomponent); + + procedure initinfo(var ainfo: envelopeinfoty); + begin + with ainfo do begin + freleasestart:= 1; + ftimescale:= 1; + floopstart:= -1; + end; + end; //initinfo() + +begin +// feventdriven:= true; + fsubsampling:= defaultenvelopesubsampling; + fmin:= 0.001; + fmax:= 1; + feventthreshold:= 0.1; +// fdecay_maxeventtime:= 0.02; + initinfo(finfos[0]); + initinfo(finfos[1]); + fdecay_options:= [sero_exp]; + frelease_options:= [sero_exp]; + inherited; + ftrigger:= tchangedoubleinputconn.create(self,isigclient(self), + {$ifdef fpc}@{$endif}dotriggerchange); + ftrigger.name:= 'trigger'; + famplitude:= tdoubleinputconn.create(self,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitude.value:= 1; + fmix:= tlimitinputconn.create(self,isigclient(self)); + fmix.name:= 'mix'; +end; + +procedure tsigenvelope.lintoexp(var avalue: double); +var + scale,offset: double; + do1: double; +begin + if (fmin > 0) and (fmax > 0) then begin + offset:= ln(fmin); + scale:= ln(fmax)-offset; + if scale <> 0 then begin + do1:= avalue*(fmax-fmin)+fmin; + if do1 > 0 then begin + avalue:= (ln(do1) - offset)/scale; + end; + end; + end; +end; + +procedure tsigenvelope.exptolin(var avalue: double); +var + scale,offset: double; + do1: double; +begin + if (fmin > 0) and (fmax > 0) then begin + offset:= ln(fmin); + scale:= ln(fmax)-offset; + do1:= fmax-fmin; + if do1 <> 0 then begin + avalue:= (exp(avalue*scale+offset)-fmin)/do1; + end; + end; +end; + +procedure tsigenvelope.updatevalues(var ainfo: envelopeinfoty); +var + timsca: double; + timoffs: double; + eventtimescale: real; + isexpbefore: boolean; + isexpbeforeset: boolean; + + procedure setscale(const options: sigenveloperangeoptionsty; + const progindex: integer; var sta: double); +// var +// do1: double; + begin + with ainfo.fprog[progindex] do begin + isexp:= sero_exp in options; + if isexp then begin + if (fmin > 0) and (fmax > 0) then begin + offset:= ln(fmin); + scale:= ln(fmax)-offset; + end + else begin + scale:= 1; //invalid + offset:= 0; + end; + if isexpbeforeset and not isexpbefore then begin + lintoexp(sta); + end; + end + else begin + offset:= fmin; + scale:= fmax-fmin; + if isexpbeforeset and isexpbefore then begin + exptolin(sta); + end; + end; + isexpbefore:= isexp; + isexpbeforeset:= true; + end; + end; //setscale + + procedure setend(const options: sigenveloperangeoptionsty; + var progindex: integer; var ti: integer; var sta: double); + begin + setscale(options,progindex,double(sta)); + with ainfo.fprog[progindex] do begin //end item + startval:= sta; + ramp:= 0; + starttime:= ti; + endtime:= -1; + inc(progindex); + end; + end; //setend + + procedure calc(const options: sigenveloperangeoptionsty; + const maxeventtime: double; + const valueitem: complexty; var progindex: integer; + var ti: integer; var sta: double); + var + int3: integer; + begin + setscale(options,progindex,double(sta)); + with ainfo.fprog[progindex] do begin + maxeventdelay:= round(maxeventtime*eventtimescale); + starttime:= ti; + startval:= sta; + int3:= ti; + ti:= round((valueitem.re+timoffs)*timsca); + endtime:= ti; + if int3 >= ti then begin + int3:= ti-1; + end; + ramp:= (valueitem.im - sta)/(ti-int3); + sta:= valueitem.im; + end; + inc(progindex); + end; //calc + + +var + int1,int2,int3: integer; + ti: integer; + sta: double; + do1: double; + aftertrigvalues: complexarty; + decaystart: double; + opt1: sigenveloperangeoptionsty; + +begin + if fupdating > 0 then begin + exit; + end; + lock; + try + ffinished:= false; + if fcontroller <> nil then begin + do1:= fcontroller.samplefrequ; + end + else begin + do1:= 44100; + end; + eventtimescale:= do1/fsubsampling; + fhasmix:= (sero_mix in fattack_options) or (sero_mix in fdecay_options) or + (sero_mix in frelease_options); + with ainfo do begin + isexpbefore:= false; + isexpbeforeset:= false; + attack_valuespo:= @fattack_values; + decay_valuespo:= @fdecay_values; + release_valuespo:= @frelease_values; + if @ainfo = @finfos[1] then begin + if not(sero_mix in fattack_options) then begin + attack_valuespo:= @finfos[0].fattack_values; + end; + if not(sero_mix in fdecay_options) then begin + decay_valuespo:= @finfos[0].fdecay_values; + end; + if not(sero_mix in frelease_options) then begin + release_valuespo:= @finfos[0].frelease_values; + end; + end; + + int1:= high(attack_valuespo^); + allocuninitedarray(int1+high(decay_valuespo^)+2,sizeof(complexty), + aftertrigvalues); + for int2:= 0 to int1 do begin + aftertrigvalues[int2]:= attack_valuespo^[int2]; + end; + if int1 >= 0 then begin + decaystart:= attack_valuespo^[int1].re; + end + else begin + decaystart:= 0; + end; + inc(int1); + for int2:= 0 to high(decay_valuespo^) do begin + with aftertrigvalues[int2+int1] do begin + re:= decay_valuespo^[int2].re + decaystart; + im:= decay_valuespo^[int2].im; + end; + end; + fprog:= nil; + timoffs:= 0; + timsca:= ftimescale/fsubsampling; + if fcontroller <> nil then begin + timsca:= timsca * fcontroller.samplefrequ; + end; + ftime:= 0; + fattackval:= 0; + fattackramp:= 0; + floopstartindex:= -1; + floopendindex:= -1; + floopval:= 0; + floopramp:= 1; + freleaseindex:= -1; + freleaseval:= 0; + freleaseramp:= 0; + + int1:= high(aftertrigvalues) + 2; //+ enditem + if floopstart >= 0 then begin + for int2:= 0 to high(decay_valuespo^) do begin + if decay_valuespo^[int2].re >= floopstart then begin + floopstartindex:= int2+length(attack_valuespo^); //fvaluestrig index + floopendindex:= length(aftertrigvalues); + break; + end; + end; + end; + if high(aftertrigvalues) >= 0 then begin + fattackval:= aftertrigvalues[0].im; + freleasestart:= aftertrigvalues[high(aftertrigvalues)].re; + end; + + if high(release_valuespo^) >= 0 then begin + int1:= int1 + high(release_valuespo^) + 2; //+enditem + freleaseval:= release_valuespo^[0].im; + freleaseramp:= release_valuespo^[0].re; + if freleaseramp > 0 then begin + freleaseramp:= 1/(freleaseramp*timsca); + end; + end; + setlength(fprog,int1); + findex:= high(fprog); //init inactive + findexhigh:= findex; + ti:= 0; + sta:= fattackval; + int1:= 0; + int3:= high(aftertrigvalues); + for int2:= 0 to high(attack_valuespo^) do begin + calc(fattack_options,fattack_maxeventtime,aftertrigvalues[int2],int1,ti,sta); + end; + for int2:= length(attack_valuespo^) to int3 do begin + calc(fdecay_options,fdecay_maxeventtime,aftertrigvalues[int2],int1,ti,sta); + end; + if floopstartindex >= 0 then begin + do1:= sta; + calc(fdecay_options,fdecay_maxeventtime,makecomplex( + aftertrigvalues[int3].re+aftertrigvalues[floopstartindex].re-floopstart, + aftertrigvalues[floopstartindex].im),int1,ti,sta); + sta:= do1; + inc(floopstartindex); //fprog index + end + else begin + opt1:= fdecay_options; + if (decay_valuespo^ = nil) and (attack_valuespo^ <> nil) then begin + opt1:= fattack_options; + end; + setend(opt1,int1,ti,sta); + end; + if high(release_valuespo^) >= 0 then begin + ti:= 0; + freleaseindex:= int1; //prog index + for int2:= 0 to high(release_valuespo^) do begin + calc(frelease_options,frelease_maxeventtime,release_valuespo^[int2], + int1,ti,sta); + end; + setend(frelease_options,int1,ti,sta); + end; + if fprog[0].endtime > 0 then begin + fattackramp:= 1/fprog[0].endtime; + end; + sendchangeevent; + end; + finally + unlock; + end; +end; + +{ +function tsigenvelope.getsigoptions: sigclientoptionsty; +begin + result:= [sco_tick]; +end; + +procedure tsigenvelope.sigtick; +begin + fcontroller.execevent(isigclient(self)); +end; +} +procedure tsigenvelope.sighandler(const ainfo: psighandlerinfoty); + + procedure startattack(var ainfo: envelopeinfoty); + begin + with ainfo do begin + ftime:= 0; + findex:= 0; + with fprog[0] do begin + if fcurrisexp and not isexp then begin + exptolin(fcurrval); + end; + if not fcurrisexp and isexp then begin + lintoexp(fcurrval); + end; + ramp:= (fattackval-fcurrval)*fattackramp; + if ramp = 0 then begin + startval:= fattackval; + end + else begin + startval:= fcurrval; + end; + end; + end; + end; //startattack() + + procedure startrelease(var ainfo: envelopeinfoty); + begin + with ainfo do begin + if freleaseindex >= 0 then begin + ftime:= 0; + findex:= freleaseindex; + with fprog[findex] do begin + if fcurrisexp and not isexp then begin + exptolin(fcurrval); + end; + if not fcurrisexp and isexp then begin + lintoexp(fcurrval); + end; + ramp:= (freleaseval-fcurrval)*freleaseramp; + if ramp = 0 then begin + startval:= freleaseval; + end + else begin + startval:= fcurrval; + end; + end; + end; + end; + end; //startrelease() + + procedure calc(var ainfo: envelopeinfoty); + begin + with ainfo do begin + with fprog[findex] do begin + fcurrisexp:= isexp; + fcurrval:= startval+ramp*(ftime-starttime); + if isexp then begin + if (fcurrval <= 0) and not (seo_nozero in foptions) then begin + fdest:= 0; + end + else begin + fdest:= exp(fcurrval*scale + offset)*famplitudepo^.value; + end; + end + else begin + fdest:= (fcurrval*scale + offset)*famplitudepo^.value; + end; + if endtime >= 0 then begin + inc(ftime); + if (ftime > endtime) then begin + if findex = floopendindex then begin + findex:= floopstartindex; + ftime:= fprog[floopstartindex].starttime; + end + else begin + inc(findex); + end; + end; + end; + end; + end; + end; //calc() + +var + bo1: boolean; + int1: integer; +begin + if fattackpending or (ftrigger.fv.value = 1) then begin + ftrigger.fv.value:= 0; + fattackpending:= false; + ffinished:= false; + startattack(finfos[0]); + startattack(finfos[1]); + end; + if freleasepending or (ftrigger.fv.value = -1) then begin + ftrigger.fv.value:= 0; + freleasepending:= false; + ffinished:= false; + startrelease(finfos[0]); + startrelease(finfos[1]); + end; + ainfo^.discard:= true; + if fsamplecount = 0 then begin + fsamplecount:= fsubsampling; + if feventdriven then begin + calc(finfos[0]); + with finfos[0] do begin + fmaxeventdelay:= fprog[findex].maxeventdelay; + bo1:= false; + if fhasmix then begin + calc(finfos[1]); + with finfos[1] do begin + int1:= fprog[findex].maxeventdelay; + if int1 < fmaxeventdelay then begin + fmaxeventdelay:= int1; + end; + bo1:= (feventtime >= fmaxeventdelay) or + (abs(fcurrval-fcurrvalbefore) > feventthreshold); + end; + end; + bo1:= bo1 or (feventtime >= fmaxeventdelay) or + (abs(fcurrval-fcurrvalbefore) > feventthreshold); + if bo1 then begin + fcurrvalbefore:= fcurrval; + end; + end; + if fhasmix then begin + calc(finfos[1]); + with finfos[1] do begin + if bo1 then begin + fcurrvalbefore:= fcurrval; + foutputpo^:= finfos[1].fdest * fmixpo^.value + + finfos[0].fdest * (1-fmixpo^.value); + end; + end; + end + else begin + if bo1 then begin + foutputpo^:= finfos[0].fdest; + end; + end; + if bo1 then begin + feventtime:= 0; + fcontroller.dispatcheventoutput(fsigclientinfo.infopo); + end; + inc(feventtime); + end + else begin + ainfo^.discard:= false; + calc(finfos[0]); + ffinished:= finfos[0].findex = finfos[0].findexhigh; + if fhasmix then begin + calc(finfos[1]); + ffinished:= ffinished and (finfos[1].findex = finfos[1].findexhigh); + foutputpo^:= finfos[1].fdest * fmixpo^.value + + finfos[0].fdest * (1-fmixpo^.value); + end + else begin + foutputpo^:= finfos[0].fdest; + end; + end; + end; + if not ffinished then begin + dec(fsamplecount); + end; +end; + +function tsigenvelope.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigenvelope.checkindex(const index: integer); +begin + if (index < 0) or (index > 1) then begin + raise exception.create(ownernamepath(self)+': Invalid array index '+ + inttostr(index)+'.'); + end; +end; + +procedure tsigenvelope.updatevalueindex(const aindex: integer); +begin + updatevalues(finfos[aindex]); + if aindex = 0 then begin + updatevalues(finfos[1]); //affects both + end; +end; + +function tsigenvelope.getattack_values(const index: integer): complexarty; +begin + checkindex(index); + result:= finfos[index].fattack_values; +end; + +procedure tsigenvelope.setattack_values(const index: integer; + const avalue: complexarty); +begin + checkindex(index); + finfos[index].fattack_values:= avalue; + updatevalueindex(index); +end; + +function tsigenvelope.getdecay_values(const index: integer): complexarty; +begin + checkindex(index); + result:= finfos[index].fdecay_values; +end; + +procedure tsigenvelope.setdecay_values(const index: integer; + const avalue: complexarty); +begin + checkindex(index); + finfos[index].fdecay_values:= avalue; + updatevalueindex(index); +end; + +function tsigenvelope.getrelease_values(const index: integer): complexarty; +begin + checkindex(index); + result:= finfos[index].frelease_values; +end; + +procedure tsigenvelope.setrelease_values(const index: integer; + const avalue: complexarty); +begin + checkindex(index); + finfos[index].frelease_values:= avalue; + updatevalueindex(index); +end; + +function tsigenvelope.getloopstart(const index: integer): real; +begin + checkindex(index); + result:= finfos[index].floopstart; +end; + +procedure tsigenvelope.setloopstart(const index: integer; + const avalue: real); +begin + checkindex(index); + finfos[index].floopstart:= avalue; + updatevalues(finfos[index]); +end; + +{ +procedure tsigenvelope.setdecaystart(const avalue: real); +begin + fdecaystart:= avalue; + updatevalues; +end; +} +{ +procedure tsigenvelope.setaftertrigvalues(const avalue: complexarty); +begin + faftertrigvalues:= avalue; + updatevalues; +end; +} + +procedure tsigenvelope.settrigger(const avalue: tchangedoubleinputconn); +begin + ftrigger.assign(avalue); +end; + +function tsigenvelope.getinputar: inputconnarty; +begin + setlength(result,3); + result[0]:= ftrigger; + result[1]:= famplitude; + result[2]:= fmix; +end; + +function tsigenvelope.getzcount: integer; +begin + result:= 1; +end; + +procedure tsigenvelope.initmodel; +begin + inherited; + famplitudepo:= @famplitude.fv; + fmixpo:= @fmix.fv; + updatevaluesx; +end; + +procedure tsigenvelope.setmin(const avalue: real); +begin + fmin:= avalue; + updatevaluesx; +end; + +procedure tsigenvelope.setmax(const avalue: real); +begin + fmax:= avalue; + updatevaluesx; +end; + +procedure tsigenvelope.setoptions(const avalue: sigenvelopeoptionsty); +begin + if avalue <> foptions then begin + eventdriven:= seo_eventoutput in avalue; + foptions:= avalue; + updatevaluesx; + end; +end; + +procedure tsigenvelope.dotriggerchange(const sender: tobject); +begin + if ftrigger.fv.value = 1 then begin + fattackpending:= true; + end; + if ftrigger.fv.value = -1 then begin + freleasepending:= true; + end; + ftrigger.fv.value:= 0; +end; + +procedure tsigenvelope.start; +begin + lock; + fattackpending:= true; + unlock; +end; + +procedure tsigenvelope.stop; +begin + lock; + freleasepending:= true; + unlock; +end; + +procedure tsigenvelope.update; +begin + inherited; + updatevaluesx; +end; + +procedure tsigenvelope.setattack_options(const avalue: sigenveloperangeoptionsty); +begin + if fattack_options <> avalue then begin + fattack_options:= avalue; + updatevaluesx; + end; +end; + +procedure tsigenvelope.setdecay_options(const avalue: sigenveloperangeoptionsty); +begin + if fdecay_options <> avalue then begin + fdecay_options:= avalue; + updatevaluesx; + end; +end; + +procedure tsigenvelope.setrelease_options(const avalue: sigenveloperangeoptionsty); +begin + if frelease_options <> avalue then begin + frelease_options:= avalue; + updatevaluesx; + end; +end; + +procedure tsigenvelope.dosync; + + procedure setval(const aindex: integer); + begin + attack_values[aindex]:= master.attack_values[aindex]; + decay_values[aindex]:= master.decay_values[aindex]; + release_values[aindex]:= master.release_values[aindex]; + loopstart[aindex]:= master.loopstart[aindex]; + end; //setval() + +begin + beginupdate; + setval(0); + setval(1); + endupdate; +end; + +procedure tsigenvelope.setmaster(const avalue: tsigenvelope); +var + env1: tsigenvelope; +begin + if avalue <> fmaster then begin + env1:= avalue; + while env1 <> nil do begin + if env1 = self then begin + raise exception.create('Recursive master.'); + end; + env1:= env1.master; + end; + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fmaster)); + if avalue <> nil then begin + dosync; + end; + end; +end; + +procedure tsigenvelope.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_changed) and (sender <> nil) and (sender = master) then begin + dosync; + end; +end; + +procedure tsigenvelope.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +procedure tsigenvelope.updatevaluesx; +begin + updatevalues(finfos[0]); + updatevalues(finfos[1]); +end; + +procedure tsigenvelope.setmix(const avalue: tlimitinputconn); +begin + fmix.assign(avalue); +end; + +function tsigenvelope.getsigoptions: sigclientoptionsty; +begin + result:= inherited getsigoptions; + if feventdriven then begin + result:= result + [sco_fulltick]; + end; +end; + +procedure tsigenvelope.setsubsampling(avalue: integer); +begin + if avalue < 1 then begin + avalue:= 1; + end; + fsubsampling:= avalue; +end; + +{ tchangedoubleinputconn } + +constructor tchangedoubleinputconn.create(const aowner: tcomponent; + const asigintf: isigclient; const aonchange: notifyeventty); +begin + fonchange:= aonchange; + inherited create(aowner,asigintf); +end; + +procedure tchangedoubleinputconn.setvalue(const avalue: double); +begin + lock; + inherited; + if tmsecomponent(owner).canevent(tmethod(fonchange)) then begin + try + fonchange(self); + finally + unlock + end; + end + else begin + unlock; + end; +end; + +{ tsigsampler } + +constructor tsigsampler.create(aowner: tcomponent); +begin + fbufferlength:= defaultsamplecount; + frefreshus:= -1; + foptions:= defaultsigsampleroptions; + inherited; + ftrigger:= tchangedoubleinputconn.create(self,isigclient(self), + {$ifdef FPC}@{$endif}dotriggerchange); + ftrigger.name:= 'trigger'; + ftriggerlevel:= tchangedoubleinputconn.create(self,isigclient(self), + {$ifdef FPC}@{$endif}dotriggerchange); + ftriggerlevel.name:= 'triggerlevel'; + ftimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}dotimer,false,[to_leak]); +end; + +destructor tsigsampler.destroy; +begin + ftimer.free; + inherited; +end; + +function tsigsampler.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigsampler.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + if not frunning and fstarted then begin + if sso_autorun in foptions then begin + do1:= 1; + end + else begin + if fnegtrig then begin + do1:= ftriggerlevel.value-ftrigger.value; + end + else begin + do1:= ftrigger.value-ftriggerlevel.value; + end; + end; + if do1 >{=} 0 then begin +// if do1 = 0 then begin +// fpretrigger:= true; +// end; + if fpretrigger then begin + fbufpo:= 0; + frunning:= true; + fstarted:= false; + end; + end + else begin + fpretrigger:= true; + end; + end; + if frunning then begin + for int1:= 0 to high(fsigbuffer) do begin + fsigbuffer[int1][fbufpo]:= finps[int1]^.value; + end; + inc(fbufpo); + if fbufpo = fbufferlength then begin + frunning:= false; + dobufferfull; + checkautostart; + end; + end + else begin + if fstartpending then begin + fstartpending:= false; + start; + end; + end; +end; + +procedure tsigsampler.clear; +begin +// fstarted:= false; + frunning:= false; + inherited; +end; + +procedure tsigsampler.setbufferlength(const avalue: integer); +begin + if fbufferlength <> avalue then begin + lock; + if avalue = 0 then begin + fbufferlength:= 1; + end + else begin + fbufferlength:= avalue; + end; + modelchange; + unlock; + end; +end; + +procedure tsigsampler.initmodel; +var + int1: integer; +begin + inherited; + fsigbuffer:= nil; + setlength(fsigbuffer,finputs.count); + for int1:= 0 to high(fsigbuffer) do begin + setlength(fsigbuffer[int1],fbufferlength); + end; + checkautostart(); +end; + +procedure tsigsampler.settrigger(const avalue: tchangedoubleinputconn); +begin + ftrigger.assign(avalue); +end; + +procedure tsigsampler.settriggerlevel(const avalue: tchangedoubleinputconn); +begin + ftriggerlevel.assign(avalue); +end; + +procedure tsigsampler.dotriggerchange(const sender: tobject); +begin + //dummy +end; + +procedure tsigsampler.start; +begin + lock; + fstarted:= true; + frunning:= false; + fpretrigger:= sso_autorun in foptions; + unlock; +end; + +procedure tsigsampler.dobufferfull; +begin + if assigned(fonbufferfull) then begin + fonbufferfull(self,fsigbuffer); + end; +end; + +function tsigsampler.getinputar: inputconnarty; +begin + setlength(result,2); + result[0]:= ftrigger; + result[1]:= ftriggerlevel; + stackarray(pointerarty(inherited getinputar),pointerarty(result)); +end; + +procedure tsigsampler.checkautostart; +begin + if (sso_autorun in foptions) and (frefreshus < 0) and + (componentstate * [csloading,csdesigning] = []) then begin + start; + end; +end; + +procedure tsigsampler.setoptions(const avalue: sigsampleroptionsty); +var + optionsbefore: sigsampleroptionsty; +begin + if foptions <> avalue then begin + optionsbefore:= foptions; + foptions:= avalue; + updateoptions(foptions); + fnegtrig:= sso_negtrig in foptions; + if (sso_fulltick in foptions) xor (sso_fulltick in optionsbefore) then begin + modelchange; + end; + if not (sso_autorun in optionsbefore) then begin + checkautostart; + end; + end; +end; + +procedure tsigsampler.setrefreshus(const avalue: integer); +begin + if frefreshus <> avalue then begin + frefreshus:= avalue; + if avalue < 0 then begin + ftimer.enabled:= false; + checkautostart; + end + else begin + ftimer.interval:= avalue; + if componentstate * [csloading,csdesigning] = [] then begin + ftimer.enabled:= true; + end; + end; + end; +end; + +procedure tsigsampler.dotimer(const sender: tobject); +begin + lock; + if not fstarted and not frunning then begin + start; + end + else begin + fstartpending:= true; + end; + unlock; +end; + +procedure tsigsampler.loaded; +begin + inherited; + if not (csdesigning in componentstate) then begin + if (frefreshus >= 0) then begin + ftimer.enabled:= true; + end + else begin + checkautostart; + end; + end; +end; + +procedure tsigsampler.updateoptions(var avalue: sigsampleroptionsty); +begin + exclude(avalue,sso_fftmag); +end; + +function tsigsampler.getsigoptions: sigclientoptionsty; +begin + result:= inherited getsigoptions; + if sso_fulltick in foptions then begin + include(result,sco_fulltick); + end; +end; + +{ tdoublesiginoutcomp } + +constructor tdoublesiginoutcomp.create(aowner: tcomponent); +begin + finput:= tdoubleinputconn.create(self,isigclient(self)); + finputpo:= @finput.fv; + inherited; +end; + +procedure tdoublesiginoutcomp.setinput(const avalue: tdoubleinputconn); +begin + finput.assign(avalue); +end; + +function tdoublesiginoutcomp.getinputar: inputconnarty; +begin + setlength(result,1); + result[0]:= finput; +end; + +{ tsigconnector } + +function tsigconnector.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigconnector.sighandler(const ainfo: psighandlerinfoty); +begin + foutputpo^:= finputpo^.value; +end; + +{ ttrigconnector } + +constructor ttrigconnector.create(aowner: tcomponent); +begin + inherited; + include(foutput.fstate,ocs_eventdriven); +end; + +{ tlimitinputconn } + +constructor tlimitinputconn.create(const aowner: tcomponent; + const asigintf: isigclient); +begin + inherited; + fmin:= 0; + fmax:= 1; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesignoise.pas b/mseide-msegui/lib/common/math/msesignoise.pas new file mode 100644 index 0000000..220b136 --- /dev/null +++ b/mseide-msegui/lib/common/math/msesignoise.pas @@ -0,0 +1,316 @@ +{ MSEgui Copyright (c) 2010-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit msesignoise; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msesignal,classes,mclasses; + +type + noisekindty = (nk_white,nk_pink,nk_brown); + + tsignoise = class(tdoublesigoutcomp) + private + famplitudepo: psigvaluety; + foffsetpo: psigvaluety; + famplitude: tdoubleinputconn; + foffset: tdoubleinputconn; + fw,fz: longword; //random seeds + fscale: double; + fsamplehigh: integer; + fsamplecount: integer; + fkind: noisekindty; + fcutofffrequ: real; + fsum: real; + fb0,fb1,fb2,fb3,fb4,fb5,fb6: double; + fsumfact: real; + procedure setamplitude(const avalue: tdoubleinputconn); + procedure setoffset(const avalue: tdoubleinputconn); + procedure setsamplecount(const avalue: integer); + procedure setkind(const avalue: noisekindty); + procedure setcutofffrequ(const avalue: real); + protected + procedure sighandlerbrown1(const ainfo: psighandlerinfoty); + procedure sighandlerbrownn(const ainfo: psighandlerinfoty); + procedure sighandlerpink1(const ainfo: psighandlerinfoty); + procedure sighandlerpinkn(const ainfo: psighandlerinfoty); + procedure sighandler1(const ainfo: psighandlerinfoty); + procedure sighandlern(const ainfo: psighandlerinfoty); + //isigclient + function gethandler: sighandlerprocty; override; + procedure initmodel; override; + function getinputar: inputconnarty; override; + function getzcount: integer; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + published + property amplitude: tdoubleinputconn read famplitude write setamplitude; + property offset: tdoubleinputconn read foffset write setoffset; + property samplecount: integer read fsamplecount + write setsamplecount default 1; + //1 -> uniform distribution + property kind: noisekindty read fkind write setkind default nk_white; + property cutofffrequ: real read fcutofffrequ write setcutofffrequ; + //nk_pink only, default 0.001 + end; + +implementation +uses + msenoise; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdoubleinputconn1 = class(tdoubleinputconn); + +{ tsignoise } + +constructor tsignoise.create(aowner: tcomponent); +begin + fcutofffrequ:= 0.001; + samplecount:= 1; + inherited; + famplitude:= tdoubleinputconn.create(self,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitude.value:= 1; + foffset:= tdoubleinputconn.create(self,isigclient(self)); + foffset.name:= 'offset'; +end; + +procedure tsignoise.clear; +begin + fz:= 0; + fw:= 0; + checkmwcseed(fz,fw); + fsum:= 0; + fb0:= 0; + fb1:= 0; + fb2:= 0; + fb3:= 0; + fb4:= 0; + fb5:= 0; + fb6:= 0; + inherited; +end; + +function tsignoise.gethandler: sighandlerprocty; +begin + if fsamplecount = 1 then begin + case fkind of + nk_pink: begin + result:= {$ifdef FPC}@{$endif}sighandlerpink1; + end; + nk_brown: begin + result:= {$ifdef FPC}@{$endif}sighandlerbrown1; + end; + else begin //nk_white + result:= {$ifdef FPC}@{$endif}sighandler1; + end; + end; + end + else begin + case fkind of + nk_pink: begin + result:= {$ifdef FPC}@{$endif}sighandlerpinkn; + end; + nk_brown: begin + result:= {$ifdef FPC}@{$endif}sighandlerbrownn; + end; + else begin //nk_white + result:= {$ifdef FPC}@{$endif}sighandlern; + end; + end; + end; +end; + +procedure tsignoise.initmodel; +var + do1: double; +begin + do1:= fcutofffrequ*2*pi; + fsamplehigh:= fsamplecount - 1; + fscale:= maxint * sqrt(fsamplecount); + if do1 > 0 then begin + case fkind of + nk_pink: begin + fscale:= fscale*4; + end; + nk_brown: begin + fscale:= fscale/sqrt(do1); + end; + end; + end; + fsumfact:= exp(-do1); + famplitudepo:= @tdoubleinputconn1(famplitude).fv; + foffsetpo:= @tdoubleinputconn1(foffset).fv; + inherited; +end; + +function tsignoise.getinputar: inputconnarty; +begin + setlength(result,2); + result[0]:= famplitude; + result[1]:= foffset; +end; + +function tsignoise.getzcount: integer; +begin + result:= 1; +end; + +procedure tsignoise.sighandler1(const ainfo: psighandlerinfoty); +begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); //mwc by George Marsaglia + fw:= 18000 * (fw and $ffff) + (fw shr 16); + foutputpo^:= (integer((fz shl 16) + fw)/fscale)*famplitudepo^.value+ + foffsetpo^.value; +end; + +procedure tsignoise.sighandlern(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + do1:= 0; + for int1:= 0 to fsamplehigh do begin //mwc by George Marsaglia + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + do1:= do1 + integer((fz shl 16) + fw); + end; + foutputpo^:= (do1*famplitudepo^.value)/fscale+foffsetpo^.value; +end; + +procedure tsignoise.sighandlerpink1(const ainfo: psighandlerinfoty); +var + white: double; +begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); //mwc by George Marsaglia + fw:= 18000 * (fw and $ffff) + (fw shr 16); + white:= (integer((fz shl 16) + fw)/fscale); + + fb0:= 0.99886 * fb0 + white * 0.0555179; //filter by Paul Kellet + fb1:= 0.99332 * fb1 + white * 0.0750759; + fb2:= 0.96900 * fb2 + white * 0.1538520; + fb3:= 0.86650 * fb3 + white * 0.3104856; + fb4:= 0.55000 * fb4 + white * 0.5329522; + fb5:= -0.7616 * fb5 - white * 0.0168980; + foutputpo^:= (fb0+fb1+fb2+fb3+fb4+fb5+fb6+white*0.5362) * + famplitudepo^.value + foffsetpo^.value; + fb6:= white * 0.115926; +end; + +procedure tsignoise.sighandlerpinkn(const ainfo: psighandlerinfoty); +var + int1: integer; + white: double; +begin + white:= 0; + for int1:= 0 to fsamplehigh do begin //mwc by george marsaglia + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + white:= white + integer((fz shl 16) + fw); + end; +//filter by Paul Kellet + + fb0:= 0.99886 * fb0 + white * 0.0555179; + fb1:= 0.99332 * fb1 + white * 0.0750759; + fb2:= 0.96900 * fb2 + white * 0.1538520; + fb3:= 0.86650 * fb3 + white * 0.3104856; + fb4:= 0.55000 * fb4 + white * 0.5329522; + fb5:= -0.7616 * fb5 - white * 0.0168980; + foutputpo^:= ((fb0+fb1+fb2+fb3+fb4+fb5+fb6+white*0.5362) * + famplitudepo^.value)/fscale + foffsetpo^.value; + fb6:= white * 0.115926; +end; + +procedure tsignoise.sighandlerbrown1(const ainfo: psighandlerinfoty); +begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); //mwc by George Marsaglia + fw:= 18000 * (fw and $ffff) + (fw shr 16); + fsum:= fsum*fsumfact + integer((fz shl 16) + fw)/fscale; + foutputpo^:= fsum*famplitudepo^.value+foffsetpo^.value; +end; + +procedure tsignoise.sighandlerbrownn(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + do1:= 0; + for int1:= 0 to fsamplehigh do begin //mwc by George Marsaglia + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + do1:= do1 + integer((fz shl 16) + fw); + end; + fsum:= fsum*fsumfact+do1; + foutputpo^:= (fsum*famplitudepo^.value)/fscale+foffsetpo^.value; +end; + +procedure tsignoise.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +procedure tsignoise.setoffset(const avalue: tdoubleinputconn); +begin + foffset.assign(avalue); +end; + +procedure tsignoise.setsamplecount(const avalue: integer); +begin + if fsamplecount <> avalue then begin + lock; + fsamplecount:= avalue; + if fsamplecount <= 0 then begin + fsamplecount:= 1; + end; + modelchange; + unlock; + end; +end; + +procedure tsignoise.setkind(const avalue: noisekindty); +begin + if fkind <> avalue then begin + lock; + fkind:= avalue; + modelchange; + unlock; + end; +end; + +procedure tsignoise.setcutofffrequ(const avalue: real); +begin + if fcutofffrequ <> avalue then begin + lock; + fcutofffrequ:= avalue; + modelchange; + unlock; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/opengl/mseftgl.pas b/mseide-msegui/lib/common/opengl/mseftgl.pas new file mode 100644 index 0000000..607130a --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseftgl.pas @@ -0,0 +1,420 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +{ +/* + * FTGL - OpenGL font library + * + * Copyright (c) 2001-2004 Henry Maddocks + * Copyright (c) 2008 Sam Hocevar + * Copyright (c) 2008 Sean Morrison + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + } +unit mseftgl; +// +//under construction +// +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msectypes,msetypes,msestrings; + +const +{$ifdef mswindows} + ftgllib: array[0..0] of filenamety = ('FTGL.dll'); +{$else} + ftgllib: array[0..1] of filenamety = ('libftgl.so.2','libftgl.so'); +{$endif} + +type + size_t = ptruint; + FT_Error = cint; +const + FT_ENCODING_NONE = 0; + + FT_ENCODING_MS_SYMBOL = (ord('s') shl 24) or + (ord('y') shl 16) or + (ord('m') shl 8) or + ord('b'); + FT_ENCODING_UNICODE = (ord('u') shl 24) or + (ord('n') shl 16) or + (ord('i') shl 8) or + ord('c'); + FT_ENCODING_SJIS = (ord('s') shl 24) or + (ord('j') shl 16) or + (ord('i') shl 8) or + ord('s'); + FT_ENCODING_GB2312 = (ord('g') shl 24) or + (ord('b') shl 16) or + (ord(' ') shl 8) or + ord(' '); + FT_ENCODING_BIG5 = (ord('b') shl 24) or + (ord('i') shl 16) or + (ord('g') shl 8) or + ord('5'); + FT_ENCODING_WANSUNG = (ord('w') shl 24) or + (ord('a') shl 16) or + (ord('n') shl 8) or + ord('s'); + FT_ENCODING_JOHAB = (ord('j') shl 24) or + (ord('o') shl 16) or + (ord('h') shl 8) or + ord('a'); + +// /* for backwards compatibility */ + FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS; + FT_ENCODING_MS_GB2312 = FT_ENCODING_GB2312; + FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5; + FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG; + FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB; + + FT_ENCODING_ADOBE_STANDARD = (ord('A') shl 24) or + (ord('D') shl 16) or + (ord('O') shl 8) or + ord('B'); + FT_ENCODING_ADOBE_EXPERT = (ord('A') shl 24) or + (ord('D') shl 16) or + (ord('B') shl 8) or + ord('E'); + FT_ENCODING_ADOBE_CUSTOM = (ord('A') shl 24) or + (ord('D') shl 16) or + (ord('B') shl 8) or + ord('C'); + FT_ENCODING_ADOBE_LATIN_1 = (ord('l') shl 24) or + (ord('a') shl 16) or + (ord('t') shl 8) or + ord('1'); + + FT_ENCODING_OLD_LATIN_2 = (ord('l') shl 24) or + (ord('a') shl 16) or + (ord('t') shl 8) or + ord('2'); + + FT_ENCODING_APPLE_ROMAN = (ord('a') shl 24) or + (ord('r') shl 16) or + (ord('m') shl 8) or + ord('n'); + + FTGL_RENDER_FRONT = $0001; + FTGL_RENDER_BACK = $0002; + FTGL_RENDER_SIDE = $0004; + FTGL_RENDER_ALL = $ffff; + + FTGL_ALIGN_LEFT = 0; + FTGL_ALIGN_CENTER = 1; + FTGL_ALIGN_RIGHT = 2; + FTGL_ALIGN_JUSTIFY = 3; + + +{/** FTFont.h + * FTGLfont is the public interface for the FTGL library. + * + * It is good practice after using these functions to test the error + * code returned. FT_Error Error(). Check the freetype file + * fterrdef.h for error definitions. + */} +type + FT_GlyphSlotRec = record end; //opaque + FT_GlyphSlot = ^FT_GlyphSlotRec; + FTGLfont = record end; //opaque + pFTGLfont = ^FTGLfont; + FTGLglyph = record end; //opaque + pFTGLglyph = ^FTGLglyph; + + makeglyphcallbackty = function(par1: FT_GlyphSlot; par2: pointer): pFTGLglyph; + cdecl; +// boundsty = array[0..5] of cfloat; + boundsty = packed record + lower,left,near,upper,right,far: cfloat; + end; + +var + +{/** + * Create a custom FTGL font object. + * + * @param fontFilePath The font file name. + * @param data A pointer to private data that will be passed to callbacks. + * @param makeglyphCallback A glyph-making callback function. + * @return An FTGLfont* object. + */} + ftglCreateCustomFont: function(fontFilePath: pchar; data: pointer; + makeglyphCallback: makeglyphcallbackty): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling bitmap fonts. + * + */} + ftglCreateBitmapFont: function(_file: pchar): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling pixmap (grey scale) fonts. + */} + ftglCreatePixmapFont: function(_file: pchar): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling vector outline fonts. + */} + ftglCreateOutlineFont: function(_file: pchar): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling tesselated polygon + * mesh fonts. + */} + ftglCreatePolygonFont: function(_file: pchar): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling texture-mapped fonts. + */} + ftglCreateTextureFont: function(_file: pchar): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling memory buffer fonts. + */} + ftglCreateBufferFont: function(_file: pchar): pFTGLfont; cdecl; + + +{/** + * Destroy an FTGL font object. + * + * @param font An FTGLfont* object. + */} + ftglDestroyFont: procedure(font: pFTGLfont); cdecl; + +{/** + * Attach auxilliary file to font e.g. font metrics. + * + * Note: not all font formats implement this function. + * + * @param font An FTGLfont* object. + * @param path Auxilliary font file path. + * @return 1 if file has been attached successfully. + */} + ftglAttachFile: function(font: pFTGLfont; path: pchar): cint; cdecl; + +{/** + * Attach auxilliary data to font, e.g. font metrics, from memory. + * + * Note: not all font formats implement this function. + * + * @param font An FTGLfont* object. + * @param data The in-memory buffer. + * @param size The length of the buffer in bytes. + * @return 1 if file has been attached successfully. + */} + ftglAttachData: function(font: pFTGLfont; data: pbyte; + size: size_t): cint; cdecl; + +{/** + * Set the character map for the face. + * + * @param font An FTGLfont* object. + * @param encoding Freetype enumerate for char map code. + * @return 1 if charmap was valid and set correctly. + */} + ftglSetFontCharMap: function(font: pFTGLfont; + encoding: cint): cint; cdecl; + +{/** + * Get the number of character maps in this face. + * + * @param font An FTGLfont* object. + * @return character map count. + */} + ftglGetFontCharMapCount: function(font: pFTGLfont): cuint; cdecl; + +{/** + * Get a list of character maps in this face. + * + * @param font An FTGLfont* object. + * @return pointer to the first encoding. + */} + ftglGetFontCharMapList: function(font: pFTGLfont): pcint; cdecl; + +{/** + * Set the char size for the current face. + * + * @param font An FTGLfont* object. + * @param size The face size in points (1/72 inch). + * @param res The resolution of the target device, or 0 to use the default + * value of 72. + * @return 1 if size was set correctly. + */} + ftglSetFontFaceSize: function(font: pFTGLfont; size: cuint; + res: cuint): cint; cdecl; + +{/** + * Get the current face size in points (1/72 inch). + * + * @param font An FTGLfont* object. + * @return face size + */} + ftglGetFontFaceSize: function(font: pFTGLfont): cuint; cdecl; + +{/** + * Set the extrusion distance for the font. Only implemented by + * FTExtrudeFont. + * + * @param font An FTGLfont* object. + * @param depth The extrusion distance. + */} + ftglSetFontDepth: procedure(font: pFTGLfont; depth: cfloat); cdecl; + +{/** + * Set the outset distance for the font. Only FTOutlineFont, FTPolygonFont + * and FTExtrudeFont implement front outset. Only FTExtrudeFont implements + * back outset. + * + * @param font An FTGLfont* object. + * @param front The front outset distance. + * @param back The back outset distance. + */} + ftglSetFontOutset: procedure(font: pFTGLfont; front: cfloat; + back: cfloat); cdecl; + +{/** + * Enable or disable the use of Display Lists inside FTGL. + * + * @param font An FTGLfont* object. + * @param useList 1 turns ON display lists. + * 0 turns OFF display lists. + */} + ftglSetFontDisplayList: procedure(font: pFTGLfont; useList: cint); cdecl; + +{/** + * Get the global ascender height for the face. + * + * @param font An FTGLfont* object. + * @return Ascender height + */} + ftglGetFontAscender: function(font: pFTGLfont): cfloat; cdecl; + +{/** + * Gets the global descender height for the face. + * + * @param font An FTGLfont* object. + * @return Descender height + */} + ftglGetFontDescender: function(font: pFTGLfont): cfloat; cdecl; + +{/** + * Gets the line spacing for the font. + * + * @param font An FTGLfont* object. + * @return Line height + */} + ftglGetFontLineHeight: function(font: pFTGLfont): cfloat; cdecl; + +{/** + * Get the bounding box for a string. + * + * @param font An FTGLfont* object. + * @param string A char buffer + * @param len The length of the string. If < 0 then all characters will be + * checked until a null character is encountered (optional). + * @param bounds An array of 6 float values where the bounding box's lower + * left near and upper right far 3D coordinates will be stored. + */} + ftglGetFontBBox: procedure(font: pFTGLfont; _string: pchar; + len: cint; out bounds: boundsty); cdecl; + +{/** + * Get the advance width for a string. + * + * @param font An FTGLfont* object. + * @param string A char string. + * @return Advance width + */} + ftglGetFontAdvance: function(font: pFTGLfont; _string: pchar): cfloat; cdecl; + +{/** + * Render a string of characters. + * + * @param font An FTGLfont* object. + * @param string Char string to be output. + * @param mode Render mode to display. + */} + ftglRenderFont: procedure(font: pFTGLfont; _string: pchar; mode: cint); cdecl; + +{/** + * Query a font for errors. + * + * @param font An FTGLfont* object. + * @return The current error code. + */} + ftglGetFontError: function(font: pFTGLfont): FT_Error; cdecl; + +procedure initializeftgl(const sonames: array of filenamety); +procedure releaseftgl; + +implementation +uses + msedynload,msesys,sysutils; +var + libinfo: dynlibinfoty; + +procedure releaseftgl; +begin + releasedynlib(libinfo); +end; + +procedure initializeftgl(const sonames: array of filenamety); +const + funcs: array[0..24] of funcinfoty = ( + (n: 'ftglCreateCustomFont'; d: @ftglCreateCustomFont), + (n: 'ftglCreateBitmapFont'; d: @ftglCreateBitmapFont), + (n: 'ftglCreatePixmapFont'; d: @ftglCreatePixmapFont), + (n: 'ftglCreateOutlineFont'; d: @ftglCreateOutlineFont), + (n: 'ftglCreatePolygonFont'; d: @ftglCreatePolygonFont), + (n: 'ftglCreateTextureFont'; d: @ftglCreateTextureFont), + (n: 'ftglCreateBufferFont'; d: @ftglCreateBufferFont), + (n: 'ftglDestroyFont'; d: @ftglDestroyFont), + (n: 'ftglAttachFile'; d: @ftglAttachFile), + (n: 'ftglAttachData'; d: @ftglAttachData), + (n: 'ftglSetFontCharMap'; d: @ftglSetFontCharMap), + (n: 'ftglGetFontCharMapCount'; d: @ftglGetFontCharMapCount), + (n: 'ftglGetFontCharMapList'; d: @ftglGetFontCharMapList), + (n: 'ftglSetFontFaceSize'; d: @ftglSetFontFaceSize), + (n: 'ftglGetFontFaceSize'; d: @ftglGetFontFaceSize), + (n: 'ftglSetFontDepth'; d: @ftglSetFontDepth), + (n: 'ftglSetFontOutset'; d: @ftglSetFontOutset), + (n: 'ftglSetFontDisplayList'; d: @ftglSetFontDisplayList), + (n: 'ftglGetFontAscender'; d: @ftglGetFontAscender), + (n: 'ftglGetFontDescender'; d: @ftglGetFontDescender), + (n: 'ftglGetFontLineHeight'; d: @ftglGetFontLineHeight), + (n: 'ftglGetFontBBox'; d: @ftglGetFontBBox), + (n: 'ftglGetFontAdvance'; d: @ftglGetFontAdvance), + (n: 'ftglRenderFont'; d: @ftglRenderFont), + (n: 'ftglGetFontError'; d: @ftglGetFontError) + ); + errormessage = 'Can not load FTGL library. '; + +begin + initializedynlib(libinfo,sonames,ftgllib,funcs,[],errormessage); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/opengl/msegl.pas b/mseide-msegui/lib/common/opengl/msegl.pas new file mode 100644 index 0000000..a3961cd --- /dev/null +++ b/mseide-msegui/lib/common/opengl/msegl.pas @@ -0,0 +1,1987 @@ +(* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +** +** (this unit actually only contains the 1.1 parts of the specification, +** the parts from the subsequence versions are in glext.pp) +*) + +{******************************************************************************} +{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) } +{******************************************************************************} + +{ modified 2011-2018 by Martin Schreiber } + + +{******************************************************************************} +{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) } +{ For the latest updates, visit Delphi3D: http://www.delphi3d.net } +{******************************************************************************} + +//{$MODE Delphi} +{$ifdef FPC}{$mode objfpc} {$h+}{$endif} +//{$macro on} +{$ifdef mswindows} + {$define wincall} +// {$define extdecl := stdcall} +{$else} +// {$define extdecl := cdecl} +{$endif} + +unit msegl; + +interface + +uses + SysUtils,msetypes,msestrings{$ifdef mswindows},windows{$endif}, + msedynload,mseglextglob; + +const +{$ifdef mswindows} + opengllib: array[0..0] of filenamety = ('opengl32.dll'); +{$else} + opengllib: array[0..1] of filenamety = ('libGL.so.1','libGL.so'); +{$endif} + +type + GLenum = Cardinal; PGLenum = ^GLenum; + GLboolean = Byte; PGLboolean = ^GLboolean; + GLbitfield = Cardinal; PGLbitfield = ^GLbitfield; + GLbyte = ShortInt; PGLbyte = ^GLbyte; + GLshort = SmallInt; PGLshort = ^GLshort; + GLint = Integer; PGLint = ^GLint; + GLsizei = Integer; PGLsizei = ^GLsizei; + GLubyte = Byte; PGLubyte = ^GLubyte; + GLushort = Word; PGLushort = ^GLushort; + GLuint = Cardinal; PGLuint = ^GLuint; + GLfloat = Single; PGLfloat = ^GLfloat; + GLclampf = Single; PGLclampf = ^GLclampf; + GLdouble = Double; PGLdouble = ^GLdouble; + GLclampd = Double; PGLclampd = ^GLclampd; +{ GLvoid = void; } PGLvoid = Pointer; + PPGLvoid = ^PGLvoid; + + TGLenum = GLenum; + TGLboolean = GLboolean; + TGLbitfield = GLbitfield; + TGLbyte = GLbyte; + TGLshort = GLshort; + TGLint = GLint; + TGLsizei = GLsizei; + TGLubyte = GLubyte; + TGLushort = GLushort; + TGLuint = GLuint; + TGLfloat = GLfloat; + TGLclampf = GLclampf; + TGLdouble = GLdouble; + TGLclampd = GLclampd; + +{******************************************************************************} + +const + // Version + GL_VERSION_1_1 = 1; + + // AccumOp + GL_ACCUM = $0100; + GL_LOAD = $0101; + GL_RETURN = $0102; + GL_MULT = $0103; + GL_ADD = $0104; + + // AlphaFunction + GL_NEVER = $0200; + GL_LESS = $0201; + GL_EQUAL = $0202; + GL_LEQUAL = $0203; + GL_GREATER = $0204; + GL_NOTEQUAL = $0205; + GL_GEQUAL = $0206; + GL_ALWAYS = $0207; + + // AttribMask + GL_CURRENT_BIT = $00000001; + GL_POINT_BIT = $00000002; + GL_LINE_BIT = $00000004; + GL_POLYGON_BIT = $00000008; + GL_POLYGON_STIPPLE_BIT = $00000010; + GL_PIXEL_MODE_BIT = $00000020; + GL_LIGHTING_BIT = $00000040; + GL_FOG_BIT = $00000080; + GL_DEPTH_BUFFER_BIT = $00000100; + GL_ACCUM_BUFFER_BIT = $00000200; + GL_STENCIL_BUFFER_BIT = $00000400; + GL_VIEWPORT_BIT = $00000800; + GL_TRANSFORM_BIT = $00001000; + GL_ENABLE_BIT = $00002000; + GL_COLOR_BUFFER_BIT = $00004000; + GL_HINT_BIT = $00008000; + GL_EVAL_BIT = $00010000; + GL_LIST_BIT = $00020000; + GL_TEXTURE_BIT = $00040000; + GL_SCISSOR_BIT = $00080000; + GL_ALL_ATTRIB_BITS = $000FFFFF; + + // BeginMode + GL_POINTS = $0000; + GL_LINES = $0001; + GL_LINE_LOOP = $0002; + GL_LINE_STRIP = $0003; + GL_TRIANGLES = $0004; + GL_TRIANGLE_STRIP = $0005; + GL_TRIANGLE_FAN = $0006; + GL_QUADS = $0007; + GL_QUAD_STRIP = $0008; + GL_POLYGON = $0009; + + // BlendingFactorDest + GL_ZERO = 0; + GL_ONE = 1; + GL_SRC_COLOR = $0300; + GL_ONE_MINUS_SRC_COLOR = $0301; + GL_SRC_ALPHA = $0302; + GL_ONE_MINUS_SRC_ALPHA = $0303; + GL_DST_ALPHA = $0304; + GL_ONE_MINUS_DST_ALPHA = $0305; + + // BlendingFactorSrc + // GL_ZERO + // GL_ONE + GL_DST_COLOR = $0306; + GL_ONE_MINUS_DST_COLOR = $0307; + GL_SRC_ALPHA_SATURATE = $0308; + // GL_SRC_ALPHA + // GL_ONE_MINUS_SRC_ALPHA + // GL_DST_ALPHA + // GL_ONE_MINUS_DST_ALPHA + + // Boolean + GL_TRUE = 1; + GL_FALSE = 0; + + // ClearBufferMask + // GL_COLOR_BUFFER_BIT + // GL_ACCUM_BUFFER_BIT + // GL_STENCIL_BUFFER_BIT + // GL_DEPTH_BUFFER_BIT + + // ClientArrayType + // GL_VERTEX_ARRAY + // GL_NORMAL_ARRAY + // GL_COLOR_ARRAY + // GL_INDEX_ARRAY + // GL_TEXTURE_COORD_ARRAY + // GL_EDGE_FLAG_ARRAY + + // ClipPlaneName + GL_CLIP_PLANE0 = $3000; + GL_CLIP_PLANE1 = $3001; + GL_CLIP_PLANE2 = $3002; + GL_CLIP_PLANE3 = $3003; + GL_CLIP_PLANE4 = $3004; + GL_CLIP_PLANE5 = $3005; + + // ColorMaterialFace + // GL_FRONT + // GL_BACK + // GL_FRONT_AND_BACK + + // ColorMaterialParameter + // GL_AMBIENT + // GL_DIFFUSE + // GL_SPECULAR + // GL_EMISSION + // GL_AMBIENT_AND_DIFFUSE + + // ColorPointerType + // GL_BYTE + // GL_UNSIGNED_BYTE + // GL_SHORT + // GL_UNSIGNED_SHORT + // GL_INT + // GL_UNSIGNED_INT + // GL_FLOAT + // GL_DOUBLE + + // CullFaceMode + // GL_FRONT + // GL_BACK + // GL_FRONT_AND_BACK + + // DataType + GL_BYTE = $1400; + GL_UNSIGNED_BYTE = $1401; + GL_SHORT = $1402; + GL_UNSIGNED_SHORT = $1403; + GL_INT = $1404; + GL_UNSIGNED_INT = $1405; + GL_FLOAT = $1406; + GL_2_BYTES = $1407; + GL_3_BYTES = $1408; + GL_4_BYTES = $1409; + GL_DOUBLE = $140A; + + // DepthFunction + // GL_NEVER + // GL_LESS + // GL_EQUAL + // GL_LEQUAL + // GL_GREATER + // GL_NOTEQUAL + // GL_GEQUAL + // GL_ALWAYS + + // DrawBufferMode + GL_NONE = 0; + GL_FRONT_LEFT = $0400; + GL_FRONT_RIGHT = $0401; + GL_BACK_LEFT = $0402; + GL_BACK_RIGHT = $0403; + GL_FRONT = $0404; + GL_BACK = $0405; + GL_LEFT = $0406; + GL_RIGHT = $0407; + GL_FRONT_AND_BACK = $0408; + GL_AUX0 = $0409; + GL_AUX1 = $040A; + GL_AUX2 = $040B; + GL_AUX3 = $040C; + + // Enable + // GL_FOG + // GL_LIGHTING + // GL_TEXTURE_1D + // GL_TEXTURE_2D + // GL_LINE_STIPPLE + // GL_POLYGON_STIPPLE + // GL_CULL_FACE + // GL_ALPHA_TEST + // GL_BLEND + // GL_INDEX_LOGIC_OP + // GL_COLOR_LOGIC_OP + // GL_DITHER + // GL_STENCIL_TEST + // GL_DEPTH_TEST + // GL_CLIP_PLANE0 + // GL_CLIP_PLANE1 + // GL_CLIP_PLANE2 + // GL_CLIP_PLANE3 + // GL_CLIP_PLANE4 + // GL_CLIP_PLANE5 + // GL_LIGHT0 + // GL_LIGHT1 + // GL_LIGHT2 + // GL_LIGHT3 + // GL_LIGHT4 + // GL_LIGHT5 + // GL_LIGHT6 + // GL_LIGHT7 + // GL_TEXTURE_GEN_S + // GL_TEXTURE_GEN_T + // GL_TEXTURE_GEN_R + // GL_TEXTURE_GEN_Q + // GL_MAP1_VERTEX_3 + // GL_MAP1_VERTEX_4 + // GL_MAP1_COLOR_4 + // GL_MAP1_INDEX + // GL_MAP1_NORMAL + // GL_MAP1_TEXTURE_COORD_1 + // GL_MAP1_TEXTURE_COORD_2 + // GL_MAP1_TEXTURE_COORD_3 + // GL_MAP1_TEXTURE_COORD_4 + // GL_MAP2_VERTEX_3 + // GL_MAP2_VERTEX_4 + // GL_MAP2_COLOR_4 + // GL_MAP2_INDEX + // GL_MAP2_NORMAL + // GL_MAP2_TEXTURE_COORD_1 + // GL_MAP2_TEXTURE_COORD_2 + // GL_MAP2_TEXTURE_COORD_3 + // GL_MAP2_TEXTURE_COORD_4 + // GL_POINT_SMOOTH + // GL_LINE_SMOOTH + // GL_POLYGON_SMOOTH + // GL_SCISSOR_TEST + // GL_COLOR_MATERIAL + // GL_NORMALIZE + // GL_AUTO_NORMAL + // GL_VERTEX_ARRAY + // GL_NORMAL_ARRAY + // GL_COLOR_ARRAY + // GL_INDEX_ARRAY + // GL_TEXTURE_COORD_ARRAY + // GL_EDGE_FLAG_ARRAY + // GL_POLYGON_OFFSET_POINT + // GL_POLYGON_OFFSET_LINE + // GL_POLYGON_OFFSET_FILL + + // ErrorCode + GL_NO_ERROR = 0; + GL_INVALID_ENUM = $0500; + GL_INVALID_VALUE = $0501; + GL_INVALID_OPERATION = $0502; + GL_STACK_OVERFLOW = $0503; + GL_STACK_UNDERFLOW = $0504; + GL_OUT_OF_MEMORY = $0505; + + // FeedBackMode + GL_2D = $0600; + GL_3D = $0601; + GL_3D_COLOR = $0602; + GL_3D_COLOR_TEXTURE = $0603; + GL_4D_COLOR_TEXTURE = $0604; + + // FeedBackToken + GL_PASS_THROUGH_TOKEN = $0700; + GL_POINT_TOKEN = $0701; + GL_LINE_TOKEN = $0702; + GL_POLYGON_TOKEN = $0703; + GL_BITMAP_TOKEN = $0704; + GL_DRAW_PIXEL_TOKEN = $0705; + GL_COPY_PIXEL_TOKEN = $0706; + GL_LINE_RESET_TOKEN = $0707; + + // FogMode + // GL_LINEAR + GL_EXP = $0800; + GL_EXP2 = $0801; + + // FogParameter + // GL_FOG_COLOR + // GL_FOG_DENSITY + // GL_FOG_END + // GL_FOG_INDEX + // GL_FOG_MODE + // GL_FOG_START + + // FrontFaceDirection + GL_CW = $0900; + GL_CCW = $0901; + + // GetMapTarget + GL_COEFF = $0A00; + GL_ORDER = $0A01; + GL_DOMAIN = $0A02; + + // GetPixelMap + // GL_PIXEL_MAP_I_TO_I + // GL_PIXEL_MAP_S_TO_S + // GL_PIXEL_MAP_I_TO_R + // GL_PIXEL_MAP_I_TO_G + // GL_PIXEL_MAP_I_TO_B + // GL_PIXEL_MAP_I_TO_A + // GL_PIXEL_MAP_R_TO_R + // GL_PIXEL_MAP_G_TO_G + // GL_PIXEL_MAP_B_TO_B + // GL_PIXEL_MAP_A_TO_A + + // GetPointerTarget + // GL_VERTEX_ARRAY_POINTER + // GL_NORMAL_ARRAY_POINTER + // GL_COLOR_ARRAY_POINTER + // GL_INDEX_ARRAY_POINTER + // GL_TEXTURE_COORD_ARRAY_POINTER + // GL_EDGE_FLAG_ARRAY_POINTER + + // GetTarget + GL_CURRENT_COLOR = $0B00; + GL_CURRENT_INDEX = $0B01; + GL_CURRENT_NORMAL = $0B02; + GL_CURRENT_TEXTURE_COORDS = $0B03; + GL_CURRENT_RASTER_COLOR = $0B04; + GL_CURRENT_RASTER_INDEX = $0B05; + GL_CURRENT_RASTER_TEXTURE_COORDS = $0B06; + GL_CURRENT_RASTER_POSITION = $0B07; + GL_CURRENT_RASTER_POSITION_VALID = $0B08; + GL_CURRENT_RASTER_DISTANCE = $0B09; + GL_POINT_SMOOTH = $0B10; + GL_POINT_SIZE = $0B11; + GL_POINT_SIZE_RANGE = $0B12; + GL_POINT_SIZE_GRANULARITY = $0B13; + GL_LINE_SMOOTH = $0B20; + GL_LINE_WIDTH = $0B21; + GL_LINE_WIDTH_RANGE = $0B22; + GL_LINE_WIDTH_GRANULARITY = $0B23; + GL_LINE_STIPPLE = $0B24; + GL_LINE_STIPPLE_PATTERN = $0B25; + GL_LINE_STIPPLE_REPEAT = $0B26; + GL_LIST_MODE = $0B30; + GL_MAX_LIST_NESTING = $0B31; + GL_LIST_BASE = $0B32; + GL_LIST_INDEX = $0B33; + GL_POLYGON_MODE = $0B40; + GL_POLYGON_SMOOTH = $0B41; + GL_POLYGON_STIPPLE = $0B42; + GL_EDGE_FLAG = $0B43; + GL_CULL_FACE = $0B44; + GL_CULL_FACE_MODE = $0B45; + GL_FRONT_FACE = $0B46; + GL_LIGHTING = $0B50; + GL_LIGHT_MODEL_LOCAL_VIEWER = $0B51; + GL_LIGHT_MODEL_TWO_SIDE = $0B52; + GL_LIGHT_MODEL_AMBIENT = $0B53; + GL_SHADE_MODEL = $0B54; + GL_COLOR_MATERIAL_FACE = $0B55; + GL_COLOR_MATERIAL_PARAMETER = $0B56; + GL_COLOR_MATERIAL = $0B57; + GL_FOG = $0B60; + GL_FOG_INDEX = $0B61; + GL_FOG_DENSITY = $0B62; + GL_FOG_START = $0B63; + GL_FOG_END = $0B64; + GL_FOG_MODE = $0B65; + GL_FOG_COLOR = $0B66; + GL_DEPTH_RANGE = $0B70; + GL_DEPTH_TEST = $0B71; + GL_DEPTH_WRITEMASK = $0B72; + GL_DEPTH_CLEAR_VALUE = $0B73; + GL_DEPTH_FUNC = $0B74; + GL_ACCUM_CLEAR_VALUE = $0B80; + GL_STENCIL_TEST = $0B90; + GL_STENCIL_CLEAR_VALUE = $0B91; + GL_STENCIL_FUNC = $0B92; + GL_STENCIL_VALUE_MASK = $0B93; + GL_STENCIL_FAIL = $0B94; + GL_STENCIL_PASS_DEPTH_FAIL = $0B95; + GL_STENCIL_PASS_DEPTH_PASS = $0B96; + GL_STENCIL_REF = $0B97; + GL_STENCIL_WRITEMASK = $0B98; + GL_MATRIX_MODE = $0BA0; + GL_NORMALIZE = $0BA1; + GL_VIEWPORT = $0BA2; + GL_MODELVIEW_STACK_DEPTH = $0BA3; + GL_PROJECTION_STACK_DEPTH = $0BA4; + GL_TEXTURE_STACK_DEPTH = $0BA5; + GL_MODELVIEW_MATRIX = $0BA6; + GL_PROJECTION_MATRIX = $0BA7; + GL_TEXTURE_MATRIX = $0BA8; + GL_ATTRIB_STACK_DEPTH = $0BB0; + GL_CLIENT_ATTRIB_STACK_DEPTH = $0BB1; + GL_ALPHA_TEST = $0BC0; + GL_ALPHA_TEST_FUNC = $0BC1; + GL_ALPHA_TEST_REF = $0BC2; + GL_DITHER = $0BD0; + GL_BLEND_DST = $0BE0; + GL_BLEND_SRC = $0BE1; + GL_BLEND = $0BE2; + GL_LOGIC_OP_MODE = $0BF0; + GL_INDEX_LOGIC_OP = $0BF1; + GL_COLOR_LOGIC_OP = $0BF2; + GL_AUX_BUFFERS = $0C00; + GL_DRAW_BUFFER = $0C01; + GL_READ_BUFFER = $0C02; + GL_SCISSOR_BOX = $0C10; + GL_SCISSOR_TEST = $0C11; + GL_INDEX_CLEAR_VALUE = $0C20; + GL_INDEX_WRITEMASK = $0C21; + GL_COLOR_CLEAR_VALUE = $0C22; + GL_COLOR_WRITEMASK = $0C23; + GL_INDEX_MODE = $0C30; + GL_RGBA_MODE = $0C31; + GL_DOUBLEBUFFER = $0C32; + GL_STEREO = $0C33; + GL_RENDER_MODE = $0C40; + GL_PERSPECTIVE_CORRECTION_HINT = $0C50; + GL_POINT_SMOOTH_HINT = $0C51; + GL_LINE_SMOOTH_HINT = $0C52; + GL_POLYGON_SMOOTH_HINT = $0C53; + GL_FOG_HINT = $0C54; + GL_TEXTURE_GEN_S = $0C60; + GL_TEXTURE_GEN_T = $0C61; + GL_TEXTURE_GEN_R = $0C62; + GL_TEXTURE_GEN_Q = $0C63; + GL_PIXEL_MAP_I_TO_I = $0C70; + GL_PIXEL_MAP_S_TO_S = $0C71; + GL_PIXEL_MAP_I_TO_R = $0C72; + GL_PIXEL_MAP_I_TO_G = $0C73; + GL_PIXEL_MAP_I_TO_B = $0C74; + GL_PIXEL_MAP_I_TO_A = $0C75; + GL_PIXEL_MAP_R_TO_R = $0C76; + GL_PIXEL_MAP_G_TO_G = $0C77; + GL_PIXEL_MAP_B_TO_B = $0C78; + GL_PIXEL_MAP_A_TO_A = $0C79; + GL_PIXEL_MAP_I_TO_I_SIZE = $0CB0; + GL_PIXEL_MAP_S_TO_S_SIZE = $0CB1; + GL_PIXEL_MAP_I_TO_R_SIZE = $0CB2; + GL_PIXEL_MAP_I_TO_G_SIZE = $0CB3; + GL_PIXEL_MAP_I_TO_B_SIZE = $0CB4; + GL_PIXEL_MAP_I_TO_A_SIZE = $0CB5; + GL_PIXEL_MAP_R_TO_R_SIZE = $0CB6; + GL_PIXEL_MAP_G_TO_G_SIZE = $0CB7; + GL_PIXEL_MAP_B_TO_B_SIZE = $0CB8; + GL_PIXEL_MAP_A_TO_A_SIZE = $0CB9; + GL_UNPACK_SWAP_BYTES = $0CF0; + GL_UNPACK_LSB_FIRST = $0CF1; + GL_UNPACK_ROW_LENGTH = $0CF2; + GL_UNPACK_SKIP_ROWS = $0CF3; + GL_UNPACK_SKIP_PIXELS = $0CF4; + GL_UNPACK_ALIGNMENT = $0CF5; + GL_PACK_SWAP_BYTES = $0D00; + GL_PACK_LSB_FIRST = $0D01; + GL_PACK_ROW_LENGTH = $0D02; + GL_PACK_SKIP_ROWS = $0D03; + GL_PACK_SKIP_PIXELS = $0D04; + GL_PACK_ALIGNMENT = $0D05; + GL_MAP_COLOR = $0D10; + GL_MAP_STENCIL = $0D11; + GL_INDEX_SHIFT = $0D12; + GL_INDEX_OFFSET = $0D13; + GL_RED_SCALE = $0D14; + GL_RED_BIAS = $0D15; + GL_ZOOM_X = $0D16; + GL_ZOOM_Y = $0D17; + GL_GREEN_SCALE = $0D18; + GL_GREEN_BIAS = $0D19; + GL_BLUE_SCALE = $0D1A; + GL_BLUE_BIAS = $0D1B; + GL_ALPHA_SCALE = $0D1C; + GL_ALPHA_BIAS = $0D1D; + GL_DEPTH_SCALE = $0D1E; + GL_DEPTH_BIAS = $0D1F; + GL_MAX_EVAL_ORDER = $0D30; + GL_MAX_LIGHTS = $0D31; + GL_MAX_CLIP_PLANES = $0D32; + GL_MAX_TEXTURE_SIZE = $0D33; + GL_MAX_PIXEL_MAP_TABLE = $0D34; + GL_MAX_ATTRIB_STACK_DEPTH = $0D35; + GL_MAX_MODELVIEW_STACK_DEPTH = $0D36; + GL_MAX_NAME_STACK_DEPTH = $0D37; + GL_MAX_PROJECTION_STACK_DEPTH = $0D38; + GL_MAX_TEXTURE_STACK_DEPTH = $0D39; + GL_MAX_VIEWPORT_DIMS = $0D3A; + GL_MAX_CLIENT_ATTRIB_STACK_DEPTH = $0D3B; + GL_SUBPIXEL_BITS = $0D50; + GL_INDEX_BITS = $0D51; + GL_RED_BITS = $0D52; + GL_GREEN_BITS = $0D53; + GL_BLUE_BITS = $0D54; + GL_ALPHA_BITS = $0D55; + GL_DEPTH_BITS = $0D56; + GL_STENCIL_BITS = $0D57; + GL_ACCUM_RED_BITS = $0D58; + GL_ACCUM_GREEN_BITS = $0D59; + GL_ACCUM_BLUE_BITS = $0D5A; + GL_ACCUM_ALPHA_BITS = $0D5B; + GL_NAME_STACK_DEPTH = $0D70; + GL_AUTO_NORMAL = $0D80; + GL_MAP1_COLOR_4 = $0D90; + GL_MAP1_INDEX = $0D91; + GL_MAP1_NORMAL = $0D92; + GL_MAP1_TEXTURE_COORD_1 = $0D93; + GL_MAP1_TEXTURE_COORD_2 = $0D94; + GL_MAP1_TEXTURE_COORD_3 = $0D95; + GL_MAP1_TEXTURE_COORD_4 = $0D96; + GL_MAP1_VERTEX_3 = $0D97; + GL_MAP1_VERTEX_4 = $0D98; + GL_MAP2_COLOR_4 = $0DB0; + GL_MAP2_INDEX = $0DB1; + GL_MAP2_NORMAL = $0DB2; + GL_MAP2_TEXTURE_COORD_1 = $0DB3; + GL_MAP2_TEXTURE_COORD_2 = $0DB4; + GL_MAP2_TEXTURE_COORD_3 = $0DB5; + GL_MAP2_TEXTURE_COORD_4 = $0DB6; + GL_MAP2_VERTEX_3 = $0DB7; + GL_MAP2_VERTEX_4 = $0DB8; + GL_MAP1_GRID_DOMAIN = $0DD0; + GL_MAP1_GRID_SEGMENTS = $0DD1; + GL_MAP2_GRID_DOMAIN = $0DD2; + GL_MAP2_GRID_SEGMENTS = $0DD3; + GL_TEXTURE_1D = $0DE0; + GL_TEXTURE_2D = $0DE1; + GL_FEEDBACK_BUFFER_POINTER = $0DF0; + GL_FEEDBACK_BUFFER_SIZE = $0DF1; + GL_FEEDBACK_BUFFER_TYPE = $0DF2; + GL_SELECTION_BUFFER_POINTER = $0DF3; + GL_SELECTION_BUFFER_SIZE = $0DF4; + // GL_TEXTURE_BINDING_1D + // GL_TEXTURE_BINDING_2D + // GL_VERTEX_ARRAY + // GL_NORMAL_ARRAY + // GL_COLOR_ARRAY + // GL_INDEX_ARRAY + // GL_TEXTURE_COORD_ARRAY + // GL_EDGE_FLAG_ARRAY + // GL_VERTEX_ARRAY_SIZE + // GL_VERTEX_ARRAY_TYPE + // GL_VERTEX_ARRAY_STRIDE + // GL_NORMAL_ARRAY_TYPE + // GL_NORMAL_ARRAY_STRIDE + // GL_COLOR_ARRAY_SIZE + // GL_COLOR_ARRAY_TYPE + // GL_COLOR_ARRAY_STRIDE + // GL_INDEX_ARRAY_TYPE + // GL_INDEX_ARRAY_STRIDE + // GL_TEXTURE_COORD_ARRAY_SIZE + // GL_TEXTURE_COORD_ARRAY_TYPE + // GL_TEXTURE_COORD_ARRAY_STRIDE + // GL_EDGE_FLAG_ARRAY_STRIDE + // GL_POLYGON_OFFSET_FACTOR + // GL_POLYGON_OFFSET_UNITS + + // GetTextureParameter + // GL_TEXTURE_MAG_FILTER + // GL_TEXTURE_MIN_FILTER + // GL_TEXTURE_WRAP_S + // GL_TEXTURE_WRAP_T + GL_TEXTURE_WIDTH = $1000; + GL_TEXTURE_HEIGHT = $1001; + GL_TEXTURE_INTERNAL_FORMAT = $1003; + GL_TEXTURE_BORDER_COLOR = $1004; + GL_TEXTURE_BORDER = $1005; + // GL_TEXTURE_RED_SIZE + // GL_TEXTURE_GREEN_SIZE + // GL_TEXTURE_BLUE_SIZE + // GL_TEXTURE_ALPHA_SIZE + // GL_TEXTURE_LUMINANCE_SIZE + // GL_TEXTURE_INTENSITY_SIZE + // GL_TEXTURE_PRIORITY + // GL_TEXTURE_RESIDENT + + // HintMode + GL_DONT_CARE = $1100; + GL_FASTEST = $1101; + GL_NICEST = $1102; + + // HintTarget + // GL_PERSPECTIVE_CORRECTION_HINT + // GL_POINT_SMOOTH_HINT + // GL_LINE_SMOOTH_HINT + // GL_POLYGON_SMOOTH_HINT + // GL_FOG_HINT + + // IndexPointerType + // GL_SHORT + // GL_INT + // GL_FLOAT + // GL_DOUBLE + + // LightModelParameter + // GL_LIGHT_MODEL_AMBIENT + // GL_LIGHT_MODEL_LOCAL_VIEWER + // GL_LIGHT_MODEL_TWO_SIDE + + // LightName + GL_LIGHT0 = $4000; + GL_LIGHT1 = $4001; + GL_LIGHT2 = $4002; + GL_LIGHT3 = $4003; + GL_LIGHT4 = $4004; + GL_LIGHT5 = $4005; + GL_LIGHT6 = $4006; + GL_LIGHT7 = $4007; + + // LightParameter + GL_AMBIENT = $1200; + GL_DIFFUSE = $1201; + GL_SPECULAR = $1202; + GL_POSITION = $1203; + GL_SPOT_DIRECTION = $1204; + GL_SPOT_EXPONENT = $1205; + GL_SPOT_CUTOFF = $1206; + GL_CONSTANT_ATTENUATION = $1207; + GL_LINEAR_ATTENUATION = $1208; + GL_QUADRATIC_ATTENUATION = $1209; + + // InterleavedArrays + // GL_V2F + // GL_V3F + // GL_C4UB_V2F + // GL_C4UB_V3F + // GL_C3F_V3F + // GL_N3F_V3F + // GL_C4F_N3F_V3F + // GL_T2F_V3F + // GL_T4F_V4F + // GL_T2F_C4UB_V3F + // GL_T2F_C3F_V3F + // GL_T2F_N3F_V3F + // GL_T2F_C4F_N3F_V3F + // GL_T4F_C4F_N3F_V4F + + // ListMode + GL_COMPILE = $1300; + GL_COMPILE_AND_EXECUTE = $1301; + + // ListNameType + // GL_BYTE + // GL_UNSIGNED_BYTE + // GL_SHORT + // GL_UNSIGNED_SHORT + // GL_INT + // GL_UNSIGNED_INT + // GL_FLOAT + // GL_2_BYTES + // GL_3_BYTES + // GL_4_BYTES + + // LogicOp + GL_CLEAR = $1500; + GL_AND = $1501; + GL_AND_REVERSE = $1502; + GL_COPY = $1503; + GL_AND_INVERTED = $1504; + GL_NOOP = $1505; + GL_XOR = $1506; + GL_OR = $1507; + GL_NOR = $1508; + GL_EQUIV = $1509; + GL_INVERT = $150A; + GL_OR_REVERSE = $150B; + GL_COPY_INVERTED = $150C; + GL_OR_INVERTED = $150D; + GL_NAND = $150E; + GL_SET = $150F; + + // MapTarget + // GL_MAP1_COLOR_4 + // GL_MAP1_INDEX + // GL_MAP1_NORMAL + // GL_MAP1_TEXTURE_COORD_1 + // GL_MAP1_TEXTURE_COORD_2 + // GL_MAP1_TEXTURE_COORD_3 + // GL_MAP1_TEXTURE_COORD_4 + // GL_MAP1_VERTEX_3 + // GL_MAP1_VERTEX_4 + // GL_MAP2_COLOR_4 + // GL_MAP2_INDEX + // GL_MAP2_NORMAL + // GL_MAP2_TEXTURE_COORD_1 + // GL_MAP2_TEXTURE_COORD_2 + // GL_MAP2_TEXTURE_COORD_3 + // GL_MAP2_TEXTURE_COORD_4 + // GL_MAP2_VERTEX_3 + // GL_MAP2_VERTEX_4 + + // MaterialFace + // GL_FRONT + // GL_BACK + // GL_FRONT_AND_BACK + + // MaterialParameter + GL_EMISSION = $1600; + GL_SHININESS = $1601; + GL_AMBIENT_AND_DIFFUSE = $1602; + GL_COLOR_INDEXES = $1603; + // GL_AMBIENT + // GL_DIFFUSE + // GL_SPECULAR + + // MatrixMode + GL_MODELVIEW = $1700; + GL_PROJECTION = $1701; + GL_TEXTURE = $1702; + + // MeshMode1 + // GL_POINT + // GL_LINE + + // MeshMode2 + // GL_POINT + // GL_LINE + // GL_FILL + + // NormalPointerType + // GL_BYTE + // GL_SHORT + // GL_INT + // GL_FLOAT + // GL_DOUBLE + + // PixelCopyType + GL_COLOR = $1800; + GL_DEPTH = $1801; + GL_STENCIL = $1802; + + // PixelFormat + GL_COLOR_INDEX = $1900; + GL_STENCIL_INDEX = $1901; + GL_DEPTH_COMPONENT = $1902; + GL_RED = $1903; + GL_GREEN = $1904; + GL_BLUE = $1905; + GL_ALPHA = $1906; + GL_RGB = $1907; + GL_RGBA = $1908; + GL_LUMINANCE = $1909; + GL_LUMINANCE_ALPHA = $190A; + + // PixelMap + // GL_PIXEL_MAP_I_TO_I + // GL_PIXEL_MAP_S_TO_S + // GL_PIXEL_MAP_I_TO_R + // GL_PIXEL_MAP_I_TO_G + // GL_PIXEL_MAP_I_TO_B + // GL_PIXEL_MAP_I_TO_A + // GL_PIXEL_MAP_R_TO_R + // GL_PIXEL_MAP_G_TO_G + // GL_PIXEL_MAP_B_TO_B + // GL_PIXEL_MAP_A_TO_A + + // PixelStore + // GL_UNPACK_SWAP_BYTES + // GL_UNPACK_LSB_FIRST + // GL_UNPACK_ROW_LENGTH + // GL_UNPACK_SKIP_ROWS + // GL_UNPACK_SKIP_PIXELS + // GL_UNPACK_ALIGNMENT + // GL_PACK_SWAP_BYTES + // GL_PACK_LSB_FIRST + // GL_PACK_ROW_LENGTH + // GL_PACK_SKIP_ROWS + // GL_PACK_SKIP_PIXELS + // GL_PACK_ALIGNMENT + + // PixelTransfer + // GL_MAP_COLOR + // GL_MAP_STENCIL + // GL_INDEX_SHIFT + // GL_INDEX_OFFSET + // GL_RED_SCALE + // GL_RED_BIAS + // GL_GREEN_SCALE + // GL_GREEN_BIAS + // GL_BLUE_SCALE + // GL_BLUE_BIAS + // GL_ALPHA_SCALE + // GL_ALPHA_BIAS + // GL_DEPTH_SCALE + // GL_DEPTH_BIAS + + // PixelType + GL_BITMAP = $1A00; + // GL_BYTE + // GL_UNSIGNED_BYTE + // GL_SHORT + // GL_UNSIGNED_SHORT + // GL_INT + // GL_UNSIGNED_INT + // GL_FLOAT + + // PolygonMode + GL_POINT = $1B00; + GL_LINE = $1B01; + GL_FILL = $1B02; + + // ReadBufferMode + // GL_FRONT_LEFT + // GL_FRONT_RIGHT + // GL_BACK_LEFT + // GL_BACK_RIGHT + // GL_FRONT + // GL_BACK + // GL_LEFT + // GL_RIGHT + // GL_AUX0 + // GL_AUX1 + // GL_AUX2 + // GL_AUX3 + + // RenderingMode + GL_RENDER = $1C00; + GL_FEEDBACK = $1C01; + GL_SELECT = $1C02; + + // ShadingModel + GL_FLAT = $1D00; + GL_SMOOTH = $1D01; + + // StencilFunction + // GL_NEVER + // GL_LESS + // GL_EQUAL + // GL_LEQUAL + // GL_GREATER + // GL_NOTEQUAL + // GL_GEQUAL + // GL_ALWAYS + + // StencilOp + // GL_ZERO + GL_KEEP = $1E00; + GL_REPLACE = $1E01; + GL_INCR = $1E02; + GL_DECR = $1E03; + // GL_INVERT + + // StringName + GL_VENDOR = $1F00; + GL_RENDERER = $1F01; + GL_VERSION = $1F02; + GL_EXTENSIONS = $1F03; + + // TextureCoordName + GL_S = $2000; + GL_T = $2001; + GL_R = $2002; + GL_Q = $2003; + + // TexCoordPointerType + // GL_SHORT + // GL_INT + // GL_FLOAT + // GL_DOUBLE + + // TextureEnvMode + GL_MODULATE = $2100; + GL_DECAL = $2101; + // GL_BLEND + // GL_REPLACE + + // TextureEnvParameter + GL_TEXTURE_ENV_MODE = $2200; + GL_TEXTURE_ENV_COLOR = $2201; + + // TextureEnvTarget + GL_TEXTURE_ENV = $2300; + + // TextureGenMode + GL_EYE_LINEAR = $2400; + GL_OBJECT_LINEAR = $2401; + GL_SPHERE_MAP = $2402; + + // TextureGenParameter + GL_TEXTURE_GEN_MODE = $2500; + GL_OBJECT_PLANE = $2501; + GL_EYE_PLANE = $2502; + + // TextureMagFilter + GL_NEAREST = $2600; + GL_LINEAR = $2601; + + // TextureMinFilter + // GL_NEAREST + // GL_LINEAR + GL_NEAREST_MIPMAP_NEAREST = $2700; + GL_LINEAR_MIPMAP_NEAREST = $2701; + GL_NEAREST_MIPMAP_LINEAR = $2702; + GL_LINEAR_MIPMAP_LINEAR = $2703; + + // TextureParameterName + GL_TEXTURE_MAG_FILTER = $2800; + GL_TEXTURE_MIN_FILTER = $2801; + GL_TEXTURE_WRAP_S = $2802; + GL_TEXTURE_WRAP_T = $2803; + // GL_TEXTURE_BORDER_COLOR + // GL_TEXTURE_PRIORITY + + // TextureTarget + // GL_TEXTURE_1D + // GL_TEXTURE_2D + // GL_PROXY_TEXTURE_1D + // GL_PROXY_TEXTURE_2D + + // TextureWrapMode + GL_CLAMP = $2900; + GL_REPEAT = $2901; + + // VertexPointerType + // GL_SHORT + // GL_INT + // GL_FLOAT + // GL_DOUBLE + + // ClientAttribMask + GL_CLIENT_PIXEL_STORE_BIT = $00000001; + GL_CLIENT_VERTEX_ARRAY_BIT = $00000002; + GL_CLIENT_ALL_ATTRIB_BITS = $FFFFFFFF; + + // polygon_offset + GL_POLYGON_OFFSET_FACTOR = $8038; + GL_POLYGON_OFFSET_UNITS = $2A00; + GL_POLYGON_OFFSET_POINT = $2A01; + GL_POLYGON_OFFSET_LINE = $2A02; + GL_POLYGON_OFFSET_FILL = $8037; + + // texture + GL_ALPHA4 = $803B; + GL_ALPHA8 = $803C; + GL_ALPHA12 = $803D; + GL_ALPHA16 = $803E; + GL_LUMINANCE4 = $803F; + GL_LUMINANCE8 = $8040; + GL_LUMINANCE12 = $8041; + GL_LUMINANCE16 = $8042; + GL_LUMINANCE4_ALPHA4 = $8043; + GL_LUMINANCE6_ALPHA2 = $8044; + GL_LUMINANCE8_ALPHA8 = $8045; + GL_LUMINANCE12_ALPHA4 = $8046; + GL_LUMINANCE12_ALPHA12 = $8047; + GL_LUMINANCE16_ALPHA16 = $8048; + GL_INTENSITY = $8049; + GL_INTENSITY4 = $804A; + GL_INTENSITY8 = $804B; + GL_INTENSITY12 = $804C; + GL_INTENSITY16 = $804D; + GL_R3_G3_B2 = $2A10; + GL_RGB4 = $804F; + GL_RGB5 = $8050; + GL_RGB8 = $8051; + GL_RGB10 = $8052; + GL_RGB12 = $8053; + GL_RGB16 = $8054; + GL_RGBA2 = $8055; + GL_RGBA4 = $8056; + GL_RGB5_A1 = $8057; + GL_RGBA8 = $8058; + GL_RGB10_A2 = $8059; + GL_RGBA12 = $805A; + GL_RGBA16 = $805B; + GL_TEXTURE_RED_SIZE = $805C; + GL_TEXTURE_GREEN_SIZE = $805D; + GL_TEXTURE_BLUE_SIZE = $805E; + GL_TEXTURE_ALPHA_SIZE = $805F; + GL_TEXTURE_LUMINANCE_SIZE = $8060; + GL_TEXTURE_INTENSITY_SIZE = $8061; + GL_PROXY_TEXTURE_1D = $8063; + GL_PROXY_TEXTURE_2D = $8064; + + // texture_object + GL_TEXTURE_PRIORITY = $8066; + GL_TEXTURE_RESIDENT = $8067; + GL_TEXTURE_BINDING_1D = $8068; + GL_TEXTURE_BINDING_2D = $8069; + + // vertex_array + GL_VERTEX_ARRAY = $8074; + GL_NORMAL_ARRAY = $8075; + GL_COLOR_ARRAY = $8076; + GL_INDEX_ARRAY = $8077; + GL_TEXTURE_COORD_ARRAY = $8078; + GL_EDGE_FLAG_ARRAY = $8079; + GL_VERTEX_ARRAY_SIZE = $807A; + GL_VERTEX_ARRAY_TYPE = $807B; + GL_VERTEX_ARRAY_STRIDE = $807C; + GL_NORMAL_ARRAY_TYPE = $807E; + GL_NORMAL_ARRAY_STRIDE = $807F; + GL_COLOR_ARRAY_SIZE = $8081; + GL_COLOR_ARRAY_TYPE = $8082; + GL_COLOR_ARRAY_STRIDE = $8083; + GL_INDEX_ARRAY_TYPE = $8085; + GL_INDEX_ARRAY_STRIDE = $8086; + GL_TEXTURE_COORD_ARRAY_SIZE = $8088; + GL_TEXTURE_COORD_ARRAY_TYPE = $8089; + GL_TEXTURE_COORD_ARRAY_STRIDE = $808A; + GL_EDGE_FLAG_ARRAY_STRIDE = $808C; + GL_VERTEX_ARRAY_POINTER = $808E; + GL_NORMAL_ARRAY_POINTER = $808F; + GL_COLOR_ARRAY_POINTER = $8090; + GL_INDEX_ARRAY_POINTER = $8091; + GL_TEXTURE_COORD_ARRAY_POINTER = $8092; + GL_EDGE_FLAG_ARRAY_POINTER = $8093; + GL_V2F = $2A20; + GL_V3F = $2A21; + GL_C4UB_V2F = $2A22; + GL_C4UB_V3F = $2A23; + GL_C3F_V3F = $2A24; + GL_N3F_V3F = $2A25; + GL_C4F_N3F_V3F = $2A26; + GL_T2F_V3F = $2A27; + GL_T4F_V4F = $2A28; + GL_T2F_C4UB_V3F = $2A29; + GL_T2F_C3F_V3F = $2A2A; + GL_T2F_N3F_V3F = $2A2B; + GL_T2F_C4F_N3F_V3F = $2A2C; + GL_T4F_C4F_N3F_V4F = $2A2D; + + // Extensions + GL_EXT_vertex_array = 1; + GL_WIN_swap_hint = 1; + GL_EXT_bgra = 1; + GL_EXT_paletted_texture = 1; + + // EXT_vertex_array + GL_VERTEX_ARRAY_EXT = $8074; + GL_NORMAL_ARRAY_EXT = $8075; + GL_COLOR_ARRAY_EXT = $8076; + GL_INDEX_ARRAY_EXT = $8077; + GL_TEXTURE_COORD_ARRAY_EXT = $8078; + GL_EDGE_FLAG_ARRAY_EXT = $8079; + GL_VERTEX_ARRAY_SIZE_EXT = $807A; + GL_VERTEX_ARRAY_TYPE_EXT = $807B; + GL_VERTEX_ARRAY_STRIDE_EXT = $807C; + GL_VERTEX_ARRAY_COUNT_EXT = $807D; + GL_NORMAL_ARRAY_TYPE_EXT = $807E; + GL_NORMAL_ARRAY_STRIDE_EXT = $807F; + GL_NORMAL_ARRAY_COUNT_EXT = $8080; + GL_COLOR_ARRAY_SIZE_EXT = $8081; + GL_COLOR_ARRAY_TYPE_EXT = $8082; + GL_COLOR_ARRAY_STRIDE_EXT = $8083; + GL_COLOR_ARRAY_COUNT_EXT = $8084; + GL_INDEX_ARRAY_TYPE_EXT = $8085; + GL_INDEX_ARRAY_STRIDE_EXT = $8086; + GL_INDEX_ARRAY_COUNT_EXT = $8087; + GL_TEXTURE_COORD_ARRAY_SIZE_EXT = $8088; + GL_TEXTURE_COORD_ARRAY_TYPE_EXT = $8089; + GL_TEXTURE_COORD_ARRAY_STRIDE_EXT = $808A; + GL_TEXTURE_COORD_ARRAY_COUNT_EXT = $808B; + GL_EDGE_FLAG_ARRAY_STRIDE_EXT = $808C; + GL_EDGE_FLAG_ARRAY_COUNT_EXT = $808D; + GL_VERTEX_ARRAY_POINTER_EXT = $808E; + GL_NORMAL_ARRAY_POINTER_EXT = $808F; + GL_COLOR_ARRAY_POINTER_EXT = $8090; + GL_INDEX_ARRAY_POINTER_EXT = $8091; + GL_TEXTURE_COORD_ARRAY_POINTER_EXT = $8092; + GL_EDGE_FLAG_ARRAY_POINTER_EXT = $8093; + GL_DOUBLE_EXT = GL_DOUBLE; + + // EXT_bgra + GL_BGR_EXT = $80E0; + GL_BGRA_EXT = $80E1; + + // EXT_paletted_texture + + // These must match the GL_COLOR_TABLE_*_SGI enumerants + GL_COLOR_TABLE_FORMAT_EXT = $80D8; + GL_COLOR_TABLE_WIDTH_EXT = $80D9; + GL_COLOR_TABLE_RED_SIZE_EXT = $80DA; + GL_COLOR_TABLE_GREEN_SIZE_EXT = $80DB; + GL_COLOR_TABLE_BLUE_SIZE_EXT = $80DC; + GL_COLOR_TABLE_ALPHA_SIZE_EXT = $80DD; + GL_COLOR_TABLE_LUMINANCE_SIZE_EXT = $80DE; + GL_COLOR_TABLE_INTENSITY_SIZE_EXT = $80DF; + + GL_COLOR_INDEX1_EXT = $80E2; + GL_COLOR_INDEX2_EXT = $80E3; + GL_COLOR_INDEX4_EXT = $80E4; + GL_COLOR_INDEX8_EXT = $80E5; + GL_COLOR_INDEX12_EXT = $80E6; + GL_COLOR_INDEX16_EXT = $80E7; + + // For compatibility with OpenGL v1.0 + GL_LOGIC_OP = GL_INDEX_LOGIC_OP; + GL_TEXTURE_COMPONENTS = GL_TEXTURE_INTERNAL_FORMAT; + +{******************************************************************************} + +{$IFDEF MORPHOS} + +{ MorphOS GL works differently due to different dynamic-library handling on Amiga-like } +{ systems, so its headers are included here. } +{$INCLUDE tinyglh.inc} + +{$ELSE MORPHOS} +var + glAccum: procedure(op: GLenum; value: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAlphaFunc: procedure(func: GLenum; ref: GLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAreTexturesResident: function (n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glArrayElement: procedure(i: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBegin: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindTexture: procedure(target: GLenum; texture: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBitmap: procedure (width, height: GLsizei; xorig, yorig: GLfloat; xmove, ymove: GLfloat; const bitmap: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBlendFunc: procedure(sfactor, dfactor: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCallList: procedure(list: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCallLists: procedure(n: GLsizei; atype: GLenum; const lists: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClear: procedure(mask: GLbitfield); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearAccum: procedure(red, green, blue, alpha: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearColor: procedure(red, green, blue, alpha: GLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearDepth: procedure(depth: GLclampd); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearIndex: procedure(c: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearStencil: procedure(s: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClipPlane: procedure(plane: GLenum; const equation: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3b: procedure(red, green, blue: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3bv: procedure(const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3d: procedure(red, green, blue: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3f: procedure(red, green, blue: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3i: procedure(red, green, blue: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3s: procedure(red, green, blue: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3ub: procedure(red, green, blue: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3ubv: procedure(const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3ui: procedure(red, green, blue: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3uiv: procedure(const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3us: procedure(red, green, blue: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3usv: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4b: procedure(red, green, blue, alpha: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4bv: procedure(const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4d: procedure(red, green, blue, alpha: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4f: procedure(red, green, blue, alpha: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4i: procedure(red, green, blue, alpha: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4s: procedure(red, green, blue, alpha: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ub: procedure(red, green, blue, alpha: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ubv: procedure(const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ui: procedure(red, green, blue, alpha: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4uiv: procedure(const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4us: procedure(red, green, blue, alpha: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4usv: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorMask: procedure(red, green, blue, alpha: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorMaterial: procedure(face, mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyPixels: procedure(x, y: GLint; width, height: GLsizei; atype: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyTexImage1D: procedure (target: GLenum; level: GLint; internalFormat: GLenum; x, y: GLint; width: GLsizei; border: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyTexImage2D: procedure(target: GLenum; level: GLint; internalFormat: GLenum; x, y: GLint; width, height: GLsizei; border: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyTexSubImage1D: procedure(target: GLenum; level, xoffset, x, y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyTexSubImage2D: procedure(target: GLenum; level, xoffset, yoffset, x, y: GLint; width, height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCullFace: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteLists: procedure(list: GLuint; range: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteTextures: procedure(n: GLsizei; const textures: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDepthFunc: procedure(func: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDepthMask: procedure(flag: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDepthRange: procedure(zNear, zFar: GLclampd); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisable: procedure(cap: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisableClientState: procedure(aarray: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawArrays: procedure(mode: GLenum; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawBuffer: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElements: procedure(mode: GLenum; count: GLsizei; atype: GLenum; const indices: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawPixels: procedure(width, height: GLsizei; format, atype: GLenum; const pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEdgeFlag: procedure(flag: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEdgeFlagPointer: procedure(stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEdgeFlagv: procedure(const flag: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnable: procedure(cap: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnableClientState: procedure(aarray: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnd: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndList: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord1d: procedure(u: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord1dv: procedure(const u: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord1f: procedure(u: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord1fv: procedure(const u: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord2d: procedure(u, v: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord2dv: procedure(const u: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord2f: procedure(u, v: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord2fv: procedure(const u: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalMesh1: procedure(mode: GLenum; i1, i2: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalMesh2: procedure(mode: GLenum; i1, i2, j1, j2: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalPoint1: procedure(i: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalPoint2: procedure(i, j: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFeedbackBuffer: procedure(size: GLsizei; atype: GLenum; buffer: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFinish: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFlush: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogf: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogfv: procedure(pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogi: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogiv: procedure(pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFrontFace: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFrustum: procedure(left, right, bottom, top, zNear, zFar: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenLists: function(range: GLsizei): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenTextures: procedure(n: GLsizei; textures: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBooleanv: procedure(pname: GLenum; params: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetClipPlane: procedure(plane: GLenum; equation: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetDoublev: procedure(pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetError: function: GLenum; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFloatv: procedure(pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetIntegerv: procedure(pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetLightfv: procedure(light, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetLightiv: procedure(light, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapdv: procedure(target, query: GLenum; v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapfv: procedure(target, query: GLenum; v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapiv: procedure(target, query: GLenum; v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMaterialfv: procedure(face, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMaterialiv: procedure(face, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPixelMapfv: procedure(map: GLenum; values: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPixelMapuiv: procedure(map: GLenum; values: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPixelMapusv: procedure(map: GLenum; values: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPointerv: procedure(pname: GLenum; params: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPolygonStipple: procedure(mask: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetString: function(name: GLenum): PChar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexEnvfv: procedure(target, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexEnviv: procedure(target, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexGendv: procedure(coord, pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexGenfv: procedure(coord, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexGeniv: procedure(coord, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexImage: procedure(target: GLenum; level: GLint; format: GLenum; atype: GLenum; pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexLevelParameterfv: procedure(target: GLenum; level: GLint; pname: GLenum; params: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexLevelParameteriv: procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexParameterfv: procedure(target, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexParameteriv: procedure(target, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glHint: procedure(target, mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexMask: procedure(mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexPointer: procedure(atype: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexd: procedure(c: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexdv: procedure(const c: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexf: procedure(c: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexfv: procedure(const c: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexi: procedure(c: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexiv: procedure(const c: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexs: procedure(c: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexsv: procedure(const c: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexub: procedure(c: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexubv: procedure(const c: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glInitNames: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glInterleavedArrays: procedure(format: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsEnabled: function(cap: GLenum): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsList: function(list: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsTexture: function(texture: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightModelf: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightModelfv: procedure(pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightModeli: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightModeliv: procedure(pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightf: procedure(light, pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightfv: procedure(light, pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLighti: procedure(light, pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightiv: procedure(light, pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLineStipple: procedure(factor: GLint; pattern: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLineWidth: procedure(width: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glListBase: procedure(base: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadIdentity: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadMatrixd: procedure(const m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadMatrixf: procedure(const m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadName: procedure(name: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLogicOp: procedure(opcode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMap1d: procedure(target: GLenum; u1, u2: GLdouble; stride, order: GLint; const points: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMap1f: procedure(target: GLenum; u1, u2: GLfloat; stride, order: GLint; const points: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMap2d: procedure(target: GLenum; u1, u2: GLdouble; ustride, uorder: GLint; v1, v2: GLdouble; vstride, vorder: GLint; const points: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMap2f: procedure(target: GLenum; u1, u2: GLfloat; ustride, uorder: GLint; v1, v2: GLfloat; vstride, vorder: GLint; const points: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapGrid1d: procedure(un: GLint; u1, u2: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapGrid1f: procedure(un: GLint; u1, u2: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapGrid2d: procedure(un: GLint; u1, u2: GLdouble; vn: GLint; v1, v2: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapGrid2f: procedure(un: GLint; u1, u2: GLfloat; vn: GLint; v1, v2: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMaterialf: procedure(face, pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMaterialfv: procedure(face, pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMateriali: procedure(face, pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMaterialiv: procedure(face, pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMatrixMode: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultMatrixd: procedure(const m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultMatrixf: procedure(const m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNewList: procedure(list: GLuint; mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3b: procedure(nx, ny, nz: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3bv: procedure(const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3d: procedure(nx, ny, nz: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3f: procedure(nx, ny, nz: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3i: procedure(nx, ny, nz: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3s: procedure(nx, ny, nz: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalPointer: procedure(atype: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glOrtho: procedure(left, right, bottom, top, zNear, zFar: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPassThrough: procedure(token: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelMapfv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelMapuiv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelMapusv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelStoref: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelStorei: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelTransferf: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelTransferi: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelZoom: procedure(xfactor, yfactor: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointSize: procedure(size: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPolygonMode: procedure(face, mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPolygonOffset: procedure(factor, units: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPolygonStipple: procedure(const mask: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPopAttrib: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPopClientAttrib: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPopMatrix: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPopName: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPrioritizeTextures: procedure(n: GLsizei; const textures: PGLuint; const priorities: PGLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPushAttrib: procedure(mask: GLbitfield); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPushClientAttrib: procedure(mask: GLbitfield); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPushMatrix: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPushName: procedure(name: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2d: procedure(x, y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2f: procedure(x, y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2i: procedure(x, y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2s: procedure(x, y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3d: procedure(x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3f: procedure(x, y, z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3i: procedure(x, y, z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3s: procedure(x, y, z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4d: procedure(x, y, z, w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4f: procedure(x, y, z, w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4i: procedure(x, y, z, w: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4s: procedure(x, y, z, w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReadBuffer: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReadPixels: procedure(x, y: GLint; width, height: GLsizei; format, atype: GLenum; pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectd: procedure(x1, y1, x2, y2: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectdv: procedure(const v1: PGLdouble; const v2: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectf: procedure(x1, y1, x2, y2: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectfv: procedure(const v1: PGLfloat; const v2: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRecti: procedure(x1, y1, x2, y2: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectiv: procedure(const v1: PGLint; const v2: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRects: procedure(x1, y1, x2, y2: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectsv: procedure(const v1: PGLshort; const v2: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRenderMode: function(mode: GLint): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRotated: procedure(angle, x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRotatef: procedure(angle, x, y, z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glScaled: procedure(x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glScalef: procedure(x, y, z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glScissor: procedure(x, y: GLint; width, height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSelectBuffer: procedure(size: GLsizei; buffer: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShadeModel: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilFunc: procedure(func: GLenum; ref: GLint; mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilMask: procedure(mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilOp: procedure(fail, zfail, zpass: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1d: procedure(s: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1f: procedure(s: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1i: procedure(s: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1s: procedure(s: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2d: procedure(s, t: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2f: procedure(s, t: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2i: procedure(s, t: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2s: procedure(s, t: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3d: procedure(s, t, r: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3f: procedure(s, t, r: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3i: procedure(s, t, r: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3s: procedure(s, t, r: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4d: procedure(s, t, r, q: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4f: procedure(s, t, r, q: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4i: procedure(s, t, r, q: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4s: procedure(s, t, r, q: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexEnvf: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexEnvfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexEnvi: procedure(target: GLenum; pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexEnviv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGend: procedure(coord: GLenum; pname: GLenum; param: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGendv: procedure(coord: GLenum; pname: GLenum; const params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGenf: procedure(coord: GLenum; pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGenfv: procedure(coord: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGeni: procedure(coord: GLenum; pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGeniv: procedure(coord: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexImage1D: procedure(target: GLenum; level, internalformat: GLint; width: GLsizei; border: GLint; format, atype: GLenum; const pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexImage2D: procedure(target: GLenum; level, internalformat: GLint; width, height: GLsizei; border: GLint; format, atype: GLenum; const pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameterf: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameteri: procedure(target: GLenum; pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexSubImage1D: procedure(target: GLenum; level, xoffset: GLint; width: GLsizei; format, atype: GLenum; const pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexSubImage2D: procedure(target: GLenum; level, xoffset, yoffset: GLint; width, height: GLsizei; format, atype: GLenum; const pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTranslated: procedure(x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTranslatef: procedure(x, y, z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2d: procedure(x, y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2f: procedure(x, y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2i: procedure(x, y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2s: procedure(x, y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3d: procedure(x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3f: procedure(x, y, z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3i: procedure(x, y, z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3s: procedure(x, y, z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4d: procedure(x, y, z, w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4f: procedure(x, y, z, w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4i: procedure(x, y, z, w: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4s: procedure(x, y, z, w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glViewport: procedure(x, y: GLint; width, height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + {$IFDEF msWindows} + ChoosePixelFormat: function(DC: HDC; p2: PPixelFormatDescriptor): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + {$ENDIF} +{$ENDIF MORPHOS} + +type + // EXT_vertex_array + PFNGLARRAYELEMENTEXTPROC = procedure(i: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLDRAWARRAYSEXTPROC = procedure(mode: GLenum; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLVERTEXPOINTEREXTPROC = procedure(size: GLint; atype: GLenum; + stride, count: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLNORMALPOINTEREXTPROC = procedure(atype: GLenum; stride, count: GLsizei; + const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLCOLORPOINTEREXTPROC = procedure(size: GLint; atype: GLenum; stride, count: GLsizei; + const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLINDEXPOINTEREXTPROC = procedure(atype: GLenum; stride, count: GLsizei; + const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLTEXCOORDPOINTEREXTPROC = procedure(size: GLint; atype: GLenum; + stride, count: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLEDGEFLAGPOINTEREXTPROC = procedure(stride, count: GLsizei; + const pointer: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLGETPOINTERVEXTPROC = procedure(pname: GLenum; params: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLARRAYELEMENTARRAYEXTPROC = procedure(mode: GLenum; count: GLsizei; + const pi: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + // WIN_swap_hint + PFNGLADDSWAPHINTRECTWINPROC = procedure(x, y: GLint; width, height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + // EXT_paletted_texture + PFNGLCOLORTABLEEXTPROC = procedure(target, internalFormat: GLenum; width: GLsizei; + format, atype: GLenum; const data: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLCOLORSUBTABLEEXTPROC = procedure(target: GLenum; start, count: GLsizei; + format, atype: GLenum; const data: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLGETCOLORTABLEEXTPROC = procedure(target, format, atype: GLenum; data: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLGETCOLORTABLEPARAMETERIVEXTPROC = procedure(target, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLGETCOLORTABLEPARAMETERFVEXTPROC = procedure(target, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//procedure LoadOpenGL(const dll: String); +//procedure FreeOpenGL; + +procedure initializeopengl(const sonames: array of filenamety); //[] = default +procedure releaseopengl; +procedure regglinit(const initproc: dynlibprocty); +procedure reggldeinit(const deinitproc: dynlibprocty); + +implementation +uses +{$if defined(cpui386) or defined(cpux86_64)} + math, +{$ifend} + msesys,msedatalist{$ifdef mswindows}{$else}{$endif}{, + mseglextglob}; + +{$ifdef mswindows} +function WinChoosePixelFormat(DC: HDC; p2: PPixelFormatDescriptor): Integer; + {$ifdef wincall}stdcall{$else}cdecl{$endif} + ; external 'gdi32' name 'ChoosePixelFormat'; +{$endif} + +var + libinfo: dynlibinfoty; + +procedure regglinit(const initproc: dynlibprocty); +begin + regdynlibinit(libinfo,initproc); +end; + +procedure reggldeinit(const deinitproc: dynlibprocty); +begin + regdynlibdeinit(libinfo,deinitproc); +end; + +procedure init(const data: pointer); +begin + { according to bug 7570, this is necessary on all x86 platforms, + maybe we've to fix the sse control word as well } + { Yes, at least for darwin/x86_64 (JM) } +{$if defined(cpui386) or defined(cpux86_64)} + SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide,exOverflow, + exUnderflow, exPrecision]); +{$ifend} +{$ifdef mswindows} +{$else} + if not mseglloadextensions([gle_glx]) then begin + raise exception.create('Can not load glx.'); + end; +{$endif} + mseglloadextensions([gle_gl_version_1_5]); +end; + +procedure deinit(const data: pointer); +begin + //dummy +end; + +procedure initializeopengl(const sonames: array of filenamety); //[] = default +const + funcs: array[0..335] of funcinfoty = ( + (n: 'glAccum'; d: {$ifndef FPC}@{$endif}@glAccum), + (n: 'glAlphaFunc'; d: {$ifndef FPC}@{$endif}@glAlphaFunc), + (n: 'glAreTexturesResident'; d: {$ifndef FPC}@{$endif}@glAreTexturesResident), + (n: 'glArrayElement'; d: {$ifndef FPC}@{$endif}@glArrayElement), + (n: 'glBegin'; d: {$ifndef FPC}@{$endif}@glBegin), + (n: 'glBindTexture'; d: {$ifndef FPC}@{$endif}@glBindTexture), + (n: 'glBitmap'; d: {$ifndef FPC}@{$endif}@glBitmap), + (n: 'glBlendFunc'; d: {$ifndef FPC}@{$endif}@glBlendFunc), + (n: 'glCallList'; d: {$ifndef FPC}@{$endif}@glCallList), + (n: 'glCallLists'; d: {$ifndef FPC}@{$endif}@glCallLists), + (n: 'glClear'; d: {$ifndef FPC}@{$endif}@glClear), + (n: 'glClearAccum'; d: {$ifndef FPC}@{$endif}@glClearAccum), + (n: 'glClearColor'; d: {$ifndef FPC}@{$endif}@glClearColor), + (n: 'glClearDepth'; d: {$ifndef FPC}@{$endif}@glClearDepth), + (n: 'glClearIndex'; d: {$ifndef FPC}@{$endif}@glClearIndex), + (n: 'glClearStencil'; d: {$ifndef FPC}@{$endif}@glClearStencil), + (n: 'glClipPlane'; d: {$ifndef FPC}@{$endif}@glClipPlane), + (n: 'glColor3b'; d: {$ifndef FPC}@{$endif}@glColor3b), + (n: 'glColor3bv'; d: {$ifndef FPC}@{$endif}@glColor3bv), + (n: 'glColor3d'; d: {$ifndef FPC}@{$endif}@glColor3d), + (n: 'glColor3dv'; d: {$ifndef FPC}@{$endif}@glColor3dv), + (n: 'glColor3f'; d: {$ifndef FPC}@{$endif}@glColor3f), + (n: 'glColor3fv'; d: {$ifndef FPC}@{$endif}@glColor3fv), + (n: 'glColor3i'; d: {$ifndef FPC}@{$endif}@glColor3i), + (n: 'glColor3iv'; d: {$ifndef FPC}@{$endif}@glColor3iv), + (n: 'glColor3s'; d: {$ifndef FPC}@{$endif}@glColor3s), + (n: 'glColor3sv'; d: {$ifndef FPC}@{$endif}@glColor3sv), + (n: 'glColor3ub'; d: {$ifndef FPC}@{$endif}@glColor3ub), + (n: 'glColor3ubv'; d: {$ifndef FPC}@{$endif}@glColor3ubv), + (n: 'glColor3ui'; d: {$ifndef FPC}@{$endif}@glColor3ui), + (n: 'glColor3uiv'; d: {$ifndef FPC}@{$endif}@glColor3uiv), + (n: 'glColor3us'; d: {$ifndef FPC}@{$endif}@glColor3us), + (n: 'glColor3usv'; d: {$ifndef FPC}@{$endif}@glColor3usv), + (n: 'glColor4b'; d: {$ifndef FPC}@{$endif}@glColor4b), + (n: 'glColor4bv'; d: {$ifndef FPC}@{$endif}@glColor4bv), + (n: 'glColor4d'; d: {$ifndef FPC}@{$endif}@glColor4d), + (n: 'glColor4dv'; d: {$ifndef FPC}@{$endif}@glColor4dv), + (n: 'glColor4f'; d: {$ifndef FPC}@{$endif}@glColor4f), + (n: 'glColor4fv'; d: {$ifndef FPC}@{$endif}@glColor4fv), + (n: 'glColor4i'; d: {$ifndef FPC}@{$endif}@glColor4i), + (n: 'glColor4iv'; d: {$ifndef FPC}@{$endif}@glColor4iv), + (n: 'glColor4s'; d: {$ifndef FPC}@{$endif}@glColor4s), + (n: 'glColor4sv'; d: {$ifndef FPC}@{$endif}@glColor4sv), + (n: 'glColor4ub'; d: {$ifndef FPC}@{$endif}@glColor4ub), + (n: 'glColor4ubv'; d: {$ifndef FPC}@{$endif}@glColor4ubv), + (n: 'glColor4ui'; d: {$ifndef FPC}@{$endif}@glColor4ui), + (n: 'glColor4uiv'; d: {$ifndef FPC}@{$endif}@glColor4uiv), + (n: 'glColor4us'; d: {$ifndef FPC}@{$endif}@glColor4us), + (n: 'glColor4usv'; d: {$ifndef FPC}@{$endif}@glColor4usv), + (n: 'glColorMask'; d: {$ifndef FPC}@{$endif}@glColorMask), + (n: 'glColorMaterial'; d: {$ifndef FPC}@{$endif}@glColorMaterial), + (n: 'glColorPointer'; d: {$ifndef FPC}@{$endif}@glColorPointer), + (n: 'glCopyPixels'; d: {$ifndef FPC}@{$endif}@glCopyPixels), + (n: 'glCopyTexImage1D'; d: {$ifndef FPC}@{$endif}@glCopyTexImage1D), + (n: 'glCopyTexImage2D'; d: {$ifndef FPC}@{$endif}@glCopyTexImage2D), + (n: 'glCopyTexSubImage1D'; d: {$ifndef FPC}@{$endif}@glCopyTexSubImage1D), + (n: 'glCopyTexSubImage2D'; d: {$ifndef FPC}@{$endif}@glCopyTexSubImage2D), + (n: 'glCullFace'; d: {$ifndef FPC}@{$endif}@glCullFace), + (n: 'glDeleteLists'; d: {$ifndef FPC}@{$endif}@glDeleteLists), + (n: 'glDeleteTextures'; d: {$ifndef FPC}@{$endif}@glDeleteTextures), + (n: 'glDepthFunc'; d: {$ifndef FPC}@{$endif}@glDepthFunc), + (n: 'glDepthMask'; d: {$ifndef FPC}@{$endif}@glDepthMask), + (n: 'glDepthRange'; d: {$ifndef FPC}@{$endif}@glDepthRange), + (n: 'glDisable'; d: {$ifndef FPC}@{$endif}@glDisable), + (n: 'glDisableClientState'; d: {$ifndef FPC}@{$endif}@glDisableClientState), + (n: 'glDrawArrays'; d: {$ifndef FPC}@{$endif}@glDrawArrays), + (n: 'glDrawBuffer'; d: {$ifndef FPC}@{$endif}@glDrawBuffer), + (n: 'glDrawElements'; d: {$ifndef FPC}@{$endif}@glDrawElements), + (n: 'glDrawPixels'; d: {$ifndef FPC}@{$endif}@glDrawPixels), + (n: 'glEdgeFlag'; d: {$ifndef FPC}@{$endif}@glEdgeFlag), + (n: 'glEdgeFlagPointer'; d: {$ifndef FPC}@{$endif}@glEdgeFlagPointer), + (n: 'glEdgeFlagv'; d: {$ifndef FPC}@{$endif}@glEdgeFlagv), + (n: 'glEnable'; d: {$ifndef FPC}@{$endif}@glEnable), + (n: 'glEnableClientState'; d: {$ifndef FPC}@{$endif}@glEnableClientState), + (n: 'glEnd'; d: {$ifndef FPC}@{$endif}@glEnd), + (n: 'glEndList'; d: {$ifndef FPC}@{$endif}@glEndList), + (n: 'glEvalCoord1d'; d: {$ifndef FPC}@{$endif}@glEvalCoord1d), + (n: 'glEvalCoord1dv'; d: {$ifndef FPC}@{$endif}@glEvalCoord1dv), + (n: 'glEvalCoord1f'; d: {$ifndef FPC}@{$endif}@glEvalCoord1f), + (n: 'glEvalCoord1fv'; d: {$ifndef FPC}@{$endif}@glEvalCoord1fv), + (n: 'glEvalCoord2d'; d: {$ifndef FPC}@{$endif}@glEvalCoord2d), + (n: 'glEvalCoord2dv'; d: {$ifndef FPC}@{$endif}@glEvalCoord2dv), + (n: 'glEvalCoord2f'; d: {$ifndef FPC}@{$endif}@glEvalCoord2f), + (n: 'glEvalCoord2fv'; d: {$ifndef FPC}@{$endif}@glEvalCoord2fv), + (n: 'glEvalMesh1'; d: {$ifndef FPC}@{$endif}@glEvalMesh1), + (n: 'glEvalMesh2'; d: {$ifndef FPC}@{$endif}@glEvalMesh2), + (n: 'glEvalPoint1'; d: {$ifndef FPC}@{$endif}@glEvalPoint1), + (n: 'glEvalPoint2'; d: {$ifndef FPC}@{$endif}@glEvalPoint2), + (n: 'glFeedbackBuffer'; d: {$ifndef FPC}@{$endif}@glFeedbackBuffer), + (n: 'glFinish'; d: {$ifndef FPC}@{$endif}@glFinish), + (n: 'glFlush'; d: {$ifndef FPC}@{$endif}@glFlush), + (n: 'glFogf'; d: {$ifndef FPC}@{$endif}@glFogf), + (n: 'glFogfv'; d: {$ifndef FPC}@{$endif}@glFogfv), + (n: 'glFogi'; d: {$ifndef FPC}@{$endif}@glFogi), + (n: 'glFogiv'; d: {$ifndef FPC}@{$endif}@glFogiv), + (n: 'glFrontFace'; d: {$ifndef FPC}@{$endif}@glFrontFace), + (n: 'glFrustum'; d: {$ifndef FPC}@{$endif}@glFrustum), + (n: 'glGenLists'; d: {$ifndef FPC}@{$endif}@glGenLists), + (n: 'glGenTextures'; d: {$ifndef FPC}@{$endif}@glGenTextures), + (n: 'glGetBooleanv'; d: {$ifndef FPC}@{$endif}@glGetBooleanv), + (n: 'glGetClipPlane'; d: {$ifndef FPC}@{$endif}@glGetClipPlane), + (n: 'glGetDoublev'; d: {$ifndef FPC}@{$endif}@glGetDoublev), + (n: 'glGetError'; d: {$ifndef FPC}@{$endif}@glGetError), + (n: 'glGetFloatv'; d: {$ifndef FPC}@{$endif}@glGetFloatv), + (n: 'glGetIntegerv'; d: {$ifndef FPC}@{$endif}@glGetIntegerv), + (n: 'glGetLightfv'; d: {$ifndef FPC}@{$endif}@glGetLightfv), + (n: 'glGetLightiv'; d: {$ifndef FPC}@{$endif}@glGetLightiv), + (n: 'glGetMapdv'; d: {$ifndef FPC}@{$endif}@glGetMapdv), + (n: 'glGetMapfv'; d: {$ifndef FPC}@{$endif}@glGetMapfv), + (n: 'glGetMapiv'; d: {$ifndef FPC}@{$endif}@glGetMapiv), + (n: 'glGetMaterialfv'; d: {$ifndef FPC}@{$endif}@glGetMaterialfv), + (n: 'glGetMaterialiv'; d: {$ifndef FPC}@{$endif}@glGetMaterialiv), + (n: 'glGetPixelMapfv'; d: {$ifndef FPC}@{$endif}@glGetPixelMapfv), + (n: 'glGetPixelMapuiv'; d: {$ifndef FPC}@{$endif}@glGetPixelMapuiv), + (n: 'glGetPixelMapusv'; d: {$ifndef FPC}@{$endif}@glGetPixelMapusv), + (n: 'glGetPointerv'; d: {$ifndef FPC}@{$endif}@glGetPointerv), + (n: 'glGetPolygonStipple'; d: {$ifndef FPC}@{$endif}@glGetPolygonStipple), + (n: 'glGetString'; d: {$ifndef FPC}@{$endif}@glGetString), + (n: 'glGetTexEnvfv'; d: {$ifndef FPC}@{$endif}@glGetTexEnvfv), + (n: 'glGetTexEnviv'; d: {$ifndef FPC}@{$endif}@glGetTexEnviv), + (n: 'glGetTexGendv'; d: {$ifndef FPC}@{$endif}@glGetTexGendv), + (n: 'glGetTexGenfv'; d: {$ifndef FPC}@{$endif}@glGetTexGenfv), + (n: 'glGetTexGeniv'; d: {$ifndef FPC}@{$endif}@glGetTexGeniv), + (n: 'glGetTexImage'; d: {$ifndef FPC}@{$endif}@glGetTexImage), + (n: 'glGetTexLevelParameterfv'; d: {$ifndef FPC}@{$endif}@glGetTexLevelParameterfv), + (n: 'glGetTexLevelParameteriv'; d: {$ifndef FPC}@{$endif}@glGetTexLevelParameteriv), + (n: 'glGetTexParameterfv'; d: {$ifndef FPC}@{$endif}@glGetTexParameterfv), + (n: 'glGetTexParameteriv'; d: {$ifndef FPC}@{$endif}@glGetTexParameteriv), + (n: 'glHint'; d: {$ifndef FPC}@{$endif}@glHint), + (n: 'glIndexMask'; d: {$ifndef FPC}@{$endif}@glIndexMask), + (n: 'glIndexPointer'; d: {$ifndef FPC}@{$endif}@glIndexPointer), + (n: 'glIndexd'; d: {$ifndef FPC}@{$endif}@glIndexd), + (n: 'glIndexdv'; d: {$ifndef FPC}@{$endif}@glIndexdv), + (n: 'glIndexf'; d: {$ifndef FPC}@{$endif}@glIndexf), + (n: 'glIndexfv'; d: {$ifndef FPC}@{$endif}@glIndexfv), + (n: 'glIndexi'; d: {$ifndef FPC}@{$endif}@glIndexi), + (n: 'glIndexiv'; d: {$ifndef FPC}@{$endif}@glIndexiv), + (n: 'glIndexs'; d: {$ifndef FPC}@{$endif}@glIndexs), + (n: 'glIndexsv'; d: {$ifndef FPC}@{$endif}@glIndexsv), + (n: 'glIndexub'; d: {$ifndef FPC}@{$endif}@glIndexub), + (n: 'glIndexubv'; d: {$ifndef FPC}@{$endif}@glIndexubv), + (n: 'glInitNames'; d: {$ifndef FPC}@{$endif}@glInitNames), + (n: 'glInterleavedArrays'; d: {$ifndef FPC}@{$endif}@glInterleavedArrays), + (n: 'glIsEnabled'; d: {$ifndef FPC}@{$endif}@glIsEnabled), + (n: 'glIsList'; d: {$ifndef FPC}@{$endif}@glIsList), + (n: 'glIsTexture'; d: {$ifndef FPC}@{$endif}@glIsTexture), + (n: 'glLightModelf'; d: {$ifndef FPC}@{$endif}@glLightModelf), + (n: 'glLightModelfv'; d: {$ifndef FPC}@{$endif}@glLightModelfv), + (n: 'glLightModeli'; d: {$ifndef FPC}@{$endif}@glLightModeli), + (n: 'glLightModeliv'; d: {$ifndef FPC}@{$endif}@glLightModeliv), + (n: 'glLightf'; d: {$ifndef FPC}@{$endif}@glLightf), + (n: 'glLightfv'; d: {$ifndef FPC}@{$endif}@glLightfv), + (n: 'glLighti'; d: {$ifndef FPC}@{$endif}@glLighti), + (n: 'glLightiv'; d: {$ifndef FPC}@{$endif}@glLightiv), + (n: 'glLineStipple'; d: {$ifndef FPC}@{$endif}@glLineStipple), + (n: 'glLineWidth'; d: {$ifndef FPC}@{$endif}@glLineWidth), + (n: 'glListBase'; d: {$ifndef FPC}@{$endif}@glListBase), + (n: 'glLoadIdentity'; d: {$ifndef FPC}@{$endif}@glLoadIdentity), + (n: 'glLoadMatrixd'; d: {$ifndef FPC}@{$endif}@glLoadMatrixd), + (n: 'glLoadMatrixf'; d: {$ifndef FPC}@{$endif}@glLoadMatrixf), + (n: 'glLoadName'; d: {$ifndef FPC}@{$endif}@glLoadName), + (n: 'glLogicOp'; d: {$ifndef FPC}@{$endif}@glLogicOp), + (n: 'glMap1d'; d: {$ifndef FPC}@{$endif}@glMap1d), + (n: 'glMap1f'; d: {$ifndef FPC}@{$endif}@glMap1f), + (n: 'glMap2d'; d: {$ifndef FPC}@{$endif}@glMap2d), + (n: 'glMap2f'; d: {$ifndef FPC}@{$endif}@glMap2f), + (n: 'glMapGrid1d'; d: {$ifndef FPC}@{$endif}@glMapGrid1d), + (n: 'glMapGrid1f'; d: {$ifndef FPC}@{$endif}@glMapGrid1f), + (n: 'glMapGrid2d'; d: {$ifndef FPC}@{$endif}@glMapGrid2d), + (n: 'glMapGrid2f'; d: {$ifndef FPC}@{$endif}@glMapGrid2f), + (n: 'glMaterialf'; d: {$ifndef FPC}@{$endif}@glMaterialf), + (n: 'glMaterialfv'; d: {$ifndef FPC}@{$endif}@glMaterialfv), + (n: 'glMateriali'; d: {$ifndef FPC}@{$endif}@glMateriali), + (n: 'glMaterialiv'; d: {$ifndef FPC}@{$endif}@glMaterialiv), + (n: 'glMatrixMode'; d: {$ifndef FPC}@{$endif}@glMatrixMode), + (n: 'glMultMatrixd'; d: {$ifndef FPC}@{$endif}@glMultMatrixd), + (n: 'glMultMatrixf'; d: {$ifndef FPC}@{$endif}@glMultMatrixf), + (n: 'glNewList'; d: {$ifndef FPC}@{$endif}@glNewList), + (n: 'glNormal3b'; d: {$ifndef FPC}@{$endif}@glNormal3b), + (n: 'glNormal3bv'; d: {$ifndef FPC}@{$endif}@glNormal3bv), + (n: 'glNormal3d'; d: {$ifndef FPC}@{$endif}@glNormal3d), + (n: 'glNormal3dv'; d: {$ifndef FPC}@{$endif}@glNormal3dv), + (n: 'glNormal3f'; d: {$ifndef FPC}@{$endif}@glNormal3f), + (n: 'glNormal3fv'; d: {$ifndef FPC}@{$endif}@glNormal3fv), + (n: 'glNormal3i'; d: {$ifndef FPC}@{$endif}@glNormal3i), + (n: 'glNormal3iv'; d: {$ifndef FPC}@{$endif}@glNormal3iv), + (n: 'glNormal3s'; d: {$ifndef FPC}@{$endif}@glNormal3s), + (n: 'glNormal3sv'; d: {$ifndef FPC}@{$endif}@glNormal3sv), + (n: 'glNormalPointer'; d: {$ifndef FPC}@{$endif}@glNormalPointer), + (n: 'glOrtho'; d: {$ifndef FPC}@{$endif}@glOrtho), + (n: 'glPassThrough'; d: {$ifndef FPC}@{$endif}@glPassThrough), + (n: 'glPixelMapfv'; d: {$ifndef FPC}@{$endif}@glPixelMapfv), + (n: 'glPixelMapuiv'; d: {$ifndef FPC}@{$endif}@glPixelMapuiv), + (n: 'glPixelMapusv'; d: {$ifndef FPC}@{$endif}@glPixelMapusv), + (n: 'glPixelStoref'; d: {$ifndef FPC}@{$endif}@glPixelStoref), + (n: 'glPixelStorei'; d: {$ifndef FPC}@{$endif}@glPixelStorei), + (n: 'glPixelTransferf'; d: {$ifndef FPC}@{$endif}@glPixelTransferf), + (n: 'glPixelTransferi'; d: {$ifndef FPC}@{$endif}@glPixelTransferi), + (n: 'glPixelZoom'; d: {$ifndef FPC}@{$endif}@glPixelZoom), + (n: 'glPointSize'; d: {$ifndef FPC}@{$endif}@glPointSize), + (n: 'glPolygonMode'; d: {$ifndef FPC}@{$endif}@glPolygonMode), + (n: 'glPolygonOffset'; d: {$ifndef FPC}@{$endif}@glPolygonOffset), + (n: 'glPolygonStipple'; d: {$ifndef FPC}@{$endif}@glPolygonStipple), + (n: 'glPopAttrib'; d: {$ifndef FPC}@{$endif}@glPopAttrib), + (n: 'glPopClientAttrib'; d: {$ifndef FPC}@{$endif}@glPopClientAttrib), + (n: 'glPopMatrix'; d: {$ifndef FPC}@{$endif}@glPopMatrix), + (n: 'glPopName'; d: {$ifndef FPC}@{$endif}@glPopName), + (n: 'glPrioritizeTextures'; d: {$ifndef FPC}@{$endif}@glPrioritizeTextures), + (n: 'glPushAttrib'; d: {$ifndef FPC}@{$endif}@glPushAttrib), + (n: 'glPushClientAttrib'; d: {$ifndef FPC}@{$endif}@glPushClientAttrib), + (n: 'glPushMatrix'; d: {$ifndef FPC}@{$endif}@glPushMatrix), + (n: 'glPushName'; d: {$ifndef FPC}@{$endif}@glPushName), + (n: 'glRasterPos2d'; d: {$ifndef FPC}@{$endif}@glRasterPos2d), + (n: 'glRasterPos2dv'; d: {$ifndef FPC}@{$endif}@glRasterPos2dv), + (n: 'glRasterPos2f'; d: {$ifndef FPC}@{$endif}@glRasterPos2f), + (n: 'glRasterPos2fv'; d: {$ifndef FPC}@{$endif}@glRasterPos2fv), + (n: 'glRasterPos2i'; d: {$ifndef FPC}@{$endif}@glRasterPos2i), + (n: 'glRasterPos2iv'; d: {$ifndef FPC}@{$endif}@glRasterPos2iv), + (n: 'glRasterPos2s'; d: {$ifndef FPC}@{$endif}@glRasterPos2s), + (n: 'glRasterPos2sv'; d: {$ifndef FPC}@{$endif}@glRasterPos2sv), + (n: 'glRasterPos3d'; d: {$ifndef FPC}@{$endif}@glRasterPos3d), + (n: 'glRasterPos3dv'; d: {$ifndef FPC}@{$endif}@glRasterPos3dv), + (n: 'glRasterPos3f'; d: {$ifndef FPC}@{$endif}@glRasterPos3f), + (n: 'glRasterPos3fv'; d: {$ifndef FPC}@{$endif}@glRasterPos3fv), + (n: 'glRasterPos3i'; d: {$ifndef FPC}@{$endif}@glRasterPos3i), + (n: 'glRasterPos3iv'; d: {$ifndef FPC}@{$endif}@glRasterPos3iv), + (n: 'glRasterPos3s'; d: {$ifndef FPC}@{$endif}@glRasterPos3s), + (n: 'glRasterPos3sv'; d: {$ifndef FPC}@{$endif}@glRasterPos3sv), + (n: 'glRasterPos4d'; d: {$ifndef FPC}@{$endif}@glRasterPos4d), + (n: 'glRasterPos4dv'; d: {$ifndef FPC}@{$endif}@glRasterPos4dv), + (n: 'glRasterPos4f'; d: {$ifndef FPC}@{$endif}@glRasterPos4f), + (n: 'glRasterPos4fv'; d: {$ifndef FPC}@{$endif}@glRasterPos4fv), + (n: 'glRasterPos4i'; d: {$ifndef FPC}@{$endif}@glRasterPos4i), + (n: 'glRasterPos4iv'; d: {$ifndef FPC}@{$endif}@glRasterPos4iv), + (n: 'glRasterPos4s'; d: {$ifndef FPC}@{$endif}@glRasterPos4s), + (n: 'glRasterPos4sv'; d: {$ifndef FPC}@{$endif}@glRasterPos4sv), + (n: 'glReadBuffer'; d: {$ifndef FPC}@{$endif}@glReadBuffer), + (n: 'glReadPixels'; d: {$ifndef FPC}@{$endif}@glReadPixels), + (n: 'glRectd'; d: {$ifndef FPC}@{$endif}@glRectd), + (n: 'glRectdv'; d: {$ifndef FPC}@{$endif}@glRectdv), + (n: 'glRectf'; d: {$ifndef FPC}@{$endif}@glRectf), + (n: 'glRectfv'; d: {$ifndef FPC}@{$endif}@glRectfv), + (n: 'glRecti'; d: {$ifndef FPC}@{$endif}@glRecti), + (n: 'glRectiv'; d: {$ifndef FPC}@{$endif}@glRectiv), + (n: 'glRects'; d: {$ifndef FPC}@{$endif}@glRects), + (n: 'glRectsv'; d: {$ifndef FPC}@{$endif}@glRectsv), + (n: 'glRenderMode'; d: {$ifndef FPC}@{$endif}@glRenderMode), + (n: 'glRotated'; d: {$ifndef FPC}@{$endif}@glRotated), + (n: 'glRotatef'; d: {$ifndef FPC}@{$endif}@glRotatef), + (n: 'glScaled'; d: {$ifndef FPC}@{$endif}@glScaled), + (n: 'glScalef'; d: {$ifndef FPC}@{$endif}@glScalef), + (n: 'glScissor'; d: {$ifndef FPC}@{$endif}@glScissor), + (n: 'glSelectBuffer'; d: {$ifndef FPC}@{$endif}@glSelectBuffer), + (n: 'glShadeModel'; d: {$ifndef FPC}@{$endif}@glShadeModel), + (n: 'glStencilFunc'; d: {$ifndef FPC}@{$endif}@glStencilFunc), + (n: 'glStencilMask'; d: {$ifndef FPC}@{$endif}@glStencilMask), + (n: 'glStencilOp'; d: {$ifndef FPC}@{$endif}@glStencilOp), + (n: 'glTexCoord1d'; d: {$ifndef FPC}@{$endif}@glTexCoord1d), + (n: 'glTexCoord1dv'; d: {$ifndef FPC}@{$endif}@glTexCoord1dv), + (n: 'glTexCoord1f'; d: {$ifndef FPC}@{$endif}@glTexCoord1f), + (n: 'glTexCoord1fv'; d: {$ifndef FPC}@{$endif}@glTexCoord1fv), + (n: 'glTexCoord1i'; d: {$ifndef FPC}@{$endif}@glTexCoord1i), + (n: 'glTexCoord1iv'; d: {$ifndef FPC}@{$endif}@glTexCoord1iv), + (n: 'glTexCoord1s'; d: {$ifndef FPC}@{$endif}@glTexCoord1s), + (n: 'glTexCoord1sv'; d: {$ifndef FPC}@{$endif}@glTexCoord1sv), + (n: 'glTexCoord2d'; d: {$ifndef FPC}@{$endif}@glTexCoord2d), + (n: 'glTexCoord2dv'; d: {$ifndef FPC}@{$endif}@glTexCoord2dv), + (n: 'glTexCoord2f'; d: {$ifndef FPC}@{$endif}@glTexCoord2f), + (n: 'glTexCoord2fv'; d: {$ifndef FPC}@{$endif}@glTexCoord2fv), + (n: 'glTexCoord2i'; d: {$ifndef FPC}@{$endif}@glTexCoord2i), + (n: 'glTexCoord2iv'; d: {$ifndef FPC}@{$endif}@glTexCoord2iv), + (n: 'glTexCoord2s'; d: {$ifndef FPC}@{$endif}@glTexCoord2s), + (n: 'glTexCoord2sv'; d: {$ifndef FPC}@{$endif}@glTexCoord2sv), + (n: 'glTexCoord3d'; d: {$ifndef FPC}@{$endif}@glTexCoord3d), + (n: 'glTexCoord3dv'; d: {$ifndef FPC}@{$endif}@glTexCoord3dv), + (n: 'glTexCoord3f'; d: {$ifndef FPC}@{$endif}@glTexCoord3f), + (n: 'glTexCoord3fv'; d: {$ifndef FPC}@{$endif}@glTexCoord3fv), + (n: 'glTexCoord3i'; d: {$ifndef FPC}@{$endif}@glTexCoord3i), + (n: 'glTexCoord3iv'; d: {$ifndef FPC}@{$endif}@glTexCoord3iv), + (n: 'glTexCoord3s'; d: {$ifndef FPC}@{$endif}@glTexCoord3s), + (n: 'glTexCoord3sv'; d: {$ifndef FPC}@{$endif}@glTexCoord3sv), + (n: 'glTexCoord4d'; d: {$ifndef FPC}@{$endif}@glTexCoord4d), + (n: 'glTexCoord4dv'; d: {$ifndef FPC}@{$endif}@glTexCoord4dv), + (n: 'glTexCoord4f'; d: {$ifndef FPC}@{$endif}@glTexCoord4f), + (n: 'glTexCoord4fv'; d: {$ifndef FPC}@{$endif}@glTexCoord4fv), + (n: 'glTexCoord4i'; d: {$ifndef FPC}@{$endif}@glTexCoord4i), + (n: 'glTexCoord4iv'; d: {$ifndef FPC}@{$endif}@glTexCoord4iv), + (n: 'glTexCoord4s'; d: {$ifndef FPC}@{$endif}@glTexCoord4s), + (n: 'glTexCoord4sv'; d: {$ifndef FPC}@{$endif}@glTexCoord4sv), + (n: 'glTexCoordPointer'; d: {$ifndef FPC}@{$endif}@glTexCoordPointer), + (n: 'glTexEnvf'; d: {$ifndef FPC}@{$endif}@glTexEnvf), + (n: 'glTexEnvfv'; d: {$ifndef FPC}@{$endif}@glTexEnvfv), + (n: 'glTexEnvi'; d: {$ifndef FPC}@{$endif}@glTexEnvi), + (n: 'glTexEnviv'; d: {$ifndef FPC}@{$endif}@glTexEnviv), + (n: 'glTexGend'; d: {$ifndef FPC}@{$endif}@glTexGend), + (n: 'glTexGendv'; d: {$ifndef FPC}@{$endif}@glTexGendv), + (n: 'glTexGenf'; d: {$ifndef FPC}@{$endif}@glTexGenf), + (n: 'glTexGenfv'; d: {$ifndef FPC}@{$endif}@glTexGenfv), + (n: 'glTexGeni'; d: {$ifndef FPC}@{$endif}@glTexGeni), + (n: 'glTexGeniv'; d: {$ifndef FPC}@{$endif}@glTexGeniv), + (n: 'glTexImage1D'; d: {$ifndef FPC}@{$endif}@glTexImage1D), + (n: 'glTexImage2D'; d: {$ifndef FPC}@{$endif}@glTexImage2D), + (n: 'glTexParameterf'; d: {$ifndef FPC}@{$endif}@glTexParameterf), + (n: 'glTexParameterfv'; d: {$ifndef FPC}@{$endif}@glTexParameterfv), + (n: 'glTexParameteri'; d: {$ifndef FPC}@{$endif}@glTexParameteri), + (n: 'glTexParameteriv'; d: {$ifndef FPC}@{$endif}@glTexParameteriv), + (n: 'glTexSubImage1D'; d: {$ifndef FPC}@{$endif}@glTexSubImage1D), + (n: 'glTexSubImage2D'; d: {$ifndef FPC}@{$endif}@glTexSubImage2D), + (n: 'glTranslated'; d: {$ifndef FPC}@{$endif}@glTranslated), + (n: 'glTranslatef'; d: {$ifndef FPC}@{$endif}@glTranslatef), + (n: 'glVertex2d'; d: {$ifndef FPC}@{$endif}@glVertex2d), + (n: 'glVertex2dv'; d: {$ifndef FPC}@{$endif}@glVertex2dv), + (n: 'glVertex2f'; d: {$ifndef FPC}@{$endif}@glVertex2f), + (n: 'glVertex2fv'; d: {$ifndef FPC}@{$endif}@glVertex2fv), + (n: 'glVertex2i'; d: {$ifndef FPC}@{$endif}@glVertex2i), + (n: 'glVertex2iv'; d: {$ifndef FPC}@{$endif}@glVertex2iv), + (n: 'glVertex2s'; d: {$ifndef FPC}@{$endif}@glVertex2s), + (n: 'glVertex2sv'; d: {$ifndef FPC}@{$endif}@glVertex2sv), + (n: 'glVertex3d'; d: {$ifndef FPC}@{$endif}@glVertex3d), + (n: 'glVertex3dv'; d: {$ifndef FPC}@{$endif}@glVertex3dv), + (n: 'glVertex3f'; d: {$ifndef FPC}@{$endif}@glVertex3f), + (n: 'glVertex3fv'; d: {$ifndef FPC}@{$endif}@glVertex3fv), + (n: 'glVertex3i'; d: {$ifndef FPC}@{$endif}@glVertex3i), + (n: 'glVertex3iv'; d: {$ifndef FPC}@{$endif}@glVertex3iv), + (n: 'glVertex3s'; d: {$ifndef FPC}@{$endif}@glVertex3s), + (n: 'glVertex3sv'; d: {$ifndef FPC}@{$endif}@glVertex3sv), + (n: 'glVertex4d'; d: {$ifndef FPC}@{$endif}@glVertex4d), + (n: 'glVertex4dv'; d: {$ifndef FPC}@{$endif}@glVertex4dv), + (n: 'glVertex4f'; d: {$ifndef FPC}@{$endif}@glVertex4f), + (n: 'glVertex4fv'; d: {$ifndef FPC}@{$endif}@glVertex4fv), + (n: 'glVertex4i'; d: {$ifndef FPC}@{$endif}@glVertex4i), + (n: 'glVertex4iv'; d: {$ifndef FPC}@{$endif}@glVertex4iv), + (n: 'glVertex4s'; d: {$ifndef FPC}@{$endif}@glVertex4s), + (n: 'glVertex4sv'; d: {$ifndef FPC}@{$endif}@glVertex4sv), + (n: 'glVertexPointer'; d: {$ifndef FPC}@{$endif}@glVertexPointer), + (n: 'glViewport'; d: {$ifndef FPC}@{$endif}@glViewport) + ); +{$ifdef mswindows} + funcsopt: array[0..0] of funcinfoty = ( + (n: 'ChoosePixelFormat'; d: {$ifndef FPC}@{$endif}@ChoosePixelFormat) + ); +{$endif} +const + errormessage = 'Can not load OpenGL library. '; + +begin + initializedynlib(libinfo,sonames,opengllib,funcs, + {$ifdef mswindows}funcsopt{$else}[]{$endif},errormessage,@init); +{$ifdef mswindows} + if {$ifndef FPC}@{$endif}ChoosePixelFormat = nil then begin + ChoosePixelFormat:= @WinChoosePixelFormat; + end; +{$endif} +end; + +procedure releaseopengl; +begin + releasedynlib(libinfo,@deinit); +end; + +initialization + initializelibinfo(libinfo); + mseglextglob.init(); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/opengl/mseglext.pas b/mseide-msegui/lib/common/opengl/mseglext.pas new file mode 100644 index 0000000..140efb6 --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseglext.pas @@ -0,0 +1,8268 @@ +{ + + Adaption of the delphi3d.net OpenGL units to FreePascal + Sebastian Guenther (sg@freepascal.org) in 2002 + These units are free to use +} + +{ modified 2011-2013 by Martin Schreiber } + +unit mseglext; +{$ifdef FPC}{$MACRO ON}{$mode objfpc} {$h+}{$endif} +{$IFDEF msWindows} + {$define wincall} +// {$DEFINE extdecl:=stdcall } +{$ELSE} +// {$DEFINE extdecl:=cdecl } +{$ENDIF} + +(************************************************** + * OpenGL extension loading library * + * Generated by MetaGLext, written by Tom Nuydens * + * (tom@delphi3d.net -- http://www.delphi3d.net * + **************************************************) + +//*** Generated on 10/11/2002 + +interface + +uses + SysUtils, + {$IFDEF msWindows} + Windows, + {$ELSE} + {$ifdef FPC}dynlibs,{$endif} + {$ENDIF} + msegl,mseglextglob{$ifndef FPC},msetypes{$endif}; + +{$IFDEF msWindows} +{ Declared in Windows unit as well in FPC; but declared here as well, to be + fully compatible to upstream version - sg } +function wglGetProcAddress(proc: PChar): Pointer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external 'OpenGL32.dll'; +{$ENDIF} +(* +// Test if the given extension name is present in the given extension string. +function glext_ExtensionSupported(const extension: String; const searchIn: String): Boolean; + +// Load the extension with the given name. +function glext_LoadExtension(ext: String): Boolean; +*) +type + GLcharARB = Char; + TGLcharARB = GLcharARB; + PGLcharARB = ^GLcharARB; + PPGLchar = ^PGLchar; + + GLhandleARB = Cardinal; + TGLhandleARB = GLhandleARB; + PGLhandleARB = ^GLhandleARB; + + GLintptr = PtrInt; + TGLintptr = GLintptr; + PGLintptr = ^GLintptr; + + GLsizeiptr = PtrInt; + TGLsizeiptr = GLsizeiptr; + PGLsizeiptr = ^GLsizeiptr; + + GLchar = Char; + TGLchar = GLchar; + PGLchar = Pchar; + + GLint64 = Int64; + TGLint64 = GLint64; + PGLint64 = ^GLint64; + + GLuint64 = QWord; + TGLuint64 = GLuint64; + PGLuint64 = ^GLuint64; + + +//***** GL_version_1_2 *****// +const + GL_UNSIGNED_BYTE_3_3_2 = $8032; + GL_UNSIGNED_SHORT_4_4_4_4 = $8033; + GL_UNSIGNED_SHORT_5_5_5_1 = $8034; + GL_UNSIGNED_INT_8_8_8_8 = $8035; + GL_UNSIGNED_INT_10_10_10_2 = $8036; + GL_RESCALE_NORMAL = $803A; + GL_UNSIGNED_BYTE_2_3_3_REV = $8362; + GL_UNSIGNED_SHORT_5_6_5 = $8363; + GL_UNSIGNED_SHORT_5_6_5_REV = $8364; + GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365; + GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366; + GL_UNSIGNED_INT_8_8_8_8_REV = $8367; + GL_UNSIGNED_INT_2_10_10_10_REV = $8368; + GL_BGR = $80E0; + GL_BGRA = $80E1; + GL_MAX_ELEMENTS_VERTICES = $80E8; + GL_MAX_ELEMENTS_INDICES = $80E9; + GL_CLAMP_TO_EDGE = $812F; + GL_TEXTURE_MIN_LOD = $813A; + GL_TEXTURE_MAX_LOD = $813B; + GL_TEXTURE_BASE_LEVEL = $813C; + GL_TEXTURE_MAX_LEVEL = $813D; + GL_LIGHT_MODEL_COLOR_CONTROL = $81F8; + GL_SINGLE_COLOR = $81F9; + GL_SEPARATE_SPECULAR_COLOR = $81FA; + GL_SMOOTH_POINT_SIZE_RANGE = $0B12; + GL_SMOOTH_POINT_SIZE_GRANULARITY = $0B13; + GL_SMOOTH_LINE_WIDTH_RANGE = $0B22; + GL_SMOOTH_LINE_WIDTH_GRANULARITY = $0B23; + GL_ALIASED_POINT_SIZE_RANGE = $846D; + GL_ALIASED_LINE_WIDTH_RANGE = $846E; + GL_PACK_SKIP_IMAGES = $806B; + GL_PACK_IMAGE_HEIGHT = $806C; + GL_UNPACK_SKIP_IMAGES = $806D; + GL_UNPACK_IMAGE_HEIGHT = $806E; + GL_TEXTURE_3D = $806F; + GL_PROXY_TEXTURE_3D = $8070; + GL_TEXTURE_DEPTH = $8071; + GL_TEXTURE_WRAP_R = $8072; + GL_MAX_3D_TEXTURE_SIZE = $8073; +var + glBlendColor: procedure(red: GLclampf; green: GLclampf; blue: GLclampf; alpha: GLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBlendEquation: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawRangeElements: procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei; _type: GLenum; const indices: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorTable: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const table: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorTableParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorTableParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyColorTable: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTable: procedure(target: GLenum; format: GLenum; _type: GLenum; table: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorSubTable: procedure(target: GLenum; start: GLsizei; count: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyColorSubTable: procedure(target: GLenum; start: GLsizei; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionFilter1D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionFilter2D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameterf: procedure(target: GLenum; pname: GLenum; params: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameteri: procedure(target: GLenum; pname: GLenum; params: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyConvolutionFilter1D: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyConvolutionFilter2D: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionFilter: procedure(target: GLenum; format: GLenum; _type: GLenum; image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSeparableFilter: procedure(target: GLenum; format: GLenum; _type: GLenum; row: PGLvoid; column: PGLvoid; span: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSeparableFilter2D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const row: PGLvoid; const column: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogram: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogramParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogramParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmax: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmaxParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmaxParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glHistogram: procedure(target: GLenum; width: GLsizei; internalformat: GLenum; sink: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMinmax: procedure(target: GLenum; internalformat: GLenum; sink: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glResetHistogram: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glResetMinmax: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexImage3D: procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_version_1_2: Boolean; + +//***** GL_ARB_imaging *****// +const + GL_CONSTANT_COLOR = $8001; + GL_ONE_MINUS_CONSTANT_COLOR = $8002; + GL_CONSTANT_ALPHA = $8003; + GL_ONE_MINUS_CONSTANT_ALPHA = $8004; + GL_BLEND_COLOR = $8005; + GL_FUNC_ADD = $8006; + GL_MIN = $8007; + GL_MAX = $8008; + GL_BLEND_EQUATION = $8009; + GL_FUNC_SUBTRACT = $800A; + GL_FUNC_REVERSE_SUBTRACT = $800B; + GL_CONVOLUTION_1D = $8010; + GL_CONVOLUTION_2D = $8011; + GL_SEPARABLE_2D = $8012; + GL_CONVOLUTION_BORDER_MODE = $8013; + GL_CONVOLUTION_FILTER_SCALE = $8014; + GL_CONVOLUTION_FILTER_BIAS = $8015; + GL_REDUCE = $8016; + GL_CONVOLUTION_FORMAT = $8017; + GL_CONVOLUTION_WIDTH = $8018; + GL_CONVOLUTION_HEIGHT = $8019; + GL_MAX_CONVOLUTION_WIDTH = $801A; + GL_MAX_CONVOLUTION_HEIGHT = $801B; + GL_POST_CONVOLUTION_RED_SCALE = $801C; + GL_POST_CONVOLUTION_GREEN_SCALE = $801D; + GL_POST_CONVOLUTION_BLUE_SCALE = $801E; + GL_POST_CONVOLUTION_ALPHA_SCALE = $801F; + GL_POST_CONVOLUTION_RED_BIAS = $8020; + GL_POST_CONVOLUTION_GREEN_BIAS = $8021; + GL_POST_CONVOLUTION_BLUE_BIAS = $8022; + GL_POST_CONVOLUTION_ALPHA_BIAS = $8023; + GL_HISTOGRAM = $8024; + GL_PROXY_HISTOGRAM = $8025; + GL_HISTOGRAM_WIDTH = $8026; + GL_HISTOGRAM_FORMAT = $8027; + GL_HISTOGRAM_RED_SIZE = $8028; + GL_HISTOGRAM_GREEN_SIZE = $8029; + GL_HISTOGRAM_BLUE_SIZE = $802A; + GL_HISTOGRAM_ALPHA_SIZE = $802B; + GL_HISTOGRAM_LUMINANCE_SIZE = $802C; + GL_HISTOGRAM_SINK = $802D; + GL_MINMAX = $802E; + GL_MINMAX_FORMAT = $802F; + GL_MINMAX_SINK = $8030; + GL_TABLE_TOO_LARGE = $8031; + GL_COLOR_MATRIX = $80B1; + GL_COLOR_MATRIX_STACK_DEPTH = $80B2; + GL_MAX_COLOR_MATRIX_STACK_DEPTH = $80B3; + GL_POST_COLOR_MATRIX_RED_SCALE = $80B4; + GL_POST_COLOR_MATRIX_GREEN_SCALE = $80B5; + GL_POST_COLOR_MATRIX_BLUE_SCALE = $80B6; + GL_POST_COLOR_MATRIX_ALPHA_SCALE = $80B7; + GL_POST_COLOR_MATRIX_RED_BIAS = $80B8; + GL_POST_COLOR_MATRIX_GREEN_BIAS = $80B9; + GL_POST_COLOR_MATRIX_BLUE_BIAS = $80BA; + GL_POST_COLOR_MATIX_ALPHA_BIAS = $80BB; + GL_COLOR_TABLE = $80D0; + GL_POST_CONVOLUTION_COLOR_TABLE = $80D1; + GL_POST_COLOR_MATRIX_COLOR_TABLE = $80D2; + GL_PROXY_COLOR_TABLE = $80D3; + GL_PROXY_POST_CONVOLUTION_COLOR_TABLE = $80D4; + GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE = $80D5; + GL_COLOR_TABLE_SCALE = $80D6; + GL_COLOR_TABLE_BIAS = $80D7; + GL_COLOR_TABLE_FORMAT = $80D8; + GL_COLOR_TABLE_WIDTH = $80D9; + GL_COLOR_TABLE_RED_SIZE = $80DA; + GL_COLOR_TABLE_GREEN_SIZE = $80DB; + GL_COLOR_TABLE_BLUE_SIZE = $80DC; + GL_COLOR_TABLE_ALPHA_SIZE = $80DD; + GL_COLOR_TABLE_LUMINANCE_SIZE = $80DE; + GL_COLOR_TABLE_INTENSITY_SIZE = $80DF; + GL_IGNORE_BORDER = $8150; + GL_CONSTANT_BORDER = $8151; + GL_WRAP_BORDER = $8152; + GL_REPLICATE_BORDER = $8153; + GL_CONVOLUTION_BORDER_COLOR = $8154; + +function Load_GL_ARB_imaging: Boolean; + +//***** GL_version_1_3 *****// +const + GL_TEXTURE0 = $84C0; + GL_TEXTURE1 = $84C1; + GL_TEXTURE2 = $84C2; + GL_TEXTURE3 = $84C3; + GL_TEXTURE4 = $84C4; + GL_TEXTURE5 = $84C5; + GL_TEXTURE6 = $84C6; + GL_TEXTURE7 = $84C7; + GL_TEXTURE8 = $84C8; + GL_TEXTURE9 = $84C9; + GL_TEXTURE10 = $84CA; + GL_TEXTURE11 = $84CB; + GL_TEXTURE12 = $84CC; + GL_TEXTURE13 = $84CD; + GL_TEXTURE14 = $84CE; + GL_TEXTURE15 = $84CF; + GL_TEXTURE16 = $84D0; + GL_TEXTURE17 = $84D1; + GL_TEXTURE18 = $84D2; + GL_TEXTURE19 = $84D3; + GL_TEXTURE20 = $84D4; + GL_TEXTURE21 = $84D5; + GL_TEXTURE22 = $84D6; + GL_TEXTURE23 = $84D7; + GL_TEXTURE24 = $84D8; + GL_TEXTURE25 = $84D9; + GL_TEXTURE26 = $84DA; + GL_TEXTURE27 = $84DB; + GL_TEXTURE28 = $84DC; + GL_TEXTURE29 = $84DD; + GL_TEXTURE30 = $84DE; + GL_TEXTURE31 = $84DF; + GL_ACTIVE_TEXTURE = $84E0; + GL_CLIENT_ACTIVE_TEXTURE = $84E1; + GL_MAX_TEXTURE_UNITS = $84E2; + GL_TRANSPOSE_MODELVIEW_MATRIX = $84E3; + GL_TRANSPOSE_PROJECTION_MATRIX = $84E4; + GL_TRANSPOSE_TEXTURE_MATRIX = $84E5; + GL_TRANSPOSE_COLOR_MATRIX = $84E6; + GL_MULTISAMPLE = $809D; + GL_SAMPLE_ALPHA_TO_COVERAGE = $809E; + GL_SAMPLE_ALPHA_TO_ONE = $809F; + GL_SAMPLE_COVERAGE = $80A0; + GL_SAMPLE_BUFFERS = $80A8; + GL_SAMPLES = $80A9; + GL_SAMPLE_COVERAGE_VALUE = $80AA; + GL_SAMPLE_COVERAGE_INVERT = $80AB; + GL_MULTISAMPLE_BIT = $20000000; + GL_NORMAL_MAP = $8511; + GL_REFLECTION_MAP = $8512; + GL_TEXTURE_CUBE_MAP = $8513; + GL_TEXTURE_BINDING_CUBE_MAP = $8514; + GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515; + GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516; + GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517; + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518; + GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519; + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A; + GL_PROXY_TEXTURE_CUBE_MAP = $851B; + GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C; + GL_COMPRESSED_ALPHA = $84E9; + GL_COMPRESSED_LUMINANCE = $84EA; + GL_COMPRESSED_LUMINANCE_ALPHA = $84EB; + GL_COMPRESSED_INTENSITY = $84EC; + GL_COMPRESSED_RGB = $84ED; + GL_COMPRESSED_RGBA = $84EE; + GL_TEXTURE_COMPRESSION_HINT = $84EF; + GL_TEXTURE_COMPRESSED_IMAGE_SIZE = $86A0; + GL_TEXTURE_COMPRESSED = $86A1; + GL_NUM_COMPRESSED_TEXTURE_FORMATS = $86A2; + GL_COMPRESSED_TEXTURE_FORMATS = $86A3; + GL_CLAMP_TO_BORDER = $812D; + GL_CLAMP_TO_BORDER_SGIS = $812D; + GL_COMBINE = $8570; + GL_COMBINE_RGB = $8571; + GL_COMBINE_ALPHA = $8572; + GL_SOURCE0_RGB = $8580; + GL_SOURCE1_RGB = $8581; + GL_SOURCE2_RGB = $8582; + GL_SOURCE0_ALPHA = $8588; + GL_SOURCE1_ALPHA = $8589; + GL_SOURCE2_ALPHA = $858A; + GL_OPERAND0_RGB = $8590; + GL_OPERAND1_RGB = $8591; + GL_OPERAND2_RGB = $8592; + GL_OPERAND0_ALPHA = $8598; + GL_OPERAND1_ALPHA = $8599; + GL_OPERAND2_ALPHA = $859A; + GL_RGB_SCALE = $8573; + GL_ADD_SIGNED = $8574; + GL_INTERPOLATE = $8575; + GL_SUBTRACT = $84E7; + GL_CONSTANT = $8576; + GL_PRIMARY_COLOR = $8577; + GL_PREVIOUS = $8578; + GL_DOT3_RGB = $86AE; + GL_DOT3_RGBA = $86AF; +var + glActiveTexture: procedure(texture: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClientActiveTexture: procedure(texture: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1d: procedure(target: GLenum; s: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1dv: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1f: procedure(target: GLenum; s: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1fv: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1i: procedure(target: GLenum; s: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1iv: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1s: procedure(target: GLenum; s: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1sv: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2d: procedure(target: GLenum; s: GLdouble; t: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2dv: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2f: procedure(target: GLenum; s: GLfloat; t: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2fv: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2i: procedure(target: GLenum; s: GLint; t: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2iv: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2s: procedure(target: GLenum; s: GLshort; t: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2sv: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3d: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3dv: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3f: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3fv: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3i: procedure(target: GLenum; s: GLint; t: GLint; r: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3iv: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3s: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3sv: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4d: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble; q: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4dv: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4f: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat; q: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4fv: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4i: procedure(target: GLenum; s: GLint; t: GLint; r: GLint; q: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4iv: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4s: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort; q: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4sv: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadTransposeMatrixf: procedure(const m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadTransposeMatrixd: procedure(const m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultTransposeMatrixf: procedure(const m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultTransposeMatrixd: procedure(const m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSampleCoverage: procedure(value: GLclampf; invert: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexImage3D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexImage2D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexImage1D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage2D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage1D: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCompressedTexImage: procedure(target: GLenum; level: GLint; img: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_version_1_3: Boolean; + +//***** GL_ARB_multitexture *****// +const + GL_TEXTURE0_ARB = $84C0; + GL_TEXTURE1_ARB = $84C1; + GL_TEXTURE2_ARB = $84C2; + GL_TEXTURE3_ARB = $84C3; + GL_TEXTURE4_ARB = $84C4; + GL_TEXTURE5_ARB = $84C5; + GL_TEXTURE6_ARB = $84C6; + GL_TEXTURE7_ARB = $84C7; + GL_TEXTURE8_ARB = $84C8; + GL_TEXTURE9_ARB = $84C9; + GL_TEXTURE10_ARB = $84CA; + GL_TEXTURE11_ARB = $84CB; + GL_TEXTURE12_ARB = $84CC; + GL_TEXTURE13_ARB = $84CD; + GL_TEXTURE14_ARB = $84CE; + GL_TEXTURE15_ARB = $84CF; + GL_TEXTURE16_ARB = $84D0; + GL_TEXTURE17_ARB = $84D1; + GL_TEXTURE18_ARB = $84D2; + GL_TEXTURE19_ARB = $84D3; + GL_TEXTURE20_ARB = $84D4; + GL_TEXTURE21_ARB = $84D5; + GL_TEXTURE22_ARB = $84D6; + GL_TEXTURE23_ARB = $84D7; + GL_TEXTURE24_ARB = $84D8; + GL_TEXTURE25_ARB = $84D9; + GL_TEXTURE26_ARB = $84DA; + GL_TEXTURE27_ARB = $84DB; + GL_TEXTURE28_ARB = $84DC; + GL_TEXTURE29_ARB = $84DD; + GL_TEXTURE30_ARB = $84DE; + GL_TEXTURE31_ARB = $84DF; + GL_ACTIVE_TEXTURE_ARB = $84E0; + GL_CLIENT_ACTIVE_TEXTURE_ARB = $84E1; + GL_MAX_TEXTURE_UNITS_ARB = $84E2; +var + glActiveTextureARB: procedure(texture: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClientActiveTextureARB: procedure(texture: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1dARB: procedure(target: GLenum; s: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1dvARB: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1fARB: procedure(target: GLenum; s: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1fvARB: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1iARB: procedure(target: GLenum; s: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1ivARB: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1sARB: procedure(target: GLenum; s: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1svARB: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2dvARB: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2fvARB: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2iARB: procedure(target: GLenum; s: GLint; t: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2ivARB: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2sARB: procedure(target: GLenum; s: GLshort; t: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2svARB: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3dvARB: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3fvARB: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3iARB: procedure(target: GLenum; s: GLint; t: GLint; r: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3ivARB: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3sARB: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3svARB: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble; q: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4dvARB: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat; q: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4fvARB: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4iARB: procedure(target: GLenum; s: GLint; t: GLint; r: GLint; q: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4ivARB: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4sARB: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort; q: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4svARB: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_multitexture: Boolean; + +//***** GL_ARB_transpose_matrix *****// +const + GL_TRANSPOSE_MODELVIEW_MATRIX_ARB = $84E3; + GL_TRANSPOSE_PROJECTION_MATRIX_ARB = $84E4; + GL_TRANSPOSE_TEXTURE_MATRIX_ARB = $84E5; + GL_TRANSPOSE_COLOR_MATRIX_ARB = $84E6; +var + glLoadTransposeMatrixfARB: procedure(m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadTransposeMatrixdARB: procedure(m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultTransposeMatrixfARB: procedure(m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultTransposeMatrixdARB: procedure(m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_transpose_matrix: Boolean; + +//***** GL_ARB_multisample *****// +const + WGL_SAMPLE_BUFFERS_ARB = $2041; + WGL_SAMPLES_ARB = $2042; + GL_MULTISAMPLE_ARB = $809D; + GL_SAMPLE_ALPHA_TO_COVERAGE_ARB = $809E; + GL_SAMPLE_ALPHA_TO_ONE_ARB = $809F; + GL_SAMPLE_COVERAGE_ARB = $80A0; + GL_MULTISAMPLE_BIT_ARB = $20000000; + GL_SAMPLE_BUFFERS_ARB = $80A8; + GL_SAMPLES_ARB = $80A9; + GL_SAMPLE_COVERAGE_VALUE_ARB = $80AA; + GL_SAMPLE_COVERAGE_INVERT_ARB = $80AB; +var + glSampleCoverageARB: procedure(value: GLclampf; invert: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_multisample: Boolean; + +//***** GL_ARB_texture_env_add *****// + +function Load_GL_ARB_texture_env_add: Boolean; + +{$IFDEF msWindows} +//***** WGL_ARB_extensions_string *****// +var + wglGetExtensionsStringARB: function(hdc: HDC): Pchar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_extensions_string: Boolean; + +//***** WGL_ARB_buffer_region *****// +const + WGL_FRONT_COLOR_BUFFER_BIT_ARB = $0001; + WGL_BACK_COLOR_BUFFER_BIT_ARB = $0002; + WGL_DEPTH_BUFFER_BIT_ARB = $0004; + WGL_STENCIL_BUFFER_BIT_ARB = $0008; +var + wglCreateBufferRegionARB: function(hDC: HDC; iLayerPlane: GLint; uType: GLuint): THandle; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDeleteBufferRegionARB: procedure(hRegion: THandle); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglSaveBufferRegionARB: function(hRegion: THandle; x: GLint; y: GLint; width: GLint; height: GLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglRestoreBufferRegionARB: function(hRegion: THandle; x: GLint; y: GLint; width: GLint; height: GLint; xSrc: GLint; ySrc: GLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_buffer_region: Boolean; +{$ENDIF} + +//***** GL_ARB_texture_cube_map *****// +const + GL_NORMAL_MAP_ARB = $8511; + GL_REFLECTION_MAP_ARB = $8512; + GL_TEXTURE_CUBE_MAP_ARB = $8513; + GL_TEXTURE_BINDING_CUBE_MAP_ARB = $8514; + GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = $8515; + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = $8516; + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = $8517; + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = $8518; + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = $8519; + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = $851A; + GL_PROXY_TEXTURE_CUBE_MAP_ARB = $851B; + GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB = $851C; + +function Load_GL_ARB_texture_cube_map: Boolean; + +//***** GL_ARB_depth_texture *****// +const + GL_DEPTH_COMPONENT16_ARB = $81A5; + GL_DEPTH_COMPONENT24_ARB = $81A6; + GL_DEPTH_COMPONENT32_ARB = $81A7; + GL_TEXTURE_DEPTH_SIZE_ARB = $884A; + GL_DEPTH_TEXTURE_MODE_ARB = $884B; + +function Load_GL_ARB_depth_texture: Boolean; + +//***** GL_ARB_point_parameters *****// +const + GL_POINT_SIZE_MIN_ARB = $8126; + GL_POINT_SIZE_MAX_ARB = $8127; + GL_POINT_FADE_THRESHOLD_SIZE_ARB = $8128; + GL_POINT_DISTANCE_ATTENUATION_ARB = $8129; +var + glPointParameterfARB: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameterfvARB: procedure(pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_point_parameters: Boolean; + +//***** GL_ARB_shadow *****// +const + GL_TEXTURE_COMPARE_MODE_ARB = $884C; + GL_TEXTURE_COMPARE_FUNC_ARB = $884D; + GL_COMPARE_R_TO_TEXTURE_ARB = $884E; + +function Load_GL_ARB_shadow: Boolean; + +//***** GL_ARB_shadow_ambient *****// +const + GL_TEXTURE_COMPARE_FAIL_VALUE_ARB = $80BF; + +function Load_GL_ARB_shadow_ambient: Boolean; + +//***** GL_ARB_texture_border_clamp *****// +const + GL_CLAMP_TO_BORDER_ARB = $812D; + +function Load_GL_ARB_texture_border_clamp: Boolean; + +//***** GL_ARB_texture_compression *****// +const + GL_COMPRESSED_ALPHA_ARB = $84E9; + GL_COMPRESSED_LUMINANCE_ARB = $84EA; + GL_COMPRESSED_LUMINANCE_ALPHA_ARB = $84EB; + GL_COMPRESSED_INTENSITY_ARB = $84EC; + GL_COMPRESSED_RGB_ARB = $84ED; + GL_COMPRESSED_RGBA_ARB = $84EE; + GL_TEXTURE_COMPRESSION_HINT_ARB = $84EF; + GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB = $86A0; + GL_TEXTURE_COMPRESSED_ARB = $86A1; + GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB = $86A2; + GL_COMPRESSED_TEXTURE_FORMATS_ARB = $86A3; +var + glCompressedTexImage3DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexImage2DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexImage1DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage3DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage2DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage1DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCompressedTexImageARB: procedure(target: GLenum; lod: GLint; img: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_texture_compression: Boolean; + +//***** GL_ARB_texture_env_combine *****// +const + GL_COMBINE_ARB = $8570; + GL_COMBINE_RGB_ARB = $8571; + GL_COMBINE_ALPHA_ARB = $8572; + GL_SOURCE0_RGB_ARB = $8580; + GL_SOURCE1_RGB_ARB = $8581; + GL_SOURCE2_RGB_ARB = $8582; + GL_SOURCE0_ALPHA_ARB = $8588; + GL_SOURCE1_ALPHA_ARB = $8589; + GL_SOURCE2_ALPHA_ARB = $858A; + GL_OPERAND0_RGB_ARB = $8590; + GL_OPERAND1_RGB_ARB = $8591; + GL_OPERAND2_RGB_ARB = $8592; + GL_OPERAND0_ALPHA_ARB = $8598; + GL_OPERAND1_ALPHA_ARB = $8599; + GL_OPERAND2_ALPHA_ARB = $859A; + GL_RGB_SCALE_ARB = $8573; + GL_ADD_SIGNED_ARB = $8574; + GL_INTERPOLATE_ARB = $8575; + GL_SUBTRACT_ARB = $84E7; + GL_CONSTANT_ARB = $8576; + GL_PRIMARY_COLOR_ARB = $8577; + GL_PREVIOUS_ARB = $8578; + +function Load_GL_ARB_texture_env_combine: Boolean; + +//***** GL_ARB_texture_env_crossbar *****// + +function Load_GL_ARB_texture_env_crossbar: Boolean; + +//***** GL_ARB_texture_env_dot3 *****// +const + GL_DOT3_RGB_ARB = $86AE; + GL_DOT3_RGBA_ARB = $86AF; + +function Load_GL_ARB_texture_env_dot3: Boolean; + +//***** GL_ARB_texture_mirrored_repeat *****// +const + GL_MIRRORED_REPEAT_ARB = $8370; + +function Load_GL_ARB_texture_mirrored_repeat: Boolean; + +//***** GL_ARB_vertex_blend *****// +const + GL_MAX_VERTEX_UNITS_ARB = $86A4; + GL_ACTIVE_VERTEX_UNITS_ARB = $86A5; + GL_WEIGHT_SUM_UNITY_ARB = $86A6; + GL_VERTEX_BLEND_ARB = $86A7; + GL_MODELVIEW0_ARB = $1700; + GL_MODELVIEW1_ARB = $850A; + GL_MODELVIEW2_ARB = $8722; + GL_MODELVIEW3_ARB = $8723; + GL_MODELVIEW4_ARB = $8724; + GL_MODELVIEW5_ARB = $8725; + GL_MODELVIEW6_ARB = $8726; + GL_MODELVIEW7_ARB = $8727; + GL_MODELVIEW8_ARB = $8728; + GL_MODELVIEW9_ARB = $8729; + GL_MODELVIEW10_ARB = $872A; + GL_MODELVIEW11_ARB = $872B; + GL_MODELVIEW12_ARB = $872C; + GL_MODELVIEW13_ARB = $872D; + GL_MODELVIEW14_ARB = $872E; + GL_MODELVIEW15_ARB = $872F; + GL_MODELVIEW16_ARB = $8730; + GL_MODELVIEW17_ARB = $8731; + GL_MODELVIEW18_ARB = $8732; + GL_MODELVIEW19_ARB = $8733; + GL_MODELVIEW20_ARB = $8734; + GL_MODELVIEW21_ARB = $8735; + GL_MODELVIEW22_ARB = $8736; + GL_MODELVIEW23_ARB = $8737; + GL_MODELVIEW24_ARB = $8738; + GL_MODELVIEW25_ARB = $8739; + GL_MODELVIEW26_ARB = $873A; + GL_MODELVIEW27_ARB = $873B; + GL_MODELVIEW28_ARB = $873C; + GL_MODELVIEW29_ARB = $873D; + GL_MODELVIEW30_ARB = $873E; + GL_MODELVIEW31_ARB = $873F; + GL_CURRENT_WEIGHT_ARB = $86A8; + GL_WEIGHT_ARRAY_TYPE_ARB = $86A9; + GL_WEIGHT_ARRAY_STRIDE_ARB = $86AA; + GL_WEIGHT_ARRAY_SIZE_ARB = $86AB; + GL_WEIGHT_ARRAY_POINTER_ARB = $86AC; + GL_WEIGHT_ARRAY_ARB = $86AD; +var + glWeightbvARB: procedure(size: GLint; weights: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightsvARB: procedure(size: GLint; weights: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightivARB: procedure(size: GLint; weights: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightfvARB: procedure(size: GLint; weights: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightdvARB: procedure(size: GLint; weights: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightvARB: procedure(size: GLint; weights: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightubvARB: procedure(size: GLint; weights: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightusvARB: procedure(size: GLint; weights: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightuivARB: procedure(size: GLint; weights: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightPointerARB: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexBlendARB: procedure(count: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_vertex_blend: Boolean; + +//***** GL_ARB_vertex_program *****// +const + GL_VERTEX_PROGRAM_ARB = $8620; + GL_VERTEX_PROGRAM_POINT_SIZE_ARB = $8642; + GL_VERTEX_PROGRAM_TWO_SIDE_ARB = $8643; + GL_COLOR_SUM_ARB = $8458; + GL_PROGRAM_FORMAT_ASCII_ARB = $8875; + GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB = $8622; + GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB = $8623; + GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB = $8624; + GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB = $8625; + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB = $886A; + GL_CURRENT_VERTEX_ATTRIB_ARB = $8626; + GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB = $8645; + GL_PROGRAM_LENGTH_ARB = $8627; + GL_PROGRAM_FORMAT_ARB = $8876; + GL_PROGRAM_BINDING_ARB = $8677; + GL_PROGRAM_INSTRUCTIONS_ARB = $88A0; + GL_MAX_PROGRAM_INSTRUCTIONS_ARB = $88A1; + GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB = $88A2; + GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB = $88A3; + GL_PROGRAM_TEMPORARIES_ARB = $88A4; + GL_MAX_PROGRAM_TEMPORARIES_ARB = $88A5; + GL_PROGRAM_NATIVE_TEMPORARIES_ARB = $88A6; + GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB = $88A7; + GL_PROGRAM_PARAMETERS_ARB = $88A8; + GL_MAX_PROGRAM_PARAMETERS_ARB = $88A9; + GL_PROGRAM_NATIVE_PARAMETERS_ARB = $88AA; + GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB = $88AB; + GL_PROGRAM_ATTRIBS_ARB = $88AC; + GL_MAX_PROGRAM_ATTRIBS_ARB = $88AD; + GL_PROGRAM_NATIVE_ATTRIBS_ARB = $88AE; + GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB = $88AF; + GL_PROGRAM_ADDRESS_REGISTERS_ARB = $88B0; + GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB = $88B1; + GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = $88B2; + GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = $88B3; + GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB = $88B4; + GL_MAX_PROGRAM_ENV_PARAMETERS_ARB = $88B5; + GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB = $88B6; + GL_PROGRAM_STRING_ARB = $8628; + GL_PROGRAM_ERROR_POSITION_ARB = $864B; + GL_CURRENT_MATRIX_ARB = $8641; + GL_TRANSPOSE_CURRENT_MATRIX_ARB = $88B7; + GL_CURRENT_MATRIX_STACK_DEPTH_ARB = $8640; + GL_MAX_VERTEX_ATTRIBS_ARB = $8869; + GL_MAX_PROGRAM_MATRICES_ARB = $862F; + GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB = $862E; + GL_PROGRAM_ERROR_STRING_ARB = $8874; + GL_MATRIX0_ARB = $88C0; + GL_MATRIX1_ARB = $88C1; + GL_MATRIX2_ARB = $88C2; + GL_MATRIX3_ARB = $88C3; + GL_MATRIX4_ARB = $88C4; + GL_MATRIX5_ARB = $88C5; + GL_MATRIX6_ARB = $88C6; + GL_MATRIX7_ARB = $88C7; + GL_MATRIX8_ARB = $88C8; + GL_MATRIX9_ARB = $88C9; + GL_MATRIX10_ARB = $88CA; + GL_MATRIX11_ARB = $88CB; + GL_MATRIX12_ARB = $88CC; + GL_MATRIX13_ARB = $88CD; + GL_MATRIX14_ARB = $88CE; + GL_MATRIX15_ARB = $88CF; + GL_MATRIX16_ARB = $88D0; + GL_MATRIX17_ARB = $88D1; + GL_MATRIX18_ARB = $88D2; + GL_MATRIX19_ARB = $88D3; + GL_MATRIX20_ARB = $88D4; + GL_MATRIX21_ARB = $88D5; + GL_MATRIX22_ARB = $88D6; + GL_MATRIX23_ARB = $88D7; + GL_MATRIX24_ARB = $88D8; + GL_MATRIX25_ARB = $88D9; + GL_MATRIX26_ARB = $88DA; + GL_MATRIX27_ARB = $88DB; + GL_MATRIX28_ARB = $88DC; + GL_MATRIX29_ARB = $88DD; + GL_MATRIX30_ARB = $88DE; + GL_MATRIX31_ARB = $88DF; +var + glVertexAttrib1sARB: procedure(index: GLuint; x: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1fARB: procedure(index: GLuint; x: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1dARB: procedure(index: GLuint; x: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2sARB: procedure(index: GLuint; x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3sARB: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4sARB: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NubARB: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1svARB: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1fvARB: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1dvARB: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2svARB: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2fvARB: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2dvARB: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3svARB: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3fvARB: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3dvARB: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4bvARB: procedure(index: GLuint; const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4svARB: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4ivARB: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4ubvARB: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4usvARB: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4uivARB: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4fvARB: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4dvARB: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NbvARB: procedure(index: GLuint; const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NsvARB: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NivARB: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NubvARB: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NusvARB: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NuivARB: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribPointerARB: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnableVertexAttribArrayARB: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisableVertexAttribArrayARB: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramStringARB: procedure(target: GLenum; format: GLenum; len: GLsizei; const _string: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindProgramARB: procedure(target: GLenum; _program: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteProgramsARB: procedure(n: GLsizei; const programs: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenProgramsARB: procedure(n: GLsizei; programs: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramEnvParameter4dARB: procedure(target: GLenum; index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramEnvParameter4dvARB: procedure(target: GLenum; index: GLuint; const params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramEnvParameter4fARB: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramEnvParameter4fvARB: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramLocalParameter4dARB: procedure(target: GLenum; index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramLocalParameter4dvARB: procedure(target: GLenum; index: GLuint; const params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramLocalParameter4fARB: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramLocalParameter4fvARB: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramEnvParameterdvARB: procedure(target: GLenum; index: GLuint; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramEnvParameterfvARB: procedure(target: GLenum; index: GLuint; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramLocalParameterdvARB: procedure(target: GLenum; index: GLuint; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramLocalParameterfvARB: procedure(target: GLenum; index: GLuint; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramivARB: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramStringARB: procedure(target: GLenum; pname: GLenum; _string: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribdvARB: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribfvARB: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribivARB: procedure(index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribPointervARB: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsProgramARB: function(_program: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_vertex_program: Boolean; + +//***** GL_ARB_window_pos *****// +var + glWindowPos2dARB: procedure(x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2fARB: procedure(x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2iARB: procedure(x: GLint; y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2sARB: procedure(x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2dvARB: procedure(const p: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2fvARB: procedure(const p: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2ivARB: procedure(const p: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2svARB: procedure(const p: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3dARB: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3fARB: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3iARB: procedure(x: GLint; y: GLint; z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3sARB: procedure(x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3dvARB: procedure(const p: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3fvARB: procedure(const p: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3ivARB: procedure(const p: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3svARB: procedure(const p: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_window_pos: Boolean; + +//***** GL_EXT_422_pixels *****// +const + GL_422_EXT = $80CC; + GL_422_REV_EXT = $80CD; + GL_422_AVERAGE_EXT = $80CE; + GL_422_REV_AVERAGE_EXT = $80CF; + +function Load_GL_EXT_422_pixels: Boolean; + +//***** GL_EXT_abgr *****// +const + GL_ABGR_EXT = $8000; + +function Load_GL_EXT_abgr: Boolean; + +//***** GL_EXT_bgra *****// +const + GL_BGR_EXT = $80E0; + GL_BGRA_EXT = $80E1; + +function Load_GL_EXT_bgra: Boolean; + +//***** GL_EXT_blend_color *****// +const + GL_CONSTANT_COLOR_EXT = $8001; + GL_ONE_MINUS_CONSTANT_COLOR_EXT = $8002; + GL_CONSTANT_ALPHA_EXT = $8003; + GL_ONE_MINUS_CONSTANT_ALPHA_EXT = $8004; + GL_BLEND_COLOR_EXT = $8005; +var + glBlendColorEXT: procedure(red: GLclampf; green: GLclampf; blue: GLclampf; alpha: GLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_blend_color: Boolean; + +//***** GL_EXT_blend_func_separate *****// +const + GL_BLEND_DST_RGB_EXT = $80C8; + GL_BLEND_SRC_RGB_EXT = $80C9; + GL_BLEND_DST_ALPHA_EXT = $80CA; + GL_BLEND_SRC_ALPHA_EXT = $80CB; +var + glBlendFuncSeparateEXT: procedure(sfactorRGB: GLenum; dfactorRGB: GLenum; sfactorAlpha: GLenum; dfactorAlpha: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_blend_func_separate: Boolean; + +//***** GL_EXT_blend_logic_op *****// + +function Load_GL_EXT_blend_logic_op: Boolean; + +//***** GL_EXT_blend_minmax *****// +const + GL_FUNC_ADD_EXT = $8006; + GL_MIN_EXT = $8007; + GL_MAX_EXT = $8008; + GL_BLEND_EQUATION_EXT = $8009; +var + glBlendEquationEXT: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_blend_minmax: Boolean; + +//***** GL_EXT_blend_subtract *****// +const + GL_FUNC_SUBTRACT_EXT = $800A; + GL_FUNC_REVERSE_SUBTRACT_EXT = $800B; + +function Load_GL_EXT_blend_subtract: Boolean; + +//***** GL_EXT_clip_volume_hint *****// +const + GL_CLIP_VOLUME_CLIPPING_HINT_EXT = $80F0; + +function Load_GL_EXT_clip_volume_hint: Boolean; + +//***** GL_EXT_color_subtable *****// +var + glColorSubTableEXT: procedure(target: GLenum; start: GLsizei; count: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyColorSubTableEXT: procedure(target: GLenum; start: GLsizei; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_color_subtable: Boolean; + +//***** GL_EXT_compiled_vertex_array *****// +const + GL_ARRAY_ELEMENT_LOCK_FIRST_EXT = $81A8; + GL_ARRAY_ELEMENT_LOCK_COUNT_EXT = $81A9; +var + glLockArraysEXT: procedure(first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUnlockArraysEXT: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_compiled_vertex_array: Boolean; + +//***** GL_EXT_convolution *****// +const + GL_CONVOLUTION_1D_EXT = $8010; + GL_CONVOLUTION_2D_EXT = $8011; + GL_SEPARABLE_2D_EXT = $8012; + GL_CONVOLUTION_BORDER_MODE_EXT = $8013; + GL_CONVOLUTION_FILTER_SCALE_EXT = $8014; + GL_CONVOLUTION_FILTER_BIAS_EXT = $8015; + GL_REDUCE_EXT = $8016; + GL_CONVOLUTION_FORMAT_EXT = $8017; + GL_CONVOLUTION_WIDTH_EXT = $8018; + GL_CONVOLUTION_HEIGHT_EXT = $8019; + GL_MAX_CONVOLUTION_WIDTH_EXT = $801A; + GL_MAX_CONVOLUTION_HEIGHT_EXT = $801B; + GL_POST_CONVOLUTION_RED_SCALE_EXT = $801C; + GL_POST_CONVOLUTION_GREEN_SCALE_EXT = $801D; + GL_POST_CONVOLUTION_BLUE_SCALE_EXT = $801E; + GL_POST_CONVOLUTION_ALPHA_SCALE_EXT = $801F; + GL_POST_CONVOLUTION_RED_BIAS_EXT = $8020; + GL_POST_CONVOLUTION_GREEN_BIAS_EXT = $8021; + GL_POST_CONVOLUTION_BLUE_BIAS_EXT = $8022; + GL_POST_CONVOLUTION_ALPHA_BIAS_EXT = $8023; +var + glConvolutionFilter1DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyConvolutionFilter1DEXT: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyConvolutionFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionFilterEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSeparableFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const row: PGLvoid; const column: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSeparableFilterEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; row: PGLvoid; column: PGLvoid; span: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameteriEXT: procedure(target: GLenum; pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameterivEXT: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameterfEXT: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameterfvEXT: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_convolution: Boolean; + +//***** GL_EXT_fog_coord *****// +const + GL_FOG_COORDINATE_SOURCE_EXT = $8450; + GL_FOG_COORDINATE_EXT = $8451; + GL_FRAGMENT_DEPTH_EXT = $8452; + GL_CURRENT_FOG_COORDINATE_EXT = $8453; + GL_FOG_COORDINATE_ARRAY_TYPE_EXT = $8454; + GL_FOG_COORDINATE_ARRAY_STRIDE_EXT = $8455; + GL_FOG_COORDINATE_ARRAY_POINTER_EXT = $8456; + GL_FOG_COORDINATE_ARRAY_EXT = $8457; +var + glFogCoordfEXT: procedure(coord: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoorddEXT: procedure(coord: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordfvEXT: procedure(coord: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoorddvEXT: procedure(coord: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordPointerEXT: procedure(_type: GLenum; stride: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_fog_coord: Boolean; + +//***** GL_EXT_histogram *****// +const + GL_HISTOGRAM_EXT = $8024; + GL_PROXY_HISTOGRAM_EXT = $8025; + GL_HISTOGRAM_WIDTH_EXT = $8026; + GL_HISTOGRAM_FORMAT_EXT = $8027; + GL_HISTOGRAM_RED_SIZE_EXT = $8028; + GL_HISTOGRAM_GREEN_SIZE_EXT = $8029; + GL_HISTOGRAM_BLUE_SIZE_EXT = $802A; + GL_HISTOGRAM_ALPHA_SIZE_EXT = $802B; + GL_HISTOGRAM_LUMINANCE_SIZE_EXT = $802C; + GL_HISTOGRAM_SINK_EXT = $802D; + GL_MINMAX_EXT = $802E; + GL_MINMAX_FORMAT_EXT = $802F; + GL_MINMAX_SINK_EXT = $8030; +var + glHistogramEXT: procedure(target: GLenum; width: GLsizei; internalformat: GLenum; sink: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glResetHistogramEXT: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogramEXT: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogramParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogramParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMinmaxEXT: procedure(target: GLenum; internalformat: GLenum; sink: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glResetMinmaxEXT: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmaxEXT: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmaxParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmaxParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_histogram: Boolean; + +//***** GL_EXT_multi_draw_arrays *****// +var + glMultiDrawArraysEXT: procedure(mode: GLenum; first: PGLint; count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawElementsEXT: procedure(mode: GLenum; count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_multi_draw_arrays: Boolean; + +//***** GL_EXT_packed_depth_stencil *****// +const + GL_DEPTH_STENCIL_EXT = $84F9; + GL_UNSIGNED_INT_24_8_EXT = $84FA; + GL_DEPTH24_STENCIL8_EXT = $88F0; + GL_TEXTURE_STENCIL_SIZE_EXT = $88F1; + +function Load_GL_EXT_packed_depth_stencil: Boolean; + +//***** GL_EXT_packed_pixels *****// +const + GL_UNSIGNED_BYTE_3_3_2_EXT = $8032; + GL_UNSIGNED_SHORT_4_4_4_4_EXT = $8033; + GL_UNSIGNED_SHORT_5_5_5_1_EXT = $8034; + GL_UNSIGNED_INT_8_8_8_8_EXT = $8035; + GL_UNSIGNED_INT_10_10_10_2_EXT = $8036; + +function Load_GL_EXT_packed_pixels: Boolean; + +//***** GL_EXT_paletted_texture *****// +const + GL_COLOR_INDEX1_EXT = $80E2; + GL_COLOR_INDEX2_EXT = $80E3; + GL_COLOR_INDEX4_EXT = $80E4; + GL_COLOR_INDEX8_EXT = $80E5; + GL_COLOR_INDEX12_EXT = $80E6; + GL_COLOR_INDEX16_EXT = $80E7; + GL_COLOR_TABLE_FORMAT_EXT = $80D8; + GL_COLOR_TABLE_WIDTH_EXT = $80D9; + GL_COLOR_TABLE_RED_SIZE_EXT = $80DA; + GL_COLOR_TABLE_GREEN_SIZE_EXT = $80DB; + GL_COLOR_TABLE_BLUE_SIZE_EXT = $80DC; + GL_COLOR_TABLE_ALPHA_SIZE_EXT = $80DD; + GL_COLOR_TABLE_LUMINANCE_SIZE_EXT = $80DE; + GL_COLOR_TABLE_INTENSITY_SIZE_EXT = $80DF; + GL_TEXTURE_INDEX_SIZE_EXT = $80ED; + GL_TEXTURE_1D = $0DE0; + GL_TEXTURE_2D = $0DE1; + GL_TEXTURE_3D_EXT = $806F; + // GL_TEXTURE_CUBE_MAP_ARB { already defined } + GL_PROXY_TEXTURE_1D = $8063; + GL_PROXY_TEXTURE_2D = $8064; + GL_PROXY_TEXTURE_3D_EXT = $8070; + // GL_PROXY_TEXTURE_CUBE_MAP_ARB { already defined } + // GL_TEXTURE_1D { already defined } + // GL_TEXTURE_2D { already defined } + // GL_TEXTURE_3D_EXT { already defined } + // GL_TEXTURE_CUBE_MAP_ARB { already defined } +var + glColorTableEXT: procedure(target: GLenum; internalFormat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + // glColorSubTableEXT { already defined } + glGetColorTableEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_paletted_texture: Boolean; + +//***** GL_EXT_point_parameters *****// +const + GL_POINT_SIZE_MIN_EXT = $8126; + GL_POINT_SIZE_MAX_EXT = $8127; + GL_POINT_FADE_THRESHOLD_SIZE_EXT = $8128; + GL_DISTANCE_ATTENUATION_EXT = $8129; +var + glPointParameterfEXT: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameterfvEXT: procedure(pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_point_parameters: Boolean; + +//***** GL_EXT_polygon_offset *****// +const + GL_POLYGON_OFFSET_EXT = $8037; + GL_POLYGON_OFFSET_FACTOR_EXT = $8038; + GL_POLYGON_OFFSET_BIAS_EXT = $8039; +var + glPolygonOffsetEXT: procedure(factor: GLfloat; bias: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_polygon_offset: Boolean; + +//***** GL_EXT_secondary_color *****// +const + GL_COLOR_SUM_EXT = $8458; + GL_CURRENT_SECONDARY_COLOR_EXT = $8459; + GL_SECONDARY_COLOR_ARRAY_SIZE_EXT = $845A; + GL_SECONDARY_COLOR_ARRAY_TYPE_EXT = $845B; + GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT = $845C; + GL_SECONDARY_COLOR_ARRAY_POINTER_EXT = $845D; + GL_SECONDARY_COLOR_ARRAY_EXT = $845E; +var + glSecondaryColor3bEXT: procedure(components: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3sEXT: procedure(components: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3iEXT: procedure(components: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3fEXT: procedure(components: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3dEXT: procedure(components: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ubEXT: procedure(components: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3usEXT: procedure(components: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3uiEXT: procedure(components: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3bvEXT: procedure(components: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3svEXT: procedure(components: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ivEXT: procedure(components: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3fvEXT: procedure(components: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3dvEXT: procedure(components: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ubvEXT: procedure(components: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3usvEXT: procedure(components: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3uivEXT: procedure(components: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColorPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_secondary_color: Boolean; + +//***** GL_EXT_separate_specular_color *****// +const + GL_LIGHT_MODEL_COLOR_CONTROL_EXT = $81F8; + GL_SINGLE_COLOR_EXT = $81F9; + GL_SEPARATE_SPECULAR_COLOR_EXT = $81FA; + +function Load_GL_EXT_separate_specular_color: Boolean; + +//***** GL_EXT_shadow_funcs *****// + +function Load_GL_EXT_shadow_funcs: Boolean; + +//***** GL_EXT_shared_texture_palette *****// +const + GL_SHARED_TEXTURE_PALETTE_EXT = $81FB; + +function Load_GL_EXT_shared_texture_palette: Boolean; + +//***** GL_EXT_stencil_two_side *****// +const + GL_STENCIL_TEST_TWO_SIDE_EXT = $8910; + GL_ACTIVE_STENCIL_FACE_EXT = $8911; +var + glActiveStencilFaceEXT: procedure(face: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_stencil_two_side: Boolean; + +//***** GL_EXT_stencil_wrap *****// +const + GL_INCR_WRAP_EXT = $8507; + GL_DECR_WRAP_EXT = $8508; + +function Load_GL_EXT_stencil_wrap: Boolean; + +//***** GL_EXT_subtexture *****// +var + glTexSubImage1DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexSubImage2DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexSubImage3DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_subtexture: Boolean; + +//***** GL_EXT_texture3D *****// +const + GL_PACK_SKIP_IMAGES_EXT = $806B; + GL_PACK_IMAGE_HEIGHT_EXT = $806C; + GL_UNPACK_SKIP_IMAGES_EXT = $806D; + GL_UNPACK_IMAGE_HEIGHT_EXT = $806E; + // GL_TEXTURE_3D_EXT { already defined } + // GL_PROXY_TEXTURE_3D_EXT { already defined } + GL_TEXTURE_DEPTH_EXT = $8071; + GL_TEXTURE_WRAP_R_EXT = $8072; + GL_MAX_3D_TEXTURE_SIZE_EXT = $8073; +var + glTexImage3DEXT: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_texture3D: Boolean; + +//***** GL_EXT_texture_compression_s3tc *****// +const + GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0; + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1; + GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2; + GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3; + +function Load_GL_EXT_texture_compression_s3tc: Boolean; + +//***** GL_EXT_texture_env_add *****// + +function Load_GL_EXT_texture_env_add: Boolean; + +//***** GL_EXT_texture_env_combine *****// +const + GL_COMBINE_EXT = $8570; + GL_COMBINE_RGB_EXT = $8571; + GL_COMBINE_ALPHA_EXT = $8572; + GL_SOURCE0_RGB_EXT = $8580; + GL_SOURCE1_RGB_EXT = $8581; + GL_SOURCE2_RGB_EXT = $8582; + GL_SOURCE0_ALPHA_EXT = $8588; + GL_SOURCE1_ALPHA_EXT = $8589; + GL_SOURCE2_ALPHA_EXT = $858A; + GL_OPERAND0_RGB_EXT = $8590; + GL_OPERAND1_RGB_EXT = $8591; + GL_OPERAND2_RGB_EXT = $8592; + GL_OPERAND0_ALPHA_EXT = $8598; + GL_OPERAND1_ALPHA_EXT = $8599; + GL_OPERAND2_ALPHA_EXT = $859A; + GL_RGB_SCALE_EXT = $8573; + GL_ADD_SIGNED_EXT = $8574; + GL_INTERPOLATE_EXT = $8575; + GL_CONSTANT_EXT = $8576; + GL_PRIMARY_COLOR_EXT = $8577; + GL_PREVIOUS_EXT = $8578; + +function Load_GL_EXT_texture_env_combine: Boolean; + +//***** GL_EXT_texture_env_dot3 *****// +const + GL_DOT3_RGB_EXT = $8740; + GL_DOT3_RGBA_EXT = $8741; + +function Load_GL_EXT_texture_env_dot3: Boolean; + +//***** GL_EXT_texture_filter_anisotropic *****// +const + GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE; + GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF; + +function Load_GL_EXT_texture_filter_anisotropic: Boolean; + +//***** GL_EXT_texture_lod_bias *****// +const + GL_TEXTURE_FILTER_CONTROL_EXT = $8500; + GL_TEXTURE_LOD_BIAS_EXT = $8501; + GL_MAX_TEXTURE_LOD_BIAS_EXT = $84FD; + +function Load_GL_EXT_texture_lod_bias: Boolean; + +//***** GL_EXT_texture_object *****// +const + GL_TEXTURE_PRIORITY_EXT = $8066; + GL_TEXTURE_RESIDENT_EXT = $8067; + GL_TEXTURE_1D_BINDING_EXT = $8068; + GL_TEXTURE_2D_BINDING_EXT = $8069; + GL_TEXTURE_3D_BINDING_EXT = $806A; +var + glGenTexturesEXT: procedure(n: GLsizei; textures: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteTexturesEXT: procedure(n: GLsizei; const textures: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindTextureEXT: procedure(target: GLenum; texture: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPrioritizeTexturesEXT: procedure(n: GLsizei; const textures: PGLuint; const priorities: PGLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAreTexturesResidentEXT: function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsTextureEXT: function(texture: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_texture_object: Boolean; + +//***** GL_EXT_vertex_array *****// +const + GL_VERTEX_ARRAY_EXT = $8074; + GL_NORMAL_ARRAY_EXT = $8075; + GL_COLOR_ARRAY_EXT = $8076; + GL_INDEX_ARRAY_EXT = $8077; + GL_TEXTURE_COORD_ARRAY_EXT = $8078; + GL_EDGE_FLAG_ARRAY_EXT = $8079; + GL_DOUBLE_EXT = $140A; + GL_VERTEX_ARRAY_SIZE_EXT = $807A; + GL_VERTEX_ARRAY_TYPE_EXT = $807B; + GL_VERTEX_ARRAY_STRIDE_EXT = $807C; + GL_VERTEX_ARRAY_COUNT_EXT = $807D; + GL_NORMAL_ARRAY_TYPE_EXT = $807E; + GL_NORMAL_ARRAY_STRIDE_EXT = $807F; + GL_NORMAL_ARRAY_COUNT_EXT = $8080; + GL_COLOR_ARRAY_SIZE_EXT = $8081; + GL_COLOR_ARRAY_TYPE_EXT = $8082; + GL_COLOR_ARRAY_STRIDE_EXT = $8083; + GL_COLOR_ARRAY_COUNT_EXT = $8084; + GL_INDEX_ARRAY_TYPE_EXT = $8085; + GL_INDEX_ARRAY_STRIDE_EXT = $8086; + GL_INDEX_ARRAY_COUNT_EXT = $8087; + GL_TEXTURE_COORD_ARRAY_SIZE_EXT = $8088; + GL_TEXTURE_COORD_ARRAY_TYPE_EXT = $8089; + GL_TEXTURE_COORD_ARRAY_STRIDE_EXT = $808A; + GL_TEXTURE_COORD_ARRAY_COUNT_EXT = $808B; + GL_EDGE_FLAG_ARRAY_STRIDE_EXT = $808C; + GL_EDGE_FLAG_ARRAY_COUNT_EXT = $808D; + GL_VERTEX_ARRAY_POINTER_EXT = $808E; + GL_NORMAL_ARRAY_POINTER_EXT = $808F; + GL_COLOR_ARRAY_POINTER_EXT = $8090; + GL_INDEX_ARRAY_POINTER_EXT = $8091; + GL_TEXTURE_COORD_ARRAY_POINTER_EXT = $8092; + GL_EDGE_FLAG_ARRAY_POINTER_EXT = $8093; +var + glArrayElementEXT: procedure(i: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawArraysEXT: procedure(mode: GLenum; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalPointerEXT: procedure(_type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexPointerEXT: procedure(_type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEdgeFlagPointerEXT: procedure(stride: GLsizei; count: GLsizei; const pointer: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPointervEXT: procedure(pname: GLenum; params: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_vertex_array: Boolean; + +//***** GL_EXT_vertex_shader *****// +const + GL_VERTEX_SHADER_EXT = $8780; + GL_VARIANT_VALUE_EXT = $87E4; + GL_VARIANT_DATATYPE_EXT = $87E5; + GL_VARIANT_ARRAY_STRIDE_EXT = $87E6; + GL_VARIANT_ARRAY_TYPE_EXT = $87E7; + GL_VARIANT_ARRAY_EXT = $87E8; + GL_VARIANT_ARRAY_POINTER_EXT = $87E9; + GL_INVARIANT_VALUE_EXT = $87EA; + GL_INVARIANT_DATATYPE_EXT = $87EB; + GL_LOCAL_CONSTANT_VALUE_EXT = $87EC; + GL_LOCAL_CONSTANT_DATATYPE_EXT = $87ED; + GL_OP_INDEX_EXT = $8782; + GL_OP_NEGATE_EXT = $8783; + GL_OP_DOT3_EXT = $8784; + GL_OP_DOT4_EXT = $8785; + GL_OP_MUL_EXT = $8786; + GL_OP_ADD_EXT = $8787; + GL_OP_MADD_EXT = $8788; + GL_OP_FRAC_EXT = $8789; + GL_OP_MAX_EXT = $878A; + GL_OP_MIN_EXT = $878B; + GL_OP_SET_GE_EXT = $878C; + GL_OP_SET_LT_EXT = $878D; + GL_OP_CLAMP_EXT = $878E; + GL_OP_FLOOR_EXT = $878F; + GL_OP_ROUND_EXT = $8790; + GL_OP_EXP_BASE_2_EXT = $8791; + GL_OP_LOG_BASE_2_EXT = $8792; + GL_OP_POWER_EXT = $8793; + GL_OP_RECIP_EXT = $8794; + GL_OP_RECIP_SQRT_EXT = $8795; + GL_OP_SUB_EXT = $8796; + GL_OP_CROSS_PRODUCT_EXT = $8797; + GL_OP_MULTIPLY_MATRIX_EXT = $8798; + GL_OP_MOV_EXT = $8799; + GL_OUTPUT_VERTEX_EXT = $879A; + GL_OUTPUT_COLOR0_EXT = $879B; + GL_OUTPUT_COLOR1_EXT = $879C; + GL_OUTPUT_TEXTURE_COORD0_EXT = $879D; + GL_OUTPUT_TEXTURE_COORD1_EXT = $879E; + GL_OUTPUT_TEXTURE_COORD2_EXT = $879F; + GL_OUTPUT_TEXTURE_COORD3_EXT = $87A0; + GL_OUTPUT_TEXTURE_COORD4_EXT = $87A1; + GL_OUTPUT_TEXTURE_COORD5_EXT = $87A2; + GL_OUTPUT_TEXTURE_COORD6_EXT = $87A3; + GL_OUTPUT_TEXTURE_COORD7_EXT = $87A4; + GL_OUTPUT_TEXTURE_COORD8_EXT = $87A5; + GL_OUTPUT_TEXTURE_COORD9_EXT = $87A6; + GL_OUTPUT_TEXTURE_COORD10_EXT = $87A7; + GL_OUTPUT_TEXTURE_COORD11_EXT = $87A8; + GL_OUTPUT_TEXTURE_COORD12_EXT = $87A9; + GL_OUTPUT_TEXTURE_COORD13_EXT = $87AA; + GL_OUTPUT_TEXTURE_COORD14_EXT = $87AB; + GL_OUTPUT_TEXTURE_COORD15_EXT = $87AC; + GL_OUTPUT_TEXTURE_COORD16_EXT = $87AD; + GL_OUTPUT_TEXTURE_COORD17_EXT = $87AE; + GL_OUTPUT_TEXTURE_COORD18_EXT = $87AF; + GL_OUTPUT_TEXTURE_COORD19_EXT = $87B0; + GL_OUTPUT_TEXTURE_COORD20_EXT = $87B1; + GL_OUTPUT_TEXTURE_COORD21_EXT = $87B2; + GL_OUTPUT_TEXTURE_COORD22_EXT = $87B3; + GL_OUTPUT_TEXTURE_COORD23_EXT = $87B4; + GL_OUTPUT_TEXTURE_COORD24_EXT = $87B5; + GL_OUTPUT_TEXTURE_COORD25_EXT = $87B6; + GL_OUTPUT_TEXTURE_COORD26_EXT = $87B7; + GL_OUTPUT_TEXTURE_COORD27_EXT = $87B8; + GL_OUTPUT_TEXTURE_COORD28_EXT = $87B9; + GL_OUTPUT_TEXTURE_COORD29_EXT = $87BA; + GL_OUTPUT_TEXTURE_COORD30_EXT = $87BB; + GL_OUTPUT_TEXTURE_COORD31_EXT = $87BC; + GL_OUTPUT_FOG_EXT = $87BD; + GL_SCALAR_EXT = $87BE; + GL_VECTOR_EXT = $87BF; + GL_MATRIX_EXT = $87C0; + GL_VARIANT_EXT = $87C1; + GL_INVARIANT_EXT = $87C2; + GL_LOCAL_CONSTANT_EXT = $87C3; + GL_LOCAL_EXT = $87C4; + GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT = $87C5; + GL_MAX_VERTEX_SHADER_VARIANTS_EXT = $87C6; + GL_MAX_VERTEX_SHADER_INVARIANTS_EXT = $87C7; + GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87C8; + GL_MAX_VERTEX_SHADER_LOCALS_EXT = $87C9; + GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT = $87CA; + GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT = $87CB; + GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87CC; + GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT = $87CD; + GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT = $87CE; + GL_VERTEX_SHADER_INSTRUCTIONS_EXT = $87CF; + GL_VERTEX_SHADER_VARIANTS_EXT = $87D0; + GL_VERTEX_SHADER_INVARIANTS_EXT = $87D1; + GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87D2; + GL_VERTEX_SHADER_LOCALS_EXT = $87D3; + GL_VERTEX_SHADER_BINDING_EXT = $8781; + GL_VERTEX_SHADER_OPTIMIZED_EXT = $87D4; + GL_X_EXT = $87D5; + GL_Y_EXT = $87D6; + GL_Z_EXT = $87D7; + GL_W_EXT = $87D8; + GL_NEGATIVE_X_EXT = $87D9; + GL_NEGATIVE_Y_EXT = $87DA; + GL_NEGATIVE_Z_EXT = $87DB; + GL_NEGATIVE_W_EXT = $87DC; + GL_ZERO_EXT = $87DD; + GL_ONE_EXT = $87DE; + GL_NEGATIVE_ONE_EXT = $87DF; + GL_NORMALIZED_RANGE_EXT = $87E0; + GL_FULL_RANGE_EXT = $87E1; + GL_CURRENT_VERTEX_EXT = $87E2; + GL_MVP_MATRIX_EXT = $87E3; +var + glBeginVertexShaderEXT: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndVertexShaderEXT: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindVertexShaderEXT: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenVertexShadersEXT: function(range: GLuint): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteVertexShaderEXT: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShaderOp1EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShaderOp2EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint; arg2: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShaderOp3EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint; arg2: GLuint; arg3: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSwizzleEXT: procedure(res: GLuint; _in: GLuint; outX: GLenum; outY: GLenum; outZ: GLenum; outW: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWriteMaskEXT: procedure(res: GLuint; _in: GLuint; outX: GLenum; outY: GLenum; outZ: GLenum; outW: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glInsertComponentEXT: procedure(res: GLuint; src: GLuint; num: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glExtractComponentEXT: procedure(res: GLuint; src: GLuint; num: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenSymbolsEXT: function(datatype: GLenum; storagetype: GLenum; range: GLenum; components: GLuint): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSetInvariantEXT: procedure(id: GLuint; _type: GLenum; addr: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSetLocalConstantEXT: procedure(id: GLuint; _type: GLenum; addr: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantbvEXT: procedure(id: GLuint; addr: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantsvEXT: procedure(id: GLuint; addr: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantivEXT: procedure(id: GLuint; addr: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantfvEXT: procedure(id: GLuint; addr: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantdvEXT: procedure(id: GLuint; addr: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantubvEXT: procedure(id: GLuint; addr: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantusvEXT: procedure(id: GLuint; addr: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantuivEXT: procedure(id: GLuint; addr: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantPointerEXT: procedure(id: GLuint; _type: GLenum; stride: GLuint; addr: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnableVariantClientStateEXT: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisableVariantClientStateEXT: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindLightParameterEXT: function(light: GLenum; value: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindMaterialParameterEXT: function(face: GLenum; value: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindTexGenParameterEXT: function(_unit: GLenum; coord: GLenum; value: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindTextureUnitParameterEXT: function(_unit: GLenum; value: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindParameterEXT: function(value: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsVariantEnabledEXT: function(id: GLuint; cap: GLenum): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantPointervEXT: procedure(id: GLuint; value: GLenum; data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetInvariantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetInvariantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetInvariantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetLocalConstantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetLocalConstantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetLocalConstantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_vertex_shader: Boolean; + +//***** GL_EXT_vertex_weighting *****// +const + GL_VERTEX_WEIGHTING_EXT = $8509; + GL_MODELVIEW0_EXT = $1700; + GL_MODELVIEW1_EXT = $850A; + GL_MODELVIEW0_MATRIX_EXT = $0BA6; + GL_MODELVIEW1_MATRIX_EXT = $8506; + GL_CURRENT_VERTEX_WEIGHT_EXT = $850B; + GL_VERTEX_WEIGHT_ARRAY_EXT = $850C; + GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT = $850D; + GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT = $850E; + GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = $850F; + GL_MODELVIEW0_STACK_DEPTH_EXT = $0BA3; + GL_MODELVIEW1_STACK_DEPTH_EXT = $8502; + GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = $8510; +var + glVertexWeightfEXT: procedure(weight: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexWeightfvEXT: procedure(weight: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexWeightPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_vertex_weighting: Boolean; + +//***** GL_HP_occlusion_test *****// +const + GL_OCCLUSION_TEST_HP = $8165; + GL_OCCLUSION_TEST_RESULT_HP = $8166; + +function Load_GL_HP_occlusion_test: Boolean; + +//***** GL_NV_blend_square *****// + +function Load_GL_NV_blend_square: Boolean; + +//***** GL_NV_copy_depth_to_color *****// +const + GL_DEPTH_STENCIL_TO_RGBA_NV = $886E; + GL_DEPTH_STENCIL_TO_BGRA_NV = $886F; + +function Load_GL_NV_copy_depth_to_color: Boolean; + +//***** GL_NV_depth_clamp *****// +const + GL_DEPTH_CLAMP_NV = $864F; + +function Load_GL_NV_depth_clamp: Boolean; + +//***** GL_NV_evaluators *****// +const + GL_EVAL_2D_NV = $86C0; + GL_EVAL_TRIANGULAR_2D_NV = $86C1; + GL_MAP_TESSELLATION_NV = $86C2; + GL_MAP_ATTRIB_U_ORDER_NV = $86C3; + GL_MAP_ATTRIB_V_ORDER_NV = $86C4; + GL_EVAL_FRACTIONAL_TESSELLATION_NV = $86C5; + GL_EVAL_VERTEX_ATTRIB0_NV = $86C6; + GL_EVAL_VERTEX_ATTRIB1_NV = $86C7; + GL_EVAL_VERTEX_ATTRIB2_NV = $86C8; + GL_EVAL_VERTEX_ATTRIB3_NV = $86C9; + GL_EVAL_VERTEX_ATTRIB4_NV = $86CA; + GL_EVAL_VERTEX_ATTRIB5_NV = $86CB; + GL_EVAL_VERTEX_ATTRIB6_NV = $86CC; + GL_EVAL_VERTEX_ATTRIB7_NV = $86CD; + GL_EVAL_VERTEX_ATTRIB8_NV = $86CE; + GL_EVAL_VERTEX_ATTRIB9_NV = $86CF; + GL_EVAL_VERTEX_ATTRIB10_NV = $86D0; + GL_EVAL_VERTEX_ATTRIB11_NV = $86D1; + GL_EVAL_VERTEX_ATTRIB12_NV = $86D2; + GL_EVAL_VERTEX_ATTRIB13_NV = $86D3; + GL_EVAL_VERTEX_ATTRIB14_NV = $86D4; + GL_EVAL_VERTEX_ATTRIB15_NV = $86D5; + GL_MAX_MAP_TESSELLATION_NV = $86D6; + GL_MAX_RATIONAL_EVAL_ORDER_NV = $86D7; +var + glMapControlPointsNV: procedure(target: GLenum; index: GLuint; _type: GLenum; ustride: GLsizei; vstride: GLsizei; uorder: GLint; vorder: GLint; _packed: GLboolean; const points: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapParameterivNV: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapParameterfvNV: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapControlPointsNV: procedure(target: GLenum; index: GLuint; _type: GLenum; ustride: GLsizei; vstride: GLsizei; _packed: GLboolean; points: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapParameterivNV: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapParameterfvNV: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapAttribParameterivNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapAttribParameterfvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalMapsNV: procedure(target: GLenum; mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_evaluators: Boolean; + +//***** GL_NV_fence *****// +const + GL_ALL_COMPLETED_NV = $84F2; + GL_FENCE_STATUS_NV = $84F3; + GL_FENCE_CONDITION_NV = $84F4; +var + glGenFencesNV: procedure(n: GLsizei; fences: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteFencesNV: procedure(n: GLsizei; const fences: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSetFenceNV: procedure(fence: GLuint; condition: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTestFenceNV: function(fence: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFinishFenceNV: procedure(fence: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsFenceNV: function(fence: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFenceivNV: procedure(fence: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_fence: Boolean; + +//***** GL_NV_fog_distance *****// +const + GL_FOG_DISTANCE_MODE_NV = $855A; + GL_EYE_RADIAL_NV = $855B; + GL_EYE_PLANE_ABSOLUTE_NV = $855C; + +function Load_GL_NV_fog_distance: Boolean; + +//***** GL_NV_light_max_exponent *****// +const + GL_MAX_SHININESS_NV = $8504; + GL_MAX_SPOT_EXPONENT_NV = $8505; + +function Load_GL_NV_light_max_exponent: Boolean; + +//***** GL_NV_multisample_filter_hint *****// +const + GL_MULTISAMPLE_FILTER_HINT_NV = $8534; + +function Load_GL_NV_multisample_filter_hint: Boolean; + +//***** GL_NV_occlusion_query *****// + // GL_OCCLUSION_TEST_HP { already defined } + // GL_OCCLUSION_TEST_RESULT_HP { already defined } +const + GL_PIXEL_COUNTER_BITS_NV = $8864; + GL_CURRENT_OCCLUSION_QUERY_ID_NV = $8865; + GL_PIXEL_COUNT_NV = $8866; + GL_PIXEL_COUNT_AVAILABLE_NV = $8867; +var + glGenOcclusionQueriesNV: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteOcclusionQueriesNV: procedure(n: GLsizei; const ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsOcclusionQueryNV: function(id: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginOcclusionQueryNV: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndOcclusionQueryNV: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetOcclusionQueryivNV: procedure(id: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetOcclusionQueryuivNV: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_occlusion_query: Boolean; + +//***** GL_NV_packed_depth_stencil *****// +const + GL_DEPTH_STENCIL_NV = $84F9; + GL_UNSIGNED_INT_24_8_NV = $84FA; + +function Load_GL_NV_packed_depth_stencil: Boolean; + +//***** GL_NV_point_sprite *****// +const + GL_POINT_SPRITE_NV = $8861; + GL_COORD_REPLACE_NV = $8862; + GL_POINT_SPRITE_R_MODE_NV = $8863; +var + glPointParameteriNV: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameterivNV: procedure(pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_point_sprite: Boolean; + +//***** GL_NV_register_combiners *****// +const + GL_REGISTER_COMBINERS_NV = $8522; + GL_COMBINER0_NV = $8550; + GL_COMBINER1_NV = $8551; + GL_COMBINER2_NV = $8552; + GL_COMBINER3_NV = $8553; + GL_COMBINER4_NV = $8554; + GL_COMBINER5_NV = $8555; + GL_COMBINER6_NV = $8556; + GL_COMBINER7_NV = $8557; + GL_VARIABLE_A_NV = $8523; + GL_VARIABLE_B_NV = $8524; + GL_VARIABLE_C_NV = $8525; + GL_VARIABLE_D_NV = $8526; + GL_VARIABLE_E_NV = $8527; + GL_VARIABLE_F_NV = $8528; + GL_VARIABLE_G_NV = $8529; + GL_CONSTANT_COLOR0_NV = $852A; + GL_CONSTANT_COLOR1_NV = $852B; + GL_PRIMARY_COLOR_NV = $852C; + GL_SECONDARY_COLOR_NV = $852D; + GL_SPARE0_NV = $852E; + GL_SPARE1_NV = $852F; + GL_UNSIGNED_IDENTITY_NV = $8536; + GL_UNSIGNED_INVERT_NV = $8537; + GL_EXPAND_NORMAL_NV = $8538; + GL_EXPAND_NEGATE_NV = $8539; + GL_HALF_BIAS_NORMAL_NV = $853A; + GL_HALF_BIAS_NEGATE_NV = $853B; + GL_SIGNED_IDENTITY_NV = $853C; + GL_SIGNED_NEGATE_NV = $853D; + GL_E_TIMES_F_NV = $8531; + GL_SPARE0_PLUS_SECONDARY_COLOR_NV = $8532; + GL_SCALE_BY_TWO_NV = $853E; + GL_SCALE_BY_FOUR_NV = $853F; + GL_SCALE_BY_ONE_HALF_NV = $8540; + GL_BIAS_BY_NEGATIVE_ONE_HALF_NV = $8541; + GL_DISCARD_NV = $8530; + GL_COMBINER_INPUT_NV = $8542; + GL_COMBINER_MAPPING_NV = $8543; + GL_COMBINER_COMPONENT_USAGE_NV = $8544; + GL_COMBINER_AB_DOT_PRODUCT_NV = $8545; + GL_COMBINER_CD_DOT_PRODUCT_NV = $8546; + GL_COMBINER_MUX_SUM_NV = $8547; + GL_COMBINER_SCALE_NV = $8548; + GL_COMBINER_BIAS_NV = $8549; + GL_COMBINER_AB_OUTPUT_NV = $854A; + GL_COMBINER_CD_OUTPUT_NV = $854B; + GL_COMBINER_SUM_OUTPUT_NV = $854C; + GL_NUM_GENERAL_COMBINERS_NV = $854E; + GL_COLOR_SUM_CLAMP_NV = $854F; + GL_MAX_GENERAL_COMBINERS_NV = $854D; +var + glCombinerParameterfvNV: procedure(pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCombinerParameterivNV: procedure(pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCombinerParameterfNV: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCombinerParameteriNV: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCombinerInputNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; input: GLenum; mapping: GLenum; componentUsage: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCombinerOutputNV: procedure(stage: GLenum; portion: GLenum; abOutput: GLenum; cdOutput: GLenum; sumOutput: GLenum; scale: GLenum; bias: GLenum; abDotProduct: GLboolean; cdDotProduct: GLboolean; muxSum: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFinalCombinerInputNV: procedure(variable: GLenum; input: GLenum; mapping: GLenum; componentUsage: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCombinerInputParameterfvNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCombinerInputParameterivNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCombinerOutputParameterfvNV: procedure(stage: GLenum; portion: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCombinerOutputParameterivNV: procedure(stage: GLenum; portion: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFinalCombinerInputParameterfvNV: procedure(variable: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFinalCombinerInputParameterivNV: procedure(variable: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_register_combiners: Boolean; + +//***** GL_NV_register_combiners2 *****// +const + GL_PER_STAGE_CONSTANTS_NV = $8535; +var + glCombinerStageParameterfvNV: procedure(stage: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCombinerStageParameterfvNV: procedure(stage: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_register_combiners2: Boolean; + +//***** GL_NV_texgen_emboss *****// +const + GL_EMBOSS_MAP_NV = $855F; + GL_EMBOSS_LIGHT_NV = $855D; + GL_EMBOSS_CONSTANT_NV = $855E; + +function Load_GL_NV_texgen_emboss: Boolean; + +//***** GL_NV_texgen_reflection *****// +const + GL_NORMAL_MAP_NV = $8511; + GL_REFLECTION_MAP_NV = $8512; + +function Load_GL_NV_texgen_reflection: Boolean; + +//***** GL_NV_texture_compression_vtc *****// + // GL_COMPRESSED_RGB_S3TC_DXT1_EXT { already defined } + // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT { already defined } + // GL_COMPRESSED_RGBA_S3TC_DXT3_EXT { already defined } + // GL_COMPRESSED_RGBA_S3TC_DXT5_EXT { already defined } + +function Load_GL_NV_texture_compression_vtc: Boolean; + +//***** GL_NV_texture_env_combine4 *****// +const + GL_COMBINE4_NV = $8503; + GL_SOURCE3_RGB_NV = $8583; + GL_SOURCE3_ALPHA_NV = $858B; + GL_OPERAND3_RGB_NV = $8593; + GL_OPERAND3_ALPHA_NV = $859B; + +function Load_GL_NV_texture_env_combine4: Boolean; + +//***** GL_NV_texture_rectangle *****// +const + GL_TEXTURE_RECTANGLE_NV = $84F5; + GL_TEXTURE_BINDING_RECTANGLE_NV = $84F6; + GL_PROXY_TEXTURE_RECTANGLE_NV = $84F7; + GL_MAX_RECTANGLE_TEXTURE_SIZE_NV = $84F8; + +function Load_GL_NV_texture_rectangle: Boolean; + +//***** GL_NV_texture_shader *****// +const + GL_TEXTURE_SHADER_NV = $86DE; + GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV = $86D9; + GL_SHADER_OPERATION_NV = $86DF; + GL_CULL_MODES_NV = $86E0; + GL_OFFSET_TEXTURE_MATRIX_NV = $86E1; + GL_OFFSET_TEXTURE_SCALE_NV = $86E2; + GL_OFFSET_TEXTURE_BIAS_NV = $86E3; + GL_PREVIOUS_TEXTURE_INPUT_NV = $86E4; + GL_CONST_EYE_NV = $86E5; + GL_SHADER_CONSISTENT_NV = $86DD; + GL_PASS_THROUGH_NV = $86E6; + GL_CULL_FRAGMENT_NV = $86E7; + GL_OFFSET_TEXTURE_2D_NV = $86E8; + GL_OFFSET_TEXTURE_RECTANGLE_NV = $864C; + GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV = $864D; + GL_DEPENDENT_AR_TEXTURE_2D_NV = $86E9; + GL_DEPENDENT_GB_TEXTURE_2D_NV = $86EA; + GL_DOT_PRODUCT_NV = $86EC; + GL_DOT_PRODUCT_DEPTH_REPLACE_NV = $86ED; + GL_DOT_PRODUCT_TEXTURE_2D_NV = $86EE; + GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV = $864E; + GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV = $86F0; + GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV = $86F1; + GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV = $86F2; + GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV = $86F3; + GL_HILO_NV = $86F4; + GL_DSDT_NV = $86F5; + GL_DSDT_MAG_NV = $86F6; + GL_DSDT_MAG_VIB_NV = $86F7; + GL_UNSIGNED_INT_S8_S8_8_8_NV = $86DA; + GL_UNSIGNED_INT_8_8_S8_S8_REV_NV = $86DB; + GL_SIGNED_RGBA_NV = $86FB; + GL_SIGNED_RGBA8_NV = $86FC; + GL_SIGNED_RGB_NV = $86FE; + GL_SIGNED_RGB8_NV = $86FF; + GL_SIGNED_LUMINANCE_NV = $8701; + GL_SIGNED_LUMINANCE8_NV = $8702; + GL_SIGNED_LUMINANCE_ALPHA_NV = $8703; + GL_SIGNED_LUMINANCE8_ALPHA8_NV = $8704; + GL_SIGNED_ALPHA_NV = $8705; + GL_SIGNED_ALPHA8_NV = $8706; + GL_SIGNED_INTENSITY_NV = $8707; + GL_SIGNED_INTENSITY8_NV = $8708; + GL_SIGNED_RGB_UNSIGNED_ALPHA_NV = $870C; + GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV = $870D; + GL_HILO16_NV = $86F8; + GL_SIGNED_HILO_NV = $86F9; + GL_SIGNED_HILO16_NV = $86FA; + GL_DSDT8_NV = $8709; + GL_DSDT8_MAG8_NV = $870A; + GL_DSDT_MAG_INTENSITY_NV = $86DC; + GL_DSDT8_MAG8_INTENSITY8_NV = $870B; + GL_HI_SCALE_NV = $870E; + GL_LO_SCALE_NV = $870F; + GL_DS_SCALE_NV = $8710; + GL_DT_SCALE_NV = $8711; + GL_MAGNITUDE_SCALE_NV = $8712; + GL_VIBRANCE_SCALE_NV = $8713; + GL_HI_BIAS_NV = $8714; + GL_LO_BIAS_NV = $8715; + GL_DS_BIAS_NV = $8716; + GL_DT_BIAS_NV = $8717; + GL_MAGNITUDE_BIAS_NV = $8718; + GL_VIBRANCE_BIAS_NV = $8719; + GL_TEXTURE_BORDER_VALUES_NV = $871A; + GL_TEXTURE_HI_SIZE_NV = $871B; + GL_TEXTURE_LO_SIZE_NV = $871C; + GL_TEXTURE_DS_SIZE_NV = $871D; + GL_TEXTURE_DT_SIZE_NV = $871E; + GL_TEXTURE_MAG_SIZE_NV = $871F; + +function Load_GL_NV_texture_shader: Boolean; + +//***** GL_NV_texture_shader2 *****// +const + GL_DOT_PRODUCT_TEXTURE_3D_NV = $86EF; + // GL_HILO_NV { already defined } + // GL_DSDT_NV { already defined } + // GL_DSDT_MAG_NV { already defined } + // GL_DSDT_MAG_VIB_NV { already defined } + // GL_UNSIGNED_INT_S8_S8_8_8_NV { already defined } + // GL_UNSIGNED_INT_8_8_S8_S8_REV_NV { already defined } + // GL_SIGNED_RGBA_NV { already defined } + // GL_SIGNED_RGBA8_NV { already defined } + // GL_SIGNED_RGB_NV { already defined } + // GL_SIGNED_RGB8_NV { already defined } + // GL_SIGNED_LUMINANCE_NV { already defined } + // GL_SIGNED_LUMINANCE8_NV { already defined } + // GL_SIGNED_LUMINANCE_ALPHA_NV { already defined } + // GL_SIGNED_LUMINANCE8_ALPHA8_NV { already defined } + // GL_SIGNED_ALPHA_NV { already defined } + // GL_SIGNED_ALPHA8_NV { already defined } + // GL_SIGNED_INTENSITY_NV { already defined } + // GL_SIGNED_INTENSITY8_NV { already defined } + // GL_SIGNED_RGB_UNSIGNED_ALPHA_NV { already defined } + // GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV { already defined } + // GL_HILO16_NV { already defined } + // GL_SIGNED_HILO_NV { already defined } + // GL_SIGNED_HILO16_NV { already defined } + // GL_DSDT8_NV { already defined } + // GL_DSDT8_MAG8_NV { already defined } + // GL_DSDT_MAG_INTENSITY_NV { already defined } + // GL_DSDT8_MAG8_INTENSITY8_NV { already defined } + +function Load_GL_NV_texture_shader2: Boolean; + +//***** GL_NV_texture_shader3 *****// +const + GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV = $8850; + GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV = $8851; + GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV = $8852; + GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV = $8853; + GL_OFFSET_HILO_TEXTURE_2D_NV = $8854; + GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV = $8855; + GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV = $8856; + GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV = $8857; + GL_DEPENDENT_HILO_TEXTURE_2D_NV = $8858; + GL_DEPENDENT_RGB_TEXTURE_3D_NV = $8859; + GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV = $885A; + GL_DOT_PRODUCT_PASS_THROUGH_NV = $885B; + GL_DOT_PRODUCT_TEXTURE_1D_NV = $885C; + GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV = $885D; + GL_HILO8_NV = $885E; + GL_SIGNED_HILO8_NV = $885F; + GL_FORCE_BLUE_TO_ONE_NV = $8860; + +function Load_GL_NV_texture_shader3: Boolean; + +//***** GL_NV_vertex_array_range *****// +const + GL_VERTEX_ARRAY_RANGE_NV = $851D; + GL_VERTEX_ARRAY_RANGE_LENGTH_NV = $851E; + GL_VERTEX_ARRAY_RANGE_VALID_NV = $851F; + GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV = $8520; + GL_VERTEX_ARRAY_RANGE_POINTER_NV = $8521; +var + glVertexArrayRangeNV: procedure(length: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFlushVertexArrayRangeNV: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$IFDEF msWindows} + wglAllocateMemoryNV: function(size: GLsizei; readFrequency: GLfloat; writeFrequency: GLfloat; priority: GLfloat): PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglFreeMemoryNV: procedure(pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ENDIF} + +function Load_GL_NV_vertex_array_range: Boolean; + +//***** GL_NV_vertex_array_range2 *****// +const + GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV = $8533; + +function Load_GL_NV_vertex_array_range2: Boolean; + +//***** GL_NV_vertex_program *****// +const + GL_VERTEX_PROGRAM_NV = $8620; + GL_VERTEX_PROGRAM_POINT_SIZE_NV = $8642; + GL_VERTEX_PROGRAM_TWO_SIDE_NV = $8643; + GL_VERTEX_STATE_PROGRAM_NV = $8621; + GL_ATTRIB_ARRAY_SIZE_NV = $8623; + GL_ATTRIB_ARRAY_STRIDE_NV = $8624; + GL_ATTRIB_ARRAY_TYPE_NV = $8625; + GL_CURRENT_ATTRIB_NV = $8626; + GL_PROGRAM_PARAMETER_NV = $8644; + GL_ATTRIB_ARRAY_POINTER_NV = $8645; + GL_PROGRAM_TARGET_NV = $8646; + GL_PROGRAM_LENGTH_NV = $8627; + GL_PROGRAM_RESIDENT_NV = $8647; + GL_PROGRAM_STRING_NV = $8628; + GL_TRACK_MATRIX_NV = $8648; + GL_TRACK_MATRIX_TRANSFORM_NV = $8649; + GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV = $862E; + GL_MAX_TRACK_MATRICES_NV = $862F; + GL_CURRENT_MATRIX_STACK_DEPTH_NV = $8640; + GL_CURRENT_MATRIX_NV = $8641; + GL_VERTEX_PROGRAM_BINDING_NV = $864A; + GL_PROGRAM_ERROR_POSITION_NV = $864B; + GL_MODELVIEW_PROJECTION_NV = $8629; + GL_MATRIX0_NV = $8630; + GL_MATRIX1_NV = $8631; + GL_MATRIX2_NV = $8632; + GL_MATRIX3_NV = $8633; + GL_MATRIX4_NV = $8634; + GL_MATRIX5_NV = $8635; + GL_MATRIX6_NV = $8636; + GL_MATRIX7_NV = $8637; + GL_IDENTITY_NV = $862A; + GL_INVERSE_NV = $862B; + GL_TRANSPOSE_NV = $862C; + GL_INVERSE_TRANSPOSE_NV = $862D; + GL_VERTEX_ATTRIB_ARRAY0_NV = $8650; + GL_VERTEX_ATTRIB_ARRAY1_NV = $8651; + GL_VERTEX_ATTRIB_ARRAY2_NV = $8652; + GL_VERTEX_ATTRIB_ARRAY3_NV = $8653; + GL_VERTEX_ATTRIB_ARRAY4_NV = $8654; + GL_VERTEX_ATTRIB_ARRAY5_NV = $8655; + GL_VERTEX_ATTRIB_ARRAY6_NV = $8656; + GL_VERTEX_ATTRIB_ARRAY7_NV = $8657; + GL_VERTEX_ATTRIB_ARRAY8_NV = $8658; + GL_VERTEX_ATTRIB_ARRAY9_NV = $8659; + GL_VERTEX_ATTRIB_ARRAY10_NV = $865A; + GL_VERTEX_ATTRIB_ARRAY11_NV = $865B; + GL_VERTEX_ATTRIB_ARRAY12_NV = $865C; + GL_VERTEX_ATTRIB_ARRAY13_NV = $865D; + GL_VERTEX_ATTRIB_ARRAY14_NV = $865E; + GL_VERTEX_ATTRIB_ARRAY15_NV = $865F; + GL_MAP1_VERTEX_ATTRIB0_4_NV = $8660; + GL_MAP1_VERTEX_ATTRIB1_4_NV = $8661; + GL_MAP1_VERTEX_ATTRIB2_4_NV = $8662; + GL_MAP1_VERTEX_ATTRIB3_4_NV = $8663; + GL_MAP1_VERTEX_ATTRIB4_4_NV = $8664; + GL_MAP1_VERTEX_ATTRIB5_4_NV = $8665; + GL_MAP1_VERTEX_ATTRIB6_4_NV = $8666; + GL_MAP1_VERTEX_ATTRIB7_4_NV = $8667; + GL_MAP1_VERTEX_ATTRIB8_4_NV = $8668; + GL_MAP1_VERTEX_ATTRIB9_4_NV = $8669; + GL_MAP1_VERTEX_ATTRIB10_4_NV = $866A; + GL_MAP1_VERTEX_ATTRIB11_4_NV = $866B; + GL_MAP1_VERTEX_ATTRIB12_4_NV = $866C; + GL_MAP1_VERTEX_ATTRIB13_4_NV = $866D; + GL_MAP1_VERTEX_ATTRIB14_4_NV = $866E; + GL_MAP1_VERTEX_ATTRIB15_4_NV = $866F; + GL_MAP2_VERTEX_ATTRIB0_4_NV = $8670; + GL_MAP2_VERTEX_ATTRIB1_4_NV = $8671; + GL_MAP2_VERTEX_ATTRIB2_4_NV = $8672; + GL_MAP2_VERTEX_ATTRIB3_4_NV = $8673; + GL_MAP2_VERTEX_ATTRIB4_4_NV = $8674; + GL_MAP2_VERTEX_ATTRIB5_4_NV = $8675; + GL_MAP2_VERTEX_ATTRIB6_4_NV = $8676; + GL_MAP2_VERTEX_ATTRIB7_4_NV = $8677; + GL_MAP2_VERTEX_ATTRIB8_4_NV = $8678; + GL_MAP2_VERTEX_ATTRIB9_4_NV = $8679; + GL_MAP2_VERTEX_ATTRIB10_4_NV = $867A; + GL_MAP2_VERTEX_ATTRIB11_4_NV = $867B; + GL_MAP2_VERTEX_ATTRIB12_4_NV = $867C; + GL_MAP2_VERTEX_ATTRIB13_4_NV = $867D; + GL_MAP2_VERTEX_ATTRIB14_4_NV = $867E; + GL_MAP2_VERTEX_ATTRIB15_4_NV = $867F; +var + glBindProgramNV: procedure(target: GLenum; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteProgramsNV: procedure(n: GLsizei; const ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glExecuteProgramNV: procedure(target: GLenum; id: GLuint; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenProgramsNV: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAreProgramsResidentNV: function(n: GLsizei; const ids: PGLuint; residences: PGLboolean): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRequestResidentProgramsNV: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramParameterfvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramParameterdvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramivNV: procedure(id: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramStringNV: procedure(id: GLuint; pname: GLenum; _program: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTrackMatrixivNV: procedure(target: GLenum; address: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribdvNV: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribfvNV: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribivNV: procedure(index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribPointervNV: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsProgramNV: function(id: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadProgramNV: procedure(target: GLenum; id: GLuint; len: GLsizei; const _program: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramParameter4fNV: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramParameter4fvNV: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramParameters4dvNV: procedure(target: GLenum; index: GLuint; num: GLuint; const params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramParameters4fvNV: procedure(target: GLenum; index: GLuint; num: GLuint; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTrackMatrixNV: procedure(target: GLenum; address: GLuint; matrix: GLenum; transform: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribPointerNV: procedure(index: GLuint; size: GLint; _type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1sNV: procedure(index: GLuint; x: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1fNV: procedure(index: GLuint; x: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1dNV: procedure(index: GLuint; x: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2sNV: procedure(index: GLuint; x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3sNV: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4sNV: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4ubNV: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1svNV: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1fvNV: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1dvNV: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2svNV: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2fvNV: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2dvNV: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3svNV: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3fvNV: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3dvNV: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4svNV: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4fvNV: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4dvNV: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4ubvNV: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs1svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs1fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs1dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs2svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs2fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs2dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs3svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs3fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs3dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs4svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs4fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs4dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs4ubvNV: procedure(index: GLuint; n: GLsizei; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_vertex_program: Boolean; + +//***** GL_NV_vertex_program1_1 *****// + +function Load_GL_NV_vertex_program1_1: Boolean; + +//***** GL_ATI_element_array *****// +const + GL_ELEMENT_ARRAY_ATI = $8768; + GL_ELEMENT_ARRAY_TYPE_ATI = $8769; + GL_ELEMENT_ARRAY_POINTER_ATI = $876A; +var + glElementPointerATI: procedure(_type: GLenum; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElementArrayATI: procedure(mode: GLenum; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawRangeElementArrayATI: procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_element_array: Boolean; + +//***** GL_ATI_envmap_bumpmap *****// +const + GL_BUMP_ROT_MATRIX_ATI = $8775; + GL_BUMP_ROT_MATRIX_SIZE_ATI = $8776; + GL_BUMP_NUM_TEX_UNITS_ATI = $8777; + GL_BUMP_TEX_UNITS_ATI = $8778; + GL_DUDV_ATI = $8779; + GL_DU8DV8_ATI = $877A; + GL_BUMP_ENVMAP_ATI = $877B; + GL_BUMP_TARGET_ATI = $877C; +var + glTexBumpParameterivATI: procedure(pname: GLenum; param: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexBumpParameterfvATI: procedure(pname: GLenum; param: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexBumpParameterivATI: procedure(pname: GLenum; param: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexBumpParameterfvATI: procedure(pname: GLenum; param: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_envmap_bumpmap: Boolean; + +//***** GL_ATI_fragment_shader *****// +const + GL_FRAGMENT_SHADER_ATI = $8920; + GL_REG_0_ATI = $8921; + GL_REG_1_ATI = $8922; + GL_REG_2_ATI = $8923; + GL_REG_3_ATI = $8924; + GL_REG_4_ATI = $8925; + GL_REG_5_ATI = $8926; + GL_CON_0_ATI = $8941; + GL_CON_1_ATI = $8942; + GL_CON_2_ATI = $8943; + GL_CON_3_ATI = $8944; + GL_CON_4_ATI = $8945; + GL_CON_5_ATI = $8946; + GL_CON_6_ATI = $8947; + GL_CON_7_ATI = $8948; + GL_MOV_ATI = $8961; + GL_ADD_ATI = $8963; + GL_MUL_ATI = $8964; + GL_SUB_ATI = $8965; + GL_DOT3_ATI = $8966; + GL_DOT4_ATI = $8967; + GL_MAD_ATI = $8968; + GL_LERP_ATI = $8969; + GL_CND_ATI = $896A; + GL_CND0_ATI = $896B; + GL_DOT2_ADD_ATI = $896C; + GL_SECONDARY_INTERPOLATOR_ATI = $896D; + GL_SWIZZLE_STR_ATI = $8976; + GL_SWIZZLE_STQ_ATI = $8977; + GL_SWIZZLE_STR_DR_ATI = $8978; + GL_SWIZZLE_STQ_DQ_ATI = $8979; + GL_RED_BIT_ATI = $0001; + GL_GREEN_BIT_ATI = $0002; + GL_BLUE_BIT_ATI = $0004; + GL_2X_BIT_ATI = $0001; + GL_4X_BIT_ATI = $0002; + GL_8X_BIT_ATI = $0004; + GL_HALF_BIT_ATI = $0008; + GL_QUARTER_BIT_ATI = $0010; + GL_EIGHTH_BIT_ATI = $0020; + GL_SATURATE_BIT_ATI = $0040; + // GL_2X_BIT_ATI { already defined } + GL_COMP_BIT_ATI = $0002; + GL_NEGATE_BIT_ATI = $0004; + GL_BIAS_BIT_ATI = $0008; +var + glGenFragmentShadersATI: function(range: GLuint): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindFragmentShaderATI: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteFragmentShaderATI: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginFragmentShaderATI: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndFragmentShaderATI: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPassTexCoordATI: procedure(dst: GLuint; coord: GLuint; swizzle: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSampleMapATI: procedure(dst: GLuint; interp: GLuint; swizzle: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorFragmentOp1ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorFragmentOp2ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorFragmentOp3ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint; arg3: GLuint; arg3Rep: GLuint; arg3Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAlphaFragmentOp1ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAlphaFragmentOp2ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAlphaFragmentOp3ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint; arg3: GLuint; arg3Rep: GLuint; arg3Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSetFragmentShaderConstantATI: procedure(dst: GLuint; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_fragment_shader: Boolean; + +//***** GL_ATI_pn_triangles *****// +const + GL_PN_TRIANGLES_ATI = $87F0; + GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI = $87F1; + GL_PN_TRIANGLES_POINT_MODE_ATI = $87F2; + GL_PN_TRIANGLES_NORMAL_MODE_ATI = $87F3; + GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI = $87F4; + GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI = $87F5; + GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI = $87F6; + GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI = $87F7; + GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI = $87F8; +var + glPNTrianglesiATI: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPNTrianglesfATI: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_pn_triangles: Boolean; + +//***** GL_ATI_texture_mirror_once *****// +const + GL_MIRROR_CLAMP_ATI = $8742; + GL_MIRROR_CLAMP_TO_EDGE_ATI = $8743; + +function Load_GL_ATI_texture_mirror_once: Boolean; + +//***** GL_ATI_vertex_array_object *****// +const + GL_STATIC_ATI = $8760; + GL_DYNAMIC_ATI = $8761; + GL_PRESERVE_ATI = $8762; + GL_DISCARD_ATI = $8763; + GL_OBJECT_BUFFER_SIZE_ATI = $8764; + GL_OBJECT_BUFFER_USAGE_ATI = $8765; + GL_ARRAY_OBJECT_BUFFER_ATI = $8766; + GL_ARRAY_OBJECT_OFFSET_ATI = $8767; +var + glNewObjectBufferATI: function(size: GLsizei; const pointer: PGLvoid; usage: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsObjectBufferATI: function(buffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUpdateObjectBufferATI: procedure(buffer: GLuint; offset: GLuint; size: GLsizei; const pointer: PGLvoid; preserve: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetObjectBufferfvATI: procedure(buffer: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetObjectBufferivATI: procedure(buffer: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteObjectBufferATI: procedure(buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glArrayObjectATI: procedure(_array: GLenum; size: GLint; _type: GLenum; stride: GLsizei; buffer: GLuint; offset: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetArrayObjectfvATI: procedure(_array: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetArrayObjectivATI: procedure(_array: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantArrayObjectATI: procedure(id: GLuint; _type: GLenum; stride: GLsizei; buffer: GLuint; offset: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantArrayObjectfvATI: procedure(id: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantArrayObjectivATI: procedure(id: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_vertex_array_object: Boolean; + +//***** GL_ATI_vertex_streams *****// +const + GL_MAX_VERTEX_STREAMS_ATI = $876B; + GL_VERTEX_STREAM0_ATI = $876C; + GL_VERTEX_STREAM1_ATI = $876D; + GL_VERTEX_STREAM2_ATI = $876E; + GL_VERTEX_STREAM3_ATI = $876F; + GL_VERTEX_STREAM4_ATI = $8770; + GL_VERTEX_STREAM5_ATI = $8771; + GL_VERTEX_STREAM6_ATI = $8772; + GL_VERTEX_STREAM7_ATI = $8773; + GL_VERTEX_SOURCE_ATI = $8774; +var + glVertexStream1s: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1i: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1f: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1d: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1sv: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1iv: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1fv: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1dv: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2s: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2i: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2f: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2d: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2sv: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2iv: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2fv: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2dv: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3s: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3i: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3f: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3d: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3sv: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3iv: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3fv: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3dv: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4s: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4i: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4f: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4d: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4sv: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4iv: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4fv: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4dv: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3b: procedure(stream: GLenum; coords: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3s: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3i: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3f: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3d: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3bv: procedure(stream: GLenum; coords: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3sv: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3iv: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3fv: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3dv: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClientActiveVertexStream: procedure(stream: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexBlendEnvi: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexBlendEnvf: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_vertex_streams: Boolean; + +{$IFDEF msWindows} +//***** WGL_I3D_image_buffer *****// +const + WGL_IMAGE_BUFFER_MIN_ACCESS_I3D = $0001; + WGL_IMAGE_BUFFER_LOCK_I3D = $0002; +var + wglCreateImageBufferI3D: function(hDC: HDC; dwSize: DWORD; uFlags: UINT): PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDestroyImageBufferI3D: function(hDC: HDC; pAddress: PGLvoid): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglAssociateImageBufferEventsI3D: function(hdc: HDC; pEvent: PHandle; pAddress: PGLvoid; pSize: PDWORD; count: UINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglReleaseImageBufferEventsI3D: function(hdc: HDC; pAddress: PGLvoid; count: UINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_image_buffer: Boolean; + +//***** WGL_I3D_swap_frame_lock *****// +var + wglEnableFrameLockI3D: function(): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDisableFrameLockI3D: function(): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglIsEnabledFrameLockI3D: function(pFlag: PBOOL): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglQueryFrameLockMasterI3D: function(pFlag: PBOOL): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_swap_frame_lock: Boolean; + +//***** WGL_I3D_swap_frame_usage *****// +var + wglGetFrameUsageI3D: function(pUsage: PGLfloat): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglBeginFrameTrackingI3D: function(): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglEndFrameTrackingI3D: function(): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglQueryFrameTrackingI3D: function(pFrameCount: PDWORD; pMissedFrames: PDWORD; pLastMissedUsage: PGLfloat): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_swap_frame_usage: Boolean; +{$ENDIF} + +//***** GL_3DFX_texture_compression_FXT1 *****// +const + GL_COMPRESSED_RGB_FXT1_3DFX = $86B0; + GL_COMPRESSED_RGBA_FXT1_3DFX = $86B1; + +function Load_GL_3DFX_texture_compression_FXT1: Boolean; + +//***** GL_IBM_cull_vertex *****// +const + GL_CULL_VERTEX_IBM = $1928A; + +function Load_GL_IBM_cull_vertex: Boolean; + +//***** GL_IBM_multimode_draw_arrays *****// +var + glMultiModeDrawArraysIBM: procedure(mode: PGLenum; first: PGLint; count: PGLsizei; primcount: GLsizei; modestride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiModeDrawElementsIBM: procedure(mode: PGLenum; count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei; modestride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_IBM_multimode_draw_arrays: Boolean; + +//***** GL_IBM_raster_pos_clip *****// +const + GL_RASTER_POSITION_UNCLIPPED_IBM = $19262; + +function Load_GL_IBM_raster_pos_clip: Boolean; + +//***** GL_IBM_texture_mirrored_repeat *****// +const + GL_MIRRORED_REPEAT_IBM = $8370; + +function Load_GL_IBM_texture_mirrored_repeat: Boolean; + +//***** GL_IBM_vertex_array_lists *****// +const + GL_VERTEX_ARRAY_LIST_IBM = $1929E; + GL_NORMAL_ARRAY_LIST_IBM = $1929F; + GL_COLOR_ARRAY_LIST_IBM = $192A0; + GL_INDEX_ARRAY_LIST_IBM = $192A1; + GL_TEXTURE_COORD_ARRAY_LIST_IBM = $192A2; + GL_EDGE_FLAG_ARRAY_LIST_IBM = $192A3; + GL_FOG_COORDINATE_ARRAY_LIST_IBM = $192A4; + GL_SECONDARY_COLOR_ARRAY_LIST_IBM = $192A5; + GL_VERTEX_ARRAY_LIST_STRIDE_IBM = $192A8; + GL_NORMAL_ARRAY_LIST_STRIDE_IBM = $192A9; + GL_COLOR_ARRAY_LIST_STRIDE_IBM = $192AA; + GL_INDEX_ARRAY_LIST_STRIDE_IBM = $192AB; + GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM = $192AC; + GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM = $192AD; + GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM = $192AE; + GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM = $192AF; +var + glColorPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColorPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEdgeFlagPointerListIBM: procedure(stride: GLint; const pointer: PGLboolean; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordPointerListIBM: procedure(_type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalPointerListIBM: procedure(_type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_IBM_vertex_array_lists: Boolean; + +//***** GL_MESA_resize_buffers *****// +var + glResizeBuffersMESA: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_MESA_resize_buffers: Boolean; + +//***** GL_MESA_window_pos *****// +var + glWindowPos2dMESA: procedure(x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2fMESA: procedure(x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2iMESA: procedure(x: GLint; y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2sMESA: procedure(x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2ivMESA: procedure(const p: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2svMESA: procedure(const p: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2fvMESA: procedure(const p: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2dvMESA: procedure(const p: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3iMESA: procedure(x: GLint; y: GLint; z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3sMESA: procedure(x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3fMESA: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3dMESA: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3ivMESA: procedure(const p: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3svMESA: procedure(const p: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3fvMESA: procedure(const p: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3dvMESA: procedure(const p: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4iMESA: procedure(x: GLint; y: GLint; z: GLint; w: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4sMESA: procedure(x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4fMESA: procedure(x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4dMESA: procedure(x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4ivMESA: procedure(const p: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4svMESA: procedure(const p: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4fvMESA: procedure(const p: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4dvMESA: procedure(const p: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_MESA_window_pos: Boolean; + +//***** GL_OML_interlace *****// +const + GL_INTERLACE_OML = $8980; + GL_INTERLACE_READ_OML = $8981; + +function Load_GL_OML_interlace: Boolean; + +//***** GL_OML_resample *****// +const + GL_PACK_RESAMPLE_OML = $8984; + GL_UNPACK_RESAMPLE_OML = $8985; + GL_RESAMPLE_REPLICATE_OML = $8986; + GL_RESAMPLE_ZERO_FILL_OML = $8987; + GL_RESAMPLE_AVERAGE_OML = $8988; + GL_RESAMPLE_DECIMATE_OML = $8989; + // GL_RESAMPLE_AVERAGE_OML { already defined } + +function Load_GL_OML_resample: Boolean; + +//***** GL_OML_subsample *****// +const + GL_FORMAT_SUBSAMPLE_24_24_OML = $8982; + GL_FORMAT_SUBSAMPLE_244_244_OML = $8983; + +function Load_GL_OML_subsample: Boolean; + +//***** GL_SGIS_generate_mipmap *****// +const + GL_GENERATE_MIPMAP_SGIS = $8191; + GL_GENERATE_MIPMAP_HINT_SGIS = $8192; + +function Load_GL_SGIS_generate_mipmap: Boolean; + +//***** GL_SGIS_multisample *****// +const + GLX_SAMPLE_BUFFERS_SGIS = $186A0; + GLX_SAMPLES_SGIS = $186A1; + GL_MULTISAMPLE_SGIS = $809D; + GL_SAMPLE_ALPHA_TO_MASK_SGIS = $809E; + GL_SAMPLE_ALPHA_TO_ONE_SGIS = $809F; + GL_SAMPLE_MASK_SGIS = $80A0; + GL_MULTISAMPLE_BIT_EXT = $20000000; + GL_1PASS_SGIS = $80A1; + GL_2PASS_0_SGIS = $80A2; + GL_2PASS_1_SGIS = $80A3; + GL_4PASS_0_SGIS = $80A4; + GL_4PASS_1_SGIS = $80A5; + GL_4PASS_2_SGIS = $80A6; + GL_4PASS_3_SGIS = $80A7; + GL_SAMPLE_BUFFERS_SGIS = $80A8; + GL_SAMPLES_SGIS = $80A9; + GL_SAMPLE_MASK_VALUE_SGIS = $80AA; + GL_SAMPLE_MASK_INVERT_SGIS = $80AB; + GL_SAMPLE_PATTERN_SGIS = $80AC; +var + glSampleMaskSGIS: procedure(value: GLclampf; invert: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplePatternSGIS: procedure(pattern: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_SGIS_multisample: Boolean; + +//***** GL_SGIS_pixel_texture *****// +const + GL_PIXEL_TEXTURE_SGIS = $8353; + GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS = $8354; + GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS = $8355; + GL_PIXEL_GROUP_COLOR_SGIS = $8356; +var + glPixelTexGenParameteriSGIS: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelTexGenParameterfSGIS: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPixelTexGenParameterivSGIS: procedure(pname: GLenum; params: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPixelTexGenParameterfvSGIS: procedure(pname: GLenum; params: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_SGIS_pixel_texture: Boolean; + +//***** GL_SGIS_texture_border_clamp *****// + // GL_CLAMP_TO_BORDER_SGIS { already defined } + +function Load_GL_SGIS_texture_border_clamp: Boolean; + +//***** GL_SGIS_texture_color_mask *****// +const + GL_TEXTURE_COLOR_WRITEMASK_SGIS = $81EF; +var + glTextureColorMaskSGIS: procedure(r: GLboolean; g: GLboolean; b: GLboolean; a: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_SGIS_texture_color_mask: Boolean; + +//***** GL_SGIS_texture_edge_clamp *****// +const + GL_CLAMP_TO_EDGE_SGIS = $812F; + +function Load_GL_SGIS_texture_edge_clamp: Boolean; + +//***** GL_SGIS_texture_lod *****// +const + GL_TEXTURE_MIN_LOD_SGIS = $813A; + GL_TEXTURE_MAX_LOD_SGIS = $813B; + GL_TEXTURE_BASE_LEVEL_SGIS = $813C; + GL_TEXTURE_MAX_LEVEL_SGIS = $813D; + +function Load_GL_SGIS_texture_lod: Boolean; + +//***** GL_SGIS_depth_texture *****// +const + GL_DEPTH_COMPONENT16_SGIX = $81A5; + GL_DEPTH_COMPONENT24_SGIX = $81A6; + GL_DEPTH_COMPONENT32_SGIX = $81A7; + +function Load_GL_SGIS_depth_texture: Boolean; + +//***** GL_SGIX_fog_offset *****// +const + GL_FOG_OFFSET_SGIX = $8198; + GL_FOG_OFFSET_VALUE_SGIX = $8199; + +function Load_GL_SGIX_fog_offset: Boolean; + +//***** GL_SGIX_interlace *****// +const + GL_INTERLACE_SGIX = $8094; + +function Load_GL_SGIX_interlace: Boolean; + +//***** GL_SGIX_shadow_ambient *****// +const + GL_SHADOW_AMBIENT_SGIX = $80BF; + +function Load_GL_SGIX_shadow_ambient: Boolean; + +//***** GL_SGI_color_matrix *****// +const + GL_COLOR_MATRIX_SGI = $80B1; + GL_COLOR_MATRIX_STACK_DEPTH_SGI = $80B2; + GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI = $80B3; + GL_POST_COLOR_MATRIX_RED_SCALE_SGI = $80B4; + GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI = $80B5; + GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI = $80B6; + GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI = $80B7; + GL_POST_COLOR_MATRIX_RED_BIAS_SGI = $80B8; + GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI = $80B9; + GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI = $80BA; + GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI = $80BB; + +function Load_GL_SGI_color_matrix: Boolean; + +//***** GL_SGI_color_table *****// +const + GL_COLOR_TABLE_SGI = $80D0; + GL_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D1; + GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D2; + GL_PROXY_COLOR_TABLE_SGI = $80D3; + GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D4; + GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D5; + GL_COLOR_TABLE_SCALE_SGI = $80D6; + GL_COLOR_TABLE_BIAS_SGI = $80D7; + GL_COLOR_TABLE_FORMAT_SGI = $80D8; + GL_COLOR_TABLE_WIDTH_SGI = $80D9; + GL_COLOR_TABLE_RED_SIZE_SGI = $80DA; + GL_COLOR_TABLE_GREEN_SIZE_SGI = $80DB; + GL_COLOR_TABLE_BLUE_SIZE_SGI = $80DC; + GL_COLOR_TABLE_ALPHA_SIZE_SGI = $80DD; + GL_COLOR_TABLE_LUMINANCE_SIZE_SGI = $80DE; + GL_COLOR_TABLE_INTENSITY_SIZE_SGI = $80DF; +var + glColorTableSGI: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const table: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyColorTableSGI: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorTableParameterivSGI: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorTableParameterfvSGI: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableSGI: procedure(target: GLenum; format: GLenum; _type: GLenum; table: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameterivSGI: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameterfvSGI: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_SGI_color_table: Boolean; + +//***** GL_SGI_texture_color_table *****// +const + GL_TEXTURE_COLOR_TABLE_SGI = $80BC; + GL_PROXY_TEXTURE_COLOR_TABLE_SGI = $80BD; + +function Load_GL_SGI_texture_color_table: Boolean; + +//***** GL_SUN_vertex *****// +var + glColor4ubVertex2fSUN: procedure(r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ubVertex2fvSUN: procedure(const c: PGLubyte; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ubVertex3fSUN: procedure(r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ubVertex3fvSUN: procedure(const c: PGLubyte; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3fVertex3fSUN: procedure(r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3fVertex3fvSUN: procedure(const c: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3fVertex3fSUN: procedure(nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3fVertex3fvSUN: procedure(const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4fNormal3fVertex3fSUN: procedure(r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4fNormal3fVertex3fvSUN: procedure(const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fVertex3fvSUN: procedure(const tc: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4fVertex4fSUN: procedure(s: GLfloat; t: GLfloat; p: GLfloat; q: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4fVertex4fvSUN: procedure(const tc: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor4ubVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor4ubVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLubyte; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor3fVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fNormal3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fNormal3fVertex3fvSUN: procedure(const tc: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor4fNormal3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor4fNormal3fVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4fColor4fNormal3fVertex4fSUN: procedure(s: GLfloat; t: GLfloat; p: GLfloat; q: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4fColor4fNormal3fVertex4fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiVertex3fSUN: procedure(rc: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiVertex3fvSUN: procedure(const rc: PGLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor4ubVertex3fSUN: procedure(rc: GLuint; r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor4ubVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLubyte; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor3fVertex3fSUN: procedure(rc: GLuint; r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor3fVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiNormal3fVertex3fSUN: procedure(rc: GLuint; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor4fNormal3fVertex3fSUN: procedure(rc: GLuint; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor4fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_SUN_vertex: Boolean; + +//***** GL_ARB_fragment_program *****// +const + GL_FRAGMENT_PROGRAM_ARB = $8804; + // GL_PROGRAM_FORMAT_ASCII_ARB { already defined } + // GL_PROGRAM_LENGTH_ARB { already defined } + // GL_PROGRAM_FORMAT_ARB { already defined } + // GL_PROGRAM_BINDING_ARB { already defined } + // GL_PROGRAM_INSTRUCTIONS_ARB { already defined } + // GL_MAX_PROGRAM_INSTRUCTIONS_ARB { already defined } + // GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB { already defined } + // GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB { already defined } + // GL_PROGRAM_TEMPORARIES_ARB { already defined } + // GL_MAX_PROGRAM_TEMPORARIES_ARB { already defined } + // GL_PROGRAM_NATIVE_TEMPORARIES_ARB { already defined } + // GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB { already defined } + // GL_PROGRAM_PARAMETERS_ARB { already defined } + // GL_MAX_PROGRAM_PARAMETERS_ARB { already defined } + // GL_PROGRAM_NATIVE_PARAMETERS_ARB { already defined } + // GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB { already defined } + // GL_PROGRAM_ATTRIBS_ARB { already defined } + // GL_MAX_PROGRAM_ATTRIBS_ARB { already defined } + // GL_PROGRAM_NATIVE_ATTRIBS_ARB { already defined } + // GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB { already defined } + // GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB { already defined } + // GL_MAX_PROGRAM_ENV_PARAMETERS_ARB { already defined } + // GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB { already defined } + GL_PROGRAM_ALU_INSTRUCTIONS_ARB = $8805; + GL_PROGRAM_TEX_INSTRUCTIONS_ARB = $8806; + GL_PROGRAM_TEX_INDIRECTIONS_ARB = $8807; + GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = $8808; + GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = $8809; + GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = $880A; + GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB = $880B; + GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB = $880C; + GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB = $880D; + GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = $880E; + GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = $880F; + GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = $8810; + // GL_PROGRAM_STRING_ARB { already defined } + // GL_PROGRAM_ERROR_POSITION_ARB { already defined } + // GL_CURRENT_MATRIX_ARB { already defined } + // GL_TRANSPOSE_CURRENT_MATRIX_ARB { already defined } + // GL_CURRENT_MATRIX_STACK_DEPTH_ARB { already defined } + // GL_MAX_PROGRAM_MATRICES_ARB { already defined } + // GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB { already defined } + GL_MAX_TEXTURE_COORDS_ARB = $8871; + GL_MAX_TEXTURE_IMAGE_UNITS_ARB = $8872; + // GL_PROGRAM_ERROR_STRING_ARB { already defined } + // GL_MATRIX0_ARB { already defined } + // GL_MATRIX1_ARB { already defined } + // GL_MATRIX2_ARB { already defined } + // GL_MATRIX3_ARB { already defined } + // GL_MATRIX4_ARB { already defined } + // GL_MATRIX5_ARB { already defined } + // GL_MATRIX6_ARB { already defined } + // GL_MATRIX7_ARB { already defined } + // GL_MATRIX8_ARB { already defined } + // GL_MATRIX9_ARB { already defined } + // GL_MATRIX10_ARB { already defined } + // GL_MATRIX11_ARB { already defined } + // GL_MATRIX12_ARB { already defined } + // GL_MATRIX13_ARB { already defined } + // GL_MATRIX14_ARB { already defined } + // GL_MATRIX15_ARB { already defined } + // GL_MATRIX16_ARB { already defined } + // GL_MATRIX17_ARB { already defined } + // GL_MATRIX18_ARB { already defined } + // GL_MATRIX19_ARB { already defined } + // GL_MATRIX20_ARB { already defined } + // GL_MATRIX21_ARB { already defined } + // GL_MATRIX22_ARB { already defined } + // GL_MATRIX23_ARB { already defined } + // GL_MATRIX24_ARB { already defined } + // GL_MATRIX25_ARB { already defined } + // GL_MATRIX26_ARB { already defined } + // GL_MATRIX27_ARB { already defined } + // GL_MATRIX28_ARB { already defined } + // GL_MATRIX29_ARB { already defined } + // GL_MATRIX30_ARB { already defined } + // GL_MATRIX31_ARB { already defined } + // glProgramStringARB { already defined } + // glBindProgramARB { already defined } + // glDeleteProgramsARB { already defined } + // glGenProgramsARB { already defined } + // glProgramEnvParameter4dARB { already defined } + // glProgramEnvParameter4dvARB { already defined } + // glProgramEnvParameter4fARB { already defined } + // glProgramEnvParameter4fvARB { already defined } + // glProgramLocalParameter4dARB { already defined } + // glProgramLocalParameter4dvARB { already defined } + // glProgramLocalParameter4fARB { already defined } + // glProgramLocalParameter4fvARB { already defined } + // glGetProgramEnvParameterdvARB { already defined } + // glGetProgramEnvParameterfvARB { already defined } + // glGetProgramLocalParameterdvARB { already defined } + // glGetProgramLocalParameterfvARB { already defined } + // glGetProgramivARB { already defined } + // glGetProgramStringARB { already defined } + // glIsProgramARB { already defined } + +function Load_GL_ARB_fragment_program: Boolean; + +{***** GL_ATI_text_fragment_shader *****} +const + GL_TEXT_FRAGMENT_SHADER_ATI = $8200; + +function Load_GL_ATI_text_fragment_shader: Boolean; + +{***** GL_ARB_vertex_buffer_object *****} +const + GL_BUFFER_SIZE_ARB = $8764; + GL_BUFFER_USAGE_ARB = $8765; + GL_ARRAY_BUFFER_ARB = $8892; + GL_ELEMENT_ARRAY_BUFFER_ARB = $8893; + GL_ARRAY_BUFFER_BINDING_ARB = $8894; + GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB = $8895; + GL_VERTEX_ARRAY_BUFFER_BINDING_ARB = $8896; + GL_NORMAL_ARRAY_BUFFER_BINDING_ARB = $8897; + GL_COLOR_ARRAY_BUFFER_BINDING_ARB = $8898; + GL_INDEX_ARRAY_BUFFER_BINDING_ARB = $8899; + GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB = $889A; + GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB = $889B; + GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB = $889C; + GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB = $889D; + GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB = $889E; + GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB = $889F; + GL_READ_ONLY_ARB = $88B8; + GL_WRITE_ONLY_ARB = $88B9; + GL_READ_WRITE_ARB = $88BA; + GL_BUFFER_ACCESS_ARB = $88BB; + GL_BUFFER_MAPPED_ARB = $88BC; + GL_BUFFER_MAP_POINTER_ARB = $88BD; + GL_STREAM_DRAW_ARB = $88E0; + GL_STREAM_READ_ARB = $88E1; + GL_STREAM_COPY_ARB = $88E2; + GL_STATIC_DRAW_ARB = $88E4; + GL_STATIC_READ_ARB = $88E5; + GL_STATIC_COPY_ARB = $88E6; + GL_DYNAMIC_DRAW_ARB = $88E8; + GL_DYNAMIC_READ_ARB = $88E9; + GL_DYNAMIC_COPY_ARB = $88EA; + +var + glBindBufferARB : procedure(target : GLenum; buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteBuffersARB : procedure(n : GLsizei; buffers : PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenBuffersARB : procedure(n : GLsizei; buffers : PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsBufferARB : function (buffer : GLuint) :GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBufferDataARB : procedure(target : GLenum; size:GLsizei; data:PGLvoid;usage: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBufferSubDataARB : procedure(target : GLenum; offset :GLint; size : GLsizei; data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferSubDataARB : procedure(target : GLenum; offset :GLint; size : GLsizei; data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapBufferARB : function (target :GLenum; access: GLenum) : PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUnmapBufferARB : function (target :GLenum) :GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferParameterivARB:procedure(target:GLenum; pname:GLenum; params:PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferPointervARB : procedure(target: GLenum; pname:GLenum; params: PPGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +function Load_GL_ARB_vertex_buffer_object : boolean; + +//***** GL_APPLE_client_storage *****// +const + GL_UNPACK_CLIENT_STORAGE_APPLE = $85B2; + +function Load_GL_APPLE_client_storage: Boolean; + +//***** GL_APPLE_element_array *****// +const + GL_ELEMENT_ARRAY_APPLE = $8768; + GL_ELEMENT_ARRAY_TYPE_APPLE = $8769; + GL_ELEMENT_ARRAY_POINTER_APPLE = $876A; +var + glElementPointerAPPLE: procedure(_type: GLenum; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElementArrayAPPLE: procedure(mode: GLenum; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawRangeElementArrayAPPLE: procedure(mode: GLenum; start: GLuint; _end: GLuint; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawElementArrayAPPLE: procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawRangeElementArrayAPPLE: procedure(mode: GLenum; start: GLuint; _end: GLuint; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_APPLE_element_array: Boolean; + +//***** GL_APPLE_fence *****// +const + GL_DRAW_PIXELS_APPLE = $8A0A; + GL_FENCE_APPLE = $8A0B; +var + glGenFencesAPPLE: procedure(n: GLsizei; fences: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteFencesAPPLE: procedure(n: GLsizei; const fences: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSetFenceAPPLE: procedure(fence: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsFenceAPPLE: function(fence: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTestFenceAPPLE: function(fence: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFinishFenceAPPLE: procedure(fence: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTestObjectAPPLE: function(_object: GLenum; name: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFinishObjectAPPLE: procedure(_object: GLenum; name: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_APPLE_fence: Boolean; + +//***** GL_APPLE_vertex_array_object *****// +const + GL_VERTEX_ARRAY_BINDING_APPLE = $85B5; +var + glBindVertexArrayAPPLE: procedure(_array: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteVertexArraysAPPLE: procedure(n: GLsizei; const arrays: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenVertexArraysAPPLE: procedure(n: GLsizei; const arrays: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsVertexArrayAPPLE: function(_array: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_APPLE_vertex_array_object: Boolean; + +//***** GL_APPLE_vertex_array_range *****// +const + GL_VERTEX_ARRAY_RANGE_APPLE = $851D; + GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE = $851E; + GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE = $8520; + GL_VERTEX_ARRAY_RANGE_POINTER_APPLE = $8521; + GL_VERTEX_ARRAY_STORAGE_HINT_APPLE = $851F; + GL_STORAGE_CACHED_APPLE = $85BE; + GL_STORAGE_SHARED_APPLE = $85BF; +var + glVertexArrayRangeAPPLE: procedure(length: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFlushVertexArrayRangeAPPLE: procedure(length: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexArrayParameteriAPPLE: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_APPLE_vertex_array_range: Boolean; + +{$IFDEF msWindows} +//***** WGL_ARB_pixel_format *****// +const + WGL_NUMBER_PIXEL_FORMATS_ARB = $2000; + WGL_DRAW_TO_WINDOW_ARB = $2001; + WGL_DRAW_TO_BITMAP_ARB = $2002; + WGL_ACCELERATION_ARB = $2003; + WGL_NEED_PALETTE_ARB = $2004; + WGL_NEED_SYSTEM_PALETTE_ARB = $2005; + WGL_SWAP_LAYER_BUFFERS_ARB = $2006; + WGL_SWAP_METHOD_ARB = $2007; + WGL_NUMBER_OVERLAYS_ARB = $2008; + WGL_NUMBER_UNDERLAYS_ARB = $2009; + WGL_TRANSPARENT_ARB = $200A; + WGL_TRANSPARENT_RED_VALUE_ARB = $2037; + WGL_TRANSPARENT_GREEN_VALUE_ARB = $2038; + WGL_TRANSPARENT_BLUE_VALUE_ARB = $2039; + WGL_TRANSPARENT_ALPHA_VALUE_ARB = $203A; + WGL_TRANSPARENT_INDEX_VALUE_ARB = $203B; + WGL_SHARE_DEPTH_ARB = $200C; + WGL_SHARE_STENCIL_ARB = $200D; + WGL_SHARE_ACCUM_ARB = $200E; + WGL_SUPPORT_GDI_ARB = $200F; + WGL_SUPPORT_OPENGL_ARB = $2010; + WGL_DOUBLE_BUFFER_ARB = $2011; + WGL_STEREO_ARB = $2012; + WGL_PIXEL_TYPE_ARB = $2013; + WGL_COLOR_BITS_ARB = $2014; + WGL_RED_BITS_ARB = $2015; + WGL_RED_SHIFT_ARB = $2016; + WGL_GREEN_BITS_ARB = $2017; + WGL_GREEN_SHIFT_ARB = $2018; + WGL_BLUE_BITS_ARB = $2019; + WGL_BLUE_SHIFT_ARB = $201A; + WGL_ALPHA_BITS_ARB = $201B; + WGL_ALPHA_SHIFT_ARB = $201C; + WGL_ACCUM_BITS_ARB = $201D; + WGL_ACCUM_RED_BITS_ARB = $201E; + WGL_ACCUM_GREEN_BITS_ARB = $201F; + WGL_ACCUM_BLUE_BITS_ARB = $2020; + WGL_ACCUM_ALPHA_BITS_ARB = $2021; + WGL_DEPTH_BITS_ARB = $2022; + WGL_STENCIL_BITS_ARB = $2023; + WGL_AUX_BUFFERS_ARB = $2024; + WGL_NO_ACCELERATION_ARB = $2025; + WGL_GENERIC_ACCELERATION_ARB = $2026; + WGL_FULL_ACCELERATION_ARB = $2027; + WGL_SWAP_EXCHANGE_ARB = $2028; + WGL_SWAP_COPY_ARB = $2029; + WGL_SWAP_UNDEFINED_ARB = $202A; + WGL_TYPE_RGBA_ARB = $202B; + WGL_TYPE_COLORINDEX_ARB = $202C; +var + wglGetPixelFormatAttribivARB: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; const piAttributes: PGLint; piValues: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetPixelFormatAttribfvARB: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; const piAttributes: PGLint; pfValues: PGLfloat): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglChoosePixelFormatARB: function(hdc: HDC; const piAttribIList: PGLint; const pfAttribFList: PGLfloat; nMaxFormats: GLuint; piFormats: PGLint; nNumFormats: PGLuint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_pixel_format: Boolean; + +//***** WGL_ARB_make_current_read *****// +const + WGL_ERROR_INVALID_PIXEL_TYPE_ARB = $2043; + WGL_ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB = $2054; +var + wglMakeContextCurrentARB: function(hDrawDC: HDC; hReadDC: HDC; hglrc: HGLRC): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetCurrentReadDCARB: function(): HDC; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_make_current_read: Boolean; + +//***** WGL_ARB_pbuffer *****// +const + WGL_DRAW_TO_PBUFFER_ARB = $202D; + // WGL_DRAW_TO_PBUFFER_ARB { already defined } + WGL_MAX_PBUFFER_PIXELS_ARB = $202E; + WGL_MAX_PBUFFER_WIDTH_ARB = $202F; + WGL_MAX_PBUFFER_HEIGHT_ARB = $2030; + WGL_PBUFFER_LARGEST_ARB = $2033; + WGL_PBUFFER_WIDTH_ARB = $2034; + WGL_PBUFFER_HEIGHT_ARB = $2035; + WGL_PBUFFER_LOST_ARB = $2036; +var + wglCreatePbufferARB: function(hDC: HDC; iPixelFormat: GLint; iWidth: GLint; iHeight: GLint; const piAttribList: PGLint): THandle; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetPbufferDCARB: function(hPbuffer: THandle): HDC; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglReleasePbufferDCARB: function(hPbuffer: THandle; hDC: HDC): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDestroyPbufferARB: function(hPbuffer: THandle): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglQueryPbufferARB: function(hPbuffer: THandle; iAttribute: GLint; piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_pbuffer: Boolean; + +//***** WGL_EXT_swap_control *****// +var + wglSwapIntervalEXT: function(interval: GLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetSwapIntervalEXT: function(): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_EXT_swap_control: Boolean; + +//***** WGL_ARB_render_texture *****// +const + WGL_BIND_TO_TEXTURE_RGB_ARB = $2070; + WGL_BIND_TO_TEXTURE_RGBA_ARB = $2071; + WGL_TEXTURE_FORMAT_ARB = $2072; + WGL_TEXTURE_TARGET_ARB = $2073; + WGL_MIPMAP_TEXTURE_ARB = $2074; + WGL_TEXTURE_RGB_ARB = $2075; + WGL_TEXTURE_RGBA_ARB = $2076; + WGL_NO_TEXTURE_ARB = $2077; + WGL_TEXTURE_CUBE_MAP_ARB = $2078; + WGL_TEXTURE_1D_ARB = $2079; + WGL_TEXTURE_2D_ARB = $207A; + // WGL_NO_TEXTURE_ARB { already defined } + WGL_MIPMAP_LEVEL_ARB = $207B; + WGL_CUBE_MAP_FACE_ARB = $207C; + WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = $207D; + WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = $207E; + WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = $207F; + WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = $2080; + WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = $2081; + WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = $2082; + WGL_FRONT_LEFT_ARB = $2083; + WGL_FRONT_RIGHT_ARB = $2084; + WGL_BACK_LEFT_ARB = $2085; + WGL_BACK_RIGHT_ARB = $2086; + WGL_AUX0_ARB = $2087; + WGL_AUX1_ARB = $2088; + WGL_AUX2_ARB = $2089; + WGL_AUX3_ARB = $208A; + WGL_AUX4_ARB = $208B; + WGL_AUX5_ARB = $208C; + WGL_AUX6_ARB = $208D; + WGL_AUX7_ARB = $208E; + WGL_AUX8_ARB = $208F; + WGL_AUX9_ARB = $2090; +var + wglBindTexImageARB: function(hPbuffer: THandle; iBuffer: GLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglReleaseTexImageARB: function(hPbuffer: THandle; iBuffer: GLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglSetPbufferAttribARB: function(hPbuffer: THandle; const piAttribList: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_render_texture: Boolean; + +//***** WGL_EXT_extensions_string *****// +var + wglGetExtensionsStringEXT: function(): Pchar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_EXT_extensions_string: Boolean; + +//***** WGL_EXT_make_current_read *****// +var + wglMakeContextCurrentEXT: function(hDrawDC: HDC; hReadDC: HDC; hglrc: HGLRC): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetCurrentReadDCEXT: function(): HDC; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_EXT_make_current_read: Boolean; + +//***** WGL_EXT_pbuffer *****// +const + WGL_DRAW_TO_PBUFFER_EXT = $202D; + WGL_MAX_PBUFFER_PIXELS_EXT = $202E; + WGL_MAX_PBUFFER_WIDTH_EXT = $202F; + WGL_MAX_PBUFFER_HEIGHT_EXT = $2030; + WGL_OPTIMAL_PBUFFER_WIDTH_EXT = $2031; + WGL_OPTIMAL_PBUFFER_HEIGHT_EXT = $2032; + WGL_PBUFFER_LARGEST_EXT = $2033; + WGL_PBUFFER_WIDTH_EXT = $2034; + WGL_PBUFFER_HEIGHT_EXT = $2035; +var + wglCreatePbufferEXT: function(hDC: HDC; iPixelFormat: GLint; iWidth: GLint; iHeight: GLint; const piAttribList: PGLint): THandle; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetPbufferDCEXT: function(hPbuffer: THandle): HDC; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglReleasePbufferDCEXT: function(hPbuffer: THandle; hDC: HDC): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDestroyPbufferEXT: function(hPbuffer: THandle): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglQueryPbufferEXT: function(hPbuffer: THandle; iAttribute: GLint; piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_EXT_pbuffer: Boolean; + +//***** WGL_EXT_pixel_format *****// +const + WGL_NUMBER_PIXEL_FORMATS_EXT = $2000; + WGL_DRAW_TO_WINDOW_EXT = $2001; + WGL_DRAW_TO_BITMAP_EXT = $2002; + WGL_ACCELERATION_EXT = $2003; + WGL_NEED_PALETTE_EXT = $2004; + WGL_NEED_SYSTEM_PALETTE_EXT = $2005; + WGL_SWAP_LAYER_BUFFERS_EXT = $2006; + WGL_SWAP_METHOD_EXT = $2007; + WGL_NUMBER_OVERLAYS_EXT = $2008; + WGL_NUMBER_UNDERLAYS_EXT = $2009; + WGL_TRANSPARENT_EXT = $200A; + WGL_TRANSPARENT_VALUE_EXT = $200B; + WGL_SHARE_DEPTH_EXT = $200C; + WGL_SHARE_STENCIL_EXT = $200D; + WGL_SHARE_ACCUM_EXT = $200E; + WGL_SUPPORT_GDI_EXT = $200F; + WGL_SUPPORT_OPENGL_EXT = $2010; + WGL_DOUBLE_BUFFER_EXT = $2011; + WGL_STEREO_EXT = $2012; + WGL_PIXEL_TYPE_EXT = $2013; + WGL_COLOR_BITS_EXT = $2014; + WGL_RED_BITS_EXT = $2015; + WGL_RED_SHIFT_EXT = $2016; + WGL_GREEN_BITS_EXT = $2017; + WGL_GREEN_SHIFT_EXT = $2018; + WGL_BLUE_BITS_EXT = $2019; + WGL_BLUE_SHIFT_EXT = $201A; + WGL_ALPHA_BITS_EXT = $201B; + WGL_ALPHA_SHIFT_EXT = $201C; + WGL_ACCUM_BITS_EXT = $201D; + WGL_ACCUM_RED_BITS_EXT = $201E; + WGL_ACCUM_GREEN_BITS_EXT = $201F; + WGL_ACCUM_BLUE_BITS_EXT = $2020; + WGL_ACCUM_ALPHA_BITS_EXT = $2021; + WGL_DEPTH_BITS_EXT = $2022; + WGL_STENCIL_BITS_EXT = $2023; + WGL_AUX_BUFFERS_EXT = $2024; + WGL_NO_ACCELERATION_EXT = $2025; + WGL_GENERIC_ACCELERATION_EXT = $2026; + WGL_FULL_ACCELERATION_EXT = $2027; + WGL_SWAP_EXCHANGE_EXT = $2028; + WGL_SWAP_COPY_EXT = $2029; + WGL_SWAP_UNDEFINED_EXT = $202A; + WGL_TYPE_RGBA_EXT = $202B; + WGL_TYPE_COLORINDEX_EXT = $202C; +var + wglGetPixelFormatAttribivEXT: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; piAttributes: PGLint; piValues: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetPixelFormatAttribfvEXT: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; piAttributes: PGLint; pfValues: PGLfloat): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglChoosePixelFormatEXT: function(hdc: HDC; const piAttribIList: PGLint; const pfAttribFList: PGLfloat; nMaxFormats: GLuint; piFormats: PGLint; nNumFormats: PGLuint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_EXT_pixel_format: Boolean; + +//***** WGL_I3D_digital_video_control *****// +const + WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D = $2050; + WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D = $2051; + WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D = $2052; + WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D = $2053; +var + wglGetDigitalVideoParametersI3D: function(hDC: HDC; iAttribute: GLint; piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglSetDigitalVideoParametersI3D: function(hDC: HDC; iAttribute: GLint; const piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_digital_video_control: Boolean; + +//***** WGL_I3D_gamma *****// +const + WGL_GAMMA_TABLE_SIZE_I3D = $204E; + WGL_GAMMA_EXCLUDE_DESKTOP_I3D = $204F; + // WGL_GAMMA_EXCLUDE_DESKTOP_I3D { already defined } +var + wglGetGammaTableParametersI3D: function(hDC: HDC; iAttribute: GLint; piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglSetGammaTableParametersI3D: function(hDC: HDC; iAttribute: GLint; const piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetGammaTableI3D: function(hDC: HDC; iEntries: GLint; puRed: PGLUSHORT; puGreen: PGLUSHORT; puBlue: PGLUSHORT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglSetGammaTableI3D: function(hDC: HDC; iEntries: GLint; const puRed: PGLUSHORT; const puGreen: PGLUSHORT; const puBlue: PGLUSHORT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_gamma: Boolean; + +//***** WGL_I3D_genlock *****// +const + WGL_GENLOCK_SOURCE_MULTIVIEW_I3D = $2044; + WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D = $2045; + WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D = $2046; + WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D = $2047; + WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D = $2048; + WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D = $2049; + WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D = $204A; + WGL_GENLOCK_SOURCE_EDGE_RISING_I3D = $204B; + WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D = $204C; +var + wglEnableGenlockI3D: function(hDC: HDC): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDisableGenlockI3D: function(hDC: HDC): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglIsEnabledGenlockI3D: function(hDC: HDC; pFlag: PBOOL): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGenlockSourceI3D: function(hDC: HDC; uSource: GLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetGenlockSourceI3D: function(hDC: HDC; uSource: PGLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGenlockSourceEdgeI3D: function(hDC: HDC; uEdge: GLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetGenlockSourceEdgeI3D: function(hDC: HDC; uEdge: PGLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGenlockSampleRateI3D: function(hDC: HDC; uRate: GLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetGenlockSampleRateI3D: function(hDC: HDC; uRate: PGLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGenlockSourceDelayI3D: function(hDC: HDC; uDelay: GLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetGenlockSourceDelayI3D: function(hDC: HDC; uDelay: PGLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglQueryGenlockMaxSourceDelayI3D: function(hDC: HDC; uMaxLineDelay: PGLUINT; uMaxPixelDelay: PGLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_genlock: Boolean; +{$ENDIF} + +//***** GL_ARB_matrix_palette *****// +const + GL_MATRIX_PALETTE_ARB = $8840; + GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB = $8841; + GL_MAX_PALETTE_MATRICES_ARB = $8842; + GL_CURRENT_PALETTE_MATRIX_ARB = $8843; + GL_MATRIX_INDEX_ARRAY_ARB = $8844; + GL_CURRENT_MATRIX_INDEX_ARB = $8845; + GL_MATRIX_INDEX_ARRAY_SIZE_ARB = $8846; + GL_MATRIX_INDEX_ARRAY_TYPE_ARB = $8847; + GL_MATRIX_INDEX_ARRAY_STRIDE_ARB = $8848; + GL_MATRIX_INDEX_ARRAY_POINTER_ARB = $8849; +var + glCurrentPaletteMatrixARB: procedure(index: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMatrixIndexubvARB: procedure(size: GLint; indices: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMatrixIndexusvARB: procedure(size: GLint; indices: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMatrixIndexuivARB: procedure(size: GLint; indices: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMatrixIndexPointerARB: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_matrix_palette: Boolean; + +//***** GL_NV_element_array *****// +const + GL_ELEMENT_ARRAY_TYPE_NV = $8769; + GL_ELEMENT_ARRAY_POINTER_NV = $876A; +var + glElementPointerNV: procedure(_type: GLenum; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElementArrayNV: procedure(mode: GLenum; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawRangeElementArrayNV: procedure(mode: GLenum; start: GLuint; _end: GLuint; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawElementArrayNV: procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawRangeElementArrayNV: procedure(mode: GLenum; start: GLuint; _end: GLuint; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_element_array: Boolean; + +//***** GL_NV_float_buffer *****// +const + GL_FLOAT_R_NV = $8880; + GL_FLOAT_RG_NV = $8881; + GL_FLOAT_RGB_NV = $8882; + GL_FLOAT_RGBA_NV = $8883; + GL_FLOAT_R16_NV = $8884; + GL_FLOAT_R32_NV = $8885; + GL_FLOAT_RG16_NV = $8886; + GL_FLOAT_RG32_NV = $8887; + GL_FLOAT_RGB16_NV = $8888; + GL_FLOAT_RGB32_NV = $8889; + GL_FLOAT_RGBA16_NV = $888A; + GL_FLOAT_RGBA32_NV = $888B; + GL_TEXTURE_FLOAT_COMPONENTS_NV = $888C; + GL_FLOAT_CLEAR_COLOR_VALUE_NV = $888D; + GL_FLOAT_RGBA_MODE_NV = $888E; +{$IFDEF msWindows} + WGL_FLOAT_COMPONENTS_NV = $20B0; + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV = $20B1; + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV = $20B2; + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV = $20B3; + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV = $20B4; + WGL_TEXTURE_FLOAT_R_NV = $20B5; + WGL_TEXTURE_FLOAT_RG_NV = $20B6; + WGL_TEXTURE_FLOAT_RGB_NV = $20B7; + WGL_TEXTURE_FLOAT_RGBA_NV = $20B8; +{$ENDIF} + +function Load_GL_NV_float_buffer: Boolean; + +//***** GL_NV_fragment_program *****// +const + GL_FRAGMENT_PROGRAM_NV = $8870; + GL_MAX_TEXTURE_COORDS_NV = $8871; + GL_MAX_TEXTURE_IMAGE_UNITS_NV = $8872; + GL_FRAGMENT_PROGRAM_BINDING_NV = $8873; + GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV = $8868; + GL_PROGRAM_ERROR_STRING_NV = $8874; +var + glProgramNamedParameter4fNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramNamedParameter4dNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramNamedParameterfvNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramNamedParameterdvNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + // glProgramLocalParameter4dARB { already defined } + // glProgramLocalParameter4dvARB { already defined } + // glProgramLocalParameter4fARB { already defined } + // glProgramLocalParameter4fvARB { already defined } + // glGetProgramLocalParameterdvARB { already defined } + // glGetProgramLocalParameterfvARB { already defined } + +function Load_GL_NV_fragment_program: Boolean; + +//***** GL_NV_primitive_restart *****// +const + GL_PRIMITIVE_RESTART_NV = $8558; + GL_PRIMITIVE_RESTART_INDEX_NV = $8559; +var + glPrimitiveRestartNV: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPrimitiveRestartIndexNV: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_primitive_restart: Boolean; + +//***** GL_NV_vertex_program2 *****// + +function Load_GL_NV_vertex_program2: Boolean; + +{$IFDEF msWindows} +//***** WGL_NV_render_texture_rectangle *****// +const + WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV = $20A0; + WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV = $20A1; + WGL_TEXTURE_RECTANGLE_NV = $20A2; + +function Load_WGL_NV_render_texture_rectangle: Boolean; +{$ENDIF} + +//***** GL_NV_pixel_data_range *****// +const + GL_WRITE_PIXEL_DATA_RANGE_NV = $8878; + GL_READ_PIXEL_DATA_RANGE_NV = $8879; + GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV = $887A; + GL_READ_PIXEL_DATA_RANGE_LENGTH_NV = $887B; + GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV = $887C; + GL_READ_PIXEL_DATA_RANGE_POINTER_NV = $887D; +var + glPixelDataRangeNV: procedure(target: GLenum; length: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFlushPixelDataRangeNV: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + // wglAllocateMemoryNV { already defined } + // wglFreeMemoryNV { already defined } + +function Load_GL_NV_pixel_data_range: Boolean; + +//***** GL_EXT_texture_rectangle *****// +const + GL_TEXTURE_RECTANGLE_EXT = $84F5; + GL_TEXTURE_BINDING_RECTANGLE_EXT = $84F6; + GL_PROXY_TEXTURE_RECTANGLE_EXT = $84F7; + GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT = $84F8; + +function Load_GL_EXT_texture_rectangle: Boolean; + +//***** GL_S3_s3tc *****// +const + GL_RGB_S3TC = $83A0; + GL_RGB4_S3TC = $83A1; + GL_RGBA_S3TC = $83A2; + GL_RGBA4_S3TC = $83A3; + +function Load_GL_S3_s3tc: Boolean; + +//***** GL_ATI_draw_buffers *****// +const + GL_MAX_DRAW_BUFFERS_ATI = $8824; + GL_DRAW_BUFFER0_ATI = $8825; + GL_DRAW_BUFFER1_ATI = $8826; + GL_DRAW_BUFFER2_ATI = $8827; + GL_DRAW_BUFFER3_ATI = $8828; + GL_DRAW_BUFFER4_ATI = $8829; + GL_DRAW_BUFFER5_ATI = $882A; + GL_DRAW_BUFFER6_ATI = $882B; + GL_DRAW_BUFFER7_ATI = $882C; + GL_DRAW_BUFFER8_ATI = $882D; + GL_DRAW_BUFFER9_ATI = $882E; + GL_DRAW_BUFFER10_ATI = $882F; + GL_DRAW_BUFFER11_ATI = $8830; + GL_DRAW_BUFFER12_ATI = $8831; + GL_DRAW_BUFFER13_ATI = $8832; + GL_DRAW_BUFFER14_ATI = $8833; + GL_DRAW_BUFFER15_ATI = $8834; +var + glDrawBuffersATI: procedure(n: GLsizei; const bufs: PGLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_draw_buffers: Boolean; + +{$IFDEF msWindows} +//***** WGL_ATI_pixel_format_float *****// +const + WGL_RGBA_FLOAT_MODE_ATI = $8820; + WGL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI = $8835; + WGL_TYPE_RGBA_FLOAT_ATI = $21A0; + +function Load_WGL_ATI_pixel_format_float: Boolean; +{$ENDIF} + +//***** GL_ATI_texture_env_combine3 *****// +const + GL_MODULATE_ADD_ATI = $8744; + GL_MODULATE_SIGNED_ADD_ATI = $8745; + GL_MODULATE_SUBTRACT_ATI = $8746; + +function Load_GL_ATI_texture_env_combine3: Boolean; + +//***** GL_ATI_texture_float *****// +const + GL_RGBA_FLOAT32_ATI = $8814; + GL_RGB_FLOAT32_ATI = $8815; + GL_ALPHA_FLOAT32_ATI = $8816; + GL_INTENSITY_FLOAT32_ATI = $8817; + GL_LUMINANCE_FLOAT32_ATI = $8818; + GL_LUMINANCE_ALPHA_FLOAT32_ATI = $8819; + GL_RGBA_FLOAT16_ATI = $881A; + GL_RGB_FLOAT16_ATI = $881B; + GL_ALPHA_FLOAT16_ATI = $881C; + GL_INTENSITY_FLOAT16_ATI = $881D; + GL_LUMINANCE_FLOAT16_ATI = $881E; + GL_LUMINANCE_ALPHA_FLOAT16_ATI = $881F; + +function Load_GL_ATI_texture_float: Boolean; + +//***** GL_NV_texture_expand_normal *****// +const + GL_TEXTURE_UNSIGNED_REMAP_MODE_NV = $888F; + +function Load_GL_NV_texture_expand_normal: Boolean; + +//***** GL_NV_half_float *****// +const + GL_HALF_FLOAT_NV = $140B; +var + glVertex2hNV: procedure(x: GLushort; y: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3hNV: procedure(x: GLushort; y: GLushort; z: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4hNV: procedure(x: GLushort; y: GLushort; z: GLushort; w: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3hNV: procedure(nx: GLushort; ny: GLushort; nz: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3hNV: procedure(red: GLushort; green: GLushort; blue: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4hNV: procedure(red: GLushort; green: GLushort; blue: GLushort; alpha: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1hNV: procedure(s: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2hNV: procedure(s: GLushort; t: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3hNV: procedure(s: GLushort; t: GLushort; r: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4hNV: procedure(s: GLushort; t: GLushort; r: GLushort; q: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1hNV: procedure(target: GLenum; s: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1hvNV: procedure(target: GLenum; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2hNV: procedure(target: GLenum; s: GLushort; t: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2hvNV: procedure(target: GLenum; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3hNV: procedure(target: GLenum; s: GLushort; t: GLushort; r: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3hvNV: procedure(target: GLenum; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4hNV: procedure(target: GLenum; s: GLushort; t: GLushort; r: GLushort; q: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4hvNV: procedure(target: GLenum; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordhNV: procedure(fog: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordhvNV: procedure(const fog: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3hNV: procedure(red: GLushort; green: GLushort; blue: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexWeighthNV: procedure(weight: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexWeighthvNV: procedure(const weight: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1hNV: procedure(index: GLuint; x: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1hvNV: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2hNV: procedure(index: GLuint; x: GLushort; y: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2hvNV: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3hNV: procedure(index: GLuint; x: GLushort; y: GLushort; z: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3hvNV: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4hNV: procedure(index: GLuint; x: GLushort; y: GLushort; z: GLushort; w: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4hvNV: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs1hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs2hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs3hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs4hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_half_float: Boolean; + +//***** GL_ATI_map_object_buffer *****// +var + glMapObjectBufferATI: function(buffer: GLuint): PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUnmapObjectBufferATI: procedure(buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_map_object_buffer: Boolean; + +//***** GL_ATI_separate_stencil *****// +const + GL_KEEP = $1E00; + GL_ZERO = $0000; + GL_REPLACE = $1E01; + GL_INCR = $1E02; + GL_DECR = $1E03; + GL_INVERT = $150A; + GL_NEVER = $0200; + GL_LESS = $0201; + GL_LEQUAL = $0203; + GL_GREATER = $0204; + GL_GEQUAL = $0206; + GL_EQUAL = $0202; + GL_NOTEQUAL = $0205; + GL_ALWAYS = $0207; + GL_FRONT = $0404; + GL_BACK = $0405; + GL_FRONT_AND_BACK = $0408; + GL_STENCIL_BACK_FUNC_ATI = $8800; + GL_STENCIL_BACK_FAIL_ATI = $8801; + GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI = $8802; + GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI = $8803; +var + glStencilOpSeparateATI: procedure(face: GLenum; sfail: GLenum; dpfail: GLenum; dppass: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilFuncSeparateATI: procedure(frontfunc: GLenum; backfunc: GLenum; ref: GLint; mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_separate_stencil: Boolean; + +//***** GL_ATI_vertex_attrib_array_object *****// +var + glVertexAttribArrayObjectATI: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; buffer: GLuint; offset: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribArrayObjectfvATI: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribArrayObjectivATI: procedure(index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_vertex_attrib_array_object: Boolean; + +//***** GL_ARB_occlusion_query *****// +const + GL_SAMPLES_PASSED_ARB = $8914; + GL_QUERY_COUNTER_BITS_ARB = $8864; + GL_CURRENT_QUERY_ARB = $8865; + GL_QUERY_RESULT_ARB = $8866; + GL_QUERY_RESULT_AVAILABLE_ARB = $8867; +var + glGenQueriesARB: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteQueriesARB: procedure(n: GLsizei; const ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsQueryARB: function(id: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginQueryARB: procedure(target: GLenum; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndQueryARB: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryivARB: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjectivARB: procedure(id: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjectuivARB: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_occlusion_query: Boolean; + +//***** GL_ARB_shader_objects *****// +const + GL_PROGRAM_OBJECT_ARB = $8B40; + GL_OBJECT_TYPE_ARB = $8B4E; + GL_OBJECT_SUBTYPE_ARB = $8B4F; + GL_OBJECT_DELETE_STATUS_ARB = $8B80; + GL_OBJECT_COMPILE_STATUS_ARB = $8B81; + GL_OBJECT_LINK_STATUS_ARB = $8B82; + GL_OBJECT_VALIDATE_STATUS_ARB = $8B83; + GL_OBJECT_INFO_LOG_LENGTH_ARB = $8B84; + GL_OBJECT_ATTACHED_OBJECTS_ARB = $8B85; + GL_OBJECT_ACTIVE_UNIFORMS_ARB = $8B86; + GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB = $8B87; + GL_OBJECT_SHADER_SOURCE_LENGTH_ARB = $8B88; + GL_SHADER_OBJECT_ARB = $8B48; + GL_FLOAT = $1406; + GL_FLOAT_VEC2_ARB = $8B50; + GL_FLOAT_VEC3_ARB = $8B51; + GL_FLOAT_VEC4_ARB = $8B52; + GL_INT = $1404; + GL_INT_VEC2_ARB = $8B53; + GL_INT_VEC3_ARB = $8B54; + GL_INT_VEC4_ARB = $8B55; + GL_BOOL_ARB = $8B56; + GL_BOOL_VEC2_ARB = $8B57; + GL_BOOL_VEC3_ARB = $8B58; + GL_BOOL_VEC4_ARB = $8B59; + GL_FLOAT_MAT2_ARB = $8B5A; + GL_FLOAT_MAT3_ARB = $8B5B; + GL_FLOAT_MAT4_ARB = $8B5C; +var + glDeleteObjectARB: procedure(obj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHandleARB: function(pname: GLenum): GLhandleARB; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDetachObjectARB: procedure(containerObj: GLhandleARB; attachedObj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCreateShaderObjectARB: function(shaderType: GLenum): GLhandleARB; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShaderSourceARB: procedure(shaderObj: GLhandleARB; count: GLsizei; const _string: PGLvoid; const length: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompileShaderARB: procedure(shaderObj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCreateProgramObjectARB: function(): GLhandleARB; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAttachObjectARB: procedure(containerObj: GLhandleARB; obj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLinkProgramARB: procedure(programObj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUseProgramObjectARB: procedure(programObj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glValidateProgramARB: procedure(programObj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1fARB: procedure(location: GLint; v0: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat; v3: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1iARB: procedure(location: GLint; v0: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2iARB: procedure(location: GLint; v0: GLint; v1: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3iARB: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4iARB: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint; v3: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetObjectParameterfvARB: procedure(obj: GLhandleARB; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetObjectParameterivARB: procedure(obj: GLhandleARB; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetInfoLogARB: procedure(obj: GLhandleARB; maxLength: GLsizei; length: PGLsizei; infoLog: PGLcharARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetAttachedObjectsARB: procedure(containerObj: GLhandleARB; maxCount: GLsizei; count: PGLsizei; obj: PGLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformLocationARB: function(programObj: GLhandleARB; const name: PGLcharARB): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniformARB: procedure(programObj: GLhandleARB; index: GLuint; maxLength: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLcharARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformfvARB: procedure(programObj: GLhandleARB; location: GLint; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformivARB: procedure(programObj: GLhandleARB; location: GLint; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetShaderSourceARB: procedure(obj: GLhandleARB; maxLength: GLsizei; length: PGLsizei; source: PGLcharARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_shader_objects: Boolean; + +//***** GL_ARB_vertex_shader *****// +const + GL_VERTEX_SHADER_ARB = $8B31; + GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB = $8B4A; + GL_MAX_VARYING_FLOATS_ARB = $8B4B; + // GL_MAX_VERTEX_ATTRIBS_ARB { already defined } + // GL_MAX_TEXTURE_IMAGE_UNITS_ARB { already defined } + GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB = $8B4C; + GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB = $8B4D; + // GL_MAX_TEXTURE_COORDS_ARB { already defined } + // GL_VERTEX_PROGRAM_POINT_SIZE_ARB { already defined } + // GL_VERTEX_PROGRAM_TWO_SIDE_ARB { already defined } + // GL_OBJECT_TYPE_ARB { already defined } + // GL_OBJECT_SUBTYPE_ARB { already defined } + GL_OBJECT_ACTIVE_ATTRIBUTES_ARB = $8B89; + GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB = $8B8A; + // GL_SHADER_OBJECT_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB { already defined } + // GL_CURRENT_VERTEX_ATTRIB_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB { already defined } + // GL_FLOAT { already defined } + // GL_FLOAT_VEC2_ARB { already defined } + // GL_FLOAT_VEC3_ARB { already defined } + // GL_FLOAT_VEC4_ARB { already defined } + // GL_FLOAT_MAT2_ARB { already defined } + // GL_FLOAT_MAT3_ARB { already defined } + // GL_FLOAT_MAT4_ARB { already defined } + // glVertexAttrib1fARB { already defined } + // glVertexAttrib1sARB { already defined } + // glVertexAttrib1dARB { already defined } + // glVertexAttrib2fARB { already defined } + // glVertexAttrib2sARB { already defined } + // glVertexAttrib2dARB { already defined } + // glVertexAttrib3fARB { already defined } + // glVertexAttrib3sARB { already defined } + // glVertexAttrib3dARB { already defined } + // glVertexAttrib4fARB { already defined } + // glVertexAttrib4sARB { already defined } + // glVertexAttrib4dARB { already defined } + // glVertexAttrib4NubARB { already defined } + // glVertexAttrib1fvARB { already defined } + // glVertexAttrib1svARB { already defined } + // glVertexAttrib1dvARB { already defined } + // glVertexAttrib2fvARB { already defined } + // glVertexAttrib2svARB { already defined } + // glVertexAttrib2dvARB { already defined } + // glVertexAttrib3fvARB { already defined } + // glVertexAttrib3svARB { already defined } + // glVertexAttrib3dvARB { already defined } + // glVertexAttrib4fvARB { already defined } + // glVertexAttrib4svARB { already defined } + // glVertexAttrib4dvARB { already defined } + // glVertexAttrib4ivARB { already defined } + // glVertexAttrib4bvARB { already defined } + // glVertexAttrib4ubvARB { already defined } + // glVertexAttrib4usvARB { already defined } + // glVertexAttrib4uivARB { already defined } + // glVertexAttrib4NbvARB { already defined } + // glVertexAttrib4NsvARB { already defined } + // glVertexAttrib4NivARB { already defined } + // glVertexAttrib4NubvARB { already defined } + // glVertexAttrib4NusvARB { already defined } + // glVertexAttrib4NuivARB { already defined } + // glVertexAttribPointerARB { already defined } + // glEnableVertexAttribArrayARB { already defined } + // glDisableVertexAttribArrayARB { already defined } +var + glBindAttribLocationARB: procedure(programObj: GLhandleARB; index: GLuint; const name: PGLcharARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveAttribARB: procedure(programObj: GLhandleARB; index: GLuint; maxLength: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLcharARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetAttribLocationARB: function(programObj: GLhandleARB; const name: PGLcharARB): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + // glGetVertexAttribdvARB { already defined } + // glGetVertexAttribfvARB { already defined } + // glGetVertexAttribivARB { already defined } + // glGetVertexAttribPointervARB { already defined } + +function Load_GL_ARB_vertex_shader: Boolean; + +//***** GL_ARB_fragment_shader *****// +const + GL_FRAGMENT_SHADER_ARB = $8B30; + GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB = $8B49; + // GL_MAX_TEXTURE_COORDS_ARB { already defined } + // GL_MAX_TEXTURE_IMAGE_UNITS_ARB { already defined } + // GL_OBJECT_TYPE_ARB { already defined } + // GL_OBJECT_SUBTYPE_ARB { already defined } + // GL_SHADER_OBJECT_ARB { already defined } + +function Load_GL_ARB_fragment_shader: Boolean; + +//***** GL_ARB_shading_language_100 *****// + +function Load_GL_ARB_shading_language_100: Boolean; + +//***** GL_ARB_texture_non_power_of_two *****// + +function Load_GL_ARB_texture_non_power_of_two: Boolean; + +//***** GL_ARB_point_sprite *****// +const + GL_POINT_SPRITE_ARB = $8861; + GL_COORD_REPLACE_ARB = $8862; + +function Load_GL_ARB_point_sprite: Boolean; + +//***** GL_EXT_depth_bounds_test *****// +const + GL_DEPTH_BOUNDS_TEST_EXT = $8890; + GL_DEPTH_BOUNDS_EXT = $8891; +var + glDepthBoundsEXT: procedure(zmin: GLclampd; zmax: GLclampd); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_depth_bounds_test: Boolean; + +//***** GL_EXT_texture_mirror_clamp *****// +const + GL_MIRROR_CLAMP_EXT = $8742; + GL_MIRROR_CLAMP_TO_EDGE_EXT = $8743; + GL_MIRROR_CLAMP_TO_BORDER_EXT = $8912; + +function Load_GL_EXT_texture_mirror_clamp: Boolean; + +//***** GL_EXT_blend_equation_separate *****// +const + GL_BLEND_EQUATION_RGB_EXT = $8009; + GL_BLEND_EQUATION_ALPHA_EXT = $883D; +var + glBlendEquationSeparateEXT: procedure(modeRGB: GLenum; modeAlpha: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_blend_equation_separate: Boolean; + +//***** GL_MESA_pack_invert *****// +const + GL_PACK_INVERT_MESA = $8758; + +function Load_GL_MESA_pack_invert: Boolean; + +//***** GL_MESA_ycbcr_texture *****// +const + GL_YCBCR_MESA = $8757; + GL_UNSIGNED_SHORT_8_8_MESA = $85BA; + GL_UNSIGNED_SHORT_8_8_REV_MESA = $85BB; + +function Load_GL_MESA_ycbcr_texture: Boolean; + +//***** GL_ARB_fragment_program_shadow *****// + +function Load_GL_ARB_fragment_program_shadow: Boolean; + +//***** GL_NV_fragment_program_option *****// + +function Load_GL_NV_fragment_program_option: Boolean; + +//***** GL_EXT_pixel_buffer_object *****// +const + GL_PIXEL_PACK_BUFFER_EXT = $88EB; + GL_PIXEL_UNPACK_BUFFER_EXT = $88EC; + GL_PIXEL_PACK_BUFFER_BINDING_EXT = $88ED; + GL_PIXEL_UNPACK_BUFFER_BINDING_EXT = $88EF; + +function Load_GL_EXT_pixel_buffer_object: Boolean; + +//***** GL_NV_fragment_program2 *****// +const + GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV = $88F4; + GL_MAX_PROGRAM_CALL_DEPTH_NV = $88F5; + GL_MAX_PROGRAM_IF_DEPTH_NV = $88F6; + GL_MAX_PROGRAM_LOOP_DEPTH_NV = $88F7; + GL_MAX_PROGRAM_LOOP_COUNT_NV = $88F8; + +function Load_GL_NV_fragment_program2: Boolean; + +//***** GL_NV_vertex_program2_option *****// + // GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV { already defined } + // GL_MAX_PROGRAM_CALL_DEPTH_NV { already defined } + +function Load_GL_NV_vertex_program2_option: Boolean; + +//***** GL_NV_vertex_program3 *****// + // GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB { already defined } + +function Load_GL_NV_vertex_program3: Boolean; + +//***** GL_ARB_draw_buffers *****// +const + GL_MAX_DRAW_BUFFERS_ARB = $8824; + GL_DRAW_BUFFER0_ARB = $8825; + GL_DRAW_BUFFER1_ARB = $8826; + GL_DRAW_BUFFER2_ARB = $8827; + GL_DRAW_BUFFER3_ARB = $8828; + GL_DRAW_BUFFER4_ARB = $8829; + GL_DRAW_BUFFER5_ARB = $882A; + GL_DRAW_BUFFER6_ARB = $882B; + GL_DRAW_BUFFER7_ARB = $882C; + GL_DRAW_BUFFER8_ARB = $882D; + GL_DRAW_BUFFER9_ARB = $882E; + GL_DRAW_BUFFER10_ARB = $882F; + GL_DRAW_BUFFER11_ARB = $8830; + GL_DRAW_BUFFER12_ARB = $8831; + GL_DRAW_BUFFER13_ARB = $8832; + GL_DRAW_BUFFER14_ARB = $8833; + GL_DRAW_BUFFER15_ARB = $8834; +var + glDrawBuffersARB: procedure(n: GLsizei; const bufs: PGLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_draw_buffers: Boolean; + +//***** GL_ARB_texture_rectangle *****// +const + GL_TEXTURE_RECTANGLE_ARB = $84F5; + GL_TEXTURE_BINDING_RECTANGLE_ARB = $84F6; + GL_PROXY_TEXTURE_RECTANGLE_ARB = $84F7; + GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB = $84F8; + +function Load_GL_ARB_texture_rectangle: Boolean; + +//***** GL_ARB_color_buffer_float *****// +const + GL_RGBA_FLOAT_MODE_ARB = $8820; + GL_CLAMP_VERTEX_COLOR_ARB = $891A; + GL_CLAMP_FRAGMENT_COLOR_ARB = $891B; + GL_CLAMP_READ_COLOR_ARB = $891C; + GL_FIXED_ONLY_ARB = $891D; + WGL_TYPE_RGBA_FLOAT_ARB = $21A0; +var + glClampColorARB: procedure(target: GLenum; clamp: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_color_buffer_float: Boolean; + +//***** GL_ARB_half_float_pixel *****// +const + GL_HALF_FLOAT_ARB = $140B; + +function Load_GL_ARB_half_float_pixel: Boolean; + +//***** GL_ARB_texture_float *****// +const + GL_TEXTURE_RED_TYPE_ARB = $8C10; + GL_TEXTURE_GREEN_TYPE_ARB = $8C11; + GL_TEXTURE_BLUE_TYPE_ARB = $8C12; + GL_TEXTURE_ALPHA_TYPE_ARB = $8C13; + GL_TEXTURE_LUMINANCE_TYPE_ARB = $8C14; + GL_TEXTURE_INTENSITY_TYPE_ARB = $8C15; + GL_TEXTURE_DEPTH_TYPE_ARB = $8C16; + GL_UNSIGNED_NORMALIZED_ARB = $8C17; + GL_RGBA32F_ARB = $8814; + GL_RGB32F_ARB = $8815; + GL_ALPHA32F_ARB = $8816; + GL_INTENSITY32F_ARB = $8817; + GL_LUMINANCE32F_ARB = $8818; + GL_LUMINANCE_ALPHA32F_ARB = $8819; + GL_RGBA16F_ARB = $881A; + GL_RGB16F_ARB = $881B; + GL_ALPHA16F_ARB = $881C; + GL_INTENSITY16F_ARB = $881D; + GL_LUMINANCE16F_ARB = $881E; + GL_LUMINANCE_ALPHA16F_ARB = $881F; + +function Load_GL_ARB_texture_float: Boolean; + +//***** GL_EXT_texture_compression_dxt1 *****// + // GL_COMPRESSED_RGB_S3TC_DXT1_EXT { already defined } + // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT { already defined } + +function Load_GL_EXT_texture_compression_dxt1: Boolean; + +//***** GL_ARB_pixel_buffer_object *****// +const + GL_PIXEL_PACK_BUFFER_ARB = $88EB; + GL_PIXEL_UNPACK_BUFFER_ARB = $88EC; + GL_PIXEL_PACK_BUFFER_BINDING_ARB = $88ED; + GL_PIXEL_UNPACK_BUFFER_BINDING_ARB = $88EF; + +function Load_GL_ARB_pixel_buffer_object: Boolean; + +//***** GL_EXT_framebuffer_object *****// +const + GL_FRAMEBUFFER_EXT = $8D40; + GL_RENDERBUFFER_EXT = $8D41; + GL_STENCIL_INDEX_EXT = $8D45; + GL_STENCIL_INDEX1_EXT = $8D46; + GL_STENCIL_INDEX4_EXT = $8D47; + GL_STENCIL_INDEX8_EXT = $8D48; + GL_STENCIL_INDEX16_EXT = $8D49; + GL_RENDERBUFFER_WIDTH_EXT = $8D42; + GL_RENDERBUFFER_HEIGHT_EXT = $8D43; + GL_RENDERBUFFER_INTERNAL_FORMAT_EXT = $8D44; + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = $8CD0; + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT = $8CD1; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT = $8CD2; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT = $8CD3; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT = $8CD4; + GL_COLOR_ATTACHMENT0_EXT = $8CE0; + GL_COLOR_ATTACHMENT1_EXT = $8CE1; + GL_COLOR_ATTACHMENT2_EXT = $8CE2; + GL_COLOR_ATTACHMENT3_EXT = $8CE3; + GL_COLOR_ATTACHMENT4_EXT = $8CE4; + GL_COLOR_ATTACHMENT5_EXT = $8CE5; + GL_COLOR_ATTACHMENT6_EXT = $8CE6; + GL_COLOR_ATTACHMENT7_EXT = $8CE7; + GL_COLOR_ATTACHMENT8_EXT = $8CE8; + GL_COLOR_ATTACHMENT9_EXT = $8CE9; + GL_COLOR_ATTACHMENT10_EXT = $8CEA; + GL_COLOR_ATTACHMENT11_EXT = $8CEB; + GL_COLOR_ATTACHMENT12_EXT = $8CEC; + GL_COLOR_ATTACHMENT13_EXT = $8CED; + GL_COLOR_ATTACHMENT14_EXT = $8CEE; + GL_COLOR_ATTACHMENT15_EXT = $8CEF; + GL_DEPTH_ATTACHMENT_EXT = $8D00; + GL_STENCIL_ATTACHMENT_EXT = $8D20; + GL_FRAMEBUFFER_COMPLETE_EXT = $8CD5; + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT = $8CD6; + GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT = $8CD7; + GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT = $8CD8; + GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT = $8CD9; + GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT = $8CDA; + GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT = $8CDB; + GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT = $8CDC; + GL_FRAMEBUFFER_UNSUPPORTED_EXT = $8CDD; + GL_FRAMEBUFFER_STATUS_ERROR_EXT = $8CDE; + GL_FRAMEBUFFER_BINDING_EXT = $8CA6; + GL_RENDERBUFFER_BINDING_EXT = $8CA7; + GL_MAX_COLOR_ATTACHMENTS_EXT = $8CDF; + GL_MAX_RENDERBUFFER_SIZE_EXT = $84E8; + GL_INVALID_FRAMEBUFFER_OPERATION_EXT = $0506; +var + glIsRenderbufferEXT: function(renderbuffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindRenderbufferEXT: procedure(target: GLenum; renderbuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteRenderbuffersEXT: procedure(n: GLsizei; const renderbuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenRenderbuffersEXT: procedure(n: GLsizei; renderbuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRenderbufferStorageEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetRenderbufferParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsFramebufferEXT: function(framebuffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindFramebufferEXT: procedure(target: GLenum; framebuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteFramebuffersEXT: procedure(n: GLsizei; const framebuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenFramebuffersEXT: procedure(n: GLsizei; framebuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCheckFramebufferStatusEXT: function(target: GLenum): GLenum; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture1DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture2DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture3DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint; zoffset: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferRenderbufferEXT: procedure(target: GLenum; attachment: GLenum; renderbuffertarget: GLenum; renderbuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFramebufferAttachmentParameterivEXT: procedure(target: GLenum; attachment: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenerateMipmapEXT: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_framebuffer_object: Boolean; + +//**** GL_ARB_framebuffer_object *****// +const + GL_INVALID_FRAMEBUFFER_OPERATION = $0506; + GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = $8210; + GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = $8211; + GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE = $8212; + GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = $8213; + GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = $8214; + GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = $8215; + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = $8216; + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = $8217; + GL_FRAMEBUFFER_DEFAULT = $8218; + GL_FRAMEBUFFER_UNDEFINED = $8219; + GL_DEPTH_STENCIL_ATTACHMENT = $821A; + GL_MAX_RENDERBUFFER_SIZE = $84E8; + GL_DEPTH_STENCIL = $84F9; + GL_UNSIGNED_INT_24_8 = $84FA; + GL_DEPTH24_STENCIL8 = $88F0; + GL_TEXTURE_STENCIL_SIZE = $88F1; + GL_TEXTURE_RED_TYPE = $8C10; + GL_TEXTURE_GREEN_TYPE = $8C11; + GL_TEXTURE_BLUE_TYPE = $8C12; + GL_TEXTURE_ALPHA_TYPE = $8C13; + GL_TEXTURE_DEPTH_TYPE = $8C16; + GL_UNSIGNED_NORMALIZED = $8C17; + GL_FRAMEBUFFER_BINDING = $8CA6; + GL_DRAW_FRAMEBUFFER_BINDING = GL_FRAMEBUFFER_BINDING; + GL_RENDERBUFFER_BINDING = $8CA7; + GL_READ_FRAMEBUFFER = $8CA8; + GL_DRAW_FRAMEBUFFER = $8CA9; + GL_READ_FRAMEBUFFER_BINDING = $8CAA; + GL_RENDERBUFFER_SAMPLES = $8CAB; + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = $8CD0; + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = $8CD1; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = $8CD2; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = $8CD3; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = $8CD4; + GL_FRAMEBUFFER_COMPLETE = $8CD5; + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = $8CD6; + GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = $8CD7; + GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = $8CDB; + GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER = $8CDC; + GL_FRAMEBUFFER_UNSUPPORTED = $8CDD; + GL_MAX_COLOR_ATTACHMENTS = $8CDF; + GL_COLOR_ATTACHMENT0 = $8CE0; + GL_COLOR_ATTACHMENT1 = $8CE1; + GL_COLOR_ATTACHMENT2 = $8CE2; + GL_COLOR_ATTACHMENT3 = $8CE3; + GL_COLOR_ATTACHMENT4 = $8CE4; + GL_COLOR_ATTACHMENT5 = $8CE5; + GL_COLOR_ATTACHMENT6 = $8CE6; + GL_COLOR_ATTACHMENT7 = $8CE7; + GL_COLOR_ATTACHMENT8 = $8CE8; + GL_COLOR_ATTACHMENT9 = $8CE9; + GL_COLOR_ATTACHMENT10 = $8CEA; + GL_COLOR_ATTACHMENT11 = $8CEB; + GL_COLOR_ATTACHMENT12 = $8CEC; + GL_COLOR_ATTACHMENT13 = $8CED; + GL_COLOR_ATTACHMENT14 = $8CEE; + GL_COLOR_ATTACHMENT15 = $8CEF; + GL_DEPTH_ATTACHMENT = $8D00; + GL_STENCIL_ATTACHMENT = $8D20; + GL_FRAMEBUFFER = $8D40; + GL_RENDERBUFFER = $8D41; + GL_RENDERBUFFER_WIDTH = $8D42; + GL_RENDERBUFFER_HEIGHT = $8D43; + GL_RENDERBUFFER_INTERNAL_FORMAT = $8D44; + GL_STENCIL_INDEX1 = $8D46; + GL_STENCIL_INDEX4 = $8D47; + GL_STENCIL_INDEX8 = $8D48; + GL_STENCIL_INDEX16 = $8D49; + GL_RENDERBUFFER_RED_SIZE = $8D50; + GL_RENDERBUFFER_GREEN_SIZE = $8D51; + GL_RENDERBUFFER_BLUE_SIZE = $8D52; + GL_RENDERBUFFER_ALPHA_SIZE = $8D53; + GL_RENDERBUFFER_DEPTH_SIZE = $8D54; + GL_RENDERBUFFER_STENCIL_SIZE = $8D55; + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = $8D56; + GL_MAX_SAMPLES = $8D57; +var + glIsRenderbuffer: function(renderbuffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindRenderbuffer: procedure(target: GLenum; renderbuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteRenderbuffers: procedure(n: GLsizei; const renderbuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenRenderbuffers: procedure(n: GLsizei; renderbuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRenderbufferStorage: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetRenderbufferParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsFramebuffer: function(framebuffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindFramebuffer: procedure(target: GLenum; framebuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteFramebuffers: procedure(n: GLsizei; const framebuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenFramebuffers: procedure(n: GLsizei; framebuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCheckFramebufferStatus: function(target: GLenum): GLenum; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture1D: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture2D: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture3D: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint; zoffset: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferRenderbuffer: procedure(target: GLenum; attachment: GLenum; renderbuffertarget: GLenum; renderbuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFramebufferAttachmentParameteriv: procedure(target: GLenum; attachment: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenerateMipmap: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBlitFramebuffer: procedure(srcX0: GLint; srcY0: GLint; srcX1: GLint; srcY1: GLint; dstX0: GLint; dstY0: GLint; dstX1: GLint; dstY1: GLint; mask: GLbitfield; filter: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRenderbufferStorageMultisample: procedure(target: GLenum; samples: GLsizei; internalformat: GLenum; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTextureLayer: procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint; layer: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_framebuffer_object(): Boolean; + +//**** GL_ARB_framebuffer_object DEPRECATED *****// +const + GL_INDEX = $8222; + GL_TEXTURE_LUMINANCE_TYPE = $8C14; + GL_TEXTURE_INTENSITY_TYPE = $8C15; + + +//**** GL_ARB_map_buffer_range *****// +const + GL_MAP_READ_BIT = $0001; + GL_MAP_WRITE_BIT = $0002; + GL_MAP_INVALIDATE_RANGE_BIT = $0004; + GL_MAP_INVALIDATE_BUFFER_BIT = $0008; + GL_MAP_FLUSH_EXPLICIT_BIT = $0010; + GL_MAP_UNSYNCHRONIZED_BIT = $0020; +var + glMapBufferRange: function(target: GLenum; offset: GLintptr; length: GLsizeiptr; access: GLbitfield): PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFlushMappedBufferRange: procedure(target: GLenum; offset: GLintptr; length: GLsizeiptr); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_map_buffer_range(): Boolean; + +//**** GL_ARB_vertex_array_object *****// +const + GL_VERTEX_ARRAY_BINDING = $85B5; +var + glBindVertexArray: procedure(_array: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteVertexArrays: procedure(n: GLsizei; const arrays: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenVertexArrays: procedure(n: GLsizei; arrays: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsVertexArray: function(_array: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_vertex_array_object(): Boolean; + +//**** GL_ARB_copy_buffer *****// +const + GL_COPY_READ_BUFFER = $8F36; + GL_COPY_WRITE_BUFFER = $8F37; +var + glCopyBufferSubData: procedure(readTarget: GLenum; writeTarget: GLenum; readOffset: GLintptr; writeOffset: GLintptr; size: GLsizeiptr); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_copy_buffer(): Boolean; + +//**** GL_ARB_uniform_buffer_object *****// +const + GL_UNIFORM_BUFFER = $8A11; + GL_UNIFORM_BUFFER_BINDING = $8A28; + GL_UNIFORM_BUFFER_START = $8A29; + GL_UNIFORM_BUFFER_SIZE = $8A2A; + GL_MAX_VERTEX_UNIFORM_BLOCKS = $8A2B; + GL_MAX_GEOMETRY_UNIFORM_BLOCKS = $8A2C; + GL_MAX_FRAGMENT_UNIFORM_BLOCKS = $8A2D; + GL_MAX_COMBINED_UNIFORM_BLOCKS = $8A2E; + GL_MAX_UNIFORM_BUFFER_BINDINGS = $8A2F; + GL_MAX_UNIFORM_BLOCK_SIZE = $8A30; + GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = $8A31; + GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS = $8A32; + GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = $8A33; + GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = $8A34; + GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH = $8A35; + GL_ACTIVE_UNIFORM_BLOCKS = $8A36; + GL_UNIFORM_TYPE = $8A37; + GL_UNIFORM_SIZE = $8A38; + GL_UNIFORM_NAME_LENGTH = $8A39; + GL_UNIFORM_BLOCK_INDEX = $8A3A; + GL_UNIFORM_OFFSET = $8A3B; + GL_UNIFORM_ARRAY_STRIDE = $8A3C; + GL_UNIFORM_MATRIX_STRIDE = $8A3D; + GL_UNIFORM_IS_ROW_MAJOR = $8A3E; + GL_UNIFORM_BLOCK_BINDING = $8A3F; + GL_UNIFORM_BLOCK_DATA_SIZE = $8A40; + GL_UNIFORM_BLOCK_NAME_LENGTH = $8A41; + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = $8A42; + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = $8A43; + GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = $8A44; + GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = $8A45; + GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = $8A46; + GL_INVALID_INDEX = DWord($FFFFFFFF); +var + glGetUniformIndices: procedure(_program: GLuint; uniformCount: GLsizei; const uniformNames: PPGLchar; uniformIndices: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniformsiv: procedure(_program: GLuint; uniformCount: GLsizei; const uniformIndices: PGLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniformName: procedure(_program: GLuint; uniformIndex: GLuint; bufSize: GLsizei; length: PGLsizei; uniformName: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformBlockIndex: function(_program: GLuint; const uniformBlockName: PGLchar): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniformBlockiv: procedure(_program: GLuint; uniformBlockIndex: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniformBlockName: procedure(_program: GLuint; uniformBlockIndex: GLuint; bufSize: GLsizei; length: PGLsizei; uniformBlockName: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformBlockBinding: procedure(_program: GLuint; uniformBlockIndex: GLuint; uniformBlockBinding: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_uniform_buffer_object(): Boolean; + +//**** GL_ARB_draw_elements_base_vertex *****// +var + glDrawElementsBaseVertex: procedure(mode: GLenum; count: GLsizei; _type: GLenum; const indices: PGLvoid; basevertex: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawRangeElementsBaseVertex: procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei; _type: GLenum; const indices: PGLvoid; basevertex: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElementsInstancedBaseVertex: procedure(mode: GLenum; count: GLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei; basevertex: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawElementsBaseVertex: procedure(mode: GLenum; const count: PGLsizei; _type: GLenum; const indices: PPGLvoid; primcount: GLsizei; const basevertex: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_draw_elements_base_vertex(): Boolean; + +//**** GL_ARB_provoking_vertex *****// +const + GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = $8E4C; + GL_FIRST_VERTEX_CONVENTION = $8E4D; + GL_LAST_VERTEX_CONVENTION = $8E4E; + GL_PROVOKING_VERTEX = $8E4F; +var + glProvokingVertex: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_provoking_vertex(): Boolean; + +//**** GL_ARB_sync *****// +type + GLsync = Pointer; + TGLsync = GLSync; + PGLsync = ^GLSync; + +const + GL_MAX_SERVER_WAIT_TIMEOUT = $9111; + GL_OBJECT_TYPE = $9112; + GL_SYNC_CONDITION = $9113; + GL_SYNC_STATUS = $9114; + GL_SYNC_FLAGS = $9115; + GL_SYNC_FENCE = $9116; + GL_SYNC_GPU_COMMANDS_COMPLETE = $9117; + GL_UNSIGNALED = $9118; + GL_SIGNALED = $9119; + GL_ALREADY_SIGNALED = $911A; + GL_TIMEOUT_EXPIRED = $911B; + GL_CONDITION_SATISFIED = $911C; + GL_WAIT_FAILED = $911D; + GL_SYNC_FLUSH_COMMANDS_BIT = $00000001; + GL_TIMEOUT_IGNORED = QWord($FFFFFFFFFFFFFFFF); +var + glFenceSync: function(condition: GLenum; flags: GLbitfield): GLsync; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsSync: function(sync: GLsync): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteSync: procedure(sync: GLsync); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClientWaitSync: function(sync: GLsync; flags: GLbitfield; timeout: GLuint64): GLenum; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWaitSync: procedure(sync: GLsync; flags: GLbitfield; timeout: GLuint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetInteger64v: procedure(pname: GLenum; params: PGLint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSynciv: procedure(sync: GLsync; pname: GLenum; bufSize: GLsizei; length: PGLsizei; values: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_sync(): Boolean; + +//**** GL_ARB_texture_multisample *****// +const + GL_SAMPLE_POSITION = $8E50; + GL_SAMPLE_MASK = $8E51; + GL_SAMPLE_MASK_VALUE = $8E52; + GL_MAX_SAMPLE_MASK_WORDS = $8E59; + GL_TEXTURE_2D_MULTISAMPLE = $9100; + GL_PROXY_TEXTURE_2D_MULTISAMPLE = $9101; + GL_TEXTURE_2D_MULTISAMPLE_ARRAY = $9102; + GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY = $9103; + GL_TEXTURE_BINDING_2D_MULTISAMPLE = $9104; + GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY = $9105; + GL_TEXTURE_SAMPLES = $9106; + GL_TEXTURE_FIXED_SAMPLE_LOCATIONS = $9107; + GL_SAMPLER_2D_MULTISAMPLE = $9108; + GL_INT_SAMPLER_2D_MULTISAMPLE = $9109; + GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = $910A; + GL_SAMPLER_2D_MULTISAMPLE_ARRAY = $910B; + GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = $910C; + GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = $910D; + GL_MAX_COLOR_TEXTURE_SAMPLES = $910E; + GL_MAX_DEPTH_TEXTURE_SAMPLES = $910F; + GL_MAX_INTEGER_SAMPLES = $9110; +var + glTexImage2DMultisample: procedure(target: GLenum; samples: GLsizei; internalformat: GLint; width: GLsizei; height: GLsizei; fixedsamplelocations: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexImage3DMultisample: procedure(target: GLenum; samples: GLsizei; internalformat: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; fixedsamplelocations: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMultisamplefv: procedure(pname: GLenum; index: GLuint; val: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSampleMaski: procedure(index: GLuint; mask: GLbitfield); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_texture_multisample(): Boolean; + +//**** GL_ARB_blend_func_extended *****// +const + GL_SRC1_COLOR = $88F9; +// reuse GL_SRC1_ALPHA +const + GL_ONE_MINUS_SRC1_COLOR = $88FA; + GL_ONE_MINUS_SRC1_ALPHA = $88FB; + GL_MAX_DUAL_SOURCE_DRAW_BUFFERS = $88FC; +var + glBindFragDataLocationIndexed: procedure(_program: GLuint; colorNumber: GLuint; index: GLuint; const name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFragDataIndex: function(_program: GLuint; const name: PGLchar): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_blend_func_extended(): Boolean; + +//**** GL_ARB_sampler_objects *****// +const + GL_SAMPLER_BINDING = $8919; +var + glGenSamplers: procedure(count: GLsizei; samplers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteSamplers: procedure(count: GLsizei; const samplers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsSampler: function(sampler: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindSampler: procedure(_unit: GLenum; sampler: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameteri: procedure(sampler: GLuint; pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameteriv: procedure(sampler: GLuint; pname: GLenum; const param: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameterf: procedure(sampler: GLuint; pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameterfv: procedure(sampler: GLuint; pname: GLenum; const param: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameterIiv: procedure(sampler: GLuint; pname: GLenum; const param: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameterIuiv: procedure(sampler: GLuint; pname: GLenum; const param: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSamplerParameteriv: procedure(sampler: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSamplerParameterIiv: procedure(sampler: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSamplerParameterfv: procedure(sampler: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSamplerParameterIfv: procedure(sampler: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_sampler_objects(): Boolean; + +//**** GL_ARB_timer_query *****// +const + GL_TIME_ELAPSED = $88BF; + GL_TIMESTAMP = $8E28; +var + glQueryCounter: procedure(id: GLuint; target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjecti64v: procedure(id: GLuint; pname: GLenum; params: PGLint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjectui64v: procedure(id: GLuint; pname: GLenum; params: PGLuint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_timer_query(): Boolean; + +//**** GL_ARB_vertex_type_2_10_10_10_rev *****// + +const + GL_INT_2_10_10_10_REV = $8D9F; +var + glVertexP2ui: procedure(_type: GLenum; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexP2uiv: procedure(_type: GLenum; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexP3ui: procedure(_type: GLenum; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexP3uiv: procedure(_type: GLenum; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexP4ui: procedure(_type: GLenum; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexP4uiv: procedure(_type: GLenum; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP1ui: procedure(_type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP1uiv: procedure(_type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP2ui: procedure(_type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP2uiv: procedure(_type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP3ui: procedure(_type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP3uiv: procedure(_type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP4ui: procedure(_type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP4uiv: procedure(_type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP1ui: procedure(texture: GLenum; _type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP1uiv: procedure(texture: GLenum; _type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP2ui: procedure(texture: GLenum; _type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP2uiv: procedure(texture: GLenum; _type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP3ui: procedure(texture: GLenum; _type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP3uiv: procedure(texture: GLenum; _type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP4ui: procedure(texture: GLenum; _type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP4uiv: procedure(texture: GLenum; _type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalP3ui: procedure(_type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalP3uiv: procedure(_type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorP3ui: procedure(_type: GLenum; color: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorP3uiv: procedure(_type: GLenum; const color: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorP4ui: procedure(_type: GLenum; color: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorP4uiv: procedure(_type: GLenum; const color: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColorP3ui: procedure(_type: GLenum; color: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColorP3uiv: procedure(_type: GLenum; const color: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP1ui: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP1uiv: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP2ui: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP2uiv: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP3ui: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP3uiv: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP4ui: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP4uiv: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_vertex_type_2_10_10_10_rev(): Boolean; + +//**** GL_ARB_gpu_shader_fp64 *****// +// reuse GL_DOUBLE +const + GL_DOUBLE_VEC2 = $8FFC; + GL_DOUBLE_VEC3 = $8FFD; + GL_DOUBLE_VEC4 = $8FFE; + GL_DOUBLE_MAT2 = $8F46; + GL_DOUBLE_MAT3 = $8F47; + GL_DOUBLE_MAT4 = $8F48; + GL_DOUBLE_MAT2x3 = $8F49; + GL_DOUBLE_MAT2x4 = $8F4A; + GL_DOUBLE_MAT3x2 = $8F4B; + GL_DOUBLE_MAT3x4 = $8F4C; + GL_DOUBLE_MAT4x2 = $8F4D; + GL_DOUBLE_MAT4x3 = $8F4E; +var + glUniform1d: procedure(location: GLint; x: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2d: procedure(location: GLint; x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3d: procedure(location: GLint; x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4d: procedure(location: GLint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1dv: procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2dv: procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3dv: procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4dv: procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2x3dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2x4dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3x2dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3x4dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4x2dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4x3dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformdv: procedure(_program: GLuint; location: GLint; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform1dEXT: procedure(_program: GLuint; location: GLint; x: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform2dEXT: procedure(_program: GLuint; location: GLint; x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform3dEXT: procedure(_program: GLuint; location: GLint; x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform4dEXT: procedure(_program: GLuint; location: GLint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform1dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform2dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform3dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform4dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix2dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix3dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix4dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix2x3dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix2x4dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix3x2dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix3x4dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix4x2dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix4x3dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_gpu_shader_fp64(): Boolean; + +//**** GL_ARB_shader_subroutine *****// +const + GL_ACTIVE_SUBROUTINES = $8DE5; + GL_ACTIVE_SUBROUTINE_UNIFORMS = $8DE6; + GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS = $8E47; + GL_ACTIVE_SUBROUTINE_MAX_LENGTH = $8E48; + GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH = $8E49; + GL_MAX_SUBROUTINES = $8DE7; + GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS = $8DE8; + GL_NUM_COMPATIBLE_SUBROUTINES = $8E4A; + GL_COMPATIBLE_SUBROUTINES = $8E4B; + +var + glGetSubroutineUniformLocation: function(_program: GLuint; shadertype: GLenum; const name: PGLchar): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSubroutineIndex: function(_program: GLuint; shadertype: GLenum; const name: PGLchar): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveSubroutineUniformiv: procedure(_program: GLuint; shadertype: GLenum; index: GLuint; pname: GLenum; values: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveSubroutineUniformName: procedure(_program: GLuint; shadertype: GLenum; index: GLuint; bufsize: GLsizei; length: PGLsizei; name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveSubroutineName: procedure(_program: GLuint; shadertype: GLenum; index: GLuint; bufsize: GLsizei; length: PGLsizei; name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformSubroutinesuiv: procedure(shadertype: GLenum; count: GLsizei; const indices: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformSubroutineuiv: procedure(shadertype: GLenum; location: GLint; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramStageiv: procedure(_program: GLuint; shadertype: GLenum; pname: GLenum; values: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_shader_subroutine(): Boolean; + +//**** GL_ARB_tessellation_shader *****// +const + GL_PATCHES = $000E; + GL_PATCH_VERTICES = $8E72; + GL_PATCH_DEFAULT_INNER_LEVEL = $8E73; + GL_PATCH_DEFAULT_OUTER_LEVEL = $8E74; + GL_TESS_CONTROL_OUTPUT_VERTICES = $8E75; + GL_TESS_GEN_MODE = $8E76; + GL_TESS_GEN_SPACING = $8E77; + GL_TESS_GEN_VERTEX_ORDER = $8E78; + GL_TESS_GEN_POINT_MODE = $8E79; +// reuse GL_TRIANGLES +// reuse GL_QUADS +const + GL_ISOLINES = $8E7A; +// reuse GL_EQUAL +const + GL_FRACTIONAL_ODD = $8E7B; + GL_FRACTIONAL_EVEN = $8E7C; +// reuse GL_CCW +// reuse GL_CW +const + GL_MAX_PATCH_VERTICES = $8E7D; + GL_MAX_TESS_GEN_LEVEL = $8E7E; + GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS = $8E7F; + GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS = $8E80; + GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS = $8E81; + GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS = $8E82; + GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS = $8E83; + GL_MAX_TESS_PATCH_COMPONENTS = $8E84; + GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS = $8E85; + GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS = $8E86; + GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS = $8E89; + GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS = $8E8A; + GL_MAX_TESS_CONTROL_INPUT_COMPONENTS = $886C; + GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS = $886D; + GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS = $8E1E; + GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS = $8E1F; + GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER = $84F0; + GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER = $84F1; + GL_TESS_EVALUATION_SHADER = $8E87; + GL_TESS_CONTROL_SHADER = $8E88; +var + glPatchParameteri: procedure(pname: GLenum; value: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPatchParameterfv: procedure(pname: GLenum; const values: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_tessellation_shader(): Boolean; + +//**** GL_ARB_transform_feedback2 *****// +const + GL_TRANSFORM_FEEDBACK = $8E22; + GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED = $8E23; + GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE = $8E24; + GL_TRANSFORM_FEEDBACK_BINDING = $8E25; +var + glBindTransformFeedback: procedure(target: GLenum; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteTransformFeedbacks: procedure(n: GLsizei; const ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenTransformFeedbacks: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsTransformFeedback: function(id: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPauseTransformFeedback: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glResumeTransformFeedback: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawTransformFeedback: procedure(mode: GLenum; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_transform_feedback2(): Boolean; + +//**** GL_ARB_transform_feedback3 *****// +const + GL_MAX_TRANSFORM_FEEDBACK_BUFFERS = $8E70; +var + glDrawTransformFeedbackStream: procedure(mode: GLenum; id: GLuint; stream: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginQueryIndexed: procedure(target: GLenum; index: GLuint; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndQueryIndexed: procedure(target: GLenum; index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryIndexediv: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_transform_feedback3(): Boolean; + + +//***** GL_version_1_4 *****// +const + GL_BLEND_DST_RGB = $80C8; + GL_BLEND_SRC_RGB = $80C9; + GL_BLEND_DST_ALPHA = $80CA; + GL_BLEND_SRC_ALPHA = $80CB; + GL_POINT_SIZE_MIN = $8126; + GL_POINT_SIZE_MAX = $8127; + GL_POINT_FADE_THRESHOLD_SIZE = $8128; + GL_POINT_DISTANCE_ATTENUATION = $8129; + GL_GENERATE_MIPMAP = $8191; + GL_GENERATE_MIPMAP_HINT = $8192; + GL_DEPTH_COMPONENT16 = $81A5; + GL_DEPTH_COMPONENT24 = $81A6; + GL_DEPTH_COMPONENT32 = $81A7; + GL_MIRRORED_REPEAT = $8370; + GL_FOG_COORDINATE_SOURCE = $8450; + GL_FOG_COORDINATE = $8451; + GL_FRAGMENT_DEPTH = $8452; + GL_CURRENT_FOG_COORDINATE = $8453; + GL_FOG_COORDINATE_ARRAY_TYPE = $8454; + GL_FOG_COORDINATE_ARRAY_STRIDE = $8455; + GL_FOG_COORDINATE_ARRAY_POINTER = $8456; + GL_FOG_COORDINATE_ARRAY = $8457; + GL_COLOR_SUM = $8458; + GL_CURRENT_SECONDARY_COLOR = $8459; + GL_SECONDARY_COLOR_ARRAY_SIZE = $845A; + GL_SECONDARY_COLOR_ARRAY_TYPE = $845B; + GL_SECONDARY_COLOR_ARRAY_STRIDE = $845C; + GL_SECONDARY_COLOR_ARRAY_POINTER = $845D; + GL_SECONDARY_COLOR_ARRAY = $845E; + GL_MAX_TEXTURE_LOD_BIAS = $84FD; + GL_TEXTURE_FILTER_CONTROL = $8500; + GL_TEXTURE_LOD_BIAS = $8501; + GL_INCR_WRAP = $8507; + GL_DECR_WRAP = $8508; + GL_TEXTURE_DEPTH_SIZE = $884A; + GL_DEPTH_TEXTURE_MODE = $884B; + GL_TEXTURE_COMPARE_MODE = $884C; + GL_TEXTURE_COMPARE_FUNC = $884D; + GL_COMPARE_R_TO_TEXTURE = $884E; +var + glBlendFuncSeparate: procedure(sfactorRGB: GLenum; dfactorRGB: GLenum; sfactorAlpha: GLenum; dfactorAlpha: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordf: procedure(coord: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordfv: procedure(const coord: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordd: procedure(coord: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoorddv: procedure(const coord: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordPointer: procedure(_type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawArrays: procedure(mode: GLenum; first: PGLint; count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawElements: procedure(mode: GLenum; const count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameterf: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameterfv: procedure(pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameteri: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameteriv: procedure(pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3b: procedure(red: GLbyte; green: GLbyte; blue: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3bv: procedure(const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3d: procedure(red: GLdouble; green: GLdouble; blue: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3f: procedure(red: GLfloat; green: GLfloat; blue: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3i: procedure(red: GLint; green: GLint; blue: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3s: procedure(red: GLshort; green: GLshort; blue: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ub: procedure(red: GLubyte; green: GLubyte; blue: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ubv: procedure(const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ui: procedure(red: GLuint; green: GLuint; blue: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3uiv: procedure(const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3us: procedure(red: GLushort; green: GLushort; blue: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3usv: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColorPointer: procedure(size: GLint; _type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2d: procedure(x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2f: procedure(x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2i: procedure(x: GLint; y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2s: procedure(x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3d: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3f: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3i: procedure(x: GLint; y: GLint; z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3s: procedure(x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_version_1_4: Boolean; + +//***** GL_version_1_5 *****// +const + GL_BUFFER_SIZE = $8764; + GL_BUFFER_USAGE = $8765; + GL_QUERY_COUNTER_BITS = $8864; + GL_CURRENT_QUERY = $8865; + GL_QUERY_RESULT = $8866; + GL_QUERY_RESULT_AVAILABLE = $8867; + GL_ARRAY_BUFFER = $8892; + GL_ELEMENT_ARRAY_BUFFER = $8893; + GL_ARRAY_BUFFER_BINDING = $8894; + GL_ELEMENT_ARRAY_BUFFER_BINDING = $8895; + GL_VERTEX_ARRAY_BUFFER_BINDING = $8896; + GL_NORMAL_ARRAY_BUFFER_BINDING = $8897; + GL_COLOR_ARRAY_BUFFER_BINDING = $8898; + GL_INDEX_ARRAY_BUFFER_BINDING = $8899; + GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING = $889A; + GL_EDGE_FLAG_ARRAY_BUFFER_BINDING = $889B; + GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING = $889C; + GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING = $889D; + GL_WEIGHT_ARRAY_BUFFER_BINDING = $889E; + GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = $889F; + GL_READ_ONLY = $88B8; + GL_WRITE_ONLY = $88B9; + GL_READ_WRITE = $88BA; + GL_BUFFER_ACCESS = $88BB; + GL_BUFFER_MAPPED = $88BC; + GL_BUFFER_MAP_POINTER = $88BD; + GL_STREAM_DRAW = $88E0; + GL_STREAM_READ = $88E1; + GL_STREAM_COPY = $88E2; + GL_STATIC_DRAW = $88E4; + GL_STATIC_READ = $88E5; + GL_STATIC_COPY = $88E6; + GL_DYNAMIC_DRAW = $88E8; + GL_DYNAMIC_READ = $88E9; + GL_DYNAMIC_COPY = $88EA; + GL_SAMPLES_PASSED = $8914; + GL_FOG_COORD_SRC = $8450; + GL_FOG_COORD = $8451; + GL_CURRENT_FOG_COORD = $8453; + GL_FOG_COORD_ARRAY_TYPE = $8454; + GL_FOG_COORD_ARRAY_STRIDE = $8455; + GL_FOG_COORD_ARRAY_POINTER = $8456; + GL_FOG_COORD_ARRAY = $8457; + GL_FOG_COORD_ARRAY_BUFFER_BINDING = $889D; + GL_SRC0_RGB = $8580; + GL_SRC1_RGB = $8581; + GL_SRC2_RGB = $8582; + GL_SRC0_ALPHA = $8588; + GL_SRC1_ALPHA = $8589; + GL_SRC2_ALPHA = $858A; +var + glGenQueries: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteQueries: procedure(n: GLsizei; const ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsQuery: function(id: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginQuery: procedure(target: GLenum; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndQuery: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryiv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjectiv: procedure(id: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjectuiv: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindBuffer: procedure(target: GLenum; buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteBuffers: procedure(n: GLsizei; const buffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenBuffers: procedure(n: GLsizei; buffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsBuffer: function(buffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBufferData: procedure(target: GLenum; size: GLsizeiptr; const data: PGLvoid; usage: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBufferSubData: procedure(target: GLenum; offset: GLintptr; size: GLsizeiptr; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferSubData: procedure(target: GLenum; offset: GLintptr; size: GLsizeiptr; data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapBuffer: function(target: GLenum; access: GLenum): PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUnmapBuffer: function(target: GLenum): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferPointerv: procedure(target: GLenum; pname: GLenum; params: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_version_1_5: Boolean; + +//***** GL_version_2_0 *****// +const + GL_BLEND_EQUATION_RGB = $8009; + GL_VERTEX_ATTRIB_ARRAY_ENABLED = $8622; + GL_VERTEX_ATTRIB_ARRAY_SIZE = $8623; + GL_VERTEX_ATTRIB_ARRAY_STRIDE = $8624; + GL_VERTEX_ATTRIB_ARRAY_TYPE = $8625; + GL_CURRENT_VERTEX_ATTRIB = $8626; + GL_VERTEX_PROGRAM_POINT_SIZE = $8642; + GL_VERTEX_PROGRAM_TWO_SIDE = $8643; + GL_VERTEX_ATTRIB_ARRAY_POINTER = $8645; + GL_STENCIL_BACK_FUNC = $8800; + GL_STENCIL_BACK_FAIL = $8801; + GL_STENCIL_BACK_PASS_DEPTH_FAIL = $8802; + GL_STENCIL_BACK_PASS_DEPTH_PASS = $8803; + GL_MAX_DRAW_BUFFERS = $8824; + GL_DRAW_BUFFER0 = $8825; + GL_DRAW_BUFFER1 = $8826; + GL_DRAW_BUFFER2 = $8827; + GL_DRAW_BUFFER3 = $8828; + GL_DRAW_BUFFER4 = $8829; + GL_DRAW_BUFFER5 = $882A; + GL_DRAW_BUFFER6 = $882B; + GL_DRAW_BUFFER7 = $882C; + GL_DRAW_BUFFER8 = $882D; + GL_DRAW_BUFFER9 = $882E; + GL_DRAW_BUFFER10 = $882F; + GL_DRAW_BUFFER11 = $8830; + GL_DRAW_BUFFER12 = $8831; + GL_DRAW_BUFFER13 = $8832; + GL_DRAW_BUFFER14 = $8833; + GL_DRAW_BUFFER15 = $8834; + GL_BLEND_EQUATION_ALPHA = $883D; + GL_POINT_SPRITE = $8861; + GL_COORD_REPLACE = $8862; + GL_MAX_VERTEX_ATTRIBS = $8869; + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED = $886A; + GL_MAX_TEXTURE_COORDS = $8871; + GL_MAX_TEXTURE_IMAGE_UNITS = $8872; + GL_FRAGMENT_SHADER = $8B30; + GL_VERTEX_SHADER = $8B31; + GL_MAX_FRAGMENT_UNIFORM_COMPONENTS = $8B49; + GL_MAX_VERTEX_UNIFORM_COMPONENTS = $8B4A; + GL_MAX_VARYING_FLOATS = $8B4B; + GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = $8B4C; + GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = $8B4D; + GL_SHADER_TYPE = $8B4F; + GL_FLOAT_VEC2 = $8B50; + GL_FLOAT_VEC3 = $8B51; + GL_FLOAT_VEC4 = $8B52; + GL_INT_VEC2 = $8B53; + GL_INT_VEC3 = $8B54; + GL_INT_VEC4 = $8B55; + GL_BOOL = $8B56; + GL_BOOL_VEC2 = $8B57; + GL_BOOL_VEC3 = $8B58; + GL_BOOL_VEC4 = $8B59; + GL_FLOAT_MAT2 = $8B5A; + GL_FLOAT_MAT3 = $8B5B; + GL_FLOAT_MAT4 = $8B5C; + GL_SAMPLER_1D = $8B5D; + GL_SAMPLER_2D = $8B5E; + GL_SAMPLER_3D = $8B5F; + GL_SAMPLER_CUBE = $8B60; + GL_SAMPLER_1D_SHADOW = $8B61; + GL_SAMPLER_2D_SHADOW = $8B62; + GL_DELETE_STATUS = $8B80; + GL_COMPILE_STATUS = $8B81; + GL_LINK_STATUS = $8B82; + GL_VALIDATE_STATUS = $8B83; + GL_INFO_LOG_LENGTH = $8B84; + GL_ATTACHED_SHADERS = $8B85; + GL_ACTIVE_UNIFORMS = $8B86; + GL_ACTIVE_UNIFORM_MAX_LENGTH = $8B87; + GL_SHADER_SOURCE_LENGTH = $8B88; + GL_ACTIVE_ATTRIBUTES = $8B89; + GL_ACTIVE_ATTRIBUTE_MAX_LENGTH = $8B8A; + GL_FRAGMENT_SHADER_DERIVATIVE_HINT = $8B8B; + GL_SHADING_LANGUAGE_VERSION = $8B8C; + GL_CURRENT_PROGRAM = $8B8D; + GL_POINT_SPRITE_COORD_ORIGIN = $8CA0; + GL_LOWER_LEFT = $8CA1; + GL_UPPER_LEFT = $8CA2; + GL_STENCIL_BACK_REF = $8CA3; + GL_STENCIL_BACK_VALUE_MASK = $8CA4; + GL_STENCIL_BACK_WRITEMASK = $8CA5; +var + glBlendEquationSeparate: procedure(modeRGB: GLenum; modeAlpha: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawBuffers: procedure(n: GLsizei; const bufs: PGLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilOpSeparate: procedure(face: GLenum; sfail: GLenum; dpfail: GLenum; dppass: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilFuncSeparate: procedure(frontfunc: GLenum; backfunc: GLenum; ref: GLint; mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilMaskSeparate: procedure(face: GLenum; mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAttachShader: procedure(_program: GLuint; shader: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindAttribLocation: procedure(_program: GLuint; index: GLuint; const name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompileShader: procedure(shader: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCreateProgram: function(): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCreateShader: function(_type: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteProgram: procedure(_program: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteShader: procedure(shader: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDetachShader: procedure(_program: GLuint; shader: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisableVertexAttribArray: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnableVertexAttribArray: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveAttrib: procedure(_program: GLuint; index: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniform: procedure(_program: GLuint; index: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetAttachedShaders: procedure(_program: GLuint; maxCount: GLsizei; count: PGLsizei; obj: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetAttribLocation: function(_program: GLuint; const name: PGLchar): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramiv: procedure(_program: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramInfoLog: procedure(_program: GLuint; bufSize: GLsizei; length: PGLsizei; infoLog: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetShaderiv: procedure(shader: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetShaderInfoLog: procedure(shader: GLuint; bufSize: GLsizei; length: PGLsizei; infoLog: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetShaderSource: procedure(shader: GLuint; bufSize: GLsizei; length: PGLsizei; source: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformLocation: function(_program: GLuint; const name: PGLchar): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformfv: procedure(_program: GLuint; location: GLint; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformiv: procedure(_program: GLuint; location: GLint; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribdv: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribfv: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribiv: procedure(index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribPointerv: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsProgram: function(_program: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsShader: function(shader: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLinkProgram: procedure(_program: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShaderSource: procedure(shader: GLuint; count: GLsizei; const _string: PGLchar; const length: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUseProgram: procedure(_program: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1f: procedure(location: GLint; v0: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2f: procedure(location: GLint; v0: GLfloat; v1: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3f: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4f: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat; v3: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1i: procedure(location: GLint; v0: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2i: procedure(location: GLint; v0: GLint; v1: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3i: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4i: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint; v3: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glValidateProgram: procedure(_program: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1d: procedure(index: GLuint; x: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1dv: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1f: procedure(index: GLuint; x: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1fv: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1s: procedure(index: GLuint; x: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1sv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2d: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2dv: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2f: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2fv: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2s: procedure(index: GLuint; x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2sv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3d: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3dv: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3f: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3fv: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3s: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3sv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nbv: procedure(index: GLuint; const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Niv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nsv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nub: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nubv: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nuiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nusv: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4bv: procedure(index: GLuint; const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4d: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4dv: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4f: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4fv: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4iv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4s: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4sv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4ubv: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4uiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4usv: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribPointer: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_version_2_0: Boolean; + +//**** GL_VERSION_2_1 *****// +const + GL_PIXEL_PACK_BUFFER = $88EB; + GL_PIXEL_UNPACK_BUFFER = $88EC; + GL_PIXEL_PACK_BUFFER_BINDING = $88ED; + GL_PIXEL_UNPACK_BUFFER_BINDING = $88EF; + GL_FLOAT_MAT2x3 = $8B65; + GL_FLOAT_MAT2x4 = $8B66; + GL_FLOAT_MAT3x2 = $8B67; + GL_FLOAT_MAT3x4 = $8B68; + GL_FLOAT_MAT4x2 = $8B69; + GL_FLOAT_MAT4x3 = $8B6A; + GL_SRGB = $8C40; + GL_SRGB8 = $8C41; + GL_SRGB_ALPHA = $8C42; + GL_SRGB8_ALPHA8 = $8C43; + GL_COMPRESSED_SRGB = $8C48; + GL_COMPRESSED_SRGB_ALPHA = $8C49; +var + glUniformMatrix2x3fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3x2fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2x4fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4x2fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3x4fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4x3fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_VERSION_2_1(): Boolean; + +//**** GL_VERSION_2_1 DEPRECATED *****// +const + GL_CURRENT_RASTER_SECONDARY_COLOR = $845F; + GL_SLUMINANCE_ALPHA = $8C44; + GL_SLUMINANCE8_ALPHA8 = $8C45; + GL_SLUMINANCE = $8C46; + GL_SLUMINANCE8 = $8C47; + GL_COMPRESSED_SLUMINANCE = $8C4A; + GL_COMPRESSED_SLUMINANCE_ALPHA = $8C4B; + +//**** GL_VERSION_3_0 *****// + +const + GL_COMPARE_REF_TO_TEXTURE = $884E; + GL_CLIP_DISTANCE0 = $3000; + GL_CLIP_DISTANCE1 = $3001; + GL_CLIP_DISTANCE2 = $3002; + GL_CLIP_DISTANCE3 = $3003; + GL_CLIP_DISTANCE4 = $3004; + GL_CLIP_DISTANCE5 = $3005; + GL_CLIP_DISTANCE6 = $3006; + GL_CLIP_DISTANCE7 = $3007; + GL_MAX_CLIP_DISTANCES = $0D32; + GL_MAJOR_VERSION = $821B; + GL_MINOR_VERSION = $821C; + GL_NUM_EXTENSIONS = $821D; + GL_CONTEXT_FLAGS = $821E; + GL_DEPTH_BUFFER = $8223; + GL_STENCIL_BUFFER = $8224; + GL_COMPRESSED_RED = $8225; + GL_COMPRESSED_RG = $8226; + GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT = $0001; + GL_RGBA32F = $8814; + GL_RGB32F = $8815; + GL_RGBA16F = $881A; + GL_RGB16F = $881B; + GL_VERTEX_ATTRIB_ARRAY_INTEGER = $88FD; + GL_MAX_ARRAY_TEXTURE_LAYERS = $88FF; + GL_MIN_PROGRAM_TEXEL_OFFSET = $8904; + GL_MAX_PROGRAM_TEXEL_OFFSET = $8905; + GL_CLAMP_READ_COLOR = $891C; + GL_FIXED_ONLY = $891D; + GL_MAX_VARYING_COMPONENTS = $8B4B; + GL_TEXTURE_1D_ARRAY = $8C18; + GL_PROXY_TEXTURE_1D_ARRAY = $8C19; + GL_TEXTURE_2D_ARRAY = $8C1A; + GL_PROXY_TEXTURE_2D_ARRAY = $8C1B; + GL_TEXTURE_BINDING_1D_ARRAY = $8C1C; + GL_TEXTURE_BINDING_2D_ARRAY = $8C1D; + GL_R11F_G11F_B10F = $8C3A; + GL_UNSIGNED_INT_10F_11F_11F_REV = $8C3B; + GL_RGB9_E5 = $8C3D; + GL_UNSIGNED_INT_5_9_9_9_REV = $8C3E; + GL_TEXTURE_SHARED_SIZE = $8C3F; + GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH = $8C76; + GL_TRANSFORM_FEEDBACK_BUFFER_MODE = $8C7F; + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = $8C80; + GL_TRANSFORM_FEEDBACK_VARYINGS = $8C83; + GL_TRANSFORM_FEEDBACK_BUFFER_START = $8C84; + GL_TRANSFORM_FEEDBACK_BUFFER_SIZE = $8C85; + GL_PRIMITIVES_GENERATED = $8C87; + GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = $8C88; + GL_RASTERIZER_DISCARD = $8C89; + GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = $8C8A; + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = $8C8B; + GL_INTERLEAVED_ATTRIBS = $8C8C; + GL_SEPARATE_ATTRIBS = $8C8D; + GL_TRANSFORM_FEEDBACK_BUFFER = $8C8E; + GL_TRANSFORM_FEEDBACK_BUFFER_BINDING = $8C8F; + GL_RGBA32UI = $8D70; + GL_RGB32UI = $8D71; + GL_RGBA16UI = $8D76; + GL_RGB16UI = $8D77; + GL_RGBA8UI = $8D7C; + GL_RGB8UI = $8D7D; + GL_RGBA32I = $8D82; + GL_RGB32I = $8D83; + GL_RGBA16I = $8D88; + GL_RGB16I = $8D89; + GL_RGBA8I = $8D8E; + GL_RGB8I = $8D8F; + GL_RED_INTEGER = $8D94; + GL_GREEN_INTEGER = $8D95; + GL_BLUE_INTEGER = $8D96; + GL_RGB_INTEGER = $8D98; + GL_RGBA_INTEGER = $8D99; + GL_BGR_INTEGER = $8D9A; + GL_BGRA_INTEGER = $8D9B; + GL_SAMPLER_1D_ARRAY = $8DC0; + GL_SAMPLER_2D_ARRAY = $8DC1; + GL_SAMPLER_1D_ARRAY_SHADOW = $8DC3; + GL_SAMPLER_2D_ARRAY_SHADOW = $8DC4; + GL_SAMPLER_CUBE_SHADOW = $8DC5; + GL_UNSIGNED_INT_VEC2 = $8DC6; + GL_UNSIGNED_INT_VEC3 = $8DC7; + GL_UNSIGNED_INT_VEC4 = $8DC8; + GL_INT_SAMPLER_1D = $8DC9; + GL_INT_SAMPLER_2D = $8DCA; + GL_INT_SAMPLER_3D = $8DCB; + GL_INT_SAMPLER_CUBE = $8DCC; + GL_INT_SAMPLER_1D_ARRAY = $8DCE; + GL_INT_SAMPLER_2D_ARRAY = $8DCF; + GL_UNSIGNED_INT_SAMPLER_1D = $8DD1; + GL_UNSIGNED_INT_SAMPLER_2D = $8DD2; + GL_UNSIGNED_INT_SAMPLER_3D = $8DD3; + GL_UNSIGNED_INT_SAMPLER_CUBE = $8DD4; + GL_UNSIGNED_INT_SAMPLER_1D_ARRAY = $8DD6; + GL_UNSIGNED_INT_SAMPLER_2D_ARRAY = $8DD7; + GL_QUERY_WAIT = $8E13; + GL_QUERY_NO_WAIT = $8E14; + GL_QUERY_BY_REGION_WAIT = $8E15; + GL_QUERY_BY_REGION_NO_WAIT = $8E16; + GL_BUFFER_ACCESS_FLAGS = $911F; + GL_BUFFER_MAP_LENGTH = $9120; + GL_BUFFER_MAP_OFFSET = $9121; + +var + glColorMaski: procedure(index: GLuint; r: GLboolean; g: GLboolean; b: GLboolean; a: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBooleani_v: procedure(target: GLenum; index: GLuint; data: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetIntegeri_v: procedure(target: GLenum; index: GLuint; data: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; (* Also used in GL_ARB_uniform_buffer_object *) + glEnablei: procedure(target: GLenum; index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisablei: procedure(target: GLenum; index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsEnabledi: function(target: GLenum; index: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginTransformFeedback: procedure(primitiveMode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndTransformFeedback: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindBufferRange: procedure(target: GLenum; index: GLuint; buffer: GLuint; offset: GLintptr; size: GLsizeiptr); {$ifdef wincall}stdcall{$else}cdecl{$endif}; (* Also used in GL_ARB_uniform_buffer_object *) + glBindBufferBase: procedure(target: GLenum; index: GLuint; buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; (* Also used in GL_ARB_uniform_buffer_object *) + glTransformFeedbackVaryings: procedure(_program: GLuint; count: GLsizei; const varyings: PPGLchar; bufferMode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTransformFeedbackVarying: procedure(_program: GLuint; index: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLsizei; _type: PGLenum; name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClampColor: procedure(target: GLenum; clamp: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginConditionalRender: procedure(id: GLuint; mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndConditionalRender: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribIPointer: procedure(index: GLuint; size: GLint; _type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribIiv: procedure(index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribIuiv: procedure(index: GLuint; pname: GLenum; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI1i: procedure(index: GLuint; x: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI2i: procedure(index: GLuint; x: GLint; y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI3i: procedure(index: GLuint; x: GLint; y: GLint; z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4i: procedure(index: GLuint; x: GLint; y: GLint; z: GLint; w: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI1ui: procedure(index: GLuint; x: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI2ui: procedure(index: GLuint; x: GLuint; y: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI3ui: procedure(index: GLuint; x: GLuint; y: GLuint; z: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4ui: procedure(index: GLuint; x: GLuint; y: GLuint; z: GLuint; w: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI1iv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI2iv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI3iv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4iv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI1uiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI2uiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI3uiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4uiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4bv: procedure(index: GLuint; const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4sv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4ubv: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4usv: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformuiv: procedure(_program: GLuint; location: GLint; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindFragDataLocation: procedure(_program: GLuint; color: GLuint; const name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFragDataLocation: function(_program: GLuint; const name: PGLchar): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1ui: procedure(location: GLint; v0: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2ui: procedure(location: GLint; v0: GLuint; v1: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3ui: procedure(location: GLint; v0: GLuint; v1: GLuint; v2: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4ui: procedure(location: GLint; v0: GLuint; v1: GLuint; v2: GLuint; v3: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1uiv: procedure(location: GLint; count: GLsizei; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2uiv: procedure(location: GLint; count: GLsizei; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3uiv: procedure(location: GLint; count: GLsizei; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4uiv: procedure(location: GLint; count: GLsizei; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameterIiv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameterIuiv: procedure(target: GLenum; pname: GLenum; const params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexParameterIiv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexParameterIuiv: procedure(target: GLenum; pname: GLenum; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearBufferiv: procedure(buffer: GLenum; drawbuffer: GLint; const value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearBufferuiv: procedure(buffer: GLenum; drawbuffer: GLint; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearBufferfv: procedure(buffer: GLenum; drawbuffer: GLint; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearBufferfi: procedure(buffer: GLenum; drawbuffer: GLint; depth: GLfloat; stencil: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetStringi: function(name: GLenum; index: GLuint): PGLubyte; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_VERSION_3_0(): Boolean; + +//**** GL_VERSION_3_0 DEPRECATED *****// +const + GL_CLAMP_VERTEX_COLOR = $891A; + GL_CLAMP_FRAGMENT_COLOR = $891B; + GL_ALPHA_INTEGER = $8D97; + +//**** GL_VERSION_3_1 *****// +const + GL_SAMPLER_2D_RECT = $8B63; + GL_SAMPLER_2D_RECT_SHADOW = $8B64; + GL_SAMPLER_BUFFER = $8DC2; + GL_INT_SAMPLER_2D_RECT = $8DCD; + GL_INT_SAMPLER_BUFFER = $8DD0; + GL_UNSIGNED_INT_SAMPLER_2D_RECT = $8DD5; + GL_UNSIGNED_INT_SAMPLER_BUFFER = $8DD8; + GL_TEXTURE_BUFFER = $8C2A; + GL_MAX_TEXTURE_BUFFER_SIZE = $8C2B; + GL_TEXTURE_BINDING_BUFFER = $8C2C; + GL_TEXTURE_BUFFER_DATA_STORE_BINDING = $8C2D; + GL_TEXTURE_BUFFER_FORMAT = $8C2E; + GL_TEXTURE_RECTANGLE = $84F5; + GL_TEXTURE_BINDING_RECTANGLE = $84F6; + GL_PROXY_TEXTURE_RECTANGLE = $84F7; + GL_MAX_RECTANGLE_TEXTURE_SIZE = $84F8; + GL_RED_SNORM = $8F90; + GL_RG_SNORM = $8F91; + GL_RGB_SNORM = $8F92; + GL_RGBA_SNORM = $8F93; + GL_R8_SNORM = $8F94; + GL_RG8_SNORM = $8F95; + GL_RGB8_SNORM = $8F96; + GL_RGBA8_SNORM = $8F97; + GL_R16_SNORM = $8F98; + GL_RG16_SNORM = $8F99; + GL_RGB16_SNORM = $8F9A; + GL_RGBA16_SNORM = $8F9B; + GL_SIGNED_NORMALIZED = $8F9C; + GL_PRIMITIVE_RESTART = $8F9D; + GL_PRIMITIVE_RESTART_INDEX = $8F9E; + +var + glDrawArraysInstanced: procedure(mode: GLenum; first: GLint; count: GLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElementsInstanced: procedure(mode: GLenum; count: GLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexBuffer: procedure(target: GLenum; internalformat: GLenum; buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPrimitiveRestartIndex: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_VERSION_3_1(): Boolean; + +//**** GL_VERSION_3_2 *****// +const + GL_CONTEXT_CORE_PROFILE_BIT = $00000001; + GL_CONTEXT_COMPATIBILITY_PROFILE_BIT = $00000002; + GL_LINES_ADJACENCY = $000A; + GL_LINE_STRIP_ADJACENCY = $000B; + GL_TRIANGLES_ADJACENCY = $000C; + GL_TRIANGLE_STRIP_ADJACENCY = $000D; + GL_PROGRAM_POINT_SIZE = $8642; + GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS = $8C29; + GL_FRAMEBUFFER_ATTACHMENT_LAYERED = $8DA7; + GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = $8DA8; + GL_GEOMETRY_SHADER = $8DD9; + GL_GEOMETRY_VERTICES_OUT = $8916; + GL_GEOMETRY_INPUT_TYPE = $8917; + GL_GEOMETRY_OUTPUT_TYPE = $8918; + GL_MAX_GEOMETRY_UNIFORM_COMPONENTS = $8DDF; + GL_MAX_GEOMETRY_OUTPUT_VERTICES = $8DE0; + GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = $8DE1; + GL_MAX_VERTEX_OUTPUT_COMPONENTS = $9122; + GL_MAX_GEOMETRY_INPUT_COMPONENTS = $9123; + GL_MAX_GEOMETRY_OUTPUT_COMPONENTS = $9124; + GL_MAX_FRAGMENT_INPUT_COMPONENTS = $9125; + GL_CONTEXT_PROFILE_MASK = $9126; + +var + glGetInteger64i_v: procedure(target: GLenum; index: GLuint; data: PGLint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferParameteri64v: procedure(target: GLenum; pname: GLenum; params: PGLint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramParameteri: procedure(_program: GLuint; pname: GLenum; value: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture: procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_VERSION_3_2(): Boolean; + +//**** GL_VERSION_3_3 *****// + +function Load_GL_VERSION_3_3(): Boolean; + +//**** GL_VERSION_4_0 *****// + +function Load_GL_VERSION_4_0(): Boolean; + +implementation +uses + msedynload,msesys{$ifdef mswindows}{$ifdef FPC},dynlibs{$endif}{$endif} + {$ifndef FPC},classes_del{$endif}; + +function getprocaddresses(const lib: tlibhandle; + const procedures: array of funcinfoty): boolean; +var + int1: integer; +begin + result:= true; + for int1:= 0 to high(procedures) do begin + with procedures[int1] do begin + {$ifdef mswindows} + d^:= wglgetprocaddress(pansichar(n)); + {$else} + d^:= getprocaddress(libgl,pansichar(n)); + {$endif} + if (d^ = nil) then begin + result:= false; + end; + end; + end; +end; +(* +function glext_ExtensionSupported(const extension: String; const searchIn: String): Boolean; +var + extensions: PChar; + start: PChar; + where, terminator: PChar; +begin + + if (Pos(' ', extension) <> 0) or (extension = '') then + begin + Result := FALSE; + Exit; + end; + + if searchIn = '' then extensions := PChar(glGetString(GL_EXTENSIONS)) + else extensions := PChar(searchIn); + start := extensions; + while TRUE do + begin + where := StrPos(start, PChar(extension)); + if where = nil then Break; + terminator := Pointer(PtrUInt(where) + Length(extension)); + if (where = start) or (PChar(PtrUInt(where) - 1)^ = ' ') then + begin + if (terminator^ = ' ') or (terminator^ = #0) then + begin + Result := TRUE; + Exit; + end; + end; + start := terminator; + end; + Result := FALSE; + +end; +*) + +function Load_GL_version_1_2: Boolean; +const + funcs: array[0..5] of funcinfoty = + ( + (n: 'glBlendColor'; d: {$ifndef FPC}@{$endif}@glBlendColor), + (n: 'glBlendEquation'; d: {$ifndef FPC}@{$endif}@glBlendEquation), + (n: 'glDrawRangeElements'; d: {$ifndef FPC}@{$endif}@glDrawRangeElements), + (n: 'glTexImage3D'; d: {$ifndef FPC}@{$endif}@glTexImage3D), + (n: 'glTexSubImage3D'; d: {$ifndef FPC}@{$endif}@glTexSubImage3D), + (n: 'glCopyTexSubImage3D'; d: {$ifndef FPC}@{$endif}@glCopyTexSubImage3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_imaging: Boolean; +const + funcs: array[0..31] of funcinfoty = + ( + (n: 'glColorTable'; d: {$ifndef FPC}@{$endif}@glColorTable), + (n: 'glColorTableParameterfv'; d: {$ifndef FPC}@{$endif}@glColorTableParameterfv), + (n: 'glColorTableParameteriv'; d: {$ifndef FPC}@{$endif}@glColorTableParameteriv), + (n: 'glCopyColorTable'; d: {$ifndef FPC}@{$endif}@glCopyColorTable), + (n: 'glGetColorTable'; d: {$ifndef FPC}@{$endif}@glGetColorTable), + (n: 'glGetColorTableParameterfv'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameterfv), + (n: 'glGetColorTableParameteriv'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameteriv), + (n: 'glColorSubTable'; d: {$ifndef FPC}@{$endif}@glColorSubTable), + (n: 'glCopyColorSubTable'; d: {$ifndef FPC}@{$endif}@glCopyColorSubTable), + (n: 'glConvolutionFilter1D'; d: {$ifndef FPC}@{$endif}@glConvolutionFilter1D), + (n: 'glConvolutionFilter2D'; d: {$ifndef FPC}@{$endif}@glConvolutionFilter2D), + (n: 'glConvolutionParameterf'; d: {$ifndef FPC}@{$endif}@glConvolutionParameterf), + (n: 'glConvolutionParameterfv'; d: {$ifndef FPC}@{$endif}@glConvolutionParameterfv), + (n: 'glConvolutionParameteri'; d: {$ifndef FPC}@{$endif}@glConvolutionParameteri), + (n: 'glConvolutionParameteriv'; d: {$ifndef FPC}@{$endif}@glConvolutionParameteriv), + (n: 'glCopyConvolutionFilter1D'; d: {$ifndef FPC}@{$endif}@glCopyConvolutionFilter1D), + (n: 'glCopyConvolutionFilter2D'; d: {$ifndef FPC}@{$endif}@glCopyConvolutionFilter2D), + (n: 'glGetConvolutionFilter'; d: {$ifndef FPC}@{$endif}@glGetConvolutionFilter), + (n: 'glGetConvolutionParameterfv'; d: {$ifndef FPC}@{$endif}@glGetConvolutionParameterfv), + (n: 'glGetConvolutionParameteriv'; d: {$ifndef FPC}@{$endif}@glGetConvolutionParameteriv), + (n: 'glGetSeparableFilter'; d: {$ifndef FPC}@{$endif}@glGetSeparableFilter), + (n: 'glSeparableFilter2D'; d: {$ifndef FPC}@{$endif}@glSeparableFilter2D), + (n: 'glGetHistogram'; d: {$ifndef FPC}@{$endif}@glGetHistogram), + (n: 'glGetHistogramParameterfv'; d: {$ifndef FPC}@{$endif}@glGetHistogramParameterfv), + (n: 'glGetHistogramParameteriv'; d: {$ifndef FPC}@{$endif}@glGetHistogramParameteriv), + (n: 'glGetMinmax'; d: {$ifndef FPC}@{$endif}@glGetMinmax), + (n: 'glGetMinmaxParameterfv'; d: {$ifndef FPC}@{$endif}@glGetMinmaxParameterfv), + (n: 'glGetMinmaxParameteriv'; d: {$ifndef FPC}@{$endif}@glGetMinmaxParameteriv), + (n: 'glHistogram'; d: {$ifndef FPC}@{$endif}@glHistogram), + (n: 'glMinmax'; d: {$ifndef FPC}@{$endif}@glMinmax), + (n: 'glResetHistogram'; d: {$ifndef FPC}@{$endif}@glResetHistogram), + (n: 'glResetMinmax'; d: {$ifndef FPC}@{$endif}@glResetMinmax) + ); + +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_version_1_3: Boolean; +const + funcs: array[0..45] of funcinfoty = + ( + (n: 'glActiveTexture'; d: {$ifndef FPC}@{$endif}@glActiveTexture), + (n: 'glClientActiveTexture'; d: {$ifndef FPC}@{$endif}@glClientActiveTexture), + (n: 'glMultiTexCoord1d'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1d), + (n: 'glMultiTexCoord1dv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1dv), + (n: 'glMultiTexCoord1f'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1f), + (n: 'glMultiTexCoord1fv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1fv), + (n: 'glMultiTexCoord1i'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1i), + (n: 'glMultiTexCoord1iv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1iv), + (n: 'glMultiTexCoord1s'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1s), + (n: 'glMultiTexCoord1sv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1sv), + (n: 'glMultiTexCoord2d'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2d), + (n: 'glMultiTexCoord2dv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2dv), + (n: 'glMultiTexCoord2f'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2f), + (n: 'glMultiTexCoord2fv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2fv), + (n: 'glMultiTexCoord2i'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2i), + (n: 'glMultiTexCoord2iv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2iv), + (n: 'glMultiTexCoord2s'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2s), + (n: 'glMultiTexCoord2sv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2sv), + (n: 'glMultiTexCoord3d'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3d), + (n: 'glMultiTexCoord3dv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3dv), + (n: 'glMultiTexCoord3f'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3f), + (n: 'glMultiTexCoord3fv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3fv), + (n: 'glMultiTexCoord3i'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3i), + (n: 'glMultiTexCoord3iv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3iv), + (n: 'glMultiTexCoord3s'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3s), + (n: 'glMultiTexCoord3sv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3sv), + (n: 'glMultiTexCoord4d'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4d), + (n: 'glMultiTexCoord4dv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4dv), + (n: 'glMultiTexCoord4f'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4f), + (n: 'glMultiTexCoord4fv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4fv), + (n: 'glMultiTexCoord4i'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4i), + (n: 'glMultiTexCoord4iv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4iv), + (n: 'glMultiTexCoord4s'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4s), + (n: 'glMultiTexCoord4sv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4sv), + (n: 'glLoadTransposeMatrixf'; d: {$ifndef FPC}@{$endif}@glLoadTransposeMatrixf), + (n: 'glLoadTransposeMatrixd'; d: {$ifndef FPC}@{$endif}@glLoadTransposeMatrixd), + (n: 'glMultTransposeMatrixf'; d: {$ifndef FPC}@{$endif}@glMultTransposeMatrixf), + (n: 'glMultTransposeMatrixd'; d: {$ifndef FPC}@{$endif}@glMultTransposeMatrixd), + (n: 'glSampleCoverage'; d: {$ifndef FPC}@{$endif}@glSampleCoverage), + (n: 'glCompressedTexImage3D'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage3D), + (n: 'glCompressedTexImage2D'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage2D), + (n: 'glCompressedTexImage1D'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage1D), + (n: 'glCompressedTexSubImage3D'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage3D), + (n: 'glCompressedTexSubImage2D'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage2D), + (n: 'glCompressedTexSubImage1D'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage1D), + (n: 'glGetCompressedTexImage'; d: {$ifndef FPC}@{$endif}@glGetCompressedTexImage) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_multitexture: Boolean; +const + funcs: array[0..33] of funcinfoty = + ( + (n: 'glActiveTextureARB'; d: {$ifndef FPC}@{$endif}@glActiveTextureARB), + (n: 'glClientActiveTextureARB'; d: {$ifndef FPC}@{$endif}@glClientActiveTextureARB), + (n: 'glMultiTexCoord1dARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1dARB), + (n: 'glMultiTexCoord1dvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1dvARB), + (n: 'glMultiTexCoord1fARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1fARB), + (n: 'glMultiTexCoord1fvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1fvARB), + (n: 'glMultiTexCoord1iARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1iARB), + (n: 'glMultiTexCoord1ivARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1ivARB), + (n: 'glMultiTexCoord1sARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1sARB), + (n: 'glMultiTexCoord1svARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1svARB), + (n: 'glMultiTexCoord2dARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2dARB), + (n: 'glMultiTexCoord2dvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2dvARB), + (n: 'glMultiTexCoord2fARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2fARB), + (n: 'glMultiTexCoord2fvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2fvARB), + (n: 'glMultiTexCoord2iARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2iARB), + (n: 'glMultiTexCoord2ivARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2ivARB), + (n: 'glMultiTexCoord2sARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2sARB), + (n: 'glMultiTexCoord2svARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2svARB), + (n: 'glMultiTexCoord3dARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3dARB), + (n: 'glMultiTexCoord3dvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3dvARB), + (n: 'glMultiTexCoord3fARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3fARB), + (n: 'glMultiTexCoord3fvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3fvARB), + (n: 'glMultiTexCoord3iARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3iARB), + (n: 'glMultiTexCoord3ivARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3ivARB), + (n: 'glMultiTexCoord3sARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3sARB), + (n: 'glMultiTexCoord3svARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3svARB), + (n: 'glMultiTexCoord4dARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4dARB), + (n: 'glMultiTexCoord4dvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4dvARB), + (n: 'glMultiTexCoord4fARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4fARB), + (n: 'glMultiTexCoord4fvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4fvARB), + (n: 'glMultiTexCoord4iARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4iARB), + (n: 'glMultiTexCoord4ivARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4ivARB), + (n: 'glMultiTexCoord4sARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4sARB), + (n: 'glMultiTexCoord4svARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4svARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_transpose_matrix: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glLoadTransposeMatrixfARB'; d: {$ifndef FPC}@{$endif}@glLoadTransposeMatrixfARB), + (n: 'glLoadTransposeMatrixdARB'; d: {$ifndef FPC}@{$endif}@glLoadTransposeMatrixdARB), + (n: 'glMultTransposeMatrixfARB'; d: {$ifndef FPC}@{$endif}@glMultTransposeMatrixfARB), + (n: 'glMultTransposeMatrixdARB'; d: {$ifndef FPC}@{$endif}@glMultTransposeMatrixdARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_multisample: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glSampleCoverageARB'; d: {$ifndef FPC}@{$endif}@glSampleCoverageARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_texture_env_add: Boolean; +begin + result:= true; //no procs +end; + +{$IFDEF msWindows} +function Load_WGL_ARB_extensions_string: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'wglGetExtensionsStringARB'; d: {$ifndef FPC}@{$endif}@wglGetExtensionsStringARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_ARB_buffer_region: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'wglCreateBufferRegionARB'; d: {$ifndef FPC}@{$endif}@wglCreateBufferRegionARB), + (n: 'wglDeleteBufferRegionARB'; d: {$ifndef FPC}@{$endif}@wglDeleteBufferRegionARB), + (n: 'wglSaveBufferRegionARB'; d: {$ifndef FPC}@{$endif}@wglSaveBufferRegionARB), + (n: 'wglRestoreBufferRegionARB'; d: {$ifndef FPC}@{$endif}@wglRestoreBufferRegionARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; +{$ENDIF} + +function Load_GL_ARB_texture_cube_map: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_depth_texture: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_point_parameters: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPointParameterfARB'; d: {$ifndef FPC}@{$endif}@glPointParameterfARB), + (n: 'glPointParameterfvARB'; d: {$ifndef FPC}@{$endif}@glPointParameterfvARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_shadow: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_shadow_ambient: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_border_clamp: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_compression: Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glCompressedTexImage3DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage3DARB), + (n: 'glCompressedTexImage2DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage2DARB), + (n: 'glCompressedTexImage1DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage1DARB), + (n: 'glCompressedTexSubImage3DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage3DARB), + (n: 'glCompressedTexSubImage2DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage2DARB), + (n: 'glCompressedTexSubImage1DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage1DARB), + (n: 'glGetCompressedTexImageARB'; d: {$ifndef FPC}@{$endif}@glGetCompressedTexImageARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_texture_env_combine: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_env_crossbar: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_env_dot3: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_mirrored_repeat: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_vertex_blend: Boolean; +const + funcs: array[0..10] of funcinfoty = + ( + (n: 'glWeightbvARB'; d: {$ifndef FPC}@{$endif}@glWeightbvARB), + (n: 'glWeightsvARB'; d: {$ifndef FPC}@{$endif}@glWeightsvARB), + (n: 'glWeightivARB'; d: {$ifndef FPC}@{$endif}@glWeightivARB), + (n: 'glWeightfvARB'; d: {$ifndef FPC}@{$endif}@glWeightfvARB), + (n: 'glWeightdvARB'; d: {$ifndef FPC}@{$endif}@glWeightdvARB), + (n: 'glWeightvARB'; d: {$ifndef FPC}@{$endif}@glWeightvARB), + (n: 'glWeightubvARB'; d: {$ifndef FPC}@{$endif}@glWeightubvARB), + (n: 'glWeightusvARB'; d: {$ifndef FPC}@{$endif}@glWeightusvARB), + (n: 'glWeightuivARB'; d: {$ifndef FPC}@{$endif}@glWeightuivARB), + (n: 'glWeightPointerARB'; d: {$ifndef FPC}@{$endif}@glWeightPointerARB), + (n: 'glVertexBlendARB'; d: {$ifndef FPC}@{$endif}@glVertexBlendARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_vertex_program: Boolean; +const + funcs: array[0..61] of funcinfoty = + ( + (n: 'glVertexAttrib1sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1sARB), + (n: 'glVertexAttrib1fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fARB), + (n: 'glVertexAttrib1dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dARB), + (n: 'glVertexAttrib2sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2sARB), + (n: 'glVertexAttrib2fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fARB), + (n: 'glVertexAttrib2dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dARB), + (n: 'glVertexAttrib3sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3sARB), + (n: 'glVertexAttrib3fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fARB), + (n: 'glVertexAttrib3dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dARB), + (n: 'glVertexAttrib4sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4sARB), + (n: 'glVertexAttrib4fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fARB), + (n: 'glVertexAttrib4dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dARB), + (n: 'glVertexAttrib4NubARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NubARB), + (n: 'glVertexAttrib1svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1svARB), + (n: 'glVertexAttrib1fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fvARB), + (n: 'glVertexAttrib1dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dvARB), + (n: 'glVertexAttrib2svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2svARB), + (n: 'glVertexAttrib2fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fvARB), + (n: 'glVertexAttrib2dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dvARB), + (n: 'glVertexAttrib3svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3svARB), + (n: 'glVertexAttrib3fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fvARB), + (n: 'glVertexAttrib3dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dvARB), + (n: 'glVertexAttrib4bvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4bvARB), + (n: 'glVertexAttrib4svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4svARB), + (n: 'glVertexAttrib4ivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ivARB), + (n: 'glVertexAttrib4ubvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ubvARB), + (n: 'glVertexAttrib4usvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4usvARB), + (n: 'glVertexAttrib4uivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4uivARB), + (n: 'glVertexAttrib4fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fvARB), + (n: 'glVertexAttrib4dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dvARB), + (n: 'glVertexAttrib4NbvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NbvARB), + (n: 'glVertexAttrib4NsvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NsvARB), + (n: 'glVertexAttrib4NivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NivARB), + (n: 'glVertexAttrib4NubvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NubvARB), + (n: 'glVertexAttrib4NusvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NusvARB), + (n: 'glVertexAttrib4NuivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NuivARB), + (n: 'glVertexAttribPointerARB'; d: {$ifndef FPC}@{$endif}@glVertexAttribPointerARB), + (n: 'glEnableVertexAttribArrayARB'; d: {$ifndef FPC}@{$endif}@glEnableVertexAttribArrayARB), + (n: 'glDisableVertexAttribArrayARB'; d: {$ifndef FPC}@{$endif}@glDisableVertexAttribArrayARB), + (n: 'glProgramStringARB'; d: {$ifndef FPC}@{$endif}@glProgramStringARB), + (n: 'glBindProgramARB'; d: {$ifndef FPC}@{$endif}@glBindProgramARB), + (n: 'glDeleteProgramsARB'; d: {$ifndef FPC}@{$endif}@glDeleteProgramsARB), + (n: 'glGenProgramsARB'; d: {$ifndef FPC}@{$endif}@glGenProgramsARB), + (n: 'glProgramEnvParameter4dARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4dARB), + (n: 'glProgramEnvParameter4dvARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4dvARB), + (n: 'glProgramEnvParameter4fARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4fARB), + (n: 'glProgramEnvParameter4fvARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4fvARB), + (n: 'glProgramLocalParameter4dARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dARB), + (n: 'glProgramLocalParameter4dvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dvARB), + (n: 'glProgramLocalParameter4fARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fARB), + (n: 'glProgramLocalParameter4fvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fvARB), + (n: 'glGetProgramEnvParameterdvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramEnvParameterdvARB), + (n: 'glGetProgramEnvParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramEnvParameterfvARB), + (n: 'glGetProgramLocalParameterdvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterdvARB), + (n: 'glGetProgramLocalParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterfvARB), + (n: 'glGetProgramivARB'; d: {$ifndef FPC}@{$endif}@glGetProgramivARB), + (n: 'glGetProgramStringARB'; d: {$ifndef FPC}@{$endif}@glGetProgramStringARB), + (n: 'glGetVertexAttribdvARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribdvARB), + (n: 'glGetVertexAttribfvARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribfvARB), + (n: 'glGetVertexAttribivARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribivARB), + (n: 'glGetVertexAttribPointervARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribPointervARB), + (n: 'glIsProgramARB'; d: {$ifndef FPC}@{$endif}@glIsProgramARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_window_pos: Boolean; +const + funcs: array[0..15] of funcinfoty = + ( + (n: 'glWindowPos2dARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2dARB), + (n: 'glWindowPos2fARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2fARB), + (n: 'glWindowPos2iARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2iARB), + (n: 'glWindowPos2sARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2sARB), + (n: 'glWindowPos2dvARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2dvARB), + (n: 'glWindowPos2fvARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2fvARB), + (n: 'glWindowPos2ivARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2ivARB), + (n: 'glWindowPos2svARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2svARB), + (n: 'glWindowPos3dARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3dARB), + (n: 'glWindowPos3fARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3fARB), + (n: 'glWindowPos3iARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3iARB), + (n: 'glWindowPos3sARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3sARB), + (n: 'glWindowPos3dvARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3dvARB), + (n: 'glWindowPos3fvARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3fvARB), + (n: 'glWindowPos3ivARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3ivARB), + (n: 'glWindowPos3svARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3svARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_422_pixels: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_abgr: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_bgra: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_blend_color: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glBlendColorEXT'; d: {$ifndef FPC}@{$endif}@glBlendColorEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_blend_func_separate: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glBlendFuncSeparateEXT'; d: {$ifndef FPC}@{$endif}@glBlendFuncSeparateEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_blend_logic_op: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_blend_minmax: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glBlendEquationEXT'; d: {$ifndef FPC}@{$endif}@glBlendEquationEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_blend_subtract: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_clip_volume_hint: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_color_subtable: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glColorSubTableEXT'; d: {$ifndef FPC}@{$endif}@glColorSubTableEXT), + (n: 'glCopyColorSubTableEXT'; d: {$ifndef FPC}@{$endif}@glCopyColorSubTableEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_compiled_vertex_array: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glLockArraysEXT'; d: {$ifndef FPC}@{$endif}@glLockArraysEXT), + (n: 'glUnlockArraysEXT'; d: {$ifndef FPC}@{$endif}@glUnlockArraysEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_convolution: Boolean; +const + funcs: array[0..12] of funcinfoty = + ( + (n: 'glConvolutionFilter1DEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionFilter1DEXT), + (n: 'glConvolutionFilter2DEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionFilter2DEXT), + (n: 'glCopyConvolutionFilter1DEXT'; d: {$ifndef FPC}@{$endif}@glCopyConvolutionFilter1DEXT), + (n: 'glCopyConvolutionFilter2DEXT'; d: {$ifndef FPC}@{$endif}@glCopyConvolutionFilter2DEXT), + (n: 'glGetConvolutionFilterEXT'; d: {$ifndef FPC}@{$endif}@glGetConvolutionFilterEXT), + (n: 'glSeparableFilter2DEXT'; d: {$ifndef FPC}@{$endif}@glSeparableFilter2DEXT), + (n: 'glGetSeparableFilterEXT'; d: {$ifndef FPC}@{$endif}@glGetSeparableFilterEXT), + (n: 'glConvolutionParameteriEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionParameteriEXT), + (n: 'glConvolutionParameterivEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionParameterivEXT), + (n: 'glConvolutionParameterfEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionParameterfEXT), + (n: 'glConvolutionParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionParameterfvEXT), + (n: 'glGetConvolutionParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetConvolutionParameterivEXT), + (n: 'glGetConvolutionParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glGetConvolutionParameterfvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_fog_coord: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glFogCoordfEXT'; d: {$ifndef FPC}@{$endif}@glFogCoordfEXT), + (n: 'glFogCoorddEXT'; d: {$ifndef FPC}@{$endif}@glFogCoorddEXT), + (n: 'glFogCoordfvEXT'; d: {$ifndef FPC}@{$endif}@glFogCoordfvEXT), + (n: 'glFogCoorddvEXT'; d: {$ifndef FPC}@{$endif}@glFogCoorddvEXT), + (n: 'glFogCoordPointerEXT'; d: {$ifndef FPC}@{$endif}@glFogCoordPointerEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_histogram: Boolean; +const + funcs: array[0..9] of funcinfoty = + ( + (n: 'glHistogramEXT'; d: {$ifndef FPC}@{$endif}@glHistogramEXT), + (n: 'glResetHistogramEXT'; d: {$ifndef FPC}@{$endif}@glResetHistogramEXT), + (n: 'glGetHistogramEXT'; d: {$ifndef FPC}@{$endif}@glGetHistogramEXT), + (n: 'glGetHistogramParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetHistogramParameterivEXT), + (n: 'glGetHistogramParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glGetHistogramParameterfvEXT), + (n: 'glMinmaxEXT'; d: {$ifndef FPC}@{$endif}@glMinmaxEXT), + (n: 'glResetMinmaxEXT'; d: {$ifndef FPC}@{$endif}@glResetMinmaxEXT), + (n: 'glGetMinmaxEXT'; d: {$ifndef FPC}@{$endif}@glGetMinmaxEXT), + (n: 'glGetMinmaxParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetMinmaxParameterivEXT), + (n: 'glGetMinmaxParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glGetMinmaxParameterfvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_multi_draw_arrays: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glMultiDrawArraysEXT'; d: {$ifndef FPC}@{$endif}@glMultiDrawArraysEXT), + (n: 'glMultiDrawElementsEXT'; d: {$ifndef FPC}@{$endif}@glMultiDrawElementsEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_packed_depth_stencil: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_packed_pixels: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_paletted_texture: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glColorTableEXT'; d: {$ifndef FPC}@{$endif}@glColorTableEXT), + (n: 'glColorSubTableEXT'; d: {$ifndef FPC}@{$endif}@glColorSubTableEXT), + (n: 'glGetColorTableEXT'; d: {$ifndef FPC}@{$endif}@glGetColorTableEXT), + (n: 'glGetColorTableParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameterivEXT), + (n: 'glGetColorTableParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameterfvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_point_parameters: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPointParameterfEXT'; d: {$ifndef FPC}@{$endif}@glPointParameterfEXT), + (n: 'glPointParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glPointParameterfvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_polygon_offset: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glPolygonOffsetEXT'; d: {$ifndef FPC}@{$endif}@glPolygonOffsetEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_secondary_color: Boolean; +const + funcs: array[0..16] of funcinfoty = + ( + (n: 'glSecondaryColor3bEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3bEXT), + (n: 'glSecondaryColor3sEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3sEXT), + (n: 'glSecondaryColor3iEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3iEXT), + (n: 'glSecondaryColor3fEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3fEXT), + (n: 'glSecondaryColor3dEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3dEXT), + (n: 'glSecondaryColor3ubEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ubEXT), + (n: 'glSecondaryColor3usEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3usEXT), + (n: 'glSecondaryColor3uiEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3uiEXT), + (n: 'glSecondaryColor3bvEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3bvEXT), + (n: 'glSecondaryColor3svEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3svEXT), + (n: 'glSecondaryColor3ivEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ivEXT), + (n: 'glSecondaryColor3fvEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3fvEXT), + (n: 'glSecondaryColor3dvEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3dvEXT), + (n: 'glSecondaryColor3ubvEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ubvEXT), + (n: 'glSecondaryColor3usvEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3usvEXT), + (n: 'glSecondaryColor3uivEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3uivEXT), + (n: 'glSecondaryColorPointerEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColorPointerEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_separate_specular_color: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_shadow_funcs: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_shared_texture_palette: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_stencil_two_side: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glActiveStencilFaceEXT'; d: {$ifndef FPC}@{$endif}@glActiveStencilFaceEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_stencil_wrap: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_subtexture: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glTexSubImage1DEXT'; d: {$ifndef FPC}@{$endif}@glTexSubImage1DEXT), + (n: 'glTexSubImage2DEXT'; d: {$ifndef FPC}@{$endif}@glTexSubImage2DEXT), + (n: 'glTexSubImage3DEXT'; d: {$ifndef FPC}@{$endif}@glTexSubImage3DEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_texture3D: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glTexImage3DEXT'; d: {$ifndef FPC}@{$endif}@glTexImage3DEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_texture_compression_s3tc: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_env_add: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_env_combine: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_env_dot3: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_filter_anisotropic: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_lod_bias: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_object: Boolean; +const + funcs: array[0..5] of funcinfoty = + ( + (n: 'glGenTexturesEXT'; d: {$ifndef FPC}@{$endif}@glGenTexturesEXT), + (n: 'glDeleteTexturesEXT'; d: {$ifndef FPC}@{$endif}@glDeleteTexturesEXT), + (n: 'glBindTextureEXT'; d: {$ifndef FPC}@{$endif}@glBindTextureEXT), + (n: 'glPrioritizeTexturesEXT'; d: {$ifndef FPC}@{$endif}@glPrioritizeTexturesEXT), + (n: 'glAreTexturesResidentEXT'; d: {$ifndef FPC}@{$endif}@glAreTexturesResidentEXT), + (n: 'glIsTextureEXT'; d: {$ifndef FPC}@{$endif}@glIsTextureEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_vertex_array: Boolean; +const + funcs: array[0..8] of funcinfoty = + ( + (n: 'glArrayElementEXT'; d: {$ifndef FPC}@{$endif}@glArrayElementEXT), + (n: 'glDrawArraysEXT'; d: {$ifndef FPC}@{$endif}@glDrawArraysEXT), + (n: 'glVertexPointerEXT'; d: {$ifndef FPC}@{$endif}@glVertexPointerEXT), + (n: 'glNormalPointerEXT'; d: {$ifndef FPC}@{$endif}@glNormalPointerEXT), + (n: 'glColorPointerEXT'; d: {$ifndef FPC}@{$endif}@glColorPointerEXT), + (n: 'glIndexPointerEXT'; d: {$ifndef FPC}@{$endif}@glIndexPointerEXT), + (n: 'glTexCoordPointerEXT'; d: {$ifndef FPC}@{$endif}@glTexCoordPointerEXT), + (n: 'glEdgeFlagPointerEXT'; d: {$ifndef FPC}@{$endif}@glEdgeFlagPointerEXT), + (n: 'glGetPointervEXT'; d: {$ifndef FPC}@{$endif}@glGetPointervEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_vertex_shader: Boolean; +const + funcs: array[0..41] of funcinfoty = + ( + (n: 'glBeginVertexShaderEXT'; d: {$ifndef FPC}@{$endif}@glBeginVertexShaderEXT), + (n: 'glEndVertexShaderEXT'; d: {$ifndef FPC}@{$endif}@glEndVertexShaderEXT), + (n: 'glBindVertexShaderEXT'; d: {$ifndef FPC}@{$endif}@glBindVertexShaderEXT), + (n: 'glGenVertexShadersEXT'; d: {$ifndef FPC}@{$endif}@glGenVertexShadersEXT), + (n: 'glDeleteVertexShaderEXT'; d: {$ifndef FPC}@{$endif}@glDeleteVertexShaderEXT), + (n: 'glShaderOp1EXT'; d: {$ifndef FPC}@{$endif}@glShaderOp1EXT), + (n: 'glShaderOp2EXT'; d: {$ifndef FPC}@{$endif}@glShaderOp2EXT), + (n: 'glShaderOp3EXT'; d: {$ifndef FPC}@{$endif}@glShaderOp3EXT), + (n: 'glSwizzleEXT'; d: {$ifndef FPC}@{$endif}@glSwizzleEXT), + (n: 'glWriteMaskEXT'; d: {$ifndef FPC}@{$endif}@glWriteMaskEXT), + (n: 'glInsertComponentEXT'; d: {$ifndef FPC}@{$endif}@glInsertComponentEXT), + (n: 'glExtractComponentEXT'; d: {$ifndef FPC}@{$endif}@glExtractComponentEXT), + (n: 'glGenSymbolsEXT'; d: {$ifndef FPC}@{$endif}@glGenSymbolsEXT), + (n: 'glSetInvariantEXT'; d: {$ifndef FPC}@{$endif}@glSetInvariantEXT), + (n: 'glSetLocalConstantEXT'; d: {$ifndef FPC}@{$endif}@glSetLocalConstantEXT), + (n: 'glVariantbvEXT'; d: {$ifndef FPC}@{$endif}@glVariantbvEXT), + (n: 'glVariantsvEXT'; d: {$ifndef FPC}@{$endif}@glVariantsvEXT), + (n: 'glVariantivEXT'; d: {$ifndef FPC}@{$endif}@glVariantivEXT), + (n: 'glVariantfvEXT'; d: {$ifndef FPC}@{$endif}@glVariantfvEXT), + (n: 'glVariantdvEXT'; d: {$ifndef FPC}@{$endif}@glVariantdvEXT), + (n: 'glVariantubvEXT'; d: {$ifndef FPC}@{$endif}@glVariantubvEXT), + (n: 'glVariantusvEXT'; d: {$ifndef FPC}@{$endif}@glVariantusvEXT), + (n: 'glVariantuivEXT'; d: {$ifndef FPC}@{$endif}@glVariantuivEXT), + (n: 'glVariantPointerEXT'; d: {$ifndef FPC}@{$endif}@glVariantPointerEXT), + (n: 'glEnableVariantClientStateEXT'; d: {$ifndef FPC}@{$endif}@glEnableVariantClientStateEXT), + (n: 'glDisableVariantClientStateEXT'; d: {$ifndef FPC}@{$endif}@glDisableVariantClientStateEXT), + (n: 'glBindLightParameterEXT'; d: {$ifndef FPC}@{$endif}@glBindLightParameterEXT), + (n: 'glBindMaterialParameterEXT'; d: {$ifndef FPC}@{$endif}@glBindMaterialParameterEXT), + (n: 'glBindTexGenParameterEXT'; d: {$ifndef FPC}@{$endif}@glBindTexGenParameterEXT), + (n: 'glBindTextureUnitParameterEXT'; d: {$ifndef FPC}@{$endif}@glBindTextureUnitParameterEXT), + (n: 'glBindParameterEXT'; d: {$ifndef FPC}@{$endif}@glBindParameterEXT), + (n: 'glIsVariantEnabledEXT'; d: {$ifndef FPC}@{$endif}@glIsVariantEnabledEXT), + (n: 'glGetVariantBooleanvEXT'; d: {$ifndef FPC}@{$endif}@glGetVariantBooleanvEXT), + (n: 'glGetVariantIntegervEXT'; d: {$ifndef FPC}@{$endif}@glGetVariantIntegervEXT), + (n: 'glGetVariantFloatvEXT'; d: {$ifndef FPC}@{$endif}@glGetVariantFloatvEXT), + (n: 'glGetVariantPointervEXT'; d: {$ifndef FPC}@{$endif}@glGetVariantPointervEXT), + (n: 'glGetInvariantBooleanvEXT'; d: {$ifndef FPC}@{$endif}@glGetInvariantBooleanvEXT), + (n: 'glGetInvariantIntegervEXT'; d: {$ifndef FPC}@{$endif}@glGetInvariantIntegervEXT), + (n: 'glGetInvariantFloatvEXT'; d: {$ifndef FPC}@{$endif}@glGetInvariantFloatvEXT), + (n: 'glGetLocalConstantBooleanvEXT'; d: {$ifndef FPC}@{$endif}@glGetLocalConstantBooleanvEXT), + (n: 'glGetLocalConstantIntegervEXT'; d: {$ifndef FPC}@{$endif}@glGetLocalConstantIntegervEXT), + (n: 'glGetLocalConstantFloatvEXT'; d: {$ifndef FPC}@{$endif}@glGetLocalConstantFloatvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_vertex_weighting: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glVertexWeightfEXT'; d: {$ifndef FPC}@{$endif}@glVertexWeightfEXT), + (n: 'glVertexWeightfvEXT'; d: {$ifndef FPC}@{$endif}@glVertexWeightfvEXT), + (n: 'glVertexWeightPointerEXT'; d: {$ifndef FPC}@{$endif}@glVertexWeightPointerEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_HP_occlusion_test: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_blend_square: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_copy_depth_to_color: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_depth_clamp: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_evaluators: Boolean; +const + funcs: array[0..8] of funcinfoty = + ( + (n: 'glMapControlPointsNV'; d: {$ifndef FPC}@{$endif}@glMapControlPointsNV), + (n: 'glMapParameterivNV'; d: {$ifndef FPC}@{$endif}@glMapParameterivNV), + (n: 'glMapParameterfvNV'; d: {$ifndef FPC}@{$endif}@glMapParameterfvNV), + (n: 'glGetMapControlPointsNV'; d: {$ifndef FPC}@{$endif}@glGetMapControlPointsNV), + (n: 'glGetMapParameterivNV'; d: {$ifndef FPC}@{$endif}@glGetMapParameterivNV), + (n: 'glGetMapParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetMapParameterfvNV), + (n: 'glGetMapAttribParameterivNV'; d: {$ifndef FPC}@{$endif}@glGetMapAttribParameterivNV), + (n: 'glGetMapAttribParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetMapAttribParameterfvNV), + (n: 'glEvalMapsNV'; d: {$ifndef FPC}@{$endif}@glEvalMapsNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_fence: Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glGenFencesNV'; d: {$ifndef FPC}@{$endif}@glGenFencesNV), + (n: 'glDeleteFencesNV'; d: {$ifndef FPC}@{$endif}@glDeleteFencesNV), + (n: 'glSetFenceNV'; d: {$ifndef FPC}@{$endif}@glSetFenceNV), + (n: 'glTestFenceNV'; d: {$ifndef FPC}@{$endif}@glTestFenceNV), + (n: 'glFinishFenceNV'; d: {$ifndef FPC}@{$endif}@glFinishFenceNV), + (n: 'glIsFenceNV'; d: {$ifndef FPC}@{$endif}@glIsFenceNV), + (n: 'glGetFenceivNV'; d: {$ifndef FPC}@{$endif}@glGetFenceivNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_fog_distance: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_light_max_exponent: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_multisample_filter_hint: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_occlusion_query: Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glGenOcclusionQueriesNV'; d: {$ifndef FPC}@{$endif}@glGenOcclusionQueriesNV), + (n: 'glDeleteOcclusionQueriesNV'; d: {$ifndef FPC}@{$endif}@glDeleteOcclusionQueriesNV), + (n: 'glIsOcclusionQueryNV'; d: {$ifndef FPC}@{$endif}@glIsOcclusionQueryNV), + (n: 'glBeginOcclusionQueryNV'; d: {$ifndef FPC}@{$endif}@glBeginOcclusionQueryNV), + (n: 'glEndOcclusionQueryNV'; d: {$ifndef FPC}@{$endif}@glEndOcclusionQueryNV), + (n: 'glGetOcclusionQueryivNV'; d: {$ifndef FPC}@{$endif}@glGetOcclusionQueryivNV), + (n: 'glGetOcclusionQueryuivNV'; d: {$ifndef FPC}@{$endif}@glGetOcclusionQueryuivNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_packed_depth_stencil: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_point_sprite: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPointParameteriNV'; d: {$ifndef FPC}@{$endif}@glPointParameteriNV), + (n: 'glPointParameterivNV'; d: {$ifndef FPC}@{$endif}@glPointParameterivNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_register_combiners: Boolean; +const + funcs: array[0..12] of funcinfoty = + ( + (n: 'glCombinerParameterfvNV'; d: {$ifndef FPC}@{$endif}@glCombinerParameterfvNV), + (n: 'glCombinerParameterivNV'; d: {$ifndef FPC}@{$endif}@glCombinerParameterivNV), + (n: 'glCombinerParameterfNV'; d: {$ifndef FPC}@{$endif}@glCombinerParameterfNV), + (n: 'glCombinerParameteriNV'; d: {$ifndef FPC}@{$endif}@glCombinerParameteriNV), + (n: 'glCombinerInputNV'; d: {$ifndef FPC}@{$endif}@glCombinerInputNV), + (n: 'glCombinerOutputNV'; d: {$ifndef FPC}@{$endif}@glCombinerOutputNV), + (n: 'glFinalCombinerInputNV'; d: {$ifndef FPC}@{$endif}@glFinalCombinerInputNV), + (n: 'glGetCombinerInputParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetCombinerInputParameterfvNV), + (n: 'glGetCombinerInputParameterivNV'; d: {$ifndef FPC}@{$endif}@glGetCombinerInputParameterivNV), + (n: 'glGetCombinerOutputParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetCombinerOutputParameterfvNV), + (n: 'glGetCombinerOutputParameterivNV'; d: {$ifndef FPC}@{$endif}@glGetCombinerOutputParameterivNV), + (n: 'glGetFinalCombinerInputParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetFinalCombinerInputParameterfvNV), + (n: 'glGetFinalCombinerInputParameterivNV'; d: {$ifndef FPC}@{$endif}@glGetFinalCombinerInputParameterivNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_register_combiners2: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glCombinerStageParameterfvNV'; d: {$ifndef FPC}@{$endif}@glCombinerStageParameterfvNV), + (n: 'glGetCombinerStageParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetCombinerStageParameterfvNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_texgen_emboss: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texgen_reflection: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_compression_vtc: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_env_combine4: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_rectangle: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_shader: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_shader2: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_shader3: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_vertex_array_range: Boolean; +const + funcs: array[0..{$ifdef mswindows}3{$else}1{$endif}] of funcinfoty = + ( + (n: 'glVertexArrayRangeNV'; d: {$ifndef FPC}@{$endif}@glVertexArrayRangeNV), + (n: 'glFlushVertexArrayRangeNV'; d: {$ifndef FPC}@{$endif}@glFlushVertexArrayRangeNV) +{$IFDEF msWindows} + , + (n: 'wglAllocateMemoryNV'; d: {$ifndef FPC}@{$endif}@wglAllocateMemoryNV), + (n: 'wglFreeMemoryNV'; d: {$ifndef FPC}@{$endif}@wglFreeMemoryNV) +{$ENDIF} + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_vertex_array_range2: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_vertex_program: Boolean; +const + funcs: array[0..61] of funcinfoty = + ( + (n: 'glBindProgramNV'; d: {$ifndef FPC}@{$endif}@glBindProgramNV), + (n: 'glDeleteProgramsNV'; d: {$ifndef FPC}@{$endif}@glDeleteProgramsNV), + (n: 'glExecuteProgramNV'; d: {$ifndef FPC}@{$endif}@glExecuteProgramNV), + (n: 'glGenProgramsNV'; d: {$ifndef FPC}@{$endif}@glGenProgramsNV), + (n: 'glAreProgramsResidentNV'; d: {$ifndef FPC}@{$endif}@glAreProgramsResidentNV), + (n: 'glRequestResidentProgramsNV'; d: {$ifndef FPC}@{$endif}@glRequestResidentProgramsNV), + (n: 'glGetProgramParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetProgramParameterfvNV), + (n: 'glGetProgramParameterdvNV'; d: {$ifndef FPC}@{$endif}@glGetProgramParameterdvNV), + (n: 'glGetProgramivNV'; d: {$ifndef FPC}@{$endif}@glGetProgramivNV), + (n: 'glGetProgramStringNV'; d: {$ifndef FPC}@{$endif}@glGetProgramStringNV), + (n: 'glGetTrackMatrixivNV'; d: {$ifndef FPC}@{$endif}@glGetTrackMatrixivNV), + (n: 'glGetVertexAttribdvNV'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribdvNV), + (n: 'glGetVertexAttribfvNV'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribfvNV), + (n: 'glGetVertexAttribivNV'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribivNV), + (n: 'glGetVertexAttribPointervNV'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribPointervNV), + (n: 'glIsProgramNV'; d: {$ifndef FPC}@{$endif}@glIsProgramNV), + (n: 'glLoadProgramNV'; d: {$ifndef FPC}@{$endif}@glLoadProgramNV), + (n: 'glProgramParameter4fNV'; d: {$ifndef FPC}@{$endif}@glProgramParameter4fNV), + (n: 'glProgramParameter4fvNV'; d: {$ifndef FPC}@{$endif}@glProgramParameter4fvNV), + (n: 'glProgramParameters4dvNV'; d: {$ifndef FPC}@{$endif}@glProgramParameters4dvNV), + (n: 'glProgramParameters4fvNV'; d: {$ifndef FPC}@{$endif}@glProgramParameters4fvNV), + (n: 'glTrackMatrixNV'; d: {$ifndef FPC}@{$endif}@glTrackMatrixNV), + (n: 'glVertexAttribPointerNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribPointerNV), + (n: 'glVertexAttrib1sNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1sNV), + (n: 'glVertexAttrib1fNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fNV), + (n: 'glVertexAttrib1dNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dNV), + (n: 'glVertexAttrib2sNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2sNV), + (n: 'glVertexAttrib2fNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fNV), + (n: 'glVertexAttrib2dNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dNV), + (n: 'glVertexAttrib3sNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3sNV), + (n: 'glVertexAttrib3fNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fNV), + (n: 'glVertexAttrib3dNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dNV), + (n: 'glVertexAttrib4sNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4sNV), + (n: 'glVertexAttrib4fNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fNV), + (n: 'glVertexAttrib4dNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dNV), + (n: 'glVertexAttrib4ubNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ubNV), + (n: 'glVertexAttrib1svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1svNV), + (n: 'glVertexAttrib1fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fvNV), + (n: 'glVertexAttrib1dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dvNV), + (n: 'glVertexAttrib2svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2svNV), + (n: 'glVertexAttrib2fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fvNV), + (n: 'glVertexAttrib2dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dvNV), + (n: 'glVertexAttrib3svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3svNV), + (n: 'glVertexAttrib3fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fvNV), + (n: 'glVertexAttrib3dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dvNV), + (n: 'glVertexAttrib4svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4svNV), + (n: 'glVertexAttrib4fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fvNV), + (n: 'glVertexAttrib4dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dvNV), + (n: 'glVertexAttrib4ubvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ubvNV), + (n: 'glVertexAttribs1svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs1svNV), + (n: 'glVertexAttribs1fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs1fvNV), + (n: 'glVertexAttribs1dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs1dvNV), + (n: 'glVertexAttribs2svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs2svNV), + (n: 'glVertexAttribs2fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs2fvNV), + (n: 'glVertexAttribs2dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs2dvNV), + (n: 'glVertexAttribs3svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs3svNV), + (n: 'glVertexAttribs3fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs3fvNV), + (n: 'glVertexAttribs3dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs3dvNV), + (n: 'glVertexAttribs4svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs4svNV), + (n: 'glVertexAttribs4fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs4fvNV), + (n: 'glVertexAttribs4dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs4dvNV), + (n: 'glVertexAttribs4ubvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs4ubvNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_vertex_program1_1: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ATI_element_array: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glElementPointerATI'; d: {$ifndef FPC}@{$endif}@glElementPointerATI), + (n: 'glDrawElementArrayATI'; d: {$ifndef FPC}@{$endif}@glDrawElementArrayATI), + (n: 'glDrawRangeElementArrayATI'; d: {$ifndef FPC}@{$endif}@glDrawRangeElementArrayATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_envmap_bumpmap: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glTexBumpParameterivATI'; d: {$ifndef FPC}@{$endif}@glTexBumpParameterivATI), + (n: 'glTexBumpParameterfvATI'; d: {$ifndef FPC}@{$endif}@glTexBumpParameterfvATI), + (n: 'glGetTexBumpParameterivATI'; d: {$ifndef FPC}@{$endif}@glGetTexBumpParameterivATI), + (n: 'glGetTexBumpParameterfvATI'; d: {$ifndef FPC}@{$endif}@glGetTexBumpParameterfvATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_fragment_shader: Boolean; +const + funcs: array[0..13] of funcinfoty = + ( + (n: 'glGenFragmentShadersATI'; d: {$ifndef FPC}@{$endif}@glGenFragmentShadersATI), + (n: 'glBindFragmentShaderATI'; d: {$ifndef FPC}@{$endif}@glBindFragmentShaderATI), + (n: 'glDeleteFragmentShaderATI'; d: {$ifndef FPC}@{$endif}@glDeleteFragmentShaderATI), + (n: 'glBeginFragmentShaderATI'; d: {$ifndef FPC}@{$endif}@glBeginFragmentShaderATI), + (n: 'glEndFragmentShaderATI'; d: {$ifndef FPC}@{$endif}@glEndFragmentShaderATI), + (n: 'glPassTexCoordATI'; d: {$ifndef FPC}@{$endif}@glPassTexCoordATI), + (n: 'glSampleMapATI'; d: {$ifndef FPC}@{$endif}@glSampleMapATI), + (n: 'glColorFragmentOp1ATI'; d: {$ifndef FPC}@{$endif}@glColorFragmentOp1ATI), + (n: 'glColorFragmentOp2ATI'; d: {$ifndef FPC}@{$endif}@glColorFragmentOp2ATI), + (n: 'glColorFragmentOp3ATI'; d: {$ifndef FPC}@{$endif}@glColorFragmentOp3ATI), + (n: 'glAlphaFragmentOp1ATI'; d: {$ifndef FPC}@{$endif}@glAlphaFragmentOp1ATI), + (n: 'glAlphaFragmentOp2ATI'; d: {$ifndef FPC}@{$endif}@glAlphaFragmentOp2ATI), + (n: 'glAlphaFragmentOp3ATI'; d: {$ifndef FPC}@{$endif}@glAlphaFragmentOp3ATI), + (n: 'glSetFragmentShaderConstantATI'; d: {$ifndef FPC}@{$endif}@glSetFragmentShaderConstantATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_pn_triangles: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPNTrianglesiATI'; d: {$ifndef FPC}@{$endif}@glPNTrianglesiATI), + (n: 'glPNTrianglesfATI'; d: {$ifndef FPC}@{$endif}@glPNTrianglesfATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_texture_mirror_once: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ATI_vertex_array_object: Boolean; +const + funcs: array[0..11] of funcinfoty = + ( + (n: 'glNewObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glNewObjectBufferATI), + (n: 'glIsObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glIsObjectBufferATI), + (n: 'glUpdateObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glUpdateObjectBufferATI), + (n: 'glGetObjectBufferfvATI'; d: {$ifndef FPC}@{$endif}@glGetObjectBufferfvATI), + (n: 'glGetObjectBufferivATI'; d: {$ifndef FPC}@{$endif}@glGetObjectBufferivATI), + (n: 'glDeleteObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glDeleteObjectBufferATI), + (n: 'glArrayObjectATI'; d: {$ifndef FPC}@{$endif}@glArrayObjectATI), + (n: 'glGetArrayObjectfvATI'; d: {$ifndef FPC}@{$endif}@glGetArrayObjectfvATI), + (n: 'glGetArrayObjectivATI'; d: {$ifndef FPC}@{$endif}@glGetArrayObjectivATI), + (n: 'glVariantArrayObjectATI'; d: {$ifndef FPC}@{$endif}@glVariantArrayObjectATI), + (n: 'glGetVariantArrayObjectfvATI'; d: {$ifndef FPC}@{$endif}@glGetVariantArrayObjectfvATI), + (n: 'glGetVariantArrayObjectivATI'; d: {$ifndef FPC}@{$endif}@glGetVariantArrayObjectivATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_vertex_streams: Boolean; +const + funcs: array[0..44] of funcinfoty = + ( + (n: 'glVertexStream1s'; d: {$ifndef FPC}@{$endif}@glVertexStream1s), + (n: 'glVertexStream1i'; d: {$ifndef FPC}@{$endif}@glVertexStream1i), + (n: 'glVertexStream1f'; d: {$ifndef FPC}@{$endif}@glVertexStream1f), + (n: 'glVertexStream1d'; d: {$ifndef FPC}@{$endif}@glVertexStream1d), + (n: 'glVertexStream1sv'; d: {$ifndef FPC}@{$endif}@glVertexStream1sv), + (n: 'glVertexStream1iv'; d: {$ifndef FPC}@{$endif}@glVertexStream1iv), + (n: 'glVertexStream1fv'; d: {$ifndef FPC}@{$endif}@glVertexStream1fv), + (n: 'glVertexStream1dv'; d: {$ifndef FPC}@{$endif}@glVertexStream1dv), + (n: 'glVertexStream2s'; d: {$ifndef FPC}@{$endif}@glVertexStream2s), + (n: 'glVertexStream2i'; d: {$ifndef FPC}@{$endif}@glVertexStream2i), + (n: 'glVertexStream2f'; d: {$ifndef FPC}@{$endif}@glVertexStream2f), + (n: 'glVertexStream2d'; d: {$ifndef FPC}@{$endif}@glVertexStream2d), + (n: 'glVertexStream2sv'; d: {$ifndef FPC}@{$endif}@glVertexStream2sv), + (n: 'glVertexStream2iv'; d: {$ifndef FPC}@{$endif}@glVertexStream2iv), + (n: 'glVertexStream2fv'; d: {$ifndef FPC}@{$endif}@glVertexStream2fv), + (n: 'glVertexStream2dv'; d: {$ifndef FPC}@{$endif}@glVertexStream2dv), + (n: 'glVertexStream3s'; d: {$ifndef FPC}@{$endif}@glVertexStream3s), + (n: 'glVertexStream3i'; d: {$ifndef FPC}@{$endif}@glVertexStream3i), + (n: 'glVertexStream3f'; d: {$ifndef FPC}@{$endif}@glVertexStream3f), + (n: 'glVertexStream3d'; d: {$ifndef FPC}@{$endif}@glVertexStream3d), + (n: 'glVertexStream3sv'; d: {$ifndef FPC}@{$endif}@glVertexStream3sv), + (n: 'glVertexStream3iv'; d: {$ifndef FPC}@{$endif}@glVertexStream3iv), + (n: 'glVertexStream3fv'; d: {$ifndef FPC}@{$endif}@glVertexStream3fv), + (n: 'glVertexStream3dv'; d: {$ifndef FPC}@{$endif}@glVertexStream3dv), + (n: 'glVertexStream4s'; d: {$ifndef FPC}@{$endif}@glVertexStream4s), + (n: 'glVertexStream4i'; d: {$ifndef FPC}@{$endif}@glVertexStream4i), + (n: 'glVertexStream4f'; d: {$ifndef FPC}@{$endif}@glVertexStream4f), + (n: 'glVertexStream4d'; d: {$ifndef FPC}@{$endif}@glVertexStream4d), + (n: 'glVertexStream4sv'; d: {$ifndef FPC}@{$endif}@glVertexStream4sv), + (n: 'glVertexStream4iv'; d: {$ifndef FPC}@{$endif}@glVertexStream4iv), + (n: 'glVertexStream4fv'; d: {$ifndef FPC}@{$endif}@glVertexStream4fv), + (n: 'glVertexStream4dv'; d: {$ifndef FPC}@{$endif}@glVertexStream4dv), + (n: 'glNormalStream3b'; d: {$ifndef FPC}@{$endif}@glNormalStream3b), + (n: 'glNormalStream3s'; d: {$ifndef FPC}@{$endif}@glNormalStream3s), + (n: 'glNormalStream3i'; d: {$ifndef FPC}@{$endif}@glNormalStream3i), + (n: 'glNormalStream3f'; d: {$ifndef FPC}@{$endif}@glNormalStream3f), + (n: 'glNormalStream3d'; d: {$ifndef FPC}@{$endif}@glNormalStream3d), + (n: 'glNormalStream3bv'; d: {$ifndef FPC}@{$endif}@glNormalStream3bv), + (n: 'glNormalStream3sv'; d: {$ifndef FPC}@{$endif}@glNormalStream3sv), + (n: 'glNormalStream3iv'; d: {$ifndef FPC}@{$endif}@glNormalStream3iv), + (n: 'glNormalStream3fv'; d: {$ifndef FPC}@{$endif}@glNormalStream3fv), + (n: 'glNormalStream3dv'; d: {$ifndef FPC}@{$endif}@glNormalStream3dv), + (n: 'glClientActiveVertexStream'; d: {$ifndef FPC}@{$endif}@glClientActiveVertexStream), + (n: 'glVertexBlendEnvi'; d: {$ifndef FPC}@{$endif}@glVertexBlendEnvi), + (n: 'glVertexBlendEnvf'; d: {$ifndef FPC}@{$endif}@glVertexBlendEnvf) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +{$IFDEF msWindows} +function Load_WGL_I3D_image_buffer: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'wglCreateImageBufferI3D'; d: {$ifndef FPC}@{$endif}@wglCreateImageBufferI3D), + (n: 'wglDestroyImageBufferI3D'; d: {$ifndef FPC}@{$endif}@wglDestroyImageBufferI3D), + (n: 'wglAssociateImageBufferEventsI3D'; d: {$ifndef FPC}@{$endif}@wglAssociateImageBufferEventsI3D), + (n: 'wglReleaseImageBufferEventsI3D'; d: {$ifndef FPC}@{$endif}@wglReleaseImageBufferEventsI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_I3D_swap_frame_lock: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'wglEnableFrameLockI3D'; d: {$ifndef FPC}@{$endif}@wglEnableFrameLockI3D), + (n: 'wglDisableFrameLockI3D'; d: {$ifndef FPC}@{$endif}@wglDisableFrameLockI3D), + (n: 'wglIsEnabledFrameLockI3D'; d: {$ifndef FPC}@{$endif}@wglIsEnabledFrameLockI3D), + (n: 'wglQueryFrameLockMasterI3D'; d: {$ifndef FPC}@{$endif}@wglQueryFrameLockMasterI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_I3D_swap_frame_usage: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'wglGetFrameUsageI3D'; d: {$ifndef FPC}@{$endif}@wglGetFrameUsageI3D), + (n: 'wglBeginFrameTrackingI3D'; d: {$ifndef FPC}@{$endif}@wglBeginFrameTrackingI3D), + (n: 'wglEndFrameTrackingI3D'; d: {$ifndef FPC}@{$endif}@wglEndFrameTrackingI3D), + (n: 'wglQueryFrameTrackingI3D'; d: {$ifndef FPC}@{$endif}@wglQueryFrameTrackingI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; +{$ENDIF} + +function Load_GL_3DFX_texture_compression_FXT1: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_IBM_cull_vertex: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_IBM_multimode_draw_arrays: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glMultiModeDrawArraysIBM'; d: {$ifndef FPC}@{$endif}@glMultiModeDrawArraysIBM), + (n: 'glMultiModeDrawElementsIBM'; d: {$ifndef FPC}@{$endif}@glMultiModeDrawElementsIBM) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_IBM_raster_pos_clip: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_IBM_texture_mirrored_repeat: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_IBM_vertex_array_lists: Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glColorPointerListIBM'; d: {$ifndef FPC}@{$endif}@glColorPointerListIBM), + (n: 'glSecondaryColorPointerListIBM'; d: {$ifndef FPC}@{$endif}@glSecondaryColorPointerListIBM), + (n: 'glEdgeFlagPointerListIBM'; d: {$ifndef FPC}@{$endif}@glEdgeFlagPointerListIBM), + (n: 'glFogCoordPointerListIBM'; d: {$ifndef FPC}@{$endif}@glFogCoordPointerListIBM), + (n: 'glNormalPointerListIBM'; d: {$ifndef FPC}@{$endif}@glNormalPointerListIBM), + (n: 'glTexCoordPointerListIBM'; d: {$ifndef FPC}@{$endif}@glTexCoordPointerListIBM), + (n: 'glVertexPointerListIBM'; d: {$ifndef FPC}@{$endif}@glVertexPointerListIBM) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_MESA_resize_buffers: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glResizeBuffersMESA'; d: {$ifndef FPC}@{$endif}@glResizeBuffersMESA) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_MESA_window_pos: Boolean; +const + funcs: array[0..23] of funcinfoty = + ( + (n: 'glWindowPos2dMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2dMESA), + (n: 'glWindowPos2fMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2fMESA), + (n: 'glWindowPos2iMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2iMESA), + (n: 'glWindowPos2sMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2sMESA), + (n: 'glWindowPos2ivMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2ivMESA), + (n: 'glWindowPos2svMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2svMESA), + (n: 'glWindowPos2fvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2fvMESA), + (n: 'glWindowPos2dvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2dvMESA), + (n: 'glWindowPos3iMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3iMESA), + (n: 'glWindowPos3sMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3sMESA), + (n: 'glWindowPos3fMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3fMESA), + (n: 'glWindowPos3dMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3dMESA), + (n: 'glWindowPos3ivMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3ivMESA), + (n: 'glWindowPos3svMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3svMESA), + (n: 'glWindowPos3fvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3fvMESA), + (n: 'glWindowPos3dvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3dvMESA), + (n: 'glWindowPos4iMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4iMESA), + (n: 'glWindowPos4sMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4sMESA), + (n: 'glWindowPos4fMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4fMESA), + (n: 'glWindowPos4dMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4dMESA), + (n: 'glWindowPos4ivMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4ivMESA), + (n: 'glWindowPos4svMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4svMESA), + (n: 'glWindowPos4fvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4fvMESA), + (n: 'glWindowPos4dvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4dvMESA) + ); +begin + result:= getprocaddresses(libgl,funcs); + +end; + +function Load_GL_OML_interlace: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_OML_resample: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_OML_subsample: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIS_generate_mipmap: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIS_multisample: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glSampleMaskSGIS'; d: {$ifndef FPC}@{$endif}@glSampleMaskSGIS), + (n: 'glSamplePatternSGIS'; d: {$ifndef FPC}@{$endif}@glSamplePatternSGIS) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_SGIS_pixel_texture: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glPixelTexGenParameteriSGIS'; d: {$ifndef FPC}@{$endif}@glPixelTexGenParameteriSGIS), + (n: 'glPixelTexGenParameterfSGIS'; d: {$ifndef FPC}@{$endif}@glPixelTexGenParameterfSGIS), + (n: 'glGetPixelTexGenParameterivSGIS'; d: {$ifndef FPC}@{$endif}@glGetPixelTexGenParameterivSGIS), + (n: 'glGetPixelTexGenParameterfvSGIS'; d: {$ifndef FPC}@{$endif}@glGetPixelTexGenParameterfvSGIS) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_SGIS_texture_border_clamp: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIS_texture_color_mask: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glTextureColorMaskSGIS'; d: {$ifndef FPC}@{$endif}@glTextureColorMaskSGIS) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_SGIS_texture_edge_clamp: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIS_texture_lod: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIS_depth_texture: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIX_fog_offset: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIX_interlace: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIX_shadow_ambient: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGI_color_matrix: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGI_color_table: Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glColorTableSGI'; d: {$ifndef FPC}@{$endif}@glColorTableSGI), + (n: 'glCopyColorTableSGI'; d: {$ifndef FPC}@{$endif}@glCopyColorTableSGI), + (n: 'glColorTableParameterivSGI'; d: {$ifndef FPC}@{$endif}@glColorTableParameterivSGI), + (n: 'glColorTableParameterfvSGI'; d: {$ifndef FPC}@{$endif}@glColorTableParameterfvSGI), + (n: 'glGetColorTableSGI'; d: {$ifndef FPC}@{$endif}@glGetColorTableSGI), + (n: 'glGetColorTableParameterivSGI'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameterivSGI), + (n: 'glGetColorTableParameterfvSGI'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameterfvSGI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_SGI_texture_color_table: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SUN_vertex: Boolean; +const + funcs: array[0..39] of funcinfoty = + ( + (n: 'glColor4ubVertex2fSUN'; d: {$ifndef FPC}@{$endif}@glColor4ubVertex2fSUN), + (n: 'glColor4ubVertex2fvSUN'; d: {$ifndef FPC}@{$endif}@glColor4ubVertex2fvSUN), + (n: 'glColor4ubVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glColor4ubVertex3fSUN), + (n: 'glColor4ubVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glColor4ubVertex3fvSUN), + (n: 'glColor3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glColor3fVertex3fSUN), + (n: 'glColor3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glColor3fVertex3fvSUN), + (n: 'glNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glNormal3fVertex3fSUN), + (n: 'glNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glNormal3fVertex3fvSUN), + (n: 'glColor4fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glColor4fNormal3fVertex3fSUN), + (n: 'glColor4fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glColor4fNormal3fVertex3fvSUN), + (n: 'glTexCoord2fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fVertex3fSUN), + (n: 'glTexCoord2fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fVertex3fvSUN), + (n: 'glTexCoord4fVertex4fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord4fVertex4fSUN), + (n: 'glTexCoord4fVertex4fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord4fVertex4fvSUN), + (n: 'glTexCoord2fColor4ubVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor4ubVertex3fSUN), + (n: 'glTexCoord2fColor4ubVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor4ubVertex3fvSUN), + (n: 'glTexCoord2fColor3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor3fVertex3fSUN), + (n: 'glTexCoord2fColor3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor3fVertex3fvSUN), + (n: 'glTexCoord2fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fNormal3fVertex3fSUN), + (n: 'glTexCoord2fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fNormal3fVertex3fvSUN), + (n: 'glTexCoord2fColor4fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor4fNormal3fVertex3fSUN), + (n: 'glTexCoord2fColor4fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor4fNormal3fVertex3fvSUN), + (n: 'glTexCoord4fColor4fNormal3fVertex4fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord4fColor4fNormal3fVertex4fSUN), + (n: 'glTexCoord4fColor4fNormal3fVertex4fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord4fColor4fNormal3fVertex4fvSUN), + (n: 'glReplacementCodeuiVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiVertex3fSUN), + (n: 'glReplacementCodeuiVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiVertex3fvSUN), + (n: 'glReplacementCodeuiColor4ubVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor4ubVertex3fSUN), + (n: 'glReplacementCodeuiColor4ubVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor4ubVertex3fvSUN), + (n: 'glReplacementCodeuiColor3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor3fVertex3fSUN), + (n: 'glReplacementCodeuiColor3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor3fVertex3fvSUN), + (n: 'glReplacementCodeuiNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiNormal3fVertex3fSUN), + (n: 'glReplacementCodeuiNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiNormal3fVertex3fvSUN), + (n: 'glReplacementCodeuiColor4fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor4fNormal3fVertex3fSUN), + (n: 'glReplacementCodeuiColor4fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor4fNormal3fVertex3fvSUN), + (n: 'glReplacementCodeuiTexCoord2fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fVertex3fSUN), + (n: 'glReplacementCodeuiTexCoord2fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fVertex3fvSUN), + (n: 'glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN), + (n: 'glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN), + (n: 'glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN), + (n: 'glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_fragment_program: Boolean; +const + funcs: array[0..18] of funcinfoty = + ( + (n: 'glProgramStringARB'; d: {$ifndef FPC}@{$endif}@glProgramStringARB), + (n: 'glBindProgramARB'; d: {$ifndef FPC}@{$endif}@glBindProgramARB), + (n: 'glDeleteProgramsARB'; d: {$ifndef FPC}@{$endif}@glDeleteProgramsARB), + (n: 'glGenProgramsARB'; d: {$ifndef FPC}@{$endif}@glGenProgramsARB), + (n: 'glProgramEnvParameter4dARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4dARB), + (n: 'glProgramEnvParameter4dvARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4dvARB), + (n: 'glProgramEnvParameter4fARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4fARB), + (n: 'glProgramEnvParameter4fvARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4fvARB), + (n: 'glProgramLocalParameter4dARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dARB), + (n: 'glProgramLocalParameter4dvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dvARB), + (n: 'glProgramLocalParameter4fARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fARB), + (n: 'glProgramLocalParameter4fvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fvARB), + (n: 'glGetProgramEnvParameterdvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramEnvParameterdvARB), + (n: 'glGetProgramEnvParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramEnvParameterfvARB), + (n: 'glGetProgramLocalParameterdvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterdvARB), + (n: 'glGetProgramLocalParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterfvARB), + (n: 'glGetProgramivARB'; d: {$ifndef FPC}@{$endif}@glGetProgramivARB), + (n: 'glGetProgramStringARB'; d: {$ifndef FPC}@{$endif}@glGetProgramStringARB), + (n: 'glIsProgramARB'; d: {$ifndef FPC}@{$endif}@glIsProgramARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_text_fragment_shader: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_APPLE_client_storage: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_APPLE_element_array: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glElementPointerAPPLE'; d: {$ifndef FPC}@{$endif}@glElementPointerAPPLE), + (n: 'glDrawElementArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glDrawElementArrayAPPLE), + (n: 'glDrawRangeElementArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glDrawRangeElementArrayAPPLE), + (n: 'glMultiDrawElementArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glMultiDrawElementArrayAPPLE), + (n: 'glMultiDrawRangeElementArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glMultiDrawRangeElementArrayAPPLE) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_APPLE_fence: Boolean; +const + funcs: array[0..7] of funcinfoty = + ( + (n: 'glGenFencesAPPLE'; d: {$ifndef FPC}@{$endif}@glGenFencesAPPLE), + (n: 'glDeleteFencesAPPLE'; d: {$ifndef FPC}@{$endif}@glDeleteFencesAPPLE), + (n: 'glSetFenceAPPLE'; d: {$ifndef FPC}@{$endif}@glSetFenceAPPLE), + (n: 'glIsFenceAPPLE'; d: {$ifndef FPC}@{$endif}@glIsFenceAPPLE), + (n: 'glTestFenceAPPLE'; d: {$ifndef FPC}@{$endif}@glTestFenceAPPLE), + (n: 'glFinishFenceAPPLE'; d: {$ifndef FPC}@{$endif}@glFinishFenceAPPLE), + (n: 'glTestObjectAPPLE'; d: {$ifndef FPC}@{$endif}@glTestObjectAPPLE), + (n: 'glFinishObjectAPPLE'; d: {$ifndef FPC}@{$endif}@glFinishObjectAPPLE) + ); +begin + result:= getprocaddresses(libgl,funcs); + +end; + +function Load_GL_APPLE_vertex_array_object: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glBindVertexArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glBindVertexArrayAPPLE), + (n: 'glDeleteVertexArraysAPPLE'; d: {$ifndef FPC}@{$endif}@glDeleteVertexArraysAPPLE), + (n: 'glGenVertexArraysAPPLE'; d: {$ifndef FPC}@{$endif}@glGenVertexArraysAPPLE), + (n: 'glIsVertexArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glIsVertexArrayAPPLE) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_APPLE_vertex_array_range: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glVertexArrayRangeAPPLE'; d: {$ifndef FPC}@{$endif}@glVertexArrayRangeAPPLE), + (n: 'glFlushVertexArrayRangeAPPLE'; d: {$ifndef FPC}@{$endif}@glFlushVertexArrayRangeAPPLE), + (n: 'glVertexArrayParameteriAPPLE'; d: {$ifndef FPC}@{$endif}@glVertexArrayParameteriAPPLE) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + + +function load_GL_ARB_vertex_buffer_object : boolean; +const + funcs: array[0..10] of funcinfoty = + ( + (n: 'glBindBufferARB'; d: {$ifndef FPC}@{$endif}@glBindBufferARB), + (n: 'glDeleteBuffersARB'; d: {$ifndef FPC}@{$endif}@glDeleteBuffersARB), + (n: 'glGenBuffersARB'; d: {$ifndef FPC}@{$endif}@glGenBuffersARB), + (n: 'glIsBufferARB'; d: {$ifndef FPC}@{$endif}@glIsBufferARB), + (n: 'glBufferDataARB'; d: {$ifndef FPC}@{$endif}@glBufferDataARB), + (n: 'glBufferSubDataARB'; d: {$ifndef FPC}@{$endif}@glBufferSubDataARB), + (n: 'glGetBufferSubDataARB'; d: {$ifndef FPC}@{$endif}@glGetBufferSubDataARB), + (n: 'glMapBufferARB'; d: {$ifndef FPC}@{$endif}@glMapBufferARB), + (n: 'glUnmapBufferARB'; d: {$ifndef FPC}@{$endif}@glUnmapBufferARB), + (n: 'glGetBufferParameterivARB'; d: {$ifndef FPC}@{$endif}@glGetBufferParameterivARB), + (n: 'glGetBufferPointervARB'; d: {$ifndef FPC}@{$endif}@glGetBufferPointervARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +{$IFDEF msWindows} +function Load_WGL_ARB_pixel_format: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'wglGetPixelFormatAttribivARB'; d: {$ifndef FPC}@{$endif}@wglGetPixelFormatAttribivARB), + (n: 'wglGetPixelFormatAttribfvARB'; d: {$ifndef FPC}@{$endif}@wglGetPixelFormatAttribfvARB), + (n: 'wglChoosePixelFormatARB'; d: {$ifndef FPC}@{$endif}@wglChoosePixelFormatARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_ARB_make_current_read: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'wglMakeContextCurrentARB'; d: {$ifndef FPC}@{$endif}@wglMakeContextCurrentARB), + (n: 'wglGetCurrentReadDCARB'; d: {$ifndef FPC}@{$endif}@wglGetCurrentReadDCARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_ARB_pbuffer: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'wglCreatePbufferARB'; d: {$ifndef FPC}@{$endif}@wglCreatePbufferARB), + (n: 'wglGetPbufferDCARB'; d: {$ifndef FPC}@{$endif}@wglGetPbufferDCARB), + (n: 'wglReleasePbufferDCARB'; d: {$ifndef FPC}@{$endif}@wglReleasePbufferDCARB), + (n: 'wglDestroyPbufferARB'; d: {$ifndef FPC}@{$endif}@wglDestroyPbufferARB), + (n: 'wglQueryPbufferARB'; d: {$ifndef FPC}@{$endif}@wglQueryPbufferARB) + ); +begin + result:= getprocaddresses(libgl,funcs); + +end; + +function Load_WGL_EXT_swap_control: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'wglSwapIntervalEXT'; d: {$ifndef FPC}@{$endif}@wglSwapIntervalEXT), + (n: 'wglGetSwapIntervalEXT'; d: {$ifndef FPC}@{$endif}@wglGetSwapIntervalEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_ARB_render_texture: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'wglBindTexImageARB'; d: {$ifndef FPC}@{$endif}@wglBindTexImageARB), + (n: 'wglReleaseTexImageARB'; d: {$ifndef FPC}@{$endif}@wglReleaseTexImageARB), + (n: 'wglSetPbufferAttribARB'; d: {$ifndef FPC}@{$endif}@wglSetPbufferAttribARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_EXT_extensions_string: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'wglGetExtensionsStringEXT'; d: {$ifndef FPC}@{$endif}@wglGetExtensionsStringEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_EXT_make_current_read: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'wglMakeContextCurrentEXT'; d: {$ifndef FPC}@{$endif}@wglMakeContextCurrentEXT), + (n: 'wglGetCurrentReadDCEXT'; d: {$ifndef FPC}@{$endif}@wglGetCurrentReadDCEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_EXT_pbuffer: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'wglCreatePbufferEXT'; d: {$ifndef FPC}@{$endif}@wglCreatePbufferEXT), + (n: 'wglGetPbufferDCEXT'; d: {$ifndef FPC}@{$endif}@wglGetPbufferDCEXT), + (n: 'wglReleasePbufferDCEXT'; d: {$ifndef FPC}@{$endif}@wglReleasePbufferDCEXT), + (n: 'wglDestroyPbufferEXT'; d: {$ifndef FPC}@{$endif}@wglDestroyPbufferEXT), + (n: 'wglQueryPbufferEXT'; d: {$ifndef FPC}@{$endif}@wglQueryPbufferEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_EXT_pixel_format: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'wglGetPixelFormatAttribivEXT'; d: {$ifndef FPC}@{$endif}@wglGetPixelFormatAttribivEXT), + (n: 'wglGetPixelFormatAttribfvEXT'; d: {$ifndef FPC}@{$endif}@wglGetPixelFormatAttribfvEXT), + (n: 'wglChoosePixelFormatEXT'; d: {$ifndef FPC}@{$endif}@wglChoosePixelFormatEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_I3D_digital_video_control: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'wglGetDigitalVideoParametersI3D'; d: {$ifndef FPC}@{$endif}@wglGetDigitalVideoParametersI3D), + (n: 'wglSetDigitalVideoParametersI3D'; d: {$ifndef FPC}@{$endif}@wglSetDigitalVideoParametersI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_I3D_gamma: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'wglGetGammaTableParametersI3D'; d: {$ifndef FPC}@{$endif}@wglGetGammaTableParametersI3D), + (n: 'wglSetGammaTableParametersI3D'; d: {$ifndef FPC}@{$endif}@wglSetGammaTableParametersI3D), + (n: 'wglGetGammaTableI3D'; d: {$ifndef FPC}@{$endif}@wglGetGammaTableI3D), + (n: 'wglSetGammaTableI3D'; d: {$ifndef FPC}@{$endif}@wglSetGammaTableI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_I3D_genlock: Boolean; +const + funcs: array[0..11] of funcinfoty = + ( + (n: 'wglEnableGenlockI3D'; d: {$ifndef FPC}@{$endif}@wglEnableGenlockI3D), + (n: 'wglDisableGenlockI3D'; d: {$ifndef FPC}@{$endif}@wglDisableGenlockI3D), + (n: 'wglIsEnabledGenlockI3D'; d: {$ifndef FPC}@{$endif}@wglIsEnabledGenlockI3D), + (n: 'wglGenlockSourceI3D'; d: {$ifndef FPC}@{$endif}@wglGenlockSourceI3D), + (n: 'wglGetGenlockSourceI3D'; d: {$ifndef FPC}@{$endif}@wglGetGenlockSourceI3D), + (n: 'wglGenlockSourceEdgeI3D'; d: {$ifndef FPC}@{$endif}@wglGenlockSourceEdgeI3D), + (n: 'wglGetGenlockSourceEdgeI3D'; d: {$ifndef FPC}@{$endif}@wglGetGenlockSourceEdgeI3D), + (n: 'wglGenlockSampleRateI3D'; d: {$ifndef FPC}@{$endif}@wglGenlockSampleRateI3D), + (n: 'wglGetGenlockSampleRateI3D'; d: {$ifndef FPC}@{$endif}@wglGetGenlockSampleRateI3D), + (n: 'wglGenlockSourceDelayI3D'; d: {$ifndef FPC}@{$endif}@wglGenlockSourceDelayI3D), + (n: 'wglGetGenlockSourceDelayI3D'; d: {$ifndef FPC}@{$endif}@wglGetGenlockSourceDelayI3D), + (n: 'wglQueryGenlockMaxSourceDelayI3D'; d: {$ifndef FPC}@{$endif}@wglQueryGenlockMaxSourceDelayI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; +{$ENDIF} + +function Load_GL_ARB_matrix_palette: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glCurrentPaletteMatrixARB'; d: {$ifndef FPC}@{$endif}@glCurrentPaletteMatrixARB), + (n: 'glMatrixIndexubvARB'; d: {$ifndef FPC}@{$endif}@glMatrixIndexubvARB), + (n: 'glMatrixIndexusvARB'; d: {$ifndef FPC}@{$endif}@glMatrixIndexusvARB), + (n: 'glMatrixIndexuivARB'; d: {$ifndef FPC}@{$endif}@glMatrixIndexuivARB), + (n: 'glMatrixIndexPointerARB'; d: {$ifndef FPC}@{$endif}@glMatrixIndexPointerARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_element_array: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glElementPointerNV'; d: {$ifndef FPC}@{$endif}@glElementPointerNV), + (n: 'glDrawElementArrayNV'; d: {$ifndef FPC}@{$endif}@glDrawElementArrayNV), + (n: 'glDrawRangeElementArrayNV'; d: {$ifndef FPC}@{$endif}@glDrawRangeElementArrayNV), + (n: 'glMultiDrawElementArrayNV'; d: {$ifndef FPC}@{$endif}@glMultiDrawElementArrayNV), + (n: 'glMultiDrawRangeElementArrayNV'; d: {$ifndef FPC}@{$endif}@glMultiDrawRangeElementArrayNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_float_buffer: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_fragment_program: Boolean; +const + funcs: array[0..9] of funcinfoty = + ( + (n: 'glProgramNamedParameter4fNV'; d: {$ifndef FPC}@{$endif}@glProgramNamedParameter4fNV), + (n: 'glProgramNamedParameter4dNV'; d: {$ifndef FPC}@{$endif}@glProgramNamedParameter4dNV), + (n: 'glGetProgramNamedParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetProgramNamedParameterfvNV), + (n: 'glGetProgramNamedParameterdvNV'; d: {$ifndef FPC}@{$endif}@glGetProgramNamedParameterdvNV), + (n: 'glProgramLocalParameter4dARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dARB), + (n: 'glProgramLocalParameter4dvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dvARB), + (n: 'glProgramLocalParameter4fARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fARB), + (n: 'glProgramLocalParameter4fvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fvARB), + (n: 'glGetProgramLocalParameterdvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterdvARB), + (n: 'glGetProgramLocalParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterfvARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_primitive_restart: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPrimitiveRestartNV'; d: {$ifndef FPC}@{$endif}@glPrimitiveRestartNV), + (n: 'glPrimitiveRestartIndexNV'; d: {$ifndef FPC}@{$endif}@glPrimitiveRestartIndexNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_vertex_program2: Boolean; +begin + result:= true; //no procs +end; + +{$IFDEF msWindows} +function Load_WGL_NV_render_texture_rectangle: Boolean; +begin + result:= true; //no procs +end; +{$ENDIF} + +function Load_GL_NV_pixel_data_range: Boolean; +const + funcs: array[0..{$ifdef mswindows}3{$else}1{$endif}] of funcinfoty = + ( + (n: 'glPixelDataRangeNV'; d: {$ifndef FPC}@{$endif}@glPixelDataRangeNV), + (n: 'glFlushPixelDataRangeNV'; d: {$ifndef FPC}@{$endif}@glFlushPixelDataRangeNV) + {$IFDEF msWindows} + , + (n: 'wglAllocateMemoryNV'; d: {$ifndef FPC}@{$endif}@wglAllocateMemoryNV), + (n: 'wglFreeMemoryNV'; d: {$ifndef FPC}@{$endif}@wglFreeMemoryNV) + {$ENDIF} + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_texture_rectangle: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_S3_s3tc: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ATI_draw_buffers: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glDrawBuffersATI'; d: {$ifndef FPC}@{$endif}@glDrawBuffersATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +{$IFDEF msWindows} +function Load_WGL_ATI_pixel_format_float: Boolean; +begin + result:= true; //no procs +end; +{$ENDIF} + +function Load_GL_ATI_texture_env_combine3: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ATI_texture_float: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_expand_normal: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_half_float: Boolean; +const + funcs: array[0..45] of funcinfoty = + ( + (n: 'glVertex2hNV'; d: {$ifndef FPC}@{$endif}@glVertex2hNV), + (n: 'glVertex2hvNV'; d: {$ifndef FPC}@{$endif}@glVertex2hvNV), + (n: 'glVertex3hNV'; d: {$ifndef FPC}@{$endif}@glVertex3hNV), + (n: 'glVertex3hvNV'; d: {$ifndef FPC}@{$endif}@glVertex3hvNV), + (n: 'glVertex4hNV'; d: {$ifndef FPC}@{$endif}@glVertex4hNV), + (n: 'glVertex4hvNV'; d: {$ifndef FPC}@{$endif}@glVertex4hvNV), + (n: 'glNormal3hNV'; d: {$ifndef FPC}@{$endif}@glNormal3hNV), + (n: 'glNormal3hvNV'; d: {$ifndef FPC}@{$endif}@glNormal3hvNV), + (n: 'glColor3hNV'; d: {$ifndef FPC}@{$endif}@glColor3hNV), + (n: 'glColor3hvNV'; d: {$ifndef FPC}@{$endif}@glColor3hvNV), + (n: 'glColor4hNV'; d: {$ifndef FPC}@{$endif}@glColor4hNV), + (n: 'glColor4hvNV'; d: {$ifndef FPC}@{$endif}@glColor4hvNV), + (n: 'glTexCoord1hNV'; d: {$ifndef FPC}@{$endif}@glTexCoord1hNV), + (n: 'glTexCoord1hvNV'; d: {$ifndef FPC}@{$endif}@glTexCoord1hvNV), + (n: 'glTexCoord2hNV'; d: {$ifndef FPC}@{$endif}@glTexCoord2hNV), + (n: 'glTexCoord2hvNV'; d: {$ifndef FPC}@{$endif}@glTexCoord2hvNV), + (n: 'glTexCoord3hNV'; d: {$ifndef FPC}@{$endif}@glTexCoord3hNV), + (n: 'glTexCoord3hvNV'; d: {$ifndef FPC}@{$endif}@glTexCoord3hvNV), + (n: 'glTexCoord4hNV'; d: {$ifndef FPC}@{$endif}@glTexCoord4hNV), + (n: 'glTexCoord4hvNV'; d: {$ifndef FPC}@{$endif}@glTexCoord4hvNV), + (n: 'glMultiTexCoord1hNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1hNV), + (n: 'glMultiTexCoord1hvNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1hvNV), + (n: 'glMultiTexCoord2hNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2hNV), + (n: 'glMultiTexCoord2hvNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2hvNV), + (n: 'glMultiTexCoord3hNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3hNV), + (n: 'glMultiTexCoord3hvNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3hvNV), + (n: 'glMultiTexCoord4hNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4hNV), + (n: 'glMultiTexCoord4hvNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4hvNV), + (n: 'glFogCoordhNV'; d: {$ifndef FPC}@{$endif}@glFogCoordhNV), + (n: 'glFogCoordhvNV'; d: {$ifndef FPC}@{$endif}@glFogCoordhvNV), + (n: 'glSecondaryColor3hNV'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3hNV), + (n: 'glSecondaryColor3hvNV'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3hvNV), + (n: 'glVertexWeighthNV'; d: {$ifndef FPC}@{$endif}@glVertexWeighthNV), + (n: 'glVertexWeighthvNV'; d: {$ifndef FPC}@{$endif}@glVertexWeighthvNV), + (n: 'glVertexAttrib1hNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1hNV), + (n: 'glVertexAttrib1hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1hvNV), + (n: 'glVertexAttrib2hNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2hNV), + (n: 'glVertexAttrib2hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2hvNV), + (n: 'glVertexAttrib3hNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3hNV), + (n: 'glVertexAttrib3hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3hvNV), + (n: 'glVertexAttrib4hNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4hNV), + (n: 'glVertexAttrib4hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4hvNV), + (n: 'glVertexAttribs1hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs1hvNV), + (n: 'glVertexAttribs2hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs2hvNV), + (n: 'glVertexAttribs3hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs3hvNV), + (n: 'glVertexAttribs4hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs4hvNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_map_object_buffer: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glMapObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glMapObjectBufferATI), + (n: 'glUnmapObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glUnmapObjectBufferATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_separate_stencil: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glStencilOpSeparateATI'; d: {$ifndef FPC}@{$endif}@glStencilOpSeparateATI), + (n: 'glStencilFuncSeparateATI'; d: {$ifndef FPC}@{$endif}@glStencilFuncSeparateATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_vertex_attrib_array_object: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glVertexAttribArrayObjectATI'; d: {$ifndef FPC}@{$endif}@glVertexAttribArrayObjectATI), + (n: 'glGetVertexAttribArrayObjectfvATI'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribArrayObjectfvATI), + (n: 'glGetVertexAttribArrayObjectivATI'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribArrayObjectivATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_occlusion_query: Boolean; +const + funcs: array[0..7] of funcinfoty = + ( + (n: 'glGenQueriesARB'; d: {$ifndef FPC}@{$endif}@glGenQueriesARB), + (n: 'glDeleteQueriesARB'; d: {$ifndef FPC}@{$endif}@glDeleteQueriesARB), + (n: 'glIsQueryARB'; d: {$ifndef FPC}@{$endif}@glIsQueryARB), + (n: 'glBeginQueryARB'; d: {$ifndef FPC}@{$endif}@glBeginQueryARB), + (n: 'glEndQueryARB'; d: {$ifndef FPC}@{$endif}@glEndQueryARB), + (n: 'glGetQueryivARB'; d: {$ifndef FPC}@{$endif}@glGetQueryivARB), + (n: 'glGetQueryObjectivARB'; d: {$ifndef FPC}@{$endif}@glGetQueryObjectivARB), + (n: 'glGetQueryObjectuivARB'; d: {$ifndef FPC}@{$endif}@glGetQueryObjectuivARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_shader_objects: Boolean; +const + funcs: array[0..38] of funcinfoty = + ( + (n: 'glDeleteObjectARB'; d: {$ifndef FPC}@{$endif}@glDeleteObjectARB), + (n: 'glGetHandleARB'; d: {$ifndef FPC}@{$endif}@glGetHandleARB), + (n: 'glDetachObjectARB'; d: {$ifndef FPC}@{$endif}@glDetachObjectARB), + (n: 'glCreateShaderObjectARB'; d: {$ifndef FPC}@{$endif}@glCreateShaderObjectARB), + (n: 'glShaderSourceARB'; d: {$ifndef FPC}@{$endif}@glShaderSourceARB), + (n: 'glCompileShaderARB'; d: {$ifndef FPC}@{$endif}@glCompileShaderARB), + (n: 'glCreateProgramObjectARB'; d: {$ifndef FPC}@{$endif}@glCreateProgramObjectARB), + (n: 'glAttachObjectARB'; d: {$ifndef FPC}@{$endif}@glAttachObjectARB), + (n: 'glLinkProgramARB'; d: {$ifndef FPC}@{$endif}@glLinkProgramARB), + (n: 'glUseProgramObjectARB'; d: {$ifndef FPC}@{$endif}@glUseProgramObjectARB), + (n: 'glValidateProgramARB'; d: {$ifndef FPC}@{$endif}@glValidateProgramARB), + (n: 'glUniform1fARB'; d: {$ifndef FPC}@{$endif}@glUniform1fARB), + (n: 'glUniform2fARB'; d: {$ifndef FPC}@{$endif}@glUniform2fARB), + (n: 'glUniform3fARB'; d: {$ifndef FPC}@{$endif}@glUniform3fARB), + (n: 'glUniform4fARB'; d: {$ifndef FPC}@{$endif}@glUniform4fARB), + (n: 'glUniform1iARB'; d: {$ifndef FPC}@{$endif}@glUniform1iARB), + (n: 'glUniform2iARB'; d: {$ifndef FPC}@{$endif}@glUniform2iARB), + (n: 'glUniform3iARB'; d: {$ifndef FPC}@{$endif}@glUniform3iARB), + (n: 'glUniform4iARB'; d: {$ifndef FPC}@{$endif}@glUniform4iARB), + (n: 'glUniform1fvARB'; d: {$ifndef FPC}@{$endif}@glUniform1fvARB), + (n: 'glUniform2fvARB'; d: {$ifndef FPC}@{$endif}@glUniform2fvARB), + (n: 'glUniform3fvARB'; d: {$ifndef FPC}@{$endif}@glUniform3fvARB), + (n: 'glUniform4fvARB'; d: {$ifndef FPC}@{$endif}@glUniform4fvARB), + (n: 'glUniform1ivARB'; d: {$ifndef FPC}@{$endif}@glUniform1ivARB), + (n: 'glUniform2ivARB'; d: {$ifndef FPC}@{$endif}@glUniform2ivARB), + (n: 'glUniform3ivARB'; d: {$ifndef FPC}@{$endif}@glUniform3ivARB), + (n: 'glUniform4ivARB'; d: {$ifndef FPC}@{$endif}@glUniform4ivARB), + (n: 'glUniformMatrix2fvARB'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2fvARB), + (n: 'glUniformMatrix3fvARB'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3fvARB), + (n: 'glUniformMatrix4fvARB'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4fvARB), + (n: 'glGetObjectParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetObjectParameterfvARB), + (n: 'glGetObjectParameterivARB'; d: {$ifndef FPC}@{$endif}@glGetObjectParameterivARB), + (n: 'glGetInfoLogARB'; d: {$ifndef FPC}@{$endif}@glGetInfoLogARB), + (n: 'glGetAttachedObjectsARB'; d: {$ifndef FPC}@{$endif}@glGetAttachedObjectsARB), + (n: 'glGetUniformLocationARB'; d: {$ifndef FPC}@{$endif}@glGetUniformLocationARB), + (n: 'glGetActiveUniformARB'; d: {$ifndef FPC}@{$endif}@glGetActiveUniformARB), + (n: 'glGetUniformfvARB'; d: {$ifndef FPC}@{$endif}@glGetUniformfvARB), + (n: 'glGetUniformivARB'; d: {$ifndef FPC}@{$endif}@glGetUniformivARB), + (n: 'glGetShaderSourceARB'; d: {$ifndef FPC}@{$endif}@glGetShaderSourceARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_vertex_shader: Boolean; +const + funcs: array[0..45] of funcinfoty = + ( + (n: 'glVertexAttrib1fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fARB), + (n: 'glVertexAttrib1sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1sARB), + (n: 'glVertexAttrib1dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dARB), + (n: 'glVertexAttrib2fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fARB), + (n: 'glVertexAttrib2sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2sARB), + (n: 'glVertexAttrib2dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dARB), + (n: 'glVertexAttrib3fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fARB), + (n: 'glVertexAttrib3sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3sARB), + (n: 'glVertexAttrib3dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dARB), + (n: 'glVertexAttrib4fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fARB), + (n: 'glVertexAttrib4sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4sARB), + (n: 'glVertexAttrib4dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dARB), + (n: 'glVertexAttrib4NubARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NubARB), + (n: 'glVertexAttrib1fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fvARB), + (n: 'glVertexAttrib1svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1svARB), + (n: 'glVertexAttrib1dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dvARB), + (n: 'glVertexAttrib2fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fvARB), + (n: 'glVertexAttrib2svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2svARB), + (n: 'glVertexAttrib2dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dvARB), + (n: 'glVertexAttrib3fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fvARB), + (n: 'glVertexAttrib3svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3svARB), + (n: 'glVertexAttrib3dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dvARB), + (n: 'glVertexAttrib4fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fvARB), + (n: 'glVertexAttrib4svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4svARB), + (n: 'glVertexAttrib4dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dvARB), + (n: 'glVertexAttrib4ivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ivARB), + (n: 'glVertexAttrib4bvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4bvARB), + (n: 'glVertexAttrib4ubvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ubvARB), + (n: 'glVertexAttrib4usvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4usvARB), + (n: 'glVertexAttrib4uivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4uivARB), + (n: 'glVertexAttrib4NbvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NbvARB), + (n: 'glVertexAttrib4NsvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NsvARB), + (n: 'glVertexAttrib4NivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NivARB), + (n: 'glVertexAttrib4NubvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NubvARB), + (n: 'glVertexAttrib4NusvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NusvARB), + (n: 'glVertexAttrib4NuivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NuivARB), + (n: 'glVertexAttribPointerARB'; d: {$ifndef FPC}@{$endif}@glVertexAttribPointerARB), + (n: 'glEnableVertexAttribArrayARB'; d: {$ifndef FPC}@{$endif}@glEnableVertexAttribArrayARB), + (n: 'glDisableVertexAttribArrayARB'; d: {$ifndef FPC}@{$endif}@glDisableVertexAttribArrayARB), + (n: 'glBindAttribLocationARB'; d: {$ifndef FPC}@{$endif}@glBindAttribLocationARB), + (n: 'glGetActiveAttribARB'; d: {$ifndef FPC}@{$endif}@glGetActiveAttribARB), + (n: 'glGetAttribLocationARB'; d: {$ifndef FPC}@{$endif}@glGetAttribLocationARB), + (n: 'glGetVertexAttribdvARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribdvARB), + (n: 'glGetVertexAttribfvARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribfvARB), + (n: 'glGetVertexAttribivARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribivARB), + (n: 'glGetVertexAttribPointervARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribPointervARB) + ); + +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_fragment_shader: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_shading_language_100: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_non_power_of_two: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_point_sprite: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_depth_bounds_test: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glDepthBoundsEXT'; d: {$ifndef FPC}@{$endif}@glDepthBoundsEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_texture_mirror_clamp: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_blend_equation_separate: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glBlendEquationSeparateEXT'; d: {$ifndef FPC}@{$endif}@glBlendEquationSeparateEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_MESA_pack_invert: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_MESA_ycbcr_texture: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_fragment_program_shadow: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_fragment_program_option: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_pixel_buffer_object: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_fragment_program2: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_vertex_program2_option: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_vertex_program3: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_draw_buffers: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glDrawBuffersARB'; d: {$ifndef FPC}@{$endif}@glDrawBuffersARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_texture_rectangle: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_color_buffer_float: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glClampColorARB'; d: {$ifndef FPC}@{$endif}@glClampColorARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_half_float_pixel: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_float: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_compression_dxt1: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_pixel_buffer_object: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_framebuffer_object: Boolean; +const + funcs: array[0..16] of funcinfoty = + ( + (n: 'glIsRenderbufferEXT'; d: {$ifndef FPC}@{$endif}@glIsRenderbufferEXT), + (n: 'glBindRenderbufferEXT'; d: {$ifndef FPC}@{$endif}@glBindRenderbufferEXT), + (n: 'glDeleteRenderbuffersEXT'; d: {$ifndef FPC}@{$endif}@glDeleteRenderbuffersEXT), + (n: 'glGenRenderbuffersEXT'; d: {$ifndef FPC}@{$endif}@glGenRenderbuffersEXT), + (n: 'glRenderbufferStorageEXT'; d: {$ifndef FPC}@{$endif}@glRenderbufferStorageEXT), + (n: 'glGetRenderbufferParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetRenderbufferParameterivEXT), + (n: 'glIsFramebufferEXT'; d: {$ifndef FPC}@{$endif}@glIsFramebufferEXT), + (n: 'glBindFramebufferEXT'; d: {$ifndef FPC}@{$endif}@glBindFramebufferEXT), + (n: 'glDeleteFramebuffersEXT'; d: {$ifndef FPC}@{$endif}@glDeleteFramebuffersEXT), + (n: 'glGenFramebuffersEXT'; d: {$ifndef FPC}@{$endif}@glGenFramebuffersEXT), + (n: 'glCheckFramebufferStatusEXT'; d: {$ifndef FPC}@{$endif}@glCheckFramebufferStatusEXT), + (n: 'glFramebufferTexture1DEXT'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture1DEXT), + (n: 'glFramebufferTexture2DEXT'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture2DEXT), + (n: 'glFramebufferTexture3DEXT'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture3DEXT), + (n: 'glFramebufferRenderbufferEXT'; d: {$ifndef FPC}@{$endif}@glFramebufferRenderbufferEXT), + (n: 'glGetFramebufferAttachmentParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetFramebufferAttachmentParameterivEXT), + (n: 'glGenerateMipmapEXT'; d: {$ifndef FPC}@{$endif}@glGenerateMipmapEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_framebuffer_object(): Boolean; +const + funcs: array[0..19] of funcinfoty = + ( + (n: 'glIsRenderbuffer'; d: {$ifndef FPC}@{$endif}@glIsRenderbuffer), + (n: 'glBindRenderbuffer'; d: {$ifndef FPC}@{$endif}@glBindRenderbuffer), + (n: 'glDeleteRenderbuffers'; d: {$ifndef FPC}@{$endif}@glDeleteRenderbuffers), + (n: 'glGenRenderbuffers'; d: {$ifndef FPC}@{$endif}@glGenRenderbuffers), + (n: 'glRenderbufferStorage'; d: {$ifndef FPC}@{$endif}@glRenderbufferStorage), + (n: 'glGetRenderbufferParameteriv'; d: {$ifndef FPC}@{$endif}@glGetRenderbufferParameteriv), + (n: 'glIsFramebuffer'; d: {$ifndef FPC}@{$endif}@glIsFramebuffer), + (n: 'glBindFramebuffer'; d: {$ifndef FPC}@{$endif}@glBindFramebuffer), + (n: 'glDeleteFramebuffers'; d: {$ifndef FPC}@{$endif}@glDeleteFramebuffers), + (n: 'glGenFramebuffers'; d: {$ifndef FPC}@{$endif}@glGenFramebuffers), + (n: 'glCheckFramebufferStatus'; d: {$ifndef FPC}@{$endif}@glCheckFramebufferStatus), + (n: 'glFramebufferTexture1D'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture1D), + (n: 'glFramebufferTexture2D'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture2D), + (n: 'glFramebufferTexture3D'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture3D), + (n: 'glFramebufferRenderbuffer'; d: {$ifndef FPC}@{$endif}@glFramebufferRenderbuffer), + (n: 'glGetFramebufferAttachmentParameteriv'; d: {$ifndef FPC}@{$endif}@glGetFramebufferAttachmentParameteriv), + (n: 'glGenerateMipmap'; d: {$ifndef FPC}@{$endif}@glGenerateMipmap), + (n: 'glBlitFramebuffer'; d: {$ifndef FPC}@{$endif}@glBlitFramebuffer), + (n: 'glRenderbufferStorageMultisample'; d: {$ifndef FPC}@{$endif}@glRenderbufferStorageMultisample), + (n: 'glFramebufferTextureLayer'; d: {$ifndef FPC}@{$endif}@glFramebufferTextureLayer) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_map_buffer_range(): Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glMapBufferRange'; d: {$ifndef FPC}@{$endif}@glMapBufferRange), + (n: 'glFlushMappedBufferRange'; d: {$ifndef FPC}@{$endif}@glFlushMappedBufferRange) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_vertex_array_object(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glBindVertexArray'; d: {$ifndef FPC}@{$endif}@glBindVertexArray), + (n: 'glDeleteVertexArrays'; d: {$ifndef FPC}@{$endif}@glDeleteVertexArrays), + (n: 'glGenVertexArrays'; d: {$ifndef FPC}@{$endif}@glGenVertexArrays), + (n: 'glIsVertexArray'; d: {$ifndef FPC}@{$endif}@glIsVertexArray) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_copy_buffer(): Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glCopyBufferSubData'; d: {$ifndef FPC}@{$endif}@glCopyBufferSubData) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_uniform_buffer_object(): Boolean; +const + funcs: array[0..9] of funcinfoty = + ( + (n: 'glGetUniformIndices'; d: {$ifndef FPC}@{$endif}@glGetUniformIndices), + (n: 'glGetActiveUniformsiv'; d: {$ifndef FPC}@{$endif}@glGetActiveUniformsiv), + (n: 'glGetActiveUniformName'; d: {$ifndef FPC}@{$endif}@glGetActiveUniformName), + (n: 'glGetUniformBlockIndex'; d: {$ifndef FPC}@{$endif}@glGetUniformBlockIndex), + (n: 'glGetActiveUniformBlockiv'; d: {$ifndef FPC}@{$endif}@glGetActiveUniformBlockiv), + (n: 'glGetActiveUniformBlockName'; d: {$ifndef FPC}@{$endif}@glGetActiveUniformBlockName), + (n: 'glUniformBlockBinding'; d: {$ifndef FPC}@{$endif}@glUniformBlockBinding), + (n: 'glBindBufferRange'; d: {$ifndef FPC}@{$endif}@glBindBufferRange), + (n: 'glBindBufferBase'; d: {$ifndef FPC}@{$endif}@glBindBufferBase), + (n: 'glGetIntegeri_v'; d: {$ifndef FPC}@{$endif}@glGetIntegeri_v) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_draw_elements_base_vertex(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glDrawElementsBaseVertex'; d: {$ifndef FPC}@{$endif}@glDrawElementsBaseVertex), + (n: 'glDrawRangeElementsBaseVertex'; d: {$ifndef FPC}@{$endif}@glDrawRangeElementsBaseVertex), + (n: 'glDrawElementsInstancedBaseVertex'; d: {$ifndef FPC}@{$endif}@glDrawElementsInstancedBaseVertex), + (n: 'glMultiDrawElementsBaseVertex'; d: {$ifndef FPC}@{$endif}@glMultiDrawElementsBaseVertex) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_provoking_vertex(): Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glProvokingVertex'; d: {$ifndef FPC}@{$endif}@glProvokingVertex) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_sync(): Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glFenceSync'; d: {$ifndef FPC}@{$endif}@glFenceSync), + (n: 'glIsSync'; d: {$ifndef FPC}@{$endif}@glIsSync), + (n: 'glDeleteSync'; d: {$ifndef FPC}@{$endif}@glDeleteSync), + (n: 'glClientWaitSync'; d: {$ifndef FPC}@{$endif}@glClientWaitSync), + (n: 'glWaitSync'; d: {$ifndef FPC}@{$endif}@glWaitSync), + (n: 'glGetInteger64v'; d: {$ifndef FPC}@{$endif}@glGetInteger64v), + (n: 'glGetSynciv'; d: {$ifndef FPC}@{$endif}@glGetSynciv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_texture_multisample(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glTexImage2DMultisample'; d: {$ifndef FPC}@{$endif}@glTexImage2DMultisample), + (n: 'glTexImage3DMultisample'; d: {$ifndef FPC}@{$endif}@glTexImage3DMultisample), + (n: 'glGetMultisamplefv'; d: {$ifndef FPC}@{$endif}@glGetMultisamplefv), + (n: 'glSampleMaski'; d: {$ifndef FPC}@{$endif}@glSampleMaski) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_sampler_objects(): Boolean; +const + funcs: array[0..13] of funcinfoty = + ( + (n: 'glGenSamplers'; d: {$ifndef FPC}@{$endif}@glGenSamplers), + (n: 'glDeleteSamplers'; d: {$ifndef FPC}@{$endif}@glDeleteSamplers), + (n: 'glIsSampler'; d: {$ifndef FPC}@{$endif}@glIsSampler), + (n: 'glBindSampler'; d: {$ifndef FPC}@{$endif}@glBindSampler), + (n: 'glSamplerParameteri'; d: {$ifndef FPC}@{$endif}@glSamplerParameteri), + (n: 'glSamplerParameteriv'; d: {$ifndef FPC}@{$endif}@glSamplerParameteriv), + (n: 'glSamplerParameterf'; d: {$ifndef FPC}@{$endif}@glSamplerParameterf), + (n: 'glSamplerParameterfv'; d: {$ifndef FPC}@{$endif}@glSamplerParameterfv), + (n: 'glSamplerParameterIiv'; d: {$ifndef FPC}@{$endif}@glSamplerParameterIiv), + (n: 'glSamplerParameterIuiv'; d: {$ifndef FPC}@{$endif}@glSamplerParameterIuiv), + (n: 'glGetSamplerParameteriv'; d: {$ifndef FPC}@{$endif}@glGetSamplerParameteriv), + (n: 'glGetSamplerParameterIiv'; d: {$ifndef FPC}@{$endif}@glGetSamplerParameterIiv), + (n: 'glGetSamplerParameterfv'; d: {$ifndef FPC}@{$endif}@glGetSamplerParameterfv), + (n: 'glGetSamplerParameterIfv'; d: {$ifndef FPC}@{$endif}@glGetSamplerParameterIfv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_blend_func_extended(): Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glBindFragDataLocationIndexed'; d: {$ifndef FPC}@{$endif}@glBindFragDataLocationIndexed), + (n: 'glGetFragDataIndex'; d: {$ifndef FPC}@{$endif}@glGetFragDataIndex) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_timer_query(): Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glQueryCounter'; d: {$ifndef FPC}@{$endif}@glQueryCounter), + (n: 'glGetQueryObjecti64v'; d: {$ifndef FPC}@{$endif}@glGetQueryObjecti64v), + (n: 'glGetQueryObjectui64v'; d: {$ifndef FPC}@{$endif}@glGetQueryObjectui64v) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_vertex_type_2_10_10_10_rev(): Boolean; +const + funcs: array[0..37] of funcinfoty = + ( + (n: 'glVertexP2ui'; d: {$ifndef FPC}@{$endif}@glVertexP2ui), + (n: 'glVertexP2uiv'; d: {$ifndef FPC}@{$endif}@glVertexP2uiv), + (n: 'glVertexP3ui'; d: {$ifndef FPC}@{$endif}@glVertexP3ui), + (n: 'glVertexP3uiv'; d: {$ifndef FPC}@{$endif}@glVertexP3uiv), + (n: 'glVertexP4ui'; d: {$ifndef FPC}@{$endif}@glVertexP4ui), + (n: 'glVertexP4uiv'; d: {$ifndef FPC}@{$endif}@glVertexP4uiv), + (n: 'glTexCoordP1ui'; d: {$ifndef FPC}@{$endif}@glTexCoordP1ui), + (n: 'glTexCoordP1uiv'; d: {$ifndef FPC}@{$endif}@glTexCoordP1uiv), + (n: 'glTexCoordP2ui'; d: {$ifndef FPC}@{$endif}@glTexCoordP2ui), + (n: 'glTexCoordP2uiv'; d: {$ifndef FPC}@{$endif}@glTexCoordP2uiv), + (n: 'glTexCoordP3ui'; d: {$ifndef FPC}@{$endif}@glTexCoordP3ui), + (n: 'glTexCoordP3uiv'; d: {$ifndef FPC}@{$endif}@glTexCoordP3uiv), + (n: 'glTexCoordP4ui'; d: {$ifndef FPC}@{$endif}@glTexCoordP4ui), + (n: 'glTexCoordP4uiv'; d: {$ifndef FPC}@{$endif}@glTexCoordP4uiv), + (n: 'glMultiTexCoordP1ui'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP1ui), + (n: 'glMultiTexCoordP1uiv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP1uiv), + (n: 'glMultiTexCoordP2ui'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP2ui), + (n: 'glMultiTexCoordP2uiv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP2uiv), + (n: 'glMultiTexCoordP3ui'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP3ui), + (n: 'glMultiTexCoordP3uiv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP3uiv), + (n: 'glMultiTexCoordP4ui'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP4ui), + (n: 'glMultiTexCoordP4uiv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP4uiv), + (n: 'glNormalP3ui'; d: {$ifndef FPC}@{$endif}@glNormalP3ui), + (n: 'glNormalP3uiv'; d: {$ifndef FPC}@{$endif}@glNormalP3uiv), + (n: 'glColorP3ui'; d: {$ifndef FPC}@{$endif}@glColorP3ui), + (n: 'glColorP3uiv'; d: {$ifndef FPC}@{$endif}@glColorP3uiv), + (n: 'glColorP4ui'; d: {$ifndef FPC}@{$endif}@glColorP4ui), + (n: 'glColorP4uiv'; d: {$ifndef FPC}@{$endif}@glColorP4uiv), + (n: 'glSecondaryColorP3ui'; d: {$ifndef FPC}@{$endif}@glSecondaryColorP3ui), + (n: 'glSecondaryColorP3uiv'; d: {$ifndef FPC}@{$endif}@glSecondaryColorP3uiv), + (n: 'glVertexAttribP1ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribP1ui), + (n: 'glVertexAttribP1uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribP1uiv), + (n: 'glVertexAttribP2ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribP2ui), + (n: 'glVertexAttribP2uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribP2uiv), + (n: 'glVertexAttribP3ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribP3ui), + (n: 'glVertexAttribP3uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribP3uiv), + (n: 'glVertexAttribP4ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribP4ui), + (n: 'glVertexAttribP4uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribP4uiv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_gpu_shader_fp64(): Boolean; +const + funcs: array[0..34] of funcinfoty = + ( + (n: 'glUniform1d'; d: {$ifndef FPC}@{$endif}@glUniform1d), + (n: 'glUniform2d'; d: {$ifndef FPC}@{$endif}@glUniform2d), + (n: 'glUniform3d'; d: {$ifndef FPC}@{$endif}@glUniform3d), + (n: 'glUniform4d'; d: {$ifndef FPC}@{$endif}@glUniform4d), + (n: 'glUniform1dv'; d: {$ifndef FPC}@{$endif}@glUniform1dv), + (n: 'glUniform2dv'; d: {$ifndef FPC}@{$endif}@glUniform2dv), + (n: 'glUniform3dv'; d: {$ifndef FPC}@{$endif}@glUniform3dv), + (n: 'glUniform4dv'; d: {$ifndef FPC}@{$endif}@glUniform4dv), + (n: 'glUniformMatrix2dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2dv), + (n: 'glUniformMatrix3dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3dv), + (n: 'glUniformMatrix4dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4dv), + (n: 'glUniformMatrix2x3dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2x3dv), + (n: 'glUniformMatrix2x4dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2x4dv), + (n: 'glUniformMatrix3x2dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3x2dv), + (n: 'glUniformMatrix3x4dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3x4dv), + (n: 'glUniformMatrix4x2dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4x2dv), + (n: 'glUniformMatrix4x3dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4x3dv), + (n: 'glGetUniformdv'; d: {$ifndef FPC}@{$endif}@glGetUniformdv), + (n: 'glProgramUniform1dEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform1dEXT), + (n: 'glProgramUniform2dEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform2dEXT), + (n: 'glProgramUniform3dEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform3dEXT), + (n: 'glProgramUniform4dEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform4dEXT), + (n: 'glProgramUniform1dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform1dvEXT), + (n: 'glProgramUniform2dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform2dvEXT), + (n: 'glProgramUniform3dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform3dvEXT), + (n: 'glProgramUniform4dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform4dvEXT), + (n: 'glProgramUniformMatrix2dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix2dvEXT), + (n: 'glProgramUniformMatrix3dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix3dvEXT), + (n: 'glProgramUniformMatrix4dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix4dvEXT), + (n: 'glProgramUniformMatrix2x3dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix2x3dvEXT), + (n: 'glProgramUniformMatrix2x4dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix2x4dvEXT), + (n: 'glProgramUniformMatrix3x2dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix3x2dvEXT), + (n: 'glProgramUniformMatrix3x4dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix3x4dvEXT), + (n: 'glProgramUniformMatrix4x2dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix4x2dvEXT), + (n: 'glProgramUniformMatrix4x3dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix4x3dvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_shader_subroutine(): Boolean; +const + funcs: array[0..7] of funcinfoty = + ( + (n: 'glGetSubroutineUniformLocation'; d: {$ifndef FPC}@{$endif}@glGetSubroutineUniformLocation), + (n: 'glGetSubroutineIndex'; d: {$ifndef FPC}@{$endif}@glGetSubroutineIndex), + (n: 'glGetActiveSubroutineUniformiv'; d: {$ifndef FPC}@{$endif}@glGetActiveSubroutineUniformiv), + (n: 'glGetActiveSubroutineUniformName'; d: {$ifndef FPC}@{$endif}@glGetActiveSubroutineUniformName), + (n: 'glGetActiveSubroutineName'; d: {$ifndef FPC}@{$endif}@glGetActiveSubroutineName), + (n: 'glUniformSubroutinesuiv'; d: {$ifndef FPC}@{$endif}@glUniformSubroutinesuiv), + (n: 'glGetUniformSubroutineuiv'; d: {$ifndef FPC}@{$endif}@glGetUniformSubroutineuiv), + (n: 'glGetProgramStageiv'; d: {$ifndef FPC}@{$endif}@glGetProgramStageiv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_tessellation_shader(): Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPatchParameteri'; d: {$ifndef FPC}@{$endif}@glPatchParameteri), + (n: 'glPatchParameterfv'; d: {$ifndef FPC}@{$endif}@glPatchParameterfv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_transform_feedback2(): Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glBindTransformFeedback'; d: {$ifndef FPC}@{$endif}@glBindTransformFeedback), + (n: 'glDeleteTransformFeedbacks'; d: {$ifndef FPC}@{$endif}@glDeleteTransformFeedbacks), + (n: 'glGenTransformFeedbacks'; d: {$ifndef FPC}@{$endif}@glGenTransformFeedbacks), + (n: 'glIsTransformFeedback'; d: {$ifndef FPC}@{$endif}@glIsTransformFeedback), + (n: 'glPauseTransformFeedback'; d: {$ifndef FPC}@{$endif}@glPauseTransformFeedback), + (n: 'glResumeTransformFeedback'; d: {$ifndef FPC}@{$endif}@glResumeTransformFeedback), + (n: 'glDrawTransformFeedback'; d: {$ifndef FPC}@{$endif}@glDrawTransformFeedback) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_transform_feedback3(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glDrawTransformFeedbackStream'; d: {$ifndef FPC}@{$endif}@glDrawTransformFeedbackStream), + (n: 'glBeginQueryIndexed'; d: {$ifndef FPC}@{$endif}@glBeginQueryIndexed), + (n: 'glEndQueryIndexed'; d: {$ifndef FPC}@{$endif}@glEndQueryIndexed), + (n: 'glGetQueryIndexediv'; d: {$ifndef FPC}@{$endif}@glGetQueryIndexediv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_version_1_4: Boolean; +const + funcs: array[0..44] of funcinfoty = + ( + (n: 'glBlendFuncSeparate'; d: {$ifndef FPC}@{$endif}@glBlendFuncSeparate), + (n: 'glFogCoordf'; d: {$ifndef FPC}@{$endif}@glFogCoordf), + (n: 'glFogCoordfv'; d: {$ifndef FPC}@{$endif}@glFogCoordfv), + (n: 'glFogCoordd'; d: {$ifndef FPC}@{$endif}@glFogCoordd), + (n: 'glFogCoorddv'; d: {$ifndef FPC}@{$endif}@glFogCoorddv), + (n: 'glFogCoordPointer'; d: {$ifndef FPC}@{$endif}@glFogCoordPointer), + (n: 'glMultiDrawArrays'; d: {$ifndef FPC}@{$endif}@glMultiDrawArrays), + (n: 'glMultiDrawElements'; d: {$ifndef FPC}@{$endif}@glMultiDrawElements), + (n: 'glPointParameterf'; d: {$ifndef FPC}@{$endif}@glPointParameterf), + (n: 'glPointParameterfv'; d: {$ifndef FPC}@{$endif}@glPointParameterfv), + (n: 'glPointParameteri'; d: {$ifndef FPC}@{$endif}@glPointParameteri), + (n: 'glPointParameteriv'; d: {$ifndef FPC}@{$endif}@glPointParameteriv), + (n: 'glSecondaryColor3b'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3b), + (n: 'glSecondaryColor3bv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3bv), + (n: 'glSecondaryColor3d'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3d), + (n: 'glSecondaryColor3dv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3dv), + (n: 'glSecondaryColor3f'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3f), + (n: 'glSecondaryColor3fv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3fv), + (n: 'glSecondaryColor3i'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3i), + (n: 'glSecondaryColor3iv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3iv), + (n: 'glSecondaryColor3s'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3s), + (n: 'glSecondaryColor3sv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3sv), + (n: 'glSecondaryColor3ub'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ub), + (n: 'glSecondaryColor3ubv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ubv), + (n: 'glSecondaryColor3ui'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ui), + (n: 'glSecondaryColor3uiv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3uiv), + (n: 'glSecondaryColor3us'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3us), + (n: 'glSecondaryColor3usv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3usv), + (n: 'glSecondaryColorPointer'; d: {$ifndef FPC}@{$endif}@glSecondaryColorPointer), + (n: 'glWindowPos2d'; d: {$ifndef FPC}@{$endif}@glWindowPos2d), + (n: 'glWindowPos2dv'; d: {$ifndef FPC}@{$endif}@glWindowPos2dv), + (n: 'glWindowPos2f'; d: {$ifndef FPC}@{$endif}@glWindowPos2f), + (n: 'glWindowPos2fv'; d: {$ifndef FPC}@{$endif}@glWindowPos2fv), + (n: 'glWindowPos2i'; d: {$ifndef FPC}@{$endif}@glWindowPos2i), + (n: 'glWindowPos2iv'; d: {$ifndef FPC}@{$endif}@glWindowPos2iv), + (n: 'glWindowPos2s'; d: {$ifndef FPC}@{$endif}@glWindowPos2s), + (n: 'glWindowPos2sv'; d: {$ifndef FPC}@{$endif}@glWindowPos2sv), + (n: 'glWindowPos3d'; d: {$ifndef FPC}@{$endif}@glWindowPos3d), + (n: 'glWindowPos3dv'; d: {$ifndef FPC}@{$endif}@glWindowPos3dv), + (n: 'glWindowPos3f'; d: {$ifndef FPC}@{$endif}@glWindowPos3f), + (n: 'glWindowPos3fv'; d: {$ifndef FPC}@{$endif}@glWindowPos3fv), + (n: 'glWindowPos3i'; d: {$ifndef FPC}@{$endif}@glWindowPos3i), + (n: 'glWindowPos3iv'; d: {$ifndef FPC}@{$endif}@glWindowPos3iv), + (n: 'glWindowPos3s'; d: {$ifndef FPC}@{$endif}@glWindowPos3s), + (n: 'glWindowPos3sv'; d: {$ifndef FPC}@{$endif}@glWindowPos3sv) + ); +begin + result:= getprocaddresses(libgl,funcs); + +end; + +function Load_GL_version_1_5: Boolean; +const + funcs: array[0..18] of funcinfoty = + ( + (n: 'glGenQueries'; d: {$ifndef FPC}@{$endif}@glGenQueries), + (n: 'glDeleteQueries'; d: {$ifndef FPC}@{$endif}@glDeleteQueries), + (n: 'glIsQuery'; d: {$ifndef FPC}@{$endif}@glIsQuery), + (n: 'glBeginQuery'; d: {$ifndef FPC}@{$endif}@glBeginQuery), + (n: 'glEndQuery'; d: {$ifndef FPC}@{$endif}@glEndQuery), + (n: 'glGetQueryiv'; d: {$ifndef FPC}@{$endif}@glGetQueryiv), + (n: 'glGetQueryObjectiv'; d: {$ifndef FPC}@{$endif}@glGetQueryObjectiv), + (n: 'glGetQueryObjectuiv'; d: {$ifndef FPC}@{$endif}@glGetQueryObjectuiv), + (n: 'glBindBuffer'; d: {$ifndef FPC}@{$endif}@glBindBuffer), + (n: 'glDeleteBuffers'; d: {$ifndef FPC}@{$endif}@glDeleteBuffers), + (n: 'glGenBuffers'; d: {$ifndef FPC}@{$endif}@glGenBuffers), + (n: 'glIsBuffer'; d: {$ifndef FPC}@{$endif}@glIsBuffer), + (n: 'glBufferData'; d: {$ifndef FPC}@{$endif}@glBufferData), + (n: 'glBufferSubData'; d: {$ifndef FPC}@{$endif}@glBufferSubData), + (n: 'glGetBufferSubData'; d: {$ifndef FPC}@{$endif}@glGetBufferSubData), + (n: 'glMapBuffer'; d: {$ifndef FPC}@{$endif}@glMapBuffer), + (n: 'glUnmapBuffer'; d: {$ifndef FPC}@{$endif}@glUnmapBuffer), + (n: 'glGetBufferParameteriv'; d: {$ifndef FPC}@{$endif}@glGetBufferParameteriv), + (n: 'glGetBufferPointerv'; d: {$ifndef FPC}@{$endif}@glGetBufferPointerv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_version_2_0: Boolean; +const + funcs: array[0..92] of funcinfoty = + ( + (n: 'glBlendEquationSeparate'; d: {$ifndef FPC}@{$endif}@glBlendEquationSeparate), + (n: 'glDrawBuffers'; d: {$ifndef FPC}@{$endif}@glDrawBuffers), + (n: 'glStencilOpSeparate'; d: {$ifndef FPC}@{$endif}@glStencilOpSeparate), + (n: 'glStencilFuncSeparate'; d: {$ifndef FPC}@{$endif}@glStencilFuncSeparate), + (n: 'glStencilMaskSeparate'; d: {$ifndef FPC}@{$endif}@glStencilMaskSeparate), + (n: 'glAttachShader'; d: {$ifndef FPC}@{$endif}@glAttachShader), + (n: 'glBindAttribLocation'; d: {$ifndef FPC}@{$endif}@glBindAttribLocation), + (n: 'glCompileShader'; d: {$ifndef FPC}@{$endif}@glCompileShader), + (n: 'glCreateProgram'; d: {$ifndef FPC}@{$endif}@glCreateProgram), + (n: 'glCreateShader'; d: {$ifndef FPC}@{$endif}@glCreateShader), + (n: 'glDeleteProgram'; d: {$ifndef FPC}@{$endif}@glDeleteProgram), + (n: 'glDeleteShader'; d: {$ifndef FPC}@{$endif}@glDeleteShader), + (n: 'glDetachShader'; d: {$ifndef FPC}@{$endif}@glDetachShader), + (n: 'glDisableVertexAttribArray'; d: {$ifndef FPC}@{$endif}@glDisableVertexAttribArray), + (n: 'glEnableVertexAttribArray'; d: {$ifndef FPC}@{$endif}@glEnableVertexAttribArray), + (n: 'glGetActiveAttrib'; d: {$ifndef FPC}@{$endif}@glGetActiveAttrib), + (n: 'glGetActiveUniform'; d: {$ifndef FPC}@{$endif}@glGetActiveUniform), + (n: 'glGetAttachedShaders'; d: {$ifndef FPC}@{$endif}@glGetAttachedShaders), + (n: 'glGetAttribLocation'; d: {$ifndef FPC}@{$endif}@glGetAttribLocation), + (n: 'glGetProgramiv'; d: {$ifndef FPC}@{$endif}@glGetProgramiv), + (n: 'glGetProgramInfoLog'; d: {$ifndef FPC}@{$endif}@glGetProgramInfoLog), + (n: 'glGetShaderiv'; d: {$ifndef FPC}@{$endif}@glGetShaderiv), + (n: 'glGetShaderInfoLog'; d: {$ifndef FPC}@{$endif}@glGetShaderInfoLog), + (n: 'glGetShaderSource'; d: {$ifndef FPC}@{$endif}@glGetShaderSource), + (n: 'glGetUniformLocation'; d: {$ifndef FPC}@{$endif}@glGetUniformLocation), + (n: 'glGetUniformfv'; d: {$ifndef FPC}@{$endif}@glGetUniformfv), + (n: 'glGetUniformiv'; d: {$ifndef FPC}@{$endif}@glGetUniformiv), + (n: 'glGetVertexAttribdv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribdv), + (n: 'glGetVertexAttribfv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribfv), + (n: 'glGetVertexAttribiv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribiv), + (n: 'glGetVertexAttribPointerv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribPointerv), + (n: 'glIsProgram'; d: {$ifndef FPC}@{$endif}@glIsProgram), + (n: 'glIsShader'; d: {$ifndef FPC}@{$endif}@glIsShader), + (n: 'glLinkProgram'; d: {$ifndef FPC}@{$endif}@glLinkProgram), + (n: 'glShaderSource'; d: {$ifndef FPC}@{$endif}@glShaderSource), + (n: 'glUseProgram'; d: {$ifndef FPC}@{$endif}@glUseProgram), + (n: 'glUniform1f'; d: {$ifndef FPC}@{$endif}@glUniform1f), + (n: 'glUniform2f'; d: {$ifndef FPC}@{$endif}@glUniform2f), + (n: 'glUniform3f'; d: {$ifndef FPC}@{$endif}@glUniform3f), + (n: 'glUniform4f'; d: {$ifndef FPC}@{$endif}@glUniform4f), + (n: 'glUniform1i'; d: {$ifndef FPC}@{$endif}@glUniform1i), + (n: 'glUniform2i'; d: {$ifndef FPC}@{$endif}@glUniform2i), + (n: 'glUniform3i'; d: {$ifndef FPC}@{$endif}@glUniform3i), + (n: 'glUniform4i'; d: {$ifndef FPC}@{$endif}@glUniform4i), + (n: 'glUniform1fv'; d: {$ifndef FPC}@{$endif}@glUniform1fv), + (n: 'glUniform2fv'; d: {$ifndef FPC}@{$endif}@glUniform2fv), + (n: 'glUniform3fv'; d: {$ifndef FPC}@{$endif}@glUniform3fv), + (n: 'glUniform4fv'; d: {$ifndef FPC}@{$endif}@glUniform4fv), + (n: 'glUniform1iv'; d: {$ifndef FPC}@{$endif}@glUniform1iv), + (n: 'glUniform2iv'; d: {$ifndef FPC}@{$endif}@glUniform2iv), + (n: 'glUniform3iv'; d: {$ifndef FPC}@{$endif}@glUniform3iv), + (n: 'glUniform4iv'; d: {$ifndef FPC}@{$endif}@glUniform4iv), + (n: 'glUniformMatrix2fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2fv), + (n: 'glUniformMatrix3fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3fv), + (n: 'glUniformMatrix4fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4fv), + (n: 'glValidateProgram'; d: {$ifndef FPC}@{$endif}@glValidateProgram), + (n: 'glVertexAttrib1d'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1d), + (n: 'glVertexAttrib1dv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dv), + (n: 'glVertexAttrib1f'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1f), + (n: 'glVertexAttrib1fv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fv), + (n: 'glVertexAttrib1s'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1s), + (n: 'glVertexAttrib1sv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1sv), + (n: 'glVertexAttrib2d'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2d), + (n: 'glVertexAttrib2dv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dv), + (n: 'glVertexAttrib2f'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2f), + (n: 'glVertexAttrib2fv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fv), + (n: 'glVertexAttrib2s'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2s), + (n: 'glVertexAttrib2sv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2sv), + (n: 'glVertexAttrib3d'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3d), + (n: 'glVertexAttrib3dv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dv), + (n: 'glVertexAttrib3f'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3f), + (n: 'glVertexAttrib3fv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fv), + (n: 'glVertexAttrib3s'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3s), + (n: 'glVertexAttrib3sv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3sv), + (n: 'glVertexAttrib4Nbv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nbv), + (n: 'glVertexAttrib4Niv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Niv), + (n: 'glVertexAttrib4Nsv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nsv), + (n: 'glVertexAttrib4Nub'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nub), + (n: 'glVertexAttrib4Nubv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nubv), + (n: 'glVertexAttrib4Nuiv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nuiv), + (n: 'glVertexAttrib4Nusv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nusv), + (n: 'glVertexAttrib4bv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4bv), + (n: 'glVertexAttrib4d'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4d), + (n: 'glVertexAttrib4dv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dv), + (n: 'glVertexAttrib4f'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4f), + (n: 'glVertexAttrib4fv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fv), + (n: 'glVertexAttrib4iv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4iv), + (n: 'glVertexAttrib4s'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4s), + (n: 'glVertexAttrib4sv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4sv), + (n: 'glVertexAttrib4ubv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ubv), + (n: 'glVertexAttrib4uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4uiv), + (n: 'glVertexAttrib4usv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4usv), + (n: 'glVertexAttribPointer'; d: {$ifndef FPC}@{$endif}@glVertexAttribPointer) + ); +begin + result:= getprocaddresses(libgl,funcs); + +end; +(* +function glext_LoadExtension(ext: String): Boolean; +begin + + Result := FALSE; + + if ext = 'GL_version_1_2' then Result := Load_GL_version_1_2 + else if ext = 'GL_ARB_imaging' then Result := Load_GL_ARB_imaging + else if ext = 'GL_version_1_3' then Result := Load_GL_version_1_3 + else if ext = 'GL_ARB_multitexture' then Result := Load_GL_ARB_multitexture + else if ext = 'GL_ARB_transpose_matrix' then Result := Load_GL_ARB_transpose_matrix + else if ext = 'GL_ARB_multisample' then Result := Load_GL_ARB_multisample + else if ext = 'GL_ARB_texture_env_add' then Result := Load_GL_ARB_texture_env_add +{$IFDEF msWindows} + else if ext = 'WGL_ARB_extensions_string' then Result := Load_WGL_ARB_extensions_string + else if ext = 'WGL_ARB_buffer_region' then Result := Load_WGL_ARB_buffer_region +{$ENDIF} + else if ext = 'GL_ARB_texture_cube_map' then Result := Load_GL_ARB_texture_cube_map + else if ext = 'GL_ARB_depth_texture' then Result := Load_GL_ARB_depth_texture + else if ext = 'GL_ARB_point_parameters' then Result := Load_GL_ARB_point_parameters + else if ext = 'GL_ARB_shadow' then Result := Load_GL_ARB_shadow + else if ext = 'GL_ARB_shadow_ambient' then Result := Load_GL_ARB_shadow_ambient + else if ext = 'GL_ARB_texture_border_clamp' then Result := Load_GL_ARB_texture_border_clamp + else if ext = 'GL_ARB_texture_compression' then Result := Load_GL_ARB_texture_compression + else if ext = 'GL_ARB_texture_env_combine' then Result := Load_GL_ARB_texture_env_combine + else if ext = 'GL_ARB_texture_env_crossbar' then Result := Load_GL_ARB_texture_env_crossbar + else if ext = 'GL_ARB_texture_env_dot3' then Result := Load_GL_ARB_texture_env_dot3 + else if ext = 'GL_ARB_texture_mirrored_repeat' then Result := Load_GL_ARB_texture_mirrored_repeat + else if ext = 'GL_ARB_vertex_blend' then Result := Load_GL_ARB_vertex_blend + else if ext = 'GL_ARB_vertex_program' then Result := Load_GL_ARB_vertex_program + else if ext = 'GL_ARB_window_pos' then Result := Load_GL_ARB_window_pos + else if ext = 'GL_EXT_422_pixels' then Result := Load_GL_EXT_422_pixels + else if ext = 'GL_EXT_abgr' then Result := Load_GL_EXT_abgr + else if ext = 'GL_EXT_bgra' then Result := Load_GL_EXT_bgra + else if ext = 'GL_EXT_blend_color' then Result := Load_GL_EXT_blend_color + else if ext = 'GL_EXT_blend_func_separate' then Result := Load_GL_EXT_blend_func_separate + else if ext = 'GL_EXT_blend_logic_op' then Result := Load_GL_EXT_blend_logic_op + else if ext = 'GL_EXT_blend_minmax' then Result := Load_GL_EXT_blend_minmax + else if ext = 'GL_EXT_blend_subtract' then Result := Load_GL_EXT_blend_subtract + else if ext = 'GL_EXT_clip_volume_hint' then Result := Load_GL_EXT_clip_volume_hint + else if ext = 'GL_EXT_color_subtable' then Result := Load_GL_EXT_color_subtable + else if ext = 'GL_EXT_compiled_vertex_array' then Result := Load_GL_EXT_compiled_vertex_array + else if ext = 'GL_EXT_convolution' then Result := Load_GL_EXT_convolution + else if ext = 'GL_EXT_fog_coord' then Result := Load_GL_EXT_fog_coord + else if ext = 'GL_EXT_histogram' then Result := Load_GL_EXT_histogram + else if ext = 'GL_EXT_multi_draw_arrays' then Result := Load_GL_EXT_multi_draw_arrays + else if ext = 'GL_EXT_packed_pixels' then Result := Load_GL_EXT_packed_pixels + else if ext = 'GL_EXT_paletted_texture' then Result := Load_GL_EXT_paletted_texture + else if ext = 'GL_EXT_point_parameters' then Result := Load_GL_EXT_point_parameters + else if ext = 'GL_EXT_polygon_offset' then Result := Load_GL_EXT_polygon_offset + else if ext = 'GL_EXT_secondary_color' then Result := Load_GL_EXT_secondary_color + else if ext = 'GL_EXT_separate_specular_color' then Result := Load_GL_EXT_separate_specular_color + else if ext = 'GL_EXT_shadow_funcs' then Result := Load_GL_EXT_shadow_funcs + else if ext = 'GL_EXT_shared_texture_palette' then Result := Load_GL_EXT_shared_texture_palette + else if ext = 'GL_EXT_stencil_two_side' then Result := Load_GL_EXT_stencil_two_side + else if ext = 'GL_EXT_stencil_wrap' then Result := Load_GL_EXT_stencil_wrap + else if ext = 'GL_EXT_subtexture' then Result := Load_GL_EXT_subtexture + else if ext = 'GL_EXT_texture3D' then Result := Load_GL_EXT_texture3D + else if ext = 'GL_EXT_texture_compression_s3tc' then Result := Load_GL_EXT_texture_compression_s3tc + else if ext = 'GL_EXT_texture_env_add' then Result := Load_GL_EXT_texture_env_add + else if ext = 'GL_EXT_texture_env_combine' then Result := Load_GL_EXT_texture_env_combine + else if ext = 'GL_EXT_texture_env_dot3' then Result := Load_GL_EXT_texture_env_dot3 + else if ext = 'GL_EXT_texture_filter_anisotropic' then Result := Load_GL_EXT_texture_filter_anisotropic + else if ext = 'GL_EXT_texture_lod_bias' then Result := Load_GL_EXT_texture_lod_bias + else if ext = 'GL_EXT_texture_object' then Result := Load_GL_EXT_texture_object + else if ext = 'GL_EXT_vertex_array' then Result := Load_GL_EXT_vertex_array + else if ext = 'GL_EXT_vertex_shader' then Result := Load_GL_EXT_vertex_shader + else if ext = 'GL_EXT_vertex_weighting' then Result := Load_GL_EXT_vertex_weighting + else if ext = 'GL_HP_occlusion_test' then Result := Load_GL_HP_occlusion_test + else if ext = 'GL_NV_blend_square' then Result := Load_GL_NV_blend_square + else if ext = 'GL_NV_copy_depth_to_color' then Result := Load_GL_NV_copy_depth_to_color + else if ext = 'GL_NV_depth_clamp' then Result := Load_GL_NV_depth_clamp + else if ext = 'GL_NV_evaluators' then Result := Load_GL_NV_evaluators + else if ext = 'GL_NV_fence' then Result := Load_GL_NV_fence + else if ext = 'GL_NV_fog_distance' then Result := Load_GL_NV_fog_distance + else if ext = 'GL_NV_light_max_exponent' then Result := Load_GL_NV_light_max_exponent + else if ext = 'GL_NV_multisample_filter_hint' then Result := Load_GL_NV_multisample_filter_hint + else if ext = 'GL_NV_occlusion_query' then Result := Load_GL_NV_occlusion_query + else if ext = 'GL_NV_packed_depth_stencil' then Result := Load_GL_NV_packed_depth_stencil + else if ext = 'GL_NV_point_sprite' then Result := Load_GL_NV_point_sprite + else if ext = 'GL_NV_register_combiners' then Result := Load_GL_NV_register_combiners + else if ext = 'GL_NV_register_combiners2' then Result := Load_GL_NV_register_combiners2 + else if ext = 'GL_NV_texgen_emboss' then Result := Load_GL_NV_texgen_emboss + else if ext = 'GL_NV_texgen_reflection' then Result := Load_GL_NV_texgen_reflection + else if ext = 'GL_NV_texture_compression_vtc' then Result := Load_GL_NV_texture_compression_vtc + else if ext = 'GL_NV_texture_env_combine4' then Result := Load_GL_NV_texture_env_combine4 + else if ext = 'GL_NV_texture_rectangle' then Result := Load_GL_NV_texture_rectangle + else if ext = 'GL_NV_texture_shader' then Result := Load_GL_NV_texture_shader + else if ext = 'GL_NV_texture_shader2' then Result := Load_GL_NV_texture_shader2 + else if ext = 'GL_NV_texture_shader3' then Result := Load_GL_NV_texture_shader3 + else if ext = 'GL_NV_vertex_array_range' then Result := Load_GL_NV_vertex_array_range + else if ext = 'GL_NV_vertex_array_range2' then Result := Load_GL_NV_vertex_array_range2 + else if ext = 'GL_NV_vertex_program' then Result := Load_GL_NV_vertex_program + else if ext = 'GL_NV_vertex_program1_1' then Result := Load_GL_NV_vertex_program1_1 + else if ext = 'GL_ATI_element_array' then Result := Load_GL_ATI_element_array + else if ext = 'GL_ATI_envmap_bumpmap' then Result := Load_GL_ATI_envmap_bumpmap + else if ext = 'GL_ATI_fragment_shader' then Result := Load_GL_ATI_fragment_shader + else if ext = 'GL_ATI_pn_triangles' then Result := Load_GL_ATI_pn_triangles + else if ext = 'GL_ATI_texture_mirror_once' then Result := Load_GL_ATI_texture_mirror_once + else if ext = 'GL_ATI_vertex_array_object' then Result := Load_GL_ATI_vertex_array_object + else if ext = 'GL_ATI_vertex_streams' then Result := Load_GL_ATI_vertex_streams +{$IFDEF msWindows} + else if ext = 'WGL_I3D_image_buffer' then Result := Load_WGL_I3D_image_buffer + else if ext = 'WGL_I3D_swap_frame_lock' then Result := Load_WGL_I3D_swap_frame_lock + else if ext = 'WGL_I3D_swap_frame_usage' then Result := Load_WGL_I3D_swap_frame_usage +{$ENDIF} + else if ext = 'GL_3DFX_texture_compression_FXT1' then Result := Load_GL_3DFX_texture_compression_FXT1 + else if ext = 'GL_IBM_cull_vertex' then Result := Load_GL_IBM_cull_vertex + else if ext = 'GL_IBM_multimode_draw_arrays' then Result := Load_GL_IBM_multimode_draw_arrays + else if ext = 'GL_IBM_raster_pos_clip' then Result := Load_GL_IBM_raster_pos_clip + else if ext = 'GL_IBM_texture_mirrored_repeat' then Result := Load_GL_IBM_texture_mirrored_repeat + else if ext = 'GL_IBM_vertex_array_lists' then Result := Load_GL_IBM_vertex_array_lists + else if ext = 'GL_MESA_resize_buffers' then Result := Load_GL_MESA_resize_buffers + else if ext = 'GL_MESA_window_pos' then Result := Load_GL_MESA_window_pos + else if ext = 'GL_OML_interlace' then Result := Load_GL_OML_interlace + else if ext = 'GL_OML_resample' then Result := Load_GL_OML_resample + else if ext = 'GL_OML_subsample' then Result := Load_GL_OML_subsample + else if ext = 'GL_SGIS_generate_mipmap' then Result := Load_GL_SGIS_generate_mipmap + else if ext = 'GL_SGIS_multisample' then Result := Load_GL_SGIS_multisample + else if ext = 'GL_SGIS_pixel_texture' then Result := Load_GL_SGIS_pixel_texture + else if ext = 'GL_SGIS_texture_border_clamp' then Result := Load_GL_SGIS_texture_border_clamp + else if ext = 'GL_SGIS_texture_color_mask' then Result := Load_GL_SGIS_texture_color_mask + else if ext = 'GL_SGIS_texture_edge_clamp' then Result := Load_GL_SGIS_texture_edge_clamp + else if ext = 'GL_SGIS_texture_lod' then Result := Load_GL_SGIS_texture_lod + else if ext = 'GL_SGIS_depth_texture' then Result := Load_GL_SGIS_depth_texture + else if ext = 'GL_SGIX_fog_offset' then Result := Load_GL_SGIX_fog_offset + else if ext = 'GL_SGIX_interlace' then Result := Load_GL_SGIX_interlace + else if ext = 'GL_SGIX_shadow_ambient' then Result := Load_GL_SGIX_shadow_ambient + else if ext = 'GL_SGI_color_matrix' then Result := Load_GL_SGI_color_matrix + else if ext = 'GL_SGI_color_table' then Result := Load_GL_SGI_color_table + else if ext = 'GL_SGI_texture_color_table' then Result := Load_GL_SGI_texture_color_table + else if ext = 'GL_SUN_vertex' then Result := Load_GL_SUN_vertex + else if ext = 'GL_ARB_fragment_program' then Result := Load_GL_ARB_fragment_program + else if ext = 'GL_ATI_text_fragment_shader' then Result := Load_GL_ATI_text_fragment_shader + else if ext = 'GL_APPLE_client_storage' then Result := Load_GL_APPLE_client_storage + else if ext = 'GL_APPLE_element_array' then Result := Load_GL_APPLE_element_array + else if ext = 'GL_APPLE_fence' then Result := Load_GL_APPLE_fence + else if ext = 'GL_APPLE_vertex_array_object' then Result := Load_GL_APPLE_vertex_array_object + else if ext = 'GL_APPLE_vertex_array_range' then Result := Load_GL_APPLE_vertex_array_range +{$IFDEF msWindows} + else if ext = 'WGL_ARB_pixel_format' then Result := Load_WGL_ARB_pixel_format + else if ext = 'WGL_ARB_make_current_read' then Result := Load_WGL_ARB_make_current_read + else if ext = 'WGL_ARB_pbuffer' then Result := Load_WGL_ARB_pbuffer + else if ext = 'WGL_EXT_swap_control' then Result := Load_WGL_EXT_swap_control + else if ext = 'WGL_ARB_render_texture' then Result := Load_WGL_ARB_render_texture + else if ext = 'WGL_EXT_extensions_string' then Result := Load_WGL_EXT_extensions_string + else if ext = 'WGL_EXT_make_current_read' then Result := Load_WGL_EXT_make_current_read + else if ext = 'WGL_EXT_pbuffer' then Result := Load_WGL_EXT_pbuffer + else if ext = 'WGL_EXT_pixel_format' then Result := Load_WGL_EXT_pixel_format + else if ext = 'WGL_I3D_digital_video_control' then Result := Load_WGL_I3D_digital_video_control + else if ext = 'WGL_I3D_gamma' then Result := Load_WGL_I3D_gamma + else if ext = 'WGL_I3D_genlock' then Result := Load_WGL_I3D_genlock +{$ENDIF} + else if ext = 'GL_ARB_matrix_palette' then Result := Load_GL_ARB_matrix_palette + else if ext = 'GL_NV_element_array' then Result := Load_GL_NV_element_array + else if ext = 'GL_NV_float_buffer' then Result := Load_GL_NV_float_buffer + else if ext = 'GL_NV_fragment_program' then Result := Load_GL_NV_fragment_program + else if ext = 'GL_NV_primitive_restart' then Result := Load_GL_NV_primitive_restart + else if ext = 'GL_NV_vertex_program2' then Result := Load_GL_NV_vertex_program2 + {$IFDEF msWindows} + else if ext = 'WGL_NV_render_texture_rectangle' then Result := Load_WGL_NV_render_texture_rectangle + {$ENDIF} + else if ext = 'GL_NV_pixel_data_range' then Result := Load_GL_NV_pixel_data_range + else if ext = 'GL_EXT_texture_rectangle' then Result := Load_GL_EXT_texture_rectangle + else if ext = 'GL_S3_s3tc' then Result := Load_GL_S3_s3tc + else if ext = 'GL_ATI_draw_buffers' then Result := Load_GL_ATI_draw_buffers + {$IFDEF msWindows} + else if ext = 'WGL_ATI_pixel_format_float' then Result := Load_WGL_ATI_pixel_format_float + {$ENDIF} + else if ext = 'GL_ATI_texture_env_combine3' then Result := Load_GL_ATI_texture_env_combine3 + else if ext = 'GL_ATI_texture_float' then Result := Load_GL_ATI_texture_float + else if ext = 'GL_NV_texture_expand_normal' then Result := Load_GL_NV_texture_expand_normal + else if ext = 'GL_NV_half_float' then Result := Load_GL_NV_half_float + else if ext = 'GL_ATI_map_object_buffer' then Result := Load_GL_ATI_map_object_buffer + else if ext = 'GL_ATI_separate_stencil' then Result := Load_GL_ATI_separate_stencil + else if ext = 'GL_ATI_vertex_attrib_array_object' then Result := Load_GL_ATI_vertex_attrib_array_object + else if ext = 'GL_ARB_vertex_buffer_object' then Result := Load_GL_ARB_vertex_buffer_object + else if ext = 'GL_ARB_occlusion_query' then Result := Load_GL_ARB_occlusion_query + else if ext = 'GL_ARB_shader_objects' then Result := Load_GL_ARB_shader_objects + else if ext = 'GL_ARB_vertex_shader' then Result := Load_GL_ARB_vertex_shader + else if ext = 'GL_ARB_fragment_shader' then Result := Load_GL_ARB_fragment_shader + else if ext = 'GL_ARB_shading_language_100' then Result := Load_GL_ARB_shading_language_100 + else if ext = 'GL_ARB_texture_non_power_of_two' then Result := Load_GL_ARB_texture_non_power_of_two + else if ext = 'GL_ARB_point_sprite' then Result := Load_GL_ARB_point_sprite + else if ext = 'GL_EXT_depth_bounds_test' then Result := Load_GL_EXT_depth_bounds_test + else if ext = 'GL_EXT_texture_mirror_clamp' then Result := Load_GL_EXT_texture_mirror_clamp + else if ext = 'GL_EXT_blend_equation_separate' then Result := Load_GL_EXT_blend_equation_separate + else if ext = 'GL_MESA_pack_invert' then Result := Load_GL_MESA_pack_invert + else if ext = 'GL_MESA_ycbcr_texture' then Result := Load_GL_MESA_ycbcr_texture + else if ext = 'GL_ARB_fragment_program_shadow' then Result := Load_GL_ARB_fragment_program_shadow + else if ext = 'GL_NV_fragment_program_option' then Result := Load_GL_NV_fragment_program_option + else if ext = 'GL_EXT_pixel_buffer_object' then Result := Load_GL_EXT_pixel_buffer_object + else if ext = 'GL_NV_fragment_program2' then Result := Load_GL_NV_fragment_program2 + else if ext = 'GL_NV_vertex_program2_option' then Result := Load_GL_NV_vertex_program2_option + else if ext = 'GL_NV_vertex_program3' then Result := Load_GL_NV_vertex_program3 + else if ext = 'GL_ARB_draw_buffers' then Result := Load_GL_ARB_draw_buffers + else if ext = 'GL_ARB_texture_rectangle' then Result := Load_GL_ARB_texture_rectangle + else if ext = 'GL_ARB_color_buffer_float' then Result := Load_GL_ARB_color_buffer_float + else if ext = 'GL_ARB_half_float_pixel' then Result := Load_GL_ARB_half_float_pixel + else if ext = 'GL_ARB_texture_float' then Result := Load_GL_ARB_texture_float + else if ext = 'GL_EXT_texture_compression_dxt1' then Result := Load_GL_EXT_texture_compression_dxt1 + else if ext = 'GL_ARB_pixel_buffer_object' then Result := Load_GL_ARB_pixel_buffer_object + else if ext = 'GL_EXT_framebuffer_object' then Result := Load_GL_EXT_framebuffer_object + else if ext = 'GL_version_1_4' then Result := Load_GL_version_1_4 + else if ext = 'GL_version_1_5' then Result := Load_GL_version_1_5 + else if ext = 'GL_version_2_0' then Result := Load_GL_version_2_0 + +end; +*) + +function Load_GL_VERSION_2_1(): Boolean; +const + funcs: array[0..5] of funcinfoty = + ( + (n: 'glUniformMatrix2x3fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2x3fv), + (n: 'glUniformMatrix3x2fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3x2fv), + (n: 'glUniformMatrix2x4fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2x4fv), + (n: 'glUniformMatrix4x2fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4x2fv), + (n: 'glUniformMatrix3x4fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3x4fv), + (n: 'glUniformMatrix4x3fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4x3fv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_VERSION_3_0(): Boolean; +const + funcs: array[0..57] of funcinfoty = + ( + (n: 'glColorMaski'; d: {$ifndef FPC}@{$endif}@glColorMaski), + (n: 'glGetBooleani_v'; d: {$ifndef FPC}@{$endif}@glGetBooleani_v), + (n: 'glGetIntegeri_v'; d: {$ifndef FPC}@{$endif}@glGetIntegeri_v), + (n: 'glEnablei'; d: {$ifndef FPC}@{$endif}@glEnablei), + (n: 'glDisablei'; d: {$ifndef FPC}@{$endif}@glDisablei), + (n: 'glIsEnabledi'; d: {$ifndef FPC}@{$endif}@glIsEnabledi), + (n: 'glBeginTransformFeedback'; d: {$ifndef FPC}@{$endif}@glBeginTransformFeedback), + (n: 'glEndTransformFeedback'; d: {$ifndef FPC}@{$endif}@glEndTransformFeedback), + (n: 'glBindBufferRange'; d: {$ifndef FPC}@{$endif}@glBindBufferRange), + (n: 'glBindBufferBase'; d: {$ifndef FPC}@{$endif}@glBindBufferBase), + (n: 'glTransformFeedbackVaryings'; d: {$ifndef FPC}@{$endif}@glTransformFeedbackVaryings), + (n: 'glGetTransformFeedbackVarying'; d: {$ifndef FPC}@{$endif}@glGetTransformFeedbackVarying), + (n: 'glClampColor'; d: {$ifndef FPC}@{$endif}@glClampColor), + (n: 'glBeginConditionalRender'; d: {$ifndef FPC}@{$endif}@glBeginConditionalRender), + (n: 'glEndConditionalRender'; d: {$ifndef FPC}@{$endif}@glEndConditionalRender), + (n: 'glVertexAttribIPointer'; d: {$ifndef FPC}@{$endif}@glVertexAttribIPointer), + (n: 'glGetVertexAttribIiv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribIiv), + (n: 'glGetVertexAttribIuiv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribIuiv), + (n: 'glVertexAttribI1i'; d: {$ifndef FPC}@{$endif}@glVertexAttribI1i), + (n: 'glVertexAttribI2i'; d: {$ifndef FPC}@{$endif}@glVertexAttribI2i), + (n: 'glVertexAttribI3i'; d: {$ifndef FPC}@{$endif}@glVertexAttribI3i), + (n: 'glVertexAttribI4i'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4i), + (n: 'glVertexAttribI1ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribI1ui), + (n: 'glVertexAttribI2ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribI2ui), + (n: 'glVertexAttribI3ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribI3ui), + (n: 'glVertexAttribI4ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4ui), + (n: 'glVertexAttribI1iv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI1iv), + (n: 'glVertexAttribI2iv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI2iv), + (n: 'glVertexAttribI3iv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI3iv), + (n: 'glVertexAttribI4iv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4iv), + (n: 'glVertexAttribI1uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI1uiv), + (n: 'glVertexAttribI2uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI2uiv), + (n: 'glVertexAttribI3uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI3uiv), + (n: 'glVertexAttribI4uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4uiv), + (n: 'glVertexAttribI4bv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4bv), + (n: 'glVertexAttribI4sv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4sv), + (n: 'glVertexAttribI4ubv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4ubv), + (n: 'glVertexAttribI4usv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4usv), + (n: 'glGetUniformuiv'; d: {$ifndef FPC}@{$endif}@glGetUniformuiv), + (n: 'glBindFragDataLocation'; d: {$ifndef FPC}@{$endif}@glBindFragDataLocation), + (n: 'glGetFragDataLocation'; d: {$ifndef FPC}@{$endif}@glGetFragDataLocation), + (n: 'glUniform1ui'; d: {$ifndef FPC}@{$endif}@glUniform1ui), + (n: 'glUniform2ui'; d: {$ifndef FPC}@{$endif}@glUniform2ui), + (n: 'glUniform3ui'; d: {$ifndef FPC}@{$endif}@glUniform3ui), + (n: 'glUniform4ui'; d: {$ifndef FPC}@{$endif}@glUniform4ui), + (n: 'glUniform1uiv'; d: {$ifndef FPC}@{$endif}@glUniform1uiv), + (n: 'glUniform2uiv'; d: {$ifndef FPC}@{$endif}@glUniform2uiv), + (n: 'glUniform3uiv'; d: {$ifndef FPC}@{$endif}@glUniform3uiv), + (n: 'glUniform4uiv'; d: {$ifndef FPC}@{$endif}@glUniform4uiv), + (n: 'glTexParameterIiv'; d: {$ifndef FPC}@{$endif}@glTexParameterIiv), + (n: 'glTexParameterIuiv'; d: {$ifndef FPC}@{$endif}@glTexParameterIuiv), + (n: 'glGetTexParameterIiv'; d: {$ifndef FPC}@{$endif}@glGetTexParameterIiv), + (n: 'glGetTexParameterIuiv'; d: {$ifndef FPC}@{$endif}@glGetTexParameterIuiv), + (n: 'glClearBufferiv'; d: {$ifndef FPC}@{$endif}@glClearBufferiv), + (n: 'glClearBufferuiv'; d: {$ifndef FPC}@{$endif}@glClearBufferuiv), + (n: 'glClearBufferfv'; d: {$ifndef FPC}@{$endif}@glClearBufferfv), + (n: 'glClearBufferfi'; d: {$ifndef FPC}@{$endif}@glClearBufferfi), + (n: 'glGetStringi'; d: {$ifndef FPC}@{$endif}@glGetStringi) + ); +begin + result:= getprocaddresses(libgl,funcs); + result:= result and mseglloadextensions([ + gle_GL_ARB_framebuffer_object, + gle_GL_ARB_map_buffer_range, + gle_GL_ARB_vertex_array_object]); +end; + +function Load_GL_VERSION_3_1(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glDrawArraysInstanced'; d: {$ifndef FPC}@{$endif}@glDrawArraysInstanced), + (n: 'glDrawElementsInstanced'; d: {$ifndef FPC}@{$endif}@glDrawElementsInstanced), + (n: 'glTexBuffer'; d: {$ifndef FPC}@{$endif}@glTexBuffer), + (n: 'glPrimitiveRestartIndex'; d: {$ifndef FPC}@{$endif}@glPrimitiveRestartIndex) + ); +begin + result:= getprocaddresses(libgl,funcs); + result:= result and mseglloadextensions([ + gle_GL_ARB_copy_buffer, + gle_GL_ARB_uniform_buffer_object]); +end; + +function Load_GL_VERSION_3_2(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glGetInteger64i_v'; d: {$ifndef FPC}@{$endif}@glGetInteger64i_v), + (n: 'glGetBufferParameteri64v'; d: {$ifndef FPC}@{$endif}@glGetBufferParameteri64v), + (n: 'glProgramParameteri'; d: {$ifndef FPC}@{$endif}@glProgramParameteri), + (n: 'glFramebufferTexture'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture) + ); +begin + result:= getprocaddresses(libgl,funcs); + result:= result and mseglloadextensions([ + gle_GL_ARB_draw_elements_base_vertex, + gle_GL_ARB_provoking_vertex, + gle_GL_ARB_sync, + gle_GL_ARB_texture_multisample]); +end; + +function Load_GL_VERSION_3_3(): Boolean; +begin + result:= mseglloadextensions([ + gle_GL_ARB_blend_func_extended, + gle_GL_ARB_sampler_objects, + gle_GL_ARB_timer_query, + gle_GL_ARB_vertex_type_2_10_10_10_rev]); +end; + +function Load_GL_VERSION_4_0(): Boolean; +begin + result:= mseglloadextensions([ + gle_GL_ARB_gpu_shader_fp64, + gle_GL_ARB_shader_subroutine, + gle_GL_ARB_tessellation_shader, + gle_GL_ARB_transform_feedback2, + gle_GL_ARB_transform_feedback3]); +end; + +end. diff --git a/mseide-msegui/lib/common/opengl/mseglextglob.pas b/mseide-msegui/lib/common/opengl/mseglextglob.pas new file mode 100644 index 0000000..8cabad7 --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseglextglob.pas @@ -0,0 +1,653 @@ +{ MSEgui Copyright (c) 2011-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseglextglob; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msedynload,{msegl,}msesys,{$ifdef FPC}dynlibs,{$else}classes_del,{$endif} + msegraphics,msetypes; + +type + glextensionty = ( + {$ifdef mswindows} + {$else} + gle_glx, + gle_glx_mesa, + {$endif} + gle_GL_version_1_2, + gle_GL_ARB_imaging, + gle_GL_version_1_3, + gle_GL_ARB_multitexture, + gle_GL_ARB_transpose_matrix, + gle_GL_ARB_multisample, + gle_GL_ARB_texture_env_add, +{$IFDEF msWindows} + gle_WGL_ARB_extensions_string, + gle_WGL_ARB_buffer_region, +{$ENDIF} + gle_GL_ARB_texture_cube_map, + gle_GL_ARB_depth_texture, + gle_GL_ARB_point_parameters, + gle_GL_ARB_shadow, + gle_GL_ARB_shadow_ambient, + gle_GL_ARB_texture_border_clamp, + gle_GL_ARB_texture_compression, + gle_GL_ARB_texture_env_combine, + gle_GL_ARB_texture_env_crossbar, + gle_GL_ARB_texture_env_dot3, + gle_GL_ARB_texture_mirrored_repeat, + gle_GL_ARB_vertex_blend, + gle_GL_ARB_vertex_program, + gle_GL_ARB_window_pos, + gle_GL_EXT_422_pixels, + gle_GL_EXT_abgr, + gle_GL_EXT_bgra, + gle_GL_EXT_blend_color, + gle_GL_EXT_blend_func_separate, + gle_GL_EXT_blend_logic_op, + gle_GL_EXT_blend_minmax, + gle_GL_EXT_blend_subtract, + gle_GL_EXT_clip_volume_hint, + gle_GL_EXT_color_subtable, + gle_GL_EXT_compiled_vertex_array, + gle_GL_EXT_convolution, + gle_GL_EXT_fog_coord, + gle_GL_EXT_histogram, + gle_GL_EXT_multi_draw_arrays, + gle_GL_EXT_packed_pixels, + gle_GL_EXT_paletted_texture, + gle_GL_EXT_point_parameters, + gle_GL_EXT_polygon_offset, + gle_GL_EXT_secondary_color, + gle_GL_EXT_separate_specular_color, + gle_GL_EXT_shadow_funcs, + gle_GL_EXT_shared_texture_palette, + gle_GL_EXT_stencil_two_side, + gle_GL_EXT_stencil_wrap, + gle_GL_EXT_subtexture, + gle_GL_EXT_texture3D, + gle_GL_EXT_texture_compression_s3tc, + gle_GL_EXT_texture_env_add, + gle_GL_EXT_texture_env_combine, + gle_GL_EXT_texture_env_dot3, + gle_GL_EXT_texture_filter_anisotropic, + gle_GL_EXT_texture_lod_bias, + gle_GL_EXT_texture_object, + gle_GL_EXT_vertex_array, + gle_GL_EXT_vertex_shader, + gle_GL_EXT_vertex_weighting, + gle_GL_HP_occlusion_test, + gle_GL_NV_blend_square, + gle_GL_NV_copy_depth_to_color, + gle_GL_NV_depth_clamp, + gle_GL_NV_evaluators, + gle_GL_NV_fence, + gle_GL_NV_fog_distance, + gle_GL_NV_light_max_exponent, + gle_GL_NV_multisample_filter_hint, + gle_GL_NV_occlusion_query, + gle_GL_NV_packed_depth_stencil, + gle_GL_NV_point_sprite, + gle_GL_NV_register_combiners, + gle_GL_NV_register_combiners2, + gle_GL_NV_texgen_emboss, + gle_GL_NV_texgen_reflection, + gle_GL_NV_texture_compression_vtc, + gle_GL_NV_texture_env_combine4, + gle_GL_NV_texture_rectangle, + gle_GL_NV_texture_shader, + gle_GL_NV_texture_shader2, + gle_GL_NV_texture_shader3, + gle_GL_NV_vertex_array_range, + gle_GL_NV_vertex_array_range2, + gle_GL_NV_vertex_program, + gle_GL_NV_vertex_program1_1, + gle_GL_ATI_element_array, + gle_GL_ATI_envmap_bumpmap, + gle_GL_ATI_fragment_shader, + gle_GL_ATI_pn_triangles, + gle_GL_ATI_texture_mirror_once, + gle_GL_ATI_vertex_array_object, + gle_GL_ATI_vertex_streams, +{$IFDEF msWindows} + gle_WGL_I3D_image_buffer, + gle_WGL_I3D_swap_frame_lock, + gle_WGL_I3D_swap_frame_usage, +{$ENDIF} + gle_GL_3DFX_texture_compression_FXT1, + gle_GL_IBM_cull_vertex, + gle_GL_IBM_multimode_draw_arrays, + gle_GL_IBM_raster_pos_clip, + gle_GL_IBM_texture_mirrored_repeat, + gle_GL_IBM_vertex_array_lists, + gle_GL_MESA_resize_buffers, + gle_GL_MESA_window_pos, + gle_GL_OML_interlace, + gle_GL_OML_resample, + gle_GL_OML_subsample, + gle_GL_SGIS_generate_mipmap, + gle_GL_SGIS_multisample, + gle_GL_SGIS_pixel_texture, + gle_GL_SGIS_texture_border_clamp, + gle_GL_SGIS_texture_color_mask, + gle_GL_SGIS_texture_edge_clamp, + gle_GL_SGIS_texture_lod, + gle_GL_SGIS_depth_texture, + gle_GL_SGIX_fog_offset, + gle_GL_SGIX_interlace, + gle_GL_SGIX_shadow_ambient, + gle_GL_SGI_color_matrix, + gle_GL_SGI_color_table, + gle_GL_SGI_texture_color_table, + gle_GL_SUN_vertex, + gle_GL_ARB_fragment_program, + gle_GL_ATI_text_fragment_shader, + gle_GL_APPLE_client_storage, + gle_GL_APPLE_element_array, + gle_GL_APPLE_fence, + gle_GL_APPLE_vertex_array_object, + gle_GL_APPLE_vertex_array_range, +{$IFDEF msWindows} + gle_WGL_ARB_pixel_format, + gle_WGL_ARB_make_current_read, + gle_WGL_ARB_pbuffer, + gle_WGL_EXT_swap_control, + gle_WGL_ARB_render_texture, + gle_WGL_EXT_extensions_string, + gle_WGL_EXT_make_current_read, + gle_WGL_EXT_pbuffer, + gle_WGL_EXT_pixel_format, + gle_WGL_I3D_digital_video_control, + gle_WGL_I3D_gamma, + gle_WGL_I3D_genlock, +{$ENDIF} + gle_GL_ARB_matrix_palette, + gle_GL_NV_element_array, + gle_GL_NV_float_buffer, + gle_GL_NV_fragment_program, + gle_GL_NV_primitive_restart, + gle_GL_NV_vertex_program2, + {$IFDEF msWindows} + gle_WGL_NV_render_texture_rectangle, + {$ENDIF} + gle_GL_NV_pixel_data_range, + gle_GL_EXT_texture_rectangle, + gle_GL_S3_s3tc, + gle_GL_ATI_draw_buffers, + {$IFDEF msWindows} + gle_WGL_ATI_pixel_format_float, + {$ENDIF} + gle_GL_ATI_texture_env_combine3, + gle_GL_ATI_texture_float, + gle_GL_NV_texture_expand_normal, + gle_GL_NV_half_float, + gle_GL_ATI_map_object_buffer, + gle_GL_ATI_separate_stencil, + gle_GL_ATI_vertex_attrib_array_object, + gle_GL_ARB_vertex_buffer_object, + gle_GL_ARB_occlusion_query, + gle_GL_ARB_shader_objects, + gle_GL_ARB_vertex_shader, + gle_GL_ARB_fragment_shader, + gle_GL_ARB_shading_language_100, + gle_GL_ARB_texture_non_power_of_two, + gle_GL_ARB_point_sprite, + gle_GL_EXT_depth_bounds_test, + gle_GL_EXT_texture_mirror_clamp, + gle_GL_EXT_blend_equation_separate, + gle_GL_MESA_pack_invert, + gle_GL_MESA_ycbcr_texture, + gle_GL_ARB_fragment_program_shadow, + gle_GL_NV_fragment_program_option, + gle_GL_EXT_pixel_buffer_object, + gle_GL_NV_fragment_program2, + gle_GL_NV_vertex_program2_option, + gle_GL_NV_vertex_program3, + gle_GL_ARB_draw_buffers, + gle_GL_ARB_texture_rectangle, + gle_GL_ARB_color_buffer_float, + gle_GL_ARB_half_float_pixel, + gle_GL_ARB_texture_float, + gle_GL_EXT_texture_compression_dxt1, + gle_GL_ARB_pixel_buffer_object, + gle_GL_EXT_framebuffer_object, + gle_GL_ARB_framebuffer_object, + gle_GL_ARB_map_buffer_range, + gle_GL_ARB_vertex_array_object, + gle_GL_ARB_copy_buffer, + gle_GL_ARB_uniform_buffer_object, + gle_GL_ARB_draw_elements_base_vertex, + gle_GL_ARB_provoking_vertex, + gle_GL_ARB_sync, + gle_GL_ARB_texture_multisample, + gle_GL_ARB_blend_func_extended, + gle_GL_ARB_sampler_objects, + gle_GL_ARB_timer_query, + gle_GL_ARB_vertex_type_2_10_10_10_rev, + gle_GL_ARB_gpu_shader_fp64, + gle_GL_ARB_shader_subroutine, + gle_GL_ARB_tessellation_shader, + gle_GL_ARB_transform_feedback2, + gle_GL_ARB_transform_feedback3, + gle_GL_version_1_4, + gle_GL_version_1_5, + gle_GL_version_2_0, + gle_GL_version_2_1, + gle_GL_version_3_0, + gle_GL_version_3_1, + gle_GL_version_3_2, + gle_GL_version_3_3, + gle_GL_version_4_0 + ); + glextensionsty = set of glextensionty; + +function mseglparseextensions(const astr: pchar): glextensionsty; +function gldeviceextensions(const device: ptruint): glextensionsty; +function mseglloadextensions(const extensions: array of glextensionty): boolean; + //true if ok +var + libgl: tlibhandle; + +procedure init(); //do not use, automatically called by msegl + +implementation +uses + msegl,mseglext,msestrings{$ifdef mswindows}{$else}, + mseglx,mseguiintf{$endif}, + mseglu; + +type + glextloaderty = function: boolean; + + glextensioninfoty = record + name: string; + loader: glextloaderty; + end; +var + loadedextensions: glextensionsty; + badextensions: glextensionsty; + +function gldeviceextensions(const device: ptruint): glextensionsty; +begin + result:= []; +{$ifdef mswindows} + if mseglloadextensions([gle_WGL_EXT_extensions_string]) then begin + result:= result + mseglparseextensions(wglGetExtensionsStringEXT()); + end; + if mseglloadextensions([gle_WGL_ARB_extensions_string]) then begin + result:= result + mseglparseextensions(wglGetExtensionsStringARB(device)); + end; +{$else} + if {$ifndef FPC}@{$endif}glxqueryextensionsstring <> nil then begin + result:= mseglparseextensions( + glxqueryextensionsstring(msedisplay,msedefaultscreenno)); + end; +{$endif} +end; + +procedure initglext(const ainfo: dynlibinfoty); +begin + libgl:= ainfo.libhandle; + initializeglu([]); +end; + +procedure deinitglext(const ainfo: dynlibinfoty); +begin + loadedextensions:= []; + badextensions:= []; + releaseglu; +end; + +function l_GL_version_1_2: boolean; +begin + result:= load_GL_version_1_2; +end; + +function l_GL_version_1_3: boolean; +begin + result:= mseglloadextensions([gle_GL_version_1_2]) and load_GL_version_1_3; +end; + +function l_GL_version_1_4: boolean; +begin + result:= mseglloadextensions([gle_GL_version_1_3]) and load_GL_version_1_4; +end; + +function l_GL_version_1_5: boolean; +begin + result:= mseglloadextensions([gle_GL_version_1_4]) and load_GL_version_1_5; +end; + +function l_GL_version_2_0: boolean; +begin + result:= mseglloadextensions([gle_GL_version_1_5]) and load_GL_version_2_0; +end; + +function l_GL_version_2_1: boolean; +begin + result:= mseglloadextensions([gle_GL_version_2_0]) and load_GL_version_2_1; +end; + +function l_GL_version_3_0: boolean; +begin + result:= mseglloadextensions([gle_GL_version_2_1]) and load_GL_version_3_0; +end; + +function l_GL_version_3_1: boolean; +begin + result:= mseglloadextensions([gle_GL_version_3_0]) and load_GL_version_3_1; +end; + +function l_GL_version_3_2: boolean; +begin + result:= mseglloadextensions([gle_GL_version_3_1]) and load_GL_version_3_2; +end; + +function l_GL_version_3_3: boolean; +begin + result:= mseglloadextensions([gle_GL_version_3_2]) and load_GL_version_3_3; +end; + +function l_GL_version_4_0: boolean; +begin + result:= mseglloadextensions([gle_GL_version_3_3]) and load_GL_version_4_0; +end; + +const + glextensions: array[glextensionty] of glextensioninfoty = + ( + {$ifdef mswindows} + {$else} + (name: 'glx'; loader: {$ifdef FPC}@{$endif}load_glx), + (name: 'glx_mesa'; loader: {$ifdef FPC}@{$endif}load_glx_mesa), + {$endif} + (name: 'GL_version_1_2'; loader: {$ifdef FPC}@{$endif}l_GL_version_1_2), + (name: 'GL_ARB_imaging'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_imaging), + (name: 'GL_version_1_3'; loader: {$ifdef FPC}@{$endif}l_GL_version_1_3), + (name: 'GL_ARB_multitexture'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_multitexture), + (name: 'GL_ARB_transpose_matrix'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_transpose_matrix), + (name: 'GL_ARB_multisample'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_multisample), + (name: 'GL_ARB_texture_env_add'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_env_add), +{$IFDEF msWindows} + (name: 'WGL_ARB_extensions_string'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_extensions_string), + (name: 'WGL_ARB_buffer_region'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_buffer_region), +{$ENDIF} + (name: 'GL_ARB_texture_cube_map'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_cube_map), + (name: 'GL_ARB_depth_texture'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_depth_texture), + (name: 'GL_ARB_point_parameters'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_point_parameters), + (name: 'GL_ARB_shadow'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_shadow), + (name: 'GL_ARB_shadow_ambient'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_shadow_ambient), + (name: 'GL_ARB_texture_border_clamp'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_border_clamp), + (name: 'GL_ARB_texture_compression'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_compression), + (name: 'GL_ARB_texture_env_combine'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_env_combine), + (name: 'GL_ARB_texture_env_crossbar'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_env_crossbar), + (name: 'GL_ARB_texture_env_dot3'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_env_dot3), + (name: 'GL_ARB_texture_mirrored_repeat'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_mirrored_repeat), + (name: 'GL_ARB_vertex_blend'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_blend), + (name: 'GL_ARB_vertex_program'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_program), + (name: 'GL_ARB_window_pos'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_window_pos), + (name: 'GL_EXT_422_pixels'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_422_pixels), + (name: 'GL_EXT_abgr'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_abgr), + (name: 'GL_EXT_bgra'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_bgra), + (name: 'GL_EXT_blend_color'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_color), + (name: 'GL_EXT_blend_func_separate'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_func_separate), + (name: 'GL_EXT_blend_logic_op'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_logic_op), + (name: 'GL_EXT_blend_minmax'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_minmax), + (name: 'GL_EXT_blend_subtract'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_subtract), + (name: 'GL_EXT_clip_volume_hint'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_clip_volume_hint), + (name: 'GL_EXT_color_subtable'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_color_subtable), + (name: 'GL_EXT_compiled_vertex_array'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_compiled_vertex_array), + (name: 'GL_EXT_convolution'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_convolution), + (name: 'GL_EXT_fog_coord'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_fog_coord), + (name: 'GL_EXT_histogram'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_histogram), + (name: 'GL_EXT_multi_draw_arrays'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_multi_draw_arrays), + (name: 'GL_EXT_packed_pixels'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_packed_pixels), + (name: 'GL_EXT_paletted_texture'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_paletted_texture), + (name: 'GL_EXT_point_parameters'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_point_parameters), + (name: 'GL_EXT_polygon_offset'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_polygon_offset), + (name: 'GL_EXT_secondary_color'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_secondary_color), + (name: 'GL_EXT_separate_specular_color'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_separate_specular_color), + (name: 'GL_EXT_shadow_funcs'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_shadow_funcs), + (name: 'GL_EXT_shared_texture_palette'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_shared_texture_palette), + (name: 'GL_EXT_stencil_two_side'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_stencil_two_side), + (name: 'GL_EXT_stencil_wrap'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_stencil_wrap), + (name: 'GL_EXT_subtexture'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_subtexture), + (name: 'GL_EXT_texture3D'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture3D), + (name: 'GL_EXT_texture_compression_s3tc'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_compression_s3tc), + (name: 'GL_EXT_texture_env_add'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_env_add), + (name: 'GL_EXT_texture_env_combine'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_env_combine), + (name: 'GL_EXT_texture_env_dot3'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_env_dot3), + (name: 'GL_EXT_texture_filter_anisotropic'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_filter_anisotropic), + (name: 'GL_EXT_texture_lod_bias'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_lod_bias), + (name: 'GL_EXT_texture_object'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_object), + (name: 'GL_EXT_vertex_array'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_vertex_array), + (name: 'GL_EXT_vertex_shader'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_vertex_shader), + (name: 'GL_EXT_vertex_weighting'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_vertex_weighting), + (name: 'GL_HP_occlusion_test'; loader: {$ifdef FPC}@{$endif}load_GL_HP_occlusion_test), + (name: 'GL_NV_blend_square'; loader: {$ifdef FPC}@{$endif}load_GL_NV_blend_square), + (name: 'GL_NV_copy_depth_to_color'; loader: {$ifdef FPC}@{$endif}load_GL_NV_copy_depth_to_color), + (name: 'GL_NV_depth_clamp'; loader: {$ifdef FPC}@{$endif}load_GL_NV_depth_clamp), + (name: 'GL_NV_evaluators'; loader: {$ifdef FPC}@{$endif}load_GL_NV_evaluators), + (name: 'GL_NV_fence'; loader: {$ifdef FPC}@{$endif}load_GL_NV_fence), + (name: 'GL_NV_fog_distance'; loader: {$ifdef FPC}@{$endif}load_GL_NV_fog_distance), + (name: 'GL_NV_light_max_exponent'; loader: {$ifdef FPC}@{$endif}load_GL_NV_light_max_exponent), + (name: 'GL_NV_multisample_filter_hint'; loader: {$ifdef FPC}@{$endif}load_GL_NV_multisample_filter_hint), + (name: 'GL_NV_occlusion_query'; loader: {$ifdef FPC}@{$endif}load_GL_NV_occlusion_query), + (name: 'GL_NV_packed_depth_stencil'; loader: {$ifdef FPC}@{$endif}load_GL_NV_packed_depth_stencil), + (name: 'GL_NV_point_sprite'; loader: {$ifdef FPC}@{$endif}load_GL_NV_point_sprite), + (name: 'GL_NV_register_combiners'; loader: {$ifdef FPC}@{$endif}load_GL_NV_register_combiners), + (name: 'GL_NV_register_combiners2'; loader: {$ifdef FPC}@{$endif}load_GL_NV_register_combiners2), + (name: 'GL_NV_texgen_emboss'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texgen_emboss), + (name: 'GL_NV_texgen_reflection'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texgen_reflection), + (name: 'GL_NV_texture_compression_vtc'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_compression_vtc), + (name: 'GL_NV_texture_env_combine4'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_env_combine4), + (name: 'GL_NV_texture_rectangle'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_rectangle), + (name: 'GL_NV_texture_shader'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_shader), + (name: 'GL_NV_texture_shader2'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_shader2), + (name: 'GL_NV_texture_shader3'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_shader3), + (name: 'GL_NV_vertex_array_range'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_array_range), + (name: 'GL_NV_vertex_array_range2'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_array_range2), + (name: 'GL_NV_vertex_program'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_program), + (name: 'GL_NV_vertex_program1_1'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_program1_1), + (name: 'GL_ATI_element_array'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_element_array), + (name: 'GL_ATI_envmap_bumpmap'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_envmap_bumpmap), + (name: 'GL_ATI_fragment_shader'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_fragment_shader), + (name: 'GL_ATI_pn_triangles'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_pn_triangles), + (name: 'GL_ATI_texture_mirror_once'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_texture_mirror_once), + (name: 'GL_ATI_vertex_array_object'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_vertex_array_object), + (name: 'GL_ATI_vertex_streams'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_vertex_streams), +{$IFDEF msWindows} + (name: 'WGL_I3D_image_buffer'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_image_buffer), + (name: 'WGL_I3D_swap_frame_lock'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_swap_frame_lock), + (name: 'WGL_I3D_swap_frame_usage'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_swap_frame_usage), +{$ENDIF} + (name: 'GL_3DFX_texture_compression_FXT1'; loader: {$ifdef FPC}@{$endif}load_GL_3DFX_texture_compression_FXT1), + (name: 'GL_IBM_cull_vertex'; loader: {$ifdef FPC}@{$endif}load_GL_IBM_cull_vertex), + (name: 'GL_IBM_multimode_draw_arrays'; loader: {$ifdef FPC}@{$endif}load_GL_IBM_multimode_draw_arrays), + (name: 'GL_IBM_raster_pos_clip'; loader: {$ifdef FPC}@{$endif}load_GL_IBM_raster_pos_clip), + (name: 'GL_IBM_texture_mirrored_repeat'; loader: {$ifdef FPC}@{$endif}load_GL_IBM_texture_mirrored_repeat), + (name: 'GL_IBM_vertex_array_lists'; loader: {$ifdef FPC}@{$endif}load_GL_IBM_vertex_array_lists), + (name: 'GL_MESA_resize_buffers'; loader: {$ifdef FPC}@{$endif}load_GL_MESA_resize_buffers), + (name: 'GL_MESA_window_pos'; loader: {$ifdef FPC}@{$endif}load_GL_MESA_window_pos), + (name: 'GL_OML_interlace'; loader: {$ifdef FPC}@{$endif}load_GL_OML_interlace), + (name: 'GL_OML_resample'; loader: {$ifdef FPC}@{$endif}load_GL_OML_resample), + (name: 'GL_OML_subsample'; loader: {$ifdef FPC}@{$endif}load_GL_OML_subsample), + (name: 'GL_SGIS_generate_mipmap'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_generate_mipmap), + (name: 'GL_SGIS_multisample'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_multisample), + (name: 'GL_SGIS_pixel_texture'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_pixel_texture), + (name: 'GL_SGIS_texture_border_clamp'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_texture_border_clamp), + (name: 'GL_SGIS_texture_color_mask'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_texture_color_mask), + (name: 'GL_SGIS_texture_edge_clamp'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_texture_edge_clamp), + (name: 'GL_SGIS_texture_lod'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_texture_lod), + (name: 'GL_SGIS_depth_texture'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_depth_texture), + (name: 'GL_SGIX_fog_offset'; loader: {$ifdef FPC}@{$endif}load_GL_SGIX_fog_offset), + (name: 'GL_SGIX_interlace'; loader: {$ifdef FPC}@{$endif}load_GL_SGIX_interlace), + (name: 'GL_SGIX_shadow_ambient'; loader: {$ifdef FPC}@{$endif}load_GL_SGIX_shadow_ambient), + (name: 'GL_SGI_color_matrix'; loader: {$ifdef FPC}@{$endif}load_GL_SGI_color_matrix), + (name: 'GL_SGI_color_table'; loader: {$ifdef FPC}@{$endif}load_GL_SGI_color_table), + (name: 'GL_SGI_texture_color_table'; loader: {$ifdef FPC}@{$endif}load_GL_SGI_texture_color_table), + (name: 'GL_SUN_vertex'; loader: {$ifdef FPC}@{$endif}load_GL_SUN_vertex), + (name: 'GL_ARB_fragment_program'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_fragment_program), + (name: 'GL_ATI_text_fragment_shader'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_text_fragment_shader), + (name: 'GL_APPLE_client_storage'; loader: {$ifdef FPC}@{$endif}load_GL_APPLE_client_storage), + (name: 'GL_APPLE_element_array'; loader: {$ifdef FPC}@{$endif}load_GL_APPLE_element_array), + (name: 'GL_APPLE_fence'; loader: {$ifdef FPC}@{$endif}load_GL_APPLE_fence), + (name: 'GL_APPLE_vertex_array_object'; loader: {$ifdef FPC}@{$endif}load_GL_APPLE_vertex_array_object), + (name: 'GL_APPLE_vertex_array_range'; loader: {$ifdef FPC}@{$endif}load_GL_APPLE_vertex_array_range), +{$IFDEF msWindows} + (name: 'WGL_ARB_pixel_format'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_pixel_format), + (name: 'WGL_ARB_make_current_read'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_make_current_read), + (name: 'WGL_ARB_pbuffer'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_pbuffer), + (name: 'WGL_EXT_swap_control'; loader: {$ifdef FPC}@{$endif}load_WGL_EXT_swap_control), + (name: 'WGL_ARB_render_texture'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_render_texture), + (name: 'WGL_EXT_extensions_string'; loader: {$ifdef FPC}@{$endif}load_WGL_EXT_extensions_string), + (name: 'WGL_EXT_make_current_read'; loader: {$ifdef FPC}@{$endif}load_WGL_EXT_make_current_read), + (name: 'WGL_EXT_pbuffer'; loader: {$ifdef FPC}@{$endif}load_WGL_EXT_pbuffer), + (name: 'WGL_EXT_pixel_format'; loader: {$ifdef FPC}@{$endif}load_WGL_EXT_pixel_format), + (name: 'WGL_I3D_digital_video_control'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_digital_video_control), + (name: 'WGL_I3D_gamma'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_gamma), + (name: 'WGL_I3D_genlock'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_genlock), +{$ENDIF} + (name: 'GL_ARB_matrix_palette'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_matrix_palette), + (name: 'GL_NV_element_array'; loader: {$ifdef FPC}@{$endif}load_GL_NV_element_array), + (name: 'GL_NV_float_buffer'; loader: {$ifdef FPC}@{$endif}load_GL_NV_float_buffer), + (name: 'GL_NV_fragment_program'; loader: {$ifdef FPC}@{$endif}load_GL_NV_fragment_program), + (name: 'GL_NV_primitive_restart'; loader: {$ifdef FPC}@{$endif}load_GL_NV_primitive_restart), + (name: 'GL_NV_vertex_program2'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_program2), + {$IFDEF msWindows} + (name: 'WGL_NV_render_texture_rectangle'; loader: {$ifdef FPC}@{$endif}load_WGL_NV_render_texture_rectangle), + {$ENDIF} + (name: 'GL_NV_pixel_data_range'; loader: {$ifdef FPC}@{$endif}load_GL_NV_pixel_data_range), + (name: 'GL_EXT_texture_rectangle'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_rectangle), + (name: 'GL_S3_s3tc'; loader: {$ifdef FPC}@{$endif}load_GL_S3_s3tc), + (name: 'GL_ATI_draw_buffers'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_draw_buffers), + {$IFDEF msWindows} + (name: 'WGL_ATI_pixel_format_float'; loader: {$ifdef FPC}@{$endif}load_WGL_ATI_pixel_format_float), + {$ENDIF} + (name: 'GL_ATI_texture_env_combine3'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_texture_env_combine3), + (name: 'GL_ATI_texture_float'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_texture_float), + (name: 'GL_NV_texture_expand_normal'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_expand_normal), + (name: 'GL_NV_half_float'; loader: {$ifdef FPC}@{$endif}load_GL_NV_half_float), + (name: 'GL_ATI_map_object_buffer'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_map_object_buffer), + (name: 'GL_ATI_separate_stencil'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_separate_stencil), + (name: 'GL_ATI_vertex_attrib_array_object'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_vertex_attrib_array_object), + (name: 'GL_ARB_vertex_buffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_buffer_object), + (name: 'GL_ARB_occlusion_query'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_occlusion_query), + (name: 'GL_ARB_shader_objects'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_shader_objects), + (name: 'GL_ARB_vertex_shader'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_shader), + (name: 'GL_ARB_fragment_shader'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_fragment_shader), + (name: 'GL_ARB_shading_language_100'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_shading_language_100), + (name: 'GL_ARB_texture_non_power_of_two'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_non_power_of_two), + (name: 'GL_ARB_point_sprite'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_point_sprite), + (name: 'GL_EXT_depth_bounds_test'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_depth_bounds_test), + (name: 'GL_EXT_texture_mirror_clamp'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_mirror_clamp), + (name: 'GL_EXT_blend_equation_separate'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_equation_separate), + (name: 'GL_MESA_pack_invert'; loader: {$ifdef FPC}@{$endif}load_GL_MESA_pack_invert), + (name: 'GL_MESA_ycbcr_texture'; loader: {$ifdef FPC}@{$endif}load_GL_MESA_ycbcr_texture), + (name: 'GL_ARB_fragment_program_shadow'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_fragment_program_shadow), + (name: 'GL_NV_fragment_program_option'; loader: {$ifdef FPC}@{$endif}load_GL_NV_fragment_program_option), + (name: 'GL_EXT_pixel_buffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_pixel_buffer_object), + (name: 'GL_NV_fragment_program2'; loader: {$ifdef FPC}@{$endif}load_GL_NV_fragment_program2), + (name: 'GL_NV_vertex_program2_option'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_program2_option), + (name: 'GL_NV_vertex_program3'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_program3), + (name: 'GL_ARB_draw_buffers'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_draw_buffers), + (name: 'GL_ARB_texture_rectangle'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_rectangle), + (name: 'GL_ARB_color_buffer_float'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_color_buffer_float), + (name: 'GL_ARB_half_float_pixel'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_half_float_pixel), + (name: 'GL_ARB_texture_float'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_float), + (name: 'GL_EXT_texture_compression_dxt1'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_compression_dxt1), + (name: 'GL_ARB_pixel_buffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_pixel_buffer_object), + (name: 'GL_EXT_framebuffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_framebuffer_object), + (name: 'GL_ARB_framebuffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_framebuffer_object), + (name: 'GL_ARB_map_buffer_range'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_map_buffer_range), + (name: 'GL_ARB_vertex_array_object'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_array_object), + (name: 'GL_ARB_copy_buffer'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_copy_buffer), + (name: 'GL_ARB_uniform_buffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_uniform_buffer_object), + (name: 'GL_ARB_draw_elements_base_vertex'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_draw_elements_base_vertex), + (name: 'GL_ARB_provoking_vertex'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_provoking_vertex), + (name: 'GL_ARB_sync'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_sync), + (name: 'GL_ARB_texture_multisample'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_multisample), + (name: 'GL_ARB_blend_func_extended'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_blend_func_extended), + (name: 'GL_ARB_sampler_objects'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_sampler_objects), + (name: 'GL_ARB_timer_query'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_timer_query), + (name: 'GL_ARB_vertex_type_2_10_10_10_rev'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_type_2_10_10_10_rev), + (name: 'GL_ARB_gpu_shader_fp64'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_gpu_shader_fp64), + (name: 'GL_ARB_shader_subroutine'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_shader_subroutine), + (name: 'GL_ARB_tessellation_shader'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_tessellation_shader), + (name: 'GL_ARB_transform_feedback2'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_transform_feedback2), + (name: 'GL_ARB_transform_feedback3'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_transform_feedback3), + (name: 'GL_version_1_4'; loader: {$ifdef FPC}@{$endif}l_GL_version_1_4), + (name: 'GL_version_1_5'; loader: {$ifdef FPC}@{$endif}l_GL_version_1_5), + (name: 'GL_version_2_0'; loader: {$ifdef FPC}@{$endif}l_GL_version_2_0), + (name: 'GL_version_2_1'; loader: {$ifdef FPC}@{$endif}l_GL_version_2_1), + (name: 'GL_version_3_0'; loader: {$ifdef FPC}@{$endif}l_GL_version_3_0), + (name: 'GL_version_3_1'; loader: {$ifdef FPC}@{$endif}l_GL_version_3_1), + (name: 'GL_version_3_2'; loader: {$ifdef FPC}@{$endif}l_GL_version_3_2), + (name: 'GL_version_3_3'; loader: {$ifdef FPC}@{$endif}l_GL_version_3_3), + (name: 'GL_version_4_0'; loader: {$ifdef FPC}@{$endif}l_GL_version_4_0) + ); + +function mseglparseextensions(const astr: pchar): glextensionsty; +var + ar1: stringarty; + int1: integer; + str1: string; + ext1: glextensionty; +begin + result:= []; + ar1:= splitstring(astr,' '); + for int1:= 0 to high(ar1) do begin + for ext1:= low(ext1) to high(ext1) do begin + pointer(str1):= pointer(ar1[int1]); //no refcount + if glextensions[ext1].name = str1 then begin + include(result,ext1); + break; + end; + end; + end; +end; + +function mseglloadextensions(const extensions: array of glextensionty): boolean; +var + int1: integer; + ext: glextensionty; +begin + result:= true; + for int1:= 0 to high(extensions) do begin + ext:= extensions[int1]; + if ext in badextensions then begin + result:= false; + end + else begin + if not (ext in loadedextensions) then begin + if glextensions[ext].loader() then begin + include(loadedextensions,ext); + end + else begin + include(badextensions,ext); + result:= false; + end; + end; + end; + end; +end; + +procedure init(); +begin + regglinit(@initglext); + reggldeinit(@deinitglext); +end; + +initialization +// regglinit(@initglext); //msegl not yet initialized +// reggldeinit(@deinitglext); +end. \ No newline at end of file diff --git a/mseide-msegui/lib/common/opengl/mseglu.pas b/mseide-msegui/lib/common/opengl/mseglu.pas new file mode 100644 index 0000000..9e08c5b --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseglu.pas @@ -0,0 +1,487 @@ +{ + + Adaption of the delphi3d.net OpenGL units to FreePascal + Sebastian Guenther (sg@freepascal.org) in 2002 + These units are free to use +} +// +// modified 2011 by Martin Schreiber +// +{*++ BUILD Version: 0004 // Increment this if a change has global effects + +Copyright (c) 1985-95, Microsoft Corporation + +Module Name: + + glu.h + +Abstract: + + Procedure declarations, constant definitions and macros for the OpenGL + Utility Library. + +--*} + +{* +** Copyright 1991-1993, Silicon Graphics, Inc. +** All Rights Reserved. +** +** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.; +** the contents of this file may not be disclosed to third parties, copied or +** duplicated in any form, in whole or in part, without the prior written +** permission of Silicon Graphics, Inc. +** +** RESTRICTED RIGHTS LEGEND: +** Use, duplication or disclosure by the Government is subject to restrictions +** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data +** and Computer Software clause at DFARS 252.227-7013, and/or in similar or +** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - +** rights reserved under the Copyright Laws of the United States. +*} + +{* +** Return the error string associated with a particular error code. +** This will return 0 for an invalid error code. +** +** The generic function prototype that can be compiled for ANSI or Unicode +** is defined as follows: +** +** LPCTSTR APIENTRY gluErrorStringWIN (GLenum errCode); +*} + +{******************************************************************************} +{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) } +{ For the latest updates, visit Delphi3D: http://www.delphi3d.net } +{******************************************************************************} + +{$ifdef FPC}{$mode objfpc} {$h+}{$MACRO ON}{$endif} +//{$MODE Delphi} +{$IFDEF msWindows} + {$define wincall} +// {$DEFINE extdecl := stdcall} +{$ELSE} +// {$DEFINE extdecl := cdecl} +{$ENDIF} + +{$IFDEF MORPHOS} +{$INLINE ON} +{$DEFINE GLU_UNIT} +{$ENDIF} + +unit mseglu; + +interface + +uses + SysUtils, + {$IFDEF msWindows} + Windows, + {$ELSE} + {$IFDEF MORPHOS} + TinyGL, + {$ENDIF} + {$ENDIF} + msegl,msetypes{,msestrings}; + +const +{$ifdef mswindows} + glulib: array[0..0] of filenamety = ('glu32.dll'); +{$else} + glulib: array[0..1] of filenamety = ('libGLU.so.1','libGLU.so.'); +{$endif} + +type + TViewPortArray = array [0..3] of GLint; + T16dArray = array [0..15] of GLdouble; + TCallBack = procedure; + T3dArray = array [0..2] of GLdouble; + p3darray = ^t3darray; + T4pArray = array [0..3] of Pointer; + T4fArray = array [0..3] of GLfloat; + PPointer = ^Pointer; + +type + GLUnurbs = record end; PGLUnurbs = ^GLUnurbs; + GLUquadric = record end; PGLUquadric = ^GLUquadric; + GLUtesselator = record end; PGLUtesselator = ^GLUtesselator; + + // backwards compatibility: + GLUnurbsObj = GLUnurbs; PGLUnurbsObj = PGLUnurbs; + GLUquadricObj = GLUquadric; PGLUquadricObj = PGLUquadric; + GLUtesselatorObj = GLUtesselator; PGLUtesselatorObj = PGLUtesselator; + GLUtriangulatorObj = GLUtesselator; PGLUtriangulatorObj = PGLUtesselator; + + TGLUnurbs = GLUnurbs; + TGLUquadric = GLUquadric; + TGLUtesselator = GLUtesselator; + + TGLUnurbsObj = GLUnurbsObj; + TGLUquadricObj = GLUquadricObj; + TGLUtesselatorObj = GLUtesselatorObj; + TGLUtriangulatorObj = GLUtriangulatorObj; + +{$IFDEF MORPHOS} + +{ MorphOS GL works differently due to different dynamic-library handling on Amiga-like } +{ systems, so its headers are included here. } +{$INCLUDE tinyglh.inc} + +{$ELSE MORPHOS} +var + gluErrorString: function(errCode: GLenum): PChar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluErrorUnicodeStringEXT: function(errCode: GLenum): PWideChar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + //not on linux + gluGetString: function(name: GLenum): PChar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluOrtho2D: procedure(left,right, bottom, top: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluPerspective: procedure(fovy, aspect, zNear, zFar: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluPickMatrix: procedure(x, y, width, height: GLdouble; var viewport: TViewPortArray); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluLookAt: procedure(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluProject: function(objx, objy, objz: GLdouble; var modelMatrix, projMatrix: T16dArray; var viewport: TViewPortArray; winx, winy, winz: PGLdouble): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluUnProject: function(winx, winy, winz: GLdouble; var modelMatrix, projMatrix: T16dArray; var viewport: TViewPortArray; objx, objy, objz: PGLdouble): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluScaleImage: function(format: GLenum; widthin, heightin: GLint; typein: GLenum; const datain: Pointer; widthout, heightout: GLint; typeout: GLenum; dataout: Pointer): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluBuild1DMipmaps: function(target: GLenum; components, width: GLint; format, atype: GLenum; const data: Pointer): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluBuild2DMipmaps: function(target: GLenum; components, width, height: GLint; format, atype: GLenum; const data: Pointer): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +var + gluNewQuadric: function: PGLUquadric; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluDeleteQuadric: procedure(state: PGLUquadric); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluQuadricNormals: procedure(quadObject: PGLUquadric; normals: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluQuadricTexture: procedure(quadObject: PGLUquadric; textureCoords: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluQuadricOrientation: procedure(quadObject: PGLUquadric; orientation: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluQuadricDrawStyle: procedure(quadObject: PGLUquadric; drawStyle: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluCylinder: procedure(qobj: PGLUquadric; baseRadius, topRadius, height: GLdouble; slices, stacks: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluDisk: procedure(qobj: PGLUquadric; innerRadius, outerRadius: GLdouble; slices, loops: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluPartialDisk: procedure(qobj: PGLUquadric; innerRadius, outerRadius: GLdouble; slices, loops: GLint; startAngle, sweepAngle: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluSphere: procedure(qobj: PGLuquadric; radius: GLdouble; slices, stacks: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluQuadricCallback: procedure(qobj: PGLUquadric; which: GLenum; fn: TCallBack); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNewTess: function: PGLUtesselator; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluDeleteTess: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessBeginPolygon: procedure(tess: PGLUtesselator; polygon_data: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessBeginContour: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessVertex: procedure(tess: PGLUtesselator; var coords: T3dArray; data: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessEndContour: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessEndPolygon: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessProperty: procedure(tess: PGLUtesselator; which: GLenum; value: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessNormal: procedure(tess: PGLUtesselator; x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessCallback: procedure(tess: PGLUtesselator; which: GLenum;fn: TCallBack); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluGetTessProperty: procedure(tess: PGLUtesselator; which: GLenum; value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNewNurbsRenderer: function: PGLUnurbs; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluDeleteNurbsRenderer: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluBeginSurface: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluBeginCurve: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluEndCurve: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluEndSurface: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluBeginTrim: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluEndTrim: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluPwlCurve: procedure(nobj: PGLUnurbs; count: GLint; aarray: PGLfloat; stride: GLint; atype: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNurbsCurve: procedure(nobj: PGLUnurbs; nknots: GLint; knot: PGLfloat; stride: GLint; ctlarray: PGLfloat; order: GLint; atype: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNurbsSurface: procedure(nobj: PGLUnurbs; sknot_count: GLint; sknot: PGLfloat; tknot_count: GLint; tknot: PGLfloat; s_stride, t_stride: GLint; ctlarray: PGLfloat; sorder, torder: GLint; atype: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluLoadSamplingMatrices: procedure(nobj: PGLUnurbs; var modelMatrix, projMatrix: T16dArray; var viewport: TViewPortArray); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNurbsProperty: procedure(nobj: PGLUnurbs; aproperty: GLenum; value: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluGetNurbsProperty: procedure(nobj: PGLUnurbs; aproperty: GLenum; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNurbsCallback: procedure(nobj: PGLUnurbs; which: GLenum; fn: TCallBack); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ENDIF MORPHOS} + +(**** Callback function prototypes ****) + +type + // gluQuadricCallback + GLUquadricErrorProc = procedure(p: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + // gluTessCallback + GLUtessBeginProc = procedure(p: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessEdgeFlagProc = procedure(p: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessVertexProc = procedure(p: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessEndProc = procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessErrorProc = procedure(p: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessCombineProc = procedure(var p1: T3dArray; p2: T4pArray; p3: T4fArray; p4: PPointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessBeginDataProc = procedure(p1: GLenum; p2: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessEdgeFlagDataProc = procedure(p1: GLboolean; p2: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessVertexDataProc = procedure(p1, p2: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessEndDataProc = procedure(p: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessErrorDataProc = procedure(p1: GLenum; p2: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessCombineDataProc = procedure(var p1: T3dArray; var p2: T4pArray; var p3: T4fArray; + p4: PPointer; p5: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + // gluNurbsCallback + GLUnurbsErrorProc = procedure(p: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + +//*** Generic constants ****/ + +const + // Version + GLU_VERSION_1_1 = 1; + GLU_VERSION_1_2 = 1; + + // Errors: (return value 0 = no error) + GLU_INVALID_ENUM = 100900; + GLU_INVALID_VALUE = 100901; + GLU_OUT_OF_MEMORY = 100902; + GLU_INCOMPATIBLE_GL_VERSION = 100903; + + // StringName + GLU_VERSION = 100800; + GLU_EXTENSIONS = 100801; + + // Boolean + GLU_TRUE = GL_TRUE; + GLU_FALSE = GL_FALSE; + + + //*** Quadric constants ****/ + + // QuadricNormal + GLU_SMOOTH = 100000; + GLU_FLAT = 100001; + GLU_NONE = 100002; + + // QuadricDrawStyle + GLU_POINT = 100010; + GLU_LINE = 100011; + GLU_FILL = 100012; + GLU_SILHOUETTE = 100013; + + // QuadricOrientation + GLU_OUTSIDE = 100020; + GLU_INSIDE = 100021; + + // Callback types: + // GLU_ERROR = 100103; + + + //*** Tesselation constants ****/ + + GLU_TESS_MAX_COORD = 1.0e150; + + // TessProperty + GLU_TESS_WINDING_RULE = 100140; + GLU_TESS_BOUNDARY_ONLY = 100141; + GLU_TESS_TOLERANCE = 100142; + + // TessWinding + GLU_TESS_WINDING_ODD = 100130; + GLU_TESS_WINDING_NONZERO = 100131; + GLU_TESS_WINDING_POSITIVE = 100132; + GLU_TESS_WINDING_NEGATIVE = 100133; + GLU_TESS_WINDING_ABS_GEQ_TWO = 100134; + + // TessCallback + GLU_TESS_BEGIN = 100100; // void (CALLBACK*)(GLenum type) + GLU_TESS_VERTEX = 100101; // void (CALLBACK*)(void *data) + GLU_TESS_END = 100102; // void (CALLBACK*)(void) + GLU_TESS_ERROR = 100103; // void (CALLBACK*)(GLenum errno) + GLU_TESS_EDGE_FLAG = 100104; // void (CALLBACK*)(GLboolean boundaryEdge) + GLU_TESS_COMBINE = 100105; { void (CALLBACK*)(GLdouble coords[3], + void *data[4], + GLfloat weight[4], + void **dataOut) } + GLU_TESS_BEGIN_DATA = 100106; { void (CALLBACK*)(GLenum type, + void *polygon_data) } + GLU_TESS_VERTEX_DATA = 100107; { void (CALLBACK*)(void *data, + void *polygon_data) } + GLU_TESS_END_DATA = 100108; // void (CALLBACK*)(void *polygon_data) + GLU_TESS_ERROR_DATA = 100109; { void (CALLBACK*)(GLenum errno, + void *polygon_data) } + GLU_TESS_EDGE_FLAG_DATA = 100110; { void (CALLBACK*)(GLboolean boundaryEdge, + void *polygon_data) } + GLU_TESS_COMBINE_DATA = 100111; { void (CALLBACK*)(GLdouble coords[3], + void *data[4], + GLfloat weight[4], + void **dataOut, + void *polygon_data) } + + // TessError + GLU_TESS_ERROR1 = 100151; + GLU_TESS_ERROR2 = 100152; + GLU_TESS_ERROR3 = 100153; + GLU_TESS_ERROR4 = 100154; + GLU_TESS_ERROR5 = 100155; + GLU_TESS_ERROR6 = 100156; + GLU_TESS_ERROR7 = 100157; + GLU_TESS_ERROR8 = 100158; + + GLU_TESS_MISSING_BEGIN_POLYGON = GLU_TESS_ERROR1; + GLU_TESS_MISSING_BEGIN_CONTOUR = GLU_TESS_ERROR2; + GLU_TESS_MISSING_END_POLYGON = GLU_TESS_ERROR3; + GLU_TESS_MISSING_END_CONTOUR = GLU_TESS_ERROR4; + GLU_TESS_COORD_TOO_LARGE = GLU_TESS_ERROR5; + GLU_TESS_NEED_COMBINE_CALLBACK = GLU_TESS_ERROR6; + + //*** NURBS constants ****/ + + // NurbsProperty + GLU_AUTO_LOAD_MATRIX = 100200; + GLU_CULLING = 100201; + GLU_SAMPLING_TOLERANCE = 100203; + GLU_DISPLAY_MODE = 100204; + GLU_PARAMETRIC_TOLERANCE = 100202; + GLU_SAMPLING_METHOD = 100205; + GLU_U_STEP = 100206; + GLU_V_STEP = 100207; + + // NurbsSampling + GLU_PATH_LENGTH = 100215; + GLU_PARAMETRIC_ERROR = 100216; + GLU_DOMAIN_DISTANCE = 100217; + + + // NurbsTrim + GLU_MAP1_TRIM_2 = 100210; + GLU_MAP1_TRIM_3 = 100211; + + // NurbsDisplay + // GLU_FILL = 100012; + GLU_OUTLINE_POLYGON = 100240; + GLU_OUTLINE_PATCH = 100241; + + // NurbsCallback + // GLU_ERROR = 100103; + + // NurbsErrors + GLU_NURBS_ERROR1 = 100251; + GLU_NURBS_ERROR2 = 100252; + GLU_NURBS_ERROR3 = 100253; + GLU_NURBS_ERROR4 = 100254; + GLU_NURBS_ERROR5 = 100255; + GLU_NURBS_ERROR6 = 100256; + GLU_NURBS_ERROR7 = 100257; + GLU_NURBS_ERROR8 = 100258; + GLU_NURBS_ERROR9 = 100259; + GLU_NURBS_ERROR10 = 100260; + GLU_NURBS_ERROR11 = 100261; + GLU_NURBS_ERROR12 = 100262; + GLU_NURBS_ERROR13 = 100263; + GLU_NURBS_ERROR14 = 100264; + GLU_NURBS_ERROR15 = 100265; + GLU_NURBS_ERROR16 = 100266; + GLU_NURBS_ERROR17 = 100267; + GLU_NURBS_ERROR18 = 100268; + GLU_NURBS_ERROR19 = 100269; + GLU_NURBS_ERROR20 = 100270; + GLU_NURBS_ERROR21 = 100271; + GLU_NURBS_ERROR22 = 100272; + GLU_NURBS_ERROR23 = 100273; + GLU_NURBS_ERROR24 = 100274; + GLU_NURBS_ERROR25 = 100275; + GLU_NURBS_ERROR26 = 100276; + GLU_NURBS_ERROR27 = 100277; + GLU_NURBS_ERROR28 = 100278; + GLU_NURBS_ERROR29 = 100279; + GLU_NURBS_ERROR30 = 100280; + GLU_NURBS_ERROR31 = 100281; + GLU_NURBS_ERROR32 = 100282; + GLU_NURBS_ERROR33 = 100283; + GLU_NURBS_ERROR34 = 100284; + GLU_NURBS_ERROR35 = 100285; + GLU_NURBS_ERROR36 = 100286; + GLU_NURBS_ERROR37 = 100287; + +//*** Backwards compatibility for old tesselator ****/ + +var + gluBeginPolygon: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNextContour: procedure(tess: PGLUtesselator; atype: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluEndPolygon: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +const + // Contours types -- obsolete! + GLU_CW = 100120; + GLU_CCW = 100121; + GLU_INTERIOR = 100122; + GLU_EXTERIOR = 100123; + GLU_UNKNOWN = 100124; + + // Names without "TESS_" prefix + GLU_BEGIN = GLU_TESS_BEGIN; + GLU_VERTEX = GLU_TESS_VERTEX; + GLU_END = GLU_TESS_END; + GLU_ERROR = GLU_TESS_ERROR; + GLU_EDGE_FLAG = GLU_TESS_EDGE_FLAG; + +//procedure LoadGLu(const dll: String); +//procedure FreeGLu; + +procedure initializeglu(const sonames: array of filenamety); //[] = default +procedure releaseglu; + +implementation +uses + msedynload,msesys; +var + libinfo: dynlibinfoty; + +procedure initializeglu(const sonames: array of filenamety); //[] = default +const + funcs: array[0..50] of funcinfoty = ( + (n: 'gluErrorString'; d: {$ifndef FPC}@{$endif}@gluErrorString), + (n: 'gluGetString'; d: {$ifndef FPC}@{$endif}@gluGetString), + (n: 'gluOrtho2D'; d: {$ifndef FPC}@{$endif}@gluOrtho2D), + (n: 'gluPerspective'; d: {$ifndef FPC}@{$endif}@gluPerspective), + (n: 'gluPickMatrix'; d: {$ifndef FPC}@{$endif}@gluPickMatrix), + (n: 'gluLookAt'; d: {$ifndef FPC}@{$endif}@gluLookAt), + (n: 'gluProject'; d: {$ifndef FPC}@{$endif}@gluProject), + (n: 'gluUnProject'; d: {$ifndef FPC}@{$endif}@gluUnProject), + (n: 'gluScaleImage'; d: {$ifndef FPC}@{$endif}@gluScaleImage), + (n: 'gluBuild1DMipmaps'; d: {$ifndef FPC}@{$endif}@gluBuild1DMipmaps), + (n: 'gluBuild2DMipmaps'; d: {$ifndef FPC}@{$endif}@gluBuild2DMipmaps), + (n: 'gluNewQuadric'; d: {$ifndef FPC}@{$endif}@gluNewQuadric), + (n: 'gluDeleteQuadric'; d: {$ifndef FPC}@{$endif}@gluDeleteQuadric), + (n: 'gluQuadricNormals'; d: {$ifndef FPC}@{$endif}@gluQuadricNormals), + (n: 'gluQuadricTexture'; d: {$ifndef FPC}@{$endif}@gluQuadricTexture), + (n: 'gluQuadricOrientation'; d: {$ifndef FPC}@{$endif}@gluQuadricOrientation), + (n: 'gluQuadricDrawStyle'; d: {$ifndef FPC}@{$endif}@gluQuadricDrawStyle), + (n: 'gluCylinder'; d: {$ifndef FPC}@{$endif}@gluCylinder), + (n: 'gluDisk'; d: {$ifndef FPC}@{$endif}@gluDisk), + (n: 'gluPartialDisk'; d: {$ifndef FPC}@{$endif}@gluPartialDisk), + (n: 'gluSphere'; d: {$ifndef FPC}@{$endif}@gluSphere), + (n: 'gluQuadricCallback'; d: {$ifndef FPC}@{$endif}@gluQuadricCallback), + (n: 'gluNewTess'; d: {$ifndef FPC}@{$endif}@gluNewTess), + (n: 'gluDeleteTess'; d: {$ifndef FPC}@{$endif}@gluDeleteTess), + (n: 'gluTessBeginPolygon'; d: {$ifndef FPC}@{$endif}@gluTessBeginPolygon), + (n: 'gluTessBeginContour'; d: {$ifndef FPC}@{$endif}@gluTessBeginContour), + (n: 'gluTessVertex'; d: {$ifndef FPC}@{$endif}@gluTessVertex), + (n: 'gluTessEndContour'; d: {$ifndef FPC}@{$endif}@gluTessEndContour), + (n: 'gluTessEndPolygon'; d: {$ifndef FPC}@{$endif}@gluTessEndPolygon), + (n: 'gluTessProperty'; d: {$ifndef FPC}@{$endif}@gluTessProperty), + (n: 'gluTessNormal'; d: {$ifndef FPC}@{$endif}@gluTessNormal), + (n: 'gluTessCallback'; d: {$ifndef FPC}@{$endif}@gluTessCallback), + (n: 'gluGetTessProperty'; d: {$ifndef FPC}@{$endif}@gluGetTessProperty), + (n: 'gluNewNurbsRenderer'; d: {$ifndef FPC}@{$endif}@gluNewNurbsRenderer), + (n: 'gluDeleteNurbsRenderer'; d: {$ifndef FPC}@{$endif}@gluDeleteNurbsRenderer), + (n: 'gluBeginSurface'; d: {$ifndef FPC}@{$endif}@gluBeginSurface), + (n: 'gluBeginCurve'; d: {$ifndef FPC}@{$endif}@gluBeginCurve), + (n: 'gluEndCurve'; d: {$ifndef FPC}@{$endif}@gluEndCurve), + (n: 'gluEndSurface'; d: {$ifndef FPC}@{$endif}@gluEndSurface), + (n: 'gluBeginTrim'; d: {$ifndef FPC}@{$endif}@gluBeginTrim), + (n: 'gluEndTrim'; d: {$ifndef FPC}@{$endif}@gluEndTrim), + (n: 'gluPwlCurve'; d: {$ifndef FPC}@{$endif}@gluPwlCurve), + (n: 'gluNurbsCurve'; d: {$ifndef FPC}@{$endif}@gluNurbsCurve), + (n: 'gluNurbsSurface'; d: {$ifndef FPC}@{$endif}@gluNurbsSurface), + (n: 'gluLoadSamplingMatrices'; d: {$ifndef FPC}@{$endif}@gluLoadSamplingMatrices), + (n: 'gluNurbsProperty'; d: {$ifndef FPC}@{$endif}@gluNurbsProperty), + (n: 'gluGetNurbsProperty'; d: {$ifndef FPC}@{$endif}@gluGetNurbsProperty), + (n: 'gluNurbsCallback'; d: {$ifndef FPC}@{$endif}@gluNurbsCallback), + (n: 'gluBeginPolygon'; d: {$ifndef FPC}@{$endif}@gluBeginPolygon), + (n: 'gluNextContour'; d: {$ifndef FPC}@{$endif}@gluNextContour), + (n: 'gluEndPolygon'; d: {$ifndef FPC}@{$endif}@gluEndPolygon) + ); + funcsopt: array[0..0] of funcinfoty = ( + (n: 'gluErrorUnicodeStringEXT'; d: {$ifndef FPC}@{$endif}@gluErrorUnicodeStringEXT) + ); + errormessage = 'Can not load glu library'; +begin + initializedynlib(libinfo,sonames,glulib,funcs,funcsopt,errormessage); +end; + +procedure releaseglu; +begin + releasedynlib(libinfo,nil,true); +//used in xclosedisplay? +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/opengl/mseglx.pas b/mseide-msegui/lib/common/opengl/mseglx.pas new file mode 100644 index 0000000..e496ea9 --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseglx.pas @@ -0,0 +1,225 @@ +{ + + Translation of the Mesa GLX headers for FreePascal + Copyright (C) 1999 Sebastian Guenther + + + Mesa 3-D graphics library + Version: 3.0 + Copyright (C) 1995-1998 Brian Paul + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +// +// modified 2011 by Martin Schreiber +// +//{$MODE delphi} // objfpc would not work because of direct proc var assignments + +{You have to enable Macros (compiler switch "-Sm") for compiling this unit! + This is necessary for supporting different platforms with different calling + conventions via a single unit.} + +{$ifdef FPC}{$mode objfpc} {$h+}{$endif} + +unit mseglx; + +interface +{$ifdef linux}{$define unix}{$endif} +{$IFDEF Unix} + uses + {$ifdef FPC}X,{$endif} XLib,{$ifdef FPC} XUtil,{$endif}mseglextglob; + {$DEFINE HasGLX} // Activate GLX stuff +{$ELSE} + {$MESSAGE Unsupported platform.} +{$ENDIF} + +{$IFNDEF HasGLX} + {$MESSAGE GLX not present on this platform.} +{$ENDIF} + + +//*) +// ======================================================= +// GLX consts, types and functions +// ======================================================= + +// Tokens for glXChooseVisual and glXGetConfig: +const + GLX_USE_GL = 1; + GLX_BUFFER_SIZE = 2; + GLX_LEVEL = 3; + GLX_RGBA = 4; + GLX_DOUBLEBUFFER = 5; + GLX_STEREO = 6; + GLX_AUX_BUFFERS = 7; + GLX_RED_SIZE = 8; + GLX_GREEN_SIZE = 9; + GLX_BLUE_SIZE = 10; + GLX_ALPHA_SIZE = 11; + GLX_DEPTH_SIZE = 12; + GLX_STENCIL_SIZE = 13; + GLX_ACCUM_RED_SIZE = 14; + GLX_ACCUM_GREEN_SIZE = 15; + GLX_ACCUM_BLUE_SIZE = 16; + GLX_ACCUM_ALPHA_SIZE = 17; + + // GLX_EXT_visual_info extension + GLX_X_VISUAL_TYPE_EXT = $22; + GLX_TRANSPARENT_TYPE_EXT = $23; + GLX_TRANSPARENT_INDEX_VALUE_EXT = $24; + GLX_TRANSPARENT_RED_VALUE_EXT = $25; + GLX_TRANSPARENT_GREEN_VALUE_EXT = $26; + GLX_TRANSPARENT_BLUE_VALUE_EXT = $27; + GLX_TRANSPARENT_ALPHA_VALUE_EXT = $28; + + + // Error codes returned by glXGetConfig: + GLX_BAD_SCREEN = 1; + GLX_BAD_ATTRIBUTE = 2; + GLX_NO_EXTENSION = 3; + GLX_BAD_VISUAL = 4; + GLX_BAD_CONTEXT = 5; + GLX_BAD_VALUE = 6; + GLX_BAD_ENUM = 7; + + // GLX 1.1 and later: + GLX_VENDOR = 1; + GLX_VERSION = 2; + GLX_EXTENSIONS = 3; + + // GLX_visual_info extension + GLX_TRUE_COLOR_EXT = $8002; + GLX_DIRECT_COLOR_EXT = $8003; + GLX_PSEUDO_COLOR_EXT = $8004; + GLX_STATIC_COLOR_EXT = $8005; + GLX_GRAY_SCALE_EXT = $8006; + GLX_STATIC_GRAY_EXT = $8007; + GLX_NONE_EXT = $8000; + GLX_TRANSPARENT_RGB_EXT = $8008; + GLX_TRANSPARENT_INDEX_EXT = $8009; + +type +{$ifndef FPC} + txid = xid; +{$endif} + // From XLib: + XPixmap = TXID; + XFont = TXID; + XColormap = TXID; + + GLXContext = Pointer; + GLXPixmap = TXID; + GLXDrawable = TXID; + GLXContextID = TXID; + + TXPixmap = XPixmap; + TXFont = XFont; + TXColormap = XColormap; + + TGLXContext = GLXContext; + TGLXPixmap = GLXPixmap; + TGLXDrawable = GLXDrawable; + TGLXContextID = GLXContextID; + +var + glXChooseVisual: function(dpy: PDisplay; screen: Integer; attribList: PInteger): PXVisualInfo; cdecl; + glXCreateContext: function(dpy: PDisplay; vis: PXVisualInfo; shareList: GLXContext; direct: Boolean): GLXContext; cdecl; + glXDestroyContext: procedure(dpy: PDisplay; ctx: GLXContext); cdecl; + glXMakeCurrent: function(dpy: PDisplay; drawable: GLXDrawable; ctx: GLXContext): Boolean; cdecl; + glXCopyContext: procedure(dpy: PDisplay; src, dst: GLXContext; mask: LongWord); cdecl; + glXSwapBuffers: procedure(dpy: PDisplay; drawable: GLXDrawable); cdecl; + glXCreateGLXPixmap: function(dpy: PDisplay; visual: PXVisualInfo; pixmap: XPixmap): GLXPixmap; cdecl; + glXDestroyGLXPixmap: procedure(dpy: PDisplay; pixmap: GLXPixmap); cdecl; + glXQueryExtension: function(dpy: PDisplay; var errorb, event: Integer): Boolean; cdecl; + glXQueryVersion: function(dpy: PDisplay; var maj, min: Integer): Boolean; cdecl; + glXIsDirect: function(dpy: PDisplay; ctx: GLXContext): Boolean; cdecl; + glXGetConfig: function(dpy: PDisplay; visual: PXVisualInfo; attrib: Integer; var value: Integer): Integer; cdecl; + glXGetCurrentContext: function: GLXContext; cdecl; + glXGetCurrentDrawable: function: GLXDrawable; cdecl; + glXWaitGL: procedure; cdecl; + glXWaitX: procedure; cdecl; + glXUseXFont: procedure(font: XFont; first, count, list: Integer); cdecl; + + // GLX 1.1 and later + glXQueryExtensionsString: function(dpy: PDisplay; screen: Integer): PChar; cdecl; + glXQueryServerString: function(dpy: PDisplay; screen, name: Integer): PChar; cdecl; + glXGetClientString: function(dpy: PDisplay; name: Integer): PChar; cdecl; + + // Mesa GLX Extensions + glXCreateGLXPixmapMESA: function(dpy: PDisplay; visual: PXVisualInfo; pixmap: XPixmap; cmap: XColormap): GLXPixmap; cdecl; + glXReleaseBufferMESA: function(dpy: PDisplay; d: GLXDrawable): Boolean; cdecl; + glXCopySubBufferMESA: procedure(dpy: PDisplay; drawbale: GLXDrawable; x, y, width, height: Integer); cdecl; + glXGetVideoSyncSGI: function(var counter: LongWord): Integer; cdecl; + glXWaitVideoSyncSGI: function(divisor, remainder: Integer; var count: LongWord): Integer; cdecl; + + +// ======================================================= +// +// ======================================================= + +function load_glx: boolean; +function load_glx_mesa: boolean; + +implementation +{$ifdef FPC}{$LINKLIB m}{$endif} + +uses + msegl,msedynload,msesys{$ifdef FPC},dynlibs{$endif}; + +function load_glx: boolean; +const + funcs: array[0..19] of funcinfoty = + ( + (n: 'glXChooseVisual'; d: {$ifndef FPC}@{$endif}@glXChooseVisual), + (n: 'glXCreateContext'; d: {$ifndef FPC}@{$endif}@glXCreateContext), + (n: 'glXDestroyContext'; d: {$ifndef FPC}@{$endif}@glXDestroyContext), + (n: 'glXMakeCurrent'; d: {$ifndef FPC}@{$endif}@glXMakeCurrent), + (n: 'glXCopyContext'; d: {$ifndef FPC}@{$endif}@glXCopyContext), + (n: 'glXSwapBuffers'; d: {$ifndef FPC}@{$endif}@glXSwapBuffers), + (n: 'glXCreateGLXPixmap'; d: {$ifndef FPC}@{$endif}@glXCreateGLXPixmap), + (n: 'glXDestroyGLXPixmap'; d: {$ifndef FPC}@{$endif}@glXDestroyGLXPixmap), + (n: 'glXQueryExtension'; d: {$ifndef FPC}@{$endif}@glXQueryExtension), + (n: 'glXQueryVersion'; d: {$ifndef FPC}@{$endif}@glXQueryVersion), + (n: 'glXIsDirect'; d: {$ifndef FPC}@{$endif}@glXIsDirect), + (n: 'glXGetConfig'; d: {$ifndef FPC}@{$endif}@glXGetConfig), + (n: 'glXGetCurrentContext'; d: {$ifndef FPC}@{$endif}@glXGetCurrentContext), + (n: 'glXGetCurrentDrawable'; d: {$ifndef FPC}@{$endif}@glXGetCurrentDrawable), + (n: 'glXWaitGL'; d: {$ifndef FPC}@{$endif}@glXWaitGL), + (n: 'glXWaitX'; d: {$ifndef FPC}@{$endif}@glXWaitX), + (n: 'glXUseXFont'; d: {$ifndef FPC}@{$endif}@glXUseXFont), + // GLX 1.1 and later + (n: 'glXQueryExtensionsString'; d: {$ifndef FPC}@{$endif}@glXQueryExtensionsString), + (n: 'glXQueryServerString'; d: {$ifndef FPC}@{$endif}@glXQueryServerString), + (n: 'glXGetClientString'; d: {$ifndef FPC}@{$endif}@glXGetClientString) + ); +begin + result:= getprocaddresses(libgl,funcs,true); +end; + +function load_glx_mesa: boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glXCreateGLXPixmapMESA'; d: {$ifndef FPC}@{$endif}@glXCreateGLXPixmapMESA), + (n: 'glXReleaseBufferMESA'; d: {$ifndef FPC}@{$endif}@glXReleaseBufferMESA), + (n: 'glXCopySubBufferMESA'; d: {$ifndef FPC}@{$endif}@glXCopySubBufferMESA), + (n: 'glXGetVideoSyncSGI'; d: {$ifndef FPC}@{$endif}@glXGetVideoSyncSGI), + (n: 'glXWaitVideoSyncSGI'; d: {$ifndef FPC}@{$endif}@glXWaitVideoSyncSGI) + ); +begin + result:= getprocaddresses(libgl,funcs,true); +end; + +end. diff --git a/mseide-msegui/lib/common/opengl/mseopengl.pas b/mseide-msegui/lib/common/opengl/mseopengl.pas new file mode 100644 index 0000000..a85e32b --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseopengl.pas @@ -0,0 +1,255 @@ +{ MSEgui Copyright (c) 2007-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopengl; +// +// under construction +// +{$ifdef FPC}{$mode objfpc}{$h+}{$INTERFACES CORBA}{$endif} + +interface +uses + msegl,{$ifdef unix}mseglx,x,xlib,xutil,{$else}windows,{$endif} + msegraphics,msetypes,mseguiglob,msegraphutils,mseopenglgdi; + +type + topenglcanvas = class(tcanvas) + private + fviewport: rectty; + procedure setviewport(const avalue: rectty); + protected + fcontextinfo: contextinfoty; + function lock: boolean; override; + function getcontextinfopo: pointer; override; + procedure updatesize(const asize: sizety); override; +// procedure linktopaintdevice(apaintdevice: paintdevicety; const gc: gcty; +// {const size: sizety;} const cliporigin: pointty); override; + public + constructor create(const user: tobject; const intf: icanvas); override; + destructor destroy; override; + class function getclassgdifuncs: pgdifunctionaty; override; + + procedure updatewindowoptions(var aoptions: internalwindowoptionsty); override; + procedure init(const acolor: colorty = cl_none); //cl_none -> colorbackground + procedure swapbuffers; + property viewport: rectty read fviewport write setviewport; + end; + + topenglbitmapcanvas = class(topenglcanvas) + end; + + topenglwindowcanvas = class(topenglcanvas) + public + procedure linktopaintdevice(apaintdevice: paintdevicety; const gc: gcty; + {const size: sizety;} const cliporigin: pointty); override; + end; + +implementation +uses + mseguiintf; +type + tsimplebitmap1 = class(tsimplebitmap); + +const + defaultcontextattributes: contextattributesty = + (buffersize: -1; + level: 0; + doublebuffer: false; + rgba: true; + stereo: false; + auxbuffers: -1; + redsize: 8; + greensize: 8; + bluesize: 8; + alphasize: -1; + depthsize: -1; + stencilsize: 2; + accumredsize: -1; + accumgreensize: -1; + accumbluesize: -1; + accumalphasize: -1 + ); + defaultmonocontextattributes: contextattributesty = + (buffersize: -1; + level: 0; + doublebuffer: false; + rgba: true; + stereo: false; + auxbuffers: -1; + redsize: 8; + greensize: 8; + bluesize: 8; + alphasize: -1; + depthsize: -1; + stencilsize: 2; + accumredsize: -1; + accumgreensize: -1; + accumbluesize: -1; + accumalphasize: -1 + ); +{$ifdef unix} + defaultvisualattributes: array[0..8] of integer = + (GLX_RGBA,GLX_RED_SIZE,8,GLX_GREEN_SIZE,8,GLX_BLUE_SIZE,8, + GLX_DOUBLEBUFFER,none); +{$endif} + +{ topenglcanvas } + +constructor topenglcanvas.create(const user: tobject; const intf: icanvas); +begin + if user is tsimplebitmap then begin + with tsimplebitmap1(user) do begin + include(fstate,pms_staticcanvas); //opengl gc creation is expensive + end; + end; + initializeopengl([]); +// fgdinum:= openglgetgdinum; + fcontextinfo.attrib:= defaultcontextattributes; +{$ifdef unix} + fcontextinfo.visualattributes:= defaultvisualattributes; +{$endif} + inherited; +end; + +destructor topenglcanvas.destroy; +begin + inherited; + releaseopengl; +end; + +class function topenglcanvas.getclassgdifuncs: pgdifunctionaty; +begin + result:= openglgetgdifuncs; +end; + +procedure topenglcanvas.setviewport(const avalue: rectty); +var + bo1: boolean; +begin + fviewport:= avalue; + fdrawinfo.gc.paintdevicesize:= fviewport.size; + if fdrawinfo.gc.handle <> 0 then begin + bo1:= lock; + fdrawinfo.rect.rect:= @fviewport; + gdi_setviewport(fdrawinfo); + if bo1 then begin + unlock; + end; + end; +end; + +procedure topenglcanvas.swapbuffers; +var + bo1: boolean; +begin + bo1:= lock; + gdi_swapbuffers(fdrawinfo); + if bo1 then begin + unlock; + end; +end; + +procedure topenglcanvas.init(const acolor: colorty = cl_none); +var + bo1: boolean; +begin + bo1:= lock; + if acolor = cl_none then begin + fdrawinfo.color.color:= colorbackground; + end + else begin + fdrawinfo.color.color:= acolor; + end; + gdi_clear(fdrawinfo); + if flushgdi then begin + doflush; + end; + if bo1 then begin + unlock; + end; +end; + +function topenglcanvas.lock: boolean; +begin + result:= inherited lock; + if fdrawinfo.gc.handle = 0 then begin + checkgcstate([cs_gc]); + end; + if fdrawinfo.paintdevice <> 0 then begin + gdi_makecurrent(fdrawinfo); + end; +end; + +function topenglcanvas.getcontextinfopo: pointer; +begin + if df_canvasismonochrome in fdrawinfo.gc.drawingflags then begin + result:= @defaultmonocontextattributes; + end + else begin + result:= @fcontextinfo; + end; +end; + +procedure topenglcanvas.updatewindowoptions(var aoptions: internalwindowoptionsty); +var + gc1: gcty; +begin + inherited; + fillchar(gc1,sizeof(gc1),0); + gdi_choosevisual(gc1,fcontextinfo); +{$ifdef unix} + with x11internalwindowoptionsty(aoptions.platformdata).d, + oglgcty(gc1.platformdata).d do begin + if fvisinfo <> nil then begin + depth:= fvisinfo^.depth; + visual:= fvisinfo^.visual; + colormap:= fcolormap; + xfree(fvisinfo); + fvisinfo:= nil; + end + else begin + depth:= 0; + visual:= nil; + colormap:= 0; + end; + end; +{$endif} +end; + +procedure topenglcanvas.updatesize(const asize: sizety); +//var +// gc1: gcty; +begin + with fdrawinfo.gc do begin + oglgcty(platformdata).d.top:= asize.cy+gltopshift; + if (handle <> 0) and not sizeisequal(asize,paintdevicesize) then begin + viewport:= mr(fviewport.pos,asize); + { + fillchar(gc1,sizeof(gc1),0); + gc1.paintdevicesize:= asize; + linktopaintdevice(fdrawinfo.paintdevice,gc1,nullpoint); + creategc(fdrawinfo.paintdevice,gck_screen,fdrawinfo.gc,''); + } + end + else begin + inherited; + end; + end; +end; + +{ topenglwindowcanvas } + +procedure topenglwindowcanvas.linktopaintdevice(apaintdevice: paintdevicety; + const gc: gcty; const cliporigin: pointty); +begin + inherited; + viewport:= mr(nullpoint,gc.paintdevicesize); +end; + +end. diff --git a/mseide-msegui/lib/common/opengl/mseopenglcanvaswidget.pas b/mseide-msegui/lib/common/opengl/mseopenglcanvaswidget.pas new file mode 100644 index 0000000..da553f0 --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseopenglcanvaswidget.pas @@ -0,0 +1,254 @@ +{ MSEgui Copyright (c) 2011-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopenglcanvaswidget; +// +// under construction +// +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msewindowwidget,msegraphics,mseopengl,classes,mclasses,mseclasses, + msegraphutils, + msegui,msemenus,mseguiglob,msetypes; + +type + + topenglwidgetcanvas = class(topenglcanvas) + protected + procedure linktopaintdevice(const aparent: winidty; + const awindowrect: rectty; out aid: winidty); reintroduce; + public + constructor create(const user: tobject; const intf: icanvas); override; + published + property options; + { + property monochrome; + property color; + property colorbackground; + property rasterop; + property font; + property brush; + + property linewidth; + property linewidthmm; + + property dashes; + //last byte 0 -> opaque dash //todo: dashoffset + property capstyle; + property joinstyle; + property lineoptions; + + property ppmm; + //used for linewidth mm, value not saved/restored + } + end; + + topenglcanvaswidget = class; + openglcanvasrendereventty = procedure(const sender: topenglcanvaswidget; + const aupdaterect: rectty) of object; + + topenglcanvaswidget = class(tcustomwindowwidget,icanvas) + private + fcanvas: topenglwidgetcanvas; + fonrender: openglcanvasrendereventty; + procedure setcanvas(const avalue: topenglwidgetcanvas); + protected + procedure readstate(reader: treader); override; + procedure doclientrectchanged; override; + procedure docreatewinid(const aparent: winidty; const awidgetrect: rectty; + var aid: winidty); override; + procedure dodestroywinid; override; + function canclientpaint: boolean; override; + procedure doclientpaint(const aupdaterect: rectty); override; + procedure updateviewport(const arect: rectty); override; + //icanvas + procedure gcneeded(const sender: tcanvas); +// function getmonochrome: boolean; + function getkind: bitmapkindty; + function getsize: sizety; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property canvas: topenglwidgetcanvas read fcanvas write setcanvas; + property onrender: openglcanvasrendereventty read fonrender write fonrender; + property optionswidget; + property optionsskin; + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property color; + property cursor; + property frame; + property face; + property anchors; + property taborder; + property hint; + property popupmenu; + property onpopup; + property onshowhint; + property enabled; + property visible; + property oncreatewinid; + property ondestroywinid; +// property onclientpaint; + property onclientrectchanged; + property onwindowmouseevent; + property onwindowmousewheelevent; + property ondestroy; + end; + +implementation +uses + mseopenglgdi,msegl; + +type + topenglcanvas1 = class(topenglcanvas); + +{ topenglcanvaswidget } + +constructor topenglcanvaswidget.create(aowner: tcomponent); +begin + fcanvas:= topenglwidgetcanvas.create(self,icanvas(self)); + inherited; +end; + +destructor topenglcanvaswidget.destroy; +begin + inherited; + fcanvas.free; +end; + +procedure topenglcanvaswidget.setcanvas(const avalue: topenglwidgetcanvas); +begin + fcanvas.assign(avalue); +end; + +procedure topenglcanvaswidget.gcneeded(const sender: tcanvas); +begin + checkclientwinid; +end; +{ +function topenglcanvaswidget.getmonochrome: boolean; +begin + result:= false; +end; +} +function topenglcanvaswidget.getkind: bitmapkindty; +begin + result:= bmk_rgb; +end; + +function topenglcanvaswidget.getsize: sizety; +begin + result:= paintsize; +end; + +procedure topenglcanvaswidget.docreatewinid(const aparent: winidty; + const awidgetrect: rectty; var aid: winidty); +begin + initializeopengl([]); + fcanvas.linktopaintdevice(aparent,awidgetrect,aid); + checkwindowrect; +end; + +procedure topenglcanvaswidget.updateviewport(const arect: rectty); +begin + fcanvas.viewport:= arect; + inherited; +end; + +procedure topenglcanvaswidget.doclientrectchanged; +begin + fcanvas.updatesize(innerpaintrect.size); + inherited; +end; + +procedure topenglcanvaswidget.dodestroywinid; +begin + fcanvas.unlink; + inherited; + releaseopengl; +end; + +procedure topenglcanvaswidget.doclientpaint(const aupdaterect: rectty); +begin + if canevent(tmethod(fonrender)) then begin + fcanvas.reset; + fonrender(self,aupdaterect); + fcanvas.endpaint; + end; +end; + +function topenglcanvaswidget.canclientpaint: boolean; +begin + result:= assigned(fonrender); +end; + +procedure topenglcanvaswidget.getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); +begin + //dummy +end; + +procedure topenglcanvaswidget.readstate(reader: treader); +begin + fcanvas.beforeread; + try + inherited; + finally + fcanvas.afterread; + end; +end; + +{ topenglwidgetcanvas } + +procedure topenglwidgetcanvas.linktopaintdevice(const aparent: winidty; + const awindowrect: rectty; out aid: winidty); +var + gc1: gcty; + info: drawinfoty; +begin + fillchar(gc1,sizeof(gc1),0); + fillchar(info,sizeof(info),0); + gc1.kind:= bmk_rgb; + with info.creategc do begin + gcpo:= @gc1; + contextinfopo:= @fcontextinfo; + windowrect:= @awindowrect; + parent:= aparent; + kind:= gck_screen; + createpaintdevice:= true; + gdi_lock; + fdrawinfo.gc.gdifuncs^[gdf_creategc](info); + gdi_unlock; + aid:= paintdevice; + end; + gc1.paintdevicesize:= awindowrect.size; + inherited linktopaintdevice(paintdevicety(aid),gc1,nullpoint); +end; + +constructor topenglwidgetcanvas.create(const user: tobject; + const intf: icanvas); +begin + inherited; +// if not flushgdi then begin +// fcontextinfo.attrib.doublebuffer:= true; +// end; +end; + +end. diff --git a/mseide-msegui/lib/common/opengl/mseopenglgdi.pas b/mseide-msegui/lib/common/opengl/mseopenglgdi.pas new file mode 100644 index 0000000..8121049 --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseopenglgdi.pas @@ -0,0 +1,1977 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopenglgdi; +// +//under construction +// + +//todo: optimize pixmap and brush handling, use server side buffers + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegl,mseglext,mseglu,{$ifdef unix}mseglx,x,xlib,xutil,msectypes, + {$else}windows,{$endif} + msegraphics,msetypes,msegraphutils,mseguiglob,mseglextglob; +{ +const + GL_BGRA = GL_BGRA_EXT; +} +const + glpixelshift = -0.5; + gltopshift = -1; + +type + contextattributesty = record + buffersize: integer; + level: integer; + doublebuffer: boolean; + rgba: boolean; + stereo: boolean; + auxbuffers: integer; + redsize: integer; + greensize: integer; + bluesize: integer; + alphasize: integer; + depthsize: integer; + stencilsize: integer; + accumredsize: integer; + accumgreensize: integer; + accumbluesize: integer; + accumalphasize: integer; + end; + + contextinfoty = record +// viewport: rectty; + attrib: contextattributesty; + {$ifdef unix} + visualattributes: integerarty; + {$endif} + end; + pcontextinfoty = ^contextinfoty; + + oglgcstatety = (ogcs_hastexture,ogcs_needsblend,ogcs_hasclipreg); + oglgcstatesty = set of oglgcstatety; + oglgcdty = record + fkind: gckindty; + {$ifdef unix} + fcontext: glxcontext; + fdpy: pdisplay; + fcolormap: tcolormap; + fscreen: integer; + fvisinfo: pxvisualinfo; + {$else} + fdc: hdc; + fcontext: hglrc; + doublebuf: boolean; + {$endif} + pd: paintdevicety; + extensions: glextensionsty; + top: integer; //y 0 coord value + glfont: fontty; + tess: pglutesselator; + texture: gluint; + brushsize: sizety; + gcstate: oglgcstatesty; + glcolorforeground: rgbtriplety; + glcolorbackground: rgbtriplety; + gcrasterop: rasteropty; + gcoptions: canvasoptionsty; + gcdrawingflags: drawingflagsty; + gcbrushorigin: pointty; + end; + + {$if sizeof(oglgcdty) > sizeof(gcpty)} {$error 'buffer overflow'}{$endif} + + oglgcty = record + case integer of + 0: (d: oglgcdty;); + 1: (_bufferspace: gcpty;); + end; + poglgcty = ^oglgcty; + +{ +function createrendercontext(const aparent: winidty; const windowrect: rectty; + const ainfo: contextinfoty; + var gc: gcty; out aid: winidty): guierrorty; +} +function openglgetgdifuncs: pgdifunctionaty; +//function openglgetgdinum: integer; + +function gdi_choosevisual(var gc: gcty; + const contextinfo: contextinfoty): gdierrorty; +procedure gdi_makecurrent(var drawinfo: drawinfoty); +procedure gdi_setviewport(var drawinfo: drawinfoty); +procedure gdi_swapbuffers(var drawinfo: drawinfoty); +procedure gdi_clear(var drawinfo: drawinfoty); + +implementation +uses + mseguiintf,{mseftgl,}msegenericgdi,msestrings,msehash,sysutils, + mseformatstr,msefontcache,mseftfontcache,mseopengl,msebits; +type + tcanvas1 = class(tcanvas); + + gluvertexty = packed record + x: double; + y: double; + z: double; + end; + pgluvertexty = ^gluvertexty; + ppgluvertexty = ^pgluvertexty; +{ + ftglfontty = record + handle: pftglfont; + end; + pftglfontty = ^ftglfontty; +} +{ + cachefontty = record + end; + pcachefontty = ^cachefontty; +} +{ + fontcachehdataty = record + height: integer; + name: string; + end; +} + tglftfontcache = class(tftfontcache) + protected + procedure drawglyph(var drawinfo: drawinfoty; const pos: pointty; + const bitmap: pbitmapdataty); override; + public + procedure drawstring16(var drawinfo: drawinfoty; + const afont: fontty); override; + end; + +var + ffontcache: tglftfontcache; +// stockgc: gcty; +// gdinumber: integer; + +function checkerror: glenum; +begin + glfinish(); + result:= glgeterror(); + if result <> gl_no_error then begin + repeat + until glgeterror() = gl_no_error; + end; +end; + +function fontcache: tglftfontcache; +begin + if ffontcache = nil then begin + tglftfontcache.create(tftfontcache(ffontcache)); + end; + result:= ffontcache; +end; + +type + glcolorty = record + r,g,b,a: glclampf; + end; + +procedure putboolean(var ar1: integerarty; var index: integer; + const atag: integer; const avalue: boolean); +begin + if avalue then begin + if index > high(ar1) then begin + setlength(ar1,19+high(ar1)*2); + end; + ar1[index]:= atag; + inc(index); + end; +end; + +procedure putvalue(var ar1: integerarty; var index: integer; + const atag,avalue,defaultvalue: integer); +begin + if avalue <> defaultvalue then begin + if index > high(ar1) then begin + setlength(ar1,19+high(ar1)*2); + end; + ar1[index]:= atag; + inc(index); + ar1[index]:= avalue; + inc(index); + end; +end; + +procedure makecurrent(const gc: gcty); +begin + with oglgcty(gc.platformdata).d do begin +{$ifdef unix} + glxmakecurrent(fdpy,pd,fcontext); +{$else} + wglmakecurrent(fdc,fcontext); +{$endif} + end; +end; + +procedure setviewport(const agc: gcty; const arect: rectty); +//var +// int1: integer; +begin + with arect do begin + glviewport(x,oglgcty(agc.platformdata).d.top-gltopshift-y-cy,cx,cy); + glloadidentity; + if (cx > 0) and (cy > 0) then begin + glortho(glpixelshift,cx+glpixelshift,glpixelshift,cy+glpixelshift,-1,1); +// glortho(0,cx,0,cy,-1,1); +// glortho(-0.5,cx-0.5,-0.5,cy-1,-1,1); +// glortho(-1,cx-1,cy-1,-1,-1,1); + end; + end; +end; + +procedure gdi_setviewport(var drawinfo: drawinfoty); +begin + setviewport(drawinfo.gc,drawinfo.rect.rect^); +end; + +procedure initcontext(const winid: winidty; var gc: gcty; + const sourceviewport: rectty); +begin + gc.gdifuncs:= openglgetgdifuncs; + if winid <> 0 then begin + with oglgcty(gc.platformdata).d do begin + // pd:= winid; + top:= sourceviewport.cy+gltopshift; + tess:= glunewtess(); + makecurrent(gc); + glclearstencil(0); + glclear(gl_stencil_buffer_bit); + setviewport(gc,sourceviewport); + glpushattrib(gl_color_buffer_bit); //no mesa glflush until the first glpopattrib? + glpopattrib(); + glgentextures(1,@texture); + end; + end; +end; + +var + gccount: integer; + +function gdi_choosevisual(var gc: gcty; + const contextinfo: contextinfoty): gdierrorty; +{$ifdef unix} +var + index: integer; + ar1: integerarty; + int1,int2: integer; +{$endif} +begin + result:= gde_ok; + with oglgcty(gc.platformdata).d do begin +{$ifdef unix} + fvisinfo:= nil; + fdpy:= msedisplay; + fscreen:= msedefaultscreenno;//defaultscreen(fdpy); + if not glxqueryextension(fdpy,int1,int2) then begin + result:= gde_noglx; + exit; + end; + index:= 0; + with contextinfo.attrib do begin + putvalue(ar1,index,glx_level,level,0); + if not (df_canvasispixmap in gc.drawingflags) then begin + if doublebuffer then begin + include(gc.drawingflags,df_doublebuffer); + putboolean(ar1,index,glx_doublebuffer,doublebuffer); + end; + end; + putvalue(ar1,index,glx_buffer_size,buffersize,-1); +// putvalue(ar1,index,glx_level,level,0); + putboolean(ar1,index,glx_rgba,rgba); + putboolean(ar1,index,glx_stereo,stereo); + putvalue(ar1,index,glx_aux_buffers,auxbuffers,-1); + putvalue(ar1,index,glx_red_size,redsize,-1); + putvalue(ar1,index,glx_green_size,greensize,-1); + putvalue(ar1,index,glx_blue_size,bluesize,-1); + putvalue(ar1,index,glx_alpha_size,alphasize,-1); + putvalue(ar1,index,glx_depth_size,depthsize,-1); + putvalue(ar1,index,glx_stencil_size,stencilsize,-1); + putvalue(ar1,index,glx_accum_red_size,accumredsize,-1); + putvalue(ar1,index,glx_accum_green_size,accumgreensize,-1); + putvalue(ar1,index,glx_accum_blue_size,accumbluesize,-1); + putvalue(ar1,index,glx_accum_alpha_size,accumalphasize,-1); + setlength(ar1,index+1); //none + fvisinfo:= glxchoosevisual(fdpy,fscreen,pinteger(ar1)); + end; +// fvisinfo:= glxchoosevisual(fdpy,fscreen,pinteger(ar1)); + if fvisinfo = nil then begin + result:= gde_novisual; + exit; + end; + fcolormap:= xcreatecolormap(fdpy,gui_getrootwindow,fvisinfo^.visual,allocnone); +{$else} + with contextinfo.attrib do begin + doublebuf:= doublebuffer; + end; +{$endif} + end; +end; +(* +{$ifdef unix} + +function createrendercontext(const aparent: winidty; const windowrect: rectty; + const ainfo: contextinfoty; + var gc: gcty; out aid: winidty): guierrorty; +var + attributes: txsetwindowattributes; + err: gdierrorty; + +begin + result:= gue_ok; + with oglgcty(gc.platformdata).d do begin + err:= gdi_choosevisual(gc,ainfo); + if err <> gde_ok then begin + case err of + gde_noglx: begin + result:= gue_noglx; + end; + end; + exit; + end; + if fvisinfo = nil then begin + result:= gue_novisual; + exit; + end; + try + fcontext:= glxcreatecontext(fdpy,fvisinfo,nil,true); + if fcontext = nil then begin + result:= gue_rendercontext; + exit; + end; + gc.handle:= ptruint(fcontext); +// fcolormap:= xcreatecolormap(fdpy,mserootwindow,fvisinfo^.visual,allocnone); + attributes.colormap:= fcolormap; + with windowrect do begin + aid:= xcreatewindow(fdpy,aparent,x,y,cx,cy,0,fvisinfo^.depth, + inputoutput,fvisinfo^.visual,cwcolormap,@attributes); + xselectinput(fdpy,aid,exposuremask); //will be mapped to parent + end; + if aid = 0 then begin + result:= gue_createwindow; + exit; + end; + pd:= aid; + // fwin:= aid; + finally + xfree(fvisinfo); + fvisinfo:= nil; + end; + end; + initcontext(aid,gc,windowrect); +end; +{$endif} + +{$ifdef mswindows} +function createrendercontext(const aparent: winidty; const windowrect: rectty; + const ainfo: contextinfoty; + var gc: gcty; out aid: winidty): guierrorty; +var + pixeldesc: tpixelformatdescriptor; + int1: integer; + options1: internalwindowoptionsty; + wi1: windowty; +begin + result:= gue_ok; + fillchar(options1,sizeof(options1),0); + options1.parent:= aparent; + guierror(gui_createwindow(windowrect,options1,wi1)); + aid:= wi1.id; + if aid = 0 then begin + result:= gue_createwindow; + exit; + end; + with oglgcty(gc.platformdata).d do begin + pd:= aid; + fdc:= getdc(aid); + fillchar(pixeldesc,sizeof(pixeldesc),0); + with pixeldesc do begin + nsize:= sizeof(pixeldesc); + nversion:= 1; + dwflags:= pfd_draw_to_window or pfd_support_opengl or pfd_doublebuffer; + ipixeltype:= pfd_type_rgba; + ccolorbits:= 24; + cdepthbits:= 32; + end; + int1:= choosepixelformat(fdc,@pixeldesc); + setpixelformat(fdc,int1,@pixeldesc); + fcontext:= wglcreatecontext(fdc); + if fcontext = 0 then begin + result:= gue_rendercontext; + exit; + end; + gc.handle:= ptruint(fcontext); + end; + initcontext(aid,gc,windowrect); +end; +{$endif} +*) + +procedure colortogl(const source: colorty; out dest: glcolorty); +var + co1: rgbtriplety; +begin + co1:= colortorgb(source); + dest.r:= co1.red/255; + dest.g:= co1.green/255; + dest.b:= co1.blue/255; + dest.a:= 0; +end; + +procedure sendrect(const drawinfo: drawinfoty; const arect: rectty); +var + startx,starty,endx,endy: real; + texstartx,texstarty,texendx,texendy: real; + +begin + with drawinfo,oglgcty(gc.platformdata).d,arect do begin + startx:= (x+origin.x)+glpixelshift; + endx:= startx+cx; + starty:= (top-gltopshift-(y+origin.y))+glpixelshift; + endy:= starty-cy; + if ogcs_hastexture in gcstate then begin + texstartx:= (x+origin.x+gcbrushorigin.x)/brushsize.cx; + texendx:= texstartx + cx/brushsize.cx; + texstarty:= (y+origin.y+gcbrushorigin.y)/brushsize.cy; + texendy:= texstarty + cy/brushsize.cy; +// texstartx:= 0; +// texendx:= 1; +// texstarty:= -1; +// texendy:= 0; + gltexcoord2d(texstartx,texstarty); + glvertex2d(startx,starty); + gltexcoord2d(texendx,texstarty); + glvertex2d(endx,starty); + gltexcoord2d(texendx,texendy); + glvertex2d(endx,endy); + gltexcoord2d(texstartx,texendy); + glvertex2d(startx,endy); + end + else begin + glvertex2f(startx,starty); + glvertex2f(endx,starty); + glvertex2f(endx,endy); + glvertex2f(startx,endy); + end; + end; +end; + +procedure gdi_makecurrent(var drawinfo: drawinfoty); +begin + with oglgcty(drawinfo.gc.platformdata).d do begin +{$ifdef unix} +// glxmakecurrent(fdpy,drawinfo.paintdevice,fcontext); + glxmakecurrent(fdpy,pd,fcontext); +{$else} + wglmakecurrent(fdc,fcontext); +{$endif} + end; +end; + +{$ifdef unix} +var + linkgc: glxcontext; +{$endif} +var + screenextensions: glextensionsty; + screenextensionschecked: boolean; + pixmapextensions: glextensionsty; + pixmapextensionschecked: boolean; + +procedure gdi_createpixmap(var drawinfo: drawinfoty); //gdifunc +{$ifdef mswindows} +var + info: tbitmapinfo; + dc: hdc; +// po1: pointer; +{$endif} +begin + with drawinfo.createpixmap do begin + {$ifdef mswindows} + with info.bmiheader do begin + bisize:= sizeof(info.bmiheader); + biwidth:= size.cx; + biheight:= -size.cy; + biplanes:= 1; + bibitcount:= 32; + bicompression:= bi_rgb; + bisizeimage:= 0; + bixpelspermeter:= 3000; + biypelspermeter:= 3000; + biclrused:= 0; + biclrimportant:= 0; + end; + dc:= getdc(0); +// pixmap:= createdibsection(dc,info,dib_rgb_colors,po1,0,0); + pixmap:= createdibitmap(dc,info.bmiheader,0,nil,info,dib_rgb_colors); + releasedc(0,dc); + {$else} + pixmap:= gui_createpixmap(size,0,bmk_rgb{false},copyfrom); + //depht 1 not supported by glx ??? + {$endif} + end; +end; + +procedure gdi_creategc(var drawinfo: drawinfoty); //gdifunc +var + device1: ptruint; //used for extension query +{$ifdef unix} + attributes: txsetwindowattributes; +{$else} + pixeldesc: tpixelformatdescriptor; + int1: integer; + options1: internalwindowoptionsty; + wi1: windowty; +{$endif} +begin + if gccount = 0 then begin + initializeopengl([]); + end; + with drawinfo.creategc,oglgcty(gcpo^.platformdata).d do begin + error:= gdi_choosevisual(gcpo^,pcontextinfoty(contextinfopo)^); + if error <> gde_ok then begin + exit; + end; + {$ifdef unix} + if fvisinfo = nil then begin + error:= gde_novisual; + exit; + end; + if linkgc = nil then begin + linkgc:= glxcreatecontext(fdpy,fvisinfo,nil,true); + end; + try + fcontext:= glxcreatecontext(fdpy,fvisinfo,nil,true); + (* + fcontext:= glxcreatecontext(fdpy,visinfo,linkgc,false{kind <> gck_pixmap}{true}); + //crashes on suse 11.1 with true on pixmap + *) + if fcontext = nil then begin + error:= gde_rendercontext; + exit; + end; + device1:= 0; //not used + inc(gccount); + gcpo^.handle:= ptruint(fcontext); + fkind:= kind; + if kind = gck_pixmap then begin + pd:= 0; + pd:= glxcreateglxpixmap(fdpy,fvisinfo,paintdevice); + if pd = 0 then begin + error:= gde_glxpixmap; + end; + end + else begin + if paintdevice = 0 then begin + if createpaintdevice then begin + with windowrect^ do begin + fcolormap:= xcreatecolormap(fdpy,gui_getrootwindow,fvisinfo^.visual, + allocnone); + attributes.colormap:= fcolormap; + paintdevice:= xcreatewindow(fdpy,parent,x,y,cx,cy,0,fvisinfo^.depth, + inputoutput,fvisinfo^.visual,cwcolormap,@attributes); + if paintdevice = 0 then begin + error:= gde_createwindow; + exit; + end; + xselectinput(fdpy,paintdevice,exposuremask); //will be mapped to parent + gcpo^.paintdevicesize:= size; + end; + end; + end + else begin + fcolormap:= xcreatecolormap(fdpy,gui_getrootwindow,fvisinfo^.visual,allocnone); + xsetwindowcolormap(fdpy,paintdevice,fcolormap); + end; + pd:= paintdevice; + end; + finally + xfree(fvisinfo); + end; + {$else} + error:= gde_ok; +// fkind:= kind; + if paintdevice = 0 then begin + if createpaintdevice then begin + fillchar(options1,sizeof(options1),0); + options1.parent:= parent; + if gui_createwindow(windowrect^,options1,wi1) <> gue_ok then begin + error:= gde_createwindow; + exit; + end; + paintdevice:= wi1.id; + gcpo^.paintdevicesize:= windowrect^.size; + end; + end; + pd:= paintdevice; + fkind:= kind; + if kind = gck_pixmap then begin + fdc:= createcompatibledc(0); + selectobject(fdc,paintdevice); + end + else begin + fdc:= getdc(pd); + end; + device1:= fdc; + fillchar(pixeldesc,sizeof(pixeldesc),0); + with pixeldesc do begin + nsize:= sizeof(pixeldesc); + nversion:= 1; + dwflags:= pfd_support_opengl; + if doublebuf then begin + dwflags:= dwflags or pfd_doublebuffer; + end; + if kind = gck_pixmap then begin + dwflags:= dwflags or pfd_draw_to_bitmap; + end + else begin + dwflags:= dwflags or pfd_draw_to_window; + end; + ipixeltype:= pfd_type_rgba; + ccolorbits:= 32; + cdepthbits:= 16; + cstencilbits:= 8; + end; + fcontext:= 0; + int1:= choosepixelformat(fdc,@pixeldesc); + if int1 <> 0 then begin + if setpixelformat(fdc,int1,@pixeldesc) then begin + fcontext:= wglcreatecontext(fdc); + end + end; + if fcontext = 0 then begin + error:= gde_rendercontext; + exit; + end; + inc(gccount); + gcpo^.handle:= ptruint(fcontext); + {$endif} + if error = gde_ok then begin + initcontext(paintdevice,gcpo^,mr(nullpoint,gcpo^.paintdevicesize)); + if paintdevice <> 0 then begin + if (kind = gck_pixmap) then begin + if not pixmapextensionschecked then begin + makecurrent(gcpo^); + pixmapextensions:= gldeviceextensions(device1) + + mseglparseextensions(glgetstring(gl_extensions)); + pixmapextensionschecked:= true; + end; + extensions:= pixmapextensions; + end + else begin + if not screenextensionschecked then begin + makecurrent(gcpo^); + screenextensions:= gldeviceextensions(device1) + + mseglparseextensions(glgetstring(gl_extensions)); + screenextensionschecked:= true; + end; + extensions:= screenextensions; + end; + end; + end; + end; +end; + +procedure destroygc(var gc: gcty; const paintdevice: paintdevicety); +begin + with oglgcty(gc.platformdata).d do begin + if tess <> nil then begin + gludeletetess(tess); + end; +{$ifdef unix} + glxmakecurrent(fdpy,0,nil); + gldeletetextures(1,@texture); + glxdestroycontext(fdpy,fcontext); + if paintdevice <> 0 then begin + if fkind = gck_pixmap then begin + glxdestroyglxpixmap(fdpy,pd); + pd:= 0; + end + else begin + xfreecolormap(fdpy,fcolormap); + end; + end; + dec(gccount); + if (gccount = 0) and (linkgc <> nil) then begin + glxdestroycontext(fdpy,linkgc); + linkgc:= nil; + end; +{$else} + wglmakecurrent(0,0); + gldeletetextures(1,@texture); + wgldeletecontext(fcontext); + if fkind = gck_pixmap then begin + deletedc(fdc); + end + else begin + releasedc(paintdevice,fdc); + end; + dec(gccount); +{$endif} + if gccount = 0 then begin + releaseopengl(); + screenextensionschecked:= false; + pixmapextensionschecked:= false; + end; + end; +end; + + +procedure gdi_destroygc(var drawinfo: drawinfoty); //gdifunc +begin + destroygc(drawinfo.gc,drawinfo.paintdevice); +end; + +procedure gdi_swapbuffers(var drawinfo: drawinfoty); +begin + with oglgcty(drawinfo.gc.platformdata).d do begin + {$ifdef unix} + glxswapbuffers(fdpy,drawinfo.paintdevice); + {$else} + swapbuffers(fdc); + {$endif} + end; +end; + +procedure gdi_clear(var drawinfo: drawinfoty); +var + co1: glcolorty; +begin + with oglgcty(drawinfo.gc.platformdata).d do begin + colortogl(drawinfo.color.color,co1); + glclearcolor(co1.r,co1.g,co1.b,co1.a); + glclear(gl_color_buffer_bit); + + end; +end; + +{***************} + +const + rops: array[rasteropty] of integer = ( + //rop_clear, rop_and, rop_andnot, rop_copy, + gl_clear, gl_and, gl_and_reverse, gl_copy, + //rop_notand, rop_nop, rop_xor, rop_or, + gl_and_inverted, gl_noop, gl_xor, gl_or, + //rop_nor, rop_notxor, rop_not, rop_ornot, + gl_nor, gl_equiv, gl_invert, gl_or_reverse, + //rop_notcopy, rop_notor, rop_nand, rop_set + gl_copy_inverted, gl_or_inverted, gl_nand, gl_set + ); + +procedure setlogicop(const rasterop: rasteropty; const gc: gcty); +begin + if rasterop = rop_copy then begin + gllogicop(gl_copy); + if df_canvasismonochrome in gc.drawingflags then begin + gldisable(gl_index_logic_op); + end + else begin + gldisable(gl_color_logic_op); + end; + end + else begin +// gllogicop(rops[rasterop]); + if df_canvasismonochrome in gc.drawingflags then begin + glenable(gl_index_logic_op); + end + else begin + glenable(gl_color_logic_op); + end; + gllogicop(rops[rasterop]); + end; +end; + +//todo: optimize +function scaletopowerof2(const source: maskedimagety; + out dest: imagety): boolean; +//true if data copied +var + ps,pd: plongword; + pm: prgbtriplety; + int1,int2: integer; + scxw,scx,dcx,scy,dcy: integer; + xintp,yintp: integer; + lwos,lwod: longword; +begin + dest:= source.image; + result:= false; + if source.image.length > 0 then begin + with dest do begin + size.cx:= nextpowerof2(source.image.size.cx); + size.cy:= nextpowerof2(source.image.size.cy); + result:= (source.mask.pixels <> nil) and (source.mask.kind <> bmk_mono) + or (size.cx <> source.image.size.cx) or + (size.cy <> source.image.size.cy); + if result then begin + dcx:= size.cx; + dcy:= size.cy; + scx:= source.image.size.cx; + scy:= source.image.size.cy; + allocimage(dest,source.image.size,source.image.kind); + scxw:= dest.linelength; + { + if source.image.monochrome then begin + scxw:= ((dcx+31) div 32); + dest.pixels:= gui_allocimagemem(scxw*dcy); + end + else begin + dest.pixels:= gui_allocimagemem(dcx*dcy); + end; + } + ps:= pointer(source.image.pixels); + pd:= pointer(dest.pixels); + yintp:= dcy; + if (source.mask.pixels <> nil) and (source.mask.kind <> bmk_mono) then begin + //color mask + pm:= pointer(source.mask.pixels); + for int1:= dcy-1 downto 0 do begin + xintp:= dcx; + for int2:= dcx-1 downto 0 do begin + pd^:= ps^; + prgbtriplety(pd)^.res:= (word(pm^.red)+pm^.green+pm^.blue) div 3; + inc(pd); + dec(xintp,scx); + if xintp <= 0 then begin + inc(ps); + inc(pm); + inc(xintp,dcx); + end; + end; + dec(yintp,scy); + if yintp <= 0 then begin + inc(yintp,dcy); + end + else begin + dec(ps,scx); //duplicate row + dec(pm,scx); //duplicate row + end; + end; + end + else begin + if source.image.kind = bmk_mono then begin + //mask in monochrome not supported + for int1:= dcy-1 downto 0 do begin + xintp:= dcx; + pd^:= 0; + lwos:= 1; + lwod:= 1; + for int2:= dcx-1 downto 0 do begin + if ps^ and lwos <> 0 then begin + pd^:= pd^ or lwod; + end; + lwod:= lwod shl 1; + if lwod = 0 then begin + inc(pd); + lwod:= 1; + end; + dec(xintp,scx); + if xintp <= 0 then begin + lwos:= lwos shl 1; + if lwos = 0 then begin + inc(ps); + lwos:= 1; + end; + inc(xintp,dcx); + end; + end; + if lwod <> 1 then begin + inc(pd); + end; + if lwos <> 0 then begin + inc(ps); + end; + dec(yintp,scy); + if yintp <= 0 then begin + inc(yintp,dcy); + end + else begin + dec(ps,scxw); //duplicate row + end; + end; + end + else begin //rgb + for int1:= dcy-1 downto 0 do begin + xintp:= dcx; + for int2:= dcx-1 downto 0 do begin + pd^:= ps^; + inc(pd); + dec(xintp,scx); + if xintp <= 0 then begin + inc(ps); + inc(xintp,dcx); + end; + end; + dec(yintp,scy); + if yintp <= 0 then begin + inc(yintp,dcy); + end + else begin + dec(ps,scx); //duplicate row + end; + end; + end; + end; + end; + end; + end; +end; + +procedure settexture(const gc: gcty; const apixmap: tsimplebitmap); +var + mode,datatype: glenum; + im1: maskedimagety; + im2: imagety; + bo1: boolean; + map: array[0..1] of glfloat; +begin + with oglgcty(gc.platformdata).d do begin + glbindtexture(gl_texture_2d,texture); + mode:= gl_rgba; + if gle_gl_ext_bgra in extensions then begin + mode:= gl_bgra; + end; + im1:= tcanvas1(apixmap.canvas).getimage(mode = gl_rgba); + makecurrent(gc); //possibly changed by getimage + brushsize:= im1.image.size; + if (brushsize.cx = 0) or (brushsize.cy = 0) then begin + glteximage2d(gl_texture_2d,0,4,0,0,0,mode,gl_unsigned_byte,nil); + gldisable(gl_texture_2d); + exclude(gcstate,ogcs_hastexture); + exit; + end; + bo1:= scaletopowerof2(im1,im2); + if im1.mask.pixels <> nil then begin + include(gcstate,ogcs_needsblend); + end; + glpushclientattrib(gl_client_pixel_store_bit); + glpushattrib(gl_pixel_mode_bit); + if im2.kind = bmk_mono then begin + map[0]:= glcolorbackground.red/255; + map[1]:= glcolorforeground.red/255; + glpixelmapfv(gl_pixel_map_i_to_r,2,@map); + map[0]:= glcolorbackground.green/255; + map[1]:= glcolorforeground.green/255; + glpixelmapfv(gl_pixel_map_i_to_g,2,@map); + map[0]:= glcolorbackground.blue/255; + map[1]:= glcolorforeground.blue/255; + glpixelmapfv(gl_pixel_map_i_to_b,2,@map); + if df_opaque in gc.drawingflags then begin + map[0]:= 1; + end + else begin + map[0]:= 0; + include(gcstate,ogcs_needsblend); + end; + map[1]:= 1; + glpixelmapfv(gl_pixel_map_i_to_a,2,@map); + mode:= gl_color_index; + datatype:= gl_bitmap; + glpixelstorei(gl_unpack_lsb_first,1); + end + else begin + datatype:= gl_unsigned_byte; + if im1.mask.pixels = nil then begin + glpixeltransferf(gl_alpha_scale,0); + glpixeltransferf(gl_alpha_bias,1); + end; + end; + with im2 do begin + glteximage2d(gl_texture_2d,0,4,size.cx,size.cy,0,mode,datatype,pixels); + end; + if bo1 then begin + gui_freeimagemem(im2.pixels); + end; + glpopattrib; + glpopclientattrib; + gltexenvi(gl_texture_env,gl_texture_env_mode,gl_replace); + gltexparameteri(gl_texture_2d, gl_texture_wrap_s, gl_repeat); + gltexparameteri (gl_texture_2d, gl_texture_wrap_t, gl_repeat); + gltexparameteri (gl_texture_2d, gl_texture_mag_filter, gl_nearest); + gltexparameteri (gl_texture_2d, gl_texture_min_filter, gl_nearest); + end; +end; + +procedure gdi_changegc(var drawinfo: drawinfoty); +var + po1: pstripety; + int1,int2,int3,int4: integer; + y1,x1: integer; + statebefore: oglgcstatesty; +begin + with drawinfo.gcvalues^,drawinfo.gc,oglgcty(platformdata).d do begin + statebefore:= gcstate; + if gvm_colorforeground in mask then begin + glcolorforeground:= colortorgb(drawinfo.acolorforeground); + with glcolorforeground do begin + glcolor3ub(red,green,blue); + end; + end; + if gvm_colorbackground in mask then begin + glcolorbackground:= colortorgb(drawinfo.acolorbackground); + //rgbtriplety(colorbackground); + end; + if gvm_rasterop in mask then begin + setlogicop(rasterop,drawinfo.gc); + gcrasterop:= rasterop; + end; + if gvm_brush in mask then begin + settexture(drawinfo.gc,brush); + end; + if gvm_brushorigin in mask then begin + gcbrushorigin:= brushorigin; + end; + if drawingflagsty((longword(drawingflags) xor + longword(gcdrawingflags))) * [df_brush]{fillmodeinfoflags} <> [] then begin + updatebit1(longword(gcstate),ord(ogcs_hastexture), + (df_brush in drawingflags) and + (brushsize.cx > 0) and (brushsize.cy > 0)); + end; + gcdrawingflags:= drawingflags; + if gvm_options in mask then begin + if (cao_smooth in options) xor + (cao_smooth in gcoptions) then begin + if cao_smooth in options then begin + glenable(gl_line_smooth); + glenable(gl_polygon_smooth); + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end + else begin + gldisable(gl_line_smooth); + gldisable(gl_polygon_smooth); + gldisable(gl_blend); + end; + end; + gcoptions:= options; + end; + + if gvm_font in mask then begin +// ftglfont:= pftglfontty(font)^; + glfont:= font; + end; + if gvm_clipregion in mask then begin + if clipregion = 0 then begin + gldisable(gl_stencil_test); + exclude(gcstate,ogcs_hasclipreg); + end + else begin + include(gcstate,ogcs_hasclipreg); + glclearstencil(0); + glclear(gl_stencil_buffer_bit); + glenable(gl_stencil_test); + glstencilfunc(gl_never,1,1); + glstencilop(gl_replace,gl_keep,gl_keep); + with pregioninfoty(clipregion)^ do begin + if rectcount > 0 then begin + glbegin(gl_quads); + y1:= top-(stripestart+cliporigin.y); + po1:= datapo; + for int1:= stripecount-1 downto 0 do begin + int3:= y1; + x1:= cliporigin.x; + y1:= y1 - po1^.header.height; //next stripe + int2:= po1^.header.rectcount -1; + po1:= @po1^.data; + for int2:= int2 downto 0 do begin + x1:= x1 + prectextentty(po1)^; //gap + glvertex2i(x1,int3); + inc(prectextentty(po1)); + int4:= x1; + x1:= x1 + prectextentty(po1)^; + glvertex2i(x1,int3); + glvertex2i(x1,y1); + glvertex2i(int4,y1); + inc(prectextentty(po1)); + end; + end; + glend; + end; + end; + glstencilop(gl_keep,gl_keep,gl_keep); + glstencilfunc(gl_equal,1,1); + end; + end; + statebefore:= oglgcstatesty(longword(statebefore) xor longword(gcstate)); + if ogcs_hastexture in statebefore then begin + if ogcs_hastexture in gcstate then begin + glenable(gl_texture_2d); + end + else begin + gldisable(gl_texture_2d); + end; + end; + if ogcs_needsblend in statebefore then begin + if ogcs_needsblend in gcstate then begin + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end + else begin + gldisable(gl_blend); + end; + end; + end; +end; + +procedure gdi_getcanvasclass(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.getcanvasclass do begin +// if not monochrome then begin + canvasclass:= topenglwindowcanvas; +// end; + end; +end; + +procedure gdi_endpaint(var drawinfo: drawinfoty); //gdifunc +begin + if df_doublebuffer in drawinfo.gc.drawingflags then begin + gdi_swapbuffers(drawinfo); + end + else begin + glflush(); + end; +end; + +procedure gdi_flush(var drawinfo: drawinfoty); //gdifunc +begin + glflush(); +end; + +procedure gdi_drawlines(var drawinfo: drawinfoty); +var + po1: ppointty; + int1,int2: integer; +begin + int2:= oglgcty(drawinfo.gc.platformdata).d.top; + with drawinfo,points do begin + if closed then begin + glbegin(gl_line_loop); + end + else begin + glbegin(gl_line_strip); + end; + po1:= points; + for int1:= count-1 downto 0 do begin + glvertex2i(po1^.x+origin.x,int2-(po1^.y+origin.y)); + inc(po1); + end; + end; + glend; +end; + +procedure gdi_drawlinesegments(var drawinfo: drawinfoty); +var + po1: ppointty; + int1,int2: integer; +begin + int2:= oglgcty(drawinfo.gc.platformdata).d.top; + glbegin(gl_lines); + with drawinfo,points do begin + po1:= points; + for int1:= count-1 downto 0 do begin + glvertex2i(po1^.x+origin.x,int2-(po1^.y+origin.y)); + inc(po1); + end; + end; + glend; +end; + +procedure drawlines(const gc: gcty; const points: pfpointty; + const count: integer; const close: boolean); +var + po1: pfpointty; + int1,int2: integer; +begin + int2:= oglgcty(gc.platformdata).d.top; + if close then begin + int1:= gl_line_loop; + end + else begin + int1:= gl_line; + end; + glbegin(int1); + po1:= points; + for int1:= count-1 downto 0 do begin + glvertex2f(po1^.x,int2-po1^.y); + inc(po1); + end; + glend; +end; + +procedure gdi_drawellipse(var drawinfo: drawinfoty); +begin + segmentellipsef(drawinfo,@drawlines); +end; + +procedure gdi_drawarc(var drawinfo: drawinfoty); +begin + gdinotimplemented; +end; + +procedure gdi_fillrect(var drawinfo: drawinfoty); +begin + glbegin(gl_quads); + sendrect(drawinfo,drawinfo.rect.rect^); + glend; +end; + +procedure gdi_fillellipse(var drawinfo: drawinfoty); +begin + gdinotimplemented; +end; + +procedure gdi_fillarc(var drawinfo: drawinfoty); +begin + gdinotimplemented; +end; + +procedure tesserror(err: glenum); {$ifdef mswindows}stdcall;{$else}cdecl;{$endif} +begin +end; + +type + vertexpoar4ty = array[0..3] of pgluvertexty; + pvertexpoar4ty = ^vertexpoar4ty; + glfloatar4ty = array[0..3] of glfloat; + pglfloatar4ty = ^glfloatar4ty; + +var + tessbuffer: array of pgluvertexty; + tessbufferindex: integer; + +function gettessbuffer: pgluvertexty; +var + int1: integer; +begin + if tessbufferindex > high(tessbuffer) then begin + setlength(tessbuffer,high(tessbuffer)*2+32); + for int1:= tessbufferindex to high(tessbuffer) do begin + getmem(tessbuffer[int1],sizeof(gluvertexty)); + end; + result:= tessbuffer[tessbufferindex]; + end; + result:= tessbuffer[tessbufferindex]; + inc(tessbufferindex); +end; + +procedure freebuffers; +var + int1: integer; +begin + for int1:= high(tessbuffer) downto 0 do begin + freemem(tessbuffer[int1]); + end; + { + if stockpixmapgc <> 0 then begin + glxdestroycontext(msedisplay,stockpixmapgc); + end; + } +end; +{ +procedure checkstockpixmapgc; +begin + if stockpixmapgc = 0 then begin + + fillchar(stockgc,sizeof(stockgc),0); + fillchar(info,sizeof(drawinfoty),0); + with info.creategc do begin + kind:= gck_pixmap; + contextinfopo:= @defaultcontextattributes; + end; +end; +} +procedure tesscombine(coords: pgluvertexty; + vertex_data: pvertexpoar4ty; + weight: pglfloatar4ty; + outdata: ppgluvertexty; + polygon_data: pointer); + {$ifdef mswindows}stdcall;{$else}cdecl;{$endif} +//var +// po1: pgluvertexty; +begin +// po1:= gettessbuffer; //not used +// po1^:= coords^; +// outdata^:= po1; + outdata^:= coords; +end; + +procedure gdi_fillpolygon(var drawinfo: drawinfoty); +var + int1: integer; + do1: double; +// vertex: gluvertexty; + po1: ppointty; + po2: pgluvertexty; +begin + with drawinfo,points,oglgcty(drawinfo.gc.platformdata).d do begin + glutesscallback(tess, glu_tess_error, tcallback(@tesserror)); + glutesscallback(tess, glu_tess_begin, tcallback(glbegin)); + glutesscallback(tess, glu_tess_vertex, tcallback(glvertex3dv)); + glutesscallback(tess, glu_tess_combine_data, tcallback(@tesscombine)); + glutesscallback(tess, glu_tess_end, tcallback(glend)); + po1:= points; + allocbuffer(drawinfo.buffer,count*sizeof(gluvertexty)); + tessbufferindex:= 0; + po2:= drawinfo.buffer.buffer; + do1:= top; + glutessbeginpolygon(tess,@drawinfo.gc); + glutessbegincontour(tess); + for int1:= count-1 downto 0 do begin + with po2^ do begin + x:= po1^.x+origin.x; + y:= do1-(po1^.y+origin.y); + z:= 0; + end; + glutessvertex(tess,p3darray(po2)^,po2); + inc(po1); + inc(po2); + end; + glutessendcontour(tess); + glutessendpolygon(tess); + end; +end; + +procedure gdi_drawstring16(var drawinfo: drawinfoty); +begin + fontcache.drawstring16(drawinfo, + oglgcty(drawinfo.gc.platformdata).d.glfont); +end; + +procedure gdi_setcliporigin(var drawinfo: drawinfoty); +begin +end; + +procedure setrasterpos(const agc: gcty; const apos: pointty); +begin + glrasterpos2f(0.999*glpixelshift,0.999*glpixelshift); + glbitmap(0,0,0,0,apos.x,oglgcty(agc.platformdata).d.top-apos.y,nil); +end; + +procedure copyareaself(var drawinfo: drawinfoty); +var + xscale,yscale: real; +begin + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + with destrect^ do begin + glpushattrib(gl_pixel_mode_bit); + xscale:= cx/sourcerect^.cx; + yscale:= cy/sourcerect^.cy; + setrasterpos(drawinfo.gc,mp(x,y+cy)); +// glrasterpos2i(x,(top-y-cy)); + glpixelzoom(xscale,yscale); + with sourcerect^ do begin + glcopypixels(x,top-y-cy,cx,cy,gl_color); + end; + glpopattrib; + end; + end; +end; + +procedure gdi_movewindowrect(var drawinfo: drawinfoty); //gdifunc +begin + glpushattrib(gl_enable_bit); + gldisable(gl_stencil_test); + gldisable(gl_blend); + with drawinfo.moverect,oglgcty(drawinfo.gc.platformdata).d do begin + with rect^ do begin + setrasterpos(drawinfo.gc,mp(x+dist^.x,y+dist^.y+cy)); + glcopypixels(x,top-y-cy,cx,cy,gl_color); + end; + end; + glpopattrib; +end; + +procedure copyareagl(var drawinfo: drawinfoty); +//todo: use persistent pixmap or texture buffer +//suse 11.4 crashes with dri shared buffers and does +//not support non dri shared buffers... +//suse 11.1 crashes with dri pixmaps... + +var +// buf: gluint; + xscale,yscale: real; +// ar1: rgbtriplearty; +// l,t,r,b,w,h: integer; +// pt1: pointty; + int1: integer; + po1: prgbtriplety; + po2: pbyte; + size1: integer; + transparentcolor1: pixelty; +const + co0: rgbtriplety = (blue: $00; green: $00; red: $00; res: $ff); + co1: rgbtriplety = (blue: $ff; green: $ff; red: $ff; res: $ff); +begin + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + makecurrent(tcanvas1(source).fdrawinfo.gc); + with sourcerect^ do begin + size1:= cx*cy; + getmem(po1,size1*sizeof(rgbtriplety)); +// setlength(ar1,cx*cy); + glreadpixels(x, + oglgcty(tcanvas1(source).fdrawinfo.gc.platformdata).d.top-y-cy+1, + cx,cy,gl_rgba,gl_unsigned_byte,po1); + if mask <> nil then begin + tcanvas1(mask.canvas).checkgcstate([cs_gc]); + makecurrent(tcanvas1(mask.canvas).fdrawinfo.gc); + getmem(po2,cx*cy); + glpushclientattrib(gl_client_pixel_store_bit); + glpixelstorei(gl_pack_alignment,1); + glreadpixels(x, + oglgcty(tcanvas1(source).fdrawinfo.gc.platformdata).d.top-y-cy+1, + cx,cy,gl_luminance,gl_unsigned_byte,po2); + glpopclientattrib; + for int1:= cx*cy-1 downto 0 do begin + prgbtripleaty(po1)^[int1].res:= pbyteaty(po2)^[int1]; + end; + end; + end; + makecurrent(drawinfo.gc); + int1:= gl_pixel_mode_bit; + if mask <> nil then begin + int1:= int1 or gl_color_buffer_bit; + end; + glpushattrib(int1); + if df_colorconvert in drawinfo.gc.drawingflags then begin + if df_canvasismonochrome in + tcanvas1(source).fdrawinfo.gc.drawingflags then begin + glpixeltransferf(gl_red_bias,glcolorbackground.red/255); + glpixeltransferf(gl_red_scale, + (glcolorforeground.red-glcolorbackground.red)/255); + glpixeltransferf(gl_green_bias,glcolorbackground.green/255); + glpixeltransferf(gl_green_scale, + (glcolorforeground.green-glcolorbackground.green)/255); + glpixeltransferf(gl_blue_bias,glcolorbackground.blue/255); + glpixeltransferf(gl_blue_scale, + (glcolorforeground.blue-glcolorbackground.blue)/255); + end + else begin + transparentcolor1:= transparentcolor; + rgbtriplety(transparentcolor1).res:= $ff; + for int1:= size1-1 downto 0 do begin + if ppixelaty(po1)^[int1] = transparentcolor1 then begin + plongwordaty(po1)^[int1]:= pixelty(co0); + end + else begin + plongwordaty(po1)^[int1]:= pixelty(co1); + end; + end; + end; + end; + if mask <> nil then begin + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end; + with destrect^ do begin + xscale:= cx/sourcerect^.cx; + yscale:= cy/sourcerect^.cy; + glpixelzoom(xscale,yscale); + setrasterpos(drawinfo.gc,mp(x,y+cy-1)); + gldrawpixels(sourcerect^.cx,sourcerect^.cy,gl_rgba,gl_unsigned_byte,po1); + end; + glpopattrib; + freemem(po1); + if mask <> nil then begin + freemem(po2); + end; + end; +(* buffer objects are unreliable + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + makecurrent(tcanvas1(source).fdrawinfo.gc); + glgenbuffers(1,@buf); + glpushclientattrib(gl_client_pixel_store_bit); + glpushattrib(gl_pixel_mode_bit); + glpixeltransferf(gl_alpha_scale,0); + glpixeltransferf(gl_alpha_bias,1); + with sourcerect^ do begin + glbufferdata(gl_pixel_pack_buffer,cx*cy*sizeof(rgbtriplety),nil,gl_stream_draw); + glbindbuffer(gl_pixel_pack_buffer,buf); + glreadpixels(x,sourceheight-y-cy,cx,cy,gl_bgra,gl_unsigned_byte,nil); + end; + glbindbuffer(gl_pixel_pack_buffer,0); + makecurrent(drawinfo.gc); + glbindbuffer(gl_pixel_unpack_buffer,buf); + with destrect^ do begin + xscale:= cx/sourcerect^.cx; + yscale:= cy/sourcerect^.cy; + glrasterpos2i(x,(sourceheight-y-cy)); + glpixelzoom(xscale,yscale); + end; + with sourcerect^ do begin +//glbindbuffer(gl_pixel_unpack_buffer,0); + + gldrawpixels(cx,cy,gl_bgra,gl_unsigned_byte,nil); + end; + glbindbuffer(gl_pixel_unpack_buffer,0); + + glpopclientattrib; + glpopattrib; + gldeletebuffers(1,@buf); + end; + *) +end; + +//todo: optimize, use data window + +procedure gdi_copyarea(var drawinfo: drawinfoty); +var + im1: maskedimagety; + mode,datatype: glenum; + map: array[0..1] of glfloat; + opacity1: glfloat; +// monomask: boolean; + ps1,pd1: prgbtripleaty; +// ps2: plongword; +// pd2: prgbtriplety; + int1: integer; + wo1: word; +// lwo1: longword; + +begin + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + if copymode <> gcrasterop then begin + setlogicop(copymode,drawinfo.gc); + end; + end; + + if tcanvas1(drawinfo.copyarea.source).fdrawinfo.gc.handle = + drawinfo.gc.handle then begin + copyareaself(drawinfo); + end + else begin + if tcanvas1(drawinfo.copyarea.source).fdrawinfo.gc.gdifuncs = + drawinfo.gc.gdifuncs then begin + copyareagl(drawinfo); + end + else begin //foreign gdi + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + mode:= gl_rgba; + if gle_gl_ext_bgra in extensions then begin + mode:= gl_bgra; + end; + im1:= tcanvas1(source).getimage(mode = gl_rgba); + makecurrent(drawinfo.gc); + if (im1.image.size.cx = 0) or (im1.image.size.cy = 0) then begin + exit; + end; + glpushclientattrib(gl_client_pixel_store_bit); + glpushattrib(gl_pixel_mode_bit or gl_color_buffer_bit or + gl_stencil_buffer_bit); + wo1:= word(opacity.red)+opacity.blue+opacity.red+opacity.blue; + if wo1 = 3*255 then begin + opacity1:= 1; + end + else begin + opacity1:= wo1/(3*255); + end; + with sourcerect^ do begin + glpixelzoom(destrect^.cx/cx,-destrect^.cy/cy); + glpixelstorei(gl_unpack_row_length,im1.image.size.cx); + glpixelstorei(gl_unpack_skip_pixels,x); + glpixelstorei(gl_unpack_skip_rows,y); + end; + setrasterpos(drawinfo.gc,destrect^.pos); + glpixelstorei(gl_unpack_lsb_first,1); + if (im1.mask.kind = bmk_mono) and (im1.mask.pixels <> nil) then begin + glstencilmask(2); + glpixeltransferi(gl_index_shift,1); + with sourcerect^ do begin + gldrawpixels(cx,cy,gl_stencil_index,gl_bitmap,im1.mask.pixels); + end; + glpixeltransferi(gl_index_shift,0); + if ogcs_hasclipreg in gcstate then begin + int1:= 3; //combine mask and clipregion + end + else begin + int1:= 2; + glenable(gl_stencil_test); + end; + glstencilfunc(gl_equal,int1,int1); + end; + if im1.image.kind = bmk_mono then begin + datatype:= gl_bitmap; + mode:= gl_color_index; + map[0]:= glcolorbackground.red/255; + map[1]:= glcolorforeground.red/255; + glpixelmapfv(gl_pixel_map_i_to_r,2,@map); + map[0]:= glcolorbackground.green/255; + map[1]:= glcolorforeground.green/255; + glpixelmapfv(gl_pixel_map_i_to_g,2,@map); + map[0]:= glcolorbackground.blue/255; + map[1]:= glcolorforeground.blue/255; + glpixelmapfv(gl_pixel_map_i_to_b,2,@map); + if df_opaque in drawinfo.gc.drawingflags then begin + map[0]:= opacity1; + if opacity1 < 1 then begin + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end; + end + else begin + map[0]:= 0; + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end; + map[1]:= opacity1; + glpixelmapfv(gl_pixel_map_i_to_a,2,@map); + end + else begin + if (im1.mask.pixels <> nil) and (im1.mask.kind <> bmk_mono) then begin + { + if im1.mask.monochrome then begin + pd2:= prgbtriplety(im1.image.pixels); + ps2:= plongword(im1.mask.pixels); + for int1:= 0 to im1.image.size.cy - 1 do begin + lwo1:= 1; + for int2:= 0 to im1.image.size.cx - 1 do begin + if ps2^ and lwo1 <> 0 then begin + pd2^.res:= $ff; + end + else begin + pd2^.res:= $00; + end; + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(ps2); + lwo1:= 1; + end; + end; + if lwo1 <> 1 then begin + inc(ps2); + end; + end; + end + else begin + } + pd1:= prgbtripleaty(im1.image.pixels); + ps1:= prgbtripleaty(im1.mask.pixels); + for int1:= im1.image.length-1 downto 0 do begin + with ps1^[int1] do begin + pd1^[int1].res:= (word(red)+green+blue) div 3; + end; + end; + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end + else begin + glpixeltransferf(gl_alpha_scale,0); + glpixeltransferf(gl_alpha_bias,1); + end; + datatype:= gl_unsigned_byte; + end; + with sourcerect^ do begin + gldrawpixels(cx,cy,mode,datatype,im1.image.pixels); + end; + glpopclientattrib; + glpopattrib; + end; + end; + end; + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + if copymode <> gcrasterop then begin + setlogicop(gcrasterop,drawinfo.gc); + end; + end; +end; + +procedure getimage(var drawinfo: drawinfoty; var image: imagety); + +//todo: optimize +var + int1,int2,int3: integer; + po1,ps1,pd1: pchar; + pd2: plongword; + lwo1: longword; + mode,datatype: glenum; +begin + with drawinfo,oglgcty(drawinfo.gc.platformdata).d do begin + with image do begin + if kind = bmk_mono then begin + datatype:= gl_unsigned_byte; + mode:= gl_luminance; + getmem(po1,size.cx*size.cy); + glpushclientattrib(gl_client_pixel_store_bit); + glpixelstorei(gl_pack_alignment,1); + glreadpixels(0,0,size.cx,size.cy,mode,datatype,po1); + glpopclientattrib; + ps1:= pointer(pchar(po1)+(size.cy-1)*size.cx); //top row + pd2:= pointer(pixels); + for int1:= size.cy-1 downto 0 do begin + pd2^:= 0; + lwo1:= 1; + for int3:= size.cx-1 downto 0 do begin + if ps1^ <> #0 then begin + pd2^:= pd2^ or lwo1; + end; + inc(ps1); + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(pd2); + lwo1:= 1; + end; + end; + dec(ps1,2*size.cx); //next row + if lwo1 <> 1 then begin + inc(pd2); + end; + end; + freemem(po1); + end + else begin + glpushattrib(gl_pixel_mode_bit); + + glpixeltransferf(gl_alpha_scale,0); + glpixeltransferf(gl_alpha_bias,0); + datatype:= gl_unsigned_byte; + if not bgr and (gle_GL_EXT_bgra in extensions) then begin + mode:= gl_bgra; + end + else begin + mode:= gl_rgba; + bgr:= true; + end; + if gle_gl_mesa_pack_invert in extensions then begin + glpushclientattrib(gl_client_pixel_store_bit); + glpixelstorei(gl_pack_invert_mesa,1); + glreadpixels(0,0,size.cx,size.cy,mode,datatype,pixels); + glpopclientattrib; + end + else begin + getmem(po1,length*sizeof(rgbtriplety)); + glreadpixels(0,0,size.cx,size.cy,mode,datatype,po1); + int2:= sizeof(rgbtriplety)*size.cx; + ps1:= pointer(pchar(po1)+(size.cy-1)*int2); //top row + pd1:= pointer(pixels); + for int1:= size.cy-1 downto 0 do begin + move(ps1^,pd1^,int2); + dec(ps1,int2); + inc(pd1,int2); + end; + freemem(po1); + end; + glpopattrib; + end; + end; + end; +end; + +procedure gdi_getimage(var drawinfo: drawinfoty); +begin + getimage(drawinfo,drawinfo.getimage.image.image); + drawinfo.getimage.error:= gde_ok; +end; + +procedure gdi_pixmaptoimage(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.pixmapimage do begin + if drawinfo.gc.handle <> 0 then begin + allocimage(image,drawinfo.gc.paintdevicesize,drawinfo.gc.kind); + getimage(drawinfo,image); + end + else begin + gui_pixmaptoimage(pixmap,image,drawinfo.gc.handle); + end; + end; +end; + +procedure gdi_imagetopixmap(var drawinfo: drawinfoty); //gdifunc +var + im1: imagety; + ps1,pd1: plongword; + int1,int2: integer; + lwo1: longword; +begin + with drawinfo.pixmapimage do begin + if image.kind = bmk_mono then begin + with image do begin + allocimage(im1,size,bmk_rgb); + ps1:= pointer(pixels); +// pd1:= plongword(im1.pixels)+(size.cy-1)*size.cx; //top row + pd1:= pointer(im1.pixels); + for int1:= size.cy-1 downto 0 do begin + lwo1:= 1; + for int2:= size.cx-1 downto 0 do begin + if ps1^ and lwo1 <> 0 then begin + pd1^:= $00ffffff; + end + else begin + pd1^:= $00000000; + end; + inc(pd1); + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(ps1); + lwo1:= 1; + end; + end; +// dec(pd1,2*size.cx); //next row + if lwo1 <> 1 then begin + inc(ps1); + end; + end; + end; + error:= gui_imagetopixmap(im1,pixmap,0); + gui_freeimagemem(im1.pixels); + end + else begin + error:= gui_imagetopixmap(image,pixmap,0); + end; + end; +end; + +procedure gdi_fonthasglyph(var drawinfo: drawinfoty); +begin + gdinotimplemented; +end; + +procedure gdi_getfont(var drawinfo: drawinfoty); +begin + fontcache.getfont(drawinfo); +end; + +procedure gdi_getfonthighres(var drawinfo: drawinfoty); +begin + gdinotimplemented; +end; + +procedure gdi_freefontdata(var drawinfo: drawinfoty); +begin + if ffontcache <> nil then begin + fontcache.freefontdata(drawinfo); + end; +end; + +procedure gdi_gettext16width(var drawinfo: drawinfoty); +begin + fontcache.gettext16width(drawinfo); +end; + +procedure gdi_getchar16widths(var drawinfo: drawinfoty); +begin + fontcache.getchar16widths(drawinfo); +end; + +procedure gdi_getfontmetrics(var drawinfo: drawinfoty); +begin + fontcache.getfontmetrics(drawinfo); +end; + +const + gdifunctions: gdifunctionaty = ( + {$ifdef FPC}@{$endif}gdi_creategc, + {$ifdef FPC}@{$endif}gdi_destroygc, + {$ifdef FPC}@{$endif}gdi_changegc, + {$ifdef FPC}@{$endif}gdi_createpixmap, + {$ifdef FPC}@{$endif}gdi_pixmaptoimage, + {$ifdef FPC}@{$endif}gdi_imagetopixmap, + {$ifdef FPC}@{$endif}gdi_getcanvasclass, + {$ifdef FPC}@{$endif}gdi_endpaint, + {$ifdef FPC}@{$endif}gdi_flush, + {$ifdef FPC}@{$endif}gdi_movewindowrect, + {$ifdef FPC}@{$endif}gdi_drawlines, + {$ifdef FPC}@{$endif}gdi_drawlinesegments, + {$ifdef FPC}@{$endif}gdi_drawellipse, + {$ifdef FPC}@{$endif}gdi_drawarc, + {$ifdef FPC}@{$endif}gdi_fillrect, + {$ifdef FPC}@{$endif}gdi_fillellipse, + {$ifdef FPC}@{$endif}gdi_fillarc, + {$ifdef FPC}@{$endif}gdi_fillpolygon, + {$ifdef FPC}@{$endif}gdi_drawstring16, + {$ifdef FPC}@{$endif}gdi_setcliporigin, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_createemptyregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_createrectregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_createrectsregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_destroyregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_copyregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_moveregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regionisempty, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regionclipbox, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regsubrect, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regsubregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regaddrect, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regaddregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regintersectrect, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regintersectregion, + {$ifdef FPC}@{$endif}gdi_copyarea, + {$ifdef FPC}@{$endif}gdi_getimage, + {$ifdef FPC}@{$endif}gdi_fonthasglyph, + {$ifdef FPC}@{$endif}gdi_getfont, + {$ifdef FPC}@{$endif}gdi_getfonthighres, + {$ifdef FPC}@{$endif}gdi_freefontdata, + {$ifdef FPC}@{$endif}gdi_gettext16width, + {$ifdef FPC}@{$endif}gdi_getchar16widths, + {$ifdef FPC}@{$endif}gdi_getfontmetrics +); + +function openglgetgdifuncs: pgdifunctionaty; +begin + result:= @gdifunctions; +end; + +{ tglftfontcache } + +procedure tglftfontcache.drawglyph(var drawinfo: drawinfoty; const pos: pointty; + const bitmap: pbitmapdataty); +begin + setrasterpos(drawinfo.gc,pos); + with bitmap^ do begin + gldrawpixels(width,height,gl_alpha,gl_unsigned_byte,@data); + end; +end; + +procedure tglftfontcache.drawstring16(var drawinfo: drawinfoty; + const afont: fontty); +var + rect1: rectty; +begin + with oglgcty(drawinfo.gc.platformdata).d do begin + if df_opaque in drawinfo.gc.drawingflags then begin + if textbackgroundrect(drawinfo,afont,rect1) then begin + with glcolorbackground do begin + glcolor3ub(red,green,blue); + end; + glbegin(gl_quads); + sendrect(drawinfo,rect1); + glend; + end; + end; + glpushclientattrib(gl_client_pixel_store_bit); + glpushattrib(gl_pixel_mode_bit or gl_color_buffer_bit); + glpixelstorei(gl_unpack_row_length, 0); + glpixelstorei(gl_unpack_alignment, 1); + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + with glcolorforeground do begin + glpixeltransferf(gl_red_scale,0); + glpixeltransferf(gl_red_bias,red/255); + glpixeltransferf(gl_green_scale,0); + glpixeltransferf(gl_green_bias,green/255); + glpixeltransferf(gl_blue_scale,0); + glpixeltransferf(gl_blue_bias,blue/255); + end; + end; + inherited; + glpopattrib; + glpopclientattrib; +end; +{ +initialization + gdinumber:= registergdi(openglgetgdifuncs); +} +finalization + freebuffers; +end. diff --git a/mseide-msegui/lib/common/opengl/mseopenglgdiinit.pas b/mseide-msegui/lib/common/opengl/mseopenglgdiinit.pas new file mode 100644 index 0000000..3035e0e --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseopenglgdiinit.pas @@ -0,0 +1,18 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopenglgdiinit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + mseopenglgdi,msegraphics; +initialization + registergdi(openglgetgdifuncs); +end. diff --git a/mseide-msegui/lib/common/opengl/mseopenglwidget.pas b/mseide-msegui/lib/common/opengl/mseopenglwidget.pas new file mode 100644 index 0000000..ce10bdb --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseopenglwidget.pas @@ -0,0 +1,407 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseopenglwidget; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef linux} {$define unix}{$endif} +interface +uses + classes,mclasses,msewindowwidget,msegl, + {$ifdef unix}mseglx,{$ifdef FPC}x,{$endif}xlib,{$else}windows,{$endif} + mseguiintf,msetypes,mseguiglob,mseclasses,msemenus,mseevent,msegui,msegraphics, + msegraphutils; + +{$ifdef unix} +{$ifdef FPC} + {$macro on} + {$define xchar2b:=txchar2b} + {$define xcharstruct:=txcharstruct} + {$define xfontstruct:=txfontstruct} + {$define xfontprop:=txfontprop} + {$define xpoint:=txpoint} + {$define xgcvalues:=txgcvalues} + {$define region:=tregion} + {$define ximage:=tximage} + {$define xwindowattributes:=txwindowattributes} + {$define xclientmessageevent:=txclientmessageevent} + {$define xtype:=_type} + {$define xrectangle:=txrectangle} + {$define keysym:=tkeysym} + {$define xsetwindowattributes:=txsetwindowattributes} + {$define xwindowchanges:=txwindowchanges} + {$define xevent:=txevent} + {$define xfunction:=_function} + {$define xwindow:=window} + {$define xlookupkeysym_:=xlookupkeysymval} + {$define c_class:= _class} + {$define xtextproperty:= txtextproperty} +{$endif} +const + defaultvisualattributes: array[0..8] of integer = + (GLX_RGBA,GLX_RED_SIZE,8,GLX_GREEN_SIZE,8,GLX_BLUE_SIZE,8, + GLX_DOUBLEBUFFER,none); +{$endif} + +type + tcustomopenglwidget = class; + openglwidgeteventty = procedure(const sender: tcustomopenglwidget) of object; + openglrendereventty = procedure(const sender: tcustomopenglwidget; + const aupdaterect: rectty) of object; + + tcustomopenglwidget = class(tcustomwindowwidget) + private + {$ifdef unix} + fcontext: glxcontext; + fdpy: pdisplay; + fcolormap: tcolormap; + fscreen: integer; + {$else} + fdc: hdc; + fcontext: hglrc; + {$endif} + fwin: winidty; + fonrender: openglrendereventty; + {$ifdef unix} + fvisualattributes: integerarty; + {$endif} + fattrib_buffersize: integer; + fattrib_level: integer; + fattrib_rgba: boolean; + fattrib_doublebuffer: boolean; + fattrib_dri: boolean; + fattrib_stereo: boolean; + fattrib_auxbuffers: integer; + fattrib_redsize: integer; + fattrib_greensize: integer; + fattrib_bluesize: integer; + fattrib_alphasize: integer; + fattrib_depthsize: integer; + fattrib_stencilsize: integer; + fattrib_accumredsize: integer; + fattrib_accumgreensize: integer; + fattrib_accumbluesize: integer; + fattrib_accumalphasize: integer; + function setcurrent: boolean; + protected + procedure doclientrectchanged; override; + procedure docreatewinid(const aparent: winidty; const awidgetrect: rectty; + var aid: winidty); override; + procedure dodestroywinid; override; + function canclientpaint: boolean; override; + procedure doclientpaint(const aupdaterect: rectty); override; + procedure updateviewport(const arect: rectty); override; + public + constructor create(aowner: tcomponent); override; + {$ifdef unix} + property visualattributes: integerarty read fvisualattributes + write fvisualattributes; + {$endif} + published + property onrender: openglrendereventty read fonrender write fonrender; + property attrib_buffersize: integer read fattrib_buffersize + write fattrib_buffersize default -1; + property attrib_level: integer read fattrib_level + write fattrib_level default 0; + property attrib_rgba: boolean read fattrib_rgba + write fattrib_rgba default true; + property attrib_doublebuffer: boolean read fattrib_doublebuffer + write fattrib_doublebuffer default true; + property attrib_dri: boolean read fattrib_dri + write fattrib_dri default true; + property attrib_stereo: boolean read fattrib_stereo + write fattrib_stereo default false; + property attrib_auxbuffers: integer read fattrib_auxbuffers + write fattrib_auxbuffers default -1; + property attrib_redsize: integer read fattrib_redsize + write fattrib_redsize default 8; + property attrib_greensize: integer read fattrib_greensize + write fattrib_greensize default 8; + property attrib_bluesize: integer read fattrib_bluesize + write fattrib_bluesize default 8; + property attrib_alphasize: integer read fattrib_alphasize + write fattrib_alphasize default -1; + property attrib_depthsize: integer read fattrib_depthsize + write fattrib_depthsize default -1; + property attrib_stencilsize: integer read fattrib_stencilsize + write fattrib_stencilsize default -1; + property attrib_accumredsize: integer read fattrib_accumredsize + write fattrib_accumredsize default -1; + property attrib_accumgreensize: integer read fattrib_accumgreensize + write fattrib_accumgreensize default -1; + property attrib_accumbluesize: integer read fattrib_accumbluesize + write fattrib_accumbluesize default -1; + property attrib_accumalphasize: integer read fattrib_accumalphasize + write fattrib_accumalphasize default -1; + end; + + topenglwidget = class(tcustomopenglwidget) + published + property onrender; + property optionswidget; + property optionsskin; + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property color; + property cursor; + property frame; + property face; + property anchors; + property taborder; + property hint; + property popupmenu; + property onpopup; + property onshowhint; + property enabled; + property visible; + property fpsmax; + property oncreatewinid; + property ondestroywinid; +// property onclientpaint; + property onclientrectchanged; + property onwindowmouseevent; + property onwindowmousewheelevent; + property ondestroy; + end; + +implementation +uses + sysutils{$ifdef unix}{$ifdef FPC},xutil{$endif}{$endif},mseglextglob; + +{ tcustomopenglwidget } + +constructor tcustomopenglwidget.create(aowner: tcomponent); +begin + fattrib_buffersize:= -1; + fattrib_level:= 0; + fattrib_rgba:= true; + fattrib_doublebuffer:= true; + fattrib_dri:= true; + fattrib_stereo:= false; + fattrib_auxbuffers:= -1; + fattrib_redsize:= 8; + fattrib_greensize:= 8; + fattrib_bluesize:= 8; + fattrib_alphasize:= -1; + fattrib_depthsize:= -1; + fattrib_stencilsize:= -1; + fattrib_accumredsize:= -1; + fattrib_accumgreensize:= -1; + fattrib_accumbluesize:= -1; + fattrib_accumalphasize:= -1; + inherited; +end; + +procedure tcustomopenglwidget.dodestroywinid; +begin + {$ifdef unix} + if fcontext <> nil then begin + glxmakecurrent(fdpy,0,nil); + glxdestroycontext(fdpy,fcontext); + fcontext:= nil; + xfreecolormap(fdpy,fcolormap); + end; + {$else} + if fcontext <> 0 then begin + wglmakecurrent(0,0); + wgldeletecontext(fcontext); + releasedc(fwin,fdc); + end; + {$endif} + inherited; + releaseopengl; +end; + +{ +procedure tcustomopenglwidget.clientrectchanged; +begin + inherited; + checkviewport; +end; +} +procedure tcustomopenglwidget.docreatewinid(const aparent: winidty; + const awidgetrect: rectty; var aid: winidty); +{$ifdef unix} +var + index: integer; + ar1: integerarty; + + procedure putboolean(const atag: integer; avalue: boolean); + begin + if index > high(ar1) then begin + setlength(ar1,19+high(ar1)*2); + end; + if avalue then begin + ar1[index]:= atag; + inc(index); + end; + end; + + procedure putvalue(const atag,avalue,defaultvalue: integer); + begin + if index > high(ar1) then begin + setlength(ar1,19+high(ar1)*2); + end; + if avalue <> defaultvalue then begin + ar1[index]:= atag; + inc(index); + ar1[index]:= avalue; + inc(index); + end; + end; + +var + int1,int2: integer; + visinfo: pxvisualinfo; + attributes: xsetwindowattributes; + +begin + fdpy:= msedisplay; + fscreen:= xdefaultscreen(fdpy); + initializeopengl([]); + if not glxqueryextension(fdpy,int1,int2) then begin + raise exception.create('GLX extension not supported.'); + end; + if fvisualattributes = nil then begin + setlength(ar1,34); + index:= 0; + putboolean(glx_doublebuffer,fattrib_doublebuffer); + putvalue(glx_buffer_size,fattrib_buffersize,-1); + putvalue(glx_level,fattrib_level,0); + putboolean(glx_rgba,fattrib_rgba); + putboolean(glx_stereo,fattrib_stereo); + putvalue(glx_aux_buffers,fattrib_auxbuffers,-1); + putvalue(glx_red_size,fattrib_redsize,-1); + putvalue(glx_green_size,fattrib_greensize,-1); + putvalue(glx_blue_size,fattrib_bluesize,-1); + putvalue(glx_alpha_size,fattrib_alphasize,-1); + putvalue(glx_depth_size,fattrib_depthsize,-1); + putvalue(glx_stencil_size,fattrib_stencilsize,-1); + putvalue(glx_accum_red_size,fattrib_accumredsize,-1); + putvalue(glx_accum_green_size,fattrib_accumgreensize,-1); + putvalue(glx_accum_blue_size,fattrib_accumbluesize,-1); + putvalue(glx_accum_alpha_size,fattrib_accumalphasize,-1); + setlength(ar1,index+1); //none + end + else begin + ar1:= copy(fvisualattributes); + setlength(ar1,high(ar1)+3); //add security nulls + end; + visinfo:= glxchoosevisual(fdpy,fscreen,pinteger(ar1)); + if visinfo = nil then begin + raise exception.create('Could not find visual.'); + end; + fcontext:= glxcreatecontext(fdpy,visinfo,nil,true); + fcolormap:= xcreatecolormap(fdpy,gui_getrootwindow(), + visinfo^.visual,allocnone); + attributes.colormap:= fcolormap; + with awidgetrect do begin + aid:= xcreatewindow(fdpy,aparent,x,y,cx,cy,0,visinfo^.depth, + inputoutput,visinfo^.visual,cwcolormap,@attributes); + xselectinput(fdpy,aid,exposuremask); //will be mapped to parent + end; + fwin:= aid; + xfree(visinfo); + if fcontext = nil then begin +{$else} +var + pixeldesc: tpixelformatdescriptor; + int1: integer; +begin + initializeopengl([]); + aid:= createchildwindow; + fwin:= aid; + fdc:= getdc(fwin); + fillchar(pixeldesc,sizeof(pixeldesc),0); + with pixeldesc do begin + nsize:= sizeof(pixeldesc); + nversion:= 1; + dwflags:= pfd_draw_to_window or pfd_support_opengl; + if fattrib_doublebuffer then begin + dwflags:= dwflags or pfd_doublebuffer; + end; + ipixeltype:= pfd_type_rgba; + ccolorbits:= 24; + cdepthbits:= 32; + end; + int1:= choosepixelformat(fdc,@pixeldesc); + setpixelformat(fdc,int1,@pixeldesc); + fcontext:= wglcreatecontext(fdc); + if fcontext = 0 then begin +{$endif} + raise exception.create('Could not create an OpenGL rendering context.'); + end; + setcurrent; + inherited; +// checkviewport; +end; + +function tcustomopenglwidget.setcurrent: boolean; +begin +{$ifdef unix} + result:= fcontext <> nil; +{$else} + result:= fcontext <> 0; +{$endif} + if result then begin + {$ifdef unix} + glxmakecurrent(fdpy,fwin,fcontext); + {$else} + wglmakecurrent(fdc,fcontext); + {$endif} + end; +end; + +procedure tcustomopenglwidget.updateviewport(const arect: rectty); +begin + if setcurrent then begin + with arect do begin + glviewport(x,y,cx,cy); + end; + end; +end; + +procedure tcustomopenglwidget.doclientpaint(const aupdaterect: rectty); +begin + setcurrent; + if canevent(tmethod(fonrender)) then begin + fonrender(self,aupdaterect); + end; +// glflush; + if fattrib_doublebuffer then begin + {$ifdef unix} + glxswapbuffers(fdpy,fwin); + {$else} + swapbuffers(fdc); + {$endif} + end + else begin + glflush; +// glfinish; + end; +end; + +procedure tcustomopenglwidget.doclientrectchanged; +begin + setcurrent; + inherited; +end; + +function tcustomopenglwidget.canclientpaint: boolean; +begin + result:= assigned(fonrender); +end; + +end. + \ No newline at end of file diff --git a/mseide-msegui/lib/common/pascalscript/msepascalscript.pas b/mseide-msegui/lib/common/pascalscript/msepascalscript.pas new file mode 100644 index 0000000..ece577b --- /dev/null +++ b/mseide-msegui/lib/common/pascalscript/msepascalscript.pas @@ -0,0 +1,435 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepascalscript; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,uPSComponent,uPSCompiler,uPSRuntime,msestrings,mseforms, + mseclasses,typinfo,mselist,uPSPreProcessor; + +type + + tpasc = class(tpsscript) + public + function compilermessagetext: msestring; + function compilermessagear: msestringarty; + end; + + ttestobj = class(tcomponent) + private + fprop: string; + public + constructor create; reintroduce; + procedure testproc; + procedure testproc1; virtual; + property prop: string read fprop write fprop; + end; + + tformscript = class(tpasc) + private + fownercomp: tmsecomponent; + protected + procedure docompimport(Sender: TObject; x: TPSPascalCompiler); + procedure docompile(sender: tpsscript); + procedure doexecimport(Sender: TObject; se: TPSExec; + x: TPSRuntimeClassImporter); + procedure doexecute(sender: tpsscript); + public + constructor create(aowner: tmsecomponent); reintroduce; + end; + + methpropinfoty = record + propinfo: ppropinfo; + instance: tobject; + name: string; + end; + pmethpropinfoty = ^methpropinfoty; + + tmethproplist = class(trecordlist) + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + procedure dosetmethodprop(Reader: TReader; Instance: TPersistent; + PropInfo: PPropInfo; const TheMethodName: string; + var Handled: boolean); + public + constructor create; + procedure additem(const apropinfo: ppropinfo; const ainstance: tobject; + const aname: string); + procedure linkmethods(const ascript: tpasc); + end; + + tpascform = class(tmseform) + private + fscript: tformscript; + fmethlist: tmethproplist; + function getpasc_script: tstrings; + procedure setpasc_script(const avalue: tstrings); + function getpasc_plugins: tpsplugins; + procedure setpasc_plugins(const avalue: tpsplugins); + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure readstate(reader: treader); override; + procedure doafterload; override; + function isscript: boolean; + public + constructor create(aowner: tcomponent; load: boolean); override; + destructor destroy; override; + property script: tformscript read fscript; + published + property pasc_script: tstrings read getpasc_script write setpasc_script; + property pasc_plugins: tpsplugins read getpasc_plugins write setpasc_plugins; + end; + + pascformclassty = class of tpascform; + +function createpascform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function loadpascform(const filename: filenamety): tpascform; + +implementation +uses + msestream,msegui,msesys,sysutils,msetmpmodules,mseobjecttext; + +type + tmsecomponent1 = class(tmsecomponent); + +function loadpascform(const filename: filenamety): tpascform; +var + stream1: ttextstream; + stream2: tmemorystream; +// reader1: treader; +begin + stream1:= nil; + stream2:= nil; + try +// result:= tpascform.create(application,false); + stream1:= ttextstream.create(filename,fm_read); + stream2:= tmemorystream.create; + objecttexttobinarymse(stream1,stream2); + stream2.position:= 0; + result:= tpascform(createtmpmodule('tpascform',stream2)); + finally + stream1.free; + stream2.free; + end; +end; +{ +function loadpascform(const filename: filenamety): tpascform; +var + methlist: tmethproplist; + stream1: ttextstream; + stream2: tmemorystream; + reader1: treader; +begin + methlist:= tmethproplist.create; + stream1:= nil; + stream2:= nil; + reader1:= nil; + beginloadtmpmodule; + try + try + result:= tpascform.create(application,false); + stream1:= ttextstream.create(filename,fm_read); + stream2:= tmemorystream.create; + objecttexttobinarymse(stream1,stream2); + stream2.position:= 0; + reader1:= treader.create(stream2,4048); + reader1.onsetmethodproperty:= @methlist.dosetmethodprop; + reader1.readrootcomponent(result); + if not result.fscript.compile then begin + raise exception.create('Error compiling script of '+result.name+':'+lineend+ + result.fscript.compilermessagetext); + end; + methlist.linkmethods(result.fscript); + addtmpmodule(result); + except + result.free; + raise; + end; + finally + endloadtmpmodule; + reader1.free; + stream1.free; + stream2.free; + methlist.free; + end; +end; +} +function createpascform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= pascformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +{ tmethproplist } + +constructor tmethproplist.create; +begin + inherited create(sizeof(methpropinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +procedure tmethproplist.additem(const apropinfo: ppropinfo; + const ainstance: tobject; const aname: string); +var + info: methpropinfoty; +begin + with info do begin + propinfo:= apropinfo; + instance:= ainstance; + name:= aname; + end; + add(info); +end; + +procedure tmethproplist.dosetmethodprop(Reader: TReader; Instance: TPersistent; + PropInfo: PPropInfo; const TheMethodName: string; + var Handled: boolean); +begin + additem(propinfo,instance,themethodname); + handled:= true; +end; + +procedure tmethproplist.finalizerecord(var item); +begin + finalize(methpropinfoty(item)); +end; + +procedure tmethproplist.copyrecord(var item); +begin + with methpropinfoty(item) do begin + stringaddref(name); + end; +end; + +procedure tmethproplist.linkmethods(const ascript: tpasc); +var + int1: integer; + meth1: tmethod; +begin + for int1:= 0 to count - 1 do begin + with pmethpropinfoty(fdata)[int1] do begin + meth1:= ascript.getprocmethod(struppercase(name)); + setmethodprop(instance,propinfo,meth1); + end; + end; +end; + +{ tpasc } + +function tpasc.compilermessagetext: msestring; +var + int1: integer; +begin + result:= ''; + for int1:= 0 to compilermessagecount - 1 do begin + result:= result+compilermessages[int1].messagetostring + lineend; + end; + if result <> '' then begin + setlength(result,length(result)-length(lineend)); + end; +end; + +function tpasc.compilermessagear: msestringarty; +var + int1: integer; +begin + result:= nil; + setlength(result,compilermessagecount); + for int1:= 0 to compilermessagecount - 1 do begin + result[int1]:= compilermessages[int1].messagetostring; + end; +end; + +{ tpascform } + +constructor tpascform.create(aowner: tcomponent; load: boolean); +begin + fscript:= tformscript.create(self{nil}); + fscript.setsubcomponent(true); + inherited; +end; + +destructor tpascform.destroy; +begin + fmethlist.free; + fscript.free; + inherited; +end; + +function tpascform.isscript: boolean; +begin + result:= (cs_tmpmodule in fmsecomponentstate) and + not (csdesigning in componentstate); +end; + +procedure tpascform.readstate(reader: treader); +begin + if isscript then begin + freeandnil(fmethlist); + fmethlist:= tmethproplist.create; +// try + reader.onsetmethodproperty:= @fmethlist.dosetmethodprop; + inherited; + { + if not fscript.compile then begin + raise exception.create('Error compiling script of '+name+':'+lineend+ + fscript.compilermessagetext); + end; + methlist.linkmethods(fscript); + finally + methlist.free; + end; + } + end + else begin + inherited; + end; +end; + +procedure tpascform.doafterload; +begin + if isscript then begin + try + if not fscript.compile then begin + raise exception.create('Error compiling script of '+name+':'+lineend+ + fscript.compilermessagetext); + end; + fmethlist.linkmethods(fscript); + finally + freeandnil(fmethlist); + end; + end; + inherited; +end; + +class function tpascform.getmoduleclassname: string; +begin + result:= 'tpascform'; +end; + +class function tpascform.hasresource: boolean; +begin + result:= self <> tpascform; +end; + +function tpascform.getpasc_script: tstrings; +begin + result:= fscript.script; +end; + +procedure tpascform.setpasc_script(const avalue: tstrings); +begin + fscript.script.assign(avalue); +end; + +function tpascform.getpasc_plugins: tpsplugins; +begin + result:= fscript.plugins; +end; + +procedure tpascform.setpasc_plugins(const avalue: tpsplugins); +begin + fscript.plugins.assign(avalue); +end; + +{ tformscript } + +constructor tformscript.create(aowner: tmsecomponent); +begin + fownercomp:= aowner; + inherited create(nil); + compileroptions:= [icAllowNoBegin,icAllowNoEnd,icBooleanShortCircuit]; + oncompimport:= @docompimport; + oncompile:= @docompile; + onexecimport:= @doexecimport; + onexecute:= @doexecute; +end; + +procedure tformscript.docompimport(Sender: TObject; x: TPSPascalCompiler); +var + int1: integer; +begin + with fownercomp do begin + with x.addclassn(x.findclass('TCOMPONENT'),'ttestobj') do begin + registermethod('procedure testproc;'); + registermethod('procedure testproc1;'); + registermethod('constructor create;'); + end; + for int1:= 0 to componentcount - 1 do begin + with components[int1] do begin + if x.findclass(classname) = nil then begin + x.addclassn(x.findclass('TCOMPONENT'),classname); + end; + end; + end; + end; +end; + +procedure tformscript.docompile(sender: tpsscript); +var + int1: integer; +begin + with fownercomp do begin + for int1:= 0 to componentcount - 1 do begin + with components[int1] do begin + sender.addregisteredvariable(name,classname); + end; + end; + end; +end; + +procedure tformscript.doexecimport(Sender: TObject; se: TPSExec; + x: TPSRuntimeClassImporter); +begin + with x.add(ttestobj) do begin + registermethod(@ttestobj.testproc,'TESTPROC'); + registervirtualmethod(@ttestobj.testproc1,'TESTPROC1'); + registerconstructor(@ttestobj.create,'CREATE'); + end; +end; + +procedure tformscript.doexecute(sender: tpsscript); +var + int1: integer; + comp1: tcomponent; +begin + with sender do begin + setvartoinstance('SELF',owner); + with fownercomp do begin + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + setvartoinstance(struppercase(comp1.name),comp1); + end; + end; + end; +end; + +{ ttestobj } + +procedure ttestobj.testproc; +begin + msegui.beep; +end; + +procedure ttestobj.testproc1; +begin + msegui.beep; +end; + +constructor ttestobj.create; +begin + inherited create(nil); + name:= 'qwertz'; +end; + +end. diff --git a/mseide-msegui/lib/common/pascalscript/msepascimport.pas b/mseide-msegui/lib/common/pascalscript/msepascimport.pas new file mode 100644 index 0000000..78c26e9 --- /dev/null +++ b/mseide-msegui/lib/common/pascalscript/msepascimport.pas @@ -0,0 +1,11 @@ +unit msepascimport; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + upscomponent,upscomponent_default; +type + tpascdllplugin = class(tpsdllplugin); + tpascimport_classes = class(tpsimport_classes); + tpascimport_dateutils = class(tpsimport_dateutils); +implementation +end. diff --git a/mseide-msegui/lib/common/pascalscript/msepascimportmsegui.pas b/mseide-msegui/lib/common/pascalscript/msepascimportmsegui.pas new file mode 100644 index 0000000..4e46da0 --- /dev/null +++ b/mseide-msegui/lib/common/pascalscript/msepascimportmsegui.pas @@ -0,0 +1,51 @@ +unit msepascimportmsegui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + upscomponent,upscompiler,upsruntime; +type + tpascimportmsegui = class(tpsplugin) + protected + procedure CompOnUses(CompExec: TPSScript); override; + procedure ExecOnUses(CompExec: TPSScript); override; + end; + +procedure registermsegui_c(s: tpspascalcompiler); +procedure registermsegui_r(s: tpsexec); + +implementation +uses + msewidgets,upsutils,msegui; + +procedure registermsegui_c(s: tpspascalcompiler); +begin + with s do begin + addtype('msestring',btwidestring); + adddelphifunction( + 'procedure showmessage1(const atext: msestring; const caption: msestring);'); + adddelphifunction('procedure beep;'); + end; +end; + +procedure registermsegui_r(s: tpsexec); +begin + with s do begin + registerdelphifunction(@showmessage1,'SHOWMESSAGE1',cdregister); + registerdelphifunction(@msegui.beep,'BEEP',cdregister); + end; +end; + +{ tpascimportmsegui } + +procedure tpascimportmsegui.CompOnUses(CompExec: TPSScript); +begin + registermsegui_c(compexec.comp); +end; + +procedure tpascimportmsegui.ExecOnUses(CompExec: TPSScript); +begin + registermsegui_r(compexec.exec); +end; + +end. + diff --git a/mseide-msegui/lib/common/printer/msegdiprint.pas b/mseide-msegui/lib/common/printer/msegdiprint.pas new file mode 100644 index 0000000..9b41567 --- /dev/null +++ b/mseide-msegui/lib/common/printer/msegdiprint.pas @@ -0,0 +1,625 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegdiprint; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +// *********************************************************** +// WARNING +// +// tgdiprinter and twmfprinter are not recommended for production use, +// there are many issues with win32 printing and metafiles. +// Please use tpostscriptprinter instead. +// +// *********************************************************** + +interface +uses + classes,mclasses,mseprinter,msegraphics,msegraphutils,msetypes,msestrings,msedrawtext, + msegui,mseguiglob{$ifdef mswindows},windows{$endif}; +const + mmtoinch = 1/25.4; + defaultgdiprintppmm = mseguiglob.defaultppmm; + screenrefprintername = 'ScreeN'; + +type + {$ifndef mswindows} + henhmetafile = longword; + {$endif} + + tgdiprintcanvas = class(tprintercanvas) + protected + procedure beginpage; override; + procedure endpage; override; + procedure checkgcstate(state: canvasstatesty); override; + function didprint: boolean; virtual; + public + constructor create(const user: tcustomprinter; const intf: icanvas); + procedure drawtext(var info: drawtextinfoty); override; + end; + + tcustomgdiprinter = class(tprinter,icanvas) + private + fppinchx: real; + fppinchy: real; + fpoffsetx: real; + fpoffsety: real; + fprintername: msestring; + protected + function actprintername: msestring; virtual; + procedure creategc(var agc: gcty; const aname: msestring); virtual; + procedure initdevicecaps(const agc: gcty); virtual; + //icanvas + procedure gcneeded(const sender: tcanvas); +// function getmonochrome: boolean; + function getkind: bitmapkindty; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + public + constructor create(aowner: tcomponent); override; + procedure beginprint(const adryrun: boolean = false); override; + procedure endprint; override; + end; + + tgdiprinter = class(tcustomgdiprinter) + published + property printername: msestring read fprintername write fprintername; + //'' -> default printer + end; + +//{$ifdef mswindows} + + twmfprintcanvas = class(tgdiprintcanvas) + private + {$ifdef mswindows} + ffilehandle: henhmetafile; + {$endif} + function getenhmetafile: henhmetafile; + protected + function didprint: boolean; override; + public + constructor create(const user: tcustomprinter; const intf: icanvas); + procedure linktopaintdevice(apaintdevice: paintdevicety; const gc: gcty; + {const size: sizety;} const cliporigin: pointty); override; + property metafilehandle: henhmetafile read getenhmetafile; + end; + + twmfprinter = class(tcustomgdiprinter) + private + frefprintername: msestring; + function getcanvas: twmfprintcanvas; + procedure setcanvas(const avalue: twmfprintcanvas); + protected + function actprintername: msestring; override; + procedure creategc(var agc: gcty; const aname: msestring); override; + function getwindowsize: sizety; override; + procedure initdevicecaps(const agc: gcty); override; + public + constructor create(aowner: tcomponent); override; + published + property canvas: twmfprintcanvas read getcanvas write setcanvas; + property filename: msestring read fprintername write fprintername; + //'' -> memory + property refprintername: msestring read frefprintername write frefprintername; + //'' -> defaultprinter, 'ScreeN' -> default dc + end; + +//{$endif} + +function defaultprinter: msestring; + +implementation +uses + mseguiintf,msedynload,sysutils,msesysintf1,msesys; +var + hasgdiprint: boolean; + +{$ifdef mswindows} +type + WINBOOL = longbool; + DOCINFOW = record + cbSize: longint; + lpszDocName: LPCWSTR; + lpszOutput: LPCWSTR; + lpszDatatype: LPCWSTR; + fwType: DWORD; + end; + TDOCINFOW = DOCINFOW; + PDOCINFOW = ^DOCINFOW; +var + SetWorldTransform: function(_para1:HDC; var _para2:XFORM):WINBOOL; stdcall; + StartDocW: function(_para1:HDC; _para2:PDOCINFOW):longint; stdcall; + GetDefaultPrinterW: function(pszBuffer: pwidechar; + pcchBuffer: pdword): WINBOOL; stdcall; +{$endif} + +{$ifdef mswindows} +procedure checkprinterror(const aresult: integer; const atext: msestring = ''); +begin + if aresult <= 0 then begin + syserror(syelasterror,atext); + end; +end; + +procedure checkprintboolerror(const aresult: boolean; + const atext: msestring = ''); +begin + if not aresult then begin + syserror(syelasterror,atext); + end; +end; +{$endif} + +procedure checkgdiprint; +begin + if not hasgdiprint then begin + exception.create('GDI printing not supported.'); + end; +end; + +{ tgdiprintcanvas } + +constructor tgdiprintcanvas.create(const user: tcustomprinter; + const intf: icanvas); +begin + inherited; + exclude(fstate,cs_internaldrawtext); +end; + +procedure tgdiprintcanvas.drawtext(var info: drawtextinfoty); +begin + if cs_inactive in fstate then exit; + msedrawtext.drawtext(self,info); +end; + +procedure tgdiprintcanvas.beginpage; +begin + initgcvalues; + exclude(fpstate,pcs_matrixvalid); + include(fstate,cs_inactive); + if not (pcs_dryrun in fpstate) and active then begin + exclude(fstate,cs_inactive); + end; + if not (cs_inactive in fstate) then begin + include(fstate,cs_pagestarted); + {$ifdef mswindows} + if not (cs_metafile in fstate) then begin + checkprinterror(startpage(gchandle)); + end; + {$endif} + end; + inherited; +end; + +procedure tgdiprintcanvas.endpage; +begin + inherited; + if not (cs_inactive in fstate) and (cs_pagestarted in fstate) then begin + exclude(fstate,cs_pagestarted); + {$ifdef mswindows} + if not (cs_metafile in fstate) then begin + checkprinterror(windows.endpage(gchandle)); + end; + {$endif} + end; +end; + +procedure tgdiprintcanvas.checkgcstate(state: canvasstatesty); +{$ifdef mswindows} +var + mat1: txform; +{$endif} +begin + inherited; + if not (pcs_matrixvalid in fpstate) then begin +{$ifdef mswindows} + fillchar(mat1,sizeof(mat1),0); + with mat1,tcustomgdiprinter(fprinter) do begin + if printorientation = pao_landscape then begin + em21:= (fppinchx*mmtoinch) / ppmm; + em12:= -(fppinchy*mmtoinch) / ppmm; + edx:= -fpoffsetx + pa_frametop*mmtoinch*fppinchx; + edy:= -fpoffsety + (pa_height - pa_frameleft)*mmtoinch*fppinchy; + end + else begin + em11:= (fppinchx*mmtoinch) / ppmm; + em22:= (fppinchy*mmtoinch) / ppmm; + edx:= -fpoffsetx + pa_frameleft*mmtoinch*fppinchx; + edy:= -fpoffsety + pa_frametop*mmtoinch*fppinchy; + end; + checkprintboolerror(setworldtransform(fdrawinfo.gc.handle,mat1)); + end; +{$endif} + include(fpstate,pcs_matrixvalid); + end; +end; + +function tgdiprintcanvas.didprint: boolean; +begin + result:= fdrawinfo.gc.handle <> 0; +end; + + +{ tcustomgdiprinter } + +constructor tcustomgdiprinter.create(aowner: tcomponent); +begin + if fcanvas = nil then begin +{$warnings off} + fcanvas:= tgdiprintcanvas.create(self,icanvas(self)); +{$warnings on} + end; + inherited; + fcanvas.ppmm:= defaultgdiprintppmm; +end; +{ +function tcustomgdiprinter.getmonochrome: boolean; +begin + result:= false; +end; +} +function tcustomgdiprinter.getkind: bitmapkindty; +begin + result:= bmk_rgb; +end; + +{$ifdef mswindows} + +function tcustomgdiprinter.actprintername: msestring; +begin + if fprintername = '' then begin + result:= defaultprinter; + end + else begin + result:= fprintername; + end; +end; + +procedure tcustomgdiprinter.creategc(var agc: gcty; const aname: msestring); +begin + gdierror(fcanvas.creategc(0,gck_printer,agc,aname),'for "'+aname+'"'); +// gdierror(gui_creategc(0,gck_printer,agc,aname),'for "'+aname+'"'); +end; + +procedure tcustomgdiprinter.initdevicecaps(const agc: gcty); +begin + fppinchx:= getdevicecaps(agc.handle,logpixelsx); + fppinchy:= getdevicecaps(agc.handle,logpixelsy); + fpoffsetx:= getdevicecaps(agc.handle,physicaloffsetx); + fpoffsety:= getdevicecaps(agc.handle,physicaloffsety); +end; + +procedure tcustomgdiprinter.gcneeded(const sender: tcanvas); +var + gc1: gcty; +// mat1: txform; + mstr1: msestring; +begin + checkgdiprint; + if not (sender is tgdiprintcanvas) then begin + guierror(gue_invalidcanvas); + end; + mstr1:= actprintername; + with tgdiprintcanvas(sender) do begin + exclude(fstate,cs_pagestarted); + fillchar(gc1,sizeof(gc1),0); + gc1.paintdevicesize:= getwindowsize; + gc1.kind:= bmk_rgb; + gc1.ppmm:= ppmm; + include(gc1.drawingflags,df_highresfont); + self.creategc(gc1,mstr1); + checkprinterror(setgraphicsmode(gc1.handle,gm_advanced)); + initdevicecaps(gc1); + linktopaintdevice(ptrint(self),gc1,{getwindowsize,}nullpoint); + end; +end; + +procedure tcustomgdiprinter.beginprint(const adryrun: boolean = false); +var + info: tdocinfow; +begin + checkgdiprint; + endprint; + with tgdiprintcanvas(fcanvas) do begin + if adryrun then begin + include(fpstate,pcs_dryrun) + end + else begin + exclude(fpstate,pcs_dryrun); + end; + initprinting; + if not (pcs_dryrun in fpstate) then begin + if not (cs_metafile in fstate) then begin + fillchar(info,sizeof(info),0); + info.cbsize:= sizeof(info); + info.lpszdocname:= pwidechar(fcanvas.title); + checkprinterror(startdocw(fcanvas.gchandle,@info), + 'Can not start print job for "'+fcanvas.title+'".'); + end; + beginpage; + end; + end; +end; + +function defaultprinter: msestring; +const + maxlen = 2048; +var + int1: integer; +begin + checkgdiprint; + int1:= maxlen; + setlength(result,int1); + checkprintboolerror(getdefaultprinterw(pwidechar(result),@int1)); + setlength(result,int1-1); +end; + +{$else} +procedure tcustomgdiprinter.beginprint(const adryrun: boolean = false); +begin + inherited; + checkgdiprint; +end; + +procedure tcustomgdiprinter.gcneeded(const sender: tcanvas); +begin + checkgdiprint; +end; + +function defaultprinter: msestring; +begin + checkgdiprint; + result:= ''; +end; + +function tcustomgdiprinter.actprintername: msestring; +begin + checkgdiprint; + result:= ''; +end; + +procedure tcustomgdiprinter.initdevicecaps(const agc: gcty); +begin + checkgdiprint; +end; + +procedure tcustomgdiprinter.creategc(var agc: gcty; const aname: msestring); +begin + checkgdiprint; +end; + +{$endif} + +procedure tcustomgdiprinter.endprint; +begin + checkgdiprint; + with tgdiprintcanvas(fcanvas) do begin + if didprint then begin + try + try + {$ifdef mswindows} + endpage; + if not (pcs_dryrun in fpstate) then begin + if not (cs_metafile in fstate) then begin + enddoc(gchandle); + end; + end; + {$endif} + finally + unlink; + end; + except + end; + end; + end; + inherited; +end; + +procedure tcustomgdiprinter.getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); +begin + //dummy +end; + +procedure doinit; +var + haserror: boolean; +begin +{$ifdef FPC} + haserror:= false; + {$ifdef mswindows} + if not iswin95 then begin + try + getprocaddresses(getmodulehandle('gdi32'), + [ + 'SetWorldTransform', //0 + 'StartDocW' //1 + ], + [ + {$ifndef FPC}@{$endif}@SetWorldTransform, //0 + {$ifndef FPC}@{$endif}@StartDocW //1 + ]); + except begin + haserror:= true; + end; + end; + if not haserror then begin + try + getprocaddresses(['WINSPOOL.DRV'], + [ + 'GetDefaultPrinterW' //0 + ], + [ + {$ifndef FPC}@{$endif}@GetDefaultPrinterW //0 + ]); + except begin + haserror:= true; + end; + end; + end; + end + else begin + haserror:= true; + end; + {$endif} +{$else} //delphi can not call the correct procedures + haserror:= true; +{$endif} + hasgdiprint:= not haserror; +end; + +{$ifdef mswindows} + +{ twmfprintcanvas } + +constructor twmfprintcanvas.create(const user: tcustomprinter; + const intf: icanvas); +begin + include(fstate,cs_metafile); + inherited; +end; + +procedure twmfprintcanvas.linktopaintdevice(apaintdevice: paintdevicety; + const gc: gcty;{ const size: sizety;} const cliporigin: pointty); +begin + if ffilehandle <> 0 then begin + deleteenhmetafile(ffilehandle); + ffilehandle:= 0; + end; + inherited; +end; + +function twmfprintcanvas.getenhmetafile: henhmetafile; +begin + if ffilehandle = 0 then begin + ffilehandle:= closeenhmetafile(gchandle); + fdrawinfo.gc.handle:= 0; + gdi(gdf_destroygc); + end; + result:= ffilehandle; +end; + +function twmfprintcanvas.didprint: boolean; +begin + result:= (ffilehandle <> 0) or inherited didprint; +end; + +{$else} //mswindows + +constructor twmfprintcanvas.create(const user: tcustomprinter; + const intf: icanvas); +begin + include(fstate,cs_metafile); + inherited; +end; + +procedure twmfprintcanvas.linktopaintdevice(apaintdevice: paintdevicety; + const gc: gcty;{ const size: sizety;} const cliporigin: pointty); +begin + checkgdiprint; +end; + +function twmfprintcanvas.getenhmetafile: henhmetafile; +begin + checkgdiprint; + result:= 0; +end; + +function twmfprintcanvas.didprint: boolean; +begin + checkgdiprint; + result:= false; +end; +{$endif} //not mswindows + +{ twmfprinter } + +constructor twmfprinter.create(aowner: tcomponent); +begin + if fcanvas = nil then begin +{$warnings off} + fcanvas:= twmfprintcanvas.create(self,icanvas(self)); +{$warnings on} + end; + inherited; +end; + +function twmfprinter.getcanvas: twmfprintcanvas; +begin + result:= twmfprintcanvas(fcanvas); +end; + +procedure twmfprinter.setcanvas(const avalue: twmfprintcanvas); +begin + fcanvas.assign(avalue); +end; + +function twmfprinter.getwindowsize: sizety; +begin + result.cx:= round(pa_width*fcanvas.ppmm); + result.cy:= round(pa_height*fcanvas.ppmm); +end; + +procedure twmfprinter.initdevicecaps(const agc: gcty); +begin + inherited; + fpoffsetx:= 0; + fpoffsety:= 0; + exit; + fppinchx:= fppinchx * fcanvas.ppmm/mmtoinch; //paint device is virtual screen + fppinchy:= fppinchx; + fpoffsetx:= 0; + fpoffsety:= 0; +end; + +function twmfprinter.actprintername: msestring; +begin + result:= fprintername; +end; + +{$ifdef mswindows} + +procedure twmfprinter.creategc(var agc: gcty; const aname: msestring); +var + str1: ansistring; +begin + if frefprintername <> screenrefprintername then begin + if frefprintername = '' then begin + str1:= ansistring(defaultprinter); + end + else begin + str1:= ansistring(frefprintername); + end; + end; + agc.refgc:= createdc('WINSPOOL',pansichar(str1),nil,nil); +// agc.refgc:= getdc(0); + try +// guierror(gui_creategc(0,gck_metafile,agc,aname),'for "'+aname+'"'); + gdierror(fcanvas.creategc(0,gck_metafile,agc,aname),'for "'+aname+'"'); + finally + if agc.refgc <> 0 then begin +// releasedc(0,agc.refgc); + deletedc(agc.refgc); + agc.refgc:= 0; + end; + end; +end; + +{$else} //mswindows + +procedure twmfprinter.creategc(var agc: gcty; const aname: msestring); +begin + checkgdiprint; +end; + + +{$endif} //not mswindows + +initialization + doinit; +end. diff --git a/mseide-msegui/lib/common/printer/msepostscriptprinter.pas b/mseide-msegui/lib/common/printer/msepostscriptprinter.pas new file mode 100644 index 0000000..0448b3a --- /dev/null +++ b/mseide-msegui/lib/common/printer/msepostscriptprinter.pas @@ -0,0 +1,2693 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepostscriptprinter; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msegraphics,mseclasses,classes,mclasses,msegraphutils, + msestream,msestrings,msetypes, + msedrawtext,mserichstring,mseprinter,mseguiglob; + +const + defaultimagecachesize = 500000; + defaultimagecachemaxitemsize = 100000; + +type + pspointty = record + x: real; + y: real; + end; + psmatrixty = array [0..2] of array [0..1] of real; + +const + psunitymatrix: psmatrixty = ((1,0), //1 0 0 + (0,1), //0 1 0 + (0,0)); //0 0 1 + +type + tpostscriptcanvas = class; + + tpostscriptprinter = class(tstreamprinter,icanvas) + private + function getcanvas: tpostscriptcanvas; + //icanvas + procedure gcneeded(const sender: tcanvas); + function getkind: bitmapkindty; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + public + constructor create(aowner: tcomponent); override; + property canvas: tpostscriptcanvas read getcanvas; + published + property options default [pro_tempfile]; + end; + + psfontinfoty = record + handle: fontnumty; + namenum: integer; + size: integer; + scalestring1: ansistring; + scalestringfull: ansistring; + rotated: boolean; + codepages: integerarty; + end; + psfontinfoarty = array of psfontinfoty; + + psalignty = (pa_center,pa_lefttop,pa_top,pa_righttop,pa_right, + pa_rightbottom,pa_bottom,pa_leftbottom,pa_left); + pslevelty = (psl_1,psl_2,psl_3); + + imagecachekindty = (ick_1,ick_2,ick_3,ick_4); + imagecachety = record + source: tcanvas; + mask: tcanvas; + kind: imagecachekindty; + sourcerect: rectty; + bytecount: integer; +// rowbytes: integer; + statestamp: longword; + maskstatestamp: longword; + end; + imagecachearty = array of imagecachety; + + tpostscriptcanvas = class(tstreamprintercanvas) + private + ffonts: psfontinfoarty; + ffontnames: stringarty; + fps_pagenumber: integer; + fmapnames: array[0..255] of string; + factfont,factcodepage: integer; +// fstarted: boolean; + flandscape: boolean; + fpslevel: pslevelty; + fimagecache: imagecachearty; + fcacheorder: integerarty; + fimagecacheused: integer; + fimagecachesize: integer; + fimagecachemaxitemsize: integer; + procedure setimagecachesize(const avalue: integer); + procedure setimagecachemaxitemsize(const avalue: integer); + protected + fhaspage: boolean; + procedure gcdestroyed(const sender: tcanvas); override; + procedure freeimagecache(const index: integer); + procedure touchimagecache(const index: integer); + function getimagecache(const akind: imagecachekindty; const asource: tcanvas; + const asourcerect: rectty; out varname: string{; + out arowbytes: integer}): boolean; + //true if found + function setimagecache(const akind: imagecachekindty; + const asource: tcanvas; + const asourcerect: rectty; out varname: string; + const bytes: bytearty; {const arowbytes: integer;} + const amask: tcanvas = nil): boolean; + //true if stored + + function getgdifuncs: pgdifunctionaty; override; + procedure updatescale; override; + procedure initgcstate; override; + procedure initgcvalues; override; + procedure finalizegcstate; override; + procedure checkgcstate(state: canvasstatesty) override; + procedure checkscale; + function encodefontname(const namenum,codepage: integer): string; + function checkfont(const afont: fontnumty; const acodepage: integer): integer; + //returns index in ffonts + function getscalestring(const astyle: fontstylesty): ansistring; + procedure selectfont(const afont: fontnumty; const acodepage: integer); + procedure definefont(const adata: fontnumty; const acodepage: integer); + procedure setpslinewidth(const avalue: integer); + function strokestr: string; + function rectscalestring(const arect: rectty): string; + //transform unity cell to arect + function imagematrixstring(const asize: sizety): string; + + function getcolorstring(const acolor: colorty): string; + function setcolorstring(const acolor: colorty): string; + procedure writebinhex(const data: bytearty); + function psencode(const text: pchar; const count: integer): string; + function getshowstring(const avalue: pmsechar; const count: integer; + fontneeded: boolean = false; + const acolor: colorty = cl_none; + const acolorbackground: colorty = cl_none; + const fontstyle: fontstylesty = []): string; + function createpattern(const sourcerect,destrect: rectty; + const acolorbackground,acolorforeground: colorty; + const acanvas: tcanvas; +// const pixmap: pixmapty; const agchandle: ptruint; + const patname: string): boolean; + //true if ok + procedure handlepoly(const points: ppointty; const lastpoint: integer; + const closed: boolean; const fill: boolean); + procedure handleellipse(const rect: rectty; const fill: boolean); + procedure checkcolorspace; + procedure ps_drawstring16; + procedure ps_drawarc; + procedure ps_destroygc; + procedure ps_changegc; + procedure ps_drawlines; + procedure ps_drawlinesegments; + + procedure ps_fillpolygon; + procedure ps_fillarc; + procedure ps_fillrect; + procedure ps_copyarea; + procedure textout(const text: richstringty; const dest: rectty; + const flags: textflagsty; const tabdist: real); override; + procedure begintextclip(const arect: rectty); override; + procedure endtextclip; override; + procedure beginpage; override; + procedure endpage; override; + function registermap(const acodepage: integer): string; + //returns mapname ('E00' for latin 1) + procedure checkmap(const acodepage: integer); + function gcposstring(const apos: pointty): string; + public + constructor create(const user: tprinter; const intf: icanvas); + + function devpos(const apos: pointty): pspointty; + function posstring(const apos: pointty): string; + function matrixstring(const mat: psmatrixty): string; + function transrotate(const sourcecenter,destcenter: pointty; + const angle: real): string; + function diststring(const adist: integer): string; + function rectsizestring(const asize: sizety): string; + function sizestring(const asize: sizety): string; + function rectstring(const arect: rectty): string; + procedure pscommandbegin(); + procedure pscommandwrite(const atext: string); + procedure pscommandend(); + procedure pscommand(const atext: string); + // writes atext to postscript stream + published + property pslevel: pslevelty read fpslevel write fpslevel default psl_3; + property imagecachesize: integer read fimagecachesize write setimagecachesize + default defaultimagecachesize; + property imagecachemaxitemsize: integer read fimagecachemaxitemsize + write setimagecachemaxitemsize + default defaultimagecachemaxitemsize; + end; + +function psrealtostr(const avalue: real): string; +procedure pstranslate(var mat: psmatrixty; const dist: pspointty); +procedure psretranslate(var mat: psmatrixty; const dist: pspointty); +procedure psscale(var mat: psmatrixty; const scale: pspointty); +procedure psscale(var mat: psmatrixty; const scale: flo64); +procedure psscalex(var mat: psmatrixty; const scale: flo64); +procedure psscaley(var mat: psmatrixty; const scale: flo64); +procedure psrotate(var mat: psmatrixty; const angle: real); //radiant +function pstransform(const mat: psmatrixty; + const apoint: pspointty): pspointty; overload; +function pstransform(const mat: psmatrixty; + const apoint: pointty): pspointty; overload; +function psdist(const source,dest: pspointty): pspointty; overload; +//function psdist(const source,dest: pointty): pspointty; overload; +function pspoint(const apoint: pointty): pspointty; +procedure psnormalizerect(var ll,ur: pspointty); + +implementation +uses + msegui,msesys,sysutils,msedatalist,mseformatstr,mseunicodeps, + mseguiintf,msebits,msefloattostr,msefont,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsimplebitmap1 = class(tsimplebitmap); + tcanvas1 = class(tcanvas); +var + gdifuncs: pgdifunctionaty; + +procedure pstranslate(var mat: psmatrixty; const dist: pspointty); +begin + mat[2,0]:= mat[2,0] + dist.x; + mat[2,1]:= mat[2,1] + dist.y; +end; + +procedure psretranslate(var mat: psmatrixty; const dist: pspointty); +begin + mat[2,0]:= mat[2,0] - dist.x; + mat[2,1]:= mat[2,1] - dist.y; +end; + +procedure psscalex(var mat: psmatrixty; const scale: flo64); +begin + mat[0,0]:= mat[0,0] * scale; + mat[1,0]:= mat[1,0] * scale; + mat[2,0]:= mat[2,0] * scale; +end; + +procedure psscaley(var mat: psmatrixty; const scale: flo64); +begin + mat[0,1]:= mat[0,1] * scale; + mat[1,1]:= mat[1,1] * scale; + mat[2,1]:= mat[2,1] * scale; +end; + +procedure psscale(var mat: psmatrixty; const scale: pspointty); +begin + mat[0,0]:= mat[0,0] * scale.x; + mat[1,0]:= mat[1,0] * scale.x; + mat[2,0]:= mat[2,0] * scale.x; + mat[0,1]:= mat[0,1] * scale.y; + mat[1,1]:= mat[1,1] * scale.y; + mat[2,1]:= mat[2,1] * scale.y; +end; + +procedure psscale(var mat: psmatrixty; const scale: flo64); +begin + mat[0,0]:= mat[0,0] * scale; + mat[1,0]:= mat[1,0] * scale; + mat[2,0]:= mat[2,0] * scale; + mat[0,1]:= mat[0,1] * scale; + mat[1,1]:= mat[1,1] * scale; + mat[2,1]:= mat[2,1] * scale; +end; + +procedure psrotate(var mat: psmatrixty; const angle: real); //radiant +var + si,co: real; + m00,m01,m10,m11,m20,m21: real; +begin + si:= sin(angle); + co:= cos(angle); + m00:= mat[0,0]*co+mat[0,1]*-si; + m01:= mat[0,0]*si+mat[0,1]*co; + m10:= mat[1,0]*co+mat[1,1]*-si; + m11:= mat[1,0]*si+mat[1,1]*co; + m20:= mat[2,0]*co+mat[2,1]*-si; + m21:= mat[2,0]*si+mat[2,1]*co; + mat[0,0]:= m00; + mat[0,1]:= m01; + mat[1,0]:= m10; + mat[1,1]:= m11; + mat[2,0]:= m20; + mat[2,1]:= m21; +end; + +function pstransform(const mat: psmatrixty; const apoint: pspointty): pspointty; +begin + result.x:= mat[0,0]*apoint.x + mat[1,0]*apoint.y + mat[2,0]; + result.y:= mat[0,1]*apoint.x + mat[1,1]*apoint.y + mat[2,1]; +end; + +function pstransform(const mat: psmatrixty; const apoint: pointty): pspointty; +begin + result.x:= mat[0,0]*apoint.x + mat[1,0]*apoint.y + mat[2,0]; + result.y:= mat[0,1]*apoint.x + mat[1,1]*apoint.y + mat[2,1]; +end; + +function psdist(const source,dest: pspointty): pspointty; +begin + result.x:= dest.x - source.x; + result.y:= dest.y - source.y; +end; +{ +function psdist(const source,dest: pointty): pspointty; +begin + result.x:= dest.x - source.x; + result.y:= dest.y - source.y; +end; +} +function pspoint(const apoint: pointty): pspointty; +begin + result.x:= apoint.x; + result.y:= apoint.y; +end; + +procedure psnormalizerect(var ll,ur: pspointty); +var + f1: flo64; +begin + if ll.x > ur.x then begin + f1:= ll.x; + ll.x:= ur.x; + ur.x:= f1; + end; + if ll.y > ur.y then begin + f1:= ll.y; + ll.y:= ur.y; + ur.y:= f1; + end; +end; + +const + pageorientations: array[pageorientationty] of string = ('Portrait','Landscape'); + + imagepatname = 'impat'; + patpatname = 'pat'; + radtodeg = 360/(2*pi); + nl = lineend; + maxlinecharcount = 80; + preamble = +'/rf {'+nl+ //register font: alias,encoding,origname-> +'findfont'+nl+ //alias,encoding,font +'dup length dict '+ //alias,encoding,font,dict +'begin '+nl+ //alias,encoding,font dict is on top of dictstack + '{ 1 index /FID ne'+nl+ //alias,encoding,font,key,value + '{def}'+nl+ //alias,encoding,font + '{pop pop}'+nl+ //alias,encoding,font + 'ifelse'+nl+ + '} forall'+nl+ //alias,encoding + '/Encoding exch def'+nl+ //alias + 'currentdict'+nl+ //alias,dict +'end'+nl+ //alias,dict dict is removed from dictstack +'definefont '+ //dict +'pop'+nl+ // +'} bind def'+nl+ + // +'/sf {'+nl+ //select font: |-> optional + //[alias,scale(x),scaley,rotation,underline,stroke]-> +'dup'+ //[bak],[alias,scale(x),scaley,rotation] +' length 2 ge' + //[bak], length >= 2 + ' {dup'+ //[bak][alias,scale(x),scaley] + ' dup length 3 ge'+nl+ //[bak],[alias,scale(x),scaley],length >= 3 + '{1 2 getinterval aload pop}'+ //[bak],scalex,scaley + ' {1 get dup}'+ //[bak],scale,scale + ' ifelse'+nl+ + 'matrix scale'+ //[bak],smatrix + ' }'+ + ' {matrix}'+ //[bak],umatrix +' ifelse'+nl+ + +' 1 index'+ //[bak],smatrix,[alias,scale(x),scaley,rotation] +' length 4 ge'+ //[bak],smatrix, length >= 4 + ' {1 index'+ //[bak],smatrix,[alias,scale(x),scaley,rotation] + ' 3 get'+ //[bak],smatrix,rotation + ' matrix rotate'+ //[bak],smatrix,rmatrix + ' matrix concatmatrix}'+ +' if'+nl+ + +'1 index'+ //[bak],rmatrix,[alias,scale(x),scaley,rotation,underline,stroke] +' dup length 5 ge' + //[bak],rmatrix, + //[alias,scale(x),scaley,rotation,underline,stroke], length >= 5 +' {dup 4 get}'+ //[bak],rmatrix,[bak],underline +' {0} ifelse'+ //[bak],rmatrix,[bak],0 +' /uli exch def'+nl+ +'dup length 6 ge' + //[bak],rmatrix,[bak] + //[alias,scale(x),scaley,rotation,underline,stroke], length >= 6 +' {5 get}'+ //[bak],rmatrix,strokeout +' {pop 0} ifelse'+ //[bak],rmatrix,0 +' /sou exch def'+nl+ // + +'exch '+ //matrix,[alias] +' 0 get'+ //matrix,alias +' findfont'+ //matrix,font +' exch makefont'+ //font +' dup /FontMatrix get exch'+ //matrix,font +' dup /FontBBox get'+nl+ + //matrix,font,bbox +'aload pop'+ //matrix,font,llx,lly,urx,ury +' 5 index'+ //matrix,font,llx,lly,urx,ury,matrix +' transform'+ //matrix,font,llx,lly,urx',ury' +' /asc exch def pop'+ //matrix,font,llx,lly +' 3 index'+ //matrix,font,llx,lly,matrix +' transform'+ //matrix,font,llx',lly' +' -1 mul'+nl+' /desc exch def pop'+ //matrix,font +' setfont pop'+nl+ +'} bind def'+nl+ + +'/w {'+nl+ //[[text,[font],color,colorbackground],...]-> cx + //[[text,[font],color],...]-> cx + //[[text,[font]],...]-> cx + //[[text],...]-> cx + //calc stringwidth +' currentfont exch'+ //fontbak,inputarray +' 0 exch'+ //fontback,0,inputarray +' {'+ //fontback,sum,[text,[font],color,colorbackground] + ' dup length 2 ge'+ //fontback,sum,[text,[font],color,colorbackground],length>=2 + '{ dup 1 get sf}'+nl+ + 'if'+ //fontback,sum,[text,[font],color,colorbackground] + //set font + ' 0 get'+ //fontback,sum,text + ' stringwidth pop add'+//fontback,sum +' } forall'+ +' exch setfont'+nl+ +'} bind def'+nl+ + +'/s {'+nl+ //[[text,[font],color,colorbackground],...]-> cx + //[[text,[font],color,colorbackground],...]-> cx + //[[text,[font],color],...]-> cx + //[[text,[font]],...]-> cx + //[[text],...]-> cx + //select font, print text, ... +' {'+ + ' currentpoint /ay exch def /ax exch def'+ //backup for underline + ' dup'+ + ' dup length 3 ge'+nl+ //[bak], + //[text,[font],color,colorbackground],length >= 3 + '{dup 2 get'+ //[bak], + //[text,[font],color,colorbackground],[color] + ' aload pop setcolor'+ //[bak], + //[text,[font],color,colorbackground] + ' 0 2 getinterval'+ //[bak], + //[text,[font]] remove color + ' } if'+nl+ + ' dup length 2 eq'+ //array,arraylength = 5 + ' {aload pop sf}'+ //[bak],text + ' {aload pop}'+ //[bak],text + ' ifelse '+nl+ + + ' exch dup length 4 eq'+ //text,[bak],length = 4 + ' {'+ //text,[text,[font],color,colorbackground] + ' [currentcolor] exch'+ //text,[colbackup],[text,[font],color,colorbackground] + ' 3 get'+ //text,[colbackup],[colorbackground] + ' aload pop setcolor exch'+ //[colbackup],text + ' dup stringwidth pop'+nl+//[colbackup],text,width + ' currentpoint currentpoint asc add'+nl+ //[colbackup],text,width,x,y,x,y+asc + ' newpath moveto'+ //[colbackup],text,width,x,y + ' 2 index 0 rlineto'+ + ' 0 0 asc sub desc sub rlineto'+ + ' 0 3 index sub 0 rlineto'+nl+ + ' closepath fill'+ //[colbackup],text,width,x,y + ' moveto'+ //[colbackup],text,width + ' pop'+ //[colbackup],text + ' exch aload pop setcolor'+ //text + ' show'+ + ' }'+nl+ + ' {'+ //text,[text,font,rot,scalex,scaley,color] + ' pop'+ //text + ' show'+ + ' }'+ + ' ifelse'+nl+ + ' uli 0 ne {ul} if'+ //underline + ' sou 0 ne {so} if'+ //strokeout +' } forall'+nl+ +'} bind def'+nl+ + +'/slt {'+nl+ //print lefttop text,llx,lly,urx,ury -> +' asc sub'+ //text,llx,lly,urx,ury-asc +' 3 index'+ //text,llx,lly,urx,ury-asc,llx +' exch moveto currentpoint /ay exch def /ax exch def'+ //backup for underline + //text,llx,lly,urx +' pop pop pop s'+nl+ +'} bind def'+nl+ + +'/cy {'+nl+ //center y text,llx,lly,urx,ury-> text,llx,lly,urx,centeredy +' 2 index sub'+ //text,llx,lly,urx,ury-lly +' dup 0 eq'+nl+ //text,llx,lly,urx,ury-lly,bool + +' {pop 1 index}'+nl+ //text,llx,lly,urx,lly + +' {asc sub desc sub'+//text,llx,lly,urx,ury-lly-asc-desc +' 2 div 2 index'+//text,llx,lly,urx,ury-lly-asc-desc/2,lly +' add desc add}'+nl+ //text,llx,lly,urx,ury-lly-asc-desc/2+lly+desc + +' ifelse'+ +'} bind def'+nl+ + +'/sl {'+nl+ //print left text,llx,lly,urx,ury +' cy'+ //text,llx,lly,urx,centeredy +' 3 index exch'+ //text,llx,lly,urx,llx,ury-lly-asc-desc/2+lly+desc +' moveto '+nl+ +//' currentpoint /ay exch def /ax exch def'+ //backup for underline + //text,llx,lly,urx +' pop pop pop s'+nl+ +'} bind def'+nl+ + +'/sr {'+ //print right text: text,llx,lly,urx,ury-> +' cy'+ //text,llx,lly,urx,centeredy +' exch'+ //text,llx,lly,newy,urx +' 4 index'+nl+ //text,llx,lly,newy,urx,text +' w'+ //text,llx,lly,newy,urx,cx +' sub'+ //text,llx,lly,newy,urx-cx +' exch moveto'+ //text,llx,lly +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly +' pop pop s'+nl+ +'} bind def'+nl+ + +'/sc {'+nl+ //print center text: text,llx,lly,urx,ury -> +' cy'+ //text,llx,lly,urx,centeredy +' 4 index'+ //text,llx,lly,urx,centeredy,text +' w'+ //text,llx,lly,urx,centeredy,cx +' 4 index'+ //text,llx,lly,urx,centeredy,cx,llx +' 3 index'+ //text,llx,lly,urx,centeredy,cx,llx,urx +' exch sub'+ //text,llx,lly,urx,centeredy,cx,urx-llx +' exch sub'+ //text,llx,lly,urx,centeredy,urx-llx-cx +' 2 div'+ //text,llx,lly,urx,centeredy,(urx-llx-cx)/2 +' 4 index add'+nl+ //text,llx,lly,urx,centeredy,(urx-llx-cx)/2+llx +' exch'+ //text,llx,lly,urx,newx,centeredy +' moveto'+nl+ //text,llx,lly,urx +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly,urx +' pop pop pop s'+nl+ +' } bind def'+nl+ + +'/slb {'+nl+ //print lefttop text,llx,lly,urx,ury -> +' pop pop'+ //text,llx,lly +' desc add'+ //text,llx,lly+desc +' moveto'+ +//' currentpoint /ay exch def /ax exch def'+ //backup for underline + //text +' s'+nl+ +'} bind def'+nl+ + +'/srb {'+nl+ //print rightbottom text: text,llx,lly,urx,ury -> +' 4 index'+ //text,llx,lly,urx,ury,text +' w'+ //text,llx,lly,urx,ury,cx +' 2 index'+ //text,llx,lly,urx,ury,cx,urx +' exch'+ //text,llx,lly,urx,ury,urx,cx +' sub'+ //text,llx,lly,urx,ury,urx-cx +' 3 index'+ //text,llx,lly,urx,ury,urx-cx,lly +' desc add'+ //text,llx,lly,urx,ury,urx-cx,lly+desc +' moveto'+nl+ +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly,urx,ury +' pop pop pop pop s'+ +'} bind def'+nl+ + +'/srt {'+nl+ //print righttoptext: text,llx,lly,urx,ury -> +' 4 index'+ //text,llx,lly,urx,ury,text +' w'+ //text,llx,lly,urx,ury,cx +' 2 index'+ //text,llx,lly,urx,ury,cx,urx +' exch'+ //text,llx,lly,urx,ury,urx,cx +' sub'+ //text,llx,lly,urx,ury,urx-cx +' exch'+ //text,llx,lly,urx,urx-cx,ury +' asc sub'+ //text,llx,lly,urx,urx-cx,ury-asc +' moveto'+nl+ +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly,urx +' pop pop pop s'+ +'} bind def'+nl+ + +'/st {'+nl+ //print top text: text,llx,lly,urx,ury -> +' 4 index'+ //text,llx,lly,urx,ury,text +' w'+ //text,llx,lly,urx,ury,cx +' 4 index'+ //text,llx,lly,urx,ury,cx,llx +' 3 index'+ //text,llx,lly,urx,ury,cx,llx,urx +' exch sub'+ //text,llx,lly,urx,ury,cx,urx-llx +' exch sub'+ //text,llx,lly,urx,ury,urx-llx-cx +' 2 div'+ //text,llx,lly,urx,ury,(urx-llx-cx)/2 +' 4 index add'+nl+//text,llx,lly,urx,ury,(urx-llx-cx)/2+llx +' exch'+ //text,llx,lly,urx,newx,ury +' asc sub'+ //text,llx,lly,urx,newx,ury-asc +' moveto'+ //text,llx,lly,urx +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly,urx +' pop pop pop s'+nl+ +'} bind def'+nl+ + +'/sb {'+nl+ //print bottom text: text,llx,lly,urx,ury -> +' 4 index'+ //text,llx,lly,urx,ury,text +' w'+ //text,llx,lly,urx,ury,cx +' 4 index'+ //text,llx,lly,urx,ury,cx,llx +' 3 index'+ //text,llx,lly,urx,ury,cx,llx,urx +' exch sub'+ //text,llx,lly,urx,ury,cx,urx-llx +' exch sub'+ //text,llx,lly,urx,ury,urx-llx-cx +' 2 div'+ //text,llx,lly,urx,ury,(urx-llx-cx)/2 +' 4 index add'+nl+ //text,llx,lly,urx,ury,(urx-llx-cx)/2+llx +' 3 index'+ //text,llx,lly,urx,ury,newx,lly +' desc add'+ //text,llx,lly,urx,ury,newx,lly+desc +' moveto'+ //text,llx,lly,urx,ury +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly,urx,ury +' pop pop pop pop s'+nl+ +'} bind def'+nl+ + +'/ul {'+nl+ //underline +' gsave'+ +' desc 4 div setlinewidth'+ +' 0 setlinecap'+ +' [] 0 setdash'+ +' currentpoint'+ //x,y +' desc 2 div sub'+nl+ //x,y-desc/2 +' dup'+ //x,newy,newy +' 2 index exch'+ //x,newy,x,newy +' moveto'+ //x,newy +' ax exch'+ //x,ax,newy +' lineto stroke'+ //x +' pop'+ +' grestore'+ +'} bind def'+nl+ + +'/so {'+ //strokeout +' gsave'+ +' desc 4 div setlinewidth'+ +' 0 setlinecap'+ +' [] 0 setdash'+ +' currentpoint'+nl+ //x,y +' asc desc add 2 div add desc sub'+ //x,y+asc+desc/2-desc +' dup'+ //x,newy,newy +' 2 index exch'+ //x,newy,x,newy +' moveto'+ //x,newy +' ax exch'+ //x,ax,newy +' lineto stroke'+ //x +' pop'+ +' grestore'+nl+ +'} bind def'+nl+ + +'/tab {'+ //get tabulatorpos: taboffset,tabwidth -> tabx +' currentpoint'+ //o,w,x,y +' pop 2 index sub'+ //o,w,x-o +' 1 index 0.01 add'+ //o,w,x-o,w+0.01 force overflow on equal pos +' add '+ //o,w,x-o+w+0.01 +' 1 index div floor'+ //o,w,tabnum +' mul add'+nl+ //tabbedx +'} bind def'+nl+ + nl; + + alignmentsubs: array[psalignty] of string = ( + //pa_center,pa_lefttop,pa_top,pa_righttop,pa_right, + 'sc', 'slt', 'st', 'srt', 'sr', + //pa_rightbottom,pa_bottom,pa_leftbottom,pa_left + 'srb', 'sb', 'slb', 'sl'); + + tftopa: array [0..15] of psalignty = (//tf_xcentered,tf_right,tf_ycentered,tf_bottom, + pa_lefttop, // 0 0 0 0 + pa_top, // 1 0 0 0 + pa_righttop, // 0 1 0 0 + pa_center, //invalid // 1 1 0 0 + pa_left, // 0 0 1 0 + pa_center, // 1 0 1 0 + pa_right, // 0 1 1 0 + pa_center, //invalid // 1 1 1 0 + pa_leftbottom, // 0 0 0 1 + pa_bottom, // 1 0 0 1 + pa_rightbottom, // 0 1 0 1 + pa_center, //invalid // 1 1 0 1 + pa_center, //invalid // 0 0 1 1 + pa_center, //invalid // 1 0 1 1 + pa_center, //invalid // 0 1 1 1 + pa_center //invalid // 1 1 1 1 + ); + +type + postscriptgcdty = record + canvas: tpostscriptcanvas; + end; + postscriptgcty = record + case integer of + 0: (d: postscriptgcdty); + 1: (_bufferspace: gcpty;); +// res: array[1..23] of longword; + end; + + +procedure gdi_destroygc(var drawinfo: drawinfoty); +begin + try + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_destroygc; + except //trap for stream write errors + end; +end; + +procedure gdi_changegc(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_changegc; +end; + +procedure gdi_drawlines(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_drawlines; +end; + +procedure gdi_drawlinesegments(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_drawlinesegments; +end; + +procedure gdi_drawellipse(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.handleellipse( + drawinfo.rect.rect^,false); +end; + +procedure gdi_drawarc(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_drawarc; +end; + +procedure gdi_fillrect(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_fillrect; +end; + +procedure gdi_fillellipse(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.handleellipse( + drawinfo.rect.rect^,true); +end; + +procedure gdi_fillarc(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_fillarc; +end; + +procedure gdi_fillpolygon(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_fillpolygon; +end; + +procedure gdi_drawstring16(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_drawstring16; +end; + +procedure gdi_setcliporigin(var drawinfo: drawinfoty); +begin +// gdierror(gde_notimplemented); +end; + +procedure gdi_copyarea(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_copyarea; +end; + +var + gdifunctions: gdifunctionaty; + +function psrealtostr(const avalue: real): string; +begin +// result:= replacechar(formatfloat('0.###',avalue),decimalseparator,'.'); + //todo: optimize + result:= ansistring(doubletostring(avalue,-3,fsm_default,'.',#0)); +// result:= formatfloatmse(avalue,'0.000'); +end; + +{ tpostscriptcanvas } + +constructor tpostscriptcanvas.create(const user: tprinter; const intf: icanvas); +begin + fimagecachesize:= defaultimagecachesize; + fimagecachemaxitemsize:= defaultimagecachemaxitemsize; + fpslevel:= psl_3; + inherited create(user,intf); + fdrawinfo.gc.fontgdifuncs:= tcanvas.getclassgdifuncs; +end; + +function tpostscriptcanvas.getgdifuncs: pgdifunctionaty; +begin + result:= @gdifunctions; +end; + +procedure tpostscriptcanvas.checkscale; +begin + if fhaspage then begin + if (printorientation = pao_landscape) xor flandscape then begin + if flandscape then begin + streamwriteln('-90 rotate'); + end + else begin + streamwriteln('90 rotate'); + end; + flandscape:= not flandscape; + end; +{ + streamwrite('initmatrix '); + if printorientation = pao_landscape then begin + streamwrite(' 90 rotate'); + end; + streamwriteln(''); +} + end; +end; + +procedure tpostscriptcanvas.initgcstate; +begin + updatescale; + fps_pagenumber:= 0; + ffonts:= nil; + ffontnames:= nil; + finalize(fmapnames); + with postscriptgcty(fdrawinfo.gc.platformdata).d do begin + canvas:= self; + end; + inherited; + streamwrite( +'%!PS-Adobe-3.0'+nl+ +'%%BoundingBox: '+inttostr(fboundingbox.left)+' '+ + inttostr(fboundingbox.bottom)+' '+ + inttostr(fboundingbox.right)+' '+ + inttostr(fboundingbox.top)+nl+ +'%%Creator: '+ansistring(application.applicationname)+nl+ +'%%Title: '+ansistring(ftitle)+nl+ +'%%DocumentMedia: '+stdpagesizes[fprinter.pa_size].name+' '+ + inttostr(fpapersize.cx)+' '+ + inttostr(fpapersize.cy)+' 0 () ()'+nl+ +'%%Pages: (atend)'+nl+ +'%%PageOrder: Ascend'+nl+ +'%%EndComments'+nl+ +'%%BeginProlog'+nl+ + preamble+fpreamble+nl,true); + if fdeststream = fpreamblestream then begin + streamwrite( +'%%EndProlog'+nl,true); + end; + fpreamble:= ''; + fhaspage:= false; +// fstarted:= true; +// beginpage; +end; + +procedure tpostscriptcanvas.initgcvalues; +begin + inherited; + fimagecache:= nil; +end; + +procedure tpostscriptcanvas.finalizegcstate; +begin + if fdeststream <> fpreamblestream then begin + streamwrite( +'%%EndProlog'+nl,true); + end; + fhaspage:= false; +// fstarted:= false; + inherited; +end; + +procedure tpostscriptcanvas.checkgcstate(state: canvasstatesty); +begin + if (state - [cs_gc] <> []) and not fhaspage then begin + beginpage(); + end; + inherited; +end; + +function tpostscriptcanvas.encodefontname(const namenum,codepage: integer): string; +begin + result:= '/F' + hextostr(longword(codepage),2)+inttostr(namenum)+' '; +end; + +procedure tpostscriptcanvas.definefont(const adata: fontnumty; + const acodepage: integer); +var + str1: string; + int1,int2: integer; + rea1: real; +begin + with getfontdata(adata)^,realfont do begin + str1:= name; + if (str1 = '') or (h.name = 'stf_default') and (str1 = 'sans') then begin + str1:= 'Helvetica'; + end + else begin + str1:= psencode(pchar(str1),length(str1)); + end; + if d.style * [fs_bold,fs_italic] <> [] then begin + str1:= str1 + '-'; + if fs_bold in d.style then begin + str1:= str1 + 'Bold'; + end; + if fs_italic in d.style then begin + str1:= str1 + 'Italic'; + end; + end; + int2:= -1; + for int1:= 0 to high(ffontnames) do begin + if ffontnames[int1] = str1 then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + checkmap(acodepage); + additem(ffontnames,str1); + int2:= high(ffontnames); + //alias,encoding,origname + streamwrite(encodefontname(int2,acodepage)+fmapnames[acodepage]+ + ' ('+str1+') rf' + nl,true); + //register font + end; + setlength(ffonts,high(ffonts)+2); + with ffonts[high(ffonts)] do begin + handle:= adata; + namenum:= int2; + additem(codepages,acodepage); + if d.height = 0 then begin + size:= round(defaultfontheight*ppmm); + end + else begin + size:= (d.height + fontsizeroundvalue) shr fontsizeshift; + end; + rea1:= (size / ppmm) * mmtoprintscale; + scalestring1:= psrealtostr(rea1 * d.xscale); //xscale + scalestringfull:= scalestring1; + str1:= ' ' + psrealtostr(rea1); //yscale + scalestringfull:= scalestringfull + str1; + if (d.xscale <> 1) or (d.rotation <> 0) then begin + scalestring1:= scalestring1 + str1; + end; + str1:= ' ' + psrealtostr(d.rotation*radtodeg); + scalestringfull:= scalestringfull + str1; + if d.rotation <> 0 then begin + scalestring1:= scalestring1 + str1; + end; + end; + end; +end; + +function tpostscriptcanvas.checkfont(const afont: fontnumty; + const acodepage: integer): integer; +var + int1,int2: integer; + bo1: boolean; +begin + int2:= -1; + for int1:= 0 to high(ffonts) do begin + if ffonts[int1].handle = afont then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + definefont(afont,acodepage); + int2:= high(ffonts); + end + else begin + with ffonts[int2] do begin + bo1:= false; + for int1:= 0 to high(codepages) do begin + if codepages[int1] = acodepage then begin + bo1:= true; + break; + end; + end; + if not bo1 then begin + checkmap(acodepage); + streamwrite(encodefontname(namenum,acodepage)+fmapnames[acodepage]+ + ' ('+ffontnames[namenum]+') rf' + nl,true); + //register font + additem(codepages,acodepage); + end; + end; + end; + result:= int2; + factfont:= int2; + factcodepage:= acodepage; +end; + +function tpostscriptcanvas.getscalestring(const astyle: fontstylesty): ansistring; +begin + with ffonts[factfont] do begin + if (astyle * [fs_underline,fs_strikeout] <> []) then begin + result:= scalestringfull; + if fs_underline in astyle then begin + result:= result + ' 1'; + end + else begin + result:= result + ' 0'; + end; + if fs_strikeout in astyle then begin + result:= result + ' 1'; + end; + end + else begin + result:= scalestring1; + end; + end; +end; + +procedure tpostscriptcanvas.selectfont(const afont: fontnumty; const acodepage: integer); +begin + checkfont(afont,acodepage); + streamwrite('['+encodefontname(ffonts[factfont].namenum,acodepage)+ + getscalestring(font.style) + '] sf'+nl); +end; + +procedure tpostscriptcanvas.ps_destroygc; +begin + endpage; + streamwrite( + '%%Trailer'+nl+ + '%%Pages: '+inttostr(fps_pagenumber)+nl+ + '%%EOF'+nl); +end; + +procedure tpostscriptcanvas.ps_changegc; +var + str1: string; + int1,int2: integer; + rect1,rect2: rectty; + ar1: rectarty; +begin + ar1:= nil; //compiler warning + with fdrawinfo,gcvalues^ do begin + if gvm_dashes in mask then begin + int2:= length(lineinfo.dashes); + if (int2 > 0) and (lineinfo.dashes[int2] = #0) then begin + dec(int2); + end; + str1:= '['; + for int1:= 1 to int2 do begin + str1:= str1 + + psrealtostr(mmtoprintscale*(byte(lineinfo.dashes[int1])/ppmm))+' '; + end; + str1:= str1+'] 0 setdash'+nl; + streamwrite(str1); + end; + if (self.brush <> nil) and + ([gvm_brush,gvm_brushorigin] * mask <> []) then begin + with tsimplebitmap1(self.brush) do begin + rect1:= makerect(nullpoint,size); + rect2:= makerect(self.brushorigin,size); + if createpattern(rect1,rect2,acolorbackground,acolorforeground, + canvas{handle,canvas.gchandle},patpatname) then begin + streamwrite('/bru exch def'+nl); + end; + end; + end; + if df_brush in gc.drawingflags then begin + streamwrite('bru setpattern'+nl); + end + else begin + if gvm_colorforeground in mask then begin + streamwrite(setcolorstring(acolorforeground)+nl); + end; + end; + if gvm_font in mask then begin + selectfont(fontnum,0); + end; + if gvm_linewidth in mask then begin + setpslinewidth(lineinfo.width); + end; + if gvm_capstyle in mask then begin + case lineinfo.capstyle of + cs_round: str1:= '1'; + cs_projecting: str1:= '2'; + else str1:= '0'; //cs_butt + end; + streamwrite(str1+' setlinecap'+nl); + end; + if gvm_joinstyle in mask then begin + case lineinfo.joinstyle of + js_round: str1:= '1'; + js_bevel: str1:= '2'; + else str1:= '0'; //js_miter + end; + streamwrite(str1+' setlinejoin'+nl); + end; + if gvm_clipregion in mask then begin + str1:= 'initclip'; + if clipregion <> 0 then begin + ar1:= gui_regiontorects(clipregion); + str1:= str1 + ' ['; + int2:= 3; + for int1:= 0 to high(ar1) do begin + str1:= str1 + ' '+ + gcposstring(addpoint(ar1[int1].pos,gc.cliporigin)) + + ' ' + rectsizestring(ar1[int1].size); + dec(int2); + if int2 <= 0 then begin + int2:= 3; + str1:= str1 + nl; + end; + end; + str1:= str1 + '] rectclip'; + end; + streamwrite(str1+nl); + end; + end; +end; + +function tpostscriptcanvas.gcposstring(const apos: pointty): string; +begin + result:= + psrealtostr(apos.x*fgcscale+fgcoffsetx)+' '+ + psrealtostr(fgcoffsety-apos.y*fgcscale); +end; + +function tpostscriptcanvas.devpos(const apos: pointty): pspointty; +begin + if not (cs_origin in fstate) then begin + checkgcstate([cs_origin]); + end; + result.x:= apos.x*fgcscale+foriginx; + result.y:= foriginy-apos.y*fgcscale; +end; + +function tpostscriptcanvas.posstring(const apos: pointty): string; +var + pt1: pspointty; +begin + pt1:= devpos(apos); + result:= psrealtostr(pt1.x)+' '+ psrealtostr(pt1.y); +end; + +function tpostscriptcanvas.matrixstring(const mat: psmatrixty): string; +begin + result:= '['+psrealtostr(mat[0,0])+' '+psrealtostr(mat[0,1])+' '+ + psrealtostr(mat[1,0])+' '+psrealtostr(mat[1,1])+' '+ + psrealtostr(mat[2,0])+' '+psrealtostr(mat[2,1])+']'; +end; + +function tpostscriptcanvas.transrotate(const sourcecenter,destcenter: pointty; + const angle: real): string; +var + mat1: psmatrixty; +begin + mat1:= psunitymatrix; + psrotate(mat1,angle); + pstranslate(mat1,psdist(pstransform(mat1,devpos(sourcecenter)), + devpos(destcenter))); + result:= matrixstring(mat1) + ' concat'; +end; + +function tpostscriptcanvas.diststring(const adist: integer): string; +begin + result:= psrealtostr(adist*fgcscale); +end; + +function tpostscriptcanvas.sizestring(const asize: sizety): string; +begin + result:= psrealtostr(asize.cx*fgcscale)+' '+psrealtostr(asize.cy*fgcscale); +end; + +function tpostscriptcanvas.rectsizestring(const asize: sizety): string; +begin + result:= psrealtostr(asize.cx*fgcscale)+' '+psrealtostr(-asize.cy*fgcscale); +end; + +function tpostscriptcanvas.rectstring(const arect: rectty): string; +begin + with arect do begin + result:= + psrealtostr(x*fgcscale+foriginx)+' '+ + psrealtostr(foriginy-y*fgcscale)+' '+ + psrealtostr(cx*fgcscale)+' '+psrealtostr(-cy*fgcscale) + end; +end; + +function tpostscriptcanvas.getcolorstring(const acolor: colorty): string; +var + co1: rgbtriplety; +begin + co1:= colortorgb(acolor); + if fcolorspace = cos_rgb then begin + result:= psrealtostr(co1.red/255)+' '+psrealtostr(co1.green/255)+' '+ + psrealtostr(co1.blue/255); + end + else begin + result:= psrealtostr((word(co1.red)+co1.green+co1.blue)/(3.0*255)); + end; +end; + +function tpostscriptcanvas.setcolorstring(const acolor: colorty): string; +begin + if fcolorspace = cos_rgb then begin + result:= getcolorstring(acolor)+' setrgbcolor'; + end + else begin + result:= getcolorstring(acolor)+' setgray'; + end; +end; + +function tpostscriptcanvas.psencode(const text: pchar; const count: integer): string; +var + int1,int2: integer; + ch1: char; + po1: pchar; +begin + setlength(result,count*4); //max + po1:= pchar(pointer(result)); + int2:= 0; + for int1:= 0 to count-1 do begin + ch1:= (text+int1)^; + if (ch1 >= #128) or (ch1 < #32) then begin + if ch1 = #0 then begin + dec(int2); //remove zeroes + end + else begin + (po1+int2)^:= '\'; //octal + (po1+int2+3)^:= char((byte(ch1) and $07) + ord('0')); + ch1:= char(byte(ch1) shr 3); + (po1+int2+2)^:= char((byte(ch1) and $07) + ord('0')); + ch1:= char(byte(ch1) shr 3); + (po1+int2+1)^:= char((byte(ch1) and $03) + ord('0')); + inc(int2,3); + end; + end + else begin + case ch1 of + '\','(',')': begin + (po1+int2)^:= '\'; + inc(int2); + (po1+int2)^:= ch1; + end; + else begin + (po1+int2)^:= ch1; + end; + end; + end; + inc(int2); + end; + setlength(result,int2); +end; + +function tpostscriptcanvas.getshowstring(const avalue: pmsechar; + const count: integer; fontneeded: boolean = false; + const acolor: colorty = cl_none; + const acolorbackground: colorty = cl_none; + const fontstyle: fontstylesty = []): string; +var + int1: integer; + wo1,wo2: word; + po1,po2: pchar; + colback: colorty; + + procedure pushsubstring; + begin + result:= result + '[('+psencode(po2,po1-po2)+')'; + if fontneeded then begin + with ffonts[factfont] do begin +// result:= result + ' ['+encodefontname(namenum,factcodepage) + scalestring1+']'; + result:= result + ' ['+encodefontname(namenum,factcodepage) + + getscalestring(fontstyle)+']'; + end; + end; + if acolor <> cl_none then begin + result:= result+'['+getcolorstring(acolor)+']'; + end; + if colback <> cl_transparent then begin + if acolor = cl_none then begin + result:= result + '[currentcolor]'; + end; + result:= result+'['+getcolorstring(colback)+']'; + end; + result:= result +']'; + po1:= po2; + end; + +begin + if acolorbackground <> cl_none then begin + colback:= acolorbackground; + end + else begin + colback:= font.colorbackground; + end; + if (acolor <> cl_none) or (colback <> cl_transparent) then begin + fontneeded:= true; + end; + getmem(po1,count); + po2:= po1; + wo1:= factcodepage shl 8; + result:= ''; + for int1:= 0 to count -1 do begin + wo2:= word(pmsecharaty(avalue)^[int1]); + if (wo2 xor wo1) and $ff00 <> 0 then begin + if int1 <> 0 then begin + pushsubstring; + end; + fontneeded:= true; + wo1:= wo2 and $ff00; + checkfont(ffonts[factfont].handle,wo1 shr 8); + end; + po1^:= char(wo2); + inc(po1); + end; + pushsubstring; + freemem(po2); +end; + +procedure tpostscriptcanvas.ps_drawstring16; +begin + if active then begin + with fdrawinfo.text16pos do begin + streamwrite(posstring(pos^)+' moveto ['+getshowstring(text,count)+'] s'+nl); + end; + end; +end; + +procedure tpostscriptcanvas.textout(const text: richstringty; const dest: rectty; + const flags: textflagsty; const tabdist: real); +const + fontstylemask{: newinfosty} = [ni_bold,ni_italic,ni_underline,ni_strikeout]; + mask1 = [tf_xcentered,tf_right]; + mask2 = [tf_ycentered,tf_bottom]; +var + str1: ansistring; + int1,int2,int3: integer; + co1,co2: colorty; + colorchanged: boolean; + style1: fontstylesty; + lastbreak: integer; + rect1: rectty; + + procedure addstring(const astring: ansistring); + begin + if (length(str1) - lastbreak) + length(astring) > maxlinecharcount then begin + str1:= str1+ nl; + lastbreak:= length(str1); + end; + str1:= str1+astring; + end; +var + pt1: pointty; + rea1: real; +begin + if not active {or (text.text = '')} then begin + exit; + end; + colorchanged:= false; + str1:= ''; + if flags * [tf_rotate90,tf_rotate180] <> [] then begin + str1:= 'matrix currentmatrix'+nl; //backup + pt1:= dest.pos; + if tf_rotate90 in flags then begin + if tf_rotate180 in flags then begin + rea1:= pi*3.0/2.0; + pt1.x:= pt1.x+dest.cx; + end + else begin + rea1:= pi/2.0; + pt1.y:= pt1.y+dest.cy; + end; + end + else begin + rea1:= pi; + pt1.x:= pt1.x+dest.cx; + pt1.y:= pt1.y+dest.cy; + end; + str1:= str1+transrotate(dest.pos,pt1,rea1)+nl; + end; + lastbreak:= 0; + str1:= str1+'['; + if (text.format = nil) or (text.text = '') then begin + addstring(getshowstring(pmsechar(text.text),length(text.text), + true,cl_none,cl_none,font.style)+'] '); + end + else begin + gcfonthandle1:= 0; //invalid after print + with text.format[0] do begin + if index > 0 then begin + addstring(getshowstring(pmsechar(pointer(text.text)),index)); + end; + end; + co1:= cl_none; + co2:= cl_none; + style1:= font.style; + for int1:= 0 to high(text.format) do begin + with text.format[int1] do begin + if int1 = high(text.format) then begin + int3:= bigint; + end + else begin + int3:= text.format[int1+1].index; + end; + if int3 > length(text.text) then begin + int3:= length(text.text); + end; + int2:= index + 1; + if int2 > length(text.text) then begin + int2:= length(text.text); + end; + if newinfos * fontstylemask <> [] then begin + style1:= style1 * fontstylesty( + {$ifndef FPC}byte({$endif} + not {$ifdef FPC}longword{$else}word{$endif}(newinfos)) + {$ifndef FPC}){$endif} + style.fontstyle; + end; + font.style:= style1; + checkfont(font.handle,(word(text.text[int2]) and $ff00) shr 8); + int2:= int3 - index; + if int2 > 0 then begin + if ni_fontcolor in newinfos then begin + if style.fontcolor = 0 then begin + co1:= font.color; + colorchanged:= false; + end + else begin + co1:= not style.fontcolor; + colorchanged:= true; + end; + end; + if ni_colorbackground in newinfos then begin + if style.colorbackground = 0 then begin + co2:= cl_none; + end + else begin + co2:= not style.colorbackground; + end; + end; + addstring(getshowstring(pmsechar(pointer(text.text))+index,int2,true,co1,co2, + style1)); + end; + end; + end; + str1:= str1 + '] '; + end; + if tf_rotate90 in flags then begin + rect1.pos:= dest.pos; + rect1.cx:= dest.cy; + rect1.cy:= dest.cx; + end + else begin + rect1:= dest; + end; + if tabdist = 0 then begin + str1:= str1 + posstring(makepoint(rect1.x,rect1.y+rect1.cy))+' '+ //lower left + posstring(makepoint(rect1.x+rect1.cx,rect1.y))+ ' '; //upper right + end + else begin + if tabdist < 0 then begin //last pos + str1:= str1 + 'currentpoint pop '; //oldx (llx) + end + else begin //defaulttab + str1:= str1 + psrealtostr(foriginx)+' '+psrealtostr(tabdist) + ' tab '; + //tabbedx (llx) + end; + str1:= str1 + psrealtostr(foriginy-(rect1.y+rect1.cy)*fgcscale)+ + //llx,lly + ' 1 index '+ //llx,lly,urx + psrealtostr(foriginy-(rect1.y)*fgcscale)+' '; //llx,lly,urx,ury + end; + int1:= (longword(flags*mask1) shr 1) or + (longword(flags*mask2) shr 3); + //remove tf_left, tf_xjustify and tf_top + str1:= str1+alignmentsubs[tftopa[int1]]; +{ + if fs_underline in font.style then begin + str1:= str1 + ' ul'; + end; + if fs_strikeout in font.style then begin + str1:= str1 + ' so'; + end; +} + if colorchanged then begin + str1:= str1 + ' '+setcolorstring(font.color); + end; + if flags * [tf_rotate90,tf_rotate180] <> [] then begin + str1:= str1+nl+'setmatrix'; //restore CTM + end; + streamwrite(str1+nl); +end; + +procedure tpostscriptcanvas.begintextclip(const arect: rectty); +begin + streamwrite('gsave '+rectstring(arect)+' rectclip'+nl); +end; + +procedure tpostscriptcanvas.endtextclip; +begin + streamwrite('grestore'+nl); +end; + +procedure tpostscriptcanvas.setpslinewidth(const avalue: integer); +var + rea1: real; +begin + if avalue = 0 then begin + rea1:= nulllinewidth; + end + else begin + rea1:= avalue/(ppmm*(1 shl linewidthshift)) * mmtoprintscale; + end; + streamwrite(psrealtostr(rea1)+' setlinewidth'+nl); +end; + +function tpostscriptcanvas.strokestr: string; +begin + if (length(dashes) > 0) and (df_opaque in fdrawinfo.gc.drawingflags) then begin + //(dashes[length(dashes)] = #0) then begin + result:= 'gsave [] 0 setdash ' + setcolorstring(fdrawinfo.acolorbackground) + + ' stroke grestore stroke'; //draw background + end + else begin + result:= 'stroke'; + end; +end; + +procedure tpostscriptcanvas.handlepoly(const points: ppointty; + const lastpoint: integer; const closed: boolean; const fill: boolean); +var + int1: integer; + str1,str2: string; +begin + if active then begin + str1:= ''; + str2:= 'newpath '+ posstring(points^) + ' moveto '+nl; + for int1:= 1 to lastpoint do begin + if length(str1) > 80 then begin + str2:= str2 + str1 + nl; + str1:= ''; + end; + str1:= str1 + posstring(ppointaty(points)^[int1])+' lineto '; + end; + str2:= str2 + str1 + nl; + if closed then begin + str2:= str2 + 'closepath '; + end; + if fill then begin + str2:= str2 + 'fill'; + end + else begin + str2:= str2 + strokestr; + end; + streamwrite(str2+nl); + end; +end; + +procedure tpostscriptcanvas.handleellipse(const rect: rectty; const fill: boolean); +var + str1: string; +begin + with rect do begin + str1:= 'newpath '; + if cy = cx then begin + str1:= str1+posstring(pos)+' '+diststring(cx div 2)+' 0 360 arc '; + end + else begin + str1:= str1 + 'matrix currentmatrix '+ posstring(pos) + ' translate '+nl+ + sizestring(size)+' scale 0 0 0.5 0 360 arc setmatrix '; + end; + end; + str1:= str1 + 'closepath '; + if fill then begin + str1:= str1 + 'fill'; + end + else begin + str1:= str1 + strokestr; + end; + streamwrite(str1+nl); +end; + +procedure tpostscriptcanvas.ps_drawarc; +var + str1: string; +begin + with fdrawinfo.arc,rect^ do begin + str1:= 'newpath '; + if cy = cx then begin + str1:= str1+posstring(pos)+' '+diststring(cx div 2)+' '+ + psrealtostr(startang*radtodeg)+' '+psrealtostr((startang+extentang)*radtodeg)+ + ' arc '; + end + else begin + str1:= str1 + 'matrix currentmatrix '+ posstring(pos) + ' translate '+nl+ + sizestring(size)+' scale 0 0 0.5 '+ + psrealtostr(startang*radtodeg)+' '+psrealtostr((startang+extentang)*radtodeg)+ + ' arc setmatrix '; + end; + end; + str1:= str1 + strokestr; + streamwrite(str1+nl); +end; + +procedure tpostscriptcanvas.ps_fillarc; +var + str1: string; +begin + with fdrawinfo.arc,rect^ do begin + str1:= 'newpath '; + if pieslice then begin + str1:= str1+posstring(pos)+' moveto '; + end; + if cy = cx then begin + str1:= str1+posstring(pos)+' '+diststring(cx div 2)+' '+ + psrealtostr(startang*radtodeg)+' '+psrealtostr((startang+extentang)*radtodeg)+ + ' arc '; + end + else begin + str1:= str1 + 'matrix currentmatrix '+ posstring(pos) + ' translate '+nl+ + sizestring(size)+' scale 0 0 0.5 '+ + psrealtostr(startang*radtodeg)+' '+psrealtostr((startang+extentang)*radtodeg)+ + ' arc setmatrix '; + end; + end; + str1:= str1 + 'closepath fill'; + streamwrite(str1+nl); +end; + +procedure tpostscriptcanvas.ps_drawlines; +begin + with fdrawinfo.points do begin + handlepoly(points,count-1,closed,false); + end; +end; + +procedure tpostscriptcanvas.ps_drawlinesegments; +var + int1: integer; +begin + with fdrawinfo.points do begin + for int1:= 0 to count div 2 - 1 do begin + handlepoly(points,1,false,false); + inc(points,2); + end; + end; +end; + +procedure tpostscriptcanvas.ps_fillpolygon; +begin + with fdrawinfo.points do begin + handlepoly(points,count-1,true,true); + end; +end; + +procedure tpostscriptcanvas.ps_fillrect; +var + points1: array[0..3] of pointty; +begin + with fdrawinfo.rect.rect^ do begin + points1[0].x:= x; + points1[0].y:= y; + points1[1].x:= x+cx; + points1[1].y:= y; + points1[2].x:= x+cx; + points1[2].y:= y+cy; + points1[3].x:= x; + points1[3].y:= y+cy; + handlepoly(@points1,high(points1),true,true); + end; +end; + +procedure tpostscriptcanvas.writebinhex(const data: bytearty); +var + int1,int2,int3: integer; + po1: pbyte; + po2: pchar; + str1: string; +begin + po1:= pointer(data); + int2:= length(data); + setlength(str1,80); + repeat + int1:= 40; + if int1 > int2 then begin + int1:= int2; + setlength(str1,2*int1); + end; + po2:= pchar(str1); + for int3:= int1 - 1 downto 0 do begin + po2^:= charhex[po1^ shr 4]; + inc(po2); + po2^:= charhex[po1^ and $0f]; + inc(po2); + inc(po1); + end; + dec(int2,40); + streamwriteln(str1); + until int2 <= 0; +end; + +function tpostscriptcanvas.rectscalestring(const arect: rectty): string; + //transform unity cell to arect +begin + with arect do begin + result:= psrealtostr(x*fgcscale+foriginx)+' '+ + psrealtostr(foriginy-(y+cy{-1})*fgcscale)+' translate '+ + psrealtostr(cx*fgcscale)+' '+psrealtostr(cy*fgcscale)+' scale'; + end; +end; + +function tpostscriptcanvas.imagematrixstring(const asize: sizety): string; +var + str1: string; +begin + with asize do begin + str1:= inttostr(cy); + result:= '['+inttostr(cx)+' 0 0 -'+str1+' 0 '+str1+']'; + end; +end; + +const + unityrectpath = 'newpath 0 0 moveto 1 0 lineto 1 1 lineto 0 1 lineto closepath'; + +procedure convertrgb(const sourcerect: rectty; const image: imagety; + out data: bytearty; out rowbytes: integer); +var + po1: prgbtriplety; + po2,po3: pbyte; + int1,int2: integer; +begin + with sourcerect do begin + rowbytes:= cx*3; + setlength(data,rowbytes*cy); + po2:= pointer(data); + if image.kind = bmk_rgb then begin + for int1:= y to y + cy - 1 do begin + po1:= @image.pixels^[int1*image.size.cx+x]; + for int2:= x to x + cx - 1 do begin + po2^:= po1^.red; + inc(po2); + po2^:= po1^.green; + inc(po2); + po2^:= po1^.blue; + inc(po2); + inc(po1); + end; + end; + end + else begin //bmk_gray + for int1:= y to y + cy - 1 do begin + po3:= pointer(image.pixels)+ int1*image.linebytes + x; + for int2:= x to x + cx - 1 do begin + po2^:= po3^; + inc(po2); + po2^:= po3^; + inc(po2); + po2^:= po3^; + inc(po2); + inc(po3); + end; + end; + end; + end; +end; + +procedure convertgray(const sourcerect: rectty; const image: imagety; + out data: bytearty; out rowbytes: integer); +var + po1: prgbtriplety; + po2,po3: pbyte; + int1,int2: integer; +begin + with sourcerect do begin + rowbytes:= cx; + setlength(data,rowbytes*cy); + po2:= pointer(data); + if image.kind = bmk_rgb then begin + for int1:= y to y + cy - 1 do begin + po1:= @image.pixels^[int1*image.size.cx+x]; + for int2:= x to x + cx - 1 do begin + po2^:= (po1^.red + po1^.green + po1^.blue) div 3; + inc(po2); + inc(po1); + end; + end; + end + else begin //bmk_gray + for int1:= y to y + cy - 1 do begin + po3:= pointer(image.pixels) + int1*image.linebytes + x; + for int2:= x to x + cx - 1 do begin + po2^:= po3^; + inc(po2); + inc(po3); + end; + end; + end; + end; +end; + +procedure convertmono(const sourcerect: rectty; const image: imagety; + out data: bytearty; out rowbytes: integer); +var + sourcerowstep: integer; + rowshiftleft,rowshiftright: byte; + po1,po2: pbyte; + int1,int2: integer; +begin + with sourcerect do begin + rowbytes:= (cx + 7) div 8; + setlength(data,rowbytes*cy); + rowshiftright:= x and $7; + rowshiftleft:= 8-rowshiftright; + sourcerowstep:= ((image.size.cx + 31) div 32)*4; + po1:= @pbyteaty(image.pixels)^[y * sourcerowstep + x div 8]; + sourcerowstep:= sourcerowstep - rowbytes; + po2:= pointer(data); + for int1:= cy - 1 downto 0 do begin + for int2:= rowbytes - 1 downto 0 do begin + po2^:= (po1^ shr rowshiftright); + inc(po1); + po2^:= bitreverse[po2^ or byte(po1^ shl rowshiftleft)]; + //byte(... needed for FPC! + inc(po2); + end; + inc(po1,sourcerowstep); + end; + end; +end; + +procedure convertmonotogray(const sourcerect: rectty; var image: imagety; + out data: bytearty; out rowbytes: integer; + const colorforeground,colorbackground: colorty); +var + grf,grb: byte; + po1: pbyte; + po2: pbyte; + int1,int2: integer; + ar1: bytearty; + rowb: integer; + by1: byte; +begin + convertmono(sourcerect,image,ar1,rowb); +// image.monochrome:= false; + image.kind:= bmk_rgb; + with colortorgb(colorforeground) do begin + grf:= (red + green + blue) div 3; + end; + with colortorgb(colorbackground) do begin + grb:= (red + green + blue) div 3; + end; + with sourcerect do begin + rowbytes:= cx; + setlength(data,rowbytes*cy); + po2:= pointer(data); + for int1:= 0 to cy - 1 do begin + po1:= @ar1[int1*rowb]; + for int2:= 0 to cx - 1 do begin + by1:= bytebitsreverse[int2 and $7]; + if po1^ and by1 = 0 then begin + po2^:= grb; + end + else begin + po2^:= grf; + end; + inc(po2); + if by1 = $01 then begin + inc(po1); + end; + end; + end; + end; +end; + +procedure convertmonotorgb(const sourcerect: rectty; var image: imagety; + out data: bytearty; out rowbytes: integer; + const colorforeground,colorbackground: colorty); +var + rgbf,rgbb: rgbtriplety; + po1: pbyte; + po2: pbyte; + int1,int2: integer; + ar1: bytearty; + rowb: integer; + by1: byte; + po3: prgbtriplety; +begin + convertmono(sourcerect,image,ar1,rowb); +// image.monochrome:= false; + image.kind:= bmk_rgb; + rgbf:= colortorgb(colorforeground); + rgbb:= colortorgb(colorbackground); + with sourcerect do begin + rowbytes:= cx*3; + setlength(data,rowbytes*cy); + po2:= pointer(data); + for int1:= 0 to cy - 1 do begin + po1:= @ar1[int1*rowb]; + for int2:= 0 to cx - 1 do begin + by1:= bytebitsreverse[int2 and $7]; + if po1^ and by1 = 0 then begin + po3:= @rgbb; + end + else begin + po3:= @rgbf; + end; + po2^:= po3^.red; + inc(po2); + po2^:= po3^.green; + inc(po2); + po2^:= po3^.blue; + inc(po2); + if by1 = $01 then begin + inc(po1); + end; + end; + end; + end; +end; + +function tpostscriptcanvas.createpattern(const sourcerect,destrect: rectty; + const acolorbackground,acolorforeground: colorty; + const acanvas: tcanvas; + {const pixmap: pixmapty; const agchandle: ptruint;} + const patname: string): boolean; + //returns pattern dict on ps stack +var + ar1: bytearty; + str1: string; +// components: integer; + rowbytes: integer; + varname: string; + image: imagety; + cached: boolean; +begin + result:= true; + rowbytes:= 0; + ar1:= nil; + cached:= getimagecache(ick_3,acanvas,sourcerect,varname{,rowbytes}); + if not cached then begin + gdi_lock; + // result:= gdi_pixmaptoimage(pixmap,image,agchandle) = gde_ok; + result:= gui_pixmaptoimage(acanvas.paintdevice,image,acanvas.gchandle) = gde_ok; + gdi_unlock; + if not result then begin + exit; + end; +// components:= 1; + if acanvas.kind = bmk_mono then begin + convertmono(sourcerect,image,ar1,rowbytes); + end + else begin + if colorspace = cos_gray then begin + convertgray(sourcerect,image,ar1,rowbytes); + end + else begin +// components:= 3; + convertrgb(sourcerect,image,ar1,rowbytes); + end; + end; + gui_freeimagemem(image.pixels); + if length(ar1) > 60000 then begin + result:= false; + exit; + end; + cached:= setimagecache(ick_3,acanvas,sourcerect,varname,ar1{,rowbytes}); + end; + if cached then begin + str1:= '/'+patname+' '+varname+' def '; + end + else begin + str1:= '/'+patname+' '+inttostr(rowbytes*sourcerect.cy)+' string def'+nl+ + 'currentfile '+patname+' readhexstring'+nl; + streamwrite(str1); + writebinhex(ar1); + str1:= 'pop pop '; + end; + str1:= str1+'gsave '+rectscalestring(destrect)+nl+ +'<< /PatternType 1 /PaintType 1 /TilingType 1 /BBox [0 0 1 1] /XStep 1 /YStep 1'+nl+ +'/PaintProc {' + nl; + if acanvas.kind = bmk_mono then begin + if acolorbackground <> cl_transparent then begin + str1:= str1 + unityrectpath + nl + + setcolorstring(acolorbackground) + ' fill '; + end; + str1:= str1 + setcolorstring(acolorforeground) + nl; + end; + str1:= str1 + + inttostr(sourcerect.size.cx) + ' ' + inttostr(sourcerect.size.cy); + if acanvas.kind = bmk_mono then begin + str1:= str1 + ' true '; + end + else begin + str1:= str1 + ' 8'; + end; + str1:= str1 + imagematrixstring(sourcerect.size)+ ' '+patname+' '; + if acanvas.kind = bmk_mono then begin + str1:= str1 + 'imagemask'; + end + else begin + if colorspace = cos_gray then begin + str1:= str1 + 'image'; + end + else begin + str1:= str1 + 'false 3 colorimage'; + end; + end; + str1:= str1+' } bind >> matrix makepattern grestore'+nl; + streamwrite(str1); +end; + +procedure tpostscriptcanvas.checkcolorspace; +begin + if not (cs_acolorforeground in fstate) then begin + streamwrite(setcolorstring(color)+nl); //init colorspace + include(fstate,cs_acolorforeground); + end; +end; + +procedure tpostscriptcanvas.ps_copyarea; +var + mono: boolean; + cached: boolean; + varname: string; + + function imagedict: string; + begin + with fdrawinfo.copyarea.sourcerect^ do begin + result:= setcolorstring(fdrawinfo.acolorforeground)+nl+ + ' << /ImageType 1 /Width '+inttostr(size.cx)+ + ' /Height '+inttostr(size.cy)+' /ImageMatrix '+imagematrixstring(size)+nl; + if cached then begin + result:= result + '/DataSource '+varname+nl; + end + else begin + result:= result + '/DataSource {currentfile picstr readhexstring pop}'+nl; + end; + result:= result + '/BitsPerComponent '; + end; + if mono{image.monochrome} then begin + result:= result+'1 '; + end + else begin + result:= result+'8 '; + end; + result:= result+'/Decode '; + if mono{image.monochrome} then begin + result:= result + '[1 0] '; + end + else begin + if colorspace = cos_gray then begin + result:= result + '[0 1] '; + end + else begin + result:= result + '[0 1 0 1 0 1] '; + end; + end; + if al_intpol in fdrawinfo.copyarea.alignment then begin + result:= result + '/Interpolate true '; + end; + result:= result + '>>'+nl; + end; + +var + ar1,ar2,ar3: bytearty; + str1: string; +// components: integer; + rowbytes,maskrowbytes: integer; + masked: boolean; + maskcopy: boolean; + maskbefore: tsimplebitmap; + po1,po2,po3: pbyte; + int1: integer; + image: imagety; +label + endlab; +begin + with fdrawinfo,copyarea do begin + if not (df_canvasispixmap in tcanvas1(source).fdrawinfo.gc.drawingflags) then begin + exit; + end; + mono:= source.kind = bmk_mono; + subpoint1(destrect^.pos,origin); //map to pd origin + maskcopy:= mono and (mask <> nil) and (mask.kind = bmk_mono) and + ((acolorforeground = cl_transparent) or + (acolorbackground = cl_transparent)); + maskbefore:= mask; //compiler warning + if maskcopy then begin + mask:= tsimplebitmap.create(bmk_mono{true}); + mask.size:= sourcerect^.size; + mask.canvas.copyarea(maskbefore.canvas,sourcerect^,nullpoint); + if acolorbackground = cl_transparent then begin + mask.canvas.copyarea(source,sourcerect^,nullpoint,rop_and); + end; + if acolorforeground = cl_transparent then begin + mask.canvas.copyarea(source,sourcerect^,nullpoint,rop_notand); + end; + end; + try + checkcolorspace; + masked:= (mask <> nil) and ((mask.kind = bmk_mono) {or (fpslevel >= psl_3)}); + //color masks not implemented in postscript + if masked then begin + if (fpslevel >= psl_3) then begin + cached:= not maskcopy and getimagecache(ick_4,source,sourcerect^,varname); + if not cached then begin + with tcanvas1(source).fdrawinfo do begin + gdi_lock; + if gui_pixmaptoimage(tsimplebitmap1(mask).handle,image, + mask.canvas.gchandle) <> gde_ok then begin + goto endlab; + end; + gdi_unlock; + if mask.kind = bmk_mono then begin + convertmono(sourcerect^,image,ar2,maskrowbytes); + end + else begin + if colorspace = cos_gray then begin + convertgray(sourcerect^,image,ar2,maskrowbytes); + end + else begin + convertrgb(sourcerect^,image,ar2,maskrowbytes); + end; + end; + gui_freeimagemem(image.pixels); + gdi_lock; + if gui_pixmaptoimage(paintdevice,image,gc.handle) <> gde_ok then begin + goto endlab; + end; + gdi_unlock; + end; + if mono{image.monochrome} then begin + if colorspace = cos_gray then begin + convertmonotogray(sourcerect^,image,ar3,rowbytes, + acolorforeground,acolorbackground); + end + else begin + convertmonotorgb(sourcerect^,image,ar3,rowbytes, + acolorforeground,acolorbackground); + end; + end + else begin + if colorspace = cos_gray then begin + convertgray(sourcerect^,image,ar3,rowbytes); + end + else begin + convertrgb(sourcerect^,image,ar3,rowbytes); + end; + end; + gui_freeimagemem(image.pixels); + setlength(ar1,length(ar2)+length(ar3)); + po1:= pointer(ar1); + po2:= pointer(ar2); + po3:= pointer(ar3); + for int1:= sourcerect^.cy - 1 downto 0 do begin + system.move(po2^,po1^,maskrowbytes); + inc(po1,maskrowbytes); + inc(po2,maskrowbytes); + system.move(po3^,po1^,rowbytes); + inc(po1,rowbytes); + inc(po3,rowbytes); + end; + rowbytes:= rowbytes + maskrowbytes; + cached:= not maskcopy and setimagecache(ick_4,source,sourcerect^,varname, + ar1,mask.canvas); + end; + mono:= false; //has been converted to color + str1:= 'gsave '; + if not cached then begin + str1:= str1 + '/picstr '+inttostr(rowbytes)+' string def '; + end; + str1:= str1 + rectscalestring(destrect^) + nl; + str1:= str1 + '/imdict '+imagedict+' def '; + with sourcerect^ do begin + str1:= str1 + '/madict << /ImageType 1 /Width '+inttostr(size.cx)+ + ' /Height '+inttostr(size.cy)+' /ImageMatrix '+imagematrixstring(size)+nl; + if mask.kind = bmk_mono then begin + str1:= str1 + '/BitsPerComponent 1 /Decode [1 0] '; + end + else begin + if colorspace = cos_gray then begin + str1:= str1 + '/BitsPerComponent 8 /Decode [0 1] '; + end + else begin + str1:= str1 + '/BitsPerComponent 1 /Decode [0 1 0 1 0 1] '; + end; + end; + end; + if al_intpol in alignment then begin + str1:= str1 + '/Interpolate true '; + end; + str1:= str1 + ' >> def'+nl+ + '<< /ImageType 3 /DataDict imdict /MaskDict madict /InterleaveType 2 >>'+nl; + str1:= str1 + 'image'; + end + else begin + cached:= not maskcopy and getimagecache(ick_2,mask.canvas,sourcerect^,varname); + gdi_lock; + if not (createpattern(sourcerect^,destrect^,acolorbackground,acolorforeground, + source,imagepatname) and + (cached or (gui_pixmaptoimage(tsimplebitmap1(mask).handle,image, + mask.canvas.gchandle) = gde_ok))) then begin + goto endlab; + end; + gdi_unlock; + if not cached then begin + convertmono(sourcerect^,image,ar1,rowbytes); + gui_freeimagemem(image.pixels); + cached:= not maskcopy and + setimagecache(ick_2,mask.canvas,sourcerect^,varname,ar1); + end; + str1:= 'gsave setpattern'; + if cached then begin + str1:= str1 + ' /bo1 0 def '; + end + else begin + str1:= str1 + ' /picstr ' + inttostr(rowbytes) + ' string def '; + end; + str1:= str1 + rectscalestring(destrect^) + nl; + str1:= str1 + inttostr(sourcerect^.size.cx) + ' ' + + inttostr(sourcerect^.size.cy); + str1:= str1 + ' true '; + str1:= str1 + imagematrixstring(sourcerect^.size)+nl; + if cached then begin + str1:= str1 + '{bo1 0 ne{()}{/b1 1 def '+varname+'}ifelse} '; + end + else begin + str1:= str1 + '{currentfile picstr readhexstring pop} '; + end; + str1:= str1 + 'imagemask' + nl; + streamwrite(str1); + if cached then begin + str1:= '/bo1 null def '; + end + else begin + writebinhex(ar1); + str1:= '/picstr null def ' + end; + str1:= str1+'/'+imagepatname+' null def grestore'+nl; + streamwrite(str1); + exit; + end; + end + else begin + cached:= getimagecache(ick_1,source,sourcerect^,varname{,rowbytes}); + if not cached then begin + with tcanvas1(source).fdrawinfo do begin + gdi_lock; + if gui_pixmaptoimage(paintdevice,image,gc.handle) <> gde_ok then begin + goto endlab; + end; + gdi_unlock; + end; +// components:= 1; + if mono{image.monochrome} then begin + convertmono(sourcerect^,image,ar1,rowbytes); + end + else begin + if colorspace = cos_gray then begin + convertgray(sourcerect^,image,ar1,rowbytes); + end + else begin +// components:= 3; + convertrgb(sourcerect^,image,ar1,rowbytes); + end; + end; + gui_freeimagemem(image.pixels); + cached:= setimagecache(ick_1,source,sourcerect^,varname, + ar1{,rowbytes}); + end; + str1:= 'gsave '; + if not cached then begin + str1:= str1 + '/picstr '+inttostr(rowbytes)+' string def '; + end; + str1:= str1 + rectscalestring(destrect^) + nl; + if mono{image.monochrome} then begin + if acolorbackground <> cl_transparent then begin + str1:= str1 + unityrectpath + nl + + setcolorstring(acolorbackground) + ' fill '; + end; + end; + if fpslevel >= psl_2 then begin + str1:= str1 + imagedict; + if mono{image.monochrome} then begin + str1:= str1 + 'imagemask'; + end + else begin + str1:= str1 + 'image'; + end; + end + else begin + if cached then begin + str1:= str1 + '/bo1 0 def '; + end; + str1:= str1 + setcolorstring(acolorforeground) + nl; + with sourcerect^ do begin + str1:= str1 + + inttostr(size.cx) + ' ' + inttostr(size.cy); + if mono{image.monochrome} then begin + str1:= str1 + ' true '; + end + else begin + str1:= str1 + ' 8'; + end; + str1:= str1 + imagematrixstring(size)+nl; + if cached then begin + str1:= str1 + '{bo1 0 ne{()}{/b1 1 def '+varname+'}ifelse} '; + end + else begin + str1:= str1 + '{currentfile picstr readhexstring pop} '; + end; + end; + if mono{image.monochrome} then begin + str1:= str1 + 'imagemask'; + end + else begin + if colorspace = cos_gray then begin + str1:= str1 + 'image'; + end + else begin + str1:= str1 + 'false 3 colorimage'; + end; + end; + if cached then begin + str1:= str1 + ' /bo1 null def'; + end; + end; + end; + streamwrite(str1+nl); + if cached then begin + str1:= ''; + end + else begin + writebinhex(ar1); + str1:= '/picstr null def '; + end; + str1:= str1 + 'grestore'; + if masked then begin + str1:= str1 + ' /imdict null def /madict null def '; + end; + streamwrite(str1+nl); + exit; +endlab: + gdi_unlock; + finally + addpoint1(destrect^.pos,origin); //map to origin + if maskcopy then begin + mask.free; + mask:= maskbefore; + end; + end; + end; +end; + +procedure tpostscriptcanvas.beginpage; +var + str1: string; +begin + initgcvalues; //init state on every page, necessary for gv + if active then begin + str1:= ' '+inttostr(fps_pagenumber+1); + streamwrite('%%Page:'+str1+str1+nl+ + '%%PageOrientation: '+pageorientations[printorientation]+nl); + streamwriteln('gsave'); + flandscape:= false; + fhaspage:= true; + checkscale; + end; + inherited; +end; + +procedure tpostscriptcanvas.endpage; +var + int1: integer; +begin + inherited; + if active then begin + for int1:= 0 to high(fimagecache) do begin + freeimagecache(int1); + end; + streamwriteln('grestore'); + streamwrite('showpage'+nl); + fhaspage:= false; + inc(fps_pagenumber); + end; +end; + +function tpostscriptcanvas.registermap(const acodepage: integer): string; + + procedure defpage(const glyphnames: string); + begin + streamwrite('/'+result+' ['+nl+glyphnames+'] def'+nl,true); + end; + +var + map1: unicodepagety; + str1: string; + int1,int2,int3: integer; +begin + result:= ''; + for map1:= low(unicodepagety) to high(unicodepagety) do begin + with encodings[map1] do begin + if codepage = acodepage then begin + result:= name; + defpage(encodings[map1].glyphnames); + break; + end; + end; + end; + if result = '' then begin + result:= 'E'+hextostr(longword(acodepage),2); + int3:= 256*acodepage; + str1:= ''; + for int1:= 0 to 31 do begin + for int2:= 0 to 7 do begin + str1:= str1 + '/uni'+hextostr(longword(int3),4)+' '; + inc(int3); + end; + if int1 = 31 then begin + setlength(str1,length(str1)-1); //remove last comma + end; + str1:= str1 + nl; + end; + defpage(str1); + end; +end; + +procedure tpostscriptcanvas.checkmap(const acodepage: integer); +begin + if fmapnames[acodepage] = '' then begin + fmapnames[acodepage]:= registermap(acodepage); + end; +end; + +procedure tpostscriptcanvas.updatescale; +begin + inherited; + checkscale; +end; + +procedure tpostscriptcanvas.pscommandbegin(); +begin + fdrawinfo.acolorforeground:= color; + fdrawinfo.acolorbackground:= colorbackground; + checkgcstate(changedmask); +end; + +procedure tpostscriptcanvas.pscommandwrite(const atext: string); +begin + streamwrite(atext); +end; + +procedure tpostscriptcanvas.pscommandend(); +begin + initgcvalues; +end; + +procedure tpostscriptcanvas.pscommand(const atext: string); +begin + pscommandbegin(); + pscommandwrite(atext); + pscommandend() +end; + +procedure tpostscriptcanvas.freeimagecache(const index: integer); +begin + with fimagecache[index] do begin + if source <> nil then begin + streamwrite('/'+'picstr'+inttostr(index)+' null def'+nl); + //delete dict entry + unregistergclink(source); + if mask <> nil then begin + unregistergclink(mask); + mask:= nil; + end; + source:= nil; + fimagecacheused:= fimagecacheused - bytecount; + end; + end; + removeitem(fcacheorder,index); +end; + +procedure tpostscriptcanvas.touchimagecache(const index: integer); +var + int1: integer; +begin + for int1:= high(fcacheorder) - 1 downto 0 do begin + if fcacheorder[int1] = index then begin + system.move(fcacheorder[int1+1],fcacheorder[int1], + (high(fcacheorder)-index)*sizeof(integer)); + fcacheorder[high(fcacheorder)]:= index; + end; + end; +end; + +procedure tpostscriptcanvas.gcdestroyed(const sender: tcanvas); +var + int1: integer; +begin + for int1:= 0 to high(fimagecache) do begin + with fimagecache[int1] do begin + if (source = sender) or (mask = sender) then begin + freeimagecache(int1); + break; + end; + end; + end; +end; + +function tpostscriptcanvas.getimagecache(const akind: imagecachekindty; + const asource: tcanvas; + const asourcerect: rectty; out varname: string{; + out arowbytes: integer}): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(fimagecache) do begin + with fimagecache[int1] do begin + if (kind = akind) and (source = asource) and + rectisequal(sourcerect,asourcerect) then begin + varname:= 'picstr'+inttostr(int1); + result:= (statestamp = asource.statestamp) and + ((mask = nil) or (maskstatestamp = mask.statestamp)); + if not result then begin + freeimagecache(int1); + end + else begin + touchimagecache(int1); + end; + end; + end; + end; +end; + +function tpostscriptcanvas.setimagecache(const akind: imagecachekindty; + const asource: tcanvas; + const asourcerect: rectty; out varname: string; + const bytes: bytearty; {const arowbytes: integer;} + const amask: tcanvas = nil): boolean; +var + int1,int2: integer; + str1: string; +begin + result:= (fimagecachemaxitemsize > 0) and (high(bytes) < fimagecachemaxitemsize); + if result then begin + int1:= fimagecachesize - length(bytes); + while (fimagecacheused > int1) do begin + freeimagecache(fcacheorder[0]); + end; + int2:= length(fimagecache); + for int1:= 0 to high(fimagecache) do begin + if fimagecache[int1].source = nil then begin + int2:= int1; + break; + end; + end; + if int2 = length(fimagecache) then begin + setlength(fimagecache,int2 + 1); + end; + varname:= 'picstr'+inttostr(int2); + additem(fcacheorder,int2); + with fimagecache[int2] do begin + kind:= akind; + source:= asource; + mask:= amask; + sourcerect:= asourcerect; + statestamp:= asource.statestamp; + bytecount:= length(bytes); +// rowbytes:= arowbytes; + fimagecacheused:= fimagecacheused + bytecount; + end; + if asource <> nil then begin + registergclink(asource); +// tcanvas1(asource).registergclink(self); + end; + if amask <> nil then begin + registergclink(amask); +// tcanvas1(amask).registergclink(self); + end; + str1:='/'+varname+' '+inttostr(length(bytes))+' string def currentfile '+ + varname + ' readhexstring'+nl; + streamwrite(str1); + writebinhex(bytes); + streamwrite('pop pop'+nl); + end; +end; + +procedure tpostscriptcanvas.setimagecachesize(const avalue: integer); +begin + fimagecachesize:= avalue; + if fimagecachemaxitemsize < avalue then begin + fimagecachemaxitemsize:= avalue; + end; +end; + +procedure tpostscriptcanvas.setimagecachemaxitemsize(const avalue: integer); +begin + fimagecachemaxitemsize:= avalue; + if fimagecachesize < avalue then begin + fimagecachesize:= avalue; + end; +end; + +{ tpostscriptprinter } + +constructor tpostscriptprinter.create(aowner: tcomponent); +begin + fcanvas:= tpostscriptcanvas.create(self,icanvas(self)); + inherited; + options:= [pro_tempfile]; +end; + +function tpostscriptprinter.getcanvas: tpostscriptcanvas; +begin + result:= tpostscriptcanvas(fcanvas); +end; + +procedure tpostscriptprinter.gcneeded(const sender: tcanvas); +var + gc1: gcty; +begin + if not (sender is tpostscriptcanvas) then begin + guierror(gue_invalidcanvas); + end; + with tpostscriptcanvas(sender) do begin + fillchar(gc1,sizeof(gc1),0); + gc1.kind:= bmk_rgb; + gc1.handle:= invalidgchandle; + gc1.drawingflags:= [df_highresfont]; + gc1.paintdevicesize:= getwindowsize; + linktopaintdevice(ptrint(self),gc1,{getwindowsize,}nullpoint); + end; +end; +{ +function tpostscriptprinter.getmonochrome: boolean; +begin + result:= false; +end; +} +function tpostscriptprinter.getkind: bitmapkindty; +begin + result:= bmk_rgb; +end; +procedure tpostscriptprinter.getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); +begin + //dummy +end; + +initialization + gdifuncs:= gui_getgdifuncs; + gdifunctions:= gdifuncs^; //default + gdifunctions[gdf_destroygc]:= {$ifdef FPC}@{$endif}gdi_destroygc; + gdifunctions[gdf_changegc]:= {$ifdef FPC}@{$endif}gdi_changegc; + gdifunctions[gdf_drawlines]:= {$ifdef FPC}@{$endif}gdi_drawlines; + gdifunctions[gdf_drawlinesegments]:= {$ifdef FPC}@{$endif}gdi_drawlinesegments; + gdifunctions[gdf_drawellipse]:= {$ifdef FPC}@{$endif}gdi_drawellipse; + gdifunctions[gdf_drawarc]:= {$ifdef FPC}@{$endif}gdi_drawarc; + gdifunctions[gdf_fillrect]:= {$ifdef FPC}@{$endif}gdi_fillrect; + gdifunctions[gdf_fillellipse]:= {$ifdef FPC}@{$endif}gdi_fillellipse; + gdifunctions[gdf_fillarc]:= {$ifdef FPC}@{$endif}gdi_fillarc; + gdifunctions[gdf_fillpolygon]:= {$ifdef FPC}@{$endif}gdi_fillpolygon; + gdifunctions[gdf_drawstring16]:= {$ifdef FPC}@{$endif}gdi_drawstring16; + gdifunctions[gdf_setcliporigin]:= {$ifdef FPC}@{$endif}gdi_setcliporigin; + +// gdifunctions[gdf_createemptyregion]:= {$ifdef FPC}@{$endif}gdi_createemptyregion; +// gdifunctions[gdf_createrectregion]:= {$ifdef FPC}@{$endif}gdi_createrectregion; +// gdifunctions[gdf_createrectsregion]:= {$ifdef FPC}@{$endif}gdi_createrectsregion; +// gdifunctions[gdf_destroyregion]:= {$ifdef FPC}@{$endif}gdi_destroyregion; +// gdifunctions[gdf_copyregion]:= {$ifdef FPC}@{$endif}gdi_copyregion; +// gdifunctions[gdf_moveregion]:= {$ifdef FPC}@{$endif}gdi_moveregion; +// gdifunctions[gdf_regionisempty]:= {$ifdef FPC}@{$endif}gdi_regionisempty; +// gdifunctions[gdf_regionclipbox]:= {$ifdef FPC}@{$endif}gdi_regionclipbox; +// gdifunctions[gdf_regsubrect]:= {$ifdef FPC}@{$endif}gdi_regsubrect; +// gdifunctions[gdf_regsubregion]:= {$ifdef FPC}@{$endif}gdi_regsubregion; +// gdifunctions[gdf_regaddrect]:= {$ifdef FPC}@{$endif}gdi_regaddrect; +// gdifunctions[gdf_regaddregion]:= {$ifdef FPC}@{$endif}gdi_regaddregion; +// gdifunctions[gdf_regintersectrect]:= {$ifdef FPC}@{$endif}gdi_regintersectrect; +// gdifunctions[gdf_regintersectregion]:= {$ifdef FPC}@{$endif}gdi_regintersectregion; + + gdifunctions[gdf_copyarea]:= {$ifdef FPC}@{$endif}gdi_copyarea; + +// gdifunctions[gdf_fonthasglyph]:= {$ifdef FPC}@{$endif}gdi_fonthasglyph; +// gdifunctions[gdf_getfont]:= {$ifdef FPC}@{$endif}gdi_getfont; +// gdifunctions[gdf_getfonthighres]:= {$ifdef FPC}@{$endif}gdi_getfonthighres; +// gdifunctions[gdf_freefontdata]:= {$ifdef FPC}@{$endif}gdi_freefontdata; +// gdifunctions[gdf_gettext16width]:= {$ifdef FPC}@{$endif}gdi_gettext16width; +// gdifunctions[gdf_getchar16widths]:= {$ifdef FPC}@{$endif}gdi_getchar16widths; +// gdifunctions[gdf_gdi_getfontmetrics]:= {$ifdef FPC}@{$endif}gdi_getfontmetrics + + {$if high(gdifuncty) <> gdf_getfontmetrics} + {$error missing gdi function} + {$ifend} +end. diff --git a/mseide-msegui/lib/common/printer/mseprinter.pas b/mseide-msegui/lib/common/printer/mseprinter.pas new file mode 100644 index 0000000..e18f005 --- /dev/null +++ b/mseide-msegui/lib/common/printer/mseprinter.pas @@ -0,0 +1,2049 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseprinter; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseclasses,msegraphics,msegraphutils,msestrings,msestream,msedrawtext, + mserichstring,classes,mclasses,msetypes,msestat,msestatfile, + msedataedits,msedropdownlist, + mseevent,mseglob,mseguiglob,msemenus,mseedit,msegui,sysutils; + +const + defaultppmm = 10; + defaultpagewidth = 210; //A4 mm + defaultpageheight = 297; //A4 mm + defaultframe = 10; //mm + defaultfontheight = 3.527; //*ppmm -> 10 point + +// gcscale = 4096; + printunit = 25.4/72; //point + mmtoprintscale = 1/printunit; + nulllinewidth = 0.2*mmtoprintscale; + +type + stdpagesizety = (sps_user, + sps_a0,sps_a1,sps_a2,sps_a3,sps_a4,sps_a5,sps_a6,sps_a7,sps_a8,sps_a9, + sps_b0,sps_b1,sps_b2,sps_b3,sps_b4,sps_b5,sps_b6,sps_b7,sps_b8,sps_b9,sps_b10, + sps_c5e,sps_comm10e,sps_dle,sps_executive,sps_folio,sps_ledger,sps_legal, + sps_letter,sps_tabloid); + + stdpagety = record + name: string; + width,height: real //mm + end; + +const + stdpagesizes: array[stdpagesizety] of stdpagety = ( + (name: 'User'; width: 0; height: 0), + (name: 'A0'; width: 841; height: 1189), + (name: 'A1'; width: 594; height: 841), + (name: 'A2'; width: 420; height: 594), + (name: 'A3'; width: 297; height: 420), + (name: 'A4'; width: 210; height: 297), + (name: 'A5'; width: 148; height: 210), + (name: 'A6'; width: 105; height: 148), + (name: 'A7'; width: 74; height: 105), + (name: 'A8'; width: 52; height: 74), + (name: 'A9'; width: 37; height: 52), + (name: 'B0'; width: 1030; height: 1456), + (name: 'B1'; width: 728; height: 1030), + (name: 'B2'; width: 515; height: 728), + (name: 'B3'; width: 364; height: 515), + (name: 'B4'; width: 257; height: 364), + (name: 'B5'; width: 182; height: 257), + (name: 'B6'; width: 128; height: 182), + (name: 'B7'; width: 91; height: 128), + (name: 'B8'; width: 64; height: 91), + (name: 'B9'; width: 45; height: 64), + (name: 'B10'; width: 32; height: 45), + (name: 'C5E'; width: 163; height: 229), + (name: 'Comm10E'; width: 105; height: 241), + (name: 'DLE'; width: 110; height: 220), + (name: 'Executive'; width: 191; height: 254), + (name: 'Folio'; width: 210; height: 330), + (name: 'Ledger'; width: 432; height: 279), + (name: 'Legal'; width: 216; height: 356), + (name: 'Letter'; width: 216; height: 279), + (name: 'Tabloid'; width: 279; height: 432) + ); + +type + printeroptionty = (pro_inactivewindow,//win32: start exe with inactive window + pro_tempfile); //use temp file for prolog building + printeroptionsty = set of printeroptionty; +const + defaultprinteroptions = [pro_inactivewindow]; +type + tcustomprinter = class; + tcustomprintercanvas = class; + tprintercanvas = class; + printereventty = procedure(const sender: tcustomprinter) of object; + + tprintertabulators = class(tcustomtabulators) + published + property defaultdist; + end; + colorspacety = (cos_gray,cos_rgb); + pageorientationty = (pao_portrait,pao_landscape); + + exceptioneventty = procedure(const sender: tobject; var e: exception; + var again: boolean) of object; + + tcustomprinter = class(tmsecomponent,istatfile) + private + fonpagestart: printereventty; + fonpageend: printereventty; + fpa_size: stdpagesizety; + fpa_width: real; + fpa_height: real; + fpa_frameleft: real; + fpa_frametop: real; + fpa_frameright: real; + fpa_framebottom: real; + ftabulators: tprintertabulators; +// fppmm: real; + fstatfile: tstatfile; + fstatvarname: msestring; + fpa_orientation: pageorientationty; + foptions: printeroptionsty; + fonerror: exceptioneventty; + fstatpriority: integer; + procedure settabulators(const avalue: tprintertabulators); +// procedure setppmm(const avalue: real); + procedure setpa_frameleft(const avalue: real); + procedure setpa_frametop(const avalue: real); + procedure setpa_frameright(const avalue: real); + procedure setpa_framebottom(const avalue: real); + procedure writepa_frameleft(writer: twriter); + procedure writepa_frametop(writer: twriter); + procedure writepa_frameright(writer: twriter); + procedure writepa_framebottom(writer: twriter); + procedure readpa_frameleft(reader: treader); + procedure readpa_frametop(reader: treader); + procedure readpa_frameright(reader: treader); + procedure readpa_framebottom(reader: treader); +// function getcolorspace: colorspacety; +// procedure setcolorspace(const avalue: colorspacety); + procedure setstatfile(const avalue: tstatfile); + procedure setpa_size(const avalue: stdpagesizety); + procedure setpa_width(const avalue: real); + procedure setpa_height(const avalue: real); + procedure pagesizechanged; + procedure setpa_orientation(const avalue: pageorientationty); + procedure setcanvas(const avalue: tprintercanvas); + function getclientwidth: real; + function getclientheight: real; + protected + fcanvas: tprintercanvas; + fcanceled: boolean; + function handleexception(const e: exception; out again: boolean): boolean; + //true if raise wanted + procedure loaded; override; + function getwindowsize: sizety; virtual; + procedure defineproperties(filer: tfiler); override; + procedure readstate(reader: treader); override; + + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + property onerror: exceptioneventty read fonerror write fonerror; + //call abort for quiet cancel + + //icanvas + function getsize: sizety; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure beginprint(const adryrun: boolean = false); virtual; + procedure endprint; virtual; + property canvas: tprintercanvas read fcanvas write setcanvas; + property onpagestart: printereventty read fonpagestart write fonpagestart; + property onpageend: printereventty read fonpageend write fonpageend; + property pa_width: real read fpa_width write setpa_width; + property pa_height: real read fpa_height write setpa_height; + property pa_size: stdpagesizety read fpa_size write setpa_size nodefault; + property pa_orientation: pageorientationty read fpa_orientation + write setpa_orientation default pao_portrait; + + property pa_frameleft: real read fpa_frameleft + write setpa_frameleft stored false; //mm, default 10 + property pa_frametop: real read fpa_frametop + write setpa_frametop stored false; //mm, default 10 + property pa_frameright: real read fpa_frameright + write setpa_frameright stored false; //mm, default 10 + property pa_framebottom: real read fpa_framebottom + write setpa_framebottom stored false; //mm, default 10 + property clientwidth: real read getclientwidth; //mm + property clientheight: real read getclientheight; //mm + + property tabulators: tprintertabulators read ftabulators write settabulators; +// property ppmm: real read fppmm write setppmm; //pixel per mm, default 10 +// property colorspace: colorspacety read getcolorspace write setcolorspace; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read fstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property options: printeroptionsty read foptions write foptions + default defaultprinteroptions; + end; + + tprinter = class(tcustomprinter) + published + property canvas; + property onpagestart; + property onpageend; + property pa_width; + property pa_height; + property pa_size; + property pa_orientation; + + property pa_frameleft; //mm, default 10 + property pa_frametop; //mm, default 10 + property pa_frameright; //mm, default 10 + property pa_framebottom; //mm, default 10 + property tabulators; +// property ppmm: real read fppmm write setppmm; //pixel per mm, default 10 +// property colorspace: colorspacety read getcolorspace write setcolorspace; + property statfile; + property statvarname; + property statpriority; + end; + + tstreamprinter = class; +// updateprinteransistringeventty = procedure(const sender: tstreamprinter; +// var avalue: ansistring) of object; + updateprinterstringeventty = procedure(const sender: tstreamprinter; + var avalue: msestring) of object; + tstreamprinter = class(tprinter) + private + fprintcommand: msestring; + fonupdateprintcommand: updateprinterstringeventty; + procedure setstream(const avalue: ttextstream); + protected + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + procedure doupdateprintcommand(const adata: pointer); + public + constructor create(aowner: tcomponent); override; + procedure beginprint(command: msestring = ''; + const apreamble: string = ''); overload; + procedure beginprint(const astream: ttextstream; + const apreamble: string = ''); overload; + //printer owns the stream, nil -> dummy mode + procedure endprint; override; + published + property printcommand: msestring read fprintcommand write fprintcommand; + property options; + property onerror; //call abort for quiet cancel + property onupdateprintcommand: updateprinterstringeventty + read fonupdateprintcommand write fonupdateprintcommand; + //runs in main thread + end; + + tprinterfont = class(tcanvasfont) + end; + + pageskindty = (pk_all,pk_even,pk_odd); + + pagerangety = record + first,last: integer; + end; + pagerangearty = array of pagerangety; + + printercanvasstatety = (pcs_matrixvalid,pcs_dryrun); + printercanvasstatesty = set of printercanvasstatety; + + tcustomprintercanvas = class(tcanvas) + private + fheaderheight: integer; + ffooterheight: integer; + fpagenumber: integer; + findentx: integer; + findenty: integer; + fprintorientation: pageorientationty; + fpagechanging: integer; + fpages: pagerangearty; + fpagesstring: msestring; + fpageskind: pageskindty; + procedure setcolorspace(const avalue: colorspacety); + function getliney: integer; + procedure setprintorientation(const avalue: pageorientationty); + procedure setliney(const avalue: integer); + procedure setpages(const avalue: pagerangearty); + protected + fpstate: printercanvasstatesty; + fgcoffsetx: real; + fgcoffsety: real; + fgcscale: real; + foriginx,foriginy: real; + fscale: real; + foffset: pointty; + fclientrect: rectty; + fpapersize: sizety; + fboundingbox: framety; + ftitle: msestring; + flinenumber: integer; + fpagelinenumber: integer; + fliney: integer; + fprinter: tcustomprinter; + fcolorspace: colorspacety; + fpreamble: string; + function createfont: tcanvasfont; override; + procedure initprinting(const apreamble: string = ''); + procedure checkgcstate(state: canvasstatesty); override; + function getfitrect: rectty; override; + procedure setppmm(avalue: real); override; + function defaultcliprect: rectty; override; + procedure updatescale; virtual; + procedure updateframe; + procedure beginpage; virtual; + procedure endpage; virtual; + procedure dotextout(const text: richstringty; const dest: rectty; + const flags: textflagsty; + const tabdist: real; afontcolorshadow: colorty); + procedure textout(const text: richstringty; const dest: rectty; + const flags: textflagsty; + const tabdist: real); virtual; abstract; + //tabdist < 0 -> lastx + procedure begintextclip(const arect: rectty); virtual; abstract; + procedure endtextclip; virtual; abstract; + procedure checknextpage; + procedure internalwriteln(const avalue: richstringty); + procedure setpagesstring(const avalue: msestring); + procedure internaldrawtext(var info); override; + //info = drawtextinfoty + public + constructor create(const user: tcustomprinter; + const intf: icanvas); reintroduce; + procedure initflags(const dest: tcanvas); override; + + // if cy of destrect = 0 and tf_ycentered in textflags -> place on baseline + procedure drawtext(var info: drawtextinfoty); overload; virtual; + procedure drawtext(const atext: richstringty; + const adest: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); overload; + procedure drawtext(const atext: richstringty; + const adest,aclip: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); overload; + procedure drawtext(const atext: msestring; + const adest: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); overload; + procedure writeln(const avalue: msestring = ''); overload; + procedure writeln(const avalue: richstringty); overload; + procedure writelines(const alines: array of msestring); overload; + procedure writelines(const alines: msestringarty); overload; + procedure writelines(const alines: richstringarty); overload; + + property indentx: integer read findentx write findentx; + //pixels + property indenty: integer read findenty write findenty; + //pixels + property headerheight: integer read fheaderheight write fheaderheight; + //pixels + property footerheight: integer read ffooterheight write ffooterheight; + //pixels + property linenumber: integer read flinenumber; + property pagelinenumber: integer read fpagelinenumber; + function remaininglines: integer; + function liney1: integer; //no checknextpage call + property liney: integer read getliney write setliney; + function lineheight: integer; //pixels + + procedure nextpage; override; + function active: boolean; + //checks pages + + property title: msestring read ftitle write ftitle; + //used as print job lable + property clientrect: rectty read fclientrect; + property clientpos: pointty read fclientrect.pos; + property clientsize: sizety read fclientrect.size; + property clientleft: integer read fclientrect.x; + property clienttop: integer read fclientrect.y; + property clientwidth: integer read fclientrect.cx; + property clientheight: integer read fclientrect.cy; + property colorspace: colorspacety read fcolorspace + write setcolorspace default cos_gray; + property pagenumber: integer read fpagenumber; + property pageskind: pageskindty read fpageskind write fpageskind; + //null based + property pages: pagerangearty read fpages write setpages; + //all if nil, null based + property pagesstring: msestring read fpagesstring write setpagesstring; + //one based, example: '1-5,7,9,11-13', all if '' + + property printorientation: pageorientationty read fprintorientation + write setprintorientation default pao_portrait; + end; + + tprintercanvas = class(tcustomprintercanvas) + published + property font; + property printorientation; + property colorspace; + property title; + property ppmm; //default 10 + end; + + tstreamprintercanvas = class(tprintercanvas) + protected + fdeststream: ttextstream; + fpreamblestream: ttextstream; + fbodystream: ttextstream; + procedure streamwrite(const atext: string; const apreamble: boolean = false); + //checks fstream = nil + procedure streamwriteln(const atext: string; const apreamble: boolean = false); + //checks fstream = nil + public +// procedure reset; override; + end; + + tprintervalueselector = class(tcustomselector) + private + fprinter: tcustomprinter; + procedure setprinter(const avalue: tcustomprinter); + procedure printerchanged; virtual; abstract; + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create(aowner: tcomponent); override; + published +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property ondataentered; + property printer: tcustomprinter read fprinter write setprinter; + end; + + pagesizeeventty = procedure(const sender: tobject; + var avalue: stdpagesizety; var accept: boolean) of object; + + tpagesizeselector = class(tprintervalueselector) + private + fpagewidth: real; + fpageheight: real; + feditwidth: tcustomrealedit; + feditheight: tcustomrealedit; + fupdatesize: boolean; + function getvalue: stdpagesizety; + procedure setvalue(const avalue: stdpagesizety); + procedure printerchanged; override; + procedure setpagewidth(const avalue: real); + procedure setpageheight(const avalue: real); + function getonsetvalue: pagesizeeventty; + procedure setongetvalue(const avalue: pagesizeeventty); + procedure seteditwidth(const avalue: tcustomrealedit); + procedure seteditheight(const avalue: tcustomrealedit); + protected + procedure getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); override; + procedure dochange; override; + procedure checkpagedim; + procedure updateedits(); + procedure objevent(const sender: iobjectlink; + const event: objecteventty) override; + public + constructor create(aowner: tcomponent); override; + procedure updatesize(); + function pagesizename: msestring; + property pagewidth: real read fpagewidth write setpagewidth; + property pageheight: real read fpageheight write setpageheight; + published + property value: stdpagesizety read getvalue write setvalue default sps_a4; + property editwidth: tcustomrealedit read feditwidth + write seteditwidth; + //set optionsedit1 oe1_sendchangeeventbycheckvalue in editwidget + property editheight: tcustomrealedit read feditheight + write seteditheight; + //set optionsedit1 oe1_sendchangeeventbycheckvalue in editwidget + property onsetvalue: pagesizeeventty read getonsetvalue + write setongetvalue; + end; + + pageorientationeventty = procedure(const sender: tobject; + var avalue: pageorientationty; var accept: boolean) of object; + + tpageorientationselector = class(tprintervalueselector) + private + function getvalue: pageorientationty; + procedure setvalue(const avalue: pageorientationty); + procedure printerchanged; override; + function getonsetvalue: pageorientationeventty; + procedure setongetvalue(const avalue: pageorientationeventty); + protected + procedure getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); override; + procedure dochange; override; + public + constructor create(aowner: tcomponent); override; + published + property value: pageorientationty read getvalue + write setvalue default pao_portrait; + property onsetvalue: pageorientationeventty read getonsetvalue + write setongetvalue; + end; + +function stringtopages(const avalue: msestring): pagerangearty; + //one based, example: '1-5,7,9,11-13' +function checkstdpagesize(const awidth,aheight: flo64): stdpagesizety; + +implementation +uses + mseprocutils,msepipestream,msesysintf,msestockobjects,mseconsts,msesys, + mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tfont1 = class(tfont); + tcanvas1 = class(tcanvas); + +function checkstdpagesize(const awidth,aheight: flo64): stdpagesizety; +var + wi1,he1: currency; + pa1: stdpagesizety; +begin + wi1:= awidth; + he1:= aheight; + for pa1:= stdpagesizety(1) to high(stdpagesizety) do begin + with stdpagesizes[pa1] do begin + if (currency(width) = wi1) and (currency(height) = he1) then begin + result:= pa1; + exit; + end; + end; + end; + result:= sps_user; +end; + +function stringtopages(const avalue: msestring): pagerangearty; +var + ar1,ar2: msestringarty; + int1,int2: integer; + ar3: pagerangearty; +begin + ar1:= nil; //compiler warning + ar2:= nil; //compiler warning + if avalue = '' then begin + result:= nil; + end + else begin + try + ar1:= splitstring(avalue,widechar(',')); + setlength(ar3,length(avalue)); //max + int2:= 0; + for int1:= high(ar1) downto 0 do begin + ar2:= splitstring(ar1[int1],widechar('-')); + if high(ar2) = 1 then begin + ar3[int2].first:= strtoint(ar2[0]); + ar3[int2].last:= strtoint(ar2[1]); + end + else begin + if high(ar2) = 0 then begin + ar3[int2].first:= strtoint(ar2[0]); + ar3[int2].last:= ar3[int2].first; + end + else begin + raise exception.create(''); + end; + end; + with ar3[int2] do begin + if (first <= 0) or (last <= 0) or (last < first) then begin + raise exception.create(''); + end; + dec(first); + dec(last); + end; + inc(int2); + end; + except + raise exception.create(ansistring('Invalid pages: '''+avalue+'''.'+lineend+ + 'Example: ''1-5,7,9,11-13''')); + end; + setlength(ar3,int2); + result:= ar3; + end; +end; + +{ tprintertabulators } + +{ tcustomprinter } + +constructor tcustomprinter.create(aowner: tcomponent); +begin +// fppmm:= defaultppmm; + foptions:= defaultprinteroptions; + fpa_size:= sps_a4; + with stdpagesizes[fpa_size] do begin + fpa_width:= width; + fpa_height:= height; + end; + fpa_frameleft:= defaultframe; + fpa_frametop:= defaultframe; + fpa_frameright:= defaultframe; + fpa_framebottom:= defaultframe; + ftabulators:= tprintertabulators.create; + inherited; + fcanvas.ppmm:= defaultppmm; +end; + +destructor tcustomprinter.destroy; +begin + endprint; + fcanvas.free; + ftabulators.free; + inherited; +end; + +procedure tcustomprinter.loaded; +begin + inherited; + pagesizechanged; + fcanvas.updatescale; +end; + +function tcustomprinter.handleexception(const e: exception; + out again: boolean): boolean; +var + e1: exception; +begin + result:= true; + again:= false; + if canevent(tmethod(fonerror)) then begin + e1:= e; + fcanceled:= true; + application.lock; + try + fonerror(self,e1,again); + finally + application.unlock; + end; + result:= not again and (e1 = e); + if not result and not again and (e1 <> nil) then begin + raise e1; + end; + fcanceled:= result; + end; +end; + +function tcustomprinter.getwindowsize: sizety; +var + rea1: real; +begin + if pa_width > pa_height then begin //quadratic for landscape/portrait switching + rea1:= pa_width; + end + else begin + rea1:= pa_height; + end; + result.cx:= round(rea1*fcanvas.ppmm); + result.cy:= result.cx; +end; + +procedure tcustomprinter.settabulators(const avalue: tprintertabulators); +begin + ftabulators.assign(avalue); +end; + +procedure tcustomprinter.pagesizechanged; +begin + if fpa_size <> sps_user then begin + with stdpagesizes[fpa_size] do begin + if fpa_orientation = pao_portrait then begin + fpa_width:= width; + fpa_height:= height; + end + else begin + fpa_width:= height; + fpa_height:= width; + end; + end; + end + else begin + if fpa_orientation = pao_portrait then begin + fpa_size:= checkstdpagesize(fpa_width,fpa_height); + end + else begin + fpa_size:= checkstdpagesize(fpa_height,fpa_width); + end; + end; + if not (csloading in componentstate) then begin + sendchangeevent; + fcanvas.updateframe; + end; +end; + +procedure tcustomprinter.setpa_width(const avalue: real); +begin + fpa_width:= avalue; + fpa_size:= sps_user; + pagesizechanged; +end; + +procedure tcustomprinter.setpa_height(const avalue: real); +begin + fpa_height:= avalue; + fpa_size:= sps_user; + pagesizechanged; +end; + +procedure tcustomprinter.setpa_size(const avalue: stdpagesizety); +begin + fpa_size:= avalue; + pagesizechanged; +end; + +procedure tcustomprinter.setpa_orientation(const avalue: pageorientationty); +begin + fpa_orientation:= avalue; + pagesizechanged; +end; +{ +procedure tcustomprinter.setppmm(const avalue: real); +begin + fppmm:= avalue; + ftabulators.ppmm:= avalue; + fcanvas.updatescale; +end; +} +procedure tcustomprinter.setpa_frameleft(const avalue: real); +begin + fpa_frameleft:= avalue; + fcanvas.updateframe; +end; + +procedure tcustomprinter.setpa_frametop(const avalue: real); +begin + fpa_frametop:= avalue; + fcanvas.updateframe; +end; + +procedure tcustomprinter.setpa_frameright(const avalue: real); +begin + fpa_frameright:= avalue; + fcanvas.updateframe; +end; + +procedure tcustomprinter.setpa_framebottom(const avalue: real); +begin + fpa_framebottom:= avalue; + fcanvas.updateframe; +end; + +function tcustomprinter.getclientwidth: real; +begin + result:= fpa_width - fpa_frameleft - fpa_frameright; +end; + +function tcustomprinter.getclientheight: real; +begin + result:= fpa_height - fpa_frametop - fpa_framebottom; +end; + + +{ +function tcustomprinter.getcolorspace: colorspacety; +begin + result:= fcanvas.colorspace; +end; + +procedure tcustomprinter.setcolorspace(const avalue: colorspacety); +begin + fcanvas.colorspace:= avalue; +end; +} +procedure tcustomprinter.dostatread(const reader: tstatreader); +begin + with reader do begin + pa_width:= readreal('width',fpa_width); + pa_height:= readreal('height',fpa_height); + pa_size:= stdpagesizety(readinteger('size',ord(fpa_size),0, + ord(high(stdpagesizety)))); + pa_orientation:= pageorientationty(readinteger('orientation', + ord(fpa_orientation),0,ord(high(pageorientationty)))); + fpa_frameleft:= readreal('frameleft',fpa_frameleft); + fpa_frametop:= readreal('frametop',fpa_frametop); + fpa_frameright:= readreal('frameright',fpa_frameright); + fpa_framebottom:= readreal('framebottom',fpa_framebottom); + fcanvas.colorspace:= colorspacety(readinteger('colorspace', + ord(fcanvas.colorspace),0,ord(high(colorspacety)))); + end; +end; + +procedure tcustomprinter.dostatwrite(const writer: tstatwriter); +begin + with writer do begin + writereal('width',fpa_width); + writereal('height',fpa_height); + writeinteger('size',ord(fpa_size)); + writeinteger('orientation',ord(fpa_orientation)); + writereal('frameleft',fpa_frameleft); + writereal('frametop',fpa_frametop); + writereal('frameright',fpa_frameright); + writereal('framebottom',fpa_framebottom); + writeinteger('colorspace',ord(fcanvas.colorspace)); + end; +end; + +procedure tcustomprinter.statreading; +begin + //dummy +end; + +procedure tcustomprinter.statread; +begin + //dummy +end; + +function tcustomprinter.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomprinter.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tcustomprinter.setcanvas(const avalue: tprintercanvas); +begin + fcanvas.assign(avalue); +end; + +function tcustomprinter.getsize: sizety; +begin + result:= fcanvas.fdrawinfo.gc.paintdevicesize; +end; + +procedure tcustomprinter.beginprint(const adryrun: boolean = false); +begin + //dummy +end; + +procedure tcustomprinter.endprint; +begin + //dummy +end; + +procedure tcustomprinter.writepa_frameleft(writer: twriter); +begin + writer.writefloat(fpa_frameleft); +end; + +procedure tcustomprinter.writepa_frametop(writer: twriter); +begin + writer.writefloat(fpa_frametop); +end; + +procedure tcustomprinter.writepa_frameright(writer: twriter); +begin + writer.writefloat(fpa_frameright); +end; + +procedure tcustomprinter.writepa_framebottom(writer: twriter); +begin + writer.writefloat(fpa_framebottom); +end; + +procedure tcustomprinter.readpa_frameleft(reader: treader); +begin + fpa_frameleft:= reader.readfloat; +end; + +procedure tcustomprinter.readpa_frametop(reader: treader); +begin + fpa_frametop:= reader.readfloat; +end; + +procedure tcustomprinter.readpa_frameright(reader: treader); +begin + fpa_frameright:= reader.readfloat; +end; + +procedure tcustomprinter.readpa_framebottom(reader: treader); +begin + fpa_framebottom:= reader.readfloat; +end; + +procedure tcustomprinter.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('pa_frameleft',{$ifdef FPC}@{$endif}readpa_frameleft, + {$ifdef FPC}@{$endif}writepa_frameleft, + (filer.ancestor = nil) and (fpa_frameleft <> defaultframe) or + (filer.ancestor <> nil) and + (tcustomprinter(filer.ancestor).fpa_frameleft <> fpa_frameleft)); + filer.defineproperty('pa_frametop',{$ifdef FPC}@{$endif}readpa_frametop, + {$ifdef FPC}@{$endif}writepa_frametop, + (filer.ancestor = nil) and (fpa_frametop <> defaultframe) or + (filer.ancestor <> nil) and + (tcustomprinter(filer.ancestor).fpa_frametop <> fpa_frametop)); + filer.defineproperty('pa_frameright',{$ifdef FPC}@{$endif}readpa_frameright, + {$ifdef FPC}@{$endif}writepa_frameright, + (filer.ancestor = nil) and (fpa_frameright <> defaultframe) or + (filer.ancestor <> nil) and + (tcustomprinter(filer.ancestor).fpa_frameright <> fpa_frameright)); + filer.defineproperty('pa_framebottom',{$ifdef FPC}@{$endif}readpa_framebottom, + {$ifdef FPC}@{$endif}writepa_framebottom, + (filer.ancestor = nil) and (fpa_framebottom <> defaultframe) or + (filer.ancestor <> nil) and + (tcustomprinter(filer.ancestor).fpa_framebottom <> fpa_framebottom)); +end; + +procedure tcustomprinter.readstate(reader: treader); +begin + fcanvas.beforeread; + try + inherited; + finally + fcanvas.afterread; + end; +end; + +function tcustomprinter.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tcustomprintercanvas } + +constructor tcustomprintercanvas.create(const user: tcustomprinter; + const intf: icanvas); +begin + fprinter:= user; + inherited create(user,intf); + fstate:= fstate+[cs_highresdevice,cs_internaldrawtext]; +end; + +procedure tcustomprintercanvas.initflags(const dest: tcanvas); +begin + inherited; + include(tcanvas1(dest).fdrawinfo.gc.drawingflags,df_highresfont); +end; + +function tcustomprintercanvas.createfont: tcanvasfont; +begin + result:= tprinterfont.create(self); +end; + +procedure tcustomprintercanvas.initprinting(const apreamble: string = ''); +begin + fpreamble:= apreamble; + fpagenumber:= 0; + fpagelinenumber:= 0; + fliney:= 0; + reset; +end; + +function tcustomprintercanvas.defaultcliprect: rectty; +begin + result.pos:= nullpoint; + result.size:= fdrawinfo.gc.paintdevicesize; + with result do begin + if cx > cy then begin + //quadratic because of cliprectinit with later orientation switch + cy:= cx; + end + else begin + cx:= cy; + end; + end; +end; + +procedure tcustomprintercanvas.updatescale; +begin + if not (csloading in fprinter.componentstate) then begin + exclude(fstate,cs_origin); + exclude(fpstate,pcs_matrixvalid); + with fprinter do begin + fgcscale:= mmtoprintscale/ppmm; //map to printerunits + + if fprintorientation = pao_landscape then begin + fdrawinfo.gc.paintdevicesize.cx:= round(fpa_height * ppmm); + fdrawinfo.gc.paintdevicesize.cy:= round(fpa_width * ppmm); + fgcoffsetx:= mmtoprintscale * fpa_frameleft; + fgcoffsety:= - fpa_frametop*mmtoprintscale; + end + else begin + fdrawinfo.gc.paintdevicesize.cx:= round(fpa_width * ppmm); + fdrawinfo.gc.paintdevicesize.cy:= round(fpa_height * ppmm); + fgcoffsetx:= mmtoprintscale * fpa_frameleft; + fgcoffsety:= (fpa_height-fpa_frametop)*mmtoprintscale; + end; + + if fprintorientation = pao_landscape then begin + fpapersize.cx:= round((fdrawinfo.gc.paintdevicesize.cy/ppmm)*mmtoprintscale); + fpapersize.cy:= round((fdrawinfo.gc.paintdevicesize.cx/ppmm)*mmtoprintscale); + fboundingbox.left:= round(fpa_frametop*mmtoprintscale); + fboundingbox.bottom:= round(fpa_frameleft*mmtoprintscale); + fboundingbox.right:= round( + (fdrawinfo.gc.paintdevicesize.cy/ppmm-fpa_framebottom)*mmtoprintscale); + fboundingbox.top:= round( + (fdrawinfo.gc.paintdevicesize.cx/ppmm-fpa_frameright)*mmtoprintscale); + end + else begin + fpapersize.cx:= round((fdrawinfo.gc.paintdevicesize.cx/ppmm)*mmtoprintscale); + fpapersize.cy:= round((fdrawinfo.gc.paintdevicesize.cy/ppmm)*mmtoprintscale); + fboundingbox.left:= round(fpa_frameleft*mmtoprintscale); + fboundingbox.bottom:= round(fpa_framebottom*mmtoprintscale); + fboundingbox.right:= round( + (fdrawinfo.gc.paintdevicesize.cx/ppmm-fpa_frameright)*mmtoprintscale); + fboundingbox.top:= round( + (fdrawinfo.gc.paintdevicesize.cy/ppmm-fpa_frametop)*mmtoprintscale); + end; + fclientrect.x:= round(fpa_frameleft*ppmm); + fclientrect.y:= round(fpa_frametop*ppmm); + fclientrect.cx:= fdrawinfo.gc.paintdevicesize.cx - + round((fpa_frameleft+fpa_frameright)*ppmm); + fclientrect.cy:= fdrawinfo.gc.paintdevicesize.cy - round( + (fpa_frametop+fpa_framebottom)*ppmm); + end; + end; +end; + +procedure tcustomprintercanvas.checkgcstate(state: canvasstatesty); +begin + if not (cs_origin in fstate) then begin + foriginx:= fgcoffsetx + mmtoprintscale * (origin.x/ppmm); + foriginy:= fgcoffsety - mmtoprintscale * (origin.y/ppmm); + end; + inherited; +end; + +procedure tcustomprintercanvas.updateframe; +begin + updatescale; +end; + +procedure tcustomprintercanvas.beginpage; +begin + fpagelinenumber:= 0; + fliney:= 0; + with fprinter do begin + if canevent(tmethod(fonpagestart)) then begin + fonpagestart(fprinter); + end; + end; +end; + +procedure tcustomprintercanvas.endpage; +begin + checkgcstate([cs_gc]); //could be an empty page + with fprinter do begin + if canevent(tmethod(fonpageend)) then begin + fonpageend(fprinter); + end; + end; +end; + +//todo: full support of shadow_*/gloss_* + +procedure tcustomprintercanvas.dotextout(const text: richstringty; + const dest: rectty; const flags: textflagsty; + const tabdist: real; afontcolorshadow: colorty); +var + col1: colorty; +begin + if tf_grayed in flags then begin + afontcolorshadow:= cl_white; + end; + col1:= fdrawinfo.acolorforeground; + if afontcolorshadow <> cl_none then begin + fdrawinfo.acolorforeground:= afontcolorshadow; + checkgcstate([cs_acolorforeground]); + textout(text,moverect(dest,makepoint(1,1)),flags,tabdist); + if tf_grayed in flags then begin + fdrawinfo.acolorforeground:= cl_dkgray; + end + else begin + fdrawinfo.acolorforeground:= col1; + end; + checkgcstate([cs_acolorforeground]); + end; + textout(text,dest,flags,tabdist); + if tf_grayed in flags then begin + fdrawinfo.acolorforeground:= col1; + checkgcstate([cs_acolorforeground]); + end; +end; + +procedure tcustomprintercanvas.drawtext(var info: drawtextinfoty); +// colorbackground gap filling not supported. +var + acolorshadow: colorty; + tab1: tcustomtabulators; + ar1: richstringarty; + int1,int2,int3,int4,int5,int6: integer; + rea1: real; + curflags,flags1,flags2: textflagsty; + rstr1: richstringty; + layoutinfo: layoutinfoty; + rect1,rect2: rectty; + backup: msestring; + lihi: integer; +label + endlab; +begin + if cs_inactive in fstate then exit; + save; + layouttext(self,info,layoutinfo); + if pcs_dryrun in fpstate then begin + goto endlab; + end; + ar1:= nil; //compiler warning + with fdrawinfo do begin + afonthandle1:= tfont1(font).gethandle; + with {fvaluepo^.}font do begin + acolorforeground:= color; + if acolorforeground = cl_default then begin + acolorforeground:= cl_text; + end; + acolorbackground:= colorbackground; + if acolorbackground = cl_default then begin + acolorbackground:= cl_transparent; + end; + acolorshadow:= shadow_color; + end; + checkgcstate([cs_font,cs_acolorforeground,cs_acolorbackground]); + end; + with info do begin + if tf_clipi in flags then begin + begintextclip(dest); + end + else begin + if tf_clipo in flags then begin + begintextclip(clip); + end; + end; + backup:= text.text; + try + with layoutinfo do begin + curflags:= flags; + if (tf_ycentered in curflags) and (curflags*[tf_top,tf_bottom] <> []) and + (not xyswapped and (info.res.cy > dest.cy) or + xyswapped and (info.res.cx > dest.cx))then begin + exclude(curflags,tf_ycentered); + end; + if tf_softhyphen in flags then begin + for int1:= 0 to high(lineinfos) do begin + with lineinfos[int1] do begin + for int2:= 0 to high(tabchars) do begin + if text.text[tabchars[int2].index] = c_softhyphen then begin + text.text[tabchars[int2].index]:= #0; //will be removed in printing routine + end; + end; + end; + end; + end; + text.text:= replacechar(text.text,c_softhyphen,'-'); + if high(lineinfos) > 0 then begin + rect1:= dest; +// flags1:= curflags; + flags2:= curflags - [tf_xcentered,tf_right,tf_xjustify]; + lihi:= font.lineheight; + int1:= 0; +// int2:= lihi; + if reversed then begin + lihi:= - lihi; + int1:= lihi; +// int2:= 0; + end; + if xyswapped then begin + rect1.cx:= font.lineheight; + if tf_ycentered in curflags then begin + rect1.x:= dest.x + (dest.cx - length(lineinfos) * lihi) div 2 + int1; + end + else begin + if tf_bottom in curflags then begin + if reversed then begin + rect1.x:= dest.x - high(lineinfos) * lihi; + end + else begin + rect1.x:= dest.x + dest.cx - length(lineinfos) * lihi; + end; + end; + end; + end + else begin + rect1.cy:= font.lineheight; + if tf_ycentered in curflags then begin + rect1.y:= dest.y + (dest.cy - length(lineinfos) * lihi) div 2 + int1; + end + else begin + if tf_bottom in curflags then begin + if reversed then begin + rect1.y:= dest.y - high(lineinfos) * lihi; + end + else begin + rect1.y:= dest.y + dest.cy - length(lineinfos) * lihi; + end; + end; + end; + end; + for int1:= 0 to high(lineinfos) do begin + with lineinfos[int1] do begin + if (tf_xjustify in curflags) and (high(justifychars) >= 0) and + ((int1 < high(lineinfos)) or + (tf_wordbreak in curflags) and (int1 = high(lineinfos))) then begin + rstr1:= richcopy(text,liindex,justifychars[0].index-liindex); + dotextout(rstr1,rect1,flags2,0,acolorshadow); //first word + rea1:= (dest.cx - liwidth + getstringwidth(' ') * + length(justifychars)) / + length(justifychars); //gap width + rect2:= rect1; //x justify text + if xyswapped then begin + rect2.cy:= 0; + int3:= dest.y; + end + else begin + rect2.cx:= 0; + int3:= dest.x; + end; + for int2:= liindex - 1 to justifychars[0].index - 2 do begin + inc(int3,charwidths[int2]); //end of first word + end; + for int2:= 0 to high(justifychars) - 1 do begin + int5:= 0; + for int4:= justifychars[int2].index to justifychars[int2+1].index - 2 do begin + inc(int5,charwidths[int4]); //width of actual word + end; + int6:= round(int3 + (int2 + 1) * rea1 + int5 div 2); + if xyswapped then begin + rect2.y:= int6; + end + else begin + rect2.x:= int6; + end; + int3:= int3 + int5; + rstr1:= richcopy(text,justifychars[int2].index+1, + justifychars[int2+1].index - justifychars[int2].index - 1); + dotextout(rstr1,rect2,flags2 + [tf_xcentered],0,acolorshadow); + end; + rstr1:= richcopy(text,justifychars[high(justifychars)].index+1, + liindex+licount-justifychars[high(justifychars)].index-1); + dotextout(rstr1,rect1,flags2+[tf_right],0,acolorshadow); //last word + end + else begin + rstr1:= richcopy(text,liindex,licount); + flags1:= curflags; + if (tf_xcentered in flags1) and + (curflags*[tf_left,tf_right] <> []) and + (liwidth > dest.cx) then begin + exclude(flags1,tf_xcentered); + end; + dotextout(rstr1,rect1,flags1,0,acolorshadow); + end; + if xyswapped then begin + inc(rect1.x,lihi); + end + else begin + inc(rect1.y,lihi); + end; + end; + end; + end + else begin //single line + if countchars(text.text,c_tab) = 0 then begin + flags1:= curflags; + if (tf_xcentered in flags1) and (curflags*[tf_left,tf_right] <> []) and + (not xyswapped and (info.res.cx > dest.cx) or + xyswapped and (info.res.cy > dest.cy))then begin + exclude(flags1,tf_xcentered); + end; + dotextout(text,dest,flags1,0,acolorshadow); + end + else begin + if tabulators = nil then begin + tab1:= fprinter.ftabulators; + end + else begin + tab1:= tabulators; + end; + if tab1.count = 0 then begin + if tab1.defaultdist = 0 then begin //has no tabs + replacechar(text.text,c_tab,' '); + dotextout(text,dest,curflags,0,acolorshadow); + end + else begin + ar1:= splitrichstring(text,c_tab); + dotextout(ar1[0],dest,curflags,0,acolorshadow); + rea1:= tab1.defaultdist*mmtoprintscale; + for int1:= 1 to high(ar1) do begin + dotextout(ar1[int1],dest,curflags,rea1,acolorshadow); + end; + end; + end + else begin + ar1:= splitrichstring(text,c_tab); + dotextout(ar1[0],dest,curflags,0,acolorshadow); + for int1:= 1 to high(ar1) do begin + if int1 > tab1.count then begin + rstr1.text:= ' '; + rstr1.format:= nil; + rstr1:= richconcat(rstr1,ar1[int1]); + for int2:= int1+1 to high(ar1) do begin + rstr1:= richconcat(rstr1,' '); + rstr1:= richconcat(rstr1,ar1[int2]); + end; + dotextout(rstr1,dest,curflags-[tf_right,tf_xcentered],-1,acolorshadow); + //print rest of string + break; + end; + flags1:= curflags - [tf_xcentered,tf_right]; + with tab1[int1-1] do begin + case kind of + tak_right,tak_decimal: flags1:= flags1 + [tf_right]; + tak_centered: flags1:= flags1 + [tf_xcentered]; + end; + if kind = tak_decimal then begin + int2:= msestrrscan(ar1[int1].text, + defaultformatsettingsmse.decimalseparator); + if int2 > 0 then begin + dotextout(richcopy(ar1[int1],1,int2-1), + makerect(round(pos*ppmm),dest.y,0, + dest.cy),flags1,0,acolorshadow); //int + dotextout(richcopy(ar1[int1],int2,bigint),makerect(0,dest.y,0, + dest.cy),flags1-[tf_right],-1,acolorshadow); //frac + end + else begin + dotextout(ar1[int1],makerect(round(pos*ppmm),dest.y,0, + dest.cy),flags1,0,acolorshadow); //no frac + end; + end + else begin + dotextout(ar1[int1],makerect(round(pos*ppmm),dest.y,0,dest.cy),flags1, + 0,acolorshadow); + end; + end; + end; + end; + end; + end; + end; //with layoutinfo + finally + text.text:= backup; + if flags * [tf_clipi,tf_clipo] <> [] then begin + endtextclip; + end; + end; + end; +endlab: + restore; +end; + +procedure tcustomprintercanvas.drawtext(const atext: richstringty; + const adest: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); +var + info: drawtextinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + text:= atext; + dest:= adest; + flags:= aflags; + font:= afont; + tabulators:= atabulators; + end; + drawtext(info); +end; + +procedure tcustomprintercanvas.drawtext(const atext: richstringty; + const adest,aclip: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); +var + info: drawtextinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + text:= atext; + dest:= adest; + clip:= aclip; + flags:= aflags; + font:= afont; + tabulators:= atabulators; + end; + drawtext(info); +end; + +procedure tcustomprintercanvas.drawtext(const atext: msestring; + const adest: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); +var + info: drawtextinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + text.text:= atext; + dest:= adest; + flags:= aflags; + font:= afont; + tabulators:= atabulators; + end; + drawtext(info); +end; + +procedure tcustomprintercanvas.checknextpage; +begin + if fpagechanging = 0 then begin + if remaininglines <= 0 then begin + inc(fpagechanging); + try + nextpage; + finally + dec(fpagechanging); + end; + end; + end; +end; + +procedure tcustomprintercanvas.writeln(const avalue: msestring = ''); +var + rstr1: richstringty; +begin + rstr1.format:= nil; + rstr1.text:= avalue; + writeln(rstr1); +end; + +procedure tcustomprintercanvas.internalwriteln(const avalue: richstringty); +begin + checknextpage; + if avalue.text <> '' then begin + drawtext(avalue,makerect(findentx,fliney + fheaderheight + findenty,0,0)); + end; + inc(fpagelinenumber); + inc(flinenumber); + fliney:= fliney + lineheight; +end; + +procedure tcustomprintercanvas.writeln(const avalue: richstringty); +var + ar1: richstringarty; + int1: integer; +begin + ar1:= breakrichlines(avalue); + for int1:= 0 to high(ar1) do begin + internalwriteln(ar1[int1]); + end; +end; + +procedure tcustomprintercanvas.writelines(const alines: array of msestring); +var + int1: integer; + rstr1: richstringty; +begin + rstr1.format:= nil; + for int1:= 0 to high(alines) do begin + rstr1.text:= alines[int1]; + internalwriteln(rstr1); + end; +end; + +procedure tcustomprintercanvas.writelines(const alines: msestringarty); +var + int1: integer; + rstr1: richstringty; +begin + rstr1.format:= nil; + for int1:= 0 to high(alines) do begin + rstr1.text:= alines[int1]; + internalwriteln(rstr1); + end; +end; + +procedure tcustomprintercanvas.writelines(const alines: richstringarty); +var + int1: integer; +begin + for int1:= 0 to high(alines) do begin + internalwriteln(alines[int1]); + end; +end; + +function tcustomprintercanvas.lineheight: integer; +begin + result:= font.height; + if result = 0 then begin + result:= round(defaultfontheight*ppmm); + end; + result:= result + font.extraspace; +end; + +function tcustomprintercanvas.remaininglines: integer; +begin + checkgcstate([cs_gc]); //init all values + result:= (fclientrect.cy - fheaderheight - ffooterheight - fliney - findenty - + origin.y) div lineheight; +end; + +procedure tcustomprintercanvas.nextpage; +begin + endpage; + inc(fpagenumber); + beginpage; +end; + +procedure tcustomprintercanvas.setcolorspace(const avalue: colorspacety); +begin + if fcolorspace <> avalue then begin + fcolorspace:= avalue; + exclude(fstate,cs_acolorforeground); +// valueschanged([cs_color,cs_colorbackground]); + end; +end; + +function tcustomprintercanvas.active: boolean; +var + int1: integer; +begin + result:= fpages = nil; + if not result then begin + for int1:= high(fpages) downto 0 do begin + with fpages[int1] do begin + if (fpagenumber >= first) and (fpagenumber <= last) then begin + result:= true; + break; + end; + end; + end; + end; + if result then begin + result:= (fpageskind = pk_all) or ((fpageskind = pk_even) xor odd(fpagenumber)); + end; +end; + +function tcustomprintercanvas.liney1: integer; +begin + result:= fliney + fheaderheight; +end; + +function tcustomprintercanvas.getliney: integer; +begin + checknextpage; + result:= liney1; +end; + +procedure tcustomprintercanvas.setliney(const avalue: integer); +begin + checknextpage; + fliney:= avalue - fheaderheight; +end; + +procedure tcustomprintercanvas.setprintorientation( + const avalue: pageorientationty); +begin + if avalue <> fprintorientation then begin + fprintorientation:= avalue; + updatescale; + end; +end; + +procedure tcustomprintercanvas.setppmm(avalue: real); +begin + inherited; + fprinter.ftabulators.ppmm:= avalue; + updatescale; +end; + +procedure tcustomprintercanvas.setpages(const avalue: pagerangearty); +begin + fpages:= copy(avalue); +end; + +procedure tcustomprintercanvas.setpagesstring(const avalue: msestring); +begin + pages:= stringtopages(avalue); + fpagesstring:= avalue; +end; + +procedure tcustomprintercanvas.internaldrawtext(var info); +begin + drawtext(drawtextinfoty(info)); +end; + +function tcustomprintercanvas.getfitrect: rectty; +begin + result:= fclientrect; +end; + +{ tprintervalueselector } + +constructor tprintervalueselector.create(aowner: tcomponent); +begin + inherited; + dropdown.cols.nostreaming:= true; +end; + +procedure tprintervalueselector.setprinter(const avalue: tcustomprinter); +begin + setlinkedvar(avalue,tmsecomponent(fprinter)); + printerchanged; +end; + +procedure tprintervalueselector.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_changed) and (sender = fprinter) then begin + printerchanged; + end; +end; + +{ tpagesizeselector } + +constructor tpagesizeselector.create(aowner: tcomponent); +var + pa1: stdpagesizety; +begin + inherited; + dropdown.cols.beginupdate(); + for pa1:= low(stdpagesizety) to high(stdpagesizety) do begin + addrow([msestring(stdpagesizes[pa1].name)]); + end; + dropdown.cols.endupdate(); + inherited value:= integer(sps_a4); +end; + +procedure tpagesizeselector.getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); +var + pa1: stdpagesizety; +begin + setlength(aenums,ord(high(stdpagesizety))); + names.clear; + for pa1:= stdpagesizety(1) to high(stdpagesizety) do begin + with stdpagesizes[pa1] do begin + names.addrow([msestring(name+' ('+formatfloat('0',width)+'*'+ + formatfloat('0',height)+' mm2)')]); + end; + aenums[ord(pa1)-1]:= ord(pa1); + end; +end; + +procedure tpagesizeselector.dochange; +begin + if fprinter <> nil then begin + fprinter.pa_size:= value; + end; + if value <> sps_user then begin + with stdpagesizes[value] do begin + fpagewidth:= width; + fpageheight:= height; + end; + updateedits(); + end; + inherited; +end; + +function tpagesizeselector.getvalue: stdpagesizety; +begin + result:= stdpagesizety(inherited value); +end; + +procedure tpagesizeselector.setvalue(const avalue: stdpagesizety); +begin + if value <> avalue then begin + inherited setvalue(integer(avalue)); + end; +end; + +procedure tpagesizeselector.printerchanged; +begin + if fprinter <> nil then begin + value:= fprinter.pa_size; + end; +end; + +function tpagesizeselector.pagesizename: msestring; +begin + result:= msestring(stdpagesizes[value].name); +end; + +procedure tpagesizeselector.setpagewidth(const avalue: real); +begin + if fpagewidth <> avalue then begin + fpagewidth:= avalue; + checkpagedim; + end; +end; + +procedure tpagesizeselector.setpageheight(const avalue: real); +begin + if fpageheight <> avalue then begin + fpageheight:= avalue; + checkpagedim; + end; +end; + +procedure tpagesizeselector.checkpagedim; +begin + updateedits(); + value:= checkstdpagesize(fpagewidth,fpageheight); + +end; + +procedure tpagesizeselector.updateedits(); +begin + if (componentstate * [csloading,csdestroying] = []) and + not fupdatesize then begin + fupdatesize:= true; + try + if (feditwidth <> nil) and not + (csdestroying in feditwidth.componentstate) then begin + feditwidth.value:= fpagewidth; + end; + if (feditheight <> nil) and not + (csdestroying in feditheight.componentstate) then begin + feditheight.value:= fpageheight; + end; + finally + fupdatesize:= false; + end; + end; +end; + +procedure tpagesizeselector.updatesize(); +begin + if not fupdatesize then begin + fupdatesize:= true; + try + if (feditwidth <> nil) and (feditwidth.value <> emptyreal) then begin + pagewidth:= feditwidth.value; + end; + if (feditheight <> nil) and (feditheight.value <> emptyreal) then begin + pageheight:= feditheight.value; + end; + finally + fupdatesize:= false; + end; + end; +end; + +procedure tpagesizeselector.objevent(const sender: iobjectlink; + const event: objecteventty); +var + inst1: tobject; +begin + inherited; + if (event = oe_changed) then begin + inst1:= sender.getinstance(); + if (inst1 <> nil) and + ((inst1 = feditwidth) or (inst1 = feditheight)) then begin + updatesize(); + end; + end; +end; + +function tpagesizeselector.getonsetvalue: pagesizeeventty; +begin + result:= pagesizeeventty(fonsetvalue1); +end; + +procedure tpagesizeselector.setongetvalue(const avalue: pagesizeeventty); +begin + pagesizeeventty(fonsetvalue1):= avalue; +end; + +procedure tpagesizeselector.seteditwidth(const avalue: tcustomrealedit); +begin + if avalue <> feditwidth then begin + setlinkedvar(avalue,tmsecomponent(feditwidth)); + updateedits(); + end; +end; + +procedure tpagesizeselector.seteditheight(const avalue: tcustomrealedit); +begin + if avalue <> feditheight then begin + setlinkedvar(avalue,tmsecomponent(feditheight)); + updateedits(); + end; +end; + +{ tpageorientationselector } + +constructor tpageorientationselector.create(aowner: tcomponent); +begin + inherited; + addrow([stockcaptions(sc_portrait)]); + addrow([stockcaptions(sc_landscape)]); +end; + +function tpageorientationselector.getvalue: pageorientationty; +begin + result:= pageorientationty(inherited value); +end; + +procedure tpageorientationselector.setvalue(const avalue: pageorientationty); +begin + if value <> avalue then begin + inherited setvalue(integer(avalue)); + end; +end; + +procedure tpageorientationselector.printerchanged; +begin + if fprinter <> nil then begin + value:= fprinter.pa_orientation; + end; +end; + +procedure tpageorientationselector.getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); +begin + names.clear; + names.addrow([stockcaptions(sc_portrait)]); + names.addrow([stockcaptions(sc_landscape)]); +end; + +procedure tpageorientationselector.dochange; +begin + if fprinter <> nil then begin + fprinter.pa_orientation:= value; + end; + inherited; +end; + +function tpageorientationselector.getonsetvalue: pageorientationeventty; +begin + result:= pageorientationeventty(fonsetvalue1); +end; + +procedure tpageorientationselector.setongetvalue(const avalue: pageorientationeventty); +begin + pageorientationeventty(fonsetvalue1):= avalue; +end; + +{ tstreamprinter } + +constructor tstreamprinter.create(aowner: tcomponent); +begin +// fprintcommand:= sys_getprintcommand; + inherited; +end; + +procedure tstreamprinter.doupdateprintcommand(const adata: pointer); +begin + if canevent(tmethod(fonupdateprintcommand)) then begin + fonupdateprintcommand(self,pmsestring(adata)^); + end; +end; + +procedure tstreamprinter.beginprint(command: msestring = ''; + const apreamble: string = ''); +var + pip1: tpipewriter; + opt1: execoptionsty; +begin + if command = '' then begin + command:= fprintcommand; + end; + if command = '' then begin + command:= msestring(sys_getprintcommand()); + end; + if canevent(tmethod(fonupdateprintcommand)) then begin + application.synchronize({$ifdef FPC}@{$endif}doupdateprintcommand,@command); + end; + pip1:= tpipewriter.create; + try + opt1:= []; + if pro_inactivewindow in foptions then begin + include(opt1,exo_inactive); + end; + execmse2(command,pip1,nil,nil,{false,}-1,opt1 + {pro_inactivewindow in foptions}); + except + pip1.free; + raise; + end; + beginprint(pip1,apreamble); +end; + +procedure tstreamprinter.beginprint(const astream: ttextstream; + const apreamble: string = ''); +begin + with tstreamprintercanvas(fcanvas) do begin + if astream = nil then begin + include(fpstate,pcs_dryrun); + end + else begin + exclude(fpstate,pcs_dryrun); + end; + endprint; + setstream(astream); + initprinting(apreamble); + end; +end; + +procedure tstreamprinter.endprint; +begin + try + setstream(nil); + finally + fcanceled:= false; + end; +end; + +procedure tstreamprinter.setstream(const avalue: ttextstream); +var + fna1: filenamety; +begin + with tstreamprintercanvas(fcanvas) do begin + try + unlink; + except + end; + try + if (fdeststream <> fpreamblestream) and (fpreamblestream <> nil) then begin + fna1:= fpreamblestream.filename; + fpreamblestream.position:= 0; + fdeststream.copyfrom(fpreamblestream,0); + freeandnil(fpreamblestream); + sys_deletefile(fna1); + end; + if (fdeststream <> fbodystream) and (fbodystream <> nil) then begin + fna1:= fbodystream.filename; + fbodystream.position:= 0; + fdeststream.copyfrom(fbodystream,0); + freeandnil(fbodystream); + sys_deletefile(fna1); + end; + freeandnil(fdeststream); + fdeststream:= avalue; + if (pro_tempfile in foptions) and (avalue <> nil) then begin + fpreamblestream:= ttextstream.createtempfile('msepspreamble',fna1); + fbodystream:= ttextstream.createtempfile('msepsbody',fna1); + fpreamblestream.usewritebuffer:= true; + fbodystream.usewritebuffer:= true; + end + else begin + if avalue <> nil then begin + avalue.usewritebuffer:= true; + end; + fpreamblestream:= avalue; + fbodystream:= avalue; + end; + except + if fdeststream <> fpreamblestream then begin + freeandnil(fpreamblestream); + freeandnil(fbodystream); + end; + freeandnil(fdeststream); + raise; + end; + end; +end; + +procedure tstreamprinter.dostatread(const reader: tstatreader); +begin + inherited; + with reader do begin + printcommand:= readmsestring('printcommand',printcommand); + end; +end; + +procedure tstreamprinter.dostatwrite(const writer: tstatwriter); +begin + inherited; + with writer do begin + writemsestring('printcommand',printcommand); + end; +end; + +{ tstreamprintercanvas } +{ +procedure tstreamprintercanvas.reset; +begin +// restore(1); //do not change the streamed values +// save; + inherited; + clipregion:= 0; //?? + origin:= nullpoint; //?? +end; +} +procedure tstreamprintercanvas.streamwrite(const atext: string; + const apreamble: boolean = false); +var + bo1: boolean; +begin + if (fdeststream <> nil) and not fprinter.fcanceled then begin + bo1:= false; + repeat + try + if apreamble then begin + fpreamblestream.write(atext); + end + else begin + fbodystream.write(atext); + end; + except + on e: exception do begin + if fprinter.handleexception(e,bo1) then begin + raise; + end; + end; + end; + until not bo1; + end; +end; + +procedure tstreamprintercanvas.streamwriteln(const atext: string; + const apreamble: boolean = false); +var + bo1: boolean; +begin + if (fdeststream <> nil) and not fprinter.fcanceled then begin + bo1:= false; + repeat + try + if apreamble then begin + fpreamblestream.writeln(atext); + end + else begin + fbodystream.writeln(atext); + end; + except + on e: exception do begin + if fprinter.handleexception(e,bo1) then begin + raise; + end; + end; + end; + until not bo1; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/regcomponents/designer_bmp.pas b/mseide-msegui/lib/common/regcomponents/designer_bmp.pas new file mode 100644 index 0000000..0a253f9 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/designer_bmp.pas @@ -0,0 +1,119 @@ +unit designer_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_TComponent: record size: integer; data: array[0..2033] of byte end = + (size: 2034; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,84,67,111, + 109,112,111,110,101,110,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,124,7,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,144,3,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,27,28,228,242,1,46,237,253,1, + 47,236,252,1,41,237,254,1,26,233,250,1,12,227,243,1,9,145,154,1, + 0,0,0,2,255,255,255,14,55,235,252,1,76,239,254,1,88,240,255,1, + 89,240,255,1,81,240,255,1,63,239,255,1,39,238,255,1,13,231,247,1, + 9,169,181,1,0,0,0,2,255,255,255,12,60,240,255,1,87,239,254,1, + 113,241,255,1,128,241,255,1,131,241,255,1,119,241,255,1,97,240,255,1, + 68,239,255,1,35,238,255,1,13,228,244,1,4,65,69,1,0,0,0,1, + 255,255,255,12,80,238,253,1,115,241,255,1,147,242,255,1,168,242,255,1, + 172,242,255,1,155,242,255,1,127,241,255,1,92,240,255,1,55,239,255,1, + 16,238,255,1,9,179,191,1,0,0,0,2,255,255,255,11,93,238,252,1, + 135,241,255,1,173,242,255,1,205,243,255,1,208,244,255,1,185,243,255,1, + 148,242,255,1,108,240,255,1,67,239,255,1,27,238,255,1,11,210,225,1, + 0,0,0,2,255,255,255,11,99,239,254,1,140,241,255,1,182,243,255,1, + 208,246,255,1,208,248,255,1,196,243,255,1,154,242,255,1,113,241,255,1, + 71,239,255,1,30,238,255,1,12,232,248,1,0,0,0,2,255,255,255,11, + 90,236,251,1,131,241,255,1,168,242,255,1,198,243,255,1,203,243,255,1, + 179,243,255,1,144,242,255,1,105,240,255,1,65,239,255,1,25,238,255,1, + 11,209,224,1,0,0,0,2,255,255,255,2,0,0,252,1,0,0,239,1, + 0,0,0,1,255,255,255,6,72,229,244,1,110,241,255,1,140,241,255,1, + 160,242,255,1,163,242,255,1,148,242,255,1,121,241,255,1,87,240,255,1, + 51,239,255,1,13,238,255,1,9,168,179,1,0,0,0,2,255,255,255,1, + 0,0,255,1,0,0,253,1,0,0,248,1,0,0,29,1,0,0,0,1, + 255,255,255,5,30,161,171,1,79,233,248,1,105,240,255,1,119,241,255,1, + 122,241,255,1,111,241,255,1,90,240,255,1,62,239,255,1,30,238,255,1, + 13,225,241,1,2,30,32,1,0,0,0,2,255,255,255,1,0,0,251,1, + 0,0,255,2,0,0,177,1,0,0,0,2,255,255,255,4,0,0,0,1, + 35,180,193,1,64,230,245,1,79,240,255,1,80,240,255,1,72,239,255,1, + 55,239,255,1,31,238,255,1,13,225,241,1,5,88,95,1,0,0,0,3, + 0,0,255,1,0,0,254,1,0,0,255,2,0,0,249,1,0,0,75,1, + 0,0,0,1,255,255,255,5,0,0,0,1,10,78,83,1,29,183,196,1, + 35,211,227,1,31,232,248,1,15,209,225,1,9,169,181,1,2,31,32,1, + 0,0,0,3,255,255,255,1,0,0,252,1,0,0,255,4,0,0,209,1, + 0,0,0,2,255,255,255,4,0,0,0,11,0,0,253,1,0,0,255,6, + 0,0,127,1,0,0,0,1,255,255,255,4,0,0,0,9,255,255,255,1, + 0,0,255,1,0,0,253,1,0,0,255,6,0,0,234,1,0,0,18,1, + 0,0,0,1,255,255,255,2,255,0,0,9,0,0,0,2,0,0,252,1, + 0,0,255,8,0,0,171,1,0,0,0,2,255,255,255,1,255,0,0,9, + 0,0,0,1,0,0,185,1,0,0,255,9,0,0,248,1,0,0,73,1, + 0,0,0,1,255,255,255,1,254,0,0,1,255,0,0,8,0,0,0,1, + 0,0,244,1,0,0,254,1,0,0,252,2,0,0,253,3,0,0,254,3, + 0,0,255,1,0,0,205,1,0,0,0,1,255,255,255,1,254,0,0,1, + 255,0,0,8,0,0,0,14,255,255,255,1,254,0,0,1,255,0,0,8, + 0,0,0,14,255,255,255,1,254,0,0,1,255,0,0,8,0,0,0,2, + 255,255,255,13,254,0,0,1,255,0,0,8,0,0,0,2,255,255,255,13, + 254,0,0,1,255,0,0,8,0,0,0,2,255,255,255,13,254,0,0,1, + 255,0,0,8,0,0,0,2,255,255,255,13,0,0,0,11,255,255,255,12, + 180,3,0,0,0,0,0,27,18,18,18,1,143,143,143,1,205,205,205,1, + 243,243,243,1,207,207,207,1,149,149,149,1,28,28,28,1,3,3,3,1, + 1,1,1,1,0,0,0,14,61,61,61,1,231,231,231,1,255,255,255,5, + 237,237,237,1,84,84,84,1,8,8,8,1,1,1,1,1,0,0,0,12, + 17,17,17,1,231,231,231,1,255,255,255,7,241,241,241,1,63,63,63,1, + 8,8,8,1,0,0,0,12,143,143,143,1,255,255,255,9,190,190,190,1, + 31,31,31,1,3,3,3,1,0,0,0,11,205,205,205,1,255,255,255,9, + 230,230,230,1,75,75,75,1,10,10,10,1,0,0,0,11,243,243,243,1, + 255,255,255,9,249,249,249,1,101,101,101,1,15,15,15,1,0,0,0,11, + 206,206,206,1,255,255,255,9,231,231,231,1,112,112,112,1,16,16,16,1, + 0,0,0,2,69,69,69,1,71,71,71,1,6,6,6,1,0,0,0,6, + 148,148,148,1,255,255,255,9,202,202,202,1,97,97,97,1,14,14,14,1, + 0,0,0,1,6,6,6,1,218,218,218,1,220,220,220,1,44,44,44,1, + 7,7,7,1,0,0,0,5,25,25,25,1,237,237,237,1,255,255,255,7, + 244,244,244,1,136,136,136,1,68,68,68,1,9,9,9,1,0,0,0,1, + 123,123,123,1,255,255,255,2,167,167,167,1,35,35,35,1,3,3,3,1, + 0,0,0,4,2,2,2,1,79,79,79,1,240,240,240,1,255,255,255,5, + 244,244,244,1,162,162,162,1,100,100,100,1,25,25,25,1,2,2,2,1, + 31,31,31,1,246,246,246,1,255,255,255,2,249,249,249,1,89,89,89,1, + 13,13,13,1,0,0,0,5,5,5,5,1,52,52,52,1,185,185,185,1, + 228,228,228,1,249,249,249,1,231,231,231,1,200,200,200,1,134,134,134,1, + 97,97,97,1,38,38,38,1,5,5,5,1,0,0,0,1,178,178,178,1, + 255,255,255,4,203,203,203,1,42,42,42,1,6,6,6,1,0,0,0,4, + 1,1,1,1,5,5,5,1,23,23,23,1,60,60,60,1,84,84,84,1, + 96,96,96,1,84,84,84,1,60,60,60,1,23,23,23,1,5,5,5,1, + 1,1,1,1,76,76,76,1,255,255,255,6,128,128,128,1,21,21,21,1, + 0,0,0,4,1,1,1,2,3,3,3,1,9,9,9,1,14,14,14,1, + 16,16,16,1,14,14,14,1,9,9,9,1,3,3,3,1,0,0,0,1, + 8,8,8,1,222,222,222,1,255,255,255,6,231,231,231,1,55,55,55,1, + 9,9,9,1,0,0,0,2,248,248,248,1,255,255,255,8,23,23,23,1, + 3,3,3,1,130,130,130,1,255,255,255,8,169,169,169,1,33,33,33,1, + 2,2,2,1,0,0,0,1,248,248,248,1,255,255,255,8,105,105,105,1, + 50,50,50,1,248,248,248,1,255,255,255,8,248,248,248,1,84,84,84,1, + 13,13,13,1,0,0,0,1,249,249,249,1,255,255,255,8,121,121,121,1, + 183,183,183,1,250,250,250,1,252,252,252,1,253,253,253,3,254,254,254,3, + 255,255,255,2,202,202,202,1,47,47,47,1,0,0,0,1,249,249,249,1, + 255,255,255,8,122,122,122,1,30,30,30,1,65,65,65,1,97,97,97,1, + 109,109,109,1,105,105,105,1,110,110,110,1,104,104,104,1,109,109,109,1, + 106,106,106,1,109,109,109,1,107,107,107,1,102,102,102,1,54,54,54,1, + 0,0,0,1,249,249,249,1,255,255,255,8,121,121,121,1,21,21,21,1, + 17,17,17,1,27,27,27,1,25,25,25,1,26,26,26,2,25,25,25,1, + 24,24,24,1,27,27,27,1,26,26,26,1,27,27,27,2,18,18,18,1, + 0,0,0,1,249,249,249,1,255,255,255,8,121,121,121,1,19,19,19,1, + 0,0,0,13,249,249,249,1,255,255,255,8,121,121,121,1,19,19,19,1, + 0,0,0,13,249,249,249,1,255,255,255,8,121,121,121,1,19,19,19,1, + 0,0,0,13,249,249,249,1,255,255,255,8,120,120,120,1,19,19,19,1, + 0,0,0,13,15,15,15,1,96,96,96,1,114,114,114,1,115,115,115,6, + 99,99,99,1,16,16,16,1,0,0,0,12,0,0) + ); + +initialization + registerobjectdata(@objdata_TComponent,tbitmapcomp,'TComponent'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regcrypto.pas b/mseide-msegui/lib/common/regcomponents/regcrypto.pas new file mode 100644 index 0000000..4aa60b8 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regcrypto.pas @@ -0,0 +1,38 @@ +{ MSEide Copyright (c) 2012 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regcrypto; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + msedesignintf,msecryptohandler,msessl,msepropertyeditors,msestream,msezstream, + regcrypto_bmp; + +procedure Register; +begin + registercomponents('Cryp',[tdummycryptohandler,tdigesthandler,tbase64handler, + tzstreamhandler, + tsymciphercryptohandler,tasymciphercryptohandler]); + registerpropertyeditor(typeinfo(tcustomcryptohandler),nil,'', + tlinkcomponentpropertyeditor); + registercomponenttabhints(['Cryp'], + ['Components for tmsefilestream.criptohandler, zlib, openssl, base64']); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regcrypto_bmp.pas b/mseide-msegui/lib/common/regcomponents/regcrypto_bmp.pas new file mode 100644 index 0000000..e301054 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regcrypto_bmp.pas @@ -0,0 +1,693 @@ +unit regcrypto_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tdummycryptohandler: record size: integer; data: array[0..2186] of byte end = + (size: 2187; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,117, + 109,109,121,99,114,121,112,116,111,104,97,110,100,108,101,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,12,8,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,132,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208, + 2,0,0,0,4,208,208,208,1,0,0,0,3,208,208,208,22,0,0,0, + 1,208,208,208,23,0,0,0,1,208,208,208,2,0,0,0,4,208,208,208, + 18,0,0,0,1,208,208,208,1,0,0,0,5,208,208,208,17,0,0,0, + 1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208, + 1,0,0,0,1,208,208,208,1,0,0,0,9,208,208,208,2,0,0,0, + 1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,3,208,208,208,1,0,0,0,12,208,208,208,1,0,0,0, + 1,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208, + 1,0,0,0,12,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0, + 2,208,208,208,2,0,0,0,3,208,208,208,1,0,0,0,3,208,208,208, + 1,0,0,0,8,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0, + 2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208, + 1,0,0,0,3,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0, + 2,208,208,208,3,0,0,0,1,208,208,208,1,0,0,0,5,208,208,208, + 1,0,0,0,5,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0, + 2,208,208,208,3,0,0,0,1,208,208,208,8,0,0,0,1,208,208,208, + 9,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,17,0,0,0, + 2,208,208,208,3,0,0,0,1,208,208,208,18,0,0,0,2,208,208,208, + 3,0,0,0,1,208,208,208,23,0,0,0,2,208,208,208,1,0,0,0, + 11,208,208,208,2,0,0,0,7,208,208,208,2,0,0,0,4,208,208,208, + 1,0,0,0,8,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0, + 6,208,208,208,1,0,0,0,3,208,208,208,4,0,0,0,2,208,208,208, + 2,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0, + 7,208,208,208,1,0,0,0,4,208,208,208,3,0,0,0,4,208,208,208, + 1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,2,0,0,0, + 7,208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,5,208,208,208, + 1,0,0,0,1,208,208,208,4,0,0,0,1,208,208,208,7,0,0,0, + 3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208, + 10,0,0,0,3,208,208,208,3,0,0,0,2,208,208,208,5,0,0,0, + 1,208,208,208,22,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 3,80,5,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60, + 1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240, + 2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22, + 1,0,0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0, + 22,240,240,240,1,0,0,0,23,202,202,202,1,0,0,0,2,18,18,18, + 1,72,72,72,1,69,69,69,1,32,32,32,1,0,0,0,18,217,217,217, + 1,0,0,0,1,64,64,64,1,197,197,197,1,154,154,154,1,204,204,204, + 1,94,94,94,1,0,0,0,17,240,240,240,1,0,0,0,1,64,64,64, + 1,111,111,111,1,0,0,0,1,11,11,11,1,197,197,197,1,0,0,0, + 1,49,49,49,1,0,0,0,1,29,29,29,1,18,18,18,1,42,42,42, + 1,44,44,44,1,54,54,54,1,1,1,1,1,57,57,57,1,1,1,1, + 1,51,51,51,1,0,0,0,2,47,47,47,1,0,0,0,1,75,75,75, + 1,225,225,225,1,0,0,0,1,64,64,64,1,111,111,111,1,0,0,0, + 2,169,169,169,1,21,21,21,1,176,176,176,1,0,0,0,1,103,103,103, + 1,64,64,64,1,170,170,170,1,150,150,150,1,198,198,198,1,144,144,144, + 1,150,150,150,1,91,91,91,1,147,147,147,1,33,33,33,1,26,26,26, + 1,141,141,141,1,0,0,0,1,240,240,240,1,0,0,0,2,64,64,64, + 1,111,111,111,1,0,0,0,2,144,144,144,1,41,41,41,1,176,176,176, + 1,0,0,0,1,103,103,103,1,64,64,64,1,180,180,180,1,5,5,5, + 1,109,109,109,1,92,92,92,1,27,27,27,1,141,141,141,1,76,76,76, + 1,101,101,101,1,95,95,95,1,71,71,71,1,0,0,0,1,240,240,240, + 1,0,0,0,2,64,64,64,1,111,111,111,1,0,0,0,2,173,173,173, + 1,20,20,20,1,176,176,176,1,0,0,0,1,106,106,106,1,64,64,64, + 1,168,168,168,1,0,0,0,1,102,102,102,1,65,65,65,1,22,22,22, + 1,145,145,145,1,11,11,11,1,162,162,162,1,157,157,157,1,9,9,9, + 1,0,0,0,1,135,135,135,1,45,45,45,1,0,0,0,1,64,64,64, + 1,111,111,111,1,0,0,0,1,34,34,34,1,195,195,195,1,0,0,0, + 1,181,181,181,1,0,0,0,1,144,144,144,1,64,64,64,1,168,168,168, + 1,0,0,0,1,102,102,102,1,65,65,65,1,22,22,22,1,145,145,145, + 1,0,0,0,1,165,165,165,1,156,156,156,1,0,0,0,3,240,240,240, + 1,0,0,0,1,64,64,64,1,233,233,233,1,218,218,218,1,208,208,208, + 1,50,50,50,1,0,0,0,1,150,150,150,1,174,174,174,1,158,158,158, + 1,64,64,64,1,168,168,168,1,0,0,0,1,102,102,102,1,65,65,65, + 1,22,22,22,1,145,145,145,1,0,0,0,1,119,119,119,1,118,118,118, + 1,0,0,0,3,240,240,240,1,0,0,0,8,9,9,9,1,0,0,0, + 9,119,119,119,1,43,43,43,1,0,0,0,2,135,135,135,1,165,165,165, + 1,0,0,0,17,93,93,93,1,184,184,184,1,0,0,0,3,240,240,240, + 1,0,0,0,18,9,9,9,1,5,5,5,1,0,0,0,3,240,240,240, + 1,0,0,0,23,75,75,75,1,105,105,105,1,0,0,0,1,52,52,52, + 1,159,159,159,1,168,168,168,1,124,124,124,1,5,5,5,1,65,65,65, + 1,119,119,119,1,176,176,176,1,125,125,125,1,160,160,160,1,27,27,27, + 1,0,0,0,2,143,143,143,1,37,37,37,1,137,137,137,1,107,107,107, + 1,167,167,167,1,161,161,161,1,55,55,55,1,0,0,0,2,240,240,240, + 1,30,30,30,1,237,237,237,1,41,41,41,1,0,0,0,1,124,124,124, + 1,84,84,84,1,95,95,95,1,229,229,229,1,34,34,34,1,22,22,22, + 1,133,133,133,1,140,140,140,1,0,0,0,1,51,51,51,1,206,206,206, + 1,0,0,0,1,199,199,199,1,162,162,162,1,8,8,8,1,35,35,35, + 1,234,234,234,1,27,27,27,1,0,0,0,1,240,240,240,1,90,90,90, + 1,184,184,184,1,0,0,0,4,95,95,95,1,169,169,169,1,0,0,0, + 2,21,21,21,1,231,231,231,1,15,15,15,1,169,169,169,1,85,85,85, + 1,0,0,0,1,199,199,199,1,64,64,64,1,0,0,0,2,183,183,183, + 1,86,86,86,1,202,202,202,1,97,97,97,1,27,27,27,1,224,224,224, + 1,1,1,1,1,0,0,0,1,76,76,76,1,100,100,100,1,95,95,95, + 1,160,160,160,1,0,0,0,3,144,144,144,1,136,136,136,1,212,212,212, + 1,2,2,2,1,0,0,0,1,199,199,199,1,108,108,108,1,0,0,0, + 1,5,5,5,1,235,235,235,1,43,43,43,1,240,240,240,1,0,0,0, + 2,112,112,112,1,168,168,168,1,155,155,155,1,180,180,180,1,27,27,27, + 1,95,95,95,1,160,160,160,1,0,0,0,3,27,27,27,1,247,247,247, + 1,96,96,96,1,0,0,0,2,199,199,199,1,196,196,196,1,165,165,165, + 1,199,199,199,1,114,114,114,1,0,0,0,1,240,240,240,1,0,0,0, + 4,7,7,7,1,0,0,0,7,33,33,33,1,213,213,213,1,4,4,4, + 1,0,0,0,2,199,199,199,1,64,64,64,1,10,10,10,1,1,1,1, + 1,0,0,0,2,7,7,7,1,172,172,172,1,0,0,0,10,119,119,119, + 1,198,198,198,1,55,55,55,1,0,0,0,3,156,156,156,1,50,50,50, + 1,0,0,0,5,240,240,240,1,0,0,0,22,22,22,22,1,240,240,240, + 1,37,37,37,1,0,0,0,2,232,232,232,1,240,240,240,1,210,210,210, + 1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0, + 2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187, + 1,240,240,240,2,0,0) + ); + +const + objdata_tbase64handler: record size: integer; data: array[0..2177] of byte end = + (size: 2178; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,98,97, + 115,101,54,52,104,97,110,100,108,101,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,8,8,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,68,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4, + 208,208,208,1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,23, + 0,0,0,1,208,208,208,1,0,0,0,4,208,208,208,11,0,0,0,2, + 208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,6,208,208,208,9, + 0,0,0,3,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,3, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,3,208,208,208,1, + 0,0,0,5,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,3, + 208,208,208,1,0,0,0,19,208,208,208,1,0,0,0,3,208,208,208,1, + 0,0,0,1,208,208,208,1,0,0,0,21,208,208,208,1,0,0,0,1, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,1, + 0,0,0,5,208,208,208,1,0,0,0,10,208,208,208,1,0,0,0,8, + 208,208,208,1,0,0,0,3,208,208,208,1,0,0,0,6,208,208,208,1, + 0,0,0,14,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,2, + 208,208,208,2,0,0,0,1,208,208,208,6,0,0,0,2,208,208,208,3, + 0,0,0,1,208,208,208,3,0,0,0,1,208,208,208,6,0,0,0,2, + 208,208,208,22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,23, + 0,0,0,2,208,208,208,1,0,0,0,11,208,208,208,2,0,0,0,7, + 208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,8,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,1,0,0,0,3, + 208,208,208,4,0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,1, + 0,0,0,2,208,208,208,2,0,0,0,7,208,208,208,1,0,0,0,4, + 208,208,208,3,0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,1, + 0,0,0,4,208,208,208,2,0,0,0,7,208,208,208,3,0,0,0,3, + 208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,1,208,208,208,4, + 0,0,0,1,208,208,208,7,0,0,0,3,208,208,208,2,0,0,0,4, + 208,208,208,2,0,0,0,2,208,208,208,10,0,0,0,3,208,208,208,3, + 0,0,0,2,208,208,208,5,0,0,0,1,208,208,208,22,0,0,0,3, + 208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,3,140,5,0,0,240,240,240,2, + 210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1, + 0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2, + 187,187,187,1,240,240,240,2,22,22,22,1,0,0,0,1,7,7,7,1, + 240,240,240,1,52,52,52,1,0,0,0,22,240,240,240,1,0,0,0,23, + 202,202,202,1,0,0,0,1,8,8,8,1,72,72,72,1,71,71,71,1, + 36,36,36,1,0,0,0,11,44,44,44,1,1,1,1,1,0,0,0,2, + 2,2,2,1,41,41,41,1,0,0,0,2,217,217,217,1,30,30,30,1, + 210,210,210,1,153,153,153,1,201,201,201,1,82,82,82,1,0,0,0,9, + 148,148,148,1,142,142,142,1,154,154,154,1,0,0,0,2,90,90,90,1, + 149,149,149,1,0,0,0,2,240,240,240,1,30,30,30,1,145,145,145,1, + 0,0,0,1,21,21,21,1,162,162,162,1,0,0,0,1,28,28,28,1, + 83,83,83,1,26,26,26,1,0,0,0,1,36,36,36,1,82,82,82,1, + 13,13,13,1,40,40,40,1,128,128,128,1,0,0,0,1,89,89,89,1, + 0,0,0,1,4,4,4,1,173,173,173,1,149,149,149,1,0,0,0,1, + 75,75,75,1,225,225,225,1,30,30,30,1,169,169,169,1,57,57,57,1, + 118,118,118,1,102,102,102,1,13,13,13,1,191,191,191,1,113,113,113,1, + 197,197,197,1,6,6,6,1,192,192,192,1,112,112,112,1,162,162,162,1, + 82,82,82,1,127,127,127,1,155,155,155,1,45,45,45,1,0,0,0,1, + 102,102,102,1,79,79,79,1,149,149,149,1,0,0,0,1,240,240,240,1, + 0,0,0,1,30,30,30,1,217,217,217,1,168,168,168,1,200,200,200,1, + 87,87,87,1,16,16,16,1,37,37,37,1,31,31,31,1,198,198,198,1, + 11,11,11,1,194,194,194,1,42,42,42,1,27,27,27,1,98,98,98,1, + 187,187,187,1,53,53,53,1,180,180,180,1,8,8,8,1,157,157,157,1, + 18,18,18,1,149,149,149,1,0,0,0,1,240,240,240,1,0,0,0,1, + 30,30,30,1,145,145,145,1,0,0,0,1,2,2,2,1,189,189,189,1, + 18,18,18,1,195,195,195,1,156,156,156,1,204,204,204,1,0,0,0,1, + 78,78,78,1,202,202,202,1,155,155,155,1,61,61,61,1,102,102,102,1, + 0,0,0,1,155,155,155,1,106,106,106,1,183,183,183,1,151,151,151,1, + 209,209,209,1,43,43,43,1,135,135,135,1,45,45,45,1,30,30,30,1, + 145,145,145,1,0,0,0,1,13,13,13,1,195,195,195,1,80,80,80,1, + 100,100,100,1,1,1,1,1,209,209,209,1,23,23,23,1,96,96,96,1, + 0,0,0,1,187,187,187,1,13,13,13,1,135,135,135,1,0,0,0,1, + 179,179,179,1,30,30,30,1,64,64,64,1,77,77,77,1,176,176,176,1, + 19,19,19,1,0,0,0,1,240,240,240,1,30,30,30,1,238,238,238,1, + 215,215,215,1,216,216,216,1,83,83,83,1,24,24,24,1,195,195,195,1, + 173,173,173,1,195,195,195,1,23,23,23,1,164,164,164,1,184,184,184,1, + 144,144,144,1,0,0,0,1,127,127,127,1,186,186,186,1,129,129,129,1, + 0,0,0,2,18,18,18,1,149,149,149,1,0,0,0,2,240,240,240,1, + 0,0,0,6,6,6,6,2,0,0,0,3,12,12,12,1,0,0,0,3, + 8,8,8,1,0,0,0,6,135,135,135,1,165,165,165,1,0,0,0,22, + 240,240,240,1,0,0,0,23,240,240,240,1,0,0,0,23,75,75,75,1, + 105,105,105,1,0,0,0,1,52,52,52,1,159,159,159,1,168,168,168,1, + 124,124,124,1,5,5,5,1,65,65,65,1,119,119,119,1,176,176,176,1, + 125,125,125,1,160,160,160,1,27,27,27,1,0,0,0,2,143,143,143,1, + 37,37,37,1,137,137,137,1,107,107,107,1,167,167,167,1,161,161,161,1, + 55,55,55,1,0,0,0,2,240,240,240,1,30,30,30,1,237,237,237,1, + 41,41,41,1,0,0,0,1,124,124,124,1,84,84,84,1,95,95,95,1, + 229,229,229,1,34,34,34,1,22,22,22,1,133,133,133,1,140,140,140,1, + 0,0,0,1,51,51,51,1,206,206,206,1,0,0,0,1,199,199,199,1, + 162,162,162,1,8,8,8,1,35,35,35,1,234,234,234,1,27,27,27,1, + 0,0,0,1,240,240,240,1,90,90,90,1,184,184,184,1,0,0,0,4, + 95,95,95,1,169,169,169,1,0,0,0,2,21,21,21,1,231,231,231,1, + 15,15,15,1,169,169,169,1,85,85,85,1,0,0,0,1,199,199,199,1, + 64,64,64,1,0,0,0,2,183,183,183,1,86,86,86,1,202,202,202,1, + 97,97,97,1,27,27,27,1,224,224,224,1,1,1,1,1,0,0,0,1, + 76,76,76,1,100,100,100,1,95,95,95,1,160,160,160,1,0,0,0,3, + 144,144,144,1,136,136,136,1,212,212,212,1,2,2,2,1,0,0,0,1, + 199,199,199,1,108,108,108,1,0,0,0,1,5,5,5,1,235,235,235,1, + 43,43,43,1,240,240,240,1,0,0,0,2,112,112,112,1,168,168,168,1, + 155,155,155,1,180,180,180,1,27,27,27,1,95,95,95,1,160,160,160,1, + 0,0,0,3,27,27,27,1,247,247,247,1,96,96,96,1,0,0,0,2, + 199,199,199,1,196,196,196,1,165,165,165,1,199,199,199,1,114,114,114,1, + 0,0,0,1,240,240,240,1,0,0,0,4,7,7,7,1,0,0,0,7, + 33,33,33,1,213,213,213,1,4,4,4,1,0,0,0,2,199,199,199,1, + 64,64,64,1,10,10,10,1,1,1,1,1,0,0,0,2,7,7,7,1, + 172,172,172,1,0,0,0,10,119,119,119,1,198,198,198,1,55,55,55,1, + 0,0,0,3,156,156,156,1,50,50,50,1,0,0,0,5,240,240,240,1, + 0,0,0,22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2, + 232,232,232,1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1, + 240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2, + 90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tsymciphercryptohandler: record size: integer; data: array[0..2182] of byte end = + (size: 2183; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,23,116,115,121, + 109,99,105,112,104,101,114,99,114,121,112,116,111,104,97,110,100,108,101,114, + 23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99, + 111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116, + 105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111, + 95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,4,8,0,0,0,0,0,0,6,0,0,0,24,0,0, + 0,24,0,0,0,92,2,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 4,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,3,208,208,208, + 22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,2,0,0,0, + 4,208,208,208,1,0,0,0,3,208,208,208,3,0,0,0,4,208,208,208, + 3,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,1,0,0,0, + 2,208,208,208,2,0,0,0,6,208,208,208,2,0,0,0,3,208,208,208, + 1,0,0,0,3,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0, + 6,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,10,208,208,208, + 3,0,0,0,4,208,208,208,2,0,0,0,3,208,208,208,1,0,0,0, + 5,208,208,208,2,0,0,0,5,208,208,208,3,0,0,0,3,208,208,208, + 2,0,0,0,9,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0, + 3,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,13,208,208,208, + 1,0,0,0,3,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0, + 5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,7,208,208,208, + 3,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0, + 2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208, + 3,0,0,0,1,208,208,208,18,0,0,0,2,208,208,208,22,0,0,0, + 1,208,208,208,23,0,0,0,1,208,208,208,23,0,0,0,2,208,208,208, + 1,0,0,0,11,208,208,208,2,0,0,0,7,208,208,208,2,0,0,0, + 4,208,208,208,1,0,0,0,8,208,208,208,1,0,0,0,2,208,208,208, + 1,0,0,0,6,208,208,208,1,0,0,0,3,208,208,208,4,0,0,0, + 2,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,7,208,208,208,1,0,0,0,4,208,208,208,3,0,0,0, + 4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208, + 2,0,0,0,7,208,208,208,3,0,0,0,3,208,208,208,2,0,0,0, + 5,208,208,208,1,0,0,0,1,208,208,208,4,0,0,0,1,208,208,208, + 7,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 2,208,208,208,10,0,0,0,3,208,208,208,3,0,0,0,2,208,208,208, + 5,0,0,0,1,208,208,208,22,0,0,0,3,208,208,208,2,0,0,0, + 3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208, + 2,0,0,0,3,112,5,0,0,240,240,240,2,210,210,210,1,0,0,0, + 2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120, + 1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240, + 2,22,22,22,1,0,0,0,1,7,7,7,1,240,240,240,1,52,52,52, + 1,0,0,0,22,240,240,240,1,0,0,0,23,202,202,202,1,0,0,0, + 2,6,6,6,1,67,67,67,1,88,88,88,1,36,36,36,1,0,0,0, + 1,7,7,7,1,71,71,71,1,3,3,3,1,0,0,0,3,55,55,55, + 1,25,25,25,1,50,50,50,1,56,56,56,1,0,0,0,3,6,6,6, + 1,72,72,72,1,17,17,17,1,0,0,0,1,217,217,217,1,5,5,5, + 1,196,196,196,1,168,168,168,1,133,133,133,1,211,211,211,1,107,107,107, + 1,0,0,0,1,174,174,174,1,118,118,118,1,0,0,0,2,50,50,50, + 1,216,216,216,1,12,12,12,1,179,179,179,1,243,243,243,1,11,11,11, + 1,0,0,0,2,80,80,80,1,255,255,255,1,60,60,60,1,0,0,0, + 1,240,240,240,1,57,57,57,1,193,193,193,1,0,0,0,2,30,30,30, + 1,183,183,183,1,0,0,0,1,22,22,22,1,227,227,227,1,39,39,39, + 1,5,5,5,1,205,205,205,1,58,58,58,1,0,0,0,1,179,179,179, + 1,196,196,196,1,87,87,87,1,0,0,0,2,167,167,167,1,203,203,203, + 1,60,60,60,1,75,75,75,1,225,225,225,1,12,12,12,1,216,216,216, + 1,153,153,153,1,65,65,65,1,5,5,5,1,0,0,0,3,86,86,86, + 1,190,190,190,1,118,118,118,1,133,133,133,1,0,0,0,2,179,179,179, + 1,109,109,109,1,174,174,174,1,0,0,0,1,11,11,11,1,188,188,188, + 1,171,171,171,1,60,60,60,1,240,240,240,1,0,0,0,2,19,19,19, + 1,112,112,112,1,192,192,192,1,236,236,236,1,107,107,107,1,0,0,0, + 3,171,171,171,1,203,203,203,1,5,5,5,1,0,0,0,2,179,179,179, + 1,60,60,60,1,209,209,209,1,13,13,13,1,89,89,89,1,109,109,109, + 1,171,171,171,1,60,60,60,1,240,240,240,1,0,0,0,1,47,47,47, + 1,42,42,42,1,0,0,0,2,26,26,26,1,226,226,226,1,25,25,25, + 1,0,0,0,2,100,100,100,1,139,139,139,1,0,0,0,3,179,179,179, + 1,60,60,60,1,131,131,131,1,92,92,92,1,174,174,174,1,23,23,23, + 1,171,171,171,1,60,60,60,1,135,135,135,1,45,45,45,1,80,80,80, + 1,189,189,189,1,9,9,9,1,0,0,0,1,13,13,13,1,216,216,216, + 1,17,17,17,1,0,0,0,2,100,100,100,1,139,139,139,1,0,0,0, + 3,179,179,179,1,60,60,60,1,45,45,45,1,187,187,187,1,179,179,179, + 1,0,0,0,1,171,171,171,1,60,60,60,1,0,0,0,1,240,240,240, + 1,2,2,2,1,134,134,134,1,223,223,223,1,202,202,202,1,220,220,220, + 1,93,93,93,1,0,0,0,3,100,100,100,1,139,139,139,1,0,0,0, + 3,179,179,179,1,60,60,60,1,0,0,0,1,214,214,214,1,97,97,97, + 1,0,0,0,1,171,171,171,1,60,60,60,1,0,0,0,1,240,240,240, + 1,0,0,0,3,20,20,20,1,0,0,0,18,135,135,135,1,165,165,165, + 1,0,0,0,22,240,240,240,1,0,0,0,23,240,240,240,1,0,0,0, + 23,75,75,75,1,105,105,105,1,0,0,0,1,52,52,52,1,159,159,159, + 1,168,168,168,1,124,124,124,1,5,5,5,1,65,65,65,1,119,119,119, + 1,176,176,176,1,125,125,125,1,160,160,160,1,27,27,27,1,0,0,0, + 2,143,143,143,1,37,37,37,1,137,137,137,1,107,107,107,1,167,167,167, + 1,161,161,161,1,55,55,55,1,0,0,0,2,240,240,240,1,30,30,30, + 1,237,237,237,1,41,41,41,1,0,0,0,1,124,124,124,1,84,84,84, + 1,95,95,95,1,229,229,229,1,34,34,34,1,22,22,22,1,133,133,133, + 1,140,140,140,1,0,0,0,1,51,51,51,1,206,206,206,1,0,0,0, + 1,199,199,199,1,162,162,162,1,8,8,8,1,35,35,35,1,234,234,234, + 1,27,27,27,1,0,0,0,1,240,240,240,1,90,90,90,1,184,184,184, + 1,0,0,0,4,95,95,95,1,169,169,169,1,0,0,0,2,21,21,21, + 1,231,231,231,1,15,15,15,1,169,169,169,1,85,85,85,1,0,0,0, + 1,199,199,199,1,64,64,64,1,0,0,0,2,183,183,183,1,86,86,86, + 1,202,202,202,1,97,97,97,1,27,27,27,1,224,224,224,1,1,1,1, + 1,0,0,0,1,76,76,76,1,100,100,100,1,95,95,95,1,160,160,160, + 1,0,0,0,3,144,144,144,1,136,136,136,1,212,212,212,1,2,2,2, + 1,0,0,0,1,199,199,199,1,108,108,108,1,0,0,0,1,5,5,5, + 1,235,235,235,1,43,43,43,1,240,240,240,1,0,0,0,2,112,112,112, + 1,168,168,168,1,155,155,155,1,180,180,180,1,27,27,27,1,95,95,95, + 1,160,160,160,1,0,0,0,3,27,27,27,1,247,247,247,1,96,96,96, + 1,0,0,0,2,199,199,199,1,196,196,196,1,165,165,165,1,199,199,199, + 1,114,114,114,1,0,0,0,1,240,240,240,1,0,0,0,4,7,7,7, + 1,0,0,0,7,33,33,33,1,213,213,213,1,4,4,4,1,0,0,0, + 2,199,199,199,1,64,64,64,1,10,10,10,1,1,1,1,1,0,0,0, + 2,7,7,7,1,172,172,172,1,0,0,0,10,119,119,119,1,198,198,198, + 1,55,55,55,1,0,0,0,3,156,156,156,1,50,50,50,1,0,0,0, + 5,240,240,240,1,0,0,0,22,22,22,22,1,240,240,240,1,37,37,37, + 1,0,0,0,2,232,232,232,1,240,240,240,1,210,210,210,1,0,0,0, + 2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120, + 1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240, + 2,0,0) + ); + +const + objdata_tasymciphercryptohandler: record size: integer; data: array[0..2275] of byte end = + (size: 2276; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,24,116,97,115, + 121,109,99,105,112,104,101,114,99,114,121,112,116,111,104,97,110,100,108,101, + 114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109, + 111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,96,8,0,0,0,0,0,0,6,0,0,0,24,0, + 0,0,24,0,0,0,132,2,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0, + 0,4,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,3,208,208, + 208,22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,3,0,0, + 0,2,208,208,208,2,0,0,0,3,208,208,208,1,0,0,0,2,208,208, + 208,2,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,6,208,208, + 208,1,0,0,0,5,208,208,208,1,0,0,0,3,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,3,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,7,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,3,208,208, + 208,2,0,0,0,7,208,208,208,1,0,0,0,4,208,208,208,2,0,0, + 0,4,208,208,208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,8,208,208,208,1,0,0,0,7,208,208,208,1,0,0, + 0,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,11,208,208, + 208,2,0,0,0,3,208,208,208,1,0,0,0,2,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,7,208,208,208,1,0,0,0,3,208,208, + 208,2,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,1,208,208, + 208,7,0,0,0,2,208,208,208,13,0,0,0,2,208,208,208,22,0,0, + 0,1,208,208,208,23,0,0,0,1,208,208,208,23,0,0,0,2,208,208, + 208,1,0,0,0,11,208,208,208,2,0,0,0,7,208,208,208,2,0,0, + 0,4,208,208,208,1,0,0,0,8,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,6,208,208,208,1,0,0,0,3,208,208,208,4,0,0, + 0,2,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,2,208,208, + 208,2,0,0,0,7,208,208,208,1,0,0,0,4,208,208,208,3,0,0, + 0,4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208, + 208,2,0,0,0,7,208,208,208,3,0,0,0,3,208,208,208,2,0,0, + 0,5,208,208,208,1,0,0,0,1,208,208,208,4,0,0,0,1,208,208, + 208,7,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0, + 0,2,208,208,208,10,0,0,0,3,208,208,208,3,0,0,0,2,208,208, + 208,5,0,0,0,1,208,208,208,22,0,0,0,3,208,208,208,2,0,0, + 0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208, + 208,2,0,0,0,3,164,5,0,0,240,240,240,2,210,210,210,1,0,0, + 0,2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120, + 120,1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240, + 240,2,22,22,22,1,0,0,0,1,7,7,7,1,240,240,240,1,52,52, + 52,1,0,0,0,22,240,240,240,1,0,0,0,23,202,202,202,1,0,0, + 0,3,47,47,47,1,12,12,12,1,0,0,0,2,12,12,12,1,82,82, + 82,1,53,53,53,1,0,0,0,1,37,37,37,1,22,22,22,1,0,0, + 0,2,40,40,40,1,21,21,21,1,72,72,72,1,4,4,4,1,0,0, + 0,2,63,63,63,1,6,6,6,1,0,0,0,1,217,217,217,1,0,0, + 0,2,200,200,200,1,94,94,94,1,0,0,0,2,179,179,179,1,144,144, + 144,1,189,189,189,1,95,95,95,1,53,53,53,1,160,160,160,1,0,0, + 0,1,3,3,3,1,195,195,195,1,17,17,17,1,254,254,254,1,57,57, + 57,1,0,0,0,1,15,15,15,1,252,252,252,1,23,23,23,1,0,0, + 0,1,240,240,240,1,0,0,0,1,32,32,32,1,142,142,142,1,163,163, + 163,1,0,0,0,1,16,16,16,1,168,168,168,1,0,0,0,1,11,11, + 11,1,145,145,145,1,0,0,0,1,179,179,179,1,33,33,33,1,90,90, + 90,1,109,109,109,1,8,8,8,1,211,211,211,1,120,120,120,1,0,0, + 0,1,78,78,78,1,217,217,217,1,23,23,23,1,75,75,75,1,225,225, + 225,1,0,0,0,1,104,104,104,1,68,68,68,1,173,173,173,1,7,7, + 7,1,0,0,0,1,202,202,202,1,116,116,116,1,18,18,18,1,0,0, + 0,2,57,57,57,1,149,149,149,1,179,179,179,1,7,7,7,1,8,8, + 8,1,168,168,168,1,162,162,162,1,0,0,0,1,136,136,136,1,160,160, + 160,1,23,23,23,1,240,240,240,1,0,0,0,2,166,166,166,1,7,7, + 7,1,114,114,114,1,72,72,72,1,0,0,0,1,27,27,27,1,144,144, + 144,1,229,229,229,1,96,96,96,1,0,0,0,2,184,184,184,1,102,102, + 102,1,0,0,0,1,8,8,8,1,167,167,167,1,158,158,158,1,4,4, + 4,1,144,144,144,1,152,152,152,1,23,23,23,1,240,240,240,1,0,0, + 0,1,6,6,6,1,225,225,225,1,208,208,208,1,210,210,210,1,150,150, + 150,1,25,25,25,1,39,39,39,1,0,0,0,1,13,13,13,1,193,193, + 193,1,0,0,0,2,135,135,135,1,48,48,48,1,0,0,0,1,8,8, + 8,1,167,167,167,1,106,106,106,1,78,78,78,1,122,122,122,1,152,152, + 152,1,23,23,23,1,135,135,135,1,45,45,45,1,66,66,66,1,121,121, + 121,1,0,0,0,2,199,199,199,1,33,33,33,1,171,171,171,1,0,0, + 0,1,6,6,6,1,178,178,178,1,0,0,0,2,135,135,135,1,48,48, + 48,1,0,0,0,1,8,8,8,1,167,167,167,1,41,41,41,1,200,200, + 200,1,57,57,57,1,152,152,152,1,23,23,23,1,0,0,0,1,240,240, + 240,1,138,138,138,1,51,51,51,1,0,0,0,2,155,155,155,1,50,50, + 50,1,136,136,136,1,213,213,213,1,216,216,216,1,84,84,84,1,0,0, + 0,2,135,135,135,1,48,48,48,1,0,0,0,1,8,8,8,1,167,167, + 167,1,0,0,0,1,219,219,219,1,4,4,4,1,152,152,152,1,23,23, + 23,1,0,0,0,1,240,240,240,1,0,0,0,7,9,9,9,1,6,6, + 6,1,0,0,0,13,135,135,135,1,165,165,165,1,0,0,0,22,240,240, + 240,1,0,0,0,23,240,240,240,1,0,0,0,23,75,75,75,1,105,105, + 105,1,0,0,0,1,52,52,52,1,159,159,159,1,168,168,168,1,124,124, + 124,1,5,5,5,1,65,65,65,1,119,119,119,1,176,176,176,1,125,125, + 125,1,160,160,160,1,27,27,27,1,0,0,0,2,143,143,143,1,37,37, + 37,1,137,137,137,1,107,107,107,1,167,167,167,1,161,161,161,1,55,55, + 55,1,0,0,0,2,240,240,240,1,30,30,30,1,237,237,237,1,41,41, + 41,1,0,0,0,1,124,124,124,1,84,84,84,1,95,95,95,1,229,229, + 229,1,34,34,34,1,22,22,22,1,133,133,133,1,140,140,140,1,0,0, + 0,1,51,51,51,1,206,206,206,1,0,0,0,1,199,199,199,1,162,162, + 162,1,8,8,8,1,35,35,35,1,234,234,234,1,27,27,27,1,0,0, + 0,1,240,240,240,1,90,90,90,1,184,184,184,1,0,0,0,4,95,95, + 95,1,169,169,169,1,0,0,0,2,21,21,21,1,231,231,231,1,15,15, + 15,1,169,169,169,1,85,85,85,1,0,0,0,1,199,199,199,1,64,64, + 64,1,0,0,0,2,183,183,183,1,86,86,86,1,202,202,202,1,97,97, + 97,1,27,27,27,1,224,224,224,1,1,1,1,1,0,0,0,1,76,76, + 76,1,100,100,100,1,95,95,95,1,160,160,160,1,0,0,0,3,144,144, + 144,1,136,136,136,1,212,212,212,1,2,2,2,1,0,0,0,1,199,199, + 199,1,108,108,108,1,0,0,0,1,5,5,5,1,235,235,235,1,43,43, + 43,1,240,240,240,1,0,0,0,2,112,112,112,1,168,168,168,1,155,155, + 155,1,180,180,180,1,27,27,27,1,95,95,95,1,160,160,160,1,0,0, + 0,3,27,27,27,1,247,247,247,1,96,96,96,1,0,0,0,2,199,199, + 199,1,196,196,196,1,165,165,165,1,199,199,199,1,114,114,114,1,0,0, + 0,1,240,240,240,1,0,0,0,4,7,7,7,1,0,0,0,7,33,33, + 33,1,213,213,213,1,4,4,4,1,0,0,0,2,199,199,199,1,64,64, + 64,1,10,10,10,1,1,1,1,1,0,0,0,2,7,7,7,1,172,172, + 172,1,0,0,0,10,119,119,119,1,198,198,198,1,55,55,55,1,0,0, + 0,3,156,156,156,1,50,50,50,1,0,0,0,5,240,240,240,1,0,0, + 0,22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232,232, + 232,1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240,240, + 240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90, + 90,1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tzstreamhandler: record size: integer; data: array[0..1834] of byte end = + (size: 1835; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,122,115, + 116,114,101,97,109,104,97,110,100,108,101,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,176,6,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,252,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 4,208,208,208,1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208, + 23,0,0,0,1,208,208,208,6,0,0,0,10,208,208,208,8,0,0,0, + 1,208,208,208,5,0,0,0,10,208,208,208,8,0,0,0,1,208,208,208, + 7,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,6,0,0,0, + 2,208,208,208,6,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208, + 5,0,0,0,1,208,208,208,7,0,0,0,2,208,208,208,2,0,0,0, + 7,208,208,208,5,0,0,0,1,208,208,208,6,0,0,0,3,208,208,208, + 2,0,0,0,7,208,208,208,5,0,0,0,2,208,208,208,5,0,0,0, + 2,208,208,208,3,0,0,0,7,208,208,208,6,0,0,0,1,208,208,208, + 5,0,0,0,12,208,208,208,6,0,0,0,1,208,208,208,14,0,0,0, + 2,208,208,208,6,0,0,0,2,208,208,208,22,0,0,0,1,208,208,208, + 23,0,0,0,1,208,208,208,23,0,0,0,2,208,208,208,1,0,0,0, + 11,208,208,208,2,0,0,0,7,208,208,208,2,0,0,0,4,208,208,208, + 1,0,0,0,8,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0, + 6,208,208,208,1,0,0,0,3,208,208,208,4,0,0,0,2,208,208,208, + 2,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0, + 7,208,208,208,1,0,0,0,4,208,208,208,3,0,0,0,4,208,208,208, + 1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,2,0,0,0, + 7,208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,5,208,208,208, + 1,0,0,0,1,208,208,208,4,0,0,0,1,208,208,208,7,0,0,0, + 3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208, + 10,0,0,0,3,208,208,208,3,0,0,0,2,208,208,208,5,0,0,0, + 1,208,208,208,22,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 3,124,4,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60, + 1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240, + 2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22, + 1,0,0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0, + 22,240,240,240,1,0,0,0,23,202,202,202,1,0,0,0,6,43,43,43, + 1,72,72,72,3,17,17,17,1,49,49,49,1,21,21,21,1,26,26,26, + 1,44,44,44,1,2,2,2,1,0,0,0,8,217,217,217,1,0,0,0, + 5,91,91,91,1,152,152,152,2,228,228,228,1,48,48,48,1,175,175,175, + 1,56,56,56,1,69,69,69,1,158,158,158,1,9,9,9,1,0,0,0, + 8,240,240,240,1,0,0,0,7,53,53,53,1,175,175,175,1,0,0,0, + 1,175,175,175,1,21,21,21,1,26,26,26,1,158,158,158,1,28,28,28, + 1,62,62,62,1,0,0,0,6,75,75,75,1,225,225,225,1,0,0,0, + 6,1,1,1,1,193,193,193,1,34,34,34,1,0,0,0,1,175,175,175, + 1,75,75,75,1,92,92,92,1,158,158,158,1,164,164,164,1,170,170,170, + 1,83,83,83,1,0,0,0,5,240,240,240,1,0,0,0,7,98,98,98, + 1,129,129,129,1,0,0,0,2,175,175,175,1,75,75,75,1,92,92,92, + 1,158,158,158,1,38,38,38,1,23,23,23,1,168,168,168,1,0,0,0, + 5,240,240,240,1,0,0,0,6,15,15,15,1,201,201,201,1,9,9,9, + 1,0,0,0,2,175,175,175,1,75,75,75,1,92,92,92,1,157,157,157, + 1,5,5,5,1,2,2,2,1,170,170,170,1,0,0,0,5,135,135,135, + 1,45,45,45,1,0,0,0,5,144,144,144,1,79,79,79,1,0,0,0, + 3,175,175,175,1,75,75,75,1,92,92,92,1,158,158,158,1,48,48,48, + 1,44,44,44,1,119,119,119,1,0,0,0,6,240,240,240,1,0,0,0, + 5,231,231,231,1,216,216,216,3,71,71,71,1,175,175,175,1,75,75,75, + 1,92,92,92,1,154,154,154,1,161,161,161,1,184,184,184,1,34,34,34, + 1,0,0,0,6,240,240,240,1,0,0,0,14,1,1,1,1,4,4,4, + 1,0,0,0,6,135,135,135,1,165,165,165,1,0,0,0,22,240,240,240, + 1,0,0,0,23,240,240,240,1,0,0,0,23,75,75,75,1,105,105,105, + 1,0,0,0,1,52,52,52,1,159,159,159,1,168,168,168,1,124,124,124, + 1,5,5,5,1,65,65,65,1,119,119,119,1,176,176,176,1,125,125,125, + 1,160,160,160,1,27,27,27,1,0,0,0,2,143,143,143,1,37,37,37, + 1,137,137,137,1,107,107,107,1,167,167,167,1,161,161,161,1,55,55,55, + 1,0,0,0,2,240,240,240,1,30,30,30,1,237,237,237,1,41,41,41, + 1,0,0,0,1,124,124,124,1,84,84,84,1,95,95,95,1,229,229,229, + 1,34,34,34,1,22,22,22,1,133,133,133,1,140,140,140,1,0,0,0, + 1,51,51,51,1,206,206,206,1,0,0,0,1,199,199,199,1,162,162,162, + 1,8,8,8,1,35,35,35,1,234,234,234,1,27,27,27,1,0,0,0, + 1,240,240,240,1,90,90,90,1,184,184,184,1,0,0,0,4,95,95,95, + 1,169,169,169,1,0,0,0,2,21,21,21,1,231,231,231,1,15,15,15, + 1,169,169,169,1,85,85,85,1,0,0,0,1,199,199,199,1,64,64,64, + 1,0,0,0,2,183,183,183,1,86,86,86,1,202,202,202,1,97,97,97, + 1,27,27,27,1,224,224,224,1,1,1,1,1,0,0,0,1,76,76,76, + 1,100,100,100,1,95,95,95,1,160,160,160,1,0,0,0,3,144,144,144, + 1,136,136,136,1,212,212,212,1,2,2,2,1,0,0,0,1,199,199,199, + 1,108,108,108,1,0,0,0,1,5,5,5,1,235,235,235,1,43,43,43, + 1,240,240,240,1,0,0,0,2,112,112,112,1,168,168,168,1,155,155,155, + 1,180,180,180,1,27,27,27,1,95,95,95,1,160,160,160,1,0,0,0, + 3,27,27,27,1,247,247,247,1,96,96,96,1,0,0,0,2,199,199,199, + 1,196,196,196,1,165,165,165,1,199,199,199,1,114,114,114,1,0,0,0, + 1,240,240,240,1,0,0,0,4,7,7,7,1,0,0,0,7,33,33,33, + 1,213,213,213,1,4,4,4,1,0,0,0,2,199,199,199,1,64,64,64, + 1,10,10,10,1,1,1,1,1,0,0,0,2,7,7,7,1,172,172,172, + 1,0,0,0,10,119,119,119,1,198,198,198,1,55,55,55,1,0,0,0, + 3,156,156,156,1,50,50,50,1,0,0,0,5,240,240,240,1,0,0,0, + 22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232,232,232, + 1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240, + 2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90, + 1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tdigesthandler: record size: integer; data: array[0..2201] of byte end = + (size: 2202; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,105, + 103,101,115,116,104,97,110,100,108,101,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,32,8,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,76,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4, + 208,208,208,1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,23, + 0,0,0,1,208,208,208,4,0,0,0,4,208,208,208,13,0,0,0,1, + 208,208,208,2,0,0,0,1,208,208,208,3,0,0,0,4,208,208,208,12, + 0,0,0,2,208,208,208,2,0,0,0,1,208,208,208,2,0,0,0,9, + 208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,20, + 208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,7,208,208,208,1, + 0,0,0,12,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,1, + 208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,12,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,20,208,208,208,2,0,0,0,1, + 208,208,208,1,0,0,0,20,208,208,208,2,0,0,0,1,208,208,208,2, + 0,0,0,1,208,208,208,4,0,0,0,1,208,208,208,1,0,0,0,2, + 208,208,208,2,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,2, + 0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,7,0,0,0,4, + 208,208,208,11,0,0,0,1,208,208,208,9,0,0,0,2,208,208,208,12, + 0,0,0,1,208,208,208,23,0,0,0,2,208,208,208,1,0,0,0,11, + 208,208,208,2,0,0,0,7,208,208,208,2,0,0,0,4,208,208,208,1, + 0,0,0,8,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,6, + 208,208,208,1,0,0,0,3,208,208,208,4,0,0,0,2,208,208,208,2, + 0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,7, + 208,208,208,1,0,0,0,4,208,208,208,3,0,0,0,4,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,2,0,0,0,7, + 208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,5,208,208,208,1, + 0,0,0,1,208,208,208,4,0,0,0,1,208,208,208,7,0,0,0,3, + 208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,10, + 0,0,0,3,208,208,208,3,0,0,0,2,208,208,208,5,0,0,0,1, + 208,208,208,22,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,3, + 156,5,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1, + 240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2, + 90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1, + 0,0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0,22, + 240,240,240,1,0,0,0,23,202,202,202,1,0,0,0,4,3,3,3,1, + 43,43,43,1,25,25,25,1,21,21,21,1,0,0,0,13,1,1,1,1, + 0,0,0,2,217,217,217,1,0,0,0,3,12,12,12,1,155,155,155,1, + 69,69,69,1,56,56,56,1,0,0,0,12,77,77,77,1,60,60,60,1, + 0,0,0,2,240,240,240,1,0,0,0,2,58,58,58,1,48,48,48,1, + 155,155,155,1,25,25,25,1,21,21,21,1,2,2,2,1,63,63,63,1, + 17,17,17,1,36,36,36,1,0,0,0,1,23,23,23,1,41,41,41,1, + 0,0,0,2,66,66,66,1,65,65,65,1,0,0,0,1,141,141,141,1, + 109,109,109,1,0,0,0,1,75,75,75,1,225,225,225,1,0,0,0,1, + 88,88,88,1,164,164,164,1,177,177,177,1,155,155,155,1,92,92,92,1, + 75,75,75,1,122,122,122,1,145,145,145,1,179,179,179,1,129,129,129,1, + 52,52,52,1,170,170,170,1,151,151,151,1,88,88,88,1,74,74,74,1, + 158,158,158,1,157,157,157,1,82,82,82,1,161,161,161,1,135,135,135,1, + 0,0,0,1,240,240,240,1,0,0,0,2,174,174,174,1,13,13,13,1, + 52,52,52,1,155,155,155,1,92,92,92,1,75,75,75,1,186,186,186,1, + 0,0,0,1,75,75,75,1,129,129,129,1,125,125,125,1,63,63,63,1, + 32,32,32,1,152,152,152,1,93,93,93,1,139,139,139,1,24,24,24,1, + 18,18,18,1,105,105,105,1,62,62,62,1,0,0,0,1,240,240,240,1, + 0,0,0,2,179,179,179,1,0,0,0,1,17,17,17,1,155,155,155,1, + 92,92,92,1,75,75,75,1,175,175,175,1,0,0,0,1,46,46,46,1, + 129,129,129,1,165,165,165,1,155,155,155,1,152,152,152,1,130,130,130,1, + 4,4,4,1,129,129,129,1,222,222,222,1,78,78,78,1,105,105,105,1, + 62,62,62,1,0,0,0,1,135,135,135,1,45,45,45,1,0,0,0,1, + 159,159,159,1,33,33,33,1,58,58,58,1,155,155,155,1,92,92,92,1, + 75,75,75,1,161,161,161,1,13,13,13,1,104,104,104,1,129,129,129,1, + 112,112,112,1,54,54,54,1,8,8,8,1,113,113,113,1,77,77,77,1, + 38,38,38,1,31,31,31,1,156,156,156,1,103,103,103,1,64,64,64,1, + 0,0,0,2,240,240,240,1,0,0,0,1,45,45,45,1,208,208,208,1, + 154,154,154,1,155,155,155,1,92,92,92,1,75,75,75,1,48,48,48,1, + 183,183,183,1,165,165,165,1,121,121,121,1,30,30,30,1,178,178,178,1, + 188,188,188,1,76,76,76,1,34,34,34,1,192,192,192,1,196,196,196,1, + 69,69,69,1,68,68,68,1,207,207,207,1,0,0,0,2,240,240,240,1, + 0,0,0,2,7,7,7,1,0,0,0,4,80,80,80,1,0,0,0,1, + 72,72,72,1,95,95,95,1,0,0,0,2,8,8,8,1,0,0,0,2, + 2,2,2,1,10,10,10,1,0,0,0,2,5,5,5,1,0,0,0,1, + 135,135,135,1,165,165,165,1,0,0,0,7,102,102,102,1,175,175,175,1, + 192,192,192,1,20,20,20,1,0,0,0,11,240,240,240,1,0,0,0,9, + 11,11,11,1,1,1,1,1,0,0,0,12,240,240,240,1,0,0,0,23, + 75,75,75,1,105,105,105,1,0,0,0,1,52,52,52,1,159,159,159,1, + 168,168,168,1,124,124,124,1,5,5,5,1,65,65,65,1,119,119,119,1, + 176,176,176,1,125,125,125,1,160,160,160,1,27,27,27,1,0,0,0,2, + 143,143,143,1,37,37,37,1,137,137,137,1,107,107,107,1,167,167,167,1, + 161,161,161,1,55,55,55,1,0,0,0,2,240,240,240,1,30,30,30,1, + 237,237,237,1,41,41,41,1,0,0,0,1,124,124,124,1,84,84,84,1, + 95,95,95,1,229,229,229,1,34,34,34,1,22,22,22,1,133,133,133,1, + 140,140,140,1,0,0,0,1,51,51,51,1,206,206,206,1,0,0,0,1, + 199,199,199,1,162,162,162,1,8,8,8,1,35,35,35,1,234,234,234,1, + 27,27,27,1,0,0,0,1,240,240,240,1,90,90,90,1,184,184,184,1, + 0,0,0,4,95,95,95,1,169,169,169,1,0,0,0,2,21,21,21,1, + 231,231,231,1,15,15,15,1,169,169,169,1,85,85,85,1,0,0,0,1, + 199,199,199,1,64,64,64,1,0,0,0,2,183,183,183,1,86,86,86,1, + 202,202,202,1,97,97,97,1,27,27,27,1,224,224,224,1,1,1,1,1, + 0,0,0,1,76,76,76,1,100,100,100,1,95,95,95,1,160,160,160,1, + 0,0,0,3,144,144,144,1,136,136,136,1,212,212,212,1,2,2,2,1, + 0,0,0,1,199,199,199,1,108,108,108,1,0,0,0,1,5,5,5,1, + 235,235,235,1,43,43,43,1,240,240,240,1,0,0,0,2,112,112,112,1, + 168,168,168,1,155,155,155,1,180,180,180,1,27,27,27,1,95,95,95,1, + 160,160,160,1,0,0,0,3,27,27,27,1,247,247,247,1,96,96,96,1, + 0,0,0,2,199,199,199,1,196,196,196,1,165,165,165,1,199,199,199,1, + 114,114,114,1,0,0,0,1,240,240,240,1,0,0,0,4,7,7,7,1, + 0,0,0,7,33,33,33,1,213,213,213,1,4,4,4,1,0,0,0,2, + 199,199,199,1,64,64,64,1,10,10,10,1,1,1,1,1,0,0,0,2, + 7,7,7,1,172,172,172,1,0,0,0,10,119,119,119,1,198,198,198,1, + 55,55,55,1,0,0,0,3,156,156,156,1,50,50,50,1,0,0,0,5, + 240,240,240,1,0,0,0,22,22,22,22,1,240,240,240,1,37,37,37,1, + 0,0,0,2,232,232,232,1,240,240,240,1,210,210,210,1,0,0,0,2, + 60,60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1, + 240,240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2, + 0,0) + ); + +initialization + registerobjectdata(@objdata_tdummycryptohandler,tbitmapcomp,'tdummycryptohandler'); + registerobjectdata(@objdata_tbase64handler,tbitmapcomp,'tbase64handler'); + registerobjectdata(@objdata_tsymciphercryptohandler,tbitmapcomp,'tsymciphercryptohandler'); + registerobjectdata(@objdata_tasymciphercryptohandler,tbitmapcomp,'tasymciphercryptohandler'); + registerobjectdata(@objdata_tzstreamhandler,tbitmapcomp,'tzstreamhandler'); + registerobjectdata(@objdata_tdigesthandler,tbitmapcomp,'tdigesthandler'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdb.pas b/mseide-msegui/lib/common/regcomponents/regdb.pas new file mode 100644 index 0000000..8265e26 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdb.pas @@ -0,0 +1,1757 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regdb; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,typinfo,msesqldb,msedbedit,msepropertyeditors,msedb, + mseclasses,msetypes,msestrings, + mseglob,mseguiglob,msegui,msedatabase,msesqlresult,msedesignintf; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdbfieldnamepropertyeditor = class(tstringpropertyeditor) + private + fnocalc: boolean; + protected + fdbeditinfointf: idbeditinfo; + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tdbfieldnamenocalcpropertyeditor = class(tdbfieldnamepropertyeditor) + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + end; + + tdbcolnamepropertyeditor = class(tstringpropertyeditor) + protected + fdbcolinfointf: idbcolinfo; + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tdbcolnamearraypropertyeditor = class(tstringarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + + tdbparampropertyeditor = class(tclasspropertyeditor) + public + function getvalue: msestring; override; + end; + + tmseparampropertyeditor = class(tclasspropertyeditor) + public + function getvalue: msestring; override; + end; + + tdbparamnamepropertyeditor = class(tstringpropertyeditor) + protected + fdbparaminfointf: idbparaminfo; + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tdbfieldnamearraypropertyeditor = class(tstringarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tsqlpropertyeditor = class(ttextstringspropertyeditor) + private + factivebefore: boolean; + fdbactivebefore: boolean; + fintf: isqlpropertyeditor; + protected + function nocheck: boolean; virtual; + function getsyntaxindex: integer; override; + procedure doafterclosequery(var amodalresult: modalresultty); override; + function gettestbutton: boolean; override; + function getutf8: boolean; override; + function getcaption: msestring; override; + public + procedure edit; override; + end; + + tmsesqlpropertyeditor = class(tsqlpropertyeditor) + protected + function ismsestring: boolean; override; + end; + + tsqlnocheckpropertyeditor = class(tsqlpropertyeditor) + protected + function nocheck: boolean; override; + end; + + tmsesqlnocheckpropertyeditor = class(tmsesqlpropertyeditor) + protected + function nocheck: boolean; override; + end; +{ + tlbdropdowncolitemeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; +} + tlbdropdowncolseditor = class(tpersistentarraypropertyeditor) + protected + function itemgetvalue(const sender: tarrayelementeditor): msestring; + override; +// function geteditorclass: propertyeditorclassty; override; + end; +{ + tdbdropdowncolitemeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; +} + tdbdropdowncolseditor = class(tpersistentarraypropertyeditor) + protected + function itemgetvalue(const sender: tarrayelementeditor): msestring; + override; +// function geteditorclass: propertyeditorclassty; override; + end; +{ + tsqlmacroitemeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; +} + +implementation +uses + {$ifdef FPC}dbconst{$else} dbconst_del,classes_del{$endif},mdb, + mseibconnection,msefb3connection,msefbservice,msefb3service, + msepqconnection,mseodbcconn,{sqldb,} + mselookupbuffer,mselocaldataset, + msearrayutils,msedbfieldeditor,sysutils,msetexteditor, + msedbdispwidgets,msedbgraphics,regdb_bmp,msedbdialog,msegrids, + msedbcalendardatetimeedit,msemacros, + regwidgets,msebufdataset,msedbevents,msesqlite3conn,msqldb,msemysqlconn, + msedblookup; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tpropertyeditor1 = class(tpropertyeditor); + tlbdropdowncol1 = class(tlbdropdowncol); + tarrayelementeditor1 = class(tarrayelementeditor); + + tdatalinkpropertyeditor = class(tclasspropertyeditor) + public + function getvalue: msestring; override; + end; + + tfielddatalinkpropertyeditor = class(tdatalinkpropertyeditor) + public + function getvalue: msestring; override; + end; + + tnolistdropdowncolpropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tpersistentfieldelementeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tpersistentfieldspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + function geteditorclass: propertyeditorclassty; override; + public + procedure edit; override; + end; + + tfieldfieldnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + procedure setvalue(const value: msestring); override; + end; + + tfielddatasetpropertyeditor = class(tcomponentpropertyeditor) + protected + procedure checkcomponent(const avalue: tcomponent); override; + end; + + tonfilterpropertyeditor = class(tmethodpropertyeditor) + public + function getdefaultstate: propertystatesty; override; + procedure setvalue(const value: msestring); override; + end; + + toptionlbpropertyeditor = class(tsetelementeditor) + public + function getdefaultstate: propertystatesty; override; + procedure setvalue(const value: msestring); override; + end; + + toptionslbpropertyeditor = class(tsetpropertyeditor) + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + function getdefaultstate: propertystatesty; override; + procedure setvalue(const value: msestring); override; + end; + + tfielddefpropertyeditor = class(tclasspropertyeditor) + public + function getvalue: msestring; override; + end; + + tfielddefspropertyeditor = class(tcollectionpropertyeditor) + public + procedure setvalue(const value: msestring); override; + end; + + tdatasetactivepropertyeditor = class(tbooleanpropertyeditor) + public + function getdefaultstate: propertystatesty; override; + end; + + tdbstringcoleditor = class(tdatacoleditor) + public + function getvalue: msestring; override; + end; + + tdbstringcolseditor = class(tdatacolseditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tindexfieldnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tindexfieldpropertyeditor = class(tclasselementeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + end; + + tindexfieldspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tlocalindexpropertyeditor = class(tclasselementeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + end; + + tlocalindexespropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; +{ + tslaveparampropertyeditor = class(tclasselementeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + end; +} + tslaveparamspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; override; + function itemgetvalue( + const sender: tarrayelementeditor): msestring; override; + // function geteditorclass: propertyeditorclassty; override; + end; + + tslavefieldspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; override; + function itemgetvalue( + const sender: tarrayelementeditor): msestring; override; + // function geteditorclass: propertyeditorclassty; override; + end; + + tlookupbufferfieldnopropertyeditor = class(tordinalpropertyeditor) + private + fintf: ilookupbufferfieldinfo; + flbdatakind: lbdatakindty; + protected + function getdefaultstate: propertystatesty; override; + function getnames: msestringarty; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + function getvalues: msestringarty; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + end; + + tparamvaluepropertyeditor = class(tvariantpropertyeditor) + public + procedure setvalue(const value: msestring); override; + end; + + tlookupfieldnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tdatasetoptionspropertyeditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + public + end; + + tsqlresconncolnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + +procedure Register; +begin + registercomponents('DB',[ + tmseibconnection,tfbservice,tfb3service,tfb3connection, + tmsepqconnection,tsqlite3connection,tmseodbcconnection, + tmsemysqlconnection, + + tmsesqltransaction,tmsesqlquery, + tlocaldataset, + + tmsedatasource, + + tsqlstatement,tmsesqlscript,tsqlresult, + tsqllookupbuffer,tlookupbuffer,tdblookupbuffer,tdbmemolookupbuffer, + + tdbnavigator,tdbstringgrid + ]); + registercomponenttabhints(['DB'],['Database components']); + + registercomponents('DBe',[tdbwidgetgrid, + tdbstringedit,tdbmemoedit, + tdbintegeredit,tdbrealedit,tdbrealspinedit, + tdbdatetimeedit,tdbcalendardatetimeedit, + tdbbooleantextedit, + tdbbooleanedit,tdbbooleaneditradio, + tdbdatabutton, + tdbdataicon,tdbdataimage, + tdbprogressbar,tdbslider, + + tdbdropdownlistedit,tdbdropdownlisteditdb,tdbdropdownlisteditlb, + + tdbenumedit,tdbenumeditdb,tdbenumeditlb, + tdbenum64editdb,tdbenum64editlb, + tdbkeystringedit,tdbkeystringeditdb,tdbkeystringeditlb, + + tdbdialogstringedit,tdbmemodialogedit, + tdbdialogintegeredit,tdbdialogrealedit, + tdbdialogdatetimeedit, + tdbfilenameedit,tdbremotefilenameedit,tdbcoloredit, + + tdropdownlisteditdb,tdropdownlisteditlb, + tenumeditdb,tenumeditlb, + tenum64editdb,tenum64editlb, + tkeystringeditdb,tkeystringeditlb + + ]); + registercomponenttabhints(['DBe'], + ['Data edit widgets, can be placed in tdbwidgetgrid']); + + registercomponents('DBl',[ + tdbstringlookupdb,tdbintegerlookupdb,tdbreallookupdb, + tdbdatetimelookupdb, + tdbstringlookup64db,tdbintegerlookup64db,tdbreallookup64db, + tdbdatetimelookup64db, + tdbstringlookupstrdb,tdbintegerlookupstrdb,tdbreallookupstrdb, + tdbdatetimelookupstrdb, + tdbstringlookuplb,tdbintegerlookuplb,tdbreallookuplb, + tdbdatetimelookuplb, + tdbstringlookup64lb,tdbintegerlookup64lb,tdbreallookup64lb, + tdbdatetimelookup64lb, + tdbstringlookupstrlb,tdbintegerlookupstrlb,tdbreallookupstrlb, + tdbdatetimelookupstrlb]); + registercomponenttabhints(['DBl'], + ['Data lookup widgets, can be placed in tdbwidgetgrid']); + + registercomponents('DBf',[ + tmsestringfield,tmselongintfield,tmselargeintfield,tmsesmallintfield, + tmsewordfield,tmseautoincfield,tmsefloatfield,tmsecurrencyfield, + tmsebooleanfield,tmsedatetimefield,tmsedatefield,tmsetimefield, + tmsebinaryfield,tmsebytesfield,tmsevarbytesfield, + tmsebcdfield,tmseblobfield,tmsememofield,tmsegraphicfield, + tmsevariantfield,tmseguidfield, + tfieldparamlink,tfieldlink,ttimestampfieldlink,tfieldfieldlink, + tsequencelink,tdbevent,tparamconnector,tsqlresultconnector, + tdblabel,tdbstringdisp,tdbintegerdisp,tdbbooleandisp, + tdbrealdisp,tdbdatetimedisp, + tdbstringdisplb,tdbintegerdisplb,tdbrealdisplb,tdbdatetimedisplb, + tdbbarcode + ]); + registercomponenttabhints(['DBf'],['Datafield and data display components']); + registerunitgroup(['msesqldb'],['msebufdataset']); + + registerpropertyeditor(typeinfo(tdatalink),nil,'',tdatalinkpropertyeditor); + registerpropertyeditor(typeinfo(tfielddatalink),nil,'', + tfielddatalinkpropertyeditor); + registerpropertyeditor(typeinfo(datasetoptionsty),nil,'', + tdatasetoptionspropertyeditor); + registerpropertyeditor(typeinfo(variant),tmseparam,'value', + tparamvaluepropertyeditor); + registerpropertyeditor(typeinfo(tnolistdropdowncol),nil,'', + tclasspropertyeditor); + registerpropertyeditor(typeinfo(tnolistdropdowncols),nil,'', + tnolistdropdowncolpropertyeditor); + registerpropertyeditor(typeinfo(string),nil,'datafield', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),nil,'fieldname', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tfield,'KeyFields', + tlookupfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tfield,'LookupKeyFields', + tlookupfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tfield,'LookupResultField', + tlookupfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),teditwidgetdatalink,'fieldnametext', + tdbfieldnamenocalcpropertyeditor); + registerpropertyeditor(typeinfo(string),tfieldfieldlink,'fieldname', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tfieldfieldlink,'destdatafield', + tdbfieldnamenocalcpropertyeditor); + registerpropertyeditor(typeinfo(string),tlookupdbdispfielddatalink, + 'lookupkeyfield',tdbfieldnamenocalcpropertyeditor); + registerpropertyeditor(typeinfo(string),tlookupdbdispfielddatalink, + 'lookupvaluefield',tdbfieldnamenocalcpropertyeditor); + registerpropertyeditor(typeinfo(string),tfieldlink,'destdatafield', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tdestfield,'destfieldname', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tfieldparamlink,'fieldname', + tdbfieldnamenocalcpropertyeditor); + registerpropertyeditor(typeinfo(string),nil,'keyfield', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tgriddatalink,'', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(tdbfieldnamearrayprop),nil,'', + tdbfieldnamearraypropertyeditor); + registerpropertyeditor(typeinfo(tdbcolnamearrayprop),nil,'', + tdbcolnamearraypropertyeditor); + registerpropertyeditor(typeinfo(tpersistentfields),nil,'', + tpersistentfieldspropertyeditor); + registerpropertyeditor(typeinfo(string),tfield,'FieldName', + tfieldfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(tcomponent),tfield,'Dataset', + tfielddatasetpropertyeditor); + registerpropertyeditor(typeinfo(string),tfieldparamlink,'paramname', + tdbparamnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tdestparam,'paramname', + tdbparamnamepropertyeditor); + registerpropertyeditor(typeinfo(tdestparams),nil,'', + tslaveparamspropertyeditor); + registerpropertyeditor(typeinfo(tdestfields),nil,'', + tslavefieldspropertyeditor); + registerpropertyeditor(typeinfo(tstrings),nil,'SQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(tsqlstringlist),nil,'', + tmsesqlpropertyeditor); + registerpropertyeditor(typeinfo(tsqlstringlist),nil,'SQLupdate', + tmsesqlnocheckpropertyeditor); + registerpropertyeditor(typeinfo(tsqlstringlist),nil,'SQLinsert', + tmsesqlnocheckpropertyeditor); + registerpropertyeditor(typeinfo(tsqlstringlist),nil,'SQLdelete', + tmsesqlnocheckpropertyeditor); +{ + registerpropertyeditor(typeinfo(tmsestringdatalist),nil,'SQL', + tmsesqlpropertyeditor); + registerpropertyeditor(typeinfo(tstringlist),tsqlquery,'SQLupdate', + tsqlnocheckpropertyeditor); + registerpropertyeditor(typeinfo(tstringlist),tsqlquery,'SQLinsert', + tsqlnocheckpropertyeditor); + registerpropertyeditor(typeinfo(tstringlist),tsqlquery,'SQLdelete', + tsqlnocheckpropertyeditor); +} + registerpropertyeditor(typeinfo(tdataset),nil,'', + tcomponentpropertyeditor); + registerpropertyeditor(typeinfo(tdataset),tfield,'dataset', + tlocalcomponentpropertyeditor); + registerpropertyeditor(typeinfo(lbfiltereventty),tcustomlbdropdownlistcontroller, + 'onfilter',tonfilterpropertyeditor); + registerpropertyeditor(typeinfo(optionslbty),tcustomlbdropdownlistcontroller, + 'optionslb',toptionslbpropertyeditor); + registerpropertyeditor(typeinfo(tfielddefs),tdataset,'', + tfielddefspropertyeditor); + registerpropertyeditor(typeinfo(boolean),tdataset,'Active', + tdatasetactivepropertyeditor); + registerpropertyeditor(typeinfo(boolean),tsqlresult,'active', + tdatasetactivepropertyeditor); + registerpropertyeditor(typeinfo(string),tsqlresultconnector,'colname', + tsqlresconncolnamepropertyeditor); + registerpropertyeditor(typeinfo(tfielddef),nil,'',tfielddefpropertyeditor); + registerpropertyeditor(typeinfo(tparam),nil,'',tdbparampropertyeditor); + registerpropertyeditor(typeinfo(tmseparam),nil,'',tmseparampropertyeditor); + registerpropertyeditor(typeinfo(tdbstringcols),nil,'',tdbstringcolseditor); + registerpropertyeditor(typeinfo(string),tindexfield,'fieldname', + tindexfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(tindexfields),nil,'', + tindexfieldspropertyeditor); + registerpropertyeditor(typeinfo(tlocalindexes),nil,'', + tlocalindexespropertyeditor); + registerpropertyeditor(typeinfo(lookupbufferfieldnoty),nil,'', + tlookupbufferfieldnopropertyeditor); + registerpropertyeditor(typeinfo(tlbdropdowncols),nil,'', + tlbdropdowncolseditor); + registerpropertyeditor(typeinfo(tdbdropdowncols),nil,'', + tdbdropdowncolseditor); +end; + + +{ tnolistdropdowncolpropertyeditor } + +function tnolistdropdowncolpropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tclasspropertyeditor; +end; + +{ tdbparamnamepropertyeditor } + +function tdbparamnamepropertyeditor.getdefaultstate: propertystatesty; +var + obj1: tobject; +begin + result:= inherited getdefaultstate; + if fremote <> nil then begin + obj1:= tobject(tpropertyeditor1(fremote.getparenteditor).getpointervalue); + if obj1 <> nil then begin + getcorbainterface(obj1,typeinfo(idbparaminfo),fdbparaminfointf); + end; + end + else begin + if (high(fprops) = 0) then begin + with fprops[0] do begin + getcorbainterface(instance,typeinfo(idbparaminfo),fdbparaminfointf); + end; + end; + end; + if (fdbparaminfointf <> nil) and (fdbparaminfointf.getdestdataset <> nil) then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; +end; + +function tdbparamnamepropertyeditor.getvalues: msestringarty; +var + int1: integer; +begin + with fdbparaminfointf.getdestdataset.params do begin + for int1:= 0 to count - 1 do begin + additem(result,msestring(items[int1].name)); + end; + end; +end; + +{ tdbfieldnamepropertyeditor } + +function tdbfieldnamepropertyeditor.getdefaultstate: propertystatesty; +var + obj1: tobject; + ar1: stringarty; + ar2: fieldtypesarty; + int1,int2: integer; +begin + result:= inherited getdefaultstate; + if (high(fprops) = 0) then begin + with fprops[0] do begin + getcorbainterface(instance,typeinfo(idbeditinfo),fdbeditinfointf); + end; + end; + if (fdbeditinfointf = nil) and (fremote <> nil) then begin + obj1:= tobject(tpropertyeditor1(fremote.getparenteditor).getpointervalue); + if obj1 <> nil then begin + getcorbainterface(obj1,typeinfo(idbeditinfo),fdbeditinfointf); + end; + end; + if fdbeditinfointf <> nil then begin + fdbeditinfointf.getfieldtypes(ar1,ar2); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if msestring(ar1[int1]) = name then begin + int2:= int1; + break; + end; + end; + if fdbeditinfointf.getdataset(int2) <> nil then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; + end; +end; + +function tdbfieldnamepropertyeditor.getvalues: msestringarty; +var + propertynames: stringarty; + fieldtypes: fieldtypesarty; + ft: fieldtypesty; + int1,int2: integer; + ds: tdataset; + +begin + result:= nil; + if (fdbeditinfointf <> nil) then begin + int2:= 0; + fdbeditinfointf.getfieldtypes(propertynames,fieldtypes); + if high(propertynames) >= 0 then begin + for int1:= 0 to high(propertynames) do begin + if msestring(propertynames[int1]) = fname then begin + int2:= int1; + break; + end; + end; + end; + if int2 <= high(fieldtypes) then begin + ft:= fieldtypes[int2]; + end + else begin + ft:= []; + end; + ds:= fdbeditinfointf.getdataset(int2); + if ds <> nil then begin + if ds.active or (ds.fields.count > 0) then begin + for int1:= 0 to ds.fields.count -1 do begin + with ds.fields[int1] do begin + if ((ft = []) or (datatype = ftunknown) or (datatype in ft)) and + (not fnocalc or (fieldkind <> fkcalculated)) then begin + additem(result,msestring(fieldname)); + end; + end; + end; + end + else begin + for int1:= 0 to ds.fielddefs.count -1 do begin + with ds.fielddefs[int1] do begin + if (ft = []) or (datatype = ftunknown) or (datatype in ft) then begin + additem(result,msestring(name)); + end; + end; + end; + end; + end; + end; +end; + +{ tdbcolnamepropertyeditor } + +function tdbcolnamepropertyeditor.getdefaultstate: propertystatesty; +var + sqlresult1: tsqlresult; + obj1: tobject; + ar1: stringarty; + ar2: fieldtypesarty; + int1,int2: integer; +begin + result:= inherited getdefaultstate; + if fremote <> nil then begin + obj1:= tobject(tpropertyeditor1(fremote.getparenteditor).getpointervalue); + if obj1 <> nil then begin + getcorbainterface(obj1,typeinfo(idbcolinfo),fdbcolinfointf); + end; + end + else begin + if (high(fprops) = 0) then begin + with fprops[0] do begin + getcorbainterface(instance,typeinfo(idbcolinfo),fdbcolinfointf); + end; + end; + end; + if fdbcolinfointf <> nil then begin + fdbcolinfointf.getfieldtypes(ar1,ar2); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if msestring(ar1[int1]) = name then begin + int2:= int1; + break; + end; + end; + sqlresult1:= fdbcolinfointf.getsqlresult(int2); + if (sqlresult1 <> nil) {and (sqlresult1.active)} then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; + end; +end; + +function tdbcolnamepropertyeditor.getvalues: msestringarty; +var + propertynames: stringarty; + fieldtypes: fieldtypesarty; + ft: fieldtypesty; + int1,int2: integer; + sqlresult1: tsqlresult; + +begin + result:= nil; + if (fdbcolinfointf <> nil) then begin + int2:= 0; + fdbcolinfointf.getfieldtypes(propertynames,fieldtypes); + if high(propertynames) >= 0 then begin + for int1:= 0 to high(propertynames) do begin + if msestring(propertynames[int1]) = fname then begin + int2:= int1; + break; + end; + end; + end; + if int2 <= high(fieldtypes) then begin + ft:= fieldtypes[int2]; + end + else begin + ft:= []; + end; + sqlresult1:= fdbcolinfointf.getsqlresult(int2); + if sqlresult1 <> nil then begin + if {sqlresult1.active or} (sqlresult1.datacols.count > 0) then begin + for int1:= 0 to sqlresult1.datacols.count -1 do begin + with sqlresult1.cols[int1] do begin + if (ft = []) or (datatype = ftunknown) or (datatype in ft) then begin + additem(result,msestring(fieldname)); + end; + end; + end; + end + else begin + if sqlresult1.fielddefs.count > 0 then begin + for int1:= 0 to sqlresult1.fielddefs.count -1 do begin + with sqlresult1.fielddefs[int1] do begin + if (ft = []) or (datatype = ftunknown) or (datatype in ft) then begin + additem(result,msestring(name)); + end; + end; + end; + end + end; + end; + end; +end; + +{ tdbfieldnamearraypropertyeditor } + +function tdbfieldnamearraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tdbfieldnamepropertyeditor; +end; + +{ tdbcolnamearraypropertyeditor } + +function tdbcolnamearraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tdbcolnamepropertyeditor; +end; + +{ tpersistentfieldelementeditor } + +function tpersistentfieldelementeditor.getvalue: msestring; +begin + result:= msestring('<'+tfield(getpointervalue).fieldname+'>') + + inherited getvalue; +end; + +{ tpersistentfieldspropertyeditor } + +function tpersistentfieldspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tpersistentfieldelementeditor; +end; + +function tpersistentfieldspropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_noadditems,ps_dialog]; +end; + +procedure tpersistentfieldspropertyeditor.edit; +begin + if editpersistentfields(tpersistentfields(getpointervalue)) then begin + modified; + end; +end; + +{ tfieldfieldnamepropertyeditor } + +function tfieldfieldnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tfieldfieldnamepropertyeditor.getvalues: msestringarty; +var + ds: tdataset; + int1,int2: integer; + ar1,ar2,ar3: stringarty; + intf: ipersistentfieldsinfo; + fclass: tclass; +begin + result:= nil; + ds:= tfield(fprops[0].instance).dataset; + if ds <> nil then begin + setlength(ar1,ds.fielddefs.count); + setlength(ar3,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar3[int1]:= ds.fielddefs[int1].name; + ar1[int1]:= uppercase(ar3[int1]); + end; + setlength(ar2,ds.fields.count); + for int1:= 0 to high(ar2) do begin + ar2[int1]:= uppercase(ds.fields[int1].fieldname); + end; + for int1:= 0 to high(ar1) do begin + for int2:= 0 to high(ar2) do begin + if ar1[int1] = ar2[int2] then begin + ar1[int1]:= ''; + break; + end; + end; + end; + if getcorbainterface(fprops[0].instance, + typeinfo(ipersistentfieldsinfo),intf) then begin + ar2:= intf.getfieldnames; + for int1:= 0 to high(ar2) do begin + ar2[int1]:= uppercase(ar2[int1]); + end; + for int1:= 0 to high(ar1) do begin + for int2:= 0 to high(ar2) do begin + if ar1[int1] = ar2[int2] then begin + ar1[int1]:= ''; + break; + end; + end; + end; + end; + fclass:= tfield(fprops[0].instance).classtype; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] <> '') and + (fclass.inheritsfrom(ds.fielddefs[int1].fieldclass) or + (fclass.inheritsfrom(tmsebooleanfield)) and + (ds.fielddefs[int1].fieldclass.inheritsfrom(tlongintfield))) then begin + additem(result,msestring(ar3[int1])); + end; + end; + end; +end; + +procedure tfieldfieldnamepropertyeditor.setvalue(const value: msestring); +var + ds: tdataset; +begin + ds:= tfield(fprops[0].instance).dataset; + if (ds <> nil) and (ds.findfield(ansistring(value)) <> nil) then begin + raise exception.create('Field '''+ansistring(value)+ + ''' exists in '+ds.name+'.'); + end; + inherited; +end; + +{ tfielddatasetpropertyeditor } + +procedure tfielddatasetpropertyeditor.checkcomponent(const avalue: tcomponent); +var + str1: string; +begin + if avalue is tdataset then begin + str1:= tfield(fprops[0].instance).fieldname; + with tdataset(avalue) do begin + if findfield(str1) <> nil then begin + raise exception.create('Field '''+str1+''' exists in '+name+'.'); + end; + end; + end; +end; + +const + sqlsyntax = +'caseinsensitive'+lineend+ +'styles'+lineend+ +' default '''''+lineend+ +' words ''b'''+lineend+ +' comment ''i'' cl_dkblue'+lineend+ +' option ''b'' cl_dkblue'+lineend+ +' string '''' cl_dkblue'+lineend+ +' '+lineend+ +'keyworddefs sql'+lineend+ +' ''ACTION'' ''ACTIVE'' ''ADD'' ''ADMIN'' ''AFTER'' ''ALL'' ''ALTER'' ''AND'''+lineend+ +' ''ANY'' ''AS'' ''ASC'''+lineend+ +' ''ASCENDING'' ''AT'' ''AUTO'' ''AUTODDL'''+lineend+ +' ''AVG'' ''BASED'' ''BASENAME'' ''BASE_NAME'' ''BEFORE'' ''BEGIN'' ''BETWEEN'''+lineend+ +' ''BLOB'' '+lineend+ +' ''BLOBEDIT'' ''BUFFER'' ''BY'' ''CACHE'''+lineend+ +' ''CASCADE'' ''CASE'' ''CAST'' ''CHAR'' ''CHARACTER'' ''CHARACTER_LENGTH'''+lineend+ +' ''CHAR_LENGTH'' ''CHECK'' '+lineend+ +' ''CHECK_POINT_LEN'''+lineend+ +' ''CHECK_POINT_LENGTH'' ''COLLATE'' ''COLLATION'' ''COLUMN'' ''COMMIT'''+lineend+ +' ''COMMITTED'' '+lineend+ +' ''COMPILETIME'''+lineend+ +' ''COMPUTED'' ''CLOSE'' ''CONDITIONAL'' ''CONNECT'' ''CONSTRAINT'''+lineend+ +' ''CONTAINING'' ''CONTINUE'' '+lineend+ +' ''COUNT'' ''CREATE'''+lineend+ +' ''CSTRING'' ''CURRENT'' ''CURRENT_DATE'' ''CURRENT_TIME'''+lineend+ +' ''CURRENT_TIMESTAMP'' ''CURSOR'''+lineend+ +' ''DATABASE'' ''DATE'' ''DAY'' ''DB_KEY'' ''DEBUG'' ''DEC'' ''DECIMAL'''+lineend+ +' ''DECLARE'' ''DEFAULT'' '+lineend+ +' ''DELETE'' ''DESC'' ''DESCENDING'''+lineend+ +' ''DESCRIBE'' ''DESCRIPTOR'' ''DISCONNECT'' ''DISPLAY'' ''DISTINCT'' ''DO'''+lineend+ +' ''DOMAIN'' '+lineend+ +' ''DOUBLE'' ''DROP'''+lineend+ +' ''ECHO'' ''EDIT'' ''ELSE'' ''END'' ''ENTRY_POINT'' ''ESCAPE'' ''EVENT'''+lineend+ +' ''EXCEPTION'' ''EXECUTE'''+lineend+ +' ''EXISTS'' ''EXIT'' ''EXTERN'' ''EXTERNAL'' ''EXTRACT'' ''FETCH'' ''FILE'''+lineend+ +' ''FILTER'' ''FLOAT'' '+lineend+ +' ''FOR'' ''FOREIGN'' ''FOUND'''+lineend+ +' ''FREE_IT'' ''FROM'' ''FULL'' ''FUNCTION'' ''GDSCODE'' ''GENERATOR'''+lineend+ +' ''GEN_ID'' ''GLOBAL'' '+lineend+ +' ''GOTO'''+lineend+ +' ''GRANT'' ''GROUP'' ''GROUP_COMMIT_WAIT'' ''GROUP_COMMIT_'' ''WAIT_TIME'''+lineend+ +' ''HAVING'' ''HELP'' '+lineend+ +' ''HOUR'' ''IF'''+lineend+ +' ''IMMEDIATE'' ''IN'' ''INACTIVE'' ''INDEX'' ''INDICATOR'' ''INIT'' ''INNER'''+lineend+ +' ''INPUT'' '+lineend+ +' ''INPUT_TYPE'''+lineend+ +' ''INSERT'' ''INT'' ''INTEGER'' ''INTO'' ''IS'' ''ISOLATION'' ''ISQL'''+lineend+ +' ''JOIN'' ''KEY'' '+lineend+ +' ''LC_MESSAGES'' ''LC_TYPE'' ''LEFT'''+lineend+ +' ''LENGTH'' ''LEV'' ''LEVEL'' ''LIKE'' ''LIMIT'''+lineend+ +' ''LOGFILE'' ''LOG_BUFFER_SIZE'''+lineend+ +' ''LOG_BUF_SIZE'' '+lineend+ +' ''LONG'' ''MANUAL'''+lineend+ +' ''MAX'' ''MAXIMUM'' ''MAXIMUM_SEGMENT'' ''MAX_SEGMENT'' ''MERGE'''+lineend+ +' ''MESSAGE'' ''MIN'' '+lineend+ +' ''MINIMUM'' ''MINUTE'''+lineend+ +' ''MODULE_NAME'' ''MONTH'' ''NAMES'' ''NATIONAL'' ''NATURAL'' ''NCHAR'''+lineend+ +' ''NO'' ''NOAUTO'' '+lineend+ +' ''NOT'''+lineend+ +' ''NULL'' ''NUMERIC'' ''NUM_LOG_BUFS'' ''NUM_LOG_BUFFERS'' ''OCTET_LENGTH'''+lineend+ +' ''OF'' ''ON'' '+lineend+ +' ''ONLY'' ''OPEN'''+lineend+ +' ''OPTION'' ''OR'' ''ORDER'' ''OUTER'' ''OUTPUT'' ''OUTPUT_TYPE'' ''OVERFLOW'''+lineend+ +' ''PAGE'' '+lineend+ +' ''PAGELENGTH'''+lineend+ +' ''PAGES'' ''PAGE_SIZE'' ''PARAMETER'' ''PASSWORD'' ''PLAN'' ''POSITION'''+lineend+ +' ''POST_EVENT'' '+lineend+ +' ''PRECISION'' ''PREPARE'''+lineend+ +' ''PROCEDURE'' ''PROTECTED'' ''PRIMARY'' ''PRIVILEGES'' ''PUBLIC'' ''QUIT'''+lineend+ +' ''RAW_PARTITIONS'' ''RDB$DB_KEY'' ''READ'' ''REAL'' ''RECORD_VERSION'''+lineend+ +' ''REFERENCES'''+lineend+ +' ''RELEASE'' ''RESERV'' ''RESERVING'' ''RESTRICT'' ''RETAIN'' ''RETURN'''+lineend+ +' ''RETURNING_VALUES'' ''RETURNS'' ''REVOKE'' ''RIGHT'' ''ROLE'' ''ROLLBACK'''+lineend+ +' ''RUNTIME'' '+lineend+ +' ''SCHEMA'' ''SECOND'''+lineend+ +' ''SEGMENT'' ''SELECT'' ''SET'' ''SHADOW'' ''SHARED'' ''SHELL'' ''SHOW'''+lineend+ +' ''SINGULAR'' ''SIZE'''+lineend+ +' ''SMALLINT'' ''SNAPSHOT'' ''SOME'' ''SORT'' ''SQLCODE'' ''SQLERROR'''+lineend+ +' ''SQLWARNING'' '+lineend+ +' ''STABILITY'' ''STARTING'''+lineend+ +' ''STARTS'' ''STATEMENT'' ''STATIC'' ''STATISTICS'' ''SUB_TYPE'' ''SUM'''+lineend+ +' ''SUSPEND'' '+lineend+ +' ''TABLE'' ''TERMINATOR'''+lineend+ +' ''THEN'' ''TIME'' ''TIMESTAMP'' ''TO'' ''TRANSACTION'' ''TRANSLATE'''+lineend+ +' ''TRANSLATION'' '+lineend+ +' ''TRIGGER'' ''TRIM'''+lineend+ +' ''TYPE'' ''UNCOMMITTED'' ''UNION'' ''UNIQUE'' ''UPDATE'' ''UPPER'' ''USER'''+lineend+ +' ''USING'' '+lineend+ +' ''VALUE'+lineend+ +' ''VALUES'' ''VARCHAR'' ''VARIABLE'' ''VARYING'' ''VERSION'' ''VIEW'' ''WAIT'''+lineend+ +' ''WEEKDAY'' '+lineend+ +' ''WHEN'''+lineend+ +' ''WHENEVER'' ''WHERE'' ''WHILE'' ''WITH'' ''WORK'' ''WRITE'' ''YEAR'''+lineend+ +' ''YEARDAY'''+lineend+ +''+lineend+ +'scope comment1 comment'+lineend+ +' endtokens'+lineend+ +' ''*/'''+lineend+ +' '+lineend+ +'scope comment2 comment'+lineend+ +' endtokens'+lineend+ +' '''''+lineend+ +' '+lineend+ +'scope string string'+lineend+ +' endtokens'+lineend+ +' '''''''' '''''+lineend+ +' '+lineend+ +'scope main'+lineend+ +''+lineend+ +' keywords words'+lineend+ +' sql'+lineend+ +' calltokens'+lineend+ +' ''/*'' comment1'+lineend+ +' ''--'' comment2'+lineend+ +' '''''''' string'+lineend; + +var + sqlindex: integer = -1; + +{ tsqlpropertyeditor } + +function tsqlpropertyeditor.getsyntaxindex: integer; +begin + if sqlindex < 0 then begin + sqlindex:= msetexteditor.syntaxpainter.readdeffile(sqlsyntax); + end; + result:= sqlindex; +end; + +procedure tsqlpropertyeditor.doafterclosequery( + var amodalresult: modalresultty); +begin + if amodalresult = mr_canclose then begin + if fintf <> nil then begin + fintf.setactive(true); + if not factivebefore then begin + fintf.setactive(false); //avoid exception by empty original statement + end; + end; + end; +end; + +function tsqlpropertyeditor.gettestbutton: boolean; +begin + result:= fintf <> nil; +end; + +function tsqlpropertyeditor.getutf8: boolean; +begin + result:= (fintf <> nil) and fintf.isutf8; +end; + +procedure tsqlpropertyeditor.edit; +begin + if not nocheck and getcorbainterface(fprops[0].instance, + typeinfo(isqlpropertyeditor),fintf) then begin + factivebefore:= fintf.getactive; + fdbactivebefore:= (fintf.getdatabase() = nil) or + fintf.getdatabase.connected; + end + else begin + fintf:= nil; + end; + inherited; + if fintf <> nil then begin + if not factivebefore then begin + fintf.setactive(false); + end; + if not fdbactivebefore and (fintf.getdatabase <> nil) then begin + fintf.getdatabase.connected:= false; + end; + end; +end; + +function tsqlpropertyeditor.getcaption: msestring; +begin + result:= 'SQL Editor'; +end; + +function tsqlpropertyeditor.nocheck: boolean; +begin + result:= false; +end; + +{ tmsesqlpropertyeditor } + +function tmsesqlpropertyeditor.ismsestring: boolean; +begin + result:= true; +end; + +{ tsqlnocheckpropertyeditor } + +function tsqlnocheckpropertyeditor.nocheck: boolean; +begin + result:= true; +end; + +{ tmsesqlnocheckpropertyeditor } + +function tmsesqlnocheckpropertyeditor.nocheck: boolean; +begin + result:= true; +end; + +{ tonfilterpropertyeditor } + +function tonfilterpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +procedure tonfilterpropertyeditor.setvalue(const value: msestring); + +begin + inherited; + with tcustomlbdropdownlistcontroller(fprops[0].instance) do begin + if not (olb_copyitems in optionslb) then begin + if getmethodvalue.data <> nil then begin + if buttonlength = 0 then begin + buttonlength:= -1; + end; + end + else begin + if buttonlength = -1 then begin + buttonlength:= 0; + end; + end; + end; + end; +end; + +procedure checkonfilter(const acontroller: tcustomlbdropdownlistcontroller; + const optbefore: optionslbty); +begin + with acontroller do begin + if (olb_copyitems in (optbefore >< optionslb)) and + (tmethod(onfilter).data <> nil) then begin + if olb_copyitems in optbefore then begin + if buttonlength = 0 then begin + buttonlength:= -1; + end; + end + else begin + if buttonlength = -1 then begin + buttonlength:= 0; + end; + end; + end; + end; +end; + +{ toptionlbpropertyeditor } + +function toptionlbpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +procedure toptionlbpropertyeditor.setvalue(const value: msestring); +var + opt1: optionslbty; + cont1: tcustomlbdropdownlistcontroller; +begin + cont1:= tcustomlbdropdownlistcontroller(fprops[0].instance); + opt1:= cont1.optionslb; + inherited; + checkonfilter(cont1,opt1); +end; + +{ toptionslbpropertyeditor } + +constructor toptionslbpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + felementeditorclass:= toptionlbpropertyeditor; + inherited; +end; + +function toptionslbpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +procedure toptionslbpropertyeditor.setvalue(const value: msestring); +var + opt1: optionslbty; + cont1: tcustomlbdropdownlistcontroller; +begin + cont1:= tcustomlbdropdownlistcontroller(fprops[0].instance); + opt1:= cont1.optionslb; + inherited; + checkonfilter(cont1,opt1); +end; + +{ tfielddefspropertyeditor } + +procedure tfielddefspropertyeditor.setvalue(const value: msestring); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + tdataset(fprops[int1].instance).active:= false; + end; + inherited; +end; + +{ tdatasetactivepropertyeditor } + +function tdatasetactivepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +{ tfielddefpropertyeditor } + +function tfielddefpropertyeditor.getvalue: msestring; +begin + with tfielddef(fprops[0].instance) do begin + result:= msestring('<'+name+'><'+ + getenumname(typeinfo(tfieldtype),ord(datatype))+'>'); + end; +end; + +{ tdbparampropertyeditor } + +function tdbparampropertyeditor.getvalue: msestring; +begin + with tparam(fprops[0].instance) do begin + result:= msestring('<'+name+'><'+ + getenumname(typeinfo(tfieldtype),ord(datatype)))+ + {'><'+getenumname(typeinfo(tparamtype),ord(paramtype))+}'>'; + end; +end; + +{ tmseparampropertyeditor } + +function tmseparampropertyeditor.getvalue: msestring; +begin + with tmseparam(fprops[0].instance) do begin + result:= msestring('<'+name+'><'+fieldname+'><'); + if connector <> nil then begin + result:= result+msestring(connector.name); + end; + result:= result+'>'; + end; +end; + +{ tdbstringcoleditor } + +function tdbstringcoleditor.getvalue: msestring; +begin + result:= inherited getvalue + + msestring('<'+tdbstringcol(getpointervalue).datafield+'>'); +end; + +{ tdbstringcolseditor } + +function tdbstringcolseditor.geteditorclass: propertyeditorclassty; +begin + result:= tdbstringcoleditor; +end; + +{ tindexfieldnamepropertyeditor } + +function tindexfieldnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tindexfieldnamepropertyeditor.getvalues: msestringarty; +var + int1: integer; +begin + result:= nil; + if high(fprops) = 0 then begin + with tmsebufdataset(fcomponent) do begin + if active or (fields.count > 0) then begin + for int1:= 0 to fields.count -1 do begin + with fields[int1] do begin + if (datatype in indexfieldtypes) and + (fieldkind in [fkdata,fkinternalcalc,fklookup]) then begin + additem(result,msestring(fieldname)); + end; + end; + end; + end + else begin + for int1:= 0 to fielddefs.count -1 do begin + with fielddefs[int1] do begin + if (datatype in indexfieldtypes) then begin + additem(result,msestring(name)); + end; + end; + end; + end; + end; + end; +end; + +{ tindexfieldpropertyeditor } + +function tindexfieldpropertyeditor.getvalue: msestring; +begin + result:= msestring('<'+tindexfield(getpointervalue).fieldname+'>'); +end; + +function tindexfieldpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_refresh] +end; + +{ tindexfieldspropertyeditor } + +function tindexfieldspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tindexfieldpropertyeditor; +end; + +{ tlocalindexpropertyeditor } + +function tlocalindexpropertyeditor.getvalue: msestring; +var + int1: integer; +begin + with tlocalindex(getpointervalue),fields do begin + result:= msestring('<'+name+'><'); + if count > 0 then begin + for int1:= 0 to count - 1 do begin + result:= result + msestring(items[int1].fieldname+','); + end; + setlength(result,length(result)-1); + end; + end; + result:= result + '>'; +end; + +function tlocalindexpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_refresh]; +end; + +{ tlocalindexespropertyeditor } + +function tlocalindexespropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tlocalindexpropertyeditor; +end; + +{ tdbfieldnamenocalcpropertyeditor } + +constructor tdbfieldnamenocalcpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fnocalc:= true; + inherited; +end; + +{ tlookupbufferfieldnopropertyeditor } + +constructor tlookupbufferfieldnopropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + getcorbainterface(aprops[0].instance,typeinfo(ilookupbufferfieldinfo),fintf); + if fintf <> nil then begin + flbdatakind:= fintf.getlbdatakind(aprops[0].propinfo^.name); + if fintf.getlookupbuffer = nil then begin + flbdatakind:= lbdk_none; + end; + end; + inherited; +end; + +function tlookupbufferfieldnopropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + if flbdatakind <> lbdk_none then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; +end; + +function tlookupbufferfieldnopropertyeditor.getnames: msestringarty; +var + lb1: tcustomlookupbuffer; + ar1: stringarty; + int1: integer; +begin + ar1:= nil; + if fintf <> nil then begin + lb1:= fintf.getlookupbuffer; + if lb1 <> nil then begin + case flbdatakind of + lbdk_integer: begin + ar1:= lb1.fieldnamesinteger; + end; + lbdk_int64: begin + ar1:= lb1.fieldnamesint64; + end; + lbdk_float: begin + ar1:= lb1.fieldnamesfloat; + end; + lbdk_text: begin + ar1:= lb1.fieldnamestext; + end; + end; + end; + end; + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= msestring(ar1[int1]); + end; +end; + +function tlookupbufferfieldnopropertyeditor.getvalues: msestringarty; +begin + result:= getnames; +end; + +procedure tlookupbufferfieldnopropertyeditor.setvalue(const value: msestring); +var + ar1: msestringarty; + int1: integer; +begin + if value <> '' then begin + ar1:= getnames; + for int1:= 0 to high(ar1) do begin + if value = ar1[int1] then begin + setordvalue(int1); + exit; + end; + end; + end; + inherited; +end; + +function tlookupbufferfieldnopropertyeditor.getvalue: msestring; +var + ar1: msestringarty; + int1: integer; +begin + result:= inherited getvalue; + if fintf <> nil then begin + int1:= getordvalue; + ar1:= getnames; + if (int1 >= 0) and (int1 <= high(ar1)) then begin + result:= result+'<'+ar1[int1]+'>'; + end + else begin + result:= result+'<>'; + end; + end; +end; + +{ tlbdropdowncolitemeditor } +{ +function tlbdropdowncolitemeditor.getvalue: msestring; +var + lb1: tcustomlookupbuffer; + ar1: stringarty; +begin + result:= '<>'; + with tlbdropdowncol1(getpointervalue) do begin + lb1:= getlookupbuffer; + if lb1 <> nil then begin + ar1:= lb1.fieldnamestext; + if (fieldno >= 0) and (fieldno <= high(ar1)) then begin + result:= '<'+ar1[fieldno]+'>'; + end; + end; + end; +end; +} +{ tlbdropdowncolseditor } +{ +function tlbdropdowncolseditor.geteditorclass: propertyeditorclassty; +begin + result:= tlbdropdowncolitemeditor; +end; +} +function tlbdropdowncolseditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +var + lb1: tcustomlookupbuffer; + ar1: stringarty; +begin + result:= '<>'; + with tlbdropdowncol1(tarrayelementeditor1(sender).getpointervalue) do begin + lb1:= getlookupbuffer; + if lb1 <> nil then begin + ar1:= lb1.fieldnamestext; + if (fieldno >= 0) and (fieldno <= high(ar1)) then begin + result:= msestring('<'+ar1[fieldno]+'>'); + end; + end; + end; +end; + +{ tdbdropdowncolitemeditor } +{ +function tdbdropdowncolitemeditor.getvalue: msestring; +begin + result:= '<'+tdbdropdowncol(getpointervalue).datafield+'>'; +end; +} +{ tdbdropdowncolseditor } +{ +function tdbdropdowncolseditor.geteditorclass: propertyeditorclassty; +begin + result:= tdbdropdowncolitemeditor; +end; +} +function tdbdropdowncolseditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + result:= msestring('<'+tdbdropdowncol( + tarrayelementeditor1(sender).getpointervalue).datafield+'>'); +end; + +{ tparamvaluepropertyeditor } + +procedure tparamvaluepropertyeditor.setvalue(const value: msestring); +var + var1: variant; +begin + fillchar(var1,sizeof(var1),0); + if value = '' then begin + setvariantvalue(var1); + end + else begin + var1:= value; + case tmseparam(instance).datatype of + ftBoolean: setvariantvalue(boolean(var1)); + ftsmallint: setvariantvalue(word(var1)); + ftinteger: setvariantvalue(integer(var1)); +{$ifdef FPC} + ftlargeint: setvariantvalue(int64(var1)); +{$else} + ftlargeint: setvariantvalue(integer(var1)); +{$endif} + ftcurrency: setvariantvalue(currency(var1)); + ftfloat: setvariantvalue(double(var1)); + ftdatetime: setvariantvalue(tdatetime(var1)); + else begin + setvariantvalue(value); + end; + end; + end; +end; + +{ tslaveparampropertyeditor } +{ +function tslaveparampropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate+[ps_refresh]; +end; + +function tslaveparampropertyeditor.getvalue: msestring; +begin + with tdestparam(getpointervalue) do begin + result:= '<'; + if datasource <> nil then begin + result:= result + datasource.name; + end; + result:= result+'.'+fieldname+'>'+'<'+paramname+'>'; + end; +end; +} +{ tslaveparamspropertyeditor } +{ +function tslaveparamspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tslaveparampropertyeditor; +end; +} +function tslaveparamspropertyeditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + with tdestparam(tarrayelementeditor1(sender).getpointervalue) do begin + result:= '<'; + if datasource <> nil then begin + result:= result + msestring(datasource.name); + end; + result:= result+msestring('.'+fieldname+'>'+'<'+paramname+'>'); + end; +end; + +function tslaveparamspropertyeditor.itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; +begin + result:= inherited itemgetdefaultstate(sender)+[ps_refresh]; +end; + +{ tslavefieldspropertyeditor } + +function tslavefieldspropertyeditor.itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; +begin + result:= inherited itemgetdefaultstate(sender)+[ps_refresh]; +end; + +function tslavefieldspropertyeditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + with tdestfield(tarrayelementeditor1(sender).getpointervalue) do begin + result:= '<'; + if datasource <> nil then begin + result:= result + msestring(datasource.name); + end; + result:= result+msestring('.'+fieldname+'>'+'<'+destfieldname+'>'); + end; +end; + +{ tsqlmacroitemeditor } +{ +function tsqlmacroitemeditor.getvalue: msestring; +begin + with tsqlmacroitem(getpointervalue) do begin + result:= '<'+name+'>'; + end; +end; +} +{ +function tsqlmacroseditor.geteditorclass: propertyeditorclassty; +begin + result:= tsqlmacroitemeditor; +end; +} +{ tlookupfieldnamepropertyeditor } + +function tlookupfieldnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function getfieldnames(const adataset: tdataset): msestringarty; +var + int1: integer; +begin + result:= nil; + if adataset <> nil then begin + with adataset.fields do begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= msestring(fields[int1].fieldname); + end; + end; + if result = nil then begin + with adataset.fielddefs do begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= msestring(items[int1].name); + end; + end; + end; + end; +end; + +function tlookupfieldnamepropertyeditor.getvalues: msestringarty; +begin + result:= nil; + if name = 'KeyFields' then begin + result:= getfieldnames(tfield(instance).dataset); + end + else begin + result:= getfieldnames(tfield(instance).lookupdataset); + end; +end; + +{ tdatasetoptionspropertyeditor } + +function tdatasetoptionspropertyeditor.getinvisibleitems: tintegerset; +begin + result:= tintegerset(card32([dso_refreshwaitcursor]+deprecatedbdsoptions)); +end; + +{ tdatalinkpropertyeditor } + +function tdatalinkpropertyeditor.getvalue: msestring; +var + inst: tdatalink; +begin + inst:= tdatalink(getpointervalue()); + if (inst <> nil) and (inst.datasource <> nil) then begin + result:= '<'+getcomponentpropname(inst.datasource)+'>'; + end + else begin + result:= inherited getvalue; + end; +end; + +{ tfielddatalinkpropertyeditor } + +function tfielddatalinkpropertyeditor.getvalue: msestring; +var + inst: tfielddatalink; +begin + inst:= tfielddatalink(getpointervalue()); + result:= inherited getvalue(); + if inst.fieldname <> '' then begin + result:= '<'+msestring(inst.fieldname)+'>'+result; + end; +end; + +{ tsqlresconncolnamepropertyeditor } + +function tsqlresconncolnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + with tsqlresultconnector(fcomponent) do begin + if source <> nil then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; + end; +end; + +function tsqlresconncolnamepropertyeditor.getvalues: msestringarty; +var + i1: int32; +begin + result:= nil; + with tsqlresultconnector(fcomponent) do begin + if source <> nil then begin + with source do begin + setlength(result,fielddefs.count); + for i1:= 0 to high(result) do begin + result[i1]:= msestring(fielddefs[i1].name); + end; + end; + end; + end; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdb_bmp.pas b/mseide-msegui/lib/common/regcomponents/regdb_bmp.pas new file mode 100644 index 0000000..1c5eb78 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdb_bmp.pas @@ -0,0 +1,9441 @@ +unit regdb_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tlocaldataset: record size: integer; data: array[0..1972] of byte end = + (size: 1973; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,108,111, + 99,97,108,100,97,116,97,115,101,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,60,7,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,248,6,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,132,255,255,1,135,255,255,1,138, + 255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152, + 255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166, + 255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180, + 255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194, + 255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140, + 255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155, + 255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169, + 255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183, + 255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197, + 255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,0,0,0,1,143, + 255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,145,238,238,1,43, + 70,70,1,6,9,9,1,49,76,76,1,157,241,241,1,169,255,255,1,172, + 255,255,1,166,243,243,1,60,87,87,1,7,10,10,1,30,42,42,1,157, + 215,215,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132, + 255,255,1,135,255,255,1,138,255,255,1,0,0,0,1,143,255,255,1,146, + 255,255,1,149,255,255,1,152,255,255,1,63,103,103,1,90,146,146,1,156, + 249,249,1,102,159,159,1,71,109,109,1,169,255,255,1,172,255,255,1,74, + 109,109,1,126,181,181,1,177,251,251,1,105,146,146,1,43,59,59,1,189, + 255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135, + 255,255,1,138,255,255,1,0,0,0,1,143,255,255,1,146,255,255,1,149, + 255,255,1,152,255,255,1,15,25,25,1,148,240,240,1,160,255,255,1,148, + 232,232,1,19,29,29,1,169,255,255,1,172,255,255,1,18,26,26,1,158, + 228,228,1,180,255,255,1,180,251,251,1,149,204,204,1,189,255,255,1,191, + 255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138, + 255,255,1,0,0,0,1,143,255,255,1,146,255,255,1,149,255,255,1,152, + 255,255,1,2,3,3,1,156,254,254,1,160,255,255,1,161,252,252,1,3, + 5,5,1,169,255,255,1,172,255,255,1,3,5,5,1,175,252,252,1,180, + 255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194, + 255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,0, + 0,0,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,16, + 26,26,1,149,242,242,1,160,255,255,1,153,240,240,1,18,27,27,1,169, + 255,255,1,172,255,255,1,20,29,29,1,158,228,228,1,180,255,255,1,174, + 243,243,1,101,138,138,1,189,255,255,1,191,255,255,1,194,255,255,1,197, + 255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,0,0,0,1,143, + 255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,65,107,107,1,87, + 142,142,1,154,245,245,1,90,141,141,1,70,107,107,1,169,255,255,1,172, + 255,255,1,73,107,107,1,124,178,178,1,176,250,250,1,90,126,126,1,53, + 72,72,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132, + 255,255,1,135,255,255,1,138,255,255,1,0,0,0,4,152,255,255,1,146, + 240,240,1,46,74,74,1,6,9,9,1,47,74,74,1,156,239,239,1,169, + 255,255,1,172,255,255,1,163,239,239,1,51,73,73,1,6,8,8,1,36, + 50,50,1,161,221,221,1,189,255,255,1,191,255,255,1,194,255,255,1,197, + 255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143, + 255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157, + 255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172, + 255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186, + 255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132, + 255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146, + 255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160, + 255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174, + 255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189, + 255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,128,128,128,25,135, + 255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149, + 255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163, + 255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128, + 128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191, + 255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140, + 255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155, + 255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169, + 255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183, + 255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128, + 128,128,26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146, + 255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160, + 255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174, + 255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189, + 255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138, + 255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128, + 128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166, + 255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180, + 255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194, + 255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1,143, + 255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157, + 255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172, + 255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186, + 255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135, + 255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149, + 255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163, + 255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128, + 128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191, + 255,255,1,194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140, + 255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155, + 255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169, + 255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183, + 255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128, + 128,128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146, + 255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160, + 255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174, + 255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189, + 255,255,1,191,255,255,1,194,255,255,1,128,128,128,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsesqlquery: record size: integer; data: array[0..1963] of byte end = + (size: 1964; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,109,115, + 101,115,113,108,113,117,101,114,121,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,52,7,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,240,6,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255, + 255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255, + 255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255, + 255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255, + 255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,97,179,179,1,20,36,36,1,3,5, + 5,1,26,46,46,1,113,193,193,1,152,255,255,1,155,255,255,1,154,250, + 250,1,72,115,115,1,12,18,18,2,76,114,114,1,169,250,250,1,174,255, + 255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,11,21,21,1,103,187,187,1,140,249,249,1,101,176,176,1,18,30, + 30,1,152,255,255,1,155,255,255,1,79,129,129,1,80,127,127,1,156,244, + 244,1,154,236,236,1,89,134,134,1,84,124,124,1,174,255,255,1,177,255, + 255,1,0,0,0,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,25,46, + 46,1,83,152,152,1,135,240,240,1,146,255,255,1,149,255,255,1,152,255, + 255,1,155,255,255,1,20,33,33,1,148,236,236,1,163,255,255,1,166,255, + 255,1,169,255,255,1,20,29,29,1,174,255,255,1,177,255,255,1,0,0, + 0,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,127,234,234,1,68,124, + 124,1,30,54,54,1,33,58,58,1,115,196,196,1,152,255,255,1,155,255, + 255,1,3,5,5,1,159,253,253,1,163,255,255,1,166,255,255,1,168,253, + 253,1,4,6,6,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,123,214,214,1,15,26,26,1,152,255,255,1,155,255,255,1,19,31, + 31,1,147,235,235,1,163,255,255,1,130,200,200,1,143,216,216,1,30,45, + 45,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,16,29,29,1,96,174,174,1,140,250,250,1,116,203, + 203,1,16,27,27,1,152,255,255,1,155,255,255,1,78,126,126,1,78,125, + 125,1,156,244,244,1,48,73,73,1,30,46,46,1,119,177,177,1,174,255, + 255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,103,191,191,1,25,45,45,1,3,5,5,1,21,37,37,1,110,188, + 188,1,152,255,255,1,155,255,255,1,154,250,250,1,69,110,110,1,10,15, + 15,1,13,20,20,1,38,58,58,1,42,63,63,1,174,255,255,1,177,255, + 255,1,0,0,0,5,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255, + 255,1,166,255,255,1,169,255,255,1,135,200,200,1,174,255,255,1,177,255, + 255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255, + 255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255, + 255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,128,128,128,25,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255, + 255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255, + 255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128, + 128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255, + 255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255, + 255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128, + 128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255, + 255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255, + 255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255, + 255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,26,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255, + 255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128, + 128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255, + 255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255, + 255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128, + 128,26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255, + 255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255, + 255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128, + 128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255, + 255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,128,128,128,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255, + 255,66,0,0) + ); + +const + objdata_tmsesqltransaction: record size: integer; data: array[0..2325] of byte end = + (size: 2326; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,109,115, + 101,115,113,108,116,114,97,110,115,97,99,116,105,111,110,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 152,8,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 84,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,255,255,1, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,97,179,179,1, + 20,36,36,1,3,5,5,1,26,46,46,1,113,193,193,1,152,255,255,1, + 155,255,255,1,154,250,250,1,72,115,115,1,12,18,18,2,76,114,114,1, + 169,250,250,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,11,21,21,1,103,187,187,1,140,249,249,1, + 101,176,176,1,18,30,30,1,152,255,255,1,155,255,255,1,79,129,129,1, + 80,127,127,1,156,244,244,1,154,236,236,1,89,134,134,1,84,124,124,1, + 174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,25,46,46,1,83,152,152,1,135,240,240,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,20,33,33,1,148,236,236,1, + 163,255,255,1,166,255,255,1,169,255,255,1,20,29,29,1,174,255,255,1, + 177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1, + 127,234,234,1,68,124,124,1,30,54,54,1,33,58,58,1,115,196,196,1, + 152,255,255,1,155,255,255,1,3,5,5,1,159,253,253,1,163,255,255,1, + 166,255,255,1,168,253,253,1,4,6,6,1,174,255,255,1,177,255,255,1, + 0,0,0,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,123,214,214,1,15,26,26,1,152,255,255,1, + 155,255,255,1,19,31,31,1,147,235,235,1,163,255,255,1,130,200,200,1, + 143,216,216,1,30,45,45,1,174,255,255,1,177,255,255,1,0,0,0,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,16,29,29,1,96,174,174,1, + 140,250,250,1,116,203,203,1,16,27,27,1,152,255,255,1,155,255,255,1, + 78,126,126,1,78,125,125,1,156,244,244,1,48,73,73,1,30,46,46,1, + 119,177,177,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,103,191,191,1,25,45,45,1,3,5,5,1, + 21,37,37,1,110,188,188,1,152,255,255,1,155,255,255,1,154,250,250,1, + 69,110,110,1,10,15,15,1,13,20,20,1,38,58,58,1,42,63,63,1, + 174,255,255,1,177,255,255,1,0,0,0,5,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,135,200,200,1, + 174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,253,253,1, + 133,192,192,1,130,150,150,1,128,129,129,1,128,128,128,14,129,129,129,1, + 139,150,150,1,160,192,192,1,193,253,253,1,197,255,255,1,132,253,253,1, + 130,156,156,1,131,169,169,1,137,227,227,1,143,252,252,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 177,255,255,1,180,255,255,1,183,255,255,1,184,252,252,1,176,227,227,1, + 148,169,169,1,142,156,156,1,196,253,253,1,130,192,192,1,130,169,169,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 149,169,169,1,163,192,192,1,129,150,150,1,133,227,227,1,0,0,0,5, + 152,255,255,1,155,255,255,1,0,0,0,3,11,17,17,1,99,150,150,1, + 172,255,255,1,174,255,255,1,177,255,255,1,128,182,182,1,0,0,0,1, + 133,182,182,1,189,255,255,1,191,255,255,1,180,227,227,1,140,150,150,1, + 128,129,129,1,135,252,252,1,138,255,255,1,140,255,255,1,0,0,0,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,0,0,0,1, + 160,255,255,1,163,255,255,1,130,200,200,1,13,19,19,1,172,255,255,1, + 174,255,255,1,177,255,255,1,53,75,75,1,76,106,106,1,55,76,76,1, + 189,255,255,1,191,255,255,1,192,252,252,1,129,129,129,1,128,128,128,1, + 135,255,255,1,138,255,255,1,140,255,255,1,0,0,0,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,0,0,0,1,160,255,255,1, + 163,255,255,1,131,202,202,1,15,22,22,1,172,255,255,1,174,255,255,1, + 154,222,222,1,25,36,36,1,180,251,251,1,27,37,37,1,165,223,223,1, + 191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1, + 140,255,255,1,0,0,0,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,0,0,0,3,12,19,19,1,109,164,164,1,172,255,255,1, + 174,255,255,1,81,117,117,1,97,138,138,1,183,255,255,1,101,138,138,1, + 87,118,118,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1, + 138,255,255,1,140,255,255,1,0,0,0,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,0,0,0,1,160,255,255,1,137,214,214,1, + 39,60,60,1,157,237,237,1,172,255,255,1,169,247,247,1,13,19,19,1, + 0,0,0,3,14,19,19,1,185,247,247,1,194,255,255,1,128,128,128,1, + 128,129,129,1,135,252,252,1,138,255,255,1,140,255,255,1,0,0,0,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,0,0,0,1, + 160,255,255,1,163,255,255,1,104,159,159,1,64,96,96,1,172,255,255,1, + 108,159,159,1,65,93,93,1,180,255,255,1,183,255,255,1,186,255,255,1, + 69,93,93,1,120,160,160,1,192,252,252,1,129,129,129,1,129,150,150,1, + 133,227,227,1,138,255,255,1,140,255,255,1,0,0,0,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,0,0,0,1,160,255,255,1, + 163,255,255,1,165,254,254,1,37,56,56,1,137,203,203,1,35,52,52,1, + 140,201,201,1,180,255,255,1,183,255,255,1,186,255,255,1,149,201,201,1, + 40,53,53,1,180,227,227,1,140,150,150,1,130,192,192,1,130,169,169,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 149,169,169,1,163,192,192,1,132,253,253,1,130,156,156,1,131,169,169,1, + 137,227,227,1,143,252,252,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,184,252,252,1,176,227,227,1,148,169,169,1,142,156,156,1, + 196,253,253,1,132,255,255,1,135,253,253,1,133,192,192,1,130,150,150,1, + 128,129,129,1,128,128,128,14,129,129,129,1,139,150,150,1,160,192,192,1, + 193,253,253,1,197,255,255,1,12,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,66,0,0) + ); + +const + objdata_tmseibconnection: record size: integer; data: array[0..2563] of byte end = + (size: 2564; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,105,98,99,111,110,110,101,99,116,105,111,110,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,136,9, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,196,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,30,20,20, + 255,1,17,66,255,1,15,101,255,1,16,89,255,1,18,60,255,1,208,208, + 208,2,17,66,255,1,15,105,255,1,15,104,255,1,18,48,255,1,208,208, + 208,12,17,72,255,1,13,128,255,1,12,150,255,1,14,113,255,1,18,57, + 255,1,208,208,208,3,20,20,255,1,17,64,255,1,15,104,255,1,15,97, + 255,1,14,118,255,1,17,73,255,1,208,208,208,8,20,20,255,1,15,94, + 255,1,12,154,255,1,15,97,255,1,18,46,255,1,208,208,208,8,20,20, + 255,1,15,101,255,1,12,151,255,1,15,99,255,1,20,20,255,1,208,208, + 208,5,20,20,255,1,15,100,255,1,10,186,255,1,16,95,255,1,208,208, + 208,12,16,82,255,1,11,182,255,1,14,116,255,1,20,20,255,1,208,208, + 208,4,16,94,255,1,10,194,255,1,16,96,255,1,208,208,208,3,20,20, + 255,1,15,104,255,1,15,110,255,1,17,77,255,1,20,28,255,1,208,208, + 208,6,15,99,255,1,9,205,255,1,15,108,255,1,20,20,255,1,208,208, + 208,2,17,69,255,1,12,167,255,1,15,104,255,1,20,20,255,1,208,208, + 208,2,20,20,255,2,11,177,254,1,8,194,239,1,9,202,254,1,12,159, + 255,1,14,127,255,1,14,115,255,1,15,105,255,1,16,88,255,1,20,20, + 255,1,208,208,208,1,20,20,255,1,14,130,255,1,9,202,255,1,16,93, + 255,1,208,208,208,1,20,20,255,1,14,122,255,1,12,158,255,1,18,51, + 255,1,208,208,208,2,15,98,255,1,11,168,255,1,11,175,255,1,8,187, + 239,1,0,0,0,1,8,191,239,1,9,204,255,1,13,134,255,1,14,127, + 255,1,13,140,255,1,13,138,255,1,20,20,255,1,208,208,208,2,16,87, + 255,1,9,203,255,1,13,130,255,1,208,208,208,1,18,56,255,1,11,181, + 255,1,15,103,255,1,208,208,208,3,15,109,255,1,10,202,255,2,11,185, + 254,1,9,186,239,1,10,201,254,1,10,202,255,1,10,196,255,1,14,135, + 255,1,17,66,255,1,20,20,255,2,208,208,208,2,19,41,255,1,13,155, + 255,1,11,179,255,1,18,57,255,1,16,94,255,1,12,172,255,1,19,37, + 255,1,208,208,208,3,18,52,255,1,15,110,255,1,16,91,255,1,18,53, + 255,1,15,107,255,1,10,200,255,4,15,117,255,1,208,208,208,5,13,140, + 255,1,10,200,255,1,17,82,255,1,15,118,255,1,12,166,255,1,20,20, + 255,1,208,208,208,5,20,20,255,1,208,208,208,1,17,78,255,1,10,190, + 255,1,10,198,255,3,13,150,255,1,20,20,255,1,208,208,208,3,20,20, + 255,1,13,144,255,1,10,198,255,1,15,106,255,1,14,126,255,1,12,163, + 255,1,20,20,255,1,208,208,208,4,18,51,255,1,17,87,255,1,15,119, + 255,1,12,175,255,1,11,196,255,4,15,125,255,1,208,208,208,4,20,20, + 255,1,13,160,255,1,11,196,255,1,15,111,255,1,15,119,255,1,13,156, + 255,1,20,20,255,1,208,208,208,3,17,74,255,1,13,152,255,1,11,194, + 255,6,11,193,255,1,16,95,255,1,208,208,208,4,16,90,255,1,11,191, + 255,1,11,194,255,1,16,96,255,1,15,109,255,1,12,161,255,1,17,70, + 255,1,208,208,208,2,19,40,255,1,14,142,255,1,11,191,255,7,15,121, + 255,1,19,35,255,1,208,208,208,3,18,49,255,1,13,145,255,1,11,191, + 255,2,17,78,255,1,16,88,255,1,12,149,255,1,15,95,255,1,208,208, + 208,2,17,75,255,1,11,188,255,1,11,189,255,6,13,149,255,1,17,68, + 255,1,208,208,208,3,19,44,255,1,15,105,255,1,11,189,255,2,11,183, + 255,1,18,61,255,1,17,61,255,1,13,134,255,1,14,120,255,1,18,47, + 255,1,208,208,208,1,16,99,255,1,12,174,255,7,15,112,255,1,208,208, + 208,3,18,55,255,1,15,112,255,1,12,174,255,3,13,150,255,1,19,36, + 255,2,14,99,255,1,13,118,255,1,16,76,255,1,20,26,255,1,16,88, + 255,1,12,153,255,7,13,142,255,1,15,97,255,1,15,95,255,1,15,105, + 255,1,13,130,255,1,12,153,255,4,16,88,255,1,208,208,208,2,17,57, + 255,1,13,102,255,2,17,58,255,1,18,59,255,1,13,132,255,15,15,106, + 255,1,18,44,255,1,208,208,208,2,19,31,255,1,16,68,255,1,14,86, + 255,1,15,74,255,1,19,34,255,1,14,97,255,1,13,111,255,13,13,110, + 255,1,17,57,255,1,208,208,208,4,18,40,255,1,14,69,255,1,14,70, + 255,1,18,41,255,1,17,56,255,1,14,89,255,13,17,60,255,1,20,20, + 255,1,208,208,208,4,20,20,255,1,18,34,255,1,16,51,255,1,17,41, + 255,1,18,32,255,1,15,61,255,1,14,68,255,10,14,67,255,1,17,45, + 255,1,19,30,255,1,208,208,208,7,18,26,255,1,17,32,255,1,18,27, + 255,1,18,30,255,1,16,42,255,1,15,47,255,8,16,42,255,1,18,31, + 255,1,20,20,255,1,208,208,208,9,20,20,255,1,19,21,255,1,20,20, + 255,1,19,22,255,1,17,24,255,1,15,26,255,5,16,25,255,1,18,23, + 255,1,19,21,255,1,208,208,208,15,20,20,255,1,19,19,255,2,18,18, + 255,1,19,19,255,2,20,20,255,1,208,208,208,8,140,4,0,0,0,0, + 0,30,6,6,6,1,86,86,86,1,138,138,138,1,189,189,189,1,131,131, + 131,1,0,0,0,2,172,172,172,1,188,188,188,1,136,136,136,1,37,37, + 37,1,0,0,0,12,64,64,64,1,199,199,199,1,232,232,232,1,157,157, + 157,1,53,53,53,1,0,0,0,3,1,1,1,1,64,64,64,1,140,140, + 140,1,209,209,209,1,172,172,172,1,73,73,73,1,0,0,0,8,1,1, + 1,1,136,136,136,1,236,236,236,1,155,155,155,1,21,21,21,1,0,0, + 0,8,8,8,8,1,146,146,146,1,234,234,234,1,150,150,150,1,5,5, + 5,1,0,0,0,5,5,5,5,1,166,166,166,1,251,251,251,1,146,146, + 146,1,0,0,0,12,98,98,98,1,247,247,247,1,185,185,185,1,11,11, + 11,1,0,0,0,4,140,140,140,1,254,254,254,1,155,155,155,1,0,0, + 0,3,23,23,23,1,163,163,163,1,153,153,153,1,111,111,111,1,22,22, + 22,1,0,0,0,6,155,155,155,1,255,255,255,1,180,180,180,1,4,4, + 4,1,0,0,0,2,54,54,54,1,235,235,235,1,170,170,170,1,1,1, + 1,1,0,0,0,2,31,31,31,1,73,73,73,1,255,255,255,3,238,238, + 238,1,195,195,195,1,167,167,167,1,151,151,151,1,137,137,137,1,15,15, + 15,1,0,0,0,1,6,6,6,1,200,200,200,1,255,255,255,1,139,139, + 139,1,0,0,0,1,2,2,2,1,190,190,190,1,231,231,231,1,31,31, + 31,1,0,0,0,2,160,160,160,1,249,249,249,1,255,255,255,5,238,238, + 238,1,214,214,214,1,229,229,229,1,247,247,247,1,40,40,40,1,0,0, + 0,2,126,126,126,1,255,255,255,1,204,204,204,1,0,0,0,1,70,70, + 70,1,253,253,253,1,152,152,152,1,0,0,0,3,172,172,172,1,255,255, + 255,7,219,219,219,1,62,62,62,1,27,27,27,1,6,6,6,1,0,0, + 0,2,24,24,24,1,238,238,238,1,251,251,251,1,60,60,60,1,140,140, + 140,1,255,255,255,1,51,51,51,1,0,0,0,3,30,30,30,1,178,178, + 178,1,173,173,173,1,68,68,68,1,189,189,189,1,255,255,255,4,167,167, + 167,1,0,0,0,5,217,217,217,1,255,255,255,1,119,119,119,1,187,187, + 187,1,255,255,255,1,40,40,40,1,0,0,0,5,11,11,11,1,0,0, + 0,1,150,150,150,1,255,255,255,4,235,235,235,1,17,17,17,1,0,0, + 0,3,4,4,4,1,232,232,232,1,255,255,255,1,145,145,145,1,210,210, + 210,1,255,255,255,1,40,40,40,1,0,0,0,4,47,47,47,1,132,132, + 132,1,180,180,180,1,247,247,247,1,255,255,255,4,199,199,199,1,0,0, + 0,4,27,27,27,1,247,247,247,1,255,255,255,1,149,149,149,1,208,208, + 208,1,255,255,255,1,40,40,40,1,0,0,0,3,73,73,73,1,232,232, + 232,1,255,255,255,7,137,137,137,1,0,0,0,4,127,127,127,1,255,255, + 255,2,131,131,131,1,206,206,206,1,255,255,255,1,110,110,110,1,0,0, + 0,2,31,31,31,1,224,224,224,1,255,255,255,7,202,202,202,1,11,11, + 11,1,0,0,0,3,27,27,27,1,224,224,224,1,255,255,255,2,115,115, + 115,1,174,174,174,1,255,255,255,1,189,189,189,1,0,0,0,2,111,111, + 111,1,255,255,255,7,227,227,227,1,49,49,49,1,0,0,0,3,20,20, + 20,1,189,189,189,1,255,255,255,3,91,91,91,1,130,130,130,1,255,255, + 255,1,248,248,248,1,64,64,64,1,0,0,0,1,149,149,149,1,255,255, + 255,7,191,191,191,1,0,0,0,3,55,55,55,1,206,206,206,1,255,255, + 255,3,250,250,250,1,47,47,47,1,46,46,46,1,242,242,242,1,255,255, + 255,1,199,199,199,1,15,15,15,1,152,152,152,1,255,255,255,7,252,252, + 252,1,193,193,193,1,167,167,167,1,209,209,209,1,246,246,246,1,255,255, + 255,4,175,175,175,1,0,0,0,2,162,162,162,1,255,255,255,2,175,175, + 175,1,119,119,119,1,255,255,255,15,231,231,231,1,41,41,41,1,0,0, + 0,2,28,28,28,1,226,226,226,1,255,255,255,1,243,243,243,1,87,87, + 87,1,249,249,249,1,255,255,255,14,136,136,136,1,0,0,0,4,129,129, + 129,1,255,255,255,2,142,142,142,1,180,180,180,1,255,255,255,13,203,203, + 203,1,7,7,7,1,0,0,0,4,5,5,5,1,157,157,157,1,248,248, + 248,1,209,209,209,1,71,71,71,1,246,246,246,1,255,255,255,11,187,187, + 187,1,27,27,27,1,0,0,0,7,106,106,106,1,223,223,223,1,163,163, + 163,1,121,121,121,1,237,237,237,1,255,255,255,8,239,239,239,1,152,152, + 152,1,5,5,5,1,0,0,0,9,6,6,6,1,94,94,94,1,20,20, + 20,1,75,75,75,1,218,218,218,1,255,255,255,5,236,236,236,1,161,161, + 161,1,49,49,49,1,0,0,0,15,20,20,20,1,86,86,86,1,118,118, + 118,1,134,134,134,1,119,119,119,1,89,89,89,1,26,26,26,1,0,0, + 0,8,0,0) + ); + +const + objdata_tfb3connection: record size: integer; data: array[0..2705] of byte end = + (size: 2706; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,102,98, + 51,99,111,110,110,101,99,116,105,111,110,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,24,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,200,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,0,0,255,1, + 17,72,255,1,14,111,255,1,15,95,255,1,17,70,255,1,0,0,0,2, + 17,62,255,1,15,96,255,1,15,104,255,1,7,24,97,1,0,0,0,12, + 17,85,255,1,14,138,255,1,13,153,255,1,16,114,255,1,15,54,255,1, + 0,0,0,4,17,55,255,1,13,99,255,1,9,64,155,1,6,43,92,1, + 16,76,255,1,0,0,0,8,0,0,255,1,16,96,255,1,12,163,255,1, + 15,98,255,1,12,35,255,1,0,0,0,8,0,0,255,1,14,88,255,1, + 13,148,255,1,15,100,255,1,0,0,255,1,0,0,0,5,0,0,255,1, + 15,100,255,1,11,180,255,1,14,89,255,1,0,0,0,12,10,44,135,1, + 2,33,49,1,1,11,26,1,0,0,0,5,16,97,255,1,11,193,255,1, + 17,96,255,1,0,0,0,3,24,24,255,1,15,98,255,1,15,109,255,1, + 16,80,255,1,24,36,255,1,0,0,0,6,14,68,193,1,8,155,196,1, + 6,47,103,1,0,0,0,3,19,78,255,1,11,182,255,1,15,101,255,1, + 0,0,255,1,0,0,0,2,20,20,255,1,23,23,255,1,13,158,255,1, + 9,196,242,1,10,203,255,1,13,160,255,1,13,130,255,1,16,121,255,1, + 16,108,255,1,15,86,231,1,9,9,132,1,0,0,0,1,0,0,255,1, + 16,128,255,1,10,204,255,1,3,20,50,1,0,0,0,1,0,0,255,1, + 15,126,255,1,14,143,255,1,12,36,255,1,0,0,0,2,15,105,255,1, + 11,167,255,1,13,156,255,1,9,192,242,1,0,0,0,1,9,195,242,1, + 10,205,255,1,13,143,255,1,14,130,255,1,13,145,255,1,5,53,94,1, + 0,0,3,1,0,0,0,2,16,74,255,1,10,192,253,1,2,25,45,1, + 0,0,1,1,18,65,255,1,11,184,255,1,17,94,255,1,0,0,0,3, + 16,118,255,1,10,203,255,1,10,199,255,1,11,173,255,1,9,189,242,1, + 10,203,255,2,10,202,255,1,14,145,255,1,17,72,255,1,10,10,111,1, + 0,0,1,1,0,0,0,2,0,0,8,1,3,32,54,1,1,18,25,1, + 10,29,133,1,15,107,255,1,12,168,255,1,18,36,255,1,0,0,0,3, + 15,54,255,1,15,111,255,1,15,91,255,1,21,28,255,1,16,93,255,1, + 10,197,255,1,10,201,255,3,16,126,255,1,0,0,0,5,9,86,164,1, + 10,195,248,1,15,80,255,1,14,123,255,1,13,142,255,1,28,28,255,1, + 0,0,0,4,0,0,255,1,21,21,255,1,0,0,0,1,16,73,255,1, + 11,187,255,1,11,198,255,3,13,158,255,1,23,23,255,1,0,0,0,4, + 15,134,255,1,11,198,255,1,16,102,255,1,14,130,255,1,15,136,255,1, + 0,0,255,1,0,0,0,4,19,61,255,1,17,94,255,1,14,115,255,1, + 13,170,255,1,11,196,255,4,14,132,255,1,0,0,255,1,0,0,0,3, + 16,16,255,1,14,151,255,1,11,196,255,1,16,111,255,1,15,125,255,1, + 14,148,255,1,20,20,255,1,0,0,0,3,18,84,255,1,13,158,255,1, + 11,194,255,6,11,192,255,1,17,94,255,1,0,0,0,4,17,81,255,1, + 12,190,255,1,11,194,255,1,16,110,255,2,13,160,255,1,18,63,255,1, + 0,0,0,2,14,43,255,1,14,149,255,1,12,192,255,7,15,119,255,1, + 21,43,255,1,0,0,0,3,13,38,255,1,14,133,255,1,12,192,255,2, + 15,105,255,1,17,94,255,1,13,150,255,1,17,87,255,1,0,0,0,2, + 17,86,255,1,12,190,255,7,15,145,255,1,23,68,255,1,0,0,0,3, + 36,36,255,1,15,100,255,1,12,189,255,1,12,190,255,2,17,79,255,1, + 16,69,255,1,13,134,255,1,14,114,255,1,18,45,255,1,0,0,0,1, + 16,102,255,1,12,175,255,7,15,108,255,1,0,0,0,3,21,53,255,1, + 16,101,255,1,12,172,255,1,12,175,255,2,13,155,255,1,22,48,255,1, + 20,40,255,1,15,101,255,1,14,118,255,1,17,75,255,1,28,28,255,1, + 16,91,255,1,13,153,255,7,14,141,255,1,16,91,255,2,16,99,255,1, + 15,128,255,1,13,153,255,4,16,96,255,1,0,0,0,2,17,64,255,1, + 14,103,255,1,14,102,255,1,17,62,255,1,17,68,255,1,13,132,255,15, + 13,123,255,1,16,52,255,1,0,0,0,2,20,40,255,1,15,75,255,1, + 14,87,255,1,16,70,255,1,21,35,255,1,14,99,255,1,14,111,255,14, + 16,61,255,1,0,0,255,1,0,0,0,3,18,41,255,1,15,69,255,1, + 16,70,255,1,18,36,255,1,17,60,255,1,14,90,255,13,17,63,255,1, + 14,28,255,1,0,0,0,4,0,0,255,1,18,36,255,1,15,54,255,1, + 18,41,255,1,19,36,255,1,14,63,255,1,15,69,255,10,15,68,255,1, + 18,47,255,1,15,29,255,1,0,0,0,6,0,0,255,1,18,28,255,1, + 17,34,255,1,17,27,255,1,18,31,255,1,16,46,255,1,15,48,255,8, + 16,43,255,1,18,32,255,1,26,26,255,1,0,0,0,9,20,20,255,1, + 19,21,255,1,14,14,255,1,18,22,255,1,17,26,255,1,16,27,255,5, + 17,26,255,1,19,24,255,1,19,23,255,1,0,0,0,15,23,23,255,1, + 20,20,255,1,19,19,255,4,18,18,255,1,0,0,0,8,24,5,0,0, + 0,0,0,17,60,60,60,1,176,176,176,1,221,221,221,1,228,228,228,1, + 193,193,193,1,91,91,91,1,0,0,0,7,6,6,6,1,89,89,89,1, + 143,143,143,1,193,193,193,1,132,132,132,1,0,0,0,2,169,169,169,1, + 189,189,189,1,140,140,140,1,108,108,108,1,250,250,250,1,133,133,133,1, + 25,25,25,1,16,16,16,1,98,98,98,1,253,253,253,1,98,98,98,1, + 0,0,0,5,90,90,90,1,207,207,207,1,231,231,231,1,157,157,157,1, + 52,52,52,1,0,0,0,4,46,46,46,1,134,134,134,1,224,224,224,1, + 228,228,228,1,81,81,81,1,0,0,0,3,215,215,215,1,176,176,176,1, + 0,0,0,3,1,1,1,1,141,141,141,1,239,239,239,1,149,149,149,1, + 22,22,22,1,0,0,0,8,4,4,4,1,127,127,127,1,231,231,231,1, + 151,151,151,1,5,5,5,1,62,62,62,1,249,249,249,1,109,109,109,1, + 0,0,0,2,5,5,5,1,166,166,166,1,247,247,247,1,129,129,129,1, + 0,0,0,12,127,127,127,1,252,252,252,1,246,246,246,1,253,253,253,1, + 116,116,116,1,0,0,0,3,155,155,155,1,254,254,254,1,149,149,149,1, + 0,0,0,3,21,21,21,1,169,169,169,1,157,157,157,1,109,109,109,1, + 21,21,21,1,0,0,0,5,10,10,10,1,149,149,149,1,255,255,255,1, + 226,226,226,1,248,248,248,1,93,93,93,1,0,0,0,1,92,92,92,1, + 248,248,248,1,170,170,170,1,1,1,1,1,0,0,0,2,25,25,25,1, + 22,22,22,1,237,237,237,1,255,255,255,2,237,237,237,1,191,191,191,1, + 164,164,164,1,147,147,147,1,137,137,137,1,27,27,27,1,0,0,0,1, + 4,4,4,1,195,195,195,1,255,255,255,1,220,220,220,1,222,222,222,1, + 3,3,3,1,199,199,199,1,218,218,218,1,21,21,21,1,0,0,0,2, + 170,170,170,1,245,245,245,1,236,236,236,1,255,255,255,4,242,242,242,1, + 216,216,216,1,228,228,228,1,252,252,252,1,238,238,238,1,13,13,13,1, + 0,0,0,1,97,97,97,1,254,254,254,1,247,247,247,1,196,196,196,1, + 86,86,86,1,253,253,253,1,138,138,138,1,0,0,0,3,179,179,179,1, + 255,255,255,2,253,253,253,1,255,255,255,4,221,221,221,1,74,74,74,1, + 53,53,53,1,216,216,216,1,218,218,218,1,134,134,134,1,132,132,132,1, + 249,249,249,1,255,255,255,1,98,98,98,1,157,157,157,1,250,250,250,1, + 42,42,42,1,0,0,0,3,33,33,33,1,184,184,184,1,165,165,165,1, + 37,37,37,1,162,162,162,1,255,255,255,4,197,197,197,1,0,0,0,1, + 2,2,2,1,69,69,69,1,110,110,110,1,112,112,112,1,222,222,222,1, + 255,255,255,1,118,118,118,1,195,195,195,1,233,233,233,1,9,9,9,1, + 0,0,0,4,1,1,1,1,12,12,12,1,0,0,0,1,112,112,112,1, + 255,255,255,4,242,242,242,1,22,22,22,1,0,0,0,4,209,209,209,1, + 255,255,255,1,145,145,145,1,215,215,215,1,228,228,228,1,4,4,4,1, + 0,0,0,4,54,54,54,1,135,135,135,1,177,177,177,1,244,244,244,1, + 255,255,255,4,216,216,216,1,1,1,1,1,0,0,0,3,16,16,16,1, + 237,237,237,1,255,255,255,1,158,158,158,1,220,220,220,1,245,245,245,1, + 26,26,26,1,0,0,0,3,100,100,100,1,236,236,236,1,255,255,255,7, + 146,146,146,1,0,0,0,4,120,120,120,1,255,255,255,2,157,157,157,1, + 208,208,208,1,255,255,255,1,101,101,101,1,0,0,0,2,36,36,36,1, + 230,230,230,1,255,255,255,7,201,201,201,1,12,12,12,1,0,0,0,3, + 20,20,20,1,214,214,214,1,255,255,255,2,151,151,151,1,181,181,181,1, + 255,255,255,1,170,170,170,1,0,0,0,2,133,133,133,1,255,255,255,7, + 223,223,223,1,45,45,45,1,0,0,0,3,7,7,7,1,181,181,181,1, + 255,255,255,3,119,119,119,1,141,141,141,1,255,255,255,1,242,242,242,1, + 57,57,57,1,0,0,0,1,162,162,162,1,255,255,255,7,181,181,181,1, + 0,0,0,3,48,48,48,1,189,189,189,1,255,255,255,3,251,251,251,1, + 58,58,58,1,51,51,51,1,244,244,244,1,255,255,255,1,197,197,197,1, + 9,9,9,1,163,163,163,1,255,255,255,7,250,250,250,1,179,179,179,1, + 160,160,160,1,194,194,194,1,242,242,242,1,255,255,255,4,192,192,192,1, + 0,0,0,2,175,175,175,1,255,255,255,2,161,161,161,1,138,138,138,1, + 255,255,255,15,252,252,252,1,98,98,98,1,0,0,0,2,63,63,63,1, + 239,239,239,1,255,255,255,1,228,228,228,1,72,72,72,1,250,250,250,1, + 255,255,255,14,175,175,175,1,1,1,1,1,0,0,0,3,144,144,144,1, + 255,255,255,2,112,112,112,1,194,194,194,1,255,255,255,13,208,208,208,1, + 18,18,18,1,0,0,0,4,5,5,5,1,171,171,171,1,255,255,255,1, + 204,204,204,1,92,92,92,1,247,247,247,1,255,255,255,11,200,200,200,1, + 35,35,35,1,0,0,0,6,3,3,3,1,127,127,127,1,227,227,227,1, + 167,167,167,1,138,138,138,1,250,250,250,1,255,255,255,8,243,243,243,1, + 158,158,158,1,10,10,10,1,0,0,0,9,25,25,25,1,133,133,133,1, + 18,18,18,1,125,125,125,1,230,230,230,1,255,255,255,5,239,239,239,1, + 178,178,178,1,67,67,67,1,0,0,0,15,22,22,22,1,104,104,104,1, + 134,134,134,1,146,146,146,1,131,131,131,1,105,105,105,1,29,29,29,1, + 0,0,0,8,0,0) + ); + +const + objdata_tfbservice: record size: integer; data: array[0..2921] of byte end = + (size: 2922; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,102,98, + 115,101,114,118,105,99,101,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,244,10,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,188,5,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,30,0,0,255,1,17,72,255,1, + 14,111,255,1,15,95,255,1,17,70,255,1,0,0,0,2,17,62,255,1, + 15,96,255,1,15,104,255,1,18,59,255,1,0,0,0,12,17,85,255,1, + 14,138,255,1,13,153,255,1,16,114,255,1,15,54,255,1,0,0,0,4, + 17,55,255,1,13,99,255,1,15,104,255,1,15,119,255,1,16,76,255,1, + 0,0,0,8,0,0,255,1,16,96,255,1,12,163,255,1,15,98,255,1, + 12,35,255,1,0,0,0,8,0,0,255,1,14,88,255,1,13,148,255,1, + 15,100,255,1,0,0,255,1,0,0,0,5,0,0,142,1,15,100,255,1, + 11,180,255,1,14,89,255,1,0,0,0,12,17,84,255,1,12,174,255,1, + 13,115,255,1,13,38,255,1,0,0,0,4,3,22,57,1,3,53,70,1, + 10,61,162,1,0,0,0,3,1,1,10,1,3,25,63,1,15,109,253,1, + 1,7,21,1,1,1,10,1,0,0,0,6,17,91,255,1,10,202,255,1, + 14,118,255,1,32,32,255,1,0,0,0,2,7,30,97,1,11,182,255,1, + 13,89,226,1,0,0,0,3,20,20,255,1,23,23,255,1,13,158,255,1, + 9,196,242,1,1,30,38,1,13,160,255,1,13,130,255,1,6,47,98,1, + 7,51,120,1,16,95,255,1,17,17,255,1,0,0,0,1,0,0,255,1, + 16,128,255,1,10,204,255,1,16,99,255,1,0,0,0,1,0,0,7,1, + 3,23,46,1,10,100,178,1,12,35,243,1,0,0,0,2,1,10,26,1, + 9,132,202,1,11,122,201,1,8,169,213,1,0,0,0,1,1,29,36,1, + 10,205,255,1,13,143,255,1,5,51,101,1,9,89,156,1,14,143,255,1, + 20,20,255,1,0,0,0,2,16,74,255,1,10,194,255,1,14,138,255,1, + 0,0,255,1,18,65,255,1,9,150,208,1,5,26,69,1,0,0,0,3, + 1,8,17,1,5,108,136,1,5,106,136,1,8,123,183,1,9,189,242,1, + 1,24,30,1,3,68,85,1,2,39,49,1,5,50,87,1,17,70,245,1, + 20,20,255,1,0,0,255,1,0,0,0,2,32,32,255,1,13,148,255,1, + 11,183,255,1,20,57,255,1,8,64,152,1,11,160,242,1,18,36,255,1, + 0,0,0,3,0,1,7,1,15,111,255,1,15,91,255,1,21,28,255,1, + 16,93,255,1,1,29,38,1,10,201,255,1,8,161,204,1,3,60,76,1, + 16,126,255,1,0,0,0,5,14,134,255,1,10,201,255,1,15,80,255,1, + 7,57,119,1,5,56,100,1,5,5,34,1,0,0,0,4,0,0,4,1, + 3,3,30,1,0,0,0,1,16,72,248,1,2,28,38,1,11,198,255,2, + 4,68,87,1,9,116,185,1,23,23,255,1,0,0,0,4,15,134,255,1, + 11,198,255,1,16,102,255,1,14,130,255,1,10,97,179,1,0,0,4,1, + 0,0,0,4,3,12,50,1,7,36,96,1,6,51,113,1,13,166,249,1, + 7,118,154,1,11,196,255,2,10,171,223,1,9,86,167,1,0,0,255,1, + 0,0,0,3,16,16,255,1,14,151,255,1,11,196,255,1,16,111,255,1, + 15,125,255,1,14,148,255,1,20,20,255,1,0,0,0,3,18,84,255,1, + 13,158,255,1,11,194,255,6,11,192,255,1,17,94,255,1,0,0,0,4, + 17,81,255,1,12,190,255,1,11,194,255,1,16,110,255,2,13,160,255,1, + 18,63,255,1,0,0,0,2,14,43,255,1,14,149,255,1,12,192,255,7, + 15,119,255,1,21,43,255,1,0,0,0,3,13,38,255,1,14,133,255,1, + 12,192,255,2,15,105,255,1,3,17,46,1,12,136,232,1,17,87,255,1, + 0,0,0,2,9,46,135,1,6,90,121,1,9,139,187,1,12,190,255,1, + 8,124,167,1,3,45,61,1,4,57,76,1,4,70,94,1,15,142,249,1, + 8,23,85,1,0,0,0,3,0,0,6,1,15,100,255,1,12,189,255,1, + 12,190,255,2,17,79,255,1,7,26,99,1,8,78,148,1,14,114,255,1, + 17,43,246,1,0,0,0,1,15,97,241,1,5,77,112,1,9,125,182,1, + 11,158,230,1,2,35,51,1,12,170,247,1,12,175,255,1,6,89,129,1, + 9,57,134,1,0,0,0,3,21,53,255,1,16,101,255,1,12,172,255,1, + 12,175,255,2,13,155,255,1,22,48,255,1,14,24,161,1,3,24,61,1, + 14,118,255,1,12,52,177,1,0,0,5,1,16,91,255,1,6,67,112,1, + 9,109,182,1,9,103,171,1,6,72,120,1,13,153,255,2,12,147,245,1, + 13,131,236,1,10,59,164,1,3,23,63,1,12,74,192,1,11,101,202,1, + 12,142,237,1,13,153,255,3,16,96,255,1,0,0,0,2,3,13,54,1, + 12,91,225,1,6,41,102,1,11,42,170,1,17,68,255,1,6,58,112,1, + 9,94,182,1,8,84,162,1,7,68,131,1,13,132,255,4,9,95,184,1, + 3,27,52,1,6,62,119,2,11,107,207,1,13,132,255,2,13,123,255,1, + 16,52,255,1,0,0,0,2,6,12,80,1,7,38,129,1,3,18,53,1, + 16,70,254,1,21,35,255,1,6,43,111,1,10,79,182,1,11,84,194,1, + 5,43,98,1,14,111,255,2,11,90,206,1,10,82,188,1,10,80,184,1, + 6,48,111,1,14,111,255,5,16,61,255,1,0,0,255,1,0,0,0,3, + 1,2,16,1,8,35,128,1,16,70,255,1,18,36,255,1,7,22,95,1, + 10,64,182,1,14,89,253,1,3,22,61,1,9,61,173,1,11,74,209,1, + 4,24,67,1,11,72,204,1,10,65,184,1,5,31,88,1,11,72,204,2, + 12,76,214,1,14,90,255,1,17,63,255,1,14,28,255,1,0,0,0,4, + 0,0,9,1,16,30,217,1,15,54,255,1,18,41,255,1,9,19,128,1, + 12,54,220,1,15,69,255,1,14,65,241,1,8,38,142,1,7,34,124,1, + 12,55,203,1,15,69,255,1,13,60,222,1,8,37,136,3,9,43,160,1, + 18,47,255,1,15,29,255,1,0,0,0,6,0,0,255,1,18,28,255,1, + 17,34,255,1,17,27,255,1,18,31,255,1,16,46,255,1,15,48,255,8, + 16,43,255,1,18,32,255,1,26,26,255,1,0,0,0,9,20,20,255,1, + 19,21,255,1,14,14,255,1,18,22,255,1,17,26,255,1,16,27,255,5, + 17,26,255,1,19,24,255,1,19,23,255,1,0,0,0,15,23,23,255,1, + 20,20,255,1,19,19,255,4,18,18,255,1,0,0,0,8,0,5,0,0, + 0,0,0,30,6,6,6,1,89,89,89,1,143,143,143,1,193,193,193,1, + 132,132,132,1,0,0,0,2,169,169,169,1,189,189,189,1,140,140,140,1, + 56,56,56,1,0,0,0,12,90,90,90,1,207,207,207,1,231,231,231,1, + 157,157,157,1,52,52,52,1,0,0,0,4,46,46,46,1,134,134,134,1, + 208,208,208,1,193,193,193,1,81,81,81,1,0,0,0,8,1,1,1,1, + 141,141,141,1,239,239,239,1,149,149,149,1,22,22,22,1,0,0,0,8, + 4,4,4,1,127,127,127,1,231,231,231,1,151,151,151,1,5,5,5,1, + 0,0,0,5,9,9,9,1,166,166,166,1,247,247,247,1,129,129,129,1, + 0,0,0,12,88,88,88,1,240,240,240,1,189,189,189,1,20,20,20,1, + 0,0,0,2,26,26,26,1,184,184,184,1,222,222,222,1,255,255,255,1, + 176,176,176,1,7,7,7,1,226,226,226,1,170,170,170,1,177,177,177,1, + 226,226,226,1,157,157,157,1,230,230,230,1,177,177,177,2,168,168,168,1, + 10,10,10,1,0,0,0,3,132,132,132,1,255,255,255,1,194,194,194,1, + 8,8,8,1,0,0,0,1,128,128,128,1,152,152,152,1,248,248,248,1, + 177,177,177,1,175,175,175,1,7,7,7,1,209,209,209,1,25,25,25,1, + 22,22,22,1,237,237,237,1,255,255,255,2,237,237,237,1,191,191,191,1, + 210,210,210,1,189,189,189,1,131,131,131,1,15,15,15,1,0,0,0,1, + 4,4,4,1,195,195,195,1,255,255,255,1,142,142,142,1,0,0,0,1, + 74,74,74,1,242,242,242,1,228,228,228,1,22,22,22,1,0,0,0,1, + 7,7,7,1,243,243,243,1,247,247,247,1,240,240,240,1,255,255,255,4, + 242,242,242,1,238,238,238,2,248,248,248,1,38,38,38,1,0,0,0,2, + 97,97,97,1,254,254,254,1,214,214,214,1,3,3,3,1,86,86,86,1, + 253,253,253,1,207,207,207,1,206,206,206,1,60,60,60,1,7,7,7,1, + 248,248,248,1,255,255,255,2,254,254,254,1,255,255,255,4,242,242,242,1, + 76,76,76,1,26,26,26,1,5,5,5,1,0,0,0,2,8,8,8,1, + 228,228,228,1,252,252,252,1,63,63,63,1,186,186,186,1,250,250,250,1, + 42,42,42,1,24,24,24,1,204,204,204,1,7,7,7,1,215,215,215,1, + 184,184,184,1,165,165,165,1,37,37,37,1,162,162,162,1,255,255,255,4, + 197,197,197,1,0,0,0,5,207,207,207,1,255,255,255,1,118,118,118,1, + 223,223,223,1,246,246,246,1,53,53,53,1,98,98,98,1,175,175,175,1, + 7,7,7,1,221,221,221,1,69,69,69,1,77,77,77,1,68,68,68,1, + 114,114,114,1,255,255,255,4,245,245,245,1,22,22,22,1,0,0,0,4, + 209,209,209,1,255,255,255,1,145,145,145,1,215,215,215,1,235,235,235,1, + 129,129,129,1,104,104,104,1,12,12,12,1,3,3,3,1,119,119,119,1, + 148,148,148,1,191,191,191,1,213,213,213,1,244,244,244,1,255,255,255,4, + 228,228,228,1,1,1,1,1,0,0,0,3,16,16,16,1,237,237,237,1, + 255,255,255,1,158,158,158,1,220,220,220,1,245,245,245,1,26,26,26,1, + 0,0,0,3,100,100,100,1,236,236,236,1,255,255,255,7,146,146,146,1, + 0,0,0,4,120,120,120,1,255,255,255,2,157,157,157,1,208,208,208,1, + 255,255,255,1,101,101,101,1,0,0,0,2,36,36,36,1,230,230,230,1, + 255,255,255,7,201,201,201,1,12,12,12,1,0,0,0,3,20,20,20,1, + 214,214,214,1,255,255,255,2,151,151,151,1,237,237,237,1,255,255,255,1, + 170,170,170,1,0,0,0,1,137,137,137,1,172,172,172,1,255,255,255,7, + 224,224,224,1,99,99,99,1,209,209,209,1,170,170,170,2,131,131,131,1, + 181,181,181,1,255,255,255,3,119,119,119,1,194,194,194,1,255,255,255,1, + 242,242,242,1,59,59,59,1,215,215,215,1,165,165,165,1,255,255,255,7, + 210,210,210,1,71,71,71,1,144,144,144,1,0,0,0,1,48,48,48,1, + 189,189,189,1,255,255,255,3,251,251,251,1,58,58,58,1,73,73,73,1, + 252,252,252,1,255,255,255,1,212,212,212,1,159,159,159,1,163,163,163,1, + 255,255,255,7,250,250,250,1,200,200,200,1,222,222,222,1,206,206,206,1, + 245,245,245,1,255,255,255,4,192,192,192,1,0,0,0,2,232,232,232,1, + 255,255,255,2,183,183,183,1,138,138,138,1,255,255,255,15,252,252,252,1, + 98,98,98,1,0,0,0,2,131,131,131,1,247,247,247,1,255,255,255,1, + 228,228,228,1,72,72,72,1,253,253,253,1,255,255,255,14,175,175,175,1, + 1,1,1,1,0,0,0,2,10,10,10,1,244,244,244,1,255,255,255,2, + 112,112,112,1,228,228,228,1,255,255,255,13,208,208,208,1,18,18,18,1, + 0,0,0,4,88,88,88,1,180,180,180,1,255,255,255,1,204,204,204,1, + 135,135,135,1,248,248,248,1,255,255,255,11,200,200,200,1,35,35,35,1, + 0,0,0,6,3,3,3,1,127,127,127,1,227,227,227,1,167,167,167,1, + 138,138,138,1,250,250,250,1,255,255,255,8,243,243,243,1,158,158,158,1, + 10,10,10,1,0,0,0,9,25,25,25,1,133,133,133,1,18,18,18,1, + 125,125,125,1,230,230,230,1,255,255,255,5,239,239,239,1,178,178,178,1, + 67,67,67,1,0,0,0,15,22,22,22,1,104,104,104,1,134,134,134,1, + 146,146,146,1,131,131,131,1,105,105,105,1,29,29,29,1,0,0,0,8, + 0,0) + ); + +const + objdata_tfb3service: record size: integer; data: array[0..3034] of byte end = + (size: 3035; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,102,98, + 51,115,101,114,118,105,99,101,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,100,11,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,188,5,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,30,0,0,255,1,17,72,255, + 1,14,111,255,1,15,95,255,1,17,70,255,1,0,0,0,2,17,62,255, + 1,15,96,255,1,15,104,255,1,7,20,91,1,0,0,0,12,17,85,255, + 1,14,138,255,1,13,153,255,1,16,114,255,1,15,54,255,1,0,0,0, + 4,17,55,255,1,13,99,255,1,9,68,167,1,6,50,107,1,16,75,252, + 1,0,0,0,8,0,0,255,1,16,96,255,1,12,163,255,1,15,98,255, + 1,12,35,255,1,0,0,0,8,0,0,255,1,14,88,255,1,13,148,255, + 1,15,100,255,1,0,0,213,1,0,0,0,5,0,0,142,1,15,100,255, + 1,11,180,255,1,14,89,255,1,0,0,0,12,10,44,137,1,1,22,32, + 1,0,4,8,1,0,0,0,5,3,22,57,1,3,53,70,1,10,57,150, + 1,0,0,0,3,1,1,10,1,3,25,63,1,14,101,236,1,2,8,27, + 1,1,1,10,1,0,0,0,6,15,80,224,1,9,176,222,1,7,62,132, + 1,0,0,0,3,6,25,82,1,11,182,255,1,15,94,237,1,0,0,0, + 3,20,20,255,1,23,23,255,1,13,158,255,1,9,196,242,1,2,33,42, + 1,13,158,251,1,13,130,255,1,8,54,114,1,7,44,104,1,12,78,212, + 1,6,6,81,1,0,0,0,1,0,0,255,1,16,128,255,1,10,204,255, + 1,4,23,59,1,0,0,0,1,0,0,9,1,2,21,43,1,9,96,171, + 1,11,33,233,1,0,0,0,2,1,9,23,1,9,132,202,1,11,122,201, + 1,8,166,210,1,0,0,0,1,1,32,40,1,10,202,251,1,13,143,255, + 1,6,59,117,1,7,80,140,1,6,62,109,1,0,0,2,1,0,0,0, + 2,16,74,255,1,10,191,251,1,2,23,42,1,0,0,1,1,18,65,255, + 1,9,155,215,1,5,27,75,1,0,0,0,3,1,8,19,1,5,108,136, + 1,5,106,136,1,8,119,176,1,9,189,242,1,2,33,42,1,3,67,84, + 1,2,44,55,1,4,43,75,1,16,69,235,1,12,12,149,1,0,0,1, + 1,0,0,0,2,0,0,5,1,2,21,38,1,2,28,40,1,11,33,150, + 1,10,67,159,1,11,156,236,1,18,36,255,1,0,0,0,3,0,1,6, + 1,15,111,255,1,15,91,255,1,21,28,255,1,16,93,255,1,2,32,42, + 1,10,198,251,1,9,171,217,1,2,50,63,1,16,126,255,1,0,0,0, + 5,11,100,190,1,10,200,254,1,15,80,255,1,8,65,135,1,4,49,88, + 1,5,5,32,1,0,0,0,4,0,0,4,1,3,3,30,1,0,0,0, + 1,15,68,237,1,2,31,42,1,11,195,251,1,11,198,255,1,4,79,102, + 1,8,105,169,1,23,23,255,1,0,0,0,4,15,134,255,1,11,198,255, + 1,16,102,255,1,14,130,255,1,11,100,187,1,0,0,4,1,0,0,0, + 4,3,12,50,1,7,36,96,1,6,51,113,1,11,161,241,1,7,120,156, + 1,11,194,253,1,11,196,255,1,10,177,230,1,9,82,158,1,0,0,255, + 1,0,0,0,3,16,16,255,1,14,151,255,1,11,196,255,1,16,111,255, + 1,15,125,255,1,14,148,255,1,20,20,255,1,0,0,0,3,18,84,255, + 1,13,158,255,1,11,194,255,6,11,192,255,1,17,94,255,1,0,0,0, + 4,17,81,255,1,12,190,255,1,11,194,255,1,16,110,255,2,13,160,255, + 1,18,63,255,1,0,0,0,2,14,43,255,1,14,149,255,1,12,192,255, + 7,15,119,255,1,21,43,255,1,0,0,0,3,13,38,255,1,14,133,255, + 1,12,192,255,2,15,105,255,1,3,21,58,1,11,129,219,1,17,87,255, + 1,0,0,0,2,9,40,118,1,6,102,137,1,8,128,172,1,12,190,255, + 1,8,133,178,1,3,46,62,1,4,57,77,1,4,64,86,1,14,139,244, + 1,9,29,106,1,0,0,0,3,0,0,5,1,15,100,255,1,12,189,255, + 1,12,190,255,2,17,79,255,1,7,31,115,1,7,69,132,1,14,114,255, + 1,18,45,255,1,0,0,0,1,14,91,228,1,6,88,128,1,8,114,166, + 1,11,165,240,1,2,31,45,1,11,167,243,1,12,175,255,1,7,100,145, + 1,7,50,117,1,0,0,0,3,21,53,255,1,16,101,255,1,12,172,255, + 1,12,175,255,2,13,155,255,1,22,48,255,1,16,28,191,1,3,20,50, + 1,14,118,255,1,12,58,195,1,0,0,4,1,16,91,255,1,7,77,128, + 1,8,100,166,1,10,112,187,1,5,62,104,1,13,153,255,2,13,148,247, + 1,13,130,234,1,12,65,183,1,3,19,54,1,12,74,192,1,11,101,202, + 1,12,140,234,1,13,153,255,3,16,96,255,1,0,0,0,2,4,17,66, + 1,12,85,211,1,6,47,117,1,11,36,151,1,17,68,255,1,7,66,128, + 1,8,86,166,1,9,92,178,1,6,60,115,1,13,132,255,4,10,104,200, + 1,2,23,44,1,6,62,119,2,10,103,199,1,13,132,255,2,13,123,255, + 1,16,52,255,1,0,0,0,2,9,15,96,1,7,34,118,1,3,18,53, + 1,16,69,249,1,21,35,255,1,7,50,126,1,9,72,166,1,11,91,209, + 1,4,36,82,1,14,111,255,2,12,93,214,1,10,78,180,1,11,87,200, + 1,5,41,95,1,14,111,255,5,16,61,255,1,0,0,255,1,0,0,0, + 3,1,3,21,1,7,30,112,1,16,70,255,1,18,36,255,1,8,26,110, + 1,9,59,166,1,14,90,255,1,4,25,70,1,9,58,164,1,12,75,212, + 1,4,26,75,1,10,67,191,1,11,71,200,1,4,27,76,1,11,72,204, + 2,12,74,211,1,14,90,255,1,17,63,255,1,14,28,255,1,0,0,0, + 4,0,0,10,1,14,29,207,1,15,54,255,1,18,41,255,1,10,20,139, + 1,12,52,213,1,15,69,255,1,14,67,246,1,9,40,146,1,7,33,123, + 1,11,53,195,1,15,69,255,1,13,62,229,1,8,37,136,3,9,41,152, + 1,18,47,255,1,15,29,255,1,0,0,0,6,0,0,255,1,18,28,255, + 1,17,34,255,1,17,27,255,1,18,31,255,1,16,46,255,1,15,48,255, + 8,16,43,255,1,18,32,255,1,26,26,255,1,0,0,0,9,20,20,255, + 1,19,21,255,1,14,14,255,1,18,22,255,1,17,26,255,1,16,27,255, + 5,17,26,255,1,19,24,255,1,19,23,255,1,0,0,0,15,23,23,255, + 1,20,20,255,1,19,19,255,4,18,18,255,1,0,0,0,8,112,5,0, + 0,0,0,0,17,76,76,76,1,197,197,197,1,242,242,242,2,220,220,220, + 1,120,120,120,1,2,2,2,1,0,0,0,6,6,6,6,1,89,89,89, + 1,143,143,143,1,193,193,193,1,132,132,132,1,0,0,0,2,169,169,169, + 1,189,189,189,1,140,140,140,1,112,112,112,1,253,253,253,1,115,115,115, + 1,4,4,4,1,0,0,0,1,68,68,68,1,248,248,248,1,119,119,119, + 1,0,0,0,5,90,90,90,1,207,207,207,1,231,231,231,1,157,157,157, + 1,52,52,52,1,0,0,0,4,46,46,46,1,134,134,134,1,222,222,222, + 1,225,225,225,1,82,82,82,1,0,0,0,3,208,208,208,1,185,185,185, + 1,0,0,0,3,1,1,1,1,141,141,141,1,239,239,239,1,149,149,149, + 1,22,22,22,1,0,0,0,8,4,4,4,1,127,127,127,1,231,231,231, + 1,151,151,151,1,6,6,6,1,82,82,82,1,249,249,249,1,101,101,101, + 1,0,0,0,2,9,9,9,1,166,166,166,1,247,247,247,1,129,129,129, + 1,0,0,0,12,127,127,127,1,253,253,253,1,252,252,252,1,253,253,253, + 1,119,119,119,1,0,0,0,1,19,19,19,1,180,180,180,1,223,223,223, + 1,255,255,255,1,180,180,180,1,0,0,0,1,222,222,222,1,170,170,170, + 1,177,177,177,1,226,226,226,1,162,162,162,1,223,223,223,1,178,178,178, + 1,175,175,175,1,174,174,174,1,16,16,16,1,0,0,0,2,5,5,5, + 1,140,140,140,1,255,255,255,1,219,219,219,1,247,247,247,1,119,119,119, + 1,112,112,112,1,162,162,162,1,248,248,248,1,174,174,174,1,183,183,183, + 1,0,0,0,1,216,216,216,1,25,25,25,1,22,22,22,1,237,237,237, + 1,255,255,255,2,237,237,237,1,191,191,191,1,204,204,204,1,196,196,196, + 1,143,143,143,1,41,41,41,1,0,0,0,1,4,4,4,1,195,195,195, + 1,255,255,255,1,215,215,215,1,231,231,231,1,60,60,60,1,244,244,244, + 1,229,229,229,1,23,23,23,1,0,0,0,2,244,244,244,1,247,247,247, + 1,240,240,240,1,255,255,255,4,242,242,242,1,236,236,236,1,239,239,239, + 1,252,252,252,1,246,246,246,1,26,26,26,1,0,0,0,1,97,97,97, + 1,254,254,254,1,247,247,247,1,195,195,195,1,86,86,86,1,253,253,253, + 1,205,205,205,1,208,208,208,1,71,71,71,1,0,0,0,1,248,248,248, + 1,255,255,255,2,254,254,254,1,255,255,255,4,244,244,244,1,78,78,78, + 1,41,41,41,1,190,190,190,1,236,236,236,1,162,162,162,1,154,154,154, + 1,251,251,251,1,255,255,255,1,92,92,92,1,184,184,184,1,250,250,250, + 1,42,42,42,1,17,17,17,1,211,211,211,1,0,0,0,1,221,221,221, + 1,184,184,184,1,165,165,165,1,37,37,37,1,162,162,162,1,255,255,255, + 4,197,197,197,1,0,0,0,2,44,44,44,1,85,85,85,1,92,92,92, + 1,217,217,217,1,255,255,255,1,118,118,118,1,219,219,219,1,247,247,247, + 1,55,55,55,1,88,88,88,1,188,188,188,1,0,0,0,1,224,224,224, + 1,69,69,69,1,77,77,77,1,68,68,68,1,116,116,116,1,255,255,255, + 4,246,246,246,1,22,22,22,1,0,0,0,4,209,209,209,1,255,255,255, + 1,145,145,145,1,215,215,215,1,235,235,235,1,127,127,127,1,109,109,109, + 1,16,16,16,1,0,0,0,1,115,115,115,1,148,148,148,1,191,191,191, + 1,213,213,213,1,245,245,245,1,255,255,255,4,229,229,229,1,1,1,1, + 1,0,0,0,3,16,16,16,1,237,237,237,1,255,255,255,1,158,158,158, + 1,220,220,220,1,245,245,245,1,26,26,26,1,0,0,0,3,100,100,100, + 1,236,236,236,1,255,255,255,7,146,146,146,1,0,0,0,4,120,120,120, + 1,255,255,255,2,157,157,157,1,208,208,208,1,255,255,255,1,101,101,101, + 1,0,0,0,2,36,36,36,1,230,230,230,1,255,255,255,7,201,201,201, + 1,12,12,12,1,0,0,0,3,20,20,20,1,214,214,214,1,255,255,255, + 2,151,151,151,1,234,234,234,1,255,255,255,1,170,170,170,1,0,0,0, + 1,122,122,122,1,179,179,179,1,255,255,255,7,224,224,224,1,87,87,87, + 1,213,213,213,1,170,170,170,2,142,142,142,1,181,181,181,1,255,255,255, + 3,119,119,119,1,187,187,187,1,255,255,255,1,242,242,242,1,57,57,57, + 1,209,209,209,1,169,169,169,1,255,255,255,7,215,215,215,1,55,55,55, + 1,160,160,160,1,0,0,0,1,48,48,48,1,189,189,189,1,255,255,255, + 3,251,251,251,1,58,58,58,1,64,64,64,1,253,253,253,1,255,255,255, + 1,208,208,208,1,175,175,175,1,163,163,163,1,255,255,255,7,250,250,250, + 1,195,195,195,1,227,227,227,1,206,206,206,1,245,245,245,1,255,255,255, + 4,192,192,192,1,0,0,0,2,228,228,228,1,255,255,255,2,189,189,189, + 1,138,138,138,1,255,255,255,15,252,252,252,1,98,98,98,1,0,0,0, + 2,119,119,119,1,247,247,247,1,255,255,255,1,229,229,229,1,72,72,72, + 1,252,252,252,1,255,255,255,14,175,175,175,1,1,1,1,1,0,0,0, + 2,4,4,4,1,239,239,239,1,255,255,255,2,112,112,112,1,224,224,224, + 1,255,255,255,13,208,208,208,1,18,18,18,1,0,0,0,4,80,80,80, + 1,182,182,182,1,255,255,255,1,204,204,204,1,130,130,130,1,248,248,248, + 1,255,255,255,11,200,200,200,1,35,35,35,1,0,0,0,6,3,3,3, + 1,127,127,127,1,227,227,227,1,167,167,167,1,138,138,138,1,250,250,250, + 1,255,255,255,8,243,243,243,1,158,158,158,1,10,10,10,1,0,0,0, + 9,25,25,25,1,133,133,133,1,18,18,18,1,125,125,125,1,230,230,230, + 1,255,255,255,5,239,239,239,1,178,178,178,1,67,67,67,1,0,0,0, + 15,22,22,22,1,104,104,104,1,134,134,134,1,146,146,146,1,131,131,131, + 1,105,105,105,1,29,29,29,1,0,0,0,8,0,0) + ); + +const + objdata_tdatasource: record size: integer; data: array[0..911] of byte end = + (size: 912; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,97, + 116,97,115,111,117,114,99,101,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,96,3,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,44,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0, + 255,49,137,134,136,1,130,127,129,1,129,126,128,1,137,134,136,1,130,127, + 129,1,137,134,136,1,131,128,130,1,136,133,135,1,139,136,138,1,136,133, + 135,1,135,130,132,1,130,129,131,1,131,136,139,1,126,131,134,1,135,130, + 132,1,255,0,255,9,134,131,133,1,202,199,201,1,205,202,204,1,192,189, + 191,1,198,195,197,2,189,186,188,1,193,190,192,1,194,191,193,2,195,192, + 194,1,198,197,199,1,192,193,197,1,189,191,192,1,129,124,126,1,255,0, + 255,9,126,123,125,1,136,133,135,1,128,127,129,1,135,134,136,2,126,125, + 127,1,134,133,135,1,139,138,140,1,137,136,138,1,134,133,135,1,128,127, + 129,1,130,129,131,1,137,134,136,1,136,133,135,1,139,134,136,1,255,0, + 255,9,135,132,134,1,247,244,246,1,255,254,255,2,242,241,243,1,214,213, + 215,1,250,249,251,1,251,250,252,1,253,252,254,1,255,254,255,1,254,253, + 255,1,255,254,255,1,255,252,254,1,255,254,255,1,133,127,128,1,255,0, + 255,4,31,31,224,1,255,0,255,4,133,130,132,1,255,254,255,1,208,207, + 209,1,185,184,186,1,255,254,255,1,199,198,200,1,236,238,239,1,205,207, + 208,1,191,193,194,1,193,195,196,1,192,194,195,1,197,196,198,1,199,197, + 197,1,255,250,251,1,142,136,137,1,255,0,255,4,31,31,224,2,255,0, + 255,3,134,131,133,1,255,253,255,1,252,251,253,1,255,254,255,1,252,251, + 253,1,190,189,191,1,253,255,255,1,250,252,253,2,253,255,255,2,252,251, + 253,1,255,255,255,1,254,252,252,1,141,136,135,1,255,0,255,1,31,31, + 224,6,255,0,255,2,132,129,131,1,253,250,252,1,205,204,206,1,192,191, + 193,1,255,254,255,1,190,189,191,1,255,254,255,1,195,194,196,2,196,195, + 197,1,197,196,198,1,195,194,196,1,255,255,255,2,129,125,124,1,255,0, + 255,4,31,31,224,2,255,0,255,3,132,129,131,1,255,254,255,1,243,242, + 244,1,255,254,255,2,195,194,196,1,242,241,243,1,255,254,255,3,255,253, + 255,1,255,254,255,1,244,244,244,1,255,255,255,1,138,136,136,1,255,0, + 255,4,31,31,224,1,255,0,255,4,135,132,134,1,255,252,254,1,213,210, + 212,1,191,188,190,1,249,246,248,1,204,201,203,1,255,254,255,1,191,188, + 190,1,201,196,198,1,194,191,193,1,191,186,188,1,202,199,201,2,255,255, + 255,1,126,124,124,1,255,0,255,9,140,137,139,1,248,245,247,1,255,252, + 254,1,255,254,255,2,193,188,190,1,255,254,255,1,255,253,255,1,255,252, + 255,1,255,253,255,1,255,249,252,1,255,254,255,1,255,253,255,1,255,254, + 255,1,131,128,130,1,255,0,255,9,129,126,128,1,137,134,136,1,134,129, + 131,1,142,137,139,1,135,130,132,1,141,134,137,1,132,125,128,1,137,128, + 131,2,131,122,125,1,134,125,128,1,137,128,131,1,139,133,138,1,131,126, + 128,1,131,124,127,1,255,0,255,41,31,31,224,1,255,0,255,6,31,31, + 224,1,255,0,255,16,31,31,224,1,255,0,255,7,31,31,224,1,255,0, + 255,15,31,31,224,1,255,0,255,8,31,31,224,1,255,0,255,2,31,31, + 224,1,255,0,255,11,31,31,224,1,255,0,255,9,31,31,224,3,255,0, + 255,11,31,31,224,1,255,0,255,9,31,31,224,3,255,0,255,9,31,31, + 224,5,255,0,255,6,31,31,224,4,255,0,255,10,31,31,224,3,255,0, + 255,22,31,31,224,1,255,0,255,62,0,0) + ); + +const + objdata_tdbnavigator: record size: integer; data: array[0..460] of byte end = + (size: 461; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,100,98, + 110,97,118,105,103,97,116,111,114,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,156,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,104,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 0,255,192,255,255,255,23,128,128,128,1,255,255,255,1,255,0,255,22,128, + 128,128,1,255,255,255,1,255,0,255,22,128,128,128,1,255,255,255,1,0, + 0,0,1,255,0,255,2,0,0,0,1,255,0,255,3,0,0,0,1,255, + 0,255,1,0,0,0,1,255,0,255,3,0,0,0,1,255,0,255,2,0, + 0,0,1,255,0,255,5,128,128,128,1,255,255,255,1,0,0,0,1,255, + 0,255,1,0,0,0,2,255,0,255,2,0,0,0,2,255,0,255,1,0, + 0,0,2,255,0,255,2,0,0,0,2,255,0,255,1,0,0,0,1,255, + 0,255,2,0,0,0,1,255,0,255,2,128,128,128,1,255,255,255,1,0, + 0,0,4,255,0,255,1,0,0,0,3,255,0,255,1,0,0,0,3,255, + 0,255,1,0,0,0,4,255,0,255,1,0,0,0,3,255,0,255,1,128, + 128,128,1,255,255,255,1,0,0,0,1,255,0,255,1,0,0,0,2,255, + 0,255,2,0,0,0,2,255,0,255,1,0,0,0,2,255,0,255,2,0, + 0,0,2,255,0,255,1,0,0,0,1,255,0,255,2,0,0,0,1,255, + 0,255,2,128,128,128,1,255,255,255,1,0,0,0,1,255,0,255,2,0, + 0,0,1,255,0,255,3,0,0,0,1,255,0,255,1,0,0,0,1,255, + 0,255,3,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,5,128, + 128,128,1,255,255,255,1,255,0,255,22,128,128,128,1,255,255,255,1,255, + 0,255,22,128,128,128,1,255,255,255,1,128,128,128,23,255,0,255,120,0, + 0) + ); + +const + objdata_tdbstringedit: record size: integer; data: array[0..824] of byte end = + (size: 825; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 115,116,114,105,110,103,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,192,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,120,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,17, + 23,23,1,184,255,255,9,0,0,0,1,184,255,255,1,0,0,0,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,17, + 23,23,1,184,255,255,10,0,0,0,1,184,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,133,184,184,1,42, + 58,58,1,43,60,60,1,34,47,47,1,154,213,213,1,184,255,255,1,14, + 20,20,1,61,84,84,1,42,58,58,1,44,61,61,1,154,213,213,1,150, + 208,208,1,42,58,58,1,44,61,61,1,55,76,76,1,175,242,242,1,184, + 255,255,1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,105,145,145,1,165,229,229,1,184, + 255,255,1,97,134,134,1,95,132,132,1,184,255,255,1,8,11,11,1,136, + 189,189,1,184,255,255,1,141,196,196,1,42,58,58,2,146,203,203,1,184, + 255,255,1,118,164,164,1,143,198,198,1,184,255,255,1,0,0,0,1,184, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,123,171,171,1,60,83,83,1,69,96,96,1,50,69,69,1,92, + 127,127,1,184,255,255,1,12,16,16,1,184,255,255,2,183,254,254,1,15, + 21,21,1,17,23,23,1,184,255,255,5,0,0,0,1,184,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,13, + 18,18,1,176,244,244,1,184,255,255,1,75,104,104,1,92,127,127,1,184, + 255,255,1,8,11,11,1,145,201,201,1,184,255,255,1,137,190,190,1,47, + 65,65,1,38,53,53,1,152,211,211,1,184,255,255,1,106,147,147,1,118, + 164,164,1,184,255,255,1,0,0,0,1,184,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,82,113,113,1,34, + 47,47,1,53,74,74,1,80,111,111,1,74,103,103,1,184,255,255,1,23, + 32,32,1,58,81,81,1,43,60,60,1,48,66,66,1,159,220,220,1,147, + 204,204,1,40,55,55,1,43,60,60,1,58,80,80,1,176,244,244,1,184, + 255,255,1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,17,0,0,0,1,184,255,255,1,0, + 0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_tdropdownlisteditdb: record size: integer; data: array[0..1402] of byte end = + (size: 1403; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,114, + 111,112,100,111,119,110,108,105,115,116,101,100,105,116,100,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,252,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,184,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,255,255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255, + 2,0,0,0,1,1,1,1,1,75,75,75,1,255,255,255,4,0,0,0, + 1,231,231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,255,255,255, + 2,88,88,88,1,75,75,75,1,89,89,89,1,255,255,255,2,0,0,0, + 1,234,234,234,1,70,70,70,1,255,255,255,5,0,0,0,1,255,255,255, + 2,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255, + 1,251,251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251, + 1,255,255,255,1,0,0,0,2,117,117,117,1,255,255,255,5,0,0,0, + 1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128, + 1,255,255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255, + 1,0,0,0,1,243,243,243,1,11,11,11,1,255,255,255,5,0,0,0, + 1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,255,255,255,1,128,128,128,1,255,255,255,1,114,114,114,1,141,141,141, + 1,255,255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0, + 1,235,235,235,1,19,19,19,1,255,255,255,3,252,252,252,1,231,231,231, + 1,0,0,0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128, + 1,255,255,255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217, + 1,255,255,255,1,217,217,217,1,38,38,38,1,255,255,255,1,0,0,0, + 1,3,3,3,1,124,124,124,1,255,255,255,3,223,223,223,1,0,0,0, + 1,223,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0, + 25,184,255,255,17,255,255,255,5,0,0,0,2,184,255,255,2,119,165,165, + 1,0,0,0,1,119,165,165,1,184,255,255,2,0,0,0,1,1,1,1, + 1,54,75,75,1,184,255,255,1,167,232,232,1,56,77,77,1,6,9,9, + 1,27,38,38,1,146,203,203,1,184,255,255,1,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255, + 2,63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0, + 1,169,234,234,1,51,70,70,1,184,255,255,1,59,82,82,1,85,118,118, + 1,177,245,245,1,120,166,166,1,38,53,53,1,184,255,255,1,255,255,255, + 1,0,0,0,3,128,128,128,1,0,0,0,2,184,255,255,1,181,251,251, + 1,15,21,21,1,159,221,221,1,14,20,20,1,181,251,251,1,184,255,255, + 1,0,0,0,2,84,117,117,1,184,255,255,1,9,12,12,1,174,241,241, + 1,184,255,255,4,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0, + 2,184,255,255,1,138,191,191,1,0,0,0,3,138,191,191,1,184,255,255, + 1,0,0,0,1,175,243,243,1,8,11,11,1,184,255,255,1,10,14,14, + 1,174,241,241,1,184,255,255,1,182,252,252,1,152,210,210,1,184,255,255, + 1,128,128,128,5,0,0,0,2,184,255,255,1,82,114,114,1,102,141,141, + 1,184,255,255,1,102,141,141,1,83,115,115,1,184,255,255,1,0,0,0, + 1,170,235,235,1,14,19,19,1,184,255,255,1,60,83,83,1,89,124,124, + 1,177,245,245,1,105,145,145,1,41,57,57,1,184,255,255,1,255,255,255, + 1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0, + 2,184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157,217,217, + 1,27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89,124,124, + 1,184,255,255,1,164,227,227,1,45,63,63,1,5,7,7,1,31,43,43, + 1,154,213,213,1,184,255,255,1,255,255,255,4,128,128,128,1,0,0,0, + 2,184,255,255,17,255,255,255,1,128,128,128,4,0,0,0,2,184,255,255, + 2,0,0,0,2,4,5,5,1,126,174,174,1,184,255,255,11,208,208,208, + 1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0, + 2,184,255,255,2,0,0,0,1,184,255,255,1,126,174,174,1,4,5,5, + 1,184,255,255,1,110,152,152,1,8,11,11,1,115,159,159,1,184,255,255, + 7,255,255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,184,255,255, + 2,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1,21,29,29, + 1,142,197,197,1,27,37,37,1,184,255,255,7,255,255,255,1,208,208,208, + 3,128,128,128,1,0,0,0,2,184,255,255,2,0,0,0,1,184,255,255, + 2,0,0,0,1,184,255,255,1,1,2,2,1,0,0,0,1,2,3,3, + 1,184,255,255,7,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0, + 2,184,255,255,2,0,0,0,1,184,255,255,1,126,174,174,1,4,5,5, + 1,184,255,255,1,18,25,25,1,163,226,226,1,184,255,255,8,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,184,255,255,2,0,0,0,2,4,5,5,1,126,174,174,1,184,255,255, + 1,105,146,146,1,6,9,9,1,71,98,98,1,184,255,255,7,128,128,128, + 5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 66,0,0) + ); + +const + objdata_tdropdownlisteditlb: record size: integer; data: array[0..1402] of byte end = + (size: 1403; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,114, + 111,112,100,111,119,110,108,105,115,116,101,100,105,116,108,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,252,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,184,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,255,255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255, + 2,0,0,0,1,1,1,1,1,75,75,75,1,255,255,255,4,0,0,0, + 1,231,231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,255,255,255, + 2,88,88,88,1,75,75,75,1,89,89,89,1,255,255,255,2,0,0,0, + 1,234,234,234,1,70,70,70,1,255,255,255,5,0,0,0,1,255,255,255, + 2,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255, + 1,251,251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251, + 1,255,255,255,1,0,0,0,2,117,117,117,1,255,255,255,5,0,0,0, + 1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128, + 1,255,255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255, + 1,0,0,0,1,243,243,243,1,11,11,11,1,255,255,255,5,0,0,0, + 1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,255,255,255,1,128,128,128,1,255,255,255,1,114,114,114,1,141,141,141, + 1,255,255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0, + 1,235,235,235,1,19,19,19,1,255,255,255,3,252,252,252,1,231,231,231, + 1,0,0,0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128, + 1,255,255,255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217, + 1,255,255,255,1,217,217,217,1,38,38,38,1,255,255,255,1,0,0,0, + 1,3,3,3,1,124,124,124,1,255,255,255,3,223,223,223,1,0,0,0, + 1,223,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0, + 25,201,201,255,17,255,255,255,5,0,0,0,2,201,201,255,2,130,130,165, + 1,0,0,0,1,130,130,165,1,201,201,255,2,0,0,0,1,1,1,1, + 1,59,59,75,1,201,201,255,1,183,183,232,1,61,61,77,1,7,7,9, + 1,30,30,38,1,160,160,203,1,201,201,255,1,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201,255, + 2,69,69,88,1,59,59,75,1,70,70,89,1,201,201,255,2,0,0,0, + 1,184,184,234,1,55,55,70,1,201,201,255,1,65,65,82,1,93,93,118, + 1,193,193,245,1,131,131,166,1,42,42,53,1,201,201,255,1,255,255,255, + 1,0,0,0,3,128,128,128,1,0,0,0,2,201,201,255,1,198,198,251, + 1,17,17,21,1,174,174,221,1,16,16,20,1,198,198,251,1,201,201,255, + 1,0,0,0,2,92,92,117,1,201,201,255,1,9,9,12,1,190,190,241, + 1,201,201,255,4,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0, + 2,201,201,255,1,151,151,191,1,0,0,0,3,151,151,191,1,201,201,255, + 1,0,0,0,1,192,192,243,1,9,9,11,1,201,201,255,1,11,11,14, + 1,190,190,241,1,201,201,255,1,199,199,252,1,166,166,210,1,201,201,255, + 1,128,128,128,5,0,0,0,2,201,201,255,1,90,90,114,1,111,111,141, + 1,201,201,255,1,111,111,141,1,91,91,115,1,201,201,255,1,0,0,0, + 1,185,185,235,1,15,15,19,1,201,201,255,1,65,65,83,1,98,98,124, + 1,193,193,245,1,114,114,145,1,45,45,57,1,201,201,255,1,255,255,255, + 1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0, + 2,201,201,255,1,29,29,37,1,171,171,217,1,201,201,255,1,171,171,217, + 1,30,30,38,1,201,201,255,1,0,0,0,1,2,2,3,1,98,98,124, + 1,201,201,255,1,179,179,227,1,50,50,63,1,6,6,7,1,34,34,43, + 1,168,168,213,1,201,201,255,1,255,255,255,4,128,128,128,1,0,0,0, + 2,201,201,255,17,255,255,255,1,128,128,128,4,0,0,0,2,201,201,255, + 2,0,0,0,2,4,4,5,1,137,137,174,1,201,201,255,11,208,208,208, + 1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0, + 2,201,201,255,2,0,0,0,1,201,201,255,1,137,137,174,1,4,4,5, + 1,201,201,255,1,120,120,152,1,9,9,11,1,125,125,159,1,201,201,255, + 7,255,255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,201,201,255, + 2,0,0,0,1,201,201,255,2,0,0,0,1,201,201,255,1,23,23,29, + 1,155,155,197,1,29,29,37,1,201,201,255,7,255,255,255,1,208,208,208, + 3,128,128,128,1,0,0,0,2,201,201,255,2,0,0,0,1,201,201,255, + 2,0,0,0,1,201,201,255,1,2,2,2,1,0,0,0,1,2,2,3, + 1,201,201,255,7,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0, + 2,201,201,255,2,0,0,0,1,201,201,255,1,137,137,174,1,4,4,5, + 1,201,201,255,1,20,20,25,1,178,178,226,1,201,201,255,8,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,201,201,255,2,0,0,0,2,4,4,5,1,137,137,174,1,201,201,255, + 1,115,115,146,1,7,7,9,1,77,77,98,1,201,201,255,7,128,128,128, + 5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 66,0,0) + ); + +const + objdata_tdbdropdownlistedit: record size: integer; data: array[0..1370] of byte end = + (size: 1371; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,220,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,152,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,184,255,255,2,119,165,165,1,0,0,0,1,119,165,165,1,184,255,255, + 2,0,0,0,1,1,1,1,1,54,75,75,1,184,255,255,4,0,0,0, + 1,167,231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,184,255,255, + 2,63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0, + 1,169,234,234,1,51,70,70,1,184,255,255,5,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,181,251,251,1,15,21,21,1,159,221,221,1,14,20,20, + 1,181,251,251,1,184,255,255,1,0,0,0,2,84,117,117,1,184,255,255, + 5,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,1,138,191,191,1,0,0,0, + 3,138,191,191,1,184,255,255,1,0,0,0,1,175,243,243,1,8,11,11, + 1,184,255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102,141,141, + 1,83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14,19,19, + 1,184,255,255,3,182,252,252,1,167,231,231,1,0,0,0,1,178,247,247, + 1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157,217,217, + 1,27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89,124,124, + 1,184,255,255,3,161,223,223,1,0,0,0,1,161,223,223,1,0,0,0, + 1,128,128,128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0, + 2,255,255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255, + 2,0,0,0,1,1,1,1,1,75,75,75,1,255,255,255,1,232,232,232, + 1,77,77,77,1,9,9,9,1,38,38,38,1,203,203,203,1,255,255,255, + 2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,255,255,255,2,88,88,88,1,75,75,75,1,89,89,89,1,255,255,255, + 2,0,0,0,1,234,234,234,1,70,70,70,1,255,255,255,1,82,82,82, + 1,118,118,118,1,245,245,245,1,166,166,166,1,53,53,53,1,255,255,255, + 2,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,1,251,251,251, + 1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255,255,255, + 1,0,0,0,2,117,117,117,1,255,255,255,1,12,12,12,1,241,241,241, + 1,255,255,255,5,208,208,208,3,128,128,128,1,0,0,0,2,255,255,255, + 1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,1,0,0,0, + 1,243,243,243,1,11,11,11,1,255,255,255,1,14,14,14,1,241,241,241, + 1,255,255,255,1,252,252,252,1,210,210,210,1,255,255,255,1,128,128,128, + 5,0,0,0,2,255,255,255,1,114,114,114,1,141,141,141,1,255,255,255, + 1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,1,235,235,235, + 1,19,19,19,1,255,255,255,1,83,83,83,1,124,124,124,1,245,245,245, + 1,145,145,145,1,57,57,57,1,255,255,255,2,212,212,212,1,252,252,252, + 1,208,208,208,1,255,255,255,1,0,0,0,2,255,255,255,1,37,37,37, + 1,217,217,217,1,255,255,255,1,217,217,217,1,38,38,38,1,255,255,255, + 1,0,0,0,1,3,3,3,1,124,124,124,1,255,255,255,1,227,227,227, + 1,63,63,63,1,7,7,7,1,43,43,43,1,213,213,213,1,255,255,255, + 5,128,128,128,1,0,0,0,2,255,255,255,18,128,128,128,4,0,0,0, + 2,255,255,255,2,0,0,0,2,5,5,5,1,174,174,174,1,255,255,255, + 11,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208, + 1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,1,174,174,174, + 1,5,5,5,1,255,255,255,1,152,152,152,1,11,11,11,1,159,159,159, + 1,255,255,255,9,252,252,252,1,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,29,29,29, + 1,197,197,197,1,37,37,37,1,255,255,255,8,208,208,208,3,128,128,128, + 1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,1,2,2,2,1,0,0,0,1,3,3,3,1,255,255,255, + 8,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0, + 1,255,255,255,1,174,174,174,1,5,5,5,1,255,255,255,1,25,25,25, + 1,226,226,226,1,255,255,255,9,208,208,208,1,0,0,0,1,208,208,208, + 1,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,2,5,5,5, + 1,174,174,174,1,255,255,255,1,146,146,146,1,9,9,9,1,98,98,98, + 1,255,255,255,7,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbdropdownlisteditdb: record size: integer; data: array[0..1416] of byte end = + (size: 1417; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,100,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,8,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,196,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,184,255,255,2,119,165,165,1,0,0,0,1,119,165,165,1,184, + 255,255,2,0,0,0,1,1,1,1,1,54,75,75,1,184,255,255,4,0, + 0,0,1,167,231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,184, + 255,255,2,63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0, + 0,0,1,169,234,234,1,51,70,70,1,184,255,255,5,0,0,0,1,184, + 255,255,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,181,251,251,1,15,21,21,1,159,221,221,1,14, + 20,20,1,181,251,251,1,184,255,255,1,0,0,0,2,84,117,117,1,184, + 255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,1,138,191,191,1,0, + 0,0,3,138,191,191,1,184,255,255,1,0,0,0,1,175,243,243,1,8, + 11,11,1,184,255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102, + 141,141,1,83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14, + 19,19,1,184,255,255,3,182,252,252,1,167,231,231,1,0,0,0,1,178, + 247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157, + 217,217,1,27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89, + 124,124,1,184,255,255,3,161,223,223,1,0,0,0,1,161,223,223,1,0, + 0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,184,255,255,17,255, + 255,255,5,0,0,0,2,184,255,255,2,119,165,165,1,0,0,0,1,119, + 165,165,1,184,255,255,2,0,0,0,1,1,1,1,1,54,75,75,1,184, + 255,255,1,167,232,232,1,56,77,77,1,6,9,9,1,27,38,38,1,146, + 203,203,1,184,255,255,1,255,255,255,1,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,0,0,0,2,184,255,255,2,63,88,88,1,54, + 75,75,1,64,89,89,1,184,255,255,2,0,0,0,1,169,234,234,1,51, + 70,70,1,184,255,255,1,59,82,82,1,85,118,118,1,177,245,245,1,120, + 166,166,1,38,53,53,1,184,255,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,0,0,0,2,184,255,255,1,181,251,251,1,15,21,21,1,159, + 221,221,1,14,20,20,1,181,251,251,1,184,255,255,1,0,0,0,2,84, + 117,117,1,184,255,255,1,9,12,12,1,174,241,241,1,184,255,255,4,255, + 255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,184,255,255,1,138, + 191,191,1,0,0,0,3,138,191,191,1,184,255,255,1,0,0,0,1,175, + 243,243,1,8,11,11,1,184,255,255,1,10,14,14,1,174,241,241,1,184, + 255,255,1,182,252,252,1,152,210,210,1,184,255,255,1,128,128,128,5,0, + 0,0,2,184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102, + 141,141,1,83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14, + 19,19,1,184,255,255,1,60,83,83,1,89,124,124,1,177,245,245,1,105, + 145,145,1,41,57,57,1,184,255,255,1,255,255,255,1,212,212,212,1,252, + 252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,184,255,255,1,27, + 37,37,1,157,217,217,1,184,255,255,1,157,217,217,1,27,38,38,1,184, + 255,255,1,0,0,0,1,2,3,3,1,89,124,124,1,184,255,255,1,164, + 227,227,1,45,63,63,1,5,7,7,1,31,43,43,1,154,213,213,1,184, + 255,255,1,255,255,255,4,128,128,128,1,0,0,0,2,184,255,255,17,255, + 255,255,1,128,128,128,4,0,0,0,2,184,255,255,2,0,0,0,2,4, + 5,5,1,126,174,174,1,184,255,255,11,208,208,208,1,255,255,255,1,211, + 211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,184,255,255,2,0, + 0,0,1,184,255,255,1,126,174,174,1,4,5,5,1,184,255,255,1,110, + 152,152,1,8,11,11,1,115,159,159,1,184,255,255,7,255,255,255,2,252, + 252,252,1,255,255,255,2,0,0,0,2,184,255,255,2,0,0,0,1,184, + 255,255,2,0,0,0,1,184,255,255,1,21,29,29,1,142,197,197,1,27, + 37,37,1,184,255,255,7,255,255,255,1,208,208,208,3,128,128,128,1,0, + 0,0,2,184,255,255,2,0,0,0,1,184,255,255,2,0,0,0,1,184, + 255,255,1,1,2,2,1,0,0,0,1,2,3,3,1,184,255,255,7,255, + 255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,184,255,255,2,0, + 0,0,1,184,255,255,1,126,174,174,1,4,5,5,1,184,255,255,1,18, + 25,25,1,163,226,226,1,184,255,255,8,255,255,255,1,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255,2,0, + 0,0,2,4,5,5,1,126,174,174,1,184,255,255,1,105,146,146,1,6, + 9,9,1,71,98,98,1,184,255,255,7,128,128,128,5,0,0,0,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbdropdownlisteditlb: record size: integer; data: array[0..1416] of byte end = + (size: 1417; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,108,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,8,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,196,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,184,255,255,2,119,165,165,1,0,0,0,1,119,165,165,1,184, + 255,255,2,0,0,0,1,1,1,1,1,54,75,75,1,184,255,255,4,0, + 0,0,1,167,231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,184, + 255,255,2,63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0, + 0,0,1,169,234,234,1,51,70,70,1,184,255,255,5,0,0,0,1,184, + 255,255,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,181,251,251,1,15,21,21,1,159,221,221,1,14, + 20,20,1,181,251,251,1,184,255,255,1,0,0,0,2,84,117,117,1,184, + 255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,1,138,191,191,1,0, + 0,0,3,138,191,191,1,184,255,255,1,0,0,0,1,175,243,243,1,8, + 11,11,1,184,255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102, + 141,141,1,83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14, + 19,19,1,184,255,255,3,182,252,252,1,167,231,231,1,0,0,0,1,178, + 247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157, + 217,217,1,27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89, + 124,124,1,184,255,255,3,161,223,223,1,0,0,0,1,161,223,223,1,0, + 0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,201,201,255,17,255, + 255,255,5,0,0,0,2,201,201,255,2,130,130,165,1,0,0,0,1,130, + 130,165,1,201,201,255,2,0,0,0,1,1,1,1,1,59,59,75,1,201, + 201,255,1,183,183,232,1,61,61,77,1,7,7,9,1,30,30,38,1,160, + 160,203,1,201,201,255,1,255,255,255,1,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,0,0,0,2,201,201,255,2,69,69,88,1,59, + 59,75,1,70,70,89,1,201,201,255,2,0,0,0,1,184,184,234,1,55, + 55,70,1,201,201,255,1,65,65,82,1,93,93,118,1,193,193,245,1,131, + 131,166,1,42,42,53,1,201,201,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,0,0,0,2,201,201,255,1,198,198,251,1,17,17,21,1,174, + 174,221,1,16,16,20,1,198,198,251,1,201,201,255,1,0,0,0,2,92, + 92,117,1,201,201,255,1,9,9,12,1,190,190,241,1,201,201,255,4,255, + 255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,201,201,255,1,151, + 151,191,1,0,0,0,3,151,151,191,1,201,201,255,1,0,0,0,1,192, + 192,243,1,9,9,11,1,201,201,255,1,11,11,14,1,190,190,241,1,201, + 201,255,1,199,199,252,1,166,166,210,1,201,201,255,1,128,128,128,5,0, + 0,0,2,201,201,255,1,90,90,114,1,111,111,141,1,201,201,255,1,111, + 111,141,1,91,91,115,1,201,201,255,1,0,0,0,1,185,185,235,1,15, + 15,19,1,201,201,255,1,65,65,83,1,98,98,124,1,193,193,245,1,114, + 114,145,1,45,45,57,1,201,201,255,1,255,255,255,1,212,212,212,1,252, + 252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,201,201,255,1,29, + 29,37,1,171,171,217,1,201,201,255,1,171,171,217,1,30,30,38,1,201, + 201,255,1,0,0,0,1,2,2,3,1,98,98,124,1,201,201,255,1,179, + 179,227,1,50,50,63,1,6,6,7,1,34,34,43,1,168,168,213,1,201, + 201,255,1,255,255,255,4,128,128,128,1,0,0,0,2,201,201,255,17,255, + 255,255,1,128,128,128,4,0,0,0,2,201,201,255,2,0,0,0,2,4, + 4,5,1,137,137,174,1,201,201,255,11,208,208,208,1,255,255,255,1,211, + 211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,201,201,255,2,0, + 0,0,1,201,201,255,1,137,137,174,1,4,4,5,1,201,201,255,1,120, + 120,152,1,9,9,11,1,125,125,159,1,201,201,255,7,255,255,255,2,252, + 252,252,1,255,255,255,2,0,0,0,2,201,201,255,2,0,0,0,1,201, + 201,255,2,0,0,0,1,201,201,255,1,23,23,29,1,155,155,197,1,29, + 29,37,1,201,201,255,7,255,255,255,1,208,208,208,3,128,128,128,1,0, + 0,0,2,201,201,255,2,0,0,0,1,201,201,255,2,0,0,0,1,201, + 201,255,1,2,2,2,1,0,0,0,1,2,2,3,1,201,201,255,7,255, + 255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,201,201,255,2,0, + 0,0,1,201,201,255,1,137,137,174,1,4,4,5,1,201,201,255,1,20, + 20,25,1,178,178,226,1,201,201,255,8,255,255,255,1,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201,255,2,0, + 0,0,2,4,4,5,1,137,137,174,1,201,201,255,1,115,115,146,1,7, + 7,9,1,77,77,98,1,201,201,255,7,128,128,128,5,0,0,0,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbbooleantextedit: record size: integer; data: array[0..1157] of byte end = + (size: 1158; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 98,111,111,108,101,97,110,116,101,120,116,101,100,105,116,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 8,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 196,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 184,255,255,14,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255,6, + 128,128,128,1,184,255,255,15,0,0,0,1,184,255,255,1,255,255,255,1, + 208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255,15, + 0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128,1, + 255,255,255,1,128,128,128,1,184,255,255,15,0,0,0,1,184,255,255,1, + 255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1, + 255,255,255,1,128,128,128,1,184,255,255,13,182,252,252,1,167,231,231,1, + 0,0,0,1,178,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1, + 255,255,255,1,128,128,128,1,184,255,255,13,161,223,223,1,0,0,0,1, + 161,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25, + 255,255,255,22,0,0,0,7,255,255,255,13,208,208,208,1,0,0,0,1, + 208,208,208,1,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,1, + 255,255,255,3,0,0,0,1,71,71,71,1,255,255,255,1,0,0,0,2, + 255,255,255,1,152,152,152,1,11,11,11,1,159,159,159,1,255,255,255,3, + 0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,1, + 255,255,255,3,0,0,0,1,213,213,213,1,255,255,255,1,0,0,0,2, + 255,255,255,1,29,29,29,1,197,197,197,1,37,37,37,1,255,255,255,3, + 208,208,208,3,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,1, + 255,255,255,3,0,0,0,1,254,254,254,1,255,255,255,1,0,0,0,2, + 255,255,255,1,2,2,2,1,0,0,0,1,3,3,3,1,255,255,255,2, + 128,128,128,5,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,3, + 0,0,0,1,255,255,255,2,5,5,5,1,0,0,0,1,255,255,255,1, + 25,25,25,1,226,226,226,1,255,255,255,4,212,212,212,1,252,252,252,1, + 208,208,208,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,1, + 255,255,255,3,0,0,0,1,255,255,255,2,215,215,215,1,5,5,5,1, + 255,255,255,1,146,146,146,1,9,9,9,1,98,98,98,1,255,255,255,6, + 128,128,128,1,0,0,0,2,255,255,255,18,128,128,128,4,0,0,0,2, + 255,255,255,1,0,0,0,3,255,255,255,6,0,0,0,1,255,255,255,6, + 208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1, + 0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,108,108,108,1, + 14,14,14,1,7,7,7,1,88,88,88,1,255,255,255,1,0,0,0,1, + 174,174,174,1,5,5,5,1,80,80,80,1,255,255,255,1,152,152,152,1, + 11,11,11,1,159,159,159,1,255,255,255,1,252,252,252,1,255,255,255,2, + 0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,3,220,220,220,1, + 1,1,1,1,255,255,255,1,0,0,0,1,39,39,39,1,55,55,55,1, + 255,255,255,2,29,29,29,1,197,197,197,1,37,37,37,1,208,208,208,3, + 128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3, + 177,177,177,1,76,76,76,1,31,31,31,1,0,0,0,1,255,255,255,1, + 0,0,0,1,218,218,218,1,30,30,30,1,195,195,195,1,255,255,255,1, + 2,2,2,1,0,0,0,1,3,3,3,1,0,0,0,3,128,128,128,1, + 0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,13,13,13,1, + 175,175,175,1,158,158,158,1,0,0,0,1,255,255,255,1,0,0,0,1, + 25,25,25,1,51,51,51,1,19,19,19,1,255,255,255,1,25,25,25,1, + 226,226,226,1,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1, + 128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3, + 94,94,94,1,8,8,8,1,112,112,112,1,0,0,0,1,255,255,255,1, + 0,0,0,1,140,140,140,1,10,10,10,1,174,174,174,1,255,255,255,1, + 146,146,146,1,9,9,9,1,49,49,49,1,128,128,128,4,0,0,0,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbmemoedit: record size: integer; data: array[0..1354] of byte end = + (size: 1355; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,98, + 109,101,109,111,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,212,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,136,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,20,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,20,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,2,8,11,11,1,66,91,91, + 1,184,255,255,3,90,125,125,1,8,11,11,1,184,255,255,11,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,16,22,22, + 1,31,43,43,1,178,246,246,1,184,255,255,2,42,58,58,1,15,21,21, + 1,184,255,255,11,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,17,23,23,1,86,119,119,1,123,170,170,1,184,255,255, + 1,141,196,196,1,82,113,113,1,17,23,23,1,184,255,255,1,157,217,217, + 1,46,64,64,1,42,58,58,1,40,56,56,1,147,204,204,1,184,255,255, + 5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 2,17,23,23,1,151,209,209,1,59,82,82,1,184,255,255,1,75,104,104, + 1,148,205,205,1,17,23,23,1,184,255,255,1,44,61,61,1,141,195,195, + 1,184,255,255,1,153,212,212,1,30,42,42,1,184,255,255,5,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,17,23,23, + 1,184,255,255,1,38,52,52,1,170,235,235,1,43,60,60,1,184,255,255, + 1,17,23,23,1,184,255,255,1,13,18,18,1,45,63,63,3,24,33,33, + 1,180,249,249,1,184,255,255,4,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,2,17,23,23,1,184,255,255,1,97,135,135, + 1,61,85,85,1,96,133,133,1,184,255,255,1,17,23,23,1,184,255,255, + 1,41,57,57,1,154,214,214,1,184,255,255,1,167,231,231,1,95,132,132, + 1,184,255,255,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,17,23,23,1,184,255,255,1,162,225,225,1,1,2,2, + 1,162,224,224,1,184,255,255,1,17,23,23,1,184,255,255,1,153,212,212, + 1,46,64,64,1,44,61,61,1,38,53,53,1,128,177,177,1,184,255,255, + 5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 2,8,11,11,1,66,91,91,1,184,255,255,3,90,125,125,1,8,11,11, + 1,184,255,255,7,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 2,16,22,22,1,31,43,43,1,178,246,246,1,184,255,255,2,42,58,58, + 1,15,21,21,1,184,255,255,8,0,0,0,1,184,255,255,2,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,17,23,23, + 1,86,119,119,1,123,170,170,1,184,255,255,1,141,196,196,1,82,113,113, + 1,17,23,23,1,184,255,255,1,152,210,210,1,42,58,58,1,41,57,57, + 1,42,58,58,1,152,210,210,1,184,255,255,2,0,0,0,1,184,255,255, + 2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 2,17,23,23,1,151,209,209,1,59,82,82,1,184,255,255,1,75,104,104, + 1,148,205,205,1,17,23,23,1,184,255,255,1,40,56,56,1,141,196,196, + 1,184,255,255,1,140,194,194,1,40,55,55,1,184,255,255,2,0,0,0, + 1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,17,23,23,1,184,255,255,1,38,52,52,1,170,235,235, + 1,43,60,60,1,184,255,255,1,17,23,23,1,184,255,255,1,14,20,20, + 1,184,255,255,2,183,254,254,1,15,21,21,1,184,255,255,2,0,0,0, + 1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,17,23,23,1,184,255,255,1,97,135,135,1,61,85,85, + 1,96,133,133,1,184,255,255,1,17,23,23,1,184,255,255,1,40,55,55, + 1,142,197,197,1,184,255,255,1,141,195,195,1,40,55,55,1,184,255,255, + 2,0,0,0,1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,2,17,23,23,1,184,255,255,1,162,225,225, + 1,1,2,2,1,162,224,224,1,184,255,255,1,17,23,23,1,184,255,255, + 1,150,208,208,1,41,57,57,1,42,58,58,1,43,59,59,1,151,209,209, + 1,184,255,255,2,0,0,0,1,184,255,255,2,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,16,0,0,0,1,184,255,255, + 1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,20,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,20,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,42,128,128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tdbintegeredit: record size: integer; data: array[0..829] of byte end = + (size: 830; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,98, + 105,110,116,101,103,101,114,101,100,105,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,196,2,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,124,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2, + 180,249,249,1,20,28,28,1,184,255,255,2,128,177,177,1,40,56,56,1, + 32,45,45,1,124,172,172,1,184,255,255,1,135,187,187,1,39,54,54,1, + 33,46,46,1,112,155,155,1,184,255,255,2,0,0,0,1,184,255,255,1, + 0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,144,200,200,1,28,39,39,1,0,0,0,1,184,255,255,2, + 45,62,62,1,180,249,249,1,159,221,221,1,17,24,24,1,184,255,255,1, + 54,75,75,1,175,242,242,1,167,231,231,1,9,13,13,1,184,255,255,3, + 0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,1,182,252,252,1,178,247,247,1,0,0,0,1, + 184,255,255,2,118,163,163,1,184,255,255,1,169,234,234,1,9,12,12,1, + 184,255,255,1,149,207,207,1,183,254,254,1,142,197,197,1,27,37,37,1, + 184,255,255,3,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,3,0,0,0,1,184,255,255,3, + 167,232,232,1,47,65,65,1,91,126,126,1,184,255,255,2,103,143,143,1, + 0,0,0,1,108,150,150,1,184,255,255,3,0,0,0,1,184,255,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 0,0,0,1,184,255,255,2,149,206,206,1,32,44,44,1,119,165,165,1, + 183,254,254,1,184,255,255,1,173,240,240,1,183,254,254,1,144,199,199,1, + 12,16,16,1,184,255,255,3,0,0,0,1,184,255,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,0,0,0,1, + 184,255,255,2,51,70,70,1,163,226,226,1,184,255,255,3,45,63,63,1, + 181,251,251,1,165,228,228,1,14,19,19,1,184,255,255,3,0,0,0,1, + 184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,3,0,0,0,1,184,255,255,1,172,238,238,1,11,15,15,1, + 37,51,51,3,184,255,255,1,115,159,159,1,39,54,54,1,32,45,45,1, + 118,164,164,1,184,255,255,3,0,0,0,1,184,255,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,17,0,0,0,1, + 184,255,255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,20,224,224,224,1,255,255,255,1,128,128,128,1, + 224,224,224,22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255, + 255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbbooleanedit: record size: integer; data: array[0..490] of byte end = + (size: 491; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,98, + 98,111,111,108,101,97,110,101,100,105,116,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,184,1,0,0,0,0,0,0,0,0,0,0,24,0,0, + 0,24,0,0,0,132,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,0,255,125,128,128,128,14,255,0,255,10,128,128,128,1,0,0,0, + 12,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,190,255,255, + 10,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0, + 1,190,255,255,1,0,0,0,2,190,255,255,4,0,0,0,2,190,255,255, + 1,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0, + 1,190,255,255,1,0,0,0,3,190,255,255,2,0,0,0,3,190,255,255, + 1,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0, + 1,190,255,255,2,0,0,0,6,190,255,255,2,192,192,192,1,255,255,255, + 1,255,0,255,10,128,128,128,1,0,0,0,1,190,255,255,3,0,0,0, + 4,190,255,255,3,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128, + 1,0,0,0,1,190,255,255,3,0,0,0,4,190,255,255,3,192,192,192, + 1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,190,255,255, + 2,0,0,0,6,190,255,255,2,192,192,192,1,255,255,255,1,255,0,255, + 10,128,128,128,1,0,0,0,1,190,255,255,1,0,0,0,3,190,255,255, + 2,0,0,0,3,190,255,255,1,192,192,192,1,255,255,255,1,255,0,255, + 10,128,128,128,1,0,0,0,1,190,255,255,1,0,0,0,2,190,255,255, + 4,0,0,0,2,190,255,255,1,192,192,192,1,255,255,255,1,255,0,255, + 10,128,128,128,1,0,0,0,1,190,255,255,10,192,192,192,1,255,255,255, + 1,255,0,255,10,128,128,128,1,192,192,192,12,255,255,255,1,255,0,255, + 10,255,255,255,14,255,0,255,125,0,0) + ); + +const + objdata_tdbdataicon: record size: integer; data: array[0..1322] of byte end = + (size: 1323; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,98, + 100,97,116,97,105,99,111,110,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,180,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,88,3,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171,171,171, + 20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128, + 1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171, + 2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128, + 1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171, + 20,128,128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128,128, + 1,184,255,255,20,128,128,128,1,171,171,171,2,128,128,128,1,184,255,255, + 5,200,244,240,1,223,228,218,1,233,213,198,1,236,201,182,1,240,186,164, + 1,236,180,153,1,227,181,155,1,219,183,159,1,208,197,178,1,193,230,222, + 1,184,255,254,1,184,255,255,4,128,128,128,1,171,171,171,2,128,128,128, + 1,184,255,255,3,202,243,239,1,245,214,198,1,250,200,179,1,246,192,169, + 1,243,184,159,1,239,176,149,1,235,168,139,1,231,160,129,1,227,152,119, + 1,223,144,109,1,219,136,98,1,215,128,88,1,209,137,101,1,190,219,208, + 1,184,255,255,3,128,128,128,1,171,171,171,2,128,128,128,1,184,255,255, + 2,210,238,231,1,249,200,181,1,247,192,170,1,243,184,160,1,239,177,150, + 1,235,168,140,1,231,161,129,1,227,153,119,1,223,145,109,1,220,137,99, + 1,216,129,89,1,212,121,79,1,208,113,69,1,204,105,58,1,199,98,50, + 1,188,194,176,1,184,255,255,2,128,128,128,1,171,171,171,2,128,128,128, + 1,184,255,255,2,236,203,185,1,243,185,160,1,239,177,150,1,235,169,140, + 1,231,161,130,1,228,153,120,1,224,145,110,1,220,137,100,1,216,129,89, + 1,212,121,79,1,208,113,69,1,204,105,59,1,200,97,49,1,197,89,39, + 1,193,82,29,1,188,104,59,1,184,255,255,2,128,128,128,1,171,171,171, + 2,128,128,128,1,184,255,255,2,226,196,176,1,236,169,141,1,232,162,131, + 1,228,154,120,1,224,146,110,1,220,138,100,1,216,130,90,1,212,122,80, + 1,208,114,70,1,205,106,60,1,201,98,50,1,197,90,39,1,193,82,29, + 1,189,74,19,1,185,66,9,1,183,107,62,1,184,255,255,2,128,128,128, + 1,171,171,171,2,128,128,128,1,184,255,255,2,196,231,223,1,225,160,128, + 1,224,146,111,1,220,138,101,1,216,130,91,1,213,122,81,1,209,114,70, + 1,205,106,60,1,201,98,50,1,197,90,40,1,193,82,30,1,189,74,20, + 1,185,67,10,1,182,59,0,1,182,70,14,1,183,205,190,1,184,255,255, + 2,128,128,128,1,171,171,171,2,128,128,128,1,184,255,255,3,188,240,235, + 1,208,166,138,1,213,125,84,1,209,115,71,1,205,107,61,1,201,99,51, + 1,197,91,41,1,193,83,31,1,189,75,20,1,186,67,10,1,182,59,0, + 1,182,62,4,1,183,115,73,1,184,230,222,1,184,255,255,3,128,128,128, + 1,171,171,171,2,128,128,128,1,184,255,255,5,185,244,241,1,191,196,179, + 1,191,162,134,1,191,141,107,1,188,118,76,1,185,111,68,1,183,126,87, + 1,183,144,111,1,184,181,159,1,184,240,236,1,184,255,255,5,128,128,128, + 1,171,171,171,2,128,128,128,1,184,255,255,20,128,128,128,1,171,171,171, + 1,128,128,128,24,171,171,171,1,128,128,128,1,171,171,171,20,128,128,128, + 1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171, + 2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128, + 1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171, + 20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128, + 1,171,171,171,1,36,1,0,0,0,0,0,1,255,255,255,1,0,0,0, + 20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0, + 20,255,255,255,1,0,0,0,1,255,255,255,24,0,0,0,1,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255, + 24,0,0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0, + 20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 1,0,0) + ); + +const + objdata_tdbbooleaneditradio: record size: integer; data: array[0..447] of byte end = + (size: 448; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 98,111,111,108,101,97,110,101,100,105,116,114,97,100,105,111,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,136,1,0,0,0,0,0,0,0,0, + 0,0,24,0,0,0,24,0,0,0,84,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,255,0,255,125,128,128,128,14,255,0,255,10,128,128, + 128,1,0,0,0,12,255,255,255,1,255,0,255,10,128,128,128,1,0,0, + 0,1,190,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10,128,128, + 128,1,0,0,0,1,190,255,255,10,192,192,192,1,255,255,255,1,255,0, + 255,10,128,128,128,1,0,0,0,1,190,255,255,4,0,0,0,2,190,255, + 255,4,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0, + 0,1,190,255,255,3,0,0,0,4,190,255,255,3,192,192,192,1,255,255, + 255,1,255,0,255,10,128,128,128,1,0,0,0,1,190,255,255,2,0,0, + 0,6,190,255,255,2,192,192,192,1,255,255,255,1,255,0,255,10,128,128, + 128,1,0,0,0,1,190,255,255,2,0,0,0,6,190,255,255,2,192,192, + 192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,190,255, + 255,3,0,0,0,4,190,255,255,3,192,192,192,1,255,255,255,1,255,0, + 255,10,128,128,128,1,0,0,0,1,190,255,255,4,0,0,0,2,190,255, + 255,4,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0, + 0,1,190,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10,128,128, + 128,1,0,0,0,1,190,255,255,10,192,192,192,1,255,255,255,1,255,0, + 255,10,128,128,128,1,192,192,192,12,255,255,255,1,255,0,255,10,255,255, + 255,14,255,0,255,125,0,0) + ); + +const + objdata_tdbrealedit: record size: integer; data: array[0..706] of byte end = + (size: 707; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,98, + 114,101,97,108,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,76,2,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,4,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0, + 22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,180,249,249, + 1,20,28,28,1,184,255,255,6,128,177,177,1,40,56,56,1,32,45,45, + 1,124,172,172,1,184,255,255,3,0,0,0,1,184,255,255,1,0,0,0, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,144,200,200,1,28,39,39,1,0,0,0,1,184,255,255,6,45,62,62, + 1,180,249,249,1,159,221,221,1,17,24,24,1,184,255,255,4,0,0,0, + 1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,182,252,252,1,178,247,247,1,0,0,0,1,184,255,255, + 6,118,163,163,1,184,255,255,1,169,234,234,1,9,12,12,1,184,255,255, + 4,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,3,0,0,0,1,184,255,255,7,167,232,232, + 1,47,65,65,1,91,126,126,1,184,255,255,4,0,0,0,1,184,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 3,0,0,0,1,184,255,255,6,149,206,206,1,32,44,44,1,119,165,165, + 1,183,254,254,1,184,255,255,4,0,0,0,1,184,255,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,3,181,251,251,1,184,255,255,2,51,70,70,1,163,226,226, + 1,184,255,255,6,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,3,0,0,0,1,184,255,255, + 3,0,0,0,1,184,255,255,1,172,238,238,1,11,15,15,1,37,51,51, + 3,184,255,255,4,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,17,0,0,0,1,184,255,255, + 1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224, + 22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tdbrealspinedit: record size: integer; data: array[0..710] of byte end = + (size: 711; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 114,101,97,108,115,112,105,110,101,100,105,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,4,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 15,208,208,208,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,180,249,249,1,20,28,28,1,184,255,255,6,128,177,177, + 1,40,56,56,1,32,45,45,1,124,172,172,1,184,255,255,1,208,208,208, + 2,0,0,0,1,208,208,208,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,144,200,200,1,28,39,39,1,0,0,0, + 1,184,255,255,6,45,62,62,1,180,249,249,1,159,221,221,1,17,24,24, + 1,184,255,255,1,208,208,208,1,0,0,0,3,208,208,208,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,182,252,252, + 1,178,247,247,1,0,0,0,1,184,255,255,6,118,163,163,1,184,255,255, + 1,169,234,234,1,9,12,12,1,184,255,255,1,0,0,0,5,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,7,167,232,232,1,47,65,65,1,91,126,126,1,184,255,255, + 1,208,208,208,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,3,0,0,0,1,184,255,255,6,149,206,206,1,32,44,44, + 1,119,165,165,1,183,254,254,1,184,255,255,1,208,208,208,5,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,3,181,251,251,1,184,255,255,2,51,70,70,1,163,226,226, + 1,184,255,255,3,0,0,0,5,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,3,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,1,172,238,238,1,11,15,15,1,37,51,51,3,184,255,255, + 1,208,208,208,1,0,0,0,3,208,208,208,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,15,208,208,208,2,0,0,0, + 1,208,208,208,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,15,208,208,208,5,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255, + 255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbdatetimeedit: record size: integer; data: array[0..686] of byte end = + (size: 687; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 100,97,116,101,116,105,109,101,101,100,105,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,52,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,0,0,0,3,4,5,5,1,126,174,174,1,184,255,255,4,0,0,0, + 5,184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0, + 1,184,255,255,2,126,174,174,1,4,5,5,1,184,255,255,6,0,0,0, + 1,184,255,255,5,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255, + 3,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,5,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255, + 3,0,0,0,1,184,255,255,6,0,0,0,1,184,255,255,5,0,0,0, + 1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,0,0,0,1,184,255,255,3,0,0,0,1,184,255,255, + 6,0,0,0,1,184,255,255,5,0,0,0,1,184,255,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0, + 1,184,255,255,2,126,174,174,1,4,5,5,1,184,255,255,6,0,0,0, + 1,184,255,255,5,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0,3,4,5,5, + 1,126,174,174,1,184,255,255,2,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,5,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,17,0,0,0,1,184,255,255, + 1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224, + 22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tdbenumedit: record size: integer; data: array[0..1394] of byte end = + (size: 1395; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,98, + 101,110,117,109,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,252,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,184,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,184,255,255,1,172,238,238, + 1,21,29,29,1,184,255,255,1,124,172,172,1,15,21,21,1,13,18,18, + 1,107,148,148,1,83,115,115,1,11,15,15,2,92,128,128,1,184,255,255, + 2,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255,6,128,128,128, + 1,184,255,255,1,71,98,98,1,0,0,0,1,184,255,255,1,21,29,29, + 1,145,201,201,1,151,209,209,1,7,10,10,1,184,255,255,2,140,194,194, + 1,12,17,17,1,184,255,255,3,0,0,0,1,184,255,255,1,255,255,255, + 1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255, + 1,178,247,247,1,0,0,0,1,184,255,255,3,148,205,205,1,49,68,68, + 1,184,255,255,1,118,164,164,1,3,4,4,1,74,103,103,1,184,255,255, + 3,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255, + 2,162,224,224,1,51,70,70,1,167,232,232,1,184,255,255,2,154,214,214, + 1,7,10,10,1,184,255,255,3,0,0,0,1,184,255,255,1,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255, + 1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255,1,119,165,165, + 1,56,77,77,1,170,235,235,1,184,255,255,1,23,32,32,1,164,227,227, + 1,169,234,234,1,17,24,24,1,184,255,255,1,182,252,252,1,167,231,231, + 1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208,3,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255, + 1,14,19,19,1,0,0,0,3,128,177,177,1,14,19,19,1,17,24,24, + 1,129,179,179,1,184,255,255,1,161,223,223,1,0,0,0,1,161,223,223, + 1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255,255,255, + 22,0,0,0,2,255,255,255,2,165,165,165,1,0,0,0,1,165,165,165, + 1,255,255,255,2,0,0,0,1,1,1,1,1,75,75,75,1,255,255,255, + 1,232,232,232,1,77,77,77,1,9,9,9,1,38,38,38,1,203,203,203, + 1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,0,0,0,2,255,255,255,2,88,88,88,1,75,75,75,1,89,89,89, + 1,255,255,255,2,0,0,0,1,234,234,234,1,70,70,70,1,255,255,255, + 1,82,82,82,1,118,118,118,1,245,245,245,1,166,166,166,1,53,53,53, + 1,255,255,255,2,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255, + 1,251,251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251, + 1,255,255,255,1,0,0,0,2,117,117,117,1,255,255,255,1,12,12,12, + 1,241,241,241,1,255,255,255,5,208,208,208,3,128,128,128,1,0,0,0, + 2,255,255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255, + 1,0,0,0,1,243,243,243,1,11,11,11,1,255,255,255,1,14,14,14, + 1,241,241,241,1,255,255,255,1,252,252,252,1,210,210,210,1,255,255,255, + 1,128,128,128,5,0,0,0,2,255,255,255,1,114,114,114,1,141,141,141, + 1,255,255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0, + 1,235,235,235,1,19,19,19,1,255,255,255,1,83,83,83,1,124,124,124, + 1,245,245,245,1,145,145,145,1,57,57,57,1,255,255,255,2,212,212,212, + 1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,255,255,255, + 1,37,37,37,1,217,217,217,1,255,255,255,1,217,217,217,1,38,38,38, + 1,255,255,255,1,0,0,0,1,3,3,3,1,124,124,124,1,255,255,255, + 1,227,227,227,1,63,63,63,1,7,7,7,1,43,43,43,1,213,213,213, + 1,255,255,255,5,128,128,128,1,0,0,0,2,255,255,255,18,128,128,128, + 4,0,0,0,2,255,255,255,2,0,0,0,2,5,5,5,1,174,174,174, + 1,255,255,255,11,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255, + 1,208,208,208,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255, + 1,174,174,174,1,5,5,5,1,255,255,255,1,152,152,152,1,11,11,11, + 1,159,159,159,1,255,255,255,9,252,252,252,1,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255, + 1,29,29,29,1,197,197,197,1,37,37,37,1,255,255,255,8,208,208,208, + 3,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,1,2,2,2,1,0,0,0,1,3,3,3, + 1,255,255,255,8,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255, + 2,0,0,0,1,255,255,255,1,174,174,174,1,5,5,5,1,255,255,255, + 1,25,25,25,1,226,226,226,1,255,255,255,9,208,208,208,1,0,0,0, + 1,208,208,208,1,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0, + 2,5,5,5,1,174,174,174,1,255,255,255,1,146,146,146,1,9,9,9, + 1,98,98,98,1,255,255,255,7,128,128,128,5,0,0,0,25,12,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbenumeditdb: record size: integer; data: array[0..1436] of byte end = + (size: 1437; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 101,110,117,109,101,100,105,116,100,98,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,36,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,224,4,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,184,255,255,1,172, + 238,238,1,21,29,29,1,184,255,255,1,124,172,172,1,15,21,21,1,13, + 18,18,1,107,148,148,1,83,115,115,1,11,15,15,2,92,128,128,1,184, + 255,255,2,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255,6,128, + 128,128,1,184,255,255,1,71,98,98,1,0,0,0,1,184,255,255,1,21, + 29,29,1,145,201,201,1,151,209,209,1,7,10,10,1,184,255,255,2,140, + 194,194,1,12,17,17,1,184,255,255,3,0,0,0,1,184,255,255,1,255, + 255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184, + 255,255,1,178,247,247,1,0,0,0,1,184,255,255,3,148,205,205,1,49, + 68,68,1,184,255,255,1,118,164,164,1,3,4,4,1,74,103,103,1,184, + 255,255,3,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184, + 255,255,2,162,224,224,1,51,70,70,1,167,232,232,1,184,255,255,2,154, + 214,214,1,7,10,10,1,184,255,255,3,0,0,0,1,184,255,255,1,255, + 255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255, + 255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255,1,119, + 165,165,1,56,77,77,1,170,235,235,1,184,255,255,1,23,32,32,1,164, + 227,227,1,169,234,234,1,17,24,24,1,184,255,255,1,182,252,252,1,167, + 231,231,1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184, + 255,255,1,14,19,19,1,0,0,0,3,128,177,177,1,14,19,19,1,17, + 24,24,1,129,179,179,1,184,255,255,1,161,223,223,1,0,0,0,1,161, + 223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,184, + 255,255,17,255,255,255,5,0,0,0,2,184,255,255,2,119,165,165,1,0, + 0,0,1,119,165,165,1,184,255,255,2,0,0,0,1,1,1,1,1,54, + 75,75,1,184,255,255,1,167,232,232,1,56,77,77,1,6,9,9,1,27, + 38,38,1,146,203,203,1,184,255,255,1,255,255,255,1,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255,2,63, + 88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0,1,169, + 234,234,1,51,70,70,1,184,255,255,1,59,82,82,1,85,118,118,1,177, + 245,245,1,120,166,166,1,38,53,53,1,184,255,255,1,255,255,255,1,0, + 0,0,3,128,128,128,1,0,0,0,2,184,255,255,1,181,251,251,1,15, + 21,21,1,159,221,221,1,14,20,20,1,181,251,251,1,184,255,255,1,0, + 0,0,2,84,117,117,1,184,255,255,1,9,12,12,1,174,241,241,1,184, + 255,255,4,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,184, + 255,255,1,138,191,191,1,0,0,0,3,138,191,191,1,184,255,255,1,0, + 0,0,1,175,243,243,1,8,11,11,1,184,255,255,1,10,14,14,1,174, + 241,241,1,184,255,255,1,182,252,252,1,152,210,210,1,184,255,255,1,128, + 128,128,5,0,0,0,2,184,255,255,1,82,114,114,1,102,141,141,1,184, + 255,255,1,102,141,141,1,83,115,115,1,184,255,255,1,0,0,0,1,170, + 235,235,1,14,19,19,1,184,255,255,1,60,83,83,1,89,124,124,1,177, + 245,245,1,105,145,145,1,41,57,57,1,184,255,255,2,206,212,212,1,185, + 252,252,1,208,208,208,1,184,255,255,1,0,0,0,2,184,255,255,1,27, + 37,37,1,157,217,217,1,184,255,255,1,157,217,217,1,27,38,38,1,184, + 255,255,1,0,0,0,1,2,3,3,1,89,124,124,1,184,255,255,1,164, + 227,227,1,45,63,63,1,5,7,7,1,31,43,43,1,154,213,213,1,184, + 255,255,1,255,255,255,4,128,128,128,1,0,0,0,2,184,255,255,17,255, + 255,255,1,128,128,128,4,0,0,0,2,184,255,255,2,0,0,0,2,4, + 5,5,1,126,174,174,1,184,255,255,11,208,208,208,1,184,255,255,1,207, + 211,211,1,184,255,255,1,208,208,208,1,0,0,0,2,184,255,255,2,0, + 0,0,1,184,255,255,1,126,174,174,1,4,5,5,1,184,255,255,1,110, + 152,152,1,8,11,11,1,115,159,159,1,184,255,255,7,255,255,255,2,252, + 252,252,1,255,255,255,2,0,0,0,2,184,255,255,2,0,0,0,1,184, + 255,255,2,0,0,0,1,184,255,255,1,21,29,29,1,142,197,197,1,27, + 37,37,1,184,255,255,7,255,255,255,1,208,208,208,3,128,128,128,1,0, + 0,0,2,184,255,255,2,0,0,0,1,184,255,255,2,0,0,0,1,184, + 255,255,1,1,2,2,1,0,0,0,1,2,3,3,1,184,255,255,7,255, + 255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,184,255,255,2,0, + 0,0,1,184,255,255,1,126,174,174,1,4,5,5,1,184,255,255,1,18, + 25,25,1,163,226,226,1,184,255,255,8,255,255,255,1,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255,2,0, + 0,0,2,4,5,5,1,126,174,174,1,184,255,255,1,105,146,146,1,6, + 9,9,1,71,98,98,1,184,255,255,7,128,128,128,5,0,0,0,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbenum64editdb: record size: integer; data: array[0..1386] of byte end = + (size: 1387; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 101,110,117,109,54,52,101,100,105,116,100,98,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240,4,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,172,4,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,184,255,255, + 1,172,238,238,1,21,29,29,1,184,255,255,1,124,172,172,1,15,21,21, + 1,13,18,18,1,107,148,148,1,83,115,115,1,11,15,15,2,92,128,128, + 1,184,255,255,2,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255, + 6,128,128,128,1,184,255,255,1,71,98,98,1,0,0,0,1,184,255,255, + 1,21,29,29,1,145,201,201,1,151,209,209,1,7,10,10,1,184,255,255, + 2,140,194,194,1,12,17,17,1,184,255,255,3,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,178,247,247,1,0,0,0,1,184,255,255,3,148,205,205, + 1,49,68,68,1,184,255,255,1,118,164,164,1,3,4,4,1,74,103,103, + 1,184,255,255,3,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0, + 3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0, + 1,184,255,255,2,162,224,224,1,51,70,70,1,167,232,232,1,184,255,255, + 2,154,214,214,1,7,10,10,1,184,255,255,3,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255, + 1,119,165,165,1,56,77,77,1,170,235,235,1,184,255,255,1,23,32,32, + 1,164,227,227,1,169,234,234,1,17,24,24,1,184,255,255,1,182,252,252, + 1,167,231,231,1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208, + 3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0, + 1,184,255,255,1,14,19,19,1,0,0,0,3,128,177,177,1,14,19,19, + 1,17,24,24,1,129,179,179,1,184,255,255,1,161,223,223,1,0,0,0, + 1,161,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0, + 25,184,255,255,17,255,255,255,5,0,0,0,2,184,255,255,17,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,184,255,255,2,183,253,253,1,96,133,133,1,17,24,24,1,4,5,5, + 1,53,73,73,1,166,230,230,1,184,255,255,5,131,182,182,1,1,2,2, + 1,184,255,255,2,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0, + 2,184,255,255,2,102,142,142,1,22,30,30,1,126,174,174,1,139,193,193, + 1,47,65,65,1,56,77,77,1,184,255,255,4,155,215,215,1,10,14,14, + 1,0,0,0,1,184,255,255,2,255,255,255,1,208,208,208,3,128,128,128, + 1,0,0,0,2,184,255,255,1,183,254,254,1,22,30,30,1,130,180,180, + 1,184,255,255,2,168,233,233,1,127,176,176,1,184,255,255,3,172,238,238, + 1,26,36,36,1,82,114,114,1,0,0,0,1,184,255,255,2,128,128,128, + 5,0,0,0,2,184,255,255,1,169,234,234,1,0,0,0,1,108,149,149, + 1,19,27,27,1,6,8,8,1,61,84,84,1,171,237,237,1,184,255,255, + 2,181,251,251,1,50,69,69,1,79,109,109,1,155,215,215,1,0,0,0, + 1,184,255,255,2,255,255,255,1,212,212,212,1,252,252,252,1,208,208,208, + 1,255,255,255,1,0,0,0,2,184,255,255,1,156,216,216,1,0,0,0, + 1,35,49,49,1,136,188,188,1,141,195,195,1,40,55,55,1,58,81,81, + 1,184,255,255,2,80,111,111,1,48,67,67,1,180,250,250,1,155,215,215, + 1,0,0,0,1,184,255,255,2,255,255,255,4,128,128,128,1,0,0,0, + 2,184,255,255,1,159,221,221,1,0,0,0,1,152,210,210,1,184,255,255, + 2,153,212,212,1,1,1,1,1,173,240,240,1,115,160,160,1,25,35,35, + 1,171,237,237,1,184,255,255,1,155,215,215,1,0,0,0,1,184,255,255, + 2,255,255,255,1,128,128,128,4,0,0,0,2,184,255,255,1,175,242,242, + 1,0,0,0,1,180,249,249,1,184,255,255,2,180,249,249,1,0,0,0, + 1,159,220,220,1,66,91,91,1,0,0,0,6,77,107,107,1,208,208,208, + 1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0, + 2,184,255,255,2,29,40,40,1,141,195,195,1,184,255,255,2,144,200,200, + 1,5,7,7,1,178,246,246,1,165,229,229,1,155,215,215,3,131,181,181, + 1,0,0,0,1,155,215,215,1,167,231,231,1,255,255,255,2,252,252,252, + 1,255,255,255,2,0,0,0,2,184,255,255,2,104,144,144,1,25,35,35, + 1,130,180,180,1,131,182,182,1,29,40,40,1,76,106,106,1,184,255,255, + 5,155,215,215,1,0,0,0,1,184,255,255,2,255,255,255,1,208,208,208, + 3,128,128,128,1,0,0,0,2,184,255,255,2,182,252,252,1,81,112,112, + 1,9,12,12,1,11,15,15,1,76,106,106,1,178,247,247,1,184,255,255, + 5,155,215,215,1,0,0,0,1,184,255,255,2,255,255,255,1,0,0,0, + 3,128,128,128,1,0,0,0,2,184,255,255,17,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255, + 17,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,66,0,0) + ); + +const + objdata_tdbenumeditlb: record size: integer; data: array[0..1440] of byte end = + (size: 1441; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 101,110,117,109,101,100,105,116,108,98,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,40,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,228,4,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,184,255,255,1,172, + 238,238,1,21,29,29,1,184,255,255,1,124,172,172,1,15,21,21,1,13, + 18,18,1,107,148,148,1,83,115,115,1,11,15,15,2,92,128,128,1,184, + 255,255,2,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255,6,128, + 128,128,1,184,255,255,1,71,98,98,1,0,0,0,1,184,255,255,1,21, + 29,29,1,145,201,201,1,151,209,209,1,7,10,10,1,184,255,255,2,140, + 194,194,1,12,17,17,1,184,255,255,3,0,0,0,1,184,255,255,1,255, + 255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184, + 255,255,1,178,247,247,1,0,0,0,1,184,255,255,3,148,205,205,1,49, + 68,68,1,184,255,255,1,118,164,164,1,3,4,4,1,74,103,103,1,184, + 255,255,3,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184, + 255,255,2,162,224,224,1,51,70,70,1,167,232,232,1,184,255,255,2,154, + 214,214,1,7,10,10,1,184,255,255,3,0,0,0,1,184,255,255,1,255, + 255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255, + 255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255,1,119, + 165,165,1,56,77,77,1,170,235,235,1,184,255,255,1,23,32,32,1,164, + 227,227,1,169,234,234,1,17,24,24,1,184,255,255,1,182,252,252,1,167, + 231,231,1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184, + 255,255,1,14,19,19,1,0,0,0,3,128,177,177,1,14,19,19,1,17, + 24,24,1,129,179,179,1,184,255,255,1,161,223,223,1,0,0,0,1,161, + 223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,201, + 201,255,17,255,255,255,5,0,0,0,2,201,201,255,2,130,130,165,1,0, + 0,0,1,130,130,165,1,201,201,255,2,0,0,0,1,1,1,1,1,59, + 59,75,1,201,201,255,1,183,183,232,1,61,61,77,1,7,7,9,1,30, + 30,38,1,160,160,203,1,201,201,255,1,255,255,255,1,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201,255,2,69, + 69,88,1,59,59,75,1,70,70,89,1,201,201,255,2,0,0,0,1,184, + 184,234,1,55,55,70,1,201,201,255,1,65,65,82,1,93,93,118,1,193, + 193,245,1,131,131,166,1,42,42,53,1,201,201,255,1,255,255,255,1,0, + 0,0,3,128,128,128,1,0,0,0,2,201,201,255,1,198,198,251,1,17, + 17,21,1,174,174,221,1,16,16,20,1,198,198,251,1,201,201,255,1,0, + 0,0,2,92,92,117,1,201,201,255,1,9,9,12,1,190,190,241,1,201, + 201,255,4,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,201, + 201,255,1,151,151,191,1,0,0,0,3,151,151,191,1,201,201,255,1,0, + 0,0,1,192,192,243,1,9,9,11,1,201,201,255,1,11,11,14,1,190, + 190,241,1,201,201,255,1,199,199,252,1,166,166,210,1,201,201,255,1,128, + 128,128,5,0,0,0,2,201,201,255,1,90,90,114,1,111,111,141,1,201, + 201,255,1,111,111,141,1,91,91,115,1,201,201,255,1,0,0,0,1,185, + 185,235,1,15,15,19,1,201,201,255,1,65,65,83,1,98,98,124,1,193, + 193,245,1,114,114,145,1,45,45,57,1,201,201,255,1,255,255,255,1,212, + 212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,201, + 201,255,1,29,29,37,1,171,171,217,1,201,201,255,1,171,171,217,1,30, + 30,38,1,201,201,255,1,0,0,0,1,2,2,3,1,98,98,124,1,201, + 201,255,1,179,179,227,1,50,50,63,1,6,6,7,1,34,34,43,1,168, + 168,213,1,201,201,255,1,255,255,255,4,128,128,128,1,0,0,0,2,201, + 201,255,17,255,255,255,1,128,128,128,4,0,0,0,2,201,201,255,2,0, + 0,0,2,4,4,5,1,137,137,174,1,201,201,255,11,208,208,208,1,255, + 255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,201, + 201,255,2,0,0,0,1,201,201,255,1,137,137,174,1,4,4,5,1,201, + 201,255,1,120,120,152,1,9,9,11,1,125,125,159,1,201,201,255,7,255, + 255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,201,201,255,2,0, + 0,0,1,201,201,255,2,0,0,0,1,201,201,255,1,23,23,29,1,155, + 155,197,1,29,29,37,1,201,201,255,7,255,255,255,1,208,208,208,3,128, + 128,128,1,0,0,0,2,201,201,255,2,0,0,0,1,201,201,255,2,0, + 0,0,1,201,201,255,1,2,2,2,1,0,0,0,1,2,2,3,1,201, + 201,255,7,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,201, + 201,255,2,0,0,0,1,201,201,255,1,137,137,174,1,4,4,5,1,201, + 201,255,1,20,20,25,1,178,178,226,1,201,201,255,8,255,255,255,1,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201, + 201,255,2,0,0,0,2,4,4,5,1,137,137,174,1,201,201,255,1,115, + 115,146,1,7,7,9,1,77,77,98,1,201,201,255,7,128,128,128,5,0, + 0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0, + 0) + ); + +const + objdata_tdbenum64editlb: record size: integer; data: array[0..1386] of byte end = + (size: 1387; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 101,110,117,109,54,52,101,100,105,116,108,98,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240,4,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,172,4,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,184,255,255, + 1,172,238,238,1,21,29,29,1,184,255,255,1,124,172,172,1,15,21,21, + 1,13,18,18,1,107,148,148,1,83,115,115,1,11,15,15,2,92,128,128, + 1,184,255,255,2,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255, + 6,128,128,128,1,184,255,255,1,71,98,98,1,0,0,0,1,184,255,255, + 1,21,29,29,1,145,201,201,1,151,209,209,1,7,10,10,1,184,255,255, + 2,140,194,194,1,12,17,17,1,184,255,255,3,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,178,247,247,1,0,0,0,1,184,255,255,3,148,205,205, + 1,49,68,68,1,184,255,255,1,118,164,164,1,3,4,4,1,74,103,103, + 1,184,255,255,3,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0, + 3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0, + 1,184,255,255,2,162,224,224,1,51,70,70,1,167,232,232,1,184,255,255, + 2,154,214,214,1,7,10,10,1,184,255,255,3,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255, + 1,119,165,165,1,56,77,77,1,170,235,235,1,184,255,255,1,23,32,32, + 1,164,227,227,1,169,234,234,1,17,24,24,1,184,255,255,1,182,252,252, + 1,167,231,231,1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208, + 3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0, + 1,184,255,255,1,14,19,19,1,0,0,0,3,128,177,177,1,14,19,19, + 1,17,24,24,1,129,179,179,1,184,255,255,1,161,223,223,1,0,0,0, + 1,161,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0, + 25,201,201,255,17,255,255,255,5,0,0,0,2,201,201,255,17,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,201,201,255,2,199,199,253,1,105,105,133,1,19,19,24,1,4,4,5, + 1,58,58,73,1,181,181,230,1,201,201,255,5,143,143,182,1,2,2,2, + 1,201,201,255,2,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0, + 2,201,201,255,2,112,112,142,1,24,24,30,1,137,137,174,1,152,152,193, + 1,51,51,65,1,61,61,77,1,201,201,255,4,169,169,215,1,11,11,14, + 1,0,0,0,1,201,201,255,2,255,255,255,1,208,208,208,3,128,128,128, + 1,0,0,0,2,201,201,255,1,200,200,254,1,24,24,30,1,142,142,180, + 1,201,201,255,2,184,184,233,1,139,139,176,1,201,201,255,3,188,188,238, + 1,28,28,36,1,90,90,114,1,0,0,0,1,201,201,255,2,128,128,128, + 5,0,0,0,2,201,201,255,1,184,184,234,1,0,0,0,1,117,117,149, + 1,21,21,27,1,6,6,8,1,66,66,84,1,187,187,237,1,201,201,255, + 2,198,198,251,1,54,54,69,1,86,86,109,1,169,169,215,1,0,0,0, + 1,201,201,255,2,255,255,255,1,212,212,212,1,252,252,252,1,208,208,208, + 1,255,255,255,1,0,0,0,2,201,201,255,1,170,170,216,1,0,0,0, + 1,39,39,49,1,148,148,188,1,154,154,195,1,43,43,55,1,64,64,81, + 1,201,201,255,2,87,87,111,1,53,53,67,1,197,197,250,1,169,169,215, + 1,0,0,0,1,201,201,255,2,255,255,255,4,128,128,128,1,0,0,0, + 2,201,201,255,1,174,174,221,1,0,0,0,1,166,166,210,1,201,201,255, + 2,167,167,212,1,1,1,1,1,189,189,240,1,126,126,160,1,28,28,35, + 1,187,187,237,1,201,201,255,1,169,169,215,1,0,0,0,1,201,201,255, + 2,255,255,255,1,128,128,128,4,0,0,0,2,201,201,255,1,191,191,242, + 1,0,0,0,1,196,196,249,1,201,201,255,2,196,196,249,1,0,0,0, + 1,173,173,220,1,72,72,91,1,0,0,0,6,84,84,107,1,208,208,208, + 1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0, + 2,201,201,255,2,32,32,40,1,154,154,195,1,201,201,255,2,158,158,200, + 1,6,6,7,1,194,194,246,1,181,181,229,1,169,169,215,3,143,143,181, + 1,0,0,0,1,169,169,215,1,182,182,231,1,255,255,255,2,252,252,252, + 1,255,255,255,2,0,0,0,2,201,201,255,2,114,114,144,1,28,28,35, + 1,142,142,180,1,143,143,182,1,32,32,40,1,84,84,106,1,201,201,255, + 5,169,169,215,1,0,0,0,1,201,201,255,2,255,255,255,1,208,208,208, + 3,128,128,128,1,0,0,0,2,201,201,255,2,199,199,252,1,88,88,112, + 1,9,9,12,1,12,12,15,1,84,84,106,1,195,195,247,1,201,201,255, + 5,169,169,215,1,0,0,0,1,201,201,255,2,255,255,255,1,0,0,0, + 3,128,128,128,1,0,0,0,2,201,201,255,17,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201,255, + 17,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,66,0,0) + ); + +const + objdata_tdbkeystringedit: record size: integer; data: array[0..1191] of byte end = + (size: 1192; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,100,98, + 107,101,121,115,116,114,105,110,103,101,100,105,116,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,232,3, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,184,255, + 255,2,119,165,165,1,0,0,0,1,119,165,165,1,184,255,255,2,0,0, + 0,1,1,1,1,1,54,75,75,1,184,255,255,4,0,0,0,1,169,234, + 234,1,17,23,23,1,255,255,255,6,128,128,128,1,184,255,255,2,63,88, + 88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0,1,169,234, + 234,1,51,70,70,1,184,255,255,5,0,0,0,1,184,255,255,1,255,255, + 255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184,255, + 255,1,181,251,251,1,15,21,21,1,159,221,221,1,14,20,20,1,181,251, + 251,1,184,255,255,1,0,0,0,2,84,117,117,1,184,255,255,5,0,0, + 0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128,1,255,255, + 255,1,128,128,128,1,184,255,255,1,138,191,191,1,0,0,0,3,138,191, + 191,1,184,255,255,1,0,0,0,1,175,243,243,1,8,11,11,1,184,255, + 255,5,0,0,0,1,184,255,255,1,255,255,255,1,208,208,208,1,0,0, + 0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,184,255, + 255,1,82,114,114,1,102,141,141,1,184,255,255,1,102,141,141,1,83,115, + 115,1,184,255,255,1,0,0,0,1,170,235,235,1,14,19,19,1,184,255, + 255,3,182,252,252,1,167,231,231,1,0,0,0,1,178,247,247,1,255,255, + 255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184,255, + 255,1,27,37,37,1,157,217,217,1,184,255,255,1,157,217,217,1,27,38, + 38,1,184,255,255,1,0,0,0,1,2,3,3,1,89,124,124,1,184,255, + 255,3,161,223,223,1,0,0,0,1,161,223,223,1,0,0,0,1,128,128, + 128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0,2,255,255, + 255,18,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0, + 0,2,255,255,255,18,0,0,0,3,128,128,128,1,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,2,157,157,157,1,102,102,102,1,255,255, + 255,12,208,208,208,3,128,128,128,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,1,201,201,201,1,65,65,65,1,249,249,249,1,255,255, + 255,11,128,128,128,5,0,0,0,2,255,255,255,1,0,0,0,1,233,233, + 233,1,53,53,53,1,230,230,230,1,255,255,255,1,186,186,186,1,25,25, + 25,2,195,195,195,1,255,255,255,1,52,52,52,1,203,203,203,1,255,255, + 255,1,204,204,204,1,50,50,50,1,255,255,255,2,212,212,212,1,252,252, + 252,1,208,208,208,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,1,62,62,62,1,124,124,124,1,255,255,255,2,39,39,39,1,194,194, + 194,1,197,197,197,1,50,50,50,1,255,255,255,1,157,157,157,1,97,97, + 97,1,255,255,255,1,102,102,102,1,152,152,152,1,255,255,255,5,128,128, + 128,1,0,0,0,2,255,255,255,1,0,0,0,1,146,146,146,1,57,57, + 57,1,208,208,208,1,255,255,255,1,3,3,3,1,0,0,0,2,4,4, + 4,1,255,255,255,1,246,246,246,1,27,27,27,1,226,226,226,1,25,25, + 25,1,242,242,242,1,255,255,255,2,128,128,128,4,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,1,217,217,217,1,51,51,51,1,244,244, + 244,1,34,34,34,1,195,195,195,1,255,255,255,4,113,113,113,1,55,55, + 55,1,99,99,99,1,255,255,255,2,208,208,208,1,255,255,255,1,211,211, + 211,1,255,255,255,1,208,208,208,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,2,161,161,161,1,94,94,94,1,179,179,179,1,23,23, + 23,1,13,13,13,1,120,120,120,1,255,255,255,2,217,217,217,1,0,0, + 0,1,201,201,201,1,255,255,255,4,252,252,252,1,255,255,255,2,0,0, + 0,2,255,255,255,12,202,202,202,1,41,41,41,1,255,255,255,4,208,208, + 208,3,128,128,128,1,0,0,0,2,255,255,255,12,12,12,12,1,168,168, + 168,1,255,255,255,4,0,0,0,3,128,128,128,1,0,0,0,2,255,255, + 255,18,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0, + 0,2,255,255,255,17,128,128,128,5,0,0,0,25,12,0,0,0,255,255, + 255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbkeystringeditdb: record size: integer; data: array[0..1237] of byte end = + (size: 1238; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 107,101,121,115,116,114,105,110,103,101,100,105,116,100,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 88,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 20,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 184,255,255,2,119,165,165,1,0,0,0,1,119,165,165,1,184,255,255,2, + 0,0,0,1,1,1,1,1,54,75,75,1,184,255,255,4,0,0,0,1, + 169,234,234,1,17,23,23,1,255,255,255,6,128,128,128,1,184,255,255,2, + 63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0,1, + 169,234,234,1,51,70,70,1,184,255,255,5,0,0,0,1,184,255,255,1, + 255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,181,251,251,1,15,21,21,1,159,221,221,1,14,20,20,1, + 181,251,251,1,184,255,255,1,0,0,0,2,84,117,117,1,184,255,255,5, + 0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128,1, + 255,255,255,1,128,128,128,1,184,255,255,1,138,191,191,1,0,0,0,3, + 138,191,191,1,184,255,255,1,0,0,0,1,175,243,243,1,8,11,11,1, + 184,255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,208,208,208,1, + 0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102,141,141,1, + 83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14,19,19,1, + 184,255,255,3,182,252,252,1,167,231,231,1,0,0,0,1,178,247,247,1, + 255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157,217,217,1, + 27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89,124,124,1, + 184,255,255,3,161,223,223,1,0,0,0,1,161,223,223,1,0,0,0,1, + 128,128,128,5,255,255,255,25,0,0,0,25,184,255,255,17,255,255,255,5, + 0,0,0,2,184,255,255,17,255,255,255,1,208,208,208,1,0,0,0,1, + 208,208,208,1,128,128,128,1,0,0,0,2,184,255,255,17,255,255,255,1, + 0,0,0,3,128,128,128,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,113,157,157,1,74,102,102,1,184,255,255,11,255,255,255,1, + 208,208,208,3,128,128,128,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,1,145,201,201,1,47,65,65,1,180,249,249,1,184,255,255,11, + 128,128,128,5,0,0,0,2,184,255,255,1,0,0,0,1,168,233,233,1, + 38,53,53,1,166,230,230,1,184,255,255,1,134,186,186,1,18,25,25,2, + 141,195,195,1,184,255,255,1,38,52,52,1,146,203,203,1,184,255,255,1, + 147,204,204,1,36,50,50,1,184,255,255,1,255,255,255,1,212,212,212,1, + 252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,45,62,62,1,89,124,124,1,184,255,255,2,28,39,39,1, + 140,194,194,1,142,197,197,1,36,50,50,1,184,255,255,1,113,157,157,1, + 70,97,97,1,184,255,255,1,74,102,102,1,110,152,152,1,184,255,255,1, + 255,255,255,4,128,128,128,1,0,0,0,2,184,255,255,1,0,0,0,1, + 105,146,146,1,41,57,57,1,150,208,208,1,184,255,255,1,2,3,3,1, + 0,0,0,2,3,4,4,1,184,255,255,1,178,246,246,1,19,27,27,1, + 163,226,226,1,18,25,25,1,175,242,242,1,184,255,255,1,255,255,255,1, + 128,128,128,4,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1, + 157,217,217,1,37,51,51,1,176,244,244,1,25,34,34,1,141,195,195,1, + 184,255,255,4,82,113,113,1,40,55,55,1,71,99,99,1,184,255,255,2, + 208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,116,161,161,1, + 68,94,94,1,129,179,179,1,17,23,23,1,9,13,13,1,87,120,120,1, + 184,255,255,2,157,217,217,1,0,0,0,1,145,201,201,1,184,255,255,2, + 255,255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,184,255,255,12, + 146,202,202,1,30,41,41,1,184,255,255,3,255,255,255,1,208,208,208,3, + 128,128,128,1,0,0,0,2,184,255,255,12,9,12,12,1,121,168,168,1, + 184,255,255,3,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2, + 184,255,255,17,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1, + 128,128,128,1,0,0,0,2,184,255,255,17,128,128,128,5,0,0,0,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbkeystringeditlb: record size: integer; data: array[0..1237] of byte end = + (size: 1238; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 107,101,121,115,116,114,105,110,103,101,100,105,116,108,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 88,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 20,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 184,255,255,2,119,165,165,1,0,0,0,1,119,165,165,1,184,255,255,2, + 0,0,0,1,1,1,1,1,54,75,75,1,184,255,255,4,0,0,0,1, + 169,234,234,1,17,23,23,1,255,255,255,6,128,128,128,1,184,255,255,2, + 63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0,1, + 169,234,234,1,51,70,70,1,184,255,255,5,0,0,0,1,184,255,255,1, + 255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,181,251,251,1,15,21,21,1,159,221,221,1,14,20,20,1, + 181,251,251,1,184,255,255,1,0,0,0,2,84,117,117,1,184,255,255,5, + 0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128,1, + 255,255,255,1,128,128,128,1,184,255,255,1,138,191,191,1,0,0,0,3, + 138,191,191,1,184,255,255,1,0,0,0,1,175,243,243,1,8,11,11,1, + 184,255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,208,208,208,1, + 0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102,141,141,1, + 83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14,19,19,1, + 184,255,255,3,182,252,252,1,167,231,231,1,0,0,0,1,178,247,247,1, + 255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157,217,217,1, + 27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89,124,124,1, + 184,255,255,3,161,223,223,1,0,0,0,1,161,223,223,1,0,0,0,1, + 128,128,128,5,255,255,255,25,0,0,0,25,201,201,255,17,255,255,255,5, + 0,0,0,2,201,201,255,17,255,255,255,1,208,208,208,1,0,0,0,1, + 208,208,208,1,128,128,128,1,0,0,0,2,201,201,255,17,255,255,255,1, + 0,0,0,3,128,128,128,1,0,0,0,2,201,201,255,1,0,0,0,1, + 201,201,255,2,124,124,157,1,80,80,102,1,201,201,255,11,255,255,255,1, + 208,208,208,3,128,128,128,1,0,0,0,2,201,201,255,1,0,0,0,1, + 201,201,255,1,158,158,201,1,51,51,65,1,196,196,249,1,201,201,255,11, + 128,128,128,5,0,0,0,2,201,201,255,1,0,0,0,1,184,184,233,1, + 42,42,53,1,181,181,230,1,201,201,255,1,147,147,186,1,20,20,25,2, + 154,154,195,1,201,201,255,1,41,41,52,1,160,160,203,1,201,201,255,1, + 161,161,204,1,39,39,50,1,201,201,255,1,255,255,255,1,212,212,212,1, + 252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,201,201,255,1, + 0,0,0,1,49,49,62,1,98,98,124,1,201,201,255,2,31,31,39,1, + 153,153,194,1,155,155,197,1,39,39,50,1,201,201,255,1,124,124,157,1, + 76,76,97,1,201,201,255,1,80,80,102,1,120,120,152,1,201,201,255,1, + 255,255,255,4,128,128,128,1,0,0,0,2,201,201,255,1,0,0,0,1, + 115,115,146,1,45,45,57,1,164,164,208,1,201,201,255,1,2,2,3,1, + 0,0,0,2,3,3,4,1,201,201,255,1,194,194,246,1,21,21,27,1, + 178,178,226,1,20,20,25,1,191,191,242,1,201,201,255,1,255,255,255,1, + 128,128,128,4,0,0,0,2,201,201,255,1,0,0,0,1,201,201,255,1, + 171,171,217,1,40,40,51,1,192,192,244,1,27,27,34,1,154,154,195,1, + 201,201,255,4,89,89,113,1,43,43,55,1,78,78,99,1,201,201,255,2, + 208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1, + 0,0,0,2,201,201,255,1,0,0,0,1,201,201,255,2,127,127,161,1, + 74,74,94,1,141,141,179,1,18,18,23,1,10,10,13,1,95,95,120,1, + 201,201,255,2,171,171,217,1,0,0,0,1,158,158,201,1,201,201,255,2, + 255,255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,201,201,255,12, + 159,159,202,1,32,32,41,1,201,201,255,3,255,255,255,1,208,208,208,3, + 128,128,128,1,0,0,0,2,201,201,255,12,9,9,12,1,132,132,168,1, + 201,201,255,3,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2, + 201,201,255,17,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1, + 128,128,128,1,0,0,0,2,201,201,255,17,128,128,128,5,0,0,0,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbstringlookuplb: record size: integer; data: array[0..948] of byte end = + (size: 949; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,108,98,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,56, + 3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,244, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,176, + 244,244,1,175,243,243,1,184,255,255,9,188,241,255,1,196,214,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,98, + 136,136,1,92,127,127,1,184,255,255,7,188,241,255,1,196,214,255,1,201, + 201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,188,241,255,1,196, + 214,255,1,201,201,255,4,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,1,151,209,209,1,45,62,62,1,26,36,36,1,22, + 31,31,1,113,156,156,1,184,255,255,1,98,136,136,1,63,87,87,1,61, + 85,85,1,22,30,30,1,95,131,131,1,188,241,255,1,196,214,255,1,137, + 137,174,1,37,37,47,1,35,35,45,1,97,97,123,1,201,201,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,63, + 88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17,17,1,184, + 255,255,1,98,136,136,1,19,27,27,1,160,222,222,1,170,217,230,1,27, + 29,35,1,149,149,189,1,171,171,217,1,15,15,19,1,169,169,214,1,198, + 198,251,1,56,56,71,1,153,153,194,1,201,201,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254,254,1,141, + 196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,184,255,255,1,98, + 136,136,1,77,98,104,1,196,214,255,1,201,201,255,1,88,88,112,1,97, + 97,123,1,125,125,158,1,61,61,78,1,201,201,255,5,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76,76,2,109, + 151,151,1,142,197,197,1,0,0,0,1,188,241,255,1,105,114,136,1,95, + 95,121,1,201,201,255,2,94,94,119,1,95,95,121,1,114,114,144,1,70, + 70,89,1,201,201,255,2,191,191,242,1,193,193,245,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,179,248,248,1,4, + 6,6,1,172,239,239,1,184,255,255,1,124,159,168,1,0,0,0,1,198, + 198,251,1,107,107,136,1,42,42,53,1,189,189,240,1,193,193,245,1,32, + 32,40,1,144,144,183,1,157,157,199,1,20,20,25,1,192,192,243,1,201, + 201,255,1,68,68,86,1,135,135,171,1,201,201,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,89,123,123,1,36, + 46,49,1,51,56,67,1,79,79,100,1,22,22,28,1,176,176,223,1,107, + 107,136,1,65,65,82,1,54,54,68,1,38,38,48,1,110,110,139,1,201, + 201,255,2,117,117,148,1,42,42,53,1,44,44,56,1,76,76,96,1,200, + 200,254,1,201,201,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,188,241,255,1,196,214,255,1,194,194,246,1,195,195,247,1,201, + 201,255,5,199,199,253,1,196,196,249,1,201,201,255,4,200,200,254,1,194, + 194,246,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,224, + 224,224,22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255,255,255, + 255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbstringlookupdb: record size: integer; data: array[0..968] of byte end = + (size: 969; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,100,98,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76, + 3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,8, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,176, + 244,244,1,175,243,243,1,184,255,255,7,174,249,255,1,97,202,255,1,18, + 153,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,174,249,255,1,97, + 202,255,1,18,153,255,2,97,202,255,1,174,249,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,98,136,136,1,92, + 127,127,1,184,255,255,3,174,249,255,1,97,202,255,1,18,153,255,2,97, + 202,255,1,174,249,255,1,184,255,255,2,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,151,209,209,1,45,62,62,1,26, + 36,36,1,22,31,31,1,113,156,156,1,184,255,255,1,98,136,136,1,63, + 87,87,1,61,85,85,1,20,29,30,1,50,104,131,1,18,153,255,2,66, + 138,174,1,32,46,47,1,32,45,45,1,89,123,123,1,184,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,63, + 88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17,17,1,184, + 255,255,1,98,136,136,1,18,26,27,1,84,176,222,1,16,138,230,1,2, + 21,35,1,72,150,189,1,148,212,217,1,14,19,19,1,154,214,214,1,181, + 251,251,1,51,71,71,1,140,194,194,1,184,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254,254,1,141, + 196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,174,249,255,1,52, + 108,136,1,7,62,104,1,18,153,255,1,97,202,255,1,76,109,112,1,89, + 123,123,1,114,158,158,1,56,78,78,1,184,255,255,5,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76,76,2,109, + 151,151,1,134,192,197,1,0,0,0,1,18,153,255,1,10,82,136,1,46, + 96,121,1,174,249,255,1,184,255,255,1,86,119,119,1,87,121,121,1,104, + 144,144,1,64,89,89,1,184,255,255,2,175,242,242,1,177,245,245,1,184, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,179, + 248,248,1,4,6,6,1,163,233,239,1,97,202,255,1,12,101,168,1,0, + 0,0,1,95,199,251,1,93,133,136,1,38,53,53,1,173,240,240,1,177, + 245,245,1,29,40,40,1,132,183,183,1,144,199,199,1,18,25,25,1,175, + 243,243,1,184,255,255,1,62,86,86,1,123,171,171,1,184,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,47, + 97,123,1,3,29,49,1,5,40,67,1,38,79,100,1,19,27,28,1,161, + 223,223,1,98,136,136,1,59,82,82,1,49,68,68,1,35,48,48,1,100, + 139,139,1,184,255,255,2,107,148,148,1,38,53,53,1,40,56,56,1,69, + 96,96,1,183,254,254,1,184,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,18,153,255,2,94,195,246,1,169,241,247,1,184, + 255,255,5,183,253,253,1,180,249,249,1,184,255,255,4,183,254,254,1,178, + 246,246,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,224, + 224,224,22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255,255,255, + 255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbintegerlookuplb: record size: integer; data: array[0..957] of byte end = + (size: 958; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,108,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 64,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 252,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,4, + 168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184,255,255,4, + 182,252,252,1,178,246,246,1,184,255,255,1,188,241,255,1,196,214,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 103,143,143,1,51,71,71,1,184,255,255,2,181,251,251,1,69,95,95,1, + 35,48,48,1,31,43,43,1,87,121,121,1,184,255,255,2,105,145,145,1, + 34,47,47,1,33,43,45,1,79,86,103,1,198,198,251,1,201,201,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1, + 175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184,255,255,2, + 118,164,164,1,62,86,86,1,184,255,255,1,180,250,250,1,32,44,44,1, + 147,204,204,1,159,221,221,1,23,29,31,1,190,207,247,1,201,201,255,1, + 43,43,55,1,142,142,180,1,201,201,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,142,197,197,1,92,127,127,1, + 126,175,175,1,51,71,71,1,184,255,255,2,154,214,214,1,162,225,225,1, + 184,255,255,2,51,71,71,1,116,149,158,1,196,214,255,1,188,188,238,1, + 201,201,255,1,199,199,252,1,32,32,40,1,143,143,181,1,201,201,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 132,183,183,1,51,71,71,1,184,255,255,5,137,176,186,1,21,23,27,1, + 187,187,237,1,201,201,255,2,139,139,176,1,19,19,24,1,66,66,84,1, + 201,201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,3,132,183,183,1,51,71,71,1,184,255,255,3,188,241,255,1, + 135,148,176,1,20,20,26,1,160,160,203,1,201,201,255,3,188,188,238,1, + 163,163,207,1,50,50,63,1,114,114,144,1,201,201,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183,183,1, + 51,71,71,1,184,255,255,1,188,241,255,1,196,214,255,1,130,130,165,1, + 26,26,33,1,168,168,213,1,201,201,255,2,188,188,238,1,175,175,222,1, + 201,201,255,2,137,137,174,1,49,49,62,1,201,201,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183,183,1, + 52,67,71,1,196,214,255,1,201,201,255,1,148,148,188,1,31,31,39,1, + 181,181,229,1,201,201,255,3,169,169,214,1,27,27,34,1,197,197,250,1, + 201,201,255,1,81,81,103,1,107,107,136,1,201,201,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,188,241,255,1, + 141,154,183,1,56,56,71,1,201,201,255,2,48,48,61,1,2,2,3,1, + 6,6,7,3,110,110,139,1,201,201,255,1,107,107,136,1,37,37,47,1, + 41,41,52,1,76,76,96,1,188,188,239,1,201,201,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,188,241,255,1,196,214,255,1, + 201,201,255,13,198,198,251,1,192,192,244,1,201,201,255,3,224,224,224,1, + 255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,208,208,208,240, + 12,0,0,0,255,255,255,255,255,255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbintegerlookupdb: record size: integer; data: array[0..989] of byte end = + (size: 990; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,100,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 96,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 28,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,4, + 168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184,255,255,4, + 182,252,252,1,168,240,246,1,97,202,255,1,18,153,255,2,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,103,143,143,1, + 51,71,71,1,184,255,255,2,181,251,251,1,69,95,95,1,35,48,48,1, + 31,43,43,1,87,121,121,1,184,255,255,2,99,142,145,1,18,37,47,1, + 3,27,45,1,7,62,103,1,95,199,251,1,174,249,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,175,242,242,1, + 75,104,104,1,13,18,18,1,51,71,71,1,184,255,255,2,118,164,164,1, + 62,86,86,1,184,255,255,1,180,250,250,1,32,44,44,1,139,199,204,1, + 84,175,221,1,2,19,31,1,17,148,247,1,97,202,255,1,38,54,55,1, + 130,180,180,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,1,142,197,197,1,92,127,127,1,126,175,175,1, + 51,71,71,1,184,255,255,2,154,214,214,1,162,225,225,1,184,255,255,1, + 174,249,255,1,27,56,71,1,11,95,158,1,18,153,255,1,91,189,238,1, + 174,249,255,1,182,252,252,1,29,40,40,1,131,181,181,1,184,255,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 132,183,183,1,51,71,71,1,184,255,255,3,174,249,255,1,97,202,255,1, + 13,112,186,1,2,16,27,1,90,188,237,1,174,249,255,1,184,255,255,1, + 127,176,176,1,17,24,24,1,61,84,84,1,184,255,255,2,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183,183,1, + 51,71,71,1,184,255,255,1,174,249,255,1,97,202,255,1,18,153,255,1, + 12,106,176,1,10,21,26,1,139,198,203,1,184,255,255,3,172,238,238,1, + 149,207,207,1,45,63,63,1,104,144,144,1,184,255,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183,183,1, + 48,69,71,1,97,202,255,1,18,153,255,2,63,131,165,1,23,32,33,1, + 154,213,213,1,184,255,255,2,172,238,238,1,160,222,222,1,184,255,255,2, + 126,174,174,1,45,62,62,1,184,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,2,174,249,255,1,70,145,183,1, + 5,43,71,1,18,153,255,1,97,202,255,1,128,184,188,1,28,39,39,1, + 165,229,229,1,184,255,255,3,154,214,214,1,25,34,34,1,180,250,250,1, + 184,255,255,1,74,103,103,1,98,136,136,1,184,255,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,97,202,255,1, + 18,153,255,1,13,110,183,1,27,56,71,1,174,249,255,1,184,255,255,1, + 44,61,61,1,2,3,3,1,5,7,7,3,100,139,139,1,184,255,255,1, + 98,136,136,1,34,47,47,1,38,52,52,1,69,96,96,1,172,239,239,1, + 184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,11,181,251,251,1, + 176,244,244,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1, + 224,224,224,22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255,255, + 255,255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbreallookuplb: record size: integer; data: array[0..870] of byte end = + (size: 871; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 114,101,97,108,108,111,111,107,117,112,108,98,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,236,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,168,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0, + 22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,168,233,233, + 1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,5,181,232,246, + 1,186,203,242,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,103,143,143,1,51,71,71,1,184,255,255,6,84,116,116, + 1,33,46,46,1,32,45,45,1,72,100,100,1,181,251,251,1,184,255,255, + 1,188,241,255,1,194,211,252,1,54,54,69,1,117,117,149,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,175,242,242,1,75,104,104, + 1,13,18,18,1,51,71,71,1,184,255,255,5,142,197,197,1,40,55,55, + 1,182,252,252,1,183,254,254,1,54,75,75,1,125,161,170,1,196,214,255, + 1,169,169,214,1,45,45,57,1,13,13,17,1,117,117,149,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,142,197,197,1,92,127,127, + 1,126,175,175,1,51,71,71,1,184,255,255,5,162,224,224,1,155,215,215, + 1,184,255,255,1,188,241,255,1,81,88,105,1,98,98,124,1,201,201,255, + 1,114,114,145,1,135,135,171,1,84,84,106,1,117,117,149,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132,183,183, + 1,51,71,71,1,184,255,255,6,188,241,255,1,196,214,255,1,164,164,208, + 1,19,19,24,1,172,172,218,1,201,201,255,3,84,84,106,1,117,117,149, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 2,132,183,183,1,51,71,71,1,184,255,255,4,188,241,255,1,196,214,255, + 1,201,201,255,1,158,158,200,1,20,20,26,1,142,142,180,1,201,201,255, + 4,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,184,255,255, + 2,188,241,255,1,196,214,255,1,201,201,255,2,151,151,191,1,22,22,28, + 1,151,151,192,1,201,201,255,5,84,84,106,1,117,117,149,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132,183,183, + 1,51,71,71,1,188,241,255,1,196,214,255,1,197,197,250,1,177,177,225, + 1,201,201,255,1,169,169,215,1,22,22,28,1,168,168,213,1,201,201,255, + 6,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,2,135,173,183,1,55,60,71,1,201,201,255, + 2,164,164,208,1,12,12,15,1,201,201,255,1,74,74,94,1,2,2,2, + 1,6,6,7,3,84,84,106,1,201,201,255,3,84,84,106,1,117,117,149, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,188,241,255, + 1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255, + 255,255,255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbreallookupdb: record size: integer; data: array[0..898] of byte end = + (size: 899; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 114,101,97,108,108,111,111,107,117,112,100,98,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,8,3,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,196,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0, + 22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,168,233,233, + 1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,3,174,249,255, + 1,97,202,255,1,17,148,246,1,17,145,242,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,2,103,143,143,1,51,71,71, + 1,184,255,255,6,84,116,116,1,33,46,46,1,32,45,45,1,72,100,100, + 1,171,245,251,1,97,202,255,1,18,153,255,1,18,151,252,1,26,55,69, + 1,102,145,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184,255,255, + 5,142,197,197,1,40,55,55,1,182,252,252,1,173,248,254,1,29,59,75, + 1,12,102,170,1,18,153,255,1,81,170,214,1,39,56,57,1,12,17,17, + 1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,142,197,197,1,92,127,127,1,126,175,175,1,51,71,71,1,184,255,255, + 5,162,224,224,1,147,210,215,1,97,202,255,1,18,153,255,1,7,63,105, + 1,47,98,124,1,174,249,255,1,105,145,145,1,123,171,171,1,76,106,106, + 1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,132,183,183,1,51,71,71,1,184,255,255,4,174,249,255, + 1,97,202,255,1,18,153,255,2,79,165,208,1,16,23,24,1,157,218,218, + 1,184,255,255,3,76,106,106,1,108,149,149,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,2,132,183,183,1,51,71,71, + 1,184,255,255,2,174,249,255,1,97,202,255,1,18,153,255,2,97,202,255, + 1,136,195,200,1,19,26,26,1,130,180,180,1,184,255,255,4,76,106,106, + 1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,132,183,183,1,51,71,71,1,174,249,255,1,97,202,255, + 1,18,153,255,2,97,202,255,1,174,249,255,1,138,191,191,1,20,28,28, + 1,139,192,192,1,184,255,255,5,76,106,106,1,108,149,149,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,125,179,183, + 1,27,56,71,1,18,153,255,2,95,198,250,1,154,220,225,1,184,255,255, + 1,155,215,215,1,20,28,28,1,154,213,213,1,184,255,255,6,76,106,106, + 1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,174,249,255,1,97,202,255,1,13,110,183,1,5,43,71,1,97,202,255, + 1,174,249,255,1,150,208,208,1,11,15,15,1,184,255,255,1,68,94,94, + 1,1,2,2,1,5,7,7,3,76,106,106,1,184,255,255,3,76,106,106, + 1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,16,224,224,224, + 1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,208,208,208, + 240,12,0,0,0,255,255,255,255,255,255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbdatetimelookuplb: record size: integer; data: array[0..870] of byte end = + (size: 871; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,108,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,232,2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,164,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1,184,255,255, + 6,173,240,240,1,167,231,231,5,175,224,237,1,196,214,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127,176,176, + 1,5,7,7,1,22,31,31,1,19,27,27,1,5,7,7,1,60,83,83, + 1,168,233,233,1,184,255,255,4,80,111,111,1,22,31,31,2,1,1,1, + 1,21,26,28,1,24,26,31,1,67,67,85,1,201,201,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127,176,176, + 1,45,63,63,1,184,255,255,2,180,250,250,1,66,92,92,1,56,78,78, + 1,184,255,255,6,188,241,255,1,8,8,10,1,181,181,229,1,201,201,255, + 3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,127,176,176,1,45,63,63,1,184,255,255,3,175,242,242,1,1,2,2, + 1,162,224,224,1,184,255,255,1,29,40,40,1,165,228,228,1,188,241,255, + 1,196,214,255,1,201,201,255,1,8,8,10,1,181,181,229,1,201,201,255, + 3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1,128,178,178, + 1,184,255,255,1,136,174,184,1,189,206,246,1,201,201,255,3,8,8,10, + 1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255, + 4,31,43,43,1,132,169,179,1,196,214,255,1,201,201,255,5,8,8,10, + 1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255, + 3,177,227,240,1,7,8,9,1,174,174,221,1,201,201,255,6,8,8,10, + 1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255, + 1,188,241,255,1,178,195,232,1,69,69,88,1,64,64,81,1,201,201,255, + 2,177,177,224,1,198,198,251,1,201,201,255,3,8,8,10,1,181,181,229, + 1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,127,176,176,1,1,1,1,1,5,6,7,1,6,6,7, + 1,17,17,22,1,78,78,99,1,192,192,243,1,201,201,255,2,1,1,1, + 1,175,175,222,1,201,201,255,3,8,8,10,1,181,181,229,1,201,201,255, + 3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,188,241,255, + 1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255, + 255,255,255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbdatetimelookupdb: record size: integer; data: array[0..926] of byte end = + (size: 927; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,100,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,32,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,220,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1,184,255,255, + 6,173,240,240,1,167,231,231,3,158,226,231,1,88,183,231,1,17,142,237, + 1,18,153,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,127,176,176,1,5,7,7,1,22,31,31,1,19,27,27, + 1,5,7,7,1,60,83,83,1,168,233,233,1,184,255,255,4,80,111,111, + 1,22,31,31,1,21,30,31,1,0,1,1,1,2,17,28,1,2,19,31, + 1,32,67,85,1,174,249,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255, + 2,180,250,250,1,66,92,92,1,56,78,78,1,184,255,255,4,174,249,255, + 1,97,202,255,1,18,153,255,1,1,6,10,1,87,181,229,1,174,249,255, + 1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,3,175,242,242, + 1,1,2,2,1,162,224,224,1,184,255,255,1,27,39,40,1,87,181,228, + 1,18,153,255,2,97,202,255,1,7,10,10,1,165,229,229,1,184,255,255, + 3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1,121,174,178, + 1,97,202,255,1,13,110,184,1,17,148,246,1,97,202,255,1,174,249,255, + 1,184,255,255,1,7,10,10,1,165,229,229,1,184,255,255,3,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127,176,176, + 1,45,63,63,1,184,255,255,3,174,249,255,1,16,34,43,1,13,107,179, + 1,18,153,255,1,97,202,255,1,174,249,255,1,184,255,255,3,7,10,10, + 1,165,229,229,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255, + 1,174,249,255,1,97,202,255,1,17,144,240,1,1,5,9,1,84,175,221, + 1,174,249,255,1,184,255,255,5,7,10,10,1,165,229,229,1,184,255,255, + 3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,127,176,176,1,43,62,63,1,97,202,255,1,18,153,255,1,16,139,232, + 1,33,70,88,1,55,79,81,1,184,255,255,2,162,224,224,1,181,251,251, + 1,184,255,255,3,7,10,10,1,165,229,229,1,184,255,255,3,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,67,139,176, + 1,0,1,1,1,0,4,7,1,3,6,7,1,15,21,22,1,71,99,99, + 1,175,243,243,1,184,255,255,2,1,1,1,1,160,222,222,1,184,255,255, + 3,7,10,10,1,165,229,229,1,184,255,255,3,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,18,153,255,2,97,202,255,1,174,249,255, + 1,184,255,255,16,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224, + 22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255,255,255,255,255, + 81,0,0,0,240,0,0) + ); + +const + objdata_tdbstringlookup64lb: record size: integer; data: array[0..1466] of byte end = + (size: 1467; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,54,52,108,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,60,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,140,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 7,176,244,244,1,175,243,243,1,184,255,255,9,188,241,255,1,196,214,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 7,98,136,136,1,92,127,127,1,184,255,255,7,188,241,255,1,196,214,255, + 1,201,201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,188,241,255, + 1,196,214,255,1,201,201,255,4,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,151,209,209,1,45,62,62,1,26,36,36, + 1,22,31,31,1,113,156,156,1,184,255,255,1,98,136,136,1,63,87,87, + 1,61,85,85,1,22,30,30,1,95,131,131,1,188,241,255,1,196,214,255, + 1,137,137,174,1,37,37,47,1,35,35,45,1,97,97,123,1,201,201,255, + 2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,63,88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17,17, + 1,184,255,255,1,98,136,136,1,19,27,27,1,160,222,222,1,170,217,230, + 1,27,29,35,1,149,149,189,1,171,171,217,1,15,15,19,1,169,169,214, + 1,198,198,251,1,56,56,71,1,153,153,194,1,201,201,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254,254, + 1,141,196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,184,255,255, + 1,98,136,136,1,77,98,104,1,196,214,255,1,201,201,255,1,88,88,112, + 1,97,97,123,1,125,125,158,1,61,61,78,1,201,201,255,5,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76,76, + 2,109,151,151,1,142,197,197,1,0,0,0,1,188,241,255,1,105,114,136, + 1,95,95,121,1,201,201,255,2,94,94,119,1,95,95,121,1,114,114,144, + 1,70,70,89,1,201,201,255,2,191,191,242,1,193,193,245,1,201,201,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,179,248,248, + 1,4,6,6,1,172,239,239,1,184,255,255,1,124,159,168,1,0,0,0, + 1,198,198,251,1,107,107,136,1,42,42,53,1,189,189,240,1,193,193,245, + 1,32,32,40,1,144,144,183,1,157,157,199,1,20,20,25,1,192,192,243, + 1,201,201,255,1,68,68,86,1,135,135,171,1,201,201,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,89,123,123, + 1,36,46,49,1,51,56,67,1,79,79,100,1,22,22,28,1,176,176,223, + 1,107,107,136,1,65,65,82,1,54,54,68,1,38,38,48,1,110,110,139, + 1,201,201,255,2,117,117,148,1,42,42,53,1,44,44,56,1,76,76,96, + 1,200,200,254,1,201,201,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,188,241,255,1,196,214,255,1,194,194,246,1,195,195,247, + 1,201,201,255,5,199,199,253,1,196,196,249,1,201,201,255,4,200,200,254, + 1,194,194,246,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208,208,208, + 6,0,0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0,0,0, + 2,208,208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0,0,0, + 3,208,208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208,208,208, + 13,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0,0,0, + 2,208,208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208,208,208, + 1,0,0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0,0,0, + 2,208,208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0,0,0, + 7,1,1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0,0,0, + 14,86,86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7,7,7, + 1,0,0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18,18,18, + 1,225,225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95,95,95, + 1,0,0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0,0,0, + 13,95,95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0,0,0, + 4,175,175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124,124,124, + 1,183,183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19,19,19, + 1,0,0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240,240,240, + 1,0,0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0,0,0, + 1,147,147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8,8,8, + 1,15,15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161,161,161, + 1,0,0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234,234,234, + 1,216,216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0,0,0, + 12,39,39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163,163,163, + 1,123,123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241,241,241, + 1,16,16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210,210,210, + 1,178,178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240,240,240, + 1,0,0,0,32,0,0) + ); + +const + objdata_tdbstringlookup64db: record size: integer; data: array[0..1486] of byte end = + (size: 1487; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,54,52,100,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,80,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,160,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 7,176,244,244,1,175,243,243,1,184,255,255,7,174,249,255,1,97,202,255, + 1,18,153,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,174,249,255, + 1,97,202,255,1,18,153,255,2,97,202,255,1,174,249,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,98,136,136, + 1,92,127,127,1,184,255,255,3,174,249,255,1,97,202,255,1,18,153,255, + 2,97,202,255,1,174,249,255,1,184,255,255,2,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,1,151,209,209,1,45,62,62, + 1,26,36,36,1,22,31,31,1,113,156,156,1,184,255,255,1,98,136,136, + 1,63,87,87,1,61,85,85,1,20,29,30,1,50,104,131,1,18,153,255, + 2,66,138,174,1,32,46,47,1,32,45,45,1,89,123,123,1,184,255,255, + 2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,63,88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17,17, + 1,184,255,255,1,98,136,136,1,18,26,27,1,84,176,222,1,16,138,230, + 1,2,21,35,1,72,150,189,1,148,212,217,1,14,19,19,1,154,214,214, + 1,181,251,251,1,51,71,71,1,140,194,194,1,184,255,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254,254, + 1,141,196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,174,249,255, + 1,52,108,136,1,7,62,104,1,18,153,255,1,97,202,255,1,76,109,112, + 1,89,123,123,1,114,158,158,1,56,78,78,1,184,255,255,5,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76,76, + 2,109,151,151,1,134,192,197,1,0,0,0,1,18,153,255,1,10,82,136, + 1,46,96,121,1,174,249,255,1,184,255,255,1,86,119,119,1,87,121,121, + 1,104,144,144,1,64,89,89,1,184,255,255,2,175,242,242,1,177,245,245, + 1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,179,248,248,1,4,6,6,1,163,233,239,1,97,202,255,1,12,101,168, + 1,0,0,0,1,95,199,251,1,93,133,136,1,38,53,53,1,173,240,240, + 1,177,245,245,1,29,40,40,1,132,183,183,1,144,199,199,1,18,25,25, + 1,175,243,243,1,184,255,255,1,62,86,86,1,123,171,171,1,184,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255, + 1,47,97,123,1,3,29,49,1,5,40,67,1,38,79,100,1,19,27,28, + 1,161,223,223,1,98,136,136,1,59,82,82,1,49,68,68,1,35,48,48, + 1,100,139,139,1,184,255,255,2,107,148,148,1,38,53,53,1,40,56,56, + 1,69,96,96,1,183,254,254,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,18,153,255,2,94,195,246,1,169,241,247, + 1,184,255,255,5,183,253,253,1,180,249,249,1,184,255,255,4,183,254,254, + 1,178,246,246,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208,208,208, + 6,0,0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0,0,0, + 2,208,208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0,0,0, + 3,208,208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208,208,208, + 13,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0,0,0, + 2,208,208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208,208,208, + 1,0,0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0,0,0, + 2,208,208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0,0,0, + 7,1,1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0,0,0, + 14,86,86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7,7,7, + 1,0,0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18,18,18, + 1,225,225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95,95,95, + 1,0,0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0,0,0, + 13,95,95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0,0,0, + 4,175,175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124,124,124, + 1,183,183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19,19,19, + 1,0,0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240,240,240, + 1,0,0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0,0,0, + 1,147,147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8,8,8, + 1,15,15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161,161,161, + 1,0,0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234,234,234, + 1,216,216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0,0,0, + 12,39,39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163,163,163, + 1,123,123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241,241,241, + 1,16,16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210,210,210, + 1,178,178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240,240,240, + 1,0,0,0,32,0,0) + ); + +const + objdata_tdbintegerlookup64lb: record size: integer; data: array[0..1475] of byte end = + (size: 1476; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,54,52,108,98,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,68,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,148,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128, + 128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,4,168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184,255, + 255,4,182,252,252,1,178,246,246,1,184,255,255,1,188,241,255,1,196,214, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,3,103,143,143,1,51,71,71,1,184,255,255,2,181,251,251,1,69,95, + 95,1,35,48,48,1,31,43,43,1,87,121,121,1,184,255,255,2,105,145, + 145,1,34,47,47,1,33,43,45,1,79,86,103,1,198,198,251,1,201,201, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,1,175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184,255, + 255,2,118,164,164,1,62,86,86,1,184,255,255,1,180,250,250,1,32,44, + 44,1,147,204,204,1,159,221,221,1,23,29,31,1,190,207,247,1,201,201, + 255,1,43,43,55,1,142,142,180,1,201,201,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,184,255,255,1,142,197,197,1,92,127, + 127,1,126,175,175,1,51,71,71,1,184,255,255,2,154,214,214,1,162,225, + 225,1,184,255,255,2,51,71,71,1,116,149,158,1,196,214,255,1,188,188, + 238,1,201,201,255,1,199,199,252,1,32,32,40,1,143,143,181,1,201,201, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,3,132,183,183,1,51,71,71,1,184,255,255,5,137,176,186,1,21,23, + 27,1,187,187,237,1,201,201,255,2,139,139,176,1,19,19,24,1,66,66, + 84,1,201,201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,184,255,255,3,132,183,183,1,51,71,71,1,184,255,255,3,188,241, + 255,1,135,148,176,1,20,20,26,1,160,160,203,1,201,201,255,3,188,188, + 238,1,163,163,207,1,50,50,63,1,114,114,144,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183, + 183,1,51,71,71,1,184,255,255,1,188,241,255,1,196,214,255,1,130,130, + 165,1,26,26,33,1,168,168,213,1,201,201,255,2,188,188,238,1,175,175, + 222,1,201,201,255,2,137,137,174,1,49,49,62,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183, + 183,1,52,67,71,1,196,214,255,1,201,201,255,1,148,148,188,1,31,31, + 39,1,181,181,229,1,201,201,255,3,169,169,214,1,27,27,34,1,197,197, + 250,1,201,201,255,1,81,81,103,1,107,107,136,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,188,241, + 255,1,141,154,183,1,56,56,71,1,201,201,255,2,48,48,61,1,2,2, + 3,1,6,6,7,3,110,110,139,1,201,201,255,1,107,107,136,1,37,37, + 47,1,41,41,52,1,76,76,96,1,188,188,239,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,188,241,255,1,196,214, + 255,1,201,201,255,13,198,198,251,1,192,192,244,1,201,201,255,3,224,224, + 224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,208,208, + 208,7,0,0,0,2,208,208,208,6,0,0,0,1,208,208,208,14,0,0, + 0,5,208,208,208,3,0,0,0,2,208,208,208,13,0,0,0,3,208,208, + 208,1,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,13,0,0, + 0,4,208,208,208,4,0,0,0,3,208,208,208,13,0,0,0,6,208,208, + 208,1,0,0,0,4,208,208,208,13,0,0,0,3,208,208,208,1,0,0, + 0,7,208,208,208,13,0,0,0,2,208,208,208,2,0,0,0,8,208,208, + 208,12,0,0,0,3,208,208,208,1,0,0,0,8,208,208,208,13,0,0, + 0,5,208,208,208,3,0,0,0,2,208,208,208,32,120,1,0,0,255,255, + 255,255,255,255,255,81,0,0,0,7,1,1,1,1,13,13,13,1,0,0, + 0,6,20,20,20,1,0,0,0,14,86,86,86,1,218,218,218,1,205,205, + 205,1,181,181,181,1,7,7,7,1,0,0,0,3,74,74,74,1,239,239, + 239,1,0,0,0,13,18,18,18,1,225,225,225,1,29,29,29,1,0,0, + 0,1,148,148,148,1,95,95,95,1,0,0,0,2,21,21,21,1,210,210, + 210,1,240,240,240,1,0,0,0,13,95,95,95,1,155,155,155,1,11,11, + 11,1,37,37,37,1,0,0,0,4,175,175,175,1,80,80,80,1,240,240, + 240,1,0,0,0,13,124,124,124,1,183,183,183,1,218,218,218,1,199,199, + 199,1,191,191,191,1,19,19,19,1,0,0,0,1,101,101,101,1,142,142, + 142,1,15,15,15,1,240,240,240,1,0,0,0,13,135,135,135,1,225,225, + 225,1,5,5,5,1,0,0,0,1,147,147,147,1,109,109,109,1,36,36, + 36,1,201,201,201,1,8,8,8,1,15,15,15,1,240,240,240,1,0,0, + 0,13,110,110,110,1,161,161,161,1,0,0,0,2,85,85,85,1,174,174, + 174,1,141,141,141,1,234,234,234,1,216,216,216,1,218,218,218,1,253,253, + 253,1,216,216,216,1,0,0,0,12,39,39,39,1,220,220,220,1,15,15, + 15,1,0,0,0,1,163,163,163,1,123,123,123,1,8,8,8,1,16,16, + 16,2,30,30,30,1,241,241,241,1,16,16,16,1,0,0,0,13,108,108, + 108,1,219,219,219,1,210,210,210,1,178,178,178,1,8,8,8,1,0,0, + 0,3,15,15,15,1,240,240,240,1,0,0,0,32,0,0) + ); + +const + objdata_tdbintegerlookup64db: record size: integer; data: array[0..1507] of byte end = + (size: 1508; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,54,52,100,98,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,100,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,180,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128, + 128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,4,168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184,255, + 255,4,182,252,252,1,168,240,246,1,97,202,255,1,18,153,255,2,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,103,143, + 143,1,51,71,71,1,184,255,255,2,181,251,251,1,69,95,95,1,35,48, + 48,1,31,43,43,1,87,121,121,1,184,255,255,2,99,142,145,1,18,37, + 47,1,3,27,45,1,7,62,103,1,95,199,251,1,174,249,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,175,242, + 242,1,75,104,104,1,13,18,18,1,51,71,71,1,184,255,255,2,118,164, + 164,1,62,86,86,1,184,255,255,1,180,250,250,1,32,44,44,1,139,199, + 204,1,84,175,221,1,2,19,31,1,17,148,247,1,97,202,255,1,38,54, + 55,1,130,180,180,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,184,255,255,1,142,197,197,1,92,127,127,1,126,175, + 175,1,51,71,71,1,184,255,255,2,154,214,214,1,162,225,225,1,184,255, + 255,1,174,249,255,1,27,56,71,1,11,95,158,1,18,153,255,1,91,189, + 238,1,174,249,255,1,182,252,252,1,29,40,40,1,131,181,181,1,184,255, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,3,132,183,183,1,51,71,71,1,184,255,255,3,174,249,255,1,97,202, + 255,1,13,112,186,1,2,16,27,1,90,188,237,1,174,249,255,1,184,255, + 255,1,127,176,176,1,17,24,24,1,61,84,84,1,184,255,255,2,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183, + 183,1,51,71,71,1,184,255,255,1,174,249,255,1,97,202,255,1,18,153, + 255,1,12,106,176,1,10,21,26,1,139,198,203,1,184,255,255,3,172,238, + 238,1,149,207,207,1,45,63,63,1,104,144,144,1,184,255,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183, + 183,1,48,69,71,1,97,202,255,1,18,153,255,2,63,131,165,1,23,32, + 33,1,154,213,213,1,184,255,255,2,172,238,238,1,160,222,222,1,184,255, + 255,2,126,174,174,1,45,62,62,1,184,255,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,184,255,255,2,174,249,255,1,70,145, + 183,1,5,43,71,1,18,153,255,1,97,202,255,1,128,184,188,1,28,39, + 39,1,165,229,229,1,184,255,255,3,154,214,214,1,25,34,34,1,180,250, + 250,1,184,255,255,1,74,103,103,1,98,136,136,1,184,255,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,97,202, + 255,1,18,153,255,1,13,110,183,1,27,56,71,1,174,249,255,1,184,255, + 255,1,44,61,61,1,2,3,3,1,5,7,7,3,100,139,139,1,184,255, + 255,1,98,136,136,1,34,47,47,1,38,52,52,1,69,96,96,1,172,239, + 239,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,11,181,251, + 251,1,176,244,244,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128, + 128,1,224,224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208,208, + 208,6,0,0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0,0, + 0,2,208,208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208,208, + 208,2,0,0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0,0, + 0,3,208,208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208,208, + 208,13,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0,0, + 0,2,208,208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208,208, + 208,1,0,0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0,0, + 0,2,208,208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0,0, + 0,7,1,1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0,0, + 0,14,86,86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7,7, + 7,1,0,0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18,18, + 18,1,225,225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95,95, + 95,1,0,0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0,0, + 0,13,95,95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0,0, + 0,4,175,175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124,124, + 124,1,183,183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19,19, + 19,1,0,0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240,240, + 240,1,0,0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0,0, + 0,1,147,147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8,8, + 8,1,15,15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161,161, + 161,1,0,0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234,234, + 234,1,216,216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0,0, + 0,12,39,39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163,163, + 163,1,123,123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241,241, + 241,1,16,16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210,210, + 210,1,178,178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240,240, + 240,1,0,0,0,32,0,0) + ); + +const + objdata_tdbreallookup64lb: record size: integer; data: array[0..1388] of byte end = + (size: 1389; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,98, + 114,101,97,108,108,111,111,107,117,112,54,52,108,98,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,64, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,168, + 233,233,1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,5,181, + 232,246,1,186,203,242,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,2,103,143,143,1,51,71,71,1,184,255,255,6,84, + 116,116,1,33,46,46,1,32,45,45,1,72,100,100,1,181,251,251,1,184, + 255,255,1,188,241,255,1,194,211,252,1,54,54,69,1,117,117,149,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,175,242,242,1,75, + 104,104,1,13,18,18,1,51,71,71,1,184,255,255,5,142,197,197,1,40, + 55,55,1,182,252,252,1,183,254,254,1,54,75,75,1,125,161,170,1,196, + 214,255,1,169,169,214,1,45,45,57,1,13,13,17,1,117,117,149,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,142,197,197,1,92, + 127,127,1,126,175,175,1,51,71,71,1,184,255,255,5,162,224,224,1,155, + 215,215,1,184,255,255,1,188,241,255,1,81,88,105,1,98,98,124,1,201, + 201,255,1,114,114,145,1,135,135,171,1,84,84,106,1,117,117,149,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132, + 183,183,1,51,71,71,1,184,255,255,6,188,241,255,1,196,214,255,1,164, + 164,208,1,19,19,24,1,172,172,218,1,201,201,255,3,84,84,106,1,117, + 117,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,2,132,183,183,1,51,71,71,1,184,255,255,4,188,241,255,1,196, + 214,255,1,201,201,255,1,158,158,200,1,20,20,26,1,142,142,180,1,201, + 201,255,4,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,184, + 255,255,2,188,241,255,1,196,214,255,1,201,201,255,2,151,151,191,1,22, + 22,28,1,151,151,192,1,201,201,255,5,84,84,106,1,117,117,149,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132, + 183,183,1,51,71,71,1,188,241,255,1,196,214,255,1,197,197,250,1,177, + 177,225,1,201,201,255,1,169,169,215,1,22,22,28,1,168,168,213,1,201, + 201,255,6,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,2,135,173,183,1,55,60,71,1,201, + 201,255,2,164,164,208,1,12,12,15,1,201,201,255,1,74,74,94,1,2, + 2,2,1,6,6,7,3,84,84,106,1,201,201,255,3,84,84,106,1,117, + 117,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,188, + 241,255,1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1,128, + 128,128,1,224,224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208, + 208,208,6,0,0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0, + 0,0,2,208,208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208, + 208,208,2,0,0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0, + 0,0,3,208,208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208, + 208,208,13,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0, + 0,0,2,208,208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208, + 208,208,1,0,0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0, + 0,0,2,208,208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0, + 0,0,7,1,1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0, + 0,0,14,86,86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7, + 7,7,1,0,0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18, + 18,18,1,225,225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95, + 95,95,1,0,0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0, + 0,0,13,95,95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0, + 0,0,4,175,175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124, + 124,124,1,183,183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19, + 19,19,1,0,0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240, + 240,240,1,0,0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0, + 0,0,1,147,147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8, + 8,8,1,15,15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161, + 161,161,1,0,0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234, + 234,234,1,216,216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0, + 0,0,12,39,39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163, + 163,163,1,123,123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241, + 241,241,1,16,16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210, + 210,210,1,178,178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240, + 240,240,1,0,0,0,32,0,0) + ); + +const + objdata_tdbreallookup64db: record size: integer; data: array[0..1416] of byte end = + (size: 1417; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,98, + 114,101,97,108,108,111,111,107,117,112,54,52,100,98,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,12, + 5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,92, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,168, + 233,233,1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,3,174, + 249,255,1,97,202,255,1,17,148,246,1,17,145,242,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,103,143,143,1,51, + 71,71,1,184,255,255,6,84,116,116,1,33,46,46,1,32,45,45,1,72, + 100,100,1,171,245,251,1,97,202,255,1,18,153,255,1,18,151,252,1,26, + 55,69,1,102,145,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184, + 255,255,5,142,197,197,1,40,55,55,1,182,252,252,1,173,248,254,1,29, + 59,75,1,12,102,170,1,18,153,255,1,81,170,214,1,39,56,57,1,12, + 17,17,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,142,197,197,1,92,127,127,1,126,175,175,1,51,71,71,1,184, + 255,255,5,162,224,224,1,147,210,215,1,97,202,255,1,18,153,255,1,7, + 63,105,1,47,98,124,1,174,249,255,1,105,145,145,1,123,171,171,1,76, + 106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,184,255,255,4,174, + 249,255,1,97,202,255,1,18,153,255,2,79,165,208,1,16,23,24,1,157, + 218,218,1,184,255,255,3,76,106,106,1,108,149,149,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132,183,183,1,51, + 71,71,1,184,255,255,2,174,249,255,1,97,202,255,1,18,153,255,2,97, + 202,255,1,136,195,200,1,19,26,26,1,130,180,180,1,184,255,255,4,76, + 106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,174,249,255,1,97, + 202,255,1,18,153,255,2,97,202,255,1,174,249,255,1,138,191,191,1,20, + 28,28,1,139,192,192,1,184,255,255,5,76,106,106,1,108,149,149,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,125, + 179,183,1,27,56,71,1,18,153,255,2,95,198,250,1,154,220,225,1,184, + 255,255,1,155,215,215,1,20,28,28,1,154,213,213,1,184,255,255,6,76, + 106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,174,249,255,1,97,202,255,1,13,110,183,1,5,43,71,1,97, + 202,255,1,174,249,255,1,150,208,208,1,11,15,15,1,184,255,255,1,68, + 94,94,1,1,2,2,1,5,7,7,3,76,106,106,1,184,255,255,3,76, + 106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,16,224, + 224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,208, + 208,208,7,0,0,0,2,208,208,208,6,0,0,0,1,208,208,208,14,0, + 0,0,5,208,208,208,3,0,0,0,2,208,208,208,13,0,0,0,3,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,13,0, + 0,0,4,208,208,208,4,0,0,0,3,208,208,208,13,0,0,0,6,208, + 208,208,1,0,0,0,4,208,208,208,13,0,0,0,3,208,208,208,1,0, + 0,0,7,208,208,208,13,0,0,0,2,208,208,208,2,0,0,0,8,208, + 208,208,12,0,0,0,3,208,208,208,1,0,0,0,8,208,208,208,13,0, + 0,0,5,208,208,208,3,0,0,0,2,208,208,208,32,120,1,0,0,255, + 255,255,255,255,255,255,81,0,0,0,7,1,1,1,1,13,13,13,1,0, + 0,0,6,20,20,20,1,0,0,0,14,86,86,86,1,218,218,218,1,205, + 205,205,1,181,181,181,1,7,7,7,1,0,0,0,3,74,74,74,1,239, + 239,239,1,0,0,0,13,18,18,18,1,225,225,225,1,29,29,29,1,0, + 0,0,1,148,148,148,1,95,95,95,1,0,0,0,2,21,21,21,1,210, + 210,210,1,240,240,240,1,0,0,0,13,95,95,95,1,155,155,155,1,11, + 11,11,1,37,37,37,1,0,0,0,4,175,175,175,1,80,80,80,1,240, + 240,240,1,0,0,0,13,124,124,124,1,183,183,183,1,218,218,218,1,199, + 199,199,1,191,191,191,1,19,19,19,1,0,0,0,1,101,101,101,1,142, + 142,142,1,15,15,15,1,240,240,240,1,0,0,0,13,135,135,135,1,225, + 225,225,1,5,5,5,1,0,0,0,1,147,147,147,1,109,109,109,1,36, + 36,36,1,201,201,201,1,8,8,8,1,15,15,15,1,240,240,240,1,0, + 0,0,13,110,110,110,1,161,161,161,1,0,0,0,2,85,85,85,1,174, + 174,174,1,141,141,141,1,234,234,234,1,216,216,216,1,218,218,218,1,253, + 253,253,1,216,216,216,1,0,0,0,12,39,39,39,1,220,220,220,1,15, + 15,15,1,0,0,0,1,163,163,163,1,123,123,123,1,8,8,8,1,16, + 16,16,2,30,30,30,1,241,241,241,1,16,16,16,1,0,0,0,13,108, + 108,108,1,219,219,219,1,210,210,210,1,178,178,178,1,8,8,8,1,0, + 0,0,3,15,15,15,1,240,240,240,1,0,0,0,32,0,0) + ); + +const + objdata_tdbdatetimelookup64lb: record size: integer; data: array[0..1388] of byte end = + (size: 1389; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,54,52,108,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,236,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,60,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1,184, + 255,255,6,173,240,240,1,167,231,231,5,175,224,237,1,196,214,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127, + 176,176,1,5,7,7,1,22,31,31,1,19,27,27,1,5,7,7,1,60, + 83,83,1,168,233,233,1,184,255,255,4,80,111,111,1,22,31,31,2,1, + 1,1,1,21,26,28,1,24,26,31,1,67,67,85,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127, + 176,176,1,45,63,63,1,184,255,255,2,180,250,250,1,66,92,92,1,56, + 78,78,1,184,255,255,6,188,241,255,1,8,8,10,1,181,181,229,1,201, + 201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,127,176,176,1,45,63,63,1,184,255,255,3,175,242,242,1,1, + 2,2,1,162,224,224,1,184,255,255,1,29,40,40,1,165,228,228,1,188, + 241,255,1,196,214,255,1,201,201,255,1,8,8,10,1,181,181,229,1,201, + 201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1,128, + 178,178,1,184,255,255,1,136,174,184,1,189,206,246,1,201,201,255,3,8, + 8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184, + 255,255,4,31,43,43,1,132,169,179,1,196,214,255,1,201,201,255,5,8, + 8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184, + 255,255,3,177,227,240,1,7,8,9,1,174,174,221,1,201,201,255,6,8, + 8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184, + 255,255,1,188,241,255,1,178,195,232,1,69,69,88,1,64,64,81,1,201, + 201,255,2,177,177,224,1,198,198,251,1,201,201,255,3,8,8,10,1,181, + 181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,1,127,176,176,1,1,1,1,1,5,6,7,1,6, + 6,7,1,17,17,22,1,78,78,99,1,192,192,243,1,201,201,255,2,1, + 1,1,1,175,175,222,1,201,201,255,3,8,8,10,1,181,181,229,1,201, + 201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,188, + 241,255,1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1,128, + 128,128,1,224,224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208, + 208,208,6,0,0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0, + 0,0,2,208,208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208, + 208,208,2,0,0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0, + 0,0,3,208,208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208, + 208,208,13,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0, + 0,0,2,208,208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208, + 208,208,1,0,0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0, + 0,0,2,208,208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0, + 0,0,7,1,1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0, + 0,0,14,86,86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7, + 7,7,1,0,0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18, + 18,18,1,225,225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95, + 95,95,1,0,0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0, + 0,0,13,95,95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0, + 0,0,4,175,175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124, + 124,124,1,183,183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19, + 19,19,1,0,0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240, + 240,240,1,0,0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0, + 0,0,1,147,147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8, + 8,8,1,15,15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161, + 161,161,1,0,0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234, + 234,234,1,216,216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0, + 0,0,12,39,39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163, + 163,163,1,123,123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241, + 241,241,1,16,16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210, + 210,210,1,178,178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240, + 240,240,1,0,0,0,32,0,0) + ); + +const + objdata_tdbdatetimelookup64db: record size: integer; data: array[0..1444] of byte end = + (size: 1445; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,54,52,100,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,36,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,116,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1,184, + 255,255,6,173,240,240,1,167,231,231,3,158,226,231,1,88,183,231,1,17, + 142,237,1,18,153,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,1,127,176,176,1,5,7,7,1,22,31,31,1,19, + 27,27,1,5,7,7,1,60,83,83,1,168,233,233,1,184,255,255,4,80, + 111,111,1,22,31,31,1,21,30,31,1,0,1,1,1,2,17,28,1,2, + 19,31,1,32,67,85,1,174,249,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184, + 255,255,2,180,250,250,1,66,92,92,1,56,78,78,1,184,255,255,4,174, + 249,255,1,97,202,255,1,18,153,255,1,1,6,10,1,87,181,229,1,174, + 249,255,1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,3,175, + 242,242,1,1,2,2,1,162,224,224,1,184,255,255,1,27,39,40,1,87, + 181,228,1,18,153,255,2,97,202,255,1,7,10,10,1,165,229,229,1,184, + 255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1,121, + 174,178,1,97,202,255,1,13,110,184,1,17,148,246,1,97,202,255,1,174, + 249,255,1,184,255,255,1,7,10,10,1,165,229,229,1,184,255,255,3,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127, + 176,176,1,45,63,63,1,184,255,255,3,174,249,255,1,16,34,43,1,13, + 107,179,1,18,153,255,1,97,202,255,1,174,249,255,1,184,255,255,3,7, + 10,10,1,165,229,229,1,184,255,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184, + 255,255,1,174,249,255,1,97,202,255,1,17,144,240,1,1,5,9,1,84, + 175,221,1,174,249,255,1,184,255,255,5,7,10,10,1,165,229,229,1,184, + 255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,127,176,176,1,43,62,63,1,97,202,255,1,18,153,255,1,16, + 139,232,1,33,70,88,1,55,79,81,1,184,255,255,2,162,224,224,1,181, + 251,251,1,184,255,255,3,7,10,10,1,165,229,229,1,184,255,255,3,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,67, + 139,176,1,0,1,1,1,0,4,7,1,3,6,7,1,15,21,22,1,71, + 99,99,1,175,243,243,1,184,255,255,2,1,1,1,1,160,222,222,1,184, + 255,255,3,7,10,10,1,165,229,229,1,184,255,255,3,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,18,153,255,2,97,202,255,1,174, + 249,255,1,184,255,255,16,224,224,224,1,255,255,255,1,128,128,128,1,224, + 224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208,208,208,6,0, + 0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0,0,0,2,208, + 208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208,208,208,2,0, + 0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0,0,0,3,208, + 208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208,208,208,13,0, + 0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0,0,0,2,208, + 208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208,208,208,1,0, + 0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0,0,0,2,208, + 208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0,0,0,7,1, + 1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0,0,0,14,86, + 86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7,7,7,1,0, + 0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18,18,18,1,225, + 225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95,95,95,1,0, + 0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0,0,0,13,95, + 95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0,0,0,4,175, + 175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124,124,124,1,183, + 183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19,19,19,1,0, + 0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240,240,240,1,0, + 0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0,0,0,1,147, + 147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8,8,8,1,15, + 15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161,161,161,1,0, + 0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234,234,234,1,216, + 216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0,0,0,12,39, + 39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163,163,163,1,123, + 123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241,241,241,1,16, + 16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210,210,210,1,178, + 178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240,240,240,1,0, + 0,0,32,0,0) + ); + +const + objdata_tdbstringlookupstrlb: record size: integer; data: array[0..1411] of byte end = + (size: 1412; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,115,116,114,108,98,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,4,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,124,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128, + 128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,7,176,244,244,1,175,243,243,1,184,255,255,9,188,241,255,1,196,214, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,7,98,136,136,1,92,127,127,1,184,255,255,7,188,241,255,1,196,214, + 255,1,201,201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,184,255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,188,241, + 255,1,196,214,255,1,201,201,255,4,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,184,255,255,1,151,209,209,1,45,62,62,1,26,36, + 36,1,22,31,31,1,113,156,156,1,184,255,255,1,98,136,136,1,63,87, + 87,1,61,85,85,1,22,30,30,1,95,131,131,1,188,241,255,1,196,214, + 255,1,137,137,174,1,37,37,47,1,35,35,45,1,97,97,123,1,201,201, + 255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,1,63,88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17, + 17,1,184,255,255,1,98,136,136,1,19,27,27,1,160,222,222,1,170,217, + 230,1,27,29,35,1,149,149,189,1,171,171,217,1,15,15,19,1,169,169, + 214,1,198,198,251,1,56,56,71,1,153,153,194,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254, + 254,1,141,196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,184,255, + 255,1,98,136,136,1,77,98,104,1,196,214,255,1,201,201,255,1,88,88, + 112,1,97,97,123,1,125,125,158,1,61,61,78,1,201,201,255,5,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76, + 76,2,109,151,151,1,142,197,197,1,0,0,0,1,188,241,255,1,105,114, + 136,1,95,95,121,1,201,201,255,2,94,94,119,1,95,95,121,1,114,114, + 144,1,70,70,89,1,201,201,255,2,191,191,242,1,193,193,245,1,201,201, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,179,248, + 248,1,4,6,6,1,172,239,239,1,184,255,255,1,124,159,168,1,0,0, + 0,1,198,198,251,1,107,107,136,1,42,42,53,1,189,189,240,1,193,193, + 245,1,32,32,40,1,144,144,183,1,157,157,199,1,20,20,25,1,192,192, + 243,1,201,201,255,1,68,68,86,1,135,135,171,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,89,123, + 123,1,36,46,49,1,51,56,67,1,79,79,100,1,22,22,28,1,176,176, + 223,1,107,107,136,1,65,65,82,1,54,54,68,1,38,38,48,1,110,110, + 139,1,201,201,255,2,117,117,148,1,42,42,53,1,44,44,56,1,76,76, + 96,1,200,200,254,1,201,201,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,188,241,255,1,196,214,255,1,194,194,246,1,195,195, + 247,1,201,201,255,5,199,199,253,1,196,196,249,1,201,201,255,4,200,200, + 254,1,194,194,246,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128, + 128,1,224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2,208,208, + 208,22,0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,7,208,208, + 208,1,0,0,0,2,208,208,208,13,0,0,0,2,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,5,208,208, + 208,1,0,0,0,5,208,208,208,32,80,1,0,0,255,255,255,255,255,255, + 255,81,0,0,0,35,45,45,45,1,105,105,105,1,0,0,0,22,104,104, + 104,1,143,143,143,1,0,0,0,16,15,15,15,1,182,182,182,1,223,223, + 223,1,213,213,213,1,84,84,84,1,30,30,30,1,218,218,218,1,227,227, + 227,1,107,107,107,1,106,106,106,1,141,141,141,1,231,231,231,1,116,116, + 116,1,0,0,0,11,106,106,106,1,156,156,156,1,0,0,0,1,41,41, + 41,1,165,165,165,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0, + 0,1,126,126,126,1,219,219,219,1,32,32,32,1,20,20,20,1,0,0, + 0,11,50,50,50,1,235,235,235,1,169,169,169,1,91,91,91,1,13,13, + 13,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0,0,1,126,126, + 126,1,147,147,147,1,0,0,0,14,21,21,21,1,103,103,103,1,185,185, + 185,1,223,223,223,1,9,9,9,1,104,104,104,1,143,143,143,1,0,0, + 0,1,126,126,126,1,129,129,129,1,0,0,0,13,93,93,93,1,130,130, + 130,1,0,0,0,1,4,4,4,1,236,236,236,1,33,33,33,1,97,97, + 97,1,151,151,151,1,0,0,0,1,126,126,126,1,129,129,129,1,0,0, + 0,13,14,14,14,1,191,191,191,1,199,199,199,1,218,218,218,1,143,143, + 143,1,0,0,0,1,47,47,47,1,237,237,237,1,140,140,140,1,126,126, + 126,1,129,129,129,1,0,0,0,32,0,0) + ); + +const + objdata_tdbstringlookupstrdb: record size: integer; data: array[0..1431] of byte end = + (size: 1432; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,115,116,114,100,98,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,24,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,144,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128, + 128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,7,176,244,244,1,175,243,243,1,184,255,255,7,174,249,255,1,97,202, + 255,1,18,153,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,184,255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,174,249, + 255,1,97,202,255,1,18,153,255,2,97,202,255,1,174,249,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,98,136, + 136,1,92,127,127,1,184,255,255,3,174,249,255,1,97,202,255,1,18,153, + 255,2,97,202,255,1,174,249,255,1,184,255,255,2,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,184,255,255,1,151,209,209,1,45,62, + 62,1,26,36,36,1,22,31,31,1,113,156,156,1,184,255,255,1,98,136, + 136,1,63,87,87,1,61,85,85,1,20,29,30,1,50,104,131,1,18,153, + 255,2,66,138,174,1,32,46,47,1,32,45,45,1,89,123,123,1,184,255, + 255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,1,63,88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17, + 17,1,184,255,255,1,98,136,136,1,18,26,27,1,84,176,222,1,16,138, + 230,1,2,21,35,1,72,150,189,1,148,212,217,1,14,19,19,1,154,214, + 214,1,181,251,251,1,51,71,71,1,140,194,194,1,184,255,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254, + 254,1,141,196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,174,249, + 255,1,52,108,136,1,7,62,104,1,18,153,255,1,97,202,255,1,76,109, + 112,1,89,123,123,1,114,158,158,1,56,78,78,1,184,255,255,5,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76, + 76,2,109,151,151,1,134,192,197,1,0,0,0,1,18,153,255,1,10,82, + 136,1,46,96,121,1,174,249,255,1,184,255,255,1,86,119,119,1,87,121, + 121,1,104,144,144,1,64,89,89,1,184,255,255,2,175,242,242,1,177,245, + 245,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,179,248,248,1,4,6,6,1,163,233,239,1,97,202,255,1,12,101, + 168,1,0,0,0,1,95,199,251,1,93,133,136,1,38,53,53,1,173,240, + 240,1,177,245,245,1,29,40,40,1,132,183,183,1,144,199,199,1,18,25, + 25,1,175,243,243,1,184,255,255,1,62,86,86,1,123,171,171,1,184,255, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249, + 255,1,47,97,123,1,3,29,49,1,5,40,67,1,38,79,100,1,19,27, + 28,1,161,223,223,1,98,136,136,1,59,82,82,1,49,68,68,1,35,48, + 48,1,100,139,139,1,184,255,255,2,107,148,148,1,38,53,53,1,40,56, + 56,1,69,96,96,1,183,254,254,1,184,255,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,18,153,255,2,94,195,246,1,169,241, + 247,1,184,255,255,5,183,253,253,1,180,249,249,1,184,255,255,4,183,254, + 254,1,178,246,246,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128, + 128,1,224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2,208,208, + 208,22,0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,7,208,208, + 208,1,0,0,0,2,208,208,208,13,0,0,0,2,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,5,208,208, + 208,1,0,0,0,5,208,208,208,32,80,1,0,0,255,255,255,255,255,255, + 255,81,0,0,0,35,45,45,45,1,105,105,105,1,0,0,0,22,104,104, + 104,1,143,143,143,1,0,0,0,16,15,15,15,1,182,182,182,1,223,223, + 223,1,213,213,213,1,84,84,84,1,30,30,30,1,218,218,218,1,227,227, + 227,1,107,107,107,1,106,106,106,1,141,141,141,1,231,231,231,1,116,116, + 116,1,0,0,0,11,106,106,106,1,156,156,156,1,0,0,0,1,41,41, + 41,1,165,165,165,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0, + 0,1,126,126,126,1,219,219,219,1,32,32,32,1,20,20,20,1,0,0, + 0,11,50,50,50,1,235,235,235,1,169,169,169,1,91,91,91,1,13,13, + 13,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0,0,1,126,126, + 126,1,147,147,147,1,0,0,0,14,21,21,21,1,103,103,103,1,185,185, + 185,1,223,223,223,1,9,9,9,1,104,104,104,1,143,143,143,1,0,0, + 0,1,126,126,126,1,129,129,129,1,0,0,0,13,93,93,93,1,130,130, + 130,1,0,0,0,1,4,4,4,1,236,236,236,1,33,33,33,1,97,97, + 97,1,151,151,151,1,0,0,0,1,126,126,126,1,129,129,129,1,0,0, + 0,13,14,14,14,1,191,191,191,1,199,199,199,1,218,218,218,1,143,143, + 143,1,0,0,0,1,47,47,47,1,237,237,237,1,140,140,140,1,126,126, + 126,1,129,129,129,1,0,0,0,32,0,0) + ); + +const + objdata_tdbintegerlookupstrlb: record size: integer; data: array[0..1420] of byte end = + (size: 1421; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,115,116,114,108,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,12,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,132,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,4,168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184, + 255,255,4,182,252,252,1,178,246,246,1,184,255,255,1,188,241,255,1,196, + 214,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,3,103,143,143,1,51,71,71,1,184,255,255,2,181,251,251,1,69, + 95,95,1,35,48,48,1,31,43,43,1,87,121,121,1,184,255,255,2,105, + 145,145,1,34,47,47,1,33,43,45,1,79,86,103,1,198,198,251,1,201, + 201,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184, + 255,255,2,118,164,164,1,62,86,86,1,184,255,255,1,180,250,250,1,32, + 44,44,1,147,204,204,1,159,221,221,1,23,29,31,1,190,207,247,1,201, + 201,255,1,43,43,55,1,142,142,180,1,201,201,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,142,197,197,1,92, + 127,127,1,126,175,175,1,51,71,71,1,184,255,255,2,154,214,214,1,162, + 225,225,1,184,255,255,2,51,71,71,1,116,149,158,1,196,214,255,1,188, + 188,238,1,201,201,255,1,199,199,252,1,32,32,40,1,143,143,181,1,201, + 201,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,3,132,183,183,1,51,71,71,1,184,255,255,5,137,176,186,1,21, + 23,27,1,187,187,237,1,201,201,255,2,139,139,176,1,19,19,24,1,66, + 66,84,1,201,201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,3,132,183,183,1,51,71,71,1,184,255,255,3,188, + 241,255,1,135,148,176,1,20,20,26,1,160,160,203,1,201,201,255,3,188, + 188,238,1,163,163,207,1,50,50,63,1,114,114,144,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132, + 183,183,1,51,71,71,1,184,255,255,1,188,241,255,1,196,214,255,1,130, + 130,165,1,26,26,33,1,168,168,213,1,201,201,255,2,188,188,238,1,175, + 175,222,1,201,201,255,2,137,137,174,1,49,49,62,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132, + 183,183,1,52,67,71,1,196,214,255,1,201,201,255,1,148,148,188,1,31, + 31,39,1,181,181,229,1,201,201,255,3,169,169,214,1,27,27,34,1,197, + 197,250,1,201,201,255,1,81,81,103,1,107,107,136,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,188, + 241,255,1,141,154,183,1,56,56,71,1,201,201,255,2,48,48,61,1,2, + 2,3,1,6,6,7,3,110,110,139,1,201,201,255,1,107,107,136,1,37, + 37,47,1,41,41,52,1,76,76,96,1,188,188,239,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,188,241,255,1,196, + 214,255,1,201,201,255,13,198,198,251,1,192,192,244,1,201,201,255,3,224, + 224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,208, + 208,208,35,0,0,0,2,208,208,208,22,0,0,0,2,208,208,208,16,0, + 0,0,13,208,208,208,11,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,11,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,14,0,0,0,7,208,208,208,1,0,0,0,2,208,208,208,13,0, + 0,0,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,2,208, + 208,208,13,0,0,0,5,208,208,208,1,0,0,0,5,208,208,208,32,80, + 1,0,0,255,255,255,255,255,255,255,81,0,0,0,35,45,45,45,1,105, + 105,105,1,0,0,0,22,104,104,104,1,143,143,143,1,0,0,0,16,15, + 15,15,1,182,182,182,1,223,223,223,1,213,213,213,1,84,84,84,1,30, + 30,30,1,218,218,218,1,227,227,227,1,107,107,107,1,106,106,106,1,141, + 141,141,1,231,231,231,1,116,116,116,1,0,0,0,11,106,106,106,1,156, + 156,156,1,0,0,0,1,41,41,41,1,165,165,165,1,0,0,0,1,104, + 104,104,1,143,143,143,1,0,0,0,1,126,126,126,1,219,219,219,1,32, + 32,32,1,20,20,20,1,0,0,0,11,50,50,50,1,235,235,235,1,169, + 169,169,1,91,91,91,1,13,13,13,1,0,0,0,1,104,104,104,1,143, + 143,143,1,0,0,0,1,126,126,126,1,147,147,147,1,0,0,0,14,21, + 21,21,1,103,103,103,1,185,185,185,1,223,223,223,1,9,9,9,1,104, + 104,104,1,143,143,143,1,0,0,0,1,126,126,126,1,129,129,129,1,0, + 0,0,13,93,93,93,1,130,130,130,1,0,0,0,1,4,4,4,1,236, + 236,236,1,33,33,33,1,97,97,97,1,151,151,151,1,0,0,0,1,126, + 126,126,1,129,129,129,1,0,0,0,13,14,14,14,1,191,191,191,1,199, + 199,199,1,218,218,218,1,143,143,143,1,0,0,0,1,47,47,47,1,237, + 237,237,1,140,140,140,1,126,126,126,1,129,129,129,1,0,0,0,32,0, + 0) + ); + +const + objdata_tdbintegerlookupstrdb: record size: integer; data: array[0..1452] of byte end = + (size: 1453; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,115,116,114,100,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,44,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,164,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,4,168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184, + 255,255,4,182,252,252,1,168,240,246,1,97,202,255,1,18,153,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,103, + 143,143,1,51,71,71,1,184,255,255,2,181,251,251,1,69,95,95,1,35, + 48,48,1,31,43,43,1,87,121,121,1,184,255,255,2,99,142,145,1,18, + 37,47,1,3,27,45,1,7,62,103,1,95,199,251,1,174,249,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,175, + 242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184,255,255,2,118, + 164,164,1,62,86,86,1,184,255,255,1,180,250,250,1,32,44,44,1,139, + 199,204,1,84,175,221,1,2,19,31,1,17,148,247,1,97,202,255,1,38, + 54,55,1,130,180,180,1,184,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,142,197,197,1,92,127,127,1,126, + 175,175,1,51,71,71,1,184,255,255,2,154,214,214,1,162,225,225,1,184, + 255,255,1,174,249,255,1,27,56,71,1,11,95,158,1,18,153,255,1,91, + 189,238,1,174,249,255,1,182,252,252,1,29,40,40,1,131,181,181,1,184, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,3,132,183,183,1,51,71,71,1,184,255,255,3,174,249,255,1,97, + 202,255,1,13,112,186,1,2,16,27,1,90,188,237,1,174,249,255,1,184, + 255,255,1,127,176,176,1,17,24,24,1,61,84,84,1,184,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132, + 183,183,1,51,71,71,1,184,255,255,1,174,249,255,1,97,202,255,1,18, + 153,255,1,12,106,176,1,10,21,26,1,139,198,203,1,184,255,255,3,172, + 238,238,1,149,207,207,1,45,63,63,1,104,144,144,1,184,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132, + 183,183,1,48,69,71,1,97,202,255,1,18,153,255,2,63,131,165,1,23, + 32,33,1,154,213,213,1,184,255,255,2,172,238,238,1,160,222,222,1,184, + 255,255,2,126,174,174,1,45,62,62,1,184,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,174,249,255,1,70, + 145,183,1,5,43,71,1,18,153,255,1,97,202,255,1,128,184,188,1,28, + 39,39,1,165,229,229,1,184,255,255,3,154,214,214,1,25,34,34,1,180, + 250,250,1,184,255,255,1,74,103,103,1,98,136,136,1,184,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,97, + 202,255,1,18,153,255,1,13,110,183,1,27,56,71,1,174,249,255,1,184, + 255,255,1,44,61,61,1,2,3,3,1,5,7,7,3,100,139,139,1,184, + 255,255,1,98,136,136,1,34,47,47,1,38,52,52,1,69,96,96,1,172, + 239,239,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,11,181, + 251,251,1,176,244,244,1,184,255,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2,208, + 208,208,22,0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,7,208, + 208,208,1,0,0,0,2,208,208,208,13,0,0,0,2,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,5,208, + 208,208,1,0,0,0,5,208,208,208,32,80,1,0,0,255,255,255,255,255, + 255,255,81,0,0,0,35,45,45,45,1,105,105,105,1,0,0,0,22,104, + 104,104,1,143,143,143,1,0,0,0,16,15,15,15,1,182,182,182,1,223, + 223,223,1,213,213,213,1,84,84,84,1,30,30,30,1,218,218,218,1,227, + 227,227,1,107,107,107,1,106,106,106,1,141,141,141,1,231,231,231,1,116, + 116,116,1,0,0,0,11,106,106,106,1,156,156,156,1,0,0,0,1,41, + 41,41,1,165,165,165,1,0,0,0,1,104,104,104,1,143,143,143,1,0, + 0,0,1,126,126,126,1,219,219,219,1,32,32,32,1,20,20,20,1,0, + 0,0,11,50,50,50,1,235,235,235,1,169,169,169,1,91,91,91,1,13, + 13,13,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0,0,1,126, + 126,126,1,147,147,147,1,0,0,0,14,21,21,21,1,103,103,103,1,185, + 185,185,1,223,223,223,1,9,9,9,1,104,104,104,1,143,143,143,1,0, + 0,0,1,126,126,126,1,129,129,129,1,0,0,0,13,93,93,93,1,130, + 130,130,1,0,0,0,1,4,4,4,1,236,236,236,1,33,33,33,1,97, + 97,97,1,151,151,151,1,0,0,0,1,126,126,126,1,129,129,129,1,0, + 0,0,13,14,14,14,1,191,191,191,1,199,199,199,1,218,218,218,1,143, + 143,143,1,0,0,0,1,47,47,47,1,237,237,237,1,140,140,140,1,126, + 126,126,1,129,129,129,1,0,0,0,32,0,0) + ); + +const + objdata_tdbreallookupstrlb: record size: integer; data: array[0..1333] of byte end = + (size: 1334; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 114,101,97,108,108,111,111,107,117,112,115,116,114,108,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 184,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 48,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 168,233,233,1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,5, + 181,232,246,1,186,203,242,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,2,103,143,143,1,51,71,71,1,184,255,255,6, + 84,116,116,1,33,46,46,1,32,45,45,1,72,100,100,1,181,251,251,1, + 184,255,255,1,188,241,255,1,194,211,252,1,54,54,69,1,117,117,149,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,175,242,242,1, + 75,104,104,1,13,18,18,1,51,71,71,1,184,255,255,5,142,197,197,1, + 40,55,55,1,182,252,252,1,183,254,254,1,54,75,75,1,125,161,170,1, + 196,214,255,1,169,169,214,1,45,45,57,1,13,13,17,1,117,117,149,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,142,197,197,1, + 92,127,127,1,126,175,175,1,51,71,71,1,184,255,255,5,162,224,224,1, + 155,215,215,1,184,255,255,1,188,241,255,1,81,88,105,1,98,98,124,1, + 201,201,255,1,114,114,145,1,135,135,171,1,84,84,106,1,117,117,149,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2, + 132,183,183,1,51,71,71,1,184,255,255,6,188,241,255,1,196,214,255,1, + 164,164,208,1,19,19,24,1,172,172,218,1,201,201,255,3,84,84,106,1, + 117,117,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,2,132,183,183,1,51,71,71,1,184,255,255,4,188,241,255,1, + 196,214,255,1,201,201,255,1,158,158,200,1,20,20,26,1,142,142,180,1, + 201,201,255,4,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,2,132,183,183,1,51,71,71,1, + 184,255,255,2,188,241,255,1,196,214,255,1,201,201,255,2,151,151,191,1, + 22,22,28,1,151,151,192,1,201,201,255,5,84,84,106,1,117,117,149,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2, + 132,183,183,1,51,71,71,1,188,241,255,1,196,214,255,1,197,197,250,1, + 177,177,225,1,201,201,255,1,169,169,215,1,22,22,28,1,168,168,213,1, + 201,201,255,6,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,2,135,173,183,1,55,60,71,1, + 201,201,255,2,164,164,208,1,12,12,15,1,201,201,255,1,74,74,94,1, + 2,2,2,1,6,6,7,3,84,84,106,1,201,201,255,3,84,84,106,1, + 117,117,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 188,241,255,1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1, + 128,128,128,1,224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2, + 208,208,208,22,0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,7, + 208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,2,208,208,208,1, + 0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,5, + 208,208,208,1,0,0,0,5,208,208,208,32,80,1,0,0,255,255,255,255, + 255,255,255,81,0,0,0,35,45,45,45,1,105,105,105,1,0,0,0,22, + 104,104,104,1,143,143,143,1,0,0,0,16,15,15,15,1,182,182,182,1, + 223,223,223,1,213,213,213,1,84,84,84,1,30,30,30,1,218,218,218,1, + 227,227,227,1,107,107,107,1,106,106,106,1,141,141,141,1,231,231,231,1, + 116,116,116,1,0,0,0,11,106,106,106,1,156,156,156,1,0,0,0,1, + 41,41,41,1,165,165,165,1,0,0,0,1,104,104,104,1,143,143,143,1, + 0,0,0,1,126,126,126,1,219,219,219,1,32,32,32,1,20,20,20,1, + 0,0,0,11,50,50,50,1,235,235,235,1,169,169,169,1,91,91,91,1, + 13,13,13,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0,0,1, + 126,126,126,1,147,147,147,1,0,0,0,14,21,21,21,1,103,103,103,1, + 185,185,185,1,223,223,223,1,9,9,9,1,104,104,104,1,143,143,143,1, + 0,0,0,1,126,126,126,1,129,129,129,1,0,0,0,13,93,93,93,1, + 130,130,130,1,0,0,0,1,4,4,4,1,236,236,236,1,33,33,33,1, + 97,97,97,1,151,151,151,1,0,0,0,1,126,126,126,1,129,129,129,1, + 0,0,0,13,14,14,14,1,191,191,191,1,199,199,199,1,218,218,218,1, + 143,143,143,1,0,0,0,1,47,47,47,1,237,237,237,1,140,140,140,1, + 126,126,126,1,129,129,129,1,0,0,0,32,0,0) + ); + +const + objdata_tdbreallookupstrdb: record size: integer; data: array[0..1361] of byte end = + (size: 1362; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 114,101,97,108,108,111,111,107,117,112,115,116,114,100,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 212,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 76,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 168,233,233,1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,3, + 174,249,255,1,97,202,255,1,17,148,246,1,17,145,242,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,103,143,143,1, + 51,71,71,1,184,255,255,6,84,116,116,1,33,46,46,1,32,45,45,1, + 72,100,100,1,171,245,251,1,97,202,255,1,18,153,255,1,18,151,252,1, + 26,55,69,1,102,145,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1, + 184,255,255,5,142,197,197,1,40,55,55,1,182,252,252,1,173,248,254,1, + 29,59,75,1,12,102,170,1,18,153,255,1,81,170,214,1,39,56,57,1, + 12,17,17,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,142,197,197,1,92,127,127,1,126,175,175,1,51,71,71,1, + 184,255,255,5,162,224,224,1,147,210,215,1,97,202,255,1,18,153,255,1, + 7,63,105,1,47,98,124,1,174,249,255,1,105,145,145,1,123,171,171,1, + 76,106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,184,255,255,4, + 174,249,255,1,97,202,255,1,18,153,255,2,79,165,208,1,16,23,24,1, + 157,218,218,1,184,255,255,3,76,106,106,1,108,149,149,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132,183,183,1, + 51,71,71,1,184,255,255,2,174,249,255,1,97,202,255,1,18,153,255,2, + 97,202,255,1,136,195,200,1,19,26,26,1,130,180,180,1,184,255,255,4, + 76,106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,174,249,255,1, + 97,202,255,1,18,153,255,2,97,202,255,1,174,249,255,1,138,191,191,1, + 20,28,28,1,139,192,192,1,184,255,255,5,76,106,106,1,108,149,149,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2, + 125,179,183,1,27,56,71,1,18,153,255,2,95,198,250,1,154,220,225,1, + 184,255,255,1,155,215,215,1,20,28,28,1,154,213,213,1,184,255,255,6, + 76,106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,174,249,255,1,97,202,255,1,13,110,183,1,5,43,71,1, + 97,202,255,1,174,249,255,1,150,208,208,1,11,15,15,1,184,255,255,1, + 68,94,94,1,1,2,2,1,5,7,7,3,76,106,106,1,184,255,255,3, + 76,106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,16, + 224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25, + 208,208,208,35,0,0,0,2,208,208,208,22,0,0,0,2,208,208,208,16, + 0,0,0,13,208,208,208,11,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,11, + 0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,14,0,0,0,7,208,208,208,1,0,0,0,2,208,208,208,13, + 0,0,0,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,2, + 208,208,208,13,0,0,0,5,208,208,208,1,0,0,0,5,208,208,208,32, + 80,1,0,0,255,255,255,255,255,255,255,81,0,0,0,35,45,45,45,1, + 105,105,105,1,0,0,0,22,104,104,104,1,143,143,143,1,0,0,0,16, + 15,15,15,1,182,182,182,1,223,223,223,1,213,213,213,1,84,84,84,1, + 30,30,30,1,218,218,218,1,227,227,227,1,107,107,107,1,106,106,106,1, + 141,141,141,1,231,231,231,1,116,116,116,1,0,0,0,11,106,106,106,1, + 156,156,156,1,0,0,0,1,41,41,41,1,165,165,165,1,0,0,0,1, + 104,104,104,1,143,143,143,1,0,0,0,1,126,126,126,1,219,219,219,1, + 32,32,32,1,20,20,20,1,0,0,0,11,50,50,50,1,235,235,235,1, + 169,169,169,1,91,91,91,1,13,13,13,1,0,0,0,1,104,104,104,1, + 143,143,143,1,0,0,0,1,126,126,126,1,147,147,147,1,0,0,0,14, + 21,21,21,1,103,103,103,1,185,185,185,1,223,223,223,1,9,9,9,1, + 104,104,104,1,143,143,143,1,0,0,0,1,126,126,126,1,129,129,129,1, + 0,0,0,13,93,93,93,1,130,130,130,1,0,0,0,1,4,4,4,1, + 236,236,236,1,33,33,33,1,97,97,97,1,151,151,151,1,0,0,0,1, + 126,126,126,1,129,129,129,1,0,0,0,13,14,14,14,1,191,191,191,1, + 199,199,199,1,218,218,218,1,143,143,143,1,0,0,0,1,47,47,47,1, + 237,237,237,1,140,140,140,1,126,126,126,1,129,129,129,1,0,0,0,32, + 0,0) + ); + +const + objdata_tdbdatetimelookupstrlb: record size: integer; data: array[0..1349] of byte end = + (size: 1350; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,115,116,114,108,98,23, + 98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105, + 111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95, + 99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,196,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0, + 24,0,0,0,60,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 128,128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1, + 184,255,255,6,173,240,240,1,167,231,231,5,175,224,237,1,196,214,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1, + 127,176,176,1,5,7,7,1,22,31,31,1,19,27,27,1,5,7,7,1, + 60,83,83,1,168,233,233,1,184,255,255,4,80,111,111,1,22,31,31,2, + 1,1,1,1,21,26,28,1,24,26,31,1,67,67,85,1,201,201,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1, + 127,176,176,1,45,63,63,1,184,255,255,2,180,250,250,1,66,92,92,1, + 56,78,78,1,184,255,255,6,188,241,255,1,8,8,10,1,181,181,229,1, + 201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,3,175,242,242,1, + 1,2,2,1,162,224,224,1,184,255,255,1,29,40,40,1,165,228,228,1, + 188,241,255,1,196,214,255,1,201,201,255,1,8,8,10,1,181,181,229,1, + 201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1, + 128,178,178,1,184,255,255,1,136,174,184,1,189,206,246,1,201,201,255,3, + 8,8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1, + 184,255,255,4,31,43,43,1,132,169,179,1,196,214,255,1,201,201,255,5, + 8,8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1, + 184,255,255,3,177,227,240,1,7,8,9,1,174,174,221,1,201,201,255,6, + 8,8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1, + 184,255,255,1,188,241,255,1,178,195,232,1,69,69,88,1,64,64,81,1, + 201,201,255,2,177,177,224,1,198,198,251,1,201,201,255,3,8,8,10,1, + 181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,1,127,176,176,1,1,1,1,1,5,6,7,1, + 6,6,7,1,17,17,22,1,78,78,99,1,192,192,243,1,201,201,255,2, + 1,1,1,1,175,175,222,1,201,201,255,3,8,8,10,1,181,181,229,1, + 201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 188,241,255,1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1, + 128,128,128,1,224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2, + 208,208,208,22,0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,4, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,13, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,5,208,208,208,1, + 0,0,0,5,208,208,208,32,80,1,0,0,255,255,255,255,255,255,255,81, + 0,0,0,35,77,77,77,1,73,73,73,1,0,0,0,22,155,155,155,1, + 92,92,92,1,0,0,0,16,40,40,40,1,203,203,203,1,221,221,221,1, + 201,201,201,1,51,51,51,1,68,68,68,1,230,230,230,1,215,215,215,1, + 69,69,69,1,150,150,150,1,139,139,139,1,234,234,234,1,72,72,72,1, + 0,0,0,11,157,157,157,1,105,105,105,1,0,0,0,1,80,80,80,1, + 125,125,125,1,0,0,0,1,155,155,155,1,92,92,92,1,0,0,0,1, + 178,178,178,1,179,179,179,1,29,29,29,1,11,11,11,1,0,0,0,11, + 91,91,91,1,234,234,234,1,154,154,154,1,74,74,74,1,4,4,4,1, + 0,0,0,1,155,155,155,1,92,92,92,1,0,0,0,1,178,178,178,1, + 96,96,96,1,0,0,0,14,35,35,35,1,119,119,119,1,205,205,205,1, + 181,181,181,1,0,0,0,1,155,155,155,1,92,92,92,1,0,0,0,1, + 178,178,178,1,77,77,77,1,0,0,0,13,138,138,138,1,85,85,85,1, + 0,0,0,1,36,36,36,1,237,237,237,1,0,0,0,1,148,148,148,1, + 99,99,99,1,0,0,0,1,178,178,178,1,77,77,77,1,0,0,0,13, + 45,45,45,1,202,202,202,1,195,195,195,1,225,225,225,1,97,97,97,1, + 0,0,0,1,92,92,92,1,236,236,236,1,97,97,97,1,178,178,178,1, + 77,77,77,1,0,0,0,32,0,0) + ); + +const + objdata_tdbdatetimelookupstrdb: record size: integer; data: array[0..1405] of byte end = + (size: 1406; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,115,116,114,100,98,23, + 98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105, + 111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95, + 99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,252,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0, + 24,0,0,0,116,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 128,128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1, + 184,255,255,6,173,240,240,1,167,231,231,3,158,226,231,1,88,183,231,1, + 17,142,237,1,18,153,255,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,1,127,176,176,1,5,7,7,1,22,31,31,1, + 19,27,27,1,5,7,7,1,60,83,83,1,168,233,233,1,184,255,255,4, + 80,111,111,1,22,31,31,1,21,30,31,1,0,1,1,1,2,17,28,1, + 2,19,31,1,32,67,85,1,174,249,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1, + 184,255,255,2,180,250,250,1,66,92,92,1,56,78,78,1,184,255,255,4, + 174,249,255,1,97,202,255,1,18,153,255,1,1,6,10,1,87,181,229,1, + 174,249,255,1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,3, + 175,242,242,1,1,2,2,1,162,224,224,1,184,255,255,1,27,39,40,1, + 87,181,228,1,18,153,255,2,97,202,255,1,7,10,10,1,165,229,229,1, + 184,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1, + 121,174,178,1,97,202,255,1,13,110,184,1,17,148,246,1,97,202,255,1, + 174,249,255,1,184,255,255,1,7,10,10,1,165,229,229,1,184,255,255,3, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1, + 127,176,176,1,45,63,63,1,184,255,255,3,174,249,255,1,16,34,43,1, + 13,107,179,1,18,153,255,1,97,202,255,1,174,249,255,1,184,255,255,3, + 7,10,10,1,165,229,229,1,184,255,255,3,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1, + 184,255,255,1,174,249,255,1,97,202,255,1,17,144,240,1,1,5,9,1, + 84,175,221,1,174,249,255,1,184,255,255,5,7,10,10,1,165,229,229,1, + 184,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,127,176,176,1,43,62,63,1,97,202,255,1,18,153,255,1, + 16,139,232,1,33,70,88,1,55,79,81,1,184,255,255,2,162,224,224,1, + 181,251,251,1,184,255,255,3,7,10,10,1,165,229,229,1,184,255,255,3, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1, + 67,139,176,1,0,1,1,1,0,4,7,1,3,6,7,1,15,21,22,1, + 71,99,99,1,175,243,243,1,184,255,255,2,1,1,1,1,160,222,222,1, + 184,255,255,3,7,10,10,1,165,229,229,1,184,255,255,3,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,18,153,255,2,97,202,255,1, + 174,249,255,1,184,255,255,16,224,224,224,1,255,255,255,1,128,128,128,1, + 224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2,208,208,208,22, + 0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1, + 0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,4,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1, + 0,0,0,2,208,208,208,13,0,0,0,5,208,208,208,1,0,0,0,5, + 208,208,208,32,80,1,0,0,255,255,255,255,255,255,255,81,0,0,0,35, + 77,77,77,1,73,73,73,1,0,0,0,22,155,155,155,1,92,92,92,1, + 0,0,0,16,40,40,40,1,203,203,203,1,221,221,221,1,201,201,201,1, + 51,51,51,1,68,68,68,1,230,230,230,1,215,215,215,1,69,69,69,1, + 150,150,150,1,139,139,139,1,234,234,234,1,72,72,72,1,0,0,0,11, + 157,157,157,1,105,105,105,1,0,0,0,1,80,80,80,1,125,125,125,1, + 0,0,0,1,155,155,155,1,92,92,92,1,0,0,0,1,178,178,178,1, + 179,179,179,1,29,29,29,1,11,11,11,1,0,0,0,11,91,91,91,1, + 234,234,234,1,154,154,154,1,74,74,74,1,4,4,4,1,0,0,0,1, + 155,155,155,1,92,92,92,1,0,0,0,1,178,178,178,1,96,96,96,1, + 0,0,0,14,35,35,35,1,119,119,119,1,205,205,205,1,181,181,181,1, + 0,0,0,1,155,155,155,1,92,92,92,1,0,0,0,1,178,178,178,1, + 77,77,77,1,0,0,0,13,138,138,138,1,85,85,85,1,0,0,0,1, + 36,36,36,1,237,237,237,1,0,0,0,1,148,148,148,1,99,99,99,1, + 0,0,0,1,178,178,178,1,77,77,77,1,0,0,0,13,45,45,45,1, + 202,202,202,1,195,195,195,1,225,225,225,1,97,97,97,1,0,0,0,1, + 92,92,92,1,236,236,236,1,97,97,97,1,178,178,178,1,77,77,77,1, + 0,0,0,32,0,0) + ); + +const + objdata_tdbwidgetgrid: record size: integer; data: array[0..1396] of byte end = + (size: 1397; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 119,105,100,103,101,116,103,114,105,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,252,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,184,4,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,2,128, + 128,128,1,208,208,208,2,112,112,112,1,153,153,153,1,171,171,171,1,165, + 165,165,1,118,118,118,1,184,184,184,1,208,208,208,2,128,128,128,1,208, + 208,208,2,154,154,154,1,148,148,148,1,190,190,190,1,186,186,186,1,148, + 148,148,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,1,179,179,179,1,142,142,142,1,116,116,116,1,148, + 148,148,1,141,141,141,1,121,121,121,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,2,144,144,144,2,131,131,131,1,146,146,146,1,165, + 165,165,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,4,175,175,175,1,176,176,176,1,208,208,208,4,128, + 128,128,1,208,208,208,2,186,186,186,1,183,183,183,1,187,187,187,1,191, + 191,191,1,197,197,197,1,208,208,208,1,255,255,255,1,128,128,128,23,255, + 255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,122, + 169,169,1,132,183,183,1,146,202,202,1,155,215,215,1,162,225,225,1,184, + 255,255,4,128,128,128,1,184,255,255,2,175,243,243,1,122,169,169,1,147, + 204,204,1,129,179,179,1,100,139,139,1,184,255,255,1,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,109,151,151,1,115, + 160,160,1,112,155,155,1,145,201,201,1,162,225,225,1,184,255,255,4,128, + 128,128,1,184,255,255,3,138,191,191,1,108,150,150,1,146,202,202,1,114, + 158,158,1,181,251,251,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,184,255,255,1,171,237,237,1,168,233,233,1,165,228,228,1,154, + 213,213,1,160,222,222,1,184,255,255,4,128,128,128,1,184,255,255,8,255, + 255,255,1,128,128,128,23,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,184,255,255,1,149,206,206,1,121,168,168,1,152,211,211,1,172, + 238,238,1,163,226,226,1,175,242,242,1,138,191,191,1,145,201,201,1,181, + 251,251,1,128,128,128,1,184,255,255,4,127,176,176,2,93,129,129,1,184, + 255,255,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184, + 255,255,1,131,181,181,1,170,236,236,1,105,145,145,1,123,170,170,1,131, + 181,181,1,117,162,162,1,137,190,190,1,133,185,185,1,184,255,255,1,128, + 128,128,1,184,255,255,4,134,186,186,1,152,211,211,1,115,159,159,1,184, + 255,255,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184, + 255,255,1,144,199,199,1,152,210,210,1,151,209,209,1,171,237,237,1,172, + 238,238,1,170,235,235,1,159,220,220,1,144,199,199,1,179,248,248,1,128, + 128,128,1,184,255,255,8,255,255,255,1,128,128,128,23,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,142,197,197,1,128, + 177,177,1,159,221,221,1,184,255,255,6,128,128,128,1,184,255,255,4,122, + 169,169,1,114,158,158,1,113,157,157,1,184,255,255,1,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,127,176,176,1,137, + 190,190,1,131,181,181,1,184,255,255,6,128,128,128,1,184,255,255,4,128, + 178,178,1,116,161,161,1,114,158,158,1,184,255,255,1,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,170,235,235,1,157, + 217,217,1,172,239,239,1,184,255,255,6,128,128,128,1,184,255,255,8,255, + 255,255,1,128,128,128,23,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,184,255,255,1,126,174,174,1,128,177,177,1,145,201,201,1,167, + 232,232,1,159,221,221,1,131,182,182,1,153,212,212,1,184,255,255,2,128, + 128,128,1,184,255,255,2,165,228,228,1,118,163,163,1,138,191,191,1,133, + 184,184,1,100,139,139,1,184,255,255,1,255,255,255,1,128,128,128,1,208, + 208,208,2,128,128,128,1,184,255,255,1,114,158,158,1,149,207,207,1,87, + 120,120,1,127,176,176,1,126,175,175,1,132,183,183,1,102,142,142,1,184, + 255,255,2,128,128,128,1,184,255,255,2,153,212,212,1,110,152,152,1,147, + 204,204,1,128,178,178,1,114,158,158,1,181,251,251,1,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,171,237,237,1,184, + 255,255,1,172,239,239,1,146,203,203,1,120,166,166,1,172,239,239,1,130, + 180,180,1,184,255,255,2,128,128,128,1,184,255,255,8,255,255,255,1,128, + 128,128,23,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184, + 255,255,1,144,199,199,2,163,226,226,1,165,228,228,1,168,233,233,1,184, + 255,255,4,128,128,128,1,184,255,255,4,124,172,172,1,142,197,197,1,99, + 137,137,1,184,255,255,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,184,255,255,1,132,183,183,1,127,176,176,1,132,183,183,1,125, + 173,173,1,94,130,130,1,184,255,255,4,128,128,128,1,184,255,255,4,150, + 208,208,1,155,215,215,1,121,168,168,1,183,254,254,1,255,255,255,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbstringgrid: record size: integer; data: array[0..1760] of byte end = + (size: 1761; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 115,116,114,105,110,103,103,114,105,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,104,6,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,36,6,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,2,128, + 128,128,1,208,208,208,2,112,112,112,1,153,153,153,1,171,171,171,1,165, + 165,165,1,118,118,118,1,184,184,184,1,208,208,208,2,128,128,128,1,208, + 208,208,2,154,154,154,1,148,148,148,1,190,190,190,1,186,186,186,1,148, + 148,148,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,1,179,179,179,1,142,142,142,1,116,116,116,1,148, + 148,148,1,141,141,141,1,121,121,121,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,2,144,144,144,2,131,131,131,1,146,146,146,1,165, + 165,165,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,4,175,175,175,1,176,176,176,1,208,208,208,4,128, + 128,128,1,208,208,208,2,186,186,186,1,183,183,183,1,187,187,187,1,191, + 191,191,1,197,197,197,1,208,208,208,1,255,255,255,1,128,128,128,23,255, + 255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,122, + 169,169,1,132,183,183,1,146,202,202,1,155,215,215,1,162,225,225,1,184, + 255,255,4,128,128,128,1,184,255,255,2,175,243,243,1,122,169,169,1,147, + 204,204,1,129,179,179,1,100,139,139,1,184,255,255,1,255,255,255,1,128, + 128,128,1,208,208,208,1,209,209,209,1,129,129,129,1,185,255,255,1,111, + 152,152,1,117,161,161,1,114,156,156,1,146,202,202,1,163,225,225,1,185, + 255,255,4,129,129,129,1,185,255,255,3,139,192,192,1,110,151,151,1,147, + 203,203,1,116,159,159,1,182,251,251,1,255,255,255,1,128,128,128,1,213, + 213,213,1,214,214,214,1,145,145,145,1,193,255,255,1,182,239,239,1,180, + 236,236,1,177,232,232,1,167,219,219,1,173,226,226,1,193,255,255,4,145, + 145,145,1,193,255,255,7,192,255,255,1,255,255,255,1,128,128,128,1,170, + 170,170,1,179,179,179,1,180,180,180,1,187,148,135,1,186,154,143,1,180, + 180,180,3,184,160,151,1,188,144,129,2,188,147,133,1,185,158,149,1,180, + 180,180,4,183,166,160,1,189,138,120,1,188,142,126,1,181,173,170,1,170, + 170,170,1,255,255,255,1,128,128,128,1,228,228,228,1,233,233,233,1,197, + 174,166,1,208,53,0,1,208,62,11,1,193,206,203,1,207,234,234,1,216, + 247,247,1,210,133,103,1,208,54,1,1,208,63,13,1,208,61,10,1,208, + 53,0,1,204,96,59,1,222,255,255,2,216,180,160,1,208,59,8,1,207, + 61,10,1,208,55,3,1,205,68,20,1,213,226,218,1,255,255,255,1,128, + 128,128,1,229,229,229,1,233,233,233,1,203,119,91,1,209,72,24,1,208, + 55,3,1,213,168,146,1,186,205,205,1,194,216,216,1,204,124,94,1,207, + 70,22,1,201,225,225,1,199,223,223,1,216,171,149,1,208,53,0,1,220, + 240,236,1,221,233,227,1,209,60,9,1,213,127,93,1,200,215,212,1,208, + 216,210,1,206,67,19,1,212,150,123,1,255,255,255,1,128,128,128,1,229, + 229,229,1,232,230,229,1,207,66,18,1,214,149,121,1,207,106,69,1,208, + 87,44,1,207,234,234,1,216,247,247,1,212,136,106,1,209,65,15,1,210, + 169,149,1,205,159,138,1,211,104,65,1,205,87,47,1,222,255,255,1,217, + 181,161,1,208,53,0,1,219,207,195,1,222,255,255,2,222,252,251,1,215, + 255,255,1,255,255,255,1,128,128,128,1,184,184,184,1,200,151,134,1,208, + 53,0,1,199,174,165,1,201,151,134,1,208,53,0,1,200,166,155,1,197, + 197,197,1,203,114,84,1,208,55,3,1,206,75,30,1,207,71,25,1,207, + 57,5,1,204,101,66,1,198,190,188,1,202,129,104,1,208,53,0,1,198, + 184,179,1,197,197,197,2,196,196,196,1,183,183,183,1,255,255,255,1,128, + 128,128,1,229,229,229,1,216,106,68,1,208,54,1,1,210,78,31,1,207, + 72,25,1,208,53,0,1,209,124,91,1,222,255,255,1,214,139,109,1,210, + 74,26,1,222,255,255,2,220,224,216,1,208,53,0,1,217,177,157,1,217, + 187,169,1,208,53,0,1,218,190,173,1,194,216,216,1,190,210,210,1,198, + 137,112,1,213,198,183,1,255,255,255,1,128,128,128,1,227,210,204,1,209, + 55,3,1,203,114,83,1,217,185,167,1,200,161,143,1,205,110,74,1,208, + 60,9,1,221,243,240,1,214,139,109,1,209,69,20,1,219,211,199,1,219, + 207,195,1,215,161,136,1,208,53,0,1,217,183,164,1,222,245,243,1,210, + 74,26,1,211,93,50,1,200,174,159,1,198,146,124,1,208,53,0,1,213, + 177,156,1,255,255,255,1,128,128,128,1,218,142,116,1,209,57,5,1,195, + 184,180,1,222,255,255,1,215,246,246,1,208,203,193,1,208,53,0,1,216, + 169,146,1,214,139,109,1,208,53,0,2,208,57,5,1,209,67,18,1,203, + 111,80,1,221,253,252,1,222,255,255,1,219,216,206,1,211,90,47,1,208, + 53,0,1,209,70,21,1,214,137,106,1,214,254,254,1,255,255,255,1,128, + 128,128,1,170,170,170,1,179,179,179,1,180,180,180,18,179,179,179,1,170, + 170,170,1,255,255,255,1,128,128,128,1,213,213,213,1,214,214,214,1,145, + 145,145,1,193,255,255,1,143,185,185,1,145,187,187,1,160,208,208,1,179, + 235,235,1,172,226,226,1,148,192,192,1,167,218,218,1,193,255,255,2,145, + 145,145,1,193,255,255,2,177,232,232,1,136,175,175,1,154,200,200,1,149, + 193,193,1,121,154,154,1,192,255,255,1,255,255,255,1,128,128,128,1,208, + 208,208,1,209,209,209,1,129,129,129,1,185,255,255,1,116,159,159,1,150, + 208,208,1,89,122,122,1,129,177,177,1,128,176,176,1,133,184,184,1,104, + 143,143,1,185,255,255,2,129,129,129,1,185,255,255,2,154,213,213,1,112, + 153,153,1,148,205,205,1,129,179,179,1,116,159,159,1,182,251,251,1,255, + 255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,171, + 237,237,1,184,255,255,1,172,239,239,1,146,203,203,1,120,166,166,1,172, + 239,239,1,130,180,180,1,184,255,255,2,128,128,128,1,184,255,255,8,255, + 255,255,1,128,128,128,23,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,184,255,255,1,144,199,199,2,163,226,226,1,165,228,228,1,168, + 233,233,1,184,255,255,4,128,128,128,1,184,255,255,4,124,172,172,1,142, + 197,197,1,99,137,137,1,184,255,255,1,255,255,255,1,128,128,128,1,208, + 208,208,2,128,128,128,1,184,255,255,1,132,183,183,1,127,176,176,1,132, + 183,183,1,125,173,173,1,94,130,130,1,184,255,255,4,128,128,128,1,184, + 255,255,4,150,208,208,1,155,215,215,1,121,168,168,1,183,254,254,1,255, + 255,255,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0, + 0) + ); + +const + objdata_tlookupbuffer: record size: integer; data: array[0..1072] of byte end = + (size: 1073; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,108,111, + 111,107,117,112,98,117,102,102,101,114,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,3,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,255,0,2,0, + 0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0, + 255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0, + 0,0,2,190,190,255,11,255,255,255,11,0,0,0,1,0,255,0,1,190, + 190,255,11,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,5,255, + 255,255,1,0,255,0,2,190,190,255,11,255,255,255,11,0,255,0,1,0, + 0,0,1,190,190,255,9,0,0,255,1,190,190,255,1,255,255,255,1,0, + 0,0,3,255,255,255,1,0,0,0,2,255,255,255,4,0,0,0,2,190, + 190,255,9,0,0,255,2,255,255,255,11,0,0,0,1,0,255,0,1,190, + 190,255,8,0,0,255,4,0,0,0,3,255,255,255,1,0,0,0,3,255, + 255,255,3,0,255,0,2,190,190,255,7,0,0,255,1,190,190,255,1,0, + 0,255,2,255,255,255,11,0,255,0,1,0,0,0,1,190,190,255,7,0, + 0,255,1,190,190,255,1,0,0,255,1,190,190,255,1,255,255,255,1,0, + 0,0,3,255,255,255,1,0,0,0,4,255,255,255,2,0,0,0,2,190, + 190,255,7,0,0,255,1,190,190,255,3,255,255,255,11,0,0,0,1,0, + 255,0,1,190,190,255,7,0,0,255,1,190,190,255,3,255,255,255,1,0, + 0,0,3,255,255,255,1,0,0,0,2,255,255,255,4,0,255,0,2,190, + 190,255,7,0,0,255,1,190,190,255,3,255,255,255,11,0,255,0,1,0, + 0,0,1,190,190,255,7,0,0,255,1,190,190,255,3,255,255,255,1,0, + 0,0,3,255,255,255,1,0,0,0,5,255,255,255,1,0,0,0,2,190, + 190,255,1,0,0,0,3,190,190,255,3,0,0,255,1,190,190,255,3,255, + 255,255,11,0,0,0,1,0,255,0,1,190,190,255,7,0,0,255,1,190, + 190,255,3,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,2,255, + 255,255,4,0,255,0,2,190,190,255,1,0,0,0,3,190,190,255,3,0, + 0,255,1,190,190,255,3,255,255,255,11,0,255,0,1,0,0,0,1,190, + 190,255,7,0,0,255,1,190,190,255,3,255,255,255,11,0,0,0,2,190, + 190,255,1,0,0,0,3,190,190,255,1,0,0,255,2,190,190,255,4,255, + 255,255,11,0,0,0,1,0,255,0,1,190,190,255,11,255,255,255,11,0, + 255,0,2,190,190,255,1,0,0,0,3,190,190,255,7,255,255,255,11,0, + 255,0,1,0,0,0,1,190,190,255,11,255,255,255,11,0,0,0,2,190, + 190,255,11,255,255,255,11,0,0,0,1,0,255,0,1,190,190,255,11,255, + 255,255,11,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0, + 255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0, + 0,0,2,0,255,0,2,0,0,0,2,0,255,0,1,232,0,0,0,0, + 0,0,1,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255, + 255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0, + 0,0,2,255,255,255,2,0,0,0,2,255,255,255,22,0,0,0,1,255, + 255,255,48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0,1,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,48,0, + 0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255, + 255,255,25,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0, + 0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255, + 255,255,2,0,0,0,2,255,255,255,1,0,0) + ); + +const + objdata_tdblookupbuffer: record size: integer; data: array[0..1074] of byte end = + (size: 1075; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 108,111,111,107,117,112,98,117,102,102,101,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,3,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,255,0, + 2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0, + 2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0, + 2,0,0,0,2,190,190,255,11,190,255,255,11,0,0,0,1,0,255,0, + 1,190,190,255,11,190,255,255,1,0,0,0,3,190,255,255,1,0,0,0, + 5,190,255,255,1,0,255,0,2,190,190,255,11,190,255,255,11,0,255,0, + 1,0,0,0,1,190,190,255,9,0,0,255,1,190,190,255,1,190,255,255, + 1,0,0,0,3,190,255,255,1,0,0,0,2,190,255,255,4,0,0,0, + 2,190,190,255,9,0,0,255,2,190,255,255,11,0,0,0,1,0,255,0, + 1,190,190,255,8,0,0,255,4,0,0,0,3,190,255,255,1,0,0,0, + 3,190,255,255,3,0,255,0,2,190,190,255,7,0,0,255,1,190,190,255, + 1,0,0,255,2,190,255,255,11,0,255,0,1,0,0,0,1,190,190,255, + 7,0,0,255,1,190,190,255,1,0,0,255,1,190,190,255,1,190,255,255, + 1,0,0,0,3,190,255,255,1,0,0,0,4,190,255,255,2,0,0,0, + 2,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255,11,0,0,0, + 1,0,255,0,1,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255, + 1,0,0,0,3,190,255,255,1,0,0,0,2,190,255,255,4,0,255,0, + 2,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255,11,0,255,0, + 1,0,0,0,1,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255, + 1,0,0,0,3,190,255,255,1,0,0,0,5,190,255,255,1,0,0,0, + 2,190,190,255,1,0,0,0,3,190,190,255,3,0,0,255,1,190,190,255, + 3,190,255,255,11,0,0,0,1,0,255,0,1,190,190,255,7,0,0,255, + 1,190,190,255,3,190,255,255,1,0,0,0,3,190,255,255,1,0,0,0, + 2,190,255,255,4,0,255,0,2,190,190,255,1,0,0,0,3,190,190,255, + 3,0,0,255,1,190,190,255,3,190,255,255,11,0,255,0,1,0,0,0, + 1,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255,11,0,0,0, + 2,190,190,255,1,0,0,0,3,190,190,255,1,0,0,255,2,190,190,255, + 4,190,255,255,11,0,0,0,1,0,255,0,1,190,190,255,11,190,255,255, + 11,0,255,0,2,190,190,255,1,0,0,0,3,190,190,255,7,190,255,255, + 11,0,255,0,1,0,0,0,1,190,190,255,11,190,255,255,11,0,0,0, + 2,190,190,255,11,190,255,255,11,0,0,0,1,0,255,0,1,190,190,255, + 11,190,255,255,11,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0, + 2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0, + 2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,1,232,0,0, + 0,0,0,0,1,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,22,0,0,0, + 1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0, + 1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255, + 48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 1,255,255,255,25,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,1,0,0) + ); + +const + objdata_tdbmemolookupbuffer: record size: integer; data: array[0..1262] of byte end = + (size: 1263; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 109,101,109,111,108,111,111,107,117,112,98,117,102,102,101,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,112,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,80,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0, + 2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0, + 2,0,255,0,2,0,0,0,2,190,190,255,11,190,255,255,11,0,0,0, + 1,0,255,0,1,190,190,255,11,190,255,255,1,0,0,0,3,190,255,255, + 1,0,0,0,5,190,255,255,1,0,255,0,2,190,190,255,11,190,255,255, + 11,0,255,0,1,0,0,0,1,190,190,255,9,0,0,255,1,190,190,255, + 1,190,255,255,1,0,0,0,3,190,255,255,1,0,0,0,2,190,255,255, + 4,0,0,0,2,190,190,255,9,0,0,255,2,190,255,255,11,0,0,0, + 1,0,255,0,1,190,190,255,8,0,0,255,4,0,0,0,3,190,255,255, + 1,0,0,0,3,190,255,255,3,0,255,0,2,190,190,255,7,0,0,255, + 1,190,190,255,1,0,0,255,2,190,255,255,11,0,255,0,1,0,0,0, + 1,190,190,255,7,0,0,255,1,190,190,255,1,0,0,255,1,190,190,255, + 1,190,255,255,1,0,0,0,3,190,255,255,1,0,0,0,4,190,255,255, + 2,0,0,0,2,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255, + 11,0,0,0,1,0,255,0,1,190,190,255,7,0,0,255,1,190,190,255, + 3,190,255,255,1,0,0,0,3,190,255,255,1,0,0,0,2,190,255,255, + 4,0,255,0,2,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255, + 11,0,255,0,1,0,0,0,1,190,190,255,7,0,0,255,1,190,190,255, + 3,190,255,255,2,0,0,0,1,60,81,81,1,190,255,255,3,71,95,95, + 1,0,0,0,1,190,255,255,2,0,0,0,2,190,190,255,1,0,0,0, + 3,190,190,255,3,0,0,255,1,190,190,255,3,190,255,255,2,0,0,0, + 1,33,44,44,1,162,218,218,1,190,255,255,1,172,231,231,1,37,49,49, + 1,0,0,0,1,190,255,255,2,0,0,0,1,0,255,0,1,190,190,255, + 7,0,0,255,1,190,190,255,3,190,255,255,2,0,0,0,1,115,154,154, + 1,77,103,103,1,190,255,255,1,93,125,125,1,117,157,157,1,0,0,0, + 1,190,255,255,2,0,255,0,2,190,190,255,1,0,0,0,3,190,190,255, + 3,0,0,255,1,190,190,255,3,190,255,255,2,0,0,0,1,184,247,247, + 1,22,30,30,1,168,225,225,1,33,44,44,1,185,248,248,1,0,0,0, + 1,190,255,255,2,0,255,0,1,0,0,0,1,190,190,255,7,0,0,255, + 1,190,190,255,3,190,255,255,2,0,0,0,1,190,255,255,1,95,127,127, + 1,31,42,42,1,98,131,131,1,190,255,255,1,0,0,0,1,190,255,255, + 2,0,0,0,2,190,190,255,1,0,0,0,3,190,190,255,1,0,0,255, + 2,190,190,255,4,190,255,255,2,0,0,0,1,190,255,255,1,174,233,233, + 1,13,18,18,1,176,236,236,1,190,255,255,1,0,0,0,1,190,255,255, + 2,0,0,0,1,0,255,0,1,190,190,255,11,190,255,255,2,0,0,0, + 1,190,255,255,5,0,0,0,1,190,255,255,2,0,255,0,2,190,190,255, + 1,0,0,0,3,190,190,255,7,190,255,255,2,0,0,0,1,190,255,255, + 5,0,0,0,1,190,255,255,2,0,255,0,1,0,0,0,1,190,190,255, + 11,190,255,255,11,0,0,0,2,190,190,255,11,190,255,255,11,0,0,0, + 1,0,255,0,1,190,190,255,11,190,255,255,11,0,255,0,2,0,0,0, + 2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0, + 2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0, + 2,0,255,0,1,232,0,0,0,0,0,0,1,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0, + 1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255, + 48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,1,255,255,255,25,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 1,0,0) + ); + +const + objdata_tmsedbf: record size: integer; data: array[0..1930] of byte end = + (size: 1931; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,109,115, + 101,100,98,102,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,24,7,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,212,6,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255, + 1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255, + 1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255, + 1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255, + 1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255, + 1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255, + 1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255, + 1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255, + 1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255, + 1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255, + 1,135,255,255,1,138,255,255,1,0,0,0,2,3,5,5,1,102,174,174, + 1,152,255,255,1,155,255,255,1,157,255,255,1,0,0,0,2,1,1,1, + 1,16,24,24,1,105,155,155,1,174,255,255,1,177,255,255,1,0,0,0, + 4,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255, + 1,138,255,255,1,0,0,0,1,143,255,255,1,100,174,174,1,6,10,10, + 1,104,174,174,1,155,255,255,1,157,255,255,1,0,0,0,1,163,255,255, + 1,165,253,253,1,129,194,194,1,9,13,13,1,174,255,255,1,177,255,255, + 1,0,0,0,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255, + 1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255, + 1,0,0,0,1,143,255,255,1,146,255,255,1,102,174,174,1,3,5,5, + 1,155,255,255,1,157,255,255,1,0,0,0,1,163,255,255,1,165,254,254, + 1,131,197,197,1,71,106,106,1,174,255,255,1,177,255,255,1,0,0,0, + 1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255, + 1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,0,0,0, + 1,143,255,255,1,146,255,255,1,149,255,255,1,0,0,0,1,155,255,255, + 1,157,255,255,1,0,0,0,4,82,122,122,1,174,255,255,1,177,255,255, + 1,0,0,0,3,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255, + 1,132,255,255,1,135,255,255,1,138,255,255,1,0,0,0,1,143,255,255, + 1,146,255,255,1,102,174,174,1,3,5,5,1,155,255,255,1,157,255,255, + 1,0,0,0,1,163,255,255,1,165,254,254,1,144,217,217,1,8,12,12, + 1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255, + 1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255, + 1,135,255,255,1,138,255,255,1,0,0,0,1,143,255,255,1,100,174,174, + 1,6,10,10,1,104,174,174,1,155,255,255,1,157,255,255,1,0,0,0, + 1,163,255,255,1,166,255,255,1,129,195,195,1,21,31,31,1,174,255,255, + 1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1,189,255,255, + 1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255, + 1,138,255,255,1,0,0,0,2,3,5,5,1,102,174,174,1,152,255,255, + 1,155,255,255,1,157,255,255,1,0,0,0,2,1,1,1,1,21,31,31, + 1,121,180,180,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255, + 1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255, + 1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255, + 1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255, + 1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255, + 1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255, + 1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255, + 1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255, + 1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255, + 1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255, + 1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255, + 1,191,255,255,1,194,255,255,1,197,255,255,1,128,128,128,25,135,255,255, + 1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255, + 1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255, + 1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128, + 1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255, + 1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255,255, + 1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255, + 1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255, + 1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255, + 1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128, + 26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255, + 1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255, + 1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255, + 1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255, + 1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255, + 1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128, + 1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255, + 1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255, + 1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255, + 1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255, + 1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255, + 1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255, + 1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255, + 1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255, + 1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255, + 1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255, + 1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128, + 1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255, + 1,194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255, + 1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255, + 1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255, + 1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255, + 1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128, + 2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255, + 1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255, + 1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255, + 1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255, + 1,191,255,255,1,194,255,255,1,128,128,128,25,12,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsefixedformatdataset: record size: integer; data: array[0..1973] of byte end = + (size: 1974; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,109,115, + 101,102,105,120,101,100,102,111,114,109,97,116,100,97,116,97,115,101,116,23, + 98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105, + 111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95, + 99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,52,7,0,0,0,0,0,0,6,0,0,0,24,0,0,0, + 24,0,0,0,240,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,0,0,0,4,157,255,255,1, + 160,255,255,1,0,0,0,1,166,255,255,1,169,255,255,1,69,103,103,1, + 115,168,168,1,177,255,255,1,119,168,168,1,74,103,103,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,0,0,0,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 0,0,0,1,166,255,255,1,169,255,255,1,169,250,250,1,52,76,76,1, + 135,195,195,1,52,74,74,1,179,249,249,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,0,0,0,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,0,0,0,1, + 166,255,255,1,169,255,255,1,172,255,255,1,158,232,232,1,31,45,45,1, + 163,231,231,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,0,0,0,3,155,255,255,1,157,255,255,1, + 160,255,255,1,0,0,0,1,166,255,255,1,169,255,255,1,172,255,255,1, + 124,181,181,1,35,51,51,1,126,179,179,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,0,0,0,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 0,0,0,1,166,255,255,1,169,255,255,1,150,222,222,1,53,78,78,1, + 173,249,249,1,56,80,80,1,159,222,222,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,0,0,0,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,0,0,0,1, + 166,255,255,1,164,247,247,1,45,66,66,1,153,224,224,1,177,255,255,1, + 159,225,225,1,47,66,66,1,180,247,247,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,0,0,0,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,0,0,0,1,166,255,255,1, + 66,99,99,1,113,168,168,1,174,255,255,1,177,255,255,1,180,255,255,1, + 121,168,168,1,72,99,99,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,128,128,128,25, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,25,12,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsesdfdataset: record size: integer; data: array[0..1957] of byte end = + (size: 1958; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,115,100,102,100,97,116,97,115,101,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,7,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,232,6,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,98,179,179,1, + 20,36,36,1,3,5,5,1,27,46,46,1,115,193,193,1,155,255,255,1, + 157,255,255,1,0,0,0,2,3,5,5,1,115,174,174,1,172,255,255,1, + 174,255,255,1,177,255,255,1,0,0,0,4,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,12,21,21,1, + 105,187,187,1,143,249,249,1,103,176,176,1,18,30,30,1,155,255,255,1, + 157,255,255,1,0,0,0,1,163,255,255,1,113,174,174,1,7,10,10,1, + 117,174,174,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,25,46,46,1,85,152,152,1, + 137,240,240,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 0,0,0,1,163,255,255,1,166,255,255,1,115,174,174,1,3,5,5,1, + 174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,128,234,234,1,70,124,124,1,31,54,54,1, + 34,58,58,1,117,196,196,1,155,255,255,1,157,255,255,1,0,0,0,1, + 163,255,255,1,166,255,255,1,169,255,255,1,0,0,0,1,174,255,255,1, + 177,255,255,1,0,0,0,3,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,125,214,214,1,15,26,26,1,155,255,255,1, + 157,255,255,1,0,0,0,1,163,255,255,1,166,255,255,1,115,174,174,1, + 3,5,5,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,16,29,29,1,98,174,174,1, + 143,250,250,1,119,203,203,1,16,27,27,1,155,255,255,1,157,255,255,1, + 0,0,0,1,163,255,255,1,113,174,174,1,7,10,10,1,117,174,174,1, + 174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,105,191,191,1,25,45,45,1,3,5,5,1, + 22,37,37,1,112,188,188,1,155,255,255,1,157,255,255,1,0,0,0,2, + 3,5,5,1,115,174,174,1,172,255,255,1,174,255,255,1,177,255,255,1, + 0,0,0,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 128,128,128,25,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsememdataset: record size: integer; data: array[0..1957] of byte end = + (size: 1958; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,109,101,109,100,97,116,97,115,101,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,7,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,232,6,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,0,0,0,1,58,107,107,1,140,255,255,1, + 143,255,255,1,146,255,255,1,63,107,107,1,0,0,0,1,155,255,255,1, + 0,0,0,1,35,55,55,2,36,55,55,2,167,248,248,1,174,255,255,1, + 0,0,0,1,76,107,107,1,183,255,255,1,186,255,255,1,189,255,255,1, + 80,107,107,1,0,0,0,1,197,255,255,1,132,255,255,1,0,0,0,1, + 29,54,54,1,138,251,251,1,143,255,255,1,144,251,251,1,32,55,55,1, + 0,0,0,1,155,255,255,1,0,0,0,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,0,0,0,1, + 38,54,54,1,180,251,251,1,186,255,255,1,186,251,251,1,41,55,55,1, + 0,0,0,1,197,255,255,1,132,255,255,1,0,0,0,1,64,119,119,1, + 102,186,186,1,143,255,255,1,108,188,188,1,70,119,119,1,0,0,0,1, + 155,255,255,1,0,0,0,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,0,0,0,1,84,119,119,1, + 133,186,186,1,186,255,255,1,139,188,188,1,89,119,119,1,0,0,0,1, + 197,255,255,1,132,255,255,1,0,0,0,1,113,208,208,1,53,97,97,1, + 143,255,255,1,58,101,101,1,121,207,207,1,0,0,0,1,155,255,255,1, + 0,0,0,4,18,27,27,1,172,255,255,1,174,255,255,1,0,0,0,1, + 147,208,208,1,70,97,97,1,186,255,255,1,75,101,101,1,155,207,207,1, + 0,0,0,1,197,255,255,1,132,255,255,1,0,0,0,1,137,254,254,1, + 31,56,56,1,136,243,243,1,33,58,58,1,148,254,254,1,0,0,0,1, + 155,255,255,1,0,0,0,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,0,0,0,1,179,254,254,1, + 40,56,56,1,177,243,243,1,43,58,58,1,190,254,254,1,0,0,0,1, + 197,255,255,1,132,255,255,1,0,0,0,1,138,255,255,1,71,129,129,1, + 58,103,103,1,73,127,127,1,149,255,255,1,0,0,0,1,155,255,255,1, + 0,0,0,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,0,0,0,1,180,255,255,1,93,129,129,1, + 75,103,103,1,94,127,127,1,191,255,255,1,0,0,0,1,197,255,255,1, + 132,255,255,1,0,0,0,1,138,255,255,1,120,218,218,1,0,0,0,1, + 123,214,214,1,149,255,255,1,0,0,0,1,155,255,255,1,0,0,0,1, + 35,55,55,2,36,55,55,2,142,211,211,1,174,255,255,1,0,0,0,1, + 180,255,255,1,156,218,218,1,0,0,0,1,159,214,214,1,191,255,255,1, + 0,0,0,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 128,128,128,25,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsepqconnection: record size: integer; data: array[0..1360] of byte end = + (size: 1361; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,112,113,99,111,110,110,101,99,116,105,111,110,12,98,105,116,109,97,112, + 46,105,109,97,103,101,10,28,5,0,0,0,0,0,0,0,0,0,0,24, + 0,0,0,24,0,0,0,232,4,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,40,0,0,0,1,3,3,3,1,5,5,5,1,18, + 16,9,1,19,17,9,1,0,0,255,6,23,23,23,1,42,42,42,1,101, + 101,101,1,127,125,122,1,79,75,64,1,24,24,24,1,6,6,6,1,17, + 17,17,1,61,61,61,1,116,116,116,1,129,129,129,1,70,70,70,1,29, + 29,29,1,14,14,14,1,77,77,77,1,126,126,126,1,134,134,134,1,67, + 67,67,1,26,26,26,1,4,4,4,1,0,0,255,3,26,26,26,1,140, + 140,140,1,178,178,178,3,176,176,176,1,126,126,126,1,47,47,47,1,105, + 105,105,1,173,173,173,1,178,178,178,3,167,167,167,1,117,117,117,1,59, + 59,59,1,114,114,114,1,167,167,167,1,178,178,178,1,140,140,140,1,31, + 31,31,1,32,26,11,1,0,0,255,1,4,4,4,1,67,67,67,1,178, + 178,178,4,156,156,156,1,91,91,91,1,105,105,105,1,172,172,172,1,178, + 178,178,6,141,141,141,1,70,70,70,1,118,118,118,1,168,168,168,1,178, + 178,178,1,121,121,121,1,11,10,7,1,0,0,255,1,5,5,5,1,135, + 135,135,1,178,178,178,3,177,177,177,1,132,132,132,1,70,70,70,1,153, + 153,153,1,174,174,174,1,177,177,177,1,178,178,178,5,175,175,175,1,133, + 133,133,1,45,45,45,1,127,127,126,1,174,174,174,1,135,135,135,1,5, + 5,5,1,0,0,255,1,5,5,5,1,135,135,135,1,178,178,178,3,176, + 176,176,1,120,120,120,1,39,39,39,1,117,117,117,1,128,128,128,1,152, + 152,152,1,172,172,172,1,178,178,178,3,177,177,177,1,144,144,144,1,97, + 97,97,1,18,18,18,1,79,78,74,1,168,168,167,1,135,135,135,1,6, + 6,6,1,0,0,255,1,11,11,7,1,135,135,135,1,178,178,178,3,176, + 176,176,1,122,122,122,1,24,24,24,1,44,44,44,1,32,32,32,1,60, + 60,60,1,134,134,134,1,178,178,178,3,156,156,156,1,64,64,64,1,9, + 9,9,1,10,10,10,1,42,41,39,1,162,162,161,1,122,122,122,1,14, + 12,8,1,0,0,255,1,29,26,15,1,129,129,129,1,178,178,178,3,176, + 176,176,1,133,133,133,1,67,67,67,1,97,97,97,1,64,64,64,1,33, + 33,33,1,98,98,98,1,178,178,178,3,109,109,109,1,32,32,32,1,41, + 41,41,1,56,56,56,1,90,90,90,1,168,168,168,1,72,72,72,1,0, + 0,255,3,86,86,86,1,178,178,178,3,176,176,176,1,142,142,142,1,109, + 109,109,1,173,173,173,1,161,161,161,1,110,110,110,1,107,107,107,1,168, + 168,168,1,178,178,178,2,109,109,109,1,56,56,56,1,127,127,127,1,91, + 91,91,1,130,130,130,1,157,157,157,1,28,28,28,1,0,0,255,3,33, + 33,33,1,178,178,178,3,173,173,173,1,133,133,133,1,109,109,109,1,178, + 178,178,2,127,127,127,1,93,92,90,1,152,151,149,1,178,178,178,2,135, + 135,135,1,60,60,60,1,126,126,126,1,91,91,91,1,130,130,130,1,114, + 114,114,1,18,18,18,1,0,0,255,3,29,29,29,1,154,154,154,1,178, + 178,178,2,163,163,161,1,105,103,98,1,109,109,109,1,178,178,178,1,172, + 172,172,1,110,110,110,1,98,96,93,1,165,164,161,1,178,178,178,2,174, + 174,174,1,82,82,82,1,81,81,81,1,101,101,101,1,128,128,128,1,69, + 69,69,1,0,0,255,5,111,111,111,1,178,178,178,2,167,166,164,1,103, + 101,96,1,78,78,78,1,166,166,166,1,162,162,162,1,90,90,90,1,105, + 105,105,1,178,178,178,4,131,131,131,1,55,55,55,1,48,48,48,1,60, + 60,60,1,28,28,28,1,0,0,255,5,65,65,65,1,169,169,169,1,178, + 178,178,1,177,177,177,1,134,134,134,1,59,59,59,1,122,122,122,1,133, + 133,133,1,80,80,80,1,126,126,126,1,178,178,178,4,98,98,98,1,23, + 23,23,1,2,2,2,1,0,0,0,1,0,0,255,6,19,19,19,1,84, + 84,84,1,178,178,178,1,177,177,177,1,142,142,142,1,63,63,63,1,72, + 72,72,1,60,60,60,1,30,30,30,1,95,95,95,1,164,164,164,1,178, + 178,178,3,52,52,52,1,0,0,0,3,0,0,255,7,11,11,11,1,67, + 67,67,1,76,76,76,1,80,80,80,1,41,41,41,1,61,61,61,1,80, + 80,80,1,255,255,255,1,134,134,134,1,146,146,146,1,178,178,178,3,52, + 52,52,1,0,0,0,4,0,0,255,8,31,31,31,1,15,15,15,1,12, + 11,11,1,28,27,23,1,255,255,255,2,105,105,105,1,142,142,142,1,178, + 178,178,3,52,52,52,1,255,255,255,3,22,22,22,1,0,0,255,11,5, + 4,1,1,45,44,42,1,54,54,54,1,58,58,58,1,142,142,142,1,178, + 178,178,3,118,118,118,1,79,79,79,1,74,74,74,2,17,17,17,1,0, + 0,255,14,58,58,58,1,142,142,142,1,178,178,178,3,145,145,145,1,33, + 33,33,1,0,0,255,17,61,61,61,1,142,142,142,1,178,178,178,3,145, + 145,145,1,33,33,33,1,0,0,255,17,90,90,90,1,142,142,142,1,178, + 178,178,3,145,145,145,1,33,33,33,1,0,0,255,17,40,40,40,1,103, + 103,103,1,169,169,169,1,178,178,178,2,64,64,64,1,4,4,4,1,0, + 0,255,18,40,38,29,1,109,107,100,1,135,135,135,1,220,220,220,1,6, + 6,6,1,0,0,255,20,14,12,7,1,6,6,6,1,0,0,255,8,0, + 0) + ); + +const + objdata_tmseodbcconnection: record size: integer; data: array[0..1561] of byte end = + (size: 1562; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,109,115, + 101,111,100,98,99,99,111,110,110,101,99,116,105,111,110,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 156,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 36,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,31, + 255,28,28,1,255,34,23,1,255,34,21,1,255,34,22,3,255,34,23,1, + 255,34,21,1,255,33,23,1,255,28,28,1,208,208,208,13,255,36,24,1, + 255,34,22,9,255,33,22,1,254,28,41,1,249,0,162,1,208,208,208,9, + 255,23,23,1,255,35,23,1,255,34,22,11,251,9,122,1,249,0,162,2, + 208,208,208,7,255,28,28,1,255,34,22,12,253,24,66,1,249,0,162,4, + 208,208,208,6,255,34,21,1,255,34,22,11,255,32,29,1,249,1,159,1, + 249,0,162,5,208,208,208,4,255,35,24,1,255,34,22,8,255,35,22,1, + 255,34,22,3,250,6,136,1,249,0,162,6,208,208,208,3,255,32,32,1, + 255,34,22,7,255,35,22,1,255,64,0,1,208,208,208,2,255,43,43,1, + 252,15,95,1,249,0,162,8,208,208,208,2,255,36,22,1,255,34,22,6, + 255,36,22,1,208,208,208,6,249,0,162,8,208,208,208,2,255,33,21,1, + 255,34,22,5,255,35,22,1,208,208,208,8,249,0,162,7,208,208,208,2, + 255,34,23,1,255,34,22,5,208,208,208,10,249,0,162,6,208,208,208,2, + 255,34,22,5,255,35,22,1,208,208,208,10,249,0,162,7,208,208,208,1, + 255,34,22,4,241,44,35,1,223,57,51,1,208,208,208,10,249,0,162,7, + 208,208,208,1,48,182,211,1,21,202,236,1,11,208,245,1,3,214,252,1, + 0,216,255,1,13,206,243,1,208,208,208,10,249,0,162,6,208,208,208,2, + 0,216,255,6,0,223,255,1,208,208,208,8,249,0,162,7,208,208,208,2, + 0,216,255,6,0,217,255,1,208,208,208,7,249,0,162,8,208,208,208,2, + 0,216,255,7,0,217,255,1,0,221,255,1,208,208,208,4,0,216,255,1, + 180,60,188,1,249,0,162,7,208,208,208,2,0,213,255,1,0,216,255,13, + 1,215,255,1,204,39,179,1,249,0,162,5,208,208,208,4,0,214,255,1, + 0,216,255,13,3,213,254,1,218,28,174,1,249,0,162,4,208,208,208,5, + 0,215,255,1,0,216,255,13,8,209,252,1,227,20,170,1,249,0,162,2, + 208,208,208,7,0,217,255,1,0,216,255,13,65,160,231,1,249,0,162,1, + 208,208,208,9,0,215,255,1,0,216,255,12,208,208,208,13,0,214,255,1, + 0,216,255,1,0,215,255,1,0,216,255,4,0,215,255,1,0,213,255,1, + 208,208,208,32,64,3,0,0,0,0,0,31,9,9,9,1,67,67,67,1, + 120,120,120,1,172,172,172,1,224,224,224,1,240,240,240,1,204,204,204,1, + 167,167,167,1,101,101,101,1,9,9,9,1,0,0,0,13,64,64,64,1, + 222,222,222,1,255,255,255,8,236,236,236,1,125,125,125,1,10,10,10,1, + 0,0,0,9,11,11,11,1,147,147,147,1,254,254,254,1,255,255,255,9, + 253,253,253,1,215,215,215,1,210,210,210,1,36,36,36,1,0,0,0,7, + 9,9,9,1,211,211,211,1,255,255,255,11,195,195,195,1,255,255,255,2, + 240,240,240,1,45,45,45,1,0,0,0,6,144,144,144,1,255,255,255,11, + 216,216,216,1,251,251,251,1,255,255,255,3,217,217,217,1,13,13,13,1, + 0,0,0,4,65,65,65,1,254,254,254,1,255,255,255,6,247,247,247,1, + 199,199,199,1,193,193,193,1,247,247,247,1,246,246,246,1,223,223,223,1, + 255,255,255,5,157,157,157,1,0,0,0,3,8,8,8,1,224,224,224,1, + 255,255,255,5,242,242,242,1,103,103,103,1,4,4,4,1,0,0,0,2, + 6,6,6,1,66,66,66,1,234,234,234,1,255,255,255,5,250,250,250,1, + 25,25,25,1,0,0,0,2,57,57,57,1,255,255,255,5,240,240,240,1, + 35,35,35,1,0,0,0,6,37,37,37,1,222,222,222,1,255,255,255,5, + 127,127,127,1,0,0,0,2,108,108,108,1,255,255,255,5,94,94,94,1, + 0,0,0,8,40,40,40,1,255,255,255,5,205,205,205,1,0,0,0,2, + 158,158,158,1,255,255,255,4,237,237,237,1,0,0,0,10,216,216,216,1, + 255,255,255,4,239,239,239,1,0,0,0,2,209,209,209,1,255,255,255,4, + 184,184,184,1,0,0,0,10,142,142,142,1,255,255,255,5,17,17,17,1, + 0,0,0,1,244,244,244,1,255,255,255,4,160,160,160,1,0,0,0,10, + 121,121,121,1,255,255,255,5,14,14,14,1,0,0,0,1,165,165,165,1, + 217,217,217,1,232,232,232,1,249,249,249,1,255,255,255,1,207,207,207,1, + 0,0,0,10,184,184,184,1,255,255,255,4,238,238,238,1,0,0,0,2, + 155,155,155,1,255,255,255,4,250,250,250,1,16,16,16,1,0,0,0,8, + 16,16,16,1,243,243,243,1,255,255,255,4,197,197,197,1,0,0,0,2, + 110,110,110,1,255,255,255,5,166,166,166,1,0,0,0,7,8,8,8,1, + 193,193,193,1,255,255,255,5,105,105,105,1,0,0,0,2,65,65,65,1, + 255,255,255,6,153,153,153,1,15,15,15,1,0,0,0,4,26,26,26,1, + 141,141,141,1,255,255,255,5,245,245,245,1,16,16,16,1,0,0,0,2, + 12,12,12,1,222,222,222,1,255,255,255,6,234,234,234,1,163,163,163,1, + 110,110,110,1,125,125,125,1,170,170,170,1,249,249,249,1,234,234,234,1, + 212,212,212,1,255,255,255,4,116,116,116,1,0,0,0,4,50,50,50,1, + 248,248,248,1,255,255,255,12,229,229,229,1,230,230,230,1,255,255,255,2, + 200,200,200,1,3,3,3,1,0,0,0,5,103,103,103,1,255,255,255,13, + 224,224,224,1,245,245,245,1,211,211,211,1,23,23,23,1,0,0,0,7, + 114,114,114,1,240,240,240,1,255,255,255,11,252,252,252,1,145,145,145,1, + 19,19,19,1,0,0,0,9,19,19,19,1,144,144,144,1,249,249,249,1, + 255,255,255,7,254,254,254,1,190,190,190,1,46,46,46,1,0,0,0,13, + 31,31,31,1,91,91,91,1,128,128,128,1,165,165,165,1,202,202,202,1, + 198,198,198,1,138,138,138,1,77,77,77,1,18,18,18,1,0,0,0,32, + 0,0) + ); + +const + objdata_tmsemysqlconnection: record size: integer; data: array[0..1746] of byte end = + (size: 1747; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,109,115, + 101,109,121,115,113,108,99,111,110,110,101,99,116,105,111,110,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,84,6,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,84,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255, + 24,143,104,0,1,160,116,0,1,169,123,0,1,164,119,0,1,157,114,0, + 1,143,104,0,1,255,255,255,18,143,104,0,1,188,137,0,1,204,149,1, + 1,205,150,2,1,214,156,0,1,184,134,0,1,166,121,0,1,158,115,0, + 1,149,108,0,1,255,255,255,16,164,119,0,1,209,152,1,1,183,155,80, + 1,191,161,81,1,184,144,39,1,204,150,6,1,224,163,0,1,197,144,0, + 1,161,117,0,1,143,104,0,1,255,255,255,14,153,111,0,1,198,144,0, + 1,183,146,49,1,255,255,255,1,255,254,254,1,218,203,163,1,185,150,58, + 1,197,146,11,1,224,163,0,1,170,124,0,1,147,107,0,1,255,255,255, + 14,164,120,0,1,198,147,9,1,227,217,189,1,231,222,197,1,177,138,34, + 1,212,194,143,1,225,213,180,1,182,142,37,1,220,160,0,1,168,123,2, + 1,143,104,0,1,255,255,255,13,152,111,0,1,203,148,3,1,187,156,71, + 1,235,227,206,1,181,141,32,1,178,143,51,1,255,255,255,1,247,244,236, + 1,184,151,63,1,214,156,2,1,166,121,1,1,143,104,0,1,255,255,255, + 12,143,104,0,1,171,126,3,1,187,144,30,1,247,244,237,1,244,240,230, + 1,236,229,211,1,255,255,255,2,252,251,248,1,183,148,55,1,217,158,0, + 1,162,118,0,1,255,255,255,13,159,116,0,1,205,149,1,1,205,183,125, + 1,255,255,255,5,246,243,234,1,181,143,39,1,198,145,1,1,155,113,0, + 1,255,255,255,12,143,104,0,1,187,139,12,1,190,157,72,1,255,255,255, + 6,221,208,170,1,200,149,9,1,166,120,0,1,143,104,0,1,255,255,255, + 12,179,133,10,1,190,157,68,1,255,255,255,7,184,150,60,1,207,151,2, + 1,157,114,0,1,255,255,255,12,178,133,12,1,189,155,63,1,255,255,255, + 7,234,226,205,1,192,145,19,1,172,125,1,1,143,104,0,1,255,255,255, + 11,178,133,13,1,189,153,59,1,255,255,255,1,255,254,254,1,255,255,255, + 6,190,161,83,1,214,156,0,1,161,117,0,1,255,255,255,11,177,132,12, + 1,189,153,56,1,239,233,218,1,166,129,31,1,244,240,230,1,255,255,255, + 5,245,242,233,1,185,143,32,1,204,150,1,1,158,115,0,1,255,255,255, + 10,169,124,3,1,185,146,44,1,200,176,111,1,215,156,0,1,175,138,39, + 1,255,255,255,6,207,185,127,1,202,151,14,1,182,135,6,1,153,111,0, + 1,255,255,255,9,157,114,0,1,187,138,6,1,166,128,24,1,198,144,1, + 1,199,145,1,1,210,190,138,1,255,255,255,6,215,198,152,1,188,145,29, + 1,192,142,10,1,160,116,0,1,143,104,0,1,255,255,255,7,143,104,0, + 1,163,121,8,1,178,130,1,1,154,112,0,1,165,120,0,1,174,130,14, + 1,245,241,232,1,255,255,255,6,239,232,215,1,187,153,63,1,189,140,9, + 1,164,120,2,1,143,104,0,1,255,255,255,7,143,104,0,1,147,107,0, + 1,255,255,255,1,143,104,0,1,159,116,1,1,176,142,51,1,255,255,255, + 7,225,212,180,1,171,136,43,1,189,138,3,1,162,118,0,1,143,104,0, + 1,255,255,255,10,143,104,0,1,161,123,21,1,223,211,180,1,255,255,255, + 5,201,178,114,1,194,144,12,1,188,139,10,1,183,134,3,1,164,119,0, + 1,147,107,0,1,255,255,255,12,225,214,186,1,255,255,255,5,222,207,168, + 1,190,145,25,1,193,141,2,1,155,113,0,1,255,255,255,21,219,203,162, + 1,185,140,21,1,196,143,1,1,157,115,0,1,255,255,255,21,216,201,158, + 1,173,133,26,1,157,114,0,1,151,110,0,1,255,255,255,22,173,140,50, + 1,153,111,0,1,255,255,255,25,200,2,0,0,0,0,0,24,5,5,5, + 1,175,175,175,1,194,194,194,1,181,181,181,1,128,128,128,1,26,26,26, + 1,0,0,0,18,34,34,34,1,234,234,234,1,252,252,252,2,255,255,255, + 1,230,230,230,1,199,199,199,1,157,157,157,1,68,68,68,1,0,0,0, + 16,198,198,198,1,252,252,252,1,255,255,255,2,249,249,249,1,251,251,251, + 1,255,255,255,1,241,241,241,1,185,185,185,1,29,29,29,1,0,0,0, + 14,72,72,72,1,241,241,241,1,251,251,251,1,255,255,255,4,249,249,249, + 1,255,255,255,1,214,214,214,1,34,34,34,1,0,0,0,14,196,196,196, + 1,250,250,250,1,255,255,255,5,253,253,253,1,255,255,255,1,215,215,215, + 1,26,26,26,1,0,0,0,13,82,82,82,1,249,249,249,1,255,255,255, + 8,213,213,213,1,22,22,22,1,0,0,0,12,1,1,1,1,211,211,211, + 1,255,255,255,9,195,195,195,1,0,0,0,13,137,137,137,1,255,255,255, + 8,253,253,253,1,244,244,244,1,83,83,83,1,0,0,0,12,17,17,17, + 1,241,241,241,1,255,255,255,8,250,250,250,1,209,209,209,1,3,3,3, + 1,0,0,0,12,231,231,231,1,255,255,255,9,251,251,251,1,122,122,122, + 1,0,0,0,12,228,228,228,1,255,255,255,9,252,252,252,1,219,219,219, + 1,15,15,15,1,0,0,0,11,226,226,226,1,255,255,255,11,182,182,182, + 1,0,0,0,11,227,227,227,1,255,255,255,10,254,254,254,1,245,245,245, + 1,117,117,117,1,0,0,0,10,216,216,216,1,253,253,253,1,255,255,255, + 2,223,223,223,1,255,255,255,7,253,253,253,1,232,232,232,1,62,62,62, + 1,0,0,0,9,137,137,137,1,251,251,251,1,248,248,248,1,244,244,244, + 1,246,246,246,1,243,243,243,1,255,255,255,8,243,243,243,1,153,153,153, + 1,7,7,7,1,0,0,0,7,8,8,8,1,206,206,206,1,238,238,238, + 1,131,131,131,1,212,212,212,1,238,238,238,1,255,255,255,9,251,251,251, + 1,206,206,206,1,19,19,19,1,0,0,0,7,10,10,10,1,65,65,65, + 1,0,0,0,1,19,19,19,1,211,211,211,1,247,247,247,1,255,255,255, + 9,253,253,253,1,197,197,197,1,6,6,6,1,0,0,0,10,10,10,10, + 1,210,210,210,1,237,237,237,1,251,251,251,1,255,255,255,6,249,249,249, + 1,232,232,232,1,209,209,209,1,62,62,62,1,0,0,0,12,126,126,126, + 1,155,155,155,1,176,176,176,1,197,197,197,1,220,220,220,1,241,241,241, + 1,255,255,255,1,252,252,252,1,238,238,238,1,136,136,136,1,0,0,0, + 14,7,7,7,1,35,35,35,1,67,67,67,1,101,101,101,1,122,122,122, + 1,143,143,143,1,166,166,166,1,207,207,207,1,246,246,246,1,240,240,240, + 1,112,112,112,1,0,0,0,17,8,8,8,1,28,28,28,1,59,59,59, + 1,90,90,90,1,142,142,142,1,221,221,221,1,239,239,239,1,50,50,50, + 1,0,0,0,20,5,5,5,1,21,21,21,1,103,103,103,1,147,147,147, + 1,0,0,0,25,0,0) + ); + +const + objdata_tenumeditdb: record size: integer; data: array[0..1426] of byte end = + (size: 1427; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,101,110, + 117,109,101,100,105,116,100,98,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,28,5,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,216,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,1,238,238,238, + 1,29,29,29,1,255,255,255,1,172,172,172,1,21,21,21,1,18,18,18, + 1,148,148,148,1,115,115,115,1,15,15,15,2,128,128,128,1,255,255,255, + 2,0,0,0,1,234,234,234,1,23,23,23,1,255,255,255,6,128,128,128, + 1,255,255,255,1,98,98,98,1,0,0,0,1,255,255,255,1,29,29,29, + 1,201,201,201,1,209,209,209,1,10,10,10,1,255,255,255,2,194,194,194, + 1,17,17,17,1,255,255,255,3,0,0,0,1,255,255,255,2,208,208,208, + 3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,247,247,247, + 1,0,0,0,1,255,255,255,3,205,205,205,1,68,68,68,1,255,255,255, + 1,164,164,164,1,4,4,4,1,103,103,103,1,255,255,255,3,0,0,0, + 1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128, + 1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,70,70,70, + 1,232,232,232,1,255,255,255,2,214,214,214,1,10,10,10,1,255,255,255, + 3,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208, + 1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0,0,0, + 1,255,255,255,1,165,165,165,1,77,77,77,1,235,235,235,1,255,255,255, + 1,32,32,32,1,227,227,227,1,234,234,234,1,24,24,24,1,255,255,255, + 1,252,252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255,255,255, + 1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255, + 2,0,0,0,1,255,255,255,1,19,19,19,1,0,0,0,3,177,177,177, + 1,19,19,19,1,24,24,24,1,179,179,179,1,255,255,255,1,223,223,223, + 1,0,0,0,1,223,223,223,1,0,0,0,1,128,128,128,5,255,255,255, + 25,0,0,0,25,184,255,255,17,255,255,255,5,0,0,0,2,184,255,255, + 2,119,165,165,1,0,0,0,1,119,165,165,1,184,255,255,2,0,0,0, + 1,1,1,1,1,54,75,75,1,184,255,255,1,167,232,232,1,56,77,77, + 1,6,9,9,1,27,38,38,1,146,203,203,1,184,255,255,1,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,184,255,255,2,63,88,88,1,54,75,75,1,64,89,89,1,184,255,255, + 2,0,0,0,1,169,234,234,1,51,70,70,1,184,255,255,1,59,82,82, + 1,85,118,118,1,177,245,245,1,120,166,166,1,38,53,53,1,184,255,255, + 1,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,184,255,255, + 1,181,251,251,1,15,21,21,1,159,221,221,1,14,20,20,1,181,251,251, + 1,184,255,255,1,0,0,0,2,84,117,117,1,184,255,255,1,9,12,12, + 1,174,241,241,1,184,255,255,4,255,255,255,1,208,208,208,3,128,128,128, + 1,0,0,0,2,184,255,255,1,138,191,191,1,0,0,0,3,138,191,191, + 1,184,255,255,1,0,0,0,1,175,243,243,1,8,11,11,1,184,255,255, + 1,10,14,14,1,174,241,241,1,184,255,255,1,182,252,252,1,152,210,210, + 1,184,255,255,1,128,128,128,5,0,0,0,2,184,255,255,1,82,114,114, + 1,102,141,141,1,184,255,255,1,102,141,141,1,83,115,115,1,184,255,255, + 1,0,0,0,1,170,235,235,1,14,19,19,1,184,255,255,1,60,83,83, + 1,89,124,124,1,177,245,245,1,105,145,145,1,41,57,57,1,184,255,255, + 1,255,255,255,1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255, + 1,0,0,0,2,184,255,255,1,27,37,37,1,157,217,217,1,184,255,255, + 1,157,217,217,1,27,38,38,1,184,255,255,1,0,0,0,1,2,3,3, + 1,89,124,124,1,184,255,255,1,164,227,227,1,45,63,63,1,5,7,7, + 1,31,43,43,1,154,213,213,1,184,255,255,1,255,255,255,4,128,128,128, + 1,0,0,0,2,184,255,255,17,255,255,255,1,128,128,128,4,0,0,0, + 2,184,255,255,2,0,0,0,2,4,5,5,1,126,174,174,1,184,255,255, + 11,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208, + 1,0,0,0,2,184,255,255,2,0,0,0,1,184,255,255,1,126,174,174, + 1,4,5,5,1,184,255,255,1,110,152,152,1,8,11,11,1,115,159,159, + 1,184,255,255,7,255,255,255,2,252,252,252,1,255,255,255,2,0,0,0, + 2,184,255,255,2,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255, + 1,21,29,29,1,142,197,197,1,27,37,37,1,184,255,255,7,255,255,255, + 1,208,208,208,3,128,128,128,1,0,0,0,2,184,255,255,2,0,0,0, + 1,184,255,255,2,0,0,0,1,184,255,255,1,1,2,2,1,0,0,0, + 1,2,3,3,1,184,255,255,7,255,255,255,1,0,0,0,3,128,128,128, + 1,0,0,0,2,184,255,255,2,0,0,0,1,184,255,255,1,126,174,174, + 1,4,5,5,1,184,255,255,1,18,25,25,1,163,226,226,1,184,255,255, + 8,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,0,0,0,2,184,255,255,2,0,0,0,2,4,5,5,1,126,174,174, + 1,184,255,255,1,105,146,146,1,6,9,9,1,71,98,98,1,184,255,255, + 7,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,66,0,0) + ); + +const + objdata_tenum64editdb: record size: integer; data: array[0..1372] of byte end = + (size: 1373; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,101,110, + 117,109,54,52,101,100,105,116,100,98,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,228,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,160,4,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,1,238, + 238,238,1,29,29,29,1,255,255,255,1,172,172,172,1,21,21,21,1,18, + 18,18,1,148,148,148,1,115,115,115,1,15,15,15,2,128,128,128,1,255, + 255,255,2,0,0,0,1,234,234,234,1,23,23,23,1,255,255,255,6,128, + 128,128,1,255,255,255,1,98,98,98,1,0,0,0,1,255,255,255,1,29, + 29,29,1,201,201,201,1,209,209,209,1,10,10,10,1,255,255,255,2,194, + 194,194,1,17,17,17,1,255,255,255,3,0,0,0,1,255,255,255,2,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,247, + 247,247,1,0,0,0,1,255,255,255,3,205,205,205,1,68,68,68,1,255, + 255,255,1,164,164,164,1,4,4,4,1,103,103,103,1,255,255,255,3,0, + 0,0,1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128, + 128,128,1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,70, + 70,70,1,232,232,232,1,255,255,255,2,214,214,214,1,10,10,10,1,255, + 255,255,3,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0, + 0,0,1,255,255,255,1,165,165,165,1,77,77,77,1,235,235,235,1,255, + 255,255,1,32,32,32,1,227,227,227,1,234,234,234,1,24,24,24,1,255, + 255,255,1,252,252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255, + 255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,2,0,0,0,1,255,255,255,1,19,19,19,1,0,0,0,3,177, + 177,177,1,19,19,19,1,24,24,24,1,179,179,179,1,255,255,255,1,223, + 223,223,1,0,0,0,1,223,223,223,1,0,0,0,1,128,128,128,5,255, + 255,255,25,0,0,0,25,184,255,255,17,255,255,255,5,0,0,0,2,184, + 255,255,17,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128, + 128,128,1,0,0,0,2,184,255,255,2,183,253,253,1,96,133,133,1,17, + 24,24,1,4,5,5,1,53,73,73,1,166,230,230,1,184,255,255,5,131, + 182,182,1,1,2,2,1,184,255,255,2,255,255,255,1,0,0,0,3,128, + 128,128,1,0,0,0,2,184,255,255,2,102,142,142,1,22,30,30,1,126, + 174,174,1,139,193,193,1,47,65,65,1,56,77,77,1,184,255,255,4,155, + 215,215,1,10,14,14,1,0,0,0,1,184,255,255,2,255,255,255,1,208, + 208,208,3,128,128,128,1,0,0,0,2,184,255,255,1,183,254,254,1,22, + 30,30,1,130,180,180,1,184,255,255,2,168,233,233,1,127,176,176,1,184, + 255,255,3,172,238,238,1,26,36,36,1,82,114,114,1,0,0,0,1,184, + 255,255,2,128,128,128,5,0,0,0,2,184,255,255,1,169,234,234,1,0, + 0,0,1,108,149,149,1,19,27,27,1,6,8,8,1,61,84,84,1,171, + 237,237,1,184,255,255,2,181,251,251,1,50,69,69,1,79,109,109,1,155, + 215,215,1,0,0,0,1,184,255,255,2,255,255,255,1,212,212,212,1,252, + 252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,184,255,255,1,156, + 216,216,1,0,0,0,1,35,49,49,1,136,188,188,1,141,195,195,1,40, + 55,55,1,58,81,81,1,184,255,255,2,80,111,111,1,48,67,67,1,180, + 250,250,1,155,215,215,1,0,0,0,1,184,255,255,2,255,255,255,4,128, + 128,128,1,0,0,0,2,184,255,255,1,159,221,221,1,0,0,0,1,152, + 210,210,1,184,255,255,2,153,212,212,1,1,1,1,1,173,240,240,1,115, + 160,160,1,25,35,35,1,171,237,237,1,184,255,255,1,155,215,215,1,0, + 0,0,1,184,255,255,2,255,255,255,1,128,128,128,4,0,0,0,2,184, + 255,255,1,175,242,242,1,0,0,0,1,180,249,249,1,184,255,255,2,180, + 249,249,1,0,0,0,1,159,220,220,1,66,91,91,1,0,0,0,6,77, + 107,107,1,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208, + 208,208,1,0,0,0,2,184,255,255,2,29,40,40,1,141,195,195,1,184, + 255,255,2,144,200,200,1,5,7,7,1,178,246,246,1,165,229,229,1,155, + 215,215,3,131,181,181,1,0,0,0,1,155,215,215,1,167,231,231,1,255, + 255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,184,255,255,2,104, + 144,144,1,25,35,35,1,130,180,180,1,131,182,182,1,29,40,40,1,76, + 106,106,1,184,255,255,5,155,215,215,1,0,0,0,1,184,255,255,2,255, + 255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,184,255,255,2,182, + 252,252,1,81,112,112,1,9,12,12,1,11,15,15,1,76,106,106,1,178, + 247,247,1,184,255,255,5,155,215,215,1,0,0,0,1,184,255,255,2,255, + 255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,184,255,255,17,255, + 255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0, + 0,0,2,184,255,255,17,128,128,128,5,0,0,0,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tenumeditlb: record size: integer; data: array[0..1426] of byte end = + (size: 1427; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,101,110, + 117,109,101,100,105,116,108,98,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,28,5,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,216,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,1,238,238,238, + 1,29,29,29,1,255,255,255,1,172,172,172,1,21,21,21,1,18,18,18, + 1,148,148,148,1,115,115,115,1,15,15,15,2,128,128,128,1,255,255,255, + 2,0,0,0,1,234,234,234,1,23,23,23,1,255,255,255,6,128,128,128, + 1,255,255,255,1,98,98,98,1,0,0,0,1,255,255,255,1,29,29,29, + 1,201,201,201,1,209,209,209,1,10,10,10,1,255,255,255,2,194,194,194, + 1,17,17,17,1,255,255,255,3,0,0,0,1,255,255,255,2,208,208,208, + 3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,247,247,247, + 1,0,0,0,1,255,255,255,3,205,205,205,1,68,68,68,1,255,255,255, + 1,164,164,164,1,4,4,4,1,103,103,103,1,255,255,255,3,0,0,0, + 1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128, + 1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,70,70,70, + 1,232,232,232,1,255,255,255,2,214,214,214,1,10,10,10,1,255,255,255, + 3,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208, + 1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0,0,0, + 1,255,255,255,1,165,165,165,1,77,77,77,1,235,235,235,1,255,255,255, + 1,32,32,32,1,227,227,227,1,234,234,234,1,24,24,24,1,255,255,255, + 1,252,252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255,255,255, + 1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255, + 2,0,0,0,1,255,255,255,1,19,19,19,1,0,0,0,3,177,177,177, + 1,19,19,19,1,24,24,24,1,179,179,179,1,255,255,255,1,223,223,223, + 1,0,0,0,1,223,223,223,1,0,0,0,1,128,128,128,5,255,255,255, + 25,0,0,0,25,201,201,255,17,255,255,255,5,0,0,0,2,201,201,255, + 2,130,130,165,1,0,0,0,1,130,130,165,1,201,201,255,2,0,0,0, + 1,1,1,1,1,59,59,75,1,201,201,255,1,183,183,232,1,61,61,77, + 1,7,7,9,1,30,30,38,1,160,160,203,1,201,201,255,1,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,201,201,255,2,69,69,88,1,59,59,75,1,70,70,89,1,201,201,255, + 2,0,0,0,1,184,184,234,1,55,55,70,1,201,201,255,1,65,65,82, + 1,93,93,118,1,193,193,245,1,131,131,166,1,42,42,53,1,201,201,255, + 1,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,201,201,255, + 1,198,198,251,1,17,17,21,1,174,174,221,1,16,16,20,1,198,198,251, + 1,201,201,255,1,0,0,0,2,92,92,117,1,201,201,255,1,9,9,12, + 1,190,190,241,1,201,201,255,4,255,255,255,1,208,208,208,3,128,128,128, + 1,0,0,0,2,201,201,255,1,151,151,191,1,0,0,0,3,151,151,191, + 1,201,201,255,1,0,0,0,1,192,192,243,1,9,9,11,1,201,201,255, + 1,11,11,14,1,190,190,241,1,201,201,255,1,199,199,252,1,166,166,210, + 1,201,201,255,1,128,128,128,5,0,0,0,2,201,201,255,1,90,90,114, + 1,111,111,141,1,201,201,255,1,111,111,141,1,91,91,115,1,201,201,255, + 1,0,0,0,1,185,185,235,1,15,15,19,1,201,201,255,1,65,65,83, + 1,98,98,124,1,193,193,245,1,114,114,145,1,45,45,57,1,201,201,255, + 1,255,255,255,1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255, + 1,0,0,0,2,201,201,255,1,29,29,37,1,171,171,217,1,201,201,255, + 1,171,171,217,1,30,30,38,1,201,201,255,1,0,0,0,1,2,2,3, + 1,98,98,124,1,201,201,255,1,179,179,227,1,50,50,63,1,6,6,7, + 1,34,34,43,1,168,168,213,1,201,201,255,1,255,255,255,4,128,128,128, + 1,0,0,0,2,201,201,255,17,255,255,255,1,128,128,128,4,0,0,0, + 2,201,201,255,2,0,0,0,2,4,4,5,1,137,137,174,1,201,201,255, + 11,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208, + 1,0,0,0,2,201,201,255,2,0,0,0,1,201,201,255,1,137,137,174, + 1,4,4,5,1,201,201,255,1,120,120,152,1,9,9,11,1,125,125,159, + 1,201,201,255,7,255,255,255,2,252,252,252,1,255,255,255,2,0,0,0, + 2,201,201,255,2,0,0,0,1,201,201,255,2,0,0,0,1,201,201,255, + 1,23,23,29,1,155,155,197,1,29,29,37,1,201,201,255,7,255,255,255, + 1,208,208,208,3,128,128,128,1,0,0,0,2,201,201,255,2,0,0,0, + 1,201,201,255,2,0,0,0,1,201,201,255,1,2,2,2,1,0,0,0, + 1,2,2,3,1,201,201,255,7,255,255,255,1,0,0,0,3,128,128,128, + 1,0,0,0,2,201,201,255,2,0,0,0,1,201,201,255,1,137,137,174, + 1,4,4,5,1,201,201,255,1,20,20,25,1,178,178,226,1,201,201,255, + 8,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,0,0,0,2,201,201,255,2,0,0,0,2,4,4,5,1,137,137,174, + 1,201,201,255,1,115,115,146,1,7,7,9,1,77,77,98,1,201,201,255, + 7,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,66,0,0) + ); + +const + objdata_tenum64editlb: record size: integer; data: array[0..1372] of byte end = + (size: 1373; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,101,110, + 117,109,54,52,101,100,105,116,108,98,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,228,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,160,4,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,1,238, + 238,238,1,29,29,29,1,255,255,255,1,172,172,172,1,21,21,21,1,18, + 18,18,1,148,148,148,1,115,115,115,1,15,15,15,2,128,128,128,1,255, + 255,255,2,0,0,0,1,234,234,234,1,23,23,23,1,255,255,255,6,128, + 128,128,1,255,255,255,1,98,98,98,1,0,0,0,1,255,255,255,1,29, + 29,29,1,201,201,201,1,209,209,209,1,10,10,10,1,255,255,255,2,194, + 194,194,1,17,17,17,1,255,255,255,3,0,0,0,1,255,255,255,2,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,247, + 247,247,1,0,0,0,1,255,255,255,3,205,205,205,1,68,68,68,1,255, + 255,255,1,164,164,164,1,4,4,4,1,103,103,103,1,255,255,255,3,0, + 0,0,1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128, + 128,128,1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,70, + 70,70,1,232,232,232,1,255,255,255,2,214,214,214,1,10,10,10,1,255, + 255,255,3,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0, + 0,0,1,255,255,255,1,165,165,165,1,77,77,77,1,235,235,235,1,255, + 255,255,1,32,32,32,1,227,227,227,1,234,234,234,1,24,24,24,1,255, + 255,255,1,252,252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255, + 255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,2,0,0,0,1,255,255,255,1,19,19,19,1,0,0,0,3,177, + 177,177,1,19,19,19,1,24,24,24,1,179,179,179,1,255,255,255,1,223, + 223,223,1,0,0,0,1,223,223,223,1,0,0,0,1,128,128,128,5,255, + 255,255,25,0,0,0,25,201,201,255,17,255,255,255,5,0,0,0,2,201, + 201,255,17,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128, + 128,128,1,0,0,0,2,201,201,255,2,199,199,253,1,105,105,133,1,19, + 19,24,1,4,4,5,1,58,58,73,1,181,181,230,1,201,201,255,5,143, + 143,182,1,2,2,2,1,201,201,255,2,255,255,255,1,0,0,0,3,128, + 128,128,1,0,0,0,2,201,201,255,2,112,112,142,1,24,24,30,1,137, + 137,174,1,152,152,193,1,51,51,65,1,61,61,77,1,201,201,255,4,169, + 169,215,1,11,11,14,1,0,0,0,1,201,201,255,2,255,255,255,1,208, + 208,208,3,128,128,128,1,0,0,0,2,201,201,255,1,200,200,254,1,24, + 24,30,1,142,142,180,1,201,201,255,2,184,184,233,1,139,139,176,1,201, + 201,255,3,188,188,238,1,28,28,36,1,90,90,114,1,0,0,0,1,201, + 201,255,2,128,128,128,5,0,0,0,2,201,201,255,1,184,184,234,1,0, + 0,0,1,117,117,149,1,21,21,27,1,6,6,8,1,66,66,84,1,187, + 187,237,1,201,201,255,2,198,198,251,1,54,54,69,1,86,86,109,1,169, + 169,215,1,0,0,0,1,201,201,255,2,255,255,255,1,212,212,212,1,252, + 252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,201,201,255,1,170, + 170,216,1,0,0,0,1,39,39,49,1,148,148,188,1,154,154,195,1,43, + 43,55,1,64,64,81,1,201,201,255,2,87,87,111,1,53,53,67,1,197, + 197,250,1,169,169,215,1,0,0,0,1,201,201,255,2,255,255,255,4,128, + 128,128,1,0,0,0,2,201,201,255,1,174,174,221,1,0,0,0,1,166, + 166,210,1,201,201,255,2,167,167,212,1,1,1,1,1,189,189,240,1,126, + 126,160,1,28,28,35,1,187,187,237,1,201,201,255,1,169,169,215,1,0, + 0,0,1,201,201,255,2,255,255,255,1,128,128,128,4,0,0,0,2,201, + 201,255,1,191,191,242,1,0,0,0,1,196,196,249,1,201,201,255,2,196, + 196,249,1,0,0,0,1,173,173,220,1,72,72,91,1,0,0,0,6,84, + 84,107,1,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208, + 208,208,1,0,0,0,2,201,201,255,2,32,32,40,1,154,154,195,1,201, + 201,255,2,158,158,200,1,6,6,7,1,194,194,246,1,181,181,229,1,169, + 169,215,3,143,143,181,1,0,0,0,1,169,169,215,1,182,182,231,1,255, + 255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,201,201,255,2,114, + 114,144,1,28,28,35,1,142,142,180,1,143,143,182,1,32,32,40,1,84, + 84,106,1,201,201,255,5,169,169,215,1,0,0,0,1,201,201,255,2,255, + 255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,201,201,255,2,199, + 199,252,1,88,88,112,1,9,9,12,1,12,12,15,1,84,84,106,1,195, + 195,247,1,201,201,255,5,169,169,215,1,0,0,0,1,201,201,255,2,255, + 255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,201,201,255,17,255, + 255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0, + 0,0,2,201,201,255,17,128,128,128,5,0,0,0,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tkeystringeditdb: record size: integer; data: array[0..1223] of byte end = + (size: 1224; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,107,101, + 121,115,116,114,105,110,103,101,100,105,116,100,98,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,8,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255, + 255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,0,0, + 0,1,1,1,1,1,75,75,75,1,255,255,255,4,0,0,0,1,234,234, + 234,1,23,23,23,1,255,255,255,6,128,128,128,1,255,255,255,2,88,88, + 88,1,75,75,75,1,89,89,89,1,255,255,255,2,0,0,0,1,234,234, + 234,1,70,70,70,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208, + 208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,251,251, + 251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255,255, + 255,1,0,0,0,2,117,117,117,1,255,255,255,5,0,0,0,1,255,255, + 255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255, + 255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,1,0,0, + 0,1,243,243,243,1,11,11,11,1,255,255,255,5,0,0,0,1,255,255, + 255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,114,114,114,1,141,141,141,1,255,255, + 255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,1,235,235, + 235,1,19,19,19,1,255,255,255,3,252,252,252,1,231,231,231,1,0,0, + 0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217,1,255,255, + 255,1,217,217,217,1,38,38,38,1,255,255,255,1,0,0,0,1,3,3, + 3,1,124,124,124,1,255,255,255,3,223,223,223,1,0,0,0,1,223,223, + 223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,184,255, + 255,17,255,255,255,5,0,0,0,2,184,255,255,17,255,255,255,1,208,208, + 208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255, + 255,17,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,184,255, + 255,1,0,0,0,1,184,255,255,2,113,157,157,1,74,102,102,1,184,255, + 255,11,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,184,255, + 255,1,0,0,0,1,184,255,255,1,145,201,201,1,47,65,65,1,180,249, + 249,1,184,255,255,11,128,128,128,5,0,0,0,2,184,255,255,1,0,0, + 0,1,168,233,233,1,38,53,53,1,166,230,230,1,184,255,255,1,134,186, + 186,1,18,25,25,2,141,195,195,1,184,255,255,1,38,52,52,1,146,203, + 203,1,184,255,255,1,147,204,204,1,36,50,50,1,184,255,255,1,255,255, + 255,1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0, + 0,2,184,255,255,1,0,0,0,1,45,62,62,1,89,124,124,1,184,255, + 255,2,28,39,39,1,140,194,194,1,142,197,197,1,36,50,50,1,184,255, + 255,1,113,157,157,1,70,97,97,1,184,255,255,1,74,102,102,1,110,152, + 152,1,184,255,255,1,255,255,255,4,128,128,128,1,0,0,0,2,184,255, + 255,1,0,0,0,1,105,146,146,1,41,57,57,1,150,208,208,1,184,255, + 255,1,2,3,3,1,0,0,0,2,3,4,4,1,184,255,255,1,178,246, + 246,1,19,27,27,1,163,226,226,1,18,25,25,1,175,242,242,1,184,255, + 255,1,255,255,255,1,128,128,128,4,0,0,0,2,184,255,255,1,0,0, + 0,1,184,255,255,1,157,217,217,1,37,51,51,1,176,244,244,1,25,34, + 34,1,141,195,195,1,184,255,255,4,82,113,113,1,40,55,55,1,71,99, + 99,1,184,255,255,2,208,208,208,1,255,255,255,1,211,211,211,1,255,255, + 255,1,208,208,208,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255, + 255,2,116,161,161,1,68,94,94,1,129,179,179,1,17,23,23,1,9,13, + 13,1,87,120,120,1,184,255,255,2,157,217,217,1,0,0,0,1,145,201, + 201,1,184,255,255,2,255,255,255,2,252,252,252,1,255,255,255,2,0,0, + 0,2,184,255,255,12,146,202,202,1,30,41,41,1,184,255,255,3,255,255, + 255,1,208,208,208,3,128,128,128,1,0,0,0,2,184,255,255,12,9,12, + 12,1,121,168,168,1,184,255,255,3,255,255,255,1,0,0,0,3,128,128, + 128,1,0,0,0,2,184,255,255,17,255,255,255,1,208,208,208,1,0,0, + 0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255,17,128,128, + 128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255, + 255,66,0,0) + ); + +const + objdata_tkeystringeditlb: record size: integer; data: array[0..1223] of byte end = + (size: 1224; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,107,101, + 121,115,116,114,105,110,103,101,100,105,116,108,98,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,8,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255, + 255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,0,0, + 0,1,1,1,1,1,75,75,75,1,255,255,255,4,0,0,0,1,234,234, + 234,1,23,23,23,1,255,255,255,6,128,128,128,1,255,255,255,2,88,88, + 88,1,75,75,75,1,89,89,89,1,255,255,255,2,0,0,0,1,234,234, + 234,1,70,70,70,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208, + 208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,251,251, + 251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255,255, + 255,1,0,0,0,2,117,117,117,1,255,255,255,5,0,0,0,1,255,255, + 255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255, + 255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,1,0,0, + 0,1,243,243,243,1,11,11,11,1,255,255,255,5,0,0,0,1,255,255, + 255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,114,114,114,1,141,141,141,1,255,255, + 255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,1,235,235, + 235,1,19,19,19,1,255,255,255,3,252,252,252,1,231,231,231,1,0,0, + 0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217,1,255,255, + 255,1,217,217,217,1,38,38,38,1,255,255,255,1,0,0,0,1,3,3, + 3,1,124,124,124,1,255,255,255,3,223,223,223,1,0,0,0,1,223,223, + 223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,201,201, + 255,17,255,255,255,5,0,0,0,2,201,201,255,17,255,255,255,1,208,208, + 208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201, + 255,17,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,201,201, + 255,1,0,0,0,1,201,201,255,2,124,124,157,1,80,80,102,1,201,201, + 255,11,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,201,201, + 255,1,0,0,0,1,201,201,255,1,158,158,201,1,51,51,65,1,196,196, + 249,1,201,201,255,11,128,128,128,5,0,0,0,2,201,201,255,1,0,0, + 0,1,184,184,233,1,42,42,53,1,181,181,230,1,201,201,255,1,147,147, + 186,1,20,20,25,2,154,154,195,1,201,201,255,1,41,41,52,1,160,160, + 203,1,201,201,255,1,161,161,204,1,39,39,50,1,201,201,255,1,255,255, + 255,1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0, + 0,2,201,201,255,1,0,0,0,1,49,49,62,1,98,98,124,1,201,201, + 255,2,31,31,39,1,153,153,194,1,155,155,197,1,39,39,50,1,201,201, + 255,1,124,124,157,1,76,76,97,1,201,201,255,1,80,80,102,1,120,120, + 152,1,201,201,255,1,255,255,255,4,128,128,128,1,0,0,0,2,201,201, + 255,1,0,0,0,1,115,115,146,1,45,45,57,1,164,164,208,1,201,201, + 255,1,2,2,3,1,0,0,0,2,3,3,4,1,201,201,255,1,194,194, + 246,1,21,21,27,1,178,178,226,1,20,20,25,1,191,191,242,1,201,201, + 255,1,255,255,255,1,128,128,128,4,0,0,0,2,201,201,255,1,0,0, + 0,1,201,201,255,1,171,171,217,1,40,40,51,1,192,192,244,1,27,27, + 34,1,154,154,195,1,201,201,255,4,89,89,113,1,43,43,55,1,78,78, + 99,1,201,201,255,2,208,208,208,1,255,255,255,1,211,211,211,1,255,255, + 255,1,208,208,208,1,0,0,0,2,201,201,255,1,0,0,0,1,201,201, + 255,2,127,127,161,1,74,74,94,1,141,141,179,1,18,18,23,1,10,10, + 13,1,95,95,120,1,201,201,255,2,171,171,217,1,0,0,0,1,158,158, + 201,1,201,201,255,2,255,255,255,2,252,252,252,1,255,255,255,2,0,0, + 0,2,201,201,255,12,159,159,202,1,32,32,41,1,201,201,255,3,255,255, + 255,1,208,208,208,3,128,128,128,1,0,0,0,2,201,201,255,12,9,9, + 12,1,132,132,168,1,201,201,255,3,255,255,255,1,0,0,0,3,128,128, + 128,1,0,0,0,2,201,201,255,17,255,255,255,1,208,208,208,1,0,0, + 0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201,255,17,128,128, + 128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255, + 255,66,0,0) + ); + +const + objdata_tmsestringfield: record size: integer; data: array[0..1206] of byte end = + (size: 1207; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,109,115, + 101,115,116,114,105,110,103,102,105,101,108,100,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,60,4,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,100,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208, + 22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255, + 2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208, + 22,184,255,255,2,208,208,208,8,0,0,0,2,208,208,208,12,184,255,255, + 2,208,208,208,8,0,0,0,2,208,208,208,12,184,255,255,2,208,208,208, + 8,0,0,0,2,208,208,208,12,184,255,255,2,208,208,208,2,0,0,0, + 5,208,208,208,1,0,0,0,6,208,208,208,1,0,0,0,5,208,208,208, + 2,184,255,255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0, + 12,208,208,208,1,0,0,0,2,208,208,208,2,184,255,255,2,208,208,208, + 3,0,0,0,7,208,208,208,2,0,0,0,5,208,208,208,5,184,255,255, + 2,208,208,208,2,0,0,0,8,208,208,208,2,0,0,0,4,208,208,208, + 2,0,0,0,2,208,208,208,2,184,255,255,2,208,208,208,2,0,0,0, + 2,208,208,208,1,0,0,0,12,208,208,208,1,0,0,0,2,208,208,208, + 2,184,255,255,2,208,208,208,2,0,0,0,12,208,208,208,1,0,0,0, + 5,208,208,208,2,184,255,255,2,208,208,208,3,0,0,0,2,208,208,208, + 6,0,0,0,1,208,208,208,5,0,0,0,1,208,208,208,4,184,255,255, + 2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208, + 22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255, + 2,208,208,208,22,184,255,255,25,160,2,0,0,255,255,255,25,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,8,5,5,5,1,18,18,18,1,0,0,0, + 12,255,255,255,2,0,0,0,8,55,55,55,1,192,192,192,1,0,0,0, + 12,255,255,255,2,0,0,0,8,55,55,55,1,192,192,192,1,0,0,0, + 12,255,255,255,2,0,0,0,2,19,19,19,1,166,166,166,1,216,216,216, + 1,229,229,229,1,151,151,151,1,0,0,0,1,55,55,55,1,208,208,208, + 1,143,143,143,1,223,223,223,1,165,165,165,1,12,12,12,1,0,0,0, + 1,40,40,40,1,192,192,192,1,219,219,219,1,166,166,166,1,14,14,14, + 1,0,0,0,2,255,255,255,2,0,0,0,2,109,109,109,1,138,138,138, + 1,0,0,0,1,13,13,13,1,233,233,233,1,45,45,45,1,55,55,55, + 1,255,255,255,1,69,69,69,1,9,9,9,1,173,173,173,1,129,129,129, + 1,1,1,1,1,223,223,223,1,91,91,91,1,0,0,0,1,127,127,127, + 1,122,122,122,1,0,0,0,2,255,255,255,2,0,0,0,3,40,40,40, + 1,98,98,98,1,147,147,147,1,238,238,238,1,62,62,62,1,55,55,55, + 1,215,215,215,1,0,0,0,2,79,79,79,1,196,196,196,1,34,34,34, + 1,237,237,237,1,2,2,2,1,0,0,0,5,255,255,255,2,0,0,0, + 2,116,116,116,1,208,208,208,1,118,118,118,1,59,59,59,1,212,212,212, + 1,63,63,63,1,55,55,55,1,198,198,198,1,0,0,0,2,73,73,73, + 1,197,197,197,1,48,48,48,1,229,229,229,1,0,0,0,2,6,6,6, + 1,18,18,18,1,0,0,0,2,255,255,255,2,0,0,0,2,193,193,193, + 1,79,79,79,1,0,0,0,1,34,34,34,1,245,245,245,1,67,67,67, + 1,55,55,55,1,244,244,244,1,37,37,37,1,1,1,1,1,161,161,161, + 1,135,135,135,1,10,10,10,1,238,238,238,1,50,50,50,1,0,0,0, + 1,106,106,106,1,147,147,147,1,0,0,0,2,255,255,255,2,0,0,0, + 2,81,81,81,1,210,210,210,1,184,184,184,1,180,180,180,1,189,189,189, + 1,95,95,95,1,55,55,55,1,205,205,205,1,172,172,172,1,206,206,206, + 1,149,149,149,1,15,15,15,1,0,0,0,1,69,69,69,1,189,189,189, + 1,198,198,198,1,187,187,187,1,25,25,25,1,0,0,0,2,255,255,255, + 2,0,0,0,3,2,2,2,1,15,15,15,1,0,0,0,6,8,8,8, + 1,0,0,0,5,10,10,10,1,0,0,0,4,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,25,0,0) + ); + +const + objdata_tmselongintfield: record size: integer; data: array[0..1259] of byte end = + (size: 1260; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,108,111,110,103,105,110,116,102,105,101,108,100,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,112,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,164,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,4,0,0,0,2,208,208,208,2,0,0, + 0,2,208,208,208,5,0,0,0,1,208,208,208,6,184,255,255,2,208,208, + 208,4,0,0,0,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0, + 0,5,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,5,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,3,208,208,208,3,184,255,255,2,208,208, + 208,4,0,0,0,2,208,208,208,2,0,0,0,4,208,208,208,3,0,0, + 0,3,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,2,208,208, + 208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,4,184,255, + 255,2,208,208,208,4,0,0,0,4,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,4,208,208,208,5,184,255,255,2,208,208,208,4,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,3,208,208, + 208,6,184,255,255,2,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,12,208,208,208,3,184,255,255,2,208,208,208,8,0,0,0,2,208,208, + 208,12,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,25,148,2,0,0,255,255, + 255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,4,22,22,22,1,3,3, + 3,1,0,0,0,2,2,2,2,1,11,11,11,1,0,0,0,5,11,11, + 11,1,0,0,0,6,255,255,255,2,0,0,0,4,238,238,238,1,33,33, + 33,1,0,0,0,1,97,97,97,1,208,208,208,2,164,164,164,1,7,7, + 7,1,0,0,0,1,52,52,52,1,192,192,192,1,205,205,205,1,199,199, + 199,1,70,70,70,1,0,0,0,4,255,255,255,2,0,0,0,4,238,238, + 238,1,33,33,33,1,22,22,22,1,228,228,228,1,15,15,15,1,0,0, + 0,1,184,184,184,1,92,92,92,1,0,0,0,1,185,185,185,1,76,76, + 76,1,0,0,0,1,54,54,54,1,213,213,213,1,0,0,0,4,255,255, + 255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0,0,1,17,17, + 17,1,0,0,0,2,201,201,201,1,91,91,91,1,0,0,0,1,67,67, + 67,1,3,3,3,1,0,0,0,1,24,24,24,1,248,248,248,1,8,8, + 8,1,0,0,0,3,255,255,255,2,0,0,0,4,238,238,238,1,33,33, + 33,1,0,0,0,2,66,66,66,1,226,226,226,1,187,187,187,1,2,2, + 2,1,0,0,0,3,1,1,1,1,158,158,158,1,156,156,156,1,0,0, + 0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0, + 0,2,15,15,15,1,44,44,44,1,181,181,181,1,128,128,128,1,0,0, + 0,2,3,3,3,1,161,161,161,1,185,185,185,1,10,10,10,1,0,0, + 0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,14,14, + 14,1,36,36,36,1,0,0,0,2,64,64,64,1,211,211,211,1,0,0, + 0,1,6,6,6,1,172,172,172,1,169,169,169,1,6,6,6,1,0,0, + 0,5,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,28,28, + 28,1,228,228,228,1,11,11,11,1,0,0,0,1,135,135,135,1,136,136, + 136,1,0,0,0,1,158,158,158,1,150,150,150,1,1,1,1,1,0,0, + 0,6,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0, + 0,1,107,107,107,1,208,208,208,1,202,202,202,1,165,165,165,1,24,24, + 24,1,33,33,33,1,254,254,254,1,249,249,249,1,248,248,248,3,26,26, + 26,1,0,0,0,3,255,255,255,2,0,0,0,8,3,3,3,1,13,13, + 13,1,0,0,0,12,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmselargeintfield: record size: integer; data: array[0..1220] of byte end = + (size: 1221; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,109,115, + 101,108,97,114,103,101,105,110,116,102,105,101,108,100,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,72, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,124, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,4,0,0,0,2,208,208,208,3,0, + 0,0,1,208,208,208,6,0,0,0,2,208,208,208,4,184,255,255,2,208, + 208,208,4,0,0,0,2,208,208,208,1,0,0,0,5,208,208,208,3,0, + 0,0,3,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,5,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,4,208,208,208,4,184, + 255,255,2,208,208,208,4,0,0,0,6,208,208,208,4,0,0,0,4,208, + 208,208,4,184,255,255,2,208,208,208,4,0,0,0,8,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,4,184,255,255,2,208, + 208,208,4,0,0,0,5,208,208,208,1,0,0,0,5,208,208,208,1,0, + 0,0,2,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,4,208, + 208,208,2,0,0,0,9,208,208,208,3,184,255,255,2,208,208,208,4,0, + 0,0,5,208,208,208,1,0,0,0,9,208,208,208,3,184,255,255,2,208, + 208,208,4,0,0,0,2,208,208,208,1,0,0,0,5,208,208,208,4,0, + 0,0,2,208,208,208,4,184,255,255,2,208,208,208,8,0,0,0,2,208, + 208,208,12,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,25,148,2,0,0,255, + 255,255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,4,22,22,22,1,3, + 3,3,1,0,0,0,3,14,14,14,1,0,0,0,6,18,18,18,1,1, + 1,1,1,0,0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33, + 33,33,1,0,0,0,1,63,63,63,1,214,214,214,1,202,202,202,1,195, + 195,195,1,24,24,24,1,0,0,0,3,46,46,46,1,248,248,248,1,19, + 19,19,1,0,0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33, + 33,33,1,4,4,4,1,218,218,218,1,51,51,51,1,0,0,0,1,116, + 116,116,1,128,128,128,1,0,0,0,2,7,7,7,1,197,197,197,1,247, + 247,247,1,19,19,19,1,0,0,0,4,255,255,255,2,0,0,0,4,238, + 238,238,1,33,33,33,1,60,60,60,1,190,190,190,1,7,7,7,1,41, + 41,41,1,0,0,0,4,143,143,143,1,98,98,98,1,236,236,236,1,19, + 19,19,1,0,0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33, + 33,33,1,89,89,89,1,195,195,195,1,215,215,215,1,191,191,191,1,205, + 205,205,1,39,39,39,1,0,0,0,1,68,68,68,1,175,175,175,1,0, + 0,0,1,236,236,236,1,19,19,19,1,0,0,0,4,255,255,255,2,0, + 0,0,4,238,238,238,1,33,33,33,1,100,100,100,1,247,247,247,1,19, + 19,19,1,0,0,0,1,113,113,113,1,144,144,144,1,18,18,18,1,206, + 206,206,1,21,21,21,1,0,0,0,1,236,236,236,1,19,19,19,1,0, + 0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,75, + 75,75,1,196,196,196,1,0,0,0,2,51,51,51,1,208,208,208,1,106, + 106,106,1,239,239,239,1,216,216,216,2,252,252,252,1,219,219,219,1,29, + 29,29,1,0,0,0,3,255,255,255,2,0,0,0,4,238,238,238,1,33, + 33,33,1,16,16,16,1,227,227,227,1,31,31,31,1,0,0,0,1,130, + 130,130,1,158,158,158,1,6,6,6,1,16,16,16,3,237,237,237,1,34, + 34,34,1,2,2,2,1,0,0,0,3,255,255,255,2,0,0,0,4,238, + 238,238,1,33,33,33,1,0,0,0,1,81,81,81,1,220,220,220,1,204, + 204,204,1,199,199,199,1,19,19,19,1,0,0,0,4,236,236,236,1,19, + 19,19,1,0,0,0,4,255,255,255,2,0,0,0,8,2,2,2,1,15, + 15,15,1,0,0,0,12,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0, + 0) + ); + +const + objdata_tmsesmallintfield: record size: integer; data: array[0..1244] of byte end = + (size: 1245; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,109,115, + 101,115,109,97,108,108,105,110,116,102,105,101,108,100,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,96, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,180, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,4,0,0,0,2,208,208,208,3,0, + 0,0,2,208,208,208,4,0,0,0,1,208,208,208,6,184,255,255,2,208, + 208,208,4,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,2,0, + 0,0,5,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,5,184, + 255,255,2,208,208,208,4,0,0,0,2,208,208,208,3,0,0,0,2,208, + 208,208,1,0,0,0,6,208,208,208,4,184,255,255,2,208,208,208,4,0, + 0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,2,208,208,208,4,184,255,255,2,208,208,208,4,0, + 0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,3,208, + 208,208,2,0,0,0,2,208,208,208,3,184,255,255,2,208,208,208,4,0, + 0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,4,184,255,255,2,208,208,208,4,0, + 0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,0,0,0,5,208, + 208,208,4,184,255,255,2,208,208,208,15,0,0,0,1,208,208,208,6,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,25,116,2,0,0,255,255,255,25,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,4,22,22,22,1,3,3,3,1,0, + 0,0,3,11,11,11,2,0,0,0,4,14,14,14,1,0,0,0,6,255, + 255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0,0,2,6, + 6,6,1,198,198,198,1,90,90,90,1,0,0,0,2,25,25,25,1,190, + 190,190,1,201,201,201,1,212,212,212,1,71,71,71,1,0,0,0,4,255, + 255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0,0,1,49, + 49,49,1,206,206,206,1,239,239,239,1,90,90,90,1,0,0,0,2,156, + 156,156,1,117,117,117,1,0,0,0,1,46,46,46,1,197,197,197,1,0, + 0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0, + 0,0,1,119,119,119,1,74,74,74,1,165,165,165,1,90,90,90,1,0, + 0,0,2,241,241,241,1,9,9,9,1,40,40,40,1,7,7,7,1,0, + 0,0,5,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0, + 0,0,3,165,165,165,1,90,90,90,1,0,0,0,1,16,16,16,1,235, + 235,235,1,187,187,187,1,189,189,189,1,220,220,220,1,86,86,86,1,0, + 0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0, + 0,0,3,165,165,165,1,90,90,90,1,0,0,0,1,27,27,27,1,255, + 255,255,1,83,83,83,1,0,0,0,1,40,40,40,1,216,216,216,1,0, + 0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0, + 0,0,3,165,165,165,1,90,90,90,1,0,0,0,1,4,4,4,1,253, + 253,253,1,13,13,13,1,0,0,0,2,234,234,234,1,25,25,25,1,0, + 0,0,3,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0, + 0,0,3,165,165,165,1,90,90,90,1,0,0,0,2,184,184,184,1,90, + 90,90,1,0,0,0,1,57,57,57,1,230,230,230,1,0,0,0,4,255, + 255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0,0,3,165, + 165,165,1,90,90,90,1,0,0,0,2,36,36,36,1,205,205,205,1,197, + 197,197,1,223,223,223,1,61,61,61,1,0,0,0,4,255,255,255,2,0, + 0,0,15,17,17,17,1,0,0,0,6,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,25,0,0) + ); + +const + objdata_tmsewordfield: record size: integer; data: array[0..1436] of byte end = + (size: 1437; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,119,111,114,100,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,36,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,244,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208, + 208,208,4,0,0,0,1,208,208,208,4,0,0,0,2,208,208,208,3,184, + 255,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,3,0,0,0,5,208,208,208,1,184, + 255,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,3,208,208,208,1,0, + 0,0,2,208,208,208,1,184,255,255,2,208,208,208,1,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,2,0, + 0,0,4,208,208,208,3,184,255,255,2,208,208,208,1,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,0, + 0,0,6,208,208,208,1,184,255,255,2,208,208,208,1,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,0, + 0,0,3,208,208,208,1,0,0,0,2,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,3,0, + 0,0,2,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,2,208, + 208,208,1,184,255,255,2,208,208,208,1,0,0,0,3,208,208,208,1,0, + 0,0,3,208,208,208,3,0,0,0,2,208,208,208,2,0,0,0,6,208, + 208,208,1,184,255,255,2,208,208,208,2,0,0,0,5,208,208,208,4,0, + 0,0,2,208,208,208,3,0,0,0,5,208,208,208,1,184,255,255,2,208, + 208,208,4,0,0,0,1,208,208,208,12,0,0,0,2,208,208,208,3,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,25,248,2,0,0,255,255,255,25,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,1,15,15,15,1,11,11,11,1,0, + 0,0,3,7,7,7,1,17,17,17,1,0,0,0,4,22,22,22,1,0, + 0,0,4,2,2,2,1,12,12,12,1,0,0,0,3,255,255,255,2,0, + 0,0,1,162,162,162,1,117,117,117,1,0,0,0,3,82,82,82,1,189, + 189,189,1,0,0,0,3,75,75,75,1,220,220,220,1,0,0,0,3,99, + 99,99,1,219,219,219,1,207,207,207,1,170,170,170,1,2,2,2,1,0, + 0,0,1,255,255,255,2,0,0,0,1,162,162,162,1,117,117,117,1,0, + 0,0,3,82,82,82,1,189,189,189,1,0,0,0,1,4,4,4,1,127, + 127,127,1,232,232,232,1,222,222,222,1,0,0,0,2,29,29,29,1,223, + 223,223,1,20,20,20,1,0,0,0,1,164,164,164,1,79,79,79,1,0, + 0,0,1,255,255,255,2,0,0,0,1,162,162,162,1,117,117,117,1,0, + 0,0,3,82,82,82,1,189,189,189,1,0,0,0,1,28,28,28,1,147, + 147,147,1,52,52,52,1,222,222,222,1,0,0,0,2,112,112,112,1,138, + 138,138,1,14,14,14,1,34,34,34,1,0,0,0,3,255,255,255,2,0, + 0,0,1,162,162,162,1,117,117,117,1,0,0,0,3,82,82,82,1,189, + 189,189,1,0,0,0,3,33,33,33,1,222,222,222,1,0,0,0,2,141, + 141,141,1,178,178,178,1,217,217,217,1,203,203,203,1,184,184,184,1,11, + 11,11,1,0,0,0,1,255,255,255,2,0,0,0,1,159,159,159,1,120, + 120,120,1,0,0,0,3,87,87,87,1,186,186,186,1,0,0,0,3,33, + 33,33,1,222,222,222,1,0,0,0,2,152,152,152,1,211,211,211,1,3, + 3,3,1,0,0,0,1,165,165,165,1,92,92,92,1,0,0,0,1,255, + 255,255,2,0,0,0,1,126,126,126,1,146,146,146,1,0,0,0,3,139, + 139,139,1,155,155,155,1,0,0,0,3,33,33,33,1,222,222,222,1,0, + 0,0,2,127,127,127,1,144,144,144,1,0,0,0,2,103,103,103,1,157, + 157,157,1,0,0,0,1,255,255,255,2,0,0,0,1,73,73,73,1,225, + 225,225,1,26,26,26,1,0,0,0,1,38,38,38,1,213,213,213,1,98, + 98,98,1,0,0,0,3,33,33,33,1,222,222,222,1,0,0,0,2,53, + 53,53,1,212,212,212,1,9,9,9,1,2,2,2,1,179,179,179,1,106, + 106,106,1,0,0,0,1,255,255,255,2,0,0,0,2,123,123,123,1,229, + 229,229,1,226,226,226,1,232,232,232,1,139,139,139,1,0,0,0,4,33, + 33,33,1,222,222,222,1,0,0,0,3,123,123,123,1,217,217,217,1,213, + 213,213,1,166,166,166,1,4,4,4,1,0,0,0,1,255,255,255,2,0, + 0,0,4,18,18,18,1,0,0,0,12,6,6,6,1,11,11,11,1,0, + 0,0,3,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmseautoincfield: record size: integer; data: array[0..1447] of byte end = + (size: 1448; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,97,117,116,111,105,110,99,102,105,101,108,100,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,5, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,244,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,3,0,0,0,2,208,208,208,4,0,0,0,2,208,208, + 208,4,184,255,255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,3,0,0,0,2,208,208,208,2,0,0,0,6,208,208, + 208,2,184,255,255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,3,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,3,208,208, + 208,1,0,0,0,3,208,208,208,2,184,255,255,2,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,184,255, + 255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,4,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,7,184,255, + 255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,7,208,208, + 208,1,0,0,0,2,208,208,208,7,184,255,255,2,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208, + 208,1,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208,1,184,255, + 255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,2,0,0,0,3,208,208,208,1,0,0,0,3,208,208,208,1,0,0, + 0,3,208,208,208,2,184,255,255,2,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,2,0,0, + 0,6,208,208,208,2,184,255,255,2,208,208,208,16,0,0,0,2,208,208, + 208,4,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,25,0,3,0,0,255,255, + 255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,2,19,19,19,1,6,6, + 6,1,0,0,0,1,20,20,20,1,6,6,6,1,0,0,0,3,13,13, + 13,1,11,11,11,1,0,0,0,4,33,33,33,1,10,10,10,1,0,0, + 0,4,255,255,255,2,0,0,0,2,206,206,206,1,65,65,65,1,0,0, + 0,1,221,221,221,1,159,159,159,1,0,0,0,3,141,141,141,1,122,122, + 122,1,0,0,0,2,97,97,97,1,224,224,224,1,200,200,200,1,221,221, + 221,1,173,173,173,1,9,9,9,1,0,0,0,2,255,255,255,2,0,0, + 0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221,221,1,245,245, + 245,1,74,74,74,1,0,0,0,2,141,141,141,1,122,122,122,1,0,0, + 0,1,86,86,86,1,223,223,223,1,25,25,25,1,0,0,0,1,1,1, + 1,1,164,164,164,1,143,143,143,1,0,0,0,2,255,255,255,2,0,0, + 0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221,221,1,111,111, + 111,1,228,228,228,1,15,15,15,1,0,0,0,1,141,141,141,1,122,122, + 122,1,0,0,0,1,184,184,184,1,85,85,85,1,0,0,0,3,18,18, + 18,1,59,59,59,1,0,0,0,2,255,255,255,2,0,0,0,2,206,206, + 206,1,65,65,65,1,0,0,0,1,221,221,221,1,34,34,34,1,160,160, + 160,1,158,158,158,1,0,0,0,1,141,141,141,1,122,122,122,1,0,0, + 0,1,237,237,237,1,36,36,36,1,0,0,0,7,255,255,255,2,0,0, + 0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221,221,1,34,34, + 34,1,16,16,16,1,228,228,228,1,73,73,73,1,141,141,141,1,122,122, + 122,1,0,0,0,1,229,229,229,1,45,45,45,1,0,0,0,7,255,255, + 255,2,0,0,0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221, + 221,1,34,34,34,1,0,0,0,1,74,74,74,1,227,227,227,1,156,156, + 156,1,122,122,122,1,0,0,0,1,177,177,177,1,98,98,98,1,0,0, + 0,3,40,40,40,1,176,176,176,1,4,4,4,1,0,0,0,1,255,255, + 255,2,0,0,0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221, + 221,1,34,34,34,1,0,0,0,2,158,158,158,1,250,250,250,1,122,122, + 122,1,0,0,0,1,63,63,63,1,231,231,231,1,41,41,41,1,0,0, + 0,1,17,17,17,1,181,181,181,1,125,125,125,1,0,0,0,2,255,255, + 255,2,0,0,0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221, + 221,1,34,34,34,1,0,0,0,2,15,15,15,1,227,227,227,1,122,122, + 122,1,0,0,0,2,95,95,95,1,206,206,206,1,218,218,218,1,222,222, + 222,1,145,145,145,1,7,7,7,1,0,0,0,2,255,255,255,2,0,0, + 0,16,12,12,12,1,1,1,1,1,0,0,0,4,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsefloatfield: record size: integer; data: array[0..1033] of byte end = + (size: 1034; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,102,108,111,97,116,102,105,101,108,100,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,144,3,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,92,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22, + 184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2, + 208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22, + 184,255,255,2,208,208,208,6,0,0,0,2,208,208,208,7,0,0,0,1, + 208,208,208,6,184,255,255,2,208,208,208,5,0,0,0,3,208,208,208,5, + 0,0,0,5,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,4, + 208,208,208,5,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,4, + 184,255,255,2,208,208,208,4,0,0,0,4,208,208,208,5,0,0,0,2, + 208,208,208,1,0,0,0,3,208,208,208,3,184,255,255,2,208,208,208,6, + 0,0,0,2,208,208,208,7,0,0,0,3,208,208,208,4,184,255,255,2, + 208,208,208,6,0,0,0,2,208,208,208,6,0,0,0,4,208,208,208,4, + 184,255,255,2,208,208,208,6,0,0,0,2,208,208,208,5,0,0,0,4, + 208,208,208,5,184,255,255,2,208,208,208,6,0,0,0,2,208,208,208,2, + 0,0,0,2,208,208,208,1,0,0,0,3,208,208,208,6,184,255,255,2, + 208,208,208,6,0,0,0,2,208,208,208,2,0,0,0,9,208,208,208,3, + 184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2, + 208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22, + 184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,25, + 252,1,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0,0,0,22, + 255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2, + 0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,6, + 15,15,15,1,7,7,7,1,0,0,0,7,11,11,11,1,0,0,0,6, + 255,255,255,2,0,0,0,5,17,17,17,1,221,221,221,1,57,57,57,1, + 0,0,0,5,52,52,52,1,192,192,192,1,205,205,205,1,199,199,199,1, + 70,70,70,1,0,0,0,4,255,255,255,2,0,0,0,4,67,67,67,1, + 218,218,218,1,242,242,242,1,57,57,57,1,0,0,0,5,185,185,185,1, + 76,76,76,1,0,0,0,1,54,54,54,1,213,213,213,1,0,0,0,4, + 255,255,255,2,0,0,0,4,137,137,137,1,56,56,56,1,198,198,198,1, + 57,57,57,1,0,0,0,5,67,67,67,1,3,3,3,1,0,0,0,1, + 24,24,24,1,248,248,248,1,8,8,8,1,0,0,0,3,255,255,255,2, + 0,0,0,6,198,198,198,1,57,57,57,1,0,0,0,7,1,1,1,1, + 158,158,158,1,156,156,156,1,0,0,0,4,255,255,255,2,0,0,0,6, + 198,198,198,1,57,57,57,1,0,0,0,6,3,3,3,1,161,161,161,1, + 185,185,185,1,10,10,10,1,0,0,0,4,255,255,255,2,0,0,0,6, + 198,198,198,1,57,57,57,1,0,0,0,5,6,6,6,1,172,172,172,1, + 169,169,169,1,6,6,6,1,0,0,0,5,255,255,255,2,0,0,0,6, + 198,198,198,1,57,57,57,1,0,0,0,2,21,21,21,1,14,14,14,1, + 0,0,0,1,158,158,158,1,150,150,150,1,1,1,1,1,0,0,0,6, + 255,255,255,2,0,0,0,6,198,198,198,1,57,57,57,1,0,0,0,2, + 174,174,174,1,113,113,113,1,33,33,33,1,254,254,254,1,249,249,249,1, + 248,248,248,3,26,26,26,1,0,0,0,3,255,255,255,2,0,0,0,22, + 255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2, + 0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22, + 255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsecurrencyfield: record size: integer; data: array[0..1232] of byte end = + (size: 1233; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,109,115, + 101,99,117,114,114,101,110,99,121,102,105,101,108,100,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,84, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,116, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,4,0,0,0,4,208,208,208,6,0, + 0,0,3,208,208,208,5,184,255,255,2,208,208,208,4,0,0,0,5,208, + 208,208,4,0,0,0,5,208,208,208,4,184,255,255,2,208,208,208,3,0, + 0,0,6,208,208,208,4,0,0,0,5,208,208,208,4,184,255,255,2,208, + 208,208,3,0,0,0,4,208,208,208,6,0,0,0,3,208,208,208,6,184, + 255,255,2,208,208,208,3,0,0,0,5,208,208,208,5,0,0,0,5,208, + 208,208,4,184,255,255,2,208,208,208,5,0,0,0,4,208,208,208,5,0, + 0,0,5,208,208,208,3,184,255,255,2,208,208,208,3,0,0,0,6,208, + 208,208,3,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,3,184, + 255,255,2,208,208,208,3,0,0,0,6,208,208,208,1,0,0,0,8,208, + 208,208,4,184,255,255,2,208,208,208,3,0,0,0,6,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,5,208,208,208,4,184,255,255,2,208, + 208,208,5,0,0,0,2,208,208,208,7,0,0,0,3,208,208,208,5,184, + 255,255,2,208,208,208,5,0,0,0,2,208,208,208,8,0,0,0,1,208, + 208,208,6,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,25,168,2,0,0,255,255,255,25,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,4,1,1,1,1,79,79,79,1,121,121,121,1,5, + 5,5,1,0,0,0,6,24,24,24,1,155,155,155,1,27,27,27,1,0, + 0,0,5,255,255,255,2,0,0,0,4,196,196,196,1,189,189,189,1,204, + 204,204,1,221,221,221,1,13,13,13,1,0,0,0,4,95,95,95,1,211, + 211,211,1,207,207,207,1,216,216,216,1,93,93,93,1,0,0,0,4,255, + 255,255,2,0,0,0,3,64,64,64,1,179,179,179,1,46,46,46,1,105, + 105,105,1,122,122,122,1,70,70,70,1,0,0,0,4,214,214,214,1,30, + 30,30,1,152,152,152,1,43,43,43,1,149,149,149,1,0,0,0,4,255, + 255,255,2,0,0,0,3,75,75,75,1,208,208,208,1,59,59,59,1,105, + 105,105,1,0,0,0,6,224,224,224,1,70,70,70,1,152,152,152,1,0, + 0,0,6,255,255,255,2,0,0,0,3,2,2,2,1,146,146,146,1,238, + 238,238,1,191,191,191,1,69,69,69,1,0,0,0,5,66,66,66,1,224, + 224,224,1,230,230,230,1,115,115,115,1,11,11,11,1,0,0,0,4,255, + 255,255,2,0,0,0,5,58,58,58,1,177,177,177,1,228,228,228,1,96, + 96,96,1,0,0,0,5,2,2,2,1,176,176,176,1,177,177,177,1,201, + 201,201,1,1,1,1,1,0,0,0,3,255,255,255,2,0,0,0,3,43, + 43,43,1,50,50,50,1,46,46,46,1,105,105,105,1,95,95,95,1,177, + 177,177,1,0,0,0,3,9,9,9,1,84,84,84,1,0,0,0,1,152, + 152,152,1,3,3,3,1,241,241,241,1,27,27,27,1,0,0,0,3,255, + 255,255,2,0,0,0,3,96,96,96,1,193,193,193,1,51,51,51,1,105, + 105,105,1,140,140,140,1,113,113,113,1,0,0,0,1,21,21,21,1,14, + 14,14,1,4,4,4,1,240,240,240,1,48,48,48,1,152,152,152,1,35, + 35,35,1,217,217,217,1,0,0,0,4,255,255,255,2,0,0,0,3,9, + 9,9,1,177,177,177,1,229,229,229,1,224,224,224,1,171,171,171,1,18, + 18,18,1,0,0,0,1,174,174,174,1,113,113,113,1,0,0,0,1,91, + 91,91,1,234,234,234,1,226,226,226,1,202,202,202,1,76,76,76,1,0, + 0,0,4,255,255,255,2,0,0,0,5,59,59,59,1,112,112,112,1,0, + 0,0,7,4,4,4,1,164,164,164,1,1,1,1,1,0,0,0,5,255, + 255,255,2,0,0,0,5,7,7,7,1,16,16,16,1,0,0,0,8,23, + 23,23,1,0,0,0,6,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsebooleanfield: record size: integer; data: array[0..1107] of byte end = + (size: 1108; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,98,111,111,108,101,97,110,102,105,101,108,100,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,216,3, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,124,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,2,0,0,0,7,208,208,208,2,0,0, + 0,8,208,208,208,3,184,255,255,2,208,208,208,2,0,0,0,8,208,208, + 208,1,0,0,0,8,208,208,208,3,184,255,255,2,208,208,208,5,0,0, + 0,2,208,208,208,4,0,0,0,4,208,208,208,7,184,255,255,2,208,208, + 208,5,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,7,184,255,255,2,208,208,208,5,0,0,0,2,208,208, + 208,3,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,3,184,255, + 255,2,208,208,208,5,0,0,0,2,208,208,208,3,0,0,0,2,208,208, + 208,1,0,0,0,6,208,208,208,3,184,255,255,2,208,208,208,5,0,0, + 0,2,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,2,208,208, + 208,7,184,255,255,2,208,208,208,5,0,0,0,2,208,208,208,2,0,0, + 0,2,208,208,208,2,0,0,0,2,208,208,208,7,184,255,255,2,208,208, + 208,5,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,2,0,0, + 0,2,208,208,208,7,184,255,255,2,208,208,208,9,0,0,0,2,208,208, + 208,11,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,25,36,2,0,0,255,255, + 255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,2,9,9,9,1,24,24, + 24,6,0,0,0,2,21,21,21,1,22,22,22,1,14,14,14,1,24,24, + 24,4,19,19,19,1,0,0,0,3,255,255,255,2,0,0,0,2,86,86, + 86,1,224,224,224,2,246,246,246,1,235,235,235,1,224,224,224,2,4,4, + 4,1,0,0,0,1,140,140,140,1,60,60,60,1,159,159,159,1,238,238, + 238,1,224,224,224,3,182,182,182,1,0,0,0,3,255,255,255,2,0,0, + 0,5,178,178,178,1,93,93,93,1,0,0,0,4,197,197,197,1,4,4, + 4,1,159,159,159,1,112,112,112,1,0,0,0,7,255,255,255,2,0,0, + 0,5,178,178,178,1,93,93,93,1,0,0,0,3,28,28,28,1,174,174, + 174,1,0,0,0,1,159,159,159,1,112,112,112,1,0,0,0,7,255,255, + 255,2,0,0,0,5,178,178,178,1,93,93,93,1,0,0,0,3,99,99, + 99,1,103,103,103,1,0,0,0,1,159,159,159,1,202,202,202,1,160,160, + 160,3,35,35,35,1,0,0,0,3,255,255,255,2,0,0,0,5,178,178, + 178,1,93,93,93,1,0,0,0,3,171,171,171,1,32,32,32,1,0,0, + 0,1,159,159,159,1,162,162,162,1,88,88,88,3,19,19,19,1,0,0, + 0,3,255,255,255,2,0,0,0,5,178,178,178,1,93,93,93,1,0,0, + 0,2,3,3,3,1,201,201,201,1,0,0,0,2,159,159,159,1,112,112, + 112,1,0,0,0,7,255,255,255,2,0,0,0,5,178,178,178,1,93,93, + 93,1,0,0,0,2,59,59,59,1,146,146,146,1,0,0,0,2,159,159, + 159,1,112,112,112,1,0,0,0,7,255,255,255,2,0,0,0,5,178,178, + 178,1,93,93,93,1,0,0,0,2,131,131,131,1,75,75,75,1,0,0, + 0,2,159,159,159,1,112,112,112,1,0,0,0,7,255,255,255,2,0,0, + 0,9,21,21,21,1,4,4,4,1,0,0,0,11,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsedatetimefield: record size: integer; data: array[0..1204] of byte end = + (size: 1205; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,109,115, + 101,100,97,116,101,116,105,109,101,102,105,101,108,100,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,56, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,132, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,2,0,0,0,5,208,208,208,6,0, + 0,0,7,208,208,208,2,184,255,255,2,208,208,208,2,0,0,0,7,208, + 208,208,4,0,0,0,7,208,208,208,2,184,255,255,2,208,208,208,2,0, + 0,0,2,208,208,208,2,0,0,0,3,208,208,208,6,0,0,0,3,208, + 208,208,4,184,255,255,2,208,208,208,2,0,0,0,2,208,208,208,3,0, + 0,0,6,208,208,208,2,0,0,0,3,208,208,208,4,184,255,255,2,208, + 208,208,2,0,0,0,2,208,208,208,4,0,0,0,5,208,208,208,2,0, + 0,0,3,208,208,208,4,184,255,255,2,208,208,208,2,0,0,0,2,208, + 208,208,4,0,0,0,2,208,208,208,5,0,0,0,3,208,208,208,4,184, + 255,255,2,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,3,208, + 208,208,5,0,0,0,3,208,208,208,4,184,255,255,2,208,208,208,2,0, + 0,0,2,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,3,208, + 208,208,2,0,0,0,3,208,208,208,4,184,255,255,2,208,208,208,2,0, + 0,0,7,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,3,208, + 208,208,4,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,25,124,2,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,2,9,9,9,1,24,24,24,2,19,19,19,1,2,2,2,1,0, + 0,0,6,17,17,17,1,24,24,24,5,16,16,16,1,0,0,0,2,255, + 255,255,2,0,0,0,2,99,99,99,1,245,245,245,1,224,224,224,1,229, + 229,229,1,247,247,247,1,162,162,162,1,14,14,14,1,0,0,0,4,162, + 162,162,1,224,224,224,1,225,225,225,1,255,255,255,1,224,224,224,2,152, + 152,152,1,0,0,0,2,255,255,255,2,0,0,0,2,99,99,99,1,172, + 172,172,1,0,0,0,2,9,9,9,1,179,179,179,1,157,157,157,1,0, + 0,0,6,9,9,9,1,255,255,255,1,6,6,6,1,0,0,0,4,255, + 255,255,2,0,0,0,2,99,99,99,1,172,172,172,1,0,0,0,3,30, + 30,30,1,254,254,254,1,13,13,13,1,16,16,16,1,216,216,216,1,10, + 10,10,1,0,0,0,2,9,9,9,1,255,255,255,1,6,6,6,1,0, + 0,0,4,255,255,255,2,0,0,0,2,99,99,99,1,172,172,172,1,0, + 0,0,4,233,233,233,1,57,57,57,1,5,5,5,1,72,72,72,1,3, + 3,3,1,0,0,0,2,9,9,9,1,255,255,255,1,6,6,6,1,0, + 0,0,4,255,255,255,2,0,0,0,2,99,99,99,1,172,172,172,1,0, + 0,0,4,232,232,232,1,56,56,56,1,0,0,0,5,9,9,9,1,255, + 255,255,1,6,6,6,1,0,0,0,4,255,255,255,2,0,0,0,2,99, + 99,99,1,172,172,172,1,0,0,0,3,28,28,28,1,250,250,250,1,18, + 18,18,1,0,0,0,5,9,9,9,1,255,255,255,1,6,6,6,1,0, + 0,0,4,255,255,255,2,0,0,0,2,99,99,99,1,172,172,172,1,0, + 0,0,1,1,1,1,1,28,28,28,1,181,181,181,1,154,154,154,1,0, + 0,0,1,2,2,2,1,32,32,32,1,1,1,1,1,0,0,0,2,9, + 9,9,1,255,255,255,1,6,6,6,1,0,0,0,4,255,255,255,2,0, + 0,0,2,99,99,99,1,253,253,253,1,248,248,248,2,230,230,230,1,145, + 145,145,1,7,7,7,1,0,0,0,1,18,18,18,1,255,255,255,1,13, + 13,13,1,0,0,0,2,9,9,9,1,255,255,255,1,6,6,6,1,0, + 0,0,4,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,25,0,0) + ); + +const + objdata_tmsedatefield: record size: integer; data: array[0..896] of byte end = + (size: 897; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,100,97,116,101,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,8,3,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,44,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,7,0,0,0,5,208,208,208,10,184,255,255,2,208, + 208,208,7,0,0,0,7,208,208,208,8,184,255,255,2,208,208,208,7,0, + 0,0,2,208,208,208,2,0,0,0,3,208,208,208,8,184,255,255,2,208, + 208,208,7,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208,7,184, + 255,255,2,208,208,208,7,0,0,0,2,208,208,208,4,0,0,0,2,208, + 208,208,7,184,255,255,2,208,208,208,7,0,0,0,2,208,208,208,4,0, + 0,0,2,208,208,208,7,184,255,255,2,208,208,208,7,0,0,0,2,208, + 208,208,3,0,0,0,3,208,208,208,7,184,255,255,2,208,208,208,7,0, + 0,0,2,208,208,208,2,0,0,0,3,208,208,208,8,184,255,255,2,208, + 208,208,7,0,0,0,7,208,208,208,8,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,25,164,1,0,0,255,255,255,25,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,7,8,8,8,1,24,24,24,2,20, + 20,20,1,2,2,2,1,0,0,0,10,255,255,255,2,0,0,0,7,89, + 89,89,1,246,246,246,1,224,224,224,1,229,229,229,1,248,248,248,1,167, + 167,167,1,17,17,17,1,0,0,0,8,255,255,255,2,0,0,0,7,89, + 89,89,1,182,182,182,1,0,0,0,2,7,7,7,1,171,171,171,1,167, + 167,167,1,0,0,0,8,255,255,255,2,0,0,0,7,89,89,89,1,182, + 182,182,1,0,0,0,3,21,21,21,1,255,255,255,1,21,21,21,1,0, + 0,0,7,255,255,255,2,0,0,0,7,89,89,89,1,182,182,182,1,0, + 0,0,4,223,223,223,1,67,67,67,1,0,0,0,7,255,255,255,2,0, + 0,0,7,89,89,89,1,182,182,182,1,0,0,0,4,222,222,222,1,66, + 66,66,1,0,0,0,7,255,255,255,2,0,0,0,7,89,89,89,1,182, + 182,182,1,0,0,0,3,21,21,21,1,250,250,250,1,26,26,26,1,0, + 0,0,7,255,255,255,2,0,0,0,7,89,89,89,1,182,182,182,1,0, + 0,0,2,25,25,25,1,174,174,174,1,164,164,164,1,0,0,0,8,255, + 255,255,2,0,0,0,7,89,89,89,1,253,253,253,1,248,248,248,2,232, + 232,232,1,151,151,151,1,9,9,9,1,0,0,0,8,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsetimefield: record size: integer; data: array[0..732] of byte end = + (size: 733; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,116,105,109,101,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,100,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,252,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,7,0,0,0,7,208,208,208,8,184,255,255,2,208, + 208,208,7,0,0,0,8,208,208,208,7,184,255,255,2,208,208,208,10,0, + 0,0,2,208,208,208,10,184,255,255,2,208,208,208,10,0,0,0,2,208, + 208,208,10,184,255,255,2,208,208,208,10,0,0,0,2,208,208,208,10,184, + 255,255,2,208,208,208,10,0,0,0,2,208,208,208,10,184,255,255,2,208, + 208,208,10,0,0,0,2,208,208,208,10,184,255,255,2,208,208,208,10,0, + 0,0,2,208,208,208,10,184,255,255,2,208,208,208,10,0,0,0,2,208, + 208,208,10,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,25,48,1,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,7,8,8,8,1,24,24,24,6,0,0,0,8,255,255,255,2,0, + 0,0,7,82,82,82,1,224,224,224,2,245,245,245,1,236,236,236,1,224, + 224,224,2,8,8,8,1,0,0,0,7,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsebinaryfield: record size: integer; data: array[0..1386] of byte end = + (size: 1387; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,109,115, + 101,98,105,110,97,114,121,102,105,101,108,100,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240,4,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,180,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208, + 22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255, + 2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208, + 22,184,255,255,2,208,208,208,2,0,0,0,4,208,208,208,4,0,0,0, + 2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208, + 2,184,255,255,2,208,208,208,2,0,0,0,6,208,208,208,2,0,0,0, + 5,208,208,208,3,0,0,0,2,208,208,208,2,184,255,255,2,208,208,208, + 2,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0, + 6,208,208,208,2,0,0,0,2,208,208,208,2,184,255,255,2,208,208,208, + 2,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0, + 7,208,208,208,1,0,0,0,2,208,208,208,2,184,255,255,2,208,208,208, + 2,0,0,0,6,208,208,208,2,0,0,0,7,208,208,208,1,0,0,0, + 2,208,208,208,2,184,255,255,2,208,208,208,2,0,0,0,7,208,208,208, + 1,0,0,0,4,208,208,208,1,0,0,0,5,208,208,208,2,184,255,255, + 2,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208, + 1,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,184,255,255, + 2,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208, + 1,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,184,255,255, + 2,208,208,208,2,0,0,0,6,208,208,208,2,0,0,0,4,208,208,208, + 3,0,0,0,3,208,208,208,2,184,255,255,2,208,208,208,22,184,255,255, + 2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208, + 22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255, + 2,208,208,208,22,184,255,255,25,4,3,0,0,255,255,255,25,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,2,17,17,17,1,24,24,24,2,13,13,13, + 1,0,0,0,4,22,22,22,1,2,2,2,1,0,0,0,1,24,24,24, + 1,2,2,2,1,0,0,0,3,16,16,16,1,7,7,7,1,0,0,0, + 2,255,255,255,2,0,0,0,2,191,191,191,1,235,235,235,1,224,224,224, + 1,237,237,237,1,223,223,223,1,60,60,60,1,0,0,0,2,245,245,245, + 1,26,26,26,1,3,3,3,1,255,255,255,1,121,121,121,1,0,0,0, + 3,179,179,179,1,84,84,84,1,0,0,0,2,255,255,255,2,0,0,0, + 2,191,191,191,1,88,88,88,1,0,0,0,2,85,85,85,1,210,210,210, + 1,0,0,0,2,245,245,245,1,26,26,26,1,3,3,3,1,254,254,254, + 1,239,239,239,1,42,42,42,1,0,0,0,2,179,179,179,1,84,84,84, + 1,0,0,0,2,255,255,255,2,0,0,0,2,191,191,191,1,88,88,88, + 1,0,0,0,2,52,52,52,1,211,211,211,1,0,0,0,2,245,245,245, + 1,26,26,26,1,3,3,3,1,252,252,252,1,115,115,115,1,202,202,202, + 1,3,3,3,1,0,0,0,1,179,179,179,1,84,84,84,1,0,0,0, + 2,255,255,255,2,0,0,0,2,191,191,191,1,203,203,203,1,176,176,176, + 1,185,185,185,1,236,236,236,1,54,54,54,1,0,0,0,2,245,245,245, + 1,26,26,26,1,3,3,3,1,252,252,252,1,2,2,2,1,197,197,197, + 1,120,120,120,1,0,0,0,1,179,179,179,1,84,84,84,1,0,0,0, + 2,255,255,255,2,0,0,0,2,191,191,191,1,135,135,135,1,72,72,72, + 1,80,80,80,1,137,137,137,1,213,213,213,1,9,9,9,1,0,0,0, + 1,245,245,245,1,26,26,26,1,3,3,3,1,252,252,252,1,0,0,0, + 1,37,37,37,1,238,238,238,1,41,41,41,1,179,179,179,1,84,84,84, + 1,0,0,0,2,255,255,255,2,0,0,0,2,191,191,191,1,88,88,88, + 1,0,0,0,3,210,210,210,1,74,74,74,1,0,0,0,1,245,245,245, + 1,26,26,26,1,3,3,3,1,252,252,252,1,0,0,0,2,112,112,112, + 1,201,201,201,1,183,183,183,1,84,84,84,1,0,0,0,2,255,255,255, + 2,0,0,0,2,191,191,191,1,88,88,88,1,0,0,0,2,48,48,48, + 1,241,241,241,1,41,41,41,1,0,0,0,1,245,245,245,1,26,26,26, + 1,3,3,3,1,252,252,252,1,0,0,0,2,2,2,2,1,194,194,194, + 1,250,250,250,1,84,84,84,1,0,0,0,2,255,255,255,2,0,0,0, + 2,191,191,191,1,250,250,250,1,248,248,248,1,245,245,245,1,222,222,222, + 1,103,103,103,1,0,0,0,2,245,245,245,1,26,26,26,1,3,3,3, + 1,252,252,252,1,0,0,0,3,36,36,36,1,245,245,245,1,84,84,84, + 1,0,0,0,2,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,25,0,0) + ); + +const + objdata_tmsebytesfield: record size: integer; data: array[0..1385] of byte end = + (size: 1386; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,98,121,116,101,115,102,105,101,108,100,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240,4,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,164,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22, + 184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2, + 208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22, + 184,255,255,2,0,0,0,4,208,208,208,18,184,255,255,2,0,0,0,6, + 208,208,208,7,0,0,0,2,208,208,208,7,184,255,255,2,0,0,0,2, + 208,208,208,2,0,0,0,3,208,208,208,6,0,0,0,2,208,208,208,7, + 184,255,255,2,0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,2, + 0,0,0,5,208,208,208,1,0,0,0,4,208,208,208,1,184,255,255,2, + 0,0,0,6,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,4, + 208,208,208,1,0,0,0,6,184,255,255,2,0,0,0,7,208,208,208,1, + 0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,6, + 184,255,255,2,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1, + 0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,6, + 184,255,255,2,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,1, + 0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,3, + 208,208,208,1,0,0,0,2,184,255,255,2,0,0,0,6,208,208,208,3, + 0,0,0,2,208,208,208,2,0,0,0,9,184,255,255,2,208,208,208,9, + 0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,0,0,0,2, + 208,208,208,2,184,255,255,2,208,208,208,7,0,0,0,3,208,208,208,12, + 184,255,255,2,208,208,208,7,0,0,0,3,208,208,208,12,184,255,255,2, + 208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22, + 184,255,255,2,208,208,208,22,184,255,255,25,20,3,0,0,255,255,255,25, + 0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22, + 255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2, + 0,0,0,22,255,255,255,2,15,15,15,1,24,24,24,2,16,16,16,1, + 0,0,0,18,255,255,255,2,162,162,162,1,238,238,238,1,224,224,224,1, + 235,235,235,1,230,230,230,1,80,80,80,1,0,0,0,7,34,34,34,1, + 117,117,117,1,0,0,0,7,255,255,255,2,162,162,162,1,117,117,117,1, + 0,0,0,2,56,56,56,1,236,236,236,1,3,3,3,1,0,0,0,6, + 82,82,82,1,165,165,165,1,0,0,0,7,255,255,255,2,162,162,162,1, + 117,117,117,1,0,0,0,2,25,25,25,1,235,235,235,1,3,3,3,1, + 120,120,120,1,107,107,107,1,0,0,0,2,107,107,107,1,109,109,109,1, + 212,212,212,1,233,233,233,1,123,123,123,1,0,0,0,1,88,88,88,1, + 191,191,191,1,196,196,196,1,94,94,94,1,0,0,0,1,255,255,255,2, + 162,162,162,1,212,212,212,1,176,176,176,1,183,183,183,1,233,233,233,1, + 79,79,79,1,0,0,0,1,53,53,53,1,212,212,212,1,0,0,0,2, + 212,212,212,1,32,32,32,1,82,82,82,1,165,165,165,1,0,0,0,1, + 86,86,86,1,204,204,204,1,18,18,18,1,23,23,23,1,199,199,199,1, + 82,82,82,1,255,255,255,2,162,162,162,1,156,156,156,1,72,72,72,1, + 78,78,78,1,124,124,124,1,220,220,220,1,26,26,26,1,0,0,0,1, + 211,211,211,1,48,48,48,1,52,52,52,1,191,191,191,1,0,0,0,1, + 82,82,82,1,165,165,165,1,0,0,0,1,162,162,162,1,188,188,188,1, + 128,128,128,2,187,187,187,1,153,153,153,1,255,255,255,2,162,162,162,1, + 117,117,117,1,0,0,0,3,181,181,181,1,103,103,103,1,0,0,0,1, + 114,114,114,1,140,140,140,1,144,144,144,1,96,96,96,1,0,0,0,1, + 82,82,82,1,165,165,165,1,0,0,0,1,170,170,170,1,156,156,156,1, + 80,80,80,3,54,54,54,1,255,255,255,2,162,162,162,1,117,117,117,1, + 0,0,0,2,33,33,33,1,228,228,228,1,69,69,69,1,0,0,0,1, + 22,22,22,1,217,217,217,1,212,212,212,1,12,12,12,1,0,0,0,1, + 75,75,75,1,172,172,172,1,0,0,0,1,113,113,113,1,196,196,196,1, + 5,5,5,1,0,0,0,1,150,150,150,1,84,84,84,1,255,255,255,2, + 162,162,162,1,251,251,251,1,248,248,248,1,246,246,246,1,228,228,228,1, + 124,124,124,1,0,0,0,3,176,176,176,1,160,160,160,1,0,0,0,2, + 32,32,32,1,234,234,234,1,159,159,159,1,6,6,6,1,167,167,167,1, + 230,230,230,1,199,199,199,1,168,168,168,1,4,4,4,1,255,255,255,2, + 0,0,0,9,178,178,178,1,60,60,60,1,0,0,0,3,1,1,1,1, + 6,6,6,1,0,0,0,2,10,10,10,1,8,8,8,1,0,0,0,2, + 255,255,255,2,0,0,0,7,46,46,46,1,171,171,171,1,191,191,191,1, + 0,0,0,12,255,255,255,2,0,0,0,7,15,15,15,1,80,80,80,1, + 14,14,14,1,0,0,0,12,255,255,255,2,0,0,0,22,255,255,255,2, + 0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22, + 255,255,255,25,0,0) + ); + +const + objdata_tmseguidfield: record size: integer; data: array[0..1424] of byte end = + (size: 1425; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,103,117,105,100,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,24,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,196,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,4,0,0,0,2,208,208,208,8,0,0,0,2,208, + 208,208,4,0,0,0,1,208,208,208,1,184,255,255,2,208,208,208,2,0, + 0,0,6,208,208,208,6,0,0,0,2,208,208,208,4,0,0,0,1,208, + 208,208,1,184,255,255,2,208,208,208,1,0,0,0,3,208,208,208,1,0, + 0,0,3,208,208,208,6,0,0,0,2,208,208,208,4,0,0,0,1,208, + 208,208,1,184,255,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0, + 0,0,4,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,4,208, + 208,208,1,184,255,255,2,208,208,208,1,0,0,0,2,208,208,208,1,0, + 0,0,6,208,208,208,2,0,0,0,9,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,2,0, + 0,0,6,208,208,208,1,0,0,0,2,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208,2,0, + 0,0,6,208,208,208,2,0,0,0,1,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,3,208,208,208,1,0,0,0,3,208,208,208,1,0, + 0,0,12,208,208,208,1,184,255,255,2,208,208,208,2,0,0,0,6,208, + 208,208,1,0,0,0,7,208,208,208,1,0,0,0,4,208,208,208,1,184, + 255,255,2,208,208,208,4,0,0,0,2,208,208,208,4,0,0,0,2,208, + 208,208,6,0,0,0,1,208,208,208,3,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,25,28,3,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,4,37,37,37,1,15,15,15,1,0,0,0,8,10,10,10,2,0, + 0,0,4,21,21,21,1,0,0,0,1,255,255,255,2,0,0,0,2,97, + 97,97,1,218,218,218,1,191,191,191,1,224,224,224,1,153,153,153,1,3, + 3,3,1,0,0,0,6,109,109,109,1,114,114,114,1,0,0,0,4,224, + 224,224,1,0,0,0,1,255,255,255,2,0,0,0,1,59,59,59,1,203, + 203,203,1,21,21,21,1,0,0,0,1,4,4,4,1,178,178,178,1,83, + 83,83,1,0,0,0,6,6,6,6,1,7,7,7,1,0,0,0,4,224, + 224,224,1,0,0,0,1,255,255,255,2,0,0,0,1,157,157,157,1,82, + 82,82,1,0,0,0,3,36,36,36,1,41,41,41,1,1,1,1,1,187, + 187,187,1,0,0,0,2,149,149,149,1,39,39,39,1,92,92,92,1,96, + 96,96,1,0,0,0,1,115,115,115,1,220,220,220,1,174,174,174,1,231, + 231,231,1,0,0,0,1,255,255,255,2,0,0,0,1,209,209,209,1,32, + 32,32,1,0,0,0,1,10,10,10,1,32,32,32,2,22,22,22,1,1, + 1,1,1,222,222,222,1,0,0,0,2,177,177,177,1,46,46,46,1,109, + 109,109,1,114,114,114,1,50,50,50,1,203,203,203,1,15,15,15,1,85, + 85,85,1,253,253,253,1,0,0,0,1,255,255,255,2,0,0,0,1,208, + 208,208,1,40,40,40,1,0,0,0,1,69,69,69,1,216,216,216,1,223, + 223,223,1,181,181,181,1,1,1,1,1,222,222,222,1,0,0,0,2,177, + 177,177,1,46,46,46,1,109,109,109,1,114,114,114,1,106,106,106,1,134, + 134,134,1,0,0,0,1,4,4,4,1,242,242,242,1,0,0,0,1,255, + 255,255,2,0,0,0,1,156,156,156,1,94,94,94,1,0,0,0,3,50, + 50,50,1,181,181,181,1,1,1,1,1,224,224,224,1,0,0,0,2,186, + 186,186,1,46,46,46,1,109,109,109,1,114,114,114,1,111,111,111,1,127, + 127,127,1,0,0,0,2,230,230,230,1,0,0,0,1,255,255,255,2,0, + 0,0,1,52,52,52,1,225,225,225,1,52,52,52,1,0,0,0,1,8, + 8,8,1,134,134,134,1,178,178,178,1,0,0,0,1,232,232,232,1,12, + 12,12,2,231,231,231,1,46,46,46,1,109,109,109,1,114,114,114,1,57, + 57,57,1,197,197,197,1,4,4,4,1,50,50,50,1,253,253,253,1,0, + 0,0,1,255,255,255,2,0,0,0,2,72,72,72,1,204,204,204,1,226, + 226,226,1,237,237,237,1,165,165,165,1,22,22,22,1,0,0,0,1,137, + 137,137,1,221,221,221,1,196,196,196,1,187,187,187,1,46,46,46,1,109, + 109,109,1,114,114,114,1,0,0,0,1,140,140,140,1,215,215,215,1,157, + 157,157,1,221,221,221,1,0,0,0,1,255,255,255,2,0,0,0,4,14, + 14,14,1,3,3,3,1,0,0,0,4,14,14,14,1,1,1,1,1,0, + 0,0,6,9,9,9,1,0,0,0,3,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,25,0,0) + ); + +const + objdata_tmsevarbytesfield: record size: integer; data: array[0..1400] of byte end = + (size: 1401; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,109,115, + 101,118,97,114,98,121,116,101,115,102,105,101,108,100,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,252, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,184, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,0,0,0,2,208,208,208,4,0,0,0,7,208, + 208,208,9,184,255,255,2,0,0,0,3,208,208,208,3,0,0,0,9,208, + 208,208,7,184,255,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0, + 0,0,4,208,208,208,2,0,0,0,3,208,208,208,7,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,3,0, + 0,0,5,208,208,208,1,0,0,0,3,184,255,255,2,208,208,208,1,0, + 0,0,3,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,7,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,184, + 255,255,2,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,7,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,184, + 255,255,2,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,2,184, + 255,255,2,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208, + 208,208,2,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2,184, + 255,255,2,208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,7,208, + 208,208,2,0,0,0,3,208,208,208,2,184,255,255,2,208,208,208,17,0, + 0,0,2,208,208,208,3,184,255,255,2,208,208,208,16,0,0,0,3,208, + 208,208,3,184,255,255,2,208,208,208,16,0,0,0,2,208,208,208,4,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,25,12,3,0,0,255, + 255,255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,10,10,10,1,17,17,17,1,0, + 0,0,4,4,4,4,1,21,21,21,1,3,3,3,1,24,24,24,2,23, + 23,23,1,4,4,4,1,0,0,0,9,255,255,255,2,55,55,55,1,232, + 232,232,1,3,3,3,1,0,0,0,3,98,98,98,1,178,178,178,1,39, + 39,39,1,254,254,254,1,224,224,224,1,226,226,226,1,241,241,241,1,174, + 174,174,1,11,11,11,1,0,0,0,7,255,255,255,2,0,0,0,1,212, + 212,212,1,71,71,71,1,0,0,0,3,194,194,194,1,78,78,78,1,39, + 39,39,1,240,240,240,1,0,0,0,2,4,4,4,1,185,185,185,1,106, + 106,106,1,0,0,0,7,255,255,255,2,0,0,0,1,113,113,113,1,162, + 162,162,1,0,0,0,2,34,34,34,1,229,229,229,1,4,4,4,1,39, + 39,39,1,240,240,240,1,0,0,0,3,157,157,157,1,106,106,106,1,19, + 19,19,1,202,202,202,1,5,5,5,1,0,0,0,1,10,10,10,1,194, + 194,194,1,3,3,3,1,255,255,255,2,0,0,0,1,21,21,21,1,237, + 237,237,1,10,10,10,1,0,0,0,1,128,128,128,1,134,134,134,1,0, + 0,0,1,39,39,39,1,251,251,251,1,176,176,176,1,177,177,177,1,202, + 202,202,1,195,195,195,1,6,6,6,1,0,0,0,1,186,186,186,1,78, + 78,78,1,0,0,0,1,91,91,91,1,153,153,153,1,0,0,0,1,255, + 255,255,2,0,0,0,2,172,172,172,1,88,88,88,1,1,1,1,1,221, + 221,221,1,36,36,36,1,0,0,0,1,39,39,39,1,244,244,244,1,72, + 72,72,2,91,91,91,1,198,198,198,1,121,121,121,1,0,0,0,1,89, + 89,89,1,171,171,171,1,0,0,0,1,185,185,185,1,58,58,58,1,0, + 0,0,1,255,255,255,2,0,0,0,2,73,73,73,1,179,179,179,1,63, + 63,63,1,191,191,191,1,0,0,0,2,39,39,39,1,240,240,240,1,0, + 0,0,3,58,58,58,1,226,226,226,1,0,0,0,1,8,8,8,1,231, + 231,231,1,39,39,39,1,215,215,215,1,0,0,0,2,255,255,255,2,0, + 0,0,2,2,2,2,1,220,220,220,1,162,162,162,1,91,91,91,1,0, + 0,0,2,39,39,39,1,240,240,240,1,0,0,0,2,5,5,5,1,134, + 134,134,1,191,191,191,1,0,0,0,2,151,151,151,1,190,190,190,1,122, + 122,122,1,0,0,0,2,255,255,255,2,0,0,0,3,131,131,131,1,237, + 237,237,1,8,8,8,1,0,0,0,2,39,39,39,1,255,255,255,1,248, + 248,248,1,247,247,247,1,239,239,239,1,191,191,191,1,38,38,38,1,0, + 0,0,2,54,54,54,1,253,253,253,1,29,29,29,1,0,0,0,2,255, + 255,255,2,0,0,0,17,56,56,56,1,182,182,182,1,0,0,0,3,255, + 255,255,2,0,0,0,16,129,129,129,1,218,218,218,1,62,62,62,1,0, + 0,0,3,255,255,255,2,0,0,0,16,61,61,61,1,49,49,49,1,0, + 0,0,4,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0, + 0) + ); + +const + objdata_tmsebcdfield: record size: integer; data: array[0..1439] of byte end = + (size: 1440; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,109,115, + 101,98,99,100,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,40,5,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,200,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,1,0,0,0,4,208,208,208,5,0,0,0,2,208,208, + 208,3,0,0,0,4,208,208,208,3,184,255,255,2,208,208,208,1,0,0, + 0,5,208,208,208,2,0,0,0,6,208,208,208,1,0,0,0,6,208,208, + 208,1,184,255,255,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,3,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,2,0,0,0,3,184,255,255,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,6,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,184,255, + 255,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,2,208,208, + 208,6,0,0,0,2,208,208,208,3,0,0,0,2,184,255,255,2,208,208, + 208,1,0,0,0,8,208,208,208,6,0,0,0,2,208,208,208,3,0,0, + 0,2,184,255,255,2,208,208,208,1,0,0,0,1,208,208,208,3,0,0, + 0,5,208,208,208,2,0,0,0,5,208,208,208,2,0,0,0,3,184,255, + 255,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,3,208,208, + 208,1,0,0,0,6,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,3,208,208,208,1,184,255,255,2,208,208,208,1,0,0,0,6,208,208, + 208,1,0,0,0,6,208,208,208,1,0,0,0,6,208,208,208,1,184,255, + 255,2,208,208,208,10,0,0,0,2,208,208,208,10,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,25,40,3,0,0,255,255,255,25,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,1,23,23,23,1,24,24,24,1,22,22,22,1,1,1, + 1,1,0,0,0,5,17,17,17,1,22,22,22,1,0,0,0,3,16,16, + 16,1,24,24,24,1,23,23,23,1,8,8,8,1,0,0,0,3,255,255, + 255,2,0,0,0,1,247,247,247,1,224,224,224,1,227,227,227,1,238,238, + 238,1,118,118,118,1,0,0,0,2,15,15,15,1,187,187,187,1,219,219, + 219,1,211,211,211,1,188,188,188,1,18,18,18,1,0,0,0,1,180,180, + 180,1,232,232,232,1,224,224,224,1,244,244,244,1,195,195,195,1,33,33, + 33,1,0,0,0,1,255,255,255,2,0,0,0,1,247,247,247,1,0,0, + 0,2,17,17,17,1,228,228,228,1,21,21,21,1,0,0,0,1,190,190, + 190,1,115,115,115,1,0,0,0,2,127,127,127,1,155,155,155,1,0,0, + 0,1,180,180,180,1,67,67,67,1,0,0,0,2,121,121,121,1,192,192, + 192,1,1,1,1,1,255,255,255,2,0,0,0,1,247,247,247,1,0,0, + 0,2,3,3,3,1,217,217,217,1,21,21,21,1,26,26,26,1,221,221, + 221,1,1,1,1,1,0,0,0,2,8,8,8,1,62,62,62,1,0,0, + 0,1,180,180,180,1,67,67,67,1,0,0,0,3,234,234,234,1,38,38, + 38,1,255,255,255,2,0,0,0,1,247,247,247,1,176,176,176,1,178,178, + 178,1,216,216,216,1,128,128,128,1,0,0,0,1,76,76,76,1,175,175, + 175,1,0,0,0,6,180,180,180,1,67,67,67,1,0,0,0,3,185,185, + 185,1,75,75,75,1,255,255,255,2,0,0,0,1,247,247,247,1,72,72, + 72,1,73,73,73,1,101,101,101,1,217,217,217,1,43,43,43,1,69,69, + 69,1,182,182,182,1,0,0,0,6,180,180,180,1,67,67,67,1,0,0, + 0,3,182,182,182,1,74,74,74,1,255,255,255,2,0,0,0,1,247,247, + 247,1,0,0,0,3,130,130,130,1,124,124,124,1,20,20,20,1,226,226, + 226,1,2,2,2,1,0,0,0,2,18,18,18,1,174,174,174,1,3,3, + 3,1,180,180,180,1,67,67,67,1,0,0,0,2,3,3,3,1,225,225, + 225,1,37,37,37,1,255,255,255,2,0,0,0,1,247,247,247,1,0,0, + 0,2,13,13,13,1,191,191,191,1,94,94,94,1,0,0,0,1,167,167, + 167,1,131,131,131,1,2,2,2,1,7,7,7,1,148,148,148,1,133,133, + 133,1,0,0,0,1,180,180,180,1,67,67,67,1,0,0,0,1,10,10, + 10,1,129,129,129,1,190,190,190,1,0,0,0,1,255,255,255,2,0,0, + 0,1,247,247,247,1,248,248,248,1,247,247,247,1,236,236,236,1,156,156, + 156,1,3,3,3,1,0,0,0,1,14,14,14,1,173,173,173,1,222,222, + 222,1,223,223,223,1,156,156,156,1,13,13,13,1,0,0,0,1,180,180, + 180,1,250,250,250,1,248,248,248,1,240,240,240,1,176,176,176,1,23,23, + 23,1,0,0,0,1,255,255,255,2,0,0,0,10,5,5,5,1,7,7, + 7,1,0,0,0,10,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmseblobfield: record size: integer; data: array[0..1444] of byte end = + (size: 1445; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,98,108,111,98,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,188,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,1,0,0,0,4,208,208,208,3,0,0,0,2,208, + 208,208,6,0,0,0,2,208,208,208,4,184,255,255,2,208,208,208,1,0, + 0,0,6,208,208,208,1,0,0,0,2,208,208,208,6,0,0,0,2,208, + 208,208,4,184,255,255,2,208,208,208,1,0,0,0,2,208,208,208,2,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,6,0,0,0,2,208, + 208,208,4,184,255,255,2,208,208,208,1,0,0,0,2,208,208,208,2,0, + 0,0,2,208,208,208,1,0,0,0,7,208,208,208,1,0,0,0,5,208, + 208,208,1,184,255,255,2,208,208,208,1,0,0,0,6,208,208,208,1,0, + 0,0,7,208,208,208,1,0,0,0,5,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,6,208,208,208,1,0,0,0,4,208,208,208,2,0, + 0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,7,208,208,208,2,0, + 0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,13,208,208,208,1,0, + 0,0,2,208,208,208,1,184,255,255,2,208,208,208,1,0,0,0,6,208, + 208,208,1,0,0,0,7,208,208,208,1,0,0,0,5,208,208,208,1,184, + 255,255,2,208,208,208,12,0,0,0,2,208,208,208,4,0,0,0,1,208, + 208,208,3,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,25,56,3,0,0,255, + 255,255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,1,9,9,9,1,24, + 24,24,2,14,14,14,1,0,0,0,3,15,15,15,1,5,5,5,1,0, + 0,0,6,16,16,16,1,5,5,5,1,0,0,0,4,255,255,255,2,0, + 0,0,1,104,104,104,1,241,241,241,1,224,224,224,1,236,236,236,1,214, + 214,214,1,35,35,35,1,0,0,0,1,170,170,170,1,61,61,61,1,0, + 0,0,6,176,176,176,1,55,55,55,1,0,0,0,4,255,255,255,2,0, + 0,0,1,104,104,104,1,143,143,143,1,0,0,0,2,104,104,104,1,161, + 161,161,1,0,0,0,1,170,170,170,1,61,61,61,1,0,0,0,6,176, + 176,176,1,55,55,55,1,0,0,0,4,255,255,255,2,0,0,0,1,104, + 104,104,1,143,143,143,1,0,0,0,2,80,80,80,1,162,162,162,1,0, + 0,0,1,170,170,170,1,61,61,61,1,2,2,2,1,124,124,124,1,210, + 210,210,1,173,173,173,1,49,49,49,1,0,0,0,1,176,176,176,1,136, + 136,136,1,208,208,208,1,192,192,192,1,24,24,24,1,0,0,0,1,255, + 255,255,2,0,0,0,1,104,104,104,1,220,220,220,1,176,176,176,1,185, + 185,185,1,230,230,230,1,29,29,29,1,0,0,0,1,170,170,170,1,61, + 61,61,1,98,98,98,1,187,187,187,1,15,15,15,1,57,57,57,1,202, + 202,202,1,0,0,0,1,176,176,176,1,169,169,169,1,7,7,7,1,125, + 125,125,1,160,160,160,1,0,0,0,1,255,255,255,2,0,0,0,1,104, + 104,104,1,175,175,175,1,72,72,72,1,80,80,80,1,152,152,152,1,171, + 171,171,1,0,0,0,1,170,170,170,1,61,61,61,1,159,159,159,1,93, + 93,93,1,0,0,0,2,206,206,206,1,29,29,29,1,176,176,176,1,75, + 75,75,1,0,0,0,1,35,35,35,1,222,222,222,1,0,0,0,1,255, + 255,255,2,0,0,0,1,104,104,104,1,143,143,143,1,0,0,0,2,1, + 1,1,1,239,239,239,1,14,14,14,1,170,170,170,1,61,61,61,1,165, + 165,165,1,84,84,84,1,0,0,0,2,201,201,201,1,46,46,46,1,176, + 176,176,1,58,58,58,1,0,0,0,1,28,28,28,1,220,220,220,1,0, + 0,0,1,255,255,255,2,0,0,0,1,104,104,104,1,143,143,143,1,0, + 0,0,2,63,63,63,1,235,235,235,1,1,1,1,1,170,170,170,1,61, + 61,61,1,113,113,113,1,166,166,166,1,1,1,1,1,28,28,28,1,243, + 243,243,1,6,6,6,1,176,176,176,1,133,133,133,1,0,0,0,1,102, + 102,102,1,162,162,162,1,0,0,0,1,255,255,255,2,0,0,0,1,104, + 104,104,1,252,252,252,1,248,248,248,1,245,245,245,1,215,215,215,1,73, + 73,73,1,0,0,0,1,170,170,170,1,61,61,61,1,9,9,9,1,144, + 144,144,1,203,203,203,1,225,225,225,1,80,80,80,1,0,0,0,1,176, + 176,176,1,152,152,152,1,201,201,201,1,174,174,174,1,29,29,29,1,0, + 0,0,1,255,255,255,2,0,0,0,12,9,9,9,1,2,2,2,1,0, + 0,0,4,7,7,7,1,0,0,0,3,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,25,0,0) + ); + +const + objdata_tmsememofield: record size: integer; data: array[0..1800] of byte end = + (size: 1801; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,109,101,109,111,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,144,6,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,60,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,5,0,0,0,2,208,208,208,3,0,0,0,3,208, + 208,208,9,184,255,255,2,208,208,208,5,0,0,0,2,208,208,208,3,0, + 0,0,3,208,208,208,9,184,255,255,2,208,208,208,5,0,0,0,3,208, + 208,208,1,0,0,0,4,208,208,208,1,0,0,0,3,208,208,208,5,184, + 255,255,2,208,208,208,5,0,0,0,3,208,208,208,1,0,0,0,9,208, + 208,208,4,184,255,255,2,208,208,208,5,0,0,0,3,208,208,208,1,0, + 0,0,6,208,208,208,1,0,0,0,2,208,208,208,4,184,255,255,2,208, + 208,208,5,0,0,0,1,208,208,208,1,0,0,0,12,208,208,208,3,184, + 255,255,2,208,208,208,5,0,0,0,1,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,4,208,208,208,1,0,0,0,3,208,208,208,3,184, + 255,255,2,208,208,208,5,0,0,0,1,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,7,208,208,208,4,184,255,255,2,208,208,208,5,0, + 0,0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,4,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,5,0,0,0,2,208, + 208,208,3,0,0,0,3,208,208,208,9,184,255,255,2,208,208,208,5,0, + 0,0,2,208,208,208,3,0,0,0,3,208,208,208,9,184,255,255,2,208, + 208,208,5,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,9,184, + 255,255,2,208,208,208,5,0,0,0,3,208,208,208,1,0,0,0,9,208, + 208,208,4,184,255,255,2,208,208,208,5,0,0,0,3,208,208,208,1,0, + 0,0,9,208,208,208,4,184,255,255,2,208,208,208,5,0,0,0,3,208, + 208,208,1,0,0,0,6,208,208,208,1,0,0,0,3,208,208,208,3,184, + 255,255,2,208,208,208,5,0,0,0,1,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,3,184, + 255,255,2,208,208,208,5,0,0,0,1,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,4,184, + 255,255,2,208,208,208,5,0,0,0,1,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,7,208,208,208,4,184,255,255,2,208,208,208,22,184, + 255,255,25,28,4,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0, + 0,0,5,143,143,143,1,92,92,92,1,0,0,0,3,53,53,53,1,152, + 152,152,1,8,8,8,1,0,0,0,9,255,255,255,2,0,0,0,5,241, + 241,241,1,212,212,212,1,0,0,0,3,153,153,153,1,253,253,253,1,13, + 13,13,1,0,0,0,9,255,255,255,2,0,0,0,5,240,240,240,1,189, + 189,189,1,37,37,37,1,0,0,0,1,1,1,1,1,199,199,199,1,227, + 227,227,1,13,13,13,1,0,0,0,1,8,8,8,1,93,93,93,1,34, + 34,34,1,0,0,0,5,255,255,255,2,0,0,0,5,240,240,240,1,110, + 110,110,1,114,114,114,1,0,0,0,1,56,56,56,1,144,144,144,1,226, + 226,226,1,13,13,13,1,45,45,45,1,203,203,203,1,120,120,120,1,190, + 190,190,1,105,105,105,1,0,0,0,4,255,255,255,2,0,0,0,5,240, + 240,240,1,31,31,31,1,190,190,190,1,0,0,0,1,136,136,136,1,63, + 63,63,1,226,226,226,1,13,13,13,1,155,155,155,1,95,95,95,1,0, + 0,0,1,11,11,11,1,194,194,194,1,0,0,0,4,255,255,255,2,0, + 0,0,5,240,240,240,1,0,0,0,1,203,203,203,1,16,16,16,1,196, + 196,196,1,3,3,3,1,226,226,226,1,13,13,13,1,188,188,188,1,216, + 216,216,1,208,208,208,2,206,206,206,1,12,12,12,1,0,0,0,3,255, + 255,255,2,0,0,0,5,240,240,240,1,0,0,0,1,128,128,128,1,126, + 126,126,1,158,158,158,1,0,0,0,1,226,226,226,1,13,13,13,1,132, + 132,132,1,97,97,97,1,0,0,0,1,1,1,1,1,78,78,78,1,1, + 1,1,1,0,0,0,3,255,255,255,2,0,0,0,5,240,240,240,1,0, + 0,0,1,49,49,49,1,246,246,246,1,78,78,78,1,0,0,0,1,226, + 226,226,1,13,13,13,1,50,50,50,1,212,212,212,1,83,83,83,1,138, + 138,138,1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0,5,120, + 120,120,1,0,0,0,2,122,122,122,1,8,8,8,1,0,0,0,1,113, + 113,113,1,6,6,6,1,0,0,0,1,29,29,29,1,127,127,127,1,96, + 96,96,1,13,13,13,1,0,0,0,4,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,5,22,22,22,1,12, + 12,12,1,0,0,0,3,6,6,6,1,24,24,24,1,1,1,1,1,0, + 0,0,9,255,255,255,2,0,0,0,5,242,242,242,1,178,178,178,1,0, + 0,0,3,113,113,113,1,255,255,255,1,13,13,13,1,0,0,0,9,255, + 255,255,2,0,0,0,5,240,240,240,1,218,218,218,1,9,9,9,1,0, + 0,0,2,187,187,187,1,239,239,239,1,13,13,13,1,0,0,0,9,255, + 255,255,2,0,0,0,5,240,240,240,1,149,149,149,1,76,76,76,1,0, + 0,0,1,20,20,20,1,181,181,181,1,226,226,226,1,13,13,13,1,10, + 10,10,1,138,138,138,1,214,214,214,1,160,160,160,1,36,36,36,1,0, + 0,0,4,255,255,255,2,0,0,0,5,240,240,240,1,70,70,70,1,152, + 152,152,1,0,0,0,1,96,96,96,1,104,104,104,1,226,226,226,1,13, + 13,13,1,129,129,129,1,163,163,163,1,8,8,8,1,86,86,86,1,173, + 173,173,1,0,0,0,4,255,255,255,2,0,0,0,5,240,240,240,1,6, + 6,6,1,213,213,213,1,0,0,0,1,174,174,174,1,25,25,25,1,226, + 226,226,1,13,13,13,1,190,190,190,1,63,63,63,1,0,0,0,1,2, + 2,2,1,225,225,225,1,9,9,9,1,0,0,0,3,255,255,255,2,0, + 0,0,5,240,240,240,1,0,0,0,1,168,168,168,1,59,59,59,1,189, + 189,189,1,0,0,0,1,226,226,226,1,13,13,13,1,196,196,196,1,53, + 53,53,1,0,0,0,2,231,231,231,1,16,16,16,1,0,0,0,3,255, + 255,255,2,0,0,0,5,240,240,240,1,0,0,0,1,89,89,89,1,201, + 201,201,1,118,118,118,1,0,0,0,1,226,226,226,1,13,13,13,1,144, + 144,144,1,138,138,138,1,0,0,0,1,54,54,54,1,222,222,222,1,0, + 0,0,4,255,255,255,2,0,0,0,5,240,240,240,1,0,0,0,1,15, + 15,15,1,250,250,250,1,37,37,37,1,0,0,0,1,226,226,226,1,13, + 13,13,1,20,20,20,1,157,157,157,1,203,203,203,1,223,223,223,1,57, + 57,57,1,0,0,0,4,255,255,255,2,0,0,0,22,255,255,255,25,0, + 0) + ); + +const + objdata_tmsegraphicfield: record size: integer; data: array[0..1451] of byte end = + (size: 1452; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,103,114,97,112,104,105,99,102,105,101,108,100,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48,5, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,104,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,255,191, + 141,22,184,255,255,2,255,191,141,22,184,255,255,2,255,194,147,13,255,194, + 146,9,184,255,255,2,255,197,153,3,238,200,160,1,123,218,205,1,21,235, + 247,1,54,230,234,1,167,211,187,1,255,197,153,10,255,197,152,4,184,255, + 255,2,255,201,159,3,123,220,208,1,32,239,250,1,123,249,254,1,98,247, + 254,1,3,237,252,1,218,206,173,1,255,201,159,13,184,255,255,2,255,204, + 165,3,21,236,247,1,123,249,254,1,183,255,255,2,56,241,252,1,118,221, + 212,1,255,204,165,13,184,255,255,2,255,208,171,3,54,232,237,1,98,247, + 254,1,183,255,255,2,32,238,250,1,153,220,204,1,255,208,171,13,184,255, + 255,2,255,211,177,3,167,220,203,1,3,237,252,1,56,241,252,1,32,238, + 250,1,18,235,248,1,244,212,180,1,255,211,177,13,184,255,255,2,255,215, + 183,4,218,218,193,1,118,226,221,1,153,224,211,1,244,216,186,1,255,215, + 183,8,255,214,183,5,248,211,178,1,184,255,255,2,255,218,189,19,197,199, + 145,1,91,174,66,1,12,151,6,1,184,255,255,2,255,222,195,6,255,221, + 195,11,188,200,144,1,77,177,57,1,6,180,3,1,4,181,0,1,4,164, + 0,1,184,255,255,2,255,225,201,15,201,208,159,1,79,184,62,1,7,192, + 4,1,2,194,0,1,3,186,0,1,4,178,0,1,5,162,0,1,184,255, + 255,2,255,228,208,5,255,228,207,8,248,225,201,1,96,189,77,1,11,200, + 8,1,1,207,1,1,2,199,0,1,3,191,0,1,3,183,0,1,4,174, + 0,1,5,162,0,1,184,255,255,2,255,232,214,9,255,232,213,3,251,230, + 210,1,63,184,52,1,0,218,1,1,1,212,1,1,2,204,1,1,2,196, + 0,1,3,187,0,1,4,179,0,1,4,171,0,1,5,162,0,1,184,255, + 255,2,253,101,47,1,254,125,59,1,254,131,70,1,254,137,82,1,254,143, + 93,1,254,150,104,1,254,156,116,1,253,159,121,1,250,148,104,1,248,137, + 85,1,245,126,67,1,243,116,49,1,235,101,30,1,29,162,3,1,1,216, + 1,1,1,208,1,1,2,200,1,1,3,192,0,1,3,184,0,1,4,176, + 0,1,5,171,0,1,5,162,0,1,184,255,255,2,254,120,50,1,255,146, + 61,1,255,154,74,1,255,161,88,1,255,169,101,1,255,176,115,1,255,184, + 129,1,255,191,142,1,252,179,122,1,249,166,100,1,246,153,79,1,243,140, + 57,1,240,126,36,1,176,109,12,1,6,192,1,1,2,205,1,1,2,197, + 0,1,3,189,0,1,4,181,0,1,4,173,0,1,5,171,0,1,5,162, + 0,1,184,255,255,2,254,120,50,1,255,144,58,1,255,152,71,1,255,160, + 85,1,255,167,98,1,255,175,112,1,255,182,126,1,255,190,139,1,252,182, + 126,1,249,169,105,1,246,155,83,1,243,142,62,1,240,129,40,1,237,116, + 19,1,94,125,3,1,2,201,1,1,2,194,0,1,3,186,0,1,4,178, + 0,1,5,171,0,2,5,162,0,1,184,255,255,2,254,120,50,1,255,143, + 55,1,255,150,68,1,255,158,82,1,255,165,95,1,255,173,109,1,255,180, + 123,1,255,188,136,1,253,185,131,1,250,171,110,1,247,158,88,1,244,145, + 67,1,241,132,45,1,238,119,24,1,228,106,2,1,41,150,2,1,3,191, + 0,1,3,183,0,1,4,175,0,1,5,171,0,2,5,162,0,1,184,255, + 255,2,254,120,50,1,255,142,53,1,255,149,65,1,255,156,79,1,255,164, + 92,1,255,171,106,1,255,179,120,1,255,186,133,1,254,187,136,1,251,174, + 114,1,248,161,93,1,245,148,71,1,242,135,50,1,239,122,28,1,236,109, + 7,1,189,111,0,1,28,157,2,1,4,180,0,1,4,171,0,1,5,171, + 0,2,5,162,0,1,184,255,255,2,254,120,50,1,255,142,53,1,255,147, + 62,1,255,155,76,1,255,162,89,1,255,170,103,1,255,177,117,1,255,185, + 130,1,254,190,141,1,251,177,119,1,248,164,98,1,245,151,76,1,242,138, + 55,1,239,125,33,1,236,112,12,1,235,105,0,1,183,111,1,1,23,151, + 2,1,5,171,0,3,5,162,0,1,184,255,255,2,254,120,50,1,255,142, + 53,1,255,145,59,1,255,153,73,1,255,160,86,1,255,168,100,1,255,175, + 114,1,255,183,127,1,255,191,141,1,252,180,124,1,249,167,102,1,246,154, + 81,1,243,141,59,1,240,128,38,1,237,115,16,1,235,105,0,2,178,107, + 2,1,19,151,1,1,5,171,0,2,5,162,0,1,184,255,255,2,253,101, + 47,1,254,120,50,1,254,121,52,1,254,127,64,1,254,134,75,1,254,140, + 87,1,254,147,98,1,254,153,109,1,254,159,121,1,252,154,114,1,250,143, + 95,1,247,132,77,1,244,121,59,1,242,110,41,1,239,99,23,1,237,89, + 5,3,173,89,7,1,13,151,1,1,5,162,0,1,4,155,0,1,184,255, + 255,25,144,0,0,0,255,255,255,255,255,255,255,6,237,237,237,1,235,235, + 235,1,255,255,255,20,247,247,247,1,249,249,249,1,255,255,255,20,252,252, + 252,1,251,251,251,1,255,255,255,20,254,254,254,1,249,249,249,1,255,255, + 255,21,233,233,233,1,255,255,255,22,251,251,251,1,226,226,226,1,255,255, + 255,23,244,244,244,1,245,245,245,1,255,255,255,23,242,242,242,1,255,255, + 255,24,245,245,245,1,255,255,255,24,245,245,245,1,255,255,255,24,242,242, + 242,1,255,255,255,23,252,252,252,1,239,239,239,1,255,255,255,23,246,246, + 246,1,239,239,239,1,255,255,255,27,0,0) + ); + +const + objdata_tmsevariantfield: record size: integer; data: array[0..1399] of byte end = + (size: 1400; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,118,97,114,105,97,110,116,102,105,101,108,100,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,252,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,192,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,1,180,249,249,1,0,0,0,1,208,208,208,5,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,5,208,208, + 208,3,184,255,255,1,170,235,235,1,0,0,0,2,208,208,208,3,0,0, + 0,2,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,7,208,208, + 208,1,184,255,255,2,0,0,0,2,208,208,208,3,0,0,0,2,208,208, + 208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,3,0,0, + 0,3,184,255,255,2,0,0,0,2,208,208,208,2,0,0,0,3,208,208, + 208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,3,0,0, + 0,3,184,255,255,2,0,0,0,3,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,6,208,208,208,1,0,0,0,7,208,208,208,1,184,255, + 255,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,6,208,208,208,1,0,0,0,6,208,208,208,2,184,255, + 255,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,9,208,208, + 208,2,0,0,0,3,208,208,208,1,184,255,255,2,208,208,208,2,0,0, + 0,3,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,5,208,208, + 208,3,0,0,0,3,184,255,255,2,208,208,208,2,0,0,0,3,208,208, + 208,1,0,0,0,2,208,208,208,4,0,0,0,4,208,208,208,3,0,0, + 0,3,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,25,4,3,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,21,21, + 21,1,0,0,0,5,24,24,24,1,1,1,1,1,0,0,0,1,13,13, + 13,1,14,14,14,1,0,0,0,3,5,5,5,1,24,24,24,3,17,17, + 17,1,0,0,0,3,255,255,255,2,246,246,246,1,24,24,24,1,0,0, + 0,3,57,57,57,1,218,218,218,1,0,0,0,2,196,196,196,1,214,214, + 214,1,0,0,0,3,58,58,58,1,249,249,249,1,208,208,208,2,221,221, + 221,1,241,241,241,1,113,113,113,1,0,0,0,1,255,255,255,2,171,171, + 171,1,112,112,112,1,0,0,0,3,152,152,152,1,120,120,120,1,0,0, + 0,1,42,42,42,1,198,198,198,1,194,194,194,1,64,64,64,1,0,0, + 0,2,58,58,58,1,221,221,221,1,0,0,0,3,52,52,52,1,251,251, + 251,1,19,19,19,1,255,255,255,2,72,72,72,1,203,203,203,1,0,0, + 0,2,8,8,8,1,235,235,235,1,24,24,24,1,0,0,0,1,141,141, + 141,1,120,120,120,1,102,102,102,1,168,168,168,1,0,0,0,2,58,58, + 58,1,221,221,221,1,0,0,0,3,9,9,9,1,239,239,239,1,25,25, + 25,1,255,255,255,2,2,2,2,1,226,226,226,1,39,39,39,1,0,0, + 0,1,87,87,87,1,176,176,176,1,0,0,0,1,5,5,5,1,232,232, + 232,1,29,29,29,1,15,15,15,1,241,241,241,1,22,22,22,1,0,0, + 0,1,58,58,58,1,238,238,238,1,128,128,128,2,140,140,140,1,202,202, + 202,1,139,139,139,1,0,0,0,1,255,255,255,2,0,0,0,1,130,130, + 130,2,0,0,0,1,182,182,182,1,76,76,76,1,0,0,0,1,82,82, + 82,1,219,219,219,1,80,80,80,2,205,205,205,1,119,119,119,1,0,0, + 0,1,58,58,58,1,235,235,235,1,104,104,104,1,114,114,114,1,224,224, + 224,1,107,107,107,1,0,0,0,2,255,255,255,2,0,0,0,1,33,33, + 33,1,219,219,219,1,25,25,25,1,225,225,225,1,3,3,3,1,0,0, + 0,1,181,181,181,1,175,175,175,1,144,144,144,2,164,164,164,1,221,221, + 221,1,1,1,1,1,58,58,58,1,221,221,221,1,0,0,0,2,37,37, + 37,1,239,239,239,1,64,64,64,1,0,0,0,1,255,255,255,2,0,0, + 0,2,189,189,189,1,155,155,155,1,132,132,132,1,0,0,0,1,27,27, + 27,1,243,243,243,1,14,14,14,1,0,0,0,2,3,3,3,1,229,229, + 229,1,71,71,71,1,58,58,58,1,221,221,221,1,0,0,0,3,101,101, + 101,1,225,225,225,1,12,12,12,1,255,255,255,2,0,0,0,2,90,90, + 90,1,253,253,253,1,34,34,34,1,0,0,0,1,123,123,123,1,169,169, + 169,1,0,0,0,4,134,134,134,1,175,175,175,1,58,58,58,1,221,221, + 221,1,0,0,0,3,1,1,1,1,193,193,193,1,147,147,147,1,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tparamconnector: record size: integer; data: array[0..1390] of byte end = + (size: 1391; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,112,97, + 114,97,109,99,111,110,110,101,99,116,111,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,244,4,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,176,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,156,156,156,25,208,208,208, + 22,156,156,156,2,208,208,208,22,156,156,156,2,208,208,208,22,156,156,156, + 2,208,208,208,22,156,156,156,2,208,208,208,22,156,156,156,2,208,208,208, + 22,156,156,156,2,208,208,208,1,0,0,0,5,208,208,208,3,0,0,0, + 2,208,208,208,3,0,0,0,5,208,208,208,3,156,156,156,2,208,208,208, + 1,0,0,0,6,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0, + 7,208,208,208,1,156,156,156,2,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,3,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0, + 2,208,208,208,2,0,0,0,3,208,208,208,1,156,156,156,2,208,208,208, + 1,0,0,0,2,208,208,208,3,0,0,0,6,208,208,208,2,0,0,0, + 2,208,208,208,3,0,0,0,2,208,208,208,1,156,156,156,2,208,208,208, + 1,0,0,0,9,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0, + 7,208,208,208,1,156,156,156,2,208,208,208,1,0,0,0,6,208,208,208, + 1,0,0,0,5,208,208,208,1,0,0,0,6,208,208,208,2,156,156,156, + 2,208,208,208,1,0,0,0,2,208,208,208,4,0,0,0,9,208,208,208, + 2,0,0,0,2,208,208,208,2,156,156,156,2,208,208,208,1,0,0,0, + 2,208,208,208,4,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208, + 2,0,0,0,3,208,208,208,1,156,156,156,2,208,208,208,1,0,0,0, + 2,208,208,208,4,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208, + 3,0,0,0,3,156,156,156,2,208,208,208,22,156,156,156,2,208,208,208, + 22,156,156,156,2,208,208,208,22,156,156,156,2,208,208,208,22,156,156,156, + 2,208,208,208,22,156,156,156,2,208,208,208,22,156,156,156,2,208,208,208, + 22,156,156,156,25,12,3,0,0,255,255,255,25,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,1,6,6,6,1,24,24,24,2,21,21,21,1,3,3,3, + 1,0,0,0,3,4,4,4,1,21,21,21,1,0,0,0,3,8,8,8, + 1,24,24,24,2,23,23,23,1,5,5,5,1,0,0,0,3,255,255,255, + 2,0,0,0,1,70,70,70,1,246,246,246,1,224,224,224,1,225,225,225, + 1,237,237,237,1,132,132,132,1,0,0,0,2,96,96,96,1,248,248,248, + 1,24,24,24,1,0,0,0,2,85,85,85,1,238,238,238,1,208,208,208, + 2,240,240,240,1,180,180,180,1,9,9,9,1,0,0,0,1,255,255,255, + 2,0,0,0,1,70,70,70,1,177,177,177,1,0,0,0,2,20,20,20, + 1,230,230,230,1,41,41,41,1,0,0,0,1,185,185,185,1,151,151,151, + 1,115,115,115,1,0,0,0,2,85,85,85,1,162,162,162,1,0,0,0, + 2,8,8,8,1,193,193,193,1,89,89,89,1,0,0,0,1,255,255,255, + 2,0,0,0,1,70,70,70,1,177,177,177,1,0,0,0,3,200,200,200, + 1,55,55,55,1,21,21,21,1,215,215,215,1,36,36,36,1,210,210,210, + 1,0,0,0,2,85,85,85,1,162,162,162,1,0,0,0,3,154,154,154, + 1,96,96,96,1,0,0,0,1,255,255,255,2,0,0,0,1,70,70,70, + 1,196,196,196,1,64,64,64,1,69,69,69,1,129,129,129,1,225,225,225, + 1,1,1,1,1,106,106,106,1,132,132,132,1,0,0,0,1,204,204,204, + 1,49,49,49,1,0,0,0,1,85,85,85,1,209,209,209,1,128,128,128, + 1,129,129,129,1,163,163,163,1,203,203,203,1,15,15,15,1,0,0,0, + 1,255,255,255,2,0,0,0,1,70,70,70,1,233,233,233,1,184,184,184, + 1,180,180,180,1,148,148,148,1,42,42,42,1,0,0,0,1,195,195,195, + 1,120,120,120,1,80,80,80,1,169,169,169,1,144,144,144,1,0,0,0, + 1,85,85,85,1,200,200,200,1,104,104,104,1,149,149,149,1,210,210,210, + 1,11,11,11,1,0,0,0,2,255,255,255,2,0,0,0,1,70,70,70, + 1,177,177,177,1,0,0,0,4,30,30,30,1,227,227,227,1,144,144,144, + 2,148,148,148,1,233,233,233,1,5,5,5,1,85,85,85,1,162,162,162, + 1,0,0,0,2,153,153,153,1,158,158,158,1,0,0,0,2,255,255,255, + 2,0,0,0,1,70,70,70,1,177,177,177,1,0,0,0,4,117,117,117, + 1,132,132,132,1,0,0,0,3,197,197,197,1,78,78,78,1,85,85,85, + 1,162,162,162,1,0,0,0,2,16,16,16,1,234,234,234,1,63,63,63, + 1,0,0,0,1,255,255,255,2,0,0,0,1,70,70,70,1,177,177,177, + 1,0,0,0,4,206,206,206,1,47,47,47,1,0,0,0,3,105,105,105, + 1,173,173,173,1,85,85,85,1,162,162,162,1,0,0,0,3,102,102,102, + 1,207,207,207,1,2,2,2,1,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tsqlresultconnector: record size: integer; data: array[0..1290] of byte end = + (size: 1291; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,115,113, + 108,114,101,115,117,108,116,99,111,110,110,101,99,116,111,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,140,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,144,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,113,200,255, + 25,208,208,208,22,113,200,255,2,208,208,208,22,113,200,255,2,208,208,208, + 22,113,200,255,2,208,208,208,22,113,200,255,2,208,208,208,22,113,200,255, + 2,208,208,208,22,113,200,255,2,208,208,208,3,0,0,0,3,208,208,208, + 5,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,4,113,200,255, + 2,208,208,208,2,0,0,0,5,208,208,208,2,0,0,0,6,208,208,208, + 1,0,0,0,2,208,208,208,4,113,200,255,2,208,208,208,1,0,0,0, + 3,208,208,208,1,0,0,0,7,208,208,208,1,0,0,0,5,208,208,208, + 4,113,200,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0, + 4,208,208,208,4,0,0,0,4,208,208,208,4,113,200,255,2,208,208,208, + 1,0,0,0,2,208,208,208,5,0,0,0,2,208,208,208,4,0,0,0, + 4,208,208,208,4,113,200,255,2,208,208,208,1,0,0,0,2,208,208,208, + 5,0,0,0,2,208,208,208,4,0,0,0,4,208,208,208,4,113,200,255, + 2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208, + 4,0,0,0,4,208,208,208,4,113,200,255,2,208,208,208,1,0,0,0, + 3,208,208,208,1,0,0,0,13,208,208,208,4,113,200,255,2,208,208,208, + 2,0,0,0,5,208,208,208,2,0,0,0,6,208,208,208,1,0,0,0, + 6,113,200,255,2,208,208,208,4,0,0,0,1,208,208,208,6,0,0,0, + 2,208,208,208,9,113,200,255,2,208,208,208,22,113,200,255,2,208,208,208, + 22,113,200,255,2,208,208,208,22,113,200,255,2,208,208,208,22,113,200,255, + 2,208,208,208,22,113,200,255,2,208,208,208,22,113,200,255,25,196,2,0, + 0,255,255,255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,3,2,2,2, + 1,36,36,36,1,1,1,1,1,0,0,0,5,31,31,31,1,19,19,19, + 1,0,0,0,3,7,7,7,1,15,15,15,1,0,0,0,4,255,255,255, + 2,0,0,0,2,105,105,105,1,227,227,227,1,197,197,197,1,218,218,218, + 1,92,92,92,1,0,0,0,2,44,44,44,1,214,214,214,1,224,224,224, + 1,215,215,215,1,194,194,194,1,21,21,21,1,0,0,0,1,83,83,83, + 1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0,1,76,76,76, + 1,214,214,214,1,15,15,15,1,0,0,0,1,25,25,25,1,228,228,228, + 1,28,28,28,1,4,4,4,1,217,217,217,1,91,91,91,1,3,3,3, + 1,0,0,0,1,108,108,108,1,193,193,193,1,2,2,2,1,83,83,83, + 1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0,1,166,166,166, + 1,83,83,83,1,0,0,0,3,51,51,51,1,19,19,19,1,76,76,76, + 1,182,182,182,1,0,0,0,4,209,209,209,1,43,43,43,1,83,83,83, + 1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0,1,216,216,216, + 1,35,35,35,1,0,0,0,5,116,116,116,1,137,137,137,1,0,0,0, + 4,158,158,158,1,95,95,95,1,83,83,83,1,164,164,164,1,0,0,0, + 4,255,255,255,2,0,0,0,1,208,208,208,1,42,42,42,1,0,0,0, + 5,113,113,113,1,132,132,132,1,0,0,0,4,154,154,154,1,92,92,92, + 1,83,83,83,1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0, + 1,160,160,160,1,90,90,90,1,0,0,0,3,125,125,125,1,71,71,71, + 1,62,62,62,1,185,185,185,1,0,0,0,4,209,209,209,1,41,41,41, + 1,83,83,83,1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0, + 1,55,55,55,1,220,220,220,1,25,25,25,1,0,0,0,1,48,48,48, + 1,226,226,226,1,14,14,14,1,5,5,5,1,195,195,195,1,127,127,127, + 1,15,15,15,1,19,19,19,1,140,140,140,1,184,184,184,1,1,1,1, + 1,83,83,83,1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0, + 2,98,98,98,1,212,212,212,1,220,220,220,1,197,197,197,1,72,72,72, + 1,0,0,0,2,21,21,21,1,177,177,177,1,230,230,230,1,234,234,234, + 1,177,177,177,1,14,14,14,1,0,0,0,1,83,83,83,1,253,253,253, + 1,248,248,248,3,58,58,58,1,255,255,255,2,0,0,0,4,12,12,12, + 1,0,0,0,6,7,7,7,1,6,6,6,1,0,0,0,9,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tdblabel: record size: integer; data: array[0..571] of byte end = + (size: 572; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,100,98, + 108,97,98,101,108,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,200,1,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,44,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,208,208,208,145,184,255,255,22,208,208,208,2,184,255, + 255,10,177,245,245,1,171,237,237,1,184,255,255,10,208,208,208,2,184,255, + 255,10,67,93,93,1,13,18,18,1,176,244,244,1,184,255,255,9,208,208, + 208,2,184,255,255,9,173,240,240,1,23,32,32,1,69,96,96,1,111,154, + 154,1,184,255,255,9,208,208,208,2,184,255,255,9,109,151,151,1,71,98, + 98,1,137,190,190,1,36,50,50,1,184,255,255,9,208,208,208,2,184,255, + 255,9,38,52,52,1,138,191,191,1,183,254,254,1,22,31,31,1,146,203, + 203,1,184,255,255,8,208,208,208,2,184,255,255,8,151,209,209,1,9,12, + 12,1,126,174,174,1,126,175,175,1,55,76,76,1,71,99,99,1,184,255, + 255,8,208,208,208,2,184,255,255,8,80,111,111,1,46,64,64,1,80,111, + 111,2,76,106,106,1,8,11,11,1,173,240,240,1,184,255,255,7,208,208, + 208,2,184,255,255,7,180,249,249,1,14,19,19,1,154,214,214,1,184,255, + 255,3,43,60,60,1,106,147,147,1,184,255,255,7,208,208,208,2,184,255, + 255,7,122,169,169,1,36,50,50,1,184,255,255,4,114,158,158,1,32,44, + 44,1,184,255,255,7,208,208,208,2,184,255,255,22,208,208,208,2,184,255, + 255,22,208,208,208,145,100,0,0,0,0,0,0,145,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,145,0,0) + ); + +const + objdata_tdbbarcode: record size: integer; data: array[0..1585] of byte end = + (size: 1586; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,100,98, + 98,97,114,99,111,100,101,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,188,5,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,120,5,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,184,255,255,72,0,0,0,1,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1, + 184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2, + 0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1, + 184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2, + 0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1, + 184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,180,250,250,1,184,255,255,2,182,252,252,1,184,255,255,2, + 0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1,182,252,252,1, + 183,254,254,1,184,255,255,1,182,252,252,1,184,255,255,2,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1, + 163,226,226,1,50,69,69,1,184,255,255,1,116,161,161,1,98,136,136,1, + 105,146,146,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,1, + 173,240,240,1,57,79,79,1,167,231,231,1,138,191,191,1,93,129,129,1, + 89,124,124,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,1,154,214,214,1,89,123,123,1, + 184,255,255,1,82,113,113,1,184,255,255,1,80,111,111,1,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,1,161,223,223,1,100,138,138,1, + 167,231,231,1,84,117,117,1,181,251,251,1,80,111,111,1,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,92,127,127,1,184,255,255,1,94,130,130,1,184,255,255,1, + 84,116,116,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,1, + 184,255,255,1,110,152,152,1,167,231,231,1,95,132,132,1,183,253,253,1, + 84,116,116,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,92,127,127,1,184,255,255,1, + 126,175,175,1,104,144,144,1,110,152,152,1,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,1,184,255,255,1,110,152,152,1,167,231,231,1, + 144,200,200,1,100,139,139,1,95,132,132,1,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,1,184,255,255,8,183,253,253,1,184,255,255,9, + 183,253,253,1,184,255,255,53,12,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,66,0,0) + ); + +const + objdata_tdbstringdisp: record size: integer; data: array[0..828] of byte end = + (size: 829; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 115,116,114,105,110,103,100,105,115,112,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,196,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,124,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,184, + 255,255,22,255,255,255,1,128,128,128,1,184,255,255,8,167,232,232,1,184, + 255,255,13,255,255,255,1,128,128,128,1,184,255,255,8,6,8,8,1,184, + 255,255,13,255,255,255,1,128,128,128,1,184,255,255,8,6,8,8,1,184, + 255,255,13,255,255,255,1,128,128,128,1,184,255,255,1,183,254,254,1,89, + 124,124,1,30,41,41,1,19,26,26,1,51,70,70,1,169,234,234,1,184, + 255,255,1,6,8,8,1,103,143,143,1,30,41,41,1,42,58,58,1,157, + 217,217,1,184,255,255,1,176,244,244,1,64,89,89,1,25,34,34,1,51, + 70,70,1,149,207,207,1,184,255,255,3,255,255,255,1,128,128,128,1,184, + 255,255,1,146,203,203,1,47,65,65,1,180,250,250,1,181,251,251,1,56, + 78,78,1,105,145,145,1,184,255,255,1,6,8,8,1,90,125,125,1,181, + 251,251,1,100,138,138,1,44,61,61,1,184,255,255,1,69,96,96,1,76, + 106,106,1,179,248,248,1,138,191,191,1,51,70,70,1,184,255,255,3,255, + 255,255,1,128,128,128,1,184,255,255,2,167,232,232,1,122,169,169,1,87, + 120,120,1,29,40,40,1,92,128,128,1,184,255,255,1,6,9,9,1,166, + 230,230,1,184,255,255,1,171,237,237,1,4,5,5,1,179,248,248,1,22, + 30,30,1,149,206,206,1,184,255,255,6,255,255,255,1,128,128,128,1,184, + 255,255,1,141,196,196,1,20,28,28,1,89,123,123,1,131,181,181,1,71, + 99,99,1,92,127,127,1,184,255,255,1,8,11,11,1,178,246,246,1,184, + 255,255,1,174,241,241,1,5,7,7,1,178,247,247,1,12,16,16,1,157, + 217,217,1,184,255,255,2,167,232,232,1,184,255,255,3,255,255,255,1,128, + 128,128,1,184,255,255,1,91,126,126,1,81,112,112,1,184,255,255,1,178, + 247,247,1,35,49,49,1,89,123,123,1,184,255,255,1,6,8,8,1,119, + 165,165,1,184,255,255,1,114,158,158,1,40,55,55,1,184,255,255,1,51, + 71,71,1,101,140,140,1,184,255,255,1,154,213,213,1,33,46,46,1,183, + 254,254,1,184,255,255,2,255,255,255,1,128,128,128,1,184,255,255,1,159, + 220,220,1,36,50,50,1,50,69,69,1,44,61,61,1,69,95,95,2,184, + 255,255,1,14,19,19,1,79,109,109,1,38,53,53,1,56,77,77,1,154, + 214,214,1,184,255,255,1,158,219,219,1,63,87,87,1,40,56,56,1,40, + 55,55,1,137,190,190,1,184,255,255,3,255,255,255,1,128,128,128,1,184, + 255,255,3,172,238,238,1,184,255,255,6,178,247,247,1,184,255,255,5,177, + 245,245,1,184,255,255,5,255,255,255,1,128,128,128,1,184,255,255,22,255, + 255,255,25,208,208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255, + 255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbintegerdisp: record size: integer; data: array[0..841] of byte end = + (size: 842; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,98, + 105,110,116,101,103,101,114,100,105,115,112,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,208,2,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,136,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25, + 184,255,255,22,255,255,255,1,128,128,128,1,184,255,255,4,173,240,240,1, + 179,248,248,1,184,255,255,4,176,244,244,1,184,255,255,5,175,242,242,1, + 184,255,255,5,255,255,255,1,128,128,128,1,184,255,255,3,171,237,237,1, + 25,34,34,1,144,199,199,1,184,255,255,2,131,182,182,1,40,55,55,1, + 35,49,49,1,47,65,65,1,149,206,206,1,184,255,255,1,165,229,229,1, + 48,66,66,1,40,56,56,1,29,40,40,1,144,200,200,1,184,255,255,3, + 255,255,255,1,128,128,128,1,184,255,255,2,135,187,187,1,27,37,37,1, + 9,13,13,1,144,199,199,1,184,255,255,1,183,253,253,1,27,38,38,1, + 154,213,213,1,184,255,255,1,121,167,167,1,55,76,76,1,184,255,255,1, + 72,100,100,1,104,144,144,1,184,255,255,1,131,182,182,1,38,52,52,1, + 184,255,255,3,255,255,255,1,128,128,128,1,184,255,255,2,84,117,117,1, + 144,199,199,1,40,55,55,1,144,199,199,1,184,255,255,1,179,248,248,1, + 139,192,192,1,184,255,255,2,144,199,199,1,22,30,30,1,184,255,255,1, + 176,244,244,1,180,249,249,1,184,255,255,1,118,164,164,1,38,53,53,1, + 184,255,255,3,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1, + 144,199,199,1,184,255,255,4,179,248,248,1,50,69,69,1,97,134,134,1, + 184,255,255,3,50,69,69,1,6,9,9,1,148,205,205,1,184,255,255,3, + 255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144,199,199,1, + 184,255,255,3,176,244,244,1,48,67,67,1,70,97,97,1,183,253,253,1, + 184,255,255,3,162,224,224,1,112,155,155,1,19,27,27,1,177,245,245,1, + 184,255,255,2,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1, + 144,199,199,1,184,255,255,2,173,240,240,1,42,58,58,1,83,115,115,1, + 183,254,254,1,184,255,255,2,152,211,211,1,180,249,249,1,184,255,255,2, + 33,46,46,1,137,190,190,1,184,255,255,2,255,255,255,1,128,128,128,1, + 184,255,255,4,40,55,55,1,144,199,199,1,184,255,255,2,45,63,63,1, + 100,138,138,1,184,255,255,4,64,89,89,1,111,154,154,1,184,255,255,1, + 162,225,225,1,17,24,24,1,178,246,246,1,184,255,255,2,255,255,255,1, + 128,128,128,1,184,255,255,4,40,55,55,1,144,199,199,1,184,255,255,1, + 136,189,189,1,0,0,0,1,5,7,7,3,11,15,15,1,184,255,255,1, + 158,219,219,1,48,67,67,1,40,56,56,2,123,171,171,1,184,255,255,3, + 255,255,255,1,128,128,128,1,184,255,255,16,172,239,239,1,184,255,255,5, + 255,255,255,1,128,128,128,1,184,255,255,22,255,255,255,25,208,208,208,120, + 16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120, + 0,0) + ); + +const + objdata_tdbbooleandisp: record size: integer; data: array[0..725] of byte end = + (size: 726; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,98, + 98,111,111,108,101,97,110,100,105,115,112,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,92,2,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,20,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25, + 184,255,255,22,255,255,255,1,128,128,128,1,184,255,255,1,171,237,237,1, + 167,231,231,5,173,240,240,1,184,255,255,2,154,214,214,1,183,253,253,1, + 167,232,232,1,167,231,231,4,177,245,245,1,184,255,255,4,255,255,255,1, + 128,128,128,1,184,255,255,1,63,87,87,1,22,31,31,1,21,29,29,1, + 0,0,0,1,22,31,31,2,78,108,108,1,184,255,255,1,183,254,254,1, + 40,56,56,1,184,255,255,1,2,3,3,1,21,29,29,1,22,31,31,3, + 111,154,154,1,184,255,255,4,255,255,255,1,128,128,128,1,184,255,255,3, + 172,239,239,1,0,0,0,1,184,255,255,4,149,206,206,1,74,103,103,1, + 184,255,255,1,2,3,3,1,170,236,236,1,184,255,255,8,255,255,255,1, + 128,128,128,1,184,255,255,3,172,239,239,1,0,0,0,1,184,255,255,4, + 97,134,134,1,126,174,174,1,184,255,255,1,2,3,3,1,170,236,236,1, + 184,255,255,8,255,255,255,1,128,128,128,1,184,255,255,3,172,239,239,1, + 0,0,0,1,184,255,255,4,48,67,67,1,174,241,241,1,184,255,255,1, + 2,3,3,1,63,88,88,1,69,95,95,2,85,118,118,1,184,255,255,5, + 255,255,255,1,128,128,128,1,184,255,255,3,172,239,239,1,0,0,0,1, + 184,255,255,3,174,241,241,1,47,65,65,1,184,255,255,2,2,3,3,1, + 112,155,155,1,121,167,167,2,130,180,180,1,184,255,255,5,255,255,255,1, + 128,128,128,1,184,255,255,3,172,239,239,1,0,0,0,1,184,255,255,3, + 126,174,174,1,95,131,131,1,184,255,255,2,2,3,3,1,170,236,236,1, + 184,255,255,8,255,255,255,1,128,128,128,1,184,255,255,3,172,239,239,1, + 0,0,0,1,184,255,255,3,74,102,102,1,146,202,202,1,184,255,255,2, + 2,3,3,1,170,236,236,1,184,255,255,8,255,255,255,1,128,128,128,1, + 184,255,255,3,172,239,239,1,0,0,0,1,184,255,255,3,37,51,51,1, + 183,253,253,1,184,255,255,2,2,3,3,1,170,236,236,1,184,255,255,8, + 255,255,255,1,128,128,128,1,184,255,255,7,183,254,254,1,167,231,231,1, + 184,255,255,13,255,255,255,1,128,128,128,1,184,255,255,22,255,255,255,25, + 208,208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81, + 0,0,0,120,0,0) + ); + +const + objdata_tdbrealdisp: record size: integer; data: array[0..786] of byte end = + (size: 787; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,98, + 114,101,97,108,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,156,2,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,84,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,184,255,255, + 22,255,255,255,1,128,128,128,1,184,255,255,4,173,240,240,1,179,248,248, + 1,184,255,255,7,176,244,244,1,184,255,255,6,168,233,233,1,184,255,255, + 1,255,255,255,1,128,128,128,1,184,255,255,3,171,237,237,1,25,34,34, + 1,144,199,199,1,184,255,255,5,146,203,203,1,45,63,63,1,36,50,50, + 1,40,56,56,1,134,186,186,1,184,255,255,3,137,190,190,1,18,25,25, + 1,184,255,255,1,255,255,255,1,128,128,128,1,184,255,255,2,135,187,187, + 1,27,37,37,1,9,13,13,1,144,199,199,1,184,255,255,5,50,69,69, + 1,130,180,180,1,184,255,255,1,144,200,200,1,31,43,43,1,184,255,255, + 1,183,253,253,1,98,136,136,1,19,26,26,1,15,21,21,1,184,255,255, + 1,255,255,255,1,128,128,128,1,184,255,255,2,84,117,117,1,144,199,199, + 1,40,55,55,1,144,199,199,1,184,255,255,5,135,187,187,1,183,253,253, + 1,184,255,255,1,166,230,230,1,6,8,8,1,178,247,247,1,171,237,237, + 1,74,102,102,1,153,212,212,1,15,21,21,1,184,255,255,1,255,255,255, + 1,128,128,128,1,184,255,255,4,40,55,55,1,144,199,199,1,184,255,255, + 7,183,254,254,1,69,96,96,1,72,100,100,1,184,255,255,3,169,234,234, + 1,15,21,21,1,184,255,255,1,255,255,255,1,128,128,128,1,184,255,255, + 4,40,55,55,1,144,199,199,1,184,255,255,6,182,252,252,1,67,93,93, + 1,51,71,71,1,177,245,245,1,184,255,255,3,169,234,234,1,15,21,21, + 1,184,255,255,1,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55, + 1,144,199,199,1,184,255,255,5,180,249,249,1,59,82,82,1,63,87,87, + 1,180,249,249,1,184,255,255,4,169,234,234,1,15,21,21,1,184,255,255, + 1,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144,199,199, + 1,184,255,255,2,169,234,234,1,174,241,241,1,184,255,255,1,69,96,96, + 1,76,106,106,1,183,254,254,1,184,255,255,5,169,234,234,1,15,21,21, + 1,184,255,255,1,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55, + 1,144,199,199,1,184,255,255,2,58,80,80,1,103,143,143,1,159,221,221, + 1,0,0,0,1,4,6,6,1,5,7,7,3,166,230,230,1,184,255,255, + 2,169,234,234,1,15,21,21,1,184,255,255,1,255,255,255,1,128,128,128, + 1,184,255,255,22,255,255,255,1,128,128,128,1,184,255,255,22,255,255,255, + 25,208,208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tdbdatetimedisp: record size: integer; data: array[0..762] of byte end = + (size: 763; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 100,97,116,101,116,105,109,101,100,105,115,112,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,128,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,56,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128, + 25,184,255,255,22,255,255,255,1,128,128,128,1,184,255,255,1,182,252,252, + 1,167,231,231,2,168,233,233,1,180,249,249,1,184,255,255,6,176,244,244, + 1,167,231,231,5,168,233,233,1,184,255,255,3,255,255,255,1,128,128,128, + 1,184,255,255,1,161,223,223,1,1,1,1,1,22,31,31,1,21,29,29, + 1,6,8,8,1,43,60,60,1,152,211,211,1,184,255,255,4,110,152,152, + 1,22,31,31,2,5,7,7,1,16,22,22,1,22,31,31,1,32,44,44, + 1,184,255,255,3,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223, + 1,11,15,15,1,184,255,255,3,97,135,135,1,29,40,40,1,178,247,247, + 1,184,255,255,6,41,57,57,1,131,182,182,1,184,255,255,5,255,255,255, + 1,128,128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255, + 4,26,36,36,1,127,176,176,1,184,255,255,1,58,80,80,1,136,188,188, + 1,184,255,255,3,41,57,57,1,131,182,182,1,184,255,255,5,255,255,255, + 1,128,128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255, + 4,64,89,89,1,95,131,131,1,184,255,255,1,142,197,197,1,168,233,233, + 1,184,255,255,3,41,57,57,1,131,182,182,1,184,255,255,5,255,255,255, + 1,128,128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255, + 4,65,90,90,1,95,132,132,1,184,255,255,6,41,57,57,1,131,182,182, + 1,184,255,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223, + 1,11,15,15,1,184,255,255,3,183,254,254,1,30,41,41,1,126,174,174, + 1,184,255,255,6,41,57,57,1,131,182,182,1,184,255,255,5,255,255,255, + 1,128,128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255, + 2,174,241,241,1,91,126,126,1,27,38,38,1,181,251,251,1,184,255,255, + 1,166,230,230,1,177,245,245,1,184,255,255,3,41,57,57,1,131,182,182, + 1,184,255,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223, + 1,0,0,0,1,5,7,7,2,12,17,17,1,56,77,77,1,162,224,224, + 1,184,255,255,2,35,48,48,1,126,175,175,1,184,255,255,3,41,57,57, + 1,131,182,182,1,184,255,255,5,255,255,255,1,128,128,128,1,184,255,255, + 22,255,255,255,1,128,128,128,1,184,255,255,22,255,255,255,25,208,208,208, + 120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0, + 120,0,0) + ); + +const + objdata_tdbstringdisplb: record size: integer; data: array[0..898] of byte end = + (size: 899; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 115,116,114,105,110,103,100,105,115,112,108,98,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,8,3,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,192,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128, + 25,184,255,255,20,187,245,255,1,197,216,255,1,255,255,255,1,128,128,128, + 1,184,255,255,8,167,232,232,1,184,255,255,9,186,248,255,1,195,221,255, + 1,201,201,255,2,255,255,255,1,128,128,128,1,184,255,255,8,6,8,8, + 1,184,255,255,7,185,251,255,1,194,226,255,1,200,202,255,1,201,201,255, + 3,255,255,255,1,128,128,128,1,184,255,255,8,6,8,8,1,184,255,255, + 5,185,254,255,1,191,230,255,1,200,205,255,1,201,201,255,5,255,255,255, + 1,128,128,128,1,184,255,255,1,183,254,254,1,89,124,124,1,30,41,41, + 1,19,26,26,1,51,70,70,1,169,234,234,1,184,255,255,1,6,8,8, + 1,103,143,143,1,30,41,41,1,42,58,58,1,157,217,217,1,190,235,255, + 1,190,199,244,1,70,70,89,1,27,27,34,1,55,55,70,1,163,163,207, + 1,201,201,255,3,255,255,255,1,128,128,128,1,184,255,255,1,146,203,203, + 1,47,65,65,1,180,250,250,1,181,251,251,1,56,78,78,1,105,145,145, + 1,184,255,255,1,6,8,8,1,90,125,125,1,181,251,251,1,102,130,138, + 1,47,50,61,1,201,201,255,1,76,76,96,1,84,84,106,1,195,195,248, + 1,151,151,191,1,55,55,70,1,201,201,255,3,255,255,255,1,128,128,128, + 1,184,255,255,2,167,232,232,1,122,169,169,1,87,120,120,1,29,40,40, + 1,92,128,128,1,184,255,255,1,6,9,9,1,169,221,230,1,197,216,255, + 1,187,187,237,1,4,4,5,1,195,195,248,1,24,24,30,1,162,162,206, + 1,201,201,255,6,255,255,255,1,128,128,128,1,184,255,255,1,141,196,196, + 1,20,28,28,1,89,123,123,1,131,181,181,1,71,99,99,1,92,127,127, + 1,186,248,255,1,8,10,11,1,194,194,246,1,201,201,255,1,190,190,241, + 1,6,6,7,1,195,195,247,1,13,13,16,1,171,171,217,1,201,201,255, + 2,183,183,232,1,201,201,255,3,255,255,255,1,128,128,128,1,184,255,255, + 1,91,126,126,1,81,112,112,1,184,255,255,1,178,247,247,1,36,48,49, + 1,94,109,123,1,200,202,255,1,6,6,8,1,130,130,165,1,201,201,255, + 1,125,125,158,1,43,43,55,1,201,201,255,1,56,56,71,1,110,110,140, + 1,201,201,255,1,168,168,213,1,36,36,46,1,200,200,254,1,201,201,255, + 2,255,255,255,1,128,128,128,1,184,255,255,1,159,220,220,1,36,50,50, + 1,50,69,69,1,46,55,61,1,75,76,95,1,75,75,95,1,201,201,255, + 1,15,15,19,1,86,86,109,1,42,42,53,1,61,61,77,1,169,169,214, + 1,201,201,255,1,173,173,219,1,69,69,87,1,44,44,56,1,43,43,55, + 1,150,150,190,1,201,201,255,3,255,255,255,1,128,128,128,1,184,255,255, + 2,190,235,255,1,186,194,238,1,201,201,255,6,195,195,247,1,201,201,255, + 5,193,193,245,1,201,201,255,5,255,255,255,1,128,128,128,1,188,240,255, + 1,198,211,255,1,201,201,255,20,255,255,255,25,208,208,208,120,16,0,0, + 0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbintegerdisplb: record size: integer; data: array[0..895] of byte end = + (size: 896; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,100,98, + 105,110,116,101,103,101,114,100,105,115,112,108,98,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,4,3, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,188,2, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128, + 128,25,184,255,255,20,187,245,255,1,197,216,255,1,255,255,255,1,128,128, + 128,1,184,255,255,4,173,240,240,1,179,248,248,1,184,255,255,4,176,244, + 244,1,184,255,255,5,175,242,242,1,184,255,255,1,186,248,255,1,195,221, + 255,1,201,201,255,2,255,255,255,1,128,128,128,1,184,255,255,3,171,237, + 237,1,25,34,34,1,144,199,199,1,184,255,255,2,131,182,182,1,40,55, + 55,1,35,49,49,1,47,65,65,1,149,206,206,1,184,255,255,1,165,229, + 229,1,48,66,66,1,41,55,56,1,30,35,40,1,157,158,200,1,201,201, + 255,3,255,255,255,1,128,128,128,1,184,255,255,2,135,187,187,1,27,37, + 37,1,9,13,13,1,144,199,199,1,184,255,255,1,183,253,253,1,27,38, + 38,1,154,213,213,1,184,255,255,1,121,167,167,1,55,76,76,1,184,255, + 255,1,73,100,100,1,108,130,144,1,200,205,255,1,143,143,182,1,41,41, + 52,1,201,201,255,3,255,255,255,1,128,128,128,1,184,255,255,2,84,117, + 117,1,144,199,199,1,40,55,55,1,144,199,199,1,184,255,255,1,179,248, + 248,1,139,192,192,1,184,255,255,2,144,199,199,1,22,30,30,1,190,235, + 255,1,190,199,244,1,196,196,249,1,201,201,255,1,129,129,164,1,42,42, + 53,1,201,201,255,3,255,255,255,1,128,128,128,1,184,255,255,4,40,55, + 55,1,144,199,199,1,184,255,255,4,179,248,248,1,51,65,69,1,104,111, + 134,1,201,201,255,3,54,54,69,1,7,7,9,1,162,162,205,1,201,201, + 255,3,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144,199, + 199,1,184,255,255,3,179,234,244,1,52,57,67,1,76,76,97,1,199,199, + 253,1,201,201,255,3,177,177,224,1,122,122,155,1,21,21,27,1,193,193, + 245,1,201,201,255,2,255,255,255,1,128,128,128,1,184,255,255,4,40,55, + 55,1,144,199,199,1,184,255,255,1,186,248,255,1,184,208,240,1,46,46, + 58,1,91,91,115,1,200,200,254,1,201,201,255,2,166,166,211,1,196,196, + 249,1,201,201,255,2,36,36,46,1,150,150,190,1,201,201,255,2,255,255, + 255,1,128,128,128,1,184,255,255,4,40,55,55,1,144,196,199,1,194,226, + 255,1,200,202,255,1,50,50,63,1,109,109,138,1,201,201,255,4,70,70, + 89,1,121,121,154,1,201,201,255,1,177,177,225,1,19,19,24,1,194,194, + 246,1,201,201,255,2,255,255,255,1,128,128,128,1,184,255,255,3,185,254, + 255,1,41,50,55,1,156,160,199,1,201,201,255,1,149,149,189,1,0,0, + 0,1,6,6,7,3,12,12,15,1,201,201,255,1,173,173,219,1,53,53, + 67,1,44,44,56,2,135,135,171,1,201,201,255,3,255,255,255,1,128,128, + 128,1,184,255,255,2,190,235,255,1,199,208,255,1,201,201,255,12,188,188, + 239,1,201,201,255,5,255,255,255,1,128,128,128,1,188,240,255,1,198,211, + 255,1,201,201,255,20,255,255,255,25,208,208,208,120,16,0,0,0,0,0, + 0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbrealdisplb: record size: integer; data: array[0..872] of byte end = + (size: 873; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 114,101,97,108,100,105,115,112,108,98,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,168,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,184, + 255,255,20,187,245,255,1,197,216,255,1,255,255,255,1,128,128,128,1,184, + 255,255,4,173,240,240,1,179,248,248,1,184,255,255,7,176,244,244,1,184, + 255,255,4,186,248,255,1,195,221,255,1,184,184,233,1,201,201,255,1,255, + 255,255,1,128,128,128,1,184,255,255,3,171,237,237,1,25,34,34,1,144, + 199,199,1,184,255,255,5,146,203,203,1,45,63,63,1,36,50,50,1,40, + 56,56,1,134,186,186,1,185,251,255,1,194,226,255,1,200,202,255,1,150, + 150,190,1,20,20,25,1,201,201,255,1,255,255,255,1,128,128,128,1,184, + 255,255,2,135,187,187,1,27,37,37,1,9,13,13,1,144,199,199,1,184, + 255,255,5,50,69,69,1,130,180,180,1,184,255,255,1,145,199,200,1,32, + 39,43,1,200,205,255,1,199,199,253,1,107,107,136,1,20,20,26,1,17, + 17,21,1,201,201,255,1,255,255,255,1,128,128,128,1,184,255,255,2,84, + 117,117,1,144,199,199,1,40,55,55,1,144,199,199,1,184,255,255,5,135, + 187,187,1,183,253,253,1,190,235,255,1,179,188,230,1,6,6,8,1,195, + 195,247,1,187,187,237,1,80,80,102,1,167,167,212,1,17,17,21,1,201, + 201,255,1,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144, + 199,199,1,184,255,255,5,188,240,255,1,198,211,255,1,200,200,254,1,76, + 76,96,1,79,79,100,1,201,201,255,3,184,184,234,1,17,17,21,1,201, + 201,255,1,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144, + 199,199,1,184,255,255,3,187,245,255,1,197,216,255,1,201,201,255,1,199, + 199,252,1,73,73,93,1,56,56,71,1,193,193,245,1,201,201,255,3,184, + 184,234,1,17,17,21,1,201,201,255,1,255,255,255,1,128,128,128,1,184, + 255,255,4,40,55,55,1,144,199,199,1,184,255,255,1,186,248,255,1,195, + 221,255,1,201,201,255,2,196,196,249,1,65,65,82,1,69,69,87,1,196, + 196,249,1,201,201,255,4,184,184,234,1,17,17,21,1,201,201,255,1,255, + 255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144,196,199,1,194, + 226,255,1,200,202,255,1,184,184,234,1,190,190,241,1,201,201,255,1,76, + 76,96,1,84,84,106,1,200,200,254,1,201,201,255,5,184,184,234,1,17, + 17,21,1,201,201,255,1,255,255,255,1,128,128,128,1,184,255,255,3,185, + 254,255,1,41,50,55,1,156,160,199,1,201,201,255,2,63,63,80,1,113, + 113,143,1,174,174,221,1,0,0,0,1,5,5,6,1,6,6,7,3,181, + 181,230,1,201,201,255,2,184,184,234,1,17,17,21,1,201,201,255,1,255, + 255,255,1,128,128,128,1,184,255,255,2,190,235,255,1,199,208,255,1,201, + 201,255,18,255,255,255,1,128,128,128,1,188,240,255,1,198,211,255,1,201, + 201,255,20,255,255,255,25,208,208,208,120,16,0,0,0,0,0,0,120,255, + 255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbdatetimedisplb: record size: integer; data: array[0..824] of byte end = + (size: 825; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,98, + 100,97,116,101,116,105,109,101,100,105,115,112,108,98,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188, + 2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,116, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128, + 128,128,25,184,255,255,20,187,245,255,1,197,216,255,1,255,255,255,1,128, + 128,128,1,184,255,255,1,182,252,252,1,167,231,231,2,168,233,233,1,180, + 249,249,1,184,255,255,6,176,244,244,1,167,231,231,5,170,227,233,1,195, + 221,255,1,201,201,255,2,255,255,255,1,128,128,128,1,184,255,255,1,161, + 223,223,1,1,1,1,1,22,31,31,1,21,29,29,1,6,8,8,1,43, + 60,60,1,152,211,211,1,184,255,255,4,110,152,152,1,22,31,31,2,5, + 7,7,1,16,22,22,1,24,27,31,1,35,35,44,1,201,201,255,3,255, + 255,255,1,128,128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184, + 255,255,3,97,135,135,1,29,40,40,1,178,247,247,1,184,255,255,5,185, + 254,255,1,43,51,57,1,143,146,182,1,201,201,255,5,255,255,255,1,128, + 128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255,4,26, + 36,36,1,127,176,176,1,184,255,255,1,58,80,80,1,136,188,188,1,184, + 255,255,1,190,235,255,1,199,208,255,1,45,45,57,1,143,143,182,1,201, + 201,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223,1,11, + 15,15,1,184,255,255,4,64,89,89,1,95,131,131,1,184,255,255,1,142, + 197,197,1,172,219,233,1,198,211,255,1,201,201,255,2,45,45,57,1,143, + 143,182,1,201,201,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161, + 223,223,1,11,15,15,1,184,255,255,4,65,90,90,1,95,132,132,1,187, + 245,255,1,197,216,255,1,201,201,255,4,45,45,57,1,143,143,182,1,201, + 201,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223,1,11, + 15,15,1,184,255,255,3,183,254,254,1,30,40,41,1,133,151,174,1,201, + 201,255,6,45,45,57,1,143,143,182,1,201,201,255,5,255,255,255,1,128, + 128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255,2,175, + 237,241,1,96,112,126,1,30,30,38,1,198,198,251,1,201,201,255,1,181, + 181,230,1,193,193,245,1,201,201,255,3,45,45,57,1,143,143,182,1,201, + 201,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223,1,0, + 0,0,1,5,7,7,1,5,6,7,1,13,14,17,1,61,61,77,1,177, + 177,224,1,201,201,255,2,38,38,48,1,138,138,175,1,201,201,255,3,45, + 45,57,1,143,143,182,1,201,201,255,5,255,255,255,1,128,128,128,1,184, + 255,255,2,190,235,255,1,199,208,255,1,201,201,255,18,255,255,255,1,128, + 128,128,1,188,240,255,1,198,211,255,1,201,201,255,20,255,255,255,25,208, + 208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_tfieldparamlink: record size: integer; data: array[0..1546] of byte end = + (size: 1547; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,102,105, + 101,108,100,112,97,114,97,109,108,105,110,107,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,144,5,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,8,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,12,255,255,255, + 12,184,255,255,1,255,255,255,10,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,7,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,7,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255,3,184,255,255, + 1,255,255,255,12,184,255,255,1,0,0,0,5,255,255,255,1,0,0,0, + 1,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255,1,0,0,0, + 2,255,255,255,4,0,0,0,1,255,255,255,3,184,255,255,1,255,255,255, + 12,184,255,255,1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255, + 3,184,255,255,1,255,255,255,4,2,2,255,4,0,0,255,1,255,255,255, + 3,184,255,255,1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255, + 3,184,255,255,1,255,255,255,4,0,0,255,3,3,3,255,1,2,2,255, + 1,3,3,255,1,255,255,255,2,184,255,255,1,255,255,255,10,184,255,255, + 1,255,255,255,8,4,4,255,1,2,2,255,1,255,255,255,2,184,255,255, + 12,255,255,255,8,0,0,255,1,2,2,255,1,0,0,255,1,255,255,255, + 22,2,2,255,1,0,0,255,1,255,255,255,22,2,2,255,1,0,0,255, + 1,255,255,255,2,0,0,0,5,255,255,255,2,0,0,0,2,255,255,255, + 3,0,0,0,5,255,255,255,1,0,0,255,5,255,255,255,1,0,0,0, + 6,255,255,255,1,0,0,0,3,255,255,255,2,0,0,0,6,255,255,255, + 1,0,0,255,3,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 6,255,255,255,2,0,0,0,1,255,255,255,3,0,0,0,2,255,255,255, + 2,0,0,255,1,255,255,255,3,0,0,0,11,255,255,255,1,0,0,0, + 5,255,255,255,7,0,0,0,5,255,255,255,1,0,0,0,5,255,255,255, + 1,0,0,0,5,255,255,255,7,0,0,0,2,255,255,255,3,0,0,0, + 6,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,3,255,255,255, + 6,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,3,0,0,0, + 3,255,255,255,3,0,0,0,2,255,255,255,101,80,3,0,0,255,255,255, + 12,0,0,0,12,255,255,255,1,0,0,0,10,255,255,255,1,0,0,0, + 12,255,255,255,1,46,46,46,1,184,184,184,4,17,17,17,1,149,149,149, + 1,0,0,0,3,255,255,255,1,0,0,0,12,255,255,255,1,64,64,64, + 1,158,158,158,1,16,16,16,3,1,1,1,1,39,39,39,1,0,0,0, + 3,255,255,255,1,0,0,0,12,255,255,255,1,64,64,64,1,152,152,152, + 1,0,0,0,4,195,195,195,1,0,0,0,3,255,255,255,1,0,0,0, + 12,255,255,255,1,64,64,64,1,230,230,230,1,192,192,192,2,120,120,120, + 1,0,0,0,1,208,208,208,1,0,0,0,3,255,255,255,1,0,0,0, + 12,255,255,255,1,64,64,64,1,152,152,152,1,0,0,0,4,208,208,208, + 1,0,0,0,3,255,255,255,1,0,0,0,12,255,255,255,1,64,64,64, + 1,152,152,152,1,0,0,0,4,208,208,208,1,0,0,0,3,255,255,255, + 1,0,0,0,4,126,126,126,1,242,242,242,1,221,221,221,1,170,170,170, + 1,60,60,60,1,0,0,0,3,255,255,255,1,48,48,48,1,114,114,114, + 1,0,0,0,4,156,156,156,1,0,0,0,3,255,255,255,1,0,0,0, + 4,1,1,1,1,14,14,14,1,40,40,40,1,102,102,102,1,225,225,225, + 1,87,87,87,1,0,0,0,2,255,255,255,1,0,0,0,10,255,255,255, + 1,0,0,0,8,68,68,68,1,205,205,205,1,0,0,0,2,255,255,255, + 12,0,0,0,8,8,8,8,1,248,248,248,1,2,2,2,1,0,0,0, + 22,243,243,243,1,12,12,12,1,0,0,0,22,249,249,249,1,4,4,4, + 1,0,0,0,2,37,37,37,1,120,120,120,2,113,113,113,1,64,64,64, + 1,0,0,0,2,31,31,31,1,103,103,103,1,0,0,0,3,106,106,106, + 1,120,120,120,1,119,119,119,1,100,100,100,1,33,33,33,1,0,0,0, + 1,255,255,255,5,0,0,0,1,80,80,80,1,179,179,179,1,80,80,80, + 1,83,83,83,1,191,191,191,1,87,87,87,1,0,0,0,1,137,137,137, + 1,206,206,206,1,41,41,41,1,0,0,0,2,218,218,218,1,64,64,64, + 2,97,97,97,1,221,221,221,1,15,15,15,1,0,0,0,1,255,255,255, + 3,0,0,0,2,80,80,80,1,144,144,144,1,0,0,0,2,87,87,87, + 1,138,138,138,1,4,4,4,1,202,202,202,1,73,73,73,1,145,145,145, + 1,0,0,0,2,216,216,216,1,0,0,0,3,182,182,182,1,42,42,42, + 1,0,0,0,2,255,255,255,1,0,0,0,3,80,80,80,1,189,189,189, + 1,104,104,104,1,122,122,122,1,202,202,202,1,51,51,51,1,77,77,77, + 1,134,134,134,1,3,3,3,1,214,214,214,1,9,9,9,1,0,0,0, + 1,222,222,222,1,160,160,160,2,177,177,177,1,148,148,148,1,0,0,0, + 7,80,80,80,1,186,186,186,1,96,96,96,1,72,72,72,1,8,8,8, + 1,0,0,0,1,175,175,175,1,191,191,191,1,168,168,168,1,226,226,226, + 1,97,97,97,1,0,0,0,1,217,217,217,1,32,32,32,1,59,59,59, + 1,196,196,196,1,34,34,34,1,0,0,0,7,80,80,80,1,144,144,144, + 1,0,0,0,3,22,22,22,1,197,197,197,1,8,8,8,2,43,43,43, + 1,200,200,200,1,0,0,0,1,216,216,216,1,0,0,0,2,64,64,64, + 1,206,206,206,1,4,4,4,1,0,0,0,6,80,80,80,1,144,144,144, + 1,0,0,0,3,114,114,114,1,113,113,113,1,0,0,0,3,195,195,195, + 1,48,48,48,1,216,216,216,1,0,0,0,3,150,150,150,1,122,122,122, + 1,0,0,0,101,0,0) + ); + +const + objdata_tmsesqlite3dataset: record size: integer; data: array[0..1006] of byte end = + (size: 1007; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,109,115, + 101,115,113,108,105,116,101,51,100,97,116,97,115,101,116,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,184,3,0,0,0,0,0,0,0,0,0, + 0,24,0,0,0,24,0,0,0,132,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,17,152,164,126,3,199,201,193,1,220,220,220, + 1,223,223,223,1,255,255,255,15,152,164,126,3,193,200,178,1,200,206,186, + 1,212,217,201,1,219,223,210,1,238,240,234,1,253,253,252,1,217,218,215, + 1,255,255,255,13,252,252,252,1,228,231,222,1,207,212,195,1,221,224,212, + 1,251,252,251,1,254,254,254,2,152,164,126,2,245,246,242,1,255,255,255, + 13,243,244,240,1,215,220,205,1,201,207,188,1,168,178,146,1,210,215,199, + 1,152,164,126,3,249,250,248,1,254,254,254,1,221,225,213,1,255,255,255, + 11,243,245,241,1,152,164,126,1,239,241,236,1,237,239,233,1,205,211,193, + 1,152,164,126,2,231,234,225,1,233,235,227,1,248,249,246,1,252,252,251, + 1,152,164,126,2,255,255,255,9,254,254,254,1,152,164,126,3,253,253,253, + 1,214,219,204,1,203,208,189,1,235,238,231,1,152,164,126,1,233,236,228, + 1,254,254,254,1,230,233,224,1,152,164,126,2,255,255,255,10,152,164,126, + 1,176,185,156,1,152,164,126,1,249,250,248,1,253,253,253,1,222,226,214, + 1,224,228,217,1,249,249,247,1,250,250,248,1,250,251,249,1,152,164,126, + 2,255,255,255,10,252,252,251,1,240,242,237,1,226,229,219,1,194,201,178, + 1,152,164,126,1,254,254,254,1,224,228,216,1,152,164,126,1,221,225,212, + 1,254,254,254,1,246,247,244,1,152,164,126,1,219,223,210,1,255,255,255, + 10,249,250,248,1,201,207,188,1,212,217,202,1,230,233,224,1,204,210,191, + 1,246,247,244,1,207,212,195,1,152,164,126,1,226,229,219,1,254,254,254, + 1,248,249,247,1,218,222,208,1,222,226,214,1,255,255,255,9,254,254,254, + 1,236,238,231,1,208,213,196,1,152,164,126,1,223,226,215,1,239,241,235, + 1,214,219,204,1,200,206,186,1,152,164,126,1,219,223,210,1,234,236,229, + 1,252,252,251,1,234,236,229,1,152,164,126,3,255,255,255,7,238,240,234, + 1,210,215,199,1,152,164,126,3,245,246,243,1,224,228,217,1,197,203,182, + 1,152,164,126,1,224,227,216,1,245,246,242,1,227,230,220,1,152,164,126, + 3,255,255,255,8,254,254,254,1,152,164,126,2,252,252,251,1,152,164,126, + 1,224,228,217,1,219,223,209,1,192,199,176,1,152,164,126,1,224,228,217, + 1,254,254,254,1,246,247,244,1,205,210,192,1,152,164,126,1,200,206,187, + 1,253,253,252,1,255,255,255,9,219,223,210,1,209,214,197,1,252,252,251, + 1,152,164,126,1,216,220,206,1,189,197,173,1,152,164,126,1,225,228,217, + 1,255,255,255,1,238,240,234,1,205,211,193,1,207,212,195,1,249,249,247, + 1,255,255,255,11,253,253,252,1,227,230,220,1,152,164,126,1,205,210,192, + 1,191,199,175,1,152,164,126,1,224,227,216,1,255,255,255,1,251,251,250, + 1,229,232,223,1,212,217,202,1,152,164,126,2,255,255,255,12,251,251,250, + 1,200,206,186,1,152,164,126,2,219,223,210,1,254,254,254,1,247,247,245, + 1,216,220,206,1,152,164,126,3,255,255,255,13,234,236,229,1,152,164,126, + 1,184,192,166,1,209,214,197,1,254,254,254,1,226,229,219,1,152,164,126, + 2,255,255,255,15,246,247,243,1,210,215,199,1,152,164,126,1,198,204,184, + 1,224,227,216,1,152,164,126,2,227,230,220,1,152,164,126,1,255,255,255, + 14,254,254,254,1,213,218,203,1,152,164,126,1,199,205,185,1,234,236,228, + 1,225,228,218,1,222,226,214,1,152,164,126,3,255,255,255,14,221,225,213, + 1,152,164,126,2,218,222,208,1,255,255,255,19,206,207,203,1,216,221,207, + 1,152,164,126,1,201,207,187,1,255,255,255,20,187,192,178,1,152,164,126, + 2,232,235,227,1,255,255,255,20,182,186,171,1,152,164,126,1,216,220,206, + 1,255,255,255,21,176,182,164,1,211,216,200,1,255,255,255,22,191,191,191, + 1,255,255,255,23,0,0) + ); + +const + objdata_tdbcalendardatetimeedit: record size: integer; data: array[0..1106] of byte end = + (size: 1107; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,23,116,100,98, + 99,97,108,101,110,100,97,114,100,97,116,101,116,105,109,101,101,100,105,116, + 23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99, + 111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116, + 105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111, + 95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,208,3,0,0,0,0,0,0,6,0,0,0,24,0,0, + 0,24,0,0,0,140,3,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,128,128,128,25,184,255,255,1,0,0,0,2,4,5,5,1,126,174,174, + 1,184,255,255,3,0,0,0,5,184,255,255,1,0,0,0,1,169,234,234, + 1,17,23,23,1,255,255,255,6,128,128,128,1,184,255,255,1,0,0,0, + 1,184,255,255,1,126,174,174,1,4,5,5,1,184,255,255,2,0,0,0, + 1,184,255,255,2,0,0,0,1,184,255,255,4,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255, + 5,0,0,0,1,184,255,255,4,0,0,0,1,184,255,255,1,255,255,255, + 1,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255, + 1,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,5,0,0,0, + 1,184,255,255,4,0,0,0,1,184,255,255,1,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,0,0,0,1,184,255,255,1,126,174,174,1,4,5,5, + 1,184,255,255,5,0,0,0,1,184,255,255,2,182,252,252,1,167,231,231, + 1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208,3,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,1,0,0,0,2,4,5,5, + 1,126,174,174,1,184,255,255,2,0,0,0,1,184,255,255,2,0,0,0, + 1,184,255,255,2,161,223,223,1,0,0,0,1,161,223,223,1,0,0,0, + 1,128,128,128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0, + 2,255,255,255,1,179,179,179,2,255,255,255,1,179,179,179,2,255,255,255, + 1,179,179,179,2,255,255,255,1,179,179,179,2,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,2,255,255,255,1,0,0,255,2,255,255,255, + 1,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,2,240,240,240,1,7,7,7,1,23,23,23,1,255,255,255, + 1,7,7,7,2,255,255,255,1,7,7,7,2,255,255,255,1,0,0,255, + 2,255,255,255,1,0,0,0,2,255,255,255,10,247,247,247,1,248,248,248, + 1,255,255,255,1,247,247,247,2,255,255,255,1,247,247,247,2,255,255,255, + 4,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,1,0,0,0, + 2,248,248,248,1,7,7,7,1,15,15,15,1,255,255,255,1,0,0,0, + 2,255,255,255,1,15,15,15,1,7,7,7,1,233,233,233,1,7,7,7, + 1,23,23,23,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0,255, + 2,255,255,255,1,0,0,0,2,255,255,255,4,247,247,247,1,248,248,248, + 1,255,255,255,4,248,248,248,1,247,247,247,1,255,255,255,1,247,247,247, + 1,248,248,248,1,255,255,255,7,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,1,7,7,7,2,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,2,255,255,255,1,15,15,15,1,7,7,7,1,248,248,248, + 1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255,1,0,0,255, + 2,255,255,255,1,0,0,0,2,255,255,255,1,247,247,247,2,255,255,255, + 7,248,248,248,1,247,247,247,1,255,255,255,10,0,0,0,2,255,255,255, + 22,0,0,0,2,255,255,255,1,0,0,0,2,247,247,247,1,0,0,0, + 1,7,7,7,1,240,240,240,1,15,15,15,1,30,30,30,1,255,255,255, + 1,7,7,7,1,0,0,0,1,247,247,247,1,159,159,159,2,255,255,255, + 1,179,179,179,2,255,255,255,1,197,197,197,1,183,183,183,1,242,242,242, + 1,0,0,0,15,10,10,10,2,0,0,0,4,9,9,9,1,11,11,11, + 1,2,2,2,1,0,0,0,1,12,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,66,0,0) + ); + +const + objdata_tsequencelink: record size: integer; data: array[0..1332] of byte end = + (size: 1333; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,101, + 113,117,101,110,99,101,108,105,110,107,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,228,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,1,184,255,255,22,255, + 255,255,2,184,255,255,1,255,255,255,14,0,0,0,1,255,255,255,5,184, + 255,255,1,255,255,255,2,184,255,255,1,255,255,255,3,0,0,0,1,255, + 255,255,1,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1,0, + 0,0,5,255,255,255,3,184,255,255,1,255,255,255,2,184,255,255,1,255, + 255,255,3,0,0,0,1,255,255,255,1,0,0,0,3,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,3,255, + 255,255,2,184,255,255,1,255,255,255,2,184,255,255,1,255,255,255,3,0, + 0,0,1,255,255,255,1,0,0,0,8,255,255,255,7,184,255,255,1,255, + 255,255,2,184,255,255,1,255,255,255,3,0,0,0,1,255,255,255,1,0, + 0,0,8,255,255,255,7,184,255,255,1,255,255,255,2,184,255,255,1,255, + 255,255,3,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,6,255,255,255,2,0,0,0,2,255,255,255,2,184,255,255,1,255, + 255,255,2,184,255,255,1,255,255,255,3,0,0,0,1,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,6,255, + 255,255,2,184,255,255,1,255,255,255,2,184,255,255,1,255,255,255,3,0, + 0,0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,2,255, + 255,255,1,0,0,0,5,255,255,255,3,184,255,255,1,255,255,255,2,184, + 255,255,1,255,255,255,20,184,255,255,1,255,255,255,2,184,255,255,22,255, + 255,255,7,0,0,255,1,255,255,255,10,0,0,255,1,255,255,255,12,0, + 0,255,1,255,255,255,9,0,0,255,3,255,255,255,11,0,0,255,1,255, + 255,255,8,0,0,255,5,255,255,255,10,0,0,255,1,255,255,255,10,0, + 0,255,1,255,255,255,10,0,0,255,5,255,255,255,8,0,0,255,1,255, + 255,255,11,0,0,255,3,255,255,255,9,0,0,255,1,255,255,255,12,0, + 0,255,1,255,255,255,10,0,0,255,1,255,255,255,150,160,2,0,0,0, + 0,0,1,255,255,255,22,0,0,0,2,255,255,255,1,0,0,0,14,3, + 3,3,1,0,0,0,5,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,3,209,209,209,1,0,0,0,1,136,136,136,1,160,160,160,1,0, + 0,0,2,67,67,67,1,134,134,134,1,0,0,0,1,24,24,24,1,179, + 179,179,1,182,182,182,1,186,186,186,1,98,98,98,1,0,0,0,3,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,3,216,216,216,1,0, + 0,0,1,141,141,141,1,225,225,225,1,78,78,78,1,0,0,0,1,69, + 69,69,1,138,138,138,1,0,0,0,1,197,197,197,1,49,49,49,1,0, + 0,0,1,3,3,3,1,190,190,190,1,26,26,26,1,0,0,0,2,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,3,216,216,216,1,0, + 0,0,1,141,141,141,1,89,89,89,1,210,210,210,1,18,18,18,1,69, + 69,69,1,138,138,138,1,27,27,27,1,189,189,189,1,0,0,0,7,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,3,216,216,216,1,0, + 0,0,1,141,141,141,1,66,66,66,1,86,86,86,1,164,164,164,1,69, + 69,69,1,138,138,138,1,53,53,53,1,174,174,174,1,0,0,0,7,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,3,216,216,216,1,0, + 0,0,1,141,141,141,1,66,66,66,1,0,0,0,1,171,171,171,1,149, + 149,149,1,138,138,138,1,9,9,9,1,214,214,214,1,2,2,2,1,0, + 0,0,2,117,117,117,1,46,46,46,1,0,0,0,2,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,3,216,216,216,1,0,0,0,1,141, + 141,141,1,66,66,66,1,0,0,0,1,21,21,21,1,233,233,233,1,138, + 138,138,1,0,0,0,1,123,123,123,1,158,158,158,1,53,53,53,1,102, + 102,102,1,198,198,198,1,2,2,2,1,0,0,0,2,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,3,108,108,108,1,0,0,0,1,70, + 70,70,1,33,33,33,1,0,0,0,2,64,64,64,1,69,69,69,1,0, + 0,0,1,1,1,1,1,75,75,75,1,137,137,137,1,99,99,99,1,17, + 17,17,1,0,0,0,3,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,22,0,0,0,7,255, + 255,255,1,0,0,0,10,255,255,255,1,0,0,0,12,255,255,255,1,0, + 0,0,9,255,255,255,3,0,0,0,11,255,255,255,1,0,0,0,8,255, + 255,255,5,0,0,0,10,255,255,255,1,0,0,0,10,255,255,255,1,0, + 0,0,10,255,255,255,5,0,0,0,8,255,255,255,1,0,0,0,11,255, + 255,255,3,0,0,0,9,255,255,255,1,0,0,0,12,255,255,255,1,0, + 0,0,10,255,255,255,1,0,0,0,150,0,0) + ); + +const + objdata_tdbdatabutton: record size: integer; data: array[0..668] of byte end = + (size: 669; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 100,97,116,97,98,117,116,116,111,110,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,36,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,220,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,224,224,224,25,255, + 255,255,22,0,0,0,1,224,224,224,1,255,255,255,1,208,249,255,20,128, + 128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,208,245,255,20,128, + 128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,201,244,255,4,188, + 228,238,1,23,28,29,1,201,244,255,1,136,165,172,1,17,20,21,1,14, + 17,18,1,117,142,148,1,91,110,115,1,12,14,15,2,101,122,128,1,201, + 244,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,192, + 246,255,4,74,95,98,1,0,0,0,1,192,246,255,1,22,28,29,1,151, + 194,201,1,157,202,209,1,8,10,10,1,192,246,255,2,146,187,194,1,13, + 16,17,1,192,246,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,182,247,255,4,176,239,247,1,0,0,0,1,182,247,255,3,146, + 199,205,1,49,66,68,1,182,247,255,1,117,159,164,1,3,4,4,1,74, + 100,103,1,182,247,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,173,248,255,5,0,0,0,1,173,248,255,2,152,218,224,1,47, + 68,70,1,157,226,232,1,173,248,255,2,145,208,214,1,7,10,10,1,173, + 248,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,164, + 250,255,5,0,0,0,1,164,250,255,1,106,162,165,1,50,75,77,1,151, + 230,235,1,164,250,255,1,21,31,32,1,146,223,227,1,150,229,234,1,15, + 24,24,1,164,250,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,154,251,255,5,0,0,0,1,154,251,255,1,11,19,19,1,0, + 0,0,3,107,174,177,1,11,19,19,1,14,24,24,1,108,176,179,1,154, + 251,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,145, + 252,255,20,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,135, + 254,255,20,128,128,128,1,0,0,0,1,224,224,224,1,128,128,128,22,0, + 0,0,25,255,255,255,120,16,0,0,0,0,0,0,120,255,255,255,255,255, + 255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbdialogstringedit: record size: integer; data: array[0..878] of byte end = + (size: 879; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 100,105,97,108,111,103,115,116,114,105,110,103,101,100,105,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,240,2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,168,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255, + 120,128,128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,13,243,243,243,7,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,183,254,254,1,22,31,31,1,125,173,173, + 1,184,255,255,1,0,0,0,1,37,51,51,1,35,49,49,1,22,31,31, + 1,108,149,149,1,0,0,0,1,184,255,255,1,0,0,0,1,243,243,243, + 1,232,232,232,5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,149,207,207,1,56,78,78,1,70,97,97, + 1,184,255,255,1,0,0,0,1,184,255,255,2,165,228,228,1,8,11,11, + 1,184,255,255,1,0,0,0,1,184,255,255,1,243,243,243,1,226,226,226, + 5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,92,128,128,1,144,199,199,1,38,53,53,1,183,253,253, + 1,0,0,0,1,184,255,255,1,183,254,254,1,136,189,189,1,31,43,43, + 1,184,255,255,1,0,0,0,1,184,255,255,1,243,243,243,1,215,215,215, + 5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,53,74,74,1,183,253,253,1,74,102,102,1,145,201,201, + 1,0,0,0,4,109,151,151,1,184,255,255,1,0,0,0,1,184,255,255, + 1,243,243,243,1,0,0,0,1,204,204,204,1,0,0,0,1,204,204,204, + 1,0,0,0,1,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,162,224,224,1,0,0,0,3,90,125,125,1,0,0,0, + 1,184,255,255,1,183,254,254,1,141,195,195,1,13,18,18,1,184,255,255, + 1,0,0,0,1,184,255,255,1,243,243,243,1,0,0,0,1,194,194,194, + 1,0,0,0,1,194,194,194,1,0,0,0,1,128,128,128,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,105,145,145,1,117,162,162, + 1,184,255,255,1,174,241,241,1,40,55,55,1,0,0,0,1,184,255,255, + 2,164,227,227,1,12,16,16,1,184,255,255,1,0,0,0,1,184,255,255, + 1,243,243,243,1,183,183,183,5,128,128,128,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,51,70,70,1,170,236,236,1,184,255,255, + 2,48,66,66,1,0,0,0,1,37,51,51,1,36,50,50,1,28,39,39, + 1,115,160,160,1,184,255,255,1,0,0,0,1,184,255,255,1,243,243,243, + 1,172,172,172,5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,10,0,0,0,1,184,255,255,1,0,0,0, + 1,243,243,243,1,167,167,167,5,128,128,128,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,13,128,128,128,7,224,224,224, + 1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16,0,0, + 0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbdataimage: record size: integer; data: array[0..1731] of byte end = + (size: 1732; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,100,98, + 100,97,116,97,105,109,97,103,101,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,6,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,160,4,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171,171, + 171,20,128,128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128, + 128,1,144,255,247,20,128,128,128,1,171,171,171,2,128,128,128,1,150,255, + 247,3,129,253,248,1,85,247,249,1,131,253,248,1,149,255,247,14,128,128, + 128,1,171,171,171,2,128,128,128,1,155,255,248,2,62,244,251,1,1,237, + 253,1,25,240,253,1,2,237,253,1,67,245,251,1,155,255,248,13,128,128, + 128,1,171,171,171,2,128,128,128,1,161,255,249,1,140,253,250,1,1,237, + 253,1,139,251,255,1,183,255,255,1,134,250,254,1,2,237,253,1,143,253, + 250,1,161,255,249,12,128,128,128,1,171,171,171,2,128,128,128,1,167,255, + 249,1,95,247,251,1,26,240,253,1,183,255,255,3,20,239,253,1,100,248, + 250,1,167,255,249,12,128,128,128,1,171,171,171,2,128,128,128,1,173,255, + 250,1,151,253,251,1,1,237,253,1,139,251,255,1,183,255,255,1,133,250, + 254,1,3,237,253,1,155,253,251,1,173,255,250,3,172,255,250,9,128,128, + 128,1,171,171,171,2,128,128,128,1,178,255,250,2,74,244,252,1,2,237, + 253,1,21,239,253,1,3,237,253,1,80,245,252,1,178,255,250,13,128,128, + 128,1,171,171,171,2,128,128,128,1,184,255,251,3,163,253,251,1,110,248, + 252,1,166,253,251,1,184,255,251,13,164,241,222,1,128,128,128,1,171,171, + 171,2,128,128,128,1,190,255,252,17,188,253,249,1,85,193,111,1,6,158, + 4,1,128,128,128,1,171,171,171,2,128,128,128,1,196,255,252,13,195,255, + 252,3,156,232,201,1,30,175,36,1,3,190,0,1,3,173,0,1,128,128, + 128,1,171,171,171,2,128,128,128,1,201,255,253,14,185,245,232,1,76,194, + 94,1,6,185,5,1,2,194,0,1,3,188,0,1,3,171,0,1,128,128, + 128,1,171,171,171,2,128,128,128,1,207,255,254,13,108,208,132,1,16,189, + 17,1,2,204,1,1,2,198,0,1,3,192,0,1,3,186,0,1,3,169, + 0,1,128,128,128,1,171,171,171,2,128,128,128,1,213,255,254,12,87,197, + 104,1,1,209,2,1,1,208,1,1,2,202,1,1,2,196,0,1,3,189, + 0,1,3,183,0,1,3,167,0,1,128,128,128,1,171,171,171,2,128,128, + 128,1,246,116,83,1,247,129,93,1,247,134,100,1,247,137,109,1,247,143, + 117,1,247,146,123,1,245,145,122,1,244,137,109,1,243,130,97,1,241,122, + 85,1,240,115,73,1,234,106,60,1,35,154,6,1,1,212,1,1,1,206, + 1,1,2,199,0,1,3,193,0,1,3,187,0,1,4,181,0,1,3,165, + 0,1,128,128,128,1,171,171,171,2,128,128,128,1,254,137,66,1,255,158, + 82,1,255,165,94,1,255,172,107,1,255,179,120,1,255,186,133,1,254,188, + 137,1,251,176,117,1,248,163,96,1,245,151,76,1,242,139,56,1,240,126, + 36,1,201,109,14,1,20,172,2,1,2,203,1,1,2,197,0,1,3,191, + 0,1,3,184,0,1,4,178,0,1,3,163,0,1,128,128,128,1,171,171, + 171,2,128,128,128,1,254,135,63,1,255,156,79,1,255,163,92,1,255,170, + 104,1,255,178,117,1,255,185,130,1,254,191,142,1,252,179,121,1,249,166, + 101,1,246,154,81,1,243,142,60,1,240,129,40,1,237,117,20,1,155,113, + 2,1,9,184,2,1,2,194,0,1,3,188,0,1,4,182,0,1,4,176, + 0,1,3,162,0,1,128,128,128,1,171,171,171,2,128,128,128,1,254,133, + 60,1,255,155,76,1,255,162,89,1,255,169,102,1,255,176,114,1,255,183, + 127,1,255,190,140,1,252,181,126,1,249,169,106,1,246,157,85,1,244,144, + 65,1,241,132,44,1,238,119,24,1,235,107,4,1,115,122,1,1,6,181, + 0,1,3,186,0,1,4,180,0,1,4,173,0,1,3,162,0,1,128,128, + 128,1,171,171,171,2,128,128,128,1,254,132,57,1,255,153,73,1,255,160, + 86,1,255,167,99,1,255,174,112,1,255,182,125,1,255,189,137,1,253,184, + 130,1,250,172,110,1,247,159,90,1,244,147,69,1,241,135,49,1,239,122, + 29,1,236,110,8,1,235,105,0,1,133,117,1,1,13,166,1,1,4,177, + 0,1,4,171,0,1,3,162,0,1,128,128,128,1,171,171,171,2,128,128, + 128,1,254,130,55,1,255,151,70,1,255,159,83,1,255,166,96,1,255,173, + 109,1,255,180,122,1,255,187,134,1,253,187,135,1,251,175,115,1,248,162, + 94,1,245,150,74,1,242,137,53,1,239,125,33,1,236,112,13,1,235,105, + 0,2,161,111,2,1,22,150,2,1,4,171,0,1,3,162,0,1,128,128, + 128,1,171,171,171,2,128,128,128,1,253,109,49,1,254,126,61,1,254,132, + 72,1,254,138,83,1,254,144,94,1,254,150,105,1,254,156,116,1,253,160, + 122,1,251,149,105,1,248,139,88,1,246,128,71,1,244,118,54,1,241,108, + 36,1,239,97,19,1,237,89,5,3,188,94,5,1,33,135,3,1,4,155, + 0,1,128,128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128, + 128,1,171,171,171,20,128,128,128,1,171,171,171,1,116,1,0,0,0,0, + 0,1,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,1,255,255, + 255,24,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,2,255,255,255,20,251,251,251,1,255,255,255,1,0,0,0,2,255,255, + 255,19,233,233,233,1,236,236,236,1,255,255,255,1,0,0,0,2,255,255, + 255,17,252,252,252,1,224,224,224,1,255,255,255,3,0,0,0,2,255,255, + 255,16,235,235,235,1,239,239,239,1,255,255,255,4,0,0,0,2,255,255, + 255,14,252,252,252,1,240,240,240,1,255,255,255,6,0,0,0,2,255,255, + 255,13,234,234,234,1,253,253,253,1,255,255,255,7,0,0,0,2,255,255, + 255,1,238,238,238,1,236,236,236,10,235,235,235,1,225,225,225,1,255,255, + 255,8,0,0,0,2,255,255,255,13,251,251,251,1,239,239,239,1,255,255, + 255,7,0,0,0,2,255,255,255,14,253,253,253,1,249,249,249,1,255,255, + 255,6,0,0,0,2,255,255,255,15,254,254,254,1,252,252,252,1,255,255, + 255,5,0,0,0,2,255,255,255,16,254,254,254,1,248,248,248,1,255,255, + 255,4,0,0,0,2,255,255,255,17,254,254,254,1,244,244,244,1,255,255, + 255,3,0,0,0,2,255,255,255,18,254,254,254,1,243,243,243,1,255,255, + 255,2,0,0,0,1,255,255,255,24,0,0,0,1,255,255,255,1,0,0, + 0,20,255,255,255,1,0,0,0,1,0,0) + ); + +const + objdata_tfieldfieldlink: record size: integer; data: array[0..1470] of byte end = + (size: 1471; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,102,105, + 101,108,100,102,105,101,108,100,108,105,110,107,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,68,5,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,0,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,12,255,255,255, + 12,184,255,255,1,255,255,255,10,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,7,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,7,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255,3,184,255,255, + 1,255,255,255,12,184,255,255,1,0,0,0,5,255,255,255,1,0,0,0, + 1,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255,1,0,0,0, + 2,255,255,255,4,0,0,0,1,255,255,255,3,184,255,255,1,255,255,255, + 12,184,255,255,1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255, + 3,184,255,255,1,255,255,255,4,2,2,255,4,0,0,255,1,255,255,255, + 3,184,255,255,1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255, + 3,184,255,255,1,255,255,255,4,0,0,255,3,3,3,255,1,2,2,255, + 1,3,3,255,1,255,255,255,2,184,255,255,1,255,255,255,10,184,255,255, + 1,255,255,255,8,4,4,255,1,2,2,255,1,255,255,255,2,184,255,255, + 12,255,255,255,8,0,0,255,1,2,2,255,1,0,0,255,1,255,255,255, + 22,2,2,255,1,0,0,255,1,255,255,255,22,2,2,255,1,0,0,255, + 1,255,255,255,2,0,0,0,8,255,255,255,3,0,0,0,5,255,255,255, + 2,0,0,255,5,255,255,255,1,0,0,0,8,255,255,255,3,0,0,0, + 6,255,255,255,2,0,0,255,3,255,255,255,2,0,0,0,2,255,255,255, + 4,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,3,0,0,255,1,255,255,255,3,0,0,0,5,255,255,255, + 1,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,7,0,0,0,5,255,255,255,1,0,0,0,2,255,255,255, + 3,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,7,0,0,0, + 2,255,255,255,4,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255, + 1,0,0,0,3,255,255,255,7,0,0,0,2,255,255,255,4,0,0,0, + 10,255,255,255,103,12,3,0,0,255,255,255,12,0,0,0,12,255,255,255, + 1,0,0,0,10,255,255,255,1,0,0,0,12,255,255,255,1,46,46,46, + 1,184,184,184,4,17,17,17,1,149,149,149,1,0,0,0,3,255,255,255, + 1,0,0,0,12,255,255,255,1,64,64,64,1,158,158,158,1,16,16,16, + 3,1,1,1,1,39,39,39,1,0,0,0,3,255,255,255,1,0,0,0, + 12,255,255,255,1,64,64,64,1,152,152,152,1,0,0,0,4,195,195,195, + 1,0,0,0,3,255,255,255,1,0,0,0,12,255,255,255,1,64,64,64, + 1,230,230,230,1,192,192,192,2,120,120,120,1,0,0,0,1,208,208,208, + 1,0,0,0,3,255,255,255,1,0,0,0,12,255,255,255,1,64,64,64, + 1,152,152,152,1,0,0,0,4,208,208,208,1,0,0,0,3,255,255,255, + 1,0,0,0,12,255,255,255,1,64,64,64,1,152,152,152,1,0,0,0, + 4,208,208,208,1,0,0,0,3,255,255,255,1,0,0,0,4,126,126,126, + 1,242,242,242,1,221,221,221,1,170,170,170,1,60,60,60,1,0,0,0, + 3,255,255,255,1,48,48,48,1,114,114,114,1,0,0,0,4,156,156,156, + 1,0,0,0,3,255,255,255,1,0,0,0,4,1,1,1,1,14,14,14, + 1,40,40,40,1,102,102,102,1,225,225,225,1,87,87,87,1,0,0,0, + 2,255,255,255,1,0,0,0,10,255,255,255,1,0,0,0,8,68,68,68, + 1,205,205,205,1,0,0,0,2,255,255,255,12,0,0,0,8,8,8,8, + 1,248,248,248,1,2,2,2,1,0,0,0,22,243,243,243,1,12,12,12, + 1,0,0,0,22,249,249,249,1,4,4,4,1,0,0,0,2,30,30,30, + 1,120,120,120,4,11,11,11,1,98,98,98,1,6,6,6,1,0,0,0, + 3,91,91,91,1,120,120,120,1,117,117,117,1,90,90,90,1,9,9,9, + 1,0,0,0,2,255,255,255,5,0,0,0,1,64,64,64,1,184,184,184, + 1,80,80,80,3,7,7,7,1,210,210,210,1,13,13,13,1,0,0,0, + 3,195,195,195,1,99,99,99,1,84,84,84,1,128,128,128,1,206,206,206, + 1,7,7,7,1,0,0,0,2,255,255,255,3,0,0,0,2,64,64,64, + 1,152,152,152,1,0,0,0,4,210,210,210,1,13,13,13,1,0,0,0, + 3,195,195,195,1,28,28,28,1,0,0,0,2,147,147,147,1,95,95,95, + 1,0,0,0,3,255,255,255,1,0,0,0,3,64,64,64,1,223,223,223, + 1,176,176,176,2,110,110,110,1,0,0,0,1,210,210,210,1,13,13,13, + 1,0,0,0,3,195,195,195,1,28,28,28,1,0,0,0,2,91,91,91, + 1,136,136,136,1,0,0,0,7,64,64,64,1,158,158,158,1,16,16,16, + 2,10,10,10,1,0,0,0,1,210,210,210,1,13,13,13,1,0,0,0, + 3,195,195,195,1,28,28,28,1,0,0,0,2,100,100,100,1,124,124,124, + 1,0,0,0,7,64,64,64,1,152,152,152,1,0,0,0,4,210,210,210, + 1,13,13,13,1,0,0,0,3,195,195,195,1,28,28,28,1,0,0,0, + 1,7,7,7,1,197,197,197,1,52,52,52,1,0,0,0,7,64,64,64, + 1,152,152,152,1,0,0,0,4,210,210,210,1,195,195,195,1,192,192,192, + 2,40,40,40,1,195,195,195,1,199,199,199,1,193,193,193,1,199,199,199, + 1,104,104,104,1,0,0,0,103,0,0) + ); + +const + objdata_tdbfilenameedit: record size: integer; data: array[0..742] of byte end = + (size: 743; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 102,105,108,101,110,97,109,101,101,100,105,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,108,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,36,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,0,0,0,4,184,255,255,2,0,0,0,1,184,255,255,2,0,0,0, + 1,184,255,255,6,0,0,0,1,184,255,255,1,0,0,0,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0, + 1,184,255,255,8,0,0,0,1,184,255,255,7,0,0,0,1,184,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,0,0,0,1,184,255,255,5,0,0,0,1,184,255,255,2,0,0,0, + 1,184,255,255,2,134,186,186,1,18,25,25,2,141,195,195,1,184,255,255, + 1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,0,0,0,3,184,255,255,3,0,0,0, + 1,184,255,255,2,0,0,0,1,184,255,255,2,28,39,39,1,140,194,194, + 1,142,197,197,1,36,50,50,1,184,255,255,1,0,0,0,1,184,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,0,0,0,1,184,255,255,5,0,0,0,1,184,255,255,2,0,0,0, + 1,184,255,255,2,2,3,3,1,0,0,0,2,3,4,4,1,184,255,255, + 1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,5,0,0,0, + 1,184,255,255,2,0,0,0,1,184,255,255,2,25,34,34,1,141,195,195, + 1,159,220,220,1,184,255,255,2,0,0,0,1,184,255,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0, + 1,184,255,255,5,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255, + 2,129,179,179,1,17,23,23,1,0,0,0,1,42,58,58,1,184,255,255, + 1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,17,0,0,0,1,184,255,255,1,0,0,0, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255, + 145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0, + 120,0,0) + ); + +const + objdata_tfieldlink: record size: integer; data: array[0..1529] of byte end = + (size: 1530; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,102,105, + 101,108,100,108,105,110,107,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,132,5,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,224,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,97,0,0,0,2,255,255,255,2, + 0,0,0,2,255,255,255,1,0,0,0,2,255,255,255,3,0,0,0,1, + 255,255,255,11,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1, + 0,0,0,3,255,255,255,2,0,0,0,1,255,255,255,11,0,0,0,2, + 255,255,255,2,0,0,0,6,255,255,255,2,0,0,0,1,255,255,255,12, + 0,0,0,4,255,255,255,1,0,0,0,5,255,255,255,1,0,0,0,1, + 255,255,255,2,2,2,255,4,0,0,255,1,255,255,255,5,0,0,0,4, + 255,255,255,1,0,0,0,5,255,255,255,1,0,0,0,1,255,255,255,2, + 0,0,255,3,3,3,255,1,2,2,255,1,3,3,255,1,255,255,255,4, + 0,0,0,10,255,255,255,1,0,0,0,1,255,255,255,6,4,4,255,1, + 2,2,255,1,255,255,255,5,0,0,0,2,255,255,255,1,0,0,0,2, + 255,255,255,3,0,0,0,7,255,255,255,2,0,0,255,1,2,2,255,1, + 0,0,255,1,255,255,255,22,2,2,255,1,0,0,255,1,255,255,255,22, + 2,2,255,1,0,0,255,1,255,255,255,2,0,0,0,8,255,255,255,3, + 0,0,0,4,255,255,255,3,0,0,255,5,255,255,255,1,0,0,0,8, + 255,255,255,3,0,0,0,5,255,255,255,3,0,0,255,3,255,255,255,2, + 0,0,0,2,255,255,255,4,0,0,0,2,255,255,255,3,0,0,0,2, + 255,255,255,2,0,0,0,2,255,255,255,3,0,0,255,1,255,255,255,3, + 0,0,0,5,255,255,255,1,0,0,0,2,255,255,255,3,0,0,0,2, + 255,255,255,2,0,0,0,2,255,255,255,7,0,0,0,5,255,255,255,1, + 0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0,2, + 255,255,255,7,0,0,0,2,255,255,255,4,0,0,0,2,255,255,255,3, + 0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,7,0,0,0,2, + 255,255,255,4,0,0,0,11,255,255,255,7,0,0,0,2,255,255,255,4, + 0,0,0,9,255,255,255,80,108,3,0,0,0,0,0,97,105,105,105,1, + 6,6,6,1,0,0,0,2,2,2,2,1,102,102,102,1,0,0,0,1, + 31,31,31,1,103,103,103,1,0,0,0,3,105,105,105,1,0,0,0,11, + 152,152,152,1,81,81,81,1,0,0,0,2,68,68,68,1,150,150,150,1, + 0,0,0,1,137,137,137,1,206,206,206,1,41,41,41,1,0,0,0,2, + 224,224,224,1,0,0,0,11,53,53,53,1,173,173,173,1,0,0,0,2, + 164,164,164,1,50,50,50,1,4,4,4,1,202,202,202,1,73,73,73,1, + 145,145,145,1,0,0,0,2,224,224,224,1,0,0,0,12,202,202,202,1, + 16,16,16,1,13,13,13,1,196,196,196,1,0,0,0,1,77,77,77,1, + 134,134,134,1,3,3,3,1,214,214,214,1,9,9,9,1,0,0,0,1, + 224,224,224,1,0,0,0,2,126,126,126,1,242,242,242,1,221,221,221,1, + 170,170,170,1,60,60,60,1,0,0,0,5,111,111,111,1,101,101,101,1, + 99,99,99,1,106,106,106,1,0,0,0,1,175,175,175,1,191,191,191,1, + 168,168,168,1,226,226,226,1,97,97,97,1,0,0,0,1,224,224,224,1, + 0,0,0,2,1,1,1,1,14,14,14,1,40,40,40,1,102,102,102,1, + 225,225,225,1,87,87,87,1,0,0,0,4,19,19,19,1,184,184,184,1, + 181,181,181,1,15,15,15,1,22,22,22,1,197,197,197,1,8,8,8,2, + 43,43,43,1,200,200,200,1,0,0,0,1,224,224,224,1,0,0,0,6, + 68,68,68,1,205,205,205,1,0,0,0,5,166,166,166,1,158,158,158,1, + 0,0,0,1,114,114,114,1,113,113,113,1,0,0,0,3,195,195,195,1, + 48,48,48,1,238,238,238,1,192,192,192,3,15,15,15,1,0,0,0,2, + 8,8,8,1,248,248,248,1,2,2,2,1,0,0,0,22,243,243,243,1, + 12,12,12,1,0,0,0,22,249,249,249,1,4,4,4,1,0,0,0,2, + 14,14,14,1,56,56,56,4,5,5,5,1,46,46,46,1,2,2,2,1, + 0,0,0,3,42,42,42,1,56,56,56,1,53,53,53,1,27,27,27,1, + 0,0,0,3,255,255,255,5,0,0,0,1,64,64,64,1,210,210,210,1, + 144,144,144,3,13,13,13,1,210,210,210,1,13,13,13,1,0,0,0,3, + 195,195,195,1,156,156,156,1,148,148,148,1,190,190,190,1,155,155,155,1, + 0,0,0,3,255,255,255,3,0,0,0,2,64,64,64,1,152,152,152,1, + 0,0,0,4,210,210,210,1,13,13,13,1,0,0,0,3,195,195,195,1, + 28,28,28,1,0,0,0,2,175,175,175,1,74,74,74,1,0,0,0,3, + 255,255,255,1,0,0,0,3,64,64,64,1,197,197,197,1,112,112,112,2, + 70,70,70,1,0,0,0,1,210,210,210,1,13,13,13,1,0,0,0,3, + 195,195,195,1,28,28,28,1,0,0,0,2,102,102,102,1,128,128,128,1, + 0,0,0,7,64,64,64,1,184,184,184,1,80,80,80,2,50,50,50,1, + 0,0,0,1,210,210,210,1,13,13,13,1,0,0,0,3,195,195,195,1, + 28,28,28,1,0,0,0,2,92,92,92,1,132,132,132,1,0,0,0,7, + 64,64,64,1,152,152,152,1,0,0,0,4,210,210,210,1,13,13,13,1, + 0,0,0,3,195,195,195,1,28,28,28,1,0,0,0,2,163,163,163,1, + 78,78,78,1,0,0,0,7,64,64,64,1,152,152,152,1,0,0,0,4, + 210,210,210,1,134,134,134,1,128,128,128,2,26,26,26,1,195,195,195,1, + 142,142,142,1,132,132,132,1,176,176,176,1,167,167,167,1,2,2,2,1, + 0,0,0,7,16,16,16,1,38,38,38,1,0,0,0,4,52,52,52,1, + 64,64,64,3,13,13,13,1,48,48,48,1,64,64,64,1,61,61,61,1, + 30,30,30,1,0,0,0,80,0,0) + ); + +const + objdata_ttimestampfieldlink: record size: integer; data: array[0..1490] of byte end = + (size: 1491; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,116,105, + 109,101,115,116,97,109,112,102,105,101,108,100,108,105,110,107,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,84,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,208,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255, + 97,0,0,0,5,255,255,255,4,0,0,0,6,255,255,255,9,0,0,0, + 6,255,255,255,3,0,0,0,6,255,255,255,9,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,11,0,0,0,2,255,255,255,3,0,0,0,4,255,255,255, + 2,0,0,0,2,255,255,255,2,2,2,255,4,0,0,255,1,255,255,255, + 4,0,0,0,2,255,255,255,3,0,0,0,1,255,255,255,5,0,0,0, + 2,255,255,255,2,0,0,255,3,3,3,255,1,2,2,255,1,3,3,255, + 1,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 5,0,0,0,2,255,255,255,6,4,4,255,1,2,2,255,1,255,255,255, + 3,0,0,0,6,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,6,0,0,255,1,2,2,255,1,0,0,255,1,255,255,255, + 22,2,2,255,1,0,0,255,1,255,255,255,22,2,2,255,1,0,0,255, + 1,255,255,255,2,0,0,0,8,255,255,255,3,0,0,0,4,255,255,255, + 3,0,0,255,5,255,255,255,1,0,0,0,8,255,255,255,3,0,0,0, + 5,255,255,255,3,0,0,255,3,255,255,255,2,0,0,0,2,255,255,255, + 4,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,3,0,0,255,1,255,255,255,3,0,0,0,5,255,255,255, + 1,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,7,0,0,0,5,255,255,255,1,0,0,0,2,255,255,255, + 3,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,7,0,0,0, + 2,255,255,255,4,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,7,0,0,0,2,255,255,255,4,0,0,0, + 11,255,255,255,7,0,0,0,2,255,255,255,4,0,0,0,9,255,255,255, + 80,76,3,0,0,0,0,0,97,37,37,37,1,120,120,120,1,119,119,119, + 1,108,108,108,1,43,43,43,1,0,0,0,4,90,90,90,1,120,120,120, + 4,44,44,44,1,0,0,0,9,80,80,80,1,179,179,179,1,80,80,80, + 1,96,96,96,1,205,205,205,1,79,79,79,1,0,0,0,3,60,60,60, + 1,80,80,80,1,190,190,190,1,118,118,118,1,80,80,80,1,29,29,29, + 1,0,0,0,9,80,80,80,1,144,144,144,1,0,0,0,2,31,31,31, + 1,210,210,210,1,0,0,0,1,116,116,116,1,43,43,43,1,0,0,0, + 2,160,160,160,1,55,55,55,1,0,0,0,11,80,80,80,1,144,144,144, + 1,0,0,0,3,225,225,225,1,1,1,1,1,37,37,37,1,13,13,13, + 1,0,0,0,2,160,160,160,1,55,55,55,1,0,0,0,2,126,126,126, + 1,242,242,242,1,221,221,221,1,170,170,170,1,60,60,60,1,0,0,0, + 4,80,80,80,1,144,144,144,1,0,0,0,3,225,225,225,1,0,0,0, + 5,160,160,160,1,55,55,55,1,0,0,0,2,1,1,1,1,14,14,14, + 1,40,40,40,1,102,102,102,1,225,225,225,1,87,87,87,1,0,0,0, + 3,80,80,80,1,144,144,144,1,0,0,0,2,89,89,89,1,167,167,167, + 1,0,0,0,5,160,160,160,1,55,55,55,1,0,0,0,6,68,68,68, + 1,205,205,205,1,0,0,0,3,80,80,80,1,228,228,228,1,192,192,192, + 1,195,195,195,1,175,175,175,1,21,21,21,1,0,0,0,1,153,153,153, + 1,56,56,56,1,0,0,0,2,160,160,160,1,55,55,55,1,0,0,0, + 6,8,8,8,1,248,248,248,1,2,2,2,1,0,0,0,22,243,243,243, + 1,12,12,12,1,0,0,0,22,249,249,249,1,4,4,4,1,0,0,0, + 2,14,14,14,1,56,56,56,4,5,5,5,1,46,46,46,1,2,2,2, + 1,0,0,0,3,42,42,42,1,56,56,56,1,53,53,53,1,27,27,27, + 1,0,0,0,3,255,255,255,5,0,0,0,1,64,64,64,1,210,210,210, + 1,144,144,144,3,13,13,13,1,210,210,210,1,13,13,13,1,0,0,0, + 3,195,195,195,1,156,156,156,1,148,148,148,1,190,190,190,1,155,155,155, + 1,0,0,0,3,255,255,255,3,0,0,0,2,64,64,64,1,152,152,152, + 1,0,0,0,4,210,210,210,1,13,13,13,1,0,0,0,3,195,195,195, + 1,28,28,28,1,0,0,0,2,175,175,175,1,74,74,74,1,0,0,0, + 3,255,255,255,1,0,0,0,3,64,64,64,1,197,197,197,1,112,112,112, + 2,70,70,70,1,0,0,0,1,210,210,210,1,13,13,13,1,0,0,0, + 3,195,195,195,1,28,28,28,1,0,0,0,2,102,102,102,1,128,128,128, + 1,0,0,0,7,64,64,64,1,184,184,184,1,80,80,80,2,50,50,50, + 1,0,0,0,1,210,210,210,1,13,13,13,1,0,0,0,3,195,195,195, + 1,28,28,28,1,0,0,0,2,92,92,92,1,132,132,132,1,0,0,0, + 7,64,64,64,1,152,152,152,1,0,0,0,4,210,210,210,1,13,13,13, + 1,0,0,0,3,195,195,195,1,28,28,28,1,0,0,0,2,163,163,163, + 1,78,78,78,1,0,0,0,7,64,64,64,1,152,152,152,1,0,0,0, + 4,210,210,210,1,134,134,134,1,128,128,128,2,26,26,26,1,195,195,195, + 1,142,142,142,1,132,132,132,1,176,176,176,1,167,167,167,1,2,2,2, + 1,0,0,0,7,16,16,16,1,38,38,38,1,0,0,0,4,52,52,52, + 1,64,64,64,3,13,13,13,1,48,48,48,1,64,64,64,1,61,61,61, + 1,30,30,30,1,0,0,0,80,0,0) + ); + +const + objdata_tdbevent: record size: integer; data: array[0..2487] of byte end = + (size: 2488; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,100,98, + 101,118,101,110,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,68,9,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,0,9,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255, + 255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255, + 255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255, + 255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255, + 255,1,164,240,255,1,165,238,255,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255, + 255,1,163,255,255,1,166,255,255,1,169,255,255,1,140,208,255,1,55,78, + 255,1,87,124,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255, + 255,1,166,255,255,1,105,159,255,1,68,88,255,1,136,137,255,1,99,120, + 255,1,166,235,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255, + 255,1,155,255,255,1,157,255,255,1,160,255,255,1,159,248,255,1,72,110, + 255,1,92,108,255,1,175,175,255,1,102,119,255,1,76,108,255,1,169,240, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255, + 255,1,157,255,255,1,140,223,255,1,60,89,255,1,123,132,255,1,145,153, + 255,1,69,92,255,1,126,184,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,111,181, + 255,1,73,98,255,1,160,163,255,1,99,119,255,1,77,115,255,1,164,243, + 255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,151,253,255,1,80,130,255,1,101,122,255,1,144,154, + 255,1,65,91,255,1,127,195,255,1,169,255,255,1,172,255,255,1,174,255, + 255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,137,235, + 255,1,64,100,255,1,135,149,255,1,98,120,255,1,79,125,255,1,158,247, + 255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255, + 255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,115,200,255,1,74,104,255,1,133,149, + 255,1,64,94,255,1,127,206,255,1,160,255,255,1,163,255,255,1,166,255, + 255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,124,222,255,1,51,72,255,1,103,115,255,1,35,56,255,1,149,245, + 255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255, + 255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,129,225,255,1,58,98,255,1,29,49,255,1,40,66,255,1,118,191, + 255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255, + 255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,116,194,255,1,46,75,255,1,30,48,255,1,63,101, + 255,1,150,234,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255, + 255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,152,255,255,1,154,253,255,1,95,154,255,1,37,59,255,1,35,55, + 255,1,100,154,255,1,168,254,255,1,172,255,255,1,174,255,255,1,177,255, + 255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255, + 255,1,155,255,255,1,157,255,255,1,151,240,255,1,75,118,255,1,32,49, + 255,1,50,76,255,1,141,209,255,1,174,255,255,1,177,255,255,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255, + 255,1,148,241,255,1,154,246,255,1,163,255,255,1,141,217,255,1,57,86, + 255,1,30,45,255,1,89,131,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,87,137, + 255,1,127,200,255,1,163,255,255,1,163,250,255,1,76,114,255,1,53,78, + 255,1,156,228,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,152,255,255,1,136,224,255,1,83,95,255,1,124,183, + 255,1,142,222,255,1,49,75,255,1,111,167,255,1,172,255,255,1,174,255, + 255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,152,255,255,1,95,137,255,1,140,140,255,1,92,125,255,1,68,107, + 255,1,154,236,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255, + 255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,125,205, + 255,1,131,137,255,1,169,169,255,1,98,104,255,1,70,96,255,1,77,119, + 255,1,112,169,255,1,161,239,255,1,174,255,255,1,177,255,255,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,115,148,255,1,171,171, + 255,1,108,108,255,1,49,55,255,1,41,64,255,1,75,115,255,1,111,167, + 255,1,162,240,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,146,255,255,1,109,180,255,1,133,158,255,1,109,153,255,1,107,169, + 255,1,146,233,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255, + 255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,147,252,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255, + 255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255, + 255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255, + 255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255, + 255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,12,0,0,0,255,255,255,255,255,255, + 255,255,255,255,255,66,0,0) + ); + +const + objdata_tsqlite3connection: record size: integer; data: array[0..1006] of byte end = + (size: 1007; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,115,113, + 108,105,116,101,51,99,111,110,110,101,99,116,105,111,110,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,184,3,0,0,0,0,0,0,0,0,0, + 0,24,0,0,0,24,0,0,0,132,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,17,152,164,126,3,199,201,193,1,220,220,220, + 1,223,223,223,1,255,255,255,15,152,164,126,3,193,200,178,1,200,206,186, + 1,212,217,201,1,219,223,210,1,238,240,234,1,253,253,252,1,217,218,215, + 1,255,255,255,13,252,252,252,1,228,231,222,1,207,212,195,1,221,224,212, + 1,251,252,251,1,254,254,254,2,152,164,126,2,245,246,242,1,255,255,255, + 13,243,244,240,1,215,220,205,1,201,207,188,1,168,178,146,1,210,215,199, + 1,152,164,126,3,249,250,248,1,254,254,254,1,221,225,213,1,255,255,255, + 11,243,245,241,1,152,164,126,1,239,241,236,1,237,239,233,1,205,211,193, + 1,152,164,126,2,231,234,225,1,233,235,227,1,248,249,246,1,252,252,251, + 1,152,164,126,2,255,255,255,9,254,254,254,1,152,164,126,3,253,253,253, + 1,214,219,204,1,203,208,189,1,235,238,231,1,152,164,126,1,233,236,228, + 1,254,254,254,1,230,233,224,1,152,164,126,2,255,255,255,10,152,164,126, + 1,176,185,156,1,152,164,126,1,249,250,248,1,253,253,253,1,222,226,214, + 1,224,228,217,1,249,249,247,1,250,250,248,1,250,251,249,1,152,164,126, + 2,255,255,255,10,252,252,251,1,240,242,237,1,226,229,219,1,194,201,178, + 1,152,164,126,1,254,254,254,1,224,228,216,1,152,164,126,1,221,225,212, + 1,254,254,254,1,246,247,244,1,152,164,126,1,219,223,210,1,255,255,255, + 10,249,250,248,1,201,207,188,1,212,217,202,1,230,233,224,1,204,210,191, + 1,246,247,244,1,207,212,195,1,152,164,126,1,226,229,219,1,254,254,254, + 1,248,249,247,1,218,222,208,1,222,226,214,1,255,255,255,9,254,254,254, + 1,236,238,231,1,208,213,196,1,152,164,126,1,223,226,215,1,239,241,235, + 1,214,219,204,1,200,206,186,1,152,164,126,1,219,223,210,1,234,236,229, + 1,252,252,251,1,234,236,229,1,152,164,126,3,255,255,255,7,238,240,234, + 1,210,215,199,1,152,164,126,3,245,246,243,1,224,228,217,1,197,203,182, + 1,152,164,126,1,224,227,216,1,245,246,242,1,227,230,220,1,152,164,126, + 3,255,255,255,8,254,254,254,1,152,164,126,2,252,252,251,1,152,164,126, + 1,224,228,217,1,219,223,209,1,192,199,176,1,152,164,126,1,224,228,217, + 1,254,254,254,1,246,247,244,1,205,210,192,1,152,164,126,1,200,206,187, + 1,253,253,252,1,255,255,255,9,219,223,210,1,209,214,197,1,252,252,251, + 1,152,164,126,1,216,220,206,1,189,197,173,1,152,164,126,1,225,228,217, + 1,255,255,255,1,238,240,234,1,205,211,193,1,207,212,195,1,249,249,247, + 1,255,255,255,11,253,253,252,1,227,230,220,1,152,164,126,1,205,210,192, + 1,191,199,175,1,152,164,126,1,224,227,216,1,255,255,255,1,251,251,250, + 1,229,232,223,1,212,217,202,1,152,164,126,2,255,255,255,12,251,251,250, + 1,200,206,186,1,152,164,126,2,219,223,210,1,254,254,254,1,247,247,245, + 1,216,220,206,1,152,164,126,3,255,255,255,13,234,236,229,1,152,164,126, + 1,184,192,166,1,209,214,197,1,254,254,254,1,226,229,219,1,152,164,126, + 2,255,255,255,15,246,247,243,1,210,215,199,1,152,164,126,1,198,204,184, + 1,224,227,216,1,152,164,126,2,227,230,220,1,152,164,126,1,255,255,255, + 14,254,254,254,1,213,218,203,1,152,164,126,1,199,205,185,1,234,236,228, + 1,225,228,218,1,222,226,214,1,152,164,126,3,255,255,255,14,221,225,213, + 1,152,164,126,2,218,222,208,1,255,255,255,19,206,207,203,1,216,221,207, + 1,152,164,126,1,201,207,187,1,255,255,255,20,187,192,178,1,152,164,126, + 2,232,235,227,1,255,255,255,20,182,186,171,1,152,164,126,1,216,220,206, + 1,255,255,255,21,176,182,164,1,211,216,200,1,255,255,255,22,191,191,191, + 1,255,255,255,23,0,0) + ); + +const + objdata_tdbslider: record size: integer; data: array[0..1108] of byte end = + (size: 1109; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,100,98, + 115,108,105,100,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,224,3,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,152,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,131,255,255,1,255,255,255,1,131, + 255,255,1,240,255,255,1,131,255,255,1,255,255,255,1,131,255,255,1,237, + 255,255,1,134,255,255,1,255,255,255,5,131,255,255,1,248,255,255,1,142, + 255,255,1,244,255,255,1,131,255,255,1,244,255,255,1,225,225,225,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,134,255,255,1,240, + 255,255,1,147,255,255,1,255,255,255,1,131,255,255,1,233,255,255,1,155, + 255,255,1,244,255,255,1,255,255,255,1,227,227,227,3,138,138,138,1,233, + 255,255,1,131,255,255,1,233,255,255,1,148,255,255,1,255,255,255,1,138, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,131, + 255,255,1,255,255,255,1,142,255,255,1,237,255,255,1,142,255,255,1,237, + 255,255,1,151,255,255,1,241,255,255,1,141,255,255,1,255,255,255,1,218, + 218,218,3,129,129,129,1,144,255,255,1,248,255,255,1,141,255,255,1,255, + 255,255,1,131,255,255,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,131,255,255,1,237,255,255,1,148, + 255,255,1,255,255,255,1,138,255,255,1,255,255,255,1,138,255,255,1,255, + 255,255,2,208,208,208,3,128,128,128,1,255,255,255,1,134,255,255,1,255, + 255,255,1,131,255,255,1,248,255,255,1,139,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,131,255,255,1,255,255,255,1,138, + 255,255,1,252,255,255,1,135,255,255,1,244,255,255,1,143,255,255,1,240, + 255,255,1,138,255,255,1,255,255,255,1,199,199,199,3,128,128,128,1,131, + 255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,131,255,255,1,240, + 255,255,1,228,228,228,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,135,255,255,1,252,255,255,1,131,255,255,1,255,255,255,1,131, + 255,255,1,255,255,255,1,138,255,255,1,233,255,255,1,255,255,255,1,190, + 190,190,3,128,128,128,1,237,255,255,1,142,255,255,1,244,255,255,1,143, + 255,255,1,255,255,255,1,131,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,131,255,255,1,255,255,255,1,131,255,255,1,244, + 255,255,1,143,255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,138, + 255,255,1,255,255,255,1,180,180,180,3,128,128,128,1,138,255,255,1,244, + 255,255,1,134,255,255,1,236,255,255,1,150,255,255,1,240,255,255,1,228, + 228,228,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,131, + 255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,131,255,255,1,255, + 255,255,1,131,255,255,1,255,255,255,2,171,171,171,3,128,128,128,1,252, + 255,255,1,142,255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,134, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,131, + 255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,134,255,255,1,255, + 255,255,1,134,255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,167, + 167,167,3,128,128,128,1,131,255,255,1,255,255,255,1,131,255,255,1,255, + 255,255,1,131,255,255,1,244,255,255,1,226,226,226,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,138,255,255,1,237,255,255,1,131, + 255,255,1,240,255,255,1,142,255,255,1,240,255,255,1,142,255,255,1,240, + 255,255,1,131,131,131,1,128,128,128,4,248,255,255,1,134,255,255,1,248, + 255,255,1,134,255,255,1,255,255,255,1,131,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,224,224,224,3,227,227,227,1,224,224,224,5,227, + 227,227,1,224,224,224,5,225,225,225,1,224,224,224,1,225,225,225,1,224, + 224,224,4,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255, + 255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbprogressbar: record size: integer; data: array[0..453] of byte end = + (size: 454; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,98, + 112,114,111,103,114,101,115,115,98,97,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,1,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,4,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,222,209,14, + 184,255,255,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 255,203,183,14,184,255,255,6,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,255,185,157,14,184,255,255,6,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,166,131,14,184,255,255,6,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,255,147,105,14,184,255,255,6, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,128,79,14, + 184,255,255,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 255,110,53,14,184,255,255,6,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,255,91,26,14,184,255,255,6,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,20,224,224,224,1,255,255,255,1, + 128,128,128,1,224,224,224,22,255,255,255,145,16,0,0,0,0,0,0,120, + 255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbcoloredit: record size: integer; data: array[0..899] of byte end = + (size: 900; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,100,98, + 99,111,108,111,114,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,12,3,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,196,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0, + 0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,17,0,0, + 0,1,184,255,255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1,0,255, + 247,1,0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1,143,255, + 0,1,218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1,255,0, + 7,1,255,0,82,1,255,0,156,1,255,0,231,1,198,0,255,1,0,0, + 0,1,39,0,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,0,36,255,1,0,111,255,1,0,187,255,1,0,255,247,1,0,255, + 167,1,0,255,87,1,0,255,7,1,68,255,0,1,143,255,0,1,218,255, + 0,1,255,217,0,1,255,142,0,1,255,67,0,1,255,0,7,1,255,0, + 82,1,255,0,156,1,255,0,231,1,198,0,255,1,0,0,0,1,39,0, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,0,36, + 255,1,0,111,255,1,0,187,255,1,0,255,247,1,0,255,167,1,0,255, + 87,1,0,255,7,1,68,255,0,1,143,255,0,1,218,255,0,1,255,217, + 0,1,255,142,0,1,255,67,0,1,255,0,7,1,255,0,82,1,255,0, + 156,1,255,0,231,1,198,0,255,1,0,0,0,1,39,0,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,0,36,255,1,0,111, + 255,1,0,187,255,1,0,255,247,1,0,255,167,1,0,255,87,1,0,255, + 7,1,68,255,0,1,143,255,0,1,218,255,0,1,255,217,0,1,255,142, + 0,1,255,67,0,1,255,0,7,1,255,0,82,1,255,0,156,1,255,0, + 231,1,198,0,255,1,0,0,0,1,39,0,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,0,36,255,1,0,111,255,1,0,187, + 255,1,0,255,247,1,0,255,167,1,0,255,87,1,0,255,7,1,68,255, + 0,1,143,255,0,1,218,255,0,1,255,217,0,1,255,142,0,1,255,67, + 0,1,255,0,7,1,255,0,82,1,255,0,156,1,255,0,231,1,198,0, + 255,1,0,0,0,1,39,0,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1,0,255, + 247,1,0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1,143,255, + 0,1,218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1,255,0, + 7,1,255,0,82,1,255,0,156,1,255,0,231,1,198,0,255,1,0,0, + 0,1,39,0,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,184,255,255,17,0,0,0,1,184,255,255,1,0,0,0,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20,224,224, + 224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16,0, + 0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tsqlstatement: record size: integer; data: array[0..2472] of byte end = + (size: 2473; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,113, + 108,115,116,97,116,101,109,101,110,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48,9,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,97,155,179,1,20,31,36,1,3,4,5,1,27, + 40,46,1,113,170,193,1,152,225,255,1,155,226,255,1,155,223,250,1,73, + 103,115,1,12,16,18,2,76,103,114,1,169,226,250,1,175,232,255,1,178, + 233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,11, + 18,21,1,103,163,187,1,141,218,249,1,101,155,176,1,18,26,30,1,152, + 225,255,1,155,226,255,1,80,115,129,1,80,114,127,1,157,219,244,1,154, + 212,236,1,89,121,134,1,84,112,124,1,175,232,255,1,178,233,255,1,0, + 0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,25,40,46,1,84, + 132,152,1,136,210,240,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,20,29,33,1,149,211,236,1,164,229,255,1,166,229,255,1,169, + 230,255,1,20,26,29,1,175,232,255,1,178,233,255,1,0,0,0,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,127,203,234,1,69,108,124,1,30, + 47,54,1,33,51,58,1,115,172,196,1,152,225,255,1,155,226,255,1,3, + 4,5,1,160,226,253,1,164,229,255,1,166,229,255,1,168,228,253,1,4, + 5,6,1,175,232,255,1,178,233,255,1,0,0,0,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,123, + 188,214,1,15,23,26,1,152,225,255,1,155,226,255,1,19,28,31,1,148, + 210,235,1,164,229,255,1,130,180,200,1,143,195,216,1,30,41,45,1,175, + 232,255,1,178,233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,16,25,29,1,96,151,174,1,141,219,250,1,117,178,203,1,16, + 24,27,1,152,225,255,1,155,226,255,1,78,112,126,1,79,112,125,1,157, + 219,244,1,48,66,73,1,30,41,46,1,119,160,177,1,175,232,255,1,178, + 233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,103, + 166,191,1,25,39,45,1,3,4,5,1,21,33,37,1,110,165,188,1,152, + 225,255,1,155,226,255,1,155,223,250,1,69,98,110,1,10,13,15,1,13, + 18,20,1,38,52,58,1,42,57,63,1,175,232,255,1,178,233,255,1,0, + 0,0,5,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,135,181,200,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161, + 228,255,1,0,0,0,1,166,229,255,1,169,230,255,1,172,231,255,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149, + 224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,0, + 0,0,1,166,229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178, + 233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,0,0,0,1,166, + 229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,0,0,0,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,0,0,0,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161, + 228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149, + 224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,0, + 0,0,1,166,229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178, + 233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161, + 228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsesqlscript: record size: integer; data: array[0..2472] of byte end = + (size: 2473; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,115,113,108,115,99,114,105,112,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48,9,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,97,155,179,1,20,31,36,1,3,4,5,1,27, + 40,46,1,113,170,193,1,152,225,255,1,155,226,255,1,155,223,250,1,73, + 103,115,1,12,16,18,2,76,103,114,1,169,226,250,1,175,232,255,1,178, + 233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,11, + 18,21,1,103,163,187,1,141,218,249,1,101,155,176,1,18,26,30,1,152, + 225,255,1,155,226,255,1,80,115,129,1,80,114,127,1,157,219,244,1,154, + 212,236,1,89,121,134,1,84,112,124,1,175,232,255,1,178,233,255,1,0, + 0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,25,40,46,1,84, + 132,152,1,136,210,240,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,20,29,33,1,149,211,236,1,164,229,255,1,166,229,255,1,169, + 230,255,1,20,26,29,1,175,232,255,1,178,233,255,1,0,0,0,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,127,203,234,1,69,108,124,1,30, + 47,54,1,33,51,58,1,115,172,196,1,152,225,255,1,155,226,255,1,3, + 4,5,1,160,226,253,1,164,229,255,1,166,229,255,1,168,228,253,1,4, + 5,6,1,175,232,255,1,178,233,255,1,0,0,0,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,123, + 188,214,1,15,23,26,1,152,225,255,1,155,226,255,1,19,28,31,1,148, + 210,235,1,164,229,255,1,130,180,200,1,143,195,216,1,30,41,45,1,175, + 232,255,1,178,233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,16,25,29,1,96,151,174,1,141,219,250,1,117,178,203,1,16, + 24,27,1,152,225,255,1,155,226,255,1,78,112,126,1,79,112,125,1,157, + 219,244,1,48,66,73,1,30,41,46,1,119,160,177,1,175,232,255,1,178, + 233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,103, + 166,191,1,25,39,45,1,3,4,5,1,21,33,37,1,110,165,188,1,152, + 225,255,1,155,226,255,1,155,223,250,1,69,98,110,1,10,13,15,1,13, + 18,20,1,38,52,58,1,42,57,63,1,175,232,255,1,178,233,255,1,0, + 0,0,5,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,135,181,200,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,0,0,0,1,158,227,255,1,161, + 228,255,1,0,0,0,1,166,229,255,1,169,230,255,1,0,0,0,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149, + 224,255,1,152,225,255,1,0,0,0,1,158,227,255,1,161,228,255,1,0, + 0,0,1,166,229,255,1,169,230,255,1,0,0,0,1,175,232,255,1,178, + 233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,0,0,0,1,158,227,255,1,161,228,255,1,0,0,0,1,166, + 229,255,1,169,230,255,1,0,0,0,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,0, + 0,0,1,158,227,255,1,161,228,255,1,0,0,0,1,166,229,255,1,169, + 230,255,1,0,0,0,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,0,0,0,1,158, + 227,255,1,161,228,255,1,0,0,0,1,166,229,255,1,169,230,255,1,0, + 0,0,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161, + 228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149, + 224,255,1,152,225,255,1,0,0,0,1,158,227,255,1,161,228,255,1,0, + 0,0,1,166,229,255,1,169,230,255,1,0,0,0,1,175,232,255,1,178, + 233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161, + 228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tsqlresult: record size: integer; data: array[0..2469] of byte end = + (size: 2470; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,115,113, + 108,114,101,115,117,108,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,48,9,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,132,219,255,1,135,220,255,1,138,221,255,1, + 141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1, + 155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1, + 169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1, + 183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1, + 198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1, + 144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1, + 158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1, + 172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1, + 186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1, + 132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1, + 147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1, + 161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1, + 175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1, + 189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1, + 135,220,255,1,97,155,179,1,20,31,36,1,3,4,5,1,27,40,46,1, + 113,170,193,1,152,225,255,1,155,226,255,1,155,223,250,1,73,103,115,1, + 12,16,18,2,76,103,114,1,169,226,250,1,175,232,255,1,178,233,255,1, + 0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1, + 195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,11,18,21,1, + 103,163,187,1,141,218,249,1,101,155,176,1,18,26,30,1,152,225,255,1, + 155,226,255,1,80,115,129,1,80,114,127,1,157,219,244,1,154,212,236,1, + 89,121,134,1,84,112,124,1,175,232,255,1,178,233,255,1,0,0,0,1, + 183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1, + 198,239,255,1,132,219,255,1,135,220,255,1,25,40,46,1,84,132,152,1, + 136,210,240,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1, + 20,29,33,1,149,211,236,1,164,229,255,1,166,229,255,1,169,230,255,1, + 20,26,29,1,175,232,255,1,178,233,255,1,0,0,0,1,183,234,255,1, + 186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1, + 132,219,255,1,135,220,255,1,127,203,234,1,69,108,124,1,30,47,54,1, + 33,51,58,1,115,172,196,1,152,225,255,1,155,226,255,1,3,4,5,1, + 160,226,253,1,164,229,255,1,166,229,255,1,168,228,253,1,4,5,6,1, + 175,232,255,1,178,233,255,1,0,0,0,1,183,234,255,1,186,235,255,1, + 189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1, + 135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,123,188,214,1, + 15,23,26,1,152,225,255,1,155,226,255,1,19,28,31,1,148,210,235,1, + 164,229,255,1,130,180,200,1,143,195,216,1,30,41,45,1,175,232,255,1, + 178,233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1, + 192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1, + 16,25,29,1,96,151,174,1,141,219,250,1,117,178,203,1,16,24,27,1, + 152,225,255,1,155,226,255,1,78,112,126,1,79,112,125,1,157,219,244,1, + 48,66,73,1,30,41,46,1,119,160,177,1,175,232,255,1,178,233,255,1, + 0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1, + 195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,103,166,191,1, + 25,39,45,1,3,4,5,1,21,33,37,1,110,165,188,1,152,225,255,1, + 155,226,255,1,155,223,250,1,69,98,110,1,10,13,15,1,13,18,20,1, + 38,52,58,1,42,57,63,1,175,232,255,1,178,233,255,1,0,0,0,5, + 195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1, + 141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1, + 155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1, + 169,230,255,1,135,181,200,1,175,232,255,1,178,233,255,1,181,234,255,1, + 183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1, + 198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1, + 144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1, + 158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1, + 172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1, + 186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1, + 132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1, + 147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1, + 161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1, + 175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1, + 189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1, + 135,220,255,1,138,221,255,1,138,217,249,1,142,220,251,1,143,218,248,1, + 147,221,252,1,151,223,253,1,153,223,252,1,132,190,213,1,42,59,66,1, + 6,9,10,1,5,7,8,1,38,52,58,1,134,180,199,1,163,217,238,1, + 175,228,250,1,180,233,254,1,182,233,254,1,185,233,253,1,189,236,255,1, + 192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1, + 138,221,255,1,139,219,251,1,139,216,247,1,140,213,242,1,145,219,249,1, + 152,225,255,1,149,217,245,1,26,37,42,1,90,127,142,1,155,216,241,1, + 158,217,242,1,103,141,156,1,13,18,20,1,167,221,243,1,176,230,252,1, + 177,229,250,1,177,226,246,1,175,221,240,1,188,234,253,1,192,237,255,1, + 195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1, + 141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,151,223,253,1, + 148,215,243,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1, + 109,148,164,1,41,55,61,1,175,232,255,1,178,233,255,1,181,234,255,1, + 183,234,255,1,177,224,243,1,185,231,250,1,192,237,255,1,195,238,255,1, + 198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1, + 144,223,255,1,147,224,255,1,148,223,254,1,151,224,254,1,154,224,253,1, + 158,227,255,1,161,228,255,1,164,229,255,1,89,122,136,1,45,61,68,1, + 161,216,238,1,175,232,255,1,178,233,255,1,181,234,255,1,182,233,254,1, + 179,226,245,1,182,227,245,1,192,237,255,1,195,238,255,1,198,239,255,1, + 132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1, + 147,224,255,1,148,223,254,1,147,218,247,1,155,226,255,1,158,227,255,1, + 161,228,255,1,164,229,255,1,5,7,8,1,159,216,240,1,172,231,255,1, + 175,232,255,1,178,233,255,1,181,234,255,1,177,226,246,1,177,224,243,1, + 189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1, + 135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1, + 149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161,228,255,1, + 164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175,232,255,1, + 178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1, + 192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1, + 138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,147,220,251,1, + 152,225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1, + 0,0,0,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1, + 181,234,255,1,182,232,253,1,186,235,255,1,189,236,255,1,192,237,255,1, + 195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1, + 141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1, + 155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1, + 169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1, + 183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1, + 198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1, + 144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1, + 158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1, + 172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1, + 186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1, + 132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1, + 147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1, + 161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1, + 175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1, + 189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1, + 135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1, + 149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161,228,255,1, + 164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175,232,255,1, + 178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1, + 192,237,255,1,195,238,255,1,198,239,255,1,12,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tsqllookupbuffer: record size: integer; data: array[0..1215] of byte end = + (size: 1216; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,115,113, + 108,108,111,111,107,117,112,98,117,102,102,101,114,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,68,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,36,3, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,255, + 0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0, + 0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255, + 0,2,0,0,0,2,190,190,255,11,190,223,255,11,0,0,0,1,0,255, + 0,1,190,190,255,11,190,223,255,1,0,0,0,3,190,223,255,1,0,0, + 0,5,190,223,255,1,0,255,0,2,190,190,255,11,190,223,255,11,0,255, + 0,1,0,0,0,1,190,190,255,9,0,0,255,1,190,190,255,1,190,223, + 255,1,0,0,0,3,190,223,255,1,0,0,0,2,190,223,255,4,0,0, + 0,2,190,190,255,9,0,0,255,2,190,223,255,11,0,0,0,1,0,255, + 0,1,190,190,255,8,0,0,255,4,0,0,0,3,190,223,255,1,0,0, + 0,3,190,223,255,3,0,255,0,2,190,190,255,7,0,0,255,1,190,190, + 255,1,0,0,255,2,190,223,255,11,0,255,0,1,0,0,0,1,190,190, + 255,7,0,0,255,1,190,190,255,1,0,0,255,1,190,190,255,1,190,223, + 255,1,0,0,0,3,190,223,255,1,0,0,0,4,190,223,255,2,0,0, + 0,2,190,190,255,7,0,0,255,1,190,190,255,3,190,223,255,11,0,0, + 0,1,0,255,0,1,190,190,255,7,0,0,255,1,190,190,255,3,190,223, + 255,1,0,0,0,3,190,223,255,1,0,0,0,2,190,223,255,4,0,255, + 0,2,190,190,255,7,0,0,255,1,190,190,255,3,190,223,255,11,0,255, + 0,1,0,0,0,1,190,190,255,7,0,0,255,1,190,190,255,3,190,223, + 255,11,0,0,0,2,190,190,255,1,0,0,0,3,190,190,255,3,0,0, + 255,1,190,190,255,3,110,148,148,1,46,62,62,1,32,43,43,1,124,167, + 167,1,190,223,255,2,110,148,148,1,46,62,62,1,32,43,43,1,124,167, + 167,1,190,223,255,1,0,0,0,1,0,255,0,1,190,190,255,7,0,0, + 255,1,190,190,255,3,190,223,255,2,177,232,238,1,29,39,39,1,190,223, + 255,4,177,232,238,1,29,39,39,1,190,223,255,1,0,255,0,2,190,190, + 255,1,0,0,0,3,190,190,255,3,0,0,255,1,190,190,255,3,190,223, + 255,2,165,222,222,1,46,62,62,1,190,223,255,4,165,222,222,1,46,62, + 62,1,190,223,255,1,0,255,0,1,0,0,0,1,190,190,255,7,0,0, + 255,1,190,190,255,3,190,223,255,1,163,219,219,1,35,47,47,1,158,212, + 212,1,190,223,255,3,163,219,219,1,35,47,47,1,158,212,212,1,190,223, + 255,1,0,0,0,2,190,190,255,1,0,0,0,3,190,190,255,1,0,0, + 255,2,190,190,255,4,190,223,255,1,57,76,76,1,171,229,229,1,190,223, + 255,4,57,76,76,1,171,229,229,1,190,223,255,2,0,0,0,1,0,255, + 0,1,190,190,255,11,190,223,255,1,71,95,95,1,190,223,255,5,71,95, + 95,1,190,223,255,3,0,255,0,2,190,190,255,1,0,0,0,3,190,190, + 255,7,190,223,255,11,0,255,0,1,0,0,0,1,190,190,255,11,190,223, + 255,1,59,79,79,1,190,223,255,5,59,79,79,1,190,223,255,3,0,0, + 0,2,190,190,255,11,190,223,255,11,0,0,0,1,0,255,0,1,190,190, + 255,11,190,223,255,11,0,255,0,2,0,0,0,2,0,255,0,2,0,0, + 0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255, + 0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,1,232,0, + 0,0,0,0,0,1,255,255,255,2,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,22,0,0, + 0,1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0,1,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,48,0,0, + 0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255, + 255,48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,1,255,255,255,25,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0) + ); + +const + objdata_tmsedatasource: record size: integer; data: array[0..1841] of byte end = + (size: 1842; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,100,97,116,97,115,111,117,114,99,101,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,6,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,116,6,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,26, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,25,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,0,0,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,0,0,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,0,0,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 0,0,255,3,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 0,0,255,3,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 0,0,255,3,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,0,0,255,5,152,255,255,1,155,255,255,1, + 0,0,255,5,172,255,255,1,174,255,255,1,0,0,255,5,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,0,0,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,0,0,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 0,0,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1, + 0,0,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1, + 157,255,255,1,160,255,255,1,0,0,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,0,0,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,0,0,255,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,0,0,255,5, + 172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,0,0,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,0,0,255,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 0,0,255,3,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,0,0,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,0,0,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,0,0,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,0,0,255,5,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,0,0,255,5, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 0,0,255,3,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,0,0,255,3,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,0,0,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,0,0,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66, + 0,0) + ); + +initialization + registerobjectdata(@objdata_tlocaldataset,tbitmapcomp,'tlocaldataset'); + registerobjectdata(@objdata_tmsesqlquery,tbitmapcomp,'tmsesqlquery'); + registerobjectdata(@objdata_tmsesqltransaction,tbitmapcomp,'tmsesqltransaction'); + registerobjectdata(@objdata_tmseibconnection,tbitmapcomp,'tmseibconnection'); + registerobjectdata(@objdata_tfb3connection,tbitmapcomp,'tfb3connection'); + registerobjectdata(@objdata_tfbservice,tbitmapcomp,'tfbservice'); + registerobjectdata(@objdata_tfb3service,tbitmapcomp,'tfb3service'); + registerobjectdata(@objdata_tdatasource,tbitmapcomp,'tdatasource'); + registerobjectdata(@objdata_tdbnavigator,tbitmapcomp,'tdbnavigator'); + registerobjectdata(@objdata_tdbstringedit,tbitmapcomp,'tdbstringedit'); + registerobjectdata(@objdata_tdropdownlisteditdb,tbitmapcomp,'tdropdownlisteditdb'); + registerobjectdata(@objdata_tdropdownlisteditlb,tbitmapcomp,'tdropdownlisteditlb'); + registerobjectdata(@objdata_tdbdropdownlistedit,tbitmapcomp,'tdbdropdownlistedit'); + registerobjectdata(@objdata_tdbdropdownlisteditdb,tbitmapcomp,'tdbdropdownlisteditdb'); + registerobjectdata(@objdata_tdbdropdownlisteditlb,tbitmapcomp,'tdbdropdownlisteditlb'); + registerobjectdata(@objdata_tdbbooleantextedit,tbitmapcomp,'tdbbooleantextedit'); + registerobjectdata(@objdata_tdbmemoedit,tbitmapcomp,'tdbmemoedit'); + registerobjectdata(@objdata_tdbintegeredit,tbitmapcomp,'tdbintegeredit'); + registerobjectdata(@objdata_tdbbooleanedit,tbitmapcomp,'tdbbooleanedit'); + registerobjectdata(@objdata_tdbdataicon,tbitmapcomp,'tdbdataicon'); + registerobjectdata(@objdata_tdbbooleaneditradio,tbitmapcomp,'tdbbooleaneditradio'); + registerobjectdata(@objdata_tdbrealedit,tbitmapcomp,'tdbrealedit'); + registerobjectdata(@objdata_tdbrealspinedit,tbitmapcomp,'tdbrealspinedit'); + registerobjectdata(@objdata_tdbdatetimeedit,tbitmapcomp,'tdbdatetimeedit'); + registerobjectdata(@objdata_tdbenumedit,tbitmapcomp,'tdbenumedit'); + registerobjectdata(@objdata_tdbenumeditdb,tbitmapcomp,'tdbenumeditdb'); + registerobjectdata(@objdata_tdbenum64editdb,tbitmapcomp,'tdbenum64editdb'); + registerobjectdata(@objdata_tdbenumeditlb,tbitmapcomp,'tdbenumeditlb'); + registerobjectdata(@objdata_tdbenum64editlb,tbitmapcomp,'tdbenum64editlb'); + registerobjectdata(@objdata_tdbkeystringedit,tbitmapcomp,'tdbkeystringedit'); + registerobjectdata(@objdata_tdbkeystringeditdb,tbitmapcomp,'tdbkeystringeditdb'); + registerobjectdata(@objdata_tdbkeystringeditlb,tbitmapcomp,'tdbkeystringeditlb'); + registerobjectdata(@objdata_tdbstringlookuplb,tbitmapcomp,'tdbstringlookuplb'); + registerobjectdata(@objdata_tdbstringlookupdb,tbitmapcomp,'tdbstringlookupdb'); + registerobjectdata(@objdata_tdbintegerlookuplb,tbitmapcomp,'tdbintegerlookuplb'); + registerobjectdata(@objdata_tdbintegerlookupdb,tbitmapcomp,'tdbintegerlookupdb'); + registerobjectdata(@objdata_tdbreallookuplb,tbitmapcomp,'tdbreallookuplb'); + registerobjectdata(@objdata_tdbreallookupdb,tbitmapcomp,'tdbreallookupdb'); + registerobjectdata(@objdata_tdbdatetimelookuplb,tbitmapcomp,'tdbdatetimelookuplb'); + registerobjectdata(@objdata_tdbdatetimelookupdb,tbitmapcomp,'tdbdatetimelookupdb'); + registerobjectdata(@objdata_tdbstringlookup64lb,tbitmapcomp,'tdbstringlookup64lb'); + registerobjectdata(@objdata_tdbstringlookup64db,tbitmapcomp,'tdbstringlookup64db'); + registerobjectdata(@objdata_tdbintegerlookup64lb,tbitmapcomp,'tdbintegerlookup64lb'); + registerobjectdata(@objdata_tdbintegerlookup64db,tbitmapcomp,'tdbintegerlookup64db'); + registerobjectdata(@objdata_tdbreallookup64lb,tbitmapcomp,'tdbreallookup64lb'); + registerobjectdata(@objdata_tdbreallookup64db,tbitmapcomp,'tdbreallookup64db'); + registerobjectdata(@objdata_tdbdatetimelookup64lb,tbitmapcomp,'tdbdatetimelookup64lb'); + registerobjectdata(@objdata_tdbdatetimelookup64db,tbitmapcomp,'tdbdatetimelookup64db'); + registerobjectdata(@objdata_tdbstringlookupstrlb,tbitmapcomp,'tdbstringlookupstrlb'); + registerobjectdata(@objdata_tdbstringlookupstrdb,tbitmapcomp,'tdbstringlookupstrdb'); + registerobjectdata(@objdata_tdbintegerlookupstrlb,tbitmapcomp,'tdbintegerlookupstrlb'); + registerobjectdata(@objdata_tdbintegerlookupstrdb,tbitmapcomp,'tdbintegerlookupstrdb'); + registerobjectdata(@objdata_tdbreallookupstrlb,tbitmapcomp,'tdbreallookupstrlb'); + registerobjectdata(@objdata_tdbreallookupstrdb,tbitmapcomp,'tdbreallookupstrdb'); + registerobjectdata(@objdata_tdbdatetimelookupstrlb,tbitmapcomp,'tdbdatetimelookupstrlb'); + registerobjectdata(@objdata_tdbdatetimelookupstrdb,tbitmapcomp,'tdbdatetimelookupstrdb'); + registerobjectdata(@objdata_tdbwidgetgrid,tbitmapcomp,'tdbwidgetgrid'); + registerobjectdata(@objdata_tdbstringgrid,tbitmapcomp,'tdbstringgrid'); + registerobjectdata(@objdata_tlookupbuffer,tbitmapcomp,'tlookupbuffer'); + registerobjectdata(@objdata_tdblookupbuffer,tbitmapcomp,'tdblookupbuffer'); + registerobjectdata(@objdata_tdbmemolookupbuffer,tbitmapcomp,'tdbmemolookupbuffer'); + registerobjectdata(@objdata_tmsedbf,tbitmapcomp,'tmsedbf'); + registerobjectdata(@objdata_tmsefixedformatdataset,tbitmapcomp,'tmsefixedformatdataset'); + registerobjectdata(@objdata_tmsesdfdataset,tbitmapcomp,'tmsesdfdataset'); + registerobjectdata(@objdata_tmsememdataset,tbitmapcomp,'tmsememdataset'); + registerobjectdata(@objdata_tmsepqconnection,tbitmapcomp,'tmsepqconnection'); + registerobjectdata(@objdata_tmseodbcconnection,tbitmapcomp,'tmseodbcconnection'); + registerobjectdata(@objdata_tmsemysqlconnection,tbitmapcomp,'tmsemysqlconnection'); + registerobjectdata(@objdata_tenumeditdb,tbitmapcomp,'tenumeditdb'); + registerobjectdata(@objdata_tenum64editdb,tbitmapcomp,'tenum64editdb'); + registerobjectdata(@objdata_tenumeditlb,tbitmapcomp,'tenumeditlb'); + registerobjectdata(@objdata_tenum64editlb,tbitmapcomp,'tenum64editlb'); + registerobjectdata(@objdata_tkeystringeditdb,tbitmapcomp,'tkeystringeditdb'); + registerobjectdata(@objdata_tkeystringeditlb,tbitmapcomp,'tkeystringeditlb'); + registerobjectdata(@objdata_tmsestringfield,tbitmapcomp,'tmsestringfield'); + registerobjectdata(@objdata_tmselongintfield,tbitmapcomp,'tmselongintfield'); + registerobjectdata(@objdata_tmselargeintfield,tbitmapcomp,'tmselargeintfield'); + registerobjectdata(@objdata_tmsesmallintfield,tbitmapcomp,'tmsesmallintfield'); + registerobjectdata(@objdata_tmsewordfield,tbitmapcomp,'tmsewordfield'); + registerobjectdata(@objdata_tmseautoincfield,tbitmapcomp,'tmseautoincfield'); + registerobjectdata(@objdata_tmsefloatfield,tbitmapcomp,'tmsefloatfield'); + registerobjectdata(@objdata_tmsecurrencyfield,tbitmapcomp,'tmsecurrencyfield'); + registerobjectdata(@objdata_tmsebooleanfield,tbitmapcomp,'tmsebooleanfield'); + registerobjectdata(@objdata_tmsedatetimefield,tbitmapcomp,'tmsedatetimefield'); + registerobjectdata(@objdata_tmsedatefield,tbitmapcomp,'tmsedatefield'); + registerobjectdata(@objdata_tmsetimefield,tbitmapcomp,'tmsetimefield'); + registerobjectdata(@objdata_tmsebinaryfield,tbitmapcomp,'tmsebinaryfield'); + registerobjectdata(@objdata_tmsebytesfield,tbitmapcomp,'tmsebytesfield'); + registerobjectdata(@objdata_tmseguidfield,tbitmapcomp,'tmseguidfield'); + registerobjectdata(@objdata_tmsevarbytesfield,tbitmapcomp,'tmsevarbytesfield'); + registerobjectdata(@objdata_tmsebcdfield,tbitmapcomp,'tmsebcdfield'); + registerobjectdata(@objdata_tmseblobfield,tbitmapcomp,'tmseblobfield'); + registerobjectdata(@objdata_tmsememofield,tbitmapcomp,'tmsememofield'); + registerobjectdata(@objdata_tmsegraphicfield,tbitmapcomp,'tmsegraphicfield'); + registerobjectdata(@objdata_tmsevariantfield,tbitmapcomp,'tmsevariantfield'); + registerobjectdata(@objdata_tparamconnector,tbitmapcomp,'tparamconnector'); + registerobjectdata(@objdata_tsqlresultconnector,tbitmapcomp,'tsqlresultconnector'); + registerobjectdata(@objdata_tdblabel,tbitmapcomp,'tdblabel'); + registerobjectdata(@objdata_tdbbarcode,tbitmapcomp,'tdbbarcode'); + registerobjectdata(@objdata_tdbstringdisp,tbitmapcomp,'tdbstringdisp'); + registerobjectdata(@objdata_tdbintegerdisp,tbitmapcomp,'tdbintegerdisp'); + registerobjectdata(@objdata_tdbbooleandisp,tbitmapcomp,'tdbbooleandisp'); + registerobjectdata(@objdata_tdbrealdisp,tbitmapcomp,'tdbrealdisp'); + registerobjectdata(@objdata_tdbdatetimedisp,tbitmapcomp,'tdbdatetimedisp'); + registerobjectdata(@objdata_tdbstringdisplb,tbitmapcomp,'tdbstringdisplb'); + registerobjectdata(@objdata_tdbintegerdisplb,tbitmapcomp,'tdbintegerdisplb'); + registerobjectdata(@objdata_tdbrealdisplb,tbitmapcomp,'tdbrealdisplb'); + registerobjectdata(@objdata_tdbdatetimedisplb,tbitmapcomp,'tdbdatetimedisplb'); + registerobjectdata(@objdata_tfieldparamlink,tbitmapcomp,'tfieldparamlink'); + registerobjectdata(@objdata_tmsesqlite3dataset,tbitmapcomp,'tmsesqlite3dataset'); + registerobjectdata(@objdata_tdbcalendardatetimeedit,tbitmapcomp,'tdbcalendardatetimeedit'); + registerobjectdata(@objdata_tsequencelink,tbitmapcomp,'tsequencelink'); + registerobjectdata(@objdata_tdbdatabutton,tbitmapcomp,'tdbdatabutton'); + registerobjectdata(@objdata_tdbdialogstringedit,tbitmapcomp,'tdbdialogstringedit'); + registerobjectdata(@objdata_tdbdataimage,tbitmapcomp,'tdbdataimage'); + registerobjectdata(@objdata_tfieldfieldlink,tbitmapcomp,'tfieldfieldlink'); + registerobjectdata(@objdata_tdbfilenameedit,tbitmapcomp,'tdbfilenameedit'); + registerobjectdata(@objdata_tfieldlink,tbitmapcomp,'tfieldlink'); + registerobjectdata(@objdata_ttimestampfieldlink,tbitmapcomp,'ttimestampfieldlink'); + registerobjectdata(@objdata_tdbevent,tbitmapcomp,'tdbevent'); + registerobjectdata(@objdata_tsqlite3connection,tbitmapcomp,'tsqlite3connection'); + registerobjectdata(@objdata_tdbslider,tbitmapcomp,'tdbslider'); + registerobjectdata(@objdata_tdbprogressbar,tbitmapcomp,'tdbprogressbar'); + registerobjectdata(@objdata_tdbcoloredit,tbitmapcomp,'tdbcoloredit'); + registerobjectdata(@objdata_tsqlstatement,tbitmapcomp,'tsqlstatement'); + registerobjectdata(@objdata_tmsesqlscript,tbitmapcomp,'tmsesqlscript'); + registerobjectdata(@objdata_tsqlresult,tbitmapcomp,'tsqlresult'); + registerobjectdata(@objdata_tsqllookupbuffer,tbitmapcomp,'tsqllookupbuffer'); + registerobjectdata(@objdata_tmsedatasource,tbitmapcomp,'tmsedatasource'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdeprecated.pas b/mseide-msegui/lib/common/regcomponents/regdeprecated.pas new file mode 100644 index 0000000..c7937d4 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdeprecated.pas @@ -0,0 +1,43 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regdeprecated; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +implementation +{$ifndef mse_no_db}{$ifdef FPC}{$define hasdb}{$endif}{$endif} +uses + regdeprecated_bmp,msedesignintf,mselistbrowser + {$ifdef hasdb} + ,msemysql40conn,msemysql41conn,msemysql50conn, + msedbf,msesdfdata,msememds + {$endif}; + +procedure Register; +begin + registercomponents('Depr',[tmbdropdownitemedit, //redundant + {$ifdef hasdb} + tmsemysql40connection,tmsemysql41connection,tmsemysql50connection, + tmsedbf,tmsefixedformatdataset,tmsesdfdataset,tmsememdataset + {$endif} + ]); + registercomponenttabhints(['Depr'],['Deprecated components']); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdeprecated_bmp.pas b/mseide-msegui/lib/common/regcomponents/regdeprecated_bmp.pas new file mode 100644 index 0000000..f132c1f --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdeprecated_bmp.pas @@ -0,0 +1,233 @@ +unit regdeprecated_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tmsemysql40connection: record size: integer; data: array[0..1373] of byte end = + (size: 1374; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,109,115, + 101,109,121,115,113,108,52,48,99,111,110,110,101,99,116,105,111,110,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,36,5,0,0,0,0,0,0, + 0,0,0,0,24,0,0,0,24,0,0,0,240,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,35,0,0,0,1,6,5,5,1, + 11,10,9,1,4,4,3,1,7,7,6,1,11,10,9,1,0,0,255,11, + 4,4,3,1,21,18,13,2,21,18,14,1,20,17,13,1,0,0,255,1, + 10,9,7,1,21,19,16,1,147,135,117,1,253,235,207,1,95,88,79,1, + 169,160,147,1,254,242,224,1,79,76,70,1,21,20,19,1,0,0,255,9, + 51,43,31,1,228,194,139,1,251,216,159,1,252,218,165,1,169,148,113,1, + 31,27,21,1,133,118,97,1,253,227,188,1,253,230,193,1,253,232,199,1, + 115,105,91,1,180,168,150,1,253,239,217,1,254,241,223,1,254,244,228,1, + 69,66,62,1,0,0,255,9,60,50,36,1,222,188,134,1,251,215,156,1, + 251,217,162,1,252,219,168,1,252,222,174,1,252,224,180,1,253,227,186,1, + 252,229,192,1,253,231,198,1,254,234,203,1,254,237,209,1,253,239,215,1, + 254,240,220,1,254,243,226,1,69,66,61,1,42,41,39,1,0,0,255,8, + 110,92,63,1,251,212,149,1,252,214,155,1,252,217,161,1,252,219,167,1, + 252,221,172,1,252,223,178,1,252,226,184,1,253,229,190,1,253,231,196,1, + 253,234,201,1,253,236,207,1,254,238,213,1,254,240,219,1,254,243,225,1, + 254,245,230,1,11,10,10,1,0,0,255,6,63,51,34,1,251,206,136,1, + 251,209,142,1,251,211,147,1,251,213,153,1,252,216,159,1,252,218,165,1, + 252,221,170,1,252,223,176,1,213,190,154,1,190,171,143,1,190,173,147,1, + 190,175,151,1,190,177,156,1,190,178,160,1,190,180,164,1,191,182,168,1, + 10,10,9,1,0,0,255,6,63,51,32,1,250,203,128,1,251,206,134,1, + 251,208,140,1,251,210,145,1,251,213,151,1,252,215,157,1,252,217,163,1, + 252,219,169,1,95,83,64,1,0,0,0,7,0,0,255,7,125,98,57,1, + 250,200,120,1,250,203,127,1,251,205,133,1,251,207,138,1,251,209,144,1, + 252,212,150,1,252,214,156,1,252,217,161,1,95,82,61,1,0,0,255,13, + 52,40,22,1,250,194,107,1,250,197,113,1,250,200,119,1,250,202,125,1, + 211,172,111,1,157,130,87,1,204,170,117,1,251,211,148,1,197,167,120,1, + 77,66,48,1,0,0,255,12,34,25,12,1,134,101,50,1,250,191,100,1, + 250,194,106,1,250,196,111,1,211,168,99,1,103,83,51,1,0,0,0,1, + 92,77,52,1,146,122,84,1,61,51,35,1,0,0,255,13,42,31,14,1, + 249,186,86,1,249,188,92,1,249,190,98,1,212,164,88,1,102,80,45,1, + 0,0,255,3,0,0,0,2,0,0,255,12,20,17,12,1,117,95,56,1, + 249,183,79,1,249,185,85,1,213,160,77,1,100,76,39,1,0,0,255,5, + 0,0,168,1,0,0,16,1,0,0,255,3,0,0,224,1,0,0,59,1, + 0,0,43,1,0,0,79,1,0,0,244,1,0,0,255,3,27,21,10,1, + 222,168,79,1,249,180,71,1,249,182,77,1,176,130,58,1,0,0,0,1, + 0,0,255,4,0,0,210,1,0,0,31,1,0,0,15,1,0,0,255,3, + 0,0,74,1,0,0,159,1,0,0,255,1,0,0,106,1,0,0,126,1, + 0,0,255,3,158,112,41,1,248,176,64,1,248,178,66,1,212,153,59,1, + 89,65,28,1,0,0,255,4,0,0,238,1,0,0,46,1,0,0,180,1, + 0,0,15,1,0,0,255,2,0,0,249,1,0,0,4,1,0,0,243,1, + 0,0,255,1,0,0,195,1,0,0,49,1,0,0,255,2,23,16,6,1, + 248,177,65,2,248,177,64,1,186,131,45,1,0,0,0,1,0,0,255,3, + 0,0,253,1,0,0,72,1,0,0,170,1,0,0,223,1,0,0,15,1, + 0,0,255,2,0,0,228,1,0,0,11,1,0,0,255,2,0,0,219,1, + 0,0,21,1,0,0,255,2,21,15,5,1,248,177,65,2,248,176,63,1, + 186,129,40,1,0,0,0,1,0,0,255,3,0,0,120,1,0,0,116,1, + 0,0,255,1,0,0,223,1,0,0,15,1,0,0,255,2,0,0,229,1, + 0,0,12,1,0,0,255,2,0,0,219,1,0,0,20,1,0,0,255,2, + 21,15,5,1,248,177,65,1,248,175,61,1,247,167,41,1,186,127,34,1, + 0,0,0,1,0,0,255,3,0,0,24,1,0,0,45,1,0,0,47,1, + 0,0,41,1,0,0,2,1,0,0,47,1,0,0,255,1,0,0,250,1, + 0,0,6,1,0,0,245,1,0,0,255,1,0,0,196,1,0,0,46,1, + 0,0,255,2,21,14,3,1,247,166,38,1,247,165,37,1,247,162,30,1, + 232,154,32,1,132,89,22,1,0,0,0,2,0,0,255,4,0,0,223,1, + 0,0,15,1,0,0,255,3,0,0,74,1,0,0,160,1,0,0,255,1, + 0,0,109,1,0,0,121,1,0,0,255,2,21,13,2,1,247,162,29,3, + 247,163,31,1,232,156,35,1,179,129,48,1,147,126,87,1,96,84,62,1, + 0,0,255,3,0,0,223,1,0,0,15,1,0,0,255,3,0,0,221,1, + 0,0,54,1,0,0,43,1,0,0,77,1,0,0,243,1,0,0,255,2, + 21,13,2,1,247,162,29,3,196,128,23,1,41,28,6,1,38,27,10,1, + 31,27,18,1,28,25,18,1,0,0,255,14,10,7,1,1,219,143,26,1, + 220,144,26,1,31,20,4,2,30,19,3,1,0,0,255,18,10,7,1,1, + 228,150,27,1,18,12,2,1,0,0,0,1,0,0,255,20,10,7,1,1, + 226,148,27,1,0,0,0,1,0,0,255,21,0,0) + ); + +const + objdata_tmsemysql41connection: record size: integer; data: array[0..1285] of byte end = + (size: 1286; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,109,115, + 101,109,121,115,113,108,52,49,99,111,110,110,101,99,116,105,111,110,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,204,4,0,0,0,0,0,0, + 0,0,0,0,24,0,0,0,24,0,0,0,152,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,35,0,0,0,1,6,5,5,1, + 11,10,9,1,4,4,3,1,7,7,6,1,11,10,9,1,0,0,255,11, + 4,4,3,1,21,18,13,2,21,18,14,1,20,17,13,1,0,0,255,1, + 10,9,7,1,21,19,16,1,147,135,117,1,253,235,207,1,95,88,79,1, + 169,160,147,1,254,242,224,1,79,76,70,1,21,20,19,1,0,0,255,9, + 51,43,31,1,228,194,139,1,251,216,159,1,252,218,165,1,169,148,113,1, + 31,27,21,1,133,118,97,1,253,227,188,1,253,230,193,1,253,232,199,1, + 115,105,91,1,180,168,150,1,253,239,217,1,254,241,223,1,254,244,228,1, + 69,66,62,1,0,0,255,9,60,50,36,1,222,188,134,1,251,215,156,1, + 251,217,162,1,252,219,168,1,252,222,174,1,252,224,180,1,253,227,186,1, + 252,229,192,1,253,231,198,1,254,234,203,1,254,237,209,1,253,239,215,1, + 254,240,220,1,254,243,226,1,69,66,61,1,42,41,39,1,0,0,255,8, + 110,92,63,1,251,212,149,1,252,214,155,1,252,217,161,1,252,219,167,1, + 252,221,172,1,252,223,178,1,252,226,184,1,253,229,190,1,253,231,196,1, + 253,234,201,1,253,236,207,1,254,238,213,1,254,240,219,1,254,243,225,1, + 254,245,230,1,11,10,10,1,0,0,255,6,63,51,34,1,251,206,136,1, + 251,209,142,1,251,211,147,1,251,213,153,1,252,216,159,1,252,218,165,1, + 252,221,170,1,252,223,176,1,213,190,154,1,190,171,143,1,190,173,147,1, + 190,175,151,1,190,177,156,1,190,178,160,1,190,180,164,1,191,182,168,1, + 10,10,9,1,0,0,255,6,63,51,32,1,250,203,128,1,251,206,134,1, + 251,208,140,1,251,210,145,1,251,213,151,1,252,215,157,1,252,217,163,1, + 252,219,169,1,95,83,64,1,0,0,0,7,0,0,255,7,125,98,57,1, + 250,200,120,1,250,203,127,1,251,205,133,1,251,207,138,1,251,209,144,1, + 252,212,150,1,252,214,156,1,252,217,161,1,95,82,61,1,0,0,255,13, + 52,40,22,1,250,194,107,1,250,197,113,1,250,200,119,1,250,202,125,1, + 211,172,111,1,157,130,87,1,204,170,117,1,251,211,148,1,197,167,120,1, + 77,66,48,1,0,0,255,12,34,25,12,1,134,101,50,1,250,191,100,1, + 250,194,106,1,250,196,111,1,211,168,99,1,103,83,51,1,0,0,0,1, + 92,77,52,1,146,122,84,1,61,51,35,1,0,0,255,13,42,31,14,1, + 249,186,86,1,249,188,92,1,249,190,98,1,212,164,88,1,102,80,45,1, + 0,0,255,3,0,0,0,2,0,0,255,12,20,17,12,1,117,95,56,1, + 249,183,79,1,249,185,85,1,213,160,77,1,100,76,39,1,0,0,255,5, + 0,0,168,1,0,0,16,1,0,0,255,4,0,0,207,1,0,0,27,1, + 0,0,255,5,27,21,10,1,222,168,79,1,249,180,71,1,249,182,77,1, + 176,130,58,1,0,0,0,1,0,0,255,4,0,0,210,1,0,0,31,1, + 0,0,15,1,0,0,255,2,0,0,253,1,0,0,158,1,0,0,23,1, + 0,0,15,1,0,0,255,5,158,112,41,1,248,176,64,1,248,178,66,1, + 212,153,59,1,89,65,28,1,0,0,255,4,0,0,238,1,0,0,46,1, + 0,0,180,1,0,0,15,1,0,0,255,2,0,0,212,1,0,0,90,1, + 0,0,194,1,0,0,15,1,0,0,255,4,23,16,6,1,248,177,65,2, + 248,177,64,1,186,131,45,1,0,0,0,1,0,0,255,3,0,0,253,1, + 0,0,72,1,0,0,170,1,0,0,223,1,0,0,15,1,0,0,255,4, + 0,0,223,1,0,0,15,1,0,0,255,4,21,15,5,1,248,177,65,2, + 248,176,63,1,186,129,40,1,0,0,0,1,0,0,255,3,0,0,120,1, + 0,0,116,1,0,0,255,1,0,0,223,1,0,0,15,1,0,0,255,4, + 0,0,223,1,0,0,15,1,0,0,255,4,21,15,5,1,248,177,65,1, + 248,175,61,1,247,167,41,1,186,127,34,1,0,0,0,1,0,0,255,3, + 0,0,24,1,0,0,45,1,0,0,47,1,0,0,41,1,0,0,2,1, + 0,0,47,1,0,0,255,3,0,0,223,1,0,0,15,1,0,0,255,4, + 21,14,3,1,247,166,38,1,247,165,37,1,247,162,30,1,232,154,32,1, + 132,89,22,1,0,0,0,2,0,0,255,4,0,0,223,1,0,0,15,1, + 0,0,255,4,0,0,223,1,0,0,15,1,0,0,255,4,21,13,2,1, + 247,162,29,3,247,163,31,1,232,156,35,1,179,129,48,1,147,126,87,1, + 96,84,62,1,0,0,255,3,0,0,223,1,0,0,15,1,0,0,255,4, + 0,0,223,1,0,0,15,1,0,0,255,4,21,13,2,1,247,162,29,3, + 196,128,23,1,41,28,6,1,38,27,10,1,31,27,18,1,28,25,18,1, + 0,0,255,14,10,7,1,1,219,143,26,1,220,144,26,1,31,20,4,2, + 30,19,3,1,0,0,255,18,10,7,1,1,228,150,27,1,18,12,2,1, + 0,0,0,1,0,0,255,20,10,7,1,1,226,148,27,1,0,0,0,1, + 0,0,255,21,0,0) + ); + +const + objdata_tmsemysql50connection: record size: integer; data: array[0..1389] of byte end = + (size: 1390; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,109,115, + 101,109,121,115,113,108,53,48,99,111,110,110,101,99,116,105,111,110,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,52,5,0,0,0,0,0,0, + 0,0,0,0,24,0,0,0,24,0,0,0,0,5,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,35,0,0,0,1,6,5,5,1, + 11,10,9,1,4,4,3,1,7,7,6,1,11,10,9,1,0,0,255,11, + 4,4,3,1,21,18,13,2,21,18,14,1,20,17,13,1,0,0,255,1, + 10,9,7,1,21,19,16,1,147,135,117,1,253,235,207,1,95,88,79,1, + 169,160,147,1,254,242,224,1,79,76,70,1,21,20,19,1,0,0,255,9, + 51,43,31,1,228,194,139,1,251,216,159,1,252,218,165,1,169,148,113,1, + 31,27,21,1,133,118,97,1,253,227,188,1,253,230,193,1,253,232,199,1, + 115,105,91,1,180,168,150,1,253,239,217,1,254,241,223,1,254,244,228,1, + 69,66,62,1,0,0,255,9,60,50,36,1,222,188,134,1,251,215,156,1, + 251,217,162,1,252,219,168,1,252,222,174,1,252,224,180,1,253,227,186,1, + 252,229,192,1,253,231,198,1,254,234,203,1,254,237,209,1,253,239,215,1, + 254,240,220,1,254,243,226,1,69,66,61,1,42,41,39,1,0,0,255,8, + 110,92,63,1,251,212,149,1,252,214,155,1,252,217,161,1,252,219,167,1, + 252,221,172,1,252,223,178,1,252,226,184,1,253,229,190,1,253,231,196,1, + 253,234,201,1,253,236,207,1,254,238,213,1,254,240,219,1,254,243,225,1, + 254,245,230,1,11,10,10,1,0,0,255,6,63,51,34,1,251,206,136,1, + 251,209,142,1,251,211,147,1,251,213,153,1,252,216,159,1,252,218,165,1, + 252,221,170,1,252,223,176,1,213,190,154,1,190,171,143,1,190,173,147,1, + 190,175,151,1,190,177,156,1,190,178,160,1,190,180,164,1,191,182,168,1, + 10,10,9,1,0,0,255,6,63,51,32,1,250,203,128,1,251,206,134,1, + 251,208,140,1,251,210,145,1,251,213,151,1,252,215,157,1,252,217,163,1, + 252,219,169,1,95,83,64,1,0,0,0,7,0,0,255,7,125,98,57,1, + 250,200,120,1,250,203,127,1,251,205,133,1,251,207,138,1,251,209,144,1, + 252,212,150,1,252,214,156,1,252,217,161,1,95,82,61,1,0,0,255,13, + 52,40,22,1,250,194,107,1,250,197,113,1,250,200,119,1,250,202,125,1, + 211,172,111,1,157,130,87,1,204,170,117,1,251,211,148,1,197,167,120,1, + 77,66,48,1,0,0,255,12,34,25,12,1,134,101,50,1,250,191,100,1, + 250,194,106,1,250,196,111,1,211,168,99,1,103,83,51,1,0,0,0,1, + 92,77,52,1,146,122,84,1,61,51,35,1,0,0,255,13,42,31,14,1, + 249,186,86,1,249,188,92,1,249,190,98,1,212,164,88,1,102,80,45,1, + 0,0,255,3,0,0,0,2,0,0,255,12,20,17,12,1,117,95,56,1, + 249,183,79,1,249,185,85,1,213,160,77,1,100,76,39,1,0,0,255,3, + 0,0,71,1,0,0,38,1,0,0,47,2,0,0,73,1,0,0,255,1, + 0,0,224,1,0,0,59,1,0,0,43,1,0,0,79,1,0,0,244,1, + 0,0,255,4,27,21,10,1,222,168,79,1,249,180,71,1,249,182,77,1, + 176,130,58,1,0,0,0,1,0,0,255,2,0,0,254,1,0,0,20,1, + 0,0,241,1,0,0,255,4,0,0,74,1,0,0,159,1,0,0,255,1, + 0,0,106,1,0,0,126,1,0,0,255,4,158,112,41,1,248,176,64,1, + 248,178,66,1,212,153,59,1,89,65,28,1,0,0,255,3,0,0,213,1, + 0,0,20,1,0,0,73,1,0,0,42,1,0,0,102,1,0,0,245,1, + 0,0,249,1,0,0,4,1,0,0,243,1,0,0,255,1,0,0,195,1, + 0,0,49,1,0,0,255,3,23,16,6,1,248,177,65,2,248,177,64,1, + 186,131,45,1,0,0,0,1,0,0,255,3,0,0,194,1,0,0,92,1, + 0,0,239,1,0,0,249,1,0,0,91,1,0,0,105,1,0,0,228,1, + 0,0,11,1,0,0,255,2,0,0,219,1,0,0,21,1,0,0,255,3, + 21,15,5,1,248,177,65,2,248,176,63,1,186,129,40,1,0,0,0,1, + 0,0,255,7,0,0,209,1,0,0,27,1,0,0,229,1,0,0,12,1, + 0,0,255,2,0,0,219,1,0,0,20,1,0,0,255,3,21,15,5,1, + 248,177,65,1,248,175,61,1,247,167,41,1,186,127,34,1,0,0,0,1, + 0,0,255,3,0,0,187,1,0,0,183,1,0,0,255,2,0,0,208,1, + 0,0,31,1,0,0,250,1,0,0,6,1,0,0,245,1,0,0,255,1, + 0,0,196,1,0,0,46,1,0,0,255,3,21,14,3,1,247,166,38,1, + 247,165,37,1,247,162,30,1,232,154,32,1,132,89,22,1,0,0,0,2, + 0,0,255,1,0,0,166,1,0,0,40,1,0,0,243,1,0,0,254,1, + 0,0,98,1,0,0,86,1,0,0,255,1,0,0,74,1,0,0,160,1, + 0,0,255,1,0,0,109,1,0,0,121,1,0,0,255,3,21,13,2,1, + 247,162,29,3,247,163,31,1,232,156,35,1,179,129,48,1,147,126,87,1, + 96,84,62,1,0,0,254,1,0,0,122,1,0,0,34,1,0,0,39,1, + 0,0,83,1,0,0,230,1,0,0,255,1,0,0,221,1,0,0,54,1, + 0,0,43,1,0,0,77,1,0,0,243,1,0,0,255,3,21,13,2,1, + 247,162,29,3,196,128,23,1,41,28,6,1,38,27,10,1,31,27,18,1, + 28,25,18,1,0,0,255,14,10,7,1,1,219,143,26,1,220,144,26,1, + 31,20,4,2,30,19,3,1,0,0,255,18,10,7,1,1,228,150,27,1, + 18,12,2,1,0,0,0,1,0,0,255,20,10,7,1,1,226,148,27,1, + 0,0,0,1,0,0,255,21,0,0) + ); + +initialization + registerobjectdata(@objdata_tmsemysql40connection,tbitmapcomp,'tmsemysql40connection'); + registerobjectdata(@objdata_tmsemysql41connection,tbitmapcomp,'tmsemysql41connection'); + registerobjectdata(@objdata_tmsemysql50connection,tbitmapcomp,'tmsemysql50connection'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdesignutils.pas b/mseide-msegui/lib/common/regcomponents/regdesignutils.pas new file mode 100644 index 0000000..8d07222 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdesignutils.pas @@ -0,0 +1,35 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regdesignutils; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + msegdbutils,classes,msedesignintf,msesyntaxedit,msesyntaxpainter,regdesignutils_bmp; + +procedure Register; +begin + registercomponents('Design',[tgdbmi,tsyntaxedit,tsyntaxpainter]); + registercomponenttabhints(['Design'],['Design utils']); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdesignutils_bmp.pas b/mseide-msegui/lib/common/regcomponents/regdesignutils_bmp.pas new file mode 100644 index 0000000..09c5f75 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdesignutils_bmp.pas @@ -0,0 +1,150 @@ +unit regdesignutils_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tgdbmi: record size: integer; data: array[0..418] of byte end = + (size: 419; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,103,100, + 98,109,105,12,98,105,116,109,97,112,46,105,109,97,103,101,10,120,1,0, + 0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,68,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,171,0,0,0, + 3,255,0,255,3,0,0,0,4,255,0,255,3,0,0,0,5,255,0,255, + 5,0,0,0,1,255,0,255,3,0,0,0,1,255,0,255,2,0,0,0, + 1,255,0,255,3,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255, + 4,0,0,0,1,255,0,255,3,0,0,0,1,255,0,255,5,0,0,0, + 1,255,0,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255,0,255, + 1,0,0,0,1,255,0,255,4,0,0,0,1,255,0,255,3,0,0,0, + 1,255,0,255,7,0,0,0,1,255,0,255,4,0,0,0,1,255,0,255, + 1,0,0,0,6,255,0,255,3,0,0,0,1,255,0,255,3,0,0,0, + 3,255,0,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255,0,255, + 1,0,0,0,1,255,0,255,4,0,0,0,1,255,0,255,3,0,0,0, + 1,255,0,255,5,0,0,0,1,255,0,255,1,0,0,0,1,255,0,255, + 4,0,0,0,1,255,0,255,1,0,0,0,1,255,0,255,4,0,0,0, + 1,255,0,255,4,0,0,0,1,255,0,255,3,0,0,0,1,255,0,255, + 2,0,0,0,1,255,0,255,3,0,0,0,1,255,0,255,2,0,0,0, + 1,255,0,255,4,0,0,0,1,255,0,255,5,0,0,0,3,255,0,255, + 3,0,0,0,4,255,0,255,3,0,0,0,5,255,0,255,219,0,0) + ); + +const + objdata_tsyntaxedit: record size: integer; data: array[0..1614] of byte end = + (size: 1615; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,115,121, + 110,116,97,120,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,216,5,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,140,5,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,140,140,140,1,148,148,148, + 1,226,226,226,1,209,209,209,1,222,222,222,2,175,175,175,1,242,242,242, + 1,132,132,132,1,210,210,210,1,215,215,215,1,226,226,226,1,190,190,190, + 1,209,209,209,1,165,165,165,1,210,210,210,1,208,208,208,1,255,255,255, + 2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 1,138,138,138,1,183,183,183,1,190,190,190,1,133,133,133,1,179,179,179, + 1,177,177,177,1,180,180,183,1,232,232,252,1,153,153,155,1,192,192,192, + 1,140,140,140,1,180,180,180,1,195,195,195,1,213,213,213,1,156,156,156, + 1,169,169,169,1,155,155,155,1,255,255,255,2,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,211,211,211,1,255,255,255, + 1,208,208,208,1,161,161,182,1,73,73,214,1,33,33,217,1,4,4,219, + 1,0,0,219,1,3,3,219,1,30,30,221,1,96,96,205,1,205,205,219, + 1,203,203,203,1,234,234,234,1,220,220,220,1,183,183,183,1,167,167,167, + 1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,255,255,255,3,193,193,246,1,22,22,222,1,0,0,219,7,32,32,224, + 1,236,236,252,1,255,255,255,1,224,224,224,1,255,255,255,1,232,232,232, + 1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,255,255,255,1,175,175,175,2,39,39,208,1,0,0,219,2,66,66,220, + 1,99,99,191,1,112,112,176,1,89,89,207,1,12,12,213,1,0,0,219, + 2,68,68,209,1,202,202,202,1,145,145,145,1,255,255,255,4,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,164,164,164, + 1,139,139,156,1,1,1,218,1,0,0,219,1,29,29,220,1,161,161,162, + 1,149,149,149,1,159,159,159,1,171,171,171,1,108,108,191,1,0,0,219, + 2,14,14,216,1,134,134,134,1,176,176,176,1,255,255,255,4,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,197,197,197, + 1,191,191,200,1,4,4,220,1,0,0,219,1,1,1,219,1,142,142,238, + 1,233,233,252,1,255,255,255,2,253,253,255,1,189,189,246,1,199,199,247, + 1,209,209,249,1,253,253,255,1,255,255,255,5,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,124,124,124,1,216,216,216, + 1,71,71,222,1,0,0,219,3,3,3,219,1,57,57,217,1,108,108,196, + 1,160,160,182,1,236,236,236,1,217,217,217,1,137,137,137,1,213,213,213, + 1,207,207,207,1,186,186,186,1,255,255,255,3,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,175,175,175,1,169,169,169, + 1,152,152,167,1,32,32,209,1,0,0,219,5,1,1,219,1,36,36,210, + 1,117,117,191,1,156,156,156,1,192,192,192,1,188,188,188,1,173,173,173, + 1,255,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,255,255,255,1,215,215,215,1,167,167,167,1,157,157,157,1,182,182,185, + 1,124,124,208,1,42,42,201,1,6,6,220,1,0,0,219,5,105,105,211, + 1,236,236,236,1,184,184,184,1,214,214,214,1,255,255,255,3,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,197,197,197, + 1,160,160,160,1,214,214,214,1,218,218,218,1,255,255,255,2,242,242,251, + 1,183,183,245,1,99,99,218,1,16,16,210,1,0,0,219,2,1,1,219, + 1,233,233,252,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0, + 1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,255,255,255,1,176,176,176,1,107,107,165,1,81,81,182,1,78,78,200, + 1,127,127,180,1,175,175,175,1,110,110,110,1,216,216,216,1,255,255,255, + 1,170,170,177,1,51,51,222,1,0,0,219,2,167,167,243,1,255,255,255, + 2,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,185,185,185,1,121,121,227,1,0,0,219, + 2,33,33,212,1,187,187,189,1,177,177,177,1,203,203,203,1,255,255,255, + 1,195,195,195,1,55,55,214,1,0,0,219,2,156,156,241,1,255,255,255, + 2,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,242,242,242,1,210,210,249,1,1,1,219, + 1,0,0,219,2,100,100,228,1,202,202,248,1,253,253,255,1,212,212,249, + 1,129,129,237,1,0,0,219,2,2,2,219,1,233,233,252,1,255,255,255, + 2,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,175,175,175,1,226,226,226,1,107,107,220, + 1,0,0,219,4,6,6,219,1,0,0,219,4,88,88,231,1,255,255,255, + 3,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,183,183,183,1,126,126,126,1,236,236,238, + 1,86,86,189,1,12,12,214,1,0,0,219,5,3,3,219,1,107,107,234, + 1,248,248,254,1,255,255,255,3,0,0,0,1,255,255,255,2,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,234,234,234, + 1,162,162,162,1,255,255,255,1,234,234,234,1,244,244,253,1,162,162,218, + 1,133,133,216,1,129,129,233,1,123,123,217,1,150,150,219,1,216,216,231, + 1,255,255,255,5,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,16,0,0,0,1,255,255,255, + 1,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,20,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,42,128,128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tsyntaxpainter: record size: integer; data: array[0..370] of byte end = + (size: 371; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,121, + 110,116,97,120,112,97,105,110,116,101,114,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,64,1,0,0,0,0,0,0,0,0,0,0,24,0,0, + 0,24,0,0,0,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,0,255,25,0,0,0,3,255,0,255,21,0,0,0,4,255,0,255, + 1,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0, + 1,255,0,255,3,255,0,0,4,255,0,255,1,128,0,0,1,255,0,255, + 53,0,0,0,1,255,0,255,1,0,0,0,2,255,0,255,3,0,0,0, + 1,255,0,255,1,0,0,0,1,255,0,255,1,0,0,0,1,255,0,255, + 16,0,0,0,1,255,0,255,43,0,0,0,1,255,0,255,1,0,0,0, + 1,255,0,255,2,0,0,0,1,255,0,255,1,0,0,0,2,255,0,255, + 63,0,0,0,4,255,0,255,2,0,0,0,1,255,0,255,1,0,0,0, + 1,255,0,255,15,0,0,0,1,255,0,255,45,0,0,0,2,255,0,255, + 22,0,0,0,2,255,0,255,70,0,0,0,5,255,0,255,19,0,0,0, + 5,255,0,255,1,0,0,0,3,255,0,255,2,0,0,0,1,255,0,255, + 2,0,0,0,1,255,0,255,1,0,0,0,1,255,0,255,58,0,0,0, + 1,255,0,255,1,0,0,0,3,255,0,255,3,0,0,0,1,255,0,255, + 1,0,0,0,1,255,0,255,33,0,0) + ); + +initialization + registerobjectdata(@objdata_tgdbmi,tbitmapcomp,'tgdbmi'); + registerobjectdata(@objdata_tsyntaxedit,tbitmapcomp,'tsyntaxedit'); + registerobjectdata(@objdata_tsyntaxpainter,tbitmapcomp,'tsyntaxpainter'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdialogs.pas b/mseide-msegui/lib/common/regcomponents/regdialogs.pas new file mode 100644 index 0000000..3fe5891 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdialogs.pas @@ -0,0 +1,43 @@ +{ MSEide Copyright (c) 1999-2012 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regdialogs; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + Classes,msefiledialog,msedesignintf,regdialogs_bmp,msecolordialog, + msememodialog,msedialog,mseguirttistat; + +procedure Register; +begin + registercomponents('Dialog',[tfilelistview,tdirtreeview, + tfiledialog, + tfilenameedit,tremotefilenameedit, + tdirdropdownedit,tcoloredit, + tdialogstringedit,tdialogintegeredit, + tdialogrealedit,tdialogdatetimeedit, + tmemodialogedit, + tmemodialoghistoryedit,tguirttistat]); + registercomponenttabhints(['Dialog'],['User dialogs']); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdialogs_bmp.pas b/mseide-msegui/lib/common/regcomponents/regdialogs_bmp.pas new file mode 100644 index 0000000..4755caf --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdialogs_bmp.pas @@ -0,0 +1,649 @@ +unit regdialogs_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tfilelistview: record size: integer; data: array[0..868] of byte end = + (size: 869; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,102,105, + 108,101,108,105,115,116,118,105,101,119,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,236,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,160,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0,0,0,4,255, + 255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,8,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,8,0,0,0,1,255,255,255,8,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,186, + 186,186,1,25,25,25,2,195,195,195,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0,0,0,3,255, + 255,255,3,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,39, + 39,39,1,194,194,194,1,197,197,197,1,50,50,50,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,2,3,3,3,1,0,0,0,2,4,4,4,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,2,34,34,34,1,195,195,195,1,220,220,220,1,255,255,255,3,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,2,179,179,179,1,23,23,23,1,0,0,0,1,58,58,58,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,25,20,0,0,0,255,255,255,255,255,255,255,255,255,255,255,42,128, + 128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tdirtreeview: record size: integer; data: array[0..1027] of byte end = + (size: 1028; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,100,105, + 114,116,114,101,101,118,105,101,119,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,140,3,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,64,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,3,57,57,57,1,68,68, + 68,2,112,112,112,1,233,233,233,1,255,255,255,2,59,59,59,1,249,249, + 249,1,225,225,225,1,54,54,54,1,68,68,68,1,71,71,71,1,95,95, + 95,1,219,219,219,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,255,255,3,8,8,8,1,249,249,249,1,254,254, + 254,1,176,176,176,1,42,42,42,1,245,245,245,1,255,255,255,1,10,10, + 10,1,247,247,247,1,217,217,217,1,39,39,39,1,255,255,255,2,175,175, + 175,1,50,50,50,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,255,255,3,8,8,8,1,249,249,249,1,255,255, + 255,2,88,88,88,1,168,168,168,1,255,255,255,1,10,10,10,1,247,247, + 247,1,217,217,217,1,39,39,39,1,255,255,255,2,222,222,222,1,25,25, + 25,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,3,8,8,8,1,249,249,249,1,255,255,255,2,120,120, + 120,1,139,139,139,1,255,255,255,1,10,10,10,1,247,247,247,1,217,217, + 217,1,16,16,16,1,102,102,102,1,98,98,98,1,49,49,49,1,173,173, + 173,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,3,8,8,8,1,249,249,249,1,255,255,255,2,85,85, + 85,1,168,168,168,1,255,255,255,1,10,10,10,1,247,247,247,1,217,217, + 217,1,34,34,34,1,221,221,221,1,190,190,190,1,41,41,41,1,247,247, + 247,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,3,8,8,8,1,249,249,249,1,252,252,252,1,168,168, + 168,1,40,40,40,1,244,244,244,1,255,255,255,1,10,10,10,1,247,247, + 247,1,217,217,217,1,39,39,39,1,255,255,255,2,114,114,114,1,123,123, + 123,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,3,57,57,57,1,68,68,68,2,116,116,116,1,234,234, + 234,1,255,255,255,2,59,59,59,1,249,249,249,1,225,225,225,1,82,82, + 82,1,255,255,255,2,242,242,242,1,69,69,69,1,232,232,232,1,255,255, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255, + 255,25,20,0,0,0,255,255,255,255,255,255,255,255,255,255,255,42,128,128, + 128,1,255,255,255,23,0,0) + ); + +const + objdata_tfiledialog: record size: integer; data: array[0..2114] of byte end = + (size: 2115; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,102,105, + 108,101,100,105,97,108,111,103,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,204,7,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,136,7,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,25,242,166,149,1,221,216,211, + 1,242,166,149,1,255,134,109,2,121,64,52,1,157,83,67,1,187,98,80, + 1,208,109,89,2,247,130,106,1,212,111,91,1,255,134,109,4,160,160,160, + 6,128,128,128,1,255,255,255,1,221,216,211,1,7,239,255,1,221,216,211, + 1,255,134,109,2,120,63,51,1,201,106,86,1,181,95,77,1,135,71,58, + 1,214,112,91,1,139,73,59,1,163,86,70,1,242,127,103,1,255,134,109, + 3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160,1,209,209,209, + 1,128,128,128,2,255,255,255,1,242,166,149,1,221,216,211,1,242,166,149, + 1,255,134,109,2,212,111,91,1,255,134,109,1,218,115,93,1,204,107,87, + 1,180,95,77,1,222,117,95,1,184,97,79,1,253,133,108,1,255,134,109, + 3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160,1,209,209,209, + 1,128,128,128,2,255,255,255,1,151,24,0,16,128,128,128,7,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225, + 1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214, + 1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209, + 1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128, + 1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,0,0,0,4,223,223,223, + 1,222,222,222,1,0,0,0,1,220,220,220,1,219,219,219,1,0,0,0, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128, + 1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,0,0,0, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,0,0,0,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,0,0,0,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,0,0,0, + 1,220,220,220,1,219,219,219,1,0,0,0,1,217,217,217,1,215,215,215, + 1,156,156,156,1,21,21,21,2,161,161,161,1,210,210,210,1,209,209,209, + 1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,0,0,0,3,224,224,224,1,223,223,223,1,222,222,222, + 1,0,0,0,1,220,220,220,1,219,219,219,1,0,0,0,1,217,217,217, + 1,215,215,215,1,33,33,33,1,162,162,162,1,164,164,164,1,41,41,41, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,0,0,0,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,0,0,0, + 1,220,220,220,1,219,219,219,1,0,0,0,1,217,217,217,1,215,215,215, + 1,3,3,3,1,0,0,0,2,3,3,3,1,210,210,210,1,209,209,209, + 1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,0,0,0,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,0,0,0,1,220,220,220,1,219,219,219, + 1,0,0,0,1,217,217,217,1,215,215,215,1,29,29,29,1,163,163,163, + 1,183,183,183,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,0,0,0,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,0,0,0,1,220,220,220,1,219,219,219,1,0,0,0, + 1,217,217,217,1,215,215,215,1,150,150,150,1,19,19,19,1,0,0,0, + 1,48,48,48,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128, + 1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225, + 1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214, + 1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209, + 1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128, + 1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,25,12,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tfilenameedit: record size: integer; data: array[0..740] of byte end = + (size: 741; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,102,105, + 108,101,110,97,109,101,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,108,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,36,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0, + 0,0,4,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,6,0,0,0,1,255,255,255,1,0,0,0,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,8,0,0,0,1,255,255,255,7,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,2,186,186,186,1,25,25,25,2,195,195,195,1,255,255,255,1,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,0,0,0,3,255,255,255,3,0,0,0,1,255, + 255,255,2,0,0,0,1,255,255,255,2,39,39,39,1,194,194,194,1,197, + 197,197,1,50,50,50,1,255,255,255,1,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,2,3,3,3,1,0,0,0,2,4,4,4,1,255,255,255,1,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,5,0,0,0,1,255, + 255,255,2,0,0,0,1,255,255,255,2,34,34,34,1,195,195,195,1,220, + 220,220,1,255,255,255,2,0,0,0,1,255,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,179, + 179,179,1,23,23,23,1,0,0,0,1,58,58,58,1,255,255,255,1,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0,0,0,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16, + 0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0, + 0) + ); + +const + objdata_tdirdropdownedit: record size: integer; data: array[0..1243] of byte end = + (size: 1244; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,100,105, + 114,100,114,111,112,100,111,119,110,101,100,105,116,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,96,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,28,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255, + 255,1,0,0,0,2,5,5,5,1,174,174,174,1,255,255,255,2,0,0, + 0,1,255,255,255,6,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,6,128,128,128,1,255,255,255,1,0,0,0,1,255,255,255,1,174,174, + 174,1,5,5,5,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,1,71,71,71,1,255,255,255,4,0,0,0,1,255,255,255,2,208,208, + 208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,1,213,213,213,1,255,255,255,4,0,0,0,1,255,255, + 255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,1,254,254,254,1,255,255,255,4,0,0, + 0,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128, + 128,1,255,255,255,1,128,128,128,1,255,255,255,1,0,0,0,1,255,255, + 255,1,174,174,174,1,5,5,5,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,3,252,252,252,1,231,231,231,1,0,0, + 0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,0,0,0,2,5,5,5,1,174,174, + 174,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,3,223,223,223,1,0,0,0,1,223,223,223,1,0,0,0,1,128,128, + 128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0,2,255,255, + 255,1,0,0,0,3,255,255,255,1,238,238,238,1,167,167,167,1,171,171, + 171,1,220,220,220,1,203,203,203,1,175,175,175,1,204,204,204,1,219,219, + 219,1,241,241,241,1,200,200,200,1,243,243,243,1,255,255,255,6,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,226,226,226,1,147,147,147,1,164,164,164,1,173,173,173,1,175,175, + 175,1,178,178,178,1,172,172,172,1,182,182,182,1,172,172,172,1,166,166, + 166,1,173,173,173,1,255,255,255,6,0,0,0,2,255,255,255,1,0,0, + 0,3,255,255,255,1,241,241,241,1,198,198,198,1,197,197,197,1,202,202, + 202,1,215,215,215,1,198,198,198,1,219,219,219,1,195,195,195,1,211,211, + 211,1,128,128,128,1,223,223,223,1,255,255,255,6,0,0,0,2,255,255, + 255,2,0,0,0,1,255,255,255,19,0,0,0,2,255,255,255,6,0,0, + 0,3,255,255,255,2,249,249,249,1,181,181,181,1,254,254,254,2,243,243, + 243,1,213,213,213,1,248,248,248,1,255,255,255,4,0,0,0,2,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,160,160,160,1,168,168, + 168,1,140,140,140,1,170,170,170,1,140,140,140,1,157,157,157,1,149,149, + 149,1,234,234,234,1,255,255,255,4,0,0,0,2,255,255,255,6,0,0, + 0,3,255,255,255,1,144,144,144,1,209,209,209,1,179,179,179,1,219,219, + 219,1,132,132,132,1,193,193,193,1,164,164,164,1,239,239,239,1,255,255, + 255,4,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,10,250,250, + 250,1,226,226,226,1,255,255,255,7,0,0,0,2,255,255,255,6,0,0, + 0,3,255,255,255,3,175,175,175,1,200,200,200,1,255,255,255,3,206,206, + 206,1,175,175,175,1,255,255,255,3,0,0,0,2,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,1,141,141,141,1,152,152,152,1,146,146, + 146,1,98,98,98,1,170,170,170,1,137,137,137,1,173,173,173,1,174,174, + 174,1,137,137,137,1,166,166,166,1,175,175,175,1,255,255,255,1,0,0, + 0,2,255,255,255,6,0,0,0,3,255,255,255,1,186,186,186,1,203,203, + 203,1,195,195,195,1,173,173,173,1,202,202,202,1,171,171,171,1,169,169, + 169,1,201,201,201,1,184,184,184,1,172,172,172,1,176,176,176,1,255,255, + 255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,15,252,252, + 252,1,183,183,183,1,241,241,241,1,255,255,255,1,0,0,0,2,255,255, + 255,22,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255, + 255,66,0,0) + ); + +const + objdata_tcoloredit: record size: integer; data: array[0..1177] of byte end = + (size: 1178; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,99,111, + 108,111,114,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,36,4,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,220,3,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0,22, + 255,255,255,1,128,128,128,1,0,0,0,1,0,36,255,1,0,111,255,1, + 0,187,255,1,0,255,247,1,0,255,167,1,0,255,87,1,0,255,7,1, + 68,255,0,1,143,255,0,1,218,255,0,1,255,217,0,1,255,142,0,1, + 255,67,0,1,255,0,7,1,255,0,82,1,255,0,156,1,255,0,231,1, + 198,0,255,1,118,0,255,1,39,0,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1, + 0,255,247,1,0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1, + 143,255,0,1,218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1, + 255,0,7,1,255,0,82,1,255,0,156,1,255,0,231,1,0,0,0,1, + 118,0,255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1,0,255,247,1, + 0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1,143,255,0,1, + 218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1,255,0,7,1, + 255,0,82,1,255,0,156,1,255,0,231,1,198,0,255,1,0,0,0,1, + 39,0,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 0,36,255,1,0,111,255,1,0,187,255,1,0,255,247,1,0,255,167,1, + 0,255,87,1,0,255,7,1,68,255,0,1,143,255,0,1,218,255,0,1, + 255,217,0,1,255,142,0,1,255,67,0,1,255,0,7,1,255,0,82,1, + 255,0,156,1,255,0,231,1,198,0,255,1,0,0,0,1,39,0,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,0,36,255,1, + 0,111,255,1,0,187,255,1,0,255,247,1,0,255,167,1,0,255,87,1, + 0,255,7,1,68,255,0,1,143,255,0,1,218,255,0,1,255,217,0,1, + 255,142,0,1,255,67,0,1,255,0,7,1,255,0,82,1,255,0,156,1, + 255,0,231,1,198,0,255,1,0,0,0,1,39,0,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,0,36,255,1,0,111,255,1, + 0,187,255,1,0,255,247,1,0,255,167,1,0,255,87,1,0,255,7,1, + 68,255,0,1,143,255,0,1,218,255,0,1,255,217,0,1,255,142,0,1, + 255,67,0,1,255,0,7,1,255,0,82,1,255,0,156,1,255,0,231,1, + 198,0,255,1,0,0,0,1,39,0,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1, + 0,255,247,1,0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1, + 143,255,0,1,218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1, + 255,0,7,1,255,0,82,1,255,0,156,1,255,0,231,1,198,0,255,1, + 0,0,0,1,39,0,255,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1,0,255,247,1, + 0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1,143,255,0,1, + 218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1,255,0,7,1, + 255,0,82,1,255,0,156,1,255,0,231,1,198,0,255,1,0,0,0,1, + 39,0,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 0,36,255,1,0,111,255,1,0,187,255,1,0,255,247,1,0,255,167,1, + 0,255,87,1,0,255,7,1,68,255,0,1,143,255,0,1,218,255,0,1, + 255,217,0,1,255,142,0,1,255,67,0,1,255,0,7,1,255,0,82,1, + 255,0,156,1,255,0,231,1,0,0,0,1,118,0,255,1,0,0,0,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,0,36,255,1, + 0,111,255,1,0,187,255,1,0,255,247,1,0,255,167,1,0,255,87,1, + 0,255,7,1,68,255,0,1,143,255,0,1,218,255,0,1,255,217,0,1, + 255,142,0,1,255,67,0,1,255,0,7,1,255,0,82,1,255,0,156,1, + 255,0,231,1,198,0,255,1,118,0,255,1,39,0,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16,0,0,0, + 0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdialogstringedit: record size: integer; data: array[0..876] of byte end = + (size: 877; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,105, + 97,108,111,103,115,116,114,105,110,103,101,100,105,116,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240, + 2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,168, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128, + 128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,13,243,243,243,7,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,254,254,254,1,31,31,31,1,173,173,173,1,255, + 255,255,1,0,0,0,1,51,51,51,1,49,49,49,1,31,31,31,1,149, + 149,149,1,0,0,0,1,255,255,255,1,0,0,0,1,243,243,243,1,232, + 232,232,5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,207,207,207,1,78,78,78,1,97,97,97,1,255, + 255,255,1,0,0,0,1,255,255,255,2,228,228,228,1,11,11,11,1,255, + 255,255,1,0,0,0,1,255,255,255,1,243,243,243,1,226,226,226,5,128, + 128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,128,128,128,1,199,199,199,1,53,53,53,1,253,253,253,1,0, + 0,0,1,255,255,255,1,254,254,254,1,189,189,189,1,43,43,43,1,255, + 255,255,1,0,0,0,1,255,255,255,1,243,243,243,1,215,215,215,5,128, + 128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,74,74,74,1,253,253,253,1,102,102,102,1,201,201,201,1,0, + 0,0,4,151,151,151,1,255,255,255,1,0,0,0,1,255,255,255,1,243, + 243,243,1,0,0,0,1,204,204,204,1,0,0,0,1,204,204,204,1,0, + 0,0,1,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,224,224,224,1,0,0,0,3,125,125,125,1,0,0,0,1,255, + 255,255,1,254,254,254,1,195,195,195,1,18,18,18,1,255,255,255,1,0, + 0,0,1,255,255,255,1,243,243,243,1,0,0,0,1,194,194,194,1,0, + 0,0,1,194,194,194,1,0,0,0,1,128,128,128,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,145,145,145,1,162,162,162,1,255, + 255,255,1,241,241,241,1,55,55,55,1,0,0,0,1,255,255,255,2,227, + 227,227,1,16,16,16,1,255,255,255,1,0,0,0,1,255,255,255,1,243, + 243,243,1,183,183,183,5,128,128,128,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,70,70,70,1,236,236,236,1,255,255,255,2,66, + 66,66,1,0,0,0,1,51,51,51,1,50,50,50,1,39,39,39,1,160, + 160,160,1,255,255,255,1,0,0,0,1,255,255,255,1,243,243,243,1,172, + 172,172,5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,0,0,0,1,255,255,255,1,0,0,0,1,243, + 243,243,1,167,167,167,5,128,128,128,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,13,128,128,128,7,224,224,224,1,255, + 255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16,0,0,0,0, + 0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tmemodialogedit: record size: integer; data: array[0..826] of byte end = + (size: 827; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,109,101, + 109,111,100,105,97,108,111,103,101,100,105,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,192,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,120,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 13,243,243,243,7,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 2,127,127,127,1,255,255,255,2,131,131,131,1,0,0,0,1,255,255,255, + 4,0,0,0,1,255,255,255,1,0,0,0,1,243,243,243,1,232,232,232, + 5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 2,86,86,86,1,255,255,255,2,91,91,91,1,0,0,0,1,255,255,255, + 5,0,0,0,1,255,255,255,1,243,243,243,1,226,226,226,5,128,128,128, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,2,101,101,101, + 1,238,238,238,1,241,241,241,1,104,104,104,1,0,0,0,1,255,255,255, + 1,238,238,238,1,73,73,73,1,57,57,57,1,150,150,150,1,0,0,0, + 1,255,255,255,1,243,243,243,1,215,215,215,5,128,128,128,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,2,169,169,169,1,170,170,170, + 1,175,175,175,1,170,170,170,1,0,0,0,1,255,255,255,1,131,131,131, + 1,196,196,196,1,255,255,255,1,86,86,86,1,0,0,0,1,255,255,255, + 1,243,243,243,1,0,0,0,1,204,204,204,1,0,0,0,1,204,204,204, + 1,0,0,0,1,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,2,236,236,236,1,101,101,101,1,107,107,107,1,237,237,237, + 1,0,0,0,1,255,255,255,1,87,87,87,1,0,0,0,4,255,255,255, + 1,243,243,243,1,0,0,0,1,194,194,194,1,0,0,0,1,194,194,194, + 1,0,0,0,1,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,2,255,255,255,1,81,81,81,1,89,89,89,1,255,255,255, + 1,0,0,0,1,255,255,255,1,109,109,109,1,208,208,208,1,255,255,255, + 1,165,165,165,1,0,0,0,1,255,255,255,1,243,243,243,1,183,183,183, + 5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 2,255,255,255,1,123,123,123,1,124,124,124,1,255,255,255,1,0,0,0, + 1,255,255,255,1,222,222,222,1,63,63,63,2,124,124,124,1,0,0,0, + 1,255,255,255,1,243,243,243,1,172,172,172,5,128,128,128,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,10,0,0,0, + 1,255,255,255,1,0,0,0,1,243,243,243,1,167,167,167,5,128,128,128, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 13,128,128,128,7,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224, + 22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tguirttistat: record size: integer; data: array[0..2711] of byte end = + (size: 2712; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,103,117, + 105,114,116,116,105,115,116,97,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,32,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,84,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,2,2,2,1,9,9,12,1,22,22, + 29,1,178,178,230,1,180,180,231,1,120,120,152,1,10,10,12,2,57,57, + 70,1,193,193,234,1,195,195,235,1,80,80,95,1,11,11,13,2,114,114, + 133,1,207,207,238,1,210,210,239,1,40,40,45,1,11,11,13,1,12,12, + 13,1,190,190,209,1,222,222,243,1,213,213,231,1,2,2,2,1,135,135, + 180,1,173,173,229,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183, + 231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195, + 235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207, + 238,1,210,210,239,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220, + 242,1,222,222,243,1,224,224,243,1,7,7,7,1,171,171,228,1,173,173, + 229,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185, + 232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197, + 236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222, + 243,1,224,224,243,1,39,39,42,1,171,171,228,1,173,173,229,1,175,175, + 229,1,178,178,230,1,178,181,231,1,131,210,242,1,95,229,250,1,65,237, + 254,1,64,229,251,1,107,214,244,1,192,196,235,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212, + 240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222,243,1,224,224, + 243,1,227,227,244,1,5,5,7,1,173,173,229,1,175,175,229,1,176,179, + 230,1,123,226,249,1,123,241,255,2,104,241,255,1,73,240,255,1,34,239, + 255,1,57,227,250,1,194,198,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,212,212,240,1,215,215,240,1,217,217, + 241,1,220,220,242,1,222,222,243,1,224,224,243,1,227,227,244,1,5,5, + 7,1,173,173,229,1,175,175,229,1,143,208,242,1,145,242,255,1,172,243, + 255,2,144,242,255,1,104,241,255,1,59,239,255,1,13,238,255,1,110,217, + 245,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222, + 243,1,224,224,243,1,109,109,117,1,17,17,22,1,173,173,229,1,175,175, + 229,1,134,229,250,1,172,243,255,1,208,245,255,2,172,243,255,1,123,241, + 255,1,73,240,255,1,22,238,255,1,49,230,251,1,200,200,236,1,202,202, + 237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212,240,1,215,215, + 240,1,217,217,241,1,220,220,242,1,222,222,243,1,224,224,243,1,7,7, + 7,1,171,171,228,1,173,173,229,1,175,175,229,1,125,238,254,1,172,243, + 255,1,208,245,255,2,172,243,255,1,123,241,255,1,73,240,255,1,22,238, + 255,1,21,236,254,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207, + 238,1,210,210,239,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220, + 242,1,222,222,243,1,224,224,243,1,7,7,7,1,171,171,228,1,173,173, + 229,1,170,170,222,1,56,107,117,1,137,229,241,1,169,238,250,1,172,243, + 255,1,144,242,255,1,104,241,255,1,59,239,255,1,13,238,255,1,49,230, + 251,1,200,200,236,1,202,202,237,1,182,182,211,1,136,136,201,1,119,119, + 246,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222, + 243,1,224,224,243,1,82,82,88,1,106,106,141,1,173,173,229,1,82,82, + 107,1,21,33,39,1,35,80,85,1,101,198,209,1,123,241,255,1,104,241, + 255,1,73,240,255,1,34,239,255,1,13,238,255,1,110,217,245,1,200,200, + 236,1,202,202,237,1,96,96,113,1,27,27,164,1,12,12,254,1,191,191, + 241,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222,243,1,224,224, + 243,1,227,227,244,1,5,5,7,1,173,173,229,1,137,137,180,1,77,79, + 101,1,33,83,92,1,73,240,255,2,59,239,255,1,34,239,255,1,8,152, + 163,1,13,53,58,1,49,50,59,1,126,126,149,1,176,176,206,1,16,16, + 33,1,0,0,46,1,0,0,208,1,57,57,188,1,61,61,68,1,50,50, + 56,1,80,80,88,1,212,212,232,1,224,224,243,1,227,227,244,1,5,5, + 7,1,173,173,229,1,173,173,226,1,175,175,225,1,171,175,223,1,106,209, + 242,1,54,227,250,1,21,236,254,1,47,228,251,1,13,26,30,1,182,186, + 223,1,189,189,226,1,80,80,94,1,184,184,239,1,6,6,121,1,0,0, + 166,1,0,0,255,1,0,0,80,1,145,145,219,1,215,215,239,1,69,69, + 76,1,145,145,159,1,224,224,243,1,59,59,63,1,44,44,59,1,173,173, + 229,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185, + 232,1,188,188,233,1,190,190,233,1,86,86,105,1,24,24,29,1,85,85, + 102,1,161,161,190,1,73,73,249,1,0,0,121,1,0,0,166,1,0,0, + 255,1,0,0,219,1,20,20,134,1,76,76,85,1,32,32,35,1,137,137, + 150,1,224,224,243,1,7,7,7,1,171,171,228,1,173,173,229,1,175,175, + 229,1,207,111,143,1,208,112,144,1,210,114,144,1,211,115,145,1,213,117, + 145,1,212,117,144,1,190,105,128,1,185,153,185,1,120,120,143,1,15,15, + 24,1,0,0,227,1,0,0,121,1,0,0,166,1,0,0,243,1,0,0, + 32,1,0,0,172,1,112,112,229,1,92,92,102,1,134,134,147,1,224,224, + 243,1,7,7,7,1,171,171,228,1,173,173,229,1,175,175,229,1,255,0, + 0,3,211,0,0,1,164,0,0,1,253,0,0,1,52,0,0,1,148,83, + 100,1,148,148,180,1,5,5,37,1,0,0,235,1,0,0,133,1,0,0, + 107,1,0,0,221,1,0,0,33,1,0,0,206,1,9,9,184,1,19,19, + 24,1,125,125,137,1,224,224,243,1,150,150,162,1,57,57,77,1,173,173, + 229,1,175,175,229,1,255,0,0,3,213,0,0,1,170,0,0,1,255,0, + 0,1,224,0,0,1,119,67,80,1,47,47,111,1,0,0,204,1,0,0, + 255,1,0,0,230,1,0,0,125,1,0,0,210,1,0,0,198,1,0,0, + 115,1,0,0,147,1,64,64,201,1,158,158,172,1,224,224,243,1,227,227, + 244,1,5,5,7,1,173,173,229,1,175,175,229,1,255,0,0,7,218,122, + 147,1,188,188,237,1,187,187,237,1,189,189,238,1,191,191,239,1,192,192, + 239,1,194,194,240,1,195,195,241,1,197,197,241,1,198,198,242,1,201,201, + 243,1,222,222,243,1,224,224,243,1,227,227,244,1,5,5,7,1,173,173, + 229,1,175,175,229,1,255,0,0,7,218,122,147,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212, + 240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222,243,1,224,224, + 243,1,18,18,20,1,88,88,117,1,173,173,229,1,175,175,229,1,255,0, + 0,7,218,122,147,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,212,212,240,1,215,215,240,1,217,217, + 241,1,220,220,242,1,222,222,243,1,224,224,243,1,7,7,7,1,171,171, + 228,1,173,173,229,1,175,175,229,1,255,0,0,7,218,122,147,1,197,197, + 236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222, + 243,1,224,224,243,1,11,11,12,1,171,171,228,1,173,173,229,1,175,175, + 229,1,255,0,0,7,218,122,147,1,197,197,236,1,200,200,236,1,202,202, + 237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212,240,1,215,215, + 240,1,217,217,241,1,220,220,242,1,222,222,243,1,224,224,243,1,227,227, + 244,1,26,26,35,1,173,173,229,1,175,175,229,1,178,178,230,1,180,180, + 231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193, + 234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,212,212,240,1,215,215,240,1,217,217, + 241,1,220,220,242,1,222,222,243,1,224,224,243,1,227,227,244,1,5,5, + 7,1,172,172,227,1,175,175,229,1,178,178,230,1,169,169,217,1,172,172, + 217,1,175,175,219,1,188,188,233,1,190,190,233,1,190,190,230,1,183,183, + 220,1,185,185,221,1,192,192,227,1,202,202,237,1,205,205,238,1,201,201, + 231,1,197,197,224,1,199,199,225,1,211,211,235,1,217,217,241,1,220,220, + 242,1,212,212,232,1,210,210,228,1,168,168,181,1,5,5,7,1,126,126, + 167,1,175,175,229,1,178,178,230,1,10,10,13,1,8,8,10,1,19,19, + 23,1,188,188,233,1,190,190,233,1,116,116,140,1,8,8,10,2,50,50, + 59,1,202,202,237,1,205,205,238,1,71,71,82,1,9,9,10,2,106,106, + 119,1,217,217,241,1,220,220,242,1,34,34,37,1,9,9,10,1,7,7, + 7,1,148,1,0,0,249,249,249,1,245,245,245,1,232,232,232,1,144,144, + 144,2,169,169,169,1,245,245,245,2,207,207,207,1,144,144,144,2,194,194, + 194,1,245,245,245,2,178,178,178,1,144,144,144,2,223,223,223,1,245,245, + 245,2,153,153,153,1,144,144,144,1,147,147,147,1,249,249,249,1,143,143, + 143,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,218,218, + 218,1,128,128,128,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,173,173,173,1,233,233, + 233,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,188,188,188,1,158,158,158,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,203,203,203,2,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,154,154, + 154,1,191,191,191,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,236,236,236,1,169,169, + 169,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,244,244, + 244,1,128,128,128,1,255,255,255,22,128,128,128,1,221,221,221,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,147,147,147,1,231,231, + 231,1,132,132,132,1,112,112,112,2,238,238,238,1,242,242,242,1,226,226, + 226,1,112,112,112,2,145,145,145,1,242,242,242,2,193,193,193,1,112,112, + 112,2,177,177,177,1,242,242,242,2,156,156,156,1,112,112,112,2,214,214, + 214,1,242,242,242,1,231,231,231,1,0,0) + ); + +initialization + registerobjectdata(@objdata_tfilelistview,tbitmapcomp,'tfilelistview'); + registerobjectdata(@objdata_tdirtreeview,tbitmapcomp,'tdirtreeview'); + registerobjectdata(@objdata_tfiledialog,tbitmapcomp,'tfiledialog'); + registerobjectdata(@objdata_tfilenameedit,tbitmapcomp,'tfilenameedit'); + registerobjectdata(@objdata_tdirdropdownedit,tbitmapcomp,'tdirdropdownedit'); + registerobjectdata(@objdata_tcoloredit,tbitmapcomp,'tcoloredit'); + registerobjectdata(@objdata_tdialogstringedit,tbitmapcomp,'tdialogstringedit'); + registerobjectdata(@objdata_tmemodialogedit,tbitmapcomp,'tmemodialogedit'); + registerobjectdata(@objdata_tguirttistat,tbitmapcomp,'tguirttistat'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regeditwidgets.pas b/mseide-msegui/lib/common/regcomponents/regeditwidgets.pas new file mode 100644 index 0000000..615b2da --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regeditwidgets.pas @@ -0,0 +1,403 @@ +{ MSEide Copyright (c) 1999-2011 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regeditwidgets; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + classes,mclasses,mseedit,msedataedits,msegraphedits, + msedataimage,mselistbrowser,msecalendardatetimeedit, + msewidgetgrid,msetextedit,msedesignintf,regeditwidgets_bmp,msepropertyeditors, + msedropdownlist,mseterminal,msedrawtext,msedatanodes,{msedialog,} + msetypes,msestrings, + regwidgets,msearrayprops,typinfo,msestockobjects,msefoldedit,msebitmap,mseglob, + msestream,mserealsumedit,msedatalist,msegui,msegrids,msesumlist,mseclasses, + sysutils,regglob,msearrayutils,mseeditglob; + +type + tpropertyeditor1 = class(tpropertyeditor); + tdropdowndatacolpropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + titemlistpropertyeditor = class(tdatalistpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + twidgetcolelementeditor = class(tdatacoleditor) + public + function getvalue: msestring; override; + end; + + twidgetcolspropertyeditor = class(tdatacolseditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tdataimagepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + function getvalue: msestring; override; + end; + + tdatalistsourcepropertyeditor = class(tstringpropertyeditor) + protected + function gettag: integer; virtual; + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tsumlistsourcelevelpropertyeditor = + class(tdatalistsourcepropertyeditor) + protected + function gettag: integer; override; + public + function getvalues: msestringarty; override; + end; + + tsumlistsourceissumpropertyeditor = + class(tdatalistsourcepropertyeditor) + protected + function gettag: integer; override; + end; + + trowstatelistsourcefoldlevelpropertyeditor = + class(tdatalistsourcepropertyeditor) + protected + function gettag: integer; override; + end; + + trowstatelistsourcefoldhiddenpropertyeditor = + class(tdatalistsourcepropertyeditor) + protected + function gettag: integer; override; + end; + + trowstatelistsourceissumpropertyeditor = + class(tdatalistsourcepropertyeditor) + protected + function gettag: integer; override; + end; + + toptionswidgetpropertyeditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + toptionseditpropertyeditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + tvalueeditpropertyeditor = class(tclasselementeditor) + public + procedure navigevent(); override; + end; + + tvalueeditspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function itemgetvalue(const sender: tarrayelementeditor): msestring; + override; +// function geteditorclass: propertyeditorclassty; override; + end; + + titemvalueeditpropertyeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + end; + +procedure Register; +begin + registercomponents('Edit',[twidgetgrid, + tstringedit,tmemoedit,trichmemoedit, + tintegeredit,tint64edit,trealedit,trealspinedit,trealsumedit, + tdatetimeedit, + tcalendardatetimeedit, + tbooleanedit,tbooleaneditradio, + tdatabutton,tstockglyphdatabutton, + tdataicon,tdataimage, + tslider,tprogressbar, + tfoldedit, + titemedit,tdropdownitemedit,{tmbdropdownitemedit,}ttreeitemedit, + trecordfieldedit, + thexstringedit,tpointeredit, + tdropdownlistedit,thistoryedit, + tenumedit,tenumtypeedit,tselector, + tkeystringedit, + {tstringlistedit,} + ttextedit,tundotextedit,tterminal +]); + registercomponenttabhints(['Edit'], + ['Edit widgets, twidgetgrid and widgets'+c_linefeed+ + 'which can be placed into twidgetgrid']); + registerpropertyeditor(tdropdowndatacols.classinfo,nil,'', + tdropdowndatacolpropertyeditor); + registerpropertyeditor(ttabulators.classinfo,tcustomtextedit,'tabulators', + toptionalpersistentarraypropertyeditor); + registerpropertyeditor(tcustomitemlist.classinfo,nil,'', + titemlistpropertyeditor); + registerpropertyeditor(typeinfo(twidgetcols),nil,'',twidgetcolspropertyeditor); + registerpropertyeditor(typeinfo(tintegerarrayprop),tstockglyphdatabutton,'', + tstockglypharraypropertyeditor); + registerpropertyeditor(typeinfo(string),tdataimage,'value', + tdataimagepropertyeditor); + registerpropertyeditor(typeinfo(tmaskedbitmap),tdataimage,'bitmap', + tclasspropertyeditor); + registerpropertyeditor(typeinfo(string),tdatalist,'sourcevalue', + tdatalistsourcepropertyeditor); + registerpropertyeditor(typeinfo(string),trealsumlist,'sourcelevel', + tsumlistsourcelevelpropertyeditor); + registerpropertyeditor(typeinfo(string),trealsumlist,'sourceissum', + tsumlistsourceissumpropertyeditor); + registerpropertyeditor(typeinfo(optionswidgetty),nil,'', + toptionswidgetpropertyeditor); + registerpropertyeditor(typeinfo(optionseditty),nil,'', + toptionseditpropertyeditor); + registerpropertyeditor(typeinfo(string),trowstatelist,'sourcefoldlevel', + trowstatelistsourcefoldlevelpropertyeditor); + registerpropertyeditor(typeinfo(string),trowstatelist,'sourcefoldhidden', + trowstatelistsourcefoldhiddenpropertyeditor); + registerpropertyeditor(typeinfo(string),trowstatelist,'sourceissum', + trowstatelistsourceissumpropertyeditor); + registerpropertyeditor(typeinfo(boolean),tcustomdatabutton,'visible', + trefreshbooleanpropertyeditor); + registerpropertyeditor(typeinfo(boolean),tcustomdatabutton,'enabled', + trefreshbooleanpropertyeditor); + registerpropertyeditor(typeinfo(tvalueedits),nil,'',tvalueeditspropertyeditor); + registerpropertyeditor(typeinfo(twidget),tvalueedititem,'', + titemvalueeditpropertyeditor); + registerpropertyeditor(typeinfo(msestring),tcustomrichmemoedit,'value', + trichstringpropertyeditor); +end; + +{ tdropdowndatacolpropertyeditor } + +function tdropdowndatacolpropertyeditor.geteditorclass: propertyeditorclassty; +var + obj1: tobject; +begin + pointer(obj1):= getpointervalue(); + if (obj1 is tdropdowncols) and tdropdowncols(obj1).nostreaming then begin + result:= tclasselementeditor; + end + else begin + result:= tmsestringdatalistpropertyeditor; + end; +end; + +{ titemlistpropertyeditor } + +function titemlistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate - [ps_dialog]; +end; + +{ twidgetcolelementeditor } + +function twidgetcolelementeditor.getvalue: msestring; +var + col1: twidgetcol; +begin + col1:= twidgetcol(getpointervalue); + result:= inherited getvalue; + if col1.editwidget <> nil then begin + result:= result + msestring('<'+col1.editwidget.name+'>'); + end + else begin + result:= result + '<>'; + end; +end; + +{ twidgetcolspropertyeditor } + +function twidgetcolspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= twidgetcolelementeditor; +end; + +{ tdataimagepropertyeditor } + +function tdataimagepropertyeditor.getvalue: msestring; +begin + if tcustomdataimage(fcomponent).bitmap.isempty then begin + result:= ''; + end + else begin + result:= ''; + end; +end; + +function tdataimagepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tdataimagepropertyeditor.edit; +var + mstr1: filenamety; + format1: string; + int1: integer; +begin + if imagefilepropedit(mstr1,format1) = mr_ok then begin + for int1:= 0 to high(fprops) do begin + tdataimage(fprops[int1].instance).value:= readfiledatastring(mstr1); + end; + modified; + end; +end; + +{ tdatalistsourcepropertyeditor } + +function tdatalistsourcepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tdatalistsourcepropertyeditor.getvalues: msestringarty; +var + int1: integer; +begin + result:= nil; + if fcomponent is tcustomgrid then begin + with tcustomgrid(fcomponent).datacols do begin + for int1:= 0 to count -1 do begin + with cols[int1] do begin + if (name <> '') and + (tdatalist(fprops[0].instance).canlink(datalist,gettag)) then begin + additem(result,msestring(name)); + end; + end; + end; + end; + end; +end; + +function tdatalistsourcepropertyeditor.gettag: integer; +begin + result:= 0; +end; + +{ tsumlistsourcelevelpropertyeditor } + +function tsumlistsourcelevelpropertyeditor.getvalues: msestringarty; +begin + result:= inherited getvalues; +// additem(result,foldlevelsumname); +end; + +function tsumlistsourcelevelpropertyeditor.gettag: integer; +begin + result:= sumleveltag; +end; + +{ tsumlistsourceissumpropertyeditor } + +function tsumlistsourceissumpropertyeditor.gettag: integer; +begin + result:= sumissumtag; +end; + +{ toptionswidgetpropertyeditor } + +function toptionswidgetpropertyeditor.getinvisibleitems: tintegerset; +begin + result:= invisibleoptionswidget; +end; + +{ toptionseditpropertyeditor } + +function toptionseditpropertyeditor.getinvisibleitems: tintegerset; +begin + result:= invisibleoptionsedit; +end; + +{ trowstatelistsourcefoldlevelpropertyeditor } + +function trowstatelistsourcefoldlevelpropertyeditor.gettag: integer; +begin + result:= rowstatefoldleveltag; +end; + +{ trowstatelistsourceissumpropertyeditor } + +function trowstatelistsourceissumpropertyeditor.gettag: integer; +begin + result:= rowstateissumtag; +end; + +{ trowstatelistsourcefoldhiddenpropertyeditor } + +function trowstatelistsourcefoldhiddenpropertyeditor.gettag: integer; +begin + result:= rowstatefoldhiddentag; +end; + +{ titemvalueeditpropertyeditor } + +function titemvalueeditpropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +var + intf1: igridwidget; +begin + result:= (acomponent is twidget) and + ((twidget(acomponent).parentwidget) = + tvalueedititem(tpropertyeditor1(parenteditor).getpointervalue()).owner) and + getcorbainterface(acomponent,typeinfo(igridwidget),intf1); +end; + +function tvalueeditspropertyeditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + with tvalueedititem( + tpropertyeditor1(sender.valueeditor).getpointervalue()) do begin + if editwidget <> nil then begin + result:= msestring('<'+inttostr(valueindex)+'>'+'<'+editwidget.name+'>'); + end + else begin + result:= '<>'; + end; + end; +end; + +function tvalueeditspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tvalueeditpropertyeditor; +end; + +{ tvalueeditpropertyeditor } + +procedure tvalueeditpropertyeditor.navigevent; +begin + with tvalueedititem(getpointervalue()) do begin + if editwidget <> nil then begin + editwidget.bringtofront(); + end; + end; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regeditwidgets_bmp.pas b/mseide-msegui/lib/common/regcomponents/regeditwidgets_bmp.pas new file mode 100644 index 0000000..418388d --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regeditwidgets_bmp.pas @@ -0,0 +1,1974 @@ +unit regeditwidgets_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_twidgetgrid: record size: integer; data: array[0..1350] of byte end = + (size: 1351; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,119,105, + 100,103,101,116,103,114,105,100,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,208,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,140,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,2,128,128,128, + 1,208,208,208,2,112,112,112,1,153,153,153,1,171,171,171,1,165,165,165, + 1,118,118,118,1,184,184,184,1,208,208,208,2,128,128,128,1,208,208,208, + 2,154,154,154,1,148,148,148,1,190,190,190,1,186,186,186,1,148,148,148, + 1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,1,179,179,179,1,142,142,142,1,116,116,116,1,148,148,148, + 1,141,141,141,1,121,121,121,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,2,144,144,144,2,131,131,131,1,146,146,146,1,165,165,165, + 1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,4,175,175,175,1,176,176,176,1,208,208,208,4,128,128,128, + 1,208,208,208,2,186,186,186,1,183,183,183,1,187,187,187,1,191,191,191, + 1,197,197,197,1,208,208,208,1,255,255,255,1,128,128,128,23,255,255,255, + 1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,169,169,169, + 1,183,183,183,1,202,202,202,1,215,215,215,1,225,225,225,1,255,255,255, + 4,128,128,128,1,255,255,255,2,243,243,243,1,169,169,169,1,204,204,204, + 1,179,179,179,1,139,139,139,1,255,255,255,2,128,128,128,1,208,208,208, + 2,128,128,128,1,255,255,255,1,151,151,151,1,160,160,160,1,155,155,155, + 1,201,201,201,1,225,225,225,1,255,255,255,4,128,128,128,1,255,255,255, + 3,191,191,191,1,150,150,150,1,202,202,202,1,158,158,158,1,251,251,251, + 1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255, + 1,237,237,237,1,233,233,233,1,228,228,228,1,213,213,213,1,222,222,222, + 1,255,255,255,4,128,128,128,1,255,255,255,9,128,128,128,23,255,255,255, + 1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,206,206,206, + 1,168,168,168,1,211,211,211,1,238,238,238,1,226,226,226,1,242,242,242, + 1,191,191,191,1,201,201,201,1,251,251,251,1,128,128,128,1,255,255,255, + 4,176,176,176,2,129,129,129,1,255,255,255,2,128,128,128,1,208,208,208, + 2,128,128,128,1,255,255,255,1,181,181,181,1,236,236,236,1,145,145,145, + 1,170,170,170,1,181,181,181,1,162,162,162,1,190,190,190,1,185,185,185, + 1,255,255,255,1,128,128,128,1,255,255,255,4,186,186,186,1,211,211,211, + 1,159,159,159,1,255,255,255,2,128,128,128,1,208,208,208,2,128,128,128, + 1,255,255,255,1,199,199,199,1,210,210,210,1,209,209,209,1,237,237,237, + 1,238,238,238,1,235,235,235,1,220,220,220,1,199,199,199,1,248,248,248, + 1,128,128,128,1,255,255,255,9,128,128,128,23,255,255,255,1,128,128,128, + 1,208,208,208,2,128,128,128,1,255,255,255,1,197,197,197,1,177,177,177, + 1,221,221,221,1,255,255,255,6,128,128,128,1,255,255,255,4,169,169,169, + 1,158,158,158,1,157,157,157,1,255,255,255,2,128,128,128,1,208,208,208, + 2,128,128,128,1,255,255,255,1,176,176,176,1,190,190,190,1,181,181,181, + 1,255,255,255,6,128,128,128,1,255,255,255,4,178,178,178,1,161,161,161, + 1,158,158,158,1,255,255,255,2,128,128,128,1,208,208,208,2,128,128,128, + 1,255,255,255,1,235,235,235,1,217,217,217,1,239,239,239,1,255,255,255, + 6,128,128,128,1,255,255,255,9,128,128,128,23,255,255,255,1,128,128,128, + 1,208,208,208,2,128,128,128,1,255,255,255,1,174,174,174,1,177,177,177, + 1,201,201,201,1,232,232,232,1,221,221,221,1,182,182,182,1,212,212,212, + 1,255,255,255,2,128,128,128,1,255,255,255,2,228,228,228,1,163,163,163, + 1,191,191,191,1,184,184,184,1,139,139,139,1,255,255,255,2,128,128,128, + 1,208,208,208,2,128,128,128,1,255,255,255,1,158,158,158,1,207,207,207, + 1,120,120,120,1,176,176,176,1,175,175,175,1,183,183,183,1,142,142,142, + 1,255,255,255,2,128,128,128,1,255,255,255,2,212,212,212,1,152,152,152, + 1,204,204,204,1,178,178,178,1,158,158,158,1,251,251,251,1,255,255,255, + 1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,237,237,237, + 1,255,255,255,1,239,239,239,1,203,203,203,1,166,166,166,1,239,239,239, + 1,180,180,180,1,255,255,255,2,128,128,128,1,255,255,255,9,128,128,128, + 23,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255, + 1,199,199,199,2,226,226,226,1,228,228,228,1,233,233,233,1,255,255,255, + 4,128,128,128,1,255,255,255,4,172,172,172,1,197,197,197,1,137,137,137, + 1,255,255,255,2,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255, + 1,183,183,183,1,176,176,176,1,183,183,183,1,173,173,173,1,130,130,130, + 1,255,255,255,4,128,128,128,1,255,255,255,4,208,208,208,1,215,215,215, + 1,168,168,168,1,254,254,254,1,255,255,255,25,12,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdataedit: record size: integer; data: array[0..429] of byte end = + (size: 430; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,100,97, + 116,97,101,100,105,116,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 128,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 76,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,146, + 128,128,128,20,255,0,255,4,128,128,128,1,0,0,0,18,255,255,255,1, + 255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,16,192,192,192,1, + 255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,13, + 0,0,0,1,255,255,255,1,0,0,0,1,192,192,192,1,255,255,255,1, + 255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,14,0,0,0,1, + 255,255,255,1,192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1, + 0,0,0,1,255,255,255,14,0,0,0,1,255,255,255,1,192,192,192,1, + 255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,14, + 0,0,0,1,255,255,255,1,192,192,192,1,255,255,255,1,255,0,255,4, + 128,128,128,1,0,0,0,1,255,255,255,14,0,0,0,1,255,255,255,1, + 192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1, + 255,255,255,14,0,0,0,1,255,255,255,1,192,192,192,1,255,255,255,1, + 255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,13,0,0,0,1, + 255,255,255,1,0,0,0,1,192,192,192,1,255,255,255,1,255,0,255,4, + 128,128,128,1,0,0,0,1,255,255,255,16,192,192,192,1,255,255,255,1, + 255,0,255,4,128,128,128,1,192,192,192,18,255,255,255,1,255,0,255,4, + 255,255,255,20,255,0,255,122,0,0) + ); + +const + objdata_ttextedit: record size: integer; data: array[0..1624] of byte end = + (size: 1625; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,116,101, + 120,116,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,228,5,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,152,5,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,140,140,140,1,148,148,148,1,226, + 226,226,1,209,209,209,1,222,222,222,2,175,175,175,1,242,242,242,1,132, + 132,132,1,210,210,210,1,215,215,215,1,226,226,226,1,190,190,190,1,209, + 209,209,1,165,165,165,1,210,210,210,1,208,208,208,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,138, + 138,138,1,183,183,183,1,190,190,190,1,133,133,133,1,179,179,179,1,177, + 177,177,1,183,183,183,1,255,255,255,1,154,154,154,1,192,192,192,1,140, + 140,140,1,180,180,180,1,195,195,195,1,213,213,213,1,156,156,156,1,169, + 169,169,1,155,155,155,1,255,255,255,2,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,211,211,211,1,255,255,255,1,208, + 208,208,1,178,178,178,1,204,204,204,1,205,205,205,1,200,200,200,1,255, + 255,255,1,202,202,202,1,231,231,231,1,191,191,191,1,219,219,219,1,203, + 203,203,1,234,234,234,1,220,220,220,1,183,183,183,1,167,167,167,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,6,193,193,193,1,209,209,209,1,220,220,220,1,255,255,255,1,195, + 195,195,1,255,255,255,4,224,224,224,1,255,255,255,1,232,232,232,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,175,175,175,2,170,170,170,1,204,204,204,2,222,222,222,1,170, + 170,170,1,159,159,159,1,193,193,193,1,149,149,149,1,151,151,151,1,178, + 178,178,1,191,191,191,1,202,202,202,1,145,145,145,1,255,255,255,4,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,164, + 164,164,1,151,151,151,1,118,118,118,1,223,223,223,1,226,226,226,1,162, + 162,162,1,149,149,149,1,159,159,159,1,171,171,171,1,175,175,175,2,131, + 131,131,1,178,178,178,1,134,134,134,1,176,176,176,1,255,255,255,4,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,197, + 197,197,1,199,199,199,1,255,255,255,3,254,254,254,1,255,255,255,13,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,124, + 124,124,1,216,216,216,1,229,229,229,1,209,209,209,1,226,226,226,1,247, + 247,247,1,238,238,238,1,212,212,212,1,182,182,182,1,178,178,178,1,236, + 236,236,1,217,217,217,1,137,137,137,1,213,213,213,1,207,207,207,1,186, + 186,186,1,255,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,175,175,175,1,169,169,169,1,163,163,163,1,164, + 164,164,1,156,156,156,1,137,137,137,1,229,229,229,1,166,166,166,1,254, + 254,254,1,166,166,166,1,176,176,176,1,177,177,177,1,156,156,156,1,192, + 192,192,1,188,188,188,1,173,173,173,1,255,255,255,3,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,215,215,215,1,167, + 167,167,1,157,157,157,1,184,184,184,1,202,202,202,1,152,152,152,1,255, + 255,255,1,244,244,244,1,177,177,177,1,212,212,212,1,206,206,206,1,242, + 242,242,1,203,203,203,1,236,236,236,1,184,184,184,1,214,214,214,1,255, + 255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,197,197,197,1,160,160,160,1,214,214,214,1,218,218,218,1,255, + 255,255,2,253,253,253,1,255,255,255,1,216,216,216,1,145,145,145,1,222, + 222,222,1,255,255,255,1,228,228,228,1,255,255,255,2,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,176,176,176,1,145,145,145,1,150, + 150,150,1,175,175,175,1,168,168,168,1,175,175,175,1,110,110,110,1,216, + 216,216,1,255,255,255,1,175,175,175,1,231,231,231,1,122,122,122,1,173, + 173,173,1,255,255,255,3,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,185,185,185,1,235, + 235,235,1,166,166,166,1,195,195,195,1,182,182,182,1,188,188,188,1,177, + 177,177,1,203,203,203,1,255,255,255,1,195,195,195,1,200,200,200,1,169, + 169,169,1,171,171,171,1,255,255,255,3,0,0,0,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,242, + 242,242,1,255,255,255,3,235,235,235,1,240,240,240,1,255,255,255,6,208, + 208,208,1,255,255,255,3,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,175,175,175,1,226, + 226,226,1,221,221,221,1,222,222,222,1,132,132,132,1,175,175,175,1,183, + 183,183,1,216,216,216,1,189,189,189,1,196,196,196,1,213,213,213,1,255, + 255,255,5,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,183,183,183,1,126,126,126,1,238, + 238,238,1,163,163,163,1,154,154,154,1,149,149,149,1,195,195,195,1,152, + 152,152,1,221,221,221,1,169,169,169,1,184,184,184,1,255,255,255,5,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,234,234,234,1,162,162,162,1,255,255,255,1,234, + 234,234,1,255,255,255,1,217,217,217,1,215,215,215,1,246,246,246,1,214, + 214,214,1,219,219,219,1,232,232,232,1,255,255,255,5,0,0,0,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,16,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,20, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,42,128,128,128,1,255, + 255,255,23,0,0) + ); + +const + objdata_tundotextedit: record size: integer; data: array[0..1608] of byte end = + (size: 1609; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,117,110, + 100,111,116,101,120,116,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,208,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,132,5,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,140,140,140,1,148, + 148,148,1,226,226,226,1,209,209,209,1,222,222,222,2,175,175,175,1,242, + 242,242,1,132,132,132,1,210,210,210,1,215,215,215,1,226,226,226,1,190, + 190,190,1,209,209,209,1,165,165,165,1,210,210,210,1,208,208,208,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,138,138,138,1,183,183,183,1,190,190,190,1,133,133,133,1,179, + 179,179,1,177,177,177,1,183,183,183,1,255,255,255,1,154,154,154,1,192, + 192,192,1,140,140,140,1,180,180,180,1,195,195,195,1,213,213,213,1,156, + 156,156,1,169,169,169,1,155,155,155,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,211,211,211,1,255, + 255,255,1,21,21,218,1,16,16,215,1,18,18,217,1,191,191,206,1,200, + 200,200,1,255,255,255,1,202,202,202,1,231,231,231,1,188,188,191,1,20, + 20,219,1,18,18,217,1,21,21,220,1,212,212,220,1,183,183,183,1,167, + 167,167,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,3,2,2,219,1,0,0,219,2,179,179,194,1,209, + 209,209,1,220,220,220,1,255,255,255,1,195,195,195,1,250,250,254,1,0, + 0,219,3,215,215,224,1,255,255,255,1,232,232,232,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,175, + 175,175,2,1,1,218,1,0,0,219,2,206,206,221,1,170,170,170,1,159, + 159,159,1,193,193,193,1,149,149,149,1,148,148,152,1,0,0,219,3,139, + 139,148,1,255,255,255,4,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,164,164,164,1,151,151,151,1,1,1,218,1,0, + 0,219,2,151,151,166,1,149,149,149,1,159,159,159,1,171,171,171,1,175, + 175,175,1,172,172,176,1,0,0,219,3,169,169,178,1,255,255,255,4,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,197, + 197,197,1,199,199,199,1,2,2,219,1,0,0,219,2,236,236,251,1,255, + 255,255,4,250,250,254,1,0,0,219,3,245,245,254,1,255,255,255,4,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,124, + 124,124,1,216,216,216,1,2,2,219,1,0,0,219,2,230,230,245,1,238, + 238,238,1,212,212,212,1,182,182,182,1,178,178,178,1,231,231,235,1,0, + 0,219,3,199,199,208,1,186,186,186,1,255,255,255,3,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,175,175,175,1,169, + 169,169,1,1,1,218,1,0,0,219,2,127,127,142,1,229,229,229,1,166, + 166,166,1,254,254,254,1,166,166,166,1,173,173,177,1,0,0,219,3,181, + 181,190,1,173,173,173,1,255,255,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,215,215,215,1,167,167,167,1,2, + 2,218,1,0,0,219,2,141,141,157,1,255,255,255,1,244,244,244,1,177, + 177,177,1,212,212,212,1,202,202,206,1,0,0,219,3,178,178,185,1,214, + 214,214,1,255,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,197,197,197,1,160,160,160,1,18,18,219,1,0, + 0,219,2,229,229,251,1,253,253,253,1,255,255,255,1,216,216,216,1,145, + 145,145,1,212,212,222,1,0,0,219,2,6,6,220,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,176,176,176,1,145, + 145,145,1,25,25,207,1,0,0,219,2,150,150,181,1,110,110,110,1,216, + 216,216,1,255,255,255,1,175,175,175,1,208,208,229,1,0,0,219,2,24, + 24,222,1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,185,185,185,1,235, + 235,235,1,43,43,205,1,0,0,219,2,108,108,201,1,177,177,177,1,203, + 203,203,1,255,255,255,1,195,195,195,1,144,144,205,1,0,0,219,2,41, + 41,225,1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,242,242,242,1,255, + 255,255,1,121,121,236,1,0,0,219,2,10,10,220,1,161,161,242,1,230, + 230,251,1,242,242,253,1,181,181,245,1,36,36,224,1,0,0,219,2,102, + 102,233,1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,175,175,175,1,226, + 226,226,1,206,206,221,1,18,18,219,1,0,0,219,4,2,2,218,1,0, + 0,219,3,7,7,220,1,225,225,251,1,255,255,255,2,0,0,0,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,183,183,183,1,126,126,126,1,238,238,238,1,145,145,169,1,40, + 40,201,1,0,0,219,6,52,52,226,1,210,210,249,1,255,255,255,3,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,234,234,234,1,162,162,162,1,255,255,255,1,234, + 234,234,1,255,255,255,1,192,192,217,1,160,160,216,1,148,148,236,1,118, + 118,216,1,153,153,219,1,197,197,230,1,253,253,255,1,255,255,255,4,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,16,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,25,20,0,0,0,255,255,255,255,255,255,255,255,255,255,255,42,128, + 128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tslider: record size: integer; data: array[0..1106] of byte end = + (size: 1107; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,108, + 105,100,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,224,3,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,152,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0,22,255,255,255, + 1,128,128,128,1,0,0,0,1,208,208,208,1,255,255,255,1,208,208,208, + 1,249,249,249,1,208,208,208,1,255,255,255,1,208,208,208,1,248,248,248, + 1,209,209,209,1,255,255,255,5,208,208,208,1,252,252,252,1,212,212,212, + 1,251,251,251,1,208,208,208,1,251,251,251,1,225,225,225,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,209,209,209,1,249,249,249, + 1,214,214,214,1,255,255,255,1,208,208,208,1,247,247,247,1,217,217,217, + 1,251,251,251,1,255,255,255,1,227,227,227,3,138,138,138,1,247,247,247, + 1,208,208,208,1,247,247,247,1,215,215,215,1,255,255,255,1,211,211,211, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,208,208,208, + 1,255,255,255,1,212,212,212,1,248,248,248,1,212,212,212,1,248,248,248, + 1,216,216,216,1,249,249,249,1,212,212,212,1,255,255,255,1,218,218,218, + 3,129,129,129,1,213,213,213,1,252,252,252,1,212,212,212,1,255,255,255, + 1,208,208,208,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,208,208,208,1,248,248,248,1,215,215,215, + 1,255,255,255,1,211,211,211,1,255,255,255,1,211,211,211,1,255,255,255, + 2,208,208,208,3,128,128,128,1,255,255,255,1,209,209,209,1,255,255,255, + 1,208,208,208,1,252,252,252,1,211,211,211,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,208,208,208,1,255,255,255,1,211,211,211, + 1,254,254,254,1,209,209,209,1,251,251,251,1,212,212,212,1,249,249,249, + 1,211,211,211,1,255,255,255,1,199,199,199,3,128,128,128,1,208,208,208, + 1,255,255,255,1,208,208,208,1,255,255,255,1,208,208,208,1,249,249,249, + 1,228,228,228,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 1,209,209,209,1,254,254,254,1,208,208,208,1,255,255,255,1,208,208,208, + 1,255,255,255,1,211,211,211,1,247,247,247,1,255,255,255,1,190,190,190, + 3,128,128,128,1,248,248,248,1,212,212,212,1,251,251,251,1,212,212,212, + 1,255,255,255,1,208,208,208,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,208,208,208,1,255,255,255,1,208,208,208,1,251,251,251, + 1,212,212,212,1,255,255,255,1,208,208,208,1,255,255,255,1,211,211,211, + 1,255,255,255,1,180,180,180,3,128,128,128,1,211,211,211,1,251,251,251, + 1,209,209,209,1,248,248,248,1,215,215,215,1,249,249,249,1,228,228,228, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,208,208,208, + 1,255,255,255,1,208,208,208,1,255,255,255,1,208,208,208,1,255,255,255, + 1,208,208,208,1,255,255,255,2,171,171,171,3,128,128,128,1,254,254,254, + 1,212,212,212,1,255,255,255,1,208,208,208,1,255,255,255,1,209,209,209, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,208,208,208, + 1,255,255,255,1,208,208,208,1,255,255,255,1,209,209,209,1,255,255,255, + 1,209,209,209,1,255,255,255,1,208,208,208,1,255,255,255,1,167,167,167, + 3,128,128,128,1,208,208,208,1,255,255,255,1,208,208,208,1,255,255,255, + 1,208,208,208,1,251,251,251,1,226,226,226,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,211,211,211,1,248,248,248,1,208,208,208, + 1,249,249,249,1,212,212,212,1,249,249,249,1,212,212,212,1,249,249,249, + 1,131,131,131,1,128,128,128,4,252,252,252,1,209,209,209,1,252,252,252, + 1,209,209,209,1,255,255,255,1,208,208,208,1,224,224,224,1,255,255,255, + 1,128,128,128,1,224,224,224,3,227,227,227,1,224,224,224,5,227,227,227, + 1,224,224,224,5,225,225,225,1,224,224,224,1,225,225,225,1,224,224,224, + 4,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tbooleanedit: record size: integer; data: array[0..488] of byte end = + (size: 489; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,98,111, + 111,108,101,97,110,101,100,105,116,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,184,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,132,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 0,255,125,128,128,128,14,255,0,255,10,128,128,128,1,0,0,0,12,255, + 255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255,255,255,10,192, + 192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255, + 255,255,1,0,0,0,2,255,255,255,4,0,0,0,2,255,255,255,1,192, + 192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255, + 255,255,1,0,0,0,3,255,255,255,2,0,0,0,3,255,255,255,1,192, + 192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255, + 255,255,2,0,0,0,6,255,255,255,2,192,192,192,1,255,255,255,1,255, + 0,255,10,128,128,128,1,0,0,0,1,255,255,255,3,0,0,0,4,255, + 255,255,3,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0, + 0,0,1,255,255,255,3,0,0,0,4,255,255,255,3,192,192,192,1,255, + 255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255,255,255,2,0, + 0,0,6,255,255,255,2,192,192,192,1,255,255,255,1,255,0,255,10,128, + 128,128,1,0,0,0,1,255,255,255,1,0,0,0,3,255,255,255,2,0, + 0,0,3,255,255,255,1,192,192,192,1,255,255,255,1,255,0,255,10,128, + 128,128,1,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,4,0, + 0,0,2,255,255,255,1,192,192,192,1,255,255,255,1,255,0,255,10,128, + 128,128,1,0,0,0,1,255,255,255,10,192,192,192,1,255,255,255,1,255, + 0,255,10,128,128,128,1,192,192,192,12,255,255,255,1,255,0,255,10,255, + 255,255,14,255,0,255,125,0,0) + ); + +const + objdata_tbooleaneditradio: record size: integer; data: array[0..445] of byte end = + (size: 446; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,98,111, + 111,108,101,97,110,101,100,105,116,114,97,100,105,111,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,136,1,0,0,0,0,0,0,0,0,0,0, + 24,0,0,0,24,0,0,0,84,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,255,125,128,128,128,14,255,0,255,10,128,128,128,1, + 0,0,0,12,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1, + 255,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1, + 0,0,0,1,255,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10, + 128,128,128,1,0,0,0,1,255,255,255,4,0,0,0,2,255,255,255,4, + 192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1, + 255,255,255,3,0,0,0,4,255,255,255,3,192,192,192,1,255,255,255,1, + 255,0,255,10,128,128,128,1,0,0,0,1,255,255,255,2,0,0,0,6, + 255,255,255,2,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1, + 0,0,0,1,255,255,255,2,0,0,0,6,255,255,255,2,192,192,192,1, + 255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255,255,255,3, + 0,0,0,4,255,255,255,3,192,192,192,1,255,255,255,1,255,0,255,10, + 128,128,128,1,0,0,0,1,255,255,255,4,0,0,0,2,255,255,255,4, + 192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1, + 255,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1, + 0,0,0,1,255,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10, + 128,128,128,1,192,192,192,12,255,255,255,1,255,0,255,10,255,255,255,14, + 255,0,255,125,0,0) + ); + +const + objdata_tdataicon: record size: integer; data: array[0..1320] of byte end = + (size: 1321; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,100,97, + 116,97,105,99,111,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,180,4,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,88,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128,128,1,255, + 255,255,20,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,5,255, + 244,240,1,254,228,218,1,251,213,198,1,247,201,182,1,243,186,164,1,239, + 180,153,1,238,181,155,1,237,183,159,1,239,197,178,1,248,230,222,1,255, + 255,254,1,255,255,255,4,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,3,255,243,239,1,254,214,198,1,250,200,179,1,246,192,169,1,243, + 184,159,1,239,176,149,1,235,168,139,1,231,160,129,1,227,152,119,1,223, + 144,109,1,219,136,98,1,215,128,88,1,218,137,101,1,243,219,208,1,255, + 255,255,3,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,2,255, + 238,231,1,250,200,181,1,247,192,170,1,243,184,160,1,239,177,150,1,235, + 168,140,1,231,161,129,1,227,153,119,1,223,145,109,1,220,137,99,1,216, + 129,89,1,212,121,79,1,208,113,69,1,204,105,58,1,200,98,50,1,233, + 194,176,1,255,255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,2,248,203,185,1,243,185,160,1,239,177,150,1,235,169,140,1,231, + 161,130,1,228,153,120,1,224,145,110,1,220,137,100,1,216,129,89,1,212, + 121,79,1,208,113,69,1,204,105,59,1,200,97,49,1,197,89,39,1,193, + 82,29,1,200,104,59,1,255,255,255,2,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,2,243,196,176,1,236,169,141,1,232,162,131,1,228, + 154,120,1,224,146,110,1,220,138,100,1,216,130,90,1,212,122,80,1,208, + 114,70,1,205,106,60,1,201,98,50,1,197,90,39,1,193,82,29,1,189, + 74,19,1,185,66,9,1,200,107,62,1,255,255,255,2,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,2,249,231,223,1,229,160,128,1,224, + 146,111,1,220,138,101,1,216,130,91,1,213,122,81,1,209,114,70,1,205, + 106,60,1,201,98,50,1,197,90,40,1,193,82,30,1,189,74,20,1,185, + 67,10,1,182,59,0,1,186,70,14,1,236,205,190,1,255,255,255,2,128, + 128,128,1,171,171,171,2,128,128,128,1,255,255,255,3,250,240,235,1,228, + 166,138,1,214,125,84,1,209,115,71,1,205,107,61,1,201,99,51,1,197, + 91,41,1,193,83,31,1,189,75,20,1,186,67,10,1,182,59,0,1,183, + 62,4,1,203,115,73,1,246,230,222,1,255,255,255,3,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,5,251,244,241,1,235,196,179,1,222, + 162,134,1,215,141,107,1,205,118,76,1,202,111,68,1,207,126,87,1,214, + 144,111,1,228,181,159,1,250,240,236,1,255,255,255,5,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,20,128,128,128,1,171,171,171,1,128, + 128,128,24,171,171,171,1,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,1,36,1,0,0,0,0,0,1,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,1,255,255,255,24,0,0,0,1,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,24,0, + 0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,1,0, + 0) + ); + +const + objdata_tdataimage: record size: integer; data: array[0..1737] of byte end = + (size: 1738; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,100,97, + 116,97,105,109,97,103,101,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,84,6,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,168,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171,171,171,20, + 128,128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128,128,1, + 255,192,144,20,128,128,128,1,171,171,171,2,128,128,128,1,255,196,150,3, + 220,202,164,1,145,213,194,1,224,201,162,1,255,196,149,12,255,195,149,2, + 128,128,128,1,171,171,171,2,128,128,128,1,255,199,155,2,100,223,216,1, + 2,237,253,1,28,238,250,1,3,237,252,1,109,222,213,1,255,199,155,13, + 128,128,128,1,171,171,171,2,128,128,128,1,255,202,161,1,221,207,174,1, + 2,237,253,1,139,251,255,1,183,255,255,1,134,250,254,1,3,237,252,1, + 227,206,171,1,255,202,161,12,128,128,128,1,171,171,171,2,128,128,128,1, + 255,205,167,1,145,219,204,1,29,239,250,1,183,255,255,3,23,238,250,1, + 153,218,201,1,255,205,167,12,128,128,128,1,171,171,171,2,128,128,128,1, + 255,209,173,1,223,213,183,1,2,237,253,1,139,251,255,1,183,255,255,1, + 133,250,254,1,4,237,252,1,229,212,181,1,255,209,173,3,255,209,172,9, + 128,128,128,1,171,171,171,2,128,128,128,1,255,212,178,2,105,227,223,1, + 3,237,253,1,24,238,251,1,4,237,252,1,114,226,220,1,255,212,178,13, + 128,128,128,1,171,171,171,2,128,128,128,1,255,215,184,3,226,218,192,1, + 153,224,211,1,230,217,191,1,255,215,184,13,227,206,163,1,128,128,128,1, + 171,171,171,2,128,128,128,1,255,218,190,17,252,216,188,1,113,176,83,1, + 8,157,4,1,128,128,128,1,171,171,171,2,128,128,128,1,255,222,196,13, + 255,222,195,3,203,205,156,1,39,171,28,1,3,190,0,1,3,173,0,1, + 128,128,128,1,171,171,171,2,128,128,128,1,255,225,201,14,234,217,185,1, + 97,182,75,1,7,185,4,1,2,194,0,1,3,188,0,1,3,171,0,1, + 128,128,128,1,171,171,171,2,128,128,128,1,255,228,207,13,134,194,107,1, + 18,187,15,1,2,204,1,1,2,198,0,1,3,192,0,1,3,186,0,1, + 3,169,0,1,128,128,128,1,171,171,171,2,128,128,128,1,255,232,213,3, + 255,231,213,9,105,187,86,1,2,209,1,1,1,208,1,1,2,202,1,1, + 2,196,0,1,3,189,0,1,3,183,0,1,3,167,0,1,128,128,128,1, + 171,171,171,2,128,128,128,1,252,113,78,1,253,126,88,1,253,131,95,1, + 253,135,104,1,253,139,111,1,253,143,118,1,251,143,117,1,250,135,104,1, + 249,128,93,1,246,120,80,1,245,112,68,1,239,104,55,1,35,153,5,1, + 1,212,1,1,1,206,1,1,2,199,0,1,3,193,0,1,3,187,0,1, + 4,181,0,1,3,165,0,1,128,128,128,1,171,171,171,2,128,128,128,1, + 254,137,66,1,255,158,82,1,255,165,94,1,255,172,107,1,255,179,120,1, + 255,186,133,1,254,188,137,1,251,176,117,1,248,163,96,1,245,151,76,1, + 242,139,56,1,240,126,36,1,201,109,14,1,20,172,2,1,2,203,1,1, + 2,197,0,1,3,191,0,1,3,184,0,1,4,178,0,1,3,163,0,1, + 128,128,128,1,171,171,171,2,128,128,128,1,254,135,63,1,255,156,79,1, + 255,163,92,1,255,170,104,1,255,178,117,1,255,185,130,1,254,191,142,1, + 252,179,121,1,249,166,101,1,246,154,81,1,243,142,60,1,240,129,40,1, + 237,117,20,1,155,113,2,1,9,184,2,1,2,194,0,1,3,188,0,1, + 4,182,0,1,4,176,0,1,3,162,0,1,128,128,128,1,171,171,171,2, + 128,128,128,1,254,133,60,1,255,155,76,1,255,162,89,1,255,169,102,1, + 255,176,114,1,255,183,127,1,255,190,140,1,252,181,126,1,249,169,106,1, + 246,157,85,1,244,144,65,1,241,132,44,1,238,119,24,1,235,107,4,1, + 115,122,1,1,6,181,0,1,3,186,0,1,4,180,0,1,4,173,0,1, + 3,162,0,1,128,128,128,1,171,171,171,2,128,128,128,1,254,132,57,1, + 255,153,73,1,255,160,86,1,255,167,99,1,255,174,112,1,255,182,125,1, + 255,189,137,1,253,184,130,1,250,172,110,1,247,159,90,1,244,147,69,1, + 241,135,49,1,239,122,29,1,236,110,8,1,235,105,0,1,133,117,1,1, + 13,166,1,1,4,177,0,1,4,171,0,1,3,162,0,1,128,128,128,1, + 171,171,171,2,128,128,128,1,254,130,55,1,255,151,70,1,255,159,83,1, + 255,166,96,1,255,173,109,1,255,180,122,1,255,187,134,1,253,187,135,1, + 251,175,115,1,248,162,94,1,245,150,74,1,242,137,53,1,239,125,33,1, + 236,112,13,1,235,105,0,2,161,111,2,1,22,150,2,1,4,171,0,1, + 3,162,0,1,128,128,128,1,171,171,171,2,128,128,128,1,253,109,49,1, + 254,126,61,1,254,132,72,1,254,138,83,1,254,144,94,1,254,150,105,1, + 254,156,116,1,253,160,122,1,251,149,105,1,248,139,88,1,246,128,71,1, + 244,118,54,1,241,108,36,1,239,97,19,1,237,89,5,3,188,94,5,1, + 33,135,3,1,4,155,0,1,128,128,128,1,171,171,171,1,128,128,128,24, + 171,171,171,1,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,1, + 116,1,0,0,0,0,0,1,255,255,255,1,0,0,0,20,255,255,255,1, + 0,0,0,1,255,255,255,24,0,0,0,1,255,255,255,22,0,0,0,2, + 255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22, + 0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2, + 255,255,255,22,0,0,0,2,255,255,255,20,251,251,251,1,255,255,255,1, + 0,0,0,2,255,255,255,19,233,233,233,1,236,236,236,1,255,255,255,1, + 0,0,0,2,255,255,255,17,252,252,252,1,224,224,224,1,255,255,255,3, + 0,0,0,2,255,255,255,16,235,235,235,1,239,239,239,1,255,255,255,4, + 0,0,0,2,255,255,255,14,252,252,252,1,240,240,240,1,255,255,255,6, + 0,0,0,2,255,255,255,13,234,234,234,1,253,253,253,1,255,255,255,7, + 0,0,0,2,255,255,255,1,238,238,238,1,236,236,236,10,235,235,235,1, + 225,225,225,1,255,255,255,8,0,0,0,2,255,255,255,13,251,251,251,1, + 239,239,239,1,255,255,255,7,0,0,0,2,255,255,255,14,253,253,253,1, + 249,249,249,1,255,255,255,6,0,0,0,2,255,255,255,15,254,254,254,1, + 252,252,252,1,255,255,255,5,0,0,0,2,255,255,255,16,254,254,254,1, + 248,248,248,1,255,255,255,4,0,0,0,2,255,255,255,17,254,254,254,1, + 244,244,244,1,255,255,255,3,0,0,0,2,255,255,255,18,254,254,254,1, + 243,243,243,1,255,255,255,2,0,0,0,1,255,255,255,24,0,0,0,1, + 255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,1,0,0) + ); + +const + objdata_tstringedit: record size: integer; data: array[0..822] of byte end = + (size: 823; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,115,116, + 114,105,110,103,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,192,2,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,120,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0, + 22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,7,23,23,23, + 1,255,255,255,9,0,0,0,1,255,255,255,1,0,0,0,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,7,23,23,23, + 1,255,255,255,10,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,184,184,184,1,58,58,58, + 1,60,60,60,1,47,47,47,1,213,213,213,1,255,255,255,1,20,20,20, + 1,84,84,84,1,58,58,58,1,61,61,61,1,213,213,213,1,208,208,208, + 1,58,58,58,1,61,61,61,1,76,76,76,1,242,242,242,1,255,255,255, + 1,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,145,145,145,1,229,229,229,1,255,255,255, + 1,134,134,134,1,132,132,132,1,255,255,255,1,11,11,11,1,189,189,189, + 1,255,255,255,1,196,196,196,1,58,58,58,2,203,203,203,1,255,255,255, + 1,164,164,164,1,198,198,198,1,255,255,255,1,0,0,0,1,255,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 1,171,171,171,1,83,83,83,1,96,96,96,1,69,69,69,1,127,127,127, + 1,255,255,255,1,16,16,16,1,255,255,255,2,254,254,254,1,21,21,21, + 1,23,23,23,1,255,255,255,5,0,0,0,1,255,255,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,18,18,18, + 1,244,244,244,1,255,255,255,1,104,104,104,1,127,127,127,1,255,255,255, + 1,11,11,11,1,201,201,201,1,255,255,255,1,190,190,190,1,65,65,65, + 1,53,53,53,1,211,211,211,1,255,255,255,1,147,147,147,1,164,164,164, + 1,255,255,255,1,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,113,113,113,1,47,47,47, + 1,74,74,74,1,111,111,111,1,103,103,103,1,255,255,255,1,32,32,32, + 1,81,81,81,1,60,60,60,1,66,66,66,1,220,220,220,1,204,204,204, + 1,55,55,55,1,60,60,60,1,80,80,80,1,244,244,244,1,255,255,255, + 1,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0,0,0, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255, + 145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0, + 120,0,0) + ); + +const + objdata_tdropdownlistedit: record size: integer; data: array[0..1356] of byte end = + (size: 1357; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,114, + 111,112,100,111,119,110,108,105,115,116,101,100,105,116,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,208, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,140, + 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255, + 255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,0, + 0,0,1,1,1,1,1,75,75,75,1,255,255,255,4,0,0,0,1,231, + 231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,255,255,255,2,88, + 88,88,1,75,75,75,1,89,89,89,1,255,255,255,2,0,0,0,1,234, + 234,234,1,70,70,70,1,255,255,255,5,0,0,0,1,255,255,255,2,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,251, + 251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255, + 255,255,1,0,0,0,2,117,117,117,1,255,255,255,5,0,0,0,1,255, + 255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,1,0, + 0,0,1,243,243,243,1,11,11,11,1,255,255,255,5,0,0,0,1,255, + 255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,114,114,114,1,141,141,141,1,255, + 255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,1,235, + 235,235,1,19,19,19,1,255,255,255,3,252,252,252,1,231,231,231,1,0, + 0,0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217,1,255, + 255,255,1,217,217,217,1,38,38,38,1,255,255,255,1,0,0,0,1,3, + 3,3,1,124,124,124,1,255,255,255,3,223,223,223,1,0,0,0,1,223, + 223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255, + 255,255,22,0,0,0,2,255,255,255,2,165,165,165,1,0,0,0,1,165, + 165,165,1,255,255,255,2,0,0,0,1,1,1,1,1,75,75,75,1,255, + 255,255,1,232,232,232,1,77,77,77,1,9,9,9,1,38,38,38,1,203, + 203,203,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128, + 128,128,1,0,0,0,2,255,255,255,2,88,88,88,1,75,75,75,1,89, + 89,89,1,255,255,255,2,0,0,0,1,234,234,234,1,70,70,70,1,255, + 255,255,1,82,82,82,1,118,118,118,1,245,245,245,1,166,166,166,1,53, + 53,53,1,255,255,255,2,0,0,0,3,128,128,128,1,0,0,0,2,255, + 255,255,1,251,251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251, + 251,251,1,255,255,255,1,0,0,0,2,117,117,117,1,255,255,255,1,12, + 12,12,1,241,241,241,1,255,255,255,5,208,208,208,3,128,128,128,1,0, + 0,0,2,255,255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255, + 255,255,1,0,0,0,1,243,243,243,1,11,11,11,1,255,255,255,1,14, + 14,14,1,241,241,241,1,255,255,255,1,252,252,252,1,210,210,210,1,255, + 255,255,1,128,128,128,5,0,0,0,2,255,255,255,1,114,114,114,1,141, + 141,141,1,255,255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0, + 0,0,1,235,235,235,1,19,19,19,1,255,255,255,1,83,83,83,1,124, + 124,124,1,245,245,245,1,145,145,145,1,57,57,57,1,255,255,255,2,212, + 212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,255, + 255,255,1,37,37,37,1,217,217,217,1,255,255,255,1,217,217,217,1,38, + 38,38,1,255,255,255,1,0,0,0,1,3,3,3,1,124,124,124,1,255, + 255,255,1,227,227,227,1,63,63,63,1,7,7,7,1,43,43,43,1,213, + 213,213,1,255,255,255,5,128,128,128,1,0,0,0,2,255,255,255,18,128, + 128,128,4,0,0,0,2,255,255,255,2,0,0,0,2,5,5,5,1,174, + 174,174,1,255,255,255,11,208,208,208,1,255,255,255,1,211,211,211,1,255, + 255,255,1,208,208,208,1,0,0,0,2,255,255,255,2,0,0,0,1,255, + 255,255,1,174,174,174,1,5,5,5,1,255,255,255,1,152,152,152,1,11, + 11,11,1,159,159,159,1,255,255,255,9,252,252,252,1,255,255,255,2,0, + 0,0,2,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,1,29,29,29,1,197,197,197,1,37,37,37,1,255,255,255,8,208, + 208,208,3,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,1,255, + 255,255,2,0,0,0,1,255,255,255,1,2,2,2,1,0,0,0,1,3, + 3,3,1,255,255,255,8,0,0,0,3,128,128,128,1,0,0,0,2,255, + 255,255,2,0,0,0,1,255,255,255,1,174,174,174,1,5,5,5,1,255, + 255,255,1,25,25,25,1,226,226,226,1,255,255,255,9,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,255,255,255,2,0, + 0,0,2,5,5,5,1,174,174,174,1,255,255,255,1,146,146,146,1,9, + 9,9,1,98,98,98,1,255,255,255,7,128,128,128,5,0,0,0,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tintegeredit: record size: integer; data: array[0..827] of byte end = + (size: 828; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,105,110, + 116,101,103,101,114,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,196,2,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,124,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0, + 0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,249,249, + 249,1,28,28,28,1,255,255,255,2,177,177,177,1,56,56,56,1,45,45, + 45,1,172,172,172,1,255,255,255,1,187,187,187,1,54,54,54,1,46,46, + 46,1,155,155,155,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,1,200,200,200,1,39,39,39,1,0,0,0,1,255,255,255,2,62,62, + 62,1,249,249,249,1,221,221,221,1,24,24,24,1,255,255,255,1,75,75, + 75,1,242,242,242,1,231,231,231,1,13,13,13,1,255,255,255,3,0,0, + 0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,1,252,252,252,1,247,247,247,1,0,0,0,1,255,255, + 255,2,163,163,163,1,255,255,255,1,234,234,234,1,12,12,12,1,255,255, + 255,1,207,207,207,1,254,254,254,1,197,197,197,1,37,37,37,1,255,255, + 255,3,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,232,232, + 232,1,65,65,65,1,126,126,126,1,255,255,255,2,143,143,143,1,0,0, + 0,1,150,150,150,1,255,255,255,3,0,0,0,1,255,255,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,2,206,206,206,1,44,44,44,1,165,165,165,1,254,254, + 254,1,255,255,255,1,240,240,240,1,254,254,254,1,199,199,199,1,16,16, + 16,1,255,255,255,3,0,0,0,1,255,255,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255, + 255,2,70,70,70,1,226,226,226,1,255,255,255,3,63,63,63,1,251,251, + 251,1,228,228,228,1,19,19,19,1,255,255,255,3,0,0,0,1,255,255, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,3,0,0,0,1,255,255,255,1,238,238,238,1,15,15,15,1,51,51, + 51,3,255,255,255,1,159,159,159,1,54,54,54,1,45,45,45,1,164,164, + 164,1,255,255,255,3,0,0,0,1,255,255,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255, + 255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224, + 224,22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255, + 255,81,0,0,0,120,0,0) + ); + +const + objdata_tint64edit: record size: integer; data: array[0..873] of byte end = + (size: 874; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,105,110, + 116,54,52,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,244,2,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,172,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0,22, + 255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,5,241,241,241,1, + 255,255,255,6,237,237,237,1,253,253,253,1,255,255,255,6,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,194,194,194,1, + 41,41,41,1,53,53,53,1,59,59,59,1,230,230,230,1,255,255,255,3, + 211,211,211,1,7,7,7,1,233,233,233,1,255,255,255,3,0,0,0,1, + 255,255,255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,255,255,255,2,252,252,252,1,39,39,39,1,202,202,202,1, + 255,255,255,1,142,142,142,1,124,124,124,1,255,255,255,2,249,249,249,1, + 59,59,59,1,9,9,9,1,233,233,233,1,255,255,255,4,0,0,0,1, + 255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 255,255,255,2,198,198,198,1,62,62,62,1,249,249,249,1,213,213,213,1, + 255,255,255,4,115,115,115,1,154,154,154,1,22,22,22,1,233,233,233,1, + 255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,255,255,2,169,169,169,1,59,59,59,1, + 41,41,41,1,64,64,64,1,49,49,49,1,214,214,214,1,255,255,255,1, + 190,190,190,1,78,78,78,1,255,255,255,1,22,22,22,1,233,233,233,1, + 255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,255,255,2,158,158,158,1,7,7,7,1, + 234,234,234,1,255,255,255,1,145,145,145,1,108,108,108,1,239,239,239,1, + 49,49,49,1,232,232,232,1,255,255,255,1,22,22,22,1,233,233,233,1, + 255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,255,255,2,183,183,183,1,56,56,56,1, + 255,255,255,2,207,207,207,1,44,44,44,1,152,152,152,1,15,15,15,1, + 39,39,39,2,3,3,3,1,36,36,36,1,223,223,223,1,255,255,255,3, + 0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,255,255,255,2,240,240,240,1,28,28,28,1,223,223,223,1, + 255,255,255,1,128,128,128,1,94,94,94,1,249,249,249,1,239,239,239,3, + 20,20,20,1,219,219,219,1,253,253,253,1,255,255,255,3,0,0,0,1, + 255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 255,255,255,3,177,177,177,1,35,35,35,1,51,51,51,1,55,55,55,1, + 234,234,234,1,255,255,255,4,22,22,22,1,233,233,233,1,255,255,255,3, + 0,0,0,1,255,255,255,1,0,0,0,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1, + 128,128,128,1,224,224,224,22,255,255,255,145,16,0,0,0,0,0,0,120, + 255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_trealedit: record size: integer; data: array[0..704] of byte end = + (size: 705; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,114,101, + 97,108,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,76,2,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,4,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,249,249,249,1,28, + 28,28,1,255,255,255,6,177,177,177,1,56,56,56,1,45,45,45,1,172, + 172,172,1,255,255,255,3,0,0,0,1,255,255,255,1,0,0,0,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,200, + 200,200,1,39,39,39,1,0,0,0,1,255,255,255,6,62,62,62,1,249, + 249,249,1,221,221,221,1,24,24,24,1,255,255,255,4,0,0,0,1,255, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,252,252,252,1,247,247,247,1,0,0,0,1,255,255,255,6,163, + 163,163,1,255,255,255,1,234,234,234,1,12,12,12,1,255,255,255,4,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,3,0,0,0,1,255,255,255,7,232,232,232,1,65, + 65,65,1,126,126,126,1,255,255,255,4,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,0, + 0,0,1,255,255,255,6,206,206,206,1,44,44,44,1,165,165,165,1,254, + 254,254,1,255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,3,251,251,251,1,255,255,255,2,70,70,70,1,226,226,226,1,255, + 255,255,6,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,0, + 0,0,1,255,255,255,1,238,238,238,1,15,15,15,1,51,51,51,3,255, + 255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0, + 0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_trealspinedit: record size: integer; data: array[0..708] of byte end = + (size: 709; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,114,101, + 97,108,115,112,105,110,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,4,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,15,208, + 208,208,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,2,249,249,249,1,28,28,28,1,255,255,255,6,177,177,177,1,56, + 56,56,1,45,45,45,1,172,172,172,1,255,255,255,1,208,208,208,2,0, + 0,0,1,208,208,208,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,200,200,200,1,39,39,39,1,0,0,0,1,255, + 255,255,6,62,62,62,1,249,249,249,1,221,221,221,1,24,24,24,1,255, + 255,255,1,208,208,208,1,0,0,0,3,208,208,208,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,252,252,252,1,247, + 247,247,1,0,0,0,1,255,255,255,6,163,163,163,1,255,255,255,1,234, + 234,234,1,12,12,12,1,255,255,255,1,0,0,0,5,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,7,232,232,232,1,65,65,65,1,126,126,126,1,255,255,255,1,208, + 208,208,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,3,0,0,0,1,255,255,255,6,206,206,206,1,44,44,44,1,165, + 165,165,1,254,254,254,1,255,255,255,1,208,208,208,5,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,3,251,251,251,1,255,255,255,2,70,70,70,1,226,226,226,1,255, + 255,255,3,0,0,0,5,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,1,238,238,238,1,15,15,15,1,51,51,51,3,255,255,255,1,208, + 208,208,1,0,0,0,3,208,208,208,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,15,208,208,208,2,0,0,0,1,208, + 208,208,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,15,208,208,208,5,224,224,224,1,255,255,255,1,128,128,128,1,224, + 224,224,22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255, + 255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdatetimeedit: record size: integer; data: array[0..684] of byte end = + (size: 685; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,97, + 116,101,116,105,109,101,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,52,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0, + 0,0,3,5,5,5,1,174,174,174,1,255,255,255,4,0,0,0,5,255, + 255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,2,174,174,174,1,5,5,5,1,255,255,255,6,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,3,0, + 0,0,1,255,255,255,2,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,3,0, + 0,0,1,255,255,255,6,0,0,0,1,255,255,255,5,0,0,0,1,255, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,6,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,2,174,174,174,1,5,5,5,1,255,255,255,6,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,0,0,0,3,5,5,5,1,174, + 174,174,1,255,255,255,2,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0, + 0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_tenumedit: record size: integer; data: array[0..1380] of byte end = + (size: 1381; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,101,110, + 117,109,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,240,4,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,172,4,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,255,255,255,1,238,238,238,1,29, + 29,29,1,255,255,255,1,172,172,172,1,21,21,21,1,18,18,18,1,148, + 148,148,1,115,115,115,1,15,15,15,2,128,128,128,1,255,255,255,2,0, + 0,0,1,234,234,234,1,23,23,23,1,255,255,255,6,128,128,128,1,255, + 255,255,1,98,98,98,1,0,0,0,1,255,255,255,1,29,29,29,1,201, + 201,201,1,209,209,209,1,10,10,10,1,255,255,255,2,194,194,194,1,17, + 17,17,1,255,255,255,3,0,0,0,1,255,255,255,2,208,208,208,3,128, + 128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,247,247,247,1,0, + 0,0,1,255,255,255,3,205,205,205,1,68,68,68,1,255,255,255,1,164, + 164,164,1,4,4,4,1,103,103,103,1,255,255,255,3,0,0,0,1,255, + 255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,70,70,70,1,232, + 232,232,1,255,255,255,2,214,214,214,1,10,10,10,1,255,255,255,3,0, + 0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128, + 128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0,0,0,1,255, + 255,255,1,165,165,165,1,77,77,77,1,235,235,235,1,255,255,255,1,32, + 32,32,1,227,227,227,1,234,234,234,1,24,24,24,1,255,255,255,1,252, + 252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255,255,255,1,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0, + 0,0,1,255,255,255,1,19,19,19,1,0,0,0,3,177,177,177,1,19, + 19,19,1,24,24,24,1,179,179,179,1,255,255,255,1,223,223,223,1,0, + 0,0,1,223,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0, + 0,0,25,255,255,255,22,0,0,0,2,255,255,255,2,165,165,165,1,0, + 0,0,1,165,165,165,1,255,255,255,2,0,0,0,1,1,1,1,1,75, + 75,75,1,255,255,255,1,232,232,232,1,77,77,77,1,9,9,9,1,38, + 38,38,1,203,203,203,1,255,255,255,2,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,0,0,0,2,255,255,255,2,88,88,88,1,75, + 75,75,1,89,89,89,1,255,255,255,2,0,0,0,1,234,234,234,1,70, + 70,70,1,255,255,255,1,82,82,82,1,118,118,118,1,245,245,245,1,166, + 166,166,1,53,53,53,1,255,255,255,2,0,0,0,3,128,128,128,1,0, + 0,0,2,255,255,255,1,251,251,251,1,21,21,21,1,221,221,221,1,20, + 20,20,1,251,251,251,1,255,255,255,1,0,0,0,2,117,117,117,1,255, + 255,255,1,12,12,12,1,241,241,241,1,255,255,255,5,208,208,208,3,128, + 128,128,1,0,0,0,2,255,255,255,1,191,191,191,1,0,0,0,3,191, + 191,191,1,255,255,255,1,0,0,0,1,243,243,243,1,11,11,11,1,255, + 255,255,1,14,14,14,1,241,241,241,1,255,255,255,1,252,252,252,1,210, + 210,210,1,255,255,255,1,128,128,128,5,0,0,0,2,255,255,255,1,114, + 114,114,1,141,141,141,1,255,255,255,1,141,141,141,1,115,115,115,1,255, + 255,255,1,0,0,0,1,235,235,235,1,19,19,19,1,255,255,255,1,83, + 83,83,1,124,124,124,1,245,245,245,1,145,145,145,1,57,57,57,1,255, + 255,255,2,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0, + 0,0,2,255,255,255,1,37,37,37,1,217,217,217,1,255,255,255,1,217, + 217,217,1,38,38,38,1,255,255,255,1,0,0,0,1,3,3,3,1,124, + 124,124,1,255,255,255,1,227,227,227,1,63,63,63,1,7,7,7,1,43, + 43,43,1,213,213,213,1,255,255,255,5,128,128,128,1,0,0,0,2,255, + 255,255,18,128,128,128,4,0,0,0,2,255,255,255,2,0,0,0,2,5, + 5,5,1,174,174,174,1,255,255,255,11,208,208,208,1,255,255,255,1,211, + 211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,255,255,255,2,0, + 0,0,1,255,255,255,1,174,174,174,1,5,5,5,1,255,255,255,1,152, + 152,152,1,11,11,11,1,159,159,159,1,255,255,255,9,252,252,252,1,255, + 255,255,2,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,1,29,29,29,1,197,197,197,1,37,37,37,1,255, + 255,255,8,208,208,208,3,128,128,128,1,0,0,0,2,255,255,255,2,0, + 0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,2,2,2,1,0, + 0,0,1,3,3,3,1,255,255,255,8,0,0,0,3,128,128,128,1,0, + 0,0,2,255,255,255,2,0,0,0,1,255,255,255,1,174,174,174,1,5, + 5,5,1,255,255,255,1,25,25,25,1,226,226,226,1,255,255,255,9,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,255, + 255,255,2,0,0,0,2,5,5,5,1,174,174,174,1,255,255,255,1,146, + 146,146,1,9,9,9,1,98,98,98,1,255,255,255,7,128,128,128,5,0, + 0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0, + 0) + ); + +const + objdata_thistoryedit: record size: integer; data: array[0..1187] of byte end = + (size: 1188; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,104,105, + 115,116,111,114,121,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,4,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,232,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,2,165,165, + 165,1,0,0,0,1,165,165,165,1,255,255,255,2,0,0,0,1,1,1, + 1,1,75,75,75,1,255,255,255,4,0,0,0,1,234,234,234,1,23,23, + 23,1,255,255,255,6,128,128,128,1,255,255,255,2,88,88,88,1,75,75, + 75,1,89,89,89,1,255,255,255,2,0,0,0,1,234,234,234,1,70,70, + 70,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208,208,3,128,128, + 128,1,255,255,255,1,128,128,128,1,255,255,255,1,251,251,251,1,21,21, + 21,1,221,221,221,1,20,20,20,1,251,251,251,1,255,255,255,1,0,0, + 0,2,117,117,117,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0, + 0,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,191,191, + 191,1,0,0,0,3,191,191,191,1,255,255,255,1,0,0,0,1,243,243, + 243,1,11,11,11,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208, + 208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128, + 128,1,255,255,255,1,114,114,114,1,141,141,141,1,255,255,255,1,141,141, + 141,1,115,115,115,1,255,255,255,1,0,0,0,1,235,235,235,1,19,19, + 19,1,255,255,255,3,252,252,252,1,231,231,231,1,0,0,0,1,247,247, + 247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128, + 128,1,255,255,255,1,37,37,37,1,217,217,217,1,255,255,255,1,217,217, + 217,1,38,38,38,1,255,255,255,1,0,0,0,1,3,3,3,1,124,124, + 124,1,255,255,255,3,223,223,223,1,0,0,0,1,223,223,223,1,0,0, + 0,1,128,128,128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0, + 0,2,255,255,255,18,208,208,208,1,0,0,0,1,208,208,208,1,128,128, + 128,1,0,0,0,2,255,255,255,18,0,0,0,3,128,128,128,1,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,6,83,83,83,1,255,255,255,2,208,208, + 208,3,128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,3,0,0,0,1,255,255,255,2,247,247,247,1,255,255,255,6,0,0, + 0,1,255,255,255,1,128,128,128,5,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,3,0,0,0,1,255,255,255,2,0,0,0,1,154,154, + 154,1,29,29,29,1,24,24,24,1,144,144,144,1,255,255,255,1,116,116, + 116,1,0,0,0,1,89,89,89,1,255,255,255,1,212,212,212,1,252,252, + 252,1,208,208,208,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,5,255,255,255,2,0,0,0,1,12,12,12,1,233,233,233,1,230,230, + 230,1,58,58,58,1,255,255,255,2,0,0,0,1,255,255,255,5,128,128, + 128,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,2,0,0,0,1,50,50,50,1,66,66,66,1,151,151, + 151,1,238,238,238,1,255,255,255,2,0,0,0,1,255,255,255,2,128,128, + 128,4,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,2,0,0,0,1,243,243,243,1,178,178,178,1,88,88, + 88,1,40,40,40,1,255,255,255,2,0,0,0,1,255,255,255,1,208,208, + 208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255, + 255,2,0,0,0,1,10,10,10,1,225,225,225,1,230,230,230,1,14,14, + 14,1,255,255,255,2,0,0,0,1,253,253,253,1,255,255,255,2,252,252, + 252,1,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,3,0,0,0,1,255,255,255,2,0,0,0,1,147,147,147,1,24,24, + 24,1,27,27,27,1,154,154,154,1,255,255,255,2,61,61,61,1,86,86, + 86,1,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,255,255, + 255,18,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,18,208,208, + 208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,255,255, + 255,17,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255, + 255,255,255,255,255,66,0,0) + ); + +const + objdata_tenumtypeedit: record size: integer; data: array[0..1092] of byte end = + (size: 1093; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,101,110, + 117,109,116,121,112,101,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,204,3,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,136,3,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,23,128, + 128,128,1,0,0,0,1,83,83,83,2,128,128,128,1,255,255,255,14,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,3,0,0,0,1,94,94,94,1,85,85,85,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,97, + 97,97,1,70,70,70,1,82,82,82,1,84,84,84,1,255,255,255,1,0, + 0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,0,0,0,3,123, + 123,123,1,0,0,0,1,243,243,243,1,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,243, + 243,243,1,0,0,0,1,246,246,246,1,0,0,0,1,255,255,255,1,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,0,0,1,243,243,243,1,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128, + 128,128,1,0,0,0,1,83,83,83,2,120,120,120,1,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,74,74,74,1,95,95,95,1,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255, + 255,255,22,0,0,0,2,255,255,255,18,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,0,0,0,2,255,255,255,18,0,0,0,3,128, + 128,128,1,0,0,0,2,255,255,255,1,0,0,0,5,255,255,255,12,208, + 208,208,3,128,128,128,1,0,0,0,2,255,255,255,3,0,0,0,1,255, + 255,255,13,128,128,128,5,0,0,0,2,255,255,255,3,0,0,0,1,255, + 255,255,2,52,52,52,1,203,203,203,1,255,255,255,1,204,204,204,1,50, + 50,50,1,255,255,255,1,0,0,0,1,100,100,100,1,17,17,17,1,174, + 174,174,1,255,255,255,2,212,212,212,1,252,252,252,1,208,208,208,1,255, + 255,255,1,0,0,0,2,255,255,255,3,0,0,0,1,255,255,255,2,157, + 157,157,1,97,97,97,1,255,255,255,1,102,102,102,1,152,152,152,1,255, + 255,255,1,0,0,0,1,175,175,175,1,179,179,179,1,37,37,37,1,255, + 255,255,5,128,128,128,1,0,0,0,2,255,255,255,3,0,0,0,1,255, + 255,255,2,246,246,246,1,27,27,27,1,226,226,226,1,25,25,25,1,242, + 242,242,1,255,255,255,1,0,0,0,1,249,249,249,1,248,248,248,1,5, + 5,5,1,255,255,255,2,128,128,128,4,0,0,0,2,255,255,255,3,0, + 0,0,1,255,255,255,3,113,113,113,1,55,55,55,1,99,99,99,1,255, + 255,255,2,0,0,0,1,183,183,183,1,180,180,180,1,41,41,41,1,255, + 255,255,1,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208, + 208,208,1,0,0,0,2,255,255,255,3,0,0,0,1,255,255,255,3,217, + 217,217,1,0,0,0,1,201,201,201,1,255,255,255,2,0,0,0,1,80, + 80,80,1,22,22,22,1,184,184,184,1,255,255,255,3,252,252,252,1,255, + 255,255,2,0,0,0,2,255,255,255,7,202,202,202,1,41,41,41,1,255, + 255,255,3,0,0,0,1,255,255,255,5,208,208,208,3,128,128,128,1,0, + 0,0,2,255,255,255,7,12,12,12,1,168,168,168,1,255,255,255,3,0, + 0,0,1,255,255,255,5,0,0,0,3,128,128,128,1,0,0,0,2,255, + 255,255,18,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0, + 0,0,2,255,255,255,17,128,128,128,5,0,0,0,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tselector: record size: integer; data: array[0..1088] of byte end = + (size: 1089; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,101, + 108,101,99,116,111,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,204,3,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,136,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,255,255,255,2,165,165,165,1,0, + 0,0,1,165,165,165,1,255,255,255,2,0,0,0,1,1,1,1,1,75, + 75,75,1,255,255,255,4,0,0,0,1,234,234,234,1,23,23,23,1,255, + 255,255,6,128,128,128,1,255,255,255,2,88,88,88,1,75,75,75,1,89, + 89,89,1,255,255,255,2,0,0,0,1,234,234,234,1,70,70,70,1,255, + 255,255,5,0,0,0,1,255,255,255,2,208,208,208,3,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,251,251,251,1,21,21,21,1,221, + 221,221,1,20,20,20,1,251,251,251,1,255,255,255,1,0,0,0,2,117, + 117,117,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,191,191,191,1,0, + 0,0,3,191,191,191,1,255,255,255,1,0,0,0,1,243,243,243,1,11, + 11,11,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,1,114,114,114,1,141,141,141,1,255,255,255,1,141,141,141,1,115, + 115,115,1,255,255,255,1,0,0,0,1,235,235,235,1,19,19,19,1,255, + 255,255,3,252,252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255, + 255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,1,37,37,37,1,217,217,217,1,255,255,255,1,217,217,217,1,38, + 38,38,1,255,255,255,1,0,0,0,1,3,3,3,1,124,124,124,1,255, + 255,255,3,223,223,223,1,0,0,0,1,223,223,223,1,0,0,0,1,128, + 128,128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0,2,255, + 255,255,18,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0, + 0,0,2,255,255,255,18,0,0,0,3,128,128,128,1,0,0,0,2,255, + 255,255,2,156,156,156,1,17,17,17,1,23,23,23,1,169,169,169,1,255, + 255,255,6,0,0,0,1,255,255,255,5,208,208,208,3,128,128,128,1,0, + 0,0,2,255,255,255,2,16,16,16,1,207,207,207,1,199,199,199,1,23, + 23,23,1,255,255,255,6,0,0,0,1,255,255,255,4,128,128,128,5,0, + 0,0,2,255,255,255,2,43,43,43,1,176,176,176,1,255,255,255,3,186, + 186,186,1,25,25,25,2,195,195,195,1,255,255,255,1,0,0,0,1,255, + 255,255,5,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0, + 0,0,2,255,255,255,2,228,228,228,1,102,102,102,1,49,49,49,1,185, + 185,185,1,255,255,255,1,39,39,39,1,194,194,194,1,197,197,197,1,50, + 50,50,1,255,255,255,1,0,0,0,1,255,255,255,8,128,128,128,1,0, + 0,0,2,255,255,255,4,227,227,227,1,23,23,23,1,255,255,255,1,3, + 3,3,1,0,0,0,2,4,4,4,1,255,255,255,1,0,0,0,1,255, + 255,255,5,128,128,128,4,0,0,0,2,255,255,255,2,22,22,22,1,199, + 199,199,1,220,220,220,1,22,22,22,1,255,255,255,1,34,34,34,1,195, + 195,195,1,255,255,255,3,0,0,0,1,255,255,255,4,208,208,208,1,255, + 255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,255, + 255,255,2,166,166,166,1,22,22,22,1,16,16,16,1,163,163,163,1,255, + 255,255,1,179,179,179,1,23,23,23,1,13,13,13,1,120,120,120,1,255, + 255,255,1,0,0,0,1,255,255,255,6,252,252,252,1,255,255,255,2,0, + 0,0,2,255,255,255,18,208,208,208,3,128,128,128,1,0,0,0,2,255, + 255,255,18,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,18,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,255, + 255,255,17,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255, + 255,255,255,255,255,255,66,0,0) + ); + +const + objdata_titemedit: record size: integer; data: array[0..916] of byte end = + (size: 917; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,105,116, + 101,109,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,32,3,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,196,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128,128,1,255, + 255,255,20,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,16,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,17,0,0,0,1,255,255,255,2,128, + 128,128,1,171,171,171,2,128,128,128,1,255,255,255,17,0,0,0,1,255, + 255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,17,0, + 0,0,1,255,255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,17,0,0,0,1,255,255,255,2,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,17,0,0,0,1,255,255,255,2,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,17,0,0,0,1,255,255,255,2,128, + 128,128,1,171,171,171,2,128,128,128,1,255,255,255,16,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,20,128,128,128,1,171,171,171,1,128,128,128,24,171, + 171,171,1,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,1,36, + 1,0,0,0,0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,1,255,255,255,24,0,0,0,1,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,1,255,255,255,24,0,0,0,1,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,1,0,0) + ); + +const + objdata_trecordfieldedit: record size: integer; data: array[0..1207] of byte end = + (size: 1208; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,114,101, + 99,111,114,100,102,105,101,108,100,101,100,105,116,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,60,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,224,2, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,171,171,1,128,128, + 128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171, + 171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128, + 128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171, + 171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128, + 128,1,171,171,171,20,128,128,128,1,171,171,171,1,128,128,128,24,171,171, + 171,1,128,128,128,1,255,255,255,20,128,128,128,1,171,171,171,2,128,128, + 128,1,0,0,0,3,17,17,17,1,150,150,150,1,255,255,255,12,0,0, + 0,1,255,255,255,1,0,0,0,1,128,128,128,1,171,171,171,2,128,128, + 128,1,0,0,0,1,255,255,255,2,200,200,200,1,19,19,19,1,255,255, + 255,13,0,0,0,1,255,255,255,1,128,128,128,1,171,171,171,2,128,128, + 128,1,0,0,0,1,255,255,255,2,202,202,202,1,22,22,22,1,255,255, + 255,2,186,186,186,1,25,25,25,2,195,195,195,1,255,255,255,2,189,189, + 189,1,32,32,32,1,42,42,42,1,197,197,197,1,255,255,255,1,0,0, + 0,1,255,255,255,1,128,128,128,1,171,171,171,2,128,128,128,1,0,0, + 0,3,19,19,19,1,164,164,164,1,255,255,255,2,39,39,39,1,194,194, + 194,1,197,197,197,1,50,50,50,1,255,255,255,2,41,41,41,1,175,175, + 175,1,196,196,196,1,34,34,34,1,255,255,255,1,0,0,0,1,255,255, + 255,1,128,128,128,1,171,171,171,2,128,128,128,1,0,0,0,1,255,255, + 255,1,214,214,214,1,60,60,60,1,237,237,237,1,255,255,255,2,3,3, + 3,1,0,0,0,2,4,4,4,1,255,255,255,2,4,4,4,1,249,249, + 249,1,255,255,255,3,0,0,0,1,255,255,255,1,128,128,128,1,171,171, + 171,2,128,128,128,1,0,0,0,1,255,255,255,2,159,159,159,1,96,96, + 96,1,255,255,255,2,34,34,34,1,195,195,195,1,220,220,220,1,255,255, + 255,3,36,36,36,1,182,182,182,1,198,198,198,1,35,35,35,1,255,255, + 255,1,0,0,0,1,255,255,255,1,128,128,128,1,171,171,171,2,128,128, + 128,1,0,0,0,1,255,255,255,2,254,254,254,1,56,56,56,1,203,203, + 203,1,255,255,255,1,179,179,179,1,23,23,23,1,0,0,0,1,58,58, + 58,1,255,255,255,2,182,182,182,1,25,25,25,1,19,19,19,1,180,180, + 180,1,255,255,255,1,0,0,0,1,255,255,255,1,128,128,128,1,171,171, + 171,2,128,128,128,1,255,255,255,17,0,0,0,1,255,255,255,1,0,0, + 0,1,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,20,128,128, + 128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128,128,1,171,171, + 171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128, + 128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171, + 171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128, + 128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171, + 171,20,128,128,128,1,171,171,171,1,36,1,0,0,0,0,0,1,255,255, + 255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255, + 255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0, + 0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255, + 255,1,0,0,0,20,255,255,255,1,0,0,0,1,255,255,255,24,0,0, + 0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,1,255,255,255,24,0,0,0,1,255,255,255,1,0,0,0,20,255,255, + 255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0, + 0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255, + 255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255, + 255,1,0,0,0,1,0,0) + ); + +const + objdata_tdropdownitemedit: record size: integer; data: array[0..1004] of byte end = + (size: 1005; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,114, + 111,112,100,111,119,110,105,116,101,109,101,100,105,116,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,112, + 3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,20, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,171,171,1,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,1,128,128,128,24,171, + 171,171,1,128,128,128,1,255,255,255,20,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,9,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,1,176,176,176,1,232,232,232,5,128,128,128,2,171,171,171,2,128, + 128,128,1,255,255,255,10,0,0,0,1,255,255,255,2,176,176,176,1,226, + 226,226,5,128,128,128,2,171,171,171,2,128,128,128,1,255,255,255,10,0, + 0,0,1,255,255,255,2,176,176,176,1,215,215,215,5,128,128,128,2,171, + 171,171,2,128,128,128,1,255,255,255,10,0,0,0,1,255,255,255,2,176, + 176,176,1,0,0,0,5,128,128,128,2,171,171,171,2,128,128,128,1,255, + 255,255,10,0,0,0,1,255,255,255,2,176,176,176,1,194,194,194,1,0, + 0,0,3,194,194,194,1,128,128,128,2,171,171,171,2,128,128,128,1,255, + 255,255,10,0,0,0,1,255,255,255,2,176,176,176,1,183,183,183,2,0, + 0,0,1,183,183,183,2,128,128,128,2,171,171,171,2,128,128,128,1,255, + 255,255,10,0,0,0,1,255,255,255,2,176,176,176,1,172,172,172,5,128, + 128,128,2,171,171,171,2,128,128,128,1,255,255,255,9,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,176,176,176,1,167,167,167,5,128, + 128,128,2,171,171,171,2,128,128,128,1,255,255,255,13,128,128,128,8,171, + 171,171,1,128,128,128,24,171,171,171,1,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,1,36,1,0,0,0,0,0,1,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,1,255,255,255,24,0,0,0,1,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255, + 255,255,24,0,0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,1,0,0) + ); + +const + objdata_tmbdropdownitemedit: record size: integer; data: array[0..1134] of byte end = + (size: 1135; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,109,98, + 100,114,111,112,100,111,119,110,105,116,101,109,101,100,105,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,240,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,148,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,171,171, + 1,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128, + 1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171, + 20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128, + 1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171, + 2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,1,128,128,128, + 24,171,171,171,1,128,128,128,1,255,255,255,20,128,128,128,1,171,171,171, + 2,128,128,128,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0, + 1,255,255,255,1,176,176,176,1,232,232,232,5,128,128,128,1,255,255,255, + 1,232,232,232,5,128,128,128,2,171,171,171,2,128,128,128,1,255,255,255, + 3,0,0,0,1,255,255,255,2,176,176,176,1,226,226,226,5,128,128,128, + 1,255,255,255,1,226,226,226,5,128,128,128,2,171,171,171,2,128,128,128, + 1,255,255,255,3,0,0,0,1,255,255,255,2,176,176,176,1,215,215,215, + 5,128,128,128,1,255,255,255,1,215,215,215,5,128,128,128,2,171,171,171, + 2,128,128,128,1,255,255,255,3,0,0,0,1,255,255,255,2,176,176,176, + 1,0,0,0,5,128,128,128,1,255,255,255,1,0,0,0,1,204,204,204, + 1,0,0,0,1,204,204,204,1,0,0,0,1,128,128,128,2,171,171,171, + 2,128,128,128,1,255,255,255,3,0,0,0,1,255,255,255,2,176,176,176, + 1,194,194,194,1,0,0,0,3,194,194,194,1,128,128,128,1,255,255,255, + 1,0,0,0,1,194,194,194,1,0,0,0,1,194,194,194,1,0,0,0, + 1,128,128,128,2,171,171,171,2,128,128,128,1,255,255,255,3,0,0,0, + 1,255,255,255,2,176,176,176,1,183,183,183,2,0,0,0,1,183,183,183, + 2,128,128,128,1,255,255,255,1,183,183,183,5,128,128,128,2,171,171,171, + 2,128,128,128,1,255,255,255,3,0,0,0,1,255,255,255,2,176,176,176, + 1,172,172,172,5,128,128,128,1,255,255,255,1,172,172,172,5,128,128,128, + 2,171,171,171,2,128,128,128,1,255,255,255,2,0,0,0,1,255,255,255, + 1,0,0,0,1,255,255,255,1,176,176,176,1,167,167,167,5,128,128,128, + 1,255,255,255,1,167,167,167,5,128,128,128,2,171,171,171,2,128,128,128, + 1,255,255,255,6,128,128,128,15,171,171,171,1,128,128,128,24,171,171,171, + 1,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128, + 1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171, + 20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128, + 1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171, + 2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,1,36,1,0, + 0,0,0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0, + 20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 1,255,255,255,24,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,1,255,255,255,24,0,0,0,1,255,255,255, + 1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0, + 20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,20,255,255,255,1,0,0,0,1,0,0) + ); + +const + objdata_ttreeitemedit: record size: integer; data: array[0..1040] of byte end = + (size: 1041; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,116,114, + 101,101,105,116,101,109,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,152,3,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,60,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128, + 128,128,1,255,255,255,20,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,1,0,0,0,7,255,255,255,8,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,1,0,0,0,1,255,255,255,5,0,0,0,1,255,255,255,9,0, + 0,0,1,255,255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,9,0,0,0,1,255,255,255,2,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,1,0,0,0,1,255,255,255,1,0, + 0,0,3,255,255,255,1,0,0,0,1,255,255,255,9,0,0,0,1,255, + 255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,1,0, + 0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,9,0,0,0,1,255,255,255,2,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,1,0,0,0,1,255,255,255,5,0,0,0,1,255, + 255,255,9,0,0,0,1,255,255,255,2,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,1,0,0,0,7,255,255,255,9,0,0,0,1,255, + 255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,16,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,20,128,128,128,1,171,171,171,1,128, + 128,128,24,171,171,171,1,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,1,36,1,0,0,0,0,0,1,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,1,255,255,255,24,0,0,0,1,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,24,0, + 0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,1,0, + 0) + ); + +const + objdata_tfoldedit: record size: integer; data: array[0..1620] of byte end = + (size: 1621; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,102,111, + 108,100,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,224,5,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,76,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,171,171,171,1,128,128,128,2,171,171,171,18,128, + 128,128,2,171,171,171,2,128,128,128,2,171,171,171,18,128,128,128,2,171, + 171,171,2,128,128,128,2,171,171,171,18,128,128,128,2,171,171,171,2,128, + 128,128,2,171,171,171,18,128,128,128,2,171,171,171,2,128,128,128,2,171, + 171,171,18,128,128,128,2,171,171,171,2,128,128,128,2,171,171,171,18,128, + 128,128,2,171,171,171,1,128,128,128,26,210,210,210,1,250,250,250,18,210, + 210,210,1,128,128,128,2,171,171,171,1,128,128,128,1,228,228,228,1,120, + 120,120,1,39,39,39,6,235,235,235,1,255,255,255,1,239,239,239,1,185, + 185,185,1,241,241,241,1,255,255,255,3,195,195,195,1,107,107,107,1,174, + 174,174,1,98,98,98,1,128,128,128,1,171,171,171,2,128,128,128,1,228, + 228,228,1,95,95,95,1,153,153,153,1,223,223,223,4,27,27,27,1,231, + 231,231,1,255,255,255,1,70,70,70,1,136,136,136,1,238,238,238,1,255, + 255,255,3,246,246,246,1,169,169,169,1,110,110,110,1,206,206,206,1,128, + 128,128,1,171,171,171,2,128,128,128,1,228,228,228,1,95,95,95,1,175, + 175,175,1,255,255,255,1,81,81,81,1,212,212,212,1,255,255,255,1,31, + 31,31,1,231,231,231,1,187,187,187,1,27,27,27,1,140,140,140,1,254, + 254,254,1,186,186,186,1,126,126,126,1,200,200,200,1,255,255,255,1,175, + 175,175,1,95,95,95,1,228,228,228,1,128,128,128,1,171,171,171,2,128, + 128,128,1,228,228,228,1,95,95,95,1,175,175,175,1,77,77,77,1,1, + 1,1,1,6,6,6,1,217,217,217,1,31,31,31,1,231,231,231,1,243, + 243,243,1,50,50,50,1,234,234,234,1,185,185,185,1,101,101,101,1,219, + 219,219,1,85,85,85,1,188,188,188,1,175,175,175,1,95,95,95,1,228, + 228,228,1,128,128,128,1,171,171,171,2,128,128,128,1,228,228,228,1,95, + 95,95,1,175,175,175,1,255,255,255,1,69,69,69,1,209,209,209,1,255, + 255,255,1,31,31,31,1,231,231,231,1,255,255,255,1,55,55,55,1,255, + 255,255,1,91,91,91,1,218,218,218,1,255,255,255,1,196,196,196,1,100, + 100,100,1,175,175,175,1,95,95,95,1,228,228,228,1,128,128,128,1,171, + 171,171,2,128,128,128,1,228,228,228,1,95,95,95,1,159,159,159,1,231, + 231,231,4,28,28,28,1,231,231,231,1,255,255,255,1,55,55,55,1,255, + 255,255,1,129,129,129,1,184,184,184,1,255,255,255,1,163,163,163,1,118, + 118,118,1,175,175,175,1,95,95,95,1,228,228,228,1,128,128,128,1,171, + 171,171,2,128,128,128,1,228,228,228,1,115,115,115,1,31,31,31,6,234, + 234,234,1,255,255,255,1,55,55,55,1,255,255,255,1,225,225,225,1,92, + 92,92,1,96,96,96,1,71,71,71,1,219,219,219,1,169,169,169,1,110, + 110,110,1,206,206,206,1,128,128,128,1,171,171,171,2,128,128,128,1,228, + 228,228,1,255,255,255,15,195,195,195,1,107,107,107,1,174,174,174,1,98, + 98,98,1,128,128,128,1,171,171,171,1,128,128,128,2,210,210,210,1,250, + 250,250,18,210,210,210,1,128,128,128,26,171,171,171,1,128,128,128,2,171, + 171,171,18,128,128,128,2,171,171,171,2,128,128,128,2,171,171,171,18,128, + 128,128,2,171,171,171,2,128,128,128,2,171,171,171,18,128,128,128,2,171, + 171,171,2,128,128,128,2,171,171,171,18,128,128,128,2,171,171,171,2,128, + 128,128,2,171,171,171,18,128,128,128,2,171,171,171,2,128,128,128,2,171, + 171,171,18,128,128,128,2,171,171,171,1,92,2,0,0,0,0,0,1,76, + 76,76,1,55,55,55,1,0,0,0,18,55,55,55,1,76,76,76,1,0, + 0,0,2,144,144,144,1,104,104,104,1,0,0,0,18,104,104,104,1,144, + 144,144,1,0,0,0,2,144,144,144,1,104,104,104,1,0,0,0,18,104, + 104,104,1,144,144,144,1,0,0,0,2,144,144,144,1,104,104,104,1,0, + 0,0,18,104,104,104,1,144,144,144,1,0,0,0,2,144,144,144,1,104, + 104,104,1,0,0,0,18,104,104,104,1,144,144,144,1,0,0,0,2,144, + 144,144,1,104,104,104,1,0,0,0,18,104,104,104,1,144,144,144,1,0, + 0,0,1,102,102,102,1,228,228,228,1,218,218,218,1,192,192,192,18,218, + 218,218,1,228,228,228,1,102,102,102,1,25,25,25,1,165,165,165,1,191, + 191,191,1,217,217,217,18,191,191,191,1,165,165,165,1,25,25,25,1,0, + 0,0,1,144,144,144,1,194,194,194,1,255,255,255,18,225,225,225,1,144, + 144,144,1,0,0,0,2,144,144,144,1,194,194,194,1,255,255,255,18,199, + 199,199,1,144,144,144,1,0,0,0,2,144,144,144,1,194,194,194,1,255, + 255,255,18,194,194,194,1,144,144,144,1,0,0,0,2,144,144,144,1,194, + 194,194,1,255,255,255,18,194,194,194,1,144,144,144,1,0,0,0,2,144, + 144,144,1,194,194,194,1,255,255,255,18,194,194,194,1,144,144,144,1,0, + 0,0,2,144,144,144,1,194,194,194,1,255,255,255,18,194,194,194,1,144, + 144,144,1,0,0,0,2,144,144,144,1,194,194,194,1,255,255,255,18,199, + 199,199,1,144,144,144,1,0,0,0,2,144,144,144,1,194,194,194,1,255, + 255,255,18,225,225,225,1,144,144,144,1,0,0,0,1,25,25,25,1,165, + 165,165,1,191,191,191,1,217,217,217,18,191,191,191,1,165,165,165,1,25, + 25,25,1,102,102,102,1,228,228,228,1,218,218,218,1,192,192,192,18,218, + 218,218,1,228,228,228,1,102,102,102,1,0,0,0,1,144,144,144,1,104, + 104,104,1,0,0,0,18,104,104,104,1,144,144,144,1,0,0,0,2,144, + 144,144,1,104,104,104,1,0,0,0,18,104,104,104,1,144,144,144,1,0, + 0,0,2,144,144,144,1,104,104,104,1,0,0,0,18,104,104,104,1,144, + 144,144,1,0,0,0,2,144,144,144,1,104,104,104,1,0,0,0,18,104, + 104,104,1,144,144,144,1,0,0,0,2,144,144,144,1,104,104,104,1,0, + 0,0,18,104,104,104,1,144,144,144,1,0,0,0,2,76,76,76,1,55, + 55,55,1,0,0,0,18,55,55,55,1,76,76,76,1,0,0,0,1,0, + 0) + ); + +const + objdata_tmemoedit: record size: integer; data: array[0..1352] of byte end = + (size: 1353; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,109,101, + 109,111,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,212,4,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,136,4,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,2,11,11,11,1,91,91,91,1,255, + 255,255,3,125,125,125,1,11,11,11,1,255,255,255,11,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,22,22,22,1,43, + 43,43,1,246,246,246,1,255,255,255,2,58,58,58,1,21,21,21,1,255, + 255,255,11,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,2,23,23,23,1,119,119,119,1,170,170,170,1,255,255,255,1,196, + 196,196,1,113,113,113,1,23,23,23,1,255,255,255,1,217,217,217,1,64, + 64,64,1,58,58,58,1,56,56,56,1,204,204,204,1,255,255,255,5,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,23, + 23,23,1,209,209,209,1,82,82,82,1,255,255,255,1,104,104,104,1,205, + 205,205,1,23,23,23,1,255,255,255,1,61,61,61,1,195,195,195,1,255, + 255,255,1,212,212,212,1,42,42,42,1,255,255,255,5,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,23,23,23,1,255, + 255,255,1,52,52,52,1,235,235,235,1,60,60,60,1,255,255,255,1,23, + 23,23,1,255,255,255,1,18,18,18,1,63,63,63,3,33,33,33,1,249, + 249,249,1,255,255,255,4,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,2,23,23,23,1,255,255,255,1,135,135,135,1,85, + 85,85,1,133,133,133,1,255,255,255,1,23,23,23,1,255,255,255,1,57, + 57,57,1,214,214,214,1,255,255,255,1,231,231,231,1,132,132,132,1,255, + 255,255,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,2,23,23,23,1,255,255,255,1,225,225,225,1,2,2,2,1,224, + 224,224,1,255,255,255,1,23,23,23,1,255,255,255,1,212,212,212,1,64, + 64,64,1,61,61,61,1,53,53,53,1,177,177,177,1,255,255,255,5,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,11, + 11,11,1,91,91,91,1,255,255,255,3,125,125,125,1,11,11,11,1,255, + 255,255,7,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,22, + 22,22,1,43,43,43,1,246,246,246,1,255,255,255,2,58,58,58,1,21, + 21,21,1,255,255,255,8,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,23,23,23,1,119, + 119,119,1,170,170,170,1,255,255,255,1,196,196,196,1,113,113,113,1,23, + 23,23,1,255,255,255,1,210,210,210,1,58,58,58,1,57,57,57,1,58, + 58,58,1,210,210,210,1,255,255,255,2,0,0,0,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,23, + 23,23,1,209,209,209,1,82,82,82,1,255,255,255,1,104,104,104,1,205, + 205,205,1,23,23,23,1,255,255,255,1,56,56,56,1,196,196,196,1,255, + 255,255,1,194,194,194,1,55,55,55,1,255,255,255,2,0,0,0,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,2,23,23,23,1,255,255,255,1,52,52,52,1,235,235,235,1,60, + 60,60,1,255,255,255,1,23,23,23,1,255,255,255,1,20,20,20,1,255, + 255,255,2,254,254,254,1,21,21,21,1,255,255,255,2,0,0,0,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,2,23,23,23,1,255,255,255,1,135,135,135,1,85,85,85,1,133, + 133,133,1,255,255,255,1,23,23,23,1,255,255,255,1,55,55,55,1,197, + 197,197,1,255,255,255,1,195,195,195,1,55,55,55,1,255,255,255,2,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,2,23,23,23,1,255,255,255,1,225,225,225,1,2, + 2,2,1,224,224,224,1,255,255,255,1,23,23,23,1,255,255,255,1,208, + 208,208,1,57,57,57,1,58,58,58,1,59,59,59,1,209,209,209,1,255, + 255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,16,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224, + 224,224,22,255,255,255,25,20,0,0,0,255,255,255,255,255,255,255,255,255, + 255,255,42,128,128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tkeystringedit: record size: integer; data: array[0..1177] of byte end = + (size: 1178; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,107,101, + 121,115,116,114,105,110,103,101,100,105,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,32,4,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,220,3,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,2, + 165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,0,0,0,1, + 1,1,1,1,75,75,75,1,255,255,255,4,0,0,0,1,234,234,234,1, + 23,23,23,1,255,255,255,6,128,128,128,1,255,255,255,2,88,88,88,1, + 75,75,75,1,89,89,89,1,255,255,255,2,0,0,0,1,234,234,234,1, + 70,70,70,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208,208,3, + 128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,251,251,251,1, + 21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255,255,255,1, + 0,0,0,2,117,117,117,1,255,255,255,5,0,0,0,1,255,255,255,2, + 0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1, + 191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,1,0,0,0,1, + 243,243,243,1,11,11,11,1,255,255,255,5,0,0,0,1,255,255,255,2, + 208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,114,114,114,1,141,141,141,1,255,255,255,1, + 141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,1,235,235,235,1, + 19,19,19,1,255,255,255,3,252,252,252,1,231,231,231,1,0,0,0,1, + 247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,37,37,37,1,217,217,217,1,255,255,255,1, + 217,217,217,1,38,38,38,1,255,255,255,1,0,0,0,1,3,3,3,1, + 124,124,124,1,255,255,255,3,223,223,223,1,0,0,0,1,223,223,223,1, + 0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255,255,255,22, + 0,0,0,2,255,255,255,18,208,208,208,1,0,0,0,1,208,208,208,1, + 128,128,128,1,0,0,0,2,255,255,255,18,0,0,0,3,128,128,128,1, + 0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,2,157,157,157,1, + 102,102,102,1,255,255,255,12,208,208,208,3,128,128,128,1,0,0,0,2, + 255,255,255,1,0,0,0,1,255,255,255,1,201,201,201,1,65,65,65,1, + 249,249,249,1,255,255,255,11,128,128,128,5,0,0,0,2,255,255,255,1, + 0,0,0,1,233,233,233,1,53,53,53,1,230,230,230,1,255,255,255,1, + 186,186,186,1,25,25,25,2,195,195,195,1,255,255,255,1,52,52,52,1, + 203,203,203,1,255,255,255,1,204,204,204,1,50,50,50,1,255,255,255,2, + 212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2, + 255,255,255,1,0,0,0,1,62,62,62,1,124,124,124,1,255,255,255,2, + 39,39,39,1,194,194,194,1,197,197,197,1,50,50,50,1,255,255,255,1, + 157,157,157,1,97,97,97,1,255,255,255,1,102,102,102,1,152,152,152,1, + 255,255,255,5,128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1, + 146,146,146,1,57,57,57,1,208,208,208,1,255,255,255,1,3,3,3,1, + 0,0,0,2,4,4,4,1,255,255,255,1,246,246,246,1,27,27,27,1, + 226,226,226,1,25,25,25,1,242,242,242,1,255,255,255,2,128,128,128,4, + 0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,1,217,217,217,1, + 51,51,51,1,244,244,244,1,34,34,34,1,195,195,195,1,255,255,255,4, + 113,113,113,1,55,55,55,1,99,99,99,1,255,255,255,2,208,208,208,1, + 255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0,2, + 255,255,255,1,0,0,0,1,255,255,255,2,161,161,161,1,94,94,94,1, + 179,179,179,1,23,23,23,1,13,13,13,1,120,120,120,1,255,255,255,2, + 217,217,217,1,0,0,0,1,201,201,201,1,255,255,255,4,252,252,252,1, + 255,255,255,2,0,0,0,2,255,255,255,12,202,202,202,1,41,41,41,1, + 255,255,255,4,208,208,208,3,128,128,128,1,0,0,0,2,255,255,255,12, + 12,12,12,1,168,168,168,1,255,255,255,4,0,0,0,3,128,128,128,1, + 0,0,0,2,255,255,255,18,208,208,208,1,0,0,0,1,208,208,208,1, + 128,128,128,1,0,0,0,2,255,255,255,17,128,128,128,5,0,0,0,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tpointeredit: record size: integer; data: array[0..763] of byte end = + (size: 764; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,112,111, + 105,110,116,101,114,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,132,2,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,60,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0, + 0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0, + 0,1,171,171,171,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,5,0,0,0,1,255,255, + 255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,1,0,0,0,1,39,39,39,1,249,249,249,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,6,0,0,0,1,255,255,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,107,107, + 107,1,139,139,139,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,1,0,0,0,1,235,235,235,1,31,31,31,1,235,235,235,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,6,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,139,139, + 139,1,106,106,106,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,1,249,249,249,1,38,38,38,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0, + 0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,171,171,171,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,5,255,255, + 255,2,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0,0, + 0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255, + 255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0, + 0,120,0,0) + ); + +const + objdata_tcalendardatetimeedit: record size: integer; data: array[0..1092] of byte end = + (size: 1093; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,99,97, + 108,101,110,100,97,114,100,97,116,101,116,105,109,101,101,100,105,116,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,196,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,128,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,255,255,255,1,0,0,0,2,5,5,5,1,174,174,174,1,255, + 255,255,3,0,0,0,5,255,255,255,1,0,0,0,1,234,234,234,1,23, + 23,23,1,255,255,255,6,128,128,128,1,255,255,255,1,0,0,0,1,255, + 255,255,1,174,174,174,1,5,5,5,1,255,255,255,2,0,0,0,1,255, + 255,255,2,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,2,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,0, + 0,0,1,255,255,255,2,0,0,0,1,255,255,255,5,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,2,0,0,0,3,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,4,0,0,0,1,255, + 255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,0,0,0,1,255,255,255,1,174, + 174,174,1,5,5,5,1,255,255,255,5,0,0,0,1,255,255,255,2,252, + 252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255,255,255,1,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,0, + 0,0,2,5,5,5,1,174,174,174,1,255,255,255,2,0,0,0,1,255, + 255,255,2,0,0,0,1,255,255,255,2,223,223,223,1,0,0,0,1,223, + 223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255, + 255,255,22,0,0,0,2,255,255,255,1,179,179,179,2,255,255,255,1,179, + 179,179,2,255,255,255,1,179,179,179,2,255,255,255,1,179,179,179,2,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,255,2,255,255,255,1,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,2,240,240,240,1,7,7,7,1,23, + 23,23,1,255,255,255,1,7,7,7,2,255,255,255,1,7,7,7,2,255, + 255,255,1,0,0,255,2,255,255,255,1,0,0,0,2,255,255,255,10,247, + 247,247,1,248,248,248,1,255,255,255,1,247,247,247,2,255,255,255,1,247, + 247,247,2,255,255,255,4,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,1,0,0,0,2,248,248,248,1,7,7,7,1,15,15,15,1,255, + 255,255,1,0,0,0,2,255,255,255,1,15,15,15,1,7,7,7,1,233, + 233,233,1,7,7,7,1,23,23,23,1,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,255,2,255,255,255,1,0,0,0,2,255,255,255,4,247, + 247,247,1,248,248,248,1,255,255,255,4,248,248,248,1,247,247,247,1,255, + 255,255,1,247,247,247,1,248,248,248,1,255,255,255,7,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,1,7,7,7,2,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,2,255,255,255,1,15,15,15,1,7, + 7,7,1,248,248,248,1,0,0,0,2,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,255,2,255,255,255,1,0,0,0,2,255,255,255,1,247, + 247,247,2,255,255,255,7,248,248,248,1,247,247,247,1,255,255,255,10,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,1,0,0,0,2,247, + 247,247,1,0,0,0,1,7,7,7,1,240,240,240,1,15,15,15,1,30, + 30,30,1,255,255,255,1,7,7,7,1,0,0,0,1,247,247,247,1,159, + 159,159,2,255,255,255,1,179,179,179,2,255,255,255,1,197,197,197,1,183, + 183,183,1,242,242,242,1,0,0,0,15,10,10,10,2,0,0,0,4,9, + 9,9,1,11,11,11,1,2,2,2,1,0,0,0,1,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdatabutton: record size: integer; data: array[0..666] of byte end = + (size: 667; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,97, + 116,97,98,117,116,116,111,110,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,36,2,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,220,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,120,224,224,224,25,255,255,255, + 22,0,0,0,1,224,224,224,1,255,255,255,1,235,235,235,20,128,128,128, + 1,0,0,0,1,224,224,224,1,255,255,255,1,232,232,232,20,128,128,128, + 1,0,0,0,1,224,224,224,1,255,255,255,1,229,229,229,4,214,214,214, + 1,26,26,26,1,229,229,229,1,154,154,154,1,19,19,19,1,16,16,16, + 1,133,133,133,1,103,103,103,1,13,13,13,2,115,115,115,1,229,229,229, + 5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,226,226,226, + 4,87,87,87,1,0,0,0,1,226,226,226,1,26,26,26,1,178,178,178, + 1,185,185,185,1,9,9,9,1,226,226,226,2,172,172,172,1,15,15,15, + 1,226,226,226,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,223,223,223,4,216,216,216,1,0,0,0,1,223,223,223,3,179,179,179, + 1,59,59,59,1,223,223,223,1,143,143,143,1,3,3,3,1,90,90,90, + 1,223,223,223,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,221,221,221,5,0,0,0,1,221,221,221,2,194,194,194,1,61,61,61, + 1,201,201,201,1,221,221,221,2,185,185,185,1,9,9,9,1,221,221,221, + 5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,218,218,218, + 5,0,0,0,1,218,218,218,1,141,141,141,1,66,66,66,1,201,201,201, + 1,218,218,218,1,27,27,27,1,194,194,194,1,200,200,200,1,21,21,21, + 1,218,218,218,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,215,215,215,5,0,0,0,1,215,215,215,1,16,16,16,1,0,0,0, + 3,149,149,149,1,16,16,16,1,20,20,20,1,151,151,151,1,215,215,215, + 5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,212,212,212, + 20,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,209,209,209, + 20,128,128,128,1,0,0,0,1,224,224,224,1,128,128,128,22,0,0,0, + 25,255,255,255,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tstockglyphdatabutton: record size: integer; data: array[0..704] of byte end = + (size: 705; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,115,116, + 111,99,107,103,108,121,112,104,100,97,116,97,98,117,116,116,111,110,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,64,2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,248,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,120,224,224,224,25,255,255,255,22,0,0,0,1,224,224,224,1,255, + 255,255,1,235,235,235,20,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,232,232,232,20,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,214,214,214,1,26,26,26,1,229,229,229,1,154,154,154,1,19, + 19,19,1,16,16,16,1,133,133,133,1,103,103,103,1,13,13,13,2,115, + 115,115,1,229,229,229,9,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,87,87,87,1,0,0,0,1,226,226,226,1,26,26,26,1,178, + 178,178,1,185,185,185,1,9,9,9,1,226,226,226,2,172,172,172,1,15, + 15,15,1,226,226,226,9,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,216,216,216,1,0,0,0,1,223,223,223,3,179,179,179,1,59, + 59,59,1,223,223,223,1,143,143,143,1,3,3,3,1,90,90,90,1,223, + 223,223,1,62,62,62,2,223,223,223,1,62,62,62,2,223,223,223,1,62, + 62,62,2,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,221, + 221,221,1,0,0,0,1,221,221,221,2,194,194,194,1,61,61,61,1,201, + 201,201,1,221,221,221,2,185,185,185,1,9,9,9,1,221,221,221,1,62, + 62,62,2,221,221,221,1,62,62,62,2,221,221,221,1,62,62,62,2,128, + 128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,218,218,218,1,0, + 0,0,1,218,218,218,1,141,141,141,1,66,66,66,1,201,201,201,1,218, + 218,218,1,27,27,27,1,194,194,194,1,200,200,200,1,21,21,21,1,218, + 218,218,9,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,215, + 215,215,1,0,0,0,1,215,215,215,1,16,16,16,1,0,0,0,3,149, + 149,149,1,16,16,16,1,20,20,20,1,151,151,151,1,215,215,215,9,128, + 128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,212,212,212,20,128, + 128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,209,209,209,20,128, + 128,128,1,0,0,0,1,224,224,224,1,128,128,128,22,0,0,0,25,255, + 255,255,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_tprogressbar: record size: integer; data: array[0..451] of byte end = + (size: 452; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,112,114, + 111,103,114,101,115,115,98,97,114,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,1,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,4,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0, + 0,22,255,255,255,1,128,128,128,1,0,0,0,1,208,208,208,20,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,222,209,14,208,208, + 208,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,203, + 183,14,208,208,208,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,185,157,14,208,208,208,6,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,166,131,14,208,208,208,6,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,147,105,14,208,208,208,6,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,128,79,14,208,208, + 208,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,110, + 53,14,208,208,208,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,91,26,14,208,208,208,6,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,208,208,208,20,224,224,224,1,255,255,255,1,128,128, + 128,1,224,224,224,22,255,255,255,145,16,0,0,0,0,0,0,120,255,255, + 255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_thexstringedit: record size: integer; data: array[0..817] of byte end = + (size: 818; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,104,101, + 120,115,116,114,105,110,103,101,100,105,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,2,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,112,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2, + 254,254,254,1,31,31,31,1,173,173,173,1,255,255,255,1,205,205,205,1, + 49,49,49,1,50,50,50,1,208,208,208,1,255,255,255,2,249,249,249,1, + 28,28,28,1,255,255,255,3,0,0,0,1,255,255,255,1,0,0,0,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2, + 207,207,207,1,78,78,78,1,97,97,97,1,255,255,255,1,71,71,71,1, + 188,188,188,1,187,187,187,1,75,75,75,1,255,255,255,1,200,200,200,1, + 39,39,39,1,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2, + 128,128,128,1,199,199,199,1,53,53,53,1,253,253,253,1,15,15,15,1, + 242,242,242,1,240,240,240,1,17,17,17,1,255,255,255,1,252,252,252,1, + 247,247,247,1,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2, + 74,74,74,1,253,253,253,1,102,102,102,1,201,201,201,1,1,1,1,1, + 254,254,254,1,252,252,252,1,2,2,2,1,255,255,255,3,0,0,0,1, + 255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,255,255,1,224,224,224,1,0,0,0,3, + 125,125,125,1,15,15,15,1,242,242,242,1,240,240,240,1,16,16,16,1, + 255,255,255,3,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1, + 145,145,145,1,162,162,162,1,255,255,255,1,241,241,241,1,55,55,55,1, + 71,71,71,1,188,188,188,1,186,186,186,1,73,73,73,1,255,255,255,3, + 0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,70,70,70,1, + 236,236,236,1,255,255,255,2,66,66,66,1,179,179,179,1,49,49,49,2, + 206,206,206,1,255,255,255,3,0,0,0,1,255,255,255,4,0,0,0,1, + 255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 255,255,255,17,0,0,0,1,255,255,255,1,0,0,0,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1, + 255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16,0,0,0, + 0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +initialization + registerobjectdata(@objdata_twidgetgrid,tbitmapcomp,'twidgetgrid'); + registerobjectdata(@objdata_tdataedit,tbitmapcomp,'tdataedit'); + registerobjectdata(@objdata_ttextedit,tbitmapcomp,'ttextedit'); + registerobjectdata(@objdata_tundotextedit,tbitmapcomp,'tundotextedit'); + registerobjectdata(@objdata_tslider,tbitmapcomp,'tslider'); + registerobjectdata(@objdata_tbooleanedit,tbitmapcomp,'tbooleanedit'); + registerobjectdata(@objdata_tbooleaneditradio,tbitmapcomp,'tbooleaneditradio'); + registerobjectdata(@objdata_tdataicon,tbitmapcomp,'tdataicon'); + registerobjectdata(@objdata_tdataimage,tbitmapcomp,'tdataimage'); + registerobjectdata(@objdata_tstringedit,tbitmapcomp,'tstringedit'); + registerobjectdata(@objdata_tdropdownlistedit,tbitmapcomp,'tdropdownlistedit'); + registerobjectdata(@objdata_tintegeredit,tbitmapcomp,'tintegeredit'); + registerobjectdata(@objdata_tint64edit,tbitmapcomp,'tint64edit'); + registerobjectdata(@objdata_trealedit,tbitmapcomp,'trealedit'); + registerobjectdata(@objdata_trealspinedit,tbitmapcomp,'trealspinedit'); + registerobjectdata(@objdata_tdatetimeedit,tbitmapcomp,'tdatetimeedit'); + registerobjectdata(@objdata_tenumedit,tbitmapcomp,'tenumedit'); + registerobjectdata(@objdata_thistoryedit,tbitmapcomp,'thistoryedit'); + registerobjectdata(@objdata_tenumtypeedit,tbitmapcomp,'tenumtypeedit'); + registerobjectdata(@objdata_tselector,tbitmapcomp,'tselector'); + registerobjectdata(@objdata_titemedit,tbitmapcomp,'titemedit'); + registerobjectdata(@objdata_trecordfieldedit,tbitmapcomp,'trecordfieldedit'); + registerobjectdata(@objdata_tdropdownitemedit,tbitmapcomp,'tdropdownitemedit'); + registerobjectdata(@objdata_tmbdropdownitemedit,tbitmapcomp,'tmbdropdownitemedit'); + registerobjectdata(@objdata_ttreeitemedit,tbitmapcomp,'ttreeitemedit'); + registerobjectdata(@objdata_tfoldedit,tbitmapcomp,'tfoldedit'); + registerobjectdata(@objdata_tmemoedit,tbitmapcomp,'tmemoedit'); + registerobjectdata(@objdata_tkeystringedit,tbitmapcomp,'tkeystringedit'); + registerobjectdata(@objdata_tpointeredit,tbitmapcomp,'tpointeredit'); + registerobjectdata(@objdata_tcalendardatetimeedit,tbitmapcomp,'tcalendardatetimeedit'); + registerobjectdata(@objdata_tdatabutton,tbitmapcomp,'tdatabutton'); + registerobjectdata(@objdata_tstockglyphdatabutton,tbitmapcomp,'tstockglyphdatabutton'); + registerobjectdata(@objdata_tprogressbar,tbitmapcomp,'tprogressbar'); + registerobjectdata(@objdata_thexstringedit,tbitmapcomp,'thexstringedit'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regexperimental.pas b/mseide-msegui/lib/common/regcomponents/regexperimental.pas new file mode 100644 index 0000000..b7d10d5 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regexperimental.pas @@ -0,0 +1,31 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regexperimental; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + msedesignintf,msetraywidget; + +procedure Register; +begin +// registercomponents('Exp',[]); + registercomponenttabhints(['Exp'],['Experimental components']); +end; +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regglob.pas b/mseide-msegui/lib/common/regcomponents/regglob.pas new file mode 100644 index 0000000..52ce861 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regglob.pas @@ -0,0 +1,144 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msepropertyeditors,typinfo,msebitmap,msetypes{msestrings}; + +type + tstockglypheditor = class(tenumpropertyeditor) + protected + function hasimagelist(): boolean; + function gettypeinfo: ptypeinfo; override; + function getdefaultstate: propertystatesty; override; + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + procedure edit; override; + end; + + tstockglypharraypropertyeditor = class(tintegerarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + timagenrpropertyeditor = class(tordinalpropertyeditor) + private + fintf: iimagelistinfo; + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + +implementation +uses + msestockobjects,mseimageselectorform,mseclasses,mseformatstr; + +{ tstockglypharraypropertyeditor } + +function tstockglypharraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tstockglypheditor; +end; + +{ tstockglypheditor } + +function tstockglypheditor.gettypeinfo: ptypeinfo; +begin + result:= typeinfo(stockglyphty); +end; + +function tstockglypheditor.hasimagelist(): boolean; +var + intf1: iimagelistinfo; +begin + result:= getcorbainterface(fprops[0].instance, + typeinfo(iimagelistinfo),intf1) and (intf1.getimagelist() <> nil); +end; + +function tstockglypheditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; + if hasimagelist then begin + result:= result - [ps_valuelist]; + end; +end; + +procedure tstockglypheditor.setvalue(const value: msestring); +begin + if hasimagelist then begin + setordvalue(strtointvalue(ansistring(value))); + end + else begin + inherited; + end; +end; + +function tstockglypheditor.getvalue: msestring; +begin + if hasimagelist then begin + result:= inttostrmse(getordvalue); + end + else begin + result:= inherited getvalue(); + end; +end; + +procedure tstockglypheditor.edit; +var + int1: integer; + intf1: iimagelistinfo; + list1: timagelist; +begin + int1:= getordvalue; + intf1:= nil; + if getcorbainterface(fprops[0].instance, + typeinfo(iimagelistinfo),intf1) then begin + list1:= intf1.getimagelist; + end; + if list1 = nil then begin + list1:= stockobjects.glyphs; + end; + timageselectorfo.create(nil,list1,int1); + setordvalue(int1); +end; + +{ timagenrpropertyeditor } + +function timagenrpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + if getcorbainterface(fprops[0].instance,typeinfo(iimagelistinfo),fintf) and + (fintf.getimagelist <> nil) then begin + result:= result + [ps_dialog]; + end; +end; + +procedure timagenrpropertyeditor.edit; +var + int1: integer; +begin + if fintf <> nil then begin + int1:= getordvalue; + timageselectorfo.create(nil,fintf.getimagelist,int1); + setordvalue(int1); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/regcomponents/regifi.pas b/mseide-msegui/lib/common/regcomponents/regifi.pas new file mode 100644 index 0000000..90055b9 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regifi.pas @@ -0,0 +1,259 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regifi; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + mseglob,classes,mseificomp,msedesignintf,regifi_bmp,msepropertyeditors, + mseclasses,mselistbrowser, + msecomponenteditors,mseificomponenteditors,msetypes{msestrings},msedatalist, + {$ifndef mse_no_db}{$ifdef FPC}mseifidbcomp,{$endif}{$endif} + mseifidialogcomp,mseifigui,mseifiendpoint, + typinfo,mseififieldeditor; + +type + tificonnectedfields1 = class(tificonnectedfields); +{ + tifiwidgeteditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + end; +} + tifidropdowncolpropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tificolitempropertyeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tifilinkcomparraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tififieldnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tifisourcefieldnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure setvalue(const value: msestring); override; + function getvalues: msestringarty; override; + end; + + tifidataconnectionpropertyeditor = class(tcomponentinterfacepropertyeditor) + protected + function getintfinfo: ptypeinfo; override; + end; + + tificonnectedfieldselementeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tificonnectedfieldspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + +procedure register; +begin + registercomponents('ifi',[tifiintegerendpoint,tifiint64endpoint, + tifipointerendpoint, + tifibooleanendpoint,tifirealendpoint,tifidatetimeendpoint, + tifistringendpoint,tifiactionendpoint, + tifiintegerlinkcomp,tifiint64linkcomp,tifipointerlinkcomp, + tifibooleanlinkcomp, + tifireallinkcomp,tifidatetimelinkcomp,tifistringlinkcomp, + tifienumlinkcomp,tifidropdownlistlinkcomp, + tifiactionlinkcomp,tififormlinkcomp, + tifidialoglinkcomp,tifidialog, + tifigridlinkcomp,tifiitemlinkcomp,tifitreeitemlinkcomp, + tconnectedifidatasource{,tifisqldatasource,} + {$ifndef mse_no_db}{$ifdef FPC},tifisqlresult{$endif}{$endif}]); + registercomponenttabhints(['ifi'], + ['MSEifi and socket components.'+lineend+ + 'Please compile with -dmse_with_pascalscript for PascalScript components.']); +// registerpropertyeditor(typeinfo(tcomponent),tcustomificlientcontroller, +// 'widget',tifiwidgeteditor); + registercomponenteditor(tifilinkcomp,tifilinkcompeditor); + registerpropertyeditor(typeinfo(tifidropdowncols),nil,'', + tifidropdowncolpropertyeditor); + registerpropertyeditor(typeinfo(tifilinkcomparrayprop),nil,'', + tifilinkcomparraypropertyeditor); + registerpropertyeditor(typeinfo(ififieldnamety),nil,'', + tififieldnamepropertyeditor); + registerpropertyeditor(typeinfo(ifisourcefieldnamety),nil,'', + tifisourcefieldnamepropertyeditor); + registerpropertyeditor(typeinfo(tificonnectedfields),nil,'', + tificonnectedfieldspropertyeditor); + registerpropertyeditor(typeinfo(tmsecomponent),tifidatasource,'connection', + tifidataconnectionpropertyeditor); +end; + +{ tifiwidgeteditor } +{ +function tifiwidgeteditor.filtercomponent( + const acomponent: tcomponent): boolean; +var + intf1: pointer; +begin +// result:= tcustomifivaluewidgetcontroller( +// fprops[0].instance).canconnect(acomponent); +end; +} +{ tifidropdowncolpropertyeditor } + +function tifidropdowncolpropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tmsestringdatalistpropertyeditor; +end; + +{ tificolitempropertyeditor } + +function tificolitempropertyeditor.getvalue: msestring; +var + obj1: tificolitem; +begin + result:= ''; + obj1:= tificolitem(getpointervalue); + if (obj1 <> nil) and (obj1.link <> nil) then begin + result:= msestring('<'+obj1.link.name+'>'); + end; +end; + +{ tifilinkcomparraypropertyeditor } + +function tifilinkcomparraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tificolitempropertyeditor; +end; + +{ tififieldnamepropertyeditor } + +function tififieldnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tififieldnamepropertyeditor.getvalues: msestringarty; +var + intf1: iififieldinfo; + intf2: iififieldsource; + dataso: tifidatasource; + types: listdatatypesty; +begin + result:= nil; + if getcorbainterface(fprops[0].instance,typeinfo(iififieldinfo), + intf1) then begin + dataso:= nil; + types:= []; + intf1.getfieldinfo(ansistring(fname),dataso,types); + if (dataso <> nil) and getcorbainterface(dataso,typeinfo(iififieldsource), + intf2) then begin + result:= intf2.getfieldnames(types); + end; + end; +end; + +{ tifisourcefieldnamepropertyeditor } + +function tifisourcefieldnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist,ps_volatile]; +end; + +function tifisourcefieldnamepropertyeditor.getvalues: msestringarty; +var + intf1: iififieldlinksource; +begin + result:= nil; + if getcorbainterface(fprops[0].instance, + typeinfo(iififieldlinksource),intf1) then begin + result:= intf1.getfieldnames(ansistring(fname)); + end; +end; + +procedure tifisourcefieldnamepropertyeditor.setvalue(const value: msestring); +var + intf1: iififieldlinksource; +begin + inherited; + if getcorbainterface(fprops[0].instance, + typeinfo(iififieldlinksource),intf1) then begin + intf1.setdesignsourcefieldname(ansistring(value)); + end; +end; + +{ tifidataconnectionpropertyeditor } + +function tifidataconnectionpropertyeditor.getintfinfo: ptypeinfo; +begin + result:= typeinfo(iifidataconnection); +end; + +{ tificonnectedfieldselementeditor } + +function tificonnectedfieldselementeditor.getvalue: msestring; +begin + with tififieldlink(getpointervalue) do begin + result:= msestring('<'+sourcefieldname+'><'+fieldname+'>'); + end; +end; + +{ tificonnectedfieldspropertyeditor } + +function tificonnectedfieldspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tificonnectedfieldselementeditor; +end; + +function tificonnectedfieldspropertyeditor.getdefaultstate: propertystatesty; +var + po1: pointer; +begin + result:= inherited getdefaultstate(); + if mseclasses.getcorbainterface( + tificonnectedfields1(getpointervalue).fowner.connection, + typeinfo(iifidbdataconnection),po1) then begin + + result:= result + [ps_dialog]; + end; +end; + +procedure tificonnectedfieldspropertyeditor.edit; +begin + if editififields(tificonnectedfields(getpointervalue)) then begin + modified; + end; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regifi_bmp.pas b/mseide-msegui/lib/common/regcomponents/regifi_bmp.pas new file mode 100644 index 0000000..429e142 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regifi_bmp.pas @@ -0,0 +1,2317 @@ +unit regifi_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tifiintegerendpoint: record size: integer; data: array[0..1282] of byte end = + (size: 1283; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,105,110,116,101,103,101,114,101,110,100,112,111,105,110,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,132,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,164,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143, + 25,208,208,208,15,0,0,0,2,208,208,208,5,151,255,143,2,208,208,208, + 7,0,0,0,11,208,208,208,4,151,255,143,2,208,208,208,7,0,0,0, + 12,208,208,208,3,151,255,143,2,208,208,208,15,0,0,0,3,208,208,208, + 4,151,255,143,2,208,208,208,15,0,0,0,2,208,208,208,5,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,5,0,0,0,2,208,208,208, + 3,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208,4,151,255,143, + 2,208,208,208,4,0,0,0,3,208,208,208,2,0,0,0,10,208,208,208, + 3,151,255,143,2,208,208,208,3,0,0,0,4,208,208,208,1,0,0,0, + 3,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,2,208,208,208, + 3,151,255,143,2,208,208,208,3,0,0,0,4,208,208,208,5,0,0,0, + 2,208,208,208,2,0,0,0,3,208,208,208,3,151,255,143,2,208,208,208, + 5,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208,3,0,0,0, + 3,208,208,208,3,151,255,143,2,208,208,208,5,0,0,0,2,208,208,208, + 2,0,0,0,4,208,208,208,4,0,0,0,3,208,208,208,2,151,255,143, + 2,208,208,208,5,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208, + 3,0,0,0,2,208,208,208,1,0,0,0,3,208,208,208,2,151,255,143, + 2,208,208,208,5,0,0,0,2,208,208,208,1,0,0,0,11,208,208,208, + 3,151,255,143,2,208,208,208,16,0,0,0,1,208,208,208,5,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208, + 22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,25,168,2,0, + 0,240,240,240,25,0,0,0,15,135,135,135,1,52,52,52,1,0,0,0, + 5,240,240,240,2,0,0,0,7,8,8,8,8,80,80,80,1,233,233,233, + 1,58,58,58,1,0,0,0,4,240,240,240,2,0,0,0,7,248,248,248, + 9,252,252,252,1,229,229,229,1,10,10,10,1,0,0,0,3,240,240,240, + 2,0,0,0,15,87,87,87,1,233,233,233,1,52,52,52,1,0,0,0, + 4,240,240,240,2,0,0,0,15,127,127,127,1,47,47,47,1,0,0,0, + 5,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,5,16,16,16, + 1,38,38,38,1,0,0,0,3,22,22,22,1,49,49,49,1,0,0,0, + 3,1,1,1,1,54,54,54,1,29,29,29,1,0,0,0,4,240,240,240, + 2,0,0,0,4,13,13,13,1,189,189,189,1,124,124,124,1,0,0,0, + 2,128,128,128,1,175,175,175,1,146,146,146,1,200,200,200,1,7,7,7, + 1,5,5,5,1,198,198,198,1,139,139,139,1,194,194,194,1,94,94,94, + 1,0,0,0,3,240,240,240,2,0,0,0,3,27,27,27,1,214,214,214, + 1,182,182,182,1,124,124,124,1,0,0,0,1,8,8,8,1,192,192,192, + 1,2,2,2,1,0,0,0,1,146,146,146,1,87,87,87,1,50,50,50, + 1,108,108,108,1,0,0,0,1,46,46,46,1,200,200,200,1,0,0,0, + 3,240,240,240,2,0,0,0,3,16,16,16,1,21,21,21,1,99,99,99, + 1,124,124,124,1,0,0,0,5,196,196,196,1,67,67,67,1,0,0,0, + 2,50,50,50,1,170,170,170,1,115,115,115,1,0,0,0,3,240,240,240, + 2,0,0,0,5,99,99,99,1,124,124,124,1,0,0,0,3,2,2,2, + 1,156,156,156,1,160,160,160,1,0,0,0,3,99,99,99,1,187,187,187, + 1,131,131,131,1,0,0,0,3,240,240,240,2,0,0,0,5,99,99,99, + 1,124,124,124,1,0,0,0,2,5,5,5,1,168,168,168,1,150,150,150, + 1,2,2,2,1,0,0,0,4,2,2,2,1,224,224,224,1,24,24,24, + 1,0,0,0,2,240,240,240,2,0,0,0,5,99,99,99,1,124,124,124, + 1,0,0,0,2,168,168,168,1,127,127,127,1,0,0,0,3,80,80,80, + 1,150,150,150,1,0,0,0,1,11,11,11,1,216,216,216,1,5,5,5, + 1,0,0,0,2,240,240,240,2,0,0,0,5,99,99,99,1,124,124,124, + 1,0,0,0,1,55,55,55,1,255,255,255,1,216,216,216,3,105,105,105, + 1,2,2,2,1,163,163,163,1,180,180,180,1,189,189,189,1,86,86,86, + 1,0,0,0,3,240,240,240,2,0,0,0,16,10,10,10,1,0,0,0, + 5,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240, + 2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0, + 22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240, + 25,0,0) + ); + +const + objdata_tifiint64endpoint: record size: integer; data: array[0..1140] of byte end = + (size: 1141; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,105,102, + 105,105,110,116,54,52,101,110,100,112,111,105,110,116,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,248, + 3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,100, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208, + 208,208,14,0,0,0,2,208,208,208,6,151,255,143,2,208,208,208,6,0, + 0,0,11,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0,12,208, + 208,208,4,151,255,143,2,208,208,208,14,0,0,0,3,208,208,208,5,151, + 255,143,2,208,208,208,14,0,0,0,2,208,208,208,6,151,255,143,2,208, + 208,208,22,151,255,143,2,208,208,208,7,0,0,0,3,208,208,208,4,0, + 0,0,2,208,208,208,6,151,255,143,2,208,208,208,6,0,0,0,5,208, + 208,208,2,0,0,0,3,208,208,208,6,151,255,143,2,208,208,208,6,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,3,208, + 208,208,6,151,255,143,2,208,208,208,5,0,0,0,6,208,208,208,1,0, + 0,0,4,208,208,208,6,151,255,143,2,208,208,208,5,0,0,0,11,208, + 208,208,6,151,255,143,2,208,208,208,5,0,0,0,3,208,208,208,1,0, + 0,0,8,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0,2,208, + 208,208,1,0,0,0,8,208,208,208,5,151,255,143,2,208,208,208,6,0, + 0,0,5,208,208,208,3,0,0,0,2,208,208,208,6,151,255,143,2,208, + 208,208,8,0,0,0,1,208,208,208,13,151,255,143,2,208,208,208,22,151, + 255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208, + 208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151, + 255,143,2,208,208,208,22,151,255,143,25,92,2,0,0,240,240,240,25,0, + 0,0,14,125,125,125,1,64,64,64,1,0,0,0,6,240,240,240,2,0, + 0,0,6,8,8,8,8,66,66,66,1,233,233,233,1,73,73,73,1,0, + 0,0,5,240,240,240,2,0,0,0,6,248,248,248,9,251,251,251,1,241, + 241,241,1,19,19,19,1,0,0,0,4,240,240,240,2,0,0,0,14,72, + 72,72,1,235,235,235,1,67,67,67,1,0,0,0,5,240,240,240,2,0, + 0,0,14,117,117,117,1,59,59,59,1,0,0,0,6,240,240,240,2,0, + 0,0,22,240,240,240,2,0,0,0,7,1,1,1,1,53,53,53,1,7, + 7,7,1,0,0,0,4,33,33,33,1,27,27,27,1,0,0,0,6,240, + 240,240,2,0,0,0,6,56,56,56,1,175,175,175,1,135,135,135,1,212, + 212,212,1,30,30,30,1,0,0,0,2,13,13,13,1,222,222,222,1,96, + 96,96,1,0,0,0,6,240,240,240,2,0,0,0,6,194,194,194,1,42, + 42,42,1,0,0,0,1,60,60,60,1,63,63,63,1,0,0,0,2,157, + 157,157,1,195,195,195,1,96,96,96,1,0,0,0,6,240,240,240,2,0, + 0,0,5,1,1,1,1,230,230,230,1,84,84,84,1,163,163,163,1,81, + 81,81,1,2,2,2,1,0,0,0,1,83,83,83,1,137,137,137,1,135, + 135,135,1,96,96,96,1,0,0,0,6,240,240,240,2,0,0,0,5,16, + 16,16,1,249,249,249,1,141,141,141,1,45,45,45,1,183,183,183,1,77, + 77,77,1,26,26,26,1,189,189,189,1,6,6,6,1,135,135,135,1,96, + 96,96,1,0,0,0,6,240,240,240,2,0,0,0,5,2,2,2,1,247, + 247,247,1,12,12,12,1,0,0,0,1,72,72,72,1,161,161,161,1,158, + 158,158,1,182,182,182,1,144,144,144,1,203,203,203,1,186,186,186,1,49, + 49,49,1,0,0,0,5,240,240,240,2,0,0,0,6,194,194,194,1,50, + 50,50,1,0,0,0,1,115,115,115,1,129,129,129,1,43,43,43,1,64, + 64,64,2,165,165,165,1,136,136,136,1,22,22,22,1,0,0,0,5,240, + 240,240,2,0,0,0,6,43,43,43,1,161,161,161,1,183,183,183,1,192, + 192,192,1,15,15,15,1,0,0,0,3,135,135,135,1,96,96,96,1,0, + 0,0,6,240,240,240,2,0,0,0,8,11,11,11,1,0,0,0,13,240, + 240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0, + 0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240, + 240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,25,0, + 0) + ); + +const + objdata_tifipointerendpoint: record size: integer; data: array[0..938] of byte end = + (size: 939; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,112,111,105,110,116,101,114,101,110,100,112,111,105,110,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,44,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255,143, + 25,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,25,64,2,0, + 0,244,244,244,25,0,0,0,13,113,113,113,1,79,79,79,1,0,0,0, + 7,244,244,244,2,0,0,0,6,6,6,6,7,54,54,54,1,232,232,232, + 1,98,98,98,1,0,0,0,6,244,244,244,2,0,0,0,6,250,250,250, + 8,252,252,252,1,255,255,255,1,30,30,30,1,0,0,0,5,244,244,244, + 2,0,0,0,13,53,53,53,1,231,231,231,1,82,82,82,1,0,0,0, + 6,244,244,244,2,0,0,0,13,105,105,105,1,70,70,70,1,0,0,0, + 7,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,5,2,2,2, + 1,51,51,51,3,21,21,21,1,0,0,0,12,244,244,244,2,0,0,0, + 5,11,11,11,1,244,244,244,1,136,136,136,1,141,141,141,1,202,202,202, + 1,126,126,126,1,0,0,0,11,244,244,244,2,0,0,0,5,11,11,11, + 1,231,231,231,1,0,0,0,2,6,6,6,1,230,230,230,1,15,15,15, + 1,0,0,0,1,73,73,73,1,108,108,108,1,41,41,41,1,0,0,0, + 6,244,244,244,2,0,0,0,5,11,11,11,1,231,231,231,1,0,0,0, + 2,6,6,6,1,230,230,230,1,15,15,15,1,132,132,132,1,166,166,166, + 1,87,87,87,1,203,203,203,1,61,61,61,1,0,0,0,5,244,244,244, + 2,0,0,0,5,11,11,11,1,245,245,245,1,153,153,153,1,156,156,156, + 1,204,204,204,1,125,125,125,1,4,4,4,1,232,232,232,1,8,8,8, + 1,0,0,0,1,65,65,65,1,172,172,172,1,0,0,0,5,244,244,244, + 2,0,0,0,5,11,11,11,1,236,236,236,1,51,51,51,1,45,45,45, + 1,13,13,13,1,0,0,0,1,12,12,12,1,222,222,222,1,0,0,0, + 2,38,38,38,1,198,198,198,1,0,0,0,5,244,244,244,2,0,0,0, + 5,11,11,11,1,231,231,231,1,0,0,0,5,211,211,211,1,34,34,34, + 1,0,0,0,1,102,102,102,1,150,150,150,1,0,0,0,5,244,244,244, + 2,0,0,0,5,11,11,11,1,231,231,231,1,0,0,0,5,59,59,59, + 1,205,205,205,1,181,181,181,1,194,194,194,1,23,23,23,1,0,0,0, + 5,244,244,244,2,0,0,0,14,14,14,14,1,0,0,0,7,244,244,244, + 2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0, + 22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244, + 2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,25,0,0) + ); + +const + objdata_tifibooleanendpoint: record size: integer; data: array[0..1226] of byte end = + (size: 1227; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,98,111,111,108,101,97,110,101,110,100,112,111,105,110,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,76,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,156,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143, + 25,208,208,208,14,0,0,0,2,208,208,208,6,151,255,143,2,208,208,208, + 14,0,0,0,3,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0, + 12,208,208,208,4,151,255,143,2,208,208,208,6,0,0,0,11,208,208,208, + 5,151,255,143,2,208,208,208,14,0,0,0,2,208,208,208,6,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,3,0,0,0,7,208,208,208, + 1,0,0,0,8,208,208,208,3,151,255,143,2,208,208,208,3,0,0,0, + 7,208,208,208,1,0,0,0,8,208,208,208,3,151,255,143,2,208,208,208, + 6,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208,7,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,3,0,0,0,1,208,208,208, + 1,0,0,0,2,208,208,208,7,151,255,143,2,208,208,208,6,0,0,0, + 2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,5,208,208,208, + 4,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208,2,0,0,0, + 2,208,208,208,1,0,0,0,2,208,208,208,7,151,255,143,2,208,208,208, + 6,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0, + 2,208,208,208,7,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208, + 1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,7,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,2,208,208,208,7,151,255,143,2,208,208,208,22,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208, + 22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143, + 2,208,208,208,22,151,255,143,25,120,2,0,0,255,255,255,1,248,248,248, + 22,255,255,255,1,248,248,248,1,0,0,0,14,129,129,129,1,70,70,70, + 1,0,0,0,6,248,248,248,2,0,0,0,14,62,62,62,1,235,235,235, + 1,79,79,79,1,0,0,0,5,248,248,248,2,0,0,0,6,248,248,248, + 9,251,251,251,1,243,243,243,1,20,20,20,1,0,0,0,4,248,248,248, + 2,0,0,0,6,8,8,8,8,80,80,80,1,236,236,236,1,65,65,65, + 1,0,0,0,5,248,248,248,2,0,0,0,14,113,113,113,1,55,55,55, + 1,0,0,0,6,248,248,248,2,0,0,0,22,248,248,248,2,0,0,0, + 3,1,1,1,1,8,8,8,5,4,4,4,1,0,0,0,1,3,3,3, + 1,23,23,23,1,4,4,4,1,8,8,8,4,2,2,2,1,0,0,0, + 3,248,248,248,2,0,0,0,3,43,43,43,1,208,208,208,2,248,248,248, + 1,214,214,214,1,208,208,208,1,112,112,112,1,0,0,0,1,66,66,66, + 1,109,109,109,1,136,136,136,1,228,228,228,1,208,208,208,3,77,77,77, + 1,0,0,0,3,248,248,248,2,0,0,0,6,214,214,214,1,33,33,33, + 1,0,0,0,3,139,139,139,1,38,38,38,1,136,136,136,1,111,111,111, + 1,0,0,0,7,248,248,248,2,0,0,0,6,214,214,214,1,33,33,33, + 1,0,0,0,3,178,178,178,1,0,0,0,1,136,136,136,1,111,111,111, + 1,0,0,0,7,248,248,248,2,0,0,0,6,214,214,214,1,33,33,33, + 1,0,0,0,2,27,27,27,1,151,151,151,1,0,0,0,1,136,136,136, + 1,233,233,233,1,216,216,216,2,181,181,181,1,0,0,0,4,248,248,248, + 2,0,0,0,6,214,214,214,1,33,33,33,1,0,0,0,2,99,99,99, + 1,81,81,81,1,0,0,0,1,136,136,136,1,111,111,111,1,0,0,0, + 7,248,248,248,2,0,0,0,6,214,214,214,1,33,33,33,1,0,0,0, + 2,167,167,167,1,14,14,14,1,0,0,0,1,136,136,136,1,111,111,111, + 1,0,0,0,7,248,248,248,2,0,0,0,6,214,214,214,1,33,33,33, + 1,0,0,0,1,4,4,4,1,178,178,178,1,0,0,0,2,136,136,136, + 1,111,111,111,1,0,0,0,7,248,248,248,2,0,0,0,6,53,53,53, + 1,8,8,8,1,0,0,0,1,14,14,14,1,54,54,54,1,0,0,0, + 2,34,34,34,1,27,27,27,1,0,0,0,7,248,248,248,2,0,0,0, + 22,248,248,248,2,0,0,0,22,248,248,248,2,0,0,0,22,248,248,248, + 2,0,0,0,22,248,248,248,2,0,0,0,22,248,248,248,2,0,0,0, + 22,248,248,248,2,0,0,0,22,248,248,248,1,255,255,255,1,248,248,248, + 22,255,255,255,1,0,0) + ); + +const + objdata_tifirealendpoint: record size: integer; data: array[0..1443] of byte end = + (size: 1444; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,114,101,97,108,101,110,100,112,111,105,110,116,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,40,5, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208,208, + 208,14,0,0,0,2,208,208,208,6,151,255,143,2,208,208,208,14,0,0, + 0,3,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0,12,208,208, + 208,4,151,255,143,2,208,208,208,6,0,0,0,11,208,208,208,5,151,255, + 143,2,208,208,208,14,0,0,0,2,208,208,208,6,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,4,0,0,0,2,208,208,208,5,0,0, + 0,3,208,208,208,3,0,0,0,3,208,208,208,2,151,255,143,2,208,208, + 208,3,0,0,0,3,208,208,208,4,0,0,0,5,208,208,208,1,0,0, + 0,5,208,208,208,1,151,255,143,2,208,208,208,2,0,0,0,4,208,208, + 208,4,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,151,255,143,2,208,208, + 208,2,0,0,0,4,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,1,151,255,143,2,208,208, + 208,4,0,0,0,2,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,4,208,208,208,2,0,0,0,2,208,208,208,1,151,255,143,2,208,208, + 208,4,0,0,0,2,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,1,151,255,143,2,208,208, + 208,4,0,0,0,2,208,208,208,2,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,5,208,208, + 208,1,151,255,143,2,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,4,208,208, + 208,2,151,255,143,2,208,208,208,12,0,0,0,1,208,208,208,5,0,0, + 0,1,208,208,208,3,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,25,4,3,0,0,240,240,240,25,0,0,0,14,119,119, + 119,1,59,59,59,1,0,0,0,6,240,240,240,2,0,0,0,14,66,66, + 66,1,232,232,232,1,67,67,67,1,0,0,0,5,240,240,240,2,0,0, + 0,6,232,232,232,9,242,242,242,1,241,241,241,1,19,19,19,1,0,0, + 0,4,240,240,240,2,0,0,0,6,24,24,24,8,80,80,80,1,235,235, + 235,1,73,73,73,1,0,0,0,5,240,240,240,2,0,0,0,14,125,125, + 125,1,64,64,64,1,0,0,0,6,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,4,49,49,49,1,6,6,6,1,0,0,0,5,6,6, + 6,1,60,60,60,1,20,20,20,1,0,0,0,3,22,22,22,1,58,58, + 58,1,6,6,6,1,0,0,0,2,240,240,240,2,0,0,0,3,62,62, + 62,1,246,246,246,1,20,20,20,1,0,0,0,4,20,20,20,1,215,215, + 215,1,148,148,148,1,221,221,221,1,52,52,52,1,0,0,0,1,86,86, + 86,1,206,206,206,1,161,161,161,1,197,197,197,1,6,6,6,1,0,0, + 0,1,240,240,240,2,0,0,0,2,104,104,104,1,199,199,199,1,224,224, + 224,1,20,20,20,1,0,0,0,4,136,136,136,1,123,123,123,1,0,0, + 0,1,84,84,84,1,173,173,173,1,0,0,0,1,224,224,224,1,34,34, + 34,1,0,0,0,1,173,173,173,1,85,85,85,1,0,0,0,1,240,240, + 240,2,0,0,0,2,36,36,36,1,2,2,2,1,203,203,203,1,20,20, + 20,1,0,0,0,4,179,179,179,1,73,73,73,1,0,0,0,1,37,37, + 37,1,216,216,216,1,11,11,11,1,240,240,240,1,1,1,1,1,0,0, + 0,1,125,125,125,1,127,127,127,1,0,0,0,1,240,240,240,2,0,0, + 0,4,203,203,203,1,20,20,20,1,0,0,0,4,203,203,203,1,40,40, + 40,1,0,0,0,1,7,7,7,1,229,229,229,1,35,35,35,1,208,208, + 208,1,0,0,0,2,95,95,95,1,141,141,141,1,0,0,0,1,240,240, + 240,2,0,0,0,4,203,203,203,1,20,20,20,1,0,0,0,4,181,181, + 181,1,76,76,76,1,0,0,0,1,46,46,46,1,203,203,203,1,13,13, + 13,1,243,243,243,1,1,1,1,1,0,0,0,1,134,134,134,1,115,115, + 115,1,0,0,0,1,240,240,240,2,0,0,0,4,203,203,203,1,20,20, + 20,1,0,0,0,2,7,7,7,1,0,0,0,1,123,123,123,1,127,127, + 127,1,0,0,0,1,103,103,103,1,153,153,153,1,0,0,0,1,211,211, + 211,1,38,38,38,1,1,1,1,1,189,189,189,1,65,65,65,1,0,0, + 0,1,240,240,240,2,0,0,0,4,203,203,203,1,20,20,20,1,0,0, + 0,1,28,28,28,1,227,227,227,1,0,0,0,1,15,15,15,1,162,162, + 162,1,191,191,191,1,204,204,204,1,22,22,22,1,0,0,0,1,58,58, + 58,1,188,188,188,1,200,200,200,1,148,148,148,1,0,0,0,2,240,240, + 240,2,0,0,0,12,10,10,10,1,0,0,0,5,10,10,10,1,0,0, + 0,3,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,25,0,0) + ); + +const + objdata_tifidatetimeendpoint: record size: integer; data: array[0..979] of byte end = + (size: 980; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,105,102, + 105,100,97,116,101,116,105,109,101,101,110,100,112,111,105,110,116,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,84,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255, + 143,25,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,25,104,2, + 0,0,244,244,244,25,0,0,0,13,113,113,113,1,79,79,79,1,0,0, + 0,7,244,244,244,2,0,0,0,6,6,6,6,7,54,54,54,1,232,232, + 232,1,98,98,98,1,0,0,0,6,244,244,244,2,0,0,0,6,250,250, + 250,8,252,252,252,1,255,255,255,1,30,30,30,1,0,0,0,5,244,244, + 244,2,0,0,0,13,53,53,53,1,231,231,231,1,82,82,82,1,0,0, + 0,6,244,244,244,2,0,0,0,13,105,105,105,1,70,70,70,1,0,0, + 0,7,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,4,29,29, + 29,1,51,51,51,1,50,50,50,1,16,16,16,1,0,0,0,4,2,2, + 2,1,51,51,51,5,28,28,28,1,0,0,0,3,244,244,244,2,0,0, + 0,4,146,146,146,1,181,181,181,1,146,146,146,1,203,203,203,1,127,127, + 127,1,0,0,0,3,5,5,5,1,136,136,136,2,222,222,222,1,162,162, + 162,1,136,136,136,1,74,74,74,1,0,0,0,3,244,244,244,2,0,0, + 0,4,146,146,146,1,97,97,97,1,0,0,0,1,4,4,4,1,192,192, + 192,1,69,69,69,1,0,0,0,1,79,79,79,1,0,0,0,3,184,184, + 184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0,0,4,146,146, + 146,1,97,97,97,1,0,0,0,2,98,98,98,1,147,147,147,1,4,4, + 4,1,146,146,146,1,3,3,3,1,0,0,0,2,184,184,184,1,57,57, + 57,1,0,0,0,5,244,244,244,2,0,0,0,4,146,146,146,1,97,97, + 97,1,0,0,0,2,78,78,78,1,164,164,164,1,0,0,0,5,184,184, + 184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0,0,4,146,146, + 146,1,97,97,97,1,0,0,0,2,112,112,112,1,136,136,136,1,0,0, + 0,5,184,184,184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0, + 0,4,146,146,146,1,97,97,97,1,0,0,0,1,29,29,29,1,216,216, + 216,1,44,44,44,1,0,0,0,5,184,184,184,1,57,57,57,1,0,0, + 0,5,244,244,244,2,0,0,0,4,146,146,146,1,223,223,223,1,204,204, + 204,1,199,199,199,1,74,74,74,1,0,0,0,1,4,4,4,1,223,223, + 223,1,3,3,3,1,0,0,0,2,184,184,184,1,57,57,57,1,0,0, + 0,5,244,244,244,2,0,0,0,11,2,2,2,1,0,0,0,10,244,244, + 244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244, + 244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,25,0,0) + ); + +const + objdata_tifistringendpoint: record size: integer; data: array[0..1417] of byte end = + (size: 1418; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,105,102, + 105,115,116,114,105,110,103,101,110,100,112,111,105,110,116,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 12,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 176,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25, + 208,208,208,14,0,0,0,2,208,208,208,6,151,255,143,2,208,208,208,6, + 0,0,0,11,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0,12, + 208,208,208,4,151,255,143,2,208,208,208,14,0,0,0,3,208,208,208,5, + 151,255,143,2,208,208,208,14,0,0,0,2,208,208,208,6,151,255,143,2, + 208,208,208,22,151,255,143,2,208,208,208,3,0,0,0,2,208,208,208,3, + 0,0,0,5,208,208,208,3,0,0,0,4,208,208,208,2,151,255,143,2, + 208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,6,208,208,208,1, + 0,0,0,6,208,208,208,1,151,255,143,2,208,208,208,2,0,0,0,4, + 208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,1, + 0,0,0,2,208,208,208,2,0,0,0,3,151,255,143,2,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,8,208,208,208,6,151,255,143,2, + 208,208,208,1,0,0,0,6,208,208,208,1,0,0,0,8,208,208,208,6, + 151,255,143,2,208,208,208,1,0,0,0,6,208,208,208,1,0,0,0,2, + 208,208,208,2,0,0,0,5,208,208,208,3,0,0,0,2,151,255,143,2, + 208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,2, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2, + 208,208,208,1,151,255,143,2,0,0,0,3,208,208,208,3,0,0,0,8, + 208,208,208,1,0,0,0,6,208,208,208,1,151,255,143,2,208,208,208,17, + 0,0,0,2,208,208,208,3,151,255,143,2,208,208,208,22,151,255,143,2, + 208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22, + 151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2, + 208,208,208,22,151,255,143,25,36,3,0,0,240,240,240,25,0,0,0,14, + 125,125,125,1,64,64,64,1,0,0,0,6,240,240,240,2,0,0,0,6, + 8,8,8,8,68,68,68,1,234,234,234,1,73,73,73,1,0,0,0,5, + 240,240,240,2,0,0,0,6,248,248,248,9,251,251,251,1,241,241,241,1, + 19,19,19,1,0,0,0,4,240,240,240,2,0,0,0,14,66,66,66,1, + 232,232,232,1,67,67,67,1,0,0,0,5,240,240,240,2,0,0,0,14, + 119,119,119,1,59,59,59,1,0,0,0,6,240,240,240,2,0,0,0,22, + 240,240,240,2,0,0,0,3,38,38,38,1,43,43,43,1,0,0,0,3, + 52,52,52,1,72,72,72,1,71,71,71,1,50,50,50,1,8,8,8,1, + 0,0,0,3,4,4,4,1,56,56,56,1,79,79,79,1,12,12,12,1, + 0,0,0,2,240,240,240,2,0,0,0,3,193,193,193,1,207,207,207,1, + 1,1,1,1,0,0,0,2,187,187,187,1,176,176,176,1,153,153,153,1, + 173,173,173,1,211,211,211,1,17,17,17,1,0,0,0,1,24,24,24,1, + 207,207,207,1,164,164,164,1,136,136,136,1,214,214,214,1,78,78,78,1, + 0,0,0,1,240,240,240,2,0,0,0,2,43,43,43,1,183,183,183,1, + 167,167,167,1,69,69,69,1,0,0,0,2,187,187,187,1,60,60,60,1, + 0,0,0,2,161,161,161,1,81,81,81,1,0,0,0,1,191,191,191,1, + 83,83,83,1,0,0,0,2,36,36,36,1,188,188,188,1,3,3,3,1, + 240,240,240,2,0,0,0,2,140,140,140,1,96,96,96,1,74,74,74,1, + 173,173,173,1,0,0,0,2,187,187,187,1,103,103,103,1,56,56,56,1, + 80,80,80,1,198,198,198,1,27,27,27,1,9,9,9,1,232,232,232,1, + 0,0,0,6,240,240,240,2,0,0,0,1,5,5,5,1,222,222,222,1, + 12,12,12,1,3,3,3,1,223,223,223,1,26,26,26,1,0,0,0,1, + 187,187,187,1,188,188,188,1,168,168,168,1,181,181,181,1,199,199,199,1, + 37,37,37,1,35,35,35,1,218,218,218,1,0,0,0,6,240,240,240,2, + 0,0,0,1,80,80,80,1,232,232,232,1,208,208,208,2,226,226,226,1, + 126,126,126,1,0,0,0,1,187,187,187,1,60,60,60,1,0,0,0,2, + 96,96,96,1,161,161,161,1,2,2,2,1,240,240,240,1,7,7,7,1, + 0,0,0,3,108,108,108,1,13,13,13,1,240,240,240,2,0,0,0,1, + 178,178,178,1,73,73,73,1,0,0,0,2,41,41,41,1,226,226,226,1, + 3,3,3,1,187,187,187,1,60,60,60,1,0,0,0,2,122,122,122,1, + 159,159,159,1,0,0,0,1,153,153,153,1,140,140,140,1,0,0,0,2, + 82,82,82,1,191,191,191,1,0,0,0,1,240,240,240,2,24,24,24,1, + 226,226,226,1,3,3,3,1,0,0,0,3,198,198,198,1,79,79,79,1, + 187,187,187,1,225,225,225,1,216,216,216,1,217,217,217,1,190,190,190,1, + 30,30,30,1,0,0,0,1,7,7,7,1,168,168,168,1,206,206,206,1, + 202,202,202,1,182,182,182,1,39,39,39,1,0,0,0,1,240,240,240,2, + 0,0,0,17,2,2,2,1,12,12,12,1,0,0,0,3,240,240,240,2, + 0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22, + 240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2, + 0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifiactionendpoint: record size: integer; data: array[0..1937] of byte end = + (size: 1938; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,105,102, + 105,97,99,116,105,111,110,101,110,100,112,111,105,110,116,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 20,7,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 52,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25, + 208,208,208,13,0,0,0,1,0,0,106,1,0,0,255,1,208,208,208,6, + 151,255,143,2,208,208,208,13,0,0,149,1,2,2,17,1,2,2,135,1, + 0,0,0,1,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0,5, + 0,0,1,1,0,0,10,1,3,3,12,1,6,6,10,1,0,0,0,1, + 0,0,39,1,0,0,0,1,208,208,208,4,151,255,143,2,208,208,208,6, + 0,0,0,4,0,0,185,1,13,13,233,1,108,108,238,1,114,114,193,1, + 3,3,19,1,0,0,71,1,0,0,0,2,208,208,208,4,151,255,143,2, + 208,208,208,9,0,0,255,1,41,41,255,1,159,159,255,1,86,86,243,1, + 3,3,95,1,0,0,22,1,0,0,0,3,208,208,208,4,151,255,143,2, + 208,208,208,7,0,0,255,1,3,3,255,1,86,86,254,1,149,149,254,1, + 32,32,233,1,0,0,145,1,0,0,0,4,208,208,208,5,151,255,143,2, + 208,208,208,6,0,0,255,1,17,17,255,1,135,135,254,1,85,85,247,1, + 6,6,210,1,0,0,37,1,0,0,0,3,208,208,208,7,151,255,143,2, + 208,208,208,5,0,0,255,1,47,47,255,1,140,140,254,1,29,29,238,1, + 0,0,132,1,0,0,0,4,208,208,208,8,151,255,143,2,208,208,208,3, + 0,0,255,1,4,4,255,1,90,90,254,1,85,85,251,1,5,5,210,1, + 0,0,23,1,0,0,0,3,208,208,208,10,151,255,143,2,208,208,208,3, + 0,0,255,1,53,53,255,1,64,64,251,1,3,3,228,1,0,0,43,1, + 0,0,0,3,208,208,208,11,151,255,143,2,208,208,208,4,0,0,197,1, + 0,0,217,1,0,0,237,1,0,0,247,2,0,0,0,1,208,208,208,12, + 151,255,143,2,208,208,208,5,0,0,0,1,0,0,158,1,0,0,226,1, + 0,0,245,1,0,0,250,1,0,0,241,1,208,208,208,11,151,255,143,2, + 208,208,208,6,0,0,0,2,0,0,189,1,0,0,235,1,0,0,247,1, + 0,0,250,1,0,0,205,1,208,208,208,9,151,255,143,2,208,208,208,8, + 0,0,0,1,0,0,72,1,0,0,208,1,0,0,241,1,0,0,249,1, + 0,0,245,1,208,208,208,8,151,255,143,2,208,208,208,8,0,0,255,1, + 0,0,0,2,0,0,136,1,0,0,223,1,0,0,248,1,0,0,245,1, + 208,208,208,7,151,255,143,2,208,208,208,8,24,24,255,1,0,0,128,1, + 208,208,208,1,0,0,249,1,0,0,253,1,0,0,217,1,0,0,5,1, + 0,0,0,1,208,208,208,6,151,255,143,2,208,208,208,7,21,21,255,1, + 95,95,255,1,33,33,147,1,0,0,251,1,0,0,255,1,0,0,233,1, + 0,0,0,3,208,208,208,6,151,255,143,2,208,208,208,7,80,80,255,1, + 161,161,255,1,28,28,218,1,0,0,246,1,0,0,0,4,208,208,208,7, + 151,255,143,2,208,208,208,6,60,60,255,1,158,158,255,1,149,149,255,1, + 81,81,253,1,20,20,249,1,0,0,250,2,0,0,0,1,208,208,208,8, + 151,255,143,2,208,208,208,5,28,28,255,1,133,133,255,1,151,151,255,1, + 80,80,251,1,21,21,230,1,0,0,203,1,0,0,169,1,0,0,69,1, + 0,0,0,2,208,208,208,7,151,255,143,2,208,208,208,5,76,76,255,1, + 117,117,250,1,36,36,161,1,0,0,36,1,0,0,0,5,208,208,208,8, + 151,255,143,2,208,208,208,5,0,0,0,8,208,208,208,9,151,255,143,8, + 150,254,142,1,150,253,142,1,150,254,142,1,151,255,143,14,168,3,0,0, + 240,240,240,25,0,0,0,13,102,102,102,1,110,110,110,1,10,10,10,1, + 0,0,0,6,240,240,240,2,0,0,0,13,151,151,151,1,250,250,250,1, + 157,157,157,1,1,1,1,1,0,0,0,5,240,240,240,2,0,0,0,6, + 240,240,240,5,241,241,241,1,250,250,250,1,252,252,252,1,255,255,255,2, + 48,48,48,1,1,1,1,1,0,0,0,4,240,240,240,2,0,0,0,6, + 16,16,16,4,58,58,58,1,188,188,188,1,233,233,233,1,244,244,244,1, + 250,250,250,1,183,183,183,1,41,41,41,1,3,3,3,1,0,0,0,4, + 240,240,240,2,0,0,0,9,93,93,93,1,193,193,193,1,250,250,250,1, + 213,213,213,1,215,215,215,1,142,142,142,1,52,52,52,1,12,12,12,1, + 1,1,1,1,0,0,0,4,240,240,240,2,0,0,0,7,7,7,7,1, + 147,147,147,1,205,205,205,1,236,236,236,1,200,200,200,1,125,125,125,1, + 67,67,67,1,29,29,29,1,4,4,4,1,1,1,1,1,0,0,0,5, + 240,240,240,2,0,0,0,6,31,31,31,1,178,178,178,1,224,224,224,1, + 205,205,205,1,173,173,173,1,83,83,83,1,49,49,49,1,11,11,11,1, + 2,2,2,1,0,0,0,7,240,240,240,2,0,0,0,5,72,72,72,1, + 190,190,190,1,224,224,224,1,192,192,192,1,114,114,114,1,64,64,64,1, + 26,26,26,1,4,4,4,1,1,1,1,1,0,0,0,8,240,240,240,2, + 0,0,0,3,2,2,2,1,127,127,127,1,200,200,200,1,198,198,198,1, + 157,157,157,1,76,76,76,1,44,44,44,1,10,10,10,1,2,2,2,1, + 0,0,0,10,240,240,240,2,0,0,0,3,59,59,59,1,193,193,193,1, + 216,216,216,1,195,195,195,1,71,71,71,1,22,22,22,1,3,3,3,1, + 1,1,1,1,0,0,0,11,240,240,240,2,0,0,0,4,21,21,21,1, + 161,161,161,1,216,216,216,1,200,200,200,1,85,85,85,1,1,1,1,1, + 0,0,0,12,240,240,240,2,0,0,0,5,4,4,4,1,64,64,64,1, + 186,186,186,1,214,214,214,1,169,169,169,1,33,33,33,1,0,0,0,11, + 240,240,240,2,0,0,0,6,2,2,2,1,8,8,8,1,103,103,103,1, + 202,202,202,1,205,205,205,1,118,118,118,1,5,5,5,1,0,0,0,9, + 240,240,240,2,0,0,0,8,3,3,3,1,18,18,18,1,140,140,140,1, + 209,209,209,1,187,187,187,1,60,60,60,1,0,0,0,8,240,240,240,2, + 0,0,0,8,16,16,16,1,1,1,1,1,3,3,3,1,41,41,41,1, + 173,173,173,1,217,217,217,1,104,104,104,1,0,0,0,7,240,240,240,2, + 0,0,0,8,157,157,157,1,4,4,4,1,0,0,0,1,38,38,38,1, + 195,195,195,1,122,122,122,1,52,52,52,1,6,6,6,1,0,0,0,6, + 240,240,240,2,0,0,0,7,62,62,62,1,251,251,251,1,70,70,70,1, + 88,88,88,1,166,166,166,1,31,31,31,1,22,22,22,1,13,13,13,1, + 1,1,1,1,0,0,0,6,240,240,240,2,0,0,0,7,190,190,190,1, + 255,255,255,1,185,185,185,1,92,92,92,1,6,6,6,1,12,12,12,1, + 2,2,2,1,1,1,1,1,0,0,0,7,240,240,240,2,0,0,0,6, + 94,94,94,1,255,255,255,2,249,249,249,1,203,203,203,1,147,147,147,1, + 91,91,91,1,1,1,1,1,0,0,0,8,240,240,240,2,0,0,0,5, + 9,9,9,1,214,214,214,1,255,255,255,1,246,246,246,1,210,210,210,1, + 169,169,169,1,116,116,116,1,48,48,48,1,14,14,14,1,1,1,1,1, + 0,0,0,7,240,240,240,2,0,0,0,5,74,74,74,1,135,135,135,1, + 122,122,122,1,85,85,85,1,73,73,73,1,56,56,56,1,36,36,36,1, + 16,16,16,1,2,2,2,1,0,0,0,8,240,240,240,2,0,0,0,5, + 1,1,1,1,16,16,16,1,36,36,36,1,19,19,19,1,4,4,4,1, + 2,2,2,2,1,1,1,1,0,0,0,9,240,240,240,25,0,0) + ); + +const + objdata_tifilinkcomp: record size: integer; data: array[0..2863] of byte end = + (size: 2864; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,105,102, + 105,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,4,2,1,13,22, + 13,1,159,255,151,1,162,255,155,1,103,159,99,1,2,4,2,1,3,4, + 2,1,45,65,43,1,177,255,171,1,180,255,174,1,66,92,64,1,3,4, + 3,2,92,123,90,1,195,255,190,1,197,255,193,1,33,42,32,1,3,4, + 3,2,166,202,164,1,212,255,209,1,204,242,201,1,0,0,0,1,107,181, + 101,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255, + 158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255, + 174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255, + 190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255, + 206,1,212,255,209,1,215,255,212,1,3,4,3,1,151,255,143,1,153,255, + 145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255,158,1,168,255, + 161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255,174,1,183,255, + 177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255, + 193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255,206,1,212,255, + 209,1,215,255,212,1,27,32,27,1,151,255,143,1,153,255,145,1,156,255, + 148,1,159,255,151,1,162,255,155,1,165,255,158,1,168,255,161,1,171,255, + 164,1,174,255,167,1,177,255,171,1,180,255,174,1,183,255,177,1,186,255, + 180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255,193,1,200,255, + 196,1,203,255,199,1,206,255,203,1,209,255,206,1,212,255,209,1,215,255, + 212,1,218,255,215,1,8,13,7,1,153,255,145,1,156,255,148,1,159,255, + 151,1,162,255,155,1,165,255,158,1,168,255,161,1,171,255,164,1,174,255, + 167,1,177,255,171,1,180,255,174,1,183,255,177,1,186,255,180,1,189,255, + 183,1,192,255,187,1,195,255,190,1,197,255,193,1,200,255,196,1,203,255, + 199,1,206,255,203,1,209,255,206,1,212,255,209,1,215,255,212,1,218,255, + 215,1,2,4,2,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255, + 155,1,165,255,158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255, + 171,1,180,255,174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255, + 187,1,195,255,190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255, + 203,1,209,255,206,1,212,255,209,1,215,255,212,1,120,141,119,1,8,13, + 7,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255, + 158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255, + 174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255, + 190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255, + 206,1,212,255,209,1,215,255,212,1,3,4,3,1,151,255,143,1,153,255, + 145,1,153,250,145,1,158,253,150,1,162,255,155,1,165,255,158,1,150,228, + 144,1,165,246,158,1,169,248,162,1,177,255,171,1,178,252,172,1,181,252, + 175,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255, + 193,1,200,255,196,1,200,251,196,1,204,253,201,1,209,255,206,1,212,255, + 209,1,215,255,212,1,3,4,3,1,151,255,143,1,153,255,145,1,54,88, + 51,1,109,175,104,1,162,255,155,1,60,92,57,1,38,58,37,1,129,193, + 124,1,7,10,7,1,177,255,171,1,96,136,93,1,108,151,105,1,186,255, + 180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255,193,1,200,255, + 196,1,101,127,99,1,129,160,127,1,209,255,206,1,212,255,209,1,215,255, + 212,1,67,79,66,1,107,181,101,1,153,255,145,1,54,88,51,1,109,175, + 104,1,159,250,152,1,18,28,17,1,156,237,150,1,170,253,163,1,7,10, + 7,1,177,255,171,1,96,136,93,1,108,151,105,1,185,254,179,1,186,251, + 180,1,192,255,187,1,180,235,175,1,197,255,193,1,200,255,196,1,101,127, + 99,1,129,160,127,1,209,255,206,1,209,251,206,1,211,250,208,1,218,255, + 215,1,2,4,2,1,153,255,145,1,54,88,51,1,109,175,104,1,90,142, + 86,1,6,9,6,1,57,86,54,1,165,246,158,1,7,10,7,1,177,255, + 171,1,96,136,93,1,108,151,105,1,149,204,144,1,45,61,44,1,78,103, + 76,1,47,62,46,1,63,82,62,1,200,255,196,1,101,127,99,1,129,160, + 127,1,180,220,178,1,41,49,40,1,175,208,173,1,218,255,215,1,2,4, + 2,1,153,255,145,1,54,88,51,1,109,175,104,1,162,255,155,1,17,27, + 17,1,166,252,159,1,170,253,163,1,7,10,7,1,177,255,171,1,96,136, + 93,1,108,151,105,1,149,204,144,1,10,14,10,1,188,250,183,1,195,255, + 190,1,25,33,25,1,186,237,182,1,101,127,99,1,103,127,101,1,43,53, + 43,1,176,212,174,1,215,255,212,1,67,79,66,1,32,54,30,1,153,255, + 145,1,54,88,51,1,109,175,104,1,162,255,155,1,17,27,17,1,166,252, + 159,1,170,253,163,1,7,10,7,1,177,255,171,1,96,136,93,1,108,151, + 105,1,149,204,144,1,51,69,50,1,192,255,187,1,195,255,190,1,40,52, + 39,1,178,227,174,1,101,127,99,1,23,28,22,1,30,36,29,1,194,233, + 191,1,215,255,212,1,3,4,3,1,151,255,143,1,153,255,145,1,54,88, + 51,1,109,175,104,1,162,255,155,1,17,27,17,1,166,252,159,1,170,253, + 163,1,7,10,7,1,177,255,171,1,96,136,93,1,108,151,105,1,149,204, + 144,1,56,75,54,1,192,255,187,1,195,255,190,1,40,52,39,1,178,227, + 174,1,101,127,99,1,127,157,125,1,127,155,125,1,67,81,66,1,215,255, + 212,1,3,4,3,1,151,255,143,1,153,255,145,1,54,88,51,1,109,175, + 104,1,162,255,155,1,17,27,17,1,166,252,159,1,170,253,163,1,7,10, + 7,1,177,255,171,1,96,136,93,1,108,151,105,1,149,204,144,1,56,75, + 54,1,192,255,187,1,195,255,190,1,40,52,39,1,178,227,174,1,101,127, + 99,1,129,160,127,1,209,255,206,1,56,67,55,1,137,163,136,1,120,141, + 119,1,64,107,60,1,153,255,145,1,131,214,124,1,147,235,139,1,162,255, + 155,1,128,198,123,1,168,255,161,1,171,255,164,1,132,194,127,1,177,255, + 171,1,160,226,154,1,164,229,159,1,177,243,172,1,156,210,151,1,192,255, + 187,1,195,255,190,1,158,205,155,1,195,248,191,1,178,223,174,1,187,232, + 185,1,209,255,206,1,195,234,192,1,173,205,170,1,218,255,215,1,2,4, + 2,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255, + 158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255, + 174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255, + 190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255, + 206,1,212,255,209,1,215,255,212,1,218,255,215,1,2,4,2,1,153,255, + 145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255,158,1,168,255, + 161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255,174,1,183,255, + 177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255, + 193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255,206,1,212,255, + 209,1,215,255,212,1,27,32,27,1,64,107,60,1,153,255,145,1,156,255, + 148,1,159,255,151,1,162,255,155,1,165,255,158,1,168,255,161,1,171,255, + 164,1,174,255,167,1,177,255,171,1,180,255,174,1,183,255,177,1,186,255, + 180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255,193,1,200,255, + 196,1,203,255,199,1,206,255,203,1,209,255,206,1,212,255,209,1,215,255, + 212,1,3,4,3,1,151,255,143,1,153,255,145,1,156,255,148,1,159,255, + 151,1,162,255,155,1,165,255,158,1,168,255,161,1,171,255,164,1,174,255, + 167,1,177,255,171,1,180,255,174,1,183,255,177,1,186,255,180,1,189,255, + 183,1,192,255,187,1,195,255,190,1,197,255,193,1,200,255,196,1,203,255, + 199,1,206,255,203,1,209,255,206,1,212,255,209,1,215,255,212,1,3,4, + 3,1,151,255,143,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255, + 155,1,165,255,158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255, + 171,1,180,255,174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255, + 187,1,195,255,190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255, + 203,1,209,255,206,1,212,255,209,1,215,255,212,1,195,228,192,1,32,54, + 30,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255, + 158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255, + 174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255, + 190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255, + 206,1,212,255,209,1,215,255,212,1,218,255,215,1,2,4,2,1,153,255, + 145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255,158,1,168,255, + 161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255,174,1,183,255, + 177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255, + 193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255,206,1,212,255, + 209,1,215,255,212,1,195,228,192,1,0,0,0,1,121,202,115,1,156,255, + 148,1,159,255,151,1,2,4,2,2,14,22,14,1,171,255,164,1,174,255, + 167,1,110,159,107,1,3,4,3,2,48,65,46,1,189,255,183,1,192,255, + 187,1,70,92,68,1,3,4,3,2,98,123,96,1,206,255,203,1,209,255, + 206,1,35,42,35,1,3,4,3,1,0,0,0,1,148,1,0,0,255,255, + 255,1,252,252,252,1,237,237,237,1,136,136,136,2,165,165,165,1,252,252, + 252,2,208,208,208,1,136,136,136,2,194,194,194,1,252,252,252,2,179,179, + 179,1,136,136,136,2,223,223,223,1,252,252,252,2,150,150,150,1,136,136, + 136,1,139,139,139,1,255,255,255,1,157,157,157,1,255,255,255,22,252,252, + 252,1,136,136,136,1,255,255,255,22,230,230,230,1,136,136,136,1,255,255, + 255,22,136,136,136,1,244,244,244,1,255,255,255,22,136,136,136,1,252,252, + 252,1,255,255,255,22,172,172,172,1,244,244,244,1,255,255,255,22,252,252, + 252,1,136,136,136,1,255,255,255,22,252,252,252,1,136,136,136,1,255,255, + 255,22,201,201,201,1,157,157,157,1,255,255,255,22,136,136,136,1,252,252, + 252,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255,22,201,201, + 201,1,215,215,215,1,255,255,255,22,252,252,252,1,136,136,136,1,255,255, + 255,22,252,252,252,1,136,136,136,1,255,255,255,22,172,172,172,1,186,186, + 186,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255,22,136,136, + 136,1,252,252,252,1,255,255,255,22,230,230,230,1,186,186,186,1,255,255, + 255,22,252,252,252,1,136,136,136,1,255,255,255,22,252,252,252,1,136,136, + 136,1,255,255,255,22,143,143,143,1,215,215,215,1,255,255,255,22,136,136, + 136,1,252,252,252,1,255,255,255,22,143,143,143,1,255,255,255,1,150,150, + 150,1,136,136,136,2,252,252,252,2,237,237,237,1,136,136,136,2,165,165, + 165,1,252,252,252,2,208,208,208,1,136,136,136,2,194,194,194,1,252,252, + 252,2,179,179,179,1,136,136,136,2,223,223,223,1,252,252,252,1,255,255, + 255,1,0,0) + ); + +const + objdata_tifiintegerlinkcomp: record size: integer; data: array[0..1370] of byte end = + (size: 1371; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,105,110,116,101,103,101,114,108,105,110,107,99,111,109,112,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,220,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,188,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143, + 25,208,208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208, + 6,151,255,143,2,208,208,208,5,0,0,0,12,208,208,208,5,151,255,143, + 2,208,208,208,4,0,0,0,14,208,208,208,4,151,255,143,2,208,208,208, + 5,0,0,0,3,208,208,208,6,0,0,0,3,208,208,208,5,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208, + 6,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,5,0,0,0, + 2,208,208,208,3,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208, + 4,151,255,143,2,208,208,208,4,0,0,0,3,208,208,208,2,0,0,0, + 10,208,208,208,3,151,255,143,2,208,208,208,3,0,0,0,4,208,208,208, + 1,0,0,0,3,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0, + 2,208,208,208,3,151,255,143,2,208,208,208,3,0,0,0,4,208,208,208, + 5,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,3,151,255,143, + 2,208,208,208,5,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208, + 3,0,0,0,3,208,208,208,3,151,255,143,2,208,208,208,5,0,0,0, + 2,208,208,208,2,0,0,0,4,208,208,208,4,0,0,0,3,208,208,208, + 2,151,255,143,2,208,208,208,5,0,0,0,2,208,208,208,2,0,0,0, + 2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,3,208,208,208, + 2,151,255,143,2,208,208,208,5,0,0,0,2,208,208,208,1,0,0,0, + 11,208,208,208,3,151,255,143,2,208,208,208,16,0,0,0,1,208,208,208, + 5,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208, + 22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143, + 25,232,2,0,0,240,240,240,25,0,0,0,6,59,59,59,1,130,130,130, + 1,0,0,0,6,125,125,125,1,64,64,64,1,0,0,0,6,240,240,240, + 2,0,0,0,5,67,67,67,1,236,236,236,1,76,76,76,1,8,8,8, + 6,68,68,68,1,234,234,234,1,73,73,73,1,0,0,0,5,240,240,240, + 2,0,0,0,4,15,15,15,1,237,237,237,1,251,251,251,1,248,248,248, + 8,251,251,251,1,241,241,241,1,19,19,19,1,0,0,0,4,240,240,240, + 2,0,0,0,5,61,61,61,1,233,233,233,1,74,74,74,1,0,0,0, + 6,66,66,66,1,232,232,232,1,67,67,67,1,0,0,0,5,240,240,240, + 2,0,0,0,6,53,53,53,1,124,124,124,1,0,0,0,6,119,119,119, + 1,59,59,59,1,0,0,0,6,240,240,240,2,0,0,0,22,240,240,240, + 2,0,0,0,5,16,16,16,1,38,38,38,1,0,0,0,3,22,22,22, + 1,49,49,49,1,0,0,0,3,1,1,1,1,54,54,54,1,29,29,29, + 1,0,0,0,4,240,240,240,2,0,0,0,4,13,13,13,1,189,189,189, + 1,124,124,124,1,0,0,0,2,128,128,128,1,175,175,175,1,146,146,146, + 1,200,200,200,1,7,7,7,1,5,5,5,1,198,198,198,1,139,139,139, + 1,194,194,194,1,94,94,94,1,0,0,0,3,240,240,240,2,0,0,0, + 3,27,27,27,1,214,214,214,1,182,182,182,1,124,124,124,1,0,0,0, + 1,8,8,8,1,192,192,192,1,2,2,2,1,0,0,0,1,146,146,146, + 1,87,87,87,1,50,50,50,1,108,108,108,1,0,0,0,1,46,46,46, + 1,200,200,200,1,0,0,0,3,240,240,240,2,0,0,0,3,16,16,16, + 1,21,21,21,1,99,99,99,1,124,124,124,1,0,0,0,5,196,196,196, + 1,67,67,67,1,0,0,0,2,50,50,50,1,170,170,170,1,115,115,115, + 1,0,0,0,3,240,240,240,2,0,0,0,5,99,99,99,1,124,124,124, + 1,0,0,0,3,2,2,2,1,156,156,156,1,160,160,160,1,0,0,0, + 3,99,99,99,1,187,187,187,1,131,131,131,1,0,0,0,3,240,240,240, + 2,0,0,0,5,99,99,99,1,124,124,124,1,0,0,0,2,5,5,5, + 1,168,168,168,1,150,150,150,1,2,2,2,1,0,0,0,4,2,2,2, + 1,224,224,224,1,24,24,24,1,0,0,0,2,240,240,240,2,0,0,0, + 5,99,99,99,1,124,124,124,1,0,0,0,2,168,168,168,1,127,127,127, + 1,0,0,0,3,80,80,80,1,150,150,150,1,0,0,0,1,11,11,11, + 1,216,216,216,1,5,5,5,1,0,0,0,2,240,240,240,2,0,0,0, + 5,99,99,99,1,124,124,124,1,0,0,0,1,55,55,55,1,255,255,255, + 1,216,216,216,3,105,105,105,1,2,2,2,1,163,163,163,1,180,180,180, + 1,189,189,189,1,86,86,86,1,0,0,0,3,240,240,240,2,0,0,0, + 16,10,10,10,1,0,0,0,5,240,240,240,2,0,0,0,22,240,240,240, + 2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0, + 22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240, + 2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifiint64linkcomp: record size: integer; data: array[0..1228] of byte end = + (size: 1229; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,105,102, + 105,105,110,116,54,52,108,105,110,107,99,111,109,112,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,80, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,124, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208, + 208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,6,151, + 255,143,2,208,208,208,5,0,0,0,12,208,208,208,5,151,255,143,2,208, + 208,208,4,0,0,0,14,208,208,208,4,151,255,143,2,208,208,208,5,0, + 0,0,3,208,208,208,6,0,0,0,3,208,208,208,5,151,255,143,2,208, + 208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,6,151, + 255,143,2,208,208,208,22,151,255,143,2,208,208,208,7,0,0,0,3,208, + 208,208,4,0,0,0,2,208,208,208,6,151,255,143,2,208,208,208,6,0, + 0,0,5,208,208,208,2,0,0,0,3,208,208,208,6,151,255,143,2,208, + 208,208,6,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,2,0, + 0,0,3,208,208,208,6,151,255,143,2,208,208,208,5,0,0,0,6,208, + 208,208,1,0,0,0,4,208,208,208,6,151,255,143,2,208,208,208,5,0, + 0,0,11,208,208,208,6,151,255,143,2,208,208,208,5,0,0,0,3,208, + 208,208,1,0,0,0,8,208,208,208,5,151,255,143,2,208,208,208,6,0, + 0,0,2,208,208,208,1,0,0,0,8,208,208,208,5,151,255,143,2,208, + 208,208,6,0,0,0,5,208,208,208,3,0,0,0,2,208,208,208,6,151, + 255,143,2,208,208,208,8,0,0,0,1,208,208,208,13,151,255,143,2,208, + 208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151, + 255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208, + 208,208,22,151,255,143,2,208,208,208,22,151,255,143,25,156,2,0,0,240, + 240,240,25,0,0,0,6,59,59,59,1,130,130,130,1,0,0,0,6,125, + 125,125,1,64,64,64,1,0,0,0,6,240,240,240,2,0,0,0,5,67, + 67,67,1,236,236,236,1,76,76,76,1,8,8,8,6,68,68,68,1,234, + 234,234,1,73,73,73,1,0,0,0,5,240,240,240,2,0,0,0,4,15, + 15,15,1,237,237,237,1,251,251,251,1,248,248,248,8,251,251,251,1,241, + 241,241,1,19,19,19,1,0,0,0,4,240,240,240,2,0,0,0,5,61, + 61,61,1,233,233,233,1,74,74,74,1,0,0,0,6,66,66,66,1,232, + 232,232,1,67,67,67,1,0,0,0,5,240,240,240,2,0,0,0,6,53, + 53,53,1,124,124,124,1,0,0,0,6,119,119,119,1,59,59,59,1,0, + 0,0,6,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,7,1, + 1,1,1,53,53,53,1,7,7,7,1,0,0,0,4,33,33,33,1,27, + 27,27,1,0,0,0,6,240,240,240,2,0,0,0,6,56,56,56,1,175, + 175,175,1,135,135,135,1,212,212,212,1,30,30,30,1,0,0,0,2,13, + 13,13,1,222,222,222,1,96,96,96,1,0,0,0,6,240,240,240,2,0, + 0,0,6,194,194,194,1,42,42,42,1,0,0,0,1,60,60,60,1,63, + 63,63,1,0,0,0,2,157,157,157,1,195,195,195,1,96,96,96,1,0, + 0,0,6,240,240,240,2,0,0,0,5,1,1,1,1,230,230,230,1,84, + 84,84,1,163,163,163,1,81,81,81,1,2,2,2,1,0,0,0,1,83, + 83,83,1,137,137,137,1,135,135,135,1,96,96,96,1,0,0,0,6,240, + 240,240,2,0,0,0,5,16,16,16,1,249,249,249,1,141,141,141,1,45, + 45,45,1,183,183,183,1,77,77,77,1,26,26,26,1,189,189,189,1,6, + 6,6,1,135,135,135,1,96,96,96,1,0,0,0,6,240,240,240,2,0, + 0,0,5,2,2,2,1,247,247,247,1,12,12,12,1,0,0,0,1,72, + 72,72,1,161,161,161,1,158,158,158,1,182,182,182,1,144,144,144,1,203, + 203,203,1,186,186,186,1,49,49,49,1,0,0,0,5,240,240,240,2,0, + 0,0,6,194,194,194,1,50,50,50,1,0,0,0,1,115,115,115,1,129, + 129,129,1,43,43,43,1,64,64,64,2,165,165,165,1,136,136,136,1,22, + 22,22,1,0,0,0,5,240,240,240,2,0,0,0,6,43,43,43,1,161, + 161,161,1,183,183,183,1,192,192,192,1,15,15,15,1,0,0,0,3,135, + 135,135,1,96,96,96,1,0,0,0,6,240,240,240,2,0,0,0,8,11, + 11,11,1,0,0,0,13,240,240,240,2,0,0,0,22,240,240,240,2,0, + 0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240, + 240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0, + 0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifipointerlinkcomp: record size: integer; data: array[0..1002] of byte end = + (size: 1003; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,112,111,105,110,116,101,114,108,105,110,107,99,111,109,112,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,108,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255,143, + 25,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,25,128,2,0, + 0,244,244,244,25,0,0,0,6,47,47,47,1,119,119,119,1,0,0,0, + 6,126,126,126,1,65,65,65,1,0,0,0,6,244,244,244,2,0,0,0, + 5,51,51,51,1,230,230,230,1,84,84,84,1,0,0,0,6,60,60,60, + 1,234,234,234,1,79,79,79,1,0,0,0,5,244,244,244,2,0,0,0, + 4,14,14,14,1,235,235,235,1,249,249,249,1,244,244,244,8,249,249,249, + 1,240,240,240,1,19,19,19,1,0,0,0,4,244,244,244,2,0,0,0, + 5,65,65,65,1,233,233,233,1,77,77,77,1,12,12,12,6,74,74,74, + 1,233,233,233,1,68,68,68,1,0,0,0,5,244,244,244,2,0,0,0, + 6,63,63,63,1,138,138,138,1,0,0,0,6,116,116,116,1,57,57,57, + 1,0,0,0,6,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0, + 5,2,2,2,1,51,51,51,3,21,21,21,1,0,0,0,12,244,244,244, + 2,0,0,0,5,11,11,11,1,244,244,244,1,136,136,136,1,141,141,141, + 1,202,202,202,1,126,126,126,1,0,0,0,11,244,244,244,2,0,0,0, + 5,11,11,11,1,231,231,231,1,0,0,0,2,6,6,6,1,230,230,230, + 1,15,15,15,1,0,0,0,1,73,73,73,1,108,108,108,1,41,41,41, + 1,0,0,0,6,244,244,244,2,0,0,0,5,11,11,11,1,231,231,231, + 1,0,0,0,2,6,6,6,1,230,230,230,1,15,15,15,1,132,132,132, + 1,166,166,166,1,87,87,87,1,203,203,203,1,61,61,61,1,0,0,0, + 5,244,244,244,2,0,0,0,5,11,11,11,1,245,245,245,1,153,153,153, + 1,156,156,156,1,204,204,204,1,125,125,125,1,4,4,4,1,232,232,232, + 1,8,8,8,1,0,0,0,1,65,65,65,1,172,172,172,1,0,0,0, + 5,244,244,244,2,0,0,0,5,11,11,11,1,236,236,236,1,51,51,51, + 1,45,45,45,1,13,13,13,1,0,0,0,1,12,12,12,1,222,222,222, + 1,0,0,0,2,38,38,38,1,198,198,198,1,0,0,0,5,244,244,244, + 2,0,0,0,5,11,11,11,1,231,231,231,1,0,0,0,5,211,211,211, + 1,34,34,34,1,0,0,0,1,102,102,102,1,150,150,150,1,0,0,0, + 5,244,244,244,2,0,0,0,5,11,11,11,1,231,231,231,1,0,0,0, + 5,59,59,59,1,205,205,205,1,181,181,181,1,194,194,194,1,23,23,23, + 1,0,0,0,5,244,244,244,2,0,0,0,14,14,14,14,1,0,0,0, + 7,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244, + 2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0, + 22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244, + 25,0,0) + ); + +const + objdata_tifibooleanlinkcomp: record size: integer; data: array[0..1262] of byte end = + (size: 1263; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,98,111,111,108,101,97,110,108,105,110,107,99,111,109,112,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,112,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,164,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143, + 25,208,208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208, + 6,151,255,143,2,208,208,208,5,0,0,0,3,208,208,208,6,0,0,0, + 3,208,208,208,5,151,255,143,2,208,208,208,4,0,0,0,14,208,208,208, + 4,151,255,143,2,208,208,208,5,0,0,0,12,208,208,208,5,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208, + 6,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,3,0,0,0, + 7,208,208,208,1,0,0,0,8,208,208,208,3,151,255,143,2,208,208,208, + 3,0,0,0,7,208,208,208,1,0,0,0,8,208,208,208,3,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208, + 7,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208,2,0,0,0, + 2,208,208,208,1,0,0,0,5,208,208,208,4,151,255,143,2,208,208,208, + 6,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0, + 5,208,208,208,4,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208, + 2,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,7,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208, + 1,0,0,0,2,208,208,208,7,151,255,143,2,208,208,208,6,0,0,0, + 2,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208, + 7,151,255,143,2,208,208,208,9,0,0,0,2,208,208,208,11,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208, + 22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,25,148,2,0, + 0,240,240,240,25,0,0,0,6,48,48,48,1,118,118,118,1,0,0,0, + 6,125,125,125,1,64,64,64,1,0,0,0,6,240,240,240,2,0,0,0, + 5,56,56,56,1,233,233,233,1,82,82,82,1,0,0,0,6,62,62,62, + 1,233,233,233,1,73,73,73,1,0,0,0,5,240,240,240,2,0,0,0, + 4,15,15,15,1,237,237,237,1,247,247,247,1,240,240,240,8,246,246,246, + 1,241,241,241,1,19,19,19,1,0,0,0,4,240,240,240,2,0,0,0, + 5,73,73,73,1,234,234,234,1,74,74,74,1,16,16,16,6,78,78,78, + 1,233,233,233,1,67,67,67,1,0,0,0,5,240,240,240,2,0,0,0, + 6,65,65,65,1,136,136,136,1,0,0,0,6,119,119,119,1,59,59,59, + 1,0,0,0,6,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0, + 3,14,14,14,1,72,72,72,5,39,39,39,1,0,0,0,1,16,16,16, + 1,57,57,57,1,38,38,38,1,72,72,72,4,26,26,26,1,0,0,0, + 3,240,240,240,2,0,0,0,3,30,30,30,1,152,152,152,2,237,237,237, + 1,166,166,166,1,152,152,152,1,83,83,83,1,0,0,0,1,91,91,91, + 1,92,92,92,1,137,137,137,1,193,193,193,1,152,152,152,3,55,55,55, + 1,0,0,0,3,240,240,240,2,0,0,0,6,211,211,211,1,36,36,36, + 1,0,0,0,3,161,161,161,1,22,22,22,1,137,137,137,1,102,102,102, + 1,0,0,0,7,240,240,240,2,0,0,0,6,211,211,211,1,36,36,36, + 1,0,0,0,2,1,1,1,1,182,182,182,1,0,0,0,1,137,137,137, + 1,126,126,126,1,40,40,40,2,33,33,33,1,0,0,0,4,240,240,240, + 2,0,0,0,6,211,211,211,1,36,36,36,1,0,0,0,2,49,49,49, + 1,134,134,134,1,0,0,0,1,137,137,137,1,207,207,207,1,176,176,176, + 2,147,147,147,1,0,0,0,4,240,240,240,2,0,0,0,6,211,211,211, + 1,36,36,36,1,0,0,0,2,120,120,120,1,63,63,63,1,0,0,0, + 1,137,137,137,1,102,102,102,1,0,0,0,7,240,240,240,2,0,0,0, + 6,211,211,211,1,36,36,36,1,0,0,0,2,178,178,178,1,5,5,5, + 1,0,0,0,1,137,137,137,1,102,102,102,1,0,0,0,7,240,240,240, + 2,0,0,0,6,211,211,211,1,36,36,36,1,0,0,0,1,12,12,12, + 1,171,171,171,1,0,0,0,2,137,137,137,1,102,102,102,1,0,0,0, + 7,240,240,240,2,0,0,0,9,5,5,5,1,17,17,17,1,0,0,0, + 11,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240, + 2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0, + 22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240, + 25,0,0) + ); + +const + objdata_tifistringlinkcomp: record size: integer; data: array[0..1505] of byte end = + (size: 1506; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,105,102, + 105,115,116,114,105,110,103,108,105,110,107,99,111,109,112,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 100,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 200,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25, + 208,208,208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5, + 151,255,143,2,208,208,208,6,0,0,0,12,208,208,208,4,151,255,143,2, + 208,208,208,5,0,0,0,14,208,208,208,3,151,255,143,2,208,208,208,6, + 0,0,0,3,208,208,208,6,0,0,0,3,208,208,208,4,151,255,143,2, + 208,208,208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5, + 151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,3,0,0,0,2, + 208,208,208,3,0,0,0,5,208,208,208,3,0,0,0,4,208,208,208,2, + 151,255,143,2,208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,6, + 208,208,208,1,0,0,0,6,208,208,208,1,151,255,143,2,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,3,151,255,143,2, + 208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,8,208,208,208,6, + 151,255,143,2,208,208,208,1,0,0,0,6,208,208,208,1,0,0,0,8, + 208,208,208,6,151,255,143,2,208,208,208,1,0,0,0,6,208,208,208,1, + 0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,3,0,0,0,2, + 151,255,143,2,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,5, + 208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,2, + 0,0,0,2,208,208,208,1,151,255,143,2,0,0,0,3,208,208,208,3, + 0,0,0,8,208,208,208,1,0,0,0,6,208,208,208,1,151,255,143,2, + 208,208,208,17,0,0,0,2,208,208,208,3,151,255,143,2,208,208,208,22, + 151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2, + 208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22, + 151,255,143,2,208,208,208,22,151,255,143,25,100,3,0,0,240,240,240,25, + 0,0,0,7,59,59,59,1,130,130,130,1,0,0,0,6,125,125,125,1, + 64,64,64,1,0,0,0,5,240,240,240,2,0,0,0,6,67,67,67,1, + 235,235,235,1,74,74,74,1,8,8,8,6,66,66,66,1,233,233,233,1, + 73,73,73,1,0,0,0,4,240,240,240,2,0,0,0,5,15,15,15,1, + 237,237,237,1,251,251,251,1,248,248,248,8,251,251,251,1,241,241,241,1, + 19,19,19,1,0,0,0,3,240,240,240,2,0,0,0,6,61,61,61,1, + 235,235,235,1,80,80,80,1,0,0,0,6,72,72,72,1,235,235,235,1, + 67,67,67,1,0,0,0,4,240,240,240,2,0,0,0,7,53,53,53,1, + 122,122,122,1,0,0,0,6,117,117,117,1,59,59,59,1,0,0,0,5, + 240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,3,38,38,38,1, + 43,43,43,1,0,0,0,3,52,52,52,1,72,72,72,1,71,71,71,1, + 50,50,50,1,8,8,8,1,0,0,0,3,4,4,4,1,56,56,56,1, + 79,79,79,1,12,12,12,1,0,0,0,2,240,240,240,2,0,0,0,3, + 193,193,193,1,207,207,207,1,1,1,1,1,0,0,0,2,187,187,187,1, + 176,176,176,1,153,153,153,1,173,173,173,1,211,211,211,1,17,17,17,1, + 0,0,0,1,24,24,24,1,207,207,207,1,164,164,164,1,136,136,136,1, + 214,214,214,1,78,78,78,1,0,0,0,1,240,240,240,2,0,0,0,2, + 43,43,43,1,183,183,183,1,167,167,167,1,69,69,69,1,0,0,0,2, + 187,187,187,1,60,60,60,1,0,0,0,2,161,161,161,1,81,81,81,1, + 0,0,0,1,191,191,191,1,83,83,83,1,0,0,0,2,36,36,36,1, + 188,188,188,1,3,3,3,1,240,240,240,2,0,0,0,2,140,140,140,1, + 96,96,96,1,74,74,74,1,173,173,173,1,0,0,0,2,187,187,187,1, + 103,103,103,1,56,56,56,1,80,80,80,1,198,198,198,1,27,27,27,1, + 9,9,9,1,232,232,232,1,0,0,0,6,240,240,240,2,0,0,0,1, + 5,5,5,1,222,222,222,1,12,12,12,1,3,3,3,1,223,223,223,1, + 26,26,26,1,0,0,0,1,187,187,187,1,188,188,188,1,168,168,168,1, + 181,181,181,1,199,199,199,1,37,37,37,1,35,35,35,1,218,218,218,1, + 0,0,0,6,240,240,240,2,0,0,0,1,80,80,80,1,232,232,232,1, + 208,208,208,2,226,226,226,1,126,126,126,1,0,0,0,1,187,187,187,1, + 60,60,60,1,0,0,0,2,96,96,96,1,161,161,161,1,2,2,2,1, + 240,240,240,1,7,7,7,1,0,0,0,3,108,108,108,1,13,13,13,1, + 240,240,240,2,0,0,0,1,178,178,178,1,73,73,73,1,0,0,0,2, + 41,41,41,1,226,226,226,1,3,3,3,1,187,187,187,1,60,60,60,1, + 0,0,0,2,122,122,122,1,159,159,159,1,0,0,0,1,153,153,153,1, + 140,140,140,1,0,0,0,2,82,82,82,1,191,191,191,1,0,0,0,1, + 240,240,240,2,24,24,24,1,226,226,226,1,3,3,3,1,0,0,0,3, + 198,198,198,1,79,79,79,1,187,187,187,1,225,225,225,1,216,216,216,1, + 217,217,217,1,190,190,190,1,30,30,30,1,0,0,0,1,7,7,7,1, + 168,168,168,1,206,206,206,1,202,202,202,1,182,182,182,1,39,39,39,1, + 0,0,0,1,240,240,240,2,0,0,0,17,2,2,2,1,12,12,12,1, + 0,0,0,3,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22, + 240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2, + 0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22, + 240,240,240,25,0,0) + ); + +const + objdata_tifidropdownlistlinkcomp: record size: integer; data: array[0..1611] of byte end = + (size: 1612; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,24,116,105,102, + 105,100,114,111,112,100,111,119,110,108,105,115,116,108,105,110,107,99,111,109, + 112,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109, + 111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,200,5,0,0,0,0,0,0,6,0,0,0,24,0, + 0,0,24,0,0,0,36,2,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,151,255,143,25,208,208,208,6,0,0,0,2,208,208,208,6,0,0, + 0,2,208,208,208,6,151,255,143,2,208,208,208,5,0,0,0,3,208,208, + 208,6,0,0,0,3,208,208,208,5,151,255,143,2,208,208,208,4,0,0, + 0,14,208,208,208,4,151,255,143,2,208,208,208,5,0,0,0,3,208,208, + 208,6,0,0,0,3,208,208,208,5,151,255,143,2,208,208,208,6,0,0, + 0,2,208,208,208,6,0,0,0,2,208,208,208,6,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,1,0,0,0,5,208,208,208,5,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208, + 208,1,151,255,143,2,208,208,208,1,0,0,0,6,208,208,208,4,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208, + 208,1,151,255,143,2,208,208,208,1,0,0,0,2,208,208,208,2,0,0, + 0,3,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,2,208,208, + 208,3,0,0,0,2,208,208,208,1,151,255,143,2,208,208,208,1,0,0, + 0,2,208,208,208,3,0,0,0,7,208,208,208,1,0,0,0,2,208,208, + 208,3,0,0,0,2,208,208,208,1,151,255,143,2,208,208,208,1,0,0, + 0,2,208,208,208,3,0,0,0,4,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,151,255, + 143,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,4,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0, + 0,2,208,208,208,1,151,255,143,2,208,208,208,1,0,0,0,2,208,208, + 208,2,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208, + 208,1,151,255,143,2,208,208,208,1,0,0,0,6,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,7,208,208,208,1,151,255,143,2,208,208, + 208,10,0,0,0,1,208,208,208,11,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,25,108,3,0,0,240,240,240,25,0,0, + 0,6,59,59,59,1,130,130,130,1,0,0,0,6,125,125,125,1,64,64, + 64,1,0,0,0,6,240,240,240,2,0,0,0,5,67,67,67,1,235,235, + 235,1,70,70,70,1,0,0,0,6,62,62,62,1,233,233,233,1,73,73, + 73,1,0,0,0,5,240,240,240,2,0,0,0,4,15,15,15,1,237,237, + 237,1,255,255,255,10,241,241,241,1,19,19,19,1,0,0,0,4,240,240, + 240,2,0,0,0,5,61,61,61,1,233,233,233,1,74,74,74,1,0,0, + 0,6,66,66,66,1,232,232,232,1,67,67,67,1,0,0,0,5,240,240, + 240,2,0,0,0,6,53,53,53,1,124,124,124,1,0,0,0,6,119,119, + 119,1,59,59,59,1,0,0,0,6,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,1,48,48,48,1,72,72,72,1,71,71,71,1,55,55, + 55,1,12,12,12,1,0,0,0,5,6,6,6,1,56,56,56,1,0,0, + 0,1,51,51,51,1,18,18,18,1,0,0,0,3,8,8,8,1,54,54, + 54,1,0,0,0,1,240,240,240,2,0,0,0,1,173,173,173,1,182,182, + 182,1,152,152,152,1,169,169,169,1,222,222,222,1,72,72,72,1,0,0, + 0,4,21,21,21,1,202,202,202,1,0,0,0,1,181,181,181,1,66,66, + 66,1,0,0,0,3,22,22,22,1,145,145,145,1,0,0,0,1,240,240, + 240,2,0,0,0,1,173,173,173,1,74,74,74,1,0,0,0,2,46,46, + 46,1,228,228,228,1,8,8,8,1,0,0,0,1,24,24,24,1,80,80, + 80,1,44,44,44,1,202,202,202,1,0,0,0,1,181,181,181,1,66,66, + 66,1,0,0,0,3,8,8,8,1,54,54,54,1,0,0,0,1,240,240, + 240,2,0,0,0,1,173,173,173,1,74,74,74,1,0,0,0,3,209,209, + 209,1,48,48,48,1,46,46,46,1,212,212,212,1,119,119,119,1,195,195, + 195,1,202,202,202,1,0,0,0,1,181,181,181,1,66,66,66,1,0,0, + 0,3,29,29,29,1,194,194,194,1,0,0,0,1,240,240,240,2,0,0, + 0,1,173,173,173,1,74,74,74,1,0,0,0,3,175,175,175,1,73,73, + 73,1,153,153,153,1,93,93,93,1,0,0,0,1,66,66,66,1,202,202, + 202,1,0,0,0,1,181,181,181,1,66,66,66,1,0,0,0,3,29,29, + 29,1,194,194,194,1,0,0,0,1,240,240,240,2,0,0,0,1,173,173, + 173,1,74,74,74,1,0,0,0,3,210,210,210,1,41,41,41,1,184,184, + 184,1,53,53,53,1,0,0,0,1,23,23,23,1,202,202,202,1,0,0, + 0,1,181,181,181,1,66,66,66,1,0,0,0,3,29,29,29,1,194,194, + 194,1,0,0,0,1,240,240,240,2,0,0,0,1,173,173,173,1,74,74, + 74,1,0,0,0,2,95,95,95,1,202,202,202,1,0,0,0,1,138,138, + 138,1,121,121,121,1,0,0,0,1,82,82,82,1,202,202,202,1,0,0, + 0,1,181,181,181,1,66,66,66,1,0,0,0,3,29,29,29,1,194,194, + 194,1,0,0,0,1,240,240,240,2,0,0,0,1,173,173,173,1,227,227, + 227,1,216,216,216,1,223,223,223,1,180,180,180,1,29,29,29,1,0,0, + 0,1,15,15,15,1,195,195,195,1,187,187,187,1,148,148,148,1,202,202, + 202,1,0,0,0,1,181,181,181,1,226,226,226,1,216,216,216,2,177,177, + 177,1,29,29,29,1,194,194,194,1,0,0,0,1,240,240,240,2,0,0, + 0,10,10,10,10,1,0,0,0,11,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifienumlinkcomp: record size: integer; data: array[0..1399] of byte end = + (size: 1400; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,101,110,117,109,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,252,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,228,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208,208, + 208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,6,151,255, + 143,2,208,208,208,5,0,0,0,3,208,208,208,6,0,0,0,3,208,208, + 208,5,151,255,143,2,208,208,208,4,0,0,0,14,208,208,208,4,151,255, + 143,2,208,208,208,5,0,0,0,3,208,208,208,6,0,0,0,3,208,208, + 208,5,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208,6,0,0, + 0,2,208,208,208,6,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,2,0,0,0,7,208,208,208,13,151,255,143,2,208,208,208,2,0,0, + 0,7,208,208,208,13,151,255,143,2,208,208,208,2,0,0,0,2,208,208, + 208,5,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,2,151,255,143,2,208,208,208,2,0,0,0,6,208,208, + 208,1,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,2,151,255,143,2,208,208,208,2,0,0,0,6,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,2,151,255,143,2,208,208, + 208,2,0,0,0,2,208,208,208,5,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,2,151,255,143,2,208,208,208,2,0,0,0,2,208,208,208,5,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,2,151,255,143,2,208,208,208,2,0,0, + 0,9,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,5,208,208, + 208,2,151,255,143,2,208,208,208,16,0,0,0,2,208,208,208,4,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,25,224,2, + 0,0,240,240,240,25,0,0,0,6,59,59,59,1,130,130,130,1,0,0, + 0,6,125,125,125,1,64,64,64,1,0,0,0,6,240,240,240,2,0,0, + 0,5,67,67,67,1,235,235,235,1,70,70,70,1,0,0,0,6,62,62, + 62,1,233,233,233,1,73,73,73,1,0,0,0,5,240,240,240,2,0,0, + 0,4,15,15,15,1,237,237,237,1,255,255,255,10,241,241,241,1,19,19, + 19,1,0,0,0,4,240,240,240,2,0,0,0,5,61,61,61,1,233,233, + 233,1,74,74,74,1,0,0,0,6,66,66,66,1,232,232,232,1,67,67, + 67,1,0,0,0,5,240,240,240,2,0,0,0,6,53,53,53,1,124,124, + 124,1,0,0,0,6,119,119,119,1,59,59,59,1,0,0,0,6,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,2,3,3,3,1,72,72, + 72,5,14,14,14,1,0,0,0,13,240,240,240,2,0,0,0,2,12,12, + 12,1,247,247,247,1,152,152,152,4,30,30,30,1,0,0,0,13,240,240, + 240,2,0,0,0,2,12,12,12,1,235,235,235,1,0,0,0,5,30,30, + 30,1,28,28,28,2,76,76,76,1,6,6,6,1,0,0,0,1,54,54, + 54,1,8,8,8,1,0,0,0,1,27,27,27,1,35,35,35,1,0,0, + 0,2,240,240,240,2,0,0,0,2,12,12,12,1,239,239,239,1,48,48, + 48,3,44,44,44,1,0,0,0,1,106,106,106,1,197,197,197,1,127,127, + 127,1,164,164,164,2,0,0,0,1,194,194,194,1,29,29,29,1,0,0, + 0,1,98,98,98,1,125,125,125,1,0,0,0,2,240,240,240,2,0,0, + 0,2,12,12,12,1,249,249,249,1,168,168,168,3,154,154,154,1,0,0, + 0,1,106,106,106,1,172,172,172,1,0,0,0,1,11,11,11,1,218,218, + 218,1,0,0,0,1,194,194,194,1,29,29,29,1,0,0,0,1,98,98, + 98,1,125,125,125,1,0,0,0,2,240,240,240,2,0,0,0,2,12,12, + 12,1,235,235,235,1,0,0,0,5,106,106,106,1,125,125,125,1,0,0, + 0,1,2,2,2,1,221,221,221,1,0,0,0,1,194,194,194,1,30,30, + 30,1,0,0,0,1,102,102,102,1,125,125,125,1,0,0,0,2,240,240, + 240,2,0,0,0,2,12,12,12,1,235,235,235,1,0,0,0,5,106,106, + 106,1,125,125,125,1,0,0,0,1,2,2,2,1,221,221,221,1,0,0, + 0,1,184,184,184,1,56,56,56,1,0,0,0,1,150,150,150,1,125,125, + 125,1,0,0,0,2,240,240,240,2,0,0,0,2,12,12,12,1,252,252, + 252,1,216,216,216,4,77,77,77,1,106,106,106,1,125,125,125,1,0,0, + 0,1,2,2,2,1,221,221,221,1,0,0,0,1,88,88,88,1,221,221, + 221,1,151,151,151,1,147,147,147,1,125,125,125,1,0,0,0,2,240,240, + 240,2,0,0,0,16,8,8,8,1,4,4,4,1,0,0,0,4,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifireallinkcomp: record size: integer; data: array[0..1531] of byte end = + (size: 1532; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,114,101,97,108,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,128,5, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,4,2, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208,208, + 208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5,151,255, + 143,2,208,208,208,6,0,0,0,12,208,208,208,4,151,255,143,2,208,208, + 208,5,0,0,0,14,208,208,208,3,151,255,143,2,208,208,208,6,0,0, + 0,3,208,208,208,6,0,0,0,3,208,208,208,4,151,255,143,2,208,208, + 208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,4,0,0,0,2,208,208, + 208,5,0,0,0,3,208,208,208,3,0,0,0,3,208,208,208,2,151,255, + 143,2,208,208,208,3,0,0,0,3,208,208,208,4,0,0,0,5,208,208, + 208,1,0,0,0,5,208,208,208,1,151,255,143,2,208,208,208,2,0,0, + 0,4,208,208,208,4,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,151,255, + 143,2,208,208,208,2,0,0,0,4,208,208,208,4,0,0,0,2,208,208, + 208,1,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,151,255, + 143,2,208,208,208,4,0,0,0,2,208,208,208,4,0,0,0,2,208,208, + 208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,151,255, + 143,2,208,208,208,4,0,0,0,2,208,208,208,4,0,0,0,2,208,208, + 208,1,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,151,255, + 143,2,208,208,208,4,0,0,0,2,208,208,208,2,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,5,208,208,208,1,151,255,143,2,208,208,208,4,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0, + 0,4,208,208,208,2,151,255,143,2,208,208,208,12,0,0,0,1,208,208, + 208,5,0,0,0,1,208,208,208,3,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,25,68,3,0,0,240,240,240,25,0,0, + 0,7,59,59,59,1,130,130,130,1,0,0,0,6,125,125,125,1,64,64, + 64,1,0,0,0,5,240,240,240,2,0,0,0,6,67,67,67,1,235,235, + 235,1,74,74,74,1,8,8,8,6,66,66,66,1,233,233,233,1,73,73, + 73,1,0,0,0,4,240,240,240,2,0,0,0,5,15,15,15,1,237,237, + 237,1,251,251,251,1,248,248,248,8,251,251,251,1,241,241,241,1,19,19, + 19,1,0,0,0,3,240,240,240,2,0,0,0,6,61,61,61,1,235,235, + 235,1,80,80,80,1,0,0,0,6,72,72,72,1,235,235,235,1,67,67, + 67,1,0,0,0,4,240,240,240,2,0,0,0,7,53,53,53,1,122,122, + 122,1,0,0,0,6,117,117,117,1,59,59,59,1,0,0,0,5,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,4,49,49,49,1,6,6, + 6,1,0,0,0,5,6,6,6,1,60,60,60,1,20,20,20,1,0,0, + 0,3,22,22,22,1,58,58,58,1,6,6,6,1,0,0,0,2,240,240, + 240,2,0,0,0,3,62,62,62,1,246,246,246,1,20,20,20,1,0,0, + 0,4,20,20,20,1,215,215,215,1,148,148,148,1,221,221,221,1,52,52, + 52,1,0,0,0,1,86,86,86,1,206,206,206,1,161,161,161,1,197,197, + 197,1,6,6,6,1,0,0,0,1,240,240,240,2,0,0,0,2,104,104, + 104,1,199,199,199,1,224,224,224,1,20,20,20,1,0,0,0,4,136,136, + 136,1,123,123,123,1,0,0,0,1,84,84,84,1,173,173,173,1,0,0, + 0,1,224,224,224,1,34,34,34,1,0,0,0,1,173,173,173,1,85,85, + 85,1,0,0,0,1,240,240,240,2,0,0,0,2,36,36,36,1,2,2, + 2,1,203,203,203,1,20,20,20,1,0,0,0,4,179,179,179,1,73,73, + 73,1,0,0,0,1,37,37,37,1,216,216,216,1,11,11,11,1,240,240, + 240,1,1,1,1,1,0,0,0,1,125,125,125,1,127,127,127,1,0,0, + 0,1,240,240,240,2,0,0,0,4,203,203,203,1,20,20,20,1,0,0, + 0,4,203,203,203,1,40,40,40,1,0,0,0,1,7,7,7,1,229,229, + 229,1,35,35,35,1,208,208,208,1,0,0,0,2,95,95,95,1,141,141, + 141,1,0,0,0,1,240,240,240,2,0,0,0,4,203,203,203,1,20,20, + 20,1,0,0,0,4,181,181,181,1,76,76,76,1,0,0,0,1,46,46, + 46,1,203,203,203,1,13,13,13,1,243,243,243,1,1,1,1,1,0,0, + 0,1,134,134,134,1,115,115,115,1,0,0,0,1,240,240,240,2,0,0, + 0,4,203,203,203,1,20,20,20,1,0,0,0,2,7,7,7,1,0,0, + 0,1,123,123,123,1,127,127,127,1,0,0,0,1,103,103,103,1,153,153, + 153,1,0,0,0,1,211,211,211,1,38,38,38,1,1,1,1,1,189,189, + 189,1,65,65,65,1,0,0,0,1,240,240,240,2,0,0,0,4,203,203, + 203,1,20,20,20,1,0,0,0,1,28,28,28,1,227,227,227,1,0,0, + 0,1,15,15,15,1,162,162,162,1,191,191,191,1,204,204,204,1,22,22, + 22,1,0,0,0,1,58,58,58,1,188,188,188,1,200,200,200,1,148,148, + 148,1,0,0,0,2,240,240,240,2,0,0,0,12,10,10,10,1,0,0, + 0,5,10,10,10,1,0,0,0,3,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifidatetimelinkcomp: record size: integer; data: array[0..1043] of byte end = + (size: 1044; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,105,102, + 105,100,97,116,101,116,105,109,101,108,105,110,107,99,111,109,112,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,148,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255, + 143,25,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,25,168,2, + 0,0,244,244,244,25,0,0,0,6,47,47,47,1,119,119,119,1,0,0, + 0,6,126,126,126,1,65,65,65,1,0,0,0,6,244,244,244,2,0,0, + 0,5,51,51,51,1,230,230,230,1,84,84,84,1,0,0,0,6,60,60, + 60,1,234,234,234,1,79,79,79,1,0,0,0,5,244,244,244,2,0,0, + 0,4,14,14,14,1,235,235,235,1,249,249,249,1,244,244,244,8,249,249, + 249,1,240,240,240,1,19,19,19,1,0,0,0,4,244,244,244,2,0,0, + 0,5,65,65,65,1,233,233,233,1,77,77,77,1,12,12,12,6,74,74, + 74,1,233,233,233,1,68,68,68,1,0,0,0,5,244,244,244,2,0,0, + 0,6,63,63,63,1,138,138,138,1,0,0,0,6,116,116,116,1,57,57, + 57,1,0,0,0,6,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,4,29,29,29,1,51,51,51,1,50,50,50,1,16,16,16,1,0,0, + 0,4,2,2,2,1,51,51,51,5,28,28,28,1,0,0,0,3,244,244, + 244,2,0,0,0,4,146,146,146,1,181,181,181,1,146,146,146,1,203,203, + 203,1,127,127,127,1,0,0,0,3,5,5,5,1,136,136,136,2,222,222, + 222,1,162,162,162,1,136,136,136,1,74,74,74,1,0,0,0,3,244,244, + 244,2,0,0,0,4,146,146,146,1,97,97,97,1,0,0,0,1,4,4, + 4,1,192,192,192,1,69,69,69,1,0,0,0,1,79,79,79,1,0,0, + 0,3,184,184,184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0, + 0,4,146,146,146,1,97,97,97,1,0,0,0,2,98,98,98,1,147,147, + 147,1,4,4,4,1,146,146,146,1,3,3,3,1,0,0,0,2,184,184, + 184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0,0,4,146,146, + 146,1,97,97,97,1,0,0,0,2,78,78,78,1,164,164,164,1,0,0, + 0,5,184,184,184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0, + 0,4,146,146,146,1,97,97,97,1,0,0,0,2,112,112,112,1,136,136, + 136,1,0,0,0,5,184,184,184,1,57,57,57,1,0,0,0,5,244,244, + 244,2,0,0,0,4,146,146,146,1,97,97,97,1,0,0,0,1,29,29, + 29,1,216,216,216,1,44,44,44,1,0,0,0,5,184,184,184,1,57,57, + 57,1,0,0,0,5,244,244,244,2,0,0,0,4,146,146,146,1,223,223, + 223,1,204,204,204,1,199,199,199,1,74,74,74,1,0,0,0,1,4,4, + 4,1,223,223,223,1,3,3,3,1,0,0,0,2,184,184,184,1,57,57, + 57,1,0,0,0,5,244,244,244,2,0,0,0,11,2,2,2,1,0,0, + 0,10,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244, + 244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244, + 244,25,0,0) + ); + +const + objdata_tifiactionlinkcomp: record size: integer; data: array[0..1993] of byte end = + (size: 1994; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,105,102, + 105,97,99,116,105,111,110,108,105,110,107,99,111,109,112,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 76,7,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 48,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25, + 208,208,208,6,0,0,0,2,208,208,208,6,0,0,59,1,0,0,33,1, + 208,208,208,6,151,255,143,2,208,208,208,5,0,0,0,3,208,208,208,5, + 0,0,255,1,17,17,166,1,0,0,11,1,0,0,0,1,208,208,208,5, + 151,255,143,2,208,208,208,4,0,0,0,8,0,0,5,1,2,2,6,1, + 5,5,7,1,0,0,3,1,0,0,0,2,208,208,208,4,151,255,143,2, + 208,208,208,5,0,0,0,5,0,0,215,1,13,13,244,1,112,112,246,1, + 145,145,245,1,24,24,165,1,0,0,8,1,0,0,0,2,208,208,208,4, + 151,255,143,2,208,208,208,6,0,0,0,2,208,208,208,1,0,0,255,1, + 41,41,255,1,159,159,255,1,86,86,243,1,6,6,211,1,0,0,13,1, + 0,0,0,3,208,208,208,4,151,255,143,2,208,208,208,7,0,0,255,1, + 3,3,255,1,86,86,254,1,149,149,254,1,32,32,233,1,0,0,145,1, + 0,0,0,4,208,208,208,5,151,255,143,2,208,208,208,6,0,0,255,1, + 17,17,255,1,135,135,254,1,85,85,247,1,6,6,210,1,0,0,37,1, + 0,0,0,3,208,208,208,7,151,255,143,2,208,208,208,5,0,0,255,1, + 47,47,255,1,140,140,254,1,29,29,238,1,0,0,132,1,0,0,0,4, + 208,208,208,8,151,255,143,2,208,208,208,3,0,0,255,1,4,4,255,1, + 90,90,254,1,85,85,251,1,5,5,210,1,0,0,23,1,0,0,0,3, + 208,208,208,10,151,255,143,2,208,208,208,3,0,0,255,1,53,53,255,1, + 64,64,251,1,3,3,228,1,0,0,43,1,0,0,0,3,208,208,208,11, + 151,255,143,2,208,208,208,4,0,0,197,1,0,0,217,1,0,0,237,1, + 0,0,247,2,0,0,0,1,208,208,208,12,151,255,143,2,208,208,208,5, + 0,0,0,1,0,0,158,1,0,0,226,1,0,0,245,1,0,0,250,1, + 0,0,241,1,208,208,208,11,151,255,143,2,208,208,208,6,0,0,0,2, + 0,0,189,1,0,0,235,1,0,0,247,1,0,0,250,1,0,0,205,1, + 208,208,208,9,151,255,143,2,208,208,208,8,0,0,0,1,0,0,72,1, + 0,0,208,1,0,0,241,1,0,0,249,1,0,0,245,1,208,208,208,8, + 151,255,143,2,208,208,208,8,0,0,255,1,0,0,0,2,0,0,136,1, + 0,0,223,1,0,0,248,1,0,0,245,1,208,208,208,7,151,255,143,2, + 208,208,208,8,24,24,255,1,0,0,128,1,208,208,208,1,0,0,249,1, + 0,0,253,1,0,0,217,1,0,0,5,1,0,0,0,1,208,208,208,6, + 151,255,143,2,208,208,208,7,21,21,255,1,95,95,255,1,33,33,147,1, + 0,0,251,1,0,0,255,1,0,0,233,1,0,0,0,3,208,208,208,6, + 151,255,143,2,208,208,208,7,80,80,255,1,161,161,255,1,28,28,218,1, + 0,0,246,1,0,0,0,4,208,208,208,7,151,255,143,2,208,208,208,6, + 60,60,255,1,158,158,255,1,149,149,255,1,81,81,253,1,20,20,249,1, + 0,0,250,2,0,0,0,1,208,208,208,8,151,255,143,2,208,208,208,5, + 28,28,255,1,133,133,255,1,151,151,255,1,80,80,251,1,21,21,230,1, + 0,0,203,1,0,0,169,1,0,0,69,1,0,0,0,2,208,208,208,7, + 151,255,143,2,208,208,208,5,76,76,255,1,117,117,250,1,36,36,161,1, + 0,0,36,1,0,0,0,5,208,208,208,8,151,255,143,2,208,208,208,5, + 0,0,0,8,208,208,208,9,151,255,143,25,228,3,0,0,240,240,240,25, + 0,0,0,6,48,48,48,1,118,118,118,1,0,0,0,6,147,147,147,1, + 61,61,61,1,0,0,0,6,240,240,240,2,0,0,0,5,56,56,56,1, + 233,233,233,1,82,82,82,1,0,0,0,5,117,117,117,1,213,213,213,1, + 243,243,243,1,62,62,62,1,0,0,0,5,240,240,240,2,0,0,0,4, + 15,15,15,1,237,237,237,1,251,251,251,1,248,248,248,5,252,252,252,1, + 254,254,254,1,255,255,255,1,254,254,254,1,242,242,242,1,20,20,20,1, + 0,0,0,4,240,240,240,2,0,0,0,5,73,73,73,1,234,234,234,1, + 68,68,68,1,8,8,8,2,52,52,52,1,186,186,186,1,233,233,233,1, + 241,241,241,1,216,216,216,1,244,244,244,1,107,107,107,1,3,3,3,1, + 0,0,0,4,240,240,240,2,0,0,0,6,65,65,65,1,136,136,136,1, + 0,0,0,1,93,93,93,1,193,193,193,1,250,250,250,1,213,213,213,1, + 181,181,181,1,173,173,173,1,108,108,108,1,12,12,12,1,1,1,1,1, + 0,0,0,4,240,240,240,2,0,0,0,7,7,7,7,1,147,147,147,1, + 205,205,205,1,236,236,236,1,200,200,200,1,125,125,125,1,67,67,67,1, + 29,29,29,1,4,4,4,1,1,1,1,1,0,0,0,5,240,240,240,2, + 0,0,0,6,31,31,31,1,178,178,178,1,224,224,224,1,205,205,205,1, + 173,173,173,1,83,83,83,1,49,49,49,1,11,11,11,1,2,2,2,1, + 0,0,0,7,240,240,240,2,0,0,0,5,72,72,72,1,190,190,190,1, + 224,224,224,1,192,192,192,1,114,114,114,1,64,64,64,1,26,26,26,1, + 4,4,4,1,1,1,1,1,0,0,0,8,240,240,240,2,0,0,0,3, + 2,2,2,1,127,127,127,1,200,200,200,1,198,198,198,1,157,157,157,1, + 76,76,76,1,44,44,44,1,10,10,10,1,2,2,2,1,0,0,0,10, + 240,240,240,2,0,0,0,3,59,59,59,1,193,193,193,1,216,216,216,1, + 195,195,195,1,71,71,71,1,22,22,22,1,3,3,3,1,1,1,1,1, + 0,0,0,11,240,240,240,2,0,0,0,4,21,21,21,1,161,161,161,1, + 216,216,216,1,200,200,200,1,85,85,85,1,1,1,1,1,0,0,0,12, + 240,240,240,2,0,0,0,5,4,4,4,1,64,64,64,1,186,186,186,1, + 214,214,214,1,169,169,169,1,33,33,33,1,0,0,0,11,240,240,240,2, + 0,0,0,6,2,2,2,1,8,8,8,1,103,103,103,1,202,202,202,1, + 205,205,205,1,118,118,118,1,5,5,5,1,0,0,0,9,240,240,240,2, + 0,0,0,8,3,3,3,1,18,18,18,1,140,140,140,1,209,209,209,1, + 187,187,187,1,60,60,60,1,0,0,0,8,240,240,240,2,0,0,0,8, + 16,16,16,1,1,1,1,1,3,3,3,1,41,41,41,1,173,173,173,1, + 217,217,217,1,104,104,104,1,0,0,0,7,240,240,240,2,0,0,0,8, + 157,157,157,1,4,4,4,1,0,0,0,1,38,38,38,1,195,195,195,1, + 122,122,122,1,52,52,52,1,6,6,6,1,0,0,0,6,240,240,240,2, + 0,0,0,7,62,62,62,1,251,251,251,1,70,70,70,1,88,88,88,1, + 166,166,166,1,31,31,31,1,22,22,22,1,13,13,13,1,1,1,1,1, + 0,0,0,6,240,240,240,2,0,0,0,7,190,190,190,1,255,255,255,1, + 185,185,185,1,92,92,92,1,6,6,6,1,12,12,12,1,2,2,2,1, + 1,1,1,1,0,0,0,7,240,240,240,2,0,0,0,6,94,94,94,1, + 255,255,255,2,249,249,249,1,203,203,203,1,147,147,147,1,91,91,91,1, + 1,1,1,1,0,0,0,8,240,240,240,2,0,0,0,5,9,9,9,1, + 214,214,214,1,255,255,255,1,246,246,246,1,210,210,210,1,169,169,169,1, + 116,116,116,1,48,48,48,1,14,14,14,1,1,1,1,1,0,0,0,7, + 240,240,240,2,0,0,0,5,74,74,74,1,135,135,135,1,122,122,122,1, + 85,85,85,1,73,73,73,1,56,56,56,1,36,36,36,1,16,16,16,1, + 2,2,2,1,0,0,0,8,240,240,240,2,0,0,0,5,1,1,1,1, + 16,16,16,1,36,36,36,1,19,19,19,1,4,4,4,1,2,2,2,2, + 1,1,1,1,0,0,0,9,240,240,240,25,0,0) + ); + +const + objdata_tifigridlinkcomp: record size: integer; data: array[0..2615] of byte end = + (size: 2616; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,103,114,105,100,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,9, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,7, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,2,1,5,8, + 4,1,15,25,14,1,159,255,152,1,162,255,155,1,102,158,98,1,5,8, + 5,2,45,66,44,1,177,255,171,1,180,255,174,1,66,92,64,1,6,8, + 6,2,92,122,90,1,195,255,190,1,198,255,194,1,31,39,30,1,6,8, + 6,2,177,215,173,1,213,255,210,1,205,241,202,1,3,4,3,1,100,169, + 95,1,153,252,146,1,153,243,147,1,156,243,150,1,159,243,152,1,161,243, + 155,1,164,243,159,1,167,243,161,1,170,243,164,1,172,243,167,1,175,243, + 170,1,178,243,173,1,180,243,176,1,183,243,179,1,186,243,181,1,189,243, + 184,1,191,243,188,1,194,243,190,1,197,243,193,1,200,243,196,1,202,243, + 199,1,210,251,208,1,216,255,213,1,7,8,7,1,151,255,143,1,144,210, + 139,1,132,143,131,1,139,160,137,1,139,158,137,1,139,157,137,1,141,160, + 140,1,142,160,140,2,143,160,141,1,144,160,142,1,144,160,143,1,145,160, + 144,2,146,160,145,1,146,158,145,1,146,157,146,1,148,160,147,1,149,160, + 147,1,150,160,149,2,186,215,184,1,216,255,213,1,25,30,25,1,151,255, + 143,1,139,185,136,1,139,153,138,1,208,208,208,1,180,180,180,1,165,165, + 165,1,208,208,208,1,176,176,176,1,139,139,139,1,154,154,154,1,151,151, + 151,1,129,129,129,1,173,173,173,1,184,184,184,1,208,208,208,1,180,180, + 180,1,165,165,165,1,143,143,143,1,135,135,135,1,177,177,177,1,175,175, + 175,1,136,163,134,1,216,255,213,1,219,255,216,1,12,21,12,1,139,185, + 136,1,139,153,138,1,208,208,208,1,180,180,180,1,165,165,165,1,208,208, + 208,1,144,144,144,1,129,129,129,1,144,144,144,1,123,123,123,1,134,134, + 134,1,143,143,143,1,146,146,146,1,208,208,208,1,180,180,180,1,165,165, + 165,1,139,139,139,1,132,132,132,1,128,128,128,1,144,144,144,1,160,191, + 157,1,216,255,213,1,219,255,216,1,5,8,4,1,139,185,136,1,138,152, + 137,1,188,203,187,1,168,177,167,1,156,163,156,1,189,203,189,1,190,203, + 189,2,189,201,189,1,146,154,145,1,187,197,186,1,192,203,191,1,193,203, + 192,2,171,177,170,1,159,163,159,1,195,203,194,1,195,203,195,2,196,203, + 195,1,213,255,210,1,216,255,213,1,120,139,118,1,9,16,9,1,139,185, + 136,1,132,147,131,1,138,157,136,1,134,147,133,1,132,142,132,1,141,159, + 140,1,141,158,140,1,142,159,141,1,143,159,142,1,144,159,143,1,145,159, + 143,1,145,159,144,1,146,159,145,2,140,148,140,1,137,142,137,1,148,159, + 147,1,149,159,148,1,149,159,149,1,150,159,149,1,213,255,210,1,216,255, + 213,1,7,8,7,1,151,255,143,1,139,185,136,1,139,153,138,1,208,208, + 208,1,168,193,166,1,162,187,160,1,196,196,196,1,160,160,160,1,162,162, + 162,1,205,205,205,1,184,184,184,1,246,246,246,1,255,255,255,3,211,211, + 211,1,185,185,185,1,162,162,162,1,210,210,210,1,179,179,179,1,137,137, + 137,1,208,249,205,1,216,255,213,1,7,8,7,1,151,255,143,1,140,185, + 136,1,140,154,139,1,210,210,210,1,171,195,169,1,165,189,163,1,198,198, + 198,1,195,195,195,1,161,161,161,1,186,186,186,1,149,149,149,1,245,245, + 245,1,255,255,255,3,213,213,213,1,189,189,189,1,193,193,193,1,167,167, + 167,1,198,198,198,1,164,164,164,1,195,234,193,1,216,255,213,1,68,79, + 67,1,107,180,101,1,142,186,139,1,145,157,145,1,206,206,206,1,179,196, + 178,1,175,192,173,1,239,239,239,9,209,209,209,1,192,192,192,1,239,239, + 239,1,238,238,238,1,237,237,237,1,235,235,235,1,213,255,210,1,216,255, + 213,1,219,255,216,1,7,10,6,1,147,187,144,1,154,160,154,1,194,194, + 194,1,188,192,188,1,187,191,187,1,200,200,200,1,199,199,199,1,200,200, + 200,7,194,194,194,1,191,191,191,1,200,200,200,1,197,197,197,1,180,180, + 180,1,163,163,163,1,213,255,210,1,216,255,213,1,219,255,216,1,8,11, + 7,1,149,188,146,1,160,168,160,1,233,233,233,1,214,226,213,1,212,223, + 211,1,251,251,251,1,204,204,204,1,227,227,227,1,236,236,236,1,226,226, + 226,1,239,239,239,1,221,221,221,1,232,232,232,1,229,229,229,1,234,234, + 234,1,223,223,223,1,218,218,218,1,214,214,214,1,164,164,164,1,255,255, + 255,1,213,255,210,1,216,255,213,1,68,79,67,1,35,58,34,1,149,188, + 146,1,161,168,160,1,233,233,233,1,215,227,214,1,212,224,211,1,241,241, + 241,1,203,203,203,1,222,222,222,1,214,214,214,1,201,201,201,1,221,221, + 221,2,216,216,216,1,226,226,226,1,235,235,235,1,224,224,224,1,223,223, + 223,1,233,233,233,1,186,186,186,1,255,255,255,1,213,255,210,1,216,255, + 213,1,7,8,7,1,153,255,146,1,149,188,146,1,160,168,160,1,227,227, + 227,1,212,222,211,1,210,220,209,1,246,246,246,9,229,229,229,1,220,220, + 220,1,246,246,246,1,245,245,245,1,241,241,241,1,236,236,236,1,213,255, + 210,1,216,255,213,1,7,8,7,1,153,255,146,1,149,188,146,1,159,164, + 159,1,205,205,205,1,201,204,201,1,200,203,200,1,211,211,211,1,210,210, + 210,1,211,211,211,7,206,206,206,1,203,203,203,1,211,211,211,1,206,206, + 206,1,186,186,186,1,164,164,164,1,213,255,210,1,216,255,213,1,120,139, + 118,1,66,108,63,1,149,188,146,1,161,168,160,1,233,233,233,1,215,227, + 214,1,212,224,211,1,248,248,248,1,217,217,217,1,222,222,222,1,234,234, + 234,1,255,255,255,5,235,235,235,1,224,224,224,1,216,216,216,1,206,206, + 206,1,185,185,185,1,255,255,255,1,213,255,210,1,216,255,213,1,219,255, + 216,1,8,11,7,1,149,188,146,1,161,168,160,1,233,233,233,1,215,226, + 214,1,212,224,211,1,244,244,244,1,217,217,217,1,220,220,220,1,225,225, + 225,1,255,255,255,5,235,235,235,1,224,224,224,1,219,219,219,1,207,207, + 207,1,185,185,185,1,255,255,255,1,213,255,210,1,216,255,213,1,219,255, + 216,1,8,11,7,1,148,188,146,1,159,166,159,1,226,226,226,1,209,220, + 208,1,207,217,206,1,245,245,245,9,227,227,227,1,217,217,217,1,245,245, + 245,1,244,244,244,1,240,240,240,1,236,236,236,1,210,250,207,1,216,255, + 213,1,25,30,25,1,70,117,66,1,146,187,142,1,151,157,150,1,186,186, + 186,1,180,184,179,1,178,182,178,1,193,193,193,9,186,186,186,1,182,182, + 182,1,193,193,193,1,190,190,190,1,177,177,177,1,162,162,162,1,197,231, + 194,1,216,255,213,1,7,8,7,1,152,255,144,1,141,185,138,1,144,156, + 143,1,213,213,213,1,178,200,176,1,172,194,170,1,237,237,237,1,154,154, + 154,2,217,217,217,1,206,206,206,1,176,176,176,1,202,202,202,1,212,212, + 212,1,255,255,255,1,216,216,216,1,194,194,194,1,204,204,204,1,187,187, + 187,1,153,153,153,1,200,200,200,1,154,184,152,1,216,255,213,1,7,8, + 7,1,151,255,143,1,150,239,144,1,151,229,146,1,160,255,153,1,163,255, + 156,1,166,255,159,1,156,235,150,1,114,170,110,1,134,195,129,1,117,168, + 113,1,122,173,118,1,101,140,98,1,140,191,136,1,143,192,139,1,192,255, + 188,1,195,255,191,1,198,255,194,1,112,142,110,1,165,205,162,1,131,161, + 128,1,172,209,169,1,154,184,152,1,216,255,213,1,207,241,205,1,29,50, + 28,1,153,255,146,1,156,255,149,1,159,255,152,1,162,255,155,1,165,255, + 158,1,168,255,162,1,171,255,165,1,174,255,168,1,177,255,171,1,145,205, + 140,1,163,227,158,1,186,255,181,1,154,208,150,1,192,255,187,1,195,255, + 190,1,198,255,194,1,201,255,197,1,204,255,200,1,207,255,203,1,210,255, + 206,1,213,255,210,1,216,255,213,1,219,255,216,1,5,8,4,1,153,255, + 146,1,156,255,149,1,159,255,152,1,162,255,155,1,165,255,158,1,168,255, + 162,1,171,255,165,1,174,255,168,1,177,255,171,1,180,255,174,1,183,255, + 178,1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255, + 194,1,201,255,197,1,204,255,200,1,207,255,203,1,210,255,206,1,213,255, + 210,1,216,255,213,1,184,215,182,1,2,4,2,1,114,191,109,1,156,255, + 149,1,159,255,152,1,8,12,7,1,5,8,5,1,16,25,16,1,171,255, + 165,1,174,255,168,1,110,158,106,1,5,8,5,1,6,8,5,1,48,66, + 47,1,189,255,184,1,192,255,187,1,70,92,69,1,6,8,6,2,98,122, + 96,1,207,255,203,1,210,255,206,1,33,39,32,1,7,8,6,1,3,4, + 3,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1,128,128, + 128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188, + 188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248, + 248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1,154,154, + 154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,229,229, + 229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1,240,240, + 240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,195,195,195,1,211,211,211,1,255,255,255,22,248,248, + 248,1,129,129,129,1,255,255,255,22,248,248,248,1,129,129,129,1,255,255, + 255,22,165,165,165,1,181,181,181,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,229,229, + 229,1,177,177,177,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1,214,214, + 214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,139,139, + 139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1,248,248, + 248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203, + 203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128, + 128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tconnectedifidatasource: record size: integer; data: array[0..2590] of byte end = + (size: 2591; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,23,116,99,111, + 110,110,101,99,116,101,100,105,102,105,100,97,116,97,115,111,117,114,99,101, + 23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99, + 111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116, + 105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111, + 95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,156,9,0,0,0,0,0,0,6,0,0,0,24,0,0, + 0,24,0,0,0,204,7,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,4,2,1,5,8,4,1,15,25,14,1,159,255,152,1,162,255,155, + 1,102,158,98,1,5,8,5,2,45,66,44,1,177,255,171,1,180,255,174, + 1,66,92,64,1,6,8,6,2,92,122,90,1,195,255,190,1,198,255,194, + 1,31,39,30,1,6,8,6,2,177,215,173,1,213,255,210,1,205,241,202, + 1,3,4,3,1,100,169,95,1,129,135,129,3,130,135,129,2,130,135,130, + 4,131,135,130,2,131,135,131,4,132,135,131,1,132,135,132,4,133,135,132, + 1,133,135,133,1,7,8,7,1,151,255,143,1,128,128,128,1,156,255,149, + 1,159,255,152,1,162,255,155,1,165,255,158,1,168,255,162,1,171,255,165, + 1,128,128,128,1,177,255,171,1,180,255,174,1,183,255,178,1,186,255,181, + 1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,194,1,128,128,128, + 1,204,255,200,1,207,255,203,1,210,255,206,1,213,255,210,1,216,255,213, + 1,25,30,25,1,151,255,143,1,128,128,128,1,156,255,149,1,159,255,152, + 1,162,255,155,1,165,255,158,1,168,255,162,1,171,255,165,1,128,128,128, + 1,177,255,171,1,180,255,174,1,183,255,178,1,186,255,181,1,189,255,184, + 1,192,255,187,1,195,255,190,1,198,255,194,1,128,128,128,1,204,255,200, + 1,207,255,203,1,210,255,206,1,213,255,210,1,216,255,213,1,219,255,216, + 1,12,21,12,1,128,128,128,1,129,135,129,2,130,135,129,2,130,135,130, + 2,128,128,128,1,130,135,130,1,131,135,130,2,131,135,131,4,132,135,131, + 1,128,128,128,1,132,135,132,3,133,135,132,1,133,135,133,1,219,255,216, + 1,5,8,4,1,128,128,128,1,156,255,149,1,159,255,152,1,162,255,155, + 1,165,255,158,1,168,255,162,1,171,255,165,1,128,128,128,1,177,255,171, + 1,180,255,174,1,183,255,178,1,186,255,181,1,189,255,184,1,192,255,187, + 1,195,255,190,1,198,255,194,1,128,128,128,1,204,255,200,1,207,255,203, + 1,210,255,206,1,213,255,210,1,216,255,213,1,120,139,118,1,9,16,9, + 1,128,128,128,1,156,255,149,1,159,255,152,1,162,255,155,1,165,255,158, + 1,168,255,162,1,171,255,165,1,128,128,128,1,177,255,171,1,180,255,174, + 1,183,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190, + 1,198,255,194,1,128,128,128,1,204,255,200,1,207,255,203,1,210,255,206, + 1,213,255,210,1,216,255,213,1,7,8,7,1,151,255,143,1,128,128,128, + 1,129,135,129,2,130,135,129,2,130,135,130,2,128,128,128,1,130,135,130, + 1,131,135,130,2,131,135,131,4,132,135,131,1,128,128,128,1,132,135,132, + 3,133,135,132,1,133,135,133,1,7,8,7,1,151,255,143,1,128,128,128, + 1,156,255,149,1,159,255,152,1,162,255,155,1,165,255,158,1,168,255,162, + 1,171,255,165,1,128,128,128,1,177,255,171,1,180,255,174,1,183,255,178, + 1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,194, + 1,128,128,128,1,204,255,200,1,207,255,203,1,210,255,206,1,213,255,210, + 1,216,255,213,1,68,79,67,1,106,179,100,1,128,128,128,1,156,255,149, + 1,159,255,152,1,162,255,155,1,165,255,158,1,168,255,162,1,171,255,165, + 1,128,128,128,1,177,255,171,1,180,255,174,1,183,255,178,1,186,255,181, + 1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,194,1,128,128,128, + 1,204,255,200,1,207,255,203,1,210,255,206,1,213,255,210,1,216,255,213, + 1,219,255,216,1,5,8,4,1,128,128,128,1,129,135,129,2,130,135,129, + 2,130,135,130,2,128,128,128,1,130,135,130,1,131,135,130,2,131,135,131, + 4,132,135,131,1,128,128,128,1,132,135,132,3,133,135,132,1,133,135,133, + 1,219,255,216,1,5,8,4,1,128,128,128,1,156,255,149,1,159,255,152, + 1,162,255,155,1,165,255,158,1,168,255,162,1,171,255,165,1,128,128,128, + 1,177,255,171,1,180,255,174,1,183,255,178,1,186,255,181,1,189,255,184, + 1,192,255,187,1,195,255,190,1,198,255,194,1,128,128,128,1,204,255,200, + 1,207,255,203,1,210,255,206,1,213,255,210,1,216,255,213,1,68,79,67, + 1,32,55,31,1,128,128,128,1,156,255,149,1,159,255,152,1,162,255,155, + 1,165,255,158,1,168,255,162,1,171,255,165,1,128,128,128,1,177,255,171, + 1,180,255,174,1,183,255,178,1,186,255,181,1,189,255,184,1,192,255,187, + 1,195,255,190,1,198,255,194,1,128,128,128,1,204,255,200,1,207,255,203, + 1,210,255,206,1,213,255,210,1,216,255,213,1,7,8,7,1,151,255,143, + 1,129,135,129,3,130,135,129,2,130,135,130,4,131,135,130,2,131,135,131, + 4,132,135,131,1,132,135,132,4,133,135,132,1,133,135,133,1,7,8,7, + 1,151,255,143,1,153,255,146,1,156,255,149,1,159,255,152,1,132,207,174, + 1,0,0,255,1,136,207,180,1,171,255,165,1,174,255,168,1,177,255,171, + 1,180,255,174,1,183,255,178,1,0,0,255,1,189,255,184,1,192,255,187, + 1,195,255,190,1,198,255,194,1,201,255,197,1,185,231,205,1,0,0,255, + 1,190,231,211,1,213,255,210,1,216,255,213,1,120,139,118,1,63,106,60, + 1,153,255,146,1,156,255,149,1,99,159,191,1,0,0,255,3,107,159,199, + 1,174,255,168,1,177,255,171,1,180,255,174,1,0,0,255,3,192,255,187, + 1,195,255,190,1,198,255,194,1,163,207,208,1,0,0,255,3,173,207,218, + 1,216,255,213,1,219,255,216,1,5,8,4,1,153,255,146,1,156,255,149, + 1,84,135,200,1,86,135,202,1,41,63,231,1,89,135,206,1,91,135,207, + 1,174,255,168,1,177,255,171,1,0,0,255,5,195,255,190,1,198,255,194, + 1,62,79,237,1,63,79,238,1,44,54,244,1,65,79,240,1,66,79,241, + 1,216,255,213,1,219,255,216,1,5,8,4,1,153,255,146,1,156,255,149, + 1,159,255,152,1,162,255,155,1,0,0,255,1,168,255,162,1,171,255,165, + 1,174,255,168,1,177,255,171,1,180,255,174,1,183,255,178,1,0,0,255, + 1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,194,1,201,255,197, + 1,204,255,200,1,0,0,255,1,210,255,206,1,213,255,210,1,216,255,213, + 1,25,30,25,1,68,115,64,1,153,255,146,1,156,255,149,1,159,255,152, + 1,162,255,155,1,0,0,255,1,168,255,162,1,171,255,165,1,174,255,168, + 1,177,255,171,1,180,255,174,1,183,255,178,1,0,0,255,1,189,255,184, + 1,192,255,187,1,195,255,190,1,198,255,194,1,201,255,197,1,204,255,200, + 1,0,0,255,1,210,255,206,1,213,255,210,1,216,255,213,1,7,8,7, + 1,151,255,143,1,153,255,146,1,156,255,149,1,159,255,152,1,162,255,155, + 1,0,0,255,1,168,255,162,1,171,255,165,1,174,255,168,1,177,255,171, + 1,0,0,255,5,195,255,190,1,198,255,194,1,201,255,197,1,204,255,200, + 1,0,0,255,1,210,255,206,1,213,255,210,1,216,255,213,1,7,8,7, + 1,151,255,143,1,153,255,146,1,156,255,149,1,84,135,200,1,86,135,202, + 1,0,0,255,1,89,135,206,1,91,135,207,1,174,255,168,1,177,255,171, + 1,180,255,174,1,0,0,255,3,192,255,187,1,195,255,190,1,198,255,194, + 1,62,79,237,1,63,79,238,1,0,0,255,1,65,79,240,1,66,79,241, + 1,216,255,213,1,207,241,205,1,29,50,28,1,153,255,146,1,156,255,149, + 1,99,159,191,1,0,0,255,3,107,159,199,1,174,255,168,1,177,255,171, + 1,180,255,174,1,183,255,178,1,0,0,255,1,189,255,184,1,192,255,187, + 1,195,255,190,1,198,255,194,1,163,207,208,1,0,0,255,3,173,207,218, + 1,216,255,213,1,219,255,216,1,5,8,4,1,153,255,146,1,156,255,149, + 1,159,255,152,1,132,207,174,1,0,0,255,1,136,207,180,1,171,255,165, + 1,174,255,168,1,177,255,171,1,180,255,174,1,183,255,178,1,186,255,181, + 1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,194,1,201,255,197, + 1,185,231,205,1,0,0,255,1,190,231,211,1,213,255,210,1,216,255,213, + 1,184,215,182,1,2,4,2,1,114,191,109,1,156,255,149,1,159,255,152, + 1,8,12,7,1,5,8,5,1,16,25,16,1,171,255,165,1,174,255,168, + 1,110,158,106,1,5,8,5,1,6,8,5,1,48,66,47,1,189,255,184, + 1,192,255,187,1,70,92,69,1,6,8,6,2,98,122,96,1,207,255,203, + 1,210,255,206,1,33,39,32,1,7,8,6,1,3,4,3,1,152,1,0, + 0,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158, + 1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248, + 2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139, + 1,128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128, + 1,255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165, + 1,180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244, + 1,146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233, + 1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128, + 2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221, + 1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tifisqlresult: record size: integer; data: array[0..2472] of byte end = + (size: 2473; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,105,102, + 105,115,113,108,114,101,115,117,108,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48,9,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,152,255,144,1,155,255,148,1,158, + 255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172, + 255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186, + 255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201, + 255,196,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215, + 255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161, + 255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175, + 255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189, + 255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203, + 255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218, + 255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164, + 255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178, + 255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192, + 255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206, + 255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152, + 255,144,1,155,255,148,1,111,179,106,1,23,36,22,1,3,5,3,1,30, + 46,29,1,128,193,123,1,172,255,166,1,175,255,169,1,175,250,169,1,82, + 115,79,1,13,18,13,2,84,114,82,1,188,250,183,1,195,255,190,1,198, + 255,193,1,0,0,0,1,203,255,199,1,206,255,202,1,209,255,205,1,212, + 255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,13, + 21,12,1,118,187,113,1,160,249,153,1,115,176,110,1,20,30,19,1,172, + 255,166,1,175,255,169,1,90,129,87,1,90,127,87,1,176,244,170,1,172, + 236,168,1,99,134,97,1,93,124,91,1,195,255,190,1,198,255,193,1,0, + 0,0,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215, + 255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,29,46,27,1,96, + 152,92,1,154,240,148,1,167,255,160,1,169,255,163,1,172,255,166,1,175, + 255,169,1,23,33,22,1,168,236,162,1,184,255,178,1,186,255,181,1,189, + 255,184,1,22,29,21,1,195,255,190,1,198,255,193,1,0,0,0,1,203, + 255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218, + 255,215,1,152,255,144,1,155,255,148,1,145,234,139,1,78,124,75,1,35, + 54,33,1,38,58,36,1,130,196,125,1,172,255,166,1,175,255,169,1,3, + 5,3,1,180,253,174,1,184,255,178,1,186,255,181,1,188,253,183,1,5, + 6,4,1,195,255,190,1,198,255,193,1,0,0,0,1,203,255,199,1,206, + 255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152, + 255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,140, + 214,134,1,17,26,17,1,172,255,166,1,175,255,169,1,22,31,21,1,167, + 235,161,1,184,255,178,1,146,200,142,1,160,216,156,1,34,45,33,1,195, + 255,190,1,198,255,193,1,0,0,0,1,203,255,199,1,206,255,202,1,209, + 255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155, + 255,148,1,18,29,17,1,110,174,105,1,161,250,154,1,133,203,127,1,18, + 27,17,1,172,255,166,1,175,255,169,1,88,126,85,1,89,125,86,1,176, + 244,170,1,53,73,52,1,34,46,33,1,133,177,130,1,195,255,190,1,198, + 255,193,1,0,0,0,1,203,255,199,1,206,255,202,1,209,255,205,1,212, + 255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,118, + 191,113,1,28,45,27,1,3,5,3,1,24,37,23,1,125,188,120,1,172, + 255,166,1,175,255,169,1,175,250,169,1,78,110,75,1,11,15,10,1,15, + 20,14,1,43,58,42,1,47,63,46,1,195,255,190,1,198,255,193,1,0, + 0,0,5,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158, + 255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172, + 255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186, + 255,181,1,189,255,184,1,151,200,147,1,195,255,190,1,198,255,193,1,201, + 255,196,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215, + 255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161, + 255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175, + 255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189, + 255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203, + 255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218, + 255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164, + 255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178, + 255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192, + 255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206, + 255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152, + 255,144,1,155,255,148,1,158,255,151,1,134,213,129,1,42,66,41,1,7, + 10,6,1,5,8,5,1,39,58,38,1,135,196,130,1,149,213,144,1,47, + 66,45,1,7,10,7,1,6,8,6,1,43,58,42,1,148,196,144,1,163, + 213,159,1,51,66,50,1,8,10,8,1,6,8,6,1,47,58,46,1,161, + 196,158,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155, + 255,148,1,158,255,151,1,27,42,25,1,91,142,87,1,158,241,151,1,160, + 242,155,1,105,156,102,1,14,20,13,1,29,42,28,1,101,142,97,1,174, + 241,168,1,177,242,172,1,116,156,113,1,15,20,15,1,32,42,31,1,110, + 142,107,1,190,241,185,1,193,242,189,1,126,156,124,1,16,20,16,1,212, + 255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158, + 255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,111, + 164,107,1,42,61,40,1,178,255,172,1,181,255,175,1,184,255,178,1,186, + 255,181,1,122,164,118,1,46,61,45,1,195,255,190,1,198,255,193,1,201, + 255,196,1,203,255,199,1,132,164,130,1,50,61,49,1,212,255,208,1,215, + 255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161, + 255,154,1,164,255,157,1,167,255,160,1,90,136,87,1,46,68,44,1,163, + 238,158,1,178,255,172,1,181,255,175,1,184,255,178,1,99,136,97,1,50, + 68,49,1,179,238,175,1,195,255,190,1,198,255,193,1,201,255,196,1,108, + 136,106,1,55,68,54,1,195,238,191,1,212,255,208,1,215,255,211,1,218, + 255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164, + 255,157,1,167,255,160,1,5,8,5,1,162,240,156,1,175,255,169,1,178, + 255,172,1,181,255,175,1,184,255,178,1,6,8,6,1,178,240,173,1,192, + 255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,6,8,6,1,194, + 240,190,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152, + 255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167, + 255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1,181, + 255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195, + 255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209, + 255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155, + 255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,0, + 0,0,1,172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184, + 255,178,1,0,0,0,1,189,255,184,1,192,255,187,1,195,255,190,1,198, + 255,193,1,201,255,196,1,0,0,0,1,206,255,202,1,209,255,205,1,212, + 255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158, + 255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172, + 255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186, + 255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201, + 255,196,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215, + 255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161, + 255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175, + 255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189, + 255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203, + 255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218, + 255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164, + 255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178, + 255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192, + 255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206, + 255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152, + 255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167, + 255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1,181, + 255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195, + 255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209, + 255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tififormlinkcomp: record size: integer; data: array[0..1475] of byte end = + (size: 1476; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,102,111,114,109,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,72,5, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,212,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208,208, + 208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,6,151,255, + 143,2,208,208,208,5,0,0,0,3,208,208,208,6,0,0,0,3,208,208, + 208,5,151,255,143,2,208,208,208,4,0,0,0,14,208,208,208,4,151,255, + 143,2,208,208,208,5,0,0,0,3,208,208,208,6,0,0,0,3,208,208, + 208,5,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208,6,0,0, + 0,2,208,208,208,6,151,255,143,2,208,208,208,22,151,255,143,2,0,0, + 0,6,208,208,208,16,151,255,143,2,0,0,0,6,208,208,208,16,151,255, + 143,2,0,0,0,2,208,208,208,5,0,0,0,3,208,208,208,1,0,0, + 0,7,208,208,208,1,0,0,0,2,208,208,208,1,151,255,143,2,0,0, + 0,5,208,208,208,1,0,0,0,16,151,255,143,2,0,0,0,5,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,2,151,255,143,2,0,0,0,2,208,208, + 208,3,0,0,0,2,208,208,208,2,0,0,0,4,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,151,255, + 143,2,0,0,0,2,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,151,255,143,2,0,0,0,2,208,208,208,4,0,0, + 0,7,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,151,255,143,2,208,208,208,8,0,0,0,1,208,208, + 208,5,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,25,60,3,0,0,240,240,240,25,0,0,0,6,59,59,59,1,130,130, + 130,1,0,0,0,6,125,125,125,1,64,64,64,1,0,0,0,6,240,240, + 240,2,0,0,0,5,67,67,67,1,235,235,235,1,70,70,70,1,0,0, + 0,6,62,62,62,1,233,233,233,1,73,73,73,1,0,0,0,5,240,240, + 240,2,0,0,0,4,15,15,15,1,237,237,237,1,255,255,255,10,241,241, + 241,1,19,19,19,1,0,0,0,4,240,240,240,2,0,0,0,5,61,61, + 61,1,233,233,233,1,74,74,74,1,0,0,0,6,66,66,66,1,232,232, + 232,1,67,67,67,1,0,0,0,5,240,240,240,2,0,0,0,6,53,53, + 53,1,124,124,124,1,0,0,0,6,119,119,119,1,59,59,59,1,0,0, + 0,6,240,240,240,2,0,0,0,22,240,240,240,2,37,37,37,1,72,72, + 72,4,11,11,11,1,0,0,0,16,240,240,240,2,134,134,134,1,194,194, + 194,1,152,152,152,3,24,24,24,1,0,0,0,16,240,240,240,2,134,134, + 134,1,105,105,105,1,0,0,0,5,26,26,26,1,66,66,66,1,2,2, + 2,1,0,0,0,1,27,27,27,1,37,37,37,1,76,76,76,1,13,13, + 13,1,5,5,5,1,4,4,4,1,12,12,12,1,0,0,0,1,1,1, + 1,1,7,7,7,1,0,0,0,1,240,240,240,2,134,134,134,1,129,129, + 129,1,40,40,40,2,26,26,26,1,0,0,0,1,121,121,121,1,186,186, + 186,1,124,124,124,1,203,203,203,1,17,17,17,1,98,98,98,1,218,218, + 218,1,157,157,157,1,66,66,66,1,205,205,205,1,184,184,184,1,219,219, + 219,1,125,125,125,1,146,146,146,1,203,203,203,1,66,66,66,1,240,240, + 240,2,134,134,134,1,209,209,209,1,176,176,176,2,116,116,116,1,0,0, + 0,1,238,238,238,1,15,15,15,1,0,0,0,1,123,123,123,1,96,96, + 96,1,98,98,98,1,148,148,148,1,0,0,0,1,39,39,39,1,223,223, + 223,1,4,4,4,1,60,60,60,1,226,226,226,1,0,0,0,1,62,62, + 62,1,153,153,153,1,240,240,240,2,134,134,134,1,105,105,105,1,0,0, + 0,3,7,7,7,1,217,217,217,1,0,0,0,2,80,80,80,1,147,147, + 147,1,98,98,98,1,118,118,118,1,0,0,0,1,39,39,39,1,188,188, + 188,1,0,0,0,1,39,39,39,1,177,177,177,1,0,0,0,1,47,47, + 47,1,168,168,168,1,240,240,240,2,134,134,134,1,105,105,105,1,0,0, + 0,4,183,183,183,1,35,35,35,1,0,0,0,1,148,148,148,1,102,102, + 102,1,98,98,98,1,117,117,117,1,0,0,0,1,39,39,39,1,184,184, + 184,1,0,0,0,1,39,39,39,1,176,176,176,1,0,0,0,1,47,47, + 47,1,168,168,168,1,240,240,240,2,134,134,134,1,105,105,105,1,0,0, + 0,4,60,60,60,1,187,187,187,1,193,193,193,1,172,172,172,1,7,7, + 7,1,98,98,98,1,117,117,117,1,0,0,0,1,39,39,39,1,184,184, + 184,1,0,0,0,1,39,39,39,1,176,176,176,1,0,0,0,1,47,47, + 47,1,168,168,168,1,240,240,240,2,0,0,0,8,11,11,11,1,0,0, + 0,5,9,9,9,1,46,46,46,1,0,0,0,1,9,9,9,1,44,44, + 44,1,0,0,0,1,11,11,11,1,42,42,42,1,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifidialoglinkcomp: record size: integer; data: array[0..1589] of byte end = + (size: 1590; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,105,102, + 105,100,105,97,108,111,103,108,105,110,107,99,111,109,112,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 184,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 204,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25, + 208,208,208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5, + 151,255,143,2,208,208,208,6,0,0,0,12,208,208,208,4,151,255,143,2, + 208,208,208,5,0,0,0,14,208,208,208,3,151,255,143,2,208,208,208,6, + 0,0,0,3,208,208,208,6,0,0,0,3,208,208,208,4,151,255,143,2, + 208,208,208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5, + 151,255,143,2,208,208,208,22,151,255,143,2,0,0,0,4,208,208,208,2, + 0,0,0,1,208,208,208,5,0,0,0,1,208,208,208,9,151,255,143,2, + 0,0,0,7,208,208,208,5,0,0,0,1,208,208,208,9,151,255,143,2, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1, + 208,208,208,1,0,0,0,3,208,208,208,1,0,0,0,1,208,208,208,2, + 0,0,0,1,208,208,208,3,0,0,0,1,208,208,208,1,0,0,0,1, + 151,255,143,2,0,0,0,2,208,208,208,2,0,0,0,9,208,208,208,1, + 0,0,0,8,151,255,143,2,0,0,0,2,208,208,208,2,0,0,0,11, + 208,208,208,1,0,0,0,6,151,255,143,2,0,0,0,2,208,208,208,2, + 0,0,0,11,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,1, + 151,255,143,2,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,1, + 0,0,0,5,208,208,208,1,0,0,0,6,151,255,143,2,0,0,0,13, + 208,208,208,1,0,0,0,8,151,255,143,2,208,208,208,8,0,0,0,2, + 208,208,208,2,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,1, + 0,0,0,4,151,255,143,2,208,208,208,18,0,0,0,4,151,255,143,2, + 208,208,208,18,0,0,0,3,208,208,208,1,151,255,143,2,208,208,208,22, + 151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2, + 208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,25,180,3,0,0, + 240,240,240,25,0,0,0,7,59,59,59,1,130,130,130,1,0,0,0,6, + 125,125,125,1,64,64,64,1,0,0,0,5,240,240,240,2,0,0,0,6, + 67,67,67,1,235,235,235,1,74,74,74,1,8,8,8,6,66,66,66,1, + 233,233,233,1,73,73,73,1,0,0,0,4,240,240,240,2,0,0,0,5, + 15,15,15,1,237,237,237,1,251,251,251,1,248,248,248,8,251,251,251,1, + 241,241,241,1,19,19,19,1,0,0,0,3,240,240,240,2,0,0,0,6, + 61,61,61,1,235,235,235,1,80,80,80,1,0,0,0,6,72,72,72,1, + 235,235,235,1,67,67,67,1,0,0,0,4,240,240,240,2,0,0,0,7, + 53,53,53,1,122,122,122,1,0,0,0,6,117,117,117,1,59,59,59,1, + 0,0,0,5,240,240,240,2,0,0,0,22,240,240,240,2,47,47,47,1, + 72,72,72,1,63,63,63,1,19,19,19,1,0,0,0,2,49,49,49,1, + 0,0,0,5,5,5,5,1,0,0,0,9,240,240,240,2,168,168,168,1, + 161,161,161,1,160,160,160,1,214,214,214,1,56,56,56,1,1,1,1,1, + 130,130,130,1,0,0,0,5,184,184,184,1,0,0,0,9,240,240,240,2, + 168,168,168,1,23,23,23,1,0,0,0,1,40,40,40,1,185,185,185,1, + 0,0,0,1,49,49,49,1,0,0,0,1,30,30,30,1,83,83,83,1, + 30,30,30,1,0,0,0,1,184,184,184,1,0,0,0,2,8,8,8,1, + 0,0,0,3,8,8,8,1,0,0,0,1,5,5,5,1,240,240,240,2, + 168,168,168,1,23,23,23,1,0,0,0,2,206,206,206,1,1,1,1,1, + 174,174,174,1,27,27,27,1,190,190,190,1,112,112,112,1,213,213,213,1, + 6,6,6,1,184,184,184,1,0,0,0,1,131,131,131,1,183,183,183,1, + 169,169,169,1,9,9,9,1,60,60,60,1,203,203,203,1,161,161,161,1, + 171,171,171,1,240,240,240,2,168,168,168,1,23,23,23,1,0,0,0,2, + 197,197,197,1,2,2,2,1,174,174,174,1,22,22,22,1,33,33,33,1, + 31,31,31,1,191,191,191,1,26,26,26,1,184,184,184,1,7,7,7,1, + 156,156,156,1,0,0,0,1,107,107,107,1,70,70,70,1,181,181,181,1, + 21,21,21,1,37,37,37,1,187,187,187,1,240,240,240,2,168,168,168,1, + 23,23,23,1,0,0,0,2,197,197,197,1,1,1,1,1,174,174,174,1, + 29,29,29,1,200,200,200,1,155,155,155,1,198,198,198,1,27,27,27,1, + 184,184,184,1,62,62,62,1,117,117,117,1,0,0,0,1,56,56,56,1, + 128,128,128,1,186,186,186,1,0,0,0,2,174,174,174,1,240,240,240,2, + 168,168,168,1,23,23,23,1,0,0,0,1,80,80,80,1,157,157,157,1, + 1,1,1,1,174,174,174,1,106,106,106,1,87,87,87,1,0,0,0,1, + 199,199,199,1,31,31,31,1,184,184,184,1,23,23,23,1,152,152,152,1, + 0,0,0,1,93,93,93,1,104,104,104,1,167,167,167,1,10,10,10,1, + 28,28,28,1,187,187,187,1,240,240,240,2,168,168,168,1,219,219,219,1, + 220,220,220,1,190,190,190,1,21,21,21,1,1,1,1,1,174,174,174,1, + 41,41,41,1,196,196,196,1,171,171,171,1,190,190,190,1,50,50,50,1, + 184,184,184,1,0,0,0,1,173,173,173,1,134,134,134,1,201,201,201,1, + 27,27,27,1,71,71,71,1,177,177,177,1,170,170,170,1,180,180,180,1, + 240,240,240,2,0,0,0,8,7,7,7,1,6,6,6,1,0,0,0,2, + 46,46,46,1,0,0,0,2,64,64,64,1,21,21,21,1,0,0,0,1, + 39,39,39,1,19,19,19,1,14,14,14,1,159,159,159,1,240,240,240,2, + 0,0,0,18,117,117,117,1,131,131,131,1,161,161,161,1,89,89,89,1, + 240,240,240,2,0,0,0,18,1,1,1,1,61,61,61,1,52,52,52,1, + 0,0,0,1,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22, + 240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2, + 0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifidialog: record size: integer; data: array[0..2489] of byte end = + (size: 2490; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,105,102, + 105,100,105,97,108,111,103,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,68,9,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,0,9,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,152,255,144,1,155,255,148,1,158,255,151,1, + 161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1, + 175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1, + 189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1, + 203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1, + 218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1, + 164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1, + 178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1, + 192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1, + 206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1, + 152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1, + 167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1, + 181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1, + 195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1, + 209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1, + 155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1, + 169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1, + 184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1, + 198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1, + 212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1, + 158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1, + 172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1, + 186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1, + 201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1, + 215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1, + 161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1, + 175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1, + 189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1, + 203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1, + 218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1, + 164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1, + 178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1, + 192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1, + 206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1, + 152,255,144,1,126,208,121,1,113,183,108,1,121,192,116,1,152,236,145,1, + 167,255,160,1,169,255,163,1,139,206,134,1,175,255,169,1,178,255,172,1, + 181,255,175,1,184,255,178,1,186,255,181,1,185,250,180,1,192,255,187,1, + 195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1, + 209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1, + 53,87,50,1,58,94,56,1,60,95,57,1,26,41,25,1,130,199,125,1, + 168,254,162,1,84,125,81,1,175,255,169,1,178,255,172,1,181,255,175,1, + 184,255,178,1,186,255,181,1,53,71,51,1,192,255,187,1,195,255,190,1, + 198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1, + 212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,53,87,50,1, + 144,232,137,1,161,255,154,1,138,215,132,1,46,70,44,1,169,255,163,1, + 139,206,134,1,175,255,169,1,157,225,152,1,122,172,118,1,162,225,157,1, + 186,255,181,1,53,71,51,1,192,255,187,1,195,255,190,1,192,247,187,1, + 201,255,196,1,203,255,199,1,206,255,202,1,202,247,199,1,212,255,208,1, + 211,250,207,1,218,255,215,1,152,255,144,1,53,87,50,1,144,232,137,1, + 161,255,154,1,164,255,157,1,32,49,31,1,168,254,162,1,55,81,53,1, + 156,228,151,1,45,65,44,1,102,143,98,1,30,42,29,1,182,249,177,1, + 53,71,51,1,192,255,187,1,95,124,92,1,56,72,54,1,68,86,66,1, + 196,246,192,1,158,195,154,1,43,52,42,1,78,94,77,1,71,84,70,1, + 218,255,215,1,152,255,144,1,53,87,50,1,144,232,137,1,161,255,154,1, + 164,255,157,1,38,58,36,1,168,253,162,1,55,81,53,1,160,233,154,1, + 155,222,150,1,159,224,154,1,46,64,45,1,167,229,163,1,53,71,51,1, + 187,248,182,1,76,99,74,1,198,255,193,1,117,148,114,1,147,185,144,1, + 60,74,59,1,192,234,188,1,181,218,178,1,57,68,56,1,218,255,215,1, + 152,255,144,1,53,87,50,1,144,232,137,1,161,255,154,1,164,255,157,1, + 38,58,36,1,168,254,162,1,55,81,53,1,155,226,150,1,38,55,37,1, + 71,100,69,1,41,57,40,1,166,228,162,1,53,71,51,1,145,193,142,1, + 106,138,103,1,198,255,193,1,157,199,153,1,101,127,99,1,56,69,55,1, + 209,255,205,1,212,255,208,1,68,81,67,1,218,255,215,1,152,255,144,1, + 53,87,50,1,144,232,137,1,161,255,154,1,113,175,108,1,64,98,61,1, + 168,254,162,1,55,81,53,1,102,149,99,1,117,168,113,1,181,255,175,1, + 40,56,39,1,163,224,159,1,53,71,51,1,175,232,170,1,79,103,77,1, + 198,255,193,1,128,162,125,1,120,151,118,1,71,88,70,1,201,245,197,1, + 189,227,185,1,57,68,56,1,218,255,215,1,152,255,144,1,53,87,50,1, + 22,36,21,1,22,35,21,1,42,65,40,1,153,234,147,1,168,254,162,1, + 55,81,53,1,147,214,142,1,41,59,40,1,60,84,58,1,47,65,45,1, + 150,205,146,1,53,71,51,1,192,255,187,1,63,82,61,1,94,121,92,1, + 43,54,42,1,182,228,178,1,149,184,146,1,64,78,63,1,71,85,69,1, + 63,75,62,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1, + 161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1, + 175,255,169,1,173,248,167,1,177,249,171,1,184,255,178,1,186,255,181,1, + 155,209,151,1,192,255,187,1,195,255,190,1,148,191,145,1,184,234,180,1, + 203,255,199,1,174,216,171,1,193,236,190,1,200,241,197,1,81,96,79,1, + 218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1, + 164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1, + 178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1, + 192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1, + 111,138,109,1,102,124,100,1,78,94,77,1,140,166,137,1,218,255,215,1, + 152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1, + 167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1, + 181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1, + 195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,205,254,201,1, + 159,194,156,1,169,203,166,1,215,255,211,1,218,255,215,1,152,255,144,1, + 155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1, + 169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1, + 184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1, + 198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1, + 212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1, + 158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1, + 172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1, + 186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1, + 201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1, + 215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1, + 161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1, + 175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1, + 189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1, + 203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1, + 218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1, + 164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1, + 178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1, + 192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1, + 206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1, + 152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1, + 167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1, + 181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1, + 195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1, + 209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1, + 155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1, + 169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1, + 184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1, + 198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1, + 212,255,208,1,215,255,211,1,218,255,215,1,12,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tifiitemlinkcomp: record size: integer; data: array[0..1135] of byte end = + (size: 1136; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,105,116,101,109,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,244,3, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,180,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255,143,25,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,25,8,3,0,0,244,244, + 244,25,0,0,0,7,59,59,59,1,133,133,133,1,0,0,0,6,126,126, + 126,1,65,65,65,1,0,0,0,5,244,244,244,2,0,0,0,6,63,63, + 63,1,233,233,233,1,74,74,74,1,6,6,6,6,65,65,65,1,234,234, + 234,1,79,79,79,1,0,0,0,4,244,244,244,2,0,0,0,5,14,14, + 14,1,235,235,235,1,252,252,252,1,250,250,250,8,252,252,252,1,240,240, + 240,1,19,19,19,1,0,0,0,3,244,244,244,2,0,0,0,6,53,53, + 53,1,230,230,230,1,82,82,82,1,0,0,0,6,65,65,65,1,232,232, + 232,1,68,68,68,1,0,0,0,4,244,244,244,2,0,0,0,7,50,50, + 50,1,123,123,123,1,0,0,0,6,116,116,116,1,57,57,57,1,0,0, + 0,5,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,3,14,14, + 14,1,24,24,24,1,0,0,0,17,244,244,244,2,0,0,0,3,70,70, + 70,1,121,121,121,1,1,1,1,1,121,121,121,1,0,0,0,15,244,244, + 244,2,0,0,0,3,70,70,70,1,121,121,121,1,80,80,80,1,211,211, + 211,1,50,50,50,1,0,0,0,1,84,84,84,1,82,82,82,1,0,0, + 0,1,47,47,47,1,53,53,53,1,103,103,103,1,22,22,22,1,75,75, + 75,1,85,85,85,1,0,0,0,4,244,244,244,2,0,0,0,3,70,70, + 70,1,121,121,121,1,67,67,67,1,206,206,206,1,42,42,42,1,104,104, + 104,1,139,139,139,1,147,147,147,1,90,90,90,1,119,119,119,1,173,173, + 173,1,113,113,113,1,224,224,224,1,117,117,117,1,178,178,178,1,65,65, + 65,1,0,0,0,3,244,244,244,2,0,0,0,3,70,70,70,1,121,121, + 121,1,2,2,2,1,181,181,181,1,0,0,0,1,176,176,176,1,53,53, + 53,1,64,64,64,1,163,163,163,1,119,119,119,1,64,64,64,1,0,0, + 0,1,200,200,200,1,0,0,0,1,81,81,81,1,105,105,105,1,0,0, + 0,3,244,244,244,2,0,0,0,3,70,70,70,1,121,121,121,1,2,2, + 2,1,181,181,181,1,0,0,0,1,201,201,201,1,153,153,153,2,108,108, + 108,1,119,119,119,1,64,64,64,1,0,0,0,1,183,183,183,1,0,0, + 0,1,75,75,75,1,108,108,108,1,0,0,0,3,244,244,244,2,0,0, + 0,3,70,70,70,1,121,121,121,1,1,1,1,1,184,184,184,1,0,0, + 0,1,171,171,171,1,24,24,24,1,2,2,2,1,32,32,32,1,119,119, + 119,1,64,64,64,1,0,0,0,1,183,183,183,1,0,0,0,1,75,75, + 75,1,108,108,108,1,0,0,0,3,244,244,244,2,0,0,0,3,70,70, + 70,1,121,121,121,1,0,0,0,1,199,199,199,1,94,94,94,1,51,51, + 51,1,201,201,201,1,190,190,190,1,74,74,74,1,119,119,119,1,64,64, + 64,1,0,0,0,1,183,183,183,1,0,0,0,1,75,75,75,1,108,108, + 108,1,0,0,0,3,244,244,244,2,0,0,0,6,6,6,6,2,0,0, + 0,1,3,3,3,1,5,5,5,1,0,0,0,11,244,244,244,2,0,0, + 0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244, + 244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,22,244,244,244,2,0,0,0,22,244,244,244,25,0,0) + ); + +const + objdata_tifitreeitemlinkcomp: record size: integer; data: array[0..1067] of byte end = + (size: 1068; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,105,102, + 105,116,114,101,101,105,116,101,109,108,105,110,107,99,111,109,112,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,172,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255, + 143,25,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,25,192,2, + 0,0,244,244,244,25,0,0,0,7,59,59,59,1,133,133,133,1,0,0, + 0,6,126,126,126,1,65,65,65,1,0,0,0,5,244,244,244,2,0,0, + 0,6,63,63,63,1,233,233,233,1,74,74,74,1,6,6,6,6,65,65, + 65,1,234,234,234,1,79,79,79,1,0,0,0,4,244,244,244,2,0,0, + 0,5,14,14,14,1,235,235,235,1,252,252,252,1,250,250,250,8,252,252, + 252,1,240,240,240,1,19,19,19,1,0,0,0,3,244,244,244,2,0,0, + 0,6,53,53,53,1,230,230,230,1,82,82,82,1,0,0,0,6,65,65, + 65,1,232,232,232,1,68,68,68,1,0,0,0,4,244,244,244,2,0,0, + 0,7,50,50,50,1,123,123,123,1,0,0,0,6,116,116,116,1,57,57, + 57,1,0,0,0,5,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,3,30,30,30,1,51,51,51,3,39,39,39,1,0,0,0,14,244,244, + 244,2,0,0,0,3,81,81,81,1,136,136,136,1,224,224,224,1,136,136, + 136,1,105,105,105,1,0,0,0,14,244,244,244,2,0,0,0,5,189,189, + 189,1,0,0,0,2,72,72,72,1,73,73,73,1,26,26,26,1,22,22, + 22,1,107,107,107,1,37,37,37,1,0,0,0,1,8,8,8,1,100,100, + 100,1,59,59,59,1,0,0,0,4,244,244,244,2,0,0,0,5,189,189, + 189,1,0,0,0,2,197,197,197,1,150,150,150,1,30,30,30,1,187,187, + 187,1,92,92,92,1,193,193,193,1,8,8,8,1,154,154,154,1,107,107, + 107,1,179,179,179,1,42,42,42,1,0,0,0,3,244,244,244,2,0,0, + 0,5,189,189,189,1,0,0,0,2,186,186,186,1,0,0,0,1,35,35, + 35,1,165,165,165,1,51,51,51,1,149,149,149,1,57,57,57,1,189,189, + 189,1,51,51,51,1,106,106,106,1,111,111,111,1,0,0,0,3,244,244, + 244,2,0,0,0,5,189,189,189,1,0,0,0,2,183,183,183,1,0,0, + 0,1,62,62,62,1,202,202,202,1,153,153,153,2,54,54,54,1,223,223, + 223,1,153,153,153,2,77,77,77,1,0,0,0,3,244,244,244,2,0,0, + 0,5,189,189,189,1,0,0,0,2,183,183,183,1,0,0,0,1,28,28, + 28,1,167,167,167,1,0,0,0,1,29,29,29,1,4,4,4,1,192,192, + 192,1,3,3,3,1,15,15,15,1,19,19,19,1,0,0,0,3,244,244, + 244,2,0,0,0,5,189,189,189,1,0,0,0,2,183,183,183,1,0,0, + 0,2,139,139,139,1,186,186,186,1,179,179,179,1,12,12,12,1,91,91, + 91,1,197,197,197,1,191,191,191,1,37,37,37,1,0,0,0,3,244,244, + 244,2,0,0,0,12,9,9,9,1,0,0,0,3,7,7,7,1,2,2, + 2,1,0,0,0,4,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244, + 244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,22,244,244,244,25,0,0) + ); + +initialization + registerobjectdata(@objdata_tifiintegerendpoint,tbitmapcomp,'tifiintegerendpoint'); + registerobjectdata(@objdata_tifiint64endpoint,tbitmapcomp,'tifiint64endpoint'); + registerobjectdata(@objdata_tifipointerendpoint,tbitmapcomp,'tifipointerendpoint'); + registerobjectdata(@objdata_tifibooleanendpoint,tbitmapcomp,'tifibooleanendpoint'); + registerobjectdata(@objdata_tifirealendpoint,tbitmapcomp,'tifirealendpoint'); + registerobjectdata(@objdata_tifidatetimeendpoint,tbitmapcomp,'tifidatetimeendpoint'); + registerobjectdata(@objdata_tifistringendpoint,tbitmapcomp,'tifistringendpoint'); + registerobjectdata(@objdata_tifiactionendpoint,tbitmapcomp,'tifiactionendpoint'); + registerobjectdata(@objdata_tifilinkcomp,tbitmapcomp,'tifilinkcomp'); + registerobjectdata(@objdata_tifiintegerlinkcomp,tbitmapcomp,'tifiintegerlinkcomp'); + registerobjectdata(@objdata_tifiint64linkcomp,tbitmapcomp,'tifiint64linkcomp'); + registerobjectdata(@objdata_tifipointerlinkcomp,tbitmapcomp,'tifipointerlinkcomp'); + registerobjectdata(@objdata_tifibooleanlinkcomp,tbitmapcomp,'tifibooleanlinkcomp'); + registerobjectdata(@objdata_tifistringlinkcomp,tbitmapcomp,'tifistringlinkcomp'); + registerobjectdata(@objdata_tifidropdownlistlinkcomp,tbitmapcomp,'tifidropdownlistlinkcomp'); + registerobjectdata(@objdata_tifienumlinkcomp,tbitmapcomp,'tifienumlinkcomp'); + registerobjectdata(@objdata_tifireallinkcomp,tbitmapcomp,'tifireallinkcomp'); + registerobjectdata(@objdata_tifidatetimelinkcomp,tbitmapcomp,'tifidatetimelinkcomp'); + registerobjectdata(@objdata_tifiactionlinkcomp,tbitmapcomp,'tifiactionlinkcomp'); + registerobjectdata(@objdata_tifigridlinkcomp,tbitmapcomp,'tifigridlinkcomp'); + registerobjectdata(@objdata_tconnectedifidatasource,tbitmapcomp,'tconnectedifidatasource'); + registerobjectdata(@objdata_tifisqlresult,tbitmapcomp,'tifisqlresult'); + registerobjectdata(@objdata_tififormlinkcomp,tbitmapcomp,'tififormlinkcomp'); + registerobjectdata(@objdata_tifidialoglinkcomp,tbitmapcomp,'tifidialoglinkcomp'); + registerobjectdata(@objdata_tifidialog,tbitmapcomp,'tifidialog'); + registerobjectdata(@objdata_tifiitemlinkcomp,tbitmapcomp,'tifiitemlinkcomp'); + registerobjectdata(@objdata_tifitreeitemlinkcomp,tbitmapcomp,'tifitreeitemlinkcomp'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regifirem.pas b/mseide-msegui/lib/common/regcomponents/regifirem.pas new file mode 100644 index 0000000..c0f77d7 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regifirem.pas @@ -0,0 +1,287 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regifirem; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + classes,mclasses,mseifi,msedesignintf,msepropertyeditors, + msetypes{msestrings},msedesigner, + mseclasses,mseifids,mseifiglob,msegui,typinfo,msesockets,mseifigui, + mseifilink,msessl,mdb,regifirem_bmp,mseifidbgui,msecryptohandler; + +type + tmodulelinkitemeditor = class(tclasselementeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + end; + + tmodulelinkeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tmodulelinkactionitemeditor = class(tmodulelinkitemeditor) + public + function getvalue: msestring; override; + end; + + tmodulelinkactionseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tifidatawidgeteditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + procedure checkcomponent(const avalue: tcomponent); override; + public + end; + + tvaluewidgetlinkitemeditor = class(tmodulelinkitemeditor) + public + function getvalue: msestring; override; + end; + + tvaluewidgetlinkseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tififieldoptoinselementeditor = class(tsetarrayelementeditor) + public + function name: msestring; override; + end; + + tififieldoptionseditor = class(tsetarraypropertyeditor) + protected + function getelementeditorclass: elementeditorclassty; override; + public + procedure setvalue(const value: msestring); override; + end; + + tifitxactioncompeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + end; + + tlocalconncompeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + end; + + tifidatacolsitemeditor = class(tmodulelinkitemeditor) + public + function getvalue: msestring; override; + end; + + tifidatacolseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + +procedure register; +begin + registercomponents('ifi',[tmodulelink,tformlink, + trxwidgetgrid,tdbrxwidgetgrid,ttxdatagrid, + {tpipeifichannel,tsocketpipeifichannel, + tsocketclientifichannel,tsocketserverifichannel,} + ttxdataset,trxdataset,ttxsqlquery, + tpipeiochannel,tsocketstdiochannel, + tsocketclientiochannel,tsocketserveriochannel, + tsocketstdio,tsocketclient, + tsocketserver,tsocketserverstdio, + tssl]); + registerpropertyeditor(typeinfo(tmodulelinkarrayprop),nil,'',tmodulelinkeditor); + registerpropertyeditor(typeinfo(tlinkactions),nil,'',tmodulelinkactionseditor); + registerpropertyeditor(typeinfo(tvaluewidgetlinks),nil,'',tvaluewidgetlinkseditor); + registerpropertyeditor(typeinfo(twidget),tvaluewidgetlink,'widget',tifidatawidgeteditor); + registerpropertyeditor(typeinfo(tcomponent),ttxlinkaction,'ificomp', + tifitxactioncompeditor); + registerpropertyeditor(typeinfo(tcustomiochannel),tcustomiochannel,'localconn', + tlocalconncompeditor); + registerpropertyeditor(typeinfo(tifidatacols),nil,'',tifidatacolseditor); +// registerpropertyeditor(typeinfo(tififieldoptions),tifidscontroller,'', +// tififieldoptionseditor); +end; + +{ tmodulelinkitemeditor } + +function tmodulelinkitemeditor.getvalue: msestring; +//var +// mstr1: msestring; +begin + with tmodulelinkprop(getpointervalue) do begin + result:= msestring('<'+name+'>'); + end; +end; + +{ tmodulelinkactionitemeditor } + +function tmodulelinkactionitemeditor.getvalue: msestring; +var + mstr1: msestring; +begin + result:= inherited getvalue; + with tlinkaction(getpointervalue) do begin + if action = nil then begin + result:= result+'<>'; + end + else begin + mstr1:= msestring(fdesigner.getcomponentname(action)); + if mstr1 = '' then begin + ownernamepath(action); + end; + result:= result+'<'+mstr1+'>'; + end; + end; +end; + +function tmodulelinkitemeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_refresh]; +end; + +{ tmodulelinkeditor } + +function tmodulelinkeditor.geteditorclass: propertyeditorclassty; +begin + result:= tmodulelinkitemeditor; +end; + +{ tmodulelinkactionseditor } + +function tmodulelinkactionseditor.geteditorclass: propertyeditorclassty; +begin + result:= tmodulelinkactionitemeditor; +end; + +{ tifidatawidgeteditor } + +function tifidatawidgeteditor.filtercomponent(const acomponent: tcomponent): boolean; +var + intf1: iificlient; +begin + result:= getcorbainterface(acomponent,typeinfo(iificlient),intf1); +end; + +{ tvaluewidgetlinkitemeditor } + +function tvaluewidgetlinkitemeditor.getvalue: msestring; +var + mstr1: msestring; +begin + result:= inherited getvalue; + with tvaluewidgetlink(getpointervalue) do begin + if widget = nil then begin + result:= result+'<>'; + end + else begin + mstr1:= msestring(fdesigner.getcomponentname(widget)); + if mstr1 = '' then begin + ownernamepath(widget); + end; + result:= result+'<'+mstr1+'>'; + end; + end; +end; + +{ tvaluewidgetlinkseditor } + +function tvaluewidgetlinkseditor.geteditorclass: propertyeditorclassty; +begin + result:= tvaluewidgetlinkitemeditor; +end; + +{ tifidatawidgeteditor } + +procedure tifidatawidgeteditor.checkcomponent(const avalue: tcomponent); +begin + inherited; + with tvaluewidgetlink(fprops[0].instance) do begin + if name = '' then begin + name:= avalue.name; + end; + end; +end; + +{ tififieldoptionseditor } + +function tififieldoptionseditor.getelementeditorclass: elementeditorclassty; +begin + result:= tififieldoptoinselementeditor; +end; + +procedure tififieldoptionseditor.setvalue(const value: msestring); +begin + //readonly +end; + +{ tififieldoptoinselementeditor } + +function tififieldoptoinselementeditor.name: msestring; +var + field1: tfield; +begin + field1:= tifidscontroller(fprops[0].instance).getfield(findex); + if field1 <> nil then begin + result:= msestring(field1.fieldname); + end + else begin + result:= inherited name; + end; +end; + +{ tifitxactioncompeditor } + +function tifitxactioncompeditor.filtercomponent( + const acomponent: tcomponent): boolean; +var + intf1: iifitxaction; +begin + result:= mseclasses.getcorbainterface(acomponent,typeinfo(iifitxaction),intf1); +end; + +{ tlocalconncompeditor } + +function tlocalconncompeditor.filtercomponent( + const acomponent: tcomponent): boolean; +begin + result:= acomponent <> fcomponent; +end; + +{ tifidatacolsitemeditor } + +function tifidatacolsitemeditor.getvalue: msestring; +begin + with tifidatacol(getpointervalue) do begin + result:= msestring('<'+name+'>'); + end; +end; + +{ tifidatacolseditor } + +function tifidatacolseditor.geteditorclass: propertyeditorclassty; +begin + result:= tifidatacolsitemeditor; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regifirem_bmp.pas b/mseide-msegui/lib/common/regcomponents/regifirem_bmp.pas new file mode 100644 index 0000000..c21aae2 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regifirem_bmp.pas @@ -0,0 +1,691 @@ +unit regifirem_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tsocketclient: record size: integer; data: array[0..221] of byte end = + (size: 222; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,111, + 99,107,101,116,99,108,105,101,110,116,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,172,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 192,192,192,38,99,99,99,3,192,192,192,20,99,99,99,1,192,192,192,2, + 99,99,99,1,192,192,192,19,99,99,99,1,192,192,192,3,0,0,0,4, + 192,192,192,13,99,99,99,4,192,192,192,3,99,99,99,1,192,192,192,16, + 99,99,99,4,192,192,192,3,99,99,99,1,192,192,192,19,99,99,99,1, + 192,192,192,3,0,0,0,4,192,192,192,17,99,99,99,1,192,192,192,2, + 99,99,99,1,192,192,192,21,99,99,99,3,192,192,192,255,192,192,192,112, + 0,0) + ); + +const + objdata_tsocketserver: record size: integer; data: array[0..237] of byte end = + (size: 238; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,111, + 99,107,101,116,115,101,114,118,101,114,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,188,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,136,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 192,192,192,42,99,99,99,3,192,192,192,20,99,99,99,1,192,192,192,3, + 99,99,99,1,192,192,192,18,99,99,99,1,192,192,192,2,0,0,0,1, + 192,192,192,2,99,99,99,1,192,192,192,17,99,99,99,1,192,192,192,5, + 99,99,99,1,192,192,192,17,99,99,99,1,192,192,192,5,99,99,99,1, + 192,192,192,17,99,99,99,1,192,192,192,2,0,0,0,1,192,192,192,2, + 99,99,99,1,192,192,192,18,99,99,99,1,192,192,192,3,99,99,99,1, + 192,192,192,20,99,99,99,3,192,192,192,255,192,192,192,108,0,0) + ); + +const + objdata_tsocketstdio: record size: integer; data: array[0..656] of byte end = + (size: 657; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,111, + 99,107,101,116,115,116,100,105,111,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,96,2,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,44,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192, + 192,192,33,99,99,99,3,192,192,192,6,99,99,99,3,192,192,192,11,99, + 99,99,1,192,192,192,2,99,99,99,1,192,192,192,5,99,99,99,1,192, + 192,192,3,99,99,99,1,192,192,192,9,99,99,99,1,192,192,192,3,0, + 0,0,3,192,192,192,2,99,99,99,1,192,192,192,2,0,0,0,1,192, + 192,192,2,99,99,99,1,192,192,192,5,99,99,99,4,192,192,192,3,99, + 99,99,1,192,192,192,4,99,99,99,1,192,192,192,5,99,99,99,1,192, + 192,192,5,99,99,99,4,192,192,192,3,99,99,99,1,192,192,192,4,99, + 99,99,1,192,192,192,5,99,99,99,1,192,192,192,8,99,99,99,1,192, + 192,192,3,0,0,0,3,192,192,192,2,99,99,99,1,192,192,192,2,0, + 0,0,1,192,192,192,2,99,99,99,1,192,192,192,9,99,99,99,1,192, + 192,192,2,99,99,99,1,192,192,192,5,99,99,99,1,192,192,192,3,99, + 99,99,1,192,192,192,11,99,99,99,3,192,192,192,6,99,99,99,3,192, + 192,192,83,0,0,0,1,192,192,192,4,0,0,0,1,192,192,192,13,0, + 0,0,3,192,192,192,2,0,0,0,1,192,192,192,4,0,0,0,1,192, + 192,192,1,0,0,0,1,192,192,192,2,0,0,0,3,192,192,192,5,0, + 0,0,1,192,192,192,4,0,0,0,3,192,192,192,1,0,0,0,3,192, + 192,192,1,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192,3,0, + 0,0,1,192,192,192,4,0,0,0,3,192,192,192,3,0,0,0,1,192, + 192,192,1,0,0,0,1,192,192,192,2,0,0,0,1,192,192,192,1,0, + 0,0,1,192,192,192,1,0,0,0,1,192,192,192,3,0,0,0,1,192, + 192,192,7,0,0,0,1,192,192,192,2,0,0,0,1,192,192,192,1,0, + 0,0,1,192,192,192,2,0,0,0,1,192,192,192,1,0,0,0,1,192, + 192,192,1,0,0,0,1,192,192,192,3,0,0,0,1,192,192,192,7,0, + 0,0,1,192,192,192,2,0,0,0,1,192,192,192,1,0,0,0,1,192, + 192,192,2,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192,1,0, + 0,0,1,192,192,192,3,0,0,0,1,192,192,192,4,0,0,0,3,192, + 192,192,3,0,0,0,1,192,192,192,2,0,0,0,3,192,192,192,1,0, + 0,0,1,192,192,192,2,0,0,0,3,192,192,192,123,0,0) + ); + +const + objdata_tsocketserverstdio: record size: integer; data: array[0..550] of byte end = + (size: 551; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,115,111, + 99,107,101,116,115,101,114,118,101,114,115,116,100,105,111,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,240,1,0,0,0,0,0,0,0,0,0, + 0,24,0,0,0,24,0,0,0,188,1,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,192,192,192,42,99,99,99,3,192,192,192,20,99,99,99, + 1,192,192,192,3,99,99,99,1,192,192,192,18,99,99,99,1,192,192,192, + 2,0,0,0,1,192,192,192,2,99,99,99,1,192,192,192,17,99,99,99, + 1,192,192,192,5,99,99,99,1,192,192,192,17,99,99,99,1,192,192,192, + 5,99,99,99,1,192,192,192,17,99,99,99,1,192,192,192,2,0,0,0, + 1,192,192,192,2,99,99,99,1,192,192,192,18,99,99,99,1,192,192,192, + 3,99,99,99,1,192,192,192,20,99,99,99,3,192,192,192,83,0,0,0, + 1,192,192,192,4,0,0,0,1,192,192,192,13,0,0,0,3,192,192,192, + 2,0,0,0,1,192,192,192,4,0,0,0,1,192,192,192,1,0,0,0, + 1,192,192,192,2,0,0,0,3,192,192,192,5,0,0,0,1,192,192,192, + 4,0,0,0,3,192,192,192,1,0,0,0,3,192,192,192,1,0,0,0, + 1,192,192,192,1,0,0,0,1,192,192,192,3,0,0,0,1,192,192,192, + 4,0,0,0,3,192,192,192,3,0,0,0,1,192,192,192,1,0,0,0, + 1,192,192,192,2,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192, + 1,0,0,0,1,192,192,192,3,0,0,0,1,192,192,192,7,0,0,0, + 1,192,192,192,2,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192, + 2,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192,1,0,0,0, + 1,192,192,192,3,0,0,0,1,192,192,192,7,0,0,0,1,192,192,192, + 2,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192,2,0,0,0, + 1,192,192,192,1,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192, + 3,0,0,0,1,192,192,192,4,0,0,0,3,192,192,192,3,0,0,0, + 1,192,192,192,2,0,0,0,3,192,192,192,1,0,0,0,1,192,192,192, + 2,0,0,0,3,192,192,192,123,0,0) + ); + +const + objdata_tpipeiochannel: record size: integer; data: array[0..886] of byte end = + (size: 887; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,112,105, + 112,101,105,111,99,104,97,110,110,101,108,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,68,3,0,0,0,0,0,0,0,0,0,0,24,0,0, + 0,24,0,0,0,16,3,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,192,192,192,25,153,227,172,22,192,192,192,2,153,227,172,3,0,0,0, + 2,147,147,147,16,153,227,172,1,192,192,192,2,153,227,172,2,0,0,0, + 1,118,119,118,2,0,0,0,1,252,252,252,13,252,253,252,2,153,227,172, + 1,192,192,192,2,153,227,172,1,0,0,0,1,166,165,166,4,0,0,0, + 1,210,214,210,1,201,216,205,1,210,214,211,1,209,215,211,1,210,215,210, + 2,210,215,211,2,209,215,211,1,210,215,211,5,153,227,172,1,192,192,192, + 2,153,227,172,1,0,0,0,1,214,214,214,4,0,0,0,1,166,165,166, + 1,166,166,166,1,166,166,165,1,166,165,165,1,165,165,165,1,166,165,165, + 1,165,165,166,1,165,166,166,1,166,166,166,1,166,165,165,5,153,227,172, + 1,192,192,192,2,153,227,172,2,0,0,0,1,252,252,252,1,255,255,255, + 1,0,0,0,1,118,119,118,1,118,118,118,1,119,118,118,1,118,118,118, + 2,118,119,118,1,118,118,118,1,118,119,118,1,119,118,119,1,118,118,118, + 1,119,118,118,5,153,227,172,1,192,192,192,2,153,227,172,3,0,0,0, + 2,90,89,90,2,89,89,89,1,90,90,90,1,90,89,90,2,89,89,90, + 2,90,90,89,1,90,89,90,7,153,227,172,1,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,1,147,147,146,1,147,147,147,1,146,146,147, + 1,147,147,147,1,147,146,147,2,147,147,147,1,146,147,147,1,147,147,147, + 2,147,147,146,2,146,147,146,2,147,147,147,2,0,0,0,2,153,227,172, + 3,192,192,192,2,153,227,172,1,252,252,252,8,253,252,252,1,252,252,252, + 1,252,252,253,1,252,252,252,1,252,253,252,2,252,252,252,1,0,0,0, + 1,118,119,118,2,0,0,0,1,153,227,172,2,192,192,192,2,153,227,172, + 1,210,215,210,1,210,214,211,1,210,215,210,1,210,215,211,1,209,215,211, + 1,210,214,210,2,201,216,205,1,210,214,211,1,209,215,211,1,210,215,210, + 2,210,215,211,2,0,0,0,1,166,165,166,4,0,0,0,1,153,227,172, + 1,192,192,192,2,153,227,172,1,166,166,166,1,165,166,166,1,165,166,165, + 1,166,165,166,1,165,165,165,1,166,165,165,1,166,165,166,1,166,166,166, + 1,166,166,165,1,166,165,165,1,165,165,165,1,166,165,165,1,165,165,166, + 1,165,166,166,1,0,0,0,1,214,214,214,4,0,0,0,1,153,227,172, + 1,192,192,192,2,153,227,172,1,118,118,118,2,119,118,119,1,118,119,118, + 1,118,118,118,1,118,118,119,1,118,118,118,1,119,118,118,1,118,118,118, + 2,118,119,118,1,118,118,118,1,118,119,118,1,119,118,119,1,118,118,119, + 1,0,0,0,1,252,252,252,1,255,255,255,1,0,0,0,1,153,227,172, + 2,192,192,192,2,153,227,172,1,90,89,89,1,89,90,90,1,90,89,90, + 1,90,90,89,1,90,89,90,1,90,89,89,1,90,90,90,1,89,89,89, + 1,90,90,90,1,90,89,90,2,89,89,90,2,90,90,89,1,90,89,90, + 1,90,90,90,1,90,89,89,1,0,0,0,1,153,227,172,3,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,25,0,0) + ); + +const + objdata_tsocketstdiochannel: record size: integer; data: array[0..823] of byte end = + (size: 824; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,115,111, + 99,107,101,116,115,116,100,105,111,99,104,97,110,110,101,108,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,0,3,0,0,0,0,0,0,0,0, + 0,0,24,0,0,0,24,0,0,0,204,2,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,192,192,192,25,153,227,172,8,99,99,99,3,153,227, + 172,6,99,99,99,3,153,227,172,2,192,192,192,2,153,227,172,7,99,99, + 99,1,192,192,192,2,99,99,99,1,153,227,172,5,99,99,99,1,192,192, + 192,3,99,99,99,1,153,227,172,1,192,192,192,2,153,227,172,6,99,99, + 99,1,192,192,192,3,0,0,0,3,153,227,172,2,99,99,99,1,192,192, + 192,2,0,0,0,1,192,192,192,2,99,99,99,1,192,192,192,2,153,227, + 172,3,99,99,99,4,192,192,192,3,99,99,99,1,153,227,172,4,99,99, + 99,1,192,192,192,5,99,99,99,1,192,192,192,2,153,227,172,3,99,99, + 99,4,192,192,192,3,99,99,99,1,153,227,172,4,99,99,99,1,192,192, + 192,5,99,99,99,1,192,192,192,2,153,227,172,6,99,99,99,1,192,192, + 192,3,0,0,0,3,153,227,172,2,99,99,99,1,192,192,192,2,0,0, + 0,1,192,192,192,2,99,99,99,1,192,192,192,2,153,227,172,7,99,99, + 99,1,192,192,192,2,99,99,99,1,153,227,172,5,99,99,99,1,192,192, + 192,3,99,99,99,1,153,227,172,1,192,192,192,2,153,227,172,8,99,99, + 99,3,153,227,172,6,99,99,99,3,153,227,172,2,192,192,192,2,153,227, + 172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192, + 192,2,153,227,172,7,0,0,0,1,153,227,172,4,0,0,0,1,153,227, + 172,9,192,192,192,2,153,227,172,2,0,0,0,3,153,227,172,2,0,0, + 0,1,153,227,172,4,0,0,0,1,153,227,172,1,0,0,0,1,153,227, + 172,2,0,0,0,3,153,227,172,2,192,192,192,2,153,227,172,1,0,0, + 0,1,153,227,172,4,0,0,0,3,153,227,172,1,0,0,0,3,153,227, + 172,1,0,0,0,1,153,227,172,1,0,0,0,1,153,227,172,3,0,0, + 0,1,153,227,172,1,192,192,192,2,153,227,172,1,0,0,0,3,153,227, + 172,3,0,0,0,1,153,227,172,1,0,0,0,1,153,227,172,2,0,0, + 0,1,153,227,172,1,0,0,0,1,153,227,172,1,0,0,0,1,153,227, + 172,3,0,0,0,1,153,227,172,1,192,192,192,2,153,227,172,4,0,0, + 0,1,153,227,172,2,0,0,0,1,153,227,172,1,0,0,0,1,153,227, + 172,2,0,0,0,1,153,227,172,1,0,0,0,1,153,227,172,1,0,0, + 0,1,153,227,172,3,0,0,0,1,153,227,172,1,192,192,192,2,153,227, + 172,4,0,0,0,1,153,227,172,2,0,0,0,1,153,227,172,1,0,0, + 0,1,153,227,172,2,0,0,0,1,153,227,172,1,0,0,0,1,153,227, + 172,1,0,0,0,1,153,227,172,3,0,0,0,1,153,227,172,1,192,192, + 192,2,153,227,172,1,0,0,0,3,153,227,172,3,0,0,0,1,153,227, + 172,2,0,0,0,3,153,227,172,1,0,0,0,1,153,227,172,2,0,0, + 0,3,153,227,172,2,192,192,192,2,153,227,172,22,192,192,192,2,153,227, + 172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192, + 192,25,0,0) + ); + +const + objdata_tsocketserveriochannel: record size: integer; data: array[0..402] of byte end = + (size: 403; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,115,111, + 99,107,101,116,115,101,114,118,101,114,105,111,99,104,97,110,110,101,108,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,88,1,0,0,0,0,0, + 0,0,0,0,0,24,0,0,0,24,0,0,0,36,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,192,192,192,25,153,227,172,17,99,99,99, + 3,153,227,172,2,192,192,192,2,153,227,172,16,99,99,99,1,192,192,192, + 3,99,99,99,1,153,227,172,1,192,192,192,2,153,227,172,15,99,99,99, + 1,192,192,192,2,0,0,0,1,192,192,192,2,99,99,99,1,192,192,192, + 2,153,227,172,15,99,99,99,1,192,192,192,5,99,99,99,1,192,192,192, + 2,153,227,172,15,99,99,99,1,192,192,192,5,99,99,99,1,192,192,192, + 2,153,227,172,15,99,99,99,1,192,192,192,2,0,0,0,1,192,192,192, + 2,99,99,99,1,192,192,192,2,153,227,172,16,99,99,99,1,192,192,192, + 3,99,99,99,1,153,227,172,1,192,192,192,2,153,227,172,17,99,99,99, + 3,153,227,172,2,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 25,0,0) + ); + +const + objdata_tsocketclientiochannel: record size: integer; data: array[0..402] of byte end = + (size: 403; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,115,111, + 99,107,101,116,99,108,105,101,110,116,105,111,99,104,97,110,110,101,108,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,88,1,0,0,0,0,0, + 0,0,0,0,0,24,0,0,0,24,0,0,0,36,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,192,192,192,25,153,227,172,13,99,99,99, + 3,153,227,172,6,192,192,192,2,153,227,172,12,99,99,99,1,192,192,192, + 2,99,99,99,1,153,227,172,6,192,192,192,2,153,227,172,11,99,99,99, + 1,192,192,192,3,0,0,0,4,153,227,172,3,192,192,192,2,153,227,172, + 8,99,99,99,4,192,192,192,3,99,99,99,1,153,227,172,6,192,192,192, + 2,153,227,172,8,99,99,99,4,192,192,192,3,99,99,99,1,153,227,172, + 6,192,192,192,2,153,227,172,11,99,99,99,1,192,192,192,3,0,0,0, + 4,153,227,172,3,192,192,192,2,153,227,172,12,99,99,99,1,192,192,192, + 2,99,99,99,1,153,227,172,6,192,192,192,2,153,227,172,13,99,99,99, + 3,153,227,172,6,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 25,0,0) + ); + +const + objdata_tformlink: record size: integer; data: array[0..733] of byte end = + (size: 734; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,102,111, + 114,109,108,105,110,107,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 176,2,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 124,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,192,192,25, + 0,0,0,1,153,227,172,2,0,0,0,2,153,227,172,2,0,0,0,2, + 153,227,172,2,0,0,0,2,153,227,172,2,0,0,0,2,153,227,172,2, + 0,0,0,2,153,227,172,1,192,192,192,2,153,227,172,22,192,192,192,2, + 153,227,172,2,255,255,255,18,153,227,172,1,0,0,0,1,192,192,192,2, + 0,0,0,1,153,227,172,1,255,255,255,1,255,0,0,13,255,255,255,1, + 0,0,0,1,192,192,192,1,128,128,128,1,153,227,172,1,0,0,0,1, + 192,192,192,2,0,0,0,1,153,227,172,1,255,255,255,1,255,0,0,13, + 255,255,255,1,192,192,192,1,0,0,0,1,128,128,128,1,153,227,172,2, + 192,192,192,2,153,227,172,2,255,255,255,1,128,128,128,17,153,227,172,2, + 192,192,192,2,153,227,172,2,255,255,255,1,192,192,192,16,128,128,128,1, + 153,227,172,1,0,0,0,1,192,192,192,2,153,227,172,2,255,255,255,1, + 192,192,192,16,128,128,128,1,153,227,172,1,0,0,0,1,192,192,192,2, + 0,0,0,1,153,227,172,1,255,255,255,1,192,192,192,16,128,128,128,1, + 153,227,172,2,192,192,192,2,0,0,0,1,153,227,172,1,255,255,255,1, + 192,192,192,16,128,128,128,1,153,227,172,2,192,192,192,2,153,227,172,2, + 255,255,255,1,192,192,192,16,128,128,128,1,153,227,172,1,0,0,0,1, + 192,192,192,2,153,227,172,2,255,255,255,1,192,192,192,16,128,128,128,1, + 153,227,172,1,0,0,0,1,192,192,192,2,0,0,0,1,153,227,172,1, + 255,255,255,1,192,192,192,16,128,128,128,1,153,227,172,2,192,192,192,2, + 0,0,0,1,153,227,172,1,255,255,255,1,192,192,192,16,128,128,128,1, + 153,227,172,2,192,192,192,2,153,227,172,2,255,255,255,1,192,192,192,16, + 128,128,128,1,153,227,172,1,0,0,0,1,192,192,192,2,153,227,172,2, + 255,255,255,1,192,192,192,16,128,128,128,1,153,227,172,1,0,0,0,1, + 192,192,192,2,0,0,0,1,153,227,172,1,255,255,255,1,192,192,192,16, + 128,128,128,1,153,227,172,2,192,192,192,2,0,0,0,1,153,227,172,1, + 255,255,255,1,192,192,192,16,128,128,128,1,153,227,172,2,192,192,192,2, + 153,227,172,2,255,255,255,1,192,192,192,16,128,128,128,1,153,227,172,1, + 0,0,0,1,192,192,192,2,153,227,172,2,128,128,128,18,153,227,172,1, + 0,0,0,1,192,192,192,2,0,0,0,1,153,227,172,21,192,192,192,2, + 0,0,0,1,153,227,172,2,0,0,0,2,153,227,172,2,0,0,0,2, + 153,227,172,2,0,0,0,2,153,227,172,2,0,0,0,2,153,227,172,2, + 0,0,0,2,153,227,172,1,192,192,192,25,0,0) + ); + +const + objdata_tmodulelink: record size: integer; data: array[0..619] of byte end = + (size: 620; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,109,111, + 100,117,108,101,108,105,110,107,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,60,2,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,192, + 192,25,0,0,0,1,153,227,172,2,0,0,0,2,153,227,172,2,0,0, + 0,2,153,227,172,2,0,0,0,2,153,227,172,2,0,0,0,2,153,227, + 172,2,0,0,0,2,153,227,172,1,192,192,192,2,153,227,172,22,192,192, + 192,2,153,227,172,21,0,0,0,1,192,192,192,2,0,0,0,1,153,227, + 172,2,0,0,0,2,153,227,172,2,0,0,0,2,153,227,172,2,0,0, + 0,2,153,227,172,2,0,0,0,2,153,227,172,4,0,0,0,1,192,192, + 192,2,0,0,0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192, + 192,2,153,227,172,18,0,0,0,1,153,227,172,3,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,153,227, + 172,3,0,0,0,2,153,227,172,2,0,0,0,2,153,227,172,2,0,0, + 0,2,153,227,172,2,0,0,0,2,153,227,172,4,0,0,0,1,192,192, + 192,2,153,227,172,21,0,0,0,1,192,192,192,2,0,0,0,1,153,227, + 172,21,192,192,192,2,0,0,0,1,153,227,172,2,0,0,0,2,153,227, + 172,2,0,0,0,2,153,227,172,2,0,0,0,2,153,227,172,2,0,0, + 0,2,153,227,172,2,0,0,0,2,153,227,172,1,192,192,192,25,0,0) + ); + +const + objdata_trxwidgetgrid: record size: integer; data: array[0..869] of byte end = + (size: 870; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,114,120, + 119,105,100,103,101,116,103,114,105,100,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,52,3,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,255,50,128,128,128,20,255,0,255,4,128,128,128,1,192,192,192,1, + 128,128,128,1,192,192,192,7,255,255,255,1,192,192,192,8,128,128,128,1, + 255,0,255,4,128,128,128,20,255,0,255,4,128,128,128,1,192,192,192,1, + 128,128,128,1,153,227,172,6,192,192,192,1,153,227,172,9,128,128,128,1, + 255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1,153,227,172,1, + 167,167,167,4,153,227,172,1,192,192,192,1,153,227,172,1,167,167,167,3, + 153,227,172,5,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1, + 128,128,128,1,0,0,255,5,153,227,172,1,192,192,192,1,153,227,172,1, + 0,0,255,1,153,227,172,5,0,0,255,1,153,227,172,1,128,128,128,1, + 255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1,0,0,255,1, + 167,167,167,4,0,0,255,1,192,192,192,1,153,227,172,1,167,167,167,1, + 0,0,255,1,167,167,167,3,0,0,255,1,153,227,172,2,128,128,128,1, + 255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1,0,0,255,1, + 153,227,172,4,0,0,255,1,192,192,192,1,153,227,172,2,0,0,255,1, + 153,227,172,3,0,0,255,1,153,227,172,2,128,128,128,1,255,0,255,4, + 128,128,128,1,192,192,192,1,128,128,128,1,0,0,255,1,167,167,167,3, + 153,227,172,1,0,0,255,1,192,192,192,1,153,227,172,1,167,167,167,2, + 0,0,255,1,167,167,167,1,0,0,255,1,167,167,167,2,153,227,172,1, + 128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1, + 0,0,255,5,153,227,172,1,192,192,192,1,153,227,172,4,0,0,255,1, + 153,227,172,4,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1, + 128,128,128,1,0,0,255,1,167,167,167,3,0,0,255,1,153,227,172,1, + 192,192,192,1,153,227,172,1,167,167,167,2,0,0,255,1,167,167,167,1, + 0,0,255,1,153,227,172,3,128,128,128,1,255,0,255,4,128,128,128,1, + 192,192,192,1,128,128,128,1,0,0,255,1,153,227,172,4,0,0,255,1, + 192,192,192,1,153,227,172,2,0,0,255,1,153,227,172,3,0,0,255,1, + 153,227,172,2,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1, + 128,128,128,1,0,0,255,1,167,167,167,3,153,227,172,1,0,0,255,1, + 192,192,192,1,153,227,172,1,167,167,167,1,0,0,255,1,167,167,167,1, + 153,227,172,2,0,0,255,1,153,227,172,2,128,128,128,1,255,0,255,4, + 128,128,128,1,192,192,192,1,128,128,128,1,0,0,255,1,153,227,172,4, + 0,0,255,1,192,192,192,1,153,227,172,1,0,0,255,1,153,227,172,5, + 0,0,255,1,153,227,172,1,128,128,128,1,255,0,255,4,128,128,128,1, + 192,192,192,1,128,128,128,1,153,227,172,1,167,167,167,3,153,227,172,2, + 192,192,192,1,153,227,172,9,128,128,128,1,255,0,255,4,128,128,128,1, + 192,192,192,1,128,128,128,1,153,227,172,6,192,192,192,1,153,227,172,9, + 128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1, + 153,227,172,6,192,192,192,1,153,227,172,9,128,128,128,1,255,0,255,4, + 128,128,128,20,255,0,255,98,0,0) + ); + +const + objdata_ttxdatagrid: record size: integer; data: array[0..871] of byte end = + (size: 872; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,116,120, + 100,97,116,97,103,114,105,100,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,56,3,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0, + 255,50,128,128,128,20,255,0,255,4,128,128,128,1,192,192,192,1,128,128, + 128,1,192,192,192,7,255,255,255,1,192,192,192,8,128,128,128,1,255,0, + 255,4,128,128,128,20,255,0,255,4,128,128,128,1,192,192,192,1,128,128, + 128,1,153,227,172,6,192,192,192,1,153,227,172,9,128,128,128,1,255,0, + 255,4,128,128,128,1,192,192,192,1,128,128,128,1,153,227,172,1,167,167, + 167,4,153,227,172,1,192,192,192,1,153,227,172,1,167,167,167,3,153,227, + 172,5,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1,0,0, + 255,7,192,192,192,1,0,0,255,1,153,227,172,5,0,0,255,1,153,227, + 172,2,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128, + 128,1,153,227,172,1,167,167,167,1,0,0,255,1,167,167,167,2,153,227, + 172,1,192,192,192,1,153,227,172,1,0,0,255,1,167,167,167,3,0,0, + 255,1,167,167,167,1,153,227,172,2,128,128,128,1,255,0,255,4,128,128, + 128,1,192,192,192,1,128,128,128,1,153,227,172,2,0,0,255,1,153,227, + 172,3,192,192,192,1,153,227,172,1,0,0,255,1,153,227,172,3,0,0, + 255,1,153,227,172,3,128,128,128,1,255,0,255,4,128,128,128,1,192,192, + 192,1,128,128,128,1,153,227,172,1,167,167,167,1,0,0,255,1,167,167, + 167,1,153,227,172,2,192,192,192,1,153,227,172,1,167,167,167,1,0,0, + 255,1,167,167,167,1,0,0,255,1,167,167,167,3,153,227,172,1,128,128, + 128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1,153,227, + 172,2,0,0,255,1,153,227,172,3,192,192,192,1,153,227,172,3,0,0, + 255,1,153,227,172,5,128,128,128,1,255,0,255,4,128,128,128,1,192,192, + 192,1,128,128,128,1,153,227,172,1,167,167,167,1,0,0,255,1,167,167, + 167,2,153,227,172,1,192,192,192,1,153,227,172,1,167,167,167,1,0,0, + 255,1,167,167,167,1,0,0,255,1,153,227,172,4,128,128,128,1,255,0, + 255,4,128,128,128,1,192,192,192,1,128,128,128,1,153,227,172,2,0,0, + 255,1,153,227,172,3,192,192,192,1,153,227,172,1,0,0,255,1,153,227, + 172,3,0,0,255,1,153,227,172,3,128,128,128,1,255,0,255,4,128,128, + 128,1,192,192,192,1,128,128,128,1,153,227,172,1,167,167,167,1,0,0, + 255,1,167,167,167,1,153,227,172,2,192,192,192,1,153,227,172,1,0,0, + 255,1,167,167,167,2,153,227,172,1,0,0,255,1,153,227,172,3,128,128, + 128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1,153,227, + 172,2,0,0,255,1,153,227,172,3,192,192,192,1,0,0,255,1,153,227, + 172,5,0,0,255,1,153,227,172,2,128,128,128,1,255,0,255,4,128,128, + 128,1,192,192,192,1,128,128,128,1,153,227,172,1,167,167,167,3,153,227, + 172,2,192,192,192,1,153,227,172,9,128,128,128,1,255,0,255,4,128,128, + 128,1,192,192,192,1,128,128,128,1,153,227,172,6,192,192,192,1,153,227, + 172,9,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128, + 128,1,153,227,172,6,192,192,192,1,153,227,172,9,128,128,128,1,255,0, + 255,4,128,128,128,20,255,0,255,98,0,0) + ); + +const + objdata_trxdataset: record size: integer; data: array[0..1290] of byte end = + (size: 1291; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,114,120, + 100,97,116,97,115,101,116,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,220,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,168,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255, + 25,153,227,172,1,8,4,8,1,0,0,0,7,0,4,0,1,0,0,0, + 3,0,4,0,1,0,0,0,1,8,4,0,1,0,0,0,2,0,4,0, + 1,0,0,0,2,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0, + 1,197,198,197,1,0,4,0,1,205,206,205,1,197,194,197,1,213,202,205, + 1,205,198,197,2,189,190,189,1,205,206,205,1,205,198,205,1,205,202,205, + 1,180,206,205,1,180,206,197,1,197,190,189,1,205,194,197,1,189,202,197, + 1,180,206,205,1,189,194,197,1,0,0,0,1,153,227,172,1,255,0,255, + 2,153,227,172,1,0,4,0,1,0,12,8,1,0,0,0,2,16,0,0, + 3,8,0,0,1,0,0,0,1,0,4,0,1,0,0,0,3,0,4,0, + 1,16,4,0,1,16,8,0,1,8,0,0,1,0,0,0,1,0,4,0, + 2,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,197,206,197, + 1,0,0,0,1,153,227,172,6,205,202,205,1,153,227,172,9,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,238,246,246, + 1,0,4,0,1,153,227,172,6,197,198,197,1,153,227,172,2,0,0,0, + 5,153,227,172,2,0,4,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,197,206,205,1,0,4,0,1,153,227,172,1,41,105,41, + 1,0,0,0,1,41,105,41,1,0,0,0,1,153,227,172,1,197,194,189, + 1,153,227,172,1,0,0,0,1,16,28,222,5,0,0,0,1,153,227,172, + 1,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172,1,0,8,0, + 1,238,246,246,1,0,12,0,1,153,227,172,6,205,194,189,1,153,227,172, + 1,0,0,0,1,16,28,222,1,153,227,172,3,16,28,222,1,0,0,0, + 1,153,227,172,1,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,197,206,197,1,0,0,0,1,153,227,172,1,41,105,41, + 1,0,0,0,2,41,105,41,1,153,227,172,1,205,190,189,1,153,227,172, + 5,16,28,222,2,0,0,0,1,153,227,172,1,0,8,0,1,153,227,172, + 1,255,0,255,2,153,227,172,1,0,0,0,1,255,255,255,1,8,4,0, + 1,153,227,172,4,180,230,190,1,153,227,172,1,213,198,197,1,153,227,172, + 4,16,28,222,2,0,0,0,1,153,227,172,2,0,0,0,1,153,227,172, + 1,255,0,255,2,153,227,172,1,8,8,8,1,197,198,197,1,0,0,0, + 1,153,227,172,1,41,105,41,1,0,0,0,3,153,227,172,1,213,202,197, + 1,153,227,172,3,16,28,222,2,0,0,0,1,153,227,172,3,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,255,255,255, + 1,8,4,0,1,153,227,172,3,180,230,190,1,153,227,172,2,205,194,197, + 1,153,227,172,3,16,28,222,1,0,0,0,1,153,227,172,4,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,8,8,1,197,198,197, + 1,0,0,0,1,153,227,172,1,41,105,41,1,0,0,0,2,41,105,41, + 1,153,227,172,1,205,198,197,1,153,227,172,3,16,28,222,1,0,0,0, + 1,153,227,172,4,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,255,250,246,1,8,4,0,1,153,227,172,6,197,190,189, + 1,153,227,172,9,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,205,206,205,1,0,0,0,1,153,227,172,6,205,202,205, + 1,153,227,172,3,16,28,222,1,0,0,0,1,153,227,172,4,8,4,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,255,4,153,227,172, + 1,0,0,0,1,153,227,172,1,0,0,255,1,153,227,172,1,0,0,0, + 1,153,227,172,1,0,0,255,1,153,227,172,1,16,28,222,1,0,0,0, + 1,153,227,172,1,8,4,0,1,0,0,0,2,8,4,0,1,153,227,172, + 1,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172,3,0,0,255, + 1,153,227,172,2,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172, + 9,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172,3,0,0,255, + 1,153,227,172,3,0,0,255,1,153,227,172,1,0,0,255,1,153,227,172, + 10,255,0,255,2,153,227,172,1,0,0,255,4,153,227,172,5,0,0,255, + 1,153,227,172,11,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172,1,0,0,255, + 1,153,227,172,10,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172,1,0,0,255, + 1,153,227,172,10,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,2,0,0,255,1,153,227,172,3,0,0,255, + 1,153,227,172,9,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,2,0,0,255,1,153,227,172,3,0,0,255, + 1,153,227,172,9,255,0,255,25,0,0) + ); + +const + objdata_ttxdataset: record size: integer; data: array[0..1234] of byte end = + (size: 1235; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,116,120, + 100,97,116,97,115,101,116,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,164,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,112,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255, + 25,153,227,172,1,8,4,8,1,0,0,0,7,0,4,0,1,0,0,0, + 3,0,4,0,1,0,0,0,1,8,4,0,1,0,0,0,2,0,4,0, + 1,0,0,0,2,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0, + 1,197,198,197,1,0,4,0,1,205,206,205,1,197,194,197,1,213,202,205, + 1,205,198,197,2,189,190,189,1,205,206,205,1,205,198,205,1,205,202,205, + 1,180,206,205,1,180,206,197,1,197,190,189,1,205,194,197,1,189,202,197, + 1,180,206,205,1,189,194,197,1,0,0,0,1,153,227,172,1,255,0,255, + 2,153,227,172,1,0,4,0,1,0,12,8,1,0,0,0,2,16,0,0, + 3,8,0,0,1,0,0,0,1,0,4,0,1,0,0,0,3,0,4,0, + 1,16,4,0,1,16,8,0,1,8,0,0,1,0,0,0,1,0,4,0, + 2,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,197,206,197, + 1,0,0,0,1,153,227,172,6,205,202,205,1,153,227,172,9,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,238,246,246, + 1,0,4,0,1,153,227,172,6,197,198,197,1,153,227,172,2,0,0,0, + 5,153,227,172,2,0,4,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,197,206,205,1,0,4,0,1,153,227,172,1,41,105,41, + 1,0,0,0,1,41,105,41,1,0,0,0,1,153,227,172,1,197,194,189, + 1,153,227,172,1,0,0,0,1,16,28,222,5,0,0,0,1,153,227,172, + 1,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172,1,0,8,0, + 1,238,246,246,1,0,12,0,1,153,227,172,6,205,194,189,1,153,227,172, + 1,0,0,0,1,16,28,222,1,153,227,172,3,16,28,222,1,0,0,0, + 1,153,227,172,1,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,197,206,197,1,0,0,0,1,153,227,172,1,41,105,41, + 1,0,0,0,2,41,105,41,1,153,227,172,1,205,190,189,1,153,227,172, + 5,16,28,222,2,0,0,0,1,153,227,172,1,0,8,0,1,153,227,172, + 1,255,0,255,2,153,227,172,1,0,0,0,1,255,255,255,1,8,4,0, + 1,153,227,172,4,180,230,190,1,153,227,172,1,213,198,197,1,153,227,172, + 4,16,28,222,2,0,0,0,1,153,227,172,2,0,0,0,1,153,227,172, + 1,255,0,255,2,153,227,172,1,8,8,8,1,197,198,197,1,0,0,0, + 1,153,227,172,1,41,105,41,1,0,0,0,3,153,227,172,1,213,202,197, + 1,153,227,172,3,16,28,222,2,0,0,0,1,153,227,172,3,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,255,255,255, + 1,8,4,0,1,153,227,172,3,180,230,190,1,153,227,172,2,205,194,197, + 1,153,227,172,3,16,28,222,1,0,0,0,1,153,227,172,4,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,8,8,1,197,198,197, + 1,0,0,0,1,153,227,172,1,41,105,41,1,0,0,0,2,41,105,41, + 1,153,227,172,1,205,198,197,1,153,227,172,3,16,28,222,1,0,0,0, + 1,153,227,172,4,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,255,250,246,1,8,4,0,1,153,227,172,6,197,190,189, + 1,153,227,172,9,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,205,206,205,1,0,0,0,1,153,227,172,6,205,202,205, + 1,153,227,172,3,16,28,222,1,0,0,0,1,153,227,172,4,8,4,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,255,5,153,227,172, + 1,0,0,255,1,153,227,172,1,0,0,0,1,153,227,172,1,0,0,255, + 1,153,227,172,2,16,28,222,1,0,0,0,1,153,227,172,1,8,4,0, + 1,0,0,0,2,8,4,0,1,153,227,172,1,255,0,255,2,153,227,172, + 3,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172,3,0,0,255, + 1,153,227,172,10,255,0,255,2,153,227,172,3,0,0,255,1,153,227,172, + 4,0,0,255,1,153,227,172,1,0,0,255,1,153,227,172,11,255,0,255, + 2,153,227,172,3,0,0,255,1,153,227,172,5,0,0,255,1,153,227,172, + 12,255,0,255,2,153,227,172,3,0,0,255,1,153,227,172,4,0,0,255, + 1,153,227,172,1,0,0,255,1,153,227,172,11,255,0,255,2,153,227,172, + 3,0,0,255,1,153,227,172,4,0,0,255,1,153,227,172,1,0,0,255, + 1,153,227,172,11,255,0,255,2,153,227,172,3,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172,10,255,0,255, + 2,153,227,172,3,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,10,255,0,255,25,0,0) + ); + +const + objdata_tssl: record size: integer; data: array[0..584] of byte end = + (size: 585; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,4,116,115,115, + 108,12,98,105,116,109,97,112,46,105,109,97,103,101,10,32,2,0,0,0, + 0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,236,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,192,192,192,25,0,0,0,1,192, + 192,192,2,0,0,0,2,192,192,192,2,0,0,0,2,192,192,192,2,0, + 0,0,2,192,192,192,2,0,0,0,2,192,192,192,2,0,0,0,2,192, + 192,192,48,0,0,0,1,192,192,192,2,0,0,0,1,192,192,192,20,0, + 0,0,1,192,192,192,2,0,0,0,1,192,192,192,68,0,0,0,1,192, + 192,192,5,0,0,0,3,192,192,192,4,0,0,0,3,192,192,192,3,0, + 0,0,1,192,192,192,4,0,0,0,1,192,192,192,2,0,0,0,1,192, + 192,192,1,0,0,0,1,192,192,192,3,0,0,0,1,192,192,192,2,0, + 0,0,1,192,192,192,3,0,0,0,1,192,192,192,2,0,0,0,1,192, + 192,192,7,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192,6,0, + 0,0,1,192,192,192,6,0,0,0,1,192,192,192,10,0,0,0,3,192, + 192,192,4,0,0,0,3,192,192,192,3,0,0,0,1,192,192,192,4,0, + 0,0,1,192,192,192,8,0,0,0,1,192,192,192,6,0,0,0,1,192, + 192,192,2,0,0,0,1,192,192,192,4,0,0,0,1,192,192,192,2,0, + 0,0,1,192,192,192,1,0,0,0,1,192,192,192,3,0,0,0,1,192, + 192,192,2,0,0,0,1,192,192,192,3,0,0,0,1,192,192,192,2,0, + 0,0,1,192,192,192,7,0,0,0,1,192,192,192,1,0,0,0,1,192, + 192,192,3,0,0,0,1,192,192,192,2,0,0,0,1,192,192,192,3,0, + 0,0,1,192,192,192,2,0,0,0,1,192,192,192,10,0,0,0,3,192, + 192,192,4,0,0,0,3,192,192,192,3,0,0,0,4,192,192,192,1,0, + 0,0,1,192,192,192,23,0,0,0,1,192,192,192,2,0,0,0,1,192, + 192,192,23,0,0,0,1,192,192,192,44,0,0,0,1,192,192,192,23,0, + 0,0,1,192,192,192,2,0,0,0,1,192,192,192,23,0,0,0,1,192, + 192,192,2,0,0,0,2,192,192,192,2,0,0,0,2,192,192,192,2,0, + 0,0,2,192,192,192,2,0,0,0,2,192,192,192,2,0,0,0,2,192, + 192,192,26,0,0) + ); + +const + objdata_ttxsqlquery: record size: integer; data: array[0..1135] of byte end = + (size: 1136; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,116,120, + 115,113,108,113,117,101,114,121,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,64,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,12,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220, + 220,25,153,227,172,2,0,0,0,3,153,227,172,2,0,0,0,3,153,227, + 172,2,0,0,0,1,153,227,172,4,0,0,0,1,153,227,172,4,220,220, + 220,2,153,227,172,1,0,0,0,1,255,214,0,3,0,0,0,2,255,214, + 0,3,0,0,0,2,255,214,0,1,0,0,0,1,153,227,172,2,0,0, + 0,1,255,214,0,1,0,0,0,1,153,227,172,3,220,220,220,2,0,0, + 0,1,255,214,0,1,0,0,0,4,255,214,0,1,0,0,0,3,255,214, + 0,1,0,0,0,1,255,214,0,1,0,0,0,1,153,227,172,3,0,0, + 0,1,255,214,0,1,0,0,0,1,153,227,172,2,220,220,220,2,0,0, + 0,1,255,214,0,1,0,0,0,1,153,227,172,2,0,0,0,1,255,214, + 0,1,0,0,0,1,153,227,172,1,0,0,0,1,255,214,0,1,0,0, + 0,1,255,214,0,1,0,0,0,1,153,227,172,4,0,0,0,1,255,214, + 0,1,0,0,0,1,153,227,172,1,220,220,220,2,0,0,0,1,255,214, + 0,1,0,0,0,2,153,227,172,1,0,0,0,1,255,214,0,1,0,0, + 0,1,153,227,172,1,0,0,0,1,255,214,0,1,0,0,0,1,255,214, + 0,1,0,0,0,1,153,227,172,5,0,0,0,1,255,214,0,1,0,0, + 0,1,220,220,220,2,153,227,172,1,0,0,0,1,255,214,0,2,0,0, + 0,2,255,214,0,1,0,0,0,1,153,227,172,1,0,0,0,1,255,214, + 0,1,0,0,0,1,255,214,0,1,0,0,0,1,153,227,172,6,0,0, + 0,1,255,214,0,1,0,0,0,1,220,220,220,1,153,227,172,2,0,0, + 0,2,255,214,0,1,0,0,0,1,255,214,0,1,0,0,0,3,255,214, + 0,1,0,0,0,1,255,214,0,1,0,0,0,1,153,227,172,5,0,0, + 0,1,255,214,0,1,0,0,0,1,220,220,220,2,153,227,172,3,0,0, + 0,1,255,214,0,1,0,0,0,1,255,214,0,1,0,0,0,1,255,214, + 0,1,0,0,0,1,255,214,0,1,0,0,0,1,255,214,0,1,0,0, + 0,1,153,227,172,4,0,0,0,1,255,214,0,1,0,0,0,1,153,227, + 172,1,220,220,220,2,153,227,172,1,0,0,0,3,255,214,0,1,0,0, + 0,1,255,214,0,1,0,0,0,2,255,214,0,1,0,0,0,2,255,214, + 0,1,0,0,0,3,153,227,172,1,0,0,0,1,255,214,0,1,0,0, + 0,1,153,227,172,2,220,220,220,2,0,0,0,1,255,214,0,3,0,0, + 0,1,153,227,172,1,0,0,0,8,255,214,0,2,0,0,0,1,255,214, + 0,1,0,0,0,1,153,227,172,3,220,220,220,2,153,227,172,1,0,0, + 0,3,153,227,172,2,0,0,0,1,99,218,94,7,0,0,0,2,153,227, + 172,1,0,0,0,1,153,227,172,4,220,220,220,2,153,227,172,6,0,0, + 0,1,99,218,94,7,0,0,0,1,153,227,172,7,220,220,220,2,153,227, + 172,7,0,0,0,4,99,218,94,3,0,0,0,1,153,227,172,7,220,220, + 220,2,153,227,172,11,99,218,94,3,0,0,0,1,153,227,172,7,220,220, + 220,2,0,0,255,5,153,227,172,1,0,0,255,1,153,227,172,3,0,0, + 255,1,99,218,94,3,0,0,0,1,153,227,172,7,220,220,220,2,153,227, + 172,2,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172,2,99,218, + 94,1,0,0,255,1,99,218,94,2,0,0,0,1,153,227,172,8,220,220, + 220,2,153,227,172,2,0,0,255,1,153,227,172,4,0,0,255,1,153,227, + 172,1,0,0,255,1,99,218,94,2,0,0,0,1,153,227,172,9,220,220, + 220,2,153,227,172,2,0,0,255,1,153,227,172,5,0,0,255,1,99,218, + 94,3,0,0,0,1,153,227,172,9,220,220,220,2,153,227,172,2,0,0, + 255,1,153,227,172,4,0,0,255,1,153,227,172,1,0,0,255,1,99,218, + 94,1,0,0,0,1,153,227,172,10,220,220,220,2,153,227,172,2,0,0, + 255,1,153,227,172,4,0,0,255,1,153,227,172,1,0,0,255,1,153,227, + 172,12,220,220,220,2,153,227,172,2,0,0,255,1,153,227,172,3,0,0, + 255,1,153,227,172,2,99,218,94,1,0,0,255,1,153,227,172,11,220,220, + 220,2,153,227,172,2,0,0,255,1,153,227,172,3,0,0,255,1,153,227, + 172,1,0,0,0,1,99,218,94,1,0,0,255,1,153,227,172,11,220,220, + 220,11,0,0,0,1,153,227,172,1,220,220,220,12,0,0) + ); + +initialization + registerobjectdata(@objdata_tsocketclient,tbitmapcomp,'tsocketclient'); + registerobjectdata(@objdata_tsocketserver,tbitmapcomp,'tsocketserver'); + registerobjectdata(@objdata_tsocketstdio,tbitmapcomp,'tsocketstdio'); + registerobjectdata(@objdata_tsocketserverstdio,tbitmapcomp,'tsocketserverstdio'); + registerobjectdata(@objdata_tpipeiochannel,tbitmapcomp,'tpipeiochannel'); + registerobjectdata(@objdata_tsocketstdiochannel,tbitmapcomp,'tsocketstdiochannel'); + registerobjectdata(@objdata_tsocketserveriochannel,tbitmapcomp,'tsocketserveriochannel'); + registerobjectdata(@objdata_tsocketclientiochannel,tbitmapcomp,'tsocketclientiochannel'); + registerobjectdata(@objdata_tformlink,tbitmapcomp,'tformlink'); + registerobjectdata(@objdata_tmodulelink,tbitmapcomp,'tmodulelink'); + registerobjectdata(@objdata_trxwidgetgrid,tbitmapcomp,'trxwidgetgrid'); + registerobjectdata(@objdata_ttxdatagrid,tbitmapcomp,'ttxdatagrid'); + registerobjectdata(@objdata_trxdataset,tbitmapcomp,'trxdataset'); + registerobjectdata(@objdata_ttxdataset,tbitmapcomp,'ttxdataset'); + registerobjectdata(@objdata_tssl,tbitmapcomp,'tssl'); + registerobjectdata(@objdata_ttxsqlquery,tbitmapcomp,'ttxsqlquery'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regkernel.pas b/mseide-msegui/lib/common/regcomponents/regkernel.pas new file mode 100644 index 0000000..6a49790 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regkernel.pas @@ -0,0 +1,908 @@ +{ MSEide Copyright (c) 1999-2018 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regkernel; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + typinfo,msepropertyeditors; + +implementation +uses + classes,mclasses,msethreadcomp,msebitmap,msetimer,msestatfile,mseact, + mseactions,mseshapes,msewidgets,mseindexlookupeditor,msecornermaskeditor, + msedesignintf,msemenus,msegui,msepipestream,sysutils,mseassistivehandler, + msegraphutils,regkernel_bmp,msegraphics,msestrings,msepostscriptprinter, + mseprinter,msetypes,msedatalist,msedatamodules,mseclasses,formdesigner, + mseapplication,mseglob,mseguiglob,mseskin,msedesigner,msemacros, + mseguithreadcomp,mseprocmonitorcomp,msefadepropedit,mseguiprocess, + msearrayprops,msesumlist,mserttistat,msestockobjects,regglob,msearrayutils, + msecryptohandler,msestringcontainer,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + tactivator1 = class(tactivator); + tskincontroller1 = class(tskincontroller); + tarrayelementeditor1 = class(tarrayelementeditor); + + temptysetpropertyeditor = class(tsetpropertyeditor) + public + procedure updatedefaultvalue; override; //implicit [] default + end; + + tactionpropertyeditor = class(tcomponentpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tshortcutactionpropertyeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tshortcutactionspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tskincolorarraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function itemgetvalue(const sender: tarrayelementeditor): msestring; + override; + end; + + tlevelarrayelementeditor = class(tarrayelementeditor) + public + function name: msestring; override; + end; + + tlevelarraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function getelementeditorclass: elementeditorclassty; override; + end; + + tneglevelarrayelementeditor = class(tarrayelementeditor) + public + function name: msestring; override; + end; + + tneglevelarraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function getelementeditorclass: elementeditorclassty; override; + end; + + tactionstatespropertyeditor = class(tsetpropertyeditor) + protected + function getdefaultstate: propertystatesty override; + function getinvisibleitems: tintegerset override; + end; + + tbounds_xeditor = class(tordinalpropertyeditor) + public + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + end; + + tbounds_yeditor = class(tordinalpropertyeditor) + public + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + end; + + tbounds_sizeeditor = class(tordinalpropertyeditor) + public + procedure setvalue(const value: msestring); override; + end; + + tframepropertyeditor = class(toptionalclasspropertyeditor) + protected + function dispname: msestring; override; + public + procedure edit; override; + end; + + tactivatorclientspropertyeditor = class(tconstarraypropertyeditor) + protected + procedure itemmoved(const source,dest: integer); override; + public + function subproperties: propertyeditorarty; override; + end; + + tskincontrollerextenderspropertyeditor = class(tconstarraypropertyeditor) + protected + procedure itemmoved(const source,dest: integer); override; + public + function subproperties: propertyeditorarty; override; + end; + + tsysshortcutelementeditor = class(tarrayelementeditor) + public + function name: msestring; override; + end; + + tsysshortcutspropertyeditor = class(tconstarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function getelementeditorclass: elementeditorclassty; override; + public + end; + + tassistiveshortcutelementeditor = class(tarrayelementeditor) + public + function name: msestring; override; + end; + + tassistiveshortcutspropertyeditor = class(tconstarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function getelementeditorclass: elementeditorclassty; override; + public + end; + + tfacelocalpropseditor = class(temptysetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + tfacepropertyeditor = class(toptionalclasspropertyeditor) + protected + function dispname: msestring; override; + end; + + tfaceelementeditor = class(tclasselementeditor) + protected + function dispname: msestring; override; + end; + + tfacelistpropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tindexlookupeditor = class(tmsestringpropertyeditor) + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + procedure edit(); override; + end; + + tcornermaskeditor = class(tmsestringpropertyeditor) + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + procedure edit(); override; + end; + + tmacroseditor = class(tpersistentarraypropertyeditor) + protected + function itemgetvalue(const sender: tarrayelementeditor): msestring + override; + end; + + timagelistversioncounteditor = class(tordinalpropertyeditor) + public + procedure setvalue(const value: msestring); override; +end; + +const + datamoduleintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createmsedatamodule; + initnewcomponent: nil; getscale: nil; sourcetoform: nil; + ); + +procedure Register; +begin + registerclass(tmsedatamodule); + registercomponents('Gui',[tmainmenu,tpopupmenu, + tfacecomp,tfacelist,tframecomp,tfontcomp,tskincontroller, +// tskinextender, + tbitmapcomp,timagelist,tshortcutcontroller,thelpcontroller, + tguiprocess, + taction,tguithreadcomp,tassistivehandler, + tassistivewidgetitem]); + registercomponenttabhints(['Gui'],['Non visual components with GUI dependence']); + + registercomponents('NoGui',[tstatfile,trttistat,tnoguiaction,tactivator, + ttimer,tanimtimer,tanimitemcomp,tthreadcomp,tpipereadercomp, + tprocessmonitor, + tstringcontainer,tkeystringcontainer]); + registercomponenttabhints(['NoGui'],['Components without GUI dependence']); + + registerpropertyeditor(typeinfo(fontlocalpropsty),nil,'', + temptysetpropertyeditor); + registerpropertyeditor(typeinfo(framelocalpropsty),nil,'', + temptysetpropertyeditor); + registerpropertyeditor(typeinfo(framelocalprops1ty),nil,'', + temptysetpropertyeditor); + registerpropertyeditor(typeinfo(facelocalpropsty),nil,'', + tfacelocalpropseditor); + + registerpropertyeditor(typeinfo(tskincolors),nil,'', + tskincolorarraypropertyeditor); + registerpropertyeditor(typeinfo(tstatfile),tstatfile,'', + tlinkcomponentpropertyeditor); + + registerpropertyeditor(typeinfo(tcustomframe),nil,'',tframepropertyeditor); + registerpropertyeditor(typeinfo(tcustomface),nil,'',tfacepropertyeditor); + + registerpropertyeditor(typeinfo(tfacearrayprop),nil,'',tfacelistpropertyeditor); + registerpropertyeditor(typeinfo(tcustomaction),nil,'',tactionpropertyeditor); + registerpropertyeditor(typeinfo(tshortcutactions),nil,'', + tshortcutactionspropertyeditor); + registerpropertyeditor(typeinfo(tcolorarrayprop),tcustomface,'fade_color', + tfacefadecoloreditor); + registerpropertyeditor(typeinfo(trealarrayprop),tcustomface,'fade_pos', + tfacefadeposeditor); + registerpropertyeditor(typeinfo(tcolorarrayprop),tfacetemplate,'fade_color', + tfacetemplatefadecoloreditor); + registerpropertyeditor(typeinfo(trealarrayprop),tfacetemplate,'fade_pos', + tfacetemplatefadeposeditor); + + registerpropertyeditor(typeinfo(tcolorarrayprop),tcustomface,'fade_opacolor', + tfacefadeopacoloreditor); + registerpropertyeditor(typeinfo(trealarrayprop),tcustomface,'fade_opapos', + tfacefadeopaposeditor); + registerpropertyeditor(typeinfo(tcolorarrayprop),tfacetemplate,'fade_opacolor', + tfacetemplatefadeopacoloreditor); + registerpropertyeditor(typeinfo(trealarrayprop),tfacetemplate,'fade_opapos', + tfacetemplatefadeopaposeditor); + + registerpropertyeditor(typeinfo(int32),timagelist,'versioncount', + timagelistversioncounteditor); + registerpropertyeditor(typeinfo(msestring),timagelist,'cornermask_topleft', + tcornermaskeditor); + registerpropertyeditor(typeinfo(msestring),timagelist,'cornermask_bottomleft', + tcornermaskeditor); + registerpropertyeditor(typeinfo(msestring),timagelist,'cornermask_bottomright', + tcornermaskeditor); + registerpropertyeditor(typeinfo(msestring),timagelist,'cornermask_topright', + tcornermaskeditor); + registerpropertyeditor(typeinfo(msestring),timagelist,'indexlookup', + tindexlookupeditor); + registerpropertyeditor(typeinfo(msestring),tfacelist,'indexlookup', + tindexlookupeditor); + + registerpropertyeditor(typeinfo(tsumdownarrayprop),nil,'', + tlevelarraypropertyeditor); + registerpropertyeditor(typeinfo(tsumuparrayprop),nil,'', + tneglevelarraypropertyeditor); + registerpropertyeditor(typeinfo(tsysshortcuts),nil,'', + tsysshortcutspropertyeditor); + registerpropertyeditor(typeinfo(tassistiveshortcuts),nil,'', + tassistiveshortcutspropertyeditor); + registerpropertyeditor(typeinfo(string),tfont,'name',tfontnamepropertyeditor); + registerpropertyeditor(typeinfo(actionstatesty),nil,'', + tactionstatespropertyeditor); + registerpropertyeditor(typeinfo(shortcutty),nil,'',tshortcutpropertyeditor); + registerpropertyeditor(typeinfo(imagenrty),nil,'',timagenrpropertyeditor); + registerpropertyeditor(typeinfo(facenrty),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(tcollection),nil,'',tcollectionpropertyeditor); + registerpropertyeditor(typeinfo(tmenuitems),nil,'',tmenuarraypropertyeditor); + registerpropertyeditor(typeinfo(tcustomframe),nil,'',tframepropertyeditor); + registerpropertyeditor(typeinfo(tcustomface),nil,'', + toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(toptionalfont),nil,'', + toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(tparentfont),nil,'', + tparentfontpropertyeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_x',tbounds_xeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_y',tbounds_yeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cy', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cx', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cymin', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cxmin', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cymax', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cxmax', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(tfacetemplate),tcustommenu,'facetemplate', + toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(tfacetemplate),tmainmenu,'popupfacetemplate', + toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(integer),tactivator,'clients', + tactivatorclientspropertyeditor); + registerpropertyeditor(typeinfo(integer),tskincontroller,'extenders', + tskincontrollerextenderspropertyeditor); + registerpropertyeditor(typeinfo(stockglyphty),nil,'', + tstockglypheditor); + registerpropertyeditor(typeinfo(tmacroproperty),nil,'', + tmacroseditor); + + registerunitgroup(['msestatfile'],['msestat']); + + registerdesignmoduleclass(tmsedatamodule,@datamoduleintf); +end; + +{ tactionpropertyeditor } + +function tactionpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +{ tactionstatespropertyeditor } + +function tactionstatespropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile,ps_refresh]; +end; + +function tactionstatespropertyeditor.getinvisibleitems: tintegerset; +begin + result:= invisibleactionstates; +end; + +{ tbounds_xeditor } + +function tbounds_xeditor.getvalue: msestring; +begin + if fprops[0].instance = fmodule then begin + result:= inttostrmse(fdesigner.getmodulex(fmodule)); +// result:= inttostr(twidget(fprops[0].instance).screenpos.x); + end + else begin + result:= inherited getvalue; + end; +end; + +procedure tbounds_xeditor.setvalue(const value: msestring); +begin + if fprops[0].instance = fmodule then begin + fdesigner.setmodulex(fmodule,strtoint(value)); + end + else begin + inherited; + end; +end; + +{ tbounds_yeditor } + +function tbounds_yeditor.getvalue: msestring; +begin + if fprops[0].instance = fmodule then begin + result:= inttostrmse(fdesigner.getmoduley(fmodule)); +// result:= inttostr(twidget(fprops[0].instance).screenpos.y); + end + else begin + result:= inherited getvalue; + end; +end; + +procedure tbounds_yeditor.setvalue(const value: msestring); +begin + if fprops[0].instance = fmodule then begin + fdesigner.setmoduley(fmodule,strtoint(value)); + end + else begin + inherited; + end; +end; + +{ tbounds_sizeeditor } + +procedure tbounds_sizeeditor.setvalue(const value: msestring); +begin + inherited; + fdesigner.modulesizechanged(fmodule); +end; + +{ tframepropertyeditor } + +function tframepropertyeditor.dispname: msestring; +begin + with tcustomframe(getpointervalue) do begin + if template <> nil then begin + result:= msestring(template.name); + end + else begin + result:= inherited dispname; + end; + end; +end; + +procedure tframepropertyeditor.edit; +begin + inherited; + if fprops[0].instance is twidget then begin + twidget1(fprops[0].instance).clientrectchanged; + end; +end; + +{ tactivatorclientspropertyeditor } + +function tactivatorclientspropertyeditor.subproperties: propertyeditorarty; +var + int1: integer; + ar1: stringarty; +begin + with tactivator1(fprops[0].instance) do begin + updateorder; + fclientnames:= nil; + ar1:= getclientnames; + setlength(result,length(fclients)); + for int1:= 0 to high(result) do begin + result[int1]:= tconstelementeditor.create(msestring(ar1[int1]), + int1,self,geteditorclass,fdesigner,fobjectinspector,fprops,ftypeinfo); + end; + end; +end; + +procedure tactivatorclientspropertyeditor.itemmoved(const source: integer; + const dest: integer); +begin + moveitem(tactivator1(fprops[0].instance).fclients,source,dest); + modified; +end; + +{ tskincontrollerextenderspropertyeditor } + +function tskincontrollerextenderspropertyeditor.subproperties: propertyeditorarty; +var + int1: integer; + ar1: stringarty; +begin + with tskincontroller1(fprops[0].instance) do begin + updateorder; + fextendernames:= nil; + ar1:= getextendernames; + setlength(result,length(fextenders)); + for int1:= 0 to high(result) do begin + result[int1]:= tconstelementeditor.create(msestring(ar1[int1]), + int1,self,geteditorclass,fdesigner,fobjectinspector,fprops,ftypeinfo); + end; + end; +end; + +procedure tskincontrollerextenderspropertyeditor.itemmoved(const source: integer; + const dest: integer); +begin + moveitem(pointerarty(tskincontroller1(fprops[0].instance).fextenders), + source,dest); + modified; +end; + +{ tsysshortcutelementeditor } + +function tsysshortcutelementeditor.name: msestring; +begin + result:= msestring(getenumname(typeinfo(sysshortcutty),findex)); +end; + +{ tsysshortcutspropertyeditor } + +function tsysshortcutspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tshortcutpropertyeditor; +end; + +function tsysshortcutspropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tsysshortcutelementeditor; +end; + +{ tassistiveshortcutelementeditor } + +function tassistiveshortcutelementeditor.name: msestring; +begin + result:= msestring(getenumname(typeinfo(assistiveshortcutty),findex)); +end; + +{ tassistiveshortcutspropertyeditor } + +function tassistiveshortcutspropertyeditor.geteditorclass(): + propertyeditorclassty; +begin + result:= tshortcutarpropertyeditor; +end; + +function tassistiveshortcutspropertyeditor.getelementeditorclass(): + elementeditorclassty; +begin + result:= tassistiveshortcutelementeditor; +end; + +{ tshortcutactionpropertyeditor } + +function tshortcutactionpropertyeditor.getvalue: msestring; +var + item1: tshortcutaction; +begin + item1:= tshortcutaction(getpointervalue); + if item1.action = nil then begin + result:= '<--->'; + end + else begin + result:= '<'+getcomponentpropname(item1.action)+'>'; + { + result:= '<'; + if item1.action.owner <> module then begin + result:= result+module.name+'.'; + end; + result:= result+designer.getcomponentdispname(item1.action)+'>'; + } + end; + result:= result + '<' + item1.dispname + '>'; +end; + +{ tshortcutactionspropertyeditor } + +function tshortcutactionspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tshortcutactionpropertyeditor; +end; + +{ tlevelarraypropertyeditor } + +function tlevelarraypropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tlevelarrayelementeditor; +end; + +{ tlevelarrayelementeditor } + +function tlevelarrayelementeditor.name: msestring; +begin + result:= 'Level ' + inttostrmse(findex+1); +end; + +{ tneglevelarraypropertyeditor } + +function tneglevelarraypropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tneglevelarrayelementeditor; +end; + +{ tneglevelarrayelementeditor } + +function tneglevelarrayelementeditor.name: msestring; +begin + result:= 'Level ' + inttostrmse(-(findex+1)); +end; + +(* +{ tactionshortcutspropertyeditor } + +constructor tactionshortcutspropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fsc1:= aprops[0].propinfo^.name = 'shortcut1'; + inherited; +end; + +procedure tactionshortcutspropertyeditor.setvalue(const value: msestring); +var + ar1: msestringarty; + ar2: shortcutarty; + int1: integer; +begin + ar1:= splitstring(value,widechar(' ')); + if high(ar1) > 0 then begin + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar2[int1]:= texttovalue(ar1[int1]); + end; + for int1:= 0 to high(fprops) do begin + if fprops[int1].instance is taction then begin + with taction(fprops[int1].instance) do begin + if fsc1 then begin + shortcuts1:= ar2; + end + else begin + shortcuts:= ar2; + end; + end; + end + else begin + setordvalue(int1,0); + end; + end; + end + else begin + inherited; + end; +end; + +function tactionshortcutspropertyeditor.getvalue: msestring; +var + ar1: shortcutarty; + int1: integer; +begin + result:= ''; + with taction(fprops[0].instance) do begin + if self.fsc1 then begin + ar1:= shortcuts1; + end + else begin + ar1:= shortcuts; + end; + end; + result:= ''; + for int1:= 0 to high(ar1) do begin + result:= result + getvaluetext(ar1[int1]) + ' '; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; +end; + +{ tshortcutactionitempropertyeditor } + +constructor tshortcutactionitempropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fsc1:= aprops[0].propinfo^.name = 'shortcut1default'; + inherited; +end; + +procedure tshortcutactionitempropertyeditor.setvalue(const value: msestring); +var + ar1: msestringarty; + ar2: shortcutarty; + int1: integer; +begin + ar1:= splitstring(value,widechar(' ')); + if high(ar1) > 0 then begin + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar2[int1]:= texttovalue(ar1[int1]); + end; + for int1:= 0 to high(fprops) do begin + if fprops[int1].instance is tshortcutaction then begin + with tshortcutaction(fprops[int1].instance) do begin + if fsc1 then begin + shortcuts1default:= ar2; + end + else begin + shortcutsdefault:= ar2; + end; + end; + end + else begin + setordvalue(int1,0); + end; + end; + end + else begin + inherited; + end; +end; + +function tshortcutactionitempropertyeditor.getvalue: msestring; +var + ar1: shortcutarty; + int1: integer; +begin + result:= ''; + with tshortcutaction(fprops[0].instance) do begin + if self.fsc1 then begin + ar1:= shortcuts1default; + end + else begin + ar1:= shortcutsdefault; + end; + end; + result:= ''; + for int1:= 0 to high(ar1) do begin + result:= result + getvaluetext(ar1[int1]) + ' '; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; +end; +*) +{ tfacelocalpropseditor } + +function tfacelocalpropseditor.getinvisibleitems: tintegerset; +begin + result:= invisiblefacelocalprops; +end; + +{ tfaceeditor } + +function tfacepropertyeditor.dispname: msestring; +begin + with tcustomface(getpointervalue) do begin + if template <> nil then begin + result:= msestring(template.name); + end + else begin + result:= inherited dispname; + end; + end; +end; + +{ tfaceelementeditor } + +function tfaceelementeditor.dispname: msestring; +begin + with tcustomface(getpointervalue) do begin + if template <> nil then begin + result:= msestring(template.name); + end + else begin + result:= inherited dispname; + end; + end; +end; + +{ tfacelistpropertyeditor } + +function tfacelistpropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tfaceelementeditor; +end; + +{ temptysetpropertyeditor } + +procedure temptysetpropertyeditor.updatedefaultvalue; +begin + if getordvalue <> 0 then begin + include(fstate,ps_modified); + end + else begin + exclude(fstate,ps_modified); + end; +end; + +{ tskincolorarraypropertyeditor } + +function tskincolorarraypropertyeditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + result:= msestring('<'+colortostring(tskincolor( + tarrayelementeditor1(sender).getpointervalue(0)).color) + '>'); +end; + +{ tindexlookupeditor } + +procedure tindexlookupeditor.setvalue(const value: msestring); +begin + if (value = '') and + askyesno('Do you want to delete the lookup list?') then begin + inherited setvalue(''); + end + else begin + inherited setvalue(getmsestringvalue(0)); + end; +end; + +function tindexlookupeditor.getvalue: msestring; +var + mstr1: msestring; +begin + mstr1:= getmsestringvalue(0,true); + if mstr1 = '' then begin + result:= ''; + end + else begin + result:= '<'+inttostrmse(length(mstr1))+'>'; + end; +end; + +procedure tindexlookupeditor.edit(); +var + mstr1: msestring; + imagelist: timagelist; + facelist: tfacelist; +begin + mstr1:= getmsestringvalue(0,true); + imagelist:= nil; + facelist:= nil; + if fcomponent is timagelist then begin + pointer(imagelist):= fcomponent; + end; + if fcomponent is tfacelist then begin + pointer(facelist):= fcomponent; + end; + if editlookupindex(mstr1,imagelist,facelist) then begin + setmsestringvalue(mstr1,true); + end; +end; + +{ tcornermaskeditor } + +procedure tcornermaskeditor.setvalue(const value: msestring); +begin + if (value = '') and + askyesno('Do you want to delete the corner mask?') then begin + inherited setvalue(''); + end + else begin + inherited setvalue(getmsestringvalue(0)); + end; +end; + +function tcornermaskeditor.getvalue: msestring; +var + mstr1: msestring; +begin + mstr1:= getmsestringvalue(0,true); + if mstr1 = '' then begin + result:= ''; + end + else begin + result:= '<'+inttostrmse(length(mstr1))+'>'; + end; +end; + +procedure tcornermaskeditor.edit(); +var + mstr1: msestring; +begin + mstr1:= getmsestringvalue(0,true); + if editcornermask(mstr1) then begin + setmsestringvalue(mstr1,true); + end; +end; + +{ tmacroseditor } + +function tmacroseditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + with tstringlistmacroitem( + tarrayelementeditor1(sender).getpointervalue) do begin + result:= '<'+name+'>'; + end; +end; + +{ timagelistversioncounteditor } + +procedure timagelistversioncounteditor.setvalue(const value: msestring); +var + int1: integer; + va: integer; +begin + va:= strtoint(value); + if va < 0 then begin + va:= 0; + end; + int1:= timagelist(fcomponent).versioncount; + if not wantpropertydelete(va,int1-1) then begin + exit; + end; + inherited; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regkernel_bmp.pas b/mseide-msegui/lib/common/regcomponents/regkernel_bmp.pas new file mode 100644 index 0000000..c19a1cd --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regkernel_bmp.pas @@ -0,0 +1,3769 @@ +unit regkernel_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_taction: record size: integer; data: array[0..467] of byte end = + (size: 468; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,97,99, + 116,105,111,110,12,98,105,116,109,97,112,46,105,109,97,103,101,10,168,1, + 0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,116,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,87,0,0, + 255,2,255,0,255,20,0,0,255,2,255,0,255,19,0,0,255,3,255,0, + 255,19,0,0,255,2,255,0,255,20,0,0,255,2,255,0,255,23,0,0, + 255,2,255,0,255,24,0,0,255,2,255,0,255,24,0,0,255,2,255,0, + 255,24,0,0,255,2,255,0,255,21,0,0,255,2,255,0,255,21,0,0, + 255,1,255,0,255,17,0,0,255,1,255,0,255,3,0,0,255,2,255,0, + 255,1,0,0,0,2,255,0,255,2,0,0,0,1,255,0,255,2,0,0, + 0,1,255,0,255,1,0,0,0,1,255,0,255,7,0,0,255,1,255,0, + 255,2,0,0,255,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0, + 0,1,255,0,255,1,0,0,0,1,255,0,255,2,0,0,0,1,255,0, + 255,1,0,0,0,1,255,0,255,6,0,0,255,1,255,0,255,1,0,0, + 255,2,255,0,255,3,0,0,0,1,255,0,255,4,0,0,0,1,255,0, + 255,2,0,0,0,1,255,0,255,1,0,0,0,1,255,0,255,6,0,0, + 255,2,255,0,255,1,0,0,255,3,255,0,255,1,0,0,0,1,255,0, + 255,1,0,0,0,2,255,0,255,1,0,0,0,1,255,0,255,2,0,0, + 0,1,255,0,255,1,0,0,0,1,255,0,255,6,0,0,255,3,255,0, + 255,4,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,1,0,0, + 0,1,255,0,255,2,0,0,0,1,255,0,255,1,0,0,0,1,255,0, + 255,14,0,0,0,2,255,0,255,3,0,0,0,2,255,0,255,2,0,0, + 0,1,255,0,255,98,0,0) + ); + +const + objdata_timagelist: record size: integer; data: array[0..1821] of byte end = + (size: 1822; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,105,109, + 97,103,101,108,105,115,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,168,6,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,32,5,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,208,208,208,4,124,123,123,1,123,123,123,19, + 208,208,208,4,125,124,123,1,251,192,146,1,255,194,147,10,255,194,146,7, + 125,124,123,1,208,208,208,2,124,124,123,1,123,123,123,19,251,195,151,1, + 125,124,123,1,208,208,208,2,125,124,124,1,251,192,146,1,255,194,147,10, + 255,194,146,7,127,125,124,1,251,199,158,1,125,124,124,1,124,123,123,1, + 123,123,123,19,251,195,151,1,127,125,124,1,251,202,164,1,125,124,124,1, + 125,124,123,1,251,192,146,1,255,194,147,10,255,194,146,7,127,125,124,1, + 251,199,158,1,127,126,125,1,251,205,170,1,125,124,124,1,125,124,123,1, + 251,195,152,1,242,199,158,1,132,216,202,1,25,235,245,1,54,230,234,1, + 168,211,187,1,255,197,153,9,255,197,152,3,127,125,124,1,251,201,164,1, + 127,126,125,1,251,208,175,1,125,124,124,1,125,124,123,1,251,199,158,1, + 136,218,203,1,29,239,250,1,121,249,254,1,100,247,254,1,5,236,252,1, + 210,208,176,1,255,201,159,11,127,125,124,1,251,205,169,1,127,126,125,1, + 251,211,181,1,125,124,124,2,251,201,164,1,30,234,245,1,117,249,254,1, + 183,255,255,2,61,242,252,1,109,224,216,1,255,204,165,11,127,125,124,1, + 251,208,175,1,127,126,125,1,82,169,60,1,121,123,121,1,125,124,124,1, + 251,205,169,1,64,231,235,1,92,246,254,1,183,255,255,2,37,238,250,1, + 145,220,206,1,255,208,171,11,127,125,124,1,251,211,181,1,124,125,123,1, + 7,187,4,1,121,124,121,1,125,124,124,1,251,208,175,1,180,219,199,1, + 3,237,252,1,54,241,252,1,34,238,250,1,16,236,249,1,240,213,182,1, + 255,211,177,11,126,125,124,1,73,172,54,1,120,124,120,1,7,184,4,1, + 121,124,121,1,125,124,124,1,251,212,181,1,255,215,183,1,220,218,193,1, + 118,226,221,1,150,224,212,1,242,216,187,1,255,215,183,7,255,214,183,5, + 123,125,122,1,7,187,4,1,120,125,120,1,7,181,4,1,121,123,121,1, + 125,124,124,1,251,215,187,1,255,218,189,15,235,211,175,1,70,173,51,1, + 120,124,120,1,7,184,4,1,120,124,120,1,8,178,4,1,121,123,121,1, + 125,124,124,1,251,219,193,1,255,222,195,2,255,221,195,12,158,194,120,1, + 16,176,11,1,3,189,0,1,120,124,120,1,7,181,4,1,120,124,120,1, + 8,174,4,1,121,123,121,1,125,124,124,1,251,222,199,1,255,225,201,12, + 207,209,162,1,58,184,45,1,3,192,2,1,2,194,0,1,3,186,0,1, + 120,124,120,1,8,178,4,1,120,124,120,1,8,172,4,1,121,123,121,1, + 125,124,124,1,251,225,205,1,255,228,208,2,255,228,207,8,250,226,203,1, + 100,186,77,1,10,194,6,1,1,207,1,1,2,199,0,1,3,191,0,1, + 3,183,0,1,120,124,120,1,8,174,4,1,120,124,120,1,9,170,4,1, + 121,123,121,1,125,124,124,1,251,229,211,1,255,232,214,6,255,232,213,3, + 252,231,210,1,84,180,55,1,0,218,1,1,1,212,1,1,2,204,1,1, + 2,196,0,1,3,188,0,1,4,180,0,1,120,124,120,1,8,171,4,1, + 120,124,120,1,9,170,4,1,121,123,121,1,125,122,122,1,250,131,72,1, + 254,137,81,1,254,143,93,1,254,150,104,1,254,156,115,1,253,159,122,1, + 250,148,104,1,248,137,86,1,245,126,68,1,243,116,50,1,237,103,33,1, + 68,150,11,1,1,217,1,1,1,209,1,1,2,201,1,1,3,193,0,1, + 3,185,0,1,4,176,0,1,120,124,120,1,9,169,4,1,120,124,120,1, + 9,170,4,1,121,123,121,1,125,122,122,1,251,152,76,1,255,161,87,1, + 255,168,101,1,255,176,114,1,255,183,128,1,255,191,142,1,252,179,122,1, + 249,166,101,1,246,153,79,1,243,140,58,1,240,127,36,1,212,113,15,1, + 40,166,5,1,1,206,1,1,2,197,0,1,3,189,0,1,4,181,0,1, + 4,173,0,1,120,124,120,1,9,169,4,1,120,124,120,1,9,170,4,1, + 121,123,121,1,125,122,122,1,251,151,73,1,255,159,84,1,255,167,98,1, + 255,174,111,1,255,182,125,1,255,189,139,1,252,182,127,1,249,169,106,1, + 246,156,84,1,243,143,63,1,240,130,41,1,237,117,20,1,171,114,1,1, + 19,179,2,1,2,194,0,1,3,186,0,1,4,178,0,1,5,171,0,1, + 120,124,120,1,9,169,4,1,121,124,121,1,123,123,123,2,125,122,122,1, + 251,149,70,1,255,158,81,1,255,165,95,1,255,173,109,1,255,180,122,1, + 255,188,136,1,253,185,132,1,250,172,110,1,247,159,89,1,244,146,67,1, + 241,133,46,1,238,120,24,1,235,107,3,1,140,121,1,1,20,170,1,1, + 3,183,0,1,4,175,0,1,5,171,0,1,120,124,120,1,9,169,4,1, + 121,124,121,1,128,128,128,1,208,208,208,1,125,122,122,1,251,147,67,1, + 255,156,78,1,255,163,92,1,255,171,106,1,255,178,119,1,255,186,133,1, + 254,188,137,1,251,175,115,1,248,162,94,1,245,149,72,1,242,136,51,1, + 239,123,29,1,236,109,8,1,235,105,0,1,165,114,1,1,27,153,6,1, + 4,172,0,1,5,171,0,1,121,123,121,1,123,123,123,2,128,128,128,1, + 208,208,208,1,125,122,122,1,251,146,64,1,255,154,75,1,255,162,89,1, + 255,169,103,1,255,177,116,1,255,184,130,1,254,191,141,1,251,178,120,1, + 248,165,98,1,245,152,77,1,242,138,55,1,239,125,34,1,236,112,12,1, + 235,105,0,2,192,109,0,1,35,139,2,1,5,171,0,1,121,123,121,1, + 123,123,123,1,208,208,208,3,125,122,122,1,123,123,123,20,208,208,208,3, + 80,1,0,0,0,0,0,4,250,250,250,1,255,255,255,19,0,0,0,4, + 251,251,251,1,255,255,255,18,252,252,252,1,0,0,0,2,250,250,250,1, + 255,255,255,20,252,252,252,1,0,0,0,2,251,251,251,1,255,255,255,20, + 252,252,252,1,250,250,250,1,255,255,255,22,252,252,252,1,251,251,251,1, + 255,255,255,22,252,252,252,1,251,251,251,1,255,255,255,22,252,252,252,1, + 251,251,251,1,255,255,255,22,252,252,252,1,251,251,251,1,255,255,255,21, + 225,225,225,1,253,253,253,1,251,251,251,1,255,255,255,22,253,253,253,1, + 251,251,251,1,255,255,255,19,254,254,254,1,255,255,255,2,253,253,253,1, + 251,251,251,1,255,255,255,22,253,253,253,1,251,251,251,1,255,255,255,22, + 253,253,253,1,251,251,251,1,255,255,255,22,253,253,253,1,251,251,251,1, + 255,255,255,22,253,253,253,1,251,251,251,1,255,255,255,22,253,253,253,1, + 252,252,252,1,255,255,255,22,253,253,253,2,255,255,255,22,253,253,253,1, + 252,252,252,1,255,255,255,22,253,253,253,1,252,252,252,1,255,255,255,23, + 252,252,252,1,255,255,255,20,253,253,253,1,8,8,8,1,0,0,0,1, + 252,252,252,1,255,255,255,21,8,8,8,1,0,0,0,1,252,252,252,1, + 255,255,255,16,240,240,240,1,255,255,255,1,253,253,253,1,8,8,8,1, + 0,0,0,3,251,251,251,1,255,255,255,19,8,8,8,1,0,0,0,3, + 0,0) + ); + +const + objdata_tstatfile: record size: integer; data: array[0..2860] of byte end = + (size: 2861; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,116, + 97,116,102,105,108,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,184,10,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,232,8,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,3,4,3,1,5,7,5,1,17,22,17,1,177, + 229,178,1,180,230,180,1,113,143,113,1,6,7,6,2,49,61,50,1,192, + 234,194,1,195,234,196,1,71,85,72,1,6,7,6,2,98,114,99,1,207, + 238,209,1,209,239,212,1,33,37,33,1,7,7,7,2,184,203,188,1,222, + 242,225,1,212,230,216,1,3,4,4,1,113,151,113,1,172,228,173,1,175, + 229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187, + 232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199, + 236,201,1,202,236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212, + 239,215,1,214,240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224, + 243,228,1,7,7,7,1,171,228,171,1,172,228,173,1,175,229,175,1,177, + 229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190, + 233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202, + 236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214, + 240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,26, + 28,27,1,171,228,171,1,172,228,173,1,175,229,175,1,177,229,178,1,180, + 230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192, + 234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204, + 237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217, + 241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,226,243,230,1,14, + 18,14,1,172,228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182, + 231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195, + 234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204,237,207,1,207, + 238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219, + 241,223,1,222,242,225,1,224,243,228,1,226,243,230,1,5,7,5,1,172, + 228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185, + 232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,197, + 235,199,1,199,236,201,1,202,236,204,1,204,237,207,1,207,238,209,1,209, + 239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219,241,223,1,222, + 242,225,1,224,243,228,1,123,133,126,1,11,14,11,1,172,228,173,1,175, + 229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187, + 232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199, + 236,201,1,202,236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212, + 239,215,1,214,240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224, + 243,228,1,7,7,7,1,171,228,171,1,172,228,173,1,175,229,175,1,177, + 229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190, + 233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202, + 236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214, + 240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,7, + 7,7,1,171,228,171,1,172,228,173,1,77,101,77,1,17,22,17,1,79, + 101,79,1,182,231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192, + 234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,92, + 107,93,1,207,238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217, + 241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,70,75,71,1,120, + 160,120,1,172,228,173,1,113,147,113,1,9,12,9,1,113,144,113,1,182, + 231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195, + 234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,0,0,0,1,207, + 238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219, + 241,223,1,222,242,225,1,224,243,228,1,226,243,230,1,5,7,5,1,172, + 228,173,1,95,125,95,1,146,189,147,1,96,123,96,1,182,231,183,1,185, + 232,186,1,187,232,188,1,190,233,191,1,131,160,132,1,3,4,3,1,9, + 11,9,1,77,92,78,1,0,0,0,3,209,239,212,1,148,167,150,1,23, + 25,23,1,9,10,9,1,117,129,119,1,222,242,225,1,224,243,228,1,226, + 243,230,1,5,7,5,1,172,228,173,1,175,229,175,1,177,229,178,1,180, + 230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,29, + 36,30,1,59,71,59,1,186,222,188,1,199,236,201,1,202,236,204,1,0, + 0,0,1,207,238,209,1,209,239,212,1,206,232,209,1,187,210,190,1,187, + 208,190,1,12,13,12,1,222,242,225,1,224,243,228,1,70,75,71,1,37, + 49,37,1,172,228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182, + 231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,164,200,166,1,29, + 35,29,1,8,9,8,1,152,180,154,1,202,236,204,1,0,0,0,1,207, + 238,209,1,209,239,212,1,147,166,149,1,64,72,65,1,26,29,27,1,0, + 0,0,1,222,242,225,1,224,243,228,1,7,7,7,1,171,228,171,1,172, + 228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185, + 232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,53, + 64,54,1,15,18,15,1,202,236,204,1,0,0,0,1,196,225,198,1,209, + 239,212,1,11,12,11,1,148,166,150,1,151,167,153,1,0,0,0,1,222, + 242,225,1,224,243,228,1,7,7,7,1,171,228,171,1,172,228,173,1,175, + 229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,0, + 0,0,1,190,233,191,1,79,96,80,1,9,11,9,1,4,5,4,1,136, + 161,137,1,202,236,204,1,45,52,45,1,6,7,6,1,209,239,212,1,78, + 88,79,1,7,8,7,1,95,106,97,1,0,0,0,1,222,242,225,1,224, + 243,228,1,123,133,126,1,71,95,71,1,172,228,173,1,175,229,175,1,177, + 229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190, + 233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202, + 236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214, + 240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,226, + 243,230,1,5,7,5,1,172,228,173,1,175,229,175,1,177,229,178,1,180, + 230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192, + 234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204, + 237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217, + 241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,226,243,230,1,5, + 7,5,1,172,228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182, + 231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195, + 234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204,237,207,1,207, + 238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219, + 241,223,1,222,242,225,1,224,243,228,1,26,28,27,1,77,103,77,1,172, + 228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185, + 232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,197, + 235,199,1,199,236,201,1,202,236,204,1,204,237,207,1,207,238,209,1,209, + 239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219,241,223,1,222, + 242,225,1,224,243,228,1,7,7,7,1,171,228,171,1,172,228,173,1,175, + 229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187, + 232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199, + 236,201,1,202,236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212, + 239,215,1,214,240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224, + 243,228,1,7,7,7,1,171,228,171,1,172,228,173,1,175,229,175,1,177, + 229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190, + 233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202, + 236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214, + 240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,214, + 230,218,1,33,44,33,1,172,228,173,1,175,229,175,1,177,229,178,1,180, + 230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192, + 234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204, + 237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217, + 241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,226,243,230,1,5, + 7,5,1,172,228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182, + 231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195, + 234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204,237,207,1,207, + 238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219, + 241,223,1,222,242,225,1,224,243,228,1,190,205,194,1,3,4,3,1,129, + 170,129,1,175,229,175,1,177,229,178,1,9,11,9,1,6,7,6,1,18, + 23,18,1,187,232,188,1,190,233,191,1,119,145,120,1,6,7,6,2,52, + 61,52,1,202,236,204,1,204,237,207,1,75,86,75,1,6,7,6,1,6, + 7,7,1,103,115,104,1,217,241,220,1,219,241,223,1,34,37,35,1,7, + 7,7,1,3,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233, + 233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128, + 128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221, + 221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244, + 244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236, + 236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165, + 165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150, + 150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255, + 255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131, + 131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255, + 255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244, + 244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248, + 248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173, + 173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0, + 0) + ); + +const + objdata_tstringcontainer: record size: integer; data: array[0..2875] of byte end = + (size: 2876; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,115,116, + 114,105,110,103,99,111,110,116,97,105,110,101,114,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,192,10, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,240,8, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,1,5,7, + 5,1,18,22,18,1,177,229,177,1,179,231,181,1,113,144,113,1,5,7, + 5,1,6,7,6,1,49,60,50,1,193,233,193,1,195,235,197,1,71,84, + 72,1,6,7,6,2,99,113,99,1,207,237,209,1,209,239,213,1,32,37, + 33,1,6,7,6,2,185,204,187,1,221,243,225,1,212,232,216,1,3,4, + 3,1,113,151,113,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231, + 181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234, + 194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238, + 207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241, + 220,1,220,242,223,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227, + 171,1,173,229,173,1,175,229,176,1,175,225,175,1,134,172,135,1,119,150, + 120,1,157,197,158,1,188,233,189,1,190,233,191,1,193,234,194,1,194,234, + 196,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238, + 210,1,210,239,213,1,212,240,215,1,169,188,171,1,217,241,220,1,220,242, + 223,1,222,243,226,1,224,243,228,1,27,28,27,1,171,227,171,1,173,229, + 173,1,173,226,174,1,43,56,43,1,60,77,60,1,88,111,89,1,33,41, + 33,1,105,131,106,1,190,233,191,1,145,176,146,1,104,125,105,1,197,236, + 199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,209,238, + 212,1,106,120,108,1,47,53,48,1,217,241,220,1,220,242,223,1,222,243, + 226,1,224,243,228,1,227,243,231,1,14,18,14,1,173,229,173,1,140,183, + 141,1,39,51,39,1,180,231,181,1,183,231,184,1,166,208,167,1,50,62, + 50,1,189,232,190,1,87,106,87,1,70,84,70,1,175,209,176,1,158,187, + 160,1,175,205,178,1,150,174,151,1,205,235,208,1,64,73,65,1,70,79, + 71,1,47,53,48,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243, + 228,1,227,243,231,1,5,7,5,1,173,229,173,1,169,221,170,1,29,37, + 29,1,71,91,71,1,135,170,136,1,181,227,182,1,188,233,189,1,189,231, + 190,1,68,83,68,1,54,65,55,1,161,193,163,1,52,61,52,1,52,61, + 53,1,84,97,84,1,205,235,208,1,179,203,181,1,192,217,195,1,47,53, + 48,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,124,133, + 127,1,11,14,11,1,173,229,173,1,175,229,176,1,166,215,166,1,102,131, + 103,1,47,59,47,1,13,16,13,1,105,131,106,1,190,233,191,1,122,148, + 122,1,96,116,97,1,197,236,199,1,52,61,52,1,148,174,150,1,205,238, + 207,1,207,238,210,1,210,239,213,1,192,217,195,1,47,53,48,1,217,241, + 220,1,220,242,223,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227, + 171,1,173,229,173,1,145,189,146,1,147,190,147,1,180,231,181,1,183,231, + 184,1,168,210,168,1,24,29,24,1,168,206,169,1,122,148,122,1,96,116, + 97,1,197,236,199,1,52,61,52,1,168,197,170,1,205,238,207,1,207,238, + 210,1,210,239,213,1,192,217,195,1,47,53,48,1,217,241,220,1,220,242, + 223,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229, + 173,1,124,163,125,1,43,56,43,1,173,222,174,1,183,231,184,1,176,221, + 177,1,30,37,30,1,174,214,175,1,124,150,125,1,93,112,94,1,197,236, + 199,1,52,61,52,1,169,198,171,1,205,238,207,1,207,238,210,1,210,239, + 213,1,192,217,195,1,47,53,48,1,217,241,220,1,220,242,223,1,222,243, + 226,1,224,243,228,1,71,75,72,1,121,160,121,1,173,229,173,1,174,228, + 175,1,88,114,88,1,23,29,23,1,38,48,38,1,25,32,26,1,116,143, + 116,1,190,233,191,1,157,190,157,1,21,25,21,1,124,148,125,1,52,61, + 52,1,169,198,171,1,205,238,207,1,207,238,210,1,210,239,213,1,192,217, + 195,1,47,53,48,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243, + 228,1,227,243,231,1,5,7,5,1,173,229,173,1,175,229,176,1,178,230, + 178,1,180,231,181,1,169,213,170,1,185,232,186,1,188,233,189,1,190,233, + 191,1,193,234,194,1,192,231,194,1,195,233,197,1,200,236,202,1,202,237, + 205,1,205,238,207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240, + 218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,227,243, + 231,1,5,7,5,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231, + 181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234, + 194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238, + 207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241, + 220,1,220,242,223,1,222,243,226,1,224,243,228,1,71,75,72,1,36,49, + 36,1,173,229,173,1,175,229,176,1,178,230,178,1,175,225,176,1,165,208, + 166,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234,194,1,195,235, + 197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238, + 210,1,210,239,213,1,210,238,213,1,215,240,218,1,217,241,220,1,220,242, + 223,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229, + 173,1,175,229,176,1,84,108,84,1,20,25,20,1,42,53,43,1,24,30, + 24,1,140,174,141,1,190,233,191,1,163,197,164,1,127,153,128,1,197,236, + 199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,89,101, + 90,1,55,62,56,1,54,60,55,1,147,164,149,1,220,242,223,1,222,243, + 226,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229,173,1,146,191, + 147,1,31,40,31,1,179,230,180,1,183,231,184,1,148,186,149,1,27,33, + 27,1,190,233,191,1,118,143,119,1,93,112,94,1,195,233,197,1,196,231, + 198,1,200,235,203,1,196,228,198,1,150,173,152,1,77,87,78,1,212,240, + 215,1,202,226,205,1,36,40,36,1,217,239,220,1,222,243,226,1,224,243, + 228,1,124,133,127,1,72,95,72,1,173,229,173,1,160,209,161,1,18,23, + 18,1,116,149,116,1,175,221,176,1,185,232,186,1,177,219,178,1,187,229, + 188,1,38,46,38,1,30,36,30,1,141,169,143,1,52,61,52,1,53,62, + 54,1,37,43,37,1,193,222,196,1,198,225,200,1,212,240,215,1,202,226, + 205,1,15,17,16,1,216,237,219,1,222,243,226,1,224,243,228,1,227,243, + 231,1,5,7,5,1,173,229,173,1,175,229,176,1,140,181,140,1,57,73, + 57,1,12,15,12,1,49,62,50,1,147,182,147,1,190,233,191,1,122,148, + 122,1,96,116,97,1,197,236,199,1,52,61,52,1,133,156,135,1,205,238, + 207,1,207,238,210,1,210,239,213,1,206,233,209,1,67,74,68,1,116,129, + 117,1,220,242,223,1,222,243,226,1,224,243,228,1,227,243,231,1,5,7, + 5,1,173,229,173,1,165,216,166,1,168,217,168,1,180,231,181,1,178,225, + 179,1,127,159,128,1,17,21,17,1,179,219,180,1,122,148,122,1,96,116, + 97,1,197,236,199,1,52,61,52,1,166,194,168,1,205,238,207,1,207,238, + 210,1,201,229,204,1,57,64,57,1,107,120,109,1,217,241,220,1,220,242, + 223,1,222,243,226,1,224,243,228,1,27,28,27,1,77,103,77,1,173,229, + 173,1,112,146,113,1,67,87,67,1,180,231,181,1,183,231,184,1,185,232, + 186,1,41,50,41,1,163,200,164,1,123,149,123,1,96,115,97,1,197,236, + 199,1,52,61,52,1,169,198,171,1,205,238,207,1,200,230,203,1,49,56, + 50,1,125,141,126,1,215,240,218,1,217,241,220,1,220,242,223,1,222,243, + 226,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229,173,1,166,217, + 167,1,46,60,46,1,50,64,50,1,84,106,84,1,51,64,51,1,72,89, + 72,1,190,233,191,1,141,171,142,1,36,43,36,1,149,179,151,1,52,61, + 52,1,169,198,171,1,205,238,207,1,106,122,108,1,24,27,24,1,86,97, + 87,1,87,97,88,1,88,97,89,1,204,225,207,1,222,243,226,1,224,243, + 228,1,7,7,7,1,171,227,171,1,173,229,173,1,175,229,176,1,176,227, + 176,1,145,187,146,1,123,155,123,1,151,189,152,1,188,233,189,1,190,233, + 191,1,193,234,194,1,150,181,151,1,169,203,171,1,163,193,165,1,194,228, + 197,1,205,238,207,1,173,199,175,1,157,179,160,1,159,180,161,1,161,180, + 163,1,163,181,165,1,214,235,217,1,222,243,226,1,224,243,228,1,216,232, + 220,1,33,44,33,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231, + 181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234, + 194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238, + 207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241, + 220,1,220,242,223,1,222,243,226,1,224,243,228,1,227,243,231,1,5,7, + 5,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231,181,1,183,231, + 184,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234,194,1,195,235, + 197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238, + 210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220,1,220,242, + 223,1,222,243,226,1,224,243,228,1,191,204,194,1,3,3,3,1,129,171, + 129,1,175,229,175,1,177,229,177,1,8,10,8,1,5,7,5,1,18,22, + 18,1,187,233,189,1,189,233,191,1,119,144,119,1,6,7,6,2,52,62, + 53,1,201,237,205,1,205,237,207,1,75,85,76,1,6,7,6,2,103,115, + 105,1,217,241,219,1,219,241,223,1,35,38,35,1,7,7,7,1,3,4, + 3,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1,128,128, + 128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188, + 188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248, + 248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1,154,154, + 154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,229,229, + 229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1,240,240, + 240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,229,229, + 229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1,214,214, + 214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,139,139, + 139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1,248,248, + 248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203, + 203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128, + 128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tkeystringcontainer: record size: integer; data: array[0..2878] of byte end = + (size: 2879; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,107,101, + 121,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,192,10,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,240,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3, + 1,5,7,5,1,18,22,18,1,177,229,177,1,179,231,181,1,113,144,113, + 1,5,7,5,1,6,7,6,1,49,60,50,1,193,233,193,1,195,235,197, + 1,71,84,72,1,6,7,6,2,99,113,99,1,207,237,209,1,209,239,213, + 1,32,37,33,1,6,7,6,2,185,204,187,1,221,243,225,1,212,232,216, + 1,3,4,3,1,113,151,113,1,173,229,173,1,175,229,176,1,178,230,178, + 1,180,231,181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191, + 1,193,234,194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205, + 1,205,238,207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218, + 1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,7,7,7, + 1,171,227,171,1,173,229,173,1,132,172,133,1,178,230,178,1,180,231,181, + 1,183,231,184,1,137,172,138,1,177,219,178,1,190,233,191,1,193,234,194, + 1,195,235,197,1,197,236,199,1,200,236,202,1,201,236,204,1,205,238,207, + 1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220, + 1,178,195,180,1,222,243,226,1,224,243,228,1,27,28,27,1,171,227,171, + 1,173,229,173,1,21,28,21,1,178,230,178,1,180,231,181,1,90,114,91, + 1,70,87,70,1,187,232,188,1,190,233,191,1,193,234,194,1,195,235,197, + 1,197,236,199,1,173,205,175,1,100,117,101,1,205,238,207,1,207,238,210, + 1,210,239,213,1,212,240,215,1,215,240,218,1,171,190,173,1,16,18,17, + 1,222,243,226,1,224,243,228,1,227,243,231,1,14,18,14,1,173,229,173, + 1,21,28,21,1,178,230,178,1,109,140,109,1,55,70,56,1,182,228,183, + 1,188,233,189,1,173,212,174,1,128,155,129,1,157,189,158,1,197,236,199, + 1,124,146,125,1,63,73,64,1,183,213,185,1,166,190,168,1,166,188,168, + 1,180,204,183,1,159,178,162,1,47,52,47,1,33,36,33,1,222,243,226, + 1,224,243,228,1,227,243,231,1,5,7,5,1,173,229,173,1,21,28,21, + 1,126,162,126,1,32,41,32,1,177,223,178,1,185,232,186,1,187,231,188, + 1,39,48,39,1,111,135,112,1,49,59,49,1,141,169,143,1,106,125,107, + 1,49,58,50,1,171,199,173,1,42,49,43,1,65,74,66,1,134,152,136, + 1,192,215,195,1,213,236,216,1,47,52,48,1,222,243,226,1,224,243,228, + 1,124,133,127,1,11,14,11,1,173,229,173,1,18,23,18,1,43,55,43, + 1,34,43,34,1,150,189,151,1,185,232,186,1,184,228,185,1,29,36,29, + 1,137,166,138,1,179,216,181,1,185,221,187,1,158,186,159,1,87,102,88, + 1,205,238,207,1,31,35,31,1,199,227,202,1,212,240,215,1,215,240,218, + 1,217,241,220,1,47,52,48,1,222,243,226,1,224,243,228,1,7,7,7, + 1,171,227,171,1,173,229,173,1,19,25,19,1,163,210,163,1,139,178,140, + 1,37,46,37,1,182,228,183,1,188,233,189,1,147,180,148,1,64,77,64, + 1,21,26,22,1,142,170,144,1,158,186,159,1,87,102,88,1,205,238,207, + 1,44,50,44,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220, + 1,47,52,48,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227,171, + 1,173,229,173,1,21,28,21,1,178,230,178,1,180,231,181,1,74,93,74, + 1,96,121,97,1,178,221,179,1,98,120,98,1,193,234,194,1,145,175,147, + 1,76,91,76,1,160,189,162,1,86,100,87,1,205,238,207,1,45,51,45, + 1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220,1,47,52,48, + 1,222,243,226,1,224,243,228,1,71,75,72,1,121,160,121,1,173,229,173, + 1,21,28,21,1,178,230,178,1,180,231,181,1,172,217,172,1,22,28,23, + 1,157,195,158,1,81,100,82,1,56,68,56,1,38,46,39,1,153,183,155, + 1,184,217,186,1,26,31,27,1,134,156,136,1,45,51,45,1,210,239,213, + 1,212,240,215,1,215,240,218,1,217,241,220,1,47,52,48,1,222,243,226, + 1,224,243,228,1,227,243,231,1,5,7,5,1,173,229,173,1,175,229,176, + 1,178,230,178,1,180,231,181,1,183,231,184,1,185,232,186,1,188,233,189, + 1,190,233,191,1,185,224,186,1,193,232,195,1,197,236,199,1,200,236,202, + 1,200,234,203,1,203,235,205,1,207,238,210,1,210,239,213,1,212,240,215, + 1,215,240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228, + 1,227,243,231,1,5,7,5,1,173,229,173,1,175,229,176,1,178,230,178, + 1,180,231,181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191, + 1,193,234,194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205, + 1,205,238,207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218, + 1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,71,75,72, + 1,36,49,36,1,173,229,173,1,170,223,171,1,178,230,178,1,180,231,181, + 1,183,231,184,1,181,227,182,1,187,231,188,1,190,233,191,1,193,234,194, + 1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207, + 1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220, + 1,218,240,221,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227,171, + 1,173,229,173,1,21,28,21,1,178,230,178,1,180,231,181,1,128,162,129, + 1,39,49,39,1,178,221,179,1,190,233,191,1,193,234,194,1,195,235,197, + 1,197,236,199,1,184,217,186,1,128,150,129,1,205,238,207,1,207,238,210, + 1,210,239,213,1,212,240,215,1,161,180,163,1,57,63,58,1,56,62,57, + 1,137,150,139,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229,173, + 1,21,28,21,1,178,230,178,1,142,182,143,1,34,43,34,1,169,212,170, + 1,188,233,189,1,190,233,191,1,176,214,177,1,193,232,195,1,197,236,199, + 1,154,181,155,1,85,99,86,1,203,235,205,1,203,233,206,1,203,231,205, + 1,210,238,213,1,57,64,58,1,203,225,205,1,219,241,222,1,51,56,52, + 1,217,235,221,1,124,133,127,1,72,95,72,1,173,229,173,1,21,28,21, + 1,153,198,153,1,32,42,33,1,160,202,161,1,185,232,186,1,188,233,189, + 1,58,71,58,1,63,76,63,1,35,42,36,1,162,194,164,1,76,90,77, + 1,27,32,27,1,151,175,153,1,50,57,50,1,43,49,43,1,104,118,105, + 1,196,218,198,1,217,241,220,1,220,242,223,1,34,37,35,1,213,231,216, + 1,227,243,231,1,5,7,5,1,173,229,173,1,19,25,19,1,38,49,38, + 1,28,36,28,1,169,213,170,1,185,232,186,1,181,225,182,1,34,41,34, + 1,180,218,181,1,161,194,162,1,163,195,165,1,158,186,159,1,87,102,88, + 1,205,238,207,1,30,35,30,1,185,211,188,1,212,240,215,1,215,240,218, + 1,217,241,220,1,114,125,115,1,95,104,97,1,224,243,228,1,227,243,231, + 1,5,7,5,1,173,229,173,1,18,23,18,1,140,180,140,1,112,143,112, + 1,63,80,63,1,185,232,186,1,188,233,189,1,106,130,106,1,23,28,24, + 1,60,73,61,1,169,203,171,1,158,186,159,1,87,102,88,1,205,238,207, + 1,41,48,42,1,210,239,213,1,212,240,215,1,215,240,218,1,126,140,128, + 1,66,73,67,1,219,239,222,1,224,243,228,1,27,28,27,1,77,103,77, + 1,173,229,173,1,21,28,21,1,178,230,178,1,180,231,181,1,46,58,46, + 1,127,159,128,1,179,222,180,1,136,167,137,1,191,231,192,1,117,141,118, + 1,76,91,76,1,158,187,160,1,86,101,88,1,205,238,207,1,45,51,45, + 1,210,239,213,1,212,240,215,1,141,157,143,1,67,75,68,1,214,235,217, + 1,222,243,226,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229,173, + 1,21,28,21,1,178,230,178,1,180,231,181,1,155,196,156,1,22,28,23, + 1,175,217,176,1,46,57,46,1,100,121,100,1,60,73,61,1,125,150,126, + 1,176,207,177,1,33,39,34,1,159,185,161,1,45,51,45,1,210,239,213, + 1,207,234,210,1,18,20,18,1,79,88,80,1,89,98,90,1,90,98,91, + 1,205,222,208,1,7,7,7,1,171,227,171,1,173,229,173,1,137,179,137, + 1,178,230,178,1,180,231,181,1,183,231,184,1,152,190,152,1,170,211,171, + 1,186,228,187,1,141,171,142,1,156,188,158,1,197,236,199,1,200,236,202, + 1,162,190,164,1,178,206,179,1,166,191,169,1,210,239,213,1,206,233,209, + 1,161,180,163,1,163,181,165,1,165,181,167,1,166,182,169,1,216,234,220, + 1,216,232,220,1,33,44,33,1,173,229,173,1,175,229,176,1,178,230,178, + 1,180,231,181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191, + 1,193,234,194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205, + 1,205,238,207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218, + 1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,227,243,231, + 1,5,7,5,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231,181, + 1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234,194, + 1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207, + 1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220, + 1,220,242,223,1,222,243,226,1,224,243,228,1,191,204,194,1,3,3,3, + 1,129,171,129,1,175,229,175,1,177,229,177,1,8,10,8,1,5,7,5, + 1,18,22,18,1,187,233,189,1,189,233,191,1,119,144,119,1,6,7,6, + 2,52,62,53,1,201,237,205,1,205,237,207,1,75,85,76,1,6,7,6, + 2,103,115,105,1,217,241,219,1,219,241,223,1,35,38,35,1,7,7,7, + 1,3,4,3,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233, + 1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128, + 2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221, + 1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244, + 1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165, + 1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131, + 1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244, + 1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248, + 2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173, + 1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_trttistat: record size: integer; data: array[0..2716] of byte end = + (size: 2717; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,114,116, + 116,105,115,116,97,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,40,10,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,92,8,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,3,3,3,1,15,20,15,1,178, + 230,178,1,180,231,181,1,114,144,115,1,3,3,3,2,49,60,49,1,193, + 234,194,1,195,235,197,1,71,85,72,1,3,4,3,2,99,115,100,1,207, + 238,210,1,210,239,212,1,35,40,36,1,3,4,3,2,175,192,177,1,222, + 243,226,1,213,231,217,1,0,0,0,1,121,161,121,1,173,229,173,1,175, + 229,176,1,178,230,178,1,180,231,181,1,183,231,184,1,185,232,186,1,188, + 233,189,1,190,233,191,1,193,234,194,1,195,235,197,1,197,236,199,1,200, + 236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212, + 240,215,1,215,240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224, + 243,228,1,3,4,3,1,171,228,171,1,173,229,173,1,175,229,176,1,178, + 230,178,1,180,231,181,1,183,231,184,1,185,232,186,1,187,233,189,1,190, + 233,191,1,193,234,194,1,195,235,197,1,197,236,199,1,200,236,202,1,202, + 237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215, + 240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,28, + 31,29,1,171,228,171,1,173,229,173,1,175,229,176,1,178,230,178,1,177, + 231,182,1,129,236,219,1,93,239,243,1,62,238,253,1,62,238,243,1,107, + 236,223,1,192,235,198,1,197,236,199,1,200,236,202,1,202,237,205,1,205, + 238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215,240,218,1,217, + 241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,227,244,231,1,9, + 11,9,1,173,229,173,1,175,229,176,1,176,231,180,1,122,239,239,1,124, + 241,255,1,123,241,255,1,104,241,255,1,73,240,255,1,34,239,255,1,57, + 237,241,1,194,236,200,1,200,236,202,1,202,237,205,1,205,238,207,1,207, + 238,210,1,210,239,212,1,212,240,215,1,215,240,218,1,217,241,220,1,220, + 242,223,1,222,243,226,1,224,243,228,1,227,244,231,1,3,3,3,1,173, + 229,173,1,175,229,176,1,141,236,217,1,146,242,255,1,173,243,255,1,172, + 243,255,1,145,242,255,1,104,241,255,1,59,239,255,1,13,238,255,1,110, + 237,226,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,210, + 239,212,1,212,240,215,1,215,240,218,1,217,241,220,1,220,242,223,1,222, + 243,226,1,224,243,228,1,125,135,128,1,9,11,9,1,173,229,173,1,175, + 229,176,1,133,239,242,1,173,243,255,1,208,245,255,2,171,243,255,1,122, + 241,255,1,72,240,255,1,22,238,255,1,49,237,244,1,200,236,202,1,202, + 237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215, + 240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,3, + 4,3,1,171,228,171,1,173,229,173,1,174,229,176,1,125,241,253,1,173, + 243,255,1,208,245,255,2,171,243,255,1,122,241,255,1,72,240,255,1,22, + 238,255,1,21,238,252,1,200,236,202,1,202,237,205,1,205,238,207,1,207, + 238,210,1,210,239,212,1,212,240,215,1,215,240,218,1,217,241,220,1,220, + 242,223,1,222,243,226,1,224,243,228,1,3,4,3,1,171,228,171,1,173, + 229,173,1,170,222,170,1,53,108,109,1,139,233,245,1,169,238,250,1,171, + 243,255,1,144,242,255,1,104,241,255,1,58,239,255,1,13,238,255,1,49, + 237,244,1,200,236,202,1,202,237,205,1,178,207,180,1,132,152,180,1,114, + 129,232,1,212,240,215,1,215,240,218,1,217,241,220,1,220,242,223,1,222, + 243,226,1,224,243,228,1,70,75,71,1,121,161,121,1,173,229,173,1,79, + 103,79,1,19,35,32,1,33,77,81,1,102,200,212,1,122,241,255,1,104, + 241,255,1,72,240,255,1,33,239,255,1,13,238,255,1,110,237,226,1,200, + 236,202,1,202,237,205,1,97,112,100,1,25,29,160,1,9,10,253,1,189, + 214,219,1,215,240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224, + 243,228,1,227,244,231,1,3,3,3,1,173,229,173,1,135,176,135,1,75, + 100,78,1,33,91,91,1,73,240,255,1,72,240,255,1,58,239,255,1,33, + 239,255,1,8,151,162,1,13,53,54,1,46,56,47,1,127,150,128,1,177, + 208,180,1,17,20,34,1,0,0,51,1,0,0,210,1,53,59,179,1,56, + 62,56,1,43,48,44,1,72,80,73,1,210,230,214,1,224,243,228,1,227, + 244,231,1,3,3,3,1,173,229,173,1,173,226,174,1,175,225,175,1,170, + 223,176,1,104,235,219,1,54,237,242,1,21,238,252,1,47,237,242,1,13, + 29,27,1,184,226,190,1,189,226,190,1,84,99,85,1,183,215,210,1,5, + 6,121,1,0,0,165,1,0,0,255,1,0,0,83,1,141,157,204,1,215, + 239,218,1,72,79,73,1,144,157,146,1,224,243,228,1,70,75,71,1,36, + 48,36,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231,181,1,183, + 231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,86,104,86,1,25, + 30,25,1,85,102,86,1,159,188,161,1,71,84,237,1,0,0,122,1,0, + 0,165,1,0,0,255,1,0,0,220,1,18,20,133,1,75,83,78,1,32, + 35,32,1,135,148,137,1,224,243,228,1,3,4,3,1,171,228,171,1,173, + 229,173,1,175,229,176,1,207,143,111,1,208,144,113,1,210,144,115,1,211, + 145,116,1,213,145,118,1,212,144,118,1,189,128,106,1,189,188,157,1,123, + 147,124,1,14,17,20,1,0,0,228,1,0,0,122,1,0,0,165,1,0, + 0,243,1,0,0,32,1,0,0,169,1,106,117,217,1,97,106,98,1,132, + 145,135,1,224,243,228,1,3,4,3,1,171,228,171,1,173,229,173,1,175, + 229,176,1,255,0,0,3,209,0,0,1,166,0,0,1,253,0,0,1,50, + 0,0,1,146,99,82,1,148,177,153,1,4,5,35,1,0,0,236,1,0, + 0,134,1,0,0,105,1,0,0,223,1,0,0,34,1,0,0,205,1,7, + 7,185,1,22,24,26,1,124,135,126,1,224,243,228,1,125,135,128,1,72, + 96,72,1,173,229,173,1,175,229,176,1,255,0,0,3,212,0,0,1,171, + 0,0,1,255,0,0,1,224,0,0,1,119,80,67,1,47,57,102,1,0, + 0,205,1,0,0,255,1,0,0,230,1,0,0,125,1,0,0,210,1,0, + 0,200,1,0,0,116,1,0,0,146,1,58,64,198,1,157,172,160,1,224, + 243,228,1,227,244,231,1,3,3,3,1,173,229,173,1,175,229,176,1,255, + 0,0,7,218,147,123,1,188,225,202,1,187,220,206,1,189,221,208,1,191, + 221,210,1,192,220,213,1,194,220,215,1,195,220,218,1,197,220,221,1,198, + 220,223,1,200,220,226,1,222,243,226,1,224,243,228,1,227,244,231,1,3, + 3,3,1,173,229,173,1,175,229,176,1,255,0,0,7,218,147,123,1,197, + 236,199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,210, + 239,212,1,212,240,215,1,215,240,218,1,217,241,220,1,220,242,223,1,222, + 243,226,1,224,243,228,1,28,31,29,1,72,96,72,1,173,229,173,1,175, + 229,176,1,255,0,0,7,218,147,123,1,197,236,199,1,200,236,202,1,202, + 237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215, + 240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,3, + 4,3,1,171,228,171,1,173,229,173,1,175,229,176,1,255,0,0,7,218, + 147,123,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207,1,207, + 238,210,1,210,239,212,1,212,240,215,1,215,240,218,1,217,241,220,1,220, + 242,223,1,222,243,226,1,224,243,228,1,3,4,3,1,171,228,171,1,173, + 229,173,1,175,229,176,1,255,0,0,7,218,147,123,1,197,236,199,1,200, + 236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212, + 240,215,1,215,240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224, + 243,228,1,203,218,207,1,36,48,36,1,173,229,173,1,175,229,176,1,180, + 223,172,1,182,224,175,1,185,224,178,1,187,225,180,1,190,226,183,1,192, + 226,185,1,195,227,188,1,196,232,195,1,197,236,199,1,200,236,202,1,202, + 237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215, + 240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,227, + 244,231,1,3,3,3,1,173,229,173,1,175,229,176,1,178,230,178,1,180, + 231,181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,193, + 234,194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205, + 238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215,240,218,1,217, + 241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,203,218,207,1,0, + 0,0,1,137,182,137,1,175,229,176,1,178,230,178,1,3,3,3,2,16, + 20,16,1,188,233,189,1,190,233,191,1,120,146,121,1,3,3,3,1,3, + 4,3,1,51,60,52,1,202,237,205,1,205,238,207,1,75,86,76,1,3, + 4,3,2,104,116,105,1,217,241,220,1,220,242,223,1,37,40,37,1,3, + 4,3,1,0,0,0,1,148,1,0,0,255,255,255,1,252,252,252,1,237, + 237,237,1,136,136,136,2,165,165,165,1,252,252,252,2,208,208,208,1,136, + 136,136,2,194,194,194,1,252,252,252,2,179,179,179,1,136,136,136,2,223, + 223,223,1,252,252,252,2,150,150,150,1,136,136,136,1,139,139,139,1,255, + 255,255,1,157,157,157,1,255,255,255,22,252,252,252,1,136,136,136,1,255, + 255,255,22,230,230,230,1,136,136,136,1,255,255,255,22,136,136,136,1,244, + 244,244,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255,22,172, + 172,172,1,244,244,244,1,255,255,255,22,252,252,252,1,136,136,136,1,255, + 255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,201,201,201,1,157, + 157,157,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255,22,136, + 136,136,1,252,252,252,1,255,255,255,22,201,201,201,1,215,215,215,1,255, + 255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,252,252,252,1,136, + 136,136,1,255,255,255,22,172,172,172,1,186,186,186,1,255,255,255,22,136, + 136,136,1,252,252,252,1,255,255,255,22,136,136,136,1,252,252,252,1,255, + 255,255,22,230,230,230,1,186,186,186,1,255,255,255,22,252,252,252,1,136, + 136,136,1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,143, + 143,143,1,215,215,215,1,255,255,255,22,136,136,136,1,252,252,252,1,255, + 255,255,22,143,143,143,1,255,255,255,1,150,150,150,1,136,136,136,2,252, + 252,252,2,237,237,237,1,136,136,136,2,165,165,165,1,252,252,252,2,208, + 208,208,1,136,136,136,2,194,194,194,1,252,252,252,2,179,179,179,1,136, + 136,136,2,223,223,223,1,252,252,252,1,255,255,255,1,0,0) + ); + +const + objdata_tbitmapcomp: record size: integer; data: array[0..2014] of byte end = + (size: 2015; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,98,105, + 116,109,97,112,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,104,7,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,200,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0, + 4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208, + 1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,2,123,123,123, + 20,208,208,208,1,0,0,0,1,208,208,208,2,123,123,123,1,255,194,147, + 11,255,194,146,7,123,123,123,1,208,208,208,2,0,0,0,1,208,208,208, + 1,123,123,123,1,255,197,153,1,238,200,160,1,123,218,205,1,21,235,247, + 1,54,230,234,1,167,211,187,1,255,197,153,10,255,197,152,2,123,123,123, + 1,208,208,208,2,0,0,0,1,208,208,208,1,123,123,123,1,255,201,159, + 1,123,220,208,1,32,239,250,1,123,249,254,1,98,247,254,1,3,237,252, + 1,218,206,173,1,255,201,159,11,123,123,123,1,208,208,208,1,0,0,0, + 2,208,208,208,1,123,123,123,1,255,204,165,1,21,236,247,1,123,249,254, + 1,183,255,255,2,56,241,252,1,118,221,212,1,255,204,165,11,123,123,123, + 1,208,208,208,1,0,0,0,1,208,208,208,2,123,123,123,1,255,208,171, + 1,54,232,237,1,98,247,254,1,183,255,255,2,32,238,250,1,153,220,204, + 1,255,208,171,11,123,123,123,1,208,208,208,1,0,0,0,1,208,208,208, + 2,123,123,123,1,255,211,177,1,167,220,203,1,3,237,252,1,56,241,252, + 1,32,238,250,1,18,235,248,1,244,212,180,1,255,211,177,11,123,123,123, + 1,208,208,208,1,0,0,0,2,208,208,208,1,123,123,123,1,255,215,183, + 2,218,218,193,1,118,226,221,1,153,224,211,1,244,216,186,1,255,215,183, + 8,255,214,183,4,123,123,123,1,208,208,208,2,0,0,0,1,208,208,208, + 1,123,123,123,1,255,218,189,16,232,209,172,1,75,169,54,1,123,123,123, + 1,208,208,208,2,0,0,0,1,208,208,208,1,123,123,123,1,255,222,195, + 4,255,221,195,11,154,190,117,1,15,173,10,1,3,189,0,1,123,123,123, + 1,208,208,208,1,0,0,0,2,208,208,208,1,123,123,123,1,255,225,201, + 13,202,208,159,1,63,182,49,1,2,193,1,1,2,194,0,1,3,186,0, + 1,123,123,123,1,208,208,208,1,0,0,0,1,208,208,208,2,123,123,123, + 1,255,228,208,3,255,228,207,8,248,225,201,1,91,188,73,1,6,199,5, + 1,1,207,1,1,2,199,0,1,3,191,0,1,3,183,0,1,123,123,123, + 1,208,208,208,1,0,0,0,1,208,208,208,2,123,123,123,1,255,232,214, + 7,255,232,213,3,251,230,210,1,59,184,49,1,0,219,1,1,1,212,1, + 1,2,204,1,1,2,196,0,1,3,187,0,1,4,179,0,1,123,123,123, + 1,208,208,208,1,0,0,0,2,208,208,208,1,123,123,123,1,254,131,70, + 1,254,137,82,1,254,143,93,1,254,150,104,1,254,156,116,1,253,159,121, + 1,251,148,104,1,248,137,85,1,246,126,67,1,243,116,49,1,234,103,30, + 1,38,155,4,1,1,216,1,1,1,208,1,1,2,200,1,1,3,192,0, + 1,3,184,0,1,4,176,0,1,123,123,123,1,208,208,208,2,0,0,0, + 1,208,208,208,1,123,123,123,1,255,154,74,1,255,161,88,1,255,169,101, + 1,255,176,115,1,255,184,129,1,255,191,142,1,252,179,122,1,249,166,100, + 1,246,153,79,1,243,140,57,1,240,126,36,1,206,112,12,1,23,170,2, + 1,2,205,1,1,2,197,0,1,3,189,0,1,4,181,0,1,4,173,0, + 1,123,123,123,1,208,208,208,2,0,0,0,1,208,208,208,1,123,123,123, + 1,255,152,71,1,255,160,85,1,255,167,98,1,255,175,112,1,255,182,126, + 1,255,190,139,1,252,182,126,1,249,169,105,1,246,155,83,1,243,142,62, + 1,240,129,40,1,237,116,19,1,165,115,1,1,10,183,2,1,2,194,0, + 1,3,186,0,1,4,178,0,1,5,171,0,1,123,123,123,1,208,208,208, + 1,0,0,0,2,208,208,208,1,123,123,123,1,255,150,68,1,255,158,82, + 1,255,165,95,1,255,173,109,1,255,180,123,1,255,188,136,1,253,185,131, + 1,250,171,110,1,247,158,88,1,244,145,67,1,241,132,45,1,238,119,24, + 1,235,106,2,1,135,122,1,1,12,174,1,1,3,183,0,1,4,175,0, + 1,5,171,0,1,123,123,123,1,208,208,208,1,0,0,0,1,208,208,208, + 2,123,123,123,1,255,149,65,1,255,156,79,1,255,164,92,1,255,171,106, + 1,255,179,120,1,255,186,133,1,254,187,136,1,251,174,114,1,248,161,93, + 1,245,148,71,1,242,135,50,1,239,122,28,1,236,109,7,1,235,105,0, + 1,159,114,1,1,20,157,1,1,4,171,0,1,5,171,0,1,123,123,123, + 1,208,208,208,1,0,0,0,1,208,208,208,2,123,123,123,1,255,147,62, + 1,255,155,76,1,255,162,89,1,255,170,103,1,255,177,117,1,255,185,130, + 1,254,190,141,1,251,177,119,1,248,164,98,1,245,151,76,1,242,138,55, + 1,239,125,33,1,236,112,12,1,235,105,0,2,184,110,1,1,33,142,2, + 1,5,171,0,1,123,123,123,1,208,208,208,1,0,0,0,2,208,208,208, + 1,123,123,123,20,208,208,208,2,0,0,0,1,208,208,208,22,0,0,0, + 3,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,3,104,2,0,0,240,240,240, + 2,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150, + 1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0, + 2,187,187,187,1,240,240,240,2,22,22,22,1,0,0,0,1,7,7,7, + 1,240,240,240,1,52,52,52,1,0,0,0,22,240,240,240,1,0,0,0, + 2,255,255,255,20,0,0,0,1,202,202,202,1,0,0,0,2,255,255,255, + 20,0,0,0,2,217,217,217,1,0,0,0,1,255,255,255,20,0,0,0, + 2,240,240,240,1,0,0,0,1,255,255,255,20,0,0,0,1,75,75,75, + 1,225,225,225,1,0,0,0,1,255,255,255,20,0,0,0,1,240,240,240, + 1,0,0,0,2,255,255,255,20,0,0,0,1,240,240,240,1,0,0,0, + 2,255,255,255,20,0,0,0,1,135,135,135,1,45,45,45,1,0,0,0, + 1,255,255,255,20,0,0,0,2,240,240,240,1,0,0,0,1,255,255,255, + 18,223,223,223,1,255,255,255,1,0,0,0,2,240,240,240,1,0,0,0, + 1,255,255,255,16,242,242,242,1,231,231,231,1,255,255,255,2,0,0,0, + 1,135,135,135,1,165,165,165,1,0,0,0,1,255,255,255,15,228,228,228, + 1,250,250,250,1,255,255,255,3,0,0,0,1,240,240,240,1,0,0,0, + 2,255,255,255,13,247,247,247,1,246,246,246,1,255,255,255,5,0,0,0, + 1,240,240,240,1,0,0,0,2,255,255,255,12,229,229,229,1,255,255,255, + 7,0,0,0,1,75,75,75,1,105,105,105,1,0,0,0,1,255,255,255, + 11,252,252,252,1,225,225,225,1,255,255,255,7,0,0,0,2,240,240,240, + 1,0,0,0,1,255,255,255,12,252,252,252,1,238,238,238,1,255,255,255, + 6,0,0,0,2,240,240,240,1,0,0,0,1,255,255,255,13,254,254,254, + 1,249,249,249,1,255,255,255,5,0,0,0,1,202,202,202,1,97,97,97, + 1,0,0,0,1,255,255,255,14,254,254,254,1,249,249,249,1,255,255,255, + 4,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,16,244,244,244, + 1,255,255,255,3,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255, + 17,239,239,239,1,255,255,255,2,0,0,0,1,7,7,7,1,172,172,172, + 1,0,0,0,1,255,255,255,20,0,0,0,2,240,240,240,1,0,0,0, + 22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232,232,232, + 1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240, + 2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90, + 1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_ttimer: record size: integer; data: array[0..3217] of byte end = + (size: 3218; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,116,105, + 109,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13, + 98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,32,12,0,0,0,0,0,0,6,0,0,0, + 24,0,0,0,24,0,0,0,164,6,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,208,208,208,10,158,158,255,1,118,118,255,1,79,79,255,1, + 208,208,208,14,26,128,139,1,46,146,156,1,55,153,163,1,53,152,161,1, + 33,135,145,1,0,96,106,1,112,112,253,1,180,180,255,1,140,140,255,1, + 101,101,255,1,61,61,255,1,208,208,208,1,0,111,122,1,24,130,140,1, + 46,146,156,1,49,149,159,1,42,143,153,1,17,120,131,1,0,0,0,1, + 208,208,208,3,0,111,122,1,57,144,153,1,155,209,215,1,186,248,255,1, + 177,248,255,2,160,235,242,1,59,153,163,1,51,68,209,1,148,148,255,1, + 163,163,255,1,123,123,255,1,84,84,255,1,5,115,126,1,54,153,162,1, + 148,225,233,1,177,248,255,1,190,249,255,1,202,248,253,1,120,187,194,1, + 50,137,146,1,0,0,0,2,208,208,208,1,24,134,146,1,166,222,228,1, + 240,253,255,1,204,250,255,1,177,248,255,3,84,171,179,1,15,69,89,1, + 90,91,153,1,138,139,64,1,132,132,84,1,208,208,208,1,27,132,142,1, + 93,179,188,1,201,250,255,1,214,251,255,1,228,252,255,1,241,253,255,1, + 254,254,255,1,128,188,194,1,7,59,64,1,0,0,0,1,0,111,122,1, + 38,162,174,1,173,247,255,1,248,254,255,1,221,252,255,1,185,248,255,1, + 175,246,253,1,67,153,162,1,11,52,56,1,0,0,6,1,8,8,60,1, + 85,85,41,1,47,47,86,1,0,0,129,1,0,0,60,1,29,113,122,1, + 92,161,167,1,249,252,253,1,231,252,255,1,203,250,255,1,175,247,255,1, + 144,243,253,1,26,121,131,1,0,0,0,1,0,111,122,1,62,199,213,1, + 136,244,255,1,211,251,255,1,239,253,255,1,193,243,249,1,51,139,148,1, + 4,30,38,1,4,4,99,1,4,4,140,1,23,23,127,1,63,64,107,1, + 66,66,108,1,27,27,129,1,5,5,141,1,7,7,127,1,10,63,80,1, + 54,144,153,1,146,239,249,1,124,243,255,1,96,240,255,1,91,240,255,1, + 34,151,163,1,0,0,0,1,8,123,134,1,74,215,229,1,99,240,255,1, + 175,247,255,1,225,239,241,1,50,127,135,1,0,12,47,1,6,6,130,1, + 45,45,107,1,152,153,37,1,175,176,33,1,184,185,38,1,192,193,44,1, + 201,202,49,1,193,194,62,1,62,62,118,1,10,10,133,1,0,19,74,1, + 22,132,143,1,82,227,241,1,91,240,255,2,42,164,176,1,0,11,12,1, + 11,127,138,1,74,216,230,1,91,240,255,1,112,218,229,1,39,115,122,1, + 0,6,13,1,6,6,130,1,88,89,68,1,157,158,22,1,166,167,27,1, + 175,176,33,1,184,185,38,1,192,193,44,1,201,202,49,1,210,211,55,1, + 219,220,60,1,134,135,97,1,10,11,132,1,0,8,20,1,18,124,135,1, + 74,215,228,1,91,240,255,1,46,170,183,1,0,17,19,1,0,111,122,1, + 53,186,200,1,64,200,214,1,16,101,109,1,0,1,1,1,4,4,104,1, + 42,42,101,1,149,150,16,1,157,158,22,1,166,167,27,1,175,176,33,1, + 184,185,38,1,192,193,44,1,201,202,49,1,210,211,55,1,219,220,60,1, + 227,228,66,1,70,70,118,1,7,7,102,1,0,2,2,1,17,119,129,1, + 64,199,213,1,32,144,155,1,0,0,0,1,208,208,208,1,19,136,148,1, + 13,98,107,1,0,0,0,1,0,0,10,1,3,3,140,1,128,129,22,1, + 149,150,16,1,157,158,22,1,166,167,27,1,175,176,33,1,184,185,38,1, + 192,193,44,1,201,202,49,1,210,211,55,1,219,220,60,1,227,228,66,1, + 211,219,87,1,12,20,148,1,0,0,9,1,0,0,0,1,15,113,123,1, + 12,93,101,1,0,0,0,1,208,208,208,1,0,0,0,3,0,0,98,1, + 18,18,125,1,140,141,11,1,149,150,16,1,156,163,33,1,129,234,198,1, + 157,201,102,1,184,185,38,1,192,193,44,1,188,210,81,1,166,232,149,1, + 144,246,200,1,131,252,229,1,170,247,172,1,33,36,133,1,0,0,49,1, + 0,0,0,4,208,208,208,1,0,0,0,3,0,0,142,1,46,46,95,1, + 140,141,11,1,149,150,16,1,156,160,27,1,140,214,147,1,117,254,250,1, + 129,242,212,1,130,245,217,1,117,255,252,1,120,253,244,1,159,241,173,1, + 213,232,91,1,236,237,71,1,83,83,118,1,0,0,83,1,0,0,0,4, + 208,208,208,4,0,0,144,1,46,46,94,1,140,141,11,1,149,150,16,1, + 157,158,22,1,166,167,27,1,154,205,112,1,118,254,249,1,125,248,229,1, + 162,227,144,1,203,214,69,1,219,220,60,1,227,228,66,1,236,237,71,1, + 83,83,118,1,0,0,82,1,0,0,0,2,208,208,208,6,0,0,144,1, + 18,18,125,1,140,141,11,1,149,150,16,1,157,158,22,1,166,167,27,1, + 175,176,33,1,179,191,56,1,191,194,47,1,201,202,49,1,210,211,55,1, + 219,220,60,1,227,228,66,1,236,237,71,1,32,32,130,1,0,0,47,1, + 0,0,0,2,208,208,208,6,0,0,128,1,3,3,140,1,128,129,22,1, + 149,150,16,1,157,158,22,1,166,167,27,1,175,176,33,1,184,185,38,1, + 192,193,44,1,201,202,49,1,210,211,55,1,219,220,60,1,227,228,66,1, + 217,217,77,1,5,5,140,1,0,0,6,1,0,0,0,2,208,208,208,7, + 5,5,134,1,41,41,103,1,149,150,16,1,157,158,22,1,166,167,27,1, + 175,176,33,1,184,185,38,1,192,193,44,1,201,202,49,1,210,211,55,1, + 219,220,60,1,227,228,66,1,69,69,119,1,6,6,98,1,0,0,0,3, + 208,208,208,7,0,0,103,1,7,7,137,1,87,88,68,1,157,158,22,1, + 166,167,27,1,175,176,33,1,184,185,38,1,192,193,44,1,201,202,49,1, + 210,211,55,1,219,220,60,1,132,133,97,1,10,11,131,1,0,0,7,1, + 0,0,0,3,208,208,208,7,24,199,223,1,59,194,215,1,7,24,139,1, + 43,43,107,1,150,151,38,1,175,176,33,1,184,185,38,1,192,193,44,1, + 201,202,49,1,189,190,64,1,60,60,117,1,10,20,132,1,22,152,177,1, + 0,144,166,1,0,7,10,1,0,0,0,2,208,208,208,6,9,196,219,1, + 75,208,240,1,116,195,218,1,0,129,150,1,4,4,100,1,4,4,140,1, + 21,21,127,1,60,60,105,1,63,63,107,1,24,24,129,1,5,5,140,1, + 5,5,94,1,2,78,89,1,172,230,238,1,11,143,189,1,0,119,136,1, + 0,0,0,2,208,208,208,6,31,201,225,1,240,248,251,1,4,154,190,1, + 0,34,38,1,0,0,0,1,0,0,8,1,0,0,51,1,0,0,82,1, + 0,0,81,1,0,0,43,1,0,0,4,1,0,0,0,1,0,12,15,1, + 49,194,220,1,134,193,219,1,0,149,176,1,0,0,0,3,208,208,208,4, + 0,195,218,1,75,207,237,1,115,184,214,1,0,145,168,1,0,0,0,10, + 24,188,211,1,233,249,251,1,22,152,192,1,0,85,97,1,0,0,0,2, + 208,208,208,4,7,197,219,1,142,222,233,1,0,153,189,1,0,53,60,1, + 0,0,0,10,0,176,208,1,45,198,225,1,110,199,219,1,0,110,125,1, + 0,0,0,2,208,208,208,4,0,0,0,1,12,172,190,1,0,107,122,1, + 0,0,0,3,208,208,208,9,11,164,180,1,23,141,154,1,0,2,2,1, + 0,0,0,2,208,208,208,5,0,0,0,5,208,208,208,9,0,0,0,5, + 208,208,208,1,68,5,0,0,0,0,0,10,1,1,1,1,43,43,43,1, + 32,32,32,1,0,0,0,14,72,72,72,1,175,175,175,1,184,184,184,1, + 186,186,186,1,134,134,134,1,28,28,28,1,129,129,129,1,239,239,239,1, + 255,255,255,1,206,206,206,1,3,3,3,1,0,0,0,1,12,12,12,1, + 107,107,107,1,177,177,177,1,178,178,178,1,174,174,174,1,53,53,53,1, + 1,1,1,1,0,0,0,3,2,2,2,1,186,186,186,1,242,242,242,1, + 255,255,255,4,220,220,220,1,124,124,124,1,255,255,255,3,39,39,39,1, + 32,32,32,1,213,213,213,1,252,252,252,1,255,255,255,3,235,235,235,1, + 153,153,153,1,8,8,8,1,1,1,1,1,0,0,0,1,127,127,127,1, + 249,249,249,1,255,255,255,5,241,241,241,1,160,160,160,1,176,176,176,1, + 255,255,255,1,64,64,64,1,0,0,0,1,85,85,85,1,230,230,230,1, + 255,255,255,5,242,242,242,1,93,93,93,1,14,14,14,1,13,13,13,1, + 221,221,221,1,255,255,255,5,239,239,239,1,168,168,168,1,129,129,129,1, + 123,123,123,1,185,185,185,1,140,140,140,1,59,59,59,1,13,13,13,1, + 77,77,77,1,231,231,231,1,255,255,255,5,214,214,214,1,64,64,64,1, + 48,48,48,1,244,244,244,1,255,255,255,4,235,235,235,1,158,158,158,1, + 198,198,198,1,251,251,251,1,242,242,242,1,246,246,246,1,247,247,247,1, + 244,244,244,1,250,250,250,1,156,156,156,1,76,76,76,1,226,226,226,1, + 255,255,255,4,238,238,238,1,109,109,109,1,84,84,84,1,255,255,255,4, + 228,228,228,1,162,162,162,1,238,238,238,1,248,248,248,1,255,255,255,6, + 249,249,249,1,235,235,235,1,103,103,103,1,215,215,215,1,254,254,254,1, + 255,255,255,2,242,242,242,1,136,136,136,1,91,91,91,1,255,255,255,2, + 252,252,252,1,219,219,219,1,141,141,141,1,236,236,236,1,254,254,254,1, + 255,255,255,9,237,237,237,1,92,92,92,1,199,199,199,1,252,252,252,1, + 255,255,255,1,243,243,243,1,144,144,144,1,28,28,28,1,236,236,236,1, + 246,246,246,1,206,206,206,1,133,133,133,1,189,189,189,1,247,247,247,1, + 255,255,255,10,250,250,250,1,195,195,195,1,67,67,67,1,174,174,174,1, + 247,247,247,1,232,232,232,1,133,133,133,1,0,0,0,1,181,181,181,1, + 161,161,161,1,125,125,125,1,104,104,104,1,250,250,250,1,255,255,255,12, + 252,252,252,1,115,115,115,1,39,39,39,1,141,141,141,1,171,171,171,1, + 121,121,121,1,0,0,0,1,5,5,5,1,45,45,45,1,79,79,79,1, + 78,78,78,1,241,241,241,1,255,255,255,12,248,248,248,1,155,155,155,1, + 69,69,69,1,14,14,14,1,31,31,31,1,71,71,71,1,0,0,0,1, + 1,1,1,1,6,6,6,1,11,11,11,1,108,108,108,1,246,246,246,1, + 255,255,255,12,250,250,250,1,185,185,185,1,97,97,97,1,14,14,14,1, + 3,3,3,1,10,10,10,1,0,0,0,4,106,106,106,1,246,246,246,1, + 255,255,255,12,250,250,250,1,187,187,187,1,114,114,114,1,17,17,17,1, + 0,0,0,6,53,53,53,1,241,241,241,1,255,255,255,12,248,248,248,1, + 162,162,162,1,113,113,113,1,17,17,17,1,0,0,0,6,6,6,6,1, + 249,249,249,1,255,255,255,12,252,252,252,1,138,138,138,1,96,96,96,1, + 14,14,14,1,0,0,0,7,146,146,146,1,247,247,247,1,255,255,255,10, + 250,250,250,1,204,204,204,1,128,128,128,1,68,68,68,1,9,9,9,1, + 0,0,0,7,10,10,10,1,226,226,226,1,254,254,254,1,255,255,255,9, + 240,240,240,1,140,140,140,1,111,111,111,1,31,31,31,1,3,3,3,1, + 0,0,0,7,146,146,146,1,196,196,196,1,230,230,230,1,249,249,249,1, + 255,255,255,6,250,250,250,1,239,239,239,1,225,225,225,1,211,211,211,1, + 75,75,75,1,17,17,17,1,2,2,2,1,0,0,0,6,56,56,56,1, + 239,239,239,1,255,255,255,1,166,166,166,1,186,186,186,1,251,251,251,1, + 248,248,248,1,250,250,250,2,249,249,249,1,252,252,252,1,200,200,200,1, + 168,168,168,1,254,254,254,1,252,252,252,1,154,154,154,1,47,47,47,1, + 8,8,8,1,0,0,0,6,181,181,181,1,255,255,255,1,235,235,235,1, + 140,140,140,1,100,100,100,1,61,61,61,1,126,126,126,1,171,171,171,1, + 172,172,172,1,148,148,148,1,123,123,123,1,118,118,118,1,102,102,102,1, + 222,222,222,1,255,255,255,1,225,225,225,1,94,94,94,1,20,20,20,1, + 2,2,2,1,0,0,0,4,34,34,34,1,233,233,233,1,255,255,255,1, + 209,209,209,1,131,131,131,1,77,77,77,1,23,23,23,1,16,16,16,1, + 27,27,27,1,46,46,46,1,59,59,59,1,46,46,46,1,27,27,27,1, + 16,16,16,1,148,148,148,1,255,255,255,1,249,249,249,1,160,160,160,1, + 55,55,55,1,9,9,9,1,0,0,0,4,70,70,70,1,246,246,246,1, + 240,240,240,1,154,154,154,1,113,113,113,1,40,40,40,1,6,6,6,1, + 1,1,1,1,2,2,2,1,5,5,5,1,8,8,8,1,5,5,5,1, + 2,2,2,1,1,1,1,1,16,16,16,1,225,225,225,1,251,251,251,1, + 186,186,186,1,91,91,91,1,18,18,18,1,0,0,0,4,1,1,1,1, + 110,110,110,1,136,136,136,1,117,117,117,1,79,79,79,1,21,21,21,1, + 0,0,0,9,67,67,67,1,143,143,143,1,112,112,112,1,87,87,87,1, + 20,20,20,1,0,0,0,5,4,4,4,1,32,32,32,1,57,57,57,1, + 21,21,21,1,4,4,4,1,0,0,0,9,2,2,2,1,24,24,24,1, + 49,49,49,1,36,36,36,1,7,7,7,1,0,0,0,1,0,0) + ); + +const + objdata_tanimtimer: record size: integer; data: array[0..3109] of byte end = + (size: 3110; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,97,110, + 105,109,116,105,109,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,176,11,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,52,6,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,10,128,128,255,1,121,121,255,1, + 82,82,255,1,0,0,0,13,0,85,85,1,33,133,143,1,48,149,159,1, + 59,157,167,1,57,155,165,1,39,139,149,1,0,99,107,1,113,113,253,1, + 181,181,255,1,141,141,255,1,103,103,255,1,64,64,255,1,0,0,0,1, + 0,112,128,1,31,136,146,1,51,150,160,1,58,157,165,1,49,148,158,1, + 27,129,140,1,0,0,0,4,0,113,113,1,61,147,155,1,179,224,228,1, + 187,249,255,1,177,248,255,2,167,240,247,1,69,162,171,1,50,73,203,1, + 148,148,255,1,164,164,255,1,124,124,255,1,83,83,255,1,25,130,140,1, + 66,162,172,1,158,234,241,1,177,248,255,1,191,249,255,1,204,250,255,1, + 159,214,219,1,49,137,144,1,0,0,0,3,31,141,153,1,190,237,242,1, + 240,254,255,1,204,250,255,1,177,248,255,3,84,169,178,1,17,66,90,1, + 90,90,150,1,139,139,65,1,118,118,95,1,4,4,253,1,8,26,234,1, + 37,69,229,1,82,102,254,1,88,102,254,1,93,103,254,1,99,104,254,1, + 159,160,254,1,150,202,207,1,22,91,97,1,0,0,0,1,0,109,128,1, + 45,171,183,1,173,248,255,1,249,254,255,1,222,252,255,1,186,249,255,1, + 174,246,253,1,64,152,161,1,9,50,55,1,0,0,17,1,7,7,80,1, + 87,87,40,1,48,48,84,1,2,2,183,1,3,3,252,1,3,3,253,5, + 67,94,254,1,147,245,255,1,30,129,139,1,0,0,0,1,4,120,131,1, + 68,207,221,1,136,244,255,1,212,251,255,1,240,254,255,1,193,243,248,1, + 49,138,146,1,5,28,48,1,7,7,108,1,5,5,140,1,45,46,113,1, + 80,80,99,1,83,83,101,1,52,52,117,1,6,6,162,1,4,4,245,1, + 3,3,253,2,3,3,249,1,3,3,253,1,38,92,254,1,91,240,255,1, + 37,155,167,1,0,7,7,1,16,133,144,1,79,223,237,1,100,241,255,1, + 175,248,255,1,225,239,240,1,51,129,137,1,0,14,51,1,6,6,133,1, + 70,70,89,1,157,157,35,1,175,176,33,1,184,185,39,1,193,194,44,1, + 202,203,50,1,197,198,61,1,63,63,156,1,3,3,253,4,36,91,254,1, + 91,240,255,1,51,177,191,1,0,23,26,1,15,134,143,1,77,220,235,1, + 91,240,255,1,110,215,226,1,37,115,122,1,0,5,27,1,6,6,133,1, + 96,97,61,1,158,159,22,1,167,168,28,1,175,176,33,1,184,185,39,1, + 193,194,44,1,202,203,50,1,174,175,90,1,21,21,237,1,3,3,253,4, + 29,80,243,1,91,240,255,1,47,172,184,1,0,18,19,1,5,118,128,1, + 61,196,210,1,63,197,211,1,15,102,109,1,0,0,0,1,6,6,111,1, + 62,62,84,1,149,150,17,1,158,159,22,1,167,168,28,1,175,176,33,1, + 184,185,39,1,193,194,44,1,167,168,86,1,20,20,237,1,3,3,253,1, + 22,22,237,1,67,68,160,1,4,4,243,1,3,3,253,1,7,36,216,1, + 62,196,209,1,31,143,154,1,0,0,0,2,22,141,151,1,12,98,106,1, + 0,0,0,1,0,0,23,1,4,4,139,1,132,133,18,1,149,150,17,1, + 158,159,22,1,167,168,28,1,175,176,33,1,184,185,39,1,162,163,78,1, + 22,22,234,1,3,3,253,1,21,21,237,1,185,190,105,1,203,228,107,1, + 13,21,166,1,3,3,241,1,3,3,230,1,14,114,123,1,14,99,107,1, + 0,0,0,5,0,0,115,1,35,35,107,1,140,141,11,1,149,150,17,1, + 157,164,33,1,129,234,197,1,156,201,103,1,154,155,74,1,21,21,233,1, + 3,3,253,1,17,22,245,1,116,204,218,1,121,254,245,1,166,248,178,1, + 63,69,129,1,0,0,110,1,3,3,201,1,0,0,0,7,0,0,143,1, + 58,59,83,1,140,141,11,1,149,150,17,1,157,162,28,1,140,215,148,1, + 98,210,251,1,14,23,250,1,3,3,253,1,13,24,253,1,101,209,244,1, + 159,240,172,1,214,232,91,1,237,238,72,1,106,106,113,1,0,0,86,1, + 0,0,14,1,0,0,0,7,0,0,144,1,57,58,84,1,140,141,11,1, + 149,150,17,1,158,159,22,1,140,141,64,1,17,22,240,1,3,3,253,1, + 13,23,250,1,139,185,154,1,206,213,64,1,219,220,61,1,228,229,66,1, + 237,238,72,1,104,104,113,1,0,0,86,1,0,0,0,8,0,0,143,1, + 34,34,108,1,140,141,11,1,149,150,17,1,133,133,59,1,19,19,232,1, + 3,3,253,1,18,19,237,1,159,162,83,1,202,203,50,1,210,211,55,1, + 219,220,61,1,228,229,66,1,237,238,72,1,59,59,123,1,0,0,66,1, + 0,0,0,8,0,0,136,1,4,4,140,1,131,132,20,1,125,126,55,1, + 18,18,231,1,3,3,253,1,17,17,235,1,153,153,77,1,193,194,44,1, + 202,203,50,1,210,211,55,1,219,220,61,1,228,229,66,1,219,220,78,1, + 7,7,140,1,0,0,14,1,0,0,0,9,6,6,134,1,50,50,114,1, + 17,17,231,1,3,3,253,1,17,17,234,1,145,146,72,1,184,185,39,1, + 193,194,44,1,202,203,50,1,210,211,55,1,219,220,61,1,228,229,66,1, + 95,95,112,1,10,10,106,1,0,0,0,10,0,0,213,1,4,4,243,1, + 3,3,253,1,16,16,234,1,139,139,68,1,175,176,33,1,184,185,39,1, + 193,194,44,1,202,203,50,1,210,211,55,1,219,220,61,1,141,142,95,1, + 10,10,134,1,0,0,19,1,0,0,0,9,0,0,255,1,4,14,251,1, + 3,3,253,1,3,4,244,1,53,53,122,1,155,155,37,1,175,176,33,1, + 184,185,39,1,193,194,44,1,202,203,50,1,194,194,62,1,87,87,109,1, + 10,19,136,1,24,150,175,1,0,139,161,1,0,9,9,1,0,0,0,7, + 0,0,255,1,3,8,252,1,3,3,253,1,13,19,250,1,1,97,181,1, + 6,6,109,1,5,5,139,1,39,39,114,1,74,75,100,1,78,79,102,1, + 44,44,119,1,6,6,140,1,7,9,102,1,3,73,93,1,176,232,240,1, + 12,145,188,1,0,128,146,1,0,0,0,6,0,0,255,1,3,3,253,2, + 23,23,253,1,4,129,204,1,0,43,48,1,0,0,0,1,0,0,23,1, + 0,0,74,1,0,0,89,1,0,0,87,1,0,0,66,1,0,0,14,1, + 0,0,0,1,0,12,14,1,49,195,220,1,134,193,220,1,0,156,183,1, + 0,3,3,1,0,0,0,6,2,28,248,1,9,19,252,1,95,153,221,1, + 0,152,176,1,0,0,0,10,23,189,209,1,229,248,251,1,23,155,194,1, + 0,92,106,1,0,0,0,6,11,191,210,1,135,202,235,1,0,155,191,1, + 0,61,68,1,0,0,0,10,0,138,149,1,45,197,223,1,113,199,220,1, + 0,110,125,1,0,0,0,7,16,166,184,1,0,113,130,1,0,0,0,12, + 12,157,177,1,26,139,152,1,0,3,3,1,0,0,0,27,68,5,0,0, + 0,0,0,10,2,2,2,1,42,42,42,1,31,31,31,1,0,0,0,13, + 3,3,3,1,107,107,107,1,180,180,180,1,195,195,195,1,187,187,187,1, + 152,152,152,1,31,31,31,1,133,133,133,1,240,240,240,1,255,255,255,1, + 204,204,204,1,4,4,4,1,0,0,0,1,16,16,16,1,131,131,131,1, + 180,180,180,1,189,189,189,1,178,178,178,1,93,93,93,1,1,1,1,1, + 0,0,0,3,9,9,9,1,193,193,193,1,250,250,250,1,255,255,255,4, + 227,227,227,1,137,137,137,1,255,255,255,3,40,40,40,1,51,51,51,1, + 219,219,219,1,255,255,255,4,246,246,246,1,166,166,166,1,9,9,9,1, + 1,1,1,1,0,0,0,1,165,165,165,1,254,254,254,1,255,255,255,5, + 241,241,241,1,162,162,162,1,178,178,178,1,255,255,255,1,67,67,67,1, + 132,132,132,1,185,185,185,1,245,245,245,1,255,255,255,5,246,246,246,1, + 129,129,129,1,18,18,18,1,14,14,14,1,222,222,222,1,255,255,255,5, + 239,239,239,1,168,168,168,1,134,134,134,1,143,143,143,1,193,193,193,1, + 148,148,148,1,117,117,117,1,236,236,236,1,255,255,255,7,222,222,222,1, + 76,76,76,1,72,72,72,1,251,251,251,1,255,255,255,4,235,235,235,1, + 164,164,164,1,208,208,208,1,250,250,250,1,243,243,243,1,251,251,251,2, + 244,244,244,1,250,250,250,1,249,249,249,1,255,255,255,6,240,240,240,1, + 117,117,117,1,113,113,113,1,255,255,255,4,231,231,231,1,165,165,165,1, + 244,244,244,1,251,251,251,1,255,255,255,6,253,253,253,1,255,255,255,6, + 246,246,246,1,146,146,146,1,105,105,105,1,255,255,255,2,252,252,252,1, + 220,220,220,1,149,149,149,1,244,244,244,1,254,254,254,1,255,255,255,12, + 254,254,254,1,255,255,255,1,244,244,244,1,145,145,145,1,52,52,52,1, + 243,243,243,1,246,246,246,1,206,206,206,1,133,133,133,1,202,202,202,1, + 251,251,251,1,255,255,255,10,253,253,253,1,251,251,251,1,255,255,255,1, + 225,225,225,1,246,246,246,1,233,233,233,1,134,134,134,1,1,1,1,1, + 176,176,176,1,164,164,164,1,125,125,125,1,110,110,110,1,249,249,249,1, + 255,255,255,12,252,252,252,1,243,243,243,1,176,176,176,1,141,141,141,1, + 176,176,176,1,122,122,122,1,0,0,0,1,6,6,6,1,44,44,44,1, + 78,78,78,1,104,104,104,1,242,242,242,1,255,255,255,12,248,248,248,1, + 183,183,183,1,171,171,171,1,16,16,16,1,31,31,31,1,73,73,73,1, + 0,0,0,1,1,1,1,1,6,6,6,1,11,11,11,1,118,118,118,1, + 250,250,250,1,255,255,255,12,252,252,252,1,190,190,190,1,109,109,109,1, + 16,16,16,1,3,3,3,1,10,10,10,1,0,0,0,4,115,115,115,1, + 250,250,250,1,255,255,255,12,252,252,252,1,190,190,190,1,117,117,117,1, + 18,18,18,1,0,0,0,6,82,82,82,1,241,241,241,1,255,255,255,12, + 248,248,248,1,175,175,175,1,117,117,117,1,18,18,18,1,0,0,0,6, + 15,15,15,1,248,248,248,1,255,255,255,12,252,252,252,1,143,143,143,1, + 104,104,104,1,16,16,16,1,0,0,0,7,162,162,162,1,251,251,251,1, + 255,255,255,10,252,252,252,1,210,210,210,1,129,129,129,1,73,73,73,1, + 10,10,10,1,0,0,0,7,60,60,60,1,253,253,253,1,255,255,255,9, + 254,254,254,1,244,244,244,1,146,146,146,1,115,115,115,1,34,34,34,1, + 3,3,3,1,0,0,0,6,41,41,41,1,244,244,244,1,255,255,255,1, + 254,254,254,1,253,253,253,1,255,255,255,6,252,252,252,1,244,244,244,1, + 224,224,224,1,208,208,208,1,81,81,81,1,22,22,22,1,4,4,4,1, + 0,0,0,5,41,41,41,1,237,237,237,1,255,255,255,2,178,178,178,1, + 197,197,197,1,251,251,251,1,248,248,248,1,251,251,251,2,248,248,248,1, + 251,251,251,1,209,209,209,1,172,172,172,1,253,253,253,1,252,252,252,1, + 150,150,150,1,47,47,47,1,12,12,12,1,1,1,1,1,0,0,0,3, + 23,23,23,1,234,234,234,1,255,255,255,2,240,240,240,1,132,132,132,1, + 91,91,91,1,76,76,76,1,148,148,148,1,178,178,178,1,181,181,181,1, + 165,165,165,1,130,130,130,1,119,119,119,1,107,107,107,1,224,224,224,1, + 255,255,255,1,226,226,226,1,83,83,83,1,29,29,29,1,5,5,5,1, + 1,1,1,1,0,0,0,3,138,138,138,1,253,253,253,1,255,255,255,1, + 206,206,206,1,113,113,113,1,73,73,73,1,26,26,26,1,19,19,19,1, + 36,36,36,1,54,54,54,1,63,63,63,1,54,54,54,1,35,35,35,1, + 19,19,19,1,154,154,154,1,255,255,255,1,249,249,249,1,149,149,149,1, + 60,60,60,1,13,13,13,1,1,1,1,1,0,0,0,3,68,68,68,1, + 247,247,247,1,239,239,239,1,142,142,142,1,105,105,105,1,44,44,44,1, + 12,12,12,1,2,2,2,1,3,3,3,1,7,7,7,1,8,8,8,1, + 7,7,7,1,3,3,3,1,2,2,2,1,24,24,24,1,226,226,226,1, + 250,250,250,1,176,176,176,1,82,82,82,1,21,21,21,1,2,2,2,1, + 0,0,0,3,2,2,2,1,112,112,112,1,122,122,122,1,95,95,95,1, + 77,77,77,1,22,22,22,1,2,2,2,1,0,0,0,7,1,1,1,1, + 65,65,65,1,138,138,138,1,93,93,93,1,69,69,69,1,25,25,25,1, + 2,2,2,1,0,0,0,3,1,1,1,1,6,6,6,1,35,35,35,1, + 50,50,50,1,30,30,30,1,10,10,10,1,1,1,1,1,0,0,0,7, + 1,1,1,1,8,8,8,1,25,25,25,1,45,45,45,1,36,36,36,1, + 7,7,7,1,1,1,1,1,0,0) + ); + +const + objdata_tanimitemcomp: record size: integer; data: array[0..1280] of byte end = + (size: 1281; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,97,110, + 105,109,105,116,101,109,99,111,109,112,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,136,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,224,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,156,156,156,25,0,0,0,22,156, + 156,156,2,0,0,0,22,156,156,156,2,0,0,0,12,3,3,252,1,3, + 3,253,7,0,0,0,2,156,156,156,2,0,0,0,13,2,2,253,1,3, + 3,253,6,0,0,0,2,156,156,156,2,0,0,0,14,2,2,253,1,3, + 3,253,2,3,3,249,1,3,3,253,2,0,0,0,2,156,156,156,2,0, + 0,0,14,6,6,255,1,3,3,253,5,0,0,0,2,156,156,156,2,0, + 0,0,13,6,6,255,1,3,3,253,6,0,0,0,2,156,156,156,2,0, + 0,0,12,6,6,255,1,3,3,253,3,6,6,255,1,2,2,253,1,3, + 3,253,2,0,0,0,2,156,156,156,2,0,0,0,11,0,0,255,1,3, + 3,253,3,6,6,255,1,0,0,0,2,3,3,253,2,0,0,0,2,156, + 156,156,2,0,0,0,10,6,6,255,1,3,3,253,3,6,6,255,1,0, + 0,0,4,3,3,252,1,0,0,0,2,156,156,156,2,0,0,0,9,0, + 0,255,1,3,3,253,3,6,6,255,1,0,0,0,8,156,156,156,2,0, + 0,0,8,0,0,255,1,3,3,253,3,6,6,255,1,0,0,0,9,156, + 156,156,2,0,0,0,7,0,0,255,1,3,3,253,3,6,6,255,1,0, + 0,0,10,156,156,156,2,0,0,0,6,0,0,255,1,3,3,253,3,6, + 6,255,1,0,0,0,11,156,156,156,2,0,0,0,5,0,0,255,1,3, + 3,253,3,6,6,255,1,0,0,0,12,156,156,156,2,0,0,0,4,0, + 0,255,1,3,3,253,3,6,6,255,1,0,0,0,13,156,156,156,2,0, + 0,0,3,0,0,255,1,3,3,253,3,6,6,255,1,0,0,0,14,156, + 156,156,2,0,0,0,2,0,0,255,1,3,3,253,3,6,6,255,1,0, + 0,0,15,156,156,156,2,0,0,0,2,3,3,254,1,3,3,253,2,6, + 6,255,1,0,0,0,16,156,156,156,2,0,0,0,2,0,0,255,1,3, + 3,254,1,6,6,255,1,0,0,0,17,156,156,156,2,0,0,0,22,156, + 156,156,2,0,0,0,22,156,156,156,25,112,2,0,0,255,255,255,25,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,12,93, + 93,93,1,237,237,237,1,238,238,238,5,230,230,230,1,0,0,0,2,255, + 255,255,2,0,0,0,13,108,108,108,1,254,254,254,1,255,255,255,4,246, + 246,246,1,0,0,0,2,255,255,255,2,0,0,0,14,108,108,108,1,254, + 254,254,1,255,255,255,3,246,246,246,1,0,0,0,2,255,255,255,2,0, + 0,0,14,45,45,45,1,241,241,241,1,255,255,255,3,246,246,246,1,0, + 0,0,2,255,255,255,2,0,0,0,13,45,45,45,1,234,234,234,1,255, + 255,255,1,241,241,241,1,254,254,254,1,255,255,255,1,246,246,246,1,0, + 0,0,2,255,255,255,2,0,0,0,12,45,45,45,1,234,234,234,1,255, + 255,255,1,234,234,234,1,45,45,45,1,108,108,108,1,254,254,254,1,246, + 246,246,1,0,0,0,2,255,255,255,2,0,0,0,11,41,41,41,1,231, + 231,231,1,255,255,255,1,234,234,234,1,45,45,45,1,0,0,0,2,102, + 102,102,1,245,245,245,1,0,0,0,2,255,255,255,2,0,0,0,10,45, + 45,45,1,234,234,234,1,255,255,255,1,234,234,234,1,45,45,45,1,0, + 0,0,4,100,100,100,1,0,0,0,2,255,255,255,2,0,0,0,9,41, + 41,41,1,231,231,231,1,255,255,255,1,234,234,234,1,45,45,45,1,0, + 0,0,8,255,255,255,2,0,0,0,8,41,41,41,1,231,231,231,1,255, + 255,255,1,234,234,234,1,45,45,45,1,0,0,0,9,255,255,255,2,0, + 0,0,7,41,41,41,1,231,231,231,1,255,255,255,1,234,234,234,1,45, + 45,45,1,0,0,0,10,255,255,255,2,0,0,0,6,41,41,41,1,231, + 231,231,1,255,255,255,1,234,234,234,1,45,45,45,1,0,0,0,11,255, + 255,255,2,0,0,0,5,41,41,41,1,231,231,231,1,255,255,255,1,234, + 234,234,1,45,45,45,1,0,0,0,12,255,255,255,2,0,0,0,4,41, + 41,41,1,231,231,231,1,255,255,255,1,234,234,234,1,45,45,45,1,0, + 0,0,13,255,255,255,2,0,0,0,3,41,41,41,1,231,231,231,1,255, + 255,255,1,234,234,234,1,45,45,45,1,0,0,0,14,255,255,255,2,0, + 0,0,2,41,41,41,1,231,231,231,1,255,255,255,1,234,234,234,1,45, + 45,45,1,0,0,0,15,255,255,255,2,0,0,0,2,177,177,177,1,255, + 255,255,1,234,234,234,1,45,45,45,1,0,0,0,16,255,255,255,2,0, + 0,0,2,14,14,14,1,177,177,177,1,45,45,45,1,0,0,0,17,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0, + 0) + ); + +const + objdata_tpipereadercomp: record size: integer; data: array[0..2074] of byte end = + (size: 2075; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,112,105, + 112,101,114,101,97,100,101,114,99,111,109,112,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,160,7,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,108,4,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,26,153,102,102, + 1,142,85,85,1,208,208,208,21,128,96,96,1,188,161,162,1,210,184,185, + 1,196,165,165,1,182,149,150,1,161,124,126,1,143,98,98,1,208,208,208, + 17,173,142,142,1,245,233,234,1,249,241,242,1,245,233,235,1,241,226,227, + 1,237,217,219,1,215,189,191,1,195,162,165,1,184,149,150,1,169,133,133, + 1,152,111,111,1,128,85,85,1,208,208,208,12,187,149,151,1,235,209,211, + 1,239,218,219,1,243,227,228,1,247,236,237,1,248,240,242,1,245,233,234, + 1,241,225,227,1,237,217,219,1,233,210,212,1,222,194,197,1,196,162,164, + 1,187,150,152,1,176,137,137,1,146,104,106,1,255,0,0,1,208,208,208, + 8,186,142,143,1,224,183,185,1,228,192,194,1,232,201,203,1,235,210,212, + 1,239,219,220,1,243,228,229,1,247,237,238,1,248,240,241,1,244,232,233, + 1,240,224,226,1,237,217,219,1,215,187,189,1,163,112,114,1,167,97,99, + 1,146,88,88,1,130,87,87,1,208,208,208,7,184,129,131,1,213,157,160, + 1,217,166,168,1,220,175,177,1,224,184,186,1,228,193,195,1,232,202,204, + 1,236,211,212,1,240,220,221,1,244,229,230,1,247,238,239,1,243,233,234, + 1,171,128,129,1,200,127,129,1,196,118,121,1,192,109,112,1,149,90,93, + 1,139,93,93,1,208,208,208,6,176,111,113,1,201,131,134,1,205,140,143, + 1,209,149,152,1,213,158,161,1,217,167,169,1,221,176,178,1,225,185,187, + 1,228,194,196,1,232,203,204,1,236,212,213,1,198,168,168,1,200,147,149, + 1,208,146,149,1,204,137,140,1,200,128,131,1,185,114,117,1,140,90,92, + 1,208,208,208,6,166,92,96,1,190,105,109,1,194,114,117,1,198,123,126, + 1,202,132,135,1,206,141,144,1,210,150,153,1,213,159,161,1,217,168,170, + 1,221,177,179,1,225,186,188,1,175,135,136,1,220,175,177,1,216,166,168, + 1,212,156,159,1,208,147,150,1,204,138,141,1,150,98,100,1,208,208,208, + 3,0,0,157,1,208,208,208,2,159,87,88,1,181,83,87,1,183,88,92, + 1,187,97,101,1,191,106,109,1,194,115,118,1,198,124,127,1,202,133,136, + 1,206,142,145,1,210,151,153,1,214,160,162,1,179,139,141,1,229,194,196, + 1,225,185,187,1,221,175,178,1,217,166,168,1,212,157,159,1,161,111,112, + 1,208,208,208,2,0,0,157,1,7,7,167,1,208,208,208,2,148,86,88, + 1,180,83,87,1,181,83,87,3,183,89,93,1,187,98,102,1,191,107,110, + 1,195,116,119,1,199,125,128,1,201,132,135,1,184,149,151,1,237,213,215, + 1,233,204,205,1,229,194,196,1,222,183,187,1,80,66,176,1,104,77,145, + 1,92,46,104,1,208,208,208,1,15,15,177,1,19,19,183,1,208,208,208, + 2,128,64,64,1,156,85,86,1,180,83,87,1,181,83,87,5,184,90,94, + 1,187,99,102,1,185,106,109,1,197,168,169,1,245,232,233,1,241,223,224, + 1,237,214,215,1,109,96,188,1,61,60,235,1,60,60,234,1,30,29,193, + 1,15,15,177,1,32,32,200,1,43,43,215,1,0,0,157,1,208,208,208, + 2,128,64,64,1,150,85,85,1,161,84,85,1,180,83,87,1,181,83,87, + 5,180,83,87,1,179,141,142,1,246,235,236,1,249,242,243,1,245,233,234, + 1,180,166,209,1,101,92,192,1,56,48,178,1,33,33,200,1,50,50,224, + 1,69,69,249,1,67,67,247,1,14,14,176,1,208,208,208,2,0,0,0, + 2,11,7,7,1,96,55,57,1,145,74,76,1,180,83,87,1,181,83,87, + 4,171,125,126,1,237,218,220,1,242,227,228,1,246,235,236,1,250,243,244, + 1,245,233,234,1,171,138,140,1,0,0,157,1,32,32,200,1,73,73,255, + 1,51,51,226,1,13,13,175,1,208,208,208,2,0,0,0,4,4,2,2, + 1,88,49,51,1,142,74,76,1,180,83,87,1,181,83,87,2,162,106,107, + 1,229,202,205,1,233,210,212,1,237,218,220,1,241,226,228,1,245,234,235, + 1,159,126,126,1,17,17,179,1,47,47,220,1,20,20,184,1,10,10,170, + 1,208,208,208,4,0,0,0,5,4,2,2,1,84,50,50,1,141,73,76, + 1,179,83,87,1,167,89,91,1,202,166,169,1,225,193,196,1,229,202,204, + 1,233,210,212,1,212,186,187,1,84,60,110,1,8,8,167,1,10,10,170, + 1,208,208,208,7,0,0,0,6,2,2,2,1,80,47,47,1,139,73,75, + 1,160,107,108,1,221,188,191,1,225,193,196,1,221,188,191,1,134,101,102, + 1,5,2,32,1,0,0,0,2,208,208,208,9,0,0,0,6,2,0,0, + 1,83,49,49,1,151,103,105,1,159,121,122,1,130,94,96,1,20,13,13, + 1,0,0,0,3,208,208,208,11,0,0,0,6,2,0,0,1,16,11,11, + 1,0,0,0,5,208,208,208,13,0,0,0,10,208,208,208,16,0,0,0, + 7,208,208,208,77,252,2,0,0,0,0,0,26,5,5,5,1,9,9,9, + 1,0,0,0,21,8,8,8,1,195,195,195,1,233,233,233,1,193,193,193, + 1,151,151,151,1,109,109,109,1,34,34,34,1,0,0,0,17,124,124,124, + 1,255,255,255,5,247,247,247,1,209,209,209,1,168,168,168,1,127,127,127, + 1,69,69,69,1,6,6,6,1,0,0,0,12,164,164,164,1,255,255,255, + 9,254,254,254,1,225,225,225,1,185,185,185,1,144,144,144,1,102,102,102, + 1,1,1,1,1,0,0,0,8,196,196,196,1,255,255,255,13,249,249,249, + 1,211,211,211,1,47,47,47,1,0,0,0,7,224,224,224,1,255,255,255, + 15,206,206,206,1,11,11,11,1,0,0,0,6,214,214,214,1,255,255,255, + 15,253,253,253,1,111,111,111,1,0,0,0,6,191,191,191,1,255,255,255, + 16,189,189,189,1,0,0,0,3,2,2,2,1,0,0,0,2,168,168,168, + 1,255,255,255,16,212,212,212,1,0,0,0,2,16,16,16,1,137,137,137, + 1,0,0,0,2,110,110,110,1,255,255,255,16,236,236,236,1,11,11,11, + 1,0,0,0,1,152,152,152,1,215,215,215,1,0,0,0,2,4,4,4, + 1,180,180,180,1,255,255,255,15,254,254,254,1,215,215,215,1,146,146,146, + 1,222,222,222,1,238,238,238,1,40,40,40,1,0,0,0,2,4,4,4, + 1,117,117,117,1,211,211,211,1,255,255,255,13,247,247,247,1,223,223,223, + 1,250,250,250,1,255,255,255,2,143,143,143,1,0,0,0,2,1,1,1, + 1,13,13,13,1,69,69,69,1,176,176,176,1,231,231,231,1,255,255,255, + 11,210,210,210,1,34,34,34,1,226,226,226,1,255,255,255,1,244,244,244, + 1,172,172,172,1,0,0,0,2,1,1,1,1,11,11,11,1,57,57,57, + 1,99,99,99,1,128,128,128,1,186,186,186,1,231,231,231,1,255,255,255, + 9,183,183,183,1,171,171,171,1,245,245,245,1,200,200,200,1,83,83,83, + 1,0,0,0,4,2,2,2,1,11,11,11,1,29,29,29,1,70,70,70, + 1,105,105,105,1,129,129,129,1,185,185,185,1,230,230,230,1,255,255,255, + 6,250,250,250,1,130,130,130,1,214,214,214,1,83,83,83,1,0,0,0, + 7,1,1,1,1,3,3,3,1,13,13,13,1,31,31,31,1,72,72,72, + 1,108,108,108,1,129,129,129,1,184,184,184,1,229,229,229,1,255,255,255, + 4,222,222,222,1,101,101,101,1,20,20,20,1,1,1,1,1,0,0,0, + 9,1,1,1,1,3,3,3,1,14,14,14,1,35,35,35,1,76,76,76, + 1,110,110,110,1,129,129,129,1,187,187,187,1,248,248,248,1,246,246,246, + 1,224,224,224,1,141,141,141,1,96,96,96,1,24,24,24,1,2,2,2, + 1,0,0,0,11,1,1,1,1,4,4,4,1,15,15,15,1,38,38,38, + 1,79,79,79,1,113,113,113,1,128,128,128,1,138,138,138,1,124,124,124, + 1,97,97,97,1,44,44,44,1,8,8,8,1,1,1,1,1,0,0,0, + 13,1,1,1,1,4,4,4,1,16,16,16,1,41,41,41,1,71,71,71, + 1,74,74,74,1,63,63,63,1,31,31,31,1,8,8,8,1,1,1,1, + 1,0,0,0,16,1,1,1,1,5,5,5,1,12,12,12,2,10,10,10, + 1,4,4,4,1,1,1,1,1,0,0,0,77,0,0) + ); + +const + objdata_tthreadcomp: record size: integer; data: array[0..1306] of byte end = + (size: 1307; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,116,104, + 114,101,97,100,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,164,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,208,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,208,208,208,101,36,169,33,1,35,169,33, + 1,36,182,36,1,208,208,208,21,32,167,32,1,35,170,33,1,35,169,33, + 1,35,168,31,1,208,208,208,22,35,168,31,1,35,169,33,1,35,170,33, + 1,32,167,32,1,208,208,208,21,36,182,36,1,35,169,33,3,36,182,36, + 1,208,208,208,21,32,167,32,1,35,169,34,1,35,169,33,1,35,168,31, + 1,208,208,208,14,138,220,255,1,141,222,255,1,208,208,208,6,35,168,31, + 1,35,169,33,1,35,170,33,1,32,167,32,1,208,208,208,2,117,216,255, + 1,138,220,255,1,208,208,208,8,180,233,255,1,144,222,255,1,146,219,255, + 1,208,208,208,6,36,182,36,1,35,169,33,1,36,169,33,1,208,208,208, + 1,134,219,255,1,155,224,255,1,180,233,255,1,208,208,208,8,221,245,255, + 1,146,223,255,1,146,222,255,1,35,169,33,1,208,208,208,1,35,169,33, + 1,208,208,208,1,35,169,33,1,208,208,208,1,35,169,33,1,208,208,208, + 1,35,169,33,1,208,208,208,1,182,233,255,1,198,238,255,1,221,245,255, + 1,208,208,208,8,248,251,253,1,149,223,255,1,148,223,255,1,35,169,33, + 1,163,228,255,1,35,169,33,1,163,228,255,1,35,169,33,1,163,228,255, + 1,35,169,33,1,163,228,255,1,35,169,33,1,163,228,255,1,225,246,255, + 1,241,250,255,1,248,251,253,1,208,208,208,8,215,234,243,1,136,214,247, + 1,143,219,251,1,35,169,33,1,255,255,255,1,35,169,33,1,255,255,255, + 1,35,169,33,1,255,255,255,1,35,169,33,1,255,255,255,1,35,169,33, + 1,255,255,255,1,244,249,251,1,231,243,248,1,215,234,243,1,208,208,208, + 8,181,217,233,1,115,199,235,1,123,205,239,1,35,169,33,1,181,217,233, + 1,35,169,33,1,181,217,233,1,35,169,33,1,181,217,233,1,35,169,33, + 1,181,217,233,1,35,169,33,1,181,217,233,1,210,232,241,1,197,225,238, + 1,181,217,233,1,208,208,208,8,148,200,223,1,94,185,223,1,102,190,227, + 1,35,169,33,1,109,180,212,1,35,169,33,1,109,180,212,1,35,169,33, + 1,109,180,212,1,35,169,33,1,109,180,212,1,35,169,33,1,109,180,212, + 1,175,214,231,1,163,208,227,1,148,200,223,1,208,208,208,8,115,184,214, + 1,74,171,211,1,81,176,215,1,35,169,33,1,36,143,190,1,35,169,33, + 1,36,143,190,1,35,169,33,1,36,143,190,1,35,169,33,1,36,143,190, + 1,35,169,33,1,36,143,190,1,141,197,221,1,128,190,217,1,115,184,214, + 1,208,208,208,8,82,167,204,1,53,156,199,1,62,161,204,1,35,169,33, + 1,208,208,208,1,35,169,33,1,208,208,208,1,35,169,33,1,208,208,208, + 1,35,169,33,1,208,208,208,1,35,169,33,1,208,208,208,1,107,179,212, + 1,94,173,207,1,82,167,204,1,208,208,208,8,49,150,194,1,33,142,187, + 1,36,146,194,1,208,208,208,10,73,158,206,1,60,155,197,1,49,150,194, + 1,208,208,208,8,16,133,184,1,12,126,177,1,208,208,208,12,24,138,186, + 1,16,133,184,1,208,208,208,100,156,1,0,0,0,0,0,101,208,208,208, + 1,124,124,124,1,7,7,7,1,0,0,0,21,32,32,32,1,176,176,176, + 1,219,219,219,1,73,73,73,1,0,0,0,22,73,73,73,1,219,219,219, + 1,176,176,176,1,32,32,32,1,0,0,0,21,7,7,7,1,124,124,124, + 1,236,236,236,1,124,124,124,1,7,7,7,1,0,0,0,21,32,32,32, + 1,175,175,175,1,219,219,219,1,73,73,73,1,0,0,0,14,255,255,255, + 1,85,85,85,1,0,0,0,6,73,73,73,1,219,219,219,1,176,176,176, + 1,32,32,32,1,0,0,0,2,85,85,85,1,255,255,255,1,0,0,0, + 8,255,255,255,1,234,234,234,1,21,21,21,1,0,0,0,6,7,7,7, + 1,124,124,124,1,208,208,208,1,0,0,0,1,21,21,21,1,234,234,234, + 1,255,255,255,1,0,0,0,8,255,255,255,2,170,170,170,1,255,255,255, + 1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0, + 1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,170,170,170, + 1,255,255,255,2,0,0,0,8,255,255,255,16,0,0,0,8,255,255,255, + 16,0,0,0,8,255,255,255,16,0,0,0,8,255,255,255,16,0,0,0, + 8,255,255,255,16,0,0,0,8,255,255,255,2,170,170,170,1,255,255,255, + 1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0, + 1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,170,170,170, + 1,255,255,255,2,0,0,0,8,255,255,255,1,234,234,234,1,21,21,21, + 1,0,0,0,10,21,21,21,1,234,234,234,1,255,255,255,1,0,0,0, + 8,255,255,255,1,85,85,85,1,0,0,0,12,85,85,85,1,255,255,255, + 1,0,0,0,100,0,0) + ); + +const + objdata_tframecomp: record size: integer; data: array[0..1469] of byte end = + (size: 1470; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,102,114, + 97,109,101,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,72,5,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,156,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4, + 208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1, + 0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,2,255,255,255,20, + 208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102,102,102,19, + 208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,1,102,102,102,1, + 208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,2,0,0,0,1, + 208,208,208,1,255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1, + 102,102,102,1,208,208,208,1,0,0,0,2,208,208,208,1,255,255,255,1, + 102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,1, + 0,0,0,1,208,208,208,2,255,255,255,1,102,102,102,1,208,208,208,16, + 255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,1,208,208,208,2, + 255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1, + 208,208,208,1,0,0,0,2,208,208,208,1,255,255,255,1,102,102,102,1, + 208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,2,0,0,0,1, + 208,208,208,1,255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1, + 102,102,102,1,208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,1, + 102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,1, + 0,0,0,2,208,208,208,1,255,255,255,1,102,102,102,1,208,208,208,16, + 255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,1,208,208,208,2, + 255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1, + 208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102,102,102,1, + 208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,2, + 208,208,208,1,255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1, + 102,102,102,1,208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,1, + 102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,2, + 0,0,0,1,208,208,208,1,255,255,255,1,102,102,102,1,208,208,208,16, + 255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,2,208,208,208,1, + 255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1, + 208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102,102,102,1, + 208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,1, + 208,208,208,2,255,255,255,19,102,102,102,1,208,208,208,1,0,0,0,2, + 208,208,208,1,102,102,102,20,208,208,208,2,0,0,0,1,208,208,208,22, + 0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,4, + 208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,3,116,2,0,0, + 240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2, + 150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1, + 0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1,0,0,0,1, + 7,7,7,1,240,240,240,1,52,52,52,1,0,0,0,22,240,240,240,1, + 0,0,0,2,255,255,255,20,0,0,0,1,202,202,202,1,0,0,0,2, + 255,255,255,20,0,0,0,2,217,217,217,1,0,0,0,1,255,255,255,2, + 0,0,0,16,255,255,255,2,0,0,0,2,240,240,240,1,0,0,0,1, + 255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,1,75,75,75,1, + 225,225,225,1,0,0,0,1,255,255,255,2,0,0,0,16,255,255,255,2, + 0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,2,0,0,0,16, + 255,255,255,2,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,2, + 0,0,0,16,255,255,255,2,0,0,0,1,135,135,135,1,45,45,45,1, + 0,0,0,1,255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,2, + 240,240,240,1,0,0,0,1,255,255,255,2,0,0,0,16,255,255,255,2, + 0,0,0,2,240,240,240,1,0,0,0,1,255,255,255,2,0,0,0,16, + 255,255,255,2,0,0,0,1,135,135,135,1,165,165,165,1,0,0,0,1, + 255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,1,240,240,240,1, + 0,0,0,2,255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,1, + 240,240,240,1,0,0,0,2,255,255,255,2,0,0,0,16,255,255,255,2, + 0,0,0,1,75,75,75,1,105,105,105,1,0,0,0,1,255,255,255,2, + 0,0,0,16,255,255,255,2,0,0,0,2,240,240,240,1,0,0,0,1, + 255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,2,240,240,240,1, + 0,0,0,1,255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,1, + 202,202,202,1,97,97,97,1,0,0,0,1,255,255,255,2,0,0,0,16, + 255,255,255,2,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,2, + 0,0,0,16,255,255,255,2,0,0,0,1,240,240,240,1,0,0,0,2, + 255,255,255,20,0,0,0,1,7,7,7,1,172,172,172,1,0,0,0,1, + 255,255,255,20,0,0,0,2,240,240,240,1,0,0,0,22,22,22,22,1, + 240,240,240,1,37,37,37,1,0,0,0,2,232,232,232,1,240,240,240,1, + 210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1, + 0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2, + 187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tfacecomp: record size: integer; data: array[0..2460] of byte end = + (size: 2461; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,102,97, + 99,101,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,40,9,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,96,7,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1,0, + 0,0,3,22,240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0, + 0,0,1,208,208,208,1,22,240,255,3,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13, + 129,255,2,0,0,0,1,208,208,208,1,22,240,255,3,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,13,129,255,2,208,208,208,1,0,0,0,1,22,240,255,3,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,13,129,255,2,208,208,208,1,0,0,0,1,22, + 240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0,0,0,2,22, + 240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0,0,0,1,208, + 208,208,1,22,240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0, + 0,0,1,208,208,208,1,22,240,255,3,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13, + 129,255,2,0,0,0,2,22,240,255,3,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13, + 129,255,2,208,208,208,1,0,0,0,1,22,240,255,3,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,13,129,255,2,208,208,208,1,0,0,0,1,22,240,255,3,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,13,129,255,2,0,0,0,2,22,240,255,3,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,13,129,255,2,0,0,0,1,208,208,208,1,22, + 240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0,0,0,1,208, + 208,208,1,22,240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0, + 0,0,2,22,240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,208, + 208,208,1,0,0,0,1,22,240,255,3,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13, + 129,255,2,208,208,208,1,0,0,0,1,22,240,255,3,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,13,129,255,2,0,0,0,2,22,240,255,3,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,13,129,255,2,0,0,0,1,208,208,208,1,22,240,255,3,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,13,129,255,2,0,0,0,1,208,208,208,1,22, + 240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0,0,0,2,22, + 240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,208,208,208,1,0, + 0,0,1,22,240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0, + 0,0,3,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,3,144,1,0,0,240, + 240,240,2,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150, + 150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0, + 0,0,2,187,187,187,1,240,240,240,2,22,22,22,1,0,0,0,1,7, + 7,7,1,240,240,240,1,52,52,52,1,255,255,255,22,240,240,240,1,0, + 0,0,1,255,255,255,22,202,202,202,1,0,0,0,1,255,255,255,22,0, + 0,0,1,217,217,217,1,255,255,255,22,0,0,0,1,240,240,240,1,255, + 255,255,22,75,75,75,1,225,225,225,1,255,255,255,22,240,240,240,1,0, + 0,0,1,255,255,255,22,240,240,240,1,0,0,0,1,255,255,255,22,135, + 135,135,1,45,45,45,1,255,255,255,22,0,0,0,1,240,240,240,1,255, + 255,255,22,0,0,0,1,240,240,240,1,255,255,255,22,135,135,135,1,165, + 165,165,1,255,255,255,22,240,240,240,1,0,0,0,1,255,255,255,22,240, + 240,240,1,0,0,0,1,255,255,255,22,75,75,75,1,105,105,105,1,255, + 255,255,22,0,0,0,1,240,240,240,1,255,255,255,22,0,0,0,1,240, + 240,240,1,255,255,255,22,202,202,202,1,97,97,97,1,255,255,255,22,240, + 240,240,1,0,0,0,1,255,255,255,22,240,240,240,1,0,0,0,1,255, + 255,255,22,7,7,7,1,172,172,172,1,255,255,255,22,0,0,0,1,240, + 240,240,1,255,255,255,22,22,22,22,1,240,240,240,1,37,37,37,1,0, + 0,0,2,232,232,232,1,240,240,240,1,210,210,210,1,0,0,0,2,60, + 60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240, + 240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,0, + 0) + ); + +const + objdata_tfontcomp: record size: integer; data: array[0..2316] of byte end = + (size: 2317; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,102,111, + 110,116,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,152,8,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,220,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1,0, + 0,0,3,208,208,208,22,0,0,0,1,208,208,208,2,0,0,0,6,208, + 208,208,15,0,0,0,1,208,208,208,2,0,0,0,6,208,208,208,12,0, + 0,0,2,208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,2,208, + 208,208,6,0,0,0,1,208,208,208,3,0,0,0,1,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,1,208, + 208,208,1,0,0,0,2,208,208,208,4,0,0,0,5,208,208,208,1,0, + 0,0,8,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,8,208, + 208,208,1,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,2,208, + 208,208,4,0,0,0,2,208,208,208,2,0,0,0,4,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208, + 208,208,2,0,0,0,2,208,208,208,4,0,0,0,2,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,4,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,1,208,208,208,1,0, + 0,0,2,208,208,208,6,0,0,0,2,208,208,208,2,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,3,208,208,208,1,0, + 0,0,1,208,208,208,22,0,0,0,2,208,208,208,22,0,0,0,1,208, + 208,208,2,0,0,0,2,208,208,208,15,0,0,0,2,208,208,208,2,0, + 0,0,1,208,208,208,2,0,0,0,2,208,208,208,15,0,0,0,2,208, + 208,208,2,0,0,0,19,208,208,208,1,0,0,0,2,208,208,208,3,0, + 0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,16,208, + 208,208,3,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0, + 0,0,1,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,10,208,208,208,2,0,0,0,1,208,208,208,2,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,7,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,12,0, + 0,0,2,208,208,208,9,0,0,0,1,208,208,208,12,0,0,0,2,208, + 208,208,8,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2,0, + 0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,3,132, + 5,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1,240, + 240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90, + 90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1,0, + 0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0,22,240, + 240,240,1,0,0,0,2,2,2,2,1,8,8,8,4,4,4,4,1,0, + 0,0,15,202,202,202,1,0,0,0,2,94,94,94,1,238,238,238,1,216, + 216,216,3,115,115,115,1,0,0,0,12,123,123,123,1,5,5,5,1,0, + 0,0,2,217,217,217,1,0,0,0,1,94,94,94,1,145,145,145,1,0, + 0,0,6,10,10,10,1,0,0,0,3,5,5,5,1,0,0,0,1,9, + 9,9,1,5,5,5,1,0,0,0,1,4,4,4,1,218,218,218,1,14, + 14,14,1,0,0,0,2,240,240,240,1,0,0,0,1,94,94,94,1,145, + 145,145,1,0,0,0,4,10,10,10,1,170,170,170,1,182,182,182,1,190, + 190,190,1,92,92,92,1,0,0,0,1,176,176,176,1,136,136,136,1,164, + 164,164,1,225,225,225,1,59,59,59,1,88,88,88,1,243,243,243,1,166, + 166,166,1,0,0,0,1,75,75,75,1,225,225,225,1,0,0,0,1,94, + 94,94,1,238,238,238,1,216,216,216,3,1,1,1,1,118,118,118,1,147, + 147,147,1,0,0,0,1,8,8,8,1,219,219,219,1,3,3,3,1,176, + 176,176,1,121,121,121,1,0,0,0,1,93,93,93,1,145,145,145,1,0, + 0,0,1,217,217,217,1,6,6,6,1,0,0,0,1,240,240,240,1,0, + 0,0,2,94,94,94,1,145,145,145,1,0,0,0,4,155,155,155,1,82, + 82,82,1,0,0,0,2,187,187,187,1,53,53,53,1,176,176,176,1,60, + 60,60,1,0,0,0,1,72,72,72,1,151,151,151,1,0,0,0,1,217, + 217,217,1,6,6,6,1,0,0,0,1,240,240,240,1,0,0,0,2,94, + 94,94,1,145,145,145,1,0,0,0,4,92,92,92,1,128,128,128,1,0, + 0,0,1,1,1,1,1,233,233,233,1,23,23,23,1,176,176,176,1,55, + 55,55,1,0,0,0,1,72,72,72,1,151,151,151,1,0,0,0,1,216, + 216,216,1,7,7,7,1,0,0,0,1,135,135,135,1,45,45,45,1,0, + 0,0,1,94,94,94,1,145,145,145,1,0,0,0,4,14,14,14,1,199, + 199,199,1,135,135,135,1,178,178,178,1,153,153,153,1,0,0,0,1,176, + 176,176,1,55,55,55,1,0,0,0,1,72,72,72,1,151,151,151,1,0, + 0,0,1,192,192,192,1,148,148,148,1,0,0,0,2,240,240,240,1,0, + 0,0,1,23,23,23,1,36,36,36,1,0,0,0,6,60,60,60,1,47, + 47,47,1,0,0,0,2,44,44,44,1,13,13,13,1,0,0,0,1,18, + 18,18,1,37,37,37,1,0,0,0,1,21,21,21,1,71,71,71,1,2, + 2,2,1,0,0,0,1,240,240,240,1,0,0,0,22,135,135,135,1,165, + 165,165,1,0,0,0,22,240,240,240,1,0,0,0,2,16,16,16,1,56, + 56,56,1,0,0,0,15,118,118,118,1,56,56,56,1,0,0,0,2,240, + 240,240,1,0,0,0,2,94,94,94,1,129,129,129,1,0,0,0,15,151, + 151,151,1,72,72,72,1,0,0,0,2,75,75,75,1,105,105,105,1,4, + 4,4,1,210,210,210,1,220,220,220,1,75,75,75,1,147,147,147,1,120, + 120,120,1,196,196,196,1,157,157,157,1,46,46,46,1,165,165,165,1,157, + 157,157,1,5,5,5,1,49,49,49,1,145,145,145,1,179,179,179,1,183, + 183,183,1,70,70,70,1,0,0,0,1,151,151,151,1,72,72,72,1,0, + 0,0,3,240,240,240,1,0,0,0,1,94,94,94,1,129,129,129,1,0, + 0,0,1,189,189,189,1,126,126,126,1,3,3,3,1,191,191,191,1,163, + 163,163,1,3,3,3,1,155,155,155,1,73,73,73,1,63,63,63,1,241, + 241,241,1,29,29,29,1,23,23,23,1,224,224,224,1,18,18,18,1,151, + 151,151,1,72,72,72,1,0,0,0,3,240,240,240,1,0,0,0,1,94, + 94,94,1,129,129,129,1,0,0,0,1,189,189,189,1,53,53,53,1,0, + 0,0,1,149,149,149,1,82,82,82,1,0,0,0,1,125,125,125,1,106, + 106,106,1,63,63,63,1,174,174,174,1,0,0,0,2,169,169,169,1,70, + 70,70,1,151,151,151,1,72,72,72,1,0,0,0,2,202,202,202,1,97, + 97,97,1,0,0,0,1,94,94,94,1,129,129,129,1,0,0,0,1,189, + 189,189,1,42,42,42,1,0,0,0,1,149,149,149,1,74,74,74,1,0, + 0,0,1,125,125,125,1,106,106,106,1,63,63,63,1,186,186,186,1,0, + 0,0,2,192,192,192,1,51,51,51,1,151,151,151,1,72,72,72,1,0, + 0,0,2,240,240,240,1,0,0,0,2,82,82,82,1,178,178,178,1,31, + 31,31,1,189,189,189,1,42,42,42,1,0,0,0,1,149,149,149,1,74, + 74,74,1,0,0,0,1,125,125,125,1,106,106,106,1,63,63,63,1,247, + 247,247,1,88,88,88,1,97,97,97,1,201,201,201,1,4,4,4,1,151, + 151,151,1,72,72,72,1,0,0,0,2,240,240,240,1,0,0,0,2,10, + 10,10,1,123,123,123,1,67,67,67,1,94,94,94,1,21,21,21,1,0, + 0,0,1,74,74,74,1,37,37,37,1,0,0,0,1,62,62,62,1,53, + 53,53,1,63,63,63,1,178,178,178,1,122,122,122,1,124,124,124,1,23, + 23,23,1,0,0,0,1,75,75,75,1,36,36,36,1,0,0,0,2,7, + 7,7,1,172,172,172,1,0,0,0,12,63,63,63,1,168,168,168,1,0, + 0,0,9,240,240,240,1,0,0,0,12,33,33,33,1,89,89,89,1,0, + 0,0,8,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232, + 232,232,1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240, + 240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90, + 90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tactivator: record size: integer; data: array[0..1465] of byte end = + (size: 1466; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,97,99, + 116,105,118,97,116,111,114,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,68,5,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,56,3,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,208,208,208,128,70,209,70,1,82,220,80,1, + 88,222,85,1,94,222,90,1,98,223,96,1,102,223,101,1,107,223,105,1, + 106,213,106,1,208,208,208,15,71,217,71,1,77,219,75,1,82,220,80,1, + 88,221,85,1,93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1, + 110,217,106,1,105,203,105,1,0,0,0,1,208,208,208,12,67,217,63,1, + 72,218,69,1,77,219,75,1,82,220,80,1,88,221,85,1,93,222,90,1, + 98,223,96,1,103,224,101,1,109,225,106,1,114,226,111,1,118,226,116,1, + 87,159,84,1,0,0,0,1,208,208,208,10,70,209,70,1,67,217,63,1, + 72,218,69,1,77,219,75,1,82,220,80,1,88,221,85,1,93,222,90,1, + 98,223,96,1,103,224,101,1,109,225,106,1,114,226,111,1,119,227,117,1, + 114,211,113,1,34,57,28,1,0,0,0,1,208,208,208,9,63,216,58,1, + 67,217,64,1,72,218,69,1,77,219,75,1,82,220,80,1,88,221,85,1, + 93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1,114,226,111,1, + 119,227,117,1,124,228,122,1,84,149,83,1,0,0,0,1,208,208,208,9, + 62,216,59,1,67,217,64,1,72,218,69,1,77,219,75,1,82,220,80,1, + 88,221,85,1,93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1, + 114,226,111,1,119,227,117,1,124,228,122,1,104,184,102,1,0,0,0,2, + 208,208,208,8,62,216,59,1,67,217,64,1,72,218,69,1,77,219,75,1, + 82,220,80,1,88,221,85,1,93,222,90,1,98,223,96,1,103,224,101,1, + 109,225,106,1,114,226,111,1,119,227,117,1,124,228,122,1,122,216,120,1, + 0,0,0,2,208,208,208,8,62,216,59,1,67,217,64,1,72,218,69,1, + 77,219,75,1,82,220,80,1,88,221,85,1,93,222,90,1,98,223,96,1, + 103,224,101,1,109,225,106,1,114,226,111,1,119,227,117,1,124,228,122,1, + 122,216,120,1,0,0,0,2,208,208,208,8,62,215,59,1,67,217,64,1, + 72,218,69,1,77,219,75,1,82,220,80,1,88,221,85,1,93,222,90,1, + 98,223,96,1,103,224,101,1,109,225,106,1,114,226,111,1,119,227,117,1, + 124,228,122,1,104,184,102,1,0,0,0,2,208,208,208,8,62,214,58,1, + 67,217,64,1,72,218,69,1,77,219,75,1,82,220,80,1,88,221,85,1, + 93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1,114,226,111,1, + 119,227,117,1,124,228,122,1,79,140,78,1,0,0,0,2,208,208,208,8, + 64,191,64,1,64,208,61,1,72,218,69,1,77,219,75,1,82,220,80,1, + 88,221,85,1,93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1, + 114,226,111,1,119,227,117,1,114,210,113,1,11,18,9,1,0,0,0,2, + 208,208,208,9,61,198,57,1,71,217,68,1,77,219,75,1,82,220,80,1, + 88,221,85,1,93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1, + 114,226,111,1,118,226,116,1,46,84,44,1,0,0,0,2,208,208,208,10, + 0,0,0,1,49,151,49,1,71,203,69,1,82,220,80,1,88,221,85,1, + 93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1,105,208,102,1, + 43,82,43,1,0,0,0,3,208,208,208,11,0,0,0,1,17,51,17,1, + 53,143,52,1,71,178,69,1,88,209,85,1,92,210,90,1,83,180,82,1, + 66,137,65,1,9,18,9,1,0,0,0,3,208,208,208,13,0,0,0,10, + 208,208,208,16,0,0,0,6,208,208,208,80,212,1,0,0,0,0,0,128, + 11,11,11,1,118,118,118,1,176,176,176,1,229,229,229,2,177,177,177,1, + 119,119,119,1,12,12,12,1,0,0,0,15,61,61,61,1,221,221,221,1, + 255,255,255,6,230,230,230,1,68,68,68,1,1,1,1,1,0,0,0,12, + 61,61,61,1,253,253,253,1,255,255,255,8,254,254,254,1,88,88,88,1, + 1,1,1,1,0,0,0,10,11,11,11,1,221,221,221,1,255,255,255,10, + 239,239,239,1,45,45,45,1,1,1,1,1,0,0,0,9,118,118,118,1, + 255,255,255,12,182,182,182,1,8,8,8,1,0,0,0,9,176,176,176,1, + 255,255,255,12,219,219,219,1,64,64,64,1,1,1,1,1,0,0,0,8, + 229,229,229,1,255,255,255,12,243,243,243,1,96,96,96,1,2,2,2,1, + 0,0,0,8,229,229,229,1,255,255,255,12,243,243,243,1,124,124,124,1, + 2,2,2,1,0,0,0,8,177,177,177,1,255,255,255,12,219,219,219,1, + 124,124,124,1,2,2,2,1,0,0,0,8,119,119,119,1,255,255,255,12, + 193,193,193,1,96,96,96,1,2,2,2,1,0,0,0,8,12,12,12,1, + 230,230,230,1,255,255,255,10,240,240,240,1,143,143,143,1,64,64,64,1, + 1,1,1,1,0,0,0,9,67,67,67,1,254,254,254,1,255,255,255,8, + 254,254,254,1,167,167,167,1,119,119,119,1,8,8,8,1,0,0,0,10, + 1,1,1,1,88,88,88,1,239,239,239,1,255,255,255,6,240,240,240,1, + 167,167,167,1,136,136,136,1,36,36,36,1,1,1,1,1,0,0,0,11, + 1,1,1,1,45,45,45,1,182,182,182,1,219,219,219,1,243,243,243,2, + 219,219,219,1,193,193,193,1,143,143,143,1,119,119,119,1,36,36,36,1, + 1,1,1,1,0,0,0,13,1,1,1,1,9,9,9,1,64,64,64,1, + 96,96,96,1,124,124,124,2,96,96,96,1,64,64,64,1,9,9,9,1, + 1,1,1,1,0,0,0,16,1,1,1,1,2,2,2,4,1,1,1,1, + 0,0,0,80,0,0) + ); + +const + objdata_tpostscriptprinter: record size: integer; data: array[0..2129] of byte end = + (size: 2130; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,112,111, + 115,116,115,99,114,105,112,116,112,114,105,110,116,101,114,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 212,7,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 236,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, + 1,1,1,1,18,18,18,1,131,131,131,1,208,208,208,2,146,146,146,1, + 29,29,29,1,4,4,4,1,38,38,38,1,157,157,157,1,208,208,208,12, + 0,0,0,1,208,208,208,2,163,163,163,1,15,15,15,1,208,208,208,2, + 17,17,17,1,153,153,153,1,203,203,203,1,144,144,144,1,24,24,24,1, + 208,208,208,12,0,0,0,1,208,208,208,1,206,206,206,1,155,155,155,1, + 18,18,18,1,208,208,208,2,38,38,38,1,124,124,124,1,196,196,196,1, + 208,208,208,14,0,0,0,3,21,21,21,1,136,136,136,1,208,208,208,2, + 191,191,191,1,101,101,101,1,44,44,44,1,47,47,47,1,160,160,160,1, + 208,208,208,12,0,0,0,1,208,208,208,9,175,175,175,1,21,21,21,1, + 208,208,208,12,0,0,0,1,208,208,208,6,24,24,24,1,142,142,142,1, + 204,204,204,1,166,166,166,1,22,22,22,1,208,208,208,12,0,0,0,1, + 208,208,208,6,156,156,156,1,37,37,37,1,4,4,4,1,26,66,69,1, + 63,162,172,1,74,172,182,5,62,145,153,1,43,147,157,1,0,122,133,1, + 208,208,208,14,33,144,155,1,146,210,217,1,162,227,233,1,177,248,255,1, + 169,236,243,1,177,248,255,2,120,168,173,1,169,242,250,1,55,159,169,1, + 18,134,140,1,208,208,208,13,48,152,164,1,113,159,163,1,140,196,202,1, + 130,182,187,1,118,165,170,1,177,248,255,1,168,235,242,1,103,144,148,1, + 121,170,175,1,119,169,174,1,40,126,134,1,0,128,128,1,208,208,208,12, + 72,164,173,1,191,232,237,1,205,250,255,1,177,216,220,1,187,227,232,1, + 205,250,255,5,76,167,176,1,208,208,208,12,0,128,128,1,71,125,129,1, + 154,166,167,1,183,197,199,1,192,206,208,1,193,207,209,1,235,253,255,1, + 197,212,214,1,189,203,205,1,194,208,210,1,235,253,255,1,71,159,167,1, + 208,208,208,12,37,139,148,1,166,194,197,1,244,253,255,1,216,224,226,1, + 199,206,208,1,213,221,223,1,244,253,255,1,208,215,217,1,203,210,212,1, + 190,197,199,1,173,210,215,1,39,140,150,1,208,208,208,11,0,128,128,1, + 67,160,168,1,147,175,179,1,162,193,197,1,185,221,225,1,175,208,212,1, + 210,250,255,1,193,229,234,1,195,232,237,1,184,219,223,1,204,246,252,1, + 53,148,157,1,115,115,115,2,119,119,119,1,208,208,208,8,0,0,0,1, + 77,145,153,1,140,220,230,1,146,204,211,1,175,245,253,1,145,203,210,1, + 137,193,199,1,176,247,255,1,165,232,239,1,146,205,212,1,152,213,220,1, + 97,183,192,1,191,207,208,1,220,220,220,1,171,171,171,1,144,144,144,1, + 208,208,208,7,158,158,158,1,188,188,189,1,56,153,162,1,93,192,203,1, + 92,191,201,1,92,190,200,1,91,189,199,1,90,188,198,1,89,187,197,1, + 89,186,197,1,88,186,196,1,84,182,192,1,123,186,192,1,235,235,235,1, + 170,170,170,1,178,178,178,1,155,155,155,1,208,208,208,5,151,151,151,1, + 185,185,185,1,230,230,230,1,238,239,239,1,218,229,230,1,220,230,231,1, + 221,230,231,1,223,231,232,1,224,232,233,1,226,233,234,1,228,234,235,1, + 229,235,235,1,231,236,236,1,232,236,236,1,221,221,222,1,160,160,160,1, + 187,187,187,1,188,188,188,1,155,155,155,1,208,208,208,4,139,139,139,1, + 160,160,160,1,177,177,177,1,179,179,179,1,181,181,181,1,182,182,182,9, + 181,181,181,1,158,158,158,1,188,188,188,3,155,155,155,1,208,208,208,4, + 146,146,146,1,187,187,187,1,203,203,203,1,219,219,219,1,235,235,235,1, + 241,241,241,1,243,243,243,1,244,244,244,1,246,246,246,1,247,247,247,1, + 248,248,248,1,125,253,136,2,189,253,194,1,232,232,232,1,167,167,167,1, + 188,188,188,2,187,187,187,1,149,149,149,1,208,208,208,4,146,146,146,1, + 187,187,187,1,203,203,203,1,219,219,219,1,235,235,235,1,241,241,241,1, + 243,243,243,1,244,244,244,1,246,246,246,1,247,247,247,1,248,248,248,1, + 0,255,21,2,126,254,137,1,232,232,232,1,167,167,167,1,188,188,188,2, + 158,158,158,1,109,109,109,1,208,208,208,4,146,146,146,1,187,187,187,1, + 203,203,203,1,219,219,219,1,235,235,235,1,241,241,241,1,243,243,243,1, + 244,244,244,1,246,246,246,1,247,247,247,1,248,248,248,1,0,0,255,2, + 126,126,254,1,232,232,232,1,167,167,167,1,188,188,188,1,141,141,141,1, + 14,14,14,1,0,0,0,1,208,208,208,4,146,146,146,1,187,187,187,1, + 203,203,203,1,219,219,219,1,235,235,235,1,241,241,241,1,243,243,243,1, + 244,244,244,1,246,246,246,1,247,247,247,1,248,248,248,1,125,125,253,2, + 189,189,253,1,232,232,232,1,167,167,167,1,149,149,149,1,27,27,27,1, + 0,0,0,2,208,208,208,4,128,128,128,1,156,156,156,1,169,169,169,1, + 183,183,183,1,196,196,196,1,201,201,201,1,203,203,203,2,205,205,205,1, + 206,206,206,1,207,207,207,1,208,208,208,1,209,209,209,1,210,210,210,1, + 193,193,193,1,144,144,144,1,41,41,41,1,0,0,0,2,208,208,208,5, + 115,115,115,1,118,118,118,1,108,108,108,1,107,107,107,1,112,112,112,1, + 115,115,115,1,116,116,116,3,117,117,117,5,119,119,119,1,67,67,67,1, + 0,0,0,2,208,208,208,7,0,0,0,16,208,208,208,4,176,2,0,0, + 255,255,255,2,254,254,254,1,233,233,233,1,95,95,95,1,0,0,0,2, + 76,76,76,1,219,219,219,1,250,250,250,1,209,209,209,1,62,62,62,1, + 0,0,0,12,255,255,255,1,0,0,0,2,55,55,55,1,236,236,236,1, + 0,0,0,2,234,234,234,1,68,68,68,1,6,6,6,1,79,79,79,1, + 225,225,225,1,0,0,0,12,255,255,255,1,0,0,0,1,2,2,2,1, + 65,65,65,1,233,233,233,1,0,0,0,2,209,209,209,1,103,103,103,1, + 15,15,15,1,0,0,0,14,255,255,255,3,229,229,229,1,88,88,88,1, + 0,0,0,2,21,21,21,1,131,131,131,1,201,201,201,1,197,197,197,1, + 59,59,59,1,0,0,0,12,255,255,255,1,0,0,0,9,41,41,41,1, + 229,229,229,1,0,0,0,12,255,255,255,1,0,0,0,6,226,226,226,1, + 81,81,81,1,5,5,5,1,52,52,52,1,228,228,228,1,0,0,0,12, + 255,255,255,1,0,0,0,6,64,64,64,1,210,210,210,1,250,250,250,1, + 230,230,230,1,233,233,233,1,220,220,220,5,225,225,225,1,203,203,203,1, + 23,23,23,1,0,0,0,14,145,145,145,1,255,255,255,8,216,216,216,1, + 42,42,42,1,0,0,0,13,176,176,176,1,255,255,255,9,225,225,225,1, + 2,2,2,1,0,0,0,12,197,197,197,1,255,255,255,9,206,206,206,1, + 0,0,0,12,4,4,4,1,227,227,227,1,255,255,255,9,183,183,183,1, + 0,0,0,12,110,110,110,1,250,250,250,1,255,255,255,8,245,245,245,1, + 104,104,104,1,0,0,0,11,2,2,2,1,206,206,206,1,255,255,255,9, + 203,203,203,1,40,40,40,2,45,45,45,1,0,0,0,8,1,1,1,1, + 165,165,165,1,253,253,253,1,255,255,255,11,238,238,238,1,195,195,195,1, + 0,0,0,7,84,84,84,1,194,194,194,1,255,255,255,12,231,231,231,1, + 251,251,251,1,168,168,168,1,0,0,0,5,64,64,64,1,181,181,181,1, + 250,250,250,1,255,255,255,11,246,246,246,1,231,231,231,1,255,255,255,2, + 168,168,168,1,0,0,0,4,161,161,161,1,228,228,228,1,225,225,225,12, + 230,230,230,1,239,239,239,1,255,255,255,3,168,168,168,1,0,0,0,4, + 168,168,168,1,255,255,255,18,149,149,149,1,0,0,0,4,168,168,168,1, + 255,255,255,17,184,184,184,1,7,7,7,1,0,0,0,4,168,168,168,1, + 255,255,255,16,229,229,229,1,147,147,147,1,77,77,77,1,0,0,0,4, + 168,168,168,1,255,255,255,15,235,235,235,1,154,154,154,1,92,92,92,1, + 1,1,1,1,0,0,0,4,175,175,175,1,255,255,255,14,245,245,245,1, + 161,161,161,1,105,105,105,1,4,4,4,1,0,0,0,5,135,135,135,1, + 183,183,183,1,211,211,211,1,223,223,223,11,228,228,228,1,181,181,181,1, + 116,116,116,1,9,9,9,1,0,0,0,7,21,21,21,1,70,70,70,14, + 15,15,15,1,0,0,0,4,0,0) + ); + +const + objdata_tgdiprinter: record size: integer; data: array[0..2314] of byte end = + (size: 2315; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,103,100, + 105,112,114,105,110,116,101,114,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,148,8,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,76,5,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,208,208,208,1,142,142,142,1,4,4,4, + 1,6,6,6,1,151,151,151,1,208,208,208,3,0,0,0,2,4,4,4, + 1,142,142,142,1,208,208,208,3,0,0,0,1,208,208,208,8,142,142,142, + 1,8,8,8,1,142,142,142,1,157,157,157,1,31,31,31,1,158,158,158, + 1,208,208,208,2,0,0,0,1,208,208,208,1,142,142,142,1,8,8,8, + 1,142,142,142,1,208,208,208,2,0,0,0,1,208,208,208,8,4,4,4, + 1,142,142,142,1,208,208,208,2,194,194,194,1,201,201,201,1,208,208,208, + 2,0,0,0,1,208,208,208,2,142,142,142,1,4,4,4,1,208,208,208, + 2,0,0,0,1,208,208,208,8,0,0,0,1,208,208,208,2,0,0,0, + 3,208,208,208,2,0,0,0,1,208,208,208,3,0,0,0,1,208,208,208, + 2,0,0,0,1,208,208,208,8,4,4,4,1,142,142,142,1,208,208,208, + 2,142,142,142,1,4,4,4,1,208,208,208,2,0,0,0,1,208,208,208, + 2,142,142,142,1,4,4,4,1,208,208,208,2,0,0,0,1,208,208,208, + 8,142,142,142,1,8,8,8,1,142,142,142,2,8,8,8,1,142,142,142, + 1,208,208,208,2,0,0,0,1,208,208,208,1,142,142,142,1,8,8,8, + 1,142,142,142,1,208,208,208,2,0,0,0,1,208,208,208,9,142,142,142, + 1,4,4,4,2,142,142,142,1,208,208,208,3,0,0,0,2,9,45,48, + 1,63,161,171,1,74,172,182,3,64,148,157,1,74,172,182,1,62,145,153, + 1,43,147,157,1,0,122,133,1,208,208,208,14,33,144,155,1,146,210,217, + 1,162,227,233,1,177,248,255,1,169,236,243,1,177,248,255,2,120,168,173, + 1,169,242,250,1,55,159,169,1,18,134,140,1,208,208,208,13,48,152,164, + 1,113,159,163,1,140,196,202,1,130,182,187,1,118,165,170,1,177,248,255, + 1,168,235,242,1,103,144,148,1,121,170,175,1,119,169,174,1,40,126,134, + 1,0,128,128,1,208,208,208,12,72,164,173,1,191,232,237,1,205,250,255, + 1,177,216,220,1,187,227,232,1,205,250,255,5,76,167,176,1,208,208,208, + 12,0,128,128,1,71,125,129,1,154,166,167,1,183,197,199,1,192,206,208, + 1,193,207,209,1,235,253,255,1,197,212,214,1,189,203,205,1,194,208,210, + 1,235,253,255,1,71,159,167,1,208,208,208,12,37,139,148,1,166,194,197, + 1,244,253,255,1,216,224,226,1,199,206,208,1,213,221,223,1,244,253,255, + 1,208,215,217,1,203,210,212,1,190,197,199,1,173,210,215,1,39,140,150, + 1,208,208,208,11,0,128,128,1,67,160,168,1,147,175,179,1,162,193,197, + 1,185,221,225,1,175,208,212,1,210,250,255,1,193,229,234,1,195,232,237, + 1,184,219,223,1,204,246,252,1,53,148,157,1,115,115,115,2,119,119,119, + 1,208,208,208,8,0,0,0,1,77,145,153,1,140,220,230,1,146,204,211, + 1,175,245,253,1,145,203,210,1,137,193,199,1,176,247,255,1,165,232,239, + 1,146,205,212,1,152,213,220,1,97,183,192,1,191,207,208,1,220,220,220, + 1,171,171,171,1,144,144,144,1,208,208,208,7,158,158,158,1,188,188,189, + 1,56,153,162,1,93,192,203,1,92,191,201,1,92,190,200,1,91,189,199, + 1,90,188,198,1,89,187,197,1,89,186,197,1,88,186,196,1,84,182,192, + 1,123,186,192,1,235,235,235,1,170,170,170,1,178,178,178,1,155,155,155, + 1,208,208,208,5,151,151,151,1,185,185,185,1,230,230,230,1,238,239,239, + 1,218,229,230,1,220,230,231,1,221,230,231,1,223,231,232,1,224,232,233, + 1,226,233,234,1,228,234,235,1,229,235,235,1,231,236,236,1,232,236,236, + 1,221,221,222,1,160,160,160,1,187,187,187,1,188,188,188,1,155,155,155, + 1,208,208,208,4,139,139,139,1,160,160,160,1,177,177,177,1,179,179,179, + 1,181,181,181,1,182,182,182,9,181,181,181,1,158,158,158,1,188,188,188, + 3,155,155,155,1,208,208,208,4,146,146,146,1,187,187,187,1,203,203,203, + 1,219,219,219,1,235,235,235,1,241,241,241,1,243,243,243,1,244,244,244, + 1,246,246,246,1,247,247,247,1,248,248,248,1,125,253,136,2,189,253,194, + 1,232,232,232,1,167,167,167,1,188,188,188,2,187,187,187,1,149,149,149, + 1,208,208,208,4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219, + 1,235,235,235,1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246, + 1,247,247,247,1,248,248,248,1,0,255,21,2,126,254,137,1,232,232,232, + 1,167,167,167,1,188,188,188,2,158,158,158,1,109,109,109,1,208,208,208, + 4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219,1,235,235,235, + 1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246,1,247,247,247, + 1,248,248,248,1,0,0,255,2,126,126,254,1,232,232,232,1,167,167,167, + 1,188,188,188,1,141,141,141,1,14,14,14,1,0,0,0,1,208,208,208, + 4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219,1,235,235,235, + 1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246,1,247,247,247, + 1,248,248,248,1,125,125,253,2,189,189,253,1,232,232,232,1,167,167,167, + 1,149,149,149,1,27,27,27,1,0,0,0,2,208,208,208,4,128,128,128, + 1,156,156,156,1,169,169,169,1,183,183,183,1,196,196,196,1,201,201,201, + 1,203,203,203,2,205,205,205,1,206,206,206,1,207,207,207,1,208,208,208, + 1,209,209,209,1,210,210,210,1,193,193,193,1,144,144,144,1,41,41,41, + 1,0,0,0,2,208,208,208,5,115,115,115,1,118,118,118,1,108,108,108, + 1,107,107,107,1,112,112,112,1,115,115,115,1,116,116,116,3,117,117,117, + 5,119,119,119,1,67,67,67,1,0,0,0,2,208,208,208,7,0,0,0, + 16,208,208,208,4,16,3,0,0,0,0,0,1,81,81,81,1,250,250,250, + 1,248,248,248,1,70,70,70,1,0,0,0,3,255,255,255,2,250,250,250, + 1,81,81,81,1,0,0,0,3,255,255,255,1,0,0,0,8,81,81,81, + 1,245,245,245,1,81,81,81,1,63,63,63,1,217,217,217,1,61,61,61, + 1,0,0,0,2,255,255,255,1,0,0,0,1,81,81,81,1,245,245,245, + 1,81,81,81,1,0,0,0,2,255,255,255,1,0,0,0,8,250,250,250, + 1,81,81,81,1,0,0,0,2,17,17,17,1,8,8,8,1,0,0,0, + 2,255,255,255,1,0,0,0,2,81,81,81,1,250,250,250,1,0,0,0, + 2,255,255,255,1,0,0,0,8,255,255,255,1,0,0,0,2,255,255,255, + 3,0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,8,250,250,250,1,81,81,81,1,0,0,0, + 2,81,81,81,1,250,250,250,1,0,0,0,2,255,255,255,1,0,0,0, + 2,81,81,81,1,250,250,250,1,0,0,0,2,255,255,255,1,0,0,0, + 8,81,81,81,1,245,245,245,1,81,81,81,2,245,245,245,1,81,81,81, + 1,0,0,0,2,255,255,255,1,0,0,0,1,81,81,81,1,245,245,245, + 1,81,81,81,1,0,0,0,2,255,255,255,1,0,0,0,9,81,81,81, + 1,250,250,250,2,81,81,81,1,0,0,0,3,255,255,255,2,252,252,252, + 1,235,235,235,1,220,220,220,3,255,255,255,1,220,220,220,1,225,225,225, + 1,203,203,203,1,23,23,23,1,0,0,0,14,145,145,145,1,255,255,255, + 8,216,216,216,1,42,42,42,1,0,0,0,13,176,176,176,1,255,255,255, + 9,225,225,225,1,2,2,2,1,0,0,0,12,197,197,197,1,255,255,255, + 9,206,206,206,1,0,0,0,12,4,4,4,1,227,227,227,1,255,255,255, + 9,183,183,183,1,0,0,0,12,110,110,110,1,250,250,250,1,255,255,255, + 8,245,245,245,1,104,104,104,1,0,0,0,11,2,2,2,1,206,206,206, + 1,255,255,255,9,203,203,203,1,40,40,40,2,45,45,45,1,0,0,0, + 8,1,1,1,1,165,165,165,1,253,253,253,1,255,255,255,11,238,238,238, + 1,195,195,195,1,0,0,0,7,84,84,84,1,194,194,194,1,255,255,255, + 12,231,231,231,1,251,251,251,1,168,168,168,1,0,0,0,5,64,64,64, + 1,181,181,181,1,250,250,250,1,255,255,255,11,246,246,246,1,231,231,231, + 1,255,255,255,2,168,168,168,1,0,0,0,4,161,161,161,1,228,228,228, + 1,225,225,225,12,230,230,230,1,239,239,239,1,255,255,255,3,168,168,168, + 1,0,0,0,4,168,168,168,1,255,255,255,18,149,149,149,1,0,0,0, + 4,168,168,168,1,255,255,255,17,184,184,184,1,7,7,7,1,0,0,0, + 4,168,168,168,1,255,255,255,16,229,229,229,1,147,147,147,1,77,77,77, + 1,0,0,0,4,168,168,168,1,255,255,255,15,235,235,235,1,154,154,154, + 1,92,92,92,1,1,1,1,1,0,0,0,4,175,175,175,1,255,255,255, + 14,245,245,245,1,161,161,161,1,105,105,105,1,4,4,4,1,0,0,0, + 5,135,135,135,1,183,183,183,1,211,211,211,1,223,223,223,11,228,228,228, + 1,181,181,181,1,116,116,116,1,9,9,9,1,0,0,0,7,21,21,21, + 1,70,70,70,14,15,15,15,1,0,0,0,4,0,0) + ); + +const + objdata_twmfprinter: record size: integer; data: array[0..2634] of byte end = + (size: 2635; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,119,109, + 102,112,114,105,110,116,101,114,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,212,9,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,236,5,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,25,25,25,1,183,183,183,1,208,208,208, + 1,125,125,125,1,1,1,1,1,132,132,132,1,208,208,208,1,185,185,185, + 1,26,26,26,1,208,208,208,1,0,0,0,1,119,119,119,1,208,208,208, + 3,118,118,118,1,0,0,0,1,208,208,208,2,0,0,0,4,208,208,208, + 1,77,77,77,1,131,131,131,1,208,208,208,1,82,82,82,1,55,55,55, + 1,90,90,90,1,208,208,208,1,132,132,132,1,79,79,79,1,208,208,208, + 1,0,0,0,1,69,69,69,1,208,208,208,3,69,69,69,1,0,0,0, + 1,208,208,208,2,0,0,0,1,208,208,208,4,128,128,128,1,79,79,79, + 1,208,208,208,1,41,41,41,1,140,140,140,1,47,47,47,1,208,208,208, + 1,80,80,80,1,131,131,131,1,208,208,208,1,0,0,0,1,91,91,91, + 1,166,166,166,1,208,208,208,1,165,165,165,1,92,92,92,1,0,0,0, + 1,208,208,208,2,0,0,0,1,208,208,208,4,180,180,180,1,28,28,28, + 1,203,203,203,1,15,15,15,1,205,205,205,1,19,19,19,1,206,206,206, + 1,29,29,29,1,184,184,184,1,208,208,208,1,0,0,0,1,153,153,153, + 1,84,84,84,1,208,208,208,1,83,83,83,1,153,153,153,1,0,0,0, + 1,208,208,208,2,0,0,0,3,208,208,208,3,24,24,24,1,142,142,142, + 1,49,49,49,1,208,208,208,1,51,51,51,1,145,145,145,1,29,29,29, + 1,208,208,208,2,0,0,0,1,203,203,203,1,23,23,23,1,192,192,192, + 1,23,23,23,1,204,204,204,1,0,0,0,1,208,208,208,2,0,0,0, + 1,208,208,208,5,75,75,75,1,48,48,48,1,91,91,91,1,208,208,208, + 1,95,95,95,1,49,49,49,1,81,81,81,1,208,208,208,2,0,0,0, + 1,208,208,208,1,67,67,67,1,73,73,73,1,68,68,68,1,208,208,208, + 1,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,5,126,126,126, + 1,0,0,0,1,132,132,132,1,208,208,208,1,138,138,138,1,0,0,0, + 1,133,133,133,1,208,208,208,2,6,42,45,1,60,162,172,1,77,169,179, + 1,64,148,157,1,77,169,179,1,74,172,182,1,64,148,157,1,62,145,153, + 1,43,147,157,1,0,11,12,1,208,208,208,14,33,144,155,1,146,210,217, + 1,162,227,233,1,177,248,255,1,169,236,243,1,177,248,255,2,120,168,173, + 1,169,242,250,1,55,159,169,1,18,134,140,1,208,208,208,13,48,152,164, + 1,113,159,163,1,140,196,202,1,130,182,187,1,118,165,170,1,177,248,255, + 1,168,235,242,1,103,144,148,1,121,170,175,1,119,169,174,1,40,126,134, + 1,0,128,128,1,208,208,208,12,72,164,173,1,191,232,237,1,205,250,255, + 1,177,216,220,1,187,227,232,1,205,250,255,5,76,167,176,1,208,208,208, + 12,0,128,128,1,71,125,129,1,154,166,167,1,183,197,199,1,192,206,208, + 1,193,207,209,1,235,253,255,1,197,212,214,1,189,203,205,1,194,208,210, + 1,235,253,255,1,71,159,167,1,208,208,208,12,37,139,148,1,166,194,197, + 1,244,253,255,1,216,224,226,1,199,206,208,1,213,221,223,1,244,253,255, + 1,208,215,217,1,203,210,212,1,190,197,199,1,173,210,215,1,39,140,150, + 1,208,208,208,11,0,128,128,1,67,160,168,1,147,175,179,1,162,193,197, + 1,185,221,225,1,175,208,212,1,210,250,255,1,193,229,234,1,195,232,237, + 1,184,219,223,1,204,246,252,1,53,148,157,1,115,115,115,2,119,119,119, + 1,208,208,208,8,0,0,0,1,77,145,153,1,140,220,230,1,146,204,211, + 1,175,245,253,1,145,203,210,1,137,193,199,1,176,247,255,1,165,232,239, + 1,146,205,212,1,152,213,220,1,97,183,192,1,191,207,208,1,220,220,220, + 1,171,171,171,1,144,144,144,1,208,208,208,7,158,158,158,1,188,188,189, + 1,56,153,162,1,93,192,203,1,92,191,201,1,92,190,200,1,91,189,199, + 1,90,188,198,1,89,187,197,1,89,186,197,1,88,186,196,1,84,182,192, + 1,123,186,192,1,235,235,235,1,170,170,170,1,178,178,178,1,155,155,155, + 1,208,208,208,5,151,151,151,1,185,185,185,1,230,230,230,1,238,239,239, + 1,218,229,230,1,220,230,231,1,221,230,231,1,223,231,232,1,224,232,233, + 1,226,233,234,1,228,234,235,1,229,235,235,1,231,236,236,1,232,236,236, + 1,221,221,222,1,160,160,160,1,187,187,187,1,188,188,188,1,155,155,155, + 1,208,208,208,4,139,139,139,1,160,160,160,1,177,177,177,1,179,179,179, + 1,181,181,181,1,182,182,182,9,181,181,181,1,158,158,158,1,188,188,188, + 3,155,155,155,1,208,208,208,4,146,146,146,1,187,187,187,1,203,203,203, + 1,219,219,219,1,235,235,235,1,241,241,241,1,243,243,243,1,244,244,244, + 1,246,246,246,1,247,247,247,1,248,248,248,1,125,253,136,2,189,253,194, + 1,232,232,232,1,167,167,167,1,188,188,188,2,187,187,187,1,149,149,149, + 1,208,208,208,4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219, + 1,235,235,235,1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246, + 1,247,247,247,1,248,248,248,1,0,255,21,2,126,254,137,1,232,232,232, + 1,167,167,167,1,188,188,188,2,158,158,158,1,109,109,109,1,208,208,208, + 4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219,1,235,235,235, + 1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246,1,247,247,247, + 1,248,248,248,1,0,0,255,2,126,126,254,1,232,232,232,1,167,167,167, + 1,188,188,188,1,141,141,141,1,14,14,14,1,0,0,0,1,208,208,208, + 4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219,1,235,235,235, + 1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246,1,247,247,247, + 1,248,248,248,1,125,125,253,2,189,189,253,1,232,232,232,1,167,167,167, + 1,149,149,149,1,27,27,27,1,0,0,0,2,208,208,208,4,128,128,128, + 1,156,156,156,1,169,169,169,1,183,183,183,1,196,196,196,1,201,201,201, + 1,203,203,203,2,205,205,205,1,206,206,206,1,207,207,207,1,208,208,208, + 1,209,209,209,1,210,210,210,1,193,193,193,1,144,144,144,1,41,41,41, + 1,0,0,0,2,208,208,208,5,115,115,115,1,118,118,118,1,108,108,108, + 1,107,107,107,1,112,112,112,1,115,115,115,1,116,116,116,3,117,117,117, + 5,119,119,119,1,67,67,67,1,0,0,0,2,208,208,208,7,0,0,0, + 16,208,208,208,4,176,3,0,0,224,224,224,1,31,31,31,1,0,0,0, + 1,102,102,102,1,254,254,254,1,93,93,93,1,0,0,0,1,28,28,28, + 1,223,223,223,1,0,0,0,1,255,255,255,1,109,109,109,1,0,0,0, + 3,110,110,110,1,255,255,255,1,0,0,0,2,255,255,255,4,0,0,0, + 1,161,161,161,1,94,94,94,1,0,0,0,1,154,154,154,1,187,187,187, + 1,145,145,145,1,0,0,0,1,93,93,93,1,158,158,158,1,0,0,0, + 1,255,255,255,1,171,171,171,1,0,0,0,3,171,171,171,1,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,4,98,98,98,1,158,158,158, + 1,0,0,0,1,205,205,205,1,83,83,83,1,197,197,197,1,0,0,0, + 1,157,157,157,1,94,94,94,1,0,0,0,1,255,255,255,1,143,143,143, + 1,52,52,52,1,0,0,0,1,53,53,53,1,142,142,142,1,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,4,34,34,34,1,221,221,221, + 1,6,6,6,1,237,237,237,1,4,4,4,1,232,232,232,1,3,3,3, + 1,220,220,220,1,29,29,29,1,0,0,0,1,255,255,255,1,68,68,68, + 1,152,152,152,1,0,0,0,1,153,153,153,1,67,67,67,1,255,255,255, + 1,0,0,0,2,255,255,255,3,0,0,0,3,226,226,226,1,81,81,81, + 1,195,195,195,1,0,0,0,1,192,192,192,1,77,77,77,1,220,220,220, + 1,0,0,0,2,255,255,255,1,6,6,6,1,227,227,227,1,20,20,20, + 1,227,227,227,1,5,5,5,1,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,5,163,163,163,1,196,196,196,1,144,144,144,1,0,0,0, + 1,139,139,139,1,195,195,195,1,156,156,156,1,0,0,0,2,255,255,255, + 1,0,0,0,1,173,173,173,1,165,165,165,1,172,172,172,1,0,0,0, + 1,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,5,100,100,100, + 1,255,255,255,1,93,93,93,1,0,0,0,1,86,86,86,1,255,255,255, + 1,92,92,92,1,0,0,0,2,255,255,255,1,225,225,225,1,233,233,233, + 1,255,255,255,1,233,233,233,1,220,220,220,1,255,255,255,1,225,225,225, + 1,203,203,203,1,255,255,255,1,0,0,0,14,145,145,145,1,255,255,255, + 8,216,216,216,1,42,42,42,1,0,0,0,13,176,176,176,1,255,255,255, + 9,225,225,225,1,2,2,2,1,0,0,0,12,197,197,197,1,255,255,255, + 9,206,206,206,1,0,0,0,12,4,4,4,1,227,227,227,1,255,255,255, + 9,183,183,183,1,0,0,0,12,110,110,110,1,250,250,250,1,255,255,255, + 8,245,245,245,1,104,104,104,1,0,0,0,11,2,2,2,1,206,206,206, + 1,255,255,255,9,203,203,203,1,40,40,40,2,45,45,45,1,0,0,0, + 8,1,1,1,1,165,165,165,1,253,253,253,1,255,255,255,11,238,238,238, + 1,195,195,195,1,0,0,0,7,84,84,84,1,194,194,194,1,255,255,255, + 12,231,231,231,1,251,251,251,1,168,168,168,1,0,0,0,5,64,64,64, + 1,181,181,181,1,250,250,250,1,255,255,255,11,246,246,246,1,231,231,231, + 1,255,255,255,2,168,168,168,1,0,0,0,4,161,161,161,1,228,228,228, + 1,225,225,225,12,230,230,230,1,239,239,239,1,255,255,255,3,168,168,168, + 1,0,0,0,4,168,168,168,1,255,255,255,18,149,149,149,1,0,0,0, + 4,168,168,168,1,255,255,255,17,184,184,184,1,7,7,7,1,0,0,0, + 4,168,168,168,1,255,255,255,16,229,229,229,1,147,147,147,1,77,77,77, + 1,0,0,0,4,168,168,168,1,255,255,255,15,235,235,235,1,154,154,154, + 1,92,92,92,1,1,1,1,1,0,0,0,4,175,175,175,1,255,255,255, + 14,245,245,245,1,161,161,161,1,105,105,105,1,4,4,4,1,0,0,0, + 5,135,135,135,1,183,183,183,1,211,211,211,1,223,223,223,11,228,228,228, + 1,181,181,181,1,116,116,116,1,9,9,9,1,0,0,0,7,21,21,21, + 1,70,70,70,14,15,15,15,1,0,0,0,4,0,0) + ); + +const + objdata_tmainmenu: record size: integer; data: array[0..1936] of byte end = + (size: 1937; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,109,97, + 105,110,109,101,110,117,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,28,7,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,128,4,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1,0, + 0,0,3,208,208,208,5,209,209,209,1,255,255,255,7,209,209,209,1,208, + 208,208,8,0,0,0,1,208,208,208,1,175,175,175,1,156,156,156,1,190, + 190,190,1,180,180,180,1,208,208,208,1,209,209,209,1,254,254,254,1,208, + 208,208,1,206,206,206,2,208,208,208,2,206,206,206,1,130,130,130,1,208, + 208,208,1,175,175,175,1,178,178,178,1,194,194,194,1,208,208,208,4,0, + 0,0,1,208,208,208,1,148,148,148,1,161,161,161,1,157,157,157,1,117, + 117,117,1,125,125,125,1,209,209,209,1,254,254,254,1,205,205,205,1,110, + 110,110,1,170,170,170,1,143,143,143,1,152,152,152,1,207,207,207,1,129, + 129,129,1,208,208,208,1,153,153,153,2,118,118,118,1,126,126,126,1,124, + 124,124,1,114,114,114,1,208,208,208,2,0,0,0,1,179,179,179,1,208, + 208,208,1,182,182,182,1,162,162,162,1,167,167,167,1,209,209,209,1,254, + 254,254,1,158,158,158,1,144,144,144,1,131,131,131,1,147,147,147,2,207, + 207,207,1,128,128,128,1,208,208,208,1,178,178,178,1,195,195,195,1,162, + 162,162,1,168,168,168,1,170,170,170,1,168,168,168,1,208,208,208,2,0, + 0,0,1,153,153,153,1,107,107,107,1,208,208,208,4,255,255,255,1,208, + 208,208,3,207,207,207,2,208,208,208,1,128,128,128,1,208,208,208,1,130, + 130,130,2,208,208,208,5,0,0,0,2,208,208,208,6,211,211,211,1,128, + 128,128,7,208,208,208,8,0,0,0,1,128,128,128,7,255,255,255,12,192, + 192,192,1,128,128,128,3,4,4,4,1,208,208,208,7,255,255,255,1,208, + 208,208,9,197,197,197,1,208,208,208,1,128,128,128,1,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,6,255,255,255,1,190,190,190,1,116, + 116,116,1,148,148,148,1,200,200,200,1,162,162,162,1,194,194,194,1,181, + 181,181,1,208,208,208,2,103,103,103,1,165,165,165,1,128,128,128,1,0, + 0,0,2,208,208,208,2,0,0,0,1,208,208,208,6,255,255,255,1,198, + 198,198,1,135,135,135,1,165,165,165,1,173,173,173,1,115,115,115,1,148, + 148,148,1,142,142,142,1,208,208,208,2,103,103,103,1,165,165,165,1,128, + 128,128,1,0,0,0,2,208,208,208,2,0,0,0,1,208,208,208,6,255, + 255,255,1,166,166,166,1,148,148,148,1,168,168,168,1,150,150,150,1,158, + 158,158,1,177,177,177,1,157,157,157,1,208,208,208,2,197,197,197,1,208, + 208,208,1,128,128,128,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,6,255,255,255,11,212,212,212,1,128,128,128,1,0,0,0,2,208, + 208,208,1,0,0,0,1,208,208,208,7,255,255,255,2,200,200,200,1,153, + 153,153,1,192,192,192,1,224,224,224,2,209,209,209,1,215,215,215,1,224, + 224,224,2,128,128,128,2,0,0,0,2,208,208,208,1,0,0,0,1,208, + 208,208,7,255,255,255,2,169,169,169,1,147,147,147,1,152,152,152,1,136, + 136,136,1,151,151,151,1,153,153,153,1,168,168,168,1,153,153,153,1,223, + 223,223,1,128,128,128,2,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,6,255,255,255,2,169,169,169,1,203,203,203,1,220,220,220,1,156, + 156,156,1,104,104,104,1,157,157,157,1,148,148,148,1,134,134,134,1,218, + 218,218,1,128,128,128,2,0,0,0,2,208,208,208,2,0,0,0,1,208, + 208,208,6,255,255,255,2,224,224,224,9,128,128,128,2,0,0,0,2,208, + 208,208,2,0,0,0,1,208,208,208,6,255,255,255,1,218,218,218,1,128, + 128,128,11,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,6,255, + 255,255,1,191,191,191,1,170,170,170,1,208,208,208,1,183,183,183,1,208, + 208,208,1,207,207,207,1,181,181,181,1,208,208,208,4,128,128,128,1,0, + 0,0,2,208,208,208,1,0,0,0,1,208,208,208,7,255,255,255,1,169, + 169,169,1,125,125,125,1,149,149,149,2,153,153,153,1,148,148,148,1,108, + 108,108,1,159,159,159,1,138,138,138,1,170,170,170,1,208,208,208,1,128, + 128,128,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,7,255, + 255,255,1,169,169,169,1,123,123,123,1,131,131,131,1,148,148,148,1,102, + 102,102,1,121,121,121,1,108,108,108,1,139,139,139,1,103,103,103,1,144, + 144,144,1,208,208,208,1,128,128,128,1,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,6,255,255,255,1,208,208,208,4,207,207,207,1,208, + 208,208,3,207,207,207,1,208,208,208,2,128,128,128,1,0,0,0,2,208, + 208,208,2,0,0,0,1,208,208,208,6,252,252,252,1,128,128,128,12,0, + 0,0,2,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,20,100, + 2,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1,240, + 240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90, + 90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1,0, + 0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,255,255,255,22,240, + 240,240,1,0,0,0,1,255,255,255,22,202,202,202,1,0,0,0,1,255, + 255,255,22,0,0,0,1,217,217,217,1,255,255,255,22,0,0,0,1,240, + 240,240,1,255,255,255,22,75,75,75,1,225,225,225,1,255,255,255,22,240, + 240,240,1,176,176,176,1,255,255,255,22,248,248,248,1,0,0,0,7,255, + 255,255,13,135,135,135,1,3,3,3,1,0,0,0,1,135,135,135,1,45, + 45,45,1,0,0,0,6,255,255,255,13,137,137,137,1,3,3,3,1,0, + 0,0,2,240,240,240,1,0,0,0,6,255,255,255,13,137,137,137,1,3, + 3,3,1,0,0,0,2,240,240,240,1,0,0,0,6,255,255,255,13,137, + 137,137,1,3,3,3,1,0,0,0,1,135,135,135,1,165,165,165,1,0, + 0,0,6,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,1,240, + 240,240,1,0,0,0,7,255,255,255,13,137,137,137,1,3,3,3,1,0, + 0,0,1,240,240,240,1,0,0,0,7,255,255,255,13,137,137,137,1,3, + 3,3,1,0,0,0,1,75,75,75,1,105,105,105,1,0,0,0,6,255, + 255,255,13,137,137,137,1,3,3,3,1,0,0,0,2,240,240,240,1,0, + 0,0,6,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,2,240, + 240,240,1,0,0,0,6,255,255,255,13,137,137,137,1,3,3,3,1,0, + 0,0,1,202,202,202,1,97,97,97,1,0,0,0,6,255,255,255,13,137, + 137,137,1,3,3,3,1,0,0,0,1,240,240,240,1,0,0,0,7,255, + 255,255,13,137,137,137,1,3,3,3,1,0,0,0,1,240,240,240,1,0, + 0,0,7,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,1,7, + 7,7,1,172,172,172,1,0,0,0,6,255,255,255,13,137,137,137,1,3, + 3,3,1,0,0,0,2,240,240,240,1,0,0,0,6,129,129,129,1,255, + 255,255,12,137,137,137,1,3,3,3,1,0,0,0,1,22,22,22,1,240, + 240,240,1,37,37,37,1,0,0,0,2,232,232,232,1,240,240,240,1,210, + 210,210,1,3,3,3,1,135,135,135,1,165,165,165,1,248,248,248,2,206, + 206,206,1,137,137,137,2,193,193,193,1,248,248,248,2,179,179,179,1,137, + 137,137,1,135,135,135,1,188,188,188,1,240,240,240,2,0,0) + ); + +const + objdata_tpopupmenu: record size: integer; data: array[0..2273] of byte end = + (size: 2274; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,112,111, + 112,117,112,109,101,110,117,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,108,8,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,104,3,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4, + 208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1, + 0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,1,255,255,255,17, + 213,213,213,1,208,208,208,4,0,0,0,1,208,208,208,1,255,255,255,2, + 208,208,208,12,0,0,0,2,208,208,208,1,128,128,128,1,208,208,208,5, + 0,0,0,1,255,255,255,2,0,0,0,11,208,208,208,1,0,0,0,3, + 128,128,128,1,208,208,208,5,0,0,0,1,255,255,255,2,0,0,0,11, + 208,208,208,1,0,0,0,3,128,128,128,1,208,208,208,4,0,0,0,2, + 255,255,255,2,0,0,0,11,208,208,208,1,0,0,0,2,208,208,208,1, + 128,128,128,1,208,208,208,4,0,0,0,1,208,208,208,1,255,255,255,2, + 191,191,191,1,127,127,127,1,191,191,191,1,255,255,255,11,213,213,213,1, + 128,128,128,1,208,208,208,4,0,0,0,1,208,208,208,1,255,255,255,3, + 0,0,0,3,208,208,208,2,0,0,0,2,208,208,208,6,128,128,128,2, + 208,208,208,4,0,0,0,2,255,255,255,3,0,0,0,8,208,208,208,2, + 0,0,0,1,208,208,208,2,128,128,128,2,208,208,208,5,0,0,0,1, + 255,255,255,3,0,0,0,9,208,208,208,1,11,11,11,1,20,20,20,1, + 0,0,0,1,128,128,128,2,208,208,208,5,0,0,0,1,255,255,255,3, + 208,208,208,9,0,0,0,1,35,35,35,1,74,74,74,1,27,27,27,1, + 111,111,111,1,128,128,128,1,208,208,208,4,0,0,0,2,255,255,255,2, + 219,219,219,1,128,128,128,9,126,126,126,1,38,38,38,1,255,255,255,1, + 144,144,144,1,34,34,34,1,78,78,78,1,208,208,208,4,0,0,0,1, + 208,208,208,1,255,255,255,2,0,0,0,2,208,208,208,1,0,0,0,1, + 208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,1,37,37,37,1, + 255,255,255,2,210,210,210,1,50,50,50,1,24,24,24,1,0,0,0,1, + 208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,2,0,0,0,11, + 37,37,37,1,255,255,255,3,247,247,247,1,53,53,53,1,13,13,13,1, + 0,0,0,1,208,208,208,1,0,0,0,2,255,255,255,2,0,0,0,11, + 38,38,38,1,255,255,255,2,206,206,206,1,55,55,55,1,30,30,30,1, + 15,15,15,1,0,0,0,1,208,208,208,2,0,0,0,1,255,255,255,2, + 208,208,208,4,0,0,0,1,208,208,208,3,0,0,0,1,208,208,208,1, + 0,0,0,1,38,38,38,1,170,170,170,1,45,45,45,1,147,147,147,1, + 39,39,39,1,9,9,9,1,208,208,208,4,0,0,0,1,255,255,255,1, + 211,211,211,1,128,128,128,10,121,121,121,1,20,20,20,1,36,36,36,1, + 47,47,47,1,76,76,76,1,176,176,176,1,33,33,33,1,0,0,0,1, + 208,208,208,2,0,0,0,2,208,208,208,12,0,0,0,2,208,208,208,1, + 0,0,0,1,36,36,36,1,243,243,243,1,100,100,100,1,27,27,27,1, + 208,208,208,2,0,0,0,1,208,208,208,17,26,26,26,1,165,165,165,1, + 245,245,245,1,48,48,48,1,21,21,21,1,208,208,208,1,0,0,0,1, + 208,208,208,17,9,9,9,1,71,71,71,1,255,255,255,1,185,185,185,1, + 31,31,31,1,0,0,0,3,208,208,208,16,0,0,0,1,37,37,37,1, + 136,136,136,1,42,42,42,1,24,24,24,1,0,0,0,1,208,208,208,1, + 0,0,0,1,208,208,208,17,22,22,22,1,27,27,27,1,3,3,3,1, + 208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,3, + 204,4,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1, + 240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2, + 90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1, + 0,0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0,22, + 240,240,240,1,0,0,0,1,8,8,8,1,255,255,255,16,192,192,192,1, + 0,0,0,4,202,202,202,1,0,0,0,1,8,8,8,1,248,248,248,1, + 0,0,0,12,10,10,10,1,4,4,4,1,0,0,0,1,255,255,255,1, + 0,0,0,5,217,217,217,1,8,8,8,1,248,248,248,1,25,25,25,1, + 117,117,117,1,69,69,69,1,10,10,10,1,55,55,55,1,19,19,19,1, + 31,31,31,1,47,47,47,1,68,68,68,1,47,47,47,1,2,2,2,1, + 0,0,0,1,40,40,40,1,160,160,160,1,4,4,4,1,255,255,255,1, + 0,0,0,5,240,240,240,1,8,8,8,1,248,248,248,1,15,15,15,1, + 86,86,86,1,62,62,62,1,43,43,43,1,108,108,108,1,73,73,73,1, + 81,81,81,1,80,80,80,1,111,111,111,1,37,37,37,1,62,62,62,1, + 0,0,0,1,40,40,40,1,162,162,162,1,4,4,4,1,255,255,255,1, + 0,0,0,4,75,75,75,1,225,225,225,1,8,8,8,1,248,248,248,1, + 55,55,55,1,73,73,73,1,49,49,49,1,72,72,72,1,57,57,57,1, + 40,40,40,1,60,60,60,1,40,40,40,1,45,45,45,1,75,75,75,1, + 14,14,14,1,0,0,0,1,10,10,10,1,4,4,4,1,0,0,0,1, + 255,255,255,1,0,0,0,4,240,240,240,1,0,0,0,1,8,8,8,1, + 248,248,248,1,255,255,255,14,192,192,192,1,255,255,255,1,0,0,0,4, + 240,240,240,1,0,0,0,1,8,8,8,1,248,248,248,2,31,31,31,1, + 80,80,80,1,33,33,33,1,0,0,0,2,20,20,20,1,7,7,7,1, + 0,0,0,6,255,255,255,2,0,0,0,4,135,135,135,1,45,45,45,1, + 8,8,8,1,248,248,248,2,72,72,72,1,82,82,82,1,85,85,85,1, + 94,94,94,1,88,88,88,1,82,82,82,1,62,62,62,1,80,80,80,1, + 0,0,0,2,62,62,62,1,0,0,0,2,255,255,255,2,0,0,0,5, + 240,240,240,1,8,8,8,1,248,248,248,2,72,72,72,1,15,15,15,1, + 13,13,13,1,70,70,70,1,137,137,137,1,82,82,82,2,105,105,105,1, + 3,3,3,1,0,0,0,1,253,253,253,1,167,167,167,1,4,4,4,1, + 255,255,255,2,0,0,0,5,240,240,240,1,8,8,8,1,248,248,248,2, + 0,0,0,9,2,2,2,1,251,251,251,1,254,254,254,1,233,233,233,1, + 255,255,255,2,0,0,0,4,135,135,135,1,165,165,165,1,8,8,8,1, + 248,248,248,1,173,173,173,1,255,255,255,15,0,0,0,4,240,240,240,1, + 0,0,0,1,8,8,8,1,248,248,248,1,24,24,24,1,44,44,44,1, + 0,0,0,1,31,31,31,1,0,0,0,1,4,4,4,1,30,30,30,1, + 0,0,0,3,6,6,6,1,251,251,251,1,255,255,255,4,205,205,205,1, + 14,14,14,1,0,0,0,2,240,240,240,1,0,0,0,1,8,8,8,1, + 248,248,248,1,56,56,56,1,97,97,97,1,72,72,72,2,70,70,70,1, + 78,78,78,1,117,117,117,1,59,59,59,1,89,89,89,1,40,40,40,1, + 8,8,8,1,251,251,251,1,255,255,255,5,244,244,244,1,45,45,45,1, + 0,0,0,1,75,75,75,1,105,105,105,1,8,8,8,1,248,248,248,1, + 56,56,56,1,99,99,99,1,95,95,95,1,73,73,73,1,133,133,133,1, + 110,110,110,1,115,115,115,1,88,88,88,1,129,129,129,1,72,72,72,1, + 10,10,10,1,250,250,250,1,255,255,255,4,239,239,239,1,103,103,103,1, + 3,3,3,1,0,0,0,2,240,240,240,1,8,8,8,1,248,248,248,1, + 0,0,0,4,1,1,1,1,0,0,0,3,1,1,1,1,0,0,0,1, + 12,12,12,1,250,250,250,1,255,255,255,1,254,254,254,1,255,255,255,2, + 67,67,67,1,0,0,0,4,240,240,240,1,4,4,4,1,190,190,190,1, + 255,255,255,16,244,244,244,1,14,14,14,1,0,0,0,2,202,202,202,1, + 97,97,97,1,0,0,0,12,8,8,8,1,75,75,75,1,0,0,0,1, + 13,13,13,1,250,250,250,1,255,255,255,2,205,205,205,1,0,0,0,2, + 240,240,240,1,0,0,0,17,221,221,221,1,255,255,255,2,253,253,253,1, + 114,114,114,1,0,0,0,1,240,240,240,1,0,0,0,17,103,103,103,1, + 254,254,254,1,255,255,255,2,249,249,249,1,33,33,33,1,7,7,7,1, + 172,172,172,1,0,0,0,16,10,10,10,1,249,249,249,1,255,255,255,1, + 252,252,252,1,220,220,220,1,51,51,51,1,0,0,0,1,240,240,240,1, + 0,0,0,17,205,205,205,1,223,223,223,1,64,64,64,1,0,0,0,2, + 22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232,232,232,1, + 240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2, + 150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,96,96,96,1, + 0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tnoguiaction: record size: integer; data: array[0..1603] of byte end = + (size: 1604; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,110,111, + 103,117,105,97,99,116,105,111,110,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,204,5,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,208,208,208,39,15,147,0,2,208,208, + 208,21,20,144,0,1,27,145,7,1,23,144,5,1,0,0,0,1,208,208, + 208,18,0,128,0,1,19,144,0,1,54,160,38,1,146,224,139,1,85,179, + 73,1,13,88,0,1,0,0,0,1,208,208,208,16,24,146,0,1,21,145, + 1,1,96,188,85,1,179,249,176,1,97,184,86,1,20,129,4,1,6,52, + 0,1,0,0,0,1,208,208,208,15,18,143,0,1,32,150,14,1,137,217, + 131,1,157,232,152,1,42,149,27,1,12,96,0,1,0,0,0,3,208,208, + 208,14,19,145,0,1,61,167,45,1,174,244,170,1,98,187,86,1,20,127, + 3,1,6,40,0,1,0,0,0,3,208,208,208,13,23,139,0,1,22,144, + 3,1,111,199,100,1,161,235,155,1,43,149,26,1,12,90,0,1,0,0, + 0,3,208,208,208,14,19,147,0,1,33,151,15,1,158,235,154,1,98,190, + 87,1,19,125,3,1,3,31,0,1,0,0,0,3,208,208,208,14,18,145, + 0,1,62,170,47,1,157,234,152,1,41,151,24,1,10,84,0,1,0,0, + 0,3,208,208,208,15,18,146,0,1,45,161,29,1,130,213,120,1,22,144, + 4,1,6,51,0,1,0,0,0,3,208,208,208,17,18,138,0,1,21,138, + 2,1,21,135,0,1,21,138,0,1,18,138,0,1,0,128,0,1,208,208, + 208,19,0,64,0,1,17,127,0,1,19,137,0,1,21,137,0,1,20,141, + 0,1,18,135,0,1,208,208,208,19,0,0,0,1,15,91,0,1,17,129, + 0,1,20,138,0,1,21,139,0,1,19,141,0,1,28,142,0,1,208,208, + 208,19,0,0,0,1,12,119,0,1,19,133,0,1,20,139,0,1,20,141, + 0,1,18,140,0,1,0,0,0,1,208,208,208,17,18,237,0,1,0,230, + 0,1,0,0,0,1,17,124,0,1,19,138,0,1,20,143,0,1,18,139, + 0,1,0,102,0,1,208,208,208,16,33,165,12,1,29,194,17,1,0,0, + 0,1,14,142,0,1,18,144,0,1,18,141,0,1,11,77,0,1,0,0, + 0,2,208,208,208,14,25,206,0,1,88,185,72,1,62,173,53,1,18,132, + 0,1,19,144,0,1,19,143,0,1,0,22,0,1,0,0,0,2,208,208, + 208,15,67,184,52,1,148,226,140,1,56,161,43,1,19,139,0,1,20,133, + 0,1,0,0,0,3,208,208,208,15,36,200,27,1,136,220,130,1,173,244, + 169,1,100,189,88,1,48,153,32,1,20,144,0,1,17,165,0,1,15,226, + 0,1,208,208,208,16,110,209,97,1,174,245,171,1,118,203,108,1,56,155, + 41,1,18,124,0,1,17,122,0,1,13,127,0,1,8,106,0,1,0,0, + 0,1,208,208,208,14,43,206,27,1,132,221,127,1,74,168,65,1,21,114, + 14,1,6,51,0,1,0,0,0,4,208,208,208,15,0,255,0,1,0,0, + 0,7,208,208,208,17,0,0,0,3,208,208,208,14,252,2,0,0,0,0, + 0,39,33,33,33,2,0,0,0,21,76,76,76,1,208,208,208,1,164,164, + 164,1,2,2,2,1,0,0,0,18,2,2,2,1,133,133,133,1,202,202, + 202,1,253,253,253,1,211,211,211,1,61,61,61,1,2,2,2,1,0,0, + 0,16,21,21,21,1,183,183,183,1,211,211,211,1,255,255,255,1,216,216, + 216,1,202,202,202,1,79,79,79,1,3,3,3,1,0,0,0,15,57,57, + 57,1,204,204,204,1,230,230,230,1,235,235,235,1,217,217,217,1,143,143, + 143,1,60,60,60,1,19,19,19,1,1,1,1,1,0,0,0,14,109,109, + 109,1,203,203,203,1,248,248,248,1,214,214,214,1,195,195,195,1,89,89, + 89,1,38,38,38,1,7,7,7,1,1,1,1,1,0,0,0,13,11,11, + 11,1,166,166,166,1,205,205,205,1,230,230,230,1,215,215,215,1,133,133, + 133,1,57,57,57,1,17,17,17,1,3,3,3,1,0,0,0,14,40,40, + 40,1,199,199,199,1,221,221,221,1,208,208,208,1,185,185,185,1,82,82, + 82,1,35,35,35,1,6,6,6,1,1,1,1,1,0,0,0,14,86,86, + 86,1,205,205,205,1,218,218,218,1,210,210,210,1,122,122,122,1,54,54, + 54,1,15,15,15,1,3,3,3,1,0,0,0,15,70,70,70,1,237,237, + 237,1,229,229,229,1,240,240,240,1,91,91,91,1,31,31,31,1,5,5, + 5,1,1,1,1,1,0,0,0,17,57,57,57,1,205,205,205,1,231,231, + 231,1,224,224,224,1,102,102,102,1,2,2,2,1,0,0,0,19,4,4, + 4,1,106,106,106,1,224,224,224,1,233,233,233,1,194,194,194,1,44,44, + 44,1,0,0,0,19,1,1,1,1,17,17,17,1,148,148,148,1,234,234, + 234,1,235,235,235,1,135,135,135,1,9,9,9,1,0,0,0,19,2,2, + 2,1,41,41,41,1,186,186,186,1,243,243,243,1,220,220,220,1,71,71, + 71,1,1,1,1,1,0,0,0,17,14,14,14,1,10,10,10,1,3,3, + 3,1,76,76,76,1,218,218,218,1,253,253,253,1,166,166,166,1,5,5, + 5,1,0,0,0,16,124,124,124,1,61,61,61,1,1,1,1,1,18,18, + 18,1,181,181,181,1,210,210,210,1,93,93,93,1,13,13,13,1,1,1, + 1,1,0,0,0,14,31,31,31,1,223,223,223,1,115,115,115,1,58,58, + 58,1,214,214,214,1,119,119,119,1,23,23,23,1,18,18,18,1,2,2, + 2,1,0,0,0,15,148,148,148,1,255,255,255,1,196,196,196,1,188,188, + 188,1,38,38,38,1,12,12,12,1,4,4,4,1,1,1,1,1,0,0, + 0,15,56,56,56,1,240,240,240,1,255,255,255,1,244,244,244,1,193,193, + 193,1,140,140,140,1,88,88,88,1,17,17,17,1,0,0,0,16,173,173, + 173,1,255,255,255,2,244,244,244,1,210,210,210,1,167,167,167,1,114,114, + 114,1,34,34,34,1,1,1,1,1,0,0,0,14,84,84,84,1,193,193, + 193,1,166,166,166,1,143,143,143,1,91,91,91,1,60,60,60,1,40,40, + 40,1,20,20,20,1,3,3,3,1,0,0,0,15,3,3,3,1,7,7, + 7,1,37,37,37,1,22,22,22,1,7,7,7,1,2,2,2,2,1,1, + 1,1,0,0,0,17,1,1,1,1,2,2,2,1,1,1,1,1,0,0, + 0,14,0,0) + ); + +const + objdata_tskincontroller: record size: integer; data: array[0..2306] of byte end = + (size: 2307; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,115,107, + 105,110,99,111,110,116,114,111,108,108,101,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,136,8,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,92,6,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 4,208,208,208,1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208, + 2,255,255,255,20,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255, + 1,102,102,102,19,208,208,208,2,0,0,0,1,208,208,208,1,255,255,255, + 1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255, + 1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255, + 1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255, + 1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208, + 2,0,0,0,1,208,208,208,1,255,255,255,1,102,102,102,1,21,237,255, + 1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255, + 1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255, + 1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255, + 1,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,2,208,208,208, + 1,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255, + 1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255, + 1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255, + 1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102, + 1,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102,102,102, + 1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255, + 1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255, + 1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255, + 1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0, + 1,208,208,208,2,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255, + 1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255, + 1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255, + 1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255, + 1,102,102,102,1,208,208,208,1,0,0,0,2,208,208,208,1,255,255,255, + 1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255, + 1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255, + 1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255, + 1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208, + 2,0,0,0,1,208,208,208,1,255,255,255,1,102,102,102,1,21,237,255, + 1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255, + 1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255, + 1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255, + 1,255,255,255,1,102,102,102,1,208,208,208,2,0,0,0,1,208,208,208, + 1,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255, + 1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255, + 1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255, + 1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102, + 1,208,208,208,1,0,0,0,2,208,208,208,1,255,255,255,1,102,102,102, + 1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255, + 1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255, + 1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255, + 1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0, + 1,208,208,208,2,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255, + 1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255, + 1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255, + 1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255, + 1,102,102,102,1,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255, + 1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255, + 1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255, + 1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255, + 1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208, + 1,0,0,0,2,208,208,208,1,255,255,255,1,102,102,102,1,21,237,255, + 1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255, + 1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255, + 1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255, + 1,255,255,255,1,102,102,102,1,208,208,208,2,0,0,0,1,208,208,208, + 1,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255, + 1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255, + 1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255, + 1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102, + 1,208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,1,102,102,102, + 1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255, + 1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255, + 1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255, + 1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0, + 2,208,208,208,1,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255, + 1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255, + 1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255, + 1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255, + 1,102,102,102,1,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255, + 1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255, + 1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255, + 1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255, + 1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208, + 1,0,0,0,1,208,208,208,2,255,255,255,19,102,102,102,1,208,208,208, + 1,0,0,0,2,208,208,208,1,102,102,102,20,208,208,208,2,0,0,0, + 1,208,208,208,22,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 3,244,1,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60, + 1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240, + 2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22, + 1,0,0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0, + 22,240,240,240,1,0,0,0,2,255,255,255,20,0,0,0,1,202,202,202, + 1,0,0,0,2,255,255,255,20,0,0,0,2,217,217,217,1,0,0,0, + 1,255,255,255,20,0,0,0,2,240,240,240,1,0,0,0,1,255,255,255, + 20,0,0,0,1,75,75,75,1,225,225,225,1,0,0,0,1,255,255,255, + 20,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,20,0,0,0, + 1,240,240,240,1,0,0,0,2,255,255,255,20,0,0,0,1,135,135,135, + 1,45,45,45,1,0,0,0,1,255,255,255,20,0,0,0,2,240,240,240, + 1,0,0,0,1,255,255,255,20,0,0,0,2,240,240,240,1,0,0,0, + 1,255,255,255,20,0,0,0,1,135,135,135,1,165,165,165,1,0,0,0, + 1,255,255,255,20,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255, + 20,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,20,0,0,0, + 1,75,75,75,1,105,105,105,1,0,0,0,1,255,255,255,20,0,0,0, + 2,240,240,240,1,0,0,0,1,255,255,255,20,0,0,0,2,240,240,240, + 1,0,0,0,1,255,255,255,20,0,0,0,1,202,202,202,1,97,97,97, + 1,0,0,0,1,255,255,255,20,0,0,0,1,240,240,240,1,0,0,0, + 2,255,255,255,20,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255, + 20,0,0,0,1,7,7,7,1,172,172,172,1,0,0,0,1,255,255,255, + 20,0,0,0,2,240,240,240,1,0,0,0,22,22,22,22,1,240,240,240, + 1,37,37,37,1,0,0,0,2,232,232,232,1,240,240,240,1,210,210,210, + 1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0, + 2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187, + 1,240,240,240,2,0,0) + ); + +const + objdata_tskinextender: record size: integer; data: array[0..1536] of byte end = + (size: 1537; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,107, + 105,110,101,120,116,101,110,100,101,114,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,136,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,92,3,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0, + 0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208, + 208,208,1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,2,255, + 255,255,20,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102, + 102,102,19,208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,1,102, + 102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208,2,0, + 0,0,1,208,208,208,1,255,255,255,1,102,102,102,1,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,255, + 255,255,1,102,102,102,1,208,208,208,1,0,0,0,2,208,208,208,1,255, + 255,255,1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208, + 208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102,102,102,1,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,1,208, + 208,208,2,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255,1,102, + 102,102,1,208,208,208,1,0,0,0,2,208,208,208,1,255,255,255,1,102, + 102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208,2,0, + 0,0,1,208,208,208,1,255,255,255,19,102,102,102,1,208,208,208,2,0, + 0,0,1,208,208,208,1,102,102,102,20,208,208,208,1,0,0,0,2,208, + 208,208,1,255,255,255,1,208,208,208,20,0,0,0,1,208,208,208,2,255, + 255,255,1,208,208,208,20,0,0,0,1,208,208,208,2,255,255,255,1,208, + 208,208,20,0,0,0,2,208,208,208,1,255,255,255,1,208,208,208,21,0, + 0,0,1,208,208,208,1,255,255,255,1,208,208,208,21,0,0,0,1,208, + 208,208,1,255,255,255,1,208,208,208,20,0,0,0,2,208,208,208,1,255, + 255,255,1,208,208,208,20,0,0,0,1,208,208,208,2,255,255,255,1,208, + 208,208,20,0,0,0,1,208,208,208,2,255,255,255,1,208,208,208,20,0, + 0,0,2,208,208,208,23,0,0,0,1,208,208,208,22,0,0,0,3,208, + 208,208,2,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0, + 0,0,4,208,208,208,2,0,0,0,3,244,1,0,0,240,240,240,2,210, + 210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1,0, + 0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2,187, + 187,187,1,240,240,240,2,22,22,22,1,0,0,0,1,7,7,7,1,240, + 240,240,1,52,52,52,1,0,0,0,22,240,240,240,1,0,0,0,2,255, + 255,255,20,0,0,0,1,202,202,202,1,0,0,0,2,255,255,255,20,0, + 0,0,2,217,217,217,1,0,0,0,1,255,255,255,20,0,0,0,2,240, + 240,240,1,0,0,0,1,255,255,255,20,0,0,0,1,75,75,75,1,225, + 225,225,1,0,0,0,1,255,255,255,20,0,0,0,1,240,240,240,1,0, + 0,0,2,255,255,255,20,0,0,0,1,240,240,240,1,0,0,0,2,255, + 255,255,20,0,0,0,1,135,135,135,1,45,45,45,1,0,0,0,1,255, + 255,255,20,0,0,0,2,240,240,240,1,0,0,0,1,255,255,255,1,128, + 128,128,1,255,255,255,18,0,0,0,2,240,240,240,1,0,0,0,1,255, + 255,255,20,0,0,0,1,135,135,135,1,165,165,165,1,0,0,0,1,255, + 255,255,1,0,0,0,20,240,240,240,1,0,0,0,2,255,255,255,1,0, + 0,0,20,240,240,240,1,0,0,0,2,255,255,255,1,0,0,0,20,75, + 75,75,1,105,105,105,1,0,0,0,1,255,255,255,1,0,0,0,21,240, + 240,240,1,0,0,0,1,255,255,255,1,0,0,0,21,240,240,240,1,0, + 0,0,1,255,255,255,1,0,0,0,20,202,202,202,1,97,97,97,1,0, + 0,0,1,255,255,255,1,0,0,0,20,240,240,240,1,0,0,0,2,255, + 255,255,1,0,0,0,20,240,240,240,1,0,0,0,2,255,255,255,1,0, + 0,0,20,7,7,7,1,172,172,172,1,0,0,0,23,240,240,240,1,0, + 0,0,22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232, + 232,232,1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240, + 240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90, + 90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tshortcutcontroller: record size: integer; data: array[0..2850] of byte end = + (size: 2851; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,115,104, + 111,114,116,99,117,116,99,111,110,116,114,111,108,108,101,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,164,10,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,212,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,4, + 1,5,5,7,1,17,17,22,1,177,177,229,1,180,180,230,1,113,113,143, + 1,6,6,7,2,49,49,61,1,192,192,234,1,195,195,234,1,71,71,85, + 1,6,6,7,2,98,98,114,1,207,207,238,1,209,209,239,1,33,33,37, + 1,7,7,7,2,184,184,203,1,222,222,242,1,212,212,230,1,3,3,4, + 1,113,113,151,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234, + 1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241, + 1,219,219,241,1,222,222,242,1,224,224,243,1,7,7,7,1,171,171,228, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,222,222,242,1,224,224,243,1,26,26,28,1,171,171,228,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242, + 1,224,224,243,1,226,226,243,1,14,14,18,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243, + 1,226,226,243,1,5,5,7,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,173,173,220,1,63,63,79,1,7,7,9,1,31,31,38, + 1,162,162,197,1,195,195,234,1,197,197,235,1,90,90,106,1,202,202,236, + 1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239,1,0,0,0, + 1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243,1,123,123,133, + 1,11,11,14,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,78,78,99,1,131,131,165,1,184,184,228,1,109,109,133,1,44,44,54, + 1,195,195,234,1,197,197,235,1,0,0,0,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,0,0,0,1,217,217,241, + 1,219,219,241,1,222,222,242,1,224,224,243,1,7,7,7,1,171,171,228, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,19,19,24, + 1,165,165,207,1,187,187,232,1,187,187,229,1,154,154,187,1,195,195,234, + 1,0,0,0,3,204,204,237,1,0,0,0,1,58,58,67,1,212,212,239, + 1,0,0,0,1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243, + 1,7,7,7,1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,4,4,5,1,183,183,229,1,187,187,232,1,190,190,233, + 1,192,192,234,1,195,195,234,1,197,197,235,1,0,0,0,1,202,202,236, + 1,204,204,237,1,0,0,0,1,175,175,200,1,212,212,239,1,0,0,0, + 1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243,1,70,70,75, + 1,120,120,160,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,21,21,26,1,165,165,207,1,187,187,232,1,181,181,222,1,104,104,127, + 1,195,195,234,1,197,197,235,1,0,0,0,1,202,202,236,1,204,204,237, + 1,0,0,0,1,208,208,238,1,212,212,239,1,0,0,0,1,217,217,241, + 1,219,219,241,1,222,222,242,1,224,224,243,1,226,226,243,1,5,5,7, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,76,76,97, + 1,129,129,162,1,183,183,227,1,94,94,115,1,54,54,66,1,195,195,234, + 1,197,197,235,1,0,0,0,1,191,191,223,1,204,204,237,1,0,0,0, + 1,209,209,239,1,212,212,239,1,0,0,0,1,217,217,241,1,219,219,241, + 1,222,222,242,1,224,224,243,1,226,226,243,1,5,5,7,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,171,171,217,1,53,53,66, + 1,6,6,7,1,37,37,46,1,166,166,203,1,195,195,234,1,197,197,235, + 1,44,44,52,1,6,6,6,1,204,204,237,1,0,0,0,1,209,209,239, + 1,212,212,239,1,0,0,0,1,217,217,241,1,219,219,241,1,222,222,242, + 1,224,224,243,1,70,70,75,1,37,37,49,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243, + 1,7,7,7,1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233, + 1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236, + 1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240, + 1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243,1,7,7,7, + 1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234, + 1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241, + 1,219,219,241,1,222,222,242,1,224,224,243,1,123,123,133,1,71,71,95, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,222,222,242,1,224,224,243,1,226,226,243,1,5,5,7,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,0,0,0, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242, + 1,224,224,243,1,226,226,243,1,5,5,7,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,0,0,0,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243, + 1,26,26,28,1,77,77,103,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233, + 1,0,0,0,5,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243, + 1,7,7,7,1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233, + 1,192,192,234,1,195,195,234,1,0,0,0,1,199,199,236,1,202,202,236, + 1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240, + 1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243,1,7,7,7, + 1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234, + 1,195,195,234,1,0,0,0,1,199,199,236,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241, + 1,219,219,241,1,222,222,242,1,224,224,243,1,214,214,230,1,33,33,44, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,222,222,242,1,224,224,243,1,226,226,243,1,5,5,7,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242, + 1,224,224,243,1,190,190,205,1,3,3,4,1,129,129,170,1,175,175,229, + 1,177,177,229,1,9,9,11,1,6,6,7,1,18,18,23,1,187,187,232, + 1,190,190,233,1,119,119,145,1,6,6,7,2,52,52,61,1,202,202,236, + 1,204,204,237,1,75,75,86,1,6,6,7,2,103,103,115,1,217,217,241, + 1,219,219,241,1,34,34,37,1,7,7,7,1,3,3,4,1,152,1,0, + 0,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158, + 1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248, + 2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139, + 1,128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128, + 1,255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165, + 1,180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244, + 1,146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233, + 1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128, + 2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221, + 1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_thelpcontroller: record size: integer; data: array[0..2858] of byte end = + (size: 2859; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,104,101, + 108,112,99,111,110,116,114,111,108,108,101,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,176,10,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,228,8,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,3,3, + 1,15,15,20,1,177,177,229,1,180,180,230,1,114,114,144,1,3,3,3, + 2,49,49,60,1,192,192,234,1,195,195,234,1,71,71,85,1,3,3,4, + 2,98,98,114,1,207,207,238,1,209,209,239,1,35,35,39,1,3,3,4, + 2,174,174,191,1,221,221,242,1,213,213,231,1,0,0,0,1,121,121,161, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,221,221,242,1,224,224,243,1,3,3,4,1,171,171,228,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242, + 1,224,224,243,1,28,28,30,1,171,171,228,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243, + 1,226,226,243,1,9,9,11,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233, + 1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236, + 1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240, + 1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243,1,226,226,243, + 1,3,3,3,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234, + 1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241, + 1,219,219,241,1,221,221,242,1,224,224,243,1,125,125,134,1,9,9,11, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,221,221,242,1,224,224,243,1,3,3,4,1,171,171,228,1,172,172,228, + 1,171,171,224,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,183,183,227,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,201,201,231,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242, + 1,224,224,243,1,3,3,4,1,171,171,228,1,172,172,228,1,27,27,35, + 1,155,155,201,1,180,180,230,1,182,182,231,1,168,168,210,1,23,23,29, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,25,25,29,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243, + 1,70,70,75,1,121,121,161,1,172,172,228,1,27,27,35,1,155,155,201, + 1,180,180,230,1,182,182,231,1,168,168,210,1,23,23,29,1,190,190,233, + 1,192,192,234,1,195,195,234,1,186,186,222,1,199,199,236,1,202,202,236, + 1,204,204,237,1,25,25,29,1,209,209,239,1,208,208,234,1,213,213,239, + 1,198,198,220,1,218,218,240,1,221,221,242,1,224,224,243,1,226,226,243, + 1,3,3,3,1,172,172,228,1,27,27,35,1,151,151,195,1,174,174,223, + 1,176,176,224,1,163,163,204,1,23,23,29,1,190,190,233,1,166,166,203, + 1,64,64,77,1,61,61,73,1,58,58,68,1,170,170,198,1,204,204,237, + 1,25,25,29,1,209,209,239,1,61,61,68,1,54,54,60,1,66,66,74, + 1,32,32,35,1,188,188,206,1,224,224,243,1,226,226,243,1,3,3,3, + 1,172,172,228,1,27,27,35,1,29,29,38,1,33,33,42,1,34,34,43, + 1,31,31,39,1,23,23,29,1,190,190,233,1,88,88,107,1,137,137,164, + 1,197,197,235,1,157,157,186,1,85,85,99,1,204,204,237,1,25,25,29, + 1,209,209,239,1,61,61,68,1,122,122,136,1,217,217,241,1,145,145,160, + 1,71,71,78,1,224,224,243,1,70,70,75,1,36,36,48,1,172,172,228, + 1,27,27,35,1,155,155,201,1,180,180,230,1,182,182,231,1,168,168,210, + 1,23,23,29,1,190,190,233,1,32,32,39,1,46,46,55,1,49,49,58, + 2,53,53,62,1,204,204,237,1,25,25,29,1,209,209,239,1,61,61,68, + 1,176,176,198,1,217,217,241,1,198,198,217,1,36,36,40,1,224,224,243, + 1,3,3,4,1,171,171,228,1,172,172,228,1,27,27,35,1,155,155,201, + 1,180,180,230,1,182,182,231,1,168,168,210,1,23,23,29,1,190,190,233, + 1,70,70,85,1,148,148,177,1,197,197,235,1,184,184,218,1,138,138,161, + 1,204,204,237,1,25,25,29,1,209,209,239,1,61,61,68,1,140,140,157, + 1,217,217,241,1,156,156,172,1,66,66,72,1,224,224,243,1,3,3,4, + 1,171,171,228,1,172,172,228,1,27,27,35,1,155,155,201,1,180,180,230, + 1,182,182,231,1,168,168,210,1,23,23,29,1,190,190,233,1,146,146,178, + 1,43,43,51,1,104,104,123,1,46,46,55,1,125,125,146,1,204,204,237, + 1,25,25,29,1,209,209,239,1,61,61,68,1,38,38,42,1,109,109,121, + 1,37,37,41,1,170,170,186,1,224,224,243,1,125,125,134,1,72,72,96, + 1,172,172,228,1,138,138,181,1,172,172,223,1,180,180,230,1,182,182,231, + 1,181,181,227,1,147,147,182,1,190,190,233,1,192,192,234,1,190,190,228, + 1,141,141,169,1,177,177,210,1,202,202,236,1,204,204,237,1,162,162,186, + 1,209,209,239,1,61,61,68,1,159,159,178,1,150,150,166,1,196,196,215, + 1,221,221,242,1,224,224,243,1,226,226,243,1,3,3,3,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,61,61,68,1,173,173,194,1,217,217,241,1,219,219,241,1,221,221,242, + 1,224,224,243,1,226,226,243,1,3,3,3,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,170,170,191, + 1,203,203,228,1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243, + 1,28,28,30,1,72,72,96,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233, + 1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236, + 1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240, + 1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243,1,3,3,4, + 1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234, + 1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241, + 1,219,219,241,1,221,221,242,1,224,224,243,1,3,3,4,1,171,171,228, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,221,221,242,1,224,224,243,1,202,202,218,1,36,36,48,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242, + 1,224,224,243,1,226,226,243,1,3,3,3,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243, + 1,202,202,218,1,0,0,0,1,137,137,181,1,175,175,229,1,177,177,229, + 1,3,3,3,2,16,16,20,1,187,187,232,1,190,190,233,1,120,120,146, + 1,3,3,3,2,51,51,60,1,202,202,236,1,204,204,237,1,75,75,86, + 1,3,3,4,2,103,103,116,1,217,217,241,1,219,219,241,1,37,37,40, + 1,3,3,4,1,0,0,0,1,148,1,0,0,255,255,255,1,252,252,252, + 1,237,237,237,1,136,136,136,2,165,165,165,1,252,252,252,2,208,208,208, + 1,136,136,136,2,194,194,194,1,252,252,252,2,179,179,179,1,136,136,136, + 2,223,223,223,1,252,252,252,2,150,150,150,1,136,136,136,1,139,139,139, + 1,255,255,255,1,157,157,157,1,255,255,255,22,252,252,252,1,136,136,136, + 1,255,255,255,22,230,230,230,1,136,136,136,1,255,255,255,22,136,136,136, + 1,244,244,244,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255, + 22,172,172,172,1,244,244,244,1,255,255,255,22,252,252,252,1,136,136,136, + 1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,201,201,201, + 1,157,157,157,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255, + 22,136,136,136,1,252,252,252,1,255,255,255,22,201,201,201,1,215,215,215, + 1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,252,252,252, + 1,136,136,136,1,255,255,255,22,172,172,172,1,186,186,186,1,255,255,255, + 22,136,136,136,1,252,252,252,1,255,255,255,22,136,136,136,1,252,252,252, + 1,255,255,255,22,230,230,230,1,186,186,186,1,255,255,255,22,252,252,252, + 1,136,136,136,1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255, + 22,143,143,143,1,215,215,215,1,255,255,255,22,136,136,136,1,252,252,252, + 1,255,255,255,22,143,143,143,1,255,255,255,1,150,150,150,1,136,136,136, + 2,252,252,252,2,237,237,237,1,136,136,136,2,165,165,165,1,252,252,252, + 2,208,208,208,1,136,136,136,2,194,194,194,1,252,252,252,2,179,179,179, + 1,136,136,136,2,223,223,223,1,252,252,252,1,255,255,255,1,0,0) + ); + +const + objdata_tguiprocess: record size: integer; data: array[0..2866] of byte end = + (size: 2867; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,103,117, + 105,112,114,111,99,101,115,115,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,2,2,1,4,4,5,1,15,15,18, + 1,183,183,225,1,185,185,227,1,117,117,143,1,4,4,5,2,49,49,58, + 1,195,195,231,1,197,197,231,1,70,70,82,1,4,4,5,2,101,101,116, + 1,209,209,237,1,211,211,237,1,33,33,37,1,5,5,5,2,185,185,204, + 1,221,221,241,1,209,209,228,1,2,2,3,1,117,117,150,1,178,178,224, + 1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229, + 1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233, + 1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237, + 1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242, + 1,224,224,243,1,5,5,5,1,175,175,223,1,178,178,224,1,180,180,225, + 1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230, + 1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234, + 1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238, + 1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243, + 1,26,26,28,1,175,175,223,1,178,178,224,1,180,180,225,1,183,183,226, + 1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230,1,193,193,230, + 1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234,1,204,204,235, + 1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238,1,215,215,239, + 1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243,1,225,225,243, + 1,12,12,15,1,178,178,224,1,180,180,225,1,183,183,226,1,185,185,227, + 1,187,187,228,1,189,189,229,1,191,191,230,1,193,193,230,1,196,196,231, + 1,198,198,232,1,200,200,233,1,202,202,234,1,204,204,235,1,206,206,236, + 1,209,209,237,1,211,211,237,1,213,213,238,1,215,215,239,1,217,217,240, + 1,219,219,241,1,222,222,242,1,224,224,243,1,225,225,243,1,4,4,5, + 1,178,178,224,1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228, + 1,189,189,229,1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232, + 1,200,200,233,1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237, + 1,211,211,237,1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241, + 1,222,222,242,1,224,224,243,1,126,126,135,1,9,9,12,1,178,178,224, + 1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229, + 1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233, + 1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237, + 1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242, + 1,224,224,243,1,5,5,5,1,175,175,223,1,178,178,224,1,154,154,192, + 1,146,146,181,1,148,148,182,1,161,161,196,1,188,188,228,1,191,191,230, + 1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234, + 1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238, + 1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243, + 1,5,5,5,1,175,175,223,1,178,178,224,1,48,48,60,1,67,67,82, + 1,86,86,106,1,59,59,72,1,47,47,57,1,184,184,222,1,193,193,230, + 1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234,1,204,204,235, + 1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238,1,215,215,239, + 1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243,1,67,67,72, + 1,124,124,158,1,178,178,224,1,48,48,60,1,143,143,176,1,185,185,227, + 1,187,187,228,1,71,71,86,1,121,121,145,1,157,157,187,1,153,153,180, + 1,119,119,139,1,190,190,221,1,194,194,225,1,129,129,148,1,126,126,144, + 1,194,194,220,1,211,211,237,1,213,213,238,1,191,191,213,1,125,125,138, + 1,147,147,162,1,219,219,239,1,224,224,243,1,225,225,243,1,4,4,5, + 1,178,178,224,1,48,48,60,1,143,143,176,1,185,185,227,1,187,187,228, + 1,71,71,86,1,121,121,146,1,102,102,122,1,25,25,30,1,102,102,120, + 1,186,186,217,1,46,46,53,1,106,106,123,1,123,123,141,1,37,37,42, + 1,199,199,224,1,189,189,211,1,35,35,38,1,137,137,152,1,100,100,110, + 1,86,86,94,1,224,224,243,1,225,225,243,1,4,4,5,1,178,178,224, + 1,48,48,60,1,57,57,71,1,74,74,91,1,54,54,65,1,50,50,60, + 1,184,184,221,1,102,102,122,1,105,105,124,1,198,198,232,1,150,150,175, + 1,59,59,69,1,204,204,235,1,206,206,236,1,98,98,111,1,127,127,142, + 1,114,114,127,1,113,113,126,1,217,217,240,1,219,219,241,1,132,132,144, + 1,224,224,243,1,67,67,72,1,37,37,47,1,178,178,224,1,48,48,60, + 1,114,114,141,1,149,149,182,1,169,169,207,1,189,189,229,1,191,191,230, + 1,102,102,122,1,108,108,127,1,198,198,232,1,136,136,158,1,82,82,95, + 1,204,204,235,1,206,206,236,1,120,120,136,1,106,106,119,1,100,100,112, + 1,133,133,148,1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243, + 1,5,5,5,1,175,175,223,1,178,178,224,1,48,48,60,1,143,143,176, + 1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230,1,102,102,122, + 1,108,108,127,1,198,198,232,1,173,173,202,1,38,38,44,1,201,201,231, + 1,206,206,236,1,67,67,76,1,145,145,163,1,139,139,155,1,87,87,97, + 1,217,217,240,1,210,210,231,1,101,101,110,1,224,224,243,1,5,5,5, + 1,175,175,223,1,178,178,224,1,48,48,60,1,143,143,176,1,185,185,227, + 1,187,187,228,1,189,189,229,1,191,191,230,1,102,102,122,1,108,108,127, + 1,198,198,232,1,200,200,233,1,114,114,132,1,42,42,49,1,49,49,56, + 1,83,83,94,1,210,210,236,1,210,210,235,1,74,74,82,1,60,60,66, + 1,50,50,55,1,154,154,168,1,224,224,243,1,126,126,135,1,70,70,90, + 1,178,178,224,1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228, + 1,189,189,229,1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232, + 1,200,200,233,1,202,202,234,1,201,201,231,1,198,198,227,1,209,209,237, + 1,211,211,237,1,213,213,238,1,215,215,239,1,209,209,232,1,217,217,239, + 1,222,222,242,1,224,224,243,1,225,225,243,1,4,4,5,1,178,178,224, + 1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229, + 1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233, + 1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237, + 1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242, + 1,224,224,243,1,225,225,243,1,4,4,5,1,178,178,224,1,180,180,225, + 1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230, + 1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234, + 1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238, + 1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243, + 1,26,26,28,1,76,76,97,1,178,178,224,1,180,180,225,1,183,183,226, + 1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230,1,193,193,230, + 1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234,1,204,204,235, + 1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238,1,215,215,239, + 1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243,1,5,5,5, + 1,175,175,223,1,178,178,224,1,180,180,225,1,183,183,226,1,185,185,227, + 1,187,187,228,1,189,189,229,1,191,191,230,1,193,193,230,1,196,196,231, + 1,198,198,232,1,200,200,233,1,202,202,234,1,204,204,235,1,206,206,236, + 1,209,209,237,1,211,211,237,1,213,213,238,1,215,215,239,1,217,217,240, + 1,219,219,241,1,222,222,242,1,224,224,243,1,5,5,5,1,175,175,223, + 1,178,178,224,1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228, + 1,189,189,229,1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232, + 1,200,200,233,1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237, + 1,211,211,237,1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241, + 1,222,222,242,1,224,224,243,1,211,211,228,1,33,33,43,1,178,178,224, + 1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229, + 1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233, + 1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237, + 1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242, + 1,224,224,243,1,225,225,243,1,4,4,5,1,178,178,224,1,180,180,225, + 1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230, + 1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234, + 1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238, + 1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243, + 1,189,189,204,1,2,2,2,1,133,133,168,1,179,179,225,1,183,183,225, + 1,6,6,8,1,4,4,5,1,16,16,19,1,191,191,229,1,193,193,229, + 1,122,122,145,1,4,4,5,2,51,51,59,1,203,203,235,1,205,205,235, + 1,73,73,84,1,5,5,5,2,106,106,118,1,217,217,239,1,219,219,241, + 1,35,35,37,1,5,5,5,1,2,2,3,1,152,1,0,0,247,247,247, + 1,250,250,250,1,236,236,236,1,128,128,128,2,157,157,157,1,250,250,250, + 2,204,204,204,1,128,128,128,2,189,189,189,1,250,250,250,2,171,171,171, + 1,128,128,128,2,221,221,221,1,250,250,250,2,139,139,139,1,128,128,128, + 1,132,132,132,1,247,247,247,1,153,153,153,1,255,255,255,22,250,250,250, + 1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255, + 22,128,128,128,1,239,239,239,1,255,255,255,22,128,128,128,1,250,250,250, + 1,255,255,255,22,164,164,164,1,243,243,243,1,255,255,255,22,250,250,250, + 1,128,128,128,1,255,255,255,22,250,250,250,1,128,128,128,1,255,255,255, + 22,197,197,197,1,150,150,150,1,255,255,255,22,128,128,128,1,250,250,250, + 1,255,255,255,22,128,128,128,1,250,250,250,1,255,255,255,22,197,197,197, + 1,211,211,211,1,255,255,255,22,250,250,250,1,128,128,128,1,255,255,255, + 22,250,250,250,1,128,128,128,1,255,255,255,22,164,164,164,1,182,182,182, + 1,255,255,255,22,128,128,128,1,250,250,250,1,255,255,255,22,128,128,128, + 1,250,250,250,1,255,255,255,22,229,229,229,1,178,178,178,1,255,255,255, + 22,250,250,250,1,128,128,128,1,255,255,255,22,250,250,250,1,128,128,128, + 1,255,255,255,22,132,132,132,1,214,214,214,1,255,255,255,22,128,128,128, + 1,250,250,250,1,255,255,255,22,139,139,139,1,247,247,247,1,146,146,146, + 1,128,128,128,2,247,247,247,1,250,250,250,1,236,236,236,1,128,128,128, + 2,157,157,157,1,250,250,250,2,204,204,204,1,128,128,128,2,189,189,189, + 1,250,250,250,2,171,171,171,1,128,128,128,2,221,221,221,1,250,250,250, + 1,247,247,247,1,0,0) + ); + +const + objdata_tguithreadcomp: record size: integer; data: array[0..1313] of byte end = + (size: 1314; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,103,117, + 105,116,104,114,101,97,100,99,111,109,112,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,168,4,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,212,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,101,15,15,255,1, + 14,14,255,1,0,0,255,1,208,208,208,21,16,16,255,1,14,14,255,1, + 15,15,255,1,14,14,255,1,208,208,208,22,14,14,255,1,15,15,255,1, + 14,14,255,1,16,16,255,1,208,208,208,21,0,0,255,1,14,14,255,1, + 15,15,255,1,14,14,255,1,0,0,255,1,208,208,208,21,16,16,255,1, + 15,15,255,2,14,14,255,1,208,208,208,14,138,220,255,1,141,222,255,1, + 208,208,208,6,14,14,255,1,15,15,255,1,14,14,255,1,16,16,255,1, + 208,208,208,2,117,216,255,1,138,220,255,1,208,208,208,8,180,233,255,1, + 144,222,255,1,146,219,255,1,208,208,208,6,0,0,255,1,14,14,255,1, + 15,15,255,1,208,208,208,1,134,219,255,1,155,224,255,1,180,233,255,1, + 208,208,208,8,221,245,255,1,146,223,255,1,146,222,255,1,15,15,255,1, + 208,208,208,1,15,15,255,1,208,208,208,1,15,15,255,1,208,208,208,1, + 15,15,255,1,208,208,208,1,15,15,255,1,208,208,208,1,182,233,255,1, + 198,238,255,1,221,245,255,1,208,208,208,8,248,251,253,1,149,223,255,1, + 148,223,255,1,15,15,255,1,163,228,255,1,15,15,255,1,163,228,255,1, + 15,15,255,1,163,228,255,1,15,15,255,1,163,228,255,1,15,15,255,1, + 163,228,255,1,225,246,255,1,241,250,255,1,248,251,253,1,208,208,208,8, + 215,234,243,1,136,214,247,1,143,219,251,1,15,15,255,1,255,255,255,1, + 15,15,255,1,255,255,255,1,15,15,255,1,255,255,255,1,15,15,255,1, + 255,255,255,1,15,15,255,1,255,255,255,1,244,249,251,1,231,243,248,1, + 215,234,243,1,208,208,208,8,181,217,233,1,115,199,235,1,123,205,239,1, + 15,15,255,1,181,217,233,1,15,15,255,1,181,217,233,1,15,15,255,1, + 181,217,233,1,15,15,255,1,181,217,233,1,15,15,255,1,181,217,233,1, + 210,232,241,1,197,225,238,1,181,217,233,1,208,208,208,8,148,200,223,1, + 94,185,223,1,102,190,227,1,15,15,255,1,109,180,212,1,15,15,255,1, + 109,180,212,1,15,15,255,1,109,180,212,1,15,15,255,1,109,180,212,1, + 15,15,255,1,109,180,212,1,175,214,231,1,163,208,227,1,148,200,223,1, + 208,208,208,8,115,184,214,1,74,171,211,1,81,176,215,1,15,15,255,1, + 36,143,190,1,15,15,255,1,36,143,190,1,15,15,255,1,36,143,190,1, + 15,15,255,1,36,143,190,1,15,15,255,1,36,143,190,1,141,197,221,1, + 128,190,217,1,115,184,214,1,208,208,208,8,82,167,204,1,53,156,199,1, + 62,161,204,1,15,15,255,1,208,208,208,1,15,15,255,1,208,208,208,1, + 15,15,255,1,208,208,208,1,15,15,255,1,208,208,208,1,15,15,255,1, + 208,208,208,1,107,179,212,1,94,173,207,1,82,167,204,1,208,208,208,8, + 49,150,194,1,33,142,187,1,36,146,194,1,208,208,208,10,73,158,206,1, + 60,155,197,1,49,150,194,1,208,208,208,8,16,133,184,1,12,126,177,1, + 208,208,208,12,24,138,186,1,16,133,184,1,208,208,208,100,156,1,0,0, + 0,0,0,101,208,208,208,1,124,124,124,1,7,7,7,1,0,0,0,21, + 32,32,32,1,176,176,176,1,219,219,219,1,73,73,73,1,0,0,0,22, + 73,73,73,1,219,219,219,1,176,176,176,1,32,32,32,1,0,0,0,21, + 7,7,7,1,124,124,124,1,236,236,236,1,124,124,124,1,7,7,7,1, + 0,0,0,21,32,32,32,1,175,175,175,1,219,219,219,1,73,73,73,1, + 0,0,0,14,255,255,255,1,85,85,85,1,0,0,0,6,73,73,73,1, + 219,219,219,1,176,176,176,1,32,32,32,1,0,0,0,2,85,85,85,1, + 255,255,255,1,0,0,0,8,255,255,255,1,234,234,234,1,21,21,21,1, + 0,0,0,6,7,7,7,1,124,124,124,1,208,208,208,1,0,0,0,1, + 21,21,21,1,234,234,234,1,255,255,255,1,0,0,0,8,255,255,255,2, + 170,170,170,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1, + 255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1, + 0,0,0,1,170,170,170,1,255,255,255,2,0,0,0,8,255,255,255,16, + 0,0,0,8,255,255,255,16,0,0,0,8,255,255,255,16,0,0,0,8, + 255,255,255,16,0,0,0,8,255,255,255,16,0,0,0,8,255,255,255,2, + 170,170,170,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1, + 255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1, + 0,0,0,1,170,170,170,1,255,255,255,2,0,0,0,8,255,255,255,1, + 234,234,234,1,21,21,21,1,0,0,0,10,21,21,21,1,234,234,234,1, + 255,255,255,1,0,0,0,8,255,255,255,1,85,85,85,1,0,0,0,12, + 85,85,85,1,255,255,255,1,0,0,0,100,0,0) + ); + +const + objdata_tprocessmonitor: record size: integer; data: array[0..2246] of byte end = + (size: 2247; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,112,114, + 111,99,101,115,115,109,111,110,105,116,111,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,8,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,12,4,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,39,15,147,0, + 2,208,208,208,21,20,144,0,1,27,145,7,1,23,145,5,1,208,208,208, + 19,0,128,0,1,19,144,0,1,54,160,38,1,146,224,139,1,90,190,77, + 1,20,141,0,1,208,208,208,8,0,0,0,1,82,82,82,1,14,14,14, + 1,142,142,142,1,208,208,208,2,0,0,0,1,58,58,58,1,208,208,208, + 1,17,103,0,1,2,13,0,1,9,18,8,1,129,180,127,1,104,197,92, + 1,23,145,4,1,13,108,0,1,26,26,26,1,34,34,34,1,161,161,161, + 1,208,208,208,5,0,0,0,1,143,143,143,1,146,146,146,1,30,30,30, + 1,208,208,208,2,0,0,0,1,174,174,174,1,18,143,0,1,5,21,2, + 1,97,154,93,1,112,165,108,1,6,23,4,1,19,143,0,1,208,208,208, + 1,33,33,33,1,143,143,143,1,160,160,160,1,28,28,28,1,208,208,208, + 5,0,0,0,1,203,203,203,1,202,202,202,1,4,4,4,1,208,208,208, + 2,0,0,0,1,19,144,0,1,62,167,45,1,2,3,2,1,101,192,88, + 1,22,142,3,1,0,2,0,1,208,208,208,2,3,3,3,1,203,203,203, + 1,208,208,208,7,0,0,0,1,149,149,149,1,147,147,147,1,33,33,33, + 1,208,208,208,1,23,139,0,1,0,0,0,1,111,200,100,1,162,237,157, + 1,6,22,4,1,13,102,0,1,148,148,148,1,29,29,29,1,208,208,208, + 2,29,29,29,1,148,148,148,1,162,162,162,1,29,29,29,1,208,208,208, + 5,0,0,0,1,65,65,65,1,18,18,18,1,150,150,150,1,19,147,0, + 1,33,151,15,1,0,0,0,1,101,196,90,1,22,146,3,1,11,105,0, + 1,18,18,18,1,20,20,20,1,148,148,148,1,208,208,208,2,148,148,148, + 1,20,20,20,1,15,15,15,1,147,147,147,1,208,208,208,5,0,0,0, + 1,208,208,208,2,18,145,0,1,62,170,47,1,157,235,153,1,43,158,26, + 1,18,146,0,1,208,208,208,16,0,0,0,1,208,208,208,1,18,146,0, + 1,45,161,29,1,131,215,121,1,23,146,4,1,16,143,0,1,208,208,208, + 20,19,144,0,1,22,144,3,1,22,140,0,1,21,142,0,1,18,143,0, + 1,0,255,0,1,208,208,208,19,0,255,0,1,19,145,0,1,20,142,0, + 1,21,140,0,1,20,144,0,1,19,143,0,1,208,208,208,20,23,139,0, + 1,19,143,0,1,20,142,0,1,21,141,0,1,19,145,0,1,32,159,0, + 1,208,208,208,12,0,0,0,1,96,96,96,1,8,8,8,1,110,110,110, + 1,78,78,78,1,7,7,7,1,142,142,142,1,208,208,208,1,15,147,0, + 1,15,101,0,1,2,13,0,2,13,104,0,1,208,208,208,2,0,0,0, + 1,64,64,64,1,7,7,7,1,142,142,142,1,208,208,208,5,0,0,0, + 1,145,145,145,1,175,175,175,1,2,2,2,1,145,145,145,1,142,142,142, + 1,4,4,4,1,18,237,0,1,0,255,0,1,29,29,29,1,14,103,0, + 1,14,101,0,1,3,20,0,1,19,143,0,1,0,170,0,1,0,0,0, + 1,148,148,148,1,142,142,142,1,4,4,4,1,208,208,208,5,0,0,0, + 1,206,206,206,1,208,208,208,1,0,0,0,1,207,207,207,1,208,208,208, + 1,0,0,0,1,33,165,12,1,30,199,17,1,2,2,2,1,15,146,0, + 1,18,141,0,1,0,2,0,1,20,143,0,1,208,208,208,1,0,0,0, + 1,207,207,207,1,208,208,208,1,0,0,0,1,208,208,208,5,0,0,0, + 1,208,208,208,2,0,0,0,1,208,208,208,2,0,0,0,1,88,185,72, + 1,74,207,64,1,3,20,0,1,13,102,0,1,13,103,0,1,0,18,0, + 1,208,208,208,2,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208, + 5,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,2,0,0,0, + 1,148,226,140,1,63,180,47,1,14,101,0,1,2,13,0,1,20,20,20, + 1,148,148,148,1,208,208,208,2,0,0,0,1,208,208,208,2,0,0,0, + 1,208,208,208,10,36,200,27,1,136,220,130,1,173,244,169,1,102,193,90, + 1,50,162,33,1,21,148,0,1,18,169,0,1,16,239,0,1,208,208,208, + 16,111,209,97,1,174,245,171,1,118,203,108,1,58,158,42,1,20,136,0, + 1,20,146,0,1,17,165,0,1,17,238,0,1,208,208,208,15,43,206,27, + 1,132,222,127,1,85,193,74,1,33,174,22,1,23,209,0,1,208,208,208, + 19,0,255,0,1,208,208,208,41,8,4,0,0,0,0,0,39,33,33,33, + 2,0,0,0,21,76,76,76,1,208,208,208,1,163,163,163,1,0,0,0, + 19,2,2,2,1,133,133,133,1,202,202,202,1,253,253,253,1,199,199,199, + 1,38,38,38,1,0,0,0,8,255,255,255,1,155,155,155,1,238,238,238, + 1,81,81,81,1,0,0,0,2,255,255,255,1,184,184,184,1,0,0,0, + 1,90,90,90,1,249,249,249,1,251,251,251,1,255,255,255,1,202,202,202, + 1,180,180,180,1,87,87,87,1,223,223,223,1,213,213,213,1,58,58,58, + 1,0,0,0,5,255,255,255,1,80,80,80,1,76,76,76,1,218,218,218, + 1,0,0,0,2,255,255,255,1,42,42,42,1,57,57,57,1,248,248,248, + 1,237,237,237,1,239,239,239,1,248,248,248,1,96,96,96,1,0,0,0, + 1,214,214,214,1,80,80,80,1,59,59,59,1,221,221,221,1,0,0,0, + 5,255,255,255,1,6,6,6,1,7,7,7,1,250,250,250,1,0,0,0, + 2,255,255,255,1,110,110,110,1,203,203,203,1,255,255,255,1,204,204,204, + 1,172,172,172,1,251,251,251,1,0,0,0,2,251,251,251,1,6,6,6, + 1,0,0,0,7,255,255,255,1,72,72,72,1,75,75,75,1,214,214,214, + 1,0,0,0,1,11,11,11,1,255,255,255,1,204,204,204,1,228,228,228, + 1,248,248,248,1,133,133,133,1,74,74,74,1,219,219,219,1,0,0,0, + 2,219,219,219,1,73,73,73,1,57,57,57,1,220,220,220,1,0,0,0, + 5,255,255,255,1,175,175,175,1,233,233,233,1,71,71,71,1,40,40,40, + 1,199,199,199,1,255,255,255,1,202,202,202,1,159,159,159,1,88,88,88, + 1,233,233,233,1,231,231,231,1,73,73,73,1,0,0,0,2,73,73,73, + 1,230,230,230,1,236,236,236,1,75,75,75,1,0,0,0,5,255,255,255, + 1,0,0,0,2,86,86,86,1,205,205,205,1,217,217,217,1,200,200,200, + 1,70,70,70,1,0,0,0,16,255,255,255,1,0,0,0,1,70,70,70, + 1,237,237,237,1,228,228,228,1,235,235,235,1,32,32,32,1,0,0,0, + 20,55,55,55,1,196,196,196,1,222,222,222,1,218,218,218,1,98,98,98, + 1,1,1,1,1,0,0,0,19,1,1,1,1,93,93,93,1,215,215,215, + 1,228,228,228,1,190,190,190,1,41,41,41,1,0,0,0,20,11,11,11, + 1,134,134,134,1,228,228,228,1,231,231,231,1,132,132,132,1,8,8,8, + 1,0,0,0,12,255,255,255,1,137,137,137,1,245,245,245,1,120,120,120, + 1,159,159,159,1,247,247,247,1,81,81,81,1,0,0,0,1,33,33,33, + 1,197,197,197,1,254,254,254,1,251,251,251,1,121,121,121,1,0,0,0, + 2,255,255,255,1,177,177,177,1,247,247,247,1,81,81,81,1,0,0,0, + 5,255,255,255,1,77,77,77,1,41,41,41,1,253,253,253,1,77,77,77, + 1,81,81,81,1,250,250,250,1,14,14,14,1,9,9,9,1,219,219,219, + 1,120,120,120,1,223,223,223,1,255,255,255,1,162,162,162,1,3,3,3, + 1,255,255,255,1,73,73,73,1,81,81,81,1,250,250,250,1,0,0,0, + 5,255,255,255,1,2,2,2,1,0,0,0,1,255,255,255,1,1,1,1, + 1,0,0,0,1,255,255,255,1,124,124,124,1,59,59,59,1,252,252,252, + 1,23,23,23,1,182,182,182,1,254,254,254,1,50,50,50,1,0,0,0, + 1,255,255,255,1,1,1,1,1,0,0,0,1,255,255,255,1,0,0,0, + 5,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255, + 1,223,223,223,1,96,96,96,1,227,227,227,1,226,226,226,1,158,158,158, + 1,220,220,220,1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,5,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0, + 2,255,255,255,2,174,174,174,1,204,204,204,1,236,236,236,1,231,231,231, + 1,73,73,73,1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,10,56,56,56,1,240,240,240,1,255,255,255,1,239,239,239, + 1,183,183,183,1,136,136,136,1,86,86,86,1,16,16,16,1,0,0,0, + 16,173,173,173,1,255,255,255,2,239,239,239,1,191,191,191,1,140,140,140, + 1,88,88,88,1,15,15,15,1,0,0,0,15,84,84,84,1,193,193,193, + 1,144,144,144,1,94,94,94,1,22,22,22,1,0,0,0,19,3,3,3, + 1,0,0,0,41,0,0) + ); + +const + objdata_tfacelist: record size: integer; data: array[0..2156] of byte end = + (size: 2157; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,102,97, + 99,101,108,105,115,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,248,7,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,128,7,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,208,208,208,4,159,159,159,20,208,208,208,4,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,208, + 208,208,2,159,159,159,20,13,132,255,1,102,102,102,1,208,208,208,2,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,159,159,159,20,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22, + 240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22, + 240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22, + 240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,3,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,208,208,208,2,159,159,159,1,22,240,255,1,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,102,102,102,3,208,208,208,2,159,159,159,1,22, + 240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,208,208,208,4,102, + 102,102,20,208,208,208,4,64,0,0,0,0,0,0,4,255,255,255,20,0, + 0,0,4,255,255,255,20,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,255,255,255,255,173,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,20,0,0,0,4,255,255,255,20,0,0,0,4,0,0) + ); + +const + objdata_tpagesizeselector: record size: integer; data: array[0..1196] of byte end = + (size: 1197; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,112,97, + 103,101,115,105,122,101,115,101,108,101,99,116,111,114,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255, + 255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,223, + 223,223,1,0,0,0,1,255,255,255,5,0,0,0,1,234,234,234,1,23, + 23,23,1,255,255,255,6,128,128,128,1,255,255,255,2,88,88,88,1,75, + 75,75,1,89,89,89,1,255,255,255,2,159,159,159,1,0,0,0,1,255, + 255,255,6,0,0,0,1,255,255,255,2,208,208,208,3,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,251,251,251,1,21,21,21,1,221, + 221,221,1,20,20,20,1,251,251,251,1,255,255,255,1,95,95,95,1,0, + 0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,191,191,191,1,0, + 0,0,3,191,191,191,1,255,255,255,1,31,31,31,1,0,0,0,1,255, + 255,255,6,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,114, + 114,114,1,141,141,141,1,255,255,255,1,141,141,141,1,115,115,115,1,255, + 255,255,1,0,0,0,3,255,255,255,3,252,252,252,1,231,231,231,1,0, + 0,0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217,1,255, + 255,255,1,217,217,217,1,38,38,38,1,255,255,255,2,0,0,0,1,255, + 255,255,4,223,223,223,1,0,0,0,1,223,223,223,1,0,0,0,1,128, + 128,128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0,2,255, + 255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,223, + 223,223,1,0,0,0,1,255,255,255,9,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,0,0,0,2,255,255,255,2,88,88,88,1,75, + 75,75,1,89,89,89,1,255,255,255,2,159,159,159,1,0,0,0,1,255, + 255,255,9,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,1,251, + 251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255, + 255,255,1,95,95,95,1,0,0,0,1,255,255,255,9,208,208,208,3,128, + 128,128,1,0,0,0,2,255,255,255,1,191,191,191,1,0,0,0,3,191, + 191,191,1,255,255,255,1,31,31,31,1,0,0,0,1,255,255,255,8,128, + 128,128,5,0,0,0,2,255,255,255,1,114,114,114,1,141,141,141,1,255, + 255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,3,255, + 255,255,8,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0, + 0,0,2,255,255,255,1,37,37,37,1,217,217,217,1,255,255,255,1,217, + 217,217,1,38,38,38,1,255,255,255,2,0,0,0,1,255,255,255,9,254, + 254,254,1,209,209,209,1,254,254,254,1,128,128,128,1,0,0,0,2,255, + 255,255,18,128,128,128,4,0,0,0,2,255,255,255,2,165,165,165,1,0, + 0,0,1,165,165,165,1,255,255,255,1,212,212,212,1,0,0,0,3,255, + 255,255,9,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,255, + 255,255,2,88,88,88,1,75,75,75,1,89,89,89,1,255,255,255,1,127, + 127,127,1,133,133,133,1,255,255,255,11,252,252,252,1,255,255,255,2,0, + 0,0,2,255,255,255,1,251,251,251,1,21,21,21,1,221,221,221,1,20, + 20,20,1,251,251,251,1,42,42,42,1,38,38,38,1,14,14,14,1,156, + 156,156,1,255,255,255,8,208,208,208,3,128,128,128,1,0,0,0,2,255, + 255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,2,245, + 245,245,1,22,22,22,1,255,255,255,8,0,0,0,3,128,128,128,1,0, + 0,0,2,255,255,255,1,114,114,114,1,141,141,141,1,255,255,255,1,141, + 141,141,1,115,115,115,1,31,31,31,1,231,231,231,1,246,246,246,1,36, + 36,36,1,255,255,255,8,208,208,208,1,0,0,0,1,208,208,208,1,128, + 128,128,1,0,0,0,2,255,255,255,1,37,37,37,1,217,217,217,1,255, + 255,255,1,217,217,217,1,38,38,38,1,174,174,174,1,18,18,18,1,24, + 24,24,1,181,181,181,1,255,255,255,7,128,128,128,5,0,0,0,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tpageorientationselector: record size: integer; data: array[0..1451] of byte end = + (size: 1452; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,24,116,112,97, + 103,101,111,114,105,101,110,116,97,116,105,111,110,115,101,108,101,99,116,111, + 114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109, + 111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,40,5,0,0,0,0,0,0,6,0,0,0,24,0, + 0,0,24,0,0,0,228,4,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,128,128,128,14,99,99,99,1,128,128,128,10,255,255,255,1,0,0, + 0,1,2,2,2,1,109,109,109,1,255,255,255,9,0,0,0,2,234,234, + 234,1,23,23,23,1,255,255,255,6,128,128,128,1,255,255,255,1,0,0, + 0,1,237,237,237,1,11,11,11,1,255,255,255,1,180,180,180,1,23,23, + 23,1,24,24,24,1,184,184,184,1,255,255,255,1,0,0,0,1,71,71, + 71,1,0,0,0,4,255,255,255,2,208,208,208,3,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,0,0,0,1,233,233,233,1,13,13, + 13,1,255,255,255,1,36,36,36,1,181,181,181,1,179,179,179,1,36,36, + 36,1,255,255,255,1,0,0,0,1,213,213,213,1,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,3,128,128, + 128,1,255,255,255,1,128,128,128,1,255,255,255,1,0,0,0,2,99,99, + 99,1,255,255,255,1,3,3,3,1,249,249,249,1,248,248,248,1,4,4, + 4,1,255,255,255,1,0,0,0,1,254,254,254,1,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,208,208,208,1,0,0, + 0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255, + 255,1,0,0,0,1,255,255,255,3,35,35,35,1,181,181,181,2,36,36, + 36,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,218,218, + 218,1,0,0,0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128, + 128,1,255,255,255,1,128,128,128,1,255,255,255,1,0,0,0,1,255,255, + 255,3,179,179,179,1,22,22,22,1,24,24,24,1,182,182,182,1,255,255, + 255,1,0,0,0,1,255,255,255,2,49,49,49,1,0,0,0,1,223,223, + 223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255,255, + 255,13,197,197,197,1,255,255,255,8,0,0,0,2,255,255,255,1,0,0, + 0,1,2,2,2,1,109,109,109,1,255,255,255,9,0,0,0,1,255,255, + 255,4,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0, + 0,2,255,255,255,1,0,0,0,1,237,237,237,1,11,11,11,1,255,255, + 255,1,180,180,180,1,23,23,23,1,24,24,24,1,184,184,184,1,255,255, + 255,1,0,0,0,1,71,71,71,1,0,0,0,3,255,255,255,3,0,0, + 0,3,128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1,233,233, + 233,1,13,13,13,1,255,255,255,1,36,36,36,1,181,181,181,1,179,179, + 179,1,36,36,36,1,255,255,255,1,0,0,0,1,213,213,213,1,255,255, + 255,1,0,0,0,1,255,255,255,4,208,208,208,3,128,128,128,1,0,0, + 0,2,255,255,255,1,0,0,0,2,99,99,99,1,255,255,255,1,3,3, + 3,1,249,249,249,1,248,248,248,1,4,4,4,1,255,255,255,1,0,0, + 0,1,254,254,254,1,255,255,255,1,0,0,0,1,255,255,255,3,128,128, + 128,5,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,35,35, + 35,1,181,181,181,2,36,36,36,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,241,241,241,1,255,255,255,3,212,212,212,1,252,252, + 252,1,208,208,208,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,3,179,179,179,1,22,22,22,1,24,24,24,1,182,182, + 182,1,255,255,255,1,0,0,0,1,255,255,255,2,56,56,56,1,7,7, + 7,1,255,255,255,3,254,254,254,1,209,209,209,1,254,254,254,1,128,128, + 128,1,0,0,0,2,255,255,255,18,128,128,128,4,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,13,0,0,0,1,255,255,255,3,211,211, + 211,1,255,255,255,1,208,208,208,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,2,108,108,108,1,14,14,14,1,7,7,7,1,88,88, + 88,1,255,255,255,1,5,5,5,1,196,196,196,1,255,255,255,1,173,173, + 173,1,18,18,18,1,92,92,92,1,0,0,0,1,255,255,255,3,252,252, + 252,1,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,4,220,220,220,1,1,1,1,1,255,255,255,1,0,0,0,1,5,5, + 5,1,255,255,255,1,35,35,35,1,183,183,183,1,177,177,177,1,0,0, + 0,1,255,255,255,2,208,208,208,3,128,128,128,1,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,2,177,177,177,1,76,76,76,1,31,31, + 31,1,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,1,4,4, + 4,1,249,249,249,1,248,248,248,1,0,0,0,1,255,255,255,2,0,0, + 0,3,128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,2,13,13,13,1,175,175,175,1,158,158,158,1,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,1,39,39,39,1,178,178,178,1,182,182, + 182,1,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208, + 208,1,128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,3,94,94, + 94,1,8,8,8,1,112,112,112,1,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,1,180,180,180,1,19,19,19,1,94,94,94,1,0,0, + 0,1,255,255,255,1,128,128,128,5,0,0,0,25,12,0,0,0,255,255, + 255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tassistivehandler: record size: integer; data: array[0..1548] of byte end = + (size: 1549; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,97,115, + 115,105,115,116,105,118,101,104,97,110,100,108,101,114,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,144, + 5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,24, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,104,109, + 11,179,1,133,12,224,1,130,12,221,1,97,12,170,1,85,0,149,1,129, + 13,219,1,135,14,228,1,121,13,199,1,0,0,0,15,104,8,175,1,127, + 12,216,1,132,12,225,2,114,11,192,1,112,10,187,1,133,12,226,2,129, + 12,218,1,90,8,158,1,0,0,0,13,85,6,146,1,112,9,189,1,116, + 9,198,3,111,9,187,1,110,9,188,1,117,9,199,3,105,9,181,1,0, + 0,0,12,58,0,104,1,92,7,159,1,99,7,171,2,100,7,171,2,100, + 7,172,4,100,7,173,1,101,7,172,1,80,6,138,1,0,0,0,10,39, + 0,78,1,76,4,131,1,83,4,144,3,83,4,145,2,84,4,145,3,84, + 4,146,3,80,4,140,1,61,6,105,1,0,0,0,8,44,0,78,1,61, + 1,107,1,66,1,117,2,67,1,117,1,67,1,118,4,67,1,119,2,68, + 1,119,2,68,1,120,2,65,1,116,1,54,3,94,1,0,0,0,6,28, + 0,52,1,49,0,86,1,50,0,91,1,50,0,89,2,47,0,84,1,43, + 0,77,1,46,0,84,1,54,0,89,1,43,0,78,4,43,0,79,1,51, + 0,88,1,50,0,89,1,51,0,90,2,41,0,73,1,0,0,0,6,61, + 2,107,1,70,2,124,4,63,1,110,1,51,0,77,1,0,0,0,4,56, + 3,101,1,68,2,121,1,70,2,124,3,61,2,109,1,43,0,43,1,0, + 0,0,6,51,0,51,1,73,4,126,1,81,4,141,4,77,3,133,1,68, + 5,118,1,59,4,102,1,67,3,114,1,74,5,128,1,80,4,140,1,81, + 4,141,3,72,4,126,1,0,0,85,1,0,0,0,8,62,0,106,1,87, + 5,149,1,91,5,157,11,88,5,151,1,66,0,113,1,0,0,0,10,73, + 5,130,1,101,7,173,1,101,7,174,10,83,7,144,1,0,0,0,12,99, + 9,172,1,112,9,191,9,102,9,175,1,0,0,85,1,0,0,0,12,88, + 9,132,1,116,10,198,1,122,10,208,7,119,10,203,1,90,9,151,1,0, + 0,0,14,108,12,185,1,130,12,222,1,132,12,225,6,110,10,190,1,0, + 0,0,16,116,11,196,1,136,13,228,1,143,14,241,3,138,14,233,1,119, + 13,200,1,0,0,0,18,77,0,128,1,112,12,193,1,123,13,207,1,117, + 14,196,1,89,13,140,1,0,0,0,106,64,3,0,0,255,255,255,1,242, + 242,242,1,211,211,211,1,0,0,0,2,61,61,61,1,242,242,242,2,151, + 151,151,1,0,0,0,2,122,122,122,1,242,242,242,2,89,89,89,1,0, + 0,0,2,183,183,183,1,242,242,242,2,28,28,28,1,0,0,0,1,2, + 2,2,1,252,252,252,1,43,43,43,1,0,0,0,22,246,246,246,1,0, + 0,0,23,201,201,201,1,0,0,0,24,234,234,234,1,0,0,0,7,47, + 47,47,1,148,148,148,1,149,149,149,1,21,21,21,1,12,12,12,1,142, + 142,142,1,151,151,151,1,59,59,59,1,0,0,0,8,246,246,246,1,0, + 0,0,6,64,64,64,1,239,239,239,1,255,255,255,2,121,121,121,1,105, + 105,105,1,255,255,255,2,240,240,240,1,34,34,34,1,0,0,0,6,75, + 75,75,1,226,226,226,1,0,0,0,5,42,42,42,1,233,233,233,1,255, + 255,255,3,219,219,219,1,206,206,206,1,255,255,255,3,175,175,175,1,0, + 0,0,6,246,246,246,1,0,0,0,5,22,22,22,1,213,213,213,1,255, + 255,255,10,89,89,89,1,0,0,0,5,246,246,246,1,0,0,0,4,13, + 13,13,1,189,189,189,1,255,255,255,11,236,236,236,1,46,46,46,1,0, + 0,0,4,139,139,139,1,50,50,50,1,0,0,0,2,46,46,46,1,193, + 193,193,1,255,255,255,13,234,234,234,1,90,90,90,1,4,4,4,1,0, + 0,0,3,246,246,246,1,0,0,0,1,64,64,64,1,184,184,184,1,182, + 182,182,1,184,184,184,2,142,142,142,1,66,66,66,1,61,61,61,1,57, + 57,57,1,65,65,65,4,106,106,106,1,171,171,171,1,178,178,178,1,190, + 190,190,2,130,130,130,1,0,0,0,3,246,246,246,1,0,0,0,2,143, + 143,143,1,255,255,255,4,174,174,174,1,20,20,20,1,0,0,0,4,96, + 96,96,1,243,243,243,1,255,255,255,3,154,154,154,1,6,6,6,1,0, + 0,0,2,138,138,138,1,165,165,165,1,0,0,0,2,5,5,5,1,188, + 188,188,1,255,255,255,4,220,220,220,1,112,112,112,1,65,65,65,1,76, + 76,76,1,170,170,170,1,254,254,254,1,255,255,255,3,180,180,180,1,3, + 3,3,1,0,0,0,3,246,246,246,1,0,0,0,4,29,29,29,1,232, + 232,232,1,255,255,255,11,236,236,236,1,27,27,27,1,0,0,0,4,246, + 246,246,1,0,0,0,5,94,94,94,1,255,255,255,11,108,108,108,1,0, + 0,0,5,76,76,76,1,113,113,113,1,0,0,0,5,175,175,175,1,255, + 255,255,9,197,197,197,1,3,3,3,1,0,0,0,6,246,246,246,1,0, + 0,0,5,29,29,29,1,233,233,233,1,255,255,255,7,249,249,249,1,54, + 54,54,1,0,0,0,7,246,246,246,1,0,0,0,6,87,87,87,1,252, + 252,252,1,255,255,255,6,125,125,125,1,0,0,0,7,200,200,200,1,102, + 102,102,1,0,0,0,7,90,90,90,1,229,229,229,1,255,255,255,3,241, + 241,241,1,120,120,120,1,0,0,0,8,246,246,246,1,0,0,0,9,10, + 10,10,1,66,66,66,1,79,79,79,1,74,74,74,1,20,20,20,1,0, + 0,0,9,246,246,246,1,0,0,0,23,15,15,15,1,174,174,174,1,0, + 0,0,23,246,246,246,1,0,0,0,22,17,17,17,1,255,255,255,1,28, + 28,28,1,0,0,0,1,2,2,2,1,244,244,244,2,210,210,210,1,0, + 0,0,2,64,64,64,1,244,244,244,2,148,148,148,1,0,0,0,2,126, + 126,126,1,244,244,244,2,86,86,86,1,0,0,0,2,188,188,188,1,244, + 244,244,1,252,252,252,1,0,0) + ); + +const + objdata_tassistivewidgetitem: record size: integer; data: array[0..1207] of byte end = + (size: 1208; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,97,115, + 115,105,115,116,105,118,101,119,105,100,103,101,116,105,116,101,109,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,56,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,184,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,156, + 156,25,170,170,170,22,156,156,156,2,0,0,0,22,156,156,156,2,0,0, + 0,22,156,156,156,2,0,0,0,22,156,156,156,2,0,0,0,22,156,156, + 156,2,0,0,0,22,156,156,156,2,0,0,0,22,156,156,156,2,0,0, + 0,22,156,156,156,2,0,0,0,7,141,14,238,1,143,13,241,1,142,14, + 240,1,143,14,241,1,128,0,255,1,143,14,241,1,142,14,241,1,142,13, + 242,2,0,0,0,6,156,156,156,2,0,0,0,5,107,7,181,1,106,8, + 182,4,107,8,183,1,106,8,182,1,107,8,183,2,107,8,184,2,106,8, + 184,1,96,0,191,1,0,0,0,4,156,156,156,2,0,0,0,2,64,0, + 128,1,71,4,124,1,70,1,124,1,71,2,124,3,71,2,125,4,72,2, + 126,4,72,2,128,1,72,3,128,1,71,3,126,1,70,0,128,1,64,0, + 128,1,0,0,0,1,156,156,156,2,0,0,0,2,70,0,119,1,68,1, + 120,4,67,2,120,1,67,0,122,1,128,0,128,1,0,0,0,3,72,0, + 120,1,69,0,119,1,68,1,119,1,68,1,120,2,68,1,119,1,69,0, + 120,1,73,0,109,1,0,0,0,1,156,156,156,2,0,0,0,3,89,0, + 153,1,88,4,153,1,89,5,154,4,89,5,155,2,89,5,154,7,98,0, + 157,1,0,0,0,3,156,156,156,2,0,0,0,5,110,8,189,1,110,8, + 188,10,111,8,188,1,0,0,0,5,156,156,156,2,0,0,0,6,131,13, + 222,2,131,12,222,7,130,10,224,1,0,0,0,6,156,156,156,2,0,0, + 0,8,150,15,255,1,152,16,255,2,150,15,255,1,150,14,255,1,149,12, + 255,1,0,0,0,8,156,156,156,2,0,0,0,22,156,156,156,2,0,0, + 0,22,156,156,156,2,0,0,0,22,156,156,156,2,0,0,0,22,156,156, + 156,2,0,0,0,22,156,156,156,2,0,0,0,22,156,156,156,25,72,2, + 0,0,253,253,253,24,245,245,245,1,3,3,3,22,234,234,234,1,245,245, + 245,1,0,0,0,22,234,234,234,1,245,245,245,1,0,0,0,22,234,234, + 234,1,245,245,245,1,0,0,0,22,234,234,234,1,245,245,245,1,0,0, + 0,22,234,234,234,1,245,245,245,1,0,0,0,22,234,234,234,1,245,245, + 245,1,0,0,0,22,234,234,234,1,245,245,245,1,0,0,0,22,234,234, + 234,1,245,245,245,1,0,0,0,7,74,74,74,1,161,161,161,1,187,187, + 187,1,141,141,141,1,2,2,2,1,141,141,141,1,187,187,187,1,171,171, + 171,1,61,61,61,1,0,0,0,6,234,234,234,1,245,245,245,1,0,0, + 0,5,76,76,76,1,203,203,203,1,255,255,255,4,218,218,218,1,255,255, + 255,3,252,252,252,1,132,132,132,1,8,8,8,1,0,0,0,4,234,234, + 234,1,245,245,245,1,0,0,0,2,16,16,16,1,72,72,72,1,185,185, + 185,1,238,238,238,12,202,202,202,1,93,93,93,1,40,40,40,1,4,4, + 4,1,0,0,0,1,234,234,234,1,245,245,245,1,0,0,0,2,77,77, + 77,1,214,214,214,1,238,238,238,2,224,224,224,1,159,159,159,1,65,65, + 65,1,2,2,2,1,0,0,0,3,32,32,32,1,126,126,126,1,207,207, + 207,1,221,221,221,1,234,234,234,1,205,205,205,1,96,96,96,1,7,7, + 7,1,0,0,0,1,234,234,234,1,245,245,245,1,0,0,0,3,20,20, + 20,1,173,173,173,1,255,255,255,4,236,236,236,1,193,193,193,1,187,187, + 187,1,224,224,224,1,255,255,255,4,164,164,164,1,13,13,13,1,0,0, + 0,3,234,234,234,1,245,245,245,1,0,0,0,5,97,97,97,1,243,243, + 243,1,255,255,255,8,246,246,246,1,99,99,99,1,0,0,0,5,234,234, + 234,1,245,245,245,1,0,0,0,6,39,39,39,1,183,183,183,1,254,254, + 254,1,255,255,255,5,194,194,194,1,49,49,49,1,0,0,0,6,234,234, + 234,1,245,245,245,1,0,0,0,8,34,34,34,1,82,82,82,1,114,114, + 114,1,119,119,119,1,90,90,90,1,41,41,41,1,0,0,0,8,234,234, + 234,1,245,245,245,1,0,0,0,22,234,234,234,1,245,245,245,1,0,0, + 0,22,234,234,234,1,245,245,245,1,0,0,0,22,234,234,234,1,245,245, + 245,1,0,0,0,22,234,234,234,1,245,245,245,1,0,0,0,22,234,234, + 234,1,245,245,245,1,0,0,0,22,234,234,234,1,255,255,255,1,248,248, + 248,22,255,255,255,1,0,0) + ); + +initialization + registerobjectdata(@objdata_taction,tbitmapcomp,'taction'); + registerobjectdata(@objdata_timagelist,tbitmapcomp,'timagelist'); + registerobjectdata(@objdata_tstatfile,tbitmapcomp,'tstatfile'); + registerobjectdata(@objdata_tstringcontainer,tbitmapcomp,'tstringcontainer'); + registerobjectdata(@objdata_tkeystringcontainer,tbitmapcomp,'tkeystringcontainer'); + registerobjectdata(@objdata_trttistat,tbitmapcomp,'trttistat'); + registerobjectdata(@objdata_tbitmapcomp,tbitmapcomp,'tbitmapcomp'); + registerobjectdata(@objdata_ttimer,tbitmapcomp,'ttimer'); + registerobjectdata(@objdata_tanimtimer,tbitmapcomp,'tanimtimer'); + registerobjectdata(@objdata_tanimitemcomp,tbitmapcomp,'tanimitemcomp'); + registerobjectdata(@objdata_tpipereadercomp,tbitmapcomp,'tpipereadercomp'); + registerobjectdata(@objdata_tthreadcomp,tbitmapcomp,'tthreadcomp'); + registerobjectdata(@objdata_tframecomp,tbitmapcomp,'tframecomp'); + registerobjectdata(@objdata_tfacecomp,tbitmapcomp,'tfacecomp'); + registerobjectdata(@objdata_tfontcomp,tbitmapcomp,'tfontcomp'); + registerobjectdata(@objdata_tactivator,tbitmapcomp,'tactivator'); + registerobjectdata(@objdata_tpostscriptprinter,tbitmapcomp,'tpostscriptprinter'); + registerobjectdata(@objdata_tgdiprinter,tbitmapcomp,'tgdiprinter'); + registerobjectdata(@objdata_twmfprinter,tbitmapcomp,'twmfprinter'); + registerobjectdata(@objdata_tmainmenu,tbitmapcomp,'tmainmenu'); + registerobjectdata(@objdata_tpopupmenu,tbitmapcomp,'tpopupmenu'); + registerobjectdata(@objdata_tnoguiaction,tbitmapcomp,'tnoguiaction'); + registerobjectdata(@objdata_tskincontroller,tbitmapcomp,'tskincontroller'); + registerobjectdata(@objdata_tskinextender,tbitmapcomp,'tskinextender'); + registerobjectdata(@objdata_tshortcutcontroller,tbitmapcomp,'tshortcutcontroller'); + registerobjectdata(@objdata_thelpcontroller,tbitmapcomp,'thelpcontroller'); + registerobjectdata(@objdata_tguiprocess,tbitmapcomp,'tguiprocess'); + registerobjectdata(@objdata_tguithreadcomp,tbitmapcomp,'tguithreadcomp'); + registerobjectdata(@objdata_tprocessmonitor,tbitmapcomp,'tprocessmonitor'); + registerobjectdata(@objdata_tfacelist,tbitmapcomp,'tfacelist'); + registerobjectdata(@objdata_tpagesizeselector,tbitmapcomp,'tpagesizeselector'); + registerobjectdata(@objdata_tpageorientationselector,tbitmapcomp,'tpageorientationselector'); + registerobjectdata(@objdata_tassistivehandler,tbitmapcomp,'tassistivehandler'); + registerobjectdata(@objdata_tassistivewidgetitem,tbitmapcomp,'tassistivewidgetitem'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regmath.pas b/mseide-msegui/lib/common/regcomponents/regmath.pas new file mode 100644 index 0000000..8286378 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regmath.pas @@ -0,0 +1,199 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regmath; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + msetypes,classes,mclasses,msefft,msedesignintf,msesignal,msefilter, + mseformatstr, + msepropertyeditors,msestrings,msedesigner,msesigfft,regmath_bmp, + msesiggui,msesigfftgui,msesignoise,msesigmidi,msedatalist, + mseiircoeffeditor,msefircoeffeditor,msegui,sysutils,mseglob; + +type + tinputconnpropertyeditor = class(tsubcomponentpropertyeditor) + protected + function getlinksource: tcomponent; override; + public + function getvalue: msestring; override; + end; + + tinputconnarraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + toutputconnpropertyeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + end; + + tiircoeffpropertyeditor = class(tdatalistpropertyeditor) + public + procedure edit; override; + end; + + tfircoeffpropertyeditor = class(tdatalistpropertyeditor) + public + procedure edit; override; + end; + +procedure register; +begin + registercomponents('Math',[tsigcontroller,tsigout,tsigin, + tsigconnector,ttrigconnector, + tsigadd,tsigmult, + tsigdelay,tsigdelayn,tsigdelayvar,tsigfir,tsigiir, + tsigfilter,tsigfilterbank, + tsigwavetable,tsignoise,tsigfuncttable,tsigenvelope, + tsigsampler,tsigscope,tsigscopefft, + tsigfft,tfft,tsigsamplerfft, + tsigrealedit,tsigslider,tsigkeyboard, + tsigmidiconnector,tsigmidimulticonnector, + twavetableedit,tfuncttableedit,tffttableedit,tenvelopeedit + ]); + registercomponenttabhints(['Math'], + ['Experimental mathematical and signal processing components.']); + registerpropertyeditor(typeinfo(tdoubleconn),tdoublezcomp,'', + tsubcomponentpropertyeditor); +// registerpropertyeditor(typeinfo(tdoubleconn),tdoubleinpconnitem,'', +// tsubcomponentpropertyeditor); + registerpropertyeditor(typeinfo(tdoubleinputconn),nil,'', + tinputconnpropertyeditor); + registerpropertyeditor(typeinfo(tdoubleoutputconn),tdoubleinputconn,'', + toutputconnpropertyeditor); + registerpropertyeditor(typeinfo(tdoubleinpconnarrayprop),nil,'', + tinputconnarraypropertyeditor); + registerpropertyeditor(typeinfo(tcomplexdatalist),tsigiir,'coeff', + tiircoeffpropertyeditor); + registerpropertyeditor(typeinfo(trealdatalist),tsigfir,'coeff', + tfircoeffpropertyeditor); +end; + +{ tinputconnpropertyeditor } + +function tinputconnpropertyeditor.getvalue: msestring; +var + inst: tdoubleinputconn; +begin + inst:= tdoubleinputconn(getpointervalue); + if inst.source = nil then begin + result:= '<->'; + end + else begin + result:= msestring('<'+designer.getcomponentdispname(inst.source)+'>'); + end; +end; + +function tinputconnpropertyeditor.getlinksource: tcomponent; +begin + result:= tdoubleinputconn(getpointervalue).source; +end; + +{ tinputconnarraypropertyeditor } + +function tinputconnarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tinputconnpropertyeditor; +end; + +{ toutputconnpropertyeditor } + +function toutputconnpropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +var + cont1: tsigcontroller; +begin + cont1:= tdoubleinputconn(instance).controller; + result:= (cont1 <> nil) and (tdoubleoutputconn(acomponent).controller = cont1); +end; + +{ tiircoeffpropertyeditor } + +procedure tiircoeffpropertyeditor.edit; +var + inst: tsigiir; + int1,int2,int3: integer; +begin + with tiircoeffeditorfo.create(nil) do begin + inst:= tsigiir(component); + numed.gridvalues:= inst.origcoeff.asarrayim; + dened.gridvalues:= inst.origcoeff.asarrayre; + numdi.gridvalues:= inst.coeff.asarrayim; + dendi.gridvalues:= inst.coeff.asarrayre; + int3:= 0; + with grid.fixcols[-1] do begin + captions.count:= grid.rowcount; + for int1:= 0 to inst.sections.count - 1 do begin + if int1 <> 0 then begin + grid.rowlinewidth[int3-1]:= 3; + end; + for int2:= 0 to inst.sections[int1] - 1 do begin + captions[int3]:= 's'+inttostrmse(int1)+':'+inttostrmse(-int2); + inc(int3); + end; + end; + end; + if show(ml_application) = mr_ok then begin + inst.coeff.asarrayre:= dendi.gridvalues; + inst.coeff.asarrayim:= numdi.gridvalues; + inst.origcoeff.asarrayre:= dened.gridvalues; + inst.origcoeff.asarrayim:= numed.gridvalues; + self.modified(); + end; + free; + end; +end; + +{ tfircoeffpropertyeditor } + +procedure tfircoeffpropertyeditor.edit; +var + inst: tsigfir; + int1,int2,int3: integer; +begin + with tfircoeffeditorfo.create(nil) do begin + inst:= tsigfir(component); + coeffed.gridvalues:= inst.coeff.asarray; + int3:= 0; + with grid.fixcols[-1] do begin + captions.count:= grid.rowcount; + for int1:= 0 to inst.sections.count - 1 do begin + if int1 <> 0 then begin + grid.rowlinewidth[int3-1]:= 3; + end; + for int2:= 0 to inst.sections[int1] - 1 do begin + captions[int3]:= 's'+inttostrmse(int1)+':'+inttostrmse(-int2); + inc(int3); + end; + end; + end; + if show(ml_application) = mr_ok then begin + inst.coeff.asarray:= coeffed.gridvalues; + self.modified(); + end; + free; + end; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regmath_bmp.pas b/mseide-msegui/lib/common/regcomponents/regmath_bmp.pas new file mode 100644 index 0000000..b4eb168 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regmath_bmp.pas @@ -0,0 +1,4887 @@ +unit regmath_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tfft: record size: integer; data: array[0..1259] of byte end = + (size: 1260; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,4,116,102,102, + 116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109, + 111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,124,4,0,0,0,0,0,0,6,0,0,0,24,0, + 0,0,24,0,0,0,148,1,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0, + 0,4,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,3,208,208, + 208,22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,24,0,0, + 0,1,208,208,208,23,0,0,0,1,208,208,208,22,0,0,0,2,208,208, + 208,22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,3,0,0, + 0,18,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,18,208,208, + 208,3,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,4,0,0, + 0,2,208,208,208,6,0,0,0,2,208,208,208,5,0,0,0,1,208,208, + 208,2,0,0,0,5,208,208,208,1,0,0,0,5,208,208,208,3,0,0, + 0,2,208,208,208,4,0,0,0,2,208,208,208,2,0,0,0,5,208,208, + 208,1,0,0,0,5,208,208,208,3,0,0,0,2,208,208,208,4,0,0, + 0,1,208,208,208,3,0,0,0,2,208,208,208,4,0,0,0,2,208,208, + 208,6,0,0,0,2,208,208,208,4,0,0,0,1,208,208,208,3,0,0, + 0,2,208,208,208,4,0,0,0,2,208,208,208,6,0,0,0,2,208,208, + 208,4,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,4,0,0, + 0,2,208,208,208,6,0,0,0,2,208,208,208,5,0,0,0,1,208,208, + 208,23,0,0,0,1,208,208,208,22,0,0,0,2,208,208,208,22,0,0, + 0,1,208,208,208,23,0,0,0,1,208,208,208,23,0,0,0,2,208,208, + 208,23,0,0,0,1,208,208,208,22,0,0,0,3,208,208,208,2,0,0, + 0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208, + 208,2,0,0,0,3,176,2,0,0,240,240,240,2,210,210,210,1,0,0, + 0,2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120, + 120,1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240, + 240,2,22,22,22,1,0,0,0,1,7,7,7,1,240,240,240,1,52,52, + 52,1,0,0,0,22,240,240,240,1,0,0,0,23,202,202,202,1,0,0, + 0,24,217,217,217,1,0,0,0,23,240,240,240,1,0,0,0,22,75,75, + 75,1,225,225,225,1,0,0,0,22,240,240,240,1,0,0,0,23,240,240, + 240,1,0,0,0,3,58,58,58,1,72,72,72,4,7,7,7,1,42,42, + 42,1,72,72,72,4,22,22,22,1,70,70,70,1,72,72,72,4,55,55, + 55,1,0,0,0,2,135,135,135,1,45,45,45,1,0,0,0,2,206,206, + 206,1,165,165,165,1,152,152,152,3,15,15,15,1,152,152,152,1,187,187, + 187,1,152,152,152,3,47,47,47,1,148,148,148,1,152,152,152,1,214,214, + 214,1,189,189,189,1,152,152,152,1,117,117,117,1,0,0,0,3,240,240, + 240,1,0,0,0,2,206,206,206,1,33,33,33,1,0,0,0,4,152,152, + 152,1,87,87,87,1,0,0,0,6,154,154,154,1,93,93,93,1,0,0, + 0,5,240,240,240,1,0,0,0,2,206,206,206,1,68,68,68,1,40,40, + 40,2,22,22,22,1,0,0,0,1,152,152,152,1,113,113,113,1,40,40, + 40,2,31,31,31,1,0,0,0,3,154,154,154,1,93,93,93,1,0,0, + 0,4,135,135,135,1,165,165,165,1,0,0,0,2,206,206,206,1,186,186, + 186,1,176,176,176,2,99,99,99,1,0,0,0,1,152,152,152,1,203,203, + 203,1,176,176,176,2,137,137,137,1,0,0,0,3,154,154,154,1,93,93, + 93,1,0,0,0,4,240,240,240,1,0,0,0,3,206,206,206,1,33,33, + 33,1,0,0,0,4,152,152,152,1,87,87,87,1,0,0,0,6,154,154, + 154,1,93,93,93,1,0,0,0,4,240,240,240,1,0,0,0,3,206,206, + 206,1,33,33,33,1,0,0,0,4,152,152,152,1,87,87,87,1,0,0, + 0,6,154,154,154,1,93,93,93,1,0,0,0,4,75,75,75,1,105,105, + 105,1,0,0,0,2,206,206,206,1,33,33,33,1,0,0,0,4,152,152, + 152,1,87,87,87,1,0,0,0,6,154,154,154,1,93,93,93,1,0,0, + 0,5,240,240,240,1,0,0,0,23,240,240,240,1,0,0,0,22,202,202, + 202,1,97,97,97,1,0,0,0,22,240,240,240,1,0,0,0,23,240,240, + 240,1,0,0,0,23,7,7,7,1,172,172,172,1,0,0,0,23,240,240, + 240,1,0,0,0,22,22,22,22,1,240,240,240,1,37,37,37,1,0,0, + 0,2,232,232,232,1,240,240,240,1,210,210,210,1,0,0,0,2,60,60, + 60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240, + 240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tsigcontroller: record size: integer; data: array[0..2729] of byte end = + (size: 2730; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,105, + 103,99,111,110,116,114,111,108,108,101,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,96,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1, + 255,230,16,18,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14,1, + 229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1, + 243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175,1, + 255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,225,220,188,1,181,178,154,1, + 204,200,173,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,255,230,16,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 190,187,157,1,53,52,44,1,4,4,3,1,12,12,10,1,0,0,0,1, + 54,53,47,1,207,205,180,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,255,230,16,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,195,191,159,1,19,19,16,1, + 101,100,84,1,202,197,168,1,236,232,200,1,192,189,164,1,49,48,42,1, + 33,32,28,1,232,230,204,1,240,237,212,1,240,238,215,1,241,238,217,1, + 255,230,16,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120,1, + 229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,54,53,44,1,65,64,54,1,234,230,194,1, + 236,231,197,1,236,232,200,1,237,233,202,1,198,195,170,1,32,31,28,1, + 183,180,161,1,240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1, + 227,222,183,1,6,6,5,1,161,158,132,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1,181,177,146,1, + 0,0,0,1,197,194,163,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1,243,241,224,1, + 75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,255,230,16,1, + 231,225,180,1,231,226,183,1,232,227,185,1,189,185,153,1,0,0,0,1, + 190,187,157,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,255,230,16,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1, + 231,226,183,1,232,227,185,1,228,224,184,1,5,5,4,1,154,152,127,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 144,142,125,1,198,195,174,1,240,237,212,1,240,238,215,1,241,238,217,1, + 255,230,16,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1, + 229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,58,57,48,1,61,60,51,1,232,228,193,1, + 236,231,197,1,236,232,200,1,237,233,202,1,173,170,149,1,0,0,0,1, + 159,157,140,1,240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1, + 243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,229,223,173,1, + 229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,205,201,167,1,19,19,16,1,85,83,70,1,190,186,158,1, + 222,218,188,1,151,148,128,1,34,33,29,1,51,51,45,1,234,231,206,1, + 240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,183,179,151,1,46,45,38,1,0,0,0,2,2,2,2,1, + 83,82,72,1,218,216,190,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,255,230,16,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,220,216,184,1,201,197,170,1,229,225,195,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 255,230,16,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100,77,1, + 229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 255,230,16,18,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1, + 230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1, + 233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1, + 238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1, + 242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1, + 128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1, + 255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1, + 180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1, + 146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigadd: record size: integer; data: array[0..2846] of byte end = + (size: 2847; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,105, + 103,97,100,100,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,172,10,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,220,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178, + 1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193, + 1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207, + 1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222, + 1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,50,49,42,1,194,191,165,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,6,6,5,1,184,181,156,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,223,219,182,1,219,216,181,1,220,217,183,1,6,6,5, + 1,173,170,147,1,222,218,189,1,224,220,193,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,65,64,53,1,0,0,0,5,7,6,6,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,217,214,177,1,212,208,175,1,213,209,177,1,6,6,5,1,168,165,142, + 1,215,211,183,1,217,213,187,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,6,6,5,1,184,181,156,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,35,34,29,1,191,187,162,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178, + 1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190, + 1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205, + 1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220, + 1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244, + 1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248, + 2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173, + 1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128, + 1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255, + 22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195, + 1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146, + 1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128, + 2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188, + 1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248, + 1,244,244,244,1,0,0) + ); + +const + objdata_tsigmult: record size: integer; data: array[0..2863] of byte end = + (size: 2864; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,115,105, + 103,109,117,108,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224, + 178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230, + 193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235, + 207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240, + 222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28, + 26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18, + 14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7, + 7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,162,159,135,1,149,146,126,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156, + 120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,81,79,67,1,53,52,45,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,205,201,167,1,112,110,92,1,208,205,173,1,100,98, + 83,1,74,73,63,1,217,213,185,1,129,127,111,1,177,175,154,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,147,145,120,1,2,2,2,1,3,3,2,1,23,23,19,1,18,17, + 15,1,5,5,4,1,0,0,0,1,106,105,93,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,222,218,183,1,154,151,128,1,3,3,2,1,0,0,0,1,131,129, + 112,1,219,216,189,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7, + 7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,226,222, + 186,1,51,50,42,1,52,51,43,1,76,75,64,1,29,28,25,1,214,210, + 184,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222, + 171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,137,134,113,1,3,3, + 2,1,191,187,159,1,212,208,180,1,14,14,12,1,95,94,82,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,190,187,158,1,236,231, + 197,1,236,232,200,1,193,190,165,1,236,232,203,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28, + 26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222, + 171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204, + 191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11, + 9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143, + 120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1,86,85, + 75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37, + 34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248, + 248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203, + 203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128, + 128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131, + 131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128, + 128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195, + 195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210, + 210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128, + 128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158, + 158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248, + 248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244, + 244,1,0,0) + ); + +const + objdata_tsigdelay: record size: integer; data: array[0..2856] of byte end = + (size: 2857; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,105, + 103,100,101,108,97,121,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,180,10,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,228,8,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230, + 224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234, + 230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238, + 235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243, + 240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28, + 28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18, + 18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,180,178,161,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,116, + 114,102,1,87,86,78,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,232,229,205,1,112, + 111,100,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,192,188,155,1,167,164,136,1,168, + 165,139,1,169,166,140,1,169,166,141,1,198,195,168,1,237,233,202,1,176, + 173,152,1,111,110,97,1,214,211,188,1,240,237,212,1,112,111,100,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160, + 156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,145,142,117,1,94,92,77,1,95,93,78,1,95, + 93,79,1,23,23,19,1,115,113,97,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,112,111,100,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,148,146,123,1,46, + 45,39,1,228,224,193,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,186,183,154,1,28,27,23,1,208,204,174,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,213, + 209,174,1,32,32,26,1,179,176,148,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,229,224,185,1,58,57,47,1,139, + 137,115,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228, + 222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,101,98,81,1,96,94,78,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,223, + 218,178,1,0,0,0,1,32,31,26,1,36,35,30,3,95,94,81,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244, + 242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100,77,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,231, + 229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3,3,1,171, + 167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7,6,1,23, + 22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7,6,2,61, + 60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7,6,2,115, + 114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7,7,1,4, + 4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1,128, + 128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188, + 188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248, + 248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1,154, + 154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,229, + 229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1,255, + 255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1,240, + 240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1,255, + 255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,229, + 229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1,214, + 214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,139, + 139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1,248, + 248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203, + 203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128, + 128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigdelayn: record size: integer; data: array[0..2857] of byte end = + (size: 2858; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,115,105, + 103,100,101,108,97,121,110,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,180,10,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,228,8,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1, + 230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1, + 234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1, + 238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1, + 243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 226,223,198,1,176,174,155,1,240,238,215,1,221,218,199,1,203,201,185,1, + 243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,208,205,183,1, + 30,30,27,1,207,205,185,1,195,192,175,1,153,151,139,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,208,205,183,1,127,125,112,1, + 91,91,82,1,192,189,173,1,153,151,139,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,192,188,155,1,167,164,136,1, + 168,165,139,1,169,166,140,1,169,166,141,1,198,195,168,1,237,233,202,1, + 176,173,152,1,111,110,97,1,186,183,163,1,136,135,121,1,183,181,164,1, + 88,87,79,1,153,151,139,1,243,240,222,1,243,241,224,1,75,75,70,1, + 160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,145,142,117,1,94,92,77,1,95,93,78,1, + 95,93,79,1,23,23,19,1,115,113,97,1,237,233,202,1,238,234,205,1, + 238,235,207,1,208,205,183,1,136,135,121,1,240,238,215,1,106,105,95,1, + 153,151,139,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,148,146,123,1, + 46,45,39,1,228,224,193,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,186,183,154,1,28,27,23,1,208,204,174,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 213,209,174,1,32,32,26,1,179,176,148,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,229,224,185,1,58,57,47,1, + 139,137,115,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,101,98,81,1,96,94,78,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 223,218,178,1,0,0,0,1,32,31,26,1,36,35,30,3,95,94,81,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100,77,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3,3,1, + 171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7,6,1, + 23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7,6,2, + 61,60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7,6,2, + 115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7,7,1, + 4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1, + 154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1, + 240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1, + 214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1, + 248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2, + 203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1, + 128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigdelayvar: record size: integer; data: array[0..2859] of byte end = + (size: 2860; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,105, + 103,100,101,108,97,121,118,97,114,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,180,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,228,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22, + 17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60, + 49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112, + 98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201, + 185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242, + 227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,216,213,189,1,188,186,166,1,240,238,215,1,197,194,177,1,221,218, + 201,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,91,90,81,1,200,198,179,1,107,105,96,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,219,217, + 194,1,29,29,26,1,227,224,204,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,192,188,155,1,167,164, + 136,1,168,165,139,1,169,166,140,1,169,166,141,1,198,195,168,1,237,233, + 202,1,176,173,152,1,111,110,97,1,214,211,188,1,136,134,120,1,122,121, + 110,1,143,141,128,1,242,239,220,1,243,240,222,1,243,241,224,1,75,75, + 70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,145,142,117,1,94,92,77,1,95,93, + 78,1,95,93,79,1,23,23,19,1,115,113,97,1,237,233,202,1,238,234, + 205,1,238,235,207,1,187,185,165,1,130,128,115,1,240,238,215,1,110,108, + 99,1,201,199,183,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,148,146, + 123,1,46,45,39,1,228,224,193,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,186,183,154,1,28,27,23,1,208,204, + 174,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,213,209,174,1,32,32,26,1,179,176,148,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,229,224,185,1,58,57, + 47,1,139,137,115,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7, + 7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,101,98,81,1,96,94,78,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93, + 71,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,223,218,178,1,0,0,0,1,32,31,26,1,36,35,30,3,95,94, + 81,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242, + 227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100, + 77,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242, + 227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3, + 3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7, + 6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7, + 6,2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7, + 6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7, + 7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233, + 233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128, + 128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221, + 221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244, + 244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236, + 236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165, + 165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150, + 150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131, + 131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244, + 244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248, + 248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173, + 173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigfir: record size: integer; data: array[0..2862] of byte end = + (size: 2863; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,105, + 103,102,105,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178, + 1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193, + 1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207, + 1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222, + 1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,188,184,147, + 1,166,162,131,1,166,163,133,1,167,164,135,1,167,164,136,1,217,214,179, + 1,212,208,176,1,195,191,163,1,236,232,200,1,193,190,165,1,171,168,147, + 1,171,169,149,1,175,173,154,1,206,204,182,1,239,237,214,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120, + 1,229,223,173,1,229,224,175,1,230,224,178,1,79,77,61,1,67,66,53, + 1,94,92,75,1,94,92,76,1,94,92,77,1,199,196,164,1,153,150,127, + 1,90,88,75,1,236,232,200,1,81,79,69,1,80,79,69,1,111,110,97, + 1,106,105,93,1,45,45,40,1,88,88,79,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,79,77,61,1,167,163,132,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,153,150,127,1,90,88,75, + 1,236,232,200,1,81,79,69,1,172,169,148,1,238,235,207,1,239,236,210, + 1,233,230,206,1,15,15,13,1,225,222,203,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,79,77,61,1,140,137,111,1,196,191,156,1,196,192,159, + 1,207,204,169,1,234,230,193,1,153,150,127,1,90,88,75,1,236,232,200, + 1,81,79,69,1,161,159,139,1,223,220,194,1,218,216,192,1,164,162,145, + 1,37,36,33,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,230,224,178, + 1,79,77,61,1,52,51,41,1,72,70,57,1,72,71,58,1,118,116,96, + 1,234,230,193,1,153,150,127,1,90,88,75,1,236,232,200,1,81,79,69, + 1,37,37,32,1,49,49,43,1,7,6,6,1,91,90,81,1,214,212,191, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,79,77,61, + 1,167,163,132,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,153,150,127,1,90,88,75,1,236,232,200,1,81,79,69,1,172,169,148, + 1,238,235,207,1,191,189,168,1,28,28,25,1,212,210,190,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,79,77,61,1,167,163,132, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,153,150,127, + 1,90,88,75,1,236,232,200,1,81,79,69,1,172,169,148,1,238,235,207, + 1,239,236,210,1,134,132,118,1,56,56,51,1,240,237,216,1,242,239,220, + 1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,229,223,173, + 1,229,224,175,1,230,224,178,1,79,77,61,1,167,163,132,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,153,150,127,1,90,88,75, + 1,236,232,200,1,81,79,69,1,172,169,148,1,238,235,207,1,239,236,210, + 1,238,235,210,1,52,51,46,1,139,137,125,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191, + 1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9, + 1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120, + 1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75, + 1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34, + 1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248, + 1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203, + 1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128, + 2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131, + 1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128, + 1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195, + 1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128, + 2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158, + 1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248, + 2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244, + 1,0,0) + ); + +const + objdata_tsigiir: record size: integer; data: array[0..2862] of byte end = + (size: 2863; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,105, + 103,105,105,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178, + 1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193, + 1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207, + 1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222, + 1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,176,172,140,1,227,222,183,1,230,226,188,1,173,170,143, + 1,235,231,195,1,213,208,178,1,169,166,144,1,170,167,145,1,172,169,148, + 1,194,192,169,1,232,229,203,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,31,30,25,1,209,205,169,1,222,218,181,1,18,18,15,1,235,231,195, + 1,153,149,127,1,46,45,39,1,111,109,94,1,111,109,96,1,70,69,61, + 1,38,38,34,1,220,217,195,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,31,30,25, + 1,209,205,169,1,222,218,181,1,18,18,15,1,235,231,195,1,153,149,127, + 1,98,96,83,1,237,233,202,1,238,234,205,1,238,235,207,1,79,78,69, + 1,152,150,134,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,31,30,25,1,209,205,169, + 1,222,218,181,1,18,18,15,1,235,231,195,1,153,149,127,1,93,91,78, + 1,222,218,189,1,222,218,191,1,193,191,168,1,36,35,31,1,201,199,178, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,31,30,25,1,209,205,169,1,222,218,181, + 1,18,18,15,1,235,231,195,1,153,149,127,1,21,21,18,1,51,50,44, + 1,21,20,18,1,45,44,39,1,187,184,164,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,31,30,25,1,209,205,169,1,222,218,181,1,18,18,15, + 1,235,231,195,1,153,149,127,1,98,96,83,1,237,233,202,1,226,222,195, + 1,46,45,40,1,157,155,138,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,31,30,25,1,209,205,169,1,222,218,181,1,18,18,15,1,235,231,195, + 1,153,149,127,1,98,96,83,1,237,233,202,1,238,234,205,1,198,195,172, + 1,18,18,16,1,211,208,186,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,31,30,25, + 1,209,205,169,1,222,218,181,1,18,18,15,1,235,231,195,1,153,149,127, + 1,98,96,83,1,237,233,202,1,238,234,205,1,238,235,207,1,122,120,107, + 1,66,65,58,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191, + 1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9, + 1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120, + 1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75, + 1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34, + 1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248, + 1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203, + 1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128, + 2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131, + 1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128, + 1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195, + 1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128, + 2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158, + 1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248, + 2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244, + 1,0,0) + ); + +const + objdata_tsigfft: record size: integer; data: array[0..2858] of byte end = + (size: 2859; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,105, + 103,102,102,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,184,10,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,232,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178, + 1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193, + 1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207, + 1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222, + 1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,178,173,138,1,166,161,129, + 1,166,162,131,1,166,163,133,1,167,164,135,1,227,223,185,1,195,192,161, + 1,169,166,140,1,169,166,141,1,169,166,144,1,170,167,145,1,217,214,187, + 1,173,170,150,1,172,169,151,1,172,170,152,1,172,171,154,1,173,171,156, + 1,190,187,173,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120, + 1,229,223,173,1,229,224,175,1,44,43,34,1,82,79,64,1,93,91,74, + 1,94,92,75,1,94,92,76,1,219,216,179,1,95,93,78,1,63,62,52, + 1,95,93,80,1,95,94,81,1,96,94,82,1,194,191,167,1,100,99,87, + 1,97,95,85,1,39,38,34,1,62,62,56,1,97,96,88,1,131,129,119, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,44,43,34,1,201,196,157,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,95,93,78,1,155,152,128,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,95,94,84,1,152,151,137,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,44,43,34,1,169,165,132,1,195,191,154,1,196,191,156,1,213,208,172, + 1,233,229,190,1,95,93,78,1,131,129,109,1,199,195,166,1,199,196,169, + 1,208,205,177,1,238,234,205,1,238,235,207,1,239,236,210,1,95,94,84, + 1,152,151,137,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,44,43,34, + 1,63,61,49,1,72,70,57,2,143,139,115,1,233,229,190,1,95,93,78, + 1,48,47,40,1,73,72,61,1,73,72,62,1,110,108,93,1,238,234,205, + 1,238,235,207,1,239,236,210,1,95,94,84,1,152,151,137,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,44,43,34,1,201,196,157,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,95,93,78,1,155,152,128, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,95,94,84,1,152,151,137,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173, + 1,229,224,175,1,44,43,34,1,201,196,157,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,95,93,78,1,155,152,128,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,95,94,84,1,152,151,137,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,95,93,71,1,229,223,173,1,229,224,175, + 1,44,43,34,1,201,196,157,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,95,93,78,1,155,152,128,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,95,94,84, + 1,152,151,137,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227, + 1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100,77, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227, + 1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3,3, + 1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7,6, + 1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7,6, + 2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7,6, + 2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7,7, + 1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233, + 1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128, + 2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221, + 1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244, + 1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165, + 1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131, + 1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244, + 1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248, + 2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173, + 1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigin: record size: integer; data: array[0..2845] of byte end = + (size: 2846; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,115,105, + 103,105,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13, + 98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,172,10,0,0,0,0,0,0,6,0,0,0, + 24,0,0,0,24,0,0,0,220,8,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178,1, + 231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193,1, + 235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207,1, + 239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222,1, + 230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 231,227,192,1,176,172,147,1,236,232,200,1,211,207,180,1,194,191,167,1, + 238,235,207,1,239,236,210,1,240,237,212,1,200,199,180,1,220,217,198,1, + 242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120,1, + 229,223,173,1,229,224,175,1,230,224,178,1,127,124,99,1,177,173,140,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,220,217,183,1, + 21,21,18,1,236,232,200,1,142,140,121,1,10,10,9,1,205,203,179,1, + 239,236,210,1,240,237,212,1,99,98,89,1,164,162,148,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,177,172,138,1,22,21,17,1,177,174,141,1, + 233,228,188,1,233,229,190,1,234,230,193,1,220,217,183,1,21,21,18,1, + 236,232,200,1,142,140,121,1,41,40,35,1,58,57,50,1,238,235,209,1, + 240,237,212,1,99,98,89,1,164,162,148,1,242,239,220,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1, + 233,229,190,1,234,230,193,1,220,217,183,1,21,21,18,1,236,232,200,1, + 142,140,121,1,118,116,101,1,77,76,67,1,135,133,119,1,240,237,212,1, + 99,98,89,1,164,162,148,1,242,239,220,1,243,240,222,1,243,241,224,1, + 75,75,70,1,49,48,37,1,229,223,173,1,0,0,0,5,51,50,41,1, + 233,229,190,1,234,230,193,1,220,217,183,1,21,21,18,1,236,232,200,1, + 142,140,121,1,118,116,101,1,218,216,190,1,28,28,25,1,205,203,181,1, + 99,98,89,1,164,162,148,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1,233,229,190,1, + 234,230,193,1,220,217,183,1,21,21,18,1,236,232,200,1,142,140,121,1, + 118,116,101,1,238,235,207,1,160,158,141,1,55,54,48,1,96,95,86,1, + 164,162,148,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,177,172,138,1, + 22,21,17,1,177,174,141,1,233,228,188,1,233,229,190,1,234,230,193,1, + 220,217,183,1,21,21,18,1,236,232,200,1,142,140,121,1,118,116,101,1, + 238,235,207,1,239,236,210,1,82,81,72,1,15,15,13,1,164,162,148,1, + 242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1, + 229,223,173,1,229,224,175,1,230,224,178,1,127,124,99,1,177,173,140,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,220,217,183,1, + 21,21,18,1,236,232,200,1,142,140,121,1,118,116,101,1,238,235,207,1, + 239,236,210,1,222,219,196,1,22,21,19,1,164,162,148,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1, + 11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1, + 145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1, + 86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1, + 38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1, + 248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2, + 203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1, + 128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1, + 131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22, + 128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1, + 210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1, + 128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2, + 158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1, + 248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1, + 244,244,244,1,0,0) + ); + +const + objdata_tsigout: record size: integer; data: array[0..2846] of byte end = + (size: 2847; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,105, + 103,111,117,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,172,10,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,220,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178, + 1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193, + 1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207, + 1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222, + 1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,220,214,170,1,159,154,124, + 1,192,188,152,1,232,227,185,1,233,228,188,1,193,189,157,1,228,225,188, + 1,235,231,195,1,232,227,194,1,193,189,163,1,201,197,171,1,171,168,147, + 1,171,169,149,1,172,169,151,1,191,189,169,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120, + 1,229,223,173,1,221,216,169,1,49,47,38,1,84,82,66,1,73,72,58, + 1,121,118,96,1,233,228,188,1,88,86,72,1,212,208,175,1,235,231,195, + 1,222,217,185,1,81,79,68,1,159,156,135,1,96,95,83,1,27,27,24, + 1,97,95,85,1,136,135,121,1,240,238,215,1,132,131,119,1,185,183,168, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,139,136,106,1,122,119,94,1,231,225,180,1,231,226,183,1,69,68,55, + 1,206,201,166,1,88,86,72,1,212,208,175,1,235,231,195,1,222,217,185, + 1,81,79,68,1,237,233,202,1,238,234,205,1,66,65,58,1,239,236,210, + 1,240,237,212,1,240,238,215,1,184,182,166,1,23,22,21,1,186,184,170, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,86,84,66, + 1,180,176,140,1,231,225,180,1,231,226,183,1,136,133,108,1,160,156,129, + 1,88,86,72,1,212,208,175,1,235,231,195,1,222,217,185,1,81,79,68, + 1,237,233,202,1,238,234,205,1,66,65,58,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,185,183,168,1,23,23,21,1,186,184,171, + 1,75,75,70,1,49,48,37,1,229,223,173,1,70,69,54,1,219,213,170, + 1,231,225,180,1,231,226,183,1,150,147,120,1,138,135,111,1,88,86,72, + 1,212,208,175,1,235,231,195,1,222,217,185,1,81,79,68,1,237,233,202, + 1,238,234,205,1,66,65,58,1,239,236,210,1,0,0,0,5,53,53,49, + 1,7,7,7,1,228,222,171,1,229,223,173,1,101,99,78,1,172,168,133, + 1,231,225,180,1,231,226,183,1,99,97,79,1,173,169,139,1,103,101,84, + 1,200,197,165,1,235,231,195,1,197,193,165,1,95,94,81,1,237,233,202, + 1,238,234,205,1,66,65,58,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,185,183,168,1,23,23,21,1,186,184,171,1,7,7,7, + 1,228,222,171,1,229,223,173,1,171,167,130,1,84,82,65,1,225,219,175, + 1,206,201,163,1,51,50,41,1,220,215,178,1,136,134,111,1,146,143,120, + 1,235,231,195,1,141,138,117,1,129,126,109,1,237,233,202,1,238,234,205, + 1,66,65,58,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166, + 1,23,22,21,1,186,184,170,1,243,241,224,1,133,132,124,1,95,93,71, + 1,229,223,173,1,229,224,175,1,115,112,89,1,39,38,30,1,33,32,26, + 1,166,162,132,1,233,228,188,1,224,220,183,1,52,51,43,1,37,36,31, + 1,52,51,43,1,225,221,191,1,237,233,202,1,238,234,205,1,66,65,58, + 1,239,236,210,1,240,237,212,1,240,238,215,1,132,131,119,1,185,183,168, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,223,217,174,1,229,224,182,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,223,219,185,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178, + 1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190, + 1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205, + 1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220, + 1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244, + 1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248, + 2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173, + 1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128, + 1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255, + 22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195, + 1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146, + 1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128, + 2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188, + 1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248, + 1,244,244,244,1,0,0) + ); + +const + objdata_tsigconnector: record size: integer; data: array[0..2796] of byte end = + (size: 2797; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,105, + 103,99,111,110,110,101,99,116,111,114,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,116,10,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,164,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22, + 22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61, + 60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114, + 112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204, + 201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244, + 242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,75, + 75,70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,127,124,100,1,177,174,141,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,132, + 131,119,1,185,183,168,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,177, + 173,140,1,22,21,17,1,178,174,144,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166,1,23, + 22,21,1,186,184,170,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,177, + 174,141,1,22,21,18,1,178,175,145,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,185,183,168,1,23, + 23,21,1,186,184,171,1,75,75,70,1,49,48,37,1,229,223,173,1,229, + 224,175,1,0,0,0,19,53,53,49,1,7,7,7,1,228,222,171,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,177, + 174,141,1,22,21,18,1,178,175,145,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,185,183,168,1,23, + 23,21,1,186,184,171,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,177,173,140,1,22,21,17,1,178, + 174,144,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,184,182,166,1,23,22,21,1,186,184,170,1,243, + 241,224,1,133,132,124,1,95,93,71,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,127,124,100,1,177,174,141,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,132,131,119,1,185,183,168,1,243,240,222,1,243,241,224,1,244, + 242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100,77,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,231, + 229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3,3,1,171, + 167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7,6,1,23, + 22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7,6,2,61, + 60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7,6,2,115, + 114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7,7,1,4, + 4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1,128, + 128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188, + 188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248, + 248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1,154, + 154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,229, + 229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1,255, + 255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1,240, + 240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1,255, + 255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,229, + 229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1,214, + 214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,139, + 139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1,248, + 248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203, + 203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128, + 128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_ttrigconnector: record size: integer; data: array[0..2821] of byte end = + (size: 2822; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,116,114, + 105,103,99,111,110,110,101,99,116,111,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,140,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,188,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,156,155,229,1,90,89,241,1,241,238,219,1,243,240,222,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,234,231,211,1,107,106,236,1, + 88,88,246,1,131,130,244,1,177,175,213,1,242,239,221,1,243,241,224,1, + 244,242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,212,209,212,1,78,77,241,1,112,112,249,1,176,175,254,1, + 89,88,231,1,116,115,199,1,239,236,218,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,175,173,218,1, + 80,79,243,1,142,142,253,1,133,133,245,1,68,68,222,1,138,136,171,1, + 185,183,168,1,234,231,214,1,242,240,224,1,133,132,124,1,14,14,11,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,235,231,200,1,124,122,228,1,101,101,243,1,176,176,254,1, + 92,91,233,1,94,93,197,1,169,167,154,1,203,200,183,1,235,232,214,1, + 242,239,221,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,220,216,201,1, + 87,86,235,1,132,132,246,1,136,135,245,1,71,70,221,1,145,143,163,1, + 185,182,163,1,223,221,200,1,238,235,214,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,190,187,207,1,85,84,239,1,158,158,249,1, + 96,95,234,1,103,101,191,1,171,169,150,1,205,202,180,1,234,231,207,1, + 239,237,214,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 75,75,70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,127,124,100,1,177,174,141,1,233,228,188,1,233,229,190,1, + 143,140,217,1,108,107,241,1,135,134,244,1,79,78,221,1,152,149,157,1, + 186,183,160,1,223,220,194,1,236,233,208,1,240,237,212,1,240,238,215,1, + 132,131,119,1,185,183,168,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 177,173,140,1,22,21,17,1,177,173,144,1,94,92,229,1,136,135,243,1, + 91,90,238,1,117,115,187,1,173,170,147,1,206,202,175,1,233,229,200,1, + 237,234,206,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166,1, + 23,22,21,1,186,184,170,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 177,174,141,1,22,21,18,1,142,139,166,1,85,84,228,1,34,33,235,1, + 56,55,223,1,188,185,197,1,234,230,200,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,185,183,168,1, + 23,23,21,1,186,184,171,1,75,75,70,1,49,48,37,1,229,223,173,1, + 229,224,175,1,0,0,0,7,0,0,89,1,0,0,187,1,0,0,203,1, + 0,0,129,1,0,0,8,1,0,0,0,7,53,53,49,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,177,174,141,1,22,21,18,1,178,175,145,1,234,230,193,1, + 232,228,192,1,212,208,187,1,95,94,208,1,40,40,234,1,59,57,237,1, + 171,169,218,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 185,183,168,1,23,23,21,1,186,184,171,1,7,7,7,1,228,222,171,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,177,173,140,1, + 22,21,17,1,178,174,144,1,233,229,190,1,234,230,193,1,235,231,195,1, + 235,230,196,1,232,228,197,1,189,185,191,1,72,71,218,1,41,40,238,1, + 91,89,234,1,216,213,215,1,240,238,215,1,184,182,166,1,23,22,21,1, + 186,184,170,1,243,241,224,1,133,132,124,1,95,93,71,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,127,124,100,1,177,174,141,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,235,231,201,1,232,228,200,1,157,154,198,1,55,54,228,1, + 49,49,241,1,141,139,228,1,130,129,119,1,185,183,168,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,230,227,201,1, + 173,170,218,1,237,233,205,1,236,233,205,1,207,206,206,1,27,26,245,1, + 85,84,220,1,219,216,209,1,241,238,219,1,243,240,222,1,243,241,224,1, + 244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,143,141,225,1,150,148,230,1, + 228,224,196,1,181,179,218,1,62,61,243,1,180,177,218,1,208,206,186,1, + 223,220,201,1,241,238,219,1,243,240,222,1,243,241,224,1,28,28,26,1, + 103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,217,212,202,1,105,104,249,1,155,154,230,1,115,113,213,1, + 116,114,231,1,227,224,207,1,224,221,198,1,234,232,210,1,240,237,216,1, + 242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 145,142,230,1,160,160,255,1,129,129,248,1,108,107,217,1,182,180,214,1, + 230,227,204,1,238,235,211,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,202,199,205,1,152,152,252,1, + 150,150,255,1,88,88,255,1,26,26,255,1,30,30,244,1,93,92,233,1, + 205,203,217,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,154,153,235,1,144,144,245,1,108,107,213,1, + 104,103,187,1,135,133,162,1,168,166,146,1,182,179,160,1,210,207,185,1, + 237,235,212,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,205,201,203,1,191,187,160,1,176,173,149,1,193,190,165,1, + 211,208,182,1,229,226,199,1,236,233,207,1,239,236,211,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1, + 4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1, + 7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1, + 7,7,6,2,60,59,51,1,234,230,199,1,236,232,203,1,86,85,75,1, + 7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1, + 7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1, + 233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1, + 128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2, + 221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1, + 244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1, + 236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1, + 150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,204,204,204,1,129,129,129,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1, + 0,0) + ); + +const + objdata_tsigwavetable: record size: integer; data: array[0..2868] of byte end = + (size: 2869; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,105, + 103,119,97,118,101,116,97,98,108,101,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22, + 22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61, + 60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114, + 112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204, + 201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,149, + 146,120,1,139,137,113,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,236,233,215,1,110,108,100,1,242, + 240,223,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,43,42,35,1,17, + 17,14,1,228,224,188,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,173,171,157,1,56,56,51,1,243,241,224,1,244, + 242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,207,202,165,1,23,22,18,1,62,61,51,1,151, + 149,125,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,94,93,85,1,134,133,123,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,139,136,111,1,90,88,72,1,157,154,128,1,57,56,47,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,238,235,214,1,20, + 20,18,1,213,210,194,1,243,241,224,1,133,132,124,1,14,14,11,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,72, + 70,57,1,157,154,127,1,228,225,186,1,22,22,18,1,199,196,165,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,181,178,163,1,48,48,44,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,225,220,178,1,15,15,12,1,220, + 215,178,1,233,229,190,1,109,107,90,1,105,103,87,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,103,102,93,1,127,126,116,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,168,164,133,1,60,59,48,1,233,228,188,1,233, + 229,190,1,202,198,167,1,19,19,16,1,230,225,192,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,239, + 237,214,1,26,26,24,1,205,202,186,1,243,240,222,1,243,241,224,1,75, + 75,70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,100,97,79,1,127,125,102,1,233,228,188,1,233,229,190,1,234, + 230,193,1,62,61,51,1,154,150,128,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,188,187,169,1,41, + 40,37,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,33, + 32,26,1,196,191,156,1,233,228,188,1,233,229,190,1,234,230,193,1,156, + 153,129,1,58,57,49,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,111,110,99,1,119,118,107,1,242, + 239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,230,224,178,1,197,191,153,1,31,30,24,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,229,226,190,1,20, + 20,17,1,200,197,169,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,34,34,30,1,198,195,178,1,242,239,220,1,243, + 240,222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229, + 224,175,1,230,224,178,1,129,125,100,1,98,96,78,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,108,106,90,1,106, + 105,90,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,197, + 194,174,1,34,34,30,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,62,60,48,1,166,162,131,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,202,197,168,1,19,19,16,1,230, + 227,196,1,238,234,205,1,238,235,207,1,239,236,210,1,120,118,106,1,111, + 110,99,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,219,213,170,1,14, + 14,11,1,224,219,177,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,60,59,51,1,155,153,132,1,238, + 234,205,1,238,235,207,1,239,236,210,1,42,42,37,1,189,188,169,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95, + 93,71,1,229,223,173,1,229,224,175,1,157,153,121,1,69,67,54,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,155,152,131,1,59,58,51,1,238,234,205,1,238, + 235,207,1,204,202,180,1,27,27,24,1,239,237,214,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,89,87,69,1,137,133,107,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,230,227,195,1,20,19,17,1,203,199,174,1,238,235,207,1,127, + 126,112,1,104,103,92,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229, + 224,175,1,23,23,18,1,204,199,159,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,107,105,91,1,108,106,93,1,238,235,207,1,51,50,44,1,183, + 180,161,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,185,181,141,1,40, + 39,31,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,201, + 197,171,1,20,19,17,1,205,203,179,1,22,22,20,1,238,235,210,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,118,115,90,1,107,105,83,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,59, + 58,51,1,56,55,49,1,97,95,85,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228, + 222,171,1,229,223,173,1,51,50,39,1,175,170,135,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,154,151,133,1,0, + 0,0,1,174,172,153,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1,229, + 223,173,1,163,160,125,1,226,220,175,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,231,228,199,1,150,148,131,1,235, + 232,207,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230, + 224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233, + 229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238, + 234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242, + 239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244, + 244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248, + 248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173, + 173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128, + 128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255, + 255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195, + 195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180, + 180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146, + 146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128, + 128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188, + 188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248, + 248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigfuncttable: record size: integer; data: array[0..2869] of byte end = + (size: 2870; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,105, + 103,102,117,110,99,116,116,97,98,108,101,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 223,220,197,1,120,119,107,1,120,119,108,1,121,119,110,1,121,120,111,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,232,229,203,1,33,33,29,1, + 104,104,94,1,120,119,108,1,121,119,110,1,121,120,111,1,243,241,224,1, + 244,242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,118,117,104,1,79,78,70,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 203,201,177,1,19,19,16,1,215,212,190,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,64,64,56,1, + 132,130,116,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,158,155,136,1,42,41,37,1,235,232,207,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 225,221,192,1,25,25,22,1,183,181,159,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 75,75,70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,104,102,89,1, + 91,90,79,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,193,189,163,1,20,20,17,1,219,216,189,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 235,230,196,1,53,52,45,1,144,142,123,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,143,140,120,1, + 53,52,45,1,236,232,201,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,217,213,180,1,20,20,17,1,193,189,163,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,90,89,75,1,104,101,87,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1, + 95,93,71,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,180,177,148,1, + 25,24,21,1,224,219,187,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,229,225,187,1,41,41,34,1,156,153,129,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,129,127,105,1,63,62,52,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,208,204,168,1, + 18,18,15,1,200,197,165,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,77,75,62,1,115,113,94,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,114,112,87,1,115,112,89,1,115,112,90,1, + 115,113,91,1,101,99,81,1,32,31,26,1,226,222,184,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1, + 229,223,173,1,114,112,87,1,115,112,89,1,115,112,90,1,115,113,91,1, + 116,113,92,1,217,212,175,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1, + 230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1, + 233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1, + 238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1, + 242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1, + 128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1, + 255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1, + 180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1, + 146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigenvelope: record size: integer; data: array[0..2867] of byte end = + (size: 2868; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,105, + 103,101,110,118,101,108,111,112,101,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22, + 17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60, + 49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112, + 98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201, + 185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,226,220,175,1,215,209,167,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,100,98, + 77,1,35,34,28,1,226,222,179,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242, + 227,1,18,18,14,1,229,223,173,1,229,224,175,1,75,73,58,1,13,12, + 10,1,130,128,103,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,50,48,38,1,139,135,108,1,20,19, + 16,1,216,211,172,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223, + 173,1,229,224,175,1,23,23,18,1,201,196,157,1,99,97,78,1,99,97, + 79,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,225,220, + 172,1,4,4,3,1,226,220,176,1,215,210,170,1,20,20,16,1,196,192, + 159,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,202,198,154,1,21,20, + 16,1,231,225,180,1,231,226,183,1,132,129,105,1,67,65,54,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,75,75, + 70,1,160,156,120,1,229,223,173,1,177,173,135,1,47,46,36,1,231,225, + 180,1,231,226,183,1,228,223,182,1,36,35,29,1,101,99,82,1,117,115, + 96,1,117,115,97,1,118,115,98,1,118,116,100,1,118,116,101,1,119,117, + 102,1,119,117,103,1,119,118,105,1,120,118,106,1,120,119,107,1,120,119, + 108,1,240,237,218,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,151,148,115,1,73,71,57,1,231,225,180,1,231,226, + 183,1,232,227,185,1,217,212,175,1,116,114,95,1,117,115,96,1,117,115, + 97,1,118,115,98,1,118,116,100,1,118,116,101,1,119,117,102,1,119,117, + 103,1,119,118,105,1,120,118,106,1,120,119,107,1,70,69,63,1,111,110, + 101,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,126,123,96,1,98,96,76,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,175,173,157,1,65,64,59,1,243,240, + 222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,100,98, + 76,1,124,121,96,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,219,217,197,1,19,19,17,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,75,73,57,1,151,147, + 117,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,23,22,21,1,217,215,198,1,243,241,224,1,7,7, + 7,1,228,222,171,1,229,223,173,1,49,48,38,1,176,171,136,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,67,67,61,1,172,169,157,1,243,241,224,1,133,132,124,1,95,93, + 71,1,229,223,173,1,23,23,18,1,202,197,156,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,112,111, + 102,1,126,124,115,1,243,241,224,1,244,242,227,1,7,7,5,1,225,220, + 170,1,4,4,3,1,225,220,175,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,158,156,143,1,80,79, + 73,1,243,241,224,1,244,242,227,1,7,7,5,1,202,197,153,1,22,22, + 17,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,202,200,184,1,33,33,30,1,243,241, + 224,1,28,28,26,1,103,100,77,1,177,172,134,1,48,47,37,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,239,236,217,1,10,9,9,1,231,229,213,1,7,7, + 7,1,228,222,171,1,151,147,114,1,75,73,57,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,50,49,45,1,186,184,171,1,7,7,7,1,228,222, + 171,1,129,126,98,1,100,98,76,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,94,93,86,1,146,145,134,1,231,229,215,1,44,43,33,1,229,223, + 173,1,225,220,172,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,237,234, + 217,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224, + 178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229, + 190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234, + 205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239, + 220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244, + 244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248, + 248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173, + 173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128, + 128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255, + 255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195, + 195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180, + 180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146, + 146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128, + 128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188, + 188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248, + 248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigsampler: record size: integer; data: array[0..2858] of byte end = + (size: 2859; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,115,105, + 103,115,97,109,112,108,101,114,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,180,10,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,228,8,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17, + 1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49, + 1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98, + 1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185, + 1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,28,28,26,1,228,222,171,1,229,223,173,1,194,190,148,1,69,67,53, + 1,35,34,28,1,66,65,52,1,183,179,146,1,233,228,188,1,233,229,190, + 1,234,230,193,1,171,168,142,1,59,58,49,1,230,226,195,1,237,233,202, + 1,238,234,205,1,156,154,136,1,52,52,46,1,216,214,191,1,240,238,215, + 1,241,238,217,1,241,238,219,1,69,68,63,1,150,148,138,1,244,242,227, + 1,18,18,14,1,229,223,173,1,34,33,26,1,162,158,126,1,226,221,176, + 1,176,172,139,1,15,15,12,1,223,218,180,1,233,229,190,1,234,230,193, + 1,73,72,60,1,74,72,62,1,153,150,129,1,237,233,202,1,238,234,205, + 1,133,131,115,1,19,19,16,1,137,136,121,1,240,238,215,1,241,238,217, + 1,186,184,169,1,14,14,13,1,123,122,113,1,244,242,227,1,7,7,5, + 1,228,222,172,1,23,23,18,1,179,175,139,1,231,225,180,1,231,226,183, + 1,176,172,140,1,218,214,176,1,233,229,190,1,213,209,176,1,41,41,34, + 1,191,187,159,1,56,55,48,1,237,233,202,1,238,234,205,1,133,131,115, + 1,95,93,83,1,57,57,51,1,240,238,215,1,241,238,217,1,102,101,93, + 1,92,91,84,1,123,122,113,1,133,132,124,1,14,14,11,1,229,223,173, + 1,170,166,130,1,33,33,26,1,37,36,29,1,105,103,83,1,195,191,155, + 1,233,228,188,1,233,229,190,1,128,126,106,1,123,120,102,1,236,231,197, + 1,45,45,38,1,197,194,168,1,238,234,205,1,133,131,115,1,121,119,106, + 1,57,57,51,1,214,212,191,1,238,235,214,1,57,56,52,1,142,140,130, + 1,123,122,113,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175, + 1,230,224,178,1,190,185,148,1,123,121,98,1,25,25,20,1,195,190,157, + 1,233,229,190,1,39,38,32,1,93,91,77,1,118,115,98,1,56,55,48, + 1,100,99,86,1,238,234,205,1,133,131,115,1,121,119,106,1,137,136,121, + 1,133,132,119,1,177,175,159,1,119,117,108,1,143,141,131,1,123,122,113, + 1,7,7,7,1,228,222,171,1,194,189,147,1,75,74,58,1,230,224,178, + 1,231,225,180,1,231,226,183,1,108,106,86,1,139,136,112,1,183,180,149, + 1,48,47,39,1,161,159,134,1,162,159,135,1,156,154,133,1,19,18,16, + 1,228,224,196,1,133,131,115,1,121,119,106,1,216,214,191,1,55,54,49, + 1,95,93,85,1,204,202,185,1,143,141,131,1,123,122,113,1,75,75,70, + 1,160,156,120,1,228,222,172,1,51,50,39,1,95,92,73,1,161,157,126, + 1,141,138,112,1,40,39,32,1,204,199,164,1,93,92,76,1,143,141,118, + 1,235,231,195,1,236,231,197,1,236,232,200,1,76,75,65,1,145,142,125, + 1,133,131,115,1,121,119,106,1,240,237,212,1,61,61,55,1,60,60,54, + 1,242,239,220,1,143,141,131,1,123,122,113,1,244,242,227,1,7,7,5, + 1,229,223,173,1,222,217,170,1,138,134,107,1,100,97,78,1,120,117,95, + 1,199,195,159,1,233,228,188,1,130,128,106,1,221,217,182,1,235,231,195, + 1,236,231,197,1,236,232,200,1,191,188,163,1,155,152,133,1,186,183,162, + 1,180,178,158,1,240,237,212,1,181,179,162,1,175,173,157,1,242,239,220, + 1,193,191,177,1,183,181,169,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,160,155,124, + 1,108,105,84,1,108,105,85,1,114,111,91,1,147,144,119,1,226,222,184, + 1,234,230,193,1,133,130,110,1,218,214,182,1,236,232,200,1,237,233,202, + 1,238,234,205,1,225,222,196,1,112,110,98,1,112,111,99,1,112,111,100, + 1,112,111,101,1,113,112,103,1,225,222,205,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,97,95,75,1,92,90,72, + 1,151,148,120,1,147,144,118,1,75,73,60,1,84,83,69,1,234,230,193, + 1,41,41,34,1,202,197,168,1,236,232,200,1,237,233,202,1,238,234,205, + 1,214,211,186,1,21,20,18,1,157,155,139,1,157,156,141,1,158,156,142, + 1,158,157,144,1,232,229,212,1,243,241,224,1,133,132,124,1,95,93,71, + 1,229,223,173,1,229,224,175,1,97,95,75,1,140,137,109,1,231,226,183, + 1,232,227,185,1,210,206,170,1,19,19,16,1,234,230,193,1,41,41,34, + 1,202,197,168,1,236,232,200,1,237,233,202,1,238,234,205,1,214,211,186, + 1,32,31,28,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,97,95,75,1,132,129,103,1,217,212,172,1,201,197,160, + 1,108,106,87,1,83,82,68,1,234,230,193,1,41,41,34,1,202,197,168, + 1,236,232,200,1,237,233,202,1,238,234,205,1,214,211,186,1,18,18,16, + 1,135,133,119,1,135,133,121,1,135,133,122,1,151,149,137,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,97,95,75,1,31,30,24,1,50,49,39,1,69,68,55,1,135,132,109, + 1,213,209,174,1,234,230,193,1,41,41,34,1,202,197,168,1,236,232,200, + 1,237,233,202,1,238,234,205,1,214,211,186,1,19,19,16,1,142,140,126, + 1,142,141,127,1,143,141,128,1,158,156,143,1,243,240,222,1,243,241,224, + 1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,97,95,75, + 1,140,137,109,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,41,41,34,1,202,197,168,1,236,232,200,1,237,233,202, + 1,238,234,205,1,214,211,186,1,32,31,28,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,97,95,75,1,140,137,109, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,41,41,34,1,182,178,152,1,214,210,181,1,215,211,183,1,222,218,191, + 1,214,211,186,1,29,29,26,1,217,215,192,1,217,216,195,1,218,216,197, + 1,219,217,199,1,236,233,216,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,131,127,101,1,163,159,127,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,90,89,75, + 1,58,57,49,2,59,58,50,1,111,109,96,1,220,217,192,1,59,58,52, + 1,59,59,52,1,59,59,53,1,60,59,54,2,188,185,172,1,243,241,224, + 1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227, + 1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3,3, + 1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7,6, + 1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7,6, + 2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7,6, + 2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7,7, + 1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233, + 1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128, + 2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221, + 1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244, + 1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165, + 1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131, + 1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244, + 1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248, + 2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173, + 1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigsamplerfft: record size: integer; data: array[0..2869] of byte end = + (size: 2870; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,105, + 103,115,97,109,112,108,101,114,102,102,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,194,190,148,1, + 69,67,53,1,35,34,28,1,66,65,52,1,183,179,146,1,233,228,188,1, + 233,229,190,1,234,230,193,1,171,168,142,1,59,58,49,1,230,226,195,1, + 237,233,202,1,238,234,205,1,156,154,136,1,52,52,46,1,216,214,191,1, + 240,238,215,1,241,238,217,1,241,238,219,1,69,68,63,1,150,148,138,1, + 244,242,227,1,18,18,14,1,229,223,173,1,34,33,26,1,162,158,126,1, + 226,221,176,1,176,172,139,1,15,15,12,1,223,218,180,1,233,229,190,1, + 234,230,193,1,73,72,60,1,74,72,62,1,153,150,129,1,237,233,202,1, + 238,234,205,1,133,131,115,1,19,19,16,1,137,136,121,1,240,238,215,1, + 241,238,217,1,186,184,169,1,14,14,13,1,123,122,113,1,244,242,227,1, + 7,7,5,1,228,222,172,1,23,23,18,1,179,175,139,1,231,225,180,1, + 231,226,183,1,176,172,140,1,218,214,176,1,233,229,190,1,213,209,176,1, + 41,41,34,1,191,187,159,1,56,55,48,1,237,233,202,1,238,234,205,1, + 133,131,115,1,95,93,83,1,57,57,51,1,240,238,215,1,241,238,217,1, + 102,101,93,1,92,91,84,1,123,122,113,1,133,132,124,1,14,14,11,1, + 229,223,173,1,170,166,130,1,33,33,26,1,37,36,29,1,105,103,83,1, + 195,191,155,1,233,228,188,1,233,229,190,1,128,126,106,1,123,120,102,1, + 236,231,197,1,45,45,38,1,197,194,168,1,238,234,205,1,133,131,115,1, + 121,119,106,1,57,57,51,1,214,212,191,1,238,235,214,1,57,56,52,1, + 142,140,130,1,123,122,113,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,190,185,148,1,123,121,98,1,25,25,20,1, + 195,190,157,1,233,229,190,1,39,38,32,1,93,91,77,1,118,115,98,1, + 56,55,48,1,100,99,86,1,238,234,205,1,133,131,115,1,121,119,106,1, + 137,136,121,1,133,132,119,1,177,175,159,1,119,117,108,1,143,141,131,1, + 123,122,113,1,7,7,7,1,228,222,171,1,194,189,147,1,75,74,58,1, + 230,224,178,1,231,225,180,1,231,226,183,1,108,106,86,1,139,136,112,1, + 183,180,149,1,48,47,39,1,161,159,134,1,162,159,135,1,156,154,133,1, + 19,18,16,1,228,224,196,1,133,131,115,1,121,119,106,1,216,214,191,1, + 55,54,49,1,95,93,85,1,204,202,185,1,143,141,131,1,123,122,113,1, + 75,75,70,1,160,156,120,1,228,222,172,1,51,50,39,1,95,92,73,1, + 161,157,126,1,141,138,112,1,40,39,32,1,204,199,164,1,93,92,76,1, + 143,141,118,1,235,231,195,1,236,231,197,1,236,232,200,1,76,75,65,1, + 145,142,125,1,133,131,115,1,121,119,106,1,240,237,212,1,61,61,55,1, + 60,60,54,1,242,239,220,1,143,141,131,1,123,122,113,1,244,242,227,1, + 7,7,5,1,229,223,173,1,222,217,170,1,138,134,107,1,100,97,78,1, + 120,117,95,1,199,195,159,1,233,228,188,1,130,128,106,1,221,217,182,1, + 235,231,195,1,236,231,197,1,236,232,200,1,191,188,163,1,155,152,133,1, + 186,183,162,1,180,178,158,1,240,237,212,1,181,179,162,1,175,173,157,1, + 242,239,220,1,193,191,177,1,183,181,169,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 201,196,156,1,108,105,84,1,108,105,85,1,108,106,86,1,109,106,88,1, + 150,147,122,1,231,227,191,1,110,108,91,1,110,108,92,1,110,108,93,1, + 111,109,94,1,127,125,109,1,187,184,162,1,112,110,98,1,112,111,99,1, + 112,111,100,1,112,111,101,1,113,112,103,1,199,197,182,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,176,171,136,1, + 45,44,35,1,151,148,120,1,152,149,121,1,153,149,123,1,180,177,147,1, + 228,225,188,1,13,13,11,1,155,151,129,1,155,152,131,1,155,153,132,1, + 166,163,143,1,205,203,179,1,157,155,138,1,152,151,135,1,9,9,8,1, + 158,156,142,1,158,157,144,1,214,212,196,1,243,241,224,1,133,132,124,1, + 95,93,71,1,229,223,173,1,229,224,175,1,176,171,136,1,69,67,54,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,228,225,188,1, + 20,20,17,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,232,230,205,1,15,15,13,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,176,171,136,1,41,40,32,1,137,134,108,1, + 137,134,110,1,138,135,111,1,220,216,180,1,228,225,188,1,12,12,10,1, + 140,137,117,1,140,137,118,1,140,138,120,1,204,201,176,1,238,235,207,1, + 239,236,210,1,232,230,205,1,15,15,13,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,176,171,136,1,39,38,30,1,130,127,103,1,130,127,104,1, + 131,128,105,1,219,216,179,1,228,225,188,1,11,11,9,1,132,130,110,1, + 132,130,112,1,133,131,113,1,202,198,174,1,238,235,207,1,239,236,210,1, + 232,230,205,1,15,15,13,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1, + 176,171,136,1,69,67,54,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,228,225,188,1,20,20,17,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,232,230,205,1, + 15,15,13,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,176,171,136,1, + 69,67,54,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 228,225,188,1,20,20,17,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,232,230,205,1,15,15,13,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,189,184,147,1,110,107,85,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,230,226,190,1, + 74,72,61,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,234,231,207,1,72,71,64,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1, + 230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1, + 233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1, + 238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1, + 242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1, + 128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1, + 255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1, + 180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1, + 146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigfilter: record size: integer; data: array[0..2865] of byte end = + (size: 2866; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,115,105, + 103,102,105,108,116,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1, + 230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1, + 234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1, + 238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1, + 243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,219,217,193,1,161,159,142,1, + 226,224,202,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,165,163,144,1,16,16,14,1,59,59,52,1,50,49,45,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,161,159,139,1, + 21,20,18,1,191,189,168,1,238,235,210,1,36,35,32,1,182,180,164,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,124,122,105,1,25,25,22,1,189,187,165,1, + 239,236,210,1,240,237,212,1,147,146,132,1,75,74,67,1,242,239,220,1, + 243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,228,224,189,1,159,156,133,1, + 65,64,55,1,52,51,44,1,215,211,185,1,238,235,207,1,239,236,210,1, + 240,237,212,1,228,226,204,1,13,13,12,1,240,237,218,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,114,112,87,1, + 115,112,89,1,115,112,90,1,115,113,91,1,116,113,92,1,116,114,94,1, + 116,114,95,1,87,86,72,1,17,16,14,1,62,61,52,1,144,142,122,1, + 231,228,197,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,40,39,36,1,202,200,184,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,114,112,87,1,115,112,89,1, + 115,112,90,1,115,113,91,1,116,113,92,1,116,114,94,1,116,114,95,1, + 147,144,121,1,214,210,177,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 90,89,81,1,152,150,138,1,243,240,222,1,243,241,224,1,75,75,70,1, + 160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,140,138,126,1, + 102,100,92,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,188,186,169,1,52,52,47,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,222,219,200,1,13,13,12,1,243,240,222,1, + 243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,16,16,15,1,221,218,202,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,53,52,48,1,185,183,169,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 89,88,81,1,149,147,136,1,243,241,224,1,133,132,124,1,95,93,71,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,125,124,114,1, + 111,110,102,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,161,159,147,1,75,74,69,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,198,196,180,1,39,39,36,1,243,241,224,1, + 28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,233,231,212,1,8,8,7,1,240,238,221,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,28,27,25,1,211,209,194,1,7,7,7,1,228,222,171,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 65,64,59,1,173,172,160,1,231,229,215,1,44,43,33,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,101,100,92,1, + 141,140,130,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,239,236,219,1,243,241,224,1, + 205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1, + 11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1, + 145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1, + 86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1, + 38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1, + 248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2, + 203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1, + 128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1, + 131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22, + 128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1, + 210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1, + 128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2, + 158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1, + 248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1, + 244,244,244,1,0,0) + ); + +const + objdata_tsigfilterbank: record size: integer; data: array[0..2869] of byte end = + (size: 2870; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,105, + 103,102,105,108,116,101,114,98,97,110,107,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,219,214,171,1,192,188,152,1,232,227,185,1, + 233,228,188,1,221,217,180,1,195,191,160,1,235,231,195,1,236,231,197,1, + 236,232,200,1,194,191,166,1,229,225,197,1,238,235,207,1,239,236,210,1, + 197,194,174,1,231,229,207,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,61,59,47,1,5,4,4,1,187,182,149,1,233,228,188,1, + 61,60,50,1,5,5,4,1,189,186,157,1,236,231,197,1,180,177,152,1, + 6,5,5,1,72,71,62,1,238,235,207,1,182,180,160,1,6,6,5,1, + 72,72,65,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 244,242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,216,210,167,1, + 11,11,8,1,105,103,83,1,105,102,83,1,218,214,176,1,11,11,9,1, + 106,105,88,1,106,104,88,1,236,231,197,1,107,106,91,1,105,103,90,1, + 15,15,13,1,221,218,192,1,109,107,96,1,106,105,94,1,15,15,13,1, + 224,221,202,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,172,168,133,1,57,56,44,1, + 196,191,155,1,25,24,20,1,174,170,140,1,58,57,47,1,198,195,163,1, + 25,24,21,1,234,229,195,1,58,57,49,1,178,175,151,1,82,81,71,1, + 143,141,124,1,59,58,52,1,180,178,159,1,83,82,74,1,145,143,130,1, + 242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1, + 229,223,173,1,229,224,175,1,149,145,115,1,83,81,65,1,231,226,183,1, + 25,24,20,1,133,130,107,1,84,83,69,1,234,230,193,1,25,24,21,1, + 207,203,173,1,34,34,29,1,204,201,174,1,145,142,125,1,90,88,78,1, + 35,34,30,1,207,204,183,1,146,145,131,1,91,90,82,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,124,121,96,1,107,104,83,1,231,226,183,1,54,53,43,1, + 95,93,77,1,108,106,88,1,234,230,193,1,54,53,45,1,178,174,148,1, + 9,9,8,1,229,225,195,1,175,172,150,1,60,59,52,1,9,9,8,1, + 232,229,205,1,176,175,158,1,60,60,54,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 100,98,77,1,130,127,102,1,231,226,183,1,83,81,66,1,63,62,51,1, + 132,129,107,1,234,230,193,1,84,82,70,1,139,136,116,1,15,15,13,1, + 237,233,202,1,204,201,176,1,28,28,24,1,14,14,12,1,240,237,212,1, + 206,204,185,1,30,30,27,1,242,239,220,1,243,240,222,1,243,241,224,1, + 75,75,70,1,160,156,120,1,229,223,173,1,229,224,175,1,77,75,59,1, + 153,149,119,1,231,226,183,1,112,109,89,1,39,38,32,1,154,152,126,1, + 234,230,193,1,113,111,94,1,99,97,83,1,38,37,32,1,237,233,202,1, + 232,228,200,1,5,5,4,1,38,38,34,1,240,237,212,1,234,232,210,1, + 6,6,5,1,239,236,217,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,52,51,40,1,177,172,138,1, + 231,226,183,1,141,138,112,1,20,20,16,1,178,175,145,1,234,230,193,1, + 143,140,119,1,65,63,54,1,62,61,53,1,237,233,202,1,238,234,205,1, + 18,18,16,1,55,54,48,1,240,237,212,1,240,238,215,1,26,25,23,1, + 213,210,193,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,28,27,22,1,200,195,156,1,231,226,183,1, + 170,166,136,1,7,7,6,1,202,198,165,1,234,230,193,1,172,169,143,1, + 36,36,30,1,86,85,73,1,237,233,202,1,238,234,205,1,34,34,30,1, + 65,64,58,1,240,237,212,1,240,238,215,1,56,55,50,1,181,179,165,1, + 243,240,222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1, + 228,223,174,1,5,5,4,1,224,218,174,1,231,226,183,1,201,197,160,1, + 1,1,0,1,226,222,184,1,234,230,193,1,205,201,170,1,13,13,11,1, + 111,109,94,1,237,233,202,1,238,234,205,1,45,45,39,1,69,68,61,1, + 240,237,212,1,240,238,215,1,89,88,80,1,148,146,135,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,208,204,159,1, + 17,17,13,1,231,225,180,1,231,226,183,1,209,205,166,1,0,0,0,1, + 227,223,185,1,234,230,193,1,232,228,193,1,3,3,2,1,132,130,112,1, + 237,233,202,1,238,234,205,1,49,49,42,1,66,65,58,1,240,237,212,1, + 240,238,215,1,122,120,110,1,116,114,105,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,184,180,141,1,41,40,32,1, + 231,225,180,1,231,226,183,1,187,182,149,1,6,6,5,1,196,193,160,1, + 234,230,193,1,235,231,195,1,10,10,8,1,136,133,115,1,237,233,202,1, + 238,234,205,1,46,46,41,1,56,55,49,1,240,237,212,1,240,238,215,1, + 155,153,140,1,83,82,75,1,243,240,222,1,243,241,224,1,133,132,124,1, + 95,93,71,1,229,223,173,1,159,155,121,1,66,64,51,1,231,225,180,1, + 231,226,183,1,161,158,128,1,19,18,15,1,164,162,134,1,234,230,193,1, + 235,231,195,1,13,12,11,1,131,129,112,1,237,233,202,1,238,234,205,1, + 36,35,31,1,38,38,34,1,240,237,212,1,240,238,215,1,188,186,169,1, + 49,49,45,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,135,132,103,1,90,88,70,1,231,225,180,1,231,226,183,1, + 136,134,109,1,38,37,31,1,132,129,107,1,234,230,193,1,235,231,195,1, + 8,8,7,1,119,117,101,1,237,233,202,1,238,234,205,1,19,18,17,1, + 14,14,13,1,240,237,212,1,240,238,215,1,221,218,199,1,16,16,15,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 106,104,81,1,118,115,91,1,231,225,180,1,231,226,183,1,107,105,86,1, + 79,77,64,1,74,73,60,1,234,230,193,1,225,221,187,1,4,4,3,1, + 74,73,63,1,237,233,202,1,228,224,196,1,7,6,6,1,37,37,33,1, + 197,194,174,1,240,238,215,1,241,238,217,1,38,37,35,1,199,197,182,1, + 243,241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,57,55,43,1, + 167,163,129,1,231,225,180,1,231,226,183,1,57,56,46,1,158,155,127,1, + 15,14,12,1,228,225,188,1,177,174,147,1,50,49,41,1,15,15,13,1, + 231,228,197,1,179,176,154,1,53,53,46,1,108,106,95,1,125,124,111,1, + 240,238,215,1,241,238,217,1,109,108,99,1,127,125,116,1,243,241,224,1, + 7,7,7,1,228,222,171,1,225,220,170,1,13,12,10,1,218,213,169,1, + 231,225,180,1,227,222,180,1,13,12,10,1,221,216,178,1,58,57,47,1, + 170,167,140,1,123,121,102,1,108,106,90,1,58,57,49,1,172,169,147,1, + 125,123,108,1,109,108,95,1,179,177,157,1,54,53,47,1,240,238,215,1, + 241,238,217,1,181,179,165,1,54,54,50,1,243,241,224,1,7,7,7,1, + 228,222,171,1,154,150,116,1,56,54,43,1,230,224,178,1,231,225,180,1, + 155,152,123,1,56,55,45,1,233,228,188,1,126,124,103,1,100,98,82,1, + 41,40,34,1,176,172,147,1,128,126,108,1,101,99,86,1,41,40,35,1, + 177,175,154,1,235,232,207,1,17,17,15,1,221,219,198,1,241,238,217,1, + 238,235,217,1,17,17,16,1,224,222,206,1,231,229,215,1,44,43,33,1, + 58,57,44,1,164,161,126,1,230,224,178,1,231,225,180,1,59,58,47,1, + 166,163,133,1,233,228,188,1,196,192,159,1,31,30,25,1,51,50,42,1, + 236,231,197,1,198,195,168,1,31,30,26,1,51,50,44,1,238,235,207,1, + 239,236,210,1,81,80,71,1,162,161,145,1,241,238,217,1,242,239,220,1, + 82,81,75,1,164,163,151,1,244,242,227,1,7,7,5,1,216,211,164,1, + 229,224,175,1,230,224,178,1,231,225,180,1,218,214,173,1,232,227,185,1, + 233,228,188,1,233,229,190,1,225,221,185,1,221,217,184,1,236,231,197,1, + 236,232,200,1,228,224,194,1,224,220,193,1,238,235,207,1,239,236,210,1, + 231,228,204,1,240,238,215,1,241,238,217,1,242,239,220,1,233,231,213,1, + 243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1, + 230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1, + 233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1, + 238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1, + 242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1, + 128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1, + 255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1, + 180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1, + 146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigkeyboard: record size: integer; data: array[0..2651] of byte end = + (size: 2652; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,105, + 103,107,101,121,98,111,97,114,100,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,228,9,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,20,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22, + 17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60, + 49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112, + 98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201, + 185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,172,167,130,1,176,174, + 146,1,242,239,216,1,181,179,162,1,120,119,108,1,118,117,101,1,182,180, + 165,1,243,241,222,1,182,181,167,1,180,178,157,1,245,242,225,1,183,181, + 170,1,122,121,113,1,121,119,108,1,184,183,172,1,246,245,232,1,184,183, + 174,1,183,181,169,1,247,246,235,1,248,246,237,1,186,184,178,1,182,181, + 168,1,28,28,26,1,228,222,171,1,114,111,86,1,120,118,106,1,254,254, + 254,1,127,127,127,1,0,0,0,1,13,13,12,1,127,127,127,1,254,254, + 254,1,63,63,63,1,60,59,55,1,254,254,254,1,127,127,127,1,0,0, + 0,2,127,127,127,1,254,254,254,1,127,127,127,1,122,122,116,1,254,254, + 254,2,127,127,127,1,121,120,112,1,244,242,227,1,18,18,14,1,114,111, + 86,1,120,118,106,1,254,254,254,1,127,127,127,1,0,0,0,1,27,26, + 24,1,127,127,127,1,254,254,254,1,63,63,63,1,60,59,55,1,254,254, + 254,1,127,127,127,1,0,0,0,2,127,127,127,1,254,254,254,1,127,127, + 127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120,112,1,244,242, + 227,1,7,7,5,1,114,111,86,1,120,118,106,1,254,254,254,1,127,127, + 127,1,0,0,0,1,27,26,24,1,127,127,127,1,254,254,254,1,63,63, + 63,1,60,59,55,1,254,254,254,1,127,127,127,1,0,0,0,2,127,127, + 127,1,254,254,254,1,127,127,127,1,122,122,116,1,254,254,254,2,127,127, + 127,1,121,120,112,1,133,132,124,1,14,14,11,1,114,111,86,1,120,118, + 106,1,254,254,254,1,127,127,127,1,0,0,0,1,27,26,24,1,127,127, + 127,1,254,254,254,1,63,63,63,1,60,59,55,1,254,254,254,1,127,127, + 127,1,0,0,0,2,127,127,127,1,254,254,254,1,127,127,127,1,122,122, + 116,1,254,254,254,2,127,127,127,1,121,120,112,1,7,7,7,1,228,222, + 171,1,114,111,86,1,120,118,106,1,254,254,254,1,127,127,127,1,0,0, + 0,1,27,26,24,1,127,127,127,1,254,254,254,1,63,63,63,1,60,59, + 55,1,254,254,254,1,127,127,127,1,0,0,0,2,127,127,127,1,254,254, + 254,1,127,127,127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120, + 112,1,7,7,7,1,228,222,171,1,114,111,86,1,120,118,106,1,254,254, + 254,1,127,127,127,1,0,0,0,1,27,26,24,1,127,127,127,1,254,254, + 254,1,63,63,63,1,60,59,55,1,254,254,254,1,127,127,127,1,0,0, + 0,2,127,127,127,1,254,254,254,1,127,127,127,1,122,122,116,1,254,254, + 254,2,127,127,127,1,121,120,112,1,75,75,70,1,160,156,120,1,114,111, + 86,1,120,118,106,1,254,254,254,1,127,127,127,1,0,0,0,1,27,26, + 24,1,127,127,127,1,254,254,254,1,63,63,63,1,60,59,55,1,254,254, + 254,1,127,127,127,1,0,0,0,2,127,127,127,1,254,254,254,1,127,127, + 127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120,112,1,244,242, + 227,1,7,7,5,1,114,111,86,1,120,118,106,1,254,254,254,1,127,127, + 127,1,0,0,0,1,27,26,24,1,127,127,127,1,254,254,254,1,63,63, + 63,1,60,59,55,1,254,254,254,1,127,127,127,1,0,0,0,2,127,127, + 127,1,254,254,254,1,127,127,127,1,122,122,116,1,254,254,254,2,127,127, + 127,1,121,120,112,1,244,242,227,1,7,7,5,1,114,111,86,1,120,118, + 106,1,254,254,254,1,127,127,127,1,0,0,0,1,27,26,24,1,127,127, + 127,1,254,254,254,1,63,63,63,1,60,59,55,1,254,254,254,1,127,127, + 127,1,0,0,0,2,127,127,127,1,254,254,254,1,127,127,127,1,122,122, + 116,1,254,254,254,2,127,127,127,1,121,120,112,1,75,75,70,1,49,48, + 37,1,114,111,86,1,120,118,106,1,254,254,254,1,127,127,127,1,0,0, + 0,1,13,13,12,1,127,127,127,1,254,254,254,1,63,63,63,1,60,59, + 55,1,254,254,254,1,127,127,127,1,0,0,0,2,127,127,127,1,254,254, + 254,1,127,127,127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120, + 112,1,7,7,7,1,228,222,171,1,114,111,86,1,120,118,106,1,254,254, + 254,1,190,190,190,1,63,63,63,1,59,59,53,1,190,190,190,1,254,254, + 254,1,63,63,63,1,60,59,55,1,254,254,254,1,190,190,190,1,47,47, + 47,1,44,44,41,1,190,190,190,1,254,254,254,1,127,127,127,1,122,122, + 116,1,254,254,254,2,127,127,127,1,121,120,112,1,7,7,7,1,228,222, + 171,1,114,111,86,1,120,118,106,1,254,254,254,2,127,127,127,1,120,119, + 109,1,254,254,254,2,63,63,63,1,60,59,55,1,254,254,254,2,127,127, + 127,1,122,121,114,1,254,254,254,2,127,127,127,1,122,122,116,1,254,254, + 254,2,127,127,127,1,121,120,112,1,133,132,124,1,95,93,71,1,114,111, + 86,1,120,118,106,1,254,254,254,2,127,127,127,1,120,119,109,1,254,254, + 254,2,63,63,63,1,60,59,55,1,254,254,254,2,127,127,127,1,122,121, + 114,1,254,254,254,2,127,127,127,1,122,122,116,1,254,254,254,2,127,127, + 127,1,121,120,112,1,244,242,227,1,7,7,5,1,114,111,86,1,120,118, + 106,1,254,254,254,2,127,127,127,1,120,119,109,1,254,254,254,2,63,63, + 63,1,60,59,55,1,254,254,254,2,127,127,127,1,122,121,114,1,254,254, + 254,2,127,127,127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120, + 112,1,244,242,227,1,7,7,5,1,114,111,86,1,120,118,106,1,254,254, + 254,2,127,127,127,1,120,119,109,1,254,254,254,2,63,63,63,1,60,59, + 55,1,254,254,254,2,127,127,127,1,122,121,114,1,254,254,254,2,127,127, + 127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120,112,1,28,28, + 26,1,103,100,77,1,114,111,86,1,120,118,106,1,254,254,254,2,127,127, + 127,1,120,119,109,1,254,254,254,2,63,63,63,1,60,59,55,1,254,254, + 254,2,127,127,127,1,122,121,114,1,254,254,254,2,127,127,127,1,122,122, + 116,1,254,254,254,2,127,127,127,1,121,120,112,1,7,7,7,1,228,222, + 171,1,114,111,86,1,120,118,106,1,254,254,254,2,127,127,127,1,120,119, + 109,1,254,254,254,2,63,63,63,1,60,59,55,1,254,254,254,2,127,127, + 127,1,122,121,114,1,254,254,254,2,127,127,127,1,122,122,116,1,254,254, + 254,2,127,127,127,1,121,120,112,1,7,7,7,1,228,222,171,1,114,111, + 86,1,58,57,48,1,120,118,107,1,120,119,107,1,59,58,53,1,59,58, + 50,1,121,119,109,1,121,120,110,1,29,29,26,2,121,120,112,2,60,59, + 56,1,60,59,54,1,122,121,114,1,122,121,115,1,60,60,57,1,60,60, + 56,1,123,122,117,2,61,60,58,1,121,120,112,1,231,229,215,1,44,43, + 33,1,172,167,130,1,114,112,87,1,115,112,89,1,115,112,90,1,115,113, + 91,1,86,85,69,1,116,114,94,1,116,114,95,1,87,86,72,1,88,86, + 73,1,118,115,98,1,118,116,100,1,118,116,101,1,89,87,76,1,119,117, + 103,1,119,118,105,1,120,118,106,1,89,89,80,1,120,119,108,1,121,119, + 110,1,121,120,111,1,182,181,168,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224, + 175,1,230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228, + 188,1,233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233, + 202,1,238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238, + 217,1,242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1, + 0,0,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158, + 158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248, + 248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139, + 139,1,128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128, + 128,1,255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165, + 165,1,180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176, + 176,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244, + 244,1,146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233, + 233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128, + 128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221, + 221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_twavetableedit: record size: integer; data: array[0..2133] of byte end = + (size: 2134; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,119,97, + 118,101,116,97,98,108,101,101,100,105,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,7,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,7,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22, + 255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,106,104,86,1,90,88,73,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 227,224,206,1,58,57,53,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 230,225,184,1,21,21,17,1,18,18,15,1,211,207,174,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,148,146,135,1, + 90,88,82,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,177,174,141,1, + 45,44,36,1,112,110,92,1,115,113,95,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,64,63,58,1,174,172,159,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,105,102,83,1,118,115,95,1, + 208,205,170,1,25,24,20,1,229,226,190,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,218,216,197,1,22,22,20,1,239,236,219,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,32,31,25,1,192,188,155,1,233,229,190,1, + 79,78,65,1,149,147,124,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 137,135,123,1,99,97,90,1,243,240,222,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1, + 190,186,151,1,32,31,25,1,233,228,188,1,233,229,190,1,180,177,148,1, + 48,47,40,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,52,51,47,1, + 183,181,167,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,118,115,93,1, + 106,103,84,1,233,228,188,1,233,229,190,1,234,230,193,1,45,44,37,1, + 184,180,154,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,208,206,186,1,26,26,24,1,241,238,219,1, + 243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 229,224,175,1,230,224,178,1,231,225,180,1,44,43,35,1,178,174,142,1, + 233,228,188,1,233,229,190,1,234,230,193,1,147,144,122,1,82,81,69,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,125,124,112,1,108,106,97,1,242,239,220,1,243,240,222,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1, + 230,224,178,1,203,198,158,1,22,21,17,1,230,225,184,1,233,228,188,1, + 233,229,190,1,234,230,193,1,228,224,189,1,24,24,20,1,213,209,180,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 41,41,37,1,192,189,173,1,242,239,220,1,243,240,222,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1, + 130,127,102,1,92,90,73,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,113,111,94,1,117,115,99,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,198,195,175,1,34,34,30,1, + 241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,58,56,45,1, + 166,162,131,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,210,206,175,1,25,25,21,1,231,228,197,1,238,234,205,1, + 238,235,207,1,239,236,210,1,114,112,101,1,117,116,105,1,241,238,217,1, + 242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,229,224,175,1,213,207,165,1,15,15,12,1,226,221,179,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,79,77,67,1,151,149,129,1,238,234,205,1,238,235,207,1, + 239,236,210,1,31,31,27,1,200,199,180,1,241,238,217,1,242,239,220,1, + 243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 229,224,175,1,143,140,111,1,80,78,62,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 180,177,153,1,49,48,42,1,238,234,205,1,238,235,207,1,187,184,164,1, + 43,43,38,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1, + 70,69,54,1,153,149,119,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 45,44,38,1,186,183,160,1,238,235,207,1,102,101,90,1,126,125,111,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,220,215,168,1,14,14,11,1, + 219,214,171,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,147,144,125,1, + 84,83,72,1,235,232,205,1,22,22,20,1,209,206,185,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,155,152,119,1,67,65,52,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,230,226,196,1,23,23,20,1, + 151,149,132,1,52,52,46,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,84,82,64,1,140,136,108,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,113,111,97,1,10,10,9,1, + 135,133,119,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 84,82,64,1,210,205,163,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,211,207,182,1,53,53,46,1,216,213,189,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1, + 255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,12,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tfuncttableedit: record size: integer; data: array[0..2118] of byte end = + (size: 2119; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,102,117, + 110,99,116,116,97,98,108,101,101,100,105,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,204,7,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,136,7,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0, + 22,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,203,201,179,1,45,45,40,1,14,14,13,3,243,240,222, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,69,68,61,1,157,155,139, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,169,167,147,1,56,56,49,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,233,229,201, + 1,37,37,32,1,193,191,170,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,130,128,112,1,95,94,83, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,216,212,184,1,28,28,24,1,218,216,190,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,90,89,77,1,134,132,116,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,187,184,158,1,40,39,34, + 1,234,230,202,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,235,230,196,1,52,51,44,1,173,170,147,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,150,147,125,1,73,72,62,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,224,220,186,1,31,30,25, + 1,204,200,173,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,111,109,92,1,112,110,93,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,202,198,167,1,30,30,25,1,225,220,188,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,72,70,59, + 1,150,148,125,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,169,166,138,1,52,51,43,1,234,230,194, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,229,224,185,1,39,39,32,1,186,183,154,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,131,128,105, + 1,90,88,73,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,14,13,10, + 1,14,13,11,3,50,49,41,1,212,208,173,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255, + 25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tffttableedit: record size: integer; data: array[0..2132] of byte end = + (size: 2133; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,102,102, + 116,116,97,98,108,101,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,7,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,7,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,0,0,0,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0, + 0,0,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,0,0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0, + 0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231, + 225,180,1,0,0,0,1,232,227,185,1,233,228,188,1,233,229,190,1,117, + 115,96,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,0, + 0,0,1,232,227,185,1,233,228,188,1,233,229,190,1,0,0,0,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,0,0,0,1,232, + 227,185,1,233,228,188,1,233,229,190,1,0,0,0,1,235,231,195,1,236, + 231,197,1,236,232,200,1,118,116,101,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,0,0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,233, + 228,188,1,233,229,190,1,0,0,0,1,235,231,195,1,236,231,197,1,236, + 232,200,1,0,0,0,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0, + 0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,233,228,188,1,233, + 229,190,1,0,0,0,1,235,231,195,1,236,231,197,1,236,232,200,1,0, + 0,0,1,238,234,205,1,238,235,207,1,239,236,210,1,120,118,106,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231, + 225,180,1,0,0,0,1,232,227,185,1,0,0,0,1,233,229,190,1,0, + 0,0,1,235,231,195,1,118,115,98,1,236,232,200,1,0,0,0,1,238, + 234,205,1,238,235,207,1,239,236,210,1,0,0,0,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,0, + 0,0,1,232,227,185,1,0,0,0,1,233,229,190,1,0,0,0,1,235, + 231,195,1,0,0,0,1,236,232,200,1,0,0,0,1,238,234,205,1,238, + 235,207,1,239,236,210,1,0,0,0,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,0,0,0,1,232, + 227,185,1,0,0,0,1,233,229,190,1,0,0,0,1,235,231,195,1,0, + 0,0,1,236,232,200,1,0,0,0,1,238,234,205,1,119,117,103,1,239, + 236,210,1,0,0,0,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,0,0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,0, + 0,0,1,233,229,190,1,0,0,0,1,235,231,195,1,0,0,0,1,236, + 232,200,1,0,0,0,1,238,234,205,1,0,0,0,1,239,236,210,1,0, + 0,0,1,240,238,215,1,120,119,108,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0, + 0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,0,0,0,1,233, + 229,190,1,0,0,0,1,235,231,195,1,0,0,0,1,236,232,200,1,0, + 0,0,1,238,234,205,1,0,0,0,1,239,236,210,1,0,0,0,1,240, + 238,215,1,0,0,0,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tenvelopeedit: record size: integer; data: array[0..2132] of byte end = + (size: 2133; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,101,110, + 118,101,108,111,112,101,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,7,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,7,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,230, + 224,179,1,218,214,173,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,162,158,126,1,16, + 16,13,1,220,215,176,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,230,224,178,1,140,136,109,1,6,6,5,1,122, + 119,97,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,230,224,178,1,118,115,92,1,103,101,82,1,25,24,20,1,222, + 217,179,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230, + 224,178,1,95,93,74,1,149,145,118,1,98,96,78,1,124,122,100,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,73, + 71,57,1,170,167,135,1,207,202,165,1,25,24,20,1,223,219,182,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,51,49,40,1,193, + 189,153,1,232,227,185,1,94,92,76,1,126,124,103,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,230,224,178,1,29,28,23,1,215,210,170,1,232, + 227,185,1,205,200,165,1,25,24,20,1,124,122,102,1,124,122,103,1,125, + 122,104,1,125,123,106,1,125,123,107,1,126,124,109,1,126,124,110,1,127, + 125,111,1,127,125,112,1,127,126,114,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,230,224,178,1,14,13,11,1,231,226,183,1,232,227,185,1,233, + 228,188,1,183,180,149,1,124,122,102,1,124,122,103,1,125,122,104,1,125, + 123,106,1,125,123,107,1,126,124,109,1,126,124,110,1,127,125,111,1,127, + 125,112,1,75,75,67,1,123,121,111,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,216, + 210,167,1,27,26,21,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,174, + 173,156,1,83,82,75,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,194,189,150,1,50, + 49,39,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,213,211,191,1,43, + 43,39,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,171,167,133,1,72,70,56,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,239,237,214,1,19,19,17,1,240, + 237,218,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,150,146,116,1,94,92,73,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,48,48,43,1,208,205,189,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,127,124,98,1,116,113,90,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,87,86,78,1,169,167,154,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,106, + 103,82,1,139,135,108,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,126,124,113,1,129,127,117,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,83,81,64,1,160, + 156,125,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,164, + 162,148,1,89,88,81,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,61,60,47,1,183,178,143,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,203,201,183,1,50, + 50,46,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,39,38,30,1,205,199,160,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,236,233,213,1,16,16,15,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,20,19,15,1,226,220,176,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,40,39,36,1,217,215,198,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,229, + 223,177,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,239,236,217,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tsigscope: record size: integer; data: array[0..2980] of byte end = + (size: 2981; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,105, + 103,115,99,111,112,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,48,11,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,96,5,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,254,228,0,2,208,208,208,1,255, + 225,0,1,254,228,0,2,208,208,208,1,255,223,0,1,254,228,0,1,208, + 208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223,0,1,254, + 228,0,1,208,208,208,3,254,228,0,1,208,208,208,1,255,255,255,1,128, + 128,128,1,254,228,0,5,253,227,0,1,24,22,0,1,141,126,0,1,247, + 222,0,1,254,228,0,9,85,76,0,1,216,194,0,1,252,226,0,1,254, + 228,0,1,255,254,247,1,128,128,128,1,254,228,0,1,208,208,208,2,255, + 223,0,1,254,228,0,1,0,0,0,2,3,2,0,1,74,67,0,1,208, + 208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223,0,1,254, + 228,0,1,0,0,0,3,119,106,0,1,208,208,208,1,255,255,255,1,128, + 128,128,1,208,208,208,4,0,0,0,6,208,208,208,6,0,0,0,6,255, + 255,255,1,128,128,128,1,254,228,0,2,208,208,208,1,255,225,0,1,171, + 153,0,1,3,3,0,1,208,208,208,1,255,223,0,1,82,74,0,1,0, + 0,0,1,208,208,208,1,255,223,0,1,254,228,0,1,208,208,208,2,255, + 223,0,1,99,89,0,1,0,0,0,1,208,208,208,2,43,38,0,1,0, + 0,0,1,255,255,255,1,128,128,128,1,254,228,0,4,120,107,0,1,128, + 115,0,1,254,228,0,2,132,119,0,1,117,105,0,1,254,228,0,6,48, + 43,0,1,199,179,0,1,254,228,0,2,98,88,0,1,150,135,0,1,255, + 254,247,1,128,128,128,1,254,228,0,1,208,208,208,2,255,223,0,1,65, + 59,0,1,0,0,0,1,208,208,208,1,255,223,0,1,162,145,0,1,0, + 0,0,1,208,208,208,1,255,223,0,1,254,228,0,1,208,208,208,2,204, + 178,0,1,9,8,0,1,0,0,0,1,208,208,208,2,134,121,0,1,0, + 0,0,1,255,255,255,1,128,128,128,1,208,208,208,3,0,0,0,3,208, + 208,208,2,0,0,0,2,208,208,208,5,0,0,0,2,208,208,208,3,0, + 0,0,2,255,255,255,1,128,128,128,1,254,228,0,1,255,223,0,1,208, + 208,208,1,67,59,0,1,33,30,0,1,255,223,0,1,208,208,208,1,255, + 223,0,1,225,202,0,1,0,0,0,1,208,208,208,1,255,223,0,1,254, + 228,0,1,208,208,208,2,18,16,0,1,67,60,0,1,208,208,208,3,166, + 149,0,1,0,0,0,1,255,255,255,1,128,128,128,1,254,228,0,2,208, + 208,208,1,163,146,0,1,87,78,0,1,254,228,0,1,208,208,208,1,254, + 228,0,1,252,226,0,1,8,7,0,1,0,0,0,1,254,228,0,3,208, + 208,208,1,138,124,0,1,111,99,0,1,254,228,0,1,208,208,208,1,254, + 228,0,1,182,164,0,1,71,63,0,1,255,255,255,1,128,128,128,1,254, + 228,0,1,255,255,0,1,208,208,208,1,6,6,0,1,136,122,0,1,208, + 208,208,2,255,223,0,1,254,228,0,1,0,0,0,2,255,223,0,1,254, + 228,0,1,208,208,208,2,5,5,0,1,147,132,0,1,208,208,208,3,197, + 177,0,1,1,1,0,1,255,255,255,1,128,128,128,1,208,208,208,3,0, + 0,0,2,208,208,208,4,0,0,0,2,208,208,208,4,0,0,0,2,208, + 208,208,3,0,0,0,2,255,255,255,1,128,128,128,1,254,228,0,1,255, + 223,0,1,208,208,208,1,1,1,0,1,236,212,0,1,255,223,0,1,208, + 208,208,2,254,228,0,1,0,0,0,2,208,208,208,1,254,228,0,1,208, + 208,208,2,0,0,0,1,208,187,0,1,208,208,208,3,228,205,0,1,1, + 1,0,1,255,255,255,1,128,128,128,1,254,228,0,2,0,0,0,1,30, + 27,0,1,254,228,0,2,208,208,208,1,254,228,0,2,162,146,0,1,0, + 0,0,1,254,228,0,3,208,208,208,1,13,12,0,1,237,213,0,1,254, + 228,0,1,208,208,208,1,254,228,0,1,253,227,0,1,240,215,0,1,255, + 255,255,1,128,128,128,1,254,228,0,1,255,223,0,1,0,0,0,2,254, + 228,0,1,208,208,208,3,254,228,0,1,0,0,0,2,208,208,208,1,254, + 228,0,1,208,208,208,1,0,0,0,2,254,228,0,1,208,208,208,3,254, + 228,0,1,255,223,0,1,255,255,255,1,128,128,128,1,208,208,208,2,0, + 0,0,2,208,208,208,5,0,0,0,3,208,208,208,2,0,0,0,2,208, + 208,208,6,255,255,255,1,128,128,128,1,254,228,0,1,214,187,0,1,0, + 0,0,1,32,28,0,1,254,228,0,1,255,223,0,1,208,208,208,2,254, + 228,0,1,208,208,208,1,0,0,0,2,254,228,0,1,208,208,208,1,0, + 0,0,2,254,228,0,1,208,208,208,3,254,228,0,1,255,223,0,1,255, + 255,255,1,128,128,128,1,254,228,0,1,169,151,0,1,0,0,0,1,254, + 228,0,3,208,208,208,1,254,228,0,3,0,0,0,1,99,89,0,1,254, + 228,0,2,0,0,0,1,163,147,0,1,254,228,0,2,208,208,208,1,254, + 228,0,3,255,255,255,1,128,128,128,1,193,173,0,1,1,1,0,1,0, + 0,0,1,208,208,208,1,254,228,0,1,208,208,208,3,254,228,0,1,208, + 208,208,1,0,0,0,2,165,148,0,1,0,0,0,3,254,228,0,1,208, + 208,208,3,254,228,0,1,255,223,0,1,255,255,255,1,128,128,128,1,0, + 0,0,2,208,208,208,9,0,0,0,4,208,208,208,7,255,255,255,1,128, + 128,128,1,254,228,0,1,255,223,0,1,208,208,208,1,255,223,0,1,254, + 228,0,1,255,223,0,1,208,208,208,2,254,228,0,1,208,208,208,3,254, + 228,0,1,0,0,0,1,208,208,208,2,254,228,0,1,208,208,208,3,254, + 228,0,1,255,223,0,1,255,255,255,1,128,128,128,1,254,228,0,2,208, + 208,208,1,254,228,0,3,208,208,208,1,254,228,0,3,208,208,208,1,254, + 228,0,3,208,208,208,1,254,228,0,3,208,208,208,1,254,228,0,3,255, + 255,255,25,152,5,0,0,255,255,255,26,8,8,8,1,0,0,0,1,15, + 15,15,1,248,248,248,1,8,8,8,1,0,0,0,1,8,8,8,1,248, + 248,248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,2,8, + 8,8,1,248,248,248,1,0,0,0,3,255,255,255,1,0,0,0,1,255, + 255,255,3,248,248,248,1,7,7,7,1,240,240,240,1,255,255,255,1,248, + 248,248,1,59,59,59,1,251,251,251,1,255,255,255,2,8,8,8,1,248, + 248,248,1,255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2,23, + 23,23,1,249,249,249,1,255,255,255,5,0,0,0,2,8,8,8,1,248, + 248,248,1,115,115,115,1,226,226,226,1,194,194,194,1,253,253,253,1,0, + 0,0,2,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248, + 248,248,1,121,121,121,1,237,237,237,1,221,221,221,1,255,255,255,1,0, + 0,0,1,255,255,255,2,0,0,0,4,16,16,16,1,234,234,234,1,42, + 42,42,1,3,3,3,1,237,237,237,1,22,22,22,1,0,0,0,6,36, + 36,36,1,234,234,234,1,28,28,28,1,22,22,22,1,240,240,240,1,3, + 3,3,1,255,255,255,3,8,8,8,1,0,0,0,1,15,15,15,1,250, + 250,250,1,181,181,181,1,0,0,0,1,8,8,8,1,253,253,253,1,90, + 90,90,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,2,8, + 8,8,1,252,252,252,1,122,122,122,1,0,0,0,2,255,255,255,1,48, + 48,48,1,255,255,255,3,248,248,248,1,7,7,7,1,240,240,240,1,255, + 255,255,1,251,251,251,1,7,7,7,1,248,248,248,1,255,255,255,2,8, + 8,8,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1,255, + 255,255,2,8,8,8,1,248,248,248,1,255,255,255,5,0,0,0,2,8, + 8,8,1,253,253,253,1,72,72,72,1,0,0,0,1,8,8,8,1,250, + 250,250,1,168,168,168,1,0,0,0,1,8,8,8,1,248,248,248,1,0, + 0,0,2,10,10,10,1,255,255,255,1,14,14,14,1,0,0,0,2,255, + 255,255,1,136,136,136,1,255,255,255,2,0,0,0,3,1,1,1,1,239, + 239,239,1,19,19,19,1,0,0,0,2,59,59,59,1,198,198,198,1,0, + 0,0,5,34,34,34,1,227,227,227,1,0,0,0,3,104,104,104,1,152, + 152,152,1,255,255,255,3,8,8,8,1,0,0,0,1,52,52,52,1,254, + 254,254,1,8,8,8,1,0,0,0,1,8,8,8,1,249,249,249,1,227, + 227,227,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,2,81, + 81,81,1,253,253,253,1,0,0,0,3,255,255,255,1,168,168,168,1,255, + 255,255,3,248,248,248,1,0,0,0,1,250,250,250,1,255,255,255,1,248, + 248,248,1,0,0,0,1,255,255,255,3,4,4,4,1,255,255,255,3,0, + 0,0,1,255,255,255,3,0,0,0,1,255,255,255,5,254,254,254,1,2, + 2,2,1,0,0,0,1,144,144,144,1,251,251,251,1,0,0,0,2,8, + 8,8,1,248,248,248,1,222,222,222,1,31,31,31,1,8,8,8,1,248, + 248,248,1,0,0,0,2,156,156,156,1,251,251,251,1,0,0,0,3,254, + 254,254,1,199,199,199,1,255,255,255,2,0,0,0,3,189,189,189,1,68, + 68,68,1,0,0,0,4,187,187,187,1,67,67,67,1,0,0,0,4,183, + 183,183,1,76,76,76,1,0,0,0,3,41,41,41,1,215,215,215,1,255, + 255,255,2,248,248,248,1,16,16,16,1,0,0,0,1,238,238,238,1,255, + 255,255,1,8,8,8,1,0,0,0,2,255,255,255,1,140,140,140,1,116, + 116,116,1,0,0,0,1,255,255,255,1,0,0,0,2,212,212,212,1,255, + 255,255,1,0,0,0,3,249,249,249,1,232,232,232,1,255,255,255,3,248, + 248,248,1,31,31,31,1,254,254,254,1,255,255,255,1,248,248,248,1,0, + 0,0,1,255,255,255,3,167,167,167,1,255,255,255,3,0,0,0,1,255, + 255,255,3,0,0,0,1,255,255,255,5,248,248,248,1,8,8,8,1,80, + 80,80,1,175,175,175,1,255,255,255,1,0,0,0,3,255,255,255,1,44, + 44,44,1,217,217,217,1,0,0,0,1,255,255,255,1,0,0,0,1,16, + 16,16,1,243,243,243,1,255,255,255,1,0,0,0,3,248,248,248,1,8, + 8,8,1,255,255,255,2,0,0,0,2,133,133,133,1,125,125,125,1,0, + 0,0,5,4,4,4,1,246,246,246,1,13,13,13,1,0,0,0,2,46, + 46,46,1,213,213,213,1,0,0,0,6,255,255,255,2,248,248,248,1,19, + 19,19,1,225,225,225,1,53,53,53,1,255,255,255,1,8,8,8,1,0, + 0,0,2,255,255,255,1,0,0,0,1,205,205,205,1,61,61,61,1,255, + 255,255,1,0,0,0,1,95,95,95,1,168,168,168,1,255,255,255,1,0, + 0,0,3,248,248,248,1,8,8,8,1,255,255,255,3,250,250,250,1,194, + 194,194,1,248,248,248,1,255,255,255,1,248,248,248,1,0,0,0,1,255, + 255,255,3,136,136,136,1,255,255,255,3,172,172,172,1,255,255,255,3,0, + 0,0,1,255,255,255,5,250,250,250,1,235,235,235,1,68,68,68,1,0, + 0,0,1,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,1,16, + 16,16,1,232,232,232,1,255,255,255,1,79,79,79,1,235,235,235,1,17, + 17,17,1,255,255,255,1,0,0,0,3,248,248,248,1,8,8,8,1,255, + 255,255,2,117,117,117,1,72,72,72,1,0,0,0,9,71,71,71,1,183, + 183,183,1,238,238,238,1,61,61,61,1,0,0,0,7,255,255,255,2,248, + 248,248,1,16,16,16,1,0,0,0,1,8,8,8,1,255,255,255,1,8, + 8,8,1,0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,2, + 2,2,1,0,0,0,2,255,255,255,1,0,0,0,3,248,248,248,1,8, + 8,8,1,255,255,255,3,248,248,248,1,0,0,0,1,248,248,248,1,255, + 255,255,1,248,248,248,1,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,28,0, + 0) + ); + +const + objdata_tsigscopefft: record size: integer; data: array[0..2803] of byte end = + (size: 2804; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,105, + 103,115,99,111,112,101,102,102,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,124,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,224,4,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,128,128,128,25,254,228,0,2,208,208, + 208,1,255,225,0,1,254,228,0,2,208,208,208,1,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223, + 0,1,254,228,0,1,208,208,208,3,254,228,0,1,208,208,208,1,255,255, + 255,1,128,128,128,1,254,228,0,22,255,254,247,1,128,128,128,1,254,228, + 0,1,208,208,208,1,0,0,0,1,255,223,0,1,254,228,0,1,208,208, + 208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,3,254,228, + 0,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,0,0, + 0,2,208,208,208,18,255,255,255,1,128,128,128,1,254,228,0,2,0,0, + 0,1,164,145,0,1,254,228,0,2,208,208,208,1,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223, + 0,1,254,228,0,1,208,208,208,3,254,228,0,1,208,208,208,1,255,255, + 255,1,128,128,128,1,254,228,0,2,0,0,0,1,246,220,0,1,254,228, + 0,18,255,254,247,1,128,128,128,1,254,228,0,1,208,208,208,1,0,0, + 0,1,125,110,0,1,254,228,0,1,208,208,208,2,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223, + 0,1,254,228,0,1,208,208,208,3,254,228,0,1,208,208,208,1,255,255, + 255,1,128,128,128,1,208,208,208,2,0,0,0,2,208,208,208,18,255,255, + 255,1,128,128,128,1,254,228,0,1,255,223,0,1,0,0,0,1,168,147, + 0,1,247,222,0,1,255,223,0,1,208,208,208,1,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223, + 0,1,254,228,0,1,208,208,208,3,254,228,0,1,208,208,208,1,255,255, + 255,1,128,128,128,1,254,228,0,2,0,0,0,1,246,221,0,1,7,6, + 0,1,246,221,0,1,208,208,208,1,254,228,0,3,208,208,208,1,254,228, + 0,3,208,208,208,1,254,228,0,3,208,208,208,1,254,228,0,3,255,255, + 255,1,128,128,128,1,254,228,0,1,255,255,0,1,0,0,0,1,125,110, + 0,1,7,6,0,1,0,0,0,1,208,208,208,1,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223, + 0,1,254,228,0,1,208,208,208,3,254,228,0,1,255,255,0,1,255,255, + 255,1,128,128,128,1,208,208,208,2,0,0,0,4,208,208,208,2,0,0, + 0,2,208,208,208,12,255,255,255,1,128,128,128,1,254,228,0,1,255,223, + 0,1,0,0,0,1,125,110,0,1,7,6,0,1,125,110,0,1,208,208, + 208,2,7,6,0,1,0,0,0,1,208,208,208,2,254,228,0,1,208,208, + 208,3,254,228,0,1,208,208,208,3,254,228,0,1,255,223,0,1,255,255, + 255,1,128,128,128,1,254,228,0,2,0,0,0,1,246,221,0,1,7,6, + 0,1,246,221,0,1,208,208,208,1,254,228,0,1,7,6,0,1,246,221, + 0,1,208,208,208,1,254,228,0,1,124,111,0,1,250,224,0,1,208,208, + 208,1,254,228,0,3,208,208,208,1,254,228,0,3,255,255,255,1,128,128, + 128,1,254,228,0,1,255,223,0,1,0,0,0,2,7,6,0,1,0,0, + 0,1,208,208,208,2,7,6,0,1,0,0,0,1,208,208,208,2,7,6, + 0,1,0,0,0,1,208,208,208,2,254,228,0,1,208,208,208,3,254,228, + 0,1,255,223,0,1,255,255,255,1,128,128,128,1,208,208,208,2,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208, + 208,2,0,0,0,2,208,208,208,4,255,255,255,1,128,128,128,1,254,228, + 0,1,255,223,0,1,0,0,0,1,125,110,0,1,7,6,0,1,125,110, + 0,1,0,0,0,2,7,6,0,1,0,0,0,3,7,6,0,1,0,0, + 0,1,208,208,208,2,7,6,0,1,0,0,0,1,208,208,208,2,254,228, + 0,1,255,223,0,1,255,255,255,1,128,128,128,1,254,228,0,2,0,0, + 0,1,246,221,0,1,7,6,0,1,246,221,0,1,0,0,0,1,246,221, + 0,1,7,6,0,1,246,221,0,1,0,0,0,1,246,221,0,1,7,6, + 0,1,246,221,0,1,208,208,208,1,254,228,0,1,7,6,0,1,246,221, + 0,1,208,208,208,1,254,228,0,3,255,255,255,1,128,128,128,1,254,228, + 0,1,255,223,0,1,0,0,0,2,7,6,0,1,0,0,0,3,7,6, + 0,1,0,0,0,3,7,6,0,1,0,0,0,3,7,6,0,1,0,0, + 0,1,208,208,208,2,254,228,0,1,255,223,0,1,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,18,208,208,208,2,255,255,255,1,128,128, + 128,1,254,228,0,1,255,223,0,1,0,0,0,1,134,117,0,1,15,13, + 0,1,134,117,0,1,0,0,0,2,15,13,0,1,0,0,0,3,15,13, + 0,1,0,0,0,3,15,13,0,1,0,0,0,3,254,228,0,1,255,223, + 0,1,255,255,255,1,128,128,128,1,254,228,0,2,208,208,208,1,254,228, + 0,3,208,208,208,1,254,228,0,3,208,208,208,1,254,228,0,3,208,208, + 208,1,254,228,0,3,208,208,208,1,254,228,0,3,255,255,255,25,100,5, + 0,0,255,255,255,26,8,8,8,1,0,0,0,1,15,15,15,1,248,248, + 248,1,8,8,8,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0, + 0,2,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248, + 248,1,0,0,0,3,255,255,255,1,0,0,0,1,255,255,255,3,248,248, + 248,1,7,7,7,1,240,240,240,1,255,255,255,1,248,248,248,1,7,7, + 7,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1,255,255, + 255,2,8,8,8,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248, + 248,1,255,255,255,5,0,0,0,1,7,7,7,1,8,8,8,1,248,248, + 248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,2,8,8, + 8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0, + 0,3,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,2,248,248, + 248,1,8,8,8,1,0,0,0,18,255,255,255,3,8,8,8,1,248,248, + 248,1,23,23,23,1,248,248,248,1,8,8,8,1,0,0,0,1,8,8, + 8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0, + 0,2,8,8,8,1,248,248,248,1,0,0,0,3,255,255,255,1,0,0, + 0,1,255,255,255,3,248,248,248,2,240,240,240,1,255,255,255,1,248,248, + 248,1,7,7,7,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248, + 248,1,255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2,8,8, + 8,1,248,248,248,1,255,255,255,5,0,0,0,1,248,248,248,1,16,16, + 16,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0, + 0,2,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248, + 248,1,0,0,0,3,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,2,248,248,248,1,8,8,8,1,0,0,0,18,255,255,255,3,8,8, + 8,1,248,248,248,1,23,23,23,1,248,248,248,1,8,8,8,1,0,0, + 0,1,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248, + 248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,3,255,255, + 255,1,0,0,0,1,255,255,255,3,248,248,248,3,255,255,255,1,248,248, + 248,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,3,0,0,0,1,255,255,255,5,254,254,254,1,2,2, + 2,1,248,248,248,1,16,16,16,1,255,255,255,1,8,8,8,1,0,0, + 0,1,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248, + 248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,3,254,254, + 254,1,2,2,2,1,255,255,255,2,0,0,0,2,248,248,248,1,8,8, + 8,1,248,248,248,1,8,8,8,1,0,0,0,2,131,131,131,1,4,4, + 4,1,0,0,0,12,255,255,255,2,248,248,248,1,16,16,16,1,248,248, + 248,1,16,16,16,1,255,255,255,1,16,16,16,1,0,0,0,2,255,255, + 255,1,8,8,8,1,0,0,0,2,255,255,255,1,0,0,0,3,255,255, + 255,1,0,0,0,3,248,248,248,1,8,8,8,1,255,255,255,3,248,248, + 248,3,255,255,255,1,248,248,248,1,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255, + 255,5,248,248,248,1,8,8,8,1,248,248,248,1,8,8,8,1,255,255, + 255,1,8,8,8,1,0,0,0,2,255,255,255,1,8,8,8,1,0,0, + 0,2,255,255,255,1,8,8,8,1,0,0,0,2,255,255,255,1,0,0, + 0,3,248,248,248,1,8,8,8,1,255,255,255,2,0,0,0,2,248,248, + 248,1,8,8,8,1,248,248,248,1,8,8,8,1,7,7,7,1,0,0, + 0,1,248,248,248,1,8,8,8,1,0,0,0,2,248,248,248,1,8,8, + 8,1,0,0,0,2,131,131,131,1,4,4,4,1,0,0,0,4,255,255, + 255,2,248,248,248,1,16,16,16,1,248,248,248,1,16,16,16,1,255,255, + 255,1,16,16,16,1,248,248,248,1,8,8,8,1,255,255,255,1,8,8, + 8,1,131,131,131,1,4,4,4,1,255,255,255,1,8,8,8,1,0,0, + 0,2,255,255,255,1,8,8,8,1,0,0,0,2,248,248,248,1,8,8, + 8,1,255,255,255,3,248,248,248,3,255,255,255,1,248,248,248,2,255,255, + 255,3,248,248,248,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,5,248,248,248,1,8,8,8,1,248,248,248,1,8,8, + 8,1,255,255,255,1,8,8,8,1,248,248,248,1,8,8,8,1,255,255, + 255,1,8,8,8,1,248,248,248,1,8,8,8,1,255,255,255,1,8,8, + 8,1,131,131,131,1,4,4,4,1,255,255,255,1,8,8,8,1,0,0, + 0,2,248,248,248,1,8,8,8,1,255,255,255,2,0,0,0,2,248,248, + 248,1,8,8,8,1,248,248,248,1,8,8,8,1,248,248,248,1,8,8, + 8,1,248,248,248,1,8,8,8,1,248,248,248,1,8,8,8,1,248,248, + 248,1,8,8,8,1,248,248,248,1,8,8,8,1,248,248,248,1,8,8, + 8,1,131,131,131,1,4,4,4,1,0,0,0,2,255,255,255,2,248,248, + 248,1,16,16,16,1,240,240,240,1,15,15,15,1,255,255,255,1,15,15, + 15,1,240,240,240,1,7,7,7,1,255,255,255,1,7,7,7,1,240,240, + 240,1,7,7,7,1,255,255,255,1,7,7,7,1,240,240,240,1,7,7, + 7,1,255,255,255,1,7,7,7,1,240,240,240,1,7,7,7,1,248,248, + 248,1,8,8,8,1,255,255,255,3,248,248,248,1,0,0,0,1,248,248, + 248,1,255,255,255,1,248,248,248,1,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255, + 255,28,0,0) + ); + +const + objdata_tsignoise: record size: integer; data: array[0..2868] of byte end = + (size: 2869; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,105, + 103,110,111,105,115,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,192,10,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230, + 224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234, + 230,193,1,231,227,192,1,85,83,71,1,7,7,6,2,114,112,98,1,238, + 235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243, + 240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,135,132,112,1,235,230,196,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,241, + 239,222,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,227,223,187,1,20,20,17,1,202,197,168,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,208,205,190,1,188,186,173,1,28, + 28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,139, + 137,115,1,0,0,0,1,158,155,132,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,105,104,96,1,158,157,146,1,244,242,227,1,18, + 18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,221,216,178,1,231,227,189,1,33,32,27,1,62, + 61,51,1,115,112,96,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,231, + 228,210,1,13,13,12,1,132,130,121,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,227,221,176,1,231,225,180,1,231,226,183,1,224, + 219,178,1,49,48,40,1,147,145,120,1,56,55,46,1,158,155,131,1,71, + 70,59,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,140,139,128,1,5, + 5,4,1,104,103,96,1,133,132,124,1,14,14,11,1,229,223,173,1,229, + 224,175,1,113,110,87,1,180,176,140,1,231,226,183,1,92,90,73,1,3, + 3,2,1,11,11,9,1,163,161,135,1,202,198,167,1,28,27,23,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,38,37,35,1,125,123,114,1,184, + 182,170,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,91, + 89,71,1,9,9,7,1,101,98,80,1,33,32,26,1,130,127,105,1,37, + 37,31,1,233,229,192,1,234,230,194,1,12,12,10,1,221,217,187,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,176,174,158,1,44,43,40,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,87,85,68,1,95, + 93,74,1,23,22,18,1,188,184,150,1,216,211,174,1,150,147,122,1,234, + 230,193,1,235,231,195,1,55,53,46,1,179,176,151,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,82, + 81,74,1,145,143,132,1,243,240,222,1,243,241,224,1,75,75,70,1,160, + 156,120,1,229,223,173,1,229,224,175,1,84,82,65,1,149,146,116,1,221, + 216,175,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,99,97,83,1,135,133,115,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,237,235,212,1,17,17,15,1,219, + 217,199,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,80,78,62,1,153,149,119,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,146, + 143,122,1,87,86,74,1,202,198,172,1,114,112,98,1,238,235,207,1,239, + 236,210,1,231,228,204,1,164,162,147,1,44,44,40,1,242,239,220,1,243, + 240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229, + 224,175,1,76,74,59,1,157,153,122,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,203,198,169,1,30, + 29,25,1,151,149,129,1,0,0,0,1,199,196,173,1,239,236,210,1,161, + 159,142,1,0,0,0,1,112,110,100,1,242,239,220,1,243,240,222,1,243, + 241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,72, + 70,56,1,160,156,125,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,24,24,20,1,99, + 97,84,1,7,6,6,1,106,105,93,1,239,236,210,1,154,152,136,1,0, + 0,0,1,179,176,161,1,242,239,220,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,69,67,53,1,164, + 160,128,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,81,80,69,1,20,19,17,1,100, + 98,86,1,21,21,19,1,237,234,208,1,147,145,130,1,37,36,33,1,235, + 232,212,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228, + 222,171,1,229,223,173,1,229,224,175,1,65,63,50,1,167,162,130,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,139,136,118,1,0,0,0,1,156,153,134,1,49, + 48,42,1,181,179,159,1,140,138,124,1,104,103,93,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,33, + 32,25,1,213,208,163,1,60,59,47,1,170,166,133,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,196,193,166,1,0,0,0,1,180,177,155,1,122,121,106,1,105, + 104,92,1,133,131,117,1,110,109,99,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,46,45,35,1,179, + 175,137,1,57,55,44,1,174,169,136,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,235, + 231,199,1,80,79,68,1,214,210,184,1,197,194,171,1,30,30,26,1,125, + 124,111,1,118,117,105,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,244,242,227,1,7,7,5,1,81,79,61,1,144,141,110,1,53, + 52,41,1,178,173,138,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,32,31,28,1,72,72,64,1,124, + 123,111,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28, + 28,26,1,103,100,77,1,115,112,87,1,110,107,84,1,47,46,36,1,184, + 179,143,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,107,106,94,1,6,6,5,1,131,130,117,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228, + 222,171,1,150,146,113,1,56,54,43,1,25,25,20,1,204,199,159,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,181,179,159,1,0,0,0,1,137,136,123,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,215, + 209,162,1,69,68,53,1,0,0,0,1,224,218,174,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,236, + 233,208,1,19,19,17,1,145,144,130,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229, + 224,175,1,143,140,111,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,150, + 148,132,1,198,196,177,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205, + 204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11, + 11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145, + 143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1,86, + 85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38, + 37,34,1,7,7,7,1,4,4,4,1,156,1,0,0,244,244,244,1,248, + 248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203, + 203,203,1,128,128,128,1,129,129,129,1,188,188,188,1,248,248,248,2,173, + 173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128, + 128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255, + 255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195, + 195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180, + 180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146, + 146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128, + 128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188, + 188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248, + 248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigmidisource: record size: integer; data: array[0..2869] of byte end = + (size: 2870; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,105, + 103,109,105,100,105,115,111,117,114,99,101,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 244,242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,181,177,138,1, + 183,178,142,1,231,225,180,1,231,226,183,1,232,227,185,1,224,219,181,1, + 167,164,136,1,222,218,183,1,229,226,190,1,178,174,148,1,236,232,200,1, + 209,206,178,1,171,168,147,1,171,169,149,1,182,180,160,1,218,216,193,1, + 240,238,215,1,241,238,217,1,242,239,220,1,180,178,165,1,241,239,222,1, + 75,75,70,1,160,156,120,1,229,223,173,1,57,55,43,1,17,17,13,1, + 226,221,176,1,231,226,183,1,232,227,185,1,148,145,119,1,0,0,0,1, + 190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1, + 44,43,38,1,96,95,84,1,86,85,76,1,38,37,33,1,123,122,110,1, + 241,238,217,1,242,239,220,1,17,17,16,1,233,232,215,1,244,242,227,1, + 7,7,5,1,229,223,173,1,57,55,43,1,53,52,41,1,164,160,128,1, + 231,226,183,1,232,227,185,1,71,70,58,1,45,44,37,1,190,187,157,1, + 215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,109,107,94,1, + 238,235,207,1,239,236,210,1,225,222,199,1,37,36,33,1,195,192,175,1, + 242,239,220,1,17,17,16,1,233,232,215,1,244,242,227,1,7,7,5,1, + 229,223,173,1,57,55,43,1,132,128,102,1,85,83,66,1,231,226,183,1, + 215,210,171,1,69,67,55,1,65,64,53,1,190,187,157,1,215,211,178,1, + 28,27,23,1,236,232,200,1,136,133,116,1,109,107,94,1,238,235,207,1, + 239,236,210,1,240,237,212,1,103,102,92,1,135,133,122,1,242,239,220,1, + 17,17,16,1,233,232,215,1,75,75,70,1,49,48,37,1,229,223,173,1, + 57,55,43,1,186,181,144,1,37,36,29,1,225,220,178,1,139,136,111,1, + 145,142,117,1,65,64,53,1,190,187,157,1,215,211,178,1,28,27,23,1, + 236,232,200,1,136,133,116,1,109,107,94,1,238,235,207,1,239,236,210,1, + 240,237,212,1,135,133,121,1,112,111,101,1,242,239,220,1,17,17,16,1, + 233,232,215,1,7,7,7,1,228,222,171,1,229,223,173,1,57,55,43,1, + 187,182,144,1,101,98,78,1,159,156,126,1,66,64,52,1,219,215,177,1, + 65,64,53,1,190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1, + 136,133,116,1,109,107,94,1,238,235,207,1,239,236,210,1,240,237,212,1, + 103,102,92,1,142,140,128,1,242,239,220,1,17,17,16,1,233,232,215,1, + 7,7,7,1,228,222,171,1,229,223,173,1,57,55,43,1,187,182,144,1, + 179,175,140,1,65,64,52,1,77,76,62,1,233,228,188,1,65,64,53,1, + 190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1, + 109,107,94,1,238,235,207,1,239,236,210,1,198,195,175,1,24,23,21,1, + 221,218,199,1,242,239,220,1,17,17,16,1,233,232,215,1,133,132,124,1, + 95,93,71,1,229,223,173,1,57,55,43,1,187,182,144,1,230,224,179,1, + 26,26,21,1,156,152,124,1,233,228,188,1,65,64,53,1,190,187,157,1, + 215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,17,17,14,1, + 36,36,32,1,32,31,28,1,51,50,45,1,180,178,161,1,241,238,217,1, + 242,239,220,1,17,17,16,1,233,232,215,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1, + 230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1, + 233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1, + 238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1, + 242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1, + 128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1, + 255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1, + 180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1, + 146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigmidiconnector: record size: integer; data: array[0..2800] of byte end = + (size: 2801; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,115,105, + 103,109,105,100,105,99,111,110,110,101,99,116,111,114,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,116, + 10,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,164, + 8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7, + 7,5,1,22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7, + 7,6,2,61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7, + 7,6,2,114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7, + 7,7,2,204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151, + 147,113,1,229,223,173,1,224,219,171,1,225,220,175,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,226,222,184,1,233,229,192,1,235, + 231,195,1,230,225,192,1,236,232,200,1,234,230,200,1,231,227,199,1,231, + 228,201,1,238,235,209,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,236,233,216,1,243,241,224,1,7,7,7,1,228,222,171,1,229, + 223,173,1,57,55,43,1,31,30,24,1,231,225,180,1,231,226,183,1,232, + 227,185,1,168,165,136,1,0,0,0,1,190,187,157,1,215,211,178,1,28, + 27,23,1,236,232,200,1,136,133,116,1,17,17,14,1,36,36,32,1,31, + 31,27,1,46,46,41,1,172,171,154,1,241,238,217,1,242,239,220,1,17, + 17,16,1,233,232,215,1,28,28,26,1,228,222,171,1,229,223,173,1,57, + 55,43,1,34,33,27,1,183,178,143,1,231,226,183,1,232,227,185,1,88, + 86,71,1,28,28,23,1,190,187,157,1,215,211,178,1,28,27,23,1,236, + 232,200,1,136,133,116,1,109,107,94,1,238,235,207,1,239,236,210,1,194, + 191,171,1,30,30,27,1,215,212,193,1,242,239,220,1,17,17,16,1,233, + 232,215,1,244,242,227,1,18,18,14,1,229,223,173,1,57,55,43,1,112, + 109,87,1,105,102,82,1,231,226,183,1,226,221,180,1,58,56,46,1,65, + 64,53,1,190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1,136, + 133,116,1,109,107,94,1,238,235,207,1,239,236,210,1,240,237,212,1,90, + 90,81,1,145,143,130,1,242,239,220,1,17,17,16,1,233,232,215,1,244, + 242,227,1,7,7,5,1,229,223,173,1,57,55,43,1,179,174,138,1,38, + 37,30,1,230,225,182,1,159,156,127,1,125,122,101,1,65,64,53,1,190, + 187,157,1,215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,109, + 107,94,1,238,235,207,1,239,236,210,1,240,237,212,1,134,133,120,1,112, + 111,101,1,242,239,220,1,17,17,16,1,233,232,215,1,133,132,124,1,14, + 14,11,1,229,223,173,1,57,55,43,1,187,182,144,1,81,79,63,1,179, + 175,142,1,80,78,64,1,206,201,166,1,65,64,53,1,190,187,157,1,215, + 211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,109,107,94,1,238, + 235,207,1,239,236,210,1,240,237,212,1,115,114,103,1,132,131,119,1,242, + 239,220,1,17,17,16,1,233,232,215,1,7,7,7,1,228,222,171,1,229, + 223,173,1,57,55,43,1,187,182,144,1,159,155,124,1,94,92,75,1,64, + 62,51,1,233,228,188,1,65,64,53,1,190,187,157,1,215,211,178,1,28, + 27,23,1,236,232,200,1,136,133,116,1,109,107,94,1,238,235,207,1,239, + 236,210,1,231,228,204,1,33,33,30,1,200,198,180,1,242,239,220,1,17, + 17,16,1,233,232,215,1,7,7,7,1,228,222,171,1,229,223,173,1,57, + 55,43,1,187,182,144,1,225,219,175,1,16,16,13,1,136,133,108,1,233, + 228,188,1,65,64,53,1,190,187,157,1,215,211,178,1,28,27,23,1,236, + 232,200,1,136,133,116,1,44,43,38,1,96,95,84,1,83,82,73,1,34, + 33,30,1,129,128,116,1,241,238,217,1,242,239,220,1,17,17,16,1,233, + 232,215,1,75,75,70,1,160,156,120,1,229,223,173,1,186,182,142,1,219, + 213,170,1,231,225,180,1,188,183,149,1,221,216,176,1,233,228,188,1,191, + 188,156,1,223,219,184,1,230,226,191,1,184,180,154,1,236,232,200,1,212, + 208,181,1,178,175,154,1,178,176,155,1,187,185,165,1,224,221,198,1,240, + 238,215,1,241,238,217,1,242,239,220,1,187,184,171,1,241,239,222,1,244, + 242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,49,48,37,1,229, + 223,173,1,229,224,175,1,230,224,178,1,127,124,99,1,177,173,140,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,132,131,118,1,184,182,166,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,177,172,138,1,22,21,17,1,177,174,141,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,184,182,164,1,23,22,20,1,185,183,168,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,184,182,166,1,23,22,21,1,186,184,170,1,243,241,224,1,133, + 132,124,1,95,93,71,1,229,223,173,1,0,0,0,19,53,53,49,1,243, + 241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,184,182,166,1,23,22,21,1,186,184,170,1,243,241,224,1,244, + 242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,177, + 172,138,1,22,21,17,1,177,174,141,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,184,182,164,1,23, + 22,20,1,185,183,168,1,243,240,222,1,243,241,224,1,28,28,26,1,103, + 100,77,1,229,223,173,1,229,224,175,1,230,224,178,1,127,124,99,1,177, + 173,140,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,132,131,118,1,184,182,166,1,242, + 239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244, + 242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4, + 3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7, + 7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7, + 7,6,2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7, + 7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7, + 7,7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233, + 233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128, + 128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221, + 221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244, + 244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236, + 236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165, + 165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150, + 150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255, + 255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131, + 131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255, + 255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244, + 244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248, + 248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173, + 173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0, + 0) + ); + +const + objdata_tsigmidimulticonnector: record size: integer; data: array[0..2733] of byte end = + (size: 2734; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,115,105, + 103,109,105,100,105,109,117,108,116,105,99,111,110,110,101,99,116,111,114,23, + 98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105, + 111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95, + 99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,44,10,0,0,0,0,0,0,6,0,0,0,24,0,0,0, + 24,0,0,0,92,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 4,3,3,1,7,7,5,1,22,22,17,1,230,224,178,1,231,225,180,1, + 143,140,113,1,7,7,6,2,61,60,49,1,234,230,193,1,235,231,195,1, + 85,83,71,1,7,7,6,2,114,112,98,1,238,235,207,1,239,236,210,1, + 37,37,33,1,7,7,7,2,204,201,185,1,243,240,222,1,230,228,212,1, + 4,4,4,1,151,147,113,1,229,223,173,1,224,219,171,1,225,220,175,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,226,222,184,1, + 233,229,192,1,235,231,195,1,230,225,192,1,236,232,200,1,234,230,200,1, + 231,227,199,1,231,228,201,1,238,235,209,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,236,233,216,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,57,55,43,1,31,30,24,1,231,225,180,1, + 231,226,183,1,232,227,185,1,168,165,136,1,0,0,0,1,190,187,157,1, + 215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,17,17,14,1, + 36,36,32,1,31,31,27,1,46,46,41,1,172,171,154,1,241,238,217,1, + 242,239,220,1,17,17,16,1,233,232,215,1,28,28,26,1,228,222,171,1, + 229,223,173,1,57,55,43,1,34,33,27,1,183,178,143,1,231,226,183,1, + 232,227,185,1,88,86,71,1,28,28,23,1,190,187,157,1,215,211,178,1, + 28,27,23,1,236,232,200,1,136,133,116,1,109,107,94,1,238,235,207,1, + 239,236,210,1,194,191,171,1,30,30,27,1,215,212,193,1,242,239,220,1, + 17,17,16,1,233,232,215,1,244,242,227,1,18,18,14,1,229,223,173,1, + 57,55,43,1,112,109,87,1,105,102,82,1,231,226,183,1,226,221,180,1, + 58,56,46,1,65,64,53,1,190,187,157,1,215,211,178,1,28,27,23,1, + 236,232,200,1,136,133,116,1,109,107,94,1,238,235,207,1,239,236,210,1, + 240,237,212,1,90,90,81,1,145,143,130,1,242,239,220,1,17,17,16,1, + 233,232,215,1,244,242,227,1,7,7,5,1,229,223,173,1,57,55,43,1, + 179,174,138,1,38,37,30,1,230,225,182,1,159,156,127,1,125,122,101,1, + 65,64,53,1,190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1, + 136,133,116,1,109,107,94,1,238,235,207,1,239,236,210,1,240,237,212,1, + 134,133,120,1,112,111,101,1,242,239,220,1,17,17,16,1,233,232,215,1, + 133,132,124,1,14,14,11,1,229,223,173,1,57,55,43,1,187,182,144,1, + 81,79,63,1,179,175,142,1,80,78,64,1,206,201,166,1,65,64,53,1, + 190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1, + 109,107,94,1,238,235,207,1,239,236,210,1,240,237,212,1,115,114,103,1, + 132,131,119,1,242,239,220,1,17,17,16,1,233,232,215,1,7,7,7,1, + 228,222,171,1,229,223,173,1,57,55,43,1,187,182,144,1,159,155,124,1, + 94,92,75,1,64,62,51,1,233,228,188,1,65,64,53,1,190,187,157,1, + 215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,109,107,94,1, + 238,235,207,1,239,236,210,1,231,228,204,1,33,33,30,1,200,198,180,1, + 242,239,220,1,17,17,16,1,233,232,215,1,7,7,7,1,228,222,171,1, + 229,223,173,1,57,55,43,1,187,182,144,1,225,219,175,1,16,16,13,1, + 136,133,108,1,233,228,188,1,65,64,53,1,190,187,157,1,215,211,178,1, + 28,27,23,1,236,232,200,1,136,133,116,1,44,43,38,1,96,95,84,1, + 83,82,73,1,34,33,30,1,129,128,116,1,241,238,217,1,242,239,220,1, + 17,17,16,1,233,232,215,1,75,75,70,1,160,156,120,1,229,223,173,1, + 186,182,142,1,219,213,170,1,231,225,180,1,188,183,149,1,221,216,176,1, + 233,228,188,1,191,188,156,1,223,219,184,1,230,226,191,1,184,180,154,1, + 236,232,200,1,212,208,181,1,178,175,154,1,178,176,155,1,187,185,165,1, + 224,221,198,1,240,238,215,1,241,238,217,1,242,239,220,1,187,184,171,1, + 241,239,222,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,127,124,99,1,177,173,140,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 132,131,118,1,184,182,166,1,242,239,220,1,243,240,222,1,243,241,224,1, + 244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1, + 177,172,138,1,22,21,17,1,177,174,141,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,184,182,164,1, + 23,22,20,1,185,183,168,1,243,240,222,1,243,241,224,1,75,75,70,1, + 49,48,37,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 177,173,140,1,22,21,17,1,178,174,144,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166,1, + 23,22,21,1,186,184,170,1,243,241,224,1,7,7,7,1,228,222,171,1, + 229,223,173,1,0,0,0,19,53,53,49,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 177,173,140,1,22,21,17,1,178,174,144,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166,1, + 23,22,21,1,186,184,170,1,243,241,224,1,133,132,124,1,95,93,71,1, + 229,223,173,1,229,224,175,1,230,224,178,1,177,172,138,1,22,21,17,1, + 177,174,141,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,184,182,164,1,23,22,20,1,185,183,168,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,70,68,54,1,135,132,107,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,72,72,65,1,141,139,127,1,242,239,220,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,177,172,138,1,22,21,17,1,177,174,141,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 184,182,164,1,23,22,20,1,185,183,168,1,243,240,222,1,243,241,224,1, + 28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 184,182,166,1,23,22,21,1,186,184,170,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,0,0,0,19,53,53,49,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 184,182,166,1,23,22,21,1,186,184,170,1,243,241,224,1,231,229,215,1, + 44,43,33,1,229,223,173,1,229,224,175,1,230,224,178,1,177,172,138,1, + 22,21,17,1,177,174,141,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,184,182,164,1,23,22,20,1, + 185,183,168,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,127,124,99,1,177,173,140,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,132,131,118,1,184,182,166,1,242,239,220,1, + 243,240,222,1,243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1, + 229,224,175,1,230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1, + 233,228,188,1,233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1, + 237,233,202,1,238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1, + 241,238,217,1,242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1, + 152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2, + 158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1, + 248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2, + 139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1, + 128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 165,165,165,1,180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1, + 176,176,176,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1, + 244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1, + 233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1, + 128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2, + 221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigoutaudio: record size: integer; data: array[0..2851] of byte end = + (size: 2852; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,105, + 103,111,117,116,97,117,100,105,111,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,172,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,220,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22, + 17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60, + 49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112, + 98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201, + 185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,185,181, + 149,1,226,222,184,1,234,230,193,1,229,225,190,1,195,191,163,1,236,232, + 200,1,237,233,202,1,202,198,174,1,227,224,197,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,231,226,184,1,33,32,27,1,159,156, + 130,1,234,230,193,1,210,207,174,1,92,90,76,1,236,232,200,1,237,233, + 202,1,108,106,93,1,197,194,171,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242, + 227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,185,181,147,1,105,103,85,1,89,87,72,1,234,230, + 193,1,210,207,174,1,92,90,76,1,236,232,200,1,237,233,202,1,108,106, + 93,1,197,194,171,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,119,117,95,1,182,178,147,1,65,64,53,1,232,228,191,1,210,207, + 174,1,92,90,76,1,236,232,200,1,237,233,202,1,108,106,93,1,197,194, + 171,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,69,68, + 55,1,231,226,187,1,115,113,94,1,180,177,148,1,210,207,174,1,92,90, + 76,1,236,232,200,1,237,233,202,1,108,106,93,1,197,194,171,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,216,211,171,1,22,21,17,1,43,42, + 35,1,38,38,31,1,108,106,89,1,226,222,187,1,80,78,66,1,236,232, + 200,1,237,233,202,1,83,82,72,1,211,208,183,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,153,150,121,1,140,137,112,1,233,228,188,1,230,226, + 188,1,53,52,44,1,235,231,195,1,56,54,46,1,230,226,195,1,229,225, + 195,1,45,44,39,1,234,231,204,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,75,75, + 70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,88,86,70,1,204,199,163,1,233,228,188,1,233,229,190,1,81,79, + 67,1,201,197,167,1,150,147,125,1,35,35,30,1,29,28,25,1,144,141, + 124,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,132,131, + 119,1,185,183,168,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,231,227,196,1,230,227,196,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166,1,23,22, + 21,1,186,184,170,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,185,183,168,1,23,23, + 21,1,186,184,171,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224, + 175,1,230,224,178,1,226,221,176,1,224,219,177,1,230,225,184,1,233,228, + 188,1,233,229,190,1,234,230,193,1,230,226,191,1,236,231,197,1,236,232, + 200,1,234,230,200,1,221,217,191,1,238,235,207,1,239,236,210,1,0,0, + 0,5,53,53,49,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,84,82,66,1,33,32,26,1,31,30,25,1,71,70, + 58,1,225,221,183,1,227,223,187,1,74,72,61,1,236,231,197,1,185,182, + 157,1,24,24,21,1,51,50,44,1,83,82,72,1,237,234,208,1,240,237, + 212,1,240,238,215,1,241,238,217,1,185,183,168,1,23,23,21,1,186,184, + 171,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,84,82,66,1,212,207,168,1,232,227,185,1,132,130,107,1,131,128, + 107,1,227,223,187,1,74,72,61,1,236,231,197,1,51,50,43,1,204,201, + 174,1,238,234,205,1,139,137,121,1,133,131,117,1,240,237,212,1,240,238, + 215,1,184,182,166,1,23,22,21,1,186,184,170,1,243,241,224,1,133,132, + 124,1,95,93,71,1,229,223,173,1,229,224,175,1,230,224,178,1,84,82, + 66,1,212,207,168,1,232,227,185,1,220,215,178,1,70,69,57,1,227,223, + 187,1,74,72,61,1,205,201,172,1,62,61,53,1,237,233,202,1,238,234, + 205,1,234,231,204,1,68,68,60,1,240,237,212,1,240,238,215,1,132,131, + 119,1,185,183,168,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,230,224,178,1,84,82,66,1,212,207, + 168,1,232,227,185,1,233,228,188,1,64,63,52,1,227,223,187,1,74,72, + 61,1,180,177,151,1,114,112,96,1,237,233,202,1,238,234,205,1,238,235, + 207,1,59,58,52,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,84,82,66,1,212,207,168,1,232,227, + 185,1,231,226,187,1,61,60,50,1,227,223,187,1,74,72,61,1,204,199, + 170,1,83,82,71,1,237,233,202,1,238,234,205,1,223,220,194,1,59,58, + 52,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,229,224, + 175,1,230,224,178,1,84,82,66,1,212,207,168,1,232,227,185,1,167,164, + 135,1,106,104,86,1,227,223,187,1,74,72,61,1,234,229,195,1,45,45, + 38,1,229,225,195,1,238,234,205,1,159,157,138,1,110,108,96,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,84,82,66,1,86,84,68,1,82,80,65,1,40,39,32,1,208,205, + 170,1,227,223,187,1,74,72,61,1,236,231,197,1,164,161,139,1,33,32, + 28,1,94,93,81,1,35,34,30,1,225,222,198,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7, + 7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,195,190, + 152,1,173,169,137,1,182,178,145,1,225,220,181,1,233,229,190,1,232,228, + 191,1,195,192,162,1,236,231,197,1,236,232,200,1,216,212,184,1,172,169, + 148,1,231,228,201,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,231,229,215,1,44,43, + 33,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224, + 175,1,230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228, + 188,1,233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233, + 202,1,238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238, + 217,1,242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1, + 0,0,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158, + 158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248, + 248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139, + 139,1,128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128, + 128,1,255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165, + 165,1,180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176, + 176,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244, + 244,1,146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233, + 233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128, + 128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221, + 221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tmidisource: record size: integer; data: array[0..1614] of byte end = + (size: 1615; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,109,105, + 100,105,115,111,117,114,99,101,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,216,5,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,228,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0, + 4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208, + 1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,23,0,0,0, + 1,208,208,208,24,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208, + 22,0,0,0,2,208,208,208,22,0,0,0,1,208,208,208,23,0,0,0, + 1,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,5,208,208,208, + 1,0,0,0,5,208,208,208,3,0,0,0,4,208,208,208,1,0,0,0, + 3,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,6,208,208,208, + 2,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0, + 3,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,3,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0, + 1,208,208,208,1,0,0,0,3,208,208,208,1,0,0,0,6,208,208,208, + 1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0, + 4,208,208,208,1,0,0,0,10,208,208,208,1,0,0,0,2,208,208,208, + 3,0,0,0,2,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0, + 10,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208, + 1,0,0,0,3,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0, + 4,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208, + 1,0,0,0,4,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0, + 4,208,208,208,1,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208, + 1,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,22,0,0,0, + 2,208,208,208,22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208, + 23,0,0,0,2,208,208,208,23,0,0,0,1,208,208,208,22,0,0,0, + 3,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,3,188,3,0,0,240,240,240, + 2,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150, + 1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0, + 2,187,187,187,1,240,240,240,2,22,22,22,1,0,0,0,1,7,7,7, + 1,240,240,240,1,52,52,52,1,0,0,0,22,240,240,240,1,0,0,0, + 23,202,202,202,1,0,0,0,24,217,217,217,1,0,0,0,23,240,240,240, + 1,0,0,0,22,75,75,75,1,225,225,225,1,0,0,0,22,240,240,240, + 1,0,0,0,23,240,240,240,1,0,0,0,2,54,54,54,1,52,52,52, + 1,0,0,0,3,10,10,10,1,72,72,72,1,13,13,13,1,6,6,6, + 1,63,63,63,1,0,0,0,1,30,30,30,1,72,72,72,2,61,61,61, + 1,23,23,23,1,0,0,0,3,66,66,66,1,2,2,2,1,135,135,135, + 1,45,45,45,1,0,0,0,1,192,192,192,1,236,236,236,1,5,5,5, + 1,0,0,0,2,93,93,93,1,255,255,255,1,48,48,48,1,22,22,22, + 1,225,225,225,1,0,0,0,1,109,109,109,1,208,208,208,1,152,152,152, + 1,163,163,163,1,215,215,215,1,124,124,124,1,0,0,0,2,237,237,237, + 1,10,10,10,1,0,0,0,1,240,240,240,1,0,0,0,1,192,192,192, + 1,196,196,196,1,74,74,74,1,0,0,0,2,177,177,177,1,206,206,206, + 1,48,48,48,1,22,22,22,1,225,225,225,1,0,0,0,1,109,109,109, + 1,138,138,138,1,0,0,0,2,16,16,16,1,216,216,216,1,49,49,49, + 1,0,0,0,1,237,237,237,1,10,10,10,1,0,0,0,1,240,240,240, + 1,0,0,0,1,192,192,192,1,109,109,109,1,161,161,161,1,0,0,0, + 1,19,19,19,1,180,180,180,1,184,184,184,1,48,48,48,1,22,22,22, + 1,225,225,225,1,0,0,0,1,109,109,109,1,138,138,138,1,0,0,0, + 3,146,146,146,1,112,112,112,1,0,0,0,1,237,237,237,1,10,10,10, + 1,135,135,135,1,165,165,165,1,0,0,0,1,192,192,192,1,49,49,49, + 1,214,214,214,1,7,7,7,1,102,102,102,1,96,96,96,1,184,184,184, + 1,48,48,48,1,22,22,22,1,225,225,225,1,0,0,0,1,109,109,109, + 1,138,138,138,1,0,0,0,3,112,112,112,1,136,136,136,1,0,0,0, + 1,237,237,237,1,10,10,10,1,240,240,240,1,0,0,0,2,192,192,192, + 1,48,48,48,1,144,144,144,1,79,79,79,1,183,183,183,1,15,15,15, + 1,184,184,184,1,48,48,48,1,22,22,22,1,225,225,225,1,0,0,0, + 1,109,109,109,1,138,138,138,1,0,0,0,3,146,146,146,1,105,105,105, + 1,0,0,0,1,237,237,237,1,10,10,10,1,240,240,240,1,0,0,0, + 2,192,192,192,1,48,48,48,1,57,57,57,1,183,183,183,1,170,170,170, + 1,0,0,0,1,184,184,184,1,48,48,48,1,22,22,22,1,225,225,225, + 1,0,0,0,1,109,109,109,1,138,138,138,1,0,0,0,2,45,45,45, + 1,230,230,230,1,21,21,21,1,0,0,0,1,237,237,237,1,10,10,10, + 1,75,75,75,1,105,105,105,1,0,0,0,1,192,192,192,1,48,48,48, + 1,1,1,1,1,226,226,226,1,84,84,84,1,0,0,0,1,184,184,184, + 1,48,48,48,1,22,22,22,1,225,225,225,1,0,0,0,1,109,109,109, + 1,237,237,237,1,216,216,216,1,221,221,221,1,201,201,201,1,64,64,64, + 1,0,0,0,2,237,237,237,1,10,10,10,1,0,0,0,1,240,240,240, + 1,0,0,0,23,240,240,240,1,0,0,0,22,202,202,202,1,97,97,97, + 1,0,0,0,22,240,240,240,1,0,0,0,23,240,240,240,1,0,0,0, + 23,7,7,7,1,172,172,172,1,0,0,0,23,240,240,240,1,0,0,0, + 22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232,232,232, + 1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240, + 2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90, + 1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_taudioout: record size: integer; data: array[0..2048] of byte end = + (size: 2049; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,97,117, + 100,105,111,111,117,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,140,7,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,140,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1,0, + 0,0,3,208,208,208,22,0,0,0,1,208,208,208,7,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,7,0, + 0,0,1,208,208,208,6,0,0,0,3,208,208,208,1,0,0,0,2,208, + 208,208,2,0,0,0,2,208,208,208,8,0,0,0,1,208,208,208,5,0, + 0,0,3,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208, + 208,208,8,0,0,0,1,208,208,208,5,0,0,0,6,208,208,208,2,0, + 0,0,2,208,208,208,7,0,0,0,2,208,208,208,5,0,0,0,6,208, + 208,208,2,0,0,0,2,208,208,208,7,0,0,0,1,208,208,208,5,0, + 0,0,7,208,208,208,2,0,0,0,2,208,208,208,7,0,0,0,1,208, + 208,208,5,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0, + 0,0,5,208,208,208,7,0,0,0,2,208,208,208,4,0,0,0,2,208, + 208,208,2,0,0,0,6,208,208,208,4,0,0,0,2,208,208,208,3,0, + 0,0,1,208,208,208,11,0,0,0,2,208,208,208,5,0,0,0,3,208, + 208,208,2,0,0,0,1,208,208,208,19,0,0,0,5,208,208,208,3,0, + 0,0,3,208,208,208,3,0,0,0,1,208,208,208,2,0,0,0,2,208, + 208,208,2,0,0,0,7,208,208,208,4,0,0,0,7,208,208,208,1,0, + 0,0,5,208,208,208,3,0,0,0,4,208,208,208,4,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,2,0,0,0,3,208,208,208,1,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,2,0, + 0,0,2,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,1,208, + 208,208,3,0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,3,0, + 0,0,1,208,208,208,7,0,0,0,1,208,208,208,3,0,0,0,2,208, + 208,208,1,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,6,0, + 0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,7,208, + 208,208,1,0,0,0,2,208,208,208,6,0,0,0,1,208,208,208,4,0, + 0,0,7,208,208,208,1,0,0,0,5,208,208,208,6,0,0,0,1,208, + 208,208,4,0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,2,0, + 0,0,3,208,208,208,7,0,0,0,2,208,208,208,23,0,0,0,1,208, + 208,208,22,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2,0, + 0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,3,200, + 4,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1,240, + 240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90, + 90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1,0, + 0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0,22,240, + 240,240,1,0,0,0,7,53,53,53,1,8,8,8,1,0,0,0,1,7, + 7,7,1,44,44,44,1,0,0,0,2,39,39,39,1,12,12,12,1,0, + 0,0,7,202,202,202,1,0,0,0,6,1,1,1,1,219,219,219,1,81, + 81,81,1,0,0,0,1,27,27,27,1,156,156,156,1,0,0,0,2,139, + 139,139,1,44,44,44,1,0,0,0,8,217,217,217,1,0,0,0,5,52, + 52,52,1,140,140,140,1,158,158,158,1,0,0,0,1,27,27,27,1,156, + 156,156,1,0,0,0,2,139,139,139,1,44,44,44,1,0,0,0,8,240, + 240,240,1,0,0,0,5,124,124,124,1,56,56,56,1,184,184,184,1,2, + 2,2,1,27,27,27,1,156,156,156,1,0,0,0,2,139,139,139,1,44, + 44,44,1,0,0,0,7,75,75,75,1,225,225,225,1,0,0,0,5,179, + 179,179,1,2,2,2,1,129,129,129,1,59,59,59,1,27,27,27,1,156, + 156,156,1,0,0,0,2,139,139,139,1,44,44,44,1,0,0,0,7,240, + 240,240,1,0,0,0,5,17,17,17,1,231,231,231,1,208,208,208,1,213, + 213,213,1,137,137,137,1,10,10,10,1,169,169,169,1,0,0,0,2,166, + 166,166,1,29,29,29,1,0,0,0,7,240,240,240,1,0,0,0,5,86, + 86,86,1,101,101,101,1,0,0,0,1,3,3,3,1,197,197,197,1,0, + 0,0,1,195,195,195,1,7,7,7,1,9,9,9,1,207,207,207,1,4, + 4,4,1,0,0,0,7,135,135,135,1,45,45,45,1,0,0,0,4,158, + 158,158,1,31,31,31,1,0,0,0,2,167,167,167,1,37,37,37,1,93, + 93,93,1,217,217,217,1,224,224,224,1,101,101,101,1,0,0,0,4,115, + 115,115,1,60,60,60,1,0,0,0,3,240,240,240,1,0,0,0,11,5, + 5,5,1,7,7,7,1,0,0,0,5,60,60,60,1,231,231,231,1,60, + 60,60,1,0,0,0,2,240,240,240,1,0,0,0,19,60,60,60,1,231, + 231,231,1,60,60,60,1,135,135,135,1,165,165,165,1,0,0,0,3,5, + 5,5,1,8,8,8,1,2,2,2,1,0,0,0,3,5,5,5,1,0, + 0,0,2,3,3,3,1,18,18,18,1,0,0,0,2,255,255,255,5,199, + 199,199,1,240,240,240,1,0,0,0,4,162,162,162,1,219,219,219,1,221, + 221,221,1,177,177,177,1,9,9,9,1,8,8,8,1,175,175,175,1,0, + 0,0,1,55,55,55,1,229,229,229,1,200,200,200,1,166,166,166,1,2, + 2,2,1,0,0,0,3,60,60,60,1,231,231,231,1,60,60,60,1,240, + 240,240,1,0,0,0,4,162,162,162,1,21,21,21,1,0,0,0,1,110, + 110,110,1,112,112,112,1,8,8,8,1,175,175,175,1,0,0,0,1,200, + 200,200,1,35,35,35,1,0,0,0,1,106,106,106,1,113,113,113,1,0, + 0,0,2,60,60,60,1,231,231,231,1,60,60,60,1,0,0,0,1,75, + 75,75,1,105,105,105,1,0,0,0,3,162,162,162,1,21,21,21,1,0, + 0,0,1,14,14,14,1,178,178,178,1,8,8,8,1,175,175,175,1,33, + 33,33,1,188,188,188,1,0,0,0,2,4,4,4,1,182,182,182,1,0, + 0,0,2,115,115,115,1,60,60,60,1,0,0,0,3,240,240,240,1,0, + 0,0,3,162,162,162,1,21,21,21,1,0,0,0,2,185,185,185,1,8, + 8,8,1,175,175,175,1,60,60,60,1,132,132,132,1,0,0,0,3,192, + 192,192,1,0,0,0,7,240,240,240,1,0,0,0,3,162,162,162,1,21, + 21,21,1,0,0,0,1,2,2,2,1,188,188,188,1,8,8,8,1,175, + 175,175,1,35,35,35,1,165,165,165,1,0,0,0,2,16,16,16,1,192, + 192,192,1,0,0,0,6,202,202,202,1,97,97,97,1,0,0,0,3,162, + 162,162,1,21,21,21,1,0,0,0,1,72,72,72,1,139,139,139,1,8, + 8,8,1,175,175,175,1,2,2,2,1,206,206,206,1,9,9,9,1,0, + 0,0,1,85,85,85,1,138,138,138,1,0,0,0,6,240,240,240,1,0, + 0,0,4,162,162,162,1,160,160,160,1,165,165,165,1,211,211,211,1,27, + 27,27,1,8,8,8,1,175,175,175,1,0,0,0,1,78,78,78,1,220, + 220,220,1,154,154,154,1,218,218,218,1,15,15,15,1,0,0,0,6,240, + 240,240,1,0,0,0,4,40,40,40,1,64,64,64,1,55,55,55,1,9, + 9,9,1,0,0,0,1,2,2,2,1,43,43,43,1,0,0,0,2,23, + 23,23,1,71,71,71,1,8,8,8,1,0,0,0,7,7,7,7,1,172, + 172,172,1,0,0,0,23,240,240,240,1,0,0,0,22,22,22,22,1,240, + 240,240,1,37,37,37,1,0,0,0,2,232,232,232,1,240,240,240,1,210, + 210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1,0, + 0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2,187, + 187,187,1,240,240,240,2,0,0) + ); + +initialization + registerobjectdata(@objdata_tfft,tbitmapcomp,'tfft'); + registerobjectdata(@objdata_tsigcontroller,tbitmapcomp,'tsigcontroller'); + registerobjectdata(@objdata_tsigadd,tbitmapcomp,'tsigadd'); + registerobjectdata(@objdata_tsigmult,tbitmapcomp,'tsigmult'); + registerobjectdata(@objdata_tsigdelay,tbitmapcomp,'tsigdelay'); + registerobjectdata(@objdata_tsigdelayn,tbitmapcomp,'tsigdelayn'); + registerobjectdata(@objdata_tsigdelayvar,tbitmapcomp,'tsigdelayvar'); + registerobjectdata(@objdata_tsigfir,tbitmapcomp,'tsigfir'); + registerobjectdata(@objdata_tsigiir,tbitmapcomp,'tsigiir'); + registerobjectdata(@objdata_tsigfft,tbitmapcomp,'tsigfft'); + registerobjectdata(@objdata_tsigin,tbitmapcomp,'tsigin'); + registerobjectdata(@objdata_tsigout,tbitmapcomp,'tsigout'); + registerobjectdata(@objdata_tsigconnector,tbitmapcomp,'tsigconnector'); + registerobjectdata(@objdata_ttrigconnector,tbitmapcomp,'ttrigconnector'); + registerobjectdata(@objdata_tsigwavetable,tbitmapcomp,'tsigwavetable'); + registerobjectdata(@objdata_tsigfuncttable,tbitmapcomp,'tsigfuncttable'); + registerobjectdata(@objdata_tsigenvelope,tbitmapcomp,'tsigenvelope'); + registerobjectdata(@objdata_tsigsampler,tbitmapcomp,'tsigsampler'); + registerobjectdata(@objdata_tsigsamplerfft,tbitmapcomp,'tsigsamplerfft'); + registerobjectdata(@objdata_tsigfilter,tbitmapcomp,'tsigfilter'); + registerobjectdata(@objdata_tsigfilterbank,tbitmapcomp,'tsigfilterbank'); + registerobjectdata(@objdata_tsigkeyboard,tbitmapcomp,'tsigkeyboard'); + registerobjectdata(@objdata_twavetableedit,tbitmapcomp,'twavetableedit'); + registerobjectdata(@objdata_tfuncttableedit,tbitmapcomp,'tfuncttableedit'); + registerobjectdata(@objdata_tffttableedit,tbitmapcomp,'tffttableedit'); + registerobjectdata(@objdata_tenvelopeedit,tbitmapcomp,'tenvelopeedit'); + registerobjectdata(@objdata_tsigscope,tbitmapcomp,'tsigscope'); + registerobjectdata(@objdata_tsigscopefft,tbitmapcomp,'tsigscopefft'); + registerobjectdata(@objdata_tsignoise,tbitmapcomp,'tsignoise'); + registerobjectdata(@objdata_tsigmidisource,tbitmapcomp,'tsigmidisource'); + registerobjectdata(@objdata_tsigmidiconnector,tbitmapcomp,'tsigmidiconnector'); + registerobjectdata(@objdata_tsigmidimulticonnector,tbitmapcomp,'tsigmidimulticonnector'); + registerobjectdata(@objdata_tsigoutaudio,tbitmapcomp,'tsigoutaudio'); + registerobjectdata(@objdata_tmidisource,tbitmapcomp,'tmidisource'); + registerobjectdata(@objdata_taudioout,tbitmapcomp,'taudioout'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regmm.pas b/mseide-msegui/lib/common/regcomponents/regmm.pas new file mode 100644 index 0000000..22e1622 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regmm.pas @@ -0,0 +1,33 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regmm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + mseaudio,msedesignintf,msesigaudio,msemidi,msesigmidi,msespeak; + +procedure register; +begin + registercomponents('MM',[taudioout,tmidisource,tespeakng]); + registercomponenttabhints(['MM'],['Multimedia components (experimental).']); + registercomponents('Math',[tsigoutaudio,tsigmidiconnector,tsigmidisource]); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regpascalscript.pas b/mseide-msegui/lib/common/regcomponents/regpascalscript.pas new file mode 100644 index 0000000..d32d339 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regpascalscript.pas @@ -0,0 +1,277 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regpascalscript; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + classes,mclasses,msedesignintf,msepascalscript,msepascimport, + msepropertyeditors,msetypes,msestrings, + msetexteditor,mseglob,mseguiglob,msegui,msewidgets,uPSComponent, + uPSComponent_Default, + msepascimportmsegui,formdesigner,sourceupdate,mseparser,pascaldesignparser, + msedesigner,mserichstring,mseclasses,msedesignparser; +type + tpascaleditor = class(ttextstringspropertyeditor) + protected + function getscript: tpasc; virtual; + function getsyntaxindex: integer; override; + procedure doafterclosequery(var amodalresult: modalresultty); override; + function gettestbutton: boolean; override; + function getcaption: msestring; override; + end; + + tpascformeditor = class(tpascaleditor) + private + fmoduleprefix: ansistring; + protected + function getscript: tpasc; override; + procedure doafterclosequery(var amodalresult: modalresultty); override; + procedure updateline(var aline: ansistring); override; + public + procedure edit; override; + end; + +function sourcetoformscript(const amodule: tmsecomponent; + const asource: trichstringdatalist): boolean; forward; +const + pascformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createpascform; + initnewcomponent: nil; getscale: nil; sourcetoform: @sourcetoformscript); + +procedure Register; +begin + registerclass(tpascform); + registercomponents('PaSc',[tpasc,tpascdllplugin,tpascimport_classes, + tpascimport_dateutils,tpascimportmsegui]); + registerpropertyeditor(typeinfo(tstrings),tpasc,'Script',tpascaleditor); + registerpropertyeditor(typeinfo(tstrings),tpascform,'pasc_script', + tpascformeditor); + registerdesignmoduleclass(tpascform,@pascformintf); + registercomponenttabhints(['PaSc'], + ['Experimental PascalScript Components']); +end; + +procedure doupdateline(aline: pchar; const moduleprefix: ansistring); +var //todo: patch PascalScript to accept classname + int1: integer; + po1,po2,po3: pchar; +begin //remove module prefix + if (moduleprefix <> '') and (aline <> nil) then begin + po1:= pchar(aline); + while po1^ <> #0 do begin + po2:= pchar(moduleprefix); + po3:= po1; + while (upperchars[po1^] = po2^) and (po1^ <> #0) do begin + inc(po1); + inc(po2); + end; + if po2^ = #0 then begin //found + for int1:= 0 to (po2 - pchar(moduleprefix)) - 1 do begin + po3[int1]:= ' '; + end; + end + else begin + po1:= po3+1; //next char + end; + end; + end; +end; + +function sourcetoformscript(const amodule: tmsecomponent; + const asource: trichstringdatalist): boolean; +var + bo1: boolean; + po1: punitinfoty; + po2: pmoduleinfoty; + mstr1: msestring; + start,stop: sourceposty; + prefix: ansistring; + int1: integer; +begin + bo1:= getimplementationtext(amodule,po1,start,stop,mstr1); + if bo1 then begin + po2:= designer.modules.findmodule(amodule); + prefix:= struppercase(po2^.moduleclassname)+'.'; + with tpascform(amodule).script.script do begin + text:= mstr1; + for int1:= 0 to count - 1 do begin + doupdateline(pchar(strings[int1]),prefix); + end; + end; + designer.componentmodified(amodule); + end; + result:= true; +end; + +var + pascalindex: integer = -1; +const + pascalsyntax = +'caseinsensitive'+lineend+ +'styles'+lineend+ +' default '''''+lineend+ +' words ''b'''+lineend+ +' comment ''i'' cl_dkblue'+lineend+ +' option ''b'' cl_dkblue'+lineend+ +' string '''' cl_dkblue'+lineend+ + +'keyworddefs pascal'+lineend+ +' ''ABSOLUTE'' ''ABSTRACT'' ''AND'' ''ARRAY'' ''AS'' ''ASM'' ''ASSEMBLER'' ''BEGIN'''+lineend+ +' ''BREAK'' ''CASE'' ''CDECL'' ''CLASS'' ''CONST'' ''CONSTRUCTOR'''+lineend+ +' ''CONTINUE'' ''DEFAULT'' ''DESTRUCTOR'' ''DISPOSE'' ''DIV'' ''DO'' ''DOWNTO'''+lineend+ +' ''ELSE'' ''END'' ''EXCEPT'' ''EXIT'' ''EXPORT'' ''EXPORTS'' ''EXTERNAL'' ''FAIL'''+lineend+ +' ''FALSE'' ''FAR'' ''FILE'' ''FINALIZATION'' ''FINALLY'' ''FOR'' ''FORWARD'' ''FUNCTION'' ''GOTO'' ''IF'''+lineend+ +' ''IMPLEMENTATION'' ''IN'' ''INDEX'' ''INHERITED'''+lineend+ +' ''INITIALIZATION'' ''INLINE'' ''INTERFACE'' ''INTERRUPT'' ''IS'' ''LABEL'' ''LIBRARY'''+lineend+ +' ''MOD'' ''NEW'' ''NIL'' ''NODEFAULT'' ''NOT'' ''OBJECT'''+lineend+ +' ''OF'' ''ON'' ''OPERATOR'' ''OR'' ''OUT'' ''OTHERWISE'' ''PACKED'' ''POPSTACK'' ''PRIVATE'' '+lineend+ +' ''PROCEDURE'' ''PROGRAM'' ''PROPERTY'' ''PROTECTED'''+lineend+ +' ''PUBLIC'' ''PUBLISHED'' ''RAISE'' ''READ'' ''RECORD'' ''REINTRODUCE'' ''REPEAT'' '+lineend+ +' ''RESOURCESTRING'''+lineend+ +' ''SELF'' ''SET'' ''SHL'' ''SHR'''+lineend+ +' ''STDCALL'' ''STORED'' ''THEN'' ''THREADVAR'' ''TO'' ''TRUE'' ''TRY'' ''TYPE'' ''UNIT'' ''UNTIL'''+lineend+ +' ''USES'' ''VAR'' ''VIRTUAL'' ''WHILE'' ''WITH'' ''WRITE'' ''XOR'''+lineend+ +' ''OVERLOAD'' ''OVERRIDE'''+lineend+ + +'scope option option'+lineend+ +' endtokens'+lineend+ +' ''}'''+lineend+ + +'scope comment1 comment'+lineend+ +' endtokens'+lineend+ +' ''}'''+lineend+ + +'scope comment2 comment'+lineend+ +' endtokens'+lineend+ +' '''''+lineend+ + +'scope comment3 comment'+lineend+ +' endtokens'+lineend+ +' ''*)'''+lineend+ + +'scope string string'+lineend+ +' endtokens'+lineend+ +' '''''''' '''''+lineend+ + +'scope string1 string'+lineend+ +' calltokens'+lineend+ +' '''''''' string'+lineend+ +' endtokens'+lineend+ +' '' '' '''''+lineend+ + +'scope main'+lineend+ + +' keywords words'+lineend+ +' pascal'+lineend+ + +' calltokens'+lineend+ +' ''{$'' option'+lineend+ +' ''{'' comment1'+lineend+ +' ''//'' comment2'+lineend+ +' ''(*'' comment3'+lineend+ +' '''''''' string'+lineend+ +' ''#'' string1'; + + +{ tpascaleditor } + +function tpascaleditor.getscript: tpasc; +begin + result:= tpasc(getordvalue(0)); +end; + +procedure tpascaleditor.doafterclosequery(var amodalresult: modalresultty); +begin + if amodalresult = mr_canclose then begin + with getscript do begin + if compile then begin +// showmessage('Compile OK'); + end + else begin + showmessage(compilermessagetext,'Compile Error'); + amodalresult:= mr_none; + end; + end; + end; +end; + +function tpascaleditor.gettestbutton: boolean; +begin + result:= true; +end; + +function tpascaleditor.getcaption: msestring; +begin + result:= 'PascalScript Editor'; +end; + +function tpascaleditor.getsyntaxindex: integer; +begin + if pascalindex < 0 then begin + pascalindex:= msetexteditor.syntaxpainter.readdeffile(pascalsyntax); + end; + result:= pascalindex; +end; + +{ tpascformeditor } + +function tpascformeditor.getscript: tpasc; +begin + result:= tpascform(component).script; +end; + +procedure tpascformeditor.edit; +var + bo1: boolean; + po1: punitinfoty; + po2: pmoduleinfoty; + mstr1: msestring; + start,stop: sourceposty; +begin + bo1:= getimplementationtext(fmodule,po1,start,stop,mstr1); + if bo1 then begin + po2:= designer.modules.findmodule(fmodule); + fmoduleprefix:= struppercase(po2^.moduleclassname)+'.'; + getscript.script.text:= mstr1; + end + else begin + fmoduleprefix:= ''; + end; + inherited; + if bo1 and (fmodalresult = mr_ok) then begin + sourceupdater.replacetext(po1,start,stop, + concatstrings(forigtext,msestring(lineend))+lineend); + end; +end; + +procedure tpascformeditor.doafterclosequery(var amodalresult: modalresultty); +begin + if amodalresult in [mr_canclose,mr_ok] then begin + end; + inherited; +end; + +procedure tpascformeditor.updateline(var aline: ansistring); + //todo: patch PascalScript to accept classname +begin + doupdateline(pchar(aline),fmoduleprefix); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regprinter.pas b/mseide-msegui/lib/common/regcomponents/regprinter.pas new file mode 100644 index 0000000..501d441 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regprinter.pas @@ -0,0 +1,32 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regprinter; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + mseprinter,msepostscriptprinter,msegdiprint,msedesignintf; + +procedure Register; +begin + registercomponents('Gui',[tpostscriptprinter,tgdiprinter,twmfprinter]); + registercomponents('Dialog',[tpagesizeselector,tpageorientationselector]); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regreport.pas b/mseide-msegui/lib/common/regcomponents/regreport.pas new file mode 100644 index 0000000..9c816b5 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regreport.pas @@ -0,0 +1,182 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regreport; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +implementation +uses + classes,mclasses,msereport,msedesignintf,formdesigner,reportdesigner, + msepropertyeditors,mseformatstr,mserepps,msedrawtext, + sysutils,msetypes{msestrings},regreport_bmp,regdb,mselookupbuffer; +const + reportintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createreport; + initnewcomponent: {$ifdef FPC}@{$endif}initreportcomponent; + getscale: {$ifdef FPC}@{$endif}getreportscale; + sourcetoform: nil); + reppageformintf: designmoduleintfty = + (createfunc: @createreppageform; + initnewcomponent: nil; + getscale: @getreppageformscale; + sourcetoform: nil); + +type + treptabulators1 = class(treptabulators); + treptabulatoritem1 = class(treptabulatoritem); + + treptabulatoreditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + treptabulatorseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + procedure itemfocused(const sender: tarrayelementeditor) override; + procedure resetactivetab(); + public + destructor destroy(); override; + end; + +procedure Register; +begin + registerclass(treport); + registerclass(treportpage); + registerclass(treppageform); + registercomponents('Rep',[treportpage,tbandarea,ttilearea,tbandgroup, + trecordband, + trepvaluedisp,treppagenumdisp,trepprintdatedisp, + {trepstringdisplb,trepintegerdisplb,treprealdisplb, + trepdatetimedisplb,} + trepspacer,treppsdisp]); + registercomponenttabhints(['Rep'],['Report components']); + + registerdesignmoduleclass(treport,@reportintf,treportdesignerfo); + registerdesignmoduleclass(treppageform,@reppageformintf,treportdesignerfo); + registerpropertyeditor(typeinfo(treptabulators),nil,'',treptabulatorseditor); + registerpropertyeditor(typeinfo(tcustomrecordband),treptabulators,'linksource', + tlocallinkcomponentpropertyeditor); +// registerpropertyeditor(typeinfo(string),tcustomreplookupdisp,'keydatafield', +// tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tcustomrecordband,'visidatafield', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tcustomrecordband,'visigroupfield', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(tcustomrecordband),tcustomrecordband,'nextband', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(tcustomrecordband),tcustomrecordband,'nextbandifempty', + tsisterwidgetpropertyeditor); +end; + +{ treptabulatoreditor } + +function treptabulatoreditor.getvalue: msestring; +var + mstr1: msestring; +begin + with treptabulatoritem(getpointervalue) do begin + if datafield = '' then begin + if ifilink <> nil then begin + mstr1:= msestring(ifilink.name); + end + else begin + mstr1:= value; + end; + end + else begin + mstr1:= ''; + if datasource <> nil then begin + mstr1:= msestring(datasource.name+'.'); + end; + mstr1:= mstr1+msestring(datafield); + if (lookupbuffer <> nil) and (lookupbuffer is tdblookupbuffer) and + (lookupvaluefieldno >= 0) then begin + with tdblookupbuffer(lookupbuffer) do begin + case lookupkind of + lk_text: begin + if lookupvaluefieldno < lookupbuffer.fieldcounttext then begin + mstr1:= mstr1+'><'+msestring(textfields[lookupvaluefieldno]); + end; + end; + lk_integer: begin + if lookupvaluefieldno < lookupbuffer.fieldcountinteger then begin + mstr1:= mstr1+'><'+msestring(integerfields[lookupvaluefieldno]); + end; + end; + lk_float,lk_date,lk_time,lk_datetime: begin + if lookupvaluefieldno < lookupbuffer.fieldcountfloat then begin + mstr1:= mstr1+'><'+msestring(floatfields[lookupvaluefieldno]); + end; + end; + end; + end; + end; + end; + result:= '<'+formatfloatmse(pos,'0.0')+'><'+mstr1+'>'; + end; +end; + +{ treptabulatorseditor } + +destructor treptabulatorseditor.destroy(); +begin + resetactivetab(); + inherited; +end; + +procedure treptabulatorseditor.resetactivetab(); +var + i1,i2: int32; + p1: treptabulators1; +begin + for i1:= 0 to high(fprops) do begin + p1:= treptabulators1(getpointervalue(i1)); + for i2:= 0 to p1.count - 1 do begin + with treptabulatoritem1(p1.fitems[i2]) do begin + exclude(fstate,tas_editactive); + end; + end; + p1.fband.invalidate(); + end; +end; + +function treptabulatorseditor.geteditorclass: propertyeditorclassty; +begin + result:= treptabulatoreditor; +end; + +procedure treptabulatorseditor.itemfocused(const sender: tarrayelementeditor); +var + i1: int32; + p1: treptabulators1; +begin + resetactivetab(); + for i1:= 0 to high(fprops) do begin + p1:= treptabulators1(getpointervalue(i1)); + if p1.count > sender.index then begin + with treptabulatoritem1(p1.fitems[sender.index]) do begin + include(fstate,tas_editactive); + end; + end; + end; + inherited; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regreport_bmp.pas b/mseide-msegui/lib/common/regcomponents/regreport_bmp.pas new file mode 100644 index 0000000..139eeb8 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regreport_bmp.pas @@ -0,0 +1,387 @@ +unit regreport_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_treportpage: record size: integer; data: array[0..1730] of byte end = + (size: 1731; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,114,101, + 112,111,114,116,112,97,103,101,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,76,6,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,24,5,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,14,14,14,1,15,15,15,1,45,45,45, + 1,255,255,255,2,195,195,195,1,15,15,15,2,105,105,105,1,255,255,255, + 2,135,135,135,1,15,15,15,2,165,165,165,1,255,255,255,2,68,68,68, + 1,15,15,15,2,233,233,233,1,255,255,255,1,248,248,248,1,15,15,15, + 1,200,200,200,1,255,255,255,22,15,15,15,1,255,255,255,23,53,53,53, + 1,255,255,255,3,245,245,245,1,135,135,135,2,137,137,137,1,163,163,163, + 1,238,238,238,1,255,255,255,1,189,189,189,1,135,135,135,4,244,244,244, + 1,189,189,189,1,135,135,135,1,136,136,136,1,146,146,146,1,216,216,216, + 1,255,255,255,3,36,36,36,1,255,255,255,2,234,234,234,1,46,46,46, + 1,191,191,191,1,190,190,190,1,139,139,139,1,52,52,52,1,255,255,255, + 1,113,113,113,1,125,125,125,1,175,175,175,3,248,248,248,1,113,113,113, + 1,119,119,119,1,175,175,175,1,165,165,165,1,39,39,39,1,221,221,221, + 1,255,255,255,2,14,14,14,1,255,255,255,2,234,234,234,1,61,61,61, + 1,255,255,255,2,253,253,253,1,37,37,37,1,251,251,251,1,113,113,113, + 1,182,182,182,1,255,255,255,4,113,113,113,1,174,174,174,1,255,255,255, + 2,105,105,105,1,180,180,180,1,255,255,255,1,180,180,180,1,28,28,28, + 1,255,255,255,2,234,234,234,1,23,23,23,1,95,95,95,1,93,93,93, + 1,72,72,72,1,146,146,146,1,255,255,255,1,113,113,113,1,51,51,51, + 1,71,71,71,2,94,94,94,1,255,255,255,1,113,113,113,1,103,103,103, + 1,151,151,151,1,120,120,120,1,48,48,48,1,247,247,247,1,255,255,255, + 1,15,15,15,1,255,255,255,3,234,234,234,1,53,53,53,1,223,223,223, + 1,172,172,172,1,67,67,67,1,244,244,244,1,255,255,255,1,113,113,113, + 1,177,177,177,1,247,247,247,2,248,248,248,1,255,255,255,1,113,113,113, + 1,109,109,109,1,160,160,160,1,200,200,200,1,254,254,254,1,255,255,255, + 2,15,15,15,1,255,255,255,3,234,234,234,1,61,61,61,1,255,255,255, + 2,142,142,142,1,93,93,93,1,255,255,255,1,113,113,113,1,182,182,182, + 1,255,255,255,4,113,113,113,1,174,174,174,1,255,255,255,5,120,120,120, + 1,208,208,208,1,255,255,255,2,234,234,234,1,61,61,61,1,255,255,255, + 2,253,253,253,1,57,57,57,1,183,183,183,1,113,113,113,1,45,45,45, + 1,63,63,63,3,207,207,207,1,113,113,113,1,174,174,174,1,255,255,255, + 6,14,14,14,1,255,255,255,23,14,14,14,1,255,255,255,22,120,120,120, + 1,87,87,87,1,255,255,255,2,249,249,249,1,199,199,199,2,203,203,203, + 1,234,234,234,1,255,255,255,2,254,254,254,1,200,200,200,1,255,255,255, + 5,221,221,221,1,189,189,189,1,233,233,233,1,255,255,255,3,15,15,15, + 1,255,255,255,3,226,226,226,1,26,26,26,1,111,111,111,1,110,110,110, + 1,52,52,52,1,159,159,159,1,255,255,255,1,192,192,192,1,22,22,22, + 1,190,190,190,1,255,255,255,2,245,245,245,1,68,68,68,1,107,107,107, + 1,137,137,137,1,60,60,60,1,167,167,167,1,255,255,255,2,15,15,15, + 1,255,255,255,3,226,226,226,1,61,61,61,1,255,255,255,2,218,218,218, + 1,63,63,63,1,255,255,255,1,95,95,95,1,167,167,167,1,86,86,86, + 1,255,255,255,2,113,113,113,1,166,166,166,1,255,255,255,2,244,244,244, + 1,107,107,107,1,255,255,255,2,180,180,180,1,146,146,146,1,255,255,255, + 2,226,226,226,1,51,51,51,1,215,215,215,1,205,205,205,1,113,113,113, + 1,127,127,127,1,242,242,242,1,58,58,58,1,255,255,255,1,53,53,53, + 1,232,232,232,1,255,255,255,1,49,49,49,1,239,239,239,1,255,255,255, + 1,249,249,249,1,244,244,244,1,241,241,241,1,255,255,255,3,14,14,14, + 1,255,255,255,2,226,226,226,1,23,23,23,1,95,95,95,1,109,109,109, + 1,179,179,179,1,247,247,247,1,155,155,155,1,73,73,73,1,151,151,151, + 1,73,73,73,1,134,134,134,1,255,255,255,1,42,42,42,1,238,238,238, + 1,255,255,255,1,129,129,129,1,71,71,71,1,15,15,15,1,240,240,240, + 1,255,255,255,2,14,14,14,1,255,255,255,2,226,226,226,1,61,61,61, + 1,255,255,255,4,61,61,61,1,175,175,175,1,183,183,183,1,178,178,178, + 1,39,39,39,1,253,253,253,1,107,107,107,1,156,156,156,1,255,255,255, + 3,53,53,53,1,240,240,240,1,255,255,255,1,53,53,53,1,154,154,154, + 1,255,255,255,2,226,226,226,1,61,61,61,1,255,255,255,3,215,215,215, + 1,70,70,70,1,255,255,255,3,85,85,85,1,182,182,182,1,243,243,243, + 1,65,65,65,1,100,100,100,1,137,137,137,1,74,74,74,1,86,86,86, + 1,250,250,250,1,255,255,255,1,15,15,15,1,255,255,255,3,248,248,248, + 1,207,207,207,1,255,255,255,3,230,230,230,1,223,223,223,1,255,255,255, + 3,228,228,228,1,221,221,221,1,255,255,255,1,254,254,254,1,212,212,212, + 1,174,174,174,1,221,221,221,1,255,255,255,3,15,15,15,1,255,255,255, + 23,248,248,248,1,80,80,80,1,255,255,255,23,14,14,14,1,255,255,255, + 22,233,233,233,1,14,14,14,1,217,217,217,1,255,255,255,2,22,22,22, + 1,15,15,15,1,44,44,44,1,255,255,255,2,194,194,194,1,15,15,15, + 2,103,103,103,1,255,255,255,2,133,133,133,1,15,15,15,2,163,163,163, + 1,255,255,255,2,67,67,67,1,15,15,15,2,252,0,0,0,254,254,254, + 1,255,255,255,23,243,243,243,1,255,255,255,23,240,240,240,1,255,255,255, + 23,240,240,240,1,255,255,255,23,253,253,253,1,255,255,255,23,254,254,254, + 1,255,255,255,23,253,253,253,1,255,255,255,23,240,240,240,1,255,255,255, + 23,240,240,240,1,255,255,255,23,243,243,243,1,255,255,255,23,254,254,254, + 1,255,255,255,23,254,254,254,1,255,255,255,23,250,250,250,1,255,255,255, + 23,240,240,240,1,255,255,255,23,240,240,240,1,255,255,255,23,246,246,246, + 1,255,255,255,23,254,254,254,1,255,255,255,23,254,254,254,1,255,255,255, + 23,246,246,246,1,255,255,255,23,240,240,240,1,255,255,255,23,240,240,240, + 1,255,255,255,23,250,250,250,1,255,255,255,23,254,254,254,1,255,255,255, + 23,254,254,254,1,249,249,249,1,248,248,248,2,254,254,254,1,255,255,255, + 1,254,254,254,1,248,248,248,2,250,250,250,1,255,255,255,2,252,252,252, + 1,248,248,248,2,251,251,251,1,255,255,255,2,250,250,250,1,248,248,248, + 2,253,253,253,1,255,255,255,2,0,0) + ); + +const + objdata_tbandarea: record size: integer; data: array[0..445] of byte end = + (size: 446; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,98,97, + 110,100,97,114,101,97,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 144,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 92,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,50, + 0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2, + 255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1, + 0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1, + 255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,1,143,143,143,18, + 255,255,255,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1, + 255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1,255,0,255,4, + 255,255,255,1,143,143,143,18,255,255,255,1,255,0,255,4,255,255,255,20, + 255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1,255,0,255,4, + 0,0,0,1,143,143,143,18,0,0,0,1,255,0,255,4,255,255,255,20, + 255,0,255,4,255,255,255,20,255,0,255,4,0,0,0,1,143,143,143,18, + 0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1, + 255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,1,143,143,143,18, + 255,255,255,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1, + 255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1,255,0,255,4, + 255,255,255,1,143,143,143,18,255,255,255,1,255,0,255,4,255,255,255,1, + 0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2, + 255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1, + 255,0,255,50,0,0) + ); + +const + objdata_ttilearea: record size: integer; data: array[0..561] of byte end = + (size: 562; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,116,105, + 108,101,97,114,101,97,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 4,2,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 208,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,50, + 0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,1, + 30,30,30,1,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2, + 255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9, + 143,143,143,1,255,255,255,8,0,0,0,1,255,0,255,4,255,255,255,10, + 143,143,143,1,255,255,255,9,255,0,255,4,255,255,255,10,143,143,143,1, + 255,255,255,9,255,0,255,4,0,0,0,1,255,255,255,9,143,143,143,1, + 255,255,255,8,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9, + 143,143,143,1,255,255,255,8,0,0,0,1,255,0,255,4,255,255,255,10, + 143,143,143,1,255,255,255,9,255,0,255,4,255,255,255,1,143,143,143,18, + 255,255,255,1,255,0,255,4,0,0,0,1,255,255,255,9,143,143,143,1, + 255,255,255,8,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9, + 143,143,143,1,255,255,255,8,0,0,0,1,255,0,255,4,255,255,255,10, + 143,143,143,1,255,255,255,9,255,0,255,4,255,255,255,10,143,143,143,1, + 255,255,255,9,255,0,255,4,0,0,0,1,255,255,255,9,143,143,143,1, + 255,255,255,8,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9, + 143,143,143,1,255,255,255,8,0,0,0,1,255,0,255,4,255,255,255,1, + 143,143,143,18,255,255,255,1,255,0,255,4,255,255,255,10,143,143,143,1, + 255,255,255,9,255,0,255,4,0,0,0,1,255,255,255,9,143,143,143,1, + 255,255,255,8,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9, + 143,143,143,1,255,255,255,8,0,0,0,1,255,0,255,4,255,255,255,10, + 143,143,143,1,255,255,255,9,255,0,255,4,255,255,255,1,0,0,0,2, + 255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2, + 0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1,255,0,255,50, + 0,0) + ); + +const + objdata_tbandgroup: record size: integer; data: array[0..338] of byte end = + (size: 339; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,98,97, + 110,100,103,114,111,117,112,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,36,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255, + 50,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 1,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0, + 1,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,20,255,0,255, + 4,0,0,0,1,255,255,255,18,0,0,0,1,255,0,255,4,0,0,0, + 3,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,2,0,0,0,3,255,0,255,4,255,255,255, + 20,255,0,255,4,255,255,255,20,255,0,255,4,0,0,0,1,255,255,255, + 18,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0, + 1,255,0,255,4,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,1,255,0,255,255,255,0,255,11,0,0) + ); + +const + objdata_trecordband: record size: integer; data: array[0..243] of byte end = + (size: 244; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,114,101, + 99,111,114,100,98,97,110,100,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,196,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0, + 255,50,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,1,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0, + 0,1,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,20,255,0, + 255,4,0,0,0,1,255,255,255,18,0,0,0,1,255,0,255,4,0,0, + 0,3,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,2,0,0,0,2,255,255,255,2,0,0,0,3,255,0,255,255,255,0, + 255,131,0,0) + ); + +const + objdata_trepvaluedisp: record size: integer; data: array[0..193] of byte end = + (size: 194; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,114,101, + 112,118,97,108,117,101,100,105,115,112,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,144,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,92,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,255,146,255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4, + 255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,20, + 255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4, + 255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,20, + 255,0,255,4,255,255,255,20,255,0,255,170,0,0) + ); + +const + objdata_treppagenumdisp: record size: integer; data: array[0..595] of byte end = + (size: 596; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,114,101, + 112,112,97,103,101,110,117,109,100,105,115,112,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,32,2,0,0,0,0,0,0,0,0,0,0,24,0, + 0,0,24,0,0,0,236,1,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,0,255,146,255,255,255,20,255,0,255,4,255,255,255,2,215,215, + 215,1,0,0,0,1,3,3,3,1,4,4,4,1,24,24,24,1,106,106, + 106,1,244,244,244,1,255,255,255,4,105,105,105,1,218,218,218,1,173,173, + 173,1,149,149,149,1,255,255,255,3,255,0,255,4,255,255,255,2,215,215, + 215,1,3,3,3,1,255,255,255,2,222,222,222,1,68,68,68,1,94,94, + 94,1,255,255,255,4,68,68,68,1,255,255,255,1,98,98,98,1,225,225, + 225,1,255,255,255,3,255,0,255,4,255,255,255,2,215,215,215,1,3,3, + 3,1,255,255,255,3,199,199,199,1,18,18,18,1,255,255,255,2,3,3, + 3,1,2,2,2,2,3,3,3,1,1,1,1,1,3,3,3,2,255,255, + 255,2,255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1,255,255, + 255,3,190,190,190,1,28,28,28,1,255,255,255,3,168,168,168,1,155,155, + 155,1,243,243,243,1,84,84,84,1,255,255,255,4,255,0,255,4,255,255, + 255,2,215,215,215,1,3,3,3,1,255,255,255,1,253,253,253,1,210,210, + 210,1,50,50,50,1,127,127,127,1,255,255,255,3,125,125,125,1,200,200, + 200,1,199,199,199,1,126,126,126,1,255,255,255,4,255,0,255,4,255,255, + 255,2,215,215,215,1,0,0,0,1,7,7,7,1,8,8,8,1,35,35, + 35,1,132,132,132,1,253,253,253,1,255,255,255,3,83,83,83,1,243,243, + 243,1,154,154,154,1,169,169,169,1,255,255,255,4,255,0,255,4,255,255, + 255,2,215,215,215,1,3,3,3,1,255,255,255,6,7,7,7,2,2,2, + 2,1,7,7,7,1,3,3,3,1,6,6,6,1,7,7,7,1,255,255, + 255,3,255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1,255,255, + 255,7,224,224,224,1,99,99,99,1,255,255,255,1,68,68,68,1,255,255, + 255,5,255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1,255,255, + 255,7,149,149,149,1,174,174,174,1,221,221,221,1,102,102,102,1,255,255, + 255,5,255,0,255,4,255,255,255,20,255,0,255,170,0,0) + ); + +const + objdata_trepprintdatedisp: record size: integer; data: array[0..565] of byte end = + (size: 566; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,114,101, + 112,112,114,105,110,116,100,97,116,101,100,105,115,112,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,0,2,0,0,0,0,0,0,0,0,0,0, + 24,0,0,0,24,0,0,0,204,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,255,146,255,255,255,20,255,0,255,4,255,255,255,2, + 215,215,215,1,0,0,0,1,4,4,4,1,5,5,5,1,27,27,27,1, + 96,96,96,1,224,224,224,1,255,255,255,2,3,3,3,3,0,0,0,1, + 3,3,3,3,255,255,255,2,255,0,255,4,255,255,255,2,215,215,215,1, + 3,3,3,1,255,255,255,1,253,253,253,1,217,217,217,1,103,103,103,1, + 25,25,25,1,231,231,231,1,255,255,255,3,215,215,215,1,7,7,7,1, + 255,255,255,5,255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1, + 255,255,255,4,89,89,89,1,105,105,105,1,255,255,255,3,215,215,215,1, + 7,7,7,1,255,255,255,5,255,0,255,4,255,255,255,2,215,215,215,1, + 3,3,3,1,255,255,255,4,184,184,184,1,34,34,34,1,255,255,255,3, + 215,215,215,1,7,7,7,1,255,255,255,5,255,0,255,4,255,255,255,2, + 215,215,215,1,3,3,3,1,255,255,255,4,210,210,210,1,12,12,12,1, + 255,255,255,3,215,215,215,1,7,7,7,1,255,255,255,5,255,0,255,4, + 255,255,255,2,215,215,215,1,3,3,3,1,255,255,255,4,187,187,187,1, + 36,36,36,1,255,255,255,3,215,215,215,1,7,7,7,1,255,255,255,5, + 255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1,255,255,255,4, + 95,95,95,1,117,117,117,1,255,255,255,3,215,215,215,1,7,7,7,1, + 255,255,255,5,255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1, + 255,255,255,1,253,253,253,1,220,220,220,1,107,107,107,1,37,37,37,1, + 241,241,241,1,255,255,255,3,215,215,215,1,7,7,7,1,255,255,255,5, + 255,0,255,4,255,255,255,2,215,215,215,1,0,0,0,1,3,3,3,1, + 5,5,5,1,30,30,30,1,105,105,105,1,234,234,234,1,255,255,255,4, + 215,215,215,1,7,7,7,1,255,255,255,5,255,0,255,4,255,255,255,20, + 255,0,255,170,0,0) + ); + +const + objdata_trepspacer: record size: integer; data: array[0..526] of byte end = + (size: 527; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,114,101, + 112,115,112,97,99,101,114,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,224,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,172,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255, + 50,255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255, + 20,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,3,0,0,0, + 1,255,255,255,11,0,0,0,1,255,255,255,4,255,0,255,4,255,255,255, + 3,0,0,0,1,255,255,255,11,0,0,0,1,255,255,255,4,255,0,255, + 4,255,255,255,3,0,0,0,1,255,255,255,11,0,0,0,1,255,255,255, + 4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255,11,0,0,0, + 1,255,255,255,4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255, + 3,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0, + 1,255,255,255,4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255, + 1,0,0,0,3,255,255,255,3,0,0,0,3,255,255,255,1,0,0,0, + 1,255,255,255,4,255,0,255,4,255,255,255,3,0,0,0,13,255,255,255, + 4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255,1,0,0,0, + 3,255,255,255,3,0,0,0,3,255,255,255,1,0,0,0,1,255,255,255, + 4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0, + 1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255, + 4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255,11,0,0,0, + 1,255,255,255,4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255, + 11,0,0,0,1,255,255,255,4,255,0,255,4,255,255,255,3,0,0,0, + 1,255,255,255,11,0,0,0,1,255,255,255,4,255,0,255,4,255,255,255, + 3,0,0,0,1,255,255,255,11,0,0,0,1,255,255,255,4,255,0,255, + 4,255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255, + 20,255,0,255,50,0,0) + ); + +const + objdata_treppsdisp: record size: integer; data: array[0..1017] of byte end = + (size: 1018; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,114,101, + 112,112,115,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,132,3,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,168,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,50,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,2,252,252,252,1, + 85,85,85,3,88,88,88,1,123,123,123,1,230,230,230,1,255,255,255,2, + 238,238,238,1,121,121,121,1,61,61,61,1,60,60,60,1,132,132,132,1, + 246,246,246,1,255,255,255,3,0,0,0,4,255,255,255,2,250,250,250,1, + 0,0,0,1,152,152,152,1,187,187,187,1,176,176,176,1,98,98,98,1, + 21,21,21,1,230,230,230,1,255,255,255,1,57,57,57,1,83,83,83,1, + 196,196,196,1,190,190,190,1,64,64,64,1,79,79,79,1,255,255,255,3, + 0,0,0,4,255,255,255,2,250,250,250,1,0,0,0,1,207,207,207,1, + 255,255,255,3,55,55,55,1,141,141,141,1,227,227,227,1,0,0,0,1, + 228,228,228,1,255,255,255,2,222,222,222,1,17,17,17,1,231,231,231,1, + 255,255,255,2,0,0,0,4,255,255,255,2,250,250,250,1,0,0,0,1, + 207,207,207,1,255,255,255,3,72,72,72,1,130,130,130,1,248,248,248,1, + 20,20,20,1,125,125,125,1,251,251,251,1,255,255,255,6,0,0,0,4, + 255,255,255,2,250,250,250,1,0,0,0,1,180,180,180,1,221,221,221,1, + 216,216,216,1,151,151,151,1,8,8,8,1,207,207,207,1,255,255,255,1, + 197,197,197,1,37,37,37,1,24,24,24,1,114,114,114,1,215,215,215,1, + 255,255,255,4,0,0,0,4,255,255,255,2,250,250,250,1,0,0,0,1, + 28,28,28,1,34,34,34,1,40,40,40,1,77,77,77,1,189,189,189,1, + 255,255,255,3,253,253,253,1,188,188,188,1,97,97,97,1,8,8,8,1, + 128,128,128,1,255,255,255,3,0,0,0,4,255,255,255,2,250,250,250,1, + 0,0,0,1,207,207,207,1,255,255,255,5,232,232,232,1,215,215,215,1, + 255,255,255,3,194,194,194,1,2,2,2,1,231,231,231,1,255,255,255,2, + 0,0,0,4,255,255,255,2,250,250,250,1,0,0,0,1,207,207,207,1, + 255,255,255,5,173,173,173,1,21,21,21,1,243,243,243,1,255,255,255,2, + 224,224,224,1,0,0,0,1,227,227,227,1,255,255,255,2,0,0,0,4, + 255,255,255,2,250,250,250,1,0,0,0,1,207,207,207,1,255,255,255,5, + 251,251,251,1,74,74,74,1,45,45,45,1,134,134,134,1,136,136,136,1, + 42,42,42,1,87,87,87,1,255,255,255,3,0,0,0,4,255,255,255,2, + 253,253,253,1,136,136,136,1,233,233,233,1,255,255,255,6,254,254,254,1, + 181,181,181,1,121,121,121,1,124,124,124,1,179,179,179,1,254,254,254,1, + 255,255,255,3,0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,50,164,0,0,0,0,0,0,50,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,50,0,0) + ); + +initialization + registerobjectdata(@objdata_treportpage,tbitmapcomp,'treportpage'); + registerobjectdata(@objdata_tbandarea,tbitmapcomp,'tbandarea'); + registerobjectdata(@objdata_ttilearea,tbitmapcomp,'ttilearea'); + registerobjectdata(@objdata_tbandgroup,tbitmapcomp,'tbandgroup'); + registerobjectdata(@objdata_trecordband,tbitmapcomp,'trecordband'); + registerobjectdata(@objdata_trepvaluedisp,tbitmapcomp,'trepvaluedisp'); + registerobjectdata(@objdata_treppagenumdisp,tbitmapcomp,'treppagenumdisp'); + registerobjectdata(@objdata_trepprintdatedisp,tbitmapcomp,'trepprintdatedisp'); + registerobjectdata(@objdata_trepspacer,tbitmapcomp,'trepspacer'); + registerobjectdata(@objdata_treppsdisp,tbitmapcomp,'treppsdisp'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regserialcomm.pas b/mseide-msegui/lib/common/regcomponents/regserialcomm.pas new file mode 100644 index 0000000..6a46bb7 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regserialcomm.pas @@ -0,0 +1,37 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regserialcomm; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + Classes,msecommport,msecommutils,msesercomm,msedesignintf,regserialcomm_bmp; + +procedure Register; +begin + registercomponents('Comm',[tcommport,tasciicommport,tasciiprotport, + tsercommcomp,tsercommchannel,tasynsercommchannel, + tcommselector]); + registercomponenttabhints(['Comm'],['Components for serial port (RS232)']); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regserialcomm_bmp.pas b/mseide-msegui/lib/common/regcomponents/regserialcomm_bmp.pas new file mode 100644 index 0000000..4c8cdc5 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regserialcomm_bmp.pas @@ -0,0 +1,721 @@ +unit regserialcomm_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tcommport: record size: integer; data: array[0..1952] of byte end = + (size: 1953; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,99,111, + 109,109,112,111,114,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,44,7,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,244,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,208,208,208,73,0,0,0,4,208,208,208,1,0, + 0,0,4,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,5,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,13,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,2,0,0,0,4,208,208,208,1,0,0,0,5,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,4,0,0,0,1,208,208,208,3,0,0,0,10,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,1,208, + 208,208,1,0,0,0,1,208,208,208,3,0,0,0,13,208,208,208,1,0, + 0,0,2,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,14,208, + 208,208,2,0,0,0,4,208,208,208,1,0,0,0,9,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,3,208,208,208,1,0,0,0,4,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,1,208,208,208,51,0,0,0,4,208, + 208,208,2,0,0,0,3,208,208,208,1,0,0,0,10,208,208,208,4,0, + 0,0,20,208,208,208,4,0,0,0,2,208,208,208,1,0,0,0,4,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,5,0,0,0,7,208,208,208,2,0,0,0,6,208, + 208,208,2,0,0,0,2,208,208,208,5,0,0,0,4,208,208,208,1,0, + 0,0,1,208,208,208,3,0,0,0,6,208,208,208,2,0,0,0,2,208, + 208,208,5,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0, + 0,0,4,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208, + 208,208,5,0,0,0,2,208,208,208,3,0,0,0,7,208,208,208,1,0, + 0,0,3,208,208,208,1,0,0,0,2,208,208,208,5,0,0,0,2,208, + 208,208,4,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,75,0,5,0,0,0,0,0,73,24,24,24,1,168, + 168,168,1,193,193,193,1,68,68,68,1,0,0,0,1,4,4,4,1,147, + 147,147,1,209,209,209,1,122,122,122,1,0,0,0,1,37,37,37,1,186, + 186,186,1,0,0,0,2,50,50,50,1,156,156,156,1,27,27,27,1,193, + 193,193,1,3,3,3,1,0,0,0,1,40,40,40,1,166,166,166,1,0, + 0,0,2,172,172,172,1,61,61,61,1,21,21,21,1,189,189,189,1,7, + 7,7,1,121,121,121,1,137,137,137,1,15,15,15,1,134,134,134,1,91, + 91,91,1,48,48,48,1,241,241,241,1,39,39,39,1,0,0,0,1,120, + 120,120,1,188,188,188,1,35,35,35,1,241,241,241,1,52,52,52,1,0, + 0,0,1,108,108,108,1,201,201,201,1,0,0,0,1,10,10,10,1,163, + 163,163,1,0,0,0,2,50,50,50,1,15,15,15,1,208,208,208,1,12, + 12,12,1,0,0,0,1,4,4,4,1,171,171,171,1,48,48,48,1,182, + 182,182,1,101,101,101,1,0,0,0,1,145,145,145,1,168,168,168,1,35, + 35,35,1,182,182,182,1,114,114,114,1,0,0,0,1,145,145,145,1,168, + 168,168,1,0,0,0,1,45,45,45,1,128,128,128,1,0,0,0,4,197, + 197,197,1,0,0,0,3,180,180,180,1,48,48,48,1,127,127,127,1,155, + 155,155,1,4,4,4,1,140,140,140,1,168,168,168,1,35,35,35,1,135, + 135,135,1,161,161,161,1,0,0,0,1,143,143,143,1,168,168,168,1,0, + 0,0,1,35,35,35,1,138,138,138,1,0,0,0,2,1,1,1,1,0, + 0,0,1,193,193,193,1,0,0,0,3,195,195,195,1,48,48,48,1,119, + 119,119,1,163,163,163,1,54,54,54,1,88,88,88,1,168,168,168,1,35, + 35,35,1,132,132,132,1,162,162,162,1,43,43,43,1,101,101,101,1,168, + 168,168,1,0,0,0,1,5,5,5,1,181,181,181,1,0,0,0,2,142, + 142,142,1,40,40,40,1,188,188,188,1,20,20,20,1,0,0,0,1,36, + 36,36,1,176,176,176,1,48,48,48,1,119,119,119,1,132,132,132,1,146, + 146,146,1,24,24,24,1,168,168,168,1,35,35,35,1,132,132,132,1,119, + 119,119,1,146,146,146,1,37,37,37,1,168,168,168,1,0,0,0,2,138, + 138,138,1,125,125,125,1,93,93,93,1,186,186,186,1,0,0,0,1,61, + 61,61,1,198,198,198,1,87,87,87,1,203,203,203,1,54,54,54,1,48, + 48,48,1,119,119,119,1,70,70,70,1,203,203,203,1,0,0,0,1,168, + 168,168,1,35,35,35,1,132,132,132,1,57,57,57,1,216,216,216,1,0, + 0,0,1,168,168,168,1,0,0,0,2,9,9,9,1,97,97,97,1,121, + 121,121,1,20,20,20,1,0,0,0,2,61,61,61,1,136,136,136,1,62, + 62,62,1,0,0,0,1,24,24,24,1,59,59,59,1,11,11,11,1,83, + 83,83,1,0,0,0,1,84,84,84,1,17,17,17,1,66,66,66,1,5, + 5,5,1,90,90,90,1,0,0,0,1,84,84,84,1,0,0,0,51,78, + 78,78,1,136,136,136,1,132,132,132,1,69,69,69,1,0,0,0,2,75, + 75,75,1,148,148,148,1,69,69,69,1,0,0,0,1,12,12,12,1,136, + 136,136,2,119,119,119,1,34,34,34,1,52,52,52,1,136,136,136,3,100, + 100,100,1,0,0,0,4,148,148,148,1,106,106,106,1,92,92,92,1,198, + 198,198,1,39,39,39,1,71,71,71,1,196,196,196,1,79,79,79,1,172, + 172,172,1,66,66,66,1,24,24,24,1,181,181,181,1,72,72,72,1,101, + 101,101,1,196,196,196,1,33,33,33,1,88,88,88,1,200,200,200,1,91, + 91,91,1,65,65,65,1,0,0,0,4,148,148,148,1,27,27,27,1,0, + 0,0,1,99,99,99,1,86,86,86,1,179,179,179,1,39,39,39,1,0, + 0,0,1,12,12,12,1,173,173,173,1,24,24,24,1,151,151,151,1,0, + 0,0,2,179,179,179,1,4,4,4,1,0,0,0,1,170,170,170,1,5, + 5,5,1,0,0,0,5,148,148,148,1,41,41,41,1,30,30,30,1,176, + 176,176,1,34,34,34,1,203,203,203,1,1,1,1,1,0,0,0,2,177, + 177,177,1,24,24,24,1,184,184,184,1,80,80,80,1,102,102,102,1,179, + 179,179,1,0,0,0,2,170,170,170,1,5,5,5,1,0,0,0,5,148, + 148,148,1,206,206,206,1,183,183,183,1,87,87,87,1,0,0,0,1,190, + 190,190,1,0,0,0,3,190,190,190,1,24,24,24,1,207,207,207,1,142, + 142,142,1,213,213,213,1,12,12,12,1,0,0,0,2,170,170,170,1,5, + 5,5,1,0,0,0,5,148,148,148,1,27,27,27,1,0,0,0,3,186, + 186,186,1,20,20,20,1,0,0,0,1,10,10,10,1,199,199,199,1,24, + 24,24,1,151,151,151,1,0,0,0,1,113,113,113,1,109,109,109,1,0, + 0,0,2,170,170,170,1,5,5,5,1,0,0,0,5,148,148,148,1,27, + 27,27,1,0,0,0,3,85,85,85,1,158,158,158,1,25,25,25,1,145, + 145,145,1,109,109,109,1,24,24,24,1,151,151,151,1,0,0,0,1,9, + 9,9,1,207,207,207,1,6,6,6,1,0,0,0,1,170,170,170,1,5, + 5,5,1,0,0,0,5,111,111,111,1,20,20,20,1,0,0,0,4,113, + 113,113,1,198,198,198,1,132,132,132,1,1,1,1,1,18,18,18,1,113, + 113,113,1,0,0,0,2,105,105,105,1,62,62,62,1,0,0,0,1,128, + 128,128,1,3,3,3,1,0,0,0,75,0,0) + ); + +const + objdata_tasciicommport: record size: integer; data: array[0..1857] of byte end = + (size: 1858; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,97,115, + 99,105,105,99,111,109,109,112,111,114,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,200,6,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,20,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,76,0,0,0,2, + 208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,4,208,208,208,1, + 0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,6,0,0,0,3, + 208,208,208,1,0,0,0,10,208,208,208,1,0,0,0,1,208,208,208,1, + 0,0,0,1,208,208,208,6,0,0,0,3,208,208,208,1,0,0,0,7, + 208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1, + 0,0,0,1,208,208,208,6,0,0,0,4,208,208,208,1,0,0,0,6, + 208,208,208,4,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,6, + 0,0,0,4,208,208,208,2,0,0,0,5,208,208,208,2,0,0,0,1, + 208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,5, + 0,0,0,7,208,208,208,1,0,0,0,4,208,208,208,2,0,0,0,1, + 208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,5, + 0,0,0,2,208,208,208,2,0,0,0,11,208,208,208,1,0,0,0,1, + 208,208,208,1,0,0,0,1,208,208,208,5,0,0,0,2,208,208,208,2, + 0,0,0,5,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,1, + 208,208,208,1,0,0,0,1,208,208,208,53,0,0,0,4,208,208,208,2, + 0,0,0,3,208,208,208,1,0,0,0,10,208,208,208,4,0,0,0,20, + 208,208,208,4,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,1, + 0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,5,0,0,0,7,208,208,208,2,0,0,0,6,208,208,208,2, + 0,0,0,2,208,208,208,5,0,0,0,4,208,208,208,1,0,0,0,1, + 208,208,208,3,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,5, + 0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,4, + 208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,5, + 0,0,0,2,208,208,208,3,0,0,0,7,208,208,208,1,0,0,0,3, + 208,208,208,1,0,0,0,2,208,208,208,5,0,0,0,2,208,208,208,4, + 0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,75,124,4,0,0,0,0,0,76,145,145,145,1,48,48,48,1, + 0,0,0,2,108,108,108,1,211,211,211,1,154,154,154,1,5,5,5,1, + 0,0,0,1,64,64,64,1,191,191,191,1,167,167,167,1,30,30,30,1, + 0,0,0,1,137,137,137,1,0,0,0,1,137,137,137,1,0,0,0,6, + 4,4,4,1,184,184,184,1,128,128,128,1,0,0,0,1,21,21,21,1, + 175,175,175,1,13,13,13,1,124,124,124,1,101,101,101,1,20,20,20,1, + 184,184,184,1,28,28,28,1,58,58,58,1,159,159,159,1,0,0,0,1, + 176,176,176,1,0,0,0,1,176,176,176,1,0,0,0,6,60,60,60,1, + 111,111,111,1,169,169,169,1,0,0,0,1,32,32,32,1,165,165,165,1, + 4,4,4,1,13,13,13,1,42,42,42,1,85,85,85,1,88,88,88,1, + 0,0,0,2,66,66,66,1,0,0,0,1,176,176,176,1,0,0,0,1, + 176,176,176,1,0,0,0,6,129,129,129,1,44,44,44,1,153,153,153,1, + 23,23,23,1,0,0,0,1,148,148,148,1,220,220,220,1,116,116,116,1, + 2,2,2,1,121,121,121,1,52,52,52,1,0,0,0,4,176,176,176,1, + 0,0,0,1,176,176,176,1,0,0,0,6,195,195,195,1,128,128,128,1, + 179,179,179,1,97,97,97,1,0,0,0,2,37,37,37,1,156,156,156,1, + 119,119,119,1,111,111,111,1,62,62,62,1,0,0,0,2,1,1,1,1, + 0,0,0,1,176,176,176,1,0,0,0,1,176,176,176,1,0,0,0,5, + 15,15,15,1,182,182,182,1,80,80,80,1,86,86,86,1,169,169,169,1, + 75,75,75,1,78,78,78,1,0,0,0,1,3,3,3,1,166,166,166,1, + 74,74,74,1,111,111,111,1,0,0,0,2,181,181,181,1,0,0,0,1, + 176,176,176,1,0,0,0,1,176,176,176,1,0,0,0,5,81,81,81,1, + 99,99,99,1,0,0,0,2,189,189,189,1,31,31,31,1,202,202,202,1, + 83,83,83,1,136,136,136,1,106,106,106,1,3,3,3,1,191,191,191,1, + 85,85,85,1,136,136,136,1,127,127,127,1,0,0,0,1,176,176,176,1, + 0,0,0,1,176,176,176,1,0,0,0,5,66,66,66,1,24,24,24,1, + 0,0,0,2,76,76,76,1,23,23,23,1,52,52,52,1,139,139,139,1, + 103,103,103,1,0,0,0,2,29,29,29,1,123,123,123,1,91,91,91,1, + 4,4,4,1,0,0,0,1,88,88,88,1,0,0,0,1,88,88,88,1, + 0,0,0,53,78,78,78,1,136,136,136,1,132,132,132,1,69,69,69,1, + 0,0,0,2,75,75,75,1,148,148,148,1,69,69,69,1,0,0,0,1, + 12,12,12,1,136,136,136,2,119,119,119,1,34,34,34,1,52,52,52,1, + 136,136,136,3,100,100,100,1,0,0,0,4,148,148,148,1,106,106,106,1, + 92,92,92,1,198,198,198,1,39,39,39,1,71,71,71,1,196,196,196,1, + 79,79,79,1,172,172,172,1,66,66,66,1,24,24,24,1,181,181,181,1, + 72,72,72,1,101,101,101,1,196,196,196,1,33,33,33,1,88,88,88,1, + 200,200,200,1,91,91,91,1,65,65,65,1,0,0,0,4,148,148,148,1, + 27,27,27,1,0,0,0,1,99,99,99,1,86,86,86,1,179,179,179,1, + 39,39,39,1,0,0,0,1,12,12,12,1,173,173,173,1,24,24,24,1, + 151,151,151,1,0,0,0,2,179,179,179,1,4,4,4,1,0,0,0,1, + 170,170,170,1,5,5,5,1,0,0,0,5,148,148,148,1,41,41,41,1, + 30,30,30,1,176,176,176,1,34,34,34,1,203,203,203,1,1,1,1,1, + 0,0,0,2,177,177,177,1,24,24,24,1,184,184,184,1,80,80,80,1, + 102,102,102,1,179,179,179,1,0,0,0,2,170,170,170,1,5,5,5,1, + 0,0,0,5,148,148,148,1,206,206,206,1,183,183,183,1,87,87,87,1, + 0,0,0,1,190,190,190,1,0,0,0,3,190,190,190,1,24,24,24,1, + 207,207,207,1,142,142,142,1,213,213,213,1,12,12,12,1,0,0,0,2, + 170,170,170,1,5,5,5,1,0,0,0,5,148,148,148,1,27,27,27,1, + 0,0,0,3,186,186,186,1,20,20,20,1,0,0,0,1,10,10,10,1, + 199,199,199,1,24,24,24,1,151,151,151,1,0,0,0,1,113,113,113,1, + 109,109,109,1,0,0,0,2,170,170,170,1,5,5,5,1,0,0,0,5, + 148,148,148,1,27,27,27,1,0,0,0,3,85,85,85,1,158,158,158,1, + 25,25,25,1,145,145,145,1,109,109,109,1,24,24,24,1,151,151,151,1, + 0,0,0,1,9,9,9,1,207,207,207,1,6,6,6,1,0,0,0,1, + 170,170,170,1,5,5,5,1,0,0,0,5,111,111,111,1,20,20,20,1, + 0,0,0,4,113,113,113,1,198,198,198,1,132,132,132,1,1,1,1,1, + 18,18,18,1,113,113,113,1,0,0,0,2,105,105,105,1,62,62,62,1, + 0,0,0,1,128,128,128,1,3,3,3,1,0,0,0,75,0,0) + ); + +const + objdata_tasciiprotport: record size: integer; data: array[0..1661] of byte end = + (size: 1662; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,97,115, + 99,105,105,112,114,111,116,112,111,114,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,4,6,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,156,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,77,0,0,0,2, + 208,208,208,12,0,0,0,1,208,208,208,8,0,0,0,3,208,208,208,12, + 0,0,0,1,208,208,208,8,0,0,0,3,208,208,208,1,0,0,0,13, + 208,208,208,7,0,0,0,3,208,208,208,1,0,0,0,12,208,208,208,7, + 0,0,0,7,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,3, + 208,208,208,7,0,0,0,13,208,208,208,1,0,0,0,3,208,208,208,7, + 0,0,0,2,208,208,208,1,0,0,0,8,208,208,208,1,0,0,0,6, + 208,208,208,6,0,0,0,2,208,208,208,2,0,0,0,7,208,208,208,1, + 0,0,0,3,208,208,208,1,0,0,0,2,208,208,208,11,0,0,0,2, + 208,208,208,22,0,0,0,2,208,208,208,16,0,0,0,4,208,208,208,2, + 0,0,0,3,208,208,208,1,0,0,0,10,208,208,208,4,0,0,0,20, + 208,208,208,4,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,1, + 0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,5,0,0,0,7,208,208,208,2,0,0,0,6,208,208,208,2, + 0,0,0,2,208,208,208,5,0,0,0,4,208,208,208,1,0,0,0,1, + 208,208,208,3,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,5, + 0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,4, + 208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,5, + 0,0,0,2,208,208,208,3,0,0,0,7,208,208,208,1,0,0,0,3, + 208,208,208,1,0,0,0,2,208,208,208,5,0,0,0,2,208,208,208,4, + 0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,75,48,4,0,0,0,0,0,77,182,182,182,1,10,10,10,1, + 0,0,0,12,52,52,52,1,0,0,0,8,42,42,42,1,197,197,197,1, + 77,77,77,1,0,0,0,12,160,160,160,1,0,0,0,8,111,111,111,1, + 79,79,79,1,150,150,150,1,0,0,0,1,94,94,94,1,148,148,148,1, + 178,178,178,1,28,28,28,1,87,87,87,1,156,156,156,1,98,98,98,1, + 83,83,83,1,182,182,182,1,83,83,83,1,58,58,58,1,229,229,229,1, + 79,79,79,1,0,0,0,7,169,169,169,1,5,5,5,1,176,176,176,1, + 0,0,0,1,121,121,121,1,120,120,120,1,45,45,45,1,149,149,149,1, + 111,111,111,1,117,117,117,1,15,15,15,1,163,163,163,1,10,10,10,1, + 172,172,172,1,3,3,3,1,160,160,160,1,0,0,0,7,6,6,6,1, + 215,215,215,1,128,128,128,1,205,205,205,1,45,45,45,1,121,121,121,1, + 51,51,51,1,0,0,0,1,174,174,174,1,111,111,111,1,56,56,56,1, + 33,33,33,1,129,129,129,1,0,0,0,1,112,112,112,1,49,49,49,1, + 160,160,160,1,0,0,0,7,63,63,63,1,151,151,151,1,80,80,80,1, + 119,119,119,1,120,120,120,1,121,121,121,1,59,59,59,1,4,4,4,1, + 172,172,172,1,111,111,111,1,48,48,48,1,22,22,22,1,141,141,141,1, + 0,0,0,1,129,129,129,1,43,43,43,1,159,159,159,1,0,0,0,7, + 132,132,132,1,47,47,47,1,0,0,0,1,8,8,8,1,186,186,186,1, + 121,121,121,1,159,159,159,1,111,111,111,1,112,112,112,1,111,111,111,1, + 48,48,48,1,0,0,0,1,182,182,182,1,73,73,73,1,190,190,190,1, + 8,8,8,1,172,172,172,1,32,32,32,1,0,0,0,6,89,89,89,1, + 1,1,1,1,0,0,0,2,98,98,98,1,122,122,122,1,121,121,121,2, + 5,5,5,1,55,55,55,1,24,24,24,1,0,0,0,1,25,25,25,1, + 129,129,129,1,46,46,46,1,0,0,0,1,75,75,75,1,67,67,67,1, + 0,0,0,11,121,121,121,1,46,46,46,1,0,0,0,22,64,64,64,1, + 24,24,24,1,0,0,0,16,78,78,78,1,136,136,136,1,132,132,132,1, + 69,69,69,1,0,0,0,2,75,75,75,1,148,148,148,1,69,69,69,1, + 0,0,0,1,12,12,12,1,136,136,136,2,119,119,119,1,34,34,34,1, + 52,52,52,1,136,136,136,3,100,100,100,1,0,0,0,4,148,148,148,1, + 106,106,106,1,92,92,92,1,198,198,198,1,39,39,39,1,71,71,71,1, + 196,196,196,1,79,79,79,1,172,172,172,1,66,66,66,1,24,24,24,1, + 181,181,181,1,72,72,72,1,101,101,101,1,196,196,196,1,33,33,33,1, + 88,88,88,1,200,200,200,1,91,91,91,1,65,65,65,1,0,0,0,4, + 148,148,148,1,27,27,27,1,0,0,0,1,99,99,99,1,86,86,86,1, + 179,179,179,1,39,39,39,1,0,0,0,1,12,12,12,1,173,173,173,1, + 24,24,24,1,151,151,151,1,0,0,0,2,179,179,179,1,4,4,4,1, + 0,0,0,1,170,170,170,1,5,5,5,1,0,0,0,5,148,148,148,1, + 41,41,41,1,30,30,30,1,176,176,176,1,34,34,34,1,203,203,203,1, + 1,1,1,1,0,0,0,2,177,177,177,1,24,24,24,1,184,184,184,1, + 80,80,80,1,102,102,102,1,179,179,179,1,0,0,0,2,170,170,170,1, + 5,5,5,1,0,0,0,5,148,148,148,1,206,206,206,1,183,183,183,1, + 87,87,87,1,0,0,0,1,190,190,190,1,0,0,0,3,190,190,190,1, + 24,24,24,1,207,207,207,1,142,142,142,1,213,213,213,1,12,12,12,1, + 0,0,0,2,170,170,170,1,5,5,5,1,0,0,0,5,148,148,148,1, + 27,27,27,1,0,0,0,3,186,186,186,1,20,20,20,1,0,0,0,1, + 10,10,10,1,199,199,199,1,24,24,24,1,151,151,151,1,0,0,0,1, + 113,113,113,1,109,109,109,1,0,0,0,2,170,170,170,1,5,5,5,1, + 0,0,0,5,148,148,148,1,27,27,27,1,0,0,0,3,85,85,85,1, + 158,158,158,1,25,25,25,1,145,145,145,1,109,109,109,1,24,24,24,1, + 151,151,151,1,0,0,0,1,9,9,9,1,207,207,207,1,6,6,6,1, + 0,0,0,1,170,170,170,1,5,5,5,1,0,0,0,5,111,111,111,1, + 20,20,20,1,0,0,0,4,113,113,113,1,198,198,198,1,132,132,132,1, + 1,1,1,1,18,18,18,1,113,113,113,1,0,0,0,2,105,105,105,1, + 62,62,62,1,0,0,0,1,128,128,128,1,3,3,3,1,0,0,0,75, + 0,0) + ); + +const + objdata_tcommselector: record size: integer; data: array[0..597] of byte end = + (size: 598; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,99,111, + 109,109,115,101,108,101,99,116,111,114,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,36,2,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,240,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,255,146,128,128,128,20,255,0,255,4,128,128,128,1,0,0,0,18, + 255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,10, + 255,0,255,5,128,128,128,1,192,192,192,1,255,255,255,1,255,0,255,4, + 128,128,128,1,0,0,0,1,255,255,255,10,255,0,255,5,128,128,128,1, + 192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1, + 255,255,255,2,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3, + 255,0,255,5,128,128,128,1,192,192,192,1,255,255,255,1,255,0,255,4, + 128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1, + 0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1, + 255,255,255,2,0,0,0,5,128,128,128,1,192,192,192,1,255,255,255,1, + 255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1, + 255,255,255,3,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2, + 255,0,255,1,0,0,0,3,255,0,255,1,128,128,128,1,192,192,192,1, + 255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,1, + 0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,1,0,0,0,1, + 255,255,255,2,255,0,255,2,0,0,0,1,255,0,255,2,128,128,128,1, + 192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1, + 255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1, + 0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,255,0,255,5, + 128,128,128,1,192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1, + 0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,3,0,0,0,1, + 255,255,255,3,255,0,255,5,128,128,128,1,192,192,192,1,255,255,255,1, + 255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,10,128,128,128,6, + 192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1,192,192,192,18, + 255,255,255,1,255,0,255,4,255,255,255,20,255,0,255,122,0,0) + ); + +const + objdata_tsercommcomp: record size: integer; data: array[0..2915] of byte end = + (size: 2916; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,101, + 114,99,111,109,109,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,236,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,32,5,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,26,255,187,75,23,223,163,1,8,77, + 57,1,26,255,187,2,24,237,174,1,7,67,49,1,4,42,31,1,16,161, + 118,1,24,231,169,1,10,101,74,1,26,255,187,2,14,138,101,1,19,189, + 139,1,8,75,55,1,25,246,181,1,26,255,187,1,15,150,110,1,21,210, + 154,1,26,255,187,5,15,146,107,1,5,50,37,1,23,226,166,1,26,255, + 187,1,12,117,86,1,16,161,118,1,23,230,168,1,5,46,33,1,25,249, + 183,1,8,76,56,1,21,210,154,1,25,246,181,1,6,57,42,1,26,253, + 185,1,2,23,17,1,14,139,102,1,26,255,187,1,13,124,91,1,20,197, + 145,1,26,255,187,5,8,83,61,1,16,160,117,1,15,144,106,1,26,255, + 187,1,11,105,77,1,18,180,132,1,26,255,187,1,20,201,147,1,25,244, + 179,1,20,198,145,1,9,90,66,1,14,142,104,1,16,154,113,1,26,255, + 187,1,7,71,52,1,6,55,40,1,25,250,183,1,13,124,91,1,20,197, + 145,1,26,255,187,4,26,254,186,1,7,71,52,1,25,243,178,1,8,77, + 57,1,26,255,187,1,22,218,160,1,3,31,23,1,7,65,48,1,19,187, + 137,1,26,255,187,2,7,73,53,1,7,66,49,1,26,253,185,1,26,255, + 187,1,8,75,55,1,14,133,97,1,15,149,110,1,13,124,91,1,20,197, + 145,1,26,255,187,4,20,198,145,1,5,47,34,1,12,114,83,1,3,31, + 23,1,25,249,183,1,26,255,187,1,26,251,184,1,17,166,122,1,4,40, + 30,1,23,225,165,1,26,255,187,1,17,162,119,1,13,127,93,1,26,255, + 187,2,8,75,55,1,25,244,179,1,5,54,39,1,12,122,89,1,20,197, + 145,1,26,255,187,4,13,125,91,1,13,129,94,1,17,163,120,1,9,86, + 63,1,18,178,131,1,9,90,66,1,26,255,187,2,14,138,101,1,18,178, + 131,1,26,255,187,1,18,174,128,1,14,137,100,1,26,255,187,2,8,75, + 55,1,26,255,187,1,12,121,89,1,5,46,33,1,20,197,145,1,26,255, + 187,4,7,69,51,1,25,249,183,1,26,255,187,1,20,193,141,1,10,101, + 74,1,13,124,91,1,9,91,67,1,17,163,120,1,6,57,42,1,24,234, + 172,1,26,255,187,1,18,174,128,1,14,137,100,1,26,255,187,2,8,75, + 55,1,26,255,187,1,24,237,174,1,1,12,9,1,20,197,145,1,26,255, + 187,4,15,151,111,1,26,255,187,2,26,253,185,1,15,146,107,1,26,254, + 186,1,14,140,103,1,10,101,74,1,20,195,143,1,26,255,187,2,22,213, + 156,1,20,194,142,1,26,255,187,2,16,159,117,1,26,255,187,2,16,161, + 118,1,23,226,166,1,26,255,187,51,25,248,182,1,14,138,101,1,11,111, + 81,1,23,221,162,1,26,255,187,2,16,160,117,1,10,95,70,1,19,183, + 134,1,26,255,187,1,23,225,165,1,12,119,87,1,26,255,187,2,22,219, + 161,1,14,136,100,1,24,233,171,1,11,113,83,1,26,255,187,2,23,227, + 167,1,13,130,95,1,26,255,187,2,11,106,78,1,12,117,86,1,16,161, + 118,1,6,59,43,1,26,255,187,1,16,157,115,1,6,56,41,1,17,166, + 122,1,7,64,47,1,20,193,141,1,20,198,145,1,0,5,4,1,23,226, + 166,1,26,255,187,1,14,137,100,1,5,50,37,1,22,213,156,1,0,4, + 3,1,22,212,156,1,26,255,187,1,15,150,110,1,4,40,29,1,26,255, + 187,1,25,250,183,1,7,64,47,1,26,255,187,2,15,149,110,1,23,228, + 168,1,5,51,37,1,23,226,166,1,26,255,187,1,24,232,170,1,8,77, + 57,1,20,198,145,1,5,49,36,1,16,158,116,1,26,255,187,1,10,97, + 71,1,8,75,55,1,22,213,156,1,5,49,36,1,15,144,106,1,26,255, + 187,1,10,100,73,1,7,73,53,1,26,255,187,1,22,211,155,1,11,108, + 79,1,26,255,187,4,4,43,32,1,26,255,187,3,7,67,49,1,20,198, + 145,1,11,105,77,1,10,96,71,1,26,255,187,1,10,98,72,1,8,75, + 55,1,22,213,156,1,10,100,73,1,9,89,65,1,26,255,187,1,10,98, + 72,1,8,75,55,1,26,255,187,1,21,204,150,1,11,111,81,1,26,255, + 187,4,6,56,41,1,26,255,187,3,6,55,40,1,20,198,145,1,13,123, + 90,1,8,80,59,1,21,210,154,1,14,138,101,1,8,75,55,1,22,213, + 156,1,11,110,81,1,8,80,59,1,23,224,164,1,13,125,91,1,8,75, + 55,1,26,255,187,1,25,243,178,1,8,77,57,1,26,255,187,2,15,143, + 105,1,22,212,156,1,5,49,36,1,25,244,179,1,26,255,187,1,23,228, + 168,1,6,58,43,1,20,198,145,1,13,123,90,1,10,96,71,1,13,124, + 91,1,21,207,152,1,8,75,55,1,22,213,156,1,11,110,81,1,11,108, + 79,1,13,125,91,1,20,193,141,1,8,75,55,1,26,255,187,2,8,74, + 54,1,19,184,135,1,22,217,159,1,6,55,41,1,26,251,184,1,14,141, + 103,1,10,96,71,1,23,225,165,1,9,86,63,1,15,149,110,1,20,198, + 145,1,13,123,90,1,16,158,116,1,5,45,33,1,26,255,187,1,8,75, + 55,1,22,213,156,1,11,110,81,1,18,172,126,1,4,36,26,1,26,251, + 184,1,8,75,55,1,26,255,187,2,22,219,161,1,8,82,60,1,6,62, + 45,1,19,185,136,1,26,255,187,1,26,254,186,1,12,119,87,1,5,47, + 35,1,12,120,88,1,26,255,187,1,22,212,156,1,16,154,113,1,23,227, + 167,1,11,111,81,1,26,255,187,1,12,116,85,1,23,224,164,1,15,143, + 105,1,24,238,175,1,10,101,74,1,26,255,187,1,12,116,85,1,26,255, + 187,73,148,5,0,0,207,207,207,23,201,201,201,1,207,207,207,23,201,201, + 201,1,207,207,207,23,201,201,201,1,207,207,207,3,212,212,212,1,238,238, + 238,1,207,207,207,2,210,210,210,1,240,240,240,1,246,246,246,1,222,222, + 222,1,211,211,211,1,234,234,234,1,207,207,207,2,227,227,227,1,218,218, + 218,1,239,239,239,1,208,208,208,1,207,207,207,1,224,224,224,1,214,214, + 214,1,207,207,207,1,201,201,201,1,207,207,207,3,225,225,225,1,244,244, + 244,1,212,212,212,1,207,207,207,1,231,231,231,1,222,222,222,1,211,211, + 211,1,245,245,245,1,208,208,208,1,238,238,238,1,214,214,214,1,208,208, + 208,1,242,242,242,1,207,207,207,1,250,250,250,1,226,226,226,1,207,207, + 207,1,229,229,229,1,216,216,216,1,207,207,207,1,201,201,201,1,207,207, + 207,3,237,237,237,1,223,223,223,1,225,225,225,1,207,207,207,1,233,233, + 233,1,219,219,219,1,207,207,207,1,216,216,216,1,209,209,209,1,216,216, + 216,1,236,236,236,1,226,226,226,1,224,224,224,1,207,207,207,1,240,240, + 240,1,243,243,243,1,208,208,208,1,229,229,229,1,216,216,216,1,207,207, + 207,1,201,201,201,1,207,207,207,3,240,240,240,1,209,209,209,1,238,238, + 238,1,207,207,207,1,213,213,213,1,248,248,248,1,241,241,241,1,218,218, + 218,1,207,207,207,2,239,239,239,1,241,241,241,1,207,207,207,2,239,239, + 239,1,228,228,228,1,225,225,225,1,229,229,229,1,216,216,216,1,207,207, + 207,1,201,201,201,1,207,207,207,2,216,216,216,1,245,245,245,1,231,231, + 231,1,248,248,248,1,208,208,208,1,207,207,207,1,208,208,208,1,221,221, + 221,1,246,246,246,1,212,212,212,1,207,207,207,1,222,222,222,1,229,229, + 229,1,207,207,207,2,239,239,239,1,209,209,209,1,243,243,243,1,230,230, + 230,1,216,216,216,1,207,207,207,1,201,201,201,1,207,207,207,2,229,229, + 229,1,228,228,228,1,222,222,222,1,237,237,237,1,219,219,219,1,236,236, + 236,1,207,207,207,2,227,227,227,1,219,219,219,1,207,207,207,1,220,220, + 220,1,227,227,227,1,207,207,207,2,239,239,239,1,207,207,207,1,230,230, + 230,1,245,245,245,1,216,216,216,1,207,207,207,1,201,201,201,1,207,207, + 207,2,240,240,240,1,208,208,208,1,207,207,207,1,217,217,217,1,234,234, + 234,1,229,229,229,1,235,235,235,1,222,222,222,1,242,242,242,1,210,210, + 210,1,207,207,207,1,220,220,220,1,227,227,227,1,207,207,207,2,239,239, + 239,1,207,207,207,1,210,210,210,1,252,252,252,1,216,216,216,1,207,207, + 207,1,201,201,201,1,207,207,207,2,224,224,224,1,207,207,207,3,225,225, + 225,1,207,207,207,1,226,226,226,1,234,234,234,1,217,217,217,1,207,207, + 207,2,214,214,214,1,217,217,217,1,207,207,207,2,223,223,223,1,207,207, + 207,2,222,222,222,1,212,212,212,1,207,207,207,1,201,201,201,1,207,207, + 207,23,201,201,201,1,207,207,207,23,201,201,201,1,207,207,207,1,208,208, + 208,1,227,227,227,1,232,232,232,1,212,212,212,1,207,207,207,2,223,223, + 223,1,235,235,235,1,219,219,219,1,207,207,207,1,212,212,212,1,230,230, + 230,1,207,207,207,2,213,213,213,1,227,227,227,1,210,210,210,1,231,231, + 231,1,207,207,207,2,211,211,211,1,228,228,228,1,201,201,201,1,207,207, + 207,1,233,233,233,1,231,231,231,1,222,222,222,1,242,242,242,1,207,207, + 207,1,223,223,223,1,243,243,243,1,221,221,221,1,241,241,241,1,217,217, + 217,1,216,216,216,1,254,254,254,1,212,212,212,1,207,207,207,1,227,227, + 227,1,244,244,244,1,214,214,214,1,254,254,254,1,214,214,214,1,207,207, + 207,1,224,224,224,1,246,246,246,1,201,201,201,1,208,208,208,1,241,241, + 241,1,207,207,207,2,225,225,225,1,211,211,211,1,244,244,244,1,212,212, + 212,1,207,207,207,1,211,211,211,1,238,238,238,1,216,216,216,1,244,244, + 244,1,223,223,223,1,207,207,207,1,234,234,234,1,239,239,239,1,214,214, + 214,1,244,244,244,1,225,225,225,1,207,207,207,1,234,234,234,1,239,239, + 239,1,201,201,201,1,214,214,214,1,232,232,232,1,207,207,207,4,245,245, + 245,1,207,207,207,3,240,240,240,1,216,216,216,1,233,233,233,1,234,234, + 234,1,207,207,207,1,234,234,234,1,239,239,239,1,214,214,214,1,234,234, + 234,1,236,236,236,1,207,207,207,1,234,234,234,1,239,239,239,1,201,201, + 201,1,215,215,215,1,232,232,232,1,207,207,207,4,243,243,243,1,207,207, + 207,3,243,243,243,1,216,216,216,1,229,229,229,1,238,238,238,1,214,214, + 214,1,227,227,227,1,239,239,239,1,214,214,214,1,232,232,232,1,238,238, + 238,1,212,212,212,1,229,229,229,1,239,239,239,1,201,201,201,1,209,209, + 209,1,238,238,238,1,207,207,207,2,226,226,226,1,214,214,214,1,244,244, + 244,1,209,209,209,1,207,207,207,1,211,211,211,1,242,242,242,1,216,216, + 216,1,229,229,229,1,234,234,234,1,229,229,229,1,215,215,215,1,239,239, + 239,1,214,214,214,1,232,232,232,2,229,229,229,1,217,217,217,1,239,239, + 239,1,201,201,201,1,207,207,207,1,239,239,239,1,218,218,218,1,213,213, + 213,1,243,243,243,1,208,208,208,1,226,226,226,1,234,234,234,1,212,212, + 212,1,237,237,237,1,225,225,225,1,216,216,216,1,229,229,229,1,223,223, + 223,1,245,245,245,1,207,207,207,1,239,239,239,1,214,214,214,1,232,232, + 232,1,221,221,221,1,247,247,247,1,208,208,208,1,239,239,239,1,201,201, + 201,1,207,207,207,1,213,213,213,1,237,237,237,1,241,241,241,1,218,218, + 218,1,207,207,207,2,230,230,230,1,244,244,244,1,230,230,230,1,207,207, + 207,1,214,214,214,1,224,224,224,1,211,211,211,1,232,232,232,1,207,207, + 207,1,231,231,231,1,212,212,212,1,226,226,226,1,210,210,210,1,234,234, + 234,1,207,207,207,1,231,231,231,1,201,201,201,1,207,207,207,23,201,201, + 201,1,207,207,207,23,201,201,201,24,195,195,195,1,0,0) + ); + +const + objdata_tsercommchannel: record size: integer; data: array[0..2066] of byte end = + (size: 2067; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,115,101, + 114,99,111,109,109,99,104,97,110,110,101,108,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,152,7,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,92,3,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,26,255,187,77,17,166,122, + 1,4,40,30,1,7,68,50,1,24,232,170,1,22,216,158,1,5,47,34, + 3,12,120,88,1,18,180,132,1,5,47,34,1,5,47,35,1,7,71,52, + 1,21,207,152,1,26,255,187,10,6,57,42,1,24,232,170,1,16,160,117, + 1,10,99,73,1,21,204,150,1,10,98,72,1,23,226,166,2,24,238,175, + 1,16,161,118,1,15,144,106,1,25,245,180,1,18,179,132,1,7,70,51, + 1,26,255,187,9,26,253,185,1,6,57,42,1,25,242,177,1,26,255,187, + 1,19,190,140,1,21,204,150,1,11,110,81,1,26,255,187,3,16,161,118, + 1,15,149,110,1,26,255,187,1,26,253,185,1,7,66,49,1,26,255,187, + 10,13,132,97,1,2,22,16,1,11,106,78,1,25,240,176,1,21,204,150, + 1,3,32,23,1,7,68,50,2,18,175,128,1,16,161,118,1,6,61,45, + 1,10,98,72,1,6,63,46,1,15,149,110,1,26,255,187,11,23,226,166, + 1,12,114,83,1,8,83,61,1,21,204,150,1,9,90,66,1,21,207,152, + 2,24,237,174,1,16,161,118,1,11,103,76,1,15,148,109,1,7,68,50, + 1,26,255,187,10,21,210,154,1,13,127,93,1,26,255,187,2,8,74,54, + 1,21,204,150,1,11,110,81,1,26,255,187,3,16,161,118,1,15,149,110, + 1,26,255,187,1,11,104,76,1,16,158,116,1,26,255,187,9,25,250,183, + 1,4,44,32,1,15,150,110,1,13,131,96,1,10,98,72,1,21,204,150, + 1,7,69,51,1,16,155,113,2,19,183,134,1,16,161,118,1,15,149,110, + 1,26,255,187,1,23,227,167,1,5,47,35,1,26,255,187,10,22,213,156, + 1,11,110,81,1,12,122,89,1,25,244,179,1,23,230,168,1,12,114,83, + 3,16,153,112,1,21,206,151,1,20,201,147,1,26,255,187,2,15,150,110, + 1,24,232,170,1,26,255,187,57,24,233,171,1,13,123,90,1,13,125,91, + 1,24,237,174,1,26,255,187,1,15,149,110,1,26,255,187,2,17,167,123, + 1,24,236,173,1,26,255,187,1,20,193,141,1,18,176,129,1,26,255,187, + 11,8,74,54,1,14,140,103,1,15,143,105,1,9,84,62,1,26,255,187, + 1,7,68,50,1,26,255,187,2,10,98,72,1,22,218,160,1,26,255,187, + 1,10,95,70,1,8,83,61,1,26,255,187,10,21,203,149,1,10,102,75, + 1,26,255,187,2,13,129,94,1,26,251,184,1,7,68,50,1,26,255,187, + 2,10,98,72,1,22,218,160,1,26,255,187,1,8,74,54,1,9,88,64, + 1,25,240,176,1,26,255,187,9,17,162,119,1,16,154,113,1,26,255,187, + 4,4,38,28,1,11,106,78,2,4,44,32,1,22,218,160,1,22,212,156, + 1,11,104,76,1,15,147,108,1,17,163,120,1,26,255,187,9,16,156,114, + 1,16,157,115,1,26,255,187,4,5,50,37,1,17,163,120,2,7,65,48, + 1,22,218,160,1,14,137,100,1,12,119,87,1,16,153,112,1,9,89,65, + 1,26,255,187,9,19,190,140,1,12,120,88,1,26,255,187,2,12,116,85, + 1,25,244,179,1,7,68,50,1,26,255,187,2,10,98,72,1,22,218,160, + 1,8,76,56,1,10,98,72,2,5,45,33,1,26,255,187,9,25,249,183, + 1,6,55,40,1,22,213,156,1,20,196,144,1,7,69,51,1,26,255,187, + 1,7,68,50,1,26,255,187,2,10,98,72,1,22,214,157,1,7,68,50, + 1,26,255,187,2,10,97,71,1,20,198,145,1,26,255,187,9,20,194,142, + 1,7,69,51,1,8,75,55,1,21,209,153,1,26,255,187,1,11,110,81, + 1,26,255,187,2,14,134,98,1,19,189,139,1,14,142,104,1,26,255,187, + 2,19,182,133,1,16,158,116,1,26,255,187,76,4,4,0,0,195,195,195, + 1,207,207,207,23,195,195,195,1,207,207,207,23,195,195,195,1,207,207,207, + 23,195,195,195,1,207,207,207,4,221,221,221,1,246,246,246,1,240,240,240, + 1,211,211,211,1,213,213,213,1,245,245,245,3,230,230,230,1,219,219,219, + 1,245,245,245,1,244,244,244,1,240,240,240,1,215,215,215,1,207,207,207, + 5,195,195,195,1,207,207,207,4,242,242,242,1,211,211,211,1,223,223,223, + 1,234,234,234,1,215,215,215,1,234,234,234,1,212,212,212,2,210,210,210, + 1,222,222,222,1,225,225,225,1,209,209,209,1,219,219,219,1,240,240,240, + 1,207,207,207,5,195,195,195,1,207,207,207,4,242,242,242,1,209,209,209, + 1,207,207,207,1,217,217,217,1,215,215,215,1,232,232,232,1,207,207,207, + 3,222,222,222,1,225,225,225,1,207,207,207,2,241,241,241,1,207,207,207, + 5,195,195,195,1,207,207,207,4,228,228,228,1,250,250,250,1,233,233,233, + 1,209,209,209,1,215,215,215,1,248,248,248,1,240,240,240,2,220,220,220, + 1,222,222,222,1,242,242,242,1,234,234,234,1,241,241,241,1,225,225,225, + 1,207,207,207,5,195,195,195,1,207,207,207,5,212,212,212,1,231,231,231, + 1,237,237,237,1,215,215,215,1,236,236,236,1,215,215,215,2,210,210,210, + 1,222,222,222,1,233,233,233,1,225,225,225,1,240,240,240,1,207,207,207, + 6,195,195,195,1,207,207,207,3,214,214,214,1,229,229,229,1,207,207,207, + 2,239,239,239,1,215,215,215,1,232,232,232,1,207,207,207,3,222,222,222, + 1,225,225,225,1,207,207,207,1,233,233,233,1,223,223,223,1,207,207,207, + 5,195,195,195,1,207,207,207,3,208,208,208,1,245,245,245,1,224,224,224, + 1,228,228,228,1,234,234,234,1,215,215,215,1,240,240,240,1,224,224,224, + 2,219,219,219,1,222,222,222,1,225,225,225,1,207,207,207,1,211,211,211, + 1,244,244,244,1,207,207,207,5,195,195,195,1,207,207,207,4,214,214,214, + 1,232,232,232,1,230,230,230,1,209,209,209,1,211,211,211,1,231,231,231, + 3,224,224,224,1,215,215,215,1,216,216,216,1,207,207,207,2,224,224,224, + 1,211,211,211,1,207,207,207,4,195,195,195,1,207,207,207,23,195,195,195, + 1,207,207,207,23,195,195,195,1,207,207,207,4,210,210,210,1,229,229,229, + 2,210,210,210,1,207,207,207,1,225,225,225,1,207,207,207,2,221,221,221, + 1,210,210,210,1,207,207,207,1,217,217,217,1,220,220,220,1,207,207,207, + 6,195,195,195,1,207,207,207,4,239,239,239,1,226,226,226,2,237,237,237, + 1,207,207,207,1,240,240,240,1,207,207,207,2,234,234,234,1,213,213,213, + 1,207,207,207,1,235,235,235,1,237,237,237,1,207,207,207,6,195,195,195, + 1,207,207,207,3,215,215,215,1,233,233,233,1,207,207,207,2,228,228,228, + 1,208,208,208,1,240,240,240,1,207,207,207,2,234,234,234,1,213,213,213, + 1,207,207,207,1,239,239,239,1,236,236,236,1,209,209,209,1,207,207,207, + 5,195,195,195,1,207,207,207,3,222,222,222,1,224,224,224,1,207,207,207, + 4,247,247,247,1,233,233,233,2,245,245,245,1,213,213,213,1,214,214,214, + 1,233,233,233,1,225,225,225,1,222,222,222,1,207,207,207,5,195,195,195, + 1,207,207,207,3,223,223,223,2,207,207,207,4,244,244,244,1,222,222,222, + 2,241,241,241,1,213,213,213,1,227,227,227,1,230,230,230,1,224,224,224, + 1,236,236,236,1,207,207,207,5,195,195,195,1,207,207,207,3,217,217,217, + 1,230,230,230,1,207,207,207,2,231,231,231,1,209,209,209,1,240,240,240, + 1,207,207,207,2,234,234,234,1,213,213,213,1,238,238,238,1,234,234,234, + 2,245,245,245,1,207,207,207,5,195,195,195,1,207,207,207,3,208,208,208, + 1,243,243,243,1,214,214,214,1,216,216,216,1,240,240,240,1,207,207,207, + 1,240,240,240,1,207,207,207,2,234,234,234,1,213,213,213,1,240,240,240, + 1,207,207,207,2,234,234,234,1,216,216,216,1,207,207,207,4,195,195,195, + 1,207,207,207,4,217,217,217,1,240,240,240,1,239,239,239,1,214,214,214, + 1,207,207,207,1,232,232,232,1,207,207,207,2,227,227,227,1,218,218,218, + 1,226,226,226,1,207,207,207,2,219,219,219,1,223,223,223,1,207,207,207, + 4,195,195,195,1,207,207,207,23,195,195,195,1,207,207,207,23,183,183,183, + 1,195,195,195,23,0,0) + ); + +const + objdata_tasynsercommchannel: record size: integer; data: array[0..2246] of byte end = + (size: 2247; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,97,115, + 121,110,115,101,114,99,111,109,109,99,104,97,110,110,101,108,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,72,8,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,20,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,255,187, + 75,23,223,164,1,8,77,57,1,26,255,187,2,24,237,174,1,6,67,49, + 1,4,43,31,1,16,161,118,1,23,231,169,1,10,101,74,1,26,255,187, + 2,13,138,101,1,19,189,139,1,7,76,55,1,25,246,181,1,26,255,187, + 1,15,150,110,1,21,210,154,1,26,255,187,5,15,146,108,1,5,50,37, + 1,23,226,166,1,26,255,187,1,12,117,85,1,16,161,118,1,23,230,168, + 1,4,46,33,1,26,249,183,1,8,76,56,1,21,210,154,1,25,246,181, + 1,6,57,42,1,26,253,186,1,2,23,17,1,15,139,103,1,26,255,187, + 1,12,124,91,1,20,197,145,1,26,255,187,5,9,83,61,1,16,160,118, + 1,15,144,107,1,26,255,187,1,11,105,77,1,19,180,133,1,26,255,187, + 1,20,201,148,1,24,244,179,1,20,198,145,1,9,90,66,1,15,142,104, + 1,16,154,113,1,26,255,187,1,7,71,52,1,5,55,40,1,26,250,184, + 1,12,124,91,1,20,197,145,1,26,255,187,4,26,254,186,1,7,71,52, + 1,24,243,178,1,8,77,57,1,26,255,187,1,22,218,160,1,3,31,23, + 1,6,66,48,1,19,187,137,1,26,255,187,2,7,73,53,1,6,67,49, + 1,26,253,186,1,26,255,187,1,7,76,55,1,13,133,97,1,15,150,110, + 1,12,124,91,1,20,197,145,1,26,255,187,4,20,198,145,1,5,47,34, + 1,11,114,84,1,3,31,23,1,26,249,183,1,26,255,187,1,26,251,184, + 1,17,166,122,1,4,40,30,1,23,225,165,1,26,255,187,1,16,162,119, + 1,13,127,92,1,26,255,187,2,7,76,55,1,24,244,179,1,5,54,40, + 1,12,122,89,1,20,197,145,1,26,255,187,4,12,125,91,1,13,129,95, + 1,16,163,119,1,9,86,62,1,19,178,132,1,9,91,66,1,26,255,187, + 2,13,138,101,1,19,178,132,1,26,255,187,1,17,174,128,1,13,137,100, + 1,26,255,187,2,7,76,55,1,26,255,187,1,12,121,89,1,4,46,33, + 1,20,197,145,1,26,255,187,4,7,69,51,1,26,249,183,1,26,255,187, + 1,20,193,141,1,10,101,74,1,12,124,91,1,10,91,67,1,16,163,119, + 1,6,57,42,1,24,234,172,1,26,255,187,1,17,174,128,1,13,137,100, + 1,26,255,187,2,7,76,55,1,26,255,187,1,24,237,174,1,1,12,9, + 1,20,197,145,1,26,255,187,4,16,151,112,1,26,255,187,2,26,253,186, + 1,15,146,108,1,26,254,186,1,15,140,103,1,10,101,74,1,20,195,143, + 1,26,255,187,2,21,213,156,1,20,194,142,1,26,255,187,2,16,159,117, + 1,26,255,187,2,16,161,118,1,23,226,166,1,26,255,187,55,24,233,171, + 1,12,122,90,1,12,125,91,1,24,237,174,1,26,255,187,1,15,150,110, + 1,26,255,187,2,17,167,123,1,24,236,172,1,26,255,187,1,20,193,141, + 1,17,176,129,1,26,255,187,11,7,74,54,1,15,140,103,1,15,143,105, + 1,9,84,61,1,26,255,187,1,7,68,50,1,26,255,187,2,10,98,72, + 1,22,218,160,1,26,255,187,1,10,95,69,1,9,83,61,1,26,255,187, + 10,20,203,149,1,10,102,76,1,26,255,187,2,13,129,95,1,26,251,184, + 1,7,68,50,1,26,255,187,2,10,98,72,1,22,218,160,1,26,255,187, + 1,7,74,54,1,9,88,65,1,24,240,177,1,26,255,187,9,16,162,119, + 1,16,154,113,1,26,255,187,4,4,38,28,1,11,106,78,2,4,44,32, + 1,22,218,160,1,21,212,156,1,11,104,77,1,15,147,108,1,16,163,119, + 1,26,255,187,9,16,156,114,1,16,157,115,1,26,255,187,4,5,50,37, + 1,16,163,119,2,6,66,48,1,22,218,160,1,13,137,100,1,12,119,88, + 1,16,153,112,1,9,89,65,1,26,255,187,9,19,190,140,1,12,120,88, + 1,26,255,187,2,12,116,85,1,24,244,179,1,7,68,50,1,26,255,187, + 2,10,98,72,1,22,218,160,1,8,76,56,1,10,98,72,2,4,45,33, + 1,26,255,187,9,26,249,183,1,5,55,40,1,21,213,156,1,20,196,144, + 1,7,69,51,1,26,255,187,1,7,68,50,1,26,255,187,2,10,98,72, + 1,22,214,158,1,7,68,50,1,26,255,187,2,10,97,72,1,20,198,145, + 1,26,255,187,9,20,194,142,1,7,69,51,1,7,75,54,1,21,209,154, + 1,26,255,187,1,11,110,80,1,26,255,187,2,13,134,99,1,19,189,139, + 1,15,142,104,1,26,255,187,2,19,182,133,1,16,158,115,1,26,255,187, + 76,252,3,0,0,207,207,207,75,212,212,212,1,238,238,238,1,207,207,207, + 2,210,210,210,1,240,240,240,1,246,246,246,1,222,222,222,1,211,211,211, + 1,234,234,234,1,207,207,207,2,227,227,227,1,218,218,218,1,239,239,239, + 1,208,208,208,1,207,207,207,1,224,224,224,1,214,214,214,1,207,207,207, + 5,225,225,225,1,244,244,244,1,212,212,212,1,207,207,207,1,231,231,231, + 1,222,222,222,1,211,211,211,1,245,245,245,1,208,208,208,1,238,238,238, + 1,214,214,214,1,208,208,208,1,242,242,242,1,207,207,207,1,250,250,250, + 1,226,226,226,1,207,207,207,1,229,229,229,1,216,216,216,1,207,207,207, + 5,237,237,237,1,223,223,223,1,225,225,225,1,207,207,207,1,233,233,233, + 1,219,219,219,1,207,207,207,1,216,216,216,1,209,209,209,1,216,216,216, + 1,236,236,236,1,226,226,226,1,224,224,224,1,207,207,207,1,240,240,240, + 1,243,243,243,1,208,208,208,1,229,229,229,1,216,216,216,1,207,207,207, + 5,240,240,240,1,209,209,209,1,238,238,238,1,207,207,207,1,213,213,213, + 1,248,248,248,1,241,241,241,1,218,218,218,1,207,207,207,2,239,239,239, + 1,241,241,241,1,207,207,207,2,239,239,239,1,228,228,228,1,225,225,225, + 1,229,229,229,1,216,216,216,1,207,207,207,4,216,216,216,1,245,245,245, + 1,231,231,231,1,248,248,248,1,208,208,208,1,207,207,207,1,208,208,208, + 1,221,221,221,1,246,246,246,1,212,212,212,1,207,207,207,1,222,222,222, + 1,229,229,229,1,207,207,207,2,239,239,239,1,209,209,209,1,243,243,243, + 1,230,230,230,1,216,216,216,1,207,207,207,4,229,229,229,1,228,228,228, + 1,222,222,222,1,237,237,237,1,219,219,219,1,236,236,236,1,207,207,207, + 2,227,227,227,1,219,219,219,1,207,207,207,1,220,220,220,1,227,227,227, + 1,207,207,207,2,239,239,239,1,207,207,207,1,230,230,230,1,245,245,245, + 1,216,216,216,1,207,207,207,4,240,240,240,1,208,208,208,1,207,207,207, + 1,217,217,217,1,234,234,234,1,229,229,229,1,235,235,235,1,222,222,222, + 1,242,242,242,1,210,210,210,1,207,207,207,1,220,220,220,1,227,227,227, + 1,207,207,207,2,239,239,239,1,207,207,207,1,210,210,210,1,252,252,252, + 1,216,216,216,1,207,207,207,4,224,224,224,1,207,207,207,3,225,225,225, + 1,207,207,207,1,226,226,226,1,234,234,234,1,217,217,217,1,207,207,207, + 2,214,214,214,1,217,217,217,1,207,207,207,2,223,223,223,1,207,207,207, + 2,222,222,222,1,212,212,212,1,207,207,207,55,210,210,210,1,229,229,229, + 2,210,210,210,1,207,207,207,1,225,225,225,1,207,207,207,2,221,221,221, + 1,210,210,210,1,207,207,207,1,217,217,217,1,220,220,220,1,207,207,207, + 11,239,239,239,1,226,226,226,2,237,237,237,1,207,207,207,1,240,240,240, + 1,207,207,207,2,234,234,234,1,213,213,213,1,207,207,207,1,235,235,235, + 1,237,237,237,1,207,207,207,10,215,215,215,1,233,233,233,1,207,207,207, + 2,228,228,228,1,208,208,208,1,240,240,240,1,207,207,207,2,234,234,234, + 1,213,213,213,1,207,207,207,1,239,239,239,1,236,236,236,1,209,209,209, + 1,207,207,207,9,222,222,222,1,224,224,224,1,207,207,207,4,247,247,247, + 1,233,233,233,2,245,245,245,1,213,213,213,1,214,214,214,1,233,233,233, + 1,225,225,225,1,222,222,222,1,207,207,207,9,223,223,223,2,207,207,207, + 4,244,244,244,1,222,222,222,2,241,241,241,1,213,213,213,1,227,227,227, + 1,230,230,230,1,224,224,224,1,236,236,236,1,207,207,207,9,217,217,217, + 1,230,230,230,1,207,207,207,2,231,231,231,1,209,209,209,1,240,240,240, + 1,207,207,207,2,234,234,234,1,213,213,213,1,238,238,238,1,234,234,234, + 2,245,245,245,1,207,207,207,9,208,208,208,1,243,243,243,1,214,214,214, + 1,216,216,216,1,240,240,240,1,207,207,207,1,240,240,240,1,207,207,207, + 2,234,234,234,1,213,213,213,1,240,240,240,1,207,207,207,2,234,234,234, + 1,216,216,216,1,207,207,207,9,217,217,217,1,240,240,240,1,239,239,239, + 1,214,214,214,1,207,207,207,1,232,232,232,1,207,207,207,2,227,227,227, + 1,218,218,218,1,226,226,226,1,207,207,207,2,219,219,219,1,223,223,223, + 1,207,207,207,76,0,0) + ); + +initialization + registerobjectdata(@objdata_tcommport,tbitmapcomp,'tcommport'); + registerobjectdata(@objdata_tasciicommport,tbitmapcomp,'tasciicommport'); + registerobjectdata(@objdata_tasciiprotport,tbitmapcomp,'tasciiprotport'); + registerobjectdata(@objdata_tcommselector,tbitmapcomp,'tcommselector'); + registerobjectdata(@objdata_tsercommcomp,tbitmapcomp,'tsercommcomp'); + registerobjectdata(@objdata_tsercommchannel,tbitmapcomp,'tsercommchannel'); + registerobjectdata(@objdata_tasynsercommchannel,tbitmapcomp,'tasynsercommchannel'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regsysutils.pas b/mseide-msegui/lib/common/regcomponents/regsysutils.pas new file mode 100644 index 0000000..ec23168 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regsysutils.pas @@ -0,0 +1,185 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regsysutils; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + msedesignintf,msesysenv,msefilechange,regsysutils_bmp,mseprocess, + msecomponenteditors,msepython, + msetypes{msestrings},msetexteditor, + sysutils,mclasses,msesysenvmanagereditor,mseglob,msepropertyeditors; +type + tarrayelementeditor1 = class(tarrayelementeditor); + + tsysenvmanagereditor = class(tcomponenteditor) + public + constructor create(const adesigner: idesigner; + acomponent: tcomponent); override; + procedure edit; override; + end; + + tprocessoptionseditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + tpythonscriptseditor = class(tpersistentarraypropertyeditor) + protected + function itemgetvalue(const sender: tarrayelementeditor): msestring + override; + end; + + tpythonpropertyeditor = class(ttextstringspropertyeditor) + private +// factivebefore: boolean; +// fdbactivebefore: boolean; +// fintf: isqlpropertyeditor; + protected +// function nocheck: boolean; virtual; + function getsyntaxindex: integer; override; +// procedure doafterclosequery(var amodalresult: modalresultty); override; +// function gettestbutton: boolean; override; +// function getutf8: boolean; override; + function getcaption: msestring; override; + function ismsestring: boolean; override; + public +// procedure edit; override; + end; + +procedure Register; +begin + registercomponents('NoGui',[tsysenvmanager,tfilechangenotifyer,tmseprocess, + tpythonscript]); + registercomponenteditor(tsysenvmanager,tsysenvmanagereditor); + registerpropertyeditor(typeinfo(processoptionsty),nil,'', + tprocessoptionseditor); + registerpropertyeditor(typeinfo(tpythonscripts),nil,'', + tpythonscriptseditor); + registerpropertyeditor(typeinfo(tpythonstringlist),nil,'', + tpythonpropertyeditor); +end; + +{ tsysenvmanagereditor } + +constructor tsysenvmanagereditor.create(const adesigner: idesigner; + acomponent: tcomponent); +begin + inherited; + fstate:= fstate + [cs_canedit]; +end; + +procedure tsysenvmanagereditor.edit; +begin + if editsysenvmanager(tsysenvmanager(fcomponent)) = mr_ok then begin + fdesigner.componentmodified(fcomponent); + end; +end; + +{ tprocessoptionseditor } + +function tprocessoptionseditor.getinvisibleitems: tintegerset; +begin + result:= [ord(pro_nopipeterminate)]; +end; + +{ tpythonscriptseditor } + +function tpythonscriptseditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + with tpythonstringlistitem( + tarrayelementeditor1(sender).getpointervalue) do begin + result:= '<'+name+'>'; + end; +end; + +{ tpythonpropertyeditor } + +const + pythonsyntax = +'styles'+lineend+ +' default '''''+lineend+ +' words ''b'''+lineend+ +' comment ''i'' cl_dkblue'+lineend+ +' option ''b'' cl_dkblue'+lineend+ +' string '''' cl_dkblue'+lineend+ +' '+lineend+ +'keyworddefs python'+lineend+ +' ''False'' ''class'' ''finally'' ''is'' ''return'''+lineend+ +' ''None'' ''continue'' ''for'' ''lambda'' ''try'''+lineend+ +' ''True'' ''def'' ''from'' ''nonlocal'' ''while'''+lineend+ +' ''and'' ''del'' ''global'' ''not'' ''with'''+lineend+ +' ''as'' ''elif'' ''if'' ''or'' ''yield'''+lineend+ +' ''assert'' ''else'' ''import'' ''pass'''+lineend+ +' ''break'' ''except'' ''in'' ''raise'''+lineend+ +''+lineend+ +'scope comment1 comment'+lineend+ +' endtokens'+lineend+ +' '''''+lineend+ +'scope string1 string'+lineend+ +' endtokens'+lineend+ +' '''''''' '''''+lineend+ +'scope string2 string'+lineend+ +' endtokens'+lineend+ +' ''"'' '''''+lineend+ +'scope string3 string'+lineend+ +' endtokens'+lineend+ +' '''''''''''''''''+lineend+ +'scope string4 string'+lineend+ +' endtokens'+lineend+ +' ''"""'''+lineend+ +' '+lineend+ +'scope main'+lineend+ +''+lineend+ +' keywords words'+lineend+ +' python'+lineend+ +' calltokens'+lineend+ +' ''#'' comment1'+lineend+ +' '''''''''''''''' string3'+lineend+ +' '''''''' string1'+lineend+ +' ''"""'' string4'+lineend+ +' ''"'' string2'+lineend+ +''; + +var + pythonindex: integer = -1; + +function tpythonpropertyeditor.getsyntaxindex: integer; +begin + if pythonindex < 0 then begin + pythonindex:= msetexteditor.syntaxpainter.readdeffile(pythonsyntax); + end; + result:= pythonindex; +end; + +function tpythonpropertyeditor.getcaption: msestring; +begin + result:= 'Python Editor'; +end; + +function tpythonpropertyeditor.ismsestring: boolean; +begin + result:= true; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regsysutils_bmp.pas b/mseide-msegui/lib/common/regcomponents/regsysutils_bmp.pas new file mode 100644 index 0000000..aa2ee7c --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regsysutils_bmp.pas @@ -0,0 +1,558 @@ +unit regsysutils_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tsysenvmanager: record size: integer; data: array[0..2865] of byte end = + (size: 2866; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,121, + 115,101,110,118,109,97,110,97,103,101,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,232,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,1,7,6,5,1, + 22,18,17,1,225,185,181,1,226,188,183,1,141,118,115,1,7,6,6,2, + 60,51,50,1,231,198,195,1,232,201,197,1,84,73,72,1,7,6,6,2, + 113,100,99,1,236,211,208,1,237,213,210,1,37,33,33,1,7,7,7,2, + 203,187,185,1,242,224,222,1,230,214,212,1,4,4,3,1,148,119,116,1, + 223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1, + 228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1, + 232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1, + 237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1, + 242,224,222,1,243,226,224,1,7,7,7,1,223,180,175,1,223,181,176,1, + 224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1, + 229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1, + 233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1, + 238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1, + 243,226,224,1,28,27,26,1,223,180,175,1,223,181,176,1,224,183,179,1, + 225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1, + 230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1, + 234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1, + 239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1, + 243,228,226,1,18,15,14,1,223,181,176,1,224,183,179,1,225,185,181,1, + 226,188,183,1,0,0,0,1,89,75,74,1,15,13,13,1,157,134,131,1, + 231,198,195,1,232,201,197,1,162,142,139,1,25,22,21,1,10,9,9,1, + 125,111,110,1,236,211,208,1,237,213,210,1,0,0,0,1,67,61,60,1, + 240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,243,228,226,1, + 7,5,5,1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1, + 0,0,0,1,156,132,129,1,161,136,133,1,33,28,28,1,231,198,195,1, + 232,201,197,1,226,197,194,1,204,179,176,1,202,179,176,1,13,11,11,1, + 236,211,208,1,237,213,210,1,0,0,0,1,200,182,180,1,240,220,217,1, + 241,222,220,1,242,224,222,1,243,226,224,1,133,125,123,1,14,11,11,1, + 0,0,0,2,225,185,181,1,226,188,183,1,0,0,0,1,223,187,184,1, + 223,189,185,1,5,4,4,1,231,198,195,1,232,201,197,1,161,141,138,1, + 69,61,60,1,28,25,25,1,0,0,0,1,236,211,208,1,237,213,210,1, + 0,0,0,1,238,217,214,1,240,220,217,1,241,222,220,1,242,224,222,1, + 243,226,224,1,7,7,7,1,223,180,175,1,223,181,176,1,224,183,179,1, + 225,185,181,1,226,188,183,1,0,0,0,1,164,138,135,1,162,137,134,1, + 37,32,31,1,231,198,195,1,232,201,197,1,12,10,10,1,161,141,139,1, + 162,144,142,1,0,0,0,1,236,211,208,1,237,213,210,1,0,0,0,1, + 239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1, + 7,7,7,1,223,180,175,1,223,181,176,1,224,183,179,1,225,185,181,1, + 226,188,183,1,0,0,0,1,72,60,59,1,20,17,16,1,166,141,139,1, + 231,198,195,1,232,201,197,1,86,75,73,1,7,6,6,1,103,91,90,1, + 0,0,0,1,236,211,208,1,237,213,210,1,0,0,0,1,239,218,215,1, + 240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,75,70,70,1, + 156,126,123,1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1, + 0,0,0,1,228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1, + 232,201,197,1,232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1, + 236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1, + 241,222,220,1,242,224,222,1,243,226,224,1,243,228,226,1,7,5,5,1, + 223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1,0,0,0,1, + 228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1, + 232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1, + 237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1, + 242,224,222,1,243,226,224,1,243,228,226,1,7,5,5,1,223,181,176,1, + 224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1, + 229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1, + 233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1, + 238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1, + 243,226,224,1,75,70,70,1,48,39,38,1,152,124,120,1,4,4,4,1, + 0,0,0,1,29,24,24,1,171,143,139,1,228,192,188,1,229,194,190,1, + 230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1, + 234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1, + 239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1, + 7,7,7,1,223,180,175,1,4,4,3,1,140,114,112,1,0,0,0,1, + 164,136,133,1,34,28,28,1,228,192,188,1,229,194,190,1,230,196,192,1, + 231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204,1, + 235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1, + 240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,7,7,7,1, + 223,180,175,1,62,50,49,1,43,35,34,1,0,0,0,1,185,154,150,1, + 227,190,185,1,228,192,188,1,229,194,190,1,168,143,140,1,23,19,19,1, + 23,20,19,1,177,155,152,1,233,205,201,1,234,207,204,1,0,0,0,1, + 72,65,64,1,7,7,7,1,162,147,145,1,239,218,215,1,47,43,43,1, + 195,179,178,1,242,224,222,1,196,183,181,1,26,24,24,1,93,75,73,1, + 216,175,170,1,127,104,102,1,0,0,0,1,13,11,11,1,113,95,92,1, + 228,192,188,1,229,194,190,1,35,30,29,1,176,151,148,1,179,155,152,1, + 45,40,39,1,233,205,201,1,234,207,204,1,0,0,0,1,168,151,148,1, + 162,145,143,1,5,4,4,1,239,218,215,1,142,130,128,1,102,94,93,1, + 242,224,222,1,104,97,96,1,142,133,132,1,7,5,5,1,223,181,176,1, + 224,183,179,1,0,0,0,1,186,155,151,1,0,0,0,1,228,192,188,1, + 229,194,190,1,3,2,2,1,0,0,0,2,4,3,3,1,233,205,201,1, + 234,207,204,1,0,0,0,1,235,210,207,1,237,213,210,1,0,0,0,1, + 239,218,215,1,228,209,206,1,26,24,24,1,229,212,210,1,27,25,25,1, + 228,214,212,1,7,5,5,1,24,20,19,1,165,135,132,1,0,0,0,1, + 154,128,125,1,4,4,4,1,228,192,188,1,229,194,190,1,31,26,26,1, + 177,151,149,1,200,173,170,1,232,203,199,1,233,205,201,1,234,207,204,1, + 0,0,0,1,236,211,208,1,237,213,210,1,0,0,0,1,239,218,215,1, + 240,220,217,1,93,85,85,1,83,76,76,1,87,81,80,1,28,27,26,1, + 100,81,79,1,154,125,121,1,24,19,19,1,0,0,0,1,11,9,9,1, + 159,133,130,1,228,192,188,1,229,194,190,1,161,138,135,1,21,18,18,1, + 0,0,0,1,53,46,45,1,233,205,201,1,234,207,204,1,0,0,0,1, + 236,211,208,1,237,213,210,1,0,0,0,1,239,218,215,1,240,220,217,1, + 189,174,173,1,0,0,0,1,181,168,167,1,7,7,7,1,223,180,175,1, + 223,181,176,1,224,183,179,1,0,0,0,1,226,188,183,1,227,190,185,1, + 228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1, + 232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1, + 237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1, + 242,224,222,1,243,226,224,1,7,7,7,1,223,180,175,1,223,181,176,1, + 224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1, + 229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1, + 233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1, + 238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1, + 243,226,224,1,230,216,214,1,43,35,34,1,223,181,176,1,224,183,179,1, + 225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1, + 230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1, + 234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1, + 239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1, + 243,228,226,1,7,5,5,1,223,181,176,1,224,183,179,1,225,185,181,1, + 226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1,230,196,192,1, + 231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204,1, + 235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1, + 240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,205,192,190,1, + 3,3,3,1,167,135,132,1,224,183,179,1,225,185,181,1,11,9,9,1, + 7,6,6,1,22,19,18,1,229,194,190,1,230,196,192,1,143,123,121,1, + 7,6,6,2,61,53,52,1,234,207,204,1,235,209,206,1,85,76,75,1, + 7,6,6,1,7,7,6,1,115,104,103,1,240,220,217,1,241,222,220,1, + 37,35,34,1,7,7,7,1,4,4,3,1,152,1,0,0,244,244,244,1, + 248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2, + 203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1, + 128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1, + 131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22, + 128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1, + 210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,238,238,238,1,180,180,180,1, + 255,255,255,22,181,181,181,1,248,248,248,1,255,255,255,22,136,136,136,1, + 248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1, + 128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2, + 158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1, + 248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1, + 244,244,244,1,0,0) + ); + +const + objdata_tmseprocess: record size: integer; data: array[0..2858] of byte end = + (size: 2859; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,109,115, + 101,112,114,111,99,101,115,115,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,180,10,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,232,8,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,1,3,3,3,1,19,16,15, + 1,225,185,181,1,226,188,183,1,142,119,115,1,3,3,3,2,59,50,49, + 1,231,198,195,1,232,201,197,1,84,73,72,1,3,3,3,2,113,101,99, + 1,236,211,208,1,237,213,210,1,39,36,35,1,4,3,3,2,191,176,175, + 1,242,224,222,1,231,215,213,1,0,0,0,1,158,127,124,1,223,181,176, + 1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188, + 1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199, + 1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210, + 1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222, + 1,243,226,224,1,4,3,3,1,223,180,175,1,223,181,176,1,224,183,179, + 1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190, + 1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201, + 1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213, + 1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224, + 1,30,29,28,1,223,180,175,1,223,181,176,1,224,183,179,1,225,185,181, + 1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1,230,196,192, + 1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204, + 1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215, + 1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,243,228,226, + 1,11,9,9,1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183, + 1,227,190,185,1,228,192,188,1,229,194,190,1,230,196,192,1,231,198,195, + 1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204,1,235,209,206, + 1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1,240,220,217, + 1,241,222,220,1,242,224,222,1,243,226,224,1,243,228,226,1,3,3,3, + 1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185, + 1,228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197, + 1,232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208, + 1,237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220, + 1,242,224,222,1,243,226,224,1,134,126,125,1,11,9,9,1,223,181,176, + 1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188, + 1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199, + 1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210, + 1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222, + 1,243,226,224,1,4,3,3,1,223,180,175,1,223,181,176,1,219,179,175, + 1,218,179,175,1,220,183,178,1,226,189,184,1,228,192,188,1,229,194,190, + 1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201, + 1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213, + 1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224, + 1,4,3,3,1,223,180,175,1,223,181,176,1,42,34,34,1,35,29,28, + 1,42,35,34,1,36,30,29,1,47,40,39,1,198,168,165,1,230,196,192, + 1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204, + 1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215, + 1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,75,70,70, + 1,158,127,124,1,223,181,176,1,42,34,34,1,190,156,153,1,226,188,183, + 1,227,190,185,1,121,102,100,1,85,72,71,1,229,195,191,1,226,194,191, + 1,218,189,185,1,229,201,197,1,233,205,201,1,234,207,204,1,220,196,193, + 1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1,232,213,210, + 1,229,211,209,1,242,224,222,1,243,226,224,1,243,228,226,1,3,3,3, + 1,223,181,176,1,42,34,34,1,190,156,153,1,226,188,183,1,227,190,185, + 1,136,114,112,1,94,80,78,1,199,170,166,1,42,36,35,1,36,32,31, + 1,110,96,94,1,175,154,151,1,53,47,46,1,70,62,61,1,71,64,63, + 1,206,185,183,1,238,216,213,1,128,117,116,1,43,40,39,1,69,64,63, + 1,113,105,104,1,243,226,224,1,243,228,226,1,3,3,3,1,223,181,176, + 1,42,34,34,1,83,68,67,1,98,82,80,1,72,60,59,1,46,39,38, + 1,186,157,154,1,199,170,166,1,15,13,13,1,224,194,190,1,232,203,199, + 1,34,30,29,1,191,169,166,1,235,209,206,1,149,133,131,1,112,100,99, + 1,213,193,190,1,25,23,23,1,239,219,216,1,241,222,220,1,115,106,105, + 1,235,219,217,1,75,70,70,1,47,38,37,1,223,181,176,1,42,34,34, + 1,136,112,109,1,162,135,131,1,195,163,159,1,228,192,188,1,229,194,190, + 1,199,170,166,1,49,42,41,1,232,201,197,1,229,201,197,1,19,17,17, + 1,234,207,204,1,235,209,206,1,213,190,188,1,43,38,38,1,175,159,157, + 1,82,74,73,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224, + 1,4,3,3,1,223,180,175,1,223,181,176,1,42,34,34,1,190,156,153, + 1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1,199,170,166, + 1,53,45,44,1,232,201,197,1,232,203,199,1,58,51,50,1,207,183,181, + 1,235,209,206,1,167,149,147,1,71,63,63,1,224,203,200,1,48,44,43, + 1,240,220,217,1,241,222,220,1,121,112,111,1,225,209,207,1,4,3,3, + 1,223,180,175,1,223,181,176,1,42,34,34,1,190,156,153,1,226,188,183, + 1,227,190,185,1,228,192,188,1,229,194,190,1,199,170,166,1,53,45,44, + 1,232,201,197,1,232,203,199,1,154,136,133,1,58,51,50,1,120,107,105, + 1,38,34,33,1,176,158,156,1,238,216,213,1,97,89,88,1,93,85,84, + 1,111,102,101,1,79,73,72,1,243,226,224,1,134,126,125,1,94,76,74, + 1,223,181,176,1,179,146,143,1,216,178,174,1,226,188,183,1,227,190,185, + 1,228,192,188,1,229,194,190,1,223,190,186,1,187,160,158,1,232,201,197, + 1,232,203,199,1,233,205,201,1,222,196,194,1,166,148,145,1,216,193,190, + 1,237,213,210,1,238,216,213,1,239,218,215,1,206,189,186,1,188,173,172, + 1,242,224,222,1,243,226,224,1,243,228,226,1,3,3,3,1,223,181,176, + 1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188, + 1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199, + 1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210, + 1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222, + 1,243,226,224,1,243,228,226,1,3,3,3,1,223,181,176,1,224,183,179, + 1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190, + 1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201, + 1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213, + 1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224, + 1,30,29,28,1,94,76,74,1,223,181,176,1,224,183,179,1,225,185,181, + 1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1,230,196,192, + 1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204, + 1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215, + 1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,4,3,3, + 1,223,180,175,1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183, + 1,227,190,185,1,228,192,188,1,229,194,190,1,230,196,192,1,231,198,195, + 1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204,1,235,209,206, + 1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1,240,220,217, + 1,241,222,220,1,242,224,222,1,243,226,224,1,4,3,3,1,223,180,175, + 1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185, + 1,228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197, + 1,232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208, + 1,237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220, + 1,242,224,222,1,243,226,224,1,218,204,202,1,47,38,37,1,223,181,176, + 1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188, + 1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199, + 1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210, + 1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222, + 1,243,226,224,1,243,228,226,1,3,3,3,1,223,181,176,1,224,183,179, + 1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190, + 1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201, + 1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213, + 1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224, + 1,218,204,202,1,0,0,0,1,177,144,140,1,224,183,179,1,225,185,181, + 1,3,3,3,2,19,16,16,1,229,194,190,1,230,196,192,1,144,124,122, + 1,3,3,3,2,60,52,51,1,234,207,204,1,235,209,206,1,85,76,75, + 1,4,3,3,2,115,105,104,1,240,220,217,1,241,222,220,1,40,37,37, + 1,4,3,3,1,0,0,0,1,148,1,0,0,255,255,255,1,252,252,252, + 1,237,237,237,1,136,136,136,2,165,165,165,1,252,252,252,2,208,208,208, + 1,136,136,136,2,194,194,194,1,252,252,252,2,179,179,179,1,136,136,136, + 2,223,223,223,1,252,252,252,2,150,150,150,1,136,136,136,1,139,139,139, + 1,255,255,255,1,157,157,157,1,255,255,255,22,252,252,252,1,136,136,136, + 1,255,255,255,22,230,230,230,1,136,136,136,1,255,255,255,22,136,136,136, + 1,244,244,244,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255, + 22,172,172,172,1,244,244,244,1,255,255,255,22,252,252,252,1,136,136,136, + 1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,201,201,201, + 1,157,157,157,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255, + 22,136,136,136,1,252,252,252,1,255,255,255,22,201,201,201,1,215,215,215, + 1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,252,252,252, + 1,136,136,136,1,255,255,255,22,172,172,172,1,186,186,186,1,255,255,255, + 22,136,136,136,1,252,252,252,1,255,255,255,22,136,136,136,1,252,252,252, + 1,255,255,255,22,230,230,230,1,186,186,186,1,255,255,255,22,252,252,252, + 1,136,136,136,1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255, + 22,143,143,143,1,215,215,215,1,255,255,255,22,136,136,136,1,252,252,252, + 1,255,255,255,22,143,143,143,1,255,255,255,1,150,150,150,1,136,136,136, + 2,252,252,252,2,237,237,237,1,136,136,136,2,165,165,165,1,252,252,252, + 2,208,208,208,1,136,136,136,2,194,194,194,1,252,252,252,2,179,179,179, + 1,136,136,136,2,223,223,223,1,252,252,252,1,255,255,255,1,0,0) + ); + +const + objdata_tpythonscript: record size: integer; data: array[0..2868] of byte end = + (size: 2869; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,112,121, + 116,104,111,110,115,99,114,105,112,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,2,2,2,1,5,4,4,1,18, + 15,15,1,225,185,181,1,225,187,183,1,143,119,115,1,5,4,4,2,58, + 50,49,1,231,199,195,1,231,201,197,1,82,72,70,1,5,4,4,2,116, + 103,101,1,237,211,209,1,237,213,211,1,37,33,33,1,5,5,5,2,204, + 185,185,1,241,225,221,1,228,213,211,1,3,2,2,1,150,120,117,1,224, + 182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228, + 192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233, + 203,200,1,234,205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238, + 214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242, + 225,222,1,243,227,225,1,5,5,5,1,223,179,175,1,224,182,177,1,225, + 184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,229, + 195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233,203,200,1,234, + 205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238, + 216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243, + 227,225,1,28,27,27,1,223,179,175,1,224,182,177,1,225,184,179,1,226, + 186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,229,195,190,1,230, + 197,193,1,231,199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235, + 207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238,216,213,1,239, + 218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,243, + 229,227,1,15,12,12,1,224,182,177,1,225,184,179,1,226,186,181,1,226, + 188,184,1,227,190,186,1,228,192,188,1,229,195,190,1,230,197,193,1,231, + 199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,236, + 210,206,1,237,212,209,1,238,214,211,1,238,216,213,1,239,218,216,1,240, + 220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,243,229,227,1,5, + 4,4,1,224,182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227, + 190,186,1,228,192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232, + 201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,236,210,206,1,237, + 212,209,1,238,214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241, + 222,220,1,242,225,222,1,243,227,225,1,135,128,126,1,12,9,9,1,224, + 182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228, + 192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233, + 203,200,1,234,205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238, + 214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242, + 225,222,1,243,227,225,1,5,5,5,1,223,179,175,1,224,182,177,1,225, + 184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,191, + 163,159,1,184,158,154,1,185,159,156,1,202,175,172,1,233,203,200,1,234, + 205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238, + 216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243, + 227,225,1,5,5,5,1,223,179,175,1,224,182,177,1,225,184,179,1,226, + 186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,42,36,35,1,93, + 80,78,1,107,92,90,1,67,58,57,1,71,62,61,1,230,202,199,1,235, + 207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238,216,213,1,239, + 218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,72, + 69,67,1,158,126,124,1,224,182,177,1,225,184,179,1,226,186,181,1,226, + 188,184,1,227,190,186,1,228,192,188,1,42,36,35,1,198,170,167,1,231, + 199,195,1,232,201,197,1,69,60,59,1,161,141,139,1,148,131,129,1,236, + 210,206,1,237,212,209,1,181,163,161,1,202,183,180,1,239,218,216,1,240, + 220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,243,229,227,1,5, + 4,4,1,224,182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227, + 190,186,1,228,192,188,1,42,36,35,1,198,170,167,1,231,199,195,1,232, + 201,197,1,69,60,59,1,168,147,145,1,41,37,36,1,199,177,174,1,237, + 212,209,1,45,40,40,1,205,186,184,1,239,218,216,1,240,220,218,1,241, + 222,220,1,242,225,222,1,243,227,225,1,243,229,227,1,5,4,4,1,224, + 182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228, + 192,188,1,42,36,35,1,79,68,67,1,92,80,78,1,60,52,51,1,73, + 64,63,1,230,202,199,1,126,111,110,1,120,107,105,1,207,185,183,1,51, + 46,46,1,238,216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242, + 225,222,1,243,227,225,1,72,69,67,1,47,37,37,1,224,182,177,1,225, + 184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,42, + 36,35,1,159,136,133,1,187,161,158,1,213,184,181,1,233,203,200,1,234, + 205,202,1,209,184,182,1,44,40,39,1,134,120,118,1,133,120,118,1,238, + 216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243, + 227,225,1,5,5,5,1,223,179,175,1,224,182,177,1,225,184,179,1,226, + 186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,42,36,35,1,198, + 170,167,1,231,199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235, + 207,204,1,61,54,53,1,35,32,31,1,214,192,189,1,238,216,213,1,239, + 218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,5, + 5,5,1,223,179,175,1,224,182,177,1,225,184,179,1,226,186,181,1,226, + 188,184,1,227,190,186,1,228,192,188,1,42,36,35,1,198,170,167,1,231, + 199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,145, + 129,127,1,60,54,53,1,238,214,211,1,238,216,213,1,239,218,216,1,240, + 220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,135,128,126,1,90, + 73,70,1,224,182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227, + 190,186,1,228,192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232, + 201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,127,113,111,1,144, + 129,127,1,238,214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241, + 222,220,1,242,225,222,1,243,227,225,1,243,229,227,1,5,4,4,1,224, + 182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228, + 192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233, + 203,200,1,234,205,202,1,99,87,86,1,49,44,43,1,228,204,201,1,238, + 214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242, + 225,222,1,243,227,225,1,243,229,227,1,5,4,4,1,224,182,177,1,225, + 184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,229, + 195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233,203,200,1,234, + 205,202,1,209,184,182,1,230,205,201,1,237,212,209,1,238,214,211,1,238, + 216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243, + 227,225,1,28,27,27,1,97,77,76,1,224,182,177,1,225,184,179,1,226, + 186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,229,195,190,1,230, + 197,193,1,231,199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235, + 207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238,216,213,1,239, + 218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,5, + 5,5,1,223,179,175,1,224,182,177,1,225,184,179,1,226,186,181,1,226, + 188,184,1,227,190,186,1,228,192,188,1,229,195,190,1,230,197,193,1,231, + 199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,236, + 210,206,1,237,212,209,1,238,214,211,1,238,216,213,1,239,218,216,1,240, + 220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,5,5,5,1,223, + 179,175,1,224,182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227, + 190,186,1,228,192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232, + 201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,236,210,206,1,237, + 212,209,1,238,214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241, + 222,220,1,242,225,222,1,243,227,225,1,228,214,213,1,43,35,33,1,224, + 182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228, + 192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233, + 203,200,1,234,205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238, + 214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242, + 225,222,1,243,227,225,1,243,229,227,1,5,4,4,1,224,182,177,1,225, + 184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,229, + 195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233,203,200,1,234, + 205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238, + 216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243, + 227,225,1,204,193,191,1,2,2,2,1,168,136,133,1,225,183,179,1,225, + 185,181,1,8,6,6,1,5,4,4,1,18,16,15,1,229,195,189,1,229, + 197,193,1,145,125,122,1,5,4,4,2,59,53,51,1,235,207,203,1,235, + 209,205,1,84,74,73,1,5,5,5,2,118,107,106,1,239,219,217,1,241, + 221,219,1,37,35,35,1,5,5,5,1,3,2,2,1,152,1,0,0,247, + 247,247,1,250,250,250,1,236,236,236,1,128,128,128,2,157,157,157,1,250, + 250,250,2,204,204,204,1,128,128,128,2,189,189,189,1,250,250,250,2,171, + 171,171,1,128,128,128,2,221,221,221,1,250,250,250,2,139,139,139,1,128, + 128,128,1,132,132,132,1,247,247,247,1,153,153,153,1,255,255,255,22,250, + 250,250,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255, + 255,255,22,128,128,128,1,239,239,239,1,255,255,255,22,128,128,128,1,250, + 250,250,1,255,255,255,22,164,164,164,1,243,243,243,1,255,255,255,22,250, + 250,250,1,128,128,128,1,255,255,255,22,250,250,250,1,128,128,128,1,255, + 255,255,22,197,197,197,1,150,150,150,1,255,255,255,22,128,128,128,1,250, + 250,250,1,255,255,255,22,128,128,128,1,250,250,250,1,255,255,255,22,197, + 197,197,1,211,211,211,1,255,255,255,22,250,250,250,1,128,128,128,1,255, + 255,255,22,250,250,250,1,128,128,128,1,255,255,255,22,164,164,164,1,182, + 182,182,1,255,255,255,22,128,128,128,1,250,250,250,1,255,255,255,22,128, + 128,128,1,250,250,250,1,255,255,255,22,229,229,229,1,178,178,178,1,255, + 255,255,22,250,250,250,1,128,128,128,1,255,255,255,22,250,250,250,1,128, + 128,128,1,255,255,255,22,132,132,132,1,214,214,214,1,255,255,255,22,128, + 128,128,1,250,250,250,1,255,255,255,22,139,139,139,1,247,247,247,1,146, + 146,146,1,128,128,128,2,247,247,247,1,250,250,250,1,236,236,236,1,128, + 128,128,2,157,157,157,1,250,250,250,2,204,204,204,1,128,128,128,2,189, + 189,189,1,250,250,250,2,171,171,171,1,128,128,128,2,221,221,221,1,250, + 250,250,1,247,247,247,1,0,0) + ); + +const + objdata_tfilechangenotifyer: record size: integer; data: array[0..1834] of byte end = + (size: 1835; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,102,105, + 108,101,99,104,97,110,103,101,110,111,116,105,102,121,101,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,172,6,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,192,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208, + 39,15,147,0,2,208,208,208,21,20,144,0,1,27,145,7,1,23,145,5, + 1,0,0,0,1,208,208,208,18,0,128,0,1,19,144,0,1,54,160,38, + 1,146,224,139,1,85,180,73,1,16,109,0,1,0,0,0,1,208,208,208, + 9,0,0,0,2,208,208,208,5,24,146,0,1,21,145,1,1,96,188,85, + 1,179,249,176,1,97,184,86,1,15,95,3,1,1,10,0,1,0,0,0, + 1,208,208,208,7,0,0,0,4,208,208,208,1,0,0,0,1,208,208,208, + 2,18,143,0,1,32,150,14,1,137,217,131,1,157,232,152,1,38,136,25, + 1,11,87,0,1,0,0,0,4,208,208,208,6,0,0,0,7,19,145,0, + 1,61,167,45,1,174,244,171,1,98,188,86,1,20,127,3,1,2,11,0, + 1,0,0,0,6,208,208,208,5,0,0,0,5,7,42,0,1,22,144,3, + 1,111,199,100,1,161,235,155,1,43,150,26,1,12,90,0,1,0,0,0, + 7,208,208,208,7,0,0,0,3,0,4,0,1,29,135,13,1,158,235,154, + 1,98,190,87,1,19,125,3,1,3,31,0,1,0,0,0,8,208,208,208, + 7,0,0,0,2,17,140,0,1,22,61,17,1,134,200,130,1,41,151,24, + 1,10,83,0,1,0,0,0,3,208,208,208,2,0,0,0,5,208,208,208, + 8,18,146,0,1,45,161,29,1,130,214,120,1,22,144,4,1,6,50,0, + 1,0,0,0,3,208,208,208,17,18,136,0,1,21,136,2,1,21,135,0, + 1,21,139,0,1,18,139,0,1,0,128,0,1,208,208,208,19,0,32,0, + 1,15,116,0,1,19,136,0,1,21,138,0,1,20,142,0,1,18,140,0, + 1,208,208,208,19,0,0,0,1,11,68,0,1,16,123,0,1,20,138,0, + 1,21,140,0,1,19,143,0,1,28,142,0,1,208,208,208,18,0,0,0, + 2,10,96,0,1,19,130,0,1,20,140,0,1,20,142,0,1,18,141,0, + 1,208,208,208,18,18,237,0,1,0,35,0,1,0,0,0,1,12,90,0, + 1,19,137,0,1,20,143,0,1,19,142,0,1,0,128,0,1,208,208,208, + 16,29,179,10,1,4,28,2,1,0,0,0,1,3,28,0,1,18,143,0, + 1,18,139,0,1,11,80,0,1,0,0,0,1,208,208,208,15,25,206,0, + 1,83,190,67,1,30,93,24,1,3,25,0,1,17,126,0,1,19,143,0, + 1,0,22,0,1,0,0,0,2,208,208,208,15,60,191,44,1,148,226,140, + 1,68,181,56,1,19,142,0,1,20,136,0,1,0,0,0,3,208,208,208, + 15,31,201,22,1,132,221,124,1,173,244,169,1,101,196,91,1,45,169,28, + 1,18,159,0,1,17,176,0,1,15,226,0,1,208,208,208,16,96,215,82, + 1,174,245,171,1,118,203,108,1,54,160,39,1,18,138,0,2,15,151,0, + 1,11,158,0,1,0,0,0,1,208,208,208,14,36,216,21,1,117,225,111, + 1,65,172,56,1,21,120,13,1,6,52,0,1,0,0,0,5,208,208,208, + 14,0,192,0,1,0,0,0,8,208,208,208,16,0,0,0,4,208,208,208, + 13,180,3,0,0,0,0,0,39,33,33,33,2,0,0,0,21,76,76,76, + 1,208,208,208,1,164,164,164,1,1,1,1,1,0,0,0,18,2,2,2, + 1,133,133,133,1,202,202,202,1,253,253,253,1,210,210,210,1,49,49,49, + 1,1,1,1,1,0,0,0,9,61,61,61,1,144,144,144,1,0,0,0, + 5,21,21,21,1,183,183,183,1,211,211,211,1,255,255,255,1,216,216,216, + 1,214,214,214,1,176,176,176,1,3,3,3,1,0,0,0,7,21,21,21, + 1,12,12,12,1,78,78,78,1,199,199,199,1,0,0,0,1,35,35,35, + 1,0,0,0,2,57,57,57,1,204,204,204,1,230,230,230,1,235,235,235, + 1,220,220,220,1,150,150,150,1,116,116,116,1,210,210,210,1,1,1,1, + 1,35,35,35,1,0,0,0,6,132,132,132,1,242,242,242,1,185,185,185, + 1,220,220,220,1,205,205,205,1,249,249,249,1,12,12,12,1,109,109,109, + 1,203,203,203,1,248,248,248,1,213,213,213,1,195,195,195,1,170,170,170, + 1,245,245,245,1,185,185,185,1,223,223,223,1,202,202,202,1,251,251,251, + 1,17,17,17,1,0,0,0,5,4,4,4,1,53,53,53,1,214,214,214, + 1,255,255,255,1,112,112,112,1,33,33,33,1,166,166,166,1,205,205,205, + 1,230,230,230,1,215,215,215,1,133,133,133,1,61,61,61,1,24,24,24, + 1,53,53,53,1,209,209,209,1,255,255,255,1,117,117,117,1,24,24,24, + 1,0,0,0,7,116,116,116,1,219,219,219,1,122,122,122,1,224,224,224, + 1,204,204,204,1,221,221,221,1,208,208,208,1,185,185,185,1,83,83,83, + 1,38,38,38,1,7,7,7,1,1,1,1,1,108,108,108,1,224,224,224, + 1,117,117,117,1,222,222,222,1,25,25,25,1,0,0,0,7,109,109,109, + 1,71,71,71,1,88,88,88,1,234,234,234,1,223,223,223,1,209,209,209, + 1,122,122,122,1,57,57,57,1,17,17,17,1,3,3,3,1,0,0,0, + 2,103,103,103,1,77,77,77,1,1,1,1,1,148,148,148,1,35,35,35, + 1,0,0,0,8,70,70,70,1,237,237,237,1,229,229,229,1,239,239,239, + 1,91,91,91,1,35,35,35,1,6,6,6,1,1,1,1,1,0,0,0, + 17,58,58,58,1,208,208,208,1,231,231,231,1,222,222,222,1,101,101,101, + 1,2,2,2,1,0,0,0,19,8,8,8,1,117,117,117,1,225,225,225, + 1,232,232,232,1,192,192,192,1,42,42,42,1,0,0,0,19,2,2,2, + 1,22,22,22,1,155,155,155,1,234,234,234,1,233,233,233,1,133,133,133, + 1,9,9,9,1,0,0,0,18,1,1,1,1,3,3,3,1,50,50,50, + 1,190,190,190,1,243,243,243,1,219,219,219,1,70,70,70,1,0,0,0, + 18,14,14,14,1,54,54,54,1,83,83,83,1,97,97,97,1,219,219,219, + 1,253,253,253,1,164,164,164,1,4,4,4,1,0,0,0,16,124,124,124, + 1,175,175,175,1,255,255,255,1,72,72,72,1,182,182,182,1,213,213,213, + 1,89,89,89,1,8,8,8,1,0,0,0,15,31,31,31,1,223,223,223, + 1,155,155,155,2,219,219,219,1,119,119,119,1,24,24,24,1,20,20,20, + 1,1,1,1,1,0,0,0,15,149,149,149,1,255,255,255,1,196,196,196, + 1,185,185,185,1,38,38,38,1,14,14,14,1,6,6,6,1,1,1,1, + 1,0,0,0,15,57,57,57,1,240,240,240,1,255,255,255,1,244,244,244, + 1,189,189,189,1,139,139,139,1,88,88,88,1,17,17,17,1,0,0,0, + 16,173,173,173,1,255,255,255,2,244,244,244,1,208,208,208,1,159,159,159, + 1,105,105,105,1,23,23,23,1,1,1,1,1,0,0,0,14,84,84,84, + 1,194,194,194,1,168,168,168,1,143,143,143,1,92,92,92,1,68,68,68, + 1,48,48,48,1,29,29,29,1,9,9,9,1,1,1,1,1,0,0,0, + 14,4,4,4,1,14,14,14,1,48,48,48,1,32,32,32,1,14,14,14, + 1,3,3,3,1,2,2,2,1,1,1,1,2,0,0,0,16,1,1,1, + 1,2,2,2,1,1,1,1,2,0,0,0,13,0,0) + ); + +initialization + registerobjectdata(@objdata_tsysenvmanager,tbitmapcomp,'tsysenvmanager'); + registerobjectdata(@objdata_tmseprocess,tbitmapcomp,'tmseprocess'); + registerobjectdata(@objdata_tpythonscript,tbitmapcomp,'tpythonscript'); + registerobjectdata(@objdata_tfilechangenotifyer,tbitmapcomp,'tfilechangenotifyer'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regunitgroups.pas b/mseide-msegui/lib/common/regcomponents/regunitgroups.pas new file mode 100644 index 0000000..79796e0 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regunitgroups.pas @@ -0,0 +1,126 @@ +{ MSEide Copyright (c) 2007-2018 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regunitgroups; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + msedesignintf; + +procedure reggroups; +begin + registerunitgroup(['msegui'],['msegraphics','msegraphutils']); + registerunitgroup(['mseskin'],['mseclasses']); + registerunitgroup(['mseedit'],['msegui','msemenus','mseguiglob','msegraphics','mseapplication','sysutils','msestat','msestatfile','msetypes','msestream']); + registerunitgroup(['msetabs'],['msegui','msemenus','mseguiglob','msegraphics','msewidgets','msegraphutils','msedragglob','msescrollbar']); + registerunitgroup(['msetoolbar'],['msegui','msemenus','mseguiglob','msegraphics','msewidgets']); + registerunitgroup(['msedataedits'],['msegui','msemenus','mseguiglob','msegraphics','msetypes','mseedit','mseificomp','mseifiglob','mseglob','mseificompglob','mseact','msedropdownlist']); + registerunitgroup(['msegraphedits'],['msegui','msemenus','mseguiglob','msegraphics','msescrollbar','msetypes','mseificomp','mseifiglob','mseglob','mseificompglob']); + registerunitgroup(['msesimplewidgets'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses','msegraphutils','msewidgets']); + registerunitgroup(['msegrids'],['msegui','msemenus','mseguiglob','msegraphics','msedragglob','msetypes']); + registerunitgroup(['msewidgets'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['mseificomp'],['mseifiglob','mseglob','mseificompglob']); + registerunitgroup(['mseactions'],['mseclasses']); + registerunitgroup(['mseprocess'],['msepipestream']); + registerunitgroup(['msemenuwidgets'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['msewidgetgrid'],['msegui','msemenus','mseguiglob','msegraphics','msegrids','msetypes']); + registerunitgroup(['msedispwidgets'],['msegui','msemenus','mseguiglob','msegraphics','msetypes','mserichstring']); + registerunitgroup(['msesplitter'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['mseforms'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils','msewidgets','mseglob','mseevent','mseclasses','msestat','mseguiintf','mseapplication','msedragglob','msedock']); + registerunitgroup(['msedock'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils','msedragglob']); + registerunitgroup(['mselistbrowser'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','msedatanodes','msestat','msegrids','mseificomp','mseifiglob','mseglob']); + registerunitgroup(['mseifigui'],['mseifi','mseifilink','mseifiglob','mseglob','msegui','msemenus','mseguiglob','msegraphics','msegrids','msetypes','mseapplication','mseforms']); + registerunitgroup(['mseifi'],['msesercomm']); + registerunitgroup(['mseifilink'],['mseifiglob','mseglob']); + registerunitgroup(['msesockets'],['msesercomm','msesys']); + registerunitgroup(['mserttistat'],['msestat']); + registerunitgroup(['msefiledialog'],['msegui','msemenus','mseguiglob','msegraphics','mselistbrowser','msegrids','msetypes','msesys','msebitmap','mseglob','msedataedits','mseedit','msedatanodes']); + registerunitgroup(['msedialog'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','mseglob']); + registerunitgroup(['msestringcontainer'],['msetypes']); + registerunitgroup(['msecolordialog'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','msegraphutils']); + registerunitgroup(['msememodialog'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit']); + registerunitgroup(['msetextedit'],['msegui','msemenus','mseguiglob','msegraphics','mseedit','msetypes','mseeditglob','msegrids','mserichstring']); + registerunitgroup(['msesyntaxedit'],['msegui','msemenus','mseguiglob','msegraphics','mseedit','msetypes','msetextedit','mseeditglob','msegrids','mserichstring']); + registerunitgroup(['msereport'],['msegui','msemenus','mseguiglob','msegraphics','msesplitter','mdb','mseifiglob','mserichstring','msetypes']); + registerunitgroup(['msesysenv'],['msetypes']); + registerunitgroup(['msepostscriptprinter'],['mseprinter','sysutils','msetypes']); + registerunitgroup(['mseprocmonitorcomp'],['msesystypes']); + registerunitgroup(['mseprinter'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit']); + registerunitgroup(['mseimage'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['msedial'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['msewindowwidget'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses','msetypes','msegraphutils']); + registerunitgroup(['msechart'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils']); + registerunitgroup(['msepolygon'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils']); + registerunitgroup(['msepickwidget'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses','mseobjectpicker','msepointer','msetypes']); + registerunitgroup(['msetraywidget'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses']); + registerunitgroup(['msedockpanelform'],['msetypes','msemenus','mseclasses']); + registerunitgroup(['msechartedit'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils','msetypes']); + registerunitgroup(['msebarcode'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['mseopenglwidget'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses','msegraphutils','msewindowwidget','msetypes']); + registerunitgroup(['mseopenglcanvaswidget'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses','msegraphutils','msewindowwidget','msetypes']); + registerunitgroup(['msedb'],['mdb','msetypes','mseifiglob']); + registerunitgroup(['msegdiprint'],['mseprinter']); + registerunitgroup(['mseterminal'],['msegui','msemenus','mseguiglob','msegraphics','mseedit','msetypes','msetextedit','mseeditglob','msegrids','mserichstring']); + registerunitgroup(['msedataimage'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['msecalendardatetimeedit'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit']); + registerunitgroup(['msefoldedit'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','msegrids']); + registerunitgroup(['mserealsumedit'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit']); + registerunitgroup(['mseguirttistat'],['mserttistat','msestat','msegui']); + registerunitgroup(['mseassistivehandler'],['msespeak','mseassistiveclient','mseguiglob','msegrids','msegraphutils','msetypes','mseassistiveserver','mseact','mseshapes','msemenuwidgets','mdb']); + registerunitgroup(['mseguithreadcomp'],['msethreadcomp']); + registerunitgroup(['msesignal'],['msetypes']); + registerunitgroup(['msesigfft'],['msetypes','msesignal']); + registerunitgroup(['msesiggui'],['msegui','msemenus','mseguiglob','msegraphics','msetypes','msegraphedits','msedataedits','mseedit','msegraphutils','msechartedit','msesignal']); + registerunitgroup(['msesigfftgui'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils','msesignal','msesigfft']); + registerunitgroup(['msesigmidi'],['msemidi','msedatamodules']); + registerunitgroup(['mseaudio'],['msetypes']); + registerunitgroup(['msesqldb'],['msedatabase','sysutils','msqldb','msebufdataset','mdb','msedb','msetypes']); + registerunitgroup(['msedbedit'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','mselookupbuffer','msegraphedits','msegrids','mdb']); + registerunitgroup(['msesqlresult'],['msqldb','sysutils','mselookupbuffer']); + registerunitgroup(['msqldb'],['sysutils']); + registerunitgroup(['msedbdispwidgets'],['msegui','msemenus','mseguiglob','msegraphics','msetypes']); + registerunitgroup(['mseibconnection'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msefb3connection'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msefbservice'],['msetypes','sysutils']); + registerunitgroup(['msefb3service'],['msetypes','sysutils']); + registerunitgroup(['msepqconnection'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['mseodbcconn'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['mselocaldataset'],['msebufdataset','mdb','msedb']); + registerunitgroup(['msedbgraphics'],['mdb','msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['msedbdialog'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','msegraphutils','mseglob']); + registerunitgroup(['msedbcalendardatetimeedit'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit']); + registerunitgroup(['msedbevents'],['msedatabase','sysutils']); + registerunitgroup(['msesqlite3conn'],['msedatabase','sysutils']); + registerunitgroup(['msemysqlconn'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msedblookup'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes']); + registerunitgroup(['mserepps'],['msegui','msemenus','mseguiglob','msegraphics','msereport']); + registerunitgroup(['mseifidbcomp'],['msesqlresult','msqldb','sysutils']); + registerunitgroup(['mseifiendpoint'],['msetypes']); + registerunitgroup(['mseifids'],['mdb','msebufdataset','msedb','msesqldb','msetypes']); + registerunitgroup(['mseifidbgui'],['msegui','msemenus','mseguiglob','msegraphics','msegrids','msetypes']); + registerunitgroup(['msecommutils'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','msecommport']); + registerunitgroup(['msemysql40conn'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msemysql41conn'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msemysql50conn'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msedbf'],['mdbf','dbf_idxfile','mdb']); + registerunitgroup(['msesdfdata'],['mdb']); + registerunitgroup(['msememds'],['mdb']); +end; + +initialization + reggroups; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regwidgets.pas b/mseide-msegui/lib/common/regcomponents/regwidgets.pas new file mode 100644 index 0000000..db722f1 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regwidgets.pas @@ -0,0 +1,570 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regwidgets; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msepropertyeditors,msestrings,sysutils; + +type + tgridpropseditor = class(tpersistentarraypropertyeditor) + protected + procedure itemmoved(const source,dest: integer); override; + end; + + tdatacoleditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tdatacolseditor = class(tgridpropseditor) + protected + function geteditorclass: propertyeditorclassty; override; + public + function itemprefix: msestring; override; + end; + +implementation +uses + classes,mclasses,msesimplewidgets,msegrids,msemenus,mseimage,msedispwidgets, + msetoolbar,msetabs,msedesignintf,regwidgets_bmp,mselistbrowser,mserichstring, + msesplitter,msedock,mseforms,mseclasses,typinfo,msearrayprops,msewidgets, + msegui,formdesigner,msedial,msemenuwidgets,msewindowwidget,msechart, + msepolygon,msepickwidget,msetraywidget,msedockpanelform,msechartedit,mseedit, + msebarcode,msedatalist,mseact,mseformatstr,msesizingform, + msetaborderoverrideeditor,msedesigner,mseglob + {$ifndef mse_no_opengl} +// {$ifdef FPC} + ,mseopenglwidget + {$ifdef mse_with_openglcanvas} + ,mseopenglcanvaswidget +// {$endif} + {$endif} + {$endif}; + +type + tpropertyeditor1 = class(tpropertyeditor); + tdatacols1 = class(tdatacols); + tfixcols1 = class(tfixcols); + tfixrows1 = class(tfixrows); + ttaborderoverride1 = class(ttaborderoverride); + + +type + tfixgridpropeditor = class(tarrayelementeditor) + public + function name: msestring; override; + end; + + tfixgridpropseditor = class(tgridpropseditor) + protected + function getelementeditorclass: elementeditorclassty; override; + end; + + tfixrowseditor = class(tfixgridpropseditor) + public + function itemprefix: msestring; override; + end; + + tfixcolseditor = class(tfixgridpropseditor) + public + function itemprefix: msestring; override; + end; + + tcolheaderelementeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tcolheaderspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tfixcolheaderspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function getelementeditorclass: elementeditorclassty; override; + end; + + ttraceeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + ttraceseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + public + end; + + ttoolbuttoneditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + ttoolbuttonseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + public + end; + + tcoloptionseditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + tgridoptionseditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + tframebuttoneditor = class(tclasspropertyeditor) + protected + function dispname: msestring; override; + end; + + tframebuttonitemeditor = class(tclasselementeditor) + public + function dispname: msestring; override; + end; + + tframebuttonseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + public + end; + + toptionsplaceeditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + ttaborderoverridepropertyeditor = class(tclasspropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit override; + end; + + toptionsdockeditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + +const + mseformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createmseform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + sizingformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createsizingform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + mainformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createmainform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + dockpanelformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createdockpanelform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + subformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createsubform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + scrollboxformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createscrollboxform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + tabformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createtabform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + +procedure Register; +begin + registerclass(tmseform); + registerclass(tdockform); + registerclass(tsubform); + registerclass(tdockpanelform); + registerclass(tscrollboxform); + registerclass(tsizingform); + + registercomponents('Widget',[ + tlabel,ticon, + tstringdisp,trichstringdisp,tintegerdisp,tint64disp,trealdisp,tdatetimedisp, + tbytestringdisp,tbooleandisp, + tedit, + tbutton,trichbutton,tstockglyphbutton,trichstockglyphbutton, + tsimplewidget,teventwidget, + tgroupbox,tscrollbox,tstepbox,tdockpanel,tdockhandle,tmseformwidget, + tdockformwidget, + texpandingwidget,tsplitter,tspacer,tlayouter, + tmainmenuwidget, + ttoolbar, + ttabbar,ttabwidget,ttabpage, + tdrawgrid,tstringgrid,tlistview, + tpaintbox,tpolygon,tpickwidget,timage,tbarcode, + tdial,tchart,txychartedit,txserieschartedit,tchartrecorder, + twindowwidget + {$ifndef mse_no_opengl} + {$ifdef FPC} + ,topenglwidget + {$ifdef mse_with_openglcanvas} + ,topenglcanvaswidget + {$endif} + {$endif} + {$endif} + ,ttraywidget,tdockpanelformcontroller + ]); + registercomponenttabhints(['Widget'], + ['Display widgets, edit widgets which can''t be placed into twidgetgrid']); + registerpropertyeditor(typeinfo(tcellframe),nil,'', + toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(tdatacols),nil,'',tdatacolseditor); + registerpropertyeditor(typeinfo(tfixcols),nil,'',tfixcolseditor); + registerpropertyeditor(typeinfo(tfixrows),nil,'',tfixrowseditor); + registerpropertyeditor(typeinfo(tfixcolheaders),nil,'', + tfixcolheaderspropertyeditor); + registerpropertyeditor(typeinfo(integer),tcolheader,'mergecols', + tvolatileordinalpropertyeditor); + registerpropertyeditor(typeinfo(tcolheaders),nil,'',tcolheaderspropertyeditor); + registerpropertyeditor(typeinfo(twidget),tsplitter,'linkleft', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tsplitter,'linktop', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tsplitter,'linkright', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tsplitter,'linkbottom', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tspacer,'linkleft', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tspacer,'linktop', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tspacer,'linkright', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tspacer,'linkbottom', + tsisterwidgetpropertyeditor); + + registerpropertyeditor(typeinfo(twidget),tlayouter,'linkleft', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tlayouter,'linktop', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tlayouter,'linkright', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tlayouter,'linkbottom', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tlayouter,'align_leader', + tchildwidgetpropertyeditor); + registerpropertyeditor(typeinfo(placeoptionsty),tlayouter,'place_options', + toptionsplaceeditor); + +// registerpropertyeditor(typeinfo(tface),tdial,'',toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(ttraces),nil,'',ttraceseditor); + registerpropertyeditor(typeinfo(ttoolbuttons),nil,'',ttoolbuttonseditor); + registerpropertyeditor(typeinfo(trealdatalist),ttrace,'', + toptionaldatalistpropertyeditor); + + registerpropertyeditor(typeinfo(boolean),tcustombutton,'visible', + trefreshbooleanpropertyeditor); + registerpropertyeditor(typeinfo(boolean),tcustombutton,'enabled', + trefreshbooleanpropertyeditor); + registerpropertyeditor(typeinfo(coloptionsty),nil,'', + tcoloptionseditor); + registerpropertyeditor(typeinfo(optionsgridty),nil,'', + tgridoptionseditor); + registerpropertyeditor(typeinfo(tframebutton),nil,'', + tframebuttoneditor); + registerpropertyeditor(typeinfo(tframebuttons),nil,'', + tframebuttonseditor); + registerpropertyeditor(typeinfo(msestring),tcustomrichstringdisp,'value', + trichstringpropertyeditor); + registerpropertyeditor(typeinfo(msestring),tcustomrichbutton,'captionrich', + trichstringpropertyeditor); + + registerpropertyeditor(typeinfo(labeloptionsty),tcustomlabel,'', + tvolatilesetpropertyeditor); + + registerpropertyeditor(typeinfo(ttaborderoverride),nil,'', + ttaborderoverridepropertyeditor); + registerpropertyeditor(typeinfo(optionsdockty),nil,'', + toptionsdockeditor); + + registerunitgroup(['msegrids'],['msegui','msegraphutils','mseclasses', + 'msegridsglob']); + registerunitgroup(['msewidgetgrid'],['msedataedits', + 'msegui','msegraphutils','mseclasses']); + + registerdesignmoduleclass(tmseform,@mseformintf); + registerdesignmoduleclass(tsizingform,@sizingformintf); + registerdesignmoduleclass(tmainform,@mainformintf); + registerdesignmoduleclass(tdockform,@mseformintf); + registerdesignmoduleclass(tdockpanelform,@dockpanelformintf); + registerdesignmoduleclass(tsubform,@subformintf); + registerdesignmoduleclass(tscrollboxform,@scrollboxformintf); + registerdesignmoduleclass(ttabform,@tabformintf); +end; + +{ tgridpropseditor } + +procedure tgridpropseditor.itemmoved(const source,dest: integer); +var + int1: integer; +begin + inherited; + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + if instance is tcustomgrid then begin + tcustomgrid(instance).layoutchanged; + end; + end; + end; +end; + +{ tfixgridpropeditor } + +function tfixgridpropeditor.name: msestring; +begin +// result:= 'Item '+inttostr(findex - tarrayprop(tpropertyeditor1(fparenteditor).getordvalue).count); + result:= tpersistentarraypropertyeditor(fparenteditor).itemprefix+ + inttostrmse(-findex - 1); +end; + +{ tfixgridpropseditor } + +function tfixgridpropseditor.getelementeditorclass: elementeditorclassty; +begin + result:= tfixgridpropeditor; +end; + +{ tdatacoleditor } + +function tdatacoleditor.getvalue: msestring; +begin + result:= msestring('<'+tdatacol(getpointervalue).name+'>'); +end; + +{ tdatacolseditor } + +function tdatacolseditor.geteditorclass: propertyeditorclassty; +begin + result:= tdatacoleditor; +end; +(* +procedure tdatacolseditor.move(const curindex: integer; + const newindex: integer); +var + int1: integer; +begin + inherited; + { + for int1:= 0 to high(fprops) do begin + with tdatacols1(getordvalue(int1)) do begin + move(curindex,newindex); +// tfixrows1(fgrid.fixrows).movecol(curindex,newindex); + end; + end; + } +end; + +*) + +function tdatacolseditor.itemprefix: msestring; +begin + result:= 'Col '; +end; + +{ tfixcolseditor } + +function tfixcolseditor.itemprefix: msestring; +begin + result:= 'Col '; +end; + +{ tcolheaderelementeditor } + +function tcolheaderelementeditor.getvalue: msestring; +begin + result:= '<'+tcolheader(getpointervalue).caption+'>'; +end; + +{ tcolheaderspropertyeditor } + +function tcolheaderspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tcolheaderelementeditor; +end; + +{ tfixcolheaderspropertyeditor } + +function tfixcolheaderspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tcolheaderelementeditor; +end; + +function tfixcolheaderspropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tfixgridpropeditor; +end; + +{ tfixrowseditor } + +function tfixrowseditor.itemprefix: msestring; +begin + result:= 'Row '; +end; + +{ ttraceeditor } + +function ttraceeditor.getvalue: msestring; +begin + result:= msestring('<'+ttrace(getpointervalue).name+'>'); +end; + +{ ttraceseditor } + +function ttraceseditor.geteditorclass: propertyeditorclassty; +begin + result:= ttraceeditor; +end; + +{ ttoolbuttoneditor } + +function ttoolbuttoneditor.getvalue: msestring; +begin + with ttoolbutton(getpointervalue) do begin + if mao_separator in options then begin + result:= '<---->'; + end + else begin + if action <> nil then begin + result:= msestring('<'+action.name+'>'); + end + else begin + result:= '<>'; + end; + end; + end; +end; + +{ ttoolbuttonseditor } + +function ttoolbuttonseditor.geteditorclass: propertyeditorclassty; +begin + result:= ttoolbuttoneditor; +end; + +{ tcoloptionseditor } + +function tcoloptionseditor.getinvisibleitems: tintegerset; +begin + result:= invisiblecoloptions; +end; + +{ tgridoptionseditor } + +function tgridoptionseditor.getinvisibleitems: tintegerset; +begin + result:= invisibleoptionsgrid; +end; + +{ tframebuttoneditor } + +function tframebuttoneditor.dispname(): msestring; +begin + with tframebutton(getpointervalue()) do begin + if action <> nil then begin + result:= msestring(action.name); + end + else begin + result:= inherited dispname(); + end; + end; +end; + +{ tframebuttonitemeditor } + +function tframebuttonitemeditor.dispname: msestring; +begin + with tframebutton(getpointervalue()) do begin + if action <> nil then begin + result:= msestring(action.name); + end + else begin + result:= inherited dispname(); + end; + end; +end; + +{ tframebuttonseditor } + +function tframebuttonseditor.geteditorclass: propertyeditorclassty; +begin + result:= tframebuttonitemeditor; +end; + +{ toptionsplaceeditor } + +function toptionsplaceeditor.getinvisibleitems: tintegerset; +begin + result:= invisibleplaceoptions; +end; + +{ ttaborderoverridepropertyeditor } + +function ttaborderoverridepropertyeditor.getdefaultstate: propertystatesty; +begin + if fmodule is twidget then begin + result:= inherited getdefaultstate + [ps_dialog]; + end; +end; + +procedure ttaborderoverridepropertyeditor.edit; +var + prop: ttaborderoverride1; + i1: int32; +begin + prop:= ttaborderoverride1(getpointervalue()); +// rcomp:= rootcomponent(prop.fowner); + with tmsetaborderoverrideeditorfo.create(prop.fowner) do begin + grid.beginupdate(); + grid.rowcount:= length(prop.fitems); + for i1:= 0 to grid.rowhigh do begin + with prop.fitems[i1] do begin + aed[i1]:= msestring(compnamepath(a)); + bed[i1]:= msestring(compnamepath(b)); + end; + end; + grid.endupdate(); + if show(ml_application) = mr_ok then begin + prop.clear(); + for i1:= 0 to grid.rowhigh do begin + prop.add(findcomp(aed[i1]),findcomp(bed[i1])); + end; + modified(); + end; + end; +end; + +{ toptionsdockeditor } + +function toptionsdockeditor.getinvisibleitems: tintegerset; +begin + result:= tintegerset(card32(deprecatedoptionsdock)); +end; + +initialization + register; +end. + + diff --git a/mseide-msegui/lib/common/regcomponents/regwidgets_bmp.pas b/mseide-msegui/lib/common/regcomponents/regwidgets_bmp.pas new file mode 100644 index 0000000..62de783 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regwidgets_bmp.pas @@ -0,0 +1,4366 @@ +unit regwidgets_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tsimplewidget: record size: integer; data: array[0..1388] of byte end = + (size: 1389; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,105, + 109,112,108,101,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,244,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,88,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,25,5,5,5,1,6, + 6,6,1,21,21,21,1,224,224,224,2,135,135,135,1,6,6,6,2,56, + 56,56,1,224,224,224,2,78,78,78,1,6,6,6,2,112,112,112,1,224, + 224,224,2,33,33,33,1,6,6,6,2,187,187,187,1,224,224,224,1,255, + 255,255,2,198,198,198,1,217,217,217,1,218,218,218,1,224,224,224,2,222, + 222,222,1,217,217,217,2,220,220,220,1,224,224,224,2,220,220,220,1,217, + 217,217,2,222,222,222,1,224,224,224,2,219,219,219,1,217,217,217,2,224, + 224,224,1,202,202,202,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,26,26,26,1,224, + 224,224,20,31,31,31,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,126,126,126,1,224, + 224,224,20,103,103,103,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,63,63,63,1,224, + 224,224,20,65,65,65,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,68,68,68,1,224, + 224,224,20,65,65,65,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,118,118,118,1,224, + 224,224,20,109,109,109,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,30,30,30,1,224, + 224,224,20,27,27,27,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,2,2,2,1,164, + 164,164,1,157,157,157,1,135,135,135,1,8,8,8,2,44,44,44,1,157, + 157,157,2,89,89,89,1,8,8,8,2,80,80,80,1,157,157,157,2,52, + 52,52,1,8,8,8,2,119,119,119,1,157,157,157,2,4,4,4,1,0, + 0,0,1,255,255,255,1,0,0,0,23,100,2,0,0,0,0,0,25,237, + 237,237,1,247,247,247,1,231,231,231,1,120,120,120,2,152,152,152,1,247, + 247,247,2,199,199,199,1,120,120,120,2,184,184,184,1,247,247,247,2,163, + 163,163,1,120,120,120,2,219,219,219,1,247,247,247,2,132,132,132,1,67, + 67,67,1,0,0,0,2,136,136,136,1,255,255,255,20,155,155,155,1,16, + 16,16,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,111, + 111,111,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,230,230,230,1,255,255,255,20,243,243,243,1,125, + 125,125,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,168,168,168,1,255,255,255,20,220,220,220,1,123, + 123,123,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,203,203,203,1,255,255,255,20,231,231,231,1,124, + 124,124,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,199,199,199,1,255,255,255,20,231,231,231,1,124, + 124,124,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,172,172,172,1,255,255,255,20,218,218,218,1,123, + 123,123,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,227,227,227,1,255,255,255,20,245,245,245,1,125, + 125,125,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,250,250,250,1,197,197,197,1,205,205,205,1,211, + 211,211,1,252,252,252,2,239,239,239,1,205,205,205,2,224,224,224,1,252, + 252,252,2,227,227,227,1,205,205,205,2,236,236,236,1,252,252,252,2,215, + 215,215,1,205,205,205,2,250,250,250,1,126,126,126,1,0,0,0,1,23, + 23,23,1,106,106,106,1,122,122,122,1,123,123,123,1,126,126,126,2,125, + 125,125,1,122,122,122,2,124,124,124,1,126,126,126,2,124,124,124,1,122, + 122,122,2,125,125,125,1,126,126,126,2,123,123,123,1,122,122,122,2,126, + 126,126,1,106,106,106,1,0,0) + ); + +const + objdata_tbutton: record size: integer; data: array[0..786] of byte end = + (size: 787; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,98,117, + 116,116,111,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,160,2,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,88,2,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,120,224,224,224,25,255,255,255,22,0,0,0, + 1,224,224,224,1,255,255,255,1,235,235,235,20,128,128,128,1,0,0,0, + 1,224,224,224,1,255,255,255,1,232,232,232,16,179,179,179,1,232,232,232, + 3,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,229,229,229, + 1,208,208,208,1,69,69,69,1,8,8,8,1,34,34,34,1,182,182,182, + 1,229,229,229,10,0,0,0,1,229,229,229,3,128,128,128,1,0,0,0, + 1,224,224,224,1,255,255,255,1,226,226,226,1,73,73,73,1,105,105,105, + 1,217,217,217,1,147,147,147,1,47,47,47,1,226,226,226,1,96,96,96, + 1,12,12,12,1,6,6,6,1,78,78,78,1,0,0,0,1,89,89,89, + 1,15,15,15,1,154,154,154,1,0,0,0,3,226,226,226,2,128,128,128, + 1,0,0,0,1,224,224,224,1,255,255,255,1,223,223,223,1,10,10,10, + 1,211,211,211,1,223,223,223,6,192,192,192,1,1,1,1,1,0,0,0, + 1,153,153,153,1,157,157,157,1,32,32,32,1,223,223,223,1,0,0,0, + 1,223,223,223,3,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,221,221,221,1,12,12,12,1,209,209,209,1,221,221,221,1,218,218,218, + 1,182,182,182,1,221,221,221,1,153,153,153,1,66,66,66,1,27,27,27, + 1,0,0,0,2,216,216,216,1,215,215,215,1,4,4,4,1,221,221,221, + 1,0,0,0,1,221,221,221,3,128,128,128,1,0,0,0,1,224,224,224, + 1,255,255,255,1,218,218,218,1,71,71,71,1,106,106,106,1,209,209,209, + 1,124,124,124,1,49,49,49,1,218,218,218,1,11,11,11,1,150,150,150, + 1,135,135,135,1,0,0,0,2,156,156,156,1,154,154,154,1,35,35,35, + 1,218,218,218,1,0,0,0,1,206,206,206,1,218,218,218,2,128,128,128, + 1,0,0,0,1,224,224,224,1,255,255,255,1,215,215,215,1,191,191,191, + 1,53,53,53,1,6,6,6,1,36,36,36,1,180,180,180,1,215,215,215, + 1,79,79,79,1,7,7,7,1,94,94,94,1,0,0,0,2,67,67,67, + 1,19,19,19,1,155,155,155,1,215,215,215,1,47,47,47,1,6,6,6, + 1,215,215,215,2,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,212,212,212,11,0,0,0,1,212,212,212,8,128,128,128,1,0,0,0, + 1,224,224,224,1,255,255,255,1,209,209,209,11,0,0,0,1,209,209,209, + 8,128,128,128,1,0,0,0,1,224,224,224,1,128,128,128,22,0,0,0, + 25,255,255,255,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tdrawgrid: record size: integer; data: array[0..1528] of byte end = + (size: 1529; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,100,114, + 97,119,103,114,105,100,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,132,5,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,64,5,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,208,208,208,2,128,128,128,1,208, + 208,208,2,112,112,112,1,153,153,153,1,171,171,171,1,165,165,165,1,118, + 118,118,1,184,184,184,1,208,208,208,2,128,128,128,1,208,208,208,2,154, + 154,154,1,148,148,148,1,190,190,190,1,186,186,186,1,148,148,148,1,208, + 208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,208, + 208,208,1,179,179,179,1,142,142,142,1,116,116,116,1,148,148,148,1,141, + 141,141,1,121,121,121,1,128,128,128,1,208,208,208,2,128,128,128,1,208, + 208,208,2,144,144,144,2,131,131,131,1,146,146,146,1,165,165,165,1,208, + 208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,208, + 208,208,4,175,175,175,1,176,176,176,1,208,208,208,4,128,128,128,1,208, + 208,208,2,186,186,186,1,183,183,183,1,187,187,187,1,191,191,191,1,197, + 197,197,1,208,208,208,1,255,255,255,1,128,128,128,23,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,169,169,169,1,183, + 183,183,1,151,215,220,1,96,235,248,1,72,239,254,1,77,241,255,1,173, + 249,255,1,255,255,255,2,128,128,128,1,255,255,255,2,243,243,243,1,169, + 169,169,1,204,204,204,1,179,179,179,1,139,139,139,1,255,255,255,2,128, + 128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,151,151,151,1,125, + 187,193,1,109,240,255,1,140,241,255,1,133,241,255,1,94,240,255,1,39, + 238,255,1,140,218,224,1,255,255,255,1,128,128,128,1,255,255,255,3,191, + 191,191,1,150,150,150,1,202,202,202,1,158,158,158,1,251,251,251,1,255, + 255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,237, + 237,237,1,114,239,251,1,153,242,255,1,208,244,255,1,192,243,255,1,131, + 241,255,1,65,239,255,1,32,216,230,1,207,207,207,1,128,128,128,1,255, + 255,255,9,128,128,128,6,92,234,248,1,154,242,255,1,208,244,255,1,194, + 243,255,1,132,241,255,1,66,239,255,1,15,227,243,1,70,70,70,1,128, + 128,128,2,113,113,143,1,128,128,128,6,255,255,255,1,128,128,128,1,208, + 208,208,2,128,128,128,1,255,255,255,1,206,206,206,1,91,219,230,1,112, + 241,255,1,143,242,255,1,136,241,255,1,96,240,255,1,41,238,255,1,35, + 196,208,1,121,121,121,1,128,128,128,1,235,235,255,1,33,33,255,1,220, + 220,240,1,255,255,255,1,176,176,176,2,129,129,129,1,255,255,255,2,128, + 128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,181,181,181,1,204, + 237,239,1,55,226,241,1,73,239,255,1,68,239,255,1,40,238,255,1,19, + 225,241,1,73,106,108,1,155,155,155,1,128,128,128,1,114,114,255,1,4, + 4,255,1,60,60,201,1,244,244,244,1,186,186,186,1,211,211,211,1,159, + 159,159,1,255,255,255,2,128,128,128,1,208,208,208,2,128,128,128,1,255, + 255,255,1,199,199,199,1,210,210,210,1,179,197,198,1,68,174,182,1,50, + 188,198,1,62,168,176,1,92,110,111,1,99,99,99,1,229,229,229,1,113, + 113,144,1,10,10,255,1,4,4,255,1,7,7,252,1,155,155,186,1,255, + 255,255,5,128,128,128,8,122,122,122,1,95,95,95,1,85,85,85,1,95, + 95,95,1,122,122,122,1,128,128,128,1,49,49,209,1,4,4,255,3,24, + 24,184,1,119,119,119,1,128,128,128,3,255,255,255,1,128,128,128,1,208, + 208,208,2,128,128,128,1,255,255,255,1,197,197,197,1,253,5,36,1,254, + 6,37,1,255,7,38,4,255,255,255,1,209,209,255,1,5,5,254,1,4, + 4,255,3,5,5,254,1,91,91,137,1,158,158,158,1,157,157,157,1,255, + 255,255,2,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,176, + 176,176,1,255,0,32,6,119,119,119,1,76,76,255,1,4,4,255,5,26, + 26,205,1,145,145,145,1,158,158,158,1,255,255,255,2,128,128,128,1,208, + 208,208,2,128,128,128,1,255,255,255,1,235,235,235,1,255,0,32,6,115, + 115,115,1,248,248,255,1,76,76,84,1,111,111,119,4,112,112,119,1,155, + 155,155,1,255,255,255,3,128,128,128,6,255,0,32,6,58,58,58,1,128, + 128,128,1,126,126,126,7,128,128,128,2,255,255,255,1,128,128,128,1,208, + 208,208,2,128,128,128,1,255,255,255,1,174,174,174,1,255,0,32,6,115, + 115,115,1,255,255,255,1,128,128,128,1,255,255,255,2,228,228,228,1,163, + 163,163,1,191,191,191,1,184,184,184,1,139,139,139,1,255,255,255,2,128, + 128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,158,158,158,1,255, + 0,32,6,115,115,115,1,255,255,255,1,128,128,128,1,255,255,255,2,212, + 212,212,1,152,152,152,1,204,204,204,1,178,178,178,1,158,158,158,1,251, + 251,251,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255, + 255,255,1,237,237,237,1,255,247,248,1,113,105,106,1,97,89,90,1,81, + 73,74,1,113,105,106,1,86,78,79,1,115,115,115,1,255,255,255,1,128, + 128,128,1,255,255,255,9,128,128,128,7,126,126,126,6,128,128,128,10,255, + 255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,199, + 199,199,2,226,226,226,1,228,228,228,1,233,233,233,1,255,255,255,4,128, + 128,128,1,255,255,255,4,172,172,172,1,197,197,197,1,137,137,137,1,255, + 255,255,2,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,183, + 183,183,1,176,176,176,1,183,183,183,1,173,173,173,1,130,130,130,1,255, + 255,255,4,128,128,128,1,255,255,255,4,208,208,208,1,215,215,215,1,168, + 168,168,1,254,254,254,1,255,255,255,25,12,0,0,0,255,255,255,255,255, + 255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tstringgrid: record size: integer; data: array[0..1730] of byte end = + (size: 1731; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,115,116, + 114,105,110,103,103,114,105,100,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,76,6,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,8,6,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,2,128,128,128, + 1,208,208,208,2,112,112,112,1,153,153,153,1,171,171,171,1,165,165,165, + 1,118,118,118,1,184,184,184,1,208,208,208,2,128,128,128,1,208,208,208, + 2,154,154,154,1,148,148,148,1,190,190,190,1,186,186,186,1,148,148,148, + 1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,1,179,179,179,1,142,142,142,1,116,116,116,1,148,148,148, + 1,141,141,141,1,121,121,121,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,2,144,144,144,2,131,131,131,1,146,146,146,1,165,165,165, + 1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,4,175,175,175,1,176,176,176,1,208,208,208,4,128,128,128, + 1,208,208,208,2,186,186,186,1,183,183,183,1,187,187,187,1,191,191,191, + 1,197,197,197,1,208,208,208,1,255,255,255,1,128,128,128,23,255,255,255, + 1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,169,169,169, + 1,183,183,183,1,202,202,202,1,215,215,215,1,225,225,225,1,255,255,255, + 4,128,128,128,1,255,255,255,2,243,243,243,1,169,169,169,1,204,204,204, + 1,179,179,179,1,139,139,139,1,255,255,255,2,128,128,128,1,208,208,208, + 1,209,209,209,1,129,129,129,1,255,255,255,1,152,152,152,1,161,161,161, + 1,156,156,156,1,202,202,202,1,225,225,225,1,255,255,255,4,129,129,129, + 1,255,255,255,3,192,192,192,1,151,151,151,1,203,203,203,1,159,159,159, + 1,251,251,251,1,255,255,255,1,128,128,128,1,213,213,213,1,214,214,214, + 1,145,145,145,1,255,255,255,1,239,239,239,1,236,236,236,1,232,232,232, + 1,219,219,219,1,226,226,226,1,255,255,255,4,145,145,145,1,255,255,255, + 9,128,128,128,1,170,170,170,1,179,179,179,1,180,180,180,1,187,148,135, + 1,186,154,143,1,180,180,180,3,184,160,151,1,188,144,129,2,188,147,133, + 1,185,158,149,1,180,180,180,4,183,166,160,1,189,138,120,1,188,142,126, + 1,181,173,170,1,170,170,170,1,255,255,255,1,128,128,128,1,228,228,228, + 1,233,233,233,1,197,174,166,1,208,53,0,1,209,62,11,1,214,206,203, + 1,234,234,234,1,247,247,247,1,222,133,103,1,208,54,1,1,209,63,13, + 1,209,61,10,1,208,53,0,1,204,96,59,1,255,255,255,2,237,180,160, + 1,209,59,8,1,208,61,10,1,209,55,3,1,207,68,20,1,248,226,218, + 1,255,255,255,1,128,128,128,1,229,229,229,1,233,233,233,1,203,119,91, + 1,212,72,24,1,208,55,3,1,231,168,146,1,205,205,205,1,216,216,216, + 1,213,124,94,1,209,70,22,1,225,225,225,1,223,223,223,1,235,171,149, + 1,208,53,0,1,251,240,236,1,250,233,227,1,210,60,9,1,225,127,93, + 1,223,215,212,1,232,216,210,1,208,67,19,1,231,150,123,1,255,255,255, + 1,128,128,128,1,229,229,229,1,232,230,229,1,207,66,18,1,230,149,121, + 1,214,106,69,1,213,87,44,1,234,234,234,1,247,247,247,1,225,136,106, + 1,210,65,15,1,227,169,149,1,220,159,138,1,219,104,65,1,205,87,47, + 1,255,255,255,1,238,181,161,1,208,53,0,1,244,207,195,1,255,255,255, + 2,254,252,251,1,255,255,255,2,128,128,128,1,184,184,184,1,200,151,134, + 1,208,53,0,1,199,174,165,1,201,151,134,1,208,53,0,1,200,166,155, + 1,197,197,197,1,203,114,84,1,208,55,3,1,206,75,30,1,207,71,25, + 1,207,57,5,1,204,101,66,1,198,190,188,1,202,129,104,1,208,53,0, + 1,198,184,179,1,197,197,197,2,196,196,196,1,183,183,183,1,255,255,255, + 1,128,128,128,1,229,229,229,1,216,106,68,1,208,54,1,1,214,78,31, + 1,210,72,25,1,208,53,0,1,220,124,91,1,255,255,255,1,228,139,109, + 1,213,74,26,1,255,255,255,2,248,224,216,1,208,53,0,1,237,177,157, + 1,239,187,169,1,208,53,0,1,240,190,173,1,216,216,216,1,210,210,210, + 1,208,137,112,1,242,198,183,1,255,255,255,1,128,128,128,1,227,210,204, + 1,209,55,3,1,203,114,83,1,239,185,167,1,215,161,143,1,213,110,74, + 1,209,60,9,1,252,243,240,1,228,139,109,1,212,69,20,1,245,211,199, + 1,244,207,195,1,233,161,136,1,208,53,0,1,238,183,164,1,253,245,243, + 1,213,74,26,1,217,93,50,1,217,174,159,1,210,146,124,1,208,53,0, + 1,237,177,156,1,255,255,255,1,128,128,128,1,218,142,116,1,209,57,5, + 1,195,184,180,1,255,255,255,1,246,246,246,1,231,203,193,1,208,53,0, + 1,235,169,146,1,228,139,109,1,208,53,0,2,209,57,5,1,211,67,18, + 1,203,111,80,1,254,253,252,1,255,255,255,1,246,216,206,1,217,90,47, + 1,208,53,0,1,212,70,21,1,228,137,106,1,255,254,254,1,255,255,255, + 1,128,128,128,1,170,170,170,1,179,179,179,1,180,180,180,18,179,179,179, + 1,170,170,170,1,255,255,255,1,128,128,128,1,213,213,213,1,214,214,214, + 1,145,145,145,1,255,255,255,1,185,185,185,1,187,187,187,1,208,208,208, + 1,235,235,235,1,226,226,226,1,192,192,192,1,218,218,218,1,255,255,255, + 2,145,145,145,1,255,255,255,2,232,232,232,1,175,175,175,1,200,200,200, + 1,193,193,193,1,154,154,154,1,255,255,255,2,128,128,128,1,208,208,208, + 1,209,209,209,1,129,129,129,1,255,255,255,1,159,159,159,1,208,208,208, + 1,122,122,122,1,177,177,177,1,176,176,176,1,184,184,184,1,143,143,143, + 1,255,255,255,2,129,129,129,1,255,255,255,2,213,213,213,1,153,153,153, + 1,205,205,205,1,179,179,179,1,159,159,159,1,251,251,251,1,255,255,255, + 1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,237,237,237, + 1,255,255,255,1,239,239,239,1,203,203,203,1,166,166,166,1,239,239,239, + 1,180,180,180,1,255,255,255,2,128,128,128,1,255,255,255,9,128,128,128, + 23,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255, + 1,199,199,199,2,226,226,226,1,228,228,228,1,233,233,233,1,255,255,255, + 4,128,128,128,1,255,255,255,4,172,172,172,1,197,197,197,1,137,137,137, + 1,255,255,255,2,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255, + 1,183,183,183,1,176,176,176,1,183,183,183,1,173,173,173,1,130,130,130, + 1,255,255,255,4,128,128,128,1,255,255,255,4,208,208,208,1,215,215,215, + 1,168,168,168,1,254,254,254,1,255,255,255,25,12,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmainmenuwidget: record size: integer; data: array[0..1474] of byte end = + (size: 1475; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,109,97, + 105,110,109,101,110,117,119,105,100,103,101,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,72,5,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,192,3,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,30,209,209,209, + 1,255,255,255,7,209,209,209,1,208,208,208,10,175,175,175,1,156,156,156, + 1,190,190,190,1,180,180,180,1,208,208,208,1,209,209,209,1,254,254,254, + 1,208,208,208,1,206,206,206,2,208,208,208,2,206,206,206,1,130,130,130, + 1,208,208,208,1,175,175,175,1,178,178,178,1,194,194,194,1,208,208,208, + 6,148,148,148,1,161,161,161,1,157,157,157,1,117,117,117,1,125,125,125, + 1,209,209,209,1,254,254,254,1,205,205,205,1,110,110,110,1,170,170,170, + 1,143,143,143,1,152,152,152,1,207,207,207,1,129,129,129,1,208,208,208, + 1,153,153,153,2,118,118,118,1,126,126,126,1,124,124,124,1,114,114,114, + 1,208,208,208,3,179,179,179,1,208,208,208,1,182,182,182,1,162,162,162, + 1,167,167,167,1,209,209,209,1,254,254,254,1,158,158,158,1,144,144,144, + 1,131,131,131,1,147,147,147,2,207,207,207,1,128,128,128,1,208,208,208, + 1,178,178,178,1,195,195,195,1,162,162,162,1,168,168,168,1,170,170,170, + 1,168,168,168,1,208,208,208,3,153,153,153,1,107,107,107,1,208,208,208, + 4,255,255,255,1,208,208,208,3,207,207,207,2,208,208,208,1,128,128,128, + 1,208,208,208,1,130,130,130,2,208,208,208,13,211,211,211,1,128,128,128, + 7,208,208,208,9,128,128,128,7,255,255,255,12,192,192,192,1,128,128,128, + 4,208,208,208,7,255,255,255,1,208,208,208,9,197,197,197,1,208,208,208, + 1,128,128,128,1,0,0,0,2,208,208,208,9,255,255,255,1,190,190,190, + 1,116,116,116,1,148,148,148,1,200,200,200,1,162,162,162,1,194,194,194, + 1,181,181,181,1,208,208,208,2,103,103,103,1,165,165,165,1,128,128,128, + 1,0,0,0,2,208,208,208,9,255,255,255,1,198,198,198,1,135,135,135, + 1,165,165,165,1,173,173,173,1,115,115,115,1,148,148,148,1,142,142,142, + 1,208,208,208,2,103,103,103,1,165,165,165,1,128,128,128,1,0,0,0, + 2,208,208,208,9,255,255,255,1,166,166,166,1,148,148,148,1,168,168,168, + 1,150,150,150,1,158,158,158,1,177,177,177,1,157,157,157,1,208,208,208, + 2,197,197,197,1,208,208,208,1,128,128,128,1,0,0,0,2,208,208,208, + 9,255,255,255,11,212,212,212,1,128,128,128,1,0,0,0,2,208,208,208, + 9,255,255,255,2,200,200,200,1,153,153,153,1,192,192,192,1,224,224,224, + 2,209,209,209,1,215,215,215,1,224,224,224,2,128,128,128,2,0,0,0, + 2,208,208,208,9,255,255,255,2,169,169,169,1,147,147,147,1,152,152,152, + 1,136,136,136,1,151,151,151,1,153,153,153,1,168,168,168,1,153,153,153, + 1,223,223,223,1,128,128,128,2,0,0,0,2,208,208,208,9,255,255,255, + 2,169,169,169,1,203,203,203,1,220,220,220,1,156,156,156,1,104,104,104, + 1,157,157,157,1,148,148,148,1,134,134,134,1,218,218,218,1,128,128,128, + 2,0,0,0,2,208,208,208,9,255,255,255,2,224,224,224,9,128,128,128, + 2,0,0,0,2,208,208,208,9,255,255,255,1,218,218,218,1,128,128,128, + 11,0,0,0,2,208,208,208,9,255,255,255,1,191,191,191,1,170,170,170, + 1,208,208,208,1,183,183,183,1,208,208,208,1,207,207,207,1,181,181,181, + 1,208,208,208,4,128,128,128,1,0,0,0,2,208,208,208,9,255,255,255, + 1,169,169,169,1,125,125,125,1,149,149,149,2,153,153,153,1,148,148,148, + 1,108,108,108,1,159,159,159,1,138,138,138,1,170,170,170,1,208,208,208, + 1,128,128,128,1,0,0,0,2,208,208,208,9,255,255,255,1,169,169,169, + 1,123,123,123,1,131,131,131,1,148,148,148,1,102,102,102,1,121,121,121, + 1,108,108,108,1,139,139,139,1,103,103,103,1,144,144,144,1,208,208,208, + 1,128,128,128,1,0,0,0,2,208,208,208,9,255,255,255,1,208,208,208, + 4,207,207,207,1,208,208,208,3,207,207,207,1,208,208,208,2,128,128,128, + 1,0,0,0,2,208,208,208,9,252,252,252,1,128,128,128,12,0,0,0, + 2,208,208,208,9,0,0,0,15,208,208,208,2,80,1,0,0,0,0,0, + 25,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,1,176,176,176,1,255,255,255,22,128,128,128, + 1,0,0,0,7,255,255,255,13,135,135,135,1,3,3,3,1,0,0,0, + 9,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255, + 13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255,13,137,137,137, + 1,3,3,3,1,0,0,0,9,255,255,255,13,137,137,137,1,3,3,3, + 1,0,0,0,9,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0, + 9,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255, + 13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255,13,137,137,137, + 1,3,3,3,1,0,0,0,9,255,255,255,13,137,137,137,1,3,3,3, + 1,0,0,0,9,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0, + 9,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255, + 13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255,13,137,137,137, + 1,3,3,3,1,0,0,0,9,129,129,129,1,255,255,255,12,137,137,137, + 1,3,3,3,1,0,0,0,9,3,3,3,1,135,135,135,1,137,137,137, + 11,135,135,135,1,3,3,3,1,0,0,0,2,0,0) + ); + +const + objdata_taction: record size: integer; data: array[0..1598] of byte end = + (size: 1599; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,97,99, + 116,105,111,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,204,5,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,140,2,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,208,208,208,39,0,0,255,2,208,208,208,21,0,0,255, + 1,7,7,255,1,6,6,252,1,0,0,0,1,208,208,208,19,0,0,255, + 1,34,34,255,1,136,136,255,1,66,66,239,1,0,0,143,1,0,0,0, + 1,208,208,208,16,0,0,255,1,2,2,255,1,75,75,254,1,175,175,255, + 1,76,76,239,1,4,4,211,1,0,0,62,1,0,0,0,1,208,208,208, + 15,0,0,255,1,14,14,255,1,118,118,255,1,141,141,252,1,25,25,230, + 1,0,0,143,1,0,0,0,3,208,208,208,14,0,0,255,1,42,42,255, + 1,160,160,255,1,77,77,243,1,3,3,207,1,0,0,37,1,0,0,0, + 3,208,208,208,13,0,0,255,1,4,4,255,1,86,86,254,1,141,141,253, + 1,24,24,234,1,0,0,131,1,0,0,0,4,208,208,208,13,0,0,255, + 1,17,17,255,1,132,132,255,1,78,78,248,1,3,3,205,1,0,0,26, + 1,0,0,0,3,208,208,208,14,0,0,255,1,46,46,255,1,129,129,254, + 1,24,24,240,1,0,0,117,1,0,0,0,3,208,208,208,15,0,0,255, + 1,28,28,255,1,97,97,254,1,5,5,242,1,0,0,33,1,0,0,0, + 3,208,208,208,17,0,0,234,1,3,3,229,1,0,0,239,1,0,0,244, + 1,0,0,238,1,0,0,0,1,208,208,208,19,0,0,0,1,0,0,179, + 1,0,0,232,1,0,0,246,1,0,0,250,1,0,0,235,1,208,208,208, + 19,0,0,0,1,0,0,43,1,0,0,204,1,0,0,239,1,0,0,248, + 1,0,0,249,1,0,0,128,1,208,208,208,18,0,0,0,2,0,0,123, + 1,0,0,218,1,0,0,244,1,0,0,250,1,0,0,242,1,208,208,208, + 18,0,0,255,1,0,0,230,1,0,0,0,1,0,0,163,1,0,0,230, + 1,0,0,248,1,0,0,250,1,0,0,0,1,208,208,208,16,12,12,255, + 1,17,17,252,1,208,208,208,1,0,0,183,1,0,0,249,1,0,0,240, + 1,0,0,97,1,0,0,0,2,208,208,208,14,0,0,255,1,72,72,255, + 1,55,55,218,1,0,0,242,1,0,0,255,1,0,0,251,1,0,0,0, + 3,208,208,208,15,52,52,255,1,140,140,255,1,48,48,224,1,0,0,247, + 1,0,0,222,1,0,0,0,3,208,208,208,15,27,27,255,1,130,130,255, + 1,169,169,255,1,92,92,250,1,32,32,245,1,0,0,248,1,0,0,251, + 1,0,0,241,1,208,208,208,16,97,97,255,1,171,171,255,1,108,108,255, + 1,41,41,250,1,0,0,234,1,0,0,223,1,0,0,214,1,0,0,170, + 1,0,0,0,1,208,208,208,14,27,27,255,1,127,127,254,1,65,65,223, + 1,14,14,168,1,0,0,61,1,0,0,0,5,208,208,208,14,0,0,192, + 1,0,0,0,8,208,208,208,16,0,0,0,4,208,208,208,13,8,3,0, + 0,0,0,0,39,15,15,15,1,17,17,17,1,0,0,0,21,47,47,47, + 1,182,182,182,1,135,135,135,1,1,1,1,1,0,0,0,19,96,96,96, + 1,193,193,193,1,253,253,253,1,200,200,200,1,36,36,36,1,1,1,1, + 1,0,0,0,16,7,7,7,1,146,146,146,1,209,209,209,1,255,255,255, + 1,213,213,213,1,181,181,181,1,62,62,62,1,3,3,3,1,0,0,0, + 15,32,32,32,1,176,176,176,1,230,230,230,1,235,235,235,1,203,203,203, + 1,127,127,127,1,65,65,65,1,25,25,25,1,2,2,2,1,0,0,0, + 14,74,74,74,1,188,188,188,1,248,248,248,1,209,209,209,1,175,175,175, + 1,83,83,83,1,45,45,45,1,10,10,10,1,2,2,2,1,0,0,0, + 13,2,2,2,1,127,127,127,1,201,201,201,1,230,230,230,1,199,199,199, + 1,117,117,117,1,63,63,63,1,23,23,23,1,3,3,3,1,1,1,1, + 1,0,0,0,13,20,20,20,1,166,166,166,1,220,220,220,1,203,203,203, + 1,164,164,164,1,78,78,78,1,43,43,43,1,8,8,8,1,1,1,1, + 1,0,0,0,14,55,55,55,1,184,184,184,1,217,217,217,1,190,190,190, + 1,106,106,106,1,60,60,60,1,20,20,20,1,3,3,3,1,0,0,0, + 15,33,33,33,1,206,206,206,1,227,227,227,1,214,214,214,1,77,77,77, + 1,39,39,39,1,7,7,7,1,1,1,1,1,0,0,0,17,33,33,33, + 1,177,177,177,1,220,220,220,1,198,198,198,1,68,68,68,1,1,1,1, + 1,0,0,0,19,5,5,5,1,87,87,87,1,198,198,198,1,214,214,214, + 1,157,157,157,1,23,23,23,1,0,0,0,19,2,2,2,1,12,12,12, + 1,126,126,126,1,209,209,209,1,205,205,205,1,103,103,103,1,2,2,2, + 1,0,0,0,18,1,1,1,1,3,3,3,1,31,31,31,1,160,160,160, + 1,215,215,215,1,183,183,183,1,48,48,48,1,0,0,0,18,14,14,14, + 1,10,10,10,1,4,4,4,1,59,59,59,1,187,187,187,1,216,216,216, + 1,127,127,127,1,1,1,1,1,0,0,0,16,124,124,124,1,60,60,60, + 1,0,0,0,1,7,7,7,1,144,144,144,1,188,188,188,1,71,71,71, + 1,11,11,11,1,1,1,1,1,0,0,0,14,31,31,31,1,223,223,223, + 1,112,112,112,1,35,35,35,1,180,180,180,1,89,89,89,1,18,18,18, + 1,24,24,24,1,3,3,3,1,0,0,0,15,148,148,148,1,255,255,255, + 1,189,189,189,1,153,153,153,1,22,22,22,1,14,14,14,1,7,7,7, + 1,2,2,2,1,0,0,0,15,56,56,56,1,240,240,240,1,255,255,255, + 1,244,244,244,1,191,191,191,1,140,140,140,1,87,87,87,1,17,17,17, + 1,0,0,0,16,173,173,173,1,255,255,255,2,244,244,244,1,209,209,209, + 1,160,160,160,1,105,105,105,1,23,23,23,1,1,1,1,1,0,0,0, + 14,84,84,84,1,193,193,193,1,165,165,165,1,143,143,143,1,92,92,92, + 1,70,70,70,1,51,51,51,1,31,31,31,1,13,13,13,1,1,1,1, + 1,0,0,0,14,4,4,4,1,10,10,10,1,49,49,49,1,34,34,34, + 1,16,16,16,1,3,3,3,1,2,2,2,1,1,1,1,2,0,0,0, + 16,1,1,1,1,2,2,2,1,1,1,1,2,0,0,0,13,0,0) + ); + +const + objdata_tlabel: record size: integer; data: array[0..837] of byte end = + (size: 838; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,108,97, + 98,101,108,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13, + 98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,212,2,0,0,0,0,0,0,6,0,0,0, + 24,0,0,0,24,0,0,0,196,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,208,208,208,82,0,0,0,3,208,208,208,21,0,0,0,4, + 208,208,208,20,0,0,0,4,208,208,208,19,0,0,0,6,208,208,208,18, + 0,0,0,6,208,208,208,17,0,0,0,3,208,208,208,1,0,0,0,3, + 208,208,208,17,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,16, + 0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,15,0,0,0,3, + 208,208,208,3,0,0,0,4,208,208,208,14,0,0,0,10,208,208,208,13, + 0,0,0,11,208,208,208,13,0,0,0,12,208,208,208,12,0,0,0,3, + 208,208,208,6,0,0,0,3,208,208,208,11,0,0,0,4,208,208,208,6, + 0,0,0,4,208,208,208,10,0,0,0,3,208,208,208,8,0,0,0,3, + 208,208,208,10,0,0,0,3,208,208,208,8,0,0,0,3,208,208,208,125, + 216,1,0,0,0,0,0,82,1,1,1,1,8,8,8,1,6,6,6,1, + 0,0,0,21,110,110,110,1,255,255,255,1,248,248,248,1,20,20,20,1, + 0,0,0,20,209,209,209,1,233,233,233,1,255,255,255,1,118,118,118,1, + 0,0,0,19,51,51,51,1,255,255,255,1,121,121,121,1,223,223,223,1, + 221,221,221,1,1,1,1,1,0,0,0,18,150,150,150,1,255,255,255,1, + 45,45,45,1,137,137,137,1,255,255,255,1,73,73,73,1,0,0,0,17, + 8,8,8,1,239,239,239,1,220,220,220,1,0,0,0,1,49,49,49,1, + 255,255,255,1,178,178,178,1,0,0,0,17,91,91,91,1,255,255,255,1, + 126,126,126,1,0,0,0,2,210,210,210,1,252,252,252,1,30,30,30,1, + 0,0,0,16,189,189,189,1,254,254,254,1,32,32,32,1,0,0,0,2, + 115,115,115,1,255,255,255,1,132,132,132,1,0,0,0,15,33,33,33,1, + 254,254,254,1,192,192,192,1,0,0,0,3,24,24,24,1,252,252,252,1, + 232,232,232,1,5,5,5,1,0,0,0,14,130,130,130,1,255,255,255,1, + 183,183,183,1,120,120,120,4,228,228,228,1,255,255,255,1,86,86,86,1, + 0,0,0,13,2,2,2,1,226,226,226,1,255,255,255,8,191,191,191,1, + 0,0,0,13,72,72,72,1,255,255,255,1,178,178,178,1,24,24,24,5, + 27,27,27,1,236,236,236,1,255,255,255,1,41,41,41,1,0,0,0,12, + 170,170,170,1,255,255,255,1,80,80,80,1,0,0,0,6,144,144,144,1, + 255,255,255,1,146,146,146,1,0,0,0,11,19,19,19,1,249,249,249,1, + 236,236,236,1,6,6,6,1,0,0,0,6,46,46,46,1,255,255,255,1, + 240,240,240,1,10,10,10,1,0,0,0,10,111,111,111,1,255,255,255,1, + 148,148,148,1,0,0,0,8,204,204,204,1,255,255,255,1,100,100,100,1, + 0,0,0,10,92,92,92,1,128,128,128,1,38,38,38,1,0,0,0,8, + 65,65,65,1,128,128,128,1,89,89,89,1,0,0,0,125,0,0) + ); + +const + objdata_timage: record size: integer; data: array[0..1525] of byte end = + (size: 1526; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,105,109, + 97,103,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13, + 98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,132,5,0,0,0,0,0,0,6,0,0,0, + 24,0,0,0,24,0,0,0,188,4,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,128,128,128,25,255,191,141,22,255,255,255,1,128,128,128,1, + 255,191,141,22,255,255,255,1,128,128,128,1,255,194,147,13,255,194,146,9, + 255,255,255,1,128,128,128,1,255,197,153,3,238,200,160,1,123,218,205,1, + 21,235,247,1,54,230,234,1,167,211,187,1,255,197,153,10,255,197,152,4, + 255,255,255,1,128,128,128,1,255,201,159,3,123,220,208,1,32,239,250,1, + 123,249,254,1,98,247,254,1,3,237,252,1,218,206,173,1,255,201,159,13, + 255,255,255,1,128,128,128,1,255,204,165,3,21,236,247,1,123,249,254,1, + 183,255,255,2,56,241,252,1,118,221,212,1,255,204,165,13,255,255,255,1, + 128,128,128,1,255,208,171,3,54,232,237,1,98,247,254,1,183,255,255,2, + 32,238,250,1,153,220,204,1,255,208,171,13,255,255,255,1,128,128,128,1, + 255,211,177,3,167,220,203,1,3,237,252,1,56,241,252,1,32,238,250,1, + 18,235,248,1,244,212,180,1,255,211,177,13,255,255,255,1,128,128,128,1, + 255,215,183,4,218,218,193,1,118,226,221,1,153,224,211,1,244,216,186,1, + 255,215,183,8,255,214,183,5,248,211,178,1,255,255,255,1,128,128,128,1, + 255,218,189,19,197,199,145,1,91,174,66,1,12,151,6,1,255,255,255,1, + 128,128,128,1,255,222,195,6,255,221,195,11,188,200,144,1,77,177,57,1, + 6,180,3,1,4,181,0,1,4,164,0,1,255,255,255,1,128,128,128,1, + 255,225,201,15,201,208,159,1,79,184,62,1,7,192,4,1,2,194,0,1, + 3,186,0,1,4,178,0,1,5,162,0,1,255,255,255,1,128,128,128,1, + 255,228,208,5,255,228,207,8,248,225,201,1,96,189,77,1,11,200,8,1, + 1,207,1,1,2,199,0,1,3,191,0,1,3,183,0,1,4,174,0,1, + 5,162,0,1,255,255,255,1,128,128,128,1,255,232,214,9,255,232,213,3, + 251,230,210,1,63,184,52,1,0,218,1,1,1,212,1,1,2,204,1,1, + 2,196,0,1,3,187,0,1,4,179,0,1,4,171,0,1,5,162,0,1, + 255,255,255,1,128,128,128,1,253,101,47,1,254,125,59,1,254,131,70,1, + 254,137,82,1,254,143,93,1,254,150,104,1,254,156,116,1,253,159,121,1, + 250,148,104,1,248,137,85,1,245,126,67,1,243,116,49,1,235,101,30,1, + 29,162,3,1,1,216,1,1,1,208,1,1,2,200,1,1,3,192,0,1, + 3,184,0,1,4,176,0,1,5,171,0,1,5,162,0,1,255,255,255,1, + 128,128,128,1,254,120,50,1,255,146,61,1,255,154,74,1,255,161,88,1, + 255,169,101,1,255,176,115,1,255,184,129,1,255,191,142,1,252,179,122,1, + 249,166,100,1,246,153,79,1,243,140,57,1,240,126,36,1,176,109,12,1, + 6,192,1,1,2,205,1,1,2,197,0,1,3,189,0,1,4,181,0,1, + 4,173,0,1,5,171,0,1,5,162,0,1,255,255,255,1,128,128,128,1, + 254,120,50,1,255,144,58,1,255,152,71,1,255,160,85,1,255,167,98,1, + 255,175,112,1,255,182,126,1,255,190,139,1,252,182,126,1,249,169,105,1, + 246,155,83,1,243,142,62,1,240,129,40,1,237,116,19,1,94,125,3,1, + 2,201,1,1,2,194,0,1,3,186,0,1,4,178,0,1,5,171,0,2, + 5,162,0,1,255,255,255,1,128,128,128,1,254,120,50,1,255,143,55,1, + 255,150,68,1,255,158,82,1,255,165,95,1,255,173,109,1,255,180,123,1, + 255,188,136,1,253,185,131,1,250,171,110,1,247,158,88,1,244,145,67,1, + 241,132,45,1,238,119,24,1,228,106,2,1,41,150,2,1,3,191,0,1, + 3,183,0,1,4,175,0,1,5,171,0,2,5,162,0,1,255,255,255,1, + 128,128,128,1,254,120,50,1,255,142,53,1,255,149,65,1,255,156,79,1, + 255,164,92,1,255,171,106,1,255,179,120,1,255,186,133,1,254,187,136,1, + 251,174,114,1,248,161,93,1,245,148,71,1,242,135,50,1,239,122,28,1, + 236,109,7,1,189,111,0,1,28,157,2,1,4,180,0,1,4,171,0,1, + 5,171,0,2,5,162,0,1,255,255,255,1,128,128,128,1,254,120,50,1, + 255,142,53,1,255,147,62,1,255,155,76,1,255,162,89,1,255,170,103,1, + 255,177,117,1,255,185,130,1,254,190,141,1,251,177,119,1,248,164,98,1, + 245,151,76,1,242,138,55,1,239,125,33,1,236,112,12,1,235,105,0,1, + 183,111,1,1,23,151,2,1,5,171,0,3,5,162,0,1,255,255,255,1, + 128,128,128,1,254,120,50,1,255,142,53,1,255,145,59,1,255,153,73,1, + 255,160,86,1,255,168,100,1,255,175,114,1,255,183,127,1,255,191,141,1, + 252,180,124,1,249,167,102,1,246,154,81,1,243,141,59,1,240,128,38,1, + 237,115,16,1,235,105,0,2,178,107,2,1,19,151,1,1,5,171,0,2, + 5,162,0,1,255,255,255,1,128,128,128,1,253,101,47,1,254,120,50,1, + 254,121,52,1,254,127,64,1,254,134,75,1,254,140,87,1,254,147,98,1, + 254,153,109,1,254,159,121,1,252,154,114,1,250,143,95,1,247,132,77,1, + 244,121,59,1,242,110,41,1,239,99,23,1,237,89,5,3,173,89,7,1, + 13,151,1,1,5,162,0,1,4,155,0,1,255,255,255,25,144,0,0,0, + 255,255,255,255,255,255,255,6,237,237,237,1,235,235,235,1,255,255,255,20, + 247,247,247,1,249,249,249,1,255,255,255,20,252,252,252,1,251,251,251,1, + 255,255,255,20,254,254,254,1,249,249,249,1,255,255,255,21,233,233,233,1, + 255,255,255,22,251,251,251,1,226,226,226,1,255,255,255,23,244,244,244,1, + 245,245,245,1,255,255,255,23,242,242,242,1,255,255,255,24,245,245,245,1, + 255,255,255,24,245,245,245,1,255,255,255,24,242,242,242,1,255,255,255,23, + 252,252,252,1,239,239,239,1,255,255,255,23,246,246,246,1,239,239,239,1, + 255,255,255,27,0,0) + ); + +const + objdata_tdispwidget: record size: integer; data: array[0..295] of byte end = + (size: 296; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,105, + 115,112,119,105,100,103,101,116,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,248,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0, + 255,146,128,128,128,20,255,0,255,4,128,128,128,1,192,192,192,18,255,255, + 255,1,255,0,255,4,128,128,128,1,192,192,192,18,255,255,255,1,255,0, + 255,4,128,128,128,1,192,192,192,18,255,255,255,1,255,0,255,4,128,128, + 128,1,192,192,192,18,255,255,255,1,255,0,255,4,128,128,128,1,192,192, + 192,18,255,255,255,1,255,0,255,4,128,128,128,1,192,192,192,18,255,255, + 255,1,255,0,255,4,128,128,128,1,192,192,192,18,255,255,255,1,255,0, + 255,4,128,128,128,1,192,192,192,18,255,255,255,1,255,0,255,4,128,128, + 128,1,192,192,192,18,255,255,255,1,255,0,255,4,128,128,128,1,192,192, + 192,18,255,255,255,1,255,0,255,4,128,128,128,1,192,192,192,18,255,255, + 255,1,255,0,255,4,255,255,255,20,255,0,255,122,0,0) + ); + +const + objdata_tintegerdisp: record size: integer; data: array[0..839] of byte end = + (size: 840; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,105,110, + 116,101,103,101,114,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,208,2,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,136,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209,209, + 209,22,255,255,255,1,128,128,128,1,211,211,211,4,199,199,199,1,205,205, + 205,1,211,211,211,4,202,202,202,1,211,211,211,5,200,200,200,1,211,211, + 211,5,255,255,255,1,128,128,128,1,214,214,214,3,199,199,199,1,29,29, + 29,1,167,167,167,1,214,214,214,2,153,153,153,1,46,46,46,1,41,41, + 41,1,55,55,55,1,173,173,173,1,214,214,214,1,192,192,192,1,55,55, + 55,1,47,47,47,1,34,34,34,1,168,168,168,1,214,214,214,3,255,255, + 255,1,128,128,128,1,217,217,217,2,159,159,159,1,31,31,31,1,11,11, + 11,1,169,169,169,1,217,217,217,1,215,215,215,1,32,32,32,1,181,181, + 181,1,217,217,217,1,142,142,142,1,65,65,65,1,217,217,217,1,85,85, + 85,1,123,123,123,1,217,217,217,1,155,155,155,1,44,44,44,1,217,217, + 217,3,255,255,255,1,128,128,128,1,219,219,219,2,100,100,100,1,171,171, + 171,1,47,47,47,1,171,171,171,1,219,219,219,1,213,213,213,1,165,165, + 165,1,219,219,219,2,171,171,171,1,26,26,26,1,219,219,219,1,210,210, + 210,1,214,214,214,1,219,219,219,1,141,141,141,1,46,46,46,1,219,219, + 219,3,255,255,255,1,128,128,128,1,222,222,222,4,48,48,48,1,173,173, + 173,1,222,222,222,4,216,216,216,1,60,60,60,1,117,117,117,1,222,222, + 222,3,60,60,60,1,8,8,8,1,178,178,178,1,222,222,222,3,255,255, + 255,1,128,128,128,1,224,224,224,4,48,48,48,1,175,175,175,1,224,224, + 224,3,214,214,214,1,59,59,59,1,85,85,85,1,222,222,222,1,224,224, + 224,3,197,197,197,1,136,136,136,1,24,24,24,1,215,215,215,1,224,224, + 224,2,255,255,255,1,128,128,128,1,227,227,227,4,49,49,49,1,177,177, + 177,1,227,227,227,2,214,214,214,1,52,52,52,1,102,102,102,1,226,226, + 226,1,227,227,227,2,188,188,188,1,222,222,222,1,227,227,227,2,41,41, + 41,1,169,169,169,1,227,227,227,2,255,255,255,1,128,128,128,1,229,229, + 229,4,49,49,49,1,179,179,179,1,229,229,229,2,57,57,57,1,124,124, + 124,1,229,229,229,4,80,80,80,1,138,138,138,1,229,229,229,1,202,202, + 202,1,22,22,22,1,221,221,221,1,229,229,229,2,255,255,255,1,128,128, + 128,1,232,232,232,4,50,50,50,1,181,181,181,1,232,232,232,1,172,172, + 172,1,0,0,0,1,6,6,6,3,14,14,14,1,232,232,232,1,199,199, + 199,1,61,61,61,1,51,51,51,2,156,156,156,1,232,232,232,3,255,255, + 255,1,128,128,128,1,235,235,235,16,220,220,220,1,235,235,235,5,255,255, + 255,1,128,128,128,1,237,237,237,22,255,255,255,25,208,208,208,120,16,0, + 0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tint64disp: record size: integer; data: array[0..733] of byte end = + (size: 734; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,105,110, + 116,54,52,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,104,2,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,32,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209,209,209,22, + 255,255,255,1,128,128,128,1,212,212,212,7,200,200,200,1,212,212,212,6, + 199,199,199,1,210,210,210,1,212,212,212,6,255,255,255,1,128,128,128,1, + 214,214,214,5,172,172,172,1,38,38,38,1,45,45,45,2,184,184,184,1, + 214,214,214,3,187,187,187,1,12,12,12,1,180,180,180,1,214,214,214,6, + 255,255,255,1,128,128,128,1,217,217,217,5,43,43,43,1,160,160,160,1, + 217,217,217,1,135,135,135,1,91,91,91,1,217,217,217,2,215,215,215,1, + 57,57,57,1,13,13,13,1,183,183,183,1,217,217,217,6,255,255,255,1, + 128,128,128,1,220,220,220,4,186,186,186,1,39,39,39,1,217,217,217,1, + 184,184,184,1,219,219,219,1,220,220,220,3,115,115,115,1,118,118,118,1, + 34,34,34,1,185,185,185,1,220,220,220,6,255,255,255,1,128,128,128,1, + 222,222,222,4,163,163,163,1,44,44,44,1,39,39,39,1,57,57,57,1, + 38,38,38,1,178,178,178,1,222,222,222,1,178,178,178,1,57,57,57,1, + 220,220,220,1,34,34,34,1,187,187,187,1,222,222,222,6,255,255,255,1, + 128,128,128,1,225,225,225,4,155,155,155,1,2,2,2,1,196,196,196,1, + 225,225,225,1,144,144,144,1,79,79,79,1,217,217,217,1,47,47,47,1, + 196,196,196,1,225,225,225,1,34,34,34,1,190,190,190,1,225,225,225,6, + 255,255,255,1,128,128,128,1,227,227,227,4,179,179,179,1,34,34,34,1, + 227,227,227,2,200,200,200,1,23,23,23,1,151,151,151,1,11,11,11,1, + 35,35,35,2,5,5,5,1,29,29,29,1,185,185,185,1,227,227,227,5, + 255,255,255,1,128,128,128,1,230,230,230,4,224,224,224,1,28,28,28,1, + 191,191,191,1,230,230,230,1,132,132,132,1,69,69,69,1,225,225,225,1, + 216,216,216,3,33,33,33,1,182,182,182,1,227,227,227,1,230,230,230,5, + 255,255,255,1,128,128,128,1,233,233,233,5,173,173,173,1,34,34,34,1, + 49,49,49,1,42,42,42,1,207,207,207,1,233,233,233,4,36,36,36,1, + 196,196,196,1,233,233,233,6,255,255,255,1,128,128,128,1,235,235,235,6, + 234,234,234,1,220,220,220,1,235,235,235,14,255,255,255,1,128,128,128,1, + 238,238,238,22,255,255,255,25,208,208,208,120,16,0,0,0,0,0,0,120, + 255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_trealdisp: record size: integer; data: array[0..784] of byte end = + (size: 785; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,114,101, + 97,108,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,156,2,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,84,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209,209,209,22,255, + 255,255,1,128,128,128,1,211,211,211,4,199,199,199,1,205,205,205,1,211, + 211,211,7,202,202,202,1,211,211,211,6,193,193,193,1,211,211,211,1,255, + 255,255,1,128,128,128,1,214,214,214,3,199,199,199,1,29,29,29,1,167, + 167,167,1,214,214,214,5,170,170,170,1,53,53,53,1,42,42,42,1,47, + 47,47,1,156,156,156,1,214,214,214,3,159,159,159,1,21,21,21,1,214, + 214,214,1,255,255,255,1,128,128,128,1,217,217,217,2,159,159,159,1,31, + 31,31,1,11,11,11,1,169,169,169,1,217,217,217,5,59,59,59,1,153, + 153,153,1,217,217,217,1,170,170,170,1,37,37,37,1,217,217,217,1,215, + 215,215,1,116,116,116,1,22,22,22,1,18,18,18,1,217,217,217,1,255, + 255,255,1,128,128,128,1,219,219,219,2,100,100,100,1,171,171,171,1,47, + 47,47,1,171,171,171,1,219,219,219,5,161,161,161,1,217,217,217,1,219, + 219,219,1,198,198,198,1,7,7,7,1,212,212,212,1,204,204,204,1,88, + 88,88,1,182,182,182,1,18,18,18,1,219,219,219,1,255,255,255,1,128, + 128,128,1,222,222,222,4,48,48,48,1,173,173,173,1,222,222,222,7,221, + 221,221,1,84,84,84,1,87,87,87,1,222,222,222,3,204,204,204,1,18, + 18,18,1,222,222,222,1,255,255,255,1,128,128,128,1,224,224,224,4,48, + 48,48,1,175,175,175,1,224,224,224,6,221,221,221,1,82,82,82,1,62, + 62,62,1,215,215,215,1,224,224,224,3,206,206,206,1,18,18,18,1,224, + 224,224,1,255,255,255,1,128,128,128,1,227,227,227,4,49,49,49,1,177, + 177,177,1,227,227,227,5,222,222,222,1,73,73,73,1,77,77,77,1,222, + 222,222,1,227,227,227,4,208,208,208,1,19,19,19,1,227,227,227,1,255, + 255,255,1,128,128,128,1,229,229,229,4,49,49,49,1,179,179,179,1,229, + 229,229,2,210,210,210,1,216,216,216,1,229,229,229,1,86,86,86,1,95, + 95,95,1,228,228,228,1,229,229,229,5,210,210,210,1,19,19,19,1,229, + 229,229,1,255,255,255,1,128,128,128,1,232,232,232,4,50,50,50,1,181, + 181,181,1,232,232,232,2,73,73,73,1,130,130,130,1,201,201,201,1,0, + 0,0,1,5,5,5,1,6,6,6,3,209,209,209,1,232,232,232,2,213, + 213,213,1,19,19,19,1,232,232,232,1,255,255,255,1,128,128,128,1,235, + 235,235,22,255,255,255,1,128,128,128,1,237,237,237,22,255,255,255,25,208, + 208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_tstringdisp: record size: integer; data: array[0..826] of byte end = + (size: 827; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,115,116, + 114,105,110,103,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,196,2,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,124,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209,209,209, + 22,255,255,255,1,128,128,128,1,211,211,211,8,192,192,192,1,211,211,211, + 13,255,255,255,1,128,128,128,1,214,214,214,8,7,7,7,1,214,214,214, + 13,255,255,255,1,128,128,128,1,217,217,217,8,7,7,7,1,217,217,217, + 13,255,255,255,1,128,128,128,1,219,219,219,1,218,218,218,1,106,106,106, + 1,35,35,35,1,22,22,22,1,60,60,60,1,201,201,201,1,219,219,219, + 1,7,7,7,1,123,123,123,1,35,35,35,1,50,50,50,1,186,186,186, + 1,219,219,219,1,210,210,210,1,76,76,76,1,29,29,29,1,60,60,60, + 1,178,178,178,1,219,219,219,3,255,255,255,1,128,128,128,1,222,222,222, + 1,177,177,177,1,57,57,57,1,218,218,218,1,219,219,219,1,68,68,68, + 1,126,126,126,1,222,222,222,1,7,7,7,1,109,109,109,1,219,219,219, + 1,120,120,120,1,53,53,53,1,222,222,222,1,84,84,84,1,92,92,92, + 1,216,216,216,1,166,166,166,1,61,61,61,1,222,222,222,3,255,255,255, + 1,128,128,128,1,224,224,224,2,204,204,204,1,148,148,148,1,105,105,105, + 1,35,35,35,1,112,112,112,1,224,224,224,1,8,8,8,1,202,202,202, + 1,224,224,224,1,208,208,208,1,4,4,4,1,218,218,218,1,26,26,26, + 1,181,181,181,1,224,224,224,6,255,255,255,1,128,128,128,1,227,227,227, + 1,174,174,174,1,25,25,25,1,109,109,109,1,161,161,161,1,88,88,88, + 1,113,113,113,1,227,227,227,1,10,10,10,1,219,219,219,1,227,227,227, + 1,215,215,215,1,6,6,6,1,220,220,220,1,14,14,14,1,193,193,193, + 1,227,227,227,2,207,207,207,1,227,227,227,3,255,255,255,1,128,128,128, + 1,229,229,229,1,113,113,113,1,101,101,101,1,229,229,229,1,222,222,222, + 1,44,44,44,1,110,110,110,1,229,229,229,1,7,7,7,1,148,148,148, + 1,229,229,229,1,142,142,142,1,49,49,49,1,229,229,229,1,64,64,64, + 1,126,126,126,1,229,229,229,1,191,191,191,1,41,41,41,1,228,228,228, + 1,229,229,229,2,255,255,255,1,128,128,128,1,232,232,232,1,200,200,200, + 1,45,45,45,1,63,63,63,1,55,55,55,1,86,86,86,2,232,232,232, + 1,17,17,17,1,99,99,99,1,48,48,48,1,70,70,70,1,195,195,195, + 1,232,232,232,1,199,199,199,1,79,79,79,1,51,51,51,1,50,50,50, + 1,173,173,173,1,232,232,232,3,255,255,255,1,128,128,128,1,235,235,235, + 3,219,219,219,1,235,235,235,6,228,228,228,1,235,235,235,5,226,226,226, + 1,235,235,235,5,255,255,255,1,128,128,128,1,237,237,237,22,255,255,255, + 25,208,208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_trichstringdisp: record size: integer; data: array[0..842] of byte end = + (size: 843; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,114,105, + 99,104,115,116,114,105,110,103,100,105,115,112,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,208,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,14,0,0,0,144,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,209,209,209, + 22,255,255,255,1,128,128,128,1,212,212,212,22,255,255,255,1,128,128,128, + 1,214,214,214,8,33,33,246,1,108,108,233,1,214,214,214,12,255,255,255, + 1,128,128,128,1,217,217,217,8,7,7,251,1,94,94,237,1,217,217,217, + 12,255,255,255,1,128,128,128,1,220,220,220,2,139,139,139,1,60,60,60, + 1,46,46,46,1,94,94,94,1,211,211,211,1,220,220,220,1,7,7,251, + 1,83,83,240,1,116,116,235,1,62,62,243,1,149,149,230,1,219,219,220, + 1,220,220,220,2,132,132,132,1,61,61,61,1,80,80,80,1,182,182,182, + 1,220,220,220,2,255,255,255,1,128,128,128,1,222,222,222,1,176,176,176, + 1,34,34,34,1,203,203,203,1,202,202,202,1,55,55,55,1,132,132,132, + 1,222,222,222,1,7,7,251,1,5,5,251,1,113,113,237,1,77,77,242, + 1,0,0,252,1,172,172,229,1,222,222,222,1,130,130,130,1,63,63,63, + 1,200,200,200,1,144,144,144,1,58,58,58,1,222,222,222,2,255,255,255, + 1,128,128,128,1,225,225,225,2,210,210,210,1,169,169,169,1,127,127,127, + 1,45,45,45,1,113,113,113,1,225,225,225,1,7,7,251,1,63,63,244, + 1,225,225,225,1,216,216,226,1,5,5,251,1,100,100,240,1,225,225,225, + 1,19,19,19,1,195,195,195,1,225,225,225,1,224,224,224,1,206,206,206, + 1,225,225,225,2,255,255,255,1,128,128,128,1,227,227,227,1,179,179,179, + 1,27,27,27,1,95,95,95,1,147,147,147,1,83,83,83,1,113,113,113, + 1,227,227,227,1,7,7,251,1,76,76,244,1,227,227,227,1,225,225,227, + 1,15,15,250,1,69,69,244,1,202,202,202,1,19,19,19,1,227,227,227, + 2,221,221,221,1,226,226,226,1,227,227,227,2,255,255,255,1,128,128,128, + 1,230,230,230,1,114,114,114,1,101,101,101,1,230,230,230,1,225,225,225, + 1,49,49,49,1,111,111,111,1,230,230,230,1,7,7,251,1,16,16,250, + 1,162,162,236,1,133,133,239,1,0,0,252,1,122,122,240,1,225,225,225, + 1,22,22,22,1,221,221,221,1,229,229,229,1,54,54,54,1,166,166,166, + 1,230,230,230,2,255,255,255,1,128,128,128,1,233,233,233,1,198,198,198, + 1,44,44,44,1,70,70,70,1,61,61,61,1,87,87,87,2,233,233,233, + 1,7,7,251,1,76,76,246,1,26,26,250,1,9,9,251,1,97,97,244, + 1,223,223,234,1,233,233,233,1,132,132,132,1,56,56,56,1,57,57,57, + 1,115,115,115,1,233,233,233,3,255,255,255,1,128,128,128,1,235,235,235, + 3,219,219,219,1,235,235,235,6,234,234,235,1,226,226,236,1,235,235,235, + 4,229,229,229,1,230,230,230,1,235,235,235,4,255,255,255,1,128,128,128, + 1,238,238,238,22,255,255,255,25,8,0,0,0,255,255,255,255,255,255,255, + 81,0,0) + ); + +const + objdata_tbooleandisp: record size: integer; data: array[0..723] of byte end = + (size: 724; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,98,111, + 111,108,101,97,110,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,92,2,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,20,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209,209, + 209,22,255,255,255,1,128,128,128,1,211,211,211,1,196,196,196,1,191,191, + 191,5,199,199,199,1,211,211,211,2,177,177,177,1,209,209,209,1,192,192, + 192,1,191,191,191,4,203,203,203,1,211,211,211,4,255,255,255,1,128,128, + 128,1,214,214,214,1,73,73,73,1,26,26,26,1,24,24,24,1,0,0, + 0,1,26,26,26,2,91,91,91,1,214,214,214,1,213,213,213,1,47,47, + 47,1,214,214,214,1,3,3,3,1,24,24,24,1,26,26,26,3,129,129, + 129,1,214,214,214,4,255,255,255,1,128,128,128,1,217,217,217,3,203,203, + 203,1,0,0,0,1,217,217,217,4,175,175,175,1,88,88,88,1,217,217, + 217,1,3,3,3,1,201,201,201,1,217,217,217,8,255,255,255,1,128,128, + 128,1,219,219,219,3,205,205,205,1,0,0,0,1,219,219,219,4,115,115, + 115,1,149,149,149,1,219,219,219,1,3,3,3,1,203,203,203,1,219,219, + 219,8,255,255,255,1,128,128,128,1,222,222,222,3,208,208,208,1,0,0, + 0,1,222,222,222,4,58,58,58,1,210,210,210,1,222,222,222,1,3,3, + 3,1,77,77,77,1,83,83,83,2,103,103,103,1,222,222,222,5,255,255, + 255,1,128,128,128,1,224,224,224,3,210,210,210,1,0,0,0,1,224,224, + 224,3,212,212,212,1,57,57,57,1,224,224,224,2,3,3,3,1,136,136, + 136,1,147,147,147,2,158,158,158,1,224,224,224,5,255,255,255,1,128,128, + 128,1,227,227,227,3,213,213,213,1,0,0,0,1,227,227,227,3,155,155, + 155,1,117,117,117,1,227,227,227,2,3,3,3,1,210,210,210,1,227,227, + 227,8,255,255,255,1,128,128,128,1,229,229,229,3,215,215,215,1,0,0, + 0,1,229,229,229,3,92,92,92,1,181,181,181,1,229,229,229,2,3,3, + 3,1,212,212,212,1,229,229,229,8,255,255,255,1,128,128,128,1,232,232, + 232,3,217,217,217,1,0,0,0,1,232,232,232,3,46,46,46,1,230,230, + 230,1,232,232,232,2,3,3,3,1,215,215,215,1,232,232,232,8,255,255, + 255,1,128,128,128,1,235,235,235,7,234,234,234,1,213,213,213,1,235,235, + 235,13,255,255,255,1,128,128,128,1,237,237,237,22,255,255,255,25,208,208, + 208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0, + 0,120,0,0) + ); + +const + objdata_tedit: record size: integer; data: array[0..484] of byte end = + (size: 485; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,5,116,101,100, + 105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110, + 116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111, + 112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98, + 109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112, + 46,105,109,97,103,101,10,116,1,0,0,0,0,0,0,6,0,0,0,24, + 0,0,0,24,0,0,0,44,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,255,255,255,120,128,128,128,25,0,0,0,22,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0, + 0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,18,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,18,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,18,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,18,0,0,0,1,255,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,18,0,0,0,1,255, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,18,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0, + 0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_ttoolbar: record size: integer; data: array[0..727] of byte end = + (size: 728; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,116,111, + 111,108,98,97,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,100,2,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,32,2,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,208,208,208,168,255,255,255,23,128,128,128,1,255,255, + 255,1,208,208,208,16,204,204,204,1,208,208,208,5,128,128,128,1,255,255, + 255,1,208,208,208,2,108,108,151,2,208,208,208,3,191,202,188,1,86,161, + 69,1,39,143,15,1,111,171,97,1,207,208,207,1,208,208,208,1,115,115, + 115,1,255,255,255,1,208,208,208,1,159,159,159,1,141,141,141,1,202,202, + 202,1,208,208,208,3,128,128,128,1,255,255,255,1,208,208,208,2,73,73, + 159,2,208,208,208,3,113,171,100,1,88,162,71,1,175,195,170,1,52,148, + 30,1,163,191,156,1,208,208,208,1,115,115,115,1,255,255,255,1,208,208, + 208,1,158,158,158,1,104,104,104,1,109,109,109,1,178,178,178,1,208,208, + 208,2,128,128,128,1,255,255,255,1,108,108,151,1,73,73,159,1,38,38, + 167,2,73,73,159,1,108,108,151,1,208,208,208,1,66,153,46,1,163,191, + 157,1,208,208,208,1,113,172,99,1,118,173,105,1,208,208,208,1,115,115, + 115,1,255,255,255,1,208,208,208,1,158,158,158,1,144,144,144,1,176,176, + 176,1,107,107,107,1,141,141,141,1,202,202,202,1,128,128,128,1,255,255, + 255,1,108,108,151,1,73,73,159,1,38,38,167,2,73,73,159,1,108,108, + 151,1,208,208,208,1,66,154,46,1,166,192,160,1,208,208,208,1,115,172, + 102,1,117,173,104,1,208,208,208,1,115,115,115,1,255,255,255,1,208,208, + 208,1,158,158,158,1,144,144,144,1,176,176,176,1,108,108,108,1,141,141, + 141,1,202,202,202,1,128,128,128,1,255,255,255,1,208,208,208,2,73,73, + 159,2,208,208,208,3,103,168,88,1,104,168,89,1,199,204,198,1,63,152, + 42,1,153,187,145,1,208,208,208,1,115,115,115,1,255,255,255,1,208,208, + 208,1,158,158,158,1,104,104,104,1,110,110,110,1,180,180,180,1,208,208, + 208,2,128,128,128,1,255,255,255,1,208,208,208,2,108,108,151,2,208,208, + 208,3,182,198,178,1,64,152,43,1,32,141,7,1,87,161,70,1,205,207, + 205,1,208,208,208,1,115,115,115,1,255,255,255,1,208,208,208,1,159,159, + 159,1,144,144,144,1,204,204,204,1,208,208,208,3,128,128,128,1,255,255, + 255,1,208,208,208,9,195,203,193,1,208,208,208,6,205,205,205,1,208,208, + 208,5,128,128,128,25,208,208,208,168,12,0,0,0,0,0,0,168,255,255, + 255,240,0,0,0,168,0,0) + ); + +const + objdata_tsplitter: record size: integer; data: array[0..1428] of byte end = + (size: 1429; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,112, + 108,105,116,116,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,32,5,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,244,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,3,3,3,1,7,7,7,1,18,18,18,1,224, + 224,224,2,139,139,139,1,7,7,7,2,58,58,58,1,224,224,224,2,81, + 81,81,1,7,7,7,2,107,107,107,1,224,224,224,2,39,39,39,1,7, + 7,7,2,177,177,177,1,224,224,224,2,255,255,255,1,7,7,7,1,224, + 224,224,21,7,7,7,1,255,255,255,1,26,26,26,1,224,224,224,21,7, + 7,7,1,0,0,0,1,224,224,224,22,25,25,25,1,0,0,0,1,224, + 224,224,22,145,145,145,1,0,0,0,1,131,131,131,1,224,224,224,21,145, + 145,145,1,0,0,0,1,7,7,7,1,224,224,224,9,112,112,112,1,224, + 224,224,1,112,112,112,1,224,224,224,9,99,99,99,1,0,0,0,1,7, + 7,7,1,224,224,224,9,0,0,0,1,224,224,224,1,0,0,0,1,224, + 224,224,9,7,7,7,1,0,0,0,1,64,64,64,1,224,224,224,9,0, + 0,0,1,224,224,224,1,0,0,0,1,224,224,224,9,7,7,7,1,0, + 0,0,1,224,224,224,5,55,55,55,1,168,168,168,1,224,224,224,3,0, + 0,0,1,224,224,224,1,0,0,0,1,224,224,224,3,168,168,168,1,55, + 55,55,1,224,224,224,4,55,55,55,1,0,0,0,1,224,224,224,5,0, + 0,0,2,55,55,55,1,168,168,168,1,224,224,224,1,0,0,0,1,224, + 224,224,1,0,0,0,1,224,224,224,1,168,168,168,1,55,55,55,1,0, + 0,0,2,224,224,224,4,145,145,145,1,0,0,0,1,75,75,75,1,112, + 112,112,1,0,0,0,7,112,112,112,1,0,0,0,1,224,224,224,1,0, + 0,0,1,112,112,112,1,0,0,0,7,112,112,112,1,145,145,145,1,0, + 0,0,1,7,7,7,1,224,224,224,4,0,0,0,2,55,55,55,1,168, + 168,168,1,224,224,224,1,0,0,0,1,224,224,224,1,0,0,0,1,224, + 224,224,1,168,168,168,1,55,55,55,1,0,0,0,2,224,224,224,4,64, + 64,64,1,0,0,0,1,7,7,7,1,224,224,224,4,55,55,55,1,168, + 168,168,1,224,224,224,3,0,0,0,1,224,224,224,1,0,0,0,1,224, + 224,224,3,168,168,168,1,55,55,55,1,224,224,224,4,7,7,7,1,0, + 0,0,1,115,115,115,1,224,224,224,9,0,0,0,1,224,224,224,1,0, + 0,0,1,224,224,224,9,7,7,7,1,0,0,0,1,224,224,224,10,0, + 0,0,1,224,224,224,1,0,0,0,1,224,224,224,9,90,90,90,1,0, + 0,0,1,224,224,224,10,112,112,112,1,224,224,224,1,112,112,112,1,224, + 224,224,9,145,145,145,1,0,0,0,1,35,35,35,1,224,224,224,21,145, + 145,145,1,0,0,0,1,7,7,7,1,224,224,224,21,32,32,32,1,0, + 0,0,1,7,7,7,1,224,224,224,21,7,7,7,1,0,0,0,1,189, + 189,189,1,224,224,224,21,7,7,7,1,0,0,0,1,224,224,224,22,129, + 129,129,1,0,0,0,1,179,179,179,1,7,7,7,2,28,28,28,1,145, + 145,145,2,94,94,94,1,7,7,7,2,59,59,59,1,145,145,145,2,59, + 59,59,1,7,7,7,2,94,94,94,1,145,145,145,2,28,28,28,1,7, + 7,7,2,134,134,134,1,85,85,85,1,0,0,0,1,255,255,255,1,0, + 0,0,23,244,1,0,0,244,244,244,1,248,248,248,1,236,236,236,1,128, + 128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188, + 188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,218,218,218,1,248, + 248,248,2,143,143,143,1,128,128,128,1,64,64,64,1,0,0,0,1,248, + 248,248,1,255,255,255,21,248,248,248,1,0,0,0,1,229,229,229,1,255, + 255,255,21,248,248,248,1,16,16,16,1,128,128,128,1,255,255,255,21,241, + 241,241,1,106,106,106,1,128,128,128,1,255,255,255,21,198,198,198,1,122, + 122,122,1,161,161,161,1,255,255,255,21,198,198,198,1,122,122,122,1,248, + 248,248,1,255,255,255,21,213,213,213,1,122,122,122,1,248,248,248,1,255, + 255,255,21,252,252,252,1,122,122,122,1,199,199,199,1,255,255,255,21,252, + 252,252,1,122,122,122,1,128,128,128,1,255,255,255,21,230,230,230,1,122, + 122,122,1,128,128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,191, + 191,191,1,255,255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255, + 255,255,21,226,226,226,1,122,122,122,1,248,248,248,1,255,255,255,21,252, + 252,252,1,122,122,122,1,169,169,169,1,255,255,255,21,252,252,252,1,122, + 122,122,1,128,128,128,1,255,255,255,21,216,216,216,1,122,122,122,1,128, + 128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,221,221,221,1,255, + 255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255,255,255,21,240, + 240,240,1,122,122,122,1,248,248,248,1,255,255,255,21,252,252,252,1,122, + 122,122,1,139,139,139,1,255,255,255,21,252,252,252,1,122,122,122,1,128, + 128,128,1,255,255,255,21,203,203,203,1,122,122,122,1,75,75,75,1,248, + 248,248,1,251,251,251,1,242,242,242,1,198,198,198,2,215,215,215,1,252, + 252,252,2,228,228,228,1,198,198,198,2,228,228,228,1,252,252,252,2,215, + 215,215,1,198,198,198,2,242,242,242,1,252,252,252,2,201,201,201,1,169, + 169,169,1,122,122,122,1,0,0,0,1,16,16,16,1,106,106,106,1,122, + 122,122,20,106,106,106,1,0,0) + ); + +const + objdata_tdockhandle: record size: integer; data: array[0..459] of byte end = + (size: 460; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,111, + 99,107,104,97,110,100,108,101,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,156,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,104,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0, + 255,237,255,255,255,1,255,0,255,22,255,255,255,1,128,128,128,1,255,0, + 255,21,255,255,255,1,128,128,128,1,192,192,192,1,255,0,255,20,255,255, + 255,1,128,128,128,1,192,192,192,1,255,255,255,1,255,0,255,19,255,255, + 255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128,128,1,255,0, + 255,18,255,255,255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128, + 128,1,192,192,192,1,255,0,255,17,255,255,255,1,128,128,128,1,192,192, + 192,1,255,255,255,1,128,128,128,1,192,192,192,1,255,255,255,1,255,0, + 255,16,255,255,255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128, + 128,1,192,192,192,1,255,255,255,1,128,128,128,1,255,0,255,15,255,255, + 255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128,128,1,192,192, + 192,1,255,255,255,1,128,128,128,1,255,0,255,15,255,255,255,1,128,128, + 128,1,192,192,192,1,255,255,255,1,128,128,128,1,192,192,192,1,255,255, + 255,1,128,128,128,1,255,0,255,15,255,255,255,1,128,128,128,1,192,192, + 192,1,255,255,255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128, + 128,1,255,0,255,15,255,255,255,1,128,128,128,1,192,192,192,1,255,255, + 255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128,128,1,255,0, + 255,15,255,255,255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128, + 128,1,192,192,192,1,255,255,255,1,128,128,128,1,255,0,255,55,0,0) + ); + +const + objdata_teventwidget: record size: integer; data: array[0..1619] of byte end = + (size: 1620; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,101,118, + 101,110,116,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,5,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,192,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,14,0,0, + 255,2,208,208,208,6,255,255,255,1,128,128,128,1,208,208,208,13,0,0, + 255,1,7,7,255,1,6,6,255,1,208,208,208,6,255,255,255,1,128,128, + 128,1,208,208,208,12,0,0,255,1,34,34,255,1,136,136,255,1,71,71, + 255,1,0,0,255,1,208,208,208,5,255,255,255,1,128,128,128,1,208,208, + 208,10,0,0,255,1,2,2,255,1,75,75,255,1,175,175,255,1,82,82, + 255,1,5,5,255,1,0,0,255,1,208,208,208,5,255,255,255,1,128,128, + 128,1,208,208,208,9,0,0,255,1,14,14,255,1,119,119,255,1,143,143, + 255,1,28,28,255,1,0,0,255,1,208,208,208,7,255,255,255,1,128,128, + 128,1,208,208,208,8,0,0,255,1,42,42,255,1,160,160,255,1,81,81, + 255,1,4,4,255,1,0,0,255,1,208,208,208,8,255,255,255,1,128,128, + 128,1,208,208,208,6,0,0,255,1,4,4,255,1,86,86,255,1,142,142, + 255,1,26,26,255,1,0,0,255,1,208,208,208,10,255,255,255,1,128,128, + 128,1,208,208,208,5,0,0,255,1,17,17,255,1,132,132,255,1,80,80, + 255,1,4,4,255,1,0,0,255,1,208,208,208,11,255,255,255,1,128,128, + 128,1,208,208,208,4,0,0,255,1,46,46,255,1,130,130,255,1,26,26, + 255,1,0,0,255,1,208,208,208,13,255,255,255,1,128,128,128,1,208,208, + 208,3,0,0,255,1,28,28,255,1,97,97,255,1,5,5,255,1,0,0, + 255,1,208,208,208,14,255,255,255,1,128,128,128,1,208,208,208,4,0,0, + 255,1,3,3,255,1,0,0,255,3,208,208,208,13,255,255,255,1,128,128, + 128,1,208,208,208,6,0,0,255,5,208,208,208,11,255,255,255,1,128,128, + 128,1,208,208,208,7,0,0,255,6,208,208,208,9,255,255,255,1,128,128, + 128,1,208,208,208,9,0,0,255,5,208,208,208,8,255,255,255,1,128,128, + 128,1,208,208,208,8,0,0,255,2,208,208,208,1,0,0,255,4,208,208, + 208,7,255,255,255,1,128,128,128,1,208,208,208,8,12,12,255,1,17,17, + 255,1,208,208,208,1,0,0,255,4,208,208,208,7,255,255,255,1,128,128, + 128,1,208,208,208,7,0,0,255,1,72,72,255,1,64,64,255,1,0,0, + 255,3,208,208,208,9,255,255,255,1,128,128,128,1,208,208,208,7,52,52, + 255,1,140,140,255,1,55,55,255,1,0,0,255,2,208,208,208,10,255,255, + 255,1,128,128,128,1,208,208,208,6,27,27,255,1,130,130,255,1,169,169, + 255,1,94,94,255,1,34,34,255,1,0,0,255,3,208,208,208,8,255,255, + 255,1,128,128,128,1,208,208,208,6,97,97,255,1,171,171,255,1,108,108, + 255,1,42,42,255,1,0,0,255,4,208,208,208,8,255,255,255,1,128,128, + 128,1,208,208,208,5,27,27,255,1,127,127,255,1,75,75,255,1,22,22, + 255,1,0,0,255,1,208,208,208,12,255,255,255,1,128,128,128,1,208,208, + 208,5,0,0,255,1,208,208,208,16,255,255,255,25,228,2,0,0,255,255, + 255,25,0,0,0,14,15,15,15,1,17,17,17,1,0,0,0,6,255,255, + 255,2,0,0,0,13,47,47,47,1,182,182,182,1,134,134,134,1,0,0, + 0,6,255,255,255,2,0,0,0,12,96,96,96,1,193,193,193,1,253,253, + 253,1,187,187,187,1,20,20,20,1,0,0,0,5,255,255,255,2,0,0, + 0,10,7,7,7,1,146,146,146,1,208,208,208,1,255,255,255,1,200,200, + 200,1,150,150,150,1,15,15,15,1,0,0,0,5,255,255,255,2,0,0, + 0,9,32,32,32,1,176,176,176,1,230,230,230,1,232,232,232,1,183,183, + 183,1,71,71,71,1,0,0,0,7,255,255,255,2,0,0,0,8,74,74, + 74,1,188,188,188,1,248,248,248,1,199,199,199,1,142,142,142,1,12,12, + 12,1,0,0,0,8,255,255,255,2,0,0,0,6,2,2,2,1,127,127, + 127,1,201,201,201,1,228,228,228,1,183,183,183,1,60,60,60,1,0,0, + 0,10,255,255,255,2,0,0,0,5,20,20,20,1,166,166,166,1,220,220, + 220,1,197,197,197,1,132,132,132,1,8,8,8,1,0,0,0,11,255,255, + 255,2,0,0,0,4,55,55,55,1,184,184,184,1,216,216,216,1,179,179, + 179,1,49,49,49,1,0,0,0,13,255,255,255,2,0,0,0,3,33,33, + 33,1,206,206,206,1,226,226,226,1,203,203,203,1,10,10,10,1,0,0, + 0,14,255,255,255,2,0,0,0,4,30,30,30,1,159,159,159,1,206,206, + 206,1,189,189,189,1,64,64,64,1,0,0,0,13,255,255,255,2,0,0, + 0,6,61,61,61,1,180,180,180,1,207,207,207,1,154,154,154,1,21,21, + 21,1,0,0,0,11,255,255,255,2,0,0,0,7,2,2,2,1,101,101, + 101,1,196,196,196,1,200,200,200,1,101,101,101,1,1,1,1,1,0,0, + 0,9,255,255,255,2,0,0,0,9,15,15,15,1,137,137,137,1,206,206, + 206,1,179,179,179,1,46,46,46,1,0,0,0,8,255,255,255,2,0,0, + 0,8,14,14,14,1,9,9,9,1,0,0,0,1,38,38,38,1,169,169, + 169,1,210,210,210,1,124,124,124,1,0,0,0,7,255,255,255,2,0,0, + 0,8,124,124,124,1,59,59,59,1,0,0,0,1,5,5,5,1,141,141, + 141,1,177,177,177,1,27,27,27,1,0,0,0,7,255,255,255,2,0,0, + 0,7,31,31,31,1,223,223,223,1,96,96,96,1,33,33,33,1,180,180, + 180,1,88,88,88,1,0,0,0,9,255,255,255,2,0,0,0,7,149,149, + 149,1,255,255,255,1,165,165,165,1,148,148,148,1,19,19,19,1,0,0, + 0,10,255,255,255,2,0,0,0,6,57,57,57,1,240,240,240,1,255,255, + 255,1,239,239,239,1,183,183,183,1,136,136,136,1,87,87,87,1,16,16, + 16,1,0,0,0,8,255,255,255,2,0,0,0,6,173,173,173,1,255,255, + 255,2,239,239,239,1,191,191,191,1,139,139,139,1,88,88,88,1,15,15, + 15,1,0,0,0,8,255,255,255,2,0,0,0,5,84,84,84,1,193,193, + 193,1,144,144,144,1,94,94,94,1,22,22,22,1,0,0,0,12,255,255, + 255,2,0,0,0,5,3,3,3,1,0,0,0,16,255,255,255,25,0,0) + ); + +const + objdata_tdockpanel: record size: integer; data: array[0..2297] of byte end = + (size: 2298; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,100,111, + 99,107,112,97,110,101,108,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,132,8,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,64,8,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,128,128,128,25,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tstockglyphbutton: record size: integer; data: array[0..772] of byte end = + (size: 773; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,115,116, + 111,99,107,103,108,121,112,104,98,117,116,116,111,110,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,136, + 2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,212, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,125,224, + 224,224,14,255,255,255,10,224,224,224,1,255,255,255,12,0,0,0,1,255, + 255,255,10,224,224,224,1,255,255,255,1,235,235,235,10,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,232,232,232,2,205, + 205,205,1,232,232,232,4,205,205,205,1,232,232,232,2,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,229,229,229,1,202, + 202,202,1,22,22,22,1,175,175,175,1,229,229,229,2,175,175,175,1,22, + 22,22,1,202,202,202,1,229,229,229,1,128,128,128,1,0,0,0,1,255, + 255,255,10,224,224,224,1,255,255,255,1,226,226,226,2,173,173,173,1,21, + 21,21,1,173,173,173,2,21,21,21,1,173,173,173,1,226,226,226,2,128, + 128,128,1,0,0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,223, + 223,223,3,171,171,171,1,16,16,16,2,171,171,171,1,223,223,223,3,128, + 128,128,1,0,0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,221, + 221,221,3,169,169,169,1,16,16,16,2,169,169,169,1,221,221,221,3,128, + 128,128,1,0,0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,218, + 218,218,2,167,167,167,1,21,21,21,1,167,167,167,2,21,21,21,1,167, + 167,167,1,218,218,218,2,128,128,128,1,0,0,0,1,255,255,255,10,224, + 224,224,1,255,255,255,1,215,215,215,1,190,190,190,1,20,20,20,1,164, + 164,164,1,215,215,215,2,164,164,164,1,20,20,20,1,190,190,190,1,215, + 215,215,1,128,128,128,1,0,0,0,1,255,255,255,10,224,224,224,1,255, + 255,255,1,212,212,212,2,187,187,187,1,212,212,212,4,187,187,187,1,212, + 212,212,2,128,128,128,1,0,0,0,1,255,255,255,10,224,224,224,1,255, + 255,255,1,209,209,209,10,128,128,128,1,0,0,0,1,255,255,255,10,224, + 224,224,1,128,128,128,12,0,0,0,1,255,255,255,10,0,0,0,14,255, + 255,255,125,124,0,0,0,0,0,0,125,255,255,255,14,0,0,0,10,255, + 255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0, + 0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255, + 255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0, + 0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255, + 255,255,1,208,208,208,1,255,255,255,12,0,0,0,10,255,255,255,14,0, + 0,0,10,255,255,255,14,0,0,0,125,0,0) + ); + +const + objdata_tgroupbox: record size: integer; data: array[0..2256] of byte end = + (size: 2257; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,103,114, + 111,117,112,98,111,120,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,92,8,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,164,7,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,208,208,208,3,0,0,0,3,208,208,208,3,0, + 0,0,1,208,208,208,17,0,0,0,9,208,208,208,12,128,128,128,3,0, + 0,0,10,128,128,128,12,230,230,230,1,229,229,229,1,204,204,204,1,184, + 184,184,1,169,169,169,1,183,183,183,1,135,135,135,1,170,170,170,1,163, + 163,163,1,157,157,157,1,147,147,147,1,219,219,219,1,218,218,218,1,217, + 217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128, + 128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226, + 226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215, + 215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230, + 230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225, + 225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214, + 214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213, + 213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208, + 208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212, + 212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255, + 255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227, + 227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222, + 222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217, + 217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128, + 128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226, + 226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215, + 215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230, + 230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225, + 225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214, + 214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213, + 213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208, + 208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212, + 212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255, + 255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227, + 227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222, + 222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217, + 217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128, + 128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226, + 226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215, + 215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230, + 230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225, + 225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214, + 214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213, + 213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208, + 208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212, + 212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255, + 255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227, + 227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222, + 222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217, + 217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128, + 128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226, + 226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215, + 215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230, + 230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225, + 225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214, + 214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213, + 213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208, + 208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212, + 212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255, + 255,255,25,128,0,0,0,0,0,0,3,19,19,19,1,88,88,88,1,58, + 58,58,1,0,0,0,3,46,46,46,1,0,0,0,17,55,55,55,1,141, + 141,141,1,175,175,175,1,58,58,58,1,31,31,31,1,69,69,69,1,102, + 102,102,1,84,84,84,1,91,91,91,1,0,0,0,12,255,255,255,2,128, + 128,128,1,55,55,55,1,154,154,154,1,161,161,161,1,91,91,91,1,63, + 63,63,1,122,122,122,1,136,136,136,1,147,147,147,1,126,126,126,1,13, + 13,13,1,255,255,255,255,255,255,255,255,255,255,255,5,0,0) + ); + +const + objdata_tscrollbox: record size: integer; data: array[0..2205] of byte end = + (size: 2206; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,115,99, + 114,111,108,108,98,111,120,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,40,8,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,228,7,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,128,128,128,25,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,5,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,210,210,210,1,209,209,209,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,128,128,128,4, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 250,250,250,1,211,211,211,1,252,252,252,1,211,211,211,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,215,215,215,1, + 255,255,255,1,209,209,209,1,255,255,255,2,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,5,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,210,210,210,1,209,209,209,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1, + 210,210,210,1,209,209,209,1,128,128,128,1,255,255,255,1,128,128,128,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1,210,210,210,1, + 209,209,209,1,128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,128,128,128,4,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,210,210,210,1,250,250,250,1, + 211,211,211,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,248,248,248,1,215,215,215,1,247,247,247,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 250,250,250,1,215,215,215,1,255,255,255,1,211,211,211,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,214,214,214,1, + 254,254,254,1,210,210,210,1,255,255,255,2,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,5,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 128,128,128,4,255,255,255,25,12,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,66,0,0) + ); + +const + objdata_tstepbox: record size: integer; data: array[0..2239] of byte end = + (size: 2240; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,115,116, + 101,112,98,111,120,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,76,8,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,8,8,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,128,128,128,17,0,0,0,1,128,128,128,2,0,0, + 0,1,128,128,128,4,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,0,0,0,2,212,212,212,1,211,211,211,1,0,0, + 0,2,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,0,0,0,3,212,212,212,1,211,211, + 211,1,0,0,0,3,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,0,0,0,4,212,212,212,1,211,211,211,1,0,0, + 0,4,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,0,0,0,3,212,212,212,1,211,211,211,1,0,0,0,3,255,255, + 255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,0,0,0,2,212,212,212,1,211,211,211,1,0,0, + 0,2,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,0,0, + 0,1,212,212,212,1,211,211,211,1,0,0,0,1,209,209,209,1,208,208, + 208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255, + 255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128, + 128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255, + 255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128, + 128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255, + 255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128, + 128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255, + 255,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_ttabbar: record size: integer; data: array[0..690] of byte end = + (size: 691; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,116,97, + 98,98,97,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,64,2,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,156,1,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,208,208,208,192,255,255,255,10,208,208,208,14,255,255,255, + 1,208,208,208,7,128,128,128,1,255,255,255,11,208,208,208,4,255,255,255, + 1,208,208,208,1,187,187,187,1,199,199,199,1,208,208,208,1,197,197,197, + 1,208,208,208,2,128,128,128,1,255,255,255,1,224,224,224,9,128,128,128, + 1,208,208,208,4,255,255,255,1,170,170,170,1,162,162,162,1,131,131,131, + 1,166,166,166,1,123,123,123,1,166,166,166,1,175,175,175,1,128,128,128, + 1,255,255,255,1,199,199,199,1,153,153,153,1,192,192,192,1,224,224,224, + 1,200,200,200,1,224,224,224,4,128,128,128,1,208,208,208,4,255,255,255, + 1,157,157,157,1,176,176,176,1,126,126,126,1,142,142,142,1,136,136,136, + 1,118,118,118,1,144,144,144,1,128,128,128,1,255,255,255,1,168,168,168, + 1,147,147,147,1,149,149,149,1,139,139,139,1,150,150,150,1,177,177,177, + 2,170,170,170,1,165,165,165,1,128,128,128,1,208,208,208,4,255,255,255, + 1,208,208,208,1,169,169,169,1,192,192,192,1,184,184,184,1,182,182,182, + 1,183,183,183,1,188,188,188,1,128,128,128,1,255,255,255,1,168,168,168, + 1,203,203,203,1,211,211,211,1,107,107,107,1,140,140,140,1,151,151,151, + 1,134,134,134,1,153,153,153,1,141,141,141,1,128,128,128,1,208,208,208, + 4,255,255,255,1,208,208,208,1,0,0,0,1,104,104,104,1,208,208,208, + 4,128,128,128,1,255,255,255,1,224,224,224,9,128,128,128,1,208,208,208, + 4,255,255,255,1,208,208,208,7,128,128,128,1,255,255,255,1,154,154,154, + 1,0,0,0,1,182,182,182,1,224,224,224,6,128,128,128,1,208,208,208, + 4,255,255,255,10,224,224,224,9,255,255,255,5,208,208,208,168,108,0,0, + 0,0,0,0,192,255,255,255,9,128,128,128,1,0,0,0,14,255,255,255, + 19,128,128,128,1,0,0,0,4,255,255,255,19,240,240,240,1,0,0,0, + 4,255,255,255,19,240,240,240,1,0,0,0,4,255,255,255,19,240,240,240, + 1,0,0,0,4,255,255,255,19,240,240,240,1,0,0,0,4,255,255,255, + 19,240,240,240,1,0,0,0,4,255,255,255,19,240,240,240,1,0,0,0, + 4,255,255,255,24,0,0,0,168,0,0) + ); + +const + objdata_ttabpage: record size: integer; data: array[0..2503] of byte end = + (size: 2504; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,116,97, + 98,112,97,103,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,84,9,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,80,7,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,255,255,255,8,251,251,251,1,254,254,254,1,230,230, + 230,1,229,229,229,7,240,240,240,1,255,255,255,1,208,208,208,4,255,255, + 255,1,211,211,211,1,208,208,208,6,133,133,133,1,252,252,252,1,254,254, + 254,9,248,248,248,1,208,208,208,4,255,255,255,1,211,211,211,1,157,157, + 157,1,171,171,171,1,208,208,208,1,183,183,183,1,208,208,208,2,133,133, + 133,1,252,252,252,1,225,225,225,1,224,224,224,8,128,128,128,2,208,208, + 208,3,255,255,255,1,163,163,163,1,185,185,185,1,139,139,139,1,152,152, + 152,1,118,118,118,1,151,151,151,1,156,156,156,1,133,133,133,1,252,252, + 252,1,206,206,206,1,151,151,151,1,189,189,189,1,224,224,224,1,204,204, + 204,1,221,221,221,1,224,224,224,3,128,128,128,2,208,208,208,3,255,255, + 255,1,184,184,184,1,134,134,134,1,122,122,122,1,138,138,138,1,124,124, + 124,1,116,116,116,1,136,136,136,1,133,133,133,1,252,252,252,1,181,181, + 181,1,138,138,138,1,148,148,148,1,143,143,143,1,150,150,150,1,171,171, + 171,1,177,177,177,1,172,172,172,1,162,162,162,1,128,128,128,2,208,208, + 208,3,255,255,255,1,211,211,211,1,201,201,201,1,205,205,205,1,208,208, + 208,4,133,133,133,1,252,252,252,1,181,181,181,1,191,191,191,1,216,216, + 216,1,105,105,105,1,146,146,146,1,148,148,148,1,132,132,132,1,155,155, + 155,1,138,138,138,1,128,128,128,2,208,208,208,3,255,255,255,1,211,211, + 211,1,19,19,19,1,95,95,95,1,208,208,208,4,133,133,133,1,252,252, + 252,1,223,223,223,1,217,217,217,1,222,222,222,1,224,224,224,6,128,128, + 128,2,208,208,208,3,255,255,255,1,214,214,214,1,211,211,211,6,143,143, + 143,1,252,252,252,1,174,174,174,1,6,6,6,1,170,170,170,1,224,224, + 224,6,132,132,132,1,193,193,193,1,255,255,255,13,228,228,228,1,224,224, + 224,8,253,253,253,1,255,255,255,4,18,18,18,1,0,0,0,2,76,76, + 76,1,228,228,228,1,227,227,227,1,75,75,75,1,0,0,0,2,74,74, + 74,1,221,221,221,1,220,220,220,1,73,73,73,1,0,0,0,2,72,72, + 72,1,215,215,215,1,214,214,214,1,71,71,71,1,0,0,0,2,70,70, + 70,1,209,209,209,1,208,208,208,1,0,0,0,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,69,69,69,1,77,77,77,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,0,0, + 0,1,232,232,232,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,0,0,0,1,232,232, + 232,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216, + 216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,69,69,69,1,77,77,77,1,231,231, + 231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,0,0,0,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,69,69, + 69,1,77,77,77,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,0,0,0,1,232,232, + 232,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216, + 216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,0,0,0,1,232,232,232,1,231,231, + 231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,69,69,69,1,77,77,77,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,69,69,69,1,46,46, + 46,1,231,231,231,1,230,230,230,1,76,76,76,1,0,0,0,2,75,75, + 75,1,225,225,225,1,223,223,223,1,74,74,74,1,0,0,0,2,73,73, + 73,1,218,218,218,1,217,217,217,1,72,72,72,1,0,0,0,2,71,71, + 71,1,212,212,212,1,211,211,211,1,70,70,70,1,0,0,0,2,204,1, + 0,0,240,240,240,1,248,248,248,8,146,146,146,1,23,23,23,8,16,16, + 16,1,4,4,4,1,0,0,0,4,240,240,240,1,241,241,241,1,255,255, + 255,17,149,149,149,1,0,0,0,4,240,240,240,1,241,241,241,1,255,255, + 255,17,233,233,233,1,8,8,8,1,0,0,0,3,240,240,240,1,244,244, + 244,1,255,255,255,17,233,233,233,1,8,8,8,1,0,0,0,3,240,240, + 240,1,243,243,243,1,255,255,255,17,233,233,233,1,8,8,8,1,0,0, + 0,3,240,240,240,1,241,241,241,1,255,255,255,17,233,233,233,1,8,8, + 8,1,0,0,0,3,240,240,240,1,241,241,241,1,255,255,255,17,233,233, + 233,1,8,8,8,1,0,0,0,3,234,234,234,1,235,235,235,1,248,248, + 248,6,254,254,254,1,255,255,255,10,234,234,234,1,16,16,16,1,8,8, + 8,3,253,253,253,1,255,255,255,9,234,234,234,1,248,248,248,8,236,236, + 236,1,248,248,248,4,208,208,208,1,255,255,255,2,192,192,192,1,128,128, + 128,2,192,192,192,1,255,255,255,2,192,192,192,1,128,128,128,2,192,192, + 192,1,255,255,255,2,192,192,192,1,128,128,128,2,192,192,192,1,255,255, + 255,2,192,192,192,1,128,128,128,1,64,64,64,1,255,255,255,23,192,192, + 192,2,255,255,255,23,128,128,128,1,255,255,255,23,128,128,128,1,255,255, + 255,22,192,192,192,2,255,255,255,22,128,128,128,1,255,255,255,23,128,128, + 128,1,255,255,255,23,192,192,192,2,255,255,255,23,128,128,128,1,255,255, + 255,23,128,128,128,1,255,255,255,22,192,192,192,2,255,255,255,22,128,128, + 128,1,255,255,255,23,128,128,128,1,255,255,255,23,192,192,192,1,160,160, + 160,1,128,128,128,2,192,192,192,1,255,255,255,2,192,192,192,1,128,128, + 128,2,192,192,192,1,255,255,255,2,192,192,192,1,128,128,128,2,192,192, + 192,1,255,255,255,2,192,192,192,1,128,128,128,2,192,192,192,1,255,255, + 255,2,0,0) + ); + +const + objdata_ttabwidget: record size: integer; data: array[0..2217] of byte end = + (size: 2218; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,116,97, + 98,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,52,8,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,20,7,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,8,251,251,251,1,254,254,254,1, + 230,230,230,1,229,229,229,7,240,240,240,1,255,255,255,1,208,208,208,4, + 255,255,255,1,211,211,211,1,208,208,208,6,133,133,133,1,252,252,252,1, + 254,254,254,9,248,248,248,1,208,208,208,4,255,255,255,1,211,211,211,1, + 157,157,157,1,171,171,171,1,208,208,208,1,183,183,183,1,208,208,208,2, + 133,133,133,1,252,252,252,1,225,225,225,1,224,224,224,8,128,128,128,2, + 208,208,208,3,255,255,255,1,163,163,163,1,185,185,185,1,139,139,139,1, + 152,152,152,1,118,118,118,1,151,151,151,1,156,156,156,1,133,133,133,1, + 252,252,252,1,206,206,206,1,151,151,151,1,189,189,189,1,224,224,224,1, + 204,204,204,1,221,221,221,1,224,224,224,3,128,128,128,2,208,208,208,3, + 255,255,255,1,184,184,184,1,134,134,134,1,122,122,122,1,138,138,138,1, + 124,124,124,1,116,116,116,1,136,136,136,1,133,133,133,1,252,252,252,1, + 181,181,181,1,138,138,138,1,148,148,148,1,143,143,143,1,150,150,150,1, + 171,171,171,1,177,177,177,1,172,172,172,1,162,162,162,1,128,128,128,2, + 208,208,208,3,255,255,255,1,211,211,211,1,201,201,201,1,205,205,205,1, + 208,208,208,4,133,133,133,1,252,252,252,1,181,181,181,1,191,191,191,1, + 216,216,216,1,105,105,105,1,146,146,146,1,148,148,148,1,132,132,132,1, + 155,155,155,1,138,138,138,1,128,128,128,2,208,208,208,3,255,255,255,1, + 211,211,211,1,19,19,19,1,95,95,95,1,208,208,208,4,133,133,133,1, + 252,252,252,1,223,223,223,1,217,217,217,1,222,222,222,1,224,224,224,6, + 128,128,128,2,208,208,208,3,255,255,255,1,214,214,214,1,211,211,211,6, + 143,143,143,1,252,252,252,1,174,174,174,1,6,6,6,1,170,170,170,1, + 224,224,224,6,132,132,132,1,193,193,193,1,255,255,255,13,228,228,228,1, + 224,224,224,8,253,253,253,1,255,255,255,5,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,23, + 232,0,0,0,240,240,240,1,248,248,248,8,146,146,146,1,23,23,23,8, + 16,16,16,1,4,4,4,1,0,0,0,4,240,240,240,1,241,241,241,1, + 255,255,255,17,149,149,149,1,0,0,0,4,240,240,240,1,241,241,241,1, + 255,255,255,17,233,233,233,1,8,8,8,1,0,0,0,3,240,240,240,1, + 244,244,244,1,255,255,255,17,233,233,233,1,8,8,8,1,0,0,0,3, + 240,240,240,1,243,243,243,1,255,255,255,17,233,233,233,1,8,8,8,1, + 0,0,0,3,240,240,240,1,241,241,241,1,255,255,255,17,233,233,233,1, + 8,8,8,1,0,0,0,3,240,240,240,1,241,241,241,1,255,255,255,17, + 233,233,233,1,8,8,8,1,0,0,0,3,234,234,234,1,235,235,235,1, + 248,248,248,6,254,254,254,1,255,255,255,10,234,234,234,1,16,16,16,1, + 8,8,8,3,253,253,253,1,255,255,255,9,234,234,234,1,248,248,248,8, + 236,236,236,1,248,248,248,4,255,255,255,255,255,255,255,105,0,0) + ); + +const + objdata_tterminal: record size: integer; data: array[0..928] of byte end = + (size: 929; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,116,101, + 114,109,105,110,97,108,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,44,3,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,224,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,8,240,240,240,1,255,255,255,11,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,8,144, + 144,144,1,38,38,38,1,136,136,136,1,231,231,231,1,255,255,255,8,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,253, + 253,253,1,247,247,247,1,255,255,255,4,254,254,254,2,188,188,188,1,92, + 92,92,1,14,14,14,1,78,78,78,1,176,176,176,1,251,251,251,1,255, + 255,255,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,141, + 141,141,1,32,32,32,1,2,2,2,1,59,59,59,1,147,147,147,1,184, + 184,184,1,96,96,96,1,208,208,208,1,255,255,255,3,241,241,241,1,155, + 155,155,1,53,53,53,1,24,24,24,1,208,208,208,1,255,255,255,4,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,105,105,105,1,204, + 204,204,1,189,189,189,1,121,121,121,1,38,38,38,1,22,22,22,1,92, + 92,92,1,241,241,241,1,255,255,255,3,207,207,207,1,109,109,109,1,20, + 20,20,1,66,66,66,1,221,221,221,1,255,255,255,4,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,8,239,239,239,1,147, + 147,147,1,49,49,49,1,26,26,26,1,122,122,122,1,221,221,221,1,255, + 255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,8,145, + 145,145,1,78,78,78,1,178,178,178,1,252,252,252,1,255,255,255,5,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,17,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,17,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,17,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,16,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,25,20,0,0,0,255,255,255,255,255,255,255,255,255,255,255,42,128, + 128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tmseformwidget: record size: integer; data: array[0..2145] of byte end = + (size: 2146; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,102,111,114,109,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,232,7,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,164,7,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,25,242,166,149,1, + 221,216,211,1,242,166,149,1,255,134,109,2,121,64,52,1,157,83,67,1, + 187,98,80,1,208,109,89,2,247,130,106,1,212,111,91,1,255,134,109,4, + 160,160,160,6,128,128,128,1,255,255,255,1,221,216,211,1,7,239,255,1, + 221,216,211,1,255,134,109,2,120,63,51,1,201,106,86,1,181,95,77,1, + 135,71,58,1,214,112,91,1,139,73,59,1,163,86,70,1,242,127,103,1, + 255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160,1, + 209,209,209,1,128,128,128,2,255,255,255,1,242,166,149,1,221,216,211,1, + 242,166,149,1,255,134,109,2,212,111,91,1,255,134,109,1,218,115,93,1, + 204,107,87,1,180,95,77,1,222,117,95,1,184,97,79,1,253,133,108,1, + 255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160,1, + 209,209,209,1,128,128,128,2,255,255,255,1,151,24,0,16,128,128,128,7, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,25,12,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,66,0,0) + ); + +const + objdata_tdockformwidget: record size: integer; data: array[0..2082] of byte end = + (size: 2083; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,111, + 99,107,102,111,114,109,119,105,100,103,101,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,168,7,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,100,7,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,25,242,166,149, + 1,221,216,211,1,242,166,149,1,255,134,109,2,121,64,52,1,157,83,67, + 1,187,98,80,1,208,109,89,2,247,130,106,1,212,111,91,1,255,134,109, + 4,160,160,160,6,128,128,128,1,255,255,255,1,221,216,211,1,7,239,255, + 1,221,216,211,1,255,134,109,2,120,63,51,1,201,106,86,1,181,95,77, + 1,135,71,58,1,214,112,91,1,139,73,59,1,163,86,70,1,242,127,103, + 1,255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160, + 1,209,209,209,1,128,128,128,2,255,255,255,1,242,166,149,1,221,216,211, + 1,242,166,149,1,255,134,109,2,212,111,91,1,255,134,109,1,218,115,93, + 1,204,107,87,1,180,95,77,1,222,117,95,1,184,97,79,1,253,133,108, + 1,255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160, + 1,209,209,209,1,128,128,128,2,255,255,255,1,151,24,0,16,128,128,128, + 7,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128, + 1,252,252,252,1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,215,215,215,1,252,252,252,1,128,128,128,1,252,252,252,1,128,128,128, + 2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252, + 1,128,128,128,1,253,253,253,1,128,128,128,2,255,255,255,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225, + 1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214, + 1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128,1,253,253,253, + 1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215, + 1,252,252,252,1,128,128,128,1,253,253,253,1,128,128,128,2,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128, + 1,253,253,253,1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,215,215,215,1,252,252,252,1,128,128,128,1,253,253,253,1,128,128,128, + 2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252, + 1,128,128,128,1,254,254,254,1,128,128,128,2,255,255,255,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225, + 1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214, + 1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128,1,254,254,254, + 1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215, + 1,252,252,252,1,128,128,128,1,254,254,254,1,128,128,128,2,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128, + 1,254,254,254,1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,215,215,215,1,252,252,252,1,128,128,128,1,254,254,254,1,128,128,128, + 2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252, + 1,128,128,128,1,254,254,254,1,128,128,128,2,255,255,255,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225, + 1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214, + 1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128,1,255,255,255, + 1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215, + 1,252,252,252,1,128,128,128,1,255,255,255,1,128,128,128,2,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128, + 1,255,255,255,1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,215,215,215,1,252,252,252,1,210,210,210,1,209,209,209,1,208,208,208, + 1,128,128,128,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 66,0,0) + ); + +const + objdata_tpaintbox: record size: integer; data: array[0..1664] of byte end = + (size: 1665; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,112,97, + 105,110,116,98,111,120,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,12,6,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,112,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,208,208,208,17,0,255,255,1,208, + 208,208,4,255,255,255,1,128,128,128,1,208,208,208,16,49,167,255,1,97, + 188,255,1,147,210,255,1,208,208,208,3,255,255,255,1,128,128,128,1,208, + 208,208,16,51,168,255,1,170,219,255,1,88,184,255,1,0,146,255,1,208, + 208,208,2,255,255,255,1,128,128,128,1,208,208,208,15,52,168,255,1,112, + 194,255,1,136,205,255,1,29,158,255,1,0,145,255,1,208,208,208,2,255, + 255,255,1,128,128,128,1,208,208,208,14,57,170,255,1,53,168,255,1,185, + 226,255,1,77,179,255,1,0,146,255,1,0,128,255,1,208,208,208,2,255, + 255,255,1,128,128,128,1,208,208,208,14,51,168,255,1,126,200,255,1,125, + 200,255,1,17,153,255,1,0,147,255,1,208,208,208,3,255,255,255,1,128, + 128,128,1,208,208,208,13,55,164,255,1,67,175,255,1,173,220,255,1,65, + 174,255,1,0,146,255,1,208,208,208,4,255,255,255,1,128,128,128,1,208, + 208,208,13,51,168,255,1,140,206,255,1,113,195,255,1,5,148,255,1,0, + 143,255,1,208,208,208,4,255,255,255,1,128,128,128,1,208,208,208,12,50, + 168,255,1,82,181,255,1,161,215,255,1,53,169,255,1,0,147,255,1,208, + 208,208,5,255,255,255,1,128,128,128,1,208,208,208,11,0,255,255,1,51, + 168,255,1,155,213,255,1,101,190,255,1,0,146,255,1,0,142,255,1,208, + 208,208,5,255,255,255,1,128,128,128,1,208,208,208,8,68,222,239,1,98, + 195,228,1,51,157,241,1,52,167,255,1,96,187,255,1,149,210,255,1,42, + 164,255,1,0,146,255,1,208,208,208,6,255,255,255,1,128,128,128,1,208, + 208,208,7,0,242,255,1,60,203,240,1,143,192,218,1,139,176,218,1,87, + 135,233,1,152,199,254,1,90,184,255,1,0,146,255,1,0,128,255,1,208, + 208,208,6,255,255,255,1,128,128,128,1,208,208,208,7,0,218,255,1,0, + 176,255,1,16,138,251,1,91,140,232,1,146,159,217,1,131,132,220,1,72, + 123,238,1,3,140,255,1,208,208,208,7,255,255,255,1,128,128,128,1,208, + 208,208,7,0,193,255,1,0,149,255,1,1,106,255,1,1,62,255,1,25, + 40,249,1,102,116,228,1,147,168,216,1,123,170,223,1,105,186,227,1,208, + 208,208,6,255,255,255,1,128,128,128,1,208,208,208,7,0,167,255,1,0, + 123,255,1,1,79,255,1,1,35,255,1,1,12,255,1,1,56,255,1,34, + 117,246,1,112,178,226,1,89,196,232,1,208,208,208,6,255,255,255,1,128, + 128,128,1,208,208,208,7,0,140,255,1,1,96,255,1,1,52,255,1,1, + 9,255,1,1,39,255,1,1,83,255,1,0,127,255,1,0,171,255,1,1, + 214,255,1,208,208,208,6,255,255,255,1,128,128,128,1,208,208,208,7,0, + 111,255,1,1,69,255,1,1,26,255,1,1,21,255,1,1,66,255,1,1, + 110,255,1,0,154,255,1,0,198,255,1,0,230,255,1,208,208,208,6,255, + 255,255,1,128,128,128,1,208,208,208,7,0,85,255,1,1,43,255,1,1, + 4,255,1,1,48,255,1,1,92,255,1,0,137,255,1,0,181,255,1,0, + 226,255,1,208,208,208,7,255,255,255,1,128,128,128,1,208,208,208,7,0, + 61,255,1,1,16,255,1,1,31,255,1,1,75,255,1,0,119,255,1,0, + 162,255,1,0,209,255,1,208,208,208,8,255,255,255,1,128,128,128,1,208, + 208,208,6,0,77,255,1,1,34,255,1,1,14,255,1,1,58,255,1,1, + 102,255,1,0,146,255,1,0,186,255,1,208,208,208,9,255,255,255,1,128, + 128,128,1,208,208,208,6,2,51,255,1,1,7,255,1,2,40,255,1,0, + 86,255,1,0,139,255,1,208,208,208,11,255,255,255,1,128,128,128,1,208, + 208,208,22,255,255,255,25,100,2,0,0,255,255,255,25,0,0,0,17,1, + 1,1,1,0,0,0,4,255,255,255,2,0,0,0,16,52,52,52,1,214, + 214,214,1,80,80,80,1,0,0,0,3,255,255,255,2,0,0,0,16,196, + 196,196,1,255,255,255,2,178,178,178,1,0,0,0,2,255,255,255,2,0, + 0,0,15,88,88,88,1,255,255,255,3,109,109,109,1,0,0,0,2,255, + 255,255,2,0,0,0,14,9,9,9,1,225,225,225,1,255,255,255,2,215, + 215,215,1,4,4,4,1,0,0,0,2,255,255,255,2,0,0,0,14,126, + 126,126,1,255,255,255,3,73,73,73,1,0,0,0,3,255,255,255,2,0, + 0,0,13,28,28,28,1,245,245,245,1,255,255,255,2,183,183,183,1,0, + 0,0,4,255,255,255,2,0,0,0,13,164,164,164,1,255,255,255,2,251, + 251,251,1,41,41,41,1,0,0,0,4,255,255,255,2,0,0,0,12,56, + 56,56,1,254,254,254,1,255,255,255,2,146,146,146,1,0,0,0,5,255, + 255,255,2,0,0,0,11,1,1,1,1,200,200,200,1,255,255,255,2,238, + 238,238,1,18,18,18,1,0,0,0,5,255,255,255,2,0,0,0,8,127, + 127,127,1,210,210,210,1,55,55,55,1,93,93,93,1,255,255,255,3,110, + 110,110,1,0,0,0,6,255,255,255,2,0,0,0,7,60,60,60,1,255, + 255,255,2,254,254,254,1,213,213,213,1,239,239,239,1,255,255,255,1,215, + 215,215,1,4,4,4,1,0,0,0,6,255,255,255,2,0,0,0,7,82, + 82,82,1,255,255,255,4,251,251,251,1,211,211,211,1,80,80,80,1,0, + 0,0,7,255,255,255,2,0,0,0,7,91,91,91,1,255,255,255,6,245, + 245,245,1,93,93,93,1,0,0,0,6,255,255,255,2,0,0,0,7,87, + 87,87,1,255,255,255,7,197,197,197,1,0,0,0,6,255,255,255,2,0, + 0,0,7,71,71,71,1,255,255,255,7,201,201,201,1,0,0,0,6,255, + 255,255,2,0,0,0,7,55,55,55,1,255,255,255,6,232,232,232,1,31, + 31,31,1,0,0,0,6,255,255,255,2,0,0,0,7,39,39,39,1,255, + 255,255,5,240,240,240,1,53,53,53,1,0,0,0,7,255,255,255,2,0, + 0,0,7,100,100,100,1,255,255,255,4,226,226,226,1,44,44,44,1,0, + 0,0,8,255,255,255,2,0,0,0,6,10,10,10,1,223,223,223,1,255, + 255,255,2,245,245,245,1,168,168,168,1,26,26,26,1,0,0,0,9,255, + 255,255,2,0,0,0,6,130,130,130,1,192,192,192,1,148,148,148,1,89, + 89,89,1,11,11,11,1,0,0,0,11,255,255,255,2,0,0,0,22,255, + 255,255,25,0,0) + ); + +const + objdata_texpandingwidget: record size: integer; data: array[0..1843] of byte end = + (size: 1844; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,101,120, + 112,97,110,100,105,110,103,119,105,100,103,101,116,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,6, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,140,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,1,7,7, + 7,1,18,18,18,1,223,223,223,2,139,139,139,1,7,7,7,2,58,58, + 58,1,223,223,223,2,80,80,80,1,7,7,7,2,106,106,106,1,223,223, + 223,2,39,39,39,1,7,7,7,2,177,177,177,1,223,223,223,2,255,255, + 255,1,7,7,7,1,223,223,223,1,210,210,210,19,223,223,223,1,7,7, + 7,1,255,255,255,1,26,26,26,1,210,210,210,1,0,0,0,19,210,210, + 210,1,7,7,7,1,0,0,0,1,223,223,223,1,210,210,210,1,0,0, + 0,1,197,197,197,1,210,210,210,7,105,105,105,1,210,210,210,7,197,197, + 197,1,0,0,0,1,210,210,210,1,24,24,24,1,0,0,0,1,223,223, + 223,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224,224,6,168,168, + 168,1,0,0,0,1,168,168,168,1,224,224,224,6,210,210,210,1,0,0, + 0,1,210,210,210,1,144,144,144,1,0,0,0,1,131,131,131,1,210,210, + 210,1,0,0,0,1,210,210,210,1,224,224,224,6,55,55,55,1,0,0, + 0,1,55,55,55,1,224,224,224,6,210,210,210,1,0,0,0,1,210,210, + 210,1,144,144,144,1,0,0,0,1,7,7,7,1,210,210,210,1,0,0, + 0,1,210,210,210,1,224,224,224,5,168,168,168,1,0,0,0,3,168,168, + 168,1,224,224,224,5,210,210,210,1,0,0,0,1,210,210,210,1,100,100, + 100,1,0,0,0,1,7,7,7,1,210,210,210,1,0,0,0,1,210,210, + 210,1,224,224,224,5,55,55,55,1,0,0,0,3,55,55,55,1,224,224, + 224,5,210,210,210,1,0,0,0,1,210,210,210,1,7,7,7,1,0,0, + 0,1,64,64,64,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224, + 224,15,210,210,210,1,0,0,0,1,210,210,210,1,7,7,7,1,0,0, + 0,1,223,223,223,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224, + 224,2,168,168,168,1,55,55,55,1,224,224,224,7,55,55,55,1,168,168, + 168,1,224,224,224,2,210,210,210,1,0,0,0,1,210,210,210,1,55,55, + 55,1,0,0,0,1,223,223,223,1,210,210,210,1,0,0,0,1,210,210, + 210,1,168,168,168,1,55,55,55,1,0,0,0,2,224,224,224,7,0,0, + 0,2,55,55,55,1,168,168,168,1,210,210,210,1,0,0,0,1,210,210, + 210,1,144,144,144,1,0,0,0,1,75,75,75,1,210,210,210,1,0,0, + 0,1,105,105,105,1,0,0,0,4,224,224,224,7,0,0,0,4,105,105, + 105,1,0,0,0,1,210,210,210,1,144,144,144,1,0,0,0,1,7,7, + 7,1,210,210,210,1,0,0,0,1,210,210,210,1,168,168,168,1,55,55, + 55,1,0,0,0,2,224,224,224,7,0,0,0,2,55,55,55,1,168,168, + 168,1,210,210,210,1,0,0,0,1,210,210,210,1,63,63,63,1,0,0, + 0,1,7,7,7,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224, + 224,2,168,168,168,1,55,55,55,1,224,224,224,7,55,55,55,1,168,168, + 168,1,224,224,224,2,210,210,210,1,0,0,0,1,210,210,210,1,7,7, + 7,1,0,0,0,1,115,115,115,1,210,210,210,1,0,0,0,1,210,210, + 210,1,224,224,224,15,210,210,210,1,0,0,0,1,210,210,210,1,7,7, + 7,1,0,0,0,1,223,223,223,1,210,210,210,1,0,0,0,1,210,210, + 210,1,224,224,224,5,55,55,55,1,0,0,0,3,55,55,55,1,224,224, + 224,5,210,210,210,1,0,0,0,1,210,210,210,1,90,90,90,1,0,0, + 0,1,223,223,223,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224, + 224,5,168,168,168,1,0,0,0,3,168,168,168,1,224,224,224,5,210,210, + 210,1,0,0,0,1,210,210,210,1,144,144,144,1,0,0,0,1,35,35, + 35,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224,224,6,55,55, + 55,1,0,0,0,1,55,55,55,1,224,224,224,6,210,210,210,1,0,0, + 0,1,210,210,210,1,144,144,144,1,0,0,0,1,7,7,7,1,210,210, + 210,1,0,0,0,1,210,210,210,1,224,224,224,6,168,168,168,1,0,0, + 0,1,168,168,168,1,224,224,224,6,210,210,210,1,0,0,0,1,210,210, + 210,1,32,32,32,1,0,0,0,1,7,7,7,1,210,210,210,1,0,0, + 0,1,197,197,197,1,210,210,210,7,105,105,105,1,210,210,210,7,197,197, + 197,1,0,0,0,1,210,210,210,1,7,7,7,1,0,0,0,1,187,187, + 187,1,210,210,210,1,0,0,0,19,210,210,210,1,7,7,7,1,0,0, + 0,1,223,223,223,2,210,210,210,19,223,223,223,1,128,128,128,1,0,0, + 0,1,180,180,180,1,7,7,7,2,27,27,27,1,144,144,144,2,94,94, + 94,1,7,7,7,2,59,59,59,1,144,144,144,2,59,59,59,1,7,7, + 7,2,94,94,94,1,144,144,144,2,27,27,27,1,7,7,7,2,133,133, + 133,1,85,85,85,1,0,0,0,1,255,255,255,1,0,0,0,23,244,1, + 0,0,244,244,244,1,248,248,248,1,236,236,236,1,128,128,128,2,158,158, + 158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248, + 248,2,173,173,173,1,128,128,128,2,218,218,218,1,248,248,248,2,143,143, + 143,1,128,128,128,1,64,64,64,1,0,0,0,1,248,248,248,1,255,255, + 255,21,248,248,248,1,0,0,0,1,229,229,229,1,255,255,255,21,248,248, + 248,1,16,16,16,1,128,128,128,1,255,255,255,21,241,241,241,1,106,106, + 106,1,128,128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,161,161, + 161,1,255,255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255,255, + 255,21,213,213,213,1,122,122,122,1,248,248,248,1,255,255,255,21,252,252, + 252,1,122,122,122,1,199,199,199,1,255,255,255,21,252,252,252,1,122,122, + 122,1,128,128,128,1,255,255,255,21,230,230,230,1,122,122,122,1,128,128, + 128,1,255,255,255,21,198,198,198,1,122,122,122,1,191,191,191,1,255,255, + 255,21,198,198,198,1,122,122,122,1,248,248,248,1,255,255,255,21,226,226, + 226,1,122,122,122,1,248,248,248,1,255,255,255,21,252,252,252,1,122,122, + 122,1,169,169,169,1,255,255,255,21,252,252,252,1,122,122,122,1,128,128, + 128,1,255,255,255,21,216,216,216,1,122,122,122,1,128,128,128,1,255,255, + 255,21,198,198,198,1,122,122,122,1,221,221,221,1,255,255,255,21,198,198, + 198,1,122,122,122,1,248,248,248,1,255,255,255,21,240,240,240,1,122,122, + 122,1,248,248,248,1,255,255,255,21,252,252,252,1,122,122,122,1,139,139, + 139,1,255,255,255,21,252,252,252,1,122,122,122,1,128,128,128,1,255,255, + 255,21,203,203,203,1,122,122,122,1,75,75,75,1,248,248,248,1,251,251, + 251,1,241,241,241,1,198,198,198,2,214,214,214,1,252,252,252,2,228,228, + 228,1,198,198,198,2,228,228,228,1,252,252,252,2,214,214,214,1,198,198, + 198,2,241,241,241,1,252,252,252,2,201,201,201,1,169,169,169,1,122,122, + 122,1,0,0,0,1,16,16,16,1,106,106,106,1,122,122,122,20,106,106, + 106,1,0,0) + ); + +const + objdata_tspacer: record size: integer; data: array[0..1446] of byte end = + (size: 1447; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,112, + 97,99,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,52,5,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,8,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,3,3,3,1,7,7,7,1,18,18,18,1,224,224,224, + 2,139,139,139,1,7,7,7,2,58,58,58,1,224,224,224,2,81,81,81, + 1,7,7,7,2,107,107,107,1,224,224,224,2,39,39,39,1,7,7,7, + 2,177,177,177,1,224,224,224,2,255,255,255,1,7,7,7,1,224,224,224, + 21,7,7,7,1,255,255,255,1,26,26,26,1,224,224,224,21,7,7,7, + 1,0,0,0,1,224,224,224,22,25,25,25,1,0,0,0,1,224,224,224, + 22,145,145,145,1,0,0,0,1,131,131,131,1,224,224,224,21,145,145,145, + 1,0,0,0,1,7,7,7,1,224,224,224,2,112,112,112,1,224,224,224, + 14,112,112,112,1,224,224,224,3,99,99,99,1,0,0,0,1,7,7,7, + 1,224,224,224,2,0,0,0,1,224,224,224,14,0,0,0,1,224,224,224, + 3,7,7,7,1,0,0,0,1,64,64,64,1,224,224,224,2,0,0,0, + 1,224,224,224,14,0,0,0,1,224,224,224,3,7,7,7,1,0,0,0, + 1,224,224,224,3,0,0,0,1,224,224,224,3,210,210,210,1,112,112,112, + 1,126,126,126,1,224,224,224,3,55,55,55,1,168,168,168,1,224,224,224, + 3,0,0,0,1,224,224,224,3,55,55,55,1,0,0,0,1,224,224,224, + 3,0,0,0,1,224,224,224,1,210,210,210,1,112,112,112,1,13,13,13, + 1,0,0,0,1,112,112,112,1,224,224,224,3,0,0,0,2,55,55,55, + 1,168,168,168,1,224,224,224,1,0,0,0,1,224,224,224,3,145,145,145, + 1,0,0,0,1,75,75,75,1,224,224,224,2,0,0,0,1,196,196,196, + 1,27,27,27,1,0,0,0,11,112,112,112,1,0,0,0,1,224,224,224, + 3,145,145,145,1,0,0,0,1,7,7,7,1,224,224,224,2,0,0,0, + 1,224,224,224,1,210,210,210,1,112,112,112,1,13,13,13,1,0,0,0, + 1,112,112,112,1,224,224,224,3,0,0,0,2,55,55,55,1,168,168,168, + 1,224,224,224,1,0,0,0,1,224,224,224,3,64,64,64,1,0,0,0, + 1,7,7,7,1,224,224,224,2,0,0,0,1,224,224,224,3,210,210,210, + 1,112,112,112,1,126,126,126,1,224,224,224,3,55,55,55,1,168,168,168, + 1,224,224,224,3,0,0,0,1,224,224,224,3,7,7,7,1,0,0,0, + 1,115,115,115,1,224,224,224,2,0,0,0,1,224,224,224,14,0,0,0, + 1,224,224,224,3,7,7,7,1,0,0,0,1,224,224,224,3,0,0,0, + 1,224,224,224,14,0,0,0,1,224,224,224,3,90,90,90,1,0,0,0, + 1,224,224,224,3,112,112,112,1,224,224,224,14,112,112,112,1,224,224,224, + 3,145,145,145,1,0,0,0,1,35,35,35,1,224,224,224,21,145,145,145, + 1,0,0,0,1,7,7,7,1,224,224,224,21,32,32,32,1,0,0,0, + 1,7,7,7,1,224,224,224,21,7,7,7,1,0,0,0,1,189,189,189, + 1,224,224,224,21,7,7,7,1,0,0,0,1,224,224,224,22,129,129,129, + 1,0,0,0,1,179,179,179,1,7,7,7,2,28,28,28,1,145,145,145, + 2,94,94,94,1,7,7,7,2,59,59,59,1,145,145,145,2,59,59,59, + 1,7,7,7,2,94,94,94,1,145,145,145,2,28,28,28,1,7,7,7, + 2,134,134,134,1,85,85,85,1,0,0,0,1,255,255,255,1,0,0,0, + 23,244,1,0,0,244,244,244,1,248,248,248,1,236,236,236,1,128,128,128, + 2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188, + 1,248,248,248,2,173,173,173,1,128,128,128,2,218,218,218,1,248,248,248, + 2,143,143,143,1,128,128,128,1,64,64,64,1,0,0,0,1,248,248,248, + 1,255,255,255,21,248,248,248,1,0,0,0,1,229,229,229,1,255,255,255, + 21,248,248,248,1,16,16,16,1,128,128,128,1,255,255,255,21,241,241,241, + 1,106,106,106,1,128,128,128,1,255,255,255,21,198,198,198,1,122,122,122, + 1,161,161,161,1,255,255,255,21,198,198,198,1,122,122,122,1,248,248,248, + 1,255,255,255,21,213,213,213,1,122,122,122,1,248,248,248,1,255,255,255, + 21,252,252,252,1,122,122,122,1,199,199,199,1,255,255,255,21,252,252,252, + 1,122,122,122,1,128,128,128,1,255,255,255,21,230,230,230,1,122,122,122, + 1,128,128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,191,191,191, + 1,255,255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255,255,255, + 21,226,226,226,1,122,122,122,1,248,248,248,1,255,255,255,21,252,252,252, + 1,122,122,122,1,169,169,169,1,255,255,255,21,252,252,252,1,122,122,122, + 1,128,128,128,1,255,255,255,21,216,216,216,1,122,122,122,1,128,128,128, + 1,255,255,255,21,198,198,198,1,122,122,122,1,221,221,221,1,255,255,255, + 21,198,198,198,1,122,122,122,1,248,248,248,1,255,255,255,21,240,240,240, + 1,122,122,122,1,248,248,248,1,255,255,255,21,252,252,252,1,122,122,122, + 1,139,139,139,1,255,255,255,21,252,252,252,1,122,122,122,1,128,128,128, + 1,255,255,255,21,203,203,203,1,122,122,122,1,75,75,75,1,248,248,248, + 1,251,251,251,1,242,242,242,1,198,198,198,2,215,215,215,1,252,252,252, + 2,228,228,228,1,198,198,198,2,228,228,228,1,252,252,252,2,215,215,215, + 1,198,198,198,2,242,242,242,1,252,252,252,2,201,201,201,1,169,169,169, + 1,122,122,122,1,0,0,0,1,16,16,16,1,106,106,106,1,122,122,122, + 20,106,106,106,1,0,0) + ); + +const + objdata_tlayouter: record size: integer; data: array[0..1564] of byte end = + (size: 1565; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,108,97, + 121,111,117,116,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,168,5,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,124,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,3,3,3,1,7,7,7,1,18,18,18,1,224, + 224,224,2,139,139,139,1,7,7,7,2,58,58,58,1,224,224,224,2,81, + 81,81,1,7,7,7,2,107,107,107,1,224,224,224,2,39,39,39,1,7, + 7,7,2,177,177,177,1,224,224,224,2,255,255,255,1,7,7,7,1,224, + 224,224,10,196,196,196,1,224,224,224,10,7,7,7,1,255,255,255,1,26, + 26,26,1,224,224,224,9,210,210,210,1,27,27,27,1,210,210,210,1,224, + 224,224,9,7,7,7,1,0,0,0,1,224,224,224,10,112,112,112,1,0, + 0,0,1,112,112,112,1,224,224,224,9,25,25,25,1,0,0,0,1,224, + 224,224,9,210,210,210,1,13,13,13,1,0,0,0,1,13,13,13,1,210, + 210,210,1,224,224,224,8,145,145,145,1,0,0,0,1,131,131,131,1,224, + 224,224,8,112,112,112,1,0,0,0,3,112,112,112,1,224,224,224,8,145, + 145,145,1,0,0,0,1,7,7,7,1,224,224,224,8,126,126,126,1,112, + 112,112,1,0,0,0,1,112,112,112,1,126,126,126,1,224,224,224,8,99, + 99,99,1,0,0,0,1,7,7,7,1,224,224,224,10,0,0,0,1,224, + 224,224,10,7,7,7,1,0,0,0,1,64,64,64,1,224,224,224,10,0, + 0,0,1,224,224,224,10,7,7,7,1,0,0,0,1,224,224,224,4,210, + 210,210,1,112,112,112,1,126,126,126,1,224,224,224,4,0,0,0,1,224, + 224,224,4,126,126,126,1,112,112,112,1,210,210,210,1,224,224,224,3,55, + 55,55,1,0,0,0,1,224,224,224,2,210,210,210,1,112,112,112,1,13, + 13,13,1,0,0,0,1,112,112,112,1,224,224,224,9,112,112,112,1,0, + 0,0,1,13,13,13,1,112,112,112,1,210,210,210,1,224,224,224,1,145, + 145,145,1,0,0,0,1,75,75,75,1,196,196,196,1,27,27,27,1,0, + 0,0,7,224,224,224,3,0,0,0,7,27,27,27,1,196,196,196,1,145, + 145,145,1,0,0,0,1,7,7,7,1,224,224,224,1,210,210,210,1,112, + 112,112,1,13,13,13,1,0,0,0,1,112,112,112,1,224,224,224,9,112, + 112,112,1,0,0,0,1,13,13,13,1,112,112,112,1,210,210,210,1,224, + 224,224,1,64,64,64,1,0,0,0,1,7,7,7,1,224,224,224,3,210, + 210,210,1,112,112,112,1,126,126,126,1,224,224,224,4,0,0,0,1,224, + 224,224,4,126,126,126,1,112,112,112,1,210,210,210,1,224,224,224,3,7, + 7,7,1,0,0,0,1,115,115,115,1,224,224,224,10,0,0,0,1,224, + 224,224,10,7,7,7,1,0,0,0,1,224,224,224,11,0,0,0,1,224, + 224,224,10,90,90,90,1,0,0,0,1,224,224,224,9,126,126,126,1,112, + 112,112,1,0,0,0,1,112,112,112,1,126,126,126,1,224,224,224,8,145, + 145,145,1,0,0,0,1,35,35,35,1,224,224,224,8,112,112,112,1,0, + 0,0,3,112,112,112,1,224,224,224,8,145,145,145,1,0,0,0,1,7, + 7,7,1,224,224,224,8,210,210,210,1,13,13,13,1,0,0,0,1,13, + 13,13,1,210,210,210,1,224,224,224,8,32,32,32,1,0,0,0,1,7, + 7,7,1,224,224,224,9,112,112,112,1,0,0,0,1,112,112,112,1,224, + 224,224,9,7,7,7,1,0,0,0,1,189,189,189,1,224,224,224,9,210, + 210,210,1,27,27,27,1,210,210,210,1,224,224,224,9,7,7,7,1,0, + 0,0,1,224,224,224,11,196,196,196,1,224,224,224,10,129,129,129,1,0, + 0,0,1,179,179,179,1,7,7,7,2,28,28,28,1,145,145,145,2,94, + 94,94,1,7,7,7,2,59,59,59,1,145,145,145,2,59,59,59,1,7, + 7,7,2,94,94,94,1,145,145,145,2,28,28,28,1,7,7,7,2,134, + 134,134,1,85,85,85,1,0,0,0,1,255,255,255,1,0,0,0,23,244, + 1,0,0,244,244,244,1,248,248,248,1,236,236,236,1,128,128,128,2,158, + 158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248, + 248,248,2,173,173,173,1,128,128,128,2,218,218,218,1,248,248,248,2,143, + 143,143,1,128,128,128,1,64,64,64,1,0,0,0,1,248,248,248,1,255, + 255,255,21,248,248,248,1,0,0,0,1,229,229,229,1,255,255,255,21,248, + 248,248,1,16,16,16,1,128,128,128,1,255,255,255,21,241,241,241,1,106, + 106,106,1,128,128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,161, + 161,161,1,255,255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255, + 255,255,21,213,213,213,1,122,122,122,1,248,248,248,1,255,255,255,21,252, + 252,252,1,122,122,122,1,199,199,199,1,255,255,255,21,252,252,252,1,122, + 122,122,1,128,128,128,1,255,255,255,21,230,230,230,1,122,122,122,1,128, + 128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,191,191,191,1,255, + 255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255,255,255,21,226, + 226,226,1,122,122,122,1,248,248,248,1,255,255,255,21,252,252,252,1,122, + 122,122,1,169,169,169,1,255,255,255,21,252,252,252,1,122,122,122,1,128, + 128,128,1,255,255,255,21,216,216,216,1,122,122,122,1,128,128,128,1,255, + 255,255,21,198,198,198,1,122,122,122,1,221,221,221,1,255,255,255,21,198, + 198,198,1,122,122,122,1,248,248,248,1,255,255,255,21,240,240,240,1,122, + 122,122,1,248,248,248,1,255,255,255,21,252,252,252,1,122,122,122,1,139, + 139,139,1,255,255,255,21,252,252,252,1,122,122,122,1,128,128,128,1,255, + 255,255,21,203,203,203,1,122,122,122,1,75,75,75,1,248,248,248,1,251, + 251,251,1,242,242,242,1,198,198,198,2,215,215,215,1,252,252,252,2,228, + 228,228,1,198,198,198,2,228,228,228,1,252,252,252,2,215,215,215,1,198, + 198,198,2,242,242,242,1,252,252,252,2,201,201,201,1,169,169,169,1,122, + 122,122,1,0,0,0,1,16,16,16,1,106,106,106,1,122,122,122,20,106, + 106,106,1,0,0) + ); + +const + objdata_tdatetimedisp: record size: integer; data: array[0..760] of byte end = + (size: 761; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,97, + 116,101,116,105,109,101,100,105,115,112,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,128,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,56,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209, + 209,209,22,255,255,255,1,128,128,128,1,211,211,211,1,209,209,209,1,191, + 191,191,2,193,193,193,1,206,206,206,1,211,211,211,6,202,202,202,1,191, + 191,191,5,193,193,193,1,211,211,211,3,255,255,255,1,128,128,128,1,214, + 214,214,1,187,187,187,1,1,1,1,1,26,26,26,1,24,24,24,1,7, + 7,7,1,50,50,50,1,177,177,177,1,214,214,214,4,128,128,128,1,26, + 26,26,2,6,6,6,1,18,18,18,1,26,26,26,1,37,37,37,1,214, + 214,214,3,255,255,255,1,128,128,128,1,217,217,217,1,190,190,190,1,13, + 13,13,1,217,217,217,3,115,115,115,1,34,34,34,1,210,210,210,1,217, + 217,217,6,49,49,49,1,155,155,155,1,217,217,217,5,255,255,255,1,128, + 128,128,1,219,219,219,1,192,192,192,1,13,13,13,1,219,219,219,4,31, + 31,31,1,151,151,151,1,219,219,219,1,69,69,69,1,161,161,161,1,219, + 219,219,3,49,49,49,1,156,156,156,1,219,219,219,5,255,255,255,1,128, + 128,128,1,222,222,222,1,194,194,194,1,13,13,13,1,222,222,222,4,77, + 77,77,1,114,114,114,1,222,222,222,1,172,172,172,1,203,203,203,1,222, + 222,222,3,50,50,50,1,158,158,158,1,222,222,222,5,255,255,255,1,128, + 128,128,1,224,224,224,1,196,196,196,1,13,13,13,1,224,224,224,4,79, + 79,79,1,116,116,116,1,224,224,224,6,50,50,50,1,160,160,160,1,224, + 224,224,5,255,255,255,1,128,128,128,1,227,227,227,1,199,199,199,1,13, + 13,13,1,227,227,227,3,226,226,226,1,36,36,36,1,155,155,155,1,227, + 227,227,6,51,51,51,1,162,162,162,1,227,227,227,5,255,255,255,1,128, + 128,128,1,229,229,229,1,200,200,200,1,13,13,13,1,229,229,229,2,216, + 216,216,1,113,113,113,1,34,34,34,1,225,225,225,1,229,229,229,1,207, + 207,207,1,220,220,220,1,229,229,229,3,51,51,51,1,163,163,163,1,229, + 229,229,5,255,255,255,1,128,128,128,1,232,232,232,1,203,203,203,1,0, + 0,0,1,6,6,6,2,15,15,15,1,70,70,70,1,204,204,204,1,232, + 232,232,2,44,44,44,1,159,159,159,1,232,232,232,3,52,52,52,1,166, + 166,166,1,232,232,232,5,255,255,255,1,128,128,128,1,235,235,235,22,255, + 255,255,1,128,128,128,1,237,237,237,22,255,255,255,25,208,208,208,120,16, + 0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0, + 0) + ); + +const + objdata_tbytestringdisp: record size: integer; data: array[0..890] of byte end = + (size: 891; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,98,121, + 116,101,115,116,114,105,110,103,100,105,115,112,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,0,3,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,184,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128, + 25,209,209,209,22,255,255,255,1,128,128,128,1,211,211,211,4,193,193,193, + 1,206,206,206,1,211,211,211,5,200,200,200,1,211,211,211,6,194,194,194, + 1,210,210,210,1,211,211,211,2,255,255,255,1,128,128,128,1,214,214,214, + 3,185,185,185,1,4,4,4,1,109,109,109,1,214,214,214,3,205,205,205, + 1,60,60,60,1,33,33,33,1,23,23,23,1,166,166,166,1,214,214,214, + 3,179,179,179,1,11,11,11,1,205,205,205,1,214,214,214,2,255,255,255, + 1,128,128,128,1,217,217,217,3,104,104,104,1,100,100,100,1,26,26,26, + 1,214,214,214,1,217,217,217,2,99,99,99,1,103,103,103,1,217,217,217, + 1,152,152,152,1,32,32,32,1,216,216,216,1,217,217,217,1,134,134,134, + 1,26,26,26,1,3,3,3,1,208,208,208,1,217,217,217,2,255,255,255, + 1,128,128,128,1,219,219,219,2,216,216,216,1,24,24,24,1,193,193,193, + 1,53,53,53,1,153,153,153,1,219,219,219,2,42,42,42,1,182,182,182, + 1,219,219,219,1,214,214,214,1,3,3,3,1,188,188,188,1,219,219,219, + 1,82,82,82,1,189,189,189,1,9,9,9,1,210,210,210,1,219,219,219, + 2,255,255,255,1,128,128,128,1,222,222,222,2,157,157,157,1,55,55,55, + 1,222,222,222,1,137,137,137,1,65,65,65,1,222,222,222,2,16,16,16, + 1,205,205,205,1,222,222,222,2,37,37,37,1,169,169,169,1,222,222,222, + 3,10,10,10,1,212,212,212,1,222,222,222,2,255,255,255,1,128,128,128, + 1,224,224,224,2,71,71,71,1,86,86,86,1,154,154,154,1,142,142,142, + 1,3,3,3,1,197,197,197,1,224,224,224,1,12,12,12,1,197,197,197, + 1,224,224,224,2,38,38,38,1,174,174,174,1,224,224,224,3,10,10,10, + 1,214,214,214,1,224,224,224,2,255,255,255,1,128,128,128,1,227,227,227, + 1,207,207,207,1,12,12,12,1,99,99,99,3,45,45,45,1,109,109,109, + 1,227,227,227,1,35,35,35,1,162,162,162,1,227,227,227,1,222,222,222, + 1,4,4,4,1,207,207,207,1,227,227,227,3,10,10,10,1,217,217,217, + 1,227,227,227,2,255,255,255,1,128,128,128,1,229,229,229,1,126,126,126, + 1,77,77,77,1,229,229,229,3,169,169,169,1,22,22,22,1,225,225,225, + 1,101,101,101,1,104,104,104,1,229,229,229,1,166,166,166,1,39,39,39, + 1,229,229,229,4,10,10,10,1,219,219,219,1,229,229,229,2,255,255,255, + 1,128,128,128,1,232,232,232,1,37,37,37,1,162,162,162,1,232,232,232, + 3,231,231,231,1,29,29,29,1,156,156,156,1,213,213,213,1,89,89,89, + 1,44,44,44,1,37,37,37,1,184,184,184,1,232,232,232,4,10,10,10, + 1,222,222,222,1,232,232,232,2,255,255,255,1,128,128,128,1,235,235,235, + 11,226,226,226,1,235,235,235,10,255,255,255,1,128,128,128,1,237,237,237, + 22,255,255,255,25,208,208,208,120,16,0,0,0,0,0,0,120,255,255,255, + 255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tlistview: record size: integer; data: array[0..2260] of byte end = + (size: 2261; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,108,105, + 115,116,118,105,101,119,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,96,8,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,28,8,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,135,207,233,1,145,214,237,1,143, + 212,237,1,140,210,237,1,138,208,237,1,137,207,237,1,134,205,237,1,132, + 203,236,1,130,201,236,1,128,199,236,1,126,198,236,1,124,196,235,1,122, + 194,235,1,119,192,235,1,118,190,235,1,116,189,234,1,113,187,234,1,111, + 185,234,1,109,183,233,1,107,181,233,1,105,180,233,1,95,172,228,1,255, + 255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,155,221,242,1,124, + 200,228,1,120,191,220,1,122,196,224,1,139,210,238,1,144,212,241,1,142, + 210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130, + 200,240,1,128,198,240,1,126,196,239,1,122,194,237,1,99,184,157,1,105, + 186,177,1,116,188,238,1,114,186,238,1,103,178,233,1,255,255,255,1,128, + 128,128,1,147,216,237,1,158,224,243,1,89,174,206,1,101,144,172,1,76, + 151,183,1,95,147,177,1,77,155,187,1,123,199,230,1,142,210,241,1,139, + 208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130,200,240,1,128, + 198,240,1,114,189,210,1,88,180,128,1,150,229,199,1,147,222,196,1,98, + 178,175,1,114,186,238,1,103,178,233,1,255,255,255,1,128,128,128,1,147, + 216,237,1,154,222,241,1,172,194,208,1,240,170,150,1,201,205,214,1,232, + 170,161,1,222,179,177,1,135,202,228,1,142,210,241,1,139,208,241,1,137, + 206,241,1,135,204,240,1,133,202,240,1,130,200,240,1,94,179,163,1,74, + 174,103,1,121,209,163,1,156,233,206,1,156,227,206,1,106,182,144,1,92, + 172,176,1,103,178,233,1,255,255,255,1,128,128,128,1,147,216,237,1,158, + 224,243,1,146,206,226,1,171,175,220,1,145,165,239,1,165,175,227,1,186, + 213,231,1,127,201,229,1,142,210,241,1,139,208,241,1,137,206,241,1,135, + 204,240,1,132,201,238,1,77,168,122,1,60,160,86,1,67,167,88,1,121, + 209,160,1,162,238,214,1,76,169,99,1,88,172,151,1,71,158,120,1,99, + 176,220,1,255,255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,136, + 207,230,1,181,213,230,1,121,133,242,1,116,128,242,1,156,205,225,1,135, + 207,237,1,142,210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,133, + 202,240,1,126,197,230,1,74,169,117,1,90,187,122,1,134,218,179,1,172, + 245,229,1,142,213,189,1,83,167,132,1,114,186,238,1,103,178,233,1,255, + 255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,155,222,243,1,125, + 192,221,1,121,186,214,1,122,186,214,1,129,199,230,1,144,212,241,1,142, + 210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,125,197,223,1,63, + 160,93,1,77,171,121,1,69,167,88,1,132,216,175,1,148,226,194,1,80, + 170,106,1,82,165,123,1,67,157,113,1,103,178,233,1,255,255,255,1,128, + 128,128,1,147,216,237,1,152,223,223,1,136,218,175,1,142,212,158,1,130, + 210,137,1,119,211,118,1,121,211,126,1,125,212,185,1,142,210,241,1,139, + 208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,128,198,234,1,75, + 169,115,1,101,195,135,1,146,227,195,1,174,244,231,1,127,201,170,1,80, + 163,123,1,98,176,195,1,103,178,233,1,255,255,255,1,128,128,128,1,147, + 216,237,1,133,217,154,1,123,216,136,1,121,215,137,1,119,215,138,1,109, + 215,120,1,95,213,92,1,79,213,62,1,116,211,171,1,139,208,241,1,137, + 206,241,1,135,204,240,1,127,198,227,1,53,155,69,1,67,170,88,1,102, + 195,134,1,140,221,191,1,161,232,218,1,118,191,155,1,77,154,102,1,46, + 132,59,1,57,148,103,1,250,253,250,1,128,128,128,1,147,216,237,1,157, + 222,241,1,101,144,157,1,121,174,192,1,151,218,242,1,149,216,242,1,122, + 179,202,1,136,200,228,1,142,210,241,1,139,208,241,1,122,184,215,1,135, + 204,240,1,133,202,240,1,130,200,240,1,114,182,212,1,102,172,187,1,67, + 155,187,1,44,132,186,1,101,180,192,1,106,182,211,1,111,184,230,1,98, + 169,221,1,255,255,255,1,128,128,128,1,147,216,237,1,156,220,239,1,76, + 108,118,1,95,137,152,1,111,160,177,1,113,163,183,1,93,137,155,1,124, + 183,208,1,113,167,192,1,123,184,213,1,93,141,164,1,135,204,240,1,133, + 202,240,1,130,200,240,1,87,134,163,1,58,90,110,1,52,112,153,1,42, + 115,167,1,89,147,186,1,98,159,201,1,114,186,238,1,74,128,167,1,255, + 255,255,1,128,128,128,1,147,216,237,1,156,220,239,1,105,150,164,1,153, + 220,243,1,99,144,159,1,97,141,158,1,89,131,148,1,103,151,172,1,99, + 146,167,1,87,131,151,1,81,121,142,1,135,204,240,1,133,202,240,1,130, + 200,240,1,84,130,157,1,95,148,180,1,63,100,123,1,83,132,164,1,84, + 134,168,1,76,124,157,1,83,136,174,1,74,128,167,1,255,255,255,1,128, + 128,128,1,147,216,237,1,158,224,243,1,156,222,243,1,153,220,243,1,149, + 217,241,1,147,215,241,1,146,214,242,1,144,212,241,1,142,210,241,1,139, + 208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130,200,240,1,117, + 181,219,1,131,189,226,1,161,171,188,1,165,185,206,1,126,169,202,1,106, + 173,218,1,114,186,238,1,96,165,217,1,255,255,255,1,128,128,128,1,147, + 216,237,1,158,224,243,1,137,207,236,1,87,173,225,1,63,159,224,1,67, + 160,224,1,84,170,225,1,127,199,234,1,142,210,241,1,139,208,241,1,137, + 206,241,1,135,204,240,1,133,202,240,1,130,200,240,1,162,157,170,1,221, + 191,192,1,227,197,197,3,211,150,155,1,114,186,238,1,103,178,233,1,255, + 255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,81,170,223,1,81, + 168,233,1,114,185,237,1,127,191,239,1,114,185,237,1,87,171,224,1,142, + 210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130, + 200,240,1,191,134,134,1,184,131,132,1,189,150,155,1,213,179,182,1,212, + 120,123,1,207,82,83,1,114,186,238,1,103,178,233,1,255,255,255,1,128, + 128,128,1,147,216,237,1,154,222,241,1,63,156,224,1,110,183,237,1,158, + 207,243,1,191,223,247,1,158,207,243,1,95,172,226,1,139,208,239,1,139, + 208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130,200,240,1,191, + 134,134,4,206,73,73,1,207,82,83,1,114,186,238,1,103,178,233,1,255, + 255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,95,177,225,1,101, + 178,235,1,146,201,241,1,169,212,244,1,144,200,240,1,101,180,226,1,142, + 210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130, + 200,240,1,191,134,134,4,206,73,73,1,201,95,100,1,114,186,238,1,103, + 178,233,1,255,255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,154, + 221,242,1,115,192,230,1,102,180,228,1,106,182,229,1,114,190,229,1,142, + 211,240,1,142,210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,133, + 202,240,1,130,200,240,1,178,151,161,1,190,136,137,1,191,134,134,2,205, + 77,78,1,144,168,204,1,114,186,238,1,103,178,233,1,255,255,255,1,128, + 128,128,1,147,216,237,1,141,199,216,1,111,158,172,1,149,215,237,1,151, + 218,242,1,149,216,242,1,146,214,242,1,144,212,241,1,142,210,241,1,139, + 208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,122,188,226,1,128, + 198,240,1,133,193,232,1,168,166,185,1,178,135,138,1,170,143,164,1,109, + 177,224,1,114,186,238,1,103,178,233,1,255,255,255,1,128,128,128,1,147, + 216,237,1,106,150,163,1,153,218,238,1,99,142,157,1,102,148,164,1,103, + 149,167,1,96,141,159,1,101,148,168,1,101,150,172,1,136,203,235,1,136, + 205,240,1,135,204,240,1,133,202,240,1,89,137,165,1,128,198,240,1,108, + 168,205,1,106,167,205,1,83,132,164,1,97,154,193,1,86,139,176,1,79, + 129,165,1,95,163,214,1,255,255,255,1,128,128,128,1,147,216,237,1,103, + 146,158,1,105,150,164,1,105,151,167,1,76,109,121,1,91,132,148,1,90, + 132,149,1,99,145,165,1,66,97,112,1,107,161,186,1,132,199,232,1,135, + 204,240,1,133,202,240,1,89,137,165,1,124,192,232,1,88,137,167,1,83, + 131,161,1,71,112,140,1,84,134,168,1,68,111,140,1,86,141,180,1,72, + 124,163,1,255,255,255,1,128,128,128,1,135,207,233,1,145,214,237,1,142, + 211,236,1,140,210,237,1,138,208,237,1,112,170,194,1,129,198,229,1,132, + 203,236,1,129,200,235,1,128,199,236,1,126,198,236,1,124,196,235,1,122, + 194,235,1,109,176,216,1,88,142,176,1,103,168,208,1,94,155,195,1,102, + 170,216,1,99,166,212,1,85,144,185,1,70,120,155,1,94,169,224,1,255, + 255,255,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0, + 0) + ); + +const + objdata_tbarcode: record size: integer; data: array[0..2863] of byte end = + (size: 2864; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,98,97, + 114,99,111,100,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,12,5,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,208,208,208,72,0,0,0,1,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,2,0,0, + 0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,3,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,7,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,7,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,5,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,3,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208, + 208,8,0,0,0,1,208,208,208,9,0,0,0,1,208,208,208,53,120,5, + 0,0,0,0,0,72,255,255,255,1,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,5,5, + 5,1,0,0,0,2,3,3,3,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,3,3,3,1,1,1,1,1,0,0, + 0,1,3,3,3,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,1,29,29,29,1,186,186, + 186,1,0,0,0,1,94,94,94,1,119,119,119,1,109,109,109,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,15,15,15,1,176,176, + 176,1,24,24,24,1,64,64,64,1,126,126,126,1,131,131,131,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,1,41,41,41,1,132,132,132,1,0,0,0,1,142,142, + 142,1,0,0,0,1,144,144,144,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,1,32,32,32,1,117,117,117,1,24,24,24,1,138,138, + 138,1,4,4,4,1,144,144,144,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,128,128, + 128,1,0,0,0,1,125,125,125,1,0,0,0,1,139,139,139,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,103,103, + 103,1,24,24,24,1,123,123,123,1,2,2,2,1,139,139,139,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,128,128,128,1,0,0,0,1,80,80,80,1,111,111, + 111,1,103,103,103,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,103,103,103,1,24,24,24,1,55,55,55,1,116,116, + 116,1,123,123,123,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,8,2,2,2,1,0,0,0,9,2,2,2,1,0,0, + 0,53,0,0) + ); + +const + objdata_tdial: record size: integer; data: array[0..641] of byte end = + (size: 642; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,5,116,100,105, + 97,108,12,98,105,116,109,97,112,46,105,109,97,103,101,10,88,2,0,0, + 0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,36,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,169,0,0,0,1, + 255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5, + 0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1, + 255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5, + 0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1, + 255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5, + 0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1, + 255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5, + 0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,145, + 0,0) + ); + +const + objdata_tchart: record size: integer; data: array[0..2621] of byte end = + (size: 2622; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,99,104, + 97,114,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13, + 98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,204,9,0,0,0,0,0,0,6,0,0,0, + 24,0,0,0,24,0,0,0,188,4,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,128,128,128,25,250,144,144,2,208,208,208,1,253,152,152,1, + 250,144,144,2,208,208,208,1,255,159,159,1,250,144,144,1,208,208,208,2, + 255,159,159,1,250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1, + 208,208,208,2,0,0,0,1,113,65,65,1,0,0,0,1,255,255,255,1, + 128,128,128,1,250,144,144,3,250,145,145,1,250,144,144,13,228,132,132,1, + 6,4,4,1,19,11,11,1,112,64,64,1,228,132,132,1,255,252,252,1, + 128,128,128,1,250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1, + 208,208,208,2,255,159,159,1,250,144,144,1,208,208,208,2,255,159,159,1, + 250,144,144,1,208,208,208,2,255,159,159,1,228,131,131,1,0,0,0,3, + 250,144,144,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,16, + 0,0,0,2,208,208,208,4,255,255,255,1,128,128,128,1,250,144,144,2, + 208,208,208,1,253,152,152,1,250,144,144,2,208,208,208,1,255,159,159,1, + 250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1,208,208,208,2, + 66,41,41,1,19,11,11,1,0,0,0,1,208,208,208,2,250,144,144,1, + 208,208,208,1,255,255,255,1,128,128,128,1,250,144,144,3,250,145,145,1, + 250,144,144,8,229,132,132,1,250,144,144,2,114,66,66,1,111,64,64,1, + 250,144,144,5,255,252,252,1,128,128,128,1,250,144,144,1,208,208,208,2, + 255,159,159,1,250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1, + 208,208,208,2,64,40,40,1,21,12,12,1,0,0,0,2,1,0,0,1, + 227,131,131,1,208,208,208,3,250,144,144,1,208,208,208,1,255,255,255,1, + 128,128,128,1,208,208,208,11,0,0,0,5,208,208,208,6,255,255,255,1, + 128,128,128,1,250,144,144,1,255,159,159,1,208,208,208,1,255,159,159,1, + 250,144,144,1,255,159,159,1,208,208,208,1,255,159,159,1,250,144,144,1, + 208,208,208,1,0,0,0,1,1,0,0,1,230,132,132,1,0,0,0,2, + 64,40,40,1,250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,1, + 255,255,255,1,128,128,128,1,250,144,144,2,208,208,208,1,250,144,144,3, + 208,208,208,1,250,144,144,3,0,0,0,1,116,67,67,1,250,144,144,2, + 0,0,0,1,250,144,144,3,208,208,208,1,250,144,144,3,255,255,255,1, + 128,128,128,1,250,144,144,1,255,128,128,1,208,208,208,1,255,159,159,1, + 250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1,0,0,0,2, + 66,41,41,1,250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1, + 208,208,208,3,250,144,144,1,255,128,128,1,255,255,255,1,128,128,128,1, + 208,208,208,9,0,0,0,2,208,208,208,11,255,255,255,1,128,128,128,1, + 250,144,144,1,255,159,159,1,0,0,0,1,255,159,159,1,250,144,144,1, + 255,159,159,1,208,208,208,1,0,0,0,1,89,51,51,1,0,0,0,2, + 208,208,208,1,250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,3, + 250,144,144,1,255,159,159,1,255,255,255,1,128,128,128,1,250,144,144,1, + 237,136,136,1,0,0,0,1,113,65,65,1,214,123,123,1,139,80,80,1, + 0,0,0,1,39,23,23,1,139,80,80,1,231,133,133,1,208,208,208,1, + 250,144,144,3,208,208,208,1,250,144,144,3,208,208,208,1,250,144,144,3, + 255,255,255,1,128,128,128,1,250,144,144,1,14,9,9,1,0,0,0,2, + 18,10,10,1,0,0,0,2,208,208,208,1,250,144,144,1,208,208,208,3, + 250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,3,250,144,144,1, + 255,159,159,1,255,255,255,1,128,128,128,1,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,1,208,208,208,17,255,255,255,1,128,128,128,1, + 237,136,136,1,1,1,1,1,0,0,0,1,255,159,159,1,250,144,144,1, + 255,159,159,1,208,208,208,2,250,144,144,1,208,208,208,3,250,144,144,1, + 208,208,208,3,250,144,144,1,208,208,208,3,250,144,144,1,255,159,159,1, + 255,255,255,1,128,128,128,1,162,93,93,1,78,45,45,1,208,208,208,1, + 250,144,144,3,208,208,208,1,250,144,144,3,208,208,208,1,250,144,144,3, + 208,208,208,1,250,144,144,3,208,208,208,1,250,144,144,3,255,255,255,1, + 128,128,128,1,77,44,44,1,14,9,9,1,208,208,208,2,250,144,144,1, + 208,208,208,3,250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,3, + 250,144,144,1,208,208,208,3,250,144,144,1,255,159,159,1,255,255,255,1, + 128,128,128,1,0,0,0,2,208,208,208,20,255,255,255,1,128,128,128,1, + 250,144,144,1,255,159,159,1,208,208,208,1,255,159,159,1,250,144,144,1, + 255,159,159,1,208,208,208,2,250,144,144,1,208,208,208,3,250,144,144,1, + 208,208,208,3,250,144,144,1,208,208,208,3,250,144,144,1,255,159,159,1, + 255,255,255,1,128,128,128,1,250,144,144,2,208,208,208,1,250,144,144,3, + 208,208,208,1,250,144,144,3,208,208,208,1,250,144,144,3,208,208,208,1, + 250,144,144,3,208,208,208,1,250,144,144,3,255,255,255,25,216,4,0,0, + 255,255,255,26,8,8,8,1,0,0,0,1,15,15,15,1,248,248,248,1, + 8,8,8,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,2, + 8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248,248,1, + 0,0,0,2,22,22,22,1,255,255,255,1,117,117,117,1,255,255,255,3, + 248,248,248,1,7,7,7,1,240,240,240,1,255,255,255,1,248,248,248,1, + 7,7,7,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1, + 255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2,144,144,144,1, + 254,254,254,1,255,255,255,5,0,0,0,2,8,8,8,1,248,248,248,1, + 0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1, + 248,248,248,1,0,0,0,2,8,8,8,1,249,249,249,1,236,236,236,1, + 143,143,143,1,24,24,24,1,255,255,255,1,0,0,0,1,255,255,255,2, + 0,0,0,16,139,139,139,1,143,143,143,1,0,0,0,4,255,255,255,3, + 8,8,8,1,0,0,0,1,15,15,15,1,248,248,248,1,8,8,8,1, + 0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1, + 248,248,248,1,0,0,0,2,28,28,28,1,254,254,254,1,24,24,24,1, + 0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,248,248,248,1, + 7,7,7,1,240,240,240,1,255,255,255,1,248,248,248,1,7,7,7,1, + 248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2, + 8,8,8,1,252,252,252,1,255,255,255,2,8,8,8,1,248,248,248,1, + 255,255,255,5,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,2, + 8,8,8,1,248,248,248,1,0,0,0,2,29,29,29,1,254,254,254,1, + 60,60,60,1,20,20,20,1,235,235,235,1,249,249,249,1,0,0,0,3, + 255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,11,140,140,140,1, + 177,177,177,1,231,231,231,1,177,177,177,1,140,140,140,1,0,0,0,6, + 255,255,255,3,8,8,8,1,0,0,0,1,16,16,16,1,248,248,248,1, + 8,8,8,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,1, + 22,22,22,1,234,234,234,1,249,249,249,1,60,60,60,1,233,233,233,1, + 29,29,29,1,248,248,248,1,0,0,0,3,255,255,255,1,0,0,0,1, + 255,255,255,3,248,248,248,1,0,0,0,1,248,248,248,1,255,255,255,1, + 248,248,248,1,0,0,0,1,255,255,255,3,140,140,140,1,255,255,255,3, + 21,21,21,1,255,255,255,3,0,0,0,1,255,255,255,5,254,254,254,1, + 2,2,2,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,2, + 8,8,8,1,248,248,248,1,22,22,22,1,234,234,234,1,28,28,28,1, + 248,248,248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,3, + 254,254,254,1,2,2,2,1,255,255,255,2,0,0,0,9,140,140,140,1, + 139,139,139,1,0,0,0,11,255,255,255,2,248,248,248,1,16,16,16,1, + 12,12,12,1,8,8,8,1,255,255,255,1,8,8,8,1,0,0,0,1, + 61,61,61,1,255,255,255,1,238,238,238,1,22,22,22,1,0,0,0,1, + 255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3,248,248,248,1, + 8,8,8,1,255,255,255,3,248,248,248,1,237,237,237,1,252,252,252,1, + 255,255,255,1,251,251,251,1,213,213,213,1,255,255,255,3,0,0,0,1, + 255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,5, + 248,248,248,1,95,95,95,1,185,185,185,1,140,140,140,1,255,255,255,1, + 164,164,164,1,62,62,62,1,0,0,0,1,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3,248,248,248,1, + 8,8,8,1,255,255,255,2,0,0,0,1,176,176,176,1,88,88,88,1, + 0,0,0,1,1,1,1,1,0,0,0,17,255,255,255,2,248,248,248,1, + 240,240,240,1,12,12,12,1,8,8,8,1,255,255,255,1,8,8,8,1, + 0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,248,248,248,1,8,8,8,1,255,255,255,3, + 253,253,253,1,0,0,0,1,248,248,248,1,255,255,255,1,248,248,248,1, + 0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1, + 255,255,255,3,0,0,0,1,255,255,255,5,253,253,253,1,95,95,95,1, + 0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3,248,248,248,1, + 8,8,8,1,255,255,255,2,119,119,119,1,13,13,13,1,0,0,0,20, + 255,255,255,2,248,248,248,1,16,16,16,1,0,0,0,1,8,8,8,1, + 255,255,255,1,8,8,8,1,0,0,0,2,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3,248,248,248,1, + 8,8,8,1,255,255,255,3,248,248,248,1,0,0,0,1,248,248,248,1, + 255,255,255,1,248,248,248,1,0,0,0,1,255,255,255,3,0,0,0,1, + 255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,28, + 0,0) + ); + +const + objdata_tchartrecorder: record size: integer; data: array[0..2833] of byte end = + (size: 2834; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,99,104, + 97,114,116,114,101,99,111,114,100,101,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,152,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,136,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,250,144,144,1, + 253,152,152,1,0,0,0,1,250,144,144,3,208,208,208,1,250,144,144,3, + 208,208,208,2,250,144,144,1,208,208,208,1,0,0,0,1,208,208,208,1, + 250,144,144,1,208,208,208,3,250,144,144,1,255,159,159,1,255,255,255,1, + 128,128,128,1,250,144,144,1,190,109,109,1,1,1,1,1,188,108,108,1, + 250,144,144,9,191,110,110,1,1,1,1,1,189,109,109,1,250,144,144,6, + 255,250,250,1,128,128,128,1,190,109,109,1,1,1,1,1,0,0,0,2, + 191,110,110,1,208,208,208,3,250,144,144,1,208,208,208,3,191,110,110,1, + 0,0,0,3,191,110,110,1,208,208,208,3,250,144,144,1,255,159,159,1, + 255,255,255,1,128,128,128,1,0,0,0,2,208,208,208,1,0,0,0,3, + 208,208,208,5,0,0,0,3,208,208,208,1,0,0,0,3,208,208,208,4, + 255,255,255,1,128,128,128,1,250,144,144,1,253,152,152,1,208,208,208,1, + 250,144,144,1,191,110,110,1,1,0,0,1,0,0,0,1,250,144,144,3, + 0,0,0,2,191,110,110,1,208,208,208,3,191,110,110,1,0,0,0,2, + 208,208,208,1,250,144,144,1,255,159,159,1,255,255,255,1,128,128,128,1, + 250,144,144,5,190,109,109,1,1,0,0,1,188,109,109,1,250,144,144,1, + 190,109,109,1,1,0,0,1,190,109,109,1,250,144,144,5,191,110,110,1, + 1,0,0,1,190,109,109,1,250,144,144,2,255,252,252,1,128,128,128,1, + 250,144,144,1,255,159,159,1,208,208,208,2,250,144,144,1,208,208,208,1, + 0,0,0,2,140,81,81,1,0,0,0,2,208,208,208,1,250,144,144,1, + 208,208,208,3,250,144,144,1,208,208,208,1,0,0,0,2,138,80,80,1, + 9,6,6,1,255,255,255,1,128,128,128,1,208,208,208,7,0,0,0,3, + 208,208,208,9,0,0,0,3,255,255,255,1,128,128,128,1,250,144,144,1, + 253,152,152,1,208,208,208,1,250,144,144,3,208,208,208,1,250,144,144,1, + 239,138,138,1,250,144,144,1,208,208,208,2,250,144,144,1,208,208,208,3, + 250,144,144,1,208,208,208,3,239,138,138,1,255,159,159,1,255,255,255,1, + 128,128,128,1,250,144,144,22,255,252,252,1,128,128,128,1,250,144,144,1, + 255,159,159,1,208,208,208,2,250,144,144,1,208,208,208,3,250,144,144,1, + 208,208,208,3,250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,3, + 250,144,144,1,255,159,159,1,255,255,255,1,128,128,128,1,208,208,208,22, + 255,255,255,1,128,128,128,1,250,144,144,1,253,152,152,1,208,208,208,1, + 250,144,144,2,40,23,23,1,0,0,0,2,72,41,41,1,39,22,22,1, + 208,208,208,2,250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,2, + 0,0,0,1,68,39,39,1,9,6,6,1,255,255,255,1,128,128,128,1, + 250,144,144,4,219,126,126,1,25,14,14,1,9,5,5,1,230,133,133,1, + 136,78,78,1,30,17,17,1,73,42,42,1,250,144,144,7,80,46,46,1, + 29,17,17,1,133,77,77,1,240,138,138,1,255,252,252,1,128,128,128,1, + 250,144,144,1,255,159,159,1,208,208,208,1,0,0,0,1,57,33,33,1, + 0,0,0,1,208,208,208,2,250,144,144,1,0,0,0,2,208,208,208,1, + 250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,1,0,0,0,2, + 250,144,144,1,255,159,159,1,255,255,255,1,128,128,128,1,208,208,208,3, + 0,0,0,2,208,208,208,4,0,0,0,3,208,208,208,5,0,0,0,3, + 208,208,208,2,255,255,255,1,128,128,128,1,250,144,144,1,253,152,152,1, + 0,0,0,1,1,0,0,1,227,131,131,1,250,144,144,1,208,208,208,1, + 250,144,144,3,0,0,0,2,238,137,137,1,208,208,208,3,239,138,138,1, + 0,0,0,2,208,208,208,1,250,144,144,1,255,159,159,1,255,255,255,1, + 128,128,128,1,250,144,144,1,246,142,142,1,2,1,1,1,159,92,92,1, + 250,144,144,7,94,54,54,1,105,60,60,1,250,144,144,3,110,63,63,1, + 96,55,55,1,250,144,144,4,255,252,252,1,128,128,128,1,216,125,125,1, + 5,3,3,1,0,0,0,1,208,208,208,1,250,144,144,1,255,146,146,1, + 208,208,208,2,250,144,144,1,255,146,146,1,208,208,208,1,0,0,0,1, + 30,17,17,1,8,5,5,1,0,0,0,2,29,17,17,1,74,42,42,1, + 208,208,208,2,250,145,145,1,255,136,136,1,255,255,255,1,128,128,128,1, + 0,0,0,3,208,208,208,9,0,0,0,5,208,208,208,5,255,255,255,1, + 128,128,128,1,250,144,144,1,253,144,144,1,208,208,208,1,250,144,144,2, + 253,152,152,1,208,208,208,1,250,144,144,2,253,153,153,1,208,208,208,2, + 250,144,144,1,255,159,159,1,208,208,208,2,250,144,144,1,255,159,159,1, + 208,208,208,2,250,145,145,1,255,143,143,1,255,255,255,1,128,128,128,1, + 250,144,144,22,255,252,252,1,255,255,255,24,216,5,0,0,255,255,255,25, + 248,248,248,1,16,16,16,1,11,11,11,1,7,7,7,1,255,255,255,1, + 8,8,8,1,0,0,0,1,7,7,7,1,255,255,255,1,6,6,6,1, + 0,0,0,2,255,255,255,1,0,0,0,1,11,11,11,1,0,0,0,1, + 255,255,255,1,0,0,0,3,248,248,248,1,8,8,8,1,255,255,255,2, + 254,254,254,1,250,250,250,1,232,232,232,1,240,240,240,1,255,255,255,1, + 248,248,248,1,11,11,11,1,236,236,236,1,255,255,255,1,249,249,249,1, + 11,11,11,1,244,244,244,1,255,255,255,2,232,232,232,1,247,247,247,1, + 255,255,255,2,12,12,12,1,244,244,244,1,255,255,255,4,250,250,250,1, + 232,232,232,1,112,112,112,1,231,231,231,1,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,255,255,255,1,231,231,231,1,112,112,112,1, + 231,231,231,1,255,255,255,1,0,0,0,3,248,248,248,1,8,8,8,1, + 255,255,255,2,115,115,115,1,60,60,60,1,0,0,0,1,60,60,60,1, + 231,231,231,1,60,60,60,1,0,0,0,5,60,60,60,1,231,231,231,1, + 60,60,60,1,0,0,0,1,60,60,60,1,231,231,231,1,60,60,60,1, + 0,0,0,4,255,255,255,2,248,248,248,1,16,16,16,1,0,0,0,1, + 7,7,7,1,255,255,255,1,232,232,232,1,60,60,60,1,7,7,7,1, + 255,255,255,1,6,6,6,1,60,60,60,1,231,231,231,1,255,255,255,1, + 0,0,0,3,255,255,255,1,231,231,231,1,60,60,60,1,0,0,0,1, + 248,248,248,1,8,8,8,1,255,255,255,3,248,248,248,1,7,7,7,1, + 240,240,240,1,255,255,255,1,250,250,250,1,232,232,232,1,244,244,244,1, + 255,255,255,1,250,250,250,1,232,232,232,1,250,250,250,1,255,255,255,2, + 8,8,8,1,248,248,248,1,255,255,255,2,232,232,232,1,250,250,250,1, + 255,255,255,4,248,248,248,1,8,8,8,1,0,0,0,2,255,255,255,1, + 0,0,0,1,60,60,60,1,231,231,231,1,255,255,255,1,231,231,231,1, + 60,60,60,1,0,0,0,1,255,255,255,1,0,0,0,3,255,255,255,1, + 0,0,0,1,60,60,60,1,231,231,231,1,251,251,251,1,119,119,119,1, + 255,255,255,2,0,0,0,7,60,60,60,1,231,231,231,1,60,60,60,1, + 0,0,0,9,60,60,60,1,231,231,231,1,60,60,60,1,255,255,255,2, + 248,248,248,1,16,16,16,1,0,0,0,1,7,7,7,1,255,255,255,1, + 8,8,8,1,0,0,0,1,7,7,7,1,255,255,255,1,6,6,6,1, + 0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3, + 248,248,248,1,8,8,8,1,255,255,255,3,248,248,248,1,7,7,7,1, + 240,240,240,1,255,255,255,1,248,248,248,1,7,7,7,1,240,240,240,1, + 255,255,255,1,249,249,249,1,7,7,7,1,248,248,248,1,255,255,255,2, + 8,8,8,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1, + 255,255,255,4,248,248,248,1,8,8,8,1,0,0,0,2,255,255,255,1, + 0,0,0,3,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,248,248,248,1,8,8,8,1,255,255,255,2, + 0,0,0,22,255,255,255,2,248,248,248,1,16,16,16,1,0,0,0,1, + 7,7,7,1,255,255,255,1,43,43,43,1,185,185,185,1,239,239,239,1, + 255,255,255,1,34,34,34,1,0,0,0,2,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,2,30,30,30,1,253,253,253,1,123,123,123,1, + 255,255,255,3,248,248,248,1,7,7,7,1,240,240,240,1,255,255,255,1, + 254,254,254,1,110,110,110,1,241,241,241,1,255,255,255,1,254,254,254,1, + 23,23,23,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1, + 255,255,255,2,23,23,23,1,254,254,254,1,255,255,255,4,248,248,248,1, + 8,8,8,1,0,0,0,1,3,3,3,1,255,255,255,1,104,104,104,1, + 0,0,0,2,255,255,255,1,147,147,147,1,157,157,157,1,0,0,0,1, + 255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,1,157,157,157,1, + 143,143,143,1,248,248,248,1,8,8,8,1,255,255,255,2,0,0,0,3, + 127,127,127,1,179,179,179,1,0,0,0,4,12,12,12,1,222,222,222,1, + 68,68,68,1,0,0,0,5,68,68,68,1,221,221,221,1,11,11,11,1, + 0,0,0,2,255,255,255,2,247,247,247,1,16,16,16,1,47,47,47,1, + 232,232,232,1,255,255,255,1,8,8,8,1,0,0,0,1,7,7,7,1, + 255,255,255,1,6,6,6,1,68,68,68,1,222,222,222,1,255,255,255,1, + 0,0,0,3,255,255,255,1,221,221,221,1,68,68,68,1,0,0,0,1, + 247,247,247,1,8,8,8,1,255,255,255,2,254,254,254,1,248,248,248,1, + 206,206,206,1,245,245,245,1,255,255,255,1,248,248,248,1,7,7,7,1, + 240,240,240,1,255,255,255,1,249,249,249,1,7,7,7,1,252,252,252,1, + 255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2,8,8,8,1, + 248,248,248,1,255,255,255,4,242,242,242,1,191,191,191,1,170,170,170,1, + 0,0,0,1,248,248,248,1,7,7,7,1,0,0,0,2,248,248,248,1, + 7,7,7,1,0,0,0,1,16,16,16,1,254,254,254,1,120,120,120,1, + 19,19,19,1,119,119,119,1,254,254,254,1,23,23,23,1,0,0,0,2, + 240,240,240,1,15,15,15,1,255,255,255,2,116,116,116,1,110,110,110,1, + 1,1,1,1,0,0,0,9,29,29,29,1,182,182,182,1,239,239,239,1, + 184,184,184,1,30,30,30,1,0,0,0,5,255,255,255,2,240,240,240,1, + 23,23,23,1,0,0,0,1,7,7,7,1,248,248,248,1,16,16,16,1, + 0,0,0,1,7,7,7,1,248,248,248,1,14,14,14,1,0,0,0,2, + 248,248,248,1,8,8,8,1,0,0,0,2,248,248,248,1,8,8,8,1, + 0,0,0,2,240,240,240,1,16,16,16,1,255,255,255,2,254,254,254,1, + 248,248,248,1,7,7,7,1,240,240,240,1,255,255,255,1,248,248,248,1, + 7,7,7,1,240,240,240,1,255,255,255,1,249,249,249,1,7,7,7,1, + 248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2, + 8,8,8,1,248,248,248,1,255,255,255,27,0,0) + ); + +const + objdata_twindowwidget: record size: integer; data: array[0..1000] of byte end = + (size: 1001; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,119,105, + 110,100,111,119,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,112,3,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,44,3,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255, + 164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128, + 128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,2,235,151,128,1,249,160,136,1,255, + 164,139,2,248,159,135,1,231,149,126,1,255,164,139,3,242,156,132,1,243, + 156,132,1,245,158,134,1,240,154,131,1,255,164,139,3,252,162,137,1,233, + 150,127,1,255,164,139,2,255,255,255,1,128,128,128,1,255,164,139,2,72, + 46,39,1,157,101,86,1,255,164,139,2,140,90,76,1,0,0,0,1,213, + 137,116,1,255,164,139,2,82,53,45,1,161,104,88,1,147,95,80,1,92, + 59,50,1,255,164,139,3,219,141,119,1,20,13,11,1,255,164,139,2,255, + 255,255,1,128,128,128,1,255,164,139,2,140,90,76,1,98,63,53,1,255, + 164,139,2,67,43,37,1,81,52,44,1,140,90,76,1,255,164,139,1,254, + 163,138,1,21,14,11,1,230,148,125,1,147,95,80,1,92,59,50,1,255, + 164,139,3,219,141,119,1,20,13,11,1,255,164,139,2,255,255,255,1,128, + 128,128,1,255,164,139,2,208,134,113,1,39,25,21,1,255,164,139,1,243, + 156,132,1,30,19,16,1,196,126,107,1,68,44,37,1,255,164,139,1,212, + 136,116,1,46,30,25,1,255,164,139,1,147,95,80,1,92,59,50,1,255, + 164,139,3,219,141,119,1,20,13,11,1,255,164,139,2,255,255,255,1,128, + 128,128,1,255,164,139,2,254,163,138,1,23,15,13,1,236,152,129,1,177, + 114,96,1,94,60,51,1,252,162,137,1,23,15,13,1,244,157,133,1,150, + 96,82,1,116,75,63,1,255,164,139,1,147,95,80,1,23,15,13,1,63, + 41,34,3,54,35,29,1,20,13,11,1,255,164,139,2,255,255,255,1,128, + 128,128,1,255,164,139,3,89,57,49,1,178,114,97,1,104,67,57,1,165, + 106,90,1,255,164,139,1,82,53,45,1,188,121,102,1,87,56,47,1,186, + 120,101,1,255,164,139,1,147,95,80,1,74,48,40,1,207,133,113,3,178, + 114,97,1,20,13,11,1,255,164,139,2,255,255,255,1,128,128,128,1,255, + 164,139,3,157,101,86,1,121,78,66,1,35,23,19,1,235,151,128,1,255, + 164,139,1,152,98,83,1,132,85,72,1,34,22,19,1,247,159,135,1,255, + 164,139,1,147,95,80,1,92,59,50,1,255,164,139,3,219,141,119,1,20, + 13,11,1,255,164,139,2,255,255,255,1,128,128,128,1,255,164,139,3,225, + 145,123,1,42,27,23,1,52,33,28,1,255,164,139,2,222,143,121,1,44, + 28,24,1,70,45,38,1,255,164,139,2,147,95,80,1,92,59,50,1,255, + 164,139,3,219,141,119,1,20,13,11,1,255,164,139,2,255,255,255,1,128, + 128,128,1,255,164,139,4,37,24,20,1,124,80,68,1,255,164,139,3,36, + 23,20,1,140,90,76,1,255,164,139,2,147,95,80,1,92,59,50,1,255, + 164,139,3,219,141,119,1,20,13,11,1,255,164,139,2,255,255,255,1,128, + 128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255, + 164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128, + 128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255, + 255,255,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0, + 0) + ); + +const + objdata_topenglwidget: record size: integer; data: array[0..832] of byte end = + (size: 833; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,111,112, + 101,110,103,108,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,200,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,132,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255, + 164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128, + 128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,7,237,152,129,1,217,140,118,1,252, + 162,137,1,255,164,139,3,234,150,128,1,251,161,137,1,255,164,139,7,255, + 255,255,1,128,128,128,1,255,164,139,5,195,125,106,1,45,29,25,1,48, + 31,26,1,61,39,33,1,24,15,13,1,157,101,86,1,255,164,139,2,22, + 14,12,1,209,134,114,1,255,164,139,7,255,255,255,1,128,128,128,1,255, + 164,139,4,212,136,116,1,33,21,18,1,203,131,111,1,255,164,139,2,222, + 143,121,1,23,15,13,1,215,138,117,1,255,164,139,1,22,14,12,1,209, + 134,114,1,255,164,139,7,255,255,255,1,128,128,128,1,255,164,139,4,111, + 71,61,1,130,84,71,1,255,164,139,4,196,126,107,1,228,147,124,1,255, + 164,139,1,22,14,12,1,209,134,114,1,255,164,139,7,255,255,255,1,128, + 128,128,1,255,164,139,4,53,34,29,1,180,116,98,1,255,164,139,2,228, + 147,124,1,223,143,122,2,237,152,129,1,255,164,139,1,22,14,12,1,209, + 134,114,1,255,164,139,7,255,255,255,1,128,128,128,1,255,164,139,4,53, + 34,29,1,172,111,94,1,255,164,139,2,73,47,40,1,39,25,21,1,21, + 14,11,1,111,71,61,1,255,164,139,1,22,14,12,1,209,134,114,1,255, + 164,139,7,255,255,255,1,128,128,128,1,255,164,139,4,113,73,62,1,117, + 75,64,1,255,164,139,4,135,87,74,1,111,71,61,1,255,164,139,1,22, + 14,12,1,209,134,114,1,255,164,139,7,255,255,255,1,128,128,128,1,255, + 164,139,4,217,140,118,1,28,18,15,1,158,102,86,1,250,161,136,1,255, + 164,139,1,223,143,122,1,67,43,37,1,115,74,63,1,255,164,139,1,22, + 14,12,1,209,134,114,1,255,164,139,7,255,255,255,1,128,128,128,1,255, + 164,139,5,215,138,117,1,70,45,38,1,24,15,13,1,28,18,15,1,27, + 17,15,1,131,84,71,1,247,159,135,1,255,164,139,1,22,14,12,1,6, + 4,3,1,7,5,4,3,218,140,119,1,255,164,139,3,255,255,255,1,128, + 128,128,1,255,164,139,7,252,162,137,1,239,154,130,1,255,164,139,13,255, + 255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255, + 164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128, + 128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,22,255,255,255,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_topenglcanvaswidget: record size: integer; data: array[0..1242] of byte end = + (size: 1243; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,111,112, + 101,110,103,108,99,97,110,118,97,115,119,105,100,103,101,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,92,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,24,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,7,236,152,129, + 1,218,140,119,1,253,163,138,1,255,164,139,3,233,150,127,1,252,162,137, + 1,255,164,139,7,255,255,255,1,128,128,128,1,255,164,139,5,189,122,103, + 1,44,28,24,1,49,32,27,1,60,39,33,1,25,16,14,1,163,105,89, + 1,255,164,139,2,14,9,8,1,217,140,118,1,255,164,139,7,255,255,255, + 1,128,128,128,1,255,164,139,4,207,133,113,1,34,22,19,1,207,133,113, + 1,255,164,139,2,218,140,119,1,21,14,11,1,221,142,120,1,255,164,139, + 1,14,9,8,1,217,140,118,1,255,164,139,7,255,255,255,1,128,128,128, + 1,255,164,139,4,104,67,57,1,137,88,75,1,255,164,139,4,194,125,106, + 1,230,148,125,1,255,164,139,1,14,9,8,1,217,140,118,1,255,164,139, + 7,255,255,255,1,128,128,128,1,255,164,139,4,45,29,25,1,188,121,102, + 1,255,164,139,2,228,147,124,1,223,143,122,2,238,153,130,1,255,164,139, + 1,14,9,8,1,217,140,118,1,255,164,139,7,255,255,255,1,128,128,128, + 1,255,164,139,4,46,30,25,1,180,116,98,1,255,164,139,2,67,43,37, + 1,39,25,21,1,20,13,11,1,119,77,65,1,255,164,139,1,14,9,8, + 1,217,140,118,1,255,164,139,7,255,255,255,1,128,128,128,1,255,164,139, + 4,105,68,57,1,124,80,68,1,255,164,139,4,128,82,70,1,119,77,65, + 1,255,164,139,1,14,9,8,1,217,140,118,1,255,164,139,7,255,255,255, + 1,128,128,128,1,255,164,139,4,213,137,116,1,26,17,14,1,163,105,89, + 1,251,161,137,1,255,164,139,1,220,141,120,1,62,40,34,1,123,79,67, + 1,255,164,139,1,14,9,8,1,217,140,118,1,255,164,139,7,255,255,255, + 1,128,128,128,1,255,164,139,5,211,136,115,1,68,44,37,1,24,15,13, + 1,27,17,15,1,29,19,16,1,135,87,74,1,248,159,135,1,255,164,139, + 1,14,9,8,1,6,4,3,1,7,5,4,3,226,145,123,1,255,164,139, + 3,255,255,255,1,128,128,128,1,255,164,139,7,252,162,137,1,240,154,131, + 1,255,164,139,13,255,255,255,1,128,128,128,1,255,164,139,5,218,140,119, + 1,138,89,75,1,89,57,49,1,148,95,81,1,229,147,125,1,255,164,139, + 4,147,95,80,1,152,98,83,1,255,164,139,6,255,255,255,1,128,128,128, + 1,255,164,139,4,203,131,111,1,32,21,17,1,131,84,71,1,188,121,102, + 1,125,80,68,1,29,19,16,1,239,154,130,1,255,164,139,2,240,154,131, + 1,39,25,21,1,25,16,14,1,242,156,132,1,255,164,139,5,255,255,255, + 1,128,128,128,1,255,164,139,4,33,21,18,1,174,112,95,1,255,164,139, + 3,119,77,65,1,160,103,87,1,255,164,139,2,152,98,83,1,106,68,58, + 1,94,60,51,1,151,97,82,1,255,164,139,5,255,255,255,1,128,128,128, + 1,255,164,139,3,231,149,126,1,13,8,7,1,255,164,139,8,53,34,29, + 1,193,124,105,1,189,122,103,1,47,30,26,1,255,164,139,5,255,255,255, + 1,128,128,128,1,255,164,139,3,196,126,107,1,38,24,21,1,255,164,139, + 7,210,135,114,1,33,21,18,1,254,163,138,2,30,19,16,1,200,129,109, + 1,255,164,139,4,255,255,255,1,128,128,128,1,255,164,139,3,238,153,130, + 1,6,4,3,1,250,161,136,1,255,164,139,3,229,147,125,1,217,140,118, + 1,255,164,139,1,111,71,61,1,16,10,9,1,47,30,26,2,16,10,9, + 1,96,62,52,1,255,164,139,4,255,255,255,1,128,128,128,1,255,164,139, + 4,49,32,27,1,157,101,86,1,255,164,139,3,81,52,44,1,121,78,66, + 1,249,160,136,1,19,12,10,1,206,132,112,1,239,154,130,2,206,132,112, + 1,10,6,5,1,239,154,130,1,255,164,139,3,255,255,255,1,128,128,128, + 1,255,164,139,4,215,138,117,1,21,14,11,1,118,76,64,1,163,105,89, + 1,91,59,50,1,33,21,18,1,245,158,134,1,169,109,92,1,53,34,29, + 1,255,164,139,4,60,39,33,1,144,93,78,1,255,164,139,3,255,255,255, + 1,128,128,128,1,255,164,139,5,227,146,124,1,160,103,87,1,114,73,62, + 1,176,113,96,1,247,159,135,1,255,164,139,1,175,113,95,1,189,122,103, + 1,255,164,139,4,195,125,106,1,161,104,88,1,255,164,139,3,255,255,255, + 1,128,128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139, + 22,255,255,255,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 66,0,0) + ); + +const + objdata_tpolygon: record size: integer; data: array[0..2067] of byte end = + (size: 2068; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,112,111, + 108,121,103,111,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,160,7,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,56,4,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,128,128,128,25,208,208,208,17,0,255,255,1,208,208, + 208,4,255,255,255,1,128,128,128,1,208,208,208,16,49,167,255,1,97,188, + 255,1,147,210,255,1,208,208,208,3,255,255,255,1,128,128,128,1,208,208, + 208,2,0,0,0,18,208,208,208,2,255,255,255,1,128,128,128,1,208,208, + 208,2,0,0,0,1,208,208,208,12,52,168,255,1,112,194,255,1,136,205, + 255,1,29,158,255,1,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,1,208,208,208,11,57,170,255,1,53,168, + 255,1,185,226,255,1,77,179,255,1,0,146,255,1,0,0,0,1,208,208, + 208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0,0,1,208,208, + 208,11,51,168,255,1,126,200,255,1,125,200,255,1,17,153,255,1,0,147, + 255,1,0,0,0,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208, + 208,2,0,0,0,1,208,208,208,10,55,164,255,1,67,175,255,1,173,220, + 255,1,65,174,255,1,0,146,255,1,208,208,208,1,0,0,0,1,208,208, + 208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0,0,1,208,208, + 208,10,51,168,255,1,140,206,255,1,113,195,255,1,5,148,255,1,0,143, + 255,1,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,1,208,208,208,9,50,168,255,1,82,181, + 255,1,161,215,255,1,53,169,255,1,0,147,255,1,208,208,208,2,0,0, + 0,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0, + 0,1,208,208,208,8,0,255,255,1,51,168,255,1,155,213,255,1,101,190, + 255,1,0,146,255,1,0,142,255,1,208,208,208,2,0,0,0,1,208,208, + 208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0,0,1,208,208, + 208,5,68,222,239,1,98,195,228,1,51,157,241,1,52,167,255,1,96,187, + 255,1,149,210,255,1,42,164,255,1,0,146,255,1,208,208,208,3,0,0, + 0,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0, + 0,1,208,208,208,4,0,242,255,1,60,203,240,1,143,192,218,1,139,176, + 218,1,87,135,233,1,152,199,254,1,90,184,255,1,0,146,255,1,0,128, + 255,1,208,208,208,3,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,1,208,208,208,4,0,218,255,1,0,176, + 255,1,16,138,251,1,91,140,232,1,146,159,217,1,131,132,220,1,72,123, + 238,1,3,140,255,1,208,208,208,4,0,0,0,1,208,208,208,2,255,255, + 255,1,128,128,128,1,208,208,208,2,0,0,0,1,208,208,208,4,0,193, + 255,1,0,149,255,1,1,106,255,1,1,62,255,1,25,40,249,1,102,116, + 228,1,147,168,216,1,123,170,223,1,105,186,227,1,208,208,208,3,0,0, + 0,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0, + 0,1,208,208,208,4,0,167,255,1,0,123,255,1,1,79,255,1,1,35, + 255,1,1,12,255,1,1,56,255,1,34,117,246,1,112,178,226,1,89,196, + 232,1,208,208,208,3,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,1,208,208,208,4,0,140,255,1,1,96, + 255,1,1,52,255,1,1,9,255,1,1,39,255,1,1,83,255,1,0,127, + 255,1,0,171,255,1,1,214,255,1,208,208,208,3,0,0,0,1,208,208, + 208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0,0,1,208,208, + 208,4,0,111,255,1,1,69,255,1,1,26,255,1,1,21,255,1,1,66, + 255,1,1,110,255,1,0,154,255,1,0,198,255,1,0,230,255,1,208,208, + 208,3,0,0,0,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208, + 208,2,0,0,0,1,208,208,208,4,0,85,255,1,1,43,255,1,1,4, + 255,1,1,48,255,1,1,92,255,1,0,137,255,1,0,181,255,1,0,226, + 255,1,208,208,208,4,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,1,208,208,208,4,0,61,255,1,1,16, + 255,1,1,31,255,1,1,75,255,1,0,119,255,1,0,162,255,1,0,209, + 255,1,208,208,208,5,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,18,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,6,2,51,255,1,1,7,255,1,2,40,255,1,0,86, + 255,1,0,139,255,1,208,208,208,11,255,255,255,1,128,128,128,1,208,208, + 208,22,255,255,255,25,48,3,0,0,255,255,255,25,0,0,0,17,1,1, + 1,1,0,0,0,4,255,255,255,2,0,0,0,16,52,52,52,1,214,214, + 214,1,80,80,80,1,0,0,0,3,255,255,255,2,0,0,0,2,255,255, + 255,18,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0, + 0,12,88,88,88,1,255,255,255,4,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,11,9,9,9,1,225,225,225,1,255,255, + 255,2,215,215,215,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,11,126,126,126,1,255,255,255,3,73,73, + 73,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,1,0,0,0,10,28,28,28,1,245,245,245,1,255,255,255,2,183,183, + 183,1,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,10,164,164,164,1,255,255,255,2,251,251, + 251,1,41,41,41,1,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,2,0,0,0,2,255,255,255,1,0,0,0,9,56,56,56,1,254,254, + 254,1,255,255,255,2,146,146,146,1,0,0,0,2,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,8,1,1, + 1,1,200,200,200,1,255,255,255,2,238,238,238,1,18,18,18,1,0,0, + 0,2,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,1,0,0,0,5,127,127,127,1,210,210,210,1,55,55,55,1,93,93, + 93,1,255,255,255,3,110,110,110,1,0,0,0,3,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,4,60,60, + 60,1,255,255,255,2,254,254,254,1,213,213,213,1,239,239,239,1,255,255, + 255,1,215,215,215,1,4,4,4,1,0,0,0,3,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,4,82,82, + 82,1,255,255,255,4,251,251,251,1,211,211,211,1,80,80,80,1,0,0, + 0,4,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,1,0,0,0,4,91,91,91,1,255,255,255,6,245,245,245,1,93,93, + 93,1,0,0,0,3,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,4,87,87,87,1,255,255,255,7,197,197, + 197,1,0,0,0,3,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,4,71,71,71,1,255,255,255,7,201,201, + 201,1,0,0,0,3,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,4,55,55,55,1,255,255,255,6,232,232, + 232,1,31,31,31,1,0,0,0,3,255,255,255,1,0,0,0,2,255,255, + 255,2,0,0,0,2,255,255,255,1,0,0,0,4,39,39,39,1,255,255, + 255,5,240,240,240,1,53,53,53,1,0,0,0,4,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,4,100,100, + 100,1,255,255,255,4,226,226,226,1,44,44,44,1,0,0,0,5,255,255, + 255,1,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,18,0,0, + 0,2,255,255,255,2,0,0,0,6,130,130,130,1,192,192,192,1,148,148, + 148,1,89,89,89,1,11,11,11,1,0,0,0,11,255,255,255,2,0,0, + 0,22,255,255,255,25,0,0) + ); + +const + objdata_trichbutton: record size: integer; data: array[0..1150] of byte end = + (size: 1151; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,114,105, + 99,104,98,117,116,116,111,110,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,8,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,192,3,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,120,224,224,224,25,255,255,255, + 22,0,0,0,1,224,224,224,1,255,255,255,1,22,240,255,2,21,237,255, + 1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255, + 1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255, + 1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255, + 1,13,132,255,1,13,129,255,1,128,128,128,1,0,0,0,1,224,224,224, + 1,255,255,255,1,22,240,255,2,21,237,255,1,21,231,255,1,20,225,255, + 1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255, + 1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255, + 1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255, + 1,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,22,240,255, + 2,21,232,250,1,11,122,135,1,7,84,95,1,11,118,137,1,18,207,247, + 1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255, + 1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,13,136,236, + 1,11,119,217,1,13,132,255,1,13,129,255,1,128,128,128,1,0,0,0, + 1,224,224,224,1,255,255,255,1,22,240,255,2,8,91,98,1,15,163,180, + 1,20,225,255,1,14,150,174,1,9,103,123,1,19,208,255,1,17,196,247, + 1,15,168,218,1,17,186,248,1,17,185,255,1,15,168,240,1,15,156,234, + 1,14,155,243,1,14,155,255,1,9,91,157,1,8,82,150,1,13,132,255, + 1,13,129,255,1,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,22,240,255,1,22,238,253,1,6,67,72,1,21,231,255,1,20,225,255, + 1,20,220,255,1,19,212,253,1,16,180,221,1,5,61,77,1,10,107,139, + 1,4,43,57,1,17,184,253,1,3,38,55,1,7,75,113,1,5,51,80, + 1,11,120,198,1,6,63,110,1,5,51,93,1,13,130,251,1,13,129,255, + 1,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,22,240,255, + 1,21,232,247,1,6,68,73,1,21,231,255,1,20,225,255,1,20,220,255, + 1,19,214,255,1,18,201,247,1,13,147,186,1,10,110,142,1,3,29,39, + 1,16,176,242,1,4,43,62,1,16,170,255,1,13,141,220,1,5,59,97, + 1,9,98,170,1,8,91,165,1,13,132,255,1,13,129,255,1,128,128,128, + 1,0,0,0,1,224,224,224,1,255,255,255,1,22,240,255,2,6,62,67, + 1,19,211,233,1,20,225,255,1,17,192,222,1,8,86,103,1,12,133,163, + 1,8,90,113,1,15,168,218,1,5,55,73,1,16,174,240,1,4,42,60, + 1,16,170,255,1,12,134,209,1,6,66,108,1,9,98,170,1,8,91,165, + 1,13,132,255,1,13,129,255,1,128,128,128,1,0,0,0,1,224,224,224, + 1,255,255,255,1,22,240,255,2,17,197,212,1,6,71,78,1,8,89,101, + 1,6,70,81,1,16,184,219,1,15,161,197,1,6,70,88,1,9,94,122, + 1,3,38,51,1,15,161,222,1,3,36,51,1,6,67,101,1,5,50,78, + 1,12,133,218,1,11,114,198,1,3,33,61,1,12,125,242,1,13,129,255, + 1,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,22,240,255, + 2,21,237,255,1,21,231,255,1,19,218,247,1,20,220,255,1,19,214,255, + 1,19,208,255,1,18,198,250,1,18,194,251,1,17,191,255,1,17,185,255, + 1,5,55,79,1,16,166,249,1,15,162,254,1,14,155,255,1,14,147,255, + 1,13,137,249,1,13,132,255,1,13,129,255,1,128,128,128,1,0,0,0, + 1,224,224,224,1,255,255,255,1,22,240,255,2,21,237,255,1,21,231,255, + 1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255, + 1,18,197,255,1,17,191,255,1,17,185,255,1,10,109,156,1,16,170,255, + 1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255, + 1,13,129,255,1,128,128,128,1,0,0,0,1,224,224,224,1,128,128,128, + 22,0,0,0,25,255,255,255,120,16,0,0,0,0,0,0,120,255,255,255, + 255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_trichstockglyphbutton: record size: integer; data: array[0..960] of byte end = + (size: 961; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,114,105, + 99,104,115,116,111,99,107,103,108,121,112,104,98,117,116,116,111,110,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,64,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,140,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,125,224,224,224,14,255,255,255,10,224,224,224,1,255,255,255,12,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,20,218,255,1,19,208,255,1,18,198,255,1,17,189,255,1,16, + 178,255,1,15,165,255,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,18,192,225,1,19,208,255,1,18,198,255,1,17,189,255,1,16, + 178,255,1,13,146,225,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,18, + 200,225,1,2,21,24,1,15,159,195,1,18,198,255,1,17,189,255,1,12, + 136,195,1,1,16,24,1,12,135,225,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,15,167,195,1,2,20,24,1,14,151,195,1,13,145,195,1,2, + 17,24,1,11,126,195,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,20,218,255,1,15,159,195,1,2,15,18,1,1,14,18,1,12, + 136,195,1,15,165,255,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,20,218,255,1,15,159,195,1,1,14,18,1,2,14,18,1,12, + 136,195,1,15,165,255,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,15,167,195,1,2,20,24,1,14,151,195,1,13,145,195,1,2, + 17,24,1,11,126,195,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,18, + 200,225,1,2,21,24,1,15,159,195,1,18,198,255,1,17,189,255,1,12, + 136,195,1,1,16,24,1,12,135,225,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,18,192,225,1,19,208,255,1,18,198,255,1,17,189,255,1,16, + 178,255,1,13,146,225,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,20,218,255,1,19,208,255,1,18,198,255,1,17,189,255,1,16, + 178,255,1,15,165,255,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,128,128,128,12,0,0,0,1,255, + 255,255,10,0,0,0,14,255,255,255,125,124,0,0,0,0,0,0,125,255, + 255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0, + 0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255, + 255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0, + 0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255, + 255,255,14,0,0,0,10,255,255,255,1,208,208,208,1,255,255,255,12,0, + 0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0,0,0,125,0, + 0) + ); + +const + objdata_txychartedit: record size: integer; data: array[0..2131] of byte end = + (size: 2132; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,120,121, + 99,104,97,114,116,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,7,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,7,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255, + 255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212, + 212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,121,121, + 121,1,182,182,182,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216, + 216,1,215,215,215,1,214,214,214,1,171,171,171,1,25,25,25,1,199,199, + 199,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231, + 231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215, + 215,1,212,212,212,1,45,45,45,1,141,141,141,1,210,210,210,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,126,126, + 126,1,61,61,61,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,196,196,196,1,21,21,21,1,184,184, + 184,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,75,75,75,1,111,111,111,1,212,212,212,1,211,211, + 211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,214,214,214,1,133,133, + 133,1,34,34,34,1,209,209,209,1,212,212,212,1,211,211,211,1,210,210, + 210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231, + 231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,193,193,193,1,107,107,107,1,25,25,25,1,64,64,64,1,192,192, + 192,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,219,219,219,1,153,153,153,1,64,64,64,1,26,26, + 26,1,109,109,109,1,192,192,192,1,216,216,216,1,215,215,215,1,214,214, + 214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,199,199,199,1,111,111, + 111,1,26,26,26,1,64,64,64,1,153,153,153,1,216,216,216,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212, + 212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,203,203,203,1,67,67,67,1,25,25,25,1,109,109,109,1,196,196, + 196,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211, + 211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,231,231,231,1,230,230,230,1,229,229,229,1,223,223,223,1,36,36, + 36,1,139,139,139,1,221,221,221,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216, + 216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210, + 210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231, + 231,1,230,230,230,1,229,229,229,1,118,118,118,1,79,79,79,1,226,226, + 226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215, + 215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230, + 230,1,198,198,198,1,22,22,22,1,207,207,207,1,226,226,226,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214, + 214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230,230,1,66,66, + 66,1,134,134,134,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212, + 212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,231,231,231,1,154,154,154,1,48,48,48,1,226,226, + 226,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211, + 211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,219,219,219,1,27,27,27,1,185,185,185,1,228,228,228,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216, + 216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210, + 210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,200,200, + 200,1,132,132,132,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215, + 215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214, + 214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255, + 255,1,128,128,128,1,224,224,224,22,255,255,255,25,12,0,0,0,255,255, + 255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_txserieschartedit: record size: integer; data: array[0..2136] of byte end = + (size: 2137; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,120,115, + 101,114,105,101,115,99,104,97,114,116,101,100,105,116,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,220, + 7,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152, + 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230, + 230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214, + 214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230,230,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212, + 212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222, + 222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217, + 217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211, + 211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,228,228,228,1,227, + 227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216, + 216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210, + 210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231, + 231,231,1,0,0,0,1,229,229,229,1,228,228,228,1,227,227,227,1,226, + 226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215, + 215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0, + 0,0,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214, + 214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212, + 212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222, + 222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217, + 217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211, + 211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227, + 227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216, + 216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210, + 210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231, + 231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227,227,227,1,226, + 226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215, + 215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0, + 0,0,1,229,229,229,1,0,0,0,1,227,227,227,1,226,226,226,1,224, + 224,224,1,111,111,111,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214, + 214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229, + 229,229,1,0,0,0,1,227,227,227,1,226,226,226,1,224,224,224,1,0, + 0,0,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212, + 212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,0, + 0,0,1,227,227,227,1,226,226,226,1,224,224,224,1,0,0,0,1,222, + 222,222,1,221,221,221,1,220,220,220,1,109,109,109,1,218,218,218,1,217, + 217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211, + 211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227, + 227,227,1,226,226,226,1,224,224,224,1,0,0,0,1,222,222,222,1,221, + 221,221,1,220,220,220,1,0,0,0,1,218,218,218,1,217,217,217,1,216, + 216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210, + 210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231, + 231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227,227,227,1,226, + 226,226,1,224,224,224,1,0,0,0,1,222,222,222,1,221,221,221,1,220, + 220,220,1,0,0,0,1,218,218,218,1,217,217,217,1,216,216,216,1,107, + 107,107,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0, + 0,0,1,229,229,229,1,0,0,0,1,227,227,227,1,0,0,0,1,224, + 224,224,1,0,0,0,1,222,222,222,1,110,110,110,1,220,220,220,1,0, + 0,0,1,218,218,218,1,217,217,217,1,216,216,216,1,0,0,0,1,214, + 214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229, + 229,229,1,0,0,0,1,227,227,227,1,0,0,0,1,224,224,224,1,0, + 0,0,1,222,222,222,1,0,0,0,1,220,220,220,1,0,0,0,1,218, + 218,218,1,217,217,217,1,216,216,216,1,0,0,0,1,214,214,214,1,212, + 212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,0, + 0,0,1,227,227,227,1,0,0,0,1,224,224,224,1,0,0,0,1,222, + 222,222,1,0,0,0,1,220,220,220,1,0,0,0,1,218,218,218,1,108, + 108,108,1,216,216,216,1,0,0,0,1,214,214,214,1,212,212,212,1,211, + 211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227, + 227,227,1,0,0,0,1,224,224,224,1,0,0,0,1,222,222,222,1,0, + 0,0,1,220,220,220,1,0,0,0,1,218,218,218,1,0,0,0,1,216, + 216,216,1,0,0,0,1,214,214,214,1,106,106,106,1,211,211,211,1,210, + 210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231, + 231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227,227,227,1,0, + 0,0,1,224,224,224,1,0,0,0,1,222,222,222,1,0,0,0,1,220, + 220,220,1,0,0,0,1,218,218,218,1,0,0,0,1,216,216,216,1,0, + 0,0,1,214,214,214,1,0,0,0,1,211,211,211,1,210,210,210,1,224, + 224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tpickwidget: record size: integer; data: array[0..2530] of byte end = + (size: 2531; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,112,105, + 99,107,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,108,9,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,156,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,14,0,0,255, + 2,208,208,208,6,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0, + 3,208,208,208,1,0,0,0,3,208,208,208,1,0,0,0,1,0,0,17, + 1,4,4,123,1,6,6,255,1,0,0,0,2,208,208,208,4,255,255,255, + 1,128,128,128,1,208,208,208,4,0,0,0,1,208,208,208,7,0,0,255, + 1,34,34,255,1,136,136,255,1,71,71,255,1,0,0,213,1,0,0,0, + 1,208,208,208,4,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0, + 1,208,208,208,5,0,0,255,1,2,2,255,1,75,75,255,1,175,175,255, + 1,82,82,255,1,5,5,255,1,0,0,255,1,208,208,208,5,255,255,255, + 1,128,128,128,1,208,208,208,9,0,0,255,1,14,14,255,1,119,119,255, + 1,143,143,255,1,28,28,255,1,0,0,255,1,208,208,208,1,0,0,0, + 2,208,208,208,4,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0, + 1,208,208,208,3,0,0,255,1,42,42,255,1,160,160,255,1,81,81,255, + 1,4,4,255,1,0,0,255,1,208,208,208,2,0,0,0,2,208,208,208, + 4,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0,1,208,208,208, + 1,0,0,255,1,4,4,255,1,86,86,255,1,142,142,255,1,26,26,255, + 1,0,0,255,1,208,208,208,4,0,0,0,2,208,208,208,4,255,255,255, + 1,128,128,128,1,208,208,208,4,0,0,0,1,0,0,255,1,17,17,255, + 1,132,132,255,1,80,80,255,1,4,4,255,1,0,0,255,1,208,208,208, + 11,255,255,255,1,128,128,128,1,208,208,208,4,0,0,255,1,46,46,255, + 1,130,130,255,1,26,26,255,1,0,0,255,1,208,208,208,4,9,9,9, + 1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,4,255,255,255, + 1,128,128,128,1,208,208,208,3,0,0,255,1,9,9,74,1,97,97,255, + 1,5,5,255,1,0,0,255,1,208,208,208,5,29,29,29,1,32,32,32, + 1,17,17,17,1,0,0,0,2,208,208,208,4,255,255,255,1,128,128,128, + 1,208,208,208,4,0,0,11,1,3,3,255,1,0,0,255,3,208,208,208, + 4,37,37,37,1,185,185,185,1,49,49,49,1,24,24,24,1,0,0,0, + 1,208,208,208,4,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0, + 1,208,208,208,1,0,0,255,5,208,208,208,2,37,37,37,1,236,236,236, + 1,246,246,246,1,101,101,101,1,29,29,29,1,8,8,8,1,208,208,208, + 3,255,255,255,1,128,128,128,1,208,208,208,7,0,0,255,6,36,36,36, + 1,239,239,239,1,255,255,255,2,174,174,174,1,34,34,34,1,19,19,19, + 1,0,0,0,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208, + 4,0,0,0,3,208,208,208,1,0,0,0,1,0,0,6,1,0,0,207, + 1,0,0,255,1,0,0,87,1,36,36,36,1,239,239,239,1,255,255,255, + 2,195,195,195,1,52,52,52,1,18,18,18,1,0,0,0,1,208,208,208, + 1,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0,3,208,208,208, + 1,0,0,146,1,0,0,106,1,0,0,0,1,0,0,255,1,0,0,242, + 1,37,37,42,1,239,239,239,1,192,192,192,1,163,163,163,1,19,19,19, + 1,15,15,15,1,0,0,0,1,208,208,208,2,255,255,255,1,128,128,128, + 1,208,208,208,8,12,12,255,1,17,17,255,1,208,208,208,1,0,0,255, + 2,34,34,38,1,51,51,51,1,24,24,24,1,100,100,100,1,105,105,105, + 1,23,23,23,1,208,208,208,3,255,255,255,1,128,128,128,1,208,208,208, + 7,0,0,255,1,72,72,255,1,64,64,255,1,0,0,255,3,9,9,9, + 1,18,18,18,1,0,0,0,1,38,38,38,1,243,243,243,1,48,48,48, + 1,17,17,17,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208,208, + 7,52,52,255,1,140,140,255,1,55,55,255,1,0,0,255,2,208,208,208, + 1,0,0,0,1,208,208,208,2,32,32,32,1,182,182,182,1,206,206,206, + 1,32,32,32,1,0,0,0,1,208,208,208,1,255,255,255,1,128,128,128, + 1,208,208,208,6,27,27,255,1,130,130,255,1,169,169,255,1,94,94,255, + 1,34,34,255,1,0,0,255,3,208,208,208,2,17,17,17,1,86,86,86, + 1,255,255,255,1,134,134,134,1,27,27,27,1,0,0,0,1,255,255,255, + 1,128,128,128,1,208,208,208,6,97,97,255,1,171,171,255,1,108,108,255, + 1,42,42,255,1,0,0,255,4,208,208,208,2,0,0,0,1,39,39,39, + 1,243,243,243,1,148,148,148,1,28,28,28,1,7,7,7,1,255,255,255, + 1,128,128,128,1,208,208,208,5,27,27,255,1,127,127,255,1,75,75,255, + 1,22,22,255,1,0,0,255,1,208,208,208,7,29,29,29,1,34,34,34, + 1,30,30,30,1,12,12,12,1,208,208,208,1,255,255,255,1,128,128,128, + 1,208,208,208,5,0,0,255,1,208,208,208,11,12,12,12,1,9,9,9, + 1,208,208,208,3,255,255,255,25,152,4,0,0,255,255,255,25,0,0,0, + 14,15,15,15,1,17,17,17,1,0,0,0,6,255,255,255,2,0,0,0, + 4,140,140,140,1,186,186,186,1,99,99,99,1,0,0,0,1,88,88,88, + 1,186,186,186,1,105,105,105,1,0,0,0,1,76,76,76,1,199,199,199, + 1,214,214,214,1,134,134,134,1,70,70,70,1,181,181,181,1,0,0,0, + 4,255,255,255,2,0,0,0,4,186,186,186,1,0,0,0,7,96,96,96, + 1,193,193,193,1,253,253,253,1,187,187,187,1,24,24,24,1,124,124,124, + 1,0,0,0,4,255,255,255,2,0,0,0,4,6,6,6,1,0,0,0, + 5,7,7,7,1,146,146,146,1,208,208,208,1,255,255,255,1,200,200,200, + 1,150,150,150,1,15,15,15,1,0,0,0,5,255,255,255,2,0,0,0, + 9,32,32,32,1,176,176,176,1,230,230,230,1,232,232,232,1,183,183,183, + 1,71,71,71,1,0,0,0,1,1,1,1,1,56,56,56,1,0,0,0, + 4,255,255,255,2,0,0,0,4,175,175,175,1,0,0,0,3,74,74,74, + 1,188,188,188,1,248,248,248,1,199,199,199,1,142,142,142,1,12,12,12, + 1,0,0,0,2,6,6,6,1,181,181,181,1,0,0,0,4,255,255,255, + 2,0,0,0,4,186,186,186,1,0,0,0,1,2,2,2,1,127,127,127, + 1,201,201,201,1,228,228,228,1,183,183,183,1,60,60,60,1,0,0,0, + 4,4,4,4,1,130,130,130,1,0,0,0,4,255,255,255,2,0,0,0, + 4,18,18,18,1,20,20,20,1,166,166,166,1,220,220,220,1,197,197,197, + 1,132,132,132,1,8,8,8,1,0,0,0,11,255,255,255,2,0,0,0, + 4,55,55,55,1,184,184,184,1,216,216,216,1,179,179,179,1,49,49,49, + 1,0,0,0,4,191,191,191,1,30,30,30,1,0,0,0,1,1,1,1, + 1,45,45,45,1,0,0,0,4,255,255,255,2,0,0,0,3,33,33,33, + 1,238,238,238,1,226,226,226,1,203,203,203,1,10,10,10,1,0,0,0, + 5,248,248,248,1,249,249,249,1,108,108,108,1,6,6,6,1,181,181,181, + 1,0,0,0,4,255,255,255,2,0,0,0,4,194,194,194,1,159,159,159, + 1,206,206,206,1,189,189,189,1,64,64,64,1,0,0,0,4,247,247,247, + 1,255,255,255,1,253,253,253,1,202,202,202,1,142,142,142,1,0,0,0, + 4,255,255,255,2,0,0,0,4,23,23,23,1,0,0,0,1,61,61,61, + 1,180,180,180,1,207,207,207,1,154,154,154,1,21,21,21,1,0,0,0, + 2,247,247,247,1,255,255,255,3,243,243,243,1,63,63,63,1,0,0,0, + 3,255,255,255,2,0,0,0,7,2,2,2,1,101,101,101,1,196,196,196, + 1,200,200,200,1,101,101,101,1,1,1,1,1,248,248,248,1,255,255,255, + 4,252,252,252,1,159,159,159,1,3,3,3,1,0,0,0,1,255,255,255, + 2,0,0,0,4,172,172,172,1,181,181,181,1,23,23,23,1,0,0,0, + 1,158,158,158,1,185,185,185,1,150,150,150,1,206,206,206,1,223,223,223, + 1,253,253,253,1,255,255,255,4,254,254,254,1,245,245,245,1,66,66,66, + 1,0,0,0,1,255,255,255,2,0,0,0,4,12,12,12,2,1,1,1, + 1,0,0,0,1,23,23,23,1,21,21,21,1,1,1,1,1,38,38,38, + 1,172,172,172,1,254,254,254,1,255,255,255,3,254,254,254,1,138,138,138, + 1,7,7,7,1,0,0,0,2,255,255,255,2,0,0,0,8,124,124,124, + 1,59,59,59,1,0,0,0,1,5,5,5,1,141,141,141,1,253,253,253, + 1,254,254,254,1,248,248,248,1,255,255,255,2,208,208,208,1,0,0,0, + 3,255,255,255,2,0,0,0,7,31,31,31,1,223,223,223,1,96,96,96, + 1,33,33,33,1,180,180,180,1,88,88,88,1,223,223,223,1,102,102,102, + 1,30,30,30,1,252,252,252,1,255,255,255,1,253,253,253,1,120,120,120, + 1,0,0,0,2,255,255,255,2,0,0,0,7,149,149,149,1,255,255,255, + 1,165,165,165,1,148,148,148,1,19,19,19,1,0,0,0,1,2,2,2, + 1,0,0,0,2,234,234,234,1,255,255,255,2,250,250,250,1,37,37,37, + 1,0,0,0,1,255,255,255,2,0,0,0,6,57,57,57,1,240,240,240, + 1,255,255,255,1,239,239,239,1,183,183,183,1,136,136,136,1,87,87,87, + 1,16,16,16,1,0,0,0,2,138,138,138,1,255,255,255,3,233,233,233, + 1,5,5,5,1,255,255,255,2,0,0,0,6,173,173,173,1,255,255,255, + 2,239,239,239,1,191,191,191,1,139,139,139,1,88,88,88,1,15,15,15, + 1,0,0,0,2,24,24,24,1,251,251,251,1,255,255,255,2,253,253,253, + 1,111,111,111,1,255,255,255,2,0,0,0,5,84,84,84,1,193,193,193, + 1,144,144,144,1,94,94,94,1,22,22,22,1,0,0,0,7,230,230,230, + 1,254,254,254,1,233,233,233,1,84,84,84,1,0,0,0,1,255,255,255, + 2,0,0,0,5,3,3,3,1,0,0,0,11,86,86,86,1,83,83,83, + 1,0,0,0,3,255,255,255,25,0,0) + ); + +const + objdata_ttraywidget: record size: integer; data: array[0..2186] of byte end = + (size: 2187; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,116,114, + 97,121,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,20,8,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,152,3,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,14,0,0,255, + 2,208,208,208,6,255,255,255,1,128,128,128,1,208,208,208,13,0,0,255, + 1,7,7,255,1,6,6,255,1,208,208,208,6,255,255,255,1,128,128,128, + 1,208,208,208,12,0,0,255,1,34,34,255,1,136,136,255,1,71,71,255, + 1,0,0,255,1,208,208,208,5,255,255,255,1,128,128,128,1,208,208,208, + 10,0,0,255,1,2,2,255,1,75,75,255,1,175,175,255,1,82,82,255, + 1,5,5,255,1,0,0,255,1,208,208,208,5,255,255,255,1,128,128,128, + 1,208,208,208,9,0,0,255,1,14,14,255,1,119,119,255,1,143,143,255, + 1,28,28,255,1,0,0,255,1,208,208,208,7,255,255,255,1,128,128,128, + 1,208,208,208,8,0,0,255,1,42,42,255,1,160,160,255,1,81,81,255, + 1,4,4,255,1,0,0,255,1,208,208,208,8,255,255,255,1,128,128,128, + 1,0,0,0,6,0,0,32,1,4,4,255,1,86,86,255,1,142,142,255, + 1,26,26,255,1,0,0,255,1,208,208,208,10,255,255,255,1,128,128,128, + 1,0,0,0,5,0,0,3,1,7,7,104,1,132,132,255,1,80,80,255, + 1,4,4,255,1,0,0,255,1,208,208,208,11,255,255,255,1,128,128,128, + 1,208,208,208,2,0,0,0,2,0,0,255,1,46,46,255,1,130,130,255, + 1,26,26,255,1,0,0,255,1,208,208,208,13,255,255,255,1,128,128,128, + 1,208,208,208,2,0,0,0,1,0,0,4,1,28,28,255,1,97,97,255, + 1,5,5,255,1,0,0,4,1,0,0,0,10,208,208,208,2,0,0,0, + 2,255,255,255,1,128,128,128,1,208,208,208,2,0,0,0,2,0,0,255, + 1,3,3,255,1,0,0,255,1,0,0,28,1,0,0,44,1,0,0,0, + 10,208,208,208,1,0,0,0,2,255,255,255,1,128,128,128,1,208,208,208, + 2,0,0,0,2,208,208,208,2,0,0,255,1,0,0,27,1,0,0,195, + 1,0,0,255,2,0,0,0,5,208,208,208,1,0,0,0,5,255,255,255, + 1,128,128,128,1,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0, + 1,0,0,180,1,0,0,255,1,0,0,219,1,0,0,11,1,0,0,1, + 1,0,0,0,3,208,208,208,1,0,0,0,4,208,208,208,1,255,255,255, + 1,128,128,128,1,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0, + 2,0,0,255,1,0,0,132,1,0,0,57,1,0,0,255,2,0,0,0, + 2,208,208,208,2,0,0,0,3,208,208,208,1,255,255,255,1,128,128,128, + 1,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,1,0,0,64, + 1,0,0,255,1,0,0,0,1,0,0,11,1,0,0,46,1,0,0,52, + 1,0,0,69,1,0,0,0,1,208,208,208,2,0,0,0,3,208,208,208, + 1,255,255,255,1,128,128,128,1,208,208,208,8,12,12,255,1,17,17,255, + 1,208,208,208,1,0,0,255,1,0,0,229,1,0,0,254,1,0,0,255, + 1,208,208,208,3,0,0,0,2,208,208,208,2,255,255,255,1,128,128,128, + 1,208,208,208,7,0,0,255,1,72,72,255,1,64,64,255,1,0,0,255, + 3,208,208,208,4,0,0,0,3,208,208,208,2,255,255,255,1,128,128,128, + 1,208,208,208,7,52,52,255,1,140,140,255,1,55,55,255,1,0,0,255, + 2,208,208,208,5,0,0,0,2,208,208,208,3,255,255,255,1,128,128,128, + 1,208,208,208,6,27,27,255,1,130,130,255,1,169,169,255,1,94,94,255, + 1,34,34,255,1,0,0,255,3,208,208,208,8,255,255,255,1,128,128,128, + 1,208,208,208,6,97,97,255,1,171,171,255,1,108,108,255,1,42,42,255, + 1,0,0,255,4,208,208,208,8,255,255,255,1,128,128,128,1,208,208,208, + 5,27,27,255,1,127,127,255,1,75,75,255,1,22,22,255,1,0,0,255, + 1,208,208,208,12,255,255,255,1,128,128,128,1,208,208,208,5,0,0,255, + 1,208,208,208,16,255,255,255,25,68,4,0,0,255,255,255,25,0,0,0, + 14,15,15,15,1,17,17,17,1,0,0,0,6,255,255,255,2,0,0,0, + 13,47,47,47,1,182,182,182,1,134,134,134,1,0,0,0,6,255,255,255, + 2,0,0,0,12,96,96,96,1,193,193,193,1,253,253,253,1,187,187,187, + 1,20,20,20,1,0,0,0,5,255,255,255,2,0,0,0,10,7,7,7, + 1,146,146,146,1,208,208,208,1,255,255,255,1,200,200,200,1,150,150,150, + 1,15,15,15,1,0,0,0,5,255,255,255,2,0,0,0,9,32,32,32, + 1,176,176,176,1,230,230,230,1,232,232,232,1,183,183,183,1,71,71,71, + 1,0,0,0,7,255,255,255,2,0,0,0,8,74,74,74,1,188,188,188, + 1,248,248,248,1,199,199,199,1,142,142,142,1,12,12,12,1,0,0,0, + 8,255,255,255,2,19,19,19,1,24,24,24,5,15,15,15,1,127,127,127, + 1,201,201,201,1,228,228,228,1,183,183,183,1,60,60,60,1,0,0,0, + 10,255,255,255,2,183,183,183,1,224,224,224,1,229,229,229,1,252,252,252, + 1,224,224,224,1,226,226,226,1,209,209,209,1,220,220,220,1,197,197,197, + 1,132,132,132,1,8,8,8,1,0,0,0,11,255,255,255,2,0,0,0, + 2,41,41,41,1,230,230,230,1,55,55,55,1,184,184,184,1,216,216,216, + 1,179,179,179,1,49,49,49,1,0,0,0,13,255,255,255,2,0,0,0, + 2,41,41,41,1,233,233,233,1,206,206,206,1,226,226,226,1,203,203,203, + 1,188,188,188,1,140,140,140,1,230,230,230,1,39,39,39,1,101,101,101, + 1,213,213,213,1,226,226,226,1,200,200,200,1,39,39,39,1,50,50,50, + 1,178,178,178,1,0,0,0,2,43,43,43,1,165,165,165,1,255,255,255, + 2,0,0,0,2,41,41,41,1,230,230,230,1,30,30,30,1,159,159,159, + 1,206,206,206,1,246,246,246,1,169,169,169,1,32,32,32,1,23,23,23, + 1,210,210,210,1,18,18,18,1,1,1,1,1,144,144,144,1,146,146,146, + 1,1,1,1,1,225,225,225,1,40,40,40,1,0,0,0,1,138,138,138, + 1,109,109,109,1,255,255,255,2,0,0,0,2,41,41,41,1,230,230,230, + 1,0,0,0,2,61,61,61,1,244,244,244,1,217,217,217,1,154,154,154, + 1,21,21,21,1,14,14,14,1,79,79,79,1,127,127,127,1,199,199,199, + 1,163,163,163,1,0,0,0,1,131,131,131,1,132,132,132,1,2,2,2, + 1,223,223,223,1,20,20,20,1,255,255,255,2,0,0,0,2,41,41,41, + 1,230,230,230,1,0,0,0,3,219,219,219,1,123,123,123,1,196,196,196, + 1,206,206,206,1,239,239,239,1,143,143,143,1,83,83,83,1,120,120,120, + 1,164,164,164,1,0,0,0,1,36,36,36,1,222,222,222,1,68,68,68, + 1,176,176,176,1,0,0,0,1,255,255,255,2,0,0,0,2,41,41,41, + 1,230,230,230,1,0,0,0,3,219,219,219,1,36,36,36,1,15,15,15, + 1,176,176,176,1,242,242,242,1,179,179,179,1,46,46,46,1,170,170,170, + 1,168,168,168,1,0,0,0,2,195,195,195,1,193,193,193,1,82,82,82, + 1,0,0,0,1,255,255,255,2,0,0,0,2,41,41,41,1,230,230,230, + 1,0,0,0,3,219,219,219,1,48,48,48,1,9,9,9,1,11,11,11, + 1,206,206,206,1,233,233,233,1,244,244,244,1,198,198,198,1,196,196,196, + 1,0,0,0,2,99,99,99,1,237,237,237,1,6,6,6,1,0,0,0, + 1,255,255,255,2,0,0,0,8,124,124,124,1,59,59,59,1,0,0,0, + 1,5,5,5,1,148,148,148,1,177,177,177,1,27,27,27,1,0,0,0, + 3,95,95,95,1,144,144,144,1,0,0,0,2,255,255,255,2,0,0,0, + 7,31,31,31,1,223,223,223,1,96,96,96,1,33,33,33,1,180,180,180, + 1,88,88,88,1,0,0,0,4,154,154,154,1,221,221,221,1,34,34,34, + 1,0,0,0,2,255,255,255,2,0,0,0,7,149,149,149,1,255,255,255, + 1,165,165,165,1,148,148,148,1,19,19,19,1,0,0,0,5,73,73,73, + 1,37,37,37,1,0,0,0,3,255,255,255,2,0,0,0,6,57,57,57, + 1,240,240,240,1,255,255,255,1,239,239,239,1,183,183,183,1,136,136,136, + 1,87,87,87,1,16,16,16,1,0,0,0,8,255,255,255,2,0,0,0, + 6,173,173,173,1,255,255,255,2,239,239,239,1,191,191,191,1,139,139,139, + 1,88,88,88,1,15,15,15,1,0,0,0,8,255,255,255,2,0,0,0, + 5,84,84,84,1,193,193,193,1,144,144,144,1,94,94,94,1,22,22,22, + 1,0,0,0,12,255,255,255,2,0,0,0,5,3,3,3,1,0,0,0, + 16,255,255,255,25,0,0) + ); + +const + objdata_tdockpanelformcontroller: record size: integer; data: array[0..2527] of byte end = + (size: 2528; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,24,116,100,111, + 99,107,112,97,110,101,108,102,111,114,109,99,111,110,116,114,111,108,108,101, + 114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109, + 111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,92,9,0,0,0,0,0,0,6,0,0,0,24,0, + 0,0,24,0,0,0,140,7,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,3,3,4,1,5,5,7,1,17,17,22,1,178,178,230,1,180,180, + 231,1,113,113,143,1,6,6,7,2,49,49,61,1,193,193,234,1,195,195, + 235,1,71,71,85,1,6,6,7,2,98,98,114,1,207,207,238,1,210,210, + 239,1,33,33,37,1,7,7,7,2,185,185,204,1,222,222,243,1,212,212, + 230,1,4,4,4,1,113,113,151,1,255,255,255,22,7,7,7,1,171,171, + 228,1,255,255,255,1,242,166,149,1,221,216,211,1,242,166,149,1,140,74, + 60,1,148,78,63,1,180,95,77,1,208,109,89,1,213,112,91,1,246,129, + 105,1,210,110,90,1,251,132,107,1,255,134,109,3,160,160,160,6,128,128, + 128,1,26,26,28,1,171,171,228,1,255,255,255,1,221,216,211,1,7,239, + 255,1,221,216,211,1,138,73,59,1,183,96,78,2,170,89,73,1,189,99, + 81,1,153,80,65,1,158,83,68,1,199,105,85,1,255,134,109,3,160,160, + 160,1,212,212,240,1,128,128,128,1,160,160,160,1,220,220,242,1,128,128, + 128,2,227,227,244,1,14,14,18,1,255,255,255,1,242,166,149,1,221,216, + 211,1,242,166,149,1,211,111,90,1,255,134,109,1,219,115,94,1,215,113, + 92,1,187,98,80,1,220,116,94,1,185,97,79,1,231,121,99,1,255,134, + 109,3,160,160,160,1,212,212,240,1,128,128,128,1,160,160,160,1,220,220, + 242,1,128,128,128,2,227,227,244,1,5,5,7,1,255,255,255,1,151,24, + 0,14,128,128,128,7,124,124,133,1,11,11,14,1,255,255,255,1,175,175, + 229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188, + 233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212, + 240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222,243,1,128,128, + 128,1,7,7,7,1,171,171,228,1,255,255,255,1,175,175,229,1,178,178, + 230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190, + 233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202, + 237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212,240,1,255,255, + 255,1,128,128,128,1,255,255,255,1,128,128,128,2,7,7,7,1,171,171, + 228,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183, + 231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195, + 235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207, + 238,1,210,210,239,1,212,212,240,1,255,255,255,1,128,128,128,1,255,255, + 255,1,128,128,128,2,70,70,75,1,120,120,160,1,255,255,255,1,175,175, + 229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188, + 233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212, + 240,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,2,227,227, + 244,1,5,5,7,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180, + 231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193, + 234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,213,213,240,1,255,255,255,1,128,128, + 128,1,255,255,255,1,128,128,128,2,227,227,244,1,5,5,7,1,255,255, + 255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185, + 232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197, + 236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,213,213,240,1,254,254,255,1,128,128,128,1,255,255,255,1,128,128, + 128,2,70,70,75,1,37,37,49,1,255,255,255,1,175,175,229,1,178,178, + 230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190, + 233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202, + 237,1,205,205,238,1,207,207,238,1,210,210,239,1,213,213,240,1,254,254, + 255,1,128,128,128,1,255,255,255,1,128,128,128,2,7,7,7,1,171,171, + 228,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183, + 231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195, + 235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207, + 238,1,210,210,239,1,213,213,240,1,254,254,255,1,128,128,128,1,255,255, + 255,1,128,128,128,2,7,7,7,1,171,171,228,1,255,255,255,1,175,175, + 229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188, + 233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,213,213, + 240,1,254,254,255,1,128,128,128,1,255,255,255,1,128,128,128,2,124,124, + 133,1,71,71,95,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180, + 231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193, + 234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,214,214,241,1,254,254,254,1,128,128, + 128,1,255,255,255,1,128,128,128,2,227,227,244,1,5,5,7,1,255,255, + 255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185, + 232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197, + 236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,214,214,241,1,253,253,254,1,128,128,128,1,255,255,255,1,128,128, + 128,2,227,227,244,1,5,5,7,1,255,255,255,1,175,175,229,1,178,178, + 230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190, + 233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202, + 237,1,205,205,238,1,207,207,238,1,210,210,239,1,214,214,241,1,253,253, + 254,1,128,128,128,1,255,255,255,1,128,128,128,2,26,26,28,1,77,77, + 103,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183, + 231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195, + 235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207, + 238,1,210,210,239,1,214,214,241,1,253,253,254,1,128,128,128,1,255,255, + 255,1,128,128,128,2,7,7,7,1,171,171,228,1,255,255,255,1,175,175, + 229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188, + 233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,214,214, + 241,1,253,253,254,1,128,128,128,1,255,255,255,1,128,128,128,2,7,7, + 7,1,171,171,228,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180, + 231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193, + 234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,214,214,241,1,253,253,254,1,128,128, + 128,1,255,255,255,1,128,128,128,2,215,215,231,1,33,33,44,1,255,255, + 255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185, + 232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197, + 236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,215,215,241,1,253,253,254,1,217,217,241,1,220,220,242,1,222,222, + 243,1,128,128,128,1,227,227,244,1,5,5,7,1,173,173,229,1,128,128, + 128,21,191,191,205,1,3,3,4,1,129,129,171,1,175,175,229,1,178,178, + 230,1,9,9,11,1,6,6,7,1,18,18,23,1,188,188,233,1,190,190, + 233,1,120,120,145,1,6,6,7,2,52,52,61,1,202,202,237,1,205,205, + 238,1,75,75,86,1,6,6,7,2,103,103,115,1,217,217,241,1,220,220, + 242,1,34,34,38,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244, + 244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248, + 248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173, + 173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128, + 128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255, + 255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195, + 195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180, + 180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146, + 146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128, + 128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188, + 188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248, + 248,1,244,244,244,1,0,0) + ); + +const + objdata_ticon: record size: integer; data: array[0..880] of byte end = + (size: 881; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,5,116,105,99, + 111,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110, + 116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111, + 112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98, + 109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112, + 46,105,109,97,103,101,10,0,3,0,0,0,0,0,0,6,0,0,0,24, + 0,0,0,24,0,0,0,228,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,171,171,171,198,255,255,255,1,255,211,189,1,253,209,189,1,251, + 201,179,1,247,192,169,1,243,184,160,1,239,176,149,1,235,168,139,1,231, + 159,129,1,226,152,119,1,224,145,110,1,255,255,0,1,171,171,171,11,255, + 207,191,1,255,208,190,1,251,200,180,1,247,192,170,1,243,184,160,1,239, + 176,150,1,235,169,139,1,231,161,129,1,228,153,119,1,224,145,109,1,220, + 137,99,1,216,129,89,1,213,121,79,1,207,112,68,1,171,171,171,9,255, + 208,192,1,251,201,181,1,247,193,170,1,243,185,160,1,239,177,150,1,236, + 169,140,1,232,161,130,1,228,153,120,1,224,145,110,1,220,137,100,1,216, + 129,89,1,212,121,79,1,208,113,69,1,205,105,59,1,201,97,49,1,197, + 88,38,1,171,171,171,8,247,192,171,1,244,185,161,1,240,177,151,1,236, + 169,141,1,232,161,131,1,228,154,120,1,224,146,110,1,220,138,100,1,216, + 130,90,1,213,122,80,1,209,114,70,1,205,106,60,1,201,98,50,1,197, + 90,39,1,193,82,29,1,189,75,19,1,171,171,171,8,240,178,151,1,236, + 170,141,1,232,162,131,1,228,154,121,1,224,146,111,1,221,138,101,1,217, + 130,91,1,213,122,80,1,209,114,70,1,205,106,60,1,201,98,50,1,197, + 91,40,1,193,82,30,1,190,75,20,1,186,67,10,1,182,59,0,1,171, + 171,171,8,231,165,133,1,229,154,122,1,225,147,111,1,221,139,101,1,217, + 131,91,1,213,123,81,1,209,115,71,1,205,107,61,1,201,99,51,1,198, + 91,41,1,194,83,31,1,190,75,21,1,186,67,10,1,182,59,0,2,180, + 59,0,1,171,171,171,9,224,139,100,1,217,130,92,1,213,123,82,1,209, + 115,72,1,206,107,62,1,202,99,51,1,198,91,41,1,194,83,31,1,190, + 76,21,1,186,68,11,1,182,60,1,1,182,59,0,2,185,62,0,1,171, + 171,171,12,201,107,67,1,202,101,53,1,198,92,43,1,195,84,32,1,190, + 76,22,1,186,68,12,1,183,60,2,1,182,58,0,1,183,58,0,1,188, + 54,0,1,171,171,171,199,228,0,0,0,0,0,0,198,1,1,1,1,58, + 58,58,1,143,143,143,1,192,192,192,1,217,217,217,1,243,243,243,2,217, + 217,217,1,192,192,192,1,143,143,143,1,58,58,58,1,1,1,1,1,0, + 0,0,11,64,64,64,1,222,222,222,1,255,255,255,10,222,222,222,1,64, + 64,64,1,0,0,0,9,93,93,93,1,253,253,253,1,255,255,255,12,253, + 253,253,1,93,93,93,1,0,0,0,8,212,212,212,1,255,255,255,14,212, + 212,212,1,0,0,0,8,193,193,193,1,255,255,255,14,193,193,193,1,0, + 0,0,8,65,65,65,1,241,241,241,1,255,255,255,12,241,241,241,1,65, + 65,65,1,0,0,0,9,33,33,33,1,182,182,182,1,251,251,251,1,255, + 255,255,8,251,251,251,1,182,182,182,1,33,33,33,1,0,0,0,12,19, + 19,19,1,96,96,96,1,144,144,144,1,169,169,169,1,195,195,195,2,169, + 169,169,1,144,144,144,1,96,96,96,1,19,19,19,1,0,0,0,199,0, + 0) + ); + +initialization + registerobjectdata(@objdata_tsimplewidget,tbitmapcomp,'tsimplewidget'); + registerobjectdata(@objdata_tbutton,tbitmapcomp,'tbutton'); + registerobjectdata(@objdata_tdrawgrid,tbitmapcomp,'tdrawgrid'); + registerobjectdata(@objdata_tstringgrid,tbitmapcomp,'tstringgrid'); + registerobjectdata(@objdata_tmainmenuwidget,tbitmapcomp,'tmainmenuwidget'); + registerobjectdata(@objdata_taction,tbitmapcomp,'taction'); + registerobjectdata(@objdata_tlabel,tbitmapcomp,'tlabel'); + registerobjectdata(@objdata_timage,tbitmapcomp,'timage'); + registerobjectdata(@objdata_tdispwidget,tbitmapcomp,'tdispwidget'); + registerobjectdata(@objdata_tintegerdisp,tbitmapcomp,'tintegerdisp'); + registerobjectdata(@objdata_tint64disp,tbitmapcomp,'tint64disp'); + registerobjectdata(@objdata_trealdisp,tbitmapcomp,'trealdisp'); + registerobjectdata(@objdata_tstringdisp,tbitmapcomp,'tstringdisp'); + registerobjectdata(@objdata_trichstringdisp,tbitmapcomp,'trichstringdisp'); + registerobjectdata(@objdata_tbooleandisp,tbitmapcomp,'tbooleandisp'); + registerobjectdata(@objdata_tedit,tbitmapcomp,'tedit'); + registerobjectdata(@objdata_ttoolbar,tbitmapcomp,'ttoolbar'); + registerobjectdata(@objdata_tsplitter,tbitmapcomp,'tsplitter'); + registerobjectdata(@objdata_tdockhandle,tbitmapcomp,'tdockhandle'); + registerobjectdata(@objdata_teventwidget,tbitmapcomp,'teventwidget'); + registerobjectdata(@objdata_tdockpanel,tbitmapcomp,'tdockpanel'); + registerobjectdata(@objdata_tstockglyphbutton,tbitmapcomp,'tstockglyphbutton'); + registerobjectdata(@objdata_tgroupbox,tbitmapcomp,'tgroupbox'); + registerobjectdata(@objdata_tscrollbox,tbitmapcomp,'tscrollbox'); + registerobjectdata(@objdata_tstepbox,tbitmapcomp,'tstepbox'); + registerobjectdata(@objdata_ttabbar,tbitmapcomp,'ttabbar'); + registerobjectdata(@objdata_ttabpage,tbitmapcomp,'ttabpage'); + registerobjectdata(@objdata_ttabwidget,tbitmapcomp,'ttabwidget'); + registerobjectdata(@objdata_tterminal,tbitmapcomp,'tterminal'); + registerobjectdata(@objdata_tmseformwidget,tbitmapcomp,'tmseformwidget'); + registerobjectdata(@objdata_tdockformwidget,tbitmapcomp,'tdockformwidget'); + registerobjectdata(@objdata_tpaintbox,tbitmapcomp,'tpaintbox'); + registerobjectdata(@objdata_texpandingwidget,tbitmapcomp,'texpandingwidget'); + registerobjectdata(@objdata_tspacer,tbitmapcomp,'tspacer'); + registerobjectdata(@objdata_tlayouter,tbitmapcomp,'tlayouter'); + registerobjectdata(@objdata_tdatetimedisp,tbitmapcomp,'tdatetimedisp'); + registerobjectdata(@objdata_tbytestringdisp,tbitmapcomp,'tbytestringdisp'); + registerobjectdata(@objdata_tlistview,tbitmapcomp,'tlistview'); + registerobjectdata(@objdata_tbarcode,tbitmapcomp,'tbarcode'); + registerobjectdata(@objdata_tdial,tbitmapcomp,'tdial'); + registerobjectdata(@objdata_tchart,tbitmapcomp,'tchart'); + registerobjectdata(@objdata_tchartrecorder,tbitmapcomp,'tchartrecorder'); + registerobjectdata(@objdata_twindowwidget,tbitmapcomp,'twindowwidget'); + registerobjectdata(@objdata_topenglwidget,tbitmapcomp,'topenglwidget'); + registerobjectdata(@objdata_topenglcanvaswidget,tbitmapcomp,'topenglcanvaswidget'); + registerobjectdata(@objdata_tpolygon,tbitmapcomp,'tpolygon'); + registerobjectdata(@objdata_trichbutton,tbitmapcomp,'trichbutton'); + registerobjectdata(@objdata_trichstockglyphbutton,tbitmapcomp,'trichstockglyphbutton'); + registerobjectdata(@objdata_txychartedit,tbitmapcomp,'txychartedit'); + registerobjectdata(@objdata_txserieschartedit,tbitmapcomp,'txserieschartedit'); + registerobjectdata(@objdata_tpickwidget,tbitmapcomp,'tpickwidget'); + registerobjectdata(@objdata_ttraywidget,tbitmapcomp,'ttraywidget'); + registerobjectdata(@objdata_tdockpanelformcontroller,tbitmapcomp,'tdockpanelformcontroller'); + registerobjectdata(@objdata_ticon,tbitmapcomp,'ticon'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regzeoslib.pas b/mseide-msegui/lib/common/regcomponents/regzeoslib.pas new file mode 100644 index 0000000..32c3697 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regzeoslib.pas @@ -0,0 +1,207 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regzeoslib; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + Classes,mclasses,msedesignintf,ZDataset,ZConnection,ZSqlUpdate, + ZStoredProcedure,ZSqlMetadata, + ZSqlProcessor,ZSqlMonitor,ZSequence,msezeos,regzeoslib_bmp,regdb, + msepropertyeditors,ZSqlStrings,ZAbstractRODataset,mseglob,msegui,mdb,msedb, + msetypes{msestrings}; + +type + tzprotocolpropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tzquerysqlpropertyeditor = class(tsqlpropertyeditor) + private + factivebefore: boolean; + protected + procedure doafterclosequery(var amodalresult: modalresultty); override; + function gettestbutton: boolean; override; + function getutf8: boolean; override; + public + procedure edit; override; + end; + + tzreadonlyquerysqlpropertyeditor = class(tsqlpropertyeditor) + private + factivebefore: boolean; + protected + procedure doafterclosequery(var amodalresult: modalresultty); override; + function gettestbutton: boolean; override; + function getutf8: boolean; override; + public + procedure edit; override; + end; + + tzcatalogpropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + +procedure Register; +begin + registercomponents('Zeos',[TZConnection, tmsezreadonlyquery, tmsezquery, + tmseztable, + TZUpdateSQL, tmsezstoredproc, TZSQLMetadata, TZSQLProcessor, + TZSQLMonitor, TZSequence, tmsezgraphicfield]); + registercomponenttabhints(['Zeos'],['ZeosLib database components']); + registerpropertyeditor(typeinfo(string),TZConnection,'Protocol', + tzprotocolpropertyeditor); + { + registerpropertyeditor(typeinfo(tstrings),TmseZreadonlyQuery,'SQL', + tzreadonlyquerysqlpropertyeditor); + registerpropertyeditor(typeinfo(tstrings),TmseZQuery,'SQL', + tzquerysqlpropertyeditor); + } + registerpropertyeditor(typeinfo(tstrings),TZUpdateSQL,'DeleteSQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(tstrings),TZUpdateSQL,'InsertSQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(tstrings),TZUpdateSQL,'ModifySQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(tstrings),TZUpdateSQL,'RefreshSQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(tstrings),TZSqlProcessor,'RefreshSQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(string),TZConnection,'Catalog', + tzcatalogpropertyeditor); + registerpropertyeditor(typeinfo(boolean),TZConnection,'Connected', + tvolatilebooleanpropertyeditor); +end; + +{ tzquerysqlpropertyeditor } + +procedure tzquerysqlpropertyeditor.doafterclosequery( + var amodalresult: modalresultty); +begin + if amodalresult = mr_canclose then begin + tmsezquery(fprops[0].instance).active:= true; + end; +end; + +function tzquerysqlpropertyeditor.gettestbutton: boolean; +begin + result:= true; +end; + +function tzquerysqlpropertyeditor.getutf8: boolean; +begin + result:= dso_utf8 in tmsezquery(fprops[0].instance).controller.options; +end; + +procedure tzquerysqlpropertyeditor.edit; +begin + factivebefore:= tmsezquery(fprops[0].instance).active; + inherited; + if not factivebefore then begin + tmsezquery(fprops[0].instance).active:= false; + end; +end; + +{ tzreadonlyquerysqlpropertyeditor } + +procedure tzreadonlyquerysqlpropertyeditor.doafterclosequery( + var amodalresult: modalresultty); +begin + if amodalresult = mr_canclose then begin + tmsezreadonlyquery(fprops[0].instance).active:= true; + end; +end; + +function tzreadonlyquerysqlpropertyeditor.gettestbutton: boolean; +begin + result:= true; +end; + +function tzreadonlyquerysqlpropertyeditor.getutf8: boolean; +begin + result:= dso_utf8 in tmsezreadonlyquery(fprops[0].instance).controller.options; +end; + +procedure tzreadonlyquerysqlpropertyeditor.edit; +begin + factivebefore:= tmsezreadonlyquery(fprops[0].instance).active; + inherited; + if not factivebefore then begin + tmsezreadonlyquery(fprops[0].instance).active:= false; + end; +end; + +{ tzprotocolpropertyeditor } + +function tzprotocolpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tzprotocolpropertyeditor.getvalues: msestringarty; +var + list1: tstringlist; + int1: integer; +begin + list1:= tstringlist.create; + try + tzconnection(fprops[0].instance).getprotocolnames(list1); + setlength(result,list1.count); + for int1:= 0 to high(result) do begin + result[int1]:= msestring(list1[int1]); + end; + finally + list1.free; + end; +end; + +{ tzcatalogpropertyeditor } + +function tzcatalogpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + if tzconnection(fprops[0].instance).connected then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; +end; + +function tzcatalogpropertyeditor.getvalues: msestringarty; +var + list1: tstringlist; + int1: integer; +begin + list1:= tstringlist.create; + try + tzconnection(fprops[0].instance).getcatalognames(list1); + setlength(result,list1.count); + for int1:= 0 to high(result) do begin + result[int1]:= msestring(list1[int1]); + end; + finally + list1.free; + end; +end; + +initialization + Register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regzeoslib_bmp.pas b/mseide-msegui/lib/common/regcomponents/regzeoslib_bmp.pas new file mode 100644 index 0000000..8f5e851 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regzeoslib_bmp.pas @@ -0,0 +1,696 @@ +unit regzeoslib_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tmsezreadonlyquery: record size: integer; data: array[0..1238] of byte end = + (size: 1239; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,109,115, + 101,122,114,101,97,100,111,110,108,121,113,117,101,114,121,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,160,4,0,0,0,0,0,0,0,0,0, + 0,24,0,0,0,24,0,0,0,108,4,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,2,132,98,4,2,4,20,4,2,132,4,4,2,4, + 1,140,174,76,2,132,170,76,1,116,154,60,1,108,142,52,1,100,138,44, + 1,92,126,36,1,84,118,28,1,76,110,28,1,68,102,20,1,60,90,12, + 1,52,82,12,1,36,70,4,1,28,62,4,1,20,50,4,1,12,42,4, + 1,4,22,4,2,4,2,4,1,164,162,164,1,4,2,132,3,4,2,4, + 1,140,174,76,2,132,170,76,1,108,142,52,2,100,138,44,1,92,126,36, + 1,84,118,28,1,68,102,20,2,60,90,12,1,36,66,44,1,12,22,132, + 1,4,10,164,1,4,18,132,1,4,34,36,1,4,22,4,2,4,2,4, + 1,156,154,148,1,4,2,132,3,4,2,4,1,220,222,220,1,188,190,188, + 6,124,126,124,1,188,190,188,3,28,34,164,1,4,10,164,1,148,146,180, + 1,4,10,164,1,28,34,164,1,188,190,188,2,4,2,4,1,156,154,156, + 1,4,2,132,3,4,2,4,1,252,254,252,1,188,190,188,3,196,194,196, + 1,196,198,196,1,196,194,196,1,188,190,188,1,204,206,204,1,204,202,204, + 1,212,210,204,1,212,214,212,1,212,210,212,1,156,158,204,1,4,10,164, + 1,28,34,172,1,220,222,220,1,228,226,228,1,4,2,4,1,156,154,156, + 1,4,2,132,3,4,2,4,1,252,254,252,1,188,190,188,2,196,194,196, + 3,204,202,204,1,188,190,188,1,204,202,204,2,212,210,212,2,116,122,188, + 1,12,14,164,1,28,34,164,1,188,186,212,1,228,226,228,2,4,2,4, + 1,156,154,156,1,4,2,132,3,4,2,4,1,228,226,228,1,188,190,188, + 6,124,126,124,1,188,190,188,4,4,10,164,2,172,174,188,1,188,190,188, + 3,4,2,4,1,156,154,148,1,4,2,132,3,4,2,4,1,252,254,252, + 1,196,194,196,2,196,198,196,2,204,202,204,2,188,190,188,1,204,206,204, + 1,212,210,212,2,212,214,212,1,220,218,220,2,220,222,220,1,228,226,228, + 2,228,230,228,1,4,2,4,1,156,154,156,1,4,2,132,3,4,2,4, + 1,252,254,252,1,188,190,188,1,196,194,196,1,196,198,196,1,196,194,196, + 1,204,202,204,2,188,190,188,1,212,210,212,1,212,210,204,1,220,218,220, + 1,212,214,212,1,4,10,164,2,228,226,228,2,236,234,236,1,228,230,228, + 1,4,2,4,1,156,154,156,1,4,2,132,3,4,2,4,1,228,226,228, + 1,188,190,188,6,124,126,124,1,188,190,188,4,4,10,164,2,188,190,188, + 4,4,2,4,1,156,154,156,1,4,2,132,3,4,2,4,1,252,254,252, + 1,196,198,196,2,204,202,204,2,132,138,92,1,68,102,20,2,132,138,92, + 1,212,210,204,1,124,134,92,1,68,102,20,3,132,142,100,1,196,198,180, + 1,68,102,20,2,20,22,12,1,156,154,148,1,4,2,132,3,4,2,4, + 1,252,254,252,1,196,202,188,1,196,198,196,1,204,202,204,1,204,206,204, + 1,68,102,20,2,132,138,100,1,68,102,20,1,196,198,188,1,68,102,20, + 2,196,194,180,1,68,102,20,2,196,198,180,1,68,102,20,2,20,22,12, + 1,156,154,156,1,4,2,132,3,4,2,4,1,220,222,220,1,172,174,188, + 1,188,190,188,3,68,102,20,2,116,118,100,1,172,170,156,1,172,174,164, + 1,68,102,20,2,164,162,148,1,68,102,20,2,140,142,108,1,68,102,20, + 2,36,42,12,1,148,146,148,1,4,2,132,2,132,130,4,5,204,206,204, + 2,124,134,92,1,68,102,20,2,124,130,92,1,204,206,196,1,68,102,20, + 2,196,194,180,1,68,102,20,2,196,198,180,1,68,102,20,2,20,22,12, + 1,148,146,124,1,4,2,132,1,132,130,4,2,252,254,252,3,132,130,4, + 2,204,206,204,1,212,210,204,1,124,134,92,1,68,102,20,2,196,202,188, + 1,60,90,12,1,68,102,20,1,196,194,180,1,68,102,20,2,196,198,180, + 1,68,102,20,2,20,22,12,1,148,146,148,1,4,2,132,1,132,130,4, + 4,236,234,236,1,132,130,4,2,4,2,4,3,68,102,20,2,20,22,12, + 1,68,102,20,2,20,26,12,1,68,102,20,2,20,22,12,1,68,102,20, + 2,20,22,12,1,148,146,148,1,4,2,132,1,132,130,4,3,252,254,252, + 1,132,130,4,3,156,154,148,1,68,102,20,1,124,130,92,1,68,102,20, + 2,140,138,124,1,68,102,20,5,140,142,108,1,68,102,20,2,140,142,108, + 1,156,154,148,1,4,2,132,1,132,130,4,2,252,254,252,1,132,130,4, + 4,4,2,132,1,116,126,84,1,68,102,20,2,108,118,76,1,4,2,132, + 1,116,122,76,1,68,102,20,1,60,90,12,1,68,102,20,1,108,118,76, + 1,4,2,132,1,60,90,12,1,68,102,20,2,60,90,12,1,4,2,132, + 1,132,130,4,2,252,254,252,3,132,130,4,2,4,2,132,9,108,118,76, + 1,68,102,20,1,4,2,132,7,132,130,4,5,4,2,132,18,0,0) + ); + +const + objdata_tmsezquery: record size: integer; data: array[0..1270] of byte end = + (size: 1271; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,109,115, + 101,122,113,117,101,114,121,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,200,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,148,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 98,0,0,0,20,0,0,128,4,0,0,0,1,141,175,79,2,134,168,72, + 1,118,152,58,1,109,143,51,1,102,136,44,1,93,127,37,1,85,119,31, + 1,75,109,25,1,67,101,19,1,56,90,14,1,48,82,8,1,37,71,3, + 1,28,62,0,1,17,51,0,1,8,42,0,1,0,23,0,2,0,0,0, + 1,164,161,164,1,0,0,128,3,0,0,0,1,141,175,79,2,134,168,72, + 1,118,152,58,1,109,143,51,1,102,136,44,1,93,127,37,1,85,119,31, + 1,75,109,25,1,67,101,19,1,56,90,14,1,39,67,41,1,10,20,134, + 1,4,10,160,1,6,17,134,1,7,35,34,1,0,23,0,2,0,0,0, + 1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225,1,188,188,188, + 6,125,125,125,1,188,188,188,3,29,33,166,1,4,9,163,1,144,145,182, + 1,4,9,163,1,29,33,166,1,188,188,188,2,0,0,0,1,157,154,157, + 1,0,0,128,3,0,0,0,1,255,255,255,1,188,188,188,2,192,192,192, + 2,197,197,197,1,199,199,199,1,188,188,188,1,204,204,204,2,208,208,208, + 1,211,211,211,1,213,213,213,1,157,158,201,1,4,9,163,1,29,34,170, + 1,225,225,225,1,227,227,227,1,0,0,0,1,157,154,157,1,0,0,128, + 3,0,0,0,1,255,255,255,1,188,188,188,1,189,189,189,1,194,194,194, + 2,199,199,199,1,201,201,201,1,188,188,188,1,206,206,206,2,210,210,210, + 1,212,212,212,1,119,121,191,1,6,11,163,1,34,38,171,1,184,185,212, + 1,226,226,226,1,229,229,229,1,0,0,0,1,157,154,157,1,0,0,128, + 3,0,0,0,1,225,225,225,1,188,188,188,6,125,125,125,1,188,188,188, + 4,8,13,164,1,4,9,163,1,171,172,186,1,188,188,188,3,0,0,0, + 1,157,154,157,1,0,0,128,3,0,0,0,1,255,255,255,1,191,191,191, + 1,193,193,193,1,198,198,198,2,202,202,202,1,205,205,205,1,188,188,188, + 1,209,209,209,2,214,214,214,1,216,216,216,1,218,218,218,1,221,221,221, + 1,225,225,225,2,230,230,230,1,232,232,232,1,0,0,0,1,157,154,157, + 1,0,0,128,3,0,0,0,1,255,255,255,1,192,192,192,1,195,195,195, + 1,199,199,199,2,204,204,204,1,206,206,206,1,188,188,188,1,211,211,211, + 2,216,216,216,1,218,218,218,1,4,9,163,2,227,227,227,2,232,232,232, + 1,234,234,234,1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0, + 1,225,225,225,1,188,188,188,5,188,188,187,1,125,125,125,1,188,188,187, + 2,188,188,188,1,188,188,187,1,4,9,163,2,188,188,187,1,188,188,188, + 3,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,255,255,255, + 1,196,196,196,1,198,198,198,1,203,203,203,2,171,160,148,1,112,82,53, + 2,173,161,150,1,213,212,211,1,174,163,151,1,112,82,53,3,182,170,158, + 1,216,212,209,1,112,82,53,2,14,11,7,1,157,154,157,1,0,0,128, + 3,0,0,0,1,255,255,255,1,198,198,198,1,200,200,200,1,205,205,205, + 1,205,205,204,1,112,82,53,2,165,156,148,1,112,82,53,1,209,207,205, + 1,112,82,53,2,208,205,202,1,112,82,53,2,216,212,208,1,112,82,53, + 2,15,11,7,1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225, + 1,188,188,188,3,188,188,187,1,112,82,53,2,123,119,115,1,180,176,173, + 1,182,180,177,1,112,82,53,2,178,173,169,1,112,82,53,2,169,162,155, + 1,112,82,53,2,28,20,13,1,155,150,152,1,0,0,128,2,128,128,0, + 5,208,208,207,2,172,160,148,1,112,82,53,2,172,159,146,1,213,211,210, + 1,112,82,53,2,212,208,204,1,112,82,53,2,219,215,211,1,112,82,53, + 2,15,11,7,1,155,150,151,1,0,0,128,1,128,128,0,2,255,255,255, + 3,128,128,0,2,210,210,209,1,212,211,211,1,172,159,146,1,112,82,53, + 2,212,209,207,1,112,82,53,2,214,210,206,1,112,82,53,2,220,216,212, + 1,112,82,53,2,15,11,7,1,155,150,151,1,0,0,128,1,128,128,0, + 4,255,255,255,1,128,128,0,2,0,0,0,1,1,1,1,1,5,4,2, + 1,112,82,53,2,14,10,7,1,112,82,53,2,16,12,7,1,112,82,53, + 2,16,12,7,1,112,82,53,2,15,11,7,1,155,150,151,1,0,0,128, + 1,128,128,0,3,255,255,255,1,128,128,0,3,157,154,157,1,112,82,53, + 1,146,136,132,1,112,82,53,2,151,144,143,1,112,82,53,5,151,144,142, + 1,112,82,53,2,151,144,143,1,161,156,157,1,0,0,128,1,128,128,0, + 2,255,255,255,1,128,128,0,4,0,0,128,1,159,145,135,1,112,82,53, + 2,153,137,126,1,0,0,128,1,155,141,130,1,112,82,53,3,152,136,123, + 1,0,0,128,1,112,82,53,4,0,0,128,1,128,128,0,2,255,255,255, + 3,128,128,0,2,0,0,128,9,157,142,130,1,112,82,53,1,0,0,128, + 7,128,128,0,5,0,0,128,18,0,0) + ); + +const + objdata_tmseztable: record size: integer; data: array[0..1070] of byte end = + (size: 1071; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,109,115, + 101,122,116,97,98,108,101,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,0,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,204,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 98,0,0,0,20,0,0,128,4,0,0,0,1,141,175,79,2,134,168,72, + 1,118,152,58,1,109,143,51,1,102,136,44,1,93,127,37,1,85,119,31, + 1,75,109,25,1,67,101,19,1,56,90,14,1,48,82,8,1,37,71,3, + 1,28,62,0,1,17,51,0,1,8,42,0,1,0,23,0,2,0,0,0, + 1,164,161,164,1,0,0,128,3,0,0,0,1,141,175,79,2,134,168,72, + 1,118,152,58,1,109,143,51,1,102,136,44,1,93,127,37,1,85,119,31, + 1,75,109,25,1,67,101,19,1,56,90,14,1,48,82,8,1,37,71,3, + 1,28,62,0,1,17,51,0,1,8,42,0,1,0,23,0,2,0,0,0, + 1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225,1,188,188,188, + 6,125,125,125,1,188,188,188,10,0,0,0,1,157,154,157,1,0,0,128, + 3,0,0,0,1,255,255,255,1,188,188,188,2,192,192,192,2,197,197,197, + 1,199,199,199,1,188,188,188,1,204,204,204,2,208,208,208,1,211,211,211, + 1,213,213,213,1,215,215,215,1,220,220,220,2,225,225,225,1,227,227,227, + 1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,255,255,255, + 1,188,188,188,1,189,189,189,1,194,194,194,2,199,199,199,1,201,201,201, + 1,188,188,188,1,206,206,206,2,210,210,210,1,212,212,212,1,215,215,215, + 1,217,217,217,1,222,222,222,2,226,226,226,1,229,229,229,1,0,0,0, + 1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225,1,188,188,188, + 6,125,125,125,1,188,188,188,10,0,0,0,1,157,154,157,1,0,0,128, + 3,0,0,0,1,255,255,255,1,191,191,191,1,193,193,193,1,198,198,198, + 2,202,202,202,1,205,205,205,1,188,188,188,1,209,209,209,2,214,214,214, + 1,216,216,216,1,218,218,218,1,221,221,221,1,225,225,225,2,230,230,230, + 1,232,232,232,1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0, + 1,255,255,255,1,192,192,192,1,195,195,195,1,199,199,199,2,204,204,204, + 1,206,206,206,1,188,188,188,1,211,211,211,2,216,216,216,1,218,218,218, + 1,220,220,220,1,223,223,223,1,227,227,227,2,232,232,232,1,234,234,234, + 1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225, + 1,188,188,188,6,125,125,125,1,188,188,188,10,0,0,0,1,157,154,157, + 1,0,0,128,3,0,0,0,1,255,255,255,1,196,196,196,1,198,198,198, + 1,203,203,203,2,208,208,208,1,210,210,210,1,188,188,188,1,215,215,215, + 2,214,214,214,1,216,216,216,1,218,218,218,1,221,221,221,1,231,231,231, + 2,235,235,235,1,238,238,238,1,0,0,0,1,157,154,157,1,0,0,128, + 3,0,0,0,1,255,255,255,1,198,198,198,1,200,200,200,1,205,205,205, + 2,209,209,209,1,212,212,212,1,188,188,188,1,216,216,216,3,218,218,218, + 1,220,220,220,1,223,223,223,1,233,233,233,2,237,237,237,1,240,240,240, + 1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225, + 1,188,188,188,6,125,125,125,1,188,188,188,10,0,0,0,1,157,154,157, + 1,0,0,128,2,128,128,0,5,208,208,208,2,213,213,213,1,215,215,215, + 1,188,188,188,1,220,220,220,2,225,225,225,1,227,227,227,1,229,229,229, + 1,232,232,232,1,236,236,236,2,241,241,241,1,243,243,243,1,0,0,0, + 1,157,154,157,1,0,0,128,1,128,128,0,2,255,255,255,3,128,128,0, + 2,210,210,210,1,215,215,215,1,217,217,217,1,188,188,188,1,222,222,222, + 2,226,226,226,1,229,229,229,1,231,231,231,1,233,233,233,1,238,238,238, + 2,243,243,243,1,245,245,245,1,0,0,0,1,157,154,157,1,0,0,128, + 1,128,128,0,4,255,255,255,1,128,128,0,2,0,0,0,15,157,154,157, + 1,0,0,128,1,128,128,0,3,255,255,255,1,128,128,0,3,157,154,157, + 15,164,161,164,1,0,0,128,1,128,128,0,2,255,255,255,1,128,128,0, + 4,0,0,128,17,128,128,0,2,255,255,255,3,128,128,0,2,0,0,128, + 18,128,128,0,5,0,0,128,18,0,0) + ); + +const + objdata_TZConnection: record size: integer; data: array[0..1008] of byte end = + (size: 1009; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,84,90,67, + 111,110,110,101,99,116,105,111,110,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,192,3,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,140,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,128,51,142,140,142,1,97,95,97,1,0,0,0,6,97,95,97,1,146, + 144,146,1,0,0,128,13,141,140,141,1,0,0,0,1,55,142,55,1,66, + 170,66,1,81,205,81,4,63,161,63,1,49,126,49,1,0,0,0,1,136, + 134,136,1,0,0,128,12,0,0,0,1,105,210,105,1,81,205,81,8,83, + 177,83,1,0,0,0,1,0,0,128,12,0,0,0,1,125,192,125,1,132, + 218,132,1,99,209,99,1,81,205,81,4,127,207,127,1,126,195,126,1,87, + 152,87,1,0,0,0,1,0,0,128,12,0,0,0,1,70,159,70,1,93, + 171,93,1,145,197,145,1,177,213,177,1,182,213,182,1,177,210,177,1,175, + 207,175,1,130,180,130,1,93,155,93,1,34,112,34,1,0,0,0,1,0, + 0,128,12,0,0,0,1,70,159,70,2,141,190,141,1,130,184,130,1,59, + 146,59,1,54,140,54,1,50,134,50,1,45,129,45,1,41,123,41,1,34, + 112,34,1,0,0,0,1,63,107,118,1,0,0,0,1,0,0,128,10,0, + 0,0,1,70,159,70,2,133,186,133,1,139,188,139,1,59,146,59,1,54, + 140,54,1,50,134,50,1,45,129,45,1,41,123,41,1,34,112,34,1,50, + 83,93,1,186,229,239,1,0,0,0,1,0,0,128,10,0,0,0,1,70, + 159,70,2,122,181,122,1,130,184,130,1,59,146,59,1,54,140,54,1,50, + 134,50,1,45,129,45,1,41,123,41,1,48,82,90,1,187,229,238,1,128, + 214,238,1,0,0,0,1,19,31,35,1,22,37,42,1,10,16,18,1,0, + 0,128,7,0,0,0,1,70,159,70,2,108,175,108,1,119,178,119,1,59, + 146,59,1,54,140,54,1,50,134,50,1,45,129,45,1,46,79,87,1,182, + 228,239,1,128,214,238,4,109,183,204,1,79,134,150,1,0,0,0,1,0, + 0,128,6,0,0,0,1,70,159,70,2,108,175,108,1,119,178,119,1,59, + 146,59,1,54,140,54,1,50,134,50,1,40,68,75,1,178,226,238,1,128, + 214,238,7,93,157,175,1,0,0,0,1,0,0,128,5,0,0,0,1,65, + 150,65,1,70,159,70,1,108,175,108,1,104,171,104,1,59,146,59,1,54, + 140,54,1,50,134,50,1,39,66,73,1,6,100,143,1,12,148,209,5,40, + 163,215,1,70,180,222,1,128,214,238,1,87,147,164,1,0,0,0,1,0, + 0,128,4,74,81,74,1,0,0,0,1,37,85,37,1,74,133,74,1,85, + 159,85,1,59,145,59,1,56,140,56,1,53,136,53,1,34,96,34,1,25, + 44,48,1,6,100,143,1,12,148,209,2,0,0,0,2,4,82,118,1,9, + 112,158,1,53,170,217,1,109,183,204,1,0,0,0,1,0,0,128,5,115, + 121,115,1,58,75,58,1,0,0,0,6,57,69,57,1,21,35,39,1,7, + 107,152,1,12,148,209,1,0,0,0,1,0,0,128,1,0,0,0,1,3, + 64,92,1,10,125,176,1,128,214,238,1,0,0,0,1,0,0,128,15,15, + 26,30,1,17,102,137,1,0,0,0,1,0,0,128,2,0,0,0,1,8, + 107,152,1,128,214,238,1,0,0,0,1,0,0,128,16,17,30,34,1,6, + 11,11,1,0,0,128,2,0,0,0,1,65,145,174,1,69,118,132,1,0, + 0,0,1,0,0,128,3,128,128,0,5,0,0,128,12,0,0,0,1,120, + 201,224,1,0,0,0,1,0,0,128,3,128,128,0,2,255,255,255,3,128, + 128,0,2,0,0,128,10,0,0,0,1,107,180,201,1,68,116,129,1,0, + 0,0,1,0,0,128,3,128,128,0,4,255,255,255,1,128,128,0,2,0, + 0,128,9,0,0,0,1,92,156,174,1,79,134,150,1,0,0,0,1,0, + 0,128,4,128,128,0,3,255,255,255,1,128,128,0,3,0,0,128,10,0, + 0,0,2,0,0,128,5,128,128,0,2,255,255,255,1,128,128,0,4,0, + 0,128,17,128,128,0,2,255,255,255,3,128,128,0,2,0,0,128,18,128, + 128,0,5,0,0,128,18,0,0) + ); + +const + objdata_TZSequence: record size: integer; data: array[0..1406] of byte end = + (size: 1407; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,84,90,83, + 101,113,117,101,110,99,101,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,80,5,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,28,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 17,150,133,119,1,119,92,67,1,108,78,49,1,119,92,67,1,150,133,119, + 1,0,0,128,18,47,47,47,1,108,78,49,1,167,121,76,1,172,125,79, + 1,167,121,76,1,108,78,49,1,47,47,47,1,0,0,128,4,142,140,142, + 1,97,95,97,1,0,0,0,6,97,95,97,1,146,144,146,1,0,0,128, + 2,92,91,92,1,108,78,49,1,172,125,79,2,255,255,255,1,172,125,79, + 2,108,78,49,1,93,92,93,1,0,0,128,2,141,140,141,1,0,0,0, + 1,55,142,55,1,66,170,66,1,81,205,81,4,63,161,63,1,49,126,49, + 1,0,0,0,1,136,134,136,1,0,0,128,1,0,0,0,1,167,121,76, + 1,172,125,79,1,108,78,49,1,255,255,255,1,108,78,49,1,172,125,79, + 1,167,121,76,1,24,24,24,1,0,0,128,2,0,0,0,1,105,210,105, + 1,81,205,81,8,83,177,83,1,0,0,0,1,0,0,128,1,0,0,0, + 1,172,125,79,1,255,255,255,5,172,125,79,1,0,0,0,1,0,0,128, + 2,0,0,0,1,125,192,125,1,132,218,132,1,99,209,99,1,81,205,81, + 4,127,207,127,1,126,195,126,1,87,152,87,1,0,0,0,1,0,0,128, + 1,27,20,14,1,167,121,76,1,172,125,79,1,108,78,49,1,255,255,255, + 1,108,78,49,1,172,125,79,1,167,121,76,1,24,24,24,1,0,0,128, + 2,0,0,0,1,70,159,70,1,93,171,93,1,145,197,145,1,177,213,177, + 1,182,213,182,1,177,210,177,1,175,207,175,1,130,180,130,1,93,155,93, + 1,34,112,34,1,0,0,0,1,0,0,128,1,93,92,93,1,108,78,49, + 1,172,125,79,2,255,255,255,1,172,125,79,2,108,78,49,1,93,92,93, + 1,0,0,128,2,0,0,0,1,70,159,70,2,141,190,141,1,130,184,130, + 1,59,146,59,1,54,140,54,1,50,134,50,1,45,129,45,1,41,123,41, + 1,34,112,34,1,0,0,0,1,0,0,128,2,47,47,47,1,108,78,49, + 1,167,121,76,1,172,125,79,1,167,121,76,1,108,78,49,1,47,47,47, + 1,0,0,128,3,0,0,0,1,70,159,70,2,133,186,133,1,139,188,139, + 1,59,146,59,1,54,140,54,1,50,134,50,1,45,129,45,1,40,122,40, + 1,33,110,33,1,0,0,0,1,0,0,128,3,93,92,93,1,18,13,8, + 1,0,0,0,1,17,17,17,1,84,82,84,1,0,0,128,4,0,0,0, + 1,70,159,70,2,122,181,122,1,130,184,130,1,59,146,59,1,54,140,54, + 1,42,114,42,1,29,85,29,1,0,0,0,3,137,135,137,1,0,0,128, + 11,0,0,0,1,70,159,70,2,108,175,108,1,119,178,119,1,59,146,59, + 1,53,139,53,1,0,0,0,3,137,135,137,1,0,0,0,3,0,0,128, + 10,0,0,0,1,70,159,70,2,108,175,108,1,119,178,119,1,59,146,59, + 1,53,137,53,1,0,0,0,1,137,135,137,1,143,149,151,1,129,135,137, + 1,133,140,142,1,120,128,131,1,0,0,0,1,112,111,112,1,0,0,128, + 9,0,0,0,1,65,150,65,1,70,159,70,1,108,175,108,1,104,171,104, + 1,58,145,58,1,0,0,0,2,115,121,123,1,95,101,103,1,59,63,64, + 1,97,102,104,1,114,122,124,1,0,0,0,2,0,0,128,9,74,81,74, + 1,0,0,0,1,37,85,37,1,74,133,74,1,85,159,85,1,58,143,58, + 1,0,0,0,1,137,135,137,1,146,153,154,1,78,82,83,1,20,22,23, + 1,115,117,118,1,147,153,155,1,74,80,82,1,0,0,0,1,146,144,146, + 1,0,0,128,9,115,121,115,1,58,75,58,1,0,0,0,5,115,120,121, + 1,125,132,134,1,150,153,154,1,179,182,183,1,117,123,125,1,0,0,0, + 2,140,138,140,1,0,0,128,15,0,0,0,1,131,136,138,1,100,105,107, + 1,108,117,120,1,86,93,95,1,77,83,84,1,0,0,0,1,83,82,83, + 1,0,0,128,16,0,0,0,3,60,65,66,1,0,0,0,3,112,110,112, + 1,0,0,128,1,1,1,1,3,0,0,128,4,128,128,0,5,0,0,128, + 5,0,0,0,3,105,104,105,1,6,6,6,2,125,123,125,1,4,4,4, + 1,225,227,228,1,3,3,3,1,122,120,122,1,8,8,8,1,9,9,9, + 1,128,128,0,2,255,255,255,3,128,128,0,2,0,0,128,7,6,6,6, + 1,225,225,225,1,177,179,179,1,6,6,6,1,65,70,72,1,150,157,159, + 1,65,70,72,1,6,6,6,1,129,135,136,1,33,33,33,1,128,128,0, + 4,255,255,255,1,128,128,0,2,0,0,128,7,8,8,8,1,173,175,176, + 1,161,167,168,1,150,157,159,3,134,142,144,1,142,149,151,1,116,125,128, + 1,65,70,72,1,128,128,0,3,255,255,255,1,128,128,0,3,0,0,128, + 8,7,7,7,1,150,157,159,2,84,88,89,1,87,94,96,1,131,136,137, + 1,116,125,128,1,107,116,118,1,6,6,6,1,128,128,0,2,255,255,255, + 1,128,128,0,4,0,0,128,6,1,1,1,2,65,70,72,1,150,157,159, + 1,87,94,96,1,63,66,67,1,36,39,40,1,48,52,54,1,150,157,159, + 1,99,107,109,1,65,70,72,1,128,128,0,2,255,255,255,3,128,128,0, + 2,0,0,128,6,1,1,1,1,225,226,226,1,175,181,182,1,150,157,159, + 1,84,88,89,1,30,32,33,1,8,9,10,1,22,24,24,1,228,230,230, + 1,116,125,128,1,92,99,101,1,0,0,128,1,128,128,0,5,0,0,128, + 7,1,1,1,1,3,3,3,1,65,70,72,1,150,157,159,1,131,136,137, + 1,48,52,54,1,20,22,22,1,137,139,140,1,220,222,223,1,92,99,101, + 1,0,0,128,1,0,0) + ); + +const + objdata_TZSqlMetadata: record size: integer; data: array[0..1253] of byte end = + (size: 1254; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,84,90,83, + 113,108,77,101,116,97,100,97,116,97,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,180,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,128,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,128,51,102,101,102,1,48,47,48,1,0,0,0,6,48,47,48,1, + 108,107,108,1,0,0,128,13,101,102,101,1,0,0,0,1,55,142,55,1, + 66,170,66,1,81,205,81,4,63,161,63,1,49,126,49,1,0,0,0,1, + 94,93,94,1,0,0,128,12,0,0,0,1,105,210,105,1,81,205,81,8, + 83,177,83,1,0,0,0,1,0,0,128,12,0,0,0,1,125,192,125,1, + 132,218,132,1,99,209,99,1,81,205,81,4,127,207,127,1,126,195,126,1, + 87,152,87,1,0,0,0,1,0,0,128,12,0,0,0,1,70,159,70,1, + 93,171,93,1,145,197,145,1,177,213,177,1,182,213,182,1,177,210,177,1, + 175,207,175,1,130,180,130,1,93,155,93,1,34,112,34,1,0,0,0,1, + 0,0,128,12,0,0,0,1,70,159,70,2,141,190,141,1,130,184,130,1, + 59,146,59,1,54,140,54,1,50,134,50,1,45,129,45,1,41,123,41,1, + 34,112,34,1,0,0,0,1,0,0,128,12,0,0,0,1,70,159,70,2, + 133,186,133,1,139,188,139,1,59,146,59,1,54,140,54,1,50,134,50,1, + 45,129,45,1,41,123,41,1,34,112,34,1,0,0,0,1,0,0,128,12, + 0,0,0,1,70,159,70,2,122,181,122,1,130,184,130,1,59,146,59,1, + 54,140,54,1,0,0,0,7,0,0,128,3,120,118,120,1,0,0,0,1, + 120,118,120,1,0,0,128,4,0,0,0,1,70,159,70,2,108,175,108,1, + 119,178,119,1,59,146,59,1,54,140,54,1,0,0,0,1,97,123,232,1, + 67,97,228,4,0,0,0,1,0,0,128,3,37,37,37,1,208,200,194,1, + 0,0,0,1,0,0,128,4,0,0,0,1,70,159,70,2,108,175,108,1, + 119,178,119,1,59,146,59,1,54,140,54,1,0,0,0,1,67,97,228,1, + 30,66,223,4,0,0,0,1,0,0,128,2,120,118,120,1,26,26,26,1, + 187,162,139,1,0,0,0,1,120,118,120,1,0,0,128,3,0,0,0,1, + 65,150,65,1,70,159,70,1,108,175,108,1,104,171,104,1,59,146,59,1, + 54,140,54,1,0,0,0,1,67,97,228,1,30,66,223,4,0,0,0,1, + 0,0,128,2,56,56,56,1,216,208,199,1,174,144,117,1,145,120,97,1, + 56,56,56,1,0,0,128,3,31,42,31,1,0,0,0,1,37,85,37,1, + 74,133,74,1,85,159,85,1,59,145,59,1,55,140,55,1,0,0,0,1, + 67,97,228,1,30,66,223,4,0,0,0,1,0,0,128,1,120,118,120,1, + 0,0,0,1,198,177,158,1,174,144,117,2,0,0,0,1,120,118,120,1, + 0,0,128,3,68,80,68,1,24,45,24,1,0,0,0,5,67,97,228,1, + 30,66,223,4,0,0,0,1,0,0,128,1,22,22,22,1,216,208,199,1, + 174,144,117,3,145,120,97,1,0,0,0,1,0,0,128,5,166,163,166,1, + 150,149,150,1,150,147,150,1,148,146,148,1,0,0,0,7,0,0,128,1, + 0,0,0,7,0,0,128,25,128,128,0,5,0,0,128,4,120,118,120,1, + 32,32,32,1,0,0,0,1,32,32,32,1,120,118,120,1,0,0,128,4, + 120,118,120,1,0,0,0,1,120,118,120,1,0,0,128,2,128,128,0,2, + 255,255,255,3,128,128,0,2,0,0,128,2,120,118,120,1,18,53,71,1, + 118,192,230,1,121,197,239,1,96,177,226,1,18,49,71,1,120,118,120,1, + 0,0,128,2,120,118,120,1,0,0,0,1,120,169,120,1,0,0,0,1, + 120,118,120,1,0,0,128,1,128,128,0,4,255,255,255,1,128,128,0,2, + 0,0,128,2,32,32,32,1,137,200,232,1,75,180,235,1,61,170,234,1, + 61,167,234,1,51,143,204,1,32,32,32,1,0,0,128,1,120,118,120,1, + 0,0,0,1,120,169,120,1,58,131,58,1,76,142,76,1,24,24,24,1, + 120,118,120,1,128,128,0,3,255,255,255,1,128,128,0,3,0,0,128,2, + 0,0,0,1,139,205,241,1,61,171,234,1,61,168,234,1,61,164,233,1, + 54,147,213,1,0,0,0,1,0,0,128,1,0,0,0,1,130,170,130,1, + 58,131,58,1,38,119,38,2,70,123,70,1,0,0,0,1,128,128,0,2, + 255,255,255,1,128,128,0,4,0,0,128,2,32,32,32,1,118,189,230,1, + 61,168,234,1,61,165,233,1,60,157,228,1,48,128,192,1,32,32,32,1, + 0,0,128,1,120,118,120,1,0,0,0,1,34,107,34,1,38,119,38,1, + 30,96,30,1,0,0,0,1,120,118,120,1,128,128,0,2,255,255,255,3, + 128,128,0,2,0,0,128,2,120,118,120,1,18,50,71,1,50,141,200,1, + 52,141,205,1,48,129,192,1,16,43,66,1,120,118,120,1,0,0,128,2, + 120,118,120,1,0,0,0,1,27,86,27,1,0,0,0,1,120,118,120,1, + 0,0,128,2,128,128,0,5,0,0,128,4,120,118,120,1,32,32,32,1, + 0,0,0,1,32,32,32,1,120,118,120,1,0,0,128,4,120,118,120,1, + 0,0,0,1,120,118,120,1,0,0,128,2,0,0) + ); + +const + objdata_TZSqlMonitor: record size: integer; data: array[0..1524] of byte end = + (size: 1525; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,84,90,83, + 113,108,77,111,110,105,116,111,114,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,196,5,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,144,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,128,1,142,140,142,1,97,95,97,1,0,0,0,6,97,95,97,1,146, + 144,146,1,0,0,128,13,141,140,141,1,0,0,0,1,55,142,55,1,66, + 170,66,1,81,205,81,4,63,161,63,1,49,126,49,1,0,0,0,1,136, + 134,136,1,0,0,128,12,0,0,0,1,105,210,105,1,81,205,81,8,83, + 177,83,1,0,0,0,1,0,0,128,12,0,0,0,1,125,192,125,1,132, + 218,132,1,99,209,99,1,81,205,81,4,127,207,127,1,126,195,126,1,76, + 132,76,1,0,0,0,1,73,72,73,1,0,0,0,1,2,2,2,1,57, + 56,57,1,118,116,118,1,0,0,128,7,0,0,0,1,70,159,70,1,93, + 171,93,1,145,197,145,1,177,213,177,1,182,213,182,1,177,210,177,1,175, + 207,175,1,130,180,130,1,62,103,62,1,3,8,3,1,93,79,67,1,146, + 125,105,1,156,135,113,1,161,138,115,1,152,129,107,1,88,75,61,1,12, + 11,12,1,129,127,129,1,0,0,128,5,0,0,0,1,70,159,70,2,141, + 190,141,1,130,184,130,1,59,146,59,1,54,140,54,1,50,134,50,1,39, + 112,39,1,3,8,3,1,130,112,94,1,176,159,142,1,203,194,185,1,225, + 220,214,1,230,222,215,1,201,182,162,1,178,150,124,1,134,113,93,1,11, + 11,11,1,0,0,128,5,0,0,0,1,70,159,70,2,133,186,133,1,139, + 188,139,1,59,146,59,1,54,140,54,1,50,134,50,1,22,62,22,1,91, + 78,65,1,179,162,145,1,222,217,211,1,247,246,246,1,249,247,245,1,244, + 238,233,1,234,224,215,1,197,172,148,1,184,155,128,1,100,83,68,1,98, + 97,98,1,0,0,128,4,0,0,0,1,70,159,70,2,122,181,122,1,130, + 184,130,1,59,146,59,1,54,140,54,1,50,133,50,1,13,37,13,1,148, + 127,106,1,207,196,185,1,248,246,245,1,249,246,242,1,244,238,233,1,232, + 221,211,1,214,195,177,1,189,161,134,1,190,164,140,1,168,141,115,1,47, + 46,47,1,0,0,128,4,0,0,0,1,70,159,70,2,108,175,108,1,119, + 178,119,1,59,146,59,1,54,140,54,1,50,133,50,1,0,0,0,1,156, + 134,112,1,233,230,227,1,252,250,249,1,243,237,231,1,233,223,212,1,217, + 199,182,1,193,166,139,1,189,160,133,1,196,172,149,1,184,156,132,1,1, + 1,1,1,0,0,128,4,0,0,0,1,70,159,70,2,108,175,108,1,119, + 178,119,1,59,146,59,1,54,140,54,1,49,132,49,1,0,0,0,1,149, + 127,106,1,225,220,213,1,242,235,229,1,232,221,211,1,217,199,182,1,195, + 168,141,1,191,163,136,1,187,158,131,1,202,181,162,1,183,157,133,1,0, + 0,0,1,0,0,128,4,0,0,0,1,65,150,65,1,70,159,70,1,108, + 175,108,1,104,171,104,1,59,146,59,1,54,140,54,1,49,132,49,1,8, + 24,8,1,137,116,96,1,187,169,151,1,226,215,204,1,215,198,181,1,193, + 166,139,1,191,163,136,1,190,162,136,1,195,171,148,1,209,192,175,1,164, + 137,111,1,48,47,48,1,0,0,128,4,74,81,74,1,0,0,0,1,37, + 85,37,1,74,133,74,1,85,159,85,1,59,145,59,1,56,140,56,1,53, + 135,53,1,14,40,14,1,81,67,56,1,154,130,107,1,177,155,135,1,185, + 157,132,1,187,158,131,1,190,162,137,1,197,173,151,1,215,200,185,1,189, + 164,141,1,99,82,66,1,93,91,93,1,0,0,128,5,115,121,115,1,58, + 75,58,1,0,0,0,6,1,2,1,1,115,96,79,1,147,124,102,1,170, + 150,132,1,180,159,139,1,196,177,159,1,205,188,171,1,195,173,152,1,138, + 114,93,1,5,5,5,1,127,126,127,1,0,0,128,11,115,113,115,1,62, + 61,62,1,0,0,0,1,11,11,11,1,85,71,57,1,136,116,97,1,153, + 131,111,1,155,130,106,1,156,129,105,1,98,81,65,1,5,5,5,1,89, + 87,89,1,0,0,128,10,171,168,171,1,0,0,0,1,5,5,5,1,7, + 7,7,1,18,13,8,1,46,34,22,1,56,51,47,1,37,37,37,1,1, + 1,1,1,0,0,0,1,21,15,10,1,50,36,23,1,102,93,87,1,0, + 0,128,1,98,72,47,1,108,79,51,1,0,0,128,7,156,154,156,1,38, + 38,38,1,185,185,185,1,144,144,144,1,22,22,22,1,47,35,22,1,129, + 121,115,1,93,68,44,1,161,158,158,1,91,67,43,1,86,63,41,1,142, + 137,136,1,88,65,42,1,94,69,45,1,0,0,128,1,108,79,51,1,111, + 81,53,1,0,0,128,6,167,164,167,1,13,13,13,1,177,177,177,1,110, + 110,110,1,0,0,0,2,77,56,36,1,151,145,144,1,0,0,128,2,105, + 77,50,1,103,76,49,1,0,0,128,1,104,76,49,1,107,78,51,1,0, + 0,128,1,112,82,53,2,0,0,128,4,128,128,0,5,0,0,0,2,74, + 68,63,1,84,62,40,1,100,73,47,1,155,141,130,1,0,0,128,1,111, + 81,53,2,0,0,128,1,111,81,53,1,112,82,53,1,0,0,128,1,112, + 82,53,2,0,0,128,3,128,128,0,2,255,255,255,3,128,128,0,2,86, + 84,85,1,144,141,142,1,139,127,117,1,108,79,51,1,112,82,53,1,0, + 0,128,1,112,82,53,2,0,0,128,1,112,82,53,2,0,0,128,1,112, + 82,53,2,0,0,128,3,128,128,0,4,255,255,255,1,128,128,0,2,145, + 143,145,1,0,0,128,2,111,81,53,1,112,82,53,1,0,0,128,1,112, + 82,53,2,0,0,128,1,112,82,53,2,0,0,128,1,112,82,53,2,0, + 0,128,3,128,128,0,3,255,255,255,1,128,128,0,3,0,0,128,1,107, + 78,51,1,175,166,161,1,112,82,53,2,0,0,128,1,112,82,53,5,0, + 0,128,1,112,82,53,2,0,0,128,3,128,128,0,2,255,255,255,1,128, + 128,0,4,0,0,128,1,162,149,139,1,112,82,53,2,157,142,130,1,0, + 0,128,1,160,145,134,1,112,82,53,3,156,140,128,1,0,0,128,1,112, + 82,53,4,0,0,128,1,128,128,0,2,255,255,255,3,128,128,0,2,0, + 0,128,9,157,142,130,1,112,82,53,1,0,0,128,7,128,128,0,5,0, + 0,128,18,0,0) + ); + +const + objdata_TZSqlProcessor: record size: integer; data: array[0..1202] of byte end = + (size: 1203; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,84,90,83, + 113,108,80,114,111,99,101,115,115,111,114,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,128,4,0,0,0,0,0,0,0,0,0,0,24,0,0, + 0,24,0,0,0,76,4,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,128,53,121,119,121,1,0,0,0,15,119,117,119,1,0,0,128, + 6,121,119,121,1,156,156,156,1,251,251,251,1,241,241,241,1,233,233,233, + 9,241,241,241,1,207,207,207,1,214,214,214,1,155,155,155,1,64,64,64, + 1,119,117,119,1,0,0,128,5,0,0,0,1,255,255,255,12,233,233,233, + 1,119,119,119,1,143,143,143,1,179,179,179,1,212,212,212,1,0,0,0, + 1,0,0,128,5,0,0,0,1,247,247,247,1,233,233,233,1,220,220,220, + 10,210,210,210,1,133,133,133,1,0,0,0,4,0,0,128,5,0,0,0, + 1,244,244,244,1,220,220,220,11,210,210,210,1,0,0,0,1,80,79,80, + 1,142,140,142,1,0,0,128,7,0,0,0,4,173,173,173,1,222,223,223, + 1,223,222,223,1,219,219,220,1,223,223,223,3,223,222,223,1,222,223,223, + 1,212,211,212,1,0,0,0,1,137,135,137,1,0,0,128,7,0,0,0, + 3,202,206,207,1,0,0,0,3,226,225,225,1,226,225,226,1,225,226,226, + 1,226,226,225,1,225,225,225,1,225,226,225,1,226,225,225,1,214,213,213, + 1,0,0,0,1,149,147,149,1,0,0,128,6,151,148,151,1,0,0,0, + 1,223,224,224,1,143,149,151,1,129,135,137,1,133,140,142,1,120,128,131, + 1,0,0,0,1,130,130,130,1,228,229,228,1,228,228,228,2,229,228,228, + 1,228,228,228,2,216,216,216,1,0,0,0,1,157,154,157,1,0,0,128, + 6,0,0,0,2,114,120,122,1,95,101,103,1,59,63,64,1,97,102,104, + 1,114,122,124,1,0,0,0,2,231,231,230,1,231,231,231,1,231,231,230, + 1,231,230,231,1,231,231,231,1,230,231,231,1,218,218,218,1,0,0,0, + 1,159,157,159,1,0,0,128,6,0,0,0,1,219,220,221,1,146,153,154, + 1,78,82,83,1,20,22,23,1,115,117,118,1,147,153,155,1,74,80,82, + 1,0,0,0,1,233,233,233,1,234,233,233,1,234,234,233,1,233,234,233, + 1,233,233,234,1,233,233,233,1,220,220,219,1,0,0,0,1,161,159,161, + 1,0,0,128,6,0,0,0,2,115,120,121,1,125,132,134,1,150,153,154, + 1,179,182,183,1,117,123,125,1,0,0,0,2,236,235,235,2,236,236,236, + 1,236,235,235,2,235,236,235,1,222,220,221,1,0,0,0,1,160,157,160, + 1,0,0,128,6,141,138,141,1,0,0,0,1,128,133,135,1,100,105,107, + 1,108,117,120,1,86,93,95,1,90,83,72,1,112,82,53,2,188,175,164, + 1,236,235,235,1,190,178,166,1,112,82,53,3,178,166,154,1,14,10,7, + 1,112,82,53,2,0,0,128,6,0,0,0,3,60,65,66,1,0,0,0, + 1,112,82,53,2,203,194,186,1,112,82,53,1,232,230,228,1,112,82,53, + 2,227,224,221,1,112,82,53,2,15,11,7,1,112,82,53,2,0,0,128, + 7,0,0,0,4,112,82,53,2,225,222,218,1,230,226,224,1,235,231,229, + 1,112,82,53,2,227,222,218,1,112,82,53,2,28,20,13,1,112,82,53, + 2,0,0,128,7,0,0,0,1,251,251,251,1,247,247,247,1,246,246,245, + 1,192,180,168,1,112,82,53,2,187,174,161,1,239,237,235,1,112,82,53, + 2,228,224,220,1,112,82,53,2,15,11,7,1,112,82,53,2,0,0,128, + 4,128,128,0,5,249,248,248,2,246,245,244,1,190,178,164,1,112,82,53, + 2,237,234,231,1,112,82,53,2,231,226,221,1,112,82,53,2,16,12,7, + 1,112,82,53,2,0,0,128,3,128,128,0,2,255,255,255,3,128,128,0, + 2,126,126,126,1,126,125,125,1,125,124,123,1,112,82,53,2,124,120,117, + 1,112,82,53,2,235,231,226,1,112,82,53,2,16,12,7,1,112,82,53, + 2,0,0,128,3,128,128,0,4,255,255,255,1,128,128,0,2,253,253,253, + 1,112,82,53,1,217,210,203,1,112,82,53,2,232,228,224,1,112,82,53, + 5,16,12,7,1,112,82,53,2,0,0,128,3,128,128,0,3,255,255,255, + 1,128,128,0,3,220,219,219,1,177,165,154,1,112,82,53,2,170,156,142, + 1,206,203,199,1,173,160,147,1,112,82,53,3,143,129,115,1,68,63,60, + 1,112,82,53,4,0,0,128,1,128,128,0,2,255,255,255,1,128,128,0, + 4,0,0,0,1,3,2,1,1,7,5,3,1,11,8,5,1,12,9,6, + 1,9,6,4,1,6,4,3,1,9,7,4,1,14,10,6,1,52,38,25, + 1,112,82,53,1,147,141,140,1,0,0,128,5,128,128,0,2,255,255,255, + 3,128,128,0,2,182,179,182,1,180,177,180,1,179,176,178,1,178,174,176, + 1,177,173,175,1,179,175,177,1,179,176,178,1,177,174,176,1,175,171,172, + 1,171,166,167,1,170,165,165,1,0,0,128,7,128,128,0,5,0,0,128, + 18,0,0) + ); + +const + objdata_TZStoredProc: record size: integer; data: array[0..976] of byte end = + (size: 977; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,84,90,83, + 116,111,114,101,100,80,114,111,99,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,160,3,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,108,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,128,52,118,116,118,1,0,0,0,1,118,116,118,1,0,0,128,7,118, + 116,118,1,30,30,30,1,0,0,0,1,30,29,30,1,112,110,112,1,0, + 0,128,8,118,116,118,1,0,0,0,1,120,169,120,1,0,0,0,1,118, + 116,118,1,0,0,128,5,118,116,118,1,18,53,71,1,118,192,230,1,121, + 197,239,1,96,177,226,1,18,49,71,1,103,101,103,1,0,0,128,6,118, + 116,118,1,0,0,0,1,120,169,120,1,58,131,58,1,76,142,76,1,24, + 24,24,1,118,116,118,1,0,0,128,4,30,30,30,1,137,200,232,1,75, + 180,235,1,61,170,234,1,61,167,234,1,51,143,204,1,24,24,24,1,0, + 0,128,6,0,0,0,1,130,170,130,1,58,131,58,1,38,119,38,2,70, + 123,70,1,0,0,0,6,139,205,241,1,61,171,234,1,61,168,234,1,61, + 164,233,1,54,147,213,1,0,0,0,1,0,0,128,6,118,116,118,1,0, + 0,0,1,34,107,34,1,38,119,38,1,30,96,30,1,0,0,0,1,118, + 116,118,1,0,0,128,4,30,29,30,1,118,189,230,1,61,168,234,1,61, + 165,233,1,60,157,228,1,48,128,192,1,22,22,22,1,0,0,128,7,118, + 116,118,1,0,0,0,1,27,86,27,1,0,0,0,1,118,116,118,1,0, + 0,128,5,112,110,112,1,18,50,71,1,50,141,200,1,52,141,205,1,48, + 129,192,1,16,43,66,1,85,84,85,1,0,0,128,8,118,116,118,1,0, + 0,0,1,118,116,118,1,0,0,128,7,103,101,103,1,24,24,24,1,0, + 0,0,1,22,22,22,1,85,84,85,1,0,0,128,10,0,0,0,1,0, + 0,128,23,0,0,0,1,0,0,128,23,0,0,0,1,0,0,128,23,0, + 0,0,1,0,0,128,20,0,0,0,7,0,0,128,17,0,0,0,1,97, + 123,232,1,67,97,228,4,43,31,20,1,112,82,53,2,162,148,138,1,0, + 0,128,1,164,150,141,1,112,82,53,3,162,148,138,1,0,0,128,1,112, + 82,53,2,0,0,128,5,0,0,0,1,67,97,228,1,30,66,223,3,30, + 66,222,1,112,82,53,2,159,148,142,1,112,82,53,1,0,0,128,1,112, + 82,53,2,0,0,128,1,112,82,53,2,0,0,128,1,112,82,53,2,0, + 0,128,5,0,0,0,1,67,97,228,1,30,66,223,3,30,66,222,1,112, + 82,53,2,169,162,161,1,0,0,128,2,112,82,53,2,0,0,128,1,112, + 82,53,2,0,0,128,1,112,82,53,2,0,0,128,4,128,128,0,5,30, + 66,222,2,45,33,21,1,112,82,53,2,159,144,133,1,0,0,128,1,112, + 82,53,2,0,0,128,1,112,82,53,2,0,0,128,1,112,82,53,2,0, + 0,128,3,128,128,0,2,255,255,255,3,128,128,0,2,30,66,222,1,3, + 2,1,1,134,120,108,1,112,82,53,2,0,0,128,1,112,82,53,2,0, + 0,128,1,112,82,53,2,0,0,128,1,112,82,53,2,0,0,128,3,128, + 128,0,4,255,255,255,1,128,128,0,2,0,0,0,1,1,0,0,1,150, + 147,147,1,112,82,53,2,0,0,128,1,112,82,53,2,0,0,128,1,112, + 82,53,2,0,0,128,1,112,82,53,2,0,0,128,3,128,128,0,3,255, + 255,255,1,128,128,0,3,118,116,118,1,112,82,53,1,150,141,136,1,112, + 82,53,2,0,0,128,1,112,82,53,5,0,0,128,1,112,82,53,2,0, + 0,128,3,128,128,0,2,255,255,255,1,128,128,0,4,0,0,128,1,153, + 139,129,1,112,82,53,2,157,141,129,1,0,0,128,1,160,145,134,1,112, + 82,53,3,156,139,127,1,0,0,128,1,112,82,53,4,0,0,128,1,128, + 128,0,2,255,255,255,3,128,128,0,2,0,0,128,9,157,141,129,1,112, + 82,53,1,0,0,128,7,128,128,0,5,0,0,128,18,0,0) + ); + +const + objdata_TZUpdateSql: record size: integer; data: array[0..1459] of byte end = + (size: 1460; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,84,90,85, + 112,100,97,116,101,83,113,108,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,132,5,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,80,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 128,38,64,63,64,1,17,17,17,1,0,0,0,1,17,17,17,1,64,63, + 64,1,0,0,128,17,80,78,80,1,29,52,29,1,90,145,91,1,127,180, + 127,1,123,180,123,1,112,173,112,1,90,147,91,1,19,46,19,1,80,78, + 80,1,0,0,128,14,80,78,80,1,59,100,59,1,144,189,145,1,109,170, + 110,1,79,154,81,1,114,176,114,1,64,149,64,1,91,164,93,1,94,167, + 94,1,66,109,67,1,80,78,80,1,0,0,128,4,0,0,0,9,32,55, + 33,1,149,193,148,1,101,166,101,1,62,145,64,1,113,177,114,1,255,255, + 255,1,65,152,67,2,67,154,69,1,94,169,96,1,19,47,20,1,0,0, + 128,4,0,0,0,1,141,175,79,2,134,168,72,1,118,152,58,1,109,143, + 51,1,102,136,44,1,93,127,37,1,28,39,10,1,99,152,99,1,118,175, + 119,1,62,145,62,1,113,174,113,1,255,255,255,4,117,181,118,1,69,158, + 71,1,58,135,58,1,53,52,53,1,0,0,128,3,0,0,0,1,141,175, + 79,2,134,168,72,1,118,152,58,1,109,143,51,1,102,136,44,1,93,127, + 37,1,7,10,3,1,145,190,145,1,86,159,86,1,64,147,65,1,65,148, + 65,1,116,180,117,1,255,255,255,1,67,154,69,1,94,170,94,1,255,255, + 255,1,69,160,72,2,14,13,14,1,0,0,128,3,0,0,0,1,225,225, + 225,1,188,188,188,6,0,0,0,1,147,193,146,1,69,150,70,1,255,255, + 255,1,66,151,66,1,66,153,68,1,136,192,137,1,68,159,70,2,255,255, + 255,1,71,162,73,1,71,164,73,1,0,0,0,1,0,0,128,3,0,0, + 0,1,255,255,255,1,188,188,188,2,192,192,192,2,197,197,197,1,199,199, + 199,1,16,16,16,1,136,187,137,1,65,150,65,1,255,255,255,1,92,167, + 94,1,68,155,68,1,255,255,255,1,118,185,120,1,70,161,72,1,71,162, + 73,1,71,164,73,2,14,13,14,1,0,0,128,3,0,0,0,1,255,255, + 255,1,188,188,188,1,189,189,189,1,194,194,194,2,199,199,199,1,201,201, + 201,1,61,61,61,1,114,163,115,1,69,154,69,1,116,180,116,1,255,255, + 255,4,119,186,120,1,72,165,72,1,73,166,75,1,63,142,63,1,51,50, + 51,1,0,0,128,3,0,0,0,1,225,225,225,1,188,188,188,6,89,89, + 89,1,30,55,30,1,102,173,102,1,68,155,70,1,69,156,71,1,70,159, + 72,1,255,255,255,1,120,188,121,1,72,167,75,2,74,167,76,1,22,51, + 22,1,111,109,111,1,0,0,128,3,0,0,0,1,255,255,255,1,191,191, + 191,1,193,193,193,1,198,198,198,2,202,202,202,1,205,205,205,1,188,188, + 188,1,84,84,84,1,78,119,78,1,94,171,94,1,69,160,72,1,70,161, + 73,1,97,175,97,1,72,165,74,1,74,167,74,1,75,168,77,1,41,96, + 41,1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,255,255, + 255,1,192,192,192,1,195,195,195,1,199,199,199,2,204,204,204,1,206,206, + 206,1,188,188,188,1,211,211,211,1,85,85,85,1,24,53,25,1,59,138, + 59,1,70,161,73,1,72,165,74,2,63,144,63,1,21,52,21,1,95,95, + 95,1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,225,225, + 225,1,188,188,188,5,188,188,187,1,125,125,125,1,188,188,187,2,133,133, + 133,1,61,61,61,1,16,16,16,1,0,0,0,1,16,16,16,1,61,61, + 61,1,133,133,133,1,188,188,188,1,0,0,0,1,157,154,157,1,0,0, + 128,3,0,0,0,1,255,255,255,1,196,196,196,1,198,198,198,1,203,203, + 203,2,171,160,148,1,112,82,53,2,173,161,150,1,213,212,211,1,174,163, + 151,1,112,82,53,3,182,170,158,1,216,212,209,1,112,82,53,2,14,11, + 7,1,157,154,157,1,0,0,128,3,0,0,0,1,255,255,255,1,198,198, + 198,1,200,200,200,1,205,205,205,1,205,205,204,1,112,82,53,2,165,156, + 148,1,112,82,53,1,209,207,205,1,112,82,53,2,208,205,202,1,112,82, + 53,2,216,212,208,1,112,82,53,2,15,11,7,1,157,154,157,1,0,0, + 128,3,0,0,0,1,225,225,225,1,188,188,188,3,188,188,187,1,112,82, + 53,2,123,119,115,1,180,176,173,1,182,180,177,1,112,82,53,2,178,173, + 169,1,112,82,53,2,169,162,155,1,112,82,53,2,28,20,13,1,155,150, + 152,1,0,0,128,2,128,128,0,5,208,208,207,2,172,160,148,1,112,82, + 53,2,172,159,146,1,213,211,210,1,112,82,53,2,212,208,204,1,112,82, + 53,2,219,215,211,1,112,82,53,2,15,11,7,1,155,150,151,1,0,0, + 128,1,128,128,0,2,255,255,255,3,128,128,0,2,210,210,209,1,212,211, + 211,1,172,159,146,1,112,82,53,2,212,209,207,1,112,82,53,2,214,210, + 206,1,112,82,53,2,220,216,212,1,112,82,53,2,15,11,7,1,155,150, + 151,1,0,0,128,1,128,128,0,4,255,255,255,1,128,128,0,2,0,0, + 0,1,1,1,1,1,5,4,2,1,112,82,53,2,14,10,7,1,112,82, + 53,2,16,12,7,1,112,82,53,2,16,12,7,1,112,82,53,2,15,11, + 7,1,155,150,151,1,0,0,128,1,128,128,0,3,255,255,255,1,128,128, + 0,3,157,154,157,1,112,82,53,1,146,136,132,1,112,82,53,2,151,144, + 143,1,112,82,53,5,151,144,142,1,112,82,53,2,151,144,143,1,161,156, + 157,1,0,0,128,1,128,128,0,2,255,255,255,1,128,128,0,4,0,0, + 128,1,159,145,135,1,112,82,53,2,153,137,126,1,0,0,128,1,155,141, + 130,1,112,82,53,3,152,136,123,1,0,0,128,1,112,82,53,4,0,0, + 128,1,128,128,0,2,255,255,255,3,128,128,0,2,0,0,128,9,157,142, + 130,1,112,82,53,1,0,0,128,7,128,128,0,5,0,0,128,18,0,0) + ); + +initialization + registerobjectdata(@objdata_tmsezreadonlyquery,tbitmapcomp,'tmsezreadonlyquery'); + registerobjectdata(@objdata_tmsezquery,tbitmapcomp,'tmsezquery'); + registerobjectdata(@objdata_tmseztable,tbitmapcomp,'tmseztable'); + registerobjectdata(@objdata_TZConnection,tbitmapcomp,'TZConnection'); + registerobjectdata(@objdata_TZSequence,tbitmapcomp,'TZSequence'); + registerobjectdata(@objdata_TZSqlMetadata,tbitmapcomp,'TZSqlMetadata'); + registerobjectdata(@objdata_TZSqlMonitor,tbitmapcomp,'TZSqlMonitor'); + registerobjectdata(@objdata_TZSqlProcessor,tbitmapcomp,'TZSqlProcessor'); + registerobjectdata(@objdata_TZStoredProc,tbitmapcomp,'TZStoredProc'); + registerobjectdata(@objdata_TZUpdateSql,tbitmapcomp,'TZUpdateSql'); +end. diff --git a/mseide-msegui/lib/common/report/mselatex.pas b/mseide-msegui/lib/common/report/mselatex.pas new file mode 100644 index 0000000..be77e1d --- /dev/null +++ b/mseide-msegui/lib/common/report/mselatex.pas @@ -0,0 +1,174 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mselatex; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msestrings,mserichstring,msetypes; + +function richstringtolatex(const source: richstringty): msestring; + +implementation +uses + msegraphutils,msearrayutils,msegraphics,sysutils,mseformatstr; + +const + escchars = ['#','$','%','&','{','}','_']; + +function richstringtolatex(const source: richstringty): msestring; + +var + d: pmsechar; + + procedure add(const astr: msestring); + var + i1: integer; + begin + i1:= length(astr); + move(pointer(astr)^,d^,i1*sizeof(msechar)); + inc(d,i1); + end; + +const + maxitemlen = 200; //maxlen of escape code + format code +var + s,e,dend: pmsechar; + mch1: msechar; + formatindex: integer; + styles1: fontstylesty; + rgb1: rgbtriplety; + defcolors: rgbtriplearty; + i1,i2: integer; +begin + if source.text = '' then begin + result:= ''; + end + else begin + defcolors:= nil; //compiler warning + setlength(result,2*length(source.text)+maxitemlen); + d:= pointer(result); + dend:= d + length(result) - maxitemlen; + s:= pointer(source.text); + formatindex:= 0; + add('{\noindent\fontseries{l}\fontshape{n}\selectfont{}'); +//prichstringty(@source)^.format:= nil; + repeat + if formatindex > high(source.format) then begin + e:= pmsechar(pointer(source.text)) + length(source.text); + end + else begin + e:= pmsechar(pointer(source.text)) + source.format[formatindex].index; + end; + while s < e do begin + mch1:= s^; + if (ord(mch1) < $80) then begin + if (char(byte(mch1)) in escchars) then begin + d^:= '\'; + inc(d); + d^:= mch1; + inc(d); + end + else begin + case mch1 of + '\': begin + add('\textbackslash{}'); + end; + '^': begin + add('\textasciicircum{}'); + end; + '~': begin + add('\textasciitilde{}'); + end; + ' ': begin + add('\hphantom{n}'); + end; + c_return: begin + inc(d); //ignore + end; + c_linefeed: begin + add('\newline'+c_return); + // d^:= c_return; //paragraph + // inc(d); + end; + else begin + d^:= mch1; + inc(d); + end; + end; + end; + end + else begin + d^:= mch1; + inc(d); + end; + if d >= dend then begin + dend:= pmsechar(result); //backup + setlength(result,length(result)*2); + inc(d,(pmsechar(pointer(result))-dend)); //relocate + dend:= pmsechar(pointer(result)) + length(result) - maxitemlen; + end; + inc(s); + end; + if formatindex <= high(source.format) then begin + with source.format[formatindex] do begin + styles1:= fontstylesty(newinfos) * style.fontstyle; + if ni_fontcolor in newinfos then begin + if style.fontcolor = 0 then begin + add('\color{black}'); + end + else begin + rgb1:= colortorgb(not style.fontcolor); + i2:= -1; + for i1:= 0 to high(defcolors) do begin + if colorty(defcolors[i1]) = colorty(rgb1) then begin + i2:= i1; + break; + end; + end; + if i2 < 0 then begin + additem(longwordarty(defcolors),colorty(rgb1)); + i2:= high(defcolors); + add('\definecolor{c'+inttostrmse(i2)+'}{RGB}{'+ + inttostrmse(rgb1.red)+','+ + inttostrmse(rgb1.green)+','+ + inttostrmse(rgb1.blue)+'}'); + end; + add('\color{c'+inttostrmse(i2)+'}'); + end; + end; + if fs_bold in styles1 then begin + add('\fontseries{b}'); + end + else begin + if ni_bold in newinfos then begin + add('\fontseries{l}'); + end; + end; + if fs_italic in styles1 then begin + add('\fontshape{it}'); + end + else begin + if ni_italic in newinfos then begin + add('\fontshape{n}'); + end; + end; + if newinfos*[ni_bold,ni_italic] <> [] then begin + add('\selectfont{}'); + end; + end; + end; + inc(formatindex); + until formatindex > length(source.format); + add('}'); + setlength(result,d-pmsechar(pointer(result))); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/report/msereport.pas b/mseide-msegui/lib/common/report/msereport.pas new file mode 100644 index 0000000..f56960a --- /dev/null +++ b/mseide-msegui/lib/common/report/msereport.pas @@ -0,0 +1,8733 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msereport; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseapplication,msegui,msegraphics,msetypes,msewidgets, + msegraphutils,mseclasses,mseinterfaces,mseificomp, + msetabs,mseprinter,msestream,msearrayprops,mseguiglob,msesimplewidgets, + msedrawtext,msestrings,mserichstring,msedb,mdb,msethread,mseobjectpicker, + msepointer,mseevent,msesplitter,msestatfile,mselookupbuffer,mseformatstr, + msegdiprint,msemenus,mseglob; + +const + defaultrepppmm = 3; + defaultreppagewidth = 190; + defaultreppageheight = 270; + defaultrepfontheight = 14; + defaultrepfontname = 'stf_report'; + tabpickthreshold = 3; + endrendertag = 49125363; + + defaultreptabtextflags = [tf_ycentered]; + defaultbandanchors = [an_top]; + defaultbandoptionswidget = defaultoptionswidget; + {(defaultoptionswidget + [ow_fontlineheight]) - + [ow_fontglyphheight];} + + defaultrepvaluedisptextflags = [tf_ycentered]; + defaultrepvaluedispoptionsscale = + [osc_expandx,osc_shrinkx,osc_expandy,osc_shrinky]; + defaultrepfontcolor = cl_black; + +type + lookupkindty = (lk_text,lk_integer,lk_int64,lk_float,lk_date,lk_time,lk_datetime); + linevisiblety = (lv_topofpage,lv_nottopofpage, + lv_firstofpage,lv_normal,lv_lastofpage, + lv_firstofgroup,lv_lastofgroup, + lv_firstrecord,lv_lastrecord); + linevisiblesty = set of linevisiblety; + + tablineinfoty = record + widthmm: real; + color: colorty; + colorgap: colorty; + capstyle: capstylety; + dashes: string; + dist: integer; + visible: linevisiblesty; + end; + tablinekindty = (tlk_top,tlk_vert,tlk_bottom); + tablineinfoarty = array[tablinekindty] of tablineinfoty; +const + defaulttablinewidth = 0; + defaulttablinecolor = cl_black; + defaulttablinecolorgap = cl_transparent; + defaulttablinecapstyle = cs_projecting; + defaulttablinedashes = ''; + defaulttablinedist = 0; + defaulttablinevisible = [lv_topofpage,lv_nottopofpage, + lv_firstofpage,lv_normal,lv_lastofpage, + lv_firstofgroup,lv_lastofgroup, + lv_firstrecord,lv_lastrecord]; + defaulttablineinfo: tablineinfoty = (widthmm: defaulttablinewidth; + color: defaulttablinecolor; colorgap: defaulttablinecolorgap; + capstyle: defaulttablinecapstyle; + dashes: defaulttablinedashes; dist: defaulttablinedist; + visible: defaulttablinevisible); +type + bandoptionshowty = ( + //show only on first/last record of group + bos_showfirstpage,bos_hidefirstpage, + bos_shownormalpage,bos_hidenormalpage, + //checks current treportpage + bos_showevenpage,bos_hideevenpage, + bos_showoddpage,bos_hideoddpage, + //checks the printed page number + bos_showtopofpage,bos_hidetopofpage, + bos_shownottopofpage,bos_hidenottopofpage, + bos_showfirstofpage,bos_hidefirstofpage, + bos_shownormalofpage,bos_hidenormalofpage, + bos_showlastofpage,bos_hidelastofpage, + //checks the position in the bandarea + bos_showfirstrecord,bos_hidefirstrecord, + bos_shownormalrecord,bos_hidenormalrecord, + bos_showlastrecord,bos_hidelastrecord + //checks the connected dataset + ); + bandoptionshowsty = set of bandoptionshowty; + + bandoptionty = (bo_once,bo_evenpage,bo_oddpage, + //defines hasdata, page nums are null based + bo_visigroupfirst,bo_visigroupnotfirst, + bo_visigrouplast,bo_visigroupnotlast, + bo_delayednextrecord, + bo_localvalue, + //used in treppagenumdisp to show the number of the current + //treportpage instead the number of the printed pages + //and in trepprinttimedisp to show now instead of + //print start time + bo_topofarea //sets areafull if not first of page before render + ); + bandoptionsty = set of bandoptionty; + +const + visibilitymask = [bos_showfirstpage,bos_hidefirstpage, + bos_shownormalpage,bos_hidenormalpage, + bos_showevenpage,bos_hideevenpage, + bos_showoddpage,bos_hideoddpage, + bos_showtopofpage,bos_hidetopofpage, + bos_shownottopofpage,bos_hidenottopofpage, + bos_showfirstofpage,bos_hidefirstofpage, + bos_shownormalofpage,bos_hidenormalofpage, + bos_showlastofpage,bos_hidelastofpage, + bos_showfirstrecord,bos_hidefirstrecord, + bos_shownormalrecord,bos_hidenormalrecord, + bos_showlastrecord,bos_hidelastrecord + ]; + defaultrepvaluedispoptions = [bo_evenpage,bo_oddpage]; + +type + reportoptionty = (reo_autorelease,reo_prepass,reo_nodisablecontrols, + reo_nothread,reo_waitdialog, + reo_autoreadstat,reo_autowritestat,reo_delayedreadstat); + reportoptionsty = set of reportoptionty; + +const + defaultreportoptions = []; + +type + tbasebandarea = class; + tcustomrecordband = class; + tcustomreportpage = class; + rendereventty = procedure(const sender: tobject; + const acanvas: tcanvas) of object; + beforerenderrecordeventty = procedure(const sender: tcustomrecordband; + var empty: boolean) of object; + synceventty = procedure() of object; + + treptabfont = class(tparentfont) + protected + procedure setname(const avalue: string); override; + public + constructor create; override; + class function getinstancepo(owner: tobject): pfont; override; + published + property color default defaultrepfontcolor; + end; + + trepwidgetfont = class(twidgetfont) + protected + procedure setname(const avalue: string); override; + public + constructor create; override; + published + property color default defaultrepfontcolor; + end; + + trepfont = class(tfont) + protected + procedure setname(const avalue: string); override; + public + constructor create; override; + published + property color default defaultrepfontcolor; + end; + + treptabulatoritem = class; + + treptabitemdatalink = class(tfielddatalink) + private + fowner: treptabulatoritem; + protected + procedure recordchanged(afield: tfield); override; + public + constructor create(const aowner: treptabulatoritem); + end; + + getrichstringeventty = procedure(const sender: tobject; + var avalue: richstringty) of object; + reptabulatoritemoptionty = (rto_disabled,rto_count,rto_sum,rto_average, + rto_shownull, + rto_nocurrentvalue,rto_noreset); + reptabulatoritemoptionsty = set of reptabulatoritemoptionty; + + itemsumty = record + count: integer; + resetpending: boolean; + reset: boolean; + case tfieldtype of + ftinteger,ftword,ftsmallint,ftboolean: (integervalue: integer); + ftlargeint: (largeintvalue: int64); + ftfloat: (floatvalue: double); + ftbcd: (bcdvalue: currency); + end; + + treptabulatoritem = class(ttabulatoritem,idbeditinfo) + private + fvalue: richstringty; + ffont: treptabfont; + ftextflags: textflagsty; + fdatalink: treptabitemdatalink; + fongetvalue: getrichstringeventty; + flineinfos: tablineinfoarty; + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: integer; + flookupvaluefieldno: integer; + flookupkind: lookupkindty; + fformat: msestring; + fcolor: colorty; + ftag: integer; + foptions: reptabulatoritemoptionsty; + fsum: itemsumty; + fifilink: tifilinkcomp; + procedure setvalue(const avalue: msestring); + procedure setrichvalue(const avalue: richstringty); + function getdisptext: richstringty; + function getfont: treptabfont; + procedure setfont(const avalue: treptabfont); + function isfontstored: boolean; + procedure createfont; + procedure changed; + procedure fontchanged(const asender: tobject); + procedure settextflags(const avalue: textflagsty); + function getdatasource1: tdatasource; + procedure setdatasource(const avalue: tdatasource); + function getdatafield: string; + procedure setdatafield(const avalue: string); + + procedure setlitop_widthmm(const avalue: real); + procedure setlitop_color(const avalue: colorty); + procedure setlitop_colorgap(const avalue: colorty); + procedure setlitop_capstyle(const avalue: capstylety); + procedure setlitop_dashes(const avalue: string); + procedure setlitop_dist(const avalue: integer); + procedure setlitop_visible(const avalue: linevisiblesty); + + procedure setlivert_widthmm(const avalue: real); + procedure setlivert_color(const avalue: colorty); + procedure setlivert_colorgap(const avalue: colorty); + procedure setlivert_capstyle(const avalue: capstylety); + procedure setlivert_dashes(const avalue: string); + procedure setlivert_dist(const avalue: integer); + procedure setlivert_visible(const avalue: linevisiblesty); + + procedure setlibottom_widthmm(const avalue: real); + procedure setlibottom_color(const avalue: colorty); + procedure setlibottom_colorgap(const avalue: colorty); + procedure setlibottom_capstyle(const avalue: capstylety); + procedure setlibottom_dashes(const avalue: string); + procedure setlibottom_dist(const avalue: integer); + procedure setlibottom_visible(const avalue: linevisiblesty); + procedure recchanged; + + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + procedure setlookupkeyfieldno(const avalue: integer); + procedure setlookupvaluefieldno(const avalue: integer); + procedure setlookupkind(const avalue: lookupkindty); + procedure setformat(const avalue: msestring); + procedure setcolor(avalue: colorty); + + function getsumasinteger: integer; + function getsumaslargeint: int64; + function getsumasfloat: double; + function getsumascurrency: currency; + procedure initsum; + procedure setoptions(const avalue: reptabulatoritemoptionsty); + function getsumcount: integer; + procedure setenabled(const avalue: boolean); + procedure setifilink(const avalue: tifilinkcomp); + protected + function getenabled: boolean override; + procedure setpos(const avalue: real); override; + function xlineoffset: integer; + procedure dobeforenextrecord(const adatasource: tdatasource); + procedure scale(const ascale: real); + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure resetsum(const skipcurrent: boolean); + + procedure setintvalue(const avalue: int32); + procedure setint64value(const avalue: int64); + procedure setfloatvalue(const avalue: flo64); + procedure setdatetimevalue(const avalue: tdatetime); + procedure setcurrencyvalue(const avalue: currency); + + property sumcount: integer read getsumcount; + property sumasinteger: integer read getsumasinteger; + property sumaslargeint: int64 read getsumaslargeint; + property sumasfloat: double read getsumasfloat; + property sumascurrency: currency read getsumascurrency; + property richvalue: richstringty read fvalue write setrichvalue; + property enabled: boolean read getenabled write setenabled; + published + property tag: integer read ftag write ftag default 0; + property options: reptabulatoritemoptionsty read foptions + write setoptions default []; + property value: msestring read fvalue.text write setvalue; + property font: treptabfont read getfont write setfont stored isfontstored; + property color: colorty read fcolor write setcolor default cl_none; + property textflags: textflagsty read ftextflags write settextflags + default defaultreptabtextflags; + property ifilink: tifilinkcomp read fifilink write setifilink; + property datafield: string read getdatafield write setdatafield; + property datasource: tdatasource read getdatasource1 write setdatasource; + property lookupbuffer: tcustomlookupbuffer read flookupbuffer + write setlookupbuffer; + property lookupkeyfieldno: integer read flookupkeyfieldno + write setlookupkeyfieldno default 0; + property lookupvaluefieldno: integer read flookupvaluefieldno + write setlookupvaluefieldno default 0; + property lookupkind: lookupkindty read flookupkind + write setlookupkind default lk_text; + property format: msestring read fformat write setformat; + + property litop_widthmm: real read flineinfos[tlk_top].widthmm write + setlitop_widthmm; + property litop_color: colorty read flineinfos[tlk_top].color write + setlitop_color default defaulttablinecolor; + property litop_colorgap: colorty read flineinfos[tlk_top].colorgap write + setlitop_colorgap default defaulttablinecolorgap; + property litop_capstyle: capstylety read flineinfos[tlk_top].capstyle write + setlitop_capstyle default defaulttablinecapstyle; + property litop_dashes: string read flineinfos[tlk_top].dashes write + setlitop_dashes; + property litop_dist: integer read flineinfos[tlk_top].dist write + setlitop_dist default defaulttablinedist; + property litop_visible: linevisiblesty read flineinfos[tlk_top].visible write + setlitop_visible default defaulttablinevisible; + + property livert_widthmm: real read flineinfos[tlk_vert].widthmm write + setlivert_widthmm; + property livert_color: colorty read flineinfos[tlk_vert].color write + setlivert_color default defaulttablinecolor; + property livert_colorgap: colorty read flineinfos[tlk_vert].colorgap write + setlivert_colorgap default defaulttablinecolorgap; + property livert_capstyle: capstylety read flineinfos[tlk_vert].capstyle write + setlivert_capstyle default defaulttablinecapstyle; + property livert_dashes: string read flineinfos[tlk_vert].dashes write + setlivert_dashes; + property livert_dist: integer read flineinfos[tlk_vert].dist write + setlivert_dist default defaulttablinedist; + property livert_visible: linevisiblesty read flineinfos[tlk_vert].visible write + setlivert_visible default defaulttablinevisible; + + property libottom_widthmm: real read flineinfos[tlk_bottom].widthmm write + setlibottom_widthmm; + property libottom_color: colorty read flineinfos[tlk_bottom].color write + setlibottom_color default defaulttablinecolor; + property libottom_colorgap: colorty read flineinfos[tlk_bottom].colorgap write + setlibottom_colorgap default defaulttablinecolorgap; + property libottom_capstyle: capstylety read flineinfos[tlk_bottom].capstyle write + setlibottom_capstyle default defaulttablinecapstyle; + property libottom_dashes: string read flineinfos[tlk_bottom].dashes write + setlibottom_dashes; + property libottom_dist: integer read flineinfos[tlk_bottom].dist write + setlibottom_dist default defaulttablinedist; + property libottom_visible: linevisiblesty read flineinfos[tlk_bottom].visible write + setlibottom_visible default defaulttablinevisible; + + property ongetvalue: getrichstringeventty read fongetvalue write fongetvalue; + property distleft; //mm + property distright; //mm + end; + + treptabulators = class(tcustomtabulators) + private + finfo: drawtextinfoty; + fminsize: sizety; + fsizevalid: boolean; + flineinfos: tablineinfoarty; + flileft: tablineinfoty; + fliright: tablineinfoty; + fdistright: real; + fdistleft: real; + + flinksource: tcustomrecordband; + procedure setlitop_widthmm(const avalue: real); + procedure setlitop_color(const avalue: colorty); + procedure setlitop_colorgap(const avalue: colorty); + procedure setlitop_capstyle(const avalue: capstylety); + procedure setlitop_dashes(const avalue: string); + procedure setlitop_dist(const avalue: integer); + procedure setlitop_visible(const avalue: linevisiblesty); + + procedure setlileft_widthmm(const avalue: real); + procedure setlileft_color(const avalue: colorty); + procedure setlileft_colorgap(const avalue: colorty); + procedure setlileft_capstyle(const avalue: capstylety); + procedure setlileft_dashes(const avalue: string); + procedure setlileft_dist(const avalue: integer); + procedure setlileft_visible(const avalue: linevisiblesty); + + procedure setlivert_widthmm(const avalue: real); + procedure setlivert_color(const avalue: colorty); + procedure setlivert_colorgap(const avalue: colorty); + procedure setlivert_capstyle(const avalue: capstylety); + procedure setlivert_dashes(const avalue: string); + procedure setlivert_dist(const avalue: integer); + procedure setlivert_visible(const avalue: linevisiblesty); + + procedure setliright_widthmm(const avalue: real); + procedure setliright_color(const avalue: colorty); + procedure setliright_colorgap(const avalue: colorty); + procedure setliright_capstyle(const avalue: capstylety); + procedure setliright_dashes(const avalue: string); + procedure setliright_dist(const avalue: integer); + procedure setliright_visible(const avalue: linevisiblesty); + + procedure setlibottom_widthmm(const avalue: real); + procedure setlibottom_color(const avalue: colorty); + procedure setlibottom_colorgap(const avalue: colorty); + procedure setlibottom_capstyle(const avalue: capstylety); + procedure setlibottom_dashes(const avalue: string); + procedure setlibottom_dist(const avalue: integer); + procedure setlibottom_visible(const avalue: linevisiblesty); + + function getitems(const index: integer): treptabulatoritem; + procedure setitems(const index: integer; const avalue: treptabulatoritem); + procedure processvalues(const acanvas: tcanvas; const adest: rectty; + const apaint: boolean); + procedure setdistleft(const avalue: real); + procedure setdistright(const avalue: real); + procedure setlinksource(const avalue: tcustomrecordband); + protected + fband: tcustomrecordband; + class function getitemclass: tabulatoritemclassty; override; + procedure paint(const acanvas: tcanvas; const adest: rectty); + procedure checksize; + procedure recchanged; + procedure sourcechanged; + procedure dochange(const aindex: integer); override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure dobeforenextrecord(const adatasource: tdatasource); + procedure initsums; + procedure scale(const ascale: real); + public + constructor create(const aowner: tcustomrecordband); + procedure resetsums(const skipcurrent: boolean); + property items[const index: integer]: treptabulatoritem read getitems + write setitems; default; + published + + property litop_widthmm: real read flineinfos[tlk_top].widthmm write + setlitop_widthmm; + property litop_color: colorty read flineinfos[tlk_top].color write + setlitop_color default defaulttablinecolor; + property litop_colorgap: colorty read flineinfos[tlk_top].colorgap write + setlitop_colorgap default defaulttablinecolorgap; + property litop_capstyle: capstylety read flineinfos[tlk_top].capstyle write + setlitop_capstyle default defaulttablinecapstyle; + property litop_dashes: string read flineinfos[tlk_top].dashes write + setlitop_dashes; + property litop_dist: integer read flineinfos[tlk_top].dist write + setlitop_dist default defaulttablinedist; + property litop_visible: linevisiblesty read flineinfos[tlk_top].visible write + setlitop_visible default defaulttablinevisible; + + property lileft_widthmm: real read flileft.widthmm write + setlileft_widthmm; + property lileft_color: colorty read flileft.color write + setlileft_color default defaulttablinecolor; + property lileft_colorgap: colorty read flileft.colorgap write + setlileft_colorgap default defaulttablinecolorgap; + property lileft_capstyle: capstylety read flileft.capstyle write + setlileft_capstyle default defaulttablinecapstyle; + property lileft_dashes: string read flileft.dashes write + setlileft_dashes; + property lileft_dist: integer read flileft.dist write + setlileft_dist default defaulttablinedist; + property lileft_visible: linevisiblesty read flileft.visible write + setlileft_visible default defaulttablinevisible; + + property livert_widthmm: real read flineinfos[tlk_vert].widthmm write + setlivert_widthmm; + property livert_color: colorty read flineinfos[tlk_vert].color write + setlivert_color default defaulttablinecolor; + property livert_colorgap: colorty read flineinfos[tlk_vert].colorgap write + setlivert_colorgap default defaulttablinecolorgap; + property livert_capstyle: capstylety read flineinfos[tlk_vert].capstyle write + setlivert_capstyle default defaulttablinecapstyle; + property livert_dashes: string read flineinfos[tlk_vert].dashes write + setlivert_dashes; + property livert_dist: integer read flineinfos[tlk_vert].dist write + setlivert_dist default defaulttablinedist; + property livert_visible: linevisiblesty read flineinfos[tlk_vert].visible write + setlivert_visible default defaulttablinevisible; + + property liright_widthmm: real read fliright.widthmm write + setliright_widthmm; + property liright_color: colorty read fliright.color write + setliright_color default defaulttablinecolor; + property liright_colorgap: colorty read fliright.colorgap write + setliright_colorgap default defaulttablinecolorgap; + property liright_capstyle: capstylety read fliright.capstyle write + setliright_capstyle default defaulttablinecapstyle; + property liright_dashes: string read fliright.dashes write + setliright_dashes; + property liright_dist: integer read fliright.dist write + setliright_dist default defaulttablinedist; + property liright_visible: linevisiblesty read fliright.visible write + setliright_visible default defaulttablinevisible; + + property libottom_widthmm: real read flineinfos[tlk_bottom].widthmm write + setlibottom_widthmm; + property libottom_color: colorty read flineinfos[tlk_bottom].color write + setlibottom_color default defaulttablinecolor; + property libottom_colorgap: colorty read flineinfos[tlk_bottom].colorgap write + setlibottom_colorgap default defaulttablinecolorgap; + property libottom_capstyle: capstylety read flineinfos[tlk_bottom].capstyle + write setlibottom_capstyle default defaulttablinecapstyle; + property libottom_dashes: string read flineinfos[tlk_bottom].dashes write + setlibottom_dashes; + property libottom_dist: integer read flineinfos[tlk_bottom].dist write + setlibottom_dist default defaulttablinedist; + property libottom_visible: linevisiblesty read flineinfos[tlk_bottom].visible + write setlibottom_visible default defaulttablinevisible; + property distleft: real read fdistleft write setdistleft; //mm + property distright: real read fdistright write setdistright; //mm + property linksource: tcustomrecordband read flinksource write setlinksource; + property defaultdist; + end; + + recordbandstatety = (rbs_prepass,rbs_rendering,rbs_showed,rbs_pageshowed, + rbs_finish, + rbs_notfirstrecord,rbs_lastrecord,rbs_visibilitychecked, + rbs_nextrecordpending); + recordbandstatesty = set of recordbandstatety; + + ireportclient = interface(inullinterface) + function getwidget: twidget; + procedure updatevisibility; + procedure beginrender(const arestart: boolean); + procedure endrender; + procedure adddatasets(var adatasets: datasetarty); + procedure init; + procedure resetzebra; + procedure setppmm(const avalue: real); + end; + ireportclientarty = array of ireportclient; + + ibandparent = interface(inullinterface)[miid_ibandparent] + procedure registerclient(const aclient: ireportclient); + procedure unregisterclient(const aclient: ireportclient); + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; + //true if area full + procedure endband(const acanvas: tcanvas; const sender: tcustomrecordband); + function istopband: boolean; + function isfirstband: boolean; + function islastband(const addheight: integer = 0): boolean; + function isfirstrecord: boolean; + function islastrecord: boolean; +// function isfirstofgroup: boolean; +// function islastofgroup: boolean; + procedure updatevisible; + function getwidget: twidget; + function remainingheight: integer; + procedure setareafull(const avalue: boolean); + function pagepagenum: integer; //null based + function reppagenum: integer; //null based + function getlastpagepagecount: integer; + function getlastreppagecount: integer; + function pageprintstarttime: tdatetime; + function repprintstarttime: tdatetime; + function getreppage: tcustomreportpage; + procedure resetzebra; + function getppmm: real; + end; + + trecordbanddatalink = class(tmsedatalink) + end; + + trepspacer = class(tlayouter,ireportclient) + private + foptionsrep: bandoptionshowsty; + fparentintf: ibandparent; + procedure setoptionsrep(const avalue: bandoptionshowsty); + protected + procedure parentchanged; override; //update fparentintf + procedure updatevisibility; + procedure beginrender(const arestart: boolean); + procedure endrender; + procedure adddatasets(var adatasets: datasetarty); + procedure init; + procedure resetzebra; + procedure setppmm(const avalue: real); + published + property optionsrep: bandoptionshowsty read foptionsrep + write setoptionsrep default []; + end; + + bandareaarty = array of tbasebandarea; + + recordbandarty = array of tcustomrecordband; + recordbandeventty = procedure(const sender: tcustomrecordband) of object; + + zebraoptionty = (zo_resetonpagestart,zo_resetparent); + zebraoptionsty = set of zebraoptionty; + + trepwidgetframe = class(tcaptionframe) + public + constructor create(const aintf: icaptionframe); + published + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + end; + + tcustomrecordband = class(tcustomscalingwidget,idbeditinfo,ireccontrol, + iobjectpicker,ireportclient,icaptionframe) + private + frecbands: recordbandarty; + fparentintf: ibandparent; + fonbeforerender: beforerenderrecordeventty; + fonafterrender: recordbandeventty; + fonpaint: painteventty; + fonafterpaint: painteventty; + ftextframe: int32; + ftabs: treptabulators; + fupdating: integer; + fdatalink: trecordbanddatalink; + fvisidatalink: tfielddatalink; + fvisigrouplink: tfielddatalink; + foptions: bandoptionsty; + foptionsshow: bandoptionshowsty; + fgroupnum: int64; + fgroupstring: msestring; + fnextgroupnum: integer; + fnextgroupstring: msestring; + fobjectpicker: tobjectpicker; + fnextband: tcustomrecordband; + fnextbandiflastofarea: tcustomrecordband; + fnextbandifempty: tcustomrecordband; + fnextbandiflast: tcustomrecordband; + fareas: bandareaarty; +// fonbeforepaint: painteventty; + fonbeforenextrecord: notifyeventty; + fonafternextrecord: notifyeventty; + fzebra_color: colorty; + fzebra_start: integer; + fzebra_height: integer; + fzebra_step: integer; + fzebra_counter: integer; + fzebra_options: zebraoptionsty; + procedure settextframe(const avalue: int32); + procedure settabs(const avalue: treptabulators); + procedure setoptionsshow(const avalue: bandoptionshowsty); + function getvisidatasource: tdatasource; + procedure setvisidatasource(const avalue: tdatasource); + function getvisidatafield: string; + procedure setvisidatafield(const avalue: string); + function getdatasource: tdatasource; overload; + procedure setdatasource(const avalue: tdatasource); virtual; + function getvisigroupfield: string; + procedure setvisigroupfield(const avalue: string); + //idbeditinfo + function getdataset(const aindex: integer): tdataset; overload; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + //ireccontrol + procedure recchanged; + procedure setnextband(const avalue: tcustomrecordband); + procedure setnextbandiflastofarea(const avalue: tcustomrecordband); + procedure setnextbandifempty(const avalue: tcustomrecordband); + procedure setnextbandiflast(const avalue: tcustomrecordband); + protected + fstate: recordbandstatesty; + procedure setfont(const avalue: trepwidgetfont); + function getfont: trepwidgetfont; + function getfontclass: widgetfontclassty; override; + + procedure internalcreateframe() override; + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure minclientsizechanged; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure fontchanged; override; + procedure clientrectchanged() override; + procedure inheritedpaint(const acanvas: tcanvas); + procedure parentchanged; override; //update fparentintf + function getminbandsize: sizety; virtual; + function calcminscrollsize: sizety; override; + function textarea(): rectty; + procedure render(const acanvas: tcanvas; var empty: boolean); virtual; + procedure init; virtual; + procedure initpage; virtual; + procedure beginrender(const arestart: boolean); virtual; + procedure endrender; virtual; + procedure adddatasets(var adatasets: datasetarty); virtual; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure doonpaint(const acanvas: tcanvas); override; + procedure doafterpaint(const acanvas: tcanvas); override; + procedure dobeforenextrecord(const adatasource: tdatasource); virtual; + procedure dosyncnextrecord; virtual; + + procedure nextrecord(const setflag: boolean = true); + function rendering: boolean; + function bandheight: integer; + procedure dobeforerender(var empty: boolean); virtual; + function bandisvisible(const checklast: boolean): boolean; + function getvisibility: boolean; + procedure updatevisibility; virtual; + function lastbandheight: integer; virtual; + procedure loaded; override; + + procedure setppmm(const avalue: real); + procedure clientmouseevent(var info: mouseeventinfoty); override; + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var ashape: cursorshapety): boolean; + //true if found + procedure getpickobjects(const sender: tobjectpicker; + var aobjects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const acanvas: tcanvas); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure paint(const canvas: tcanvas); override; + function actualcolor: colorty; override; + procedure scale(const ascale: real); override; + procedure synctofontheight; override; + procedure beginupdate; + procedure endupdate; + function remainingbands: integer; + function reppage: tcustomreportpage; + procedure finish; + function isfirstrecord: boolean; + function islastrecord: boolean; + function isfirstofgroup: boolean; + function islastofgroup: boolean; + procedure restart; + procedure resetzebra; virtual; + + property textframe: int32 read ftextframe write settextframe default 1; + property tabs: treptabulators read ftabs write settabs; + property font: trepwidgetfont read getfont write setfont stored isfontstored; + property datasource: tdatasource read getdatasource write setdatasource; + property visidatasource: tdatasource read getvisidatasource + write setvisidatasource; + property visidatafield: string read getvisidatafield write setvisidatafield; + //controls visibility not null -> visible + property visigroupfield: string read getvisigroupfield write setvisigroupfield; + property options: bandoptionsty read foptions write foptions default []; + property optionsshow: bandoptionshowsty read foptionsshow write setoptionsshow default []; + property nextband: tcustomrecordband read fnextband write setnextband; + //used by tcustombandarea + property nextbandiflastofarea: tcustomrecordband read fnextbandiflastofarea + write setnextbandiflastofarea; + //used by tcustombandarea + property nextbandifempty: tcustomrecordband read fnextbandifempty + write setnextbandifempty; + //used by tcustombandarea + property nextbandiflast: tcustomrecordband read fnextbandiflast + write setnextbandiflast; + //used by tcustombandarea + property zebra_counter: integer read fzebra_counter write fzebra_counter; + property zebra_color: colorty read fzebra_color write fzebra_color default cl_infobackground; + property zebra_start: integer read fzebra_start write fzebra_start default 0; + property zebra_height: integer read fzebra_height write fzebra_height default 0; + property zebra_step: integer read fzebra_step write fzebra_step default 2; + property zebra_options: zebraoptionsty read fzebra_options + write fzebra_options default []; + + property onbeforerender: beforerenderrecordeventty read fonbeforerender + write fonbeforerender; +// property onbeforepaint: painteventty read fonbeforepaint write fonbeforepaint; + property onpaint: painteventty read fonpaint write fonpaint; + property onafterpaint: painteventty read fonafterpaint write fonafterpaint; + property onafterrender: recordbandeventty read fonafterrender + write fonafterrender; + property onbeforenextrecord: notifyeventty read fonbeforenextrecord + write fonbeforenextrecord; + property onafternextrecord: notifyeventty read fonafternextrecord + write fonafternextrecord; + published + property anchors default defaultbandanchors; + property optionswidget default defaultbandoptionswidget; + end; + + trecordband = class(tcustomrecordband) + published + property font; +// property fontempty; + property textframe; + property tabs; + property datasource; + property options; + property optionsshow; + property optionsscale; + property visidatasource; + property visidatafield; + property visigroupfield; + property nextband; + property nextbandiflastofarea; + property nextbandifempty; + property nextbandiflast; + + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property zebra_options; + property onfontheightdelta; + property onlayout; + + property onbeforerender; + property onbeforepaint; + property onpaint; + property onafterpaint; + property onafterrender; + property onbeforenextrecord; + property onafternextrecord; + end; + + tcustomrepvaluedisp = class; + getrepvaluetexteventty = procedure(const sender: tcustomrepvaluedisp; + var atext: msestring) of object; + + tcustomrepvaluedisp = class(tcustomrecordband) + private + ftextflags: textflagsty; + fformat: msestring; + fongettext: getrepvaluetexteventty; + procedure setformat(const avalue: msestring); + procedure settextflags(const avalue: textflagsty); + protected + function calcminscrollsize: sizety; override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure dogettext(var atext: msestring); + function getdisptext: msestring; virtual; + procedure render(const acanvas: tcanvas; var empty: boolean); override; + public + constructor create(aowner: tcomponent); override; + property textflags: textflagsty read ftextflags write settextflags default + defaultrepvaluedisptextflags; + property format: msestring read fformat write setformat; + property optionsscale default defaultrepvaluedispoptionsscale; + property ongettext: getrepvaluetexteventty read fongettext write fongettext; + property options default defaultrepvaluedispoptions; + published + property anchors default [an_left,an_top]; + end; + + trepvaluedisp = class(tcustomrepvaluedisp) + private + fvalue: msestring; + procedure setvalue(const avalue: msestring); + protected + function getdisptext: msestring; override; + procedure dobeforerender(var empty: boolean); override; + published + property value: msestring read fvalue write setvalue; + property font; +// property tabs; +// property datasource; + property textflags; + property textframe; + property options; + property optionsshow; + property optionsscale; + property visidatasource; + property visidatafield; + property visigroupfield; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property zebra_options; + property onfontheightdelta; + property onlayout; + + property onbeforerender; + property onbeforepaint; + property onpaint; + property onafterpaint; + property onafterrender; + property ongettext; + end; + + treppagenumdisp = class(trepvaluedisp) + private + foffset: integer; + procedure setoffset(const avalue: integer); + protected + function getdisptext: msestring; override; + procedure initpage; override; + procedure parentchanged; override; + public + constructor create(aowner: tcomponent); override; + published + property offset: integer read foffset write setoffset default 1; + property format; //'1' returns lastpagecount + end; + + trepprintdatedisp = class(trepvaluedisp) + protected + procedure initpage; override; + procedure parentchanged; override; + function getdisptext: msestring; override; + published + property format; + end; + + tcustombandgroup = class(tcustomrecordband,ibandparent) + private + procedure setdatasource(const avalue: tdatasource); override; + //ibandparent; + procedure registerclient(const aclient: ireportclient); + procedure unregisterclient(const aclient: ireportclient); + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; + //true if area full + procedure endband(const acanvas: tcanvas; const sender: tcustomrecordband); + function istopband: boolean; + function isfirstband: boolean; + function islastband(const addheight: integer = 0): boolean; + procedure updatevisible; + function getwidget: twidget; + function remainingheight: integer; + function pagepagenum: integer; //null based + function reppagenum: integer; //null based + function getlastpagepagecount: integer; + function getlastreppagecount: integer; + function pageprintstarttime: tdatetime; + function repprintstarttime: tdatetime; + function getreppage: tcustomreportpage; + protected + procedure dobeforenextrecord(const adatasource: tdatasource); override; + procedure dosyncnextrecord; override; + function getppmm: real; + procedure setparentwidget(const avalue: twidget); override; + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure dobeforerender(var empty: boolean); override; + procedure dopaint(const acanvas: tcanvas); override; +// procedure updatevisibility; override; + function getminbandsize: sizety; override; + procedure initpage; override; + procedure init; override; + procedure beginrender(const arestart: boolean); override; + procedure endrender; override; + procedure adddatasets(var adatasets: datasetarty); override; + function lastbandheight: integer; override; + procedure setareafull(const avalue: boolean); + public + procedure resetzebra; override; + property font: trepwidgetfont read getfont write setfont stored isfontstored; + end; + + tbandgroup = class(tcustombandgroup) + published + property font; +// property fontempty; + property tabs; + property datasource; + property nextband; + property nextbandiflastofarea; + property nextbandifempty; + property nextbandiflast; + property options; + property optionsshow; + property optionsscale; + property visidatasource; + property visidatafield; + property visigroupfield; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property zebra_options; + + property onfontheightdelta; + property onlayout; + + property onbeforerender; + property onpaint; + property onafterpaint; + property onafterrender; + end; + + bandareastatety = (bas_inited,bas_backgroundrendered,bas_areafull, + bas_rendering, + bas_top,bas_notfirstband,bas_lastband,bas_bandstarted, + bas_activebandchanged,bas_finished); + bandareastatesty = set of bandareastatety; + + bandareaeventty = procedure(const sender: tbasebandarea) of object; + bandareapainteventty = procedure(const sender: tbasebandarea; + const acanvas: tcanvas) of object; + + tbasebandarea = class(tpublishedwidget,ibandparent) + private + fareabands: recordbandarty; + fstate: bandareastatesty; + freportpage: tcustomreportpage; + frecordband: tcustomrecordband; + fonbeforerender: bandareaeventty; + fonafterrender: bandareaeventty; + fonpaint: bandareapainteventty; + fonafterpaint: bandareapainteventty; + fonfirstarea: bandareaeventty; + fonlastarea: bandareaeventty; + forigin: pointty; + fsaveindex: integer; + function getareafull: boolean; + procedure setareafull(const avalue: boolean); + protected + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure setparentwidget(const avalue: twidget); override; + procedure renderbackground(const acanvas: tcanvas); + function render(const acanvas: tcanvas): boolean; virtual; + //true if finished + function rendering: boolean; + procedure beginrender(const arestart: boolean); + procedure endrender; + procedure adddatasets(var adatasets: datasetarty); + procedure dofirstarea; virtual; + procedure dobeforerender; virtual; + procedure doonpaint(const acanvas: tcanvas); override; + procedure doafterpaint1(const acanvas: tcanvas); virtual; + procedure init; virtual; + procedure initareapage; virtual; + procedure initband; virtual; + procedure initpage; + procedure dobeforenextrecord(const adatasource: tdatasource); + procedure dosyncnextrecord; + function checkareafull(ay: integer): boolean; + procedure setppmm(const avalue: real); + //ibandparent + function getppmm: real; + procedure registerclient(const aclient: ireportclient); + procedure unregisterclient(const aclient: ireportclient); + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; virtual; + //true if area full + procedure endband(const acanvas: tcanvas; + const sender: tcustomrecordband); virtual; + procedure updatevisible; + function getlastpagepagecount: integer; + function getlastreppagecount: integer; + procedure setfont(const avalue: trepwidgetfont); + function getfont: trepwidgetfont; + function getfontclass: widgetfontclassty; override; + public + procedure paint(const canvas: tcanvas); override; + function isfirstrecord: boolean; + function islastrecord: boolean; + function istopband: boolean; virtual; + function isfirstband: boolean; virtual; + function islastband(const addheight: integer = 0): boolean; virtual; + function remainingheight: integer; virtual; + + function pagepagenum: integer; //null based + function reppagenum: integer; //null based + function pageprintstarttime: tdatetime; + function repprintstarttime: tdatetime; + function getreppage: tcustomreportpage; + + procedure restart; virtual; + procedure resetzebra; + + property font: trepwidgetfont read getfont write setfont stored isfontstored; + property onfirstarea: bandareaeventty read fonfirstarea write fonfirstarea; + property onlastarea: bandareaeventty read fonlastarea write fonlastarea; + property onbeforerender: bandareaeventty read fonbeforerender + write fonbeforerender; + property onafterrender: bandareaeventty read fonafterrender + write fonafterrender; + property onpaint: bandareapainteventty read fonpaint write fonpaint; + property onafterpaint: bandareapainteventty read fonafterpaint write fonafterpaint; + end; + + bandareaoptionty = (bao_nopagerestart); + bandareaoptionsty = set of bandareaoptionty; + + tcustombandarea = class(tbasebandarea) + private + factiveband: integer; + facty: integer; + factybefore: integer; + fbandnum: integer; + function getacty: integer; + protected + foptions: bandareaoptionsty; + procedure init; override; + procedure initband; override; + procedure initareapage; override; + function render(const acanvas: tcanvas): boolean; override; + //true if finished + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; override; + //true if area full + procedure endband(const acanvas: tcanvas; + const sender: tcustomrecordband); override; + public + function isfirstband: boolean; override; + function islastband(const addheight: integer = 0): boolean; override; + function remainingheight: integer; override; + procedure restart; override; + + property acty: integer read getacty; + property areafull: boolean read getareafull write setareafull; + property options: bandareaoptionsty read foptions write foptions default []; + end; + + tbandarea = class(tcustombandarea) + published + property font; +// property fontempty; + property options; + property onfirstarea; + property onlastarea; + property onbeforerender; + property onafterrender; + property onpaint; + property onafterpaint; + end; + + tileareaoptionty = (tao_vertical); + tileareaoptionsty = set of tileareaoptionty; + + tcustomtilearea = class(tbasebandarea) + private + fcolcount: integer; + frowcount: integer; + fcellorigin: pointty; + flihorz: tablineinfoty; + flivert: tablineinfoty; + flileft: tablineinfoty; + flitop: tablineinfoty; + fliright: tablineinfoty; + flibottom: tablineinfoty; + foptions: tileareaoptionsty; + procedure setcolcount(const avalue: integer); + procedure setrowcount(const avalue: integer); + + procedure setlivert_widthmm(const avalue: real); + procedure setlivert_color(const avalue: colorty); + procedure setlivert_colorgap(const avalue: colorty); + procedure setlivert_capstyle(const avalue: capstylety); + procedure setlivert_dashes(const avalue: string); + + procedure setlihorz_widthmm(const avalue: real); + procedure setlihorz_color(const avalue: colorty); + procedure setlihorz_colorgap(const avalue: colorty); + procedure setlihorz_capstyle(const avalue: capstylety); + procedure setlihorz_dashes(const avalue: string); + + procedure setlileft_widthmm(const avalue: real); + procedure setlileft_color(const avalue: colorty); + procedure setlileft_colorgap(const avalue: colorty); + procedure setlileft_capstyle(const avalue: capstylety); + procedure setlileft_dashes(const avalue: string); + procedure setlileft_dist(const avalue: integer); + + procedure setlitop_widthmm(const avalue: real); + procedure setlitop_color(const avalue: colorty); + procedure setlitop_colorgap(const avalue: colorty); + procedure setlitop_capstyle(const avalue: capstylety); + procedure setlitop_dashes(const avalue: string); + procedure setlitop_dist(const avalue: integer); + + procedure setliright_widthmm(const avalue: real); + procedure setliright_color(const avalue: colorty); + procedure setliright_colorgap(const avalue: colorty); + procedure setliright_capstyle(const avalue: capstylety); + procedure setliright_dashes(const avalue: string); + procedure setliright_dist(const avalue: integer); + + procedure setlibottom_widthmm(const avalue: real); + procedure setlibottom_color(const avalue: colorty); + procedure setlibottom_colorgap(const avalue: colorty); + procedure setlibottom_capstyle(const avalue: capstylety); + procedure setlibottom_dashes(const avalue: string); + procedure setlibottom_dist(const avalue: integer); + + protected + procedure drawline(const acanvas: tcanvas; const ainfo: tablineinfoty; + const start,stop: pointty); + procedure drawlines(const acanvas: tcanvas); + procedure dopaintoverlay(const canvas: tcanvas); override; + function render(const acanvas: tcanvas): boolean; override; + //true if finished + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; override; + procedure endband(const acanvas: tcanvas; const sender: tcustomrecordband); override; + public + constructor create(aowner: tcomponent); override; + function cellwidthmm: real; + function cellheightmm: real; + function cellsize: sizety; + function cellrect: rectty; + + property colcount: integer read fcolcount write setcolcount default 2; + property rowcount: integer read frowcount write setrowcount default 2; + + property livert_widthmm: real read flivert.widthmm write + setlivert_widthmm; + property livert_color: colorty read flivert.color write + setlivert_color default defaulttablinecolor; + property livert_colorgap: colorty read flivert.colorgap write + setlivert_colorgap default defaulttablinecolorgap; + property livert_capstyle: capstylety read flivert.capstyle write + setlivert_capstyle default defaulttablinecapstyle; + property livert_dashes: string read flivert.dashes write + setlivert_dashes; + + property lihorz_widthmm: real read flihorz.widthmm write + setlihorz_widthmm; + property lihorz_color: colorty read flihorz.color write + setlihorz_color default defaulttablinecolor; + property lihorz_colorgap: colorty read flihorz.colorgap write + setlihorz_colorgap default defaulttablinecolorgap; + property lihorz_capstyle: capstylety read flihorz.capstyle write + setlihorz_capstyle default defaulttablinecapstyle; + property lihorz_dashes: string read flihorz.dashes write + setlihorz_dashes; + + property lileft_widthmm: real read flileft.widthmm write + setlileft_widthmm; + property lileft_color: colorty read flileft.color write + setlileft_color default defaulttablinecolor; + property lileft_colorgap: colorty read flileft.colorgap write + setlileft_colorgap default defaulttablinecolorgap; + property lileft_capstyle: capstylety read flileft.capstyle write + setlileft_capstyle default defaulttablinecapstyle; + property lileft_dashes: string read flileft.dashes write + setlileft_dashes; + property lileft_dist: integer read flileft.dist write + setlileft_dist default defaulttablinedist; + + property litop_widthmm: real read flitop.widthmm write + setlitop_widthmm; + property litop_color: colorty read flitop.color write + setlitop_color default defaulttablinecolor; + property litop_colorgap: colorty read flitop.colorgap write + setlitop_colorgap default defaulttablinecolorgap; + property litop_capstyle: capstylety read flitop.capstyle write + setlitop_capstyle default defaulttablinecapstyle; + property litop_dashes: string read flitop.dashes write + setlitop_dashes; + property litop_dist: integer read flitop.dist write + setlitop_dist default defaulttablinedist; + + property liright_widthmm: real read fliright.widthmm write + setliright_widthmm; + property liright_color: colorty read fliright.color write + setliright_color default defaulttablinecolor; + property liright_colorgap: colorty read fliright.colorgap write + setliright_colorgap default defaulttablinecolorgap; + property liright_capstyle: capstylety read fliright.capstyle write + setliright_capstyle default defaulttablinecapstyle; + property liright_dashes: string read fliright.dashes write + setliright_dashes; + property liright_dist: integer read fliright.dist write + setliright_dist default defaulttablinedist; + + property libottom_widthmm: real read flibottom.widthmm write + setlibottom_widthmm; + property libottom_color: colorty read flibottom.color write + setlibottom_color default defaulttablinecolor; + property libottom_colorgap: colorty read flibottom.colorgap write + setlibottom_colorgap default defaulttablinecolorgap; + property libottom_capstyle: capstylety read flibottom.capstyle write + setlibottom_capstyle default defaulttablinecapstyle; + property libottom_dashes: string read flibottom.dashes write + setlibottom_dashes; + property libottom_dist: integer read flibottom.dist write + setlibottom_dist default defaulttablinedist; + + property options: tileareaoptionsty read foptions write foptions default []; + end; + + ttilearea = class(tcustomtilearea) + published + property colcount; + property rowcount; + + property livert_widthmm; + property livert_color; + property livert_colorgap; + property livert_capstyle; + property livert_dashes; + + property lihorz_widthmm; + property lihorz_color; + property lihorz_colorgap; + property lihorz_capstyle; + property lihorz_dashes; + + property lileft_widthmm; + property lileft_color; + property lileft_colorgap; + property lileft_capstyle; + property lileft_dashes; + property lileft_dist; + + property litop_widthmm; + property litop_color; + property litop_colorgap; + property litop_capstyle; + property litop_dashes; + property litop_dist; + + property liright_widthmm; + property liright_color; + property liright_colorgap; + property liright_capstyle; + property liright_dashes; + property liright_dist; + + property libottom_widthmm; + property libottom_color; + property libottom_colorgap; + property libottom_capstyle; + property libottom_dashes; + property libottom_dist; + + property options; + + property font; +// property fontempty; + property onfirstarea; + property onlastarea; + property onbeforerender; + property onafterrender; + property onpaint; + property onafterpaint; + end; + + reportpagestatety = (rpps_inited,rpps_sizesetting,rpps_rendering, + rpps_backgroundrendered, + rpps_restart, + rpps_showed,rpps_finish,rpps_notfirstrecord,rpps_lastrecord, + rpps_nextrecordpending); + reportpagestatesty = set of reportpagestatety; + + tcustomreport = class; + + treportpagedatalink = class(tmsedatalink) + end; + + reportpageoptionty = (rpo_once,rpo_firsteven,rpo_firstodd, + rpo_delayednextrecord,rpo_datasourceonly, + rpo_reportpagewidth,rpo_reportpageheight); + reportpageoptionsty = set of reportpageoptionty; + + reportpageeventty = procedure(const sender: tcustomreportpage) of object; + reportpagepainteventty = procedure(const sender: tcustomreportpage; + const acanvas: tcanvas) of object; + beforerenderpageeventty = procedure(const sender: tcustomreportpage; + var empty: boolean) of object; + reppageorientationty = (rpo_default,rpo_portrait,rpo_landscape); + + tcustomreportpage = class(twidget,ibandparent) + private + fbands: recordbandarty; + fclients: ireportclientarty; + fareas: bandareaarty; + fstate: reportpagestatesty; + fonbeforerender: beforerenderpageeventty; + fonafterrender: reportpageeventty; + fonpaint: reportpagepainteventty; + fonafterpaint: reportpagepainteventty; + fpagedim: sizety; + fpagewidth: real; + fpageheight: real; + fppmm: real; + fvisiblepage: boolean; + fpagenum: integer; + fonfirstpage: reportpageeventty; + fonafterlastpage: reportpageeventty; + fnextpage: tcustomreportpage; + fnextpageifempty: tcustomreportpage; + fnextpageiflast: tcustomreportpage; + fsaveindex: integer; + fdatalink: treportpagedatalink; + foptions: reportpageoptionsty; + fprintstarttime: tdatetime; + freccontrols: pointerarty; + fprintorientation: reppageorientationty; + flastpagecount: integer; + fonbeforenextrecord: notifyeventty; + fonafternextrecord: notifyeventty; + procedure setpagewidth(const avalue: real); + procedure setpageheight(const avalue: real); + procedure updatepagesize; + procedure setppmm(const avalue: real); + procedure setnextpage(const avalue: tcustomreportpage); + procedure setnextpageifempty(const avalue: tcustomreportpage); + procedure setnextpageiflast(const avalue: tcustomreportpage); + function getdatasource: tdatasource; + procedure setdatasource(const avalue: tdatasource); + procedure setoptions(const avalue: reportpageoptionsty); + protected + freport: tcustomreport; + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure setparentwidget(const avalue: twidget); override; + procedure sizechanged; override; + + procedure setfont(const avalue: trepwidgetfont); + function getfont: trepwidgetfont; + function getfontclass: widgetfontclassty; override; + + procedure renderbackground(const acanvas: tcanvas); + procedure beginrender(const arestart: boolean); + procedure endrender; + procedure adddatasets(var adatasets: datasetarty); + function rendering: boolean; + procedure beginarea(const acanvas: tcanvas; const sender: tbasebandarea); + procedure dofirstpage; virtual; + procedure dobeforerender(var empty: boolean); virtual; + procedure doonpaint(const acanvas: tcanvas); override; + procedure doafterpaint1(const acanvas: tcanvas); virtual; + procedure doafterlastpage; virtual; + procedure dobeforenextrecord(const adatasource: tdatasource); + procedure dosyncnextrecord; + property ppmm: real read fppmm write setppmm; //pixel per mm + + procedure init; virtual; + procedure nextrecord; + function render(const acanvas: tcanvas): boolean; + //true if empty + + //ibandparent + function getppmm: real; + procedure registerclient(const aclient: ireportclient); + procedure unregisterclient(const aclient: ireportclient); + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; + procedure endband(const acanvas: tcanvas; const sender: tcustomrecordband); + function istopband: boolean; + function isfirstband: boolean; + function islastband(const addheight: integer = 0): boolean; + procedure setareafull(const avalue: boolean); + + procedure updatevisible; + function remainingheight: integer; + function pagepagenum: integer; //null based + function reppagenum: integer; //null based + function pageprintstarttime: tdatetime; + function repprintstarttime: tdatetime; + function getreppage: tcustomreportpage; + function getlastpagepagecount: integer; + function getlastreppagecount: integer; + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + function isfirstrecord: boolean; + function islastrecord: boolean; + procedure insertwidget(const awidget: twidget; const apos: pointty); override; + + procedure recordchanged; + property report: tcustomreport read freport; + property pagenum: integer read fpagenum write fpagenum; + //null-based, local to this page + property lastpagecount: integer read getlastpagepagecount write flastpagecount; + //local to this page + property printstarttime: tdatetime read fprintstarttime write fprintstarttime; + property visiblepage: boolean read fvisiblepage write fvisiblepage default true; + procedure activatepage; + procedure finish; + procedure restart; + procedure resetzebra; + + property pagewidth: real read fpagewidth write setpagewidth; + //mm, 0 -> use report value + property pageheight: real read fpageheight write setpageheight; + //mm, 0 -> use report value + function getpagewidth: real; //actual value + function getpageheight: real; //actual value + + property font: trepwidgetfont read getfont write setfont stored isfontstored; + property nextpage: tcustomreportpage read fnextpage write setnextpage; + property nextpageifempty: tcustomreportpage read fnextpageifempty write + setnextpageifempty; + property nextpageiflast: tcustomreportpage read fnextpageiflast write + setnextpageiflast; + property datasource: tdatasource read getdatasource write setdatasource; + property options: reportpageoptionsty read foptions write setoptions + default []; + property printorientation: reppageorientationty read fprintorientation + write fprintorientation default rpo_default; + //default --> printer.canvas value + + property onfirstpage: reportpageeventty read fonfirstpage + write fonfirstpage; + property onbeforerender: beforerenderpageeventty read fonbeforerender + write fonbeforerender; + property onafterrender: reportpageeventty read fonafterrender + write fonafterrender; + property onpaint: reportpagepainteventty read fonpaint write fonpaint; + property onafterpaint: reportpagepainteventty read fonafterpaint + write fonafterpaint; + property onbeforenextrecord: notifyeventty read fonbeforenextrecord + write fonbeforenextrecord; + property onafternextrecord: notifyeventty read fonafternextrecord + write fonafternextrecord; + property onafterlastpage: reportpageeventty read fonafterlastpage + write fonafterlastpage; + end; + + reportpagearty = array of tcustomreportpage; + + treportpage = class(tcustomreportpage) + published + property pagewidth; + property pageheight; + property color; + property frame; + property face; + property visible; + property font; +// property fontempty; + property nextpage; + property nextpageifempty; + property nextpageiflast; + property visiblepage; + property datasource; + property options; + property printorientation; + + property onfirstpage; + property onbeforerender; + property onafterrender; + property onpaint; + property onafterpaint; + property onbeforenextrecord; + property onafternextrecord; + property onafterlastpage; + end; + + repdesigninfoty = record + widgetrect: rectty; + gridsize: real; + showgrid: boolean; + snaptogrid: boolean; + end; + prepdesigninfoty = ^repdesigninfoty; + + treppageform = class(treportpage) + private + function getgrid_show: boolean; + procedure setgrid_show(const avalue: boolean); + function getgrid_snap: boolean; + procedure setgrid_snap(const avalue: boolean); + function getgrid_size: real; + procedure setgrid_size(avalue: real); + procedure writerepdesigninfo(writer: twriter); + procedure readrepdesigninfo(reader: treader); + protected + frepdesigninfo: repdesigninfoty; + class function hasresource(): boolean override; + class function getmoduleclassname(): string override; + procedure defineproperties(filer: tfiler) override; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); + overload; virtual; + published + property grid_show: boolean read frepdesigninfo.showgrid + write setgrid_show default true; + property grid_snap: boolean read frepdesigninfo.snaptogrid + write setgrid_snap default true; + property grid_size: real read frepdesigninfo.gridsize write setgrid_size; + property ppmm; + property color default cl_transparent; + end; + + reppageformclassty = class of treppageform; + + repstatety = (rs_activepageset,rs_finish,rs_restart,rs_running,rs_endpass, + rs_dummypage); + repstatesty = set of repstatety; + + reporteventty = procedure(const sender: tcustomreport) of object; + preambleeventty = procedure(const sender: tcustomreport; var apreamble: string) of object; + + tcustomreport = class(twidget) + private + fppmm: real; + fonreportstart: reporteventty; + fonbeforerender: reporteventty; + fonafterrender: reporteventty; + fonreportfinished: notifyeventty; + fprinter: tcustomprinter; //preliminary + fstream: ttextstream; + fstreamset: boolean; + fcommand: msestring; + fcanvas: tcanvas; + fpagenum: integer; + fthread: tmsethread; + fcanceled: boolean; + fppmmbefore: real; + fstate: repstatesty; + factivepage: integer; + fprintstarttime: tdatetime; + fonprogress: notifyeventty; + fonrenderfinish: reporteventty; + fnilstream: boolean; + foptions: reportoptionsty; + flastpagecount: integer; +// fonloaded: notifyeventty; + fonpreamble: preambleeventty; + fdialogtext: msestring; + fdialogcaption: msestring; + fdatasets: datasetarty; + fonpagebeforerender: beforerenderpageeventty; + fonpageafterpaint: reportpagepainteventty; + fonpagepaint: reportpagepainteventty; + fpagewidth: real; + fpageheight: real; + procedure setppmm(const avalue: real); + function getreppages(index: integer): tcustomreportpage; + procedure setreppages(index: integer; const avalue: tcustomreportpage); + function getgrid_show: boolean; + procedure setgrid_show(const avalue: boolean); + function getgrid_snap: boolean; + procedure setgrid_snap(const avalue: boolean); + function getgrid_size: real; + procedure setgrid_size(avalue: real); + procedure writerepdesigninfo(writer: twriter); + procedure readrepdesigninfo(reader: treader); + function exec(thread: tmsethread): integer; + function getcanceled: boolean; + procedure setcanceled(const avalue: boolean); + function getrunning: boolean; + procedure setactivepage(const avalue: integer); + procedure doexec(const sender: tobject); + procedure docancel(const sender: tobject); + procedure setpagewidth(const avalue: real); + procedure setpageheight(const avalue: real); + protected + frepdesigninfo: repdesigninfoty; + freppages: reportpagearty; + fdefaultprintorientation: pageorientationty; + class function hasresource: boolean override; + procedure updatepagesize; + procedure dopagebeforerender(const sender: tcustomreportpage; + var empty: boolean); + procedure dopagepaint(const sender: tcustomreportpage; + const acanvas: tcanvas); + procedure dopageafterpaint(const sender: tcustomreportpage; + const acanvas: tcanvas); + + procedure internalrender(const acanvas: tcanvas; const aprinter: tcustomprinter; + const acommand: msestring; const astream: ttextstream; + const anilstream: boolean; const onafterrender: reporteventty); + procedure initpage(const apage: tcustomreportpage); + procedure unregisterchildwidget(const child: twidget); override; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; + procedure defineproperties(filer: tfiler); override; + procedure nextpage(const acanvas: tcanvas); + procedure doprogress; + procedure doasyncevent(var atag: integer); override; + procedure notification(acomponent: tcomponent; + operation: toperation); override; + procedure setfont(const avalue: trepfont); + function getfont: trepfont; + function getfontclass: widgetfontclassty; override; + function getdialogcaption: msestring virtual; + function getdialogtext: msestring virtual; +// procedure doloaded; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure insertwidget(const awidget: twidget; const apos: pointty) override; + function add(const apage: tcustomreportpage; + aindex: int32 = bigint): tcustomreportpage; + //report owns page + procedure delete(const aindex: int32); + procedure clear(); + procedure movepage(const curindex,newindex: int32); + + procedure render(const acanvas: tcanvas; + const onafterrender: reporteventty = nil); overload; + procedure render(const aprinter: tstreamprinter; + const command: msestring = ''; + const onafterrender: reporteventty = nil); overload; + procedure render(const aprinter: tstreamprinter; + const astream: ttextstream; //owns the stream + const onafterrender: reporteventty = nil); overload; + procedure render(const aprinter: tcustomgdiprinter; + const onafterrender: reporteventty = nil); overload; + procedure waitfor; //returns before calling of onafterrender + function prepass: boolean; //true if in prepass render state + procedure restart; + procedure recordchanged; + //calls recordchanged of active page + + property ppmm: real read fppmm write setppmm; //pixel per mm + property pagewidth: real read fpagewidth write setpagewidth; + //mm, default 190 + property pageheight: real read fpageheight write setpageheight; + //mm, default 270 + + function reppagecount: integer; + property reppages[index: integer]: tcustomreportpage read getreppages + write setreppages; default; + property pagenum: integer read fpagenum {write fpagenum}; + //null-based + property lastpagecount: integer read flastpagecount write flastpagecount; + property activepage: integer read factivepage write setactivepage; + procedure finish; + property printstarttime: tdatetime read fprintstarttime + write fprintstarttime; + property nilstream: boolean read fnilstream; + //true if reder called with nil stream + + property font: trepfont read getfont write setfont; + property color default cl_transparent; + property grid_show: boolean read frepdesigninfo.showgrid + write setgrid_show default true; + property grid_snap: boolean read frepdesigninfo.snaptogrid + write setgrid_snap default true; + property grid_size: real read frepdesigninfo.gridsize write setgrid_size; + property canceled: boolean read getcanceled write setcanceled; + property running: boolean read getrunning; + property options: reportoptionsty read foptions write foptions + default defaultreportoptions; + property dialogtext: msestring read fdialogtext write fdialogtext; + property dialogcaption: msestring read fdialogcaption write fdialogcaption; + + property onpreamble: preambleeventty read fonpreamble write fonpreamble; + property onreportstart: reporteventty read fonreportstart + write fonreportstart; + property onbeforerender: reporteventty read fonbeforerender + write fonbeforerender; + property onafterrender: reporteventty read fonafterrender + write fonafterrender; + property onreportfinished: notifyeventty read fonreportfinished + write fonreportfinished; + //executed in main thread context + property onpagebeforerender: beforerenderpageeventty + read fonpagebeforerender write fonpagebeforerender; + property onpagepaint: reportpagepainteventty read fonpagepaint + write fonpagepaint; + property onpageafterpaint: reportpagepainteventty read fonpageafterpaint + write fonpageafterpaint; + property onprogress: notifyeventty read fonprogress write fonprogress; +// property onloaded: notifyeventty read fonloaded write fonloaded; + end; + + treport = class(tcustomreport) + private + fstatfile: tstatfile; + foncreate: notifyeventty; + foncreated: notifyeventty; + fonloaded: notifyeventty; + fondestroy: notifyeventty; + fondestroyed: notifyeventty; + procedure setstatfile(const avalue: tstatfile); + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure doafterload; override; + procedure dooncreate; virtual; + procedure readstate(reader: treader); override; + procedure autoreadstat; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); + overload; virtual; + destructor destroy; override; + procedure beforedestruction; override; + procedure reload; + procedure afterconstruction; override; + published + property statfile: tstatfile read fstatfile write setstatfile; + property color; + property ppmm; + property pagewidth; + property pageheight; + property font; +// property fontempty; + property grid_show; + property grid_snap; + property grid_size; + property options; + property dialogtext; + property dialogcaption; + property onpreamble; + property onreportstart; + property onbeforerender; + property onafterrender; + property onreportfinished; + property onpagebeforerender; + property onpagepaint; + property onpageafterpaint; + property onprogress; + property oncreate: notifyeventty read foncreate write foncreate; + property oncreated: notifyeventty read foncreated write foncreated; + property onloaded: notifyeventty read fonloaded write fonloaded; + property ondestroy: notifyeventty read fondestroy write fondestroy; + property ondestroyed: notifyeventty read fondestroyed write fondestroyed; + end; + + reportclassty = class of treport; + +function createreport(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +procedure initreportcomponent(const amodule: tcomponent; + const acomponent: tcomponent); +function getreportscale(const amodule: tcomponent): real; +function createreppageform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function getreppageformscale(const amodule: tcomponent): real; + +implementation +uses + msearrayutils,sysutils,msestreaming,msebits,msereal,math,msesysintf,msesys, + msedate; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustomframe1 = class(tcustomframe); + twidget1 = class(twidget); + twindow1 = class(twindow); + tmsecomponent1 = class(tmsecomponent); + tdataset1 = class(tdataset); + tcanvas1 = class(tcanvas); + tifilink1 = class(tifilinkcomp); + +function checkdashes(const avalue: string): string; +var + int1: integer; +begin + result:= avalue; + for int1:= 1 to length(avalue) do begin + if avalue[int1] = #0 then begin + setlength(result,int1-1); //remove nulls + break; + end; + end; +end; + +procedure renderingerror; +begin + raise exception.create('Operation not possible while rendering'); +end; +{ +function checkisfirstrecord(const adatalink: tmsedatalink; + out avalue: boolean): boolean; //true if adatalink active +begin + result:= adatalink.active; + if result then begin + avalue:= adatalink.dataset.recno = 1; + end + else begin + avalue:= false; + end; +end; + +function checkislastrecord(const adatalink: tmsedatalink; + out avalue: boolean): boolean; //true if adatalink active +begin + result:= adatalink.active; + if result then begin + avalue:= adatalink.dataset.recno = adatalink.dataset.recordcount; + end + else begin + avalue:= false; + end; +end; +} +function checkislastrecord(const adatalink: tmsedatalink; + const syncproc: synceventty): boolean; +var +// bm: string; + int1: integer; +begin + result:= false; + with adatalink do begin //todo: optimize + if active then begin + if dataset.eof then begin + result:= true; + end + else begin + if (dscontroller <> nil) and not assigned(syncproc) then begin + result:= dscontroller.islastrecord; + end + else begin + int1:= dataset.recno; + tdataset1(dataset).settempstate(dataset.state); //disable controls + try + dataset.next; + result:= dataset.eof; + if assigned(syncproc) and not result then begin + syncproc; + end; + dataset.recno:= int1; + finally + tdataset1(dataset).restorestate(dataset.state); + end; + end; + end; + end; + end; +end; + +function createreport(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= reportclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function getreportscale(const amodule: tcomponent): real; +begin + result:= tcustomreport(amodule).fppmm/defaultppmm; +end; + +procedure initreportcomponent(const amodule: tcomponent; + const acomponent: tcomponent); +begin +// if acomponent is twidget then begin +// twidget(acomponent).scale(getreportscale(amodule)); +// end; +end; + +function createreppageform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= reppageformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function getreppageformscale(const amodule: tcomponent): real; +begin + result:= tcustomreportpage(amodule).fppmm/defaultppmm; +end; + +{ treptabfont } + +class function treptabfont.getinstancepo(owner: tobject): pfont; +begin + result:= @treptabulatoritem(owner).ffont; +end; + +constructor treptabfont.create; +begin + inherited; + finfo.baseinfo.color:= defaultrepfontcolor; + finfo.baseinfo.name:= defaultrepfontname; +end; + +procedure treptabfont.setname(const avalue: string); +begin + if avalue = '' then begin + inherited setname(defaultrepfontname); + end + else begin + inherited; + end; +end; + +{ treptabitemdatalink } + +constructor treptabitemdatalink.create(const aowner: treptabulatoritem); +begin + fowner:= aowner; + inherited create; +end; + +procedure treptabitemdatalink.recordchanged(afield: tfield); +begin + if (afield = nil) or (afield = field) then begin + fowner.changed; + { + with treptabulators(fowner.fowner).fband do begin + invalidate; + end; + } + end; +end; + +{ treptabulatoritem } + +constructor treptabulatoritem.create(aowner: tobject); +var + kind1: tablinekindty; +begin + fcolor:= cl_none; + ftextflags:= defaultreptabtextflags; + fdatalink:= treptabitemdatalink.create(self); + for kind1:= low(tablinekindty) to high(tablinekindty) do begin + flineinfos[kind1]:= defaulttablineinfo; + end; + inherited; + with treptabulators(aowner),fband do begin + self.flineinfos[tlk_vert]:= flineinfos[tlk_vert]; + if not (csloading in componentstate) then begin + self.fdatalink.datasource:= datasource; + self.fdistleft:= distleft; + self.fdistright:= distright; + end; + end; +end; + +destructor treptabulatoritem.destroy; +begin + lookupbuffer:= nil; + ifilink:= nil; + inherited; + ffont.free; + fdatalink.free; +end; + +procedure treptabulatoritem.setvalue(const avalue: msestring); +begin + fvalue.text:= avalue; + fvalue.format:= nil; + changed; +end; + +procedure treptabulatoritem.setrichvalue(const avalue: richstringty); +begin + fvalue:= avalue; + changed; +end; + +function treptabulatoritem.getfont: treptabfont; +begin + getoptionalobject(treptabulators(fowner).fband.componentstate,ffont, + {$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin +{$warnings off} + result:= treptabfont(treptabulators(fowner).fband.getfont); +{$warnings on} + end; +end; + +procedure treptabulatoritem.createfont; +begin + if ffont = nil then begin + ffont:= treptabfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +procedure treptabulatoritem.setfont(const avalue: treptabfont); +begin + if avalue <> ffont then begin + setoptionalobject(treptabulators(fowner).fband.componentstate,avalue, + ffont,{$ifdef fpc}@{$endif}createfont); + changed; + end; +end; + +function treptabulatoritem.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +procedure treptabulatoritem.changed; +begin + with treptabulators(fowner),fband do begin + fsizevalid:= false; + if rendering or ([csdesigning,csdestroying] * componentstate = + [csdesigning]) then begin + minclientsizechanged; +// change(-1); + end; + end; +end; + +procedure treptabulatoritem.setpos(const avalue: real); +begin + inherited; + treptabulators(fowner).fband.sendchangeevent(oe_designchanged); + //syncronize linked tabs +end; + +procedure treptabulatoritem.fontchanged(const asender: tobject); +begin + changed; +end; + +procedure treptabulatoritem.settextflags(const avalue: textflagsty); +begin + if ftextflags <> avalue then begin + ftextflags:= checktextflags(ftextflags,avalue); + changed; + end; +end; + +function treptabulatoritem.getdatasource1: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure treptabulatoritem.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; + changed; +end; + +function treptabulatoritem.getdatafield: string; +begin + result:= fdatalink.fieldname; +end; + +procedure treptabulatoritem.setdatafield(const avalue: string); +begin + fdatalink.fieldname:= avalue; +end; + +function treptabulatoritem.getdataset(const aindex: integer): tdataset; +begin + result:= fdatalink.dataset; +end; + +procedure treptabulatoritem.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + afieldtypes:= nil; +end; + +function treptabulatoritem.getdisptext: richstringty; + + procedure dofloat(const avalue: realty); + begin + case flookupkind of + lk_float: begin + result.text:= realtytostring(avalue,fformat); + end; + lk_time: begin + result.text:= mseformatstr.timetostring(avalue,fformat); + end; + lk_date: begin + result.text:= mseformatstr.datetostring(avalue,fformat); + end; + lk_datetime: begin + result.text:= mseformatstr.datetimetostring(avalue,fformat); + end; + end; + end; + +var + ikey: integer; + i64key: integer; + skey: msestring; + int1: integer; + int641: int64; + cl1: customificlientcontrollerclassty; + +begin + if fdatalink.fieldactive then begin + result.format:= nil; + if flookupbuffer <> nil then begin + try + result.text:= ''; + if fdatalink.islargeint then begin + i64key:= fdatalink.field.aslargeint; + case flookupkind of + lk_text: begin + result.text:= fformat + flookupbuffer.lookuptext(flookupkeyfieldno, + flookupvaluefieldno,i64key); + end; + lk_integer: begin + int1:= flookupbuffer.lookupinteger(flookupkeyfieldno, + flookupvaluefieldno,i64key); + result.text:= realtytostring(int1,fformat); + end; + lk_int64: begin + int641:= flookupbuffer.lookupint64(flookupkeyfieldno, + flookupvaluefieldno,i64key); + result.text:= realtytostring(int641,fformat); + end; + lk_float,lk_time,lk_date,lk_datetime: begin + dofloat(flookupbuffer.lookupfloat(flookupkeyfieldno, + flookupvaluefieldno,i64key)); + end; + end; + end + else begin + if fdatalink.ismsestring then begin + skey:= tmsestringfield(fdatalink.field).asmsestring; + case flookupkind of + lk_text: begin + result.text:= fformat + flookupbuffer.lookuptext(flookupkeyfieldno, + flookupvaluefieldno,skey); + end; + lk_integer: begin + int1:= flookupbuffer.lookupinteger(flookupkeyfieldno, + flookupvaluefieldno,skey); + result.text:= realtytostring(int1,fformat); + end; + lk_int64: begin + int641:= flookupbuffer.lookupint64(flookupkeyfieldno, + flookupvaluefieldno,skey); + result.text:= realtytostring(int641,fformat); + end; + lk_float,lk_time,lk_date,lk_datetime: begin + dofloat(flookupbuffer.lookupfloat(flookupkeyfieldno, + flookupvaluefieldno,skey)); + end; + end; + end + else begin + ikey:= fdatalink.field.asinteger; + case flookupkind of + lk_text: begin + result.text:= fformat + flookupbuffer.lookuptext(flookupkeyfieldno, + flookupvaluefieldno,ikey); + end; + lk_integer: begin + int1:= flookupbuffer.lookupinteger(flookupkeyfieldno, + flookupvaluefieldno,ikey); + result.text:= realtytostring(int1,fformat); + end; + lk_int64: begin + int641:= flookupbuffer.lookupint64(flookupkeyfieldno, + flookupvaluefieldno,ikey); + result.text:= realtytostring(int641,fformat); + end; + lk_float,lk_time,lk_date,lk_datetime: begin + dofloat(flookupbuffer.lookupfloat(flookupkeyfieldno, + flookupvaluefieldno,ikey)); + end; + end; + end; + end; + except + end; + end + else begin + if foptions * [rto_sum,rto_count,rto_average] <> [] then begin + with fdatalink.field do begin + if not (rto_shownull in foptions) and + ((rto_nocurrentvalue in foptions) or fsum.resetpending or + isnull and not (rto_count in foptions)) and + (fsum.count = 0) then begin + result.text:= ''; + end + else begin + if rto_count in foptions then begin + result.text:= realtytostring(sumcount,fformat); + end + else begin + if rto_average in foptions then begin + int1:= sumcount; + if int1 = 0 then begin + result.text:= realtytostring(0,fformat); + end + else begin + case datatype of + ftinteger,ftword,ftsmallint,ftboolean: begin + result.text:= realtytostring(sumasinteger/int1,fformat); + end; + ftlargeint: begin + result.text:= realtytostring(sumaslargeint/int1,fformat); + end; + ftfloat,ftcurrency: begin + result.text:= realtytostring(sumasfloat/int1,fformat); + end; + ftbcd: begin + result.text:= realtytostring(sumascurrency/int1,fformat); + end; + end; + end; + end + else begin + case datatype of + ftinteger,ftword,ftsmallint,ftboolean: begin + result.text:= realtytostring(sumasinteger,fformat); + end; + ftlargeint: begin + result.text:= realtytostring(sumaslargeint,fformat); + end; + ftfloat,ftcurrency: begin + result.text:= realtytostring(sumasfloat,fformat); + end; + ftbcd: begin + result.text:= realtytostring(sumascurrency,fformat); + end; + end; + end; + end; + end; + end; + end + else begin + result.text:= fdatalink.msedisplaytext(fformat); + end; + end; + end + else begin + if rto_count in foptions then begin + if not (rto_shownull in foptions) and + ((rto_nocurrentvalue in foptions) or fsum.resetpending) and + (fsum.count = 0) then begin + result.text:= ''; + end + else begin + result.text:= realtytostring(sumcount,fformat); + end + end + else begin + if fifilink <> nil then begin + cl1:= tifilink1(fifilink).getcontrollerclass(); + if cl1 = tstringclientcontroller then begin + result.text:= tstringclientcontroller(fifilink.c).value; + end + else begin + if cl1 = tintegerclientcontroller then begin + result.text:= realtytostring( + tintegerclientcontroller(fifilink.c).value,fformat); + end + else begin + if cl1 = tint64clientcontroller then begin + result.text:= realtytostring( + tint64clientcontroller(fifilink.c).value,fformat); + end + else begin + if cl1 = trealclientcontroller then begin + result.text:= realtytostring( + trealclientcontroller(fifilink.c).value,fformat); + end + else begin + if cl1 = tdatetimeclientcontroller then begin + result.text:= mseformatstr.datetimetostring( + tdatetimeclientcontroller(fifilink.c).value,fformat); + end; + end; + end; + end; + end; + end + else begin + result:= fvalue; + end; + end; + end; + if treptabulators(fowner).fband.canevent(tmethod(fongetvalue)) then begin + fongetvalue(self,result); + end; +end; + +procedure treptabulatoritem.setlitop_widthmm(const avalue: real); +begin + flineinfos[tlk_top].widthmm:= avalue; + changed; +end; + +procedure treptabulatoritem.setlitop_color(const avalue: colorty); +begin + flineinfos[tlk_top].color:= avalue; + changed; +end; + +procedure treptabulatoritem.setlitop_colorgap(const avalue: colorty); +begin + flineinfos[tlk_top].colorgap:= avalue; + changed; +end; + +procedure treptabulatoritem.setlitop_capstyle(const avalue: capstylety); +begin + flineinfos[tlk_top].capstyle:= avalue; + changed; +end; + +procedure treptabulatoritem.setlitop_dashes(const avalue: string); +begin + flineinfos[tlk_top].dashes:= checkdashes(avalue); + changed; +end; + +procedure treptabulatoritem.setlitop_dist(const avalue: integer); +begin + flineinfos[tlk_top].dist:= avalue; + changed; +end; + +procedure treptabulatoritem.setlitop_visible(const avalue: linevisiblesty); +begin + flineinfos[tlk_top].visible:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_widthmm(const avalue: real); +begin + flineinfos[tlk_vert].widthmm:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_color(const avalue: colorty); +begin + flineinfos[tlk_vert].color:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_colorgap(const avalue: colorty); +begin + flineinfos[tlk_vert].colorgap:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_capstyle(const avalue: capstylety); +begin + flineinfos[tlk_vert].capstyle:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_dashes(const avalue: string); +begin + flineinfos[tlk_vert].dashes:= checkdashes(avalue); + changed; +end; + +procedure treptabulatoritem.setlivert_dist(const avalue: integer); +begin + flineinfos[tlk_vert].dist:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_visible(const avalue: linevisiblesty); +begin + flineinfos[tlk_vert].visible:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_widthmm(const avalue: real); +begin + flineinfos[tlk_bottom].widthmm:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_color(const avalue: colorty); +begin + flineinfos[tlk_bottom].color:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_colorgap(const avalue: colorty); +begin + flineinfos[tlk_bottom].colorgap:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_capstyle(const avalue: capstylety); +begin + flineinfos[tlk_bottom].capstyle:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_dashes(const avalue: string); +begin + flineinfos[tlk_bottom].dashes:= checkdashes(avalue); + changed; +end; + +procedure treptabulatoritem.setlibottom_dist(const avalue: integer); +begin + flineinfos[tlk_bottom].dist:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_visible(const avalue: linevisiblesty); +begin + flineinfos[tlk_bottom].visible:= avalue; + changed; +end; + +function treptabulatoritem.xlineoffset: integer; +begin + with flineinfos[tlk_vert] do begin + if kind = tak_left then begin + result:= -dist; + end + else begin + result:= dist; + end; + end; +end; + +procedure treptabulatoritem.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure treptabulatoritem.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + treptabulators(fowner).fband.setlinkedvar(avalue,tmsecomponent(flookupbuffer)); + changed; +end; + +procedure treptabulatoritem.setifilink(const avalue: tifilinkcomp); +begin + treptabulators(fowner).fband.setlinkedvar(avalue,tmsecomponent(fifilink)); + changed(); +end; + +procedure treptabulatoritem.setlookupkeyfieldno(const avalue: integer); +begin + flookupkeyfieldno:= avalue; + changed; +end; + +procedure treptabulatoritem.setlookupvaluefieldno(const avalue: integer); +begin + flookupvaluefieldno:= avalue; + changed; +end; + +procedure treptabulatoritem.setlookupkind(const avalue: lookupkindty); +begin + flookupkind:= avalue; + changed; +end; + +procedure treptabulatoritem.setformat(const avalue: msestring); +begin + fformat:= avalue; + changed; +end; + +procedure treptabulatoritem.setcolor(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if fcolor <> avalue then begin + fcolor:= avalue; + treptabulators(fowner).fband.invalidate; + end +end; + +procedure treptabulatoritem.resetsum(const skipcurrent: boolean); +begin + fillchar(fsum,sizeof(fsum),0); + fsum.resetpending:= skipcurrent; + fsum.reset:= true; +end; + +procedure treptabulatoritem.setintvalue(const avalue: int32); +begin + value:= formatfloatmse(avalue,format); +end; + +procedure treptabulatoritem.setint64value(const avalue: int64); +begin + value:= formatfloatmse(avalue,format); +end; + +procedure treptabulatoritem.setfloatvalue(const avalue: flo64); +begin + value:= formatfloatmse(avalue,format); +end; + +procedure treptabulatoritem.setdatetimevalue(const avalue: tdatetime); +begin + value:= formatdatetimemse(avalue,format); +end; + +procedure treptabulatoritem.setcurrencyvalue(const avalue: currency); +begin + value:= formatfloatmse(avalue,format); +end; + +procedure treptabulatoritem.initsum; +begin + fillchar(fsum,sizeof(fsum),0); +end; + +procedure treptabulatoritem.dobeforenextrecord(const adatasource: tdatasource); +begin + if (foptions * [rto_count,rto_sum,rto_average] <> []) and + (fdatalink.datasource = adatasource) then begin + if fdatalink.active then begin + if fdatalink.field = nil then begin + inc(fsum.count); + end + else begin + with fdatalink.field,fsum do begin + if not isnull then begin + inc(count); + case datatype of + ftinteger,ftword,ftsmallint,ftboolean: begin + integervalue:= integervalue + asinteger; + end; + ftlargeint: begin + largeintvalue:= largeintvalue + aslargeint; + end; + ftfloat,ftcurrency: begin + floatvalue:= floatvalue + asfloat; + end; + ftbcd: begin + bcdvalue:= bcdvalue + ascurrency; + end; + end; + end; + end; + end; + end; + if fsum.resetpending then begin + initsum; + end; + end; +end; + +function treptabulatoritem.getsumasinteger: integer; +begin + if fsum.resetpending and fsum.reset or not fdatalink.fieldactive then begin + result:= 0; + end + else begin + result:= fsum.integervalue; + if not (rto_nocurrentvalue in foptions) then begin + result:= result + fdatalink.field.asinteger; + end; + end; +end; + +function treptabulatoritem.getsumaslargeint: int64; +begin + if fsum.resetpending and fsum.reset or not fdatalink.fieldactive then begin + result:= 0; + end + else begin + result:= fsum.largeintvalue; + if not (rto_nocurrentvalue in foptions) then begin + result:= result + fdatalink.field.aslargeint; + end; + end; +end; + +function treptabulatoritem.getsumasfloat: double; +begin + if fsum.resetpending and fsum.reset or not fdatalink.fieldactive then begin + result:= 0; + end + else begin + result:= fsum.floatvalue; + if not (rto_nocurrentvalue in foptions) then begin + result:= result + fdatalink.field.asfloat; + end; + end; +end; + +function treptabulatoritem.getsumascurrency: currency; +begin + if fsum.resetpending and fsum.reset or not fdatalink.fieldactive then begin + result:= 0; + end + else begin + result:= fsum.bcdvalue; + if not (rto_nocurrentvalue in foptions) then begin + result:= result + fdatalink.field.ascurrency; + end; + end; +end; + +function treptabulatoritem.getsumcount: integer; +begin + if fsum.resetpending and fsum.reset or not fdatalink.active then begin + result:= 0; + end + else begin + result:= fsum.count; + if not (rto_nocurrentvalue in foptions) then begin + result:= result + 1; + end; + end; +end; + +function treptabulatoritem.getenabled: boolean; +begin + result:= not (rto_disabled in foptions); +end; + +procedure treptabulatoritem.setenabled(const avalue: boolean); +begin + if avalue then begin + options:= options - [rto_disabled]; + end + else begin + options:= options + [rto_disabled]; + end; +end; + +procedure treptabulatoritem.setoptions(const avalue: reptabulatoritemoptionsty); +const + mask: reptabulatoritemoptionsty = [rto_count,rto_sum,rto_average]; +begin + if avalue <> foptions then begin + foptions:= reptabulatoritemoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + changed; + end; +end; + +procedure treptabulatoritem.scale(const ascale: real); +begin + if ffont <> nil then begin + ffont.scale(ascale); + end; +end; + +{ treptabulators } + +constructor treptabulators.create(const aowner: tcustomrecordband); +var + kind1: tablinekindty; +begin + fband:= aowner; + flileft:= defaulttablineinfo; + fliright:= defaulttablineinfo; + for kind1:= low(tablinekindty) to high(tablinekindty) do begin + flineinfos[kind1]:= defaulttablineinfo; + end; + inherited create; +end; + +class function treptabulators.getitemclass: tabulatoritemclassty; +begin + result:= treptabulatoritem; +end; + +function treptabulators.getitems(const index: integer): treptabulatoritem; +begin + result:= treptabulatoritem(inherited items[index]); +end; + +procedure treptabulators.setitems(const index: integer; + const avalue: treptabulatoritem); +begin + inherited items[index]:= avalue; +end; + +procedure treptabulators.processvalues(const acanvas: tcanvas; + const adest: rectty; const apaint: boolean); +var + saved: boolean; + bandcx: integer; + visiblemask: linevisiblesty; + + procedure checkinit(const ainfo: tablineinfoty); + var + rect1: rectty; + reppage1: tcustomreportpage; + begin + if not saved then begin + saved:= true; + acanvas.save; + acanvas.move(makepoint(adest.x,0)); + acanvas.addcliprect(inflaterect(makerect(nullpoint,fband.size),1000)); + //allow line drawing everywhere + if not fband.rendering then begin + reppage1:= fband.reppage; + if reppage1 <> nil then begin + rect1:= reppage1.clippedpaintrect; + translateclientpoint1(rect1.pos,reppage1,fband); + end + else begin + rect1:= fband.paintsizerect; + end; + rect1.x:= rect1.x - adest.x; + acanvas.intersectcliprect(rect1); //limit line drawing area + end; + end; + with ainfo do begin + acanvas.linewidthmm:= widthmm; + acanvas.capstyle:= capstyle; + if (dashes <> '') and (colorgap <> cl_transparent) then begin + acanvas.dashes:= copy(dashes+#0,1,high(dashesstringty)); + acanvas.colorbackground:= colorgap; + end + else begin + acanvas.dashes:= copy(dashes,1,high(dashesstringty)); + end; + end; + end; + + procedure drawhorzline(const aindex: integer; const akind: tablinekindty); + function nextx: integer; + begin + if aindex < high(ftabs) then begin + with ftabs[aindex+1] do begin + result:= linepos + treptabulatoritem(fitems[index]).xlineoffset; + end; + end + else begin + result:= bandcx; + end; + end; + + var + startx,endx,y: integer; + begin + with treptabulatoritem(fitems[ftabs[aindex].index]) do begin + with flineinfos[akind] do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(flineinfos[akind]); + with ftabs[aindex] do begin + case kind of + tak_left: begin + startx:=linepos + xlineoffset; + endx:= nextx; + end; + else begin + if aindex > 0 then begin + with ftabs[aindex-1] do begin + startx:= linepos + treptabulatoritem(fitems[index]).xlineoffset; + end; + end + else begin + startx:= 0; + end; + if kind = tak_centered then begin + endx:= nextx; + end + else begin + endx:= linepos + xlineoffset; + end; + end; + end; + end; + if akind = tlk_top then begin + y:= - flineinfos[tlk_top].dist; + end + else begin + y:= treptabulators(fowner).fband.clientheight + + flineinfos[tlk_bottom].dist; + end; + acanvas.drawline(makepoint(startx,y),makepoint(endx,y),color); + end; + end; + end; + end; + end; + +var + int1,int2,int3,int4: integer; + moved: boolean; + rstr1: richstringty; +// rect1: rectty; + isdecimal: boolean; + cellrect: rectty; + tab1: treptabulatoritem; +begin + fminsize:= nullsize; + bandcx:= adest.cx; + saved:= false; + moved:= false; + visiblemask:= []; + if apaint then begin + with fband do begin + cellrect:= adest; + if not rendering or (fparentintf = nil) then begin + visiblemask:= [lv_topofpage,lv_nottopofpage, + lv_firstofpage,lv_normal,lv_lastofpage, + lv_firstofgroup,lv_lastofgroup, + lv_firstrecord,lv_lastrecord]; + end + else begin + visiblemask:= [lv_normal]; + with fparentintf do begin + if istopband then begin + include(visiblemask,lv_topofpage); + exclude(visiblemask,lv_nottopofpage); + end + else begin + include(visiblemask,lv_nottopofpage); + exclude(visiblemask,lv_topofpage); + end; + if isfirstband then begin + include(visiblemask,lv_firstofpage); + exclude(visiblemask,lv_normal); + end; + if islastband then begin + include(visiblemask,lv_lastofpage); + exclude(visiblemask,lv_normal); + end; + if fband.isfirstofgroup then begin + include(visiblemask,lv_firstofgroup); + end; + if fband.islastofgroup then begin + include(visiblemask,lv_lastofgroup); + end; + end; + if isfirstrecord then begin + include(visiblemask,lv_firstrecord); + exclude(visiblemask,lv_normal); + end; + if islastrecord then begin + include(visiblemask,lv_lastrecord); + exclude(visiblemask,lv_normal); + end; + end; + end; + end; + if count > 0 then begin + checkuptodate; + with finfo do begin + for int1:= 0 to count - 1 do begin + tab1:= treptabulatoritem(fitems[ftabs[int1].index]); + if tab1.enabled then begin + with ftabs[int1],tab1 do begin + text:= getdisptext; + if apaint and (foptions*[rto_count,rto_sum,rto_average] <> []) and + not (rto_noreset in foptions) then begin + fsum.resetpending:= true; + end; + finfo.font:= font; + flags:= ftextflags; + dest:= adest; + if width <= 0 then begin + case kind of + tak_left: begin + dest.cx:= adest.cx - textpos + width; + end; + else begin + dest.cx:= adest.cx + width; + end; + end; + end + else begin + dest.cx:= width; + end; + dest.x:= adest.x + textpos; + if apaint and (fcolor <> cl_none) then begin + cellrect.x:= adest.x + linepos; + if int1 < high(ftabs) then begin + cellrect.cx:= cellwidth; + end + else begin + cellrect.cx:= adest.cx - linepos; + end; + acanvas.fillrect(cellrect,fcolor); + end; + isdecimal:= tabkind = tak_decimal; + case tabkind of + tak_centered: begin + flags:= (flags - [tf_right]) + [tf_xcentered]; + dec(dest.x,dest.cx div 2); + end; + tak_right,tak_decimal: begin + flags:= (flags - [tf_xcentered]) + [tf_right]; + dec(dest.x,dest.cx); + end; + end; + end; + if isdecimal then begin + int2:= findlastchar(text.text,defaultformatsettingsmse.decimalseparator); + if int2 > 0 then begin + rstr1:= text; + text:= richcopy(rstr1,1,int2-1); + if apaint then begin + drawtext(acanvas,finfo); + end + else begin + textrect(acanvas,finfo); + end; + int3:= res.x; + int4:= res.cx; + text:= richcopy(rstr1,int2,bigint); + inc(dest.x,dest.cx); + exclude(flags,tf_right); + if apaint then begin + drawtext(acanvas,finfo); + end + else begin + textrect(acanvas,finfo); + end; + res.x:= int3; + res.cx:= res.cx + int4; + text:= rstr1; + end + else begin + if apaint then begin + drawtext(acanvas,finfo); + end + else begin + textrect(acanvas,finfo); + end; + end; + end + else begin //not decimal + if apaint then begin + drawtext(acanvas,finfo); + end + else begin + textrect(acanvas,finfo); + end; + end; + int2:= res.x + res.cx; + if int2 > fminsize.cx then begin + fminsize.cx:= int2; + end; + if res.cy = 0 then begin + res.cy:= font.lineheight; + end; + int2:= dest.y + res.cy; + if int2 > fminsize.cy then begin + fminsize.cy:= int2; + end; + end; + end; + end; + if apaint then begin + for int1:= 0 to count - 1 do begin + with treptabulatoritem(fitems[ftabs[int1].index]) do begin + if enabled then begin + with flineinfos[tlk_vert] do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(flineinfos[tlk_vert]); + with ftabs[int1] do begin + case kind of + tak_left: begin + int2:= linepos - dist + end + else begin + int2:= linepos + dist; + end; + end; + end; + acanvas.drawline(makepoint(int2,fband.clientheight+libottom_dist), + makepoint(int2,-litop_dist),color); + end; + end; + end; + drawhorzline(int1,tlk_top); + drawhorzline(int1,tlk_bottom); + end; + end; + end; + end; + end; + if apaint then begin + moved:= not saved; + acanvas.remove(makepoint(adest.x,0)); + bandcx:= fband.clientwidth; + with flileft do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(flileft); + acanvas.drawline(makepoint(-dist, + fband.clientheight+flineinfos[tlk_bottom].dist), + makepoint(-dist,-flineinfos[tlk_top].dist),color); + end; + end; + end; + with fliright do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(fliright); + acanvas.drawline(makepoint(bandcx+dist,fband.clientheight+ + flineinfos[tlk_bottom].dist), + makepoint(bandcx+dist,-flineinfos[tlk_top].dist),color); + end; + end; + end; + with flineinfos[tlk_top] do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(flineinfos[tlk_top]); + acanvas.drawline(makepoint(-flileft.dist,-dist), + makepoint(bandcx+fliright.dist,-dist),color); + end; + end; + end; + with flineinfos[tlk_bottom] do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(flineinfos[tlk_bottom]); + int2:= fband.clientheight+dist; + acanvas.drawline(makepoint(-flileft.dist,int2), + makepoint(bandcx+fliright.dist,int2),color); + end; + end; + end; + end; + if saved then begin + acanvas.restore; + end; + if moved then begin + acanvas.move(makepoint(adest.x,0)); + end; + fsizevalid:= true; +end; + +procedure treptabulators.paint(const acanvas: tcanvas; const adest: rectty); +begin + processvalues(acanvas,adest,true); +end; + +procedure treptabulators.checksize; +begin + if not fsizevalid then begin + processvalues(fband.getcanvas,fband.textarea(),false); + end; +end; + +procedure treptabulators.setlitop_widthmm(const avalue: real); +begin + if avalue <> flineinfos[tlk_top].widthmm then begin + flineinfos[tlk_top].widthmm:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_color(const avalue: colorty); +begin + if avalue <> flineinfos[tlk_top].color then begin + flineinfos[tlk_top].color:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_colorgap(const avalue: colorty); +begin + if avalue <> flineinfos[tlk_top].colorgap then begin + flineinfos[tlk_top].colorgap:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_capstyle(const avalue: capstylety); +begin + if avalue <> flineinfos[tlk_top].capstyle then begin + flineinfos[tlk_top].capstyle:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_dashes(const avalue: string); +begin + if avalue <> flineinfos[tlk_top].dashes then begin + flineinfos[tlk_top].dashes:= checkdashes(avalue); + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_dist(const avalue: integer); +begin + if avalue <> flineinfos[tlk_top].dist then begin + flineinfos[tlk_top].dist:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_visible(const avalue: linevisiblesty); +begin + if avalue <> flineinfos[tlk_top].visible then begin + flineinfos[tlk_top].visible:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_widthmm(const avalue: real); +begin + if avalue <> flileft.widthmm then begin + flileft.widthmm:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_color(const avalue: colorty); +begin + if avalue <> flileft.color then begin + flileft.color:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_colorgap(const avalue: colorty); +begin + if avalue <> flileft.colorgap then begin + flileft.colorgap:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_capstyle(const avalue: capstylety); +begin + if avalue <> flileft.capstyle then begin + flileft.capstyle:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_dashes(const avalue: string); +begin + if avalue <> flileft.dashes then begin + flileft.dashes:= checkdashes(avalue); + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_dist(const avalue: integer); +begin + if avalue <> flileft.dist then begin + flileft.dist:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_visible(const avalue: linevisiblesty); +begin + if avalue <> flileft.visible then begin + flileft.visible:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlivert_widthmm(const avalue: real); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].widthmm) then begin + flineinfos[tlk_vert].widthmm:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_widthmm:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setlivert_color(const avalue: colorty); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].color) then begin + flineinfos[tlk_vert].color:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_color:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setlivert_colorgap(const avalue: colorty); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].colorgap) then begin + flineinfos[tlk_vert].colorgap:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_colorgap:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setlivert_capstyle(const avalue: capstylety); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].capstyle) then begin + flineinfos[tlk_vert].capstyle:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_capstyle:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setlivert_dashes(const avalue: string); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].dashes) then begin + flineinfos[tlk_vert].dashes:= checkdashes(avalue); + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_dashes:= checkdashes(avalue); + end; + end; +// end; +end; + +procedure treptabulators.setlivert_dist(const avalue: integer); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].dist) then begin + flineinfos[tlk_vert].dist:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_dist:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setlivert_visible(const avalue: linevisiblesty); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].visible) and +// not (csloading in fband.componentstate) then begin + flineinfos[tlk_vert].visible:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_visible:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setdistleft(const avalue: real); +var + int1: integer; +begin +// if avalue <> fdistleft then begin + fdistleft:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).distleft:= fdistleft; + end; + end; +// end; +end; + +procedure treptabulators.setdistright(const avalue: real); +var + int1: integer; +begin +// if avalue <> fdistright then begin + fdistright:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).distright:= fdistright; + end; + end; +// end; +end; + +procedure treptabulators.setliright_widthmm(const avalue: real); +begin + if avalue <> fliright.widthmm then begin + fliright.widthmm:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_color(const avalue: colorty); +begin + if avalue <> fliright.color then begin + fliright.color:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_colorgap(const avalue: colorty); +begin + if avalue <> fliright.colorgap then begin + fliright.colorgap:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_capstyle(const avalue: capstylety); +begin + if avalue <> fliright.capstyle then begin + fliright.capstyle:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_dashes(const avalue: string); +begin + if avalue <> fliright.dashes then begin + fliright.dashes:= checkdashes(avalue); + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_dist(const avalue: integer); +begin + if avalue <> fliright.dist then begin + fliright.dist:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_visible(const avalue: linevisiblesty); +begin + if avalue <> fliright.visible then begin + fliright.visible:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_widthmm(const avalue: real); +begin + if avalue <> flineinfos[tlk_bottom].widthmm then begin + flineinfos[tlk_bottom].widthmm:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_color(const avalue: colorty); +begin + if avalue <> flineinfos[tlk_bottom].color then begin + flineinfos[tlk_bottom].color:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_colorgap(const avalue: colorty); +begin + if avalue <> flineinfos[tlk_bottom].colorgap then begin + flineinfos[tlk_bottom].colorgap:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_capstyle(const avalue: capstylety); +begin + if avalue <> flineinfos[tlk_bottom].capstyle then begin + flineinfos[tlk_bottom].capstyle:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_dashes(const avalue: string); +begin + if avalue <> flineinfos[tlk_bottom].dashes then begin + flineinfos[tlk_bottom].dashes:= checkdashes(avalue); + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_dist(const avalue: integer); +begin + if avalue <> flineinfos[tlk_bottom].dist then begin + flineinfos[tlk_bottom].dist:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_visible(const avalue: linevisiblesty); +begin + if avalue <> flineinfos[tlk_bottom].visible then begin + flineinfos[tlk_bottom].visible:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.recchanged; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).recchanged; + end; +end; + +procedure treptabulators.setlinksource(const avalue: tcustomrecordband); +var + band1: tcustomrecordband; +begin + if avalue <> flinksource then begin + band1:= avalue; + while band1 <> nil do begin + if band1 = fband then begin + raise exception.create('Recursive linksource.'); + end; + band1:= band1.ftabs.flinksource; + end; + fband.setlinkedvar(avalue,tmsecomponent(flinksource)); + sourcechanged; + end; +end; + +procedure treptabulators.sourcechanged; +var + int1: integer; +begin + if (flinksource <> nil) and + not (csloading in flinksource.componentstate) then begin + beginupdate; + try + count:= flinksource.ftabs.count; + for int1:= 0 to high(fitems) do begin + with treptabulatoritem(fitems[int1]) do begin + pos:= treptabulatoritem(flinksource.ftabs.fitems[int1]).pos; + end; + end; + finally + endupdate; + end; + end; +end; + +procedure treptabulators.dochange(const aindex: integer); +begin + fsizevalid:= false; + inherited; +// fband.sendchangeevent(oe_designchanged); +end; + +procedure treptabulators.setcount1(acount: integer; doinit: boolean); +const + step = 10; +var + countbefore: integer; + int1,int2: integer; +begin + with fband do begin + if (componentstate * [csdesigning,csloading] = [csdesigning]) and + (acount > count) then begin + countbefore:= count; + checkuptodate; + if countbefore > 0 then begin + int2:= self.pos[countbefore-1] + step; + end + else begin + int2:= 0; + end; + inherited; + for int1:= countbefore to count - 1 do begin + items[int1].pos:= int2 / ppmm; + inc(int2,step); //offset + end; + end + else begin + inherited; + end; + end; +end; + +procedure treptabulators.resetsums(const skipcurrent: boolean); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).resetsum(skipcurrent); + end; +end; + +procedure treptabulators.dobeforenextrecord(const adatasource: tdatasource); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).dobeforenextrecord(adatasource); + end; +end; + +procedure treptabulators.initsums; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).initsum; + end; +end; + +procedure treptabulators.scale(const ascale: real); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).scale(ascale); + end; +end; + +procedure setbandoptionsshow(const avalue: bandoptionshowsty; + var foptions: bandoptionshowsty); +const + topmask: bandoptionshowsty = [bos_showtopofpage,bos_hidetopofpage]; + nottopmask: bandoptionshowsty = [bos_shownottopofpage,bos_hidenottopofpage]; + firstmask: bandoptionshowsty = [bos_showfirstpage,bos_hidefirstpage]; + normalmask: bandoptionshowsty = [bos_shownormalpage,bos_hidenormalpage]; + evenmask: bandoptionshowsty = [bos_showevenpage,bos_hideevenpage]; + oddmask: bandoptionshowsty = [bos_showoddpage,bos_hideoddpage]; + firstofpagemask: bandoptionshowsty = [bos_showfirstofpage,bos_hidefirstofpage]; + normalofpagemask: bandoptionshowsty = [bos_shownormalofpage,bos_hidenormalofpage]; + lastofpagemask: bandoptionshowsty = [bos_showlastofpage,bos_hidelastofpage]; + firstrecmask: bandoptionshowsty = [bos_showfirstrecord,bos_hidefirstrecord]; + normalrecmask: bandoptionshowsty = [bos_shownormalrecord,bos_hidenormalrecord]; + lastrecmask: bandoptionshowsty = [bos_showlastrecord,bos_hidelastrecord]; +var + vis1: bandoptionshowsty; +begin + vis1:= bandoptionshowsty(setsinglebit(longword(avalue),longword(foptions), + longword(topmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(avalue),longword(foptions), + longword(nottopmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(avalue),longword(foptions), + longword(firstmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(normalmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(evenmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(oddmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(firstofpagemask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(normalofpagemask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1), + longword(foptions),longword(lastofpagemask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(firstrecmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(normalrecmask))); + foptions:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(lastrecmask))); +end; + +function checkvisibility(const fparentintf: ibandparent; + const foptions: bandoptionshowsty; checklast: boolean; + var aresult: boolean; out show: boolean): boolean; + //true if more checks possible +label + endlab; +var + topofpage,firstofpage,lastofpage: boolean; + even1,first1: boolean; +begin + result:= false; + show:= false; + if foptions * visibilitymask <> [] then begin + if fparentintf <> nil then begin + first1:= fparentintf.pagepagenum = 0; + if first1 and (bos_hidefirstpage in foptions) then begin + aresult:= false; + goto endlab; + end; + if first1 and (bos_showfirstpage in foptions) then begin + aresult:= true; + goto endlab; + end; + if not first1 and (bos_hidenormalpage in foptions) then begin + aresult:= false; + goto endlab; + end; + if not first1 and (bos_shownormalpage in foptions) then begin + aresult:= true; + goto endlab; + end; + + even1:= not odd(fparentintf.reppagenum); + if even1 and (bos_hideevenpage in foptions) then begin + aresult:= false; + goto endlab; + end; + if not even1 and (bos_hideoddpage in foptions) then begin + aresult:= false; + goto endlab; + end; + show:= even1 and (bos_showevenpage in foptions); + show:= show or not even1 and (bos_showoddpage in foptions); + + topofpage:= fparentintf.istopband; + firstofpage:= fparentintf.isfirstband; + lastofpage:= checklast and fparentintf.islastband; + if topofpage then begin + if bos_showtopofpage in foptions then begin + aresult:= true; + goto endlab; + end + else begin + if bos_hidetopofpage in foptions then begin + aresult:= false; + end; + end; + end + else begin + if bos_shownottopofpage in foptions then begin + aresult:= true; + goto endlab; + end + else begin + if bos_hidenottopofpage in foptions then begin + aresult:= false; + end; + end; + end; + if firstofpage then begin + if bos_showfirstofpage in foptions then begin + aresult:= true; + goto endlab; + end + else begin + if bos_hidefirstofpage in foptions then begin + aresult:= false; + end; + end; + end; + if lastofpage then begin + if bos_showlastofpage in foptions then begin + aresult:= true; + goto endlab; + end + else begin + if bos_hidelastofpage in foptions then begin + aresult:= false; + show:= false; + end; + end; + end; + if not firstofpage and not lastofpage then begin + if bos_shownormalofpage in foptions then begin + aresult:= true; + goto endlab; + end + else begin + if bos_hidenormalofpage in foptions then begin + aresult:= false; + show:= false; + end; + end; + end; + end; + end; + result:= true; +endlab: +end; + +procedure updateparentintf(const sender: ireportclient; + var fparentintf: ibandparent); +var + widget1: twidget; +begin + with twidget1(sender.getwidget) do begin + if fparentwidget <> nil then begin + if fparentintf <> nil then begin + fparentintf.unregisterclient(sender); + end; + widget1:= fparentwidget; + while (widget1 <> nil) and + not widget1.getcorbainterface(typeinfo(ibandparent),fparentintf) do begin + widget1:= widget1.parentwidget; + end; + if fparentintf <> nil then begin + fparentintf.registerclient(sender); + sender.setppmm(fparentintf.getppmm); + end; + end + else begin + if fparentintf <> nil then begin + fparentintf.unregisterclient(sender); + end; + fparentintf:= nil; + end; + end; +end; + +{ trepspacer } + +procedure trepspacer.updatevisibility; +var + bo1,bo2: boolean; +begin + bo1:= visible; + checkvisibility(fparentintf,foptionsrep,true,bo1,bo2); + visible:= bo1 or bo2; +end; + +procedure trepspacer.setoptionsrep(const avalue: bandoptionshowsty); +const + spacerbandoptions = [ + bos_showtopofpage,bos_hidetopofpage, + bos_shownottopofpage,bos_hidenottopofpage, + bos_showfirstpage,bos_hidefirstpage, + bos_shownormalpage,bos_hidenormalpage, + bos_showevenpage,bos_hideevenpage, + bos_showoddpage,bos_hideoddpage, + bos_showfirstofpage,bos_hidefirstofpage, + bos_shownormalofpage,bos_hidenormalofpage, + bos_showlastofpage,bos_hidelastofpage + // bo_showfirstrecord,bo_hidefirstrecord, + // bo_shownormalrecord,bo_hidenormalrecord, + // bo_showlastrecord,bo_hidelastrecord, + //todo: check first-last record + // bo_localvalue + ]; + + +begin + setbandoptionsshow(avalue * spacerbandoptions,foptionsrep); +end; + +procedure trepspacer.parentchanged; +begin + updateparentintf(ireportclient(self),fparentintf); + inherited; +end; + +procedure trepspacer.beginrender(const arestart: boolean); +begin + include(fwidgetstate1,ws1_noclipchildren); +end; + +procedure trepspacer.endrender; +begin + exclude(fwidgetstate1,ws1_noclipchildren); +end; + +procedure trepspacer.adddatasets(var adatasets: datasetarty); +begin + //dummy +end; + +procedure trepspacer.init; +begin + //dummy +end; + +procedure trepspacer.resetzebra; +begin + //dummy +end; + +procedure trepspacer.setppmm(const avalue: real); +begin + //dummy +end; + +{ tcustomrecordband } + +constructor tcustomrecordband.create(aowner: tcomponent); +begin + ftextframe:= 1; + ftabs:= treptabulators.create(self); + fdatalink:= trecordbanddatalink.create; + fvisidatalink:= tfielddatalink.create; + fvisigrouplink:= tfielddatalink.create; + fzebra_step:= 2; + fzebra_color:= cl_infobackground; + inherited; + include(fwidgetstate1,ws1_designactive); + fanchors:= defaultbandanchors; + foptionswidget:= defaultbandoptionswidget; +end; + +destructor tcustomrecordband.destroy; +begin + fobjectpicker.free; + ftabs.free; + fdatalink.free; + fvisidatalink.free; + fvisigrouplink.free; + inherited; +end; + +procedure tcustomrecordband.loaded; +begin + inherited; + if (csdesigning in componentstate) and (fobjectpicker = nil) then begin + fobjectpicker:= tobjectpicker.create(iobjectpicker(self)); + end; +end; + +procedure tcustomrecordband.parentchanged; +begin + updateparentintf(ireportclient(self),fparentintf); + inherited; +end; + +procedure tcustomrecordband.dobeforerender(var empty: boolean); +begin + if not (not(rbs_showed in fstate) and (bo_once in foptions)) and + not(bo_once in foptions) and fdatalink.active then begin + empty:= (rbs_finish in fstate) or fdatalink.dataset.eof; + end; + if canevent(tmethod(fonbeforerender)) then begin + application.lock; + try + fonbeforerender(self,empty); + finally + application.unlock; + end; + end; + if not empty and visible and (bo_topofarea in foptions) and + (fparentintf <> nil) and not fparentintf.istopband + {fparentintf.isfirstband} then begin + fparentintf.setareafull(true); + end; +end; + +procedure tcustomrecordband.doonpaint(const acanvas: tcanvas); +begin + if canevent(tmethod(fonpaint)) then begin + application.lock; + try + fonpaint(self,acanvas); + finally + application.unlock; + end; + end; +end; + +function tcustomrecordband.actualcolor: colorty; +var + bo1: boolean; + int1: integer; +begin + bo1:= false; + if (rbs_rendering in fstate) and (fzebra_height > 0) and (fzebra_step > 0) then begin + int1:= (fzebra_counter - fzebra_start) mod fzebra_step; + if int1 < 0 then begin + if int1 < fzebra_height - fzebra_step then begin + bo1:= true; + end; + end + else begin + if int1 < fzebra_height then begin + bo1:= true; + end; + end; + end; + if bo1 then begin + result:= fzebra_color; + end + else begin + result:= inherited actualcolor; + end; +end; + +procedure tcustomrecordband.render(const acanvas: tcanvas; var empty: boolean); +var + widget1: twidget; + int1: integer; +begin + exclude(fstate,rbs_prepass); + widget1:= rootwidget; + if (widget1 is tcustomreport) then begin + with tcustomreport(widget1) do begin + if canceled then begin + abort; + end; + if prepass then begin + include(self.fstate,rbs_prepass); + end; + end; + end; + application.checkoverload; + if rbs_nextrecordpending in fstate then begin + nextrecord; + end; + fparentintf.updatevisible; //?? + include(fstate,rbs_visibilitychecked); + empty:= empty or (rbs_finish in fstate); + dobeforerender(empty); + if not empty then begin + if not (rbs_visibilitychecked in fstate) then begin + fparentintf.updatevisible; + end; + if visible then begin + if fparentintf.beginband(acanvas,self) then begin + exit; //area full + end; + try + for int1:= 0 to high(fareas) do begin + fareas[int1].initband; + end; + inheritedpaint(acanvas); + finally + fparentintf.endband(acanvas,self); + end; + if canevent(tmethod(fonafterrender)) then begin + application.lock; + try + fonafterrender(self); + finally + application.unlock; + end; + end; + end; + if bo_delayednextrecord in foptions then begin + include(fstate,rbs_nextrecordpending); + end + else begin + nextrecord; + end; + end; +end; + +procedure tcustomrecordband.init; +var + int1: integer; +begin + exclude(fstate,rbs_finish); + if fvisigrouplink.fieldactive then begin + if fvisigrouplink.isstringfield then begin + fgroupstring:= fvisigrouplink.asmsestring; + end + else begin + fgroupnum:= fvisigrouplink.aslargeint; + end; +// fnextgroupnum:= fgroupnum; set by beginrender + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].init; + end; +end; + +procedure tcustomrecordband.initpage; +var + int1: integer; +begin + if (zo_resetonpagestart in fzebra_options) then begin + fzebra_counter:= 0; + end; + exclude(fstate,rbs_pageshowed); + for int1:= 0 to high(fareas) do begin + fareas[int1].initpage; + end; +end; + +function tcustomrecordband.rendering: boolean; +begin + result:= rbs_rendering in fstate; +end; + +function tcustomrecordband.bandheight: integer; +begin + result:= bounds_cy; +end; + +procedure tcustomrecordband.inheritedpaint(const acanvas: tcanvas); +begin + inherited paint(acanvas); + inc(fzebra_counter); + if (zo_resetparent in fzebra_options) and (fparentintf <> nil) then begin + fparentintf.resetzebra; + end; +end; + +procedure tcustomrecordband.paint(const canvas: tcanvas); +begin + if not rendering then begin + inherited; + end; +end; + +procedure tcustomrecordband.beginrender(const arestart: boolean); +var + int1: integer; +begin + ftabs.initsums; + fzebra_counter:= 0; + if arestart then begin + fstate:= (fstate * [rbs_pageshowed]) + [rbs_rendering] + end + else begin + fstate:= [rbs_rendering]; + end; + include(fwidgetstate1,ws1_noclipchildren); + if fdatalink.active then begin + application.lock; + try + if not (bo_once in foptions) then begin + fdatalink.dataset.first(); + if checkislastrecord(fdatalink,@dosyncnextrecord) then begin + include(fstate,rbs_lastrecord); + end; + end + else begin + include(fstate,rbs_lastrecord); + end; + recchanged; + finally + application.unlock; + end; + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].beginrender(arestart); + end; +end; + +procedure tcustomrecordband.restart; +begin + beginrender(true); +end; + +procedure tcustomrecordband.resetzebra; +var + int1: integer; +begin + fzebra_counter:= 0; + for int1:= 0 to high(fareas) do begin + fareas[int1].resetzebra; + end; +end; + +procedure tcustomrecordband.endrender; +var + int1: integer; +begin + for int1:= 0 to high(fareas) do begin + fareas[int1].endrender; + end; + exclude(fstate,rbs_rendering); + exclude(fwidgetstate1,ws1_noclipchildren); +end; + +procedure tcustomrecordband.adddatasets(var adatasets: datasetarty); +var + int1: integer; +begin + for int1:= 0 to high(fareas) do begin + fareas[int1].adddatasets(adatasets); + end; + if fdatalink.dataset <> nil then begin + adduniqueitem(pointerarty(adatasets),fdatalink.dataset); + end; +end; + +procedure tcustomrecordband.settextframe(const avalue: int32); +begin + if ftextframe <> avalue then begin + ftextframe:= avalue; + if fframe = nil then begin +// minclientsizechanged(); + clientrectchanged(); + end; + end; +end; + +procedure tcustomrecordband.settabs(const avalue: treptabulators); +begin + ftabs.assign(avalue); +end; + +procedure tcustomrecordband.dobeforenextrecord(const adatasource: tdatasource); +begin + ftabs.dobeforenextrecord(adatasource); + if fvisigrouplink.fieldactive then begin + if fvisigrouplink.isstringfield then begin + fgroupstring:= fvisigrouplink.asmsestring; + end + else begin + fgroupnum:= fvisigrouplink.field.aslargeint; + end; + end; +end; + +procedure tcustomrecordband.dosyncnextrecord; +begin + if fvisigrouplink.fieldactive then begin + if fvisigrouplink.isstringfield then begin + fnextgroupstring:= fvisigrouplink.asmsestring; + end + else begin + fnextgroupnum:= fvisigrouplink.field.aslargeint; + end; + end; +end; + +procedure tcustomrecordband.nextrecord(const setflag: boolean = true); +begin + application.lock; + try + exclude(fstate,rbs_nextrecordpending); + if canevent(tmethod(fonbeforenextrecord)) then begin + fonbeforenextrecord(self); + end; + if setflag then begin + include(fstate,rbs_notfirstrecord); + dobeforenextrecord(fdatalink.datasource); + end; + if fdatalink.active and not (bo_once in foptions) then begin + fdatalink.dataset.next; + if setflag then begin + if checkislastrecord(fdatalink, + {$ifdef FPC}@{$endif}dosyncnextrecord) then begin + include(fstate,rbs_lastrecord); + end; + fparentintf.getreppage.recordchanged; + end; + end; + if canevent(tmethod(fonafternextrecord)) then begin + fonafternextrecord(self); + end; + finally + application.unlock; + end; +end; + +procedure tcustomrecordband.doafterpaint(const acanvas: tcanvas); +var +// ar1: segmentarty; + ar2: tabulatorarty; + int1,int2: integer; + a,b: pointty; + col1: colorty; +begin + inherited; + if (rbs_rendering in fstate) then begin + if canevent(tmethod(fonafterpaint)) then begin + application.lock; + try + fonafterpaint(self,acanvas); + finally + application.unlock; + end; + end; + end; + if csdesigning in componentstate then begin + ar2:= ftabs.tabs; +// setlength(ar1,length(ar2)); + int2:= innerclientwidgetpos.x; + if fframe = nil then begin + int2:= int2 + ftextframe; + end; + for int1:= 0 to high(ar2) do begin +// with ar1[int1] do begin + with ar2[int1] do begin + with treptabulatoritem(ftabs.fitems[index]) do begin + if enabled then begin + col1:= cl_red; + end + else begin + col1:= cl_blue; + end; + if tas_editactive in fstate then begin + acanvas.dashes:= ''; + end + else begin + acanvas.dashes:= #2#2; + end + end; + a.x:= linepos+int2; + end; + a.y:= 0; + b.x:= a.x; + b.y:= fwidgetrect.cy; + acanvas.drawline(a,b,col1); +// end; + end; +// acanvas.drawlinesegments(ar1,cl_red); + acanvas.dashes:= ''; + end; +end; + +procedure tcustomrecordband.dopaintforeground(const acanvas: tcanvas); +begin +{ + if canevent(tmethod(fonbeforepaint)) then begin + fonbeforepaint(self,acanvas); + end; +} + inherited; + ftabs.paint(acanvas,textarea()); +end; + +function tcustomrecordband.getminbandsize: sizety; +begin + ftabs.checksize; + result:= ftabs.fminsize; +end; + +function tcustomrecordband.calcminscrollsize: sizety; +var + size1: sizety; +begin + result:= inherited calcminscrollsize; + size1:= getminbandsize; + if fframe <> nil then begin + with tcustomframe1(fframe) do begin + size1.cx:= size1.cx + fi.innerframe.right; + size1.cy:= size1.cy + fi.innerframe.bottom; + end; + end + else begin + size1.cx:= size1.cx + ftextframe; + size1.cy:= size1.cy + ftextframe; + end; + with size1 do begin + if cx > result.cx then begin + result.cx:= cx; + end; + if cy > result.cy then begin + result.cy:= cy + end; + end; +end; + +function tcustomrecordband.textarea(): rectty; +begin + result:= innerclientrect; + if fframe = nil then begin + inflaterect1(result,-ftextframe); + end; +end; + +procedure tcustomrecordband.minclientsizechanged; +begin + if (fupdating <= 0) and not (csloading in componentstate) then begin + clientrectchanged; + end; +end; + +procedure tcustomrecordband.fontchanged; +begin + ftabs.fsizevalid:= false; + inherited; + minclientsizechanged; +end; + +procedure tcustomrecordband.clientrectchanged(); +begin + ftabs.fsizevalid:= false; + inherited; +end; + +procedure tcustomrecordband.beginupdate; +begin + inc(fupdating); +end; + +procedure tcustomrecordband.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + clientrectchanged; + end; +end; + +procedure tcustomrecordband.setdatasource(const avalue: tdatasource); +var + int1: integer; +begin + fdatalink.datasource:= avalue; + if (componentstate*[csdesigning,csloading] = [csdesigning]) and + (avalue <> nil) then begin + for int1:= 0 to ftabs.count - 1 do begin + ftabs[int1].datasource:= avalue; + end; + end; +end; + +function tcustomrecordband.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tcustomrecordband.setoptionsshow(const avalue: bandoptionshowsty); +begin + setbandoptionsshow(avalue,foptionsshow); +end; + +procedure tcustomrecordband.synctofontheight; +var + i1: int32; +begin +// inherited; + i1:= calcminscrollsize().cy; + if ftabs.count = 0 then begin + i1:= i1 + font.glyphheight; + if fframe <> nil then begin + with tcustomframe1(fframe) do begin + i1:= i1 + fi.innerframe.top; + end; + end + else begin + i1:= i1 + ftextframe; + end; + end; + if fframe <> nil then begin + i1:= i1 + fframe.paintframedim.cy + end; + height:= i1; +// syncsinglelinefontheight(true); +end; + +function tcustomrecordband.isfirstrecord: boolean; +begin + if fdatalink.active then begin + result:= not (rbs_notfirstrecord in fstate); + end + else begin + if fparentintf <> nil then begin + result:= fparentintf.isfirstrecord; + end + else begin + result:= false; + end; + end; +end; + +function tcustomrecordband.islastrecord: boolean; +begin + if fdatalink.active then begin + result:= rbs_lastrecord in fstate; + end + else begin + if fparentintf <> nil then begin + result:= fparentintf.islastrecord; + end + else begin + result:= false; + end; + end; +end; + +function tcustomrecordband.isfirstofgroup: boolean; +begin + if fvisigrouplink.isstringfield then begin + result:= fvisigrouplink.fieldactive and (isfirstrecord or + (fvisigrouplink.asmsestring <> fgroupstring)); + end + else begin + result:= fvisigrouplink.fieldactive and (isfirstrecord or + (fvisigrouplink.field.aslargeint <> fgroupnum)); + end; +end; + +function tcustomrecordband.islastofgroup: boolean; +begin + if fvisigrouplink.isstringfield then begin + result:= fvisigrouplink.fieldactive and (islastrecord or + (fvisigrouplink.asmsestring <> fnextgroupstring)); + end + else begin + result:= fvisigrouplink.fieldactive and (islastrecord or + (fvisigrouplink.field.aslargeint <> fnextgroupnum)); + end; +end; + +function tcustomrecordband.bandisvisible(const checklast: boolean): boolean; +label + endlab; +var + firstrecord,lastrecord: boolean; + bo1: boolean; +begin + result:= visible; + firstrecord:= isfirstrecord; + lastrecord:= islastrecord; + if fvisigrouplink.fieldactive then begin + if fvisigrouplink.isstringfield then begin + if (bo_visigroupfirst in foptions) and (firstrecord or + (fvisigrouplink.asmsestring <> fgroupstring)) or + (bo_visigrouplast in foptions) and (lastrecord or + (fvisigrouplink.asmsestring <> fnextgroupstring)) or + (bo_visigroupnotfirst in foptions) and not (firstrecord or + (fvisigrouplink.asmsestring <> fgroupstring)) or + (bo_visigroupnotlast in foptions) and not(lastrecord or + (fvisigrouplink.asmsestring <> fnextgroupstring)) then begin + result:= true; + end + else begin + result:= false; + end; + end + else begin + if (bo_visigroupfirst in foptions) and (firstrecord or + (fvisigrouplink.field.aslargeint <> fgroupnum)) or + (bo_visigrouplast in foptions) and (lastrecord or + (fvisigrouplink.field.aslargeint <> fnextgroupnum)) or + (bo_visigroupnotfirst in foptions) and not (firstrecord or + (fvisigrouplink.field.aslargeint <> fgroupnum)) or + (bo_visigroupnotlast in foptions) and not(lastrecord or + (fvisigrouplink.field.aslargeint <> fnextgroupnum)) then begin + result:= true; + end + else begin + result:= false; + end; + end; + end; + if fvisidatalink.fieldactive then begin + if fvisidatalink.field.isnull then begin + result:= false; + end + else begin + result:= true; + end; + end; + if checkvisibility(fparentintf,foptionsshow,checklast,result,bo1) then begin + if firstrecord then begin + if bos_showfirstrecord in foptionsshow then begin + result:= true; + goto endlab; + end + else begin + if bos_hidefirstrecord in foptionsshow then begin + result:= false; + bo1:= false; + end; + end; + end; + if lastrecord then begin + if bos_showlastrecord in foptionsshow then begin + result:= true; + goto endlab; + end + else begin + if bos_hidelastrecord in foptionsshow then begin + result:= false; + bo1:= false; + end; + end; + end; + if not firstrecord and not lastrecord then begin + if bos_shownormalrecord in foptionsshow then begin + result:= true; + goto endlab; + end + else begin + if bos_hidenormalrecord in foptionsshow then begin + result:= false; + bo1:= false; + end; + end; + end; + if bo1 then begin + result:= true; + end; + end; + endlab: +end; + +function tcustomrecordband.getvisibility: boolean; +begin + result:= bandisvisible(true); +end; + +procedure tcustomrecordband.updatevisibility; +var + int1: integer; +begin + visible:= getvisibility; + beginscaling; + for int1:= 0 to high(frecbands) do begin + with frecbands[int1] do begin + updatevisibility; + end; + end; + endscaling; +end; + +function tcustomrecordband.lastbandheight: integer; +begin + result:= bounds_cy; +end; + +function tcustomrecordband.remainingbands: integer; +var + widget1,widget2,widget3: twidget; + {int1,}int2: integer; +begin + result:= 0; + if fparentintf <> nil then begin + widget3:= fparentintf.getwidget; + widget1:= self; + repeat + widget2:= widget1; + widget1:= widget1.parentwidget; + until (widget1 = widget3); + if widget2 is tcustomrecordband then begin + with tcustomrecordband(widget2) do begin + int2:= fparentintf.remainingheight - lastbandheight; + if int2 >= 0 then begin + if bounds_cy <= 0 then begin + result:= bigint; + end + else begin + result:= 1 + int2 div bounds_cy; + end; + end; + end; + end; + end; +end; + +function tcustomrecordband.reppage: tcustomreportpage; +begin + if fparentintf <> nil then begin + result:= fparentintf.getreppage; + end + else begin + result:= nil; + end; +end; + +procedure tcustomrecordband.finish; +begin + include(fstate,rbs_finish); +end; + +function tcustomrecordband.getvisidatasource: tdatasource; +begin + result:= fvisidatalink.datasource; +end; + +procedure tcustomrecordband.setvisidatasource(const avalue: tdatasource); +begin + fvisidatalink.datasource:= avalue; + fvisigrouplink.datasource:= avalue; +end; + +function tcustomrecordband.getvisidatafield: string; +begin + result:= fvisidatalink.fieldname; +end; + +procedure tcustomrecordband.setvisidatafield(const avalue: string); +begin + fvisidatalink.fieldname:= avalue; +end; + +function tcustomrecordband.getdataset(const aindex: integer): tdataset; +begin + result:= fvisidatalink.dataset; +end; + +procedure tcustomrecordband.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + setlength(apropertynames,2); + apropertynames[0]:= 'visidatafield'; + apropertynames[1]:= 'visigroupfield'; + setlength(afieldtypes,2); + afieldtypes[0]:= []; + afieldtypes[1]:= [ftinteger,ftlargeint,ftsmallint, + ftword,ftboolean] + textfields; +end; + +function tcustomrecordband.getvisigroupfield: string; +begin + result:= fvisigrouplink.fieldname; +end; + +procedure tcustomrecordband.setvisigroupfield(const avalue: string); +begin + fvisigrouplink.fieldname:= avalue; +end; + +procedure tcustomrecordband.recchanged; +begin + fdatalink.recordchanged(nil); + ftabs.recchanged; +end; + +function tcustomrecordband.getcursorshape(const sender: tobjectpicker; + var ashape: cursorshapety): boolean; +var + ar1: integerarty; +begin + getpickobjects(sender,ar1); + result:= ar1 <> nil; + if result then begin + ashape:= cr_sizehor; + end; +end; + +procedure tcustomrecordband.getpickobjects(const sender: tobjectpicker; + var aobjects: integerarty); +var + int1,int2,int3: integer; + arect: rectty; +begin + arect:= sender.pickrect; + if fframe <> nil then begin + int3:= arect.x - frame.framei_left; + end + else begin + int3:= arect.x - ftextframe; + end; + for int1:= 0 to ftabs.count - 1 do begin + int2:= abs(int3 - ftabs.linepos[int1]); + if int2 < tabpickthreshold then begin + setlength(aobjects,1); + aobjects[0]:= int1; + break; + end; + end; +end; + +procedure tcustomrecordband.beginpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomrecordband.pickthumbtrack(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomrecordband.endpickmove(const sender: tobjectpicker); +begin + ftabs.linepos[sender.currentobjects[0]]:= + ftabs.linepos[sender.currentobjects[0]] + sender.pickoffset.x; +//fitems[ftabs[index].index] + designchanged('tabs',ftabs.ftabs[sender.currentobjects[0]].index); +end; + +procedure tcustomrecordband.paintxorpic(const sender: tobjectpicker; + const acanvas: tcanvas); +var + i1: int32; +begin + i1:= innerclientpos.x; + if fframe = nil then begin + i1:= i1 + ftextframe; + end; + acanvas.fillxorrect(makerect(i1+sender.pickoffset.x + + ftabs.linepos[sender.currentobjects[0]],0,1,clientheight)); +end; + +procedure tcustomrecordband.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) and (fobjectpicker <> nil) then begin + fobjectpicker.mouseevent(info); + end; +end; + +procedure tcustomrecordband.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_designchanged) and (sender = ftabs.flinksource) then begin + ftabs.sourcechanged; +// designchanged; + end; +end; + +procedure tcustomrecordband.setfont(const avalue: trepwidgetfont); +begin + inherited setfont(avalue); +end; + +function tcustomrecordband.getfont: trepwidgetfont; +begin + result:= trepwidgetfont(inherited getfont); +end; + +function tcustomrecordband.getfontclass: widgetfontclassty; +begin + result:= trepwidgetfont; +end; + +procedure tcustomrecordband.internalcreateframe(); +begin + trepwidgetframe.create(icaptionframe(self)); +end; + +procedure tcustomrecordband.setnextband(const avalue: tcustomrecordband); +begin + setlinkedvar(avalue,tmsecomponent(fnextband)); +end; + +procedure tcustomrecordband.setnextbandiflastofarea( + const avalue: tcustomrecordband); +begin + setlinkedvar(avalue,tmsecomponent(fnextbandiflastofarea)); +end; + +procedure tcustomrecordband.setnextbandifempty(const avalue: tcustomrecordband); +begin + setlinkedvar(avalue,tmsecomponent(fnextbandifempty)); +end; + +procedure tcustomrecordband.setnextbandiflast(const avalue: tcustomrecordband); +begin + setlinkedvar(avalue,tmsecomponent(fnextbandiflast)); +end; + +procedure tcustomrecordband.registerchildwidget(const child: twidget); +begin + inherited; + if child is tbasebandarea then begin + additem(pointerarty(fareas),child); + end; + if child is tcustomrecordband then begin + additem(pointerarty(frecbands),child); + end; +end; + +procedure tcustomrecordband.unregisterchildwidget(const child: twidget); +begin + removeitem(pointerarty(fareas),child); + removeitem(pointerarty(frecbands),child); + inherited; +end; + +procedure tcustomrecordband.setppmm(const avalue: real); +var + int1: integer; +begin + ftabs.ppmm:= avalue; + for int1:= 0 to high(fareas) do begin + fareas[int1].setppmm(avalue); + end; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].setppmm(avalue); + end; +end; + +procedure tcustomrecordband.scale(const ascale: real); +begin + inherited; + ftabs.scale(ascale); +end; + +procedure tcustomrecordband.cancelpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +{ tcustombandgroup } + +procedure tcustombandgroup.registerchildwidget(const child: twidget); +begin + if child is tcustomrecordband then begin + inherited; +// additem(pointerarty(fbands),child); + with tcustomrecordband(child) do begin + fparentintf:= ibandparent(self); + include(fwidgetstate1,ws1_nominsize); + end; + end + else begin + raise exception.create('Widget must be tcustomrecordband.'); + end; +end; + +procedure tcustombandgroup.unregisterchildwidget(const child: twidget); +begin +// removeitem(pointerarty(fbands),child); + tcustomrecordband(child).fparentintf:= nil; + inherited; + exclude(tcustomrecordband(child).fwidgetstate1,ws1_nominsize); +end; + +procedure tcustombandgroup.registerclient(const aclient: ireportclient); +begin + //dummy, register children only +end; + +procedure tcustombandgroup.unregisterclient(const aclient: ireportclient); +begin + //dummy, register children only +end; + +procedure tcustombandgroup.dobeforerender(var empty: boolean); +var + int1: integer; + bo1: boolean; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + bo1:= empty; + frecbands[int1].dobeforerender(bo1); + end; +end; + +procedure tcustombandgroup.dopaint(const acanvas: tcanvas); +var + int1,int2,int3: integer; + pt1: pointty; +begin + inherited; + if rendering then begin + pt1:= acanvas.origin; + int2:= pt1.x - paintpos.x; + int3:= pt1.y + innerclientpos.y; + for int1:= 0 to high(frecbands) do begin + with frecbands[int1] do begin + if visible then begin + acanvas.origin:= makepoint(int2 + bounds_x,int3); + inheritedpaint(acanvas); + inc(int3,bounds_cy); +// acanvas.move(makepoint(0,bounds_cy)); + nextrecord; + end; + end; + end; + acanvas.origin:= pt1; + end; +end; + +procedure tcustombandgroup.setdatasource(const avalue: tdatasource); +var + int1,int2: integer; +begin + inherited; + if (componentstate*[csdesigning,csloading] = [csdesigning]) and + (avalue <> nil) then begin + for int1:= 0 to high(frecbands) do begin + with frecbands[int1] do begin + if datasource = nil then begin + for int2:= 0 to ftabs.count - 1 do begin + ftabs[int2].datasource:= avalue; + end; + end; + end; + end; + end; +end; + +procedure tcustombandgroup.setparentwidget(const avalue: twidget); +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].fparentintf:= fparentintf; + end; +end; +{ +procedure tcustombandgroup.updatevisibility; +var + int1: integer; +begin + inherited; + beginscaling; + for int1:= 0 to high(fbands) do begin + with fbands[int1] do begin + updatevisibility; + end; + end; + endscaling; +end; +} +function tcustombandgroup.getminbandsize: sizety; +var + int1,int2,int3: integer; +begin + result:= inherited getminbandsize; + int2:= 0; + for int1:= 0 to high(frecbands) do begin + with frecbands[int1] do begin + if visible then begin + int3:= bounds_x + bounds_cx; + if int3 > result.cx then begin + result.cx:= int3; + end; + inc(int2,bounds_cy); + end; + end; + end; + if int2 > result.cy then begin + result.cy:= int2; + end; +end; + +function tcustombandgroup.lastbandheight: integer; +var + int1,int2: integer; +begin + result:= inherited lastbandheight; + if osc_expandy in optionsscale then begin + int2:= innerclientframewidth.cy; + for int1:= 0 to high(frecbands) do begin + with frecbands[int1] do begin + if bandisvisible(false) and not (bos_hidelastofpage in foptionsshow) or + (bos_showlastofpage in foptionsshow) then begin + int2:= int2 + bounds_cy; + end; + end; + end; + if int2 > result then begin + result:= int2; + end; + end; +end; + +procedure tcustombandgroup.setareafull(const avalue: boolean); +begin + if fparentintf <> nil then begin + fparentintf.setareafull(avalue); + end; +end; + +procedure tcustombandgroup.init; +var + int1: integer; +begin + sortwidgetsyorder(widgetarty(frecbands)); + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].init; + end; +end; + +procedure tcustombandgroup.beginrender(const arestart: boolean); +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].beginrender(arestart); + end; +end; + +procedure tcustombandgroup.resetzebra; +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].resetzebra; + end; +end; + +procedure tcustombandgroup.endrender; +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].endrender; + end; +end; + +procedure tcustombandgroup.adddatasets(var adatasets: datasetarty); +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].adddatasets(adatasets); + end; +end; + +function tcustombandgroup.beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; +begin + result:= fparentintf.beginband(acanvas,sender); +end; + +procedure tcustombandgroup.endband(const acanvas: tcanvas; + const sender: tcustomrecordband); +begin + fparentintf.endband(acanvas,sender); +end; + +function tcustombandgroup.istopband: boolean; +begin + result:= fparentintf.istopband; +end; + +function tcustombandgroup.isfirstband: boolean; +begin + result:= fparentintf.isfirstband; +end; + +function tcustombandgroup.islastband(const addheight: integer = 0): boolean; +begin + result:= fparentintf.islastband; +end; + +procedure tcustombandgroup.updatevisible; +begin + fparentintf.updatevisible; +end; + +function tcustombandgroup.getwidget: twidget; +begin + result:= fparentintf.getwidget; +end; + +function tcustombandgroup.remainingheight: integer; +begin + result:= fparentintf.remainingheight; +end; + +function tcustombandgroup.pagepagenum: integer; +begin + result:= fparentintf.pagepagenum; +end; + +function tcustombandgroup.reppagenum: integer; +begin + result:= fparentintf.reppagenum; +end; + +function tcustombandgroup.getlastpagepagecount: integer; +begin + result:= fparentintf.getlastpagepagecount; +end; + +function tcustombandgroup.getlastreppagecount: integer; +begin + result:= fparentintf.getlastreppagecount; +end; + +function tcustombandgroup.pageprintstarttime: tdatetime; +begin + result:= fparentintf.pageprintstarttime; +end; + +function tcustombandgroup.repprintstarttime: tdatetime; +begin + result:= fparentintf.repprintstarttime; +end; + +function tcustombandgroup.getreppage: tcustomreportpage; +begin + result:= fparentintf.getreppage; +end; + +procedure tcustombandgroup.dobeforenextrecord(const adatasource: tdatasource); +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].dobeforenextrecord(adatasource); + end; +end; + +procedure tcustombandgroup.dosyncnextrecord; +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].dosyncnextrecord; + end; +end; + +procedure tcustombandgroup.initpage; +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].initpage; + end; +end; + +function tcustombandgroup.getppmm: real; +begin + result:= ftabs.ppmm; +end; + +{ tbasebandarea } + +function tbasebandarea.getareafull: boolean; +begin + result:= bas_areafull in fstate; +end; + +procedure tbasebandarea.setareafull(const avalue: boolean); +begin + if avalue then begin + include(fstate,bas_areafull); + end + else begin + exclude(fstate,bas_areafull); + end; +end; + +procedure tbasebandarea.registerchildwidget(const child: twidget); +begin + inherited; + if child is tcustomrecordband then begin + additem(pointerarty(fareabands),child); + end; +end; + +procedure tbasebandarea.unregisterchildwidget(const child: twidget); +begin + removeitem(pointerarty(fareabands),child); + inherited; +end; + +procedure tbasebandarea.registerclient(const aclient: ireportclient); +begin + //dummy, register children only +end; + +procedure tbasebandarea.unregisterclient(const aclient: ireportclient); +begin + //dummy, register children only +end; + +procedure tbasebandarea.setparentwidget(const avalue: twidget); +var + widget1: twidget; +begin + if avalue is tcustomrecordband then begin + frecordband:= tcustomrecordband(avalue); + end + else begin + frecordband:= nil; + end; + if avalue is tcustomreportpage then begin + freportpage:= tcustomreportpage(avalue); + end + else begin + freportpage:= nil; + widget1:= avalue.parentwidget; + while widget1 <> nil do begin + if widget1 is tcustomreportpage then begin + freportpage:= tcustomreportpage(widget1); + break; + end; + widget1:= widget1.parentwidget; + end; + end; + inherited; +end; + +procedure tbasebandarea.init; +var + int1: integer; +begin + include(fstate,bas_inited); + sortwidgetsyorder(widgetarty(fareabands)); + for int1:= 0 to high(fareabands) do begin + fareabands[int1].init; + end; + initareapage; +end; + +procedure tbasebandarea.initband; +begin + sortwidgetsyorder(widgetarty(fareabands)); + fstate:= fstate - [bas_areafull,bas_backgroundrendered,bas_notfirstband, + bas_lastband]; +end; + +procedure tbasebandarea.initpage; +var + int1: integer; +begin + include(fstate,bas_top); + for int1:= 0 to high(fareabands) do begin + fareabands[int1].initpage; + end; + initband; +end; + +function tbasebandarea.render(const acanvas: tcanvas): boolean; +begin + result:= false; + //dummy +end; + +procedure tbasebandarea.initareapage; +begin + exclude(fstate,bas_notfirstband); + include(fstate,bas_top); +end; + +procedure tbasebandarea.dofirstarea; +begin + if canevent(tmethod(fonfirstarea)) then begin + application.lock; + try + fonfirstarea(self); + finally + application.unlock; + end; + end; +end; + +procedure tbasebandarea.dobeforerender; +begin + if canevent(tmethod(fonbeforerender)) then begin + application.lock; + try + fonbeforerender(self); + finally + application.unlock; + end; + end; +end; + +procedure tbasebandarea.doonpaint(const acanvas: tcanvas); +begin + if canevent(tmethod(fonpaint)) then begin + application.lock; + try + fonpaint(self,acanvas); + finally + application.unlock; + end; + end; +end; + +procedure tbasebandarea.doafterpaint1(const acanvas: tcanvas); +begin + if canevent(tmethod(fonafterpaint)) then begin + application.lock; + try + fonafterpaint(self,acanvas); + finally + application.unlock; + end; + end; +end; + +procedure tbasebandarea.renderbackground(const acanvas: tcanvas); +begin + if frecordband = nil then begin + freportpage.beginarea(acanvas,self); + acanvas.origin:= pos; + end + else begin + acanvas.origin:= forigin; + end; + inherited paint(acanvas); +end; + +function tbasebandarea.checkareafull(ay: integer): boolean; +begin + if frame <> nil then begin + ay:= ay + fframe.innerframe.bottom; + end; + result:= ay > bounds_y + bounds_cy; +end; + +function tbasebandarea.beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; +begin + result:= false; //dummy +end; + +procedure tbasebandarea.endband(const acanvas: tcanvas; + const sender: tcustomrecordband); +begin + //dummy +end; + +procedure tbasebandarea.paint(const canvas: tcanvas); +begin + if not rendering then begin + inherited; + end + else begin + if (frecordband <> nil) then begin + forigin:= canvas.origin; + render(canvas); + end; + end; +end; + +function tbasebandarea.rendering: boolean; +begin + result:= bas_rendering in fstate; +end; + +procedure tbasebandarea.beginrender(const arestart: boolean); +var + int1: integer; +begin + if arestart then begin + fstate:= fstate - [bas_notfirstband,bas_finished]; + end + else begin + fstate:= [bas_rendering]; + end; + include(fwidgetstate1,ws1_noclipchildren); + for int1:= 0 to high(fareabands) do begin + with fareabands[int1] do begin + beginrender(false); + end; + end; +end; + +procedure tbasebandarea.resetzebra; +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].resetzebra; + end; +end; + +procedure tbasebandarea.endrender; +var + int1: integer; +begin + exclude(fstate,bas_rendering); + exclude(fwidgetstate1,ws1_noclipchildren); + for int1:= 0 to high(fareabands) do begin + fareabands[int1].endrender; + end; +end; + +procedure tbasebandarea.adddatasets(var adatasets: datasetarty); +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].adddatasets(adatasets); + end; +end; + +function tbasebandarea.istopband: boolean; +begin + result:= bas_top in fstate; +end; + +function tbasebandarea.isfirstband: boolean; +begin + result:= false; //dummy +end; + +function tbasebandarea.islastband(const addheight: integer = 0): boolean; +begin + result:= false; //dummy +end; + +function tbasebandarea.remainingheight: integer; +begin + result:= 0; //dummy +end; + +procedure tbasebandarea.updatevisible; +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].updatevisibility; + end; +end; + +function tbasebandarea.pagepagenum: integer; +begin + result:= freportpage.pagenum; +end; + +function tbasebandarea.reppagenum: integer; +begin + if freportpage.freport <> nil then begin + result:= freportpage.freport.pagenum; + end + else begin + result:= 0; + end; +end; + +function tbasebandarea.pageprintstarttime: tdatetime; +begin + result:= freportpage.fprintstarttime; +end; + +function tbasebandarea.getlastpagepagecount: integer; +begin + result:= freportpage.flastpagecount; +end; + +function tbasebandarea.getlastreppagecount: integer; +begin + if freportpage.freport <> nil then begin + result:= freportpage.freport.flastpagecount; + end + else begin + result:= 0; + end; +end; + +function tbasebandarea.repprintstarttime: tdatetime; +begin + if freportpage.freport <> nil then begin + result:= freportpage.freport.fprintstarttime; + end + else begin + result:= nowlocal; + end; +end; + +function tbasebandarea.getreppage: tcustomreportpage; +begin + result:= freportpage; +end; + +function tbasebandarea.isfirstrecord: boolean; +begin + if frecordband <> nil then begin + result:= frecordband.isfirstrecord; + end + else begin + result:= freportpage.isfirstrecord; + end; +end; + +function tbasebandarea.islastrecord: boolean; +begin + if frecordband <> nil then begin + result:= frecordband.islastrecord; + end + else begin + result:= freportpage.islastrecord; + end; +end; + +procedure tbasebandarea.dobeforenextrecord(const adatasource: tdatasource); +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].dobeforenextrecord(adatasource); + end; +end; + +procedure tbasebandarea.setppmm(const avalue: real); +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].setppmm(avalue); + end; +end; + +procedure tbasebandarea.dosyncnextrecord; +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].dosyncnextrecord; + end; +end; + +procedure tbasebandarea.setfont(const avalue: trepwidgetfont); +begin + inherited setfont(avalue); +end; + +function tbasebandarea.getfont: trepwidgetfont; +begin + result:= trepwidgetfont(inherited getfont); +end; + +function tbasebandarea.getfontclass: widgetfontclassty; +begin + result:= trepwidgetfont; +end; + +procedure tbasebandarea.restart; +begin + beginrender(true); + if freportpage <> nil then begin + freportpage.recordchanged; + end; +end; + +function tbasebandarea.getppmm: real; +begin + if freportpage <> nil then begin + result:= freportpage.ppmm; + end + else begin + result:= defaultppmm; + end; +end; + +{ tcustomreportpage } + +constructor tcustomreportpage.create(aowner: tcomponent); +begin + fprintstarttime:= nowlocal; + fvisiblepage:= true; + fdatalink:= treportpagedatalink.create; + inherited; + fwidgetstate1:= fwidgetstate1 + [{ws1_nodesignvisible,}ws1_nodesignmove + {,ws1_nodesignhandles,ws1_nodesigndelete}]; +// fpagewidth:= defaultreppagewidth; +// fpageheight:= defaultreppageheight; + fppmm:= defaultrepppmm; + with fwidgetrect do begin + cx:= round(defaultreppagewidth*defaultrepppmm); + cy:= round(defaultreppageheight*defaultrepppmm); + end; +end; + +destructor tcustomreportpage.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tcustomreportpage.registerchildwidget(const child: twidget); +begin + inherited; + if child is tbasebandarea then begin + additem(pointerarty(fareas),child); + end; +end; + +procedure tcustomreportpage.unregisterchildwidget(const child: twidget); +begin + removeitem(pointerarty(fareas),child); + inherited; +end; + +procedure tcustomreportpage.registerclient(const aclient: ireportclient); +var + widget1: twidget; +begin + if finditem(pointerarty(fclients),pointer(aclient)) < 0 then begin + additem(pointerarty(fclients),pointer(aclient)); + end; + widget1:= aclient.getwidget; + if widget1 is tcustomrecordband then begin + if finditem(pointerarty(fbands),widget1) < 0 then begin + additem(pointerarty(fbands),widget1); + end; + end; +end; + +procedure tcustomreportpage.unregisterclient(const aclient: ireportclient); +begin + removeitem(pointerarty(fclients),pointer(aclient)); + removeitem(pointerarty(fbands),aclient.getwidget); +end; + +procedure tcustomreportpage.setparentwidget(const avalue: twidget); +begin + if avalue is tcustomreport then begin + freport:= tcustomreport(avalue); + updatepagesize; + end + else begin + freport:= nil; + end; + inherited; +end; + +procedure tcustomreportpage.init; +var + int1: integer; +begin + include(fstate,rpps_inited); + exclude(fstate,rpps_showed); + for int1:= 0 to high(fclients) do begin + fclients[int1].init; + end; +// for int1:= 0 to high(fareas) do begin +// fareas[int1].init; +// end; +end; + +procedure tcustomreportpage.dosyncnextrecord; +var + int1: integer; +begin + for int1:= 0 to high(fareas) do begin + fareas[int1].dosyncnextrecord; + end; + for int1:= 0 to high(fbands) do begin + fbands[int1].dosyncnextrecord; + end; +end; + +procedure tcustomreportpage.dobeforenextrecord(const adatasource: tdatasource); +var + int1: integer; +begin + for int1:= 0 to high(fareas) do begin + fareas[int1].dobeforenextrecord(adatasource); + end; + for int1:= 0 to high(fbands) do begin + fbands[int1].dobeforenextrecord(adatasource); + end; +end; + +procedure tcustomreportpage.nextrecord; +begin + application.lock; + try + exclude(fstate,rpps_nextrecordpending); + if canevent(tmethod(fonbeforenextrecord)) then begin + fonbeforenextrecord(self); + end; + dobeforenextrecord(fdatalink.datasource); + fdatalink.dataset.next; + if checkislastrecord(fdatalink,{$ifdef FPC}@{$endif}dosyncnextrecord) then begin + include(fstate,rpps_lastrecord); + end; + if canevent(tmethod(fonafternextrecord)) then begin + fonafternextrecord(self); + end; + finally + application.unlock; + end; + recordchanged; +end; + +function tcustomreportpage.render(const acanvas: tcanvas): boolean; +var + int1: integer; + bo1,bo2,bo4: boolean; + customdataempty: boolean; + backgroundrendered: boolean; +// hascustomdata: boolean; + + procedure renderband(const aband: tcustomrecordband); + begin + with aband do begin + bo4:= (not customdataempty or backgroundrendered) and + (bo2 and (bo_oddpage in foptions) or + not bo2 and (bo_evenpage in foptions)); //has data + bo4:= not(bo4 or ((bo_once in foptions) and not (rbs_showed in fstate))); + //empty + render(acanvas,bo4); + bo1:= bo1 and bo4; + end; + end; + +var + orient1: pageorientationty; + +begin + if not (rpps_inited in fstate) then begin + init; + end; + fprintstarttime:= nowlocal; + bo1:= odd(reppagenum); + if bo1 and (rpo_firsteven in foptions) or not bo1 and + (rpo_firstodd in foptions) then begin + freport.nextpage(acanvas); + with freport do begin + if fpagenum = 0 then begin + include(fstate,rs_dummypage); + end; + inc(fpagenum); + end; + end; + fpagenum:= 0; + exclude(fstate,rpps_finish); + recordchanged; + dofirstpage; + result:= true; + repeat + if rpps_finish in fstate then begin + break; + end; + if rpps_nextrecordpending in fstate then begin + nextrecord; + end; + exclude(fstate,rpps_backgroundrendered); + acanvas.reset; + if acanvas is tcustomprintercanvas then begin + if fprintorientation = rpo_default then begin + orient1:= freport.fdefaultprintorientation; + end + else begin + orient1:= pageorientationty(pred(fprintorientation)); + end; + tcustomprintercanvas(acanvas).printorientation:= orient1; + end; + acanvas.intersectcliprect(makerect(nullpoint,fwidgetrect.size)); + updatevisible; + bo1:= (not fdatalink.active or fdatalink.dataset.eof) and + not ((rpo_once in foptions) and not (rpps_showed in fstate)); + dobeforerender(bo1); + customdataempty:= bo1; + if not bo1 or not (rpo_datasourceonly in foptions) then begin + for int1:= 0 to high(fareas) do begin + fareas[int1].initpage; + end; + for int1:= 0 to high(fbands) do begin + fbands[int1].initpage; + end; + updatevisible; + for int1:= 0 to high(fareas) do begin + with fareas[int1] do begin + if visible then begin + bo1:= render(acanvas) and bo1; + end; + end; + end; + sortwidgetsyorder(widgetarty(fbands),self); + bo2:= odd(reppagenum); + // bo5:= true; + backgroundrendered:= rpps_backgroundrendered in fstate; + for int1:= 0 to high(fbands) do begin + if not (fbands[int1] is tcustomrepvaluedisp) then begin + renderband(fbands[int1]); + end; + end; + backgroundrendered:= rpps_backgroundrendered in fstate; + for int1:= 0 to high(fbands) do begin + if fbands[int1] is tcustomrepvaluedisp then begin + renderband(fbands[int1]); + end; + end; + if not (rpps_backgroundrendered in fstate) and not customdataempty then begin + renderbackground(acanvas); + end; + + if rpps_backgroundrendered in fstate then begin + doafterpaint1(acanvas); + if canevent(tmethod(fonafterrender)) then begin + fonafterrender(self); + end; + if not (rpps_finish in fstate) and fdatalink.active then begin + bo1:= false; + if rpo_delayednextrecord in foptions then begin + include(fstate,rpps_nextrecordpending); + end + else begin + nextrecord; + end; + end; + inc(fpagenum); + inc(freport.fpagenum); + include(fstate,rpps_showed); + end; + freport.doprogress; + end; + result:= result and bo1; + if bo1 or (fnextpage <> nil) or (rpps_finish in fstate) then begin + //next page + exclude(fstate,rpps_restart); + doafterlastpage; + if rpps_restart in fstate then begin + bo1:= false; + end; + end; + until bo1 or (fnextpage <> nil); +end; + +function tcustomreportpage.rendering: boolean; +begin + result:= rpps_rendering in fstate; +end; + +procedure tcustomreportpage.dobeforerender(var empty: boolean); +begin + if canevent(tmethod(fonbeforerender)) then begin + application.lock; + try + fonbeforerender(self,empty); + finally + application.unlock; + end; + end; + freport.dopagebeforerender(self,empty); +end; + +procedure tcustomreportpage.doonpaint(const acanvas: tcanvas); +begin + if freport <> nil then begin + freport.dopagepaint(self,acanvas); + if canevent(tmethod(fonpaint)) then begin + application.lock; + try + fonpaint(self,acanvas); + finally + application.unlock; + end; + end; + end; +end; + +procedure tcustomreportpage.doafterpaint1(const acanvas: tcanvas); +begin + if canevent(tmethod(fonafterpaint)) then begin + application.lock; + try + fonafterpaint(self,acanvas); + finally + application.unlock; + end; + end; + if freport <> nil then begin + freport.dopageafterpaint(self,acanvas); + end; +end; + +procedure tcustomreportpage.renderbackground(const acanvas: tcanvas); +//var +// orient1: pageorientationty; +begin + if (freport.fpagenum <> 0) and not (rs_dummypage in freport.fstate) then begin + freport.nextpage(acanvas); + end; + exclude(freport.fstate,rs_dummypage); +{ moved to render + if acanvas is tprintercanvas then begin + if fprintorientation = rpo_default then begin + orient1:= freport.fdefaultprintorientation; + end + else begin + orient1:= pageorientationty(pred(fprintorientation)); + end; + tprintercanvas(acanvas).printorientation:= orient1; + end; +} + acanvas.origin:= pos; + inherited paint(acanvas); + include(fstate,rpps_backgroundrendered); +end; + +procedure tcustomreportpage.beginarea(const acanvas: tcanvas; + const sender: tbasebandarea); +begin + if not (rpps_backgroundrendered in fstate) then begin + include(fstate,rpps_backgroundrendered); + renderbackground(acanvas); + end; +end; + +procedure tcustomreportpage.beginrender(const arestart: boolean); + procedure addreccontrols(const awidget: twidget); + var + int1: integer; + po1: pointer; + begin + for int1:= 0 to awidget.widgetcount -1 do begin + addreccontrols(awidget.widgets[int1]); + if awidget.widgets[int1].getcorbainterface(typeinfo(ireccontrol),po1) then begin + additem(freccontrols,po1); + end; + end; + end; +var + int1: integer; +begin + freccontrols:= nil; + addreccontrols(self); + if arestart then begin + fstate:= fstate * [rpps_inited,rpps_rendering]; + end + else begin + fstate:= [rpps_rendering]; + end; + include(fwidgetstate1,ws1_noclipchildren); + with fdatalink do begin + if active then begin + application.lock; + try + dataset.first; + if checkislastrecord(fdatalink,{$ifdef FPC}@{$endif}dosyncnextrecord) then begin + include(fstate,rpps_lastrecord); + end; + finally + application.unlock; + end; + self.recordchanged; + end; + end; + for int1:= 0 to high(fclients) do begin + fclients[int1].beginrender(false); + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].beginrender(false); + end; +end; + +procedure tcustomreportpage.resetzebra; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + fclients[int1].resetzebra; + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].resetzebra; + end; +end; + +procedure tcustomreportpage.endrender; +var + int1: integer; +begin + flastpagecount:= fpagenum; + freccontrols:= nil; + exclude(fstate,rpps_rendering); + exclude(fwidgetstate1,ws1_noclipchildren); + for int1:= 0 to high(fclients) do begin + fclients[int1].endrender; + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].endrender; + end; +end; + +procedure tcustomreportpage.adddatasets(var adatasets: datasetarty); +var + int1: integer; +begin + if fdatalink.dataset <> nil then begin + adduniqueitem(pointerarty(adatasets),fdatalink.dataset); + end; + for int1:= 0 to high(fclients) do begin + fclients[int1].adddatasets(adatasets); + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].adddatasets(adatasets); + end; +end; + +procedure tcustomreportpage.setpagewidth(const avalue: real); +begin + if fpagewidth <> avalue then begin + fpagewidth:= avalue; + updatepagesize; + end; +end; + +procedure tcustomreportpage.setpageheight(const avalue: real); +begin + if fpageheight <> avalue then begin + fpageheight:= avalue; + updatepagesize; + end; +end; + +procedure tcustomreportpage.updatepagesize; +begin + if not (rpps_sizesetting in fstate) then begin + include(fstate,rpps_sizesetting); + size:= makesize(round(getpagewidth*fppmm),round(getpageheight*fppmm)); + fpagedim:= size; + exclude(fstate,rpps_sizesetting); + end; +end; + +procedure tcustomreportpage.sizechanged; +begin + if (freport <> nil) and visible then begin + freport.size:= size; + end; + inherited; + if (csdesigning in componentstate) and + not (rpps_sizesetting in fstate) then begin + if width <> fpagedim.cx then begin + fpagedim.cx:= width; + fpagewidth:= fpagedim.cx / fppmm; + end; + if height <> fpagedim.cy then begin + fpagedim.cy:= height; + fpageheight:= fpagedim.cy / fppmm; + end; + end; +end; + +procedure tcustomreportpage.setppmm(const avalue: real); +var + rea1: real; + int1: integer; +begin + if avalue <> fppmm then begin + rea1:= avalue/fppmm; + fppmm:= avalue; + for int1:= 0 to high(fclients) do begin + fclients[int1].setppmm(avalue); + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].setppmm(avalue); + end; + if not (csloading in componentstate) then begin + scale(rea1); + end; + updatepagesize; + end; +end; + +procedure tcustomreportpage.insertwidget(const awidget: twidget; + const apos: pointty); +begin + if (awidget is tcustomreportpage) and (fparentwidget <> nil) then begin + fparentwidget.insertwidget(awidget,addpoint(apos,pos)); + end + else begin + inherited; + end; +end; + +procedure tcustomreportpage.dofirstpage; +begin + if canevent(tmethod(fonfirstpage)) then begin + application.lock; + try + fonfirstpage(self); + finally + application.unlock; + end; + end; +end; + +procedure tcustomreportpage.doafterlastpage; +begin + if canevent(tmethod(fonafterlastpage)) then begin + application.lock; + try + fonafterlastpage(self); + finally + application.unlock; + end; + end; +end; + +procedure tcustomreportpage.setnextpage(const avalue: tcustomreportpage); +begin + setlinkedvar(avalue,tmsecomponent(fnextpage)); +end; + +procedure tcustomreportpage.setnextpageifempty(const avalue: tcustomreportpage); +begin + setlinkedvar(avalue,tmsecomponent(fnextpageifempty)); +end; + +procedure tcustomreportpage.setnextpageiflast(const avalue: tcustomreportpage); +begin + setlinkedvar(avalue,tmsecomponent(fnextpageiflast)); +end; + +function tcustomreportpage.beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; +begin + fsaveindex:= acanvas.save; + if not (rpps_backgroundrendered in fstate) then begin + renderbackground(acanvas); + end; + acanvas.origin:= translatewidgetpoint(sender.pos,sender.parentwidget,self); + result:= false; +end; + +procedure tcustomreportpage.endband(const acanvas: tcanvas; + const sender: tcustomrecordband); +begin + acanvas.restore(fsaveindex); + include(sender.fstate,rbs_showed); +end; + +function tcustomreportpage.istopband: boolean; +begin + result:= false; +end; + +function tcustomreportpage.isfirstband: boolean; +begin + result:= false; +end; + +function tcustomreportpage.islastband(const addheight: integer = 0): boolean; +begin + result:= false; +end; + +procedure tcustomreportpage.setareafull(const avalue: boolean); +begin + //dummy +end; + +procedure tcustomreportpage.updatevisible; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + fclients[int1].updatevisibility; + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].updatevisible; + end; +end; + +function tcustomreportpage.remainingheight: integer; +begin + result:= 0; +end; + +function tcustomreportpage.pagepagenum: integer; +begin + result:= fpagenum; +end; + +function tcustomreportpage.reppagenum: integer; +begin + if freport <> nil then begin + result:= freport.fpagenum; + end + else begin + result:= 0; + end; +end; + +function tcustomreportpage.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +function tcustomreportpage.pageprintstarttime: tdatetime; +begin + result:= fprintstarttime; +end; + +function tcustomreportpage.repprintstarttime: tdatetime; +begin + if freport <> nil then begin + result:= freport.fprintstarttime; + end + else begin + result:= nowlocal(); + end; +end; + +procedure tcustomreportpage.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; +end; + +procedure tcustomreportpage.activatepage; +begin + if freport <> nil then begin + freport.activepage:= finditem(pointerarty(freport.freppages),self); + end; +end; + +procedure tcustomreportpage.finish; +begin + include(fstate,rpps_finish); +end; + +procedure tcustomreportpage.restart; +begin + beginrender(true); + include(fstate,rpps_restart); + recordchanged; +end; + +procedure tcustomreportpage.setoptions(const avalue: reportpageoptionsty); +const + mask: reportpageoptionsty = [rpo_firsteven,rpo_firstodd]; +begin + foptions:= reportpageoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); +end; + +function tcustomreportpage.getreppage: tcustomreportpage; +begin + result:= self; +end; + +function tcustomreportpage.isfirstrecord: boolean; +begin + if fdatalink.active then begin + result:= not (rpps_notfirstrecord in fstate); + end + else begin + result:= false; + end; +end; + +function tcustomreportpage.islastrecord: boolean; +begin + if fdatalink.active then begin + result:= rpps_lastrecord in fstate; + end + else begin + result:= false; + end; +end; + +procedure tcustomreportpage.recordchanged; +var + int1: integer; +begin + application.lock; + try + for int1:= 0 to high(freccontrols) do begin + ireccontrol(freccontrols[int1]).recchanged; + end; + finally + application.unlock; + end; +end; + +function tcustomreportpage.getlastpagepagecount: integer; +begin + result:= flastpagecount; +end; + +function tcustomreportpage.getlastreppagecount: integer; +begin + if freport <> nil then begin + result:= freport.flastpagecount; + end + else begin + result:= 0; + end; +end; + +procedure tcustomreportpage.setfont(const avalue: trepwidgetfont); +begin + inherited setfont(avalue); +end; + +function tcustomreportpage.getfont: trepwidgetfont; +begin + result:= trepwidgetfont(inherited getfont); +end; + +function tcustomreportpage.getfontclass: widgetfontclassty; +begin + result:= trepwidgetfont; +end; + +function tcustomreportpage.getppmm: real; +begin + result:= fppmm; +end; + +function tcustomreportpage.getpagewidth: real; +begin + result:= fpagewidth; + if result = 0 then begin + if freport = nil then begin + result:= defaultpagewidth; + end + else begin + result:= freport.fpagewidth; + end; + end + else begin + if (rpo_reportpagewidth in foptions) and (freport <> nil) then begin + result:= freport.fpagewidth; + end; + end; +end; + +function tcustomreportpage.getpageheight: real; +begin + result:= fpageheight; + if result = 0 then begin + if freport = nil then begin + result:= defaultpageheight; + end + else begin + result:= freport.fpageheight; + end; + end + else begin + if (rpo_reportpageheight in foptions) and (freport <> nil) then begin + result:= freport.fpageheight; + end; + end; +end; + +procedure initrepdesigninfo(var ainfo: repdesigninfoty); +begin + with ainfo do begin + widgetrect:= makerect(50,50,50,50); + gridsize:= 2; //mm + showgrid:= true; + snaptogrid:= true; + end; +end; + +{ tcustomreport } + +constructor tcustomreport.create(aowner: tcomponent); +begin + fprintstarttime:= nowlocal; + fppmm:= defaultrepppmm; + fpagewidth:= defaultreppagewidth; + fpageheight:= defaultreppageheight; + foptions:= defaultreportoptions; + initrepdesigninfo(frepdesigninfo); + inherited; + visible:= false; + color:= cl_transparent; +{$warnings off} + ffont:= twidgetfont(trepfont.create); +{$warnings on} + ffont.height:= round(defaultrepfontheight * (fppmm/defaultrepppmm)); + ffont.onchange:= {$ifdef FPC}@{$endif}dofontchanged; + //createfont; +end; + +destructor tcustomreport.destroy; +begin + if fthread <> nil then begin + fthread.terminate; + application.waitforthread(fthread); + end; + fthread.free; + inherited; +end; + +class function tcustomreport.hasresource: boolean; +begin + result:= true; +end; + +procedure tcustomreport.unregisterchildwidget(const child: twidget); +begin + removeitem(pointerarty(freppages),child); + inherited; +end; + +procedure tcustomreport.setppmm(const avalue: real); +var + int1: integer; +begin + if avalue <> fppmm then begin + if avalue <= 0 then begin + raise exception.create('Invalid value'); + end; + if (ffont <> nil) and (fppmm > 0) then begin + include(fwidgetstate1,ws1_scaling); + ffont.scale(avalue/fppmm); + exclude(fwidgetstate1,ws1_scaling); + end; + fppmm:= avalue; + for int1:= 0 to high(freppages) do begin + freppages[int1].ppmm:= avalue; + end; + if not (csloading in componentstate) then begin + postchildscaled; + end; + end; +end; + +procedure tcustomreport.initpage(const apage: tcustomreportpage); +begin + apage.ppmm:= fppmm; +end; + +procedure tcustomreport.insertwidget(const awidget: twidget; + const apos: pointty); +begin + if not (awidget is tcustomreportpage) then begin + raise exception.create('Invalid widget'); + end; + additem(pointerarty(freppages),awidget); + initpage(tcustomreportpage(awidget)); + inherited insertwidget(awidget,nullpoint); +end; + +function tcustomreport.add(const apage: tcustomreportpage; + aindex: int32 = bigint): tcustomreportpage; +var + i1: int32; +begin + result:= apage; + i1:= length(freppages); + if aindex >= i1 then begin + aindex:= i1; + end; + insertitem(pointerarty(freppages),aindex,apage); + initpage(apage); + apage.parentwidget:= self; +end; + +procedure tcustomreport.delete(const aindex: int32); +begin + reppages[aindex].destroy(); +end; + +procedure tcustomreport.clear(); +begin + while freppages <> nil do begin + delete(high(freppages)); + end; +end; + +procedure tcustomreport.movepage(const curindex: int32; const newindex: int32); +begin + moveitem(pointerarty(freppages),curindex,newindex); +end; + +function tcustomreport.exec(thread: tmsethread): integer; + + function checkterminated: boolean; + begin + result:= (thread <> nil) and thread.terminated or fcanceled; + end; + + procedure fakevisible(const awidget: twidget; const aset: boolean); + var + int1: integer; + begin + with twidget1(awidget) do begin + if aset then begin + include(fwidgetstate1,ws1_fakevisible); + end + else begin + exclude(fwidgetstate1,ws1_fakevisible); + end; +// updateopaque(false); + for int1:= 0 to high(fwidgets) do begin + fakevisible(fwidgets[int1],aset); + end; + end; + end; + +var + terminated1: boolean; + recnos: integerarty; + renderbegin: boolean; + + procedure dofinish(const islast: boolean); + var + int1: integer; + begin + application.lock; + try + fakevisible(self,false); + flastpagecount:= fpagenum; + if renderbegin then begin + for int1:= 0 to high(freppages) do begin + freppages[int1].endrender; + end; + end; + terminated1:= checkterminated; + if islast or (rs_endpass in fstate) or terminated1 then begin + exclude(fstate,rs_running); + fstream.free; + if fprinter <> nil then begin + fprinter.endprint; + fprinter.canvas.printorientation:= fdefaultprintorientation; + end; + fcanvas.ppmm:= fppmmbefore; + asyncevent(endrendertag); + for int1:= 0 to high(fdatasets) do begin + with fdatasets[int1] do begin + if active then begin + if (recnos[int1] > 0) and (recnos[int1] <= recordcount) then begin + try + if recno <> recnos[int1] then begin + //no checkbrowsemode if there was no scroll + recno:= recnos[int1]; + end; + except; + end; + end; + end; + if not (reo_nodisablecontrols in foptions) then begin + try + enablecontrols; + except + end; + end; + end; + end; + fdatasets:= nil; + end; + finally + application.unlock; + end; + end; + +var + int1: integer; + bo1: boolean; + page1: tcustomreportpage; + stream1: ttextstream; + str1: string; + restarted: boolean; + +begin + fstate:= [rs_running]; + result:= 0; + fdefaultprintorientation:= pao_portrait; + if fprinter <> nil then begin + fdefaultprintorientation:= fprinter.canvas.printorientation; + end; + fppmmbefore:= fcanvas.ppmm; + fcanvas.ppmm:= fppmm; + if not (reo_prepass in foptions) then begin + include(fstate,rs_endpass); + end; + application.lock; + try + twindow1(window).setasynccanvas(fcanvas); + finally + application.unlock; + end; + for int1:= 0 to high(freppages) do begin + freppages[int1].adddatasets(fdatasets); + end; + setlength(recnos,length(fdatasets)); + for int1:= 0 to high(fdatasets) do begin + with fdatasets[int1] do begin + if not (reo_nodisablecontrols in foptions) then begin + disablecontrols; + end; + recnos[int1]:= recno; + end; + end; + try + repeat //until terminated1 + fpagenum:= 0; + factivepage:= 0; + renderbegin:= false; + fakevisible(self,true); + try + if fprinter <> nil then begin + str1:= ''; + if canevent(tmethod(fonpreamble)) then begin + application.lock; + try + fonpreamble(self,str1); + finally + application.unlock; + end; + end; + if rs_endpass in fstate then begin + if fprinter is tstreamprinter then begin + with tstreamprinter(fprinter) do begin + if fstreamset then begin + stream1:= fstream; + fstream:= nil; + beginprint(stream1,str1); + end + else begin + beginprint(fcommand,str1); + end; + end; + end + else begin + with fprinter do begin + beginprint(false); + end; + end; + end + else begin + if fprinter is tstreamprinter then begin + with tstreamprinter(fprinter) do begin + beginprint(nil,str1); + end; + end + else begin + fprinter.beginprint(true); + end; + end; + end; + if canevent(tmethod(fonreportstart)) then begin + application.lock; + try + fonreportstart(self); + finally + application.unlock; + end; + end; + except + dofinish(true); + raise; + end; + restarted:= false; + repeat //until not restarted + try + if canevent(tmethod(fonbeforerender)) then begin + application.lock; + try + fonbeforerender(self); + finally + application.unlock; + end; + end; + renderbegin:= true; + for int1:= 0 to high(freppages) do begin + freppages[int1].beginrender(false); + end; + if high(freppages) >= factivepage then begin + page1:= freppages[factivepage]; + while true do begin + for int1:= finditem(pointerarty(freppages),page1) to high(freppages) do begin + if freppages[int1].visiblepage then begin + page1:= freppages[int1]; + break; + end; + end; + if page1.visiblepage and not checkterminated then begin + exclude(fstate,rs_activepageset); + factivepage:= finditem(pointerarty(freppages),page1); + bo1:= page1.render(fcanvas); + if rs_finish in fstate then begin + break; + end; + if rs_activepageset in fstate then begin + page1:= freppages[factivepage]; + end + else begin + if not bo1 and (page1.fnextpage <> nil) then begin + page1:= page1.fnextpage; + end + else begin + if bo1 and (page1.fnextpageifempty <> nil) then begin + page1:= page1.fnextpageifempty; + end + else begin + if page1.fnextpageiflast <> nil then begin + page1:= page1.fnextpageiflast; + end + else begin + int1:= finditem(pointerarty(freppages),page1); + if (int1 >= 0) and (int1 < high(freppages)) then begin + page1:= freppages[int1+1]; + end + else begin + page1:= nil; + end; + end; + end; + end; + end; + if finditem(pointerarty(freppages),page1) < 0 then begin + break; + end; + end + else begin + break; + end; + end; + end; + except + dofinish(true); + raise; + end; + restarted:= false; + if canevent(tmethod(fonafterrender)) then begin + application.lock; + try + exclude(fstate,rs_restart); + fonafterrender(self); + restarted:= rs_restart in fstate; + finally + application.unlock; + end; + end; + until not restarted; + dofinish(false); + if (rs_endpass in fstate) then begin + break; + end; + fstate:= [rs_endpass]; + until terminated1; + finally + application.lock; + try + twindow1(window).releaseasynccanvas; + finally + application.unlock; + end; + if {(fthread <> nil) and }(reo_waitdialog in foptions) then begin + application.terminatewait; + end; + end; +end; + +procedure tcustomreport.doexec(const sender: tobject); +begin + exec(nil); +end; + +procedure tcustomreport.docancel(const sender: tobject); +begin + canceled:= true; +end; + +procedure tcustomreport.internalrender(const acanvas: tcanvas; + const aprinter: tcustomprinter; const acommand: msestring; + const astream: ttextstream; const anilstream: boolean; + const onafterrender: reporteventty); +begin + if running then begin + raise exception.create('Already rendering.'); + end; + include(fstate,rs_running); + fnilstream:= anilstream; + fonrenderfinish:= onafterrender; + if assigned(fonrenderfinish) and + (tobject(tmethod(fonrenderfinish).data) is tcomponent) then begin + tcomponent(tmethod(fonrenderfinish).data).freenotification(self); + end; + fprintstarttime:= nowlocal; + fprinter:= aprinter; + fcanvas:= acanvas; + fstream:= astream; + fstreamset:= (astream <> nil) or nilstream; + fcommand:= acommand; + freeandnil(fthread); + fcanceled:= false; + if reo_nothread in foptions then begin + application.beginwait; + try + if reo_waitdialog in foptions then begin + application.waitdialog(nil,getdialogtext,getdialogcaption, + {$ifdef FPC}@{$endif}docancel,{$ifdef FPC}@{$endif}doexec); +// if not canceled then begin +// application.terminatewait; +// end; + end + else begin + exec(nil); + end; + finally + application.endwait; + end; + end + else begin + if reo_waitdialog in foptions then begin + application.resetwaitdialog; + end; + fthread:= tmsethread.create({$ifdef FPC}@{$endif}exec); + if reo_waitdialog in foptions then begin + application.waitdialog(nil,getdialogtext,getdialogcaption); + waitfor; + end; + end; +end; + +procedure tcustomreport.render(const acanvas: tcanvas; + const onafterrender: reporteventty = nil); +begin + internalrender(acanvas,nil,'',nil,false,onafterrender); +end; + +procedure tcustomreport.render(const aprinter: tstreamprinter; + const command: msestring = ''; + const onafterrender: reporteventty = nil); +begin + internalrender(aprinter.canvas,aprinter,command,nil,false,onafterrender); +end; + +procedure tcustomreport.render(const aprinter: tstreamprinter; + const astream: ttextstream; + const onafterrender: reporteventty = nil); +begin + internalrender(aprinter.canvas,aprinter,'',astream,astream = nil,onafterrender); +end; + +procedure tcustomreport.render(const aprinter: tcustomgdiprinter; + const onafterrender: reporteventty = nil); +begin + internalrender(aprinter.canvas,aprinter,'',nil,true,onafterrender); +end; + +procedure tcustomreport.getchildren(proc: tgetchildproc; root: tcomponent); +var + int1: integer; + comp1: tcomponent; +begin + for int1:= 0 to high(freppages) do begin + comp1:= freppages[int1]; + if (comp1.owner = root) and + not (cssubcomponent in comp1.componentstyle) then begin + proc(comp1); + end; + end; + getcompchildren(proc,root); + { + for int1:= 0 to high(freppages) do begin + comp1:= freppages[int1]; + if ((comp1.owner = root) or (csinline in root.componentstate) and + not (csancestor in comp1.componentstate) and + issubcomponent(comp1.owner,root)) then begin + proc(comp1); + end; + end; + if root = self then begin + for int1 := 0 to componentcount - 1 do begin + comp1 := components[int1]; + if not comp1.hasparent then begin + proc(comp1); + end; + end; + end; + } +end; + +function tcustomreport.getreppages(index: integer): tcustomreportpage; +begin + checkarrayindex(freppages,index); + result:= freppages[index]; +end; + +procedure tcustomreport.setreppages(index: integer; + const avalue: tcustomreportpage); +begin + checkarrayindex(freppages,index); + freppages[index].assign(avalue); +end; + +function tcustomreport.reppagecount: integer; +begin + result:= length(freppages); +end; +{ +procedure tcustomreport.internalcreatefont; +var + font1: twidgetfont; +begin + font1:= trepwidgetfont.create; + font1.height:= round(defaultrepfontheight * (fppmm/defaultrepppmm)); +// font1.name:= defaultrepfontname; + ffont:= font1; + inherited; +end; +} +function tcustomreport.getgrid_show: boolean; +begin + result:= frepdesigninfo.showgrid; +end; + +procedure tcustomreport.setgrid_show(const avalue: boolean); +begin + frepdesigninfo.showgrid:= avalue; + designchanged; +end; + +function tcustomreport.getgrid_snap: boolean; +begin + result:= frepdesigninfo.snaptogrid; +end; + +procedure tcustomreport.setgrid_snap(const avalue: boolean); +begin + frepdesigninfo.snaptogrid:= avalue; + designchanged; +end; + +function tcustomreport.getgrid_size: real; +begin + result:= frepdesigninfo.gridsize; +end; + +procedure tcustomreport.setgrid_size(avalue: real); +begin + if avalue < 2/ppmm then begin + avalue:= 2/ppmm; + end; + frepdesigninfo.gridsize:= avalue; + designchanged; +end; + +procedure tcustomreport.writerepdesigninfo(writer: twriter); +begin + writerectty(writer,frepdesigninfo.widgetrect); +end; + +procedure tcustomreport.readrepdesigninfo(reader: treader); +begin + frepdesigninfo.widgetrect:= readrectty(reader); +end; + +procedure tcustomreport.defineproperties(filer: tfiler); +begin + filer.defineproperty('repdesigninfo',{$ifdef FPC}@{$endif}readrepdesigninfo, + {$ifdef FPC}@{$endif}writerepdesigninfo,true); + inherited; +end; + +procedure tcustomreport.nextpage(const acanvas: tcanvas); +begin + tcanvas1(acanvas).nextpage; +{ + if acanvas is tcustomprintercanvas then begin + tcustomprintercanvas(acanvas).nextpage; + end; +} +end; + +function tcustomreport.getcanceled: boolean; +begin + result:= (fthread <> nil) and + (fthread.terminated or ((reo_waitdialog in foptions) and + application.waitcanceled)) or fcanceled; +end; + +procedure tcustomreport.setcanceled(const avalue: boolean); +begin + fcanceled:= fcanceled or avalue; + if avalue and (fthread <> nil) then begin + fthread.terminate; + end; +end; + +function tcustomreport.getrunning: boolean; +begin + result:= rs_running in fstate; + { + result:= (fthread <> nil) and fthread.running; + } +end; + +procedure tcustomreport.waitfor; +var + int1: integer; +begin + if running and (fthread <> nil) then begin + int1:= application.unlockall; + fthread.waitfor; + application.relockall(int1); +// exclude(fstate,rs_running); + end; +end; + +procedure tcustomreport.setactivepage(const avalue: integer); +begin + checkarrayindex(freppages,avalue); + include(fstate,rs_activepageset); + factivepage:= avalue; +end; + +procedure tcustomreport.finish; +begin + include(fstate,rs_finish); +end; + +procedure tcustomreport.doprogress; +begin + if canevent(tmethod(fonprogress)) then begin + application.lock; + try + fonprogress(self); + finally + application.unlock; + end; + end; + if (fthread = nil) and (reo_waitdialog in foptions) and not canceled then begin + application.processmessages; + end; +end; + +procedure tcustomreport.doasyncevent(var atag: integer); +begin + inherited; + if (atag = endrendertag) then begin + try + if canevent(tmethod(fonreportfinished)) then begin + fonreportfinished(self); + end; + if canevent(tmethod(fonrenderfinish)) then begin + fonrenderfinish(self); + end; +// exclude(fstate,rs_running); + finally + if reo_autorelease in foptions then begin + release; + end; + end; + end; +end; + +procedure tcustomreport.notification(acomponent: tcomponent; + operation: toperation); +begin + inherited; + if assigned(fonrenderfinish) and + (tmethod(fonrenderfinish).data = pointer(acomponent)) then begin + fonrenderfinish:= nil; + end; +end; + +procedure tcustomreport.setfont(const avalue: trepfont); +begin + ffont.assign(avalue); +end; + +function tcustomreport.getfont: trepfont; +begin +{$warnings off} + result:= trepfont(ffont); //has no parent font +{$warnings on} +end; + +function tcustomreport.getfontclass: widgetfontclassty; +begin + result:= nil; //static font +end; + +function tcustomreport.getdialogcaption: msestring; +begin + result:= fdialogcaption; + if result = '' then begin + result:= 'Report' + end; +end; + +function tcustomreport.getdialogtext: msestring; +begin + result:= fdialogtext; + if result = '' then begin + result:= 'Rendering...' + end; +end; + +function tcustomreport.prepass: boolean; +begin + result:= not (rs_endpass in fstate); +end; + +procedure tcustomreport.restart; +var + int1: integer; +begin + include(fstate,rs_restart); + for int1:= 0 to high(freppages) do begin + freppages[int1].restart; + end; + activepage:= 0; +end; + +procedure tcustomreport.recordchanged; +begin + freppages[factivepage].recordchanged; +end; + +procedure tcustomreport.dopagebeforerender(const sender: tcustomreportpage; + var empty: boolean); +begin + if canevent(tmethod(fonpagebeforerender)) then begin + application.lock; + try + fonpagebeforerender(sender,empty); + finally + application.unlock; + end; + end; +end; + +procedure tcustomreport.dopageafterpaint(const sender: tcustomreportpage; + const acanvas: tcanvas); +begin + if canevent(tmethod(fonpageafterpaint)) then begin + application.lock; + try + fonpageafterpaint(sender,acanvas); + finally + application.unlock; + end; + end; +end; + +procedure tcustomreport.dopagepaint(const sender: tcustomreportpage; + const acanvas: tcanvas); +begin + if canevent(tmethod(fonpagepaint)) then begin + application.lock; + try + fonpagepaint(sender,acanvas); + finally + application.unlock; + end; + end; +end; + +procedure tcustomreport.setpagewidth(const avalue: real); +begin + if fpagewidth <> avalue then begin + fpagewidth:= avalue; + updatepagesize; + end; +end; + +procedure tcustomreport.setpageheight(const avalue: real); +begin + if fpageheight <> avalue then begin + fpageheight:= avalue; + updatepagesize; + end; +end; + +procedure tcustomreport.updatepagesize; +var + int1: integer; +begin + if not (csloading in componentstate) then begin + for int1:= 0 to high(freppages) do begin + with freppages[int1] do begin + if (fpagewidth = 0) or (fpageheight = 0) then begin + updatepagesize(); + end; + end; + end; + end; +end; + +{ +procedure tcustomreport.notifycontrols; +var + int1: integer; +begin + if running then begin + application.lock; + try + for int1:= 0 to high(fdatasets) do begin + try + fdatasets[int1].enablecontrols; + finally + fdatasets[int1].disablecontrols; + end; + end; + finally + application.unlock; + end; + end; +end; +} + {treport} + +constructor treport.create(aowner: tcomponent); +begin + create(aowner,true); +end; + +constructor treport.create(aowner: tcomponent; load: boolean); +begin + include(fmsecomponentstate,cs_ismodule); + inherited create(aowner); + if load and not (csdesigning in componentstate) and + (cs_ismodule in fmsecomponentstate) then begin + loadmsemodule(self,treport); + end; + + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; + if not load then begin + doafterload; + end; +end; + +destructor treport.destroy; +var + bo1: boolean; +begin + bo1:= csdesigning in componentstate; + inherited; //csdesigningflag is removed + if not bo1 and candestroyevent(tmethod(fondestroyed)) then begin + fondestroyed(self); + end; +end; + +procedure treport.setstatfile(const avalue: tstatfile); +begin + setlinkedvar(avalue,tmsecomponent(fstatfile)); +end; + +procedure treport.beforedestruction; +begin + if (fstatfile <> nil) and (reo_autowritestat in foptions) and + not (csdesigning in componentstate) then begin + fstatfile.writestat; + end; + inherited; + if candestroyevent(tmethod(fondestroy)) then begin + fondestroy(self); + end; +end; + +procedure treport.afterconstruction; +begin + inherited; + if assigned(foncreated) then begin + foncreated(self); + end; +end; + +procedure treport.doafterload; +begin + inherited; + autoreadstat; + if canevent(tmethod(fonloaded)) then begin + fonloaded(self); + end; +end; + +procedure treport.dooncreate; +begin + if not (cs_inheritedloading in msecomponentstate) then begin + include(factstate,acs_dooncreatecalled); + if assigned(foncreate) then begin //csloading possibly set + foncreate(self); + end; + end; +end; + +class function treport.getmoduleclassname: string; +begin + result:= 'treport'; +end; + +class function treport.hasresource: boolean; +begin + result:= self <> treport; +end; + +procedure treport.readstate(reader: treader); +begin + inherited; + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; +end; + +procedure treport.reload; +begin + name:= ''; + reloadmsecomponent(self); +end; + +procedure treport.autoreadstat; +begin + if (fstatfile <> nil) and not (csdesigning in componentstate) and + (foptions*[reo_autoreadstat,reo_delayedreadstat] = + [reo_autoreadstat]) then begin + fstatfile.readstat; + end; +end; + +{ treppageform } + +constructor treppageform.create(aowner: tcomponent); +begin + create(aowner,true); +end; + +constructor treppageform.create(aowner: tcomponent; load: boolean); +begin + initrepdesigninfo(frepdesigninfo); + include(fmsecomponentstate,cs_ismodule); + inherited create(aowner); + color:= cl_transparent; + createfont(); + if load and not (csdesigning in componentstate) and + (cs_ismodule in fmsecomponentstate) then begin + loadmsemodule(self,treport); + end; +end; + +class function treppageform.getmoduleclassname(): string; +begin + result:= 'treppageform'; +end; + +class function treppageform.hasresource(): boolean; +begin + result:= self <> treppageform; +end; + +function treppageform.getgrid_show: boolean; +begin + result:= frepdesigninfo.showgrid; +end; + +procedure treppageform.setgrid_show(const avalue: boolean); +begin + frepdesigninfo.showgrid:= avalue; + designchanged; +end; + +function treppageform.getgrid_snap: boolean; +begin + result:= frepdesigninfo.snaptogrid; +end; + +procedure treppageform.setgrid_snap(const avalue: boolean); +begin + frepdesigninfo.snaptogrid:= avalue; + designchanged; +end; + +function treppageform.getgrid_size: real; +begin + result:= frepdesigninfo.gridsize; +end; + +procedure treppageform.setgrid_size(avalue: real); +begin + if avalue < 2/ppmm then begin + avalue:= 2/ppmm; + end; + frepdesigninfo.gridsize:= avalue; + designchanged; +end; + +procedure treppageform.writerepdesigninfo(writer: twriter); +begin + writerectty(writer,frepdesigninfo.widgetrect); +end; + +procedure treppageform.readrepdesigninfo(reader: treader); +begin + frepdesigninfo.widgetrect:= readrectty(reader); +end; + +procedure treppageform.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('repdesigninfo',@readrepdesigninfo, + @writerepdesigninfo,true); +end; + +{ tcustomrepvaluedisp } + +constructor tcustomrepvaluedisp.create(aowner: tcomponent); +begin + ftextflags:= defaultrepvaluedisptextflags; + foptionsscale:= defaultrepvaluedispoptionsscale; + inherited; + foptions:= defaultrepvaluedispoptions; + foptionsscale:= defaultrepvaluedispoptionsscale; + fanchors:= [an_left,an_top]; +end; + +procedure tcustomrepvaluedisp.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + drawtext(acanvas,getdisptext,textarea,ftextflags,font); +end; + +procedure tcustomrepvaluedisp.dogettext(var atext: msestring); +begin + if canevent(tmethod(fongettext)) then begin + fongettext(self,atext); + end; +end; + +function tcustomrepvaluedisp.getdisptext: msestring; +begin + result:= msestring(name); + dogettext(result); +end; + +procedure tcustomrepvaluedisp.setformat(const avalue: msestring); +begin + if fformat <> avalue then begin + fformat:= avalue; + minclientsizechanged; + end; +// invalidate; +end; + +procedure tcustomrepvaluedisp.settextflags(const avalue: textflagsty); +begin + if ftextflags <> avalue then begin + ftextflags:= avalue; + minclientsizechanged; + end; +end; + +function tcustomrepvaluedisp.calcminscrollsize: sizety; +var + size1: sizety; +begin + result:= inherited calcminscrollsize; + size1:= textrect(getcanvas,getdisptext,innerclientrect,ftextflags,font).size; + if fframe <> nil then begin + with fframe do begin + size1.cx:= size1.cx + framei_left + framei_right; + size1.cy:= size1.cy + framei_top + framei_bottom; + end; + end + else begin + size1.cx:= size1.cx + 2*ftextframe; + size1.cy:= size1.cy + 2*ftextframe; + end; + if size1.cx > result.cx then begin + result.cx:= size1.cx; + end; + if size1.cy > result.cy then begin + result.cy:= size1.cy; + end; +end; + +procedure tcustomrepvaluedisp.render(const acanvas: tcanvas; + var empty: boolean); +begin + inherited; +// empty:= true; +end; + +{ trepvaluedisp } + +procedure trepvaluedisp.setvalue(const avalue: msestring); +begin +// if fvalue <> avalue then begin + fvalue:= avalue; + minclientsizechanged; +// end; +end; + +function trepvaluedisp.getdisptext: msestring; +begin + result:= fvalue; + if (csdesigning in componentstate) and (result = '') then begin + result:= msestring(name); + end; + if rendering then begin + dogettext(result); + end; +end; + +procedure trepvaluedisp.dobeforerender(var empty: boolean); +begin + inherited; + minclientsizechanged; +end; + +{ treppagenumdisp } + +constructor treppagenumdisp.create(aowner: tcomponent); +begin + foffset:= 1; + inherited; +end; + +function treppagenumdisp.getdisptext: msestring; +var + int1,int2: integer; + mstr1: msestring; + squote,dquote: boolean; +begin + if fparentintf <> nil then begin + squote:= false; + dquote:= false; + mstr1:= fformat; + for int1:= 1 to length(fformat) do begin + case fformat[int1] of + '''': begin + if not dquote then begin + squote:= not squote; + end; + end; + '"': begin + if not squote then begin + dquote:= not dquote; + end; + end; + '1': begin + if not (squote or dquote) then begin + + if bo_localvalue in foptions then begin + int2:= fparentintf.getlastpagepagecount; + end + else begin + int2:= fparentintf.getlastreppagecount; + end; + mstr1:= copy(fformat,1,int1-1) + '"' +inttostrmse(int2) +'"' + + copy(fformat,int1+1,bigint); + end; + end; + end; + end; + if bo_localvalue in foptions then begin + int1:= fparentintf.pagepagenum; + end + else begin + int1:= fparentintf.reppagenum + end; + result:= formatfloatmse(int1+foffset,mstr1); + dogettext(result); + end + else begin + result:= inherited getdisptext; + end; +end; + +procedure treppagenumdisp.setoffset(const avalue: integer); +begin + if foffset <> avalue then begin + foffset:= avalue; + minclientsizechanged; + end; +end; + +procedure treppagenumdisp.initpage; +begin + inherited; + minclientsizechanged; +end; + +procedure treppagenumdisp.parentchanged; +begin + inherited; + minclientsizechanged; +end; + +{ trepprintdatedisp } + +function trepprintdatedisp.getdisptext: msestring; +var + ti1: tdatetime; + str1: msestring; +begin + if fparentintf <> nil then begin + if bo_localvalue in foptions then begin + ti1:= fparentintf.pageprintstarttime; + end + else begin + ti1:= fparentintf.repprintstarttime; + end; + if fformat = '' then begin + str1:= 'c'; + end + else begin + str1:= fformat; + end; + result:= mseformatstr.datetimetostring(ti1,str1); +// result:= formatdatetime(str1,ti1); + dogettext(result); + end + else begin + result:= inherited getdisptext; + end; +end; + +procedure trepprintdatedisp.initpage; +begin + inherited; + minclientsizechanged; +end; + +procedure trepprintdatedisp.parentchanged; +begin + inherited; + minclientsizechanged; +end; + +{ trepwidgetfont } + +constructor trepwidgetfont.create; +begin + inherited; + finfo.baseinfo.color:= defaultrepfontcolor; + finfo.baseinfo.name:= defaultrepfontname; +end; + +procedure trepwidgetfont.setname(const avalue: string); +begin + if avalue = '' then begin + inherited setname(defaultrepfontname); + end + else begin + inherited; + end; +end; + +{ trepfont } + +constructor trepfont.create; +begin + inherited; + finfo.baseinfo.color:= defaultrepfontcolor; + finfo.baseinfo.name:= defaultrepfontname; +end; + +procedure trepfont.setname(const avalue: string); +begin + if avalue = '' then begin + inherited setname(defaultrepfontname); + end + else begin + inherited; + end; +end; +(* +{ tcustomreplookupdisp } + +constructor tcustomreplookupdisp.create(aowner: tcomponent); +begin + fkeydatalink:= treplookupdatalink.create(self); + inherited; +end; + +destructor tcustomreplookupdisp.destroy; +begin + fkeydatalink.free; + inherited; +end; + +procedure tcustomreplookupdisp.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); + change; +end; + +function tcustomreplookupdisp.getdatasource(const aindex: integer): tdatasource; +begin + result:= keydatasource; +end; + +procedure tcustomreplookupdisp.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + setlength(fieldtypes,1); + fieldtypes[0]:= integerfields; +end; + +function tcustomreplookupdisp.getkeydatasource: tdatasource; +begin + result:= fkeydatalink.datasource; +end; + +procedure tcustomreplookupdisp.setkeydatasource(const avalue: tdatasource); +begin + fkeydatalink.datasource:= avalue; +end; + +function tcustomreplookupdisp.getkeydatafield: string; +begin + result:= fkeydatalink.fieldname; +end; + +procedure tcustomreplookupdisp.setkeydatafield(const avalue: string); +begin + fkeydatalink.fieldname:= avalue; +end; + +procedure tcustomreplookupdisp.setlookupkeyfieldno(const avalue: integer); +begin + if avalue <> flookupkeyfieldno then begin + flookupkeyfieldno:= avalue; + change; + end; +end; + +procedure tcustomreplookupdisp.setlookupvaluefieldno(const avalue: integer); +begin + if avalue <> flookupvaluefieldno then begin + flookupvaluefieldno:= avalue; + change; + end; +end; + +procedure tcustomreplookupdisp.change; +begin + minclientsizechanged; +end; + +procedure tcustomreplookupdisp.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + change; + end; +end; + +procedure tcustomreplookupdisp.settextdefault(const avalue: msestring); +begin + ftextdefault:= avalue; + change; +end; + +function tcustomreplookupdisp.getdisptext: msestring; +begin + result:= ''; + if fkeydatalink.fieldactive then begin + keyvalue:= fkeydatalink.field.asinteger; + result:= flookuptext; + end; + if (result = '') and (csdesigning in componentstate) then begin + result:= ftextdefault; + if result = '' then begin + result:= inherited getdisptext; + end; + end + else begin + dogettext(result); + end; +end; + +procedure tcustomreplookupdisp.setkeyvalue(const avalue: integer); +begin + fkeyvalue:= avalue; + if flookupbuffer <> nil then begin + flookuptext:= getlookuptext; + end + else begin + flookuptext:= ''; + end; +end; + +function tcustomreplookupdisp.getlookuptext: msestring; +begin + result:= name; +end; + +{ treplookupdatalink } + +constructor treplookupdatalink.create(const aowner: tcustomreplookupdisp); +begin + fowner:= aowner; + inherited create; +end; + +procedure treplookupdatalink.recordchanged(afield: tfield); +begin + if (afield = nil) or (afield = field) then begin + fowner.change; + end; +end; + +{ trepstringdisplb } + +function trepstringdisplb.getlookuptext: msestring; +begin + result:= flookupbuffer.lookuptext(flookupkeyfieldno,flookupvaluefieldno, + fkeyvalue); +end; + +{ trepintegerdisplb } + +constructor trepintegerdisplb.create(aowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +function trepintegerdisplb.getlookuptext: msestring; +var + int1: integer; +begin + int1:= flookupbuffer.lookupinteger(flookupkeyfieldno,flookupvaluefieldno, + fkeyvalue); + result:= intvaluetostr(int1,fbase,fbitcount) +end; + +procedure trepintegerdisplb.setbase(const avalue: numbasety); +begin + fbase:= avalue; + change; +end; + +procedure trepintegerdisplb.setbitcount(const avalue: integer); +begin + fbitcount:= avalue; + change; +end; + +{ treprealdisplb } + +function treprealdisplb.getlookuptext: msestring; +var + rea1: realty; +begin + rea1:= flookupbuffer.lookupfloat(flookupkeyfieldno,flookupvaluefieldno, + fkeyvalue); + result:= realtytostring(rea1,fformat) +end; + +{ trepdatetimedisplb } + +constructor trepdatetimedisplb.create(aowner: tcomponent); +begin + fkind:= dtk_date; + inherited; +end; + +function trepdatetimedisplb.getlookuptext: msestring; +var + dat1: tdatetime; +begin + dat1:= flookupbuffer.lookupfloat(flookupkeyfieldno,flookupvaluefieldno, + fkeyvalue); + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure trepdatetimedisplb.setkind(const avalue: datetimekindty); +begin + fkind:= avalue; + change; +end; +*) + +{ tcustombandarea } + +procedure tcustombandarea.init; +begin + factiveband:= 0; + inherited; +end; + +procedure tcustombandarea.initband; +begin + if not (bao_nopagerestart in foptions) then begin + factiveband:= 0; + end; + inherited; +end; + +procedure tcustombandarea.initareapage; +begin + facty:= innerclientwidgetpos.y + bounds_y; + fbandnum:= 0; + inherited; +end; + +function tcustombandarea.render(const acanvas: tcanvas): boolean; +var //true if finished + bo1,bo2: boolean; + int1,int2: integer; + isfinished: boolean; + band1: tcustomrecordband; + activebandhaddata: boolean; +begin + result:= true; + if not (bas_inited in fstate) then begin + init; + dofirstarea; + end; + try + if factiveband <= high(fareabands) then begin + updatevisible; + dobeforerender; + isfinished:= true; + activebandhaddata:= false; + while (factiveband <= high(fareabands)) and not areafull do begin + exclude(fstate,bas_bandstarted); + while (factiveband <= high(fareabands)) and + not fareabands[factiveband].visible do begin + inc(factiveband); + end; + if factiveband <= high(fareabands) then begin + exclude(fstate,bas_activebandchanged); + with fareabands[factiveband] do begin + if not (bas_finished in self.fstate) then begin + bo2:= odd(fparentintf.reppagenum); + bo2:= bo2 and (bo_oddpage in foptions) or + not bo2 and (bo_evenpage in foptions); //has data + end + else begin + bo2:= false; + end; + bo1:= ((rbs_showed in fstate) or not(bo_once in foptions)) and + ((rbs_pageshowed in fstate) or not bo2); //empty + render(acanvas,bo1); + activebandhaddata:= activebandhaddata or not bo1; + if bas_activebandchanged in self.fstate then begin + updatevisible; + activebandhaddata:= false; + continue; + end; + if not bo2 then begin + isfinished:= bo1; + end; + bo1:= bo1 or bo2; + result:= result and bo1; + if bo1 then begin //empty + band1:= nil; + if not activebandhaddata and (fnextbandifempty <> nil) then begin + band1:= fnextbandifempty; + end + else begin + if fnextbandiflast <> nil then begin + band1:= fnextbandiflast; + end; + end; + if band1 <> nil then begin + for int1:= 0 to high(fareabands) do begin + if fareabands[int1] = band1 then begin + for int2:= int1 to factiveband do begin + exclude(fareabands[int2].fstate,rbs_showed); + end; + factiveband:= int1-1; + break; + end; + end; + end; + repeat + inc(factiveband); + until (factiveband > high(fareabands)) or fareabands[factiveband].visible; + activebandhaddata:= false; + end + else begin + band1:= nil; + if bas_areafull in self.fstate then begin + if fnextbandiflastofarea <> nil then begin + band1:= fnextbandiflastofarea; + end; + end + else begin + if (fnextband <> nil) and + not (fdatalink.active and fdatalink.dataset.eof) then begin + band1:= fnextband; + end; + end; + if band1 <> nil then begin + for int1:= 0 to high(fareabands) do begin + if fareabands[int1] = band1 then begin + for int2:= int1 to factiveband do begin + exclude(fareabands[int2].fstate,rbs_showed); + end; + factiveband:= int1; + while (factiveband <= high(fareabands)) and + not fareabands[factiveband].visible do begin + inc(factiveband); + end; + activebandhaddata:= false; + break; + end; + end; + end; + end; + end; + end; + end; + if isfinished then begin + include(fstate,bas_finished); + end; + end; + finally + if result then begin + exclude(fstate,bas_inited); + end; + end; + if bas_backgroundrendered in fstate then begin + doafterpaint1(acanvas); + if canevent(tmethod(fonafterrender)) then begin + application.lock; + try + fonafterrender(self); + finally + application.unlock; + end; + end; + end; + if result and canevent(tmethod(fonlastarea)) then begin + application.lock; + try + fonlastarea(self); + finally + application.unlock; + end; + end; +end; + +function tcustombandarea.beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; + //true if area full +var + bo1: boolean; + pt1: pointty; +begin + result:= bas_areafull in fstate; + if not result then begin + fsaveindex:= acanvas.save; + bo1:= (bas_backgroundrendered in fstate); + if not bo1 then begin + include(fstate,bas_backgroundrendered); + renderbackground(acanvas); + initareapage; + end; + if frecordband <> nil then begin + pt1.x:= sender.bounds_x + forigin.x; + pt1.y:= forigin.y + facty - sender.bounds_y; + end + else begin + pt1:= makepoint(sender.bounds_x+bounds_x,facty); + end; + acanvas.origin:= pt1; + factybefore:= facty; + inc(facty,sender.bandheight); + include(fstate,bas_bandstarted); + result:= bo1 and checkareafull(facty); + //print minimum one band + end; + if result then begin + include(fstate,bas_areafull); + initareapage; + end; +end; + +procedure tcustombandarea.endband(const acanvas: tcanvas; + const sender: tcustomrecordband); +begin + acanvas.restore(fsaveindex); + include(fstate,bas_notfirstband); + exclude(fstate,bas_top); + sender.fstate:= sender.fstate + [rbs_showed,rbs_pageshowed]; + inc(fbandnum); +end; + +function tcustombandarea.getacty: integer; +begin + if (bas_bandstarted in fstate) then begin + result:= factybefore; + end + else begin + result:= facty; + end; + result:= result - (innerclientwidgetpos.y + bounds_y); +end; + +function tcustombandarea.remainingheight: integer; +begin + result:= facty - (bounds_y + bounds_cy); + if fframe <> nil then begin + result:= result - fframe.innerframe.bottom; + end; +end; + +procedure tcustombandarea.restart; +begin + factiveband:= 0; + include(fstate,bas_activebandchanged); + inherited; +end; + +function tcustombandarea.isfirstband: boolean; +begin + result:= (factiveband <= high(fareabands)) and + not (rbs_pageshowed in fareabands[factiveband].fstate); +// result:= not (bas_notfirstband in fstate); +end; + +function tcustombandarea.islastband(const addheight: integer = 0): boolean; +var + int1: integer; +begin + result:= fstate * [bas_lastband{,bas_lastchecking}] <> []; + if not result and (factiveband <= high(fareabands)) then begin + with fareabands[factiveband] do begin + int1:= facty + addheight + lastbandheight; + if not (bas_bandstarted in self.fstate) then begin + int1:= int1 + bounds_cy; + end; + end; + result:= checkareafull(int1); + end; +end; + +{ tcustomtilearea } + +constructor tcustomtilearea.create(aowner: tcomponent); +begin + fcolcount:= 2; + frowcount:= 2; + flivert:= defaulttablineinfo; + flihorz:= defaulttablineinfo; + flileft:= defaulttablineinfo; + flitop:= defaulttablineinfo; + fliright:= defaulttablineinfo; + flibottom:= defaulttablineinfo; + inherited; +end; + +function tcustomtilearea.cellwidthmm: real; +begin + result:= innerclientsize.cx / (getppmm * fcolcount); +end; + +function tcustomtilearea.cellheightmm: real; +begin + result:= innerclientsize.cy / (getppmm * frowcount); +end; + +function tcustomtilearea.cellsize: sizety; +begin + result:= innerclientsize; + result.cx:= (result.cx + fcolcount div 2) div fcolcount; + result.cy:= (result.cy + frowcount div 2) div frowcount; +end; + +function tcustomtilearea.cellrect: rectty; +begin + result.pos:= innerclientpos; + result.size:= cellsize; +end; + +function tcustomtilearea.render(const acanvas: tcanvas): boolean; +var //true if finished + bo1,bo2: boolean; + int1{,int2}: integer; + isfinished: boolean; + col,row: integer; + cellwidthmm1,cellheightmm1: real; +// y: real; +begin + result:= true; + if not (bas_inited in fstate) then begin + init; + dofirstarea; + end; + col:= 0; + row:= 0; + cellwidthmm1:= cellwidthmm; + cellheightmm1:= cellheightmm; + try + updatevisible; + dobeforerender; + isfinished:= true; + repeat + fcellorigin.x:= round(col*cellwidthmm1*getppmm); + fcellorigin.y:= round(row*cellheightmm1*getppmm); + isfinished:= true; + for int1:= 0 to high(fareabands) do begin + with fareabands[int1] do begin + if visible then begin + if not (bas_finished in self.fstate) then begin + bo2:= odd(fparentintf.reppagenum); + bo2:= bo2 and (bo_oddpage in foptions) or + not bo2 and (bo_evenpage in foptions); //has data + end + else begin + bo2:= false; //has no autodata + end; + bo1:= ((rbs_showed in fstate) or not(bo_once in foptions)) and + ((rbs_pageshowed in fstate) or not bo2); //empty + render(acanvas,bo1); + if not bo2 then begin + isfinished:= isfinished and bo1; + end; + bo1:= bo1 or bo2; + result:= result and bo1; + end; + end; + end; + if isfinished then begin + include(fstate,bas_finished); + end; + if tao_vertical in foptions then begin + inc(row); + if row >= frowcount then begin + row:= 0; + inc(col); + if col >= fcolcount then begin + break; + end; + end; + end + else begin + inc(col); + if col >= fcolcount then begin + col:= 0; + inc(row); + if row >= frowcount then begin + break; + end; + end; + end; + until isfinished; + finally + if result then begin + exclude(fstate,bas_inited); + end; + end; + if bas_backgroundrendered in fstate then begin + acanvas.save; + try + if frecordband <> nil then begin + acanvas.move(forigin); + end + else begin + acanvas.move(pos); + end; + drawlines(acanvas); + doafterpaint1(acanvas); + finally + acanvas.restore; + end; + if canevent(tmethod(fonafterrender)) then begin + application.lock; + try + fonafterrender(self); + finally + application.unlock; + end; + end; + end; + if result and canevent(tmethod(fonlastarea)) then begin + application.lock; + try + fonlastarea(self); + finally + application.unlock; + end; + end; +end; + +procedure tcustomtilearea.setcolcount(const avalue: integer); +begin + fcolcount:= avalue; + if avalue <= 0 then begin + fcolcount:= 1; + end; + invalidate; +end; + +procedure tcustomtilearea.setrowcount(const avalue: integer); +begin + frowcount:= avalue; + if avalue <= 0 then begin + frowcount:= 1; + end; + invalidate; +end; + +function tcustomtilearea.beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; +var + bo1: boolean; + pt1: pointty; +begin + fsaveindex:= acanvas.save; + bo1:= (bas_backgroundrendered in fstate); + if not bo1 then begin + include(fstate,bas_backgroundrendered); + renderbackground(acanvas); + initareapage; + end; + pt1:= sender.pos; + if frecordband <> nil then begin + addpoint1(pt1,forigin); + end + else begin + addpoint1(pt1,pos); + end; + addpoint1(pt1,fcellorigin); + acanvas.origin:= pt1; + include(fstate,bas_bandstarted); + result:= false; +end; + +procedure tcustomtilearea.endband(const acanvas: tcanvas; + const sender: tcustomrecordband); +begin + acanvas.restore(fsaveindex); + include(fstate,bas_notfirstband); + exclude(fstate,bas_top); + sender.fstate:= sender.fstate + [rbs_showed,rbs_pageshowed]; +// inc(fbandnum); +end; + +procedure tcustomtilearea.setlivert_widthmm(const avalue: real); +begin + if avalue <> flivert.widthmm then begin + flivert.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlivert_color(const avalue: colorty); +begin + if avalue <> flivert.color then begin + flivert.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlivert_colorgap(const avalue: colorty); +begin + if avalue <> flivert.colorgap then begin + flivert.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlivert_capstyle(const avalue: capstylety); +begin + if avalue <> flivert.capstyle then begin + flivert.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlivert_dashes(const avalue: string); +begin + if avalue <> flivert.dashes then begin + flivert.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setlihorz_widthmm(const avalue: real); +begin + if avalue <> flihorz.widthmm then begin + flihorz.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlihorz_color(const avalue: colorty); +begin + if avalue <> flihorz.color then begin + flihorz.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlihorz_colorgap(const avalue: colorty); +begin + if avalue <> flihorz.colorgap then begin + flihorz.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlihorz_capstyle(const avalue: capstylety); +begin + if avalue <> flihorz.capstyle then begin + flihorz.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlihorz_dashes(const avalue: string); +begin + if avalue <> flihorz.dashes then begin + flihorz.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_widthmm(const avalue: real); +begin + if avalue <> flileft.widthmm then begin + flileft.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_color(const avalue: colorty); +begin + if avalue <> flileft.color then begin + flileft.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_colorgap(const avalue: colorty); +begin + if avalue <> flileft.colorgap then begin + flileft.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_capstyle(const avalue: capstylety); +begin + if avalue <> flileft.capstyle then begin + flileft.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_dashes(const avalue: string); +begin + if avalue <> flileft.dashes then begin + flileft.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_dist(const avalue: integer); +begin + if avalue <> flileft.dist then begin + flileft.dist:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_widthmm(const avalue: real); +begin + if avalue <> flitop.widthmm then begin + flitop.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_color(const avalue: colorty); +begin + if avalue <> flitop.color then begin + flitop.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_colorgap(const avalue: colorty); +begin + if avalue <> flitop.colorgap then begin + flitop.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_capstyle(const avalue: capstylety); +begin + if avalue <> flitop.capstyle then begin + flitop.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_dashes(const avalue: string); +begin + if avalue <> flitop.dashes then begin + flitop.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_dist(const avalue: integer); +begin + if avalue <> flitop.dist then begin + flitop.dist:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_widthmm(const avalue: real); +begin + if avalue <> fliright.widthmm then begin + fliright.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_color(const avalue: colorty); +begin + if avalue <> fliright.color then begin + fliright.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_colorgap(const avalue: colorty); +begin + if avalue <> fliright.colorgap then begin + fliright.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_capstyle(const avalue: capstylety); +begin + if avalue <> fliright.capstyle then begin + fliright.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_dashes(const avalue: string); +begin + if avalue <> fliright.dashes then begin + fliright.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_dist(const avalue: integer); +begin + if avalue <> fliright.dist then begin + fliright.dist:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_widthmm(const avalue: real); +begin + if avalue <> flibottom.widthmm then begin + flibottom.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_color(const avalue: colorty); +begin + if avalue <> flibottom.color then begin + flibottom.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_colorgap(const avalue: colorty); +begin + if avalue <> flibottom.colorgap then begin + flibottom.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_capstyle(const avalue: capstylety); +begin + if avalue <> flibottom.capstyle then begin + flibottom.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_dashes(const avalue: string); +begin + if avalue <> flibottom.dashes then begin + flibottom.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_dist(const avalue: integer); +begin + if avalue <> flibottom.dist then begin + flibottom.dist:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.drawline(const acanvas: tcanvas; const ainfo: tablineinfoty; + const start,stop: pointty); +begin + if ainfo.widthmm > 0 then begin + with acanvas do begin + linewidthmm:= ainfo.widthmm; + colorbackground:= ainfo.colorgap; + capstyle:= ainfo.capstyle; + dashes:= ainfo.dashes; + acanvas.drawline(start,stop,ainfo.color); + end; + end + else begin + if csdesigning in componentstate then begin + with acanvas do begin + linewidth:= 0; + dashes:= #2#3; + capstyle:= cs_butt; + acanvas.drawline(start,stop,cl_black); + end; + end; + end; +end; + +procedure tcustomtilearea.drawlines(const acanvas: tcanvas); +var + rect1: rectty; + pt1,pt2: pointty; + int1: integer; + cellh,cellv: real; +begin + acanvas.save; + acanvas.addcliprect(inflaterect(widgetsizerect,1000)); + rect1:= innerwidgetrect; + with rect1 do begin + cellh:= cellwidthmm * getppmm; + cellv:= cellheightmm * getppmm; + + pt1.y:= y - flitop.dist; + pt2.y:= y + cy + flibottom.dist; + for int1:= 1 to fcolcount - 1 do begin + pt1.x:= x + round(int1 * cellh); + pt2.x:= pt1.x; + drawline(acanvas,flivert,pt1,pt2); + end; + + pt1.x:= x - flileft.dist; + pt2.x:= x + cx + fliright.dist; + for int1:= 1 to frowcount - 1 do begin + pt1.y:= y + round(int1 * cellv); + pt2.y:= pt1.y; + drawline(acanvas,flihorz,pt1,pt2); + end; + + pt1.y:= y - flitop.dist; + pt2.y:= pt1.y; + drawline(acanvas,flitop,pt1,pt2); + pt1.y:= y + cy + flibottom.dist; + pt2.y:= pt1.y; + drawline(acanvas,flibottom,pt1,pt2); + + pt1.y:= y - flitop.dist; + pt2.y:= y + cy + flibottom.dist; + pt1.x:= x - flileft.dist; + pt2.x:= pt1.x; + drawline(acanvas,flileft,pt1,pt2); + pt1.x:= x + cx + fliright.dist; + pt2.x:= pt1.x; + drawline(acanvas,fliright,pt1,pt2); + end; + + acanvas.restore; +end; + +procedure tcustomtilearea.dopaintoverlay(const canvas: tcanvas); +begin + if not rendering then begin + drawlines(canvas); + end; + inherited; +end; + +{ trepwidgetframe } + +constructor trepwidgetframe.create(const aintf: icaptionframe); +begin + inherited; + inflateframe1(fi.innerframe,1); + internalupdatestate; +end; + +end. diff --git a/mseide-msegui/lib/common/report/mserepps.pas b/mseide-msegui/lib/common/report/mserepps.pas new file mode 100644 index 0000000..11725da --- /dev/null +++ b/mseide-msegui/lib/common/report/mserepps.pas @@ -0,0 +1,322 @@ +{ MSEgui Copyright (c) 2016-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mserepps; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,msereport,msestrings,msepostscriptprinter,msegraphics,mclasses, + msegraphutils,msegui,msemenus,mseguiglob; +type + optionpsty = (ops_noheadercomments,ops_noshowpage); + optionspsty = set of optionpsty; + layoutflagty = (la_right,la_bottom,la_xcentered,la_ycentered, + la_stretchx,la_stretchy,la_fit, + la_mirrorx,la_mirrory,la_rotate90,la_rotate180); + layoutflagsty = set of layoutflagty; + +const + defaultoptionsps = [ops_noheadercomments,ops_noshowpage]; + +type +// +//todo: use ps text from datafield +// + treppsdisp = class(tcustomrecordband) + private + fpsfile: filenamety; + foptionsps: optionspsty; + flayout: layoutflagsty; + fscale: flo64; + fshifthorz: flo64; + fshiftvert: flo64; + procedure setlayout(const avalue: layoutflagsty); + protected + procedure render(const acanvas: tcanvas; var empty: boolean) override; + public + constructor create(aowner: tcomponent); override; + published + property anchors default [an_left,an_top]; + property psfile: filenamety read fpsfile write fpsfile; + property optionsps: optionspsty read foptionsps write foptionsps + default defaultoptionsps; + property layout: layoutflagsty read flayout + write setlayout default []; + property scale: flo64 read fscale write fscale; + property shifthorz: flo64 read fshifthorz write fshifthorz; //mm + property shiftvert: flo64 read fshiftvert write fshiftvert; //mm +// property value: msestring read fvalue write setvalue; + property font; +// property tabs; +// property datasource; +// property textflags; + property options; + property optionsshow; + property optionsscale; + property visidatasource; + property visidatafield; + property visigroupfield; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property zebra_options; + property onfontheightdelta; + property onlayout; + + property onbeforerender; + property onbeforepaint; + property onpaint; + property onafterpaint; + property onafterrender; +// property ongettext; + end; + +implementation +uses + msestream,msesys,mseformatstr,msebits,mseprinter; + +{ treppsdisp } + +constructor treppsdisp.create(aowner: tcomponent); +begin + foptionsps:= defaultoptionsps; + fscale:= 1; + inherited; + fanchors:= [an_left,an_top]; +end; + +procedure treppsdisp.setlayout(const avalue: layoutflagsty); +begin + flayout:= layoutflagsty( + setsinglebit(card32(avalue),card32(flayout), + [card32([la_xcentered,la_right]),card32([la_ycentered,la_bottom]), + card32([la_fit,la_stretchx]),card32([la_fit,la_stretchy])] + ) + ); +end; + +procedure treppsdisp.render(const acanvas: tcanvas; var empty: boolean); +const + nl = lineend; +var + stream1: ttextstream; + as1: ansistring; + b1,b2,inheader,hasbb: boolean; + ar1: stringarty; + bbll,bbur: pspointty; + destll,destur: pspointty; + pt1,pt2: pspointty; + destpos: pointty; + destsize: sizety; + mat1,mat2: psmatrixty; + f1,f2: flo64; +begin + b1:= rbs_showed in fstate; + inherited; + if visible and (fpsfile <> '') and not (rbs_prepass in fstate) and not b1 and + (acanvas is tpostscriptcanvas) then begin + stream1:= ttextstream.create(fpsfile,fm_read); + try + with tpostscriptcanvas(acanvas) do begin + pscommandbegin(); + inheader:= true; + hasbb:= false; + repeat + b1:= stream1.readstrln(as1); + b2:= (length(as1) >= 2) and (as1[1] = '%') and + ((as1[2] = '%') or (as1[2] = '!')); + if inheader then begin + if b2 then begin + if startsstr(pchar('BoundingBox:'),pchar(pointer(as1))+2) then begin + ar1:= splitstring(as1,' ',true); + if high(ar1) >= 4 then begin + if trystrtodouble(ar1[1],bbll.x,'.') and + trystrtodouble(ar1[2],bbll.y,'.') and + trystrtodouble(ar1[3],bbur.x,'.') and + trystrtodouble(ar1[4],bbur.y,'.') then begin + hasbb:= true; + end; + end; + end; + if (ops_noheadercomments in foptionsps) then begin + continue; //skip headercomment + end; + end + else begin + inheader:= false; + pscommandwrite('save'+nl); + if ops_noshowpage in foptionsps then begin +// pscommandwrite('/showpage_orig /showpage load def'+nl); + pscommandwrite('/showpage {} bind def'+nl); + //disable showpage command + mat1:= psunitymatrix; + if hasbb then begin + destpos:= addpoint(rootpos,innerclientwidgetpos); + destsize:= innerclientsize; + destll:= devpos(mp(destpos.x,destpos.y+destsize.cy)); + destur:= devpos(mp(destpos.x+destsize.cx,destpos.y)); + if la_mirrorx in flayout then begin + mat1[0,0]:= -1.0; + bbll.x:= -bbll.x; + bbur.x:= -bbur.x; + end; + if la_mirrory in flayout then begin + mat1[1,1]:= -1.0; + bbll.y:= -bbll.y; + bbur.y:= -bbur.y; + end; + f1:= 0; + if la_rotate90 in flayout then begin + f1:= f1 + pi/2; + end; + if la_rotate180 in flayout then begin + f1:= f1 + pi; + end; + if f1 <> 0.0 then begin + psrotate(mat1,f1); + mat2:= psunitymatrix; + psrotate(mat2,f1); + bbll:= pstransform(mat2,bbll); + bbur:= pstransform(mat2,bbur); + end; + psnormalizerect(bbll,bbur); + if la_fit in flayout then begin + f1:= bbur.x - bbll.x; + if f1 <> 0 then begin + f1:= (destur.x-destll.x) / f1; + f2:= bbur.y - bbll.y; + if f2 <> 0 then begin + f2:= (destur.y-destll.y) / f2; + if f2 < f1 then begin + f1:= f2; + end; + psscale(mat1,f1); + bbll.x:= bbll.x * f1; + bbll.y:= bbll.y * f1; + bbur.x:= bbur.x * f1; + bbur.y:= bbur.y * f1; + end; + end; + end + else begin + if la_stretchx in flayout then begin + f1:= bbur.x - bbll.x; + if f1 <> 0 then begin + f2:= destur.x - destll.x; + f1:= f2/f1; + psscalex(mat1,f1); + bbll.x:= bbll.x * f1; + bbur.x:= bbur.x * f1; + end; + end; + if la_stretchy in flayout then begin + f1:= bbur.y - bbll.y; + if f1 <> 0 then begin + f2:= destur.y - destll.y; + f1:= f2/f1; + psscaley(mat1,f1); + bbll.y:= bbll.y * f1; + bbur.y:= bbur.y * f1; + end; + end; + end; + if la_right in flayout then begin + pt1.x:= bbur.x; + pt2.x:= destur.x; + end + else begin + if la_xcentered in flayout then begin + pt1.x:= (bbll.x + bbur.x) / 2; + pt2.x:= (destll.x + destur.x) / 2; + end + else begin + pt1.x:= bbll.x; + pt2.x:= destll.x; + end; + end; + if la_bottom in flayout then begin + pt1.y:= bbll.y; + pt2.y:= destll.y; + end + else begin + if la_ycentered in flayout then begin + pt1.y:= (bbll.y + bbur.y) / 2; + pt2.y:= (destll.y + destur.y) / 2; + end + else begin + pt1.y:= bbur.y; + pt2.y:= destur.y; + end; + end; + pstranslate(mat1,psdist(pt1,pt2)); + psscale(mat1,fscale); + if la_right in flayout then begin + pt1.x:= destur.x * (1-fscale); //right + end + else begin + if flayout * [la_stretchx,la_xcentered,la_fit] <> [] then begin + pt1.x:= ((destll.x + destur.x) * (1-fscale)) / 2; + end + else begin //left + pt1.x:= destll.x * (1-fscale); + end; + end; + if flayout * [la_stretchy,la_ycentered, + la_fit,la_bottom] = [] then begin + pt1.y:= destur.y * (1-fscale); //top + end + else begin + if not (la_bottom in flayout) then begin + pt1.y:= ((destll.y + destur.y) * (1-fscale)) / 2; + end + else begin //bottom + pt1.y:= destll.y * (fscale - 1); + end; + end; + pt1.x:= pt1.x + mmtoprintscale* fshifthorz; + pt1.y:= pt1.y + mmtoprintscale* fshiftvert; + end + else begin + psscale(mat1,fscale); + pt1.x:= mmtoprintscale* fshifthorz; + pt1.y:= mmtoprintscale* fshiftvert; + end; + pstranslate(mat1,pt1); + pscommandwrite(psrealtostr(destll.x)+' '+psrealtostr(destll.y) + ' '+ + psrealtostr(destur.x-destll.x)+' '+ + psrealtostr(destur.y-destll.y)+' rectclip'+nl); + pscommandwrite(matrixstring(mat1)+' concat'+nl); + end; + end; + end + else begin + if b2 and (ops_noheadercomments in foptionsps) then begin + continue; + end; + end; + pscommandwrite(as1+c_return+c_linefeed); + until not b1; +// if (ops_noshowpage in foptionsps) and not inheader then begin +// pscommandwrite('/showpage /showpage_orig load def'+nl); +// //restore showpage command +// end; + pscommandwrite('restore'+nl); + pscommandend(); + end; + finally + stream1.destroy(); + end; + end + else begin + empty:= true; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/serialcomm/msecommport.pas b/mseide-msegui/lib/common/serialcomm/msecommport.pas new file mode 100644 index 0000000..845440f --- /dev/null +++ b/mseide-msegui/lib/common/serialcomm/msecommport.pas @@ -0,0 +1,2263 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msecommport; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses {$ifdef mswindows} windows,{$ifndef FPC} mmsystem,{$endif} + {$else} mselibc, + {$endif} + classes,mclasses,msethread,mseguiglob,msecommtimer,mseevent,mseclasses, + msesystypes,msestrings,msestat,msestatfile,msetypes,mseglob; + +type + commstatety = ( + coms_none, //0 + coms_ok, //1 + coms_working, //2 + coms_notopen, //3 + coms_abort, //4 + coms_timeout, //5 + coms_exception, //6 + coms_error, //7 + coms_bufferoverflow, //8 + coms_canceled, //9 + coms_unknown, //10 + coms_command, //11 + coms_parameter, //12 + coms_busy //13 + ); + + errorrecty = record + error: integer; + text: msestring; + end; + perrorrecty = ^errorrecty; + +const + defaulteorchar = c_linefeed; + + cpf_none = 0; + cpf_ok = 1; + cpf_working = 2; + cpf_notopen = 3; + cpf_abort = 4; + cpf_timeout = 5; + cpf_exception = 6; + cpf_error = 7; + cpf_bufferoverflow = 8; + cpf_canceled = 9; + + cpf_unknown = 10; //asciiprot errors + cpf_command = 11; + cpf_parameter = 12; + cpf_busy = 13; + cpf_user = 100; + + errortexte: array[commstatety] of errorrecty = + ( + (error: cpf_none; text: ''), + (error: cpf_ok; text: 'OK'), + (error: cpf_working; text: 'busy'), + (error: cpf_notopen; text: 'not open'), + (error: cpf_abort; text: 'abort'), + (error: cpf_timeout; text: 'timeout'), + (error: cpf_exception; text: 'exception'), + (error: cpf_error; text: 'error'), + (error: cpf_bufferoverflow; text: 'bufferoverflow'), + (error: cpf_canceled; text: 'canceled'), + (error: cpf_unknown; text: 'unknown'), + (error: cpf_command; text: 'command error'), + (error: cpf_parameter; text: 'paramter error'), + (error: cpf_busy; text: 'busy') + ); + + commerrors = ' 1 ok' + c_linefeed + + ' 2 working' + c_linefeed + + ' 3 port not open' + c_linefeed + + ' 4 abort' + c_linefeed + + ' 5 timeout' + c_linefeed + + ' 6 exception' + c_linefeed + + ' 7 error' + c_linefeed + + ' 8 bufferoverflow' + c_linefeed + + ' 9 canceled'; + +type + commnrty = (cnr_invalid=-1, + cnr_1,cnr_2,cnr_3,cnr_4,cnr_5,cnr_6,cnr_7,cnr_8,cnr_9); + commbaudratety = (cbr_50,cbr_75,cbr_110,cbr_134,cbr_150,cbr_200,cbr_300,cbr_600, + cbr_1200,cbr_1800,cbr_2400,cbr_4800,cbr_9600,cbr_19200, + cbr_38400,cbr_57600,cbr_115200); + commdatabitsty = (cdb_5,cdb_6,cdb_7,cdb_8); + commstopbitty = (csb_1,csb_2); + commparityty = (cpa_none,cpa_odd,cpa_even); + +const + {$ifdef UNIX} + + commname: array[commnrty] of string = + ('','ttyS0','ttyS1','ttyS2','ttyS3','ttyS4','ttyS5', + 'ttyS6','ttyS7','ttyS8'{,'ttyS9'}); + { + commname: array[commnrty] of string = + ('ttys0','ttys1','ttys2','ttys3','ttys4','ttys5', + 'ttys6','ttys7','ttys8'); + } + invalidfilehandle = ptruint(-1); + infinitemse = cardinal(-1); + B57600 = $1001; //0010001 + B115200 = $1002; //0010002 + commbaudflags: array[commbaudratety] of integer = + (B50,B75,B110,B134,B150,B200,B300,B600, + B1200,B1800,B2400,B4800,B9600,B19200, + B38400,B57600,B115200); + commdatabitflags: array[commdatabitsty] of integer = (cs5,cs6,cs7,cs8); + {$else} + commname: array[commnrty] of string = ('','COM1','COM2','COM3','COM4','COM5', + 'COM6','COM7','COM8','COM9'); + invalidfilehandle = INVALID_HANDLE_VALUE; + infinitemse = INFINITE; + {$endif} + commbittime: array[commbaudratety] of real = + (1/50,1/75,1/110,1/134,1/150,1/200,1/300,1/600, + 1/1200,1/1800,1/2400,1/4800,1/9600,1/19200, + 1/38400,1/57600,1/115200); + commbaudrates: array[commbaudratety] of integer = ( + 50,75,110,134,150,200,300,600, + 1200,1800,2400,4800,9600,19200, + 38400,57600,115200); + +type + + tcustomrs232 = class(tpersistent) + private + fowner: tmsecomponent; //can be nil + fhandle: ptruint; + fcommnr: commnrty; + frtstimevor: integer; //in us fuer halbduplex + frtstimenach: integer; + fhalfduplex: boolean; + fbaud: commbaudratety; + fstopbit: commstopbitty; + faparity: commparityty; + fbyteus: integer; + foncheckabort: checkeventty; + {$ifdef mswindows} + overlappedrx: toverlapped; + overlappedtx: toverlapped; + timer: tmmtimermse; + commtimeouts: tcommtimeouts; + {$endif} + fdatabits: commdatabitsty; + fcommname: filenamety; + fopenerror: int32; + procedure updatebyteinfo; + procedure Setbaud(const Value: commbaudratety); + procedure Setcommnr(const Value: commnrty); + procedure Setparity(const Value: commparityty); + procedure Setstopbit(const Value: commstopbitty); + function waitfortx(timeout: integer): boolean; //timeout in us + function defaulttimeout(us: longword; anzahl: integer; out timeout: longword): boolean; + // timeout in us 0 -> 2*uebertragungszeit, + // infinitemse -> kein timeout + {$ifdef mswindows} + procedure eotevent(sender: tobject); + function setreadnonblocked(const anonblocked: boolean): boolean; + {$endif} + procedure setdatabits(const avalue: commdatabitsty); + procedure setactive(const avalue: boolean); + procedure setcommname(const avalue: filenamety); + protected + fvmin: char; + fnoclosehandle: boolean; + fonopen: proceventty; + fonclose: proceventty; + function canevent(const aevent: tmethod): boolean; + function piperead(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean): boolean; + function pipewrite(const buffer; count: longint): longint; + public + constructor create(const aowner: tmsecomponent; //aowner can be nil + const aoncheckabort: checkeventty = nil); + destructor destroy; override; + function open: boolean; + procedure close; + function opened: boolean; + procedure reset; + procedure resetinput; + procedure resetoutput; + procedure setrts(active: boolean); + procedure setdtr(active: boolean); + function writestring(const dat: string; timeout: longword = 0; + waitforeot: boolean = false): boolean; + //timeout in us, wenn = 0 -> warten auf uebertragungsende, bei halbduplex sowiso + function readbuffer(anzahl: integer; out dat; + timeout: longword = 0): integer; + //list daten, true wenn gelungen, timeout in us 0 -> 2*uebertragungszeit + function readstring(anzahl: integer; out dat: string; + timeout: longword = infinitemse): boolean; + //list daten, true wenn gelungen, timeout in us 0 -> 2*uebertragungszeit + function readavailbuffer(const maxcount: integer; out dat): integer; + function readavailstring(const maxcount: integer): string; + + function transmissiontime(const acount: integer): longword; //bringt uebertragungszeit in us + property active: boolean read opened write setactive; + property openerror: int32 read fopenerror; + property handle: ptruint read fhandle; + property commnr: commnrty read Fcommnr write Setcommnr default cnr_1; + property commname: filenamety read fcommname write setcommname; + //overrides commnr + function commpath(): filenamety; + property baud: commbaudratety read Fbaud write Setbaud default cbr_9600; + property databits: commdatabitsty read fdatabits write setdatabits default cdb_8; + property stopbit: commstopbitty read Fstopbit write Setstopbit default csb_1; + property parity: commparityty read Faparity write Setparity default cpa_none; + property halfduplex: boolean read fhalfduplex write fhalfduplex default false; + property oncheckabort: checkeventty read foncheckabort; + property rtstimevor: integer read frtstimevor write frtstimevor; //in us + property rtstimenach: integer read frtstimenach write frtstimenach; //in us + property byteus: integer read fbyteus; + end; + + trs232 = class(tcustomrs232) + end; + + tcommevent = class; + commeventty = procedure(const sender: tcommevent) of object; + tcommthread = class; + + tcommevent = class(tmseevent) + private + fstate: commstatety; + fpersistent: boolean; + fsem: semty; + protected + procedure process(const thread: tcommthread; var ok: boolean); virtual; + procedure processed(const thread: tcommthread; var ok: boolean); virtual; + public + onerror: commeventty; //synchronized with maineventloop + onsuccess: commeventty; //synchronized with maineventloop + timeout: integer; //us + constructor create(persistent: boolean; atimeout: integer = 200000); virtual; + destructor destroy; override; + function state: commstatety; + function waitfordata: boolean; //true if no error + end; + + tcommthread = class(teventthread) + private + protected + fowner: tmsecomponent; + fport: trs232; + fabort: boolean; + fsendretries: integer; + function checkabort(const sender: tobject): boolean; virtual; + function execute(thread: tmsethread): integer; override; + public + constructor create(const aowner: tmsecomponent); //owner can be nil + destructor destroy; override; + function writestring(const dat: string; timeout: integer = 0): boolean; + //timeout in us, wenn = 0 -> warten auf uebertragungsende, bei halbduplex sowiso + function readstring(anzahl: integer; out dat: string; + timeout: integer = 0): boolean; + //list daten, true wenn gelungen, timeout in us, 0 -> doppelte uebertragungszeit + procedure abort; //alle laufende auftraege werden mit timeout abgebrochen + //ruecksetzung bei leerer messagequeue, bei aufruf aus fremdem thread, + // rueckkehr nach ruecksetzung + procedure postevent(event: tcommevent); + procedure reset; virtual; + property port: trs232 read fport; + property sendretries: integer read fsendretries write fsendretries default 0; + end; + + tcommport = class(tmsecomponent,istatfile) + private + Fonconnectedchange: booleanchangedeventty; + flastresult: integer; + Fonportchange: notifyeventty; + fopened: boolean; + factive: boolean; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: integer; + function getport: commnrty; + procedure setport(const Value: commnrty); + function getopened: boolean; + function getbusy: boolean; + function getbaudrate: commbaudratety; + function getparity: commparityty; + function getstopbit: commstopbitty; + procedure Setbaudrate(const Value: commbaudratety); + procedure Setparity(const Value: commparityty); + procedure Setstopbit(const Value: commstopbitty); + function gethalfduplex: boolean; + procedure sethalfduplex(const Value: boolean); + function getsendretries: integer; + procedure setsendretries(const Value: integer); + function getrtstimenach: integer; + function getrtstimevor: integer; + procedure setrtstimenach(const Value: integer); + procedure setrtstimevor(const Value: integer); + procedure setactive(const Value: boolean); + procedure setstatfile(const Value: tstatfile); +// function waitfordata(const event: tcomevent): comstatety; +// function getpriority: tthreadprioritymse; +// procedure setpriority(const Value: tthreadprioritymse); + function getdatabits: commdatabitsty; + procedure setdatabits(const avalue: commdatabitsty); + function getportname: filenamety; + procedure setportname(const avalue: filenamety); + protected + ftimeout: integer; + fthread: tcommthread; + procedure portchanged; virtual; +// function createdatascanner(slavenr,adresse,anzahl,zykluszeit: integer; +// empfaengerproc: empfaengerprocty): tdatascanner; virtual; +// function waitresult(const data: portdataty): boolean; + function postandwait(const event: tcommevent): boolean; //true if ok + procedure postevent(const event: tcommevent); + procedure loaded; override; + function extracterrortext(error: integer; errors: array of errorrecty; + var text: msestring): boolean; //true if found + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + procedure doafteropen; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function openport(raiseexception: boolean = false): boolean; + // true wenn gelungen + procedure closeport; + procedure abort; + //bricht laufende auftraege mit timeout ab, wird automatisch rueckgesetzt + function geterrortext(error: integer): msestring; virtual; + function getlastresulttext: msestring; + property thread: tcommthread read fthread; + property opened: boolean read getopened; + property busy: boolean read getbusy; + property halfduplex: boolean read gethalfduplex write sethalfduplex default false; + + property objectlinker: tobjectlinker read getobjectlinker + {$ifdef msehasimplements}implements istatfile{$endif}; + published + property onportchange: notifyeventty read Fonportchange + write fonportchange; + property onconnectchanged: booleanchangedeventty read Fonconnectedchange + write fonconnectedchange; + property sendretries: integer read getsendretries write setsendretries default 0; + property port: commnrty read getport write setport default cnr_1; + property portname: filenamety read getportname write setportname; + //overrides port + property baudrate: commbaudratety read getbaudrate write Setbaudrate default cbr_9600; + property stopbit: commstopbitty read getstopbit write Setstopbit default csb_1; + property parity: commparityty read getparity write Setparity default cpa_none; + property databits: commdatabitsty read getdatabits write setdatabits default cdb_8; + property rtstimevor: integer read getrtstimevor write setrtstimevor default 0; + property rtstimenach: integer read getrtstimenach write setrtstimenach default 0; + property timeout: integer read ftimeout write ftimeout default 200000; +// property priority: tthreadprioritymse read getpriority write setpriority default tpnormal; + property active: boolean read factive write setactive default false; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + end; + + tasciicommevent = class(tcommevent) + protected + procedure process(const thread: tcommthread; var ok: boolean); override; + public + commandstring: string; + resultstring: string; + resultcode: integer; //cpf_... + end; + + asciicommeventclassty = class of tasciicommevent; + + tasciicommthread = class(tcommthread) + private + puffer: string; + zeitstempel: longword; //in us + timeoutstarted: boolean; + feorchar: char; + procedure starttimeout(step: longword); + procedure closetimeout; + protected + function checkabort(const sender: tobject): boolean; override; + public + constructor create(const aowner: tmsecomponent); + procedure reset; override; //setzt commport zurueck + function readln(timeout: integer; out dat: string): integer; + //cpf_io wenn gelungen + function sendstring(const data: string; out antwort: string; + timeout: integer): integer; overload; + function sendstring(const data: string): integer; overload; + //no answer reading + property eorchar: char read feorchar write feorchar default defaulteorchar; + end; + + tasciicommport = class(tcommport) + private + function geteorchar: char; + procedure seteorchar(const avalue: char); + function getthread: tasciicommthread; + protected + function geteventclass: asciicommeventclassty; virtual; + public + constructor create(aowner: tcomponent); override; + function send(const commandstring: string; out answer: string; + atimeout: integer = 0): integer; overload; + function send(const commandstrings: array of string): integer; overload; + //reads no answer + property thread: tasciicommthread read getthread; + published + property halfduplex; + property eorchar: char read geteorchar write seteorchar default defaulteorchar; + end; + + asciiproterrorty = (ape_unknown,ape_command,ape_parameter,ape_busy); + +const + errorchar = '*'; + errorcodes: array[asciiproterrorty] of integer = + (cpf_unknown,cpf_command,cpf_parameter,cpf_busy); + +type + tasciiprotevent = class(tasciicommevent) + private + protected + procedure processed(const thread: tcommthread; var ok: boolean); override; + public + constructor create(persistent: boolean; atimeout: integer = 200000); override; + end; + + tasciiprotport = class(tasciicommport) + protected + function geteventclass: asciicommeventclassty; override; + public + function send(const commandstring: string; out answer: string; + atimeout: integer = 0; aadress: integer = -1): integer; + //-1: no address + end; + +function checkcommport(commnr: commnrty): boolean; //true wenn comport zur verfuegung +function crc16(const data; len: integer): word; +function bintoascii(const bytes: string): string; overload; + // $0..$f->'A'..'P', lsb first +function bintoascii(const bytes: pchar; const len: integer): string; overload; +function asciitobin(const chars: string): string; + +implementation +uses +// {$ifdef UNIX} {kernelioctl,}msesysbindings, {$endif} + sysutils,mseapplication,msesysintf1,msesysintf,msesys,msesysutils, + msepipestream,msefileutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + asciipufferlaenge = 255; + + t_nichtoffen = 'not open'; + databitcounts: array[commdatabitsty] of integer = (5,6,7,8); + + {$ifdef mswindows} +const // fuer tdcb.flags + fBinary = $0001; // binary mode, no EOF check + fParity = $0002; // enable parity checking + fOutxCtsFlow = $0004; // CTS output flow control + fOutxDsrFlow = $0008; // DSR output flow control + fDtrControldisable = $0000; // DTR flow control type + fDtrControlenable = $0010; + fDsrSensitivity = $0040; // DSR sensitivity + TXContinueOnXoff = $0080; // XOFF continues Tx + + fOutX = $0100; // XON/XOFF out flow control + fInX = $0200; // XON/XOFF in flow control + fErrorChar = $0400; // enable error replacement + fNull = $0800; // enable null stripping + fRtsControldisable = $0000; // RTS flow control + fRtsControlenable = $1000; + fRtsControlhandshake = $2000; + fRtsControltoggle = $3000; + fAbortOnError = $4000; // abort reads/writes on error +// DWORD fDummy2:17; // reserved +{ + defaultdcb: tdcb = ( + DCBlength: sizeof(tdcb); + BaudRate: 9600; + Flags: fbinary+fdtrcontrolenable+frtscontrolenable; + wReserved: 0; + XonLim: 256; + XoffLim: 128; + ByteSize: 8; + Parity: NOPARITY; + StopBits: ONESTOPBIT; + XonChar: #17; + XoffChar: #19; + ErrorChar: #0; + EofChar: #0; + EvtChar: #0; + wReserved1: 0; + ); + } + {$endif} + +{/* Table of CRC values for high-order byte */} +const //crcpolynom = $a001; + auchCRCHi: array[0..255] of byte = ( +$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, +$80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, +$00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, +$80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40, +$00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1, +$81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41, +$00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1, +$81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, +$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, +$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, +$01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, +$81, $40, $01, $C0, $80, $41, $00, $C1, $81, $40, +$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, +$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, +$01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, +$80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40, +$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, +$80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, +$00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, +$80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, +$01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, +$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, +$01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, +$81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, +$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, +$80, $41, $00, $C1, $81, $40 +) ; + auchCRCLo: array[0..255] of byte = ( +$00, $C0, $C1, $01, $C3, $03, $02, $C2, $C6, $06, +$07, $C7, $05, $C5, $C4, $04, $CC, $0C, $0D, $CD, +$0F, $CF, $CE, $0E, $0A, $CA, $CB, $0B, $C9, $09, +$08, $C8, $D8, $18, $19, $D9, $1B, $DB, $DA, $1A, +$1E, $DE, $DF, $1F, $DD, $1D, $1C, $DC, $14, $D4, +$D5, $15, $D7, $17, $16, $D6, $D2, $12, $13, $D3, +$11, $D1, $D0, $10, $F0, $30, $31, $F1, $33, $F3, +$F2, $32, $36, $F6, $F7, $37, $F5, $35, $34, $F4, +$3C, $FC, $FD, $3D, $FF, $3F, $3E, $FE, $FA, $3A, +$3B, $FB, $39, $F9, $F8, $38, $28, $E8, $E9, $29, +$EB, $2B, $2A, $EA, $EE, $2E, $2F, $EF, $2D, $ED, +$EC, $2C, $E4, $24, $25, $E5, $27, $E7, $E6, $26, +$22, $E2, $E3, $23, $E1, $21, $20, $E0, $A0, $60, +$61, $A1, $63, $A3, $A2, $62, $66, $A6, $A7, $67, +$A5, $65, $64, $A4, $6C, $AC, $AD, $6D, $AF, $6F, +$6E, $AE, $AA, $6A, $6B, $AB, $69, $A9, $A8, $68, +$78, $B8, $B9, $79, $BB, $7B, $7A, $BA, $BE, $7E, +$7F, $BF, $7D, $BD, $BC, $7C, $B4, $74, $75, $B5, +$77, $B7, $B6, $76, $72, $B2, $B3, $73, $B1, $71, +$70, $B0, $50, $90, $91, $51, $93, $53, $52, $92, +$96, $56, $57, $97, $55, $95, $94, $54, $9C, $5C, +$5D, $9D, $5F, $9F, $9E, $5E, $5A, $9A, $9B, $5B, +$99, $59, $58, $98, $88, $48, $49, $89, $4B, $8B, +$8A, $4A, $4E, $8E, $8F, $4F, $8D, $4D, $4C, $8C, +$44, $84, $85, $45, $87, $47, $46, $86, $82, $42, +$43, $83, $41, $81, $80, $40 +) ; + +function crc16(const data; len: integer): word; +var + uchcrchi,uchcrclo: byte; + int1: integer; + po: pbyte; + by1: byte; +begin + uchcrchi:= $ff; + uchcrclo:= $ff; + po:= @data; + for int1:= len-1 downto 0 do begin + by1:= po^ xor uchCRCHi; + inc(po); + uchCRCHi:= uchCRCLo xor auchCRCHi[by1]; + uchCRCLo:= auchCRCLo[by1] ; + end; +// result:= (uchCRCHi shl 8) or uchCRCLo; + result:= (uchCRCLo shl 8) or uchCRCHi; //gedreht! +end; + +function gettickus: longword; //laufzeit in us + {$ifdef UNIX} +var + t1: timeval; +begin +// gettimeofday(t1,ptimezone(nil){$ifdef FPC}^{$endif}); + gettimeofday(@t1,ptimezone(nil)); + result:= t1.tv_sec * 1000000 + t1.tv_usec; +end; + {$else} +begin + result:= windows.gettickcount*1000; +end; + {$endif} + +function commnrtocommname(commnr: commnrty): string; +begin + if (commnr < low(commnrty)) or (commnr > high(commnrty)) then begin + raise exception.Create('Invalid comnr: '+inttostr(integer(commnr))+'.'); + end; + result:= commname[commnr]; +end; + +function checkcommport(commnr: commnrty): boolean; //true wenn comport zur verfuegung //clx +var + hcomm: thandle; +{$ifndef mswindows} + info: termios; +{$endif} +begin + {$ifdef mswindows} + hcomm:= createfile(pchar(commname[commnr]), GENERIC_READ or GENERIC_WRITE, 0, nil, + OPEN_EXISTING,0,0); + if hcomm = invalidfilehandle then begin + result:= false; + end + else begin + result:= true; + closehandle(hcomm); + end; + {$else} + hcomm:= mselibc.open(PChar('/dev/'+commname[commnr]), o_rdwr or o_nonblock + {,FileAccessRights}); + if hcomm = thandle(invalidfilehandle) then begin + result:= false; + end + else begin + result:= msetcgetattr(hcomm,info) = 0; + __close(hcomm); + end; + {$endif} +end; + +function getbyte(char: pchar): byte; +begin + result:= ord(char^)-ord('A') + ((ord((char+1)^)-ord('A')) shl 4); +end; + +function getword(char: pchar): word; +begin + result:= getbyte(char) + (getbyte(char+2) shl 8); +end; + +function bintoascii(const bytes: pchar; const len: integer): string; +var + int1: integer; + po: pchar; +begin + if len > 0 then begin + setlength(result,2*len); + po:= @result[1]; + for int1:= 0 to len-1 do begin + po^:= char((pbyteaty(bytes)^[int1] and $0f) + ord('A')); + inc(po); + po^:= char((pbyteaty(bytes)^[int1] shr 4) + ord('A')); + inc(po); + end; + end + else begin + result:= ''; + end; +end; + +function bintoascii(const bytes: string): string; +begin + result:= bintoascii(pointer(bytes),length(bytes)); +end; + +function asciitobin(const chars: string): string; +var + po: pchar; + int1: integer; +begin + setlength(result,(length(chars)+1) div 2); + po:= pointer(chars); + for int1:= 1 to length(result) do begin + result[int1]:= char(getbyte(po)); + inc(po,2); + end; +end; + +{ tcustomrs232 } + +constructor tcustomrs232.create(const aowner: tmsecomponent; const + aoncheckabort: checkeventty = nil); +begin + fcommnr:= cnr_1; + fowner:= aowner; + fhandle:= invalidfilehandle; + fbaud:= cbr_9600; + fdatabits:= cdb_8; + fstopbit:= csb_1; + faparity:= cpa_none; + foncheckabort:= aoncheckabort; + updatebyteinfo; +end; + +destructor tcustomrs232.destroy; +begin + close; + inherited; +end; + +procedure tcustomrs232.updatebyteinfo; +var + openedvorher: boolean; + int1: integer; +begin + openedvorher:= opened; + if openedvorher then begin + close; + end; + int1:= 1 + databitcounts[fdatabits] + 1; //start + N daten + stop + if fstopbit = csb_2 then begin + inc(int1); + end; + if faparity <> cpa_none then begin + inc(int1); + end; + fbyteus:= round(int1*1000000*commbittime[fbaud]); + if openedvorher then begin + open; + end; +end; + +function tcustomrs232.transmissiontime(const acount: integer): longword; +begin + result:= fbyteus * acount; +end; + +procedure tcustomrs232.Setbaud(const Value: commbaudratety); +begin + if fbaud <> value then begin + Fbaud := Value; + updatebyteinfo; + end; +end; + +procedure tcustomrs232.Setcommnr(const Value: commnrty); +begin + if (value < cnr_1) or (value > high(commnrty)) then begin + raise exception.Create('Invalid commnr: '+inttostr(integer(value))+'.'); + end; + if fcommnr <> value then begin + Fcommnr := Value; + updatebyteinfo; + end; +end; + +procedure tcustomrs232.setcommname(const avalue: filenamety); +begin + if fcommname <> avalue then begin + fcommname:= avalue; + updatebyteinfo; + end; +end; + +procedure tcustomrs232.Setparity(const Value: commparityty); +begin + if faparity <> value then begin + Faparity := Value; + updatebyteinfo; + end; +end; + +procedure tcustomrs232.setdatabits(const avalue: commdatabitsty); +begin + if fdatabits <> avalue then begin + fdatabits:= avalue; + updatebyteinfo; + end; +end; + +function tcustomrs232.canevent(const aevent: tmethod): boolean; +begin + result:= (fowner = nil) or (fowner.canevent(aevent)); +end; + +procedure tcustomrs232.Setstopbit(const Value: commstopbitty); +begin + if fstopbit <> value then begin + Fstopbit := Value; + updatebyteinfo; + end; +end; + +procedure tcustomrs232.reset; +begin + if opened then begin + {$ifdef UNIX} + ioctl(fhandle,TCFLSH,[2]); //input und output flushen + {$else} + purgecomm(fhandle,PURGE_TXABORT+PURGE_RXABORT+PURGE_TXCLEAR+PURGE_RXCLEAR); + {$endif} + end; +end; + +procedure tcustomrs232.resetinput; +begin + if opened then begin + {$ifdef UNIX} + ioctl(fhandle,TCFLSH,[0]); //input flushen + {$else} + purgecomm(fhandle,PURGE_RXABORT+PURGE_RXCLEAR); + {$endif} + end; +end; + +procedure tcustomrs232.resetoutput; +begin + if opened then begin + {$ifdef UNIX} + ioctl(fhandle,TCFLSH,[1]); //output flushen + {$else} + purgecomm(fhandle,PURGE_TXABORT+PURGE_TXCLEAR); + {$endif} + end; +end; + +procedure tcustomrs232.close; +begin + if opened then begin + if assigned(fonclose) then begin + fonclose; + end; + {$ifdef UNIX} + if not fnoclosehandle then begin + __close(fhandle); + end; + {$else} + if not fnoclosehandle then begin + closehandle(fhandle); + end; + if overlappedrx.hevent <> 0 then begin + closehandle(overlappedrx.hevent); + overlappedrx.hEvent:= 0; + end; + if overlappedtx.hevent <> 0 then begin + closehandle(overlappedtx.hevent); + overlappedtx.hEvent:= 0; + end; + freeandnil(timer); + {$endif} + end; + fhandle:= invalidfilehandle; + fopenerror:= 0; +end; + +function tcustomrs232.opened: boolean; +begin + result:= fhandle <> invalidfilehandle; +end; + +function tcustomrs232.commpath(): filenamety; +begin + if fcommname <> '' then begin + result:= tosysfilepath(fcommname); + end + else begin + {$ifdef MSWINDOWS} + result:= msestring(msecommport.commname[fcommnr]); + {$else} + result:= msestring('/dev/'+msecommport.commname[fcommnr]); + {$endif} + end; +end; + +function tcustomrs232.open: boolean; +{$ifdef UNIX} +const + iflagoff = BRKINT or INPCK or ISTRIP or IGNCR or INLCR or ICRNL or IUCLC or + IXON or IXANY or IXOFF or IMAXBEL; + iflagon = IGNBRK or IGNPAR; + oflagoff = OPOST or OLCUC or ONLCR or OCRNL or ONOCR or ONLRET or OFILL or + OFDEL or NLDLY or TABDLY or BSDLY or VTDLY or FFDLY; + oflagon = 0; + cflagoff = CBAUD or CSIZE or CSTOPB or PARENB or PARODD or HUPCL or CBAUDEX or + CIBAUD or CRTSCTS ; + cflagon = CREAD or CLOCAL; + lflagoff = ISIG or ICANON or XCASE or ECHO or ECHOE or ECHOK or ECHONL or + NOFLSH or TOSTOP or ECHOCTL or ECHOPRT or ECHOKE or IEXTEN; + lflagon = 0; +var + info: termios{ty}; + {$else} +var + int1: integer; + dcb: tdcb; +// bitzeit: real; +const // fuer tdcb.flags + fBinary = $0001; // binary mode, no EOF check + fParity = $0002; // enable parity checking + fOutxCtsFlow = $0004; // CTS output flow control + fOutxDsrFlow = $0008; // DSR output flow control + fDtrControldisable = $0000; // DTR flow control type + fDtrControlenable = $0010; + fDsrSensitivity = $0040; // DSR sensitivity + TXContinueOnXoff = $0080; // XOFF continues Tx + + fOutX = $0100; // XON/XOFF out flow control + fInX = $0200; // XON/XOFF in flow control + fErrorChar = $0400; // enable error replacement + fNull = $0800; // enable null stripping + fRtsControldisable = $0000; // RTS flow control + fRtsControlenable = $1000; + fRtsControlhandshake = $2000; + fRtsControltoggle = $3000; + fAbortOnError = $4000; // abort reads/writes on error +// DWORD fDummy2:17; // reserved + + defaultdcb: tdcb = ( + DCBlength: sizeof(tdcb); + BaudRate: 9600; + Flags: fbinary{+fdtrcontrolenable+frtscontrolenable}; + wReserved: 0; + XonLim: 256; + XoffLim: 128; + ByteSize: 8; + Parity: NOPARITY; + StopBits: ONESTOPBIT; + XonChar: #17; + XoffChar: #19; + ErrorChar: #0; + EofChar: #0; + EvtChar: #0; + wReserved1: 0; + + ); + +{$endif} + + procedure raiseerror; + begin + close; + syserror(syelasterror,'trs232: Can not set port mode.'); + end; +var + str1: string; + +begin //open + close; + str1:= ansistring(commpath()); + {$ifdef UNIX} + fhandle:= mselibc.open(PChar(str1),o_rdwr or o_nonblock{,FileAccessRights}); + if integer(fhandle) >= 0 then begin + msetcgetattr(fhandle,info); + info.c_iflag:= info.c_iflag and not(iflagoff) or iflagon; + info.c_oflag:= info.c_oflag and not(oflagoff) or oflagon; + info.c_cflag:= info.c_cflag and not(cflagoff) or cflagon; + info.c_lflag:= info.c_lflag and not(lflagoff) or lflagon; + if fstopbit = csb_2 then begin + info.c_cflag:= info.c_cflag or cstopb; + end; + if faparity <> cpa_none then begin + info.c_cflag:= info.c_cflag or parenb; + end; + if faparity = cpa_odd then begin + info.c_cflag:= info.c_cflag or parodd; + end; + info.c_line:= char(N_TTY); + info.c_cc[VMIN]:= fvmin; + info.c_cc[VTIME]:= #0; + + info.c_cflag:= info.c_cflag or commdatabitflags[fdatabits]; + cfsetispeed(info,commbaudflags[fbaud]); + cfsetospeed(info,commbaudflags[fbaud]); + if msetcsetattr(fhandle,TCSANOW,info) <> 0 then begin + raiseerror; + end; + reset; + end; + {$else} + int1:= 0; + fillchar(overlappedrx,sizeof(overlappedrx),0); + fillchar(overlappedtx,sizeof(overlappedtx),0); + overlappedrx.hevent:= createevent(nil,true,false,nil); + overlappedtx.hevent:= createevent(nil,true,false,nil); + + repeat + fhandle:= createfile(pchar(str1),GENERIC_READ or GENERIC_WRITE, 0, + nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0); + if (fhandle = invalidfilehandle) and (pos('//./',str1) = 0) then begin + str1:= '//./'+str1; + fhandle:= createfile(pchar(str1),GENERIC_READ or GENERIC_WRITE, 0, + nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0); + end; + if fhandle = invalidfilehandle then begin + sleep(100); + end; + inc(int1); + until (fhandle <> invalidfilehandle) or (int1 > 2); + if fhandle <> invalidfilehandle then begin + fillchar(commtimeouts,sizeof(commtimeouts),#0); //keine timeouts +// commtimeouts.readintervaltimeout:= maxdword; //bei read sofortige rueckkehr + setcommtimeouts(fhandle,commtimeouts); + dcb:= defaultdcb; + if fhalfduplex then begin +// dcb.flags:= fbinary+fdtrcontrolenable+frtscontroltoggle; //geht nicht bei win95! +// dcb.flags:= fbinary+fdtrcontrolenable+frtscontroldisable; + timer:= tmmtimermse.create; + end; + dcb.baudrate:= commbaudrates[fbaud]; + dcb.bytesize:= databitcounts[fdatabits]; + case fstopbit of + csb_1: dcb.stopbits:= onestopbit; + csb_2: begin + dcb.stopbits:= twostopbits; + end; + end; + case self.faparity of + cpa_none: dcb.parity:= noparity; + cpa_odd: dcb.parity:= oddparity; + cpa_even: dcb.parity:= evenparity; + end; + if not setcommstate(fhandle,dcb) then begin + raiseerror; + end; + reset; + end; + {$endif} + result:= opened; + if not result then begin + fopenerror:= getlasterror(); + end; + if result and assigned(fonopen) then begin + fonopen; + end; +end; + +procedure tcustomrs232.setrts(active: boolean); +{$ifndef mswindows} +var + flags: integer; +{$endif} +begin + if opened then begin + {$ifdef UNIX} + flags:= TIOCM_RTS; + if active then begin + ioctl(fhandle,TIOCMBIS,@flags); + end + else begin + ioctl(fhandle,TIOCMBIC,@flags); + end; + {$else} + if active then begin + escapecommfunction(fhandle,windows.setrts); + end + else begin + escapecommfunction(fhandle,windows.clrrts); + end; + {$endif} + end; +end; + +procedure tcustomrs232.setdtr(active: boolean); +{$ifndef mswindows} +var + flags: integer; +{$endif} +begin + if opened then begin + {$ifdef UNIX} + flags:= TIOCM_DTR; + if active then begin + ioctl(fhandle,TIOCMBIS,@flags); + end + else begin + ioctl(fhandle,TIOCMBIC,@flags); + end; + {$else} + if active then begin + escapecommfunction(fhandle,windows.setdtr); + end + else begin + escapecommfunction(fhandle,windows.clrdtr); + end; + {$endif} + end; +end; + +function tcustomrs232.waitfortx(timeout: integer): boolean; + //fuer LINUX: um max ein tick verzoegert! + //funktioniert nicht in win2k, vermutlich bug + + {$ifdef mswindows} +var + ca1: longword; + {$endif} +begin + {$ifdef UNIX} + ioctl(fhandle,tcsbrk,[-1]); + result:= true; + {$else} + getcommmask(fhandle,ca1); + if ca1 <> ev_txempty then begin + raise exception.Create('trs232.waitfortx falsche commmask'); + end; + waitcommevent(fhandle,ca1,@overlappedtx); + result:= waitforsingleobject(overlappedtx.hevent,timeout div 1000) = + wait_object_0; + if not result then begin + setcommmask(fhandle,0); //overlapped puffer freigeben + end; + {$endif} +end; + +{$ifdef mswindows} +procedure tcustomrs232.eotevent(sender: tobject); +begin + setrts(false); +end; + +{$endif} +function tcustomrs232.defaulttimeout(us: longword; anzahl: integer; + out timeout: longword): boolean; + // timeout in us 0 -> 2*uebertragungszeit, +begin + timeout:= us; + result:= us <> infinitemse; + if result then begin + if us = 0 then begin + timeout:= transmissiontime(anzahl)*2+30000; + end; + end; +end; + +function tcustomrs232.writestring(const dat: string; timeout: longword = 0; + waitforeot: boolean = false): boolean; + // timeout in us 0 -> 2*uebertragungszeit, + // waitforeot -> warten auf uebertragungsende, bei halbduplex sowiso +var + len: longword; + {$ifdef UNIX} + timed: boolean; + int1: integer; + ca1: longword; + po: ^byte; + time: longword; + {$else} + ca1: longword; +// time: longword; +// bo1: boolean; + {$endif} +begin + result:= false; + if integer(fhandle) >= 0 then begin + len:= length(dat); + if len = 0 then begin + result:= true; + exit; + end; + if fhalfduplex then begin + setrts(true); + {$ifdef mswindows} +// waitus(frtstimevor); + timer.wait(frtstimevor+1000); + timer.start(integer(len)*fbyteus+frtstimenach+1000,{$ifdef FPC}@{$endif}eotevent); + {$else} + waitus(frtstimevor); +// usleep(frtstimevor); + {$endif} + end; + {$ifdef UNIX} + timed:= defaulttimeout(timeout,len,timeout); + time:= timestep(timeout); + po:= @dat[1]; + repeat + int1:= __write(fhandle,po^,len); + inc(po,int1); + dec(len,int1); + until (len = 0) or (timed and msesysutils.timeout(time)); + result:= len = 0; + {$else} + defaulttimeout(timeout,len,timeout); + setcommmask(fhandle,0); + setcommmask(fhandle,ev_txempty); //funktioniert nicht fuer w2k, waitcommevent kehrt sofort zurueck! + if not writefile(fhandle,dat[1],len,ca1,@overlappedtx) then begin + if getlasterror = ERROR_IO_PENDING then begin + result:= waitforsingleobject(overlappedtx.hevent,timeout div 1000+1) = + WAIT_OBJECT_0; + end; + end + else begin + result:= true; + end; + if not result then begin + purgecomm(fhandle,PURGE_TXABORT); //overlapped puffer freigeben + end; + {$endif} + if fhalfduplex then begin + if result then begin + {$ifdef mswindows} + timer.wait; + {$else} +// result:= false; + time:= timestep(transmissiontime(length(dat)*2)); + repeat + ioctl(fhandle,tiocsergetlsr,@ca1); + result:= ca1 and TIOCSER_TEMT <> 0; + until result or msesysutils.timeout(time); + if result and (frtstimenach <> 0) then begin + waitus(frtstimenach); + end; +// usleep(frtstimenach); + {$endif} + end; + setrts(false); + end + else begin + if waitforeot then begin + result:= waitfortx(timeout); + end; + end; + end; + {$ifdef mswindows} + purgecomm(fhandle,PURGE_TXABORT); //overlapped puffer freigeben + {$endif} +end; + +function tcustomrs232.readbuffer(anzahl: integer; out dat; + timeout: longword = 0): integer; + //list daten, bringt anzahl gelesene zeichen timeout in us 0 -> 2*uebertragungszeit +var + po: ^byte; + int1: integer; + {$ifdef UNIX} + time: longword; + pollinfo: array[0..0] of pollfd; + {$else} + time: longword; + bo1: boolean; + {$endif} + timed: boolean; +begin + result:= 0; + po:= @dat; + if opened then begin + if anzahl > 0 then begin + timed:= defaulttimeout(timeout,anzahl,timeout); + time:= timestep(timeout); + {$ifdef mswindows} + bo1:= windows.readfile(fhandle,po^,anzahl,longword(int1),@overlappedrx); + {$else} + if timed then begin + fillchar(pollinfo,sizeof(pollinfo),0); + with pollinfo[0] do begin + fd:= fhandle; + events:= pollin; + end; + end; + {$endif} + while true do begin + {$ifdef UNIX} + if timed then begin + repeat + int1:= poll(@pollinfo,1,timeout div 1000 + 1); + if (int1 < 0) and (sys_getlasterror <> eintr) then begin + break; + end; + until int1 >= 0; + if int1 > 0 then begin + int1:= __read(fhandle,po^,anzahl); + end; + end + else begin + int1:= __read(fhandle,po^,anzahl); + end; + {$else} + if not bo1 then begin + if not getoverlappedresult(fhandle, + overlappedrx,longword(int1),false) then begin + bo1:= windows.getlasterror = error_io_incomplete; + if bo1 then begin + bo1:= waitforsingleobject( + overlappedrx.hevent,timeout div 1000 + 1) = WAIT_OBJECT_0; + if bo1 then begin + bo1:= getoverlappedresult(fhandle, + overlappedrx,longword(int1),false); + end; + end; + if not bo1 then begin + int1:= -1; + purgecomm(fhandle,PURGE_RXABORT); //puffer freigeben + end; + end; + end; + {$endif} + if int1 < 0 then begin + break; + end; + if int1 <> 0 then begin + inc(po,int1); + end; + anzahl:= anzahl - int1; + result:= result + int1; + if (anzahl <= 0) or timed and msesysutils.timeout(time) or + (canevent(tmethod(foncheckabort)) and foncheckabort(self)) then begin + break; +// end +// else begin +// sleepus(fbyteus); + end; + end; + end; + end; +end; + +(* +{$ifdef UNIX} +function tcustomrs232.readbuffer(anzahl: integer; out dat; + timeout: longword = 0): integer; + //list daten, bringt anzahl gelesene zeichen timeout in us 0 -> 2*uebertragungszeit +var + po: ^byte; + int1: integer; + time: timeval; + timed: boolean; +begin + result:= 0; + po:= @dat; + if opened then begin + if anzahl > 0 then begin + timed:= defaulttimeout(timeout,anzahl,timeout); + time:= timestep(timeout); + while true do begin + int1:= __read(fhandle,po^,anzahl); + if int1 < 0 then begin + break; + end; + if int1 <> 0 then begin + inc(po,int1); + end; + anzahl:= anzahl - int1; + result:= result + int1; + if (anzahl <= 0) or timed and zeitabgelaufen(time) or + (canevent(foncheckabort) and foncheckabort(self)) then begin + break; + end + else begin + usleep(fbyteus); + end; + end; + end; + end; +end; + +{$else} + +function tcustomrs232.readbuffer(anzahl: integer; out dat; + timeout: longword = 0): integer; + //liest daten, bringt anzahl gelesene zeichen timeout in us 0 -> 2*uebertragungszeit +var + po: ^byte; + int1: integer; + bo1: boolean; +begin + result:= 0; + po:= @dat; + if opened then begin + if anzahl > 0 then begin + if defaulttimeout(timeout,anzahl,timeout) then begin + timeout:= timeout div 1000; + end; + bo1:= windows.readfile(fhandle,po^,anzahl,longword(result),@overlapped); + if not bo1 and (getlasterror = ERROR_IO_PENDING) then begin + bo1:= waitforsingleobject(overlapped.hevent,timeout) = WAIT_OBJECT_0; + end; + if not bo1 then begin + purgecomm(fhandle,PURGE_RXABORT); //puffer freigeben + end + else begin + if not getoverlappedresult(fhandle,overlapped,longword(result),false) then begin + result:= 0; + end; + end; + end; + end; +end; +{$endif} //not unix +{$ifend} +*) + +function tcustomrs232.readstring(anzahl: integer; out dat: string; + timeout: longword = infinitemse): boolean; + //timeout = 0 -> timeout = 2*uebertragungszeit +var + int1: integer; +begin + result:= false; + if opened then begin + setlength(dat,anzahl); + int1:= readbuffer(anzahl,dat[1],timeout); + setlength(dat,int1); + result:= int1 = anzahl; + end; +end; + +function tcustomrs232.readavailbuffer(const maxcount: integer; out dat): integer; +begin + result:= 0; + if maxcount > 0 then begin + piperead(dat,maxcount,result,true); + end; +end; + +function tcustomrs232.readavailstring(const maxcount: integer): string; +begin + setlength(result,maxcount); + setlength(result,readavailbuffer(maxcount,pointer(result)^)); +end; + +{$ifdef mswindows} +function tcustomrs232.setreadnonblocked(const anonblocked: boolean): boolean; +begin + result:= true; + if anonblocked then begin + if commtimeouts.readintervaltimeout <> maxdword then begin + commtimeouts.readintervaltimeout:= maxdword; + result:= setcommtimeouts(fhandle,commtimeouts); + end; + end + else begin + if commtimeouts.readintervaltimeout <> 0 then begin + commtimeouts.readintervaltimeout:= 0; + result:= setcommtimeouts(fhandle,commtimeouts); + end; + end; + if not result then begin + commtimeouts.readintervaltimeout:= maxdword div 2; //setting invalid + end; +end; +{$endif} + +function tcustomrs232.piperead(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean): boolean; +{$ifdef mswindows} +var + w1: dword; + bo1: boolean; +{$endif} +begin +{$ifdef mswindows} + bo1:= true; + w1:= 0; + bo1:= setreadnonblocked(nonblocked); + if bo1 then begin + if nonblocked then begin + bo1:= windows.readfile(fhandle,buf,acount,w1,@overlappedrx); + end + else begin + if acount > 0 then begin + bo1:= windows.readfile(fhandle,buf,1,w1,@overlappedrx); + end + else begin + bo1:= windows.readfile(fhandle,buf,0,w1,@overlappedrx); + end; + if not bo1 and (getlasterror = ERROR_IO_PENDING) then begin + bo1:= getoverlappedresult(fhandle,overlappedrx,w1,true); + end; + if bo1 and (acount > 1) then begin + bo1:= setreadnonblocked(true) and + windows.readfile(fhandle,(pchar(@buf)+1)^,acount-1,w1,@overlappedrx); + if not bo1 and (getlasterror = ERROR_IO_PENDING) then begin + bo1:= getoverlappedresult(fhandle,overlappedrx,w1,true); + end; + if bo1 then begin + w1:= w1 + 1; + end; + end; + end; + end; + if not bo1 then begin + readcount:= 0; + end + else begin + readcount:= w1; + end; + result:= bo1; +{$else} + readcount:= readfilenonblock(handle,buf,acount,nonblocked); + result:= readcount >= 0; +{$endif} +end; + +function tcustomrs232.pipewrite(const buffer; count: longint): longint; +{$ifdef mswindows} +var + w1: dword; + bo1: boolean; +{$endif} +begin +{$ifdef mswindows} + bo1:= windows.writefile(fhandle,buffer,count,w1,@overlappedtx); + if not bo1 and (getlasterror = ERROR_IO_PENDING) then begin + bo1:= getoverlappedresult(fhandle,overlappedtx,w1,true); + end; + if bo1 then begin + result:= w1; + end + else begin + result:= -1; + end; +{$else} + result:= sys_write(fhandle,@buffer,count); +{$endif} +end; + +procedure tcustomrs232.setactive(const avalue: boolean); +begin + if avalue then begin + open; + end + else begin + close; + end; +end; + +{ tcommthread } + +constructor tcommthread.create(const aowner: tmsecomponent); +begin + fowner:= aowner; + fport:= trs232.create(fowner,{$ifdef FPC}@{$endif}checkabort); + inherited create({$ifdef FPC}@{$endif}execute); +end; + +destructor tcommthread.destroy; +begin + inherited; + fport.Free; +end; + +function tcommthread.readstring(anzahl: integer; out dat: string; + timeout: integer): boolean; +begin + result:= fport.readstring(anzahl,dat,timeout); + if not result then begin + fport.reset; //puffer freigeben + end; +end; + +function tcommthread.writestring(const dat: string; + timeout: integer): boolean; +begin + result:= fport.writestring(dat,timeout,timeout=0); +end; + +procedure tcommthread.abort; +begin + if running then begin + fabort := true; + inherited postevent(tmseevent.create(ek_abort)); + if sys_getcurrentthread <> id then begin + while fabort do begin + sys_threadschedyield; + end; + end; + end; +end; + +function tcommthread.checkabort(const sender: tobject): boolean; +begin + result:= application.terminated or terminated or fabort; +end; + +function tcommthread.execute(thread: tmsethread): integer; +var + event: tmseevent; + abort1: boolean; + + procedure freeevent; + begin + if event is tcommevent then begin + with tcommevent(event) do begin + if not fpersistent then begin + free1; + end + else begin + if abort1 then begin + fstate:= coms_abort; + sys_sempost(fsem); + end; + end; + end; + end + else begin + event.Free1; + end; + end; + +var + bo1,bo2: boolean; + +begin + repeat + event:= waitevent; + abort1:= fabort; + if abort1 then begin + freeevent; + while eventcount > 0 do begin + event:= waitevent; + freeevent; + end; + fabort:= false; + end + else begin + if event is tcommevent then begin + with tcommevent(event) do begin + bo2:= not fpersistent; //event can be destroyed later + try + bo1:= false; + process(self,bo1); + finally + if bo2 then begin + event.free1; + end; + end; + end; + end + else begin + event.Free1; + end; + end; + until terminated; + result:= 0; +end; + +procedure tcommthread.reset; +begin + fport.reset; +end; + +procedure tcommthread.postevent(event: tcommevent); +begin + with event do begin + if fstate = coms_working then begin + raise exception.Create('Comevent working!'); + end; + fstate:= coms_working; +// if fpersistent then begin +// semreset{(fsem)}; +// end; + end; + inherited postevent(event); +end; + +{ tcomevent } + +constructor tcommevent.create(persistent: boolean; atimeout: integer = 200000); +begin + fpersistent:= persistent; + timeout:= atimeout; + if fpersistent then begin + sys_semcreate(fsem,0); + end; + inherited create(ek_user); +end; + +destructor tcommevent.destroy; +begin + if fpersistent then begin + sys_semdestroy(fsem); + end; + inherited; +end; + +procedure tcommevent.process(const thread: tcommthread; var ok: boolean); +begin + processed(thread,ok); +end; + +procedure tcommevent.processed(const thread: tcommthread; var ok: boolean); +begin + if ok then begin + fstate:= coms_ok; + if assigned(onsuccess) then begin + application.lock; + try + onsuccess(self); + finally + application.unlock; + end; + end; + end + else begin + fstate:= coms_error; + if assigned(onerror) then begin + application.lock; + try + onerror(self); + finally + application.unlock; + end; + end; + end; + if fpersistent then begin + sys_sempost(fsem); + end; +end; + +function tcommevent.state: commstatety; +begin + result:= fstate; +end; + +function tcommevent.waitfordata: boolean; +begin + if not fpersistent then begin + raise exception.Create('Comevent not persistent!'); + end; + sys_semwait(fsem,0); + result:= fstate = coms_ok; +end; + +{ tasciicommthread } + +constructor tasciicommthread.create(const aowner: tmsecomponent); +begin + feorchar:= defaulteorchar; + inherited; +end; + +function tasciicommthread.checkabort(const sender: tobject): boolean; +begin + result:= inherited checkabort(sender) or + timeoutstarted and later(zeitstempel,gettickus); +end; + +procedure tasciicommthread.closetimeout; +begin + timeoutstarted:= false; +end; + +procedure tasciicommthread.starttimeout(step: longword); +begin + zeitstempel:= gettickus + step; + timeoutstarted:= true; +end; + +function tasciicommthread.readln(timeout: integer; + out dat: string): integer; //todo: optimize +var + po,po1: pchar; + laenge: integer; //longword; + lwo1: longword; + bo1,bo2: boolean; +// ca1: longword; +begin + result:= cpf_timeout; + dat:= ''; + laenge:= length(puffer); + setlength(puffer,asciipufferlaenge); + po:= pchar(puffer); //start + po1:= po; + bo1:= false; + bo2:= false; + starttimeout(timeout); + while not bo1 do begin + po1:= strlscan(po1,feorchar,laenge-(po1-po)); + if po1 <> nil then begin + dat:= dat + copy(puffer,1,po1-po); + move(po1[1],po^,laenge-(po1-po)); + laenge:= laenge-(po1-po)-1; + result:= cpf_ok; + break; + end; + if laenge >= asciipufferlaenge then begin + dat:= dat + puffer; + uniquestring(puffer); + laenge:= 0; + { + laenge:= 0; //platz fuer naechstes telegramm + result:= cpf_bufferoverflow; + break; //puffer voll + } + end; + po1:= po+laenge; + lwo1:= fport.readbuffer(asciipufferlaenge-laenge,po1[0],fport.transmissiontime(2)); + laenge:= laenge + integer(lwo1); + bo1:= bo2; + bo2:= checkabort(nil); + end; + setlength(puffer,laenge); + closetimeout; +end; + +procedure tasciicommthread.reset; +begin + puffer:= ''; + inherited; +end; + +function tasciicommthread.sendstring(const data: string): integer; +begin + if not fport.opened then begin + result:= cpf_notopen; + exit; + end; + result:= cpf_timeout; + if fport.writestring(data+feorchar,0) then begin + result:= cpf_ok; + end; +end; + +function tasciicommthread.sendstring(const data: string; + out antwort: string; timeout: integer): integer; +var + int1: integer; + bo1: boolean; +// str1: string; +begin + if not fport.opened then begin + result:= cpf_notopen; + exit; + end; + int1:= fsendretries; + repeat +// while (result <> cpf_ok) and (int1 >= 0) do begin + reset; // puffer loeschen + result:= sendstring(data); + if result = cpf_ok then begin + result:= cpf_timeout; +// if fport.writestring(data+feorchar,0) then begin + if fport.fhalfduplex then begin +// sleep(20); + bo1:= fport.readstring(length(data)+1,antwort,0); //eigene zeichen + end + else begin + bo1:= true; + end; + if bo1 then begin + result:= readln(timeout,antwort); + end; + end; + dec(int1); + until (result = cpf_ok) or (int1 < 0); +end; + +{ tcommport } + +constructor tcommport.create(aowner: tcomponent); +begin + ftimeout:= 200000; + if fthread = nil then begin + fthread:= tcommthread.create(self); + end; + inherited; +end; + +destructor tcommport.destroy; +begin + freeandnil(fthread); + inherited; +end; + +procedure tcommport.abort; +begin + fthread.abort; +end; + +procedure tcommport.closeport; +begin + fthread.fport.close; + fopened:= false; + portchanged; +end; + +function tcommport.getbusy: boolean; +begin + result:= fthread.eventcount > 0; +end; + +function tcommport.getbaudrate: commbaudratety; +begin + result:= fthread.fport.baud; +end; + +procedure tcommport.Setbaudrate(const Value: commbaudratety); +begin + fthread.fport.baud:= value; +end; + +function tcommport.getdatabits: commdatabitsty; +begin + result:= fthread.fport.databits; +end; + +procedure tcommport.setdatabits(const avalue: commdatabitsty); +begin + fthread.fport.databits:= avalue; +end; + +function tcommport.extracterrortext(error: integer; + errors: array of errorrecty; var text: msestring): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(errors) do begin + if errors[int1].error = error then begin + text:= errors[int1].text; + result:= true; + break; + end; + end; +end; + +function tcommport.geterrortext(error: integer): msestring; +begin + if not extracterrortext(error,errortexte,result) then begin + result:= 'Error Nr.: '+inttostrmse(error); + end; +end; + +function tcommport.gethalfduplex: boolean; +begin + result:= fthread.fport.halfduplex; +end; + +procedure tcommport.sethalfduplex(const Value: boolean); +begin + fthread.fport.halfduplex:= value; +end; + +function tcommport.getlastresulttext: msestring; +begin + result:= geterrortext(flastresult); +end; + +function tcommport.getopened: boolean; +begin + result:= (fthread <> nil ) and fopened and (fthread.fport.opened); +end; + +function tcommport.getparity: commparityty; +begin + result:= fthread.fport.parity; +end; + +procedure tcommport.Setparity(const Value: commparityty); +begin + fthread.fport.parity:= value; +end; + +function tcommport.getport: commnrty; +begin + result:= fthread.fport.commnr; +end; + +procedure tcommport.setport(const Value: commnrty); +begin + fthread.fport.commnr:= value; + portchanged; +end; + +function tcommport.getportname: filenamety; +begin + result:= fthread.fport.commname; +end; + +procedure tcommport.setportname(const avalue: filenamety); +begin + fthread.fport.commname:= avalue; + portchanged; +end; + + +function tcommport.getrtstimenach: integer; +begin + result:= fthread.fport.frtstimenach; +end; + +procedure tcommport.setrtstimenach(const Value: integer); +begin + fthread.fport.rtstimenach:= value; +end; + +function tcommport.getrtstimevor: integer; +begin + result:= fthread.fport.frtstimevor; +end; + +procedure tcommport.setrtstimevor(const Value: integer); +begin + fthread.fport.rtstimevor:= value; +end; + +function tcommport.getsendretries: integer; +begin + result:= fthread.sendretries; +end; + +procedure tcommport.setsendretries(const Value: integer); +begin + fthread.sendretries:= value; +end; + +function tcommport.getstopbit: commstopbitty; +begin + result:= fthread.fport.stopbit; +end; + +procedure tcommport.Setstopbit(const Value: commstopbitty); +begin + fthread.fport.stopbit:= value; +end; + +function tcommport.openport(raiseexception: boolean): boolean; +begin + result:= fthread.fport.open; + fopened:= true; + if raiseexception and not result then begin +// raise EFCreateError.Create(commname[fport.fcommnr]+' '+t_nichtoffen+'.'); + raise exception.Create(commname[fthread.fport.fcommnr]+' '+t_nichtoffen+'.'); + end; + doafteropen; + portchanged; +end; + +procedure tcommport.portchanged; +begin + if canevent(tmethod(fonportchange)) then begin + fonportchange(self); + end; +end; + +function tcommport.postandwait(const event: tcommevent): boolean; +begin + fthread.postevent(event); + result:= event.waitfordata; +end; + +procedure tcommport.postevent(const event: tcommevent); +begin + fthread.postevent(event); +end; + +procedure tcommport.setactive(const Value: boolean); +begin + factive := Value; + if componentstate * [csloading,csdesigning] = [] then begin + if value then begin + openport; + end + else begin + closeport; + end; + end; +end; + +procedure tcommport.loaded; +begin + inherited; + setactive(factive); +end; + +procedure tcommport.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +function tcommport.getstatvarname: msestring; +begin + Result := fstatvarname; +end; + +procedure tcommport.dostatread(const reader: tstatreader); +begin + port:= commnrty(reader.readinteger('port',integer(port), + ord(low(commnrty)),ord(high(commnrty)))); +end; + +procedure tcommport.dostatwrite(const writer: tstatwriter); +begin + writer.writeinteger('port',integer(port)); +end; + +procedure tcommport.statreading; +begin + //dummy +end; + +procedure tcommport.statread; +begin + //dummy +end; + +procedure tcommport.doafteropen; +begin + //dummy; +end; + +function tcommport.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tasciicommport } + +constructor tasciicommport.create(aowner: tcomponent); +begin + fthread:= tasciicommthread.create(self); + inherited; +end; + +function tasciicommport.geteorchar: char; +begin + result:= tasciicommthread(fthread).eorchar; +end; + +procedure tasciicommport.seteorchar(const avalue: char); +begin + tasciicommthread(fthread).eorchar:= avalue; +end; + +function tasciicommport.send(const commandstring: string; + out answer: string; atimeout: integer = 0): integer; +var + ev: tasciicommevent; +begin + if atimeout = 0 then begin + atimeout:= ftimeout; + end; + ev:= geteventclass.create(true,atimeout); + try + ev.commandstring:= commandstring; + tasciicommthread(fthread).postevent(ev); + ev.waitfordata; + if (ev.state = coms_ok) or (ev.state = coms_error) then begin + result:= ev.resultcode; + answer:= ev.resultstring; + end + else begin + result:= integer(ev.state); + answer:= ''; + end; + finally + ev.Free1; + end; +end; + +function tasciicommport.geteventclass: asciicommeventclassty; +begin + result:= tasciicommevent; +end; + +function tasciicommport.send(const commandstrings: array of string): integer; +var + int1: integer; +// str1: string; +begin + result:= cpf_none; + for int1:= 0 to high(commandstrings) do begin + result:= tasciicommthread(fthread).sendstring(commandstrings[int1]); + if result <> cpf_ok then begin + break; + end; + end; +end; + +function tasciicommport.getthread: tasciicommthread; +begin + result:= tasciicommthread(fthread); +end; + +{ tasciicomevent } + +procedure tasciicommevent.process(const thread: tcommthread; var ok: boolean); +begin + if commandstring <> '' then begin + with tasciicommthread(thread) do begin + resultcode:= sendstring(commandstring,resultstring,timeout); + end; + ok:= resultcode = cpf_ok; + end; + inherited; +end; + +{ tasciiprotevent } + +constructor tasciiprotevent.create(persistent: boolean; + atimeout: integer = 200000); +begin + inherited; +end; + +procedure tasciiprotevent.processed(const thread: tcommthread; var ok: boolean); +var + int1: integer; +begin + if ok and (length(resultstring) > 0) then begin + if resultstring[1] = errorchar then begin + ok:= false; + if length(resultstring) = 1 then begin + int1:= ord(ape_command); + end + else begin + int1:= ord(resultstring[2]) - ord('A')+1; + if (int1 < ord(ape_command)) or + (int1 > ord(high(asciiproterrorty))) then begin + int1:= ord(ape_unknown); + end; + end; + resultcode:= errorcodes[asciiproterrorty(int1)]; + end; + end; + inherited; +end; + +{ asciiprotport } + +function tasciiprotport.geteventclass: asciicommeventclassty; +begin + result:= tasciiprotevent; +end; + +function tasciiprotport.send(const commandstring: string; out answer: string; + atimeout: integer = 0; aadress: integer = -1): integer; +begin + if aadress = -1 then begin + result:= inherited send(commandstring,answer,atimeout); + end + else begin + result:= inherited send(char(byte(aadress) or $80) + + commandstring,answer,atimeout); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/serialcomm/msecommtimer.pas b/mseide-msegui/lib/common/serialcomm/msecommtimer.pas new file mode 100644 index 0000000..d75dc43 --- /dev/null +++ b/mseide-msegui/lib/common/serialcomm/msecommtimer.pas @@ -0,0 +1,196 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msecommtimer; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +uses + {$ifdef mswindows} + windows,{$ifndef FPC}mmsystem,{$endif} + {$endif} + {$ifdef UNIX} + mselibc, + {$endif} + Classes; +{$ifdef mswindows} +type + {$ifdef FPC} + PTimeCaps = ^TTimeCaps; + timecaps_tag = record + wPeriodMin: UINT; { minimum period supported } + wPeriodMax: UINT; { maximum period supported } + end; + TTimeCaps = timecaps_tag; + TIMECAPS = timecaps_tag; + TFNTimeCallBack = procedure(uTimerID, uMessage: UINT; + dwUser, dw1, dw2: DWORD) stdcall; + {$endif} + + tmmtimermse = class //mindeszeit bei nt ca 10ms, + // ungestoerte zeit meistens 10ms zu klein + private + fevent: thandle; + fontimer: tnotifyevent; + ftimecaps: timecaps; + fresolution: integer; + ftimehandle: integer; + protected + fid: int32; //index in instance array + public + constructor create; + destructor destroy; override; + procedure wait(us: longword; aontimer: tnotifyevent = nil); overload; + procedure wait; overload; + procedure start(us: longword; aontimer: tnotifyevent = nil); + procedure abort; + end; + + {$ifdef FPC} +const + TIME_ONESHOT = 0; { program timer for single event } + TIME_PERIODIC = 1; { program for continuous periodic event } + TIME_CALLBACK_FUNCTION = $0000; { callback is function } + TIME_CALLBACK_EVENT_SET = $0010; { callback is event - use SetEvent } + TIME_CALLBACK_EVENT_PULSE = $0020; { callback is event - use PulseEvent } + mmsyst = 'winmm.dll'; +function timeKillEvent(uTimerID: UINT): MMRESULT; stdcall; + external mmsyst name 'timeKillEvent'; +function timeGetDevCaps(lpTimeCaps: PTimeCaps; uSize: UINT): MMRESULT; stdcall; + external mmsyst name 'timeGetDevCaps'; +function timeBeginPeriod(uPeriod: UINT): MMRESULT; stdcall; + external mmsyst name 'timeBeginPeriod'; +function timeEndPeriod(uPeriod: UINT): MMRESULT; stdcall; + external mmsyst name 'timeEndPeriod'; +function timeSetEvent(uDelay, uResolution: UINT; + lpFunction: TFNTimeCallBack; dwUser: DWORD; uFlags: UINT): MMRESULT; stdcall; + external mmsyst name 'timeSetEvent'; + {$endif} +{$endif mswindows} + +implementation +uses + {$ifdef mswindows}msesystypes,msesysintf1,{$endif}sysutils; + +{$ifdef mswindows} +var + timerinstances: array of tmmtimermse; + timerlock: mutexty; + +procedure locktimer(); +begin + sys_mutexlock(timerlock); +end; + +procedure unlocktimer(); +begin + sys_mutexunlock(timerlock); +end; + +procedure mmtimerevent(uTimerID, uMessage: UINT; + dwUser, dw1, dw2: DWORD); stdcall; +var + ti1: tmmtimermse; +begin + locktimer(); + ti1:= timerinstances[dwuser]; + unlocktimer(); + with ti1 do begin + if assigned(fontimer) then begin + fontimer(ti1); + end; + setevent(fevent); + end; +end; + +procedure tmmtimermse.abort; +begin + if ftimehandle <> 0 then begin + timekillevent(ftimehandle); + ftimehandle:= 0; + end; +end; + +constructor tmmtimermse.create; +var + i1: int32; +begin + fevent:= createevent(nil,false,false,nil); + timegetdevcaps(@ftimecaps,sizeof(timecaps)); + fresolution:= ftimecaps.wPeriodMin; + if fresolution < 1 then begin + fresolution:= 1; + end; + timebeginperiod(fresolution); + inherited; + fid:= -1; + locktimer(); + for i1:= 0 to high(timerinstances) do begin + if timerinstances[i1] = nil then begin + fid:= i1; + end; + end; + if fid < 0 then begin + fid:= length(timerinstances); + setlength(timerinstances,fid+1); + end; + timerinstances[fid]:= self; + unlocktimer(); +end; + +destructor tmmtimermse.destroy; +begin + abort; + closehandle(fevent); + timeendperiod(fresolution); + locktimer(); + timerinstances[fid]:= nil; + unlocktimer(); + inherited; +end; + +procedure tmmtimermse.start(us: longword; aontimer: tnotifyevent = nil); +var + ms: longword; +begin + abort; + fontimer:= aontimer; + ms:= us div 1000; + if ms >= ftimecaps.wPeriodMin then begin + ftimehandle:= timesetevent(ms,1,@mmtimerevent,fid,time_oneshot); + if ftimehandle = 0 then begin + raise exception.Create('timererror'); + end; + end + else begin + mmtimerevent(0,0,fid,0,0); + end; +end; + +procedure tmmtimermse.wait; +begin + waitforsingleobject(fevent,infinite{ms+20}); + abort; +end; + +procedure tmmtimermse.wait(us: longword; aontimer: tnotifyevent = nil); +begin + start(us,aontimer); + wait; +end; + +initialization + sys_mutexcreate(timerlock); +finalization + sys_mutexdestroy(timerlock); +{$endif} + +end. diff --git a/mseide-msegui/lib/common/serialcomm/msecommutils.pas b/mseide-msegui/lib/common/serialcomm/msecommutils.pas new file mode 100644 index 0000000..bcf39b4 --- /dev/null +++ b/mseide-msegui/lib/common/serialcomm/msecommutils.pas @@ -0,0 +1,211 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msecommutils; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msedataedits,msecommport,msetypes,msedatalist, + classes,mclasses,mseclasses,msedropdownlist,msestat, + msemenus,mseevent,msestrings,msegui,mseguiglob,mseedit,msegraphics; +type + setcommnreventty = procedure(const sender: tobject; var avalue: commnrty; + var accept: boolean) of object; + getcommnreventty = procedure(const sender: tobject; + var avalue: commnrty) of object; + + tcommselector = class(tcustomselector) + private + fongetactivecommnr: getcommnreventty; + fvaluename: filenamety; + function getvalue: commnrty; + procedure setvalue(const aValue: commnrty); + function readonsetvalue: setcommnreventty; + procedure writeonsetvalue(const aValue: setcommnreventty); + procedure setvaluename(const avalue: filenamety); + protected + procedure getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); override; +// function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + public + constructor create(aowner: tcomponent); override; + published + property value: commnrty read getvalue write setvalue default cnr_1; + property valuename: filenamety read fvaluename write setvaluename; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onsetvalue: setcommnreventty read readonsetvalue write writeonsetvalue; + property onbeforedropdown; + property onafterclosedropdown; + property ongetactivecommnr: getcommnreventty read fongetactivecommnr + write fongetactivecommnr; + end; + +implementation +uses + mseeditglob; + +type + comminforecty = record anzeigetext, dropdowntext: string; commnr: commnrty end; + comminfoty = array[cnr_1..cnr_9] of comminforecty; +const + + {$ifdef mswindows} + comminfo: comminfoty = ((anzeigetext:'COM1'; dropdowntext:'1 COM1'; commnr: cnr_1), + (anzeigetext:'COM2'; dropdowntext:'2 COM2'; commnr: cnr_2), + (anzeigetext:'COM3'; dropdowntext:'3 COM3'; commnr: cnr_3), + (anzeigetext:'COM4'; dropdowntext:'4 COM4'; commnr: cnr_4), + (anzeigetext:'COM5'; dropdowntext:'5 COM5'; commnr: cnr_5), + (anzeigetext:'COM6'; dropdowntext:'6 COM6'; commnr: cnr_6), + (anzeigetext:'COM7'; dropdowntext:'7 COM7'; commnr: cnr_7), + (anzeigetext:'COM8'; dropdowntext:'8 COM8'; commnr: cnr_8), + (anzeigetext:'COM9'; dropdowntext:'9 COM9'; commnr: cnr_9) + ); + {$else} + + comminfo: comminfoty = ((anzeigetext:'ttyS0'; dropdowntext:'0 ttyS0'; commnr: cnr_1), + (anzeigetext:'ttyS1'; dropdowntext:'1 ttyS1'; commnr: cnr_2), + (anzeigetext:'ttyS2'; dropdowntext:'2 ttyS2'; commnr: cnr_3), + (anzeigetext:'ttyS3'; dropdowntext:'3 ttyS3'; commnr: cnr_4), + (anzeigetext:'ttyS4'; dropdowntext:'4 ttyS4'; commnr: cnr_5), + (anzeigetext:'ttyS5'; dropdowntext:'5 ttyS5'; commnr: cnr_6), + (anzeigetext:'ttyS6'; dropdowntext:'6 ttyS6'; commnr: cnr_7), + (anzeigetext:'ttyS7'; dropdowntext:'7 ttyS7'; commnr: cnr_8), + (anzeigetext:'ttyS8'; dropdowntext:'8 ttyS8'; commnr: cnr_9) + ); + { + comminfo: comminfoty = ((anzeigetext:'ttys0'; dropdowntext:'0 ttys0'; commnr: cnr_1), + (anzeigetext:'ttys1'; dropdowntext:'1 ttys1'; commnr: cnr_2), + (anzeigetext:'ttys2'; dropdowntext:'2 ttys2'; commnr: cnr_3), + (anzeigetext:'ttys3'; dropdowntext:'3 ttys3'; commnr: cnr_4), + (anzeigetext:'ttys4'; dropdowntext:'4 ttys4'; commnr: cnr_5), + (anzeigetext:'ttys5'; dropdowntext:'5 ttys5'; commnr: cnr_6), + (anzeigetext:'ttys6'; dropdowntext:'6 ttys6'; commnr: cnr_7), + (anzeigetext:'ttys7'; dropdowntext:'7 ttys7'; commnr: cnr_8), + (anzeigetext:'ttys8'; dropdowntext:'8 ttys8'; commnr: cnr_9) + ); + } + {$endif} + + +{ tcommselector } + +constructor tcommselector.create(aowner: tcomponent); +var + comm: commnrty; +begin + inherited; + dropdown.cols.nostreaming:= true; + inherited value:= integer(cnr_1); + for comm:= low(comminfo) to high(comminfo) do begin + tdropdownlistcontroller(fdropdown).cols[0].add( + msestring(comminfo[comm].anzeigetext)); + end; +end; + +procedure tcommselector.getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); +var + comm: commnrty; + int1: integer; + activecomm: commnrty; +begin + setlength(aenums,integer(high(commnrty))); + names[0].clear; + activecomm:= commnrty(-1); + if canevent(tmethod(fongetactivecommnr)) then begin + fongetactivecommnr(self,activecomm); + end; + int1:= 0; + for comm:= low(comminfo) to high(comminfo) do begin + if (comm = activecomm) or checkcommport(comm) then begin + aenums[int1]:= integer(comm); + names[0].add(msestring(comminfo[comm].dropdowntext)); + inc(int1); + end; + end; + setlength(aenums,int1); +end; + +function tcommselector.getvalue: commnrty; +begin + result:= commnrty(fvalue1); +end; + +function tcommselector.readonsetvalue: setcommnreventty; +begin + result:= setcommnreventty(fonsetvalue1); +end; + +procedure tcommselector.writeonsetvalue(const aValue: setcommnreventty); +begin + fonsetvalue1:= setintegereventty(avalue); +end; + +procedure tcommselector.setvalue(const aValue: commnrty); +begin + inherited setvalue(integer(avalue)); +end; +{ +function tcommselector.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tnocolsenumdropdowncontroller.create(idropdownlist(self)); +end; +} +procedure tcommselector.setvaluename(const avalue: filenamety); +begin + if avalue <> fvaluename then begin + fvaluename:= avalue; + changed; + end; +end; + +procedure tcommselector.texttovalue(var accept: boolean; const quiet: boolean); +var + mstr1: msestring; +begin + mstr1:= fvaluename; + if not (des_statreading in fstate) then begin + fvaluename:= text; + end; + inherited; + if not accept then begin + fvaluename:= mstr1; + end; +end; + +function tcommselector.internaldatatotext(const data): msestring; +begin + result:= inherited internaldatatotext(data); + if (@data = nil) and (value = cnr_invalid) then begin + result:= fvaluename; + end; +end; + +procedure tcommselector.readstatvalue(const reader: tstatreader); +begin + inherited; + valuename:= reader.readmsestring(valuevarname+'_name',fvaluename); +end; + +procedure tcommselector.writestatvalue(const writer: tstatwriter); +begin + inherited; + writer.writemsestring(valuevarname+'_name',fvaluename); +end; + +end. diff --git a/mseide-msegui/lib/common/serialcomm/msesercomm.pas b/mseide-msegui/lib/common/serialcomm/msesercomm.pas new file mode 100644 index 0000000..6759563 --- /dev/null +++ b/mseide-msegui/lib/common/serialcomm/msesercomm.pas @@ -0,0 +1,1328 @@ +{ MSEgui Copyright (c) 2011-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesercomm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,msecommport,mseclasses,mseglob,msepipestream,msetypes, + msecryptio,msethread,mseevent,mseapplication,msesystypes,msetimer; + +const + closepipestag = 836915; + closeconnectiontag = closepipestag + 1; + +type + tcustomcommpipes = class; + tcommreader = class; + commpipeseventty = procedure(const sender: tcustomcommpipes) of object; + + icommserver = interface(inullinterface) + end; + icommclient = interface(iobjectlink) + procedure setcommserverintf(const aintf: icommserver); + function getobjectlinker: tobjectlinker; + procedure dorxchange(const areader: tcommreader); + end; + icommclientarty = array of icommclient; + + tcommreader = class(tpipereader) + private + ftimeoutms: integer; + fonthreadterminate: proceventty; + protected + fpipes: tcustomcommpipes; + fcrypto: pcryptoioinfoty; + fonafterconnect: proceventty; + procedure settimeoutms(const avalue: integer); virtual; + function execthread(thread: tmsethread): integer; override; + function internalread(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean = false): boolean; virtual; + function doread(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean = false): boolean; override; + procedure dochange; override; + public + constructor create(const apipes: tcustomcommpipes); + property timeoutms: integer read ftimeoutms write settimeoutms; + end; + + + tcommwriter = class(tpipewriter) + private + ftimeoutms: integer; + protected + fowner: tcustomcommpipes; + fcrypto: pcryptoioinfoty; + procedure settimeoutms(const avalue: integer); virtual; + function internalwrite(const buffer; count: longint): longint; virtual; + function dowrite(const buffer; count: longint): longint; override; + public + constructor create(const aowner: tcustomcommpipes); + property timeoutms: integer read ftimeoutms write settimeoutms; + end; + + tsercommwriter = class(tcommwriter) + protected + function internalwrite(const buffer; count: longint): longint; override; + end; + + tsercommreader = class(tcommreader) + protected + function internalread(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean = false): boolean; override; + end; + + tcustomcommcomp = class; + + commpipesstatety = (cps_open,cps_closing,cps_detached,cps_releasing); + commpipesstatesty = set of commpipesstatety; + + tcustomcommpipes = class(tlinkedpersistent,ievent) + private + foninputavailable: commpipeseventty; + foncommbroken: commpipeseventty; + fowner: tcustomcommcomp; + fonbeforeconnect: commpipeseventty; + fonafterconnect: commpipeseventty; + fonbeforedisconnect: commpipeseventty; + fonafterdisconnect: commpipeseventty; + function gethandle: integer; + procedure sethandle(const avalue: integer); + function getoverloadsleepus: integer; + procedure setoverloadsleepus(const avalue: integer); + procedure setoninputavailable(const avalue: commpipeseventty); + procedure doinputavailable(const sender: tpipereader); + procedure dopipebroken(const sender: tpipereader); + procedure internalclose; + function getoptionsreader: pipereaderoptionsty; + procedure setoptionsreader(const avalue: pipereaderoptionsty); + function getrxtimeoutms: integer; + procedure setrxtimeoutms(const avalue: integer); + function gettxtimeoutms: integer; + procedure settxtimeoutms(const avalue: integer); + procedure dorxchange(const areader: tcommreader); virtual; + protected + fstate: commpipesstatesty; + frx: tcommreader; + ftx: tcommwriter; + fcryptoio: tcryptoio; + fcryptoioinfo: cryptoioinfoty; + procedure createpipes; virtual; abstract; + procedure doafterconnect; virtual; + procedure dothreadterminate; + procedure setcryptoio(const acryptoio: tcryptoio); + procedure receiveevent(const event: tobjectevent); + property oncommbroken: commpipeseventty read foncommbroken + write foncommbroken; + public + constructor create(const aowner: tcustomcommcomp; + const acryptkind: cryptoiokindty); reintroduce; + destructor destroy; override; + procedure close; + procedure release; + { + procedure runhandlerapp(const commandline: filenamety); + //connects to input/output + } + property handle: integer read gethandle write sethandle; + property rx: tcommreader read frx; + property tx: tcommwriter read ftx; + property rxtimeoutms: integer read getrxtimeoutms write setrxtimeoutms; + property txtimeoutms: integer read gettxtimeoutms write settxtimeoutms; + + property overloadsleepus: integer read getoverloadsleepus + write setoverloadsleepus default -1; + //checks application.checkoverload before calling oninputavaliable + //if >= 0 + property optionsreader: pipereaderoptionsty read getoptionsreader + write setoptionsreader default []; + property onbeforeconnect: commpipeseventty read fonbeforeconnect + write fonbeforeconnect; + property onafterconnect: commpipeseventty read fonafterconnect + write fonafterconnect; + property onbeforedisconnect: commpipeseventty read fonbeforedisconnect + write fonbeforedisconnect; + property onafterdisconnect: commpipeseventty read fonafterdisconnect + write fonafterdisconnect; + property oninputavailable: commpipeseventty read foninputavailable + write setoninputavailable; + end; + + tsercommpipes = class(tcustomcommpipes) + protected + procedure createpipes; override; + published + property optionsreader; + property overloadsleepus; + property oninputavailable; + property oncommbroken; + end; + + commcompeventty = procedure(sender: tcustomcommcomp) of object; + + tcustomcommcomp = class(tactcomponent,icommserver) + private + fclients: icommclientarty; + fonbeforeconnect: commcompeventty; + fonafterconnect: commcompeventty; + fonbeforedisconnect: commcompeventty; + fonafterdisconnect: commcompeventty; + procedure setcryptoio(const avalue: tcryptoio); + protected + fhandle: integer; + factive: boolean; + factiveafterload: boolean; + fcryptoio: tcryptoio; + procedure setactive(const avalue: boolean); override; + procedure doactivated; override; + procedure dodeactivated; override; + procedure internalconnect; virtual; abstract; + procedure internaldisconnect; virtual; + procedure closepipes(const sender: tcustomcommpipes); virtual; abstract; + procedure writedata(const adata: string); + function trywritedata(const adata: string): syserrorty; virtual; abstract; + procedure connect; + procedure disconnect; + procedure checkinactive; + procedure doafterconnect(const sender: tcustomcommpipes); + procedure loaded; override; + function gethalfduplex: boolean; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function calctransmissiontime(const alength: integer): integer; virtual; + //us, 0 if not supported + property active: boolean read factive write setactive default false; + property cryptoio: tcryptoio read fcryptoio write setcryptoio; + + property onbeforeconnect: commcompeventty read fonbeforeconnect + write fonbeforeconnect; + property onafterconnect: commcompeventty read fonafterconnect + write fonafterconnect; + property onbeforedisconnect: commcompeventty read fonbeforedisconnect + write fonbeforedisconnect; + property onafterdisconnect: commcompeventty read fonafterdisconnect + write fonafterdisconnect; + end; + + tasyncserport = class(tcustomrs232) + protected + + public + constructor create(const aowner: tmsecomponent; //aowner can be nil + const aoncheckabort: checkeventty = nil); + published + property commnr; + property commname; + property baud; + property databits; + property stopbit; + property parity; + end; + + sercommoptionty = (sco_halfduplex,sco_nopipe); + sercommoptionsty = set of sercommoptionty; + + tcustomsercommcomp = class(tcustomcommcomp) + private + foptions: sercommoptionsty; + procedure setpipes(const avalue: tsercommpipes); + procedure setport(const avalue: tasyncserport); + procedure setoptions(const avalue: sercommoptionsty); + protected + fpipes: tsercommpipes; + fport: tasyncserport; +// procedure writedata(const adata: string); override; + function trywritedata(const adata: string): syserrorty; override; + procedure internalconnect; override; + procedure internaldisconnect; override; + procedure closepipes(const sender: tcustomcommpipes); override; + procedure doasyncevent(var atag: integer); override; + function gethalfduplex: boolean; override; + protected + procedure doportopen; + procedure doportclose; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function calctransmissiontime(const alength: integer): integer; override; + property pipes: tsercommpipes read fpipes write setpipes; + property port: tasyncserport read fport write setport; + property options: sercommoptionsty read foptions + write setoptions default []; + end; + + tsercommcomp = class(tcustomsercommcomp) + published + property pipes; + property port; + property active; + property activator; + property cryptoio; + property options; + property onbeforeconnect; + property onafterconnect; + property onbeforedisconnect; + property onafterdisconnect; + end; + + commresponseflagty = (crf_error,crf_timeout,crf_eof,crf_trunc,crf_writeerror); + commresponseflagsty = set of commresponseflagty; + tcustomsercommchannel = class; + commresponseeventty = procedure(const sender: tcustomsercommchannel; + var adata: string; var aflags: commresponseflagsty) of object; + sercommchannelstatety = (sccs_pending,sccs_sync,sccs_eor); + sercommchannelstatesty = set of sercommchannelstatety; + + tcustomsercommchannel = class(tmsecomponent,icommclient) + private + fsercomm: tcustomcommcomp; + fserverintf: icommserver; + fonresponse: commresponseeventty; + ftimer: tsimpletimer; + ftimeoutus: integer; + fsem: semty; + feor: string; + procedure setsercomm(const avalue: tcustomcommcomp); + procedure dotimer(const sender: tobject); + protected + fstate: sercommchannelstatesty; + fexpected: integer; + fsent: integer; + fdata: string; + fflags: commresponseflagsty; + function internaltransmit(const adata: string; + const aresponselength: integer; const atimeoutus: integer; + const sync: boolean; const aeor: boolean): syserrorty; + procedure checksercomm; + procedure doresponse; virtual; + //icommclient + procedure setcommserverintf(const aintf: icommserver); + procedure dorxchange(const areader: tcommreader); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; + function transmit(const adata: string; const aresponselength: integer; + const atimeoutus: integer = -1): syserrorty; virtual; overload; + //threadsafe + //async, answer by onresponse + //0 -> timeoutus property, + //-1 -> timeoutus + guessed transmission time, + //-2 unlimited + function transmiteor(const adata: string; const aresponselength: integer = 0; + const atimeoutus: integer = -1): syserrorty; virtual; overload; + //use EOR, async + function transmit(const adata: string; const aresponselength: integer; + out aresult: string; + const atimeoutus: integer = -1): commresponseflagsty; virtual; overload; + //synchronous, threadsafe + function transmiteor(const adata: string; out aresult: string; + const aresponselength: integer = 0; + const atimeoutus: integer = -1): commresponseflagsty; virtual; overload; + //use EOR, synchronous, threadsafe + property sercomm: tcustomcommcomp read fsercomm write setsercomm; + property timeoutus: integer read ftimeoutus write ftimeoutus default 0; + //0 -> unlimited, + property onresponse: commresponseeventty read fonresponse write fonresponse; + property eor: string read feor write feor; //end of record, default $0a + end; + + tsercommchannel = class(tcustomsercommchannel) + published + property sercomm; + property timeoutus; + property eor; + property onresponse; + end; + + setupcommeventty = procedure(const sender: tobject; + const acomm: tcustomsercommcomp) of object; + + tasynsercommchannel = class(tcustomsercommchannel) + private + fonconnect: notifyeventty; + fondisconnect: notifyeventty; + fonsetupcomm: setupcommeventty; + fconnected: boolean; + fconnectafterload: boolean; + function getsercomm: tcustomsercommcomp; + procedure setsercomm(const avalue: tcustomsercommcomp); + procedure setconnected(const avalue: boolean); + protected + procedure loaded; override; + procedure setupcomm(const acomm: tcustomsercommcomp); virtual; + procedure doconnect; virtual; + procedure dodisconnect; virtual; + property onconnect: notifyeventty read fonconnect write fonconnect; + property ondisconnect: notifyeventty read fondisconnect write fondisconnect; + public + procedure connect; virtual; + procedure disconnect; virtual; + published + property sercomm: tcustomsercommcomp read getsercomm write setsercomm; + property onsetupcomm: setupcommeventty read fonsetupcomm write fonsetupcomm; + property timeoutus; + property eor; + property onresponse; + property connected: boolean read fconnected write setconnected + default false; + end; + +procedure setcomcomp(const alink: icommclient; const acommcomp: tcustomcommcomp; + var dest: tcustomcommcomp); +procedure connectcryptoio(const acryptoio: tcryptoio; const tx: tcommwriter; + const rx: tcommreader; + var cryptoioinfo: cryptoioinfoty; + txfd: integer = invalidfilehandle; + rxfd: integer = invalidfilehandle); + +implementation +uses + msesys,msestream,msearrayutils,sysutils,msebits,msesysintf1,msestrings, + msesysutils; + +procedure setcomcomp(const alink: icommclient; + const acommcomp: tcustomcommcomp; var dest: tcustomcommcomp); +begin + alink.setcommserverintf(nil); + if dest <> nil then begin + removeitem(pointerarty(dest.fclients),pointer(alink)); + end; + alink.getobjectlinker.setlinkedvar(alink,acommcomp,tmsecomponent(dest)); + if dest <> nil then begin + additem(pointerarty(dest.fclients),pointer(alink)); + alink.setcommserverintf(icommserver(dest)); + end; +end; + +procedure connectcryptoio(const acryptoio: tcryptoio; const tx: tcommwriter; + const rx: tcommreader; + var cryptoioinfo: cryptoioinfoty; + txfd: integer = invalidfilehandle; + rxfd: integer = invalidfilehandle); +begin + if (acryptoio <> nil) and (cryptoioinfo.kind <> cyk_none) then begin + if txfd = invalidfilehandle then begin + txfd:= tx.handle; + end; + if rxfd = invalidfilehandle then begin + rxfd:= rx.handle; + end; + tx.fcrypto:= @cryptoioinfo; + rx.fcrypto:= @cryptoioinfo; + acryptoio.link(txfd,rxfd,cryptoioinfo); + if cryptoioinfo.kind = cyk_server then begin + cryptoaccept(cryptoioinfo,rx.timeoutms); + end + else begin + cryptoconnect(cryptoioinfo,rx.timeoutms); + end; + end + else begin + tx.fcrypto:= nil; + rx.fcrypto:= nil; + end; +end; + +{ tcustomsercommcomp } + +constructor tcustomsercommcomp.create(aowner: tcomponent); +begin + if fpipes = nil then begin + fpipes:= tsercommpipes.create(self,cyk_none); //todo: cyk_sercomm + end; + fport:= tasyncserport.create(self); + fport.fnoclosehandle:= true; + fport.fonopen:= @doportopen; + fport.fonclose:= @doportclose; + inherited; +end; + +destructor tcustomsercommcomp.destroy; +begin + fport.free; + fpipes.free; + inherited; +end; + +procedure tcustomsercommcomp.setpipes(const avalue: tsercommpipes); +begin + fpipes.assign(avalue); +end; + +procedure tcustomsercommcomp.doportopen; +begin + if (fpipes.handle = invalidfilehandle) and + not (sco_nopipe in foptions) then begin + fpipes.handle:= fport.handle; + end; + factive:= true; +end; + +procedure tcustomsercommcomp.doportclose; +begin + fpipes.handle:= msesystypes.invalidfilehandle; + factive:= false; +end; + +procedure tcustomsercommcomp.internalconnect; +begin + if not (csdesigning in componentstate) then begin + if not fport.open then begin + componentexception(self, + 'Can not open comm port "'+fport.commpath+'":'+lineend+ + msestring(syserrortext(sye_lasterror))); + end; + {$ifdef unix} + setfilenonblock(fport.handle,sco_nopipe in foptions); + {$endif}; +// if not (sco_nopipe in foptions) then begin +// fpipes.handle:= fport.handle; +// end; + end; + factive:= true; + doafterconnect(fpipes); +end; + +procedure tcustomsercommcomp.internaldisconnect; +begin + fpipes.handle:= msesystypes.invalidfilehandle; + inherited; + fport.close; +end; + +procedure tcustomsercommcomp.closepipes(const sender: tcustomcommpipes); +begin +// if (csdestroying in componentstate) and application.ismainthread then begin + disconnect; +// end +// else begin +// asyncevent(closepipestag); +// end; +end; + +procedure tcustomsercommcomp.doasyncevent(var atag: integer); +begin + if atag = closepipestag then begin + disconnect; + end; +end; + +procedure tcustomsercommcomp.setport(const avalue: tasyncserport); +begin + fport.assign(avalue); +end; + +function tcustomsercommcomp.trywritedata(const adata: string): syserrorty; +begin + result:= fpipes.tx.trywritebuffer(pointer(adata)^,length(adata)); +end; + +function tcustomsercommcomp.gethalfduplex: boolean; +begin + result:= sco_halfduplex in foptions; +end; + +function tcustomsercommcomp.calctransmissiontime( + const alength: integer): integer; +begin + result:= fport.transmissiontime(alength); +end; + +procedure tcustomsercommcomp.setoptions(const avalue: sercommoptionsty); +begin + foptions:= avalue; + fport.fnoclosehandle:= not (sco_nopipe in foptions); +end; + +{ tsercommpipes } + +procedure tsercommpipes.createpipes; +begin + ftx:= tsercommwriter.create(self); + frx:= tsercommreader.create(self); +end; + +{ tasyncserport } + +constructor tasyncserport.create(const aowner: tmsecomponent; + const aoncheckabort: checkeventty = nil); +begin + inherited create(aowner,aoncheckabort); + fvmin:= #1; //blocking until first byte +end; + +{ tcustomcommpipes } + +constructor tcustomcommpipes.create(const aowner: tcustomcommcomp; + const acryptkind: cryptoiokindty); +begin + fowner:= aowner; + createpipes; +// frx:= tsocketreader.create; + frx.fonafterconnect:= {$ifdef FPC}@{$endif}doafterconnect; + frx.onpipebroken:= {$ifdef FPC}@{$endif}dopipebroken; + frx.fonthreadterminate:= {$ifdef FPC}@{$endif}dothreadterminate; +// ftx:= tsocketwriter.create; + setlinkedvar(aowner.fcryptoio,tmsecomponent(fcryptoio)); + fcryptoioinfo.kind:= acryptkind; +end; + +destructor tcustomcommpipes.destroy; +begin + inherited; + close; + frx.free; + ftx.free; +end; + +procedure tcustomcommpipes.release; +begin + if not (cps_releasing in fstate) then begin + application.postevent(tobjectevent.create(ek_release,ievent(self))); + include(fstate,cps_releasing); + end; +end; + +function tcustomcommpipes.gethandle: integer; +begin + result:= ftx.handle; +end; + +procedure tcustomcommpipes.doafterconnect; +begin + connectcryptoio(fcryptoio,ftx,frx,fcryptoioinfo); + if assigned(fonafterconnect) then begin + fonafterconnect(self); + end; +end; + +procedure tcustomcommpipes.dothreadterminate; +begin + cryptothreadterminate(fcryptoioinfo); + //dummy +end; + +procedure tcustomcommpipes.sethandle(const avalue: integer); +//var +// int1: integer; +begin + ftx.releasehandle; + ftx.handle:= avalue; + frx.handle:= avalue; + { + int1:= avalue; + if avalue <> invalidfilehandle then begin + syserror(sys_dup(avalue,int1)); + end; + frx.handle:= int1; + } + if avalue <> invalidfilehandle then begin + include(fstate,cps_open); + end + else begin + setcryptoio(nil); + exclude(fstate,cps_open); + end; +end; + +procedure tcustomcommpipes.setcryptoio(const acryptoio: tcryptoio); +begin + fcryptoio:= acryptoio; + with fcryptoioinfo do begin + cryptounlink(fcryptoioinfo); + ftx.fcrypto:= nil; + frx.fcrypto:= nil; + end; +end; + +function tcustomcommpipes.getoverloadsleepus: integer; +begin + result:= frx.overloadsleepus; +end; + +procedure tcustomcommpipes.setoverloadsleepus(const avalue: integer); +begin + frx.overloadsleepus:= avalue; +end; + +procedure tcustomcommpipes.setoninputavailable(const avalue: commpipeseventty); +begin + foninputavailable:= avalue; + if assigned(avalue) then begin + frx.oninputavailable:= {$ifdef FPC}@{$endif}doinputavailable; + end + else begin + frx.oninputavailable:= nil; + end; +end; + +procedure tcustomcommpipes.doinputavailable(const sender: tpipereader); +begin + if fowner.canevent(tmethod(foninputavailable)) then begin + foninputavailable(self); + end; +end; + +procedure tcustomcommpipes.receiveevent(const event: tobjectevent); +begin + if (event is tuserevent) and (tuserevent(event).tag = closepipestag) then begin + if assigned(foncommbroken) then begin + foncommbroken(self); + end + else begin + close; + end; + end + else begin + if event.kind = ek_release then begin + free; + end; + end; +end; + +procedure tcustomcommpipes.dopipebroken(const sender: tpipereader); +begin + application.postevent(tuserevent.create(ievent(self),closepipestag)); +end; + +procedure tcustomcommpipes.internalclose; +begin + fowner.closepipes(self); +end; + +procedure tcustomcommpipes.close; +begin + if fstate * [cps_open,cps_closing] = [cps_open] then begin + include(fstate,cps_closing); + try + if fowner.canevent(tmethod(fonbeforedisconnect)) then begin + fonbeforedisconnect(self); + end; + internalclose; + if fowner.canevent(tmethod(fonafterdisconnect)) then begin + fonafterdisconnect(self); + end; + finally + fstate:= fstate - [cps_closing,cps_open]; + end; + end; +end; + +function tcustomcommpipes.getoptionsreader: pipereaderoptionsty; +begin + result:= frx.options; +end; + +procedure tcustomcommpipes.setoptionsreader(const avalue: pipereaderoptionsty); +begin + frx.options:= avalue; +end; + +function tcustomcommpipes.getrxtimeoutms: integer; +begin + result:= frx.timeoutms; +end; + +procedure tcustomcommpipes.setrxtimeoutms(const avalue: integer); +begin + frx.timeoutms:= avalue; +end; + +function tcustomcommpipes.gettxtimeoutms: integer; +begin + result:= ftx.timeoutms; +end; + +procedure tcustomcommpipes.settxtimeoutms(const avalue: integer); +begin + ftx.timeoutms:= avalue; +end; + +procedure tcustomcommpipes.dorxchange(const areader: tcommreader); +var + int1: integer; +begin + for int1:= 0 to high(fowner.fclients) do begin + fowner.fclients[int1].dorxchange(areader); + end; +end; + +{ +procedure tcustomcommpipes.runhandlerapp(const commandline: filenamety); +var + rxha,txha: integer; + str1: string; +begin + rxha:= frx.handle; + txha:= ftx.handle; + frx.releasehandle; + ftx.releasehandle; + include(fstate,sops_detached); + internalclose; + execmse1(commandline,@rxha,@txha); +end; +} +{ tcustomcommcomp } + +constructor tcustomcommcomp.create(aowner: tcomponent); +begin + fhandle:= invalidfilehandle; + inherited; +end; + +destructor tcustomcommcomp.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + fclients[int1].setcommserverintf(nil); + end; + fclients:= nil; + inherited; +end; + +procedure tcustomcommcomp.doactivated; +begin + active:= true; +// if factive then begin +// connect; +// end; +end; + +procedure tcustomcommcomp.dodeactivated; +begin + active:= false; +end; + +procedure tcustomcommcomp.internaldisconnect; +begin + fhandle:= invalidfilehandle; + factive:= false; +end; + +procedure tcustomcommcomp.checkinactive; +begin + if not (csloading in componentstate) and active then begin + raise exception.create('Socket must be inactive.'); + end; +end; + +procedure tcustomcommcomp.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + if not (csreading in componentstate) then begin + if avalue then begin + connect; + end + else begin + disconnect; + end; + end + else begin + factiveafterload:= avalue; + end; + end; +end; + +procedure tcustomcommcomp.doafterconnect(const sender: tcustomcommpipes); +begin + if canevent(tmethod(fonafterconnect)) then begin + application.lock; + try + fonafterconnect(self); + finally + application.unlock; + end; + end; +end; + +procedure tcustomcommcomp.connect; +begin + if canevent(tmethod(fonbeforeconnect)) then begin + fonbeforeconnect(self); + end; + internalconnect; +end; + +procedure tcustomcommcomp.disconnect; +begin + if canevent(tmethod(fonbeforedisconnect)) then begin + fonbeforedisconnect(self); + end; + internaldisconnect; + if canevent(tmethod(fonafterdisconnect)) then begin + fonafterdisconnect(self); + end; +end; + +procedure tcustomcommcomp.setcryptoio(const avalue: tcryptoio); +begin + setlinkedvar(avalue,tmsecomponent(fcryptoio)); +end; + +procedure tcustomcommcomp.loaded; +begin + inherited; + if factiveafterload then begin + active:= true; + end; +end; + +function tcustomcommcomp.gethalfduplex: boolean; +begin + result:= false; +end; + +function tcustomcommcomp.calctransmissiontime(const alength: integer): integer; +begin + result:= 0; +end; + +procedure tcustomcommcomp.writedata(const adata: string); +begin + syserror(trywritedata(adata)); +end; + +{ tcommreader } + +constructor tcommreader.create(const apipes: tcustomcommpipes); +begin + fpipes:= apipes; + inherited create; + fstate:= fstate + [tss_haslink]; +end; + +procedure tcommreader.settimeoutms(const avalue: integer); +begin + ftimeoutms:= avalue; +end; + +function tcommreader.execthread(thread: tmsethread): integer; +var + bo1: boolean; +begin +{$ifdef mse_debugsockets} + debugout(self,'socketreader execthread'); +{$endif} + fthread:= tsemthread(thread); + try + if assigned(fonafterconnect) then begin + try + fonafterconnect; + except + include(fstate,tss_error); + include(fstate,tss_eof); + doinputavailable; + raise; + end; + end; + with fthread do begin + while not terminated and not (tss_error in fstate) do begin + bo1:= doread(fmsbuf,sizeof(fmsbuf),fmsbufcount); + if not terminated then begin + if not bo1 then begin + include(fstate,tss_error); //broken socket + end; + if (fmsbufcount > 0) or (tss_error in fstate) then begin + include(fstate,tss_pipeactive); + doinputavailable; + if not terminated and not (tss_error in fstate) then begin + semwait; + end; + end; + end; + end; + include(fstate,tss_eof); + end; + result:= 0; + finally + if assigned(fonthreadterminate) then begin + fonthreadterminate; + end; + end; +{$ifdef mse_debugsockets} + debugout(self,'socketreader exitthread'); +{$endif} +end; + +function tcommreader.internalread(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean = false): boolean; +begin + result:= inherited doread(buf,acount,readcount,nonblocked); +end; + +function tcommreader.doread(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean = false): boolean; +var + int1: integer; +begin + if fcrypto <> nil then begin + if nonblocked then begin + int1:= -1; + end + else begin + int1:= 0; + end; + readcount:= cryptoread(fcrypto^,@buf,acount,int1); + result:= readcount >= 0; + if not result then begin + readcount:= 0; + end; + end + else begin + result:= internalread(buf,acount,readcount,nonblocked); + end; +end; + +procedure tcommreader.dochange; +begin + fpipes.dorxchange(self); +end; + +{ tcommwriter } + +constructor tcommwriter.create(const aowner: tcustomcommpipes); +begin + fowner:= aowner; + inherited create; +end; + +procedure tcommwriter.settimeoutms(const avalue: integer); +begin + ftimeoutms:= avalue; +end; + +function tcommwriter.internalwrite(const buffer; count: longint): longint; +begin + result:= inherited dowrite(buffer,count); +end; + +function tcommwriter.dowrite(const buffer; count: longint): longint; +begin + if fcrypto <> nil then begin + result:= cryptowrite(fcrypto^,@buffer,count,ftimeoutms); + end + else begin + result:= internalwrite(buffer,count); + end; +end; + +{ tcustomsercommchannel } + +constructor tcustomsercommchannel.create(aowner: tcomponent); +begin + feor:= c_linefeed; + sys_semcreate(fsem,0); + ftimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}dotimer,false,[to_single]); + inherited; +end; + +destructor tcustomsercommchannel.destroy; +begin + clear; + ftimer.free; + sercomm:= nil; + sys_semdestroy(fsem); + inherited; +end; + +procedure tcustomsercommchannel.setsercomm(const avalue: tcustomcommcomp); +begin + if fsercomm <> avalue then begin + setcomcomp(icommclient(self),avalue,fsercomm); + end; +end; + +procedure tcustomsercommchannel.setcommserverintf(const aintf: icommserver); +begin + fserverintf:= aintf; +end; + +procedure tcustomsercommchannel.doresponse; +begin + if canevent(tmethod(fonresponse)) then begin + fonresponse(self,fdata,fflags); + end; +end; + +procedure tcustomsercommchannel.dorxchange(const areader: tcommreader); +var + bo1: boolean; + int1: integer; +begin + if sccs_pending in fstate then begin + fdata:= fdata + areader.readdatastring; + fflags:= []; + if areader.eof then begin + include(fflags,crf_eof); + end; + if sccs_eor in fstate then begin + int1:= pos(feor,fdata); + bo1:= int1 > 0; + if bo1 then begin + setlength(fdata,int1-1); + end; + end + else begin + bo1:= length(fdata) >= fexpected; + end; + if (fflags <> []) or bo1 then begin + exclude(fstate,sccs_pending); + if fsercomm.gethalfduplex then begin + fdata:= copy(fdata,fsent+1,bigint); + fexpected:= fexpected - fsent; + end; + if length(fdata) < fexpected then begin + include(fflags,crf_trunc); + end; + ftimer.enabled:= false; + if sccs_sync in fstate then begin + sys_sempost(fsem); + end + else begin + doresponse; + end; + end; + end + else begin + areader.readdatastring; //drop the data + end; +end; + +procedure tcustomsercommchannel.dotimer(const sender: tobject); +begin + fflags:= [crf_timeout]; + doresponse; +end; + +function tcustomsercommchannel.internaltransmit(const adata: string; + const aresponselength: integer; const atimeoutus: integer; + const sync: boolean; const aeor: boolean): syserrorty; +var + int1: integer; +begin + result:= sye_ok; + application.lock; + try + clear; + checksercomm; + if aeor and (feor = '') then begin + componentexception(self,'No end of record marker'); + end; + fsent:= length(adata); + fexpected:= aresponselength; + if fsercomm.gethalfduplex then begin + fexpected:= fexpected+fsent; + end; + int1:= ftimeoutus; + if atimeoutus <> 0 then begin + int1:= atimeoutus; + end; + if atimeoutus = -2 then begin + int1:= 0; + end; + if int1 = -1 then begin + int1:= 2*fsercomm.calctransmissiontime(fexpected+fsent)+ftimeoutus; + end; + updatebit({$ifdef FPC}longword{$else}byte{$endif}(fstate), + ord(sccs_sync),sync); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(fstate),ord(sccs_eor),aeor); + include(fstate, sccs_pending); + result:= fsercomm.trywritedata(adata); + if result = sye_ok then begin + if sync then begin + sys_semtrywait(fsem); //clear + result:= application.semwait(fsem,int1); + exclude(fstate, sccs_pending); + end + else begin + if int1 > 0 then begin + ftimer.interval:= int1; + ftimer.enabled:= true; + end; + end; + end; + finally + application.unlock; + end; +end; + +function tcustomsercommchannel.transmit(const adata: string; + const aresponselength: integer; + const atimeoutus: integer = -1): syserrorty; +begin + result:= internaltransmit(adata,aresponselength,atimeoutus,false,false); +end; + +function tcustomsercommchannel.transmit(const adata: string; + const aresponselength: integer; + out aresult: string; + const atimeoutus: integer = -1): commresponseflagsty; + //synchronous +begin + case internaltransmit(adata,aresponselength,atimeoutus,true,false) of + sye_ok: begin + result:= fflags; + end; + sye_write: begin + result:= [crf_writeerror]; + end; + else begin + result:= [crf_timeout]; + end; + end; + aresult:= fdata; +end; + +procedure tcustomsercommchannel.checksercomm; +begin + if fsercomm = nil then begin + componentexception(self,'No sercomm.'); + end; + if not fsercomm.active then begin + componentexception(self,'sercomm inactive.'); + end; +end; + +procedure tcustomsercommchannel.clear; +begin + ftimer.enabled:= false; + fdata:= ''; + fstate:= fstate-[sccs_pending]; +end; + +function tcustomsercommchannel.transmiteor(const adata: string; + const aresponselength: integer = 0; + const atimeoutus: integer = -1): syserrorty; +begin + result:= internaltransmit(adata+feor,aresponselength,atimeoutus,false,true); +end; + +function tcustomsercommchannel.transmiteor(const adata: string; + out aresult: string; const aresponselength: integer = 0; + const atimeoutus: integer = -1): commresponseflagsty; +begin + case internaltransmit(adata+feor,aresponselength,atimeoutus,true,true) of + sye_ok: begin + result:= fflags; + end; + sye_write: begin + result:= [crf_writeerror]; + end; + else begin + result:= [crf_timeout]; + end; + end; + aresult:= fdata; +end; + +{ tsercommreader } + +function tsercommreader.internalread(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean = false): boolean; +begin + result:= tcustomsercommcomp(fpipes.fowner).port.piperead(buf,acount,readcount, + nonblocked); +// result:= inherited internalread(buf,acount,readcount,nonblocked); +end; + +{ tsercommwriter } + +function tsercommwriter.internalwrite(const buffer; count: longint): longint; +begin + result:= tcustomsercommcomp(fowner.fowner).port.pipewrite(buffer,count); +end; + +{ tasynsercommchannel } + +function tasynsercommchannel.getsercomm: tcustomsercommcomp; +begin + result:= tcustomsercommcomp(inherited sercomm); +end; + +procedure tasynsercommchannel.setsercomm(const avalue: tcustomsercommcomp); +begin + if avalue = nil then begin + connected:= false; + end; + inherited setsercomm(avalue); + if (avalue <> nil) and not (csloading in componentstate) then begin + setupcomm(avalue); + end; +end; + +procedure tasynsercommchannel.doconnect; +begin + if canevent(tmethod(fonconnect)) then begin + fonconnect(self); + end; +end; + +procedure tasynsercommchannel.dodisconnect; +begin + if canevent(tmethod(fondisconnect)) then begin + fondisconnect(self); + end; +end; + +procedure tasynsercommchannel.setconnected(const avalue: boolean); +begin + if csloading in componentstate then begin + fconnectafterload:= avalue; + end + else begin + if fconnected <> avalue then begin + if avalue then begin + connect; + end + else begin + disconnect; + end; + end; + end; +end; + +procedure tasynsercommchannel.loaded; +begin + inherited; + if fsercomm <> nil then begin + setupcomm(tcustomsercommcomp(fsercomm)); + end; + if fconnectafterload then begin + connect; + end; +end; + +procedure tasynsercommchannel.setupcomm(const acomm: tcustomsercommcomp); +begin + if canevent(tmethod(fonsetupcomm)) then begin + fonsetupcomm(self,acomm); + end; +end; + +procedure tasynsercommchannel.connect; +begin + if fsercomm <> nil then begin + fsercomm.active:= true; + end; + fconnected:= true; +end; + +procedure tasynsercommchannel.disconnect; +begin + fconnected:= false; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msedbus.pas b/mseide-msegui/lib/common/sysutils/msedbus.pas new file mode 100644 index 0000000..a9ad2ec --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msedbus.pas @@ -0,0 +1,750 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedbus; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msectypes,msetypes,msestrings; + +{$packrecords c} + +const +{$ifdef mswindows} + {$define wincall} //depends on compiler? + dbuslib: array[0..0] of filenamety = ('libdbus.dll'); +{$else} + dbuslib: array[0..1] of filenamety = ('libdbus-1.so','libdbus-1.so.3'); +{$endif} + +type + dbus_int64_t = int64; + dbus_uint64_t = uint64; + dbus_int32_t = int32; + pdbus_uint32_t = ^dbus_uint32_t; + dbus_uint32_t = uint32; + dbus_int16_t = int16; + dbus_uint16_t = uint16; + size_t = uint32; + dbus_unichar_t = dbus_uint32_t; + dbus_bool_t = dbus_uint32_t; + pdbus_bool_t = ^dbus_bool_t; + va_list = record end; + pva_list = ^va_list; + +//** +// * Indicates the status of incoming data on a #DBusConnection. This determines whether +// * dbus_connection_dispatch() needs to be called. +// */ + DBusDispatchStatus = ( + DBUS_DISPATCH_DATA_REMAINS, //**< There is more data to potentially convert to messages. */ + DBUS_DISPATCH_COMPLETE, //**< All currently available data has been processed. */ + DBUS_DISPATCH_NEED_MEMORY //**< More memory is needed to continue. */ + ); + +const + +//* Types of message */ + +//** This value is never a valid message type, see dbus_message_get_type() */ + DBUS_MESSAGE_TYPE_INVALID = 0; +//** Message type of a method call message, see dbus_message_get_type() */ + DBUS_MESSAGE_TYPE_METHOD_CALL = 1; +//** Message type of a method return message, see dbus_message_get_type() */ + DBUS_MESSAGE_TYPE_METHOD_RETURN = 2; +//** Message type of an error reply message, see dbus_message_get_type() */ + DBUS_MESSAGE_TYPE_ERROR = 3; +//** Message type of a signal message, see dbus_message_get_type() */ + DBUS_MESSAGE_TYPE_SIGNAL = 4; + + DBUS_NUM_MESSAGE_TYPES = 5; + +//** Type code that is never equal to a legitimate type code */ + DBUS_TYPE_INVALID = cint(0); +///** #DBUS_TYPE_INVALID as a string literal instead of a int literal */ + DBUS_TYPE_INVALID_AS_STRING = cchar(#0); + +//* Primitive types */ +//** Type code marking an 8-bit unsigned integer */ + DBUS_TYPE_BYTE = cint('y'); +//** #DBUS_TYPE_BYTE as a string literal instead of a int literal */ + DBUS_TYPE_BYTE_AS_STRING = 'y'; +//** Type code marking a boolean */ + DBUS_TYPE_BOOLEAN = cint('b'); +//** #DBUS_TYPE_BOOLEAN as a string literal instead of a int literal */ + DBUS_TYPE_BOOLEAN_AS_STRING = 'b'; +//** Type code marking a 16-bit signed integer */ + DBUS_TYPE_INT16 = cint('n'); +//** #DBUS_TYPE_INT16 as a string literal instead of a int literal */ + DBUS_TYPE_INT16_AS_STRING = 'n'; +//** Type code marking a 16-bit unsigned integer */ + DBUS_TYPE_UINT16 = cint('q'); +//** #DBUS_TYPE_UINT16 as a string literal instead of a int literal */ + DBUS_TYPE_UINT16_AS_STRING = 'q'; +//** Type code marking a 32-bit signed integer */ + DBUS_TYPE_INT32 = cint('i'); +//** #DBUS_TYPE_INT32 as a string literal instead of a int literal */ + DBUS_TYPE_INT32_AS_STRING = 'i'; +//** Type code marking a 32-bit unsigned integer */ + DBUS_TYPE_UINT32 = cint('u'); +//** #DBUS_TYPE_UINT32 as a string literal instead of a int literal */ + DBUS_TYPE_UINT32_AS_STRING = 'u'; +//** Type code marking a 64-bit signed integer */ + DBUS_TYPE_INT64 = cint('x'); +//** #DBUS_TYPE_INT64 as a string literal instead of a int literal */ + DBUS_TYPE_INT64_AS_STRING = 'x'; +//** Type code marking a 64-bit unsigned integer */ + DBUS_TYPE_UINT64 = cint('t'); +//** #DBUS_TYPE_UINT64 as a string literal instead of a int literal */ + DBUS_TYPE_UINT64_AS_STRING = 't'; +//** Type code marking an 8-byte double in IEEE 754 format */ + DBUS_TYPE_DOUBLE = cint('d'); +//** #DBUS_TYPE_DOUBLE as a string literal instead of a int literal */ + DBUS_TYPE_DOUBLE_AS_STRING = 'd'; +//** Type code marking a UTF-8 encoded, nul-terminated Unicode string */ + DBUS_TYPE_STRING = cint('s'); +//** #DBUS_TYPE_STRING as a string literal instead of a int literal */ + DBUS_TYPE_STRING_AS_STRING = 's'; +//** Type code marking a D-Bus object path */ + DBUS_TYPE_OBJECT_PATH = cint('o'); +//** #DBUS_TYPE_OBJECT_PATH as a string literal instead of a int literal */ + DBUS_TYPE_OBJECT_PATH_AS_STRING = 'o'; +//** Type code marking a D-Bus type signature */ + DBUS_TYPE_SIGNATURE = cint('g'); +//** #DBUS_TYPE_SIGNATURE as a string literal instead of a int literal */ + DBUS_TYPE_SIGNATURE_AS_STRING = 'g'; +//** Type code marking a unix file descriptor */ + DBUS_TYPE_UNIX_FD = cint('h'); +//** #DBUS_TYPE_UNIX_FD as a string literal instead of a int literal */ + DBUS_TYPE_UNIX_FD_AS_STRING = 'h'; + +//* Compound types */ +//** Type code marking a D-Bus array type */ + DBUS_TYPE_ARRAY = cint('a'); +//** #DBUS_TYPE_ARRAY as a string literal instead of a int literal */ + DBUS_TYPE_ARRAY_AS_STRING = 'a'; +//** Type code marking a D-Bus variant type */ + DBUS_TYPE_VARIANT = cint('v'); +//** #DBUS_TYPE_VARIANT as a string literal instead of a int literal */ + DBUS_TYPE_VARIANT_AS_STRING = 'v'; + +//** STRUCT and DICT_ENTRY are sort of special since their codes can't +// * appear in a type string, instead +// * DBUS_STRUCT_BEGIN_CHAR/DBUS_DICT_ENTRY_BEGIN_CHAR have to appear +// */ +//** Type code used to represent a struct; however, this type code does not appear +// * in type signatures, instead #DBUS_STRUCT_BEGIN_CHAR and #DBUS_STRUCT_END_CHAR will +// * appear in a signature. +// */ + DBUS_TYPE_STRUCT = cint('r'); +//** #DBUS_TYPE_STRUCT as a string literal instead of a int literal */ + DBUS_TYPE_STRUCT_AS_STRING = 'r'; +//** Type code used to represent a dict entry; however, this type code does not appear +// * in type signatures, instead #DBUS_DICT_ENTRY_BEGIN_CHAR and #DBUS_DICT_ENTRY_END_CHAR will +// * appear in a signature. +// */ + DBUS_TYPE_DICT_ENTRY = cint('e'); +//** #DBUS_TYPE_DICT_ENTRY as a string literal instead of a int literal */ + DBUS_TYPE_DICT_ENTRY_AS_STRING = 'e'; + +//* Owner flags */ + DBUS_NAME_FLAG_ALLOW_REPLACEMENT = $1; + //**< Allow another service to become the primary owner if requested */ + DBUS_NAME_FLAG_REPLACE_EXISTING = $2; + //**< Request to replace the current primary owner */ + DBUS_NAME_FLAG_DO_NOT_QUEUE = $4; + //**< If we can not become the primary owner do not place us in the queue */ + +//* Replies to request for a name */ + DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1; + //**< Service has become the primary owner of the requested name */ + DBUS_REQUEST_NAME_REPLY_IN_QUEUE = 2; + //**< Service could not become the primary owner and has been placed in the queue */ + DBUS_REQUEST_NAME_REPLY_EXISTS = 3; + //**< Service is already in the queue */ + DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER = 4; + //**< Service is already the primary owner */ + + DBUS_TIMEOUT_INFINITE = cint($7fffffff); + DBUS_TIMEOUT_USE_DEFAULT = cint(-1); + + DBUS_WATCH_READABLE = 1 shl 0; //**< As in POLLIN */ + DBUS_WATCH_WRITABLE = 1 shl 1; //**< As in POLLOUT */ + DBUS_WATCH_ERROR = 1 shl 2; //**< As in POLLERR (can't watch for + // * this, but can be present in + // * current state passed to + // * dbus_watch_handle()). + // */ + DBUS_WATCH_HANGUP = 1 shl 3; //**< As in POLLHUP (can't watch for + //* it, but can be present in current + //* state passed to + //* dbus_watch_handle()). + //*/ + //* Internal to libdbus, there is also _DBUS_WATCH_NVAL in dbus-watch.h */ + +type + DBusError = record + name: pcchar; //**< public error name field */ + message: pcchar; //**< public error message field */ + dummy: cuint; +// unsigned int dummy1 : 1; /**< placeholder */ +// unsigned int dummy2 : 1; /**< placeholder */ +// unsigned int dummy3 : 1; /**< placeholder */ +// unsigned int dummy4 : 1; /**< placeholder */ +// unsigned int dummy5 : 1; /**< placeholder */ + padding1: pointer; {< placeholder } + end; + pDBusError = ^DBusError; + + DBusMessageIter = record + dummy1: pointer; //**< Don't use this */ + dummy2: pointer; //**< Don't use this */ + dummy3: dbus_uint32_t; //**< Don't use this */ + dummy4: cint; //**< Don't use this */ + dummy5: cint; //**< Don't use this */ + dummy6: cint; //**< Don't use this */ + dummy7: cint; //**< Don't use this */ + dummy8: cint; //**< Don't use this */ + dummy9: cint; //**< Don't use this */ + dummy10: cint; //**< Don't use this */ + dummy11: cint; //**< Don't use this */ + pad1: cint; //**< Don't use this */ + pad2: cint; //**< Don't use this */ + pad3: pointer; //**< Don't use this */ + end; + pDBusMessageIter = ^DBusMessageIter; + + DBusConnection = record end; + pDBusConnection = ^DBusConnection; + DBusMessage = record end; + pDBusMessage = ^DBusMessage; + DBusWatch = record end; + pDBusWatch = ^DBusWatch; + DBusTimeout = record end; + pDBusTimeout = ^DBusTimeout; + DBusPendingCall = record end; + pDBusPendingCall = ^DBusPendingCall; + ppDBusPendingCall = ^pDBusPendingCall; + +//** +//* Results that a message handler can return. +//*/ +DBusHandlerResult = ( + DBUS_HANDLER_RESULT_HANDLED, + //**< Message has had its effect - no need to run more handlers. */ + DBUS_HANDLER_RESULT_NOT_YET_HANDLED, + //**< Message has not had any effect - see if other handlers want it. */ + DBUS_HANDLER_RESULT_NEED_MEMORY + //**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or + //#DBUS_HANDLER_RESULT_NOT_YET_HANDLED. + // Please try again later with more memory. */ +); + +///** +// * Called when a message needs to be handled. The result indicates whether or +// * not more handlers should be run. Set with dbus_connection_add_filter(). +// */ + DBusHandleMessageFunction = + function(connection: pDBusConnection; message: pDBusMessage; + user_data: pointer): DBusHandlerResult + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +//** +//* Called when a message is sent to a registered object path. Found in +//* #DBusObjectPathVTable which is registered with dbus_connection_register_object_path() +//* or dbus_connection_register_fallback(). +//*/ + DBusObjectPathMessageFunction = + function(connection: pDBusConnection; message: pDBusMessage; + user_data: pointer): DBusHandlerResult + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +//** +//* Called when a #DBusObjectPathVTable is unregistered (or its connection is freed). +//* Found in #DBusObjectPathVTable. +//*/ + DBusObjectPathUnregisterFunction = procedure(connection: pDBusConnection; + user_data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + DBusObjectPathVTable = record + unregister_function: DBusObjectPathUnregisterFunction; + //**< Function to unregister this handler */ + message_function: DBusObjectPathMessageFunction; + //**< Function to handle messages */ + + dbus_internal_pad1: pointer; //**< Reserved for future expansion */ + dbus_internal_pad2: pointer; //**< Reserved for future expansion */ + dbus_internal_pad3: pointer; //**< Reserved for future expansion */ + dbus_internal_pad4: pointer; //**< Reserved for future expansion */ + end; + pDBusObjectPathVTable = ^DBusObjectPathVTable; + + DBusBusType = ( + DBUS_BUS_SESSION, //**< The login session bus */ + DBUS_BUS_SYSTEM, //**< The systemwide bus */ + DBUS_BUS_STARTER //**< The bus that started us, if any */ + ); + + DBusFreeFunction = procedure(memory: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** Called when libdbus needs a new watch to be monitored by the main +//* loop. Returns #FALSE if it lacks enough memory to add the +//* watch. Set by dbus_connection_set_watch_functions() or +//* dbus_server_set_watch_functions(). +//*/ + DBusAddWatchFunction = function(watch: pDBusWatch; + data: pointer): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** Called when dbus_watch_get_enabled() may return a different value +//* than it did before. Set by dbus_connection_set_watch_functions() +//* or dbus_server_set_watch_functions(). +//*/ + DBusWatchToggledFunction = procedure(watch: pDBusWatch; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** Called when libdbus no longer needs a watch to be monitored by the +//* main loop. Set by dbus_connection_set_watch_functions() or +//* dbus_server_set_watch_functions(). +//*/ + DBusRemoveWatchFunction = procedure(watch: pDBusWatch; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** Called when libdbus needs a new timeout to be monitored by the main +//* loop. Returns #FALSE if it lacks enough memory to add the +//* watch. Set by dbus_connection_set_timeout_functions() or +//* dbus_server_set_timeout_functions(). +//*/ + DBusAddTimeoutFunction = function(timeout: pDBusTimeout; + data: pointer): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** Called when dbus_timeout_get_enabled() may return a different +//* value than it did before. +//* Set by dbus_connection_set_timeout_functions() or +//* dbus_server_set_timeout_functions(). +//*/ + DBusTimeoutToggledFunction = procedure(timeout: pDBusTimeout; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +//** Called when libdbus no longer needs a timeout to be monitored by the +//* main loop. Set by dbus_connection_set_timeout_functions() or +//* dbus_server_set_timeout_functions(). +//*/ + DBusRemoveTimeoutFunction = procedure(timeout: pDBusTimeout; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** +//* Called when a pending call now has a reply available. Set with +//* dbus_pending_call_set_notify(). +//*/ + DBusPendingCallNotifyFunction = procedure(pending: pDBusPendingCall; + user_data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +var + dbus_bus_get: + function(type_: DBusBusType; error: PDBusError): PDBusConnection + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_bus_get_private: + function(type_: DBusBusType; error: PDBusError): PDBusConnection + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_close: procedure(connection: pDBusConnection) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_shutdown: procedure() + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_connection_set_watch_functions: + function(connection: pDBusConnection; add_function: DBusAddWatchFunction; + remove_function: DBusRemoveWatchFunction; + toggled_function: DBusWatchToggledFunction; + data: pointer; + free_data_function: DBusFreeFunction): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_set_timeout_functions: + function(connection: pDBusConnection; add_function: DBusAddTimeoutFunction; + remove_function: DBusRemoveTimeoutFunction; + toggled_function: DBusTimeoutToggledFunction; + data: pointer; + free_data_function: DBusFreeFunction): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_connection_add_filter: + function(connection: pDBusConnection; function_: DBusHandleMessageFunction; + user_data: pointer; free_data_function: DBusFreeFunction): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_remove_filter: + procedure(connection: pDBusConnection; + function_: DBusHandleMessageFunction; user_data: pointer); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_try_register_object_path: + function(cionnection: pDBusConnection; path: pchar; + vtable: pDBusObjectPathVTable; + user_data: pointer; error: pDBusError): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_unregister_object_path: + function(connection: pDBusConnection; path: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_try_register_fallback: + function(connection: pDBusConnection; path: pcchar; + vtable: pDBusObjectPathVTable; user_data: pointer; + error: pDBusError): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_watch_get_unix_fd: function(watch: pDBusWatch): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_get_socket: function(watch: pDBusWatch): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_get_flags: function(watch: pDBusWatch): cuint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_get_data: function(watch: pDBusWatch): pointer + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_set_data: procedure(watch: pDBusWatch; data: pointer; + free_data_function: DBusFreeFunction) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_handle: function(watch: pDBusWatch; flags: cuint): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_get_enabled: function(watch: pDBusWatch): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_timeout_get_interval: function(timeout: pDBusTimeout): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_get_data: function(timeout: pDBusTimeout): pointer + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_set_data: procedure(timeout: pDBusTimeout; data: pointer; + free_data_function: DBusFreeFunction) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_handle: function(timeout: pDBusTimeout): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_get_enabled: function(timeout: pDBusTimeout): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_needs_restart: function(timeout: pDBusTimeout): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_restarted: procedure(timeout: pDBusTimeout) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_error_init: procedure(error: pDBusError) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_error_free: procedure(error: pDBusError) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_error_is_set: function(error: pDBusError): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_set_exit_on_disconnect: + procedure(connection: pDBusConnection; exit_on_disconnect: dbus_bool_t) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_bus_get_unique_name: function(connection: pDBusConnection): pcchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_bus_request_name: + function(connection: PDBusConnection; name: pcchar; flags: cuint; + error: pDBusError): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_new_method_call: + function(bus_name: pcchar; path: pcchar; iface: pcchar; + method: pcchar): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_new_method_return: + function(method_call: pDBusMessage): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_new_signal: + function(path: pchar; iface: pchar; name: pcchar): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_new_error: + function(reply_to: pDBusMessage; error_name: pcchar; + error_message: pcchar): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_message_unref: procedure(message: pDBusMessage) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_type: function(message: pDBusMessage): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_path: function(message:pDBusMessage; + object_path: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_path: function(message: pDBusMessage): pcchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_interface: + function(message: pDBusMessage; iface: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_interface: function(message: pDBusMessage): pcchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_member: + function(message: pDBusMessage; member: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_member: function(message: pDBusMessage): pcchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_error_name: + function(message: pDBusMessage; name: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_error_name: + function(message: pDBusMessage): pcchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_destination: + function(message: pDBusMessage; destination: pchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_destination: function(message: pDBusMessage): pchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_sender: + function(msessage: pDBusMessage; sender: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_sender: function (message: pDBusMessage): pcchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_signature: function(message: pDBusMessage): pchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_no_reply: + procedure(message: pDBusMessage; no_reply: dbus_bool_t) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_no_reply: function(message: pDBusMessage): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_message_iter_init_append: + procedure(message: pDBusMessage; iter: pDBusMessageIter) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_init: + function(message: pDBusMessage; iter: pDBusMessageIter): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_append_args_valist: + function (message: pDBusMessage; first_arg_type: cint; + var_args: pva_list): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_append_basic: + function(iter: pDBusMessageIter; type_: cint; value: pointer): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_append_fixed_array: + function(iter: pDBusMessageIter; element_type: cint; value: pointer; + n_elements: cint): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_message_iter_next: function (iter: pDBusMessageIter): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_get_arg_type: function (iter: pDBusMessageIter): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_get_basic: procedure (iter: pDBusMessageIter; value: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_open_container: + function(iter: pDBusMessageIter; type_: cint; + const contained_signature: pcchar; + sub: pDBusMessageIter): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_close_container: + function(iter: pDBusMessageIter; sub: pDBusMessageIter): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_abandon_container: + procedure(iter: pDBusMessageIter; sub: pDBusMessageIter); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_message_iter_recurse: + procedure (iter: pDBusMessageIter; sub: pDBusMessageIter) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_get_element_type: function (iter: pDBusMessageIter): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_get_fixed_array: + procedure (iter: pDBusMessageIter; value: pointer; n_elements: pcint) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_connection_send_with_reply_and_block: + function(connection: pDBusConnection; message: pDBusMessage; + timeout_milliseconds: cint; error: pDBusError): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_send_with_reply: + function(connection: pDBusConnection; message: pDBusMessage; + pending_return: ppDBusPendingCall; + timeout_milliseconds: cint): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_send: + function(connection: pDBusConnection; message: pDBusMessage; + client_serial: pdbus_uint32_t): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_flush: procedure(connection: pDBusConnection) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_dispatch: + function(connection: pDBusConnection): DBusDispatchStatus + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_pending_call_unref: procedure(pending: pDBusPendingCall) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_pending_call_set_notify: + function(pending: pDBusPendingCall; + function_: DBusPendingCallNotifyFunction; + user_data: pointer; free_user_data: DBusFreeFunction): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_pending_call_steal_reply: + function(pending: pDBusPendingCall): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_bus_add_match: + procedure(connection: pDBusConnection; rule: pcchar; error: pDBusError) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_bus_remove_match: + procedure(connection: pDBusConnection; rule: pcchar; error: pDBusError) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function initializedbus(const sonames: array of filenamety; //[] = default + const onlyonce: boolean = false): boolean; + //true if ok +procedure releasedbus(); + +implementation +uses + msedynload,sysutils; +var + libinfo: dynlibinfoty; + +procedure inidbus(const data: pointer); +begin +end; + +procedure finidbus(const data: pointer); +begin +end; + +function initializedbus(const sonames: array of filenamety; //[] = default + const onlyonce: boolean = false): boolean; +const + funcs: array[0..76] of funcinfoty = ( + (n: 'dbus_bus_get'; d: @dbus_bus_get), // 0 + (n: 'dbus_bus_get_private'; d: @dbus_bus_get_private), // 1 + (n: 'dbus_connection_close'; d: @dbus_connection_close), // 2 + (n: 'dbus_shutdown'; d: @dbus_shutdown), // 3 + (n: 'dbus_connection_set_watch_functions'; + d: @dbus_connection_set_watch_functions), // 4 + (n: 'dbus_connection_set_timeout_functions'; + d: @dbus_connection_set_timeout_functions), // 5 + (n: 'dbus_connection_add_filter'; + d: @dbus_connection_add_filter), // 6 + (n: 'dbus_connection_remove_filter'; + d: @dbus_connection_remove_filter), // 7 + (n: 'dbus_connection_try_register_object_path'; + d: @dbus_connection_try_register_object_path), // 8 + (n: 'dbus_connection_try_register_fallback'; + d: @dbus_connection_try_register_fallback), // 9 + (n: 'dbus_connection_unregister_object_path'; + d: @dbus_connection_unregister_object_path), //10 + (n: 'dbus_watch_get_unix_fd'; d: @dbus_watch_get_unix_fd), //11 + (n: 'dbus_watch_get_socket'; d: @dbus_watch_get_socket), //12 + (n: 'dbus_watch_get_flags'; d: @dbus_watch_get_flags), //13 + (n: 'dbus_watch_get_data'; d: @dbus_watch_get_data), //14 + (n: 'dbus_watch_set_data'; d: @dbus_watch_set_data), //15 + (n: 'dbus_watch_handle'; d: @dbus_watch_handle), //16 + (n: 'dbus_watch_get_enabled'; d: @dbus_watch_get_enabled), //17 + + (n: 'dbus_timeout_get_interval'; + d: @dbus_timeout_get_interval), //18 + (n: 'dbus_timeout_get_data'; d: @dbus_timeout_get_data), //19 + (n: 'dbus_timeout_set_data'; d: @dbus_timeout_set_data), //20 + (n: 'dbus_timeout_handle'; d: @dbus_timeout_handle), //21 + (n: 'dbus_timeout_get_enabled'; d: @dbus_timeout_get_enabled), //22 + (n: 'dbus_timeout_needs_restart'; + d: @dbus_timeout_needs_restart), //23 + (n: 'dbus_timeout_restarted'; d: @dbus_timeout_restarted), //24 + + (n: 'dbus_error_init'; d: @dbus_error_init), //25 + (n: 'dbus_error_free'; d: @dbus_error_free), //26 + (n: 'dbus_error_is_set'; d: @dbus_error_is_set), //27 + (n: 'dbus_connection_set_exit_on_disconnect'; + d: @dbus_connection_set_exit_on_disconnect), //28 + (n: 'dbus_bus_get_unique_name'; d: @dbus_bus_get_unique_name), //29 + (n: 'dbus_bus_request_name'; d: @dbus_bus_request_name), //30 + (n: 'dbus_message_new_method_call'; + d: @dbus_message_new_method_call), //31 + (n: 'dbus_message_new_method_return'; + d: @dbus_message_new_method_return), //32 + (n: 'dbus_message_new_signal'; d: @dbus_message_new_signal), //33 + (n: 'dbus_message_new_error'; d: @dbus_message_new_error), //34 + (n: 'dbus_message_get_type'; d: @dbus_message_get_type), //35 + (n: 'dbus_message_set_path'; d: @dbus_message_set_path), //36 + (n: 'dbus_message_get_path'; d: @dbus_message_get_path), //37 + (n: 'dbus_message_set_interface'; + d: @dbus_message_set_interface), //38 + (n: 'dbus_message_get_interface'; + d: @dbus_message_get_interface), //39 + (n: 'dbus_message_set_member'; d: @dbus_message_set_member), //40 + (n: 'dbus_message_get_member'; d: @dbus_message_get_member), //41 + (n: 'dbus_message_set_error_name'; + d: @dbus_message_set_error_name), //42 + (n: 'dbus_message_get_error_name'; + d: @dbus_message_get_error_name), //43 + (n: 'dbus_message_set_destination'; + d: @dbus_message_set_destination), //44 + (n: 'dbus_message_get_destination'; + d: @dbus_message_get_destination), //45 + (n: 'dbus_message_set_sender'; d: @dbus_message_set_sender), //46 + (n: 'dbus_message_set_sender'; d: @dbus_message_set_sender), //47 + (n: 'dbus_message_get_sender'; d: @dbus_message_get_sender), //48 + (n: 'dbus_message_get_signature'; + d: @dbus_message_get_signature), //49 + (n: 'dbus_message_set_no_reply'; + d: @dbus_message_set_no_reply), //50 + (n: 'dbus_message_get_no_reply'; + d: @dbus_message_get_no_reply), //51 + + (n: 'dbus_message_unref'; d: @dbus_message_unref), //52 + (n: 'dbus_message_iter_init_append'; + d: @dbus_message_iter_init_append), //53 + (n: 'dbus_message_iter_init'; d: @dbus_message_iter_init), //54 + (n: 'dbus_message_append_args_valist'; + d: @dbus_message_append_args_valist), //55 + (n: 'dbus_message_iter_append_basic'; + d: @dbus_message_iter_append_basic), //56 + (n: 'dbus_message_iter_append_fixed_array'; + d: @dbus_message_iter_append_fixed_array), //57 + (n: 'dbus_message_iter_next'; d: @dbus_message_iter_next), //58 + (n: 'dbus_message_iter_get_arg_type'; + d: @dbus_message_iter_get_arg_type), //59 + (n: 'dbus_message_iter_get_basic'; + d: @dbus_message_iter_get_basic), //60 + (n: 'dbus_message_iter_open_container'; + d: @dbus_message_iter_open_container), //61 + (n: 'dbus_message_iter_close_container'; + d: @dbus_message_iter_close_container), //62 + (n: 'dbus_message_iter_abandon_container'; + d: @dbus_message_iter_abandon_container), //63 + (n: 'dbus_message_iter_recurse'; + d: @dbus_message_iter_recurse), //64 + (n: 'dbus_message_iter_get_element_type'; + d: @dbus_message_iter_get_element_type), //65 + (n: 'dbus_message_iter_get_fixed_array'; + d: @dbus_message_iter_get_fixed_array), //66 + (n: 'dbus_connection_send_with_reply_and_block'; + d: @dbus_connection_send_with_reply_and_block), //67 + (n: 'dbus_connection_send_with_reply'; + d: @dbus_connection_send_with_reply), //68 + (n: 'dbus_connection_send'; d: @dbus_connection_send), //69 + (n: 'dbus_connection_flush'; d: @dbus_connection_flush), //70 + (n: 'dbus_connection_dispatch'; d: @dbus_connection_dispatch), //71 + (n: 'dbus_pending_call_unref'; d: @dbus_pending_call_unref), //72 + (n: 'dbus_pending_call_set_notify'; + d: @dbus_pending_call_set_notify), //73 + (n: 'dbus_pending_call_steal_reply'; + d: @dbus_pending_call_steal_reply), //74 + (n: 'dbus_bus_add_match'; d: @dbus_bus_add_match), //75 + (n: 'dbus_bus_remove_match'; d: @dbus_bus_remove_match) //76 + ); + +{ + (n: ''; d: @),// +} + + errormessage = 'Can not load D-Bus library. '; + +begin + if not onlyonce or (libinfo.refcount = 0) then begin + result:= initializedynlib(libinfo,sonames,dbuslib,funcs,[], + errormessage,@inidbus,true); + end; +end; + +procedure releasedbus(); +begin + releasedynlib(libinfo,@finidbus); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/sysutils/msedbusinterface.pas b/mseide-msegui/lib/common/sysutils/msedbusinterface.pas new file mode 100644 index 0000000..77e8575 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msedbusinterface.pas @@ -0,0 +1,3916 @@ +{ MSEgui Copyright (c) 2016-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedbusinterface; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on} + {$if FPC_FULLVERSION >= 030000} {$define mse_fpc_3_0} {$endif} + {$if FPC_FULLVERSION >= 030100} {$define mse_fpc_3_2} {$endif} +{$endif} + +{$ifdef mswindows} + {$define wincall} //depends on compiler? +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseglob,msectypes,msedbus,msetypes,mseclasses,mseevent,msehash,sysutils, + msesys,msetimer,msehashstore,msestringident,mselinklist,typinfo; + +const + msebusname = 'mse.msegui.app'; + +type + dbusdataty = ( + dbt_INVALID, + dbt_BYTE, + dbt_BOOLEAN, + dbt_INT16, + dbt_UINT16, + dbt_INT32, + dbt_UINT32, + dbt_INT64, + dbt_UINT64, + dbt_DOUBLE, + dbt_STRING, + dbt_OBJECT_PATH, + dbt_SIGNATURE, + dbt_UNIX_FD, + dbt_ARRAY, + dbt_VARIANT, + dbt_STRUCT, + dbt_DICT_ENTRY, + dbt_msevariant, + dbt_structend + ); + pdbusdataty = ^dbusdataty; + dbusdatatyarty = array of dbusdataty; + + variantvaluekindty = (vvk_none,vvk_string,vvk_int32,vvk_card32,vvk_dynar, + vvk_record,vvk_variantar); + dynarinfoty = record + data: pointer; + typinfo: ptypeinfo; + end; + pdynarinfoty = ^dynarinfoty; + variantarinfoty = record + data: pointer; //variantvaluearty + typinfo: ptypeinfo; + end; +// pvariantarinfoty = ^variantarinfoty; + + variantflagty = (vf_var,vf_dict); + variantflagsty = set of variantflagty; + variantvaluety = record +// types: dbusdatatyarty; + flags: variantflagsty; + case kind: variantvaluekindty of + vvk_string: (vstring: pointer;); + vvk_int32: (vint32: int32;); + vvk_card32: (vcard32: card32;); + vvk_dynar: (vdynar: dynarinfoty); + vvk_record,vvk_variantar: (vvariantar: variantarinfoty); + end; + pvariantvaluety = ^variantvaluety; + variantvaluearty = array of variantvaluety; + + dictentryty = record + name: string; + value: variantvaluety; + end; + pdictentryty = ^dictentryty; + dictentryarty = array of dictentryty; + + edbus = class(exception) + end; + + idbusclient = interface(iobjectlink) + end; + idbusresponse = interface(idbusclient) + procedure replied(const serial: card32; const amessage: pdbusmessage{; + const auser_data: pointer}); + end; + +const + dbusdatasizes: array[dbusdataty] of int32 = ( + 0, //dbt_INVALID, + sizeof(byte), //dbt_BYTE, + sizeof(boolean), //dbt_BOOLEAN, + sizeof(int16), //dbt_INT16, + sizeof(card16), //dbt_UINT16, + sizeof(int32), //dbt_INT32, + sizeof(card32), //dbt_UINT32, + sizeof(int64), //dbt_INT64, + sizeof(card64), //dbt_UINT64, + sizeof(flo64), //dbt_DOUBLE, + sizeof(ansistring), //dbt_STRING, + sizeof(ansistring), //dbt_OBJECT_PATH, + sizeof(ansistring), //dbt_SIGNATURE, + 0, //dbt_UNIX_FD, + sizeof(dynarinfoty), //dbt_ARRAY, + 0, //dbt_VARIANT, + 0, //dbt_STRUCT, + sizeof(dictentryty), //dbt_DICT_ENTRY + sizeof(variantvaluety), //dbt_msevariant + 0 //dbt_structend + ); + + methodhandlerid = strid0; + signalmatchid = strid1; + signalhandlerid = strid1; + separatorid = strid3; + +var + arraytypes: array[dbusdataty] of pdynarraytypeinfo; +const + dbusdatacodes: array[dbusdataty] of cint = ( + DBUS_TYPE_INVALID, + DBUS_TYPE_BYTE, + DBUS_TYPE_BOOLEAN, + DBUS_TYPE_INT16, + DBUS_TYPE_UINT16, + DBUS_TYPE_INT32, + DBUS_TYPE_UINT32, + DBUS_TYPE_INT64, + DBUS_TYPE_UINT64, + DBUS_TYPE_DOUBLE, + DBUS_TYPE_STRING, + DBUS_TYPE_OBJECT_PATH, + DBUS_TYPE_SIGNATURE, + DBUS_TYPE_UNIX_FD, + DBUS_TYPE_ARRAY, + DBUS_TYPE_VARIANT, + DBUS_TYPE_STRUCT, + DBUS_TYPE_DICT_ENTRY, + -1, //dbt_msevariant + -1 //dbt_structend + ); + + dbusdatatycodes: array[variantvaluekindty] of cint = ( + DBUS_TYPE_INVALID, //vvk_none + DBUS_TYPE_STRING, //vvk_string, + DBUS_TYPE_INT32, //vvk_int32, + DBUS_TYPE_UINT32, //vvk_card32, + DBUS_TYPE_INVALID, //vvk_dynar, + DBUS_TYPE_INVALID, //vvk_record + DBUS_TYPE_INVALID //vvk_variantar + ); + + dbusdatastrings: array[dbusdataty] of string = ( + DBUS_TYPE_INVALID_AS_STRING, + DBUS_TYPE_BYTE_AS_STRING, + DBUS_TYPE_BOOLEAN_AS_STRING, + DBUS_TYPE_INT16_AS_STRING, + DBUS_TYPE_UINT16_AS_STRING, + DBUS_TYPE_INT32_AS_STRING, + DBUS_TYPE_UINT32_AS_STRING, + DBUS_TYPE_INT64_AS_STRING, + DBUS_TYPE_UINT64_AS_STRING, + DBUS_TYPE_DOUBLE_AS_STRING, + DBUS_TYPE_STRING_AS_STRING, + DBUS_TYPE_OBJECT_PATH_AS_STRING, + DBUS_TYPE_SIGNATURE_AS_STRING, + DBUS_TYPE_UNIX_FD_AS_STRING, + '',//DBUS_TYPE_ARRAY_AS_STRING, + '',//DBUS_TYPE_VARIANT_AS_STRING, + '',//DBUS_TYPE_STRUCT_AS_STRING, + '{sv}', //DBUS_TYPE_DICT_ENTRY_AS_STRING + '', //dbt_msevariant + '' //dbt_structend + ); + +type + messageeventty = procedure(const amessage: pdbusmessage; + var handled: boolean) of object; + messagedataeventty = procedure(const amessage: pdbusmessage; + const data: pointer; var handled: boolean) of object; + //default false + + idbusservice = interface; + + idbusobject = interface(inullinterface) + function getinstance: tobject; + procedure registeritems(const sender: idbusservice); + function getpath(): string; + function getintrospecttext(const aindent: int32): string; + procedure busconnected(); + end; + + idbusservice = interface(inullinterface) + procedure registerobject(const sender: idbusobject); + procedure unregisterobject(const sender: idbusobject); + procedure registermethodhandler(const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); + + procedure registersignalhandler(const asender: string; const apath: string; + const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); + end; + +type + watchinfoty = record + flags: pollflagsty; + id: int32; + watch: pdbuswatch; + end; + pwatchinfoty = ^watchinfoty; + + timeoutinfoty = record + timeout: pdbustimeout; + timer: tsimpletimer; + end; + ptimeoutinfoty = ^timeoutinfoty; + + pendinginfoty = record + pendingpo: pdbuspendingcall; + serial: card32; + link: hashoffsetty; + prev: hashoffsetty; + next: hashoffsetty; + end; + ppendinginfoty = ^pendinginfoty; + + linkinfoty = record + link: idbusclient; + pendingoffs: hashoffsetty; //chain + end; + plinkinfoty = ^linkinfoty; + + objinfoty = record + prev: hashoffsetty; + next: hashoffsetty; + obj: idbusobject; +// path: pointer; //string +// items: pointer; //stringarty + handlers: pointer; //hashoffsetarty + end; + pobjinfoty = ^objinfoty; + + itemkindty = (dbk_watch,dbk_timeout,dbk_pending,dbk_link,dbk_obj); + + dbusinfoty = record + case kind: itemkindty of + dbk_watch: (watch: watchinfoty); + dbk_timeout: (timeout: timeoutinfoty); + dbk_pending: (pending: pendinginfoty); + dbk_link: (link: linkinfoty); + dbk_obj: (obj: objinfoty); + end; + pdbusinfoty = ^dbusinfoty; + dbusitemty = record + key: pointer; + data: dbusinfoty; + end; + pdbusitemty = ^dbusitemty; + dbusitemhashdataty = record + header: hashheaderty; + data: dbusitemty; + end; + pdbusitemhashdataty = ^dbusitemhashdataty; + + tdbusservice = class; + + tdbusitemhashdatalist = class(tpointerhashdatalist,iobjectlink) + private + fwatches: card32arty; + funlinking: boolean; + fserial: card32; + protected + fowner: tdbusservice; + fobjects: hashoffsetty; //chain + flastobject: hashoffsetty; + procedure finalizeitem(const aitem: phashdataty) override; + procedure dopollcallback(const aflags: pollflagsty; const adata: pointer); + function findwatch(const key: pdbuswatch): pwatchinfoty; + function findtimeout(const key: pdbustimeout): ptimeoutinfoty; + function findpending(const key: pdbuspendingcall): ppendinginfoty; + + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + //source = 1 -> dest destroyed + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + function getrecordsize(): int32 override; + public + constructor create(const aowner: tdbusservice); + function addwatch(const key: pdbuswatch): pwatchinfoty; + function addlink(const alink: idbusclient; + const apending: hashoffsetty): plinkinfoty; + function addpending(const apending: pdbuspendingcall; + const alink: idbusresponse; + var aserial: card32): ppendinginfoty; + function addobject(const aobj: idbusobject): pobjinfoty; +// function addpending(const aitem: pdbuspendingcall): ppendinginfoty; +// procedure freeitems(); + procedure handlewatches(); + end; + + handlerkindty = (hk_none,hk_match,hk_method,hk_signal); + + signaldataty = record + match: hashoffsetty; + prev: hashoffsetty; + next: hashoffsetty; + end; + handlerhandlerdataty = record + handler: messagedataeventty; + datapo: pointer; + case handlerkindty of + hk_signal: (signal: signaldataty); + end; + handlermatchdataty = record + match: identty; + refcount: int32; + end; + + handlerdataty = record + case kind: handlerkindty of + hk_match: + (match: handlermatchdataty); + hk_method,hk_signal: + (handler: handlerhandlerdataty); + end; + handlerhashdataty = record + header: treeelementhashdataty; + data: handlerdataty; + end; + phandlerhashdataty = ^handlerhashdataty; + + thandlerhashdatalist = class(thashtree) + private + fstringidents: tstringidents; + femptystringid: identty; + protected + fowner: tdbusservice; + function getrecordsize(): int32 override; + procedure finalizeitem(const aitem: phashdataty) override; + + public + constructor create(const aowner: tdbusservice); + destructor destroy(); override; + function scanpath(var avec: identvecty; + const apath: pchar; const aseparator: char): boolean; + //true if ok, too many levels otherwise + function addmethod(const aobject,ainterface,amember,asignature: string; + out adata: phandlerhashdataty): hashoffsetty; + function findmethod(const aobject,ainterface,amember, + asignature: pchar): phandlerhashdataty; + function addsignal( + const asender,apath,ainterface,amember,asignature: string; + out adata: phandlerhashdataty): hashoffsetty; + function findsignal(const asender,apath,ainterface,amember, + asignature: pchar): phandlerhashdataty; + end; + + tdbusservice = class(tlinkedobject,idbusservice,idbusobject) + private + fconn: pdbusconnection; + ferr: dbuserror; + fbusid: string; + fbusname: string; + fitems: tdbusitemhashdatalist; + fregisteringobj: pobjinfoty; + fregisteringpath: string; + fhandlers: thandlerhashdatalist; +// fwatches: array of pwatchinfoty; +// ftimeouts: array of ptimeoutinfoty; +// fpendings: array of ppendinfoty; + protected + procedure disconnect(); + function doaddwatch(const awatch: pdbuswatch): int32; + procedure dowatchtoggled(const awatch: pdbuswatch); + procedure doremovewatch(const awatch: pdbuswatch); + function doaddtimeout(const atimeout: pdbustimeout): int32; + procedure dotimeouttoggled(const atimeout: pdbustimeout); + procedure doremovetimeout(const atimeout: pdbustimeout); + procedure updatewatch(const awatch: pdbuswatch); + procedure updatetimeout(const atimeout: pdbustimeout); + procedure dotimer(const sender: tobject); + function err(): pdbuserror; + function checkok(): boolean; + procedure raisedbuserror(); + procedure doidle(var again: boolean); + procedure dopendingcallback(pending: pDBusPendingCall{; user_data: pointer}); + procedure setupmessage(const amessage: pdbusmessage; + const params: array of variantvaluety); + function methodcall(const bus_name,path,iface,method: string; + const params: array of variantvaluety): pdbusmessage; + procedure dounregisterobj(const aobj: pobjinfoty); + procedure doregisteritems(const aobj: pobjinfoty); + procedure dounregisteritems(const aobj: pobjinfoty); + procedure unregisteritem(const apath: string); + procedure mainfilter(const amessage: pdbusmessage; var handled: boolean); + procedure registerobjects(); + procedure unregisterobjects(); + function checkconnect(): boolean; + procedure introspect(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + + //idbusobject for rootobject + procedure registeritems(const sender: idbusservice); + function getpath(): string; + function getintrospecttext(const aindent: int32): string; + procedure busconnected(); + + public + constructor create(); + destructor destroy(); override; + function connected: boolean; + function connect: boolean; + //idbusservice + procedure registerobject(const sender: idbusobject); + procedure unregisterobject(const sender: idbusobject); + procedure registermethodhandler(const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); + procedure registersignalhandler(const asender: string; const apath: string; + const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); + function dbuscallmethod(const returnedto: idbusresponse; var aserial: card32; + const bus_name,path,iface,method: string; + const params: array of variantvaluety; + const timeout: int32 = -1): boolean; //true if ok + function dbuscallmethod(const bus_name,path,iface,method: string; + const params: array of variantvaluety; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; //blocking, true if ok + function dbusreadmessage(const amessage: pdbusmessage; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const apartial: boolean = false): boolean; + //true if ok + function dbusgetproperty(const bus_name,path,iface,property_name: string; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; //blocking, true if ok + function dbusreply(const amessage: pdbusmessage; + const params: array of variantvaluety): boolean; + function dbuserror(const amessage: pdbusmessage; + const aname: string; const atext: string): boolean; + function dbussignal(const path,iface,name: string; + const params: array of variantvaluety): boolean; + property dbusid: string read fbusid; + property dbusname: string read fbusname; + end; + +{$typeinfo on} + tdbusobject = class(teventobject,idbusobject) + protected + fservice: tdbusservice; + function getpropvalue(const aprop: ppropinfo; + out avalue: variantvaluety): boolean; + procedure introspect(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure propget(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure propset(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure propgetall(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + function getintrospectitems(): string virtual; + function getpropintf: string virtual; + function rootpath: string; + procedure propchangesignal(const amember: string); + + procedure propertyget(const amessage: pdbusmessage; + const aname: string; var avalue: variantvaluety) virtual; + procedure propertiesget(var props: dictentryarty) virtual; + procedure propertyset(const amessage: pdbusmessage; + const aname: string; var ahandled: boolean) virtual; + //idbusobject + procedure registeritems(const sender: idbusservice) virtual; + function getpath(): string virtual; + function getintrospecttext(const aindent: int32): string virtual; + procedure busconnected() virtual; + public + constructor create(const aservice: tdbusservice); + destructor destroy(); override; + end; +{$typeinfo off} + +var + dbuslasterror: string; +{ +function dbusconnect(): boolean; //true if ok +procedure dbusdisconnect(); +function dbusid(): string; +function dbusname(): string; + +function dbuscallmethod(const returnedto: idbusresponse; var serial: card32; + const bus_name,path,iface,method: string; + const paramtypes: array of dbusdataty; + const params: array of pointer; + const timeout: int32 = -1): boolean; //true if ok +function dbusreadmessage(const amessage: pdbusmessage; + const resulttypes: array of dbusdataty; + const results: array of pointer): boolean; //true if ok +function dbuscallmethod(const bus_name,path,iface,method: string; + const paramtypes: array of dbusdataty; + const params: array of pointer; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; //blocking, true if ok +procedure dbusreply(const amessage: pdbusmessage; + const paramtypes: array of dbusdataty; + const params: array of pointer); +} +{$ifdef mse_dumpdbus} +function dbusdumpmessage(const amessage: pdbusmessage): string; +{$endif} + +procedure additem(var dest: dbusdatatyarty; const value: dbusdataty); +procedure additem(var dest: variantvaluearty; const value: variantvaluety); + +procedure setvariantvalue(const avalue: string; var avariant: variantvaluety; + const aflags: variantflagsty = []); +function variantvalue(const avalue: string; + const aflags: variantflagsty = []): variantvaluety; +procedure setvariantvalue(const avalue: int32; var avariant: variantvaluety; + const aflags: variantflagsty = []); +function variantvalue(const avalue: int32; + const aflags: variantflagsty = []): variantvaluety; +procedure setvariantvalue(const avalue: card32; var avariant: variantvaluety; + const aflags: variantflagsty = []); +function variantvalue(const avalue: card32; + const aflags: variantflagsty = []): variantvaluety; +procedure setvariantvalue(const avaluead: pointer; const atypeinfo: ptypeinfo; + var avariant: variantvaluety; const aflags: variantflagsty = []); +function variantvalue(const avaluead: pointer; const atypeinfo: ptypeinfo; + const aflags: variantflagsty = []): variantvaluety; + +function itemtypeinfo(const dynartypeinfo: ptypeinfo): ptypeinfo; +function dbusdatastring(const atypeinfo: ptypeinfo): string; + +implementation +uses + msestrings,msesysintf,mseguiintf, + msefloattostr,mseapplication,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + lineend = c_linefeed; + + peerintf = +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend; + + introspectintf = +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend; + + propertiesintf = +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend; + +{ +type + userdatarecty = record + service: tdbusservice; + data: pointer; + end; + puserdatarecty = ^userdatarecty; +} +var +// conn: pdbusconnection; +// ferr: dbuserror; +// busid: string; +// busname: string; +// fdbc: tdbusservice; + dbuslibinited: boolean; + nextidnumber: card16; +// userdatacache: linklistty; + dbusalignments: array[dbusdataty] of int32; + +function initdbuslib(): boolean; +begin + result:= true; + if not dbuslibinited then begin + result:= initializedbus([]); + if result then begin + dbuslibinited:= true; + end; + end; +end; + +procedure raiseerror(const message: string); +begin + raise edbus.create(message); +end; + +procedure error(const message: string); +begin + dbuslasterror:= message; +end; + +procedure outofmemory(); +begin + error('Out of memory'); +end; + +function itemtypeinfo(const dynartypeinfo: ptypeinfo): ptypeinfo; +begin + result:= ptypeinfo(gettypedata(dynartypeinfo)^.eltype2); +end; + +procedure additem(var dest: dbusdatatyarty; const value: dbusdataty); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: variantvaluearty; const value: variantvaluety); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +function getsignature(const asignature: array of dbusdataty): string; +var + i1: int32; +begin + result:= ''; + for i1:= 0 to high(asignature) do begin + result:= result + dbusdatastrings[asignature[i1]]; + end; +end; + +function indent(const atext: string; const aindent: int32): string; +var + p1,p2: pchar; + s1: string; +begin + result:= ''; + if atext <> '' then begin + s1:= charstring(' ',2*aindent); + p1:= pchar(atext); + while p1^ <> #0 do begin + p2:= p1; + while (p1^ <> #0) and (p1^ <> c_linefeed) do begin + inc(p1); + end; + if p1^ <> #0 then begin + inc(p1); + end; + result:= result+s1+psubstr(p2,p1); + end; + end; +end; + +function dbuspath(const apath: string): string; +var + i1: int32; +begin + result:= apath; + i1:= length(result); + if (i1 > 1) and (result[i1] = '/') then begin + setlength(result,i1-1); //remove trailing '/' + end; +end; + +(* +function checkconnect(): boolean; +begin + result:= (fdbc <> nil) and fdbc.connected; +end; + +function dbuscontroller(): tdbusservice; +begin + if fdbc = nil then begin + fdbc:= tdbusservice.create; + end; + result:= fdbc; +end; + +function dbusconnect(): boolean; //true if ok +begin + result:= dbuscontroller.connect(); +end; + +procedure dbusdisconnect(); +begin + if fdbc <> nil then begin + fdbc.disconnect(); + end; +end; + +function dbusid(): string; +begin + result:= ''; + if checkconnect() then begin + result:= fdbc.fbusid; + end; +end; + +function dbusname(): string; +begin + result:= ''; + if checkconnect() then begin + result:= fdbc.fbusname; + end; +end; + +function dbuscallmethod(const returnedto: idbusresponse; var serial: card32; + const bus_name,path,iface,method: string; + const paramtypes: array of dbusdataty; + const params: array of pointer; + const timeout: int32 = -1): boolean; //true if ok +begin + result:= false; + if checkconnect() then begin + result:= fdbc.dbuscallmethod(returnedto,serial,bus_name,path,iface,method, + paramtypes,params,timeout); + end; +end; +*) +{$ifdef mse_dumpdbus} +function dbusdumpmessage(const amessage: pdbusmessage): string; +var + level: int32; + + function nilstr(const astr: pcchar): string; + begin + if astr = nil then begin + result:= 'NIL'; + end + else begin + result:= string(astr); + end; + end; //nilstr + + function dumptype(const t: int32): string; + begin + case t of + DBUS_TYPE_INVALID: result:= ''; + DBUS_TYPE_BYTE: result:= 'BYTE'; + DBUS_TYPE_BOOLEAN: result:= 'BOOLEAN'; + DBUS_TYPE_INT16: result:= 'INT16'; + DBUS_TYPE_UINT16: result:= 'UINT16'; + DBUS_TYPE_INT32: result:= 'INT32'; + DBUS_TYPE_UINT32: result:= 'UINT32'; + DBUS_TYPE_INT64: result:= 'INT64'; + DBUS_TYPE_UINT64: result:= 'UINT64'; + DBUS_TYPE_DOUBLE: result:= 'DOUBLE'; + DBUS_TYPE_STRING: result:= 'STRING'; + DBUS_TYPE_OBJECT_PATH: result:= 'OBJECT_PATH'; + DBUS_TYPE_SIGNATURE: result:= 'SIGNATURE'; + DBUS_TYPE_UNIX_FD: result:= 'UNIX_FD'; + DBUS_TYPE_ARRAY: result:= 'ARRAY'; + DBUS_TYPE_VARIANT: result:= 'VARIANT'; + DBUS_TYPE_STRUCT: result:= 'STRUCT'; + DBUS_TYPE_DICT_ENTRY: result:= 'DICT_ENTRY'; + end; + end; + + function dumpdata(const t: int32; iterpo: pdbusmessageiter): string; + var + b1: byte; + bool1: dbus_bool_t; + i16: int16; + c16: card16; + i32: int32; + c32: card32; + i64: int64; + c64: card64; + f64: flo64; + pc1: pcchar; + + begin + result:= ''; + case t of + DBUS_TYPE_INVALID: begin end; + DBUS_TYPE_BYTE: begin + dbus_message_iter_get_basic(iterpo,@b1); + result:= inttostr(b1); + end; + DBUS_TYPE_BOOLEAN: begin + dbus_message_iter_get_basic(iterpo,@bool1); + result:= inttostr(bool1); + end; + DBUS_TYPE_INT16: begin; + dbus_message_iter_get_basic(iterpo,@i16); + result:= inttostr(i16); + end; + DBUS_TYPE_UINT16: begin + dbus_message_iter_get_basic(iterpo,@c16); + result:= inttostr(c16); + end; + DBUS_TYPE_INT32: begin + dbus_message_iter_get_basic(iterpo,@i32); + result:= inttostr(i32); + end; + DBUS_TYPE_UINT32: begin + dbus_message_iter_get_basic(iterpo,@c32); + result:= inttostr(c32); + end; + DBUS_TYPE_INT64: begin + dbus_message_iter_get_basic(iterpo,@i64); + result:= inttostr(i64); + end; + DBUS_TYPE_UINT64: begin + dbus_message_iter_get_basic(iterpo,@c64); + result:= inttostr(c64); + end; + DBUS_TYPE_DOUBLE: begin + dbus_message_iter_get_basic(iterpo,@f64); + result:= string(doubletostring(f64,-1)); + end; + DBUS_TYPE_STRING, + DBUS_TYPE_OBJECT_PATH, + DBUS_TYPE_SIGNATURE: begin + dbus_message_iter_get_basic(iterpo,@pc1); + result:= '"'+string(pc1)+'"'; + end; + DBUS_TYPE_UNIX_FD: begin end; + DBUS_TYPE_ARRAY: begin end; + DBUS_TYPE_VARIANT: begin end; + DBUS_TYPE_STRUCT: begin end; + DBUS_TYPE_DICT_ENTRY: begin end; + end; + end; + + function readvalue(var aiter: dbusmessageiter): string; + var + i1,i2: int32; + iter2,iter3: dbusmessageiter; + iterpo: pdbusmessageiter; + first: boolean; + s1,s2: string; + label + endlab; + begin + inc(level); + s2:= charstring(' ',level); + result:= s2; + iterpo:= @aiter; + i1:= dbus_message_iter_get_arg_type(iterpo); + if i1 = DBUS_TYPE_INVALID then begin + goto endlab; + end; + if i1 = DBUS_TYPE_VARIANT then begin + dbus_message_iter_recurse(@aiter,@iter3); + iterpo:= @iter3; + i1:= dbus_message_iter_get_arg_type(iterpo); //nested variants? + end; + case i1 of + DBUS_TYPE_ARRAY: begin + i2:= dbus_message_iter_get_element_type(iterpo); + dbus_message_iter_recurse(iterpo,@iter2); + result:= dumptype(i2)+'['; + first:= true; + while dbus_message_iter_get_arg_type(@iter2) <> DBUS_TYPE_INVALID do begin + s1:= readvalue(iter2); + if s1 = '' then begin + if not first then begin + setlength(result,length(result)-1); //remove last comma + end; + result:= result+']'; + break; + end + else begin + result:= result+s1+','; + end; + first:= false; + end; + end; //array +// DBUS_TYPE_VARIANT, //todo +// DBUS_TYPE_STRUCT, +// DBUS_TYPE_DICT_ENTRY + else begin + result:= result+dumptype(i1)+' '+dumpdata(i1,iterpo); + end; + end; + dbus_message_iter_next(@aiter); + +endlab: + if result <> s2 then begin + result:= result+lineend; + end + else begin + result:= ''; + end; + end;//readvalue + +var + iter1: dbusmessageiter; + s1: string; + +begin + level:= 0; + result:= '*'; + if amessage = nil then begin + result:= result+'NIL'; + end + else begin + dbus_message_iter_init(amessage,@iter1); + case dbus_message_get_type(amessage) of + DBUS_MESSAGE_TYPE_INVALID: begin + result:= result+'INVALID'; + end; + DBUS_MESSAGE_TYPE_METHOD_CALL: begin + result:= result+'METHODCALL'; + end; + DBUS_MESSAGE_TYPE_METHOD_RETURN: begin + result:= result+'METHOD_RETURN'; + end; + DBUS_MESSAGE_TYPE_ERROR: begin + result:= result+'ERROR'; + end; + DBUS_MESSAGE_TYPE_SIGNAL: begin + result:= result+'SIGNAL'; + end; + end; + result:= result+' '+nilstr(dbus_message_get_destination(amessage))+' '+ + nilstr(dbus_message_get_path(amessage))+' '+ + nilstr(dbus_message_get_interface(amessage))+' '+ + nilstr(dbus_message_get_member(amessage))+' '+lineend; + repeat + s1:= readvalue(iter1); + result:= result+s1; + until s1 = ''; + end; +end; +{$endif} +(* +function dbusreadmessage(const amessage: pdbusmessage; + const resulttypes: array of dbusdataty; + const results: array of pointer): boolean; //true if ok +begin + result:= false; + if checkconnect() then begin + result:= fdbc.readmessage(amessage,resulttypes,results); + end; +end; + +function dbuscallmethod(const bus_name,path,iface,method: string; + const paramtypes: array of dbusdataty; + const params: array of pointer; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; //blocking, true if ok +begin + result:= false; + if checkconnect() then begin + result:= fdbc.dbuscallmethod(bus_name,path,iface,method,paramtypes,params, + resulttypes,results,timeout); + end; +end; + +procedure dbusreply(const amessage: pdbusmessage; + const paramtypes: array of dbusdataty; + const params: array of pointer); +begin + if checkconnect() then begin + fdbc.reply(amessage,paramtypes,params); + end; +end; +*) +function addwatch(watch: pDBusWatch; data: pointer): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + result:= tdbusservice(data).doaddwatch(watch); +end; + +procedure watchtoggled(watch: pDBusWatch; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + tdbusservice(data).dowatchtoggled(watch); +end; + +procedure removewatch(watch: pDBusWatch; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + tdbusservice(data).doremovewatch(watch); +end; + +function addtimeout(timeout: pDBusTimeout; data: pointer): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + result:= tdbusservice(data).doaddtimeout(timeout); +end; + +procedure timeouttoggled(timeout: pDBusTimeout; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + tdbusservice(data).dotimeouttoggled(timeout); +end; + +procedure removetimeout(timeout: pDBusTimeout; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + tdbusservice(data).doremovetimeout(timeout); +end; + +procedure pendingcallback(pending: pDBusPendingCall; user_data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin +// if fdbc <> nil then begin +{$ifdef mse_debugdbus} + writeln('**pendingcallback'); +{$endif} + tdbusservice(user_data).dopendingcallback(pending); +{ + with puserdatarecty(getlistitem(userdatacache,ptruint(user_data)))^ do begin + service.dopendingcallback(pending,data); + end; +} +end; +{ +procedure pollcallback(const aflags: pollflagsty; const adata: pointer); +begin +// if fdbc <> nil then begin + with puserdatarecty(getlistitem(userdatacache,ptruint(adata)))^ do begin + service.fitems.dopollcallback(aflags,data); + end; +end; +} + +function aligntoptr(const p: pointer): pointer; inline; +begin +{$ifdef FPC_REQUIRES_PROPER_ALIGNMENT} + result:=align(p,sizeof(p)); +{$else FPC_REQUIRES_PROPER_ALIGNMENT} + result:=p; +{$endif FPC_REQUIRES_PROPER_ALIGNMENT} +end; + +procedure alignandstep(const atype: dbusdataty; var adataad: pointer); +var + pu1: ptruint; +begin + pu1:= dbusalignments[atype]-1; + adataad:= pointer((ptruint(adataad)+pu1) and not pu1) + //align + dbusdatasizes[atype]; +end; + +procedure align(const atype: dbusdataty; var adataad: pointer); +var + pu1: ptruint; +begin + pu1:= dbusalignments[atype]-1; + adataad:= pointer((ptruint(adataad)+pu1) and not pu1); +end; + +const + inttypestrings: array[tordtype] of string = ( + //otSByte, otUByte, + DBUS_TYPE_BYTE_AS_STRING,DBUS_TYPE_BYTE_AS_STRING, + //otSWord, otUWord, + DBUS_TYPE_INT16_AS_STRING,DBUS_TYPE_UINT16_AS_STRING, + //otSLong, otULong + DBUS_TYPE_INT32_AS_STRING,DBUS_TYPE_UINT32_AS_STRING +{$ifdef mse_fpc_3_2} + //otSQWord, otUQWord + ,DBUS_TYPE_INT64_AS_STRING,DBUS_TYPE_UINT64_AS_STRING +{$endif} + ); +type +{$ifdef mse_fpc_3_0} + precordtypedata = ptypedata; +{$else} + recordtypedata = + {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} + packed + {$endif} + record + case TTypeKind of + tkrecord: ( + RecSize: Integer; + ManagedFldCount: Integer; + {ManagedFields: array[1..ManagedFldCount] of TManagedField} + ); + end; + precordtypedata = ^recordtypedata; + PManagedField = ^TManagedField; + TManagedField = + {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} + packed + {$endif} + record + TypeRef: PTypeInfo; + {$ifdef mse_fpc_3_0} + FldOffset: SizeInt; + {$else} + FldOffset: longint; + {$endif} + end; +{$endif} + +function dbusdatastring(const atypeinfo: ptypeinfo): string; +var + p1: ptypedata; + p2,pe: pmanagedfield; +begin + result:= ''; + p1:= gettypedata(atypeinfo); + case atypeinfo^.kind of + tkdynarray: begin + result:= 'a'+dbusdatastring(ptypeinfo(p1^.eltype2)); + end; + tkrecord: begin + result:= '('; + p2:= aligntoptr(pointer(@precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})+ + sizeof(precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})); + pe:= p2+precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}; + while p2 < pe do begin + result:= result+dbusdatastring(p2^.typeref); + inc(p2); + end; + result:= result+')'; + end; + tkinteger: begin + result:= inttypestrings[p1^.ordtype]; + end; + tkastring: begin + result:= 's'; + end; + else begin + raiseerror('type not supported'); + end; + end; +end; + +{$ifdef mse_debugvariant} +var + variantlevel: int32; +{$endif} + +function dbusdatastring(const avalue: variantvaluety): string; +var + p1,pe: pvariantvaluety; +begin +{$ifdef mse_debugvariant} + inc(variantlevel); + writeln('**dbusdatastring:',variantlevel,':',avalue.kind); +{$endif} + case avalue.kind of + vvk_string: begin + result:= dbusdatastrings[dbt_string]; + end; + vvk_int32: begin + result:= dbusdatastrings[dbt_int32]; + end; + vvk_dynar: begin + result:= dbusdatastring(avalue.vdynar.typinfo); + end; + vvk_variantar: begin + result:= dbusdatastring(avalue.vvariantar.typinfo); + end; + vvk_record: begin + result:= '('; + p1:= avalue.vvariantar.data; + pe:= p1 + length(variantvaluearty(avalue.vvariantar.data)); + {$ifdef mse_debugvariant} + writeln('*recordcount:',variantlevel,':',pe-p1); + {$endif} + while p1 < pe do begin + result:= result+dbusdatastring(p1^); + inc(p1); + end; + result:= result+')'; + end; + else begin + raiseerror('type not supported'); + end; + end; +{$ifdef mse_debugvariant} + writeln('*dbusdatastring:',variantlevel,':',result); + dec(variantlevel); +{$endif} +end; + +const + inttypes: array[tordtype] of dbusdataty = ( + //otSByte, otUByte, + dbt_byte,dbt_byte, + //otSWord, otUWord, + dbt_int16,dbt_uint16, + //otSLong, otULong + dbt_int32,dbt_uint32 +{$ifdef mse_fpc_3_2} + //otSQWord, otUQWord + ,dbt_int64,dbt_uint64 +{$endif} + ); + +procedure stackarray(const source: dbusdatatyarty; var dest: dbusdatatyarty); +var + i1: int32; +begin + i1:= length(dest); + setlength(dest,i1+length(source)); + move(source[0],dest[i1],length(source)*sizeof(source[0])); +end; + +function dbusdatatypes(const atypeinfo: ptypeinfo): dbusdatatyarty; +var + p1: ptypedata; + p2,pe: pmanagedfield; +begin + setlength(result,1); + p1:= gettypedata(atypeinfo); + case atypeinfo^.kind of + tkdynarray: begin + result[0]:= dbt_array; + stackarray(dbusdatatypes(ptypeinfo(p1^.eltype2)),result); + end; + tkrecord: begin + result[0]:= dbt_struct; + p2:= aligntoptr(pointer(@precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})+ + sizeof(precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})); + pe:= p2+precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}; + while p2 < pe do begin + stackarray(dbusdatatypes(p2^.typeref),result); + inc(p2); + end; + setlength(result,high(result)+2); + result[high(result)]:= dbt_structend; + end; + tkinteger: begin + result[0]:= inttypes[p1^.ordtype]; + end; + tkastring: begin + result[0]:= dbt_string; + end; + else begin + raiseerror('type not supported'); + end; + end; +end; +{ +function dbusdatastring(const atype: dbusdataty; var adataad: pointer): string; +var + i1: int32; + p1: pointer; +begin + align(atype,adataad); + case atype of + dbt_msevariant: begin + result:= ''; + with pvariantvaluety(adataad)^ do begin + case kind of + vvk_dynar: begin + result:= dbusdatastring(vdynar.typinfo); + end; + vvk_record: begin + result:= dbusdatastring(vrecord.typinfo); + end; + else begin + p1:= nil; + result:= dbusdatastring(types[0],p1); //simple type + end; + end; + end; + end; + else begin //structs, dictentries? + result:= dbusdatastrings[atype]; + end; + end; + adataad:= adataad + dbusdatasizes[atype]; +end; +} +procedure finalizevariantvalue(var avariant: variantvaluety); +var + p1: pvariantvaluety; + pe: pointer; +begin + with avariant do begin + case kind of + vvk_variantar,vvk_record: begin + p1:= vvariantar.data; + pe:= p1 + length(variantvaluearty(vvariantar.data)); + while p1 < pe do begin + finalizevariantvalue(p1^); + inc(p1); + end; + variantvaluearty(vvariantar.data):= nil; + end; +// vvk_string: begin +// string(vstring):= ''; +// end; + end; + end; +end; + +procedure finalizedictentryar(var adict: dictentryarty); +var + p1,pe: pdictentryty; +begin + p1:= pointer(adict); + pe:= p1 + length(adict); + while p1 < pe do begin + finalizevariantvalue(p1^.value); + inc(p1); + end; +end; + +procedure setvariantvalue(const avalue: string; var avariant: variantvaluety; + const aflags: variantflagsty = []); +begin + with avariant do begin + kind:= vvk_string; + flags:= aflags; +// setlength(types,1); +// types[0]:= dbt_string; + vstring:= pchar(avalue); +// vstring:= nil; +// string(vstring):= avalue; + end; +end; + +function variantvalue(const avalue: string; + const aflags: variantflagsty = []): variantvaluety; +begin + setvariantvalue(avalue,result,aflags); +end; + +procedure setvariantvalue(const avalue: int32; var avariant: variantvaluety; + const aflags: variantflagsty = []); +begin + with avariant do begin + kind:= vvk_int32; + flags:= aflags; + vint32:= avalue; + end; +end; + +function variantvalue(const avalue: int32; + const aflags: variantflagsty = []): variantvaluety; +begin + setvariantvalue(avalue,result,aflags); +end; + +procedure setvariantvalue(const avalue: card32; var avariant: variantvaluety; + const aflags: variantflagsty = []); +begin + with avariant do begin + kind:= vvk_card32; + flags:= aflags; + vcard32:= avalue; + end; +end; + +function variantvalue(const avalue: card32; + const aflags: variantflagsty = []): variantvaluety; +begin + setvariantvalue(avalue,result,aflags); +end; + +{ +procedure setvariantdynarvalue(const avalue: pointer; + const atypeinfo: ptypeinfo; var avariant: variantvaluety; + const aflags: variantflagsty = []); +begin + with avariant do begin + kind:= vvk_dynar; + flags:= aflags; +// types:= dbusdatatypes(atypeinfo); + vdynar.data:= avalue; + vdynar.typinfo:= atypeinfo; + end; +end; + +function variantdynarvalue(const avalue: pointer; const atypeinfo: ptypeinfo; + const aflags: variantflagsty = []): variantvaluety; +begin + setvariantdynarvalue(avalue,atypeinfo,result,aflags); +end; +} + +procedure setvariantvalue(const avaluead: pointer; const atypeinfo: ptypeinfo; + var avariant: variantvaluety; const aflags: variantflagsty = []); +var + pt: ptypedata; + p1: pmanagedfield; + pe: pointer; + pvalue: pvariantvaluety; + pvar: pvariantvaluety; + p2: pointer; +begin +{$ifdef mse_debugvariant} +inc(variantlevel); +writeln('**setvariantvalue:',variantlevel,':',atypeinfo^.name, + ' ',atypeinfo^.kind); +{$endif} + + pt:= gettypedata(atypeinfo); + with avariant do begin + flags:= aflags; + case atypeinfo^.kind of + tkastring: begin + setvariantvalue(pstring(avaluead)^,avariant,aflags); + end; + tkinteger: begin + if pt^.ordtype <> otslong then begin + raiseerror('Invalid ord type'); + end; + setvariantvalue(pint32(avaluead)^,avariant,aflags); + end; + tkdynarray: begin + kind:= vvk_dynar; + case ptypeinfo(pt^.eltype2)^.kind of + tkrecord: begin + if vf_dict in aflags then begin + vdynar.data:= ppointer(avaluead)^; + vdynar.typinfo:= atypeinfo; + end + else begin + kind:= vvk_variantar; //needs finalize + vvariantar.typinfo:= atypeinfo; + vvariantar.data:= nil; + p2:= ppointer(avaluead)^; + setlength(variantvaluearty(vvariantar.data), + dynarraylength(p2)); + pvar:= vvariantar.data; + pe:= pvar + dynarraylength(p2); + while pvar < pe do begin + setvariantvalue(p2,ptypeinfo(pt^.eltype2),pvar^); + inc(pvar); + inc(p2,pt^.elsize); + end; + end; + end + else begin + vdynar.data:= ppointer(avaluead)^; + vdynar.typinfo:= atypeinfo; + end; + end; + end; + tkrecord: begin + kind:= vvk_record; + vvariantar.data:= nil; + setlength(variantvaluearty(vvariantar.data),precordtypedata(pt)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}); + p1:= aligntoptr(pointer(@precordtypedata(pt)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}) + + sizeof(precordtypedata(pt)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})); + pe:= p1+precordtypedata(pt)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}; + pvalue:= vvariantar.data; +{$ifdef mse_debugvariant} +writeln('*recordfieldcount:',variantlevel,':',pe-p1); +{$endif} + while p1 < pe do begin + setvariantvalue(avaluead+p1^.fldoffset,p1^.typeref,pvalue^); + inc(p1); + inc(pvalue); + end; +{$ifdef mse_debugvariant} +writeln('*endfields:',variantlevel); +{$endif} + end; + else begin + raiseerror('Invalid type'); + end; + end; + end; +{$ifdef mse_debugvariant} + dec(variantlevel); +{$endif} +end; + +function variantvalue(const avaluead: pointer; const atypeinfo: ptypeinfo; + const aflags: variantflagsty = []): variantvaluety; +begin + setvariantvalue(avaluead,atypeinfo,result,aflags); +end; +(* +procedure setvariantrecordvalue(const avalue: pointer; + atypeinfo: ptypeinfo; var avariant: variantvaluety); +var + pt: ptypedata; + p1,pe: pmanagedfield; + pvalue: pvariantvaluety; +begin + with avariant do begin + kind:= vvk_record; +// types:= dbusdatatypes(atypeinfo); + vrecord.data:= nil; +// vrecord.typinfo:= atypeinfo; + pt:= gettypedata(atypeinfo); + setlength(variantvaluearty(vrecord.data),pt^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}); + p1:= aligntoptr(pointer(@pt^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})+ + sizeof(pt^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})); + pe:= p1+pt^.{$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}; + pvalue:= vrecord.data; + while p1 < pe do begin + setvariantvalue(avalue+p1^.fldoffset,p1^.typeref,pvalue^); + inc(p1); + inc(pvalue); + end; + end; +end; + +function variantrecordvalue(const avaluead: pointer; + const atypeinfo: ptypeinfo): variantvaluety; +begin + setvariantrecordvalue(avaluead,atypeinfo,result); +end; +*) +{ tdbusitemhashdatalist } + +constructor tdbusitemhashdatalist.create(const aowner: tdbusservice); +begin + fowner:= aowner; + inherited create(); + include(fstate,hls_needsfinalize); +end; + +function tdbusitemhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(dbusitemhashdataty); +end; + +function tdbusitemhashdatalist.addwatch(const key: pdbuswatch): pwatchinfoty; +var + p1: pdbusitemhashdataty; +begin + p1:= pdbusitemhashdataty(add(key)); + p1^.data.data.kind:= dbk_watch; + result:= @p1^.data.data.watch; + msearrayutils.additem(longwordarty(fwatches),getdataoffs(result)); + with result^ do begin + flags:= []; + watch:= key; + end; +end; + +function tdbusitemhashdatalist.addlink(const alink: idbusclient; + const apending: hashoffsetty): plinkinfoty; +var + p1,p2: pdbusitemhashdataty; +begin + p1:= pdbusitemhashdataty(find(alink)); + if p1 = nil then begin + p1:= pdbusitemhashdataty(add(alink)); + p1^.data.data.kind:= dbk_link; + alink.link(iobjectlink(pchar(alink)+1),iobjectlink(self)); + //create backlink + p1^.data.data.link.pendingoffs:= 0; + end; + result:= @p1^.data.data.link; + with result^ do begin + link:= alink; + if pendingoffs <> 0 then begin + p2:= getdatapo(pendingoffs); + p2^.data.data.pending.prev:= apending; + end; + p2:= getdatapo(apending); + p2^.data.data.pending.next:= pendingoffs; + p2^.data.data.pending.prev:= 0; + p2^.data.data.pending.link:= getdataoffs(p1); + pendingoffs:= apending; + end; +end; + +function tdbusitemhashdatalist.addpending(const apending: pdbuspendingcall; + const alink: idbusresponse; var aserial: card32): ppendinginfoty; +var + p1: pdbusitemhashdataty; +begin + p1:= pdbusitemhashdataty(add(apending)); + p1^.data.data.kind:= dbk_pending; + result:= @p1^.data.data.pending; + with result^ do begin + pendingpo:= apending; + inc(fserial); + if fserial = 0 then begin + inc(fserial); + end; + serial:= fserial; + aserial:= serial; + end; + addlink(alink,getdataoffs(p1)); +end; + +function tdbusitemhashdatalist.addobject( + const aobj: idbusobject): pobjinfoty; +var + p1: pdbusitemhashdataty; + o1: hashoffsetty; +begin + p1:= pdbusitemhashdataty(add(aobj)); + o1:= getdataoffs(p1); + if flastobject = 0 then begin + flastobject:= o1; + end; + p1^.data.data.kind:= dbk_obj; + result:= @p1^.data.data.obj; + with result^ do begin + obj:= aobj; +// path:= nil; +// items:= nil; + handlers:= nil; + prev:= 0; + next:= fobjects; + if fobjects <> 0 then begin + with pdbusitemhashdataty(getdatapo(fobjects))^.data.data.obj do begin + prev:= o1; + end; + end; + fobjects:= o1; + end; +end; + +procedure tdbusitemhashdatalist.finalizeitem(const aitem: phashdataty); +var + p1: pdbusitemhashdataty; + o1: hashoffsetty; +begin + with pdbusitemhashdataty(aitem)^.data do begin + case data.kind of + dbk_watch: begin + gui_removepollfd(data.watch.id); + removeitem(integerarty(fwatches),getdataoffs(@data.watch)); + end; + dbk_timeout: begin + data.timeout.timer.free; + end; + dbk_link: begin + if not funlinking then begin + data.link.link.unlink(iobjectlink(pchar(iobjectlink(self))+1), + data.link.link); + //remove backlink + end; + o1:= data.link.pendingoffs; + while o1 <> 0 do begin + p1:= getdatapo(o1); + with p1^.data.data.pending do begin + o1:= next; + link:= 0; + end; + end; + end; + dbk_pending: begin + with data.pending do begin + if prev <> 0 then begin + p1:= getdatapo(prev); + p1^.data.data.pending.next:= next; + end + else begin //first in pending chain + if link <> 0 then begin + p1:= getdatapo(link); + if next <> 0 then begin + p1^.data.data.link.pendingoffs:= next; + end + else begin + internaldelete(link); //empty pending chain + end; + end; + end; + dbus_pending_call_unref(pendingpo); + end; + end; + dbk_obj: begin + fowner.dounregisterobj(@data.obj); + with data.obj do begin + if next <> 0 then begin + with pdbusitemhashdataty(getdatapo(next))^.data.data do begin + obj.prev:= prev; + end; + end + else begin + flastobject:= prev; + end; + if prev <> 0 then begin + with pdbusitemhashdataty(getdatapo(prev))^.data.data do begin + obj.next:= next; + end; + end + else begin + fobjects:= next; + end; +// string(path):= ''; +// stringarty(items):= nil; + hashoffsetarty(handlers):= nil; + end; + end; + end; + end; +end; + +procedure tdbusitemhashdatalist.dopollcallback(const aflags: pollflagsty; + const adata: pointer); +var + p1: pdbusitemhashdataty; +begin + p1:= pdbusitemhashdataty(find(adata)); + if (p1 <> nil) and (p1^.data.data.kind = dbk_watch) then begin + //throw no exception +{$ifdef mse_debugdbus} + if p1^.data.data.watch.flags <> aflags then begin + writeln('**dopollcallback:',int32(aflags)); + end; +{$endif} + p1^.data.data.watch.flags:= p1^.data.data.watch.flags + aflags; + end; +end; + +function tdbusitemhashdatalist.findwatch(const key: pdbuswatch): pwatchinfoty; +begin + result:= pointer(find(key)); + if result = nil then begin + raiseerror('Watch not found'); + end; + if pdbusitemhashdataty(result)^.data.data.kind <> dbk_watch then begin + raiseerror('Invalid watch'); + end; + result:= @pdbusitemhashdataty(result)^.data.data.watch; +end; + +function tdbusitemhashdatalist.findtimeout( + const key: pdbustimeout): ptimeoutinfoty; +begin + result:= pointer(find(key)); + if result = nil then begin + raiseerror('Timeout not found'); + end; + if pdbusitemhashdataty(result)^.data.data.kind <> dbk_timeout then begin + raiseerror('Invalid timeout'); + end; + result:= @pdbusitemhashdataty(result)^.data.data.timeout; +end; + +function tdbusitemhashdatalist.findpending( + const key: pdbuspendingcall): ppendinginfoty; +begin + result:= pointer(find(key)); + if result = nil then begin + raiseerror('Pendingcall not found'); + end; + if pdbusitemhashdataty(result)^.data.data.kind <> dbk_pending then begin + raiseerror('Invalid pendingcall'); + end; + result:= @pdbusitemhashdataty(result)^.data.data.pending; +end; + +procedure tdbusitemhashdatalist.link(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + //dummy +end; + +procedure tdbusitemhashdatalist.unlink(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil); +begin + if not odd(ptruint(source)) then begin //full link + delete(source); + end; +end; + +procedure tdbusitemhashdatalist.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + if event = oe_destroyed then begin + funlinking:= true; + delete(sender); + funlinking:= false; + end; +end; + +function tdbusitemhashdatalist.getinstance: tobject; +begin + result:= self; +end; + +const + watchflags: array[pollflagty] of card32 = ( + DBUS_WATCH_READABLE, //pf_in, //POLLIN = $001; + 0, //pf_pri, //POLLPRI = $002; + DBUS_WATCH_WRITABLE, //pf_out, //POLLOUT = $004; + DBUS_WATCH_ERROR, //pf_err, //POLLERR = $008; + DBUS_WATCH_HANGUP, //pf_hup, //POLLHUP = $010; + 0 //pf_nval //POLLNVAL = $020; + ); + +procedure tdbusitemhashdatalist.handlewatches(); +var + i1: int32; + c1: card32; + f1: pollflagty; +begin + for i1:= 0 to high(fwatches) do begin + with pwatchinfoty(getdatapo(fwatches[i1]))^ do begin + if flags <> [] then begin + c1:= 0; + for f1:= low(f1) to high(f1) do begin + if f1 in flags then begin + c1:= c1 or watchflags[f1]; + end; + end; + dbus_watch_handle(watch,c1); + end; + end; + end; +end; + +{ tdbusservice } + +constructor tdbusservice.create(); +begin + fitems:= tdbusitemhashdatalist.create(self); + fhandlers:= thandlerhashdatalist.create(self); + inherited; + registerobject(idbusobject(self)); +end; + +destructor tdbusservice.destroy(); +begin + unregisterobject(idbusobject(self)); + disconnect(); + inherited; + fitems.free(); + fhandlers.free(); +end; + +function tdbusservice.connected: boolean; +begin + result:= fconn <> nil; +end; +(* +procedure tdbusservice.setupmessage(const amessage: pdbusmessage; + const paramtypes: array of dbusdataty; + const params: array of pointer); + + function writevalue(var iter: dbusmessageiter; + var pt: pdbusdataty; var pd: ppointer; var datapo: pointer): boolean; + var + p1,pe: pointer; + p2: ppointer; + p3: pdbusdataty; + pdict: pdictentryty; + precord: precordinfoty; + record1: recordinfoty; + pvariant: pvariantvaluety; + pdynar: pdynarinfoty; + ptypda: ptypedata; + pd1: pointer; + p5: pointer; + bool1: dbus_bool_t; + pc1: pcchar; + iter2: dbusmessageiter; + i1,i2: int32; + d1: dbusdataty; + d2: array[0..1] of dbusdataty; + s1: string; + label + oklab,oklab1; + begin + result:= false; +{ + if pt >= pte then begin + error('dbuscallmethod() paramtypes and params count do not match'); + exit; + end; +} + p1:= pd^; + case pt^ of +// dbt_INVALID, + dbt_BYTE: begin + p1:= @bool1; + bool1:= 0; + if pboolean(pd)^ then begin + bool1:= 1; + end; + end; + dbt_BOOLEAN: begin + end; + dbt_INT16: begin + end; + dbt_UINT16: begin + end; + dbt_INT32: begin + end; + dbt_UINT32: begin + end; + dbt_INT64: begin + end; + dbt_UINT64: begin + end; + dbt_DOUBLE: begin + end; + dbt_STRING,dbt_OBJECT_PATH,dbt_SIGNATURE: begin + p1:= @pc1; + pc1:= pchar(pansistring(pd^)^); + end; + +// dbt_UNIX_FD, + dbt_ARRAY: begin + inc(pt); +{ + if pt >= pte then begin + error('dbuscallmethod() paramtypes and params count do not match'); + exit; + end; +} + pdynar:= pd^; //pointer to dynarinfoty + ptypda:= gettypedata(pdynar^.typinfo); + i1:= ptypda^.elsize; + s1:= dbusdatastrings[pt^]; + if s1 = '' then begin + s1:= dbusdatastring(ptypda^.eltype2); + end; + if dbus_message_iter_open_container(@iter,dbusdatacodes[dbt_array], + pchar(s1),@iter2) = 0 then begin + outofmemory(); + exit; + end; + p1:= ppointer(p1)^; //dynamic array + i2:= dynarraylength(p1); + if p1 <> nil then begin + pe:= p1 + i1 * i2; + while p1 < pe do begin + p2:= @p1; //restore + p3:= pt; //restore + if not writevalue(iter2,p3,p2,pd1) then begin //pd1 is dummy + dbus_message_iter_abandon_container(@iter,@iter2); + exit; + end; + inc(p1,i1); + end; + end; + if dbus_message_iter_close_container(@iter,@iter2) = 0 then begin + outofmemory(); + exit; + end; + goto oklab; + end; + dbt_VARIANT: begin + inc(pt); + p1:= pd^; + if dbus_message_iter_open_container(@iter,dbusdatacodes[dbt_variant], + pchar(dbusdatastring(pt^,p1)),@iter2) = 0 then begin + outofmemory(); + exit; + end; + if not writevalue(iter2,pt,pd,pd1) then begin //pd1 is dummy + dbus_message_iter_abandon_container(@iter,@iter2); + exit; + end; + if dbus_message_iter_close_container(@iter,@iter2) = 0 then begin + outofmemory(); + exit; + end; + goto oklab1; + end; + dbt_STRUCT: begin + precord:= pd^; + inc(pt); + pd1:= precord^.dataad; //record start + if dbus_message_iter_open_container(@iter,dbusdatacodes[dbt_struct], + nil,@iter2) = 0 then begin + outofmemory(); + exit; + end; + while pt^ <> dbt_structend do begin + if pt^ = dbt_struct then begin + record1.dataad:= pd1; //typinfo not used + p1:= @record1; + p2:= @p1; + end + else begin + p2:= @pd1; //restore + end; + if not writevalue(iter2,pt,p2,pd1) then begin + dbus_message_iter_abandon_container(@iter,@iter2); + exit; + end; + end; + if dbus_message_iter_close_container(@iter,@iter2) = 0 then begin + outofmemory(); + exit; + end; + goto oklab1; + end; + dbt_DICT_ENTRY: begin + pdict:= pd^; +{ + d2[0]:= dbt_variant; + p4:= pd^; + case p4^.value.kind of + vvk_string: begin + d2[1]:= dbt_string; + p1:= @p4^.value.vstring; + end; + vvk_int32: begin + d2[1]:= dbt_int32; + p1:= @p4^.value.vint32; + end; + else begin + result:= false; + error('dbuscallmethod() paramtype not yet supported'); + exit; + end; + end; + } + if dbus_message_iter_open_container(@iter,dbusdatacodes[dbt_dict_entry], + nil,@iter2) = 0 then begin + outofmemory(); + exit; + end; + d1:= dbt_string; + p3:= @d1; + p5:= @pdict^.name; + p2:= @p5; + if not writevalue(iter2,p3,p2,pd1) then begin //name, pd1 is dummy + dbus_message_iter_abandon_container(@iter,@iter2); + exit; + end; + d2[0]:= dbt_variant; + d2[1]:= dbt_msevariant; + p3:= @d2; + p1:= @pdict^.value; + p2:= @p1; + if not writevalue(iter2,p3,p2,pd1) then begin //value, pd1 is dummy + dbus_message_iter_abandon_container(@iter,@iter2); + exit; + end; + if dbus_message_iter_close_container(@iter,@iter2) = 0 then begin + outofmemory(); + exit; + end; + goto oklab1; + end; + dbt_msevariant: begin + pvariant:= pd^; + case pvariant^.kind of + vvk_string: begin + p1:= @pvariant^.vstring; + end; + vvk_int32: begin + p1:= @pvariant^.vint32; + end; + vvk_dynar: begin + p1:= @pvariant^.vdynar.data; + end; + vvk_record: begin + p1:= @pvariant^.vrecord.dataad; + end; + else begin + error('dbuscallmethod() variant data type not yet supported'); + exit; + end; + end; + p2:= @p1; + p3:= pointer(pvariant^.types); + if not writevalue(iter,p3,p2,pd1) then begin //pd1 is dummy + exit; + end; + goto oklab; + end; + else begin + result:= false; + error('dbuscallmethod() paramtype not yet supported'); + exit; + end; + end; + + if dbus_message_iter_append_basic(@iter, + dbusdatacodes[pt^],p1) = 0 then begin + outofmemory(); + exit; + end; + alignandstep(pt^,datapo); + oklab: + inc(pt); + inc(pd); + oklab1: + result:= true; + end;//writevalue + +var + pde: ppointer; + iter1: dbusmessageiter; + pt: pdbusdataty; + pte: pdbusdataty; + + pd: ppointer; + pd1: pointer; + +label + errorlab,oklab; + +begin + dbus_message_iter_init_append(amessage,@iter1); + pt:= @paramtypes[0]; + pte:= pt + length(paramtypes); + pd:= @params[0]; + pde:= pd + length(params); + while pd < pde do begin + if not writevalue(iter1,pt,pd,pd1) then begin //pd1 is dummy + goto errorlab; + end; + end; + goto oklab; + if pt <> pte then begin + error('dbuscallmethod() paramtypes and params count do not match'); + goto errorlab; + end; +errorlab: + dbus_message_unref(amessage); + raiseerror(dbuslasterror); +oklab: +end; +*) + +procedure tdbusservice.setupmessage(const amessage: pdbusmessage; + const params: array of variantvaluety); + + function writevalue(const aiter: dbusmessageiter; + const param: variantvaluety): boolean; + var + p1: pointer; + pe: pointer; + pc: pchar; + ps: pstring; + pv: pvariantvaluety; + pt: ptypeinfo; + v1: variantvaluety; + i1: int32; + iter1,iter2,iter3: dbusmessageiter; + s1: string; + pdict: pdictentryty; + piter: pdbusmessageiter; + label + oklab, + errorlab,error1lab,error2lab; + begin + if vf_var in param.flags then begin + if dbus_message_iter_open_container(@aiter,dbusdatacodes[dbt_variant], + pchar(dbusdatastring(param)),@iter3) = 0 then begin + outofmemory; + exit; + end; + piter:= @iter3; + end + else begin + piter:= @aiter; + end; + case param.kind of + vvk_string: begin + pc:= pchar(string(param.vstring)); + p1:= @pc; + end; + vvk_int32: begin + p1:= @param.vint32; + end; + vvk_card32: begin + p1:= @param.vcard32; + end; + vvk_variantar: begin + pt:= ptypeinfo(gettypedata(param.vvariantar.typinfo)^.eltype2); + s1:= dbusdatastring(pt); + if dbus_message_iter_open_container(piter,dbusdatacodes[dbt_array], + pchar(s1),@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + pv:= param.vvariantar.data; + pe:= pv+length(variantvaluearty(param.vvariantar.data)); + while pv < pe do begin + if not writevalue(iter1,pv^) then begin + goto error1lab; + end; + inc(pv); + end; + if dbus_message_iter_close_container(piter,@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + goto oklab; + end; + vvk_dynar: begin + if vf_dict in param.flags then begin + s1:= dbusdatastrings[dbt_dict_entry]; + end + else begin + pt:= ptypeinfo(gettypedata(param.vdynar.typinfo)^.eltype2); + s1:= dbusdatastring(pt); + end; + if dbus_message_iter_open_container(piter,dbusdatacodes[dbt_array], + pchar(s1),@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + if vf_dict in param.flags then begin + pdict:= param.vdynar.data; + pe:= pointer(pdict+length(dictentryarty(param.vdynar.data))); + while pointer(pdict) < pe do begin + if dbus_message_iter_open_container(@iter1,dbusdatacodes[dbt_dict_entry], + nil,@iter2) = 0 then begin + outofmemory(); + goto error1lab; + end; + v1.flags:= []; + v1.kind:= vvk_string; + v1.vstring:= pointer(pdict^.name); + if not writevalue(iter2,v1) then begin + goto error2lab; + end; + if not writevalue(iter2,pdict^.value) then begin + goto error2lab; + end; + if dbus_message_iter_close_container(@iter1,@iter2) = 0 then begin + outofmemory(); + goto error1lab; + end; + inc(pdict); + end; + end + else begin + case pt^.kind of + tkinteger: begin + i1:= dynarraylength(param.vdynar.data); + if i1 > 0 then begin + if dbus_message_iter_append_fixed_array(@iter1, + dbusdatacodes[inttypes[gettypedata(pt)^.ordtype]],@param.vdynar.data, + i1) = 0 then begin + outofmemory(); + goto error1lab; + end; + end; + end; + tkastring: begin + i1:= dynarraylength(param.vdynar.data); + if i1 > 0 then begin + ps:= param.vdynar.data; + pe:= ps+i1; + while ps < pe do begin + pc:= pchar(ps^); + if dbus_message_iter_append_basic( + @iter1,dbusdatacodes[dbt_string],@pc) = 0 then begin + outofmemory(); + goto error1lab; + end; + inc(ps); + end; + end; + end; +{ + tkrecord: begin + pv:= param.vdynar.data; + pe:= pv+length(variantvaluearty(param.vdynar.data)); + while pv < pe do begin + if not writevalue(iter1,pv^) then begin + goto error1lab; + end; + inc(pv); + end; + end; +} + else begin + raiseerror('dbuscallmethod() data type not yet supported'); + end; + end; + end; + if dbus_message_iter_close_container(piter,@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + goto oklab; + end; + vvk_record: begin + if dbus_message_iter_open_container(piter,dbusdatacodes[dbt_struct], + nil,@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + pv:= param.vvariantar.data; + pe:= pv+length(variantvaluearty(param.vvariantar.data)); + while pv < pe do begin + if not writevalue(iter1,pv^) then begin + goto error1lab; + end; + inc(pv); + end; + if dbus_message_iter_close_container(piter,@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + goto oklab; + end; + else begin + raiseerror('dbuscallmethod() variant data type not yet supported'); + end; + end; + if dbus_message_iter_append_basic(piter, + dbusdatatycodes[param.kind],p1) = 0 then begin + outofmemory(); + goto errorlab; + end; + oklab: + if piter <> @aiter then begin + if dbus_message_iter_close_container(@aiter,piter) = 0 then begin + outofmemory(); + exit; + end; + end; + result:= true; + exit; + + error2lab: + dbus_message_iter_abandon_container(@iter1,@iter2); + error1lab: + dbus_message_iter_abandon_container(piter,@iter1); + errorlab: + if piter <> @aiter then begin + dbus_message_iter_abandon_container(piter,piter); + end; + end;//writevalue + +var + pd,pe: pvariantvaluety; + iter1: dbusmessageiter; +begin + dbus_message_iter_init_append(amessage,@iter1); + pd:= @params[0]; + pe:= pd + length(params); + while pd < pe do begin + if not writevalue(iter1,pd^) then begin //pd1 is dummy + dbus_message_unref(amessage); + raiseerror(dbuslasterror); + end; + inc(pd); + end; +end; + +function tdbusservice.dbusreply(const amessage: pdbusmessage; + const params: array of variantvaluety): boolean; +var + m1: pdbusmessage; +begin + m1:= dbus_message_new_method_return(amessage); + setupmessage(m1,params); + result:= dbus_connection_send(fconn,m1,nil) <> 0; + dbus_message_unref(m1); +end; + +function tdbusservice.dbuserror(const amessage: pdbusmessage; + const aname: string; const atext: string): boolean; +var + m1: pdbusmessage; +begin + m1:= dbus_message_new_error(amessage,pchar(aname),pointer(atext)); + result:= dbus_connection_send(fconn,m1,nil) <> 0; + dbus_message_unref(m1); +end; + +function tdbusservice.dbussignal(const path: string; const iface: string; + const name: string; + const params: array of variantvaluety): boolean; +var + m1: pdbusmessage; +begin + result:= false; + m1:= dbus_message_new_signal(pchar(path),pchar(iface),pchar(name)); + setupmessage(m1,params); + result:= dbus_connection_send(fconn,m1,nil) <> 0; + dbus_message_unref(m1); +end; + + +function tdbusservice.methodcall(const bus_name,path,iface,method: string; + const params: array of variantvaluety): pdbusmessage; +begin + result:= dbus_message_new_method_call(pointer(bus_name),pchar(path), + pointer(iface),pchar(method)); + if result = nil then begin + outofmemory(); + end + else begin + setupmessage(result,params); + end; +end; + +type + callbackinfoty = record + handler: messageeventty; + end; + pcallbackinfoty = ^callbackinfoty; + +function filtertrampoline(connection: pDBusConnection; message: pDBusMessage; + user_data: pointer): DBusHandlerResult + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +var + handler: messageeventty; + b1: boolean; +begin + tmethod(handler).data:= user_data; + tmethod(handler).code:= @tdbusservice.mainfilter; + b1:= false; + handler(message,b1); + if b1 then begin + result:= DBUS_HANDLER_RESULT_HANDLED; +// dbus_message_unref(message); + end + else begin + result:= DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + end; +end; + +function objectpathhandlertrampoline(connection: pDBusConnection; + message: pDBusMessage; user_data: pointer): DBusHandlerResult + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +var + b1: boolean; +begin + with pcallbackinfoty(user_data)^ do begin + b1:= false; + handler(message,b1); + if b1 then begin + result:= DBUS_HANDLER_RESULT_HANDLED; + dbus_message_unref(message); + end + else begin + result:= DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + end; + end; +end; + +procedure unregisterobjectpath(connection: pDBusConnection; + user_data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + freemem(user_data); +end; +{ +const + dbuscallbackvtable: DBusObjectPathVTable = ( + unregister_function: @unregisterobjectpath; + message_function: @objectpathhandlertrampoline; + dbus_internal_pad1: nil; + dbus_internal_pad2: nil; + dbus_internal_pad3: nil; + dbus_internal_pad4: nil; + ); +} +{ +procedure tdbusservice.registerfallback(const apath: string; + const ahandler: messageeventty); +var + p1: pcallbackinfoty; +begin + p1:= getmem(sizeof(callbackinfoty)); + if dbus_connection_try_register_fallback(fconn, + pchar(apath), + @dbuscallbackvtable,p1,err) <> 0 then begin + with p1^ do begin + handler:= ahandler; + end; + end + else begin + freemem(p1); + raisedbuserror(); + end; +end; +} +{ +procedure tdbusservice.registeritem(const ainterface: string; + const apath: string; const asignature: string; + const ahandler: messageeventty); +var + p1: pcallbackinfoty; + s1: string; +begin + p1:= getmem(sizeof(callbackinfoty)); + with fregisteringobj^ do begin + s1:= pchar(fregisteringpath+'/'+apath); + if dbus_connection_try_register_object_path(fconn, + pchar(s1), + @dbuscallbackvtable,p1,err) <> 0 then begin + with p1^ do begin + handler:= ahandler; + end; + msearrayutils.additem(stringarty(items),apath); + end + else begin + freemem(p1); + raisedbuserror(); + end; + end; +end; +} +function tdbusservice.checkconnect(): boolean; +begin + result:= connected(); + if not result then begin + result:= connect(); + end; +end; + +const + introspectheader = +''+lineend; + +procedure tdbusservice.introspect(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + s1: string; + o1: hashoffsetty; +begin + s1:= introspectheader+''+lineend; + o1:= fitems.flastobject; + while o1 <> 0 do begin + with pdbusitemhashdataty(fitems.getdatapo(o1))^.data.data.obj do begin + s1:= s1+obj.getintrospecttext(1); + o1:= prev; + end; + end; + s1:= s1+''+lineend; + if dbusreply(amessage,variantvalue(s1)) then begin + ahandled:= true; + end; +end; + +procedure tdbusservice.registeritems(const sender: idbusservice); +begin + sender.registermethodhandler( + 'org.freedesktop.DBus.Introspectable','Introspect',[],@introspect,nil); +end; + +function tdbusservice.getpath(): string; +begin + result:= ''; +end; + +function tdbusservice.getintrospecttext(const aindent: int32): string; +begin + result:= indent(peerintf+introspectintf,aindent); +end; + +procedure tdbusservice.busconnected(); +begin + //dummy +end; + +procedure tdbusservice.registermethodhandler(const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); +var + offs1: hashoffsetty; + p1: phandlerhashdataty; + s1: string; +begin + s1:= getsignature(asignature); + offs1:= fhandlers.addmethod(fregisteringpath,ainterface,amember,s1,p1); + addoffs(hashoffsetarty(fregisteringobj^.handlers),offs1); + with p1^.data.handler do begin + datapo:= adata; + handler:= ahandler; + end; +end; + +procedure tdbusservice.registersignalhandler(const asender: string; + const apath: string; const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); +var + offs1: hashoffsetty; + p1: phandlerhashdataty; + s1: string; +begin + s1:= getsignature(asignature); + offs1:= fhandlers.addsignal(asender,apath,ainterface,amember,s1,p1); + addoffs(hashoffsetarty(fregisteringobj^.handlers),offs1); + with p1^.data.handler do begin + datapo:= adata; + handler:= ahandler; + end; +end; + +procedure tdbusservice.doregisteritems(const aobj: pobjinfoty); +begin + fregisteringobj:= aobj; + fregisteringpath:= '/'+dbuspath(aobj^.obj.getpath()); + try + aobj^.obj.registeritems(idbusservice(self)); + finally + fregisteringobj:= nil; + fregisteringpath:= ''; + end; +end; + +procedure tdbusservice.dounregisteritems(const aobj: pobjinfoty); +var + po1,poe: phashoffsetty; +begin + po1:= aobj^.handlers; + poe:= po1 + length(hashoffsetarty(aobj^.handlers)); + while po1 < poe do begin + fhandlers.delete(po1^); + inc(po1); + end; +end; + +procedure tdbusservice.unregisteritem(const apath: string); +begin + dbus_connection_unregister_object_path(fconn,pchar(apath)); +end; + +procedure tdbusservice.mainfilter(const amessage: pdbusmessage; + var handled: boolean); +var + p1: phandlerhashdataty; + + procedure handlesignal(); + begin + while not handled and (p1 <> nil) do begin + try + with p1^.data.handler do begin + handler(amessage,datapo,handled); + end; + except + //application.handleexception(); does not work because of idle recursion + on e: exception do begin + error(e.message); + end; + end; + p1:= fhandlers.getdatapoornil(p1^.data.handler.signal.next); + end; + end; + +begin +{$ifdef mse_dumpdbus} + write(dbusdumpmessage(amessage)); +{$endif} + handled:= false; + case dbus_message_get_type(amessage) of + DBUS_MESSAGE_TYPE_METHOD_CALL: begin + p1:= fhandlers.findmethod(dbus_message_get_path(amessage), + dbus_message_get_interface(amessage), + dbus_message_get_member(amessage), + dbus_message_get_signature(amessage)); + if p1 <> nil then begin + try + with p1^.data.handler do begin + handler(amessage,datapo,handled); + end; + except + //application.handleexception(); does not work because of idle recursion + on e: exception do begin + error(e.message); + end; + end; + end; + end; + DBUS_MESSAGE_TYPE_SIGNAL: begin + p1:= fhandlers.findsignal(dbus_message_get_sender(amessage), + dbus_message_get_path(amessage), + dbus_message_get_interface(amessage), + dbus_message_get_member(amessage), + dbus_message_get_signature(amessage)); + handlesignal(); + if not handled then begin + p1:= fhandlers.findsignal('', //try any sender + dbus_message_get_path(amessage), + dbus_message_get_interface(amessage), + dbus_message_get_member(amessage), + dbus_message_get_signature(amessage)); + handlesignal(); + end; + end; + end; +end; + +procedure tdbusservice.registerobjects(); +var + i1: int32; + p1: pdbusitemhashdataty; +begin + for i1:= 0 to fitems.count - 1 do begin + p1:= pointer(fitems.next()); + if p1^.data.data.kind = dbk_obj then begin + doregisteritems(@p1^.data.data.obj); + end; + end; + for i1:= 0 to fitems.count - 1 do begin + p1:= pointer(fitems.next()); + if p1^.data.data.kind = dbk_obj then begin + p1^.data.data.obj.obj.busconnected(); + end; + end; +end; + +procedure tdbusservice.unregisterobjects(); +begin +// unregisteritem('/'); +end; + +procedure tdbusservice.dounregisterobj(const aobj: pobjinfoty); +begin + if fconn <> nil then begin + dounregisteritems(aobj); + end; +end; + +procedure tdbusservice.registerobject(const sender: idbusobject); +var + p1: pobjinfoty; +begin + + p1:= fitems.addobject(sender); + if connected then begin + doregisteritems(p1); + sender.busconnected(); + end; +end; + +procedure tdbusservice.unregisterobject(const sender: idbusobject); +begin + fitems.delete(sender); +end; + +function tdbusservice.dbuscallmethod(const returnedto: idbusresponse; + var aserial: card32; + const bus_name: string; const path: string; const iface: string; + const method: string; + const params: array of variantvaluety; + const timeout: int32 = -1): boolean; + +var + pend1: pdbuspendingcall; + m1: pdbusmessage; + +label + errorlab; +begin + result:= false; + if checkconnect() then begin + m1:= methodcall(bus_name,path,iface,method,params); + if m1 <> nil then begin + result:= dbus_connection_send_with_reply(fconn,m1,@pend1,timeout) <> 0; + if not result then begin + outofmemory(); + goto errorlab; + end; + fitems.addpending(pend1,returnedto,aserial); + dbus_pending_call_set_notify(pend1,@pendingcallback,self,nil); +errorlab: + dbus_message_unref(m1); + end; + end; +end; + +function tdbusservice.dbuscallmethod(const bus_name: string; + const path: string; const iface: string; const method: string; + const params: array of variantvaluety; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; +var + m1,m2: pdbusmessage; + +label + errorlab; +begin + result:= false; + if checkconnect() then begin + m1:= methodcall(bus_name,path,iface,method,params); + if m1 <> nil then begin + m2:= dbus_connection_send_with_reply_and_block(fconn,m1,timeout,err()); + if m2 = nil then begin + checkok(); + end + else begin + result:= dbusreadmessage(m2,resulttypes,results); + dbus_message_unref(m2); + end; +errorlab: + dbus_message_unref(m1); + end; + end; +end; + +function tdbusservice.dbusgetproperty( + const bus_name,path,iface,property_name: string; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; //blocking, true if ok +begin + result:= dbuscallmethod(bus_name,path,'org.freedesktop.DBus.Properties','Get', + [variantvalue(iface),variantvalue(property_name)], + resulttypes,results,timeout) +end; + +function tdbusservice.dbusreadmessage(const amessage: pdbusmessage; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const apartial: boolean = false): boolean; + //true if ok +var + pte: pdbusdataty; + + function readvalue(var aiter: dbusmessageiter; + var pt: pdbusdataty; var pd: ppointer): boolean; + var + i1,i2,i3: int32; + si1: sizeint; + p1,p2: pointer; + p3: pdbusdataty; + p4: ppointer; + bool1: dbus_bool_t; + pc1: pcchar; + isstring: boolean; + typ1: pdynarraytypeinfo; + t1: dbusdataty; + iter2,iter3: dbusmessageiter; + iterpo: pdbusmessageiter; + + label + oklab; + begin + result:= false; + if pt >= pte then begin + error('dbuscallmethod() resulttypes and results count do not match'); + exit; + end; + iterpo:= @aiter; + i1:= dbus_message_iter_get_arg_type(iterpo); + if i1 = DBUS_TYPE_INVALID then begin + error('dbuscallmethod() returned param count:'+ + inttostr(pd - ppointer(@results[0]))+ + ' expected:'+inttostr(length(results))); + exit; + end; + if i1 = DBUS_TYPE_VARIANT then begin + dbus_message_iter_recurse(@aiter,@iter3); + iterpo:= @iter3; + i1:= dbus_message_iter_get_arg_type(iterpo); //nested variants? + end; + if i1 <> dbusdatacodes[pt^] then begin + error('dbuscallmethod() returned param does not match:'+inttostr(i1)+ + ' expected:'+inttostr(dbusdatacodes[pt^])); + exit; + end; + isstring:= false; + p1:= pd^; + case i1 of +// DBUS_TYPE_INVALID, + DBUS_TYPE_BYTE: begin + end; + DBUS_TYPE_BOOLEAN: begin + p1:= @bool1; + end; + DBUS_TYPE_INT16: begin + end; + DBUS_TYPE_UINT16: begin + end; + DBUS_TYPE_INT32: begin + end; + DBUS_TYPE_UINT32: begin + end; + DBUS_TYPE_INT64: begin + end; + DBUS_TYPE_UINT64: begin + end; + DBUS_TYPE_DOUBLE: begin + end; + DBUS_TYPE_STRING,DBUS_TYPE_OBJECT_PATH,DBUS_TYPE_SIGNATURE: begin + isstring:= true; + p1:= @pc1; + end; + +// DBUS_TYPE_UNIX_FD, + DBUS_TYPE_ARRAY: begin + inc(pt); + if pt >= pte then begin + error('dbuscallmethod() returntypes and returns count do not match'); + exit; + end; + i1:= dbusdatasizes[pt^]; + if i1 = 0 then begin + error('dbuscallmethod() array item type not yet supported'); + exit; + end; + i2:= dbus_message_iter_get_element_type(iterpo); + if i2 <> dbusdatacodes[pt^] then begin + error('dbuscallmethod() returned array item type does not match'); + exit; + end; + p1:= pd^; //pointer to var + t1:= pt^; + typ1:= arraytypes[t1]; + i3:= 0; + dbus_message_iter_recurse(iterpo,@iter2); + while dbus_message_iter_get_arg_type(@iter2) <> DBUS_TYPE_INVALID do begin + msearrayutils.additem(p1^,typ1,i3); + p2:= ppointer(p1)^ + i1*(i3-1); //data pointer in array + p4:= @p2; + p3:= @t1; + if not readvalue(iter2,p3,p4) then begin + exit; + end; + end; + si1:= i3; + dynarraysetlength(ppointer(p1)^,typ1,1,@si1); + goto oklab; + end; //array +// DBUS_TYPE_VARIANT, +// DBUS_TYPE_STRUCT, +// DBUS_TYPE_DICT_ENTRY + else begin + error('dbuscallmethod() invalid returned value'); + exit; + end; + end; + dbus_message_iter_get_basic(iterpo,p1); + p1:= pd^; + if isstring then begin + if pc1 = nil then begin + pansistring(p1)^:= ''; + end + else begin + pansistring(p1)^:= ansistring(pc1); + end; + end + else begin + if i1 = DBUS_TYPE_BOOLEAN then begin + pboolean(p1)^:= bool1 <> 0; + end; + end; + oklab: + dbus_message_iter_next(@aiter); + inc(pt); + inc(pd); + result:= true; + end;//readvalue + +var + iter1: dbusmessageiter; + pde: ppointer; + pt: pdbusdataty; + pd: ppointer; + s1: string; + p1: pointer; + t1: dbusdataty; + +label + errorlab; +begin + result:= false; + if checkconnect() then begin + if amessage = nil then begin + error('NIL message'); + goto errorlab; + end + else begin + dbus_message_iter_init(amessage,@iter1); + + if dbus_message_get_type(amessage) = DBUS_MESSAGE_TYPE_ERROR then begin + p1:= @s1; + pd:= @p1; + t1:= dbt_string; + pt:= @t1; + pte:= pt+1; + if readvalue(iter1,pt,pd) then begin + error(s1); + end; + goto errorlab; + end; + + pt:= @resulttypes[0]; + pte:= pt + length(resulttypes); + pd:= @results[0]; + pde:= pd + length(results); + while pd < pde do begin + if not readvalue(iter1,pt,pd) then begin + goto errorlab; + end; + end; + if not apartial and (dbus_message_iter_get_arg_type(@iter1) <> + DBUS_TYPE_INVALID) then begin + error('dbuscallmethod() wrong returned param count'); + goto errorlab; + end; + if pt <> pte then begin + error('dbuscallmethod() resulttypes and results count do not match'); + goto errorlab; + end; + result:= true; + end; +errorlab: + end; +end; + +function tdbusservice.connect: boolean; +var + i1,i2: int32; + s1,s2: string; +begin + if fconn <> nil then begin + result:= true; + exit; + end; + result:= false; + try + if not initdbuslib() then begin + exit; + end; + dbus_error_init(@ferr); + fconn:= dbus_bus_get_private(dbus_bus_session,err); + if fconn = nil then begin + checkok(); + end + else begin + dbus_connection_set_exit_on_disconnect(fconn,0); + fbusid:= dbus_bus_get_unique_name(fconn); + s1:= msebusname+'-'+inttostr(sys_getpid())+'-'; + i1:= nextidnumber; + repeat + s2:= s1+inttostr(i1); + i2:= dbus_bus_request_name(fconn,pchar(s2), + DBUS_NAME_FLAG_DO_NOT_QUEUE,err()); + inc(i1); + if (i1 > nextidnumber+200) or (i2 < 0) then begin + disconnect(); + exit; + end; + until (i2 = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER){ or + (i2 = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER)}; + nextidnumber:= i1; + fbusname:= s2; + dbus_connection_add_filter(fconn,@filtertrampoline,self,nil); + //start asynchronous message handling + dbus_connection_set_watch_functions(fconn,@addwatch,@removewatch, + @watchtoggled,self,nil); + dbus_connection_set_timeout_functions(fconn,@addtimeout,@removetimeout, + @timeouttoggled,self,nil); + application.registeronidle(@doidle); + registerobjects(); + result:= true; + end; + except + on e: exception do begin + dbuslasterror:= e.message; + end; + end; +end; + +procedure tdbusservice.disconnect(); +begin + if fconn <> nil then begin + unregisterobjects(); + dbus_connection_close(fconn); + dbus_connection_remove_filter(fconn,@filtertrampoline,self); + fitems.clear(); + if not applicationdestroyed() then begin + application.unregisteronidle(@doidle); + end; + err(); //free ferr + dbus_shutdown(); + fconn:= nil; + fbusid:= ''; + fbusname:= ''; +// releasedbus(); + end; +end; + +function tdbusservice.doaddwatch(const awatch: pdbuswatch): int32; +var + i1,i2: int32; + fla1: pollflagsty; + p1: pwatchinfoty; +begin + result:= 0; + i2:= dbus_watch_get_unix_fd(awatch); + if i2 > 0 then begin + fla1:= []; + i1:= dbus_watch_get_flags(awatch); + if i1 and DBUS_WATCH_READABLE <> 0 then begin + include(fla1,pf_in); + end; + if i1 and DBUS_WATCH_WRITABLE <> 0 then begin + include(fla1,pf_out); + end; + p1:= fitems.addwatch(awatch); + gui_addpollfd(p1^.id,i2,fla1,@fitems.dopollcallback,awatch); + updatewatch(awatch); + result:= 1; + end; +end; + +procedure tdbusservice.updatewatch(const awatch: pdbuswatch); +begin + with fitems.findwatch(awatch)^ do begin + gui_setpollfdactive(id,dbus_watch_get_enabled(awatch) <> 0); + end; +end; + +procedure tdbusservice.dowatchtoggled(const awatch: pdbuswatch); +begin + updatewatch(awatch); +end; + +procedure tdbusservice.doremovewatch(const awatch: pdbuswatch); +//var +// p1: pwatchinfoty; +begin + fitems.delete(awatch); +{ + p1:= dbus_watch_get_data(awatch); + gui_removepollfd(p1^.id); + removeitem(pointerarty(fwatches),p1); +} +end; + +procedure tdbusservice.updatetimeout(const atimeout: pdbustimeout); +var + i1: int32; + b1: boolean; +begin + with fitems.findtimeout(atimeout)^.timer do begin + b1:= dbus_timeout_get_enabled(atimeout) <> 0; + i1:= dbus_timeout_get_interval(atimeout)*1000; + if b1 then begin + if i1 <> interval then begin + interval:= i1; + enabled:= true; + end; + end + else begin + enabled:= false; + interval:= i1; + end; + end; +end; + +function tdbusservice.doaddtimeout(const atimeout: pdbustimeout): int32; +var + meth1: notifyeventty; +begin + meth1:= @dotimer; + tmethod(meth1).data:= atimeout; + with pdbusitemhashdataty(fitems.add(atimeout))^.data.data do begin + kind:= dbk_timeout; + with timeout do begin + timer:= tsimpletimer.create(0,meth1); + end; + end; +// dbus_timeout_set_data(atimeout,ti1,@freetimeout); + updatetimeout(atimeout); + result:= 1; +end; + +procedure tdbusservice.dotimeouttoggled(const atimeout: pdbustimeout); +begin + updatetimeout(atimeout); +end; + +procedure tdbusservice.doremovetimeout(const atimeout: pdbustimeout); +begin + fitems.delete(atimeout); +end; + +procedure tdbusservice.dotimer(const sender: tobject); +var + timeout1: pdbustimeout; +begin +{$ifdef mse_debugdbus} + writeln('**dotimer'); +{$endif} + timeout1:= pdbustimeout(pointer(self)); + dbus_timeout_handle(timeout1); +end; + +function tdbusservice.err(): pdbuserror; +begin + if dbus_error_is_set(@ferr) <> 0 then begin + dbus_error_free(@ferr); + end; + result:= @ferr; +end; + +function tdbusservice.checkok(): boolean; +begin + result:= dbus_error_is_set(@ferr) = 0; + if not result then begin + dbuslasterror:= string(ferr.message); + end; +end; + +procedure tdbusservice.raisedbuserror(); +begin + if not checkok() then begin + raiseerror(dbuslasterror); + end; +end; + +procedure tdbusservice.doidle(var again: boolean); +begin + if fconn <> nil then begin +{$ifdef mse_debugdbus} + writeln('**doidle'); +{$endif} + fitems.handlewatches(); + repeat + until dbus_connection_dispatch(fconn) <> DBUS_DISPATCH_DATA_REMAINS; + dbus_connection_flush(fconn); + end; +end; + +procedure tdbusservice.dopendingcallback(pending: pDBusPendingCall{; + user_data: pointer}); +var + m1: pdbusmessage; + p1: pdbusitemhashdataty; +begin + m1:= dbus_pending_call_steal_reply(pending); + with fitems.findpending(pending)^ do begin + if link <> 0 then begin + p1:= fitems.getdatapo(link); + idbusresponse(p1^.data.data.link.link).replied(serial,m1{,user_data}); +// fitems.delete(link); + end; + fitems.delete(pending); + end; + if m1 <> nil then begin + dbus_message_unref(m1); + end; +end; + +{ +procedure tdbusservice.dofreependingcallback(memory: pointer); +begin + removeitem(pointerarty(fpendings),memory); + freemem(memory); +end; +} +{ tdbusobject } + +constructor tdbusobject.create(const aservice: tdbusservice); +begin + setlinkedvar(aservice,tlinkedobject(fservice)); + inherited create; + if fservice <> nil then begin + fservice.registerobject(idbusobject(self)); + end; +end; + +destructor tdbusobject.destroy(); +begin + if fservice <> nil then begin + fservice.unregisterobject(idbusobject(self)); + end; + inherited; +end; +{ +function tdbusobject.getinstance(): tobject; +begin + result:= self; +end; +} +procedure tdbusobject.registeritems(const sender: idbusservice); +begin + sender.registermethodhandler( + 'org.freedesktop.DBus.Introspectable','Introspect',[],@introspect,nil); + sender.registermethodhandler( + 'org.freedesktop.DBus.Properties','Get', + [dbt_string,dbt_string],@propget,nil); + sender.registermethodhandler( + 'org.freedesktop.DBus.Properties','Set', + [dbt_string,dbt_string,dbt_variant],@propset,nil); + sender.registermethodhandler( + 'org.freedesktop.DBus.Properties','GetAll', + [dbt_string],@propgetall,nil); +end; + +function tdbusobject.getpath(): string; +begin + result:= ''; +end; + +function tdbusobject.getintrospecttext(const aindent: int32): string; +var + s1: string; +begin + s1:= charstring(' ',2*aindent); + result:= s1+''+lineend; + result:= result + indent(getintrospectitems(),aindent+1); + result:= result+s1+''+lineend; +end; + +procedure tdbusobject.busconnected(); +begin + //dummy +end; + +procedure tdbusobject.introspect(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + s1: string; +begin + s1:= introspectheader+getintrospecttext(0); + fservice.dbusreply(amessage,variantvalue(s1)); + ahandled:= true; +end; + +function tdbusobject.getpropvalue(const aprop: ppropinfo; + out avalue: variantvaluety): boolean; +var + p3: pointer; +begin + result:= true; + with aprop^ do begin + if getproc <> nil then begin + case proptype^.kind of + tkastring: begin + setvariantvalue(getstrprop(self,aprop),avalue,[vf_var]); + end; + tkinteger: begin + setvariantvalue(int32(getordprop(self,aprop)),avalue,[vf_var]); + end; + tkdynarray: begin + p3:= pointer(ptruint(getordprop(self,aprop))); + setvariantvalue(@p3,proptype,avalue,[vf_var]); + end; + else begin + result:= false; + end; + end; + end + else begin + result:= false; + end; + end; +end; + +procedure tdbusobject.propget(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); +var + s1,s2: string; + p1: ppropinfo; + v1: variantvaluety; +begin + if fservice.dbusreadmessage(amessage, + [dbt_string,dbt_string],[@s1,@s2]) then begin + if (s1 = '') or (s1 = getpropintf()) then begin + v1.kind:= vvk_none; + propertyget(amessage,s2,v1); + if v1.kind = vvk_none then begin + p1:= getpropinfo(self,s2); + if p1 = nil then begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.InvalidArgs', + 'Property '+s2+' was not found in object '+rootpath()); + end + else begin + if not getpropvalue(p1,v1) then begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.PropertyWriteOnly', //unofficional + 'Property '+s2+' is write only'); + end; + end; + end; + if v1.kind <> vvk_none then begin + fservice.dbusreply(amessage,[v1]); + end; + end + else begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.UnknownInterface', + 'Interface '+s1+' was not found in object '+rootpath()); + end; + end; + ahandled:= true; +end; + +procedure tdbusobject.propset(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + s1,s2,s3: string; + p1: ppropinfo; + b1: boolean; +label + oklab; +begin + if fservice.dbusreadmessage(amessage,[dbt_string,dbt_string], + [@s1,@s2],true) then begin + if (s1 = '') or (s1 = getpropintf()) then begin + b1:= false; + propertyset(amessage,s2,b1); + if not b1 then begin + p1:= getpropinfo(self,s2); + if p1 = nil then begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.InvalidArgs', + 'Property '+s2+' was not found in object '+rootpath()); + end + else begin + if p1^.setproc = nil then begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.PropertyReadOnly', + 'Property '+s2+' is read only'); + end + else begin + case p1^.proptype^.kind of + tkastring: begin + if fservice.dbusreadmessage(amessage, + [dbt_string,dbt_string,dbt_string],[@s1,@s2,@s3]) then begin + setstrprop(self,p1,s3); + goto oklab; + end; + end; + end; + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.InvalidArgs', + 'Property '+s2+' wrong type'); + end; + end; + end; + end + else begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.UnknownInterface', + 'Interface '+s1+' was not found in object '+rootpath()); + end; + end; +oklab: + ahandled:= true; +end; + +type + pppropinfo = ^ppropinfo; + +procedure tdbusobject.propgetall(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + ar1: dictentryarty; + ar2: propinfopoarty; + i1,i2: int32; + p1: pdictentryty; + p2: pppropinfo; +// dynar1: dynarinfoty; +begin + propertiesget(ar1); + + i1:= length(ar1); + ar2:= getpropinfoar(self); + setlength(ar1,i1+length(ar2)); //max + + try + p1:= @ar1[i1]; + p2:= pointer(ar2); + for i2:= i1 to high(ar1) do begin + if getpropvalue(p2^,p1^.value) then begin + p1^.name:= p2^^.name; + inc(p1); + end; + inc(p2); + end; + setlength(ar1,p1-pdictentryty(pointer(ar1))); +// dynar1.data:= pointer(ar1); +// dynar1.typinfo:= typeinfo(ar1); + if fservice.dbusreply(amessage, + variantvalue(@ar1,typeinfo(ar1),[vf_dict])) then begin + ahandled:= true; + end; + finally + finalizedictentryar(ar1); + end; +end; + +function tdbusobject.getintrospectitems(): string; +begin + result:= introspectintf+propertiesintf; +end; + +function tdbusobject.getpropintf: string; +begin + result:= ''; +end; + +function tdbusobject.rootpath: string; +begin + result:= '/'+dbuspath(getpath()); +end; + +procedure tdbusobject.propchangesignal(const amember: string); +begin + if (fservice <> nil) and fservice.connected then begin + fservice.dbussignal(rootpath(),getpropintf(),amember,[]); + end; +end; +{ +procedure tdbusobject.setrecordprop(const adataad: pointer; + atype: ptypeinfo; var avalue: variantvaluety; + const aflags: variantflagsty = []); +begin + if atype^.kind = tkdynarray then begin + atype:= gettypedata(atype)^.eltype2; + end; + setvariantvalue(adataad,atype,avalue,aflags); +end; +} +procedure tdbusobject.propertyget(const amessage: pdbusmessage; + const aname: string; var avalue: variantvaluety); +begin + //dummy +end; + +procedure tdbusobject.propertiesget(var props: dictentryarty); +begin + //dummy +end; + +procedure tdbusobject.propertyset(const amessage: pdbusmessage; + const aname: string; var ahandled: boolean); +begin + //dummy +end; + +{ +procedure tdbusobject.unregisteritems(const sender: idbusservice); +begin + //dummy +end; +} +{ thandlerhashdatalist } + +constructor thandlerhashdatalist.create(const aowner: tdbusservice); +begin + fowner:= aowner; + fstringidents:= tstringidents.create(); + femptystringid:= fstringidents.getident(''); + fstate:= fstate+[hls_needsnull,hls_needsfinalize]; + inherited create(); +end; + +destructor thandlerhashdatalist.destroy(); +begin + inherited; + fstringidents.free(); +end; + +function thandlerhashdatalist.scanpath(var avec: identvecty; + const apath: pchar; const aseparator: char): boolean; +var + p1,p2: pchar; +begin + result:= true; + with avec do begin + if high >= system.high(d) then begin + result:= false; + exit; + end; + inc(high); + d[high]:= separatorid; + if apath <> nil then begin + p1:= apath; + while p1^ <> #0 do begin + if high >= system.high(d) then begin + result:= false; + exit; + end; + p2:= p1; + while (p2^ <> aseparator) and (p2^ <> #0) do begin + inc(p2); + end; + inc(high); + d[high]:= fstringidents.getident(p1,p2); + if p2^ = #0 then begin + break; + end; + p1:= p2+1; + end; + end; + end; +end; + +function thandlerhashdatalist.addmethod( + const aobject,ainterface,amember,asignature: string; + out adata: phandlerhashdataty): hashoffsetty; + procedure pathlenerror(); + begin + raiseerror('Too many path elements'); + end;//pathlenerror + +var + vec1: identvecty; +begin + vec1.high:= 0; + vec1.d[0]:= methodhandlerid; + if not scanpath(vec1,pchar(aobject),'/') then begin + pathlenerror(); + end; + if not scanpath(vec1,pchar(ainterface),'.') then begin + pathlenerror(); + end; + if not scanpath(vec1,pchar(amember),'.') then begin + pathlenerror(); + end; + if not scanpath(vec1,pchar(asignature),#0) then begin + pathlenerror(); + end; + result:= inherited add(vec1,pointer(adata)); + adata^.data.kind:= hk_method; +end; + +function constructmatch(const asender,apath,ainterface,amember: string): string; +begin + result:= ''; + if asender <> '' then begin + result:= result+'sender='+''''+asender+''','; + end; + if apath <> '' then begin + result:= result+'path='+''''+apath+''','; + end; + if ainterface <> '' then begin + result:= result+'interface='+''''+ainterface+''','; + end; + if amember <> '' then begin + result:= result+'member='+''''+amember+''','; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; +end; + +function thandlerhashdatalist.addsignal( + const asender,apath,ainterface,amember,asignature: string; + out adata: phandlerhashdataty): hashoffsetty; + procedure pathlenerror(); + begin + raiseerror('Too many path elements'); + end;//pathlenerror + +var + vec1: identvecty; + p1: phandlerhashdataty; + s1: string; + o1,o2: hashoffsetty; +begin + s1:= 'type=signal,'+constructmatch(asender,apath,ainterface,amember); + vec1.high:= 1; + vec1.d[0]:= signalmatchid; + vec1.d[1]:= fstringidents.getident(s1); + p1:= phandlerhashdataty(find(vec1)); + if p1 = nil then begin + add(vec1,pointer(p1)); + dbus_bus_add_match(fowner.fconn,pchar(s1),nil); + p1^.data.kind:= hk_match; + with p1^.data.match do begin + match:= vec1.d[1]; + refcount:= 0; + end; + end; + o1:= getdataoffs(p1); + inc(p1^.data.match.refcount); + + vec1.high:= 5; + vec1.d[0]:= signalhandlerid; + vec1.d[1]:= fstringidents.getident(asender); + vec1.d[2]:= fstringidents.getident(apath); + vec1.d[3]:= fstringidents.getident(ainterface); + vec1.d[4]:= fstringidents.getident(amember); + vec1.d[5]:= fstringidents.getident(asignature); + find(vec1,o2); //always the last entered? + result:= inherited add(vec1,pointer(adata)); + adata^.data.kind:= hk_signal; + with adata^.data.handler do begin + signal.match:= o1; + signal.prev:= 0; + if o2 <> 0 then begin + phandlerhashdataty(getdatapo(o2))^.data.handler.signal.prev:= result; + + signal.next:= o2; + end + else begin + signal.next:= 0; + end; + end; +end; + +function thandlerhashdatalist.findmethod(const aobject: pchar; + const ainterface: pchar; const amember: pchar; + const asignature: pchar): phandlerhashdataty; +var + vec1: identvecty; +begin + result:= nil; + vec1.high:= 0; + vec1.d[0]:= methodhandlerid; + if scanpath(vec1,aobject,'/') and + scanpath(vec1,ainterface,'.') and + scanpath(vec1,amember,'.') and + scanpath(vec1,asignature,#0) then begin + result:= phandlerhashdataty(inherited find(vec1)); + if (result <> nil) and (result^.data.kind <> hk_method) then begin + result:= nil; + end; + end; +end; + +function thandlerhashdatalist.findsignal(const asender: pchar; + const apath: pchar; const ainterface: pchar; + const amember: pchar; const asignature: pchar): phandlerhashdataty; +var + vec1: identvecty; +begin + vec1.high:= 5; + vec1.d[0]:= signalhandlerid; + vec1.d[1]:= fstringidents.getident(asender); + vec1.d[2]:= fstringidents.getident(apath); + vec1.d[3]:= fstringidents.getident(ainterface); + vec1.d[4]:= fstringidents.getident(amember); + vec1.d[5]:= fstringidents.getident(asignature); + result:= phandlerhashdataty(inherited find(vec1)); + if (result <> nil) and (result^.data.kind <> hk_signal) then begin + result:= nil; + end; +end; + +function thandlerhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(handlerhashdataty); +end; + +procedure thandlerhashdatalist.finalizeitem(const aitem: phashdataty); +var + p1: phandlerhashdataty; +begin + with phandlerhashdataty(aitem)^ do begin + case data.kind of + hk_match: begin + if fowner.fconn <> nil then begin + dbus_bus_remove_match(fowner.fconn, + fstringidents.getidentnamep(data.match.match),nil); + end; + end; + hk_signal: begin + if data.handler.signal.next <> 0 then begin + phandlerhashdataty(getdatapo(data.handler.signal.next))^. + data.handler.signal.prev:= data.handler.signal.prev; + end; + if data.handler.signal.prev <> 0 then begin + phandlerhashdataty(getdatapo(data.handler.signal.prev))^. + data.handler.signal.next:= data.handler.signal.next; + end; + p1:= getdatapo(data.handler.signal.match); + dec(p1^.data.match.refcount); + if p1^.data.match.refcount = 0 then begin + internaldelete(data.handler.signal.match); + end; + end; + end; + end; + inherited; +end; + +{ +var + card32rec: record b: byte; v: card32 end; +const + card32align: int32 = (@card32rec.v - @card32rec.b); + + dbusalignments: array[dbusdataty] of int32 = ( + 0, //dbt_INVALID, + sizeof(byte), //dbt_BYTE, + sizeof(boolean), //dbt_BOOLEAN, + sizeof(int16), //dbt_INT16, + sizeof(card16), //dbt_UINT16, + sizeof(int32), //dbt_INT32, + sizeof(card32), //dbt_UINT32, + sizeof(int64), //dbt_INT64, + sizeof(card64), //dbt_UINT64, + sizeof(flo64), //dbt_DOUBLE, + sizeof(ansistring), //dbt_STRING, + sizeof(ansistring), //dbt_OBJECT_PATH, + sizeof(ansistring), //dbt_SIGNATURE, + 0, //dbt_UNIX_FD, + 0, //dbt_ARRAY, + 0, //dbt_VARIANT, + 0, //dbt_STRUCT, + sizeof(dictentryty), //dbt_DICT_ENTRY + sizeof(variantvaluety) //dbt_msevariant + ); +} + +procedure doinit(); +var + card32rec: record b: byte; v: card32 end; + card64rec: record b: byte; v: card64 end; + flo64rec: record b: byte; v: flo64 end; + porec: record b: byte; v: pointer end; + dictrec: record b: byte; v: dictentryty end; + msevarrec: record b: byte; v: variantvaluety end; + offs32: int32; + offs64: int32; + offsflo64: int32; + offspo: int32; + offsdict: int32; + offsmsevar: int32; +begin + offs32:= @card32rec.v - @card32rec.b; + offs64:= @card64rec.v - @card64rec.b; + offsflo64:= @flo64rec.v - @flo64rec.b; + offspo:= @porec.v - @porec.b; + offsdict:= @dictrec.v - @dictrec.b; + offsmsevar:= @msevarrec.v - @msevarrec.b; + + dbusalignments[dbt_INVALID]:= 0; + dbusalignments[dbt_BYTE]:= sizeof(byte); + dbusalignments[dbt_BOOLEAN]:= sizeof(boolean); + dbusalignments[dbt_INT16]:= sizeof(int16); + dbusalignments[dbt_UINT16]:= sizeof(uint16); + dbusalignments[dbt_INT32]:= offs32; + dbusalignments[dbt_UINT32]:= offs32; + dbusalignments[dbt_INT64]:= offs64; + dbusalignments[dbt_UINT64]:= offs64; + dbusalignments[dbt_DOUBLE]:= offsflo64; + dbusalignments[dbt_STRING]:= offspo; + dbusalignments[dbt_OBJECT_PATH]:= offspo; + dbusalignments[dbt_SIGNATURE]:= offspo; + dbusalignments[dbt_UNIX_FD]:= 0; + dbusalignments[dbt_ARRAY]:= 0; + dbusalignments[dbt_VARIANT]:= 0; + dbusalignments[dbt_STRUCT]:= 0; + dbusalignments[dbt_DICT_ENTRY]:= offsdict; + dbusalignments[dbt_msevariant]:= offsmsevar; + + arraytypes[dbt_INVALID]:= nil; + arraytypes[dbt_BYTE]:= typeinfo(bytearty); + arraytypes[dbt_BOOLEAN]:= typeinfo(booleanarty); + arraytypes[dbt_INT16]:= typeinfo(int16arty); + arraytypes[dbt_UINT16]:= typeinfo(card16arty); + arraytypes[dbt_INT32]:= typeinfo(int32arty); + arraytypes[dbt_UINT32]:= typeinfo(card32arty); + arraytypes[dbt_INT64]:= typeinfo(int64arty); + arraytypes[dbt_UINT64]:= typeinfo(card64arty); + arraytypes[dbt_DOUBLE]:= typeinfo(flo64arty); + arraytypes[dbt_STRING]:= typeinfo(ansistringarty); + arraytypes[dbt_OBJECT_PATH]:= typeinfo(ansistringarty); + arraytypes[dbt_SIGNATURE]:= typeinfo(ansistringarty); + arraytypes[dbt_UNIX_FD]:= nil; + arraytypes[dbt_ARRAY]:= nil; + arraytypes[dbt_VARIANT]:= nil; + arraytypes[dbt_STRUCT]:= nil; + arraytypes[dbt_DICT_ENTRY]:= nil; + arraytypes[dbt_msevariant]:= nil; +end; + +initialization + doinit(); +// clearlist(userdatacache,sizeof(userdatarecty),0); +finalization + dbuslasterror:= ''; //memory leak without on FPC 2.6.4 +// freelist(userdatacache); +end. diff --git a/mseide-msegui/lib/common/sysutils/mseenvmacros.pas b/mseide-msegui/lib/common/sysutils/mseenvmacros.pas new file mode 100644 index 0000000..ba6d20f --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseenvmacros.pas @@ -0,0 +1,67 @@ +{ MSEgui Copyright (c) 2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit mseenvmacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msemacros; + +function envmacros(): macroinfoarty; + +implementation +uses + msetypes{msestrings},msesysintf; + +var + fenvmacros: macroinfoarty; + +function envmacros(): macroinfoarty; +begin + result:= fenvmacros; +end; + +function env_var(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + if sys_getenv(params[0],result) then begin + if high(params) > 1 then begin + result:= params[2]; + end; + end + else begin + if high(params) > 0 then begin + result:= params[1]; + end; + end; + end; +end; + +const + envmacroconst: array[0..0] of macroinfoty = ( + (name: 'ENV_VAR'; value: ''; handler: macrohandlerty(@env_var); + expandlevel: 0) + ); + +procedure initenvmacros(); +var + int1: integer; +begin + setlength(fenvmacros,length(envmacroconst)); + for int1:= 0 to high(envmacroconst) do begin + fenvmacros[int1]:= envmacroconst[int1]; + end; +end; + +initialization + initenvmacros(); +end. diff --git a/mseide-msegui/lib/common/sysutils/mseexecmacros.pas b/mseide-msegui/lib/common/sysutils/mseexecmacros.pas new file mode 100644 index 0000000..263841b --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseexecmacros.pas @@ -0,0 +1,73 @@ +{ MSEgui Copyright (c) 2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit mseexecmacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msemacros; + +function execmacros(): macroinfoarty; + +implementation +uses + mseprocess,mseprocutils,msefileutils,msetypes{msestrings},mseformatstr; + +var + fexecmacros: macroinfoarty; + +function execmacros(): macroinfoarty; +begin + result:= fexecmacros; +end; + +function exec_out(const sender: tmacrolist; + const params: msestringarty): msestring; +const + defaulttimeout = 1000000; //1 second +var + str1: string; + i1: int32; +begin + result:= ''; + if params <> nil then begin + i1:= defaulttimeout; + if high(params) >= 1 then begin + if trystrtoint(params[1],i1) then begin + i1:= i1 * 1000; + end + else begin + i1:= defaulttimeout; + end; + end; + getprocessoutput(syscommandline(params[0]),'',str1,i1); + result:= msestring(str1); + end; +end; + +const + execmacroconst: array[0..0] of macroinfoty = ( + (name: 'EXEC_OUT'; value: ''; handler: macrohandlerty(@exec_out); + expandlevel: 0) //processoutput + ); + +procedure initexecmacros(); +var + int1: integer; +begin + setlength(fexecmacros,length(execmacroconst)); + for int1:= 0 to high(execmacroconst) do begin + fexecmacros[int1]:= execmacroconst[int1]; + end; +end; + +initialization + initexecmacros(); +end. diff --git a/mseide-msegui/lib/common/sysutils/msefilechange.pas b/mseide-msegui/lib/common/sysutils/msefilechange.pas new file mode 100644 index 0000000..7641ced --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msefilechange.pas @@ -0,0 +1,708 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msefilechange; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface + +uses + mseclasses,SysUtils,msethread,msefileutils,msesys, + msetypes,msestrings,classes,mseapplication,mseevent; + +{$ifdef UNIX} +const + sigpuffermask = 32-1; //maximale anzahl pending notifications +{$endif} + +type + tfilechangenotifyer = class; + + filechangeinfoty = record + dir: filenamety; + infovorher: fileinfoty; + info: fileinfoty; + tag: integer; + force: boolean; + changed: filechangesty; + end; + + filechangedeventty = procedure(const sender: tfilechangenotifyer; + const info: filechangeinfoty) of object; + + filechangeinfo1ty = record + info: filechangeinfoty; + owner: tfilechangenotifyer; + isroot: boolean; + end; + fileinfosty = array of filechangeinfo1ty; + + tdirinfo = class + private + ffileinfos: fileinfosty; + fpath: filenamety; + fdirhandle: integer; + procedure deleteinfo(index: integer); + public + constructor create(afd: integer; const apath: filenamety); //owns the fd + destructor destroy; override; + procedure addfile(root: boolean; const sender: tfilechangenotifyer; + const tag: integer; const aforce: boolean; + const ainfo: fileinfoty); + procedure changed; + property path: filenamety read fpath; + end; + + dirchangedeventty = procedure(const sender: tdirinfo) of object; + +{$ifdef mswindows} + handlearty = array of thandle; +{$endif} + + tdirchangethread = class(tsemthread) + private +{$ifdef mswindows} + sem: cardinal; + dirdescriptors: handlearty; +{$endif} + fdirs: array of tdirinfo; +{$ifdef UNIX} + fsigqueue: array[0..sigpuffermask] of integer; + fsiginpo,fsigoutpo: integer; + procedure changesignal(const afd: integer); +{$endif} + procedure dochange(const afd: integer); + procedure deletedirinfo(index: integer); + protected + function execute(thread: tmsethread): integer; override; + public + constructor Create; + destructor Destroy; override; + procedure addnotification(const sender: tfilechangenotifyer; + const filename: filenamety; + const tag: integer; const force: boolean); + procedure removenotification(const sender: tfilechangenotifyer; + const filename: filenamety; tag: integer); + procedure clear; + //filename = '' -> filename nicht auswerten, + //onchanged = nil -> onchanged nicht auswerten. tag = 0 -> tag nicht auswerten + end; + + tfilechangenotifyer = class(tactcomponent) + private + fonfilechanged: filechangedeventty; + fpath: filenamety; + feventtag: integer; + procedure dofilechanged(const sender: tfilechangenotifyer; + const info: filechangeinfoty); + procedure setpath(const Value: filenamety); + procedure removepath; + procedure addpath; + procedure seteventtag(const Value: integer); + protected + procedure loaded; override; + procedure receiveevent(const event: tobjectevent); override; + public + destructor destroy; override; + procedure addnotification(const filename: filenamety; const atag: integer = 0; + const force: boolean = false); + procedure removenotification(const filename: filenamety; atag: integer = 0); + procedure clear; + published + property onfilechanged: filechangedeventty read fonfilechanged write fonfilechanged; + property path: filenamety read fpath write setpath; + property eventtag: integer read feventtag write seteventtag default 0; + + end; + +implementation +uses + msedatalist,rtlconsts,msesysintf1,msesysintf,mselist,msearrayutils +{$ifdef mswindows} + ,windows +{$else} + ,mselibc +{$endif} + ; +var + fchangethread: tdirchangethread; + +function changethread: tdirchangethread; +begin + if fchangethread = nil then begin + fchangethread:= tdirchangethread.Create; + end; + result:= fchangethread; +end; + +{$ifdef UNIX} +var + dirinfosig: integer; + +procedure DirChanged(SigNum : Integer; context: psiginfo; p: pointer); cdecl; + //kernel 2.6.25.18 does not return si_fd! +begin + if SigNum = dirinfosig then begin + if fchangethread <> nil then begin + fchangethread.changesignal(context^._sigpoll.si_fd); + end; + end; +end; + +const + notifyflags = DN_MODIFY or DN_CREATE or DN_DELETE or DN_RENAME or DN_ATTRIB; + +function adddir(const sender: tdirchangethread; + const name: filenamety): integer; +var +{$ifdef linux} + flags: longword; + action: tsigactionex; +{$endif} + str1: string; +begin + str1:= ansistring(name); + result:= mselibc.open(PChar(str1),o_rdonly); +// if sys_openfile(name,fm_read,[],[],result) = sye_ok then begin +{$ifdef linux} + if result >= 0 then begin + FillChar(action, SizeOf(action), 0); + with action do begin + sa_sigaction:= @DirChanged; + sa_flags := SA_SIGINFO or SA_RESTART; + end; + Flags:= notifyflags; + if not((sigactionex(dirinfosig,action, nil) = 0) and + (fcntl(result, F_SETSIG,[dirinfosig]) = 0) and + (fcntl(result, F_NOTIFY,[Flags]) = 0)) then begin + sys_closefile(result); //es hat nicht geklappt + result:= -1; + exit; + end; + unblocksignal(dirinfosig); + end; +{$endif} +end; + +{$ENDIF unix} + +{ tdirinfo } + +constructor tdirinfo.create(afd: integer; const apath: filenamety); +begin + fdirhandle:= afd; + fpath:= apath; + inherited create; +end; + +destructor tdirinfo.destroy; +begin + {$ifdef mswindows} + findclosechangenotification(fdirhandle); + {$else} + sys_closefile(fdirhandle); + {$endif} + inherited +end; + +procedure tdirinfo.deleteinfo(index: integer); +var + info1: array[0..sizeof(filechangeinfo1ty)-1] of byte; +begin + move(ffileinfos[index],info1,sizeof(info1)); + move(ffileinfos[index+1],ffileinfos[index], + (length(ffileinfos)-index-1)*sizeof(ffileinfos[0])); + move(info1,ffileinfos[high(ffileinfos)],sizeof(info1)); + setlength(ffileinfos,high(ffileinfos)); +end; + +procedure tdirinfo.addfile(root: boolean; const sender:tfilechangenotifyer; + const tag: integer; const aforce: boolean; const ainfo: fileinfoty); +var + int1: integer; +begin + int1:= length(ffileinfos); + setlength(ffileinfos,int1+1); + with ffileinfos[int1] do begin + info.dir:= fpath; + info.infovorher:= ainfo; + info.tag:= tag; + info.force:= aforce; + isroot:= root; + owner:= sender; + end; +end; + +type + tfilechangeevent = class(tasyncevent) + public + info: filechangeinfoty; + end; + +procedure tdirinfo.changed; +const + notcheckflags = [fc_accesstime,fc_ctime]; //ctime is unreliable in freebsd +var + int1: integer; + bo1: boolean; + str1: string; + aevent: tfilechangeevent; +begin +{$ifdef UNIX} + {$ifdef linux} + fcntl(fdirhandle,F_NOTIFY,[notifyflags]); + {$endif} +{$endif} + for int1:= 0 to length(ffileinfos) - 1 do begin + with ffileinfos[int1] do begin + if isroot then begin + bo1:= getfileinfo(filedir(fpath),info.info); + end + else begin + bo1:= getfileinfo(fpath+info.infovorher.name,info.info); + end; + if bo1 then begin + info.changed:= compfileinfos(info.infovorher,info.info); + end + else begin + bo1:= not (fc_removed in info.changed); //report only once + info.changed:= [fc_removed]; + end; + if isroot and (info.changed = []) then begin + include(info.changed,fc_direntries); + end; + if info.force then begin + include(info.changed,fc_force); + info.force:= false; + end; + if bo1 and (info.changed - notcheckflags <> []) then begin + aevent:= tfilechangeevent.Create(ievent(owner),0); + aevent.info:= info; + application.postevent(aevent); + str1:= ansistring(info.infovorher.name); + info.infovorher:= info.info; + info.infovorher.name:= filenamety(str1); + if not (fc_removed in info.changed) then begin + info.changed:= []; + end; + end; + end; + end; +end; + +constructor tdirchangethread.Create; +begin + {$ifdef mswindows} + setlength(dirdescriptors,1); + sem:= createsemaphore(nil,0,bigint,nil); + dirdescriptors[0]:= sem; + {$endif} + inherited Create({$ifdef FPC}@{$endif}execute); +end; + +destructor tdirchangethread.Destroy; +begin + terminate; + clear; +{$ifdef mswindows} + closehandle(sem); +{$endif} + inherited; +end; + +procedure tdirchangethread.deletedirinfo(index: integer); +begin + lock; + fdirs[index].Free; + + move(fdirs[index+1],fdirs[index],(length(fdirs)-index-1)*sizeof(fdirs[0])); + setlength(fdirs,length(fdirs)-1); +{$ifdef mswindows} + deleteitem(pointerarty(dirdescriptors),index+1); + releasesemaphore(sem,1,nil); +{$endif} + unlock; +end; + +procedure tdirchangethread.clear; +var + int1: integer; +begin + lock; + for int1:= 0 to length(fdirs) - 1 do begin + fdirs[int1].Free; + end; + setlength(fdirs,0); +{$ifdef mswindows} + setlength(dirdescriptors,1); + releasesemaphore(sem,1,nil); +{$endif} + unlock; +end; + +{$ifdef UNIX} +procedure tdirchangethread.changesignal(const afd: integer); +var + int1: integer; +begin + if not terminated then begin + int1:= fsigoutpo; + while int1 <> fsiginpo do begin + if fsigqueue[int1] = afd then begin + exit; //allready seen + end; + int1:= (int1 + 1) and sigpuffermask; + end; + int1:= (fsiginpo + 1) and sigpuffermask; + if int1 <> fsigoutpo then begin + fsigqueue[fsiginpo]:= afd; +// fsiginpo:= int1; + interlockedexchange(fsiginpo,int1); + end; + sempost; + end; +end; +{$endif} + +procedure tdirchangethread.dochange(const afd: integer); +var + int1: integer; +begin + if terminated or application.terminated then begin + exit; + end; + lock; + try + if afd = -1 then begin + for int1:= 0 to high(fdirs) do begin + fdirs[int1].changed; + end; + end + else begin + for int1:= 0 to high(fdirs) do begin + if (fdirs[int1].fdirhandle = afd) then begin + //ev. unzuverlaessig bei wiederverwendetem fd? + fdirs[int1].changed; + break; + end; + end; + end; + finally + unlock; + end; +end; + +function tdirchangethread.execute(thread: tmsethread): integer; +{$ifdef mswindows} +var + Obj: DWORD; + Handles: handlearty; + fafd: thandle; +begin + result:= 0; + handles:= nil; //compilerwarning + while not Terminated and not application.terminated do begin + lock; + handles:= copy(dirdescriptors); + unlock; + Obj := WaitForMultipleObjects(length(handles), @Handles[0], False, INFINITE); + if not terminated and not application.terminated then begin + if obj <> wait_failed then begin //else closed handle + obj:= obj - wait_object_0; + if (obj > 0) and (integer(obj) < length(handles)) then begin + fafd:= handles[obj]; + FindNextChangeNotification(fafd); + dochange(fafd); + end; + end; + end; + end; +end; +{$else} //unix +{$ifdef linux} +var + int1: integer; +{$endif} +begin + while not terminated do begin + {$ifdef linux} + semwait; + while not terminated and not (application.terminated) and + (fsiginpo <> fsigoutpo) do begin + int1:= fsigoutpo; + interlockedexchange(fsigoutpo,(fsigoutpo + 1) and sigpuffermask); + dochange(fsigqueue[int1]); + end; + {$else} + semwait(500000); //freebsd needs polling + if not terminated and not (application.terminated) then begin + dochange(-1); + end; + {$endif} + if not terminated then begin + sleep(500); + end; + end; + result:= 0; +end; +{$endif} + +procedure tdirchangethread.addnotification(const sender: tfilechangenotifyer; + const filename: filenamety; const tag: integer; + const force: boolean); +var + int1: integer; + apath: filenamety; + fname: filenamety; + wstr1: filenamety; + dirinfo: tdirinfo; + info: fileinfoty; +{$ifdef mswindows} + fd: thandle; +{$else} + fd: integer; +{$endif} + +begin + wstr1:= filepath(filename); + if not getfileinfo(wstr1,info) then begin +{$ifdef FPC} + raise EFCreateError.CreateFmt(SFCreateError,[filepath(FileName), + sys_geterrortext(mselasterror)]); +{$else} + + {$if RTLVersion > 14.1} + raise EFOpenError.CreateResFmt(@SFOpenErrorEx, [filepath(FileName), + SysErrorMessage(mselasterror)]); + {$else} + raise EFOpenError.CreateResFmt(@SFOpenError, [filepath(FileName), + SysErrorMessage(mselasterror)]); + {$ifend} +{$endif} + end; + if info.extinfo1.filetype = ft_dir then begin + apath:= filepath(wstr1,fk_dir); + fname:= ''; + end + else begin + splitfilepath(wstr1,apath,fname); +// apath:= extractfilepath(str1); +// fname:= extractfilename(str1); + end; + tosysfilepath1(apath); + dirinfo:= nil; + for int1:= 0 to length(fdirs) - 1 do begin + if fdirs[int1].path = apath then begin + dirinfo:= fdirs[int1]; + break; + end; + end; + lock; + if dirinfo = nil then begin + int1:= length(fdirs); +{$ifdef mswindows} + if iswin95 then begin + fd:= FindFirstChangeNotificationA(PChar(string(apath)), + False, FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME or + FILE_NOTIFY_CHANGE_ATTRIBUTES or FILE_NOTIFY_CHANGE_SIZE or + file_notify_change_last_write or file_notify_change_security); + end + else begin + fd:= FindFirstChangeNotificationW(PwideChar(apath), + False, FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME or + FILE_NOTIFY_CHANGE_ATTRIBUTES or FILE_NOTIFY_CHANGE_SIZE or + file_notify_change_last_write or file_notify_change_security); + end; + if fd <> invalid_handle_value then begin + setlength(dirdescriptors,int1+2); + dirdescriptors[int1+1]:= fd; +{$else unix} + fd:= adddir(self,apath); + if fd >= 0 then begin +{$endif} + setlength(fdirs,int1+1); + dirinfo:= tdirinfo.Create(fd,apath); + fdirs[int1]:= dirinfo; + + {$ifdef mswindows} + releasesemaphore(sem,1,nil); + {$endif} + end; + end; + if dirinfo <> nil then begin + dirinfo.addfile(fname = '',sender,tag,force,info); + end; + unlock; +end; + +procedure tdirchangethread.removenotification(const sender: tfilechangenotifyer; + const filename: filenamety; tag: integer); +var + apath,aname: filenamety; + int1,int2: integer; + +begin + if filename = '' then begin + apath:= ''; + end + else begin + apath:= tosysfilepath(filepath(filename,fk_dir)); + end; + lock; + for int1:= 0 to length(fdirs) - 1 do begin + with fdirs[int1] do begin + if (apath = '') or (fpath = apath) then begin + int2:= 0; + while int2 < length(ffileinfos) do begin + with ffileinfos[int2] do begin + if isroot and (owner = sender) and + ((tag = 0) or (info.tag = tag)) then begin + deleteinfo(int2); + end + else begin + inc(int2); + end; + end; + end; + end; + end; + end; + if filename = '' then begin + apath:= ''; + aname:= ''; + end + else begin + splitfilepath(filename,apath,aname); + end; + tosysfilepath1(apath); + for int1:= 0 to length(fdirs) - 1 do begin + with fdirs[int1] do begin + if (apath = '') or (fpath = apath) then begin + int2:= 0; + while int2 < length(ffileinfos) do begin + with ffileinfos[int2] do begin + if ((aname = '') or (info.infovorher.name = aname)) and + (owner = sender) and ((tag = 0) or (info.tag = tag)) then begin + deleteinfo(int2); + end + else begin + inc(int2); + end; + end; + end; + end; + end; + end; + int1:= 0; + while int1 < length(fdirs) do begin + if length(fdirs[int1].ffileinfos) = 0 then begin + deletedirinfo(int1); + end + else begin + inc(int1); + end; + end; + unlock; +end; + +{ tfilechangenotifyer } + +destructor tfilechangenotifyer.destroy; +begin + clear; + inherited; +end; + +procedure tfilechangenotifyer.dofilechanged(const sender: tfilechangenotifyer; + const info: filechangeinfoty); +begin + if assigned(fonfilechanged) then begin + fonfilechanged(self,info); + end; +end; + +procedure tfilechangenotifyer.setpath(const Value: filenamety); +begin + if fpath <> value then begin + removepath; + fpath := Value; + addpath; + end; +end; + +procedure tfilechangenotifyer.seteventtag(const Value: integer); +begin + if feventtag <> value then begin + removepath; + feventtag := Value; + addpath; + end; +end; + +procedure tfilechangenotifyer.loaded; +begin + inherited; + addpath; +end; + +procedure tfilechangenotifyer.receiveevent(const event: tobjectevent); +begin + if event is tfilechangeevent then begin + dofilechanged(self,tfilechangeevent(event).info); + end + else begin + inherited; + end; +end; + +procedure tfilechangenotifyer.addpath; +begin + if (fpath <> '') and (componentstate * [csdesigning,csloading] = []) then begin + addnotification(fpath,feventtag); + end; +end; + +procedure tfilechangenotifyer.removepath; +begin + if (fpath <> '') and (componentstate * [csdesigning,csloading] = []) then begin + removenotification(fpath,feventtag); + end; +end; + +procedure tfilechangenotifyer.addnotification(const filename: filenamety; + const atag: integer = 0; const force: boolean = false); +begin + changethread.addnotification(self,filename,atag,force); +end; + +procedure tfilechangenotifyer.removenotification(const filename: filenamety; + atag: integer = 0); +begin + if fchangethread <> nil then begin + fchangethread.removenotification(self,filename,atag); + end; +end; + +procedure tfilechangenotifyer.clear; +begin + removenotification(''); +end; + +initialization +{$ifdef UNIX} + dirinfosig:= sigrtmin + 10; + if dirinfosig > sigrtmax then begin + dirinfosig:= sigrtmax; + end; +{$endif unix} +finalization + freeandnil(fchangethread); +end. diff --git a/mseide-msegui/lib/common/sysutils/msefilemacros.pas b/mseide-msegui/lib/common/sysutils/msefilemacros.pas new file mode 100644 index 0000000..918d8a7 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msefilemacros.pas @@ -0,0 +1,158 @@ +{ MSEgui Copyright (c) 2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit msefilemacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msemacros; + +function filemacros(): macroinfoarty; + +implementation +uses + msefileutils,msetypes{msestrings}; + +var + ffilemacros: macroinfoarty; + +function filemacros(): macroinfoarty; +begin + result:= ffilemacros; +end; + +function file_mse(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= tomsefilepath(params[0]); + end; +end; + +function file_sys(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= tosysfilepath(params[0]); + end; +end; + +function file_path(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= filepath(params[0]); + end; +end; + +function file_file(const sender: tmacrolist; + const params: msestringarty): msestring; + //no trailing path delimiter +begin + result:= ''; + if params <> nil then begin + result:= filepath(params[0],fk_file,true); + end; +end; + +function file_dir(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= filepath(params[0],fk_dir,true); + end; +end; + +function file_name(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= filename(params[0]); + end; +end; + +function file_namebase(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= filenamebase(params[0]); + end; +end; + +function file_ext(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= fileext(params[0]); + end; +end; + +function file_noname(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= filedir(params[0]); + end; +end; + +function file_noext(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= removefileext(params[0]); + end; +end; + +const + filemacroconst: array[0..9] of macroinfoty = ( + (name: 'FILE_MSE'; value: ''; handler: macrohandlerty(@file_mse); + expandlevel: 0), //convert to mse format + (name: 'FILE_SYS'; value: ''; handler: macrohandlerty(@file_sys); + expandlevel: 0), //convert to sys format + (name: 'FILE_PATH'; value: ''; handler: macrohandlerty(@file_path); + expandlevel: 0), //absolute path + (name: 'FILE_FILE'; value: ''; handler: macrohandlerty(@file_FILE); + expandlevel: 0), //no trailing path delimiter + (name: 'FILE_DIR'; value: ''; handler: macrohandlerty(@file_dir); + expandlevel: 0), //trailing path delimiter + (name: 'FILE_NAME'; value: ''; handler: macrohandlerty(@file_name); + expandlevel: 0), //no directory part + (name: 'FILE_NAMEBASE'; value: ''; handler: macrohandlerty(@file_namebase); + expandlevel: 0), //no directory and name extension part + (name: 'FILE_EXT'; value: ''; handler: macrohandlerty(@file_ext); + expandlevel: 0), //file name extension + (name: 'FILE_NONAME'; value: ''; handler: macrohandlerty(@file_noname); + expandlevel: 0), //directory part only + (name: 'FILE_NOEXT'; value: ''; handler: macrohandlerty(@file_noext); + expandlevel: 0) //no file name extension + ); + +procedure initfilemacros(); +var + int1: integer; +begin + setlength(ffilemacros,length(filemacroconst)); + for int1:= 0 to high(filemacroconst) do begin + ffilemacros[int1]:= filemacroconst[int1]; + end; +end; + +initialization + initfilemacros(); +end. diff --git a/mseide-msegui/lib/common/sysutils/mseguiprocess.pas b/mseide-msegui/lib/common/sysutils/mseguiprocess.pas new file mode 100644 index 0000000..226c355 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseguiprocess.pas @@ -0,0 +1,114 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseguiprocess; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseprocess,msetypes{msestrings}; + +type + guiprocessoptionty = (prog_waitdialog, + prog_cancontinue); //continue button in wait dialog + guiprocessoptionsty = set of guiprocessoptionty; + + tguiprocess = class(tmseprocess) + private + fdialogcaption: msestring; + fdialoggaption: msestring; + fdialogtext: msestring; + foptionsgui: guiprocessoptionsty; + function getcancontinue: boolean; + procedure setcancontinue(const avalue: boolean); + protected + procedure setactive(const avalue: boolean) override; + function getdialogcaption: msestring virtual; + function getdialogtext: msestring virtual; + procedure cancelev(const sender: tobject); + procedure continueev(const sender: tobject); + procedure doprocfinished() override; + public + property cancontinue: boolean read getcancontinue write setcancontinue; + published + property dialogcaption: msestring read fdialogcaption write fdialoggaption; + property dialogtext: msestring read fdialogtext write fdialogtext; + property optionsgui: guiprocessoptionsty read foptionsgui + write foptionsgui default []; + end; + +implementation +uses + msegui; + +{ tguiprocess } + +function tguiprocess.getcancontinue: boolean; +begin + result:= prog_cancontinue in foptionsgui; +end; + +procedure tguiprocess.setcancontinue(const avalue: boolean); +begin + if avalue then begin + optionsgui:= optionsgui + [prog_cancontinue]; + end + else begin + optionsgui:= optionsgui - [prog_cancontinue]; + end; +end; + +procedure tguiprocess.setactive(const avalue: boolean); +begin + inherited; + if (prog_waitdialog in foptionsgui) and avalue and active then begin + if prog_cancontinue in foptionsgui then begin + application.waitdialog(nil,getdialogtext(),getdialogcaption(),@cancelev,nil, + nil,@continueev); + end + else begin + application.waitdialog(nil,getdialogtext(),getdialogcaption(),@cancelev); + end; + end; +end; + +function tguiprocess.getdialogcaption: msestring; +begin + result:= fdialogcaption; + if result = '' then begin + result:= 'Process' + end; +end; + +function tguiprocess.getdialogtext: msestring; +begin + result:= fdialogtext; + if result = '' then begin + result:= 'Running...' + end; +end; + +procedure tguiprocess.cancelev(const sender: tobject); +begin + kill(); +end; + +procedure tguiprocess.continueev(const sender: tobject); +begin + active:= false; +end; + +procedure tguiprocess.doprocfinished(); +begin + inherited; + if (prog_waitdialog in foptionsgui) and application.waitstarted() then begin + application.terminatewait(); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/mseinputcontroller.pas b/mseide-msegui/lib/common/sysutils/mseinputcontroller.pas new file mode 100644 index 0000000..8ee873d --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseinputcontroller.pas @@ -0,0 +1,242 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseinputcontroller; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface + +uses + Classes,msethread,msetypes,mseclasses; + +type + + tinputcontroller = class; + + fileinputeventty = procedure (sender: tinputcontroller; + const activefiles: integerarty) of object; + + tinputcontroller = class(tmsethread) + private + factive: boolean; + finputfiles: integerarty; + ainputfiles: integerarty; + foninputavailable: fileinputeventty; + fchanged: boolean; + readyfiles: integerarty; + procedure inputavailable; + procedure getfiles; + procedure setactive(const Value: boolean); + procedure psetinputfiles(const Value: integerarty); + protected + function execute(thread: tmsethread): integer; override; + public + constructor create; + procedure setinputfiles(files: array of integer); + property active: boolean read factive write setactive; + property inputfiles: integerarty read finputfiles write psetinputfiles; + property oninputavailable: fileinputeventty read foninputavailable + write foninputavailable; + end; + + tinputcontrollercomp = class(tmsecomponent) + private + fcontroller: tinputcontroller; + function getinputfiles: integerarty; + function getoninputavailable: fileinputeventty; + procedure psetinputfiles(const Value: integerarty); + procedure setactive(const Value: boolean); + procedure setoninputavailable(const Value: fileinputeventty); + function getactive: boolean; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure setinputfiles(files: array of integer); + published + property active: boolean read getactive write setactive default false; + property inputfiles: integerarty read getinputfiles write psetinputfiles; + property oninputavailable: fileinputeventty read getoninputavailable + write setoninputavailable; + end; + + +implementation +uses + mseapplication, +{$ifdef UNIX} + mselibc; +{$else} + msesysutils; + +type + tfdset = integer; //dummys + tfdsetpoty = ^tfdset; +const + fd_setsize = 1; + +procedure fd_zero(fdset: tfdset); +begin +end; +procedure fd_set(index: integer;fdset: tfdset); +begin +end; +function fd_isset(index: integer; fdset: tfdset): boolean; +begin + result:= false; +end; +function select(size: integer; fdset: tfdsetpoty; po1,po2,po3: pointer): integer; +begin + result:= 0; +end; +{$endif} + +{ tinputcontroller } + +function tinputcontroller.execute(thread: tmsethread): integer; +var + fdset: tfdset; + timeout: timeval; + int1,int2: integer; +begin + fd_zero(fdset); + repeat + if factive then begin + timeout.tv_sec:= 0; + timeout.tv_usec:= 100000; + if fchanged then begin + application.synchronize(getfiles); + fd_zero(fdset); + end; + for int1:= 0 to length(ainputfiles) - 1 do begin + fd_set(ainputfiles[int1],fdset); + end; + int1:= select(fd_setsize,@fdset,nil,nil,@timeout); + if not fchanged then begin + if (int1 > 0) then begin + int2:= 0; + setlength(readyfiles,length(ainputfiles)); + for int1:= 0 to length(ainputfiles) - 1 do begin + if fd_isset(ainputfiles[int1],fdset) then begin + readyfiles[int2]:= ainputfiles[int1]; + inc(int2); + end; + end; + setlength(readyfiles,int2); + application.synchronize(inputavailable); + end; + end; + end; + if not factive then begin + sys_threadschedyield(0); + end; + until terminated; + result:= 0; +end; + +procedure tinputcontroller.getfiles; +begin + ainputfiles:= finputfiles; + fchanged:= false; +end; + +procedure tinputcontroller.setactive(const Value: boolean); +begin + factive := Value; +end; + +procedure tinputcontroller.psetinputfiles(const Value: integerarty); +var + bo1: boolean; +begin + bo1:= factive; + factive:= false; + finputfiles:= Value; + fchanged:= true; + factive:= bo1; +end; + +procedure tinputcontroller.inputavailable; +begin + if factive and not fchanged and assigned(foninputavailable) then begin + foninputavailable(self,readyfiles); + end; +end; + +procedure tinputcontroller.setinputfiles(files: array of integer); +var + intar: integerarty; + int1: integer; +begin + setlength(intar,length(files)); + for int1:= 0 to length(intar)-1 do begin + intar[int1]:= files[int1]; + end; + psetinputfiles(intar); +end; + +constructor tinputcontroller.create; +begin + inherited create(execute); +end; + +{ tinputcontrollercomp } + +constructor tinputcontrollercomp.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tinputcontroller.create; +end; + +destructor tinputcontrollercomp.destroy; +begin + fcontroller.free; + inherited; +end; + +function tinputcontrollercomp.getactive: boolean; +begin + result:= fcontroller.active; +end; + +function tinputcontrollercomp.getinputfiles: integerarty; +begin + result:= fcontroller.inputfiles; +end; + +function tinputcontrollercomp.getoninputavailable: fileinputeventty; +begin + result:= fcontroller.oninputavailable; +end; + +procedure tinputcontrollercomp.psetinputfiles(const Value: integerarty); +begin + fcontroller.inputfiles:= value; +end; + +procedure tinputcontrollercomp.setactive(const Value: boolean); +begin + fcontroller.active:= Value; +end; + +procedure tinputcontrollercomp.setinputfiles(files: array of integer); +begin + fcontroller.setinputfiles(files); +end; + +procedure tinputcontrollercomp.setoninputavailable( + const Value: fileinputeventty); +begin + fcontroller.oninputavailable:= value; +end; + +end. + diff --git a/mseide-msegui/lib/common/sysutils/msemacmacros.pas b/mseide-msegui/lib/common/sysutils/msemacmacros.pas new file mode 100644 index 0000000..27b04c8 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msemacmacros.pas @@ -0,0 +1,73 @@ +{ MSEgui Copyright (c) 2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit msemacmacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msemacros; + +function macmacros(): macroinfoarty; + +implementation +uses + msetypes{msestrings},msesysintf; + +var + fmacmacros: macroinfoarty; + +function macmacros(): macroinfoarty; +begin + result:= fmacmacros; +end; + +function mac_ifdef(const sender: tmacrolist; + const params: msestringarty): msestring; + //name,[ifndef value[,ifdef value]] +var + po1: pmacroinfoty; +begin + result:= ''; + if params <> nil then begin + if sender.find(params[0],po1) then begin + if high(params) > 1 then begin + result:= params[2]; + end + else begin + result:= po1^.value; + end; + end + else begin + if high(params) > 0 then begin + result:= params[1]; + end; + end; + end; +end; + +const + macmacroconst: array[0..0] of macroinfoty = ( + (name: 'MAC_IFDEF'; value: ''; handler: macrohandlerty(@mac_ifdef); + expandlevel: 0) + ); + +procedure initmacmacros(); +var + int1: integer; +begin + setlength(fmacmacros,length(macmacroconst)); + for int1:= 0 to high(macmacroconst) do begin + fmacmacros[int1]:= macmacroconst[int1]; + end; +end; + +initialization + initmacmacros(); +end. diff --git a/mseide-msegui/lib/common/sysutils/msemime.pas b/mseide-msegui/lib/common/sysutils/msemime.pas new file mode 100644 index 0000000..d19dcfd --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msemime.pas @@ -0,0 +1,246 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msemime; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegui,msedrag,msestrings,msetypes,msegraphutils,mseglob,mseguiglob,mseclasses, + msedragglob; + +type + + tmimedragobject = class; + + imimesource = interface(iobjectlink) + procedure convertmimedata(const sender: tmimedragobject; + var adata: string; const atypeindex: integer); + procedure convertmimetext(const sender: tmimedragobject; + var adata: msestring; const atypeindex: integer); + end; + + tmimedragobject = class(tdragobject,iobjectlink) + private + fdata: string; + ftext: msestring; + fobjectlinker: tobjectlinker; + procedure setformatindex(const avalue: integer); + protected + fformats: msestringarty; + fformatistext: booleanarty; + fformatindex: integer; + fwantedformatindex: integer; + fintf: imimesource; + function getdata: string; virtual; + function gettext: msestring; virtual; + procedure setdata(const avalue: string); virtual; + procedure settext(const avalue: msestring); virtual; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const asender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); virtual; + constructor createwrite(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); + destructor destroy; override; + function checkformat(const awanted: array of msestring): boolean; + property formats: msestringarty read fformats; //do not modify + property formatistext: booleanarty read fformatistext; //do not modify + property formatindex: integer read fformatindex + write setformatindex default -1; + //-1 -> none selected + property wantedformatindex: integer read fwantedformatindex + write fwantedformatindex default -1; + //-1 -> none selected + property data: string read getdata write setdata; + property text: msestring read gettext write settext; + function convertmimedata(const atypeindex: integer): string; virtual; + function convertmimetext(const atypeindex: integer): msestring; virtual; + end; + +implementation +uses + msearrayutils; + +{ tmimedragobject } + +constructor tmimedragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); +begin + fobjectlinker:= tobjectlinker.create(iobjectlink(self),nil); + fformats:= opentodynarraym(aformats); + fformatistext:= opentodynarraybo(aformatistext); + setlength(fformatistext,length(fformats)); + factions:= aactions; + fformatindex:= -1; + fwantedformatindex:= -1; + fintf:= aintf; + if fintf <> nil then begin + fobjectlinker.link(iobjectlink(self),fintf); + end; + inherited create(asender,instance,apickpos,aactions); +end; + +constructor tmimedragobject.createwrite(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); +begin + include(fstate,dos_write); + create(asender,instance,apickpos,aformats,aformatistext,aactions,aintf); +end; + +destructor tmimedragobject.destroy; +begin + fobjectlinker.free; + inherited; +end; + +procedure tmimedragobject.setformatindex(const avalue: integer); +begin + if avalue < 0 then begin + fformatindex:= -1; + end + else begin + checkarrayindex(fformats,avalue); + fformatindex:= avalue; + end; +end; + +function tmimedragobject.checkformat( + const awanted: array of msestring): boolean; +var + int1,int2: integer; +begin + result:= false; + fformatindex:= -1; + fwantedformatindex:= -1; + for int1:= 0 to high(awanted) do begin + for int2:= 0 to high(fformats) do begin + if awanted[int1] = fformats[int2] then begin + result:= true; + fformatindex:= int2; + fwantedformatindex:= int1; + exit; + end; + end; + end; +end; + +function tmimedragobject.getdata: string; +begin + if fformatindex >= 0 then begin + result:= convertmimedata(fformatindex); + end + else begin + if fdata = '' then begin + result:= ansistring(ftext); + end + else begin + result:= fdata; + end; + end; +end; + +function tmimedragobject.gettext: msestring; +begin + if fformatindex >= 0 then begin + result:= convertmimetext(fformatindex); + end + else begin + if ftext = '' then begin + result:= msestring(fdata); + end + else begin + result:= ftext; + end; + end; +end; + +procedure tmimedragobject.setdata(const avalue: string); +begin + ftext:= ''; + fdata:= avalue; +end; + +procedure tmimedragobject.settext(const avalue: msestring); +begin + fdata:= ''; + ftext:= avalue; +end; + +function tmimedragobject.convertmimedata(const atypeindex: integer): string; +begin + if fdata = '' then begin + result:= ansistring(ftext); + end + else begin + result:= fdata; + end; + if fintf <> nil then begin + fintf.convertmimedata(self,result,atypeindex); + end; +end; + +function tmimedragobject.convertmimetext(const atypeindex: integer): msestring; +begin + if ftext = '' then begin + result:= msestring(fdata); + end + else begin + result:= ftext; + end; + if fintf <> nil then begin + fintf.convertmimetext(self,result,atypeindex); + end; +end; + +procedure tmimedragobject.link(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + fobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tmimedragobject.unlink(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil); +begin + fobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tmimedragobject.objevent(const asender: iobjectlink; + const event: objecteventty); +begin + if (asender = fintf) and (event = oe_destroyed) then begin + destroy; + end; +end; + +function tmimedragobject.getinstance: tobject; +begin + result:= self; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/mseprocess.pas b/mseide-msegui/lib/common/sysutils/mseprocess.pas new file mode 100644 index 0000000..3e911f5 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseprocess.pas @@ -0,0 +1,1044 @@ +{ MSEgui Copyright (c) 2010-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseprocess; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses,msepipestream,msestrings,msestatfile,msestat, + msesystypes,mseevent,msetypes,mseprocmonitor,mseapplication,msedatalist; +const + defaultpipewaitus = 0; +type + processstatety = (prs_listening,prs_waitcursor); + processstatesty = set of processstatety; + processoptionty = (pro_output,pro_erroroutput,pro_input,pro_errorouttoout, + pro_shell, //default on linux + pro_noshell, //default on windows, + pro_inactive,pro_nostdhandle, //windows only + pro_newconsole,pro_nowindow,pro_detached, //windows only + pro_allowsetforegroundwindow, //windows only + pro_group, //linux only + pro_sessionleader, //linux only + pro_settty, //linux only + pro_tty,pro_echo,pro_icanon, //linux only + pro_nowaitforpipeeof, + pro_nopipeterminate, //not used + pro_usepipewritehandles,pro_winpipewritehandles, + pro_waitcursor,pro_checkescape,pro_escapekill, + //terminate or kill process if esc pressed + pro_processmessages, + pro_ctrlc //for tterminal + ); + processoptionsty = set of processoptionty; +const + defaultprocessoptions = [pro_winpipewritehandles]; + //there is no other way on win32 to + //terminate read on a hanging process + defaultgetprocessoutputoptions = defaultprocessoptions + [pro_inactive]; + defaultgetprocessoutputoptionserrorouttoout = + defaultprocessoptions + [pro_inactive,pro_errorouttoout]; + defaultstartprocessoptions = defaultprocessoptions + [pro_inactive]; + +type + tcustommseprocess = class; + + tcustommseprocess = class(tactcomponent,istatfile,iprocmonitor) + private + finput: tpipewriterpers; + foutput: tpipereaderpers; + ferroroutput: tpipereaderpers; + ffilename: filenamety; + fparameter: msestring; + fstatfile: tstatfile; + fstatvarname: msestring; + factive: boolean; + fprochandle: prochandlety; + flastprochandle: prochandlety; + fonprocfinished: notifyeventty; + flistenid: ptruint; + fexitcode: integer; + fcommandline: msestring; + fcommandline1: msestring; + fworkingdirectory: filenamety; + fpipewaitus: integer; + fstatpriority: integer; + foncheckabort: updatebooleaneventty; + fparams: tmsestringdatalist; + fenvvars: tmsestringdatalist; + procedure setoutput(const avalue: tpipereaderpers); + procedure seterroroutput(const avalue: tpipereaderpers); + function getactive: boolean; + procedure setstatfile(const avalue: tstatfile); + procedure updatecommandline; + function getcommandline: msestring; + procedure setcommandline(const avalue: msestring); + procedure procend; + procedure setinput(const avalue: tpipewriterpers); + procedure setparams(const avalue: tmsestringdatalist); + procedure setenvvars(const avalue: tmsestringdatalist); + protected + foptions: processoptionsty; + fstate: processstatesty; + procedure setoptions(const avalue: processoptionsty) virtual; + procedure setactive(const avalue: boolean); override; + procedure loaded; override; + procedure listen; + procedure unlisten; + procedure finalizeexec; + procedure receiveevent(const event: tobjectevent); override; + procedure waitforpipeeof; + procedure doprocfinished virtual; + procedure postprocessdied; + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + //iprocmonitor + procedure processdied(const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function running: boolean; + procedure terminate; + procedure kill; + function waitforprocess: integer; overload; //returns exitcode + function waitforprocess(const atimeoutus: integer): boolean; overload; + //true if process finished + property commandline: msestring read getcommandline write setcommandline; + //overrides filename and parameter + property prochandle: prochandlety read fprochandle; + property lastprochandle: prochandlety read flastprochandle; + property exitcode: integer read fexitcode; + + property filename: filenamety read ffilename write ffilename; + property parameter: msestring read fparameter write fparameter; + property workingdirectory: filenamety read fworkingdirectory + write fworkingdirectory; + property params: tmsestringdatalist read fparams write setparams; + property envvars: tmsestringdatalist read fenvvars write setenvvars; + property active: boolean read getactive write setactive default false; + property options: processoptionsty read foptions write setoptions + default defaultprocessoptions; + property pipewaitus: integer read fpipewaitus write fpipewaitus + default defaultpipewaitus; + //0 -> infinite + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property input: tpipewriterpers read finput write setinput; + property output: tpipereaderpers read foutput write setoutput; + property erroroutput: tpipereaderpers read ferroroutput write seterroroutput; + property onprocfinished: notifyeventty read fonprocfinished + write fonprocfinished; + property oncheckabort: updatebooleaneventty + read foncheckabort write foncheckabort; + end; + + tmseprocess = class(tcustommseprocess) + published + property filename; + property parameter; + property workingdirectory; + property params; + property envvars; + property active; + property options; + property pipewaitus; + property statfile; + property statvarname; + property statpriority; + property input; + property output; + property erroroutput; + property onprocfinished; + property oncheckabort; + end; + +function getprocessoutput(const filename: msestring; + const aparams: msestringarty; + const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached + +function getprocessoutput(const acommandline: msestring; const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached +function getprocessoutput(const acommandline: msestring; const todata: string; + out fromdata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptionserrorouttoout; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached +function getprocessoutput(out prochandle: prochandlety; + const acommandline: msestring; const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached +function getprocessoutput(out prochandle: prochandlety; + const acommandline: msestring; const todata: string; + out fromdata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptionserrorouttoout; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached + +function startprocessandwait(const acommandline: msestring; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil): integer; + //returns program exitcode, -1 in case of error +implementation +uses + mseprocutils,msefileutils,sysutils,msesysintf,msebits,msesys, + msesysutils; +type + tstringprocess = class(tcustommseprocess) + private + ffromdata: string; + ffromcount: sizeint; + ferrordata: string; + ferrorcount: sizeint; + fmaxdatalen: sizeint; + fmaxdatareached: boolean; + procedure readdata(const sender: tpipereader; + var adata: string; var acount: sizeint); + procedure fromavail(const sender: tpipereader); + procedure erroravail(const sender: tpipereader); + public + constructor create(const amaxdatalen: sizeint = 0); reintroduce; + end; + +function getprocessoutput1(const prochandlepo: pprochandlety; + const acommandline: msestring; const aparams: msestringarty; + const todata: string; + out fromdata: string; out errordata: string; + const atimeout: integer; const aoptions: processoptionsty; + const acheckabort: updatebooleaneventty; + const amaxdatalen: integer): integer; + //returns program exitcode, -1 in case of error, + //-2 in case of maxdatalen reached +var + proc1: tstringprocess; + i1: int32; +begin + result:= -1; + proc1:= tstringprocess.create(amaxdatalen); + try + with proc1 do begin + if aparams <> nil then begin + filename:= acommandline; + params.count:= length(aparams); + for i1:= 0 to high(aparams) do begin + params[i1]:= aparams[i1]; + end; + end + else begin + commandline:= acommandline; + end; + options:= aoptions + [pro_output,pro_erroroutput,pro_input]; + oncheckabort:= acheckabort; + active:= true; + if prochandlepo <> nil then begin + application.lock; + prochandlepo^:= prochandle; + application.unlock; + end; + if todata <> '' then begin + try + input.pipewriter.write(todata); + except + end; + input.pipewriter.close; + end; + if atimeout < 0 then begin + result:= waitforprocess; + end + else begin + if waitforprocess(atimeout) then begin + result:= exitcode; + end; + end; + if fmaxdatareached then begin + result:= -2; + end; + if result <> -1 then begin + setlength(proc1.ffromdata,proc1.ffromcount); + fromdata:= proc1.ffromdata; + setlength(proc1.ferrordata,proc1.ferrorcount); + errordata:= proc1.ferrordata; + end; + end; + finally + application.lock; + if prochandlepo <> nil then begin + prochandlepo^:= invalidprochandle; + end; + proc1.release; +// proc1.free; //calls application.unlockall + application.unlock; + end; +end; + +function startprocessandwait(const acommandline: msestring; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultstartprocessoptions; + const acheckabort: updatebooleaneventty = nil): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached +var + proc1: tcustommseprocess; +begin + result:= -1; + proc1:= tcustommseprocess.create(nil); + try + with proc1 do begin + commandline:= acommandline; + options:= aoptions - [pro_output,pro_erroroutput,pro_input]; + oncheckabort:= acheckabort; + active:= true; + if atimeoutus < 0 then begin + result:= waitforprocess; + end + else begin + if waitforprocess(atimeoutus) then begin + result:= exitcode; + end; + end; + end; + finally + proc1.free; + end; +end; + +function getprocessoutput(const filename: msestring; + const aparams: msestringarty; + const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached +begin + result:= getprocessoutput1(nil,filename,aparams,todata,fromdata,errordata, + atimeoutus,aoptions,acheckabort,amaxdatalen); +end; + +function getprocessoutput(const acommandline: msestring; const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; +begin + result:= getprocessoutput1(nil,acommandline,nil,todata,fromdata,errordata, + atimeoutus,aoptions,acheckabort,amaxdatalen); +end; + +function getprocessoutput(const acommandline: msestring; const todata: string; + out fromdata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptionserrorouttoout; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; +var + str1: string; +begin + result:= getprocessoutput1(nil,acommandline,nil,todata,fromdata,str1, + atimeoutus,aoptions,acheckabort,amaxdatalen); +end; + +function getprocessoutput(out prochandle: prochandlety; + const acommandline: msestring; const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; +begin + result:= getprocessoutput1(@prochandle,acommandline,nil,todata,fromdata,errordata, + atimeoutus,aoptions,acheckabort,amaxdatalen); +end; + +function getprocessoutput(out prochandle: prochandlety; + const acommandline: msestring; const todata: string; + out fromdata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptionserrorouttoout; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; +var + str1: string; +begin + result:= getprocessoutput1(@prochandle,acommandline,nil,todata,fromdata,str1, + atimeoutus,aoptions,acheckabort,amaxdatalen); +end; + +{ tcustommseprocess } + +constructor tcustommseprocess.create(aowner: tcomponent); +begin + foptions:= defaultprocessoptions; + fprochandle:= invalidprochandle; + finput:= tpipewriterpers.create(self); + foutput:= tpipereaderpers.create(self); + ferroroutput:= tpipereaderpers.create(self); + fpipewaitus:= defaultpipewaitus; + fparams:= tmsestringdatalist.create; + fenvvars:= tmsestringdatalist.create; + inherited; +end; + +destructor tcustommseprocess.destroy; +begin + finalizeexec(); + finput.free(); + foutput.free(); //calls application.unlockall + ferroroutput.free(); //calls application.unlockall + fparams.free(); + fenvvars.free(); + inherited; +// finput.free; +// foutput.free; +// ferroroutput.free; +end; + +procedure tcustommseprocess.setoutput(const avalue: tpipereaderpers); +begin + foutput.assign(avalue); +end; + +procedure tcustommseprocess.seterroroutput(const avalue: tpipereaderpers); +begin + ferroroutput.assign(avalue); +end; + +function tcustommseprocess.getactive: boolean; +begin + if componentstate * [csloading,csdesigning] <> [] then begin + result:= factive; + end + else begin + result:= fprochandle <> invalidprochandle; + end; +end; + +procedure tcustommseprocess.doprocfinished; +begin + if canevent(tmethod(fonprocfinished)) then begin + fonprocfinished(self); + end; + { + if not (pro_nopipeterminate in foptions) then begin + foutput.pipereader.terminate; + ferroroutput.pipereader.terminate; + end; + } +end; + +procedure tcustommseprocess.procend; +begin + fprochandle:= invalidprochandle; + foutput.pipereader.writehandle:= invalidfilehandle; + ferroroutput.pipereader.writehandle:= invalidfilehandle; + waitforpipeeof; + if prs_waitcursor in fstate then begin + exclude(fstate,prs_waitcursor); + application.endwait; + end; + finalizeexec(); + doprocfinished; +end; + +procedure tcustommseprocess.postprocessdied; +begin + exclude(fstate,prs_listening); + application.postevent(tchildprocevent.create(ievent(self),fprochandle, + fexitcode,pointer(flistenid))); + fprochandle:= invalidprochandle; +end; + +procedure tcustommseprocess.setactive(const avalue: boolean); +var + outp: tpipereader; + erroroutp: tpipereader; + inp: tpipewriter; + sessionleader: boolean; + group: integer; + opt1: execoptionsty; +// str1: ansistring; +// mstr1: msestring; +begin + sessionleader:= false; + group:= -1; + if componentstate * [csloading,csdesigning] <> [] then begin + factive:= avalue; + end + else begin + if avalue <> active then begin + outp:= nil; + erroroutp:= nil; + inp:= nil; + finalizeexec(); + if avalue then begin + application.lock; + try + updatecommandline; + if pro_output in foptions then begin + outp:= foutput.pipereader; + end; + if pro_erroroutput in foptions then begin + erroroutp:= ferroroutput.pipereader; + end + else begin + if pro_errorouttoout in foptions then begin + erroroutp:= foutput.pipereader; + end; + end; + if pro_input in foptions then begin + inp:= finput.pipewriter; + end; + if pro_group in foptions then begin + group:= 0; + end; + if pro_sessionleader in foptions then begin + sessionleader:= true; + group:= -1; + end; + opt1:= []; + if sessionleader then begin + include(opt1,exo_sessionleader); + end; + if pro_settty in foptions then begin + include(opt1,exo_settty); + end; + if pro_shell in foptions then begin + include(opt1,exo_shell); + end; + if pro_noshell in foptions then begin + include(opt1,exo_noshell); + end; + if pro_inactive in foptions then begin + include(opt1,exo_inactive); + end; + if pro_tty in foptions then begin + include(opt1,exo_tty); + end; + if pro_echo in foptions then begin + include(opt1,exo_echo); + end; + if pro_icanon in foptions then begin + include(opt1,exo_icanon); + end; + if pro_nostdhandle in foptions then begin + include(opt1,exo_nostdhandle); + end; + if pro_newconsole in foptions then begin + include(opt1,exo_newconsole); + end; + if pro_nowindow in foptions then begin + include(opt1,exo_nowindow); + end; + if pro_detached in foptions then begin + include(opt1,exo_detached); + end; + if pro_allowsetforegroundwindow in foptions then begin + include(opt1,exo_allowsetforegroundwindow); + end; + if pro_usepipewritehandles in foptions then begin + include(opt1,exo_usepipewritehandles); + end; + if pro_winpipewritehandles in foptions then begin + include(opt1,exo_winpipewritehandles); + end; + { + if fworkingdirectory <> '' then begin + mstr1:= filepath(fworkingdirectory); + sys_tosysfilepath(mstr1); + str1:= mstr1; + end; + } + try + fprochandle:= execmse2(syscommandline(fcommandline1), + inp,outp,erroroutp,group,opt1,fworkingdirectory, + fparams.asarray,fenvvars.asarray); +// fprochandle:= execmse2(syscommandline(fcommandline1), +// inp,outp,erroroutp,group,opt1,str1); + except + fprochandle:= invalidprochandle; + flastprochandle:= invalidprochandle; + finalizeexec(); + fexitcode:= -1; + raise; + end; + flastprochandle:= fprochandle; + if fprochandle = invalidprochandle then begin + finalizeexec; + end + else begin + if pro_waitcursor in foptions then begin + include(fstate,prs_waitcursor); + application.beginwait; + end; + listen; + end; + finally + application.unlock; + end; + end; + end; + end; +end; + +procedure tcustommseprocess.receiveevent(const event: tobjectevent); +begin + if (event.kind = ek_childproc) then begin + with tchildprocevent(event) do begin + if data = pointer(flistenid) then begin + procend; + end; + end; + end + else begin + inherited; + end; +end; + +function tcustommseprocess.waitforprocess(const atimeoutus: integer): boolean; + //true if process finished +var + int1: integer; + bo1: boolean; + ts1: longword; + procerr: processexiterrorty; + i2: int32; +begin + result:= false; + procerr:= pee_ok; + bo1:= prs_listening in fstate; + unlisten; + if bo1 then begin + int1:= application.unlockall; + if (foptions*[pro_checkescape,pro_processmessages] <> []) or + assigned(foncheckabort) then begin + ts1:= timestep(atimeoutus); + i2:= 100000; + if (atimeoutus >= 0) and (atimeoutus < i2) then begin + i2:= atimeoutus; + end; + repeat + if pro_processmessages in foptions then begin + application.relockall(int1); + application.processmessages; + int1:= application.unlockall; + end; + procerr:= mseprocutils.getprocessexitcode(fprochandle,fexitcode,i2); + bo1:= (procerr <> pee_timeout) or ((atimeoutus >= 0) and timeout(ts1)); + if not bo1 then begin + if (pro_checkescape in foptions) then begin + bo1:= application.waitescaped; + end; + if assigned(foncheckabort) then begin + foncheckabort(self,bo1); + end; + end; + until bo1; + result:= procerr in [pee_ok,pee_signaled]; + if not result then begin + if pro_escapekill in foptions then begin + killprocess(fprochandle); + end + else begin + terminateprocess(fprochandle); + end; + procend(); + end; + end + else begin + procerr:= mseprocutils.getprocessexitcode(fprochandle,fexitcode,atimeoutus); + result:= procerr in [pee_ok,pee_signaled]; + end; + application.relockall(int1); + end + else begin + result:= true; + end; + if result or (procerr = pee_error) then begin + procend(); + end; +end; + +function tcustommseprocess.waitforprocess: integer; +begin + result:= -1; + if waitforprocess(-1) then begin + result:= fexitcode; + end; +end; + +procedure tcustommseprocess.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +function tcustommseprocess.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustommseprocess.dostatread(const reader: tstatreader); +begin + ffilename:= reader.readmsestring('file',ffilename); + fparameter:= reader.readmsestring('param',fparameter); +end; + +procedure tcustommseprocess.dostatwrite(const writer: tstatwriter); +begin + writer.writemsestring('file',ffilename); + writer.writemsestring('param',fparameter); +end; + +procedure tcustommseprocess.statreading; +begin + //dummy +end; + +procedure tcustommseprocess.statread; +begin + //dummy +end; + +procedure tcustommseprocess.loaded; +begin + inherited; + active:= factive; +end; + +procedure tcustommseprocess.listen; +begin + application.lock; + if not (prs_listening in fstate) and + (fprochandle <> invalidprochandle) then begin + pro_listentoprocess(fprochandle,iprocmonitor(self),pointer(flistenid)); + include(fstate,prs_listening); + end; + application.unlock; +end; + +procedure tcustommseprocess.unlisten; +begin + application.lock; + try + inc(flistenid); + if prs_listening in fstate then begin + pro_unlistentoprocess(fprochandle,iprocmonitor(self)); + end; + exclude(fstate,prs_listening); + finally + application.unlock; + end; +end; + +procedure tcustommseprocess.finalizeexec; +begin + finput.pipewriter.close(); + foutput.pipereader.terminateandwait(); + ferroroutput.pipereader.terminateandwait(); + application.lock; + unlisten; + if fprochandle <> invalidprochandle then begin + pro_killzombie(fprochandle); + fprochandle:= invalidprochandle; + end; + application.unlock; + foutput.pipereader.close(); + ferroroutput.pipereader.close(); +end; + +procedure tcustommseprocess.waitforpipeeof; +var + int1,int2,int3: integer; + lwo1: longword; +begin + if not (pro_nowaitforpipeeof in foptions) then begin + int1:= application.unlockall; + int2:= foutput.pipereader.overloadsleepus; + int3:= ferroroutput.pipereader.overloadsleepus; + foutput.pipereader.overloadsleepus:= 0; + ferroroutput.pipereader.overloadsleepus:= 0; + lwo1:= timestep(fpipewaitus); +// sleepus(0); //shed_yield + sys_schedyield(); + while not (foutput.pipereader.eof and ferroroutput.pipereader.eof) and + ((fpipewaitus = 0) or not timeout(lwo1)) do begin + sleepus(1000); //wait for last chars + end; + application.relockall(int1); + if (foutput.pipereader.eof and ferroroutput.pipereader.eof) then begin + foutput.pipereader.waitfor; //process data + ferroroutput.pipereader.waitfor; //process data + end; + foutput.pipereader.overloadsleepus:= int2; + ferroroutput.pipereader.overloadsleepus:= int3; + end; +end; + +procedure tcustommseprocess.processdied(const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); +begin + if (prs_listening in fstate) and (adata = pointer(flistenid)) then begin + fexitcode:= aexecresult; + postprocessdied; + end +end; + +procedure tcustommseprocess.updatecommandline; +begin + if fcommandline <> '' then begin + fcommandline1:= fcommandline; + end + else begin + fcommandline1:= quotefilename(tosysfilepath(ffilename)); + if fparameter <> '' then begin + fcommandline1:= fcommandline1 + ' ' + fparameter; + end; + end; +end; + +function tcustommseprocess.getcommandline: msestring; +begin + updatecommandline; + result:= fcommandline1; +end; + +procedure tcustommseprocess.setcommandline(const avalue: msestring); +begin + fcommandline:= avalue; +end; + + +{ +function tcustommseprocess.waitforprocess: integer; +var + int1: integer; +begin + int1:= application.unlockall; + try + unlisten; + result:= fexitcode; + if running then begin + result:= mseprocutils.waitforprocess(fprochandle); + fexitcode:= result; + procend; + end; + finally + application.relockall(int1); + end; +end; + +function tcustommseprocess.waitforprocess(const atimeoutus: integer): boolean; + //true if process finished +var + int1: integer; +begin + int1:= application.unlockall; + try + unlisten; + if running then begin + result:= mseprocutils.getprocessexitcode(fprochandle,fexitcode,atimeoutus); + if result then begin + procend; + end + else begin + application.lock; + try + listen; + result:= mseprocutils.getprocessexitcode(fprochandle,fexitcode,0); + if result then begin + unlisten; + end; + finally + application.unlock; + end; + if result then begin + procend; + end; + end; + end + else begin + result:= true; + end; + finally + application.relockall(int1); + end; +end; +} + +function tcustommseprocess.running: boolean; +begin + result:= fprochandle <> invalidprochandle; +end; + +procedure tcustommseprocess.terminate; +begin +{$ifdef mswindows} + kill(); +{$else} + application.lock; + try + if running then begin + syserror(sys_terminateprocess(fprochandle)); + end; + finally + application.unlock; + end; +{$endif} +end; + +procedure tcustommseprocess.kill; +begin + application.lock; + try + if running then begin + finput.pipewriter.close; + syserror(sys_killprocess(fprochandle)); + foutput.pipereader.terminate; + ferroroutput.pipereader.terminate; +// syserror(sys_killprocess(fprochandle)); + end; + finally + application.unlock; + end; +end; + +procedure tcustommseprocess.setoptions(const avalue: processoptionsty); +{$ifndef FPC} +const + mask1: processoptionsty = [pro_erroroutput,pro_errorouttoout]; + mask2: processoptionsty = [pro_shell,pro_noshell]; + mask3: processoptionsty = [pro_sessionleader,pro_group]; +{$endif} +begin + foptions:= processoptionsty( + {$ifdef FPC} + setsinglebit(longword(avalue), + longword(foptions), + [longword([pro_erroroutput,pro_errorouttoout]), + longword([pro_shell,pro_noshell]), + longword([pro_sessionleader,pro_group])])); + {$else} + setsinglebitar32(longword(avalue), + longword(foptions), + [longword(mask1),longword(mask2),longword(mask3)])); + {$endif} + exclude(foptions,pro_nopipeterminate); + if foptions * [pro_nowaitforpipeeof{,pro_nopipeterminate}] = [] then begin + exclude(foptions,pro_usepipewritehandles); + end; +end; + +function tcustommseprocess.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tcustommseprocess.setinput(const avalue: tpipewriterpers); +begin + finput.assign(avalue); +end; + +procedure tcustommseprocess.setparams(const avalue: tmsestringdatalist); +begin + fparams.assign(avalue); +end; + +procedure tcustommseprocess.setenvvars(const avalue: tmsestringdatalist); +begin + fenvvars.assign(avalue); +end; + +{ tstringprocess } + +constructor tstringprocess.create(const amaxdatalen: sizeint = 0); +begin + fmaxdatalen:= amaxdatalen; + inherited create(nil); + options:= options + [pro_output,pro_erroroutput,pro_input]; + output.pipereader.oninputavailable:= {$ifdef FPC}@{$endif}fromavail; + erroroutput.pipereader.oninputavailable:= {$ifdef FPC}@{$endif}erroravail; +end; + +procedure tstringprocess.readdata(const sender: tpipereader; + var adata: string; var acount: sizeint); +begin + if sender.active then begin + if adata = '' then begin + adata:= sender.readbuffer; //try to get complete small results without + //buffer oversize + acount:= length(adata); + end + else begin + sender.appenddatastring(adata,acount); + end; + if (fmaxdatalen > 0) and (acount > fmaxdatalen) then begin + kill(); + fmaxdatareached:= true; + end; + end; +end; + +procedure tstringprocess.fromavail(const sender: tpipereader); +begin + readdata(sender,ffromdata,ffromcount); +end; + +procedure tstringprocess.erroravail(const sender: tpipereader); +begin + readdata(sender,ferrordata,ferrorcount); +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/mseprocmonitorcomp.pas b/mseide-msegui/lib/common/sysutils/mseprocmonitorcomp.pas new file mode 100644 index 0000000..7d108c7 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseprocmonitorcomp.pas @@ -0,0 +1,145 @@ +{ MSEgui Copyright (c) 2008-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseprocmonitorcomp; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + msetypes,mseclasses,msesystypes,mseevent,mseprocmonitor,mseprocutils, + msestrings; + +type + proclisteninfoty = record + prochandle: prochandlety; + data: pointer; + end; + proclisteninfoarty = array of proclisteninfoty; + + childdiedeventty = procedure(const sender: tobject; + const prochandle: prochandlety; const execresult: integer; + const data: pointer) of object; + + tprocessmonitor = class(tmsecomponent,iprocmonitor) + private + fonchilddied: childdiedeventty; + finfos: proclisteninfoarty; + protected + procedure receiveevent(const event: tobjectevent); override; + procedure internalunlistentoprocess(const aprochandle: prochandlety; + const internal: boolean); + //iprocmonitor + procedure processdied(const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); + public + destructor destroy; override; + function listentoprocess(const aprochandle: prochandlety; + const adata: pointer = nil): boolean; + //does nothing and returns false if aprochandle = invalidprochandle + procedure unlistentoprocess(const aprochandle: prochandlety); + function exec(const acommandline: msestring; + const aoptions: execoptionsty = [] +// const inactive: boolean = true; + //windows only +// const nostdhandle: boolean = false + //windows only + ): prochandlety; + published + property onchilddied: childdiedeventty read fonchilddied write fonchilddied; + end; + +implementation +uses + msedatalist,mseapplication,msearrayutils; + +{ tprocessmonitor } + +destructor tprocessmonitor.destroy; +var + int1: integer; +begin + for int1:= high(finfos) downto 0 do begin + pro_unlistentoprocess(finfos[int1].prochandle,iprocmonitor(self)); + end; + inherited; +end; + +function tprocessmonitor.listentoprocess(const aprochandle: prochandlety; + const adata: pointer): boolean; +begin + result:= aprochandle <> invalidprochandle; + if result then begin + setlength(finfos,high(finfos)+2); + with finfos[high(finfos)] do begin + prochandle:= aprochandle; + data:= adata; + end; + pro_listentoprocess(aprochandle,iprocmonitor(self),adata); + end; +end; + +procedure tprocessmonitor.internalunlistentoprocess( + const aprochandle: prochandlety; const internal: boolean); +var + int1: integer; +begin + for int1:= high(finfos) downto 0 do begin + with finfos[int1] do begin + if prochandle = aprochandle then begin + if not internal then begin + pro_unlistentoprocess(aprochandle,iprocmonitor(self)); + end; + deleteitem(finfos,typeinfo(proclisteninfoarty),int1); + end; + end; + end; +end; + +procedure tprocessmonitor.processdied(const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); +begin + application.postevent(tchildprocevent.create(ievent(self),aprochandle, + aexecresult,adata)); +end; + +procedure tprocessmonitor.receiveevent(const event: tobjectevent); +begin + if (event.kind = ek_childproc) then begin + with tchildprocevent(event) do begin + if canevent(tmethod(fonchilddied)) then begin + fonchilddied(self,prochandle,execresult,data); + end; + internalunlistentoprocess(prochandle,true); + end; + end + else begin + inherited; + end; +end; + +procedure tprocessmonitor.unlistentoprocess(const aprochandle: prochandlety); +begin + internalunlistentoprocess(aprochandle, false); +end; + +function tprocessmonitor.exec(const acommandline: msestring; + const aoptions: execoptionsty = [] +// const inactive: boolean = true; +// const nostdhandle: boolean = false + ): prochandlety; +begin + application.lock; + try + result:= execmse4(acommandline,aoptions{inactive,nostdhandle}); + listentoprocess(result); + finally + application.unlock; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/mseprocutils.pas b/mseide-msegui/lib/common/sysutils/mseprocutils.pas new file mode 100644 index 0000000..1a8c5c0 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseprocutils.pas @@ -0,0 +1,1510 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseprocutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} +{$if fpc_fullversion >= 30000} + {$define mse_fpc_3} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + {$ifdef mswindows}windows{$else}mselibc{$endif}, + msetypes,msestream,msepipestream,sysutils,msesysutils,msesystypes,msesys, + msestrings; + +type + pipedescriptorty = record + {$ifdef mswindows} + readdes: ptrint; + writedes: ptrint; + {$else} + readdes: integer; + writedes: integer; + {$endif} + end; + execoptionty = (exo_shell, //default on Linux + exo_noshell, //default on Windows + exo_inactive, //windows only + exo_nostdhandle, //windows only + exo_newconsole, //windows only + exo_nowindow, //windows only + exo_detached, //windows only + exo_allowsetforegroundwindow, //windows only + exo_sessionleader, //linux only + exo_settty, //linux only + exo_tty,exo_echo,exo_icanon, //linux only + exo_usepipewritehandles,exo_winpipewritehandles + ); + execoptionsty = set of execoptionty; +const + pipewritehandlemask = [exo_usepipewritehandles + {$ifdef mswindows},exo_winpipewritehandles{$endif}]; +type + processexiterrorty = (pee_ok,pee_signaled,pee_timeout,pee_error); + +function getprocessexitcode(prochandle: prochandlety; out exitcode: integer; + const timeoutus: integer = 0): processexiterrorty; + //<0 -> no timeout, closes handle + //exicode = -signum - 256 by pee_signaled (unix only) + +function waitforprocess(prochandle: prochandlety): integer; + +function execmse(const commandline: msestring; //sys format + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): boolean; +//starts program, true if OK + +function execmse4(const commandline: msestring; //sys format + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; +//starts program, returns processhandle, execerror on error +//don't forget closehandle on windows! + +function execmse1(const commandline: msestring; //sys format + topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; +//starts program, returns processhandle, execerror on error +//don't forget closehandle on windows! +//creates pipes + +function execmse2(const commandline: msestring; //sys format + topipe: tpipewriter = nil; + frompipe: tpipereader = nil; + errorpipe: tpipereader = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; +//starts program, returns processhandle, execerror on error +//don't forget closehandle on windows! +//creates pipes + +function execmse3(const commandline: msestring; //sys format + topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; +//starts program, returns processhandle, execerror on error +//don't forget closehandle on windows! +//uses existing file handles + +function execwaitmse(const commandline: msestring; //sys format + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): integer; overload; +//runs programm, waits for program termination, returns program exitcode +//inactive true -> no console window (win32 only) + +procedure killprocess(handle: prochandlety); +procedure killprocesstree(handle: prochandlety); +function terminateprocess(handle: prochandlety): integer; + //sendet sigterm, bringt exitresult, -1 on error +procedure killprocessid(id: procidty); +procedure killprocesstreeid(id: procidty); + +function getpid: procidty; + +function getprocesstree: procitemarty; +function getprocesschildren(const pid: procidty): procidarty; +function getallprocesschildren(const pid: procidty): procidarty; +{moved to msegui +function activateprocesswindow(const procid: integer; + const araise: boolean = true): boolean; + //true if ok +} +function pipe(out desc: pipedescriptorty; write: boolean): boolean; + //true if ok + + {$ifdef UNIX} +function getpseudoterminal(out name: string): integer; + +type + procinfoty = record + pid: integer; + comm: string; + state: char; + ppid: integer; + pgrp: integer; + session: integer; + tty_nr: integer; + tpgid: integer; + flags: longword; + minflt: longword; + cminflt: longword; + majflt: longword; + cmajflt: longword; + utime: longword; + stime: longword; + cutime: longint; + cstime: longint; + priority: longint; + nice: longint; + null: longint; + itrealvalue: longint; + starttime: longword; + vsize: longword; + rss: longint; + rlim: longword; + startcode: longword; + endcode: longword; + startstack: longword; + kstkesp: longword; + kstkeip: longword; + signal: longword; + blocked: longword; + sigignore: longword; + sigcatch: longword; + wchan: longword; + nswap: longword; + cnswap: longword; + exitsignal: integer; + processor: integer; + end; + +function getprocinfo(pid: procidty): procinfoty; +function getchildpid(pid: procidty): procidarty; +function getinnerstpid(pid: procidty): procidty; +function getppid2(pid: procidty): procidty; + + {$endif} +type + eexecerror = class(msesysutils.eoserror) + end; + +implementation +uses + msesysintf1,msesysintf,mseprocmonitor,msearrayutils,mseformatstr, + mseapplication,msefileutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure killprocesstree1(id: procidty); +var + ar1: procidarty; + int1: integer; +begin + ar1:= getprocesschildren(id); + for int1:= 0 to high(ar1) do begin + killprocesstree1(ar1[int1]); + killprocessid(ar1[int1]); + end; +end; + +procedure killprocesstree(handle: prochandlety); +begin +{$ifdef windows} + killprocesstree1(procidfromprochandle(handle)); +{$else} + killprocesstree1(handle); +{$endif} + killprocess(handle); +end; + +procedure killprocessid(id: procidty); +{$ifdef mswindows} +var + h1: prochandlety; +{$endif} +begin +{$ifdef mswindows} + h1:= windows.openprocess(process_terminate,false,id); + if h1 <> 0 then begin + windows.terminateprocess(h1,0); + windows.closehandle(h1); + end; +{$else} + killprocess(id); +{$endif} +end; + +procedure killprocesstreeid(id: procidty); +{$ifdef mswindows} +var + h1: prochandlety; +{$endif} +begin +{$ifdef mswindows} + h1:= windows.openprocess(process_terminate,false,id); + if h1 <> 0 then begin + killprocesstree(h1); + windows.closehandle(h1); + end; +{$else} + killprocesstree1(id); + killprocessid(id); +{$endif} +end; + +function getpid: procidty; +begin + result:= sys_getpid; +end; + +function compprocitem(const l,r): integer; +begin + result:= procitemty(l).pid - procitemty(r).pid; +end; + +function findprocitem(const l,r): integer; +begin + result:= procidty(l) - procitemty(r).pid; +end; + +function getprocesstree: procitemarty; +var + int1,int2: integer; +begin + result:= sys_getprocesses; + sortarray(result,sizeof(procitemty),{$ifdef FPC}@{$endif}compprocitem); + for int1:= 0 to high(result) do begin + if findarrayitem(result[int1].ppid,result,sizeof(procitemty), + {$ifdef FPC}@{$endif}findprocitem,int2) then begin + additem(winidarty(result[int2].children),result[int1].pid); + end; + end; +end; + +function getprocesschildren(const pid: procidty): procidarty; +var + ar1: procitemarty; + int2: integer; +begin + result:= nil; + if pid <> invalidprocid then begin + ar1:= getprocesstree; + if findarrayitem(pid,ar1,sizeof(procitemty), + {$ifdef FPC}@{$endif}findprocitem,int2) then begin + result:= ar1[int2].children; + end; + end; +end; + +function getallprocesschildren(const pid: procidty): procidarty; +var + ar1: procitemarty; + + procedure addproc(const pid: integer); + var + int1,int2: integer; + begin + if findarrayitem(pid,ar1,sizeof(procitemty), + {$ifdef FPC}@{$endif}findprocitem,int2) then begin + stackarray(winidarty(ar1[int2].children),winidarty(result)); + for int1:= 0 to high(ar1[int2].children) do begin + addproc(ar1[int2].children[int1]); + end; + end; + end; + +begin + ar1:= getprocesstree; + setlength(result,1); + result[0]:= pid; + addproc(pid); +end; + +procedure execerror(const errno: integer; const commandline: msestring); +begin + raise eexecerror.Create(errno, + ansistring('Can not execute "'+commandline+'".'+lineend)); +end; + +{$ifdef mswindows} +function getprocessexitcode(prochandle: prochandlety; out exitcode: integer; + const timeoutus: integer = 0): processexiterrorty; + //true if ok, close handle +var + dwo1: longword; + ca1: longword; +begin + result:= pee_error; + exitcode:= -1; + if prochandle <> invalidprochandle then begin + if timeoutus < 0 then begin + exitcode:= waitforprocess(prochandle); + if exitcode <> -1 then begin + result:= pee_ok; + end; + end + else begin + ca1:= timestep(timeoutus); + while true do begin + if getexitcodeprocess(prochandle,dwo1) then begin + if dwo1 <> still_active then begin + exitcode:= dwo1; + closehandle(prochandle); + result:= pee_ok; + break; + end + else begin + if (timeoutus = 0) or timeout(ca1) then begin + result:= pee_timeout; + break; + end; + sys_schedyield; + end; + end + else begin + exit; + end; + end; + end; + end; +end; + +function waitforprocess(prochandle: prochandlety): integer; +begin + result:= -1; + if waitforsingleobject(prochandle,infinite) = wait_object_0 then begin + getprocessexitcode(prochandle,result); + end; +// else begin +// raise eoserror.create(''); +// end; +end; + +function pipe(out desc: pipedescriptorty; write: boolean): boolean; + //true if ok + + procedure error; + begin + closehandle(desc.writedes); + closehandle(desc.readdes); + end; + +var + sa: security_attributes; + hdup: integer; + po1: pinteger; +begin + result:= false; + fillchar(sa,sizeof(sa),0); + sa.nlength:= sizeof(sa); + sa.bInheritHandle:= true; + if createpipe(ptruint(desc.readdes),ptruint(desc.writedes),@sa,0) then begin + if write then begin + po1:= @desc.writedes; + end + else begin + po1:= @desc.readdes; + end; + if not duplicatehandle(getcurrentprocess,po1^,getcurrentprocess,@hdup,0, + false,duplicate_same_access) then begin //non inheritable + error; + end + else begin + closehandle(po1^); + po1^:= hdup; + end; + result:= true; + end; +end; + +function execmse0(const commandline: msestring; topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: msestring = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil + ): prochandlety; +//startet programm, bringt processhandle, execerror wenn misslungen +//closehandle nicht vergessen! + +var + topipehandles,frompipehandles,errorpipehandles: pipedescriptorty; + + procedure execerr; + var + errorbefore: integer; + begin + errorbefore:= sys_getlasterror; + if errorbefore = 0 then begin + errorbefore:= 2; //filenotfound + end; + if topipehandles.writedes <> invalidfilehandle then closehandle(topipehandles.writedes); + if topipehandles.readdes <> invalidfilehandle then closehandle(topipehandles.readdes); + if frompipehandles.writedes <> invalidfilehandle then closehandle(frompipehandles.writedes); + if frompipehandles.readdes <> invalidfilehandle then closehandle(frompipehandles.readdes); + if errorpipehandles.writedes <> invalidfilehandle then closehandle(errorpipehandles.writedes); + if errorpipehandles.readdes <> invalidfilehandle then closehandle(errorpipehandles.readdes); + execerror(errorbefore,commandline); + end; + +var + startupinfo: {$ifdef mse_fpc_3}tstartupinfow{$else}tstartupinfo{$endif}; + creationflags: dword; + processinfo: tprocessinformation; + bo1: boolean; + mstr1: msestring; + wd1,cmd1,env1: msestring; + i1,i2,i3,i4: int32; +begin + creationflags:= 0; + result:= invalidprochandle; + fillchar(startupinfo,sizeof(startupinfo),0); + startupinfo.hStdInput:= stdinputhandle; + startupinfo.hStdoutput:= stdoutputhandle; + startupinfo.hStderror:= stderrorhandle; + + topipehandles.writedes:= invalidfilehandle; + topipehandles.readdes:= invalidfilehandle; + frompipehandles.writedes:= invalidfilehandle; + frompipehandles.readdes:= invalidfilehandle; + errorpipehandles.writedes:= invalidfilehandle; + errorpipehandles.readdes:= invalidfilehandle; + + if topipe <> nil then begin + if topipe^ = invalidfilehandle then begin + if not pipe(topipehandles,true) then execerr; + topipe^:= topipehandles.WriteDes; + startupinfo.hStdInput:= topipehandles.readdes; + end + else begin + startupinfo.hStdInput:= topipe^; + end; + end; + if frompipe <> nil then begin + if frompipe^ = invalidfilehandle then begin + if not pipe(frompipehandles,false) then execerr; + frompipe^:= frompipehandles.readDes; + startupinfo.hStdoutput:= frompipehandles.writedes; + end + else begin + startupinfo.hStdoutput:= frompipe^; + end; + end; + if errorpipe <> nil then begin + if errorpipe <> frompipe then begin + if errorpipe^ = invalidfilehandle then begin + if not pipe(errorpipehandles,false) then execerr; + errorpipe^:= errorpipehandles.readdes; + startupinfo.hStderror:= errorpipehandles.writedes; + end + else begin + startupinfo.hStderror:= errorpipe^; + end; + end + else begin + if frompipe^ <> invalidfilehandle then begin + errorpipe^:= frompipehandles.readdes; + startupinfo.hStderror:= frompipehandles.writedes; + end + else begin + startupinfo.hStderror:= frompipe^; + end; + end; + end; + if not (exo_nostdhandle in options) then begin + startupinfo.dwflags:= startupinfo.dwFlags or startf_usestdhandles; + end; + if exo_nowindow in options then begin + creationflags:= creationflags or create_no_window; + end; + if exo_newconsole in options then begin + creationflags:= creationflags or create_new_console; + end; + if exo_detached in options then begin + creationflags:= creationflags or detached_process; + end; + if (exo_allowsetforegroundwindow in options) and + assigned(allowsetforegroundwindow) then begin + allowsetforegroundwindow(asfw_any); + end; + if exo_inactive in options then begin + startupinfo.wShowWindow:= sw_hide; + startupinfo.dwflags:= startupinfo.dwFlags or startf_useshowwindow; + end; + wd1:= tosysfilepath(workingdirectory); + mstr1:= commandline; + for i1:= 0 to high(params) do begin + if params[i1] = '' then begin + mstr1:= mstr1 + ' ""'; + end + else begin + mstr1:= mstr1 + ' '+quotestring(params[i1],'"',false); + end; + end; + + cmd1:= copy(mstr1,1,bigint); //must be writeable for createprocessw + env1:= ''; + if envvars <> nil then begin + i2:= 0; + for i1:= 0 to high(envvars) do begin + i4:= length(envvars[i1]); + if i4 > 0 then begin + i2:= i2+i4; + end; + end; + setlength(env1,i2+length(envvars)); + i3:= 0; + for i1:= 0 to high(envvars) do begin + i4:= length(envvars[i1]); + if i4 > 0 then begin + move(pointer(envvars[i1])^,(pmsechar(pointer(env1))+i3)^, + (i4+1)*sizeof(msechar)); + i3:= i3 + i4 + 1; + end; + end; + end; //string has terminating #0 + + if exo_shell in options then begin + cmd1:= 'cmd.exe /q /c'+cmd1; + end; + if iswin95 then begin + bo1:= createprocessa(nil,pchar(ansistring(cmd1)),nil,nil,true,creationflags, + pointer(ansistring(env1)), + pointer(ansistring(wd1)), + {$ifdef mse_fpc_3}tstartupinfoa{$endif}(startupinfo),processinfo); + end + else begin + bo1:= createprocessw(nil,pmsechar(cmd1),nil,nil,true, + creationflags or create_unicode_environment, + pointer(env1), + pointer(wd1),startupinfo,processinfo); + end; + + if bo1 then begin + if topipehandles.readdes <> invalidfilehandle then begin + closehandle(topipehandles.readdes); + end; + if frompipehandles.writedes <> invalidfilehandle then begin + if frompipewritehandle <> nil then begin + frompipewritehandle^:= frompipehandles.writedes; + end + else begin + closehandle(frompipehandles.writedes); + end; + end; + if errorpipehandles.writedes <> invalidfilehandle then begin + if errorpipewritehandle <> nil then begin + errorpipewritehandle^:= errorpipehandles.writedes; + end + else begin + closehandle(errorpipehandles.writedes); + end; + end; + result:= processinfo.hProcess; + closehandle(processinfo.hThread); + end + else begin + execerr; + end; +end; + +procedure killprocess(handle: prochandlety); +begin + if handle <> invalidprochandle then begin + windows.terminateprocess(handle,0); + closehandle(handle); + end; +end; + +function terminateprocess(handle: prochandlety): integer; + //bricht process ab, kein exitresult +begin + result:= -1; + if handle <> invalidprochandle then begin + result:= 0; + killprocess(handle); + end; +end; + +{$endif} + +{$ifdef UNIX} +function getprocessexitcode(prochandle: prochandlety; out exitcode: integer; + const timeoutus: integer = 0): processexiterrorty; + //-1 -> no timeout +var + dwo1: longword; + cancel: boolean; + + function check(const apid: integer): boolean; + begin + result:= false; + if apid <> -1 then begin + result:= apid = prochandle; +// if result then begin +// exitcode:= wexitstatus(dwo1); +// end; + end + else begin + if sys_getlasterror <> eintr then begin + cancel:= true; + end; + end; + end; + + procedure setresult(); + begin + if wifsignaled(dwo1) then begin + result:= pee_signaled; + exitcode:= -wtermsig(dwo1)-256; + end + else begin + result:= pee_ok; + exitcode:= wexitstatus(dwo1); + end; + end; + +var + i1: int32; + +begin + result:= pee_error; + cancel:= false; + exitcode:= -1; + if prochandle <> invalidprochandle then begin + if check(waitpid(prochandle,@dwo1,wnohang)) then begin + setresult(); + exit; + end + else begin + if not cancel then begin + result:= pee_timeout; + end; + end; + + if (result = pee_timeout) and (timeoutus <> 0) then begin + if timeoutus < 0 then begin + repeat + until check(waitpid(prochandle,@dwo1,0)) or cancel; + if cancel then begin + result:= pee_error; + end + else begin + setresult(); +// result:= pee_ok; + end + end + else begin + i1:= timedwaitpid(prochandle,@dwo1,timeoutus); + case i1 of + -2: begin + result:= pee_timeout; + end; + else begin + if i1 >= 0 then begin + if i1 > 0 then begin + setresult(); +// exitcode:= wexitstatus(dwo1); +// if wifsignaled(dwo1) then begin +// result:= pee_signaled; +// end +// else begin +// result:= pee_ok; +// end; + end + else begin + result:= pee_timeout; + end; + end + else begin + result:= pee_error; + end; + end; + end; + end; + end; + end; +end; + +function waitforprocess(prochandle: prochandlety): integer; +var + dwo1: longword; + pid: integer; +begin + result:= -1; + while true do begin + pid:= waitpid(prochandle,@dwo1,0); + if pid <> -1 then begin + if wifsignaled(dwo1) then begin + result:= -wtermsig(dwo1)-256; + end + else begin + result:= wexitstatus(dwo1); + end; + break; + end + else begin + if sys_getlasterror <> eintr then begin + exit; +// result:= 0; //compilerwarning +// raise eoserror.create(''); + end; + end; + end; +end; + +function pipe(out desc: pipedescriptorty; write: boolean): boolean; + //returns errorcode, 0 if ok +begin + result:= mselibc.pipe(tpipedescriptors(desc)) = 0; + if result then begin + if write then begin + setcloexec(desc.writedes); + end + else begin + setcloexec(desc.readdes); + end; + end; +end; + +function getpseudoterminal(out name: string): integer; +const + buflen = 256; +var + buffer: array[0..buflen] of char; +begin + result:= getpt; + if result < 0 then begin + syserror(sye_lasterror); + end; + if (grantpt(result) < 0) or (unlockpt(result) < 0) then begin + syserror(sye_lasterror); + end; + if ptsname_r(result,@buffer,buflen) < 0 then begin + syserror(sye_lasterror); + end; + name:= buffer; +end; + +function execmse0(const commandline: msestring; topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil + ): prochandlety; +const + shell = shortstring('/bin/sh'); + buflen = 256; +type + namebufferty = array[0..buflen] of char; +var + procid: integer; + topipehandles,frompipehandles,errorpipehandles: tpipedescriptors; + ptyout: integer;// = -1; + ptyerr: integer;// = -1; + ptynameout: namebufferty; + ptynameerr: namebufferty; + + procedure execerr; + var + errorbefore: integer; + begin + errorbefore:= sys_getlasterror; + if topipehandles.writedes <> invalidfilehandle then __close(topipehandles.writedes); + if topipehandles.readdes <> invalidfilehandle then __close(topipehandles.readdes); + if frompipehandles.writedes <> invalidfilehandle then __close(frompipehandles.writedes); + if frompipehandles.readdes <> invalidfilehandle then __close(frompipehandles.readdes); + if errorpipehandles.writedes <> invalidfilehandle then __close(errorpipehandles.writedes); + if errorpipehandles.readdes <> invalidfilehandle then __close(errorpipehandles.readdes); + execerror(errorbefore,commandline); + end; + + function dogetpt(var pty: integer; var ptyname: namebufferty): integer; + procedure ptyerror; + begin + __close(pty); + pty:= -1; + end; //ptyerror + var + ios: termios; + begin + if pty < 0 then begin + pty:= getpt; + if msetcgetattr(pty,ios) <> 0 then begin + ptyerror; + end + else begin + if exo_icanon in options then begin + ios.c_lflag:= ios.c_lflag or icanon; + end + else begin + ios.c_lflag:= ios.c_lflag and not icanon; + end; + if exo_echo in options then begin + ios.c_lflag:= ios.c_lflag or echo; + end + else begin + ios.c_lflag:= ios.c_lflag and not echo; + end; + ios.c_cc[vmin]:= #1; + ios.c_cc[vtime]:= #0; + if msetcsetattr(pty,tcsanow,ios) <> 0 then begin + ptyerror; + end + else begin + if (grantpt(pty) < 0) or (unlockpt(pty) < 0) then begin + ptyerror; + end; + end; + end; + end + else begin + pty:= dup(pty); + end; + if pty >= 0 then begin + if ptsname_r(pty,@ptyname,buflen) < 0 then begin + ptyerror; + end; + end; + result:= pty; + end; //dogetpt + + procedure openpipe(var pipehandles: tpipedescriptors); + begin + if exo_tty in options then begin + with pipehandles do begin + if @pipehandles = @topipehandles then begin + writedes:= dogetpt(ptyout,ptynameout); + readdes:= open(ptynameout,o_rdonly); + if readdes < 0 then execerr; + end + else begin + if @pipehandles = @frompipehandles then begin + readdes:= dogetpt(ptyout,ptynameout); + if readdes < 0 then execerr; + writedes:= open(ptynameout,o_wronly); + end + else begin + readdes:= dogetpt(ptyerr,ptynameerr); + if readdes < 0 then execerr; + writedes:= open(ptynameerr,o_wronly); + end; + if writedes < 0 then execerr; + end; + end; + end + else begin + if mselibc.pipe(pipehandles) <> 0 then execerr; + end; + end; + +var + bo1: boolean; + i1,i2: int32; + wd1: ansistring; + command1,commandline1: ansistring; + params1,envvars1: pointerarty; + par,env: stringarty; + useshell: boolean; +begin + wd1:= ''; + commandline1:= ansistring(commandline); + if workingdirectory <> '' then begin + wd1:= ansistring(tosysfilepath(workingdirectory)); + end; + setlength(par,length(params)); + for i1:= 0 to high(par) do begin + par[i1]:= ansistring(params[i1]); + end; + setlength(env,length(envvars)); + for i1:= 0 to high(env) do begin + env[i1]:= ansistring(envvars[i1]); + end; + useshell:= not (exo_noshell in options); + if useshell then begin + command1:= shell; + if params <> nil then begin +// i1:= length(parsecommandline(commandline)); +// for i1:= i1 to i1 + high(params) do begin + for i1:= 1 to length(params) do begin + if params[i1-1] = '' then begin + commandline1:= commandline1 + ' ""'; + end + else begin + commandline1:= commandline1 + ' ${'+inttostr(i1)+'}'; + end; + end; + end; + setlength(params1,4); + params1[1]:= pchar('-c'); + params1[2]:= pchar(commandline1); + params1[3]:= pchar(command1); //shell name + end + else begin + command1:= ansistring(tosysfilepath(msestring(commandline))); + setlength(params1,1); + end; + + params1[0]:= pchar(command1); + i2:= length(params1); + setlength(params1,i2+length(params)+1); + for i1:= 0 to high(par) do begin + params1[i2]:= pchar(par[i1]); + inc(i2); + end; + params1[high(params1)]:= nil; + + setlength(envvars1,length(envvars)+1); + for i1:= 0 to high(env) do begin + envvars1[i1]:= pchar(env[i1]); + end; + envvars1[high(envvars1)]:= nil; + + ptyout:= -1; + ptyerr:= -1; + result:= invalidprochandle; //compilerwarnung; + topipehandles.writedes:= invalidfilehandle; + topipehandles.readdes:= invalidfilehandle; + frompipehandles.writedes:= invalidfilehandle; + frompipehandles.readdes:= invalidfilehandle; + errorpipehandles.writedes:= invalidfilehandle; + errorpipehandles.readdes:= invalidfilehandle; + + if topipe <> nil then begin + if topipe^ = invalidfilehandle then begin + openpipe(topipehandles); + setcloexec(topipehandles.writedes); + topipe^:= topipehandles.writedes; + end + else begin + topipehandles.readdes:= topipe^; + end; + end; + if frompipe <> nil then begin + if frompipe^ = invalidfilehandle then begin + openpipe(frompipehandles); + setcloexec(frompipehandles.readdes); + frompipe^:= frompipehandles.readdes; + end + else begin + frompipehandles.writedes:= frompipe^; + end; + end; + if errorpipe <> nil then begin + if errorpipe <> frompipe then begin + if errorpipe^ = invalidfilehandle then begin + openpipe(errorpipehandles); + setcloexec(errorpipehandles.readdes); + errorpipe^:= errorpipehandles.readdes; + end + else begin + errorpipehandles.writedes:= errorpipe^; + end; + end; + end; + + procid:= mselibc.vfork; +// procid:= mselibc.fork; + + if procid = -1 then execerr; + + if procid = 0 then begin //child + if wd1 <> '' then begin + mselibc.__chdir(pointer(wd1)); + end; + if exo_sessionleader in options then begin + setsid; + end + else begin + if groupid <> -1 then begin + if groupid = 0 then begin + setpgid(procid,procid); + end + else begin + setpgid(procid,groupid); + end; + end; + end; + + if topipe <> nil then begin + __close(topipehandles.writedes); + if dup2(topipehandles.ReadDes,0) = -1 then begin + mselibc._exit(exit_failure); + end; + __close(topipehandles.readdes); + end; + if frompipe <> nil then begin + __close(frompipehandles.readdes); + if dup2(frompipehandles.writeDes,1) = -1 then begin + mselibc._exit(exit_failure); + end; + end; + if errorpipe <> nil then begin + if errorpipe <> frompipe then begin + __close(errorpipehandles.readdes); + if dup2(errorpipehandles.writeDes,2) = -1 then begin + mselibc._exit(exit_failure); + end; + __close(errorpipehandles.writedes); + end + else begin + if dup2(frompipehandles.writeDes,2) = -1 then begin + mselibc._exit(exit_failure); + end; + end + end; + if frompipe <> nil then begin + __close(frompipehandles.writedes); + end; + + if (exo_settty in options) then begin + bo1:= false; //search posssible controlling TTY + if (topipehandles.writedes <> invalidfilehandle) and + (isatty(0) <> 0) then begin + bo1:= ioctl(0,TIOCSCTTY,[]) <> -1; + end; + if not bo1 and (frompipehandles.writedes <> invalidfilehandle) and + (isatty(1) <> 0) then begin + bo1:= ioctl(1,TIOCSCTTY,[]) <> -1; + end; + if not bo1 and (errorpipehandles.writedes <> invalidfilehandle) and + (isatty(2) <> 0) then begin + bo1:= ioctl(2,TIOCSCTTY,[]) <> -1; + end; + end; + +// mselibc.execl(shell,shell,['-c',pchar(commandline),nil]); + if envvars <> nil then begin + mselibc.execve(pointer(pchar(command1)),pointer(params1),pointer(envvars1)); + end + else begin + mselibc.execv(pointer(pchar(command1)),pointer(params1)); + end; + mselibc._exit(exit_failure); //execl misslungen + + end + else begin //parent + if topipe <> nil then begin + __close(topipehandles.readDes); + end; + if frompipe <> nil then begin + if frompipewritehandle <> nil then begin + frompipewritehandle^:= frompipehandles.writedes; + end + else begin + __close(frompipehandles.writeDes); + end; + end; + if (errorpipe <> nil) and (errorpipe <> frompipe) then begin + if errorpipewritehandle <> nil then begin + errorpipewritehandle^:= errorpipehandles.writedes; + end + else begin + __close(errorpipehandles.writeDes); + end; + end; + result:= procid; + end; +end; + +procedure killprocess(handle: prochandlety); +var + int1: integer; +begin + if handle <> invalidprochandle then begin + int1:= kill(handle,sigterm); + if (int1 <> 0) and (errno <> esrch) then begin + exit; +// raise eoserror.create(''); //sigterm nicht moeglich + end; + if waitpid(handle,@int1,wnohang) = 0 then begin + sleep(100); + if waitpid(handle,@int1,wnohang) = 0 then begin + sleep(1000); + if waitpid(handle,@int1,wnohang) = 0 then begin + int1:= kill(handle,sigkill); + if (int1 <> 0) and (errno <> esrch) then begin + raise eoserror.create(''); //sigkill nicht moeglich + end; + while waitpid(handle,@int1,0) = -1 do begin + if sys_getlasterror <> eintr then begin + break; +// raise eoserror.create(''); + end; + end; + end; + end; + end; + end; +end; + +function terminateprocess(handle: prochandlety): integer; + //bringt exitresult +var + int1: integer; +begin + result:= -1; + if handle <> invalidprochandle then begin + int1:= kill(handle,sigterm); + if (int1 <> 0) and (errno <> esrch) then begin + exit; //sigterm nicht moeglich +// raise eoserror.create(''); + end; + + while waitpid(handle,@result,0) = -1 do begin + if sys_getlasterror <> eintr then begin + break; +// raise eoserror.create(''); + end; + end; + end; +end; + +function getppid2(pid: procidty): procidty; +var + stream: ttextstream; + str1: string; +begin + stream:= ttextstream.create('/proc/'+inttostrmse(pid)+'/stat',fm_read); + try + fillchar(result,sizeof(result),0); + stream.readln(str1); +// {$ifdef FPC} + sscanf(pchar(str1),'%*d (%*a[^)]) %*c %d',[@result]); +// {$else} +// sscanf(pchar(str1),'%*d (%*a[^)]) %*c %d',@result); +// {$endif} + finally + stream.free; + end; +end; + +function getprocinfo(pid: procidty): procinfoty; +var + stream: ttextstream; + str1: string; + commpo: pchar; +begin + stream:= ttextstream.create('/proc/'+inttostrmse(pid)+'/stat',fm_read); + try + fillchar(result,sizeof(result),0); + stream.readln(str1); + with result do begin + mselibc.sscanf(pchar(str1),'%d (%a[^)]) %c %d %d %d %d %d %lu %lu '+ + '%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu '+ + '%lu %lu %lu %lu %lu %lu %lu %lu %d %d', +// {$ifdef FPC}[{$endif} + [ + @pid, + @commpo, + @state, + @ppid, + @pgrp, + @session, + @tty_nr, + @tpgid, + @flags, + @minflt, + @cminflt, + @majflt, + @cmajflt, + @utime, + @stime, + @cutime, + @cstime, + @priority, + @nice, + @null, + @itrealvalue, + @starttime, + @vsize, + @rss, + @rlim, + @startcode, + @endcode, + @startstack, + @kstkesp, + @kstkeip, + @signal, + @blocked, + @sigignore, + @sigcatch, + @wchan, + @nswap, + @cnswap, + @exitsignal, + @processor + ] +// {$ifdef FPC}]{$endif} + ); + comm:= string(commpo); + mselibc.free(commpo); + end; + finally + stream.Free; + end +end; + +function getchildpid(pid: procidty): procidarty; +var + srec: tsearchrec; + int1: procidty; +begin + result:= nil; + if findfirst('/proc/*',fadirectory,srec) = 0 then begin + repeat + if (length(srec.name) > 0) and (srec.name[1] >= '0') and + (srec.name[1] <= '9') then begin +{$ifdef CPU64} + if trystrtoint64(srec.name,int1) then begin +{$else} + if trystrtoint(srec.name,int1) then begin +{$endif} + if getppid2(int1) = pid then begin + setlength(result,length(result)+1); + result[length(result)-1]:= int1; + end; + end; + end; + until findnext(srec) <> 0; + end; +end; + +function getinnerstpid(pid: procidty): procidty; +var + intar1: procidarty; + int1,int2: integer; +begin + result:= pid; + intar1:= getchildpid(pid); + for int1:= 0 to length(intar1) - 1 do begin + int2:= getinnerstpid(intar1[int1]); + if int2 > result then begin + result:= int2; + end; + end; +end; + +{$endif} + +function execmse(const commandline: msestring; + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): boolean; +var + procid: prochandlety; +begin + result:= true; +{$ifdef MSWINDOWS} + try + try + procid:= execmse1(commandline,nil,nil,nil,-1,options,nil,nil, + workingdirectory,params,envvars); + finally + if procid <> invalidprochandle then begin + closehandle(procid); + end; + end; + except + result:= false; + end; +{$else} + try + procid:= execmse1(commandline,nil,nil,nil,-1,options,nil,nil, + workingdirectory,params,envvars); + pro_killzombie(procid); + except + result:= false; + end; +{$endif} +end; + +function execwaitmse(const commandline: msestring; + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): integer; +//startet programm, wartet auf ende, bring exitcode, -1 wenn start nicht moeglich +var + prochandle: prochandlety; +begin + result:= -1; + //programm wurde nicht gestartet oder getexitcodeprozessproblem + prochandle:= execmse1(commandline,nil,nil,nil,-1,options,nil,nil, + workingdirectory,params,envvars); + if prochandle <> invalidprochandle then begin + result:= waitforprocess(prochandle); + end; +end; +{ +function execwaitmse(const commandline: string; + const options: execoptionsty = []; + const workingdirectory: ansistring = '' + //const inactive: boolean = true + ): integer; +begin + result:= mselibc.__system(pchar(commandline)); +end; +} + +function execmse1(const commandline: msestring; topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; + //creates pipes +begin + if topipe <> nil then begin + topipe^:= invalidfilehandle; + end; + if frompipe <> nil then begin + frompipe^:= invalidfilehandle; + end; + if errorpipe <> nil then begin + errorpipe^:= invalidfilehandle; + end; + result:= execmse0(commandline,topipe,frompipe,errorpipe,groupid,options, + frompipewritehandle,errorpipewritehandle, + workingdirectory,params,envvars); +end; + +function execmse2(const commandline: msestring; topipe: tpipewriter = nil; + frompipe: tpipereader = nil; + errorpipe: tpipereader = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; + //bringt procid +var + top,fromp,errp,fromwrite,errwrite: integer; + topp,frompp,errpp,fromwritep,errwritep: pinteger; +begin + if topipe <> nil then begin + topp:= @top; + topipe.close; + end + else begin + topp:= nil; + end; + if frompipe <> nil then begin + frompipe.close; + frompp:= @fromp; + fromwritep:= @fromwrite; + end + else begin + frompp:= nil; + fromwritep:= nil; + end; + if errorpipe <> nil then begin + if errorpipe <> frompipe then begin + errorpipe.close; + errpp:= @errp; + errwritep:= @errwrite; + end + else begin + errpp:= @fromp; + errwritep:= nil; + end; + end + else begin + errpp:= nil; + errwritep:= nil; + end; + if options * pipewritehandlemask = [] then begin + fromwritep:= nil; + errwritep:= nil; + end; + result:= execmse1(commandline,topp,frompp,errpp,groupid, + options, + fromwritep,errwritep,workingdirectory,params,envvars); + if topp <> nil then begin + topipe.Handle:= topp^; + end; + if frompp <> nil then begin + frompipe.Handle:= frompp^; + if fromwritep <> nil then begin + frompipe.writehandle:= fromwritep^; + end; + end; + if errpp <> nil then begin + if errorpipe <> frompipe then begin + errorpipe.Handle:= errpp^; + if errwritep <> nil then begin + errorpipe.writehandle:= errwritep^; + end; + end; + end; +end; + +function execmse3(const commandline: msestring; + topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; + //uses existing file handles +begin + result:= execmse0(commandline,topipe,frompipe,errorpipe, + groupid,options,frompipewritehandle,errorpipewritehandle, + workingdirectory,params,envvars); +end; + +function execmse4(const commandline: msestring; + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; +begin + result:= execmse1(commandline,nil,nil,nil,-1,options,nil,nil, + workingdirectory,params,envvars); +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msepython.pas b/mseide-msegui/lib/common/sysutils/msepython.pas new file mode 100644 index 0000000..6492397 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msepython.pas @@ -0,0 +1,302 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepython; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseprocess,mclasses,msearrayprops,msemacros,mseclasses, + msetypes{msestrings}; + +const + defaultpythonprocoptions = defaultprocessoptions + [pro_input]; + pyboolstrings: array[boolean] of msestring = ('False','True'); + +type + tpythonstringlist = class(tmacrostringlist) + end; + + tpythonstringlistitem = class(townedpersistent) + private + fname: msestring; + fscript: tpythonstringlist; + procedure setscript(const avalue: tpythonstringlist); + protected + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure assign(source: tpersistent); override; + function execute(const atimeoutus: integer = -1): int32; //-1 -> infinite + //returns exitcode, -1 for timeout + published + property name: msestring read fname write fname; + property script: tpythonstringlist read fscript write setscript; + end; + + tpythonscript = class; + + tpythonscripts = class(townedpersistentarrayprop) + private + fdummylist: tmacrostringlist; + function getitems(const aindex: integer): tpythonstringlistitem; + procedure setitems(const aindex: integer; + const avalue: tpythonstringlistitem); + procedure setmacros(const avalue: tmacroproperty); + function getmacros: tmacroproperty; + protected + public + constructor create(const aowner: tpythonscript); reintroduce; + destructor destroy(); override; + property items[const aindex: integer]: tpythonstringlistitem read getitems + write setitems; default; + function itembyname(const aname: msestring): tpythonstringlistitem; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + published + property macros: tmacroproperty read getmacros write setmacros; + end; + + tpythonscript = class(tcustommseprocess) + private + fscripts: tpythonscripts; + procedure setscripts(const avalue: tpythonscripts); + protected + procedure setoptions(const avalue: processoptionsty) override; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + published + property scripts: tpythonscripts read fscripts write setscripts; + property filename; + property parameter; + property workingdirectory; + property params; + property envvars; + property active; + property options default defaultpythonprocoptions; + property pipewaitus; + property statfile; + property statvarname; + property statpriority; + property input; + property output; + property erroroutput; + property onprocfinished; + property oncheckabort; + end; + +function pyboolean(const avalue: boolean): msestring; + +implementation +uses + sysutils,mseapplication; + +function pyboolean(const avalue: boolean): msestring; +begin + if avalue then begin + result:= 'True'; + end + else begin + result:= 'False'; + end; +{ + if avalue then begin + result:= '1'; + end + else begin + result:= '0'; + end; +} +end; + +{ tpythonscript } + +constructor tpythonscript.create(aowner: tcomponent); +begin + fscripts:= tpythonscripts.create(self); + inherited; + filename:= 'python'; + options:= defaultpythonprocoptions; +end; + +destructor tpythonscript.destroy(); +begin + inherited; + fscripts.free(); +end; + +procedure tpythonscript.setscripts(const avalue: tpythonscripts); +begin + fscripts.assign(avalue); +end; + +procedure tpythonscript.setoptions(const avalue: processoptionsty); +begin + inherited; + if not (pro_input in foptions) then begin + inherited setoptions(foptions + [pro_noshell]); + //bash -c only supports a single commandstring -> + //python -c can not be used with bash and paramlist + end; +end; + +{ tpythonstringlistitem } + +constructor tpythonstringlistitem.create(aowner: tobject); +begin + fscript:= tpythonstringlist.create(); + inherited; +end; + +destructor tpythonstringlistitem.destroy; +begin + fscript.free; + inherited; +end; + +procedure tpythonstringlistitem.assign(source: tpersistent); +begin + if source is tpythonstringlistitem then begin + with tpythonstringlistitem(source) do begin + self.name:= name; + self.script:= script; + end; + end; +end; + +function tpythonstringlistitem.execute(const atimeoutus: integer = -1): int32; +var + i1,i2: int32; + ms1: msestring; +begin + with tpythonscript(fowner) do begin + active:= false; + ms1:= fscripts.fdummylist.expandmacros(fscript.text); + if not (pro_input in options) then begin + i2:= -1; + for i1:= 0 to params.count-1 do begin + if params[i1] = '-' then begin + i2:= i1; + break; + end; + end; + i1:= i2; + if i1 < 0 then begin + params.insert(0,'-c'); + params.insert(1,ms1); + i1:= 0; + i2:= 2; + end + else begin + params[i1]:= '-c'; + inc(i1); + params.insert(i1,ms1); + i2:= 1; + end; + try + active:= true; + finally + if i2 = 1 then begin + params[i1-1]:= '-'; + end; + params.deleteitems(i1,i2); + end; + end + else begin + active:= true; + try + input.pipewriter.write(ms1); + except + application.handleexception(); + end; + input.pipewriter.close(); + end; + if atimeoutus < 0 then begin + result:= waitforprocess(); + end + else begin + if atimeoutus > 0 then begin + if not waitforprocess(atimeoutus) then begin + result:= -1; + end + else begin + result:= exitcode; + end; + end + else begin + result:= exitcode; + end; + end; + end; +end; + +procedure tpythonstringlistitem.setscript(const avalue: tpythonstringlist); +begin + fscript.assign(avalue); +end; + +{ tpythonscripts } + +constructor tpythonscripts.create(const aowner: tpythonscript); +begin + fowner:= aowner; + fdummylist:= tmacrostringlist.create(); + inherited create(aowner,tpythonstringlistitem); +end; + +destructor tpythonscripts.destroy(); +begin + inherited; + fdummylist.free(); +end; + +function tpythonscripts.getitems(const aindex: integer): tpythonstringlistitem; +begin + result:= tpythonstringlistitem(inherited getitems(aindex)); +end; + +procedure tpythonscripts.setitems(const aindex: integer; + const avalue: tpythonstringlistitem); +begin + inherited; +end; + +procedure tpythonscripts.setmacros(const avalue: tmacroproperty); +begin + fdummylist.macros:= avalue; +end; + +function tpythonscripts.getmacros: tmacroproperty; +begin + result:= fdummylist.macros; +end; + +function tpythonscripts.itembyname( + const aname: msestring): tpythonstringlistitem; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fitems) do begin + if tpythonstringlistitem(fitems[int1]).name = aname then begin + result:= tpythonstringlistitem(fitems[int1]); + break; + end; + end; + if result = nil then begin + raise exception.create('Script "'+ansistring(aname)+'" not found.'); + end; +end; + +class function tpythonscripts.getitemclasstype: persistentclassty; +begin + result:= tpythonstringlistitem; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msestatusnotifieritem.pas b/mseide-msegui/lib/common/sysutils/msestatusnotifieritem.pas new file mode 100644 index 0000000..8f9178e --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msestatusnotifieritem.pas @@ -0,0 +1,608 @@ + { MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +// +// for internal use in MSEgui only +// +unit msestatusnotifieritem; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msedbusinterface,msestrings,msetypes,msebitmap,msedbus,msegraphutils, + mseevent; +type + desktopkindty = (desk_none,desk_freedesktop,desk_kde); + + iconpixmapty = record + cx,cy: int32; + data: bytearty; + end; + iconpixmaparty = array of iconpixmapty; + + tooltipinfoty = record + iconname: string; + iconpixmap: array of iconpixmapty; + title: string; + text: string; + end; + tooltipinfoarty = array of tooltipinfoty; + //workaround in order to get item typeinfo + + statusnotifiercategoryty = (snc_applicationstatus,snc_communications, + snc_systemservices,snc_hardware); + tstatusnotifieritem = class; + statusnotifierposprocty = procedure(const sender: tstatusnotifieritem; + const apos: pointty) of object; + tstatusnotifieritem = class(tdbusobject) + private + fstatuscategory: statusnotifiercategoryty; + fid: string; + fid1: string; //possibly updated from applicationname + ftitle: string; + fstatus: string; + fwindowid: int32; + ficonname: string; + ficonpixmap: iconpixmaparty; + foverlayiconname: string; + foverlayiconpixmap: iconpixmaparty; + fatentioniconname: string; + fatentioniconpixmap: iconpixmaparty; + fatentionmoviename: string; + ftooltip: tooltipinfoty; + factive: boolean; + foncontextmenu: statusnotifierposprocty; + fonactivate: statusnotifierposprocty; + fmessageid: card32; + fonsecondaryactivate: statusnotifierposprocty; + function getcategory: string; + function getid: string; + procedure setactive(const avalue: boolean); + protected + fdesktopkind: desktopkindty; + function getintrospectitems(): string override; + function getpath(): string override; + procedure busconnected() override; + procedure propertiesget(var props: dictentryarty) override; + procedure propertyget(const amessage: pdbusmessage; + const aname: string; var avalue: variantvaluety) override; + function getpropintf: string override; + procedure registeritems(const sender: idbusservice) override; + procedure contextmenu(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure activate(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure secondaryactivate(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); + procedure scroll(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure receiveevent(const event: tobjectevent) override; + public + constructor create(); + destructor destroy(); override; + function checkdesktop(): boolean; + property desktopkind: desktopkindty read fdesktopkind; + function showmessage(const message: msestring; const title: msestring; + out messageid: card32; + const timeoutms: card32 = 0): boolean; + function cancelmessage(const messageid: card32): boolean; + + property active: boolean read factive write setactive; + property statuscategory: statusnotifiercategoryty read fstatuscategory + write fstatuscategory default snc_applicationstatus; + procedure setToolTip(const avalue: tooltipinfoty); + procedure setId(const avalue: string); //'' -> applicationname + procedure setTitle(const avalue: string); + procedure setStatus(const avalue: string); + procedure setWindowId(const avalue: int32); + procedure setIconName(const avalue: string); + procedure setIconPixmap(const avalue: tmaskedbitmap); + procedure setIconPixmap(const avalue: iconpixmaparty); + procedure setOverlayIconName(const avalue: string); + procedure setOverlayIconPixmap(const avalue: iconpixmaparty); + procedure setAtentionIconName(const avalue: string); + procedure setAtentionIconPixmap(const avalue: iconpixmaparty); + procedure setAtentionMovieName(const avalue: string); + property ToolTip: tooltipinfoty read ftooltip; + property oncontextmenu: statusnotifierposprocty read foncontextmenu + write foncontextmenu; + property onactivate: statusnotifierposprocty read fonactivate + write fonactivate; + property onsecondaryactivate: statusnotifierposprocty + read fonsecondaryactivate write fonsecondaryactivate; + published + property Category: string read getcategory; + property Id: string read getid; + property Title: string read ftitle; + property Status: string read fstatus; + property WindowId: int32 read fwindowid; + property IconName: string read ficonname; + property IconPixmap: iconpixmaparty read ficonpixmap; + property OverlayIconName: string read foverlayiconname; + property OverlayIconPixmap: iconpixmaparty read foverlayiconpixmap; + property AtentionIconName: string read fatentioniconname; + property AtentionIconPixmap: iconpixmaparty read fatentioniconpixmap; + property AtentionMovieName: string read fatentionmoviename; + end; + +function bitmaptoiconpixmap(const abitmap: tmaskedbitmap): iconpixmapty; + +implementation +uses + mseapplication,msegraphics,sysutils; +type + dbuspixelty = packed record a,r,g,b: card8 end; //in network byte order + pdbuspixelty = ^dbuspixelty; + +function bitmaptoiconpixmap(const abitmap: tmaskedbitmap): iconpixmapty; +var + p1: pdbuspixelty; + p1a: prgbtriplety; + p2: pcard8; + pe: pointer; + bmp1: tmaskedbitmap; + i1: int32; +begin + bmp1:= tmaskedbitmap.create(abitmap.kind); + bmp1.assign(abitmap); + bmp1.kind:= bmk_rgb; + with result do begin + cx:= abitmap.width; + cy:= abitmap.height; + setlength(data,cx*cy*4); + if (cx <> 0) and (cy <> 0) then begin + p1:= pdbuspixelty(pointer(data)); + p1a:= bmp1.scanline[0]; + if bmp1.masked then begin + bmp1.graymask:= true; + for i1:= 0 to cy-1 do begin + p2:= bmp1.mask.scanline[i1]; + pe:= p2+cx; + while p2 < pe do begin + p1^.r:= p1a^.red; + p1^.g:= p1a^.green; + p1^.b:= p1a^.blue; + p1^.a:= p2^; + inc(p1); + inc(p1a); + inc(p2); + end; + end; + end + else begin + p1:= pdbuspixelty(pointer(data)); + pe:= p1 + cx*cy; + while p1 < pe do begin + p1^.r:= p1a^.red; + p1^.g:= p1a^.green; + p1^.b:= p1a^.blue; + p1^.a:= $ff; + inc(p1); + inc(p1a); + end; + end; + end; + { + p1:= pdbuspixelty(pointer(data)); + pe:= p1 + cx*cy; + while p1 < pe do begin + swapendian(card32(p1^)); + inc(p1); + end; + } + end; + bmp1.free; +end; + +const + datadef1 = +''+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +//' '+lineend+ +//' '+lineend+ +//' '+lineend+ +' '+lineend+ +' '+lineend+ +//' '+lineend+ +//' '+lineend+ +' '+lineend+ +' '+lineend+ +//' '+lineend+ +//' '+lineend+ +' '+lineend+ +' '+lineend+ +//' '+lineend+ +//' '+lineend+ +' '+lineend+ +' '+lineend+ +//' '+lineend+ +//' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +''+lineend; + +const + interfacestart: array[desktopkindty] of string = ( + '','org.freedesktop.','org.kde.'); + +constructor tstatusnotifieritem.create(); +begin + inherited create(nil); +// checkdesktop(); +end; + +destructor tstatusnotifieritem.destroy(); +begin + inherited; + active:= false; + freeandnil(fservice); //in case of checkdesktop out of setactive +end; + +function tstatusnotifieritem.showmessage(const message: msestring; + const title: msestring; + out messageid: card32; const timeoutms: card32 = 0): boolean; +var + s1,s2,s3: string; + c1: card32; + p1: pointer; +begin + inc(fmessageid); + s1:= getid; + s2:= stringtoutf8(title); + s3:= stringtoutf8(message); + if fmessageid = 0 then begin + inc(fmessageid); + end; + messageid:= fmessageid; + p1:= nil; + result:= fservice.dbuscallmethod('org.freedesktop.Notifications', + '/org/freedesktop/Notifications','org.freedesktop.Notifications', + 'Notify', + [variantvalue(s1),variantvalue(fmessageid), + variantvalue(''), + variantvalue(s2), + variantvalue(s3), + variantvalue(@p1,typeinfo(stringarty)), + variantvalue(@p1,typeinfo(dictentryarty),[vf_dict]), + variantvalue(int32(timeoutms))],[dbt_uint32],[@c1]); +end; + +function tstatusnotifieritem.cancelmessage( + const messageid: card32): boolean; +begin + result:= fservice.dbuscallmethod('org.freedesktop.Notifications', + '/org/freedesktop/Notifications','org.freedesktop.Notifications', + 'CloseNotification',[variantvalue(messageid)],[],[]); +end; + +const + categorynames: array[statusnotifiercategoryty] of string = ( + //snc_applicationstatus,snc_communications,snc_systemservices,snc_hardware + 'ApplicationStatus', 'Communications', 'SystemServices', 'Hardware'); + +function tstatusnotifieritem.getcategory: string; +begin + result:= categorynames[fstatuscategory]; +end; + +function tstatusnotifieritem.getid: string; +begin + fid1:= fid; + if fid1 = '' then begin + fid1:= stringtoutf8(application.applicationname); + end; + result:= fid1; +end; + +function tstatusnotifieritem.checkdesktop(): boolean; +var + b2: boolean; + desk1: desktopkindty; +begin + if fservice = nil then begin + fservice:= tdbusservice.create(); + try + if fservice.connect() then begin + for desk1:= desktopkindty(1) to high(desk1) do begin + if fservice.dbusgetproperty(interfacestart[desk1]+'StatusNotifierWatcher', + '/StatusNotifierWatcher',interfacestart[desk1]+'StatusNotifierWatcher', + 'IsStatusNotifierHostRegistered',[dbt_boolean],[@b2]) then begin + if b2 then begin + fdesktopkind:= desk1; + break; + end; + end; + end; + end; + if fdesktopkind = desk_none then begin + fservice.destroy(); + fservice:= nil; + end; + except + fservice.destroy; + fservice:= nil; + raise; + end; + end; + result:= fservice <> nil; +end; + +procedure tstatusnotifieritem.setactive(const avalue: boolean); +begin + if avalue <> factive then begin + if factive then begin + fservice.destroy; + fservice:= nil; + factive:= false; + end + else begin + if checkdesktop() then begin + factive:= true; + fservice.registerobject(idbusobject(self)); + end; + end; + end; +end; + +function tstatusnotifieritem.getintrospectitems(): string; +begin + result:= inherited getintrospectitems() + + datadef1+getpropintf()+datadef2; +end; + +function tstatusnotifieritem.getpath(): string; +begin + result:= inherited getpath()+'StatusNotifierItem'; +end; + +procedure tstatusnotifieritem.busconnected(); +var + s1: string; +begin + inherited; +// s1:= fservice.dbusname; + s1:= fservice.dbusid; + if not fservice.dbuscallmethod( + interfacestart[fdesktopkind]+'StatusNotifierWatcher', + '/StatusNotifierWatcher', + interfacestart[fdesktopkind]+'StatusNotifierWatcher', + 'RegisterStatusNotifierItem',variantvalue(s1),[],[]) then begin + end; +end; + +procedure tstatusnotifieritem.propertiesget(var props: dictentryarty); +begin + setlength(props,1); + with props[0] do begin + name:= 'ToolTip'; + setvariantvalue(@ftooltip,itemtypeinfo(typeinfo(tooltipinfoarty)), + value,[vf_var]); + end; +end; + +procedure tstatusnotifieritem.propertyget(const amessage: pdbusmessage; + const aname: string; var avalue: variantvaluety); +begin + if aname = 'ToolTip' then begin + setvariantvalue(@ftooltip,itemtypeinfo(typeinfo(tooltipinfoarty)), + avalue,[vf_var]); + end; +end; + +function tstatusnotifieritem.getpropintf: string; +begin + result:= interfacestart[fdesktopkind]+'StatusNotifierItem'; +end; + +procedure tstatusnotifieritem.registeritems(const sender: idbusservice); +begin + inherited; + sender.registermethodhandler(getpropintf(), + 'ContextMenu',[dbt_int32,dbt_int32],@contextmenu,nil); + sender.registermethodhandler(getpropintf(), + 'Activate',[dbt_int32,dbt_int32],@activate,nil); + sender.registermethodhandler(getpropintf(), + 'SecondaryActivate',[dbt_int32,dbt_int32],@secondaryactivate,nil); + sender.registermethodhandler(getpropintf(), + 'Scroll',[dbt_int32,dbt_string],@scroll,nil); +end; + +procedure tstatusnotifieritem.receiveevent(const event: tobjectevent); +begin + inherited; + if (event.kind = ek_objectdata) and (event is tpointobjectevent) and + assigned(foncontextmenu) then begin + foncontextmenu(self,tpointobjectevent(event).data); + end; +end; + +procedure tstatusnotifieritem.contextmenu(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + x,y: int32; +begin + if fservice.dbusreadmessage(amessage,[dbt_int32,dbt_int32],[@x,@y]) then begin + application.postevent(tpointobjectevent.create(mp(x,y),ievent(self))); + //deadlock in dbus library if called directly because of modal call + fservice.dbusreply(amessage,[]); + ahandled:= true; + end +end; + +procedure tstatusnotifieritem.activate(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + x,y: int32; +begin + if fservice.dbusreadmessage(amessage,[dbt_int32,dbt_int32],[@x,@y]) then begin + fservice.dbusreply(amessage,[]); + if assigned(fonactivate) then begin + fonactivate(self,mp(x,y)); + end; + ahandled:= true; + end +end; + +procedure tstatusnotifieritem.secondaryactivate(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + x,y: int32; +begin + if fservice.dbusreadmessage(amessage,[dbt_int32,dbt_int32],[@x,@y]) then begin + fservice.dbusreply(amessage,[]); + if assigned(fonsecondaryactivate) then begin + fonsecondaryactivate(self,mp(x,y)); + end; + ahandled:= true; + end +end; + +procedure tstatusnotifieritem.scroll(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + delta: int32; + orientation: string; +begin + if fservice.dbusreadmessage(amessage,[dbt_int32,dbt_string], + [@delta,@orientation]) then begin + fservice.dbusreply(amessage,[]); + ahandled:= true; + end +end; + +procedure tstatusnotifieritem.setId(const avalue: string); +begin + fid:= avalue; +end; + +procedure tstatusnotifieritem.setTitle(const avalue: string); +begin + ftitle:= avalue; + propchangesignal('NewTitle'); +end; + +procedure tstatusnotifieritem.setStatus(const avalue: string); +begin + fstatus:= avalue; + if (fservice <> nil) and fservice.connected then begin + fservice.dbussignal(rootpath(),getpropintf(),'NewStatus', + variantvalue(fstatus)); + end; +end; + +procedure tstatusnotifieritem.setWindowId(const avalue: int32); +begin + fwindowid:= avalue; +end; + +procedure tstatusnotifieritem.setIconName(const avalue: string); +begin + ficonname:= avalue; + propchangesignal('NewIcon'); +end; + +procedure tstatusnotifieritem.setIconPixmap(const avalue: tmaskedbitmap); +var + ar1: iconpixmaparty; +begin + ar1:= nil; + if (avalue <> nil) and avalue.hasimage() then begin + setlength(ar1,1); + ar1[0]:= bitmaptoiconpixmap(avalue); + end; + seticonpixmap(ar1); +end; + +procedure tstatusnotifieritem.setIconPixmap(const avalue: iconpixmaparty); +begin + ficonpixmap:= avalue; + propchangesignal('NewIcon'); +end; + +procedure tstatusnotifieritem.setOverlayIconName(const avalue: string); +begin + foverlayiconname:= avalue; + propchangesignal('NewOverlayIcon'); +end; + +procedure tstatusnotifieritem.setOverlayIconPixmap( + const avalue: iconpixmaparty); +begin + foverlayiconpixmap:= avalue; + propchangesignal('NewOverlayIcon'); +end; + +procedure tstatusnotifieritem.setAtentionIconName(const avalue: string); +begin + fatentioniconname:= avalue; + propchangesignal('NewAttentionIcon'); +end; + +procedure tstatusnotifieritem.setAtentionIconPixmap( + const avalue: iconpixmaparty); +begin + fatentioniconpixmap:= avalue; + propchangesignal('NewAttentionIcon'); +end; + +procedure tstatusnotifieritem.setAtentionMovieName(const avalue: string); +begin + fatentionmoviename:= avalue; +end; + +procedure tstatusnotifieritem.setToolTip(const avalue: tooltipinfoty); +begin + ftooltip:= avalue; + propchangesignal('NewToolTip'); +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msestatussnotifieritem.pas b/mseide-msegui/lib/common/sysutils/msestatussnotifieritem.pas new file mode 100644 index 0000000..08193b9 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msestatussnotifieritem.pas @@ -0,0 +1,99 @@ + { MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msestatussnotifieritem; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msedbusinterface; +type + tstatusnotifieritem = class(tdbusobject) + protected + function getintrospectitems(): string virtual; + end; + +implementation + +const + datadef = +''+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +''+lineend; + +{ tstatusnotifieritem } + +function tstatusnotifieritem.getintrospectitems(): string; +begin + result:= datadef; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msestrmacros.pas b/mseide-msegui/lib/common/sysutils/msestrmacros.pas new file mode 100644 index 0000000..c1c8d58 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msestrmacros.pas @@ -0,0 +1,98 @@ +{ MSEgui Copyright (c) 2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} + +unit msestrmacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msemacros; + +function strmacros(): macroinfoarty; + +implementation +uses + mseprocess,mseprocutils,msefileutils,msetypes{msestrings},sysutils; + +var + fstrmacros: macroinfoarty; + +function strmacros(): macroinfoarty; +begin + result:= fstrmacros; +end; + +function str_trim(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= trim(sender.expandmacros(params[0])); + end; +end; + +function str_trimleft(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= trimleft(sender.expandmacros(params[0])); + end; +end; + +function str_trimright(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= trimright(sender.expandmacros(params[0])); + end; +end; + +function str_coalesce(const sender: tmacrolist; + const params: msestringarty): msestring; +var + i1: int32; +begin + result:= ''; + if params <> nil then begin + for i1:= 0 to high(params) do begin + result:= sender.expandmacros(params[i1]); + if result <> '' then begin + break; + end; + end; + end; +end; + +const + strmacroconst: array[0..3] of macroinfoty = ( + (name: 'STR_TRIM'; value: ''; handler: macrohandlerty(@str_trim); + expandlevel: 0), + (name: 'STR_TRIMLEFT'; value: ''; handler: macrohandlerty(@str_trimleft); + expandlevel: 0), + (name: 'STR_TRIMRIGHT'; value: ''; handler: macrohandlerty(@str_trimright); + expandlevel: 0), + (name: 'STR_COALESCE'; value: ''; handler: macrohandlerty(@str_coalesce); + expandlevel: 0) + ); + +procedure initexecmacros(); +var + int1: integer; +begin + setlength(fstrmacros,length(strmacroconst)); + for int1:= 0 to high(strmacroconst) do begin + fstrmacros[int1]:= strmacroconst[int1]; + end; +end; + +initialization + initexecmacros(); +end. diff --git a/mseide-msegui/lib/common/sysutils/msesysdnd.pas b/mseide-msegui/lib/common/sysutils/msesysdnd.pas new file mode 100644 index 0000000..8300dba --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msesysdnd.pas @@ -0,0 +1,194 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesysdnd; +//under construction + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + mseevent,msetypes,msegraphutils,mseguiglob,msedragglob,msedrag,msestrings, + msemime,mseglob,msegui; + +type + + tsysdndevent = class(twindowevent) + private + public + fformats: msestringarty; + fformatistext: booleanarty; + fpos: pointty; + fshiftstate: shiftstatesty; + fscroll: boolean; + fdndkind: drageventkindty; + factions: dndactionsty; + constructor create(const adndkind: drageventkindty; + const awinid: winidty; const apos: pointty; + const ashiftstate: shiftstatesty; const ascroll: boolean; + const aformats: msestringarty; + const aformatistext: booleanarty; + const aactions: dndactionsty); + end; + + tsysdndstatusevent = class(tobjectevent) + private + faccept: boolean; + public + constructor create(const aintf: ievent; const aaccept: boolean); + property accept: boolean read faccept; + end; + + tsysmimedragobject = class(tmimedragobject,isysdnd) + private + protected + procedure checkwritable; + procedure setdata(const avalue: string); override; + procedure settext(const avalue: msestring); override; + function getdata: string; override; + function gettext: msestring; override; + procedure cancelsysdnd; virtual; + //isysdnd + function getformats: msestringarty; + function getformatistext: booleanarty; + function getactions: dndactionsty; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); override; + constructor createwrite(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); + end; + +implementation +uses + msearrayutils,mseguiintf,sysutils; + +{ tsysdndevent } + +constructor tsysdndevent.create(const adndkind: drageventkindty; + const awinid: winidty; const apos: pointty; + const ashiftstate: shiftstatesty; const ascroll: boolean; + const aformats: msestringarty; const aformatistext: booleanarty; + const aactions: dndactionsty); +begin + fdndkind:= adndkind; + fpos:= apos; + fshiftstate:= ashiftstate; + fscroll:= ascroll; + fformats:= aformats; + fformatistext:= aformatistext; + factions:= aactions; + inherited create(ek_sysdnd,awinid); +end; + +{ tsysmimedragobject } + +constructor tsysmimedragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); +begin + fsysdndintf:= isysdnd(self); + include(fstate,dos_sysdnd); + inherited create(asender,instance,apickpos,aformats,aformatistext, + aactions,aintf); +end; + +constructor tsysmimedragobject.createwrite(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); +begin + include(fstate,dos_sysdnd); + inherited createwrite(asender,instance,apickpos,aformats,aformatistext, + aactions,aintf); +end; + +function tsysmimedragobject.getdata: string; +begin + if dos_write in fstate then begin + result:= inherited getdata; + end + else begin + result:= ''; + gui_sysdndreaddata(result,formatindex); +// guierror(gui_sysdndreaddata(result,typeindex),'Can not read sysdnd data.'); + end; +end; + +function tsysmimedragobject.gettext: msestring; +begin + if dos_write in fstate then begin + result:= inherited gettext; + end + else begin + result:= ''; + gui_sysdndreadtext(result,formatindex); +// guierror(gui_sysdndreadtext(result,typeindex),'Can not read sysdnd text.'); + end; +end; + +procedure tsysmimedragobject.checkwritable; +begin + if not (dos_write in fstate) then begin + raise exception.create('Dragobject is readonly'); + end; +end; + +procedure tsysmimedragobject.setdata(const avalue: string); +begin + checkwritable; + inherited; +end; + +procedure tsysmimedragobject.settext(const avalue: msestring); +begin + checkwritable; + inherited; +end; + +procedure tsysmimedragobject.cancelsysdnd; +begin + destroy; +end; + +function tsysmimedragobject.getformats: msestringarty; +begin + result:= formats; +end; + +function tsysmimedragobject.getformatistext: booleanarty; +begin + result:= fformatistext; +end; + +function tsysmimedragobject.getactions: dndactionsty; +begin + result:= factions; +end; + +{ tsysdndstatusevent } + +constructor tsysdndstatusevent.create(const aintf: ievent; + const aaccept: boolean); +begin + faccept:= aaccept; + inherited create(ek_sysdndstatus,aintf); +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msesysenv.pas b/mseide-msegui/lib/common/sysutils/msesysenv.pas new file mode 100644 index 0000000..fa1936d --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msesysenv.pas @@ -0,0 +1,1349 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesysenv; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msestat,msestatfile,mseclasses,msetypes, + msestrings,msedatalist,sysutils, + mselist,msearrayutils,msemacros; + +const + commandlineparchar = '-'; + defaulterrorcode = 1; + +type + argumentkindty = (ak_none, + ak_envvar, //environement variable z.b. 'PATH' + ak_par, //commandlineparameter + //z.b. '-v', '--help' + ak_pararg, //commandlineparameter mit argument + //z.b. '-vabc', '-v abc', '-v "abc def" + // '--file=abc' + ak_arg //commandline argument, name muss '' sein, + // z.b. 'abc', '"abc def"' + ); + + argumentkindsty = set of argumentkindty; +const + at_pars = [ak_par,ak_pararg]; + +type + sysenverrornrty = (ern_io,ern_user,ern_invalidparameter,ern_missedargument,ern_invalidargument, + ern_ambiguousparameter,ern_invalidinteger,ern_mandatoryparameter); +const + errtexte: array[sysenverrornrty] of msestring = ('','', + 'Invalid parameter','Missed argument','Invalid argument','Ambiguous parameter', + 'Invalid integer','Parameter mandatory'); +type + argumentflagty = (arf_envdefined, // wert aus env. gesetzt 0 + arf_statdefined, // wert aus statfile. gesetzt 1 + arf_setdefined, // wert aus programm gesetzt 2 + arf_res1, //3 + arf_res2, //4 + arf_res3, //5 + arf_res4, //6 + arf_mandatory, // obligatorisch //7 + arf_argopt, // argument optional //8 + arf_filenames, // argument wird durch pathsep //9 + // gesplitted + arf_statoverride, // wert wird durch statfile //10 + // ueberschrieben + // ev. auch geloescht + arf_stataddval, // wert wird von statfile //11 + // geschrieben falls + // noch nicht gesetzt + arf_unquote, //unquote argument value //12 + arf_integer, //fuer arg und pararg //13 + arf_help //print help and terminate //14 + ); + + argumentflagsty = set of argumentflagty; + + sysenvoptionty = (seo_appterminateonexception,seo_terminateonerror, + seo_haltonerror,seo_exceptiononerror,seo_exitoninfo, + seo_noerrormess, + seo_tooutput, //info -> outputpipe + seo_toerror, //errormeldung -> errorpipe + seo_noautoinit //no call of init in loaded() + ); + sysenvoptionsty = set of sysenvoptionty; + +const + arf_defined = [arf_envdefined,arf_statdefined,arf_setdefined]; + defaultsysenvmanageroptions = [seo_tooutput,seo_toerror]; + +type + ehalt = class(exception); + + argumentdefty = record + kind: argumentkindty; + name: msestring; //case sensitive, single char -> + // short parameter 'a' 'b' -> '-a' '-b' or '-ab' or '-ba', + // '-abcde' -> '--abcde' + anames: pmsestring;//pointer auf array[0..0] of string alias, + //letzter string muss leer sein ('abc','def',''); + flags: argumentflagsty; + initvalue: msestring; + end; + + pargumentdefty = ^argumentdefty; + argumentdefaty = array [0..0] of argumentdefty; + pargumentdefaty = ^argumentdefaty; + argumentdefarty = array of argumentdefty; + + envvarty = record + flags: argumentflagsty; + values: msestringarty; + name: msestring; + end; + penvvarty = ^envvarty; + envvararty = array of envvarty; + + tsysenvmanager = class; + sysenvmanagereventty = procedure(sender: tsysenvmanager) of object; + + sysenvmanagervalueeventty = procedure(sender: tsysenvmanager; + const index: integer; var defined: boolean; + var argument: msestringarty; var error: sysenverrornrty) of object; + + sysenvdefty = record + kind: argumentkindty; + name: msestring; + anames: msestringarty; + flags: argumentflagsty; + initvalue: msestring; + argument: msestring; + before: msestring; + help: msestring; + after: msestring; + end; + psysenvdefty = ^sysenvdefty; + sysenvdefarty = array of sysenvdefty; + + tsysenvmanager = class(tmsecomponent,istatfile) + private + foninit: sysenvmanagereventty; + fenvvars: envvararty; + foptions: sysenvoptionsty; + ferrorcode: integer; + fstatfile: tstatfile; + fstatvarname: msestring; + fonvalueread: sysenvmanagervalueeventty; + fdefs: sysenvdefarty; + fhelpheader: msestring; + fhelpfooter: msestring; + fonafterinit: sysenvmanagereventty; + fstatpriority: integer; + ferrorcount: int32; + procedure setoninit(const Value: sysenvmanagereventty); + procedure doinit; + procedure errorme(nr: sysenverrornrty; value: msestring); + procedure checkindex(index: integer); + function getdefined(index: integer): boolean; + function getvalue(index: integer): msestring; + function getvalues(index: integer): msestringarty; + procedure setstatfile(const Value: tstatfile); + function dovalueread(const index: integer; + var defined: boolean; var value: msestringarty): sysenverrornrty; + procedure setdefined(index: integer; const Value: boolean); + procedure setvalue(index: integer; const Value: msestring); + procedure setvalues(index: integer; const Value: msestringarty); + function setdef(index: integer; avalue: msestringarty; + adefined: argumentflagsty): sysenverrornrty; overload; + function setdef(index: integer; avalue: msestring; + adefined: argumentflagsty): sysenverrornrty; overload; + function getintegervalue1(index: integer): integer; + procedure setintegervalue(index: integer; const Value: integer); + procedure setdefs(const avalue: sysenvdefarty); + procedure readdefs(reader: treader); + procedure writedefs(writer: twriter); +// procedure readinitvalues(reader: treader); +// procedure writeinitvalues(writer: twriter); +// procedure readhelps(reader: treader); +// procedure writehelps(writer: twriter); + procedure setoptions(const avalue: sysenvoptionsty); + function getdefcount: int32; + protected + procedure loaded; override; + procedure defineproperties(filer: tfiler); override; + //istatfiler + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + function init(const arguments: array of argumentdefty; + const values: msestringarty): boolean; + //true if ok + function init(const arguments: array of argumentdefty): boolean; + //use commandline values + function init(const values: msestringarty): boolean; //use defs + function init(): boolean; //use defs and commandline values + + procedure processinfo(index: integer; value: string); + procedure errormessage(const mess: msestring); + procedure printmessage(value: msestring); + procedure printhelp; + function getcommandlinemacros(const macrodef: integer; + const firstenvvarmacro: integer = -1; + const lastenvvarmacro: integer = -1; + prepend: macroinfoarty = nil): macroinfoarty; + property errorcount: int32 read ferrorcount; + property defined[index: integer]: boolean read getdefined + write setdefined; default; + property objectlinker: tobjectlinker read getobjectlinker + {$ifdef msehasimplements}implements istatfile{$endif}; + property values[index: integer]: msestringarty + read getvalues write setvalues; + property value[index: integer]: msestring read getvalue write setvalue; + //bringt letzten string in array + property integervalue[index: integer]: integer read getintegervalue1 + write setintegervalue; + //bringt letzten string in array als integer + function getintegervalue(var avalue: integer; const index: integer; + const min: integer = minint; + const max: integer = maxint): boolean; + //false if not defined or not in range + function findfirstfile(filename: filenamety; + searchinvars: array of integer): filenamety; + //bringt erstes filevorkommen + function findlastfile(filename: filenamety; + searchinvars: array of integer): filenamety; + //bringt letztes filevorkommen + property defs: sysenvdefarty read fdefs write setdefs; + property defcount: int32 read getdefcount; + published + property options: sysenvoptionsty read foptions write setoptions + default defaultsysenvmanageroptions; + property errorcode: integer read ferrorcode write ferrorcode + default defaulterrorcode; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property helpheader: msestring read fhelpheader write fhelpheader; + property helpfooter: msestring read fhelpfooter write fhelpfooter; + + property onvalueread: sysenvmanagervalueeventty read fonvalueread + write fonvalueread; + property oninit: sysenvmanagereventty read foninit write setoninit; + property onafterinit: sysenvmanagereventty read fonafterinit + write fonafterinit; + end; + +procedure defstoarguments(const defs: sysenvdefarty; + out arguments: argumentdefarty; out alias: msestringararty); + +implementation +uses + msesysutils,RTLConsts,msestream,msesys{$ifdef UNIX},mselibc{$endif}, + typinfo,mseapplication,msebits,msesysintf,mseformatstr,msefileutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure defstoarguments(const defs: sysenvdefarty; + out arguments: argumentdefarty; out alias: msestringararty); +var + int1,int2: integer; + d: psysenvdefty; +begin + setlength(arguments,length(defs)); + setlength(alias,length(defs)); + for int1:= 0 to high(defs) do begin + d:= @defs[int1]; + with arguments[int1] do begin + kind:= d^.kind; + name:= d^.name; + setlength(alias[int1],length(d^.anames)); + for int2:= 0 to high(d^.anames) do begin + alias[int1][int2]:= d^.anames[int2]; + end; + if alias[int1] <> nil then begin + setlength(alias[int1],high(alias[int1])+2); //end marker + end; + anames:= pointer(alias[int1]); + flags:= d^.flags; + initvalue:= d^.initvalue; +// argument:= d^.argument; +// help:= d^.help; + end; + end; +end; + +{ +procedure defstoarguments(const defs: msestring; + out arguments: argumentdefarty; out alias: stringararty); +var + ar1,ar2: msestringarty; + int1: integer; +begin + ar1:= breaklines(defs); + setlength(arguments,length(ar1)); + setlength(alias,length(ar1)); + for int1:= 0 to high(ar1) do begin + splitstringquoted(ar1[int1],ar2,'"',','); + setlength(ar2,5); //max + with arguments[int1] do begin + kind:= argumentkindty(checkenumvalue(typeinfo(argumentkindty),ar2[0])); + name:= ar2[1]; + splitstringquoted(ar2[2],alias[int1]); + if alias[int1] <> nil then begin + setlength(alias[int1],high(alias[int1])+2); + end; + anames:= pointer(alias[int1]); + flags:= argumentflagsty(stringtoset( + ptypeinfo(typeinfo(argumentflagsty)),ar2[3])); + initvalue:= ar2[4]; + end; + end; +end; +} + +{ tsysenvmanager } + +constructor tsysenvmanager.create(aowner: tcomponent); +begin + ferrorcode:= defaulterrorcode; + foptions:= defaultsysenvmanageroptions; + inherited; +end; + +procedure tsysenvmanager.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +function tsysenvmanager.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tsysenvmanager.dostatread(const reader: tstatreader); +var + int1,int2: integer; + strar1: msestringarty; + aflags: argumentflagsty; +begin + strar1:= nil; + with reader do begin + int1:= readinteger('envvars',0,0,maxint); + for int1:= 0 to int1-1 do begin + int2:= readinteger(arrayname('flags',int1)); + strar1:= readarray(arrayname('values',int1),msestringarty(nil)); + aflags:= argumentflagsty({$ifdef FPC}longword{$else}word{$endif}(int2)); + if int1 < length(fenvvars) then begin + with fenvvars[int1] do begin + if aflags * arf_defined <> [] then begin + aflags:= aflags - arf_defined + [arf_statdefined]; + end + else begin + aflags:= aflags - arf_defined; + end; + if arf_statoverride in flags then begin + setdef(int1,strar1,flags); + end + else begin + if (arf_stataddval in flags) and not (arf_envdefined in flags) and + (arf_statdefined in aflags) then begin + setdef(int1,strar1,aflags); + end; + end; + end; + end; + end; + end; +end; + +procedure tsysenvmanager.statreading; +begin + //dummy +end; + +procedure tsysenvmanager.statread; +begin + //dummy +end; + +procedure tsysenvmanager.dostatwrite(const writer: tstatwriter); +var + int1: integer; +begin + with writer do begin + writeinteger('envvars',length(fenvvars)); + for int1:= 0 to high(fenvvars) do begin + with fenvvars[int1] do begin + writeinteger('flags',{$ifdef FPC}longword{$else}word{$endif}(flags)); + writearray(arrayname('values',int1),values); +// writeln(word(flags)); +// writeln(values); + end; + end; + end; +end; + +procedure tsysenvmanager.checkindex(index: integer); +begin + if (index < 0) or (index >= length(fenvvars)) then begin + tlist.Error(SListIndexError, Index); + end; +end; + +procedure tsysenvmanager.doinit; +var + ar1: argumentdefarty; + ar2: msestringararty; +begin + if not (csdesigning in componentstate) then begin + if assigned(foninit) then begin + foninit(self); + end + else begin + if fdefs <> nil then begin + defstoarguments(fdefs,ar1,ar2); + init(ar1); + end; + end; + if assigned(fonafterinit) then begin + fonafterinit(self); + end; + end + else begin + if fdefs <> nil then begin + try + try + defstoarguments(fdefs,ar1,ar2); + except + on e: exception do begin + componentexception(self,msestring(e.message)); + end; + end; + except + application.handleexception + end; + end; + end; +end; + +procedure tsysenvmanager.errorme(nr: sysenverrornrty; value: msestring); +var + str1: string; +begin + if nr <> ern_io then begin + inc(ferrorcount); + if not (seo_noerrormess in foptions) then begin + if nr = ern_user then begin + str1:= ansistring(value); + end + else begin + str1:= ansistring(errtexte[nr] + ': '+value); + end; + if seo_toerror in foptions then begin + writestderr(str1,true); + end + else begin +// dispfehler(str1,'Parameter Error'); //!!!!todo + end; + end; + if seo_terminateonerror in foptions then begin + if ferrorcode <> 0 then begin + exitcode:= ferrorcode; + end; + application.terminated:= true; + end; + if seo_haltonerror in foptions then begin + halt(ferrorcode); + end; + if seo_exceptiononerror in foptions then begin + raise ehalt.Create(''); + end; + end; +end; + +procedure tsysenvmanager.errormessage(const mess: msestring); +begin + errorme(ern_user,mess); +end; + +procedure tsysenvmanager.printhelp; + + procedure printitem(const aitem: sysenvdefty{; const envvars: boolean}); + var + int2: integer; + mstr1: msestring; + ar1: msestringarty; + a0,a1: msestring; + begin + mstr1:= ''; + with aitem do begin + if name <> '' then begin + if (kind = ak_par) then begin +// if envvars then begin +// exit; +// end; + if name[1] <> '-' then begin + mstr1:= ' -'+name; + end + else begin + mstr1:= ' -'+name; + end; + if anames <> nil then begin + mstr1:= mstr1+','; + extendstring(mstr1,6); + for int2:= 0 to high(anames) do begin + mstr1:= mstr1+'-'+anames[int2]; + mstr1:= mstr1+','; + end; + setlength(mstr1,length(mstr1)-1); //remove last comma + end; + end + else begin + if (kind = ak_pararg) then begin +// if envvars then begin +// exit; +// end; + if arf_argopt in flags then begin + a0:= '['; + a1:= ']'; + end + else begin + a0:= ''; + a1:= ''; + end; + if name[1] <> '-' then begin + mstr1:= ' -'+name; + end + else begin + mstr1:= ' -'+name+a0+'='; + end; + mstr1:= mstr1+argument+a1; + if anames <> nil then begin + mstr1:= mstr1+','; + extendstring(mstr1,6); + for int2:= 0 to high(anames) do begin + if anames[int2] <> '' then begin + if anames[int2][1] = '-' then begin + mstr1:= mstr1+'-'+anames[int2]+a0+'='+argument+a1; + end + else begin + mstr1:= mstr1+'-'+anames[int2]+a0+argument+a1; + end; + end; + mstr1:= mstr1+','; + end; + setlength(mstr1,length(mstr1)-1); //remove last comma + end; + end + else begin + if {envvars and }(kind = ak_envvar) and (help <> '') then begin + mstr1:= ' '+name; + for int2:= 0 to high(anames) do begin + mstr1:= mstr1+','+anames[int2]; + end; + end + else begin + exit; + end; + end; + end; + end; + if help <> '' then begin + ar1:= breaklines(help); + if length(mstr1) < 29 then begin + extendstring(mstr1,29); + mstr1:= mstr1 + ar1[0]; + end + else begin + mstr1:= mstr1+lineend+charstring(msechar(' '),29)+ar1[0]; + end; + for int2:= 1 to high(ar1) do begin + mstr1:= mstr1+lineend+charstring(msechar(' '),29)+ar1[int2]; + end; + end; + if mstr1 <> '' then begin + if before <> '' then begin + writestderr(ansistring(before),true); + end; + writestderr(ansistring(mstr1),true); + if after <> '' then begin + writestderr(ansistring(after),true); + end; + end; + end; + end; + +var + int1: integer; + +begin + if fhelpheader <> '' then begin + writestderr(ansistring(fhelpheader),true); + end; + for int1:= 0 to high(fdefs) do begin + printitem(fdefs[int1]{,false}); + end; +{ + for int1:= 0 to high(fdefs) do begin + printitem(fdefs[int1],true); + end; +} + if fhelpfooter <> '' then begin + writestderr(ansistring(fhelpfooter),true); + end; +end; + +procedure tsysenvmanager.printmessage(value: msestring); +begin + if seo_tooutput in foptions then begin + value:= value+lineend; + writestdout(ansistring(value)); + end + else begin +// dispmessage(value); //!!!!todo + end; + if seo_exitoninfo in foptions then begin + halt(0); + end; +end; + +function tsysenvmanager.findfirstfile(filename: filenamety; + searchinvars: array of integer): filenamety; +var + int1,int2: integer; + index: integer; + str1: filenamety; +begin + result:= ''; + for int1:= 0 to high(searchinvars) do begin + index:= searchinvars[int1]; + checkindex(index); + for int2:= 0 to high(fenvvars[index].values) do begin + str1:= fenvvars[index].values[int2]; + if str1 <> '' then begin + str1:= includetrailingpathdelimiter(str1); + end; + str1:= str1 + filename; + if fileexists(str1) then begin + result:= str1; + exit; + end; + end; + end; +end; + +function tsysenvmanager.findlastfile(filename: filenamety; + searchinvars: array of integer): filenamety; +var + int1,int2: integer; + index: integer; + str1: filenamety; +begin + result:= ''; + for int1:= high(searchinvars) downto 0 do begin + index:= searchinvars[int1]; + checkindex(index); + for int2:= high(fenvvars[index].values) downto 0 do begin + str1:= fenvvars[index].values[int2]; + if str1 <> '' then begin + str1:= includetrailingpathdelimiter(str1); + end; + str1:= str1 + filename; + if fileexists(str1) then begin + result:= str1; + exit; + end; + end; + end; +end; + +function tsysenvmanager.getdefined(index: integer): boolean; +begin + checkindex(index); + result:= fenvvars[index].flags * arf_defined <> []; +end; + +procedure tsysenvmanager.setdefined(index: integer; + const Value: boolean); +begin + checkindex(index); + if value then begin + fenvvars[index].flags:= fenvvars[index].flags + [arf_setdefined]; + end + else begin + fenvvars[index].flags:= fenvvars[index].flags - arf_defined; + end; +end; + +function tsysenvmanager.getvalue(index: integer): msestring; +begin + checkindex(index); + if length(fenvvars[index].values) = 0 then begin + result:= ''; + end + else begin + result:= fenvvars[index].values[high(fenvvars[index].values)]; + end; +end; + +procedure tsysenvmanager.setvalue(index: integer; const Value: msestring); +var + strar: msestringarty; +begin + checkindex(index); + setlength(strar,1); + strar[0]:= value; + setvalues(index,strar); +end; + +function tsysenvmanager.getvalues(index: integer): msestringarty; +begin + checkindex(index); + result:= fenvvars[index].values; +end; + +procedure tsysenvmanager.setvalues(index: integer; + const Value: msestringarty); +begin + checkindex(index); + fenvvars[index].values:= value; + setdefined(index,true); +end; + +function tsysenvmanager.dovalueread(const index: integer; + var defined: boolean; var value: msestringarty): sysenverrornrty; +begin + result:= ern_io; + if assigned(fonvalueread) then begin + fonvalueread(self,index,defined,value,result); + end; +end; + +function tsysenvmanager.setdef(index: integer; avalue: msestringarty; + adefined: argumentflagsty): sysenverrornrty; +var + strar1: msestringarty; + int1,int2: integer; + bo1: boolean; + i1: int32; +begin + result:= ern_io; + if index >= 0 then begin + bo1:= adefined <> []; + result:= dovalueread(index,bo1,avalue); + if not bo1 then begin + adefined:= adefined - arf_defined; + end; + adefined:= adefined * arf_defined; + + with fenvvars[index] do begin + if flags * arf_defined = [] then begin + {$ifdef FPC} + setlength(values,0); //values:= nil; -> av! + {$else} + values:= nil; //initvalue entfernen + {$endif} + end; + if adefined = [] then begin + flags:= flags - arf_defined; + end + else begin + flags:= flags + adefined; + end; + if result = ern_io then begin + if arf_filenames in flags then begin + for int1:= 0 to high(avalue) do begin + splitstring(avalue[int1],strar1,pathsep); + stackarray(strar1,values); + end; + end + else begin + if arf_integer in flags then begin + for int1:= 0 to high(avalue) do begin + if not trystrtoint(avalue[int1],int2) then begin + result:= ern_invalidinteger; + break; + end; + end; + end; + if result = ern_io then begin + i1:= length(values); + stackarray(avalue,values); + if arf_unquote in flags then begin + for i1:= i1 to high(values) do begin + values[i1]:= unquotefilename(values[i1]); + end; + end; + end; + end; + end; + end; + end; +end; + +function tsysenvmanager.setdef(index: integer; avalue: msestring; + adefined: argumentflagsty): sysenverrornrty; +var + strar1: msestringarty; +begin + setlength(strar1,1); + strar1[0]:= avalue; + result:= setdef(index,strar1,adefined); +end; + +function tsysenvmanager.init(const arguments: array of argumentdefty; + const values: msestringarty): boolean; + +var + index: integer; + strar1: msestringarty; + + function finddef(typen: argumentkindsty; aname: msestring): integer; + + function checkname(const argumentdef: argumentdefty): boolean; + + function checkanames: boolean; + var + po1: pmsestring; + begin + result:= false; + po1:= argumentdef.anames; + if po1 <> nil then begin + while po1^ <> '' do begin + if msecomparestrlen(aname,po1^) = 0 then begin + result:= true; + exit; + end; + inc(po1); + end; + end; + end; //checkanames + + begin //checkname + with argumentdef do begin + result:= kind in typen; + if result then begin +// result:= (msecomparestrlen(aname,name) = 0) or checkanames; + result:= (aname = '') or (msecomparestrlen(name,aname) = 0) or + checkanames(); + end; + end; + end; + + var + int1,int2: integer; + begin + for int1:= 0 to high(arguments) do begin + if checkname(arguments[int1]) then begin + result:= int1; + for int2:= int1 + 1 to high(arguments) do begin + if checkname(arguments[int2]) then begin + errorme(ern_ambiguousparameter,strar1[index]); + result:= -2; + break; + end; + end; + exit; + end; + end; + result:= -1; + end; + + function isparameter(const str: msestring): boolean; + begin + result:= (length(str) > 0) and (str[1] = commandlineparchar); + end; + + procedure findswitch(str1: msestring); + var + pardefindex1: integer; + + procedure setoptargument; + var + needed: boolean; + begin + needed:= not (arf_argopt in arguments[pardefindex1].flags); + inc(index); + if index < length(strar1) then begin + if isparameter(strar1[index]) then begin + dec(index); + if needed then begin + errorme(ern_missedargument,strar1[index]); + end + else begin + errorme(setdef(pardefindex1,nil,[arf_envdefined]),strar1[index]); + end; + end + else begin + errorme(setdef(pardefindex1,strar1[index],[arf_envdefined]),strar1[index]); + end; + end + else begin + dec(index); + if needed then begin + errorme(ern_missedargument,strar1[index]); + end + else begin + errorme(setdef(pardefindex1,nil,[arf_envdefined]),strar1[index]); + end; + end; + end; + + procedure checkarguments; + begin + case arguments[pardefindex1].kind of + ak_pararg: begin + if length(str1) > 0 then begin + errorme(setdef(pardefindex1,str1,[arf_envdefined]),str1) + end + else begin + setoptargument; + end; + end; + ak_par: begin + errorme(setdef(pardefindex1,nil,[arf_envdefined]),str1); + if length(str1) > 0 then begin + findswitch(str1); + end; + end; + end; + end; + + var + strar2: msestringarty; + + begin //findswitch + if length(str1) > 0 then begin + if isparameter(str1) then begin //langer parameter + setlength(strar2,2); + splitstring(str1,strar2,'='); + pardefindex1:= finddef(at_pars,strar2[0]); + if pardefindex1 >= 0 then begin + with fenvvars[pardefindex1] do begin + case arguments[pardefindex1].kind of + ak_par: begin + if length(strar2) > 1 then begin + errorme(ern_invalidargument,strar1[index]); + end + else begin + include(flags,arf_envdefined); + end; + end; + ak_pararg: begin + if length(strar2) > 1 then begin + errorme(setdef(pardefindex1,strar2[1],[arf_envdefined]),strar1[index]); + end + else begin + setoptargument; + end; + end; + end; + end; + end + else begin + if pardefindex1 = -1 then begin + errorme(ern_invalidparameter,strar1[index]); + end; + end; + end + else begin + pardefindex1:= finddef(at_pars,str1); + if pardefindex1 < 0 then begin + pardefindex1:= finddef(at_pars,str1[1]); + if pardefindex1 >= 0 then begin + str1:= copy(str1,2,maxint); + checkarguments; + end + else begin + if pardefindex1 = -1 then begin + errorme(ern_invalidparameter,strar1[index]); + end; + end; + end + else begin + str1:= copy(str1,length(arguments[pardefindex1].name)+1,maxint); + checkarguments; + end; + end; + end + else begin + errorme(ern_invalidparameter,strar1[index]); + end; + end; + +var + i1: integer; + str1: msestring; +// {$ifdef UNIX} +// po1: pchar; +// {$endif} +begin //init + ferrorcount:= 0; + if high(arguments) = -1 then begin + exit; + end; + setlength(fenvvars,high(arguments)+1); + for i1:= 0 to high(fenvvars) do begin + with fenvvars[i1] do begin + flags:= arguments[i1].flags; + name:= arguments[i1].name; + setlength(values,1); + values[0]:= arguments[i1].initvalue; + end; + end; + strar1:= values; + index:= 0; + while index < length(strar1) do begin + str1:= strar1[index]; + if isparameter(str1) then begin + str1:= copy(str1,2,maxint); + findswitch(str1); + end + else begin + i1:= finddef([ak_arg],''); + if i1 >= 0 then begin + errorme(setdef(i1,str1,[arf_envdefined]),str1); + end + else begin + errorme(ern_invalidargument,str1); + end; + end; + inc(index); + end; + for i1:= 0 to high(arguments) do begin + if (arf_help in arguments[i1].flags) and + (fenvvars[i1].flags * arf_defined <> []) then begin + printhelp; + application.terminated:= true; + exit; + end; + end; + for i1:= 0 to high(arguments) do begin + with arguments[i1] do begin + if kind = ak_envvar then begin + {$ifdef mswindows} + str1:= + {$ifdef FPC}sysutils.{$endif}getenvironmentvariable(name); + //!!!! delphi bug flicken(info in qc)!! + if str1 <> '' then begin +// errorme(setdef(int1,str1,true),name); + errorme(setdef(i1,str1,[arf_envdefined]),name); + end; + {$else} +{ + po1:= getenv(pchar(name)); + if po1 <> nil then begin + errorme(setdef(int1,po1,[arf_envdefined]),name); + end; +} + if sys_getenv(name,str1) then begin + errorme(setdef(i1,str1,[arf_envdefined]),name); + end; + {$endif}; + end; + if (arf_mandatory in flags) and not defined[i1] then begin + str1:= ''; + if not (kind in [ak_arg]) then begin + str1:= '-'; + end; + errorme(ern_mandatoryparameter,str1+name); + end; + end; + end; + result:= ferrorcount = 0; +end; + +function tsysenvmanager.init(const arguments: array of argumentdefty): boolean; +var + ar1: msestringarty; +begin + ar1:= getcommandlinearguments(); + if high(ar1) > 0 then begin + //FPC 2.6.4 throws an exception in copy() if out of range + result:= init(arguments,copy(ar1,1,bigint)); + end + else begin + result:= init(arguments,nil); + end; +end; + +function tsysenvmanager.init(const values: msestringarty): boolean; //use defs +var + ar1: argumentdefarty; + ar2: msestringararty; +begin + defstoarguments(fdefs,ar1,ar2); + result:= init(ar1,values); +end; + +function tsysenvmanager.init(): boolean; //use defs and commandline values +begin + result:= init(copy(getcommandlinearguments(),1,bigint)); +end; + +procedure tsysenvmanager.processinfo(index: integer; value: string); +begin + if defined[index] then begin + printmessage(msestring(value)); + end; +end; + +procedure tsysenvmanager.setoninit(const Value: sysenvmanagereventty); +begin + foninit := Value; + if not (csloading in componentstate) then begin + doinit(); + end; +end; + +procedure tsysenvmanager.loaded; +begin + inherited; + if not (seo_noautoinit in foptions) then begin + doinit(); + end; +end; + +procedure readdefdata(const reader: treader; var data); +begin + with sysenvdefty(data) do begin + ord(kind):= reader.readenum(typeinfo(kind)); + name:= reader.readunicodestring; + readstringar(reader,anames); + longword(flags):= reader.readset(typeinfo(flags)); + initvalue:= reader.readunicodestring; + argument:= reader.readunicodestring; + help:= reader.readunicodestring; + before:= reader.readunicodestring; + after:= reader.readunicodestring; + end; +end; + +procedure tsysenvmanager.readdefs(reader: treader); +var + ar1: sysenvdefarty; +begin + ar1:= nil; //compiler warning + readrecordar(reader,ar1,typeinfo(ar1),@readdefdata); + defs:= ar1; +end; + +procedure writedefdata(const writer: twriter; const data); +begin + with sysenvdefty(data) do begin + writer.writeenum(ord(kind),typeinfo(kind)); + writer.writeunicodestring(name); + writestringar(writer,anames); + writer.writeset(longword(flags),typeinfo(flags)); + writer.writeunicodestring(initvalue); + writer.writeunicodestring(argument); + writer.writeunicodestring(help); + writer.writeunicodestring(before); + writer.writeunicodestring(after); + end; +end; + +procedure tsysenvmanager.writedefs(writer: twriter); +begin + writerecordar(writer,fdefs,typeinfo(fdefs),@writedefdata); +end; +{ +procedure tsysenvmanager.readinitvalues(reader: treader); +begin +end; + +procedure tsysenvmanager.writeinitvalues(writer: twriter); +begin +end; + +procedure tsysenvmanager.readhelps(reader: treader); +begin +end; + +procedure tsysenvmanager.writehelps(writer: twriter); +begin +end; +} +procedure tsysenvmanager.defineproperties(filer: tfiler); + + function needswritedefs: boolean; + var + po1: psysenvdefty; + int1,int2: integer; + begin + with tsysenvmanager(filer.ancestor) do begin + result:= high(fdefs) <> high(self.fdefs); + if not result then begin + for int1:= 0 to high(fdefs) do begin + po1:= @self.fdefs[int1]; + with fdefs[int1] do begin + result:= high(anames) <> high(po1^.anames); + if not result then begin + for int2:= 0 to high(anames) do begin + if anames[int2] <> po1^.anames[int2] then begin + result:= true; + break; + end; + end; + if not result then begin + result:= + (kind <> po1^.kind) or + (name <> po1^.name) or + (flags <> po1^.flags) or + (initvalue <> po1^.initvalue) or + (argument <> po1^.argument) or + (help <> po1^.help); + end; + end; + end; + if result then begin + break; + end; + end; + end; + end; + end; + +begin + inherited; + filer.defineproperty('defs',@readdefs,@writedefs, + (filer.ancestor = nil) and (fdefs <> nil) or + (filer.ancestor <> nil) and needswritedefs); +// filer.defineproperty('default',@readinitvalues,@writeinitvalues,fdefs <> nil); +// filer.defineproperty('help',@readhelps,@writehelps,fdefs <> nil); +end; + +function tsysenvmanager.getintegervalue1(index: integer): integer; +begin + result:= strtoint(getvalue(index)); +end; + +function tsysenvmanager.getintegervalue(var avalue: integer; const index: integer; + const min: integer = minint; const max: integer = maxint): boolean; + //false if not defined or not in range +var + int1: integer; +begin + result:= defined[index]; + if result then begin + int1:= integervalue[index]; + if (int1 < min) or (int1 > max) then begin + result:= false; + end + else begin + avalue:= int1; + end; + end; +end; + +procedure tsysenvmanager.setintegervalue(index: integer; + const Value: integer); +begin + setvalue(index,inttostrmse(value)); +end; + +function tsysenvmanager.getcommandlinemacros( + const macrodef: integer; + const firstenvvarmacro: integer = -1; const lastenvvarmacro: integer = -1; + prepend: macroinfoarty = nil): macroinfoarty; +var + ar1,ar2: msestringarty; + int1,int2,int3,int4: integer; + po1: penvvarty; +begin + result:= prepend; + checkindex(macrodef); + if (firstenvvarmacro >= 0) and (lastenvvarmacro >= 0) then begin + checkindex(firstenvvarmacro); + checkindex(lastenvvarmacro); + for int1:= ord(firstenvvarmacro) to ord(lastenvvarmacro) do begin + //envvar macros can be overridden by --macrodef + if defined[int1] then begin + setlength(result,high(result) + 2); + with result[high(result)] do begin + po1:= @fenvvars[int1]; + name:= po1^.name; + if po1^.values <> nil then begin + value:= po1^.values[high(po1^.values)]; + end; + end; + end; + end; + end; + ar1:= values[macrodef]; + for int1:= 0 to high(ar1) do begin + ar2:= nil; + splitstringquoted(ar1[int1],ar2,msechar('"'),msechar(',')); + if ar2 <> nil then begin + int3:= length(result); + int4:= (high(ar2)+2) div 2; //pair count + setlength(result,int3+int4); + for int2:= 0 to int4-1 do begin + with result[int2+int3] do begin + int4:= int2 * 2; + name:= ar2[int4]; + if int4 < high(ar2) then begin + value:= ar2[int4+1] + end; + end; + end; + end; + end; +end; + +procedure tsysenvmanager.setdefs(const avalue: sysenvdefarty); + +begin + fdefs:= avalue; + if not (csloading in componentstate) then begin + doinit; + end; +end; + +procedure tsysenvmanager.setoptions(const avalue: sysenvoptionsty); +begin + foptions:= sysenvoptionsty(setsinglebit(longword(avalue),longword(foptions), + longword([seo_terminateonerror,seo_haltonerror,seo_exceptiononerror]))); + if not (csdesigning in componentstate) and + (seo_appterminateonexception in avalue) then begin + application.options:= application.options + [apo_terminateonexception]; + end; +end; + +function tsysenvmanager.getdefcount: int32; +begin + result:= length(fdefs); +end; + +function tsysenvmanager.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +end. diff --git a/mseide-msegui/lib/common/unicode/mseunicode.pas b/mseide-msegui/lib/common/unicode/mseunicode.pas new file mode 100644 index 0000000..d833db1 --- /dev/null +++ b/mseide-msegui/lib/common/unicode/mseunicode.pas @@ -0,0 +1,287 @@ +unit mseunicode; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes{msestrings},msegraphics,msegraphutils,mseguiglob; + +type + + tunifont = class(tfont) + public + constructor create; override; + function hasglyph(const achar: unicharty): boolean; + function createfontwithglyph(const achar: unicharty): tunifont; + //nil if none exist + end; + unifontarty = array of tunifont; + + tunisubstfont = class(tunifont) + private + fbase: tunifont; + protected + function getfont(var drawinfo: drawinfoty): boolean; override; + function gethandle: fontnumty; override; + public + constructor create(const base: tunifont; const aglyph: unicharty); reintroduce; + end; + + unitextstatety = (uts_fontmatched); + unitextstatesty = set of unitextstatety; + + segmentinfoty = record + charindex: integer; //null based + fontnum: integer; //index in ffonts + end; + segmentinfoarty = array of segmentinfoty; + + tunitext = class + private + ffont: tunifont; + ftext: msestring; + fstate: unitextstatesty; + ffonts: unifontarty; + fsegments: segmentinfoarty; + procedure setfont(const avalue: tunifont); + procedure settext(const avalue: msestring); + procedure freefonts; + protected + procedure fontchanged(const sender: tobject); + procedure changed; + procedure checkstate; + procedure matchfonts; + public + constructor create(const atext: msestring = ''; const afont: tfont = nil); + //afont = nil -> stf_unicode + destructor destroy; override; + procedure drawstring(const acanvas: tcanvas; const apos: pointty; + const grayed: boolean = false); + property font: tunifont read ffont write setfont; + property text: msestring read ftext write settext; + end; + +procedure unidrawstring(const acanvas: tcanvas; const atext: msestring; + const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false); +implementation +uses + mseuniintf,sysutils,msefont; + +procedure unidrawstring(const acanvas: tcanvas; const atext: msestring; + const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false); +var + unitext1: tunitext; +begin + unitext1:= tunitext.create(atext,afont); + try + unitext1.drawstring(acanvas,apos,grayed); + finally + unitext1.free; + end; +end; + +{ tunifont } + +constructor tunifont.create; +begin + inherited; + name:= 'stf_unicode'; +end; + +function tunifont.hasglyph(const achar: unicharty): boolean; +var + info: drawinfoty; +begin + with info,fonthasglyph do begin + try + font:= getdatapo^.font; + unichar:= achar; + gdi_call(gdf_fonthasglyph,info); + result:= hasglyph; + except + result:= false; + end; + end; +end; + +function tunifont.createfontwithglyph(const achar: unicharty): tunifont; +begin + result:= tunisubstfont.create(self,achar); + if not result.hasglyph(achar) then begin + freeandnil(result); + end; +end; + +{ tunisubstfont } + +constructor tunisubstfont.create(const base: tunifont; const aglyph: unicharty); +begin + finfo.glyph:= aglyph; + fbase:= base; + inherited create; + assignproperties(base,false); +end; + +function tunisubstfont.getfont(var drawinfo: drawinfoty): boolean; +begin + result:= uni_getfontwithglyph(drawinfo); + if result then begin + drawinfo.getfont.basefont:= fbase.getdatapo^.font; + end; +end; + +function tunisubstfont.gethandle: fontnumty; +begin + if fhandlepo^ = 0 then begin + fhandlepo^:= getfontforglyph(fbase.getdatapo^.font,finfo.glyph); + end; + result:= inherited gethandle; +end; + +{ tunitext } + +constructor tunitext.create(const atext: msestring = ''; const afont: tfont = nil); +begin + ftext:= atext; + ffont:= tunifont.create; + setlength(ffonts,1); + ffonts[0]:= ffont; + if afont <> nil then begin + ffont.assign(afont); + end; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; +end; + +destructor tunitext.destroy; +begin + ffont.free; + freefonts; + inherited; +end; + +procedure tunitext.setfont(const avalue: tunifont); +begin + ffont.assign(avalue); +end; + +procedure tunitext.fontchanged(const sender: tobject); +begin + changed; +end; + +procedure tunitext.changed; +begin + exclude(fstate,uts_fontmatched); +end; + +procedure tunitext.drawstring(const acanvas: tcanvas; const apos: pointty; + const grayed: boolean = false); +var + int1,int2,int3: integer; + pt1: pointty; + po1: pmsechar; +begin + checkstate; + pt1:= apos; + po1:= pmsechar(ftext); + for int1:= 0 to high(fsegments) do begin + with fsegments[int1] do begin + if int1 < high(fsegments) then begin + int2:= fsegments[int1+1].charindex - charindex; + int3:= acanvas.getstringwidth(po1,int2,ffonts[fontnum]); + end + else begin + int2:= length(ftext) - charindex; //rest + int3:= 0; //compiler warning + end; + acanvas.drawstring(po1,int2,pt1,ffonts[fontnum]); + inc(pt1.x,int3); + inc(po1,int2); + end; + end; +end; + +procedure tunitext.checkstate; +begin + if not (uts_fontmatched in fstate) then begin + matchfonts; + end; +end; + +procedure tunitext.matchfonts; +var + int1: integer; + fontnum1: integer; + first: boolean; + + procedure addsegment; + begin + if not first then begin + setlength(fsegments,high(fsegments)+2); + end; + with fsegments[high(fsegments)] do begin + charindex:= int1 - 1; + fontnum:= fontnum1; + end; + end; + +var + int2: integer; + fontnum2: integer; + unich1: unicharty; + font1: tunifont; + +begin + fontnum1:= 0; + int1:= 1; + fsegments:= nil; + first:= false; + addsegment; + first:= true; + while int1 <= length(ftext) do begin + unich1:= word(ftext[int1]); + fontnum2:= -1; + for int2:= 0 to high(ffonts) do begin + if ffonts[int2].hasglyph(unich1) then begin + fontnum2:= int2; + break; + end; + end; + if fontnum2 < 0 then begin + font1:= ffont.createfontwithglyph(unich1); + if font1 <> nil then begin + setlength(ffonts,high(ffonts)+2); + fontnum2:= high(ffonts); + ffonts[fontnum2]:= font1; + end + else begin + fontnum2:= 0; //no font with glyph found + end; + end; + if fontnum2 <> fontnum1 then begin + fontnum1:= fontnum2; + addsegment; + end; + first:= false; + inc(int1); + end; + include(fstate,uts_fontmatched); +end; + +procedure tunitext.settext(const avalue: msestring); +begin + ftext:= avalue; + changed; +end; + +procedure tunitext.freefonts; +var + int1: integer; +begin + for int1:= 1 to high(ffonts) do begin + ffonts[int1].free; + end; + setlength(ffonts,1); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msebarcode.pas b/mseide-msegui/lib/common/widgets/msebarcode.pas new file mode 100644 index 0000000..21bae43 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msebarcode.pas @@ -0,0 +1,739 @@ +{ MSEgui Copyright (c) 2011-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msebarcode; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,classes,mclasses,msewidgets,msebitmap,msegraphics,mseclasses, + msegraphutils, + msestrings,msegui,msemenus,mseguiglob; + +type + barcodestatety = (bcs_bitmapvalid,bcs_layoutvalid,bcs_painting); + barcodestatesty = set of barcodestatety; + bitmapnumty = (bmn_1,bmn_2); + + tcustombarcode = class; + + tbarcodefont = class(tfont) + private + fowner: tcustombarcode; + protected + procedure dochanged(const changed: canvasstatesty; + const nochange: boolean); override; + public + constructor create(const aowner: tcustombarcode); reintroduce; + end; + + barcodeoptionty = (bco_calcchecksum); + barcodeoptionsty = set of barcodeoptionty; + + tcustombarcode = class(tpublishedwidget) + private + fbitmap1: tbitmap; + fbitmap2: tbitmap; + fcellcount: integer; + fcelldata1: pbyte; + fcelldata2: pbyte; + fcolorbar: colorty; + fcolorspace: colorty; + fvalue: msestring; + fcode: msestring; + fcoderect: rectty; + fsubcliprects: rectarty; + ffontbar: tbarcodefont; + fdirection: graphicdirectionty; + foptions: barcodeoptionsty; + procedure setcolorbar(const avalue: colorty); + procedure setcolorspace(const avalue: colorty); + procedure setvalue(const avalue: msestring); + procedure setcell1(const adata: pbyte; const aindex: integer; + const avalue: boolean); + procedure setfontbar(const avalue: tbarcodefont); + procedure setdirection(const avalue: graphicdirectionty); + procedure setoptions(const avalue: barcodeoptionsty); + protected + fbarrect1: rectty; + fbarrect2: rectty; + fstate: barcodestatesty; + procedure adjustrect(var arect: rectty); + procedure checkbitmap; + procedure calcbitmap; virtual; abstract; + procedure updatelayout(const asize: sizety); virtual; + procedure checkvalue; virtual; + procedure dopaint2(const acanvas: tcanvas); virtual; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure clientrectchanged; override; + procedure change(const alayout: boolean); + procedure setcell(const anum: bitmapnumty; const aindex: integer; + const avalue: boolean = true); overload; + procedure setcell(const anum: bitmapnumty; + const aindex: array of integer); overload; + procedure subcliprect(const arect: rectty); + procedure drawtext(const acanvas: tcanvas; const atext: msestring; + const adest: rectty; const aheight: integer); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property direction: graphicdirectionty read fdirection + write setdirection default gd_right; + property colorbar: colorty read fcolorbar write setcolorbar + default cl_black; + property colorspace: colorty read fcolorspace write setcolorspace + default cl_transparent; + property value: msestring read fvalue write setvalue; + property fontbar: tbarcodefont read ffontbar write setfontbar; + property options: barcodeoptionsty read foptions write setoptions default []; + end; + + barcodekindty = (bk_none,bk_gtin_13,bk_gtin_8); + + tcustombarcode1 = class(tcustombarcode) + private + fkind: barcodekindty; + procedure setkind(const avalue: barcodekindty); + protected + ffontheight: integer; + frect1: rectty; + frect2: rectty; + frect3: rectty; + procedure checkvalue; override; + procedure calcbitmap; override; + procedure updatelayout(const asize: sizety); override; + procedure dopaint2(const acanvas: tcanvas); override; + public + property kind: barcodekindty read fkind write setkind default bk_none; + end; + + tbarcode = class(tcustombarcode1) + published + property options; + property kind; + property direction; + property colorbar; + property colorspace; + property value; + property fontbar; + end; + +function encodegtin13(const avalue: int64): msestring; //'' on error +function decodegtin13(const avalue: msestring): int64; //-1 on error + +implementation +uses + rtlconsts,msebits,msedrawtext,mseformatstr; + +function gtin13checksum(const avalue: int64): int32; +var + i1,i2,i3: int32; + i4: int64; +begin + i2:= 0; + i4:= avalue; + for i1:= 0 to 11 do begin + i3:= i4 mod 10; + if odd(i1) then begin + i2:= i2 + i3; + end + else begin + i2:= i2 + i3*3; + end; + i4:= i4 div 10; + end; + result:= (10 - i2 mod 10) mod 10; +end; + +function encodegtin13(const avalue: int64): msestring; //'' on error +begin + result:= ''; + if (avalue >= 0) and (avalue <= 999999999999) then begin + result:= inttostrmse(avalue*10+int64(gtin13checksum(avalue))); + end; +end; + +function decodegtin13(const avalue: msestring): int64; //-1 on error +var + i1,i2: int64; +begin + result:= -1; + if trystrtoint64(avalue,i1) then begin + i2:= i1 div 10; + if gtin13checksum(i2) = i1 mod 10 then begin + result:= i2; + end; + end; +end; + +type + patterngtin13ty = (pgt13_l0,pgt13_l1,pgt13_r,pgt13_13); + +const + textflags: array[graphicdirectionty] of textflagsty = + //gd_right + ([tf_xcentered,tf_ycentered], + //gd_up + [tf_xcentered,tf_ycentered,tf_rotate90], + //gd_left + [tf_xcentered,tf_ycentered,tf_rotate180], + //gd_down + [tf_xcentered,tf_ycentered,tf_rotate180,tf_rotate90], + //gd_none + [tf_xcentered,tf_ycentered]); + + cellcounts: array[barcodekindty] of integer = + //bk_none,bk_gtin_13, bk_gtin_8 + (0, 3+6*7+5+6*7+3, 3+4*7+5+4*7+3 ); + framesizes: array[barcodekindty] of integer = + //bk_none,bk_gtin_13, bk_gtin_8 + (0, 2*7, 2*7); + charwidths: array[barcodekindty] of integer = + //bk_none,bk_gtin_13, bk_gtin_8 + (0, 7, 7); + { + spacecounts: array[barcodekindty] of integer = + //bk_none,bk_gtin_13 + (0, 3*3+2*7); + charcounts: array[barcodekindty] of integer = + //bk_none,bk_gtin_13 + (1, 13); + } + patterngtin13: array[patterngtin13ty,0..9] of byte = +// 0 1 2 3 4 5 6 7 8 9 +//0001101 0011001 0010011 0111101 0100011 0110001 0101111 0111011 0110111 0001011 _l0 + (($0d, $19, $13, $3d, $23, $31, $2f, $3b, $37, $0b),//_13 0 +//0100111 0110011 0011011 0100001 0011101 0111001 0000101 0010001 0001001 0010111 _l1 + ($27, $33, $1b, $21, $1d, $39, $05, $11, $09, $17),//_13 1 +//1110010 1100110 1101100 1000010 1011100 1001110 1010000 1000100 1001000 1110100 _r + ($72, $66, $6c, $42, $5c, $4e, $50, $44, $48, $74), +// 000000 001011 001101 001110 010011 011001 011100 010101 010110 011010 _13 + ($00, $0b, $0d, $0e, $13, $19, $1c, $15, $16, $1a) + ); + + reversemask7: array[0..6] of byte = + //1000000 0100000 0010000 0001000 0000100 0000010 0000001 + ( $40, $20, $10, $08, $04, $02, $01); + reversemask6: array[0..5] of byte = + //0100000 0010000 0001000 0000100 0000010 0000001 + ( $20, $10, $08, $04, $02, $01); + +{ tcustombarcode } + +constructor tcustombarcode.create(aowner: tcomponent); +begin + fcolorbar:= cl_black; + fcolorspace:= cl_transparent; + ffontbar:= tbarcodefont.create(self); + inherited; + fbitmap1:= tbitmap.create(bmk_mono{true}); + fbitmap2:= tbitmap.create(bmk_mono{true}); +end; + +destructor tcustombarcode.destroy; +begin + fbitmap1.free; + fbitmap2.free; + ffontbar.free; + inherited; +end; + +procedure tcustombarcode.checkbitmap; +var + int1: integer; +begin + if fstate * [bcs_bitmapvalid,bcs_layoutvalid] <> + [bcs_bitmapvalid,bcs_layoutvalid] then begin + checkvalue; + if not (bcs_layoutvalid in fstate) then begin + fsubcliprects:= nil; + fcellcount:= 0; + fbarrect1:= mr(nullpoint,fcoderect.size); + if fdirection in [gd_up,gd_down] then begin + with fbarrect1 do begin + int1:= cx; + cx:= cy; + cy:= int1; + end; + end; + fbarrect2:= fbarrect1; + if fdirection in [gd_up,gd_down] then begin + updatelayout(ms(fcoderect.cy,fcoderect.cx)); + end + else begin + updatelayout(fcoderect.size); + end; + adjustrect(fbarrect1); + adjustrect(fbarrect2); + for int1:= 0 to high(fsubcliprects) do begin + adjustrect(fsubcliprects[int1]); + end; + end; + fcelldata1:= nil; + fcelldata2:= nil; + if (fcode = '') or (fcellcount <= 0) then begin + fbitmap1.clear; + fbitmap2.clear; + end + else begin + if fdirection in [gd_up,gd_down] then begin + fbitmap1.size:= ms(1,fcellcount); + fbitmap2.size:= ms(1,fcellcount); + fcelldata1:= fbitmap1.scanline[0]; + fcelldata2:= fbitmap2.scanline[0]; + fillchar(fcelldata1^,fcellcount*4,0); + fillchar(fcelldata2^,fcellcount*4,0); + end + else begin + fbitmap1.size:= ms(fcellcount,1); + fbitmap2.size:= ms(fcellcount,1); + fcelldata1:= fbitmap1.scanline[0]; + fcelldata2:= fbitmap2.scanline[0]; + fillchar(fcelldata1^,((fcellcount+31) div 32) * 4,0); + fillchar(fcelldata2^,((fcellcount+31) div 32) * 4,0); + end; + calcbitmap; + end; + fstate:= fstate + [bcs_bitmapvalid,bcs_layoutvalid]; + end; +end; + +procedure tcustombarcode.dopaintforeground(const acanvas: tcanvas); +var + reg1: regionty; + int1: integer; +begin + inherited; + checkbitmap; + if fsubcliprects <> nil then begin + reg1:= acanvas.copyclipregion; + for int1:= 0 to high(fsubcliprects) do begin + acanvas.subcliprect(fsubcliprects[int1]); + end; + end; + fbitmap1.paint(acanvas,fbarrect1,[al_stretchx,al_stretchy,al_or], + fcolorbar,fcolorspace); + fbitmap2.paint(acanvas,fbarrect2,[al_stretchx,al_stretchy,al_or], + fcolorbar,cl_transparent); + if fsubcliprects <> nil then begin + acanvas.clipregion:= reg1; + end; + include(fstate,bcs_painting); + try + dopaint2(acanvas); + finally + exclude(fstate,bcs_painting); + end; +end; + +procedure tcustombarcode.change(const alayout: boolean); +begin + exclude(fstate,bcs_bitmapvalid); + if alayout then begin + exclude(fstate,bcs_layoutvalid); + end; + invalidate; +end; + +procedure tcustombarcode.setcell1(const adata: pbyte; const aindex: integer; + const avalue: boolean); +var + po1: pbyte; + int1: integer; +begin + if (aindex < 0) or (aindex >= fcellcount) then begin + tlist.error(slistindexerror,aindex); + end; + int1:= aindex; + if fdirection in [gd_left,gd_up] then begin + int1:= fcellcount-aindex-1; + end; + if fdirection in [gd_right,gd_left] then begin + po1:= pbyte(pchar(adata)+(int1 div 8)); + if avalue then begin + po1^:= po1^ or bits[int1 and $07]; + end + else begin + po1^:= po1^ and not bits[int1 and $07]; + end; + end + else begin + po1:= pbyte(pchar(adata)+(int1 * 4)); + if avalue then begin + plongword(po1)^:= $ffffffff; + end + else begin + po1^:= 0; + end; + end; +end; + +procedure tcustombarcode.setcell(const anum: bitmapnumty; const aindex: integer; + const avalue: boolean = true); +begin + if anum = bmn_1 then begin + setcell1(fcelldata1,aindex,avalue); + end + else begin + setcell1(fcelldata2,aindex,avalue); + end; +end; + +procedure tcustombarcode.setcell(const anum: bitmapnumty; + const aindex: array of integer); +var + int1: integer; + po1: pbyte; +begin + po1:= fcelldata2; + if anum = bmn_1 then begin + po1:= fcelldata1; + end; + for int1:= 0 to high(aindex) do begin + setcell1(po1,aindex[int1],true); + end; +end; + +procedure tcustombarcode.setcolorbar(const avalue: colorty); +begin + if fcolorbar <> avalue then begin + fcolorbar:= avalue; + invalidate; + end; +end; + +procedure tcustombarcode.setcolorspace(const avalue: colorty); +begin + if fcolorspace <> avalue then begin + fcolorspace:= avalue; + invalidate; + end; +end; + +procedure tcustombarcode.setvalue(const avalue: msestring); +begin + if fvalue <> avalue then begin + fvalue:= avalue; +// checkvalue; + change(false); + end; +end; + +procedure tcustombarcode.checkvalue; +begin + fcode:= fvalue; +end; + +procedure tcustombarcode.updatelayout(const asize: sizety); +begin + //dummy +end; + +procedure tcustombarcode.clientrectchanged; +begin + inherited; + fcoderect:= innerclientrect; + change(true); +end; + +procedure tcustombarcode.subcliprect(const arect: rectty); +begin + setlength(fsubcliprects,high(fsubcliprects)+2); + fsubcliprects[high(fsubcliprects)]:= arect; +end; + +procedure tcustombarcode.drawtext(const acanvas: tcanvas; + const atext: msestring; const adest: rectty; + const aheight: integer); +var + int1: integer; +begin + int1:= ffontbar.height; + ffontbar.height:= aheight; + msedrawtext.drawtext(acanvas,atext,adest,textflags[fdirection],ffontbar); + ffontbar.height:= int1; +end; + +procedure tcustombarcode.setfontbar(const avalue: tbarcodefont); +begin + ffontbar.assign(avalue); +end; + +procedure tcustombarcode.dopaint2(const acanvas: tcanvas); +begin + //dummy +end; + +procedure tcustombarcode.setdirection(const avalue: graphicdirectionty); +begin + if fdirection <> avalue then begin + if not (csreading in componentstate) then begin + changedirection(avalue,fdirection); + end + else begin + fdirection:= avalue; + end; + change(true); + end; +end; + +procedure tcustombarcode.adjustrect(var arect: rectty); +var + pt1: pointty; + int1: integer; +begin + pt1:= arect.pos; + with arect do begin + case fdirection of + gd_up: begin + pt1.x:= y + fcoderect.x; + pt1.y:= fcoderect.y + fcoderect.cy - x - cx; + int1:= arect.cx; + arect.cx:= arect.cy; + arect.cy:= int1; + end; + gd_left: begin + pt1.x:= fcoderect.x + fcoderect.cx - x - cx; + pt1.y:= fcoderect.y + fcoderect.cy - y - cy; + end; + gd_down: begin + pt1.x:= fcoderect.x + fcoderect.cx - y - cy; + pt1.y:= fcoderect.y + x; + int1:= arect.cx; + arect.cx:= arect.cy; + arect.cy:= int1; + end; + else begin //gd_right + pt1.x:= fcoderect.x + x; + pt1.y:= fcoderect.y + y; + end; + end; + end; + arect.pos:= pt1; +end; + +procedure tcustombarcode.setoptions(const avalue: barcodeoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + change(false); +// checkvalue; + end; +end; + +{ tcustombarcode1 } + +procedure tcustombarcode1.calcbitmap; +var + cellindex: integer; + + procedure putcells(const apattern: byte); + var + int1: integer; + begin + for int1:= 0 to high(reversemask7) do begin + if apattern and reversemask7[int1] <> 0 then begin + setcell(bmn_2,cellindex); + end; + inc(cellindex); + end; + end; + +var + int1: integer; + digits: array[0..11] of byte; + by2: byte; + pat1: patterngtin13ty; +begin + case fkind of + bk_gtin_8: begin + setcell(bmn_1,[0,2,32,34,64,66]); //start, center, stop + for int1:= 6 to 13 do begin + digits[int1-6]:= ord(fcode[int1])-ord('0'); + end; + cellindex:= 3; + for int1:= 0 to 3 do begin + putcells(patterngtin13[pgt13_l0,digits[int1]]); + end; + cellindex:= 36; + for int1:= 4 to 7 do begin + putcells(patterngtin13[pgt13_r,digits[int1]]); + end; + end; + bk_gtin_13: begin + setcell(bmn_1,[0,2,46,48,92,94]); //start, center, stop + for int1:= 2 to 13 do begin + digits[int1-2]:= ord(fcode[int1])-ord('0'); + end; + by2:= patterngtin13[pgt13_13,ord(fcode[1])-ord('0')]; + cellindex:= 3; + for int1:= 0 to 5 do begin + pat1:= pgt13_l0; + if by2 and reversemask6[int1] <> 0 then begin + pat1:= pgt13_l1; + end; + putcells(patterngtin13[pat1,digits[int1]]); + end; + cellindex:= 50; + for int1:= 6 to 11 do begin + putcells(patterngtin13[pgt13_r,digits[int1]]); + end; + end; + end; +end; + +procedure tcustombarcode1.setkind(const avalue: barcodekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + change(true); + end; +end; + +procedure tcustombarcode1.checkvalue; +var + int1,int2,int3: integer; + by1: byte; + po1: pmsechar; + mch1: msechar; +begin + inherited; + if fcode <> '' then begin + case fkind of + bk_gtin_13,bk_gtin_8: begin + int2:= length(fcode); + setlength(fcode,13); //unique instance + po1:= pointer(fcode); + for int1:= 0 to int2-1 do begin + mch1:= (po1+int1)^; + if (mch1 < '0') or (mch1 > '9') then begin + (po1+int1)^:= '0'; + end; + end; + if int2 < 13 then begin + move(po1^,(po1+13-int2)^,int2*sizeof(msechar)); + for int1:= 0 to 12-int2 do begin + (po1+int1)^:= '0'; + end; + end; + if bco_calcchecksum in foptions then begin + int2:= 0; + int3:= 0; + for int1:= 12 downto 1 do begin + if odd(int1) then begin + int2:= int2 + ord((po1+int1)^) - ord('0'); //*1 + end + else begin + int3:= int3 + ord((po1+int1)^) - ord('0'); //*3 + end; + end; + by1:= (3*int3+int2) mod 10; + if by1 <> 0 then begin + by1:= (10-by1) mod 10; //controllsum + end; + move((po1+1)^,po1^,12*sizeof(msechar)); + (po1+12)^:= msechar(by1+ord('0')); + end; + end; + end; + end; +end; + +procedure tcustombarcode1.updatelayout(const asize: sizety); +var + cellsize1: real; + charwidth1: real; + framesize1: integer; + int1: integer; +begin + fcellcount:= cellcounts[fkind]; + if fcellcount > 0 then begin + framesize1:= framesizes[fkind]; + cellsize1:= asize.cx / (fcellcount+framesize1); + charwidth1:= charwidths[fkind]*cellsize1; + with fbarrect1 do begin //center barrect + cx:= round(fcellcount*cellsize1); + x:= (asize.cx-cx) div 2; + end; + fbarrect2:= fbarrect1; + if ffontbar.height = 0 then begin + ffontheight:= round(charwidth1*1.5); + end + else begin + ffontheight:= ffontbar.height; + end; + fbarrect2.cy:= fbarrect2.cy - round(ffontheight*1.2); + + case fkind of + bk_gtin_13,bk_gtin_8: begin + with frect1 do begin + int1:= round(charwidth1); + x:= fbarrect1.x - int1; + y:= asize.cy - ffontheight; + cx:= int1; + cy:= ffontheight; + end; + with frect2 do begin + y:= frect1.y; + cy:= frect1.cy; + x:= fbarrect1.x + round(3*cellsize1); + int1:= 6; + if fkind = bk_gtin_8 then begin + int1:= 4; + end; + cx:= round(int1*charwidth1); + end; + frect3:= frect2; + with frect3 do begin + x:= fbarrect1.x + round((3+int1*7+5)*cellsize1); + end; + adjustrect(frect1); + adjustrect(frect2); + adjustrect(frect3); + end; + end; + end; +end; + +procedure tcustombarcode1.dopaint2(const acanvas: tcanvas); +begin + inherited; + if fcode <> '' then begin + case fkind of + bk_gtin_13: begin + drawtext(acanvas,fcode[1],frect1,ffontheight); + drawtext(acanvas,copy(fcode,2,6),frect2,ffontheight); + drawtext(acanvas,copy(fcode,8,6),frect3,ffontheight); + end; + bk_gtin_8: begin + drawtext(acanvas,copy(fcode,6,4),frect2,ffontheight); + drawtext(acanvas,copy(fcode,10,4),frect3,ffontheight); + end; + end; + end; +end; + +{ tbarcodefont } + +constructor tbarcodefont.create(const aowner: tcustombarcode); +begin + fowner:= aowner; + inherited create; +end; + +procedure tbarcodefont.dochanged(const changed: canvasstatesty; + const nochange: boolean); +begin + inherited; + if not nochange and not(bcs_painting in fowner.fstate) then begin + fowner.change(cs_font in changed); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msechart.pas b/mseide-msegui/lib/common/widgets/msechart.pas new file mode 100644 index 0000000..ee54737 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msechart.pas @@ -0,0 +1,4637 @@ +{ MSEgui Copyright (c) 2007-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msechart; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msegui,mseguiglob,mseclasses,msearrayprops,msetypes, + msegraphics,msegraphutils,mseglob,msereal, + msewidgets,msesimplewidgets,msedial,msebitmap,msemenus,mseevent, + msedatalist,msestatfile,msestat,msestrings; + +type + optionchartty = (oca_autofitleft,oca_autofittop,oca_autofitright, + oca_autofitbottom); //same layout as rectsidesty + optionschartty = set of optionchartty; +const + allrectsides = [rs_left,rs_top,rs_right,rs_bottom]; + rectsidesmask = [oca_autofitleft,oca_autofittop,oca_autofitright, + oca_autofitbottom]; + defaultoptionschart = [oca_autofitleft,oca_autofittop,oca_autofitright, + oca_autofitbottom]; +type + chartstatety = (chs_nocolorchart,chs_hasdialscroll,chs_hasdialshift, + chs_started,chs_full,chs_chartvalid, //for tchartrecorder + chs_layoutvalid); + chartstatesty = set of chartstatety; + charttraceoptionty = (cto_invisible,cto_smooth,cto_stockglyphs,cto_adddataright, + cto_xordered, //optimize for big data quantity + cto_logx,cto_logy,cto_seriescentered, + cto_savexscale,cto_saveyscale + ); + charttraceoptionsty = set of charttraceoptionty; + tracelegendplacementty = (tlp_none,tlp_xy,tlp_above,tlp_below); + +const + chartrecorderstatesmask = [chs_hasdialscroll,chs_hasdialshift,chs_started, + chs_full,chs_chartvalid]; + defaultxytraceoptions = [cto_xordered]; + defaultlegenddist = 1; + defaultlegendplacement = tlp_xy; + +type + tcustomchart = class; + tracestatety = (trs_datapointsvalid,trs_ownsxdatalist,trs_ownsydatalist); + tracestatesty = set of tracestatety; + tracekindty = (trk_xseries,trk_xy); + tracechartkindty = (tck_line,tck_bar); + tracechartkindsty = set of tracechartkindty; + + xseriesdataty = record + value: real; + index: integer; + end; + + datapointty = record + first,min,max,last: integer; + used: boolean; + end; + datapointarty = array of datapointty; + + barrefty = (br_zero,br_top,br_bottom); + + ttracefont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + traceinfoty = record + xdata: realarty; + ydata: realarty; + xydata: complexarty; + xdatalist: trealdatalist; + ydatalist: trealdatalist; + state: tracestatesty; + datapoints: pointarty; + barlines: segmentarty; + bottommargin,topmargin: integer; + color: colorty; + colorimage: colorty; + xserrange: real; + xserstart: real; + xrange: real; + xstart: real; + yrange: real; + ystart: real; + kind: tracekindty; + maxcount: integer; + widthmm: real; + dashes: string; + legend: msestring; + legendrect: rectty; + font: ttracefont; + options: charttraceoptionsty; + chartkind: tracechartkindty; + bar_offset: integer; + bar_width: integer; + bar_frame: tframe; + bar_face: tface; + bar_ref: barrefty; + start: integer; + imagenr: imagenrty; + name: string; + end; + + ttraces = class; + + tbarframe = class(tframe) + public + constructor create(const aintf: iframe); + end; + ttrace = class; + + ttracedatalist = class(trealdatalist) + private + fowner: ttrace; + procedure readdummy(reader: treader); + procedure writedummy(writer: twriter); + protected + procedure dochange; override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(const aowner: ttrace); reintroduce; + property defaultzero default true; + end; + + ttrace = class(townedeventpersistent,iimagelistinfo,iframe,iface) + private + finfo: traceinfoty; + fbreaks: integerarty; + fbmp2: tmaskedbitmap; + fco1: colorty; + fimli1: timagelist; + frect1: rectty; + fimagealignment: alignmentsty; + fhint_captionx: msestring; + fhint_captiony: msestring; + procedure setxydata(const avalue: complexarty); + procedure datachange; + procedure legendchange; + procedure setcolor(const avalue: colorty); + procedure setcolorimage(const avalue: colorty); + procedure setxserrange(const avalue: real); + procedure setxserstart(const avalue: real); + procedure setxrange(const avalue: real); + procedure setxstart(const avalue: real); + procedure setyrange(const avalue: real); + procedure setystart(const avalue: real); + procedure scaleerror; + procedure setxdata(const avalue: realarty); + procedure setydata(const avalue: realarty); + procedure setmaxcount(const avalue: integer); + procedure setwidthmm(const avalue: real); + procedure setdashes(const avalue: string); + procedure readxseriescount(reader: treader); + procedure readxscale(reader: treader); + procedure readxoffset(reader: treader); + procedure readyscale(reader: treader); + procedure readyoffset(reader: treader); + procedure setstart(const avalue: integer); + function getxdatalist: trealdatalist; + procedure setxdatalist(const avalue: trealdatalist); + function getydatalist: trealdatalist; + procedure setydatalist(const avalue: trealdatalist); + procedure setimagenr(const avalue: imagenrty); + function getimagelist: timagelist; + function getlogx: boolean; + procedure setlogx(const avalue: boolean); + function getlogy: boolean; + procedure setlogy(const avalue: boolean); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getxdatapo: preal; + function getydatapo: preal; + function getxydatapo: pcomplexty; + function getcount: integer; + function getxvalue(const index: integer): real; + procedure setxvalue(const index: integer; const avalue: real); + function getyvalue(const index: integer): real; + procedure setyvalue(const index: integer; const avalue: real); + function getxyvalue(const index: integer): complexty; + procedure setxyvalue(const index: integer; const avalue: complexty); + procedure setchartkind(const avalue: tracechartkindty); + procedure setbar_offset(const avalue: integer); + procedure setbar_width(const avalue: integer); + function getbar_frame: tframe; + procedure setbar_frame(const avalue: tframe); + function getbar_face: tface; + procedure setbar_face(const avalue: tface); + procedure setbar_ref(const avalue: barrefty); + procedure setbreaks(const avalue: integerarty); + function getlegend_font: ttracefont; + procedure setlegend_font(const avalue: ttracefont); + procedure setlegend_caption(const avalue: msestring); + function isfontstored: boolean; + procedure fontchanged(const sender: tobject); + function getsmooth: boolean; + procedure setsmooth(const avalue: boolean); + protected + fstate: tracestatesty; + ftraces: ttraces; + fcurfont: tfont; + flnxstart: real; + flnxrange: real; + flnystart: real; + flnyrange: real; + procedure setkind(const avalue: tracekindty); virtual; + procedure setoptions(const avalue: charttraceoptionsty); virtual; + function getxitempo(const aindex: integer): preal; + function getyitempo(const aindex: integer): preal; + procedure getdatapo(out xpo,ypo: preal; //xpo nil for xseries + out xcount,ycount,xstep,ystep: integer); + + procedure checkgraphic; + procedure clip2(const acanvas: tcanvas); + procedure paint(const acanvas: tcanvas); + procedure paint1(const acanvas: tcanvas; const imagesize: sizety; + const imagealignment: alignmentsty); + procedure paint2(const acanvas: tcanvas); + procedure defineproperties(filer: tfiler); override; + function hintx: msestring; + function hinty: msestring; + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getwidget: twidget; + function getwidgetrect: rectty; + function getframestateflags: framestateflagsty; + //iface + function translatecolor(const acolor: colorty): colorty; + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + procedure widgetregioninvalid; + procedure forcexyarray; + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure createbar_frame; + procedure createbar_face; + procedure createfont; + + procedure clear; + procedure deletedata(const aindex: integer); overload; + procedure deletedata(const aindexar: integerarty); overload; + procedure addxydata(const xy: complexty); overload; + procedure addxydata(const x: real; const y: real); overload; + procedure addxseriesdata(const avalue: real); + procedure insertxseriesdata(const avalue: xseriesdataty); + procedure assign(source: tpersistent); override; + procedure minmaxx(out amin,amax: real); + procedure minmaxx1(var amin,amax: real); //extend + procedure minmaxy(out amin,amax: real); + procedure minmaxy1(var amin,amax: real); //extend + procedure autoscalex(const astartmargin: real = 0; + const aendmargin: real = 0); + procedure autoscaley(const astartmargin: real = 0; + const aendmargin: real = 0); + + property xdata: realarty read finfo.xdata write setxdata; + property ydata: realarty read finfo.ydata write setydata; + property xydata: complexarty read finfo.xydata write setxydata; + property breaks: integerarty read fbreaks write setbreaks; + //for xy without cto_xordered only + + property xvalue[const index: integer]: real read getxvalue write setxvalue; + property yvalue[const index: integer]: real read getyvalue write setyvalue; + property xyvalue[const index: integer]: complexty read getxyvalue + write setxyvalue; + property xdatapo: preal read getxdatapo; + property ydatapo: preal read getydatapo; + property xydatapo: pcomplexty read getxydatapo; + property count: integer read getcount; + + property logx: boolean read getlogx write setlogx; + property logy: boolean read getlogy write setlogy; + property visible: boolean read getvisible write setvisible; + property smooth: boolean read getsmooth write setsmooth; + + published + property xdatalist: trealdatalist read getxdatalist write setxdatalist; + property ydatalist: trealdatalist read getydatalist write setydatalist; + property color: colorty read finfo.color write setcolor default cl_black; + property colorimage: colorty read finfo.colorimage + write setcolorimage default cl_default; + property widthmm: real read finfo.widthmm write setwidthmm; //default 0.3 + property dashes: string read finfo.dashes write setdashes; + property xserrange: real read finfo.xserrange write setxserrange; + //default 1.0 + property xserstart: real read finfo.xserstart write setxserstart; + property xrange: real read finfo.xrange write setxrange; //default 1.0 + property xstart: real read finfo.xstart write setxstart; + property yrange: real read finfo.yrange write setyrange; //default 1.0 + property ystart: real read finfo.ystart write setystart; + property kind: tracekindty read finfo.kind write setkind default trk_xseries; + property start: integer read finfo.start write setstart default 0; + property maxcount: integer read finfo.maxcount write setmaxcount default 0; + //0-> data count + property chartkind: tracechartkindty read finfo.chartkind write setchartkind + default tck_line; + property options: charttraceoptionsty read finfo.options + write setoptions default []; + property bar_offset: integer read finfo.bar_offset + write setbar_offset default 0; + property bar_width: integer read finfo.bar_width + write setbar_width default 0; //0 -> bar line + property bar_frame: tframe read getbar_frame write setbar_frame; + property bar_face: tface read getbar_face write setbar_face; + property bar_ref: barrefty read finfo.bar_ref write setbar_ref default br_zero; + + property imagenr: imagenrty read finfo.imagenr write setimagenr default -1; + property name: string read finfo.name write finfo.name; + property legend_caption: msestring read finfo.legend write setlegend_caption; + property legend_font: ttracefont read getlegend_font + write setlegend_font stored isfontstored; + property hint_captionx: msestring read fhint_captionx + write fhint_captionx; + property hint_captiony: msestring read fhint_captiony + write fhint_captiony; + end; + + traceaty = array[0..0] of ttrace; + ptraceaty = ^traceaty; + + tracesstatety = (trss_graphicvalid); + tracesstatesty = set of tracesstatety; + + ttracesfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttraces = class(townedeventpersistentarrayprop) + private + ftracestate: tracesstatesty; + fxserstart: real; + fxstart: real; + fystart: real; + fxserrange: real; + fxrange: real; + fyrange: real; + fmaxcount: integer; + fimage_list: timagelist; + fimage_widthmm: real; + fimage_heightmm: real; + foptions: charttraceoptionsty; + fkind: tracekindty; + fchartkind: tracechartkindty; + fbar_width: integer; + fbar_ref: barrefty; + ffont: ttracesfont; + flegend_pos: complexty; + flegend_dist: integer; + flegend_placement: tracelegendplacementty; + flegend_fitdist: integer; + fstart: integer; + procedure setitems(const index: integer; const avalue: ttrace); + function getitems(const index: integer): ttrace; + procedure setxserstart(const avalue: real); + procedure setxstart(const avalue: real); + procedure setystart(const avalue: real); + procedure setxserrange(const avalue: real); + procedure setxrange(const avalue: real); + procedure setyrange(const avalue: real); + procedure setstart(const avalue: integer); + procedure setmaxcount(const avalue: integer); + procedure setimage_list(const avalue: timagelist); + procedure setimage_widthmm(const avalue: real); + procedure setimage_heightmm(const avalue: real); + function getlogx: boolean; + procedure setlogx(const avalue: boolean); + function getlogy: boolean; + procedure setlogy(const avalue: boolean); + procedure setchartkind(const avalue: tracechartkindty); + procedure setbar_width(const avalue: integer); + procedure setbar_ref(const avalue: barrefty); + function getfont: ttracesfont; + procedure setfont(const avalue: ttracesfont); + function isfontstored: boolean; + procedure fontchanged(const sender: tobject); + procedure setlegend_pos(const avalue: complexty); + procedure setlegend_x(const avalue: real); + procedure setlegend_y(const avalue: real); + procedure setlegend_dist(const avalue: integer); + procedure setlegend_placement(const avalue: tracelegendplacementty); + procedure setlegend_fitdist(const avalue: integer); + protected + fsize: sizety; + fscalex: real; + fscaley: real; + flegendsize: sizety; + procedure setkind(const avalue: tracekindty); virtual; + procedure setoptions(const avalue: charttraceoptionsty); virtual; + procedure change; reintroduce; + procedure layoutchanged; + procedure clientrectchanged; + procedure clipoverlay(const acanvas: tcanvas); + procedure paint(const acanvas: tcanvas); + procedure paintoverlay(const acanvas: tcanvas); + procedure calclegendrect; + procedure checkgraphic; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tcustomchart); reintroduce; + destructor destroy; override; + class function getitemclasstype: persistentclassty; override; + procedure createfont; + function itembyname(const aname: string): ttrace; + function actualimagelist: timagelist; + procedure assign(source: tpersistent); override; + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure setdata(const adata: realararty); overload; + procedure setdata(const adata: complexararty); overload; + property logx: boolean read getlogx write setlogx; + property logy: boolean read getlogy write setlogy; + property items[const index: integer]: ttrace read getitems + write setitems; default; + property legend_pos: complexty read flegend_pos write setlegend_pos; + published + property kind: tracekindty read fkind write setkind default trk_xseries; + property chartkind: tracechartkindty read fchartkind + write setchartkind default tck_line; + property options: charttraceoptionsty read foptions + write setoptions default []; + //item default values + property xserstart: real read fxserstart write setxserstart; + property xstart: real read fxstart write setxstart; + property ystart: real read fystart write setystart; + property xrange: real read fxrange write setxrange; + property xserrange: real read fxserrange write setxserrange; + property yrange: real read fyrange write setyrange; + property start: integer read fstart write setstart default 0; + property maxcount: integer read fmaxcount write setmaxcount default 0; + //properties not used in asssign below + property image_list: timagelist read fimage_list write setimage_list; + property image_widthmm: real read fimage_widthmm write setimage_widthmm; + property image_heighthmm: real read fimage_heightmm write setimage_heightmm; + property bar_width: integer read fbar_width + write setbar_width default 0; //0 -> bar line + property bar_ref: barrefty read fbar_ref write setbar_ref default br_zero; + property font: ttracesfont read getfont write setfont stored isfontstored; + property legend_x: real read flegend_pos.re write setlegend_x; + property legend_y: real read flegend_pos.im write setlegend_y; + property legend_dist: integer read flegend_dist write setlegend_dist default + defaultlegenddist; + property legend_fitdist: integer read flegend_fitdist + write setlegend_fitdist default defaultlegenddist; + property legend_placement: tracelegendplacementty read flegend_placement + write setlegend_placement default tlp_xy; + end; + + txytrace = class(ttrace) + protected + procedure setkind(const avalue: tracekindty); override; + procedure setoptions(const avalue: charttraceoptionsty); override; + public + constructor create(aowner: tobject); override; + published + property kind default trk_xy; + property options default defaultxytraceoptions; + end; + + txytraces = class(ttraces) + protected + fxordered: boolean; + procedure setkind(const avalue: tracekindty); override; + procedure setoptions(const avalue: charttraceoptionsty); override; + public + constructor create(const aowner: tcustomchart; const axordered: boolean); + class function getitemclasstype: persistentclassty; override; + published + property kind default trk_xy; + property options default defaultxytraceoptions; + end; + + ichartdialcontroller = interface(idialcontroller) + function getxstart: real; + function getystart: real; + function getxrange: real; + function getyrange: real; + end; + + tchartdialvert = class(tcustomdialcontroller) + protected + procedure setdirection(const avalue: graphicdirectionty); override; + public + constructor create(const aintf: idialcontroller); override; + published + property options; //first! + property color; + property widthmm; + property direction default gd_up; + property indent1; + property indent2; + property fitdist; + property start; + property range; + property kind; + property markers; + property ticks; + end; + + tchartdialhorz = class(tcustomdialcontroller) + protected + procedure setdirection(const avalue: graphicdirectionty); override; + public + constructor create(const aintf: idialcontroller); override; + published + property options; //first! + property color; + property widthmm; + property direction default gd_right; + property indent1; + property indent2; + property fitdist; + property start; + property range; + property kind; + property markers; + property ticks; + end; + + tchartdials = class(tcustomdialcontrollers) + private + function getitems(const aindex: integer): tcustomdialcontroller; + procedure setitems(const aindex: integer; + const avalue: tcustomdialcontroller); + protected + public + constructor create(const aintf: ichartdialcontroller); + procedure changed; + procedure paint(const acanvas: tcanvas); + procedure afterpaint(const acanvas: tcanvas); + property items[const aindex: integer]: tcustomdialcontroller read getitems + write setitems; default; + end; + + tchartdialshorz = class(tchartdials) + private + function getitems(const aindex: integer): tchartdialhorz; + procedure setitems(const aindex: integer; const avalue: tchartdialhorz); + protected + function getitemclass: dialcontrollerclassty; override; + procedure createitem(const index: integer; var item: tpersistent); override; + public + class function getitemclasstype: persistentclassty; override; + property items[const aindex: integer]: tchartdialhorz read getitems write setitems; default; + end; + + tchartdialsvert = class(tchartdials) + private + function getitems(const aindex: integer): tchartdialvert; + procedure setitems(const aindex: integer; const avalue: tchartdialvert); + protected + function getitemclass: dialcontrollerclassty; override; + procedure createitem(const index: integer; var item: tpersistent); override; + public + class function getitemclasstype: persistentclassty; override; + property items[const aindex: integer]: tchartdialvert read getitems + write setitems; default; + end; + + tchartframe = class(tscrollboxframe) + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: iscrollframe; const owner: twidget); + published + property framei_left default 0; + property framei_top default 0; + property framei_right default 1; + property framei_bottom default 1; + property colorclient {default cl_foreground}; + end; + +const + defaultchartoptionswidget = defaultscrollboxoptionswidget - + [ow_mousefocus,ow_tabfocus,ow_arrowfocus]; +type + tcuchart = class(tscrollbox,ichartdialcontroller,istatfile,iframe) + private + fxdials: tchartdialshorz; + fydials: tchartdialsvert; + fxstart: real; + fystart: real; + fxrange: real; + fyrange: real; + fstatfile: tstatfile; + fstatvarname: msestring; + foptionschart: optionschartty; + ffitframe: framety; + fstatpriority: integer; + procedure setxdials(const avalue: tchartdialshorz); + procedure setydials(const avalue: tchartdialsvert); + procedure setcolorchart(const avalue: colorty); + function getxstart: real; + procedure setxstart(const avalue: real); virtual; + function getystart: real; + procedure setystart(const avalue: real); virtual; + function getxrange: real; + procedure setxrange(const avalue: real); virtual; + function getyrange: real; + procedure setyrange(const avalue: real); virtual; + procedure setstatfile(const avalue: tstatfile); + procedure setoptionschart(const avalue: optionschartty); + procedure setfitframe(const avalue: framety); + procedure setfitframe_left(const avalue: integer); + procedure setfitframe_top(const avalue: integer); + procedure setfitframe_right(const avalue: integer); + procedure setfitframe_bottom(const avalue: integer); + function getfacechart: tface; + procedure setfacechart(const avalue: tface); + function getframechart: tframe; + procedure setframechart(const avalue: tframe); + protected + fcolorchart: colorty; + ffacechart: tface; + fframechart: tframe; + fstate: chartstatesty; + fshiftsum: int64; + fscrollsum: integer; + fsampleco: integer; + fchartframerect: rectty; + procedure fontchanged; override; + function checklayout: boolean; virtual; //true if changes made + function actualcolorchart(): colorty; + procedure changed; virtual; + procedure layoutchanged; virtual; + procedure chartchange; + procedure invalidatelayout; + procedure clientrectchanged; override; + procedure dopaintbackground(const canvas: tcanvas); override; + procedure doclipcontent1(const acanvas: tcanvas); virtual; + procedure dopaintcontent(const acanvas: tcanvas); virtual; + procedure dopaintcontent1(const acanvas: tcanvas); virtual; + procedure dopaintforeground(const acanvas: tcanvas); override; + //iscrollframe + function getzoomrefframe: framety; override; + //idialcontroller + procedure directionchanged(const dir,dirbefore: graphicdirectionty); + function getdialrect: rectty; + function getlimitrect: rectty; + procedure internalcreateframe; override; + procedure defineproperties(filer: tfiler); override; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; virtual; + procedure statread; virtual; + function getstatvarname: msestring; + function getstatpriority: integer; + procedure initscrollstate; + procedure extendfit(const asides: rectsidesty; var aext: rectextty); virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure paint(const acanvas: tcanvas); override; + procedure createfacechart; + procedure createframechart; + function fit(const asides: rectsidesty = allrectsides): boolean; + //adjust fitframe for extents of dials + //returns true if changes made + + property optionschart: optionschartty read foptionschart + write setoptionschart default defaultoptionschart; + property colorchart: colorty read fcolorchart write setcolorchart + default cl_default; + property facechart: tface read getfacechart write setfacechart; + property framechart: tframe read getframechart write setframechart; + property xstart: real read getxstart write setxstart; + property ystart: real read getystart write setystart; + property xrange: real read getxrange write setxrange; //default 1 + property yrange: real read getyrange write setyrange; //default 1 + + property xdials: tchartdialshorz read fxdials write setxdials; + property ydials: tchartdialsvert read fydials write setydials; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property fitframe: framety read ffitframe write setfitframe; + property fitframe_left: integer read ffitframe.left + write setfitframe_left default 0; + property fitframe_top: integer read ffitframe.top + write setfitframe_top default 0; + property fitframe_right: integer read ffitframe.right + write setfitframe_right default 0; + property fitframe_bottom: integer read ffitframe.bottom + write setfitframe_bottom default 0; + published + property optionswidget default defaultchartoptionswidget; + end; + + tcustomchart = class(tcuchart) + private + ftracehint_captionx: msestring; + ftracehint_captiony: msestring; + fmarkerhintcaption: msestring; + procedure settraces(const avalue: ttraces); + procedure setxstart(const avalue: real); override; + procedure setystart(const avalue: real); override; + procedure setxrange(const avalue: real); override; + procedure setyrange(const avalue: real); override; + protected + ftraces: ttraces; + procedure clientrectchanged; override; + procedure doclipcontent1(const acanvas: tcanvas); override; + procedure dopaintcontent(const acanvas: tcanvas); override; + procedure dopaintcontent1(const acanvas: tcanvas); override; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + procedure layoutchanged; override; + procedure extendfit(const asides: rectsidesty; var aext: rectextty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; virtual; + procedure autoscalex(const astartmargin: real = 0; + const aendmargin: real = 0); + procedure autoscaley(const astartmargin: real = 0; + const aendmargin: real = 0); + procedure addsample(const asamples: array of real); virtual; + property traces: ttraces read ftraces write settraces; + property tracehint_captionx: msestring read ftracehint_captionx + write ftracehint_captionx; + property tracehint_captiony: msestring read ftracehint_captiony + write ftracehint_captiony; + property markerhintcaption: msestring read fmarkerhintcaption + write fmarkerhintcaption; + end; + + tchart = class(tcustomchart) + published + property optionschart; + property traces; + property colorchart; + property facechart; + property framechart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property statfile; + property statvarname; + property statpriority; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + + trecordertrace = class(tvirtualpersistent) + private + fybefore: integer; + fstart: real; + frange: real; + fcolor: colorty; + fwidth: integer; + procedure setrange(const avalue: real); + public + constructor create; override; + published + property start: real read fstart write fstart; + property range: real read frange write setrange; + property color: colorty read fcolor write fcolor default cl_glyph; + property width: integer read fwidth write fwidth default 0; + end; + + trecordertraces = class(tpersistentarrayprop) + public + constructor create; + class function getitemclasstype: persistentclassty; override; + end; + + chartrecorderoptionty = (cro_adddataright); + chartrecorderoptionsty = set of chartrecorderoptionty; + + tchartrecorder = class(tcuchart) + private + fchart: tmaskedbitmap; + fsamplecount: integer; + fstep: real; + fstepsum: real; + fchartrect: rectty; + fchartclientrect: rectty; + fchartwindowrect: rectty; + fxref: integer; + ftraces: trecordertraces; + foptions: chartrecorderoptionsty; + procedure setsamplecount(const avalue: integer); + procedure settraces(const avalue: trecordertraces); + protected + procedure checkinit; + procedure dopaintcontent(const acanvas: tcanvas); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure addsample(const asamples: array of real); + procedure clear; + published + property options: chartrecorderoptionsty read foptions write foptions + default []; + property samplecount: integer read fsamplecount write setsamplecount + default 100; + property traces: trecordertraces read ftraces write settraces; + + property optionschart; + property colorchart; + property facechart; + property framechart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property statfile; + property statvarname; + property statpriority; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + +function autointerval(const arange: real; const aintervalcount: real): real; + //returns apropropriate 1/2/5 value +function calctracerange(var min: real; const max: real; const log: boolean; + const startmargin: real = 0; const endmargin: real = 0): real; +function makexseriesdata(const value: real; const index: integer): xseriesdataty; + +implementation +uses + sysutils,math,msebits,rtlconsts,msestockobjects,msearrayutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustomdialcontroller1 = class(tcustomdialcontroller); + tdialticks1 = class(tdialticks); + tdialmarkers1 = class(tdialmarkers); + tcustomframe1 = class(tcustomframe); + +function makexseriesdata(const value: real; const index: integer): xseriesdataty; +begin + result.value:= value; + result.index:= index; +end; + +function autointerval(const arange: real; const aintervalcount: real): real; + //returns apropropriate 1/2/5 value +var + rea1: real; + rea2: real; + int1: integer; + scale: real; +begin + rea1:= abs(arange/aintervalcount); + if rea1 < 1e-99 then begin + rea1:= 1e-99; + end; + int1:= ceil(log10(rea1)); + scale:= intpower(10,int1-1); + rea2:= 0.9*rea1/scale; //1..10, 10% overrange + if rea2 < 1 then begin + rea2:= 1; + end + else begin + if rea2 < 2 then begin + rea2:= 2; + end + else begin + if rea2 < 5 then begin + rea2:= 5; + end + else begin + rea2:= 10; + end; + end; + end; + result:= rea2 * scale; + if arange < 0 then begin + result:= -result; + end; +end; + +{ ttracefont } + +class function ttracefont.getinstancepo(owner: tobject): pfont; +begin + result:= @ttrace(owner).finfo.font; +end; + +{ ttracedatalist } + +constructor ttracedatalist.create(const aowner: ttrace); +begin + fowner:= aowner; + inherited create; + defaultzero:= true; + min:= -bigreal; +end; + +procedure ttracedatalist.dochange; +begin + fowner.datachange; + inherited; +end; + +procedure ttracedatalist.readdummy(reader: treader); +begin + reader.readinteger; +end; + +procedure ttracedatalist.writedummy(writer: twriter); +begin + writer.writeinteger(0); +end; + +procedure ttracedatalist.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('dummy',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,(filer.ancestor = nil)and (count = 0)); + //in order to create optional instance +end; + +{ ttrace } + +constructor ttrace.create(aowner: tobject); +begin + ftraces:= tcustomchart(aowner).ftraces; + finfo.color:= cl_black; + finfo.colorimage:= cl_default; + finfo.widthmm:= 0.3; + finfo.xserrange:= 1.0; + finfo.xrange:= 1.0; + finfo.yrange:= 1.0; + finfo.imagenr:= -1; + inherited; +end; + +destructor ttrace.destroy; +begin + xdatalist:= nil; + ydatalist:= nil; + inherited; + finfo.bar_frame.free; + finfo.bar_face.free; + finfo.font.free; + fbmp2.free; +end; + +procedure ttrace.datachange; +begin + exclude(finfo.state,trs_datapointsvalid); + tcustomchart(fowner).traces.change; +end; + +procedure ttrace.legendchange; +begin + with tcustomchart(fowner).traces do begin + if legend_placement in [tlp_above,tlp_below] then begin + layoutchanged; + end + else begin + change; + end; + end; +end; + +procedure ttrace.setxydata(const avalue: complexarty); +begin + xdatalist:= nil; + ydatalist:= nil; + finfo.xdata:= nil; + finfo.ydata:= nil; + finfo.xydata:= avalue; + datachange; +end; + +procedure ttrace.setbreaks(const avalue: integerarty); +begin + fbreaks:= avalue; + tcustomchart(fowner).traces.change; +end; + +procedure ttrace.setxdata(const avalue: realarty); +begin + xdatalist:= nil; + finfo.xydata:= nil; + finfo.xdata:= avalue; + datachange; +end; + +procedure ttrace.setydata(const avalue: realarty); +begin + ydatalist:= nil; + finfo.xydata:= nil; + finfo.ydata:= avalue; + datachange; +end; + +procedure ttrace.setxdatalist(const avalue: trealdatalist); +begin + finfo.xdata:= nil; + finfo.xydata:= nil; + if csdesigning in tcustomchart(fowner).componentstate then begin + if avalue = nil then begin + freeandnil(finfo.xdatalist); + exclude(fstate,trs_ownsxdatalist); + end + else begin + if finfo.xdatalist = nil then begin + finfo.xdatalist:= ttracedatalist.create(self); + include(finfo.state,trs_ownsxdatalist); + end; + if (ptruint(pointer(avalue)) <> 1) then begin + finfo.xdatalist.assign(avalue); + end; + end; + end + else begin + if trs_ownsxdatalist in fstate then begin + finfo.xdatalist.free; + exclude(fstate,trs_ownsxdatalist); + end; + finfo.xdatalist:= avalue; + end; + datachange; +end; + +procedure ttrace.setydatalist(const avalue: trealdatalist); +begin + finfo.ydata:= nil; + finfo.xydata:= nil; + if csdesigning in tcustomchart(fowner).componentstate then begin + if avalue = nil then begin + freeandnil(finfo.ydatalist); + exclude(fstate,trs_ownsydatalist); + end + else begin + if finfo.ydatalist = nil then begin + finfo.ydatalist:= ttracedatalist.create(self); + include(finfo.state,trs_ownsydatalist); + end; + if (ptruint(pointer(avalue)) <> 1) then begin + finfo.ydatalist.assign(avalue); + end; + end; + end + else begin + if trs_ownsydatalist in fstate then begin + finfo.ydatalist.free; + exclude(fstate,trs_ownsydatalist); + end; + finfo.ydatalist:= avalue; + end; + datachange; +end; + +procedure ttrace.forcexyarray; +var + ar1: complexarty; +begin + with finfo do begin + ar1:= xydata; + if ar1 = nil then begin + if xdatalist <> nil then begin + xdatalist.assigntore(ar1); + end; + if ydatalist <> nil then begin + ydatalist.assigntoim(ar1); + end; + if xdata <> nil then begin + copytore(xdata,ar1); + end; + if ydata <> nil then begin + copytoim(ydata,ar1); + end; + end; + if ar1 <> xydata then begin + self.xydata:= ar1; + end; + end; +end; + +function ttrace.getxdatalist: trealdatalist; +begin + if (finfo.xdatalist = nil) and + (csreading in tcustomchart(fowner).componentstate) then begin + finfo.xdatalist:= ttracedatalist.create(self); + include(finfo.state,trs_ownsxdatalist); + end; + result:= finfo.xdatalist; +end; + +function ttrace.getydatalist: trealdatalist; +begin + if (finfo.ydatalist = nil) and + (csreading in tcustomchart(fowner).componentstate) then begin + finfo.ydatalist:= ttracedatalist.create(self); + include(finfo.state,trs_ownsydatalist); + end; + result:= finfo.ydatalist; +end; + +procedure ttrace.checkgraphic; + + function pkround(const avalue: real): integer; + begin + if avalue > $3fff then begin //X11 range is 16bit + result:= $3fff; + end + else begin + if avalue < -$4000 then begin + result:= -$4000; + end + else begin + result:= round(avalue); + end; + end; + end; + +var + pox,poy: pchar; + intx,inty: integer; + + procedure checkrange(var dpcount: integer); + var + int1: integer; + begin + int1:= finfo.maxcount; + if int1 = 0 then begin + int1:= dpcount; + end; + if finfo.start + int1 > dpcount then begin + int1:= dpcount - finfo.start; + end; + if int1 < dpcount then begin + dpcount:= int1; + end; + if dpcount < 0 then begin + dpcount:= 0; + end; + pox:= pox + finfo.start * intx; + poy:= poy + finfo.start * inty; + end; + +var + int1,int2,int3,int4: integer; + xo,xs,yo,ys,lxo,lxs: real; + rea1: real; + ar1: datapointarty; + dpcountx,dpcounty,dpcountxy: integer; + xbottom,xtop: integer; + isxseries: boolean; + dpcounty1: integer; + islogx,islogy: boolean; + +begin + if not (trs_datapointsvalid in finfo.state) and visible then begin + dpcounty1:= 0; + finfo.datapoints:= nil; + include(finfo.state,trs_datapointsvalid); + dpcountx:= 0; + dpcounty:= 0; + with finfo do begin + isxseries:= (kind = trk_xseries); + islogx:= cto_logx in options; + islogy:= cto_logy in options; + bottommargin:= 0; + topmargin:= 0; + if xydata <> nil then begin + pox:= @xydata[0].re; + poy:= @xydata[0].im; + intx:= sizeof(complexty); + inty:= sizeof(complexty); + dpcountx:= length(xydata); + dpcounty:= dpcountx; + end + else begin + if xdatalist <> nil then begin + dpcountx:= xdatalist.count; + pox:= xdatalist.datapo; + intx:= finfo.xdatalist.size; + end + else begin + pox:= pointer(xdata); + intx:= sizeof(real); + dpcountx:= length(xdata); + end; + if ydatalist <> nil then begin + dpcounty:= ydatalist.count; + poy:= ydatalist.datapo; + inty:= ydatalist.size; + end + else begin + poy:= pointer(ydata); + inty:= sizeof(real); + dpcounty:= length(ydata); + end; + end; + end; + dpcountxy:= dpcountx; + if isxseries or (dpcounty < dpcountxy) then begin + dpcountxy:= dpcounty; + end; + if islogy then begin + yo:= -(chartln(finfo.ystart + finfo.yrange)); + ys:= -tcustomchart(fowner).traces.fscaley / (-chartln(finfo.ystart) - yo); + end + else begin + yo:= -finfo.ystart - finfo.yrange; + ys:= -tcustomchart(fowner).traces.fscaley / finfo.yrange; + end; + case finfo.kind of + trk_xy,trk_xseries: begin + lxo:= 0; + lxs:= 1; + if isxseries then begin + dpcounty1:= dpcounty-1; + rea1:= 0; + if maxcount > 1 then begin + int2:= maxcount - 1; + if (int2 > dpcounty1) and + (cto_adddataright in finfo.options) then begin + rea1:= {$ifdef FPC}real({$endif}1.0{$ifdef FPC}){$endif} - + dpcounty1 / int2; + end; + end + else begin + int2:= dpcounty1; + end; + if cto_logx in options then begin + lxo:= int2 * (finfo.xserstart/finfo.xserrange); + lxs:= finfo.xserrange; + xo:= -chartln(-(rea1 - finfo.xstart) * int2); + xs:= tcustomchart(fowner).traces.fscalex; + if int2 > 0 then begin + xs:= xs / (chartln((finfo.xstart+finfo.xrange) * int2)+xo); + end; + if xs <> 0 then begin + xo:= xo + 1/xs; + end; + end + else begin + xo:= (rea1 - finfo.xstart) * int2; + xs:= tcustomchart(fowner).traces.fscalex; + if int2 > 0 then begin + xs:= xs / (finfo.xrange * int2); + end; + if xs <> 0 then begin + xo:= xo + 1/xs; + end; + xo:= (finfo.xserstart*int2+xo)/(finfo.xserrange); + xs:= xs*finfo.xserrange; + end; + end + else begin + if cto_logx in options then begin + xo:= -chartln(finfo.xstart); + xs:= tcustomchart(fowner).traces.fscalex / + (chartln(finfo.xrange+finfo.xstart)+xo); + end + else begin + xo:= -finfo.xstart; + xs:= tcustomchart(fowner).traces.fscalex / finfo.xrange; + end; + end; + checkrange(dpcountxy); + if isxseries and (cto_seriescentered in finfo.options) and + (dpcounty > 0) then begin + xs:= xs*(dpcounty1/dpcounty); + xo:= xo + 0.5; + end; + + if (cto_xordered in finfo.options) or isxseries then begin + int4:= tcustomchart(fowner).traces.fsize.cx+3;//2; //cx + 1 + setlength(ar1,int4); + dec(int4); + xbottom:= minint; + xtop:= maxint; + for int1:= 0 to dpcountxy - 1 do begin + if isxseries then begin + if islogx then begin + int2:= round((chartln((int1+lxo)*lxs) + xo) * xs); + end + else begin + int2:= round((int1 + xo) * xs); + end; + end + else begin + if islogx then begin + int2:= pkround((chartln(preal(pox)^) + xo) * xs) + 1; + end + else begin + int2:= pkround((preal(pox)^ + xo) * xs) + 1; + end; + end; + if islogy then begin + int3:= pkround((chartln(preal(poy)^) + yo) * ys); + end + else begin + int3:= pkround((preal(poy)^ + yo) * ys); + end; + if int2 < 0 then begin + if int2 > xbottom then begin + xbottom:= int2; + end; + int2:= 0; + end; + if int2 > int4 then begin + if int2 < xtop then begin + xtop:= int2; + end; + int2:= int4; + end; + with ar1[int2] do begin + if not used then begin + used:= true; + first:= int3; + min:= int3; + max:= int3; + end + else begin + if int3 < min then begin + min:= int3; + end; + if int3 > max then begin + max:= int3; + end; + end; + last:= int3; + end; + if xtop <> maxint then begin + break; + end; + inc(pox,intx); + inc(poy,inty); + end; + with ar1[0] do begin //endpoints + first:= last; + min:= last; + max:= last; + end; + with ar1[high(ar1)] do begin + first:= last; + min:= last; + max:= last; + end; + setlength(finfo.datapoints,length(ar1)*4); //first->max->min->last + int2:= 0; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if used then begin + int3:= int1-1; + finfo.datapoints[int2].x:= int3; + finfo.datapoints[int2].y:= first; + inc(int2); + if max > first then begin + finfo.datapoints[int2].x:= int3; + finfo.datapoints[int2].y:= max; + inc(int2); + end; + if min < max then begin + finfo.datapoints[int2].x:= int3; + finfo.datapoints[int2].y:= min; + inc(int2); + end; + if last > min then begin + finfo.datapoints[int2].x:= int3; + finfo.datapoints[int2].y:= last; + inc(int2); + end; + end; + end; + end; + setlength(finfo.datapoints,int2); + if chartkind = tck_line then begin + with finfo do begin //adjust boundary values + //todo: extend window for image size + barlines:= nil; + if int2 > 1 then begin + if ar1[0].used then begin + bottommargin:= 1; + datapoints[0].y:= pkround(datapoints[0].y + + (datapoints[1].y - datapoints[0].y) * + (-1-xbottom)/ + (datapoints[1].x-xbottom)); + end; + if ar1[high(ar1)].used then begin + topmargin:= 1; + datapoints[int2-1].y:= pkround(datapoints[int2-1].y + + (datapoints[int2-2].y - datapoints[int2-1].y) * + (length(ar1)-xtop)/ + (datapoints[int2-2].x-xtop)); + end; + end; + end; + end + else begin //tck_barline + with finfo do begin + setlength(barlines,length(datapoints)); + case bar_ref of + br_top: begin + int2:= -1; + end; + br_bottom: begin + int2:= tcustomchart(fowner).traces.fsize.cy+1; + end; + else begin //br_zero + int2:= round(yo*ys); //zero position + if int2 < 0 then begin + int2:= -1; + end; + if int2 > tcustomchart(fowner).traces.fsize.cy+1 then begin + int2:= tcustomchart(fowner).traces.fsize.cy+1; + end; + end; + end; + for int1:= 0 to high(barlines) do begin + with barlines[int1] do begin + a.x:= datapoints[int1].x + bar_offset; + a.y:= datapoints[int1].y; + b.x:= a.x; + b.y:= int2; + end; + end; + end; + end; + end //xordered + else begin //xy + setlength(finfo.datapoints,dpcountxy); + for int1:= 0 to high(finfo.datapoints) do begin + if islogx then begin + finfo.datapoints[int1].x:= pkround((chartln(preal(pox)^) + xo)* xs); + end + else begin + finfo.datapoints[int1].x:= pkround((preal(pox)^ + xo)* xs); + end; + if islogy then begin + finfo.datapoints[int1].y:= pkround((chartln(preal(poy)^) + yo)* ys); + end + else begin + finfo.datapoints[int1].y:= pkround((preal(poy)^ + yo)* ys); + end; + inc(pox,intx); + inc(poy,inty); + end; + end; + end; + end; + end; +end; + +procedure ttrace.paint(const acanvas: tcanvas); +var + int1,int2: integer; + rect1,rect2: rectty; + bo1: boolean; + po1,pend: ppointty; + startindex,pointcount: integer; +begin + if (finfo.widthmm > 0) and visible then begin + acanvas.linewidthmm:= finfo.widthmm; + if finfo.dashes <> '' then begin + acanvas.dashes:= finfo.dashes; + end; + if finfo.chartkind = tck_bar then begin + if finfo.bar_width = 0 then begin + acanvas.drawlinesegments(finfo.barlines,finfo.color); + end + else begin + rect1.cx:= finfo.bar_width; + for int1:= 0 to high(finfo.barlines) do begin + with finfo.barlines[int1] do begin + rect1.pos:= a; + rect1.cy:= b.y - a.y; + acanvas.fillrect(rect1,finfo.color); + if finfo.bar_frame <> nil then begin + if rect1.cy < 0 then begin + rect1.y:= rect1.y + rect1.cy; + rect1.y:= -rect1.y; + end; + acanvas.save; + finfo.bar_frame.paintbackground(acanvas,rect1,true,true); + if finfo.bar_face <> nil then begin + rect2:= deflaterect(rect1,finfo.bar_frame.innerframe); + acanvas.remove(pointty(finfo.bar_frame.paintframe.topleft)); + finfo.bar_face.paint(acanvas,rect2); + end; + acanvas.restore; + finfo.bar_frame.paintoverlay(acanvas,rect1); + end + else begin + if finfo.bar_face <> nil then begin + finfo.bar_face.paint(acanvas,rect1); + end; + end; + end; + end; + end; + end + else begin + if finfo.datapoints <> nil then begin + if cto_smooth in finfo.options then begin + acanvas.smooth:= true; + end; + acanvas.capstyle:= cs_round; + acanvas.joinstyle:= js_round; + bo1:= (kind = trk_xseries) or (cto_xordered in finfo.options); + if bo1 then begin + po1:= pointer(finfo.datapoints); + inc(po1); + pend:= po1 + high(finfo.datapoints); + rect1:= acanvas.clipbox; + int2:= (acanvas.linewidth+1) div 2; + int1:= rect1.x - int2; + while po1 < pend do begin + if po1^.x >= int1 then begin + break; + end; + inc(po1); + end; + dec(po1); + startindex:= po1 - ppointty(pointer(finfo.datapoints)); + int1:= rect1.x+rect1.cx+int2; + dec(pend); + while po1 < pend do begin + if po1^.x > int1 then begin + break; + end; + inc(po1); + end; + inc(po1); + pointcount:= po1 - ppointty(pointer(finfo.datapoints)) - startindex; + end + else begin + startindex:= 0; + pointcount:= length(finfo.datapoints); + end; + if (fbreaks = nil) or bo1 then begin + acanvas.drawlines(finfo.datapoints,false,finfo.color,startindex,pointcount); + end + else begin + acanvas.drawlines(finfo.datapoints,fbreaks,false,finfo.color,startindex, + pointcount); + end; + acanvas.capstyle:= cs_butt; + acanvas.joinstyle:= js_miter; + acanvas.smooth:= false; + end; + end; + if finfo.dashes <> '' then begin + acanvas.dashes:= ''; + end; + end; +end; + +procedure ttrace.paint1(const acanvas: tcanvas; const imagesize: sizety; + const imagealignment: alignmentsty); +var + int1: integer; + pt1: pointty; +// rect1: rectty; +// co1: colorty; + bmp1{,bmp2}: tmaskedbitmap; +// margin: integer; +// imli1: timagelist; +begin + if not visible then begin + exit; + end; + fimagealignment:= imagealignment; + with ftraces do begin + fimli1:= actualimagelist; + if (fimli1 <> nil) and (finfo.imagenr >= 0) and + (finfo.imagenr < fimli1.count) then begin + pt1:= pointty(imagesize); + pt1.x:= pt1.x div 2; + pt1.y:= pt1.y div 2; + acanvas.remove(pt1); + frect1.size:= imagesize; + fco1:= finfo.colorimage; + if fco1 = cl_default then begin + fco1:= finfo.color; + end; + if not acanvas.highresdevice and + (imagealignment * [al_stretchx,al_stretchy] <> []) then begin + bmp1:= tmaskedbitmap.create(fimli1.kind{fimli1.monochrome}); + fbmp2.free; //in case of previous exception + fbmp2:= tmaskedbitmap.create(bmk_rgb{false}); + try + bmp1.masked:= fimli1.masked; + fimli1.getimage(finfo.imagenr,bmp1); + bmp1.colorforeground:= fco1; + bmp1.colorbackground:= tcuchart(fowner).actualcolorchart; +// bmp1.monochrome:= false; + bmp1.kind:= bmk_rgb; + bmp1.colormask:= true; + fbmp2.size:= imagesize; + bmp1.stretch(fbmp2); + for int1:= finfo.bottommargin to high(finfo.datapoints) - + finfo.topmargin do begin + fbmp2.paint(acanvas,finfo.datapoints[int1],[],fco1); + end; + finally + bmp1.free; +// bmp2.free; + end; + end + else begin + for int1:= finfo.bottommargin to high(finfo.datapoints) - + finfo.topmargin do begin + frect1.pos:= finfo.datapoints[int1]; + fimli1.paint(acanvas,finfo.imagenr,frect1,imagealignment,fco1); + end; + end; + acanvas.move(pt1); + end + else begin + fimli1:= nil; + end; + end; +end; + +procedure ttrace.paint2(const acanvas: tcanvas); +var + int1: integer; + pt1: pointty; +begin + if not visible then begin + exit; + end; + if finfo.legend <> '' then begin + int1:= finfo.legendrect.x + 2*fcurfont.glyphheight; + acanvas.drawstring(finfo.legend,mp(int1,finfo.legendrect.y+fcurfont.ascent), + fcurfont); + pt1.y:= finfo.legendrect.y + finfo.legendrect.cy div 2; + if finfo.widthmm > 0 then begin + acanvas.dashes:= finfo.dashes; + acanvas.linewidthmm:= finfo.widthmm; + acanvas.drawvect(mp(finfo.legendrect.x+1,pt1.y), + gd_right,2*fcurfont.glyphheight-3,finfo.color); + acanvas.dashes:= ''; + acanvas.linewidthmm:= 0; + end; + pt1.x:= int1 - fcurfont.glyphheight; //image center + if fimli1 <> nil then begin + if fbmp2 <> nil then begin + pt1.x:= pt1.x - fbmp2.width div 2; + pt1.y:= pt1.x - fbmp2.height div 2; + fbmp2.paint(acanvas,pt1,[],fco1); + end + else begin + frect1.x:= pt1.x - frect1.cx div 2; + frect1.y:= pt1.y - frect1.cy div 2; + fimli1.paint(acanvas,finfo.imagenr,frect1,fimagealignment,fco1); + end; + end; + end; + fbmp2.free; + fbmp2:= nil; +end; + +procedure ttrace.clip2(const acanvas: tcanvas); +//const +// padding = 1; +//var +// rect1: rectty; +begin + if not visible then begin + exit; + end; + if finfo.legend <> '' then begin + fcurfont:= legend_font; +{ + rect1.pos:= finfo.legendpos; + rect1.cx:= acanvas.getstringwidth(finfo.legend,fcurfont)+ + 2*fcurfont.glyphheight + 2*padding; + rect1.cy:= fcurfont.glyphheight + 2*padding; + rect1.y:= rect1.y - fcurfont.ascent - padding; + rect1.x:= rect1.x - padding; + acanvas.subcliprect(rect1); +} + acanvas.subcliprect(finfo.legendrect); + end; +end; + +procedure ttrace.setcolor(const avalue: colorty); +begin + if finfo.color <> avalue then begin + finfo.color:= avalue; + tcustomchart(fowner).traces.change; + end; +end; + +procedure ttrace.setcolorimage(const avalue: colorty); +begin + if finfo.colorimage <> avalue then begin + finfo.colorimage:= avalue; + tcustomchart(fowner).traces.change; + end; +end; + +procedure ttrace.setwidthmm(const avalue: real); +begin + finfo.widthmm:= avalue; + tcustomchart(fowner).traces.change; +end; + +procedure ttrace.setdashes(const avalue: string); +begin + finfo.dashes:= avalue; + tcustomchart(fowner).traces.change; +end; + +procedure ttrace.setxserstart(const avalue: real); +begin + finfo.xserstart:= avalue; + datachange; +end; + +procedure ttrace.setxstart(const avalue: real); +begin + finfo.xstart:= avalue; + flnxstart:= chartln(avalue); + flnxrange:= chartln(finfo.xstart+finfo.xrange)-flnxstart; + datachange; +end; + +procedure ttrace.setxrange(const avalue: real); +begin + if avalue = 0 then begin + scaleerror; + end; + finfo.xrange:= avalue; + flnxrange:= chartln(finfo.xstart+finfo.xrange)-flnxstart; + datachange; +end; + +procedure ttrace.setxserrange(const avalue: real); +begin + if avalue = 0 then begin + scaleerror; + end; + finfo.xserrange:= avalue; + datachange; +end; + +procedure ttrace.setystart(const avalue: real); +begin + finfo.ystart:= avalue; + flnystart:= chartln(avalue); + flnyrange:= chartln(finfo.ystart+finfo.yrange)-flnystart; + datachange; +end; + +procedure ttrace.setyrange(const avalue: real); +begin + if avalue = 0 then begin + scaleerror; + end; + finfo.yrange:= avalue; + flnyrange:= chartln(finfo.ystart+finfo.yrange)-flnystart; + datachange; +end; + +procedure ttrace.setoptions(const avalue: charttraceoptionsty); +begin + if avalue <> finfo.options then begin + finfo.options:= avalue {- [cto_stockglyphs]}; + datachange; + end; +end; + +procedure ttrace.setchartkind(const avalue: tracechartkindty); +begin + if finfo.chartkind <> avalue then begin + finfo.chartkind:= avalue; + datachange; + end; +end; + +procedure ttrace.setbar_offset(const avalue: integer); +begin + if finfo.bar_offset <> avalue then begin + finfo.bar_offset:= avalue; + datachange; + end; +end; + +procedure ttrace.setbar_width(const avalue: integer); +begin + if finfo.bar_width <> avalue then begin + finfo.bar_width:= avalue; + datachange; + end; +end; + +procedure ttrace.setbar_ref(const avalue: barrefty); +begin + if finfo.bar_ref <> avalue then begin + finfo.bar_ref:= avalue; + datachange; + end; +end; + +procedure ttrace.scaleerror; +begin + raise exception.create('Range can not be 0.'); +end; + +procedure ttrace.setkind(const avalue: tracekindty); +begin + if finfo.kind <> avalue then begin + finfo.kind:= avalue; + datachange; + end; +end; + +procedure ttrace.setstart(const avalue: integer); +begin + if finfo.start <> avalue then begin + finfo.start:= avalue; + datachange; + end; +end; + +procedure ttrace.setmaxcount(const avalue: integer); +begin + if finfo.maxcount <> avalue then begin + finfo.maxcount:= avalue; + datachange; + end; +end; + +procedure ttrace.addxseriesdata(const avalue: real); +begin + finfo.ydatalist:= nil; + if (finfo.maxcount = 0) or (length(finfo.ydata) < finfo.maxcount) then begin + setlength(finfo.ydata,high(finfo.ydata) + 2); + end + else begin + move(finfo.ydata[1],finfo.ydata[0], + sizeof(finfo.ydata[0])*high(finfo.ydata)); + end; + finfo.ydata[high(finfo.ydata)]:= avalue; + datachange; +end; + +procedure ttrace.insertxseriesdata(const avalue: xseriesdataty); +begin + finfo.ydatalist:= nil; + insertitem(finfo.ydata,avalue.index,avalue.value); + datachange; +end; + +procedure ttrace.readxseriescount(reader: treader); +begin + maxcount:= reader.readinteger; +end; + +procedure ttrace.readxscale(reader: treader); +begin + xrange:= reader.readfloat; +end; + +procedure ttrace.readxoffset(reader: treader); +begin + xstart:= -reader.readfloat; +end; + +procedure ttrace.readyscale(reader: treader); +begin + yrange:= reader.readfloat; +end; + +procedure ttrace.readyoffset(reader: treader); +begin + ystart:= -reader.readfloat; +end; + +procedure ttrace.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('xseriescount',{$ifdef FPC}@{$endif}readxseriescount, + nil,false); + filer.defineproperty('xoffset',{$ifdef FPC}@{$endif}readxoffset, + nil,false); + filer.defineproperty('xscale',{$ifdef FPC}@{$endif}readxscale, + nil,false); + filer.defineproperty('yoffset',{$ifdef FPC}@{$endif}readyoffset, + nil,false); + filer.defineproperty('yscale',{$ifdef FPC}@{$endif}readyscale, + nil,false); +end; + +procedure ttrace.setimagenr(const avalue: imagenrty); +begin + if finfo.imagenr <> avalue then begin + finfo.imagenr:= avalue; + datachange; + end; +end; + +function ttrace.getimagelist: timagelist; +begin + result:= ftraces.actualimagelist; +end; + +procedure ttrace.assign(source: tpersistent); +begin + if source is ttrace then begin + with ttrace(source) do begin + self.finfo:= finfo; + datachange; + end; + end + else begin + inherited; + end; +end; + +procedure ttrace.clear; +begin + xydata:= nil; + fbreaks:= nil; +end; + +procedure ttrace.addxydata(const x: real; const y: real); +var + int1,int2: integer; +begin + with finfo do begin + xdatalist:= nil; + ydatalist:= nil; + if xydata <> nil then begin + if cto_xordered in options then begin + int2:= 0; + for int1:= high(xydata) downto 0 do begin + if xydata[int1].re <= x then begin + int2:= int1+1; + break; + end; + end; + insertitem(xydata,int2,makecomplex(x,y)); + end + else begin + setlength(xydata,high(xydata)+2); + with xydata[high(xydata)] do begin + re:= x; + im:= y; + end; + end; + end + else begin + if (xdata <> nil) then begin + if cto_xordered in options then begin + int2:= 0; + for int1:= high(xdata) downto 0 do begin + if xdata[int1] <= x then begin + int2:= int1+1; + break; + end; + end; + setlength(ydata,length(xdata)); + insertitem(xdata,int2,x); + insertitem(ydata,int2,y); + end + else begin + setlength(xdata,high(xdata)+2); + setlength(ydata,length(xdata)); + xdata[high(xdata)]:= x; + ydata[high(xdata)]:= y; + end; + end + else begin + if (ydata <> nil) then begin + if cto_xordered in options then begin + end + else begin + setlength(ydata,high(ydata)+2); + setlength(xdata,length(ydata)); + xdata[high(xdata)]:= x; + ydata[high(xdata)]:= y; + end; + end + else begin + setlength(xydata,1); + with xydata[0] do begin + re:= x; + im:= y; + end; + end; + end; + end; + end; + datachange; +end; + +function ttrace.getlogx: boolean; +begin + result:= cto_logx in options; +end; + +procedure ttrace.setlogx(const avalue: boolean); +begin + if avalue then begin + options:= options + [cto_logx]; + end + else begin + options:= options - [cto_logx]; + end; +end; + +function ttrace.getlogy: boolean; +begin + result:= cto_logy in options; +end; + +procedure ttrace.setlogy(const avalue: boolean); +begin + if avalue then begin + options:= options + [cto_logy]; + end + else begin + options:= options - [cto_logy]; + end; +end; + +function ttrace.getvisible: boolean; +begin + result:= not (cto_invisible in finfo.options); +end; + +procedure ttrace.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [cto_invisible]; + end + else begin + options:= options + [cto_invisible]; + end; +end; + +function ttrace.getsmooth: boolean; +begin + result:= cto_smooth in options; +end; + +procedure ttrace.setsmooth(const avalue: boolean); +begin + if avalue then begin + options:= options + [cto_smooth]; + end + else begin + options:= options - [cto_smooth]; + end; +end; + +function ttrace.getxdatapo: preal; +begin + result:= pointer(finfo.xdata); + if xdatalist <> nil then begin + result:= xdatalist.datapo; + end; +end; + +function ttrace.getydatapo: preal; +begin + result:= pointer(finfo.ydata); + if ydatalist <> nil then begin + result:= ydatalist.datapo; + end; +end; + +function ttrace.getxydatapo: pcomplexty; +begin + result:= pointer(finfo.xydata); +end; + +function ttrace.getcount: integer; +begin + result:= 0; + with finfo do begin + if ydata <> nil then begin + result:= length(ydata); + exit; + end; + if xdata <> nil then begin + result:= length(xdata); + exit; + end; + if xydata <> nil then begin + result:= length(xydata); + exit; + end; + if ydatalist <> nil then begin + result:= ydatalist.count; + exit; + end; + if xdatalist <> nil then begin + result:= xdatalist.count; + exit; + end; + end; +end; + +function ttrace.getxvalue(const index: integer): real; +begin + result:= getxitempo(index)^; +end; + +procedure ttrace.setxvalue(const index: integer; const avalue: real); +begin + getxitempo(index)^:= avalue; + datachange; +end; + +function ttrace.getyvalue(const index: integer): real; +begin + result:= getyitempo(index)^; +end; + +procedure ttrace.setyvalue(const index: integer; const avalue: real); +begin + getyitempo(index)^:= avalue; + datachange; +end; + +function ttrace.getxyvalue(const index: integer): complexty; +begin + result.re:= getxitempo(index)^; + result.im:= getyitempo(index)^; +end; + +procedure ttrace.setxyvalue(const index: integer; const avalue: complexty); +begin + getxitempo(index)^:= avalue.re; + getyitempo(index)^:= avalue.im; + datachange; +end; + +procedure ttrace.addxydata(const xy: complexty); +begin + addxydata(xy.re,xy.im); +end; + +function ttrace.getxitempo(const aindex: integer): preal; +begin + with finfo do begin + if xdatalist <> nil then begin + result:= xdatalist.getitempo(aindex); + end + else begin + if xdata <> nil then begin + checkarrayindex(xdata,aindex); + result:= @xdata[aindex]; + end + else begin + checkarrayindex(xydata,aindex); + result:= @xydata[aindex].re; + end; + end; + end; +end; + +function ttrace.getyitempo(const aindex: integer): preal; +begin + with finfo do begin + if ydatalist <> nil then begin + result:= ydatalist.getitempo(aindex); + end + else begin + if ydata <> nil then begin + checkarrayindex(ydata,aindex); + result:= @ydata[aindex]; + end + else begin + checkarrayindex(xydata,aindex); + result:= @xydata[aindex].im; + end + end; + end; +end; + +procedure ttrace.getdatapo(out xpo,ypo: preal; //xpo nil for xseries + out xcount,ycount,xstep,ystep: integer); +begin + ystep:= 1; + xstep:= 1; + xpo:= nil; + ypo:= nil; + xcount:= 0; + ycount:= 0; + with finfo do begin + if ydatalist <> nil then begin + ypo:= ydatalist.datapo; + ycount:= ydatalist.count; + end + else begin + if ydata <> nil then begin + ypo:= pointer(ydata); + ycount:= length(ydata); + end + else begin + ypo:= pointer(xydata); + ycount:= length(xydata); + ystep:= 2; + if ypo <> nil then begin + inc(ypo); + end; + end; + end; + if kind <> trk_xseries then begin + if xdatalist <> nil then begin + xpo:= xdatalist.datapo; + xcount:= xdatalist.count; + end + else begin + if xdata <> nil then begin + xpo:= pointer(xdata); + xcount:= length(xdata); + end + else begin + xpo:= pointer(xydata); + xcount:= length(xydata); + ystep:= 2; + end; + end; + end; + end; +end; + +procedure ttrace.deletedata(const aindex: integer); +begin + if (aindex < 0) or (aindex >= count) then begin + tlist.error(slistindexerror, aindex); + end; + datachange; + with finfo do begin + if ydata <> nil then begin + deleteitem(ydata,aindex); + end; + if xdata <> nil then begin + deleteitem(xdata,aindex); + end; + if xydata <> nil then begin + deleteitem(xydata,aindex); + end; + if ydatalist <> nil then begin + ydatalist.deletedata(aindex); + end; + if xdatalist <> nil then begin + xdatalist.deletedata(aindex); + end; + end; +end; + +procedure ttrace.deletedata(const aindexar: integerarty); +var + int1,int2,int3: integer; + ar1: integerarty; +begin + ar1:= copy(aindexar); + for int1:= 0 to high(ar1) do begin + int2:= ar1[int1]; + deletedata(int2); + for int3:= int1+1 to high(ar1) do begin + if ar1[int3] >= int2 then begin + dec(ar1[int3]); + end; + end; + end; +end; + +function ttrace.getbar_frame: tframe; +begin + tcustomchart(fowner).getoptionalobject(finfo.bar_frame, + {$ifdef FPC}@{$endif}createbar_frame); + result:= finfo.bar_frame; +end; + +procedure ttrace.setbar_frame(const avalue: tframe); +begin + tcustomchart(fowner).setoptionalobject(avalue,finfo.bar_frame, + {$ifdef FPC}@{$endif}createbar_frame); + datachange; +end; + +function ttrace.getbar_face: tface; +begin + tcustomchart(fowner).getoptionalobject(finfo.bar_face,{$ifdef FPC}@{$endif}createbar_face); + result:= finfo.bar_face; +end; + +procedure ttrace.setbar_face(const avalue: tface); +begin + tcustomchart(fowner).setoptionalobject(avalue,finfo.bar_face, + {$ifdef FPC}@{$endif}createbar_face); + datachange; +end; + +procedure ttrace.createbar_frame; +begin + if finfo.bar_frame = nil then begin + tbarframe.create(iframe(self)); + end; +end; + +procedure ttrace.createbar_face; +begin + if finfo.bar_face = nil then begin + finfo.bar_face:= tface.create(iface(self)); + end; +end; + +procedure ttrace.setframeinstance(instance: tcustomframe); +begin + finfo.bar_frame:= tframe(instance); +end; + +procedure ttrace.setstaticframe(value: boolean); +begin + //dummy +end; + +function ttrace.getstaticframe: boolean; +begin + result:= false; +end; + +procedure ttrace.scrollwidgets(const dist: pointty); +begin + //dummy +end; + +procedure ttrace.clientrectchanged; +begin + invalidate; +end; + +function ttrace.getcomponentstate: tcomponentstate; +begin + result:= tcustomchart(fowner).componentstate; +end; + +function ttrace.getmsecomponentstate: msecomponentstatesty; +begin + result:= tcustomchart(fowner).msecomponentstate; +end; + +procedure ttrace.invalidate; +begin + tcustomchart(fowner).invalidate; +end; + +procedure ttrace.invalidatewidget; +begin + tcustomchart(fowner).invalidatewidget; +end; + +procedure ttrace.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + tcustomchart(fowner).invalidaterect(rect,org,noclip); +end; + +function ttrace.getwidget: twidget; +begin + result:= tcustomchart(fowner); +end; + +function ttrace.getwidgetrect: rectty; +begin + result:= tcustomchart(fowner).innerclientrect; +end; + +function ttrace.getframestateflags: framestateflagsty; +begin + result:= []; +end; + +function ttrace.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; + if acolor = cl_default then begin + result:= finfo.color; + end + else begin + result:= acolor; + end; +end; + +function ttrace.getclientrect: rectty; +begin + result:= tcustomchart(fowner).getdialrect; +end; + +procedure ttrace.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + tcustomchart(fowner).setlinkedvar(source,dest,linkintf); +end; + +procedure ttrace.widgetregioninvalid; +begin + //dummy +end; + +procedure ttrace.minmaxx1(var amin: real; var amax: real); +var + min,max: real; + int1: integer; + pox,poy: preal; + cx,cy,sx,sy: integer; +begin + if kind = trk_xseries then begin + min:= xserstart; + max:= min + xserrange; + end + else begin + getdatapo(pox,poy,cx,cy,sx,sy); + if cx = 0 then begin + min:= 0; + max:= 1; + end + else begin + min:= amin; + max:= amax; + for int1:= cx-1 downto 0 do begin + if pox^ > max then begin + max:= pox^; + end; + if pox^ < min then begin + min:= pox^; + end; + inc(pox,sx); + end; + end; + end; + if min < amin then begin + amin:= min; + end; + if max > amax then begin + amax:= max; + end; +end; + +procedure ttrace.minmaxy1(var amin: real; var amax: real); +var + min,max: real; + int1: integer; + pox,poy: preal; + cx,cy,sx,sy: integer; +begin + getdatapo(pox,poy,cx,cy,sx,sy); + if cy = 0 then begin + min:= 0; + max:= 1; + end + else begin + min:= amin; + max:= amax; + for int1:= cy-1 downto 0 do begin + if poy^ > max then begin + max:= poy^; + end; + if poy^ < min then begin + min:= poy^; + end; + inc(poy,sy); + end; + end; + if min < amin then begin + amin:= min; + end; + if max > amax then begin + amax:= max; + end; +end; + +procedure ttrace.minmaxx(out amin: real; out amax: real); +begin + amin:= bigreal; + amax:= -bigreal; + minmaxx1(amin,amax); + if amax < amin then begin + amin:= 0; + amax:= 0; + end; +end; + +procedure ttrace.minmaxy(out amin: real; out amax: real); +begin + amin:= bigreal; + amax:= -bigreal; + minmaxy1(amin,amax); + if amax < amin then begin + amin:= 0; + amax:= 0; + end; +end; + +procedure ttrace.autoscalex(const astartmargin: real = 0; + const aendmargin: real = 0); +var + min,max: real; +begin + minmaxx(min,max); + xrange:= calctracerange(min,max,cto_logx in options,astartmargin,aendmargin); + xstart:= min; +end; + +procedure ttrace.autoscaley(const astartmargin: real = 0; + const aendmargin: real = 0); +var + min,max: real; +begin + minmaxy(min,max); + yrange:= calctracerange(min,max,cto_logy in options,astartmargin,aendmargin); + ystart:= min; +end; + +procedure ttrace.fontchanged(const sender: tobject); +begin + legendchange; +end; + +function ttrace.isfontstored: boolean; +begin + result:= finfo.font <> nil; +end; + +procedure ttrace.createfont; +begin + if finfo.font = nil then begin + finfo.font:= ttracefont.create; + finfo.font.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function ttrace.getlegend_font: ttracefont; +begin + getoptionalobject(tcustomchart(fowner).componentstate, + finfo.font,{$ifdef FPC}@{$endif}createfont); + if finfo.font <> nil then begin + result:= finfo.font; + end + else begin +{$warnings off} + result:= ttracefont(ftraces.getfont); +{$warnings on} + end; +end; + +procedure ttrace.setlegend_font(const avalue: ttracefont); +begin + if avalue <> finfo.font then begin + setoptionalobject(tcustomchart(fowner).componentstate, + avalue,finfo.font,{$ifdef FPC}@{$endif}createfont); + legendchange; + end; +end; + +procedure ttrace.setlegend_caption(const avalue: msestring); +begin + finfo.legend:= avalue; + legendchange; +end; + +function ttrace.hintx: msestring; +begin + result:= fhint_captionx; + if result = '' then begin + result:= tcustomchart(fowner).tracehint_captionx; + end; +end; + +function ttrace.hinty: msestring; +begin + result:= fhint_captiony; + if result = '' then begin + result:= tcustomchart(fowner).tracehint_captiony; + end; +end; + +{ ttracesfont } + +class function ttracesfont.getinstancepo(owner: tobject): pfont; +begin + result:= @ttraces(owner).ffont; +end; + +{ ttraces } + +constructor ttraces.create(const aowner: tcustomchart); +begin + fkind:= trk_xseries; + fxserrange:= 1; + fxrange:= 1; + fyrange:= 1; + flegend_dist:= defaultlegenddist; + flegend_fitdist:= defaultlegenddist; + flegend_placement:= defaultlegendplacement; + inherited create(aowner,ownedeventpersistentclassty(getitemclasstype)); +end; + +destructor ttraces.destroy; +begin + inherited; + ffont.free; +end; + +class function ttraces.getitemclasstype: persistentclassty; +begin + result:= ttrace; +end; + +procedure ttraces.change; +begin + exclude(ftracestate,trss_graphicvalid); + tcuchart(fowner).invalidate; +end; + +procedure ttraces.clientrectchanged; +var + int1: integer; +begin + exclude(ftracestate,trss_graphicvalid); + for int1:= 0 to high(fitems) do begin + exclude(ptraceaty(fitems)^[int1].finfo.state,trs_datapointsvalid); + end; +end; + +procedure ttraces.paint(const acanvas: tcanvas); +var + int1: integer; + size1: sizety; + align1: alignmentsty; + imli1: timagelist; +begin + for int1:= 0 to high(fitems) do begin + ptraceaty(fitems)^[int1].paint(acanvas); + end; + align1:= []; + size1:= nullsize; + imli1:= actualimagelist; + if imli1 <> nil then begin + size1:= imli1.size; + if fimage_widthmm <> 0 then begin + size1.cx:= round(fimage_widthmm*acanvas.ppmm); + align1:= align1 + [al_stretchx,al_intpol]; + end; + if fimage_heightmm <> 0 then begin + size1.cy:= round(fimage_heightmm*acanvas.ppmm); + align1:= align1 + [al_stretchy,al_intpol]; + end; + end; + exclude(align1,al_intpol); + for int1:= 0 to high(fitems) do begin + ptraceaty(fitems)^[int1].paint1(acanvas,size1,align1); + end; + acanvas.linewidth:= 0; +end; + +procedure ttraces.clipoverlay(const acanvas: tcanvas); +var + int1: integer; +begin + checkgraphic; + if flegend_placement <> tlp_none then begin + for int1:= 0 to high(fitems) do begin + ptraceaty(fitems)^[int1].clip2(acanvas); + end; + end; +end; + +procedure ttraces.paintoverlay(const acanvas: tcanvas); +var + int1: integer; +begin + if flegend_placement <> tlp_none then begin + for int1:= 0 to high(fitems) do begin + ptraceaty(fitems)^[int1].paint2(acanvas); + end; + end; +end; + +procedure ttraces.calclegendrect; +type + rowinfoty = record + last: integer; + width: integer; + height: integer; + end; +var + int1,int2,int3: integer; + x1,y1,x2,y2: integer; + canvas1: tcanvas; + rect1: rectty; + ar1: array of rowinfoty; + + procedure pushrow(const aindex: integer); + begin + with ar1[int2] do begin + last:= aindex; + width:= x1; + height:= y1; + end; + y2:= y2 + y1; + inc(int2); + x1:= -1; + y1:= 0; + end; //pushrow + +begin + if not (trss_graphicvalid in ftracestate) then begin + canvas1:= tcustomchart(fowner).getcanvas; + rect1:= tcustomchart(fowner).getdialrect; + fsize:= rect1.size; + if fsize.cx < 0 then begin + fsize.cx:= 0; + end; + if fsize.cy < 0 then begin + fsize.cy:= 0; + end; + fscalex:= fsize.cx; + fscaley:= fsize.cy; + + x1:= 0; + y1:= 0; + for int1:= 0 to high(fitems) do begin + with ptraceaty(fitems)^[int1] do begin + if (finfo.legend <> '') and not (cto_invisible in finfo.options) then begin + with finfo.legendrect do begin + fcurfont:= getlegend_font; + cy:= fcurfont.glyphheight; + cx:= 2*cy + canvas1.getstringwidth(finfo.legend,fcurfont); + if cx > x1 then begin + x1:= cx; + end; + y1:= y1 + cy; + end; + end + else begin + finfo.legendrect:= nullrect; + end; + end; + end; + case flegend_placement of + tlp_xy: begin + x2:= round(flegend_pos.re*fsize.cx) - x1 div 2; + int1:= fsize.cx - x1 - flegend_dist; + if x2 > int1 then begin + x2:= int1; + end; + if x2 < flegend_dist then begin + x2:= flegend_dist; + end; + y2:= fsize.cy - round(flegend_pos.im*fsize.cy) - y1 div 2; + int1:= fsize.cy - y1 - flegend_dist; + if y2 > int1 then begin + y2:= int1; + end; + if y2 < flegend_dist then begin + y2:= flegend_dist; + end; + + x2:= x2 + rect1.x; + y2:= y2 + rect1.y; + for int1:= 0 to high(fitems) do begin + with ptraceaty(fitems)^[int1].finfo.legendrect do begin + x:= x2; + y:= y2; + y2:= y2 + cy; + end; + end; + end; + tlp_above,tlp_below: begin + setlength(ar1,length(fitems)); //max + if ar1 <> nil then begin + x2:= rect1.cx; //max width + y2:= 0; //tot height + with ptraceaty(fitems)^[0].finfo.legendrect do begin + x1:= cx; + y1:= cy; + end; + int2:= 0; + for int1:= 1 to high(fitems) do begin + with ptraceaty(fitems)^[int1].finfo.legendrect do begin + if x1+cx+1 > x2 then begin + pushrow(int1-1); + end; + x1:= x1 + cx + 1; + if cy > y1 then begin + y1:= cy; + end; + end; + end; + if (int2 = 0) or (high(fitems) > 0) then begin + pushrow(high(fitems)); //last or single + end; + setlength(ar1,int2); + if flegend_placement = tlp_above then begin + y1:= rect1.y - y2 - flegend_dist; + end + else begin + y1:= rect1.y + rect1.cy + flegend_dist; + end; + int2:= 0; + x2:= 0; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if x2 < width then begin + x2:= width; + end; + end; + end; + flegendsize.cx:= x2; + flegendsize.cy:= y2; + x2:= rect1.x + (rect1.cx - x2) div 2; //center block + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + x1:= x2; + for int3:= int2 to last do begin + with ptraceaty(fitems)^[int3].finfo.legendrect do begin + x:= x1; + y:= y1 + (height - cy) div 2; + x1:= x1 + cx + 1; + end; + end; + int2:= last + 1; + y1:= y1 + height; + end; + end; + end; + end; + end; + end; +end; + +procedure ttraces.checkgraphic; +var + int1: integer; +begin + if not (trss_graphicvalid in ftracestate) then begin + calclegendrect; + for int1:= 0 to high(fitems) do begin + with ptraceaty(fitems)^[int1] do begin + checkgraphic; + end; + end; + include(ftracestate,trss_graphicvalid); + end; +end; + +procedure ttraces.setitems(const index: integer; const avalue: ttrace); +begin + inherited getitems(index).assign(avalue); +end; + +function ttraces.getitems(const index: integer): ttrace; +begin + result:= ttrace(inherited getitems(index)); +end; + +function ttraces.itembyname(const aname: string): ttrace; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fitems) do begin + if ttrace(fitems[int1]).name = aname then begin + result:= ttrace(fitems[int1]); + break; + end; + end; +end; + +procedure ttraces.setxserstart(const avalue: real); +var + int1: integer; +begin + fxserstart:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).xserstart:= avalue; + end; + end; +end; + +procedure ttraces.setxstart(const avalue: real); +var + int1: integer; +begin + fxstart:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).xstart:= avalue; + end; + end; +end; + +procedure ttraces.setystart(const avalue: real); +var + int1: integer; +begin + fystart:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).ystart:= avalue; + end; + end; +end; + +procedure ttraces.setxserrange(const avalue: real); +var + int1: integer; +begin + fxserrange:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).xserrange:= avalue; + end; + end; +end; + +procedure ttraces.setxrange(const avalue: real); +var + int1: integer; +begin + fxrange:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).xrange:= avalue; + end; + end; +end; + +procedure ttraces.setyrange(const avalue: real); +var + int1: integer; +begin + fyrange:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).yrange:= avalue; + end; + end; +end; + +procedure ttraces.setstart(const avalue: integer); +var + int1: integer; +begin + fstart:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).start:= avalue; + end; + end; +end; + +procedure ttraces.setmaxcount(const avalue: integer); +var + int1: integer; +begin + fmaxcount:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).maxcount:= avalue; + end; + end; +end; + +procedure ttraces.setkind(const avalue: tracekindty); +var + int1: integer; +begin + if fkind <> avalue then begin + fkind:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + ttrace(fitems[int1]).kind:= avalue; + end; + end; + end; +end; + +procedure ttraces.setchartkind(const avalue: tracechartkindty); +var + int1: integer; +begin + if fchartkind <> avalue then begin + fchartkind:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + ttrace(fitems[int1]).chartkind:= avalue; + end; + end; + end; +end; + +procedure ttraces.setbar_width(const avalue: integer); +var + int1: integer; +begin + if fbar_width <> avalue then begin + fbar_width:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + ttrace(fitems[int1]).bar_width:= avalue; + end; + end; + end; +end; + +procedure ttraces.setbar_ref(const avalue: barrefty); +var + int1: integer; +begin + if fbar_ref <> avalue then begin + fbar_ref:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + ttrace(fitems[int1]).bar_ref:= avalue; + end; + end; + end; +end; + +procedure ttraces.setoptions(const avalue: charttraceoptionsty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}byte{$endif}; +begin + if foptions <> avalue then begin + mask:= {$ifdef FPC}longword{$else}word{$endif}(avalue) xor + {$ifdef FPC}longword{$else}word{$endif}(foptions); + foptions:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + ttrace(fitems[int1]).options:= charttraceoptionsty(replacebits( + {$ifdef FPC}longword{$else}word{$endif}(foptions), + {$ifdef FPC}longword{$else}word{$endif}( + ttrace(fitems[int1]).options),mask)); + end; + end; + end; +end; + +procedure ttraces.createitem(const index: integer; var item: tpersistent); +begin + inherited; + with ttrace(item) do begin + kind:= self.fkind; + chartkind:= self.fchartkind; + bar_width:= self.fbar_width; + bar_ref:= self.fbar_ref; + options:= self.foptions; + xserstart:= self.fxserstart; + xstart:= self.fxstart; + ystart:= self.fystart; + xserrange:= self.fxserrange; + xrange:= self.fxrange; + yrange:= self.fyrange; + start:= self.fstart; + maxcount:= self.fmaxcount; + end; +end; + +procedure ttraces.assign(source: tpersistent); +begin + if source is ttraces then begin + with ttraces(source) do begin + self.fxserstart:= fxserstart; + self.fxstart:= fxstart; + self.fystart:= fystart; + self.fxserrange:= fxserrange; + self.fxrange:= fxrange; + self.fyrange:= fyrange; + self.maxcount:= fmaxcount; + end; + end; + inherited; +end; + +procedure ttraces.setimage_list(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fimage_list)); + change; +end; + +procedure ttraces.setimage_widthmm(const avalue: real); +begin + fimage_widthmm:= avalue; + change; +end; + +procedure ttraces.setimage_heightmm(const avalue: real); +begin + fimage_heightmm:= avalue; + change; +end; + +function ttraces.getfont: ttracesfont; +begin + getoptionalobject(tcustomchart(fowner).componentstate, + ffont,{$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin +{$warnings off} + result:= ttracesfont(tcustomchart(fowner).getfont); +{$warnings on} + end; +end; + +procedure ttraces.setfont(const avalue: ttracesfont); +begin + if avalue <> ffont then begin + setoptionalobject(tcustomchart(fowner).componentstate, + avalue,ffont,{$ifdef FPC}@{$endif}createfont); + layoutchanged; + end; +end; + +procedure ttraces.dostatread(const reader: tstatreader); +var + int1: integer; + mstr1: msestring; +begin + for int1:= 0 to count - 1 do begin + mstr1:= inttostrmse(int1); + with ttrace(fitems[int1]) do begin + if cto_savexscale in foptions then begin + xstart:= reader.readreal('xstart'+mstr1,xstart); + xrange:= reader.readreal('xrange'+mstr1,xrange); + end; + if cto_saveyscale in foptions then begin + ystart:= reader.readreal('ystart'+mstr1,ystart); + yrange:= reader.readreal('yrange'+mstr1,yrange); + end; + end; + end; +end; + +procedure ttraces.dostatwrite(const writer: tstatwriter); +var + int1: integer; + mstr1: msestring; +begin + for int1:= 0 to count - 1 do begin + mstr1:= inttostrmse(int1); + with ttrace(fitems[int1]) do begin + if cto_savexscale in foptions then begin + writer.writereal('xstart'+mstr1,xstart); + writer.writereal('xrange'+mstr1,xrange); + end; + if cto_saveyscale in foptions then begin + writer.writereal('ystart'+mstr1,ystart); + writer.writereal('yrange'+mstr1,yrange); + end; + end; + end; +end; + +function ttraces.getlogx: boolean; +begin + result:= cto_logx in options; +end; + +procedure ttraces.setlogx(const avalue: boolean); +begin + if avalue then begin + options:= options + [cto_logx]; + end + else begin + options:= options - [cto_logx]; + end; +end; + +function ttraces.getlogy: boolean; +begin + result:= cto_logy in options; +end; + +procedure ttraces.setlogy(const avalue: boolean); +begin + if avalue then begin + options:= options + [cto_logy]; + end + else begin + options:= options - [cto_logy]; + end; +end; + +function ttraces.actualimagelist: timagelist; +begin + result:= fimage_list; + if (result = nil) and (cto_stockglyphs in foptions) then begin + result:= stockobjects.glyphs; + end; +end; + +procedure ttraces.setdata(const adata: realararty); +var + int1: integer; +begin + for int1:= 0 to high(adata) do begin + if int1 > high(fitems) then begin + break; + end; + ttrace(fitems[int1]).ydata:= adata[int1]; + end; +end; + +procedure ttraces.setdata(const adata: complexararty); +var + int1: integer; +begin + for int1:= 0 to high(adata) do begin + if int1 > high(fitems) then begin + break; + end; + ttrace(fitems[int1]).xydata:= adata[int1]; + end; +end; + +function ttraces.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +procedure ttraces.createfont; +begin + if font = nil then begin + ffont:= ttracesfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +procedure ttraces.fontchanged(const sender: tobject); +begin + layoutchanged; +end; + +procedure ttraces.setlegend_pos(const avalue: complexty); +begin + if (flegend_pos.re <> avalue.re) or (flegend_pos.im <> avalue.im) then begin + flegend_pos:= avalue; + change; + end; +end; + +procedure ttraces.setlegend_x(const avalue: real); +begin + legend_pos:= mc(avalue,flegend_pos.im); +end; + +procedure ttraces.setlegend_y(const avalue: real); +begin + legend_pos:= mc(flegend_pos.re,avalue); +end; + +procedure ttraces.setlegend_dist(const avalue: integer); +begin + if flegend_dist <> avalue then begin + flegend_dist:= avalue; + layoutchanged; + end; +end; + +procedure ttraces.setlegend_placement(const avalue: tracelegendplacementty); +begin + if flegend_placement <> avalue then begin + flegend_placement:= avalue; + layoutchanged; + end; +end; + +procedure ttraces.setlegend_fitdist(const avalue: integer); +begin + if flegend_fitdist <> avalue then begin + flegend_fitdist:= avalue; + layoutchanged; + end; +end; + +procedure ttraces.layoutchanged; +begin + exclude(ftracestate,trss_graphicvalid); + change; + tcustomchart(fowner).layoutchanged; +end; + +{ tchartdialvert } + +constructor tchartdialvert.create(const aintf: idialcontroller); +begin + inherited create(aintf); + direction:= gd_up; +end; + +procedure tchartdialvert.setdirection(const avalue: graphicdirectionty); +begin + if avalue in [gd_up,gd_down] then begin + inherited; + end; +end; + +{ tchartdialhorz } + +constructor tchartdialhorz.create(const aintf: idialcontroller); +begin + inherited; + direction:= gd_right; +end; + +procedure tchartdialhorz.setdirection(const avalue: graphicdirectionty); +begin + if avalue in [gd_right,gd_left] then begin + inherited; + end; +end; + +{ tchartframe } + +constructor tchartframe.create(const aintf: iscrollframe; const owner: twidget); +begin + inherited; + fi.innerframe.left:= 0; + fi.innerframe.top:= 0; + fi.innerframe.right:= 1; + fi.innerframe.bottom:= 1; +end; + +function tchartframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + +{ tcuchart } + +constructor tcuchart.create(aowner: tcomponent); +begin + fcolorchart:= cl_default; + foptionschart:= defaultoptionschart; + fxrange:= 1; + fyrange:= 1; + fydials:= tchartdialsvert.create(ichartdialcontroller(self)); + fxdials:= tchartdialshorz.create(ichartdialcontroller(self)); +{ + with fdialvert do begin + direction:= gd_up; + ticks.count:= 1; + with ticks[0] do begin + intervalcount:= 10; + color:= cl_dkgray; + end; + end; + with fdialhorz do begin + direction:= gd_right; + ticks.count:= 1; + with ticks[0] do begin + intervalcount:= 10; + color:= cl_dkgray; + end; + end; +} + inherited; + optionswidget:= defaultchartoptionswidget; +end; + +destructor tcuchart.destroy; +begin + fydials.free; + fxdials.free; + inherited; + ffacechart.free; + fframechart.free; +end; + +procedure tcuchart.invalidatelayout; +begin + if componentstate * [csloading,csdestroying] = [] then begin + exclude(fstate,chs_layoutvalid); + fxdials.changed; + fydials.changed; + chartchange; + end; +end; + +procedure tcuchart.clientrectchanged; +begin + invalidatelayout; + inherited; +end; +{ +procedure tcuchart.dobeforepaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; + if canevent(tmethod(fonbeforepaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonbeforepaint(self,canvas); + canvas.remove(pt1); + end; +end; +} + +procedure tcuchart.doclipcontent1(const acanvas: tcanvas); +begin + //dummy +end; + +procedure tcuchart.dopaintcontent(const acanvas: tcanvas); +begin + //dummy +end; + +procedure tcuchart.dopaintcontent1(const acanvas: tcanvas); +begin + //dummy +end; + +procedure tcuchart.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if not (chs_nocolorchart in fstate) and not canvas.clipregionisempty then begin + if fcolorchart <> cl_default then begin + canvas.fillrect(getdialrect,fcolorchart); + end; + if ffacechart <> nil then begin + ffacechart.paint(canvas,getdialrect); + end; + end; +// if canevent(tmethod(fonpaintbackground)) then begin +// fonpaintbackground(self,canvas); +// end; +end; +{ +procedure tcuchart.doonpaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaint)) then begin + fonpaint(self,canvas); + end; +end; + +procedure tcuchart.doafterpaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; + if canevent(tmethod(fonafterpaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonafterpaint(self,canvas); + canvas.remove(pt1); + end; +end; +} +procedure tcuchart.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + acanvas.save; + doclipcontent1(acanvas); + fxdials.paint(acanvas); + fydials.paint(acanvas); + dopaintcontent(acanvas); + fxdials.afterpaint(acanvas); + fydials.afterpaint(acanvas); + acanvas.restore; + dopaintcontent1(acanvas); + if fframechart <> nil then begin + fframechart.paintoverlay(acanvas,fchartframerect); + end; +end; + +procedure tcuchart.paint(const acanvas: tcanvas); +begin + checklayout; + inherited; +end; + +procedure tcuchart.setcolorchart(const avalue: colorty); +begin + if fcolorchart <> avalue then begin + fcolorchart:= avalue; + exclude(fstate,chs_chartvalid); //for tchartrecorder + changed; + end; +end; + +procedure tcuchart.setxdials(const avalue: tchartdialshorz); +begin + fxdials.assign(avalue); +end; + +procedure tcuchart.setydials(const avalue: tchartdialsvert); +begin + fydials.assign(avalue); +end; + +procedure tcuchart.directionchanged(const dir: graphicdirectionty; + const dirbefore: graphicdirectionty); +begin + //dummy +end; + +function tcuchart.getdialrect: rectty; +begin + result:= innerclientrect; + deflaterect1(result,ffitframe); + if fframechart <> nil then begin +{$warnings off} + deflaterect1(result,fframechart.innerframe); +{$warnings on} + end; +end; + +function tcuchart.getlimitrect: rectty; +begin + result:= innerclientrect; +end; + +procedure tcuchart.internalcreateframe; +begin + tchartframe.create(iscrollframe(self),self); +end; + +procedure tcuchart.changed; +begin + invalidate; +end; + +procedure tcuchart.defineproperties(filer: tfiler); +begin + inherited; +end; + +function tcuchart.getxstart: real; +begin + result:= fxstart; +end; + +procedure tcuchart.setxstart(const avalue: real); +begin + fxstart:= avalue; + fxdials.start:= avalue; +end; + +function tcuchart.getystart: real; +begin + result:= fystart; +end; + +procedure tcuchart.setystart(const avalue: real); +begin + fystart:= avalue; + fydials.start:= avalue; +end; + +function tcuchart.getxrange: real; +begin + result:= fxrange; +end; + +procedure tcuchart.setxrange(const avalue: real); +begin + fxrange:= avalue; + fxdials.range:= avalue; +end; + +function tcuchart.getyrange: real; +begin + result:= fyrange; +end; + +procedure tcuchart.setyrange(const avalue: real); +begin + fyrange:= avalue; + fydials.range:= avalue; +end; + +procedure tcuchart.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tcuchart.dostatread(const reader: tstatreader); +begin + fxdials.dostatread(reader); + fydials.dostatread(reader); +end; + +procedure tcuchart.dostatwrite(const writer: tstatwriter); +begin + fxdials.dostatwrite(writer); + fydials.dostatwrite(writer); +end; + +procedure tcuchart.statreading; +begin + //dummy +end; + +procedure tcuchart.statread; +begin + //dummy +end; + +function tcuchart.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcuchart.initscrollstate; +var + int1: integer; +begin + fshiftsum:= 0; + fscrollsum:= 0; + fsampleco:= 0; + fstate:= fstate - [chs_hasdialscroll,chs_hasdialshift]; + for int1:= 0 to fxdials.count -1 do begin + with fxdials[int1] do begin + if do_scrollwithdata in options then begin + include(self.fstate,chs_hasdialscroll); + end; + if do_shiftwithdata in options then begin + self.fstate:= self.fstate + [chs_hasdialscroll,chs_hasdialshift]; + end; + shift:= 0; + end; + end; +end; + +procedure tcuchart.layoutchanged; +begin + exclude(fstate,chs_layoutvalid); + invalidate; +end; + +procedure tcuchart.chartchange; +begin + exclude(fstate,chs_chartvalid); + invalidate; +end; + +function tcuchart.fit(const asides: rectsidesty = allrectsides): boolean; +var + ext1: rectextty; + int1: integer; + fra1: framety; + rect1: rectty; + si1: sizety; + shift1,shift2: integer; + + procedure handle(const adial: tcustomdialcontroller1; + const active1,active2,isx: boolean); + var + int1: integer; + begin + with adial do begin + if visible then begin + if do_opposite in options then begin + if active2 then begin + indent1:= -shift2-fitdist; + end; + end + else begin + if active2 then begin + indent1:= -shift1-fitdist; + end; + end; + checklayout; + expandrectext1(ext1,tdialticks1(ticks).fdim); + expandrectext1(ext1,tdialmarkers1(markers).fdim); + with tdialticks1(ticks).fdim do begin + if isx then begin + int1:= fitdist + bottom - top; + end + else begin + int1:= fitdist + right - left; + end; + end; + if do_opposite in options then begin + shift2:= shift2 + int1; + end + else begin + shift1:= shift1 + int1; + end; + end; + end; + end; + +begin + result:= false; + si1:= clientsize; + rect1:= getdialrect; + ext1.topleft:= rect1.pos; + ext1.bottomright:= addpoint(rect1.pos,pointty(rect1.size)); + shift1:= 0; + shift2:= 0; + for int1:= 0 to fxdials.count-1 do begin + {$warnings off} + handle(tcustomdialcontroller1(fxdials[int1]), + rs_bottom in asides,rs_top in asides,true); + {$warnings on} + end; + shift1:= 0; + shift2:= 0; + for int1:= 0 to fydials.count-1 do begin + {$warnings off} + handle(tcustomdialcontroller1(fydials[int1]), + rs_right in asides,rs_left in asides,false); + {$warnings on} + end; + extendfit(asides,ext1); + inflaterectext1(ext1,tcustomframe1(fframe).fi.innerframe); + if fframechart <> nil then begin + inflaterectext1(ext1,fframechart.framei); + end; + + fra1:= ffitframe; + + if rs_left in asides then begin + fra1.left:= fra1.left - ext1.left; + end; + if rs_top in asides then begin + fra1.top:= fra1.top - ext1.top; + end; + if rs_right in asides then begin + fra1.right:= fra1.right + (ext1.right - si1.cx); + end; + if rs_bottom in asides then begin + fra1.bottom:= fra1.bottom + (ext1.bottom - si1.cy); + end; + + if not frameisequal(fra1,ffitframe) then begin + result:= true; + fitframe:= fra1; + end; +end; + +procedure tcuchart.setoptionschart(const avalue: optionschartty); +begin + if foptionschart <> avalue then begin + foptionschart:= avalue; + layoutchanged; + end; +end; + +function tcuchart.checklayout: boolean; +begin + result:= false; + if not (chs_layoutvalid in fstate) then begin + if foptionschart * rectsidesmask <> [] then begin + result:= fit(rectsidesty(foptionschart*rectsidesmask)) or result; + end; + fchartframerect:= getdialrect; + if framechart <> nil then begin + inflaterect1(fchartframerect,fframechart.innerframe); + end; + end; + include(fstate,chs_layoutvalid); +end; + +function tcuchart.actualcolorchart(): colorty; +begin + result:= fcolorchart; + if result = cl_default then begin + if fframe <> nil then begin + result:= fframe.colorclient; + end; + end; + if result = cl_default then begin + result:= actualcolor; + end; +end; + +procedure tcuchart.setfitframe(const avalue: framety); +begin + ffitframe:= avalue; + invalidatelayout; +end; + +procedure tcuchart.setfitframe_left(const avalue: integer); +begin + if ffitframe.left <> avalue then begin + ffitframe.left:= avalue; + invalidatelayout; + end; +end; + +procedure tcuchart.setfitframe_top(const avalue: integer); +begin + if ffitframe.top <> avalue then begin + ffitframe.top:= avalue; + invalidatelayout; + end; +end; + +procedure tcuchart.setfitframe_right(const avalue: integer); +begin + if ffitframe.right <> avalue then begin + ffitframe.right:= avalue; + invalidatelayout; + end; +end; + +procedure tcuchart.setfitframe_bottom(const avalue: integer); +begin + if ffitframe.bottom <> avalue then begin + ffitframe.bottom:= avalue; + invalidatelayout; + end; +end; + +procedure tcuchart.fontchanged; +begin + invalidatelayout; + inherited; +end; + +function tcuchart.getfacechart: tface; +begin + getoptionalobject(ffacechart,{$ifdef FPC}@{$endif}createfacechart); + result:= ffacechart; +end; + +procedure tcuchart.setfacechart(const avalue: tface); +begin + setoptionalobject(avalue,ffacechart,{$ifdef FPC}@{$endif}createfacechart); + invalidate; +end; + +procedure tcuchart.createfacechart; +begin + if ffacechart = nil then begin + ffacechart:= tface.create(iface(self)); + end; +end; + +procedure tcuchart.createframechart; +begin + if fframechart = nil then begin + fframechart:= tframe(tframe.newinstance); + {$warnings off} + include(tcustomframe1(fframechart).fstate,fs_nosetinstance); + {$warnings on} + fframechart.create(iframe(self)); + end; +end; + +function tcuchart.getframechart: tframe; +begin + getoptionalobject(fframechart,{$ifdef FPC}@{$endif}createframechart); + result:= fframechart; +end; + +procedure tcuchart.setframechart(const avalue: tframe); +begin + setoptionalobject(avalue,fframechart,{$ifdef FPC}@{$endif}createframechart); + invalidate; +end; + +procedure tcuchart.extendfit(const asides: rectsidesty; var aext: rectextty); +begin + //dummy +end; + +function tcuchart.getzoomrefframe: framety; +begin + result:= inherited getzoomrefframe; + addframe1(result,ffitframe); + if fframechart <> nil then begin + addframe1(result,fframechart.innerframe); + end; +end; + +function tcuchart.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tcustomchart } + +constructor tcustomchart.create(aowner: tcomponent); +begin + if ftraces = nil then begin + ftraces:= ttraces.create(self); + end; + inherited; +end; + +destructor tcustomchart.destroy; +begin + ftraces.free; + inherited; +end; + +procedure tcustomchart.clear; +var + int1: integer; +begin + initscrollstate; + include(fstate,chs_chartvalid); + for int1:= 0 to ftraces.count - 1 do begin + ftraces[int1].clear; + end; +end; + +procedure tcustomchart.addsample(const asamples: array of real); +var + int1: integer; + rea1,rea2: real; +begin + if not (chs_chartvalid in fstate) then begin + initscrollstate; + include(fstate,chs_chartvalid); + end; + int1:= high(asamples); + if int1 >= ftraces.count then begin + int1:= ftraces.count-1; + end; + for int1:= 0 to int1 do begin + ttrace(ftraces.fitems[int1]).addxseriesdata(asamples[int1]); + end; + if chs_hasdialscroll in fstate then begin + inc(fsampleco); + if cto_adddataright in ftraces.options then begin + int1:= 1; + end + else begin + int1:= 0; + if fsampleco >= ftraces.maxcount then begin + int1:= fsampleco-ftraces.maxcount; + fsampleco:= fsampleco - int1; + end; + end; + if (int1 <> 0) and (ftraces.maxcount > 0) then begin + fscrollsum:= fscrollsum + int1; + fshiftsum:= fshiftsum + int1; + rea1:= (fshiftsum)/ftraces.maxcount; + if fscrollsum > ftraces.maxcount then begin + fscrollsum:= fscrollsum - ftraces.maxcount; + end; + rea2:= (fscrollsum)/ftraces.maxcount; + for int1:= 0 to fxdials.count - 1 do begin + with fxdials[int1] do begin + if do_shiftwithdata in options then begin + shift:= rea1*range; + end + else begin + shift:= rea2*range; + end; + end; + end; + end; + end; +end; + +procedure tcustomchart.settraces(const avalue: ttraces); +begin + ftraces.assign(avalue); +end; + +procedure tcustomchart.clientrectchanged; +begin + ftraces.clientrectchanged; + inherited; +end; + +procedure tcustomchart.doclipcontent1(const acanvas: tcanvas); +begin + inherited; + ftraces.clipoverlay(acanvas); +end; + +procedure tcustomchart.dopaintcontent(const acanvas: tcanvas); +var + rect1: rectty; +begin + inherited; + acanvas.save; + rect1:= getdialrect; + inc(rect1.cx); + inc(rect1.cy); + acanvas.intersectcliprect(rect1); + acanvas.move(rect1.pos); + ftraces.paint(acanvas); + acanvas.restore; +// acanvas.remove(innerclientpos); +end; + +procedure tcustomchart.dopaintcontent1(const acanvas: tcanvas); +begin + inherited; + ftraces.paintoverlay(acanvas); +end; + +procedure tcustomchart.setxstart(const avalue: real); +begin + inherited; + ftraces.xstart:= avalue; + fxdials.start:= avalue; +end; + +procedure tcustomchart.setystart(const avalue: real); +begin + inherited; + ftraces.ystart:= avalue; + fydials.start:= avalue; +end; + +procedure tcustomchart.setxrange(const avalue: real); +begin + inherited; + ftraces.xrange:= avalue; + fxdials.range:= avalue; +end; + +procedure tcustomchart.setyrange(const avalue: real); +begin + inherited; + ftraces.yrange:= avalue; + fydials.range:= avalue; +end; + +procedure tcustomchart.dostatread(const reader: tstatreader); +begin + inherited; + ftraces.dostatread(reader); +end; + +procedure tcustomchart.dostatwrite(const writer: tstatwriter); +begin + inherited; + ftraces.dostatwrite(writer); +end; + +function calctracerange(var min: real; const max: real; const log: boolean; + const startmargin: real = 0; const endmargin: real = 0): real; +var + rea1,rea2,rea3: real; + logmin,logmax: real; +begin + rea2:= 1-startmargin-endmargin; + rea1:= max-min; + if log then begin + if min <= 0 then begin + min:= max/100; + end; + if (min > 0) and (max > 0) and (rea1 > 0) and (rea2 > 0.01) then begin + logmin:= ln(min); + logmax:= ln(max); + rea1:= logmax-logmin; + rea2:= 1/rea2; + min:= exp(logmin - startmargin*rea2*rea1); + rea3:= exp(logmax + endmargin*rea2*rea1); + result:= rea3-min; + end + else begin//invalid + min:= 0.1; + result:= 0.9; + end; + end + else begin + if (rea1 = 0) or (rea2 < 0.01) then begin //invalid + result:= min; + if result = 0 then begin + result:= 1; + end; + min:= min - result / 2; + end + else begin + rea2:= 1/rea2; + min:= min - startmargin*rea2*rea1; + rea3:= max + endmargin*rea2*rea1; + result:= rea3 - min; + end; + end; +end; + +procedure tcustomchart.autoscalex(const astartmargin: real = 0; + const aendmargin: real = 0); +var + rea1,rea2: real; + min,max,ra: real; + int1: integer; +begin + min:= bigreal; + max:= -bigreal; + for int1:= 0 to traces.count - 1 do begin + with traces[int1] do begin + minmaxx(rea1,rea2); + if rea1 < min then begin + min:= rea1; + end; + if rea2 > max then begin + max:= rea2; + end; + end; + end; + ra:= calctracerange(min,max,cto_logx in traces.options, + astartmargin,aendmargin); + xstart:= min; + xrange:= ra; +end; + +procedure tcustomchart.autoscaley(const astartmargin: real = 0; + const aendmargin: real = 0); +var + rea1,rea2: real; + min,max,ra: real; + int1: integer; +begin + min:= bigreal; + max:= -bigreal; + for int1:= 0 to traces.count - 1 do begin + with traces[int1] do begin + minmaxy(rea1,rea2); + if rea1 < min then begin + min:= rea1; + end; + if rea2 > max then begin + max:= rea2; + end; + end; + end; + ra:= calctracerange(min,max,cto_logy in traces.options, + astartmargin,aendmargin); + ystart:= min; + yrange:= ra; +end; + +procedure tcustomchart.layoutchanged; +begin + inherited; + ftraces.change; +end; + +procedure tcustomchart.extendfit(const asides: rectsidesty; var aext: rectextty); +var + rect1: rectty; +// int1: integer; +begin + inherited; + with ftraces do begin + if legend_placement in [tlp_above,tlp_below] then begin +// checkgraphic; + rect1:= self.getdialrect; + calclegendrect; + if legend_placement = tlp_above then begin + legend_dist:= rect1.y - aext.top + legend_fitdist; + aext.top:= aext.top - flegendsize.cy - legend_fitdist; + end + else begin + legend_dist:= aext.bottom - rect1.y - rect1.cy + legend_fitdist; + aext.bottom:= aext.bottom + flegendsize.cy + legend_fitdist; + end; + end; + { + if legend_placement in [tlp_above,tlp_below] then begin + checkgraphic; + rect1:= self.getdialrect; + int1:= flegendsize.cy + legend_fitdist; + if legend_placement = tlp_above then begin + legend_dist:= rect1.y - aext.top + legend_fitdist; + aext.top:= aext.top - int1; + end + else begin + legend_dist:= aext.bottom - rect1.y - rect1.cy + legend_fitdist; + aext.bottom:= aext.bottom + int1; + end; + end; + } + end; +end; + +{ trecordertraces } + +constructor trecordertraces.create; +begin + inherited create(trecordertrace); +end; + +class function trecordertraces.getitemclasstype: persistentclassty; +begin + result:= trecordertrace; +end; + +{ trecordertrace } + +constructor trecordertrace.create; +begin + frange:= 1; + fcolor:= cl_glyph; + inherited; +end; + +procedure trecordertrace.setrange(const avalue: real); +begin + checknullrange(avalue); + frange:= avalue; +end; + +{ tchartrecorder } + +constructor tchartrecorder.create(aowner: tcomponent); +begin + fsamplecount:= 100; + fchart:= tmaskedbitmap.create(bmk_rgb{false}); + ftraces:= trecordertraces.create; + inherited; + include(fstate,chs_nocolorchart); +end; + +destructor tchartrecorder.destroy; +begin + fchart.free; + ftraces.free; + inherited; +end; +{ +procedure tchartrecorder.clientrectchanged; +begin + chartchange; + inherited; +end; +} +procedure tchartrecorder.checkinit; +var + int1: integer; + bo1: boolean; +begin + if not (csloading in componentstate) and + not (chs_chartvalid in fstate) then begin + fstate:= fstate - chartrecorderstatesmask; +// fstarted:= false; + bo1:= false; + initscrollstate; + for int1:= 0 to fxdials.count -1 do begin + with fxdials[int1] do begin + if not (do_front in options) then begin + bo1:= true; + end; + end; + end; + if not bo1 then begin + for int1:= 0 to fydials.count -1 do begin + if not (do_front in fydials[int1].options) then begin + bo1:= true; + break; + end; + end; + end; + with fchart do begin + masked:= bo1; + fchartclientrect:= innerclientrect; + fchartwindowrect.size:= fchartclientrect.size; + fchartrect.cx:= fchartclientrect.cx + 10; //room for linewidth + fchartrect.cy:= fchartclientrect.cy; + size:= fchartrect.size; + fstep:= {$ifdef FPC}real({$endif}fchartwindowrect.cx{$ifdef FPC}){$endif} / + fsamplecount; + fstepsum:= 0; + fxref:= fchartwindowrect.x; + if cro_adddataright in foptions then begin + include(fstate,chs_full); + end; + init(actualcolorchart); + canvas.capstyle:= cs_round; + if masked then begin + mask.init(cl_0); + mask.canvas.capstyle:= cs_round; + end; + end; + include(fstate,chs_chartvalid); + end; +end; + +procedure tchartrecorder.dopaintcontent(const acanvas: tcanvas); +begin + checkinit; + fchart.paint(acanvas,fchartclientrect.pos); +// canvas.copyarea(fchart.canvas,fchartwindowrect,fchartclientrect.pos); +end; + +procedure tchartrecorder.setsamplecount(const avalue: integer); +begin + if fsamplecount <> avalue then begin + fsamplecount:= avalue; + if fsamplecount <= 0 then begin + fsamplecount:= 1; + end; + chartchange; + end; +end; + +procedure tchartrecorder.addsample(const asamples: array of real); +var + acanvas,mcanvas: tcanvas; + amasked: boolean; + + procedure shift(const adist: integer); + begin + fshiftsum:= fshiftsum+adist; + fscrollsum:= fscrollsum+adist; + acanvas.copyarea(acanvas,fchartrect,makepoint(-adist,0)); + acanvas.fillrect(makerect(fchartrect.cx-adist,0,adist,fchartrect.cy),fcolorchart); + if amasked then begin + mcanvas.copyarea(mcanvas,fchartrect,makepoint(-adist,0)); + mcanvas.fillrect(makerect(fchartrect.cx-adist,0,adist,fchartrect.cy),cl_0); + end; + end; //shift + +var + int1,int2: integer; + startx,endx,y: integer; + rea1,rea2: real; +begin + mcanvas:= nil; + if (chs_hasdialshift in fstate) and (fshiftsum < 0) then begin + exclude(fstate,chs_chartvalid); + end; + checkinit; + fstepsum:= fstepsum + fstep; + int1:= round(fstepsum); + fstepsum:= fstepsum - int1; + with fchart do begin + acanvas:= canvas; + amasked:= masked; + if amasked then begin + mcanvas:= mask.canvas; + end; + end; + if chs_full in fstate then begin + startx:= fchartwindowrect.cx-int1; + endx:= fchartwindowrect.cx; + shift(int1); + end + else begin + startx:= fxref; + fxref:= fxref+int1; + endx:= fxref; + int1:= endx-fchartwindowrect.cx; + if int1 >= 0 then begin + if int1 <> 0 then begin //should not happen + shift(int1); + startx:= startx-int1; + endx:= endx-int1; + end; + include(fstate,chs_full); + end; + end; + if (chs_hasdialscroll in fstate) and (fchartwindowrect.cx > 0) then begin + rea1:= fshiftsum/fchartwindowrect.cx; + if fscrollsum > fchartwindowrect.cx then begin + fscrollsum:= fscrollsum - fchartwindowrect.cx; + end; + rea2:= fscrollsum/fchartwindowrect.cx; + for int1:= 0 to fxdials.count -1 do begin + with fxdials[int1] do begin + if do_shiftwithdata in options then begin + shift:= rea1*range; + end + else begin + shift:= rea2*range; + end; + end; + end; + end; + int1:= high(asamples); + if int1 > high(ftraces.fitems) then begin + int1:= high(ftraces.fitems); + end; + for int2:= 0 to int1 do begin + with trecordertrace(ftraces.fitems[int2]) do begin + y:= fchartrect.cy - round(fchartrect.cy * ((asamples[int2] - fstart)/frange)); + if chs_started in fstate then begin + acanvas.linewidth:= fwidth; + acanvas.drawline(makepoint(startx,fybefore),makepoint(endx,y),fcolor); + if amasked then begin + mcanvas.linewidth:= fwidth; + mcanvas.drawline(makepoint(startx,fybefore),makepoint(endx,y),cl_1); + end; + end; + fybefore:= y; + end; + end; + invalidaterect(fchartclientrect); + include(fstate,chs_started); +end; + +procedure tchartrecorder.settraces(const avalue: trecordertraces); +begin + ftraces.assign(avalue); +end; + +procedure tchartrecorder.clear; +begin + exclude(fstate,chs_chartvalid); + invalidate; +end; +{ +procedure tchartrecorder.changed; +begin + fchartvalid:= false; + inherited; +end; +} +{ tchartdialshorz } + +function tchartdialshorz.getitemclass: dialcontrollerclassty; +begin + result:= tchartdialhorz; +end; + +procedure tchartdialshorz.setitems(const aindex: integer; + const avalue: tchartdialhorz); +begin + getitems(aindex).assign(avalue); +end; + +function tchartdialshorz.getitems(const aindex: integer): tchartdialhorz; +begin + result:= tchartdialhorz(inherited getitems(aindex)); +end; + +procedure tchartdialshorz.createitem(const index: integer; + var item: tpersistent); +begin + inherited; + with tchartdialhorz(item) do begin + start:= ichartdialcontroller(fintf).getxstart; + range:= ichartdialcontroller(fintf).getxrange; + end; +end; + +class function tchartdialshorz.getitemclasstype: persistentclassty; +begin + result:= tchartdialhorz; +end; + +{ tchartdialsvert } + +function tchartdialsvert.getitemclass: dialcontrollerclassty; +begin + result:= tchartdialvert; +end; + +procedure tchartdialsvert.setitems(const aindex: integer; + const avalue: tchartdialvert); +begin + getitems(aindex).assign(avalue); +end; + +function tchartdialsvert.getitems(const aindex: integer): tchartdialvert; +begin + result:= tchartdialvert(inherited getitems(aindex)); +end; + +procedure tchartdialsvert.createitem(const index: integer; + var item: tpersistent); +begin + inherited; + with tchartdialvert(item) do begin + start:= ichartdialcontroller(fintf).getystart; + range:= ichartdialcontroller(fintf).getyrange; + end; +end; + +class function tchartdialsvert.getitemclasstype: persistentclassty; +begin + result:= tchartdialvert; +end; + +{ tchartdials } + +procedure tchartdials.changed; +var + int1: integer; +begin + for int1:= high(fitems) downto 0 do begin + tcustomdialcontroller1(fitems[int1]).changed; + end; +end; + +procedure tchartdials.paint(const acanvas: tcanvas); +var + int1: integer; +begin + for int1:= high(fitems) downto 0 do begin + tcustomdialcontroller(fitems[int1]).paint(acanvas); + end; +end; + +procedure tchartdials.afterpaint(const acanvas: tcanvas); +var + int1: integer; +begin + for int1:= high(fitems) downto 0 do begin + tcustomdialcontroller(fitems[int1]).afterpaint(acanvas); + end; +end; + +constructor tchartdials.create(const aintf: ichartdialcontroller); +begin + inherited create(aintf); +end; + +procedure tchartdials.setitems(const aindex: integer; + const avalue: tcustomdialcontroller); +begin + inherited getitems(aindex).assign(avalue); +end; + +function tchartdials.getitems(const aindex: integer): tcustomdialcontroller; +begin + result:= tcustomdialcontroller(inherited getitems(aindex)); +end; + +{ txytrace } + +constructor txytrace.create(aowner: tobject); +begin + inherited; +end; + +procedure txytrace.setoptions(const avalue: charttraceoptionsty); +begin + if txytraces(ftraces).fxordered then begin + inherited setoptions(avalue + [cto_xordered]); + end + else begin + inherited; + end; +end; + +procedure txytrace.setkind(const avalue: tracekindty); +begin + inherited setkind(trk_xy); +end; + +{ txytraces } + +constructor txytraces.create(const aowner: tcustomchart; const axordered: boolean); +begin + fxordered:= axordered; + inherited create(aowner); + kind:= trk_xy; + options:= defaultxytraceoptions; +end; + +class function txytraces.getitemclasstype: persistentclassty; +begin + result:= txytrace; +end; + +procedure txytraces.setoptions(const avalue: charttraceoptionsty); +begin + if fxordered then begin + inherited setoptions(avalue + [cto_xordered]); + end + else begin + inherited; + end; +end; + +procedure txytraces.setkind(const avalue: tracekindty); +begin + inherited setkind(trk_xy); +end; + +{ tbarframe } + +constructor tbarframe.create(const aintf: iframe); +begin + inherited; + include(fstate,fs_nowidget); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msechartedit.pas b/mseide-msegui/lib/common/widgets/msechartedit.pas new file mode 100644 index 0000000..ef40a34 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msechartedit.pas @@ -0,0 +1,2019 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msechartedit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msechart,mseguiglob,mseevent,mseeditglob,msegraphutils, + msetypes, + mseobjectpicker,msepointer,msegraphics,mseclasses,msestat,msestatfile, + msestrings,msedial,msegui,msemenus,mseglob; + +const + defaultsnapdist = 4; + markersnapdist = 2; + defaultchartoptionsedit1 = [oe1_checkvalueafterstatread,oe1_savevalue, + oe1_savestate]; + defaultcharteditoptionswidget = defaultchartoptionswidget + [ow_mousefocus]; + +type + setcomplexareventty = procedure(const sender: tobject; + var avalue: complexarty; var accept: boolean) of object; + setrealareventty = procedure(const sender: tobject; + var avalue: realarty; var accept: boolean) of object; + charteditoptionty = (ceo_thumbtrack,ceo_markerthumbtrack, + ceo_noinsert,ceo_nodelete, + ceo_tracehint,ceo_markerhint); + charteditoptionsty = set of charteditoptionty; + + charteditmovestatety = (cems_markermoving,cems_canbottomlimit,cems_cantoplimit, + cems_xbottomlimit,cems_ybottomlimit, + cems_xtoplimit,cems_ytoplimit); + charteditmovestatesty = set of charteditmovestatety; + + tcustomchartedit = class; + tracehinteventty = procedure(const sender: tcustomchartedit; + const atrace,aindex: integer; var ahint: hintinfoty) of object; + markerhinteventty = procedure(const sender: tcustomchartedit; + const isy: boolean; const adial,aindex: integer; + var ahint: hintinfoty) of object; + markerseteventty = procedure(const sender: tcustomchartedit; + const isy: boolean; const adial,aindex: integer; + var avalue: realty) of object; + + tcustomchartedit = class(tcustomchart,iobjectpicker) + private + factivetrace: integer; + foptionsedit: optionseditty; + foptionsedit1: optionsedit1ty; + fobjectpicker: tobjectpicker; + fsnapdist: integer; + foffsetmin: pointty; + foffsetmax: pointty; + fonchange: notifyeventty; + fondataentered: notifyeventty; + foptions: charteditoptionsty; + fpickref: pointty; + fmovestate: charteditmovestatesty; + fmarkermovestartpos: int32; + fontracehint: tracehinteventty; + fonmarkerhint: markerhinteventty; + fnodehintindex: integer; + fnodehinttrace: integer; + fonsetmarker: markerseteventty; + fonmarkerentered: notifyeventty; + procedure setactivetrace(avalue: integer); + function limitmoveoffset(const aoffset: pointty): pointty; + function getreadonly: boolean; + procedure setreadonly(const avalue: boolean); + procedure setoptions(const avalue: charteditoptionsty); + procedure dopickmove(const sender: tobjectpicker); + procedure setoptionsedit(const avalue: optionseditty); + protected + procedure resetnodehint; + function hasactivetrace: boolean; + function nodepos(const atrace: integer; const aindex: integer): pointty; + function nearestnode(const apos: pointty; const all: boolean; + out atrace,aindex: integer): boolean; + function nodesinrect(const arect: rectty): integerarty; + function encodenodes(const atrace: integer; + const aindex: array of integer): integerarty; + function decodenodes(const aitems: integerarty; + out atrace: integer; out aindex: integerarty): boolean; + + function chartcoordxy(const atrace: integer; + const avalue: complexty): pointty; + function tracecoordxy(const atrace: integer; + const apos: pointty): complexty; + function chartcoordxseries(const atrace: integer; + const avalue: xseriesdataty): pointty; + function tracecoordxseries(const atrace: integer; + const apos: pointty): xseriesdataty; + + function encodemarker(const isy: boolean; + const adial,aindex: integer): integerarty; + function decodemarker(const aitems: integerarty; out isy: boolean; + out adial: integer; out aindex: integer): boolean; + function xmarkertochart(const avalue: real; const adial: integer): integer; + function ymarkertochart(const avalue: real; const adial: integer): integer; + function xcharttomarker(const apos: integer; const adial: integer): real; + function ycharttomarker(const apos: integer; const adial: integer): real; + function getmarker(const apos: pointty; const nolimited: boolean; + out isy: boolean; out adial,aindex: integer): boolean; + + procedure tracehint(const atrace,aindex: integer); + procedure markerhint(const apos: pointty; const isy: boolean; + const adial,aindex: integer); + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + procedure dobeforepaint(const acanvas: tcanvas); override; + procedure doafterpaint(const acanvas: tcanvas); override; + procedure change; + procedure dochange; virtual; + procedure domarkerchange; virtual; + function chartdataxy: complexarty; + function chartdataxseries: realarty; + function activetraceitem: ttrace; + + procedure doreadvalue(const reader: tstatreader); virtual; abstract; + procedure dowritevalue(const writer: tstatwriter); virtual; abstract; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + procedure statread; override; + procedure loaded; override; + procedure docheckvalue(var accept: boolean); virtual; abstract; + procedure doclear; virtual; abstract; + procedure drawcrosshaircursor(const canvas: tcanvas; + const center: pointty); virtual; + + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; override; + function checkvalue: boolean; + property readonly: boolean read getreadonly write setreadonly; + property activetrace: integer read factivetrace + write setactivetrace default 0; + property optionsedit: optionseditty read foptionsedit write setoptionsedit + default defaultoptionsedit; + property optionsedit1: optionsedit1ty read foptionsedit1 write foptionsedit1 + default defaultchartoptionsedit1; + property snapdist: integer read fsnapdist write fsnapdist + default defaultsnapdist; + property options: charteditoptionsty read foptions + write setoptions default []; + property onchange: notifyeventty read fonchange write fonchange; + property onsetmarker: markerseteventty read fonsetmarker write fonsetmarker; + property onmarkerentered: notifyeventty read fonmarkerentered + write fonmarkerentered; + property ontracehint: tracehinteventty read fontracehint write fontracehint; + property onmarkerhint: markerhinteventty read fonmarkerhint + write fonmarkerhint; + published + property optionswidget default defaultcharteditoptionswidget; + end; + + tcustomxychartedit = class(tcustomchartedit) + private + fonsetvalue: setcomplexareventty; + function getvalue: complexarty; + procedure setvalue(const avalue: complexarty); + function getvalueitems(const index: integer): complexty; + procedure setvalueitems(const index: integer; const avalue: complexty); + function getreitems(const index: integer): real; + procedure setreitems(const index: integer; const avalue: real); + function getimitems(const index: integer): real; + procedure setimitems(const index: integer; const avalue: real); + protected + fvalue: complexarty; + procedure dochange; override; + procedure docheckvalue(var accept: boolean); override; + procedure doreadvalue(const reader: tstatreader); override; + procedure dowritevalue(const writer: tstatwriter); override; + class function xordered: boolean; virtual; + procedure doclear; override; + public + constructor create(aowner: tcomponent); override; + property value: complexarty read getvalue write setvalue; + property valueitems[const index: integer]: complexty read getvalueitems + write setvalueitems; + property reitems[const index: integer]: real read getreitems write setreitems; + property imitems[const index: integer]: real read getimitems write setimitems; + property ondataentered: notifyeventty read fondataentered + write fondataentered; + property onsetvalue: setcomplexareventty read fonsetvalue write fonsetvalue; + end; + + txychartedit = class(tcustomxychartedit) + published + property traces; + property colorchart; + property facechart; + property framechart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property statfile; + property statvarname; + property statpriority; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property ondataentered; + property onsetvalue; + property activetrace; + property optionsedit; + property optionsedit1; + property snapdist; + property tracehint_captionx; + property tracehint_captiony; + property options; + property optionschart; + property onchange; + property onsetmarker; + property onmarkerentered; + property ontracehint; + property onmarkerhint; + end; + + tcustomorderedxychartedit = class(tcustomxychartedit) + protected + class function xordered: boolean; override; + public + end; + + torderedxychartedit = class(tcustomorderedxychartedit) + published + property traces; + property colorchart; + property facechart; + property framechart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property statfile; + property statvarname; + property statpriority; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property ondataentered; + property onsetvalue; + property activetrace; + property optionsedit; + property optionsedit1; + property snapdist; + property tracehint_captionx; + property tracehint_captiony; + property options; + property optionschart; + property onchange; + property onsetmarker; + property onmarkerentered; + property ontracehint; + property onmarkerhint; + end; + + tcustomxserieschartedit = class(tcustomchartedit) + private + fonsetvalue: setrealareventty; + function getvalue: realarty; + procedure setvalue(const avalue: realarty); + function getvalueitems(const index: integer): real; + procedure setvalueitems(const index: integer; const avalue: real); + protected + fvalue: realarty; + procedure dochange; override; + procedure docheckvalue(var accept: boolean); override; + procedure doreadvalue(const reader: tstatreader); override; + procedure dowritevalue(const writer: tstatwriter); override; + procedure doclear; override; + public + property value: realarty read getvalue write setvalue; + property valueitems[const index: integer]: real read getvalueitems + write setvalueitems; + public + property ondataentered: notifyeventty read fondataentered + write fondataentered; + property onsetvalue: setrealareventty read fonsetvalue write fonsetvalue; + end; + + txserieschartedit = class(tcustomxserieschartedit) + published + property traces; + property colorchart; + property facechart; + property framechart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property statfile; + property statvarname; + property statpriority; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property ondataentered; + property onsetvalue; + property activetrace; + property optionsedit; + property optionsedit1; + property snapdist; + property tracehint_captionx; + property tracehint_captiony; + property options; + property optionschart; + property onchange; + property onsetmarker; + property onmarkerentered; + property ontracehint; + property onmarkerhint; + end; + +implementation +uses + msereal,msekeyboard,msedatalist,sysutils,msearrayutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + ttraces1 = class(ttraces); + ttrace1 = class(ttrace); + tdialmarkers1 = class(tdialmarkers); + tdialmarker1 = class(tdialmarker); + tcustomdialcontroller1 = class(tcustomdialcontroller); + tchartdialshorz1 = class(tchartdialshorz); + tchartdialhorz1 = class(tchartdialhorz); + tchartdialsvert1 = class(tchartdialsvert); + tchartdialvert1 = class(tchartdialvert); + +{ tcustomchartedit } + +constructor tcustomchartedit.create(aowner: tcomponent); +begin + fsnapdist:= defaultsnapdist; + foptionsedit:= defaultoptionsedit; + foptionsedit1:= defaultchartoptionsedit1; + resetnodehint; + inherited; + optionswidget:= defaultcharteditoptionswidget; + traces.count:= 1; + fobjectpicker:= tobjectpicker.create(iobjectpicker(self)); + fobjectpicker.options:= [opo_mousemoveobjectquery,opo_rectselect, + opo_multiselect]; +end; + +destructor tcustomchartedit.destroy; +begin + fobjectpicker.free; + inherited; +end; + +procedure tcustomchartedit.setactivetrace(avalue: integer); +begin + if avalue < 0 then begin + avalue:= -1; +// raise exception.create('Negative value'); + end; + factivetrace:= avalue; +// if traces.count <= avalue then begin +// traces.count:= avalue+1; +// end; +end; + +function tcustomchartedit.activetraceitem: ttrace; +begin + result:= nil; + if factivetrace >= 0 then begin + if factivetrace >= traces.count then begin + traces.count:= factivetrace+1; + end; + result:= ttrace(ttraces1(traces).fitems[factivetrace]); + end; +end; + +procedure tcustomchartedit.resetnodehint; +begin + fnodehintindex:= -1; + fnodehinttrace:= -1; +end; + +function tcustomchartedit.hasactivetrace: boolean; +begin + result:= (factivetrace >= 0) and (factivetrace < traces.count) and + traces[factivetrace].visible; +end; + +procedure tcustomchartedit.tracehint(const atrace,aindex: integer); +var + info: hintinfoty; + x,y: real; + mstr1,mstr2: msestring; +begin + fillchar(info,sizeof(info),0); + with info do begin + with posrect do begin + pos:= nodepos(atrace,aindex); + addpoint1(pos,mp(-20,-20)); + cx:= 40; + cy:= 40; + end; + placement:= cp_bottomleft; + end; + with ttrace1(traces[atrace]) do begin + y:= yvalue[aindex]; + if kind = trk_xy then begin + x:= xvalue[aindex]; + end + else begin + x:= aindex; + end; + mstr1:= hintx; + if mstr1 = '' then begin + mstr1:= 'x: '+formatfloatmse(x,''); + end + else begin + mstr1:= formatfloatmse(x,mstr1); + end; + mstr2:= hinty; + if mstr2 = '' then begin + mstr2:= 'y: '+formatfloatmse(y,''); + end + else begin + mstr2:= formatfloatmse(y,mstr2); + end; + info.caption:= mstr1+lineend+mstr2; + end; + if canevent(tmethod(fontracehint)) then begin + fontracehint(self,atrace,aindex,info); + end; + if info.caption <> '' then begin + application.showhint(self,info); + end; +end; + +procedure tcustomchartedit.markerhint(const apos: pointty; const isy: boolean; + const adial,aindex: integer); +var + info: hintinfoty; + mstr1: msestring; + marker1: tdialmarker; + +begin + fillchar(info,sizeof(info),0); + with info do begin + with posrect do begin + pos:= apos; + addpoint1(pos,mp(-20,-20)); + cx:= 40; + cy:= 40; + placement:= cp_bottomleft; + end; + if isy then begin + marker1:= ydials[adial].markers[aindex]; + end + else begin + marker1:= xdials[adial].markers[aindex]; + end; + end; + with marker1 do begin + mstr1:= hintcaption; + if mstr1 = '' then begin + mstr1:= markerhintcaption; + end; + info.caption:= formatfloatmse(value,mstr1) + end; + if canevent(tmethod(fonmarkerhint)) then begin + fonmarkerhint(self,isy,adial,aindex,info); + end; + if info.caption <> '' then begin + application.showhint(self,info); + end; +end; + +procedure tcustomchartedit.clientmouseevent(var info: mouseeventinfoty); +var + co1: complexty; + co2: xseriesdataty; + trace1: integer; + ar1: integerarty; + int1,int2: integer; + bo1: boolean; +begin + if not (es_processed in info.eventstate) then begin + fobjectpicker.mouseevent(info); + if (not (es_processed in info.eventstate) or + (info.eventkind = ek_mousepark)) and + not (csdesigning in componentstate) then begin + case info.eventkind of + ek_mousepark: begin + if ceo_tracehint in foptions then begin + if not decodenodes(fobjectpicker.currentobjects,trace1,ar1) then begin + resetnodehint; + end + else begin + if (ar1[0] <> fnodehintindex) or (trace1 <> fnodehinttrace) then begin + tracehint(trace1,ar1[0]); + exit; +// include(info.eventstate,es_processed); + end; + end; + end; + if (ceo_markerhint in foptions) and + getmarker(info.pos,true,bo1,int1,int2) then begin + markerhint(info.pos,bo1,int1,int2); + exit; +// include(info.eventstate,es_processed); + end; + end; + ek_clientmouseleave: begin + resetnodehint; + end; + ek_buttonpress: begin + if not (oe_readonly in foptionsedit) and + not (ceo_noinsert in foptions) and hasactivetrace and + (info.shiftstate * shiftstatesmask = [ss_left]) then begin + if pointinrect(info.pos,getdialrect) then begin + with activetraceitem do begin + if kind = trk_xseries then begin + co2:= tracecoordxseries(factivetrace,info.pos); + insertxseriesdata(co2); + end + else begin + co1:= tracecoordxy(factivetrace,info.pos); + addxydata(co1.re,co1.im); + end; + end; + include(info.eventstate,es_processed); + checkvalue; + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; + end; +end; + +function tcustomchartedit.xmarkertochart(const avalue: real; + const adial: integer): integer; +var + rect1: rectty; +begin + rect1:= getdialrect; +{$warnings off} + with tcustomdialcontroller1(xdials[adial]) do begin +{$warnings on} + if do_log in options then begin + result:= rect1.x + + chartround(rect1.cx*(chartln(avalue)-flnsstart)/flnrange); + end + else begin + result:= rect1.x + chartround(((avalue-fsstart)/frange)*rect1.cx); + end; + end; +end; + +function tcustomchartedit.ymarkertochart(const avalue: real; + const adial: integer): integer; +var + rect1: rectty; +begin + rect1:= getdialrect; +{$warnings off} + with tcustomdialcontroller1(ydials[adial]) do begin +{$warnings on} + if do_log in options then begin + result:= rect1.y + rect1.cy - + chartround(rect1.cy*(chartln(avalue)-flnsstart)/flnrange); + end + else begin + result:= rect1.y + rect1.cy - chartround(((avalue-fsstart)/frange)*rect1.cy); + end; + end; +end; + +function tcustomchartedit.xcharttomarker(const apos: integer; + const adial: integer): real; +var + rect1: rectty; +begin + rect1:= getdialrect; +{$warnings off} + with tcustomdialcontroller1(xdials[adial]) do begin +{$warnings on} + if do_log in options then begin + result:= exp(((apos - rect1.x) / rect1.cx)*flnrange+flnsstart); + end + else begin + result:= start + ((apos - rect1.x) / rect1.cx)*range; + end; + end; +end; + +function tcustomchartedit.ycharttomarker(const apos: integer; + const adial: integer): real; +var + rect1: rectty; +begin + rect1:= getdialrect; +{$warnings off} + with tcustomdialcontroller1(ydials[adial]) do begin +{$warnings on} + if do_log in options then begin + result:= exp( + ((rect1.y+rect1.cy-apos) / rect1.cy)*flnrange+flnsstart); + end + else begin + result:= start + ((rect1.y+rect1.cy-apos) / rect1.cy)*range; + end; + end; +end; + +function tcustomchartedit.tracecoordxy(const atrace: integer; + const apos: pointty): complexty; +var + rect1: rectty; +begin + if (atrace >= 0) and (atrace < ftraces.count) then begin + rect1:= getdialrect; + with ttrace1(traces[atrace]) do begin + if rect1.cx <= 0 then begin + result.re:= xstart; + end + else begin + if cto_logx in options then begin + result.re:= exp(((apos.x - rect1.x) / rect1.cx)*flnxrange+flnxstart); + end + else begin + result.re:= xstart + ((apos.x - rect1.x) / rect1.cx)*xrange; + end; + end; + if rect1.cy <= 0 then begin + result.im:= ystart; + end + else begin + if cto_logy in options then begin + result.im:= exp( + ((rect1.y+rect1.cy-apos.y) / rect1.cy)*flnyrange+flnystart); + end + else begin + result.im:= ystart + ((rect1.y+rect1.cy-apos.y) / rect1.cy)*yrange; + end; + end; + end; + end + else begin + result:= nullcomplex; + end; +end; + +function tcustomchartedit.tracecoordxseries(const atrace: integer; + const apos: pointty): xseriesdataty; +var + rect1: rectty; +begin + if (atrace >= 0) and (atrace < ftraces.count) then begin + rect1:= getdialrect; + with traces[atrace] do begin + result.index:= 0; + if (count > 0) and (rect1.cx > 0) then begin + if cto_seriescentered in options then begin + result.index:= ((apos.x-rect1.x)*count + rect1.cx div 2) div rect1.cx; + end + else begin + result.index:= ((apos.x-rect1.x)*(count-1)) div rect1.cx; + end; + end; + if rect1.cy <= 0 then begin + result.value:= ystart; + end + else begin + result.value:= ystart + ((rect1.y+rect1.cy-apos.y) / rect1.cy)*yrange; + end; + end; + end + else begin + result.value:= 0; + result.index:= -1; + end; +end; + +function tcustomchartedit.chartcoordxy(const atrace: integer; + const avalue: complexty): pointty; +var + rect1: rectty; + x,y: real; +begin + if (atrace >= 0) and (atrace < ftraces.count) then begin + rect1:= getdialrect; + with ttrace1(traces[atrace]) do begin + if cto_logx in options then begin + x:= rect1.x + (rect1.cx*(chartln(avalue.re)-flnxstart)/flnxrange); + end + else begin + x:= rect1.x + (((avalue.re-xstart)/xrange)*rect1.cx); + end; + if cto_logy in options then begin + y:= rect1.y + rect1.cy - + (rect1.cy*(chartln(avalue.im)-flnystart)/flnyrange); + end + else begin + y:= rect1.y + rect1.cy - (((avalue.im-ystart)/yrange)*rect1.cy); + end; + end; + if x > 100000 then begin + result.x:= 100000; + end + else begin + if x < -100000 then begin + result.x:= -100000; + end + else begin + result.x:= round(x); + end; + end; + if y > 100000 then begin + result.y:= 100000; + end + else begin + if y < -100000 then begin + result.y:= -100000; + end + else begin + result.y:= round(y); + end; + end; + end + else begin + result:= nullpoint; + end; +end; + +function tcustomchartedit.chartcoordxseries(const atrace: integer; + const avalue: xseriesdataty): pointty; +var + rect1: rectty; + y: real; +begin + if (atrace >= 0) and (atrace < ftraces.count) then begin + rect1:= getdialrect; + with ttrace1(traces[atrace]) do begin + if (cto_seriescentered in options) or (count = 1) then begin + result.x:= rect1.x + (avalue.index * rect1.cx+rect1.cx div 2) div count; + end + else begin + result.x:= rect1.x + (avalue.index * rect1.cx) div (count-1); + end; + if cto_logy in options then begin + y:= rect1.y + rect1.cy - + (rect1.cy*(chartln(avalue.value)-flnystart)/flnyrange); + end + else begin + y:= rect1.y + rect1.cy - (((avalue.value-ystart)/yrange)*rect1.cy); + end; + if y > 100000 then begin + result.y:= 100000; + end + else begin + if y < -100000 then begin + result.y:= -100000; + end + else begin + result.y:= round(y); + end; + end; + end; + end + else begin + result:= nullpoint; + end; +end; + +function tcustomchartedit.nodepos(const atrace: integer; + const aindex: integer): pointty; +begin + if (atrace >= 0) and (atrace < ftraces.count) then begin + with traces[atrace] do begin + if kind = trk_xseries then begin + result:= chartcoordxseries(atrace,makexseriesdata(yvalue[aindex],aindex)); + end + else begin + result:= chartcoordxy(atrace,xyvalue[aindex]); + end; + end; + end + else begin + result:= nullpoint; + end; +end; + +function tcustomchartedit.nearestnode(const apos: pointty; const all: boolean; + out atrace,aindex: integer): boolean; +var + dist: integer; + + function checkdist(const atrace: integer): integer; + //todo: optimze for ordered data + var + int1: integer; + + procedure handlepoint(const pt1: pointty); + var + int2,int3: integer; + begin + int2:= apos.x - pt1.x; + if abs(int2) > fsnapdist then begin + exit; + end; + int3:= apos.y - pt1.y; + if abs(int3) > fsnapdist then begin + exit; + end; + int2:= int2*int2; + int3:= int3*int3; + int3:= int2+int3; + if int3 < dist then begin + dist:= int3; + result:= int1; + end; + end; //handlepoint + + var + datahigh: integer; + px,py: preal; + pxy: pcomplexty; + begin + result:= -1; + with ftraces[atrace] do begin + if visible then begin + datahigh:= count-1; + if kind = trk_xseries then begin + py:= ydatapo; + if py <> nil then begin + for int1:= 0 to datahigh do begin + handlepoint(chartcoordxseries(atrace,makexseriesdata(py^,int1))); + inc(py); + end; + end; + end + else begin + pxy:= xydatapo; + if pxy <> nil then begin + for int1:= 0 to datahigh do begin + handlepoint(chartcoordxy(atrace,pxy^)); + inc(pxy); + end; + end + else begin + px:= xdatapo; + py:= ydatapo; + if (px <> nil) and (py <> nil) then begin + for int1:= 0 to datahigh do begin + handlepoint(chartcoordxy(atrace,makecomplex(px^,py^))); + inc(px); + inc(py); + end; + end; + end; + end; + end; + end; + end; //checkdist + +var + int1,int2: integer; + +begin + aindex:= 0; + dist:= maxint; + if hasactivetrace and not all then begin + atrace:= factivetrace; + aindex:= checkdist(factivetrace); + end + else begin + if hasactivetrace then begin + aindex:= checkdist(factivetrace); + atrace:= factivetrace; + end; + for int1:= 0 to traces.count-1 do begin + int2:= checkdist(int1); + if int2 >= 0 then begin + aindex:= int2; + atrace:= int1; + end; + end; + end; + if (dist >= fsnapdist*fsnapdist) then begin + aindex:= -1; + atrace:= -1; + end; + result:= aindex >= 0; +end; + +function tcustomchartedit.nodesinrect(const arect: rectty): integerarty; +var + px,py: preal; + pxy: pcomplexty; + int1,int2: integer; +begin + result:= nil; + if hasactivetrace then begin + with traces[factivetrace] do begin + int2:= 0; + setlength(result,count); + if kind = trk_xseries then begin + py:= ydatapo; + if py <> nil then begin + for int1:= 0 to high(result) do begin + if pointinrect(chartcoordxseries(factivetrace, + makexseriesdata(py^,int1)),arect) then begin + result[int2]:= int1; + inc(int2); + end; + inc(py); + end; + end; + end + else begin + pxy:= xydatapo; + if pxy <> nil then begin + for int1:= 0 to high(result) do begin + if pointinrect(chartcoordxy(factivetrace,pxy^),arect) then begin + result[int2]:= int1; + inc(int2); + end; + inc(pxy); + end; + end + else begin + px:= xdatapo; + py:= ydatapo; + if (px <> nil) and (py <> nil) then begin + for int1:= 0 to high(result) do begin + if pointinrect(chartcoordxy(factivetrace, + makecomplex(px^,py^)),arect) then begin + result[int2]:= int1; + inc(int2); + end; + inc(px); + inc(py); + end; + end; + end; + end; + setlength(result,int2); + end; + end; +end; + +function tcustomchartedit.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; +var + int1: integer; + bo1: boolean; +begin + result:= not (cems_markermoving in fmovestate) and sender.moving and + sender.hascurrentobjects; + if result then begin + shape:= cr_none; + end + else begin + if not sender.hascurrentobjects or (cems_markermoving in fmovestate) then begin + result:= getmarker(sender.pickrect.pos,false,bo1,int1,int1); + if result then begin + if bo1 then begin + shape:= cr_sizever; + end + else begin + shape:= cr_sizehor; + end; + end; + end; + end; +end; + +function tcustomchartedit.encodenodes(const atrace: integer; + const aindex: array of integer): integerarty; +var + int1,int2: integer; +begin + int2:= 0; + for int1:= 0 to atrace - 1 do begin + int2:= int2 + ftraces[int1].count; + end; + setlength(result,length(aindex)); + for int1:= 0 to high(result) do begin + result[int1]:= int2 + aindex[int1]; + end; +end; + +function tcustomchartedit.decodenodes(const aitems: integerarty; + out atrace: integer; out aindex: integerarty): boolean; +var + int1,int2,int3: integer; + min,max: integer; +begin + min:= 0; + max:= 0; + atrace:= -1; + setlength(aindex,length(aitems)); + for int1:= 0 to high(aindex) do begin + int2:= aitems[int1]; + if int2 >= 0 then begin + if atrace < 0 then begin + min:= 0; + max:= 0; + for int3:= 0 to ftraces.count - 1 do begin + min:= max; + max:= max + ttrace(ttraces1(ftraces).fitems[int3]).count; + atrace:= int3; + if max > int2 then begin + break; + end; + end; + max:= max-min; + end; + int2:= int2 - min; + if (int2 < 0) or (int2 >= max) then begin //in other trace, invalid + aindex:= nil; + atrace:= -1; + break; + end; + end; + aindex[int1]:= int2; + end; + result:= atrace >= 0; +end; + +procedure tcustomchartedit.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +var + int1,int2: integer; + bo1: boolean; + rect: rectty; +begin + objects:= nil; + rect:= sender.pickrect; + if sender.rectselecting then begin + if not readonly then begin + objects:= encodenodes(factivetrace,nodesinrect(rect)); + end; + end + else begin + if nearestnode(rect.pos,false,int1,int2) then begin + objects:= encodenodes(int1,int2); + end + else begin + if sender.picking then begin + if getmarker(sender.pickpos,false,bo1,int1,int2) then begin + objects:= encodemarker(bo1,int1,int2); + end; + end; + end; + end; +end; + +function tcustomchartedit.limitmoveoffset(const aoffset: pointty): pointty; +begin + result:= addpoint(aoffset,fpickref); + fmovestate:= fmovestate - [cems_xbottomlimit,cems_ybottomlimit, + cems_xtoplimit,cems_ytoplimit]; + if ops_moving in fobjectpicker.state then begin + if result.x > foffsetmax.x then begin + result.x:= foffsetmax.x; + include(fmovestate,cems_xtoplimit); + end; + if result.y > foffsetmax.y then begin + result.y:= foffsetmax.y; + include(fmovestate,cems_ytoplimit); + end; + if result.x < foffsetmin.x then begin + result.x:= foffsetmin.x; + include(fmovestate,cems_xbottomlimit); + end; + if result.y < foffsetmin.y then begin + result.y:= foffsetmin.y; + include(fmovestate,cems_ybottomlimit); + end; + end; + subpoint1(result,fpickref); +end; + +procedure tcustomchartedit.beginpickmove(const sender: tobjectpicker); +var + rect1: rectty; + int1,int2,int3,int4: integer; + mi,ma: pointty; + pt1: pointty; + ar1: pointarty; + objs: integerarty; + trace1: integer; + isy: boolean; + dial1,index1: integer; +begin + objs:= nil; + ar1:= nil; + trace1:= 0; + fpickref:= nullpoint; + rect1:= getdialrect; + mi.x:= maxint; + mi.y:= maxint; + ma.x:= minint; + ma.y:= minint; + if decodemarker(sender.currentobjects,isy,dial1,index1) then begin + fobjectpicker.thumbtrack:= ceo_markerthumbtrack in options; + include(fmovestate,cems_markermoving); + fmovestate:= fmovestate - [cems_canbottomlimit,cems_cantoplimit]; + with rect1 do begin + if isy then begin + with ydials[dial1].markers[index1] do begin + int3:= pos; + fmarkermovestartpos:= int3; + ma.y:= y-int3; + mi.y:= y+cy-int3; + if (dmo_ordered in options) then begin + if index1 < ydials[dial1].markers.count - 1 then begin + int4:= ydials[dial1].markers[index1+1].pos; + if int4 > y then begin + ma.y:= int4-int3; + include(fmovestate,cems_canbottomlimit); + end; + end; + if index1 > 0 then begin + int4:= ydials[dial1].markers[index1-1].pos; + if int4 < y+cy then begin + mi.y:= int4-int3; + include(fmovestate,cems_cantoplimit); + end; + end; + end; + end; + end + else begin //x + with xdials[dial1].markers[index1] do begin + int3:= pos; + fmarkermovestartpos:= int3; + ma.x:= x-int3; + mi.x:= x+cx-int3; + if (dmo_ordered in options) then begin + if index1 > 0 then begin + int4:= xdials[dial1].markers[index1-1].pos; + if int4 > x then begin + ma.x:= int4-int3; + include(fmovestate,cems_canbottomlimit); + end; + end; + if index1 < xdials[dial1].markers.count - 1 then begin + int4:= xdials[dial1].markers[index1+1].pos; + if int4 < x+cx then begin + mi.x:= int4-int3; + include(fmovestate,cems_cantoplimit); + end; + end; + end; + end; + end; + end; + end + else begin + exclude(fmovestate,cems_markermoving); + fobjectpicker.thumbtrack:= ceo_thumbtrack in options; + if readonly then begin + sender.clear; + exit; + end + else begin + if decodenodes(sender.currentobjects,trace1,objs) then begin + setlength(ar1,length(objs)); + for int1:= 0 to high(objs) do begin + pt1:= nodepos(trace1,objs[int1]); + ar1[int1]:= pt1; + if pt1.x < mi.x then begin + mi.x:= pt1.x; + end; + if pt1.y < mi.y then begin + mi.y:= pt1.y; + end; + if pt1.x > ma.x then begin + ma.x:= pt1.x; + end; + if pt1.y > ma.y then begin + ma.y:= pt1.y; + end; + end; + end; + end; + end; + if cems_markermoving in fmovestate then begin + foffsetmin:= ma; + foffsetmax:= mi; + end + else begin + with rect1 do begin + foffsetmin.x:= x - mi.x; + foffsetmin.y:= y - mi.y; + foffsetmax.x:= x + cx - ma.x; + foffsetmax.y:= y + cy - ma.y; + end; + with ftraces[trace1] do begin + if kind = trk_xseries then begin + foffsetmin.x:= 0; + foffsetmax.x:= 0; + end + else begin + if cto_xordered in options then begin + //limit to neighbours + for int1:= 0 to high(ar1) do begin + int2:= objs[int1]; + if (int2 > 0) and ((int1 = 0) or (objs[int1-1] <> int2 - 1)) then begin + pt1:= nodepos(trace1,int2-1); + int3:= pt1.x - ar1[int1].x; + if int3 > foffsetmin.x then begin + foffsetmin.x:= int3; + end; + end; + int4:= ftraces[trace1].count - 1; + if (int2 < int4) and ((int1 = high(ar1)) or + (objs[int1+1] <> int2 + 1)) then begin + pt1:= nodepos(trace1,int2+1); + int3:= pt1.x - ar1[int1].x; + if int3 < foffsetmax.x then begin + foffsetmax.x:= int3; + end; + end; + end; + end; + end; + end; + end; +end; + +function tcustomchartedit.encodemarker(const isy: boolean; + const adial,aindex: integer): integerarty; +begin + setlength(result,1); + result[0]:= (-2*(aindex+1)) and ((not adial shl 24) or $80fffffe); + if isy then begin + inc(result[0]); + end; +end; + +function tcustomchartedit.decodemarker(const aitems: integerarty; + out isy: boolean; out adial,aindex: integer): boolean; +begin + result:= (high(aitems) = 0) and (aitems[0] < 0); + if result then begin + aindex:= aitems[0]; + isy:= odd(aindex); + adial:= (not aindex and $7f000000) shr 24; + aindex:= integer(-((aindex or $7f000000) and $fffffffe)) div 2 - 1; +// end +// else begin +// aindex:= -1; +// adial:= -1; +// isy:= false; + end; +end; + +procedure tcustomchartedit.dopickmove(const sender: tobjectpicker); +var + int1,int2: integer; + pt1: pointty; + rea1: real; + da1: xseriesdataty; + co1,co2: complexty; + offs: pointty; + objs: integerarty; + marker1: tdialmarker; + trace1,tracebefore: integer; + dialindex: integer; + bo1: boolean; + +begin + offs:= limitmoveoffset(subpoint(sender.pickoffset,fpickref)); + if cems_markermoving in fmovestate then begin + decodemarker(sender.currentobjects,bo1,dialindex,int1); + if bo1 then begin + marker1:= ydials[dialindex].markers[int1]; + if fmovestate * [cems_cantoplimit,cems_ytoplimit] = + [cems_cantoplimit,cems_ytoplimit] then begin + marker1.value:= ydials[dialindex].markers[int1-1].value; + //y is screen reversed + end + else begin + if fmovestate * [cems_canbottomlimit,cems_ybottomlimit] = + [cems_canbottomlimit,cems_ybottomlimit] then begin + marker1.value:= ydials[dialindex].markers[int1+1].value; + //y is screen reversed + end + else begin + if offs.y <> 0 then begin + rea1:= ycharttomarker(fmarkermovestartpos+offs.y,dialindex); + if canevent(tmethod(fonsetmarker)) then begin + fonsetmarker(self,true,dialindex,int1,realty(rea1)); + end; + marker1.value:= rea1; + domarkerchange; + if canevent(tmethod(fonmarkerentered)) then begin + fonmarkerentered(self); + end; + end; + end; + end; + end + else begin + marker1:= xdials[dialindex].markers[int1]; + if fmovestate * [cems_cantoplimit,cems_xtoplimit] = + [cems_cantoplimit,cems_xtoplimit] then begin + marker1.value:= xdials[dialindex].markers[int1+1].value; + end + else begin + if fmovestate * [cems_canbottomlimit,cems_xbottomlimit] = + [cems_canbottomlimit,cems_xbottomlimit] then begin + marker1.value:= xdials[dialindex].markers[int1-1].value; + end + else begin + if offs.x <> 0 then begin + rea1:= xcharttomarker(fmarkermovestartpos + offs.x,dialindex); + if canevent(tmethod(fonsetmarker)) then begin + fonsetmarker(self,false,dialindex,int1,realty(rea1)); + end; + marker1.value:= rea1; + domarkerchange; + if canevent(tmethod(fonmarkerentered)) then begin + fonmarkerentered(self); + end; + end; + end; + end; + end; + end + else begin + addpoint1(fpickref,offs); + if decodenodes(sender.currentobjects,trace1,objs) then begin + tracebefore:= activetrace; + activetrace:= trace1; + try + with activetraceitem do begin + if kind = trk_xseries then begin + for int1:= 0 to high(objs) do begin + int2:= objs[int1]; + pt1:= nodepos(trace1,int2); + rea1:= yvalue[int2]; + da1:= tracecoordxseries(trace1,addpoint(pt1,offs)); + if offs.y <> 0 then begin //no rounding if nochange + rea1:= da1.value; + end; + yvalue[int2]:= rea1; + end; + end + else begin + for int1:= 0 to high(objs) do begin + int2:= objs[int1]; + pt1:= nodepos(trace1,int2); + co1:= xyvalue[int2]; + co2:= tracecoordxy(trace1,addpoint(pt1,offs)); + if offs.x <> 0 then begin //no rounding if nochange + co1.re:= co2.re; + end; + if offs.y <> 0 then begin //no rounding if nochange + co1.im:= co2.im; + end; + xyvalue[int2]:= co1; + end; + end; + end; + checkvalue; + finally + activetrace:= tracebefore; + end; + end; + end; +end; + +procedure tcustomchartedit.pickthumbtrack(const sender: tobjectpicker); +begin +// if not (cems_markermoving in fmovestate) then begin + dopickmove(sender); +// end; +end; + +procedure tcustomchartedit.endpickmove(const sender: tobjectpicker); +begin + dopickmove(sender); + if not (cems_markermoving in fmovestate) and not readonly then begin + addpoint1(sender.mouseeventinfopo^.pos,subpoint(fpickref,sender.pickoffset)); + end; + exclude(fmovestate,cems_markermoving); + fobjectpicker.thumbtrack:= false; +end; + +procedure tcustomchartedit.cancelpickmove(const sender: tobjectpicker); +begin + exclude(fmovestate,cems_markermoving); + fobjectpicker.thumbtrack:= false; +end; + +procedure tcustomchartedit.drawcrosshaircursor(const canvas: tcanvas; + const center: pointty); +begin + with center do begin + canvas.drawline(makepoint(0,y),makepoint(clientwidth,y)); + canvas.drawline(makepoint(x,0),makepoint(x,clientheight)); + end; +end; + +procedure tcustomchartedit.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); +var + ar1: pointarty; + ar2: segmentarty; + int1,int2,int3: integer; + dialindex: integer; + offs: pointty; + objs: integerarty; + trace1: integer; + rect1: rectty; + bo1: boolean; +begin + with sender do begin + if cems_markermoving in fmovestate then begin + offs:= limitmoveoffset(pickoffset); +// rect1:= getdialrect; + rect1:= innerclientrect; + decodemarker(sender.currentobjects,bo1,dialindex,int1); + with rect1 do begin + if bo1 then begin + int2:= ydials[dialindex].markers[int1].pos + offs.y; + canvas.drawline(makepoint(x,int2),makepoint(x+cx,int2)); + end + else begin + int2:= xdials[dialindex].markers[int1].pos + offs.x; + canvas.drawline(makepoint(int2,y),makepoint(int2,y+cy)); + end; + end; + end + else begin + if decodenodes(currentobjects,trace1,objs) then begin + if ceo_thumbtrack in foptions then begin + offs:= nullpoint; + end + else begin + offs:= limitmoveoffset(pickoffset); + end; + setlength(ar1,length(objs)); + setlength(ar2,length(objs)*2); //max + int2:= 0; + for int1:= 0 to high(objs) do begin + ar1[int1]:= addpoint(nodepos(trace1,objs[int1]),offs); + int3:= objs[int1]-1; + if int3 >= 0 then begin + ar2[int2].a:= nodepos(trace1,int3); + ar2[int2].b:= ar1[int1]; + if finditem(objs,int3) >= 0 then begin + addpoint1(ar2[int2].a,offs); + end; + inc(int2); + end; + int3:= objs[int1]+1; + if int3 < traces[trace1].count then begin + ar2[int2].a:= ar1[int1]; + ar2[int2].b:= nodepos(trace1,int3); + if finditem(objs,int3) < 0 then begin + inc(int2); + end; + end; + end; + setlength(ar2,int2); + canvas.drawlinesegments(ar2); + for int1:= 0 to high(ar1) do begin + canvas.drawellipse(makerect(ar1[int1],makesize(6,6))); + end; + if (ops_moving in fobjectpicker.state) then begin + if decodenodes(sender.mouseoverobjects,trace1,objs) then begin + drawcrosshaircursor(canvas,addpoint(nodepos(trace1,objs[0]),offs)); + end; + end; + end; + end; + end; +end; + +function tcustomchartedit.getreadonly: boolean; +begin + result:= oe_readonly in foptionsedit; +end; + +procedure tcustomchartedit.setreadonly(const avalue: boolean); +begin + if avalue then begin + optionsedit:= optionsedit + [oe_readonly]; + end + else begin + optionsedit:= optionsedit - [oe_readonly]; + end; +end; + +procedure tcustomchartedit.dokeydown(var ainfo: keyeventinfoty); +var + trace1,tracebefore: integer; + ar1: integerarty; +begin + if not (es_processed in ainfo.eventstate) then begin + inherited; + end; + if not (es_processed in ainfo.eventstate) then begin + fobjectpicker.dokeydown(ainfo); + end; + if not (es_processed in ainfo.eventstate) and (ainfo.key = key_delete) and + not readonly and not (ceo_nodelete in foptions) and + (ainfo.shiftstate*shiftstatesmask = []) and + fobjectpicker.hascurrentobjects then begin + if decodenodes(fobjectpicker.currentobjects,trace1,ar1) then begin + tracebefore:= activetrace; + activetrace:= trace1; + try + activetraceitem.deletedata(ar1); + fobjectpicker.clear; + include(ainfo.eventstate,es_processed); + checkvalue; + finally + activetrace:= tracebefore; + end; + end; + end; +end; + +procedure tcustomchartedit.dobeforepaint(const acanvas: tcanvas); +begin + fobjectpicker.dobeforepaint(acanvas); + inherited; +end; + +procedure tcustomchartedit.doafterpaint(const acanvas: tcanvas); +begin + inherited; + fobjectpicker.doafterpaint(acanvas); +end; + +function tcustomchartedit.chartdataxy: complexarty; +begin + with ttrace1(activetraceitem) do begin + forcexyarray; + result:= copy(xydata); + end; +end; + +function tcustomchartedit.chartdataxseries: realarty; +begin + result:= copy(activetraceitem.ydata); +end; + +procedure tcustomchartedit.dochange; +begin + resetnodehint; + if not (ws_loadedproc in fwidgetstate) then begin + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + end; +end; + +procedure tcustomchartedit.domarkerchange; +begin + if not (ws_loadedproc in fwidgetstate) then begin + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + end; +end; + +procedure tcustomchartedit.change; +begin + if not (csloading in componentstate) then begin + dochange; + end; +end; + +function tcustomchartedit.checkvalue: boolean; +begin + result:= true; + docheckvalue(result); + if result then begin + if canevent(tmethod(fondataentered)) then begin + fondataentered(self); + end; + end; +end; + +procedure tcustomchartedit.dostatread(const reader: tstatreader); +var + co1: complexty; + pt1: pointty; +begin + if canstatstate(optionsedit1,reader) then begin + inherited; + with frame do begin + co1:= zoom; + co1.re:= reader.readreal('zoomx',co1.re,1,1000); + co1.im:= reader.readreal('zoomy',co1.im,1,1000); + zoom:= co1; + pt1:= scrollpos; + pt1.x:= reader.readinteger('scrollx',pt1.x,-bigint,0); + pt1.y:= reader.readinteger('scrolly',pt1.y,-bigint,0); + scrollpos:= pt1; + end; + activetrace:= reader.readinteger('activetrace',activetrace,0,ftraces.count-1); + end; + if canstatvalue(optionsedit1,reader) then begin + doreadvalue(reader); + end; +end; + +procedure tcustomchartedit.dostatwrite(const writer: tstatwriter); +var + co1: complexty; + pt1: pointty; +begin + if canstatstate(optionsedit1,writer) then begin + inherited; + with frame do begin + co1:= zoom; + writer.writereal('zoomx',co1.re); + writer.writereal('zoomy',co1.im); + pt1:= scrollpos; + writer.writeinteger('scrollx',pt1.x); + writer.writeinteger('scrolly',pt1.y); + end; + writer.writeinteger('activetrace',activetrace); + end; + if canstatvalue(optionsedit1,writer) then begin + dowritevalue(writer); + end; +end; + +procedure tcustomchartedit.statread; +var + rea1: real; + i1,i2: int32; +begin + inherited; + if (oe1_checkvalueafterstatread in foptionsedit1) and hasactivetrace then begin + checkvalue; + if canevent(tmethod(fonsetmarker)) then begin + for i1:= 0 to xdials.count-1 do begin + with tchartdialhorz1(tchartdialshorz1(xdials).fitems[i1]) do begin + for i2:= 0 to markers.count-1 do begin + with tdialmarker1(tdialmarkers1(markers).fitems[i2]) do begin + if dmo_savevalue in options then begin + rea1:= value; + fonsetmarker(self,false,i1,i2,realty(rea1)); + finfo.value:= rea1; + end; + end; + end; + end; + end; + for i1:= 0 to ydials.count-1 do begin + with tchartdialvert1(tchartdialsvert1(ydials).fitems[i1]) do begin + for i2:= 0 to markers.count-1 do begin + with tdialmarker1(tdialmarkers1(markers).fitems[i2]) do begin + if dmo_savevalue in options then begin + rea1:= value; + fonsetmarker(self,true,i1,i2,realty(rea1)); + finfo.value:= rea1; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tcustomchartedit.setoptions(const avalue: charteditoptionsty); +begin + if avalue <> foptions then begin + foptions:= avalue; + +// with fobjectpicker do begin +// if avalue * [ceo_thumbtrack{,ceo_markerthumbtrack}] <> [] then begin +// options:= options + [opo_thumbtrack]; +// end +// else begin +// options:= options - [opo_thumbtrack]; +// end; +// end; + end; +end; + +procedure tcustomchartedit.loaded; +begin + inherited; + include(fwidgetstate,ws_loadedproc); + try + change; + finally + exclude(fwidgetstate,ws_loadedproc); + end; +end; + +procedure tcustomchartedit.clear; +begin + inherited; + doclear; + change; +end; + +function tcustomchartedit.getmarker(const apos: pointty; + const nolimited: boolean; out isy: boolean; + out adial,aindex: integer): boolean; +var + int1,int3: integer; + marker1: tdialmarker; +begin + result:= false; + for int3:= 0 to xdials.count -1 do begin +{$warnings off} + with tcustomdialcontroller1(xdials[int3]) do begin +{$warnings on} + checklayout; + for int1:= 0 to high(tdialmarkers1(markers).fitems) do begin + marker1:= tdialmarker(tdialmarkers1(markers).fitems[int1]); + if not (dmo_fix in marker1.options) and + (not nolimited or not marker1.limited) and marker1.active and + (abs(apos.x-marker1.pos) <= markersnapdist) then begin + result:= true; + isy:= false; + adial:= int3; + aindex:= int1; + exit; + end; + end; + end; + end; + for int3:= 0 to ydials.count -1 do begin +{$warnings off} + with tcustomdialcontroller1(ydials[int3]) do begin +{$warnings on} + checklayout; + for int1:= 0 to high(tdialmarkers1(markers).fitems) do begin + marker1:= tdialmarker(tdialmarkers1(markers).fitems[int1]); + if not (dmo_fix in marker1.options) and + (not nolimited or not marker1.limited) and marker1.active and + (abs(apos.y-marker1.pos) <= markersnapdist) then begin + result:= true; + isy:= true; + adial:= int3; + aindex:= int1; + exit; + end; + end; + end; + end; +end; + +procedure tcustomchartedit.setoptionsedit(const avalue: optionseditty); +begin + if foptionsedit <> avalue then begin + transferoptionsedit(self,avalue,foptionsedit,foptionsedit1); + if oe_readonly in foptionsedit then begin + fobjectpicker.options:= fobjectpicker.options - [opo_rectselect]; + end + else begin + fobjectpicker.options:= fobjectpicker.options + [opo_rectselect]; + end; + + end; +end; + +{ tcustomxychartedit } + +constructor tcustomxychartedit.create(aowner: tcomponent); +begin + if ftraces = nil then begin + ftraces:= txytraces.create(self,xordered); + end; + inherited; +end; + +function tcustomxychartedit.getvalue: complexarty; +begin + result:= fvalue; +end; + +procedure tcustomxychartedit.setvalue(const avalue: complexarty); +begin + fvalue:= avalue; + change; +end; + +procedure tcustomxychartedit.dochange; +begin + if hasactivetrace then begin + activetraceitem.xydata:= fvalue; + end; + inherited; +end; + +procedure tcustomxychartedit.docheckvalue(var accept: boolean); +var + ar1: complexarty; +begin + ar1:= chartdataxy; + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,ar1,accept); + end; + if accept then begin + value:= ar1; + end; +end; + +procedure tcustomxychartedit.doreadvalue(const reader: tstatreader); +var + int1: integer; +begin + for int1:= 0 to ftraces.count - 1 do begin + ftraces[int1].xydata:= reader.readarray('value'+inttostrmse(int1), + ftraces[int1].xydata); + end; + if hasactivetrace then begin + value:= activetraceitem.xydata; + end; +// value:= reader.readarray('value',fvalue); +end; + +procedure tcustomxychartedit.dowritevalue(const writer: tstatwriter); +var + int1: integer; +begin + for int1:= 0 to ftraces.count - 1 do begin + writer.writearray('value'+inttostrmse(int1),ftraces[int1].xydata); + end; +// writer.writearray('value',fvalue); +end; + +function tcustomxychartedit.getvalueitems(const index: integer): complexty; +begin + checkarrayindex(fvalue,index); + result:= fvalue[index]; +end; + +procedure tcustomxychartedit.setvalueitems(const index: integer; + const avalue: complexty); +begin + checkarrayindex(fvalue,index); + fvalue[index]:= avalue; + change; +end; + +function tcustomxychartedit.getreitems(const index: integer): real; +begin + checkarrayindex(fvalue,index); + result:= fvalue[index].re; +end; + +procedure tcustomxychartedit.setreitems(const index: integer; const avalue: real); +begin + checkarrayindex(fvalue,index); + fvalue[index].re:= avalue; + change; +end; + +function tcustomxychartedit.getimitems(const index: integer): real; +begin + checkarrayindex(fvalue,index); + result:= fvalue[index].im; +end; + +procedure tcustomxychartedit.setimitems(const index: integer; const avalue: real); +begin + checkarrayindex(fvalue,index); + fvalue[index].im:= avalue; + change; +end; + +class function tcustomxychartedit.xordered: boolean; +begin + result:= false; +end; + +procedure tcustomxychartedit.doclear; +begin + fvalue:= nil; +end; + +{ tcustomxserieschartedit } + +function tcustomxserieschartedit.getvalue: realarty; +begin + result:= fvalue; +// result:= traces[factivetrace].xydata; +end; + +procedure tcustomxserieschartedit.setvalue(const avalue: realarty); +begin + fvalue:= avalue; + change; +end; + +procedure tcustomxserieschartedit.dochange; +begin + if hasactivetrace then begin + activetraceitem.ydata:= fvalue; + end; + inherited; +end; + +procedure tcustomxserieschartedit.docheckvalue(var accept: boolean); +var + ar1: realarty; +begin + ar1:= chartdataxseries; + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,ar1,accept); + end; + if accept then begin + value:= ar1; + end; +end; + +procedure tcustomxserieschartedit.doreadvalue(const reader: tstatreader); +begin + value:= reader.readarray('value',fvalue); +end; + +procedure tcustomxserieschartedit.dowritevalue(const writer: tstatwriter); +begin + writer.writearray('value',fvalue); +end; + +function tcustomxserieschartedit.getvalueitems(const index: integer): real; +begin + checkarrayindex(fvalue,index); + result:= fvalue[index]; +end; + +procedure tcustomxserieschartedit.setvalueitems(const index: integer; + const avalue: real); +begin + checkarrayindex(fvalue,index); + fvalue[index]:= avalue; + change; +end; + +procedure tcustomxserieschartedit.doclear; +begin + fvalue:= nil; +end; + +{ tcustomorderedxychartedit } + +class function tcustomorderedxychartedit.xordered: boolean; +begin + result:= true; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msedial.pas b/mseide-msegui/lib/common/widgets/msedial.pas new file mode 100644 index 0000000..15acf99 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msedial.pas @@ -0,0 +1,3037 @@ +{ MSEgui Copyright (c) 2009-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedial; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + classes,mclasses,msewidgets,msegraphutils,msegraphics,msegui,msearrayprops, + mseclasses, + msetypes,mseglob,mseguiglob,msestrings,msemenus,mseevent,msestat; + +const + defaultdialcolor = cl_dkgray; + +type + rectsidety = (rs_left,rs_top,rs_right,rs_bottom); + rectsidesty = set of rectsidety; + + dialstatety = (dis_layoutvalid,dis_needstransform); + dialstatesty = set of dialstatety; + + tickcaptionty = record + caption: msestring; + width: integer; + pos: pointty; + angle: real; + end; + tickcaptionarty = array of tickcaptionty; + + tdialpropfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tdialfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + dialdatakindty = (dtk_real,dtk_datetime); + + diallineinfoty = record + color: colorty; + widthmm: real; + dashes: string; + indent: integer; + length: integer; + captiondist: integer; + captionoffset: integer; + escapement: real; + font: tdialpropfont; + caption: msestring; + captionunit: msestring; +// kind: dialdatakindty; + end; + + dialtickoptionty = (dto_invisible,dto_opposite,dto_rotatetext, + dto_multiplecaptions, + dto_alignstart,dto_aligncenter,dto_alignend); + //allow captions of different ticks at same position + + dialtickoptionsty = set of dialtickoptionty; + + dialtickinfoty = record + ticks: segmentarty; + ticksreal: realarty; + captions: tickcaptionarty; + intervalco: real; + interval: real; + afont: tfont; + options: dialtickoptionsty; + end; + + tdialprop = class(townedpersistent) + private + fli: diallineinfoty; + procedure setcolor(const avalue: colorty); + procedure setwidthmm(const avalue: real); + procedure setdashes(const avalue: string); + procedure setindent(const avalue: integer); + procedure setlength(const avalue: integer); + procedure setcaption(const avalue: msestring); + procedure setcaptionunit(const avalue: msestring); + procedure setcaptiondist(const avalue: integer); + procedure setcaptionoffset(const avalue: integer); + function getfont: tdialpropfont; + procedure setfont(const avalue: tdialpropfont); + function isfontstored: boolean; + procedure fontchanged(const sender: tobject); + procedure setescapement(const avalue: real); + + protected + flayoutvalid: boolean; + procedure changed; virtual; + function getactcaption(const avalue: real; const aformat: msestring): msestring; + function actualcolor: colorty; + function actualwidthmm: real; + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure createfont; + published + property color: colorty read fli.color write setcolor + default cl_default; + property widthmm: real read fli.widthmm write setwidthmm; + //0 -> withmm of dialcontroller + property dashes: string read fli.dashes write setdashes; + property indent: integer read fli.indent + write setindent default 0; + property length: integer read fli.length + write setlength default 0; + //0 -> whole innerclientrect + property caption: msestring read fli.caption write setcaption; + property captionunit: msestring read fli.captionunit write setcaptionunit; + property captiondist: integer read fli.captiondist write setcaptiondist + default 2; + property captionoffset: integer read fli.captionoffset write setcaptionoffset + default 0; + property font: tdialpropfont read getfont write setfont stored isfontstored; + property escapement: real read fli.escapement write setescapement; + end; + + dialmarkeroptionty = (dmo_invisible,dmo_opposite,dmo_back,dmo_rotatetext, + dmo_bar,dmo_barfront, + dmo_hideoverload,dmo_limitoverload,dmo_limitoverloadi, + dmo_hidelimit, + dmo_fix,dmo_ordered,dmo_savevalue); //for tchartedit + dialmarkeroptionsty = set of dialmarkeroptionty; + + tmarkerframe = class(tframe) + public + constructor create(const aintf: iframe); + end; + + markerinfoty = record + active: boolean; + limited: boolean; + line: segmentty; + value: realty; + captionpos: pointty; + aangle: real; + afont: tfont; + acaption: msestring; + options: dialmarkeroptionsty; + barrect: rectty; + bar_color: colorty; + bar_width: integer; + bar_shift: integer; + bar_frame: tframe; + bar_face: tface; + end; + +const + defaultmarkerwidth = 3; + +type + tdialmarker = class(tdialprop,iframe,iface) + private + fhintcaption: msestring; + procedure checklayout; + procedure readvalue(reader: treader); + procedure setvalue(const avalue: realty); + procedure setoptions(const avalue: dialmarkeroptionsty); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getbar_frame: tframe; + procedure setbar_frame(const avalue: tframe); + function getbar_face: tface; + procedure setbar_face(const avalue: tface); + procedure setbar_width(const avalue: integer); + procedure setbar_shift(const avalue: integer); + procedure setbar_color(const avalue: colorty); + protected + finfo: markerinfoty; + procedure defineproperties(filer: tfiler); override; + procedure updatemarker; + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getwidget: twidget; + function getwidgetrect: rectty; + function getframestateflags: framestateflagsty; + //iface + function translatecolor(const acolor: colorty): colorty; + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + procedure widgetregioninvalid; + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure createframe; + procedure createface; + function pos: integer; + procedure paint(const acanvas: tcanvas); + property visible: boolean read getvisible write setvisible; + property active: boolean read finfo.active; + property limited: boolean read finfo.limited; + published + property value: realty read finfo.value write setvalue {stored false}; + property options: dialmarkeroptionsty read finfo.options + write setoptions default []; + property hintcaption: msestring read fhintcaption + write fhintcaption; + property bar_color: colorty read finfo.bar_color + write setbar_color default cl_none; + property bar_width: integer read finfo.bar_width write setbar_width + default defaultmarkerwidth; + property bar_shift: integer read finfo.bar_shift write setbar_shift + default 0; + property bar_frame: tframe read getbar_frame write setbar_frame; + property bar_face: tface read getbar_face write setbar_face; + end; + + tcustomdialcontroller = class; + + tdialmarkers = class(townedpersistentarrayprop) + private + function getitems(const aindex: integer): tdialmarker; + procedure changed; + protected + fdim: rectextty; + procedure dosizechanged; override; + public + constructor create(const aowner: tcustomdialcontroller); reintroduce; + procedure paint1(const acanvas: tcanvas); + procedure paint2(const acanvas: tcanvas); + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tdialmarker read getitems; default; + end; + + tdialtick = class(tdialprop) + private + finfo: dialtickinfoty; + function getintervalcount: real; + procedure setintervalcount(const avalue: real); + procedure setoptions(const avalue: dialtickoptionsty); + function getinterval: real; + procedure setinterval(const avalue: real); + function isintervalcountstored: boolean; + function isintervalstored: boolean; + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + protected + public + property visible: boolean read getvisible write setvisible; + published + property intervalcount: real read getintervalcount write setintervalcount + stored isintervalcountstored; + //0 -> off + property interval: real read getinterval write setinterval + stored isintervalstored; + //0 -> off + property options: dialtickoptionsty read finfo.options + write setoptions default []; + end; + + tdialticks = class(townedpersistentarrayprop) + private + function getitems(const aindex: integer): tdialtick; + protected + fdim: rectextty; + procedure changed; + procedure change(const index: integer); override; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tcustomdialcontroller); reintroduce; + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tdialtick read getitems; default; + end; + + dialoptionty = (do_invisible,do_opposite,do_sideline,do_boxline,do_log, + do_front,do_smooth,do_scrollwithdata,do_shiftwithdata, + do_savestate); + dialoptionsty = set of dialoptionty; + + idialcontroller = interface(inullinterface) + procedure directionchanged(const dir,dirbefore: graphicdirectionty); + procedure layoutchanged; + function getwidget: twidget; + function getdialrect: rectty; + function getlimitrect: rectty; + end; + + tcustomdialcontroller = class(tvirtualpersistent) + private + fdirection: graphicdirectionty; + fstate: dialstatesty; + fmarkers: tdialmarkers; + fticks: tdialticks; + foptions: dialoptionsty; + fintf: idialcontroller; + ffont: tdialfont; + fcolor: colorty; + fwidthmm: real; + fboxlines: segmentarty; + fstartang,farcang: real; + fsidearc: rectty; + fboxarc: rectty; + fkind: dialdatakindty; + fangle: real; + fa: real; //0.5 * angle in radiant + fr: real; //radius + fscalep: real; //periphery scale, 2/size + foffsr: integer; //radius offset + foffsp: integer; //periphery shift before/after transform + fendr: integer; //radius end for reversed direction + farcscale: real; //factor diallenght arc / diallenght linear + findent1: integer; + findent2: integer; + ffitdist: integer; + procedure setstart(const avalue: real); + procedure setshift(const avalue: real); + procedure setrange(const avalue: real); + procedure setmarkers(const avalue: tdialmarkers); + procedure setoptions(const avalue: dialoptionsty); + procedure setticks(const avalue: tdialticks); + function getfont: tdialfont; + procedure setfont(const avalue: tdialfont); + function isfontstored: boolean; + procedure setcolor(const avalue: colorty); + procedure setwidthmm(const avalue: real); + procedure setkind(const avalue: dialdatakindty); + procedure setangle(const avalue: real); + procedure readstart(reader: treader); + procedure setindent1(const avalue: integer); + procedure setindent2(const avalue: integer); + function getlog: boolean; + procedure setlog(const avalue: boolean); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getopposite: boolean; + procedure setopposite(const avalue: boolean); + function getsideline: boolean; + procedure setsideline(const avalue: boolean); + function getboxline: boolean; + procedure setboxline(const avalue: boolean); + function getfront: boolean; + procedure setfront(const avalue: boolean); + procedure setfitdist(const avalue: integer); + protected + fsstart: real; + flnsstart: real; + fstart: real; + fshift: real; + frange: real; + flnrange: real; + procedure setdirection(const avalue: graphicdirectionty); virtual; + procedure layoutchanged; + procedure changed; + procedure calclineend(const ainfo: diallineinfoty; const aopposite: boolean; + const arect: rectty; out linestart,lineend: integer; + out linedirection: graphicdirectionty; + out adim: rectextty); + procedure adjustcaption(const dir: graphicdirectionty; + const arotatetext: boolean; + const ainfo: diallineinfoty; const afont: tfont; + const stringwidth: integer; var pos: pointty); + procedure checklayout; + procedure invalidate; + procedure fontchanged(const sender: tobject); + procedure transform(var apoint: pointty); + procedure defineproperties(filer: tfiler); override; + function getactdialrect(out arect: rectty): boolean; + procedure paintdial(const acanvas: tcanvas); + public + constructor create(const aintf: idialcontroller); reintroduce; virtual; + destructor destroy; override; + procedure createfont; + procedure paint(const acanvas: tcanvas); + procedure afterpaint(const acanvas: tcanvas); + property options: dialoptionsty read foptions write setoptions default []; + //first! + property visible: boolean read getvisible write setvisible; + property opposite: boolean read getopposite write setopposite; + property sideline: boolean read getsideline write setsideline; + property boxline: boolean read getboxline write setboxline; + property log: boolean read getlog write setlog; + property front: boolean read getfront write setfront; + + property direction: graphicdirectionty read fdirection write setdirection + default gd_right; + property indent1: integer read findent1 write setindent1 default 0; + property indent2: integer read findent2 write setindent2 default 0; + property fitdist: integer read ffitdist write setfitdist default 0; + property start: real read fstart write setstart; + property shift: real read fshift write setshift; //added to start + property range: real read frange write setrange; //default 1.0 + property kind: dialdatakindty read fkind write setkind default dtk_real; + property markers: tdialmarkers read fmarkers write setmarkers; + property ticks: tdialticks read fticks write setticks; + property color: colorty read fcolor write setcolor default defaultdialcolor; + property widthmm: real read fwidthmm write setwidthmm; + //linewidth, default 0.3 + property font: tdialfont read getfont write setfont stored isfontstored; + property angle: real read fangle write setangle; //0 -linear, 1 -> 360 grad + end; + + dialcontrollerclassty = class of tcustomdialcontroller; + + tcustomdialcontrollers = class(tpersistentarrayprop) + private + fstart: real; + frange: real; + procedure setstart(const avalue: real); + procedure setrange(const avalue: real); + protected + fintf: idialcontroller; + function getitemclass: dialcontrollerclassty; virtual; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure changed; + public + constructor create(const aintf: idialcontroller); + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + published + property start: real read fstart write setstart; + property range: real read frange write setrange; + end; + +const + defaultdialcontrolleroptions = [do_opposite]; + +type + tdialcontroller = class(tcustomdialcontroller) + public + constructor create(const aintf: idialcontroller); override; + published + property options default defaultdialcontrolleroptions; //first! + property color; + property widthmm; + property direction; + property indent1; + property indent2; + property start; + property range; + property kind; + property markers; + property ticks; + property font; + property angle; + end; + + optiondialty = (odi_autofitleft,odi_autofittop,odi_autofitright, + odi_autofitbottom); //same layout as rectsidesty + optionsdialty = set of optiondialty; + +const + allrectsides = [rs_left,rs_top,rs_right,rs_bottom]; + rectsidesmask = [odi_autofitleft,odi_autofittop,odi_autofitright, + odi_autofitbottom]; + defaultoptionsdial = [odi_autofitleft,odi_autofittop,odi_autofitright, + odi_autofitbottom]; +type + dialwidgetstatety = (dws_layoutvalid); + dialwidgetstatesty = set of dialwidgetstatety; + + tcustomdial = class(tpublishedwidget,idialcontroller) + private + fdial: tdialcontroller; + ffitframe: framety; + foptions: optionsdialty; + fstate: dialwidgetstatesty; + procedure setdial(const avalue: tdialcontroller); + procedure setfitframe(const avalue: framety); + procedure setfitframe_left(const avalue: integer); + procedure setfitframe_top(const avalue: integer); + procedure setfitframe_right(const avalue: integer); + procedure setfitframe_bottom(const avalue: integer); + procedure setoptions(const avalue: optionsdialty); + protected + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure clientrectchanged; override; + procedure invalidatelayout; + function checklayout: boolean; virtual; //true if changes made + //idialcontroller + procedure layoutchanged; + procedure directionchanged(const dir,dirbefore: graphicdirectionty); + function getdialrect: rectty; + function getlimitrect: rectty; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure paint(const acanvas: tcanvas); override; + function fit(const asides: rectsidesty = allrectsides): boolean; + //adjust fitframe for extents of dial + //returns true if changes made + property dial: tdialcontroller read fdial write setdial; + property fitframe: framety read ffitframe write setfitframe; + property fitframe_left: integer read ffitframe.left + write setfitframe_left default 0; + property fitframe_top: integer read ffitframe.top + write setfitframe_top default 0; + property fitframe_right: integer read ffitframe.right + write setfitframe_right default 0; + property fitframe_bottom: integer read ffitframe.bottom + write setfitframe_bottom default 0; + property options: optionsdialty read foptions write setoptions + default defaultoptionsdial; + published + property color default cl_transparent; + property optionswidget default defaultoptionswidgetnofocus; + end; + + tdial = class(tcustomdial) + published + property dial; + property bounds_cy default 15; + property bounds_cx default 100; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property options; + end; + +procedure checknullrange(const avalue: real); +function chartln(const avalue: real): real; + //big neg value for avalue <= 0 +function chartround(const avalue: real): integer; //limit to +-bigint + +implementation +uses + sysutils,msereal,msestreaming,mseformatstr,math,msebits; +type + tcustomframe1 = class(tcustomframe); + twidget1 = class(twidget); + +procedure checknullrange(const avalue: real); +begin + if avalue = 0 then begin + raise exception.create('Range can not be 0.0.'); + end; +end; + +function chartln(const avalue: real): real; +begin + if avalue <= 0 then begin + result:= -100000; + end + else begin + result:= ln(avalue); + end; +end; + +function chartround(const avalue: real): integer; //limit to +-bigint +begin + if avalue > bigint then begin + result:= bigint; + end + else begin + if avalue < -bigint then begin + result:= -bigint; + end + else begin + result:= round(avalue); + end; + end; +end; + +procedure extenddim(const textwidth,asc,desc: integer; const pos: pointty; + var dim: rectextty); +var + int2: integer; +begin + with dim do begin + int2:= pos.x + textwidth; + if pos.x < left then begin + left:= pos.x; + end; + if int2 > right then begin + right:= int2; + end; + if top > pos.y - asc then begin + top:= pos.y - asc; + end; + if bottom < pos.y + desc then begin + bottom:= pos.y + desc; + end; + end; +end; + +{ tdialpropfont } + +class function tdialpropfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tdialprop(owner).fli.font; +end; + +{ tdialfont } + +class function tdialfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomdialcontroller(owner).ffont; +end; + +{ tdialprop } + +constructor tdialprop.create(aowner: tobject); +begin + fli.color:= cl_default; + fli.captiondist:= 2; +// fli.widthmm:= 0.3; + inherited; +end; + +destructor tdialprop.destroy; +begin + fli.font.free; + inherited; +end; + +procedure tdialprop.changed; +begin + flayoutvalid:= false; + tcustomdialcontroller(fowner).layoutchanged; +end; + +procedure tdialprop.setcolor(const avalue: colorty); +begin + if fli.color <> avalue then begin + fli.color:= avalue; + tcustomdialcontroller(fowner).invalidate; + end; +end; + +procedure tdialprop.setwidthmm(const avalue: real); +begin + fli.widthmm:= avalue; +// changed; + tcustomdialcontroller(fowner).invalidate; +end; + +procedure tdialprop.setdashes(const avalue: string); +begin + fli.dashes:= avalue; + tcustomdialcontroller(fowner).invalidate; +end; + +procedure tdialprop.setindent(const avalue: integer); +begin + if fli.indent <> avalue then begin + fli.indent:= avalue; + changed; + end; +end; + +procedure tdialprop.setlength(const avalue: integer); +begin + if fli.length <> avalue then begin + fli.length:= avalue; + changed; + end; +end; + +procedure tdialprop.setcaption(const avalue: msestring); +begin + fli.caption:= avalue; + changed; +end; + +procedure tdialprop.setcaptionunit(const avalue: msestring); +begin + fli.captionunit:= avalue; + changed; +end; + +procedure tdialprop.setcaptiondist(const avalue: integer); +begin + if fli.captiondist <> avalue then begin + fli.captiondist:= avalue; + changed; + end; +end; + +procedure tdialprop.setcaptionoffset(const avalue: integer); +begin + if fli.captionoffset <> avalue then begin + fli.captionoffset:= avalue; + changed; + end; +end; + +procedure tdialprop.fontchanged(const sender: tobject); +begin + changed; +end; + +procedure tdialprop.createfont; +begin + if fli.font = nil then begin + fli.font:= tdialpropfont.create; + fli.font.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function tdialprop.getfont: tdialpropfont; +begin + getoptionalobject(tcustomdialcontroller(fowner).fintf.getwidget.componentstate, + fli.font,{$ifdef FPC}@{$endif}createfont); + if fli.font <> nil then begin + result:= fli.font; + end + else begin +{$warnings off} + result:= tdialpropfont(tcustomdialcontroller(fowner).getfont); +{$warnings on} + end; +end; + +procedure tdialprop.setfont(const avalue: tdialpropfont); +begin + if avalue <> fli.font then begin + setoptionalobject(tcustomdialcontroller(fowner).fintf.getwidget.componentstate, + avalue,fli.font,{$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function tdialprop.isfontstored: boolean; +begin + result:= fli.font <> nil; +end; + +procedure tdialprop.setescapement(const avalue: real); +begin + if avalue <> fli.escapement then begin + fli.escapement:= avalue; + changed; + end; +end; + +function tdialprop.getactcaption(const avalue: real; const aformat: msestring): msestring; +begin + if tcustomdialcontroller(fowner).fkind = dtk_datetime then begin + result:= datetimetostring(avalue,aformat); + end + else begin + result:= formatfloatmse(avalue,aformat); + end; +end; + +function tdialprop.actualcolor: colorty; +begin + result:= fli.color; + if fli.color = cl_default then begin + result:= tcustomdialcontroller(fowner).fcolor; + end; +end; + +function tdialprop.actualwidthmm: real; +begin + result:= fli.widthmm; + if result = 0 then begin + result:= tcustomdialcontroller(fowner).fwidthmm; + end; +end; + +{ tdialmarker } + +constructor tdialmarker.create(aowner: tobject); +begin + finfo.bar_color:= cl_none; + finfo.bar_width:= defaultmarkerwidth; + inherited; +end; + +destructor tdialmarker.destroy; +begin + inherited; + finfo.bar_frame.free; + finfo.bar_face.free; +end; + +procedure tdialmarker.setvalue(const avalue: realty); +begin + if finfo.value <> avalue then begin + finfo.value:= avalue; + changed; + end; +end; + +procedure tdialmarker.paint(const acanvas: tcanvas); + procedure drawbar; + var + rect2: rectty; + begin + if finfo.bar_color <> cl_none then begin + acanvas.fillrect(finfo.barrect,finfo.bar_color); + end; + if finfo.bar_frame <> nil then begin + acanvas.save; + finfo.bar_frame.paintbackground(acanvas,finfo.barrect,true,true); + if finfo.bar_face <> nil then begin + rect2:= deflaterect(finfo.barrect,finfo.bar_frame.innerframe); + acanvas.remove(pointty(finfo.bar_frame.paintframe.topleft)); + finfo.bar_face.paint(acanvas,rect2); + end; + acanvas.restore; + finfo.bar_frame.paintoverlay(acanvas,finfo.barrect); + end + else begin + if finfo.bar_face <> nil then begin + finfo.bar_face.paint(acanvas,finfo.barrect); + end; + end; + end; //drawbar + +begin + checklayout; + with finfo,fli do begin + if active then begin + if not limited or not(dmo_hidelimit in options) then begin + if not (dmo_barfront in options) then begin + drawbar; + end; + acanvas.linewidthmm:= actualwidthmm; + if dashes <> '' then begin + acanvas.dashes:= dashes; + end; + acanvas.drawline(line.a,line.b,actualcolor); + if dashes <> '' then begin + acanvas.dashes:= ''; + end; + if dmo_barfront in options then begin + drawbar; + end; + end; + if caption <> '' then begin + acanvas.drawstring(acaption,captionpos,self.font,false,aangle); + end; + end; + end; +end; + +procedure tdialmarker.checklayout; +begin + if not flayoutvalid then begin + with finfo do begin + active:= not (finfo.value = emptyreal); + if active then begin + updatemarker; + end; + end; + flayoutvalid:= true; + end; +end; + +procedure tdialmarker.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; +{ +procedure tdialmarker.writevalue(writer: twriter); +begin + writerealty(writer,finfo.value); +end; +} +procedure tdialmarker.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); +end; + +procedure tdialmarker.updatemarker; +var + rect1: rectty; + + function snap(const avalue: real): integer; + //snap to ticks + var + int1,int2: integer; + begin + with tcustomdialcontroller(fowner) do begin + if not (dis_needstransform in fstate) then begin + with fticks do begin + for int1:= 0 to count - 1 do begin + with tdialtick(fitems[int1]).finfo do begin + for int2:= 0 to high(ticksreal) do begin + if abs(avalue-ticksreal[int2]) < 0.1 then begin + if direction in [gd_right,gd_left] then begin + result:= ticks[int2].a.x; + end + else begin + result:= ticks[int2].a.y; + end; + exit; + end; + end; + end; + end; + end; + end; + result:= round(avalue); + if direction in [gd_right,gd_left] then begin + result:= result + rect1.x; + end + else begin + result:= result + rect1.y; + end; + end; + end; + +var + linestart,lineend: integer; + dir1: graphicdirectionty; + rea1,rea2: real; + start1,stop1: real; + rect2: rectty; + pt1: pointty; + rectext1: rectextty; + int1: integer; + +begin + stop1:= 0; + start1:= 0; + with tcustomdialcontroller(fowner),fli,finfo,line do begin + getactdialrect(rect1); + active:= false; + limited:= false; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + calclineend(fli,dmo_opposite in options,rect1,linestart,lineend,dir1, + rectext1); + if do_log in foptions then begin + rea2:= flnsstart; + rea1:= flnrange; + if rea1 = 0 then begin + exit; + end; + rea1:= (chartln(value) - rea2)/rea1; + end + else begin + rea1:= (value - fsstart)/frange; + end; + if dmo_hideoverload in options then begin + if (rea1 < 0) or (rea1 > 1) then begin + exit; + end; + end; + if dmo_limitoverloadi in options then begin + if rea1 < 0 then begin + rea1:= 0; + limited:= true; + end + else begin + if rea1 > 1 then begin + rea1:= 1; + limited:= true; + end; + end; + end + else begin + if dmo_limitoverload in options then begin + rect2:= fintf.getlimitrect; + case fdirection of + gd_right: begin + start1:= (rect2.x - rect1.x) / rect1.cx; + stop1:= (rect2.x + rect2.cx - rect1.x {- 1}) / rect1.cx; + end; + gd_up: begin + start1:= (rect1.y + rect1.cy - rect2.y - rect2.cy {- 1}) / rect1.cy; + stop1:= (rect1.y + rect1.cy - rect2.y) / rect1.cy; + end; + gd_left: begin + start1:= (rect1.x + rect1.cx - rect2.x - rect2.cx {- 1}) / rect1.cx; + stop1:= (rect1.x + rect1.cx - rect2.x) / rect1.cx; + end; + gd_down: begin + start1:= (rect2.y - rect1.y) / rect1.cy; + stop1:= (rect2.y + rect2.cy - rect1.y {- 1}) / rect1.cy; + end; + end; + if rea1 < start1 then begin + rea1:= start1; + limited:= true; + end + else begin + if rea1 > stop1 then begin + rea1:= stop1; + limited:= true; + end; + end; + end; + end; + case fdirection of + gd_right: begin + a.x:= snap(rect1.cx * rea1); + b.x:= a.x; + a.y:= linestart; + b.y:= lineend; + end; + gd_up: begin + a.y:= snap(rect1.cy - (rect1.cy * rea1)); + b.y:= a.y; + a.x:= linestart; + b.x:= lineend; + end; + gd_left: begin + a.x:= snap(rect1.cx - (rect1.cx * rea1)); + b.x:= a.x; + a.y:= linestart; + b.y:= lineend; + end; + gd_down: begin + a.y:= snap(rect1.cy * rea1); + b.y:= a.y; + a.x:= linestart; + b.x:= lineend; + end; + end; + if dmo_bar in options then begin + case fdirection of + gd_right: begin + barrect.x:= rect1.x; + barrect.cx:= a.x - barrect.x; + barrect.y:= rect1.y + (rect1.cy - bar_width) div 2 + bar_shift; + barrect.cy:= bar_width; + end; + gd_up: begin + barrect.y:= a.y; + barrect.cy:= rect1.y + rect1.cy - barrect.y; + barrect.x:= rect1.x + (rect1.cx - bar_width) div 2 + bar_shift; + barrect.cx:= bar_width; + end; + gd_left: begin + barrect.x:= a.x; + barrect.cx:= rect1.x + rect1.cx - barrect.x; + barrect.y:= rect1.y + (rect1.cy - bar_width) div 2 - bar_shift; + barrect.cy:= bar_width; + end; + gd_down: begin + barrect.y:= rect1.y; + barrect.cy:= a.y - barrect.y; + barrect.x:= rect1.x + (rect1.cx - bar_width) div 2 - bar_shift; + barrect.cx:= bar_width; + end; + end; + end + else begin + if fdirection in [gd_left,gd_right] then begin + barrect.x:= a.x - bar_width div 2; + if fdirection = gd_right then begin + barrect.x:= barrect.x + bar_shift; + end + else begin + barrect.x:= barrect.x - bar_shift; + end; + barrect.cx:= bar_width; + if linestart > lineend then begin + barrect.y:= lineend; + barrect.cy:= linestart-lineend; + end + else begin + barrect.y:= linestart; + barrect.cy:= lineend-linestart; + end; + end + else begin + barrect.y:= a.y - bar_width div 2; + if fdirection = gd_up then begin + barrect.y:= barrect.y - bar_shift; + end + else begin + barrect.y:= barrect.y + bar_shift; + end; + barrect.cy:= bar_width; + if linestart > lineend then begin + barrect.x:= lineend; + barrect.cx:= linestart-lineend; + end + else begin + barrect.x:= linestart; + barrect.cx:= lineend-linestart; + end; + end; + end; + if dmo_rotatetext in self.finfo.options then begin + aangle:= -angle * (rea1-0.5) * 2*pi; + end + else begin + aangle:= 0; + end; + aangle:= aangle + escapement*2*pi; + if caption <> '' then begin + afont:= self.font; + acaption:= getactcaption(value,caption); + captionpos:= a; + int1:= fintf.getwidget.getcanvas.getstringwidth(acaption,afont); + adjustcaption(dir1,dmo_rotatetext in self.finfo.options,fli,afont, + int1,captionpos); + extenddim(int1,afont.ascent,afont.descent,captionpos,fmarkers.fdim); + end; + transform(a); + transform(b); + if dmo_opposite in options then begin + pt1:= a; + a:= b; + b:= pt1; + end; + active:= true; + end; + end; +end; + +procedure tdialmarker.setoptions(const avalue: dialmarkeroptionsty); +begin + if finfo.options <> avalue then begin + finfo.options:= avalue; + changed; + end; +end; + +function tdialmarker.getvisible: boolean; +begin + result:= not (dmo_invisible in finfo.options); +end; + +procedure tdialmarker.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [dmo_invisible]; + end + else begin + options:= options + [dmo_invisible]; + end; +end; + +function tdialmarker.pos: integer; +begin + if tcustomdialcontroller(fowner).direction in [gd_left,gd_right] then begin + result:= finfo.line.a.x; + end + else begin + result:= finfo.line.a.y; + end; +end; + +function tdialmarker.getbar_frame: tframe; +begin + tcustomdialcontroller(fowner).fintf.getwidget.getoptionalobject( + finfo.bar_frame,{$ifdef FPC}@{$endif}createframe); + result:= finfo.bar_frame; +end; + +procedure tdialmarker.setbar_frame(const avalue: tframe); +begin + tcustomdialcontroller(fowner).fintf.getwidget.setoptionalobject( + avalue,finfo.bar_frame,{$ifdef FPC}@{$endif}createframe); + changed; +end; + +procedure tdialmarker.createframe; +begin + if finfo.bar_frame = nil then begin + tmarkerframe.create(iframe(self)); + end; +end; + +procedure tdialmarker.setframeinstance(instance: tcustomframe); +begin + finfo.bar_frame:= tframe(instance); +end; + +procedure tdialmarker.setstaticframe(value: boolean); +begin + //dummy +end; + +function tdialmarker.getstaticframe: boolean; +begin + result:= false; +end; + +procedure tdialmarker.scrollwidgets(const dist: pointty); +begin + //dummy +end; + +procedure tdialmarker.clientrectchanged; +begin + invalidate; +end; + +function tdialmarker.getcomponentstate: tcomponentstate; +begin + result:= tcustomdialcontroller(fowner).fintf.getwidget.componentstate; +end; + +function tdialmarker.getmsecomponentstate: msecomponentstatesty; +begin + result:= tcustomdialcontroller(fowner).fintf.getwidget.msecomponentstate; +end; + +procedure tdialmarker.invalidate; +begin + tcustomdialcontroller(fowner).fintf.getwidget.invalidate; +end; + +procedure tdialmarker.invalidatewidget; +begin + tcustomdialcontroller(fowner).fintf.getwidget.invalidatewidget; +end; + +procedure tdialmarker.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + tcustomdialcontroller(fowner).fintf.getwidget.invalidaterect(rect,org,noclip); +end; + +function tdialmarker.getwidget: twidget; +begin + result:= tcustomdialcontroller(fowner).fintf.getwidget; +end; + +function tdialmarker.getwidgetrect: rectty; +begin + result:= finfo.barrect; +end; + +function tdialmarker.getframestateflags: framestateflagsty; +begin + result:= []; +end; + +function tdialmarker.getbar_face: tface; +begin + tcustomdialcontroller(fowner).fintf.getwidget.getoptionalobject( + finfo.bar_face,{$ifdef FPC}@{$endif}createface); + result:= finfo.bar_face; +end; + +procedure tdialmarker.setbar_face(const avalue: tface); +begin + tcustomdialcontroller(fowner).fintf.getwidget.setoptionalobject( + avalue,finfo.bar_face,{$ifdef FPC}@{$endif}createface); + changed; +end; + +procedure tdialmarker.createface; +begin + if finfo.bar_face = nil then begin + finfo.bar_face:= tface.create(iface(self)); + end; +end; + +function tdialmarker.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; + if acolor = cl_default then begin + result:= fli.color; + end + else begin + result:= acolor; + end; +end; + +function tdialmarker.getclientrect: rectty; +begin + result:= finfo.barrect; +end; + +procedure tdialmarker.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + twidget1(tcustomdialcontroller(fowner).fintf.getwidget).setlinkedvar( + source,dest,linkintf); +end; + +procedure tdialmarker.widgetregioninvalid; +begin + //dummy +end; + +procedure tdialmarker.setbar_width(const avalue: integer); +begin + if finfo.bar_width <> avalue then begin + finfo.bar_width:= avalue; + changed; + end; +end; + +procedure tdialmarker.setbar_shift(const avalue: integer); +begin + if finfo.bar_shift <> avalue then begin + finfo.bar_shift:= avalue; + changed; + end; +end; + +procedure tdialmarker.setbar_color(const avalue: colorty); +begin + if finfo.bar_color <> avalue then begin + finfo.bar_color:= avalue; + changed; + end; +end; + +{ tdialmarkers } + +constructor tdialmarkers.create(const aowner: tcustomdialcontroller); +begin + inherited create(aowner,tdialmarker); +end; + +class function tdialmarkers.getitemclasstype: persistentclassty; +begin + result:= tdialmarker; +end; + +function tdialmarkers.getitems(const aindex: integer): tdialmarker; +begin + result:= tdialmarker(inherited items[aindex]); +end; + +procedure tdialmarkers.paint1(const acanvas: tcanvas); +var + int1: integer; +begin + for int1:= high(fitems) downto 0 do begin + with tdialmarker(fitems[int1]) do begin + if visible and (dmo_back in options) then begin + paint(acanvas); + end; + end; + end; +end; + +procedure tdialmarkers.paint2(const acanvas: tcanvas); +var + int1: integer; +begin + for int1:= high(fitems) downto 0 do begin + with tdialmarker(fitems[int1]) do begin + if visible and not (dmo_back in options) then begin + paint(acanvas); + end; + end; + end; +end; + +procedure tdialmarkers.changed; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tdialmarker(fitems[int1]).flayoutvalid:= false; + end; +end; + +procedure tdialmarkers.dosizechanged; +begin + inherited; + tcustomdialcontroller(fowner).changed; +end; + +{ tdialtick } + +procedure tdialtick.setoptions(const avalue: dialtickoptionsty); +{$ifndef FPC} +const + mask1: dialtickoptionsty = [dto_alignstart,dto_aligncenter,dto_alignend]; +{$endif} +begin + if finfo.options <> avalue then begin + finfo.options:= dialtickoptionsty( + {$ifdef FPC} + setsinglebit(longword(avalue),longword(finfo.options), + longword([dto_alignstart,dto_aligncenter,dto_alignend]))); + {$else} + setsinglebit(byte(avalue),byte(finfo.options),byte(mask1))); + {$endif} + changed; + end; +end; + +function tdialtick.getintervalcount: real; +begin + if (finfo.intervalco <> 0) or + (do_log in tcustomdialcontroller(fowner).foptions) then begin + result:= finfo.intervalco; + end + else begin + if finfo.interval <> 0 then begin + result:= tcustomdialcontroller(fowner).range/finfo.interval; + if result > 1000 then begin + result:= 1000; + end; + end + else begin + result:= 0; + end; + end; +end; + +procedure tdialtick.setintervalcount(const avalue: real); +begin + if finfo.intervalco <> avalue then begin + finfo.intervalco:= avalue; + if not (do_log in tcustomdialcontroller(fowner).foptions) then begin + finfo.interval:= 0; + end; + changed; + end; +end; + +function tdialtick.getinterval: real; +begin + if (finfo.interval <> 0) or + (do_log in tcustomdialcontroller(fowner).foptions) then begin + result:= finfo.interval; + end + else begin + if finfo.intervalco <> 0 then begin + result:= tcustomdialcontroller(fowner).range/finfo.intervalco; + end + else begin + result:= 0; + end; + end; +end; + +procedure tdialtick.setinterval(const avalue: real); +begin + if avalue <> finfo.interval then begin + finfo.interval:= avalue; + if not (do_log in tcustomdialcontroller(fowner).foptions) then begin + finfo.intervalco:= 0; + end; + changed; + end; +end; + +function tdialtick.isintervalcountstored: boolean; +begin + result:= (do_log in tcustomdialcontroller(fowner).foptions) or + (finfo.intervalco <> 0); +end; + +function tdialtick.isintervalstored: boolean; +begin + result:= (do_log in tcustomdialcontroller(fowner).foptions) or + (finfo.interval <> 0); +end; + +function tdialtick.getvisible: boolean; +begin + result:= not (dto_invisible in finfo.options); +end; + +procedure tdialtick.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [dto_invisible]; + end + else begin + options:= options + [dto_invisible]; + end; +end; + +{ tdialticks } + +constructor tdialticks.create(const aowner: tcustomdialcontroller); +begin + inherited create(aowner,tdialtick); +end; + +class function tdialticks.getitemclasstype: persistentclassty; +begin + result:= tdialtick; +end; + +function tdialticks.getitems(const aindex: integer): tdialtick; +begin + result:= tdialtick(inherited items[aindex]); +end; + +procedure tdialticks.change(const index: integer); +begin + inherited; + if not (aps_destroying in fstate) then begin + tcustomdialcontroller(fowner).changed; + end; +end; + +procedure tdialticks.createitem(const index: integer; var item: tpersistent); +begin + inherited; + if do_log in tcustomdialcontroller(fowner).foptions then begin + tdialtick(item).interval:= 10; + end; +end; + +procedure tdialticks.changed; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tdialtick(fitems[int1]).flayoutvalid:= false; + end; +end; + +{ tcustomdialcontroller } + +constructor tcustomdialcontroller.create(const aintf: idialcontroller); +begin + fintf:= aintf; + fcolor:= defaultdialcolor; + fwidthmm:= 0.3; + frange:= 1.0; + fmarkers:= tdialmarkers.create(self); + fticks:= tdialticks.create(self); +end; + +destructor tcustomdialcontroller.destroy; +begin + fmarkers.free; + fticks.free; + ffont.free; + inherited; +end; + +procedure tcustomdialcontroller.setdirection(const avalue: graphicdirectionty); +var + dir1,dir2: graphicdirectionty; + int1: integer; +begin + if avalue <> fdirection then begin + dir1:= fdirection; + fdirection:= avalue; + if fdirection >= gd_none then begin + fdirection:= pred(fdirection); + end; + dir2:= fdirection; + changed; + if fintf.getwidget.componentstate * + [csreading,csdesigning] = [csdesigning] then begin + with fmarkers do begin + for int1:= 0 to high(fitems) do begin + with tdialmarker(fitems[int1]) do begin + if finfo.bar_frame <> nil then begin + finfo.bar_frame.changedirection(dir1,dir2); + end; + if finfo.bar_face <> nil then begin + finfo.bar_face.fade_direction:= rotatedirection( + finfo.bar_face.fade_direction,dir1,dir2); + end; + end; + end; + end; + end; + fintf.directionchanged(dir2,dir1); + end; +end; + +procedure tcustomdialcontroller.layoutchanged; +begin + fintf.layoutchanged; + exclude(fstate,dis_layoutvalid); +end; + +procedure tcustomdialcontroller.changed; +begin + fmarkers.changed; + fticks.changed; + layoutchanged; +end; + +procedure tcustomdialcontroller.calclineend(const ainfo: diallineinfoty; + const aopposite: boolean; + const arect: rectty; out linestart,lineend: integer; + out linedirection: graphicdirectionty; + out adim: rectextty); +var +// int1: integer; + bo1: boolean; +begin + linestart:= 0; + bo1:= (do_opposite in foptions) xor aopposite; + linedirection:= fdirection; + if bo1 then begin + linedirection:= graphicdirectionty((ord(fdirection)+2) and $3); + end; + with ainfo do begin + case linedirection of + gd_right: begin + linestart:= arect.y + arect.cy - indent {- 1}; + if length = 0 then begin + lineend:= linestart - arect.cy + indent; + end + else begin + lineend:= linestart - length; + end; + end; + gd_up: begin + linestart:= arect.x + arect.cx - indent {- 1}; + if length = 0 then begin + lineend:= linestart - arect.cx + indent; + end + else begin + lineend:= linestart - length; + end; + end; + gd_left: begin + linestart:= arect.y + indent; + if length = 0 then begin + lineend:= linestart + arect.cy - indent; + end + else begin + lineend:= linestart + length; + end; + end; + gd_down: begin + linestart:= arect.x + indent; + if length = 0 then begin + lineend:= linestart + arect.cx - indent; + end + else begin + lineend:= linestart + length; + end; + end; + end; + if linedirection in [gd_up,gd_down] then begin + adim.left:= linestart; + adim.right:= linestart; + adim.top:= arect.y; + adim.bottom:= arect.y + arect.cy; + end + else begin + adim.top:= linestart; + adim.bottom:= linestart; + adim.left:= arect.x; + adim.right:= arect.x + arect.cx; + end; + end; +end; + +procedure tcustomdialcontroller.transform(var apoint: pointty); + procedure trans(var pxy,ryx: integer); + var + r1: real; + p1: real; + begin + r1:= fr - ryx + foffsr; + p1:= fa*((pxy-foffsp)*fscalep); + pxy:= round(r1*sin(p1)) + foffsp; + ryx:= round(r1*(1-cos(p1))) + ryx; + end; +begin + if dis_needstransform in fstate then begin + case fdirection of + gd_left: begin + apoint.y:= fendr - apoint.y; + trans(apoint.x,apoint.y); + apoint.y:= fendr - apoint.y + end; + gd_down: begin + apoint.x:= fendr - apoint.x; + trans(apoint.y,apoint.x); + apoint.x:= fendr - apoint.x + end; + gd_up: begin + trans(apoint.y,apoint.x); + end; + else begin //gd_right + trans(apoint.x,apoint.y); + end; + end; + end; +end; + +procedure tcustomdialcontroller.adjustcaption(const dir: graphicdirectionty; + const arotatetext: boolean; const ainfo: diallineinfoty; + const afont: tfont; const stringwidth: integer; var pos: pointty); + + function adjustscale(const avalue: integer): real; + begin + if fangle = 0 then begin + result:= 1; + end + else begin + if fdirection in [gd_left,gd_down] then begin + result:= fendr - avalue; + end + else begin + result:= avalue; + end; + result:= fr - result + foffsr; + if result = 0 then begin + result:= 1; + end + else begin + result:= farcscale/result; + end; + end; + end; + +begin + with ainfo,pos do begin + case dir of + gd_right: begin + y:= y + captiondist; + x:= x + captionoffset; + if not arotatetext then begin + transform(pos); + end; + if escapement = 0 then begin + y:= y + afont.ascent; + x:= x - round((stringwidth div 2)*adjustscale(y)); + end; + end; + gd_down: begin + x:= x - captiondist; + y:= y + captionoffset; + if not arotatetext then begin + transform(pos); + end; + if escapement = 0 then begin + x:= x - stringwidth; + y:= y + round((afont.ascent - afont.glyphheight div 2)*adjustscale(x)); + end; + end; + gd_left: begin + y:= y - captiondist; + x:= x + captionoffset; + if not arotatetext then begin + transform(pos); + end; + if escapement = 0 then begin + y:= y - afont.descent; + x:= x - round((stringwidth div 2)*adjustscale(y)); + end; + end; + gd_up: begin + x:= x + captiondist; + y:= y + captionoffset; + if not arotatetext then begin + transform(pos); + end; + if escapement = 0 then begin + y:= y + round((afont.ascent - afont.glyphheight div 2)*adjustscale(x)); + end; + end; + end; + end; + if arotatetext then begin + transform(pos); + end; +end; + +procedure tcustomdialcontroller.checklayout; + +const + tolerance = 0.000001; + + function getico(const interval: real; const intervalcount: integer): integer; + begin + result:= intervalcount - + floor((1/interval) * intervalcount * (1 + tolerance)); + //ticks below decade + end; + + function getlogval(const avalue: integer; const interval: real; + const intervalcount: integer): real; + var + ico: integer; + int1: integer; + begin + ico:= getico(interval,intervalcount); + if ico = 0 then begin + result:= 0; + end + else begin + result:= power(interval,avalue div ico); + int1:= avalue mod ico; + if int1 <> 0 then begin + if int1 < 0 then begin + int1:= int1+ico; + result:= result * ((int1+intervalcount-ico)/intervalcount); + end + else begin + result:= result * interval * ((int1+intervalcount-ico)/intervalcount); + end; + end; + end; + end; + + function getlogn(const avalue: real; const interval: real; + const intervalcount: integer): integer; + var + rea1{,rea2}: real; + ico: integer; + begin + if avalue > 0 then begin + result:= floor(logn(interval,avalue) + tolerance); + rea1:= intpower(interval,result+1); + ico:= getico(interval,intervalcount); + result:= floor(result * ico + (avalue/rea1)*intervalcount+tolerance) - + intervalcount + ico; + end + else begin + result:= 0; + end; + end; + +var + asc,desc: integer; + +var + rect1: rectty; + canvas1: tcanvas; + linestart,lineend: integer; + step: real; + offs: real; + first: real; + valstep: real; + int1,int2,int3,int4: integer; + dir1: graphicdirectionty; + boxlines: array[0..1] of segmentty; + bo1: boolean; + rea1,rea2,rea3: real; + po1,po2: prectty; + po3: psegmentty; + horz1: boolean; + islog: boolean; + logstartn,intervalcount1: integer; + ar1: realarty; + ar2: booleanarty; + pt1: pointty; + rectext1: rectextty; + +begin + if not (dis_layoutvalid in fstate) then begin + intervalcount1:= 0; + logstartn:= 0; + first:= 0; + valstep:= 0; + ar1:= nil; + rea1:= 0; + canvas1:= fintf.getwidget.getcanvas; + bo1:= getactdialrect(rect1); + exclude(fstate,dis_needstransform); + fsidearc:= nullrect; + fboxarc:= nullrect; + farcscale:= 1; + horz1:= fdirection in [gd_right,gd_left]; + if fangle <> 0 then begin + if bo1 then begin + int2:= findent1; + end + else begin + int2:= findent2; + end; + with rect1 do begin + fa:= pi*fangle; //0.5 * angle in radiant + if fangle < 0.5 then begin + int1:= round(sin(fa)*int2); + end + else begin + int1:= int2; + end; + if horz1 then begin + x:= x + int1; + cx:= cx - 2 * int1; + foffsr:= y; + int1:= cx; + foffsp:= int1 div 2 + x; + if fdirection = gd_left then begin + fendr:= 2*foffsr + cy; + end; + end + else begin + y:= y + int1; + cy:= cy - 2 * int1; + foffsr:= x; + int1:= cy; + foffsp:= int1 div 2 + y; + if fdirection = gd_down then begin + fendr:= 2*foffsr + cx; + end; + end; + end; + if int1 > 0 then begin + include(fstate,dis_needstransform); + fscalep:= 2.0/int1; + fr:= int1/2.0; + if fangle < 0.5 then begin + fr:= fr/sin(fa); + end; + farcscale:= int1/(fa*2); + end; + int1:= round(abs(fr)); //radius to direction + if int1 < 30000 then begin + int2:= round(2*abs(fr)); //diameter + int3:= 0; //perpendicular to direction + if (fangle < 0) xor (direction in [gd_down,gd_left]) then begin + int3:= -int2; + end; + if (do_opposite in foptions) then begin + po1:= @fsidearc; + po2:= @fboxarc; + end + else begin + po1:= @fboxarc; + po2:= @fsidearc; + end; + case direction of + gd_right: begin + with po1^ do begin //normal circle + x:= foffsp - int1; + cx:= int2; + y:= foffsr + int3; + cy:= cx; + end; + with po2^ do begin //small/big circle + if fangle < 0 then begin + rea1:= 0.5+1; + x:= foffsp - int1 - rect1.cy; + cy:= int2 + rect1.cy + rect1.cy; + y:= foffsr + int3 - rect1.cy; + end + else begin + rea1:= 0.5; + x:= foffsp - int1 + rect1.cy; + cy:= int2 - rect1.cy - rect1.cy; + y:= foffsr + int3 + rect1.cy; + end; + cx:= cy; + end; + end; + gd_up: begin + with po1^ do begin //normal circle + y:= foffsp - int1; + cx:= int2; + x:= foffsr + int3; + cy:= cx; + end; + with po2^ do begin //small/big circle + if fangle < 0 then begin + rea1:= 0; + y:= foffsp - int1 - rect1.cx; + cx:= int2 + rect1.cx + rect1.cx; + x:= foffsr + int3 - rect1.cx; + end + else begin + rea1:= 1; + y:= foffsp - int1 + rect1.cx; + cx:= int2 - rect1.cx - rect1.cx; + x:= foffsr + int3 + rect1.cx; + end; + cy:= cx; + end; + end; + gd_left: begin + with po1^ do begin //normal circle + x:= foffsp - int1; + cx:= int2; + y:= foffsr + int3 + rect1.cy; + cy:= cx; + end; + with po2^ do begin //small/big circle + if fangle < 0 then begin + rea1:= 0.5; + x:= foffsp - int1 - rect1.cy; + cy:= int2 + rect1.cy + rect1.cy; + y:= foffsr + int3; + end + else begin + rea1:= -0.5; + x:= foffsp - int1 + rect1.cy; + cy:= int2 - rect1.cy - rect1.cy; + y:= foffsr + int3 + rect1.cy + rect1.cy; + end; + cx:= cy; + end; + end; + gd_down: begin + with po1^ do begin //normal circle + y:= foffsp - int1; + cy:= int2; + x:= foffsr + int3 + rect1.cx; + cx:= cy; + end; + with po2^ do begin //small/big circle + if fangle < 0 then begin + rea1:= 1; + y:= foffsp - int1 - rect1.cx; + cx:= int2 + rect1.cx + rect1.cx; + x:= foffsr + int3; + end + else begin + rea1:= 0; + y:= foffsp - int1 + rect1.cx; + cx:= int2 - rect1.cx - rect1.cx; + x:= foffsr + int3 + rect1.cx + rect1.cx; + end; + cy:= cx; + end; + end; + end; + fstartang:= pi*(rea1-fangle); + farcang:= 2*pi*fangle; + end; + end; + + with rect1 do begin + if horz1 then begin + boxlines[0].a.x:= x; + boxlines[0].b.x:= x + cx; + boxlines[1].a.x:= boxlines[0].a.x; + boxlines[1].b.x:= boxlines[0].b.x; + + boxlines[0].a.y:= y + cy; + boxlines[0].b.y:= boxlines[0].a.y; + boxlines[1].a.y:= y; + boxlines[1].b.y:= y; + end + else begin + boxlines[0].a.y:= y; + boxlines[0].b.y:= y + cy; + boxlines[1].a.y:= boxlines[0].a.y; + boxlines[1].b.y:= boxlines[0].b.y; + + boxlines[0].a.x:= x + cx; + boxlines[0].b.x:= boxlines[0].a.x; + boxlines[1].a.x:= x; + boxlines[1].b.x:= x; + end; + end; + if do_sideline in foptions then begin + setlength(fboxlines,1); + if bo1 then begin + fboxlines[0]:= boxlines[1]; + end + else begin + fboxlines[0]:= boxlines[0]; + end; + end + else begin + fboxlines:= nil; + end; + if do_boxline in foptions then begin + setlength(fboxlines,high(fboxlines)+2); + if bo1 then begin + fboxlines[high(fboxlines)]:= boxlines[0]; + end + else begin + fboxlines[high(fboxlines)]:= boxlines[1]; + end; + end; + islog:= do_log in foptions; + fticks.fdim:= emptyrectext; + for int4:= 0 to high(fticks.fitems) do begin + with tdialtick(fticks.fitems[int4]) do begin + finfo.afont:= font; + asc:= font.ascent; + desc:= font.descent; + linestart:= 0; //compiler warning + lineend:= 0; //compiler warning + with finfo,fli do begin + if intervalcount <= 0 then begin + ticks:= nil; + end + else begin + calclineend(fli,dto_opposite in options,rect1,linestart,lineend, + dir1,rectext1); + expandrectext1(fticks.fdim,rectext1); + if islog then begin + offs:= -flnsstart; + rea1:= flnrange; + if rea1 = 0 then begin + exit; + end; + step:= 1/rea1; //used for scaling + offs:= offs * step; + intervalcount1:= round(intervalcount); + if interval <= 0 then begin + interval:= 10; + end; + logstartn:= getlogn(fsstart,interval,intervalcount1); + rea1:= getlogval(logstartn,interval,intervalcount1); + if fsstart <> 0 then begin + if (fsstart-rea1)/fsstart > tolerance then begin + inc(logstartn); + end; + end; + rea1:= fsstart + frange; + int1:= getlogn(rea1,interval,intervalcount1); + int1:= int1 - logstartn; + end + else begin + step:= 1/intervalcount; + valstep:= step * frange; + first:= (fsstart*intervalcount)/range; + offs:= frac(first)/intervalcount; //scaled to 1.0 + first:= int(first); + if offs > 0.0001 then begin + offs:= offs - 1.0/intervalcount; + first:= first + 1; + end; + offs:= -offs; + int1:= trunc((1.0001-offs)*intervalcount); + first:= (first * frange) / intervalcount; //real value + end; + inc(int1); + if int1 < 0 then begin + int1:= 0; + end; + system.setlength(ticks,int1); + system.setlength(ticksreal,int1); + if islog then begin + system.setlength(ar1,int1); + end; + if horz1 then begin + step:= rect1.cx * step; + offs:= rect1.cx * offs; + if fdirection = gd_left then begin + step:= - step; + offs:= rect1.cx - offs{ + 1}; + end; + for int1:= 0 to high(ticks) do begin + with ticks[int1] do begin + if islog then begin + ar1[int1]:= getlogval(int1 + logstartn,interval,intervalcount1); + ticksreal[int1]:= chartln(ar1[int1])*step + offs; + end + else begin + ticksreal[int1]:= int1*step + offs; + end; + a.x:= rect1.x + round(ticksreal[int1]); + b.x:= a.x; + a.y:= linestart; + b.y:= lineend; + end; + end; + end + else begin + step:= rect1.cy * step; + offs:= rect1.cy * offs; + if fdirection = gd_up{gd_up} then begin + step:= - step; + offs:= rect1.cy - offs {+ 1}; + end; + for int1:= 0 to high(ticks) do begin + with ticks[int1] do begin + if islog then begin + ar1[int1]:= getlogval(int1 + logstartn,interval,intervalcount1); + ticksreal[int1]:= chartln(ar1[int1]) * step + offs; + end + else begin + ticksreal[int1]:= int1*step + offs; + end; + a.y:= rect1.y + round(ticksreal[int1]); + b.y:= a.y; + a.x:= linestart; + b.x:= lineend; + end; + end; + end; + ar2:= nil; + system.setlength(ar2,system.length(ticks)); + bo1:= not (dto_multiplecaptions in options); + for int1:= 0 to high(ticks) do begin //snap to existing ticks + po3:= nil; + rea1:= ticksreal[int1]; + for int2:= int4-1 downto 0 do begin + with tdialtick(fticks.fitems[int2]).finfo do begin + for int3:= 0 to high(ticks) do begin + if abs(rea1-ticksreal[int3]) < 0.1 then begin + po3:= @ticks[int3]; + ar2[int1]:= bo1 and (captions <> nil); + break; + end; + end; + end; + if (po3 <> nil) and (not bo1 or ar2[int1]) then begin + //else check more captions + break; + end; + end; + if po3 <> nil then begin + if horz1 then begin + with ticks[int1] do begin + a.x:= po3^.a.x; + b.x:= a.x; + end; + end + else begin + with ticks[int1] do begin + a.y:= po3^.a.y; + b.y:= a.y; + end; + end; + end; + end; + if (caption = '') and (captionunit = '') then begin + captions:= nil; + end + else begin + system.setlength(captions,system.length(ticks)); + rea3:= 0; //offset + rea2:= 0; //scale + if dto_rotatetext in options then begin + rea3:= angle*pi; //offset + if horz1 then begin + if rect1.cx <> 0 then begin + rea2:= -angle*2*pi/rect1.cx; + if direction = gd_left then begin + rea2:= -rea2; + rea3:= -rea3; + end; + end; + end + else begin + if rect1.cy <> 0 then begin + rea2:= -angle*2*pi/rect1.cy; + if direction = gd_up then begin + rea2:= -rea2; + rea3:= -rea3; + end; + end; + end; + end; + rea3:= rea3+escapement * 2 * pi; + int2:= -bigint; + bo1:= direction in [gd_left,gd_right]; + for int1:= 0 to high(captions) do begin + if islog then begin + rea1:= ar1[int1]; + end + else begin + rea1:= int1*valstep+first; + if abs(rea1/valstep) < 1e-6 then begin + rea1:= 0; + end; + end; + if ar2[int1] then begin + captions[int1].caption:= ''; + end + else begin + if (captionunit <> '') and (int1 = high(captions) - 1) and + (int1 > 0) then begin + captions[int1].caption:= captionunit; + end + else begin + captions[int1].caption:= getactcaption(rea1,caption); + end; + end; + with captions[int1] do begin + pos:= ticks[int1].a; + width:= canvas1.getstringwidth(caption,afont); + if width > int2 then begin + int2:= width; + end; + adjustcaption(dir1,dto_rotatetext in options,fli,afont, + width,pos); + if bo1 then begin + if dto_alignstart in options then begin + pos.x:= pos.x + width div 2; + end + else begin + if dto_alignend in options then begin + pos.x:= pos.x - width div 2; + end; + end; + end; + angle:= ticksreal[int1] * rea2 + rea3; + extenddim(width,asc,desc,pos,fticks.fdim); + end; + end; + if options * [dto_alignstart,dto_aligncenter,dto_alignend] <> [] then begin + if dto_aligncenter in options then begin + case direction of + gd_up,gd_down: begin + if (dto_opposite in options) xor opposite then begin + for int1:= 0 to high(captions) do begin + with captions[int1] do begin + pos.x:= pos.x - (int2-width) div 2; + end; + end; + end + else begin + for int1:= 0 to high(captions) do begin + with captions[int1] do begin + pos.x:= pos.x + (int2-width) div 2; + end; + end; + end; + end; + end; + end + else begin + if dto_alignend in options then begin + case direction of + gd_up,gd_down: begin + if (dto_opposite in options) xor opposite then begin + for int1:= 0 to high(captions) do begin + with captions[int1] do begin + pos.x:= pos.x - (int2-width); + end; + end; + end + else begin + for int1:= 0 to high(captions) do begin + with captions[int1] do begin + pos.x:= pos.x + (int2-width); + end; + end; + end; + end; + end; + end + else begin + if dto_alignstart in options then begin + end; + end; + end; + end; + //todo: variable unitcaption pos. + end; + end; + end; + end; + end; + if dis_needstransform in fstate then begin + for int4:= 0 to high(fticks.fitems) do begin + with tdialtick(fticks.fitems[int4]).finfo do begin + for int1:= 0 to high(ticks) do begin + with ticks[int1] do begin + transform(a); + transform(b); + end; + end; + end; + end; + end; + for int4:= 0 to high(fticks.fitems) do begin + with tdialtick(fticks.fitems[int4]).finfo do begin + if dto_opposite in options then begin + for int1:= 0 to high(ticks) do begin + with ticks[int1] do begin + pt1:= a; + a:= b; + b:= pt1; + end; + end; + end; + end; + end; + with fmarkers do begin + fdim:= emptyrectext; + for int1:= 0 to count - 1 do begin + with tdialmarker(fitems[int1]) do begin + flayoutvalid:= false; + checklayout; + end; + end; + end; + include(fstate,dis_layoutvalid); + end; +end; + +procedure tcustomdialcontroller.invalidate; +begin + fintf.getwidget.invalidate; +end; + +procedure tcustomdialcontroller.paintdial(const acanvas: tcanvas); +var + int1,int2: integer; +begin + fmarkers.paint1(acanvas); + if visible then begin + if (do_smooth in options) and (angle <> 0) then begin + acanvas.smooth:= true; + end; + for int1:= high(fticks.fitems) downto 0 do begin + with tdialtick(fticks.fitems[int1]),finfo do begin + if visible then begin + if ticks <> nil then begin + acanvas.linewidthmm:= actualwidthmm; + if dashes <> '' then begin + acanvas.dashes:= dashes; + end; + acanvas.drawlinesegments(ticks,actualcolor); + if dashes <> '' then begin + acanvas.dashes:= ''; + end; + end; + for int2:= 0 to high(captions) do begin + with captions[int2] do begin + acanvas.drawstring(caption,pos,afont,false,angle); + end; + end; + end; + end; + end; + end; + fmarkers.paint2(acanvas); + acanvas.linewidth:= 0; + acanvas.smooth:= false; +end; + +procedure tcustomdialcontroller.paint(const acanvas: tcanvas); +begin + checklayout; + if not (do_front in foptions) then begin + paintdial(acanvas); + end; +end; + +procedure tcustomdialcontroller.afterpaint(const acanvas: tcanvas); +begin + if do_front in foptions then begin + paintdial(acanvas); + end; + if foptions * [do_sideline,do_boxline] <> [] then begin + acanvas.capstyle:= cs_projecting; + acanvas.linewidthmm:= fwidthmm; + if fboxarc.cx <> 0 then begin + if do_smooth in options then begin + acanvas.smooth:= true; + end; + if fangle = 1 then begin + if do_boxline in foptions then begin + acanvas.drawellipse1(fboxarc,fcolor); + end; + if do_sideline in foptions then begin + acanvas.drawellipse1(fsidearc,fcolor); + end; + end + else begin + if do_boxline in foptions then begin + acanvas.drawarc1(fboxarc,fstartang,farcang,fcolor); + end; + if do_sideline in foptions then begin + acanvas.drawarc1(fsidearc,fstartang,farcang,fcolor); + end; + end; + acanvas.smooth:= false; + end + else begin + acanvas.drawlinesegments(fboxlines,fcolor); + end; + acanvas.capstyle:= cs_butt; + acanvas.linewidth:= 0; + end; +end; + +procedure tcustomdialcontroller.setstart(const avalue: real); +begin + if fstart <> avalue then begin + fstart:= avalue; + fsstart:= fshift+avalue; + flnsstart:= chartln(fsstart); + flnrange:= chartln(fsstart+frange)-flnsstart; + changed; + end; +end; + +procedure tcustomdialcontroller.setshift(const avalue: real); +begin + if fshift <> avalue then begin + fshift:= avalue; + fsstart:= fstart+avalue; + flnsstart:= chartln(fsstart); + flnrange:= chartln(fsstart+frange)-flnsstart; + changed; + end; +end; + +procedure tcustomdialcontroller.setrange(const avalue: real); +begin + if frange <> avalue then begin + checknullrange(avalue); + frange:= avalue; + flnrange:= chartln(fsstart+frange)-flnsstart; + changed; + end; +end; + +procedure tcustomdialcontroller.setkind(const avalue: dialdatakindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + changed; + end; +end; + +procedure tcustomdialcontroller.setmarkers(const avalue: tdialmarkers); +begin + fmarkers.assign(avalue); +end; + +procedure tcustomdialcontroller.setoptions(const avalue: dialoptionsty); +const + mask: dialoptionsty = [do_scrollwithdata,do_shiftwithdata]; +begin + if foptions <> avalue then begin + foptions:= dialoptionsty( + setsinglebit({$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(foptions), + {$ifdef FPC}longword{$else}word{$endif}(mask))); + changed; + end; +end; + +procedure tcustomdialcontroller.setticks(const avalue: tdialticks); +begin + fticks.assign(avalue); +end; + +function tcustomdialcontroller.getfont: tdialfont; +begin + getoptionalobject(fintf.getwidget.componentstate, + ffont,{$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin +{$warnings off} + result:= tdialfont(twidget1(fintf.getwidget).getfont); +{$warnings on} + end; +end; + +procedure tcustomdialcontroller.setfont(const avalue: tdialfont); +begin + if avalue <> ffont then begin + setoptionalobject(fintf.getwidget.componentstate, + avalue,ffont,{$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function tcustomdialcontroller.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +procedure tcustomdialcontroller.createfont; +begin + if ffont = nil then begin + ffont:= tdialfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +procedure tcustomdialcontroller.fontchanged(const sender: tobject); +begin + changed; +end; + +procedure tcustomdialcontroller.setcolor(const avalue: colorty); +begin + if avalue <> fcolor then begin + fcolor:= avalue; + fintf.getwidget.invalidate; + end; +end; + +procedure tcustomdialcontroller.setwidthmm(const avalue: real); +begin + fwidthmm:= avalue; + fintf.getwidget.invalidate; +// changed; +end; + +procedure tcustomdialcontroller.setangle(const avalue: real); +begin + fangle:= avalue; + changed; +end; + +procedure tcustomdialcontroller.setindent1(const avalue: integer); +begin + if findent1 <> avalue then begin + findent1:= avalue; + changed; + end; +end; + +procedure tcustomdialcontroller.setindent2(const avalue: integer); +begin + if findent2 <> avalue then begin + findent2:= avalue; + changed; + end; +end; + +procedure tcustomdialcontroller.setfitdist(const avalue: integer); +begin + if ffitdist <> avalue then begin + ffitdist:= avalue; + changed; + end; +end; + +procedure tcustomdialcontroller.readstart(reader: treader); +begin + start:= reader.readfloat; +end; + +procedure tcustomdialcontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('offset',{$ifdef FPC}@{$endif}readstart,nil,false); +end; + +function tcustomdialcontroller.getactdialrect(out arect: rectty): boolean; +var + int1,int2: integer; +begin + arect:= fintf.getdialrect; + result:= (fdirection in [gd_left,gd_down]) xor (do_opposite in foptions); + if result then begin + int1:= findent1; + int2:= findent2; + end + else begin + int2:= findent1; + int1:= findent2; + end; + with arect do begin + if fdirection in [gd_right,gd_left] then begin + y:= y + int1; + cy:= cy - int1 - int2; + end + else begin + x:= x + int1; + cx:= cx - int1 - int2; + end; + end; +end; + +function tcustomdialcontroller.getlog: boolean; +begin + result:= do_log in options; +end; + +procedure tcustomdialcontroller.setlog(const avalue: boolean); +begin + if avalue then begin + options:= options + [do_log]; + end + else begin + options:= options - [do_log]; + end; +end; + +function tcustomdialcontroller.getvisible: boolean; +begin + result:= not (do_invisible in foptions); +end; + +procedure tcustomdialcontroller.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [do_invisible]; + end + else begin + options:= options + [do_invisible]; + end; +end; + +function tcustomdialcontroller.getopposite: boolean; +begin + result:= do_opposite in foptions; +end; + +procedure tcustomdialcontroller.setopposite(const avalue: boolean); +begin + if avalue then begin + options:= options + [do_opposite]; + end + else begin + options:= options - [do_opposite]; + end; +end; + +function tcustomdialcontroller.getsideline: boolean; +begin + result:= do_sideline in foptions; +end; + +procedure tcustomdialcontroller.setsideline(const avalue: boolean); +begin + if avalue then begin + options:= options + [do_sideline]; + end + else begin + options:= options - [do_sideline]; + end; +end; + +function tcustomdialcontroller.getboxline: boolean; +begin + result:= do_boxline in foptions; +end; + +procedure tcustomdialcontroller.setboxline(const avalue: boolean); +begin + if avalue then begin + options:= options + [do_boxline]; + end + else begin + options:= options - [do_boxline]; + end; +end; + +function tcustomdialcontroller.getfront: boolean; +begin + result:= do_front in foptions; +end; + +procedure tcustomdialcontroller.setfront(const avalue: boolean); +begin + if avalue then begin + options:= options + [do_front]; + end + else begin + options:= options - [do_front]; + end; +end; + +{ tcustomdial } + +constructor tcustomdial.create(aowner: tcomponent); +begin + foptions:= defaultoptionsdial; + fdial:= tdialcontroller.create(idialcontroller(self)); + inherited; + size:= makesize(100,15); + color:= cl_transparent; + optionswidget:= defaultoptionswidgetnofocus; +end; + +destructor tcustomdial.destroy; +begin + fdial.free; + inherited; +end; + +procedure tcustomdial.setdial(const avalue: tdialcontroller); +begin + fdial.assign(avalue); +end; + +procedure tcustomdial.directionchanged(const dir,dirbefore: graphicdirectionty); +begin + if not (csloading in componentstate) then begin + if fframe <> nil then begin + rotateframe1(tcustomframe1(fframe).fi.innerframe,dirbefore,dir); + end; + rotateframe1(ffitframe,dirbefore,dir); + widgetrect:= changerectdirection(widgetrect,dirbefore,dir); + end; +end; + +function tcustomdial.getdialrect: rectty; +begin + result:= innerclientrect; + deflaterect1(result,ffitframe); +end; + +function tcustomdial.getlimitrect: rectty; +begin + result:= innerclientrect; +end; + +procedure tcustomdial.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + fdial.paint(acanvas); + fdial.afterpaint(acanvas); +end; + +procedure tcustomdial.paint(const acanvas: tcanvas); +begin + checklayout; + inherited; +end; + +procedure tcustomdial.clientrectchanged; +begin + invalidatelayout; + inherited; +end; + +procedure tcustomdial.invalidatelayout; +begin + if componentstate * [csloading,csdestroying] = [] then begin + exclude(fstate,dws_layoutvalid); + fdial.changed; + end; +end; + +procedure tcustomdial.layoutchanged; +begin + exclude(fstate,dws_layoutvalid); + invalidate; +end; + +procedure tcustomdial.setfitframe(const avalue: framety); +begin + ffitframe:= avalue; + invalidatelayout; +end; + +procedure tcustomdial.setfitframe_left(const avalue: integer); +begin + if ffitframe.left <> avalue then begin + ffitframe.left:= avalue; + invalidatelayout; + end; +end; + +procedure tcustomdial.setfitframe_top(const avalue: integer); +begin + if ffitframe.top <> avalue then begin + ffitframe.top:= avalue; + invalidatelayout; + end; +end; + +procedure tcustomdial.setfitframe_right(const avalue: integer); +begin + if ffitframe.right <> avalue then begin + ffitframe.right:= avalue; + invalidatelayout; + end; +end; + +procedure tcustomdial.setfitframe_bottom(const avalue: integer); +begin + if ffitframe.bottom <> avalue then begin + ffitframe.bottom:= avalue; + invalidatelayout; + end; +end; + +procedure tcustomdial.setoptions(const avalue: optionsdialty); +begin + if avalue <> foptions then begin + foptions:= avalue; + invalidatelayout; + end; +end; + +function tcustomdial.fit(const asides: rectsidesty = allrectsides): boolean; +var + ext1: rectextty; +// int1: integer; + fra1: framety; + rect1: rectty; + si1: sizety; +begin + result:= false; + si1:= clientsize; + rect1:= getdialrect; + ext1.topleft:= rect1.pos; + ext1.bottomright:= addpoint(rect1.pos,pointty(rect1.size)); + fra1:= ffitframe; + + with fdial do begin + checklayout; + expandrectext1(ext1,fticks.fdim); + expandrectext1(ext1,fmarkers.fdim); + end; + + if fframe <> nil then begin + inflaterectext1(ext1,tcustomframe1(fframe).fi.innerframe); + end; + + if rs_left in asides then begin + fra1.left:= fra1.left - ext1.left; + end; + if rs_top in asides then begin + fra1.top:= fra1.top - ext1.top; + end; + if rs_right in asides then begin + fra1.right:= fra1.right + (ext1.right - si1.cx); + end; + if rs_bottom in asides then begin + fra1.bottom:= fra1.bottom + (ext1.bottom - si1.cy); + end; + + if not frameisequal(fra1,ffitframe) then begin + result:= true; + fitframe:= fra1; + end; +end; + +function tcustomdial.checklayout: boolean; +begin + result:= false; + if not (dws_layoutvalid in fstate) then begin + if foptions * rectsidesmask <> [] then begin + result:= fit(rectsidesty(foptions*rectsidesmask)); + end; + end; + include(fstate,dws_layoutvalid); +end; + +{ tcustomdialcontrollers } + +constructor tcustomdialcontrollers.create(const aintf: idialcontroller); +begin + fintf:= aintf; + frange:= 1; + inherited create(getitemclass); +end; + +procedure tcustomdialcontrollers.createitem(const index: integer; + var item: tpersistent); +begin + item:= dialcontrollerclassty(fitemclasstype).create(fintf); + tcustomdialcontroller(item).start:= fstart; + tcustomdialcontroller(item).range:= frange; +end; + +function tcustomdialcontrollers.getitemclass: dialcontrollerclassty; +begin + result:= tcustomdialcontroller; +end; + +procedure tcustomdialcontrollers.setstart(const avalue: real); +var + int1: integer; +begin + fstart:= avalue; + for int1:= 0 to high(fitems) do begin + tcustomdialcontroller(fitems[int1]).start:= avalue; + end; +end; + +procedure tcustomdialcontrollers.setrange(const avalue: real); +var + int1: integer; +begin + frange:= avalue; + for int1:= 0 to high(fitems) do begin + tcustomdialcontroller(fitems[int1]).range:= avalue; + end; +end; + +procedure tcustomdialcontrollers.dostatread(const reader: tstatreader); +var + int1,int2: integer; + mstr1: msestring; +begin + for int1:= 0 to count - 1 do begin + mstr1:= inttostrmse(int1); + with tcustomdialcontroller(fitems[int1]) do begin + if do_savestate in foptions then begin + start:= reader.readreal('start'+mstr1,start); + range:= reader.readreal('range'+mstr1,range); + end; + mstr1:= 'marker'+mstr1+'_'; + for int2:= 0 to markers.count - 1 do begin + with markers[int2] do begin + if dmo_savevalue in options then begin + value:= reader.readreal(mstr1+inttostrmse(int2),value); + end; + end; + end; + end; + end; +end; + +procedure tcustomdialcontrollers.dostatwrite(const writer: tstatwriter); +var + int1,int2: integer; + mstr1: msestring; +begin + for int1:= 0 to count - 1 do begin + mstr1:= inttostrmse(int1); + with tcustomdialcontroller(fitems[int1]) do begin + if do_savestate in options then begin + writer.writereal('start'+mstr1,start); + writer.writereal('range'+mstr1,range); + end; + mstr1:= 'marker'+mstr1+'_'; + for int2:= 0 to markers.count - 1 do begin + with markers[int2] do begin + if dmo_savevalue in options then begin + writer.writereal(mstr1+inttostrmse(int2),value); + end; + end; + end; + end; + end; +end; + +procedure tcustomdialcontrollers.changed; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + with tcustomdialcontroller(fitems[int1]) do begin + changed; + end; + end; +end; + +{ tdialcontroller } + +constructor tdialcontroller.create(const aintf: idialcontroller); +begin + inherited; + options:= defaultdialcontrolleroptions; +end; + +{ tmarkerframe } + +constructor tmarkerframe.create(const aintf: iframe); +begin + inherited; + include(fstate,fs_nowidget); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msedispwidgets.pas b/mseide-msegui/lib/common/widgets/msedispwidgets.pas new file mode 100644 index 0000000..9528e88 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msedispwidgets.pas @@ -0,0 +1,1388 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedispwidgets; + +{$ifdef FPC} + {$mode objfpc}{$h+} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +uses + msegraphics,classes,mclasses,msegui,mseguiglob,msewidgets, + msedrawtext,msegraphutils,mseassistiveclient, + msemenus,msetypes,msestrings,mseformatstr,mseevent,mseclasses,mserichstring + {$ifdef mse_with_ifi} + ,mseificomp,mseifiglob,mseificompglob,typinfo,msedatalist + {$endif}; + +const + defaultdisptextflags = [tf_ycentered]; + defaultdispwidgetwidth = 100; + defaultdispwidgetheight = 20; + defaultdispwidgetoptions = (defaultoptionswidget - + [ow_mousefocus,ow_tabfocus,ow_arrowfocus]){ + + [ow_fontglyphheight]}; + + defaultdispwidgetoptions1 = defaultoptionswidget1 + [ow1_fontglyphheight]; + +type + + tdispframe = class(tcustomcaptionframe) + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: icaptionframe); + published + property options; + property levelo default -1; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property colorclient; + property caption; + property captiontextflags; + property captionpos; + property captiondist; +// property captiondistouter; +// property captionframecentered; + property captionoffset; +// property captionnoclip; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + dispwidgetoptionty = (dwo_hintclippedtext,dwo_nogray, + dwo_showlocal,dwo_showutc, + dwo_blank); + //dwo_blank has only effect if componentstate csreading + //or csdesigning are set + dispwidgetoptionsty = set of dispwidgetoptionty; + dispwidgetflagty = (dwf_textrectvalid,dwf_cleared); + dispwidgetflagsty = set of dispwidgetflagty; + + tdispwidget = class(tpublishedwidget{$ifdef mse_with_ifi},iifidatalink{$endif}) + private + finfo: drawtextinfoty; + ftext: msestring; + foptions: dispwidgetoptionsty; + ftextflags: textflagsty; +// ftextrectvalid: boolean; + fonchange: notifyeventty; + procedure updatetextflags; + procedure settextflags(const value: textflagsty); + procedure settext(const avalue: msestring); + protected + fflags: dispwidgetflagsty; +{$ifdef mse_with_ifi} + fifilink: tifilinkcomp; + function getdefaultifilink: iificlient; override; + //iifidatalink + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifilinkcomp); + function ifigriddata: tdatalist; + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue) virtual; + procedure setifivalue(const avalue) virtual; + procedure updatereadonlystate; +{$endif} + procedure invalidatetext; + procedure setoptions(const avalue: dispwidgetoptionsty); virtual; + procedure valuechanged(); virtual; + procedure formatchanged(); + function getvaluetext: msestring; virtual; abstract; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure clientrectchanged; override; + procedure getautopaintsize(var asize: sizety); override; + procedure fontchanged; override; + procedure internalcreateframe; override; + procedure doloaded; override; + procedure showhint(const aid: int32; var info: hintinfoty); override; + procedure enabledchanged; override; + function verticalfontheightdelta: boolean; override; + class function classskininfo: skininfoty; override; + //iassistiveclient + function getassistivetext(): msestring override; + function getassistiveflags(): assistiveflagsty override; + public + constructor create(aowner: tcomponent); override; + procedure initnewcomponent(const ascale: real); override; + procedure synctofontheight; override; + procedure clear; virtual; + procedure resetclear(); + property disptext: msestring read finfo.text.text; + published + property text: msestring read ftext write settext; + //overrides valuetext + property bounds_cx default defaultdispwidgetwidth; + property bounds_cy default defaultdispwidgetheight; + property font: twidgetfont read getfont write setfont stored isfontstored; + property textflags: textflagsty read ftextflags write settextflags + default defaultdisptextflags; + property optionswidget default defaultdispwidgetoptions; + property optionswidget1 default defaultdispwidgetoptions1; + property options: dispwidgetoptionsty read foptions + write setoptions default []; + property onchange: notifyeventty read fonchange write fonchange; + property onshowhint; + end; + + tbasestringdisp = class(tdispwidget) + private + {$ifdef mse_with_ifi} + function getifilink: tifistringlinkcomp; + procedure setifilink(const avalue: tifistringlinkcomp); + {$endif} + protected + published +{$ifdef mse_with_ifi} + property ifilink: tifistringlinkcomp read getifilink write setifilink; +{$endif} + end; + + tcustomstringdisp = class(tbasestringdisp) + private + fvalue: msestring; + fondatachange: updatestringeventty; + procedure setvalue(const Value: msestring); + protected + function getvaluetext: msestring; override; + procedure valuechanged; override; + public + procedure clear; override; + property value: msestring read fvalue write setvalue; + published + property ondatachange: updatestringeventty read fondatachange + write fondatachange; + end; + + tstringdisp = class(tcustomstringdisp) + published + property value; + end; + + tcustomrichstringdisp = class(tbasestringdisp,irichstringprop) + private +// fvalue: richstringty; + fondatachange: updaterichstringeventty; + procedure setvalue(const avalue: msestring); + function getrichvalue(): richstringty; + procedure setrichvalue(const avalue: richstringty); + procedure setformat(const avalue: formatinfoarty); + procedure readvalue(reader: treader); + procedure readrichvalue(reader: treader); + procedure writerichvalue(writer: twriter); + protected + function getvaluetext: msestring; override; + procedure valuechanged; override; + procedure defineproperties(filer: tfiler) override; + public + procedure clear; override; + property value: msestring read finfo.text.text write setvalue stored false; + property richvalue: richstringty read finfo.text write setrichvalue; + property formatvalue: formatinfoarty read finfo.text.format write setformat; + published + property ondatachange: updaterichstringeventty read fondatachange + write fondatachange; + end; + + trichstringdisp = class(tcustomrichstringdisp) + published + property value; + end; + + tbytestringdisp = class(tdispwidget) + private + fvalue: string; + fondatachange: updateansistringeventty; + fbase: numbasety; + procedure setvalue(const Value: string); + procedure setbase(const Value: numbasety); + protected + function getvaluetext: msestring; override; + procedure valuechanged; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + published + property value: string read fvalue write setvalue; + property ondatachange: updateansistringeventty read fondatachange + write fondatachange; + property base: numbasety read fbase write setbase default nb_hex; + end; + +const + defaultnumdisptextflags = defaultdisptextflags + [tf_right]; + +type + tnumdisp = class(tdispwidget) + protected + public + constructor create(aowner: tcomponent); override; + published + property textflags default defaultnumdisptextflags; + end; + + tcustomintegerdisp = class(tnumdisp) + private + fvalue: integer; + fondatachange: updateintegereventty; + fbase: numbasety; + fbitcount: integer; + procedure setvalue(const Value: integer); + procedure setbase(const Value: numbasety); + procedure setbitcount(const Value: integer); + {$ifdef mse_with_ifi} + function getifilink: tifiintegerlinkcomp; + procedure setifilink(const avalue: tifiintegerlinkcomp); + {$endif} + protected + function getvaluetext: msestring; override; + procedure valuechanged; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property value: integer read fvalue write setvalue default 0; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + property ondatachange: updateintegereventty read fondatachange + write fondatachange; +{$ifdef mse_with_ifi} + property ifilink: tifiintegerlinkcomp read getifilink write setifilink; +{$endif} + end; + + tintegerdisp = class(tcustomintegerdisp) + published + property value; + end; + + tcustomint64disp = class(tnumdisp) + private + fvalue: int64; + fondatachange: updateint64eventty; + fbase: numbasety; + fbitcount: integer; + procedure setvalue(const Value: int64); + procedure setbase(const Value: numbasety); + procedure setbitcount(const Value: integer); + {$ifdef mse_with_ifi} + function getifilink: tifiint64linkcomp; + procedure setifilink(const avalue: tifiint64linkcomp); + {$endif} + protected + function getvaluetext: msestring; override; + procedure valuechanged; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property value: int64 read fvalue write setvalue default 0; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 64; + property ondatachange: updateint64eventty read fondatachange + write fondatachange; +{$ifdef mse_with_ifi} + property ifilink: tifiint64linkcomp read getifilink write setifilink; +{$endif} + end; + + tint64disp = class(tcustomint64disp) + published + property value; + end; + + tcustomrealdisp = class(tnumdisp) + private + fvalue: realty; + fondatachange: updaterealeventty; + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + procedure setvalue(const avalue: realty); + procedure readvalue(reader: treader); +// procedure writevalue(writer: twriter); + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + procedure readvaluescale(reader: treader); + {$ifdef mse_with_ifi} + function getifilink: tifireallinkcomp; + procedure setifilink(const avalue: tifireallinkcomp); + {$endif} + protected + procedure valuechanged; override; + function getvaluetext: msestring; override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property value: realty read fvalue write setvalue {stored false}; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + property ondatachange: updaterealeventty read fondatachange + write fondatachange; +{$ifdef mse_with_ifi} + property ifilink: tifireallinkcomp read getifilink write setifilink; +{$endif} + end; + + trealdisp = class(tcustomrealdisp) + published + property value{stored false}; + end; + + tcustomdatetimedisp = class(tnumdisp) + private + fvalue: tdatetime; + fondatachange: updatedatetimeeventty; + fformat: msestring; + fkind: datetimekindty; + fconvert: dateconvertty; + procedure setvalue(const avalue: tdatetime); + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + procedure readvalue(reader: treader); +// procedure writevalue(writer: twriter); + {$ifdef mse_with_ifi} + function getifilink: tifidatetimelinkcomp; + procedure setifilink(const avalue: tifidatetimelinkcomp); + {$endif} + protected + procedure setoptions(const avalue: dispwidgetoptionsty); override; + procedure valuechanged; override; + function getvaluetext: msestring; override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property value: tdatetime read fvalue write setvalue; + published + property format: msestring read fformat write setformat; + property ondatachange: updatedatetimeeventty read fondatachange + write fondatachange; + property kind: datetimekindty read fkind write setkind default dtk_date; +{$ifdef mse_with_ifi} + property ifilink: tifidatetimelinkcomp read getifilink write setifilink; +{$endif} + end; + + tdatetimedisp = class(tcustomdatetimedisp) + published + property value{ stored false}; + end; + + tcustombooleandisp = class(tdispwidget) + private + fvalue: boolean; + fondatachange: updatebooleaneventty; + ftext_false: msestring; + ftext_true: msestring; + procedure setvalue(const Value: boolean); + procedure settext_false(const avalue: msestring); + procedure settext_true(const avalue: msestring); + protected + procedure valuechanged; override; + function getvaluetext: msestring; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property value: boolean read fvalue write setvalue default false; + published + property textflags default defaultdisptextflags + [tf_xcentered]; + property ondatachange: updatebooleaneventty read fondatachange + write fondatachange; + property text_false: msestring read ftext_false write settext_false; + property text_true: msestring read ftext_true write settext_true; + end; + + tbooleandisp = class(tcustombooleandisp) + published + property value; + end; + +implementation +uses + sysutils,msereal,math,msestreaming,msedate,msebits; + +{ tdispframe } + +constructor tdispframe.create(const aintf: icaptionframe); +begin + inherited; +// clientcolor:= cl_foreground; + fi.levelo:= -1; + inflateframe1(fi.innerframe,1); + internalupdatestate; +end; + +function tdispframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_noedit; + end; +end; + +{ tdispwidget } + +constructor tdispwidget.create(aowner: tcomponent); +begin + inherited; + foptionswidget:= defaultdispwidgetoptions; + foptionswidget1:= defaultdispwidgetoptions1; + fwidgetrect.cx:= defaultdispwidgetwidth; + fwidgetrect.cy:= defaultdispwidgetheight; + ftextflags:= defaultdisptextflags; + finfo.flags:= ftextflags; +end; + +class function tdispwidget.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_dispwidget; +end; + +function tdispwidget.getassistivetext(): msestring; +begin + result:= disptext; +end; + +function tdispwidget.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_dispwidget,asf_readonly]; +end; + +procedure tdispwidget.initnewcomponent(const ascale: real); +begin + inherited; + internalcreateframe; + fframe.scale(ascale); +// synctofontheight; +end; + +procedure tdispwidget.settextflags(const value: textflagsty); +begin + if ftextflags <> value then begin + ftextflags:= checktextflags(ftextflags,value); + updatetextflags; + invalidatetext; + end; +end; + +procedure tdispwidget.clientrectchanged; +begin + exclude(fflags,dwf_textrectvalid); + inherited; + finfo.dest:= innerclientrect; +end; + +procedure tdispwidget.getautopaintsize(var asize: sizety); +var + fram1: framety; +begin + if fframe = nil then begin + fram1:= nullframe; + end + else begin + fram1:= fframe.framei; + end; + if not (dwf_textrectvalid in fflags) then begin + if finfo.font = nil then begin + finfo.font:= getfont; + end; + msedrawtext.textrect(getcanvas,finfo); + include(fflags,dwf_textrectvalid); + end; + asize.cx:= finfo.res.size.cx + fram1.left + fram1.right; + asize.cy:= finfo.res.size.cy + fram1.top + fram1.bottom; +end; + +procedure tdispwidget.dopaintforeground(const canvas: tcanvas); +begin + inherited; + if not (dwf_cleared in fflags) or (ftext <> '') then begin + drawtext(canvas,finfo); + if finfo.text.text = '' then begin + finfo.res.cy:= finfo.font.glyphheight; + end; + end + else begin + finfo.res.cx:= 0; + finfo.res.cy:= finfo.font.glyphheight; + end; + include(fflags,dwf_textrectvalid); +end; + +procedure tdispwidget.fontchanged; +begin + finfo.font:= getfont; + invalidatetext; + inherited; +end; + +procedure tdispwidget.internalcreateframe; +begin + tdispframe.create(iscrollframe(self)); +end; + +procedure tdispwidget.settext(const avalue: msestring); +begin + exclude(fflags,dwf_cleared); + ftext:= avalue; + if avalue = '' then begin + finfo.text.text:= getvaluetext; + end + else begin + finfo.text.text:= avalue; + end; + invalidatetext; +end; + +procedure tdispwidget.valuechanged(); +begin + if not (dwo_blank in foptions) or + (componentstate*[csreading,csdesigning] = []) and + not (ws_loadedproc in widgetstate) then begin + exclude(fflags,dwf_cleared); + end; + if ftext = '' then begin + finfo.text.text:= getvaluetext; + invalidatetext; + end; +{$ifdef mse_with_ifi} + if not (ws_loadedproc in fwidgetstate) then begin + if fifiserverintf <> nil then begin + iifidataserver(fifiserverintf).valuechanged(iifidatalink(self)); + end; + end; +{$endif} + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; +end; + +{$ifdef mse_with_ifi} +function tdispwidget.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure tdispwidget.setifilink(const avalue: tifilinkcomp); +begin + mseificomp.setifilinkcomp(iifidatalink(self),avalue,fifilink); +end; + +function tdispwidget.ifigriddata: tdatalist; +begin + result:= nil; +end; + +procedure tdispwidget.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +function tdispwidget.getgriddata: tdatalist; +begin + result:= nil; +end; + +function tdispwidget.getvalueprop: ppropinfo; +begin + result:= getpropinfo(self,'value'); +end; + +procedure tdispwidget.getifivalue(var avalue); +begin + //dummy +end; + +procedure tdispwidget.setifivalue(const avalue); +begin + //dummy +end; + +procedure tdispwidget.updatereadonlystate; +begin + //dummy +end; + +{$endif} + +procedure tdispwidget.formatchanged; +begin + if ftext = '' then begin + finfo.text.text:= getvaluetext; + end; + invalidatetext; +end; + +procedure tdispwidget.doloaded; +begin + inherited; + valuechanged; +end; + +procedure tdispwidget.showhint(const aid: int32; var info: hintinfoty); +begin + if (dwo_hintclippedtext in foptions) and getshowhint and + textclipped(getcanvas,finfo) then begin + info.caption:= finfo.text.text; + end; + inherited; +end; + +function tdispwidget.verticalfontheightdelta: boolean; +begin + result:= tf_rotate90 in textflags; +end; + +procedure tdispwidget.synctofontheight; +begin + syncsinglelinefontheight; +end; + +procedure tdispwidget.updatetextflags; +begin + if not (csloading in componentstate) then begin + if isenabled or (dwo_nogray in foptions) then begin + finfo.flags:= ftextflags; + end + else begin + finfo.flags:= ftextflags + [tf_grayed]; + end; + end; +end; + +procedure tdispwidget.enabledchanged; +begin + inherited; + updatetextflags; + invalidate; +end; + +procedure tdispwidget.setoptions(const avalue: dispwidgetoptionsty); +begin + if (componentstate*[csreading,csdesigning] <> []) then begin + if dwo_blank in avalue then begin + if not (dwf_cleared in fflags) then begin + include(fflags,dwf_cleared); + invalidatetext(); + end; + end + else begin + if dwf_cleared in fflags then begin + exclude(fflags,dwf_cleared); + invalidatetext(); + end; + end; + end; + if foptions <> avalue then begin + foptions:= avalue-[dwo_showlocal,dwo_showutc]; + updatetextflags; + invalidatetext; + end; +end; + +procedure tdispwidget.invalidatetext; +begin + exclude(fflags,dwf_textrectvalid); + invalidate; + checkautosize; +end; + +procedure tdispwidget.clear; +begin + if not (dwf_cleared in fflags) then begin + include(fflags,dwf_cleared); + invalidatetext(); + end; +end; + +procedure tdispwidget.resetclear(); +begin + if dwf_cleared in fflags then begin + exclude(fflags,dwf_cleared); + if ftext = '' then begin + invalidatetext(); + end; + end; +end; + +{$ifdef mse_with_ifi} + +function tdispwidget.getdefaultifilink: iificlient; +begin + result:= iifidatalink(self); +end; + +function tbasestringdisp.getifilink: tifistringlinkcomp; +begin + result:= tifistringlinkcomp(fifilink); +end; + +procedure tbasestringdisp.setifilink(const avalue: tifistringlinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +{ tcustomstringdisp } + +function tcustomstringdisp.getvaluetext: msestring; +begin + result:= fvalue; +end; + +procedure tcustomstringdisp.setvalue(const Value: msestring); +begin + if (fvalue <> value) then begin + fvalue:= Value; + valuechanged(); + end + else begin + resetclear(); + end; +end; + +procedure tcustomstringdisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +procedure tcustomstringdisp.clear; +begin + value:= ''; + inherited; +end; + +{ tcustomrichstringdisp } + +procedure tcustomrichstringdisp.setvalue(const avalue: msestring); +begin +// if (fvalue <> value) or (finfo.text.format <> nil) then begin + finfo.text.text:= avalue; + finfo.text.format:= nil; + valuechanged(); +// end +// else begin +// resetclear(); +// end; +end; + +function tcustomrichstringdisp.getrichvalue(): richstringty; +begin + result:= finfo.text; +end; + +procedure tcustomrichstringdisp.setrichvalue(const avalue: richstringty); +begin + finfo.text:= avalue; + valuechanged; +end; + +procedure tcustomrichstringdisp.setformat(const avalue: formatinfoarty); +begin + finfo.text.format:= copy(avalue); + valuechanged(); +end; + +procedure tcustomrichstringdisp.readvalue(reader: treader); +begin + value:= reader.readunicodestring(); +end; + +procedure tcustomrichstringdisp.readrichvalue(reader: treader); +begin + richvalue:= readrichstring(reader); +end; + +procedure tcustomrichstringdisp.writerichvalue(writer: twriter); +begin + writerichstring(writer,finfo.text); +end; + +procedure tcustomrichstringdisp.defineproperties(filer: tfiler); +var + b1: boolean; +begin + inherited; + filer.defineproperty('value',@readvalue,nil,false); + if filer.ancestor <> nil then begin + b1:= isequalrichstring(tcustomrichstringdisp(filer.ancestor).finfo.text, + finfo.text); + end + else begin + b1:= not isemptyrichstring(finfo.text); + end; + filer.defineproperty('richvalue',@readrichvalue,@writerichvalue,b1); +end; + +function tcustomrichstringdisp.getvaluetext: msestring; +begin + result:= finfo.text.text; +end; + +procedure tcustomrichstringdisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,finfo.text); + end; + inherited; +end; + +procedure tcustomrichstringdisp.clear; +begin + richvalue:= emptyrichstring; + inherited; +end; + +{ tbytestringdisp } + +constructor tbytestringdisp.create(aowner: tcomponent); +begin + fbase:= nb_hex; + inherited; +end; + +function tbytestringdisp.getvaluetext: msestring; +begin + if length(fvalue) > 256 then begin + result:= msestring(bytestrtostr(copy(fvalue,1,256),fbase,' '))+'...'; + end + else begin + result:= msestring(bytestrtostr(fvalue,fbase,' ')); + end; +end; + +procedure tbytestringdisp.setbase(const Value: numbasety); +begin + if fbase <> value then begin + fbase:= Value; + formatchanged; + end; +end; + +procedure tbytestringdisp.setvalue(const Value: string); +begin + if fvalue <> value then begin + fvalue := Value; + valuechanged; + end + else begin + resetclear(); + end; +end; + +procedure tbytestringdisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +procedure tbytestringdisp.clear; +begin + value:= ''; + inherited; +end; + +{ tnumdisp } + +constructor tnumdisp.create(aowner: tcomponent); +begin + inherited; + ftextflags:= defaultnumdisptextflags; + finfo.flags:= ftextflags; +end; + +{ tcustomintegerdisp } + +constructor tcustomintegerdisp.create(aowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +{$ifdef mse_with_ifi} + +function tcustomintegerdisp.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure tcustomintegerdisp.setifilink(const avalue: tifiintegerlinkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +function tcustomintegerdisp.getvaluetext: msestring; +begin + result:= msestring(intvaluetostr(fvalue,fbase,fbitcount)); +end; + +procedure tcustomintegerdisp.setbase(const Value: numbasety); +begin + if fbase <> value then begin + fbase := Value; + formatchanged; + end; +end; + +procedure tcustomintegerdisp.setbitcount(const Value: integer); +begin + if fbitcount <> value then begin + fbitcount := Value; + formatchanged; + end; +end; + +procedure tcustomintegerdisp.setvalue(const Value: integer); +begin + if fvalue <> value then begin + fvalue := Value; + valuechanged(); + end + else begin + resetclear(); + end; +end; + +procedure tcustomintegerdisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +procedure tcustomintegerdisp.clear; +begin + value:= 0; + inherited; +end; + +{ tcustomint64disp } + +constructor tcustomint64disp.create(aowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 64; + inherited; +end; + +{$ifdef mse_with_ifi} + +function tcustomint64disp.getifilink: tifiint64linkcomp; +begin + result:= tifiint64linkcomp(fifilink); +end; + +procedure tcustomint64disp.setifilink(const avalue: tifiint64linkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +function tcustomint64disp.getvaluetext: msestring; +begin + result:= msestring(intvaluetostr(fvalue,fbase,fbitcount)); +end; + +procedure tcustomint64disp.setbase(const Value: numbasety); +begin + if fbase <> value then begin + fbase := Value; + formatchanged; + end; +end; + +procedure tcustomint64disp.setbitcount(const Value: integer); +begin + if fbitcount <> value then begin + fbitcount := Value; + formatchanged; + end; +end; + +procedure tcustomint64disp.setvalue(const Value: int64); +begin + if fvalue <> value then begin + fvalue := Value; + valuechanged; + end + else begin + resetclear(); + end; +end; + +procedure tcustomint64disp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +procedure tcustomint64disp.clear; +begin + value:= 0; + inherited; +end; + +{ tcustomrealdisp } + +constructor tcustomrealdisp.create(aowner: tcomponent); +begin + fvalue:= emptyreal; + fvaluerange:= 1; + inherited; +end; + +procedure tcustomrealdisp.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; +{ +procedure tcustomrealdisp.writevalue(writer: twriter); +begin + writerealty(writer,fvalue); +end; +} +procedure tcustomrealdisp.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tcustomrealdisp.defineproperties(filer: tfiler); +begin + inherited; + filer.DefineProperty('val',{$ifdef FPC}@{$endif}readvalue,nil,false); + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + +function tcustomrealdisp.getvaluetext: msestring; +begin + result:= realtytostrrange(fvalue,fformat,fvaluerange,fvaluestart); +end; + +procedure tcustomrealdisp.setvalue(const avalue: realty); +begin + if fvalue <> avalue then begin + fvalue := avalue; + valuechanged; + end + else begin + resetclear(); + end; +end; + +{$ifdef mse_with_ifi} + +function tcustomrealdisp.getifilink: tifireallinkcomp; +begin + result:= tifireallinkcomp(fifilink); +end; + +procedure tcustomrealdisp.setifilink(const avalue: tifireallinkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +procedure tcustomrealdisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,real(fvalue)); + end; + inherited; +end; + +procedure tcustomrealdisp.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tcustomrealdisp.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tcustomrealdisp.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +procedure tcustomrealdisp.clear; +begin + value:= emptyreal; + inherited; +end; + +{ tcustomdatetimedisp } + +constructor tcustomdatetimedisp.create(aowner: tcomponent); +begin + fvalue:= emptydatetime; + inherited; +end; + +procedure tcustomdatetimedisp.setvalue(const avalue: tdatetime); +begin + if fvalue <> avalue then begin + fvalue := avalue; + valuechanged; + end + else begin + resetclear(); + end; +end; + +procedure tcustomdatetimedisp.setformat(const avalue: msestring); +begin + fformat := avalue; + formatchanged; +end; + +{$ifdef mse_with_ifi} +function tcustomdatetimedisp.getifilink: tifidatetimelinkcomp; +begin + result:= tifidatetimelinkcomp(fifilink); +end; + +procedure tcustomdatetimedisp.setifilink(const avalue: tifidatetimelinkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +procedure tcustomdatetimedisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +function tcustomdatetimedisp.getvaluetext: msestring; +var + dt1: tdatetime; +begin + dt1:= fvalue; + checkdatereconvert(fconvert,dt1); + case fkind of + dtk_time: begin + result:= mseformatstr.timetostring(dt1,fformat); + end; + dtk_date: begin + result:= mseformatstr.datetostring(dt1,fformat); + end; + else begin + result:= mseformatstr.datetimetostring(dt1,fformat); + end; + end; +end; + +procedure tcustomdatetimedisp.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +procedure tcustomdatetimedisp.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; +{ +procedure tcustomdatetimedisp.writevalue(writer: twriter); +begin + writerealty(writer,fvalue); +end; +} +procedure tcustomdatetimedisp.defineproperties(filer: tfiler); +begin + inherited; + filer.DefineProperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); +end; + +procedure tcustomdatetimedisp.setoptions(const avalue: dispwidgetoptionsty); +{$ifndef FPC} +const + mask1: dispwidgetoptionsty = [dwo_showlocal,dwo_showutc]; +{$endif} +var + opt1: dispwidgetoptionsty; +begin + opt1:= foptions; + inherited; + foptions:= dispwidgetoptionsty( + {$ifdef FPC} + replacebits(setsinglebit(longword(avalue),longword(opt1), + longword([dwo_showlocal,dwo_showutc])), + longword(foptions), + longword([dwo_showlocal,dwo_showutc]))); + {$else} + replacebits(setsinglebit(byte(avalue),byte(opt1), + byte(mask1)),byte(foptions),byte(mask1))); + {$endif} + fconvert:= dc_none; + if dwo_showutc in foptions then begin + fconvert:= dc_tolocal; + end; + if dwo_showlocal in foptions then begin + fconvert:= dc_toutc; + end; + formatchanged; +end; + +procedure tcustomdatetimedisp.clear; +begin + value:= emptydatetime; + inherited; +end; + +{ tcustombooleandisp } + +constructor tcustombooleandisp.create(aowner: tcomponent); +begin + ftext_true:= 'T'; + ftext_false:= 'F'; + inherited; + finfo.flags:= finfo.flags + [tf_xcentered]; +end; + +function tcustombooleandisp.getvaluetext: msestring; +begin + if fvalue then begin + result:= ftext_true; + end + else begin + result:= ftext_false; + end; +end; + +procedure tcustombooleandisp.setvalue(const Value: boolean); +begin + if fvalue <> value then begin + fvalue := Value; + valuechanged; + end + else begin + resetclear(); + end; +end; + +procedure tcustombooleandisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +procedure tcustombooleandisp.settext_false(const avalue: msestring); +begin + ftext_false:= avalue; + formatchanged; +end; + +procedure tcustombooleandisp.settext_true(const avalue: msestring); +begin + ftext_true:= avalue; + formatchanged; +end; + +procedure tcustombooleandisp.clear; +begin + value:= false; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msedock.pas b/mseide-msegui/lib/common/widgets/msedock.pas new file mode 100644 index 0000000..53c3183 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msedock.pas @@ -0,0 +1,6027 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedock; + +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msewidgets,classes,mclasses,msedrag,msegui,msegraphutils,mseevent,mseclasses, + msegraphics,msestockobjects,mseglob,mseguiglob,msestat,msestatfile,msepointer, + msesplitter,msesimplewidgets,msetypes,msestrings,msebitmap,mseobjectpicker, + msetabsglob,msemenus,msedrawtext,mseshapes,msedragglob,mseinterfaces,msetabs; + +//todo: optimize + +const + defaultgripsize = 10; + defaultgripgrip = stb_none; + defaultgripcolor = cl_white; + defaultgripcoloractive = cl_activegrip; + defaultgrippos = cp_right; + defaultsplittersize = 3; + +type + optiondockty = (od_savepos,od_savezorder,od_savechildren, + od_canmove,od_cansize,od_canfloat,od_candock,od_acceptsdock, + od_dockparent,od_expandforfixsize, + od_splitvert,od_splithorz,od_tabed,od_proportional, + od_propsize,od_fixsize,od_top,od_background, + od_alignbegin,od_aligncenter,od_alignend, + od_nofit,od_banded,od_nosplitsize,od_nosplitmove, + od_lock,od_nolock,od_thumbtrack,od_captionhint,{od_buttonhints,} + od_childicons); //use odf_childicons instead + optionsdockty = set of optiondockty; + + dockbuttonrectty = (dbr_none,dbr_handle,dbr_close,dbr_maximize,dbr_normalize, + dbr_minimize,dbr_fixsize,dbr_float, + dbr_top,dbr_background,dbr_lock,dbr_nolock); +const + defaultoptionsdock = [od_savepos,od_savezorder,od_savechildren, + od_captionhint]; + defaultoptionsdocknochildren = defaultoptionsdock - [od_savechildren]; + deprecatedoptionsdock = [od_childicons]; + + dbr_first = dbr_handle; + dbr_last = dbr_nolock; + dbr_firstbutton = dockbuttonrectty(ord(dbr_first)+1); + dbr_lastbutton = dbr_last; + defaulttaboptions= [tabo_dragdest,tabo_dragsource]; + +type + twidgetdragobject = class(tdragobject) + private + function getwidget: twidget; + public + constructor create(const asender: twidget; var instance: tdragobject; + const apickpos: pointty); + property widget: twidget read getwidget; + end; + + tdockcontroller = class; + + tdockdragobject = class(twidgetdragobject) + private + fxorwidget: twidget; + fxorrect: rectty; //screen origin + fdock: tdockcontroller; + findex: integer; + fcheckeddockcontroller: tdockcontroller; + protected + procedure drawxorpic; + procedure setxorwidget(const awidget: twidget; const screenrect: rectty); + public + constructor create(const adock: tdockcontroller; const asender: twidget; + var instance: tdragobject; const apickpos: pointty); + destructor destroy; override; + procedure refused(const apos: pointty); override; + end; + + idockcontroller = interface(idragcontroller)[miid_idockcontroller] + function checkdock(var info: draginfoty): boolean; + function getbuttonrects(const index: dockbuttonrectty): rectty; + //origin = clientrect.pos + function getplacementrect: rectty; //origin = container.pos + function getminimizedsize(out apos: captionposty): sizety; + //cx = 0 -> normalwidth, cy = 0 -> normalheight + function getcaption: msestring; + function getchildicon: tmaskedbitmap; //own or first icon of dockchildren, + //can return nil + procedure dolayoutchanged(const sender: tdockcontroller); + procedure dodockcaptionchanged(const sender: tdockcontroller); + end; + + checkdockeventty = procedure(const sender: tobject; const apos: pointty; + const dockdragobject: tdockdragobject; + var accept: boolean) of object; + + tdockhandle = class(tpublishedwidget) + private + fcontroller: tdockcontroller; + fgrip_pos: captionposty; + fgrip_color: colorty; + fgrip_grip: stockbitmapty; + procedure setgrip_color(const Value: colorty); + procedure setgrip_grip(const Value: stockbitmapty); + procedure setgrip_pos(const Value: captionposty); + protected + function gethandlerect: rectty; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dopaintforeground(const canvas: tcanvas); override; + function gethint: msestring; override; + public + constructor create(aowner: tcomponent); override; + published + property grip_pos: captionposty read fgrip_pos write setgrip_pos default cp_bottomright; + property grip_grip: stockbitmapty read fgrip_grip write setgrip_grip default stb_none; + property grip_color: colorty read fgrip_color write setgrip_color default defaultgripcolor; + property bounds_cx default 15; + property bounds_cy default 15; + property anchors default [an_right,an_bottom]; + property color default cl_transparent; + property optionswidget default defaultoptionswidget + [ow_top{,ow_noautosizing}]; + property optionswidget1 default defaultoptionswidget1 + [ow1_noautosizing]; + end; + + dockstatety = (dos_layoutvalid,dos_sizing, + dos_updating1,dos_updating2,dos_updating3, + dos_updating4,dos_updating5,dos_tabedending, + { + dos_closebuttonclicked,dos_maximizebuttonclicked, + dos_normalizebuttonclicked,dos_minimizebuttonclicked, + dos_fixsizebuttonclicked,dos_floatbuttonclicked, + dos_topbuttonclicked,dos_backgroundbuttonclicked, + dos_lockbuttonclicked,dos_nolockbuttonclicked, + } + dos_moving,dos_hasfloatbutton, + {dos_proprefvalid,}dos_showed,dos_xorpic); + dockstatesty = set of dockstatety; + + splitdirty = (sd_none,sd_vert,sd_horz,sd_tabed); + mdistatety = (mds_normal,mds_maximized,mds_minimized,mds_floating); + + dockcontrollereventty = procedure(const sender: tdockcontroller) of object; + + docklayouteventty = procedure(const sender: twidget; + const achildren: widgetarty) of object; + mdistatechangedeventty = procedure(const sender: twidget; + const oldvalue,newvalue: mdistatety) of object; + dockrecteventty = procedure(const sender: twidget; + var arect: rectty) of object; + + bandinfoty = record + first: integer; + last: integer; + size: integer; + end; + + bandinfoarty = array of bandinfoty; + + tdockcontroller = class(tdragcontroller) + private + foncalclayout: docklayouteventty; + fonlayoutchanged: dockcontrollereventty; + fonboundschanged: dockcontrollereventty; + foncaptionchanged: dockcontrollereventty; + fonfloat: notifyeventty; + fondock: notifyeventty; + fonchilddock: widgeteventty; + fonchildfloat: widgeteventty; + foncheckdock: checkdockeventty; + fdockhandle: tdockhandle; + fsplitter_size: integer; + fcursorbefore: cursorshapety; + fsizeindex: integer; + fmoveindex: integer; + fsizingrect: rectty; + fsizeoffset: integer; + fdockstate: dockstatesty; + fcaption: msestring; + fsize: sizety; + fsplitter_color: colorty; + fsplitter_colorgrip: colorty; + fsplitter_grip: stockbitmapty; + fsplitterrects: rectarty; + frecalclevel: integer; + fsplitdir,fasplitdir: splitdirty; + fmdistate: mdistatety; + fnormalrect: rectty; + ftabwidget: ttabwidget; //tdocktabwidget + ftabpage: ttabpage; //tdocktabpage + ftaborder: msestringarty; + factivetab: integer; //used only for statreading + fuseroptions: optionsdockty; + floatdockcount: integer; + fonmdistatechanged: mdistatechangedeventty; + ftab_options: tabbaroptionsty; + ftab_size: integer; + ftab_sizemin: integer; + ftab_sizemax: integer; + ftab_color: colorty; + ftab_colortab: colorty; + ftab_coloractivetab: colorty; + ftab_frame: tframecomp; + ftab_face: tfacecomp; + ftab_facetab: tfacecomp; + ftab_faceactivetab: tfacecomp; + ftab_frametab: tframecomp; + fplacementrect: rectty; + fhiddensizeref: sizety; + fbands: bandinfoarty; + fbandstart: integer; + fbandgap: integer; + fsizes: integerarty; + frefsize: integer; + fwidgetsbefore: widgetarty; + fwidgetrectsbefore: rectarty; + ftab_textflags: textflagsty; + ftab_width: integer; + ftab_widthmin: integer; + ftab_widthmax: integer; + fdefaultsplitdir: splitdirty; + fchildren: stringarty; + ffocusedchild: integer; + fonbeforefloat: dockrecteventty; + fcolortab: colorty; + fcoloractivetab: colorty; + ffacetab: tfacecomp; + ffaceactivetab: tfacecomp; + procedure updaterefsize; + procedure setdockhandle(const avalue: tdockhandle); + function checksplit(const awidgets: widgetarty; + out propsize,varsize,fixsize,fixcount: integer; + out isprop,isfix: booleanarty; + const fixedareprop: boolean): widgetarty; overload; + function checksplit(out propsize,fixsize: integer; + out isprop,isfix: booleanarty; + const fixedareprop: boolean): widgetarty; overload; + function checksplit: widgetarty; overload; + procedure setcaption(const Value: msestring); + procedure setsplitter_size(const Value: integer); + procedure setsplitter_setgrip(const Value: stockbitmapty); + procedure setsplitter_color(const Value: colorty); + procedure setsplitter_colorgrip(const Value: colorty); + procedure splitterchanged; + procedure updategrip(const asplitdir: splitdirty; const awidget: twidget); + procedure setuseroptions(const avalue: optionsdockty); + function placementrect: rectty; + procedure settab_options(const avalue: tabbaroptionsty); + procedure settab_frame(const avalue: tframecomp); + procedure settab_face(const avalue: tfacecomp); + procedure settab_color(const avalue: colorty); + procedure settab_colortab(const avalue: colorty); + procedure settab_coloractivetab(const avalue: colorty); + procedure settab_facetab(const avalue: tfacecomp); + procedure settab_faceactivetab(const avalue: tfacecomp); + procedure settab_size(const avalue: integer); + procedure settab_sizemin(const avalue: integer); + procedure settab_sizemax(const avalue: integer); + procedure setbandgap(const avalue: integer); + + procedure settab_textflags(const avalue: textflagsty); + procedure settab_width(const avalue: integer); + procedure settab_widthmin(const avalue: integer); + procedure settab_widthmax(const avalue: integer); + procedure setsplitdir(const avalue: splitdirty); + procedure setcurrentsplitdir(const avalue: splitdirty); + function getdockrect: rectty; + procedure settab_frametab(const avalue: tframecomp); + function getactivetabpage: ttabpage; + procedure setcolortab(const avalue: colorty); + procedure setcoloractivetab(const avalue: colorty); + procedure setfacetab(const avalue: tfacecomp); + procedure setfaceactivetab(const avalue: tfacecomp); + protected + foptionsdock: optionsdockty; + fr: prectaccessty; + fw: pwidgetaccessty; + fplacing: integer; + fclickedbutton: dockbuttonrectty; + fwidgetstate: widgetstatesty; + + procedure checkdirection; + procedure objectevent(const sender: tobject; + const event: objecteventty) override; + function checkclickstate(const info: mouseeventinfoty): boolean override; + procedure dokeypress(const sender: twidget; var info: keyeventinfoty) + override; + + procedure drawxorpic(const ashow: boolean; var canvas1: tcanvas); + procedure endmouseop1(); + procedure endmouseop2(); + procedure cancelsizing(); + + function doclose(const awidget: twidget): boolean; + procedure setmdistate(const avalue: mdistatety); virtual; + procedure domdistatechanged(const oldstate,newstate: mdistatety); virtual; + function dofloat(const adist: pointty): boolean; virtual; + function dodock(const oldparent: tdockcontroller): boolean; virtual; + procedure dochilddock(const awidget: twidget); virtual; + procedure dochildfloat(const awidget: twidget); virtual; + function docheckdock(const info: draginfoty): boolean; virtual; + function dockdrag(const dragobj: tdockdragobject): boolean; + procedure childstatechanged(const sender: twidget; + const newstate,oldstate: widgetstatesty); virtual; + + property useroptions: optionsdockty read fuseroptions write setuseroptions + default defaultoptionsdock; + + function nogrip: boolean; + function canfloat: boolean; + procedure refused(const apos: pointty); + function calclayout(const dragobject: tdockdragobject; + const nonewplace: boolean): boolean; //false if canceled + procedure setpickshape(const ashape: cursorshapety); + procedure restorepickshape; + function checkbuttonarea(const apos: pointty): dockbuttonrectty; + procedure updatesplitterrects(const awidgets: widgetarty); + procedure checksplitdir(var asplitdir: splitdirty); + procedure setoptionsdock(const avalue: optionsdockty); virtual; + function isfullarea: boolean; + function istabed: boolean; + function ismdi: boolean; + function isfloating: boolean; + function canmdisize: boolean; + procedure dolayoutchanged; virtual; + procedure doboundschanged; + procedure docaptionchanged; + function findbandpos(const apos: integer; out aindex: integer; + out arect: rectty): boolean; + //false if not found, band index and band rect + function findbandwidget(const apos: pointty; out aindex: integer; + out arect: rectty): boolean; + //false if not found. widget index and widget rect + function findbandindex(const widgetindex: integer; out aindex: integer; + out arect: rectty): boolean; + function nofit: boolean; + function writechild(const index: integer): msestring; + procedure readchildrencount(const acount: integer); + procedure readchild(const index: integer; const avalue: msestring); + procedure receiveevent(const aevent: tobjectevent); override; + function canbegindrag: boolean; override; + procedure dostatplace(const aparent: twidget; + const avisible: boolean; arect: rectty); virtual; + procedure updatetabpage(const sender: ttabpage); + public + constructor create(aintf: idockcontroller); + destructor destroy; override; + + function beforedragevent(var info: draginfoty): boolean; override; + procedure enddrag; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure childormouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure checkmouseactivate(const sender: twidget; + var info: mouseeventinfoty); + procedure dopaint(const acanvas: tcanvas); + //canvasorigin = container.clientpos; + procedure doactivate; + procedure sizechanged(force: boolean = false; + scalefixedalso: boolean = false; const awidgets: widgetarty = nil); + procedure parentchanged(const sender: twidget); + procedure poschanged; + procedure statechanged(const astate: widgetstatesty); virtual; + procedure widgetregionchanged(const sender: twidget); + procedure updateminscrollsize(var asize: sizety); + procedure beginclientrectchanged; + procedure endclientrectchanged; + procedure beginplacement(); + procedure endplacement(); + procedure layoutchanged; //force layout calcualation + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter; + const bounds: prectty = nil); + procedure statreading; + procedure statread; + function getdockcaption: msestring; + function getfloatcaption: msestring; + function getitems: widgetarty; //reference count = 1 + function getwidget: twidget; + function activewidget: twidget; //focused child + property tabwidget: ttabwidget read ftabwidget; //can be nil + property activetabpage: ttabpage read getactivetabpage; + + function getparentcontroller( + out acontroller: tdockcontroller): boolean; overload; + function getparentcontroller: tdockcontroller; overload; + function dockparentname(): string; //'' if none + function childicon(): tmaskedbitmap virtual; + + property mdistate: mdistatety read fmdistate write setmdistate; + property currentsplitdir: splitdirty read fsplitdir + write setcurrentsplitdir; + property dockrect: rectty read getdockrect; + //origin = getwidget.container.pos + function close: boolean; //simulates mr_windowclosed for owner + function closeactivewidget: boolean; + //simulates mr_windowclosed for active widget, true if ok + function float(): boolean; //false if canceled + function dockto(const dest: tdockcontroller; const apos: pointty): boolean; + procedure dock(const source: tdockcontroller; const arect: rectty); + //simulates dostatread, use in beginplacement()/endplacement() + published + property dockhandle: tdockhandle read fdockhandle write setdockhandle; + property splitter_size: integer read fsplitter_size + write setsplitter_size default defaultsplittersize; + property splitter_grip: stockbitmapty read fsplitter_grip + write setsplitter_setgrip default defaultsplittergrip; + property splitter_color: colorty read fsplitter_color + write setsplitter_color default defaultsplittercolor; + property splitter_colorgrip: colorty read fsplitter_colorgrip + write setsplitter_colorgrip default defaultsplittercolorgrip; + property tab_options: tabbaroptionsty read ftab_options write settab_options + default defaulttaboptions; + property tab_textflags: textflagsty read ftab_textflags write + settab_textflags default defaultcaptiontextflags; + property tab_width: integer read ftab_width write settab_width default 0; + property tab_widthmin: integer read ftab_widthmin + write settab_widthmin default 0; + property tab_widthmax: integer read ftab_widthmax + write settab_widthmax default 0; + + property tab_frame: tframecomp read ftab_frame write settab_frame; + property tab_face: tfacecomp read ftab_face write settab_face; + property tab_color: colorty read ftab_color write settab_color + default cl_default; + property tab_colortab: colorty read ftab_colortab + write settab_colortab default cl_transparent; + property tab_coloractivetab: colorty read ftab_coloractivetab + write settab_coloractivetab default cl_active; + property tab_frametab: tframecomp read ftab_frametab write settab_frametab; + property tab_facetab: tfacecomp read ftab_facetab write settab_facetab; + property tab_faceactivetab: tfacecomp read ftab_faceactivetab + write settab_faceactivetab; + property tab_size: integer read ftab_size write settab_size default 0; + property tab_sizemin: integer read ftab_sizemin write settab_sizemin + default defaulttabsizemin; + property tab_sizemax: integer read ftab_sizemax write settab_sizemax + default defaulttabsizemax; + property colortab: colorty read fcolortab + write setcolortab default cl_default; + property coloractivetab: colorty read fcoloractivetab + write setcoloractivetab default cl_default; + property facetab: tfacecomp read ffacetab write setfacetab; + property faceactivetab: tfacecomp read ffaceactivetab write setfaceactivetab; + property caption: msestring read fcaption write setcaption; + property splitdir: splitdirty read fdefaultsplitdir write setsplitdir + default sd_none; //sets default and current splitdir, + //returns default + property optionsdock: optionsdockty read foptionsdock write setoptionsdock + default defaultoptionsdock; + property bandgap: integer read fbandgap write setbandgap default 0; + + property oncalclayout: docklayouteventty read foncalclayout + write foncalclayout; + property onlayoutchanged: dockcontrollereventty read fonlayoutchanged + write fonlayoutchanged; + property onboundschanged: dockcontrollereventty read fonboundschanged + write fonboundschanged; + property oncaptionchanged: dockcontrollereventty read foncaptionchanged + write foncaptionchanged; + property onbeforefloat: dockrecteventty read fonbeforefloat + write fonbeforefloat; + property onfloat: notifyeventty read fonfloat write fonfloat; + property ondock: notifyeventty read fondock write fondock; + property onchilddock: widgeteventty read fonchilddock write fonchilddock; + property onchildfloat: widgeteventty read fonchildfloat write fonchildfloat; + property oncheckdock: checkdockeventty read foncheckdock write foncheckdock; + property onmdistatechanged: mdistatechangedeventty read fonmdistatechanged + write fonmdistatechanged; + end; + + tnochildrendockcontroller = class(tdockcontroller) + public + constructor create(aintf: idockcontroller); + published + property optionsdock default defaultoptionsdocknochildren; + end; + + idocktarget = interface(inullinterface)[miid_idocktarget] + function getdockcontroller: tdockcontroller; + end; + +type + gripoptionty = (go_closebutton,go_minimizebutton,go_normalizebutton, + go_maximizebutton, + go_fixsizebutton, + go_floatbutton,go_topbutton,go_backgroundbutton, + go_lockbutton,go_nolockbutton,go_buttonframe, + go_buttonhints, + go_horz,go_vert,go_opposite,go_showsplitcaption, + go_showfloatcaption); + gripoptionsty = set of gripoptionty; + +const + defaultgripoptions = [go_closebutton,go_buttonhints]; + defaultdockpaneloptionswidget = defaultoptionswidget + [ow_subfocus]; + defaulttextflagstop = [tf_ycentered,tf_clipo]; + defaulttextflagsleft = [tf_ycentered,tf_rotate90,tf_clipo]; + defaulttextflagsbottom = [tf_ycentered,tf_clipo]; + defaulttextflagsright = [tf_ycentered,tf_rotate90,tf_clipo]; + +type + gripstatety = (grps_sizevalid); + gripstatesty = set of gripstatety; + + tgripframe = class(tcaptionframe,iobjectpicker,iface) + private + fgrip_pos: captionposty; + fgrip_color: colorty; + fgrip_size: integer; + fgrip_grip: stockbitmapty; + fgrip_options: gripoptionsty; + fgrip_colorglyph: colorty; + fcontroller: tdockcontroller; + fgrip_coloractive: colorty; + fobjectpicker: tobjectpicker; + fgrip_colorbutton: colorty; + fgrip_colorbuttonactive: colorty; + fgrip_colorglyphactive: colorty; + fgrip_face: tface; + fgrip_faceactive: tface; + fgrip_textflagstop: textflagsty; + fgrip_textflagsleft: textflagsty; + fgrip_textflagsbottom: textflagsty; + fgrip_textflagsright: textflagsty; + fgrip_captiondist: integer; + fgrip_captionoffset: integer; + fgrip_hint: msestring; + procedure setgrip_color(const avalue: colorty); + procedure setgrip_grip(const avalue: stockbitmapty); + procedure setgrip_size(const avalue: integer); + procedure setgrip_options(avalue: gripoptionsty); + procedure setgrip_colorglyph(const avalue: colorty); + function getbuttonrects(const index: dockbuttonrectty): rectty; + procedure setgrip_coloractive(const avalue: colorty); + procedure setgrip_colorbutton(const avalue: colorty); + procedure setgrip_colorbuttonactive(const avalue: colorty); + procedure setgrip_colorglyphactive(const avalue: colorty); + function getgrip_face: tface; + procedure setgrip_face(const avalue: tface); + function getgrip_faceactive: tface; + procedure setgrip_faceactive(const avalue: tface); + procedure setgrip_textflagstop(const avalue: textflagsty); + procedure setgrip_textflagsright(const avalue: textflagsty); + procedure setgrip_textflagsbottom(const avalue: textflagsty); + procedure setgrip_textflagsrright(const avalue: textflagsty); + procedure setgrip_captiondist(const avalue: integer); + procedure setgrip_captionoffset(const avalue: integer); + protected + frects: array[dbr_first..dbr_last] of rectty; + fedges: array[dbr_first..dbr_last] of edgesty; + fgriprect: rectty; + fgripstate: gripstatesty; + factgripsize: integer; + fmousebutton: dockbuttonrectty; + procedure checkgripsize; + procedure updatewidgetstate; override; + procedure updaterects; override; + procedure updatestate; override; + procedure getpaintframe(var frame: framety); override; + function ishintarea(const apos: pointty; var aid: int32): boolean; override; + function calcsizingrect(const akind: sizingkindty; + const offset: pointty): rectty; + procedure drawgripbutton(const acanvas: tcanvas; + const akind: dockbuttonrectty; const arect: rectty; + const acolorglyph,acolorbutton: colorty; + const ahiddenedges: edgesty); virtual; + + //iface + function getclientrect: rectty; + procedure invalidatewidget(); + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function translatecolor(const acolor: colorty): colorty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + function getcomponentstate: tcomponentstate; + procedure widgetregioninvalid; + //iobjectpicker + function getwidget: twidget; + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + //true if found + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) override; + + public + constructor create(const aintf: icaptionframe; + const acontroller: tdockcontroller); + destructor destroy; override; + procedure createface(); + procedure createfaceactive(); + + procedure checktemplate(const sender: tobject) override; + procedure showhint(const aid: int32; var info: hintinfoty); override; + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure mouseevent(var info: mouseeventinfoty); + property buttonrects[const index: dockbuttonrectty]: rectty + read getbuttonrects; + //client origin + function getminimizedsize(out apos: captionposty): sizety; + function griprect: rectty; //origin = pos + published + property grip_size: integer read fgrip_size write setgrip_size stored true; + //for optionalclass + property grip_textflagstop: textflagsty read fgrip_textflagstop + write setgrip_textflagstop default defaulttextflagstop; + property grip_textflagsleft: textflagsty read fgrip_textflagsleft + write setgrip_textflagsright default defaulttextflagsleft; + property grip_textflagsbottom: textflagsty read fgrip_textflagsbottom + write setgrip_textflagsbottom default defaulttextflagsbottom; + property grip_textflagsright: textflagsty read fgrip_textflagsright + write setgrip_textflagsrright default defaulttextflagsright; + property grip_captiondist: integer read fgrip_captiondist + write setgrip_captiondist default 1; + property grip_captionoffset: integer read fgrip_captionoffset + write setgrip_captionoffset default 0; + property grip_grip: stockbitmapty read fgrip_grip write setgrip_grip + default defaultgripgrip; + property grip_color: colorty read fgrip_color write setgrip_color + default defaultgripcolor; + property grip_coloractive: colorty read fgrip_coloractive + write setgrip_coloractive default defaultgripcoloractive; + property grip_colorglyph: colorty read fgrip_colorglyph write + setgrip_colorglyph default cl_glyph; + property grip_colorglyphactive: colorty read fgrip_colorglyphactive write + setgrip_colorglyphactive default cl_glyphactive; + property grip_colorbutton: colorty read fgrip_colorbutton write + setgrip_colorbutton default cl_transparent; + property grip_colorbuttonactive: colorty read fgrip_colorbuttonactive write + setgrip_colorbuttonactive default cl_transparent; + property grip_options: gripoptionsty read fgrip_options write setgrip_options + default defaultgripoptions; + property grip_face: tface read getgrip_face write setgrip_face; + property grip_faceactive: tface read getgrip_faceactive + write setgrip_faceactive; + property grip_hint: msestring read fgrip_hint write fgrip_hint; + end; + + tdockpanel = class(tscalingwidget,idockcontroller,idocktarget,istatfile) + private + fdragdock: tnochildrendockcontroller; + foptionswindow: windowoptionsty; + fstatfile: tstatfile; + fstatvarname: msestring; + ficon: tmaskedbitmap; + fstatpriority: integer; + fdockingareacaption: msestring; + procedure setdragdock(const Value: tnochildrendockcontroller); + function getframe: tgripframe; + procedure setframe(const Value: tgripframe); + procedure setstatfile(const Value: tstatfile); + procedure seticon(const avalue: tmaskedbitmap); + procedure iconchanged(const sender: tobject); + procedure setdockingareacaption(const avalue: msestring); + protected +// procedure mouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure updatewindowinfo(var info: windowinfoty); override; + procedure internalcreateframe; override; + procedure clientrectchanged; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure setparentwidget(const Value: twidget); override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure doactivate; override; + procedure statechanged; override; + procedure poschanged; override; + procedure parentchanged; override; + function calcminscrollsize: sizety; override; + procedure dopaintbackground(const canvas: tcanvas); override; + //idockcontroller + function checkdock(var info: draginfoty): boolean; + function getbuttonrects(const index: dockbuttonrectty): rectty; + function getplacementrect: rectty; + function getminimizedsize(out apos: captionposty): sizety; + function getcaption: msestring; + function getchildicon: tmaskedbitmap; + procedure dolayoutchanged(const sender: tdockcontroller); virtual; + procedure dodockcaptionchanged(const sender: tdockcontroller); virtual; + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure dragevent(var info: draginfoty); override; + function getdockcontroller: tdockcontroller; + published + property dragdock: tnochildrendockcontroller read fdragdock write setdragdock; + property optionswidget default defaultdockpaneloptionswidget; + property optionswindow: windowoptionsty read foptionswindow + write foptionswindow default []; + property frame: tgripframe read getframe write setframe; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read fstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property icon: tmaskedbitmap read ficon write seticon; + property dockingareacaption: msestring read fdockingareacaption + write setdockingareacaption; + end; + +procedure paintdockingareacaption(const canvas: tcanvas; const sender: twidget; + const atext: msestring = 'Docking Area'); + +implementation +uses + msearrayutils,sysutils,msebits,{msetabs,}mseguiintf,{mseforms,}msestream, + mseformatstr,msekeyboard; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + twindow1 = class(twindow); + tcustomframe1 = class(tcustomframe); + tcustomtabwidget1 = class(tcustomtabwidget); + tface1 = class(tface); + ttabwidget1 = class(ttabwidget); + +const + useroptionsmask: optionsdockty = [od_fixsize,od_top,od_background, + od_lock,od_nolock]; + +type + tchildorderevent = class(tobjectevent) + protected + fchildren: stringarty; + ffocusedchild: integer; + public + constructor create(const sender: tdockcontroller); + end; + + tdocktabwidget = class(ttabwidget) + private + fcontroller: tdockcontroller; + protected + procedure doclosepage(const sender: tobject); override; + procedure dopageremoved(const apage: twidget); override; + procedure tabchanged(const synctabindex: boolean); override; + procedure updateoptions; + public + constructor create(const acontroller: tdockcontroller; + const aparent: twidget); reintroduce; + destructor destroy; override; + end; + + tdocktabpage = class(ttabpage,idocktarget) + private + fcontroller: tdockcontroller; + ftarget: twidget; + ftargetanchors: anchorsty; + //idocktarget + function getdockcontroller: tdockcontroller; + protected + procedure unregisterchildwidget(const child: twidget); override; + procedure widgetregionchanged(const sender: twidget); override; + public + constructor create(const atabwidget: tdocktabwidget; const awidget: twidget); + reintroduce; + destructor destroy(); override; + end; + +procedure paintdockingareacaption(const canvas: tcanvas; const sender: twidget; + const atext: msestring = 'Docking Area'); +begin + if sender.visiblechildrencount = 0 then begin + canvas.save; + canvas.font.height:= 20; + drawtext(canvas,atext,sender.paintclientrect(), + [tf_xcentered,tf_ycentered,tf_grayed]); + canvas.restore; + end; +end; + +{ twidgetdragobject } + +constructor twidgetdragobject.create(const asender: twidget; + var instance: tdragobject; const apickpos: pointty); +begin + inherited create(asender,instance,apickpos); +end; + +function twidgetdragobject.getwidget: twidget; +begin + result:= twidget(fsender); +end; + +{ tdockdragobject } + +constructor tdockdragobject.create(const adock: tdockcontroller; + const asender: twidget; var instance: tdragobject; + const apickpos: pointty); +begin + fdock:= adock; + inherited create(asender,instance,apickpos); +end; + +destructor tdockdragobject.destroy; +begin + if fcheckeddockcontroller <> nil then begin + fcheckeddockcontroller.fasplitdir:= sd_none; + end; + inherited; +end; + +procedure tdockdragobject.drawxorpic; +begin + if fxorwidget <> nil then begin + with fxorwidget.getcanvas(org_screen) do begin + drawxorframe(fxorrect,-3,stockobjects.bitmaps[stb_dens50]); + end; + end; +end; + +procedure tdockdragobject.refused(const apos: pointty); +begin + inherited; + drawxorpic; + fxorwidget:= nil; + fdock.refused(apos); +end; + +procedure tdockdragobject.setxorwidget(const awidget: twidget; + const screenrect: rectty); +begin + if (awidget <> fxorwidget) or not rectisequal(fxorrect,screenrect) then begin + drawxorpic; + fxorwidget:= awidget; + fxorrect:= screenrect; + drawxorpic; + end; +end; + +{ tdocktabwidget } + +constructor tdocktabwidget.create(const acontroller: tdockcontroller; + const aparent: twidget); +begin + fcontroller:= acontroller; + inherited create(nil); + parentwidget:= aparent; + updateoptions; + synctofontheight; +end; + +procedure tdocktabwidget.updateoptions; +begin + with fcontroller do begin + self.tab_options:= ftab_options; + self.tab_color:= ftab_color; + self.tab_colortab:= ftab_colortab; + self.tab_coloractivetab:= ftab_coloractivetab; + self.tab_size:= ftab_size; + self.tab_sizemin:= ftab_sizemin; + self.tab_sizemax:= ftab_sizemax; + self.tab_textflags:= ftab_textflags; + self.tab_width:= ftab_width; + self.tab_widthmin:= ftab_widthmin; + self.tab_widthmax:= ftab_widthmax; + if ftab_frame <> nil then begin + self.tab_frame:= tstepboxframe1(1); + self.tab_frame.assign(ftab_frame); + end + else begin + self.tab_frame:= nil; + end; + if ftab_face <> nil then begin + self.tab_face:= tface(1); + self.tab_face.assign(ftab_face); + end + else begin + self.tab_face:= nil; + end; + if ftab_frametab <> nil then begin + self.tab_frametab:= ttabframe(1); + self.tab_frametab.assign(ftab_frametab); + end + else begin + self.tab_frametab:= nil; + end; + if ftab_facetab <> nil then begin + self.tab_facetab:= tface(1); + self.tab_facetab.assign(ftab_facetab); + end + else begin + self.tab_facetab:= nil; + end; + if ftab_faceactivetab <> nil then begin + self.tab_faceactivetab:= tface(1); + self.tab_faceactivetab.assign(ftab_faceactivetab); + end + else begin + self.tab_faceactivetab:= nil; + end; + end; +end; + +destructor tdocktabwidget.destroy; +begin + if fcontroller.ftabwidget = self then begin + fcontroller.ftabwidget:= nil; + end; + inherited; +end; + +procedure tdocktabwidget.doclosepage(const sender: tobject); +begin + fcontroller.doclose(tdocktabpage(items[fpopuptab]).ftarget); +end; + +procedure tdocktabwidget.dopageremoved(const apage: twidget); +begin + inherited; + if (count = 0) and not application.terminated then begin + fcontroller.ftabwidget:= nil; + fcontroller.fsplitterrects:= nil; + release; + end; + fcontroller.dolayoutchanged(); +end; + +procedure tdocktabwidget.tabchanged(const synctabindex: boolean); +begin + inherited; + if fcontroller.fintf.getwidget.componentstate * + [csloading,csdestroying] = [] then begin + fcontroller.dolayoutchanged(); + end; +end; + +{ tdocktabpage } + +constructor tdocktabpage.create(const atabwidget: tdocktabwidget; + const awidget: twidget); +var + intf1: idocktarget; +begin + fcontroller:= atabwidget.fcontroller; + inherited create(nil); + optionswidget:= optionswidget - [ow_destroywidgets]; + ftarget:= awidget; + ftargetanchors:= awidget.anchors; + if awidget.getcorbainterface(typeinfo(idocktarget),intf1) then begin + intf1.getdockcontroller.updatetabpage(self); +// caption:= intf1.getdockcontroller.getdockcaption; + + end + else begin + caption:= 'Page '+inttostrmse(atabwidget.count); + end; + awidget.anchors:= []; + parentwidget:= atabwidget; + insertwidget(awidget,paintpos); +end; + +destructor tdocktabpage.destroy(); +begin + fcontroller.ftabpage:= nil; + inherited; +end; + +procedure tdocktabpage.unregisterchildwidget(const child: twidget); +begin + inherited; + if (child = ftarget) then begin +// ftarget:= nil; + child.anchors:= ftargetanchors; + if not application.terminated then begin + visible:= false; + parentwidget:= nil; + release; + end; + end; +end; + +procedure tdocktabpage.widgetregionchanged(const sender: twidget); +var + focusedwidgetbefore: twidget; +begin + inherited; + if (sender <> nil) and (sender = ftarget) and not sender.visible and + (fparentwidget <> nil) and (fparentwidget.parentwidget <> nil) and + not (csdestroying in sender.componentstate) then begin + optionswidget:= optionswidget - [ow_tabfocus]; //don't accept focus + focusedwidgetbefore:= nil; + if entered then begin + setlinkedvar(window.focusedwidget,tmsecomponent(focusedwidgetbefore)); + end; + try + sender.parentwidget:= fparentwidget.parentwidget; //remove page + if (focusedwidgetbefore <> nil) and (window.focusedwidget = nil) then begin + focusedwidgetbefore.parentfocus; //restore focus + end; + finally + setlinkedvar(nil,tmsecomponent(focusedwidgetbefore)); + end; + end; +end; + +function tdocktabpage.getdockcontroller: tdockcontroller; +begin + result:= fcontroller; +end; + +{ tdockcontroller } + +constructor tdockcontroller.create(aintf: idockcontroller); +begin + fr:= @rectaccessx; + fw:= @widgetaccessx; + fsizeindex:= -1; + foptionsdock:= defaultoptionsdock; + fuseroptions:= defaultoptionsdock; + fsplitter_grip:= defaultsplittergrip; + fsplitter_color:= defaultsplittercolor; + fsplitter_colorgrip:= defaultsplittercolorgrip; + fsplitter_size:= defaultsplittersize; + ftab_options:= defaulttaboptions; + ftab_color:= cl_default; + ftab_colortab:= cl_transparent; + ftab_coloractivetab:= cl_active; + ftab_sizemin:= defaulttabsizemin; + ftab_sizemax:= defaulttabsizemax; + ftab_textflags:= defaultcaptiontextflags; + fcolortab:= cl_default; + fcoloractivetab:= cl_default; + fmdistate:= mds_floating; + inherited create(aintf); +end; + +destructor tdockcontroller.destroy; +begin + freeandnil(ftabwidget); + inherited; +end; + +function tdockcontroller.checksplit(const awidgets: widgetarty; + out propsize,varsize,fixsize,fixcount: integer; + out isprop,isfix: booleanarty; + const fixedareprop: boolean): widgetarty; + //calculate order and total widths/heights of elements +var + ar1: widgetarty; + int1,int2,int3: integer; + intf1: idocktarget; + opt1: optionsdockty; + fixend: boolean; + banded: boolean; +// needspropref: boolean; + dcont1: tdockcontroller; + widget1: twidget; + bo1: boolean; +begin + checkdirection; + banded:= (od_banded in foptionsdock) and (fsplitdir in [sd_vert,sd_horz]); + if awidgets = nil then begin + if (fsplitdir = sd_vert) then begin + ar1:= fintf.getwidget.getsortxchildren(banded); + end + else begin + if (fsplitdir = sd_horz) or (fsplitdir = sd_tabed) then begin + ar1:= fintf.getwidget.getsortychildren(banded); + end + else begin + ar1:= nil; + end; + end; + end + else begin + if fsplitdir = sd_tabed then begin + ar1:= nil; + end + else begin + ar1:= awidgets; + end; + end; + setlength(result,length(ar1)); + setlength(isprop,length(ar1)); + setlength(isfix,length(ar1)); + int2:= 0; + propsize:= 0; + varsize:= 0; + fixsize:= 0; + fixcount:= 0; + fixend:= foptionsdock * [od_nofit] <> []; +// needspropref:= false; + for int1:= 0 to high(ar1) do begin + widget1:= ar1[int1]; + with twidget1(widget1) do begin + include(fwidgetstate1,ws1_nominsize); + if not (ow1_noautosizing in foptionswidget1) then begin + if visible then begin + result[int2]:= ar1[int1]; + if fixend then begin + isfix[int2]:= true; + inc(fixcount); + end + else begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + dcont1:= intf1.getdockcontroller; + if dcont1.fmdistate = mds_floating then begin + dcont1.fmdistate:= mds_normal; //placed by setparent + end; + opt1:= dcont1.foptionsdock; +// needspropref:= needspropref or not (dos_proprefvalid in dcont1.fdockstate); + dcont1.fdockstate:= dcont1.fdockstate + [{dos_proprefvalid,}dos_showed]; + bo1:= false; + if dos_sizing in fdockstate then begin + if fsplitdir in [sd_vert,sd_horz] then begin + int3:= fr^.si(dcont1.fhiddensizeref); + bo1:= int3 > 0; //widget is visible again, restore old size + if bo1 and (opt1 * [od_propsize,od_fixsize] = [od_propsize]) then begin + fw^.setsize(widget1, + fw^.size(widget1)*fr^.si(fplacementrect.size) div int3); + //adjust to current container size + end; + end; + dcont1.fhiddensizeref:= nullsize; + end; +// include(dcont1.fdockstate,dos_proprefvalid); + if bo1 or not fixedareprop and (od_fixsize in opt1) then begin + isfix[int2]:= true; + inc(fixcount); + end; + if not bo1 and ((od_propsize in opt1) and not (od_fixsize in opt1) or + fixedareprop and (od_fixsize in opt1)) then begin + isprop[int2]:= true; + propsize:= propsize + fw^.size(ar1[int1]); + end + end; + end; + if not isprop[int2] then begin + fixsize:= fixsize + fw^.size(ar1[int1]); + if not isfix[int2] then begin + varsize:= varsize + fw^.size(ar1[int1]); + end; + end; + inc(int2); + end + else begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + dcont1:= intf1.getdockcontroller; + if dcont1.fmdistate = mds_floating then begin + dcont1.fmdistate:= mds_normal; //placed by setparent + end; + if dos_showed in dcont1.fdockstate then begin + exclude(dcont1.fdockstate,dos_showed); + if not (dos_updating4 in dcont1.fdockstate) then begin //no statreading + dcont1.fhiddensizeref:= fplacementrect.size; + end; + end; + end; + end; + end; + end; + end; +// if needspropref then begin +// updaterefsize; +// end; + setlength(result,int2); + setlength(isprop,int2); + setlength(isfix,int2); + if (awidgets = nil) and not banded and (fsplitdir in [sd_vert,sd_horz]) and + (high(result) > 0) and (fw^.pos(result[0]) = fw^.pos(result[1])) and + (finditem(pointerarty(fwidgetsbefore),pointer(result[1])) < 0) then begin + widget1:= result[0]; //probably revisible + result[0]:= result[1]; + result[1]:= widget1; + bo1:= isprop[0]; + isprop[0]:= isprop[1]; + isprop[1]:= bo1; + bo1:= isfix[0]; + isfix[0]:= isfix[1]; + isfix[1]:= bo1; + end; + fwidgetsbefore:= result; +end; + +function tdockcontroller.checksplit(out propsize,fixsize: integer; + out isprop,isfix: booleanarty; const fixedareprop: boolean): widgetarty; +var + int1,int2: integer; +begin + result:= checksplit(nil,propsize,int1,fixsize,int2,isprop,isfix,fixedareprop); +end; + +function tdockcontroller.checksplit: widgetarty; +var + ar1,ar2: booleanarty; + int1,int2,int3,int4: integer; +begin + if ftabwidget <> nil then begin + setlength(result,tdocktabwidget(ftabwidget).count); + int2:= 0; + for int1:= 0 to high(result) do begin + result[int2]:= tdocktabpage(tdocktabwidget(ftabwidget)[int1]).ftarget; + if result[int2] <> nil then begin + inc(int2); + end; + end; + setlength(result,int2); + end + else begin + result:= checksplit(nil,int1,int2,int3,int4,ar1,ar2,false); + end; +end; + +procedure tdockcontroller.sizechanged(force: boolean = false; + scalefixedalso: boolean = false; + const awidgets: widgetarty = nil); +var + ar1: widgetarty; + ar2: realarty; + prop,fix: booleanarty; + fixsize: integer; + propsize: integer; + banded: boolean; + opt1: optionsdockty; + + procedure calcsize; + var + int1: integer; + rea1,rea2: real; + begin + int1:= fr^.size(fplacementrect) - high(ar1) * fsplitter_size - fixsize; + if int1 < 0 then begin + int1:= 0; + end; + if (frefsize > 0) and (high(ar1) = high(fsizes)) then begin + rea1:= int1 / frefsize; + for int1:= 0 to high(ar1) do begin + if prop[int1] then begin + ar2[int1]:= fsizes[int1] * rea1; + end + else begin + ar2[int1]:= fw^.size(ar1[int1]); + end; + end; + end + else begin + if (propsize = 0) then begin + rea1:= 1; + end + else begin + rea1:= int1/propsize; + end; + for int1:= 0 to high(ar1) do begin + ar2[int1]:= fw^.size(ar1[int1]); + if prop[int1] then begin + ar2[int1]:= ar2[int1] * rea1; + end; + end; + end; + rea2:= 0; + for int1:= 0 to high(ar2) do begin + if (fw^.max(ar1[int1]) <> 0) and (ar2[int1] > fw^.max(ar1[int1])) then begin + ar2[int1]:= fw^.max(ar1[int1]); + end; + if ar2[int1] < fw^.min(ar1[int1]) then begin + ar2[int1]:= fw^.min(ar1[int1]); + end; + rea2:= rea2 + ar2[int1]; //total size + end; + rea1:= fr^.size(fplacementrect); + if not nofit then begin + //adjust sizes for fit + rea2:= rea1 - (rea2 + high(ar2) * fsplitter_size); + //delta + if rea2 < 0 then begin + for int1:= high(ar2) downto 0 do begin + if not (fix[int1] and not scalefixedalso) and not prop[int1] then begin + rea1:= fw^.min(ar1[int1]); + ar2[int1]:= ar2[int1] + rea2; + if ar2[int1] < rea1 then begin + rea2:= ar2[int1] - rea1; + ar2[int1]:= rea1; + end + else begin + break; + end; + end; + end; + end + else begin + for int1:= high(ar2) downto 0 do begin + if not fix[int1] and not prop[int1] then begin + rea1:= fw^.max(ar1[int1]); + ar2[int1]:= ar2[int1] + rea2; + if (ar2[int1] > rea1) and (rea1 > 0) then begin + rea2:= ar2[int1] - rea1; + ar2[int1]:= rea1; + end + else begin + break; + end; + end; + end; + end; + end; + rea2:= fr^.pos(fplacementrect); + ar2[0]:= ar2[0] + rea2 + fsplitter_size; + for int1:= 1 to high(ar1) do begin //calc pos vector + ar2[int1]:= ar2[int1-1] + fsplitter_size + ar2[int1]; + end; + end; //calcsize + +var + minsize1: integer; + + procedure calcpos; + var + bandindex: integer; + + procedure calcbandheight(const aindex: integer); + var + int2,int3,int4: integer; + begin + setlength(fbands,high(fbands)+2); + int3:= 0; + for int2:= bandindex to aindex - 1 do begin + int4:= fw^.osize(ar1[int2]); + if int4 > int3 then begin + int3:= int4; //find biggest widget + end; + end; + with fbands[high(fbands)] do begin + first:= bandindex; + last:= aindex-1; + size:= int3; + end; + bandindex:= aindex; + end; //calcbandheight + + var + rea1,rea2: real; + int1: integer; + rect1: prectty; + rect2: rectty; + ar3: rectarty; + int2: integer; + bandpos: integer; + + procedure clipwidget; + var + int1: integer; + begin + int1:= fr^.stop(fplacementrect) - fsplitter_size; + if fr^.stop(rect1^) > int1 then begin + fr^.setstop(rect1^,int1); + end; + end; //clipwidget + + begin + rea2:= fr^.pos(fplacementrect); + if not nofit then begin + setlength(fbands,1); + with fbands[0] do begin + first:= 0; + last:= high(ar1); + size:= fr^.osize(fplacementrect); + end; + rect2:= fplacementrect; + for int1:= 0 to high(ar1) do begin + fr^.setpos(rect2,round(rea2)); + fr^.setsize(rect2,round(ar2[int1] - rea2) - fsplitter_size); + ar1[int1].widgetrect:= rect2; + rea2:= rea2 + fw^.size(ar1[int1]) + fsplitter_size; + end; + minsize1:= fr^.stop(rect2) - fr^.pos(fplacementrect); + end + else begin + setlength(ar3,length(ar1)); + bandindex:= 0; + rea1:= 0; + int2:= 0; + for int1:= 0 to high(ar1) do begin + rect1:= @ar3[int1]; //set size + rect1^:= fplacementrect; + fr^.setpos(rect1^,round(rea2)); + fr^.setsize(rect1^,round(ar2[int1] - rea2 - rea1) - fsplitter_size); + if banded and + (fr^.stop(rect1^) + fsplitter_size > fr^.stop(fplacementrect)) then begin + if int1 > int2 then begin //next band + calcbandheight(int1); + int2:= int1; // minimal one widget in band + fr^.setpos(rect1^,fr^.pos(fplacementrect)); //restart + clipwidget; + rea1:= rea1 + rea2; + rea2:= fr^.pos(rect1^); + rea1:= rea1 - rea2; + end + else begin + clipwidget; + end; + end; + rea2:= rea2 + fr^.size(rect1^) + fsplitter_size; + end; + calcbandheight(length(ar1)); + if not banded then begin + fbands[0].size:= fr^.osize(fplacementrect); + end; + bandpos:= fbandstart; + for int2:= 0 to high(fbands) do begin + with fbands[int2] do begin + for int1:= first to last do begin + rect1:= @ar3[int1]; //set ortho size + fr^.setosize(rect1^,fw^.osize(ar1[int1])); + if opt1 = [od_aligncenter] then begin + fr^.setopos(rect1^, + bandpos + (size-fr^.osize(rect1^)) div 2); + end + else begin + if opt1 = [od_alignend] then begin + fr^.setopos(rect1^,bandpos + (size-fr^.osize(rect1^))); + end + else begin + if opt1 = [od_alignbegin] then begin + fr^.setopos(rect1^,bandpos); + end + else begin + fr^.setopos(rect1^,bandpos + fr^.osize(rect1^)); + end; + end; + end; + ar1[int1].widgetrect:= rect1^; + end; + bandpos:= bandpos + size + fbandgap; + end; + end; + end; + end; //calcpos + +var + needsfixscale: boolean; + hasparent1: boolean; + + procedure updateplacement; + var + widget1: twidget; + int1: integer; + begin + widget1:= fintf.getwidget; + int1:= minsize1 - fr^.size(fplacementrect); + if (int1 > 0) then begin //extend placementrect + if not scalefixedalso and + not (od_expandforfixsize in foptionsdock) then begin + needsfixscale:= true; + end + else begin + if hasparent1 then begin + fw^.setanchordsize(widget1,fw^.size(widget1)+int1); //extend size + { + if not fw^.anchstop(widget1) then begin + fw^.setsize(widget1,fw^.size(widget1)+int1); //extend size + end + else begin + if not fw^.anchboth(widget1) then begin //use setanchordsize? + widget1.parentwidget.clientsize:= + addsize(widget1.parentwidget.clientsize,fr^.makesize(int1,0)); + //not async +// widget1.parentwidget.changeclientsize(fr^.makesize(int1,0)); + end; + end; + } + end; + end; + end + else begin + if not nofit then begin + fw^.setstop(ar1[high(ar1)],fr^.stop(fplacementrect)); + end; + end; + end; + +var + int1,int2: integer; + widget1: twidget; + widget2: twidget; + +begin + widget2:= fintf.getwidget; + hasparent1:= widget2.parentwidget <> nil; + widget1:= widget2.container; + checkdirection; + if (widget1 <> nil) and + (widget1.ComponentState * [csloading,csdesigning] = []) then begin + banded:= od_banded in foptionsdock; + fplacementrect:= idockcontroller(fintf).getplacementrect; + fbandstart:= fr^.opos(fplacementrect); + if fsplitdir in [sd_vert,sd_horz] then begin + ar1:= nil; //compiler warning + if not sizeisequal(fsize,fplacementrect.size) or force then begin + fbands:= nil; + fsize:= fplacementrect.size; + if fdockstate * [dos_updating1,dos_updating2,dos_updating4] <> [] then begin + exclude(fdockstate,dos_layoutvalid); + end + else begin + needsfixscale:= false; + fdockstate:= fdockstate + [dos_layoutvalid,dos_updating2,dos_sizing]; + try + inc(frecalclevel); + ar1:= checksplit(awidgets,propsize,int1,fixsize,int2,prop,fix,false); + if high(ar1) >= 0 then begin + setlength(ar2,length(ar1)); + if not (od_proportional in foptionsdock) then begin + for int1:= 0 to high(prop) do begin + prop[int1]:= false; + end; + end; + minsize1:= 0; + opt1:= foptionsdock * [od_alignbegin,od_aligncenter,od_alignend]; + if fsplitdir in [sd_vert,sd_horz] then begin + calcsize; + calcpos; + end; + if (opt1 = []) and not nofit then begin + updateplacement; + end; + end; + finally + fdockstate:= fdockstate - [dos_updating1,dos_updating2,dos_sizing]; + if (not (dos_layoutvalid in fdockstate) or needsfixscale) and + (frecalclevel < 4) then begin + try + sizechanged(force or needsfixscale,needsfixscale); + finally + dec(frecalclevel); + end; + end + else begin + dec(frecalclevel); + updatesplitterrects(ar1); + end; + end; + end; + end; + end + else begin + if (fsplitdir = sd_tabed) and (ws_loadedproc in widget1.widgetstate) and + (awidgets = nil) then begin + calclayout(nil,false); + end; + fbands:= nil; + if ismdi then begin + case fmdistate of + mds_normal: begin + fnormalrect:= widget2.widgetrect; + end; + end; + end; + end; + end; + doboundschanged; +end; + +procedure tdockcontroller.dopaint(const acanvas: tcanvas); //canvasorigin = container.clientpos; +var + int1: integer; + color1: colorty; + brush1: tsimplebitmap; +begin + if fsplitterrects <> nil then begin + if fsplitter_color <> cl_none then begin + for int1:= 0 to high(fsplitterrects) do begin + acanvas.fillrect(fsplitterrects[int1],fsplitter_color); + end; + end; + if fsplitter_grip <> stb_none then begin + with acanvas do begin + color1:= color; + brush1:= brush; + brush:= stockobjects.bitmaps[fsplitter_grip]; + color:= fsplitter_colorgrip; + for int1:= 0 to high(fsplitterrects) do begin + fillrect(fsplitterrects[int1],cl_brushcanvas); + end; + brush:= brush1; + color:= color1; + end; + end; + end; +end; + +procedure tdockcontroller.doactivate; +var + size1: sizety; + intf1: idocktarget; + widget1: twidget; +begin + size1:= fintf.getwidget.size; + if (size1.cx <= 0) or (size1.cy <= 0) then begin + widget1:= fintf.getwidget.parentwidget; + if (widget1 <> nil) and widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + intf1.getdockcontroller.calclayout(nil,false); + end; + end; +end; + +procedure tdockcontroller.updategrip(const asplitdir: splitdirty; + const awidget: twidget); +var + frame1: tcustomframe; + grippos1: captionposty; +begin + frame1:= twidget1(awidget).fframe; + if frame1 is tgripframe then begin + with tgripframe(frame1) do begin + grippos1:= fgrip_pos; + if fgrip_options * [go_horz,go_vert] = [] then begin + if asplitdir = sd_vert then begin + if go_opposite in fgrip_options then begin + fgrip_pos:= cp_bottom; + end + else begin + fgrip_pos:= cp_top; + end; + end + else begin + if (asplitdir = sd_horz) or (asplitdir = sd_tabed) or + (asplitdir = sd_none) then begin + if go_opposite in fgrip_options then begin + fgrip_pos:= cp_left; + end + else begin + fgrip_pos:= cp_right; + end; + end; + end; + end; + if grippos1 <> fgrip_pos then begin + internalupdatestate; + end; + end; + end; +end; + +procedure tdockcontroller.updatesplitterrects(const awidgets: widgetarty); +var + fixend: boolean; + + procedure calcsplitters; + var + rect1: rectty; + int1,int2: integer; + bandpos: integer; + begin + fr^.setsize(rect1,fsplitter_size); + bandpos:= fbandstart; + for int2:= 0 to high(fbands) do begin + with fbands[int2] do begin + fr^.setopos(rect1,bandpos); + fr^.setosize(rect1,size); + for int1:= first to last do begin + fr^.setpos(rect1,fw^.stop(awidgets[int1])); + fsplitterrects[int1]:= rect1; + end; + bandpos:= bandpos + size + fbandgap; + end; + end; + end; + +var + po1: pointty; + int1: integer; + sd1: splitdirty; +begin + sd1:= fsplitdir; + if nofit then begin + if sd1 = sd_vert then begin + sd1:= sd_horz; + end + else begin + sd1:= sd_vert; + end; + end; + for int1:= 0 to high(awidgets) do begin + updategrip(sd1,awidgets[int1]); + end; + if (high(awidgets) >= 0) and (fsplitter_size > 0) and + ((fsplitter_color <> cl_none) or (fsplitter_grip <> stb_none)) then begin + fixend:= foptionsdock * [od_nofit] <> []; + setlength(fsplitterrects,length(awidgets)); + calcsplitters; + if not fixend then begin + setlength(fsplitterrects,high(fsplitterrects)); + end; + po1:= fintf.getwidget.container.clientwidgetpos; + for int1:= 0 to high(fsplitterrects) do begin + subpoint1(fsplitterrects[int1].pos,po1); //clientorg + end; + end + else begin + fsplitterrects:= nil; + end; + fintf.getwidget.container.invalidate; +end; + +procedure tdockcontroller.checksplitdir(var asplitdir: splitdirty); +begin + if asplitdir = sd_none then begin + asplitdir:= fdefaultsplitdir; + end; + if not (od_splitvert in foptionsdock) and (asplitdir = sd_vert) then begin + asplitdir:= sd_none; + end; + if not (od_splithorz in foptionsdock) and (asplitdir = sd_horz) then begin + asplitdir:= sd_none; + end; + if not (od_tabed in foptionsdock) and (asplitdir = sd_tabed) then begin + asplitdir:= sd_none; + end; + if (asplitdir = sd_none) then begin + if od_splithorz in foptionsdock then begin + asplitdir:= sd_horz; + end + else begin + if od_splitvert in foptionsdock then begin + asplitdir:= sd_vert; + end + else begin + if od_tabed in foptionsdock then begin + asplitdir:= sd_tabed; + end; + end; + end; + end; +end; + +procedure tdockcontroller.setoptionsdock(const avalue: optionsdockty); +const + mask1: optionsdockty = [od_top,od_background]; + mask2: optionsdockty = [od_alignbegin,od_aligncenter,od_alignend]; + +var + splitdirbefore: splitdirty; + intf1: idocktarget; + cont1: tdockcontroller; + int1: integer; + val1,val2{,val3}: optionsdockty; + bo1: boolean; + optbefore: optionsdockty; +begin + if foptionsdock <> avalue then begin + optbefore:= foptionsdock; + bo1:= od_fixsize in foptionsdock; + splitdirbefore:= fsplitdir; + val1:= optionsdockty( + setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(avalue), + {$ifdef FPC}longword{$else}longword{$endif}(foptionsdock), + {$ifdef FPC}longword{$else}longword{$endif}(mask1))); + val2:= optionsdockty( + setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(avalue), + {$ifdef FPC}longword{$else}longword{$endif}(foptionsdock), + {$ifdef FPC}longword{$else}longword{$endif}(mask2))); + foptionsdock:= ((avalue - (mask1+mask2)) + val1*mask1 + val2*mask2) - + deprecatedoptionsdock; + if not (od_nofit in foptionsdock) then begin + if not (od_banded in optbefore) and (od_banded in foptionsdock) then begin + include(foptionsdock,od_nofit); + end + else begin + exclude(foptionsdock,od_banded); + end; + end; + if (od_banded in foptionsdock) and (foptionsdock * mask2 = []) then begin + include(foptionsdock,od_aligncenter); + end; + { + if bo1 xor (od_fixsize in foptionsdock) then begin + exclude(fdockstate,dos_proprefvalid); + end; + } + fuseroptions:= foptionsdock; + checksplitdir(fsplitdir); + with fintf.getwidget do begin + if od_top in foptionsdock then begin + optionswidget:= optionswidget + [ow_top]; + end + else begin + optionswidget:= optionswidget - [ow_top]; + end; + if od_background in foptionsdock then begin + optionswidget:= optionswidget + [ow_background]; + end + else begin + optionswidget:= optionswidget - [ow_background]; + end; + if not (csloading in componentstate) then begin + if (splitdirbefore <> fsplitdir) then begin + calclayout(nil,false); + with container do begin + if fsplitdir = sd_none then begin + for int1:= 0 to widgetcount - 1 do begin + with widgets[int1] do begin + if getcorbainterface(typeinfo(idocktarget),intf1) then begin + cont1:= intf1.getdockcontroller; + cont1.fmdistate:= mds_normal; + anchors:= [an_left,an_top]; + widgetrect:= cont1.fnormalrect; + end; + end; + end; + end; + end; + invalidate; + end + else begin + if (bo1 xor (od_fixsize in foptionsdock)) and + getparentcontroller(cont1) then begin + cont1.updaterefsize; + end; + end; + end; + end; + end; +end; + +{ +procedure tdockcontroller.invalidategripsize; + + procedure descend1(const awidget: twidget1); + var + int1: integer; + begin + if awidget.fframe is tgripframe then begin + with tgripframe(awidget.fframe) do begin + exclude(fgripstate,grps_sizevalid); + end; + end; + for int1:= 0 to awidget.widgetcount-1 do begin + descend1(twidget1(awidget.widgets[int1])); + end; + end; + + procedure descend2(const awidget: twidget1); + var + int1: integer; + begin + if awidget.fframe is tgripframe then begin + with tgripframe(awidget.fframe) do begin + internalupdatestate; + end; + end; + for int1:= 0 to awidget.widgetcount-1 do begin + descend2(twidget1(awidget.widgets[int1])); + end; + end; +var + widget1: twidget; + +begin //invalidategripsize + widget1:= fintf.getwidget; + if not (csloading in widget1.componentstate) then begin + descend1(twidget1(widget1)); + descend2(twidget1(widget1)); + end; +end; +} +procedure tdockcontroller.setuseroptions(const avalue: optionsdockty); + + +var + optbefore: optionsdockty; + widget1: twidget1; +begin + optbefore:= foptionsdock; + optionsdock:= optionsdockty(replacebits(longword(avalue), + longword(foptionsdock),longword(useroptionsmask))); + if (foptionsdock >< optbefore) * [od_lock,od_nolock] <> [] then begin + widget1:= twidget1(fintf.getwidget); + if not widget1.isloading then begin + widget1.parentchanged; + end; + end; +end; + +procedure tdockcontroller.splitterchanged; +begin + if not (csloading in fintf.getwidget.ComponentState) then begin + updatesplitterrects(checksplit); + end; +end; + +procedure tdockcontroller.checkdirection; +begin + if fsplitdir = sd_horz then begin + fr:= @rectaccessy; + fw:= @widgetaccessy; + end + else begin + fr:= @rectaccessx; + fw:= @widgetaccessx; + end; +end; + +function tdockcontroller.getparentcontroller( + out acontroller: tdockcontroller): boolean; +var + widget1: twidget; + intf1: idocktarget; +begin + result:= false; + acontroller:= nil; + widget1:= fintf.getwidget.parentwidget; + if widget1 <> nil then begin + if widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + acontroller:= intf1.getdockcontroller; + result:= true; + end; + end; +end; + +function tdockcontroller.getparentcontroller: tdockcontroller; +var + widget1: twidget; + intf1: idocktarget; +begin + result:= nil; + widget1:= fintf.getwidget.parentwidget; + if widget1 <> nil then begin + if widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + result:= intf1.getdockcontroller; + end; + end; +end; + +procedure tdockcontroller.updaterefsize; +var + int1: integer; + ar1: widgetarty; + ar2,ar3: booleanarty; +begin + if fsplitdir in [sd_vert,sd_horz] then begin + ar1:= checksplit(frefsize,int1,ar2,ar3,false); + setlength(fsizes,length(ar1)); + for int1:= 0 to high(ar1) do begin + fsizes[int1]:= fw^.size(ar1[int1]); + end; + end + else begin + fsizes:= nil; + end; +end; + +function tdockcontroller.calclayout(const dragobject: tdockdragobject; + const nonewplace: boolean): boolean; +var + rect1{,rect2}: rectty; + po1: pointty; + ar1: widgetarty; + int1{,int2}: integer; + step,stepsum,pos: real; + container1: twidget1; + widget1,widget2: twidget; + index: integer; + xorrect: rectty; + intf1: idocktarget; + propsize,varsize,fixsize,fixcount: integer; + prop,fix: booleanarty; + dirchanged: boolean; + newwidget: boolean; + controller1: tdockcontroller; + bo1: boolean; +label + endlab; +begin + result:= false; + container1:= twidget1(fintf.getwidget.container); + if container1.componentstate * [csdestroying,csdesigning] <> [] then begin + exit; + end; + checkdirection; + if (ftabwidget <> nil) and (fsplitdir = sd_tabed) then begin + include(fdockstate,dos_updating5); + int1:= 0; + while int1 <= high(container1.fwidgets) do begin + widget1:= container1.fwidgets[int1]; + if widget1.visible and (widget1 <> ftabwidget) then begin + tdocktabpage.create(tdocktabwidget(ftabwidget),widget1); + end + else begin + inc(int1); + end; + end; + exclude(fdockstate,dos_updating5); + end; + ar1:= checksplit; + if fasplitdir <> sd_none then begin + dirchanged:= fsplitdir <> fasplitdir; + fsplitdir:= fasplitdir; + fasplitdir:= sd_none; + end + else begin + dirchanged:= false; + end; + if (ar1 = nil) and (dragobject = nil) then begin + if fsplitdir = sd_none then begin + fsplitterrects:= nil; + end; + goto endlab; + end; + rect1:= fplacementrect;//idockcontroller(fintf).getplacementrect; + po1:= addpoint(pointty(rect1.size),rect1.pos); //lower right + include(fdockstate,dos_updating1); + if dragobject <> nil then begin + with dragobject do begin + widget1:= widget; + index:= findex; + xorrect:= fxorrect; + end; + end + else begin + widget1:= nil; + index:= 0; + end; + if (ftabwidget <> nil) and (fsplitdir <> sd_tabed) then begin + with tdocktabwidget(ftabwidget) do begin + for int1:= count - 1 downto 0 do begin + with tdocktabpage(items[int1]) do begin + widget2:= ftarget; + ftarget:= nil; + include(fdockstate,dos_tabedending); + try + widget2.anchors:= ftargetanchors; + widget2.parentwidget:= container1; + finally + exclude(fdockstate,dos_tabedending); + end; + end; + end; + freeandnil(ftabwidget); + end; + end; + if (widget1 <> nil) then begin + newwidget:= true; + if (widget1.parentwidget = container1) then begin + for int1:= 0 to high(ar1) do begin + if ar1[int1] = widget1 then begin + deleteitem(pointerarty(ar1),int1); + newwidget:= false; + break; + end; + end; + end + else begin + widget2:= widget1.parentwidget; + if fsplitdir <> sd_tabed then begin + widget1.size:= xorrect.size; + widget1.parentwidget:= container1; + if widget1.parentwidget <> container1 then begin + exit; //probably widget can not be defocused + end; + end; + if getparentcontroller(controller1) then begin + controller1.layoutchanged; //notify removing + end; + if (widget2 <> nil) and widget2.getcorbainterface(typeinfo(idocktarget),intf1) then begin + intf1.getdockcontroller.layoutchanged; + end; + end; + end + else begin + newwidget:= false; + end; + if (length(ar1) > 0) or (widget1 <> nil) then begin + step:= 0; //compiler warning + stepsum:= 0; + if (fsplitdir <> sd_none) then begin + if (widget1 <> nil) then begin + if index > length(ar1) then begin + index:= length(ar1); + end; + insertitem(pointerarty(ar1),index,widget1); + if nofit then begin +// if not newwidget then begin + fr^.setosize(fsizingrect,fw^.osize(widget1)); + //don't change height +// end; + widget1.widgetrect:= fsizingrect; + end; + end; + if fsplitdir = sd_tabed then begin //use all children + checksplit(ar1,propsize,varsize,fixsize,fixcount,prop,fix,false); + end + else begin //use visible children only + ar1:= checksplit(ar1,propsize,varsize,fixsize,fixcount,prop,fix,false); + end; + if dirchanged or (propsize = 0) and newwidget then begin + for int1:= 0 to high(prop) do begin //split even + prop[int1]:= true; + fix[int1]:= false; + propsize:= fixsize + propsize; + fixsize:= 0; + varsize:= 0; + fixcount:= 0; + end; + end; + if fixcount < length(ar1) then begin + if fsplitdir = sd_horz then begin + step:= rect1.cy; + end + else begin + step:= rect1.cx; + end; + stepsum:= (step - fixsize + varsize - fsplitter_size * high(ar1)); + if stepsum < 0 then begin + stepsum:= 0; + end; + step:= stepsum /(length(ar1) - fixcount); + end; + end; + case fsplitdir of + sd_vert,sd_horz: begin + if not nonewplace and not nofit then begin + pos:= fr^.pos(rect1); + bo1:= round(stepsum) = propsize+varsize; //no change if size matches + for int1:= 0 to high(ar1) do begin + fr^.setpos(rect1,round(pos)); + if prop[int1] and not bo1 then begin + pos:= pos + step; + end + else begin + pos:= pos + fw^.size(ar1[int1]); + end; + if int1 = high(ar1) then begin + fr^.setsize(rect1,fr^.pt(po1) - fr^.pos(rect1)); + end + else begin + fr^.setsize(rect1,round(pos) - fr^.pos(rect1)); + end; + ar1[int1].widgetrect:= rect1; + pos:= pos + fsplitter_size; + end; + end; + end; + sd_tabed: begin + include(fdockstate,dos_updating5); + try + fsplitterrects:= nil; + if ftabwidget = nil then begin + ftabwidget:= tdocktabwidget.create(self,container1); + include(ttabwidget1(ftabwidget).foptionswidget1,ow1_noautosizing); + ftabwidget.anchors:= [an_left,an_right,an_top,an_bottom]; + end; + with tdocktabwidget(ftabwidget) do begin + widgetrect:= fplacementrect; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] <> ftabwidget) and + ((ar1[int1].parentwidget = nil) or + (ar1[int1].parentwidget.parentwidget <> ftabwidget)) then begin + tdocktabpage.create(tdocktabwidget(ftabwidget),ar1[int1]); + end; + end; + end; + finally + exclude(fdockstate,dos_updating5); + end; + end; + else begin + if widget1 <> nil then begin + widget1.parentwidget:= container1; + widget1.widgetrect:= translatewidgetrect(xorrect,nil,container1); + end; + end; + end; + end; + exclude(fdockstate,dos_updating1); + sizechanged(true,false,ar1); + updatesplitterrects(ar1); +endlab: + widget1:= fintf.getwidget; + if widget1.canevent(tmethod(foncalclayout)) and + not application.terminated then begin + foncalclayout(widget1,ar1); + end; + dolayoutchanged; + result:= true; +end; + +procedure tdockcontroller.updateminscrollsize(var asize: sizety); +var + rect1: rectty; + ar1: widgetarty; + int1,int2: integer; + bandlength,bandsize: integer; + placementlength{,placementsize}: integer; + maxlength,maxsize: integer; + bo1: boolean; + firstband: boolean; +begin + if (od_banded in optionsdock) and nofit then begin + if (fsplitdir = sd_vert) then begin + ar1:= fintf.getwidget.getsortxchildren(true); + end + else begin + ar1:= fintf.getwidget.getsortychildren(true); + end; + rect1:= idockcontroller(fintf).getplacementrect(); + placementlength:= fr^.size(rect1); +// placementsize:= fr^.osize(rect1); + bandlength:= 0; + bandsize:= 0; + maxlength:= 0; + maxsize:= 0; + bo1:= true; + firstband:= true; + for int1:= 0 to high(ar1) do begin + int2:= fw^.size(ar1[int1])+fsplitter_size; + bandlength:= bandlength+int2; + if bandlength >{=} placementlength then begin //next band + if not bo1 then begin //shift to next band + bandlength:= bandlength - int2; + if bandlength > maxlength then begin + maxlength:= bandlength; + end; + bandlength:= int2; + bandsize:= bandsize+maxsize; + if not firstband then begin + bandsize:= bandsize + fbandgap; + end; + maxsize:= fw^.osize(ar1[int1]); + end + else begin //at least one widget + if bandlength > maxlength then begin + maxlength:= bandlength; + end; + bandsize:= bandsize + fw^.osize(ar1[int1]); + if not firstband and (int1 < high(ar1)) then begin + bandsize:= bandsize + fbandgap; + end; + bandlength:= 0; + maxsize:= 0; + bo1:= true; //first widget of band + end; + firstband:= false; + end + else begin + bo1:= false; //not first widget of band + if bandlength > maxlength then begin + maxlength:= bandlength; + end; + int2:= fw^.osize(ar1[int1]); + if int2 > maxsize then begin + maxsize:= int2; + end; + end; + end; + bandsize:= bandsize+maxsize; + if not firstband then begin + bandsize:= bandsize + fbandgap; + end; + fr^.setsize(rect1,maxlength); + fr^.setosize(rect1,bandsize); + if rect1.cx > asize.cx then begin + asize.cx:= rect1.cx; + end; + if rect1.cy > asize.cy then begin + asize.cy:= rect1.cy; + end; + end; +end; + +function tdockcontroller.nofit: boolean; +begin + result:= (od_nofit in foptionsdock) and (fsplitdir in [sd_vert,sd_horz]); +end; + +function tdockcontroller.dockdrag(const dragobj: tdockdragobject): boolean; +var + parentbefore: tdockcontroller; +begin + dragobj.fdock.getparentcontroller(parentbefore); + result:= false; + if calclayout(tdockdragobject(dragobj),false) then begin + updaterefsize; + result:= dragobj.fdock.dodock(parentbefore); + end; +end; + +procedure tdockcontroller.childstatechanged(const sender: twidget; + const newstate: widgetstatesty; const oldstate: widgetstatesty); +var + dock1: tdockcontroller; +begin + if getparentcontroller(dock1) then begin + dock1.childstatechanged(sender,newstate,oldstate); + end; +end; + +function tdockcontroller.beforedragevent(var info: draginfoty): boolean; + +var + widget1: twidget; + container1: twidget; + rect1: rectty; + size1: sizety; + count1: integer; + sd1: splitdirty; + int1,int2: integer; + mouseinhandle: boolean; + ischild1: boolean; + + function checkaccept: boolean; + var + intf1: idocktarget; + widget2: twidget; + begin + ischild1:= false; + result:= (info.dragobjectpo^ is tdockdragobject); + if result then begin + ischild1:= + (tdockdragobject(info.dragobjectpo^).fdock.getparentcontroller = self); + result:= ischild1 or + (od_acceptsdock in foptionsdock) and + (od_candock in tdockdragobject(info.dragobjectpo^).fdock.foptionsdock); + end; + if result and not mouseinhandle and (od_dockparent in foptionsdock) and + not widget1.checkdescendent( + tdockdragobject(info.dragobjectpo^).fdock.fintf.getwidget) then begin + widget2:= widget1.parentwidget; + while widget2 <> nil do begin + if widget2.getcorbainterface(typeinfo(idocktarget),intf1) and + (od_acceptsdock in intf1.getdockcontroller.foptionsdock) then begin + result:= false; + break; + end; + widget2:= widget2.parentwidget; + end; + end; + end; + + procedure adjustdockrect; + var + nofit: boolean; + rect2: rectty; + pt1: pointty; + x1,y1: integer; + f1: flo64; + begin + with info,tdockdragobject(dragobjectpo^) do begin + nofit:= (od_nofit in optionsdock) and (fsplitdir in [sd_vert,sd_horz]); + if (fcheckeddockcontroller <> self) then begin + if fcheckeddockcontroller <> nil then begin + fcheckeddockcontroller.fasplitdir:= sd_none; + end; + fcheckeddockcontroller:= self; + end; + if fasplitdir = sd_none then begin + fasplitdir:= fsplitdir; + end; + if not widget.checkdescendent(widget1) and + idockcontroller(fintf).checkdock(info) and + docheckdock(info) then begin + accept:= true; + rect1:= makerect(pos,widget.size); + addpoint1(rect1.pos,widget1.clientwidgetpos); + addpoint1(rect1.pos,widget1.screenpos); + subpoint1(rect1.pos,addpoint(pickpos,widget.clientwidgetpos)); + if not nofit then begin +// size1:= widget1.clientsize; +// pt1:= addpoint(info.pos,container1.clientpos); //paint origin + pt1:= subpoint(info.pos,fplacementrect.pos); //paint origin +// size1:= container1.paintsize; + size1:= fplacementrect.size; + with size1 do begin + x1:= cx div 8; + y1:= (cy * 7) div 8; + end; + if (od_splitvert in foptionsdock) and + (pt1.x < x1) and (pt1.y < y1) then begin + fasplitdir:= sd_vert; + end + else begin + if (od_splithorz in foptionsdock) and + (pt1.y > y1) and (pt1.x > x1) then begin + fasplitdir:= sd_horz; + end + else begin + if (od_tabed in foptionsdock) and + (pt1.x > (size1.cx * 7) div 16) and + (pt1.x < (size1.cx * 9) div 16) and + (pt1.y > (size1.cy * 7) div 16) and + (pt1.y < (size1.cy * 9) div 16) then begin + fasplitdir:= sd_tabed; + end; + end; + end; +// size1:= container1.paintsize; + size1:= fplacementrect.size; + if (widget.anchors * [an_left,an_right] = []) and + (fsplitdir = sd_none) then begin + rect1.x:= container1.screenpos.x + fplacementrect.x; + //container1.paintpos.x; + rect1.cx:= size1.cx; + end; + if (widget.anchors * [an_top,an_bottom] = []) and + (fsplitdir = sd_none) then begin + rect1.y:= container1.screenpos.y + fplacementrect.y; + //container1.paintpos.y; + rect1.cy:= size1.cy; + end; + sd1:= fsplitdir; + fsplitdir:= fasplitdir; + count1:= length(checksplit); + fsplitdir:= sd1; + if (widget.parentwidget <> container1) and + not widget1.checkdescendent(ftabwidget) then begin + inc(count1); + end; + findex:= count1-1; + case fasplitdir of + sd_vert: begin + rect1.y:= container1.screenpos.y + fplacementrect.y; + //container1.paintpos.y; + rect1.cy:= size1.cy; + if count1 = 0 then begin + exit; //should not happen + end; + f1:= size1.cx / count1; + rect1.cx:= size1.cx div count1; + if rect1.cx > 0 then begin + findex:= (pt1.x div rect1.cx); + rect1.x:= round(findex * f1) + + container1.screenpos.x + fplacementrect.x; + //container1.paintpos.x; + end; + if count1 = 1 then begin + dec(rect1.cx,rect1.cx div 16); + end; + end; + sd_horz: begin + rect1.x:= container1.screenpos.x + fplacementrect.x; + //container1.paintpos.x; + rect1.cx:= size1.cx; + if count1 = 0 then begin + exit; //should not happen + end; + f1:= size1.cy / count1; + rect1.cy:= size1.cy div count1; + if rect1.cy > 0 then begin + findex:= (pt1.y div rect1.cy); + rect1.y:= round(findex * f1) + + container1.screenpos.y + fplacementrect.y; + //container1.paintpos.y; + end; + if count1 = 1 then begin + int1:= rect1.cy div 16; + dec(rect1.cy,int1); + inc(rect1.y,int1); + end; + end; + sd_tabed: begin + int1:= size1.cy div 16; + int2:= size1.cx div 16; + if int2 < int1 then begin + int1:= int2; + end; + rect1:= inflaterect(fplacementrect + {idockcontroller(fintf).getplacementrect},-int1); + translatewidgetpoint1(rect1.pos,container1,nil); + end; + end; + if fasplitdir = sd_none then begin +// subpoint1(rect1.pos,widget.paintpos); + if widget1 <> container1 then begin +// addpoint1(rect1.pos,subpoint(widget1.paintpos,widget.paintpos)); +// subpoint1(rect1.pos,container1.pos); + end; + setxorwidget(container1,clipinrect(rect1, + makerect(translatewidgetpoint(container1.clientwidgetpos, + container1,nil),container1.maxclientsize))); + end + else begin + setxorwidget(container1,clipinrect(rect1, + makerect(translatewidgetpoint(fplacementrect.pos{container1.paintpos}, + container1,nil),size1))); + end; + end + else begin //nofit +// pt1:= translateclientpoint(rect1.pos,nil,container1); + pt1:= addpoint(info.pos,widget1.paintpos); + if findbandwidget(pt1,int1,rect2) then begin + findex:= int1; + fr^.setsize(rect2,fr^.size(rect1)); + fsizingrect:= rect2; + translatewidgetpoint1(rect2.pos,container1,nil); + setxorwidget(container1,rect2); + end; + end; + result:= true; + end; + end; + end; + + procedure dockwidget; + begin + with info,tdockdragobject(dragobjectpo^) do begin + if container1 = fxorwidget then begin + with tdockdragobject(dragobjectpo^).fdock do begin + if fmdistate = mds_floating then begin + fmdistate:= mds_normal; + end + else begin + if fmdistate = mds_maximized then begin + fnormalrect:= widget1.widgetrect; + mdistate:= mds_normal; + end; + end; + translatewidgetpoint1(fsizingrect.pos,nil,container1); + //used incalclayout + end; + fsizes:= nil; + dockdrag(tdockdragobject(dragobjectpo^)); + { + calclayout(tdockdragobject(dragobjectpo^),false); + updaterefsize; + tdockdragobject(dragobjectpo^).fdock.dodock; +// dochilddock(widget); +} + result:= true; + end; + end; + end; + +begin + widget1:= fintf.getwidget; + container1:= widget1.container; + result:= false; + ischild1:= false; + if not(csdesigning in widget1.ComponentState) then begin + with info do begin + if fdockhandle <> nil then begin + mouseinhandle:= (fdockhandle <> nil) and + pointinrect(translateclientpoint(info.pos, + idockcontroller(fintf).getwidget,fdockhandle),fdockhandle.gethandlerect); + end + else begin + mouseinhandle:= + pointinrect({widget1.clientpostowidgetpos(}info.pos{)}, + idockcontroller(fintf).getbuttonrects(dbr_handle)); + end; +// mouseinhandle:= (fdockhandle <> nil) and pointinrect( +// translateclientpoint(info.pos,idockcontroller(fintf).getwidget,fdockhandle), +// fdockhandle.gethandlerect) or +// pointinrect({widget1.clientpostowidgetpos(}info.pos{)}, +// idockcontroller(fintf).getbuttonrects(dbr_handle)); + case eventkind of + dek_begin: begin + if mouseinhandle then begin + if (widget1.parentwidget <> nil) then begin + if od_canmove in foptionsdock then begin + tdockdragobject.create(self,widget1,dragobjectpo^,fpickpos); + result:= true; + end + else begin + if canfloat and not (dos_hasfloatbutton in fdockstate) and + not(csdesigning in widget1.componentstate) then begin + dofloat(nullpoint); + result:= true; + end; + end; + end + else begin + if (od_candock in foptionsdock) and (widget1.parentwidget = nil) and + (dragobjectpo^ = nil) then begin + tdockdragobject.create(self,widget1,dragobjectpo^,fpickpos); + result:= true; + end; + end; + if result then begin + fclickedbutton:= dbr_none; + end; + end + end; + dek_check: begin + if checkaccept then begin + adjustdockrect; + end; + end; + dek_drop: begin + if checkaccept and (not ischild1 or + (tdockdragobject(info.dragobjectpo^).fdock.fmdistate <> + mds_maximized)) then begin + dockwidget; + end; + end; + end; + end; + end; + if not result then begin + result:= inherited beforedragevent(info); + end; +end; + +procedure tdockcontroller.setdockhandle(const avalue: tdockhandle); +begin + if fdockhandle <> nil then begin + fdockhandle.fcontroller:= nil; + end; + setlinkedvar(avalue,tmsecomponent(fdockhandle)); + if fdockhandle <> nil then begin + fdockhandle.fcontroller:= self; + end; +end; + +function tdockcontroller.dodock(const oldparent: tdockcontroller): boolean; +var + widget1: twidget1; + int1: integer; + controller1: tdockcontroller; +begin + widget1:= twidget1(fintf.getwidget); + inc(floatdockcount); + int1:= floatdockcount; + if widget1.canevent(tmethod(fondock)) then begin + fondock(widget1); + end; + if floatdockcount = int1 then begin + if getparentcontroller(controller1) then begin + if (fmdistate <> mds_minimized) or (oldparent <> controller1) then begin + fmdistate:= mds_normal; + end; + if oldparent <> controller1 then begin + controller1.dochilddock(widget1); + end; + end; + end; + result:= floatdockcount = int1; +end; + +function tdockcontroller.dofloat(const adist: pointty): boolean; +var + widget1: twidget1; + wstr1: msestring; + int1: integer; + controller1: tdockcontroller; + rect1: rectty; +begin + widget1:= twidget1(fintf.getwidget); + if widget1.parentwidget = nil then begin + result:= true; + end + else begin + result:= false; + getparentcontroller(controller1); + with widget1 do begin + if not (fmdistate in [mds_normal,mds_floating]) then begin + rect1.pos:= translatewidgetpoint(fnormalrect.pos,parentwidget,nil); + rect1.size:= fnormalrect.size; + end + else begin + rect1.pos:= screenpos; + rect1.size:= size; + end; + addpoint1(rect1.pos,adist); + if canevent(tmethod(fonbeforefloat)) then begin + fonbeforefloat(widget1,rect1); + end; + parentwidget:= nil; + if parentwidget <> nil then begin + exit; + end; + widgetrect:= rect1; + if fmdistate = mds_maximized then begin + anchors:= [an_left,an_top]; + end; + end; + fmdistate:= mds_floating; + // widget1.pos:= addpoint(widget1.pos,adist); + wstr1:= getfloatcaption; + if wstr1 <> '' then begin + widget1.window.caption:= wstr1; + end; + updategrip(sd_none,widget1); + inc(floatdockcount); + int1:= floatdockcount; + if widget1.canevent(tmethod(fonfloat)) then begin + fonfloat(widget1); + end; + if (floatdockcount = int1) and (controller1 <> nil) then begin + fhiddensizeref:= nullsize; + controller1.dochildfloat(widget1); + widget1.activate; + end; + result:= floatdockcount = int1; + if result then begin + dolayoutchanged(); + end; + end; +end; + +function tdockcontroller.float(): boolean; + //false if canceled +begin + result:= dofloat(nullpoint); +end; + +function tdockcontroller.dockto(const dest: tdockcontroller; + const apos: pointty): boolean; +var + dragobj: tdockdragobject; + widget1: twidget; +begin + dragobj:= nil; + widget1:= fintf.getwidget; + dragobj:= tdockdragobject.create(self,widget1,tdragobject(dragobj),nullpoint); + try + with dragobj.fxorrect do begin + size:= widget1.size; + widget1:= dest.fintf.getwidget.container; + pos:= translatewidgetpoint(apos,widget1,nil); + addpoint1(pos,widget1.clientwidgetpos); +// addpoint1(dragobj.fxorrect.pos,dest.fplacementrect.pos); + result:= dest.dockdrag(dragobj); + end; + finally + dragobj.free; + end; +end; + +function tdockcontroller.canfloat: boolean; +begin + result:= (od_canfloat in foptionsdock) and + not (ismdi and (mdistate = mds_minimized)) +end; + +function tdockcontroller.nogrip: boolean; +var + parent: tdockcontroller; +begin + result:= (od_lock in foptionsdock) or + not (od_nolock in foptionsdock) and getparentcontroller(parent) and + parent.nogrip; +end; + +procedure tdockcontroller.refused(const apos: pointty); +var + widget1: twidget; + intf1: idocktarget; + dir1: splitdirty; +begin + if canfloat and not (dos_hasfloatbutton in fdockstate) then begin + widget1:= fintf.getwidget.parentwidget; + dir1:= sd_none; //compiler warning + if widget1 <> nil then begin + if widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + with intf1.getdockcontroller do begin + dir1:= fasplitdir; + fasplitdir:= fsplitdir; //no change of dir in calclayout + end; + end; + dofloat(subpoint(apos,translateclientpoint(fpickpos,fintf.getwidget,nil))); + if intf1 <> nil then begin + with intf1.getdockcontroller do begin + fasplitdir:= dir1; + end; + end; + end; + end; +end; + +procedure tdockcontroller.dochilddock(const awidget: twidget); +var + widget1: twidget1; +begin + widget1:= twidget1(fintf.getwidget); + if widget1.canevent(tmethod(fonchilddock)) then begin + fonchilddock(widget1,awidget); + end; +end; + +procedure tdockcontroller.dochildfloat(const awidget: twidget); +var + widget1: twidget1; +begin + widget1:= twidget1(fintf.getwidget); + if widget1.canevent(tmethod(fonchildfloat)) then begin + fonchildfloat(widget1,awidget); + end; +end; + +procedure tdockcontroller.domdistatechanged(const oldstate,newstate: mdistatety); +var + widget1: twidget1; +begin + widget1:= twidget1(fintf.getwidget); + if widget1.canevent(tmethod(fonmdistatechanged)) then begin + fonmdistatechanged(widget1,oldstate,newstate); + end; +end; + +function tdockcontroller.docheckdock(const info: draginfoty): boolean; +var + widget1: twidget1; +begin + widget1:= twidget1(fintf.getwidget); + if widget1.canevent(tmethod(foncheckdock)) then begin + result:= false; + foncheckdock(widget1,info.pos,tdockdragobject(info.dragobjectpo^),result); + end + else begin + result:= true; + end; +end; + +procedure tdockcontroller.enddrag; +begin + if fdragobject is tdockdragobject then begin + with tdockdragobject(fdragobject) do begin + if fxorwidget <> nil then begin + fxorwidget.invalidatewidget; + end; + end; + end; + inherited; +end; + +procedure tdockcontroller.beginplacement(); +begin + if fplacing = 0 then begin + include(fdockstate,dos_updating4); + end; + inc(fplacing); +end; + +procedure tdockcontroller.endplacement(); +var + int1,int2,int3: integer; + str1: string; + widget1: twidget; +begin + dec(fplacing); + if fplacing = 0 then begin + exclude(fdockstate,dos_updating4); + sizechanged(true); + calclayout(nil,true); + if (ftaborder <> nil) then begin + if (fsplitdir = sd_tabed) and (ftabwidget <> nil) then begin + int3:= 0; + for int1:= 0 to high(ftaborder) do begin + str1:= ansistring(ftaborder[int1]); + for int2:= int3 to tdocktabwidget(ftabwidget).count - 1 do begin + widget1:= tdocktabpage(tdocktabwidget(ftabwidget)[int2]).ftarget; + if (widget1 <> nil) and (widget1.Name = str1) then begin + tdocktabwidget(ftabwidget).movepage(int2,int3); + inc(int3); + break; + end; + end; + end; + if factivetab < tdocktabwidget(ftabwidget).count then begin + tdocktabwidget(ftabwidget).activepageindex:= factivetab; + end; + end; + ftaborder:= nil; + end; + end; +end; + + //istatfile +procedure tdockcontroller.statreading; +begin + beginplacement(); +// include(fdockstate,dos_updating4); +end; + +procedure tdockcontroller.statread; +begin + fsize:= idockcontroller(fintf).getplacementrect.size; + endplacement(); +// exclude(fdockstate,dos_updating4); +// calclayout(nil,true); +end; + +function tdockcontroller.getdockcaption: msestring; +begin + if fcaption = '' then begin + result:= idockcontroller(fintf).getcaption; + end + else begin + result:= fcaption + end; +end; + +function tdockcontroller.getfloatcaption: msestring; +begin + result:= idockcontroller(fintf).getcaption; + if result = '' then begin + result:= fcaption + end; +end; + +procedure tdockcontroller.readchildrencount(const acount: integer); +begin + setlength(fchildren,acount); +end; + +procedure tdockcontroller.readchild(const index: integer; + const avalue: msestring); +var + na: ansistring; + rect1,rect2: rectty; + w1: twidget; +begin + decoderecord(avalue,[@na,@rect1.x,@rect1.y,@rect1.cx,@rect1.cy],'siiii'); + with fintf.getwidget do begin + w1:= findchild(na); + fchildren[index]:= na; + if w1 <> nil then begin + rect2:= application.screenrect(window); + shiftinrect(rect1,rect2); + clipinrect(rect1,rect2); + w1.widgetrect:= rect1; + end; + end; +end; + +procedure tdockcontroller.dostatplace(const aparent: twidget; + const avisible: boolean; arect: rectty); +var + intf1: idocktarget; + widget0: twidget; +begin + widget0:= fintf.getwidget(); + with widget0 do begin + if not avisible then begin + visible:= false; + end; + if (aparent <> nil) and + aparent.getcorbainterface(typeinfo(idocktarget), + intf1) then begin + intf1.getdockcontroller.frefsize:= 0; //invalid + end; + parentwidget:= aparent; + if (parentwidget <> nil) then begin + if not parentwidget.getcorbainterface(typeinfo(idocktarget), + intf1) then begin + arect:= clipinrect(arect,parentwidget.paintrect); //shift into widget + end; + widgetrect:= arect; + end + else begin + updategrip(sd_none,widget0); + arect:= clipinrect(arect,application.screenrect); //shift into screen + widgetrect:= arect; + application.postevent(tobjectevent.create(ek_checkscreenrange, + ievent(widget0))); + end; + visible:= avisible; + end; +end; + +procedure tdockcontroller.updatetabpage(const sender: ttabpage); +begin + ftabpage:= sender; + sender.caption:= getdockcaption; + if fcolortab <> cl_default then begin + sender.colortab:= fcolortab; + end; + if fcoloractivetab <> cl_default then begin + sender.coloractivetab:= fcoloractivetab; + end; + sender.facetab:= ffacetab; + sender.faceactivetab:= ffaceactivetab; +end; + +procedure tdockcontroller.dostatread(const reader: tstatreader); +var + rect1: rectty; + widget0,widget1: twidget; + str1: string; + bo1: boolean; +begin + if not (od_banded in foptionsdock) then begin + fsplitdir:= splitdirty(reader.readinteger('splitdir',ord(fsplitdir), + 0,ord(high(splitdirty)))); + end; + useroptions:= optionsdockty(longword( + reader.readinteger('useroptions',integer(longword(fuseroptions))))); +// setoptionsdock(foptionsdock); //check valid values + ftaborder:= reader.readarray('order',msestringarty(nil)); + factivetab:= reader.readinteger('activetab',0); + widget0:= fintf.getwidget; + with widget0 do begin + if od_savepos in foptionsdock then begin + if parentwidget = nil then begin + str1:= ''; + end + else begin + str1:= ownernamepath(parentwidget); + end; + str1:= reader.readstring('parent',str1); + fmdistate:= mdistatety(reader.readinteger('mdistate',ord(fmdistate))); + with fnormalrect do begin + x:= reader.readinteger('nx',x); + y:= reader.readinteger('ny',y); + cx:= reader.readinteger('ncx',cx,0); + cy:= reader.readinteger('ncy',cy,0); + end; + rect1:= widgetrect; + with rect1 do begin + x:= reader.readinteger('x',x); + y:= reader.readinteger('y',y); + cx:= reader.readinteger('cx',cx,0); + cy:= reader.readinteger('cy',cy,0); + end; + with fhiddensizeref do begin + cx:= reader.readinteger('rcx',cx); + cy:= reader.readinteger('rcy',cy); + end; + bo1:= visible; + bo1:= reader.readboolean('visible',bo1); + application.findwidget(str1,widget1); + dostatplace(widget1,bo1,rect1); + end; + if od_savechildren in foptionsdock then begin + ffocusedchild:= reader.readinteger('focusedchild',-1); + reader.readrecordarray('children',{$ifdef FPC}@{$endif}readchildrencount, + {$ifdef FPC}@{$endif}readchild); + if fchildren <> nil then begin + application.postevent(tchildorderevent.create(self)); + fchildren:= nil; + end; + end; + if (parentwidget = nil) and (od_savezorder in foptionsdock) then begin + str1:= '~'; + str1:= reader.readstring('stackedunder',str1); + if str1 <> '~' then begin + if trim(str1) = '' then begin + window.stackunder(nil); + end + else begin + if application.findwidget(str1,widget1) and (widget1 <> nil) then begin + window.stackunder(widget1.window); + end; + end; + end; + window.caption:= getfloatcaption; + end; + end; +end; + +procedure tdockcontroller.dock(const source: tdockcontroller; + const arect: rectty); +var + child1,parent1: twidget; +begin + fhiddensizeref:= arect.size; + fnormalrect:= arect; + child1:= source.getwidget(); + parent1:= getwidget().container; + source.dostatplace(parent1,child1.visible,arect); +end; + +function tdockcontroller.writechild(const index: integer): msestring; +begin + with twidget1(fintf.getwidget).container.widgets[index] do begin + result:= encoderecord([name,bounds_x,bounds_y,bounds_cx,bounds_cy]); + if entered then begin + ffocusedchild:= index; + end; + end; +end; + +procedure tdockcontroller.dostatwrite(const writer: tstatwriter; + const bounds: prectty = nil); +var + str1: string; + window1: twindow; + tabed: boolean; + ar1: msestringarty; + int1: integer; + po1: prectty; +begin + str1:= ''; + writer.writeinteger('splitdir',ord(fsplitdir)); + writer.writeinteger('useroptions', + {$ifdef FPC}longword{$else}longword{$endif}(fuseroptions)); + if ftabwidget <> nil then begin + with tdocktabwidget(ftabwidget) do begin + setlength(ar1,count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= msestring(tdocktabpage(items[int1]).ftarget.Name); + end; + writer.writearray('order',ar1); + writer.writeinteger('activetab',activepageindex); + end; + end; + with twidget1(fintf.getwidget) do begin + if od_savezorder in foptionsdock then begin + if parentwidget = nil then begin + str1:= ''; + window1:= window.stackedunder; + if window1 <> nil then begin + writer.writestring('stackedunder',ownernamepath(window1.owner)); + end + else begin + writer.writestring('stackedunder',''); + end; + end; + end; + if od_savepos in foptionsdock then begin + tabed:= (parentwidget is tdocktabpage) and (parentwidget.parentwidget <> nil); + if parentwidget <> nil then begin + if tabed then begin + str1:= ownernamepath(parentwidget.parentwidget.parentwidget); + end + else begin + str1:= ownernamepath(parentwidget); + end; + end; + writer.writestring('parent',str1); + po1:= bounds; + if po1 = nil then begin + po1:= @fwidgetrect; + writer.writeboolean('visible',visible); + end; + writer.writeinteger('mdistate',ord(fmdistate)); + writer.writeinteger('nx',fnormalrect.x); + writer.writeinteger('ny',fnormalrect.y); + writer.writeinteger('ncx',fnormalrect.cx); + writer.writeinteger('ncy',fnormalrect.cy); + writer.writeinteger('x',po1^.x); + writer.writeinteger('y',po1^.y); + writer.writeinteger('cx',po1^.cx); + writer.writeinteger('cy',po1^.cy); + with fhiddensizeref do begin + writer.writeinteger('rcx',cx); + writer.writeinteger('rcy',cy); + end; + end; + if od_savechildren in foptionsdock then begin + writer.writerecordarray('children',container.widgetcount, + {$ifdef FPC}@{$endif}writechild); + writer.writeinteger('focusedchild',ffocusedchild); + end; + end; +end; + +procedure tdockcontroller.setsplitter_size(const Value: integer); +begin + if value <> fsplitter_size then begin + fsplitter_size := Value; + layoutchanged; + end; +end; + +procedure tdockcontroller.setsplitter_setgrip(const Value: stockbitmapty); +begin + if fsplitter_grip <> value then begin + fsplitter_grip:= Value; + splitterchanged; + end; +end; + +procedure tdockcontroller.setsplitter_color(const Value: colorty); +begin + if fsplitter_color <> value then begin + fsplitter_color := Value; + splitterchanged; + end; +end; + +procedure tdockcontroller.setsplitter_colorgrip(const Value: colorty); +begin + if fsplitter_colorgrip <> value then begin + fsplitter_colorgrip := Value; + splitterchanged; + end; +end; + +procedure tdockcontroller.setbandgap(const avalue: integer); +begin + if fbandgap <> avalue then begin + fbandgap:= avalue; + layoutchanged; + end; +end; + +procedure tdockcontroller.layoutchanged; +begin + if not (csloading in fintf.getwidget.ComponentState) then begin + calclayout(nil,false); + end; +end; + +procedure tdockcontroller.setpickshape(const ashape: cursorshapety); +begin + with fintf.getwidget do begin + if not (ds_cursorshapechanged in fstate) then begin + fcursorbefore:= cursor; + include(fstate,ds_cursorshapechanged); + end; + cursor:= ashape; + end; +end; + +procedure tdockcontroller.restorepickshape; +begin + if ds_cursorshapechanged in fstate then begin + fintf.getwidget.cursor:= fcursorbefore; + exclude(fstate,ds_cursorshapechanged); + end; +end; + +function tdockcontroller.checkbuttonarea(const apos: pointty): dockbuttonrectty; +var + dbr1: dockbuttonrectty; +begin + result:= dbr_none; + for dbr1:= dbr_firstbutton to dbr_lastbutton do begin + if pointinrect(apos,idockcontroller(fintf).getbuttonrects(dbr1)) then begin + result:= dbr1; + break; + end; + end; + if (result = dbr_none) then begin + if fdockhandle <> nil then begin + if pointinrect(apos,fdockhandle.paintparentrect) then begin + result:= dbr_handle; + end; + end + else begin + if pointinrect(apos, + idockcontroller(fintf).getbuttonrects(dbr_handle)) then begin + result:= dbr_handle; //handle rect can include buttons + end; + end; + end; +end; + +function tdockcontroller.findbandpos(const apos: integer; out aindex: integer; + out arect: rectty): boolean; +var + int1,int2: integer; +begin + result:= false; + int2:= fbandstart; + for int1:= 0 to high(fbands) do begin + with fbands[int1] do begin + if (apos >= int2) and (apos < int2 + size) then begin + result:= true; + aindex:= int1; + fr^.setopos(arect,int2); + fr^.setosize(arect,size); + fr^.setpos(arect,fr^.pos(fplacementrect)); + fr^.setsize(arect,fr^.size(fplacementrect)); + break; + end; + int2:= int2 + size + fbandgap; + end; + end; +end; + +function tdockcontroller.findbandwidget(const apos: pointty; out aindex: integer; + out arect: rectty): boolean; + //false if not found. widget index and widget rect +var + ar1: widgetarty; + int1,int2,int3,int4,int5: integer; +begin + result:= findbandpos(fr^.opt(apos),int4,arect); + if result then begin + ar1:= checksplit; + aindex:= -1; + if ar1 <> nil then begin + int3:= fr^.pos(arect); + int5:= fr^.pt(apos); + with fbands[int4] do begin + aindex:= last; + for int1:= first to last - 1 do begin + int2:= fw^.size(ar1[int1]) + fsplitter_size; + if int3 + int2 >= int5 then begin + aindex:= int1; + break; + end; + int3:= int3 + int2; + end; + end; + fr^.setpos(arect,int3); + fr^.setsize(arect,fw^.size(ar1[aindex])); + end; + end; +end; + +function tdockcontroller.findbandindex(const widgetindex: integer; out aindex: integer; + out arect: rectty): boolean; +var + int1,int2: integer; +begin + result:= false; + int2:= fbandstart; + for int1:= 0 to high(fbands) do begin + with fbands[int1] do begin + if last >= widgetindex then begin + result:= true; + aindex:= int1; + fr^.setopos(arect,int2); + fr^.setosize(arect,size); + fr^.setpos(arect,fr^.pos(fplacementrect)); + fr^.setsize(arect,fr^.size(fplacementrect)); + break; + end; + int2:= int2 + size + fbandgap; + end; + end; +end; + +function tdockcontroller.doclose(const awidget: twidget): boolean; +begin + result:= simulatemodalresult(awidget,mr_windowclosed); +end; + +function tdockcontroller.canbegindrag: boolean; +begin + result:= (fdockstate * [dos_moving,dos_sizing,dos_xorpic] = []) and + not ((fmdistate = mds_maximized) and not (od_canfloat in foptionsdock)); +end; + +procedure tdockcontroller.drawxorpic(const ashow: boolean; + var canvas1: tcanvas); +var + rect1: rectty; +begin + if canvas1 = nil then begin + canvas1:= fintf.getwidget().container.getcanvas(org_widget); + end; + if dos_moving in fdockstate then begin + canvas1.drawxorframe(fsizingrect,-2,stockobjects.bitmaps[stb_dens50]); + end + else begin + if not (od_thumbtrack in foptionsdock) then begin + if fsplitdir = sd_vert then begin + rect1:= moverect(fsizingrect,makepoint(fsizeoffset,0)); + end + else begin + rect1:= moverect(fsizingrect,makepoint(0,fsizeoffset)); + end; + canvas1.fillxorrect(rect1,stockobjects.bitmaps[stb_dens50]); + end; + end; + if ashow then begin + include(fdockstate,dos_xorpic); + end + else begin + exclude(fdockstate,dos_xorpic); + end; +end; + +procedure tdockcontroller.endmouseop1(); +var + c1: tcanvas; +begin + restorepickshape(); + if dos_xorpic in fdockstate then begin + c1:= nil; + drawxorpic(false,c1); //remove pic + end; + if fsizeindex >= 0 then begin + application.unregisteronkeypress(@dokeypress); + end; +end; + +const + resetmousedockstate = + [{dos_closebuttonclicked,dos_maximizebuttonclicked, + dos_normalizebuttonclicked,dos_minimizebuttonclicked, + dos_fixsizebuttonclicked,dos_floatbuttonclicked,dos_topbuttonclicked, + dos_backgroundbuttonclicked, + dos_lockbuttonclicked,dos_nolockbuttonclicked,}dos_moving]; + +procedure tdockcontroller.endmouseop2(); +begin + fdockstate:= fdockstate - resetmousedockstate; + fclickedbutton:= dbr_none; +end; + +procedure tdockcontroller.cancelsizing(); +var + i1: int32; +begin + endmouseop1(); + endmouseop2(); + fsizeindex:= -1; + if (od_thumbtrack in foptionsdock) and + (high(fwidgetrectsbefore) = high(fwidgetsbefore)) then begin + include(fdockstate,dos_updating1); + try + for i1:= 0 to high(fwidgetrectsbefore) do begin + fwidgetsbefore[i1].widgetrect:= fwidgetrectsbefore[i1]; + end; + finally + fwidgetrectsbefore:= nil; + exclude(fdockstate,dos_updating1); + calclayout(nil,true); + updaterefsize(); + end; + end; + fwidgetrectsbefore:= nil; +end; + +procedure tdockcontroller.clientmouseevent(var info: mouseeventinfoty); + +var + po1: pointty; + widget1: twidget1; + propsize,fixsize: integer; + ar1: widgetarty; + prop,fix: booleanarty; + fixend: boolean; + + function checksizing(const move: boolean): integer; + + function updatesizingrect: integer; + var + int1,int2: integer; + w1: twidget; + p1: integer; + bandnumber: integer; + bandrect: rectty; + lastitem: integer; + begin + result:= -1; + if not findbandpos(fr^.opt(po1),bandnumber,bandrect) then begin + exit; + end; + p1:= fr^.pt(po1); //widget direction + lastitem:= fbands[bandnumber].last; + if not fixend then begin + dec(lastitem); + end; + for int1:= fbands[bandnumber].first to lastitem do begin + w1:= twidget1(ar1[int1]); + int2:= fw^.stop(w1); + if (fsplitter_size = 0) and (p1 >= int2 - sizingtol) and + (p1 < int2 + sizingtol) or + (fsplitter_size <> 0) and (p1 >= int2) and + (p1 < int2 + fsplitter_size) then begin + fr^.setopos(fsizingrect,fr^.opos(bandrect)); + fr^.setosize(fsizingrect,fr^.osize(bandrect)); + if move then begin + fr^.setsize(fsizingrect,fw^.size(w1)); + fr^.setpos(fsizingrect,int2-fr^.size(fsizingrect)); + end + else begin + if fsplitter_size = 0 then begin + fr^.setpos(fsizingrect,int2-sizingtol); + fr^.setsize(fsizingrect,2*sizingtol); + end + else begin + fr^.setpos(fsizingrect,int2); + fr^.setsize(fsizingrect,fsplitter_size); + end; + end; + result:= int1; + break; + end; + end; + end; + + begin + ar1:= nil; //compilerwarning + result:= -1; + if move and (optionsdock * [od_nofit,od_nosplitmove] <> [od_nofit]) then begin + exit; + end; + if not move and (optionsdock * [od_nosplitsize] <> []) then begin + exit; + end; + ar1:= checksplit; + if fsplitdir in [sd_vert,sd_horz] then begin + result:= updatesizingrect; + if result >= 0 then begin + if fsplitdir = sd_vert then begin + setpickshape(cr_sizehor); + end + else begin + setpickshape(cr_sizever); + end; + end; + end; + if result < 0 then begin + restorepickshape; + end; + end; + + procedure checksizeoffset; + var + start,stop: integer; + int1,int2,int4: integer; + movestart: integer; + rect1: rectty; + bandindex: integer; + begin + stop:= 0; + start:= 0; + ar1:= checksplit(propsize,fixsize,prop,fix,false); + if fsizeindex <= high(ar1) then begin + movestart:= fr^.pos(fplacementrect); + start:= movestart - fw^.stop(ar1[fsizeindex]); + stop:= start + fr^.size(fplacementrect); + if not fixend then begin + for int1:= 0 to fsizeindex - 1 do begin + if fix[int1] then begin + start:= start + fw^.size(ar1[int1]); + end + else begin + start:= start + fw^.min(ar1[int1]); + end; + end; + for int1:= fsizeindex + 1 to high(ar1) do begin + if fix[int1] and (int1 <> fsizeindex + 1) then begin + stop:= stop - fw^.size(ar1[int1]); + end + else begin + stop:= stop - fw^.min(ar1[int1]); + end; + end; + start:= start + fsizeindex * fsplitter_size; + stop:= stop - (high(ar1)-fsizeindex) * fsplitter_size; + end + else begin + if dos_moving in fdockstate then begin + movestart:= movestart + fsplitter_size; + fmoveindex:= fsizeindex; + int4:= fsizeoffset + fw^.pos(ar1[fsizeindex]); //mouse position + if findbandpos(fr^.opt(po1),bandindex,rect1) then begin + with fbands[bandindex] do begin + fmoveindex:= last; + for int1:= first to last do begin + int2:= fw^.pos(ar1[int1]); + movestart:= movestart + int2 + fsplitter_size; + if movestart > int4 then begin + fmoveindex:= int1; + break; + end; + end; + end; + end + else begin + findbandindex(fsizeindex,int1,rect1); + end; + fr^.setopos(fsizingrect,fr^.opos(rect1)); + fr^.setosize(fsizingrect,fr^.osize(rect1)); + fr^.setpos(fsizingrect,fw^.pos(ar1[fmoveindex])); + end + else begin + start:= start + fw^.pos(ar1[fsizeindex]) - fr^.pos(fplacementrect) + + fw^.min(ar1[fsizeindex]); + stop:= stop - fsplitter_size; + end; + end; + end; + if fsizeoffset < start then begin + fsizeoffset:= start; + end; + if fsizeoffset > stop then begin + fsizeoffset:= stop; + end; + end; + + procedure calcdelta; + var + int1,int2,int3: integer; + wi1: twidget; + rect1,rect2: rectty; + begin + ar1:= checksplit(propsize,fixsize,prop,fix,false); + if high(ar1) > 0 then begin + int2:= fsizeoffset; + include(fdockstate,dos_updating4); + try + if not fixend then begin + for int1:= fsizeindex downto 0 do begin + if not fix[int1] or (int1 = fsizeindex) then begin + int3:= fw^.size(ar1[int1]); + fw^.setsize(ar1[int1],int3+int2); + int2:= int2 + int3 - fw^.size(ar1[int1]); + if int2 = 0 then begin + break; + end; + end; + end; + fw^.setsize(ar1[0],fw^.size(ar1[0]) + int2); //ev. rest + int2:= - fsizeoffset; + for int1:= fsizeindex + 1 to high(ar1) do begin + if not fix[int1] or (int1 = fsizeindex + 1) then begin + int3:= fw^.size(ar1[int1]); + fw^.setsize(ar1[int1],int3+int2); + int2:= int2 + int3 - fw^.size(ar1[int1]); + if int2 = 0 then begin + break; + end; + end; + end; + end; + if dos_moving in fdockstate then begin + findbandindex(fsizeindex,int1,rect1); + findbandindex(fmoveindex,int2,rect2); + int1:= fr^.opos(rect2)-fr^.opos(rect1); + wi1:= ar1[fsizeindex]; + fw^.setopos(wi1,fw^.opos(wi1)+int1); //shift in new band; + deleteitem(pointerarty(ar1),fsizeindex); + insertitem(pointerarty(ar1),fmoveindex,wi1); + int2:= 0; + for int1:= 0 to high(ar1) do begin + fw^.setpos(ar1[int1],int2); + int2:= int2 + fw^.size(ar1[int1]); + end; + end + else begin + fw^.setsize(ar1[fsizeindex],fw^.size(ar1[fsizeindex]) + int2); //ev. rest + end; + finally + exclude(fdockstate,dos_updating4); + end; + end; + updaterefsize; + end; + +var + canvas1: tcanvas; + + procedure dosize; + begin + checksizeoffset; + if high(ar1) > 0 then begin + calcdelta; + sizechanged(true); + end; + end; //dosize + + procedure setmousebutton(const abutton: dockbuttonrectty); + begin + if (widget1.fframe <> nil) and (widget1.fframe is tgripframe) then begin + with tgripframe(widget1.fframe) do begin + if abutton <> fmousebutton then begin + if fmousebutton <> dbr_none then begin + widget1.invalidaterect(frects[fmousebutton],org_widget); + end; + fmousebutton:= abutton; + if (fmousebutton >= dbr_first) and (fmousebutton <= dbr_last) then begin + widget1.invalidaterect(frects[fmousebutton],org_widget); + end; + end; + if (abutton <> fclickedbutton) and + (abutton >= dbr_first) and (abutton <= dbr_last) then begin + widget1.invalidaterect(frects[abutton],org_widget); + end; + end; + end; + if (abutton <> fclickedbutton) then begin + fclickedbutton:= dbr_none; + end; + end; //setmousebutton + +var + bu1: dockbuttonrectty; + i1: int32; + +begin + inherited; + with info do begin + if (eventstate * [es_processed] = []) then begin + canvas1:= nil; + fixend:= foptionsdock * [od_nofit] <> []; + widget1:= twidget1(fintf.getwidget); + po1:= translatewidgetpoint(addpoint(info.pos,widget1.clientwidgetpos), + widget1,widget1.container); //widget origin + case info.eventkind of + ek_mouseleave,ek_clientmouseleave: begin + setmousebutton(dbr_none); + if not (ds_clicked in fstate) or + (info.eventkind = ek_mouseleave) then begin + restorepickshape; + fsizeindex:= -1; + if dos_xorpic in fdockstate then begin + drawxorpic(false,canvas1); //remove pic + end; + exclude(fstate,ds_clicked); + fdockstate:= fdockstate - resetmousedockstate; + fclickedbutton:= dbr_none; + end; + end; + ek_mousemove: begin + if fsizeindex < 0 then begin + if not (csdesigning in widget1.componentstate) then begin + setmousebutton(checkbuttonarea(pos)); + end; + checksizing((dos_moving in fdockstate) or + (od_nosplitsize in foptionsdock)); + end + else begin + setmousebutton(dbr_none); + if od_thumbtrack in optionsdock then begin + if fsplitdir = sd_vert then begin + fsizeoffset:= pos.x - fpickpos.x; + end; + if fsplitdir = sd_horz then begin + fsizeoffset:= pos.y - fpickpos.y; + end; + dosize(); + if fsplitdir = sd_vert then begin + fpickpos.x:= fpickpos.x+fsizeoffset; + end; + if fsplitdir = sd_horz then begin + fpickpos.y:= fpickpos.y+fsizeoffset; + end; + end + else begin + if fsplitdir = sd_vert then begin + drawxorpic(false,canvas1); //remove pic + fsizeoffset:= pos.x - fpickpos.x; + checksizeoffset; + drawxorpic(true,canvas1); //draw pic + end; + if fsplitdir = sd_horz then begin + drawxorpic(false,canvas1); //remove pic + fsizeoffset:= pos.y - fpickpos.y; + checksizeoffset; + drawxorpic(true,canvas1); //draw pic + end; + end; + end; + end; + ek_buttonpress: begin + fsizeoffset:= 0; + if shiftstate - [ss_left,ss_shift] = [] then begin + fsizeindex:= checksizing((ss_shift in shiftstate) or + (od_nosplitsize in foptionsdock)); + if fsizeindex >= 0 then begin + if (ss_shift in shiftstate) or + (od_nosplitsize in foptionsdock) then begin + include(fdockstate,dos_moving); + end + else begin + application.registeronkeypress(@dokeypress); + exclude(fdockstate,dos_moving); + if od_thumbtrack in foptionsdock then begin + setlength(fwidgetrectsbefore,length(fwidgetsbefore)); + for i1:= 0 to high(fwidgetsbefore) do begin + fwidgetrectsbefore[i1]:= fwidgetsbefore[i1].widgetrect; + end; + end; + end; + drawxorpic(true,canvas1); + end; + if not (ss_shift in shiftstate) then begin + bu1:= checkbuttonarea(pos); + setmousebutton(bu1); + fclickedbutton:= bu1; + end; + end; + end; + ek_buttonrelease: begin + endmouseop1(); + if fsizeindex >= 0 then begin + fwidgetrectsbefore:= nil; + if od_thumbtrack in foptionsdock then begin + fsizeoffset:= 0; + end; + dosize(); + fsizeindex:= -1; + fintf.getwidget.invalidate(); + checksizing((dos_moving in fdockstate) or + (od_nosplitsize in foptionsdock)); + end + else begin + case checkbuttonarea(pos) of + dbr_close: begin + if fclickedbutton = dbr_close then begin + doclose(widget1); + end; + end; + dbr_maximize: mdistate:= mds_maximized; + dbr_normalize: mdistate:= mds_normal; + dbr_minimize: mdistate:= mds_minimized; + dbr_fixsize: begin + if fclickedbutton = dbr_fixsize then begin + useroptions:= optionsdockty( + togglebit({$ifdef FPC}longword{$else}longword{$endif}(fuseroptions), + ord(od_fixsize))); + widget1.invalidatewidget; + end; + end; + dbr_float: begin + if fclickedbutton = dbr_float then begin + if not (csdesigning in widget1.componentstate) then begin + dofloat(nullpoint); + end; + end; + end; + dbr_top: begin + if fclickedbutton = dbr_top then begin + useroptions:= optionsdockty( + togglebit({$ifdef FPC}longword{$else}longword{$endif}(fuseroptions), + ord(od_top))); + widget1.invalidatewidget; + end; + end; + dbr_background: begin + if fclickedbutton = dbr_background then begin + useroptions:= optionsdockty( + togglebit({$ifdef FPC}longword{$else}longword{$endif}(fuseroptions), + ord(od_background))); + widget1.invalidatewidget; + end; + end; + dbr_lock: begin + if fclickedbutton = dbr_lock then begin + useroptions:= optionsdockty( + togglebit({$ifdef FPC}longword{$else}longword{$endif}(fuseroptions), + ord(od_lock))); + widget1.invalidatewidget; + end; + end; + dbr_nolock: begin + if fclickedbutton = dbr_nolock then begin + useroptions:= optionsdockty( + togglebit({$ifdef FPC}longword{$else}longword{$endif}(fuseroptions), + ord(od_nolock))); + widget1.invalidatewidget; + end; + end; + end; + end; + endmouseop2(); + end; + end; + end; + end; +end; + +procedure tdockcontroller.checkmouseactivate(const sender: twidget; + var info: mouseeventinfoty); +var + widget1: twidget; + pt1: pointty; +begin + if (info.eventkind = ek_buttonpress) then begin + if ismdi then begin + widget1:= fintf.getwidget; + widget1.bringtofront; + if ((sender = widget1) or (sender = widget1.container)) and + widget1.canfocus and + not widget1.checkdescendent(widget1.window.focusedwidget)then begin + pt1:= sender.pos; + widget1.setfocus; + application.delayedmouseshift(subpoint(sender.pos,pt1)); + //follow shift in view ??? + end; + end; + end; +end; + +procedure tdockcontroller.mouseevent(var info: mouseeventinfoty); +begin + if ismdi then begin + with twidget1(fintf.getwidget) do begin + if (fframe is tgripframe) and + not (csdesigning in componentstate) then begin + tgripframe(fframe).mouseevent(info); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdockcontroller.childormouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + checkmouseactivate(sender,info); + inherited; +end; + +procedure tdockcontroller.widgetregionchanged(const sender: twidget); +begin + if (sender <> nil) and + (fdockstate * [dos_updating1,dos_updating2,dos_updating3,dos_updating4, + dos_updating5] = []) then begin + with fintf.getwidget do begin + if (componentstate * [csloading,csdesigning] = []) and + not (ws_destroying in widgetstate) and + not (ow1_noautosizing in sender.optionswidget1) and + not(dos_tabedending in fdockstate)then begin + include(fdockstate,dos_updating3); + try + calclayout(nil,not(ws1_parentupdating in sender.widgetstate1)); + updaterefsize; + finally + exclude(fdockstate,dos_updating3); + end; + end; + end; + end; +end; + +procedure tdockcontroller.setcaption(const Value: msestring); +var + widget1: twidget; + mstr1: msestring; +begin + mstr1:= fcaption; + fcaption:= Value; + widget1:= fintf.getwidget; + if not (csdestroying in widget1.componentstate) then begin + if widget1.ownswindow then begin + widget1.window.caption:= fcaption; + end + else begin + if istabed and (widget1.parentwidget is tdocktabpage) then begin + tdocktabpage(widget1.parentwidget).caption:= value; + end; + end; + end; + if mstr1 <> fcaption then begin + docaptionchanged; + end; +end; + +procedure tdockcontroller.beginclientrectchanged; +begin + include(fdockstate,dos_updating1); +end; + +procedure tdockcontroller.endclientrectchanged; +begin + exclude(fdockstate,dos_updating1); + if (fdockstate * [dos_updating2,dos_updating4] = []) then begin + sizechanged; + end + else begin + exclude(fdockstate,dos_layoutvalid); + end; +end; + +function tdockcontroller.isfullarea: boolean; +var + acontroller: tdockcontroller; +begin + result:= getparentcontroller(acontroller) and + (acontroller.fsplitdir <> sd_none); +end; + +function tdockcontroller.istabed: boolean; +var + acontroller: tdockcontroller; +begin + result:= getparentcontroller(acontroller) and + (acontroller.fsplitdir = sd_tabed); +end; + +function tdockcontroller.ismdi: boolean; +var + acontroller: tdockcontroller; +begin + result:= (fintf.getwidget.parentwidget <> nil) and + (fmdistate <> mds_floating) and getparentcontroller(acontroller) and + (acontroller.fsplitdir = sd_none) and + not (dos_tabedending in acontroller.fdockstate); +end; + +function tdockcontroller.isfloating: boolean; +begin + with fintf.getwidget do begin + result:= (parentwidget = nil) or (csdesigning in componentstate) and + (parentwidget = owner); + end; +end; + +function tdockcontroller.canmdisize: boolean; +begin + result:= ismdi and (od_cansize in foptionsdock); +end; + +function tdockcontroller.getitems: widgetarty; //reference count = 1 +var + int1: integer; +begin + if ftabwidget <> nil then begin + with tdocktabwidget(ftabwidget) do begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= tdocktabpage(items[int1]).ftarget; + end; + end; + end + else begin + if fsplitdir = sd_horz then begin + result:= fintf.getwidget.getsortxchildren(); + end + else begin + if fsplitdir = sd_tabed then begin + result:= nil; + end + else begin + result:= fintf.getwidget.getsortychildren(); + end; + end; + end; +end; + +procedure tdockcontroller.setmdistate(const avalue: mdistatety); +var + statebefore: mdistatety; + rect1: rectty; + pos1: captionposty; +begin + if fmdistate <> avalue then begin + if ismdi then begin + statebefore:= fmdistate; + with twidget1(fintf.getwidget) do begin + if fmdistate = mds_normal then begin + fnormalrect:= widgetrect; + end; + case avalue of + mds_normal: begin + fmdistate:= mds_normal; + anchors:= [an_left,an_top]; + widgetrect:= fnormalrect; + end; + mds_minimized: begin + if canclose(nil) then begin + fmdistate:= mds_minimized; + nextfocus; + with rect1 do begin + pos:= fnormalrect.pos; + size:= idockcontroller(fintf).getminimizedsize(pos1); + if cx = 0 then begin + cx:= fnormalrect.cx; + end; + if cy = 0 then begin + cy:= fnormalrect.cy; + end; + case pos1 of + cp_right: inc(x,fnormalrect.cx - cx); + cp_bottom: inc(y,fnormalrect.cy - cy); + end; + end; + anchors:= [an_left,an_top]; + widgetrect:= rect1; + end + else begin + exit; + end; + end; + mds_maximized: begin + fmdistate:= mds_maximized; + anchors:= []; + end; + end; + if (fframe <> nil) then begin + tcustomframe1(fframe).updatestate; + end; + domdistatechanged(statebefore,fmdistate); + end; + end + else begin + fmdistate:= avalue; + end; + end; +end; + +function tdockcontroller.placementrect: rectty; +var + contr1: tdockcontroller; +begin + if getparentcontroller(contr1) then begin + result:= idockcontroller(contr1.fintf).getplacementrect; + end + else begin + result:= nullrect; + end; +end; + +procedure tdockcontroller.parentchanged(const sender: twidget); +begin + exclude(twidget1(sender).fwidgetstate1,ws1_nominsize); + if not (csloading in sender.componentstate) and + (twidget1(sender).fframe is tgripframe) then begin + with tgripframe(twidget1(sender).fframe) do begin + exclude(fgripstate,grps_sizevalid); + internalupdatestate; + end; + end; +end; + +procedure tdockcontroller.poschanged; +var + pos1: captionposty; + widget1: twidget; +begin + if ismdi then begin + widget1:= fintf.getwidget; + case fmdistate of + mds_normal: begin + fnormalrect:= widget1.widgetrect; + end; + mds_minimized: begin + idockcontroller(fintf).getminimizedsize(pos1); + with widget1 do begin + case pos1 of + cp_left,cp_top: begin + fnormalrect.pos:= pos; + end; + cp_right: begin + fnormalrect.y:= bounds_y; + fnormalrect.x:= bounds_x + bounds_cx - fnormalrect.cx; + end; + cp_bottom: begin + fnormalrect.x:= bounds_x; + fnormalrect.y:= bounds_y + bounds_cy - fnormalrect.cy; + end; + end; + end; + end; + end; + end; +end; + +procedure tdockcontroller.statechanged(const astate: widgetstatesty); +var + dock1: tdockcontroller; +begin + if getparentcontroller(dock1) then begin + dock1.childstatechanged(fintf.getwidget(),astate,fwidgetstate); + end; + fwidgetstate:= astate; +end; + +procedure tdockcontroller.settab_options(const avalue: tabbaroptionsty); +begin + ftab_options:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_color(const avalue: colorty); +begin + ftab_color:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_colortab(const avalue: colorty); +begin + ftab_colortab:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_coloractivetab(const avalue: colorty); +begin + ftab_coloractivetab:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_size(const avalue: integer); +begin + ftab_size:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_sizemin(const avalue: integer); +begin + ftab_sizemin:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_sizemax(const avalue: integer); +begin + ftab_sizemax:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_textflags(const avalue: textflagsty); +begin + ftab_textflags:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_width(const avalue: integer); +begin + ftab_width:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_widthmin(const avalue: integer); +begin + ftab_widthmin:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_widthmax(const avalue: integer); +begin + ftab_widthmax:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftab_frame)); + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftab_face)); + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_facetab(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftab_facetab)); + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_faceactivetab(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftab_faceactivetab)); + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_frametab(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftab_frametab)); + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +function tdockcontroller.getactivetabpage: ttabpage; +begin + result:= nil; + if ftabwidget <> nil then begin + result:= ttabpage(ftabwidget.activepage); + end; +end; + +procedure tdockcontroller.setcolortab(const avalue: colorty); +begin + if fcolortab <> avalue then begin + fcolortab:= avalue; + if ftabpage <> nil then begin + ftabpage.colortab:= fcolortab; + end; + end; +end; + +procedure tdockcontroller.setcoloractivetab(const avalue: colorty); +begin + if fcoloractivetab <> avalue then begin + fcoloractivetab:= avalue; + if ftabpage <> nil then begin + ftabpage.coloractivetab:= fcoloractivetab; + end; + end; +end; + +procedure tdockcontroller.setfacetab(const avalue: tfacecomp); +begin + if ffacetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffacetab)); + if ftabpage <> nil then begin + ftabpage.facetab:= ffacetab; + end; + end; +end; + +procedure tdockcontroller.setfaceactivetab(const avalue: tfacecomp); +begin + if ffaceactivetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffaceactivetab)); + if ftabpage <> nil then begin + ftabpage.faceactivetab:= ffaceactivetab; + end; + end; +end; + +procedure tdockcontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_changed) and (ftabwidget <> nil) then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.dolayoutchanged; +var + widget1: twidget; + intf1: idocktarget; +begin + idockcontroller(fintf).dolayoutchanged(self); + widget1:= fintf.getwidget; + if widget1.canevent(tmethod(fonlayoutchanged)) then begin + fonlayoutchanged(self); + end; + widget1:= widget1.parentwidget; + while widget1 <> nil do begin + if widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + intf1.getdockcontroller.dolayoutchanged; + break; + end; + widget1:= widget1.parentwidget; + end; + doboundschanged; +end; + +procedure tdockcontroller.doboundschanged; +var + widget1: twidget; +begin + widget1:= fintf.getwidget; + if widget1.canevent(tmethod(fonboundschanged)) and + not application.terminated then begin + fonboundschanged(self); + end; +end; + +procedure tdockcontroller.docaptionchanged; +var + widget1: twidget; + intf1: idocktarget; +begin + idockcontroller(fintf).dodockcaptionchanged(self); + widget1:= fintf.getwidget; + if widget1.canevent(tmethod(foncaptionchanged)) then begin + foncaptionchanged(self); + end; + widget1:= widget1.parentwidget; + while widget1 <> nil do begin + if widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + intf1.getdockcontroller.docaptionchanged; + break; + end; + widget1:= widget1.parentwidget; + end; +end; + + +function tdockcontroller.getwidget: twidget; +begin + result:= fintf.getwidget; +end; + +function tdockcontroller.activewidget: twidget; //focused child or active tab +var + tab1: tdocktabpage; +begin + result:= nil; + if ftabwidget <> nil then begin + tab1:= tdocktabpage(tdocktabwidget(ftabwidget).activepage); + if tab1 <> nil then begin + result:= tab1.ftarget; + end; + end + else begin + result:= fintf.getwidget.enteredchild; + end; +end; + +function tdockcontroller.dockparentname(): string; +var + parent: tdockcontroller; +begin + result:= ''; + if getparentcontroller(parent) then begin + result:= parent.getwidget.name; + end; +end; + +function tdockcontroller.childicon(): tmaskedbitmap; + + function check(const awidget: twidget; var res: tmaskedbitmap): boolean; + var + intf1: idockcontroller; + begin + result:= false; + if getcorbainterface(awidget,typeinfo(idockcontroller),intf1) then begin + res:= intf1.getchildicon(); + if (res <> nil) and res.hasimage() then begin + result:= true; + end; + end; + end; //check + +var + ar1: widgetarty; + i1: int32; +begin + if not check(activewidget,result) then begin + ar1:= getitems; + result:= nil; + for i1:= 0 to high(ar1) do begin + if check(ar1[i1],result) then begin + break; + end; + end; + end; +end; + +function tdockcontroller.close: boolean; //simulates mr_windowclosed for owner +begin + result:= doclose(fintf.getwidget); +end; + +function tdockcontroller.closeactivewidget: boolean; + //simulates mr_windowclosed for active widget, true if ok +begin + result:= doclose(activewidget); +end; + +function tdockcontroller.checkclickstate(const info: mouseeventinfoty): boolean; +begin + if od_nofit in foptionsdock then begin + result:= info.shiftstate - [ss_left,ss_shift] = []; + end + else begin + result:= info.shiftstate - [ss_left] = []; + end; +end; + +procedure tdockcontroller.dokeypress(const sender: twidget; + var info: keyeventinfoty); +begin + if (info.key = key_escape) and (fsizeindex >= 0) then begin + include(info.eventstate,es_processed); + cancelsizing(); + end; + inherited; +end; + +procedure tdockcontroller.setsplitdir(const avalue: splitdirty); +begin + if avalue <> fdefaultsplitdir then begin + fdefaultsplitdir:= avalue; + if (avalue <> sd_none) and + not (csloading in fintf.getwidget.componentstate) then begin + fasplitdir:= avalue; + checksplitdir(fasplitdir); + if (fasplitdir <> sd_none) then begin + calclayout(nil,false); + end; + end; + end; +end; + +procedure tdockcontroller.setcurrentsplitdir(const avalue: splitdirty); +begin + if (avalue <> sd_none) and (avalue <> fsplitdir) then begin + fasplitdir:= avalue; + calclayout(nil,false); + end; +end; + +function tdockcontroller.getdockrect: rectty; +var + w1: twidget; +begin + if (ftabwidget <> nil) and + (tdocktabwidget(ftabwidget).activepage <> nil) then begin + w1:= tdocktabwidget(ftabwidget).activepage.container; + result:= w1.paintrect; + translatewidgetpoint1(result.pos,w1,getwidget().container); + end + else begin + result:= idockcontroller(fintf).getplacementrect(); //origin container.pos + end; +end; + +procedure tdockcontroller.receiveevent(const aevent: tobjectevent); +var + int1: integer; + ar1: widgetarty; + widget1: twidget; +begin + if aevent is tchildorderevent then begin + with tchildorderevent(aevent) do begin + setlength(ar1,length(fchildren)); + widget1:= fintf.getwidget; + for int1:= 0 to high(fchildren) do begin + ar1[int1]:= widget1.findchild(fchildren[int1]); + end; + if (ffocusedchild >= 0) and (ffocusedchild <= high(ar1)) and + (ar1[ffocusedchild] <> nil) and ar1[ffocusedchild].canfocus then begin + ar1[ffocusedchild].setfocus(false); + end; + widget1.setchildorder(ar1); + end; + end + else begin + inherited; + end; +end; + +{ tnochildrendockcontroller } + +constructor tnochildrendockcontroller.create(aintf: idockcontroller); +begin + inherited; + foptionsdock:= defaultoptionsdocknochildren; +end; + +{ tgripframe } + +constructor tgripframe.create(const aintf: icaptionframe; + const acontroller: tdockcontroller); +begin + fgrip_color:= defaultgripcolor; + fgrip_coloractive:= defaultgripcoloractive; + fgrip_colorglyph:= cl_glyph; + fgrip_colorglyphactive:= cl_glyphactive; + fgrip_colorbutton:= cl_transparent; + fgrip_colorbuttonactive:= cl_transparent; + fgrip_size:= defaultgripsize; + fgrip_pos:= defaultgrippos; + fgrip_grip:= defaultgripgrip; + fgrip_options:= defaultgripoptions; + fgrip_textflagstop:= defaulttextflagstop; + fgrip_textflagsleft:= defaulttextflagsleft; + fgrip_textflagsbottom:= defaulttextflagsbottom; + fgrip_textflagsright:= defaulttextflagsright; + fgrip_captiondist:= 1; + fcontroller:= acontroller; + inherited create(aintf); + fobjectpicker:= tobjectpicker.create(iobjectpicker(self)); +end; + +destructor tgripframe.destroy; +begin + fobjectpicker.free; + fgrip_face.free; + fgrip_faceactive.free; + inherited; +end; + +procedure tgripframe.checktemplate(const sender: tobject); +begin + inherited; + if fgrip_face <> nil then begin + fgrip_face.checktemplate(sender); + end; + if fgrip_faceactive <> nil then begin + fgrip_faceactive.checktemplate(sender); + end; +end; + +procedure tgripframe.showhint(const aid: int32; var info: hintinfoty); +begin + case dockbuttonrectty(-(aid - hintidframe)) of + dbr_handle: begin + if fgrip_hint = '' then begin + info.caption:= fcontroller.getfloatcaption; + end + else begin + info.caption:= fgrip_hint; + end; + end; + dbr_close: begin + info.caption:= sc(sc_close); + end; + dbr_maximize: begin + info.caption:= sc(sc_maximize); + end; + dbr_normalize: begin + info.caption:= sc(sc_normalize); + end; + dbr_minimize: begin + info.caption:= sc(sc_minimize); + end; + dbr_fixsize: begin + info.caption:= sc(sc_fix_size); + end; + dbr_float: begin + info.caption:= sc(sc_float); + end; + dbr_top: begin + info.caption:= sc(sc_stay_on_top); + end; + dbr_background: begin + info.caption:= sc(sc_stay_in_background); + end; + dbr_lock: begin + info.caption:= sc(sc_lock_children); + end; + dbr_nolock: begin + info.caption:= sc(sc_no_lock); + end; + end; +end; + +procedure tgripframe.drawgripbutton(const acanvas: tcanvas; + const akind: dockbuttonrectty; const arect: rectty; + const acolorglyph: colorty; const acolorbutton: colorty; + const ahiddenedges: edgesty); + +var + hiddenedges1: edgesty; + + function calclevel(const aoption: optiondockty): integer; + begin + if (ord(aoption) >= 0) and ((aoption in fcontroller.foptionsdock) or + (fcontroller.fclickedbutton = akind)) then begin + result:= -1; + hiddenedges1:= [] + end + else begin + result:= 1; + end; + end; + +var + rect2: rectty; + int1: integer; + i1: int32; +begin + if akind = fmousebutton then begin + hiddenedges1:= []; + end + else begin + hiddenedges1:= ahiddenedges; + end; + with acanvas,arect do begin + fillrect(arect,acolorbutton); + i1:= calclevel(optiondockty(-1)); + case akind of + dbr_close: begin + if factgripsize >= 8 then begin + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawcross(inflaterect(arect,-2),acolorglyph); + end + else begin + drawcross(arect,acolorglyph); + end; + end; + dbr_maximize: begin + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawframe(inflaterect(arect,-2),-1,acolorglyph); + drawvect(makepoint(x+2,y+3),gd_right,cx-5,acolorglyph); + end; + dbr_normalize: begin + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + rect2.cx:= cx * 2 div 3 - 3; + rect2.cy:= rect2.cx; + rect2.pos:= addpoint(pos,makepoint(2,2)); + drawrect(rect2,acolorglyph); + rect2.x:= x + cx - 3 - rect2.cx; + rect2.y:= y + cy - 3 - rect2.cy; + drawrect(rect2,acolorglyph); + end; + dbr_minimize: begin + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + acanvas.move(pos); + case fgrip_pos of + cp_left: begin + drawvect(makepoint(2,2),gd_down,cy-5,acolorglyph); + drawvect(makepoint(3,2),gd_down,cy-5,acolorglyph); + end; + cp_right: begin + drawvect(makepoint(cx-3,2),gd_down,cy-5,acolorglyph); + drawvect(makepoint(cx-4,2),gd_down,cy-5,acolorglyph); + end; + cp_bottom: begin + drawvect(makepoint(2,cy-3),gd_right,cx-5,acolorglyph); + drawvect(makepoint(2,cy-4),gd_right,cx-5,acolorglyph); + end; + else begin //cp_top + drawvect(makepoint(2,2),gd_right,cx-5,acolorglyph); + drawvect(makepoint(2,3),gd_right,cx-5,acolorglyph); + end; + end; + acanvas.remove(pos); + end; + dbr_fixsize: begin + i1:= calclevel(od_fixsize); + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawframe(inflaterect(arect,-2),-1,acolorglyph); + end; + dbr_float: begin + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + int1:= cx div 2; + acanvas.move(pos); + drawlines([mp(2,int1),mp(2,2),mp(int1,2)],false,acolorglyph); + drawline(mp(cx-3,cy-3),mp(2,2),acolorglyph); + acanvas.remove(pos); + end; + dbr_top: begin + int1:= x + cx div 2; + i1:= calclevel(od_top); + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawlines([makepoint(int1-3,y+4),makepoint(int1,y+1), + makepoint(int1,y+cy-1)],false,acolorglyph); + drawline(makepoint(int1+3,y+4),makepoint(int1,y+1),acolorglyph); + end; + dbr_background: begin + int1:= x + cx div 2; + i1:= calclevel(od_background); + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawlines([makepoint(int1-3,y+cx-4),makepoint(int1,y+cy-1), + makepoint(int1,y+1)],false,acolorglyph); + drawline(makepoint(int1+3,y+cx-4),makepoint(int1,y+cy-1),acolorglyph); + end; + dbr_lock: begin + i1:= calclevel(od_lock); + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawellipse1(makerect(arect.x+2,arect.y+2,arect.cx-5,arect.cy-5), + acolorglyph); + end; + dbr_nolock: begin + i1:= calclevel(od_nolock); + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + fillellipse1(makerect(arect.x+2,arect.y+2,arect.cx-5,arect.cy-5), + acolorglyph); + drawellipse1(makerect(arect.x+2,arect.y+2,arect.cx-5,arect.cy-5), + acolorglyph); + end; + end; + end; +end; + +procedure tgripframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); + +var +// brushbefore: tsimplebitmap; +// colorbefore: colorty; + po1,po2: pointty; + int1,int2: integer; + rect1: rectty; + col1: colorty; + info1: drawtextinfoty; + floating: boolean; + colorbutton,colorglyph: colorty; + bo1: boolean; + dirbefore: graphicdirectionty; + face1: tface1; + isactive: boolean; +label + endlab; +begin + inherited; + dirbefore:= gd_none; + checkstate; + checkgripsize; + with canvas do begin + rect1:= clipbox; + if testintersectrect(rect1,fgriprect) then begin + isactive:= fintf.getwidget.active; + rect1:= frects[dbr_handle]; + info1.text.text:= fcontroller.caption; + floating:= fcontroller.isfloating; + face1:= tface1(fgrip_face); + if isactive and (fgrip_faceactive <> nil) then begin + face1:= tface1(fgrip_faceactive); + end; + + if face1 <> nil then begin + bo1:= fgrip_pos in [cp_left,cp_right]; + if bo1 then begin + with face1.fi do begin + dirbefore:= fade_direction; + fade_direction:= graphicdirectionty((ord(fade_direction) + 1) and 3); + end; + end; + face1.paint(canvas,rect1); + if bo1 then begin + with face1.fi do begin + fade_direction:= dirbefore; + end; + end; + end; + canvas.save(); + if isactive then begin + colorbutton:= fgrip_colorbuttonactive; + colorglyph:= fgrip_colorglyphactive; + end + else begin + colorbutton:= fgrip_colorbutton; + colorglyph:= fgrip_colorglyph; + end; + if go_closebutton in fgrip_options then begin + drawgripbutton(canvas,dbr_close,frects[dbr_close],colorglyph,colorbutton, + fedges[dbr_close]); + end; + if (frects[dbr_maximize].cx > 0) and + (go_maximizebutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_maximize,frects[dbr_maximize],colorglyph, + colorbutton,fedges[dbr_maximize]); + end; + if (frects[dbr_normalize].cx > 0) and + (go_normalizebutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_normalize,frects[dbr_normalize],colorglyph, + colorbutton,fedges[dbr_normalize]); + end; + if (frects[dbr_minimize].cx > 0) and + (go_minimizebutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_minimize,frects[dbr_minimize],colorglyph, + colorbutton,fedges[dbr_minimize]); + end; + if (frects[dbr_fixsize].cx > 0) and + (go_fixsizebutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_fixsize,frects[dbr_fixsize],colorglyph, + colorbutton,fedges[dbr_fixsize]); + end; + if (frects[dbr_float].cx > 0) and + (go_floatbutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_float,frects[dbr_float],colorglyph,colorbutton, + fedges[dbr_float]); + end; + if (frects[dbr_top].cx > 0) and + (go_topbutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_top,frects[dbr_top],colorglyph,colorbutton, + fedges[dbr_top]); + end; + if (frects[dbr_background].cx > 0) and + (go_backgroundbutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_background,frects[dbr_background],colorglyph, + colorbutton,fedges[dbr_background]); + end; + if (frects[dbr_lock].cx > 0) and + (go_lockbutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_lock,frects[dbr_lock],colorglyph,colorbutton, + fedges[dbr_lock]); + end; + if (frects[dbr_nolock].cx > 0) and + (go_nolockbutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_nolock,frects[dbr_nolock],colorglyph, + colorbutton,fedges[dbr_nolock]); + end; + if (info1.text.text <> '') and + (not floating and (go_showsplitcaption in fgrip_options) or + floating and (go_showfloatcaption in fgrip_options) or + fcontroller.ismdi) then begin + with info1 do begin + text.format:= nil; + dest:= rect1; + clip:= rect1; + font:= self.font; + tabulators:= nil; + case fgrip_pos of + cp_top: begin + flags:= fgrip_textflagstop; + if not ((tf_right in flags) xor (tf_rotate180 in flags)) then begin + inc(dest.x,fgrip_captiondist); + end; + if not (tf_xcentered in flags) then begin + dec(dest.cx,fgrip_captiondist); + end; + inc(dest.y,fgrip_captionoffset); + if tf_clipi in flags then begin + clip.y:= -1000; //no vertical clip + clip.cy:= 2000; + end; + end; + cp_left: begin + flags:= fgrip_textflagsleft; + if (tf_right in flags) xor (tf_rotate180 in flags) then begin + inc(dest.y,fgrip_captiondist); + end + else begin + dec(dest.cy,fgrip_captiondist); + if tf_xcentered in flags then begin + dec(dest.y,fgrip_captiondist); + end; + end; + inc(dest.x,fgrip_captionoffset); + if tf_clipi in flags then begin + clip.x:= -1000; //no horicontal clip + clip.cx:= 2000; + end; + end; + cp_bottom: begin + flags:= fgrip_textflagsbottom; + if not ((tf_right in flags) xor (tf_rotate180 in flags))then begin + inc(dest.x,fgrip_captiondist); + end; + if not (tf_xcentered in flags) then begin + dec(dest.cx,fgrip_captiondist); + end; + dec(dest.y,fgrip_captionoffset); + if tf_clipi in flags then begin + clip.y:= -1000; //no vertical clip + clip.cy:= 2000; + end; + end; + cp_right: begin + flags:= fgrip_textflagsright; + if (tf_right in flags) xor (tf_rotate180 in flags) then begin + inc(dest.y,fgrip_captiondist); + end + else begin + dec(dest.cy,fgrip_captiondist); + if tf_xcentered in flags then begin + dec(dest.y,fgrip_captiondist); + end; + end; + dec(dest.x,fgrip_captionoffset); + if tf_clipi in flags then begin + clip.x:= -1000; //no horicontal clip + clip.cx:= 2000; + end; + end; + end; + drawtext(canvas,info1); + canvas.subcliprect(inflaterect(info1.res,1)); + end; + end; + if fgrip_grip = stb_none then begin + if fintf.getwidget.active then begin + col1:= fgrip_coloractive; + end + else begin + col1:= cl_shadow; + end; + with rect1 do begin + int1:= factgripsize div 4; + int2:= (factgripsize mod 4) div 2; + if fgrip_pos in [cp_left,cp_right] then begin + if cy > 4 then begin + po1.x:= x + int2; + po1.y:= y + 2; + po2.x:= po1.x; + po2.y:= y + cy - 3; + for int2:= 1 to int1 do begin + drawline(po1,po2,cl_highlight); + inc(po1.x,2); + inc(po2.x,2); + drawline(po1,po2,col1); + inc(po1.x,2); + inc(po2.x,2); + end; + end; + end + else begin + if cy > 4 then begin + po1.y:= y + int2; + po1.x:= x + 2; + po2.y:= po1.y; + po2.x:= x + cx - 3; + for int2:= 1 to int1 do begin + drawline(po1,po2,cl_highlight); + inc(po1.y,2); + inc(po2.y,2); + drawline(po1,po2,col1); + inc(po1.y,2); + inc(po2.y,2); + end; + end; + end; + end; + end + else begin +// brushbefore:= brush; + brush:= stockobjects.bitmaps[fgrip_grip]; + if fintf.getwidget.active then begin + color:= fgrip_coloractive; + end + else begin + color:= fgrip_color; + end; + fillrect(rect1,cl_brushcanvas); +// brush:= brushbefore; + // stockobjects.bitmaps[fgrip_grip].paint(canvas,fhandlerect, + // [al_xcentered,al_ycentered,al_tiled],fgrip_color,cl_transparent); + end; +endlab: + canvas.restore;//color:= colorbefore; + end; + end; +end; + +function tgripframe.getbuttonrects(const index: dockbuttonrectty): rectty; +begin + if (index >= dbr_first) and (index <= dbr_last) then begin + if index = dbr_handle then begin + result:= fgriprect; + end + else begin + result:= frects[index]; + end; + dec(result.x,fpaintrect.x+fclientrect.x); + dec(result.y,fpaintrect.y+fclientrect.y); + end + else begin + result:= nullrect; + end; +end; + +function tgripframe.getminimizedsize(out apos: captionposty): sizety; +begin + checkstate; + if fgrip_pos in [cp_right,cp_left] then begin + result.cy:= 0; + result.cx:= fpaintframe.left + fpaintframe.right; + end + else begin + result.cx:= 0; + result.cy:= fpaintframe.top + fpaintframe.bottom;; + end; + apos:= fgrip_pos; +end; + +procedure tgripframe.getpaintframe(var frame: framety); +begin + inherited; + checkgripsize; + case fgrip_pos of + cp_right: inc(frame.right,factgripsize); + cp_top: inc(frame.top,factgripsize); + cp_bottom: inc(frame.bottom,factgripsize); + else inc(frame.left,factgripsize); + end; +end; + +procedure tgripframe.setgrip_color(const avalue: colorty); +begin + if fgrip_color <> avalue then begin + fgrip_color := avalue; + fintf.invalidatewidget; + end; +end; + +procedure tgripframe.setgrip_coloractive(const avalue: colorty); +begin + if fgrip_coloractive <> avalue then begin + fgrip_coloractive:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tgripframe.setgrip_grip(const avalue: stockbitmapty); +begin + if fgrip_grip <> avalue then begin + fgrip_grip:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tgripframe.setgrip_size(const avalue: integer); +begin + if fgrip_size <> avalue then begin + fgrip_size:= avalue; + exclude(fgripstate,grps_sizevalid); + internalupdatestate; + end; +end; + +procedure tgripframe.setgrip_options(avalue: gripoptionsty); +const + amask: gripoptionsty = [go_horz,go_vert]; +begin + avalue:= gripoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(fgrip_options), + {$ifdef FPC}longword{$else}word{$endif}(amask))); + if fgrip_options <> avalue then begin + if go_floatbutton in avalue then begin + include(fcontroller.fdockstate,dos_hasfloatbutton); + end + else begin + exclude(fcontroller.fdockstate,dos_hasfloatbutton); + end; + fgrip_options:= avalue; + internalupdatestate; + end; +end; + +procedure tgripframe.setgrip_colorglyph(const avalue: colorty); +begin + if fgrip_colorglyph <> avalue then begin + fgrip_colorglyph := avalue; + internalupdatestate; + end; +end; + +procedure tgripframe.setgrip_colorglyphactive(const avalue: colorty); +begin + if fgrip_colorglyphactive <> avalue then begin + fgrip_colorglyphactive := avalue; + internalupdatestate; + end; +end; + +procedure tgripframe.setgrip_colorbutton(const avalue: colorty); +begin + if fgrip_colorbutton <> avalue then begin + fgrip_colorbutton := avalue; + internalupdatestate; + end; +end; + +procedure tgripframe.setgrip_colorbuttonactive(const avalue: colorty); +begin + if fgrip_colorbuttonactive <> avalue then begin + fgrip_colorbuttonactive := avalue; + internalupdatestate; + end; +end; + +procedure tgripframe.checkgripsize; +var + parentcontroller: tdockcontroller; +begin + if not (grps_sizevalid in fgripstate) then begin + factgripsize:= fgrip_size; + if not (od_nolock in fcontroller.foptionsdock) and + fcontroller.getparentcontroller(parentcontroller) and + parentcontroller.nogrip then begin + factgripsize:= 0; + end; + include(fgripstate,grps_sizevalid); + end; +end; + +procedure tgripframe.updaterects; + +var + firstbu,lastbu: dockbuttonrectty; + + procedure initrect(const index: dockbuttonrectty); + begin + if firstbu = dbr_none then begin + firstbu:= index; + end; + lastbu:= index; + with frects[dbr_handle] do begin + case fgrip_pos of + cp_right,cp_left: begin + frects[index].x:= x; + frects[index].y:= y; + inc(y,factgripsize); + dec(cy,factgripsize); + fedges[index]:= [edg_top,edg_bottom]; + end; + else begin //top,bottom + dec(cx,factgripsize); + frects[index].x:= x + cx; + frects[index].y:= y; + fedges[index]:= [edg_left,edg_right]; + end; + end; + end; + if go_buttonframe in fgrip_options then begin + fedges[index]:= []; + end; + with frects[index] do begin + cx:= factgripsize; + cy:= factgripsize; + end; + end; + +var + bo1,bo2,bo3,designing: boolean; + parentcontroller: tdockcontroller; + +begin //widget origin + inherited; + firstbu:= dbr_none; + checkgripsize; + with fgriprect do begin + case fgrip_pos of + cp_right: begin + x:= fpaintrect.x + fpaintrect.cx; + y:= fpaintrect.y; + cx:= factgripsize; + cy:= fpaintrect.cy; + end; + cp_left: begin + x:= fpaintrect.x - factgripsize; + y:= fpaintrect.y; + cx:= factgripsize; + cy:= fpaintrect.cy; + end; + cp_top: begin + x:= fpaintrect.x; + y:= fpaintrect.y - factgripsize; + cx:= fpaintrect.cx; + cy:= factgripsize; + end; + else begin //cp_bottom + x:= fpaintrect.x; + y:= fpaintrect.y + fpaintrect.cy; + cx:= fpaintrect.cx; + cy:= factgripsize; + end; + end; + end; + with fintf.getwidget do begin + fillchar(frects,sizeof(frects),0); + frects[dbr_handle]:= fgriprect; + designing:= csdesigning in componentstate; + bo1:= (parentwidget <> nil) and (fcontroller.fmdistate <> mds_floating) or + designing; + bo3:= fcontroller.isfullarea; + bo2:= not bo3 or designing; + if bo1 and (go_closebutton in fgrip_options) then begin + initrect(dbr_close); + end; + if fcontroller.ismdi or designing then begin + if (go_maximizebutton in fgrip_options) and + ((fcontroller.mdistate <> mds_maximized) or designing) then begin + initrect(dbr_maximize); + end; + if (go_normalizebutton in fgrip_options) and + ((fcontroller.mdistate <> mds_normal) or designing) then begin + initrect(dbr_normalize); + end; + if (go_minimizebutton in fgrip_options) and + ((fcontroller.mdistate <> mds_minimized) or designing) then begin + initrect(dbr_minimize); + end; + end; + if bo1{ or designing} then begin + if (go_fixsizebutton in fgrip_options) then begin + if designing or + bo3 and fcontroller.getparentcontroller(parentcontroller) and + not parentcontroller.nofit and + (parentcontroller.fsplitdir <> sd_tabed) then begin + initrect(dbr_fixsize); + end; + end; + if (go_floatbutton in fgrip_options) then begin + initrect(dbr_float); + end; + end; + if bo2 then begin + if go_topbutton in fgrip_options then begin + initrect(dbr_top); + end; + if go_backgroundbutton in fgrip_options then begin + initrect(dbr_background); + end; + end; + if go_lockbutton in fgrip_options then begin + initrect(dbr_lock); + end; + if bo1 and (go_nolockbutton in fgrip_options) and + ((fcontroller.getparentcontroller <> nil) or designing) then begin + initrect(dbr_nolock); + end; + end; + if firstbu <> dbr_none then begin + if fgrip_pos in [cp_right,cp_left] then begin + exclude(fedges[firstbu],edg_top); + exclude(fedges[lastbu],edg_bottom); + end + else begin + exclude(fedges[firstbu],edg_right); + exclude(fedges[lastbu],edg_left); + end; + end; +end; + +procedure tgripframe.updatestate; +begin + if go_horz in fgrip_options then begin + if go_opposite in fgrip_options then begin + fgrip_pos:= cp_bottom; + end + else begin + fgrip_pos:= cp_top; + end; + end + else begin + if go_vert in fgrip_options then begin + if go_opposite in fgrip_options then begin + fgrip_pos:= cp_left; + end + else begin + fgrip_pos:= cp_right; + end; + end; + end; + inherited; +end; + +function tgripframe.griprect: rectty; +begin + result:= frects[dbr_handle]; +end; + +function tgripframe.getwidget: twidget; +begin + result:= fcontroller.fintf.getwidget; +end; + +function tgripframe.getclientrect: rectty; +begin + result:= fcontroller.fintf.getwidget.clientrect; +end; + +procedure tgripframe.invalidatewidget(); +begin + fcontroller.fintf.getwidget.invalidatewidget(); +end; + +procedure tgripframe.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + fcontroller.fintf.getwidget.invalidaterect(rect,org,noclip); +end; + +procedure tgripframe.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + with twidget1(fcontroller.fintf.getwidget) do begin + if not (csdestroying in componentstate) then begin + setlinkedvar(source,dest,linkintf); + end; + end; +end; + +function tgripframe.getcomponentstate: tcomponentstate; +begin + result:= fcontroller.fintf.getwidget.componentstate; +end; + +procedure tgripframe.widgetregioninvalid; +begin + twidget1(fcontroller.fintf.getwidget).widgetregioninvalid; +end; + +procedure tgripframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + if pointinrect(info.pos,fgriprect) or (fcontroller.canmdisize) then begin + with twidget1(sender) do begin + fwidgetstate:= fwidgetstate + [ws_wantmousemove,ws_wantmousebutton]; + end; + end; +end; + +procedure tgripframe.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +var + kind1: sizingkindty; + rect: rectty; +begin + rect:= sender.pickrect; + if fcontroller.canmdisize and + (fcontroller.mdistate <> mds_minimized) and + (not pointinrect(rect.pos,fgriprect) or + pointinrect(rect.pos,frects[dbr_handle])) then begin + with fintf.getwidget do begin + kind1:= calcsizingkind(rect.pos,makerect(nullpoint,size)); + if anchors * [an_left,an_right] = [] then begin + case kind1 of + sik_right,sik_left: kind1:= sik_none; + sik_topright,sik_topleft: kind1:= sik_top; + sik_bottomright,sik_bottomleft: kind1:= sik_bottom; + end; + end; + if anchors * [an_top,an_bottom] = [] then begin + case kind1 of + sik_top,sik_bottom: kind1:= sik_none; + sik_topleft,sik_bottomleft: kind1:= sik_left; + sik_topright,sik_bottomright: kind1:= sik_right; + end; + end; + end; + if kind1 <> sik_none then begin + setlength(objects,1); + objects[0]:= ord(kind1); + end + else begin + objects:= nil; + end; + end + else begin + objects:= nil; + end; +end; + +function tgripframe.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; +var + ar1: integerarty; +begin + getpickobjects(sender,ar1); + result:= ar1 <> nil; + if result then begin + shape:= sizingcursors[sizingkindty(ar1[0])]; + end +end; + +procedure tgripframe.beginpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tgripframe.pickthumbtrack(const sender: tobjectpicker); +begin + //dummy +end; + +function tgripframe.calcsizingrect(const akind: sizingkindty; + const offset: pointty): rectty; +var + cxmin,cymin: integer; + int1: integer; +begin + with fintf.getwidget do begin + cxmin:= bounds_cxmin; + cymin:= bounds_cymin; + if fgrip_pos in [cp_right,cp_left] then begin + int1:= fpaintframe.left + fpaintframe.right; + if cxmin < int1 then begin + cxmin:= int1; + end; + int1:= fpaintframe.top + fpaintframe.bottom + + fgriprect.cy - frects[dbr_handle].cy; + if cymin < int1 then begin + cymin:= int1; + end; + end + else begin + int1:= fpaintframe.top + fpaintframe.bottom; + if cymin < int1 then begin + cymin:= int1; + end; + int1:= fpaintframe.left + fpaintframe.right + + fgriprect.cx - frects[dbr_handle].cx; + if cxmin < int1 then begin + cxmin:= int1; + end; + end; + result:= adjustsizingrect(widgetrect,akind,offset, + cxmin,bounds_cxmax,cymin,bounds_cymax); + if parentwidget <> nil then begin + with parentwidget do begin + intersectrect(result,makerect(clientwidgetpos,maxclientsize),result); + end; + end; + end; +end; + +procedure tgripframe.endpickmove(const sender: tobjectpicker); +var + ar1: integerarty; +begin + ar1:= sender.currentobjects; + if ar1 <> nil then begin + fcontroller.fnormalrect:= calcsizingrect(sizingkindty(ar1[0]), + sender.pickoffset); + fcontroller.mdistate:= mds_normal; + fintf.getwidget.widgetrect:= fcontroller.fnormalrect; + end; +end; + +procedure tgripframe.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); +var + rect1: rectty; + ar1: integerarty; +begin + ar1:= sender.currentobjects; + if ar1 <> nil then begin + rect1:= calcsizingrect(sizingkindty(ar1[0]),sender.pickoffset); + with fintf.getwidget do begin + subpoint1(rect1.pos,paintparentpos); + canvas.save; + canvas.addcliprect(paintrectparent); + canvas.drawxorframe(rect1,-3,stockobjects.bitmaps[stb_dens50]); + canvas.restore; + end; + end; +end; + +procedure tgripframe.mouseevent(var info: mouseeventinfoty); +begin + if not fcontroller.active then begin + fobjectpicker.mouseevent(info); + end; +end; + +procedure tgripframe.updatewidgetstate; +begin + inherited; + fintf.getwidget.invalidaterect(fgriprect,org_widget); +end; + +function tgripframe.getgrip_face: tface; +begin + fintf.getwidget.getoptionalobject(fgrip_face,@createface); + result:= fgrip_face; +end; + +procedure tgripframe.setgrip_face(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fgrip_face,@createface); +end; + +function tgripframe.getgrip_faceactive: tface; +begin + fintf.getwidget.getoptionalobject(fgrip_faceactive,@createfaceactive); + result:= fgrip_faceactive; +end; + +procedure tgripframe.setgrip_faceactive(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fgrip_faceactive,@createfaceactive); +end; + +procedure tgripframe.createface(); +begin + fgrip_face:= tface.create(iface(self)); +end; + +procedure tgripframe.createfaceactive(); +begin + fgrip_faceactive:= tface.create(iface(self)); +end; + +function tgripframe.translatecolor(const acolor: colorty): colorty; +begin + result:= fintf.getwidget.translatecolor(acolor); +end; + +procedure tgripframe.cancelpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +function tgripframe.ishintarea(const apos: pointty; var aid: int32): boolean; + //widget origin +begin + result:= pointinrect(apos,fgriprect{frects[dbr_handle]}); + if result then begin + if go_buttonhints in fgrip_options then begin + aid:= hintidframe - ord(fcontroller.checkbuttonarea( + subpoint(apos,fcontroller.getwidget.clientwidgetpos))); + if not (od_captionhint in fcontroller.optionsdock) and + (aid = hintidframe-ord(dbr_handle)) then begin + result:= false; + end; + end + else begin + if (od_captionhint in fcontroller.optionsdock) then begin + aid:= hintidframe - ord(dbr_handle); + end; + end; + end + else begin + result:= inherited ishintarea(apos,aid); + end; +end; + +procedure tgripframe.setgrip_textflagstop(const avalue: textflagsty); +begin + if fgrip_textflagstop <> avalue then begin + fgrip_textflagstop:= checktextflags(fgrip_textflagstop,avalue); + fintf.invalidatewidget(); + end; +end; + +procedure tgripframe.setgrip_textflagsright(const avalue: textflagsty); +begin + if fgrip_textflagsleft <> avalue then begin + fgrip_textflagsleft:= checktextflags(fgrip_textflagsleft,avalue); + fintf.invalidatewidget(); + end; +end; + +procedure tgripframe.setgrip_textflagsbottom(const avalue: textflagsty); +begin + if fgrip_textflagsbottom <> avalue then begin + fgrip_textflagsbottom:= checktextflags(fgrip_textflagsbottom,avalue); + fintf.invalidatewidget(); + end; +end; + +procedure tgripframe.setgrip_textflagsrright(const avalue: textflagsty); +begin + if fgrip_textflagsright <> avalue then begin + fgrip_textflagsright:= checktextflags(fgrip_textflagsright,avalue); + fintf.invalidatewidget(); + end; +end; + +procedure tgripframe.setgrip_captiondist(const avalue: integer); +begin + if fgrip_captiondist <> avalue then begin + fgrip_captiondist:= avalue; + fintf.invalidatewidget(); + end; +end; + +procedure tgripframe.setgrip_captionoffset(const avalue: integer); +begin + if fgrip_captionoffset <> avalue then begin + fgrip_captionoffset:= avalue; + fintf.invalidatewidget(); + end; +end; + +{ tdockhandle } + +constructor tdockhandle.create(aowner: tcomponent); +begin + fgrip_color:= defaultgripcolor; + fgrip_pos:= cp_bottomright; + fgrip_grip:= stb_none; + inherited; + foptionswidget:= defaultoptionswidget + [ow_top{,ow_noautosizing}]; + foptionswidget1:= defaultoptionswidget1 + [ow1_noautosizing]; + size:= makesize(15,15); + anchors:= [an_right,an_bottom]; + color:= cl_transparent; +end; + +function tdockhandle.gethandlerect: rectty; +begin + result:= paintrect; +end; + +procedure tdockhandle.setgrip_color(const Value: colorty); +begin + if fgrip_color <> value then begin + fgrip_color:= value; + invalidate; + end; +end; + +procedure tdockhandle.setgrip_grip(const Value: stockbitmapty); +begin + if fgrip_grip <> value then begin + fgrip_grip:= value; + invalidate; + end; +end; + +procedure tdockhandle.setgrip_pos(const Value: captionposty); +begin + if fgrip_pos <> value then begin + fgrip_pos:= value; + invalidate; + end; +end; + +procedure tdockhandle.clientmouseevent(var info: mouseeventinfoty); +var + po1: pointty; +begin + inherited; + if not (es_processed in info.eventstate) and (fcontroller <> nil) then begin + po1:= translateclientpoint(nullpoint,self,fcontroller.fintf.getwidget); + addpoint1(info.pos,po1); + fcontroller.clientmouseevent(info); + subpoint1(info.pos,po1); + end; +end; + +procedure tdockhandle.dopaintforeground(const canvas: tcanvas); +var + rect1: rectty; + int1,int2,x,y: integer; +begin + inherited; + rect1:= innerclientrect; + if fgrip_grip <> stb_none then begin + with canvas do begin + brush:= stockobjects.bitmaps[fgrip_grip]; + color:= fgrip_color; + fillrect(rect1,cl_brushcanvas); + end; + end + else begin + case fgrip_pos of + cp_bottomright: begin + x:= rect1.x + rect1.cx - 1; + y:= rect1.y + rect1.cy - 1; + if rect1.cy < rect1.cx then begin + int2:= rect1.cy; + end + else begin + int2:= rect1.cx + end; + dec(int2); + int1:= 2; + while (int1 < int2) do begin + canvas.drawline(makepoint(x-int1,y),makepoint(x,y-int1),cl_shadow); + canvas.drawline(makepoint(x-int1-1,y-1),makepoint(x-1,y-int1-1),cl_highlight); + inc(int1,4); + end; + end; + end; + end; +end; + +function tdockhandle.gethint: msestring; +begin + result:= inherited gethint(); + if (result = '') and (fcontroller <> nil) and + (od_captionhint in fcontroller.optionsdock) then begin + result:= fcontroller.caption; + end; +end; + +{ tdockpanel } + +constructor tdockpanel.create(aowner: tcomponent); +begin + ficon:= tmaskedbitmap.create(bmk_rgb); + ficon.onchange:= {$ifdef FPC}@{$endif}iconchanged; + if fdragdock = nil then begin + fdragdock:= tnochildrendockcontroller.create(idockcontroller(self)); + end; + inherited; + optionswidget:= defaultdockpaneloptionswidget; +end; + +destructor tdockpanel.destroy; +begin + ficon.free; + inherited; + fdragdock.Free; +end; + +function tdockpanel.checkdock(var info: draginfoty): boolean; +begin + result:= true; +end; + +procedure tdockpanel.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + fdragdock.childormouseevent(sender,info); + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +procedure tdockpanel.internalcreateframe; +begin + tgripframe.create(iscrollframe(self),fdragdock); +end; + +procedure tdockpanel.dragevent(var info: draginfoty); +begin + if not fdragdock.beforedragevent(info) then begin + inherited; + end; + fdragdock.afterdragevent(info); +end; + +function tdockpanel.getframe: tgripframe; +begin + result:= tgripframe(inherited getframe); +end; + +procedure tdockpanel.setframe(const Value: tgripframe); +begin + inherited setframe(value); +end; + +procedure tdockpanel.setdragdock(const Value: tnochildrendockcontroller); +begin + fdragdock.assign(Value); +end; + +procedure tdockpanel.updatewindowinfo(var info: windowinfoty); +begin + inherited; + info.options:= foptionswindow; + getwindowicon(ficon,info.icon,info.iconmask); +end; + +function tdockpanel.getbuttonrects(const index: dockbuttonrectty): rectty; +begin + if fframe = nil then begin + if index = dbr_handle then begin + result:= clientrect; + end + else begin + result:= nullrect; + end; + end + else begin + result:= tgripframe(fframe).getbuttonrects(index); + end; +end; + +function tdockpanel.getminimizedsize(out apos: captionposty): sizety; +begin + if fframe = nil then begin + result:= nullsize; + end + else begin + result:= tgripframe(fframe).getminimizedsize(apos); + end; +end; + +function tdockpanel.getplacementrect: rectty; +begin + result:= innerpaintrect; + minsize:= nullsize; +end; + +function tdockpanel.getcaption: msestring; +begin + result:= ''; +end; + +function tdockpanel.getchildicon: tmaskedbitmap; +begin + result:= nil; +end; + +procedure tdockpanel.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tdockpanel.seticon(const avalue: tmaskedbitmap); +begin + ficon.assign(avalue); +end; + +procedure tdockpanel.iconchanged(const sender: tobject); +var + icon1,mask1: pixmapty; +begin + if ownswindow then begin + getwindowicon(ficon,icon1,mask1); + gui_setwindowicon(window.winid,icon1,mask1); + end; +end; + + //istatfile +procedure tdockpanel.dostatread(const reader: tstatreader); +begin + fdragdock.dostatread(reader); +end; + +procedure tdockpanel.dostatwrite(const writer: tstatwriter); +begin + fdragdock.dostatwrite(writer,nil); +end; + +procedure tdockpanel.statreading; +begin + fdragdock.statreading; +end; + +procedure tdockpanel.statread; +begin + fdragdock.statread; +end; + +function tdockpanel.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tdockpanel.clientrectchanged; +begin + fdragdock.beginclientrectchanged; + inherited; + fdragdock.endclientrectchanged; +end; + +procedure tdockpanel.widgetregionchanged(const sender: twidget); +begin + inherited; + fdragdock.widgetregionchanged(sender); +end; + +procedure tdockpanel.setparentwidget(const Value: twidget); +begin + if fframe <> nil then begin + exclude(tcustomframe1(fframe).fstate,fs_rectsvalid); + end; + inherited; +end; + +procedure tdockpanel.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + fdragdock.dopaint(acanvas); +end; + +procedure tdockpanel.doactivate; +begin + fdragdock.doactivate; + inherited; +end; + +procedure tdockpanel.statechanged; +begin + fdragdock.statechanged(fwidgetstate); + inherited; +end; + +procedure tdockpanel.poschanged; +begin + fdragdock.poschanged; +end; + +procedure tdockpanel.parentchanged; +begin + inherited; + fdragdock.parentchanged(self); +end; + +function tdockpanel.getdockcontroller: tdockcontroller; +begin + result:= fdragdock; +end; + +procedure tdockpanel.dolayoutchanged(const sender: tdockcontroller); +begin + //dummy +end; + +procedure tdockpanel.dodockcaptionchanged(const sender: tdockcontroller); +begin + //dummy +end; + +function tdockpanel.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +function tdockpanel.calcminscrollsize: sizety; +begin + result:= inherited calcminscrollsize(); + if not (csdesigning in componentstate) then begin + fdragdock.updateminscrollsize(result); + end; +end; + +procedure tdockpanel.setdockingareacaption(const avalue: msestring); +begin + fdockingareacaption:= avalue; + invalidate; +end; + +procedure tdockpanel.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if fdockingareacaption <> '' then begin + paintdockingareacaption(canvas,self,fdockingareacaption); + end; +end; + +{ tchildorderevent } + +constructor tchildorderevent.create(const sender: tdockcontroller); +begin + fchildren:= sender.fchildren; + ffocusedchild:= sender.ffocusedchild; + inherited create(ek_object,ievent(sender)); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msedockpanelform.pas b/mseide-msegui/lib/common/widgets/msedockpanelform.pas new file mode 100644 index 0000000..c1eb575 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msedockpanelform.pas @@ -0,0 +1,835 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedockpanelform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mselist,msetypes,mseglob,mseguiglob,mseguiintf,mseapplication, + msestat,msemenus,msegui,msedatalist, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msedock, + msestrings,msestatfile; + +const + defaultdockpanelgripoptions = defaultgripoptions + + [go_fixsizebutton,go_topbutton,go_backgroundbutton,go_lockbutton]; + defaultdockpaneloptionsdock = defaultoptionsdock + + [od_canmove,od_canfloat,od_candock,od_acceptsdock,od_dockparent, + od_splitvert,od_splithorz,od_tabed,od_proportional,od_propsize]; + defaultdockpanelwidth = 350; + defaultdockpanelheight = 200; + defaultdockpaneloptions = + (defaultformoptions - [fo_autoreadstat,fo_autowritestat]) + + [fo_globalshortcuts,fo_screencentered]; + defaultdockpaneloptionswidget = + (defaultformwidgetoptions - [ow_destroywidgets]) + + [ow_mousefocus,ow_arrowfocusin,ow_arrowfocusout]; + defaultdockstatprio = 256; +type + tdockpanelformcontroller = class; + tdockpanelform = class; + + tdockpanelformmenuitem = class(tmenuitem) + private + fpanel: tdockpanelform; + public + constructor create(const apanel: tdockpanelform); + destructor destroy; override; + end; + + tdockpanelformscrollbox = class(tdockformscrollbox) + protected + fdockingareacaption: msestring; + procedure dopaintbackground(const canvas: tcanvas) override; + end; + + tdockpanelform = class(tdockformwidget) + private + fmenuitem: tdockpanelformmenuitem; + fnameindex: integer; //0 for unnumbered + fcontroller: tdockpanelformcontroller; + procedure showexecute(const sender: tobject); + procedure setdockingareacaption(const avalue: msestring); + function getdockingareacaption: msestring; + protected + procedure updatecaption(acaption: msestring); + procedure dodockcaptionchanged(const sender: tdockcontroller); override; + procedure dolayoutchanged(const sender: tdockcontroller); override; + class function hasresource: boolean; override; + class function getmoduleclassname: string; override; +// constructor docreate(aowner: tcomponent); override; + procedure docreate(aowner: tcomponent); override; + public + constructor create(aowner: tcomponent; load: boolean); override; + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure doonclose; override; + function canclose(const newfocus: twidget): boolean; override; + published + property visible default false; + property bounds_cx default defaultdockpanelwidth; + property bounds_cy default defaultdockpanelheight; + property options default defaultdockpaneloptions; + property optionswidget default defaultdockpaneloptionswidget; + property dockingareacaption: msestring read getdockingareacaption + write setdockingareacaption; + end; + + panelfoclassty = class of tdockpanelform; + + dockpanelupdatecaptioneventty = + procedure(const sender: tdockpanelformcontroller; const apanel: tdockpanelform; + var avalue: msestring) of object; + dockpanelupdatemenueventty = + procedure(const sender: tdockpanelformcontroller; const apanel: tdockpanelform; + const avalue: tmenuitem) of object; + createpaneleventty = + procedure(const sender: tdockpanelformcontroller; + var apanel: tdockpanelform) of object; +{ getpanelclasseventty = + procedure(const sender: tdockpanelcontroller; + var aclass: panelfoclassty) of object; +} + createdynamiccompeventty = + procedure(const sender: tdockpanelformcontroller; + const aclassname: string; + const aname: string; var acomponent: tmsecomponent) of object; + dynamiccompeventty = procedure(const sender: tdockpanelformcontroller; + const acomponent: tmsecomponent) of object; + + tdockpanelformcontroller = class(tmsecomponent,istatfile) + private + fpanellist: tpointerlist; + fmenu: tcustommenu; + fstatfile: tstatfile; + fstatvarname: msestring; + fmenunamepath: string; + fonupdatecaption: dockpanelupdatecaptioneventty; + fonupdatemenu: dockpanelupdatemenueventty; + fstatfileclient: tstatfile; + foncreatepanel: createpaneleventty; + foptionsdock: optionsdockty; + foptionsgrip: gripoptionsty; + fcaption: msestring; + fstatfileclients: tstatfilearrayprop; + fstatpriority: integer; + fdockingareacaption: msestring; + fdynamiccomps: msecomponentarty; + foncreatedynamiccomp: createdynamiccompeventty; + fonregisterdynamiccomp: dynamiccompeventty; + fonunregisterdynamiccomp: dynamiccompeventty; + procedure updatestat(const filer: tstatfiler); + procedure setmenu(const avalue: tcustommenu); +// procedure checkstatfile(const avalue: tstatfile; const ref: tstatfile); + procedure setstatfile(const avalue: tstatfile); + procedure setstatfileclient(const avalue: tstatfile); + procedure setstatfileclients(const avalue: tstatfilearrayprop); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty) override; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function newpanel(aname: string = ''): tdockpanelform; + procedure updatewindowcaptions(const avalue: msestring); + procedure removepanels; + function createdynamiccomp(const aclassname: string): tmsecomponent; + //nil if not found + function createdynamiccomp( + const aclass: msecomponentclassty): tmsecomponent; + function createdynamicwidget(const aclass: widgetclassty): twidget; + procedure registerdynamiccomp(const acomp: tmsecomponent); + procedure unregisterdynamiccomp(const acomp: tmsecomponent); + property dynamiccomps: msecomponentarty read fdynamiccomps; + published + property menu: tcustommenu read fmenu write setmenu; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default defaultdockstatprio; + property statfileclients: tstatfilearrayprop read fstatfileclients + write setstatfileclients; //called before statfileclient + property statfileclient: tstatfile read fstatfileclient + write setstatfileclient; //last called + + property menunamepath: string read fmenunamepath write fmenunamepath; + //delimiter = '.' + property caption: msestring read fcaption write fcaption; + property dockingareacaption: msestring read fdockingareacaption + write fdockingareacaption; + property optionsdock: optionsdockty read foptionsdock + write foptionsdock default defaultdockpaneloptionsdock; + property optionsgrip: gripoptionsty read foptionsgrip + write foptionsgrip default defaultdockpanelgripoptions; + property onupdatecaption: dockpanelupdatecaptioneventty + read fonupdatecaption write fonupdatecaption; + property onupdatemenu: dockpanelupdatemenueventty + read fonupdatemenu write fonupdatemenu; + property oncreatepanel: createpaneleventty read foncreatepanel + write foncreatepanel; + property oncreatedynamiccomp: createdynamiccompeventty + read foncreatedynamiccomp write foncreatedynamiccomp; + property onregisterdynamiccomp: dynamiccompeventty + read fonregisterdynamiccomp write fonregisterdynamiccomp; + property onunregisterdynamiccomp: dynamiccompeventty + read fonunregisterdynamiccomp write fonunregisterdynamiccomp; + end; + +function createdockpanelform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +implementation +uses + {msedockpanelform_mfm,}sysutils,msekeyboard,mseactions,msearrayutils, + mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcomponent1 = class(tcomponent); + tmsecomponent1 = class(tmsecomponent); + + pdockpanelform = ^tdockpanelform; + + tpanelformdockcontroller = class(tformdockcontroller) + public + constructor create(const aowner: tcustomdockform); +// constructor create(aintf: idockcontroller); + published + property optionsdock default defaultoptionsdock; + end; + +function createdockpanelform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +begin + result:= tmsecomponent(aclass.newinstance); +{$warnings off} + tcomponent1(result).setdesigning(true); //used for wo_groupleader +{$warnings on} + tdockpanelform(result).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +{ tdockpanelformcontroller } + +constructor tdockpanelformcontroller.create(aowner: tcomponent); +begin + fstatpriority:= defaultdockstatprio; + foptionsdock:= defaultdockpaneloptionsdock; + foptionsgrip:= defaultdockpanelgripoptions; +// fcaption:= 'Panel'; + fpanellist:= tpointerlist.create; + fstatfileclients:= tstatfilearrayprop.create; + inherited; +end; + +destructor tdockpanelformcontroller.destroy; +var + i1: int32; +begin + for i1:= high(fdynamiccomps) downto 0 do begin + ievent(fdynamiccomps[i1]).unlink(ievent(self), + ievent(fdynamiccomps[i1])); + end; + fdynamiccomps:= nil; + inherited; + freeandnil(fpanellist); + fstatfileclients.free; +end; + +procedure tdockpanelformcontroller.updatestat(const filer: tstatfiler); +var + ar1,ar2,ar3: msestringarty; + i1: integer; + comp1: tmsecomponent; +begin + ar1:= nil; + if filer.iswriter then begin + setlength(ar1,fpanellist.count); + for i1:= 0 to high(ar1) do begin + ar1[i1]:= msestring(tdockpanelform(fpanellist[i1]).name); + end; + setlength(ar2,length(fdynamiccomps)); + for i1:= 0 to high(ar2) do begin + ar2[i1]:= msestring(fdynamiccomps[i1].classname+','+fdynamiccomps[i1].name); + end; + end; + filer.updatevalue('panels',ar1); + filer.updatevalue('dynamiccomps',ar2); + if not filer.iswriter then begin + if canevent(tmethod(foncreatedynamiccomp)) then begin + for i1:= 0 to high(ar2) do begin + ar3:= splitstring(ar2[i1],','); + if high(ar3) > 0 then begin + comp1:= nil; + foncreatedynamiccomp(self,string(ar3[0]),string(ar3[1]),comp1); + if comp1 <> nil then begin + comp1.name:= string(ar3[1]); + registerdynamiccomp(comp1); + end; + end; + end; + end; + for i1:= fpanellist.count - 1 downto 0 do begin + tdockpanelform(fpanellist[i1]).free; + end; + for i1:= 0 to high(ar1) do begin + try + with newpanel(ansistring(ar1[i1])) do begin + if statfile = self.statfile then begin + statreading(); + end; + end; + except + end; + end; + end; + with fstatfileclients do begin + for i1:= 0 to count - 1 do begin + with items[i1] do begin + if (statfile <> nil) and (statfile <> fstatfile) then begin + statfile.updatestat('client_'+inttostrmse(i1),filer); + end; + end; + end; + end; + if (fstatfileclient <> nil) and (fstatfile <> fstatfileclient) then begin + fstatfileclient.updatestat('clients',filer); + end; +end; + +function tdockpanelformcontroller.newpanel(aname: string = ''): tdockpanelform; +var + item1: tmenuitem; + int1,int2: integer; + ar1: integerarty; +begin + result:= nil; + item1:= nil; + int2:= 0; + if fmenu <> nil then begin + if fmenunamepath <> '' then begin + item1:= fmenu.menu.itembynames(splitstring(fmenunamepath,'.')); + end; + end; + if aname = '' then begin + setlength(ar1,fpanellist.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tdockpanelform(fpanellist[int1]).fnameindex; + end; + sortarray(ar1); + int2:= length(ar1); + for int1:= 0 to high(ar1) do begin //find first gap + if ar1[int1] <> int1 then begin + int2:= int1; + break; + end; + end; + end + else begin + int2:= strtoint(copy(aname,6,bigint))-1; + end; + + if canevent(tmethod(foncreatepanel)) then begin + foncreatepanel(self,result); + end; + if result = nil then begin + result:= tdockpanelform.create(self); + with result do begin + createframe; + dragdock.optionsdock:= defaultdockpaneloptionsdock; + frame.grip_options:= defaultdockpanelgripoptions; + dragdock.optionsdock:= foptionsdock; + frame.grip_options:= foptionsgrip; + container.frame.framei:= nullframe; + statfile:= self.fstatfileclient; + end; + end; + + int1:= int2 + 1; + if aname = '' then begin + aname:= 'panel'+inttostr(int1); + end; + with result do begin + name:= aname; + fnameindex:= int2; + if dockingareacaption = '' then begin + dockingareacaption:= self.dockingareacaption; + end; + if item1 <> nil then begin + tdockpanelformmenuitem.create(result); +// fmenuitem:= tmenuitem.create(nil,nil); + end; + updatecaption(''); + end; + if item1 <> nil then begin + if int2 >= fpanellist.count then begin + int2:= fpanellist.count-1; + end; + if int2 > item1.count - 2 then begin + int2:= item1.count - 2; + end; + if int2 < 0 then begin + int2:= 0; + end; + item1.submenu.insert(int2,result.fmenuitem); + end; +end; + +procedure tdockpanelformcontroller.setmenu(const avalue: tcustommenu); +begin + setlinkedvar(avalue,tmsecomponent(fmenu)); +end; +{ +procedure tdockpanelformcontroller.checkstatfile( + const avalue: tstatfile; const ref: tstatfile); +begin + if (avalue <> nil) and (avalue = ref) then begin + raise exception.create(self.name+':Invalid statfile '+avalue.name+'.'); + end; +end; +} +procedure tdockpanelformcontroller.setstatfile(const avalue: tstatfile); +begin +// checkstatfile(avalue,fstatfileclient); + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tdockpanelformcontroller.dostatread(const reader: tstatreader); +begin + updatestat(reader); +end; + +procedure tdockpanelformcontroller.dostatwrite(const writer: tstatwriter); +begin + updatestat(writer); +end; + +procedure tdockpanelformcontroller.statreading; +begin + while high(fdynamiccomps) >= 0 do begin + fdynamiccomps[high(fdynamiccomps)].destroy(); + end; +end; + +procedure tdockpanelformcontroller.statread; +begin + //dummy +end; + +function tdockpanelformcontroller.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tdockpanelformcontroller.setstatfileclient(const avalue: tstatfile); +begin +// checkstatfile(avalue,fstatfile); + setlinkedvar(avalue,tmsecomponent(fstatfileclient)); +end; + +procedure tdockpanelformcontroller.updatewindowcaptions(const avalue: msestring); +var + po1: pdockpanelform; + int1: integer; +begin + with fpanellist do begin + po1:= pointer(datapo); + for int1:= 0 to count - 1 do begin + po1^.caption:= avalue; + inc(po1); + end; + end; +end; + +procedure tdockpanelformcontroller.setstatfileclients( + const avalue: tstatfilearrayprop); +begin + fstatfileclients.assign(avalue); +end; + +procedure tdockpanelformcontroller.removepanels; +begin + while fpanellist.count > 0 do begin + tobject(fpanellist.items[fpanellist.count-1]).free; + end; +end; + +function tdockpanelformcontroller.createdynamiccomp( + const aclassname: string): tmsecomponent; +var + cla1: tpersistentclass; +begin + result:= nil; + cla1:= getclass(aclassname); + if cla1.inheritsfrom(tmsecomponent) then begin + application.createdatamodule(msecomponentclassty(cla1),result); +// result:= msecomponentclassty(cla1).create(nil); + end; +end; + +function tdockpanelformcontroller.createdynamiccomp( + const aclass: msecomponentclassty): tmsecomponent; +begin + application.createdatamodule(aclass,result); + registerdynamiccomp(result); +end; + +function tdockpanelformcontroller.createdynamicwidget( + const aclass: widgetclassty): twidget; +begin + application.createform(aclass,result); + registerdynamiccomp(result); +end; + +procedure tdockpanelformcontroller.objectevent(const sender: tobject; + const event: objecteventty); +var + i1: int32; +begin + if event = oe_destroyed then begin + for i1:= high(fdynamiccomps) downto 0 do begin + if fdynamiccomps[i1] = sender then begin + deleteitem(pointerarty(fdynamiccomps),i1); + if canevent(tmethod(fonunregisterdynamiccomp)) then begin + fonunregisterdynamiccomp(self,tmsecomponent(sender)); + end; + break; + end; + end; + end; + inherited; +end; + +procedure tdockpanelformcontroller.registerdynamiccomp( + const acomp: tmsecomponent); +var + i1: int32; +begin + for i1:= 0 to high(fdynamiccomps) do begin + if fdynamiccomps[i1] = acomp then begin + exit; + end; + end; + setlength(fdynamiccomps,high(fdynamiccomps)+2); + fdynamiccomps[high(fdynamiccomps)]:= acomp; + ievent(acomp).link(ievent(self),ievent(acomp)); + if canevent(tmethod(fonregisterdynamiccomp)) then begin + fonregisterdynamiccomp(self,acomp); + end; +end; + +procedure tdockpanelformcontroller.unregisterdynamiccomp( + const acomp: tmsecomponent); +var + i1: int32; +begin + for i1:= high(fdynamiccomps) downto 0 do begin + if fdynamiccomps[i1] = acomp then begin + ievent(fdynamiccomps[i1]).unlink(ievent(self), + ievent(fdynamiccomps[i1])); + deleteitem(pointerarty(fdynamiccomps),i1); + if canevent(tmethod(fonunregisterdynamiccomp)) then begin + fonunregisterdynamiccomp(self,acomp); + end; + exit; + end; + end; +end; + +function tdockpanelformcontroller.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tdockpanelformmenuitem } + +constructor tdockpanelformmenuitem.create(const apanel: tdockpanelform); +begin + inherited create(nil,nil); + fpanel:= apanel; + apanel.fmenuitem:= self; +end; + +destructor tdockpanelformmenuitem.destroy; +begin + if fpanel <> nil then begin + fpanel.fmenuitem:= nil; + end; + inherited; +end; + +{ tdockpanelform } + +constructor tdockpanelform.create(aowner: tcomponent); +begin + if aowner is tdockpanelformcontroller then begin + setlinkedvar(tmsecomponent(aowner),tmsecomponent(fcontroller)); + end; + inherited; +end; + +constructor tdockpanelform.create(aowner: tcomponent; load: boolean); +begin + if fdragdock = nil then begin +// fdragdock:= tpanelformdockcontroller.create(idockcontroller(self)); + fdragdock:= tpanelformdockcontroller.create(self); + end; + include(fmsecomponentstate,cs_ismodule); + fscrollbox:= tdockpanelformscrollbox.create(self); + inherited; +end; + +//constructor tdockpanelform.docreate(aowner: tcomponent); +procedure tdockpanelform.docreate(aowner: tcomponent); +begin + inherited; + visible:= false; + options:= defaultdockpaneloptions; + optionswidget:= defaultdockpaneloptionswidget; + { + createframe; + options:= (options - [fo_autoreadstat,fo_autowritestat]) + + [fo_globalshortcuts,fo_screencentered]; + optionswidget:= (optionswidget - [ow_destroywidgets]) + + [ow_mousefocus,ow_arrowfocusin,ow_arrowfocusout]; + dragdock.optionsdock:= defaultdockpaneloptionsdock; + frame.grip_options:= defaultdockpanelgripoptions; + } + size:= makesize(defaultdockpanelwidth,defaultdockpanelheight); + if fcontroller <> nil then begin + statfile:= fcontroller.statfileclient; + fcontroller.fpanellist.add(self); + end; +end; + +destructor tdockpanelform.destroy; +begin + if fcontroller <> nil then begin + with fcontroller do begin + if fpanellist <> nil then begin + fpanellist.remove(self); + end; + if (fmenuitem <> nil) then begin + if (fmenuitem.owner <> nil) and + not (csdestroying in fmenuitem.owner.componentstate) then begin + fmenuitem.parentmenu.submenu.delete(fmenuitem.index); + end + else begin + fmenuitem.fpanel:= nil; + end; + end; + end; + end; + inherited; +end; + +procedure tdockpanelform.updatecaption(acaption: msestring); +var + menucapt: msestring; +begin + if acaption = '' then begin + if fcontroller <> nil then begin + acaption:= fcontroller.caption; + end; + end; + if fmenuitem <> nil then begin + menucapt:= acaption; + with fmenuitem do begin + onexecute:= {$ifdef FPC}@{$endif}showexecute; + if fnameindex < 9 then begin + shortcut:= (ord(key_f1) or key_modctrl) + fnameindex; + if menucapt <> '' then begin + menucapt:= acaption + ' '; + end; + menucapt:= menucapt + '&' + inttostrmse(fnameindex+1); + end + else begin + shortcut:= 0; + end; + caption:= menucapt; + if (fcontroller <> nil) and + fcontroller.canevent(tmethod(fcontroller.fonupdatemenu)) then begin + fcontroller.fonupdatemenu(fcontroller,self,fmenuitem); + end; + if shortcut <> 0 then begin + acaption:= acaption + ' ('+encodeshortcutname(shortcut)+')'; + end; + end; + end + else begin + acaption:= acaption+' '+inttostrmse(fnameindex+1); + end; + if (fcontroller <> nil) and + fcontroller.canevent(tmethod(fcontroller.fonupdatecaption)) then begin + fcontroller.fonupdatecaption(fcontroller,self,acaption); + end; + dragdock.caption:= acaption; +end; + +procedure tdockpanelform.showexecute(const sender: tobject); +begin + activate; +end; + +function tdockpanelform.canclose(const newfocus: twidget): boolean; + + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; + +begin + result:= inherited canclose(newfocus); + { + if result and (newfocus = nil) and containerempty then begin + release; + end; + } +end; + +procedure tdockpanelform.doonclose; + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; +begin + inherited; + if containerempty and not (csdesigning in componentstate) then begin + release; + end; +end; + +procedure tdockpanelform.dodockcaptionchanged(const sender: tdockcontroller); +var + intf1: idocktarget; + mstr1: msestring; + int1: integer; + ar1: widgetarty; +begin + mstr1:= ''; + ar1:= sender.getitems; + for int1:= 0 to high(ar1) do begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + mstr1:= mstr1 + intf1.getdockcontroller.getdockcaption+','; + end; + end; + updatecaption(copy(mstr1,1,length(mstr1)-1)); //remove last comma +end; + +procedure tdockpanelform.dolayoutchanged(const sender: tdockcontroller); +begin + dodockcaptionchanged(sender); +end; + +{ +procedure tdockpanelform.dolayoutchanged(const sender: tdockcontroller); +var + intf1: idocktarget; + mstr1: msestring; + int1: integer; + ar1: widgetarty; +begin + mstr1:= ''; + ar1:= sender.getitems; + for int1:= 0 to high(ar1) do begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + mstr1:= mstr1 + intf1.getdockcontroller.getdockcaption+','; + end; + end; + updatecaption(copy(mstr1,1,length(mstr1)-1)); //remove last comma +end; +} + +class function tdockpanelform.hasresource: boolean; +begin + result:= self <> tdockpanelform; +end; + +class function tdockpanelform.getmoduleclassname: string; +begin + result:= 'tdockpanelform'; +end; + +procedure tdockpanelform.setdockingareacaption(const avalue: msestring); +begin + with tdockpanelformscrollbox(fscrollbox) do begin + fdockingareacaption:= avalue; + invalidate; + end; +end; + +function tdockpanelform.getdockingareacaption: msestring; +begin + result:= tdockpanelformscrollbox(fscrollbox).fdockingareacaption; +end; + +{ tpanelformdockcontroller } + +constructor tpanelformdockcontroller.create(const aowner: tcustomdockform); +//constructor tpanelformdockcontroller.create(aintf: idockcontroller); +begin + inherited; + foptionsdock:= defaultoptionsdock; +end; + +{ tdockpanelformscrollbox } + +procedure tdockpanelformscrollbox.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if fdockingareacaption <> '' then begin + paintdockingareacaption(canvas,self,fdockingareacaption); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msedragglob.pas b/mseide-msegui/lib/common/widgets/msedragglob.pas new file mode 100644 index 0000000..014163f --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msedragglob.pas @@ -0,0 +1,131 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msedragglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,msegraphutils,mseguiglob,mseevent; + +type + dragobjstatety = (dos_dropped,dos_sysdnd,dos_write,dos_sysdroppending); + dragobjstatesty = set of dragobjstatety; + + pdragobject = ^tdragobject; + tdragobject = class(tnullinterfacedobject) + private + fpickpos: pointty; + fdroppos: pointty; + function getdropped: boolean; + protected + finstancepo: pdragobject; + fsender: tobject; + fstate: dragobjstatesty; + fsysdndintf: isysdnd; + feventintf: ievent; + factions: dndactionsty; + function checksysdnd(const aaction: sysdndactionty; + const arect: rectty): boolean; + //isysdnd + function geteventintf: ievent; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; //clientorigin + const aactions: dndactionsty = []); + destructor destroy; override; + function sender: tobject; + procedure acepted(const apos: pointty); virtual; //screenorigin + procedure refused(const apos: pointty); virtual; //screenorigin + property pickpos: pointty read fpickpos write fpickpos; //clientorigin + property droppos: pointty read fdroppos write fdroppos; //screenorigin + property state: dragobjstatesty read fstate; + property dropped: boolean read getdropped; + property actions: dndactionsty read factions write factions; + end; + + drageventkindty = (dek_begin,dek_check,dek_drop,dek_end, + dek_leavesysdnd,dek_leavewidget); + + draginfoty = record + eventkind: drageventkindty; + pos: pointty; //origin = clientrect.pos + pickpos: pointty; //origin = screenorigin + clientpickpos: pointty; //origin = clientrect.pos + dragobjectpo: pdragobject; + accept: boolean; + end; + +implementation + +uses + mseapplication,msegui,mseguiintf; +type + tguiapplication1 = class(tguiapplication); + +{ tdragobject } + +constructor tdragobject.create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; + const aactions: dndactionsty); +begin + fsender:= asender; + finstancepo:= @instance; + if finstancepo <> nil then begin + instance.Free; + instance:= self; + end; + fpickpos:= apickpos; + factions:= aactions; + tguiapplication1(application).dragstarted; +end; + +destructor tdragobject.destroy; +begin + checksysdnd(sdnda_destroyed,nullrect); + if finstancepo <> nil then begin + finstancepo^:= nil; + end; + inherited; +end; + +function tdragobject.getdropped: boolean; +begin + result:= dos_dropped in fstate; +end; + +procedure tdragobject.acepted(const apos: pointty); +begin + //dummy +end; + +procedure tdragobject.refused(const apos: pointty); +begin + //dummy +end; + +function tdragobject.sender: tobject; +begin + result:= fsender; +end; + +function tdragobject.checksysdnd(const aaction: sysdndactionty; + const arect: rectty): boolean; +begin + result:= false; + if dos_sysdnd in fstate then begin + gui_sysdnd(aaction,fsysdndintf,arect,result); + end; +end; + +function tdragobject.geteventintf: ievent; +begin + result:= feventintf; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/mseeditglob.pas b/mseide-msegui/lib/common/widgets/mseeditglob.pas new file mode 100644 index 0000000..66642b4 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseeditglob.pas @@ -0,0 +1,273 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseeditglob; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + mseglob,mseguiglob,{msegui,}msetypes,{msegraphics,}msegraphutils, + classes,mclasses; + +type + //used in MSEifi + optioneditty = (oe_readonly,oe_undoonesc, + oe_closequery,oe_checkmrcancel, + oe_nogray, + oe_linebreak, + // if oe_shiftreturn -> shift key_return inserts linebreak + // else -> key_return inserts linebreak + oe_shiftreturn, + oe_forcereturncheckvalue, + //call checkvalue unconditionally by key_return + oe_eatreturn, + // oe_returntaborder, //key_return selects next widget in taborder + //moved to twidget.optionswidget ow_keyreturntaborder + oe_resetselectonexit, + + //same layout as strincoleditoptionty + oe_exitoncursor, + oe_nofirstarrownavig, + oe_endonenter, + oe_homeonenter, + oe_autoselect, //selectall bei widget enter + oe_autoselectonfirstclick, + oe_caretonreadonly, + oe_focusrectonreadonly, + oe_trimright, + oe_trimleft, + oe_uppercase, + oe_lowercase, + oe_hintclippedtext, + oe_locate, + oe_casesensitive, + + oe_notnull, + oe_null, //accept empty value independent of min setting + //in trealedit + oe_directdbnullcheck, //check null by canclose() + oe_savevalue,oe_savestate,oe_saveoptions, //deprecated, + oe_checkvaluepaststatread //moved to optionsedit1ty + +// oe_autopopupmenu, //deprecated, moved to optionsedit1ty +// oe_keyexecute + ); + optionseditty = set of optioneditty; +const + deprecatedoptionsedit = [oe_savevalue,oe_savestate, + oe_saveoptions,oe_checkvaluepaststatread]; + invisibleoptionsedit = [ord(oe_savevalue),ord(oe_savestate), + ord(oe_saveoptions),ord(oe_checkvaluepaststatread)]; + +type + optionedit1ty = (oe1_noselectall,oe1_multiline, + oe1_autopopupmenu, + oe1_keyexecute, //alt+down-key starts dialog + oe1_readonlydialog, + oe1_savevalue,oe1_savestate,oe1_saveoptions, + oe1_checkvalueafterstatread, + oe1_sendchangeeventbycheckvalue, + oe1_nocellpaint, //draw widget image instead of cell image + //for titemedit value edits + oe1_thumbtrack //for tcoloredit + ); + optionsedit1ty = set of optionedit1ty; + + dataeditstatety = (des_edited,des_emptytext,des_grayed, + {des_isdataedit,}des_isdb,des_dbnull,des_dbnullcheck, + des_actualcursor,des_updating,des_valueread, + des_statreading, + des_disabled, //for tdatabutton + des_updatelayout,des_editing{,des_dropdowntextsetting}); + dataeditstatesty = set of dataeditstatety; + + editactionty = (ea_none,ea_beforechange,ea_textchanged,ea_resetemptytext, + ea_textedited,ea_undone, + ea_textentered,ea_indexmoved,{ea_selectindexmoved,} + ea_textsizechanged, + ea_delchar,ea_undo, + {ea_selectstart,ea_selectend,}ea_clearselection, + ea_deleteselection,ea_copyselection,ea_pasteselection, + ea_selectall,ea_exit,ea_caretupdating); + + editactionstatety = (eas_shift,eas_delete); + editactionstatesty = set of editactionstatety; + + editnotificationinfoty = record + state: editactionstatesty; + case action: editactionty of + ea_exit,ea_delchar:( + dir: graphicdirectionty; + ); + ea_caretupdating:( + caretrect: rectty; + showrect: rectty; + ); + ea_textsizechanged:( + sizebefore: sizety; + newsize: sizety; + ); + ea_pasteselection,ea_copyselection:( + bufferkind: clipboardbufferty; + ); + end; + + idataeditcontroller = interface (inullinterface) + procedure dokeydown(var info: keyeventinfoty); + procedure updatereadonlystate; + procedure internalcreateframe; + procedure mouseevent(var info: mouseeventinfoty); + procedure domousewheelevent(var info: mousewheeleventinfoty); + procedure editnotification(var info: editnotificationinfoty); + end; + +const + defaultoptionsedit = [oe_undoonesc,oe_closequery,oe_exitoncursor, + oe_focusrectonreadonly, + oe_shiftreturn,oe_eatreturn, + oe_autoselect,oe_endonenter, + oe_autoselectonfirstclick, + oe_resetselectonexit, + oe_checkmrcancel]; + defaultoptionsedit1 = [oe1_autopopupmenu,oe1_keyexecute, + oe1_checkvalueafterstatread,oe1_savevalue,oe1_savestate]; + + nullcoord: gridcoordty = (col: 0; row: 0); + invalidcell: gridcoordty = (col: invalidaxis; row: invalidaxis); + bigcoord: gridcoordty = (col: bigint; row: bigint); + +function makegridcoord(col: integer; row: integer): gridcoordty; {$ifdef FPC}inline;{$endif} + {$ifdef FPC}inline;{$endif} +function mgc(col: integer; row: integer): gridcoordty; {$ifdef FPC}inline;{$endif} + {$ifdef FPC}inline;{$endif} +function makegridsize(colcount: integer; rowcount: integer): gridsizety; + {$ifdef FPC}inline;{$endif} +function mgs(colcount: integer; rowcount: integer): gridsizety; + {$ifdef FPC}inline;{$endif} +function makegridrect(const pos: gridcoordty; const size: gridsizety): gridrectty; overload; + {$ifdef FPC}inline;{$endif} +function mgr(const pos: gridcoordty; const size: gridsizety): gridrectty; overload; + {$ifdef FPC}inline;{$endif} +function makegridrect(const start,stop: gridcoordty): gridrectty; overload; + //normalized rect, includes start and stop +function mgr(const start,stop: gridcoordty): gridrectty; overload; + //normalized rect, includes start and stop + +function gridcoordisequal(const a,b: gridcoordty): boolean; + +procedure transferoptionsedit(const sender: tcomponent; + const source: optionseditty; var dest: optionseditty; + var dest1: optionsedit1ty); + //move deprecated flags + +implementation +uses + msebits; + +function makegridcoord(col: integer; row: integer): gridcoordty; +begin + result.col:= col; + result.row:= row; +end; + +function mgc(col: integer; row: integer): gridcoordty; +begin + result.col:= col; + result.row:= row; +end; + +function gridcoordisequal(const a,b: gridcoordty): boolean; +begin + result:= (a.col = b.col) and (a.row = b.row); +end; + +function makegridsize(colcount: integer; rowcount: integer): gridsizety; +begin + result.colcount:= colcount; + result.rowcount:= rowcount; +end; + +function mgs(colcount: integer; rowcount: integer): gridsizety; +begin + result.colcount:= colcount; + result.rowcount:= rowcount; +end; + +function makegridrect(const pos: gridcoordty; const size: gridsizety): gridrectty; overload; +begin + result.pos:= pos; + result.size:= size; +end; + +function mgr(const pos: gridcoordty; const size: gridsizety): gridrectty; overload; +begin + result.pos:= pos; + result.size:= size; +end; + +function makegridrect(const start,stop: gridcoordty): gridrectty; overload; +begin + if stop.col >= start.col then begin + result.col:= start.col; + result.colcount:= stop.col - start.col + 1; + end + else begin + result.col:= stop.col; + result.colcount:= start.col - stop.col + 1; + end; + if stop.row >= start.row then begin + result.row:= start.row; + result.rowcount:= stop.row - start.row + 1; + end + else begin + result.row:= stop.row; + result.rowcount:= start.row - stop.row + 1; + end; +end; + +function mgr(const start,stop: gridcoordty): gridrectty; overload; +begin + if stop.col >= start.col then begin + result.col:= start.col; + result.colcount:= stop.col - start.col + 1; + end + else begin + result.col:= stop.col; + result.colcount:= start.col - stop.col + 1; + end; + if stop.row >= start.row then begin + result.row:= start.row; + result.rowcount:= stop.row - start.row + 1; + end + else begin + result.row:= stop.row; + result.rowcount:= start.row - stop.row + 1; + end; +end; + +procedure transferoptionsedit(const sender: tcomponent; + const source: optionseditty; var dest: optionseditty; + var dest1: optionsedit1ty); +begin + dest:= source - deprecatedoptionsedit; + if (csreading in sender.componentstate) and + (source * deprecatedoptionsedit <> []) then begin + updatebit(longword(dest1),ord(oe1_savevalue), + oe_savevalue in source); + updatebit(longword(dest1),ord(oe1_savestate), + oe_savestate in source); + updatebit(longword(dest1),ord(oe1_saveoptions), + oe_saveoptions in source); + updatebit(longword(dest1),ord(oe1_checkvalueafterstatread), + oe_checkvaluepaststatread in source); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/mseforms.pas b/mseide-msegui/lib/common/widgets/mseforms.pas new file mode 100644 index 0000000..e681cea --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseforms.pas @@ -0,0 +1,3308 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseforms; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +uses + msewidgets,msemenus,msegraphics,mseapplication,msegui,msegraphutils,mseevent, + msetypes,msestrings,mseglob,mseguiglob,mseguiintf,msedragglob,msepointer, + msemenuwidgets,msestat,msestatfile,mseclasses,classes,mclasses,msedock, + msesimplewidgets,msebitmap,typinfo,msesplitter,mseobjectpicker,msetabs, + mseassistiveclient + {$ifdef mse_with_ifi},mseifiglob,mseificompglob,mseificomp{$endif}; + +{$if defined(FPC) and (fpc_fullversion >= 020403)} + {$define mse_fpc_2_4_3} +{$ifend} + +type + formoptionty = (fo_main,fo_terminateonclose,fo_freeonclose, + fo_windowclosecancel, + fo_defaultpos,fo_screencentered,fo_screencenteredvirt, + fo_transientforcentered,fo_mainwindowcentered, + fo_modal,fo_createmodal, + fo_minimized,fo_maximized,fo_fullscreen,fo_fullscreenvirt, + fo_closeonesc,fo_cancelonesc,fo_closeonenter,fo_closeonf10, + fo_keycloseifwinonly,fo_nowindowclose, + fo_globalshortcuts,fo_localshortcuts, + fo_autoreadstat,fo_delayedreadstat,fo_autowritestat, + fo_savepos,fo_savezorder,fo_savestate); + formoptionsty = set of formoptionty; + +const + defaultformoptions = [fo_autoreadstat,fo_autowritestat, + fo_savepos,fo_savezorder,fo_savestate]; + defaultmainformoptions = defaultformoptions + [fo_main,fo_terminateonclose]; + defaultmainformoptionswindow = [wo_groupleader,wo_taskbar]; + + defaultformwidgetoptions = (defaultoptionswidgetmousewheel - + [{ow_mousefocus}{,ow_tabfocus}]) + [ow_subfocus,ow_hinton]; + defaultcontaineroptionswidget = defaultoptionswidgetmousewheel + + [ow_subfocus,ow_mousetransparent]; + +type + tcustommseform = class; + closequeryeventty = procedure(const sender: tcustommseform; + var amodalresult: modalresultty) of object; + + tformscrollbox = class(tscrollingwidgetnwr) + //for internal use only + private + procedure readdummy(reader: treader); + procedure writedummy(writer: twriter); + procedure readbounds(reader: treader); + procedure writebounds(writer: twriter); + protected + fboundsread: boolean; + procedure setoptionswidget(const avalue: optionswidgetty); override; + procedure defineproperties(filer: tfiler); override; + procedure clientrectchanged; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure docheckautosize; + function getassistiveflags(): assistiveflagsty override; + public + constructor create(aowner: tcustommseform); reintroduce; + procedure dolayout(const sender: twidget); override; + published + property onscroll; + property onscrolled; + property onresize; + property onfontheightdelta; + property onlayout; + property oncalcminscrollsize; + property onchildmouseevent; + property onmouseevent; + property onclientmouseevent; + property onmousewheelevent; + property onbeforepaint; + property onpaint; + property onafterpaint; + property optionswidget default defaultcontaineroptionswidget; + end; + + syseventeventty = procedure(const sender: tcustommseform; + var aevent: syseventty; var handled: boolean) of object; + + formstatety = (fos_statreading); + formstatesty = set of formstatety; + optionsizingty = (osi_left,osi_top,osi_right,osi_bottom); + optionssizingty = set of optionsizingty; + + tcustommseform = class(tcustomeventwidget,istatfile,idockcontroller + {$ifdef mse_with_ifi},iififormlink{$endif}) + private + foncreate: notifyeventty; + foncreated: notifyeventty; + fonloaded: notifyeventty; + fondestroyed: notifyeventty; + foneventloopstart: notifyeventty; + fondestroy: notifyeventty; + fonbeforeclosequery: closequeryeventty; + fonclosequery: closequeryeventty; + fonclose: notifyeventty; + fonidle: idleeventty; + fonterminatequery: terminatequeryeventty; + fonterminated: notifyeventty; + fmainmenu: tmainmenu; + foptions: formoptionsty; + fstatfile: tstatfile; + fcaption: msestring; + fmainmenuwidget: tframemenuwidget; + foptionswindow: windowoptionsty; + fonstatread: statreadeventty; + fonstatafterread: notifyeventty; + fonstatbeforeread: notifyeventty; + fonstatafterwrite: notifyeventty; + fonstatbeforewrite: notifyeventty; + fonstatupdate: statupdateeventty; + fstatvarname: msestring; + fonstatwrite: statwriteeventty; + fonwidgetactivechanged: widgetchangeeventty; + fonwindowactivechanged: windowchangeeventty; + fonwindowdestroyed: windoweventty; + fonapplicationactivechanged: booleaneventty; + fonfontheightdelta: fontheightdeltaeventty; + ficon: tmaskedbitmap; + ficonchanging: integer; + fonsysevent: syseventeventty; + fonsyswindowevent: syseventeventty; + fonapplicationevent: applicationeventeventty; + factivatortarget: tactivator; + fstatpriority: integer; + ftaborderoverride: ttaborderoverride; +{$ifdef mse_with_ifi} + fifilink: tififormlinkcomp; + fwindowopacity: realty; + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tififormlinkcomp); +{$endif} + function getonlayout: notifyeventty; + procedure setonlayout(const avalue: notifyeventty); + procedure setmainmenu(const Value: tmainmenu); + procedure updatemainmenutemplates; + procedure setoptions(const Value: formoptionsty); + procedure setoptionswindow(const Value: windowoptionsty); + procedure setstatfile(const avalue: tstatfile); + procedure setscrollbox(const avalue: tformscrollbox); + function getonafterpaint: painteventty; + function getonbeforepaint: painteventty; + function getonpaint: painteventty; + procedure setonafterpaint(const Value: painteventty); + procedure setonbeforepaint(const Value: painteventty); + procedure setonpaint(const Value: painteventty); + procedure seticon(const avalue: tmaskedbitmap); + procedure registerhandlers; + procedure unregisterhandlers; + procedure setonsysevent(const avalue: syseventeventty); + procedure setonsyswindowevent(const avalue: syseventeventty); + procedure setonapplicationevent(const avalue: applicationeventeventty); + procedure readonchildscaled(reader: treader); + procedure setactivatortarget(const avalue: tactivator); + procedure settaborderoverride(const avalue: ttaborderoverride); + procedure setwindowopacity(const avalue: realty); + protected + fformstate: formstatesty; + fscrollbox: tformscrollbox; //needed to distinguish between scrolled and + //unscrolled (mainmenu...) widgets + function internalgeticon(): tmaskedbitmap; virtual; + procedure iconchanged(const sender: tobject); + procedure aftercreate; virtual; + function createmainmenuwidget: tframemenuwidget; virtual; + function ismainwindow(): boolean virtual; + procedure updateoptions; virtual; + function getoptions: formoptionsty; virtual; + procedure updatescrollboxrect; + procedure internalsetwidgetrect(Value: rectty; + const windowevent: boolean); override; + procedure clientrectchanged; override; + procedure rootchanged(const aflags: rootchangeflagsty) override; + procedure setparentwidget(const Value: twidget); override; + procedure updatewindowinfo(var info: windowinfoty); override; + function isgroupleader: boolean; override; + + procedure readstate(reader: treader); override; + procedure defineproperties(filer: tfiler); override; + procedure dooncreate; virtual; + procedure doafterload; override; + procedure loaded; override; + procedure autoreadstat; + procedure setoptionswidget(const avalue: optionswidgetty); override; + function nexttaborderoverride(const sender: twidget; + const down: boolean): twidget override; + + function getcaption: msestring; + procedure setcaption(const Value: msestring); virtual; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; + procedure doeventloopstart; virtual; + procedure doterminated(const sender: tobject); virtual; + procedure doterminatequery(var terminate: boolean); virtual; + procedure doidle(var again: boolean); virtual; + procedure dowidgetactivechanged(const oldwidget,newwidget: twidget); virtual; + procedure dowindowactivechanged(const oldwindow,newwindow: twindow); virtual; + procedure dowindowdestroyed(const awindow: twindow); virtual; + procedure doapplicationactivechanged(const avalue: boolean); virtual; + procedure dosysevent(const awindow: winidty; var aevent: syseventty; + var handled: boolean); virtual; + procedure doapplicationevent(var aevent: tmseevent; + var handled: boolean) virtual; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure receiveevent(const event: tobjectevent); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + procedure windowcreated; override; + procedure dofontheightdelta(var delta: integer); override; + procedure widgetregionchanged(const sender: twidget); override; + + function getcontainer: twidget; override; + function getchildwidgets(const index: integer): twidget; override; + procedure getautopaintsize(var asize: sizety); override; + + procedure dostatread1(const reader: tstatreader); virtual; + procedure dostatwrite1(const writer: tstatwriter); virtual; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; virtual; + procedure statread; virtual; + function getstatvarname: msestring; + function getstatpriority: integer; + function getwindowcaption: msestring; virtual; + //idockcontroller + function getchildicon: tmaskedbitmap; virtual; + function checkdock(var info: draginfoty): boolean; + function getbuttonrects(const index: dockbuttonrectty): rectty; + function getplacementrect: rectty; + function getminimizedsize(out apos: captionposty): sizety; + procedure dolayoutchanged(const sender: tdockcontroller); virtual; + procedure dodockcaptionchanged(const sender: tdockcontroller); virtual; + + procedure updatelayout(const sender: twidget); virtual; + //called from scrollbox.dolayout + //iassistiveclient + function getassistivecaption(): msestring override; + //iificommand + {$ifdef mse_with_ifi} + procedure executeificommand(var acommand: ificommandcodety); override; + //iififormlink + procedure setmodalresult(const avalue: modalresultty); + {$endif} + + procedure docreate(aowner: tcomponent); virtual; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); reintroduce; overload; virtual; + destructor destroy; override; + procedure afterconstruction; override; + procedure freeinstance override; + procedure reload(const callafterload: boolean = false); + procedure writestate(writer: twriter); override; + + procedure insertwidget(const widget: twidget; const apos: pointty); override; + procedure dolayout(const sender: twidget); override; + function childrencount: integer; override; + + procedure beforeclosequery(var amodalresult: modalresultty); override; + procedure doonclose; virtual; + function canclose(const newfocus: twidget): boolean; override; + function close(const amodalresult: modalresultty = mr_windowclosed): boolean; + //true if ok + procedure beforedestruction; override; + property optionswidget default defaultformwidgetoptions; + property optionswindow: windowoptionsty read foptionswindow + write setoptionswindow default []; + property mainmenu: tmainmenu read fmainmenu write setmainmenu; + property font: twidgetfont read getfont write setfont stored isfontstored; + property fontempty: twidgetfontempty read getfontempty + write setfontempty stored isfontemptystored; + property options: formoptionsty read getoptions write setoptions + default defaultformoptions; + + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + + property caption: msestring read getcaption write setcaption; + property icon: tmaskedbitmap read ficon write seticon; + property windowopacity: realty read fwindowopacity write setwindowopacity; + //emptyreal -> undefined, 0.0 -> trasparent, 1.0 -> opaque + //default = emptyreal + + property oncreate: notifyeventty read foncreate write foncreate; + property oncreated: notifyeventty read foncreated write foncreated; + property onloaded: notifyeventty read fonloaded write fonloaded; + property oneventloopstart: notifyeventty read foneventloopstart + write foneventloopstart; + property ondestroy: notifyeventty read fondestroy write fondestroy; + property ondestroyed: notifyeventty read fondestroyed write fondestroyed; + property onbeforeclosequery: closequeryeventty read fonbeforeclosequery + write fonbeforeclosequery; + property onclosequery: closequeryeventty read fonclosequery + write fonclosequery; + property onclose: notifyeventty read fonclose write fonclose; + property onidle: idleeventty read fonidle write fonidle; + property onterminatequery: terminatequeryeventty read fonterminatequery + write fonterminatequery; + property onterminated: notifyeventty read fonterminated + write fonterminated; + + property onbeforepaint: painteventty read getonbeforepaint + write setonbeforepaint; + property onpaint: painteventty read getonpaint write setonpaint; + property onafterpaint: painteventty read getonafterpaint + write setonafterpaint; + + property onstatupdate: statupdateeventty read fonstatupdate + write fonstatupdate; + property onstatread: statreadeventty read fonstatread write fonstatread; + property onstatbeforeread: notifyeventty read fonstatbeforeread + write fonstatbeforeread; + property onstatafterread: notifyeventty read fonstatafterread + write fonstatafterread; + property onstatwrite: statwriteeventty read fonstatwrite write fonstatwrite; + property onstatbeforewrite: notifyeventty read fonstatbeforewrite + write fonstatbeforewrite; + property onstatafterwrite: notifyeventty read fonstatafterwrite + write fonstatafterwrite; + + property onwidgetactivechanged: widgetchangeeventty + read fonwidgetactivechanged write fonwidgetactivechanged; + property onwindowactivechanged: windowchangeeventty + read fonwindowactivechanged write fonwindowactivechanged; + property onwindowdestroyed: windoweventty read fonwindowdestroyed + write fonwindowdestroyed; + property onapplicationactivechanged: booleaneventty + read fonapplicationactivechanged write fonapplicationactivechanged; + + property onfontheightdelta: fontheightdeltaeventty read fonfontheightdelta + write fonfontheightdelta; + property onlayout: notifyeventty read getonlayout write setonlayout; + property onsysevent: syseventeventty read fonsysevent write setonsysevent; + property onsyswindowevent: syseventeventty read fonsyswindowevent + write setonsyswindowevent; + property onapplicationevent: applicationeventeventty + read fonapplicationevent write setonapplicationevent; + published + property container: tformscrollbox read fscrollbox write setscrollbox; +{$ifdef mse_with_ifi} + property ifilink: tififormlinkcomp read fifilink write setifilink; +{$endif} + property activatortarget: tactivator read factivatortarget + write setactivatortarget; + property taborderoverride: ttaborderoverride read ftaborderoverride + write settaborderoverride; + property onshortcut; + end; + + custommseformclassty = class of tcustommseform; + + tmseformwidget = class(tcustommseform) + published + property optionswidget; + property optionsskin; + property optionswindow; + property mainmenu; + property color; + property font; + property fontempty; + property options; + property statfile; + property statvarname; + property statpriority; + property caption; + property icon; + property windowopacity; + + property oncreate; + property oncreated; + property onloaded; + property oneventloopstart; + property ondestroy; + property ondestroyed; + property onbeforeclosequery; + property onclosequery; + property onclose; + property onidle; + property onwidgetactivechanged; + property onwindowactivechanged; + property onwindowdestroyed; + property onapplicationactivechanged; + property onterminatequery; + property onterminated; + + property onmouseevent; + property onclientmouseevent; + property onchildmouseevent; + property onmousewheelevent; + property onkeydown; + property onkeyup; + property onshortcut; + + property onbeforepaint; + property onpaint; + property onafterpaint; + + property onmove; + property onresize; + property onshow; + property onactivate; + property onenter; + property onexit; + property onfocusedwidgetchanged; + property ondeactivate; + property onhide; + property onevent; + property oncomponentevent; + property onasyncevent; + + property onstatupdate; + property onstatread; + property onstatbeforeread; + property onstatafterread; + property onstatwrite; + property onstatbeforewrite; + property onstatafterwrite; + + property onfontheightdelta; + property onlayout; + + property onsysevent; + property onsyswindowevent; + property onapplicationevent; + end; + + tmseform = class(tmseformwidget) + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + public + constructor create(aowner: tcomponent; load: boolean); override; + end; + + tmainform = class(tmseform) + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure aftercreate; override; + public + published + property options default defaultmainformoptions; + property optionswindow default defaultmainformoptionswindow; + end; + + mainformclassty = class of tmainform; + tcustomdockform = class; + + optiondockformty = (odf_main,odf_childicons,odf_mainchildicon,odf_maintaskbar, + odf_mainmainwindow); //is mainwindow if it contains + //an odf_main dock + optionsdockformty = set of optiondockformty; + +const + defaultoptionsdockform = [odf_childicons,odf_mainchildicon,odf_maintaskbar, + odf_mainmainwindow]; + +type + tformdockcontroller = class(tnochildrendockcontroller) + private + procedure setoptionsdockform(const avalue: optionsdockformty); + protected + fowner: tcustomdockform; + foptionsdockform: optionsdockformty; + function hasmain(): boolean; + procedure setoptionsdock(const avalue: optionsdockty); override; + procedure dolayoutchanged(); override; + procedure childstatechanged(const sender: twidget; + const newstate,oldstate: widgetstatesty); override; + public + constructor create(const aowner: tcustomdockform); + function childicon(): tmaskedbitmap override; + published + property optionsdockform: optionsdockformty read foptionsdockform + write setoptionsdockform default defaultoptionsdockform; + end; + + tcustomdockform = class(tcustommseform,idocktarget) + private + fdockingareacaption: msestring; + function getdockcontroller: tdockcontroller; + procedure setdragdock(const Value: tformdockcontroller); + function getframe: tgripframe; + procedure setframe(const avalue: tgripframe); + procedure setdockingareacaption(const avalue: msestring); + protected + fdragdock: tformdockcontroller; + fhasdocktaskbaricon: boolean; + function ismainwindow(): boolean override; + function needsdocktaskbaricon(): boolean; + procedure updatewindowinfo(var info: windowinfoty) override; + procedure internalcreateframe; override; + function internalgeticon(): tmaskedbitmap; override; + procedure updateoptions; override; + function getoptions: formoptionsty; override; + procedure statreading; override; + procedure statread; override; + procedure dostatread1(const reader: tstatreader); override; + procedure dostatwrite1(const writer: tstatwriter); override; +// procedure dokeydown(var info: keyeventinfoty) override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure statechanged; override; + procedure poschanged; override; + procedure activechanged; override; + procedure doactivate; override; + procedure parentchanged; override; + function getwindowcaption: msestring; override; + procedure dolayoutchanged(const sender: tdockcontroller); override; + procedure checkdockicon(); + function getchildicon(): tmaskedbitmap; override; + procedure loaded(); override; + procedure doenter(); override; + procedure doexit(); override; + public + constructor create(aowner: tcomponent; load: boolean); override; + destructor destroy(); override; + procedure activate(const abringtofront: boolean = true; + const aforce: boolean = false); override; + function canfocus: boolean; override; + procedure dragevent(var info: draginfoty); override; + property dockingareacaption: msestring read fdockingareacaption + write setdockingareacaption; + published + property dragdock: tformdockcontroller read fdragdock write setdragdock; + property frame: tgripframe read getframe write setframe; + end; + + tdockformwidget = class(tcustomdockform) + published + property optionswidget; + property optionsskin; + property optionswindow; + property mainmenu; + property color; + property font; + property fontempty; + property options; + property statfile; + property statvarname; + property statpriority; + property caption; + property icon; + property dockingareacaption; + + property oncreate; + property oncreated; + property onloaded; + property oneventloopstart; + property ondestroy; + property ondestroyed; + property onbeforeclosequery; + property onclosequery; + property onclose; + property onidle; + property onwidgetactivechanged; + property onwindowactivechanged; + property onwindowdestroyed; + property onapplicationactivechanged; + property onterminatequery; + property onterminated; + + property onmouseevent; + property onclientmouseevent; + property onchildmouseevent; + property onmousewheelevent; + property onkeydown; + property onkeyup; + property onshortcut; + + property onbeforepaint; + property onpaint; + property onafterpaint; + + property onmove; + property onresize; + property onshow; + property onactivate; + property onenter; + property onexit; + property onfocusedwidgetchanged; + property ondeactivate; + property onhide; + property onevent; + property oncomponentevent; + property onasyncevent; + + property onstatupdate; + property onstatread; + property onstatbeforeread; + property onstatafterread; + property onstatwrite; + property onstatbeforewrite; + property onstatafterwrite; + + property onfontheightdelta; + property onlayout; + + property onsysevent; + property onsyswindowevent; + end; + + tdockform = class(tdockformwidget) + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + public + constructor create(aowner: tcomponent; load: boolean); override; + end; + + tdockformscrollbox = class(tformscrollbox,idocktarget) + protected + procedure clientrectchanged; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure dopaintforeground(const acanvas: tcanvas); override; + function getdockcontroller: tdockcontroller; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure dopaintbackground(const canvas: tcanvas); override; + public + constructor create(aowner: tcustomdockform); reintroduce; + end; + + tsubform = class(tlayouter) + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); + reintroduce; overload; virtual; + published + property onloaded; + end; + + subformclassty = class of tsubform; + + tscrollboxform = class(tscrollbox) + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); + reintroduce; overload; virtual; + end; + + scrollboxformclassty = class of tscrollboxform; + + ttabformfonttab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabformfontactivetab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabform = class(tmseform,itabpage,iimagelistinfo) + private + ftabwidget: tcustomtabwidget; + fimagelist: timagelist; + fimagenr: integer; + fimagenrdisabled: integer; + fcolortab,fcoloractivetab: colorty; + ffacetab,ffaceactivetab: tfacecomp; + ftabhint: msestring; + ftabnoface: boolean; + fonselect: notifyeventty; + fondeselect: notifyeventty; + finvisible: boolean; + ffonttab: ttabformfonttab; + ffontactivetab: ttabformfontactivetab; + procedure settabwidget(const value: tcustomtabwidget); + function gettabwidget: tcustomtabwidget; + function getcolortab: colorty; + procedure setcolortab(const avalue: colorty); + function getcoloractivetab: colorty; + procedure setcoloractivetab(const avalue: colorty); + function gettabindex: integer; + procedure settabindex(const avalue: integer); + function gettabhint: msestring; + procedure settabhint(const avalue: msestring); + function gettabnoface: boolean; + procedure settabnoface(const avalue: boolean); + function getimagelist: timagelist; + procedure setimagelist(const avalue: timagelist); + function getimagenr: imagenrty; + procedure setimagenr(const avalue: imagenrty); + function getimagenrdisabled: imagenrty; + procedure setimagenrdisabled(const avalue: imagenrty); + function getinvisible: boolean; + procedure setinvisible(const avalue: boolean); + function getfonttab: tfont; + function getfontactivetab: tfont; + function getfonttab1: ttabformfonttab; + procedure setfonttab1(const avalue: ttabformfonttab); + procedure setfonttab(const avalue: tfont); + function isfonttabstored: boolean; + function getfontactivetab1: ttabformfontactivetab; + procedure setfontactivetab1(const avalue: ttabformfontactivetab); + procedure setfontactivetab(const avalue: tfont); + function isfontactivetabstored: boolean; + function getfacetab: tfacecomp; + procedure setfacetab(const avalue: tfacecomp); + function getfaceactivetab: tfacecomp; + procedure setfaceactivetab(const avalue: tfacecomp); + protected + class function getmoduleclassname: string; override; + procedure changed; + procedure fontchanged1(const sender: tobject); + procedure visiblechanged; override; + procedure setcaption(const value: msestring); override; + procedure doselect; virtual; + procedure dodeselect; virtual; + procedure loaded; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + class function hasresource: boolean; override; +// constructor docreate(aowner: tcomponent); override; + procedure docreate(aowner: tcomponent); override; + class function classskininfo: skininfoty; override; + public + destructor destroy; override; + procedure createfonttab; + procedure createfontactivetab; + function isactivepage: boolean; + property tabwidget: tcustomtabwidget read ftabwidget; + property tabindex: integer read gettabindex write settabindex; + published + property color default cl_default; + property colortab: colorty read getcolortab + write setcolortab default cl_default; + property coloractivetab: colorty read getcoloractivetab + write setcoloractivetab default cl_default; + property facetab: tfacecomp read getfacetab write setfacetab; + property faceactivetab: tfacecomp read getfaceactivetab + write setfaceactivetab; + property fonttab: ttabformfonttab read getfonttab1 write setfonttab1 + stored isfonttabstored; + property fontactivetab: ttabformfontactivetab read getfontactivetab1 + write setfontactivetab1 stored isfontactivetabstored; + property tabhint: msestring read gettabhint write settabhint; + property tabnoface: boolean read gettabnoface + write settabnoface default false; + property imagelist: timagelist read getimagelist write setimagelist; + property imagenr: imagenrty read getimagenr write setimagenr default -1; + property imagenrdisabled: imagenrty read getimagenrdisabled + write setimagenrdisabled default -2; + //-2 -> same as imagenr + property onselect: notifyeventty read fonselect write fonselect; + property ondeselect: notifyeventty read fondeselect write fondeselect; + property invisible: boolean read getinvisible write setinvisible default false; + property visible default false; + property optionsskin; + end; + + tabformclassty = class of ttabform; + +function createmseform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function createmainform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function createsubform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function createscrollboxform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function createtabform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +implementation +uses + sysutils,mselist,msekeyboard,msebits,msestreaming,msestockobjects; +const + containercommonflags: optionswidgetty = + [ow_arrowfocus,ow_arrowfocusin,ow_arrowfocusout,ow_destroywidgets, + ow_parenttabfocus,ow_mousewheel{, + ow_subfocus,ow_mousefocus,ow_tabfocus}]; + +type + tcomponent1 = class(tcomponent); + tmsecomponent1 = class(tmsecomponent); + twidget1 = class(twidget); + twindow1 = class(twindow); + tcustomframe1 = class(tcustomframe); + treader1 = class(treader); + tframemenuwidget1 = class(tframemenuwidget); + tcustomtabwidget1 = class(tcustomtabwidget); + ttaborderoverride1 = class(ttaborderoverride); + + +function createmseform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +begin + result:= custommseformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function createmainform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +begin + result:= tmsecomponent(aclass.newinstance); +{$warnings off} + tcomponent1(result).setdesigning(true); //used for wo_groupleader +{$warnings on} + tcustommseform(result).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function createsubform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= subformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function createscrollboxform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= scrollboxformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function createtabform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= tabformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +{ tformscrollbox} + +constructor tformscrollbox.create(aowner: tcustommseform); +begin +// fowner:= aowner; + inherited create(aowner); //dockcontroller needs owner + setsubcomponent(true); + exclude(fwidgetstate,ws_iswidget); + include(fwidgetstate1,ws1_designactive); + foptionswidget:= defaultcontaineroptionswidget; +// parentwidget:= aowner; + setlockedparentwidget(aowner); + name:= 'container'; +end; + +procedure tformscrollbox.setoptionswidget(const avalue: optionswidgetty); +begin + if fparentwidget <> nil then begin + replacebits1(longword(twidget1(fparentwidget).foptionswidget),longword(avalue), + longword(containercommonflags)); + end; + inherited; +end; + +procedure tformscrollbox.readdummy(reader: treader); +begin + reader.driver.skipvalue; +end; + +procedure tformscrollbox.writedummy(writer: twriter); +begin + //dummy +end; + +procedure tformscrollbox.readbounds(reader: treader); +var + rect1: rectty; +begin + reader.readlistbegin; + rect1.x:= reader.readinteger; + rect1.y:= reader.readinteger; + rect1.cx:= reader.readinteger; + rect1.cy:= reader.readinteger; + reader.readlistend; + widgetrect:= rect1; + fboundsread:= true; +end; + +procedure tformscrollbox.writebounds(writer: twriter); +begin + writer.writelistbegin; + writer.writeinteger(fwidgetrect.x); + writer.writeinteger(fwidgetrect.y); + writer.writeinteger(fwidgetrect.cx); + writer.writeinteger(fwidgetrect.cy); + writer.writelistend; +end; + +procedure tformscrollbox.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('bounds_x',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds_y',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds_cx',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds_cy',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds_cxmin',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds_cymax',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('anchors',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds',{$ifdef FPC}@{$endif}readbounds, + {$ifdef FPC}@{$endif}writebounds,true); +end; + +procedure tformscrollbox.dolayout(const sender: twidget); +begin + if owner <> nil then begin + tcustommseform(owner).updatelayout(sender); + end; + inherited; +end; + +procedure tformscrollbox.docheckautosize; +begin + if owner <> nil then begin + with tcustommseform(owner) do begin + if optionswidget1 * [ow1_autowidth,ow1_autoheight] <> [] then begin + checkautosize; + end; + end; + end; +end; + +function tformscrollbox.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags(); + if twidget(owner).ownswindow then begin + include(result,asf_toplevel); + end; +end; + +procedure tformscrollbox.clientrectchanged; +begin + inherited; + docheckautosize; +end; + +procedure tformscrollbox.widgetregionchanged(const sender: twidget); +begin + inherited; + docheckautosize; +end; + +{ tdockformscrollbox } + +constructor tdockformscrollbox.create(aowner: tcustomdockform); +begin + inherited create(aowner); +end; + +procedure tdockformscrollbox.clientrectchanged; +begin + if not (ws_loadlock in fwidgetstate) and (owner <> nil) then begin + tcustomdockform(owner).fdragdock.beginclientrectchanged; + end; + inherited; + if not (ws_loadlock in fwidgetstate) and (owner <> nil) then begin + tcustomdockform(owner).fdragdock.endclientrectchanged; + end; +end; + +procedure tdockformscrollbox.widgetregionchanged(const sender: twidget); +begin + inherited; + if not (ws_loadlock in fwidgetstate) and + not (ws1_updateopaque in twidget1(sender).fwidgetstate1) then begin + tcustomdockform(owner).fdragdock.widgetregionchanged(sender); + end; +end; + +procedure tdockformscrollbox.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + tcustomdockform(owner).fdragdock.dopaint(acanvas); +end; + +function tdockformscrollbox.getdockcontroller: tdockcontroller; +begin + result:= tcustomdockform(owner).fdragdock; +end; + +procedure tdockformscrollbox.mouseevent(var info: mouseeventinfoty); +begin + inherited; + getdockcontroller.checkmouseactivate(self,info); +end; + +procedure tdockformscrollbox.dopaintbackground(const canvas: tcanvas); +begin + inherited; + with tcustomdockform(owner) do begin + if fdockingareacaption <> '' then begin + paintdockingareacaption(canvas,self,fdockingareacaption); + end; + end; +end; + +{ tcustommseform } + +procedure tcustommseform.docreate(aowner: tcomponent); +begin + inherited create(aowner); + fwidgetrect.cx:= 100; + fwidgetrect.cy:= 100; + if fscrollbox = nil then begin + fscrollbox:= tformscrollbox.create(self); + end; + optionswidget:= defaultformwidgetoptions; +end; + +procedure tcustommseform.aftercreate; +begin + //dummy +end; + +constructor tcustommseform.create(aowner: tcomponent; load: boolean); + +begin + ftaborderoverride:= ttaborderoverride.create(self); + ficon:= tmaskedbitmap.create(bmk_rgb); + ficon.onchange:= {$ifdef FPC}@{$endif}iconchanged; + fwindowopacity:= emptyreal; + fwidgetrect.x:= 100; + fwidgetrect.y:= 100; + foptions:= defaultformoptions; + docreate(aowner); + aftercreate; + registerhandlers; + if load and not (csdesigning in componentstate) and + (cs_ismodule in fmsecomponentstate) then begin + loadmsemodule(self,tcustommseform); + end; + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; + if not load then begin +// autoreadstat; + doafterload; + end; + if (fo_createmodal in foptions) and + (componentstate*[csdesigning,csdestroying,csloading] = []){ and + showing} then begin + show(true); + end; +end; + +constructor tcustommseform.create(aowner: tcomponent); +begin + create(aowner,not (cs_noload in fmsecomponentstate)); +end; + +destructor tcustommseform.destroy; +var + bo1: boolean; +begin + bo1:= csdesigning in componentstate; + include(fwidgetstate,ws_destroying); + unregisterhandlers; + mainmenu:= nil; + ficon.free; + fscrollbox.free; + fmainmenuwidget.free; + statfile:= nil; //unlink client connection + inherited; //csdesigningflag is removed + ftaborderoverride.free(); + if not bo1 and candestroyevent(tmethod(fondestroyed)) then begin + fondestroyed(self); + end; +end; + +procedure tcustommseform.afterconstruction; +begin + inherited; + if assigned(foncreated) then begin + foncreated(self); + end; +end; + +procedure tcustommseform.beforedestruction; +begin + inherited; + if candestroyevent(tmethod(fondestroy)) then begin + fondestroy(self); + end; +end; + +procedure tcustommseform.unregisterhandlers; +begin + application.unregisteronterminated({$ifdef FPC}@{$endif}doterminated); + application.unregisteronterminate({$ifdef FPC}@{$endif}doterminatequery); + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + application.unregisteronwidgetactivechanged( + {$ifdef FPC}@{$endif}dowidgetactivechanged); + application.unregisteronwindowactivechanged( + {$ifdef FPC}@{$endif}dowindowactivechanged); + application.unregisteronwindowdestroyed( + {$ifdef FPC}@{$endif}dowindowdestroyed); + application.unregisteronapplicationactivechanged( + {$ifdef FPC}@{$endif}doapplicationactivechanged); + if not (csdesigning in componentstate) and + (assigned(fonsysevent) or assigned(fonsyswindowevent)) then begin + application.unregistersyseventhandler({$ifdef FPC}@{$endif}dosysevent); + end; + if not (csdesigning in componentstate) and + assigned(fonapplicationevent) then begin + application.unregisterapplicationeventhandler(@doapplicationevent); + end; +end; + +procedure tcustommseform.registerhandlers; +begin + application.registeronterminated({$ifdef FPC}@{$endif}doterminated); + application.registeronterminate({$ifdef FPC}@{$endif}doterminatequery); + application.registeronidle({$ifdef FPC}@{$endif}doidle); + application.registeronwidgetactivechanged( + {$ifdef FPC}@{$endif}dowidgetactivechanged); + application.registeronwindowactivechanged( + {$ifdef FPC}@{$endif}dowindowactivechanged); + application.registeronwindowdestroyed({$ifdef FPC}@{$endif}dowindowdestroyed); + application.registeronapplicationactivechanged( + {$ifdef FPC}@{$endif}doapplicationactivechanged); +end; + +procedure tcustommseform.dooncreate; +begin + if not (cs_inheritedloading in msecomponentstate) then begin + include(factstate,acs_dooncreatecalled); + if assigned(foncreate) then begin //csloading possibly set + beginsuspendgloballoading; + try + foncreate(self); + finally + endsuspendgloballoading; + end; + end; + end; +end; + +procedure tcustommseform.doafterload; +begin + inherited; + autoreadstat; + if canevent(tmethod(fonloaded)) then begin + fonloaded(self); + end; +end; + +procedure tcustommseform.loaded; +begin + if (factivatortarget <> nil) and + not (csdesigning in componentstate) then begin + factivatortarget.activaterecursive(); + end; + exclude(fscrollbox.fwidgetstate,ws_loadlock); + if not (csdesigning in componentstate) then begin + if fo_screencentered in foptions then begin + window.windowpos:= wp_screencentered; + end; + if fo_screencenteredvirt in foptions then begin + window.windowpos:= wp_screencenteredvirt; + end; + end; + inherited; + if fmainmenuwidget <> nil then begin + fmainmenuwidget.visible:= true; +// fmainmenuwidget.loaded; +// include(tframemenuwidget1(fmainmenuwidget).fwidgetstate,ws_visible); + end; + updateoptions; + updatemainmenutemplates; + application.postevent(tobjectevent.create(ek_loaded,ievent(self)){,true}); + //to the OS queue +end; + +procedure tcustommseform.freeinstance; +begin + if (factivatortarget <> nil) and + not (csdesigning in componentstate) then begin + try + factivatortarget.deactivaterecursive; + finally + inherited; + end; + end + else begin + inherited; + end; +end; + +procedure tcustommseform.readstate(reader: treader); +var + bo1: boolean; +begin + include(fscrollbox.fwidgetstate,ws_loadlock); + bo1:= false; +{$warnings off} + with treader1(reader) do begin +{$warnings on} + if floaded <> nil then begin + if floaded.IndexOf(fscrollbox) < 0 then begin + floaded.add(fscrollbox); +{$warnings off} + tcomponent1(fscrollbox).FComponentState:= + tcomponent1(fscrollbox).FComponentState + [csloading]; +{$warnings on} + end; + end; + bo1:= not (csreading in fscrollbox.componentstate); + if bo1 then begin +{$warnings off} + tcomponent1(fscrollbox).FComponentState:= + tcomponent1(fscrollbox).FComponentState + [csreading]; +{$warnings on} + end; + end; + inherited; + ttaborderoverride1(ftaborderoverride).endread(reader); + if bo1 then begin +{$warnings off} + exclude(tcomponent1(fscrollbox).FComponentState,csreading); +{$warnings on} + end; + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; +end; + +procedure tcustommseform.reload(const callafterload: boolean = false); +begin + name:= ''; + unregisterhandlers; + try + reloadmsecomponent(self); + finally + registerhandlers; + end; + if callafterload then begin + doafterload; + end; +end; + +procedure tcustommseform.writestate(writer: twriter); +begin + tscrollboxframe(fscrollbox.frame).scrollpos:= nullpoint; + inherited; +end; + +{$ifdef mse_with_ifi} +procedure tcustommseform.executeificommand(var acommand: ificommandcodety); +begin + inherited; + case acommand of + icc_close: begin + application.postevent(tobjectevent.create(ek_closeform,ievent(self))); + end; + end; +end; + +procedure tcustommseform.setmodalresult(const avalue: modalresultty); +begin + window.modalresult:= avalue; +end; + +function tcustommseform.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iififormlink); +end; + +procedure tcustommseform.setifilink(const avalue: tififormlinkcomp); +begin + mseificomp.setifilinkcomp(iififormlink(self),avalue,tifilinkcomp(fifilink)); +end; + +{$endif} + +procedure tcustommseform.beforeclosequery(var amodalresult: modalresultty); +begin + inherited; + if canevent(tmethod(fonbeforeclosequery)) then begin + fonbeforeclosequery(self,amodalresult); + end; + if (amodalresult = mr_windowclosed) and + (fo_windowclosecancel in foptions) then begin + amodalresult:= mr_cancel; + end; +end; + +procedure tcustommseform.doonclose; +begin + if canevent(tmethod(fonclose)) then begin + fonclose(self); + end; +end; + +function tcustommseform.canclose(const newfocus: twidget): boolean; +var + modres: modalresultty; +begin + result:= inherited canclose(newfocus); + if result and (newfocus = nil) and ((fwindow = nil) or + not (tws_candefocus in fwindow.state)) then begin + modres:= twindow1(window).fmodalresult; + if (modres = mr_windowclosed) and (fo_nowindowclose in foptions) then begin + result:= false; + exit; + end; + if modres = mr_none then begin + modres:= mr_canclose; + end; + if canevent(tmethod(fonclosequery)) then begin + fonclosequery(self,modres); + end; + {$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.closequery(iificlient(self),modres); + end; + {$endif} + result:= modres <> mr_none; +// if twindow1(window).fmodalresult <> mr_canclose then begin + if modres <> mr_canclose then begin + twindow1(window).fmodalresult:= modres; + end; + if result and ((twindow1(window).fmodalresult <> mr_none) or + (application.terminating) or (ws1_forceclose in fwidgetstate1)) then begin + doonclose; + {$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.sendmodalresult(iificlient(self),window.modalresult); + end; + {$endif} + if (fo_terminateonclose in foptions) and not application.terminating and + not (csdesigning in componentstate) then begin + result:= application.terminate(window); + end; + if result and (fstatfile <> nil) and (fo_autowritestat in foptions) and + not (csdesigning in componentstate) then begin + fstatfile.writestat; + end; + if result and (fo_freeonclose in foptions) and + not (csdesigning in componentstate) then begin + release; + end; + end; + end; +end; + +function tcustommseform.close( + const amodalresult: modalresultty = mr_windowclosed): boolean; + //simulates mr_windowclose, true if ok +begin + if ownswindow then begin + result:= window.close(amodalresult); + end + else begin + result:= simulatemodalresult(self,amodalresult); + end; +end; + +procedure tcustommseform.doterminated(const sender: tobject); +begin + if canevent(tmethod(fonterminated)) then begin + fonterminated(sender); + end; +end; + +procedure tcustommseform.doterminatequery(var terminate: boolean); +begin + if canevent(tmethod(fonterminatequery)) then begin + fonterminatequery(terminate); + end; +end; + +procedure tcustommseform.doidle(var again: boolean); +begin + if canevent(tmethod(fonidle)) then begin + fonidle(again); + end; +end; + +procedure tcustommseform.dowidgetactivechanged(const oldwidget, + newwidget: twidget); +begin + if canevent(tmethod(fonwidgetactivechanged)) then begin + fonwidgetactivechanged(oldwidget,newwidget); + end; +end; + +procedure tcustommseform.dowindowactivechanged(const oldwindow, + newwindow: twindow); +begin + if canevent(tmethod(fonwindowactivechanged)) then begin + fonwindowactivechanged(oldwindow,newwindow); + end; +end; + +procedure tcustommseform.dowindowdestroyed(const awindow: twindow); +begin + if canevent(tmethod(fonwindowdestroyed)) then begin + fonwindowdestroyed(awindow); + end; +end; + +procedure tcustommseform.doapplicationactivechanged(const avalue: boolean); +begin + if canevent(tmethod(fonapplicationactivechanged)) then begin + fonapplicationactivechanged(avalue); + end; +end; + +procedure tcustommseform.getchildren(proc: tgetchildproc; root: tcomponent); +begin + inherited; + fscrollbox.getchildren(proc,root); + getcompchildren(proc,root); +end; + +procedure tcustommseform.setoptionswidget(const avalue: optionswidgetty); +begin + inherited; + replacebits1(longword(fscrollbox.foptionswidget),longword(avalue), + longword(containercommonflags)); +end; + +function tcustommseform.nexttaborderoverride(const sender: twidget; + const down: boolean): twidget; +begin + result:= ftaborderoverride.nexttaborder(sender,down); + if result = nil then begin + result:= inherited nexttaborderoverride(sender,down); + end; +end; + +procedure tcustommseform.doeventloopstart; +begin + if (fstatfile <> nil) and not (csdesigning in componentstate) and + (foptions*[fo_autoreadstat,fo_delayedreadstat] = + [fo_autoreadstat,fo_delayedreadstat]) then begin + fstatfile.readstat; + end; + if canevent(tmethod(foneventloopstart)) then begin + foneventloopstart(self); + end; +end; + +procedure tcustommseform.receiveevent(const event: tobjectevent); +var + rect1: rectty; +begin + inherited; + case event.kind of + ek_loaded: begin + doeventloopstart; + if (fo_modal in foptions) and + (componentstate*[csloading,csdesigning] = []){ and showing} then begin + show(true); + end; + end; + ek_closeform: begin + close; + end; + ek_checkscreenrange: begin + if ownswindow and visible and (window.windowpos = wp_normal) then begin + rect1:= window.decoratedwidgetrect; + if clipinrect1(rect1,application.screenrect) then begin + window.decoratedwidgetrect:= rect1; + end; + end; + end; + end; +end; + +function tcustommseform.getonlayout: notifyeventty; +begin + result:= fscrollbox.onlayout; +end; + +procedure tcustommseform.setonlayout(const avalue: notifyeventty); +begin + fscrollbox.onlayout:= avalue; +end; + +procedure tcustommseform.updatemainmenutemplates; +begin +// if not (csloading in componentstate) then begin + if (fmainmenuwidget <> nil) and + (fmainmenu <> nil) then begin + fmainmenuwidget.assigntemplate(fmainmenu.template); + end; + updatescrollboxrect; +// end; +end; + +function tcustommseform.createmainmenuwidget: tframemenuwidget; +begin + result:= tframemenuwidget.create(self,fmainmenu); +end; + +procedure tcustommseform.setmainmenu(const Value: tmainmenu); +begin + if value <> fmainmenu then begin + freeandnil(fmainmenuwidget); + setlinkedvar(value,tmsecomponent(fmainmenu)); + if value <> nil then begin + fmainmenuwidget:= createmainmenuwidget; +{$warnings off} + twidget1(fmainmenuwidget).setdesigning(csdesigning in componentstate); +{$warnings on} + updatemainmenutemplates; + end + else begin + updatescrollboxrect; + end; + end; +end; + +procedure tcustommseform.objectevent(const sender: tobject; + const event: objecteventty); +begin + if sender = fmainmenu then begin + case event of + oe_destroyed: begin + setmainmenu(nil); + end; + oe_changed: begin + if not (csdestroying in componentstate) then begin + updatemainmenutemplates; + if fmainmenuwidget <> nil then begin + fmainmenuwidget.menuchanged(nil); + end; + end; + end; + end; + end; + inherited; +end; + +procedure tcustommseform.setoptions(const Value: formoptionsty); +{$ifndef FPC} +const + mask1: formoptionsty = [fo_screencentered,fo_screencenteredvirt, + fo_transientforcentered,fo_mainwindowcentered, + fo_defaultpos]; + mask2: formoptionsty = [fo_closeonesc,fo_cancelonesc]; + mask3: formoptionsty = [fo_maximized,fo_minimized,fo_fullscreen, + fo_fullscreenvirt]; + mask4: formoptionsty = [fo_modal,fo_createmodal]; +{$endif} +//var +// opt1,opt2: formoptionsty; +begin + if foptions <> value then begin + {$ifdef FPC} + foptions:= formoptionsty(setsinglebit(longword(value),longword(foptions), + [longword([fo_screencentered,fo_screencenteredvirt, + fo_transientforcentered,fo_mainwindowcentered,fo_defaultpos]), + longword([fo_closeonesc,fo_cancelonesc]), + longword([fo_maximized,fo_minimized,fo_fullscreen,fo_fullscreenvirt]), + longword([fo_modal,fo_createmodal]) + ])); + {$else} + foptions:= formoptionsty(setsinglebitar32(longword(value),longword(foptions), + [longword(mask1),longword(mask2),longword(mask3),longword(mask4)])); + {$endif} +(* + opt1:= formoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask2))); + opt2:= formoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask3))); + foptions:= formoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask1))); + foptions:= formoptionsty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(opt1), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask2))); + foptions:= formoptionsty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(opt2), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask3))); +*) + updateoptions; + end; +end; + +function tcustommseform.ismainwindow(): boolean; +begin + result:= (fo_main in foptions) and not (csdesigning in componentstate); +end; + +procedure tcustommseform.updateoptions; +begin + if (componentstate * [csloading,csdestroying,csdesigning] = []) and + (window.owner = self) then begin + fwindow.globalshortcuts:= fo_globalshortcuts in foptions; + fwindow.localshortcuts:= fo_localshortcuts in foptions; + if ismainwindow() then begin + application.mainwindow:= fwindow; + end; + if fo_fullscreen in foptions then begin + fwindow.windowpos:= wp_fullscreen; + end + else begin + if fo_maximized in foptions then begin + fwindow.windowpos:= wp_maximized; + end + else begin + if fo_minimized in foptions then begin + fwindow.windowpos:= wp_minimized; + end + else begin + if fo_screencentered in foptions then begin + fwindow.windowpos:= wp_screencentered; + end + else begin + if fo_transientforcentered in foptions then begin + fwindow.windowpos:= wp_transientforcentered; + end + else begin + if fo_mainwindowcentered in foptions then begin + fwindow.windowpos:= wp_mainwindowcentered; + end + else begin + if fo_defaultpos in foptions then begin + fwindow.windowpos:= wp_default; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tcustommseform.getoptions: formoptionsty; +begin + result:= foptions; +end; + +procedure tcustommseform.setoptionswindow(const Value: windowoptionsty); +const + mask1: windowoptionsty = [wo_taskbar,wo_notaskbar]; +begin + foptionswindow:= windowoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptionswindow), + {$ifdef FPC}longword{$else}longword{$endif}(mask1))); +end; + +procedure tcustommseform.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +function tcustommseform.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustommseform.dostatread1(const reader: tstatreader); +var + rect1{,rect2}: rectty; + str1: string; + widget1: twidget; +begin + if fo_savepos in foptions then begin + rect1:= widgetrect; + with rect1 do begin + x:= reader.readinteger('x',x); + y:= reader.readinteger('y',y); + cx:= reader.readinteger('cx',cx,0); + cy:= reader.readinteger('cy',cy,0); + end; +// setclippedwidgetrect(rect1); + rect1:= clipinrect(rect1,application.screenrect); //shift into screen + widgetrect:= rect1; + application.postevent(tobjectevent.create(ek_checkscreenrange,ievent(self))); + end; + if fo_savezorder in foptions then begin + str1:= '~'; + str1:= reader.readstring('stackedunder',str1); + if str1 <> '~' then begin + if trim(str1) = '' then begin + window.stackunder(nil); + end + else begin + if application.findwidget(str1,widget1) and (widget1 <> nil) then begin + window.stackunder(widget1.window); + end; + end; + end; + end; +end; + +procedure tcustommseform.dostatread(const reader: tstatreader); +var + bo1: boolean; + pos1: windowposty; +begin + if canevent(tmethod(fonstatupdate)) then begin + fonstatupdate(self,reader); + end; + if canevent(tmethod(fonstatread)) then begin + fonstatread(self,reader); + end; + dostatread1(reader); + if fparentwidget = nil then begin + with reader do begin + if fo_savestate in foptions then begin + pos1:= windowposty(readinteger('wsize',ord(window.windowpos),0, + ord(high(windowposty)))); + bo1:= readboolean('visible',visible); + bo1:= visible or bo1; + if fo_main in foptions then begin + bo1:= true; + if pos1 = wp_minimized then begin + pos1:= wp_normal; + end; + end; + if bo1 then begin + if pos1 <> wp_minimized then begin + show; + end; + window.windowpos:= pos1; //does not work with kde and invisible window + end; + if readboolean('active',active) then begin + application.postevent(tobjectevent.create(ek_activate,ievent(self))); + //to the OS queue +// activate; + end; + end; + end; + end; +end; + +procedure tcustommseform.statreading; +begin + include(fformstate,fos_statreading); + if canevent(tmethod(fonstatbeforeread)) then begin + fonstatbeforeread(self); + end; +end; + +procedure tcustommseform.statread; +begin + exclude(fformstate,fos_statreading); + if canevent(tmethod(fonstatafterread)) then begin + fonstatafterread(self); + end; +end; + +procedure tcustommseform.dostatwrite1(const writer: tstatwriter); +var + window1: twindow; +begin + if fparentwidget = nil then begin + if fo_savezorder in foptions then begin + window1:= window.stackedunder; + if window1 <> nil then begin + writer.writestring('stackedunder',ownernamepath(window1.owner)); + end + else begin + writer.writestring('stackedunder',''); + end; + end; + if fo_savepos in foptions then begin + with window.normalwindowrect do begin + writer.writeinteger('x',x); + writer.writeinteger('y',y); + writer.writeinteger('cx',cx); + writer.writeinteger('cy',cy); + end; + end; + end; +end; + +procedure tcustommseform.dostatwrite(const writer: tstatwriter); +begin + if assigned(fonstatbeforewrite) then begin + fonstatbeforewrite(self); + end; + if assigned(fonstatupdate) then begin + fonstatupdate(self,writer); + end; + if assigned(fonstatwrite) then begin + fonstatwrite(self,writer); + end; + dostatwrite1(writer); + if fparentwidget = nil then begin + with writer do begin + if fo_savestate in foptions then begin + writeinteger('wsize',ord(window.windowpos)); + writeboolean('active',active); + writeboolean('visible',visible); + end; + end; + end; + if assigned(fonstatafterwrite) then begin + fonstatafterwrite(self); + end; +end; + +procedure tcustommseform.updatescrollboxrect; +var + rect1: rectty; +begin + if not (ws_destroying in fwidgetstate) and + (not (csloading in componentstate) or + not fscrollbox.fboundsread) then begin + rect1:= innerwidgetrect; + if fmainmenuwidget <> nil then begin + with tframemenuwidget1(fmainmenuwidget) do begin + setwidgetrect(makerect(self.paintpos,makesize( + self.paintsize.cx,bounds_cy))); + updatelayout(); + inc(rect1.y,bounds_cy); + dec(rect1.cy,bounds_cy); + end; + end; + if fscrollbox <> nil then begin + fscrollbox.setwidgetrect(rect1); + end; + end; +end; + +procedure tcustommseform.internalsetwidgetrect(Value: rectty; + const windowevent: boolean); +begin + inherited; + if csloading in componentstate then begin + updatescrollboxrect; //no clientrectchanged + end; +end; + +procedure tcustommseform.clientrectchanged; +begin + inherited; + updatescrollboxrect; +end; + +procedure tcustommseform.updatewindowinfo(var info: windowinfoty); +begin + inherited; + info.options:= foptionswindow; + if csdesigning in componentstate then begin + exclude(info.options,wo_groupleader); + end; + if fo_maximized in foptions then begin + info.initialwindowpos:= wp_maximized; + end + else begin + if fo_minimized in foptions then begin + info.initialwindowpos:= wp_minimized; + end + else begin + if fo_defaultpos in foptions then begin + info.initialwindowpos:= wp_default; + end; + end; + end; + getwindowicon(ficon,info.icon,info.iconmask); +end; + +procedure tcustommseform.rootchanged(const aflags: rootchangeflagsty); +begin + inherited; + if (rcf_windowset in aflags) and + (foptions * [fo_main,fo_globalshortcuts] = + [fo_main,fo_globalshortcuts]) then begin + window.globalshortcuts:= true; + end; +end; + +procedure tcustommseform.setparentwidget(const Value: twidget); +begin + if (value = nil) and (fparentwidget <> nil) and (fwindow <> nil) and + (foptions * [fo_main,fo_globalshortcuts] = + [fo_main,fo_globalshortcuts]) then begin + fwindow.globalshortcuts:= false; //restore + end; + if fframe <> nil then begin + exclude(tcustomframe1(fframe).fstate,fs_rectsvalid); + end; + inherited; +end; + +function tcustommseform.isgroupleader: boolean; +begin + result:= (wo_groupleader in foptionswindow) or (fo_main in foptions); +end; + +procedure tcustommseform.insertwidget(const widget: twidget; const apos: pointty); +begin +// if not (csloading in widget.componentstate) then begin + if not (csloading in componentstate) then begin + fscrollbox.insertwidget(widget,subpoint(apos,fscrollbox.fwidgetrect.pos)); + end + else begin + fscrollbox.insertwidget(widget,apos); + end; +end; + +function tcustommseform.getcontainer: twidget; +begin + result:= fscrollbox; +end; + +function tcustommseform.getchildwidgets(const index: integer): twidget; +begin + result:= fscrollbox.getchildwidgets(index); +end; + +function tcustommseform.childrencount: integer; +begin + result:= fscrollbox.childrencount; +end; + +procedure tcustommseform.dolayout(const sender: twidget); +begin + inherited; + if (fmainmenuwidget <> nil) and (fmainmenuwidget = sender) then begin + updatescrollboxrect; + end; +end; + +function tcustommseform.checkdock(var info: draginfoty): boolean; +begin + result:= true; +end; + +function tcustommseform.getbuttonrects(const index: dockbuttonrectty): rectty; +begin + if fframe = nil then begin + if index = dbr_handle then begin + result:= clientrect; + end + else begin + result:= nullrect; + end; + end + else begin + result:= tgripframe(fframe).buttonrects[index]; + end; +end; + +function tcustommseform.getplacementrect: rectty; +begin + with fscrollbox do begin + result:= paintrect; + deflaterect1(result,tcustomframe1(fframe).fi.innerframe); + addpoint1(result.pos,clientpos); //??? + end; +end; + +function tcustommseform.getminimizedsize(out apos: captionposty): sizety; +begin + if fframe = nil then begin + result:= nullsize; + end + else begin + result:= tgripframe(fframe).getminimizedsize(apos); + end; +end; + +function tcustommseform.getcaption: msestring; +begin + result:= fcaption; +end; + +procedure tcustommseform.setcaption(const Value: msestring); +begin + fcaption := Value; + if ownswindow then begin + window.caption:= fcaption; + end; +end; + +function tcustommseform.getwindowcaption: msestring; +begin + result:= fcaption; +end; + +function tcustommseform.getchildicon: tmaskedbitmap; +begin + result:= nil; + if not (csdestroying in componentstate) then begin + if ficon.hasimage then begin + result:= ficon; + end; + end; +end; + +procedure tcustommseform.windowcreated; +var + mstr1: msestring; +begin + inherited; + mstr1:= getwindowcaption; + if mstr1 <> '' then begin + window.caption:= mstr1; + end; + if fwindowopacity <> emptyreal then begin + window.opacity:= fwindowopacity; + end; +// if fcaption <> '' then begin +// caption:= fcaption; //set windowcaption +// end; +end; + +procedure tcustommseform.dofontheightdelta(var delta: integer); +begin + if canevent(tmethod(fonfontheightdelta)) then begin + fonfontheightdelta(self,delta); + end; +end; + +procedure tcustommseform.dokeydown(var info: keyeventinfoty); +var + modres1: modalresultty; +begin + inherited; + with info do begin + if not (es_processed in eventstate) and + (shiftstate * shiftstatesrepeatmask = []) and + (not (fo_keycloseifwinonly in foptions) or (fparentwidget = nil)) and + (((fo_closeonesc in foptions) or (fo_cancelonesc in foptions)) and + (key = key_escape) or + (fo_closeonf10 in foptions) and (key = key_f10) or + (fo_closeonenter in foptions) and isenterkey(self,key)) then begin + include(eventstate,es_processed); + if key = key_f10 then begin + modres1:= mr_f10; + end + else begin + if key = key_escape then begin + if fo_cancelonesc in foptions then begin + modres1:= mr_cancel; + end + else begin + modres1:= mr_escape; + end; + end + else begin + modres1:= mr_ok; + end; + end; + close(modres1); + end; + end; +end; + +procedure tcustommseform.doshortcut(var info: keyeventinfoty; const sender: twidget); +begin + if not (es_processed in info.eventstate) then begin + if (fmainmenu <> nil) and not ((csdesigning) in componentstate) then begin + fmainmenu.doshortcut(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; +// if not info.processed and (fmainmenuwidget <> nil) and (info.shiftstate = [ss_alt]) then begin +// fmainmenuwidget.keydown +// end; + end; + end; +end; +{ +function tcustommseform.getframe: tgripframe; +begin + result:= tgripframe(inherited getframe); +end; + +procedure tcustommseform.setframe(const Value: tgripframe); +begin + inherited setframe(value); +end; +} +{ +function tcustommseform.getframescrollbox: tscrollboxframe; +begin + result:= fscrollbox.frame; +end; + +procedure tcustommseform.setframescrollbox(const Value: tscrollboxframe); +begin + fscrollbox.frame:= value; +end; +} +procedure tcustommseform.setscrollbox(const avalue: tformscrollbox); +begin + fscrollbox.Assign(avalue); +end; + +function tcustommseform.getonbeforepaint: painteventty; +begin + result:= fscrollbox.onbeforepaint; +end; + +procedure tcustommseform.setonbeforepaint(const Value: painteventty); +begin + fscrollbox.onbeforepaint:= value; +end; + +function tcustommseform.getonpaint: painteventty; +begin + result:= fscrollbox.onpaint; +end; + +procedure tcustommseform.setonpaint(const Value: painteventty); +begin + fscrollbox.onpaint:= value; +end; + +function tcustommseform.getonafterpaint: painteventty; +begin + result:= fscrollbox.onafterpaint; +end; + +procedure tcustommseform.setonafterpaint(const Value: painteventty); +begin + fscrollbox.onafterpaint:= value; +end; + +procedure tcustommseform.seticon(const avalue: tmaskedbitmap); +begin + ficon.assign(avalue); +end; + +procedure tcustommseform.setwindowopacity(const avalue: realty); +begin + fwindowopacity:= avalue; + if ownswindow then begin + window.opacity:= avalue; + end; +end; + +procedure tcustommseform.iconchanged(const sender: tobject); +var + icon1,mask1: pixmapty; +begin + if ficonchanging = 0 then begin + inc(ficonchanging); + if ownswindow then begin + getwindowicon(internalgeticon(),icon1,mask1); + gui_setwindowicon(window.winid,icon1,mask1); + if (fo_main in foptions) and not (csdesigning in componentstate) then begin + gui_setapplicationicon(icon1,mask1); + end; + end; + dec(ficonchanging); + end; +end; + +procedure tcustommseform.widgetregionchanged(const sender: twidget); +begin + inherited; + if (fmainmenuwidget <> nil) and (sender = fmainmenuwidget) then begin + updatescrollboxrect; + end; +end; + +procedure tcustommseform.setonsysevent(const avalue: syseventeventty); +begin + if not (csdesigning in componentstate) then begin + if assigned(avalue) then begin + if not assigned(fonsysevent) and not assigned(fonsyswindowevent) then begin + application.registersyseventhandler({$ifdef FPC}@{$endif}dosysevent); + end; + end + else begin + if assigned(fonsysevent) and not assigned(fonsyswindowevent) then begin + application.unregistersyseventhandler({$ifdef FPC}@{$endif}dosysevent); + end; + end; + end; + fonsysevent:= avalue; +end; + +procedure tcustommseform.setonsyswindowevent(const avalue: syseventeventty); +begin + if not (csdesigning in componentstate) then begin + if assigned(avalue) then begin + if not assigned(fonsysevent) and not assigned(fonsyswindowevent) then begin + application.registersyseventhandler({$ifdef FPC}@{$endif}dosysevent); + end; + end + else begin + if assigned(fonsyswindowevent) and not assigned(fonsysevent) then begin + application.unregistersyseventhandler({$ifdef FPC}@{$endif}dosysevent); + end; + end; + end; + fonsyswindowevent:= avalue; +end; + +procedure tcustommseform.setonapplicationevent( + const avalue: applicationeventeventty); +begin + if not (csdesigning in componentstate) then begin + if assigned(avalue) then begin + if not assigned(fonapplicationevent) then begin + application.registerapplicationeventhandler(@doapplicationevent); + end; + end + else begin + if assigned(fonapplicationevent) then begin + application.unregisterapplicationeventhandler(@doapplicationevent); + end; + end; + end; + fonapplicationevent:= avalue; +end; + +procedure tcustommseform.dosysevent(const awindow: winidty; + var aevent: syseventty; var handled: boolean); +begin + if assigned(fonsysevent) then begin + fonsysevent(self,aevent,handled); + end; + if assigned(fonsyswindowevent) and not handled and + (awindow <> 0) and (twindow1(window).fwindow.id = awindow) then begin + fonsyswindowevent(self,aevent,handled); + end; +end; + +procedure tcustommseform.doapplicationevent(var aevent: tmseevent; + var handled: boolean); +begin + if assigned(fonapplicationevent) then begin + fonapplicationevent(self,aevent,handled); + end; +end; + +procedure tcustommseform.updatelayout(const sender: twidget); +begin + //dummy +end; + +function tcustommseform.getassistivecaption(): msestring; +begin +{ + result:= ''; + if caption <> '' then begin + if ownswindow then begin + result:= sc(sc_window)+' '+caption; + end + else begin + result:= caption; + end; + end; +} + result:= caption; + if result = '' then begin + result:= inherited getassistivecaption(); + end; +end; + +procedure tcustommseform.readonchildscaled(reader: treader); +begin + onlayout:= notifyeventty(readmethod(reader)); +end; + +procedure tcustommseform.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('onchildscaled', + {$ifdef FPC}@{$endif}readonchildscaled,nil,false); +end; + +procedure tcustommseform.dolayoutchanged(const sender: tdockcontroller); +begin + //dummy +end; + +procedure tcustommseform.dodockcaptionchanged(const sender: tdockcontroller); +begin + //dummy +end; + +procedure tcustommseform.autoreadstat; +begin + if (fstatfile <> nil) and not (csdesigning in componentstate) and + (foptions*[fo_autoreadstat,fo_delayedreadstat] = + [fo_autoreadstat]) then begin + fstatfile.readstat; + end; +end; + +procedure tcustommseform.getautopaintsize(var asize: sizety); +var + size1: sizety; +begin + with fscrollbox do begin + asize:= calcminscrollsize; + size1:= frame.paintframedim; + subpoint1(pointty(size1),self.paintpos); + asize.cx:= asize.cx + fscrollbox.bounds_x + size1.cx; + asize.cy:= asize.cy + fscrollbox.bounds_y + size1.cy; + end; +end; + +procedure tcustommseform.setactivatortarget(const avalue: tactivator); +begin + setlinkedvar(avalue,tmsecomponent(factivatortarget)); +end; + +procedure tcustommseform.settaborderoverride(const avalue: ttaborderoverride); +begin + ftaborderoverride.assign(avalue); +end; + +function tcustommseform.internalgeticon(): tmaskedbitmap; +begin + result:= ficon; +end; + +function tcustommseform.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tmseform } + +constructor tmseform.create(aowner: tcomponent; load: boolean); +begin + include(fmsecomponentstate,cs_ismodule); + inherited; +end; + +class function tmseform.getmoduleclassname: string; +begin +// result:= tmseform.ClassName; + //bug in dcc32: tmseform is replaced by self + result:= 'tmseform'; +end; + +class function tmseform.hasresource: boolean; +begin + result:= self <> tmseform; +end; + +{ tmainform } + +class function tmainform.getmoduleclassname: string; +begin +// result:= tmseform.ClassName; + //bug in dcc32: tmseform is replaced by self + result:= 'tmainform'; +end; + +class function tmainform.hasresource: boolean; +begin + result:= self <> tmainform; +end; + +procedure tmainform.aftercreate; +begin + inherited; + foptions:= defaultmainformoptions; + foptionswindow:= defaultmainformoptionswindow; +end; + +{ tformdockcontroller } + + +constructor tformdockcontroller.create(const aowner: tcustomdockform); +begin + fowner:= aowner; + foptionsdockform:= defaultoptionsdockform; + inherited create(idockcontroller(aowner)); +end; + +procedure tformdockcontroller.setoptionsdock(const avalue: optionsdockty); +begin + inherited; + updatebit(longword(tdockform(fintf.getwidget).foptions), + ord(fo_savepos),od_savepos in foptionsdock); + updatebit(longword(tdockform(fintf.getwidget).foptions), + ord(fo_savezorder),od_savezorder in foptionsdock); +end; + +procedure tformdockcontroller.setoptionsdockform( + const avalue: optionsdockformty); +begin + if foptionsdockform <> avalue then begin + foptionsdockform:= avalue; + if fowner.componentstate * [csloading,csdestroying] = [] then begin + layoutchanged(); + end; + end; +end; + +function tformdockcontroller.hasmain(): boolean; +var + ar1: widgetarty; + w1: twidget; + i1: int32; +begin + result:= false; + if not (csdestroying in fowner.componentstate) then begin + result:= odf_main in foptionsdockform; + if not result then begin + ar1:= getitems(); + for i1:= 0 to high(ar1) do begin + w1:= ar1[i1]; + if not (csdestroying in w1.componentstate) and + (w1 is tcustomdockform) then begin + result:= tcustomdockform(w1).fdragdock.hasmain(); + if result then begin + break; + end; + end; + end; + end; + end; +end; + +function tformdockcontroller.childicon(): tmaskedbitmap; + + function check(const avalue: tformdockcontroller): tmaskedbitmap; + var + ar1: widgetarty; + w1: twidget; + i1: int32; + begin + result:= nil; + with avalue do begin + if not (csdestroying in fowner.componentstate) then begin + if odf_main in foptionsdockform then begin + result:= fowner.ficon; + end + else begin + ar1:= getitems(); + for i1:= 0 to high(ar1) do begin + w1:= ar1[i1]; + if w1 is tcustomdockform then begin + result:= check(tcustomdockform(w1).fdragdock); + if result <> nil then begin + break; + end; + end; + end; + end; + end; + end; + end; //check + +begin + if (odf_mainchildicon in foptionsdockform) then begin + result:= check(self); + if result = nil then begin + result:= inherited childicon(); + end + else begin + if not result.hasimage then begin + result:= nil; + end; + end; + end + else begin + result:= inherited childicon; + end; +end; + +procedure tformdockcontroller.dolayoutchanged(); +begin + inherited; + if odf_childicons in foptionsdockform then begin + fowner.iconchanged(nil); + end; +end; + +procedure tformdockcontroller.childstatechanged(const sender: twidget; + const newstate: widgetstatesty; const oldstate: widgetstatesty); +begin + inherited; + if (odf_childicons in foptionsdockform) and (ws_entered in newstate) and + not (ws_entered in oldstate) then begin + fowner.iconchanged(nil); + end; +end; + +{ tcustomdockform } + +constructor tcustomdockform.create(aowner: tcomponent; load: boolean); +begin + if fdragdock = nil then begin + fdragdock:= tformdockcontroller.create(self); + end; + if fscrollbox = nil then begin + fscrollbox:= tdockformscrollbox.create(self); + end; + inherited; +end; + +destructor tcustomdockform.destroy(); +begin + inherited; + fdragdock.Free; +end; + +function tcustomdockform.getdockcontroller: tdockcontroller; +begin + result:= fdragdock; +end; + +procedure tcustomdockform.setdragdock(const value: tformdockcontroller); +begin + fdragdock.assign(value); +end; + +function tcustomdockform.getframe: tgripframe; +begin + result:= tgripframe(inherited getframe); +end; + +procedure tcustomdockform.setframe(const avalue: tgripframe); +begin + inherited setframe(avalue); +end; + +procedure tcustomdockform.internalcreateframe; +begin + tgripframe.create(iscrollframe(self),fdragdock); +end; + +function tcustomdockform.internalgeticon(): tmaskedbitmap; +begin + result:= inherited internalgeticon(); + if (result = nil) or not result.hasimage() and + (odf_childicons in fdragdock.optionsdockform) then begin + result:= fdragdock.childicon(); + end; +end; + +procedure tcustomdockform.dragevent(var info: draginfoty); +begin + if not fdragdock.beforedragevent(info) then begin + inherited; + end; + fdragdock.afterdragevent(info); +end; + +procedure tcustomdockform.updateoptions; +begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fdragdock.foptionsdock), + ord(od_savepos),fo_savepos in foptions); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fdragdock.foptionsdock), + ord(od_savezorder),fo_savezorder in foptions); + inherited; +end; + +function tcustomdockform.getoptions: formoptionsty; +begin + if od_savepos in fdragdock.optionsdock then begin + include(foptions,fo_savepos); + end + else begin + exclude(foptions,fo_savepos); + end; + if od_savezorder in fdragdock.optionsdock then begin + include(foptions,fo_savezorder); + end + else begin + exclude(foptions,fo_savezorder); + end; + result:= inherited getoptions; +end; + +procedure tcustomdockform.dostatread1(const reader: tstatreader); +begin + tdockcontroller(fdragdock).dostatread(reader); +end; + +procedure tcustomdockform.dostatwrite1(const writer: tstatwriter); +var + rect1: rectty; +begin + if fparentwidget = nil then begin + rect1:= window.normalwindowrect; + fdragdock.dostatwrite(writer,@rect1); + end + else begin + fdragdock.dostatwrite(writer,nil); + end; +end; +{ +procedure tcustomdockform.dokeydown(var info: keyeventinfoty); +begin + fdragdock.keydown(info); + if not es_processed in info.eventstate then begin + inherited; + end; +end; +} +procedure tcustomdockform.statreading; +begin + tdockcontroller(fdragdock).statreading; + inherited; +end; + +procedure tcustomdockform.statread; +begin + tdockcontroller(fdragdock).statread; + inherited; +end; +(* +procedure tcustomdockform.mouseevent(var info: mouseeventinfoty); +var + bo1: boolean; +begin + inherited; + { + bo1:= info.eventkind = ek_buttonrelease; + if not (es_processed in info.eventstate) and bo1 then begin + fdragdock.mouseevent(info); + end; + inherited; + if not (es_processed in info.eventstate) and not bo1 then begin + fdragdock.mouseevent(info); + end; + } +end; +*) +procedure tcustomdockform.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + fdragdock.childormouseevent(sender,info); + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +procedure tcustomdockform.doactivate; +begin + fdragdock.doactivate; + inherited; +end; + +procedure tcustomdockform.parentchanged; +begin + inherited; + fdragdock.parentchanged(self); +end; + +function tcustomdockform.canfocus: boolean; +begin + result:= inherited canfocus and (fdragdock.mdistate <> mds_minimized); +end; + +procedure tcustomdockform.activate(const abringtofront: boolean = true; + const aforce: boolean = false); +begin + if fdragdock.mdistate = mds_minimized then begin + fdragdock.mdistate:= mds_normal; + end; + if fdragdock.ismdi then begin + bringtofront; + end; + inherited; +end; + +procedure tcustomdockform.activechanged; +begin + if fframe <> nil then begin + invalidaterect(tgripframe(fframe).griprect,org_widget); + end; + inherited; +end; + +procedure tcustomdockform.statechanged; +begin + fdragdock.statechanged(fwidgetstate); + inherited; +end; + +procedure tcustomdockform.poschanged; +begin + fdragdock.poschanged; + inherited; +end; + +function tcustomdockform.getwindowcaption: msestring; +begin + result:= fdragdock.getfloatcaption; +end; + +function tcustomdockform.ismainwindow(): boolean; +begin + result:= inherited ismainwindow() or not(csdesigning in componentstate) and + (odf_mainmainwindow in fdragdock.foptionsdockform) and + fdragdock.hasmain(); +end; + +procedure tcustomdockform.dolayoutchanged(const sender: tdockcontroller); +begin + inherited; + if not (csdestroying in componentstate) then begin + checkdockicon(); + if (window.owner = self) then begin + if ismainwindow() then begin + application.mainwindow:= fwindow; + end + else begin + if application.mainwindow = fwindow then begin + application.mainwindow:= nil; + end; + end; + end; + end; +end; + +procedure tcustomdockform.checkdockicon(); +begin + if odf_childicons in fdragdock.optionsdockform then begin + iconchanged(nil); + end; + if fhasdocktaskbaricon <> needsdocktaskbaricon() then begin + window.recreatewindow(); + end; +end; + +function tcustomdockform.getchildicon(): tmaskedbitmap; +begin + result:= inherited getchildicon(); + if (result = nil) and not (csdestroying in componentstate) then begin + result:= fdragdock.childicon(); + end; +end; + +procedure tcustomdockform.loaded(); +begin + inherited; + checkdockicon(); +end; + +procedure tcustomdockform.doenter(); +begin + inherited; + fdragdock.statechanged(fwidgetstate); +end; + +procedure tcustomdockform.doexit(); +begin + inherited; + fdragdock.statechanged(fwidgetstate); +end; + +procedure tcustomdockform.setdockingareacaption(const avalue: msestring); +begin + fdockingareacaption:= avalue; + invalidate; +end; + +function tcustomdockform.needsdocktaskbaricon(): boolean; +begin + result:= (odf_maintaskbar in fdragdock.foptionsdockform) and + fdragdock.hasmain(); +end; + +procedure tcustomdockform.updatewindowinfo(var info: windowinfoty); +begin + inherited; + fhasdocktaskbaricon:= needsdocktaskbaricon(); + if fhasdocktaskbaricon then begin + include(info.options,wo_taskbar); + end; +end; + +{ tdockform} + +constructor tdockform.create(aowner: tcomponent; load: boolean); +begin + include(fmsecomponentstate,cs_ismodule); + inherited; +end; + +class function tdockform.getmoduleclassname: string; +begin + result:= 'tdockform'; +end; + +class function tdockform.hasresource: boolean; +begin + result:= self <> tdockform; +end; + +{ tsubform } + +constructor tsubform.create(aowner: tcomponent); +begin + create(aowner,not (cs_noload in fmsecomponentstate)); +end; + +constructor tsubform.create(aowner: tcomponent; load: boolean); +begin + include(fmsecomponentstate,cs_ismodule); + fwidgetrect.x:= 100; + fwidgetrect.y:= 100; + inherited create(aowner); + fwidgetrect.cx:= 100; + fwidgetrect.cy:= 100; + if load and not (csdesigning in componentstate) and + (cs_ismodule in fmsecomponentstate) then begin + loadmsemodule(self,tsubform); + end; +end; + +class function tsubform.getmoduleclassname: string; +begin + result:= 'tsubform'; +end; + +class function tsubform.hasresource: boolean; +begin + result:= self <> tsubform; +end; + +procedure tsubform.getchildren(proc: tgetchildproc; root: tcomponent); +begin + inherited; + getcompchildren(proc,root); +end; + +{ tscrollboxform } + +constructor tscrollboxform.create(aowner: tcomponent); +begin + create(aowner,not (cs_noload in fmsecomponentstate)); +end; + +constructor tscrollboxform.create(aowner: tcomponent; load: boolean); +begin + include(fmsecomponentstate,cs_ismodule); + fwidgetrect.x:= 100; + fwidgetrect.y:= 100; + inherited create(aowner); + fwidgetrect.cx:= 100; + fwidgetrect.cy:= 100; + if load and not (csdesigning in componentstate) and + (cs_ismodule in fmsecomponentstate) then begin + loadmsemodule(self,tscrollboxform); + end; +end; + +class function tscrollboxform.getmoduleclassname: string; +begin + result:= 'tscrollboxform'; +end; + +class function tscrollboxform.hasresource: boolean; +begin + result:= self <> tscrollboxform; +end; + +procedure tscrollboxform.getchildren(proc: tgetchildproc; root: tcomponent); +begin + inherited; + getcompchildren(proc,root); +end; + +{ ttabformfonttab } + +class function ttabformfonttab.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabform(owner).ffonttab; +end; + +{ ttabpagefontactivetab } + +class function ttabformfontactivetab.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabform(owner).ffontactivetab; +end; + +{ ttabform } + +//constructor ttabform.docreate(aowner: tcomponent); +procedure ttabform.docreate(aowner: tcomponent); +begin + fcolortab:= cl_default; + fcoloractivetab:= cl_default; + fimagenr:= -1; + fimagenrdisabled:= -2; + inherited; +// inherited create(aowner); + fcolor:= cl_default; + exclude(fwidgetstate,ws_visible); +end; + +destructor ttabform.destroy; +begin + inherited; + freeandnil(ffonttab); + freeandnil(ffontactivetab); +end; + +class function ttabform.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_tabpage; +end; + +procedure ttabform.createfonttab; +begin + if ffonttab = nil then begin + ffonttab:= ttabformfonttab.create; + ffonttab.onchange:= {$ifdef FPC}@{$endif}fontchanged1; + end; +end; + +procedure ttabform.createfontactivetab; +begin + if ffontactivetab = nil then begin + ffontactivetab:= ttabformfontactivetab.create; + ffontactivetab.onchange:= {$ifdef FPC}@{$endif}fontchanged1; + end; +end; + +procedure ttabform.loaded; +begin + if fparentwidget is tcustomtabwidget then begin + include(fwidgetstate1,ws1_nodesignvisible); + end; + inherited; +end; + +class function ttabform.getmoduleclassname: string; +begin + result:= 'ttabform'; +end; + +procedure ttabform.changed; +begin + if ftabwidget <> nil then begin + tcustomtabwidget1(ftabwidget).pagechanged(itabpage(self)); + end; +end; + +procedure ttabform.fontchanged1(const sender: tobject); +begin + changed; +end; + +function ttabform.getcolortab: colorty; +begin + result:= fcolortab; +end; + +procedure ttabform.setcolortab(const avalue: colorty); +begin + if fcolortab <> avalue then begin + fcolortab:= avalue; + changed; + end; +end; + +function ttabform.getcoloractivetab: colorty; +begin + result:= fcoloractivetab; +end; + +procedure ttabform.setcoloractivetab(const avalue: colorty); +begin + if fcoloractivetab <> fcoloractivetab then begin + fcoloractivetab:= avalue; + changed; + end; +end; + +function ttabform.gettabwidget: tcustomtabwidget; +begin + result:= ftabwidget; +end; + +function ttabform.isactivepage: boolean; +begin + result:= (ftabwidget <> nil) and (ftabwidget.activepage = self); +end; + +procedure ttabform.setcaption(const value: msestring); +begin + inherited; + changed; +end; + +function ttabform.gettabhint: msestring; +begin + result:= ftabhint; +end; + +procedure ttabform.settabhint(const avalue: msestring); +begin + ftabhint:= avalue; + changed; +end; + +function ttabform.gettabnoface: boolean; +begin + result:= ftabnoface; +end; + +procedure ttabform.settabnoface(const avalue: boolean); +begin + if ftabnoface <> avalue then begin + ftabnoface:= avalue; + changed; + end; +end; + +procedure ttabform.settabwidget(const value: tcustomtabwidget); +begin + ftabwidget:= value; +end; + +procedure ttabform.visiblechanged; +begin + inherited; + changed; +end; + +function ttabform.gettabindex: integer; +begin + if tabwidget = nil then begin + result:= -1; + end + else begin + result:= tabwidget.indexof(self); + end; +end; + +procedure ttabform.settabindex(const avalue: integer); +begin + if tabwidget <> nil then begin + tabwidget.movepage(tabindex,avalue); + end; +end; + +procedure ttabform.doselect; +begin + if canevent(tmethod(fonselect)) then begin + fonselect(self); + end; +end; + +procedure ttabform.dodeselect; +begin + if canevent(tmethod(fondeselect)) then begin + fondeselect(self); + end; +end; + +function ttabform.getimagelist: timagelist; +begin + result:= fimagelist +end; + +procedure ttabform.setimagelist(const avalue: timagelist); +begin + if fimagelist <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + changed; + end; +end; + +function ttabform.getimagenr: imagenrty; +begin + result:= fimagenr; +end; + +procedure ttabform.setimagenr(const avalue: imagenrty); +begin + if fimagenr <> avalue then begin + fimagenr:= avalue; + changed; + end; +end; +{ +function ttabform.getimagenractive: integer; +begin + result:= fimagenractive; +end; + +procedure ttabform.setimagenractive(const avalue: integer); +begin + if fimagenractive <> avalue then begin + fimagenractive:= avalue; + changed; + end; +end; +} +function ttabform.getimagenrdisabled: imagenrty; +begin + result:= fimagenrdisabled; +end; + +procedure ttabform.setimagenrdisabled(const avalue: imagenrty); +begin + if fimagenrdisabled <> avalue then begin + fimagenrdisabled:= avalue; + changed; + end; +end; + +procedure ttabform.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if event = oe_destroyed then begin + if sender = fimagelist then begin + fimagelist:= nil; + changed; + end; + if sender = ffacetab then begin + ffacetab:= nil; + changed; + end; + if sender = ffaceactivetab then begin + ffaceactivetab:= nil; + changed; + end; + end + else begin + if event = oe_changed then begin + changed; + end; + end; +end; + +function ttabform.getinvisible: boolean; +begin + result:= finvisible; +end; + +procedure ttabform.setinvisible(const avalue: boolean); +begin + if finvisible <> avalue then begin + finvisible:= avalue; + changed; + end; +end; + +class function ttabform.hasresource: boolean; +begin + result:= self <> ttabform; +end; + +function ttabform.getfonttab: tfont; +begin + result:= ffonttab; +end; + +function ttabform.getfontactivetab: tfont; +begin + result:= ffontactivetab; +end; + +function ttabform.getfonttab1: ttabformfonttab; +begin + getoptionalobject(ffonttab, + {$ifdef FPC}@{$endif}createfonttab); + result:= ffonttab; +end; + +procedure ttabform.setfonttab1(const avalue: ttabformfonttab); +begin + if avalue <> ffonttab then begin + setoptionalobject(avalue,ffonttab, + {$ifdef FPC}@{$endif}createfonttab); + changed; + end; +end; + +procedure ttabform.setfonttab(const avalue: tfont); +begin + setfonttab1(ttabformfonttab(avalue)); +end; + +function ttabform.isfonttabstored: boolean; +begin + result:= ffonttab <> nil; +end; + +function ttabform.getfontactivetab1: ttabformfontactivetab; +begin + getoptionalobject(ffontactivetab, + {$ifdef FPC}@{$endif}createfontactivetab); + result:= ffontactivetab; +end; + +procedure ttabform.setfontactivetab1(const avalue: ttabformfontactivetab); +begin + if avalue <> ffontactivetab then begin + setoptionalobject(avalue,ffontactivetab, + {$ifdef FPC}@{$endif}createfontactivetab); + changed; + end; +end; + +procedure ttabform.setfontactivetab(const avalue: tfont); +begin + setfontactivetab1(ttabformfontactivetab(avalue)); +end; + +function ttabform.isfontactivetabstored: boolean; +begin + result:= ffontactivetab <> nil; +end; + +function ttabform.getfacetab: tfacecomp; +begin + result:= ffacetab; +end; + +procedure ttabform.setfacetab(const avalue: tfacecomp); +begin + if ffacetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffacetab)); + changed(); + end; +end; + +function ttabform.getfaceactivetab: tfacecomp; +begin + result:= ffaceactivetab; +end; + +procedure ttabform.setfaceactivetab(const avalue: tfacecomp); +begin + if ffaceactivetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffaceactivetab)); + changed(); + end; +end; + +{ +function ttabform.gettabwidth: integer; +begin + result:= ftabwidth; +end; + +procedure ttabform.settabwidth(const avalue: integer); +begin + ftabwidth:= avalue; + changed; +end; + +function ttabform.gettabwidthmin: integer; +begin + result:= ftabwidthmin; +end; + +procedure ttabform.settabwidthmin(const avalue: integer); +begin + ftabwidthmin:= avalue; + changed; +end; + +function ttabform.gettabwidthmax: integer; +begin + result:= ftabwidthmax; +end; + +procedure ttabform.settabwidthmax(const avalue: integer); +begin + ftabwidthmax:= avalue; + changed; +end; +} +end. + diff --git a/mseide-msegui/lib/common/widgets/msegrids.pas b/mseide-msegui/lib/common/widgets/msegrids.pas new file mode 100644 index 0000000..415f980 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msegrids.pas @@ -0,0 +1,19460 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegrids; + +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba}{$goto on} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,sysutils,mseclasses,msegui,msedragglob, + msegraphics,msetypes,msestrings,msegraphutils,msebitmap,mseassistiveclient, + msescrollbar,msearrayprops,mseglob,mseguiglob,typinfo,msearrayutils, + msedatalist,msedrawtext,msewidgets,mseevent,mseinplaceedit,mseeditglob, + mseobjectpicker,msepointer,msetimer,msebits,msestat,msestatfile,msekeyboard, + msestream,msedrag,msemenus,msepipestream,mseshapes,msegridsglob,mselist + {$ifdef mse_with_ifi},mseificomp,mseifiglob,mseificompglob{$endif}; + +type + // listvievoptionty from mselistbrowser + // lvo_readonly,lvo_mousemoving,lvo_keymoving,lvo_horz, + coloptionty = (co_readonly, co_nofocus, co_invisible, co_disabled, + // lvo_drawfocus,lvo_mousemovefocus,lvo_leftbuttonfocusonly, + co_drawfocus,co_mousemovefocus,co_leftbuttonfocusonly, + // lvo_middlebuttonfocus, + co_middlebuttonfocus, + // lvo_noctrlmousefocus, + co_noctrlmousefocus, + // lvo_focusselect,lvo_mouseselect,lvo_keyselect, + co_focusselect, co_mouseselect, co_keyselect, + // lvo_multiselect,lvo_resetselectonexit{,lvo_noresetselect} + co_multiselect, co_resetselectonexit,{co_noresetselect,} + co_rowselect, + + co_fixwidth,co_fixpos,co_fill,co_proportional,co_nohscroll, +// co_autorowheight, + co_savevalue,co_savestate, +// co_rowfont,co_rowcolor,co_zebracolor, //deprecated -> co1_ +// co_rowcoloractive, //deprecated -> co1_ + + co_nosort,co_sortdescend,co_sortcaseinsensitive,co_norearange, + co_cancopy,co_canpaste,co_mousescrollrow,co_rowdatachange + ); + coloptionsty = set of coloptionty; +// celloptionty = (ceo_autorowheight); +// celloptionsty = set of celloptionty; + + coloption1ty = (co1_rowfont,co1_rowcolor,co1_zebracolor, + co1_rowcoloractive,co1_rowcolorfocused,co1_rowreadonly, +// co1_active, //not used + co1_autorowheight,co1_autocolwidth,co1_noautocolwidth, + co1_autoheaderwidth + ); + coloptions1ty = set of coloption1ty; + +const + deprecatedcoloptions = [{co_rowfont,co_rowcolor,co_zebracolor, + co_rowcoloractive}]; + invisiblecoloptions = [{ord(co_rowfont),ord(co_rowcolor),ord(co_zebracolor), + ord(co_rowcoloractive)}]; +// deprecatedcoloptions1 = [co1_active]; + +type + fixcoloptionty = (fco_invisible,fco_mousefocus,fco_mouseselect, + fco_rowfont,fco_rowcolor,fco_zebracolor{, + fco_rowcoloractive,fco_rowcolorfocus}{fco_active}); + fixcoloptionsty = set of fixcoloptionty; + fixrowoptionty = (fro_invisible,fro_mousefocus,fro_mouseselect); + fixrowoptionsty = set of fixrowoptionty; + +const + fixcoloptionsshift1 = ord(fco_rowfont)-ord(co1_rowfont); + fixcoloptionsmask: coloptions1ty = + [co1_rowfont,co1_rowcolor,co1_zebracolor{, + co1_rowcoloractive,co1_rowcolorfocus}]; + + defaultfixcoloptions = []; + defaultgridskinoptions = [osk_framebuttononly]; + sortglyphwidth = 11; + defaultwheelscrollheight = 0; + + rowstatefoldleveltag = 0; + rowstateissumtag = 1; + rowstatefoldhiddentag = 2; + gridautosizetag = 3; + +type + optiongridty = (og_colsizing,og_colmoving,og_keycolmoving, + og_rowsizing,og_rowmoving,og_keyrowmoving, + og_rowinserting,og_rowdeleting,og_selectedrowsdeleting, + og_focuscellonenter,og_containerfocusbackonesc, + og_autofirstrow,og_autoappend,og_appendempty,og_noinsertempty, + og_savestate,og_nosaveremoveappendedrow, + og_sorted,og_nodefaultsort,og_noreorderrow, + og_customsort, //externally sorted data by onsortchanged + og_folded,og_colmerged,og_rowheight, + og_colchangeontabkey,og_colchangeonreturnkey, + og_wraprow,og_wrapcol, + og_visiblerowpagestep, + og_autopopup, + og_mousescrollcol{, + og_noresetselect //deprecated -> og1_noresetselect} + ); + optionsgridty = set of optiongridty; + optiongrid1ty = (og1_norowdeletequery,og1_swaprowinsertappend,//for Ctrl+Insert + og1_forcerowsmodified, + //onrowsmodified fired by doremoveappinsrow() and + //appinsrow + og1_focusmorerows,og1_scrollmorerows, + og1_noresetselect,og1_pasteinselection); + optionsgrid1ty = set of optiongrid1ty; + +const + rowstateoptions = [og_colmerged,og_rowheight]; //variable rowstate size +// deprecatedoptionsgrid = [og_noresetselect]; + invisibleoptionsgrid = [{ord(og_noresetselect)}]; + newcomponentoptionsgridadd = [og_rowinserting,og_rowdeleting, + og_autofirstrow,og_autoappend]; + +type + pickobjectkindty = (pok_none,pok_fixcolsize,pok_fixcol,pok_datacolsize,pok_datacol, + pok_fixrowsize,pok_fixrow,pok_datarowsize,pok_datarow); + + stringcoleditoptionty = ( + scoe_undoonesc,scoe_forcereturncheckvalue,scoe_eatreturn, +// scoe_autorowheight, + + //same layout as editoptionty + scoe_exitoncursor, + scoe_nofirstarrownavig, + scoe_endonenter, + scoe_homeonenter, + scoe_autoselect, //selectall bei enter + scoe_autoselectonfirstclick, + scoe_caretonreadonly, + scoe_focusrectonreadonly, + scoe_trimright, + scoe_trimleft, + scoe_uppercase, + scoe_lowercase, + scoe_hintclippedtext, + scoe_locate, + scoe_casesensitive, + + scoe_checkbox + ); + + stringcoleditoptionsty = set of stringcoleditoptionty; + +const + stringcoloptionseditmask: optionseditty = [ + oe_exitoncursor, + oe_nofirstarrownavig, + oe_endonenter, + oe_homeonenter, + oe_autoselect, //selectall bei enter + oe_autoselectonfirstclick, + oe_caretonreadonly, + oe_focusrectonreadonly, + oe_trimright, + oe_trimleft, + oe_uppercase, + oe_lowercase, + oe_hintclippedtext, + oe_locate, + oe_casesensitive]; + stringcoloptionseditshift = ord(oe_exitoncursor) - + ord(scoe_exitoncursor); + + gridvaluevarname = 'values'; + pickobjectstep = integer(high(pickobjectkindty)) + 1; + layoutchangedcoloptions: coloptionsty = [co_fill,co_proportional,co_invisible, + co_nohscroll{,co_rowcoloractive}]; + layoutchangedcoloptions1: coloptions1ty = + [co1_rowcoloractive,co1_rowcolorfocused, + co1_autorowheight,co1_autocolwidth,co1_autoheaderwidth]; + notfixcoloptions = [co_fixwidth,co_fixpos,co_fill,co_proportional,co_nohscroll, + co_rowdatachange]; + defaultoptionsgrid = [og_autopopup,og_colchangeontabkey,og_focuscellonenter, + og_mousescrollcol,og_wrapcol]; + + mousescrolldist = 5; + griddefaultcolwidth = 50; + griddefaultrowheight = 20; + defaultcoltextflags = [tf_ycentered,tf_noselect]; + defaultactivecoltextflags = defaultcoltextflags - [tf_noselect]; + defaultgridlinewidth = 1; + defaultdatalinecolor = cl_gridline{cl_dkgray}; + defaultfixlinecolor = cl_gridlinefix{cl_black}; + + defaultselectedcellcolor = cl_gridselect{cl_active}; + defaultdatacoloptions = [{co_selectedcolor,}co_savestate,co_savevalue, + {co_rowfont,co_rowcolor,co_zebracolor,}co_mousescrollrow]; + defaultdatacoloptions1 = [co1_rowfont,co1_rowcolor,co1_zebracolor, + co1_rowcoloractive,co1_rowcolorfocused,co1_rowreadonly]; + defaultfixcoltextflags = [tf_ycentered,tf_xcentered]; + defaultstringcoleditoptions = [scoe_exitoncursor,scoe_undoonesc,scoe_autoselect, + scoe_autoselectonfirstclick,scoe_eatreturn, + scoe_focusrectonreadonly]; +// defaultcolheadertextflags = [tf_ycentered,tf_xcentered]; + + + slowrepeat = 200000; //us + fastrepeat = 100000; //us + + defaultgridwidgetoptions = defaultoptionswidgetmousewheel + + [ow_focusbackonesc{,ow_fontglyphheight}]; + defaultgridwidgetoptions1 = defaultoptionswidget1 + + [ow1_fontglyphheight]; + +type + tgridexception = class(exception); + + gridstatety = ( + gs_layoutvalid,gs_layoutupdating,gs_updatelocked,gs_changelock, +// gs_visiblerowsupdating, + gs_cellentered,gs_cellclicked,gs_emptyrowremoved, + gs_rowcountinvalid,gs_rowreadonly, + gs_scrollup,gs_scrolldown,gs_scrollleft,gs_scrollright, + gs_selectionchanged,gs_rowdatachanged,gs_focusedcellchanged,gs_invalidated, + gs_mouseentered,gs_childmousecaptured,gs_child, + gs_mousecellredirected,gs_restorerow,gs_cellexiting,gs_rowremoving, + gs_appending, + gs_hasactiverowcolor, + gs_needszebraoffset, //has zebrastep or autonumcol + gs_needsrowheight, + gs_islist,//contiguous select blocks + gs_isdb); //do not change rowcount + gridstatesty = set of gridstatety; + gridstate1ty = (gs1_showcellinvalid,gs1_sortvalid,gs1_rowsortinvalid, + gs1_sortmoving,gs1_sortchangelock,gs1_rowinserted, + gs1_gridsorted,gs1_dbsorted,gs1_customsort, + gs1_rowdeleting,gs1_autoappending,gs1_autoremoving, + gs1_autosizepending, + gs1_focuscellonenterlock,gs1_mousecaptureendlock, + gs1_forcenullcheck, + gs1_cellsizesyncing,gs1_userinput,gs1_autoappendlock, + gs1_scrolllimit,gs1_nocellassistive); + gridstates1ty = set of gridstate1ty; + + cellkindty = (ck_invalid,ck_data,ck_fixcol,ck_fixrow,ck_fixcolrow); + griderrorty = (gre_ok,gre_invaliddatacell,gre_differentrowcount, + gre_rowindex,gre_colindex,gre_invalidwidget); + +const + mousecellevents = [cek_mousemove,cek_mousepark,cek_firstmousepark, + cek_buttonpress,cek_buttonrelease]; + repeaterstates = [gs_scrollup,gs_scrolldown,gs_scrollleft,gs_scrollright]; + + +type + tcustomgrid = class; + + celleventinfoty = record //same layout as ificelleventinfoty + cell: gridcoordty; + grid: tcustomgrid; + case eventkind: celleventkindty of + cek_exit,cek_enter,cek_focusedcellchanged: + (cellbefore,newcell: gridcoordty; selectaction: focuscellactionty); + cek_select: + (selected: boolean; accept: boolean); + cek_mousemove,cek_mousepark,cek_firstmousepark, + cek_buttonpress,cek_buttonrelease: + (zone: cellzonety; mouseeventinfopo: pmouseeventinfoty; + gridmousepos: pointty); + cek_keydown,cek_keyup: + (keyeventinfopo: pkeyeventinfoty); + end; + pcelleventinfoty = ^celleventinfoty; + + tgridarrayprop = class; + + tcellframe = class(tframe) + public + constructor create(const aintf: iframe); + published + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + end; + + tfixcellframe = class(tcellframe) + end; + + tcellface = class(tface) + end; + + tfixcellface = class(tcellface) + end; + + rowfoldinfoty = record + foldlevel: byte; + isvisible: boolean; + haschildren: boolean; + isopen: boolean; + nolines: booleanarty; + end; + prowfoldinfoty = ^rowfoldinfoty; + rowfoldinfoarty = array of rowfoldinfoty; + rowfoldinfoaty = array[0..0] of rowfoldinfoty; + prowfoldinfoaty = ^rowfoldinfoaty; + + celldrawstatety = (cds_selected,cds_readonly,cds_focused,cds_active,cds_notext, + cds_usecoloractive,cds_ismousecell); + celldrawstatesty = set of celldrawstatety; + + cellinfoty = record + grid: tcustomgrid; + cell: gridcoordty; + rect: rectty; + innerrect: rectty; //origin rect.pos + frameinnerrect: rectty; //innerrect of cell frame or rect if nil + color: colorty; + colorline: colorty; + font: tfont; + drawstate: celldrawstatesty; +// selected: boolean; +// readonly: boolean; +// focused: boolean; +// active: boolean; +// notext: boolean; +// useactivecolor: boolean; +// ismousecell: boolean; + datapo: pointer; + rowstate: prowstatety; + foldinfo: prowfoldinfoty; +// needslayout: boolean; + calcautocellsize: boolean; // don't paint + autocellsize: sizety; + end; + pcellinfoty = ^cellinfoty; + + tgridpropfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + gridpropstatety = (gps_fix,gps_selected,gps_noinvalidate,gps_edited, + gps_readonlyupdating,gps_selectionchanged,gps_changelock, + gps_datalistvalid,gps_needsrowheight, + gps_maxsizevalid,gps_autosizevalid); + gridpropstatesty = set of gridpropstatety; + + tgridprop = class(tindexpersistent,iframe,iface) + private + fcellrect: rectty; + ftag: integer; + function getframe: tcellframe; + procedure setframe(const Value: tcellframe); + function getface: tcellface; + procedure setface(const Value: tcellface); + procedure setcolor(const Value: colorty); + function getfont: tgridpropfont; + function isfontstored: Boolean; + procedure setfont(const Value: tgridpropfont); + procedure setlinewidth(const Value: integer); + procedure setlinecolor(const Value: colorty); + procedure setlinecolorfix(const Value: colorty); + procedure setcolorselect(const Value: colorty); + procedure setcoloractive(avalue: colorty); + procedure setcolorfocused(avalue: colorty); +// procedure setcursor(const avalue: cursorshapety); + protected + fstate: gridpropstatesty; + fstart,fend: integer; + flinepos: integer; + flinewidth: integer; + flinecolor: colorty; + flinecolorfix: colorty; + fcolor: colorty; + fcursor: cursorshapety; + ffont: tgridpropfont; +// fgrid: tcustomgrid; + fframe: tcellframe; + fface: tcellface; + fcellinfo: cellinfoty; + foptions: coloptionsty; + fcolorselect: colorty; + fcoloractive: colorty; + fcolorfocused: colorty; + procedure updatelayout; virtual; + procedure changed; virtual; + procedure updatecellrect(const aframe: tcustomframe); + function getinnerframe: framety; virtual; + function step(getscrollable: boolean = true): integer; virtual; abstract; + function scrollable: boolean; virtual; abstract; + function framedim: sizety; + + //iframe + function getwidget: twidget; + procedure setframeinstance(instance: tcustomframe); + function getwidgetrect: rectty; + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function widgetstate: widgetstatesty; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; const org: originty = org_client; + const noclip: boolean = false); + function getframestateflags: framestateflagsty; + + procedure updatecellheight(const canvas: tcanvas; var aheight: integer); virtual; + //iface + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + procedure widgetregioninvalid; + function translatecolor(const acolor: colorty): colorty; + + procedure fontchanged(const sender: tobject); virtual; + property font: tgridpropfont read getfont write setfont stored isfontstored; + public + constructor create(const agrid: tcustomgrid; + const aprop: tgridarrayprop); reintroduce; virtual; + destructor destroy; override; + procedure createfont; + procedure createframe(); + procedure createface(); + procedure drawcellbackground(const acanvas: tcanvas; + const aframe: tcustomframe; const aface: tcustomface); + procedure drawcelloverlay(const acanvas: tcanvas; const aframe: tcustomframe); + property grid: tcustomgrid read fcellinfo.grid; + property innerframe: framety read getinnerframe; + published + property color: colorty read fcolor write setcolor default cl_default; + property cursor: cursorshapety read fcursor write fcursor default cr_default; + property frame: tcellframe read getframe write setframe; + property face: tcellface read getface write setface; + property linewidth: integer read flinewidth write setlinewidth + default defaultgridlinewidth; + property linecolor: colorty read flinecolor write setlinecolor; + property linecolorfix: colorty read flinecolorfix write setlinecolorfix + default defaultfixlinecolor; + property colorselect: colorty read fcolorselect write setcolorselect + default cl_default; + property coloractive: colorty read fcoloractive write setcoloractive + default cl_none; + property colorfocused: colorty read fcolorfocused write setcolorfocused + default cl_none; + property tag: integer read ftag write ftag default 0; + end; + + gridpropclassty = class of tgridprop; + + colpaintinfoty = record + canvas: tcanvas; + ystart,ystep: integer; + rows: integerarty; + foldinfo: rowfoldinfoarty; + startrow,endrow: integer; //index in rows + calcautocellsize: boolean; + autocellsize: sizety; + end; + + tcols = class; + rangety = record + startindex,endindex: integer; + end; + cellaxisrangety = record + scrollables: boolean; + range1,range2: rangety; + end; + rowpaintinfoty = record + canvas: tcanvas; + cols: tcols; + colrange: cellaxisrangety; + fix: boolean; + calcautocellsize: boolean; + end; + rowspaintinfoty = record + rowinfo: rowpaintinfoty; + rowrange: cellaxisrangety; + end; + + tcolselectfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tcol = class; + + celleventty = procedure(const sender: tobject; + var info: celleventinfoty) of object; + drawcelleventty = procedure(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty) of object; + beforedrawcelleventty = procedure(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: boolean) of object; + tcol = class(tgridprop) + private + frowfontoffset: integer; + frowfontoffsetselect: integer; + frowcoloroffset: integer; + fonbeforedrawcell: beforedrawcelleventty; + fonafterdrawcell: drawcelleventty; + frowcoloroffsetselect: integer; + ffontactivenum: integer; + ffontfocusednum: integer; + fwidthmax: integer; + fwidthmin: integer; + function getcolindex: integer; + procedure setfocusrectdist(const avalue: integer); + procedure updatepropwidth; + procedure setrowcoloroffset(const avalue: integer); + procedure setrowcoloroffsetselect(const avalue: integer); + procedure setrowfontoffset(const avalue: integer); + procedure setrowfontoffsetselect(const avalue: integer); + function getfontselect: tcolselectfont; + function isfontselectstored: Boolean; + procedure setfontselect(const Value: tcolselectfont); + + procedure setfontactivenum(const avalue: integer); + procedure setfontfocusednum(const avalue: integer); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getreadonly: boolean; + procedure setreadonly(const avalue: boolean); + protected + foptions1: coloptions1ty; + fwidth: integer; + fpropwidth: real; + ffontselect: tcolselectfont; + ffocusrectdist: integer; + fmaxwidth: integer; + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function checkautocolwidth: boolean; //true if width changed + procedure updatecolwidth(const arow,acount: integer; var acolwidth: integer); + procedure createfontselect; + function getselected(const row: integer): boolean; virtual; + procedure updatewidth(var avalue: integer); virtual; + procedure setwidth(const Value: integer); virtual; + procedure invalidatelayout; + procedure setoptions(const Value: coloptionsty); virtual; + procedure setoptions1(const avalue: coloptions1ty); virtual; + procedure updatelayout; override; + procedure rearange(const list: integerarty); virtual; abstract; + + procedure checkmaxwidth; + function checkactivecolor(const aindex: integer): boolean; + //true if coloractive and fontactivenum active + function checkfocusedcolor(const aindex: integer): boolean; + //true if colorfocus and fontfocusnum active + function isopaque: boolean; virtual; + function needsfocusrect: boolean; virtual; + function getdatapo(const arow: integer): pointer; virtual; + procedure clean(const start,stop: integer); virtual; + procedure paint(var info: colpaintinfoty); virtual; + class function defaultstep(width: integer): integer; virtual; + function step(getscrollable: boolean = true): integer; override; + function scrollable: boolean; override; + procedure dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); virtual; + procedure doafterdrawcell(const acanvas: tcanvas); virtual; + + procedure drawcell(const acanvas: tcanvas); virtual; + procedure drawfocusedcell(const acanvas: tcanvas); virtual; + procedure rowcountchanged(const newcount: integer); virtual; + procedure drawfocus(const acanvas: tcanvas); virtual; + procedure moverow(const curindex,newindex: integer; + const count: integer = 1); virtual; abstract; + procedure insertrow(const aindex: integer; + const count: integer = 1); virtual; abstract; + procedure deleterow(const aindex: integer; + const count: integer = 1); virtual; abstract; + property options: coloptionsty read foptions write setoptions; + property options1: coloptions1ty read foptions1 write setoptions1 default []; + property focusrectdist: integer read ffocusrectdist write setfocusrectdist + default 0; + function getmerged(const row: integer): boolean; virtual; + procedure setmerged(const row: integer; const avalue: boolean); virtual; + property merged[const row: integer]: boolean read getmerged write setmerged; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + procedure invalidate; + procedure invalidatecell(const arow: integer); + procedure invalidatemaxsize(const arow: integer = -1); virtual; + //-1 -> all + function rowcolor(const aindex: integer): colorty; + function rowfont(const aindex: integer): tfont; + procedure changed; override; + procedure cellchanged(const row: integer); virtual; + function actualcolor: colorty; + function actualfont: tfont; virtual; + function maxwidth: integer; + function minmaxwidth(): integer; //bigger of fwidthmin, fmaxwidth + property colindex: integer read getcolindex; + function translatetocell(const arow: integer; const apos: pointty): pointty; + property visible: boolean read getvisible write setvisible; + property enabled: boolean read getenabled write setenabled; + property readonly: boolean read getreadonly write setreadonly; + published + property width: integer read fwidth write setwidth + default griddefaultcolwidth; + property rowcoloroffset: integer read frowcoloroffset + write setrowcoloroffset default 0; + property rowcoloroffsetselect: integer read frowcoloroffsetselect + write setrowcoloroffsetselect default 0; + property rowfontoffset: integer read frowfontoffset write + setrowfontoffset default 0; + property rowfontoffsetselect: integer read frowfontoffsetselect write + setrowfontoffsetselect default 0; + property fontselect: tcolselectfont read getfontselect write + setfontselect stored isfontselectstored; + property fontactivenum: integer read ffontactivenum + write setfontactivenum default -1; + //index in grid.rowfonts + property fontfocusednum: integer read ffontfocusednum + write setfontfocusednum default -1; + //index in grid.rowfonts + property onbeforedrawcell: beforedrawcelleventty read fonbeforedrawcell + write fonbeforedrawcell; + property onafterdrawcell: drawcelleventty read fonafterdrawcell + write fonafterdrawcell; + end; + + tdatacol = class; + + showcolhinteventty = procedure(const sender: tdatacol; const arow: integer; + var info: hintinfoty) of object; + datacoleventty = procedure(const sender: tdatacol) of object; + datacolchangeeventty = procedure(const sender: tdatacol; + const aindex: integer) of object; + + tdatacol = class(tcol) + private + foncellevent: celleventty; + fonshowhint: showcolhinteventty; + fselectedrow: integer; //-1 none, -2 more than one + fselectedrowcount: int32; + fonselectionchanged: datacoleventty; + fselectlock: integer; + procedure internaldoentercell(const cellbefore: gridcoordty; + var newcell: gridcoordty; const action: focuscellactionty); + procedure internaldoexitcell(const cellbefore: gridcoordty; + var newcell: gridcoordty; const selectaction: focuscellactionty); + procedure setwidthmax(const Value: integer); + procedure setwidthmin(const Value: integer); + function getcellorigin: pointty; + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function getreadonly: boolean; + procedure setreadonly(const avalue: boolean); + function getselectedcells: integerarty; + procedure setselectedcells(const avalue: integerarty); + procedure setdata(const avalue: tdatalist); + function getsortdescend: boolean; + procedure setsortdescend(const avalue: boolean); + protected + fdata: tdatalist; + fname: string; + fnameb: string; + fonchange: datacolchangeeventty; + function getmerged(const row: integer): boolean; override; + procedure setmerged(const row: integer; const avalue: boolean); override; + procedure beginselect; + procedure endselect; + function getdatapo(const arow: integer): pointer; override; + function getrowdatapo: pointer; + procedure beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); virtual; + procedure afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); virtual; + procedure doselectionchanged; + procedure setselected(const row: integer; value: boolean); virtual; + function getselected(const row: integer): boolean; override; + procedure setoptions(const Value: coloptionsty); override; + function createdatalist: tdatalist; virtual; + procedure rowcountchanged(const newcount: integer); override; + procedure docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); virtual; + procedure doactivate; virtual; + procedure dodeactivate; virtual; + procedure clientmouseevent(const acell: gridcoordty; + var info: mouseeventinfoty); virtual; + procedure dokeyevent(var info: keyeventinfoty; up: boolean); virtual; + procedure checkdirtyautorowheight(aindex: integer); + procedure afterrowcountupdate; virtual; + procedure datachange(const arow: integer); virtual; + procedure itemchanged(const sender: tdatalist; const aindex: integer); virtual; + procedure updatewidth(var avalue: integer); override; + procedure updatelayout; override; + procedure moverow(const fromindex,toindex: integer; const count: integer = 1); override; + procedure insertrow(const aindex: integer; const count: integer = 1); override; + procedure deleterow(const aindex: integer; const count: integer = 1); override; + procedure rearange(const list: integerarty); override; + function sortcompare(const index1,index2: integer): integer; virtual; + function sortcomparecaseinsensitive( + const index1,index2: integer): integer; virtual; + function isempty(const aindex: integer): boolean; virtual; + procedure docellevent(var info: celleventinfoty); virtual; + function getcursor(const arow: integer; const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; virtual; + function getdatastatname: msestring; + function getstatsuffix(): msestring; + procedure coloptionstoeditoptions(var dest: optionseditty; + var dest1: optionsedit1ty); + procedure clean(const start,stop: integer); override; + function defaultrowheight: integer; virtual; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + + function canfocus(const abutton: mousebuttonty; + const ashiftstate: shiftstatesty; + const noreadonly: boolean; + out canrowfocus: boolean): boolean; virtual; + function isreadonly: boolean; //col readonly or row readonly + procedure updatecellzone(const row: integer; const pos: pointty; + var result: cellzonety); virtual; + procedure autocellheightchanged(const aindex: integer); + procedure autocellwidthchanged(const aindex: integer); + property datalist: tdatalist read fdata write setdata; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + procedure clearselection; + function defaultcaption(): msestring; + property merged; + property selected[const row: integer]: boolean read getselected write setselected; + //row < 0 -> whole col + property selectedcells: integerarty read getselectedcells + write setselectedcells; +// function selectedcellcount: integer; + property selectedcellcount: int32 read fselectedrowcount; + property cellorigin: pointty read getcellorigin; //org = grid.paintpos + property visible: boolean read getvisible write setvisible; + property enabled: boolean read getenabled write setenabled; + property readonly: boolean read getreadonly write setreadonly; + property sortdescend: boolean read getsortdescend write setsortdescend; + published + property options default defaultdatacoloptions; + property options1 default defaultdatacoloptions1; + property widthmin: integer read fwidthmin write setwidthmin default 1; + property widthmax: integer read fwidthmax write setwidthmax default 0; + property name: string read fname write fname; + property nameb: string read fnameb write fnameb; //ex. sumlevel + property onchange: datacolchangeeventty read fonchange write fonchange; + property oncellevent: celleventty read foncellevent write foncellevent; + property onshowhint: showcolhinteventty read fonshowhint write fonshowhint; + property onselectionchanged: datacoleventty read fonselectionchanged write + fonselectionchanged; + property linecolor default defaultdatalinecolor; + end; + + datacolaty = array[0..0] of tdatacol; + pdatacolaty = ^datacolaty; + + tcelldragobject = class(tdragobject) + private + fgrid: tcustomgrid; + fcell: gridcoordty; + public + constructor create(const draginfo: draginfoty; const cellinfo: cellinfoty); + constructor create(const agrid: tcustomgrid; + var ainstance: tdragobject; const apos: pointty); + property grid: tcustomgrid read fgrid; + property cell: gridcoordty read fcell; + end; + + celldrageventty = procedure(const cellinfo: cellinfoty; + var draginfo: draginfoty; var dragobject: tcelldragobject; + var accept: boolean; var processed: boolean) of object; + + tdrawcol = class(tdatacol) + private + fondrawcell: drawcelleventty; + fonbeforedragevent: celldrageventty; + fonafterdragevent: celldrageventty; + protected + procedure drawcell(const canvas: tcanvas); override; + procedure beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean) override; + procedure afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean) override; + published + property focusrectdist; + property ondrawcell: drawcelleventty read fondrawcell write fondrawcell; + property onbeforedragevent: celldrageventty read fonbeforedragevent + write fonbeforedragevent; + property onafterdragevent: celldrageventty read fonafterdragevent + write fonafterdragevent; + property font; + end; + + tstringcoldatalist = class(tmsestringdatalist) + private + fgrid: tcustomgrid; + fnoparagraph: integerarty; + fvaluedefault: msestring; + protected + procedure afterrowcountupdate; + function getnoparagraphs(index: integer): boolean; override; + function getdefault: pointer; override; + public + constructor create(const agrid: tcustomgrid); reintroduce; + function add(const avalue: msestring; const anoparagraph: boolean): integer; + override; + function empty(const index: integer): boolean; override; //true wenn leer + function getparagraph(const index: integer; + const aseparator: msestring = ''): msestring; + property noparagraph[index: integer]: boolean read getnoparagraphs; + published + property facultative; + end; + + tcustomstringcol = class(tdatacol) + private + ftextflagsactive: textflagsty; + fpasswordchar: msechar; + fonsetvalue: setstringeventty; + fondataentered: notifyeventty; + foncopytoclipboard: updatestringeventty; + fonpastefromclipboard: updatestringeventty; + fvaluetrue: msestring; + fvaluefalse: msestring; + fcolorglyph: colorty; + fondrawcell: drawcelleventty; + procedure settextflags(const avalue: textflagsty); + function getdatalist: tstringcoldatalist; + procedure setdatalist(const value: tstringcoldatalist); + procedure settextflagsactive(const avalue: textflagsty); + function geteditpos: gridcoordty; + procedure seteditpos(const avalue: gridcoordty); + procedure setpasswordchar(const avalue: msechar); + function getchecked(aindex: integer): boolean; + procedure setchecked(aindex: integer; const avalue: boolean); + function getvaluedefault: msestring; + procedure setvaluedefault(const avalue: msestring); + procedure setcolorglyph(const avalue: colorty); + function getnoparagraph(const aindex: integer): boolean; + protected + ftextinfo: drawtextinfoty; + foptionsedit: stringcoleditoptionsty; + foptionsedit1: optionsedit1ty; + feditstate: dataeditstatesty; +// procedure setisdb; + function geteditstate: dataeditstatesty; + procedure seteditstate(const avalue: dataeditstatesty); + + function needsfocusrect: boolean; override; + function getoptionsedit: optionseditty; virtual; + function getitems(aindex: integer): msestring; virtual; + procedure setitems(aindex: integer; const Value: msestring); virtual; + function createdatalist: tdatalist; override; + procedure afterrowcountupdate; override; + procedure updatedisptext(var avalue: msestring); virtual; + function getrowtext(const arow: integer): msestring; virtual; + procedure drawcell(const canvas: tcanvas); override; + procedure docellevent(var info: celleventinfoty); override; + procedure updatelayout; override; + function getinnerframe: framety; override; + function getcursor(const arow: integer; const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; override; + procedure modified; virtual; + procedure checkcellvalue(var avalue: msestring; var accept: boolean); + function defaultrowheight(): integer; override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + function edited: boolean; + function readpipe(const pipe: tpipereader; + const aoptions: addcharoptionsty = [aco_processeditchars]; +// const processeditchars: boolean = false; + const maxchars: integer = 0): integer; overload; + //returns added rowcount + function readpipe(const text: string; + const aoptions: addcharoptionsty = [aco_processeditchars]; +// const processeditchars: boolean = false; + const maxchars: integer = 0): integer; overload; + //returns added rowcount + procedure fillcol(const value: msestring); + property items[aindex: integer]: msestring read getitems + write setitems; default; + property noparagraph[const aindex: integer]: boolean read getnoparagraph; + property checked[aindex: integer]: boolean read getchecked write setchecked; + + property textflags: textflagsty read ftextinfo.flags write settextflags + default defaultcoltextflags; + property textflagsactive: textflagsty read ftextflagsactive + write settextflagsactive default defaultactivecoltextflags; + property optionsedit: stringcoleditoptionsty read foptionsedit + write foptionsedit default defaultstringcoleditoptions; + property optionsedit1: optionsedit1ty read foptionsedit1 + write foptionsedit1 default defaultoptionsedit1; + property passwordchar: msechar read fpasswordchar + write setpasswordchar default #0; + property font; + property datalist: tstringcoldatalist read getdatalist write setdatalist; + property editpos: gridcoordty read geteditpos write seteditpos; + property colorglyph: colorty read fcolorglyph write setcolorglyph + default cl_glyph; + property valuedefault: msestring read getvaluedefault write setvaluedefault; + property valuetrue: msestring read fvaluetrue write fvaluetrue; + property valuefalse: msestring read fvaluefalse write fvaluefalse; + property onsetvalue: setstringeventty read fonsetvalue write fonsetvalue; + //sender is tcustomstringcol + property ondataentered: notifyeventty read fondataentered write fondataentered; + //sender is tcustomstringcol + property oncopytoclipboard: updatestringeventty read foncopytoclipboard + write foncopytoclipboard; + //sender is tcustomstringcol + property onpastefromclipboard: updatestringeventty read fonpastefromclipboard + write fonpastefromclipboard; + //sender is tcustomstringcol + property ondrawcell: drawcelleventty read fondrawcell write fondrawcell; + end; + + tstringcol = class(tcustomstringcol) + published + property focusrectdist; + property textflags; + property textflagsactive; + property passwordchar; + property optionsedit1; //before optionsedit! + property optionsedit; + property font; + property datalist; + property valuedefault; + property valuefalse; + property valuetrue; + property fontselect; + property onsetvalue; + property ondataentered; + property oncopytoclipboard; + property onpastefromclipboard; + property ondrawcell; + end; + + stringcolclassty = class of tcustomstringcol; + + tfixcol = class(tcol) + private + fnumstart: integer; + fnumstep: integer; + fcaptions: tmsestringdatalist; + foptionsfix: fixcoloptionsty; + procedure settextflags(const Value: textflagsty); + procedure setnumstart(const Value: integer); + procedure setnumstep(const Value: integer); + procedure setcaptions(const Value: tmsestringdatalist); + function getcaptions: tmsestringdatalist; + function iscaptionsstored: Boolean; + procedure captionchanged(const sender: tdatalist; const aindex: integer); + procedure setoptionsfix(const avalue: fixcoloptionsty); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + protected + ftextinfo: drawtextinfoty; + procedure setoptions(const Value: coloptionsty); override; + procedure drawcell(const canvas: tcanvas); override; + procedure moverow(const fromindex,toindex: integer; const count: integer = 1); override; + procedure insertrow(const aindex: integer; const count: integer = 1); override; + procedure deleterow(const aindex: integer; const count: integer = 1); override; + procedure paint(var info: colpaintinfoty); override; + procedure rearange(const list: integerarty); override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + property visible: boolean read getvisible write setvisible; + published + property linewidth; + property linecolor default defaultfixlinecolor; + property textflags: textflagsty read ftextinfo.flags write settextflags + default defaultfixcoltextflags; + property numstart: integer read fnumstart write setnumstart default 0; + property numstep: integer read fnumstep write setnumstep default 0; + property captions: tmsestringdatalist + read getcaptions write setcaptions stored iscaptionsstored; + property color default cl_parent; + property options: fixcoloptionsty read foptionsfix write setoptionsfix + default defaultfixcoloptions; + property font; + end; + fixcolclassty = class of tfixcol; + + tcolheaderfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + cellmergeflagty = (cmf_h,cmf_v,cmf_rline); + cellmergeflagsty = set of cellmergeflagty; + + tcolheader = class(tindexpersistent,iframe,iface,iimagelistinfo) + private + finfo: captioninfoty; + ffont: tcolheaderfont; + fcolor: colorty; + fhint: msestring; + fmergecols: integer; + fmergerows: integer; + fmergeflags: cellmergeflagsty; + fmergedcx: integer; + fmergedx: integer; + fmergedcy: integer; + fmergedy: integer; + frefcell: gridcoordty; + procedure setcaption(const avalue: msestring); + procedure settextflags(const avalue: textflagsty); + function getfont: tcolheaderfont; + procedure setfont(const Value: tcolheaderfont); + function isfontstored: Boolean; + function getframe: tfixcellframe; + procedure setframe(const avalue: tfixcellframe); + function getface: tfixcellface; + procedure setface(const avalue: tfixcellface); + procedure setcolor(const avalue: colorty); + procedure setmergecols(const avalue: integer); + procedure setmergerows(const avalue: integer); + procedure setimagelist(const avalue: timagelist); + procedure setimagenr(const avalue: imagenrty); + procedure setcolorglyph(const avalue: colorty); + procedure setimagepos(const avalue: imageposty); + procedure setimagedist(const avalue: integer); + procedure setcaptiondist(const avalue: integer); + procedure readcaptionpos(reader: treader); + protected + fgrid: tcustomgrid; + fframe: tfixcellframe; + fface: tfixcellface; + fautocellsize: sizety; + procedure defineproperties(filer: tfiler); override; + procedure changed; + procedure fontchanged(const sender: tobject); + procedure drawcell(const acanvas: tcanvas; const adest: rectty); virtual; + + //iframe + function getwidget: twidget; + procedure setframeinstance(instance: tcustomframe); + function getwidgetrect: rectty; + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function widgetstate: widgetstatesty; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; const org: originty = org_client; + const noclip: boolean = false); + function getframestateflags: framestateflagsty; + //iface + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + procedure widgetregioninvalid; + function translatecolor(const acolor: colorty): colorty; + //iimagelistinfo + function getimagelist: timagelist; + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); override; + destructor destroy; override; + procedure createfont; + procedure createframe; + procedure createface; + property mergedcx: integer read fmergedcx; + property mergedx: integer read fmergedx; + property mergedcy: integer read fmergedcy; + property mergedy: integer read fmergedy; + published + property color: colorty read fcolor write setcolor default cl_parent; + property caption: msestring read finfo.caption.text write setcaption; + property textflags: textflagsty read finfo.textflags write settextflags + default defaultcaptiontextflags; + property font: tcolheaderfont read getfont write setfont stored isfontstored; + property frame: tfixcellframe read getframe write setframe; + property face: tfixcellface read getface write setface; + property mergecols: integer read fmergecols write setmergecols default 0; + property mergerows: integer read fmergerows write setmergerows default 0; + property hint: msestring read fhint write fhint; + property imagelist: timagelist read finfo.imagelist write setimagelist; + property imagenr: imagenrty read finfo.imagenr write setimagenr default -1; + property imagedist: integer read finfo.imagedist write setimagedist + default 0; + property captiondist: integer read finfo.captiondist write setcaptiondist + default defaultshapecaptiondist; + property imagepos: imageposty read finfo.imagepos write setimagepos + default ip_center; + property colorglyph: colorty read finfo.colorglyph + write setcolorglyph default cl_glyph; + //cl_none -> no no glyph + end; + + datacolheaderoptionty = (dco_colsort,dco_wholecellsortclick, + dco_nodisabledsortindicator,dco_hintclippedtext, + dco_noautowidth); + datacolheaderoptionsty = set of datacolheaderoptionty; + + tdatacolheader = class(tcolheader) + private + foptions: datacolheaderoptionsty; + procedure setoptions(const avalue: datacolheaderoptionsty); + protected + procedure drawcell(const acanvas: tcanvas; const adest: rectty); override; + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); override; + published + property options: datacolheaderoptionsty read foptions write setoptions + default [dco_hintclippedtext]; + end; + + tcolheaders = class(tindexpersistentarrayprop) + private + fgridprop: tgridprop; + ffixcol: boolean; + protected + fmergeflags: cellmergeflagsty; + procedure movecol(const curindex,newindex: integer); + procedure colcountchanged(const acount: integer); + procedure updatelayout(const cols: tgridarrayprop); + procedure dosizechanged; override; + public + constructor create(const agridprop: tgridprop); reintroduce; + end; + + tfixcolheaders = class(tcolheaders) + private + function getitems(const index: integer): tcolheader; + procedure setitems(const index: integer; const Value: tcolheader); + public + constructor create(const agridprop: tgridprop); + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tcolheader read getitems + write setitems; default; + end; + + tdatacolheaders = class(tcolheaders) + private + function getitems(const index: integer): tdatacolheader; + procedure setitems(const index: integer; const Value: tdatacolheader); + public + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tdatacolheader read getitems + write setitems; default; + end; + + tfixrow = class; + beforefixdrawcelleventty = procedure(const sender: tfixrow; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: boolean) of object; + drawfixcelleventty = procedure(const sender: tfixrow; const canvas: tcanvas; + const cellinfo: cellinfoty) of object; + + tfixrows = class; + tfixrow = class(tgridprop) + private + fheight: integer; + fnumstart: integer; + fnumstep: integer; + fcaptions: tdatacolheaders; + fcaptionsfix: tfixcolheaders; + foptionsfix: fixrowoptionsty; + fonbeforedrawcell: beforefixdrawcelleventty; + fonafterdrawcell: drawfixcelleventty; + procedure setheight(const Value: integer); + function getrowindex: integer; + procedure captionchanged(const sender: tarrayprop; const aindex: integer); + procedure setnumstart(const Value: integer); + procedure setnumstep(const Value: integer); + procedure settextflags(const Value: textflagsty); + procedure setcaptions(const Value: tdatacolheaders); + procedure setcaptionsfix(const Value: tfixcolheaders); + procedure setoptionsfix(const avalue: fixrowoptionsty); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + protected + ftextinfo: drawtextinfoty; + procedure datacolscountchanged(const acount: integer); + procedure fixcolscountchanged(const acount: integer); + procedure invalidatemaxsize(const acol: int32); + procedure cellchanged(const acol: integer); virtual; + procedure changed; override; + procedure updatelayout; override; + procedure updatemergedcells; + function step(getscrollable: boolean = true): integer; override; + procedure paint(const info: rowpaintinfoty); virtual; + procedure updateautocellsize(); + procedure drawcell(const canvas: tcanvas);{ virtual;} + procedure movecol(const curindex,newindex: integer; const aisfix: boolean); + procedure reorderdatacols(const neworder: integerarty); + procedure orderdatacols(const oldorder: integerarty); + procedure buttoncellevent(var info: celleventinfoty); + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + procedure synctofontheight; + property rowindex: integer read getrowindex; + property visible: boolean read getvisible write setvisible; + published + property height: integer read fheight write setheight; + property textflags: textflagsty read ftextinfo.flags write settextflags + default defaultfixcoltextflags; + property numstart: integer read fnumstart write setnumstart default 0; + property numstep: integer read fnumstep write setnumstep default 0; + property captions: tdatacolheaders read fcaptions write setcaptions; + property captionsfix: tfixcolheaders read fcaptionsfix write setcaptionsfix; + property font; + property linecolor default defaultfixlinecolor; + property options: fixrowoptionsty read foptionsfix + write setoptionsfix default []; + property onbeforedrawcell: beforefixdrawcelleventty read fonbeforedrawcell + write fonbeforedrawcell; + property onafterdrawcell: drawfixcelleventty read fonafterdrawcell + write fonafterdrawcell; + end; + + tgridarrayprop = class(tindexpersistentarrayprop) + private + ffirstsize: integer; + ftotsize: integer; + foppositecount: integer; + ffirstopposite: integer; + flinewidth: integer; + flinecolor: colorty; + flinecolorfix: colorty; + fcolorselect: colorty; + fcoloractive: colorty; + fcolorfocused: colorty; + finnerframe: framety; + fcursor: cursorshapety; + fcolor: colorty; + procedure setlinewidth(const Value: integer); + procedure setlinecolor(const Value: colorty); + procedure setlinecolorfix(const Value: colorty); + procedure setcolorselect(const avalue: colorty); + procedure setcoloractive(avalue: colorty); + procedure setcolorfocused(avalue: colorty); + procedure setinnerframe(const avalue: framety); + procedure setinnerframe_left(const avalue: integer); + procedure setinnerframe_top(const avalue: integer); + procedure setinnerframe_right(const avalue: integer); + procedure setinnerframe_bottom(const avalue: integer); + procedure setcursor(const avalue: cursorshapety); + procedure setcolor(const avalue: colorty); + protected + freversedorder: boolean; + fgrid: tcustomgrid; + function geotoindex(const ageoindex: integer): integer; + function geoitems(const aindex: integer): tgridprop; + procedure updatelayout; virtual; + function getclientsize: integer; virtual; abstract; + procedure setoppositecount(const value: integer); + procedure setcount1(acount: integer; doinit: boolean); override; + procedure countchanged; virtual; + function scrollablecount: integer; + procedure dochange(const aindex: integer); override; + procedure getindexrange(startpos,length: integer; + out range: cellaxisrangety; ascrollables: boolean = true); + function itematpos(const pos: integer; + const getscrollable: boolean = true): integer; //-1 if none + procedure createitem(const index: integer; var item: tpersistent); override; + procedure fontchanged; + procedure checktemplate(const sender: tobject); + public + constructor create(aowner: tcustomgrid; aclasstype: gridpropclassty); reintroduce; + function fixindex(const index: integer): integer; + property oppositecount: integer read foppositecount write setoppositecount default 0; + property innerframe: framety read finnerframe write setinnerframe; + published + property cursor: cursorshapety read fcursor write setcursor default cr_default; + property linewidth: integer read flinewidth + write setlinewidth default defaultgridlinewidth; + property linecolor: colorty read flinecolor + write setlinecolor; + property linecolorfix: colorty read flinecolorfix + write setlinecolorfix default defaultfixlinecolor; + property color: colorty read fcolor write setcolor + default cl_default; + property colorselect: colorty read fcolorselect write setcolorselect + default cl_default; + property coloractive: colorty read fcoloractive write setcoloractive + default cl_none; + property colorfocused: colorty read fcolorfocused write setcolorfocused + default cl_none; + property innerframe_left: integer read finnerframe.left + write setinnerframe_left default 1; + property innerframe_top: integer read finnerframe.top + write setinnerframe_top default 1; + property innerframe_right: integer read finnerframe.right + write setinnerframe_right default 1; + property innerframe_bottom: integer read finnerframe.bottom + write setinnerframe_bottom default 1; + end; + + tcolsfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tcolsfontselect = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tcols = class(tgridarrayprop) + private + fwidth: integer; + foptions: coloptionsty; + foptions1: coloptions1ty; + ffocusrectdist: integer; + ffontactivenum: integer; + ffontfocusednum: integer; + ffontselect: tcolsfontselect; + ffont: tcolsfont; + function getcols(const index: integer): tcol; + procedure setwidth(const value: integer); + procedure setoptions(const avalue: coloptionsty); + procedure setoptions(const avalue: coloptionsty; const aforce: boolean); + procedure setoptions1(const Value: coloptions1ty); + procedure setfocusrectdist(const avalue: integer); + procedure setfontactivenum(const avalue: integer); + procedure setfontfocusednum(const avalue: integer); + function getfontselect: tcolsfontselect; + function isfontselectstored: Boolean; + procedure setfontselect(const avalue: tcolsfontselect); + procedure fontselectchanged(const sender: tobject); + function getfont: tcolsfont; + procedure setfont(const avalue: tcolsfont); + function isfontstored: Boolean; + protected + fdataupdating: integer; + procedure begindataupdate; virtual; + procedure enddataupdate; virtual; + function getclientsize: integer; override; + procedure paint(var info: colpaintinfoty; const scrollables: boolean = true); + procedure updaterowheight(const arow: integer; var arowheight: integer); + function totwidth: integer; + procedure rowcountchanged(const countbefore: int32; + const newcount: int32); virtual; + procedure updatelayout; override; + procedure countchanged; override; + procedure moverow(const curindex,newindex: integer; + const acount: integer = 1); virtual; + procedure insertrow(const index: integer; const acount: integer = 1) virtual; + procedure deleterow(const index: integer; const acount: integer = 1) virtual; + procedure rearange(const list: integerarty); virtual; + procedure resetpropwidth; + property options: coloptionsty read foptions + write setoptions default []; + property options1: coloptions1ty read foptions1 + write setoptions1 default []; + public + constructor create(aowner: tcustomgrid; aclasstype: gridpropclassty); + destructor destroy; override; + procedure invalidatemaxsize(const arow: integer = -1); + procedure createfont(); + procedure createfontselect(); + procedure move(const curindex,newindex: integer); override; + function mergedwidth(const acol: integer; const amerged: longword): integer; + //returns additional width + property cols[const index: integer]: tcol read getcols; default; + property focusrectdist: integer read ffocusrectdist + write setfocusrectdist default 0; + property fontselect: tcolsfontselect read getfontselect + write setfontselect stored isfontselectstored; + property font: tcolsfont read getfont + write setfont stored isfontstored; + published + property width: integer read fwidth + write setwidth default griddefaultcolwidth; + property fontactivenum: integer read ffontactivenum + write setfontactivenum default -1; + //index in grid.rowfonts + property fontfocusednum: integer read ffontfocusednum + write setfontfocusednum default -1; + //index in grid.rowfonts + end; + + trowstatelist = class(tcustomrowstatelist + {$ifdef mse_with_ifi},iifidatalink{$endif}) + private + fdirtyvisible: integer; + fdirtyrow: integer; + fdirtyrowheight: integer; + fdirtyautorowheight: integer; + ffolded: boolean; + fgrid: tcustomgrid; + fhiddencount: integer; + fvisiblerows: integerarty; + fvisiblerowmap: tintegerdatalist; + ffoldchangedrow: integer; + ftopypos: integer; + flinkfoldhidden: listlinkinfoty; + flinkfoldlevel: listlinkinfoty; + flinkissum: listlinkinfoty; + ffoldhiddensourcelock: integer; + ffoldlevelsourcelock: integer; + fissumsourcelock: integer; + procedure cleanfolding(arow: integer; visibleindex: integer); + function isvisible(const arow: integer): boolean; + procedure counthidden(var aindex: integer); + procedure setfoldlevel(const index: integer; avalue: byte); + procedure setfolded(const avalue: boolean); + procedure setheight(const index: integer; const avalue: integer); + procedure setlinewidth(const index: integer; avalue: rowlinewidthty); + function getrowypos(const index: integer): integer; + procedure setsourcefoldhidden1(const avalue: string); + procedure setsourcefoldhidden(const avalue: string); + procedure setsourcefoldlevel1(const avalue: string); + procedure setsourcefoldlevel(const avalue: string); + procedure setsourceissum1(const avalue: string); + procedure setsourceissum(const avalue: string); + procedure sourcenamechanged(const atag: integer); + {$ifdef mse_with_ifi} + //iifilink + function getifilinkkind: ptypeinfo; + //iificlient + procedure setifiserverintf(const aintf: iifiserver); + function getdefaultifilink: iificlient; virtual; + + //iifidatalink + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + procedure ifisetvalue(var avalue; var accept: boolean); + procedure getifivalue(var avalue); + procedure setifivalue(const avalue); + function getgriddata: tdatalist; reintroduce; + function getvalueprop: ppropinfo; + procedure updatereadonlystate; + {$endif} + protected + procedure sethidden(const index: integer; const avalue: boolean); override; + procedure setfoldissum(const index: integer; const avalue: boolean); override; + function getlinkdatatypes(const atag: integer): listdatatypesty; override; + procedure checksyncfoldlevelsource(const index: integer; + const acount: integer); + procedure checksyncfoldhiddensource(const index: integer; + const acount: integer); + procedure foldhiddentosource(const index: integer; const acount: integer); + procedure foldissumtosource(const index: integer; const acount: integer); + procedure checksyncfoldissumsource(const index: integer; + const acount: integer); + + function totchildrencount(const aindex: integer; + const acount: integer): integer; + procedure movegrouptoparent(const aindex: integer; const acount: integer); + //called before deleting of rows + procedure updatedeletedrows(const index: integer; const acount: integer); + procedure internalshow(var aindex: integer); + procedure internalhide(var aindex: integer); + procedure show(const aindex: integer); + procedure hide(const aindex: integer); + procedure initdirty; override; + procedure cleanvisible(visibleindex: integer); + procedure clean(arow: integer); reintroduce; + procedure cleanrowheight(const aindex: integer); + procedure invalidatedirtyrowheight(const arow: int32); + //-2 -> count change + procedure checkdirty(const arow: integer); override; + procedure checkdirtyautorowheight(const arow: integer); + procedure recalchidden; override; + procedure readstate(const reader; const acount: integer; + const name: msestring); override; + function getstatdata(const index: integer): msestring; override; + procedure setstatdata(const index: integer; const value: msestring); + override; + function internalheight(const aindex: integer): integer; + //no valid checks + function internalystep(const aindex: integer): integer; overload; + //no valid checks + procedure internalystep(const aindex: integer; out ay: integer; + out acy:integer); overload; + //no valid checks + public + constructor create(const aowner: tcustomgrid); reintroduce; + destructor destroy; override; + + procedure listdestroyed(const sender: tdatalist); override; + function getsourcecount: integer; override; + function getsourceinfo(const atag: integer): plistlinkinfoty; override; + procedure linksource(const source: tdatalist; const atag: integer); override; + procedure sourcechange(const sender: tdatalist; + const index: integer); override; + procedure foldleveltosource(const index: integer; const acount: integer); + + procedure clearmemberitem(const subitem: integer; + const index: integer); override; + procedure setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); override; + + procedure change(const index: integer); override; + function cellrow(const arow: integer): integer; + function visiblerow(const arowindex: integer): integer; + //returns count of visible previous rows + function visiblerowcount: integer; + function visiblerowtoindex(const avisibleindex: integer): integer; + function visiblerows1(const astart: integer; const aendy: integer): integerarty; + procedure updatefoldinfo(const rows: integerarty; + var infos: rowfoldinfoarty); + function visiblerowstep(const arow: integer; const step: integer; + const autoappend: boolean): integer; + function rowhidden(const arow: integer): boolean; + function nearestvisiblerow(const arow: integer): integer; + procedure getfoldstate(const arow: integer; out aisvisible: boolean; + out afoldlevel: byte; out ahaschildren,aisopen: boolean); + procedure hidechildren(const arow: integer); + procedure showchildren(const arow: integer); + property folded: boolean read ffolded write setfolded; + procedure setupfoldinfo(asource: pbyte; const acount: integer); + property hidden[const index: integer]: boolean read gethidden write sethidden; + property foldlevel[const index: integer]: byte read getfoldlevel + write setfoldlevel; //0..63 + property foldissum[const index: integer]: boolean read getfoldissum + write setfoldissum; + property height[const index: integer]: integer read getheight + write setheight; + property linewidth[const index: integer]: rowlinewidthty + read getlinewidth write setlinewidth; + //-1 = default + function currentrowheight(const index: integer): integer; + property rowypos[const index: integer]: integer read getrowypos; + function rowindex(const aypos: integer): integer; + procedure fillfoldlevel(const index: integer; const acount: integer; + const avalue: byte); + published + property sourcefoldhidden: string read flinkfoldhidden.name + write setsourcefoldhidden; + property sourcefoldlevel: string read flinkfoldlevel.name + write setsourcefoldlevel; + property sourceissum: string read flinkissum.name + write setsourceissum; + end; + + tdatacols = class(tcols) + private + fselectedrow: integer; //-1 none, -2 more than one + fselectedrowcount: int32; + fsortcol: integer; + fsortcoldefault: integer; + fnewrowcol: integer; + fchangelock: integer; + flastvisiblecol: integer; + function getcols(const index: integer): tdatacol; + procedure setcols(const index: integer; const Value: tdatacol); + function getselectedcells: gridcoordarty; + procedure setselectedcells(const Value: gridcoordarty); + function getselectedrows: integerarty; + procedure setselectedrows(const avalue: integerarty); + function getselected(const cell: gridcoordty): boolean; + procedure setselected(const cell: gridcoordty; const Value: boolean); + function roworderinvalid: boolean; //true if accepted + procedure checkindexrange; + procedure setsortcol(const avalue: integer); + procedure setsortcoldefault(const avalue: integer); + procedure setnewrowcol(const avalue: integer); + function getrowselected(const index: integer): boolean; + procedure setrowselected(const index: integer; const avalue: boolean); + function getreadonly: boolean; + procedure setreadonly(const avalue: boolean); + protected + frowstate: trowstatelist; + fscrollsize: integer; + ffirsthscrollindex: integer; + procedure beginchangelock; + procedure endchangelock; + procedure datasourcechanged; virtual; + procedure begindataupdate; override; + procedure enddataupdate; override; + procedure dosizechanged; override; + procedure countchanged; override; + procedure mergechanged(const arow: integer); + procedure rearange(const list: integerarty); override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure setrowcountmax(const value: integer); + procedure rowcountchanged(const countbefore: int32; + const newcount: int32); override; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure updatelayout; override; + function colatpos(const x: integer; + const getscrollable: boolean = true): integer; + //0..count-1, invalidaxis if invalid + procedure moverow(const fromindex,toindex: integer; + const acount: integer = 1); override; + procedure insertrow(const index: integer; + const acount: integer = 1); override; + procedure deleterow(const index: integer; + const acount: integer = 1); override; + procedure changeselectedrange(const start,oldend,newend: gridcoordty; + calldoselectcell: boolean); virtual; + procedure beginselect; + procedure endselect; + procedure decselect; + + function hassortstat: boolean; + function hasdatastat: boolean; + procedure dostatread(const reader: tstatreader; + const aorder: boolean); virtual; + procedure dostatwrite(const writer: tstatwriter; + const aorder: boolean); virtual; + + function cancopy: boolean; + function canpaste: boolean; + procedure updatedatastate(var accepted: boolean); overload; virtual; + + public + constructor create(aowner: tcustomgrid; aclasstype: gridpropclassty); + destructor destroy; override; + function sortfunc(const l,r: integer): integer; + function updatedatastate: boolean; overload; + procedure move(const curindex,newindex: integer); override; + function previosvisiblecol(aindex: integer): integer; + //invalidaxis if none + function nextvisiblecol(aindex: integer): integer; + //invalidaxis if none + property lastvisiblecol: integer read flastvisiblecol; + function rowempty(const arow: integer): boolean; + property cols[const index: integer]: tdatacol read getcols + write setcols; default; + function colbyname(const aname: string): tdatacol; + //name is case sensitive + function datalistbyname(const aname: string): tdatalist; //can be nil + function colsubdatainfo(const aname: string): subdatainfoty; + + procedure clearselection; + function hasselection: boolean; + property selectedrowcount: int32 read fselectedrowcount; + function selectedcellcount: integer; + function hascolselection: boolean; + property selectedcells: gridcoordarty read getselectedcells + write setselectedcells; + property selectedrows: integerarty read getselectedrows + write setselectedrows; + property rowselected[const index: integer]: boolean read getrowselected + write setrowselected; + property selected[const cell: gridcoordty]: boolean read Getselected write Setselected; + //col < 0 and row < 0 -> whole grid, col < 0 -> whole col, + //row = < 0 -> whole row + procedure setselectedrange(const rect: gridrectty; const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); overload; + procedure setselectedrange(const start,stop: gridcoordty; + const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); overload; virtual; + procedure mergecols(const arow: integer; const astart: longword = 0; + const acount: longword = bigint); + procedure unmergecols(const arow: integer = invalidaxis); + //invalidaxis = all + property rowstate: trowstatelist read frowstate; + function defaultrowheight: integer; + property readonly: boolean read getreadonly write setreadonly; + published + property sortcol: integer read fsortcol write setsortcol default -1; + //-1 -> all + property sortcoldefault: integer read fsortcoldefault + write setsortcoldefault default -1; + //-1 -> no + property newrowcol: integer read fnewrowcol write setnewrowcol default -1; + //-1 -> actual + property width; + property options default defaultdatacoloptions; + property options1 default defaultdatacoloptions1; + property font; + property fontselect; + property linewidth; + property linecolor default defaultdatalinecolor; + property linecolorfix; + end; + + tdrawcols = class(tdatacols) + private + function getcols(const index: integer): tdrawcol; + public + constructor create(aowner: tcustomgrid); + class function getitemclasstype: persistentclassty; override; + property cols[const index: integer]: tdrawcol read getcols; default; + published + property focusrectdist; + end; + + tstringcols = class(tdatacols) + private + foptionsedit: stringcoleditoptionsty; + foptionsedit1: optionsedit1ty; + ftextflags: textflagsty; + ftextflagsactive: textflagsty; + function getcols(const index: integer): tstringcol; + procedure settextflags(avalue: textflagsty); + procedure settextflagsactive(avalue: textflagsty); + procedure setoptionsedit(avalue: stringcoleditoptionsty); + procedure setoptionsedit1(avalue: optionsedit1ty); + protected + function getcolclass: stringcolclassty; virtual; + procedure updatedatastate(var accepted: boolean); override; + public + constructor create(aowner: tcustomgrid); + class function getitemclasstype: persistentclassty; override; + property cols[const index: integer]: tstringcol read getcols; default; //last! + published + property focusrectdist; + property textflags: textflagsty read ftextflags write settextflags + default defaultcoltextflags; + property textflagsactive: textflagsty read ftextflagsactive + write settextflagsactive default defaultactivecoltextflags; + property optionsedit: stringcoleditoptionsty read foptionsedit + write setoptionsedit default defaultstringcoleditoptions; + property optionsedit1: optionsedit1ty read foptionsedit1 + write setoptionsedit1 default defaultoptionsedit1; + end; + + tfixcols = class(tcols) + private + function getcols(const index: integer): tfixcol; + procedure setcols(const index: integer; const Value: tfixcol); + protected + procedure countchanged; override; + procedure updatelayout; override; + function colatpos(const x: integer): integer; //-cout..-1, 0 if invalid + public + constructor create(aowner: tcustomgrid); + class function getitemclasstype: persistentclassty; override; + property cols[const index: integer]: tfixcol read getcols write setcols; default; + //index -1..-count + published + property width; + property linewidth; + property linecolor default defaultfixlinecolor; + property linecolorfix; + property oppositecount; + end; + + tfixrows = class(tgridarrayprop) + private + function getrows(const index: integer): tfixrow; + procedure setrows(const index: integer; const Value: tfixrow); + protected + function getclientsize: integer; override; + procedure updatelayout; override; + procedure updatemergedcells; + function rowatpos(const y: integer): integer; //-count..-1, 0 if invalid + procedure paint(const info: rowspaintinfoty); + procedure movecol(const curindex,newindex: integer; const isfix: boolean); + procedure datacolscountchanged; + procedure fixcolscountchanged; + procedure reorderdatacols(const neworder: integerarty); + procedure orderdatacols(const oldorder: integerarty); + procedure dofontheightdelta(var delta: integer); + public + constructor create(aowner: tcustomgrid); + class function getitemclasstype: persistentclassty; override; + procedure synctofontheight; + property rows[const index: integer]: tfixrow read getrows write setrows; default; + //index -1..-count + published + property oppositecount; + property linewidth; + property linecolor default defaultfixlinecolor; + property linecolorfix default defaultfixlinecolor; + end; + + tgridframe = class(tcustomautoscrollframe) + protected + function getscrollbarclass(vert: boolean): framescrollbarclassty; override; + function actualcolorclient(): colorty override; + public + constructor create(const aintf: iscrollframe; const owner: twidget; + const autoscrollintf: iautoscrollframe); + published + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient {default cl_foreground}; + property framei_left default 0; + property framei_top default 0; + property framei_right default 0; + property framei_bottom default 0; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property options; + property optionsskin; + + property sbvert; + property sbhorz; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + trowfontarrayprop = class(tpersistentarrayprop) + private + fgrid: tcustomgrid; + procedure setitems(const index: integer; const avalue: tfont); + protected + function getitems(const index: integer): tfont; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tcustomgrid); + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + property items[const index: integer]: tfont read getitems + write setitems; default; + end; + + cellinnerlevelty = (cil_all,cil_noline,cil_paint,cil_inner); + cellselectmodety = (csm_select,csm_deselect,csm_reverse); + selectcellmodety = (scm_cell,scm_row,scm_col); + + optionfoldty = (of_insertsamelevel,of_deletetree,of_shiftdeltoparent, + of_shiftchildren,of_validatelevel); + optionsfoldty = set of optionfoldty; + + gridnotifyeventty = procedure(const sender: tcustomgrid) of object; + griddataeventty = procedure(const sender: tcustomgrid; + const acell: gridcoordty) of object; + griddatablockeventty = procedure(const sender: tcustomgrid; + const acell: gridcoordty; const acount: integer) of object; + gridblockmovingeventty = procedure(const sender: tcustomgrid; + var fromindex,toindex,acount: integer) of object; + gridblockmovedeventty = procedure(const sender: tcustomgrid; + const fromindex,toindex,acount: integer) of object; + gridbeforeblockeventty = procedure(const sender: tcustomgrid; + var aindex,acount: integer) of object; + gridblockeventty = procedure(const sender: tcustomgrid; + const aindex: integer; const acount: integer) of object; + gridsorteventty = procedure(const sender: tcustomgrid; + const lindex,rindex: integer; + var aresult: integer) of object; + gridmorerowseventty = procedure(const sender: tcustomgrid; + const count: integer) of object; + //negative -> before row 0 + gridscrolleventty = procedure(const sender: tcustomgrid; + var step: integer) of object; + copyselectioneventty = procedure(const sender: tcustomgrid; + var handled: boolean) of object; + pasteselectioneventty = procedure(const sender: tcustomgrid; + var handled: boolean) of object; + + tcustomgrid = class(tpublishedwidget,iautoscrollframe,iobjectpicker,iscrollbar, + idragcontroller,istatfile + {$ifdef mse_with_ifi},iifigridlink{$endif}, + iassistiveclientgrid) + private + frepeater: tsimpletimer; + frepeataction: focuscellactionty; + fystep: integer; + ffirstvisiblerow: integer; + flastvisiblerow: integer; + fvisiblerows: integerarty; + fvisiblerowfoldinfo: rowfoldinfoarty; + fvisiblerowsbase: integer; //number of visible rows below scrollwindow + + flayoutupdating: integer; + fvisiblerowsupdating: integer; + fnullchecking: integer; + frowdatachanging: integer; + frowdatachangestart: int32; + fnoshowcaretrect: integer; + finvalidatedcells: gridcoordarty; + + foncellevent: celleventty; + fonrowsmoved: gridblockmovedeventty; + fonrowdatachanged: griddataeventty; + fonrowsdatachanged: griddatablockeventty; + fonrowsinserting: gridbeforeblockeventty; + fonrowsinserted: gridblockeventty; + fonrowsdeleting: gridbeforeblockeventty; + fonrowsdeleted: gridblockeventty; + fonrowcountchanged: gridnotifyeventty; + fonlayoutchanged: gridnotifyeventty; + fonbeforeupdatelayout: gridnotifyeventty; + fonsort: gridsorteventty; + + fdatarowlinewidth: integer; + fdatarowlinecolor: colorty; + fdatarowlinecolorfix: colorty; + + foncolmoved: gridblockmovedeventty; + fonselectionchanged: notifyeventty; + fgridframecolor: colorty; + frowcolors: tcolorarrayprop; + frowfonts: trowfontarrayprop; + fmouseparkcell: gridcoordty; + fclickedcell: gridcoordty; + fclickedcellbefore: gridcoordty; + + fstatfile: tstatfile; + fstatvarname: msestring; + + fonkeydown: keyeventty; + + fmouserefpos: pointty; + + fwheelscrollheight: integer; + fonscrollrows: gridscrolleventty; + + fonsortchanged: gridnotifyeventty; + fdatarowheightmin: integer; + fdatarowheightmax: integer; + foptionsfold: optionsfoldty; + foncopyselection: copyselectioneventty; + fonpasteselection: pasteselectioneventty; + fongetmorerows: gridmorerowseventty; + foncolmoving: gridblockmovingeventty; + fonrowsmoving: gridblockmovingeventty; + fonrowsmodified: notifyeventty; + fstatpriority: integer; +{$ifdef mse_with_ifi} + fifilink: tifigridlinkcomp; + fonedited: notifyeventty; + fnorowedit: boolean; + procedure ifirowchange; + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifigridlinkcomp); + //iifidatalink + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue); + procedure setifivalue(const avalue); + procedure updatereadonlystate; + //iifigridlink + function getrowstate: tcustomrowstatelist; +{$endif} + procedure setframe(const avalue: tgridframe); + function getframe: tgridframe; + procedure setstatfile(const Value: tstatfile); + + procedure setrowcount(value: integer); + procedure setrowcountmax(const value: integer); + procedure setdatacols(const Value: tdatacols); + procedure setfixcols(const Value: tfixcols); + procedure setfixrows(const Value: tfixrows); + procedure setcol(const value: integer); + procedure setrow(const value: integer); + + procedure killrepeater; + procedure startrepeater(state: gridstatety; time: integer); + procedure repeatproc(const sender: tobject); + + procedure calcpropcolwidthref; + procedure updatevisiblerows; + procedure setdatarowlinewidth(const Value: integer); + procedure setdatarowlinecolor(const Value: colorty); + procedure setdatarowlinecolorfix(const Value: colorty); + + procedure decodepickobject(code: integer; out kind: pickobjectkindty; + out cell: gridcoordty; out col: tcol; out row: tfixrow); + procedure setgridframecolor(const Value: colorty); + procedure setrowcolors(const Value: tcolorarrayprop); + procedure setrowfonts(const Value: trowfontarrayprop); + function getrowcolorstate(index: integer): rowstatenumty; + procedure setrowcolorstate(index: integer; const Value: rowstatenumty); + function getrowlinecolorstate(index: integer): rowstatenumty; + procedure setrowlinecolorstate(index: integer; const Value: rowstatenumty); + function getrowlinecolorfixstate(index: integer): rowstatenumty; + procedure setrowlinecolorfixstate(index: integer; const Value: rowstatenumty); + function getrowfontstate(index: integer): rowstatenumty; + procedure setrowfontstate(index: integer; const Value: rowstatenumty); + procedure setdragcontroller(const avalue: tdragcontroller); + function getrowreadonlystate(index: integer): boolean; + procedure setrowreadonlystate(index: integer; const avalue: boolean); + function getrowhidden(index: integer): boolean; + procedure setrowhidden(index: integer; const avalue: boolean); + function getrowfoldlevel(index: integer): byte; + procedure setrowfoldlevel(index: integer; const avalue: byte); + function getrowfoldissum(index: integer): boolean; + procedure setrowfoldissum(index: integer; const avalue: boolean); + function getrowheight(index: integer): integer; + procedure setrowheight(index: integer; avalue: integer); + + procedure setzebra_color(const avalue: colorty); + procedure setzebra_start(const avalue: integer); + procedure setzebra_height(const avalue: integer); + procedure setzebra_step(const avalue: integer); + function getsorted: boolean; + procedure setsorted(const avalue: boolean); + function getfolded: boolean; + procedure setfolded(const avalue: boolean); + function getrowstatelist: trowstatelist; + procedure setrowstatelist(const avalue: trowstatelist); + function getrowlinewidth(index: integer): rowlinewidthty; + procedure setrowlinewidth(index: integer; const avalue: rowlinewidthty); + function doonsort(const l,r: integer): integer; + procedure readgridframewidth(reader: treader); + function getrowwindowpos: int32; + procedure setrowwindowpos(const avalue: int32); + function getcolwindowpos: int32; + procedure setcolwindowpos(const avalue: int32); + function getcellwindowpos: pointty; + procedure setcellwindowpos(const avalue: pointty); + protected + fupdating: integer; + ffocuscount: integer; + fcellvaluechecking: integer; + flastcol: integer; + fpropcolwidthref: integer; + fzebra_start: integer; + fzebra_color: colorty; + fzebra_height: integer; + fzebra_step: integer; + ffocusedcell: gridcoordty; + fmousecell: gridcoordty; + fmouseeventcol: integer; + factiverow: integer; + fstartanchor,fendanchor: gridcoordty; + foptionsgrid: optionsgridty; + foptionsgrid1: optionsgrid1ty; + fstate: gridstatesty; + fstate1: gridstates1ty; + fshowcell: gridcoordty; + fshowcellmode: cellpositionty; + ffixcols: tfixcols; + ffixrows: tfixrows; + fdatacols: tdatacols; + fdatarowheight: integer; + frowcount: integer; + frowcountmax: integer; + fscrollrect: rectty; + fdatarect,fdatarectx,fdatarecty: rectty; + //origin = clientrect.pos + frootbrushorigin: pointty; + fbrushorigin: pointty; + //origin windowpos + fdragcontroller: tdragcontroller; + fobjectpicker: tobjectpicker; + fpickkind: pickobjectkindty; + fnumoffset: integer; //for fixcols + fnonullcheck: integer; + fnocheckvalue: integer; + fappendcount: integer; + flastcellpos: pointty; + flastcellzone: cellzonety; + class function classskininfo: skininfoty; override; + + function checkrowindex(var aindex: integer): boolean; + procedure setselected(const cell: gridcoordty; + const avalue: boolean); virtual; + procedure internalselectionchanged; + procedure setoptionsgrid(const avalue: optionsgridty); virtual; + function updatesortcol(const avalue: integer): integer; virtual; + //used in dbgrid switching index + function getsortdescend(const acol: integer): boolean; + procedure checkrowreadonlystate; virtual; + procedure checkneedsrowheight; + procedure updaterowheight(const arow: integer; var arowheight: integer); + + function setuserinput(const avalue: boolean): boolean; //returns old value + procedure resetuserinput(const avalue: boolean); + procedure doinsertrow(const sender: tobject); virtual; + procedure doappendrow(const sender: tobject); virtual; + function deleterowconfirmation(): boolean; + procedure dodeleterow(const sender: tobject); virtual; + procedure dodeleteselectedrows(const sender: tobject); virtual; + procedure dodeleterows(const sender: tobject); + procedure docopycells(const sender: tobject); + procedure dopastecells(const sender: tobject); + + procedure initeventinfo(const cell: gridcoordty; eventkind: celleventkindty; + out info: celleventinfoty); + procedure invalidate; + procedure invalidatesinglecell(const cell: gridcoordty); + function caninvalidate: boolean; + function docheckcellvalue: boolean; + procedure dolayoutchanged; virtual; + procedure internalupdatelayout(const force: boolean = false); + procedure updatelayout; virtual; + function intersectdatarect(var arect: rectty): boolean; + procedure setdatarowheight(const value: integer); + function getcaretcliprect: rectty; override; + procedure checkdatacell(const coord: gridcoordty); + procedure datacellerror(const coord: gridcoordty); + procedure error(aerror: griderrorty; text: string = ''); + procedure indexerror(row: boolean; index: integer; text: string = ''); + + procedure defineproperties(filer: tfiler); override; + function getdisprect: rectty; override; + procedure dofontheightdelta(var delta: integer); override; + procedure fontchanged; override; + procedure clientrectchanged; override; + procedure internalcreateframe; override; + function getscrollrect: rectty; + procedure setscrollrect(const rect: rectty); + function scrollcaret(const vertical: boolean): boolean; virtual; + procedure firstcellclick(const cell: gridcoordty; + var info: mouseeventinfoty); virtual; + function getzebrastart: integer; virtual; + function getnumoffset: integer; virtual; + + function createdatacols: tdatacols; virtual; + procedure createdatacol(const index: integer; out item: tdatacol); virtual; + function createfixcols: tfixcols; virtual; + function createfixrows: tfixrows; virtual; + procedure initcellinfo(var info: cellinfoty); virtual; + function cellhasfocus: boolean; virtual; + + procedure colchanged(const sender: tcol); + procedure cellchanged(const sender: tcol; const row: integer); + procedure focusedcellchanged; virtual; + procedure rowchanged(const arow: integer); virtual; + procedure rowstatechanged(const arow: integer); virtual; + procedure scrolled(const dist: pointty); virtual; + function hascolumnsort: boolean; + procedure sortchanged(const all: boolean); + procedure checkinvalidate; + function startanchor: gridcoordty; + function endanchor: gridcoordty; + + procedure doselectionchanged; virtual; + procedure docolmoved(const fromindex,toindex: integer); virtual; + procedure dorowsmoved(const fromindex,toindex,count: integer); virtual; + procedure dorowsinserting(var index,count: integer); virtual; + procedure dorowsinserted(const index,count: integer); virtual; + procedure dorowsdeleting(var index,count: integer); virtual; + procedure dorowsdeleted(index,count: integer); virtual; + procedure dorowsmodified; + procedure doedited(); + procedure dorowsdatachanged(const acell: gridcoordty; + const acount: integer); virtual; + procedure dorowcountchanged(const countbefore,newcount: integer); virtual; + procedure docellevent(var info: celleventinfoty); virtual; + procedure cellmouseevent(const acell: gridcoordty; var info: mouseeventinfoty; + const acellinfopo: pcelleventinfoty = nil; + const aeventkind: celleventkindty = cek_none); + procedure dofocusedcellposchanged; virtual; + function isfirstrow: boolean; virtual; + function islastrow: boolean; virtual; + + procedure internalinsertrow(var aindex: integer; var acount: integer; + const auserinput: boolean); virtual; + procedure internaldeleterow(var aindex: integer; var acount: integer; + const auserinput: boolean); virtual; + function internalsort(const sortfunc: indexsortcomparemethodty; + var refindex: integer): boolean; + //true if moved + procedure updaterowdata; virtual; + + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + + procedure doasyncevent(var atag: integer) override; + procedure loaded; override; + procedure doexit; override; + procedure doenter; override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure activechanged; override; + procedure getautopaintsize(var asize: sizety) override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure dobeforepaint(const canvas: tcanvas); override; + procedure doafterpaint(const canvas: tcanvas); override; + function getnoscroll(): boolean override; + procedure drawfocusedcell(const acanvas: tcanvas); virtual; + procedure drawcellbackground(const acanvas: tcanvas); + procedure drawcelloverlay(const acanvas: tcanvas); + + function caninsertrow: boolean; virtual; + function canappendrow: boolean; virtual; + function candeleterow: boolean; virtual; + function canmoverow: boolean; virtual; + + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + function rowatpos(y: integer): integer; + //0..rowcount-1, invalidaxis if invalid, client origin + function rowpos(arow: integer): integer; + //client origin + function ystep: integer; + function mergestart(const acol: integer; const arow: integer): integer; + function mergeend(const acol: integer; const arow: integer): integer; + function getmerged(const arow: integer): longword; + function nextfocusablecol(const acol: integer; const aleft: boolean; + const arow: integer; const noreadonly: boolean): integer; + procedure checkcellvalue(var accept: boolean); virtual; + //store edited value to grid + procedure checkmorerows(const acount: integer); + procedure beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); virtual; + procedure afterfocuscell(const cellbefore: gridcoordty; + const selectaction: focuscellactionty); virtual; + function wheelheight: integer; + function calcshowshift(const rect: rectty; + const position: cellpositionty): pointty; + procedure focusrow(const arow: integer; const action: focuscellactionty; + const noreadonly: boolean; + const selectmode: selectcellmodety = scm_cell); + function doremoveappinsrow(const oldrow,newrow: integer): boolean; + //true if removed + function hassort: boolean; + function canautoappend: boolean; virtual; + + + //idragcontroller + function getdragrect(const apos: pointty): rectty; override; + //iscrollbar + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); virtual; + + //idragcontroller + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + procedure beginnullchecking; + procedure endnullchecking; + procedure beginnonullcheck; + procedure endnonullcheck; + procedure beginnocheckvalue; + procedure endnocheckvalue; + function nocheckvalue: boolean; + procedure reorderrow; + + function getiassistiveclient(): iassistiveclient; override; + //iassistiveclient + function getassistiveflags(): assistiveflagsty; override; + //iassistiveclientgrid + function getassistivecellcaption(const acell: gridcoordty): msestring virtual; + function getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring virtual; + function getassistivefocusedcell(): gridcoordty; + function getassistivegridinfo(): assistivegridinfoty virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure initnewcomponent(const ascale: real); override; + procedure synctofontheight; override; + procedure dragevent(var info: draginfoty); override; + function internaldragevent(var info: draginfoty): boolean; virtual; + //true if processed + function actualcursor(const apos: pointty): cursorshapety; override; + + procedure beginupdate; + procedure endupdate(const nosort: boolean = false; + const invalidrowstart: int32 = 0); + function updating: boolean; reintroduce; + function calcminscrollsize: sizety; override; + procedure layoutchanged; + function cellclicked: boolean; + procedure rowdatachanged; overload; + procedure rowdatachanged(const acell: gridcoordty; + const count: integer = 1); overload; + //acell.col = invalidaxis -> col unknown + + procedure rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false) virtual; + procedure rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false) virtual; + procedure pageup(const action: focuscellactionty = fca_focusin); virtual; + procedure pagedown(const action: focuscellactionty = fca_focusin); virtual; + procedure wheelup(const action: focuscellactionty = fca_focusin); virtual; + procedure wheeldown(const action: focuscellactionty = fca_focusin); virtual; + procedure lastrow(const action: focuscellactionty = fca_focusin); virtual; + procedure firstrow(const action: focuscellactionty = fca_focusin); virtual; + + procedure colstep(const action: focuscellactionty; const step: integer; + const rowchange: boolean; + const nocolwrap: boolean; + const noreadonly: boolean); virtual; + //step > 0 -> right, step < 0 left + + function hasdata: boolean; + function canexitrow(const force: boolean = false): boolean; + function cellexiting: boolean; + + function gridprop(const coord: gridcoordty): tgridprop; //nil if none + function isdatacell(const coord: gridcoordty): boolean; + function isvalidcell(const coord: gridcoordty): boolean; + function isfixrow(const coord: gridcoordty): boolean; + function isfixcol(const coord: gridcoordty): boolean; + function rowvisible(const arow: integer): integer; + //0 -> fully visible, < 0 -> below > 0 above + function rowsperpage: integer; + function cellatpos(const apos: pointty; + out coord: gridcoordty): cellkindty; overload; + //origin = paintrect.pos + function cellatpos(const apos: pointty): gridcoordty; overload; + function cellrect(const cell: gridcoordty; + const innerlevel: cellinnerlevelty = cil_all; + const nomerged: boolean = false; + const acellorigin: boolean = false): rectty; + //origin = paintrect.pos if acellorigin = false, + //cell origin otherwise + function clippedcellrect(const cell: gridcoordty; + const innerlevel: cellinnerlevelty = cil_all): rectty; + //origin = paintrect.pos, clipped by datarect + function cellvisible(const acell: gridcoordty): boolean; + //returns row.visible and col.visible, independent from scrolling + procedure invalidatecell(const cell: gridcoordty); + procedure invalidatefocusedcell; + procedure invalidaterow(const arow: integer); + + function selectcell(const cell: gridcoordty; + const amode: cellselectmodety; + const checkmultiselect: boolean = false): boolean; + //true if accepted + function getselectedrange: gridrectty; //selected by focuscell() +// function getselectedrows: integerarty; + //moved to tdatacols.selectedrows + + function focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; virtual; + //true if ok + procedure focuscolbyname(const aname: string); + //case sensitive + function focusedcellvalid: boolean; + function rowremoving: boolean; + function scrollingcol: boolean; //true if focusedcolvalid and no co_nohscroll + function noscrollingcol: boolean; //true if focusedcolvalid and co_nohscroll + + function defocuscell: boolean; + function defocusrow: boolean; + function showrect(const rect: rectty; + const position: cellpositionty = cep_nearest; + const noxshift: boolean = false): pointty; + //returns shifted amount + function showcaretrect(const arect: rectty; + const aframe: tcustomframe): pointty; overload; + function showcaretrect(const arect: rectty; + const aframe: framety): pointty; overload; + function showcellrect(const rect: rectty; + const origin: cellinnerlevelty = cil_paint): pointty; + procedure showcell(const cell: gridcoordty; + const position: cellpositionty = cep_nearest; + const force: boolean = false); + //scrolls cell into view, force true -> if scrollbar clicked also + procedure showrow(const arow: integer; + const position: cellpositionty = cep_nearest; + const force: boolean = false); + procedure showlastrow; + procedure scrollrows(step: integer); + procedure scrollleft; + procedure scrollright; + procedure scrollpageleft; + procedure scrollpageright; + + //distance of active cell topleft to datarect topleft + property cellwindowpos: pointty read getcellwindowpos + write setcellwindowpos; + property rowwindowpos: int32 read getrowwindowpos write setrowwindowpos; + property colwindowpos: int32 read getcolwindowpos write setcolwindowpos; + + function userinput: boolean; + procedure movecol(curindex,newindex: integer; + const auserinput: boolean = false); virtual; + procedure moverow(curindex,newindex: integer; count: integer = 1; + const auserinput: boolean = false); virtual; + function insertrow(aindex: integer; acount: integer = 1; + const auserinput: boolean = false): int32; + //returns index of first row; + procedure deleterow(aindex: integer; acount: integer = 1; + const auserinput: boolean = false); + function appinsrow(aindex: integer;const auserinput: boolean = false): int32; + //insert or append empty row, set focused row to index + //empty row removed by exit row if og_noinsertempty + //returns insert index + function isinsertempty: boolean; + //true if row will be removed by og_noinsertempty + function isautoappend: boolean; //true if last row is auto appended + function autoappending: boolean; //empty row appending by focuscell + function checkreautoappend: boolean; //true if row appended + procedure removeappendedrow; + function autoremoving: boolean; //removing empty row + + procedure clear; //sets rowcount to 0 + function appendrow(const checkautoappend: boolean = false): integer; + //returns index of new row, does not call change events, calls updatelayout. + //use for single visible append, + //do not use for multiple row append in a block. + function appenddatarow: integer; + //returns index of new row, use it in a beginupdate/endupdate block + + procedure sortinvalid(const acol: integer = invalidaxis; + const arow: integer = invalidaxis); + function checksort: boolean; //true if sortchanged called + procedure sort; + + function copyselection: boolean; virtual; //false if no copy + function pasteselection: boolean; virtual; //false if no paste + + property optionsgrid: optionsgridty read foptionsgrid write setoptionsgrid + default defaultoptionsgrid; //first! + property optionsgrid1: optionsgrid1ty read foptionsgrid1 write foptionsgrid1 + default []; + property optionsfold: optionsfoldty read foptionsfold + write foptionsfold default []; + property norowedit: boolean read fnorowedit write fnorowedit; + property sorted: boolean read getsorted write setsorted; + property folded: boolean read getfolded write setfolded; + + property datarowlinewidth: integer read fdatarowlinewidth + write setdatarowlinewidth default defaultgridlinewidth; + property datarowlinecolorfix: colorty read fdatarowlinecolorfix + write setdatarowlinecolorfix default defaultfixlinecolor; + property datarowlinecolor: colorty read fdatarowlinecolor + write setdatarowlinecolor default defaultdatalinecolor; + property datarowheight: integer read fdatarowheight + write setdatarowheight default griddefaultrowheight; + property datarowheightmin: integer read fdatarowheightmin + write fdatarowheightmin default 1; + property datarowheightmax: integer read fdatarowheightmax + write fdatarowheightmax default maxint; + + property datacols: tdatacols read fdatacols write setdatacols; + property fixcols: tfixcols read ffixcols write setfixcols; + property fixrows: tfixrows read ffixrows write setfixrows; + + property rowcount: integer read frowcount write setrowcount default 0; + function rowhigh: integer; //rowcount - 1 + function datarowhigh: integer; //without auto appended empty row + property rowcountmax: integer read frowcountmax + write setrowcountmax default bigint; + function visiblerow(const arow: integer): integer; + //returns index in visible rows, invaidaxis if not visible + property firstvisiblerow: integer read ffirstvisiblerow; + property lastvisiblerow: integer read flastvisiblerow; + property visiblerows: integerarty read fvisiblerows; + + + property focusedcell: gridcoordty read ffocusedcell; + //col,row = invalidaxis if none + property col: integer read ffocusedcell.col write setcol; + property row: integer read ffocusedcell.row write setrow; + property mousecell: gridcoordty read fmousecell; + +// property gridframewidth: integer read fgridframewidth +// write setgridframewidth default 0; + property gridframecolor: colorty read fgridframecolor + write setgridframecolor default cl_gridframe; + + //rowproperties index = -1 -> focused row + property rowcolors: tcolorarrayprop read frowcolors write setrowcolors; + property rowcolorstate[index: integer]: rowstatenumty read getrowcolorstate + + write setrowcolorstate; //default = -1 + property rowlinecolorstate[index: integer]: rowstatenumty read getrowlinecolorstate + write setrowlinecolorstate; + //default = -1, og_rowheight must be set + property rowlinecolorfixstate[index: integer]: rowstatenumty + read getrowlinecolorfixstate + write setrowlinecolorfixstate; + //default = -1, og_rowheight must be set + property rowlinewidth[index: integer]: rowlinewidthty read getrowlinewidth + write setrowlinewidth; + //default = -1, og_rowheight must be set + + property rowfonts: trowfontarrayprop read frowfonts write setrowfonts; + property rowfontstate[index: integer]: rowstatenumty read getrowfontstate + write setrowfontstate; //default = -1 + property rowreadonlystate[index: integer]: boolean read getrowreadonlystate + write setrowreadonlystate; + property rowhidden[index: integer]: boolean read getrowhidden + write setrowhidden; + property rowfoldlevel[index: integer]: byte read getrowfoldlevel + write setrowfoldlevel; + property rowfoldissum[index: integer]: boolean read getrowfoldissum + write setrowfoldissum; + function rowfoldinfo: prowfoldinfoty; //nil if focused row not visible + property rowheight[index: integer]: integer read getrowheight + write setrowheight; + //og_rowheight must be set + property rowstatelist: trowstatelist read getrowstatelist + write setrowstatelist; +{$ifdef mse_with_ifi} + property ifilink: tifigridlinkcomp read fifilink write setifilink; +{$endif} + + property zebra_color: colorty read fzebra_color write setzebra_color + default cl_zebra; + property zebra_start: integer read fzebra_start write setzebra_start default 0; + property zebra_height: integer read fzebra_height write setzebra_height default 0; + property zebra_step: integer read fzebra_step write setzebra_step default 2; + + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + + property onbeforeupdatelayout: gridnotifyeventty + read fonbeforeupdatelayout write fonbeforeupdatelayout; + property onlayoutchanged: gridnotifyeventty read fonlayoutchanged + write fonlayoutchanged; + property oncolmoving: gridblockmovingeventty read foncolmoving + write foncolmoving; + property oncolmoved: gridblockmovedeventty read foncolmoved + write foncolmoved; + property onrowcountchanged: gridnotifyeventty read fonrowcountchanged + write fonrowcountchanged; + property onrowsdatachanged: griddatablockeventty read fonrowsdatachanged + write fonrowsdatachanged; + property onrowdatachanged: griddataeventty read fonrowdatachanged + write fonrowdatachanged; + property onrowsmoving: gridblockmovingeventty read fonrowsmoving + write fonrowsmoving; + property onrowsmoved: gridblockmovedeventty read fonrowsmoved + write fonrowsmoved; + property onscrollrows: gridscrolleventty read fonscrollrows + write fonscrollrows; + property ongetmorerows: gridmorerowseventty read fongetmorerows + write fongetmorerows; + + property onrowsinserting: gridbeforeblockeventty read fonrowsinserting + write fonrowsinserting; + property onrowsinserted: gridblockeventty read fonrowsinserted + write fonrowsinserted; + + property onrowsdeleting: gridbeforeblockeventty read fonrowsdeleting + write fonrowsdeleting; + property onrowsdeleted: gridblockeventty read fonrowsdeleted + write fonrowsdeleted; + property onrowsmodified: notifyeventty read fonrowsmodified + write fonrowsmodified; + //called if user deletes, inserts or moves rows + property onedited: notifyeventty read fonedited write fonedited; + //called if user types celltext or chages a cell value + property onsort: gridsorteventty read fonsort write fonsort; + property onsortchanged: gridnotifyeventty read fonsortchanged + write fonsortchanged; + + property oncellevent: celleventty read foncellevent write foncellevent; + property onselectionchanged: notifyeventty read fonselectionchanged + write fonselectionchanged; + property oncopyselection: copyselectioneventty read foncopyselection + write foncopyselection; + property onpasteselection: pasteselectioneventty read fonpasteselection + write fonpasteselection; + + property drag: tdragcontroller read fdragcontroller write setdragcontroller; + + published + property frame: tgridframe read getframe write setframe; + property font: twidgetfont read getfont write setfont stored isfontstored; + property fontempty: twidgetfontempty read getfontempty + write setfontempty stored isfontemptystored; + property onkeydown: keyeventty read fonkeydown write fonkeydown; + property wheelscrollheight: integer read fwheelscrollheight write + fwheelscrollheight default defaultwheelscrollheight; + property optionswidget default defaultgridwidgetoptions; + property optionswidget1 default defaultgridwidgetoptions1; + property onshortcut; + end; + + tcellgrid = class(tcustomgrid) + protected + procedure clientmouseevent(var info: mouseeventinfoty); override; + end; + + tdrawgrid = class(tcellgrid) + private + function getdatacols: tdrawcols; + procedure setdatacols(const value: tdrawcols); + function getcols(index: integer): tdrawcol; + procedure setcols(index: integer; const avalue: tdrawcol); + protected + function createdatacols: tdatacols; override; + property cols[index: integer]: tdrawcol read getcols write setcols; default; + published + property optionsgrid; + property optionsgrid1; + property optionsfold; + property datacols: tdrawcols read getdatacols write setdatacols; + property rowstatelist; + property fixcols; + property fixrows; + property rowcount; + property rowcountmax; + property gridframecolor; +// property gridframewidth; + property rowcolors; + property rowfonts; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datarowheight; + property datarowheightmin; + property datarowheightmax; + + property statfile; + property statvarname; + property statpriority; + + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property oncolmoving; + property oncolmoved; + property onrowcountchanged; + property onrowdatachanged; + property onrowsdatachanged; + property onrowsmoving; + property onrowsmoved; + property onrowsinserting; + property onrowsinserted; + property onrowsdeleting; + property onrowsdeleted; + property onrowsmodified; + property onedited; + property onscrollrows; + property ongetmorerows; + property oncellevent; + property onselectionchanged; + property onsort; + property onsortchanged; + property drag; + + end; + + tcustomstringgrid = class(tcellgrid,iedit) + private + function getdatacols: tstringcols; + procedure setdatacols(const value: tstringcols); + function getcols(index: integer): tstringcol; + procedure setcols(index: integer; const Value: tstringcol); + function getitems(const cell: gridcoordty): msestring; + procedure setitems(const cell: gridcoordty; const Value: msestring); + function getcaretwidth: integer; + procedure setcaretwidth(const value: integer); + protected + feditor: tinplaceedit; + procedure setupeditor(const acell: gridcoordty; const focusin: boolean); virtual; + procedure dofontheightdelta(var delta: integer); override; + procedure checkcellvalue(var accept: boolean); override; + procedure rootchanged(const aflags: rootchangeflagsty); override; + procedure updatelayout; override; + procedure firstcellclick(const cell: gridcoordty; + var info: mouseeventinfoty); override; + function createdatacols: tdatacols; override; + procedure docellevent(var info: celleventinfoty); override; + procedure drawfocusedcell(const canvas: tcanvas); override; + procedure scrolled(const dist: pointty); override; + function getcaretcliprect: rectty; override; //origin = clientrect.pos + property cols[index: integer]: tstringcol read getcols write setcols; default; + function currentdatalist: tmsestringdatalist; + + //iedit + function getoptionsedit: optionseditty; virtual; + procedure editnotification(var info: editnotificationinfoty); virtual; + function hasselection: boolean; + procedure updatecopytoclipboard(var atext: msestring); + procedure updatepastefromclipboard(var atext: msestring); + function locatecount: integer; //number of locate values + function locatecurrentindex: integer; //index of current row + procedure locatesetcurrentindex(const aindex: integer); + function getkeystring(const aindex: integer): msestring; //locate text + function getedited: boolean; + + procedure rowstatechanged(const arow: integer); override; + procedure dofocusedcellposchanged; override; + procedure focusedcellchanged; override; + procedure checkrowreadonlystate; override; + //interface to inplaceedit + procedure dokeydown(var info: keyeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure doactivate; override; + procedure dodeactivate; override; + + procedure doselectionchanged; override; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + //iassistiveclient + function getassistivecaretindex(): int32; override; + //iassistiveclientgrid + function getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure initnewcomponent(const ascale: real) override; + procedure synctofontheight; override; + function canclose(const newfocus: twidget): boolean; override; + function textclipped(const acell: gridcoordty; + out acellrect: rectty): boolean; overload; + function textclipped(const acell: gridcoordty): boolean; overload; + + function appendrow(const value: array of msestring; + const ashowlastrow: boolean = false): integer; overload; + function appendrow(const value: msestringarty; + const ashowlastrow: boolean = false): integer; overload; + function appendrow(const value: msestring; + const ashowlastrow: boolean = false): integer; overload; + //for visible single row append + + function appenddatarow(const value: array of msestring): integer; overload; + function appenddatarow(const value: msestringarty): integer; overload; + function appenddatarow(const value: msestring): integer; overload; + //for multiple data append in a beginupdate/endupdate block + + function copyselection: boolean; override; + function pasteselection: boolean; override; + property items[const cell: gridcoordty]: msestring read getitems write setitems; + property datacols: tstringcols read getdatacols write setdatacols; + property caretwidth: integer read getcaretwidth write setcaretwidth + default defaultcaretwidth; + end; + + tstringgrid = class(tcustomstringgrid) + public + procedure initnewcomponent(const ascale: real); override; + published + property optionsgrid; + property optionsgrid1; + property optionsfold; + property datacols; + property rowstatelist; + property fixcols; + property fixrows; + property rowcount; + property rowcountmax; + property gridframecolor; +// property gridframewidth; + property rowcolors; + property rowfonts; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datarowheight; + property datarowheightmin; + property datarowheightmax; + property caretwidth; + + property statfile; + property statvarname; + property statpriority; + + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property oncolmoving; + property oncolmoved; + property onrowcountchanged; + property onrowdatachanged; + property onrowsdatachanged; + property onrowsmoving; + property onrowsmoved; + property onrowsinserting; + property onrowsinserted; + property onrowsdeleting; + property onrowsdeleted; + property onrowsmodified; + property onedited; + property onscrollrows; + property ongetmorerows; + property oncellevent; + property onselectionchanged; + property onsort; + property onsortchanged; + property drag; + end; + + cellclickrestrictionty = (ccr_buttonpress,ccr_dblclick, + ccr_nodefaultzone,ccr_nokeyreturn,ccr_data); + cellclickrestrictionsty = set of cellclickrestrictionty; + +function gridcoordtotext(const coord: gridcoordty): string; +function isequalgridcoord(const a,b: gridcoordty): boolean; + +function iscellkeypress(const info: celleventinfoty; + const akey: keyty = key_none; //key_none -> all keys + const shiftstatemustinclude: shiftstatesty = []; + const shiftstatemustnotinclude: shiftstatesty = []): boolean; + +function iscellclick(const info: celleventinfoty; + const restrictions: cellclickrestrictionsty = []; + const shiftstatemustinclude: shiftstatesty = []; + const shiftstatemustnotinclude: shiftstatesty = [ss_repeat]): boolean; + +function isrowenter(const info: celleventinfoty; + const noentergrid: boolean = false): boolean; +function isrowexit(const info: celleventinfoty; + const noexitgrid: boolean = false): boolean; +function isrowchange(const info: celleventinfoty): boolean; +function wasrowenter(const info: celleventinfoty; + const noentergrid: boolean = false): boolean; +function wasrowexit(const info: celleventinfoty; + const noexitgrid: boolean = false): boolean; +function cellkeypress(const info: celleventinfoty): keyty; + +implementation +uses + mseguiintf,msestockobjects,mseact,mseactions,rtlconsts,msegraphedits, + mseassistiveserver,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tframe1 = class(tcustomframe); + tdatalist1 = class(tdatalist); + twidget1 = class(twidget); + tinplaceedit1 = class(tinplaceedit); + tcustomscrollbar1 = class(tcustomscrollbar); + +const + errorstrings: array[griderrorty] of string = ( + '', //ok + 'Ivalid datacell', + 'Rowcounts are different', + 'Invalid row index', + 'Invalid col index', + 'Invalid widget' + ); + +//var +// coloptionssplitinfo: setsplitinfoty; + +function iscellkeypress(const info: celleventinfoty; + const akey: keyty = key_none; //key_none -> all keys + const shiftstatemustinclude: shiftstatesty = []; + const shiftstatemustnotinclude: shiftstatesty = []): boolean; +begin + result:= false; + with info do begin + if (eventkind = cek_keydown) then begin + with keyeventinfopo^ do begin + if (key = akey) and + (shiftstate * shiftstatemustinclude = shiftstatemustinclude) and + (shiftstate * shiftstatemustnotinclude = []) then begin + include(eventstate,es_processed); + result:= true; + end; + end; + end; + end; +end; + +function iscellclick(const info: celleventinfoty; + const restrictions: cellclickrestrictionsty = []; + const shiftstatemustinclude: shiftstatesty = []; + const shiftstatemustnotinclude: shiftstatesty = [ss_repeat]): boolean; +begin + result:= false; + with info do begin + if not (ccr_data in restrictions) or + (info.cell.col >= 0) and (info.cell.row >= 0) then begin + case eventkind of + cek_keydown: begin + if not (ccr_nokeyreturn in restrictions) then begin + with info.keyeventinfopo^ do begin + if isenterkey(nil,key) and + (shiftstate * shiftstatemustinclude = shiftstatemustinclude) and + (shiftstate * shiftstatemustnotinclude = []) then begin + result:= true; + include(eventstate,es_processed); + end; + end; + end; + end; + cek_buttonpress,cek_buttonrelease: begin + if (zone <> cz_none) and not + ((zone = cz_default) and (ccr_nodefaultzone in restrictions)) then begin + with info.mouseeventinfopo^ do begin + if (button = mb_left) and not (es_objectpicking in eventstate) and + (shiftstate * shiftstatemustinclude = shiftstatemustinclude) and + (shiftstate * shiftstatemustnotinclude = []) then begin + if ((ccr_buttonpress in restrictions) and (eventkind = ek_buttonpress) or + not (ccr_buttonpress in restrictions) and + (eventkind = ek_buttonrelease)) then begin + if ccr_dblclick in restrictions then begin + result:= (ss_double in info.mouseeventinfopo^.shiftstate) and + (grid.fclickedcellbefore.row = cell.row) and + (grid.fclickedcellbefore.col = cell.col); + end + else begin + result:= true; + end; + if (eventkind = ek_buttonrelease) and + ((grid.fclickedcell.row <> cell.row) or + (grid.fclickedcell.col <> cell.col)) then begin + result:= false; + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function isrowenter(const info: celleventinfoty; + const noentergrid: boolean = false): boolean; +begin + with info do begin + result:= (eventkind = cek_enter) and + ((cellbefore.row <> newcell.row) or (selectaction = fca_focusinforce)) and + (not noentergrid or (selectaction <> fca_entergrid)); + end; +end; + +function isrowexit(const info: celleventinfoty; + const noexitgrid: boolean = false): boolean; +begin + with info do begin + result:= (eventkind = cek_exit) and (cellbefore.row <> newcell.row) and + (not noexitgrid or (info.selectaction <> fca_exitgrid)); + end; +end; + +function isrowchange(const info: celleventinfoty): boolean; +begin + with info do begin + result:= (eventkind = cek_focusedcellchanged) and (cellbefore.row <> newcell.row); + end; +end; + +function wasrowenter(const info: celleventinfoty; + const noentergrid: boolean = false): boolean; +begin + with info do begin + result:= isrowchange(info) and (newcell.row >= 0) and + (not noentergrid or (selectaction <> fca_entergrid)); + end; +end; + +function wasrowexit(const info: celleventinfoty; + const noexitgrid: boolean = false): boolean; +begin + with info do begin + result:= isrowchange(info) and (newcell.row < 0) and + (not noexitgrid or (selectaction <> fca_exitgrid)); + end; +end; + +function cellkeypress(const info: celleventinfoty): keyty; +begin + if info.eventkind = cek_keydown then begin + result:= info.keyeventinfopo^.key; + end + else begin + result:= key_none; + end; +end; + +function gridcoordtotext(const coord: gridcoordty): string; +begin + result:= 'Col: '+inttostr(coord.col) + ' Row: '+inttostr(coord.row); +end; + +function isequalgridcoord(const a,b: gridcoordty): boolean; +begin + result:= (a.col = b.col) and (a.row = b.row); +end; + +procedure stringcoltooptionsedit(const source: stringcoleditoptionsty; + var dest: optionseditty); +begin + if scoe_undoonesc in source then begin + include(dest,oe_undoonesc); + end; + if scoe_forcereturncheckvalue in source then begin + include(dest,oe_forcereturncheckvalue); + end; + if scoe_eatreturn in source then begin + include(dest,oe_eatreturn); + end; + dest:= optionseditty(replacebits( + longword({$ifdef FPC}longword{$else}longword{$endif}(source)) + shl stringcoloptionseditshift, + longword(dest),longword(stringcoloptionseditmask))); +end; + +procedure transferdeprecatedcoloptions(const source: coloptionsty; + var dest: coloptions1ty); +begin +{ + if co_rowfont in source then begin + include(dest,co1_rowfont); + end; + if co_rowcolor in source then begin + include(dest,co1_rowcolor); + end; + if co_zebracolor in source then begin + include(dest,co1_zebracolor); + end; + if co_rowcoloractive in source then begin + include(dest,co1_rowcoloractive); + end; +} +end; + +{ tcellframe } + +constructor tcellframe.create(const aintf: iframe); +begin + inherited; + include(fstate,fs_nowidget); + fi.innerframe.right:= 1; + fi.innerframe.top:= 1; + fi.innerframe.left:= 1; + fi.innerframe.bottom:= 1; +end; + +{ tgridframe } + +constructor tgridframe.create(const aintf: iscrollframe; const owner: twidget; + const autoscrollintf: iautoscrollframe); +begin + inherited; + fi.innerframe.right:= 0; + fi.innerframe.top:= 0; + fi.innerframe.left:= 0; + fi.innerframe.bottom:= 0; + internalupdatestate; + fi.levelo:= -2; +end; + +function tgridframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + +function tgridframe.getscrollbarclass(vert: boolean): framescrollbarclassty; +begin + result:= tthumbtracknopagesizescrollbar; +end; + +{ tgridpropfont } + +class function tgridpropfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tgridprop(owner).ffont; +end; + +{ tgridprop } + +constructor tgridprop.create(const agrid: tcustomgrid; + const aprop: tgridarrayprop); +begin + fcellinfo.grid:= agrid; + fcolor:= aprop.fcolor; + fcursor:= aprop.fcursor; + fcolorselect:= aprop.fcolorselect; + fcoloractive:= aprop.fcoloractive; + fcolorfocused:= aprop.fcolorfocused; + flinecolor:= aprop.linecolor; + flinecolorfix:= aprop.linecolorfix; + flinewidth:= aprop.linewidth; + inherited create(agrid,aprop); + agrid.initcellinfo(fcellinfo); +end; + +destructor tgridprop.destroy; +begin + inherited; + fframe.free; + fface.free; + ffont.free; +end; + +procedure tgridprop.createframe; +begin + if fframe = nil then begin + tcellframe.create(iframe(self)); + end; +end; + +procedure tgridprop.createface; +begin + if fface = nil then begin + fface:= tcellface.create(iface(self)); + end; +end; + +procedure tgridprop.setlinewidth(const Value: integer); +begin + if flinewidth <> value then begin + if value < 0 then begin + flinewidth:= 0; + end + else begin + flinewidth:= Value; + end; + fcellinfo.grid.layoutchanged; + end; +end; +{ +function tgridprop.islinewidthstored: Boolean; +begin + result:= flinewidth <> tcols(prop).flinewidth; +end; +} +procedure tgridprop.setlinecolor(const Value: colorty); +begin + if flinecolor <> value then begin + flinecolor:= Value; + fcellinfo.grid.layoutchanged; + end; +end; +{ +function tgridprop.islinecolorstored: Boolean; +begin + result:= flinecolor <> tcols(prop).flinecolor; +end; +} +procedure tgridprop.setlinecolorfix(const Value: colorty); +begin + if flinecolorfix <> value then begin + flinecolorfix:= Value; + fcellinfo.grid.layoutchanged; + end; +end; + +procedure tgridprop.setcolorselect(const Value: colorty); +begin + if value <> fcolorselect then begin + fcolorselect := Value; + changed; + end; +end; + +procedure tgridprop.setcoloractive(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if avalue <> fcoloractive then begin + fcoloractive:= avalue; + fcellinfo.grid.layoutchanged; + changed; + end; +end; + +procedure tgridprop.setcolorfocused(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if avalue <> fcolorfocused then begin + fcolorfocused:= avalue; + fcellinfo.grid.layoutchanged; + changed; + end; +end; +{ +function tgridprop.islinecolorfixstored: Boolean; +begin + result:= flinecolorfix <> tgridarrayprop(prop).flinecolorfix; +end; + +function tgridprop.iscolorselectstored: boolean; +begin + result:= fcolorselect <> tgridarrayprop(prop).fcolorselect; +end; + +function tgridprop.iscoloractivestored: boolean; +begin + result:= fcoloractive <> tgridarrayprop(prop).fcoloractive; +end; +} +function tgridprop.getframe: tcellframe; +begin + fcellinfo.grid.getoptionalobject(fframe,{$ifdef FPC}@{$endif}createframe); + result:= fframe; +end; + +function tgridprop.getface: tcellface; +begin + fcellinfo.grid.getoptionalobject(fface,{$ifdef FPC}@{$endif}createface); + result:= fface; +end; + + //iframe +function tgridprop.getwidget: twidget; +begin + result:= fcellinfo.grid; +end; + +function tgridprop.getclientrect: rectty; +begin + result:= fcellinfo.grid.clientrect; +end; + +procedure tgridprop.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + fcellinfo.grid.setlinkedvar(source,dest,linkintf); +end; + +procedure tgridprop.widgetregioninvalid; +begin + fcellinfo.grid.widgetregioninvalid; +end; + +procedure tgridprop.setframeinstance(instance: tcustomframe); +begin + fframe:= tcellframe(instance); +end; + +function tgridprop.getwidgetrect: rectty; +begin + result:= fcellrect; +end; +{ +procedure tgridprop.setwidgetrect(const rect: rectty); +begin + twidget1(getwidget).setwidgetrect(rect); +end; +} +procedure tgridprop.setstaticframe(value: boolean); +begin + //dummy +end; + +function tgridprop.getstaticframe: boolean; +begin + result:= false; +end; + +function tgridprop.widgetstate: widgetstatesty; +begin + result:= twidget1(getwidget).widgetstate; +end; + +procedure tgridprop.scrollwidgets(const dist: pointty); +begin + twidget1(getwidget).scrollwidgets(dist); +end; + +procedure tgridprop.clientrectchanged; +begin + fcellinfo.grid.layoutchanged; +end; + +function tgridprop.getcomponentstate: tcomponentstate; +begin + result:= getwidget.componentstate; +end; + +function tgridprop.getmsecomponentstate: msecomponentstatesty; +begin + result:= getwidget.msecomponentstate; +end; + +procedure tgridprop.invalidate; +begin + getwidget.invalidate; +end; + +procedure tgridprop.invalidatewidget; +begin + getwidget.invalidatewidget; +end; + +procedure tgridprop.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + getwidget.invalidaterect(rect,org,noclip); +end; +{ +function tgridprop.getframefont: tfont; +begin + result:= twidget1(getwidget).getfont; +end; + +function tgridprop.getcanvas(aorigin: originty = org_client): tcanvas; +begin + result:= getwidget.getcanvas(aorigin); +end; + +function tgridprop.canfocus: boolean; +begin + result:= getwidget.canfocus; +end; + +function tgridprop.setfocus(aactivate: boolean = true): boolean; +begin + result:= getwidget.setfocus(aactivate); +end; +} +procedure tgridprop.setframe(const Value: tcellframe); +begin + fcellinfo.grid.setoptionalobject(value,fframe,{$ifdef FPC}@{$endif}createframe); + clientrectchanged; +end; + +procedure tgridprop.setface(const Value: tcellface); +begin + fcellinfo.grid.setoptionalobject(value,fface,{$ifdef FPC}@{$endif}createface); + fcellinfo.grid.invalidate; +end; + +procedure tgridprop.drawcellbackground(const acanvas: tcanvas; + const aframe: tcustomframe; const aface: tcustomface); +var + rect1: rectty; +// pt1: pointty; +begin + rect1:= makerect(nullpoint,fcellrect.size); + acanvas.fillrect(rect1,fcellinfo.color); + if aframe <> nil then begin + aframe.paintbackground(acanvas,rect1,true,true); + end; + acanvas.rootbrushorigin:= fcellinfo.grid.fbrushorigin; + if aface <> nil then begin + aface.paint(acanvas,makerect(nullpoint,fcellinfo.rect.size)); + end; +end; + +procedure tgridprop.drawcelloverlay(const acanvas: tcanvas; + const aframe: tcustomframe); +begin + if aframe <> nil then begin + aframe.paintoverlay(acanvas,makerect(nullpoint,fcellrect.size)); + end; +end; + +procedure tgridprop.setcolor(const Value: colorty); +begin + if color <> value then begin + fcolor := Value; + changed; + end; +end; + +procedure tgridprop.changed; +begin + //dummy +end; + +function tgridprop.getinnerframe: framety; +begin + result:= tgridarrayprop(prop).finnerframe; +end; + +procedure tgridprop.updatecellrect(const aframe: tcustomframe); +begin + fcellinfo.rect:= makerect(nullpoint,fcellrect.size); + if aframe <> nil then begin + deflaterect1(fcellinfo.rect,tframe1(aframe).fpaintframe); + with tframe1(aframe).fi.innerframe do begin + fcellinfo.innerrect.pos:= pointty(topleft); + fcellinfo.innerrect.cx:= fcellinfo.rect.cx - left - right; + fcellinfo.innerrect.cy:= fcellinfo.rect.cy - top - bottom; + fcellinfo.frameinnerrect:= fcellinfo.innerrect; + end; + end + else begin + fcellinfo.innerrect:= deflaterect(makerect(nullpoint,fcellinfo.rect.size), + getinnerframe); + fcellinfo.frameinnerrect:= fcellinfo.rect; + end; +end; + +procedure tgridprop.updatelayout; +begin + if fframe <> nil then begin + fframe.updatestate; + end; + updatecellrect(fframe); +end; + +//iface +function tgridprop.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; +end; + +procedure tgridprop.fontchanged(const sender: tobject); +begin + changed; +end; + +function tgridprop.getfont: tgridpropfont; +begin + getoptionalobject(fcellinfo.grid.componentstate,ffont, + {$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= tgridpropfont(pointer(fcellinfo.grid.getfont)); + end; +end; + +procedure tgridprop.setfont(const Value: tgridpropfont); +begin + if value <> ffont then begin + setoptionalobject(fcellinfo.grid.ComponentState,value,ffont, + {$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function tgridprop.isfontstored: Boolean; +begin + result:= ffont <> nil; +end; + +procedure tgridprop.createfont; +begin + if ffont = nil then begin + ffont:= tgridpropfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function tgridprop.getframestateflags: framestateflagsty; +begin + result:= []; +end; + +procedure tgridprop.updatecellheight(const canvas: tcanvas; var aheight: integer); +begin + //dummy +end; + +function tgridprop.framedim: sizety; +begin + if fframe = nil then begin + result:= nullsize; + end + else begin + result:= fframe.paintframedim; + end; +end; + +{ tcolselectfont } + +class function tcolselectfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcol(owner).ffontselect; +end; + +{ tcol} + +constructor tcol.create(const agrid: tcustomgrid; const aowner: tgridarrayprop); +begin + inherited create(agrid,aowner); + ffocusrectdist:= tcols(aowner).ffocusrectdist; + fwidth:= tcols(aowner).fwidth; + foptions:= tcols(aowner).foptions; + foptions1:= tcols(aowner).foptions1; + if co1_autorowheight in foptions1 then begin + include(fstate,gps_needsrowheight); + end; + flinewidth:= tcols(aowner).flinewidth; + flinecolor:= tcols(aowner).flinecolor; + ffontactivenum:= tcols(aowner).ffontactivenum; + ffontfocusednum:= tcols(aowner).ffontfocusednum; +end; + +destructor tcol.destroy; +begin + ffontselect.free; + inherited; +end; +(* +procedure tcol.readoptions(reader: treader); +var + set1,set2: tintegerset; +begin + if readsplitset(reader,coloptionssplitinfo,set1,set2) then begin + optionscell:= celloptionsty(set2); + end; + options:= coloptionsty(set1); +// options:= coloptionsty(readset(reader,typeinfo(coloptionsty))); +end; + +procedure tcol.defineproperties(filer: tfiler); +begin + filer.defineproperty('options',{$ifdef FPC}@{$endif}readoptions,nil,false); +end; +*) +procedure tcol.invalidate; +begin + fcellinfo.grid.colchanged(self); +end; + +procedure tcol.changed; +begin + inherited; + invalidate; +end; + +procedure tcol.cellchanged(const row: integer); +begin + fcellinfo.grid.cellchanged(self,row); +end; + +procedure tcol.invalidatecell(const arow: integer); +begin + fcellinfo.grid.invalidatecell(makegridcoord(colindex,arow)); +end; + +procedure tcol.drawcell(const acanvas: tcanvas); +begin + if not fcellinfo.calcautocellsize then begin + drawcellbackground(acanvas,fframe,fface); + end; +end; + +function tcol.actualcolor: colorty; +begin + if fcolor <> cl_default then begin + if fcolor = cl_parent then begin + result:= fcellinfo.grid.actualopaquecolor; + end + else begin + result:= fcolor; + end; + end + else begin + result:= tframe1(fcellinfo.grid.fframe).actualcolorclient; + end; +end; + +function tcol.isopaque: boolean; +begin + result:= actualcolor <> cl_transparent; +end; + +function tcol.checkactivecolor(const aindex: integer): boolean; + //true if coloractive and fontactivenum active +begin + result:= (fcellinfo.grid.entered {or (co1_active in foptions1)}) and + (aindex = fcellinfo.grid.ffocusedcell.row) and + ((gps_fix in fstate) or (co1_rowcoloractive in foptions1) or + (findex = fcellinfo.grid.ffocusedcell.col)) +end; + +function tcol.checkfocusedcolor(const aindex: integer): boolean; + //true if colorfocus and fontfocusnum active +begin + result:= //(fgrid.entered {or (co1_active in {tcols(prop).}foptions1)}) and + (aindex = fcellinfo.grid.ffocusedcell.row) and + ((gps_fix in fstate) or (co1_rowcolorfocused in foptions1) or + (findex = fcellinfo.grid.ffocusedcell.col)) +end; + +function tcol.rowcolor(const aindex: integer): colorty; +var + po1: prowstatety; + by1: byte; + int1: integer; + bo1: boolean; +begin + result:= cl_none; + if aindex >= 0 then begin + bo1:= getselected(aindex); + if co1_rowcolor in foptions1 then begin + po1:= fcellinfo.grid.fdatacols.frowstate.getitempo(aindex); + by1:= po1^.color and rowstatenummask; +// if by1 <> 0 then begin + int1:= by1 + frowcoloroffset - 1; + if bo1 then begin + int1:= int1 + frowcoloroffsetselect; + end; + if (int1 >= 0) and (int1 < fcellinfo.grid.frowcolors.count) then begin + result:= fcellinfo.grid.frowcolors[int1]; + end; +// end; + end; + if bo1 and (result = cl_none) and (fcolorselect <> cl_none) then begin + if fcolorselect <> cl_default then begin + result:= fcolorselect; + end + else begin + result:= defaultselectedcellcolor; + end; + end; + if (result = cl_none) and checkactivecolor(aindex) then begin + result:= fcoloractive; + end; + if (result = cl_none) and checkfocusedcolor(aindex) then begin + result:= fcolorfocused; + end; + if result = cl_none then begin + if (co1_zebracolor in foptions1) then begin + with fcellinfo.grid do begin + if (fzebra_step > 0) then begin + int1:= (aindex - getzebrastart) mod fzebra_step; + if int1 < 0 then begin + if int1 < fzebra_height - fzebra_step then begin + result:= fzebra_color; + end; + end + else begin + if int1 < fzebra_height then begin + result:= fzebra_color; + end; + end; + end; + end; + end; + end; + end; + if result = cl_none then begin + result:= actualcolor; + end; +end; + +function tcol.actualfont: tfont; +begin + if ffont = nil then begin + result:= tcols(prop).ffont; + if result = nil then begin + result:= fcellinfo.grid.getfont; + end; + end + else begin + result:= ffont; + end; +end; + +function tcol.rowfont(const aindex: integer): tfont; +var + po1: prowstatety; + by1: byte; + int1: integer; + bo1: boolean; +begin + result:= nil; + if aindex >= 0 then begin + bo1:= getselected(aindex); + if co1_rowfont in foptions1 then begin + po1:= fcellinfo.grid.fdatacols.frowstate.getitempo(aindex); + by1:= po1^.font and rowstatenummask; + if by1 <> 0 then begin + int1:= by1 + frowfontoffset - 1; + if bo1 then begin + int1:= int1 + frowfontoffsetselect; + end; + if (int1 >= 0) and (int1 < fcellinfo.grid.frowfonts.count) then begin + result:= tfont(fcellinfo.grid.frowfonts.fitems[int1]); + end; + end; + end; + if bo1 and (result = nil) then begin + result:= ffontselect; + if result = nil then begin + result:= tcols(prop).ffontselect; + end; + end; + end; + if result = nil then begin + if (ffontactivenum >= 0) and + (ffontactivenum < fcellinfo.grid.frowfonts.count) then begin + if checkactivecolor(aindex) then begin + result:= tfont(fcellinfo.grid.frowfonts.fitems[ffontactivenum]); + end; + end; + if result = nil then begin + if (ffontfocusednum >= 0) and + (ffontfocusednum < fcellinfo.grid.frowfonts.count) then begin + if checkfocusedcolor(aindex) then begin + result:= tfont(fcellinfo.grid.frowfonts.fitems[ffontfocusednum]); + end; + end; + if result = nil then begin + result:= actualfont; + end; + end; + end; +end; + +function tcol.getdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +function tcol.checkautocolwidth: boolean; +var + int1: integer; +begin + result:= false; + if (co1_autocolwidth in foptions1) and + not (gps_autosizevalid in fstate) and + not (csdesigning in fcellinfo.grid.componentstate) then begin + include(fstate,gps_autosizevalid); + int1:= width; + width:= maxwidth; + if width <> int1 then begin + result:= true; + end; + end; +end; + +procedure tcol.dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); +begin + fonbeforedrawcell(self,acanvas,fcellinfo,processed); +end; + +procedure tcol.doafterdrawcell(const acanvas: tcanvas); +begin + fonafterdrawcell(self,acanvas,fcellinfo); +end; + +function tcol.needsfocusrect: boolean; +begin + result:= co_drawfocus in foptions; +end; + +procedure tcol.paint(var info: colpaintinfoty); +var + int1,int2,int3: integer; + isgridcol,isfocusedcol,isfocusedcell: boolean; + bo1,bo2: boolean; + saveindex: integer; + linewidthbefore: integer; + font1: tfont; + canbeforedrawcell: boolean; + canafterdrawcell: boolean; + row1: integer; + hiddenlines: integerarty; + segments1: segmentarty; + po1: pdatacolaty; + nextcol: tdatacol; + widthextend,heightextend: integer; + checkmerge: boolean; + hasrowheight: boolean; + rowstatelist: trowstatelist; + endy: integer; + framedim1: sizety; +begin + if (not (co_invisible in foptions) or + (csdesigning in fcellinfo.grid.componentstate)) then begin + if not info.calcautocellsize and checkautocolwidth then begin + exit; + end; + checkmerge:= og_colmerged in fcellinfo.grid.foptionsgrid; + canbeforedrawcell:= fcellinfo.grid.canevent(tmethod(fonbeforedrawcell)); + canafterdrawcell:= fcellinfo.grid.canevent(tmethod(fonafterdrawcell)); + hiddenlines:= nil; + with info do begin + fcellinfo.calcautocellsize:= calcautocellsize; + framedim1:= framedim; + fcellinfo.autocellsize:= subsize(autocellsize,framedim1); + fcellinfo.grid.fbrushorigin.x:= fcellinfo.grid.frootbrushorigin.x; + if not (co_nohscroll in foptions) then begin + fcellinfo.grid.fbrushorigin.x:= + fcellinfo.grid.fbrushorigin.x + fcellinfo.grid.fscrollrect.x; + end; + fcellinfo.font:= nil; + isgridcol:= (fcellinfo.cell.col = fcellinfo.grid.ffocusedcell.col); + isfocusedcol:= isgridcol and (gs_cellentered in fcellinfo.grid.fstate); + canvas.drawinfopo:= @fcellinfo; + canvas.move(makepoint(fcellrect.x,fcellrect.y + ystart)); + fcellinfo.foldinfo:= nil; + nextcol:= nil; + po1:= nil; + if not (gps_fix in fstate) then begin + po1:= pointer(fcellinfo.grid.fdatacols.fitems); + if index <> fcellinfo.grid.datacols.lastvisiblecol then begin + nextcol:= po1^[index+1]; + end; + end; + clean(startrow,endrow); + hasrowheight:= og_rowheight in fcellinfo.grid.optionsgrid; + rowstatelist:= fcellinfo.grid.fdatacols.frowstate; + for int1:= startrow to endrow do begin + row1:= rows[int1]; + fcellinfo.cell.row:= row1; + fcellinfo.rowstate:= rowstatelist.getitempo(row1); + bo1:= false; + if checkmerge and (nextcol <> nil) and nextcol.merged[row1] then begin + bo1:= true; //has merged columns + additem(hiddenlines,row1); //by merged columns + end; + if not checkmerge or not merged[row1] then begin + isfocusedcell:= isfocusedcol and (row1 = fcellinfo.grid.ffocusedcell.row); + heightextend:= 0; + if hasrowheight then begin + with fcellinfo do begin + heightextend:= rowstatelist.internalheight(row1) - fcellinfo.grid.fdatarowheight;//rect.cy; + inc(fcellrect.cy,heightextend); + inc(rect.cy,heightextend); + inc(innerrect.cy,heightextend); + inc(frameinnerrect.cy,heightextend); + end; + end; + widthextend:= 0; + if bo1 then begin + for int2:= index + 1 to fcellinfo.grid.fdatacols.count - 1 do begin + with po1^[int2] do begin + if not (co_invisible in foptions) then begin + if merged[row1] then begin + inc(widthextend,step); + end + else begin + break; + end; + end; + end; + end; + with fcellinfo do begin + inc(fcellrect.cx,widthextend); + inc(rect.cx,widthextend); + inc(innerrect.cx,widthextend); + inc(frameinnerrect.cx,widthextend); + end; + end; + try + font1:= rowfont(row1); + if font1 <> fcellinfo.font then begin + fcellinfo.font:= font1; + canvas.font:= font1; + end; + if og_folded in fcellinfo.grid.foptionsgrid then begin + fcellinfo.foldinfo:= @foldinfo[int1]; + end; + fcellinfo.datapo:= getdatapo(row1); + fcellinfo.drawstate:= []; + if getselected(row1) then begin + include(fcellinfo.drawstate,cds_selected); + end; + if fcellinfo.grid.getrowreadonlystate(row1) then begin + include(fcellinfo.drawstate,cds_readonly); + end; + if isgridcol and (row1 = fcellinfo.grid.ffocusedcell.row) then begin + include(fcellinfo.drawstate,cds_focused); + end; + if isfocusedcell then begin + include(fcellinfo.drawstate,cds_active); + end; + if isfocusedcell or (co1_rowcoloractive in foptions1) and + (row1 = fcellinfo.grid.ffocusedcell.row) then begin + include(fcellinfo.drawstate,cds_usecoloractive); + end; + +// fcellinfo.notext:= false; + if (fcellinfo.grid.fmousecell.col = fcellinfo.cell.col) and + (fcellinfo.grid.fmousecell.row = row1) then begin + include(fcellinfo.drawstate,cds_ismousecell); + end; + saveindex:= canvas.save; + fcellinfo.color:= rowcolor(row1); + canvas.intersectcliprect(mr(nullpoint,fcellrect.size)); + bo2:= false; + if canbeforedrawcell then begin + dobeforedrawcell(canvas,bo2); + end; + if not bo2 then begin + if isfocusedcell then begin + drawfocusedcell(canvas); + if calcautocellsize then begin +// fcellinfo.focused:= false; + exclude(fcellinfo.drawstate,cds_active); + drawcell(canvas); //possibly bigger + end; + end + else begin + drawcell(canvas); + end; + end; + if canafterdrawcell then begin + doafterdrawcell(canvas); + end; + canvas.restore(saveindex); + if calcautocellsize then begin + continue; + end; + if not bo2 then begin + drawcelloverlay(canvas,fframe); + end; + if isfocusedcol and (row1 = fcellinfo.grid.ffocusedcell.row) and + needsfocusrect and + fcellinfo.grid.cellhasfocus and fcellinfo.grid.active then begin + if fframe <> nil then begin + canvas.move(fframe.fpaintrect.pos); + end; + drawfocus(canvas); + if fframe <> nil then begin + canvas.remove(fframe.fpaintrect.pos); + end; + end; + finally + if heightextend <> 0 then begin + with fcellinfo do begin //restore original values + dec(fcellrect.cy,heightextend); + dec(rect.cy,heightextend); + dec(innerrect.cy,heightextend); + dec(frameinnerrect.cy,heightextend); + end; + end; + if widthextend <> 0 then begin + with fcellinfo do begin //restore original values + dec(fcellrect.cx,widthextend); + dec(rect.cx,widthextend); + dec(innerrect.cx,widthextend); + dec(frameinnerrect.cx,widthextend); + end; + end; + end; + end; + if hasrowheight then begin + canvas.move(makepoint(0,rowstatelist.internalystep(row1))); + end + else begin + canvas.move(makepoint(0,ystep)); + end; + end; + if not calcautocellsize and (flinewidth > 0) then begin + linewidthbefore:= canvas.linewidth; + if flinewidth = 1 then begin + canvas.linewidth:= 0; + end + else begin + canvas.linewidth:= flinewidth; + end; + if hasrowheight then begin + endy:= rowstatelist.getrowypos(rows[endrow]+1) + end; + if hiddenlines = nil then begin + if hasrowheight then begin + int2:= endy - rowstatelist.getrowypos(rows[0]) + end + else begin + int2:= ystep * length(rows); + end; + canvas.drawline(makepoint(flinepos,-int2), + makepoint(flinepos,-1),flinecolor); + end + else begin + setlength(segments1,endrow-startrow+1); //max + int2:= 0; //index in hiddenlines + int3:= 0; //index in segments1 + bo1:= false; //line started + bo2:= false; //line stopped + for int1:= startrow to endrow do begin + if (int2 > high(hiddenlines)) or + (rows[int1] <> hiddenlines[int2]) then begin + if not bo1 then begin //start line + bo1:= true; + bo2:= false; + with segments1[int3] do begin + a.x:= flinepos; + b.x:= flinepos; + if hasrowheight then begin + a.y:= rowstatelist.getrowypos(rows[int1]) - endy; + end + else begin + a.y:= -ystep * (endrow-int1+1); + end; + end; + end; + end + else begin + if not bo2 and bo1 then begin //stop line + bo2:= true; + bo1:= false; + if hasrowheight then begin + segments1[int3].b.y:= rowstatelist.getrowypos(rows[int1]) - endy - 1; + end + else begin + segments1[int3].b.y:= -ystep * (endrow-int1+1)-1; + end; + inc(int3); + end; + inc(int2); + end; + end; + if bo1 and not bo2 then begin //finish last line + segments1[int3].b.y:= -1; + inc(int3); + end; + setlength(segments1,int3); + canvas.drawlinesegments(segments1,flinecolor); + end; + canvas.linewidth:= linewidthbefore; + end; + autocellsize:= addsize(fcellinfo.autocellsize,framedim1); + end; + end; +end; + +procedure tcol.rowcountchanged(const newcount: integer); +begin + //dummy +end; + +procedure tcol.updatepropwidth; +var + int1: integer; +begin + if not (csloading in fcellinfo.grid.componentstate) and + not (gs_updatelocked in fcellinfo.grid.fstate) then begin +// int1:= tgridframe(fgrid.fframe).fpaintrect.cx; + int1:= fcellinfo.grid.fpropcolwidthref; + if int1 <> 0 then begin + fpropwidth:= fwidth / int1; + end; + end; +end; + +procedure tcol.setwidth(const Value: integer); +begin + if fwidth <> value then begin + if value < 0 then begin + fwidth:= 0; + end + else begin + fwidth:= Value; + end; + updatewidth(fwidth); + updatepropwidth; + fcellinfo.grid.layoutchanged; + if (gps_needsrowheight in fstate) and + not (csloading in fcellinfo.grid.componentstate) then begin +// updatecellrect(fframe); + fcellinfo.grid.updatelayout; + fcellinfo.grid.datacols.rowstate.change(-1); + end; +// updatepropwidth; + end; +end; + +class function tcol.defaultstep(width: integer): integer; +begin + result:= width + defaultgridlinewidth; +end; + +function tcol.step(getscrollable: boolean = true): integer; +begin + result:= 0; + if (getscrollable xor (co_nohscroll in foptions)) and + (not (co_invisible in foptions) or + (csdesigning in fcellinfo.grid.ComponentState)) then begin + result:= fwidth + flinewidth; + end; +end; + +function tcol.scrollable: boolean; +begin + result:= not (co_nohscroll in foptions); +end; + +function tcol.getcolindex: integer; +begin + fcellinfo.grid.internalupdatelayout; + result:= fcellinfo.cell.col; +end; + +procedure tcol.drawfocusedcell(const acanvas: tcanvas); +begin + fcellinfo.grid.drawfocusedcell(acanvas); +end; + +function tcol.getselected(const row: integer): boolean; +begin + if row >= 0 then begin + result:= (gps_selected in fstate) or + (fcellinfo.grid.fdatacols.frowstate.getitempo(row)^.selected and + wholerowselectedmask <> 0); + end + else begin + result:= gps_selected in fstate; + end; +end; + +procedure tcol.invalidatelayout; +//var +// int1: integer; +begin + if not (csreading in fcellinfo.grid.componentstate) then begin + fcellinfo.grid.layoutchanged; + tcols(prop).resetpropwidth; + { + with tgridarrayprop(prop) do begin //grid propewidthref is invalid + for int1:= 0 to high(fitems) do begin + tcol(fitems[int1]).fpropwidth:= 0; + end; + end; + } + end; +end; + +procedure tcol.setoptions(const Value: coloptionsty); +var + valuebefore: coloptionsty; +begin + if foptions <> value then begin + valuebefore:= foptions; + foptions:= value - deprecatedcoloptions; + if csreading in fcellinfo.grid.componentstate then begin + transferdeprecatedcoloptions(value,foptions1); + end; + if bitschanged({$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(valuebefore), + {$ifdef FPC}longword{$else}longword{$endif}(layoutchangedcoloptions)) then begin + invalidatelayout; + end + else begin + changed; + end; + end; +end; + +procedure tcol.setoptions1(const avalue: coloptions1ty); +var + optionsbefore: coloptions1ty; + opt1: coloptions1ty; +begin +// avalue:= avalue - deprecatedcoloptions1; + optionsbefore:= foptions1; + foptions1:= avalue; + opt1:= coloptions1ty({$ifdef FPC}longword{$else}word{$endif}(optionsbefore) xor + {$ifdef FPC}longword{$else}word{$endif}(foptions1)); + if co1_autorowheight in opt1 then begin + if co1_autorowheight in foptions1 then begin + include(fstate,gps_needsrowheight); + end + else begin + exclude(fstate,gps_needsrowheight); + end; + fcellinfo.grid.checkneedsrowheight; + end; + if opt1 * layoutchangedcoloptions1 <> [] then begin + invalidatelayout; + invalidatemaxsize(); + end; +end; + + +procedure tcol.setfocusrectdist(const avalue: integer); +begin + if ffocusrectdist <> avalue then begin + ffocusrectdist:= avalue; + changed; + end; +end; + +procedure tcol.drawfocus(const acanvas: tcanvas); +begin + drawfocusrect(acanvas,inflaterect(makerect(nullpoint,fcellinfo.rect.size), + -ffocusrectdist)); +end; + +procedure tcol.updatelayout; +var + bo1: boolean; +begin + fcellrect.size.cy:= fcellinfo.grid.fdatarowheight; + fcellrect.size.cx:= fwidth; + fcellrect.y:= 0; + bo1:= fcellinfo.cell.col < 0; + if bo1 and (fcellinfo.cell.col <= tgridarrayprop(prop).ffirstopposite) or + not bo1 and + (fcellinfo.cell.col >= tgridarrayprop(prop).ffirstopposite) then begin + flinepos:= -((flinewidth+1) div 2); + fcellrect.x:= flinewidth; + end + else begin + flinepos:= fwidth + flinewidth div 2; + fcellrect.x:= 0; + end; + inherited; +end; + +procedure tcol.setrowcoloroffset(const avalue: integer); +begin + if frowcoloroffset <> avalue then begin + frowcoloroffset:= avalue; + invalidate; + end; +end; + +procedure tcol.setrowcoloroffsetselect(const avalue: integer); +begin + if frowcoloroffsetselect <> avalue then begin + frowcoloroffsetselect:= avalue; + invalidate; + end; +end; + +procedure tcol.setrowfontoffset(const avalue: integer); +begin + if frowfontoffset <> avalue then begin + frowfontoffset:= avalue; + invalidate; + end; +end; + +procedure tcol.setrowfontoffsetselect(const avalue: integer); +begin + if frowfontoffsetselect <> avalue then begin + frowfontoffsetselect:= avalue; + invalidate; + end; +end; +{ +function tcol.iswidthstored: boolean; +begin + result:= fwidth <> tcols(prop).fwidth; +end; +} +function tcol.getfontselect: tcolselectfont; +begin + getoptionalobject(fcellinfo.grid.componentstate,ffontselect, + {$ifdef FPC}@{$endif}createfontselect); + if ffontselect <> nil then begin + result:= ffontselect; + end + else begin + result:= tcolselectfont(pointer(getfont)); + end; +end; + +procedure tcol.setfontselect(const Value: tcolselectfont); +begin + if value <> ffontselect then begin + setoptionalobject(fcellinfo.grid.ComponentState,value,ffontselect, + {$ifdef FPC}@{$endif}createfontselect); + changed; + end; +end; + +function tcol.isfontselectstored: Boolean; +begin + result:= ffontselect <> nil; +end; + +procedure tcol.setfontactivenum(const avalue: integer); +begin + if ffontactivenum <> avalue then begin + ffontactivenum:= avalue; + invalidate; + end; +end; + +procedure tcol.setfontfocusednum(const avalue: integer); +begin + if ffontfocusednum <> avalue then begin + ffontfocusednum:= avalue; + invalidate; + end; +end; + +procedure tcol.createfontselect; +begin + if ffontselect = nil then begin + ffontselect:= tcolselectfont.create; + ffontselect.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function tcol.translatetocell(const arow: integer; + const apos: pointty): pointty; +begin + result:= subpoint(apos, + fcellinfo.grid.cellrect(makegridcoord(colindex,arow)).pos); +end; + +function tcol.getmerged(const row: integer): boolean; +begin + result:= false; +end; + +procedure tcol.setmerged(const row: integer; const avalue: boolean); +begin + //dummy +end; + +procedure tcol.clean(const start,stop: integer); +begin + //dummy +end; + +procedure tcol.updatewidth(var avalue: integer); +begin + //dummy +end; + +function tcol.getvisible: boolean; +begin + result:= not (co_invisible in options); +end; + +procedure tcol.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [co_invisible]; + end + else begin + options:= options + [co_invisible]; + end; +end; + +function tcol.getenabled: boolean; +begin + result:= not (co_disabled in options); +end; + +procedure tcol.setenabled(const avalue: boolean); +begin + if avalue then begin + options:= options - [co_disabled]; + end + else begin + options:= options + [co_disabled]; + end; +end; + +function tcol.getreadonly: boolean; +begin + result:= co_readonly in options; +end; + +procedure tcol.setreadonly(const avalue: boolean); +begin + if avalue then begin + options:= options + [co_readonly]; + end + else begin + options:= options - [co_readonly]; + end; +end; + +procedure tcol.updatecolwidth(const arow,acount: integer; + var acolwidth: integer); +var + i1,i2: integer; + info: colpaintinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + calcautocellsize:= true; + autocellsize.cx:= acolwidth; + autocellsize.cy:= fcellinfo.grid.datarowheight; + canvas:= fcellinfo.grid.getcanvas; + allocuninitedarray(acount,sizeof(rows[0]),rows); //including invisible rows + i2:= arow; + startrow:= arow; + endrow:= arow + acount - 1; + for i1:= arow to endrow do begin + rows[i1]:= i2; + inc(i2); + end; + paint(info); + acolwidth:= autocellsize.cx; + end; + if (index >= 0) and (co1_autoheaderwidth in foptions1) then begin + for i1:= 0 to grid.ffixrows.count - 1 do begin + with tfixrow(grid.ffixrows.fitems[i1]) do begin + if fcaptions.count > self.index then begin + with tdatacolheader(fcaptions[self.index]) do begin + if not (dco_noautowidth in options) then begin + updateautocellsize(); + if acolwidth < fautocellsize.cx then begin + acolwidth:= fautocellsize.cx; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tcol.checkmaxwidth; +begin + if not (gps_maxsizevalid in fstate) then begin + include(fstate,gps_maxsizevalid); + fmaxwidth:= 0; + updatecolwidth(0,fcellinfo.grid.rowcount,fmaxwidth); + end; +end; + +function tcol.maxwidth: integer; +begin + checkmaxwidth; + result:= fmaxwidth; +end; + +function tcol.minmaxwidth(): integer; +begin + if fmaxwidth > fwidthmin then begin + result:= fmaxwidth; + end + else begin + result:= fwidthmin; + end; +end; + +procedure tcol.invalidatemaxsize(const arow: integer = -1); +begin + fstate:= fstate - [gps_maxsizevalid,gps_autosizevalid]; +end; + +{ tcolheaderfont } + +class function tcolheaderfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcolheader(owner).ffont; +end; + +{ tcolheader } + +constructor tcolheader.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + initcaptioninfo(finfo); + with finfo do begin + imagenr:= -1; + colorglyph:= cl_glyph; + imagepos:= ip_center; + end; +// finfo.textflags:= defaultcolheadertextflags; + fcolor:= cl_parent; + inherited; + fgrid:= tcolheaders(fowner).fgridprop.fcellinfo.grid; +end; + +destructor tcolheader.destroy; +begin + inherited; + ffont.free; + fframe.free; + fface.free; +end; + +procedure tcolheader.readcaptionpos(reader: treader); +begin + imagepos:= readcaptiontoimagepos(reader); +end; + +procedure tcolheader.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('captionpos',{$ifdef FPC}@{$endif}readcaptionpos,nil,false); +end; + +procedure tcolheader.changed; +begin + tcolheaders(fowner).dochange(findex); +end; + +function tcolheader.getfont: tcolheaderfont; +begin + getoptionalobject(fgrid.componentstate,ffont,{$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= tcolheaderfont(pointer(tcolheaders(fowner).fgridprop.getfont)); + end; +end; + +procedure tcolheader.setfont(const Value: tcolheaderfont); +begin + if value <> ffont then begin + setoptionalobject(tcolheaders(fowner).fgridprop.fcellinfo.grid.ComponentState, + value,ffont,{$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function tcolheader.isfontstored: Boolean; +begin + result:= ffont <> nil; +end; + +procedure tcolheader.createfont; +begin + if ffont = nil then begin + ffont:= tcolheaderfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +procedure tcolheader.fontchanged(const sender: tobject); +begin + changed; +end; + +procedure tcolheader.drawcell(const acanvas: tcanvas; const adest: rectty); +var + si1: sizety; +begin + with finfo do begin + font:= getfont; + dim:= adest; + with cellinfoty(acanvas.drawinfopo^) do begin + if calcautocellsize then begin + si1:= calccaptionsize(acanvas,finfo); + fautocellsize:= rect.size; + fautocellsize.cx:= fautocellsize.cx + si1.cx - adest.cx - fmergedcx; + fautocellsize.cy:= fautocellsize.cy + si1.cy - adest.cy - fmergedcy; + end + else begin + drawcaption(acanvas,finfo); + end; + end; + end; +end; + + //iframe +function tcolheader.getwidget: twidget; +begin + result:= fgrid; +end; + +function tcolheader.getclientrect: rectty; +begin + result:= fgrid.clientrect; +end; + +procedure tcolheader.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + fgrid.setlinkedvar(source,dest,linkintf); +end; + +procedure tcolheader.widgetregioninvalid; +begin + fgrid.widgetregioninvalid; +end; + +procedure tcolheader.setframeinstance(instance: tcustomframe); +begin + fframe:= tfixcellframe(instance); +end; + +function tcolheader.getwidgetrect: rectty; +begin + result:= nullrect; +// result:= fcellrect; +end; + +procedure tcolheader.setstaticframe(value: boolean); +begin +// twidget1(getwidget).setstaticframe(value); +end; + +function tcolheader.getstaticframe: boolean; +begin + result:= false; +end; + +function tcolheader.widgetstate: widgetstatesty; +begin + result:= twidget1(getwidget).widgetstate; +end; + +procedure tcolheader.scrollwidgets(const dist: pointty); +begin +// twidget1(getwidget).scrollwidgets(dist); +end; + +procedure tcolheader.clientrectchanged; +begin + changed; +// fgrid.layoutchanged; +end; + +function tcolheader.getcomponentstate: tcomponentstate; +begin + result:= getwidget.componentstate; +end; + +function tcolheader.getmsecomponentstate: msecomponentstatesty; +begin + result:= getwidget.msecomponentstate; +end; + +procedure tcolheader.invalidate; +begin + changed; +// getwidget.invalidate; +end; + +procedure tcolheader.invalidatewidget; +begin + changed; +// getwidget.invalidatewidget; +end; + +procedure tcolheader.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + changed; +// getwidget.invalidaterect(rect,org); +end; + +//iface +function tcolheader.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; +end; + +procedure tcolheader.setcaption(const avalue: msestring); +begin + finfo.caption.text:= avalue; + changed; +end; + +procedure tcolheader.settextflags(const avalue: textflagsty); +begin + if finfo.textflags <> avalue then begin + finfo.textflags:= checktextflags(finfo.textflags,avalue); + changed; + end; +end; + +function tcolheader.getframe: tfixcellframe; +begin + fgrid.getoptionalobject(fframe,{$ifdef FPC}@{$endif}createframe); + result:= fframe; +end; + +procedure tcolheader.setframe(const avalue: tfixcellframe); +begin + fgrid.setoptionalobject(avalue,fframe,{$ifdef FPC}@{$endif}createframe); + clientrectchanged; +end; + +function tcolheader.getface: tfixcellface; +begin + fgrid.getoptionalobject(fface,{$ifdef FPC}@{$endif}createface); + result:= fface; +end; + +procedure tcolheader.setface(const avalue: tfixcellface); +begin + fgrid.setoptionalobject(avalue,fface,{$ifdef FPC}@{$endif}createface); + fgrid.invalidate; +end; + +procedure tcolheader.createframe(); +begin + if fframe = nil then begin + tfixcellframe.create(iframe(self)); + end; +end; + +procedure tcolheader.createface(); +begin + if fface = nil then begin + fface:= tfixcellface.create(iface(self)); + end; +end; + +procedure tcolheader.setcolor(const avalue: colorty); +begin + if fcolor <> avalue then begin + fcolor:= avalue; + changed; + end; +end; + +procedure tcolheader.setmergecols(const avalue: integer); +begin + if fmergecols <> avalue then begin + fmergecols:= avalue; + fgrid.layoutchanged; + if fgrid.componentstate * [csloading,csdesigning,csdestroying] = + [csdesigning] then begin + fgrid.updatelayout; //check colheaders.count + end; + end; +end; + +procedure tcolheader.setmergerows(const avalue: integer); +begin + if fmergerows <> avalue then begin + fmergerows:= avalue; + fgrid.layoutchanged; + if fgrid.componentstate * [csloading,csdesigning,csdestroying] = + [csdesigning] then begin + fgrid.updatelayout; //check colheaders.count + end; + end; +end; + +function tcolheader.getframestateflags: framestateflagsty; +begin + result:= []; +end; + +procedure tcolheader.setimagenr(const avalue: imagenrty); +begin + if finfo.imagenr <> avalue then begin + finfo.imagenr:= avalue; + changed; + end; +end; + +procedure tcolheader.setcolorglyph(const avalue: colorty); +begin + if finfo.colorglyph <> avalue then begin + finfo.colorglyph:= avalue; + changed; + end; +end; + +procedure tcolheader.setimagepos(const avalue: imageposty); +begin + if finfo.imagepos <> avalue then begin + finfo.imagepos:= simpleimagepos[avalue]; + changed; + end; +end; + +procedure tcolheader.setimagedist(const avalue: integer); +begin + if finfo.imagedist <> avalue then begin + finfo.imagedist:= avalue; + changed; + end; +end; + +procedure tcolheader.setcaptiondist(const avalue: integer); +begin + if finfo.captiondist <> avalue then begin + finfo.captiondist:= avalue; + changed; + end; +end; + +function tcolheader.getimagelist: timagelist; +begin + result:= finfo.imagelist; +end; + +procedure tcolheader.setimagelist(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(finfo.imagelist)); + changed; +end; + +{ tdatacolheader } + +constructor tdatacolheader.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + foptions:= [dco_hintclippedtext]; + inherited; +end; + +procedure tdatacolheader.setoptions(const avalue: datacolheaderoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + changed(); + end; +end; + +procedure tdatacolheader.drawcell(const acanvas: tcanvas; const adest: rectty); +var + rect1: rectty; + al1: alignmentsty; + int1,int2: integer; +begin + if (dco_colsort in foptions) and (index < fgrid.datacols.count) then begin + rect1:= adest; + al1:= [al_right,al_ycentered]; + with tdatacol(fgrid.fdatacols.fitems[index]) do begin + if co_sortdescend in options then begin + int1:= ord(stg_arrowupsmall); + end + else begin + int1:= ord(stg_arrowdownsmall); + end; + if not (fgrid.hassort) or + (co_nosort in options) or + (fgrid.datacols.sortcol >= 0) and (fgrid.datacols.sortcol <> index) or + (fgrid.datacols.sortcol < 0) and + (og_nodefaultsort in fgrid.foptionsgrid) then begin + if dco_nodisabledsortindicator in self.foptions then begin + int1:= -1; + end; + include(al1,al_grayed); + end; + end; + int2:= (15-sortglyphwidth) div 2; + inc(rect1.cx,int2); + if not cellinfoty(acanvas.drawinfopo^).calcautocellsize then begin + stockobjects.glyphs.paint(acanvas,int1,rect1,al1,finfo.colorglyph); + end; + int2:= sortglyphwidth+int2; + if int1 >= 0 then begin + with rect1 do begin + acanvas.subcliprect(mr(x+cx-int2,y,int2,cy)); + end; + end; + dec(rect1.cx,int2); + inherited drawcell(acanvas,rect1); + end + else begin + inherited; + end; +end; + +{ tcolheaders } + +constructor tcolheaders.create(const agridprop: tgridprop); +begin + fgridprop:= agridprop; + inherited create(self,indexpersistentclassty(getitemclasstype)); +end; + +procedure tcolheaders.movecol(const curindex,newindex: integer); +var + int1: integer; +begin + if (curindex <= high(fitems)) or (newindex <= high(fitems)) then begin + int1:= curindex; + if newindex > high(fitems) then begin + count:= newindex + 1; + end; + if curindex > high(fitems) then begin + count:= high(fitems) + 2; + int1:= high(fitems); + end; + move(int1,newindex); + end; +end; + +procedure tcolheaders.colcountchanged(const acount: integer); +begin + //dummy +end; + +procedure tcolheaders.updatelayout(const cols: tgridarrayprop); +var + int1,int2,int3,int4: integer; + headers1: tcolheaders; + header1: tcolheader; + lastmergedcol: integer; + lastmergedrow: integer; + bo1: boolean; + cell1: gridcoordty; + mergedcxbefore: int32; +begin + int2:= count; + for int1:= 0 to count - 1 do begin + with tcolheader(fitems[int1]) do begin //extend count for mergecols + fmergeflags:= []; + int3:= int1 + fmergecols; + if int3 >= int2 then begin + int2:= int3 + 1; + end; + end; + end; + if int2 > count then begin + count:= int2; + end; + cell1.row:= -fgridprop.index - 1; + for int1:= 0 to count -1 do begin + if ffixcol then begin + cell1.col:= -int1-1; + end + else begin + cell1.col:= int1; + end; + with tcolheader(fitems[int1]) do begin + mergedcxbefore:= fmergedcx; + lastmergedcol:= int1 + fmergecols; + if lastmergedcol >= count then begin + lastmergedcol:= count - 1; + end; + if lastmergedcol >= cols.count then begin + lastmergedcol:= cols.count - 1; + end; + if int1 < lastmergedcol then begin + fmergedcx:= tgridprop(cols.fitems[int1]).flinewidth - + tgridprop(cols.fitems[lastmergedcol]).flinewidth; + if cols.freversedorder then begin + fmergedx:= -fmergedcx; + end + else begin + fmergedx:= 0; + end; + bo1:= tgridprop(cols.fitems[int1]).scrollable; + for int2:= int1 + 1 to lastmergedcol do begin + with tcolheader(fitems[int2]) do begin + include(fmergeflags,cmf_h); + frefcell:= cell1; + end; + int4:= tgridprop(cols.fitems[int2]).step(bo1); + inc(fmergedcx,int4); + if cols.freversedorder then begin + dec(fmergedx,int4); + end; + end; + end + else begin + fmergedcx:= 0; + fmergedx:= 0; + end; + if not ffixcol and (mergedcxbefore <> fmergedcx) and + not (dco_noautowidth in tdatacolheader(fitems[int1]).options) and + (int1 < cols.count) and + (co1_autoheaderwidth in tcol(cols.fitems[int1]).options1) then begin + tfixrow(fgridprop).invalidatemaxsize(int1); + end; + + lastmergedrow:= fgridprop.index + fmergerows; + if lastmergedrow >= fgrid.fixrows.count then begin + lastmergedrow:= fgrid.fixrows.count-1; + end; + if fgridprop.index < lastmergedrow then begin + fmergedcy:= fgridprop.flinewidth - + tfixrow(fgrid.ffixrows.fitems[lastmergedrow]).flinewidth; + fmergedy:= -fmergedcy; + if lastmergedcol < int1 then begin + lastmergedcol:= int1; + end; + bo1:= fgridprop.index >= fgrid.ffixrows.count - + fgrid.ffixrows.foppositecount; + for int2:= fgridprop.index + 1 to lastmergedrow do begin + with tfixrow(fgrid.ffixrows.fitems[int2]) do begin + int4:= step; + inc(fmergedcy,int4); + dec(fmergedy,int4); + if ffixcol then begin + headers1:= fcaptionsfix; + end + else begin + headers1:= fcaptions; + end; + end; + if headers1.count <= lastmergedcol then begin + headers1.count:= lastmergedcol + 1; + end; + header1:= tcolheader(headers1.fitems[int1]); + include(header1.fmergeflags,cmf_v); + header1.frefcell:= cell1; + if not bo1 then begin + include(header1.fmergeflags,cmf_rline); + end; + for int3:= int1 + 1 to lastmergedcol do begin + with tcolheader(headers1.fitems[int3]) do begin + if not bo1 then begin + fmergeflags:= fmergeflags + [cmf_v,cmf_h,cmf_rline]; + end + else begin + fmergeflags:= fmergeflags + [cmf_v,cmf_h]; + end; + frefcell:= cell1; + end; + end; + end; + if bo1 then begin + for int2:= fgridprop.index to lastmergedrow - 1 do begin + with tfixrow(fgrid.ffixrows.fitems[int2]) do begin + if ffixcol then begin + headers1:= fcaptionsfix; + end + else begin + headers1:= fcaptions; + end; + end; + header1:= tcolheader(headers1.fitems[int1]); + include(header1.fmergeflags,cmf_rline); + for int3:= int1 + 1 to lastmergedcol do begin + with tcolheader(headers1.fitems[int3]) do begin + include(fmergeflags,cmf_rline); + end; + end; + end; + end; + end + else begin + fmergedcy:= 0; + fmergedy:= 0; + end; + end; + end; + fmergeflags:= []; + for int1:= 0 to count - 1 do begin + fmergeflags:= fmergeflags + tcolheader(fitems[int1]).fmergeflags; + end; +end; + +procedure tcolheaders.dosizechanged; +begin + inherited; + fgridprop.fcellinfo.grid.layoutchanged; +end; + +{ tfixcolheaders } + +constructor tfixcolheaders.create(const agridprop: tgridprop); +begin + ffixcol:= true; + inherited; +end; + +class function tfixcolheaders.getitemclasstype: persistentclassty; +begin + result:= tcolheader; +end; + +function tfixcolheaders.getitems(const index: integer): tcolheader; +begin + result:= tcolheader(inherited getitems(-index-1)); +end; + +procedure tfixcolheaders.setitems(const index: integer; + const Value: tcolheader); +begin + inherited getitems(-index-1).Assign(value); +end; + +{ tdatacolheaders } + +class function tdatacolheaders.getitemclasstype: persistentclassty; +begin + result:= tdatacolheader; +end; + +function tdatacolheaders.getitems(const index: integer): tdatacolheader; +begin + result:= tdatacolheader(inherited getitems(index)); +end; + +procedure tdatacolheaders.setitems(const index: integer; + const Value: tdatacolheader); +begin + inherited getitems(index).Assign(value); +end; + +{ tfixrow } + +constructor tfixrow.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + ftextinfo.flags:= defaultfixcoltextflags; + fcaptions:= tdatacolheaders.create(self); + fcaptions.onchange:= {$ifdef FPC}@{$endif}captionchanged; + fcaptionsfix:= tfixcolheaders.create(self); + fcaptionsfix.onchange:= {$ifdef FPC}@{$endif}captionchanged; +// fhints:= tmsestringarrayprop.create; + inherited create(agrid,aowner); + fheight:= agrid.fdatarowheight; +end; + +destructor tfixrow.destroy; +begin + inherited; + fcaptions.free; + fcaptionsfix.free; +end; + +procedure tfixrow.movecol(const curindex,newindex: integer; const aisfix: boolean); +begin + if aisfix then begin + fcaptionsfix.movecol(curindex,newindex); + end + else begin + fcaptions.movecol(curindex,newindex); + end; +end; + +procedure tfixrow.datacolscountchanged(const acount: integer); +begin + fcaptions.colcountchanged(acount); +end; + +procedure tfixrow.fixcolscountchanged(const acount: integer); +begin + fcaptionsfix.colcountchanged(acount); +end; + + +procedure tfixrow.reorderdatacols(const neworder: integerarty); +begin + if fcaptions.count > 0 then begin + fcaptions.count:= length(neworder); + fcaptions.reorder(neworder); + end; +end; + +procedure tfixrow.orderdatacols(const oldorder: integerarty); +begin + if fcaptions.count > 0 then begin + fcaptions.count:= length(oldorder); + fcaptions.order(oldorder); + end; +end; + +procedure tfixrow.synctofontheight; +begin + if fframe <> nil then begin + fframe.checkstate; + height:= {height + }font.glyphheight + fframe.finnerframe.top + + fframe.finnerframe.bottom; + end + else begin + with tgridarrayprop(prop).finnerframe do begin + height:= font.glyphheight + top + bottom; + end; + end; +end; + +function tfixrow.getrowindex: integer; +begin + fcellinfo.grid.internalupdatelayout; + result:= fcellinfo.cell.row; +end; + +procedure tfixrow.setheight(const Value: integer); +begin + if fheight <> value then begin + if value < 1 then begin + fheight:= 1; + end + else begin + fheight := Value; + end; + fcellinfo.grid.layoutchanged; + end; +end; + +procedure tfixrow.drawcell(const canvas: tcanvas); +var + int1,linewidthbefore: integer; + frame1: tcustomframe; + face1: tcustomface; + headers1: tcolheaders; + pt1: pointty; + sizebefore: sizety; + linemerged: boolean; + +label + endlab,endlab2; +begin + with cellinfoty(canvas.drawinfopo^) do begin + if cell.col >= 0 then begin + int1:= cell.col; + headers1:= fcaptions; + end + else begin + headers1:= fcaptionsfix; + int1:= -cell.col-1; + end; + + frame1:= fframe; + face1:= fface; + pt1:= nullpoint; + sizebefore:= fcellrect.size; + linemerged:= false; + if (int1 >= 0) and (int1 < headers1.count) then begin + with tcolheader(headers1.fitems[int1]) do begin + linemerged:= cmf_rline in fmergeflags; + if fmergeflags * [cmf_v,cmf_h] <> [] then begin + goto endlab; + end; + if fcolor <> cl_parent then begin + fcellinfo.color:= fcolor; + end; + inc(fcellrect.cx,fmergedcx); + inc(fcellrect.cy,fmergedcy); + pt1.x:= fmergedx; + pt1.y:= fmergedy; + if fframe <> nil then begin + frame1:= fframe; + tframe1(frame1).checkstate; + end; + if fface <> nil then begin + face1:= fface; + end; + end; + end; + canvas.move(pt1); + updatecellrect(frame1); + ftextinfo.dest:= fcellinfo.innerrect; + ftextinfo.clip:= fcellinfo.rect; + canvas.save; + canvas.intersectcliprect(makerect(nullpoint,fcellrect.size)); + if not calcautocellsize then begin + drawcellbackground(canvas,frame1,face1); + end; + if (int1 >= 0) and (int1 < headers1.count) then begin + tcolheader(headers1.fitems[int1]).drawcell(canvas,ftextinfo.dest); + end + else begin + if (fnumstep <> 0) and (cell.col >= 0) then begin + ftextinfo.text.text:= inttostrmse(fnumstart+fnumstep*cell.col); + if calcautocellsize then begin + textrect(canvas,ftextinfo); + end + else begin + drawtext(canvas,ftextinfo); + end; + end; + end; + canvas.restore; + if calcautocellsize then begin + goto endlab2; + end; + drawcelloverlay(canvas,frame1); + canvas.remove(makepoint(0,pt1.y)); +endlab: + if (flinewidth > 0) and not linemerged then begin + linewidthbefore:= canvas.linewidth; + if flinewidth = 1 then begin + canvas.linewidth:= 0; + end + else begin + canvas.linewidth:= flinewidth; + end; + canvas.drawline(makepoint(fcellrect.x,flinepos), + makepoint(fcellrect.x+fcellrect.cx{-1},flinepos),colorline); + canvas.linewidth:= linewidthbefore; + end; + canvas.remove(makepoint(pt1.x,0)); +endlab2: + fcellrect.size:= sizebefore; + end; +end; + +procedure tfixrow.paint(const info: rowpaintinfoty); +var + pt1,pt2: pointty; + +var + linewidthbefore: integer; + color1: colorty; + canbeforedrawcell,canafterdrawcell: boolean; + + procedure paintcols(const range: rangety); + var + int1,int2,int3: integer; + bo1,bo2: boolean; + headers1: tcolheaders; + begin + with info do begin + if fix then begin + headers1:= fcaptionsfix; + end + else begin + headers1:= fcaptions; + end; + int2:= range.startindex; + if range.startindex < headers1.count then begin + for int3:= range.startindex downto 0 do begin + int2:= int3; + if not (cmf_h in tcolheader(headers1.fitems[int3]).fmergeflags) then begin + break; + end; + end; + end; + for int1:= int2 to range.endindex do begin + with tcol(cols.fitems[int1]) do begin + bo1:= (colrange.scrollables xor (co_nohscroll in foptions)) and + (not (co_invisible in foptions) or + (csdesigning in fcellinfo.grid.componentstate)); + if bo1 then begin + self.fcellrect.cx:= fwidth; + self.fcellinfo.cell.col:= fcellinfo.cell.col; + pt2.x:= pt1.x + fstart + fcellrect.x; + end; + end; + if bo1 then begin + fcellinfo.color:= color1; + if fix then begin + fcellinfo.cell.col:= -int1-1; + end + else begin + fcellinfo.cell.col:= int1; + if (fcolorselect <> cl_none) and + (gps_selected in fcellinfo.grid.fdatacols[int1].fstate) then begin + if fcolorselect <> cl_default then begin + fcellinfo.color:= fcolorselect; + end + else begin + fcellinfo.color:= defaultselectedcellcolor; + end; + end; + end; + canvas.origin:= pt2; + bo2:= false; + if canbeforedrawcell then begin + fonbeforedrawcell(self,canvas,fcellinfo,bo2); + end; + if not bo2 then begin + drawcell(canvas); + end; + if canafterdrawcell then begin + fonafterdrawcell(self,canvas,fcellinfo); + end; + end; + end; + end; + end; + +begin + if (not (co_invisible in foptions) or info.calcautocellsize) or + (csdesigning in fcellinfo.grid.ComponentState) then begin + with info do begin + fcellinfo.calcautocellsize:= calcautocellsize; + if ffont = nil then begin + ftextinfo.font:= fcellinfo.grid.getfont; + end + else begin + ftextinfo.font:= ffont; + end; + canvas.drawinfopo:= @fcellinfo; + if fcolor <> cl_default then begin + color1:= fcolor; + end + else begin + color1:= fcellinfo.grid.actualopaquecolor; + end; + pt1:= canvas.origin; + linewidthbefore:= canvas.linewidth; + if fix then begin + fcellinfo.colorline:= flinecolorfix; + end + else begin + fcellinfo.colorline:= flinecolor; + end; + pt2.y:= pt1.y+fcellrect.y; + canbeforedrawcell:= fcellinfo.grid.canevent(tmethod(fonbeforedrawcell)); + canafterdrawcell:= fcellinfo.grid.canevent(tmethod(fonafterdrawcell)); + paintcols(colrange.range2); + paintcols(colrange.range1); + canvas.linewidth:= linewidthbefore; //??? + canvas.origin:= pt1; + end; + end; +end; + +procedure tfixrow.updateautocellsize(); +var + info: rowpaintinfoty; +begin + if not (gps_autosizevalid in fstate) then begin + include(fstate,gps_autosizevalid); + info.calcautocellsize:= true; + info.canvas:= fcellinfo.grid.getcanvas; + info.cols:= fcellinfo.grid.fdatacols; + info.fix:= false; + info.colrange.range1.startindex:= 0; + info.colrange.range1.endindex:= info.cols.count-1; + info.colrange.range2.startindex:= 0; + info.colrange.range2.endindex:= -1; + info.colrange.scrollables:= false; + paint(info); + info.colrange.scrollables:= true; + paint(info); + end; +end; + +function tfixrow.step(getscrollable: boolean = true): integer; +begin + if (not (co_invisible in foptions) or + (csdesigning in fcellinfo.grid.ComponentState)) then begin + result:= fheight+flinewidth; + end + else begin + result:= 0; + end; +end; + +procedure tfixrow.updatelayout; +begin + fcellrect.size.cy:= fheight; + if fcellinfo.cell.row <= tgridarrayprop(prop).ffirstopposite then begin + flinepos:= -((flinewidth+1) div 2); + fcellrect.y:= flinewidth; +// fcellrect.y:= 0; + end + else begin + flinepos:= fheight + flinewidth div 2; + fcellrect.y:= 0; + end; + inherited; +end; + +procedure tfixrow.updatemergedcells; +begin + fcaptionsfix.updatelayout(fcellinfo.grid.ffixcols); + fcaptions.updatelayout(fcellinfo.grid.fdatacols); +end; + +procedure tfixrow.changed; +begin + inherited; + exclude(fstate,gps_autosizevalid); + if fcellinfo.grid.caninvalidate then begin + fcellinfo.grid.invalidaterect( + fcellinfo.grid.cellrect(makegridcoord(invalidaxis,getrowindex))); + end; +end; + +procedure tfixrow.setcaptions(const Value: tdatacolheaders); +begin + fcaptions.assign(Value); +end; + +procedure tfixrow.setcaptionsfix(const Value: tfixcolheaders); +begin + fcaptionsfix.assign(Value); +end; + +procedure tfixrow.setnumstart(const Value: integer); +begin + if fnumstep <> value then begin + fnumstart := Value; + changed; + end; +end; + +procedure tfixrow.setnumstep(const Value: integer); +begin + if fnumstep <> value then begin + fnumstep := Value; + changed; + end; +end; + +procedure tfixrow.settextflags(const Value: textflagsty); +var + int1: integer; +begin + if ftextinfo.flags <> value then begin + ftextinfo.flags := Value; + if not (csloading in fcellinfo.grid.componentstate) then begin + for int1:= 0 to fcaptions.count - 1 do begin + fcaptions[int1].textflags:= value; + end; + end; + end; +end; + +procedure tfixrow.captionchanged(const sender: tarrayprop; + const aindex: integer); +begin + if aindex < 0 then begin + changed; + end + else begin + if sender = fcaptionsfix then begin + cellchanged(aindex-fcaptionsfix.count); + end + else begin + cellchanged(aindex); + end; + end; +end; + +procedure tfixrow.invalidatemaxsize(const acol: int32); +begin + if acol >= 0 then begin + fstate:= fstate - [gps_autosizevalid,gps_maxsizevalid]; + if (acol < fcaptions.count) and (acol < grid.fdatacols.count){ and + (dco_autowidth in tdatacolheader(fcaptions.fitems[acol]).options)} then begin + with tdatacol(grid.fdatacols.fitems[acol]) do begin + invalidatemaxsize(); + end; + end; + end; +end; + +procedure tfixrow.cellchanged(const acol: integer); +begin + if not (csloading in fcellinfo.grid.componentstate) then begin + invalidatemaxsize(acol); + fcellinfo.grid.invalidatecell(makegridcoord(acol,getrowindex)); + end; +end; + +procedure tfixrow.setoptionsfix(const avalue: fixrowoptionsty); +begin + foptionsfix:= avalue; + if (fro_invisible in avalue) xor (co_invisible in foptions) then begin + if fro_invisible in avalue then begin + foptions:= foptions + [co_invisible]; + end + else begin + foptions:= foptions - [co_invisible]; + end; + fcellinfo.grid.layoutchanged; + end; +end; + +function tfixrow.getvisible: boolean; +begin + result:= not (fro_invisible in options); +end; + +procedure tfixrow.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [fro_invisible]; + end + else begin + options:= options + [fro_invisible]; + end; +end; + +procedure tfixrow.buttoncellevent(var info: celleventinfoty); +var + opt1: datacolheaderoptionsty; +begin + if (info.cell.col >= 0) and (info.cell.col < fcaptions.count) then begin + opt1:= fcaptions[info.cell.col].options; + if (dco_colsort in opt1) and + iscellclick(info,[ccr_nokeyreturn]{,[ss_ctrl]}) then begin + with fcellinfo.grid.datacols[info.cell.col] do begin + if ((opt1 * [dco_wholecellsortclick,dco_nodisabledsortindicator] <> []) and + (info.mouseeventinfopo^.pos.x > 0) or + (info.mouseeventinfopo^.pos.x > fwidth - 15)) and + //button click of merged cells not supported + not (co_nosort in foptions) then begin + if (fcellinfo.grid.datacols.sortcol = info.cell.col) and + fcellinfo.grid.hassort then begin + if ss_ctrl in info.mouseeventinfopo^.shiftstate then begin + if fcellinfo.grid.datacols.sortcoldefault >= 0 then begin + fcellinfo.grid.datacols.sortcol:= + fcellinfo.grid.datacols.sortcoldefault; + end + else begin + fcellinfo.grid.sorted:= false; + fcellinfo.grid.fdatacols.fsortcol:= -1; + end; + end + else begin + if co_sortdescend in foptions then begin + options:= foptions - [co_sortdescend]; + end + else begin + options:= foptions + [co_sortdescend]; + end; + fcellinfo.grid.datacols.sortcol:= fcellinfo.grid.datacols.sortcol; + //call updatesortcol + end; + end + else begin + fcellinfo.grid.datacols.sortcol:= info.cell.col; + if fcellinfo.grid.datacols.sortcol = info.cell.col then begin + fcellinfo.grid.sorted:= true; + end; + end; + end; + end; + end; + end; +end; + +{ tgridarrayprop } + +constructor tgridarrayprop.create(aowner: tcustomgrid; + aclasstype: gridpropclassty); +begin + ffirstopposite:= -bigint; + fgrid:= aowner; + flinewidth:= defaultgridlinewidth; + flinecolorfix:= defaultfixlinecolor; + fcolor:= cl_default; + fcolorselect:= cl_default; + fcoloractive:= cl_none; + fcolorfocused:= cl_none; + fcursor:= cr_default; + finnerframe:= minimalframe; + inherited create(self,aclasstype); +end; + +procedure tgridarrayprop.setcursor(const avalue: cursorshapety); +var + int1: integer; +begin + if fcursor <> avalue then begin + fcursor := avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).cursor:= avalue; + end; + end; + end; +end; + +procedure tgridarrayprop.setlinewidth(const Value: integer); +var + int1: integer; +begin + if flinewidth <> value then begin + flinewidth := Value; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).linewidth:= value; + end; + end; + end; +end; + +procedure tgridarrayprop.setlinecolor(const Value: colorty); +var + int1: integer; +begin + if flinecolor <> value then begin + flinecolor := Value; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).linecolor:= value; + end; + end; + end; +end; + +procedure tgridarrayprop.setlinecolorfix(const Value: colorty); +var + int1: integer; +begin + if flinecolorfix <> value then begin + flinecolorfix := Value; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).linecolorfix:= value; + end; + end; + end; +end; + +procedure tgridarrayprop.setcolor(const avalue: colorty); +var + int1: integer; +begin + if fcolor <> avalue then begin + fcolor:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).color:= avalue; + end; + end; + end; +end; + +procedure tgridarrayprop.setcolorselect(const avalue: colorty); +var + int1: integer; +begin + if fcolorselect <> avalue then begin + fcolorselect:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).colorselect:= avalue; + end; + end; + end; +end; + +procedure tgridarrayprop.setcoloractive(avalue: colorty); +var + int1: integer; +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if fcoloractive <> avalue then begin + fcoloractive:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).coloractive:= avalue; + end; + end; + end; +end; + +procedure tgridarrayprop.setcolorfocused(avalue: colorty); +var + int1: integer; +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if fcolorfocused <> avalue then begin + fcolorfocused:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).colorfocused:= avalue; + end; + end; + end; +end; + +function tgridarrayprop.fixindex(const index: integer): integer; +begin + result:= -index-1; +end; + +procedure tgridarrayprop.countchanged; +begin + fgrid.layoutchanged; +end; + +procedure tgridarrayprop.dochange(const aindex: integer); +begin + fgrid.layoutchanged; + inherited; +end; + +procedure tgridarrayprop.createitem(const index: integer; var item: tpersistent); +begin + item:= gridpropclassty(fitemclasstype).create(fgrid,self); +end; + +procedure tgridarrayprop.setcount1(acount: integer; doinit: boolean); +begin + if acount < foppositecount then begin + foppositecount:= acount; + end; + inherited; + countchanged; +end; + +function tgridarrayprop.geoitems(const aindex: integer): tgridprop; +var + int1: integer; +begin + if freversedorder then begin + int1:= aindex + ffirstopposite + 2; + if int1 > 0 then begin + result:= tgridprop(fitems[count-int1]); + end + else begin + result:= tgridprop(fitems[-int1]); + end; + end + else begin + result:= tgridprop(fitems[aindex]); + end; +end; + +function tgridarrayprop.geotoindex(const ageoindex: integer): integer; +var + int1: integer; +begin + if freversedorder then begin + int1:= count - foppositecount - ageoindex - 1; + if ageoindex + foppositecount - count >= 0 then begin + result:= count + int1; + end + else begin + result:= int1; + end; + end + else begin + result:= ageoindex; + end; +end; + +procedure tgridarrayprop.updatelayout; +var + int1,int2,int3: integer; +begin + if freversedorder then begin //fixrows or fixcols + int3:= getclientsize; + int2:= 0; + for int1:= count - foppositecount to count - 1 do begin + with tgridprop(fitems[int1]) do begin + fend:= int3; + dec(int3,step); + inc(int2,step); + fstart:= int3; + end; + end; + ftotsize:= int2; + int2:= 0; + for int1:= count - foppositecount - 1 downto 0 do begin + with tgridprop(fitems[int1]) do begin + if not (co_nohscroll in foptions) then begin + fstart:= int2; + inc(int2,step); + fend:= int2; + end; + end; + end; + ffirstsize:= int2; + ftotsize:= ftotsize + int2; + end + else begin //datacols + with tdatacols(self) do begin + int2:= 0; + fscrollsize:= 0; + for int1:= ffirsthscrollindex to count - foppositecount - 1 do begin + with tgridprop(fitems[int1]) do begin + // if not (co_nohscroll in foptions) then begin + fstart:= int2; + inc(int2,step); + fend:= int2; + // end; + end; + end; + fscrollsize:= int2; + end; + end; +end; + +procedure tgridarrayprop.setoppositecount(const value: integer); +begin + if value <> foppositecount then begin + if csloading in fgrid.componentstate then begin + foppositecount:= value; //count is invalid + end + else begin + if count < value then begin + foppositecount:= count; + end + else begin + foppositecount := Value; + end; + fgrid.layoutchanged; + end; + end; +end; + +procedure tgridarrayprop.getindexrange(startpos, length: integer; + out range: cellaxisrangety; ascrollables: boolean = true); + + procedure calcrange(first,last: integer; out range: rangety); + var + int1: integer; + begin //todo: optimize + with range do begin + endindex:= -1; + if first > last then begin + startindex:= 0; + end + else begin + startindex:= -1; + for int1:= first to last do begin + with geoitems(int1) do begin + if ascrollables xor (co_nohscroll in foptions) then begin + if fstart >= length then begin + if int1 > first then begin + endindex:= int1 - 1; + end; + break; + end; + if (startindex < 0) and (fend > startpos) then begin + startindex:= int1; + end; + end; + end; + end; + if startindex < 0 then begin + startindex:= 0; + end + else begin + if endindex < 0 then begin + endindex:= last; + end; + end; + if freversedorder and (endindex >= startindex) then begin + startindex:= geotoindex(startindex); + endindex:= geotoindex(endindex); + if startindex > endindex then begin + int1:= startindex; + startindex:= endindex; + endindex:= int1; + end; + end; + end; + end; + end; + +begin + length:= startpos + length; + with range do begin + scrollables:= ascrollables; + calcrange(count-foppositecount,count-1,range1); + calcrange(0,count-foppositecount-1,range2); + end; +end; + +function tgridarrayprop.itematpos(const pos: integer; + const getscrollable: boolean = true): integer; +var + int1,int2: integer; +begin + result:= invalidaxis; + for int1:= 0 to count - 1 do begin + with geoitems(int1) do begin + if (not (co_invisible in foptions) or + (csdesigning in fgrid.componentstate)) and + (getscrollable xor (co_nohscroll in foptions)) then begin + if (pos >= fstart) and (pos < fend) then begin + if freversedorder then begin + int2:= int1 + ffirstopposite + 2; + if int2 > 0 then begin + result:= count-int2; + end + else begin + result:= -int2; + end; + end + else begin + result:= int1; + end; + break; + end; + end; + end; + end; +end; + +function tgridarrayprop.scrollablecount: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to count - 1 do begin + with tgridprop(items[int1]) do begin + if (not (co_invisible in foptions) or (csdesigning in fgrid.componentstate)) and + not(co_nohscroll in foptions) then begin + inc(result); + end; + end; + end; +end; + +procedure tgridarrayprop.fontchanged; +var + int1: integer; +begin + for int1:= 0 to count -1 do begin + tgridprop(items[int1]).fontchanged(fgrid); + end; +end; + +procedure tgridarrayprop.checktemplate(const sender: tobject); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + with tgridprop(fitems[int1]) do begin + if fframe <> nil then begin + fframe.checktemplate(sender); + end; + if face <> nil then begin + fface.checktemplate(sender); + end; + end; + end; +end; + +procedure tgridarrayprop.setinnerframe(const avalue: framety); +begin + finnerframe:= avalue; + fgrid.layoutchanged; +end; + +procedure tgridarrayprop.setinnerframe_left(const avalue: integer); +begin + if finnerframe.left <> avalue then begin + finnerframe.left:= avalue; + fgrid.layoutchanged; + end; +end; + +procedure tgridarrayprop.setinnerframe_top(const avalue: integer); +begin + if finnerframe.top <> avalue then begin + finnerframe.top:= avalue; + fgrid.layoutchanged; + end; +end; + +procedure tgridarrayprop.setinnerframe_right(const avalue: integer); +begin + if finnerframe.right <> avalue then begin + finnerframe.right:= avalue; + fgrid.layoutchanged; + end; +end; + +procedure tgridarrayprop.setinnerframe_bottom(const avalue: integer); +begin + if finnerframe.bottom <> avalue then begin + finnerframe.bottom:= avalue; + fgrid.layoutchanged; + end; +end; + +{ tdatacol } + +constructor tdatacol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fwidthmin:= 1; + fselectedrow:= -1; + inherited; + fdata:= createdatalist; + if fdata <> nil then begin + fdata.count:= fcellinfo.grid.rowcount; + fdata.maxcount:= fcellinfo.grid.frowcountmax; + fdata.onitemchange:= {$ifdef FPC}@{$endif}itemchanged; + end; +end; + +destructor tdatacol.destroy; +begin + if (fdata <> nil) and not (dls_remote in fdata.state) then begin + fdata.destroy; + end; + inherited; +end; + +function tdatacol.getcellorigin: pointty; +begin + fcellinfo.grid.internalupdatelayout; + result.x:= fstart + flinewidth + fcellrect.x; + if not (co_nohscroll in foptions) then begin + result.x:= result.x + fcellinfo.grid.fdatarect.x + + fcellinfo.grid.fscrollrect.x; + end; + result.y:= fcellrect.y + fcellinfo.grid.fdatarect.y + + fcellinfo.grid.fscrollrect.y; +end; + +function tdatacol.createdatalist: tdatalist; +begin + result:= nil; //dummy +end; + +procedure tdatacol.rowcountchanged(const newcount: integer); +var + int1: integer; +begin + if fdata <> nil then begin + with tdatalist1(fdata) do begin + int1:= newcount - fscrolled; + if int1 < fcellinfo.grid.frowcount then begin + int1:= fcellinfo.grid.frowcount; + end; + count:= int1; + fscrolled:= 0; + end; + end; + inherited; + invalidatemaxsize(-1); +end; + +procedure tdatacol.docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); +var + info: celleventinfoty; + bo1: boolean; +begin +{ + if fgrid.updating then begin + fgrid.factiverow:= newcell.row; + exit; + end; +} + bo1:= (gs_hasactiverowcolor in fcellinfo.grid.fstate) and + (newcell.row <> cellbefore.row); + if enter then begin + fcellinfo.grid.factiverow:= newcell.row; + if bo1 then begin + fcellinfo.grid.invalidaterow(newcell.row); + end + else begin + if (co_drawfocus in foptions) or (fcoloractive <> cl_none) or + (fcolorfocused <> cl_none) then begin + invalidatecell(newcell.row); + end; + end; + fcellinfo.grid.initeventinfo(newcell,cek_enter,info); + end + else begin + if selectaction <> fca_exitgrid then begin + fcellinfo.grid.factiverow:= newcell.row; + end; + if bo1 then begin + fcellinfo.grid.invalidaterow(cellbefore.row); + end + else begin + if (co_drawfocus in foptions) or (fcoloractive <> cl_none) or + (fcolorfocused <> cl_none) then begin + invalidatecell(cellbefore.row); + end; + end; + fcellinfo.grid.initeventinfo(cellbefore{newcell},cek_exit,info); + end; + info.selectaction:= selectaction; + info.cellbefore:= cellbefore; + info.newcell:= newcell; + fcellinfo.grid.docellevent(info); + newcell:= info.newcell; +end; + +procedure tdatacol.dokeyevent(var info: keyeventinfoty; up: boolean); +var + event: celleventkindty; + cellinfo: celleventinfoty; +begin + with cellinfo do begin + if up then begin + event:= cek_keyup; + end + else begin + event:= cek_keydown; + end; + if event <> cek_none then begin + fcellinfo.grid.initeventinfo(fcellinfo.grid.ffocusedcell,event,cellinfo); + keyeventinfopo:= @info; + fcellinfo.grid.docellevent(cellinfo); + end; + end; +end; + +procedure tdatacol.updatecellzone(const row: integer; const pos: pointty; + var result: cellzonety); +begin + fcellinfo.grid.internalupdatelayout; + if pointinrect(pos,fcellinfo.rect) then begin + result:= cz_default; + end + else begin + result:= cz_none; + end; +end; + +procedure tdatacol.clientmouseevent(const acell: gridcoordty; + var info: mouseeventinfoty); +var + cellinfo: celleventinfoty; + po1: pointty; +begin + if info.eventkind = ek_clientmouseleave then begin + fcellinfo.grid.cellmouseevent(acell,info,nil); + end + else begin + fcellinfo.grid.cellmouseevent(acell,info,@cellinfo); + if cellinfo.eventkind <> cek_none then begin + po1:= fcellinfo.grid.cellrect(cellinfo.cell).pos; + try + subpoint1(info.pos,po1); + updatecellzone(acell.row,info.pos,cellinfo.zone); + fcellinfo.grid.flastcellzone:= cellinfo.zone; + fcellinfo.grid.docellevent(cellinfo); + finally + addpoint1(info.pos,po1); + end; + end; + end; +end; + +function tdatacol.getselected(const row: integer): boolean; +begin + if ident <= selectedcolmax then begin + if row >= 0 then begin + result:= (gps_selected in fstate) or + (fcellinfo.grid.fdatacols.frowstate.getitempo(row)^.selected and + (bits[ident] or wholerowselectedmask) <> 0); + end + else begin + result:= gps_selected in fstate; + end; + end + else begin + result:= inherited getselected(row); + end; +end; + +procedure tdatacol.setselected(const row: integer; value: boolean); +var + po1,po2,pe: prowstatety; + ca1: longword; + int1,int2: integer; +begin + if ident <= selectedcolmax then begin + if row >= 0 then begin + with fcellinfo.grid.fdatacols.frowstate.getitempo(row)^ do begin + if fdata <> nil then begin + tdatalist1(fdata).setitemselected(row,value); + end; + ca1:= selected; + if value then begin + selected:= selected or bits[ident]; + end + else begin + if gps_selected in fstate then begin + ca1:= bits[ident]; + with fcellinfo.grid.fdatacols.frowstate do begin + int1:= fsize; + po2:= datapo; + pe:= pointer(po2) + count * int1; + while po2 < pe do begin + po2^.selected:= po2^.selected or ca1; + inc(pointer(po2),int1); + end; + end; + fselectedrowcount:= fcellinfo.grid.rowcount-1; + case fselectedrowcount of + 0: begin + fselectedrow:= -1; + end; + 1: begin + fselectedrow:= 0; + end; + else begin + fselectedrow:= -2; + end; + end; + selected:= selected and not (ca1 or wholerowselectedmask); + exclude(fstate,gps_selected); + invalidatecell(invalidaxis); + doselectionchanged(); + exit; + end + else begin + selected:= selected and not (bits[ident] or wholerowselectedmask); + end; + end; + if ca1 <> selected then begin + if value then begin + inc(fselectedrowcount); + if fselectedrow = -1 then begin + fselectedrow:= row; + end + else begin + fselectedrow:= -2; + end; + end + else begin + dec(fselectedrowcount); + if (fselectedrow = row) or (fselectedrowcount = 0) then begin + fselectedrow:= -1; + end; + end; + invalidatecell(row); + doselectionchanged; + end; + end; + end + else begin //row < 0 + if fdata <> nil then begin + tdatalist1(fdata).setitemselected(row,value); + end; + if value then begin + if not (gps_selected in fstate) then begin + include(fstate,gps_selected); + fselectedrowcount:= fcellinfo.grid.rowcount; + fselectedrow:= -2; + changed; + doselectionchanged; + end; + end + else begin + exclude(fstate,gps_selected); + if fselectedrow <> -1 then begin + po1:= fcellinfo.grid.fdatacols.frowstate.datapo; + ca1:= not (bits[ident] {or wholerowselectedmask}); + int2:= fcellinfo.grid.fdatacols.frowstate.fsize; + if fselectedrow >= 0 then begin + with prowstatety(pchar(po1)+fselectedrow*int2)^ do begin + selected:= selected and ca1; + end; + invalidatecell(fselectedrow); + end + else begin + for int1:= 0 to fcellinfo.grid.frowcount - 1 do begin + po1^.selected:= po1^.selected and ca1; + inc(pchar(po1),int2); + end; + changed; + end; + fselectedrowcount:= 0; + fselectedrow:= -1; + doselectionchanged; + end; + end; + end; + end; +end; + +function tdatacol.getmerged(const row: integer): boolean; +begin + if index = 0 then begin + result:= false; + end + else begin + if index > mergedcolmax then begin + result:= fcellinfo.grid.fdatacols.frowstate.getitempocolmerge(row)^. + colmerge.merged = mergedcolall; + end + else begin + result:= fcellinfo.grid.fdatacols.frowstate.getitempocolmerge(row)^. + colmerge.merged and bits[index-1] <> 0; + end; + end; +end; + +procedure tdatacol.setmerged(const row: integer; const avalue: boolean); +begin + if (index > 0) and (index <= mergedcolmax) then begin + if updatebit(fcellinfo.grid.fdatacols.frowstate.getitempocolmerge(row)^. + colmerge.merged,index-1,avalue) then begin + fcellinfo.grid.fdatacols.mergechanged(row); + end; + end; +end; + +function tdatacol.getselectedcells: integerarty; +const + capacitystep = 64; +var + int1,int3: integer; +begin + result:= nil; + with tdatacols(prop) do begin + if hasselection then begin //todo: optimize + int3:= 0; + for int1:= 0 to frowstate.count - 1 do begin + if frowstate.getitempo(int1)^.selected <> 0 then begin + if self.selected[int1] then begin + if int3 >= length(result) then begin + setlength(result,length(result)*2 + capacitystep); + end; + result[int3]:= int1; + inc(int3); + end; + end; + end; + setlength(result,int3); + end; + end; +end; + +procedure tdatacol.setselectedcells(const avalue: integerarty); + //todo: optimize +var + int1: integer; +begin + grid.beginupdate; + try + beginselect; + clearselection; + for int1:= 0 to high(avalue) do begin + setselected(avalue[int1],true); + end; + endselect; + finally + grid.endupdate; + end; +end; + +procedure tdatacol.doselectionchanged; +begin + if (fselectlock = 0) then begin + if assigned(fonselectionchanged) then begin + inc(fselectlock); //avoid recursion + try + fonselectionchanged(self); + finally + dec(fselectlock); + end; + end; + end + else begin + include(fstate,gps_selectionchanged); + end; + fcellinfo.grid.internalselectionchanged; +end; + +procedure tdatacol.beginselect; +begin + inc(fselectlock); +end; + +procedure tdatacol.endselect; +begin + dec(fselectlock); + if fselectlock = 0 then begin + if gps_selectionchanged in fstate then begin + exclude(fstate,gps_selectionchanged); + doselectionchanged; + end; + end; +end; +(* +function tdatacol.selectedcellcount: integer; +var + int1{,int2}: integer; +begin + result:= 0; + if fselectedrow <> -1 then begin + for int1:= 0 to fcellinfo.grid.rowhigh do begin + if selected[int1] then begin + inc(result); + end; + end; + end; +end; +*) +procedure tdatacol.clearselection; +begin + setselected(-1,false); +end; + +function tdatacol.defaultcaption(): msestring; +begin + result:= ''; + if fcellinfo.grid.ffixrows.count > 0 then begin + with tfixrow(fcellinfo.grid.fixrows.fitems[0]) do begin + if fcaptions.count > self.findex then begin + result:= tcolheader(fcaptions.fitems[self.findex]).caption; + end; + end; + end; +end; + +procedure tdatacol.internaldoentercell(const cellbefore: gridcoordty; + var newcell: gridcoordty; const action: focuscellactionty); +begin + if not (gs_cellentered in fcellinfo.grid.fstate) or + (action = fca_entergrid) then begin + include(fcellinfo.grid.fstate,gs_cellentered); +// include(fgrid.fstate1,gs1_focusedcellchanged); + docellfocuschanged(true,cellbefore,newcell,action); + end; +end; + +procedure tdatacol.internaldoexitcell(const cellbefore: gridcoordty; + var newcell: gridcoordty; const selectaction: focuscellactionty); +begin + if gs_cellentered in fcellinfo.grid.fstate then begin + exclude(fcellinfo.grid.fstate,gs_cellentered); +// include(fgrid.fstate1,gs1_focusedcellchanged); + docellfocuschanged(false,cellbefore,newcell,selectaction); + end + else begin + if ((co1_rowcoloractive in foptions1) or (co1_rowcolorfocused in foptions1) or + (ffontactivenum >= 0) or (ffontfocusednum >= 0)) and + (cellbefore.row >= 0) then begin + invalidatecell(cellbefore.row); + end; + end; +end; + +procedure tdatacol.checkdirtyautorowheight(aindex: integer); +begin + if gps_needsrowheight in fstate then begin + tdatacols(prop).rowstate.checkdirtyautorowheight(aindex); + end; +end; + +procedure tdatacol.afterrowcountupdate; +begin + //dummy +end; + +procedure tdatacol.datachange(const arow: integer); +begin + if (datalist = nil) and not (gps_noinvalidate in fstate) and + not (csloading in fcellinfo.grid.componentstate) then begin + checkdirtyautorowheight(arow); + end; +end; + +procedure tdatacol.itemchanged(const sender: tdatalist; const aindex: integer); +var + coord1: gridcoordty; + int1: integer; +begin + if (aindex < 0) then begin + with tdatalist1(sender) do begin + int1:= count + fscrolled; + if int1 <> fcellinfo.grid.frowcount then begin + if fcellinfo.grid.fupdating = 0 then begin + fcellinfo.grid.rowcount:= int1; + afterrowcountupdate; + end + else begin + include(fcellinfo.grid.fstate,gs_rowcountinvalid) + end; + end; + end; + end; + if not (gps_noinvalidate in fstate) and + not (csloading in fcellinfo.grid.componentstate) then begin + checkdirtyautorowheight(aindex); + if aindex < 0 then begin + cellchanged(invalidaxis); + end + else begin + cellchanged(aindex); + end; + if (co_rowdatachange in foptions) and + (fcellinfo.grid.frowdatachanging = 0) then begin + //no recursion + coord1.col:= index; + if aindex < 0 then begin + coord1.row:= 0; + fcellinfo.grid.rowdatachanged(coord1,fcellinfo.grid.frowcount); + end + else begin + coord1.row:= aindex; + fcellinfo.grid.rowdatachanged(coord1); + end; + end; + end; + if not (co_nosort in foptions) then begin + fcellinfo.grid.sortinvalid(index,aindex); + end; + invalidatemaxsize(aindex); + if not (gps_changelock in fstate) and + fcellinfo.grid.canevent(tmethod(fonchange)) then begin + fonchange(self,aindex); + end; +end; + +procedure tdatacol.doactivate; +begin + if (co_drawfocus in foptions) and (fcellinfo.grid.row >= 0) then begin + invalidatecell(fcellinfo.grid.row); + end; +end; + +procedure tdatacol.dodeactivate; +begin + if (co_drawfocus in foptions) and (fcellinfo.grid.row >= 0) then begin + invalidatecell(fcellinfo.grid.row); + end; +end; + +procedure tdatacol.setwidthmax(const Value: integer); +begin + if fwidthmax <> value then begin + if value < 0 then begin + fwidthmax:= 0; + end + else begin + fwidthmax:= Value; + end; + fcellinfo.grid.layoutchanged; + end; +end; + +procedure tdatacol.setwidthmin(const Value: integer); +begin + if fwidthmin <> value then begin + if value < 0 then begin + fwidthmin:= 0; + end + else begin + fwidthmin:= Value; + end; + fcellinfo.grid.layoutchanged; + end; +end; + +procedure tdatacol.updatewidth(var avalue: integer); +begin + if (fwidthmax <> 0) and (avalue > fwidthmax) then begin + avalue:= fwidthmax; + end; + if (fwidthmin <> 0) and (avalue < fwidthmin) then begin + avalue:= fwidthmin; + end; +end; + +procedure tdatacol.updatelayout; +begin + if fpropwidth = 0 then begin + updatepropwidth; + end; + if (co_proportional in foptions) and (fpropwidth <> 0) then begin + fwidth:= round(fcellinfo.grid.fpropcolwidthref * fpropwidth); +// fwidth:= round(tgridframe(fgrid.fframe).fpaintrect.cx * fpropwidth); + end; + updatewidth(fwidth); + inherited; +end; + +procedure tdatacol.moverow(const fromindex, toindex: integer; + const count: integer); +begin + if (fdata <> nil) and not (co_norearange in foptions) then begin + fdata.blockmovedata(fromindex,toindex,count); + end; +end; + +procedure tdatacol.insertrow(const aindex: integer; const count: integer); +begin + if fdata <> nil then begin + fdata.insertitems(aindex,count); + end; +end; + +procedure tdatacol.deleterow(const aindex: integer; const count: integer); +begin + if fdata <> nil then begin + fdata.deleteitems(aindex,count); + end; +end; + +procedure tdatacol.setoptions(const Value: coloptionsty); +const + mask: coloptionsty = [co_fill,co_proportional]; +var + optionsbefore: coloptionsty; + optionsplusdelta: coloptionsty; +begin + optionsbefore:= foptions; + inherited setoptions(coloptionsty(setsinglebit( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask)))); + if coloptionsty(longword(optionsbefore) xor longword(foptions)) * + [co_nosort,co_sortdescend,co_sortcaseinsensitive] <> [] then begin + fcellinfo.grid.sortinvalid(index,-1); + fcellinfo.grid.checksort; + end; + optionsplusdelta:= coloptionsty((longword(optionsbefore) xor longword(foptions)) and + longword(value)); + if (co_focusselect in optionsplusdelta) and + (fcellinfo.grid.ffocusedcell.col = findex) and + (fcellinfo.grid.ffocusedcell.row >= 0) then begin + fcellinfo.grid.selectcell( + makegridcoord(findex,fcellinfo.grid.ffocusedcell.row),csm_select); + end; + if (co_disabled in optionsplusdelta) and + (fcellinfo.grid.ffocusedcell.col = colindex) then begin + fcellinfo.grid.colstep(fca_focusin,1,false,false,false); + end; +end; + +function tdatacol.canfocus(const abutton: mousebuttonty; + const ashiftstate: shiftstatesty; + const noreadonly: boolean; + out canrowfocus: boolean): boolean; +begin + canrowfocus:= ((abutton = mb_left) or (abutton = mb_none) or + not (co_leftbuttonfocusonly in foptions) or + (abutton = mb_middle) and (co_middlebuttonfocus in foptions)) and + ((ashiftstate*[ss_ctrl] = []) or + not (co_noctrlmousefocus in foptions)); + result:= (foptions * [co_invisible,co_disabled,co_nofocus] = []) and + canrowfocus and (not noreadonly or not(co_readonly in options)); +end; + +procedure tdatacol.rearange(const list: integerarty); +begin + if not (co_norearange in foptions) and (fdata <> nil) then begin + fdata.rearange(list); + fdata.change(-1); + end; +end; + +function tdatacol.sortcompare(const index1,index2: integer): integer; +begin + result:= 0; + if fdata <> nil then begin + with tdatalist1(fdata) do begin + result:= tdatalist1(fdata).compare((fdatapo+index1*fsize)^, + (fdatapo+index2*fsize)^); + end; + end; +end; + +function tdatacol.sortcomparecaseinsensitive( + const index1,index2: integer): integer; +begin + result:= 0; + if fdata <> nil then begin + with tdatalist1(fdata) do begin + result:= tdatalist1(fdata).comparecaseinsensitive((fdatapo+index1*fsize)^, + (fdatapo+index2*fsize)^); + end; + end; +end; + +function tdatacol.isempty(const aindex: integer): boolean; +begin + if fdata <> nil then begin + result:= (aindex >= fdata.count) or fdata.empty(aindex); + end + else begin + result:= true; + end; +end; + +procedure tdatacol.docellevent(var info: celleventinfoty); +var + hintinfo: hintinfoty; +begin + if fcellinfo.grid.canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; + if (info.eventkind = cek_firstmousepark) and + fcellinfo.grid.canevent(tmethod(fonshowhint)) and + application.active then begin + application.inithintinfo(hintinfo,fcellinfo.grid); + fonshowhint(self,info.cell.row,hintinfo); + application.showhint(fcellinfo.grid,hintinfo); + end; +end; + +function tdatacol.getcursor(const arow: integer; const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; +begin + result:= cursor; +// result:= cr_arrow; +end; + +function tdatacol.getdatastatname: msestring; +begin + if fname <> '' then begin + result:= msestring(fname); + end + else begin + result:= gridvaluevarname + inttostrmse(ident); + end; +end; + +function tdatacol.getstatsuffix(): msestring; +begin + if fname <> '' then begin + result:= '_'+msestring(fname); + end + else begin + result:= inttostrmse(ident); + end; +end; + + +procedure tdatacol.coloptionstoeditoptions(var dest: optionseditty; + var dest1: optionsedit1ty); +begin + updatebit(longword(dest),ord(oe_readonly),isreadonly); + updatebit(longword(dest1),ord(oe1_savevalue),co_savevalue in foptions); +end; + +procedure tdatacol.dostatread(const reader: tstatreader); +var + bo1: boolean; + mstr1: msestring; +begin + if (fdata <> nil) and not (dls_remote in fdata.state) and + (co_savevalue in foptions) and + not (gs_isdb in fcellinfo.grid.fstate) and reader.candata then begin + reader.readdatalist(getdatastatname,fdata); + end; + if (co_savestate in foptions) and reader.canstate then begin + mstr1:= getstatsuffix(); + if not (co_fixwidth in foptions) and + (og_colsizing in fcellinfo.grid.optionsgrid) then begin + width:= reader.readinteger('width'+mstr1,fwidth,0); + end; + bo1:= reader.readboolean('sortdescend'+mstr1,co_sortdescend in foptions); + if bo1 then begin + options:= options + [co_sortdescend]; + end + else begin + options:= options - [co_sortdescend]; + end; + end; +end; + +procedure tdatacol.dostatwrite(const writer: tstatwriter); +var + mstr1: msestring; +begin + inherited; + if (fdata <> nil) and not (dls_remote in fdata.state) and + (co_savevalue in foptions) and + not (gs_isdb in fcellinfo.grid.fstate) and + writer.candata then begin + writer.writedatalist(getdatastatname,fdata); + end; + if (co_savestate in foptions) and writer.canstate then begin + mstr1:= getstatsuffix(); + if not (co_fixwidth in foptions) and + (og_colsizing in fcellinfo.grid.optionsgrid) then begin + writer.writeinteger('width'+mstr1,fwidth); + end; + writer.writeboolean('sortdescend'+mstr1,co_sortdescend in foptions); + end; +end; +{ +procedure tdatacol.cellchanged(const row: integer); +var + coord1: gridcoordty; +begin + inherited; + if (co_rowdatachange in foptions) and (fgrid.frowdatachanging = 0) then begin + //no recursion + coord1.col:= index; + if row < 0 then begin + coord1.row:= 0; + fgrid.rowdatachanged(coord1,fgrid.frowcount); + end + else begin + coord1.row:= row; + fgrid.rowdatachanged(coord1); + end; + end; +end; +} +function tdatacol.getvisible: boolean; +begin + result:= not (co_invisible in foptions); +end; + +procedure tdatacol.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [co_invisible]; + end + else begin + options:= options + [co_invisible]; + end; +end; + +function tdatacol.getenabled: boolean; +begin + result:= not (co_disabled in foptions); +end; + +procedure tdatacol.setenabled(const avalue: boolean); +begin + if avalue then begin + options:= options - [co_disabled]; + end + else begin + options:= options + [co_disabled]; + end; +end; + +function tdatacol.getreadonly: boolean; +begin + result:= co_readonly in foptions; +end; + +procedure tdatacol.setreadonly(const avalue: boolean); +begin + if avalue then begin + options:= options + [co_readonly]; + end + else begin + options:= options - [co_readonly]; + end; +end; + +function tdatacol.getsortdescend: boolean; +begin + result:= co_sortdescend in foptions; +end; + +procedure tdatacol.setsortdescend(const avalue: boolean); +begin + if avalue then begin + options:= options + [co_sortdescend]; + end + else begin + options:= options - [co_sortdescend]; + end; +end; + + +function tdatacol.getdatapo(const arow: integer): pointer; +begin + if (fdata <> nil) and (arow < fdata.count) then begin + result:= fdata.getitempo(arow); + end + else begin + result:= nil; + end; +end; + +function tdatacol.getrowdatapo: pointer; +begin + result:= nil; + if fcellinfo.grid.row >= 0 then begin + result:= getdatapo(fcellinfo.grid.row); + end; +end; + +{ +function tdatacol.ismerged: boolean; +begin + with fcellinfo.rowstate^ do begin + result:= merged <> 0; + if result then begin + result:= (index <> 0) and + ((merged = mergedcolall) or (index < mergedcolmax) and + (merged and bits[index] <> 0)); + end; + end; +end; +} +procedure tdatacol.beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + //dummy +end; + +procedure tdatacol.afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + //dummy +end; + +function tdatacol.isreadonly: boolean; +begin + result:= (co1_rowreadonly in foptions1) and + (gs_rowreadonly in fcellinfo.grid.fstate) or + (co_readonly in foptions); +end; + +procedure tdatacol.clean(const start,stop: integer); +begin + if fdata <> nil then begin + fdata.clean(start,stop); + end; +end; + +procedure tdatacol.setdata(const avalue: tdatalist); +begin + fdata.assign(avalue); +end; + +procedure tdatacol.autocellheightchanged(const aindex: integer); +begin + checkdirtyautorowheight(aindex); +end; + +procedure tdatacol.autocellwidthchanged(const aindex: integer); +begin + //dummy +end; + +function tdatacol.defaultrowheight: integer; +begin + result:= tcustomgrid(fowner).datarowheight; +end; + +{ tdrawcol } + +procedure tdrawcol.drawcell(const canvas: tcanvas); +begin + inherited; + if assigned(fondrawcell) then begin + fondrawcell(self,canvas,cellinfoty(canvas.drawinfopo^)); + end; +end; + +procedure tdrawcol.beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + if not processed and assigned(fonbeforedragevent) then begin + fcellinfo.cell.row:= arow; + fonbeforedragevent(fcellinfo,ainfo,tcelldragobject(ainfo.dragobjectpo^), + ainfo.accept,processed); + end; + if not processed then begin + inherited; + end; +end; + +procedure tdrawcol.afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + if not processed and assigned(fonafterdragevent) then begin + fcellinfo.cell.row:= arow; + fonafterdragevent(fcellinfo,ainfo,tcelldragobject(ainfo.dragobjectpo^), + ainfo.accept,processed); + end; + if not processed then begin + inherited; + end; +end; + +{ tstringcoldatalist } + +constructor tstringcoldatalist.create(const agrid: tcustomgrid); +begin + fgrid:= agrid; + inherited create; +end; + +function tstringcoldatalist.add(const avalue: msestring; + const anoparagraph: boolean): integer; +begin + result:= inherited add(avalue,anoparagraph); + if anoparagraph then begin + if (nochange = 0) and (fgrid.fupdating = 0) then begin + fgrid.fdatacols.frowstate.flag1[result]:= true; + end + else begin + additem(fnoparagraph,result); + end; + end; +end; + +procedure tstringcoldatalist.afterrowcountupdate; +var + int1: integer; +begin + with fgrid.fdatacols.frowstate do begin + for int1:= 0 to high(fnoparagraph) do begin + if fnoparagraph[int1] < count then begin + flag1[fnoparagraph[int1]]:= true; + end; + end; + end; + fnoparagraph:= nil; +end; + +function tstringcoldatalist.getparagraph(const index: integer; + const aseparator: msestring = ''): msestring; +var + int1: integer; + start{,stop}: integer; +begin + start:= index; + with fgrid.fdatacols.frowstate do begin + while start >= 0 do begin + if not flag1[start] then begin + break; + end; + dec(start); + end; + result:= self.items[start]; + for int1:= start+1 to count-1 do begin + if not flag1[int1] then begin + break; + end; + result:= result + aseparator + self.items[int1]; + end; + end; +end; + +function tstringcoldatalist.getnoparagraphs(index: integer): boolean; +begin + result:= fgrid.fdatacols.frowstate.flag1[index]; +end; + +function tstringcoldatalist.getdefault: pointer; +begin + if fvaluedefault = '' then begin + result:= nil; //use block fillchar() + end + else begin + result:= @fvaluedefault; + end; +end; + +function tstringcoldatalist.empty(const index: integer): boolean; +begin + result:= pmsestring(getitempo(index))^ = fvaluedefault; +end; + +{ tcustomstringcol } + +constructor tcustomstringcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fvaluetrue:= '1'; + fvaluefalse:= '0'; + fcolorglyph:= cl_glyph; + foptionsedit:= tstringcols(aowner).foptionsedit; + foptionsedit1:= tstringcols(aowner).foptionsedit1; + ftextinfo.flags:= tstringcols(aowner).ftextflags; + ftextflagsactive:= tstringcols(aowner).ftextflagsactive; + inherited; +end; + +destructor tcustomstringcol.destroy; +begin + inherited; +end; + +procedure tcustomstringcol.settextflags(const avalue: textflagsty); +begin + if ftextinfo.flags <> avalue then begin + ftextinfo.flags:= checktextflags(ftextinfo.flags,avalue); + changed; + end; +end; + +procedure tcustomstringcol.settextflagsactive(const avalue: textflagsty); +begin + if ftextflagsactive <> avalue then begin + ftextflagsactive:= checktextflags(ftextflagsactive,avalue); + end; + changed; +end; + +function tcustomstringcol.createdatalist: tdatalist; +begin + result:= tstringcoldatalist.create(fcellinfo.grid); +end; + +function tcustomstringcol.getinnerframe: framety; +begin + result:= inherited getinnerframe; +end; + +function tcustomstringcol.getcursor(const arow: integer; + const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; +begin + result:= inherited getcursor(arow,actcellzone,amousepos); + if result = cr_default then begin + if not isreadonly and not (scoe_checkbox in foptionsedit) then begin + result:= cr_ibeam; + end; + end; +end; + +procedure tcustomstringcol.modified; +begin + include(fstate,gps_edited); + //dummy +end; + +procedure tcustomstringcol.checkcellvalue(var avalue: msestring; + var accept: boolean); +begin + updatedisptext(avalue); + if fcellinfo.grid.canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,avalue,accept); + end; + if accept then begin + items[fcellinfo.grid.ffocusedcell.row]:= avalue; + if fcellinfo.grid.canevent(tmethod(fondataentered)) then begin + fondataentered(self); + end; + end; + exclude(fstate,gps_edited); +end; + +function tcustomstringcol.geteditpos: gridcoordty; +begin + result.row:= invalidaxis; + result.col:= invalidaxis; + if (fcellinfo.grid.row >= 0) and (fcellinfo.grid.col >= index) then begin + result.row:= fcellinfo.grid.row; + result.col:= tcustomstringgrid(fcellinfo.grid).feditor.curindex; + end; +end; + +procedure tcustomstringcol.seteditpos(const avalue: gridcoordty); +begin + if (fcellinfo.grid.row >= 0) and (fcellinfo.grid.col >= index) then begin + fcellinfo.grid.focuscell(makegridcoord(index,avalue.row)); + if (fcellinfo.grid.row >= 0) and (fcellinfo.grid.col >= index) then begin + tcustomstringgrid(fcellinfo.grid).feditor.curindex:= avalue.col; + end; + end; +end; + +procedure tcustomstringcol.updatelayout; +begin + inherited; + ftextinfo.clip.pos:= nullpoint; + ftextinfo.clip.size:= fcellinfo.rect.size; + ftextinfo.dest:= fcellinfo.innerrect; +end; + +function tcustomstringcol.getrowtext(const arow: integer): msestring; +begin + result:= items[arow]; +end; + +procedure tcustomstringcol.updatedisptext(var avalue: msestring); +begin + if scoe_trimleft in foptionsedit then begin + avalue:= trimleft(avalue); + end; + if scoe_trimright in foptionsedit then begin + avalue:= trimright(avalue); + end; + if scoe_uppercase in foptionsedit then begin + avalue:= mseuppercase(avalue); + end + else begin + if scoe_lowercase in foptionsedit then begin + avalue:= mselowercase(avalue); + end; + end; +end; + +procedure tcustomstringcol.setpasswordchar(const avalue: widechar); +begin + if fpasswordchar <> avalue then begin + fpasswordchar:= avalue; + changed; + end; +end; + +procedure tcustomstringcol.drawcell(const canvas: tcanvas); +var + int1: integer; +begin + inherited; + ftextinfo.font:= canvas.font; + ftextinfo.text.format:= nil; + with cellinfoty(canvas.drawinfopo^) do begin + if cell.row < fcellinfo.grid.rowcount then begin + if scoe_checkbox in foptionsedit then begin + if calcautocellsize then begin + textrect(canvas,ftextinfo); + int1:= rect.cx - innerrect.cx + ftextinfo.res.cx; + if defaultboxsize > autocellsize.cx then begin + autocellsize.cx:= defaultboxsize; + end; + if defaultboxsize > autocellsize.cy then begin + autocellsize.cy:= defaultboxsize; + end; + end + else begin + if checked[cell.row] then begin + stockobjects.paintglyph(canvas,stg_checked,innerrect, + co_disabled in foptions,fcolorglyph); + end; + end; + end + else begin + ftextinfo.dest.cx:= innerrect.cx; + ftextinfo.dest.cy:= innerrect.cy; + ftextinfo.clip.cx:= rect.cx; + ftextinfo.clip.cy:= rect.cy; + ftextinfo.text.text:= getrowtext(cell.row); + updatedisptext(ftextinfo.text.text); + if passwordchar <> #0 then begin + ftextinfo.text.text:= charstring(passwordchar,length(ftextinfo.text.text)); + end; + if calcautocellsize then begin + textrect(canvas,ftextinfo); + int1:= rect.cx - innerrect.cx + ftextinfo.res.cx; + if int1 > autocellsize.cx then begin + autocellsize.cx:= int1; + end; + int1:= rect.cy - innerrect.cy + ftextinfo.res.cy; + if int1 > autocellsize.cy then begin + autocellsize.cy:= int1; + end; + end + else begin + drawtext(canvas,ftextinfo); + end; + end; + end; + end; + if assigned(fondrawcell) then begin + fondrawcell(self,canvas,cellinfoty(canvas.drawinfopo^)); + end; +end; + +function tcustomstringcol.defaultrowheight(): integer; +var + int1: integer; + fra1: framety; +begin + result:= actualfont.lineheight; + if ffontselect <> nil then begin + int1:= ffontselect.height; + if int1 > result then begin + result:= int1; + end; + end; + if (scoe_checkbox in foptionsedit) and (result < defaultboxsize) then begin + result:= defaultboxsize; + end; + fra1:= getinnerframe; + result:= result + fra1.top + fra1.bottom + framedim.cy; +end; + +function tcustomstringcol.getitems(aindex: integer): msestring; +begin + if aindex = -1 then begin + aindex:= fcellinfo.grid.row; + end; + if aindex >= 0 then begin + result:= tmsestringdatalist(fdata)[aindex]; + end + else begin + tdatalist1(fdata).getgriddefaultdata(result); + end; +end; + +procedure tcustomstringcol.setitems(aindex: integer; const Value: msestring); +begin + if aindex = -1 then begin + aindex:= fcellinfo.grid.row; + end; + if aindex >= 0 then begin + tmsestringdatalist(fdata)[aindex]:= value; + end; +// cellchanged(aindex); //??? already called? +end; + +function tcustomstringcol.getchecked(aindex: integer): boolean; +begin + result:= getitems(aindex) = fvaluetrue;; +end; + +procedure tcustomstringcol.setchecked(aindex: integer; const avalue: boolean); +begin + if avalue then begin + setitems(aindex,fvaluetrue); + end + else begin + setitems(aindex,fvaluefalse); + end; +end; + +function tcustomstringcol.getvaluedefault: msestring; +begin + result:= tstringcoldatalist(fdata).fvaluedefault; +end; + +procedure tcustomstringcol.setvaluedefault(const avalue: msestring); +begin + tstringcoldatalist(fdata).fvaluedefault:= avalue; +end; + + +function tcustomstringcol.getdatalist: tstringcoldatalist; +begin + result:= tstringcoldatalist(fdata); +end; + +procedure tcustomstringcol.setdatalist(const value: tstringcoldatalist); +begin + fdata.Assign(value); +end; + +function tcustomstringcol.readpipe(const text: string; +// const processeditchars: boolean = false; + const aoptions: addcharoptionsty = [aco_processeditchars]; + const maxchars: integer = 0): integer; +var + mstr1: msestring; +begin + mstr1:= msestring(text); + result:= datalist.addchars(mstr1,aoptions,maxchars); +end; + +function tcustomstringcol.readpipe(const pipe: tpipereader; + const aoptions: addcharoptionsty = [aco_processeditchars]; +// const processeditchars: boolean = false; + const maxchars: integer = 0): integer; +var + str1: string; +begin + try + str1:= pipe.readdatastring; + except + end; + result:= readpipe(str1,aoptions,maxchars); +end; + +function tcustomstringcol.geteditstate: dataeditstatesty; +begin + result:= feditstate; +end; + +procedure tcustomstringcol.seteditstate(const avalue: dataeditstatesty); +begin + feditstate:= avalue; +end; +{ +procedure tcustomstringcol.setisdb; +begin + //dummy +end; +} +function tcustomstringcol.getoptionsedit: optionseditty; +begin + result:= []; + stringcoltooptionsedit(foptionsedit,result); +end; + +function tcustomstringcol.needsfocusrect: boolean; +begin + result:= inherited needsfocusrect or + (scoe_focusrectonreadonly in foptionsedit) and + ((co_readonly in foptions) or (oe_readonly in getoptionsedit)); +end; + +procedure tcustomstringcol.docellevent(var info: celleventinfoty); +var + hintinfo: hintinfoty; + mstr1: msestring; + bo1: boolean; +begin + if scoe_checkbox in foptionsedit then begin + if not isreadonly and (info.cell.row >= 0) then begin + if iscellclick(info) or (info.eventkind = cek_keyup) and + (info.keyeventinfopo^.key = key_space) and + (info.keyeventinfopo^.shiftstate = []) then begin + if checked[info.cell.row] then begin + mstr1:= fvaluefalse; + end + else begin + mstr1:= fvaluetrue; + end; + bo1:= true; + checkcellvalue(mstr1,bo1); + end; + end; + end + else begin + if (scoe_hintclippedtext in foptionsedit) and + (info.eventkind = cek_firstmousepark) and application.active and + fcellinfo.grid.getshowhint and + tcustomstringgrid(fcellinfo.grid).textclipped(info.cell) then begin + application.inithintinfo(hintinfo,fcellinfo.grid); + hintinfo.caption:= self[info.cell.row]; + application.showhint(fcellinfo.grid,hintinfo); + end; + end; + inherited; +end; + +procedure tcustomstringcol.afterrowcountupdate; +//var +// int1: integer; +begin + inherited; + if fdata <> nil then begin + tstringcoldatalist(fdata).afterrowcountupdate; + end; +end; + +function tcustomstringcol.edited: boolean; +begin + result:= gps_edited in fstate; +end; + +procedure tcustomstringcol.setcolorglyph(const avalue: colorty); +begin + if fcolorglyph <> avalue then begin + fcolorglyph:= avalue; + invalidate; + end; +end; + +procedure tcustomstringcol.fillcol(const value: msestring); +begin + datalist.fill(datalist.count,value); +end; + +function tcustomstringcol.getnoparagraph(const aindex: integer): boolean; +begin + result:= tcustomgrid(fowner).fdatacols.frowstate.flag1[aindex]; +end; + +{ tfixcol } + +constructor tfixcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + foptionsfix:= defaultfixcoloptions; + ftextinfo.flags:= defaultfixcoltextflags; + fcaptions:= tmsestringdatalist.create; + fcaptions.onitemchange:= {$ifdef FPC}@{$endif}captionchanged; + inherited; + include(fstate,gps_fix); + fcolor:= cl_parent; +end; + +destructor tfixcol.destroy; +begin + inherited; + fcaptions.Free; +end; + +procedure tfixcol.setoptionsfix(const avalue: fixcoloptionsty); +var + opt1: coloptions1ty; +begin + foptionsfix:= avalue; + opt1:= coloptions1ty( + {$ifndef FPC}word({$endif} + replacebits( + longword( + {$ifndef FPC}byte({$endif}avalue{$ifndef FPC}){$endif}) + shr longword(fixcoloptionsshift1), + longword(foptions), + longword( + {$ifndef FPC}word({$endif} + fixcoloptionsmask + {$ifndef FPC}){$endif} + ) + ) + {$ifndef FPC}){$endif} + ); + inherited options1:= opt1; + if fco_invisible in avalue then begin + inherited options:= inherited options + [co_invisible]; + end + else begin + inherited options:= inherited options - [co_invisible]; + end; + { + if fco_active in avalue then begin + options1:= options1 + [co1_active]; + end + else begin + options1:= options1 - [co1_active]; + end; + } +end; + +procedure tfixcol.drawcell(const canvas: tcanvas); +begin + inherited; + with cellinfoty(canvas.drawinfopo^) do begin + if not (cds_notext in drawstate) then begin + ftextinfo.dest:= innerrect; + if cell.row < fcaptions.count then begin + ftextinfo.text.text:= fcaptions[cell.row]; + drawtext(canvas,ftextinfo); + end + else begin + if fnumstep <> 0 then begin + ftextinfo.text.text:= + inttostrmse(fcellinfo.grid.fnumoffset+fnumstart+fnumstep*cell.row); + drawtext(canvas,ftextinfo); + end; + end; + end; + end; +end; + +procedure tfixcol.moverow(const fromindex, toindex: integer; + const count: integer = 1); +begin + +end; + +procedure tfixcol.insertrow(const aindex: integer; const count: integer = 1); +begin + //dummy +end; + +procedure tfixcol.deleterow(const aindex: integer; const count: integer = 1); +begin + //dummy +end; + +procedure tfixcol.setoptions(const Value: coloptionsty); +begin + inherited setoptions(value - notfixcoloptions); +end; + +procedure tfixcol.settextflags(const Value: textflagsty); +begin + if ftextinfo.flags <> value then begin + ftextinfo.flags := checktextflags(ftextinfo.flags,Value); + changed; + end; +end; + +procedure tfixcol.setnumstart(const Value: integer); +begin + if fnumstart <> value then begin + fnumstart:= Value; + changed; + end; +end; + +procedure tfixcol.setnumstep(const Value: integer); +begin + if fnumstep <> value then begin + fnumstep := Value; + changed; + end; +end; + +{ +procedure tfixcol.updatelayout; +begin + inherited; + ftextinfo.dest:= fcellinfo.innerrect; +end; +} + +procedure tfixcol.paint(var info: colpaintinfoty); +begin + if ffont = nil then begin + ftextinfo.font:= fcellinfo.grid.getfont; + end + else begin + ftextinfo.font:= ffont; + end; + inherited; +end; + +procedure tfixcol.setcaptions(const Value: tmsestringdatalist); +begin + fcaptions.assign(Value); +end; + +function tfixcol.getcaptions: tmsestringdatalist; +begin + result:= fcaptions; +end; + +function tfixcol.iscaptionsstored: Boolean; +begin + result:= fcaptions.count > 0; +end; + +procedure tfixcol.captionchanged(const sender: tdatalist; const aindex: integer); +begin + if aindex < 0 then begin + changed; + end + else begin + cellchanged(aindex); + end; +end; + +procedure tfixcol.rearange(const list: integerarty); +begin + if not (co_norearange in foptions) and (fnumstep = 0) and + (fcaptions.count = length(list)) then begin + fcaptions.rearange(list); + end; +end; + +function tfixcol.getvisible: boolean; +begin + result:= not (fco_invisible in options); +end; + +procedure tfixcol.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [fco_invisible]; + end + else begin + options:= options + [fco_invisible]; + end; +end; + +{ tcolsfont } + +class function tcolsfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcols(owner).ffont; +end; + +{ tcolsfontselect } + +class function tcolsfontselect.getinstancepo(owner: tobject): pfont; +begin + result:= @tcols(owner).ffontselect; +end; + +{ tcols } + +constructor tcols.create(aowner: tcustomgrid; aclasstype: gridpropclassty); +begin + fwidth:= griddefaultcolwidth; + ffontactivenum:= -1; + ffontfocusednum:= -1; + inherited; +end; + +destructor tcols.destroy; +begin + inherited; + ffont.free; + ffontselect.free; +end; + +function tcols.mergedwidth(const acol: integer; const amerged: longword): integer; +var + int1: integer; +begin + result:= 0; + if (amerged <> 0) and (acol < mergedcolmax) then begin + if (acol = 0) or (amerged and bits[acol-1] = 0) then begin + if amerged = mergedcolall then begin + for int1:= 1 to count -1 do begin + with tcol(fitems[int1]) do begin + if not (co_invisible in foptions) then begin + result:= result + step; + end; + end; + end; + end + else begin + for int1:= acol to count -1 do begin + if amerged and bits[int1] <> 0 then begin + with tcol(fitems[int1]) do begin + if not (co_invisible in foptions) then begin + result:= result + step; + end; + end; + end + else begin + break; + end; + end; + end; + end; + end; +end; + +procedure tcols.paint(var info: colpaintinfoty; const scrollables: boolean = true); +var + startx,endx: integer; + pt1,pt2: pointty; + int1,int2,int3,int4: integer; + ar1: integerarty; +// po1: prowstatety; +begin + with info do begin + pt1:= canvas.origin; + with canvas.clipbox do begin + startx:= x {+ po1.x}; + endx:= startx + cx; + end; + pt2:= pt1; + setlength(ar1,count); + if (og_colmerged in fgrid.foptionsgrid) and (self is tdatacols) then begin + for int1:= 0 to high(ar1) do begin + with tcol(fitems[int1]) do begin + int4:= 0; + if int1 < mergedcolmax then begin + for int2:= 0 to high(info.rows) do begin + int3:= mergedwidth(int1,tdatacols(self).frowstate.merged[int2]); + if int3 > int4 then begin + int4:= int3; + end; + end; + end; + ar1[int1]:= fend + int4; + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tcol(fitems[int1]).fend; + end; + end; + for int1:= 0 to count-1 do begin + with tcol(fitems[int1]) do begin + if (scrollables xor (co_nohscroll in foptions)) and + (calcautocellsize or not ((startx < fstart) and (endx <= fstart) or + (startx >= ar1[int1]) and (endx > ar1[int1]))) then begin + pt2.x:= fstart + pt1.x; + canvas.origin:= pt2; + paint(info); + end; + end; + end; + canvas.origin:= pt1; + end; +end; + +procedure tcols.updaterowheight(const arow: integer; var arowheight: integer); +var + info: colpaintinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + calcautocellsize:= true; + autocellsize.cx:= 0; + autocellsize.cy:= arowheight; + canvas:= fgrid.getcanvas; + setlength(rows,1); + rows[0]:= arow; //startrow = endrow = 0 + paint(info,true); + paint(info,false); + arowheight:= autocellsize.cy; + end; +end; + +procedure tcols.updatelayout; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + tcol(fitems[int1]).updatelayout; + end; + inherited; +end; + +procedure tcols.rowcountchanged(const countbefore: int32; + const newcount: integer); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + tcol(fitems[int1]).rowcountchanged(newcount); + end; +end; + +function tcols.totwidth: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to count-1 do begin + inc(result,tcol(items[int1]).step); + end; +end; + +function tcols.getclientsize: integer; +begin + result:= tgridframe(fgrid.fframe).finnerclientrect.cx; +end; + +function tcols.getcols(const index: integer): tcol; +begin + result:= tcol(items[index]); +end; + +procedure tcols.setwidth(const Value: integer); +var + int1: integer; +begin + if fwidth <> value then begin + fwidth:= value; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).width:= value; + end; + end; + end; +end; + +procedure tcols.setoptions(const avalue: coloptionsty; + const aforce: boolean); +var + int1: integer; + mask: longword; +begin + mask:= longword(avalue - deprecatedcoloptions) xor longword(foptions); + foptions:= avalue - deprecatedcoloptions; + if csreading in fgrid.componentstate then begin + transferdeprecatedcoloptions(avalue,foptions1); + end; + if not (csloading in fgrid.componentstate) or aforce then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).options:= coloptionsty(replacebits(longword(foptions), + longword(tcol(items[int1]).options),mask)); + end; + end; +end; + +procedure tcols.setoptions(const avalue: coloptionsty); +begin + if foptions <> avalue then begin + setoptions(avalue,false); + end; +end; + +procedure tcols.setoptions1(const value: coloptions1ty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}byte{$endif}; +begin + if foptions1 <> value then begin + mask:= {$ifdef FPC}longword{$else}word{$endif}(value) xor + {$ifdef FPC}longword{$else}word{$endif}(foptions1); + foptions1:= Value; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).options1:= coloptions1ty( + replacebits( + {$ifdef FPC}longword{$else}word{$endif}(value), + {$ifdef FPC}longword{$else}word{$endif}(tcol(items[int1]).options1), + mask)); + end; + end; + fgrid.invalidate; + end; +end; + +procedure tcols.setfontactivenum(const avalue: integer); +var + int1: integer; +begin + if ffontactivenum <> avalue then begin + ffontactivenum:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).fontactivenum:= avalue; + end; + end; + end; +end; + +procedure tcols.setfontfocusednum(const avalue: integer); +var + int1: integer; +begin + if ffontfocusednum <> avalue then begin + ffontfocusednum:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).fontfocusednum:= avalue; + end; + end; + end; +end; + +procedure tcols.setfocusrectdist(const avalue: integer); +var + int1: integer; +begin + if ffocusrectdist <> avalue then begin + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).focusrectdist:= avalue; + end; + end; + end; +end; + +function tcols.getfont: tcolsfont; +begin + getoptionalobject(fgrid.componentstate,ffont,@createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= tcolsfont(pointer(fgrid.font)); + end; +end; + +procedure tcols.setfont(const avalue: tcolsfont); +begin + if avalue <> ffont then begin + setoptionalobject(fgrid.ComponentState,avalue,ffont, + @createfont); + fgrid.invalidate; + end; +end; + +function tcols.isfontstored: Boolean; +begin + result:= ffont <> nil; +end; + +procedure tcols.createfont; +begin + if ffont = nil then begin + ffont:= tcolsfont.create; + ffont.onchange:= @fontselectchanged; + end; +end; + +procedure tcols.fontselectchanged(const sender: tobject); +begin + fgrid.invalidate; +end; + +function tcols.getfontselect: tcolsfontselect; +begin + getoptionalobject(fgrid.componentstate,ffontselect,@createfontselect); + if ffontselect <> nil then begin + result:= ffontselect; + end + else begin + result:= tcolsfontselect(pointer(fgrid.font)); + end; +end; + +procedure tcols.setfontselect(const avalue: tcolsfontselect); +begin + if avalue <> ffontselect then begin + setoptionalobject(fgrid.ComponentState,avalue,ffontselect,@createfontselect); + fgrid.invalidate; + end; +end; + +function tcols.isfontselectstored: Boolean; +begin + result:= ffontselect <> nil; +end; + +procedure tcols.createfontselect; +begin + if ffontselect = nil then begin + ffontselect:= tcolsfontselect.create; + ffontselect.onchange:= @fontselectchanged; + end; +end; + +procedure tcols.move(const curindex, newindex: integer); +begin + inherited; + fgrid.ffixrows.movecol(curindex,newindex,freversedorder); + fgrid.layoutchanged; +end; + +procedure tcols.moverow(const curindex,newindex: integer; const acount: integer); +var + int1: integer; +begin + begindataupdate; + try + for int1:= 0 to self.count - 1 do begin + tcol(items[int1]).moverow(curindex,newindex,acount); + end; + finally + enddataupdate; + end; +end; + +procedure tcols.insertrow(const index: integer; const acount: integer = 1); +var + int1: integer; +begin + for int1:= 0 to self.count - 1 do begin + tcol(items[int1]).insertrow(index,acount); + end; +end; + +procedure tcols.deleterow(const index: integer; const acount: integer = 1); +var + int1: integer; +begin + for int1:= 0 to self.count - 1 do begin + tcol(items[int1]).deleterow(index,acount); + end; +end; + +procedure tcols.rearange(const list: integerarty); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + cols[int1].rearange(list); + end; +end; + +procedure tcols.begindataupdate; +begin + inc(fdataupdating); +end; + +procedure tcols.enddataupdate; +begin + dec(fdataupdating); +end; + +procedure tcols.resetpropwidth; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tcol(fitems[int1]).fpropwidth:= 0; + end; +end; + +procedure tcols.countchanged; +begin + resetpropwidth; + inherited; +end; + +procedure tcols.invalidatemaxsize(const arow: integer = -1); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tcol(fitems[int1]).invalidatemaxsize(arow); + end; +end; + +{ tdatacols } + +constructor tdatacols.create(aowner: tcustomgrid; aclasstype: gridpropclassty); +begin + fselectedrow:= -1; + fsortcol:= -1; + fsortcoldefault:= -1; + fnewrowcol:= -1; + flastvisiblecol:= -1; + frowstate:= trowstatelist.create(aowner); + inherited; + flinecolor:= defaultdatalinecolor; + foptions:= defaultdatacoloptions; + foptions1:= defaultdatacoloptions1; +end; + +destructor tdatacols.destroy; +begin + inherited; + frowstate.free; +end; + +procedure tdatacols.setcols(const index: integer; const Value: tdatacol); +begin + tdatacol(items[index]).Assign(value); +end; + +function tdatacols.getcols(const index: integer): tdatacol; +begin + result:= tdatacol(items[index]); +end; + +function tdatacols.colatpos(const x: integer; + const getscrollable: boolean = true): integer; +begin + result:= itematpos(x,getscrollable); +end; + +procedure tdatacols.updatelayout; +var + int1,int2: integer; +begin + int2:= -1; + flastvisiblecol:= -1; + for int1:= 0 to count - 1 do begin + with tdatacol(fitems[int1]) do begin + fcellinfo.cell.col:= int1; + if foptions * [co_fill,co_invisible,co_nohscroll] = [co_fill] then begin + int2:= int1; + end; + if not (co_invisible in foptions) then begin + flastvisiblecol:= int1; + end; + end; + end; + if int2 >= 0 then begin //last co_fill + with tdatacol(fitems[int2]) do begin + if co1_autocolwidth in foptions1 then begin + fwidth:= minmaxwidth; + end + else begin + fwidth:= fwidthmin; + end; + end; + end; + ffirstopposite:= 0; + for int1:= count-1 downto 0 do begin + with tdatacol(fitems[int1]) do begin + if not (co_nohscroll in foptions) then begin + ffirstopposite:= int1+1; + break; + end; + end; + end; + if ffirstopposite = 0 then begin + ffirstopposite:= count; + end; + inherited; + if int2 >= 0 then begin + int1:= totwidth; + if int1 < fgrid.fdatarect.cx then begin + with tdatacol(fitems[int2]) do begin + fwidth:= fwidth + fgrid.fdatarect.cx - int1{ - (step-fwidth)}; + if (gps_needsrowheight in fstate) then begin + rowstate.change(-1); + end; + end; + inherited; + end; + end; +end; + +procedure tdatacols.createitem(const index: integer; var item: tpersistent); +begin + item:= nil; + fgrid.createdatacol(index,tdatacol(item)); + if item = nil then begin + inherited; + end; +end; + +procedure tdatacols.rowcountchanged(const countbefore: int32; + const newcount: int32); +var + int1: integer; +begin + if fselectedrow >= newcount then begin + fselectedrow:= -1; + end; + if (newcount < countbefore) and (fselectedrow = -2) then begin + fselectedrowcount:= length(getselectedrows); + end; + for int1:= 0 to count - 1 do begin + with tdatacol(items[int1]) do begin + if fselectedrow >= newcount then begin + fselectedrow:= -1; + end; + if (newcount < countbefore) and (fselectedrow = -2) then begin + fselectedrowcount:= length(getselectedcells); + end; + end; + end; + with frowstate do begin + if folded and (newcount < count) then begin + updatedeletedrows(newcount,count-newcount); + end; + count:= newcount; + if fvisiblerowmap <> nil then begin + fvisiblerowmap.count:= newcount; + checkdirty(newcount); + end; + end; + inherited; +end; + +procedure tdatacols.setrowcountmax(const value: integer); +var + int1: integer; +begin + with frowstate do begin + maxcount:= value; + if fvisiblerowmap <> nil then begin + fvisiblerowmap.maxcount:= value; + checkdirty(value); + end; + end; + for int1:= 0 to count - 1 do begin + with tdatacol(items[int1]) do begin + if fdata <> nil then begin + fdata.maxcount:= value; + end; + end; + end; +end; + +function tdatacols.roworderinvalid: boolean; +var + int1: integer; +begin + if fselectedrow <> -1 then begin + fselectedrow:= -2; + end; + for int1:= 0 to count - 1 do begin + with tdatacol(items[int1]) do begin + if fselectedrow <> -1 then begin + fselectedrow:= -2; + end; + end; + end; + result:= true; + updatedatastate(result); +end; + +procedure tdatacols.checkindexrange; +begin + if not (csloading in fgrid.componentstate) then begin + if fsortcol >= count then begin + fsortcol:= count - 1; + end; + if fsortcoldefault >= count then begin + fsortcoldefault:= count - 1; + end; + if fnewrowcol >= count then begin + fnewrowcol:= count - 1; + end; + end; +end; + +procedure tdatacols.setsortcol(const avalue: integer); +var + int1: integer; +begin + int1:= fgrid.updatesortcol(avalue); + if int1 <> avalue then begin + fgrid.sorted:= false; + end; + if fsortcol <> int1 then begin + fsortcol := avalue; + checkindexrange; + fgrid.sortchanged(true); + end; +end; + +procedure tdatacols.setsortcoldefault(const avalue: integer); +begin + if fsortcoldefault <> avalue then begin + fsortcoldefault:= avalue; + checkindexrange; + fgrid.sortchanged(true); + end; +end; + +procedure tdatacols.setnewrowcol(const avalue: integer); +begin + if fnewrowcol <> avalue then begin + fnewrowcol := avalue; + checkindexrange; + end; +end; + +procedure tdatacols.moverow(const fromindex, toindex: integer; const acount: integer = 1); +begin +// roworderinvalid; + with frowstate do begin + blockmovedata(fromindex,toindex,acount); + if fvisiblerowmap <> nil then begin + fvisiblerowmap.blockmovedata(fromindex,toindex,acount); + checkdirty(fromindex); + checkdirty(toindex); + end; + end; + inherited; +end; + +procedure tdatacols.insertrow(const index: integer; const acount: integer = 1); +begin +// roworderinvalid; + with frowstate do begin + insertitems(index,acount); + if fvisiblerowmap <> nil then begin + fvisiblerowmap.insertitems(index,acount); + checkdirty(index); + end; + end; + inherited; +end; + + +procedure tdatacols.deleterow(const index: integer; const acount: integer = 1); +begin +// roworderinvalid; + with frowstate do begin + if fvisiblerowmap <> nil then begin + updatedeletedrows(index,acount); + fvisiblerowmap.deleteitems(index,acount); + end; + deleteitems(index,acount); + end; + inherited; +end; + +procedure tdatacols.beginchangelock; +var + int1: integer; +begin + if fchangelock = 0 then begin + for int1:= 0 to count-1 do begin + with tdatacol(fitems[int1]) do begin + include(fstate,gps_changelock); + end; + end; + end; + inc(fchangelock); +end; + +procedure tdatacols.endchangelock; +var + int1: integer; + col1: tdatacol; +begin + dec(fchangelock); + if fchangelock = 0 then begin + for int1:= 0 to count-1 do begin + with tdatacol(fitems[int1]) do begin + exclude(fstate,gps_changelock); + end; + end; + if fgrid.componentstate * + [csloading,csdesigning,csdestroying] = [] then begin + for int1:= 0 to count - 1 do begin + col1:= tdatacol(fitems[int1]); + if assigned(col1.fonchange) then begin + col1.fonchange(col1,-1); + end; + end; + end; + end; +end; + +procedure tdatacols.setcount1(acount: integer; doinit: boolean); +begin + roworderinvalid; + if fgrid.ffocusedcell.col >= acount then begin + if csdestroying in fgrid.componentstate then begin + fgrid.ffocusedcell:= invalidcell; + end + else begin + fgrid.col:= invalidaxis; + end; + end; + inherited; +end; + +function tdatacols.getselected(const cell: gridcoordty): boolean; +var + int1: integer; +begin + if cell.col >= 0 then begin + result:= cols[cell.col].getselected(cell.row); + end + else begin + if cell.row >= 0 then begin + result:= (frowstate.getitempo(cell.row)^.selected and + wholerowselectedmask <> 0); + end + else begin + result:= true; + for int1:= 0 to count - 1 do begin + if not (gps_selected in cols[int1].fstate) then begin + result:= false; + break; + end; + end; + end; + end; +end; + +procedure tdatacols.setselected(const cell: gridcoordty; const Value: boolean); +var + int1: integer; + po1: prowstatety; + ca1: longword; + bo1: boolean; + rowstatesize: integer; + +begin + fgrid.setselected(cell,value); +// if not (gs_isdb in fgrid.fstate) then begin + if cell.col >= 0 then begin + cols[cell.col].setselected(cell.row,value); + end + else begin //select-deselect whole row + fgrid.beginupdate; + try + for int1:= 0 to count - 1 do begin + cols[int1].setselected(cell.row,value); + end; + if value then begin + ca1:= $ffffffff; + end + else begin + ca1:= 0; + end; + bo1:= false; + if cell.row >= 0 then begin + po1:= frowstate.getitempo(cell.row); + if ca1 <> po1^.selected then begin + if value then begin + inc(fselectedrowcount); + if fselectedrow = -1 then begin + fselectedrow:= cell.row; + end + else begin + fselectedrow:= -2; + end; + end + else begin + dec(fselectedrowcount); + if (fselectedrow = cell.row) or (fselectedrowcount = 0) then begin + fselectedrow:= -1; + end; + end; + po1^.selected:= ca1; + fgrid.invalidaterow(cell.row); //for fixcols + bo1:= true; + end; + end + else begin + po1:= frowstate.datapo; + rowstatesize:= frowstate.fsize; + if value then begin + for int1:= 0 to frowstate.count - 1 do begin + if ca1 <> po1^.selected then begin + po1^.selected:= ca1; + fgrid.invalidaterow(int1); //for fixcols + end; + inc(pchar(po1),rowstatesize); + end; + fselectedrowcount:= fgrid.rowcount; + fselectedrow:= -2; + end + else begin + if fselectedrow <> -1 then begin + if fselectedrow >= 0 then begin + prowstatety(pchar(po1) + fselectedrow * rowstatesize)^.selected:= ca1; + fgrid.invalidaterow(fselectedrow); //for fixcols + bo1:= true; + end + else begin + for int1:= 0 to frowstate.count - 1 do begin + if ca1 <> po1^.selected then begin + po1^.selected:= ca1; + fgrid.invalidaterow(int1); //for fixcols + bo1:= true; + end; + inc(pchar(po1),rowstatesize); + end; + end; + fselectedrowcount:= 0; + fselectedrow:= -1; + end; + end; + end; + if bo1 then begin + fgrid.internalselectionchanged; + end; + finally + fgrid.endupdate; + end; + end; +// end; +end; + +function tdatacols.Getrowselected(const index: integer): boolean; +begin + result:= getselected(makegridcoord(invalidaxis,index)); +end; + +procedure tdatacols.Setrowselected(const index: integer; const avalue: boolean); +begin + setselected(makegridcoord(invalidaxis,index),avalue); +end; + +function tdatacols.getreadonly: boolean; +begin + result:= co_readonly in foptions; +end; + +procedure tdatacols.setreadonly(const avalue: boolean); +begin + if avalue then begin //propagate to items independent of loading state + setoptions(foptions + [co_readonly],true); + end + else begin + setoptions(foptions - [co_readonly],true); + end; +end; + +procedure tdatacols.clearselection; +begin + setselected(invalidcell,false); +end; + +procedure tdatacols.setselectedrange(const start,stop: gridcoordty; + const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); +var + int1,int2: integer; + mo1: cellselectmodety; + rect: gridrectty; +begin + rect.pos:= start; + rect.colcount:= stop.col - start.col; + rect.rowcount:= stop.row - start.row; + normalizerect1(rectty(rect)); + if calldoselectcell then begin + if value then begin + mo1:= csm_select; + end + else begin + mo1:= csm_deselect; + end; + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + cols[int1].beginselect; + for int2:= rect.row to rect.row + rect.rowcount - 1 do begin + fgrid.selectcell(makegridcoord(int1,int2),mo1,checkmultiselect); + end; + end; + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + try + cols[int1].endselect; + except + application.handleexception; + end; + end; + end + else begin + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + with cols[int1] do begin + beginselect; + if not value or not checkmultiselect or + (co_multiselect in options) then begin + for int2:= rect.row to rect.row + rect.rowcount - 1 do begin + selected[int2]:= value; + end; + end; + end; + end; + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + dec(cols[int1].fselectlock); + end; + end; +end; + +procedure tdatacols.setselectedrange(const rect: gridrectty; const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); +begin + setselectedrange(rect.pos, + makegridcoord(rect.col+rect.colcount,rect.row+rect.rowcount), + value,calldoselectcell,checkmultiselect); +end; + +procedure tdatacols.changeselectedrange(const start,oldend,newend: gridcoordty; + calldoselectcell: boolean); +begin +//dummy +end; + +function tdatacols.hasselection: boolean; +var + int1: integer; +begin + result:= fselectedrow <> -1; + if not result then begin + for int1:= 0 to count - 1 do begin + if cols[int1].fselectedrow <> -1 then begin + result:= true; + break; + end; + end; + end; +end; + +procedure tdatacols.mergecols(const arow: integer; const astart: longword = 0; + const acount: longword = bigint); +begin + if frowstate.mergecols(arow,astart,acount) then begin + mergechanged(arow); + end; +end; + +procedure tdatacols.unmergecols(const arow: integer = invalidaxis); +begin + if frowstate.unmergecols(arow) then begin + mergechanged(arow); + end; +end; + +function tdatacols.previosvisiblecol(aindex: integer): integer; +var + int1: integer; +begin + result:= invalidaxis; + if aindex >= count then begin + aindex:= count - 1; + end; + for int1:= aindex - 1 downto 0 do begin + if not (co_invisible in tdatacol(fitems[int1]).foptions) or + (csdesigning in fgrid.ComponentState) then begin + result:= int1; + break; + end; + end; +end; + +function tdatacols.nextvisiblecol(aindex: integer): integer; +var + int1: integer; +begin + result:= invalidaxis; + if aindex < 0 then begin + aindex:= 0; + end; + for int1:= aindex + 1 to count-1 do begin + if not (co_invisible in tdatacol(fitems[int1]).foptions) or + (csdesigning in fgrid.ComponentState) then begin + result:= int1; + break; + end; + end; +end; + +function tdatacols.selectedcellcount: integer; +var + {int1,}int2: integer; +// bo1: boolean; +begin + result:= 0; + for int2:= 0 to count - 1 do begin + with tdatacol(fitems[int2]) do begin + result:= result + selectedcellcount; + end; + end; +{ + if hasselection then begin + bo1:= hascolselection; + for int1:= 0 to frowstate.count - 1 do begin + if bo1 or (frowstate.getitempo(int1)^.selected <> 0) then begin + for int2:= 0 to count - 1 do begin + if tdatacol(fitems[int2]).selected[int1] then begin + inc(result); + end; + end; + end; + end; + end; +} +end; + +function tdatacols.hascolselection: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count - 1 do begin + if gps_selected in tdatacol(fitems[int1]).fstate then begin + result:= true; + exit; + end; + end; +end; + +function tdatacols.getselectedcells: gridcoordarty; +const + capacitystep = 64; +var + int1,int2,int3: integer; + cell: gridcoordty; + bo1: boolean; +begin + result:= nil; + if hasselection then begin //todo: optimize + int3:= 0; + bo1:= hascolselection; + for int1:= 0 to frowstate.count - 1 do begin + if bo1 or (frowstate.getitempo(int1)^.selected <> 0) then begin + cell.row:= int1; + for int2:= 0 to count - 1 do begin + if tdatacol(fitems[int2]).selected[int1] then begin + if int3 >= length(result) then begin + setlength(result,length(result)*2 + capacitystep); + end; + cell.col:= int2; + result[int3]:= cell; + inc(int3); + end; + end; + end; + end; + setlength(result,int3); + end; +end; + +procedure tdatacols.beginselect; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tdatacol(fitems[int1]).beginselect; + end; +end; + +procedure tdatacols.endselect; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + try + tdatacol(fitems[int1]).endselect; + except + application.handleexception; + end; + end; +end; + +procedure tdatacols.decselect; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tdatacol(fitems[int1]) do begin + dec(fselectlock); + end; + end; +end; + +procedure tdatacols.setselectedcells(const Value: gridcoordarty); +var + int1: integer; +begin + fgrid.beginupdate; + beginselect; + clearselection; + for int1:= 0 to high(value) do begin + setselected(value[int1],true); + end; + endselect; + fgrid.endupdate; +end; + +function tdatacols.getselectedrows: integerarty; +var + int1,int2,int3: integer; + po1: prowstatety; +begin + result:= nil; + po1:= frowstate.datapo; + int2:= 0; + int3:= frowstate.fsize; + for int1:= 0 to fgrid.frowcount - 1 do begin + if po1^.selected and wholerowselectedmask <> 0 then begin + additem(result,int1,int2); + end; + inc(pchar(po1),int3); + end; + setlength(result,int2); +end; + +procedure tdatacols.setselectedrows(const avalue: integerarty); +var + int1: integer; +begin + fgrid.beginupdate; + beginselect; + clearselection; + for int1:= 0 to high(avalue) do begin + setselected(makegridcoord(invalidaxis,avalue[int1]),true); + end; + endselect; + fgrid.endupdate; +end; + +function tdatacols.sortfunc(const l,r: integer): integer; +var + int1: integer; +begin + result:= 0; + if fsortcol < 0 then begin + for int1:= 0 to count-1 do begin + with tdatacol(fitems[int1]) do begin + if not(co_nosort in foptions) then begin + if co_sortcaseinsensitive in foptions then begin + result:= sortcomparecaseinsensitive(l,r); + end + else begin + result:= sortcompare(l,r); + end; + if result <> 0 then begin + if co_sortdescend in foptions then begin + result:= - result; + end; + break; + end; + end; + end; + end; + end + else begin + with tdatacol(fitems[fsortcol]) do begin + if not(co_nosort in foptions) then begin + result:= sortcompare(l,r); + if co_sortdescend in foptions then begin + result:= - result; + end; + end; + end; + if (result = 0) and (fsortcoldefault >= 0) then begin + with tdatacol(fitems[fsortcoldefault]) do begin + if not(co_nosort in foptions) then begin + result:= sortcompare(l,r); + if co_sortdescend in foptions then begin + result:= - result; + end; + end; + end; + end; + end; +end; + +procedure tdatacols.updatedatastate(var accepted: boolean); +begin +//dummy +end; + +function compcol(const l,r): integer; +begin + result:= tdatacol(l).fcellinfo.cell.col - tdatacol(r).fcellinfo.cell.col; +end; + +procedure tdatacols.dostatread(const reader: tstatreader; const aorder: boolean); +var + int1: integer; + ar1: integerarty; + int2: integer; +begin + ar1:= nil; //compiler warning + fgrid.beginupdate; + try + if (og_savestate in fgrid.foptionsgrid) and reader.canstate then begin + if og_colmoving in fgrid.optionsgrid then begin + fgrid.ffixrows.orderdatacols(originalorder); + ar1:= readorder(reader); + if ar1 <> nil then begin + fgrid.fixrows.reorderdatacols(ar1); + fgrid.layoutchanged; + end; + end; + end; + for int1:= 0 to count - 1 do begin + cols[int1].dostatread(reader); + end; + if hassortstat then begin + sortcol:= reader.readinteger('sortcol',sortcol,-1,count-1); + end; + if not (gs_isdb in fgrid.fstate) then begin + int2:= -1; + if (og_savestate in fgrid.foptionsgrid) and + (fgrid.foptionsgrid * [og_folded,og_colmerged,og_rowheight] <> []) and + hasdatastat and reader.candata then begin + reader.readdatalist('rowstate',frowstate); + int2:= frowstate.count; + end; + for int1:= 0 to count - 1 do begin + with cols[int1] do begin + if (fdata <> nil) and (fdata.count > int2) then begin + int2:= fdata.count; + end; + end; + end; + if int2 >= 0 then begin + frowstate.count:= int2; + for int1:= 0 to count - 1 do begin + with cols[int1] do begin + if (fdata <> nil) then begin + fdata.count:= int2; + end; + end; + end; + fgrid.rowcount:= int2; + if frowstate.folded then begin + frowstate.recalchidden; + end; + end; + end; + finally + fgrid.endupdate; + end; +end; + +procedure tdatacols.dostatwrite(const writer: tstatwriter; const aorder: boolean); +begin + inherited; + if (og_savestate in fgrid.foptionsgrid) and writer.canstate and + hassortstat then begin + writer.writeinteger('sortcol',sortcol); + end; + if (fgrid.foptionsgrid * [og_folded,og_colmerged,og_rowheight] <> []) and + writer.candata then begin + writer.writedatalist('rowstate',frowstate); + end; +end; + +function tdatacols.cancopy: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count-1 do begin + with tdatacol(fitems[int1]) do begin + if co_cancopy in foptions then begin + result:= true; + break; + end; + end; + end; +end; + +function tdatacols.canpaste: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count-1 do begin + with tdatacol(fitems[int1]) do begin + if co_canpaste in foptions then begin + result:= true; + break; + end; + end; + end; +end; + +function tdatacols.rowempty(const arow: integer): boolean; +var + int1: integer; +begin + result:= true; + for int1:= 0 to count - 1 do begin + if not tdatacol(fitems[int1]).isempty(arow) then begin + result:= false; + break; + end; + end; +end; + +procedure tdatacols.rearange(const list: integerarty); +begin + inherited; + frowstate.rearange(list); +end; + +procedure tdatacols.move(const curindex: integer; const newindex: integer); + + procedure domove(var avalue: integer); + begin + if avalue >= 0 then begin + if avalue = curindex then begin + avalue:= newindex; + end + else begin + if (avalue > curindex) and (avalue <= newindex) then begin + dec(avalue); + end + else begin + if (avalue < curindex) and (avalue >= newindex) then begin + inc(avalue); + end; + end; + end; + end; + end; //domove + +begin + inherited; + domove(fnewrowcol); + domove(fsortcol); + domove(fsortcoldefault); +end; + +procedure tdatacols.dosizechanged; +begin + checkindexrange; + inherited; +end; + +function tdatacols.colbyname(const aname: string): tdatacol; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to count - 1 do begin + if tdatacol(fitems[int1]).fname = aname then begin + result:= tdatacol(fitems[int1]); + break; + end; + end; +end; + +function tdatacols.datalistbyname(const aname: string): tdatalist; //can be nil +var + col1: tdatacol; +begin + result:= nil; + col1:= colbyname(aname); + if col1 <> nil then begin + result:= col1.datalist; + end; +end; + +function tdatacols.colsubdatainfo(const aname: string): subdatainfoty; +var + int1: integer; +begin + result.subindex:= 0; + result.list:= nil; + for int1:= 0 to count - 1 do begin + with tdatacol(fitems[int1]) do begin + if fname = aname then begin + result.list:= datalist; + break; + end; + if fnameb = aname then begin + result.list:= datalist; + result.subindex:= 1; + break; + end; + end; + end; +end; + +procedure tdatacols.datasourcechanged; +begin + //dummy +end; + +procedure tdatacols.begindataupdate; +var + int1: integer; +begin + if fdataupdating = 0 then begin + for int1:= 0 to count - 1 do begin + with tdatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.beginupdate; + end; + end; + end; + end; + inherited; +end; + +procedure tdatacols.enddataupdate; +var + int1: integer; +begin + inherited; + if fdataupdating = 0 then begin + for int1:= 0 to count - 1 do begin + try + with tdatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.endupdate; + end; + end; + except + application.handleexception(fgrid); + end; + end; + end; +end; + +procedure tdatacols.countchanged; +begin + if flastvisiblecol >= count then begin + flastvisiblecol:= count - 1; + end; + fgrid.ffixrows.datacolscountchanged; + inherited; +end; + +procedure tdatacols.mergechanged(const arow: integer); +begin + if (arow < 0) or (arow >= 0) and (arow = fgrid.row) then begin + fgrid.layoutchanged; + end + else begin + fgrid.invalidaterow(arow); + end; + fgrid.rowstatechanged(arow); +end; + +function tdatacols.hassortstat: boolean; +var + int1,int2,int3: integer; +begin + result:= false; + int3:= high(fitems); + for int1:= 0 to fgrid.ffixrows.count-1 do begin + with tfixrow(fgrid.ffixrows.fitems[int1]) do begin + for int2:= 0 to high(fcaptions.fitems) do begin + if int2 >= int3 then begin + break; + end; + with tdatacolheader(fcaptions.fitems[int2]) do begin + if dco_colsort in foptions then begin + result:= true; + break; + end; + end; + end; + if result then begin + break; + end; + end; + end; +end; + +function tdatacols.hasdatastat: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(fitems) do begin + with tdatacol(fitems[int1]) do begin + if co_savevalue in foptions then begin + result:= true; + break; + end; + end; + end; +end; + + +function tdatacols.updatedatastate: boolean; +begin + result:= true; + updatedatastate(result); +end; + +function tdatacols.defaultrowheight: integer; +var + int1: integer; + int2: integer; +begin + if fitems = nil then begin + result:= fgrid.datarowheight; + end + else begin + result:= 0; + for int1:= 0 to high(fitems) do begin + int2:= tdatacol(fitems[int1]).defaultrowheight; + if int2 > result then begin + result:= int2; + end; + end; + end; +end; + +{ tdrawcols } + +constructor tdrawcols.create(aowner: tcustomgrid); +begin + inherited create(aowner,tdrawcol); +end; + +class function tdrawcols.getitemclasstype: persistentclassty; +begin + result:= tdrawcol; +end; + +function tdrawcols.getcols(const index: integer): tdrawcol; +begin + result:= tdrawcol(items[index]); +end; + +{ tstringcols } + +constructor tstringcols.create(aowner: tcustomgrid); +begin + ftextflags:= defaultcoltextflags; + ftextflagsactive:= defaultactivecoltextflags; + foptionsedit:= defaultstringcoleditoptions; + foptionsedit1:= defaultoptionsedit1; + inherited create(aowner,getcolclass); +end; + +class function tstringcols.getitemclasstype: persistentclassty; +begin + result:= tstringcol; +end; + +function tstringcols.getcolclass: stringcolclassty; +begin + result:= tstringcol; +end; + +function tstringcols.getcols(const index: integer): tstringcol; +begin + result:= tstringcol(items[index]); +end; + +procedure tstringcols.settextflags(avalue: textflagsty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}word{$endif}; +begin + if ftextflags <> avalue then begin + avalue:= checktextflags(ftextflags,avalue); + mask:= {$ifdef FPC}longword{$else}longword{$endif}(avalue) xor + {$ifdef FPC}longword{$else}longword{$endif}(ftextflags); + ftextflags:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tstringcol(items[int1]).textflags:= + textflagsty(replacebits({$ifdef FPC}longword{$else}longword{$endif}(avalue), + {$ifdef FPC}longword{$else}longword{$endif}(tstringcol(items[int1]).textflags),mask)); + end; + end; + end; +end; + +procedure tstringcols.settextflagsactive(avalue: textflagsty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}word{$endif}; +begin + if ftextflagsactive <> avalue then begin + avalue:= checktextflags(ftextflagsactive,avalue); + mask:= {$ifdef FPC}longword{$else}longword{$endif}(avalue) xor + {$ifdef FPC}longword{$else}longword{$endif}(ftextflagsactive); + ftextflagsactive := avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tstringcol(items[int1]).textflagsactive:= + textflagsty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(avalue), + {$ifdef FPC}longword{$else}longword{$endif} + (tstringcol(items[int1]).textflagsactive),mask)); + end; + end; + end; +end; + +procedure tstringcols.setoptionsedit(avalue: stringcoleditoptionsty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}byte{$endif}; +begin +// exclude(avalue,scoe_autopost); + if foptionsedit <> avalue then begin + mask:= {$ifdef FPC}longword{$else}longword{$endif}(avalue) xor + {$ifdef FPC}longword{$else}longword{$endif}(foptionsedit); + foptionsedit := avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tstringcol(items[int1]).optionsedit:= stringcoleditoptionsty( + replacebits({$ifdef FPC}longword{$else}longword{$endif}(avalue), + {$ifdef FPC}longword{$else}longword{$endif} + (tstringcol(items[int1]).optionsedit),mask)); + end; + end; + end; +end; + +procedure tstringcols.setoptionsedit1(avalue: optionsedit1ty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}byte{$endif}; +begin +// exclude(avalue,scoe_autopost); + if foptionsedit1 <> avalue then begin + mask:= {$ifdef FPC}longword{$else}byte{$endif}(avalue) xor + {$ifdef FPC}longword{$else}byte{$endif}(foptionsedit1); + foptionsedit1:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tstringcol(items[int1]).optionsedit1:= optionsedit1ty( + replacebits({$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif} + (tstringcol(items[int1]).optionsedit1),mask)); + end; + end; + end; +end; + +procedure tstringcols.updatedatastate(var accepted: boolean); +begin + fgrid.checkcellvalue(accepted); + inherited; +end; + +{ tfixcols } + +constructor tfixcols.create(aowner: tcustomgrid); +begin + freversedorder:= true; + inherited create(aowner,tfixcol); + flinecolor:= defaultfixlinecolor; +end; + +class function tfixcols.getitemclasstype: persistentclassty; +begin + result:= tfixcol; +end; + +function tfixcols.getcols(const index: integer): tfixcol; +begin + result:= tfixcol(items[-index-1]); +end; + +procedure tfixcols.setcols(const index: integer; const Value: tfixcol); +begin + tfixcol(items[-index-1]).assign(value); +end; + +function tfixcols.colatpos(const x: integer): integer; +begin + result:= itematpos(x); + if result < 0 then begin + result:= 0; + end + else begin + result:= -result - 1; + end; +end; + +procedure tfixcols.updatelayout; +var + int1: integer; +begin + if foppositecount > count then begin + foppositecount:= count; + end; + ffirstopposite:= -(count-foppositecount)-1; + for int1:= 0 to count - 1 do begin + tfixcol(fitems[int1]).fcellinfo.cell.col:= -int1-1; + end; + inherited; +end; + +procedure tfixcols.countchanged; +begin + fgrid.fixrows.fixcolscountchanged; + inherited; +end; + +{ tfixrows } + +constructor tfixrows.create(aowner: tcustomgrid); +begin + freversedorder:= true; + inherited create(aowner,tfixrow); + flinecolor:= defaultfixlinecolor; +end; + +class function tfixrows.getitemclasstype: persistentclassty; +begin + result:= tfixrow; +end; + +function tfixrows.getrows(const index: integer): tfixrow; +begin + result:= tfixrow(items[-index-1]); +end; + +procedure tfixrows.setrows(const index: integer; const Value: tfixrow); +begin + tfixrow(items[-index-1]).Assign(value); +end; + +function tfixrows.rowatpos(const y: integer): integer; +begin + result:= itematpos(y); + if result < 0 then begin + result:= 0; + end + else begin + result:= -result - 1; + end; +end; + +procedure tfixrows.updatelayout; +var + int1: integer; +begin + if foppositecount > count then begin + foppositecount:= count; + end; + ffirstopposite:= -(count-foppositecount)-1; + for int1:= 0 to count - 1 do begin + tfixrow(fitems[int1]).fcellinfo.cell.row:= -int1-1; + end; + inherited; + for int1:= 0 to count - 1 do begin + tfixrow(items[int1]).updatelayout; + end; +end; + +procedure tfixrows.updatemergedcells; +var + int1: integer; +begin + for int1:= count - 1 downto 0 do begin //top down for row merging + tfixrow(items[int1]).updatemergedcells; + end; +end; + +procedure tfixrows.paint(const info: rowspaintinfoty); +var + po1,po2: pointty; + linewidthbefore: integer; + + procedure paintrows(const range: rangety); + var + int1: integer; + begin + with info do begin + for int1:= range.startindex to range.endindex do begin + with tfixrow(fitems[int1]) do begin + po2.y:= po1.y + fstart; + with rowinfo do begin + canvas.origin:= po2; + paint(rowinfo); + end; + end; + end; + end; + end; + +var + int1,int2,int3,int4: integer; + reg: regionty; + +begin + with info,rowinfo do begin + calcautocellsize:= false; + if (info.rowinfo.cols.count > 0) and //fpc bug 4130 +// if (cols.count > 0) and + (rowrange.range1.endindex >= rowrange.range1.startindex) or + (rowrange.range2.endindex >= rowrange.range2.startindex) then begin +{ + po1:= canvas.origin; + po2.x:= po1.x; + paintrows(rowrange.range1); + paintrows(rowrange.range2); + canvas.origin:= po1; +} + reg:= canvas.copyclipregion; + canvas.subcliprect(makerect(0, + fgrid.fdatarect.y-tframe1(fgrid.fframe).fi.innerframe.top, + bigint{tframe1(fgrid.fframe).fpaintrect.cx)},fgrid.fdatarect.cy)); + if fix then begin + with fgrid.ffixcols do begin + int3:= fgrid.fdatarecty.cx - ftotsize+ffirstsize; + int4:= -1-ffirstopposite; + end; + end + else begin + with fgrid.fdatacols do begin + int3:= fgrid.fdatarecty.cx - + fgrid.ffixcols.ftotsize + fgrid.ffixcols.ffirstsize - + ftotsize + ffirstsize; + if colrange.scrollables then begin + int3:= int3 - fgrid.fscrollrect.x; + end; + int4:= ffirstopposite; + end; + end; + for int1:= 0 to cols.count - 1 do begin + with cols[int1] do begin + if (flinewidth > 0) and (colrange.scrollables xor + (co_nohscroll in foptions)) and + (not(co_invisible in foptions) or + (csdesigning in fgrid.componentstate)) then begin + int2:= fstart + flinepos + fcellrect.x; + if (index >= int4) or + (int2 < int3) then begin + //not overlapped by right side columns + linewidthbefore:= canvas.linewidth; + if flinewidth = 1 then begin + canvas.linewidth:= 0; + end + else begin + canvas.linewidth:= flinewidth; + end; + //todo: merged cells should be clipped + canvas.drawline(makepoint(int2,0), + makepoint(int2, + tframe1(fgrid.fframe).finnerclientrect.cy{ - 1}), + flinecolorfix); + canvas.linewidth:= linewidthbefore; + end; + end; + end; + end; + canvas.clipregion:= reg; + //todo: should be on top because of overwriting + //overlapping co_nohscroll grid lines + + po1:= canvas.origin; + po2.x:= po1.x; + paintrows(rowrange.range1); + paintrows(rowrange.range2); + canvas.origin:= po1; + end; + end; +end; + +procedure tfixrows.movecol(const curindex,newindex: integer; + const isfix: boolean); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).movecol(curindex,newindex,isfix); + end; +end; + +procedure tfixrows.datacolscountchanged; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).datacolscountchanged(count); + end; +end; + +procedure tfixrows.fixcolscountchanged; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).fixcolscountchanged(count); + end; +end; + +procedure tfixrows.reorderdatacols(const neworder: integerarty); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).reorderdatacols(neworder); + end; +end; + +procedure tfixrows.orderdatacols(const oldorder: integerarty); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).orderdatacols(oldorder); + end; +end; + +procedure tfixrows.dofontheightdelta(var delta: integer); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tfixrow(fitems[int1]) do begin + if ffont = nil then begin + height:= height + delta; + end; + end; + end; +end; + +procedure tfixrows.synctofontheight; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).synctofontheight; + end; +end; + +function tfixrows.getclientsize: integer; +begin + result:= tgridframe(fgrid.fframe).finnerclientrect.cy; +end; + +{ tcustomgrid } + +constructor tcustomgrid.create(aowner: tcomponent); +begin + include(fstate,gs_updatelocked); + fmouseeventcol:= -1; + fmousecell:= invalidcell; + fwheelscrollheight:= defaultwheelscrollheight; + frowcountmax:= bigint; + frowcolors:= tcolorarrayprop.Create; + frowfonts:= trowfontarrayprop.Create(self); + ffocusedcell:= invalidcell; + fstartanchor:= invalidcell; + fendanchor:= invalidcell; + fmouseparkcell:= invalidcell; + factiverow:= invalidaxis; + flastcol:= invalidaxis; + + foptionsgrid:= defaultoptionsgrid; + fdatarowlinewidth:= defaultgridlinewidth; + fdatarowlinecolorfix:= defaultfixlinecolor; + fdatarowlinecolor:= defaultdatalinecolor; + + fdatarowheight:= griddefaultrowheight; + fdatarowheightmin:= 1; + fdatarowheightmax:= maxint; + + fgridframecolor:= cl_gridframe; + + fdatacols:= createdatacols; + ffixcols:= createfixcols; + ffixrows:= createfixrows; + + fdragcontroller:= tdragcontroller.create(idragcontroller(self)); + fzebra_color:= cl_zebra; + fzebra_step:= 2; + + inherited; + include(fwidgetstate1,ws1_designactive); + internalcreateframe; + fobjectpicker:= tobjectpicker.create(iobjectpicker(self)); +// fobjectpicker.options:= fobjectpicker.options + [opo_candoubleclick]; + foptionswidget:= defaultgridwidgetoptions; + foptionswidget1:= defaultgridwidgetoptions1; + exclude(fstate,gs_updatelocked); + internalupdatelayout; +end; + +destructor tcustomgrid.destroy; +begin + killrepeater; + inherited; + fdragcontroller.Free; + fobjectpicker.Free; + fdatacols.Free; + ffixcols.Free; + ffixrows.Free; + frowcolors.Free; + frowfonts.Free; +end; + +procedure tcustomgrid.initeventinfo(const cell: gridcoordty; + eventkind: celleventkindty; out info: celleventinfoty); +begin + fillchar(info,sizeof(info),0); + info.cell:= cell; + info.eventkind:= eventkind; +end; + +procedure tcustomgrid.invalidate; +begin + if fnoinvalidate = 0 then begin + finvalidatedcells:= nil; + end; + if caninvalidate then begin + inherited; + exclude(fstate,gs_invalidated); + end; +end; + +function tcustomgrid.caninvalidate: boolean; +begin + if fnoinvalidate = 0 then begin + result:= (fupdating = 0) and not (csloading in componentstate); + include(fstate,gs_invalidated); + end + else begin + result:= false; + end; +end; + +procedure tcustomgrid.layoutchanged; +begin + if fstate * [gs_layoutvalid,gs_layoutupdating] = [gs_layoutvalid] then begin + exclude(fstate,gs_layoutvalid); + invalidate; + end; +end; + +procedure tcustomgrid.rowdatachanged(const acell: gridcoordty; + const count: integer = 1); +begin + if not (csloading in componentstate) then begin + sortinvalid; + if acell.col >= 0 then begin + fdatacols[acell.col].checkdirtyautorowheight(acell.row); + end + else begin + if gs_needsrowheight in fstate then begin + fdatacols.rowstate.checkdirtyautorowheight(acell.row); + end; + end; + if fupdating = 0 then begin + exclude(fstate,gs_rowdatachanged); + inc(frowdatachanging); + try + dorowsdatachanged(acell,count); + finally + dec(frowdatachanging); + end; + end + else begin + include(fstate,gs_rowdatachanged); + if acell.row < frowdatachangestart then begin + frowdatachangestart:= acell.row; + end; + end; + end; +end; + +procedure tcustomgrid.rowdatachanged; +begin + if frowcount > 0 then begin + rowdatachanged(mgc(invalidaxis,0),frowcount); + end; +end; + +procedure tcustomgrid.setselected(const cell: gridcoordty; const avalue: boolean); +begin + //dummy +end; + +procedure tcustomgrid.internalselectionchanged; +begin + if fupdating = 0 then begin + exclude(fstate,gs_selectionchanged); + doselectionchanged; + end + else begin + include(fstate,gs_selectionchanged); + end; +end; + +procedure tcustomgrid.doselectionchanged; +begin + if assigned(fonselectionchanged) then begin + fonselectionchanged(self); + end; +end; + +function tcustomgrid.getscrollrect: rectty; +begin + internalupdatelayout; + result:= fscrollrect; +end; + +procedure tcustomgrid.setscrollrect(const rect: rectty); +var + po2,po3: pointty; + bo1: boolean; +begin + po2:= subpoint(rect.pos,fscrollrect.pos); + fscrollrect.size:= rect.size; + if (po2.x <> 0) or (po2.y <> 0) then begin + bo1:= fobjectpicker.removexorpic; + po3.x:= 0; + po3.y:= po2.y; + scrollrect(po3,fdatarecty,scrollcaret(true)); + fscrollrect.y:= rect.y; + updatevisiblerows; + scrolled(po3); + po3.x:= po2.x; + po3.y:= 0; + scrollrect(po3,fdatarectx,scrollcaret(false)); + fscrollrect.x:= rect.x; + scrolled(po3); + if bo1 then begin + update; + fobjectpicker.paintxorpic; + end; + end; +end; + +function tcustomgrid.calcminscrollsize: sizety; +begin + internalupdatelayout; + if not (gs_updatelocked in fstate) then begin + result.cx:= fdatacols.fscrollsize + fdatacols.ftotsize + + ffixcols.ftotsize + + tgridframe(fframe).fi.innerframe.left + + tgridframe(fframe).fi.innerframe.right; + if og_rowheight in foptionsgrid then begin + result.cy:= fdatacols.frowstate.rowypos[frowcount]; + end + else begin + result.cy:= (frowcount - fdatacols.frowstate.fhiddencount) * fystep; + end; + result.cy:= result.cy + ffixrows.ftotsize + + tgridframe(fframe).fi.innerframe.top + + tgridframe(fframe).fi.innerframe.bottom; + end + else begin + result:= nullsize; + end; +end; + +procedure tcustomgrid.calcpropcolwidthref; +var + int1,int3: integer; +begin + with tgridframe(fframe) do begin + fpropcolwidthref:= self.fwidgetrect.cx - + fouterframe.left - fouterframe.right - + 2*(fi.levelo+fi.framewidth+fi.leveli) - + finnerframe.left - finnerframe.right{ - + 2 * gridframewidth}; + end; + int3:= 0; + for int1:= 0 to fdatacols.count - 1 do begin + with fdatacols[int1] do begin + if not (co_invisible in options) then begin + if options * [co_proportional,co_fill] = [] then begin + fpropcolwidthref:= fpropcolwidthref - width; + end + else begin + if co1_autocolwidth in options1 then begin + fpropcolwidthref:= fpropcolwidthref - minmaxwidth; + int3:= int3 + minmaxwidth; + end + else begin + int3:= int3 + widthmin; + end; + end; + end; + end; + end; + for int1:= 0 to ffixcols.count - 1 do begin + with tfixcol(ffixcols.items[int1]) do begin + if not (fco_invisible in options) then begin + fpropcolwidthref:= fpropcolwidthref - width; + end; + end; + end; + if fpropcolwidthref < int3 then begin + fpropcolwidthref:= int3; + end; +end; + +procedure tcustomgrid.updatelayout; +var + scrollstate: framestatesty; + int1,int2,int3: integer; + loopcount{,firsthscrollindex}: integer; + bo1: boolean; + reshowfocusedcell: boolean; + propcolwidthrefchanged: boolean; + i1: int32; +begin + reshowfocusedcell:= false; + if focusedcellvalid then begin + bo1:= gs_updatelocked in fstate; + include(fstate,gs_updatelocked); + reshowfocusedcell:= not + rectisequal(clippedcellrect(ffocusedcell,cil_paint),nullrect); + if not bo1 then begin + exclude(fstate,gs_updatelocked); + end; + end; + bo1:= fobjectpicker.removexorpic; + exclude(fstate,gs_hasactiverowcolor); + exclude(fstate,gs_needszebraoffset); + if (zebra_step <> 0) then begin + include(fstate,gs_needszebraoffset); + end; + for int1:= 0 to ffixcols.count -1 do begin + with tfixcol(ffixcols.items[int1]) do begin + if numstep <> 0 then begin + include(self.fstate,gs_needszebraoffset); + end; + if (coloractive <> cl_none) or (colorfocused <> cl_none) or + (fontactivenum >= 0) or (fontfocusednum >= 0) then begin + include(self.fstate,gs_hasactiverowcolor); + end; + end; + end; + if not (gs_hasactiverowcolor in fstate) then begin + for int1:= 0 to fdatacols.count -1 do begin + with tdatacol(fdatacols.items[int1]) do begin + if ((fcoloractive <> cl_none) or (fontactivenum >= 0)) and + (co1_rowcoloractive in foptions1) or + ((fcolorfocused <> cl_none) or (fontfocusednum >= 0)) and + (co1_rowcolorfocused in foptions1) then begin + include(self.fstate,gs_hasactiverowcolor); + break; + end; + end; + end; + end; + loopcount:= 0; + repeat + i1:= fpropcolwidthref; + calcpropcolwidthref; + propcolwidthrefchanged:= fpropcolwidthref <> i1; + scrollstate:= frame.state; + fystep:= fdatarowheight + fdatarowlinewidth; + ffixcols.updatelayout; + ffixrows.updatelayout; +// { + fdatacols.ffirsthscrollindex:= fdatacols.count; + int3:= fixcols.ffirstsize; + for int1:= 0 to fdatacols.count - 1 do begin + with tdatacol(fdatacols.fitems[int1]) do begin + if not (co_nohscroll in foptions) then begin + fdatacols.ffirsthscrollindex:= int1; + break; + end; + fstart:= int3; + inc(int3,step(false)); + fend:= int3; + end; + end; + fdatacols.ffirstsize:= int3 - fixcols.ffirstsize; +// } + with tgridframe(fframe) do begin + checkstate; + with fdatarecty,ffixrows do begin +// finnerdatarect.y:= ffirstsize + fi.innerframe.top; +// finnerdatarect.cy:= finnerclientrect.cy - ftotsize; + x:= fi.innerframe.left; + cx:= finnerclientrect.cx; + y:= ffirstsize + fi.innerframe.top; + cy:= finnerclientrect.cy-ftotsize; + if cx < 0 then begin + cx:= 0; + end; + if cy < 0 then begin + cy:= 0; + end; + { + if finnerdatarect.cy < 0 then begin + finnerdatarect.cy:= 0; + end; + } + end; + with fdatarectx,ffixcols do begin + int2:= finnerclientrect.cx - ftotsize + ffirstsize; + int3:= int2; + fdatacols.foppositecount:= 0; + for int1:= fdatacols.count - 1 downto fdatacols.ffirsthscrollindex do begin + with fdatacols[int1] do begin + if not (co_nohscroll in foptions) then begin + fdatacols.foppositecount:= fdatacols.count-int1-1; + break; + end; + fend:= int3; + dec(int3,step(false)); + fstart:= int3; + end; + end; + fdatacols.ftotsize:= fdatacols.ffirstsize + int2 - int3; //width +// finnerdatarect.x:= ffirstsize + fi.innerframe.left + fdatacols.ffirstsize; +// finnerdatarect.cx:= finnerclientrect.cx - ftotsize - fdatacols.ftotsize; + y:= fi.innerframe.top; + cy:= finnerclientrect.cy; + x:= fi.innerframe.left + ffirstsize + fdatacols.ffirstsize; + { + x:= ffirstnohscroll; + if foppositecount = count then begin + inc(x,fi.innerframe.left); + end + else begin + if (ffirstsize > 0) then begin + x:= ffirstsize + fi.innerframe.left + ffirstnohscroll; + end; + end; + } + cx:= fpaintrect.cx - x - ftotsize + ffirstsize - + fdatacols.ftotsize + fdatacols.ffirstsize - + fi.innerframe.right; + { + cx:= fpaintrect.cx - x; + if (foppositecount > 0) and (ftotsize - ffirstsize > 0) then begin + cx:= cx - ftotsize + ffirstsize - fi.innerframe.right; + end + else begin + cx:= cx - fi.innerframe.right; + end; + } + if cx < 0 then begin + cx:= 0; + end; + if cy < 0 then begin + cy:= 0; + end; +// if finnerdatarect.cx < 0 then begin +// finnerdatarect.cx:= 0; +// end; + end; + with fdatarect do begin + x:= fdatarectx.x; + cx:= fdatarectx.cx; + y:= fdatarecty.y; + cy:= fdatarecty.cy; + end; + end; + fdatacols.updatelayout; + ffixrows.updatemergedcells; + updatevisiblerows; //scroll needs valid visiblerows + tgridframe(fframe).updatestate; + inc(loopcount); + until not propcolwidthrefchanged and + (frame.state * scrollbarframestates = + scrollstate * scrollbarframestates) or (loopcount > 40); + + if bo1 then begin + fobjectpicker.paintxorpic; + end; + if reshowfocusedcell and focusedcellvalid then begin + showcell(ffocusedcell); + end; +end; + +procedure tcustomgrid.dolayoutchanged; +begin + if canevent(tmethod(fonlayoutchanged)) then begin + fonlayoutchanged(self); + if not (gs_layoutvalid in fstate) and (flayoutupdating < 16) then begin + inc(flayoutupdating); + try + internalupdatelayout; + finally + dec(flayoutupdating); + end; + end; + end; +end; + +procedure tcustomgrid.internalupdatelayout(const force: boolean); +var + bo1: boolean; +begin + if (fstate * [gs_layoutvalid,gs_updatelocked] = []) and + not (csdestroying in componentstate) and + (force or (fupdating = 0)) then begin + bo1:= not (gs_layoutupdating in fstate); + if bo1 and canevent(tmethod(fonbeforeupdatelayout)) then begin + fonbeforeupdatelayout(self); + end; + try + fstate:= fstate + [gs_layoutvalid,gs_layoutupdating]; + updatelayout; + finally + if bo1 then begin + exclude(fstate,gs_layoutupdating); + dolayoutchanged; + end; + end; + end; +end; + +function tcustomgrid.intersectdatarect(var arect: rectty): boolean; +begin + internalupdatelayout; + result:= intersectrect(fdatarect,arect,arect); +end; + +procedure tcustomgrid.dopaintforeground(const acanvas: tcanvas); + +var + rect1: rectty; + arowinfo: rowspaintinfoty; + colinfo: colpaintinfoty; + lines: segmentarty; + int1,int2,int3,int4,int5: integer; + dataclip: rectty; + fixdataclip: rectty; + reg: regionty; + saveindex: integer; + linewidthbefore: integer; + rowheight1: boolean; + rowstate1: trowstatelist; + lineinfos: array of record + lcolor: colorty; + lcolorfix: colorty; + lwidth: integer; + end; + +begin + inherited; + lines:= nil; + lineinfos:= nil; + rowheight1:= og_rowheight in foptionsgrid; + rowstate1:= fdatacols.frowstate; + internalupdatelayout(true); + fnumoffset:= getnumoffset; + saveindex:= acanvas.save; + acanvas.move(pointty(tframe1(fframe).fi.innerframe.topleft)); + frootbrushorigin:= clientwidgetpos; + frootbrushorigin.x:= frootbrushorigin.x + fdatarect.x + rootpos.x; + frootbrushorigin.y:= frootbrushorigin.y + fdatarect.y + rootpos.y; + fbrushorigin.x:= frootbrushorigin.x; + fbrushorigin.y:= frootbrushorigin.y + fscrollrect.y; + rect1:= acanvas.clipbox; + if (rect1.cx > 0) or (rect1.cy > 0) then begin + fixdataclip:= mr(fdatarecty.x-tframe1(fframe).fi.innerframe.left,0, + fdatarecty.cx-ffixcols.ftotsize+ffixcols.ffirstsize,bigint); + if fixdataclip.cx < 0 then begin + fixdataclip.cx:= 0; + end; + with arowinfo do begin + ffixrows.getindexrange(rect1.y,rect1.cy,rowrange); + if (rowrange.range1.endindex >= rowrange.range1.endindex) or + (rowrange.range2.endindex >= rowrange.range2.endindex) then begin + ffixcols.getindexrange(rect1.x,rect1.cx,rowinfo.colrange); + with rowinfo do begin + canvas:= acanvas; + cols:= ffixcols; + fix:= true; + end; + ffixrows.paint(arowinfo); + rowinfo.cols:= fdatacols; + rowinfo.fix:= false; + fdatacols.getindexrange(rect1.x,rect1.cx,rowinfo.colrange,false); + acanvas.save; + acanvas.intersectcliprect(fixdataclip); + ffixrows.paint(arowinfo); + acanvas.intersectcliprect(makerect(fdatarect.x - + tframe1(fframe).fi.innerframe.left,0, + fdatarect.cx,tframe1(fframe).fpaintrect.cy)); + acanvas.move(makepoint(ffixcols.ffirstsize+fdatacols.ffirstsize+ + fscrollrect.x,0)); + rect1:= acanvas.clipbox; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + fdatacols.getindexrange(rect1.x,rect1.cx,rowinfo.colrange); + fixrows.paint(arowinfo); + end; + acanvas.restore; + end; + end; + + rect1.x:= -tframe1(fframe).fi.innerframe.left; + rect1.y:= fdatarecty.y-tframe1(fframe).fi.innerframe.top; + rect1.cx:= tframe1(fframe).fpaintrect.cx; + rect1.cy:= fdatarecty.cy; + acanvas.intersectcliprect(rect1); + acanvas.move(makepoint(0,fscrollrect.y + ffixrows.ffirstsize)); + //move to clientorigin + rect1:= acanvas.clipbox; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + if high(fvisiblerows) >= 0 then begin + with colinfo do begin + calcautocellsize:= false; + autocellsize:= nullsize; + ystep:= self.fystep; + if rowheight1 then begin + startrow:= -1; + for int1:= high(fvisiblerows) downto 0 do begin + with prowstaterowheightty(rowstate1.getitempo(fvisiblerows[int1]))^ do begin + if rect1.y >= rowheight.ypos then begin + startrow:= int1; + ystart:= rowheight.ypos; + break; + end; + end; + end; + if startrow < 0 then begin + startrow:= 0; + ystart:= prowstaterowheightty( + rowstate1.getitempo(fvisiblerows[0]))^.rowheight.ypos; + end; + endrow:= high(fvisiblerows); + int2:= rect1.y + rect1.cy; + for int1:= startrow to high(fvisiblerows) do begin + if prowstaterowheightty( + rowstate1.getitempo(fvisiblerows[int1]))^.rowheight.ypos >= + int2 then begin + endrow:= int1-1; + break; + end; + end; + end + else begin + startrow:= rect1.y div ystep - fvisiblerowsbase; + if startrow < 0 then begin + startrow:= 0; + end; + ystart:= (startrow + fvisiblerowsbase) * ystep; + endrow:= (rect1.y + rect1.cy - 1) div ystep - fvisiblerowsbase; + end; + rows:= fvisiblerows; + foldinfo:= fvisiblerowfoldinfo; + if endrow > high(fvisiblerows) then begin + endrow:= high(fvisiblerows); + end; + if endrow >= startrow then begin + canvas:= acanvas; + ffixcols.paint(colinfo); + dataclip:= makerect( + fdatarect.x-tframe1(fframe).fi.innerframe.left-fdatacols.ffirstsize, + -fscrollrect.y,fdatarecty.cx-ffixcols.ftotsize,fdatarect.cy); + if dataclip.cx < 0 then begin + dataclip.cx:= 0; + end; + + linewidthbefore:= acanvas.linewidth; + if (fdatarowlinewidth > 0) or rowheight1 then begin + acanvas.linewidth:= fdatarowlinewidth; + int1:= endrow-startrow+1; + setlength(lines,int1); + if rowheight1 then begin + setlength(lineinfos,int1); + int2:= ystart; + end + else begin + int2:= ystart - (fdatarowlinewidth + 1) div 2; + end; + int3:= tframe1(fframe).finnerclientrect.cx{ - 1}; + int5:= rowcolors.count; + int4:= 0; + for int1:= 0 to high(lines) do begin + if rowheight1 then begin + with rowstate1.getitemporowheight( + fvisiblerows[int1+startrow])^.rowheight, + lineinfos[int1] do begin + int4:= (linecolor and rowstatemask) - 1; + if (int4 < 0) or (int4 >= int5) then begin + lcolor:= fdatarowlinecolor; + end + else begin + lcolor:= rowcolors[int4]; + end; + int4:= (linecolorfix and rowstatemask) - 1; + if (int4 < 0) or (int4 >= int5) then begin + lcolorfix:= fdatarowlinecolorfix; + end + else begin + lcolorfix:= rowcolors[int4]; + end; + if linewidth = 0 then begin + lwidth:= fdatarowlinewidth; + end + else begin + lwidth:= linewidth-1; + end; + int4:= (lwidth + 1) div 2; + end; + inc(int2,rowstate1.internalystep(fvisiblerows[int1+startrow])); + end + else begin + inc(int2,ystep); + end; + with lines[int1] do begin + a.x:= 0; + a.y:= int2-int4; + b.x:= int3; + b.y:= int2-int4; + end; + end; + if ffixcols.count > 0 then begin //draw horz lines fixcols + reg:= acanvas.copyclipregion; + acanvas.subcliprect(dataclip); + if not acanvas.clipregionisempty then begin + if rowheight1 then begin + for int1:= 0 to high(lines) do begin + with lines[int1],lineinfos[int1] do begin + if lwidth > 0 then begin + acanvas.linewidth:= lwidth; + acanvas.drawline(a,b,lcolorfix); + end; + end; + end; + end + else begin + acanvas.drawlinesegments(lines,fdatarowlinecolorfix); + end; + end; + acanvas.clipregion:= reg; + end; + end; + + acanvas.intersectcliprect(fixdataclip); + fdatacols.paint(colinfo,false); //draw fix datacols + + acanvas.intersectcliprect(dataclip); + int1:= fscrollrect.x + fdatacols.fscrollsize + + fdatarect.x - tframe1(fframe).fi.innerframe.left; + int2:= fdatarect.x + fdatarect.cx - tframe1(fframe).fi.innerframe.left; + if int1 < int2 then begin + acanvas.subcliprect(mr(int1,dataclip.y,int2-int1,dataclip.cy)); + end; + if not acanvas.clipregionisempty then begin //draw horz lines datacols + int2:= fdatarecty.cx - ffixcols.ftotsize + ffixcols.ffirstsize; + if int2 < fdatarect.x then begin + int2:= fdatarect.x; + end; + int3:= ffixcols.ffirstsize; + if int2 > paintrect.cx then begin + int2:= paintrect.cx; + end; + if int3 < 0 then begin + int3:= 0; + end; + if length(lines) > 0 then begin //draw horz lines datacols + for int1:= 0 to high(lines) do begin + with lines[int1] do begin + a.x:= int3; + b.x:= int2; +//b.y:= b.y -3; + end; + end; + if rowheight1 then begin + for int1:= 0 to high(lines) do begin + with lines[int1],lineinfos[int1] do begin + if lwidth > 0 then begin + acanvas.linewidth:= lwidth; + acanvas.drawline(a,b,lcolor); + end; + end; + end; + end + else begin + acanvas.drawlinesegments(lines,fdatarowlinecolor); + end; + end; + if fdatacols.fscrollsize > 0 then begin + acanvas.intersectcliprect( + mr(fdatacols.ffirstsize+ffixcols.ffirstsize,-fscrollrect.y, + fdatarect.cx,fscrollrect.size.cy)); + end; + acanvas.move(mp(fdatacols.ffirstsize+ffixcols.ffirstsize+ + fscrollrect.x,0)); + acanvas.linewidth:= linewidthbefore; + fdatacols.paint(colinfo,true); //draw normal cols + end; + acanvas.linewidth:= linewidthbefore; + end; //endrow >= startrow + end; //with colinfo + end; //fvisiblerows <> nil + end; //rect1 not empty + end; //if cliprect not empty + + acanvas.restore(saveindex); + with tgridframe(fframe).fi do begin + acanvas.drawframe(clientrect,innerframe,fgridframecolor); + end; +end; + +procedure tcustomgrid.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tcustomgrid.setframe(const avalue: tgridframe); +begin + inherited setframe(avalue); +end; + +function tcustomgrid.getframe: tgridframe; +begin + result:= tgridframe(inherited getframe); +end; + +procedure tcustomgrid.dostatread(const reader: tstatreader); +var + po1: gridcoordty; +begin + beginupdate; + try + if reader.canstate then begin + fpropcolwidthref:= reader.readinteger('propcolwidthref',fpropcolwidthref,0); + end; + fdatacols.dostatread(reader,foptionsgrid * [og_savestate,og_colmoving] = + [og_savestate,og_colmoving]); + if (og_savestate in foptionsgrid) and reader.canstate then begin + sorted:= reader.readboolean('sorted',sorted); + po1.col:= reader.readinteger('col',ffocusedcell.col); + if not (gs_isdb in fstate) then begin + po1.row:= reader.readinteger('row',ffocusedcell.row); + end + else begin + po1.row:= ffocusedcell.row; + end; + if og_rowsizing in foptionsgrid then begin + datarowheight:= reader.readinteger('rowheight',datarowheight); + end; + if ((po1.col < 0) or (po1.col < fdatacols.count)) and + ((po1.row < 0) or (po1.row < frowcount)) then begin + focuscell(po1); + end; + end; + finally + endupdate; + end; +end; + +procedure tcustomgrid.dostatwrite(const writer: tstatwriter); +var + int1: integer; +begin + int1:= row; + if not (og_nosaveremoveappendedrow in foptionsgrid) then begin + removeappendedrow; //calls docheckcellvalue + end + else begin + docheckcellvalue; + end; + if writer.canstate then begin + writer.writeinteger('propcolwidthref',fpropcolwidthref); + end; + fdatacols.dostatwrite(writer,foptionsgrid * [og_savestate,og_colmoving] = + [og_savestate,og_colmoving]); + row:= int1; + if (og_savestate in foptionsgrid) and writer.canstate then begin + writer.writeboolean('sorted',hassort); + writer.writeinteger('col',ffocusedcell.col); + if not (gs_isdb in fstate) then begin + writer.writeinteger('row',ffocusedcell.row); + end; + writer.writeinteger('rowheight',datarowheight); + end; +end; + +procedure tcustomgrid.statreading; +begin + //dummy +end; + +procedure tcustomgrid.statread; +begin + //dummy +end; + +function tcustomgrid.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +function tcustomgrid.rowhigh: integer; +begin + result:= frowcount - 1; +end; + +function tcustomgrid.datarowhigh: integer; //without auto appended empty row +begin + result:= frowcount - 1; + if isautoappend then begin + dec(result); + end; +end; + +procedure tcustomgrid.setrowcount(Value: integer); +var + int1: integer; + bo1,bo2: boolean; +begin + if frowcount <> value then begin + beginupdate; + try + if factiverow >= value then begin + factiverow:= invalidaxis; + end; + if ffocusedcell.row >= value then begin + int1:= frowcount; + exclude(fstate,gs_emptyrowremoved); + include(fstate,gs_rowremoving); + try + defocusrow; + finally + exclude(fstate,gs_rowremoving); + end; + if (gs_emptyrowremoved in fstate) then begin + dec(int1); + end; + if (frowcount <> int1) then begin + exit; + end; + bo2:= frowcount = value; + bo1:= true; + end + else begin + bo1:= false; + bo2:= false; + end; + int1:= frowcount; + if value > frowcountmax then begin + frowcount:= frowcountmax; + if ffocusedcell.row >= 0 then begin + dec(ffocusedcell.row,value-frowcount); + if ffocusedcell.row < 0 then begin + ffocusedcell.row:= invalidaxis; + fstate:= fstate - [gs_cellentered]; + end; + factiverow:= ffocusedcell.row; + end; + end + else begin + frowcount := Value; + end; + if not bo2 then begin + dorowcountchanged(int1,value); + end; + layoutchanged; + if not (gs_isdb in fstate) and entered and + (bo1 and ((og_autoappend in foptionsgrid) and (frowcount <> 0) or + (frowcount = 0) and (og_autofirstrow in foptionsgrid))) then begin + row:= frowcount; + end; + finally + endupdate; + end; + end; +end; + +procedure tcustomgrid.setrowcountmax(const Value: integer); +begin + if (value < frowcount) {and (value <> 0)} then begin + rowcount:= value; + end; + if value <> frowcountmax then begin + fdatacols.setrowcountmax(value); + frowcountmax := Value; + end; +end; + +procedure tcustomgrid.setdatarowlinewidth(const Value: integer); +begin + if fdatarowlinewidth <> value then begin + if value < 0 then begin + fdatarowlinewidth:= 0; + end + else begin + fdatarowlinewidth := Value; + end; + rowstatelist.change(-1); + layoutchanged; + end; +end; + +procedure tcustomgrid.setdatarowlinecolor(const Value: colorty); +begin + if fdatarowlinecolor <> value then begin + fdatarowlinecolor := Value; + invalidate; + end; +end; + +procedure tcustomgrid.setdatarowlinecolorfix(const Value: colorty); +begin + if fdatarowlinecolorfix <> value then begin + fdatarowlinecolorfix:= Value; + invalidate; + end; +end; + +function tcustomgrid.wheelheight: integer; +begin + if fwheelscrollheight <= 0 then begin + result:= application.mousewheelacceleration(1); + end + else begin + result:= rowsperpage - 1; + if fwheelscrollheight < result then begin + result:= fwheelscrollheight; + end; + end; +end; + +procedure tcustomgrid.scrollevent(sender: tcustomscrollbar; event: scrolleventty); +begin + if sender.tag = 1 then begin + case event of + sbe_stepup: scrollrows(-1); + sbe_stepdown: scrollrows(1); + sbe_pageup: scrollrows(-(rowsperpage-1)); + sbe_pagedown: scrollrows(rowsperpage-1); + sbe_wheelup: scrollrows(-wheelheight); + sbe_wheeldown: scrollrows(wheelheight); + end; + end + else begin + case event of + sbe_stepup: scrollleft; + sbe_stepdown: scrollright; + sbe_pageup,sbe_wheelup: scrollpageleft; + sbe_pagedown,sbe_wheeldown: scrollpageright; + end; + end; +end; + +function tcustomgrid.caninsertrow: boolean; +begin + result:= not fnorowedit; +end; + +function tcustomgrid.canappendrow: boolean; +begin + result:= not fnorowedit; +end; + +function tcustomgrid.candeleterow: boolean; +begin + result:= not fnorowedit; +end; + +function tcustomgrid.canmoverow: boolean; +begin + result:= not fnorowedit; +end; + +procedure tcustomgrid.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); + + function menustates(const aenabled: boolean): actionstatesarty; + begin + if aenabled then begin + result:= nil; + end + else begin + setlength(result,1); + result[0]:= [as_disabled] + end; + end; //menustates + +var + bo1: boolean; + state1: actionstatesty; + sepchar: msechar; +begin + if (og_autopopup in foptionsgrid) then begin + if popupmenu <> nil then begin + sepchar:= popupmenu.shortcutseparator; + end + else begin + sepchar:= tcustommenu.getshortcutseparator(amenu); + end; + bo1:= false; + if fdatacols.cancopy or canevent(tmethod(foncopyselection)) then begin + if fdatacols.hasselection then begin + state1:= []; + end + else begin + state1:= [as_disabled]; + end; + tpopupmenu.additems(amenu,self,mouseinfo,[ + stockobjects.captions[sc_copy_cells]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_copycells])+')'], + [],[state1],[{$ifdef FPC}@{$endif}docopycells],not bo1); + bo1:= true; + end; + if fdatacols.canpaste or canevent(tmethod(fonpasteselection)) then begin + if fdatacols.readonly then begin + state1:= [as_disabled]; + end + else begin + state1:= []; + end; + tpopupmenu.additems(amenu,self,mouseinfo,[ + stockobjects.captions[sc_paste_cells]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_pastecells])+')'], + [],[state1],[{$ifdef FPC}@{$endif}dopastecells],not bo1); + bo1:= true; + end; + + if og_rowinserting in foptionsgrid then begin + tpopupmenu.additems(amenu,self,mouseinfo,[ + stockobjects.captions[sc_insert_rowhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_rowinsert])+')'],[], + menustates(caninsertrow), + [{$ifdef FPC}@{$endif}doinsertrow],not bo1); + bo1:= true; + tpopupmenu.additems(amenu,self,mouseinfo,[ + stockobjects.captions[sc_append_rowhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_rowappend])+')'],[], + menustates(canappendrow),[{$ifdef FPC}@{$endif}doappendrow],not bo1); + bo1:= true; + end; + if og_rowdeleting in foptionsgrid then begin + if (ffocusedcell.row >= 0) and candeleterow then begin + state1:= []; + end + else begin + state1:= [as_disabled]; + end; + tpopupmenu.additems(amenu,self,mouseinfo,[ + stockobjects.captions[sc_delete_rowhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_rowdelete])+')'], + [[mao_nocandefocus]],[state1],[{$ifdef FPC}@{$endif}dodeleterows],not bo1); + bo1:= true; + end; + end; + inherited; +end; + +procedure tcustomgrid.setdatacols(const Value: tdatacols); +begin + fdatacols.assign(Value); +end; + +procedure tcustomgrid.setfixcols(const Value: tfixcols); +begin + ffixcols.assign(Value); +end; + +procedure tcustomgrid.setfixrows(const Value: tfixrows); +begin + ffixrows.assign(Value); +end; + +procedure tcustomgrid.setcol(const value: integer); +begin + focuscell(makegridcoord(value,ffocusedcell.row)); +end; + +procedure tcustomgrid.setrow(const value: integer); +begin + focuscell(makegridcoord(ffocusedcell.col,value)); +end; + +function tcustomgrid.visiblerow(const arow: integer): integer; + //returns index in visible rows, invalidaxis if not visible +begin + if not (csdesigning in componentstate) then begin + result:= fdatacols.frowstate.visiblerow(arow); + end + else begin + result:= arow; + if (arow < 0) or (arow >= frowcount) then begin + result:= invalidaxis; + end; + end; +end; + +function tcustomgrid.createdatacols: tdatacols; +begin +{$warnings off} + result:= tdatacols.create(self,tdatacol); +{$warnings on} +end; + +function tcustomgrid.createfixcols: tfixcols; +begin + result:= tfixcols.create(self); +end; + +function tcustomgrid.createfixrows: tfixrows; +begin + result:= tfixrows.create(self); +end; + +procedure tcustomgrid.initcellinfo(var info: cellinfoty); +begin + //dummy +end; + +function tcustomgrid.ystep: integer; +begin + internalupdatelayout; + result:= fystep; +end; + +procedure tcustomgrid.setdatarowheight(const value: integer); +begin + if fdatarowheight <> value then begin + if value < fdatarowheightmin then begin + fdatarowheight:= fdatarowheightmin; + end + else begin + if value > fdatarowheightmax then begin + fdatarowheight:= fdatarowheightmax; + end + else begin + fdatarowheight:= value; + end; + end; + rowstatelist.change(-1); + layoutchanged; + end; +end; + +procedure tcustomgrid.internalcreateframe; +begin + tgridframe.create(iscrollframe(self),self,iautoscrollframe(self)); +end; + +procedure tcustomgrid.dorowcountchanged(const countbefore,newcount: integer); +begin + if (fclickedcell.row >= 0) and (newcount <= fclickedcell.row) then begin + exclude(fstate,gs_cellclicked); + end; + layoutchanged; + ffixcols.rowcountchanged(countbefore,newcount); + fdatacols.rowcountchanged(countbefore,newcount); + if canevent(tmethod(fonrowcountchanged)) then begin + fonrowcountchanged(self); + end; +end; + +procedure tcustomgrid.dorowsdatachanged(const acell: gridcoordty; + const acount: integer); +var + int1: integer; + coord1: gridcoordty; +begin + if canevent(tmethod(fonrowsdatachanged)) then begin + fonrowsdatachanged(self,acell,acount); + end; + if canevent(tmethod(fonrowdatachanged)) then begin + coord1.col:= acell.col; + for int1:= acell.row to acell.row + acount-1 do begin + coord1.row:= int1; + fonrowdatachanged(self,coord1); + end; + end; +end; + +procedure tcustomgrid.invalidatecell(const cell: gridcoordty); +begin + internalupdatelayout; + if (cell.row < 0) or + (cell.row >= ffirstvisiblerow) and + (cell.row <= flastvisiblerow) then begin + invalidaterect(cellrect(cell)); + end; +end; + +procedure tcustomgrid.invalidatesinglecell(const cell: gridcoordty); +begin + if (cell.row <> invalidaxis) and (cell.col <> invalidaxis) then begin + invalidatecell(cell); + end; +end; + +procedure tcustomgrid.invalidaterow(const arow: integer); +begin + invalidatecell(makegridcoord(invalidaxis,arow)); +end; + +procedure tcustomgrid.invalidatefocusedcell; +begin + if (ffocusedcell.row >= 0) and (ffocusedcell.col >= 0) then begin + invalidatecell(ffocusedcell); + end; +end; + +procedure tcustomgrid.cellchanged(const sender: tcol; const row: integer); +var + bo1: boolean; +begin + bo1:= (ffocusedcell.row >= 0) and (sender.colindex = ffocusedcell.col) and + ((row < 0) or (row = ffocusedcell.row)); + if fupdating = 0 then begin + if row >= 0 then begin + invalidatecell(makegridcoord(sender.colindex,row)); + end + else begin + colchanged(sender); + end; + if bo1 then begin + focusedcellchanged; + end; + end + else begin + if bo1 then begin + include(fstate,gs_focusedcellchanged); + end; + if fnoinvalidate = 0 then begin + if fstate * [gs_invalidated,gs_layoutvalid] = [gs_layoutvalid] then begin + if high(finvalidatedcells) > 20 then begin + include(fstate,gs_invalidated); + finvalidatedcells:= nil; + end + else begin + incrementarraylength(pointer(finvalidatedcells),typeinfo(gridcoordarty)); + finvalidatedcells[high(finvalidatedcells)]:= + makegridcoord(sender.colindex,row); + end; + end; + end; + end; +end; + +procedure tcustomgrid.focusedcellchanged; +begin + exclude(fstate,gs_focusedcellchanged); +end; + +procedure tcustomgrid.colchanged(const sender: tcol); +var + rect1: rectty; +begin + if not (csloading in componentstate) then begin + internalupdatelayout; + rect1:= cellrect(makegridcoord(sender.colindex,0)); + rect1.y:= 0; + rect1.cy:= tgridframe(fframe).fpaintrect.cy; + invalidaterect(rect1); + end; +end; + +procedure tcustomgrid.rowchanged(const arow: integer); +var + rect1: rectty; +begin + if fnoinvalidate = 0 then begin + internalupdatelayout; + rect1:= cellrect(makegridcoord(0,arow)); + rect1.x:= 0; + rect1.cx:= tgridframe(fframe).fpaintrect.cx; + invalidaterect(rect1); + end; +end; + +procedure tcustomgrid.rowstatechanged(const arow: integer); +begin + //dummy +end; + +function tcustomgrid.cellatpos(const apos: pointty; + out coord: gridcoordty): cellkindty; +var + po1: pointty; +begin + result:= ck_invalid; + coord:= invalidcell; + internalupdatelayout; + with tgridframe(fframe) do begin + if not pointinrect(apos,clientrect) then begin + exit; + end; + end; + po1.x:= apos.x - tgridframe(fframe).fi.innerframe.left; + po1.y:= apos.y - tgridframe(fframe).fi.innerframe.top; + + with po1,coord do begin + row:= ffixrows.rowatpos(y); + if row < 0 then begin + col:= ffixcols.colatpos(x); + if col = 0 then begin + col:= fdatacols.colatpos(x,false); + if col < 0 then begin + dec(x,fscrollrect.x+ffixcols.ffirstsize+fdatacols.ffirstsize); + col:= fdatacols.colatpos(x,true); + end; + if col >= 0 then begin + result:= ck_fixrow; + end; + end + else begin + result:= ck_fixcolrow; + end; + end + else begin //datarows + dec(y,fscrollrect.y+ffixrows.ffirstsize); + row:= rowatpos(y); + col:= ffixcols.colatpos(x); + if col = 0 then begin + col:= fdatacols.colatpos(x,false); + if col < 0 then begin + dec(x,fscrollrect.x+ffixcols.ffirstsize+fdatacols.ffirstsize); + col:= fdatacols.colatpos(x,true); + end; + if (col >= 0) and (row >= 0) then begin + result:= ck_data; + end; + end + else begin + if row >= 0 then begin + result:= ck_fixcol; + end; + end; + end; + end; +end; + +function tcustomgrid.cellatpos(const apos: pointty): gridcoordty; +begin + cellatpos(apos,result); +end; + +function tcustomgrid.rowatpos(y: integer): integer; +//var +// int1: integer; +begin + result:= invalidaxis; + if y >= 0 then begin + if og_rowheight in foptionsgrid then begin + result:= fdatacols.frowstate.rowindex(y); + end + else begin + result:= fdatacols.frowstate.visiblerowtoindex(y div fystep); + end; + end; +end; + +function tcustomgrid.rowpos(arow: integer): integer; +begin + result:= 0; + if arow < 0 then begin + arow:= 0; + end; + if arow >= frowcount then begin + arow:= frowcount-1; + end; + if arow > 0 then begin + if og_rowheight in foptionsgrid then begin + result:= fdatacols.frowstate.rowypos[arow]; + end + else begin + result:= fdatacols.frowstate.visiblerow(arow) * fystep; + end; + end; +end; + +procedure tcustomgrid.firstcellclick(const cell: gridcoordty; + var info: mouseeventinfoty); +begin + //dummy +end; + +function tcustomgrid.getzebrastart: integer; +begin + result:= fzebra_start; +end; + +function tcustomgrid.getnumoffset: integer; +begin + result:= 0; +end; + +procedure tcustomgrid.mouseevent(var info: mouseeventinfoty); +begin + tgridframe(fframe).mouseevent(info); + inherited; +end; + +function tcustomgrid.actualcursor(const apos: pointty): cursorshapety; +var + prop1: tgridprop; +begin + prop1:= gridprop(fmousecell); + if prop1 <> nil then begin + result:= prop1.cursor; + if result <> cr_default then begin + exit; + end; + end; + + with fmousecell do begin + if (row >= 0) and (col >= 0) and (col < datacols.count) then begin + result:= datacols[fmousecell.col].getcursor(fmousecell.row,flastcellzone, + subpoint(apos,flastcellpos)); + end + else begin + result:= inherited actualcursor(apos); + end; + end; +end; + +procedure tcustomgrid.clientmouseevent(var info: mouseeventinfoty); + + procedure mouseleavecol; + var + info1: mouseeventinfoty; + begin + if fmouseeventcol >= 0 then begin + if fmouseeventcol < fdatacols.count then begin + fillchar(info1,sizeof(info1),0); + info1.eventkind:= ek_clientmouseleave; + fdatacols[fmouseeventcol].clientmouseevent(makegridcoord(fmouseeventcol,-1), + info1); + fmouseeventcol:= -1; + end; + end; + end; + +var + cellkind: cellkindty; + + procedure checkfocuscell; + + function getfocusact(const canselect: boolean): focuscellactionty; + begin + result:= fca_focusin; + if canselect then begin + if info.shiftstate * keyshiftstatesmask = [ss_shift] then begin + result:= fca_selectend; + end + else begin + if info.eventkind = ek_buttonpress then begin + result:= fca_reverse; + end; + end; + end; + end; + + var + po1: pointty; + action: focuscellactionty; + bo1,bo2: boolean; + cell1: gridcoordty; + rowfocus: boolean; + pos1: cellpositionty; + begin //checkfocuscell + po1:= fscrollrect.pos; + action:= fca_focusin; + case cellkind of + ck_data: begin + if not (gs_mousecellredirected in fstate) then begin + cell1:= fmousecell; + cell1.col:= mergestart(cell1.col,cell1.row); + bo2:= fdatacols[cell1.col].canfocus(info.button,info.shiftstate,false, + rowfocus); + if not bo2 then begin + if rowfocus then begin + cell1.col:= mergestart(ffocusedcell.col,cell1.row); + //try to focus mouse row + if (cell1.col < 0) or + (co_nofocus in fdatacols[cell1.col].options) then begin + cell1.col:= nextfocusablecol(0,false,cell1.row,false); + end; + end + else begin + cell1.col:= invalidaxis; + end; + end; + if (cell1.col >= 0) and + fdatacols[cell1.col].canfocus(info.button, + info.shiftstate,false,bo1) then begin + bo1:= not gridcoordisequal(cell1,ffocusedcell); + if (info.shiftstate * [ss_left,ss_middle,ss_right] = [ss_left]) and + (co_mouseselect in fdatacols[cell1.col].foptions) then begin + if (info.shiftstate * keyshiftstatesmask = [ss_shift]) then begin + action:= fca_selectend; + end + else begin + if info.shiftstate * keyshiftstatesmask = [ss_ctrl] then begin + if (info.button = mb_left) or (cell1.col <> ffocusedcell.col) or + (cell1.row <> ffocusedcell.row) then begin + action:= fca_reverse; + end; + end; + end; + end + else begin + if (action = fca_focusin) and (ss_shift in info.shiftstate) then begin + action:= fca_focusinshift; + end; + end; + pos1:= cep_nearest; + if not bo2 then begin + pos1:= cep_none; + end; + focuscell(cell1,action,scm_cell,pos1); + if not bo2 then begin + showcell(fmousecell); + end + else begin + if bo1 then begin + firstcellclick(cell1,info); + end; + end; + end + else begin + if (fmousecell.row >= 0) and rowfocus then begin + focuscell(makegridcoord(invalidaxis,fmousecell.row)); + end + else begin + showcell(fmousecell); + end; + end; + end; + end; + ck_fixcol: begin + with fixcols[fmousecell.col] do begin + if (fco_mousefocus in options) then begin + if (fmousecell.row <> ffocusedcell.row) or + (info.eventkind = ek_buttonpress) then begin + focusrow(fmousecell.row,getfocusact(fco_mouseselect in options), + true,scm_row); + end; + end + else begin + if (info.eventkind = ek_buttonpress) and + (fco_mouseselect in fixcols[fmousecell.col].options) then begin + fdatacols.selected[fmousecell]:= not fdatacols.selected[fmousecell]; + end; + showcell(fmousecell); + end; + end; + end; + ck_fixrow: begin + with fixrows[fmousecell.row] do begin + if (fro_mousefocus in options) then begin + if (fmousecell.col <> ffocusedcell.col) or + (info.eventkind = ek_buttonpress) then begin + focuscell(makegridcoord(fmousecell.col,row), + getfocusact(fro_mouseselect in options),scm_col); + end; + end + else begin + if (info.eventkind = ek_buttonpress) and + (fro_mouseselect in fixrows[fmousecell.row].options) then begin + fdatacols.selected[fmousecell]:= not fdatacols.selected[fmousecell]; + end; + showcell(fmousecell); + end; + end; + end; + ck_fixcolrow: begin + if (info.eventkind = ek_buttonpress) and + (fro_mouseselect in fixrows[fmousecell.row].options) and + (fco_mouseselect in fixcols[fmousecell.col].options) then begin + fdatacols.selected[fmousecell]:= not fdatacols.selected[fmousecell]; + end; + end; + end; + addpoint1(info.pos,subpoint(tgridframe(fframe).scrollpos,po1)); + //shift mouse with grid; + end; + + procedure checkrepeater(const drag: boolean); + var + bo1: boolean; + begin + with info do begin + if gs_cellclicked in fstate then begin + if drag then begin + frepeataction:= fca_none; + end + else begin + if ss_shift in shiftstate then begin + if co_mouseselect in fdatacols[ffocusedcell.col].foptions then begin + frepeataction:= fca_selectend; + end + else begin + frepeataction:= fca_focusinshift; + end; + end + else begin + frepeataction:= fca_focusinrepeater; + end; + end; + if pos.y < fdatarect.y - mousescrolldist then begin + if (ffocusedcell.col >= 0) and + (co_mousescrollrow in datacols[ffocusedcell.col].options) then begin + startrepeater(gs_scrolldown,fastrepeat); + end; + end + else begin + if pos.y - mousescrolldist >= fdatarect.y + fdatarect.cy then begin + if (ffocusedcell.col >= 0) and + (co_mousescrollrow in datacols[ffocusedcell.col].options) then begin + startrepeater(gs_scrollup,fastrepeat); + end; + end + else begin + bo1:= not ((focusedcell.col >= 0) and + (co_nohscroll in + tcol(fdatacols.fitems[ffocusedcell.col]).options)); + if bo1 and (pos.x < fdatarect.x - mousescrolldist) then begin + if og_mousescrollcol in foptionsgrid then begin + startrepeater(gs_scrollleft,slowrepeat); + end; + end + else begin + if bo1 and (pos.x - mousescrolldist >= + fdatarect.x + fdatarect.cx) then begin + if og_mousescrollcol in foptionsgrid then begin + startrepeater(gs_scrollright,slowrepeat); + end; + end + else begin + killrepeater; + end; + end; + end; + end; + end; + end; + end; + +var + coord1: gridcoordty; + str1: msestring; + hintinfo: hintinfoty; + mousewidgetbefore: twidget; + bo1: boolean; + +begin + inherited; + bo1:= es_processed in info.eventstate; + if not bo1 then begin + fobjectpicker.mouseevent(info); + if (info.eventkind = ek_buttonpress) and + not(csdesigning in componentstate) and + (fobjectpicker.currentobjects <> nil) and + (pickobjectkindty(fobjectpicker.currentobjects[0] mod pickobjectstep) in + [pok_datacol,pok_datarow]) then begin + exclude(info.eventstate,es_processed); //allow mouse row selecting + end; + if not (es_processed in info.eventstate) then begin + fdragcontroller.clientmouseevent(info); + end; + end; + if not(csdesigning in componentstate) then begin + if es_processed in info.eventstate then begin + if info.eventkind in [ek_mousemove,ek_mousepark] then begin + checkrepeater(true); + end; + if not bo1 and isvalidcell(fmousecell) then begin + cellmouseevent(fmousecell,info); + end; + end + else begin + with info do begin + if eventkind = ek_buttonpress then begin + checkreautoappend; + end; + if eventkind in mouseposevents then begin + coord1:= fmousecell; + cellkind:= cellatpos(pos,fmousecell); + if (coord1.col <> fmousecell.col) or + (coord1.row <> fmousecell.row) then begin + if isvalidcell(coord1) then begin + cellmouseevent(coord1,info,nil,cek_mouseleave); + end; + if (fmousecell.row <> invalidaxis) and + (fmousecell.col <> invalidaxis) then begin + cellmouseevent(fmousecell,info,nil,cek_mouseenter); + end; + end; + if (fmousecell.row <> fmouseparkcell.row) or + (fmousecell.col <> fmouseparkcell.col) then begin + fmouseparkcell:= invalidcell; + end; + end + else begin + cellkind:= ck_invalid; + end; + case eventkind of + ek_clientmouseenter: begin + include(fstate,gs_mouseentered); + end; + ek_clientmouseleave: begin + if isvalidcell(fmousecell) then begin + cellmouseevent(fmousecell,info,nil,cek_mouseleave); + end; + fmousecell:= invalidcell; + fmouseparkcell:= invalidcell; + end; + ek_buttonpress: begin + mousewidgetbefore:= application.mousewidget; + checkfocuscell; + if (mousewidgetbefore = application.mousewidget) and + //not interrupted by beginmodal + (button = mb_left) then begin + fclickedcellbefore:= fclickedcell; + fclickedcell:= fmousecell; + if isdatacell(fmousecell) then begin + include(fstate,gs_cellclicked); + end; + end; + end; + ek_mousemove,ek_mousepark: begin + if not (es_child in info.eventstate) then begin + if cellkind = ck_data then begin + application.widgetcursorshape:= + datacols[fmousecell.col].getcursor(fmousecell.row, + flastcellzone,subpoint(info.pos,flastcellpos)); + end + else begin + application.widgetcursorshape:= cr_default; + if (eventkind = ek_mousepark) and + (cellkind in [ck_fixrow,ck_fixcolrow]) and + ((fmousecell.row <> fmouseparkcell.row) or + (fmousecell.col <> fmouseparkcell.col)) then begin + fmouseparkcell:= fmousecell; + str1:= ''; + with ffixrows[fmouseparkcell.row] do begin + if fmouseparkcell.col >= 0 then begin + if fmouseparkcell.col < fcaptions.count then begin + with fcaptions[fmouseparkcell.col] do begin + str1:= hint; + if (str1 = '') and (dco_hintclippedtext in options) and + finfo.captionclipped then begin + str1:= caption; + end; + end; + end; + end + else begin + if -fmouseparkcell.row <= fcaptionsfix.count then begin + with fcaptionsfix[fmouseparkcell.col] do begin + str1:= hint; + end; + end; + end; + end; + if (str1 <> '') and application.active then begin + application.inithintinfo(hintinfo,self); + hintinfo.caption:= str1; + application.showhint(self,hintinfo); + end; + end; + end; + if (info.shiftstate * [ss_left,ss_middle,ss_right] = [ss_left]) and + (ws_lclicked in fwidgetstate) then begin + checkfocuscell; + end + else begin + if (shiftstate = []) and (cellkind = ck_data) and + (co_mousemovefocus in fdatacols[fmousecell.col].foptions) and + not (aso_nogridmousemove in assistiveoptions) then begin + if gs_mouseentered in fstate then begin + exclude(fstate,gs_mouseentered); + fmouserefpos:= info.pos; + end; + if (distance(fmouserefpos,info.pos) > 3) and active then begin + fmouserefpos:= info.pos; + if not fdatacols[fmousecell.col].canfocus( + info.button,info.shiftstate,false,bo1) then begin + showcell(fmousecell); + end + else begin + focuscell(fmousecell); + end; + end; + end; + end; + end; + checkrepeater(false); + end; + end; + if cellkind = ck_data then begin + if fmousecell.col <> fmouseeventcol then begin + mouseleavecol; + end; + fmouseeventcol:= fmousecell.col; + if not (es_processed in info.eventstate) and + (fmousecell.col >= 0) then begin //ek_clientmouseleave otherwise + coord1:= ffocusedcell; + fdatacols[fmousecell.col].clientmouseevent(fmousecell,info); + if not gridcoordisequal(ffocusedcell,coord1) then begin + include(fstate,gs_mousecellredirected); + end; + end; + end + else begin + mouseleavecol; + if not (es_processed in info.eventstate) then begin + cellmouseevent(fmousecell,info); + end; + end; + end; + end; + end; + if (info.eventkind = ek_buttonrelease) or + (info.eventkind = ek_mousecaptureend) and + not (gs1_mousecaptureendlock in fstate1) then begin + if gs_cellclicked in fstate then begin + killrepeater; + end; + fstate:= fstate - [gs_mousecellredirected,gs_cellclicked]; + end; +end; + +procedure tcustomgrid.docellevent(var info: celleventinfoty); +begin + with info do begin + grid:= self; + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; + if info.cell.col >= 0 then begin + datacols[info.cell.col].docellevent(info); + end; + if canassistive() and not (gs1_nocellassistive in fstate1) then begin + assistiveserver.docellevent(iassistiveclientgrid(getiassistiveclient()), + info); + end; + {$ifdef mse_with_ifi} + if fifilink <> nil then begin + fifilink.controller.docellevent(ificelleventinfoty(info)); + end; + {$endif} + if eventkind = cek_mousepark then begin + if (fmouseparkcell.row <> cell.row) or + (fmouseparkcell.col <> cell.col) then begin + fmouseparkcell:= cell; + if isdatacell(cell) then begin + eventkind:= cek_firstmousepark; + docellevent(info); + end; + end; + end; + end; +end; + +procedure tcustomgrid.cellmouseevent(const acell: gridcoordty; + var info: mouseeventinfoty; + const acellinfopo: pcelleventinfoty = nil; + const aeventkind: celleventkindty = cek_none); +var + cellinfo: celleventinfoty; +// po1: pointty; + cellinfopo: pcelleventinfoty; +begin + cellinfopo:= acellinfopo; + if cellinfopo = nil then begin + cellinfopo:= @cellinfo; + end; + fillchar(cellinfopo^,sizeof(cellinfo),0); + with cellinfopo^ do begin + mouseeventinfopo:= @info; + cell:= acell; + grid:= self; + gridmousepos:= info.pos; + eventkind:= aeventkind; + if eventkind = cek_none then begin + case info.eventkind of + ek_mousemove: eventkind:= cek_mousemove; + ek_mousepark: eventkind:= cek_mousepark; + ek_buttonpress: eventkind:= cek_buttonpress; + ek_buttonrelease: eventkind:= cek_buttonrelease; + end; + end; + if (acellinfopo = nil) and (eventkind <> cek_none) then begin + if eventkind in mousecellevents then begin + zone:= cz_default; + end; + flastcellpos:= cellrect(cellinfo.cell).pos; + try + subpoint1(info.pos,flastcellpos); + if (eventkind = cek_buttonrelease) and (cell.row < 0) and + (cell.row <> invalidaxis) then begin + docellevent(cellinfopo^); + if not (es_processed in mouseeventinfopo^.eventstate) then begin + fixrows[cell.row].buttoncellevent(cellinfopo^); + end; + end + else begin + docellevent(cellinfopo^); + end; + finally + addpoint1(info.pos,flastcellpos); + end; + end; + end; +end; + +procedure tcustomgrid.dofocusedcellposchanged; +begin + //dummy +end; + +function tcustomgrid.isfirstrow: boolean; +begin + result:= (ffocusedcell.row <= 0); +end; + +function tcustomgrid.islastrow: boolean; +begin + result:= (ffocusedcell.row < 0) or (ffocusedcell.row = rowhigh); +end; + +function tcustomgrid.selectcell(const cell: gridcoordty; + const amode: cellselectmodety; + const checkmultiselect: boolean = false): boolean; + //calls onselectcell +var + info: celleventinfoty; + bo1: boolean; + int1: integer; +begin + initeventinfo(cell,cek_select,info); + info.accept:= true; + case amode of + csm_reverse: begin + info.selected:= not fdatacols.selected[cell]; + end; + csm_select: begin + info.selected:= true; + end; + else begin + info.selected:= false; + end; + end; + if (amode = csm_reverse) or + (cell.row = invalidaxis) or (cell.col = invalidaxis) or + (info.selected <> fdatacols.selected[cell]) then begin + bo1:= info.selected; + docellevent(info); + result:= info.accept; + if result then begin + bo1:= bo1 and checkmultiselect; + if bo1 then begin + beginupdate; + end; + try + if bo1 then begin + if fdatacols.foptions * + [co_multiselect,co_rowselect] = [co_rowselect] then begin + if fdatacols.fselectedrow >= 0 then begin + fdatacols.rowselected[fdatacols.fselectedrow]:= false; + end + else begin + if fdatacols.fselectedrow = -2 then begin + fdatacols.rowselected[invalidaxis]:= false; + end; + end; + end; + for int1:= 0 to fdatacols.count - 1 do begin + with tdatacol(fdatacols.fitems[int1]) do begin + if not (co_multiselect in foptions) then begin + selected[invalidaxis]:= false; + end; + end; + end; + end; + if (cell.col >= 0) and + (co_rowselect in fdatacols[cell.col].foptions) then begin +// fdatacols.selected[makegridcoord(invalidaxis,cell.row)]:= info.selected; + fdatacols.rowselected[cell.row]:= info.selected; + end + else begin + fdatacols.selected[cell]:= info.selected; + end; + finally + if bo1 then begin + endupdate; + end; + end; + end; + end + else begin + result:= true; + end; +end; + +function tcustomgrid.canexitrow(const force: boolean = false): boolean; +begin + if force then begin + include(fstate1,gs1_forcenullcheck); + end; + try + result:= container.canclose(nil); + //for notnull check in twidgetgrid + finally + exclude(fstate1,gs1_forcenullcheck); + end; +end; + +procedure tcustomgrid.checkmorerows(const acount: integer); + //<0 -> before +begin + if canevent(tmethod(fongetmorerows)) then begin + fongetmorerows(self,acount); + end; +end; + +procedure tcustomgrid.beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); +begin + if (og1_focusmorerows in foptionsgrid1) and + (cell.row <> invalidaxis) then begin + if cell.row >= frowcount then begin + checkmorerows(cell.row - frowcount + 1); + end + else begin + if cell.row < 0 then begin + checkmorerows(cell.row); + end; + end; + end; +end; + +procedure tcustomgrid.afterfocuscell(const cellbefore: gridcoordty; + const selectaction: focuscellactionty); +var + info: celleventinfoty; +begin + initeventinfo(ffocusedcell,cek_focusedcellchanged,info); + info.cellbefore:= cellbefore; + info.newcell:= ffocusedcell; + info.selectaction:= selectaction; + docellevent(info); +end; + +function tcustomgrid.focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; + + function isappend(const arow: integer): boolean; + begin + result:= canappendrow and + (not (gs_isdb in fstate) and not (gs1_autoappendlock in fstate1) and + ((og_autoappend in foptionsgrid) and + (arow >= frowcount) and (frowcount <> 0) or + (arow = 0) and (frowcount = 0) and (og_autofirstrow in foptionsgrid))); + end; + + procedure doselectaction; + + procedure startanchors; + begin + fstartanchor:= cell; + fendanchor:= invalidcell; + end; + + procedure changeselectedrange(rows: boolean); + type + rectaccessty = record pos: integer; dummy: integer; count: integer end; + var + rect1: gridrectty; + int1: integer; + po1,po3: pinteger; + po2: ^rectaccessty; + begin + rect1:= self.getselectedrange; + if rows then begin + po1:= @cell.row; + po2:= @rect1.row; + po3:= @fstartanchor.row; + end + else begin + po1:= @cell.col; + po2:= @rect1.col; + po3:= @fstartanchor.col; + end; + if po1^ < po2^.pos then begin + po2^.count:= po2^.pos - po1^; + po2^.pos:= po1^; + fdatacols.setselectedrange(rect1,true,true,true); + end + else begin + if po1^ >= po3^ then begin //right side + int1:= po1^ - po2^.pos - po2^.count; + if int1 >= 0 then begin + po2^.pos:= po2^.pos + po2^.count; + po2^.count:= int1 + 1; + fdatacols.setselectedrange(rect1,true,true,true); + end + else begin + po2^.pos:= po1^ + 1; + po2^.count:= -int1 - 1; + fdatacols.setselectedrange(rect1,false,true,true); + end; + end + else begin //left side + int1:= po2^.pos - po1^; + if int1 >= 0 then begin + po2^.pos:= po1^; + po2^.count:= int1; + fdatacols.setselectedrange(rect1,true,true,true); + end + else begin + po2^.count:= -int1; + fdatacols.setselectedrange(rect1,false,true,true); + end; + end; + end; + end; + + procedure doselectcell(const mode: cellselectmodety); + begin + case selectmode of + scm_row: begin + selectcell(makegridcoord(invalidaxis,cell.row),mode,true); + end; + scm_col: begin + selectcell(makegridcoord(cell.col,invalidaxis),mode,true); + end; + else begin + selectcell(cell,mode,true); + end; + end; + end; + + var + cells,celle: gridcoordty; + rect1: gridrectty; + int1: integer; + + begin //doselectaction + beginupdate; + try + case selectaction of + fca_entergrid,fca_focusin,fca_focusinshift,fca_focusinrepeater, + fca_focusinforce,fca_setfocusedcell: begin + if (selectaction <> fca_entergrid) then begin + if not (og1_noresetselect in foptionsgrid1) then begin + fdatacols.selected[invalidcell]:= false; + end; + end; + startanchors; + if isdatacell(cell) and (co_focusselect in fdatacols[cell.col].foptions) then begin + doselectcell(csm_select); + end; + end; + fca_reverse: begin + doselectcell(csm_reverse); + startanchors; + end; + fca_selectstart: begin + fdatacols.selected[invalidcell]:= false; + doselectcell(csm_select); + startanchors; + end; + fca_selectend: begin + getselectedrange; //ev. adjust startanchor to rowcount + if fstartanchor.col < 0 then begin + fstartanchor:= ffocusedcell; + end; + if fstartanchor.col >= 0 then begin + cells:= fstartanchor; + celle:= cell; + case selectmode of + scm_row: begin + cells.col:= 0; + celle.col:= fdatacols.count - 1; + end; + scm_col: begin + cells.row:= 0; + celle.row:= rowhigh; + end; + end; + if fendanchor.col >= 0 then begin + case selectmode of + scm_row: begin + celle.col:= cells.col; + end; + scm_col: begin + celle.row:= cells.row; + end; + end; + if gs_islist in fstate then begin + fdatacols.changeselectedrange(fstartanchor,fendanchor,cell,true); + end + else begin //todo: optimize for selectmode <> scm_cell + if (selectmode <> scm_cell) or ((cell.col >= fstartanchor.col) xor + (fendanchor.col >= fstartanchor.col)) or + ((cell.row >= fstartanchor.row) xor + (fendanchor.row >= fstartanchor.row)) then begin + rect1:= makegridrect(celle,cells); + fdatacols.selected[invalidcell]:= false; + fdatacols.setselectedrange(rect1,true,true,true); + case selectmode of + scm_row: begin + beginupdate; + rect1.col:= invalidaxis; + for int1:= rect1.rowcount - 1 downto 0 do begin + fdatacols.selected[rect1.pos]:= true; + inc(rect1.row); + end; + endupdate; + end; + scm_col: begin + beginupdate; + rect1.row:= invalidaxis; + for int1:= rect1.colcount - 1 downto 0 do begin + fdatacols.selected[rect1.pos]:= true; + inc(rect1.col); + end; + endupdate; + end; + end; + end + else begin + changeselectedrange(false); + fendanchor.col:= cell.col; + changeselectedrange(true); + end; + end; + end + else begin + if celle.col < cells.col then begin + dec(celle.col); + end + else begin + inc(celle.col); + end; + if celle.row < cells.row then begin + dec(celle.row); + end + else begin + inc(celle.row); + end; + fdatacols.setselectedrange(cells,celle,true,true,true); + end; + end; + fendanchor:= cell; + end; + end; + finally + ffocusedcell:= cell; + endupdate(true); + end; + end; //doselectaction() + +var + sortchecked: boolean; + + procedure dosortcheck(const isappend: boolean); //follow sort order + var + int1: integer; + begin + if not sortchecked and not isautoappend then begin + sortchecked:= true; + int1:= cell.row - ffocusedcell.row; + if (int1 <> 0) or (selectaction = fca_focusinforce) then begin + checksort; + if cell.row >= 0 then begin + if (cell.row >= 0) and (ffocusedcell.row >= 0) then begin + cell.row:= ffocusedcell.row + int1; + if cell.row < 0 then begin + cell.row:= 0; + end; + if isappend then begin + if cell.row > frowcount then begin + cell.row:= frowcount; + end; + end + else begin + if cell.row >= frowcount then begin + cell.row:= frowcount-1; + end; + end; + end; + end; + end; + end; + end; //dosortcheck + +var + focuscount: integer; + coord1,coord2: gridcoordty; + bo1,bo2,bo3: boolean; + int1: integer; + rect1: rectty; + nullchecklocked: boolean; + cellbefore: gridcoordty; + rowcountbefore: integer; + autorowappended: boolean; + +begin //focuscell + if selectaction <> fca_exitgrid then begin + if (cell.row > invalidaxis) and (cell.col > invalidaxis) then begin + rect1:= cellrect(cell); + with rect1 do begin + bo1:= (cell.row >= 0); + if bo1 then begin + int1:= fdatarect.y - y; + bo1:= (int1 > 0) and (int1 < fdatarect.cy); + end; + if not bo1 then begin + bo1:= (cell.col >= 0) and (cell.col < fdatacols.count) and + not (co_nohscroll in tcol(fdatacols.fitems[cell.col]).foptions); + if bo1 then begin + int1:= fdatarect.x - x; + bo1:= (int1 > 0) and (int1 < fdatarect.cx); + end; + end; + if bo1 then begin + update; //scrolling needed, update pending paintings with old focused cell + end; + end; + end; + end; + inc(ffocuscount); + focuscount:= ffocuscount; + beforefocuscell(cell,selectaction); + if focuscount <> ffocuscount then begin + exit; + end; + result:= false; + exclude(fstate,gs_mousecellredirected); + nullchecklocked:= false; + if ffocusedcell.row = cell.row then begin + nullchecklocked:= true; + beginnonullcheck; + end; + autorowappended:= (ffocusedcell.row = frowcount-1) and isautoappend; + rowcountbefore:= frowcount; + try + if (fnocheckvalue = 0) and not (gs_rowremoving in fstate) then begin + int1:= ffocusedcell.row; + if ((cell.row <> ffocusedcell.row) or (cell.col <> ffocusedcell.col) or + (selectaction = fca_focusinforce)) and + not docheckcellvalue or (focuscount <> ffocuscount) then begin + exit; + end; + if cell.row = int1 then begin + cell.row:= ffocusedcell.row; //follow possible change by sort + end; + if ((cell.row <> ffocusedcell.row) or (selectaction = fca_focusinforce)) and + (ffocusedcell.row >= 0) and container.entered and + not ((gs1_rowdeleting in fstate1) or + container.canclose(window.focusedwidget)) then begin + //for notnull check in twidgetgrid + + exit; + end; + end; + if (selectaction in [fca_focusin,fca_focusinrepeater,fca_focusinforce]) and + ((cell.col < 0) or (cell.col >= fdatacols.count) or + not fdatacols[cell.col].canfocus(mb_none,[],false,bo1)) then begin + selectaction:= fca_setfocusedcell; + end; + if selectaction = fca_entergrid then begin + if cell.row < 0 then begin + cell.row:= 0; + end; + if cell.col < 0 then begin + cell.col:= 0; + end; + cell.col:= nextfocusablecol(cell.col,false,cell.row,true); + if (gs_hasactiverowcolor in fstate) and (cell.row < frowcount) then begin + invalidaterow(cell.row); + end; + end; + if cell.row < 0 then begin + cell.row:= invalidaxis; + end; + if cell.col < 0 then begin + cell.col:= invalidaxis; + end; + if (cell.row >= 0) and (cell.col >= 0) then begin + if cell.col >= fdatacols.count then begin + cell.col:= fdatacols.count - 1; + if cell.col < 0 then begin + exit; + end; + end; + if (cell.row >= frowcount) and not isappend(cell.row) then begin + cell.row:= frowcount - 1; + if cell.row < 0 then begin + if selectaction = fca_entergrid then begin + cell.row:= invalidaxis; + end + else begin + exit; + end; + end; + end; + cell.col:= mergestart(cell.col,cell.row); + end; + bo1:= ((cell.col <> invalidaxis) or (cell.row <> invalidaxis)) and + (ashowcell <> cep_none); + if (cell.col <> ffocusedcell.col) or (cell.row <> ffocusedcell.row) or + (selectaction in [fca_entergrid,fca_focusinforce]) or + (gs_restorerow in fstate) then begin + exclude(fstate,gs_restorerow); + coord1:= ffocusedcell; + if (selectaction <> fca_entergrid) and isdatacell(coord1) then begin + include(fstate,gs_cellexiting); + fdatacols[coord1.col].internaldoexitcell(coord1,cell,selectaction); + exclude(fstate,gs_cellexiting); + if ffocuscount <> focuscount then begin + exit; + end; + end + else begin + coord1:= invalidcell; + end; + sortchecked:= false; + if isappend(cell.row) then begin + dosortcheck(true); + if (frowcount = 0) or (og_appendempty in foptionsgrid) or + not fdatacols.rowempty(frowcount-1) then begin + cell.row:= frowcount; + if fdatacols.fnewrowcol >= 0 then begin + cell.col:= fdatacols.fnewrowcol; + end; + bo2:= gs1_sortchangelock in fstate1; + include(fstate1,gs1_sortchangelock); + bo3:= gs1_autoappending in fstate1; + include(fstate1,gs1_autoappending); + try + insertrow(frowcount,1,og1_forcerowsmodified in foptionsgrid1); + include(fstate1,gs1_rowsortinvalid); + if ffocuscount <> focuscount then begin + focuscell(mgc(ffocusedcell.col,cell.row)); + exit; + end; + autorowappended:= true; + finally + if not bo2 then begin + exclude(fstate1,gs1_sortchangelock); + end; + if not bo3 then begin + exclude(fstate1,gs1_autoappending); + end; + end; + end + else begin + factiverow:= coord1.row; + include(fstate,gs_restorerow); + focuscell(coord1,selectaction); //restore previous row + exit; + end; + end; +// else begin + if cell.row >= frowcount then begin + cell.row:= frowcount - 1; + if cell.row < 0 then begin + cell.row:= invalidaxis; + end; + end; +// end; + cellbefore:= ffocusedcell; + if (selectaction = fca_exitgrid) or + ((cell.row <> ffocusedcell.row) and + (coord1.row >= 0) and + ((coord1.row >= frowcount-1) and (cell.row < coord1.row) or + not autorowappended and + ((cell.row <= rowcountbefore{-1}) and not (gs_restorerow in fstate) or + (cell.row < frowcount) + ) + ) + ) then begin + int1:= ffocusedcell.row; + ffocusedcell.row:= invalidaxis; + updaterowdata; //for twidgetgrid, data invalid + bo2:= false; + if (int1 <> cell.row) and doremoveappinsrow(int1,cell.row) then begin + if (cell.row > int1) then begin + dec(cell.row); + bo2:= true; + end; + end; + if int1 >= frowcount then begin + int1:= frowcount-1; + end; + if (int1 >= 0) and not ((selectaction = fca_exitgrid) and + (gs_rowremoving in fstate)) and + ((cell.row >= 0) or (selectaction = fca_exitgrid)) then begin + ffocusedcell.row:= int1; +// if bo2 and (cell.row = cell.row) then begin +// updaterowdata; //no focusin data update +// end; + end; + if ffocusedcell.row >= 0 then begin + updaterowdata; //current values + end; + end; + dosortcheck(false); + + if not (selectaction in [fca_exitgrid,fca_entergrid]) then begin + ffocusedcell:= invalidcell; + end; + if selectaction = fca_exitgrid then begin + factiverow:= ffocusedcell.row; + for int1:= 0 to fdatacols.count - 1 do begin + if co_resetselectonexit in fdatacols[int1].foptions then begin + fdatacols.selected[makegridcoord(int1,-1)]:= false; + end; + end; + if gs_emptyrowremoved in fstate then begin + cell:= ffocusedcell; + selectaction:= fca_focusin; + doselectaction; + end; + end + else begin + doselectaction; +// ffocusedcell:= cell; moved to doselectaction + end; + if bo1 then begin + showcell(cell,ashowcell); + end; + if isdatacell(cell) then begin + checkrowreadonlystate; + coord2:= cell; + fdatacols[cell.col].internaldoentercell(coord1,cell,selectaction); + if ffocuscount <> focuscount then begin + exit; + end; + if ((cell.col <> coord2.col) or (cell.row <> coord2.row)) then begin + focuscell(cell,selectaction); + exit; + end; + end; + if (gs_hasactiverowcolor in fstate) and + (ffocusedcell.row <> cellbefore.row) then begin + if cellbefore.row >= 0 then begin + invalidaterow(cellbefore.row); + end; + if ffocusedcell.row >= 0 then begin + invalidaterow(ffocusedcell.row); + end; + end; + end + else begin //cell = ffocusedcell + cellbefore:= ffocusedcell; + if bo1 then begin + showcell(cell,ashowcell); + end; + if not (selectaction in [fca_focusin,fca_focusinrepeater, + fca_setfocusedcell,fca_none]) then begin + doselectaction; + end; + end; + finally + if nullchecklocked then begin + endnonullcheck; + end; + end; + factiverow:= ffocusedcell.row; + afterfocuscell(cellbefore,selectaction); + flastcol:= ffocusedcell.col; + result:= true; +end; + +function tcustomgrid.defocuscell: boolean; +begin + result:= focuscell(invalidcell{,fca_none}); +end; + +function tcustomgrid.defocusrow: boolean; +begin + result:= focuscell(makegridcoord(ffocusedcell.col,invalidaxis){,fca_none}); +end; + +function tcustomgrid.focusedcellvalid: boolean; +begin + result:= (ffocusedcell.col >= 0) and (ffocusedcell.row >= 0) and + not (gs_cellexiting in fstate); +end; + +function tcustomgrid.rowremoving: boolean; +begin + result:= gs_rowremoving in fstate; +end; + +function tcustomgrid.scrollingcol: boolean; + //true if focusedcolvalid and no co_nohscroll +begin + result:= (ffocusedcell.col >= 0) and + not (co_nohscroll in fdatacols[ffocusedcell.col].foptions); +end; + +function tcustomgrid.noscrollingcol: boolean; + //true if focusedcolvalid and co_nohscroll +begin + result:= (ffocusedcell.col >= 0) and + (co_nohscroll in fdatacols[ffocusedcell.col].foptions); +end; + +function tcustomgrid.cellexiting: boolean; +begin + result:= gs_cellexiting in fstate; +end; + +function tcustomgrid.isinsertempty: boolean; +begin + result:= (gs1_rowinserted in fstate1) and + (og_noinsertempty in foptionsgrid) and + (ffocusedcell.row >= 0) and fdatacols.rowempty(ffocusedcell.row); +end; + +function tcustomgrid.isautoappend: boolean; + //true if last row is auto appended + //todo: simplify, use gs1_rowinserted +begin + result:= not (gs_isdb in fstate) and (frowcount > 0) and + ((frowcount = 1) and (og_autofirstrow in foptionsgrid) or + (foptionsgrid * [og_autoappend,og_appendempty] = [og_autoappend]) + ) and fdatacols.rowempty(frowcount - 1); +end; + +function tcustomgrid.autoappending: boolean; +begin + result:= gs1_autoappending in fstate1; +end; + +function tcustomgrid.autoremoving: boolean; +begin + result:= gs1_autoremoving in fstate1; +end; + +function tcustomgrid.doremoveappinsrow(const oldrow,newrow: integer): boolean; +var + b1: boolean; +begin + result:= false; + if not (gs_isdb in fstate) then begin + b1:= gs1_autoremoving in fstate1; + include(fstate1,gs1_autoremoving); + try + if gs1_rowinserted in fstate1 then begin + if (og_noinsertempty in foptionsgrid) and + (oldrow >= 0) and fdatacols.rowempty(oldrow) then begin + fstate1:= fstate1-[gs1_rowinserted,gs1_rowsortinvalid]; + if not (gs_rowremoving in fstate) then begin + result:= true; + deleterow(oldrow); + end; + exit; + end; + end + else begin + if (newrow <> frowcount-1) and (oldrow = frowcount-1) and + isautoappend then begin + if row >= 0 then begin + if row = 0 then begin + row:= invalidaxis; + end + else begin + row:= newrow-1; + end; + end + else begin + if newrow = frowcount-1 then begin + exclude(fstate1,gs1_rowsortinvalid); + end; + if not (gs_rowremoving in fstate) and + not (og_appendempty in optionsgrid) then begin + result:= true; + deleterow(frowcount-1,1,og1_forcerowsmodified in foptionsgrid1); + include(fstate,gs_emptyrowremoved); + end; + end; + end + end; + finally + if not b1 then begin + exclude(fstate1,gs1_autoremoving); + end; + end; + end; + exclude(fstate1,gs1_rowinserted); +end; + +procedure tcustomgrid.removeappendedrow; +begin + docheckcellvalue; + doremoveappinsrow(row,invalidaxis); +end; + +function tcustomgrid.hasdata: boolean; +begin + result:= (rowcount > 1) or (rowcount = 1) and not isautoappend; +end; + +function tcustomgrid.gridprop(const coord: gridcoordty): tgridprop; //nil if none +begin + result:= nil; + with coord do begin + if row < 0 then begin + if row >= - ffixrows.count then begin + result:= tgridprop(ffixrows.fitems[-1-row]); + exit; + end; + end; + if {(row = invalidaxis) or} (row >= 0) and (row < frowcount) then begin + if col < 0 then begin + if col >= -fixcols.count then begin + result:= tgridprop(ffixcols.fitems[-1-col]); + exit; + end; + end + else begin + if col < fdatacols.count then begin + result:= tgridprop(fdatacols.fitems[col]); + exit; + end; + end; + end; + end; +end; + +function tcustomgrid.isdatacell(const coord: gridcoordty): boolean; +begin + with coord do begin + result:= (col >= 0) and (row >= 0) and + (col < fdatacols.count) and (row < frowcount); + end; +end; + +function tcustomgrid.isvalidcell(const coord: gridcoordty): boolean; +begin + with coord do begin + result:= (col < fdatacols.count) and (col >= -ffixcols.count) and + (row < frowcount) and (row >= -ffixrows.count); + end; +end; + +function tcustomgrid.isfixrow(const coord: gridcoordty): boolean; +begin + with coord do begin + result:= (row < 0) and (fixrows.count + row >= 0); + end; +end; + +function tcustomgrid.isfixcol(const coord: gridcoordty): boolean; +begin + with coord do begin + result:= (col < 0) and (fixcols.count + col >= 0); + end; +end; + +procedure tcustomgrid.checkdatacell(const coord: gridcoordty); +begin + if not isdatacell(coord) then begin + datacellerror(coord); + end; +end; + +procedure tcustomgrid.datacellerror(const coord: gridcoordty); +begin + error(gre_invaliddatacell,gridcoordtotext(coord)); +end; + +procedure tcustomgrid.error(aerror: griderrorty; text: string); +begin + if aerror <> gre_ok then begin + if text <> '' then begin + raise tgridexception.create(errorstrings[aerror]+' '+text+'.'); + end + else begin + raise tgridexception.create(errorstrings[aerror]+'.'); + end; + end; +end; + +procedure tcustomgrid.indexerror(row: boolean; index: integer; text: string); +begin + if row then begin + error(gre_colindex,text+' '+inttostr(index)); + end + else begin + error(gre_rowindex,text+' '+inttostr(index)); + end; +end; + +procedure tcustomgrid.scrollrows(step: integer); +var + int1: integer; +begin + if og1_scrollmorerows in foptionsgrid1 then begin + if step > 0 then begin + int1:= firstvisiblerow - step; + if int1 < 0 then begin + checkmorerows(int1); + end; + end + else begin + int1:= lastvisiblerow - step - rowcount+1; + if int1 > 0 then begin + checkmorerows(int1); + end; + end; + end; + if canevent(tmethod(fonscrollrows)) then begin + fonscrollrows(self,step); + end; + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(0,ystep*step)); +end; + +procedure tcustomgrid.scrollleft; +var + int1: integer; + coord1: gridcoordty; + rect1: rectty; +begin + if fdatacols.scrollablecount <= 1 then begin + tgridframe(fframe).scrollpos:= subpoint(tgridframe(fframe).scrollpos, + makepoint(fdatarect.cx div 10 + 1,0)); + end + else begin + cellatpos(makepoint(fdatarect.x+fdatarect.cx-1,fdatarect.y),coord1); + if coord1.col >= 0 then begin + rect1:= cellrect(coord1); + if rect1.x + rect1.cx = fdatarect.x + fdatarect.cx then begin + if coord1.col < fdatacols.Count - 1 then begin + rect1:= cellrect(makegridcoord(coord1.col+1,coord1.row)); + end + else begin + rect1.x:= fdatarect.x + fdatarect.cx - rect1.cx; + end; + end; + int1:= fdatarect.x + fdatarect.cx - rect1.x - rect1.cx; + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(int1,0)); + end; + end; +end; + +procedure tcustomgrid.scrollright; +var + int1: integer; + coord1: gridcoordty; + rect1: rectty; +begin + if fdatacols.scrollablecount <= 1 then begin + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(fdatarect.cx div 10 + 1,0)); + end + else begin + cellatpos(fdatarect.pos,coord1); + if coord1.col >= 0 then begin + rect1:= cellrect(coord1); + if rect1.x = fdatarect.x then begin + if coord1.col > 0 then begin + rect1:= cellrect(makegridcoord(coord1.col-1,coord1.row)); + end + else begin + rect1.x:= fdatarect.x; + end; + end; + int1:= fdatarect.x - rect1.x; + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(int1,0)); + end; + end; +end; + +procedure tcustomgrid.scrollpageleft; +var + int1,int2: integer; + coord1: gridcoordty; + rect1: rectty; +begin + if fdatacols.scrollablecount <= 1 then begin + tgridframe(fframe).scrollpos:= subpoint(tgridframe(fframe).scrollpos, + makepoint(fdatarect.cx,0)); + end + else begin + cellatpos(fdatarect.pos,coord1); + if coord1.col >= 0 then begin + rect1:= cellrect(coord1); + int2:= fdatacols[coord1.col].step; + for int1:= coord1.col to datacols.count - 1 do begin + inc(int2,fdatacols[int1].step); + if int2 > fdatarect.cx then begin + dec(int2,fdatacols[int1].step); + break; + end; + end; + int2:= int2 + rect1.x; + tgridframe(fframe).scrollpos:= subpoint(tgridframe(fframe).scrollpos, + makepoint(int2,0)); + end; + end; +end; + +procedure tcustomgrid.scrollpageright; +var + int1,int2: integer; + coord1: gridcoordty; + rect1: rectty; +begin + if fdatacols.scrollablecount <= 1 then begin + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(fdatarect.cx,0)); + end + else begin + cellatpos(fdatarect.pos,coord1); + if coord1.col >= 0 then begin + rect1:= cellrect(coord1); + int2:= -rect1.x; + if coord1.col > 0 then begin + inc(int2,fdatacols[coord1.col-1].step); + end; + for int1:= coord1.col - 1 downto 0 do begin + inc(int2,fdatacols[int1].step); + if int2 > fdatarect.cx then begin + dec(int2,fdatacols[int1].step); + break; + end; + end; + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(int2,0)); + end; + end; +end; + +function tcustomgrid.calcshowshift(const rect: rectty; const position: cellpositionty): pointty; +var + po1,po2: pointty; +begin + po1:= nullpoint; //left, up + po2:= nullpoint; //right, down + with rect do begin + po1.x:= fdatarect.x + fdatarect.cx - (x + cx); //rangeend-endpos + po2.x:= fdatarect.x - x; //rangestart-startpos + case position of + cep_nearest: begin + if po1.x >= 0 then begin //no left shift + po1.x:= 0; + if po2.x <= 0 then begin //no right shift + po2.x:= 0; + end; + end + else begin //left shift + if po2.x >= 0 then begin //right shift + po2.x:= 0; //no change + po1.x:= 0; + end + else begin + if po2.x >= 0 then begin //right shift + po1.x:= 0; //no left shift + end + else begin + if po1.x - po2.x < 0 then begin //left shift to big + po1.x:= 0; //shift to left margin + end + else begin + po2.x:= 0; //left shift + end; + end; + end; + end; + end; + else begin + po1.x:= 0; + po2.x:= 0; + end; + end; + po1.y:= fdatarect.y + fdatarect.cy - (y + cy); //rangeend-endpos + case position of + cep_nearest: begin + if po1.y > 0 then begin + po1.y:= 0; + end; + end; + end; + po2.y:= fdatarect.y - y; //rangestart-startpos + case position of + cep_nearest: begin + if po2.y <= 0 then begin + po2.y:= 0; + end + else begin + po1.y:= 0; + end; + end; + cep_rowcentered: begin + po1.y:= -(y - fdatarect.y - (fdatarect.cy - cy) div 2); + po2.y:= 0; + end; + cep_rowcenteredif: begin + if (po1.y < 0) or (po2.y > 0) then begin + result:= calcshowshift(rect,cep_rowcentered); + end + else begin + result:= nullpoint; + end; + exit; + end; + cep_top: begin + po1.y:= 0; + end; + cep_bottom: begin + po2.y:= 0; + end; + else begin + po1.y:= 0; + po2.y:= 0; + end; + end; + end; + result:= addpoint(po1,po2); +end; + +function tcustomgrid.showrect(const rect: rectty; + const position: cellpositionty = cep_nearest; + const noxshift: boolean = false): pointty; +var + po1: pointty; + int1: integer; +begin + with tgridframe(fframe) do begin + result:= scrollpos; + po1:= calcshowshift(rect,position); + if noxshift then begin + po1.x:= 0; + end; + if (po1.x <> 0) then begin + int1:= po1.x + result.x + fscrollrect.cx - + tgridframe(fframe).fpaintrect.x - tgridframe(fframe).fpaintrect.cx; + if int1 < 0 then begin + dec(po1.x,int1); + end; + int1:= po1.x + fscrollrect.x; + if int1 > 0 then begin + dec(po1.x,int1); + end; + end; + + scrollpos:= addpoint(result,po1); + result:= subpoint(scrollpos,result); + end; +end; + +function tcustomgrid.showcaretrect(const arect: rectty; + const aframe: framety): pointty; +var + rect1: rectty; +begin + if not window.activating and + ([gs_cellexiting,gs_layoutupdating] * fstate =[]) and + (fnoshowcaretrect = 0) and + not (frame.sbhorz.clicked or frame.sbvert.clicked) and + intersectrect(inflaterect(arect,aframe),cellrect(ffocusedcell),rect1) then begin + result:= showrect(rect1,cep_nearest,noscrollingcol); + end + else begin + result:= nullpoint; + end; +end; + +function tcustomgrid.showcaretrect(const arect: rectty; + const aframe: tcustomframe): pointty; +begin + if aframe <> nil then begin + result:= showcaretrect(arect,aframe.innerframe); + end + else begin + result:= showcaretrect(arect,nullframe); + end; +end; + +function tcustomgrid.showcellrect(const rect: rectty; + const origin: cellinnerlevelty = cil_paint): pointty; +var + rect1: rectty; +begin + if focusedcellvalid then begin + rect1:= cellrect(ffocusedcell,origin); + inc(rect1.x,rect.x); + inc(rect1.y,rect.y); + rect1.cx:= rect.cx; + rect1.cy:= rect.cy; + result:= showrect(rect1,cep_nearest,noscrollingcol); + end + else begin + result:= nullpoint; + end; +end; + +procedure tcustomgrid.showcell(const cell: gridcoordty; + const position: cellpositionty = cep_nearest; + const force: boolean = false); +var + coord1: gridcoordty; + rect1: rectty; + po1: pointty; +begin + if position = cep_none then begin + exit; + end; + if (fupdating > 0) then begin + include(fstate1,gs1_showcellinvalid); + fshowcell:= cell; + fshowcellmode:= position; + end + else begin + if force or not (frame.sbhorz.clicked or frame.sbvert.clicked) then begin + coord1:= cell; + with coord1 do begin + if col >= fdatacols.count then begin + col:= fdatacols.count - 1; + end; + if row >= frowcount then begin + row:= frowcount-1; + end; + rect1:= cellrect(coord1); //updatelayout + po1:= calcshowshift(rect1,position); + if (col < 0) or (co_nohscroll in fdatacols[col].foptions){noscrollingcol} then begin + po1.x:= 0; + end; + if coord1.row < 0 then begin + po1.y:= 0; + end; + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos,po1); + end; + end; + end; +end; + +procedure tcustomgrid.showrow(const arow: integer; + const position: cellpositionty = cep_nearest; + const force: boolean = false); +begin + showcell(mgc(invalidaxis,arow),position,force); +end; + +procedure tcustomgrid.showlastrow; +begin + showcell(makegridcoord(col,rowhigh)); +end; + +function tcustomgrid.cellrect(const cell: gridcoordty; + const innerlevel: cellinnerlevelty = cil_all; + const nomerged: boolean = false; + const acellorigin: boolean = false): rectty; + + procedure updatex(const aprop: tgridprop); + begin + with result,aprop do begin + case innerlevel of + cil_paint: begin + inc(x,fcellinfo.rect.x); + cx:= fcellinfo.rect.cx; + end; + cil_inner: begin + inc(x,fcellinfo.rect.x); + inc(x,fcellinfo.innerrect.x); + cx:= fcellinfo.innerrect.cx; + end; + end; + end; + end; + + procedure updatey(const aprop: tgridprop); + begin + with result,aprop do begin + case innerlevel of + cil_paint: begin + inc(y,fcellinfo.rect.y); + dec(cy,fdatarowheight-fcellinfo.rect.cy); +// cy:= fcellinfo.rect.cy; + end; + cil_inner: begin + inc(y,fcellinfo.rect.y); + inc(y,fcellinfo.innerrect.y); + dec(cy,fdatarowheight-fcellinfo.innerrect.cy); +// cy:= fcellinfo.innerrect.cy; + end; + end; + end; + end; + +var + isfixr: boolean; + int1,int2: integer; + po1: prowstatecolmergety; + +begin //cellrect + result:= nullrect; + if (cell.col >= fdatacols.count) or (cell.row >= frowcount) and + not(csdesigning in componentstate) then begin + exit; + end; + internalupdatelayout; + isfixr:= false; + with result,cell do begin + if row < 0 then begin + isfixr:= -row <= ffixrows.count; + if isfixr then begin + with ffixrows[row] do begin + if not acellorigin then begin + y:= fstart; + end; + cy:= fend-fstart; + if innerlevel = cil_noline then begin + dec(cy,linewidth); + if -row > ffixrows.count - ffixrows.oppositecount then begin + inc(y,linewidth); + end; + end; + updatey(ffixrows[row]); + if fframe <> nil then begin + with fframe do begin + if innerlevel >= cil_paint then begin + checkstate; + inc(x,fpaintframe.left); + dec(cx,fpaintframe.left + fpaintframe.right); + end; + if innerlevel >= cil_inner then begin + inc(x,fi.innerframe.left); + dec(cx,fi.innerframe.left + fi.innerframe.right); + end; + end; + end; + if not nomerged then begin + if col >= 0 then begin + if col < fcaptions.count then begin + with tcolheader(fcaptions.fitems[col]) do begin + if fmergeflags * [cmf_v,cmf_h] <> [] then begin + result:= cellrect(frefcell,innerlevel,false,acellorigin); + exit; + end; + inc(cx,fmergedcx); + inc(y,fmergedy); + inc(cy,fmergedcy); + end; + end; + end + else begin + int1:= -col - 1; + if int1 < fcaptionsfix.count then begin + with tcolheader(fcaptionsfix.fitems[int1]) do begin + if fmergeflags * [cmf_v,cmf_h] <> [] then begin + result:= cellrect(frefcell,innerlevel,false,acellorigin); + exit; + end; + inc(x,fmergedx); + inc(cx,fmergedcx); + inc(y,fmergedy); + inc(cy,fmergedcy); + end; + end; + end; + end; + end; + end + else begin //whole height + y:= 0; + cy:= tgridframe(fframe).finnerclientrect.cy; + end; + end + else begin //datarows + int1:= visiblerow(row); + if (int1 >= 0) or (csdesigning in componentstate) then begin + if (og_rowheight in foptionsgrid) and (int1 >= 0) then begin + fdatacols.frowstate.cleanrowheight(row); + fdatacols.frowstate.internalystep(row,y,cy); + if acellorigin then begin + y:= 0; + end; + end + else begin + cy:= fystep; + if not acellorigin then begin + if int1 < 0 then begin + y:= row * cy; + end + else begin + y:= int1 * cy; + end; + end; + end; + if not acellorigin then begin + y:= y + ffixrows.ffirstsize + fscrollrect.y; + end; + if innerlevel > cil_all then begin + int2:= fdatarowlinewidth; + if (og_rowheight in foptionsgrid) and + (row >= 0) and (row < frowcount) then begin + with prowstaterowheightty( + fdatacols.frowstate.getitempo(row))^.rowheight do begin + if linewidth > 0 then begin + int2:= linewidth-1; + end; + end; + end; + dec(cy,int2); + end; + if col < 0 then begin + if -col <= ffixcols.count then begin + updatey(ffixcols[col]); + end; + end + else begin + updatey(fdatacols[col]); + end; + end; + end; + if col < 0 then begin + if -col <= ffixcols.count then begin + with ffixcols[col] do begin + if not acellorigin then begin + x:= x + fstart; + end; + cx:= cx + fend - fstart; + if (innerlevel = cil_noline) or isfixr and + (innerlevel >= cil_noline) then begin + dec(cx,flinewidth); + if -cell.col > ffixcols.count - ffixcols.oppositecount then begin + inc(x,flinewidth); + end; + end; + if not isfixr then begin + updatex(ffixcols[col]); + end; + end; + end + else begin //whole width + x:= 0; + cx:= tgridframe(fframe).finnerclientrect.cx; + end; + end + else begin + with fdatacols[col] do begin + cx:= cx + fend-fstart; + if not acellorigin then begin + if co_nohscroll in foptions then begin + x:= x + fstart; + end + else begin + x:= x + fstart + ffixcols.ffirstsize + fdatacols.ffirstsize + + fscrollrect.x; + end; + end; + if (innerlevel >= cil_noline) or + isfixr and (innerlevel >= cil_noline) then begin + dec(cx,flinewidth); + if (co_nohscroll in foptions) and + (index >= fdatacols.ffirsthscrollindex) then begin + inc(x,flinewidth); + end; + end; + if not isfixr then begin + updatex(fdatacols[col]); + if (og_colmerged in foptionsgrid) and not nomerged then begin + if (row >= 0) and (row < frowcount) and + (col < fdatacols.flastvisiblecol) then begin + po1:= fdatacols.frowstate.getitempocolmerge(row); + if po1^.colmerge.merged <> 0 then begin //has merged cols + for int1:= col to fdatacols.flastvisiblecol-1 do begin + if (po1^.colmerge.merged = mergedcolall) or + (int1 < mergedcolmax) and (po1^.colmerge.merged and + bits[int1] <> 0) then begin + with tdatacol(fdatacols.fitems[int1+1]) do begin + if not (co_invisible in foptions) then begin + inc(result.cx,step); + end; + end; + end + else begin + break; + end; + end; + end; + end; + end; + end; + end; + end; + end; + if not acellorigin then begin + addpoint1(result.pos,pointty(tgridframe(fframe).fi.innerframe.topleft)); + end; +end; //cellrect + +function tcustomgrid.clippedcellrect(const cell: gridcoordty; + const innerlevel: cellinnerlevelty = cil_all): rectty; + //origin = paintrect.pos, clipped by datarect +begin + result:= cellrect(cell,innerlevel); + intersectdatarect(result); +end; + +procedure tcustomgrid.clientrectchanged; +begin + inherited; + if (componentstate * [csloading,csdestroying] = []) and + not (gs_updatelocked in fstate) then begin + layoutchanged; + updatevisiblerows; + end; +end; + +procedure tcustomgrid.drawcellbackground(const acanvas: tcanvas); +begin + with fdatacols[ffocusedcell.col] do begin + drawcellbackground(acanvas,fframe,fface); + end; +end; + +procedure tcustomgrid.drawcelloverlay(const acanvas: tcanvas); +begin + with fdatacols[ffocusedcell.col] do begin + drawcelloverlay(acanvas,fframe); + end; +end; + +procedure tcustomgrid.drawfocusedcell(const acanvas: tcanvas); +begin + fdatacols[ffocusedcell.col].drawcell(acanvas); +end; + +function tcustomgrid.getcaretcliprect: rectty; +begin + internalupdatelayout; + if noscrollingcol then begin + result:= fdatarecty; + end + else begin + result:= fdatarect; + end; +end; + +procedure tcustomgrid.scrolled(const dist: pointty); +begin + //dummy +end; + +procedure tcustomgrid.createdatacol(const index: integer; + out item: tdatacol); +begin + //dummy +end; + +function tcustomgrid.rowvisible(const arow: integer): integer; +var + rect1: rectty; +begin + internalupdatelayout; + rect1:= cellrect(makegridcoord(0,arow)); + if rect1.y < fdatarect.y then begin + result:= -1; + end + else begin + if rect1.y + rect1.cy > fdatarect.y + fdatarect.cy then begin + result:= 1; + end + else begin + result:= 0; + end; + end; +end; + +function tcustomgrid.rowsperpage: integer; +begin + internalupdatelayout; + result:= fdatarect.cy div ystep; +end; + +procedure tcustomgrid.focusrow(const arow: integer; + const action: focuscellactionty; + const noreadonly: boolean; + const selectmode: selectcellmodety = scm_cell); +var + int1,int2: integer; +begin + int1:= flastcol; + focuscell(makegridcoord( + nextfocusablecol(flastcol,false,arow,noreadonly),arow),action,selectmode); + int2:= mergestart(flastcol,ffocusedcell.row); + if (int2 <= int1) and (mergeend(flastcol,ffocusedcell.row) > int1) or + (int2 > 0) and not (co_nofocus in datacols[int2].options) then begin + flastcol:= int1; + end; +end; + +procedure tcustomgrid.rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean=false); +begin + if ffocusedcell.row = 0 then begin + checkmorerows(-1); + end; + with fdatacols.frowstate do begin + if visiblerowcount > 0 then begin + if (ffocusedcell.row > 0) or not (og_wraprow in foptionsgrid) then begin + focusrow(visiblerowstep(ffocusedcell.row,-1,false),action,false); + end + else begin + if not nowrap and (og_wraprow in foptionsgrid) then begin + focusrow(visiblerowstep(frowcount-1,0,false),action,false); + end; + end; + end; + end; +end; + +procedure tcustomgrid.rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean=false); +//var +// int1: integer; +begin + if ffocusedcell.row = frowcount - 1 then begin + checkmorerows(1); + end; + with fdatacols.frowstate do begin + if visiblerowcount > 0 then begin + if not (og_wraprow in foptionsgrid) or + (visiblerow(ffocusedcell.row) < visiblerowcount - 1) then begin + focusrow(visiblerowstep(ffocusedcell.row,1,og_autoappend in foptionsgrid), + action,false); + end + else begin + if not nowrap and (og_wraprow in foptionsgrid) then begin + focusrow(visiblerowstep(0,0,false),action,false); + end; + end; + end; + end; +end; + +procedure tcustomgrid.pageup(const action: focuscellactionty = fca_focusin); +var + int1: integer; +begin + if (ffocusedcell.row >= 0) then begin + int1:= ffocusedcell.row - rowsperpage; + if int1 < 0 then begin + checkmorerows(int1); + end; + end; + with fdatacols.frowstate do begin + if visiblerowcount > 0 then begin + int1:= visiblerowstep(ffocusedcell.row,-rowsperpage+1,false); + if visiblerow(int1) < visiblerowcount then begin + scrollrows(rowsperpage - 1); + focusrow(int1,action,false); + end; + end; + end; +end; + +procedure tcustomgrid.pagedown(const action: focuscellactionty = fca_focusin); +var + int1: integer; +begin + int1:= (ffocusedcell.row+rowsperpage)-frowcount+1; + if int1 > 0 then begin + checkmorerows(int1); + end; + with fdatacols.frowstate do begin + if visiblerowcount > 0 then begin + int1:= visiblerowstep(ffocusedcell.row,rowsperpage-1,false); + if int1 >= 0 then begin + scrollrows(-(rowsperpage - 1)); + focusrow(int1,action,false); + end; + end; + end; +end; + +procedure tcustomgrid.wheelup(const action: focuscellactionty = fca_focusin); +var + int1: integer; +begin + int1:= ffocusedcell.row - wheelheight; + if int1 < 0 then begin + int1:= 0; + end; + if int1 < frowcount then begin + scrollrows(wheelheight); + focusrow(int1,action,false); + end; +end; + +procedure tcustomgrid.wheeldown(const action: focuscellactionty = fca_focusin); +var + int1: integer; +begin + int1:= ffocusedcell.row + wheelheight; + if int1 > frowcount - 1 then begin + int1:= frowcount -1; + end; + if int1 >= 0 then begin + scrollrows(-wheelheight); + focusrow(int1,action,false); + end; +end; + +procedure tcustomgrid.firstrow(const action: focuscellactionty = fca_focusin); +begin + if frowcount > 0 then begin + focusrow(0,action,false); + end; +end; + +procedure tcustomgrid.lastrow(const action: focuscellactionty = fca_focusin); +begin + if frowcount > 0 then begin + focusrow(frowcount-1,action,false); + end; +end; + +procedure tcustomgrid.domousewheelevent(var info: mousewheeleventinfoty); +begin + if not (es_transientfor in info.eventstate) or + not (gs_isdb in fstate) then begin + frame.domousewheelevent(info,fwheelscrollheight = -1); + end; + inherited; +end; + +function tcustomgrid.canautoappend: boolean; +begin + result:= (rowcount = 0) and (og_autofirstrow in foptionsgrid) and canappendrow; +end; + +function tcustomgrid.checkreautoappend: boolean; +begin + result:= (og_focuscellonenter in foptionsgrid) and + canautoappend and entered and (row < 0); + if result then begin + row:= 0; + end; +end; + +procedure tcustomgrid.dokeydown(var info: keyeventinfoty); +var + action,actioncol: focuscellactionty; + focusbefore: gridcoordty; + mo1: cellselectmodety; + celleventinfo: celleventinfoty; + cellbefore: gridcoordty; + bo1: boolean; + shiftstate: shiftstatesty; + + procedure checkselection; + begin + if (es_processed in info.eventstate) then begin + if not checkreautoappend and (ffocusedcell.col >= 0) then begin + if co_keyselect in fdatacols[ffocusedcell.col].foptions then begin + if ss_shift in shiftstate then begin + if fstartanchor.col < 0 then begin + fstartanchor:= focusbefore; + end; + action:= fca_selectend; + end + else begin + action:= fca_focusin; + end; + focuscell(ffocusedcell,action); + end; + end; + end; + end; +var + gd1: graphicdirectionty; +label + checkwidgetexit; +begin + actioncol:= fca_none; + exclude(fstate1,gs1_scrolllimit); + if canevent(tmethod(fonkeydown)) then begin + fonkeydown(self,info); + end; + if not(es_processed in info.eventstate) then begin + shiftstate:= info.shiftstate * shiftstatesmask; + if ffocusedcell.col >= 0 then begin + fdatacols[ffocusedcell.col].dokeyevent(info,false); + end + else begin + with celleventinfo do begin + initeventinfo(ffocusedcell,cek_keydown,celleventinfo); + keyeventinfopo:= @info; + docellevent(celleventinfo); + end; + end; + cellbefore:= focusedcell; + bo1:= (ow_arrowfocusout in optionswidget) and (shiftstate = []) and + not(((info.key = key_up) or (info.key = key_pageup)) and not isfirstrow or + ((info.key = key_down) or (info.key = key_pagedown)) and not islastrow); + //test for db rows, exit widget + if shiftstate - [ss_shift,ss_ctrl] = [] then begin + if not (es_processed in info.eventstate) then begin + if ss_shift in shiftstate then begin + if (ffocusedcell.col >= 0) and + (co_keyselect in fdatacols[ffocusedcell.col].foptions) then begin + action:= fca_selectend; + actioncol:= action; + end + else begin + action:= fca_focusinshift; + actioncol:= action; + end; + end + else begin + action:= fca_focusinforce; + actioncol:= fca_focusin; + end; + focusbefore:= ffocusedcell; + include(info.eventstate,es_processed); + case info.key of + key_up: begin + if shiftstate = [ss_ctrl] then begin + if (og_keyrowmoving in foptionsgrid) and canmoverow() then begin + if ffocusedcell.row > 0 then begin + moverow(ffocusedcell.row,ffocusedcell.row - 1,1,true); + showcell(ffocusedcell); + end; + end + else begin + scrollrows(1); + end; + exit; + end + else begin + rowup(action,aso_gridnavig in assistiveoptions); + checkselection; + gd1:= gd_up; + goto checkwidgetexit; + end; + end; + key_down: begin + if shiftstate = [ss_ctrl] then begin + if (og_keyrowmoving in foptionsgrid) and canmoverow then begin + if (ffocusedcell.row >= 0) and (ffocusedcell.row < frowcount-1) then begin + moverow(ffocusedcell.row,ffocusedcell.row + 1,1,true); + showcell(ffocusedcell); + end; + end + else begin + scrollrows(-1); + end; + exit; + end + else begin + rowdown(action,aso_gridnavig in assistiveoptions); + checkselection; + gd1:= gd_down; + goto checkwidgetexit; + end; + end; + key_home: begin + if ss_ctrl in shiftstate then begin + focuscell(makegridcoord(nextfocusablecol(0,false,0,true),0),action); + end + else begin + exclude(info.eventstate,es_processed); + end; + end; + key_end: begin + if ss_ctrl in shiftstate then begin + focuscell(makegridcoord( + nextfocusablecol(datacols.count-1,true,frowcount-1,true), + frowcount-1),action); + end + else begin + exclude(info.eventstate,es_processed); + end; + end; + key_pageup: begin + if ss_ctrl in shiftstate then begin + if og_visiblerowpagestep in foptionsgrid then begin + focuscell(makegridcoord(ffocusedcell.col,ffirstvisiblerow),action); + end + else begin + firstrow(action); + end; + end + else begin + pageup(action); + end; + end; + key_pagedown: begin + if ss_ctrl in shiftstate then begin + if og_visiblerowpagestep in foptionsgrid then begin + focuscell(makegridcoord(ffocusedcell.col,flastvisiblerow),action); + end + else begin + lastrow(action); + end; + end + else begin + pagedown(action); + end; + end; + else begin + exclude(info.eventstate,es_processed); + end; + end; + end; + if not(es_processed in info.eventstate) and + (ffocusedcell.col >= 0) then begin + include(info.eventstate,es_processed); + case info.key of + key_return: begin + if (og_colchangeonreturnkey in foptionsgrid) and + (shiftstate = []) then begin + colstep(fca_focusin,1,true,false,true); + end + else begin + exclude(info.eventstate,es_processed); + end; + end; + key_tab,key_backtab: begin + if not (og_colchangeontabkey in foptionsgrid) or (rowcount = 0) then begin + exclude(info.eventstate,es_processed); + dokeydownaftershortcut(info); + end + else begin + if shiftstate - [ss_shift] = [] then begin + if docheckcellvalue then begin + action:= fca_focusin; + if shiftstate = [ss_shift] then begin + colstep(actioncol,-1,true,false,true); + end + else begin + colstep(actioncol,1,true,false,true); + end; + end; + end + else begin + exclude(info.eventstate,es_processed); + end; + end; + end; + key_left: begin + if shiftstate = [ss_ctrl] then begin + if og_keycolmoving in foptionsgrid then begin + if ffocusedcell.col > 0 then begin + movecol(ffocusedcell.col,ffocusedcell.col-1); + end; + end + else begin + scrollleft; + end; + exit; + end + else begin + colstep(actioncol,-1,false,(aso_gridnavig in assistiveoptions) or + not (og_wrapcol in foptionsgrid),false); + checkselection; + gd1:= gd_left; + goto checkwidgetexit; + end; + end; + key_right: begin + if shiftstate = [ss_ctrl] then begin + if og_keycolmoving in foptionsgrid then begin + if (ffocusedcell.col >= 0) and + (ffocusedcell.col < fdatacols.count-1) then begin + moverow(ffocusedcell.col,ffocusedcell.col + 1); + end; + end + else begin + scrollright; + end; + exit; + end + else begin + colstep(actioncol,1,false,(aso_gridnavig in assistiveoptions) or + not (og_wrapcol in foptionsgrid),false); + checkselection; + gd1:= gd_right; + goto checkwidgetexit; + end; + end; + else begin + exclude(info.eventstate,es_processed); + end; + end; + end; + checkselection; + if not (es_processed in info.eventstate) and (ffocusedcell.col >= 0) then begin + with fdatacols[ffocusedcell.col] do begin + if (info.key = key_space) and (co_keyselect in foptions) and + ((shiftstate = [ss_shift]) or (shiftstate = [ss_ctrl])) then begin + if shiftstate = [ss_ctrl] then begin + mo1:= csm_reverse; + end + else begin + mo1:= csm_select; + end; + selectcell(ffocusedcell,mo1,true); + include(info.eventstate,es_processed); + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + if {issysshortcut(sho_copy,info) or} + issysshortcut(sho_copycells,info) and + (fdatacols.cancopy or canevent(tmethod(foncopyselection))) and + copyselection then begin + include(info.eventstate,es_processed); + end + else begin + if issysshortcut(sho_pastecells,info) and + (fdatacols.canpaste or canevent(tmethod(fonpasteselection))) and + pasteselection then begin + include(info.eventstate,es_processed); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + if og_rowinserting in foptionsgrid then begin + if issysshortcut(sho_rowinsert,info) then begin + if og1_swaprowinsertappend in foptionsgrid1 then begin + if canappendrow then begin + doappendrow(nil); + end; + end + else begin + if caninsertrow then begin + doinsertrow(nil); + end; + end; + include(info.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowappend,info) then begin + if og1_swaprowinsertappend in foptionsgrid1 then begin + if caninsertrow then begin + doinsertrow(nil); + end; + end + else begin + if canappendrow then begin + doappendrow(nil); + end; + end; + include(info.eventstate,es_processed); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + if (og_rowdeleting in foptionsgrid) and + issysshortcut(sho_rowdelete,info) then begin + if candeleterow then begin + dodeleterows(nil); + end; + include(info.eventstate,es_processed); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; + exit; + +checkwidgetexit: + if (row = cellbefore.row) and (col = cellbefore.col) then begin + if bo1 then begin + exclude(info.eventstate,es_processed); + if es_child in info.eventstate then begin + dokeydownaftershortcut(info); + end; + end + else begin + if canassistive() and ((gd1 in [gd_left,gd_right]) or + not (gs_isdb in fstate) or (gs1_scrolllimit in fstate1)) then begin + assistiveserver.dogridbordertouched( + iassistiveclientgrid(getiassistiveclient),gd1); + end; + exclude(fstate1,gs1_scrolllimit); + end; + end; +end; + +procedure tcustomgrid.dokeyup(var info: keyeventinfoty); +var + celleventinfo: celleventinfoty; +begin + if ffocusedcell.col >= 0 then begin + fdatacols[ffocusedcell.col].dokeyevent(info,true); + end + else begin + with celleventinfo do begin + initeventinfo(ffocusedcell,cek_keyup,celleventinfo); + keyeventinfopo:= @info; + docellevent(celleventinfo); + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomgrid.updatevisiblerows; + //todo: optimize +var + cell: gridcoordty; + int1: integer; +begin +// if not (gs_visiblerowsupdating in fstate) then begin +// include(fstate,gs_visiblerowsupdating); +// try + inc(fvisiblerowsupdating); + if frowcount = 0 then begin + fvisiblerowfoldinfo:= nil; + fvisiblerows:= nil; + ffirstvisiblerow:= invalidaxis; + flastvisiblerow:= invalidaxis; + fvisiblerowsbase:= invalidaxis; + end + else begin + int1:= fvisiblerowsupdating; + cellatpos(makepoint(0,fdatarecty.y),cell); //calls updatelayout + if int1 <> fvisiblerowsupdating then begin + exit; //recursion + end; + int1:= fvisiblerowsupdating; + ffirstvisiblerow:= cell.row; + cellatpos(makepoint(0,fdatarecty.y+fdatarecty.cy-1),cell); + if int1 <> fvisiblerowsupdating then begin + exit; //recursion + end; + flastvisiblerow:= cell.row; + if ffirstvisiblerow < 0 then begin + ffirstvisiblerow:= 0; + end; + if flastvisiblerow < 0 then begin + flastvisiblerow:= frowcount - 1; + end; + fvisiblerowsbase:= fdatacols.frowstate.visiblerow(ffirstvisiblerow); + if fvisiblerowsbase < 0 then begin + flastvisiblerow:= invalidaxis; + end; + if flastvisiblerow < 0 then begin + fvisiblerows:= nil; + end + else begin + fvisiblerows:= fdatacols.frowstate.visiblerows1(fvisiblerowsbase, + fdatarect.cy - fscrollrect.y{ div fdatarowheight + 2}); + int1:= high(fvisiblerows); + if int1 >= 0 then begin + while fvisiblerows[int1] > flastvisiblerow do begin + dec(int1); + end; + setlength(fvisiblerows,int1+1); + end; + end; + if (og_folded in foptionsgrid) then begin + with fdatacols.frowstate do begin + updatefoldinfo(self.fvisiblerows,fvisiblerowfoldinfo); + { + if (row >= 0) then begin + int1:= row; + row:= nearestvisiblerow(row); + if row = int1 then begin //no focuscell + if row >= ffoldchangedrow then begin + dofocusedcellposchanged; + fdatacols.frowstate.ffoldchangedrow:= bigint; + end; + end; + end; + } + end; + end + else begin + fvisiblerowfoldinfo:= nil; + end; + end; +// finally +// exclude(fstate,gs_visiblerowsupdating); +// end; +// end; +end; + +function tcustomgrid.getselectedrange: gridrectty; +begin + if fstartanchor.row >= frowcount then begin //ev. appended row removed + fstartanchor.row:= frowcount - 1; + if fstartanchor.row < 0 then begin + fstartanchor.col:= invalidaxis; + end; + end; + if fendanchor.row >= frowcount then begin //ev. appended row removed + fendanchor.row:= frowcount - 1; + if fendanchor.row < 0 then begin + fendanchor.col:= invalidaxis; + end; + end; + if (fstartanchor.col < 0) or (fendanchor.col < 0) then begin + result.pos:= invalidcell; + result.size:= gridsizety(nullsize); + end + else begin + result:= makegridrect(fstartanchor,fendanchor); + end; +end; + +procedure tcustomgrid.doenter; +begin + inherited; + if ((og_focuscellonenter in foptionsgrid) or + (ffocusedcell.col >= 0) and (ffocusedcell.row >= 0)) and + not (gs1_focuscellonenterlock in fstate1)then begin + focuscell(ffocusedcell,fca_entergrid); + end; +end; +{ +procedure tcustomgrid.dofocus; +begin + inherited; + if og_focuscellonenter in foptionsgrid then begin + focuscell(ffocusedcell,fca_entergrid); + end; +end; +} +procedure tcustomgrid.initnewcomponent(const ascale: real); +begin + ffixrows.count:= 1; + inherited; +end; + +procedure tcustomgrid.loaded; +var + int1: integer; + col1: tdatacol; +begin + inherited; + fdatacols.resetpropwidth; + ffixcols.resetpropwidth; + checkneedsrowheight; + updatelayout; //set propwidthref of cols + fdatacols.checkindexrange; + fdatacols.frowstate.sourcenamechanged(-1); + checksort; + for int1:= 0 to fdatacols.count - 1 do begin + col1:= tdatacol(fdatacols.fitems[int1]); + with col1 do begin + if (fdata <> nil) and canevent(tmethod(fonchange)) then begin + fonchange(col1,-1); + end; + end; + end; + dorowsdatachanged(makegridcoord(invalidaxis,0),frowcount); +end; + +procedure tcustomgrid.doexit; +begin + if not (csdestroying in componentstate) then begin + focuscell(invalidcell,fca_exitgrid); + end; + inherited; +end; + +procedure tcustomgrid.doactivate; +begin + if focusedcellvalid then begin + fdatacols[ffocusedcell.col].doactivate; + end; + inherited; +end; + +procedure tcustomgrid.dodeactivate; +begin + exclude(fstate,gs_cellclicked); + if focusedcellvalid then begin + fdatacols[ffocusedcell.col].dodeactivate; + end; + inherited; +end; + +procedure tcustomgrid.activechanged; +begin + inherited; + if (ffocusedcell.row >= 0) and (gs_hasactiverowcolor in fstate) then begin + invalidaterow(ffocusedcell.row); + end; +end; + +procedure tcustomgrid.doasyncevent(var atag: integer); +begin + if atag = gridautosizetag then begin + exclude(fstate1,gs1_autosizepending); + checkautosize(); + designchanged; + end + else begin + inherited; + end; +end; + +procedure tcustomgrid.getautopaintsize(var asize: sizety); +begin + if foptionswidget1 * [ow1_autowidth,ow1_autoheight] = [] then begin + inherited; + end + else begin + if fstate*[gs_updatelocked,gs_layoutupdating] <> [] then begin + if not (gs1_autosizepending in fstate1) then begin + include(fstate1,gs1_autosizepending); + asyncevent(gridautosizetag,[peo_local]); + end; + end + else begin + asize:= calcminscrollsize(); + end; + inherited; + end; +end; + +procedure tcustomgrid.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +var + cellkind: cellkindty; + cell: gridcoordty; + rect1: rectty; + + function cancolsizing(col: integer): boolean; + begin + result:= (col <> invalidaxis) and ((csdesigning in componentstate) or + (col >= 0) and + (og_colsizing in foptionsgrid) and + not (co_fixwidth in fdatacols[col].foptions)); + end; + + function cancolmoving: boolean; + begin + result:= (csdesigning in componentstate) or + (og_colmoving in foptionsgrid) and + not (co_fixpos in fdatacols[cell.col].foptions); + end; + + function canrowsizing: boolean; + begin + result:= (csdesigning in componentstate) or (og_rowsizing in foptionsgrid); + end; + + function canrowmoving: boolean; + begin + result:= (csdesigning in componentstate) or + ((og_rowmoving in foptionsgrid) and canmoverow); + end; + + function checkfixcol(nofixed: boolean = false): boolean; + begin + result:= false; + with sender.pickrect do begin + if (cell.row >= 0) and (pos.y <= rect1.y + sizingtol) then begin + if canrowsizing then begin + objects[0]:= pickobjectstep * (cell.row-1) + integer(pok_datarowsize); + end; + end + else begin + if (cell.row >= 0) and (pos.y >= rect1.y + rect1.cy - sizingtol) then begin + if canrowsizing then begin + objects[0]:= pickobjectstep * (cell.row) + integer(pok_datarowsize); + end; + end + else begin + if (csdesigning in componentstate) and not nofixed then begin + if (pos.x <= rect1.x + sizingtol) and //left line + (cell.col <> ffixcols.ffirstopposite + 1) then begin + //not left col + if cell.col <= ffixcols.ffirstopposite then begin //right of table + objects[0]:= -pickobjectstep * (cell.col) + integer(pok_fixcolsize); + end + else begin //left of table + objects[0]:= -pickobjectstep * (cell.col-1) + integer(pok_fixcolsize); + end; + end + else begin + if (pos.x >= rect1.x + rect1.cx - sizingtol) then begin //right line + if (cell.col <> ffixcols.ffirstopposite) then begin //not right col + if cell.col <= ffixcols.ffirstopposite then begin //right of table + objects[0]:= -pickobjectstep * (cell.col+1) + integer(pok_fixcolsize); + end + else begin + objects[0]:= -pickobjectstep * (cell.col) + integer(pok_fixcolsize); + end; + end; + end; + end; + end + else begin + if canrowmoving and not nofixed then begin + objects[0]:= pickobjectstep * (cell.row) + integer(pok_datarow); + result:= true; + end; + end; + end; + end; + end; + end; + + function checkfixrow(nofixed: boolean = false): boolean; + var + int1: integer; + begin + result:= false; + with sender.pickrect do begin + if (pos.x >= rect1.x + rect1.cx - sizingtol) then begin + if (cell.col >= 0) then begin + int1:= cell.col; + if int1 >= fdatacols.ffirstopposite then begin + int1:= fdatacols.nextvisiblecol(int1); + end; + if cancolsizing(int1) then begin + objects[0]:= pickobjectstep * (int1) + integer(pok_datacolsize); + end; + end; + end + else begin + if (pos.x <= rect1.x + sizingtol) then begin + int1:= cell.col; + if cell.col < fdatacols.ffirstopposite then begin + int1:= fdatacols.previosvisiblecol(int1); + end; + if (int1 >= 0) and cancolsizing(int1) then begin + objects[0]:= pickobjectstep * (int1) + integer(pok_datacolsize); + end; + end + else begin + if (csdesigning in componentstate) and not nofixed then begin + if (pos.y <= rect1.y + sizingtol) then begin + //top line + if cell.row <> ffixrows.ffirstopposite + 1 then begin //not top row + if cell.row <= ffixrows.ffirstopposite then begin //below the table + objects[0]:= -pickobjectstep * (cell.row) + integer(pok_fixrowsize); + end + else begin //above the table + objects[0]:= -pickobjectstep * (cell.row-1) + integer(pok_fixrowsize); + end; + end; + end + else begin + if (pos.y >= rect1.y + rect1.cy - sizingtol) and + (cell.row <> ffixrows.ffirstopposite) then begin + //bottom line, not bottom row + if cell.row <= ffixrows.ffirstopposite then begin //below the table + objects[0]:= -pickobjectstep * (cell.row+1) + integer(pok_fixrowsize); + end + else begin + objects[0]:= -pickobjectstep * (cell.row) + integer(pok_fixrowsize); + end; + end + else begin + if not (gs_child in fstate) then begin + objects[0]:= pickobjectstep * cell.col + integer(pok_datacol); + result:= true; + end; + end; + end; + end + else begin + if cancolmoving and not nofixed and not (gs_child in fstate) then begin + with fixrows[cell.row] do begin + if (cell.col >= fcaptions.count) or + not (dco_colsort in fcaptions[cell.col].options) or + (pos.x < rect1.x + rect1.cx - sortglyphwidth) or + (csdesigning in componentstate) then begin + objects[0]:= pickobjectstep * cell.col + integer(pok_datacol); + result:= true; + end; + end; + end; + end; + end; + end; + end; + end; + +begin + if ((sender.shiftstate * shiftstatesmask) - [ss_left] <> []) or + (gs_child in fstate) then begin + exit; + end; + setlength(objects,1); + objects[0]:= -1; //none + with sender.pickrect do begin + cellkind:= cellatpos(pos,cell); + rect1:= cellrect(cell,cil_noline,true); + case cellkind of + ck_fixcolrow: begin + if (csdesigning in componentstate) then begin + if checkfixcol or (objects[0] < 0) then begin + if checkfixrow or (objects[0] < 0) then begin + objects[0]:= -pickobjectstep * (cell.row) + integer(pok_fixrow); + end; + end; + end; + end; + ck_fixcol: begin + checkfixcol; + end; + ck_fixrow: begin + checkfixrow; + end; + ck_data: begin + if ffixcols.count = 0 then begin + checkfixcol(true); + end; + if ffixrows.count = 0 then begin + checkfixrow(true); + end; + end; + end; + end; + if objects[0] < 0 then begin + objects:= nil; + end; +end; + +function tcustomgrid.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; +var + objects1: integerarty; +begin + getpickobjects(sender,objects1); + if length(objects1) > 0 then begin + fpickkind:= pickobjectkindty(objects1[0] mod pickobjectstep); + result:= true; + case fpickkind of + pok_datacolsize,pok_fixcolsize: shape:= cr_sizehor; + pok_datarowsize,pok_fixrowsize: shape:= cr_sizever; + else begin + result:= false; + end; + end; + end + else begin + result:= false; + fpickkind:= pok_none; + end; +end; + +procedure tcustomgrid.beginpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomgrid.pickthumbtrack(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomgrid.decodepickobject(code: integer; out kind: pickobjectkindty; + out cell: gridcoordty; out col: tcol; out row: tfixrow); +var + int1: integer; +begin + kind:= pickobjectkindty(code mod pickobjectstep); + int1:= code div pickobjectstep; + if kind in [pok_fixcol,pok_fixcolsize,pok_fixrow,pok_fixrowsize] then begin + int1:= -int1; + end; + if kind in [pok_fixrow,pok_fixrowsize,pok_datarow,pok_datarowsize] then begin + cell:= makegridcoord(invalidaxis,int1); + end + else begin + cell:= makegridcoord(int1,invalidaxis); + end; + if kind in [pok_datacol,pok_datacolsize] then begin + col:= fdatacols[int1]; + end + else begin + if kind in [pok_fixcol,pok_fixcolsize] then begin + col:= ffixcols[int1]; + end + else begin + col:= nil; + if kind in [pok_fixrow,pok_fixrowsize] then begin + row:= ffixrows[int1]; + end + else begin + row:= nil; + end; + end; + end; +end; + +procedure tcustomgrid.endpickmove(const sender: tobjectpicker); +var + kind: pickobjectkindty; + cell,cell1: gridcoordty; + col1: tcol; + fixrow: tfixrow; + int1,int2: integer; + offset: pointty; + apos: pointty; + ar1: integerarty; +begin + killrepeater; + ar1:= sender.currentobjects; + if ar1 <> nil then begin + decodepickobject(ar1[0],kind,cell,col1,fixrow); + offset:= sender.pickoffset; + apos:= sender.pos; + case kind of + pok_datacolsize,pok_fixcolsize: begin + if (ss_double in sender.mouseeventinfopo^.shiftstate) and + not(co1_noautocolwidth in col1.foptions1) then begin + col1.width:= col1.maxwidth; + end + else begin + if (kind = pok_fixcolsize) and (cell.col <= fixcols.ffirstopposite) or + (kind = pok_datacolsize) and + (cell.col >= fdatacols.ffirstopposite) then begin + col1.width:= col1.width - offset.x; + end + else begin + int1:= offset.x; + with col1 do begin + if co_nohscroll in foptions then begin + if fend + int1 > fdatarect.x + fdatarect.cx then begin + int1:= fdatarect.x + fdatarect.cx - fend; + end; + end; + if co_fill in options then begin + if (int1 < 0) then begin + if width + int1 < fwidthmin then begin + int1:= fwidthmin - width; + end; + end + else begin + if (fwidthmax <> 0) and + (width + int1 > fwidthmax) then begin + int1:= fwidthmax - width; + end; + end; + for int2:= index to datacols.count - 1 do begin + with datacols[int2] do begin + if options * [co_fixwidth,co_fill,co_invisible] = [] then begin + width:= width - int1; + int1:= 0; + break; + end; + end; + end; + if int1 <> 0 then begin + for int2:= index-1 downto 0 do begin + with datacols[int2] do begin + if options * [co_fixwidth,co_fill,co_invisible] = [] then begin + width:= width - int1; + int1:= 0; + break; + end; + end; + end; + end; + end; + width:= width + int1; + end; + end; + end; + end; + pok_fixrowsize: begin + if cell.row <= fixrows.ffirstopposite then begin + fixrow.height:= fixrow.height - offset.y; + end + else begin + fixrow.height:= fixrow.height + offset.y; + end; + end; + pok_datarowsize: begin + if og_rowheight in foptionsgrid then begin + if ss_double in sender.shiftstate then begin + rowheight[cell.row]:= 0; + end + else begin + int1:= fdatacols.frowstate.currentrowheight(cell.row); + rowheight[cell.row]:= int1 + offset.y; + end; + end + else begin + datarowheight:= fdatarowheight + offset.y; + end; + end; + pok_datacol: begin + //cellkind:= + cellatpos(makepoint(apos.x,fdatarect.y),cell1); + if (cell1.col >= 0) and (cell.col <> cell1.col) and not + ((co_nohscroll in tdatacol(fdatacols.fitems[cell1.col]).options) xor + (co_nohscroll in tdatacol(fdatacols.fitems[cell.col]).options)) then begin + movecol(cell.col,cell1.col); + end + else begin + end; + end; + pok_datarow: begin + // cellkind:= + cellatpos(makepoint(fdatarect.x,apos.y),cell1); + if (cell1.row >= 0) and (cell.row <> cell1.row) then begin + moverow(cell.row,cell1.row,1,true); + end + else begin + end; + end; + end; + designchanged; + end; +end; + +procedure tcustomgrid.cancelpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomgrid.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); + + procedure drawhorzline(pos: integer); + begin + with tframe1(fframe) do begin + canvas.intersectcliprect(makerect(fdatarecty.x,0, + fdatarecty.cx,fpaintrect.cy)); + canvas.fillxorrect(makepoint(finnerclientrect.x,pos),finnerclientrect.cx, + gd_right,2,stockobjects.bitmaps[stb_dens50]); + end; + end; + + procedure drawvertline(pos: integer); + begin + with tframe1(fframe) do begin + canvas.intersectcliprect(makerect(0,fdatarectx.y, + fpaintrect.cx,fdatarectx.cy)); + canvas.fillxorrect(makepoint(pos,finnerclientrect.y),finnerclientrect.cy, + gd_down,2,stockobjects.bitmaps[stb_dens50]); + end; + end; + +var + kind: pickobjectkindty; + cell,cell1: gridcoordty; + col1: tcol; + fixrow: tfixrow; + int1,int2: integer; + rect1: rectty; + offset: pointty; + apos: pointty; + ar1: integerarty; + {bo1,}s1,d1: boolean; +begin + int1:= 0; + offset:= sender.pickoffset; + apos:= sender.pos; + ar1:= sender.currentobjects; + if ar1 = nil then begin + exit; + end; + decodepickobject(ar1[0],kind,cell,col1,fixrow); + rect1:= cellrect(cell); + with rect1 do begin + case kind of + pok_datacolsize,pok_fixcolsize: begin + if (kind = pok_fixcolsize) and (cell.col <= fixcols.ffirstopposite) or + (kind = pok_datacolsize) and (cell.col >= + fdatacols.ffirstopposite) then begin + int1:= offset.x+x; + end + else begin + int1:= offset.x+x+cx; + end; + drawvertline(int1); + end; + pok_datarowsize,pok_fixrowsize: begin + if (kind = pok_fixrowsize) and (cell.row < + -(fixrows.count-fixrows.foppositecount)) then begin + int1:= offset.y+y; + end + else begin + int1:= offset.y+y+cy; + end; + drawhorzline(int1); + end; + pok_datarow: begin + cellatpos(makepoint(fdatarect.x,apos.y),cell1); + if cell1.row >= 0 then begin + rect1:= cellrect(cell1); + killrepeater; + if cell1.row > cell.row then begin + int1:= rect1.y+rect1.cy; + if int1 > fdatarect.y + fdatarect.cy then begin + startrepeater(gs_scrolldown,slowrepeat); + end + else begin + drawhorzline(int1); + end; + end + else begin + if (cell1.row > 0) and (rect1.y {- fystep} < fdatarect.y) then begin + startrepeater(gs_scrollup,slowrepeat); + end + else begin + drawhorzline(rect1.y); + end; + end; + end + else begin + if apos.y < fdatarect.y then begin + startrepeater(gs_scrollup,fastrepeat); + end + else begin + rect1:= cellrect(makegridcoord(0,frowcount-1)); + drawhorzline(rect1.y+rect1.cy-2); + startrepeater(gs_scrolldown,fastrepeat); + end; + end; + end; + pok_datacol: begin + s1:= co_nohscroll in tdatacol(fdatacols.fitems[cell.col]).options; + cellatpos(makepoint(apos.x,fdatarect.y),cell1); + d1:= not s1; //inhibit + if cell1.col >= 0 then begin + d1:= co_nohscroll in tdatacol(fdatacols.fitems[cell1.col]).options; + rect1:= cellrect(cell1); + int1:= rect1.x; + if cell1.col > cell.col then begin + int1:= rect1.x+rect1.cx; + end; + end; + killrepeater; + if not s1 then begin + if int1 < fdatarect.x then begin + int1:= fdatarect.x; + end + else begin + int2:= fdatarect.x + fdatarect.cx; + if int1 > int2 then begin + int1:= int2; + end; + end; + if (apos.x < fdatarect.x) then begin + startrepeater(gs_scrollleft,slowrepeat); + end + else begin + if (apos.x >= fdatarect.x + fdatarect.cx) then begin + startrepeater(gs_scrollright,slowrepeat); + end; + end; + end; + if s1 = d1 then begin + drawvertline(int1); + end; + { + else begin + if not s1 then begin + if (apos.x < fdatarect.x) then begin + startrepeater(gs_scrollleft,slowrepeat); + end + else begin +// rect1:= cellrect(makegridcoord(fdatacols.count-1,0)); +// if cell1.col <> invalidaxis then begin +// drawvertline(rect1.x+rect1.cx-2); +// end; + startrepeater(gs_scrollright,slowrepeat); + end; + end; + end; + } + end; + end; + end; +end; + +procedure tcustomgrid.killrepeater; +begin + freeandnil(frepeater); + fstate:= fstate - repeaterstates; +end; + + +procedure tcustomgrid.dobeforepaint(const canvas: tcanvas); +begin + fobjectpicker.dobeforepaint(canvas); + inherited; +end; + +procedure tcustomgrid.doafterpaint(const canvas: tcanvas); +begin + inherited; + fobjectpicker.doafterpaint(canvas); +end; + +function tcustomgrid.getnoscroll(): boolean; +begin + result:= inherited getnoscroll() or (ws1_widgetrectsetting in fwidgetstate1); +end; + +procedure tcustomgrid.repeatproc(const sender: tobject); +var + bo1: boolean; +begin + bo1:= (gs_cellclicked in fstate) and (frepeataction <> fca_none); + if gs_scrollup in fstate then begin + if bo1 then begin + if row < rowcount - 1 then begin + rowdown(frepeataction); + end; + end + else begin + scrollrows(1); + end; + end + else begin + if gs_scrolldown in fstate then begin + if bo1 then begin + if row > 0 then begin + rowup(frepeataction); + end; + end + else begin + scrollrows(-1); + end; + end + else begin + if gs_scrollleft in fstate then begin + if bo1 then begin + if (ffocusedcell.col < 0) or (ffocusedcell.col > 0) and + not (co_nohscroll in + tcol(fdatacols.fitems[ffocusedcell.col-1]).options) then begin + colstep(frepeataction,-1,false,false,false); + end; + end + else begin + scrollright; + end; + end + else begin + if gs_scrollright in fstate then begin + if bo1 then begin + if (ffocusedcell.col < 0) or (ffocusedcell.col < fdatacols.count - 1) and + not (co_nohscroll in + tcol(fdatacols.fitems[ffocusedcell.col+1]).options) then begin + colstep(frepeataction,1,false,false,false); + end; + end + else begin + scrollleft; + end; + end + end; + end; + end; +end; + +procedure tcustomgrid.startrepeater(state: gridstatety; time: integer); +begin + if not (state in fstate) then begin + killrepeater; + include(fstate,state); + frepeater:= tsimpletimer.create(time,{$ifdef FPC}@{$endif}repeatproc,true,[]); + end; +end; + +procedure tcustomgrid.movecol(curindex, newindex: integer; + const auserinput: boolean = false); +var + colbefore: integer; + count: integer; + bo1: boolean; +begin + bo1:= setuserinput(auserinput); + try + if canevent(tmethod(foncolmoving)) then begin + count:= 1; + foncolmoving(self,curindex,newindex,count); + if count <= 0 then begin + exit; + end; + end; + if curindex <> newindex then begin + colbefore:= ffocusedcell.col; + beginupdate; + if curindex >= 0 then begin //datacols + if (ffocusedcell.col = curindex) then begin + ffocusedcell.col:= newindex; + end + else begin + if (ffocusedcell.col >= newindex) and (ffocusedcell.col < curindex) then begin + inc(ffocusedcell.col); + end + else begin + if (ffocusedcell.col <= newindex) and (ffocusedcell.col > curindex) then begin + dec(ffocusedcell.col); + end; + end; + end; + fdatacols.move(curindex,newindex); + end; + endupdate; + docolmoved(curindex,newindex); + if colbefore <> ffocusedcell.col then begin + dofocusedcellposchanged; + end; + end; + finally + resetuserinput(bo1); + end; +end; + +procedure tcustomgrid.moverow(curindex, newindex: integer; count: integer = 1; + const auserinput: boolean = false); +var + int1: integer; + rowbefore: integer; + bo1: boolean; +begin + bo1:= setuserinput(auserinput); + try + if canevent(tmethod(fonrowsmoving)) then begin + fonrowsmoving(self,curindex,newindex,count); + end; + if (count > 0) and (curindex <> newindex) then begin + if (curindex < 0) or (curindex + count > rowcount) then begin + tlist.Error(SListIndexError,curindex); + end; + if (newindex < 0) or (newindex >= rowcount) then begin + tlist.Error(SListIndexError,newindex); + end; + + rowbefore:= ffocusedcell.row; + beginupdate; + if curindex >= 0 then begin //datarows + if not (gs_changelock in fstate) then begin + include(fstate,gs_changelock); + fdatacols.beginchangelock; + end; + if not fdatacols.roworderinvalid then begin + exit; + end; + fdatacols.moverow(curindex,newindex,count); + if (ffocusedcell.row >= 0) then begin + if (ffocusedcell.row >= curindex) and + (ffocusedcell.row < curindex + count) then begin + //focus in moved block + int1:= newindex; + if int1 >= curindex + count then begin + int1:= int1 - count + 1; + end; + ffocusedcell.row:= ffocusedcell.row + int1 - curindex; + end + else begin + if (ffocusedcell.row > curindex) and (ffocusedcell.row < newindex + count) then begin + dec(ffocusedcell.row,count); + end + else begin + if (ffocusedcell.row < curindex) and (ffocusedcell.row >= newindex) then begin + inc(ffocusedcell.row,count); + end; + end; + end; + end; + if factiverow >= 0 then begin + factiverow:= ffocusedcell.row; + end; + invalidate //for fixcols colorselect + end; + include(fstate,gs_rowdatachanged); + endupdate(gs1_sortmoving in fstate1); + dorowsmoved(curindex,newindex,count); + if rowbefore <> ffocusedcell.row then begin + dofocusedcellposchanged; + end; + end; + finally + resetuserinput(bo1); + end; +end; + +procedure tcustomgrid.internalinsertrow(var aindex: integer; + var acount: integer; const auserinput: boolean); +var + rowbefore: integer; + bo1: boolean; +// int1{,int2}: integer; +begin + if acount > 0 then begin + bo1:= setuserinput(auserinput); + try + dorowsinserting(aindex,acount); + if acount > 0 then begin + rowbefore:= ffocusedcell.row; + beginupdate; + try + if aindex >= 0 then begin //datarows + if not (gs_changelock in fstate) then begin + include(fstate,gs_changelock); + fdatacols.beginchangelock; + end; + if not fdatacols.roworderinvalid then begin + exit; + end; + fdatacols.insertrow(aindex,acount); + ffixcols.insertrow(aindex,acount); + if (ffocusedcell.row >= 0) then begin + if (ffocusedcell.row >= aindex) then begin + inc(ffocusedcell.row,acount); + if (factiverow >= 0) then begin + factiverow:= ffocusedcell.row; + end; + end; + end; + inc(frowcount,acount); + if frowcount > frowcountmax then begin + frowcount:= frowcountmax; + end; + if of_insertsamelevel in foptionsfold then begin + with fdatacols.frowstate do begin + if folded then begin + if (gs_appending in self.fstate) or (aindex+acount >= frowcount) then begin + if (aindex > 0) then begin + fillfoldlevel(aindex,acount,foldlevel[aindex-1]); + end; + end + else begin + fillfoldlevel(aindex,acount,foldlevel[aindex+acount]); + end; + end; + end; + end; + dorowcountchanged(frowcount-acount,frowcount); + end; + finally + endupdate; + end; + dorowsinserted(aindex,acount); + if rowbefore <> ffocusedcell.row then begin + dofocusedcellposchanged; + end; + end; + finally + resetuserinput(bo1); + end; + end; +end; + +function tcustomgrid.insertrow(aindex: integer; acount: integer = 1; + const auserinput: boolean = false): int32; +begin + internalinsertrow(aindex,acount,auserinput); + result:= aindex; +end; + +procedure tcustomgrid.internaldeleterow(var aindex: integer; + var acount: integer; const auserinput: boolean); +var + cellbefore: gridcoordty; + countbefore: integer; + defocused: boolean; + bo1,bo2,bo3: boolean; +begin + if acount > 0 then begin + bo3:= setuserinput(auserinput); + try + if (aindex >= 0) and (of_deletetree in foptionsfold) then begin + acount:= fdatacols.rowstate.totchildrencount(aindex,acount); + end; + dorowsdeleting(aindex,acount); + if acount > 0 then begin + defocused:= false; + cellbefore:= ffocusedcell; + beginupdate; + bo2:= gs1_rowdeleting in fstate1; + inc(fnonullcheck); + include(fstate1,gs1_rowdeleting); + try + if aindex >= 0 then begin //datarows + if not fdatacols.roworderinvalid then begin + exit; + end; + if (fclickedcell.row >= 0) and + (aindex <= fclickedcell.row) and + (fclickedcell.row < aindex + acount) then begin + exclude(fstate,gs_cellclicked); + end; + if (factiverow >= 0) then begin + if (factiverow >= aindex + acount) then begin + dec(factiverow,acount); + end + end; + if (ffocusedcell.row >= 0) then begin + if (ffocusedcell.row >= aindex + acount) then begin + dec(ffocusedcell.row,acount); + end + else begin + if ffocusedcell.row >= aindex then begin + countbefore:= frowcount; + bo1:= gs_rowremoving in fstate; + if ffocusedcell.row < aindex + acount then begin + include(fstate,gs_rowremoving); + end; + try + focuscell(makegridcoord(ffocusedcell.col,invalidaxis)); //defocus row + finally + if not bo1 then begin + exclude(fstate,gs_rowremoving); + end; + end; + if ffocusedcell.row <> invalidaxis then begin + factiverow:= ffocusedcell.row; + exit; + end; + defocused:= true; + if aindex + acount > frowcount then begin + dec(acount,countbefore - frowcount); //correct removed empty last row + end; + end; + end; + end; + if acount > 0 then begin + if not (gs_changelock in fstate) then begin + include(fstate,gs_changelock); + fdatacols.beginchangelock; + end; + if of_shiftdeltoparent in foptionsfold then begin + fdatacols.frowstate.movegrouptoparent(aindex,acount); + end; + bo1:= gs1_sortchangelock in fstate1; + include(fstate1,gs1_sortchangelock); + try + fdatacols.deleterow(aindex,acount); + finally + if not bo1 then begin + exclude(fstate1,gs1_sortchangelock); + end; + end; + ffixcols.deleterow(aindex,acount); + dec(frowcount,acount); + dorowcountchanged(frowcount+acount,frowcount); + end; + end; + finally + dec(fnonullcheck); + if not bo2 then begin + exclude(fstate1,gs1_rowdeleting); + end; + endupdate; + end; + dorowsdeleted(aindex,acount); + if cellbefore.row <> ffocusedcell.row then begin + dofocusedcellposchanged; + end; + if (og_focuscellonenter in foptionsgrid) and defocused then begin + cellbefore.row:= aindex; + if cellbefore.row >= frowcount then begin + cellbefore.row:= frowcount - 1; + if cellbefore.row < 0 then begin + cellbefore.row:= 0; + end; + end; + focuscell(cellbefore,fca_focusin); + //ev. auto first row + end; + end; + finally + resetuserinput(bo3); + end; + end; +end; + +procedure tcustomgrid.deleterow(aindex: integer; acount: integer = 1; + const auserinput: boolean = false); +begin + internaldeleterow(aindex,acount,auserinput); +end; + +procedure tcustomgrid.clear; //sets rowcount to 0 +begin + rowcount:= 0; +end; + +function tcustomgrid.appendrow(const checkautoappend: boolean = false): integer; //returns index of new row +var + updatingbefore: integer; + noinvalidatebefore: integer; + po1: pointty; + statebefore: framestatesty; + scrollheightbefore: integer; + + procedure updatelayout1; + begin + fupdating:= 0; + internalupdatelayout; + fupdating:= updatingbefore; + end; + +var + canscroll: boolean; + +begin + if checkautoappend and isautoappend then begin + result:= rowhigh; + end + else begin + statebefore:= tgridframe(fframe).fstate; + scrollheightbefore:= + tcustomscrollbar1(tgridframe(fframe).fvert).fdrawinfo.areas[sbbu_move].ca.dim.cy; + noinvalidatebefore:= fnoinvalidate; + updatingbefore:= fupdating; + beginupdate; + try + if frowcount >= frowcountmax then begin + canscroll:= showing and (fappendcount < 5); + inc(fappendcount); + po1.x:= 0; + po1.y:= -fystep; + if canscroll then begin + updatelayout1; + checkinvalidate; + scrollrect(po1,fdatarecty,scrollcaret(true)); + end + else begin + invalidate; + end; + inc(fnoinvalidate); + rowcount:= frowcount+1; + updatelayout1; + dec(fnoinvalidate); + if canscroll then begin + rowchanged(frowcount-1); + end; + end + else begin + inc(fnoinvalidate); + rowcount:= rowcount+1; + updatelayout1; + dec(fnoinvalidate); + rowchanged(frowcount-1); + end; + result:= frowcount-1; + if statebefore * scrollbarframestates <> + tgridframe(fframe).fstate * scrollbarframestates then begin + invalidatewidget; + end + else begin + if tcustomscrollbar1(tgridframe(fframe).fvert). + fdrawinfo.areas[sbbu_move].ca.dim.cy <> + scrollheightbefore then begin + tcustomscrollbar1(tgridframe(fframe).fvert).invalidate; + end; + end; + finally + fnoinvalidate:= noinvalidatebefore; + fupdating:= updatingbefore + end; + end; +end; + +function tcustomgrid.appenddatarow: integer; +begin + result:= rowcount; + rowcount:= rowcount+1; +end; + +procedure tcustomgrid.checkinvalidate; +var + int1: integer; +begin + if gs_invalidated in fstate then begin + invalidate; + end + else begin + if finvalidatedcells <> nil then begin + for int1:= 0 to high(finvalidatedcells) do begin + with finvalidatedcells[int1] do begin + if (row < 0) and (col < 0) then begin + invalidate; + break; + end + else begin + invalidatecell(finvalidatedcells[int1]); + end; + end; + end; + finvalidatedcells:= nil; + end; + end; +end; + +procedure tcustomgrid.beginupdate; +begin + if fupdating = 0 then begin + exclude(fstate,gs_emptyrowremoved); //possibly checked in endupdate + fappendcount:= 0; + frowdatachangestart:= rowcount; + end; + inc(fupdating); +end; + +procedure tcustomgrid.endupdate(const nosort: boolean = false; + const invalidrowstart: int32 = 0); +var + int1,int2: integer; +{$ifdef mse_with_ifi} + bo1: boolean; +{$endif} +begin + dec(fupdating); + if fupdating = 0 then begin +{$ifdef mse_with_ifi} + bo1:= fstate * + [gs_rowcountinvalid,gs_rowdatachanged,gs_selectionchanged] <> []; +{$endif} + if gs_rowcountinvalid in fstate then begin + int2:= bigint; + for int1:= 0 to datacols.count - 1 do begin + with datacols[int1] do begin + if (fdata <> nil) and (fdata.count < int2) then begin + int2:= fdata.count; + end; + end; + end; + exclude(fstate,gs_rowcountinvalid); + if int2 <> bigint then begin + rowcount:= int2; + end; + end; + if not nosort then begin + checksort; + end; + checkinvalidate; + if gs_changelock in fstate then begin + exclude(fstate,gs_changelock); + fdatacols.endchangelock; + end; + if gs_rowdatachanged in fstate then begin + updaterowdata; + if frowdatachangestart < rowcount then begin + rowdatachanged(makegridcoord(invalidaxis,frowdatachangestart), + frowcount-frowdatachangestart); + end; +// rowdatachanged(makegridcoord(invalidaxis,invalidrowstart), +// frowcount-invalidrowstart); + end; + if gs_selectionchanged in fstate then begin + internalselectionchanged; + end; + {$ifdef mse_with_ifi} + if bo1 and (fifiserverintf <> nil) and not(ws_loadedproc in fwidgetstate) and + not (gs_emptyrowremoved in fstate) and not isautoappend then begin + iifidataserver(fifiserverintf).valuechanged(iifigridlink(self)); + end; + {$endif} + if (gs1_showcellinvalid in fstate1) then begin + showcell(fshowcell,fshowcellmode); + exclude(fstate1,gs1_showcellinvalid); + end; + if (gs_focusedcellchanged in fstate) and + (ffocusedcell.col >= 0) and (ffocusedcell.row >= 0) then begin + focusedcellchanged; + end; + end; +end; + +procedure tcustomgrid.docolmoved(const fromindex, toindex: integer); +begin + if canevent(tmethod(foncolmoved)) then begin + foncolmoved(self,fromindex,toindex,1); + end; +end; + +procedure tcustomgrid.dorowsmoved(const fromindex, toindex, count: integer); +begin + if canevent(tmethod(fonrowsmoved)) then begin + fonrowsmoved(self,fromindex,toindex,count); + end; + dorowsmodified; +end; + +procedure tcustomgrid.dorowsinserting(var index, count: integer); +begin + {$ifdef mse_with_ifi} + if fifilink <> nil then begin + fifilink.controller.dorowsinserting(index,count,userinput); + end; + {$endif} + if canevent(tmethod(fonrowsinserting)) then begin + fonrowsinserting(self,index,count); + end; +end; + +procedure tcustomgrid.dorowsinserted(const index, count: integer); +begin + {$ifdef mse_with_ifi} + if fifilink <> nil then begin + fifilink.controller.dorowsinserted(index,count,userinput); + end; + {$endif} + if canevent(tmethod(fonrowsinserted)) then begin + fonrowsinserted(self,index,count); + end; + dorowsdatachanged(makegridcoord(invalidaxis,index),count); + dorowsmodified; +end; + +procedure tcustomgrid.dorowsdeleting(var index, count: integer); +begin + if canevent(tmethod(fonrowsdeleting)) then begin + fonrowsdeleting(self,index,count); + end; + {$ifdef mse_with_ifi} + if fifilink <> nil then begin + fifilink.controller.dorowsdeleting(index,count,userinput); + end; + {$endif} +end; + +procedure tcustomgrid.dorowsdeleted(index, count: integer); +begin + {$ifdef mse_with_ifi} + if fifilink <> nil then begin + fifilink.controller.dorowsdeleted(index,count,userinput); + end; + {$endif} + if canevent(tmethod(fonrowsdeleted)) then begin + fonrowsdeleted(self,index,count); + end; + dorowsmodified; +end; + +class function tcustomgrid.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_grid; +end; + +procedure tcustomgrid.setoptionsgrid(const avalue: optionsgridty); +const + mask1: optionsgridty = rowstateoptions; +var + optionsbefore: optionsgridty; +begin + if foptionsgrid <> avalue then begin +{ + if (csreading in componentstate) then begin + if (og_noresetselect in avalue) then begin + include(foptionsgrid1,og1_noresetselect); + end; + end; +} + optionsbefore:= foptionsgrid; + foptionsgrid:= avalue; +// foptionsgrid:= optionsgridty( +// setsinglebit(card32(avalue),card32(foptionsgrid), +// card32([og_customsorted,og_sorted]))); +// foptionsgrid:= avalue-deprecatedoptionsgrid; + if (longword(avalue) xor longword(optionsbefore)) + and longword(mask1) <> 0 then begin + fdatacols.frowstate.free; + fdatacols.frowstate:= trowstatelist.create(self); + fdatacols.frowstate.count:= rowcount; + end; + fdatacols.frowstate.folded:= og_folded in avalue; + layoutchanged; + if og_sorted in foptionsgrid then begin + include(fstate1,gs1_gridsorted); + end + else begin + exclude(fstate1,gs1_gridsorted); + end; + if og_customsort in foptionsgrid then begin + include(fstate1,gs1_customsort); + end + else begin + exclude(fstate1,gs1_customsort); + end; + if (og_sorted in foptionsgrid) and not(og_sorted in optionsbefore) then begin + exclude(fstate1,gs1_sortvalid); + checksort(); + end; + end; +end; + +function tcustomgrid.scrollcaret(const vertical: boolean): boolean; +begin + result:= false; +end; + +procedure tcustomgrid.synctofontheight; +begin + inherited; + ffixrows.synctofontheight; +end; + +function tcustomgrid.internaldragevent(var info: draginfoty): boolean; +begin + result:= false; +end; + +procedure tcustomgrid.dragevent(var info: draginfoty); +var + bo1,bo2: boolean; + cell1: gridcoordty; +begin + cell1:= cellatpos(info.pos); + bo2:= isdatacell(cell1); + if not fdragcontroller.beforedragevent(info) then begin + if bo2 then begin + bo1:= false; + datacols[cell1.col].beforedragevent(info,cell1.row,bo1); + if not bo1 then begin + if not internaldragevent(info) then begin + inherited; + end; + end; + end + else begin + if not internaldragevent(info) then begin + inherited; + end; + end; + end; + if not fdragcontroller.afterdragevent(info) then begin + bo1:= false; + if bo2 then begin + datacols[cell1.col].afterdragevent(info,cell1.row,bo1); + end; + end; +end; + +function tcustomgrid.getdisprect: rectty; +begin + if (ffocusedcell.row = invalidaxis) and + (ffocusedcell.col = invalidaxis) then begin + result:= inherited getdisprect; + end + else begin + result:= cellrect(ffocusedcell); + addpoint1(result.pos,paintpos); + end; +end; + +procedure tcustomgrid.dofontheightdelta(var delta: integer); +begin + if ow1_autoscale in optionswidget1 then begin + ffixrows.dofontheightdelta(delta); + end; +end; + +procedure tcustomgrid.fontchanged; +begin + inherited; + fdatacols.fontchanged; + ffixrows.fontchanged; + ffixcols.fontchanged; +end; + +procedure tcustomgrid.setgridframecolor(const Value: colorty); +begin + if fgridframecolor <> value then begin + fgridframecolor := Value; + invalidate; + end; +end; +{ +procedure tcustomgrid.setgridframewidth(const Value: integer); +begin + if fgridframewidth <> value then begin + if componentstate * [csdesigning,csloading] = [csdesigning] then begin + with tframe1(fframe),fi.innerframe do begin + if right = self.fgridframewidth then begin + right:= value; + end; + if top = self.fgridframewidth then begin + top:= value; + end; + if left = self.fgridframewidth then begin + left:= value; + end; + if bottom = self.fgridframewidth then begin + bottom:= value; + end; + self.fgridframewidth := Value; + self.layoutchanged; + tframe1(fframe).updatestate; + end; + end + else begin + fgridframewidth := Value; + layoutchanged; + end; + end; +end; +} +function tcustomgrid.getmerged(const arow: integer): longword; +begin + result:= 0; + if (og_colmerged in foptionsgrid) and (arow >= 0) and + (arow < frowcount) then begin + result:= fdatacols.frowstate.getitempocolmerge(arow)^.colmerge.merged; + end; +end; + +function tcustomgrid.mergestart(const acol: integer; const arow: integer): integer; +var + int1: integer; + merged1: longword; +begin + result:= acol; + if acol >= 0 then begin + merged1:= getmerged(arow); + if merged1 <> 0 then begin + if merged1 = mergedcolall then begin + result:= 0; + end + else begin + if result < mergedcolmax then begin + result:= 0; + for int1:= acol - 1 downto 0 do begin + if merged1 and bits[int1] = 0 then begin + result:= int1 + 1; + break; + end; + end; + end; + end; + end; + end; +end; + +function tcustomgrid.mergeend(const acol: integer; const arow: integer): integer; +var + int1,int2: integer; + merged1: longword; +begin + result:= acol; + if acol >= 0 then begin + merged1:= getmerged(arow); + if merged1 <> 0 then begin + if merged1 = mergedcolall then begin + result:= fdatacols.count; + end + else begin + if (acol < mergedcolmax) and + ((acol = 0) or (merged1 and bits[acol-1] <> 0)) then begin + result:= fdatacols.count; + int2:= fdatacols.count - 1; + if int2 >= mergedcolmax then begin + int2:= mergedcolmax - 1; + end; + for int1:= acol to int2 do begin + if merged1 and bits[int1] = 0 then begin + result:= int1 + 1; + break; + end; + end; + end; + end; + end; + end; +end; + +procedure tcustomgrid.colstep(const action: focuscellactionty; + const step: integer; + const rowchange: boolean; const nocolwrap: boolean; + const noreadonly: boolean); +var + int1: integer; + row1: integer; + bo1: boolean; + finished: boolean; + act1: focuscellactionty; + step1: integer; + +begin + if fdatacols.count > 0 then begin + act1:= action; + step1:= step; + row1:= ffocusedcell.row; + int1:= ffocusedcell.col; + if int1 < 0 then begin + exit; + end; + finished:= true; + repeat + if step1 > 0 then begin + inc(int1); + finished:= int1 <= ffocusedcell.col; + int1:= mergeend(int1,row1); + finished:= finished and (int1 >= ffocusedcell.col); + if int1 >= fdatacols.count then begin + if nocolwrap then begin + exit; + end; + if rowchange then begin + inc(row1); + if act1 = fca_focusin then begin + act1:= fca_focusinforce; + end; + end; + int1:= 0; + finished:= int1 = ffocusedcell.col; + end; + if fdatacols[int1].canfocus(mb_none,[],noreadonly,bo1) then begin + dec(step1); + end; + end + else begin + dec(int1); + finished:= int1 >= ffocusedcell.col; + int1:= mergestart(int1,row1); + finished:= finished and (int1 <= ffocusedcell.col); + if int1 < 0 then begin + if nocolwrap then begin + exit; + end; + if rowchange then begin + dec(row1); + if act1 = fca_focusin then begin + act1:= fca_focusinforce; + end; + end; + int1:= mergestart(fdatacols.count - 1,row1); + finished:= int1 <= ffocusedcell.col; + end; + if fdatacols[int1].canfocus(mb_none,[],noreadonly,bo1) then begin + inc(step1); + end; + end; + if step1 = 0 then begin + if row1 < 0 then begin + row1:= rowcount-1; + end + else begin + if row1 >= rowcount then begin + if not (gs_isdb in fstate) and (og_autoappend in foptionsgrid) then begin + if fdatacols.rowempty(rowcount - 1) then begin + row1:= rowcount-1; + end + else begin + row1:= rowcount; + end; + end + else begin + row1:= 0; + end; + end; + end; + focuscell(makegridcoord(int1,row1),act1); + finished:= false; + break; + end; + until finished; //none found + if finished and noreadonly then begin + colstep(action,step,rowchange,nocolwrap,false); //try readonly + end; + end; +end; + +function tcustomgrid.nextfocusablecol(const acol: integer; + const aleft: boolean; const arow: integer; + const noreadonly: boolean): integer; +var + int1{,int2}: integer; + loopcount: integer; + bo1: boolean; + col1: integer; +begin + result:= -1; + col1:= acol; + if fdatacols.count > 0 then begin + if col1 > fdatacols.count then begin + col1:= fdatacols.count; + end; + if col1 < -1 then begin + col1:= -1; + end; + loopcount:= -1; + if aleft then begin + if col1 = fdatacols.count then begin + col1:= fdatacols.count - 1; + end; + int1:= col1; + repeat + if int1 < 0 then begin + int1:= fdatacols.count - 1; + inc(loopcount); + end; + int1:= mergestart(int1,arow); + if fdatacols[int1].canfocus(mb_none,[],noreadonly,bo1) then begin + result:= int1; + break; + end; + dec(int1); + until (int1 = col1) or (loopcount > 0); + end + else begin + if col1 < 0 then begin + col1:= 0; + end; + int1:= mergestart(col1,arow); + repeat + if int1 >= fdatacols.count then begin + int1:= 0; + inc(loopcount); + end; + if fdatacols[int1].canfocus(mb_none,[],noreadonly,bo1) then begin + result:= int1; + break; + end; + inc(int1); + int1:= mergeend(int1,arow); + until (int1 = col1) or (loopcount > 0); + end; + end; + if noreadonly and (result = -1) then begin + result:= nextfocusablecol(acol,aleft,arow,false); //try readonly cols + end; +end; + +procedure tcustomgrid.checkcellvalue(var accept: boolean); +begin + //dummy +end; + +function tcustomgrid.docheckcellvalue: boolean; +begin + result:= true; + if focusedcellvalid and (fnullchecking = 0) and + not(gs1_rowdeleting in fstate1) then begin + inc(fcellvaluechecking); + try + checkcellvalue(result); + finally + dec(fcellvaluechecking); + end; + end; +end; + +function tcustomgrid.internalsort(const sortfunc: indexsortcomparemethodty; + var refindex: integer): boolean; +var + ar1: integerarty; + bo1: boolean; + int1: integer; +begin + result:= false; + int1:= frowcount; + if int1 > 0 then begin + bo1:= not (gs_isdb in fstate) and (og_autoappend in foptionsgrid) and + fdatacols.rowempty(int1-1); + if bo1 then begin + dec(int1); //do not sort last row + end; + mergesort(int1,sortfunc,ar1,refindex,result); + if result then begin + if bo1 then begin + additem(ar1,int1); + end; + for int1:= 0 to fdatacols.count - 1 do begin + include(tdatacol(fdatacols.fitems[int1]).fstate,gps_noinvalidate); + end; + try + fdatacols.rearange(ar1); + finally + for int1:= 0 to fdatacols.count - 1 do begin + exclude(tdatacol(fdatacols.fitems[int1]).fstate,gps_noinvalidate); + end; + end; + ffixcols.rearange(ar1); + end; + end; +end; +(* +function tcustomgrid.internalsort(sortfunc: gridsorteventty; + var refindex: integer): boolean; + //true if rows moved, refindex is new indexpos +var + list: tintegerdatalist; + bewegt: boolean; + //todo: use merge sort + procedure quicksort(L, R: Integer); + var + I, J: Integer; + P, T: integer; + int1: integer; + begin + if r >= l then begin + repeat + I := L; + J := R; + P := list.items[(L + R) shr 1]; + repeat + repeat + int1:= 0; + sortfunc(self,List.items[I], P,int1); + if int1 = 0 then begin + int1:= list.items[i] - p; + end; + if int1 >= 0 then break; + inc(i); + until false; + repeat + int1:= 0; + sortfunc(self,List.items[j], P,int1); + if int1 = 0 then begin + int1:= list.items[j] - p; + end; + if int1 <= 0 then break; + dec(j); + until false; +// while (sortfunc(List.items[I], P,self) < 0) do Inc(I); +// while (sortfunc(List.items[J], P,self) > 0) do Dec(J); + if I <= J then + begin + if i <> j then begin + bewegt:= true; + T := List.items[I]; + List.items[I] := List.items[J]; + List.items[J] := T; + end; + Inc(I); + Dec(J); + end; + until I > J; + if L < J then QuickSort(L, J); + L := I; + until I >= R; + end; + end; + +var + int1: integer; + bo1: boolean; + +begin + bewegt:= false; + int1:= frowcount; + if int1 > 0 then begin + bo1:= not (gs_isdb in fstate) and (og_autoappend in foptionsgrid) and + fdatacols.rowempty(int1-1); + if bo1 then begin + dec(int1); //do not sort last row + end; + list:= tintegerdatalist.create; + try + list.count:= int1; + list.number(0,1); + quicksort(0,list.count-1); + if bewegt then begin + if bo1 then begin + list.add(int1); + end; + for int1:= 0 to fdatacols.count - 1 do begin + include(tdatacol(fdatacols.fitems[int1]).fstate,gps_noinvalidate); + end; + try + fdatacols.rearange(list); + finally + for int1:= 0 to fdatacols.count - 1 do begin + exclude(tdatacol(fdatacols.fitems[int1]).fstate,gps_noinvalidate); + end; + end; + ffixcols.rearange(list); + if refindex >= 0 then begin + for int1:= 0 to list.count-1 do begin //neue position bestimmen + if list.items[int1] = refindex then break; + end; + refindex:= int1; + end; + end; + finally + list.free; + end; + end; + result:= bewegt; +end; +*) + +procedure tcustomgrid.reorderrow; +var + lo,hi,pivot: integer; + sf: indexsortcomparemethodty; + bo1: boolean; +// int1: integer; + + function check(const a,b: integer): integer; + begin + result:= sf(a,b); + if result = 0 then begin + result:= a-b; + end; + end; //check + +begin + exclude(fstate1,gs1_rowsortinvalid); + if og_noreorderrow in foptionsgrid then begin + exclude(fstate1,gs1_sortvalid); + sort; + exit; + end; + if not (gs_isdb in fstate) then begin + if assigned(fonsort) then begin + sf:= {$ifdef FPC}@{$endif}doonsort; + end + else begin + sf:= {$ifdef FPC}@{$endif}fdatacols.sortfunc; + end; + if frowcount > 1 then begin + bo1:= true; + if row > 0 then begin + bo1:= sf(row-1,row) <= 0; + end; + if bo1 and (row < rowhigh) then begin + bo1:= sf(row+1,row) >= 0; + end; + if not bo1 then begin //position changed + lo:= 0; + hi:= rowhigh; + if check(hi,row) < 0 then begin //last? + lo:= hi; + end + else begin + if check(lo,row) > 0 then begin //first? + hi:= lo; + end + else begin + while hi-lo > 1 do begin + pivot:= (lo+hi) div 2; + if pivot = row then begin + if row - lo > hi-row then begin + dec(pivot); + end + else begin + inc(pivot); + end; + end; + if check(row,pivot) <= 0 then begin + hi:= pivot; + end + else begin + lo:= pivot; + end; + end; + end; + end; + bo1:= gs1_sortmoving in fstate1; + include(fstate1,gs1_sortmoving); + try + if row < lo then begin + moverow(row,lo); + end + else begin + moverow(row,hi); + end; + include(fstate1,gs1_sortvalid); + finally + if not bo1 then begin + exclude(fstate1,gs1_sortmoving); + end; + end; + end; + end; + end; +end; + +function tcustomgrid.getiassistiveclient(): iassistiveclient; +begin + result:= iassistiveclientgrid(self); +end; + +function tcustomgrid.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_grid]; + if gs1_scrolllimit in fstate1 then begin + include(result,asf_scrolllimit); + end; +end; + +function tcustomgrid.getassistivecellcaption( + const acell: gridcoordty): msestring; +begin + result:= ''; + if isvalidcell(acell) then begin + if acell.row < 0 then begin + with fixrows[acell.row] do begin + if acell.col < 0 then begin + if -acell.col <= captionsfix.count then begin + result:= captionsfix[acell.col].caption; + end; + end + else begin + if acell.col < captions.count then begin + result:= captions[acell.col].caption; + end; + end; + end; + end; + end; +end; + +function tcustomgrid.getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring; +begin + result:= ''; + aflags:= [asf_gridcell]; + if (acell.col >= 0) and (acell.col < datacols.count) then begin + if tdatacol(fdatacols.fitems[acell.col]).readonly then begin + include(aflags,asf_readonly); + end; + end; +end; + +function tcustomgrid.getassistivefocusedcell(): gridcoordty; +begin + result:= ffocusedcell; +end; + +function tcustomgrid.getassistivegridinfo(): assistivegridinfoty; +begin + with result do begin + colmin:= -fixcols.count; + colmax:= datacols.count-1; + rowmin:= -fixrows.count; + rowmax:= rowhigh; + end; +end; + +procedure tcustomgrid.sort; +var + bo1: boolean; + int1: integer; +begin + if gs_isdb in fstate then begin + include(fstate1,gs1_sortvalid); + exclude(fstate1,gs1_rowsortinvalid); + end + else begin + fdatacols.roworderinvalid; + beginupdate; + try + bo1:= factiverow = ffocusedcell.row; + for int1:= 0 to high(fdatacols.fitems) do begin + with tdatacol(fdatacols.fitems[int1]) do begin + if fdata <> nil then begin + tdatalist1(fdata).fgridsortdescend:= co_sortdescend in options; + end; + end; + end; + if assigned(fonsort) then begin + internalsort({$ifdef FPC}@{$endif}doonsort{fonsort},ffocusedcell.row); + end + else begin + internalsort({$ifdef FPC}@{$endif}fdatacols.sortfunc,ffocusedcell.row); + end; + if bo1 then begin + factiverow:= ffocusedcell.row; + end; + include(fstate1,gs1_sortvalid); + exclude(fstate1,gs1_rowsortinvalid); + layoutchanged; + finally + endupdate; + end; + if ffocusedcell.row >= 0 then begin + showcell(makegridcoord(invalidaxis,ffocusedcell.row)); + end; + end; +end; + +function tcustomgrid.copyselection: boolean; + //false if no copy +begin + result:= false; + if canevent(tmethod(foncopyselection)) then begin + foncopyselection(self,result); + end; +end; + +function tcustomgrid.pasteselection: boolean; + //false if no paste +begin + result:= false; + if canevent(tmethod(fonpasteselection)) then begin + fonpasteselection(self,result); + end; +end; + +function tcustomgrid.hascolumnsort: boolean; +begin + result:= (og_sorted in foptionsgrid) and + (assigned(fonsort) or (fdatacols.fsortcol >= 0) or + not (og_nodefaultsort in foptionsgrid)); +end; + +procedure tcustomgrid.sortchanged(const all: boolean); +begin + if not(csloading in componentstate) then begin + if assigned(fonsortchanged) then begin + fonsortchanged(self); + end; + if hascolumnsort and not (gs1_customsort in fstate1) then begin + if not all and (gs1_sortvalid in fstate1) and + (ffocusedcell.row >= 0) then begin + reorderrow; + end + else begin + sort; + end; + end + else begin + include(fstate1,gs1_sortvalid); + exclude(fstate1,gs1_rowsortinvalid); + invalidate; //for sort indicator + end; + end; +end; + +procedure tcustomgrid.sortinvalid(const acol: integer; const arow: integer); +begin + if not (gs1_sortchangelock in fstate1) and + ((acol < 0) or (fdatacols.fsortcol < 0) or + (acol = fdatacols.fsortcol) or + (acol = fdatacols.fsortcoldefault) or + assigned(fonsort)) then begin + if ((arow < 0) or (arow <> ffocusedcell.row)) then begin + exclude(fstate1,gs1_sortvalid); + end + else begin + include(fstate1,gs1_rowsortinvalid); + end; + end; +end; + +function tcustomgrid.checksort: boolean; +begin + result:= false; + if (fstate1 * [gs1_sortvalid,gs1_rowsortinvalid] <> [gs1_sortvalid]) and + not (gs1_sortchangelock in fstate1) and (fupdating = 0) then begin + sortchanged(false); + result:= true; + end; +end; + +procedure tcustomgrid.setrowcolors(const Value: tcolorarrayprop); +begin + frowcolors.assign(Value); +end; + +procedure tcustomgrid.setrowfonts(const Value: trowfontarrayprop); +begin + frowfonts.assign(Value); +end; + +function tcustomgrid.checkrowindex(var aindex: integer): boolean; +begin + if aindex < 0 then begin + if aindex = -1 then begin + aindex:= ffocusedcell.row; + end; + end; + result:= aindex >= 0; +end; + +function tcustomgrid.getrowcolorstate(index: integer): rowstatenumty; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.color[index]; + end + else begin + result:= -1; + end; +end; + +procedure tcustomgrid.setrowcolorstate(index: integer; const Value: rowstatenumty); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.color[index]:= value; + rowchanged(index); + rowstatechanged(index); + end; +end; + +function tcustomgrid.getrowlinecolorstate(index: integer): rowstatenumty; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.linecolor[index]; + end + else begin + result:= -1; + end; +end; + +procedure tcustomgrid.setrowlinecolorstate(index: integer; const Value: rowstatenumty); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.linecolor[index]:= value; + rowchanged(index); + rowstatechanged(index); + end; +end; + +function tcustomgrid.getrowlinecolorfixstate(index: integer): rowstatenumty; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.linecolorfix[index]; + end + else begin + result:= -1; + end; +end; + +procedure tcustomgrid.setrowlinecolorfixstate(index: integer; + const Value: rowstatenumty); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.linecolorfix[index]:= value; + rowchanged(index); + rowstatechanged(index); + end; +end; + +function tcustomgrid.getrowlinewidth(index: integer): rowlinewidthty; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.linewidth[index]; + end + else begin + result:= fdatarowlinewidth; + end; +end; + +procedure tcustomgrid.setrowlinewidth(index: integer; + const avalue: rowlinewidthty); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.linewidth[index]:= avalue; + end; +end; + +function tcustomgrid.getrowfontstate(index: integer): rowstatenumty; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.font[index]; + end + else begin + result:= -1; + end; +end; + +procedure tcustomgrid.setrowfontstate(index: integer; const Value: rowstatenumty); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.font[index]:= value; + rowchanged(index); + rowstatechanged(index); + end; +end; + +function tcustomgrid.getrowreadonlystate(index: integer): boolean; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.readonly[index]; + end + else begin + result:= false; + end; +end; + +procedure tcustomgrid.setrowreadonlystate(index: integer; + const avalue: boolean); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.readonly[index]:= avalue; + if index = row then begin + checkrowreadonlystate; + end; + rowstatechanged(index); + end; +end; + + +function tcustomgrid.getrowhidden(index: integer): boolean; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.hidden[index]; + end + else begin + result:= false; + end; +end; + +procedure tcustomgrid.setrowhidden(index: integer; const avalue: boolean); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.hidden[index]:= avalue; + end; +end; + +function tcustomgrid.getrowfoldlevel(index: integer): byte; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.foldlevel[index]; + end + else begin + result:= 0; + end; +end; + +procedure tcustomgrid.setrowfoldlevel(index: integer; const avalue: byte); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.foldlevel[index]:= avalue; + end; +end; + +function tcustomgrid.getrowfoldissum(index: integer): boolean; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.foldissum[index]; + end + else begin + result:= false; + end; +end; + +procedure tcustomgrid.setrowfoldissum(index: integer; const avalue: boolean); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.foldissum[index]:= avalue; + end; +end; + +function tcustomgrid.getrowheight(index: integer): integer; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.height[index]; + end + else begin + result:= 0; + end; +end; + +procedure tcustomgrid.setrowheight(index: integer; avalue: integer); +begin + if checkrowindex(index) then begin + if (avalue <> 0) and (avalue < fdatarowheightmin) then begin + avalue:= fdatarowheightmin; + end + else begin + if avalue > fdatarowheightmax then begin + avalue:= fdatarowheightmax; + end; + end; + fdatacols.frowstate.height[index]:= avalue; + end; +end; + +function tcustomgrid.rowfoldinfo: prowfoldinfoty; + //nil if focused row not visible +var + int1: integer; +begin //todo: optimize + result:= nil; + if row >= 0 then begin + internalupdatelayout; + if (fvisiblerowfoldinfo <> nil) and (row >= fvisiblerows[0]) and + (row <= fvisiblerows[high(fvisiblerows)]) then begin + for int1:= 0 to high(fvisiblerows) do begin + if fvisiblerows[int1] = row then begin + result:= @fvisiblerowfoldinfo[int1]; + break; + end; + end; + end; + end; +end; + +procedure tcustomgrid.checkrowreadonlystate; +begin + if (row >= 0) and rowreadonlystate[row] then begin + include(fstate,gs_rowreadonly); + end + else begin + exclude(fstate,gs_rowreadonly); + end; +end; + +procedure tcustomgrid.checkneedsrowheight; +var + int1: integer; + bo1: boolean; +begin + if not (csloading in componentstate) then begin + bo1:= gs_needsrowheight in fstate; + exclude(fstate,gs_needsrowheight); + with fdatacols do begin + for int1:= 0 to count -1 do begin + if gps_needsrowheight in tgridprop(pointerarty(fitems)[int1]).fstate then begin + include(self.fstate,gs_needsrowheight); + if not bo1 and (frowcount > 0) then begin + fdatacols.rowstate.change(-1); + end; + break; + end; + end; + end; + end; +end; + +procedure tcustomgrid.updaterowheight(const arow: integer; + var arowheight: integer); +begin + fdatacols.updaterowheight(arow,arowheight); +// ffixcols.updaterowheight(arow,arowheight); not used up to now +end; + +procedure tcustomgrid.setdragcontroller(const avalue: tdragcontroller); +begin + fdragcontroller.assign(avalue); +end; + +procedure tcustomgrid.setzebra_color(const avalue: colorty); +begin + if fzebra_color <> avalue then begin + fzebra_color:= avalue; + invalidate; + end; +end; + +procedure tcustomgrid.setzebra_start(const avalue: integer); +begin + if fzebra_start <> avalue then begin + fzebra_start:= avalue; + invalidate; + end; +end; + +procedure tcustomgrid.setzebra_height(const avalue: integer); +begin + if fzebra_height <> avalue then begin + fzebra_height:= avalue; + invalidate; + end; +end; + +procedure tcustomgrid.setzebra_step(const avalue: integer); +begin + if fzebra_step <> avalue then begin + fzebra_step:= avalue; + invalidate; + end; +end; + +function tcustomgrid.appinsrow(aindex: integer; + const auserinput: boolean = false): int32; +var + int1,int2: integer; + bo1: boolean; +begin + result:= invalidaxis; + if docheckcellvalue and container.canclose(window.focusedwidget) then begin + //for not null check in twidgetgrid + int1:= ffocusedcell.row; + checksort; + aindex:= aindex+ffocusedcell.row-int1; + if aindex < 0 then begin + aindex:= 0; + end; + if aindex > rowcount then begin + aindex:= rowcount; + end; + bo1:= gs1_sortchangelock in fstate1; + include(fstate1,gs1_sortchangelock); + try + int2:= 1; + internalinsertrow(aindex,int2,auserinput); + if int2 = 0 then begin + exit; + end; + if fdatacols.fnewrowcol < 0 then begin + int1:= ffocusedcell.col; + end + else begin + int1:= fdatacols.fnewrowcol; + end; + finally + if not bo1 then begin + exclude(fstate1,gs1_sortchangelock); + end; + end; + focuscell(makegridcoord(int1,aindex)); + if ffocusedcell.row = aindex then begin + fstate1:= fstate1 + [gs1_rowsortinvalid,gs1_rowinserted]; + end; + result:= aindex; + end; +end; + +procedure tcustomgrid.doinsertrow(const sender: tobject); +//var +// int1: integer; +begin + appinsrow(ffocusedcell.row,true); +end; + +procedure tcustomgrid.doappendrow(const sender: tobject); +var + bo1: boolean; +begin + bo1:= gs_appending in fstate; + include(fstate,gs_appending); + try + appinsrow(ffocusedcell.row+1,true); + finally + if not bo1 then begin + exclude(fstate,gs_appending); + end; + end; +end; + +function tcustomgrid.deleterowconfirmation(): boolean; +begin + with stockobjects do begin + result:= (og1_norowdeletequery in foptionsgrid1) or + askok(captions[sc_Delete_row_question],captions[sc_Confirmation]); + end; +end; + +procedure tcustomgrid.dodeleterow(const sender: tobject); +begin + if deleterowconfirmation() then begin + deleterow(ffocusedcell.row,1,true); + end; +end; + +procedure tcustomgrid.dodeleteselectedrows(const sender: tobject); +var + ar1: integerarty; + int1: integer; +begin + ar1:= fdatacols.getselectedrows; + if high(ar1) >= 0 then begin + if askok(stockobjects.textgenerators[tg_delete_n_selected_rows]( + [integer(length(ar1))]), + stockobjects.captions[sc_Confirmation]) then begin + beginupdate; + try + for int1:= high(ar1) downto 0 do begin + deleterow(ar1[int1],1,true); + end; + finally + endupdate; + end; + end; + end; +end; + +procedure tcustomgrid.dodeleterows(const sender: tobject); +begin + if (og_selectedrowsdeleting in foptionsgrid) and + (high(fdatacols.getselectedrows) >= 0) then begin + dodeleteselectedrows(sender); + end + else begin + if (og_rowdeleting in foptionsgrid) and (ffocusedcell.row >= 0) then begin + dodeleterow(sender); + end; + end; +end; + +procedure tcustomgrid.docopycells(const sender: tobject); +begin + copyselection; +end; + +procedure tcustomgrid.dopastecells(const sender: tobject); +begin + pasteselection; +end; + +function tcustomgrid.endanchor: gridcoordty; +begin + result:= fendanchor; +end; + +function tcustomgrid.startanchor: gridcoordty; +begin + result:= fstartanchor; +end; + +procedure tcustomgrid.beginnullchecking; +begin + inc(fnullchecking); +end; + +procedure tcustomgrid.endnullchecking; +begin + dec(fnullchecking); +end; + +procedure tcustomgrid.beginnonullcheck; +begin + inc(fnonullcheck); +end; + +procedure tcustomgrid.endnonullcheck; +begin + dec(fnonullcheck); +end; + +procedure tcustomgrid.beginnocheckvalue; +begin + inc(fnocheckvalue); +end; + +procedure tcustomgrid.endnocheckvalue; +begin + dec(fnocheckvalue); +end; + +function tcustomgrid.nocheckvalue: boolean; +begin + result:= fnocheckvalue > 0; +end; + +function tcustomgrid.cellclicked: boolean; +begin + result:= gs_cellclicked in fstate; +end; + +function tcustomgrid.cellvisible(const acell: gridcoordty): boolean; +var + int1: integer; +begin + result:= false; + if acell.col >= 0 then begin + if acell.col < fdatacols.count then begin + result:= fdatacols[acell.col].visible; + end; + end + else begin + int1:= - acell.col - 1; + if int1 < ffixcols.count then begin + result:= tfixcol(ffixcols.fitems[int1]).visible; + end; + end; + if result then begin + if acell.row < 0 then begin + int1:= -acell.row - 1; + if int1 < ffixrows.count then begin + result:= tfixrow(ffixrows.fitems[int1]).visible; + end + else begin + result:= false; + end; + end + else begin + result:= acell.row < frowcount; + end; + end; +end; + +procedure tcustomgrid.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if event = oe_changed then begin //todo: optimize + fdatacols.checktemplate(sender); + ffixcols.checktemplate(sender); + ffixrows.checktemplate(sender); + end; +end; + +procedure tcustomgrid.focuscolbyname(const aname: string); +var + col1: tdatacol; +begin + col1:= fdatacols.colbyname(aname); + if col1 <> nil then begin + col:= col1.index; + if not entered then begin + setfocus; + end; + end; +end; + +function tcustomgrid.getdragrect(const apos: pointty): rectty; +var + cell1: gridcoordty; +begin + cell1:= cellatpos(apos); + if isdatacell(cell1) then begin + result:= cellrect(cell1); + end + else begin + result:= inherited getdragrect(apos); + end; +end; + +procedure tcustomgrid.updaterowdata; +begin + //dummy +end; + +function tcustomgrid.getsorted: boolean; +begin + result:= og_sorted in optionsgrid; +end; + +procedure tcustomgrid.setsorted(const avalue: boolean); +begin + if avalue then begin + optionsgrid:= optionsgrid + [og_sorted]; + end + else begin + optionsgrid:= optionsgrid - [og_sorted]; + end; +end; + +function tcustomgrid.getfolded: boolean; +begin + result:= og_folded in optionsgrid; +end; + +procedure tcustomgrid.setfolded(const avalue: boolean); +begin + if avalue then begin + optionsgrid:= optionsgrid + [og_folded]; + end + else begin + optionsgrid:= optionsgrid - [og_folded]; + end; +end; + +function tcustomgrid.getrowstatelist: trowstatelist; +begin + result:= fdatacols.frowstate; +end; + +procedure tcustomgrid.setrowstatelist(const avalue: trowstatelist); +begin + fdatacols.frowstate.assign(avalue); +end; + +function tcustomgrid.updating: boolean; +begin + result:= fupdating > 0; +end; + +{$ifdef mse_with_ifi} + +procedure tcustomgrid.ifirowchange; +begin + if (fupdating = 0) and (fifiserverintf <> nil) and + not(ws_loadedproc in fwidgetstate) then begin + iifidataserver(fifiserverintf).valuechanged(iifigridlink(self)); + end; +end; + +function tcustomgrid.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifigridlink); +end; + +function tcustomgrid.getrowstate: tcustomrowstatelist; +begin + result:= fdatacols.frowstate; +end; + +procedure tcustomgrid.setifilink(const avalue: tifigridlinkcomp); +begin + mseificomp.setifilinkcomp(iifigridlink(self),avalue,tifilinkcomp(fifilink)); +end; + +procedure tcustomgrid.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +function tcustomgrid.getgriddata: tdatalist; +begin + result:= nil; +end; + +function tcustomgrid.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure tcustomgrid.getifivalue(var avalue); +begin + //dummy +end; + +procedure tcustomgrid.setifivalue(const avalue); +begin + //dummy +end; + +procedure tcustomgrid.updatereadonlystate; +begin + //dummy +end; + +{$endif} + +function tcustomgrid.hassort: boolean; +begin + result:= fstate1 * [gs1_gridsorted,gs1_dbsorted] <> []; +end; + +function tcustomgrid.updatesortcol(const avalue: integer): integer; +begin + result:= avalue; +end; + +function tcustomgrid.getsortdescend(const acol: integer): boolean; +begin + result:= false; + if (acol >= 0) and (acol < fdatacols.count) then begin + result:= co_sortdescend in tdatacol(fdatacols.fitems[acol]).foptions; + end; +end; + +function tcustomgrid.cellhasfocus: boolean; +begin + result:= entered; +end; + +function tcustomgrid.doonsort(const l,r: integer): integer; +begin + result:= 0; + fonsort(self,l,r,result); +end; + +procedure tcustomgrid.readgridframewidth(reader: treader); +var + int1: integer; +begin + int1:= reader.readinteger; + fframe.framei_right:= int1; + fframe.framei_top:= int1; + fframe.framei_left:= int1; + fframe.framei_bottom:= int1; +end; + +function tcustomgrid.getcellwindowpos: pointty; +var + rect1: rectty; +begin + if focusedcellvalid() then begin + internalupdatelayout; + rect1:= cellrect(focusedcell); + result:= subpoint(rect1.pos,fdatarect.pos); + end + else begin + result:= nullpoint; + end; +end; + +procedure tcustomgrid.setcellwindowpos(const avalue: pointty); +var + rect1: rectty; +begin + if focusedcellvalid() then begin + internalupdatelayout; + rect1:= cellrect(focusedcell); + subpoint1(rect1.pos,fdatarect.pos); //current distance + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + subpoint(avalue,rect1.pos)); + end; +end; + +function tcustomgrid.getrowwindowpos: int32; +begin + result:= getcellwindowpos.y; +end; + +procedure tcustomgrid.setrowwindowpos(const avalue: int32); +begin + setcellwindowpos(mp(getcolwindowpos,avalue)); +end; + +function tcustomgrid.getcolwindowpos: int32; +begin + result:= getcellwindowpos.x; +end; + +procedure tcustomgrid.setcolwindowpos(const avalue: int32); +begin + setcellwindowpos(mp(avalue,getrowwindowpos)); +end; + +procedure tcustomgrid.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('gridframewidth',{$ifdef FPC}@{$endif}readgridframewidth, + nil,false); +end; + +procedure tcustomgrid.resetuserinput(const avalue: boolean); +begin + if avalue then begin + include(fstate1,gs1_userinput); + end + else begin + exclude(fstate1,gs1_userinput); + end; +end; + +function tcustomgrid.setuserinput(const avalue: boolean): boolean; +begin + result:= gs1_userinput in fstate1; + resetuserinput(avalue); +end; + +function tcustomgrid.userinput: boolean; +begin + result:= gs1_userinput in fstate1; +end; + +procedure tcustomgrid.dorowsmodified; +begin + if userinput and canevent(tmethod(fonrowsmodified)) then begin + fonrowsmodified(self); + end; +end; + +procedure tcustomgrid.doedited(); +begin + if canevent(tmethod(fonedited)) then begin + fonedited(self); + end; +end; + +function tcustomgrid.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tdrawgrid } + +function tdrawgrid.createdatacols: tdatacols; +begin + result:= tdrawcols.create(self); +end; + +function tdrawgrid.getdatacols: tdrawcols; +begin + result:= tdrawcols(fdatacols); +end; + +procedure tdrawgrid.setdatacols(const value: tdrawcols); +begin + fdatacols.assign(value); +end; + +function tdrawgrid.getcols(index: integer): tdrawcol; +begin + result:= tdrawcol(fdatacols[index]); +end; + +procedure tdrawgrid.setcols(index: integer; const avalue: tdrawcol); +begin + tdrawcol(fdatacols[index]).assign(avalue); +end; + +{ tcellgrid } + +procedure tcellgrid.clientmouseevent(var info: mouseeventinfoty); +var + bo1,bo2: boolean; +begin + bo1:= es_child in info.eventstate; + bo2:= gs_cellclicked in fstate; + if bo2 and (info.shiftstate * keyshiftstatesmask = []) then begin + include(info.eventstate,es_child); + end; + inherited; + if not bo1 then begin + exclude(info.eventstate,es_child); + end; +end; + +{ tcustomstringgrid } + +constructor tcustomstringgrid.create(aowner: tcomponent); +begin + inherited; + feditor:= tinplaceedit.create(self,iedit(self)); +end; + +destructor tcustomstringgrid.destroy; +begin + inherited; + feditor.free; +end; + +function tcustomstringgrid.createdatacols: tdatacols; +begin + result:= tstringcols.create(self); +end; + +function tcustomstringgrid.getcols(index: integer): tstringcol; +begin + result:= tstringcol(fdatacols[index]); +end; + +procedure tcustomstringgrid.setcols(index: integer; const Value: tstringcol); +begin + fdatacols[index].Assign(value); +end; + +function tcustomstringgrid.getdatacols: tstringcols; +begin + result:= tstringcols(fdatacols); +end; + +procedure tcustomstringgrid.setdatacols(const value: tstringcols); +begin + fdatacols.assign(value); +end; + +procedure tcustomstringgrid.drawfocusedcell(const canvas: tcanvas); +var + po1: pointty; + rect1: rectty; + int1: integer; +begin + with cellinfoty(canvas.drawinfopo^) do begin + if scoe_checkbox in tcustomstringcol( + fdatacols.fitems[ffocusedcell.col]).foptionsedit then begin + inherited; + end + else begin + if calcautocellsize then begin + rect1:= feditor.textrect; + int1:= rect.cx - innerrect.cx + rect1.cx; + if int1 > autocellsize.cx then begin + autocellsize.cx:= int1; + end; + int1:= rect.cy - innerrect.cy + rect1.cy; + if int1 > autocellsize.cy then begin + autocellsize.cy:= int1; + end; + end + else begin + drawcellbackground(canvas); + po1:= cellrect(ffocusedcell,cil_paint).pos; + canvas.remove(po1); + feditor.dopaint(canvas); + canvas.move(po1); + end; + end; + end; +end; + +procedure tcustomstringgrid.doselectionchanged; +begin + if isdatacell(focusedcell) then begin + feditor.font:= fdatacols[ffocusedcell.col].rowfont(ffocusedcell.row) + end; + inherited; +end; + +procedure tcustomstringgrid.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + if isdatacell(ffocusedcell) and (oe1_autopopupmenu in + tcustomstringcol(fdatacols.fitems[ffocusedcell.col]). + foptionsedit1) then begin + feditor.updatepopupmenu(amenu,popupmenu,mouseinfo,false); + end; + inherited; +end; + +function tcustomstringgrid.getassistivecaretindex(): int32; +begin + result:= feditor.curindex; +end; + +function tcustomstringgrid.getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring; +begin + result:= inherited getassistivecelltext(acell,aflags); + include(aflags,asf_textedit); + if isdatacell(acell) then begin + result:= self[acell.col].getrowtext(acell.row); + end; +end; + +procedure tcustomstringgrid.setupeditor(const acell: gridcoordty; + const focusin: boolean); +var + col1: tcustomstringcol; + mstr1: msestring; + int1: integer; +begin + col1:= tcustomstringcol(fdatacols[acell.col]); + mstr1:= col1.getrowtext(acell.row); + col1.updatedisptext(mstr1); + int1:= 0; + if not focusin then begin + int1:= feditor.curindex; + end; + feditor.optionsedit1:= col1.foptionsedit1; + feditor.setup(mstr1,int1,not focusin,cellrect(acell,cil_inner), + cellrect(acell,cil_paint),nil,nil, + fdatacols[acell.col].rowfont(acell.row)); + feditor.textflags:= col1.textflags; + feditor.textflagsactive:= col1.ftextflagsactive; + feditor.passwordchar:= col1.passwordchar; + if scoe_checkbox in tcustomstringcol(fdatacols.fitems[acell.col]).optionsedit then begin + feditor.dodefocus; + end + else begin + if focusin then begin + feditor.dofocus; + end; + if active then begin + feditor.doactivate; + end; + end; +end; + +procedure tcustomstringgrid.rowstatechanged(const arow: integer); +begin + inherited; + if (arow = ffocusedcell.row) and (ffocusedcell.col >= 0) then begin + feditor.font:= fdatacols[ffocusedcell.col].rowfont(ffocusedcell.row) + end; +end; + +procedure tcustomstringgrid.dofocusedcellposchanged; +begin + inherited; + if ffocusedcell.col >= 0 then begin + feditor.updatepos(cellrect(ffocusedcell,cil_inner), + cellrect(ffocusedcell,cil_paint)); + end; +end; + +procedure tcustomstringgrid.focusedcellchanged; +begin + inherited; + setupeditor(ffocusedcell,true); +end; + +procedure tcustomstringgrid.checkrowreadonlystate; +begin + inherited; + if isdatacell(ffocusedcell) then begin + feditor.updatecaret; + end; +end; + +procedure tcustomstringgrid.docellevent(var info: celleventinfoty); +begin + inherited; + with info do begin + case eventkind of + cek_enter: begin + setupeditor(newcell,true); + end; + cek_exit: begin + feditor.dodefocus; + end; + end; + end; +end; + +procedure tcustomstringgrid.scrolled(const dist: pointty); +var + po1: pointty; +begin + inherited; + if focusedcellvalid then begin + po1:= dist; + if not scrollingcol then begin + po1.x:= 0; + end; + feditor.scroll(po1); + end; +end; + +procedure tcustomstringgrid.firstcellclick(const cell: gridcoordty; + var info: mouseeventinfoty); +begin + inherited; + feditor.setfirstclick(info); +end; + +procedure tcustomstringgrid.clientmouseevent(var info: mouseeventinfoty); +var + bo2: boolean; +begin + bo2:= gs_cellclicked in fstate; + inherited; + if (not (es_processed in info.eventstate) or (es_drag in info.eventstate)) and + focusedcellvalid and + (info.eventkind in mouseposevents) and + (gridcoordisequal(ffocusedcell,fmousecell) or bo2) and + not (scoe_checkbox in tcustomstringcol( + fdatacols.fitems[ffocusedcell.col]).optionsedit) then begin + feditor.mouseevent(info); + end; +end; + +procedure tcustomstringgrid.doactivate; +begin + if focusedcellvalid and + not (scoe_checkbox in tcustomstringcol( + fdatacols.fitems[ffocusedcell.col]).optionsedit) then begin + feditor.doactivate; + + end; + inherited; +end; + +procedure tcustomstringgrid.dodeactivate; +begin + if focusedcellvalid then begin + feditor.dodeactivate; + end; + inherited; +end; + +procedure tcustomstringgrid.dokeydown(var info: keyeventinfoty); +begin + if focusedcellvalid and not (scoe_checkbox in tcustomstringcol( + fdatacols.fitems[ffocusedcell.col]).optionsedit) then begin + feditor.dokeydown(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +function tcustomstringgrid.copyselection: boolean; +var + ar1: gridcoordarty; + wstr1: msestring; + int1,int2: integer; +begin + result:= inherited copyselection; + if result then begin + exit; + end; + ar1:= nil; //compiler waring + ar1:= datacols.selectedcells; + if ar1 <> nil then begin + wstr1:= ''; + int2:= ar1[0].row; + for int1:= 0 to high(ar1) do begin + if ar1[int1].row <> int2 then begin + removetabterminator(wstr1); + wstr1:= wstr1 + lineend; + int2:= ar1[int1].row; + end; + if co_cancopy in datacols[ar1[int1].col].foptions then begin + wstr1:= wstr1 + self.items[ar1[int1]] + c_tab; + end; + end; + removetabterminator(wstr1); + wstr1:= wstr1 + lineend; //terminator + msewidgets.copytoclipboard(wstr1); + result:= true; + end; +end; + +function tcustomstringgrid.pasteselection: boolean; +var + wstr1: msestring; + int1,int2,int3,int5: integer; + ar4,ar5: msestringarty; + ar1: gridcoordarty; + bo2: boolean; +begin + result:= inherited pasteselection; + if result = true then begin + exit; + end; + ar4:= nil; //compiler warning + ar5:= nil; //compiler warning + if fdatacols.canpaste{bo1} and pastefromclipboard(wstr1) then begin + ar4:= breaklines(wstr1); + bo2:= high(ar4) > 0; + if high(ar4) >= 0 then begin + if ar4[high(ar4)] = '' then begin + setlength(ar4,high(ar4)); //remove terminator + end; + beginupdate; + try + if (og1_pasteinselection in optionsgrid1) and (high(ar4) = 0) and + datacols.hasselection and (findchar(ar4[0],c_tab) = 0) then begin + ar1:= datacols.selectedcells; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + datacols[col][row]:= ar4[0]; + end; + end; + end + else begin + if not bo2 then begin + exit; + end; + int5:= row; + if int5 < 0 then begin + int5:= 0; + end; + datacols.clearselection; + // int1:= row; + bo2:= og_rowinserting in optionsgrid; + if bo2 then begin + insertrow(int5,length(ar4)); + end; + if high(ar4) >= rowcount - int5 then begin + setlength(ar4,rowcount-int5); + end; + // for int2:= int1 to int1 + high(ar4) do begin + // end; + for int1:= 0 to high(ar4) do begin + if bo2 then begin + datacols.selected[makegridcoord(invalidaxis,int5)]:= true; + end; + ar5:= splitstring(ar4[int1],c_tab); + int3:= 0; + for int2:= 0 to high(ar5) do begin + while (int3 < datacols.count) and + not (co_canpaste in datacols[int3].options) do begin + inc(int3); + end; + if int3 >= datacols.count then begin + break; + end; + if not bo2 then begin + datacols[int3].selected[int5]:= true; + end; + datacols[int3][int5]:= ar5[int2]; + inc(int3); + end; + inc(int5); + end; + end; + finally + endupdate; + end; + result:= true; + end; + end; +end; + +procedure tcustomstringgrid.editnotification(var info: editnotificationinfoty); +var + frame1: framety; + bo1: boolean; +begin + if focusedcellvalid then begin + with tcustomstringcol(fdatacols[ffocusedcell.col]) do begin + case info.action of + ea_textedited: begin + modified; + self.doedited(); + end; + ea_textentered: begin + bo1:= true; + if (gps_edited in fstate) or + (scoe_forcereturncheckvalue in foptionsedit) then begin + include(fstate,gps_edited); + bo1:= docheckcellvalue; + if scoe_eatreturn in foptionsedit then begin + info.action:= ea_none; + end; + end; + if bo1 and + (og_colchangeonreturnkey in fcellinfo.grid.optionsgrid) then begin + info.action:= ea_none; + self.colstep(fca_focusin,1,true,false,true); + end; + end; + ea_undo: begin + exclude(fstate,gps_edited); + end; + ea_caretupdating: begin + if not (gs_layoutupdating in self.fstate) then begin + frame1:= nullframe; + if fframe <> nil then begin + frame1:= fframe.innerframe; + end + else begin + frame1.left:= fcellinfo.innerrect.x; + end; + addpoint1(info.caretrect.pos, + showcaretrect(info.caretrect,frame1)); + end; + end; + end; + end; + end; +end; + +procedure tcustomstringgrid.dofontheightdelta(var delta: integer); +begin + inherited; + if ow1_autoscale in foptionswidget1 then begin + datarowheight:= datarowheight + delta; + end; +end; + +procedure tcustomstringgrid.checkcellvalue(var accept: boolean); +var + mstr1: msestring; + strcol: tcustomstringcol; +begin + if isdatacell(ffocusedcell) + and not (oe_readonly in feditor.optionsedit) then begin + strcol:= datacols[ffocusedcell.col]; + if gps_edited in strcol.fstate then begin + mstr1:= feditor.text; + strcol.checkcellvalue(mstr1,accept); + feditor.dofocus; + end; + end; +end; + +procedure tcustomstringgrid.rootchanged(const aflags: rootchangeflagsty); +begin + inherited; + feditor.poschanged; +end; + +procedure tcustomstringgrid.updatelayout; +var + rect2: rectty; +begin + inherited; + if focusedcellvalid then begin + rect2:= cellrect(ffocusedcell,cil_inner); + feditor.updatepos(rect2,rect2); + end; +end; + +function tcustomstringgrid.getoptionsedit: optionseditty; +begin + result:= [oe_exitoncursor]; + with tcustomstringcol(fdatacols[ffocusedcell.col]) do begin + if (ffocusedcell.col < 0) or isreadonly{(co_readonly in foptions)} then begin + include(result,oe_readonly); + end; + result:= result + getoptionsedit; +// stringcoltooptionsedit(foptionsedit,result); + end; +end; + +procedure tcustomstringgrid.updatecopytoclipboard(var atext: msestring); +var + col1: tcustomstringcol; +begin + col1:= tcustomstringcol(fdatacols[ffocusedcell.col]); + with col1 do begin + if canevent(tmethod(foncopytoclipboard)) then begin + foncopytoclipboard(col1,atext); + end; + end; +end; + +procedure tcustomstringgrid.updatepastefromclipboard(var atext: msestring); +var + col1: tcustomstringcol; +begin + col1:= tcustomstringcol(fdatacols[ffocusedcell.col]); + with col1 do begin + if canevent(tmethod(fonpastefromclipboard)) then begin + fonpastefromclipboard(col1,atext); + end; + end; +end; + + +function tcustomstringgrid.hasselection: boolean; +begin + result:= false; +end; + +function tcustomstringgrid.getitems(const cell: gridcoordty): msestring; +begin + result:= cols[cell.col][cell.row]; +end; + +procedure tcustomstringgrid.setitems(const cell: gridcoordty; const Value: msestring); +begin + cols[cell.col][cell.row]:= value; +end; + +function tcustomstringgrid.getcaretwidth: integer; +begin + result:= feditor.caretwidth; +end; + +procedure tcustomstringgrid.setcaretwidth(const value: integer); +begin + tinplaceedit1(feditor).fcaretwidth:= value; +end; + +procedure tcustomstringgrid.synctofontheight; +begin + inherited; + datarowheight:= datacols.defaultrowheight(); + { + if ow1_fontlineheight in optionswidget1 then begin + datarowheight:= font.lineheight; + end + else begin + with fdatacols.finnerframe do begin + datarowheight:= font.glyphheight + top + bottom; + end; + end; + } +end; + +function tcustomstringgrid.textclipped(const acell: gridcoordty; + out acellrect: rectty): boolean; +var + rect2: rectty; + canvas1: tcanvas; +begin + result:= isdatacell(acell); + if result then begin + acellrect:= clippedcellrect(acell,cil_inner); + canvas1:= getcanvas; + with datacols[acell.col] do begin + rect2:= textrect(canvas1,getrowtext(acell.row),acellrect,textflags,font); + end; + result:= not rectinrect(rect2,acellrect); + end + else begin + acellrect:= nullrect; + end; +end; + +function tcustomstringgrid.textclipped(const acell: gridcoordty): boolean; +var + rect1: rectty; +begin + result:= textclipped(acell,rect1); +end; + +function tcustomstringgrid.appendrow(const value: msestringarty; + const ashowlastrow: boolean = false): integer; +var + int1: integer; +begin + result:= inherited appendrow; + for int1:= 0 to high(value) do begin + datacols[int1][result]:= value[int1]; + end; + if ashowlastrow then begin + showlastrow(); + end; +end; + +function tcustomstringgrid.appendrow(const value: array of msestring; + const ashowlastrow: boolean = false): integer; +var + int1: integer; +begin + result:= inherited appendrow; + for int1:= 0 to high(value) do begin + datacols[int1][result]:= value[int1]; + end; + if ashowlastrow then begin + showlastrow(); + end; +end; + +function tcustomstringgrid.appendrow(const value: msestring; + const ashowlastrow: boolean = false): integer; +var + ar1: msestringarty; +begin + setlength(ar1,1); + ar1[0]:= value; + result:= appendrow(ar1,ashowlastrow); +end; + +function tcustomstringgrid.appenddatarow(const value: msestringarty): integer; +var + int1: integer; +begin + result:= inherited appenddatarow; + for int1:= 0 to high(value) do begin + datacols[int1][result]:= value[int1]; + end; +end; + +function tcustomstringgrid.appenddatarow(const value: array of msestring): integer; +var + int1: integer; +begin + result:= inherited appenddatarow; + for int1:= 0 to high(value) do begin + datacols[int1][result]:= value[int1]; + end; +end; + +function tcustomstringgrid.appenddatarow(const value: msestring): integer; +var + ar1: msestringarty; +begin + setlength(ar1,1); + ar1[0]:= value; + result:= appenddatarow(ar1); +end; + +function tcustomstringgrid.getcaretcliprect: rectty; +var + pt1: pointty; +begin + result:= cellrect(ffocusedcell); + if ffocusedcell.col >= 0 then begin + pt1:= clientpos; + with fdatarect do begin + if co_nohscroll in tcol(fdatacols.fitems[ffocusedcell.col]).options then begin + with fdatacols do begin + if ffocusedcell.col >= ffirsthscrollindex then begin + intersectrect1(result, + mr(fdatarecty.x+fdatarecty.cx-ffixcols.ftotsize+ffixcols.ffirstsize- + ftotsize+ffirstsize+pt1.x,y+pt1.y, + ftotsize-ffirstsize,cy)); + end + else begin + intersectrect1(result, + mr(fdatarecty.x+ffixcols.ffirstsize+pt1.x,y+pt1.y,ffirstsize,cy)); + end; + end; + end + else begin + intersectrect1(result,mr(x+pt1.x,y+pt1.y,cx,cy)); + end; + end; + end; +end; + +function tcustomstringgrid.canclose(const newfocus: twidget): boolean; +begin + result:= inherited canclose(newfocus); + if result then begin + checkcellvalue(result); + end; +end; + +function tcustomstringgrid.currentdatalist: tmsestringdatalist; +begin + result:= nil; + if ffocusedcell.col >= 0 then begin + result:= tmsestringdatalist( + tcustomstringcol(fdatacols.fitems[ffocusedcell.col]).fdata); + end; +end; + +procedure tcustomstringgrid.initnewcomponent(const ascale: real); +begin + inherited; + datacols.count:= 1; + synctofontheight(); +end; + +function tcustomstringgrid.locatecount: integer; +begin + result:= rowcount; + if currentdatalist = nil then begin + result:= 0; + end; +end; + +function tcustomstringgrid.locatecurrentindex: integer; +begin + result:= row; +end; + +procedure tcustomstringgrid.locatesetcurrentindex(const aindex: integer); +begin + row:= aindex; +end; + +function tcustomstringgrid.getkeystring(const aindex: integer): msestring; +var + list1: tmsestringdatalist; +begin + result:= ''; + list1:= currentdatalist; + if list1 <> nil then begin + result:= list1[aindex]; + end; +end; + +function tcustomstringgrid.getedited: boolean; +begin + result:= isdatacell(ffocusedcell) and cols[ffocusedcell.col].edited; +end; + +{ trowfontarrayprop } + +constructor trowfontarrayprop.create(const aowner: tcustomgrid); +begin + fgrid:= aowner; + inherited create(nil); +end; + +class function trowfontarrayprop.getitemclasstype: persistentclassty; +begin + result:= tfont; +end; + +procedure trowfontarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tfont.create; + item.assign(stockobjects.fonts[stf_default]); +end; + +procedure trowfontarrayprop.setitems(const index: integer; const avalue: tfont); +begin + checkindex(index); + if fitems[index] <> nil then begin + fitems[index].assign(avalue); + end; +end; + +function trowfontarrayprop.getitems(const index: integer): tfont; +begin + result:= tfont(inherited getitems(index)); +end; + +{ trowstatelist } + +constructor trowstatelist.create(const aowner: tcustomgrid); +var + level1: rowinfolevelty; +begin + fgrid:= aowner; + level1:= ril_normal; + if og_colmerged in aowner.optionsgrid then begin + level1:= ril_colmerge; + end; + if og_rowheight in aowner.optionsgrid then begin + level1:= ril_rowheight; + end; + inherited create(level1); +end; + +destructor trowstatelist.destroy; +begin + unlinksource(flinkfoldlevel); + unlinksource(flinkissum); + unlinksource(flinkfoldhidden); + inherited; + fvisiblerowmap.free; +end; + +function trowstatelist.isvisible(const arow: integer): boolean; +var +// po1: pintegeraty; + po2: prowstatety; + int1: integer; + by1: byte; +begin + if arow < fdirtyrow then begin + result:= prowstatety(inherited getitempo(arow))^.fold and + currentfoldhiddenmask = 0; + end + else begin + result:= false; + po2:= datapo; + inc(pchar(po2),arow*fsize); + for int1:= arow downto 0 do begin + by1:= po2^.fold and not currentfoldhiddenmask; + if by1 = 0 then begin + result:= true; + break; + end; + if (by1 and foldhiddenmask <> 0) or (by1 and foldlevelmask = 0) then begin + break; + end; + dec(pchar(po2),fsize); + end; + end; +end; + +procedure trowstatelist.counthidden(var aindex: integer); +var //todo: optimize + po1: prowstatety; + level1,level2: byte; +begin + po1:= datapo; + inc(pchar(po1),aindex*fsize); + level1:= po1^.fold and foldlevelmask; + while (aindex < count) do begin + level2:= po1^.fold and foldlevelmask; + if level2 < level1 then begin + break; + end; + if po1^.fold and foldhiddenmask = 0 then begin + if level2 > level1 then begin + counthidden(aindex); + end + else begin //same level + inc(fhiddencount); + inc(aindex); + inc(pchar(po1),fsize); + end; + end + else begin + inc(aindex); + inc(pchar(po1),fsize); + end; + end; +end; + +procedure trowstatelist.recalchidden; +var + int1: integer; + po1: prowstatety; + lev1: byte; + s1: integer; +begin + checkdirty(0); + fhiddencount:= 0; + po1:= datapo; + int1:= count; + s1:= size; + while int1 > 0 do begin + if po1^.fold and foldhiddenmask <> 0 then begin + inc(fhiddencount); + lev1:= po1^.fold and foldlevelmask; + dec(int1); + inc(pchar(po1),s1); + while (int1 > 0) and (po1^.fold and foldlevelmask > lev1) do begin + inc(fhiddencount); + dec(int1); + inc(pchar(po1),s1); + end; + end + else begin + dec(int1); + inc(pchar(po1),s1); + end; + end; +end; + +procedure trowstatelist.setupfoldinfo(asource: pbyte; + const acount: integer); +var + po1: prowstatety; + var int1: integer; + s1: integer; +begin + fgrid.rowcount:= acount; + po1:= datapo; + s1:= size; + for int1:= count-1 downto 0 do begin + po1^.fold:= asource^; + inc(pchar(po1),s1); + inc(asource); + end; + recalchidden; +end; + +procedure trowstatelist.internalshow(var aindex: integer); +var + int1,int2: integer; + po1: prowstatety; +begin + dec(fhiddencount); + int1:= aindex+1; + if (int1 < count) then begin + po1:= datapo; + inc(pchar(po1),fsize*aindex); + if (prowstatety(pchar(po1)+fsize)^.fold and foldlevelmask) > + (po1^.fold and foldlevelmask) then begin + int2:= fhiddencount; + counthidden(int1); + fhiddencount:= fhiddencount - 2*(fhiddencount-int2); + end; + end; + aindex:= int1; +end; + +procedure trowstatelist.show(const aindex: integer); +var + int1: integer; +begin + int1:= aindex; + internalshow(int1); + checkdirty(aindex); +end; + +procedure trowstatelist.internalhide(var aindex: integer); +var + int1: integer; + po1: prowstatety; +begin + inc(fhiddencount); + int1:= aindex+1; + if (int1 < count) then begin + po1:= datapo; + inc(pchar(po1),int1*fsize); + if (po1^.fold and foldlevelmask) > + (prowstatety(pchar(po1)-fsize)^.fold and foldlevelmask) then begin + counthidden(int1); + end; + end; + aindex:= int1; +end; + +procedure trowstatelist.hide(const aindex: integer); +var + int1: integer; +begin + int1:= aindex; + internalhide(int1); + checkdirty(aindex); +end; + +procedure trowstatelist.hidechildren(const arow: integer); +var + int1{,int2}: integer; + po0: pchar; + po1: prowstatety; + level1,level2: byte; + bo1: boolean; + s1: integer; +begin + checkindexrange(arow); + po0:= datapo; + s1:= size; + po1:= prowstatety(po0+arow*s1); + level1:= po1^.fold and foldlevelmask; + int1:= arow+1; + bo1:= false; + while int1 < count do begin + po1:= prowstatety(po0+int1*s1); + with po1^ do begin + level2:= fold and foldlevelmask; + if level2 <= level1 then begin + break; + end; + if fold and foldhiddenmask = 0 then begin + bo1:= true; + fold:= fold or foldhiddenmask; + fgrid.rowstatechanged(int1); + internalhide(int1); + end + else begin + while (int1 < count) and (po1^.fold and foldhiddenmask > + level2) do begin + inc(int1); + inc(pchar(po1),s1); + end; + end; + end; + end; + if bo1 then begin + checkdirty(arow+1); + fgrid.layoutchanged; + end; +end; + +procedure trowstatelist.showchildren(const arow: integer); +var + int1,int2: integer; + po0: pchar; + po1: prowstatety; + level1,level2: byte; + bo1: boolean; + s1: integer; +begin + checkindexrange(arow); + po0:= datapo; + s1:= size; + po1:= prowstatety(po0+arow*s1); + level1:= po1^.fold and foldlevelmask; + int1:= arow+1; + bo1:= false; + while int1 < count do begin + po1:= prowstatety(po0+int1*s1); + int2:= int1; + with po1^ do begin + level2:= fold and foldlevelmask; + if level2 <= level1 then begin + break; + end; + if fold and foldhiddenmask <> 0 then begin + bo1:= true; + fold:= fold and not foldhiddenmask; + fgrid.rowstatechanged(int1); + internalshow(int1); + end + else begin + while (int1 < count) and (po1^.fold and foldhiddenmask > + level2) do begin + inc(int1); + inc(pchar(po1),s1); + end; + end; + end; + if int1 = int2 then begin + break; //invalid + end; + end; + if bo1 then begin + checkdirty(arow+1); + fgrid.layoutchanged; + end; +end; + +procedure trowstatelist.sethidden(const index: integer; const avalue: boolean); +var + po1: prowstatety; + bo1: boolean; +begin + if ffolded then begin + po1:= getitempo(index); + bo1:= isvisible(index); + if updatebit(po1^.fold,foldhiddenbit,avalue) then begin + if avalue then begin + if bo1 then begin + hide(index); + end; + end + else begin + if not bo1 then begin + show(index); + end; + end; + checksyncfoldhiddensource(index,1); + fgrid.layoutchanged; + fgrid.rowstatechanged(index); + end; + end + else begin + raise exception.create('Grid not folded.'); + end; +end; + +procedure trowstatelist.setfoldlevel(const index: integer; avalue: byte); +var + po1,po2: prowstatety; + by1,by2: byte; + delta: integer; + int1: integer; + bo1: boolean; +begin + bo1:= of_validatelevel in fgrid.foptionsfold; + if bo1 then begin + if index = 0 then begin + if avalue = 0 then begin + bo1:= false; + end; + avalue:= 0; + end + else begin + by1:= (getitempo(index-1)^.fold and foldlevelmask) + 1; + if avalue > by1 then begin + avalue:= by1; + end + else begin + bo1:= false; + end; + end; + end; //bo1 -> avalue modified + + if of_shiftchildren in fgrid.foptionsfold then begin + normalizering; + po1:= getitempo(index); + po2:= po1; + by1:= po1^.fold and foldlevelmask; + delta:= integer(avalue) - integer(by1); + if delta <> 0 then begin + for int1:= index to fcount-1 do begin + by2:= po1^.fold and foldlevelmask; + if (by2 <= by1) and (int1 <> index) then begin + break; + end; + by2:= by2 + delta; + po1^.fold:= po1^.fold and not foldlevelmask or by2 and foldlevelmask; + inc(pbyte(po1),fsize); + end; + checkdirty(index); + checksyncfoldlevelsource(index,(pchar(po1)-pchar(po2)) div fsize); + end + else begin + if bo1 then begin + checksyncfoldlevelsource(index,1); + end; + end; + end + else begin + po1:= getitempo(index); + if replacebits1(byte(po1^.fold),byte(avalue),byte(foldlevelmask)) then begin + checkdirty(index); +// change(index); +// if bo1 then begin + checksyncfoldlevelsource(index,1); +// end +// else begin +// fgrid.rowstatechanged(index); +// end; + end + else begin + if bo1 then begin + checksyncfoldlevelsource(index,1); + end; + end; + end; +end; + +procedure trowstatelist.setfoldissum(const index: integer; + const avalue: boolean); +var + po1: prowstatety; + bo1: boolean; +begin + po1:= getitempo(index); + bo1:= po1^.flags and foldissummask <> 0; + if bo1 xor avalue then begin + if avalue then begin + po1^.flags:= po1^.flags or foldissummask; + end + else begin + po1^.flags:= po1^.flags and not foldissummask; + end; + checkdirty(index); + checksyncfoldissumsource(index,1); + end; +end; + +procedure trowstatelist.foldleveltosource(const index: integer; + const acount: integer); +var + po1: prowstatety; + po2: pinteger; + int1: integer; +begin + inc(ffoldlevelsourcelock); + try + with flinkfoldlevel.source do begin + if acount > 1 then begin + self.normalizering; + normalizering; + end; + po1:= self.getitempo(index); + po2:= getitempo(index); + for int1:= 0 to acount-1 do begin + po2^:= po1^.fold and foldlevelmask; + inc(pchar(po1),self.size); + inc(pchar(po2),size); + end; + if acount = 1 then begin + change(index); + end + else begin + change(-1); + end; + end; + if acount = 1 then begin + change(index); + fgrid.rowstatechanged(index); + end + else begin + change(-1); + fgrid.rowstatechanged(-1); + end; + finally + dec(ffoldlevelsourcelock); + end; +end; + +procedure trowstatelist.foldhiddentosource(const index: integer; + const acount: integer); +var + po1: prowstatety; + po2: pinteger; + int1: integer; +begin + inc(ffoldhiddensourcelock); + try + with flinkfoldhidden.source do begin + if acount > 1 then begin + self.normalizering; + normalizering; + end; + po1:= self.getitempo(index); + po2:= getitempo(index); + for int1:= 0 to acount-1 do begin + plongbool(po2)^:= po1^.fold and foldhiddenmask <> 0; + inc(pchar(po1),self.size); + inc(pchar(po2),size); + end; + if acount = 1 then begin + change(index); + end + else begin + change(-1); + end; + end; + if acount = 1 then begin + change(index); + fgrid.rowstatechanged(index); + end + else begin + change(-1); + fgrid.rowstatechanged(-1); + end; + finally + dec(ffoldhiddensourcelock); + end; +end; + + +procedure trowstatelist.foldissumtosource(const index: integer; + const acount: integer); +var + po1: prowstatety; + po2: pinteger; + int1: integer; +begin + inc(fissumsourcelock); + try + with flinkissum.source do begin + if acount > 1 then begin + self.normalizering; + normalizering; + end; + po1:= self.getitempo(index); + po2:= getitempo(index); + for int1:= 0 to acount-1 do begin + if po1^.flags and foldissummask <> 0 then begin + po2^:= longint(longbool(true)); + end + else begin + po2^:= 0; + end; + inc(pchar(po1),self.size); + inc(pchar(po2),size); + end; + if acount = 1 then begin + change(index); + end + else begin + change(-1); + end; + end; + if acount = 1 then begin + change(index); + fgrid.rowstatechanged(index); + end + else begin + change(-1); + fgrid.rowstatechanged(-1); + end; + finally + dec(fissumsourcelock); + end; +end; + +procedure trowstatelist.fillfoldlevel(const index: integer; + const acount: integer; const avalue: byte); +var + po1: prowstatety; + int1: integer; + bo1: boolean; +begin + if acount > 0 then begin + checkindexrange(index,acount); + normalizering; + po1:= getitempo(index); + checkdirty(index); + bo1:= false; + for int1:= 0 to acount-1 do begin + bo1:= bo1 or replacebits1(byte(po1^.fold),byte(avalue),byte(foldlevelmask)); + inc(pbyte(po1),fsize); + end; + if bo1 then begin + checksyncfoldlevelsource(index,acount); + end; + end; +end; + +procedure trowstatelist.setfolded(const avalue: boolean); +begin + if avalue <> ffolded then begin + ffolded:= avalue; + if avalue then begin + setlength(fvisiblerows,count); + fvisiblerowmap:= tintegerdatalist.create; + fvisiblerowmap.count:= count; + fdirtyvisible:= 0; + fdirtyrow:= 0; + end + else begin + fvisiblerows:= nil; + freeandnil(fvisiblerowmap); + fhiddencount:= 0; + end; + checkdirty(0); + end; +end; + +function trowstatelist.cellrow(const arow: integer): integer; +begin + result:= arow; + if ffolded and (arow >= 0) then begin + clean(arow); + result:= fvisiblerowmap[arow]; + end; +end; + +procedure trowstatelist.checkdirty(const arow: integer); +begin + if ffolded then begin + if arow < fdirtyrowheight then begin + fdirtyrowheight:= arow; + end; + if arow < fdirtyrow then begin + fdirtyrow:= arow; + fdirtyvisible:= 0; + if arow > 0 then begin + fdirtyvisible:= fvisiblerowmap[arow-1]; + end; + fgrid.layoutchanged; + end; + if arow < ffoldchangedrow then begin + ffoldchangedrow:= arow; + end; + end; +end; + +procedure trowstatelist.invalidatedirtyrowheight(const arow: int32); + //-2 -> count change +begin + if (arow = -2) then begin + if count < fdirtyrowheight then begin + fdirtyrowheight:= count; + end + else begin + if fdirtyrowheight > 0 then begin + dec(fdirtyrowheight); //could be above previous count + end; + end; + if count < fdirtyautorowheight then begin + fdirtyautorowheight:= count; + end + else begin + if fdirtyautorowheight > 0 then begin + dec(fdirtyautorowheight); //could be above previous count + end; + end; + end + else begin + fdirtyrowheight:= 0; + fdirtyautorowheight:= 0; + end; +end; + +procedure trowstatelist.checkdirtyautorowheight(const arow: integer); +var + bo1: boolean; +begin + bo1:= false; + if arow < 0 then begin + invalidatedirtyrowheight(arow); + bo1:= true; + end + else begin + if (finfolevel >= ril_rowheight) and (arow < count) then begin + with prowstaterowheightty(getitempo(arow))^ do begin + if rowheight.height <= 0 then begin + rowheight.height:= 0; + bo1:= true; + end; + end; + end; + if arow < fdirtyrowheight then begin + fdirtyrowheight:= arow; + bo1:= true; + end; + if arow < fdirtyautorowheight then begin + fdirtyautorowheight:= arow; + bo1:= true; + end; + end; + if bo1 then begin + fgrid.layoutchanged; + end; +end; + +procedure trowstatelist.change(const index: integer); +begin + if (finfolevel >= ril_rowheight) and (index < 0) then begin + invalidatedirtyrowheight(index); + inherited; + fgrid.layoutchanged; + end + else begin + inherited; + end; +end; + +procedure copyfoldlevel(const source,dest: pointer); +begin + prowstatety(dest)^.fold:= prowstatety(dest)^.fold and not foldlevelmask + or pinteger(source)^ and foldlevelmask; +end; + +procedure copyfoldhidden(const source,dest: pointer); +begin + if pinteger(source)^ <> 0 then begin + prowstatety(dest)^.fold:= prowstatety(dest)^.fold or foldhiddenmask; + end + else begin + prowstatety(dest)^.fold:= prowstatety(dest)^.fold and not foldhiddenmask; + end; +end; + +procedure copyissum(const source,dest: pointer); +begin + if pinteger(source)^ <> 0 then begin + prowstatety(dest)^.flags:= prowstatety(dest)^.flags or foldissummask; + end + else begin + prowstatety(dest)^.flags:= prowstatety(dest)^.flags and not foldissummask; + end; +end; + +procedure trowstatelist.cleanfolding(arow: integer; visibleindex: integer); +var + int1,int2: integer; + rowstat1: prowstatety; + visirow1: pinteger; + level1: byte; + bo1: boolean; +begin //todo: optimize + bo1:= sourceischanged(flinkfoldlevel) or sourceischanged(flinkfoldhidden); + checksourcecopy(flinkfoldlevel,@copyfoldlevel); + checksourcecopy(flinkfoldhidden,@copyfoldhidden); + checksourcecopy(flinkissum,@copyissum); + if bo1 then begin + recalchidden; + end; + int2:= 0; + if fdirtyvisible > 0 then begin + int2:= fvisiblerows[fdirtyvisible-1]+1; //first row to check + end; + rowstat1:= prowstatety(pchar(datapo)+int2*fsize); + visirow1:= @pintegeraty(fvisiblerowmap.datapo)^[int2]; + if fdirtyvisible < 0 then begin + int1:= -1; + end + else begin + int1:= fdirtyvisible-1; //visible row index + end; + while int1 < visibleindex do begin + while (rowstat1^.fold and foldhiddenmask <> 0) and (int2 <= arow) do begin + rowstat1^.fold:= rowstat1^.fold or currentfoldhiddenmask; + level1:= rowstat1^.fold and foldlevelmask; + visirow1^:= int1; + inc(pchar(rowstat1),fsize); + inc(visirow1); + inc(int2); + while (int2 <= arow) and + (rowstat1^.fold and foldlevelmask > level1) do begin + visirow1^:= int1; + rowstat1^.fold:= rowstat1^.fold or currentfoldhiddenmask; + inc(pchar(rowstat1),fsize); + inc(visirow1); + inc(int2); + end; + end; + if int2 <= arow then begin + inc(int1); + visirow1^:= int1; + if int1 > high(fvisiblerows) then begin //????? + setlength(fvisiblerows,high(fvisiblerows)+2); + end; + fvisiblerows[int1]:= int2; + rowstat1^.fold:= rowstat1^.fold and not currentfoldhiddenmask; + inc(int2); + inc(pchar(rowstat1),fsize); + inc(visirow1); + end + else begin + break; + end; + end; + fdirtyvisible:= int1 + 1; + fdirtyrow:= int2; +end; + +procedure trowstatelist.cleanvisible(visibleindex: integer); +var + int1: integer; +begin + if ffolded then begin + int1:= visiblerowcount; + if visibleindex >= int1 then begin + visibleindex:= int1 - 1; + end; + if (visibleindex >= fdirtyvisible) then begin + cleanfolding(count-1,visibleindex); + end; + end; +end; + +procedure trowstatelist.clean(arow: integer); +var + int1: integer; +begin + if ffolded then begin + int1:= count; + if arow >= int1 then begin + arow:= int1 -1; + end; + if arow >= fdirtyrow then begin + cleanfolding(arow,bigint); + end; + end; +end; + +procedure trowstatelist.cleanrowheight(const aindex: integer); + +//todo: optimize cleaning with co1_autorowheight + +var + int1,int2,int3,int4,int5: integer; + po1: prowstaterowheightty; + needsrowheightupdate: boolean; +begin + if aindex >= fdirtyrowheight then begin + ftopypos:= 0; + if count > 0 then begin + needsrowheightupdate:= gs_needsrowheight in fgrid.fstate; + po1:= dataporowheight; + inc(pchar(po1),fdirtyrowheight*fsize); + if fdirtyrowheight = 0 then begin + po1^.rowheight.ypos:= 0; + end; + int3:= po1^.rowheight.ypos; + if ffolded then begin + cleanvisible(aindex); + end; + for int1:= fdirtyrowheight to aindex do begin + if po1^.rowheight.linewidth = 0 then begin + int4:= fgrid.fdatarowlinewidth; + end + else begin + int4:= po1^.rowheight.linewidth - 1; + end; + int2:= fgrid.fdatarowheight + int4; + po1^.rowheight.ypos:= int3; + if not folded or (po1^.normal.fold and currentfoldhiddenmask = 0) then begin + if po1^.rowheight.height <= 0 then begin + if needsrowheightupdate then begin + int5:= fgrid.fdatarowheight; + if (po1^.rowheight.height = 0) or (int1 >= fdirtyautorowheight) then begin + fgrid.updaterowheight(int1,int5); + po1^.rowheight.height:= -int5; + end + else begin + int5:= -po1^.rowheight.height; + end; + int3:= int3 + int5 + int4; + end + else begin + int3:= int3 + int2; + end; + end + else begin + int3:= int3 + po1^.rowheight.height + int4; + end; + end; + inc(pchar(po1),fsize); + end; + if aindex >= count-1 then begin + ftopypos:= int3; + end + else begin + po1^.rowheight.ypos:= int3; + end; + fdirtyrowheight:= aindex+1; + if fdirtyrowheight > fdirtyautorowheight then begin + fdirtyautorowheight:= fdirtyrowheight; + end; + end; + end; +end; + + +function trowstatelist.visiblerows1(const astart: integer; + const aendy: integer): integerarty; +var + int1,int2: integer; + acount: integer; +begin //todo: optimize + result:= nil; + if count > 0 then begin + if og_rowheight in fgrid.foptionsgrid then begin + int1:= rowindex(aendy); + if int1 < 0 then begin + acount:= cellrow(count-1); + end + else begin + acount:= cellrow(int1); + end; + end + else begin + acount:= aendy div fgrid.fdatarowheight; + end; + acount:= acount - astart + 2; + if ffolded then begin + cleanvisible(astart+acount); + int1:= visiblerowcount; + if astart + acount > int1 then begin + acount:= int1 - astart; + end; + if acount > 0 then begin + result:= copy(fvisiblerows,astart,acount); + end + else begin + result:= nil; + end; + end + else begin + int1:= count - astart; + if acount > int1 then begin + acount:= int1; + end; + setlength(result,acount); + int2:= astart; + for int1:= 0 to high(result) do begin + result[int1]:= int2; + inc(int2); + end; + end; + end; +end; + +procedure trowstatelist.updatefoldinfo(const rows: integerarty; + var infos: rowfoldinfoarty); +var + int1,int2: integer; + po1: prowstatety; + po2: prowstatety; + po3: prowfoldinfoty; + level1,level2: byte; + lastrow: integer; +// visible1: boolean; + ar1: booleanarty; +begin + setlength(infos,length(rows)); + if high(rows) >= 0 then begin + for int1:= high(rows) downto 0 do begin + with infos[int1] do begin + getfoldstate(rows[int1],isvisible,foldlevel,haschildren,isopen); + setlength(nolines,foldlevel); + fillchar(nolines[0],(foldlevel)*sizeof(boolean),0); + end; + end; + po1:= datapo; + lastrow:= rows[high(rows)]; + po2:= prowstatety(pchar(po1)+lastrow*fsize); + level1:= po2^.fold and foldlevelmask; //level of last row + setlength(ar1,level1+1); + for int1:= lastrow+1 to count-1 do begin //mark linecontinuations + inc(pchar(po2),fsize); + with po2^ do begin + if fold and foldhiddenmask = 0 then begin + level2:= fold and foldlevelmask; + if (level2 = 0) then begin + break; + end; + if level2 <= level1 then begin + ar1[level2]:= true; //line continuation found + level1:= level2; + end; + end; + end; + end; + po3:= @infos[high(infos)]; + for int1:= high(ar1) downto 1 do begin + po3^.nolines[int1-1]:= not ar1[int1]; //set missing continuations + end; + for int1:= high(infos) - 1 downto 0 do begin + with infos[int1] do begin + for int2:= 0 to high(nolines) do begin + nolines[int2]:= (int2 > high(po3^.nolines)) or + (int2 < high(po3^.nolines)) and po3^.nolines[int2]; + end; + end; + dec(po3); + end; + end; +end; + +function trowstatelist.visiblerowstep(const arow: integer; const step: integer; + const autoappend: boolean): integer; +begin + if not folded then begin + result:= arow + step; + if result < 0 then begin + result:= 0; + end; + if result >= fgrid.frowcount then begin + if autoappend then begin + result:= fgrid.frowcount; + end + else begin + result:= fgrid.frowcount - 1; + end; + end; + end + else begin + result:= visiblerowtoindex(visiblerow(arow)+step); + if result < 0 then begin + if step < 0 then begin + result:= visiblerowtoindex(0); + end + else begin + if autoappend then begin + result:= fgrid.frowcount; + end + else begin + if visiblerowcount > 0 then begin + result:= visiblerowtoindex(visiblerowcount - 1); + end; + end; + end; + end; + end; +end; + +function trowstatelist.visiblerow(const arowindex: integer): integer; +begin + result:= invalidaxis; + if (arowindex >= 0) and (arowindex < count) then begin + if not ffolded then begin + result:= arowindex; + end + else begin + if not hidden[arowindex] then begin + clean(arowindex); + result:= fvisiblerowmap[arowindex]; + end; + end; + end; +end; + +function trowstatelist.visiblerowcount: integer; +begin + result:= count - fhiddencount; +end; + +function trowstatelist.visiblerowtoindex(const avisibleindex: integer): integer; +begin + result:= invalidaxis; + if (avisibleindex >= 0) then begin + if not ffolded then begin + if avisibleindex < count then begin + result:= avisibleindex; + end; + end + else begin + cleanvisible(avisibleindex); + if avisibleindex < visiblerowcount then begin +// cleanvisible(avisibleindex); + if fvisiblerows <> nil then begin + if avisibleindex > high(fvisiblerows) then begin + result:= fvisiblerows[high(fvisiblerows)]; + end + else begin + result:= fvisiblerows[avisibleindex]; + end; + end + end; + end; + end; +end; +{ +procedure trowstatelist.setcount(const value: integer); +var + bo1: boolean; +begin + if ffolded then begin + bo1:= value < fcount; + setlength(fvisiblerows,count); //????? + inherited; + if bo1 then begin + setlength(fvisiblerows,count); //????? + end; + end + else begin + inherited; + end; +end; + +procedure trowstatelist.clearbuffer; +begin + fvisiblerows:= nil; + inherited; +end; +} +procedure trowstatelist.updatedeletedrows(const index: integer; + const acount: integer); +var + int1: integer; + int2: integer; + po1: pinteger; +begin + if acount >= count then begin + fhiddencount:= 0; + end + else begin + clean(index+acount-1); + po1:= @pintegeraty(fvisiblerowmap.datapo)[index]; + dec(po1); + if index = 0 then begin + int2:= -1; + end + else begin + int2:= po1^; + end; + for int1:= acount-1 downto 0 do begin + inc(po1); + if (po1^ = int2) then begin + dec(fhiddencount); + end; + int2:= po1^; + end; + end; + checkdirty(index); +end; + +function trowstatelist.rowhidden(const arow: integer): boolean; +begin + result:= ffolded; + if result then begin + result:= hidden[arow]; + end; +end; + +function trowstatelist.nearestvisiblerow(const arow: integer): integer; +var + po1: prowstatety; + int1: integer; +begin + result:= arow; + if rowhidden(arow) then begin + po1:= datapo; + inc(pbyte(po1),arow*fsize); + for int1:= arow to count -1 do begin + if po1^.fold and foldhiddenmask = 0 then begin + result:= int1; + exit; + end; + inc(pbyte(po1),fsize); + end; + result:= invalidaxis; + po1:= datapo; + inc(pbyte(po1),(arow-1)*fsize); + for int1:= arow - 1 downto 0 do begin + if po1^.fold and foldhiddenmask = 0 then begin + result:= int1; + exit; + end; + dec(pbyte(po1),fsize); + end; + end; +end; + +procedure trowstatelist.getfoldstate(const arow: integer; + out aisvisible: boolean; out afoldlevel: byte; + out ahaschildren,aisopen: boolean); +var + po1: prowstatety; + nextfoldlevel: byte; + by1: byte; + bo1: boolean; +begin + by1:= 0; + nextfoldlevel:= 0; + checkindexrange(arow); + po1:= datapo; + inc(pchar(po1),arow*fsize); + with po1^ do begin + afoldlevel:= fold and foldlevelmask; + aisvisible:= fold and foldhiddenmask = 0; + bo1:= arow < count-1; + if bo1 then begin + by1:= prowstatety(pchar(po1)+fsize)^.fold; + nextfoldlevel:= by1 and foldlevelmask; + end; + ahaschildren:= bo1 and (nextfoldlevel > afoldlevel); + aisopen:= ahaschildren and (by1 and foldhiddenmask = 0); + end; +end; + +function trowstatelist.getstatdata(const index: integer): msestring; +var + int1: integer; +begin + with prowstaterowheightty(inherited getitempo(index))^ do begin + result:= inttostrmse(normal.fold + normal.flags shl 8); + if finfolevel >= ril_colmerge then begin + result:= result + ' ' + inttostrmse(colmerge.merged); + end; + if (finfolevel >= ril_rowheight) and + (og_savestate in fgrid.foptionsgrid) then begin + int1:= rowheight.height; + if int1 < 0 then begin + int1:= 0; //auto height + end; + result:= result + ' ' + inttostrmse(int1); + end; + end; +end; + +procedure trowstatelist.setstatdata(const index: integer; + const value: msestring); +var + ar1: msestringarty; + int1: integer; +begin + splitstring(value,ar1,msechar(' ')); + if high(ar1) >= 0 then begin + with prowstaterowheightty(inherited getitempo(index))^ do begin + int1:= strtoint(ar1[0]); + normal.fold:= int1 and $ff; + normal.flags:= (int1 shr 8) and $ff; + if (finfolevel >= ril_colmerge) and (high(ar1) > 0) then begin + colmerge.merged:= strtoint(ar1[1]); + end; + if (og_savestate in fgrid.foptionsgrid) and (finfolevel >= ril_rowheight) and (high(ar1) > 1) then begin + rowheight.height:= strtoint(ar1[2]); + if (rowheight.height < 0) then begin + rowheight.height:= 0; + end; + if (rowheight.height > 0) and + (rowheight.height < fgrid.fdatarowheightmin) then begin + rowheight.height:= fgrid.fdatarowheightmin; + end; + if rowheight.height > fgrid.fdatarowheightmax then begin + rowheight.height:= fgrid.fdatarowheightmax; + end; + end; + end; + end; +end; + +procedure trowstatelist.setheight(const index: integer; + const avalue: integer); +begin + with getitemporowheight(index)^ do begin + if avalue <> rowheight.height then begin + rowheight.height:= avalue; + if index < fdirtyrowheight then begin + fdirtyrowheight:= index; + fgrid.layoutchanged; + end; + end; + end; +end; + +procedure trowstatelist.setlinewidth(const index: integer; + avalue: rowlinewidthty); +begin + inc(avalue); + with getitemporowheight(index)^ do begin + if avalue <> rowheight.linewidth then begin + rowheight.linewidth:= avalue; + if index < fdirtyrowheight then begin + fdirtyrowheight:= index; + fgrid.layoutchanged; + end; + end; + end; +end; + +function trowstatelist.getrowypos(const index: integer): integer; +begin + result:= 0; + if index >= count then begin + if index > 0 then begin + cleanrowheight(count-1); + result:= ftopypos; + end; + end + else begin + cleanrowheight(index); + result:= getitemporowheight(index)^.rowheight.ypos; + end; +end; + +function trowstatelist.internalystep(const aindex: integer): integer; +begin + with prowstaterowheightty(getitempo(aindex))^ do begin + if aindex >= count - 1 then begin + result:= ftopypos - rowheight.ypos; + end + else begin + result:= prowstaterowheightty(getitempo(aindex+1))^.rowheight.ypos - rowheight.ypos; + end; + end; +end; + +procedure trowstatelist.internalystep(const aindex: integer; out ay: integer; + out acy: integer); +begin + with prowstaterowheightty(getitempo(aindex))^ do begin + ay:= rowheight.ypos; + if aindex >= count - 1 then begin + acy:= ftopypos - ay; + end + else begin + acy:= prowstaterowheightty(getitempo(aindex+1))^.rowheight.ypos - ay; + end; + end; +end; + +function trowstatelist.internalheight(const aindex: integer): integer; +begin + with prowstaterowheightty(getitempo(aindex))^.rowheight do begin + if height = 0 then begin + result:= fgrid.fdatarowheight; + end + else begin + result:= height; + if result < 0 then begin + result:= -result; //auto height + end; + end; + end; +{ + with prowstaterowheightty(getitempo(aindex))^ do begin + if aindex >= count - 1 then begin + result:= ftopypos - rowheight.ypos; + end + else begin + result:= prowstaterowheightty(getitempo(aindex+1))^.rowheight.ypos - rowheight.ypos; + end; + end; + result:= result - fgrid.fdatarowlinewidth; +} +end; + +function trowstatelist.currentrowheight(const index: integer): integer; +begin + cleanrowheight(index); + result:= internalheight(index); +end; + +function comprowypos(const l,r): integer; +begin + result:= integer(l) - rowstaterowheightty(r).rowheight.ypos; +end; + +function trowstatelist.rowindex(const aypos: integer): integer; +var + po1: prowstaterowheightty; + int1,int2: integer; + bo1: boolean; +begin + cleanrowheight(count-1); + po1:= dataporowheight; + bo1:= findarrayvalue(aypos,po1,fsize,count,@comprowypos,result); + if not bo1 then begin + dec(result); + if (result = count-1) then begin + with prowstaterowheightaty(po1)^[result] do begin + if aypos >= ftopypos then begin + result:= invalidaxis; + end; + end; + end; + if (result >= 0) and ffolded then begin + cleanvisible(result); + int2:= invalidaxis; + inc(pbyte(po1),result*fsize); + for int1:= result downto 0 do begin + if po1^.normal.fold and currentfoldhiddenmask = 0 then begin + int2:= int1; + break; + end; + dec(pbyte(po1),fsize); + end; + result:= int2; + end; + end; +end; + +procedure trowstatelist.initdirty; +begin + fdirtyvisible:= 0; + fdirtyrow:= 0; + fdirtyrowheight:= 0; + fdirtyautorowheight:= 0; +end; + +procedure trowstatelist.clearmemberitem(const subitem: integer; + const index: integer); +begin + case rowstatememberty(subitem-1) of + rsm_select: begin + selected[index]:= 0; + fgrid.invalidaterow(index); //todo: update selectstate + end; + rsm_color: begin + fgrid.rowcolorstate[index]:= -1; + end; + rsm_font: begin + fgrid.rowfontstate[index]:= -1; + end; + rsm_readonly: begin + fgrid.rowreadonlystate[index]:= false; + end; + rsm_foldlevel: begin + fgrid.rowfoldlevel[index]:= 0; + end; + rsm_foldissum: begin + fgrid.rowfoldissum[index]:= false; + end; + rsm_hidden: begin + if folded then begin + fgrid.rowhidden[index]:= false; + end; + end; + rsm_merged: begin + if finfolevel >= ril_colmerge then begin + merged[index]:= 0; + fgrid.datacols.mergechanged(index); + end; + end; + rsm_height: begin + if finfolevel >= ril_rowheight then begin + fgrid.rowheight[index]:= 0; + end; + end; + end; +end; + +procedure trowstatelist.setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); +begin + case rowstatememberty(subitem-1) of + rsm_select: begin + selected[index]:= avalue; + fgrid.invalidaterow(index); //todo: update selectstate + end; + rsm_color: begin + fgrid.rowcolorstate[index]:= avalue; + end; + rsm_font: begin + fgrid.rowfontstate[index]:= avalue; + end; + rsm_readonly: begin + fgrid.rowreadonlystate[index]:= avalue <> 0; + end; + rsm_foldlevel: begin + fgrid.rowfoldlevel[index]:= avalue; + end; + rsm_foldissum: begin + fgrid.rowfoldissum[index]:= avalue <> 0; + end; + rsm_hidden: begin + if folded then begin + fgrid.rowhidden[index]:= avalue <> 0; + end; + end; + rsm_merged: begin + if finfolevel >= ril_colmerge then begin + merged[index]:= avalue; + fgrid.datacols.mergechanged(index); + end; + end; + rsm_height: begin + if finfolevel >= ril_rowheight then begin + fgrid.rowheight[index]:= avalue; + end; + end; + end; +end; + +function trowstatelist.totchildrencount(const aindex: integer; + const acount: integer): integer; +var + lev1,lev2: byte; + ind1: integer; + int1: integer; + po1: prowstatety; +begin + lev2:= 0; + checkindexrange(aindex,acount); + normalizering; + po1:= getitempo(aindex); + lev1:= po1^.fold and foldlevelmask; + ind1:= aindex; + for int1:= acount - 1 downto 0 do begin + lev2:= po1^.fold and foldlevelmask; + if lev2 < lev1 then begin + lev1:= lev2; + ind1:= aindex - int1 + acount-1 + end; + inc(pbyte(po1),fsize); + end; + po1:= getitempo(ind1); + for int1:= ind1+1 to fcount-1 do begin + inc(pbyte(po1),fsize); + if po1^.fold and foldlevelmask <= lev2 then begin + break; + end; + end; + result:= int1 - aindex; +end; + +procedure trowstatelist.checksyncfoldlevelsource(const index: integer; + const acount: integer); +var + int1: integer; +begin + if flinkfoldlevel.source <> nil then begin + foldleveltosource(index,acount); + end + else begin + for int1:= index to index + acount - 1 do begin + change(int1); + fgrid.rowstatechanged(int1); + end; + end; +end; + +procedure trowstatelist.checksyncfoldhiddensource(const index: integer; + const acount: integer); +var + int1: integer; +begin + if flinkfoldhidden.source <> nil then begin + foldhiddentosource(index,acount); + end + else begin + for int1:= index to index + acount - 1 do begin + change(int1); + fgrid.rowstatechanged(int1); + end; + end; +end; + +procedure trowstatelist.checksyncfoldissumsource(const index: integer; + const acount: integer); +begin + if flinkissum.source <> nil then begin + foldissumtosource(index,acount); + end + else begin + if acount = 1 then begin + change(index); + fgrid.rowstatechanged(index); + end + else begin + change(-1); + fgrid.rowstatechanged(-1); + end; + end; +end; + +procedure trowstatelist.movegrouptoparent(const aindex: integer; + const acount: integer); +var + po1,po2,po3,po4: prowstatety; + lev1,lev2: integer; + int1,int2: integer; + by1: byte; +begin + if acount > 0 then begin + checkindexrange(aindex,acount); + normalizering; + int1:= aindex+acount-1; + po1:= getitempo(int1); + po3:= po1; + po4:= nil; + lev1:= 0; + for int1:= int1 downto aindex do begin + lev2:= po1^.fold and foldlevelmask; + po2:= po1; + for int2:= int1+1 to fcount -1 do begin + inc(pbyte(po2),fsize); + by1:= po2^.fold and foldlevelmask; + if by1 <= lev2 then begin + break; + end; + replacebits1(byte(po2^.fold),by1-1,byte(foldlevelmask)); + po3:= po2; + if po4 = nil then begin + po4:= po2; + end; + end; + if lev2 < lev1 then begin + break; + end; + inc(pbyte(po1),fsize); + end; + if po4 <> nil then begin + checksyncfoldlevelsource((pchar(po4)-pchar(datapo)) div fsize, + (pchar(po3)-pchar(getitempo(aindex))) div fsize); + end; + end; +end; + +procedure trowstatelist.sourcenamechanged(const atag: integer); +var + datalist1: tdatalist; + str1: string; + int1: integer; +begin + if not (csloading in fgrid.componentstate) then begin + if atag >= 0 then begin + str1:= getsourcename(atag); + datalist1:= nil; + if str1 <> '' then begin + datalist1:= fgrid.datacols.datalistbyname(str1); + end; + linksource(datalist1,atag); + end + else begin + for int1:= 0 to getsourcecount-1 do begin + str1:= getsourcename(int1); //link all source lists + datalist1:= nil; + if str1 <> '' then begin + datalist1:= fgrid.datacols.datalistbyname(str1); + end; + linksource(datalist1,int1); + end; + end; + end; +end; + +procedure trowstatelist.setsourcefoldlevel1(const avalue: string); +begin + flinkfoldlevel.name:= avalue; + sourcenamechanged(rowstatefoldleveltag); +end; + +procedure trowstatelist.setsourcefoldlevel(const avalue: string); +begin + {$ifdef mse_with_ifi} +// setifilinkfoldlevel1(nil); + {$endif} + setsourcefoldlevel1(avalue); +end; + +procedure trowstatelist.setsourcefoldhidden1(const avalue: string); +begin + flinkfoldhidden.name:= avalue; + sourcenamechanged(rowstatefoldhiddentag); +end; + +procedure trowstatelist.setsourcefoldhidden(const avalue: string); +begin + {$ifdef mse_with_ifi} +// setifilinkfoldlevel1(nil); + {$endif} + setsourcefoldhidden1(avalue); +end; + +procedure trowstatelist.setsourceissum1(const avalue: string); +begin + flinkissum.name:= avalue; + sourcenamechanged(rowstateissumtag); +end; + +procedure trowstatelist.setsourceissum(const avalue: string); +begin + {$ifdef mse_with_ifi} +// setifilinkissum1(nil); + {$endif} + setsourceissum1(avalue); +end; + +procedure trowstatelist.sourcechange(const sender: tdatalist; + const index: integer); +begin + inherited; + if sender <> nil then begin + if (sender = flinkfoldlevel.source) and (ffoldlevelsourcelock = 0) then begin + if checksourcechange(flinkfoldlevel,sender,index) then begin + if (of_shiftchildren in fgrid.optionsfold) and (index >= 0) then begin + foldlevel[index]:= pinteger(flinkfoldlevel.source.getitempo(index))^; + end + else begin + checkdirty(index); + change(index); + fgrid.rowstatechanged(index); + end; + end; + end + else begin + if (sender = flinkissum.source) and (fissumsourcelock = 0) then begin + if checksourcechange(flinkissum,sender,index) then begin + checkdirty(index); + change(index); + fgrid.rowstatechanged(index); + end; + end + else begin + if (sender = flinkfoldhidden.source) and (ffoldhiddensourcelock = 0) then begin + if checksourcechange(flinkfoldhidden,sender,index) then begin + checkdirty(index); + change(index); + fgrid.rowstatechanged(index); + end; + end + end; + end; + end; +end; + +function trowstatelist.getsourcecount: integer; +begin + result:= 3; +end; + +function trowstatelist.getsourceinfo(const atag: integer): plistlinkinfoty; +begin + case atag of + rowstatefoldleveltag: begin + result:= @flinkfoldlevel; + end; + rowstateissumtag: begin + result:= @flinkissum; + end; + rowstatefoldhiddentag: begin + result:= @flinkfoldhidden; + end; + else begin + result:= nil; + end; + end; +end; + +procedure trowstatelist.linksource(const source: tdatalist; + const atag: integer); +begin + case atag of + rowstatefoldleveltag: begin + internallinksource(source,atag,flinkfoldlevel.source); + end; + rowstateissumtag: begin + internallinksource(source,atag,flinkissum.source); + end; + rowstatefoldhiddentag: begin + internallinksource(source,atag,flinkfoldhidden.source); + end; + end; +end; + +function trowstatelist.getlinkdatatypes(const atag: integer): listdatatypesty; +begin + result:= []; + case atag of + rowstatefoldleveltag,rowstateissumtag,rowstatefoldhiddentag: begin + result:= [dl_integer]; + end; + end; +end; + +procedure trowstatelist.readstate(const reader; const acount: integer; + const name: msestring); +begin + inherited; + if (infolevel > ril_normal) or folded then begin + fgrid.layoutchanged; + end; +end; + +procedure trowstatelist.listdestroyed(const sender: tdatalist); +begin + if sender = flinkfoldhidden.source then begin + flinkfoldhidden.source:= nil; + end; + if sender = flinkfoldlevel.source then begin + flinkfoldlevel.source:= nil; + end; + if sender = flinkissum.source then begin + flinkissum.source:= nil; + end; + inherited; +end; + +{$ifdef mse_with_ifi} + +function trowstatelist.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure trowstatelist.setifiserverintf(const aintf: iifiserver); +begin + //dummy +end; + +procedure trowstatelist.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +procedure trowstatelist.ifisetvalue(var avalue; var accept: boolean); +begin + //dummy +end; + +procedure trowstatelist.getifivalue(var avalue); +begin + //dummy +end; + +procedure trowstatelist.setifivalue(const avalue); +begin + //dummy +end; + +function trowstatelist.getgriddata: tdatalist; +begin + result:= self; +end; + +function trowstatelist.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure trowstatelist.updatereadonlystate; +begin + //dummy +end; + +function trowstatelist.getdefaultifilink: iificlient; +begin + result:= iifidatalink(self); +end; + +{$endif} + +{ tstringgrid } + +procedure tstringgrid.initnewcomponent(const ascale: real); +begin + inherited; + optionsgrid:= optionsgrid + newcomponentoptionsgridadd; +end; + +{ tcelldragobject } + +constructor tcelldragobject.create(const draginfo: draginfoty; + const cellinfo: cellinfoty); +begin + fgrid:= cellinfo.grid; + fcell:= cellinfo.cell; + inherited create(cellinfo.grid,draginfo.dragobjectpo^,draginfo.pickpos); +end; + +constructor tcelldragobject.create(const agrid: tcustomgrid; + var ainstance: tdragobject; const apos: pointty); +begin + fgrid:= agrid; + fcell:= agrid.cellatpos(apos); + inherited create(agrid,ainstance,apos); +end; + +end. + diff --git a/mseide-msegui/lib/common/widgets/msegridsglob.pas b/mseide-msegui/lib/common/widgets/msegridsglob.pas new file mode 100644 index 0000000..0e951ce --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msegridsglob.pas @@ -0,0 +1,35 @@ +{ MSEgui Copyright (c) 1999-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msegridsglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface + +type + cellpositionty = (cep_none,cep_nearest,cep_topleft,cep_top,cep_topright, + cep_bottomright, + cep_bottom,cep_bottomleft,cep_left, + cep_rowcentered,cep_rowcenteredif); + + celleventkindty = (cek_none,cek_enter,cek_exit,cek_select, + cek_focusedcellchanged, + cek_mousemove,cek_mousepark,cek_firstmousepark, + cek_buttonpress,cek_buttonrelease, + cek_mouseenter,cek_mouseleave, + cek_keydown,cek_keyup); + + focuscellactionty = (fca_none,fca_entergrid,fca_exitgrid, + fca_reverse,fca_focusin,fca_focusinforce, + fca_focusinshift,fca_focusinrepeater,fca_setfocusedcell, + fca_selectstart,fca_selectend); + + cellzonety = (cz_none,cz_default,cz_checkbox,cz_image,cz_caption,cz_child); + +implementation +end. diff --git a/mseide-msegui/lib/common/widgets/mseguirttistat.pas b/mseide-msegui/lib/common/widgets/mseguirttistat.pas new file mode 100644 index 0000000..8900637 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseguirttistat.pas @@ -0,0 +1,92 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseguirttistat; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +interface +uses + msegui,mserttistat,mseglob,mseclasses,msestat,msestatfile; + +type + rttistatoption = (rso_autowritestat); + rttistatoptionsty = set of rttistatoption; + + getwidgetclassprocty = procedure (const sender: tobject; + var aclass: widgetclassty) of object; + tguirttistat = class(trttistat) + private + fongetdialogclass: getwidgetclassprocty; + fdialogclass: widgetclassty; + foptions: rttistatoptionsty; + fdialog: twidget; + fonbeforeedit: notifyeventty; + fonafteredit: notifyeventty; + fediting: boolean; + public + function edit: modalresultty; + property dialogclass: widgetclassty read fdialogclass write fdialogclass; + property dialog: twidget read fdialog; + property editing: boolean read fediting; + published + property options: rttistatoptionsty read foptions write foptions default []; + property ongetdialogclass: getwidgetclassprocty read fongetdialogclass + write fongetdialogclass; + property onbeforeedit: notifyeventty read fonbeforeedit write fonbeforeedit; + property onafteredit: notifyeventty read fonafteredit write fonafteredit; + end; + +implementation +uses + sysutils; + +{ tguirttistat } + +function tguirttistat.edit: modalresultty; +var +// dia1: twidget; + cla1: widgetclassty; +begin + result:= mr_none; + cla1:= fdialogclass; + if canevent(tmethod(fongetdialogclass)) then begin + fongetdialogclass(self,cla1); + end; + if cla1 <> nil then begin + fdialog:= cla1.create(nil); + fediting:= true; + try + {$ifdef mse_with_ifi} + objtovalues(fdialog); + {$endif} + if canevent(tmethod(fonbeforeedit)) then begin + fonbeforeedit(self); + end; + result:= fdialog.show(ml_application); + if result = mr_ok then begin + {$ifdef mse_with_ifi} + valuestoobj(fdialog); + {$endif} + if canevent(tmethod(fonafteredit)) then begin + fonafteredit(self); + end; + if (rso_autowritestat in foptions) and (statfile <> nil) then begin + statfile.writestat; + end; + end; + finally + fediting:= false; + freeandnil(fdialog); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/mseimage.pas b/mseide-msegui/lib/common/widgets/mseimage.pas new file mode 100644 index 0000000..965cdb3 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseimage.pas @@ -0,0 +1,188 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseimage; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,msegraphics,msegraphutils,msewidgets, + msebitmap,msegui,msemenus,mseevent,mseguiglob; +const + defaultimageoptionswidget = defaultoptionswidgetnofocus + [ow_mousewheel]; +type + timageframe = class(tscrollboxframe) + protected + procedure initinnerframe; override; + published + property framei_left default 0; + property framei_top default 0; + property framei_right default 0; + property framei_bottom default 0; + end; + + timage = class(tscrollingwidget) + private + fbitmap: tmaskedbitmap; + fcolorforeground: colorty; + fcolorbackground: colorty; + procedure setbitmap(const Value: tmaskedbitmap); + procedure bitmapchanged(const sender: tobject); + procedure setcolorbackground(const Value: colorty); + procedure setcolorforeground(const Value: colorty); + protected + procedure paintbmp(const acanvas: tcanvas; const abmp: tmaskedbitmap; + const dest: rectty); + procedure dopaintforeground(const canvas: tcanvas); override; + function calcminscrollsize: sizety; override; + procedure internalcreateframe; override; + procedure getautopaintsize(var asize: sizety); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure changed; virtual; + published + property bitmap: tmaskedbitmap read fbitmap write setbitmap; + property colorforeground: colorty read fcolorforeground //for monochrome bitmaps + write setcolorforeground default cl_black; + property colorbackground: colorty read fcolorbackground //for monochrome bitmaps + write setcolorbackground default cl_white; + property optionswidget default defaultimageoptionswidget; + property onmouseevent; + property onclientmouseevent; + property onchildmouseevent; + property onmousewheelevent; + property onkeydown; + property onkeyup; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; +end; + +implementation +uses + mseguiintf,msebits,msekeyboard; + +{ timage } + +constructor timage.create(aowner: tcomponent); +begin + fcolorforeground:= cl_black; + fcolorbackground:= cl_white; + fbitmap:= tmaskedbitmap.create(bmk_rgb); + fbitmap.onchange:= {$ifdef FPC}@{$endif}bitmapchanged; + inherited; + optionswidget:= defaultimageoptionswidget; +end; + +destructor timage.destroy; +begin + inherited; + fbitmap.Free; +end; + +procedure timage.changed; +begin + invalidate; + minscrollsizechanged; +end; + +procedure timage.paintbmp(const acanvas: tcanvas; const abmp: tmaskedbitmap; + const dest: rectty); +//var +// col1,col2: colorty; +begin +// col1:= acanvas.color; +// col2:= acanvas.colorbackground; +// acanvas.color:= fcolorforeground; +// acanvas.colorbackground:= fcolorbackground; +// abmp.paint(acanvas,makerect(nullpoint,clientsize)); +// abmp.paint(acanvas,innerclientrect); + abmp.paint(acanvas,dest,fcolorforeground,fcolorbackground); +// acanvas.color:= col1; +// acanvas.colorbackground:= col2; +end; + +procedure timage.dopaintforeground(const canvas: tcanvas); +begin + inherited; +// paintbmp(canvas,fbitmap,makerect(nullpoint,clientsize)); + paintbmp(canvas,fbitmap,innerclientrect); +end; + +procedure timage.setbitmap(const Value: tmaskedbitmap); +begin + fbitmap.assign(Value); +end; + +procedure timage.bitmapchanged(const sender: tobject); +begin + changed; +// invalidate; +end; + +procedure timage.setcolorbackground(const Value: colorty); +begin + if fcolorbackground <> value then begin + fcolorbackground := Value; + changed; + end; +end; + +procedure timage.setcolorforeground(const Value: colorty); +begin + if fcolorforeground <> value then begin + fcolorforeground := Value; + changed; + end; +end; + +function timage.calcminscrollsize: sizety; +var + size1: sizety; +begin + result:= inherited calcminscrollsize; + if fbitmap.alignment * [al_fit,al_thumbnail] = [] then begin + size1:= result; + if not (al_stretchx in fbitmap.alignment) then begin + size1.cx:= fbitmap.bitmap.width+innerframewidth.cx; + end; + if not (al_stretchy in fbitmap.alignment) then begin + size1.cy:= fbitmap.bitmap.height+innerframewidth.cy; + end; + if (result.cx < size1.cx) then begin + result.cx:= size1.cx; + end; + if (result.cy < size1.cy) then begin + result.cy:= size1.cy; + end; + end; +end; + +procedure timage.internalcreateframe; +begin + timageframe.create(iscrollframe(self),self); +end; + +procedure timage.getautopaintsize(var asize: sizety); +begin + asize:= fbitmap.size; + innertopaintsize(asize); +end; + +{ timageframe } + +procedure timageframe.initinnerframe; +begin + //dummy +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/mseinplaceedit.pas b/mseide-msegui/lib/common/widgets/mseinplaceedit.pas new file mode 100644 index 0000000..f08cc3b --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseinplaceedit.pas @@ -0,0 +1,3026 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseinplaceedit; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msegui,mseguiglob,msegraphics,msedrawtext,msegraphutils, + mserichstring,msetimer,mseevent,msetypes,msestrings,mseeditglob,msedatalist, + msemenus,mseactions,mseact,mseglob,msegridsglob,mseassistiveclient, + mseificompglob{$ifdef mse_with_ifi},mseifiglob{$endif}; + +const + defaultundomaxcount = 256; + defaultundobuffermaxsize = 100000; + defaultcaretwidth = -1; //use globalcaretwith + defaultglobalcaretwith = -300; //30% of 'o' + +type + editnotificationeventty = procedure(const sender: tobject; + var info: editnotificationinfoty) of object; + + iedit = interface(inullinterface) + function hasselection: boolean; + function getoptionsedit: optionseditty; + procedure editnotification(var info: editnotificationinfoty); + function getwidget: twidget; + procedure updatecopytoclipboard(var atext: msestring); + procedure updatepastefromclipboard(var atext: msestring); + function locatecount: integer; //number of locate values + function locatecurrentindex: integer; //index of current row + procedure locatesetcurrentindex(const aindex: integer); + function getkeystring(const aindex: integer): msestring; //locate text + function getedited: boolean; + end; + + inplaceeditstatety = (ies_focused,ies_emptytext, + ies_poschanging,ies_firstclick,ies_istextedit, + ies_forcecaret,ies_textrectvalid,ies_touched, + ies_edited, + ies_cangroupundo,ies_caretposvalid); + inplaceeditstatesty = set of inplaceeditstatety; + + tinplaceedit = class(tobject,iassistiveclientedit) + private + fwidget: twidget; + fintf: iedit; + finfo: drawtextinfoty; + ftextrectbefore: rectty; + ffont: tfont; + ffontstyle: fontstylesty; + ffontcolor: colorty; + ffontcolorbackground: colorty; + foldtext: msestring; + fselstart: integer; + fsellength: halfinteger; + fcurindex: integer; + curindexbackup,selstartbackup,sellengthbackup: integer; + fupdatecaretcount: integer; + fmoveindexcount: integer; + fcaretpos: pointty; + ftextrect: rectty; + ftextflags: textflagsty; + ftextflagsactive: textflagsty; + fmaxlength: integer; + fpasswordchar: msechar; + fmousemovepos: pointty; + fscrollsum: pointty; //for getcaretpos + frepeater: tsimpletimer; + ffiltertext: msestring; + foptionsedit1: optionsedit1ty; + procedure resetoffset; + function getinsertstate: boolean; + procedure setinsertstate(const Value: boolean); + procedure setsellength(const avalue: halfinteger); + procedure setselstart(const avalue: integer); + function getforcecaret: boolean; + procedure setforcecaret(const avalue: boolean); + procedure internalupdatecaret(force: boolean = false; + nocaret: boolean = false); + procedure updateselect; + procedure updatetextflags(active: boolean); + function internaldeleteselection(textinput: boolean): boolean; + procedure invalidatetextrect(const left,right: integer); + function invalidatepos: integer; + procedure invalidatetext(textinput,trailing: boolean; + startpos: integer = -bigint; endpos: integer = bigint); + //textinput-> notify client, trailing-> from curindex to right + procedure notify(var info: editnotificationinfoty); overload; + procedure notify(action: editactionty); overload; + procedure settextflags(const Value: textflagsty); + procedure settextflagsactive(const Value: textflagsty); + procedure setpasswordchar(const Value: msechar); + procedure setcaretwidth(const Value: integer); + procedure settext(const Value: msestring); + procedure setmaxlength(const Value: integer); + procedure checkmaxlength; + procedure movemouseindex(const sender: tobject); + procedure killrepeater; + procedure setrichtext(const avalue: richstringty); + procedure setformat(const avalue: formatinfoarty); + function nofullinvalidateneeded: boolean; + procedure setfont(const avalue: tfont); + procedure checktextrect; + function gettextrect: rectty; + + procedure setfiltertext(const avalue: msestring); + function getcaretpos: pointty; + protected + fupdating: integer; + fstate: inplaceeditstatesty; + fcaretwidth: integer; + frow: integer; + fbackup: msestring; + function caretonreadonly(): boolean; + function initactioninfo(aaction: editactionty): editnotificationinfoty; + function updateindex(const avalue: int32): int32; + procedure checkindexvalues; + procedure setcurindex(const avalue: integer); + procedure moveindex1(newindex: integer; shift: boolean = false; + donotify: boolean = true); + procedure deletechar; virtual; + procedure deleteback; virtual; + procedure internaldelete(start,len,startindex: integer; + selected: boolean); virtual; + function checkaction(const aaction: editactionty): boolean; overload; + function checkaction(var info: editnotificationinfoty): boolean; overload; + procedure enterchars(const chars: msestring); virtual; + function locating: boolean; + + procedure onundo(const sender: tobject); + procedure onredo(const sender: tobject); + procedure oncopy(const sender: tobject); + procedure oncut(const sender: tobject); + procedure onpaste(const sender: tobject); + procedure onselectall(const sender: tobject); + procedure redo; virtual; + function canredo: boolean; virtual; + function pastefromclipboard( + const buffer: clipboardbufferty): boolean; virtual; + //true if pasted + function copytoclipboard(const buffer: clipboardbufferty): boolean; //true if copied + function cuttoclipboard(const buffer: clipboardbufferty): boolean; virtual; //true if cut + function getiassistiveclient(): iassistiveclientedit virtual; + //iassistiveclient + function getassistiveparent(): iassistiveclient; + function getinstance: tobject; + function getassistivewidget(): tobject; + function getassistivename(): msestring; + function getassistivecaption(): msestring; + function getassistivetext(): msestring; + function getassistivecaretindex(): int32; //-1 -> none + function getassistivehint(): msestring; + function getassistiveflags(): assistiveflagsty; + {$ifdef mse_with_ifi} + function getifidatalinkintf(): iifidatalink; //can be nil + {$endif} + public + constructor create(aowner: twidget; editintf: iedit; + istextedit: boolean = false); + destructor destroy; override; + procedure setup(const text: msestring; cursorindex: integer; shift: boolean; + const atextrect,aclientrect: rectty; + const format: formatinfoarty = nil; + const tabulators: tcustomtabulators = nil; + const font: tfont = nil; noinvalidate: boolean = false); + procedure updatepos(const atextrect,aclientrect: rectty); + procedure movepos(const adist: pointty); //shifts textrects + procedure setscrollvalue(const avalue: real; const horz: boolean); + property font: tfont read ffont write setfont; + property fontstyle: fontstylesty read ffontstyle write ffontstyle default []; + property fontcolor: colorty read ffontcolor write ffontcolor default cl_none; + property fontcolorbackground: colorty read ffontcolor write + ffontcolorbackground default cl_none; + + property widget: twidget read fwidget; + function getfontcanvas: tcanvas; + + function beforechange: boolean; //true if not aborted + procedure begingroup; virtual; + procedure endgroup; virtual; + procedure scroll(const dist: pointty; const scrollcaret: boolean = true); + procedure beginupdate; //no caret update by index change + procedure endupdate; + function updating: boolean; + + procedure updatecaret; + + procedure dokeydown(var kinfo: keyeventinfoty); + procedure mouseevent(var minfo: mouseeventinfoty); + procedure updatepopupmenu(var amenu: tpopupmenu; const popupmenu: tpopupmenu; + var mouseinfo: mouseeventinfoty; + const hasselection: boolean); + procedure setfirstclick(var ainfo: mouseeventinfoty); + procedure doactivate; + procedure dodeactivate; + procedure dofocus; + procedure dodefocus; + procedure dopaint(const canvas: tcanvas); + procedure poschanged; + procedure dragstarted; //kills repeater + + procedure clear; virtual; + procedure initfocus; + procedure moveindex(newindex: integer; shift: boolean = false; + donotify: boolean = true); virtual; + procedure inserttext(const text: msestring; nooverwrite: boolean = true); + function copytoclipboard: boolean; //true if copied + function cuttoclipboard: boolean; //true if cut + function pastefromclipboard: boolean; //true if pasted + procedure deleteselection; + procedure clearundo; + procedure undo; virtual; + procedure selectall; + procedure clearselection; + property forcecaret: boolean read getforcecaret write setforcecaret; + + function optionsedit: optionseditty; + function canedit: boolean; + function canundo: boolean; virtual; + function cancopy: boolean; + function canpaste: boolean; + function getinsertcaretwidth(const canvas: tcanvas; + const afont: tfont): integer; + property insertstate: boolean read getinsertstate write setinsertstate; + property selstart: integer read fselstart write setselstart; + property sellength: halfinteger read fsellength write setsellength; + function selectedtext: msestring; + function hasselection: boolean; + property curindex: integer read fcurindex write setcurindex; + property caretpos: pointty read getcaretpos; + function lasttextclipped: boolean; //result of last drawing + function lasttextclipped(const acliprect: rectty): boolean; + function textclipped: boolean; + function mousepostotextindex(const apos: pointty): integer; + function textindextomousepos(const aindex: integer): pointty; + + property optionsedit1: optionsedit1ty read foptionsedit1 + write foptionsedit1 default defaultoptionsedit1; + property textflags: textflagsty read ftextflags write settextflags; + property textflagsactive: textflagsty read ftextflagsactive + write settextflagsactive; + property passwordchar: msechar read fpasswordchar + write setpasswordchar default #0; + property maxlength: integer read fmaxlength write setmaxlength default -1; + //<0-> no limit + property caretwidth: integer read fcaretwidth write setcaretwidth + default defaultcaretwidth; + //<0-> proportional to width of char 'o', -1024 -> 100% + property text: msestring read finfo.text.text write settext; + property oldtext: msestring read foldtext write foldtext; + property richtext: richstringty read finfo.text write setrichtext; + property format: formatinfoarty read finfo.text.format write setformat; + property destrect: rectty read finfo.dest; + property cliprect: rectty read finfo.clip; + property textrect: rectty read gettextrect; + property filtertext: msestring read ffiltertext write setfiltertext; + end; + + undotypety = (ut_none,ut_setpos,ut_inserttext,ut_overwritetext, + ut_deletetext); + undoflagty = (uf_selected,uf_backwards); + undoflagsty = set of undoflagty; + + undoinfoty = record + text: msestring; //first! + utype: undotypety; + selectstartpos,startpos,endpos: gridcoordty; + flags: undoflagsty; + textbefore: msestring; + link: boolean; + end; + + pundoinfoty = ^undoinfoty; + + iundo = interface(inullinterface) + procedure setedpos(const Value: gridcoordty; const select: boolean; + const donotify: boolean; const ashowcell: cellpositionty); + procedure deletetext(const startpos,endpos: gridcoordty); + procedure inserttext(const pos: gridcoordty; const text: msestring; + selected: boolean; + insertbackwards: boolean); + procedure getselectstart(var selectstartpos: gridcoordty); + procedure setselectstart(const selectstartpos: gridcoordty); + end; + + ttextundolist = class(tdynamicdatalist) + private + fintf: iundo; + flock: integer; + fundopo: integer; + flinked: integer; + fmaxsize: integer; + fbuffersize: integer; + function getitems(const index: integer): pundoinfoty; + function checkrecord(atype: undotypety; const astartpos,aendpos: gridcoordty; + selected: boolean; backwards: boolean; alink: boolean; + textlength: integer): pundoinfoty; + property items[const index: integer]: pundoinfoty read getitems; + function getcanundo: boolean; + function getcanredo: boolean; + function getlocked: boolean; + protected + procedure freedata(var data); override; //gibt daten frei + procedure beforecopy(var data); override; + public + constructor create(intf: iundo); reintroduce; + procedure clear; override; + procedure beginlink(linkto: undotypety; forcenew: boolean); + procedure endlink(forcenew: boolean); + procedure setpos(const endpos: gridcoordty; selected: boolean; + alink: boolean = false); + procedure inserttext(const startpos,endpos: gridcoordty; + const atext: msestring; + selected: boolean; backwards: boolean; alink: boolean = false); + procedure overwritetext(const startpos,endpos: gridcoordty; + const atext,atextbefore: msestring; selected: boolean; + alink: boolean = false); + procedure deletetext(const startpos,endpos: gridcoordty; + const atext: msestring; selected: boolean; + backwards: boolean; alink: boolean = false); + procedure undo; + procedure redo; + property canundo: boolean read getcanundo; + property canredo: boolean read getcanredo; + property maxcount default defaultundomaxcount; + property maxsize: integer read fmaxsize write fmaxsize default defaultundobuffermaxsize; + property locked: boolean read getlocked; + end; + + tundoinplaceedit = class(tinplaceedit) + private + protected + fundolist: ttextundolist; + procedure deletechar; override; + procedure deleteback; override; + procedure internaldelete(start,len,startindex: integer; selected: boolean); override; + procedure enterchars(const chars: msestring); override; + function pastefromclipboard( + const buffer: clipboardbufferty): boolean; override; + function cuttoclipboard(const buffer: clipboardbufferty): boolean; override; + public + constructor create(aowner: twidget; editintf: iedit; undointf: iundo; + istextedit: boolean); + destructor destroy; override; + procedure begingroup; override; + procedure endgroup; override; + function canundo: boolean; override; + function canredo: boolean; override; + procedure undo; override; + procedure redo; override; + procedure moveindex(newindex: integer; shift: boolean = false; + donotify: boolean = true); override; + + property undolist: ttextundolist read fundolist; + end; + +var + globalcaretwidth: integer = defaultglobalcaretwith; + +function textendpoint(const start: pointty; const text: msestring): pointty; + +implementation +uses + msekeyboard,sysutils,msesysutils,msebits,msewidgets,classes,msestockobjects, + mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + +var + overwrite: boolean; //insertstate + +function textendpoint(const start: pointty; const text: msestring): pointty; +var + y: integer; +begin + y:= countchars(text,c_linefeed); + result.y:= start.y + y; + if y = 0 then begin + result.x:= start.x + length(text); + end + else begin + result.x:= length(lastline(text)); + end; +end; + +{ tinplaceedit } + +constructor tinplaceedit.create(aowner: twidget; editintf: iedit; + istextedit: boolean = false); +begin + fwidget:= aowner; + fintf:= editintf; + fcaretwidth:= defaultcaretwidth; + fmaxlength:= -1; + ffontcolor:= cl_none; + ffontcolorbackground:= cl_none; + foptionsedit1:= defaultoptionsedit1; + if istextedit then begin + include(fstate,ies_istextedit); + end; +end; + +destructor tinplaceedit.destroy; +begin + killrepeater; + inherited; +end; + +procedure tinplaceedit.onundo(const sender: tobject); +begin + undo; +end; + +procedure tinplaceedit.onredo(const sender: tobject); +begin + redo; +end; + +procedure tinplaceedit.oncopy(const sender: tobject); +begin + copytoclipboard; +end; + +procedure tinplaceedit.oncut(const sender: tobject); +begin + cuttoclipboard; +end; + +procedure tinplaceedit.onpaste(const sender: tobject); +begin + pastefromclipboard; +end; + +procedure tinplaceedit.onselectall(const sender: tobject); +begin + selectall(); +end; + +procedure tinplaceedit.updatepopupmenu(var amenu: tpopupmenu; + const popupmenu: tpopupmenu; var mouseinfo: mouseeventinfoty; + const hasselection{, cangridcopy}: boolean); +var + states: array of actionstatesty; + sepchar: msechar; + bo1: boolean; + undoindex,redoindex,copyindex,cutindex,pasteindex: integer; +begin + if ies_cangroupundo in fstate then begin + setlength(states,5); + undoindex:= 0; + redoindex:= 1; + copyindex:= 2; + cutindex:= 3; + pasteindex:= 4; + if canredo then begin + states[redoindex]:= []; + end + else begin + states[redoindex]:= [as_disabled]; + end; + end + else begin + setlength(states,4); + undoindex:= 0; + redoindex:= 0; //invalid + copyindex:= 1; + cutindex:= 2; + pasteindex:= 3; + end; + if canundo then begin + states[undoindex]:= []; //undo + end + else begin + states[undoindex]:= [as_disabled]; + end; + bo1:= (cancopy or hasselection) and (passwordchar = #0); + if bo1 {or cangridcopy} then begin + states[copyindex]:= []; //copy + if bo1 and canedit then begin + states[cutindex]:= []; + end + else begin + states[cutindex]:= [as_disabled]; //cut + end; + end + else begin + states[copyindex]:= [as_disabled]; //copy + states[cutindex]:= [as_disabled]; //cut + end; + if canpaste then begin + states[pasteindex]:= []; //paste + end + else begin + states[pasteindex]:= [as_disabled]; + end; + if popupmenu <> nil then begin + sepchar:= popupmenu.shortcutseparator; + end + else begin + sepchar:= tcustommenu.getshortcutseparator(amenu); + end; + if ies_cangroupundo in fstate then begin + tpopupmenu.additems(amenu,fintf.getwidget,mouseinfo, + [stockobjects.captions[sc_Undohk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_groupundo])+')', + stockobjects.captions[sc_Redohk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_groupredo])+')', + stockobjects.captions[sc_Copyhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_copy])+')', + stockobjects.captions[sc_Cuthk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_cut])+')', + stockobjects.captions[sc_Pastehk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_paste])+')', + stockobjects.captions[sc_Select_allhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_selectall])+')' + ], + [[mao_nocandefocus],[mao_nocandefocus],[mao_nocandefocus], + [mao_nocandefocus],[mao_nocandefocus]], + states,[@onundo,@onredo,@oncopy,@oncut,@onpaste,@onselectall]); + end + else begin + tpopupmenu.additems(amenu,fintf.getwidget,mouseinfo, + [stockobjects.captions[sc_Undohk]+sepchar+'(Esc)', + stockobjects.captions[sc_Copyhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_copy])+')', + stockobjects.captions[sc_Cuthk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_cut])+')', + stockobjects.captions[sc_Pastehk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_paste])+')', + stockobjects.captions[sc_Select_allhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_selectall])+')' + ], + [[mao_nocandefocus],[mao_nocandefocus],[mao_nocandefocus], + [mao_nocandefocus],[mao_nocandefocus]], + states,[@onundo,@oncopy,@oncut,@onpaste,@onselectall]); + end; +end; + +procedure tinplaceedit.notify(var info: editnotificationinfoty); +begin + fintf.editnotification(info); +end; + +procedure tinplaceedit.notify(action: editactionty); +var + info: editnotificationinfoty; +begin + info:= initactioninfo(action); + notify(info); +end; + +function tinplaceedit.checkaction(var info: editnotificationinfoty): boolean; +var + aaction: editactionty; +begin + aaction:= info.action; + fintf.editnotification(info); + result:= aaction = info.action; +end; + +function tinplaceedit.checkaction(const aaction: editactionty): boolean; +var + info: editnotificationinfoty; +begin + info:= initactioninfo(aaction); + result:= checkaction(info); +end; + +function tinplaceedit.beforechange: boolean; +begin + result:= checkaction(ea_beforechange); +end; + +procedure tinplaceedit.killrepeater; +begin + freeandnil(frepeater); +end; + +function tinplaceedit.locating: boolean; +begin + result:= iedit(fintf).getoptionsedit * [oe_locate,oe_readonly] = + [oe_locate,oe_readonly]; +end; + +procedure tinplaceedit.setup(const text: msestring; + cursorindex: integer; shift: boolean; + const atextrect, aclientrect: rectty; + const format: formatinfoarty = nil; + const tabulators: tcustomtabulators = nil; + const font: tfont = nil; + noinvalidate: boolean = false); +begin +// exclude(fstate,ies_emptytext); + finfo.text.text:= text; + ffiltertext:= ''; + if locating then begin + fcurindex:= 0; + end + else begin + fcurindex:= cursorindex; + end; + ftextrect := atextrect; + finfo.dest:= atextrect; + finfo.clip:= aclientrect; + if atextrect.cx < 0 then begin + ftextrect.cx:= 0; + finfo.dest.cx:= 0; + end; + if atextrect.cy < 0 then begin + ftextrect.cy:= 0; + finfo.dest.cy:= 0; + end; + if aclientrect.cx < 0 then begin + finfo.clip.cx:= 0; + end; + ffont:= font; + resetoffset; + finfo.text.format:= copy(format); + finfo.tabulators:= tabulators; + if not shift then begin + fselstart:= updateindex(fcurindex); + fsellength:= 0; + end; + setselected1(finfo.text,fselstart,fsellength); + if fcurindex > length(text) then begin + fcurindex:= length(text); + end; + if not noinvalidate then begin + invalidatetext(false,false); + end; + internalupdatecaret; +end; + +procedure tinplaceedit.updatepos(const atextrect,aclientrect: rectty); +begin + ftextrect := atextrect; + finfo.dest:= atextrect; + finfo.clip:= aclientrect; + invalidatetext(false,false); + internalupdatecaret; +end; + +procedure tinplaceedit.movepos(const adist: pointty); +begin + addpoint1(ftextrect.pos,adist); + addpoint1(finfo.dest.pos,adist); + addpoint1(finfo.clip.pos,adist); + invalidatetext(false,false); + internalupdatecaret; +end; + +procedure tinplaceedit.setfont(const avalue: tfont); +begin + if ffont <> avalue then begin + ffont:= avalue; + invalidatetext(false,false); + internalupdatecaret; + end; +end; + +procedure tinplaceedit.clear; +begin + fsellength:= 0; + fselstart:= 0; + finfo.text.text:= ''; + finfo.text.format:= nil; + clearundo; + invalidatetext(true,false); +end; + +function tinplaceedit.initactioninfo(aaction: editactionty): editnotificationinfoty; +begin + finalize(result); + fillchar(result,sizeof(result),0); + result.action:= aaction; +end; + +function tinplaceedit.getinsertcaretwidth(const canvas: tcanvas; const afont: tfont): integer; +var + int1: integer; +begin + if fcaretwidth = -1 then begin + int1:= globalcaretwidth; + end + else begin + int1:= fcaretwidth; + end; + if int1 < 0 then begin + result:= (canvas.getfontmetrics('o',afont).sum * - int1 - + int1 div 2) div 1024; //round + if result = 0 then begin + result:= 1; + end + end + else begin + result:= int1; + end; +end; + +function tinplaceedit.caretonreadonly(): boolean; +begin + result:= (oe_caretonreadonly in fintf.getoptionsedit) or fwidget.canassistive; +end; + +procedure tinplaceedit.internalupdatecaret(force: boolean = false; + nocaret: boolean = false); +var + wstr1: msestring; + metrics: fontmetricsty; + po1: pointty; + canvas: tcanvas; + afont,font1: tfont; + actioninfo: editnotificationinfoty; + int1,int2: integer; + posbefore: rectty; + updatecaretcountref: integer; +// options1: optionseditty; + haspasswordchar: boolean; + +begin + if (fupdating > 0) or (ws_destroying in fwidget.widgetstate) or + (csdestroying in fwidget.componentstate) then begin + exit; //no createwindow by getcanvas + end; + wstr1:= ''; //compiler warning + inc(fupdatecaretcount); + updatecaretcountref:= fupdatecaretcount; + posbefore:= finfo.dest; +// options1:= fintf.getoptionsedit; + if not (canedit or caretonreadonly()) then begin + nocaret:= true; + end; + actioninfo:= initactioninfo(ea_caretupdating); + if fwidget.active or (ies_forcecaret in fstate) or force then begin + canvas:= getfontcanvas; + haspasswordchar:= (fpasswordchar <> #0) and not (ies_emptytext in fstate); + if haspasswordchar then begin + wstr1:= finfo.text.text; + finfo.text.text:= stringfromchar(fpasswordchar,length(wstr1)); + end; +// fcaretpos:= textindextopos(canvas,finfo,fcurindex); + fcaretpos:= textindextomousepos(fcurindex); + //updates finfo.res + include(fstate,ies_caretposvalid); + fscrollsum:= nullpoint; + int1:= finfo.dest.x + finfo.res.cx; + int2:= ftextrect.x + ftextrect.cx; + if int1 < int2 then begin //right margin + int1:= int2 - int1 + finfo.dest.x; + if int1 > ftextrect.x then begin + int1:= ftextrect.x; + end; + finfo.dest.x:= int1; + end; + int1:= finfo.dest.y + finfo.res.cy; + int2:= ftextrect.y + ftextrect.cy; + if int1 < int2 then begin //bottom margin + int1:= int2 - int1 + finfo.dest.y; + if int1 > ftextrect.y then begin + int1:= ftextrect.y; + end; + finfo.dest.y:= int1; + end; + fcaretpos.x:= fcaretpos.x + finfo.dest.x - posbefore.x; + fcaretpos.y:= fcaretpos.y + finfo.dest.y - posbefore.y; + //add shift + + if haspasswordchar then begin + finfo.text.text:= wstr1; + end; + with finfo,actioninfo do begin + int1:= getinsertcaretwidth(canvas,ffont); + afont:= canvas.font; + if insertstate and not nocaret then begin + caretrect.cx:= int1; + showrect.x:= fcaretpos.x; //for clamp in view + showrect.cx:= caretrect.cx div 2; + if showrect.cx = 0 then begin + showrect.cx:= 1; + end; + caretrect.x:= fcaretpos.x - showrect.cx; + inc(caretrect.x,afont.caretshift); + if showrect.x > caretrect.x then begin + showrect.x:= caretrect.x; + end; + int1:= caretrect.x+caretrect.cx-(showrect.x+showrect.cx); + if int1 > 0 then begin + showrect.cx:= showrect.cx+int1; + end; + end + else begin + font1:= tfont.create; + font1.assign(afont); + font1.style:= getcharstyle(text.format,fcurindex).fontstyle; + if fcurindex < length(text.text) then begin + metrics:= canvas.getfontmetrics(text.text[fcurindex+1],font1); + end + else begin + metrics:= canvas.getfontmetrics('o',font1); + end; + font1.Free; + caretrect.cx:= metrics.width; + if caretrect.cx < int1 then begin + caretrect.cx:= int1; + end; + if not nocaret then begin + caretrect.x:= fcaretpos.x + metrics.leftbearing; + end + else begin + caretrect.x:= fcaretpos.x; + caretrect.cx:= 0; + end; + showrect.x:= caretrect.x; + showrect.cx:= caretrect.cx; + end; + + caretrect.y:= fcaretpos.y - afont.ascent; + caretrect.cy:= afont.ascent + afont.descent; + showrect.y:= caretrect.y; + showrect.cy:= caretrect.cy; + + po1:= nullpoint; + if ies_focused in fstate then begin + with showrect do begin //bring caret into clientrect; + if x < ftextrect.x then begin + po1.x:= ftextrect.x - x; + end + else begin + if x + cx > ftextrect.x + ftextrect.cx then begin + po1.x:= ftextrect.x + ftextrect.cx - x -cx; + end; + end; + if y < ftextrect.y then begin + po1.y:= ftextrect.y - y; + end + else begin + if y + cy > ftextrect.y + ftextrect.cy then begin + po1.y:= ftextrect.y + ftextrect.cy - y -cy; + end; + end; + end; + if not isnullpoint(po1) then begin + if not (tf_clipi in flags) then begin + addpoint1(dest.pos,po1); + int1:= dest.x - ftextrect.x; + if int1 > 0 then begin //use cliprect space + int2:= ftextrect.x - clip.x; + if int1 > int2 then begin + int1:= int2; + end; + po1.x:= po1.x - int1; + dest.x:= dest.x - int1; + end; + end + else begin + if tf_right in flags then begin + dest.cx:= dest.cx + po1.x; + end + else begin + if tf_xcentered in flags then begin + dest.x:= dest.x + po1.x; + int1:= dest.x - ftextrect.x; + int2:= ftextrect.y+ftextrect.cx - (dest.x+dest.cx); + if int2 > int1 then begin //adjust to textrect + int1:= int2; + end; + dest.x:= dest.x - int1; + dest.cx:= dest.cx + 2*int1; + end + else begin + dest.x:= dest.x + po1.x; + dest.cx:= dest.cx - po1.x; + end; + end; + if tf_bottom in flags then begin + dest.cy:= dest.cy + po1.y; + end + else begin + if tf_ycentered in flags then begin + dest.y:= dest.y + po1.y; + int1:= dest.y - ftextrect.y; + int2:= ftextrect.y+ftextrect.cy - (dest.y+dest.cy); + if int2 > int1 then begin //adjust to textrect + int1:= int2; + end; + dest.y:= dest.y - int1; + dest.cy:= dest.cy + 2*int1; + end + else begin + dest.y:= dest.y + po1.y; + dest.cy:= dest.cy - po1.y; + end; + end; + end; + addpoint1(fcaretpos,po1); + addpoint1(caretrect.pos,po1); + addpoint1(showrect.pos,po1); + end; + end; + end; + if (ies_poschanging in fstate) or checkaction(actioninfo) then begin + if updatecaretcountref <> fupdatecaretcount then begin + exit; + end; + if (fwidget.activefocused or (ies_forcecaret in fstate)) and + not nocaret then begin + fwidget.getcaret; + with application.caret do begin + bounds:= actioninfo.caretrect; + show; + end; + end; + if nocaret then begin + if fwidget.hascaret then begin + application.caret.hide; + end; + end; + end; + end; + if (finfo.dest.x <> posbefore.x) or (finfo.dest.y <> posbefore.y) or + (finfo.dest.cx <> posbefore.cx) or + (finfo.dest.cy <> posbefore.cy) then begin + invalidatetextrect(minint,bigint); + end; +end; + +function tinplaceedit.getforcecaret: boolean; +begin + result:= ies_forcecaret in fstate; +end; + +procedure tinplaceedit.setforcecaret(const avalue: boolean); +begin + if avalue then begin + include(fstate,ies_forcecaret); + end + else begin + exclude(fstate,ies_forcecaret); + end; + internalupdatecaret(true); +end; + +procedure tinplaceedit.invalidatetextrect(const left,right: integer); +var + rect1: rectty; +begin + exclude(fstate,ies_textrectvalid); + rect1.x:= left; + rect1.cx:= right-left; + rect1.y:= finfo.clip.y; + rect1.cy:= finfo.clip.cy; + if msegraphutils.intersectrect(finfo.clip,rect1,rect1) then begin + fwidget.invalidaterect(rect1,org_client); + end; +end; + +procedure tinplaceedit.updateselect; +begin + if fselstart + fsellength > length(finfo.text.text) then begin + fsellength:= length(finfo.text.text) - fselstart; + end; + if fsellength < 0 then begin + fsellength:= 0; + end; + setselected1(finfo.text,fselstart,fsellength); + invalidatetextrect(minint,bigint); +end; + +procedure tinplaceedit.resetoffset; +begin + finfo.dest:= ftextrect; +end; + +procedure tinplaceedit.updatetextflags(active: boolean); +var + textflagsbefore: textflagsty; +begin + textflagsbefore:= finfo.flags; + if active then begin + finfo.flags:= ftextflagsactive; + end + else begin + finfo.flags:= ftextflags; + end; + if finfo.flags <> textflagsbefore then begin + resetoffset; + invalidatetext(false,false); + end; +end; + +procedure tinplaceedit.invalidatetext(textinput, trailing: boolean; + startpos: integer = -bigint; endpos: integer = bigint); +begin + if trailing then begin + invalidatetextrect(invalidatepos,endpos); + end + else begin + invalidatetextrect(startpos,endpos); + end; + notify(ea_textchanged); + if textinput then begin + notify(ea_textedited); + end; + if fcurindex > length(finfo.text.text) then begin + fcurindex:= length(finfo.text.text); + end; +end; + +function tinplaceedit.nofullinvalidateneeded: boolean; +begin + result:= finfo.flags * [tf_wordbreak,tf_xcentered,tf_right] = []; + +end; + +function tinplaceedit.getinsertstate: boolean; +begin + result:= not overwrite; +end; + +procedure tinplaceedit.setinsertstate(const Value: boolean); +var + m1: editinputmodety; +begin + overwrite:= not value; + internalupdatecaret; + if twidget1(fwidget).canassistive() then begin + m1:= eim_insert; + if overwrite then begin + m1:= eim_overwrite; + end; + assistiveserver.doeditinputmodeset(getiassistiveclient(),m1); + end; +end; + +function tinplaceedit.optionsedit: optionseditty; +begin + result:= fintf.getoptionsedit; +end; + +function tinplaceedit.canedit: boolean; +begin + result:= not (oe_readonly in iedit(fintf).getoptionsedit); +end; + +function tinplaceedit.canundo: boolean; +begin + result:= (ies_edited in fstate) or not (ies_emptytext in fstate) and + (fbackup <> finfo.text.text) or fintf.getedited; +end; + +function tinplaceedit.cancopy: boolean; +begin + result:= fsellength > 0; +end; + +function tinplaceedit.canpaste: boolean; +begin + result:= canedit and canpastefromclipboard; +end; + +function tinplaceedit.textclipped: boolean; +begin +// msedrawtext.textrect(getfontcanvas,finfo); +// result:= not rectinrect(finfo.res,fowner.innerclientrect); + result:= not rectinrect(gettextrect,fwidget.innerclientrect); +end; + +function tinplaceedit.lasttextclipped: boolean; +begin + result:= not rectinrect(finfo.res,finfo.clip); +end; + +function tinplaceedit.lasttextclipped(const acliprect: rectty): boolean; +begin + result:= not rectinrect(finfo.res,intersectrect(finfo.clip,acliprect)); +end; + +function tinplaceedit.mousepostotextindex(const apos: pointty): integer; +var + mstr1: msestring; +begin + if (fpasswordchar <> #0) and not (ies_emptytext in fstate) then begin + mstr1:= finfo.text.text; + finfo.text.text:= stringfromchar(fpasswordchar,length(mstr1)); + postotextindex(getfontcanvas,finfo,apos,result); + finfo.text.text:= mstr1; + end + else begin + if ies_emptytext in fstate then begin + result:= 0; + end + else begin + postotextindex(getfontcanvas,finfo,apos,result); + end; + end; +end; + +function tinplaceedit.textindextomousepos(const aindex: integer): pointty; +var + mstr1: msestring; +begin + ftextrectbefore:= finfo.res; + if (fpasswordchar <> #0) and not (ies_emptytext in fstate) then begin + mstr1:= finfo.text.text; + finfo.text.text:= stringfromchar(fpasswordchar,length(mstr1)); + result:= textindextopos(getfontcanvas,finfo,aindex); + finfo.text.text:= mstr1; + end + else begin + if ies_emptytext in fstate then begin + result:= textindextopos(getfontcanvas,finfo,0); + end + else begin + result:= textindextopos(getfontcanvas,finfo,aindex); + end; + end; + checktextrect; +end; + +procedure tinplaceedit.deleteselection; +var + s1: msestring; +begin + if twidget1(fwidget).canassistive() then begin + s1:= selectedtext(); + end; + if fsellength > 0 then begin + clearundo; + end; + internaldeleteselection(true); //every time called for ttextedit + if (s1 <> '') and twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(),etbm_delete,s1); + end; +end; + +procedure tinplaceedit.clearundo; +begin + if ies_emptytext in fstate then begin + fbackup:= ''; + end + else begin + fbackup:= finfo.text.text; + end; + exclude(fstate,ies_edited); + foldtext:= fbackup; + curindexbackup:= fcurindex; + selstartbackup:= fselstart; + sellengthbackup:= fsellength; +end; + +procedure tinplaceedit.undo; +begin + if checkaction(ea_undo) then begin + finfo.text.text:= fbackup; + fselstart:= selstartbackup; + fsellength:= sellengthbackup; + updateselect; + curindex:= curindexbackup; + invalidatetext(false,false); + fstate:= fstate - [ies_touched,ies_edited]; + notify(ea_undone); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditwithdrawn(getiassistiveclient); + end; + end; +end; + +procedure tinplaceedit.deleteback; +var + bo1: boolean; + ch1: msechar; + s1: msestring; +begin + if ies_emptytext in fstate then begin + exit; + end; + if fcurindex > 0 then begin + ch1:= finfo.text.text[fcurindex]; + end + else begin + ch1:= #0; + end; + bo1:= nofullinvalidateneeded and (ch1 <> c_return) and (ch1 <> c_linefeed); + if (fcurindex > 1) and + ((card16(ch1) and $fc00 = $dc00) or + (finfo.text.text[fcurindex-1] = c_return) and + (ch1 = c_linefeed)) then begin + s1:= copy(finfo.text.text,fcurindex-1,2); + richdelete(finfo.text,fcurindex-1,2); + fcurindex:= fcurindex - 2; + end + else begin + s1:= copy(finfo.text.text,fcurindex,1); + richdelete(finfo.text,fcurindex,1); + fcurindex:= fcurindex - 1; + end; + fstate:= fstate + [ies_touched,ies_edited]; + internalupdatecaret(true); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditchardelete(getiassistiveclient(),s1); + end; + invalidatetext(true,bo1); + notify(ea_indexmoved); +end; + +procedure tinplaceedit.deletechar; +var + bo1: boolean; + ch1: msechar; + s1: msestring; +begin + if ies_emptytext in fstate then begin + exit; + end; + if fcurindex < length(finfo.text.text) then begin + ch1:= finfo.text.text[fcurindex+1]; + end + else begin + ch1:= #0; + end; + bo1:= nofullinvalidateneeded and (ch1 <> c_return) and (ch1 <> c_linefeed); + if (card16(ch1) and $fc00 = $d800) or + (ch1 = c_linefeed) and (fcurindex > 0) and + (finfo.text.text = c_return) then begin + s1:= copy(finfo.text.text,fcurindex+1,2); + richdelete(finfo.text,fcurindex+1,2); + end + else begin + s1:= copy(finfo.text.text,fcurindex+1,1); + richdelete(finfo.text,fcurindex+1,1); + end; + fstate:= fstate + [ies_touched,ies_edited]; + invalidatetext(true,bo1); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditchardelete(getiassistiveclient(),s1); + end; +// if not bo1 then begin + internalupdatecaret; +// end; +end; + +procedure tinplaceedit.dokeydown(var kinfo: keyeventinfoty); +var + nochars: boolean; + finished: boolean; + actioninfo: editnotificationinfoty; + bo1: boolean; + opt1: optionseditty; + locating1: boolean; + shiftstate1,shiftstate2: shiftstatesty; + int1: integer; + ismultilinectrl: boolean; + s1: msestring; + +begin + with kinfo do begin + shiftstate1:= shiftstate * keyshiftstatesmask; + if (es_processed in eventstate) then begin + exit; + end; + opt1:= iedit(fintf).getoptionsedit; + locating1:= opt1 * [oe_locate,oe_readonly] = [oe_locate,oe_readonly]; + include(eventstate,es_processed); + actioninfo:= initactioninfo(ea_exit); + if ss_shift in shiftstate1 then begin + include(actioninfo.state,eas_shift); + end; + nochars:= true; + finished:= true; + if not(oe1_noselectall in foptionsedit1) and + issysshortcut(sho_selectall,kinfo) then begin + selectall; + end + else begin + if issysshortcut(sho_copy,kinfo) then begin + if (passwordchar = #0) and hasselection then begin + finished:= copytoclipboard(cbb_clipboard);; + end + else begin + finished:= false; + end; + end + else begin + if issysshortcut(sho_paste,kinfo) then begin + if canedit then begin + finished:= pastefromclipboard(cbb_clipboard); + end + else begin + finished:= false; + end; + end + else begin + if issysshortcut(sho_cut,kinfo) then begin + if canedit and (passwordchar = #0) and hasselection then begin + finished:= cuttoclipboard(cbb_clipboard); + end + else begin + finished:= false; + end; + end + else begin + finished:= false; + if ies_cangroupundo in fstate then begin + if issysshortcut(sho_groupundo,kinfo) then begin + if canundo then begin + undo; + finished:= true; + end; + end + else begin + if issysshortcut(sho_groupredo,kinfo) then begin + if canredo then begin + redo; + finished:= true; + end; + end; + end; + end; + end; + end; + end; + end; + if finished then begin + exit; + end; + ismultilinectrl:= (oe1_multiline in foptionsedit1) and + ((key = key_end) or (key = key_home)); + if (shiftstate1 <> [ss_ctrl]) or ismultilinectrl then begin + finished:= true; + bo1:= true; + if (key = key_return) {or (key = key_enter)} then begin + removechar1(chars,c_return); + removechar1(chars,c_linefeed); + if (shiftstate1 - [ss_shift] = []) and (oe_linebreak in opt1) and + ((oe_shiftreturn in opt1) xor (shiftstate1 = []))then begin + finished:= false; + nochars:= false; + bo1:= false; + chars:= chars + lineend; + fwidget.invalidate; + end; + end; + if bo1 then begin + if (shiftstate1 = []) then begin + case key of + key_return{,key_enter}: begin + if checkaction(ea_textentered) then begin + exclude(eventstate,es_processed); + end; + end; + key_escape: begin + if canundo and (oe_undoonesc in opt1) and + not (ies_cangroupundo in fstate) then begin + undo; + end + else begin + exclude(eventstate,es_processed); + end; + end; + key_insert: begin + insertstate:= not insertstate; + end; + key_backspace: begin + if locating1 then begin + filtertext:= copy(filtertext,1,length(filtertext)-1); + end + else begin + include(actioninfo.state,eas_delete); + actioninfo.dir:= gd_left; + if canedit then begin + if fsellength > 0 then begin + deleteselection; + end + else begin + if fcurindex > 0 then begin + actioninfo.action:= ea_delchar; + if checkaction(actioninfo) then begin + deleteback; + end; + end + else begin + if checkaction(actioninfo) then begin + finished:= false; + end; + end; + end; + end + else begin + exclude(eventstate,es_processed); + end; + end; + end; + key_delete: begin + if canedit then begin + if fsellength > 0 then begin + s1:= selectedtext(); + internaldeleteselection(true); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(), + etbm_delete,s1); + end; + end + else begin + actioninfo.action:= ea_delchar; + actioninfo.dir:= gd_none; + if checkaction(actioninfo) then begin + if fcurindex < length(finfo.text.text) then begin + deletechar; + end + else begin + finished:= false; + end; + end; + end; + end + else begin + exclude(eventstate,es_processed); + end; + end; + key_tab: begin + exclude(eventstate,es_processed); + if (finfo.tabulators <> nil) then begin + nochars:= false; + end; + end; + else begin + finished:= false; + nochars:= false; + end; + end; + end + else begin + if shiftstate1 = [ss_shift] then begin + finished:= false; + nochars:= false; + end + else begin + finished:= false; + end; + end; + end; + if not finished then begin + finished:= true; + shiftstate2:= shiftstate1; + if ismultilinectrl then begin + exclude(shiftstate2,ss_ctrl); + end; + if (shiftstate2 = []) or (shiftstate2 = [ss_shift]) then begin + case key of + key_tab,key_backtab,key_escape,key_backspace,key_delete: begin //nochars + finished:= false; + nochars:= true; + end; + key_home: begin + if locating1 and (shiftstate2 = []) then begin + filtertext:= ''; + end + else begin + if not (oe1_multiline in foptionsedit1) or + (ss_ctrl in shiftstate1) then begin + moveindex1(0,ss_shift in shiftstate1); + end + else begin + int1:= mousepostotextindex(mp(-bigint,fcaretpos.y)); + moveindex1(int1,ss_shift in shiftstate1); + end; + end; + end; + key_end: begin + if locating1 and (shiftstate2 = []) then begin + filtertext:= finfo.text.text; + end + else begin + if not (oe1_multiline in foptionsedit1) or + (ss_ctrl in shiftstate1) then begin + moveindex1(length(finfo.text.text),ss_shift in shiftstate1); + end + else begin + int1:= mousepostotextindex(mp(bigint,fcaretpos.y)); + moveindex1(int1,ss_shift in shiftstate1); + end; + end; + end; + key_left: begin + if not(oe_nofirstarrownavig in opt1) and (shiftstate1 <> [ss_shift]) and + ((fsellength = length(finfo.text.text)) or + not(ies_touched in fstate) and + (fcurindex = length(finfo.text.text)) + ) or + (fcurindex = 0) and + ((fsellength = 0) or (shiftstate1 <> [ss_shift]) or + (ies_istextedit in fstate) + ) or + (oe_readonly in opt1) and not caretonreadonly()then begin + actioninfo.dir:= gd_left; + if checkaction(actioninfo) then begin + if not(oe_exitoncursor in opt1) then begin + if shiftstate1 <> [ss_shift] then begin + sellength:= 0; + end; + end + else begin + finished:= false; + end; + end; + end + else begin + moveindex1(fcurindex-1,shiftstate1 = [ss_shift]); + end; + end; + key_right: begin + if not(oe_nofirstarrownavig in opt1) and (shiftstate1 <> [ss_shift]) and + ((fsellength = length(finfo.text.text)) or + not(ies_touched in fstate) and + (fcurindex = 0) + ) or + (fcurindex = length(finfo.text.text)) and + ((shiftstate1 <> [ss_shift]) or (fsellength = 0) or + (ies_istextedit in fstate) or + (fsellength = length(finfo.text.text)) and + (oe_autoselect in opt1) and (shiftstate1 <> [ss_shift]) + ) or + (oe_readonly in opt1) and not caretonreadonly() then begin + actioninfo.dir:= gd_right; + if checkaction(actioninfo) then begin + if not(oe_exitoncursor in opt1) or + ((fsellength = length(finfo.text.text)) and (fsellength <> 0)) and + (shiftstate1 <> [ss_shift]) and + (oe_nofirstarrownavig in opt1) then begin + if shiftstate1 <> [ss_shift] then begin + sellength:= 0; + end; + end + else begin + finished:= false; + end; + end; + end + else begin + moveindex1(fcurindex+1,shiftstate1 = [ss_shift]); + end; + end + else begin + finished:= false; + nochars:= false; + end; + end; + end + else begin + finished:= false; + if (shiftstate1 = [ss_ctrl,ss_alt]) and + not (ss_second in shiftstate) then begin + nochars:= false; + end; + end; + end; + end; + if not finished then begin + exclude(eventstate,es_processed); + end; + if not (es_processed in eventstate) and not nochars and (chars <> '') then begin + if locating1 then begin + filtertext:= filtertext + chars; + include(eventstate,es_processed); + end + else begin + if canedit then begin + enterchars(chars); + fselstart:= updateindex(fcurindex); + include(eventstate,es_processed); + end; + end; + end; + end; +end; + +procedure tinplaceedit.setfirstclick(var ainfo: mouseeventinfoty); +begin + include(fstate,ies_firstclick); + resetoffset; + finfo.flags:= ftextflags; //restore flags before activate +end; + +procedure tinplaceedit.mouseevent(var minfo: mouseeventinfoty); +var + po1: pointty; + int1: integer; + opt1: optionseditty; + autoselect1: boolean; +begin + with minfo do begin + if es_drag in eventstate then begin + killrepeater; + end + else begin + opt1:= fintf.getoptionsedit; + autoselect1:= (oe_autoselectonfirstclick in opt1) and + (opt1 * [oe_locate,oe_readonly] <> [oe_locate,oe_readonly]); + case eventkind of + ek_buttonpress: begin + if pointinrect(pos,finfo.clip) and + (minfo.button = mb_left) or (minfo.button = mb_middle) and + not (oe_readonly in opt1) then begin + if not ((minfo.button = mb_middle) and + (minfo.shiftstate * shiftstatesmask <> [ss_middle])) then begin + if not fwidget.focused and fwidget.canfocus and + (ow_mousefocus in fwidget.optionswidget) then begin + if minfo.button = mb_left then begin + include(fstate,ies_firstclick); + end; + include(minfo.eventstate,es_processed); + int1:= mousepostotextindex(pos); + moveindex(int1,false); + internalupdatecaret(true); + po1:= fcaretpos; + include(eventstate,es_nofocus); + if not fwidget.setfocus then begin + exclude(fstate,ies_firstclick); + exit; + end; + if autoselect1 and (minfo.button = mb_left) then begin + selectall; + subpoint1(po1,textindextomousepos(int1)); + end + else begin + moveindex(int1,false); + subpoint1(po1,fcaretpos); + end; + end + else begin + int1:= mousepostotextindex(pos); + po1:= textindextomousepos(int1); + if (ies_firstclick in fstate) then begin + finfo.flags:= ftextflagsactive; + if autoselect1 and (minfo.button = mb_left) then begin + selectall; + end + else begin + initfocus; + moveindex(int1,false); + end; + end + else begin + moveindex(int1,ss_shift in shiftstate); + end; + subpoint1(po1,textindextomousepos(int1)); + end; + if (minfo.button = mb_middle) and + not (oe_readonly in fintf.getoptionsedit) then begin + //cold be changed by moveindex + addpoint1(po1,textindextomousepos(int1)); + clearselection; + pastefromclipboard(cbb_primary); + subpoint1(po1,textindextomousepos(int1)); + end; + subpoint1(pos,po1); + if pos.x < ftextrect.x then begin + pos.x:= ftextrect.x; + end; + if pos.x > ftextrect.x + ftextrect.cx then begin + pos.x:= ftextrect.x + ftextrect.cx; + end; + if pos.y < ftextrect.y then begin + pos.y:= ftextrect.y; + end; + if pos.y > ftextrect.y + ftextrect.cy then begin + pos.y:= ftextrect.y + ftextrect.cy; + end; + end; + end; + end; + ek_buttonrelease,ek_mousecaptureend: begin + killrepeater; + exclude(fstate,ies_firstclick); + end; + ek_mousemove: begin + if fwidget.clicked and + not ((ies_firstclick in fstate) and autoselect1) then begin + fmousemovepos:= minfo.pos; + if not pointinrect(pos,ftextrect) then begin + if frepeater = nil then begin + movemouseindex(nil); + frepeater:= tsimpletimer.create(100000, + {$ifdef FPC}@{$endif}movemouseindex,true,[]); + end; + end + else begin + killrepeater; + movemouseindex(nil); + end; + end; + end; + end; + end; + end; +end; + +procedure tinplaceedit.movemouseindex(const sender: tobject); +begin + moveindex(mousepostotextindex(fmousemovepos),true); + if passwordchar = #0 then begin + copytoclipboard(cbb_primary); + end; +// msewidgets.copytoclipboard(selectedtext,cbb_primary); +end; + +function tinplaceedit.invalidatepos: integer; +begin + result:= fcaretpos.x - getfontcanvas.getfontmetrics('o').width; +end; + +procedure tinplaceedit.inserttext(const text: msestring; + nooverwrite: boolean = true); +var + int1,int2,int3: integer; +begin + if ies_emptytext in fstate then begin + finfo.text.text:= ''; + end; + if insertstate or nooverwrite then begin + richinsert(text,finfo.text,fcurindex+1); + end + else begin + replacetext1(finfo.text.text,fcurindex+1,text); + end; + checkmaxlength; + if ies_emptytext in fstate then begin + notify(ea_resetemptytext); //remove empty_text settings + end; + int3:= getfontcanvas.getfontmetrics('o').width; + int1:= fcaretpos.x - int3; + moveindex(fcurindex + length(text),false); + if nofullinvalidateneeded then begin + if (fcurindex = length(finfo.text.text)) then begin + int2:= fcaretpos.x + int3; + invalidatetext(true,false,int1,int2); + end + else begin + invalidatetext(true,false,int1); + end; + end + else begin + invalidatetext(true,false); + end; + { + if twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(),etbm_insert,text); + end; + } +end; + +procedure tinplaceedit.moveindex(newindex: integer; shift: boolean; + donotify: boolean); + //cursor verschieben +var + anchor: integer; + selstartbefore,sellengthbefore: integer; + info: editnotificationinfoty; + int1: integer; + moveindexcountref: integer; + +begin + if (newindex <> 0) and (ies_emptytext in fstate) then begin + exit; + end; + include(fstate,ies_touched); + inc(fmoveindexcount); + moveindexcountref:= fmoveindexcount; + selstartbefore:= fselstart; + sellengthbefore:= fsellength; + if newindex > length(finfo.text.text) then begin + newindex:= length(finfo.text.text); + end + else begin + if newindex < 0 then begin + newindex:= 0; + end; + end; + if finfo.text.text <> '' then begin + if (newindex < fcurindex) and + (card16(finfo.text.text[newindex]) and $fc00 = $d800) then begin + dec(newindex); //surrogate pair + end + else begin + if (newindex > fcurindex) and + (card16(finfo.text.text[newindex]) and $fc00 = $d800) then begin + inc(newindex); //surrogate pair + end; + end; + end; + if shift then begin + if fcurindex = fselstart then begin + anchor:= fselstart + fsellength; + end + else begin + anchor:= fselstart; + end; + if newindex <= anchor then begin + fselstart:= newindex; + fsellength:= anchor-newindex; + end + else begin + fselstart:= anchor; + fsellength:= newindex - anchor; + end; + end + else begin + fselstart:= newindex; + fsellength:= 0; + notify(ea_clearselection); + if moveindexcountref <> fmoveindexcount then begin + exit; + end; + end; + if (ies_istextedit in fstate) or (sellengthbefore <> fsellength) or + (selstartbefore <> fselstart) and (fsellength <> 0) then begin + updateselect; + end; + int1:= fcurindex; + curindex:= newindex; + if moveindexcountref <> fmoveindexcount then begin + exit; + end; + if (fcurindex > newindex) and (int1 > newindex) then begin + curindex:= newindex-1; //linebreak + end; + if donotify then begin + internalupdatecaret(true); + if moveindexcountref <> fmoveindexcount then begin + exit; + end; + info:= initactioninfo(ea_indexmoved); + if shift then begin + include(info.state,eas_shift); + end; + notify(info); + { + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditindexmoved(getiassistiveclient(),fcurindex); + end; + } + end; +end; + +procedure tinplaceedit.moveindex1(newindex: integer; shift: boolean = false; + donotify: boolean = true); +begin + moveindex(newindex,shift,donotify); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditindexmoved(getiassistiveclient(),fcurindex); + end; +end; + +function tinplaceedit.updateindex(const avalue: int32): int32; +begin + result:= avalue; + if result > length(finfo.text.text) then begin + result:= length(finfo.text.text); + end + else begin + if result < 0 then begin + result:= 0; + end; + end; + if (finfo.text.text <> '') and + (card16(finfo.text.text[result]) and $fc00 = $d800) then begin + inc(result); //surrogate pair + end; +end; + +procedure tinplaceedit.setcurindex(const avalue: integer); +begin + include(fstate,ies_touched); + fcurindex:= updateindex(avalue); + exclude(fstate,ies_caretposvalid); + internalupdatecaret(ies_forcecaret in fstate); +end; + +procedure tinplaceedit.setsellength(const avalue: halfinteger); +begin + if fsellength <> avalue then begin + fsellength:= updateindex(fselstart+avalue) - fselstart; + updateselect; + end; +end; + +procedure tinplaceedit.setselstart(const avalue: integer); +begin + if fselstart <> avalue then begin + fselstart:= updateindex(avalue); + if fsellength > 0 then begin + updateselect; + end; + end; +end; + +function tinplaceedit.copytoclipboard(const buffer: clipboardbufferty): boolean; +var + mstr1: msestring; + info: editnotificationinfoty; +begin + info:= initactioninfo(ea_copyselection); + info.bufferkind:= buffer; + result:= true; + if checkaction(info) then begin + if fsellength > 0 then begin + mstr1:= selectedtext; + fintf.updatecopytoclipboard(mstr1); + msewidgets.copytoclipboard(mstr1,info.bufferkind); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(),etbm_copy, + selectedtext); + end; + end + else begin + result:= false; + end; + end; +end; + +function tinplaceedit.copytoclipboard: boolean; +begin + result:= copytoclipboard(cbb_clipboard); +end; + +function tinplaceedit.cuttoclipboard(const buffer: clipboardbufferty): boolean; +var + s1: msestring; +begin + s1:= selectedtext; + result:= copytoclipboard(buffer); + deleteselection; + if twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(),etbm_cut, + s1); + end; +end; + +function tinplaceedit.getiassistiveclient(): iassistiveclientedit; +begin + result:= iassistiveclientedit(self); +end; + +function tinplaceedit.getassistiveparent(): iassistiveclient; +begin + result:= twidget1(fwidget).getassistiveparent(); +end; + +function tinplaceedit.getinstance: tobject; +begin + result:= twidget1(fwidget).getinstance(); +end; + +function tinplaceedit.getassistivewidget(): tobject; +begin + result:= twidget1(fwidget).getassistivewidget(); +end; + +function tinplaceedit.getassistivename(): msestring; +begin + result:= twidget1(fwidget).getassistivename(); +end; + +function tinplaceedit.getassistivecaption(): msestring; +begin + result:= twidget1(fwidget).getassistivecaption(); +end; + +function tinplaceedit.getassistivetext(): msestring; +begin + result:= twidget1(fwidget).getassistivetext(); +end; + +function tinplaceedit.getassistivecaretindex(): int32; +begin + result:= twidget1(fwidget).getassistivecaretindex(); +end; + +function tinplaceedit.getassistivehint(): msestring; +begin + result:= twidget1(fwidget).getassistivehint(); +end; + +function tinplaceedit.getassistiveflags(): assistiveflagsty; +begin + result:= twidget1(fwidget).getassistiveflags(); + include(result,asf_inplaceedit); +end; + +function tinplaceedit.getifidatalinkintf(): iifidatalink; +begin + result:= twidget1(fwidget).getifidatalinkintf(); +end; + +function tinplaceedit.cuttoclipboard: boolean; +begin + result:= cuttoclipboard(cbb_clipboard); +end; + +function tinplaceedit.pastefromclipboard( + const buffer: clipboardbufferty): boolean; +var + int1: integer; + info: editnotificationinfoty; + wstr1: msestring; +begin + info:= initactioninfo(ea_pasteselection); + info.bufferkind:= buffer; + result:= true; + if checkaction(info) then begin + if msewidgets.pastefromclipboard(wstr1,info.bufferkind) then begin + fintf.updatepastefromclipboard(wstr1); + deleteselection; + int1:= fcurindex; + inserttext(wstr1); + fselstart:= int1; + fsellength:= length(wstr1); + updateselect; + if twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(),etbm_paste,wstr1); + end; + end + else begin + result:= false; + end; + end; +end; + +function tinplaceedit.pastefromclipboard: boolean; +begin + result:= pastefromclipboard(cbb_clipboard); +end; + +function tinplaceedit.internaldeleteselection(textinput: boolean): boolean; +var + aselstart,asellength: integer; +begin + beforechange; + result:= checkaction(ea_deleteselection); + if result then begin + if fsellength > 0 then begin + aselstart:= fselstart; + asellength:= fsellength; + if asellength > 0 then begin + internaldelete(aselstart,asellength,fcurindex,true); + end; + include(fstate,ies_edited); + moveindex(fselstart,false); + sellength:= 0; + invalidatetext(textinput,nofullinvalidateneeded); + end; + end; +end; + +procedure tinplaceedit.internaldelete(start, len, startindex: integer; + selected: boolean); + //selected is for tundoinplaceedit +begin + richdelete(finfo.text,start+1,len); +end; + +procedure tinplaceedit.selectall; +begin + if ies_emptytext in fstate then begin + exit; + end; + if checkaction(ea_selectall) then begin + resetoffset; + fcurindex:= 0; + fselstart:= 0; + fsellength:= length(finfo.text.text); + updateselect; + if oe_homeonenter in optionsedit then begin + curindex:= 0; + end + else begin + curindex:= fsellength; + end; + end; +end; + +procedure tinplaceedit.clearselection; +begin + fstate:= fstate + [ies_touched,ies_edited]; + if fsellength > 0 then begin + fsellength:= 0; + updateselect; + end; +end; + +procedure tinplaceedit.doactivate; +begin + updatetextflags(true); + internalupdatecaret; +end; + +procedure tinplaceedit.dodeactivate; +begin + updatetextflags(false); + application.caret.hide; +end; + +procedure tinplaceedit.initfocus; +var + opt1: optionseditty; +begin + ffiltertext:= ''; + resetoffset; + invalidatetextrect(-bigint,bigint); + opt1:= iedit(fintf).getoptionsedit; + if opt1 * [oe_locate,oe_readonly] = [oe_locate,oe_readonly] then begin + curindex:= 0; + fselstart:= 0; + fsellength:= 0; + updateselect; + end + else begin + if ies_emptytext in fstate then begin + moveindex(0,false,false); + end + else begin + if (oe_autoselect in opt1) then begin + selectall; + end + else begin + if oe_endonenter in opt1 then begin + moveindex(bigint,false,false); + end + else begin + if oe_homeonenter in opt1 then begin + moveindex(0,false,false); + end + end; + end; + end; + end; + clearundo(); + exclude(fstate,ies_touched); + updatecaret(); +end; + +procedure tinplaceedit.dofocus; +begin + include(fstate,ies_focused); + initfocus; +end; + +procedure tinplaceedit.dodefocus; +begin + exclude(fstate,ies_focused); + updatetextflags(false); + if oe_resetselectonexit in iedit(fintf).getoptionsedit then begin + sellength:= 0; + resetoffset; + end; + internalupdatecaret(true,true); +end; + +procedure tinplaceedit.settextflags(const Value: textflagsty); +begin + if ftextflags <> value then begin + ftextflags := Value+[tf_clipo]; + updatetextflags(fwidget.focused); + end; +end; + +procedure tinplaceedit.settextflagsactive(const Value: textflagsty); +begin + if ftextflagsactive <> value then begin + ftextflagsactive:= Value+[tf_clipo]; + updatetextflags(fwidget.active); + end; +end; + +procedure tinplaceedit.dopaint(const canvas: tcanvas); +var + str1: msestring; + co1,co2: rgbtriplety; + haspasswordchar: boolean; +begin + str1:= ''; + ftextrectbefore:= finfo.res; + if length(finfo.text.text) > 0 then begin + canvas.save(); + haspasswordchar:= (fpasswordchar <> #0) and not (ies_emptytext in fstate); + if haspasswordchar then begin + str1:= finfo.text.text; + finfo.text.text:= stringfromchar(fpasswordchar,length(str1)); + end; + if ffont <> nil then begin + canvas.font:= ffont; + end; + if ffontstyle <> [] then begin + canvas.font.style:= ffontstyle; + end; + if ffontcolor <> cl_none then begin + canvas.font.color:= ffontcolor; + end; + if ffontcolorbackground <> cl_none then begin + canvas.font.colorbackground:= ffontcolorbackground; + end; + with defaulteditfontcolors do begin + if canvas.font.color = cl_default then begin + canvas.font.color:= text; + end; + if canvas.font.colorbackground = cl_default then begin + canvas.font.colorbackground:= textbackground; + end; + co1:= colortorgb(cl_selectedtext); + co2:= colortorgb(cl_selectedtextbackground); + setcolormapvalue(cl_selectedtext,selectedtext); + setcolormapvalue(cl_selectedtextbackground,selectedtextbackground); + end; + msedrawtext.drawtext(canvas,finfo); + setcolormapvalue(cl_selectedtext,co1.red,co1.green,co1.blue); + setcolormapvalue(cl_selectedtextbackground,co2.red,co2.green,co2.blue); + if haspasswordchar then begin + finfo.text.text:= str1; + end; + canvas.restore(); + end; + checktextrect; +end; + +procedure tinplaceedit.checktextrect; +var + info: editnotificationinfoty; +begin + include(fstate,ies_textrectvalid); + if (ftextrectbefore.cx <> finfo.res.cx) or + (ftextrectbefore.cy <> finfo.res.cy) then begin + info:= initactioninfo(ea_textsizechanged); + info.sizebefore:= ftextrectbefore.size; + info.newsize:= finfo.res.size; + checkaction(info); + end; +end; + +function tinplaceedit.gettextrect: rectty; +begin + if not (ies_textrectvalid in fstate) then begin + ftextrectbefore:= finfo.res; + msedrawtext.textrect(getfontcanvas,finfo); + checktextrect; + end; + result:= finfo.res; +end; + +function tinplaceedit.getfontcanvas: tcanvas; +begin + result:= fwidget.getcanvas; + if ffont <> nil then begin + result.font:= ffont; + end; + if ffontstyle <> [] then begin + result.font.style:= ffontstyle; + end; +end; + +procedure tinplaceedit.setpasswordchar(const Value: msechar); +begin + if fpasswordchar <> value then begin + fpasswordchar:= Value; + invalidatetext(false,false); + end; +end; + +procedure tinplaceedit.setcaretwidth(const Value: integer); +begin + if fcaretwidth <> value then begin + fcaretwidth:= Value; + internalupdatecaret; + end; +end; + +procedure tinplaceedit.checkindexvalues(); +begin + fcurindex:= updateindex(fcurindex); + fselstart:= updateindex(fselstart); + fsellength:= updateindex(fselstart+fsellength)-fselstart; +end; + +procedure tinplaceedit.settext(const Value: msestring); +begin + finfo.text.text:= Value; + checkindexvalues(); + invalidatetext(false,false); + if ies_focused in fstate then begin + internalupdatecaret; + end; +end; + +procedure tinplaceedit.setrichtext(const avalue: richstringty); +begin + beforechange; + finfo.text := avalue; + setlength(finfo.text.format,length(finfo.text.format)); + invalidatetext(false,false); + checkindexvalues(); + if ies_focused in fstate then begin + internalupdatecaret; + end; +end; + +procedure tinplaceedit.setformat(const avalue: formatinfoarty); +begin + finfo.text.format:= copy(avalue); + updateselect(); + invalidatetext(false,false); + if ies_focused in fstate then begin + internalupdatecaret; + end; +end; + +procedure tinplaceedit.checkmaxlength; +begin + if (fmaxlength >= 0) and (length(finfo.text.text) > fmaxlength) then begin + setlength(finfo.text.text,fmaxlength); + if fcurindex > fmaxlength then begin + curindex:= fmaxlength; + end; + invalidatetext(false,false); + end; +end; + +procedure tinplaceedit.setmaxlength(const Value: integer); +begin + if fmaxlength <> value then begin + fmaxlength := Value; + checkmaxlength; + end; +end; + +procedure tinplaceedit.scroll(const dist: pointty; + const scrollcaret: boolean = true); +begin + with finfo do begin + addpoint1(dest.pos,dist); + addpoint1(clip.pos,dist); + end; + addpoint1(ftextrect.pos,dist); + if scrollcaret then begin + fwidget.scrollcaret(dist); + end; +end; + +procedure tinplaceedit.updatecaret; +//var +// int1: integer; +begin +// int1:= fupdating; +// fupdating:= 0; + internalupdatecaret; +// fupdating:= int1; +end; + +function tinplaceedit.getcaretpos: pointty; +begin + if not (ies_caretposvalid in fstate) then begin + fcaretpos:= textindextomousepos(fcurindex); + include(fstate,ies_caretposvalid); + fscrollsum:= nullpoint; + end; + result:= addpoint(fcaretpos,fscrollsum); +end; + +procedure tinplaceedit.poschanged; +begin + if fstate * [ies_focused,ies_poschanging] = [ies_focused] then begin + include(fstate,ies_poschanging); + try + internalupdatecaret; + finally + exclude(fstate,ies_poschanging); + end; + end; +end; + +function tinplaceedit.selectedtext: msestring; +begin + if fsellength > 0 then begin + result:= copy(finfo.text.text,fselstart+1,fsellength); + end + else begin + result:= ''; + end; +end; + +procedure tinplaceedit.enterchars(const chars: msestring); +begin + begingroup; + try + deleteselection; + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditcharenter(getiassistiveclient(),chars); + end; + inserttext(chars,false); + finally + endgroup; + end; + { + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditcharenter(getiassistiveclient(),chars); + end; + } +end; + +procedure tinplaceedit.begingroup; +begin + //dummy +end; + +procedure tinplaceedit.endgroup; +begin + //dummy +end; + +procedure tinplaceedit.beginupdate; +begin + application.caret.remove; + inc(fupdating); +end; + +procedure tinplaceedit.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + internalupdatecaret; + invalidatetextrect(minint,bigint); + end; + application.caret.restore; +end; + +procedure tinplaceedit.setscrollvalue(const avalue: real; const horz: boolean); +var + rect1: rectty; + int1: integer; +begin + rect1:= textrect; + subsize1(rect1.size,ftextrect.size); + if horz then begin + if rect1.cx > 0 then begin + int1:= -(finfo.dest.x + round(rect1.cx*avalue) - ftextrect.x); + if int1 <> 0 then begin + fwidget.scrollrect(makepoint(int1,0),finfo.clip,true); + inc(finfo.dest.x,int1); + inc(fscrollsum.x,int1); + end; + end; + end + else begin + if rect1.cy > 0 then begin + int1:= -(finfo.dest.y + round(rect1.cy*avalue) - ftextrect.y); + if int1 <> 0 then begin + fwidget.scrollrect(makepoint(0,int1),finfo.clip,true); + inc(finfo.dest.y,int1); + inc(fscrollsum.y,int1); + end; + end; + end; +end; + +procedure tinplaceedit.dragstarted; +begin + killrepeater; +end; + +procedure tinplaceedit.setfiltertext(const avalue: msestring); +var + int1,int2,int3: integer; + foundindex: integer; + mstr1: msestring; + casesensitive: boolean; +begin + if avalue <> '' then begin + int1:= fintf.locatecount; + if int1 > 0 then begin + casesensitive:= oe_casesensitive in fintf.getoptionsedit; + if casesensitive then begin + mstr1:= avalue; + end + else begin + mstr1:= mseuppercase(avalue); + end; + foundindex:= -1; + int2:= fintf.locatecurrentindex; + if int2 < 0 then begin + int2:= 0; + end; + if casesensitive then begin + for int3:= int2 to int1 - 1 do begin + if msecomparestrlen(mstr1,fintf.getkeystring(int3)) = 0 then begin + foundindex:= int3; + break; + end; + end; + end + else begin + for int3:= int2 to int1 - 1 do begin + if msecomparetextlenupper(mstr1,fintf.getkeystring(int3)) = 0 then begin + foundindex:= int3; + break; + end; + end; + end; + if foundindex < 0 then begin + if casesensitive then begin + for int3:= int2-1 downto 0 do begin + if msecomparestrlen(mstr1,fintf.getkeystring(int3)) = 0 then begin + foundindex:= int3; + break; + end; + end; + end + else begin + for int3:= int2-1 downto 0 do begin + if msecomparetextlenupper(mstr1,fintf.getkeystring(int3)) = 0 then begin + foundindex:= int3; + break; + end; + end; + end; + end; + if foundindex >= 0 then begin + fintf.locatesetcurrentindex(foundindex); + ffiltertext:= avalue; + fselstart:= 0; + fsellength:= length(ffiltertext); + curindex:= fselstart+fsellength; + updateselect; + end; + end; + end + else begin + ffiltertext:= ''; + fselstart:= 0; + fsellength:= 0; + curindex:= 0; + updateselect; + end; +end; + +function tinplaceedit.updating: boolean; +begin + result:= fupdating > 0; +end; + +procedure tinplaceedit.redo; +begin + //dummy +end; + +function tinplaceedit.canredo: boolean; +begin + result:= false; +end; + +function tinplaceedit.hasselection: boolean; +begin + result:= (fsellength > 0) or fintf.hasselection(); +end; + +{ ttextundolist } + +constructor ttextundolist.create(intf: iundo); +begin + fintf:= intf; + fmaxsize:= defaultundobuffermaxsize; + inherited create; + fsize:= sizeof(undoinfoty); + maxcount:= defaultundomaxcount; +end; + +procedure ttextundolist.beforecopy(var data); +begin + inherited; + with undoinfoty(data) do begin + stringaddref(text); + stringaddref(textbefore); +// reallocstring(text); +// reallocstring(textbefore); + end; +end; + +procedure ttextundolist.freedata(var data); +begin + inherited; + with undoinfoty(data) do begin + dec(fbuffersize,length(text)); + text:= ''; + textbefore:= ''; + end; +end; + +function ttextundolist.getitems(const index: integer): pundoinfoty; +begin + result:= pundoinfoty(getitempo(index)); +end; + +function ttextundolist.checkrecord(atype: undotypety; const astartpos,aendpos: gridcoordty; + selected: boolean; backwards: boolean; alink: boolean; + textlength: integer): pundoinfoty; + + procedure newrecord; + begin + count:= fundopo; + count:= fcount + 1; + inc(fbuffersize,textlength); + while (count > 4) and (fbuffersize > fmaxsize) do begin + deleteitems(0,1); + end; + result:= items[fcount-1]; + with result^ do begin + utype:= atype; + fintf.getselectstart(selectstartpos); + startpos:= astartpos; + endpos:= aendpos; + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(uf_selected),selected); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(uf_backwards),backwards); + end; + fundopo:= count; + end; + +var + undocount: integer; + forcednew: boolean; +begin + result:= nil; + alink:= alink or (flinked > 0); + forcednew:= (dls_forcenew in fstate); + if (fcount = 0) then begin + newrecord; + undocount:= fundopo-1; + end + else begin + undocount:= fundopo-1; + if undocount < 0 then begin + undocount:= 0; + end + else begin + if undocount >= fcount then begin + undocount:= fcount - 1; + end; + end; + result:= items[undocount]; + end; + with result^ do begin + if atype = ut_setpos then begin + if utype = ut_setpos then begin + if forcednew or + ((selected xor (uf_selected in flags)) or (fundopo = 1)) then begin + newrecord; + end + else begin + endpos:= aendpos; + end; + end + else begin + if forcednew or + ((aendpos.row <> endpos.row) or (aendpos.col <> endpos.col)) then begin + newrecord; + end; + end; + end + else begin + if forcednew or + (utype <> atype) or + selected and not(uf_selected in flags) or + backwards and not(uf_backwards in flags) then begin + newrecord; + end + else begin + endpos:= aendpos; + count:= undocount+1; //cut history + end; + end; + end; + result^.link:= alink; + exclude(fstate,dls_forcenew); +end; + +procedure ttextundolist.setpos(const endpos: gridcoordty; selected: boolean; + alink: boolean = false); +begin + if flock <> 0 then exit; + checkrecord(ut_setpos,gridcoordty(nullpoint),endpos,selected,false,alink,0); +end; + +procedure ttextundolist.inserttext(const startpos,endpos: gridcoordty; + const atext: msestring; selected: boolean; backwards: boolean; + alink: boolean = false); +begin + if flock <> 0 then exit; + with checkrecord(ut_inserttext,startpos,endpos,selected,backwards,alink,length(atext))^ do begin + text:= text + atext; + end; +end; + +procedure ttextundolist.overwritetext(const startpos,endpos: gridcoordty; + const atext, atextbefore: msestring; selected: boolean; + alink: boolean = false); +begin + if flock <> 0 then exit; + with checkrecord(ut_overwritetext,startpos,endpos,selected,false, + alink,length(atext))^ do begin + text:= text + atext; + textbefore:= textbefore + atextbefore; + end; +end; + +procedure ttextundolist.deletetext(const startpos,endpos: gridcoordty; + const atext: msestring; selected: boolean; backwards: boolean; + alink: boolean = false); +begin + if flock <> 0 then exit; + with checkrecord(ut_deletetext,startpos,endpos,selected,backwards, + alink,length(atext))^ do begin + if backwards then begin + text:= atext + text; + end + else begin + text:= text + atext; + end; + end; +end; + +procedure ttextundolist.undo; +var + linked: boolean; +begin + if fundopo < 1 then begin + exit; + end; + inc(flock); + linked:= true; //compiler warning + try + repeat + if fundopo < 1 then begin + break; + end; + dec(fundopo); + with items[fundopo]^ do begin + case utype of + ut_setpos: begin + if fundopo > 0 then begin + with items[fundopo-1]^ do begin + if uf_selected in flags then begin + fintf.setselectstart(selectstartpos); + end; + fintf.setedpos(endpos,uf_selected in flags,false,cep_nearest); + end; + end; + end; + ut_inserttext: begin + fintf.deletetext(startpos,endpos); + end; + ut_overwritetext: begin + fintf.deletetext(startpos,endpos); + fintf.inserttext(startpos,textbefore,uf_selected in flags,false); + end; + ut_deletetext: begin + fintf.inserttext(endpos,text,uf_selected in flags, + not(uf_backwards in flags)); + end; + end; + if utype <> ut_setpos then begin + fintf.setedpos(startpos,uf_selected in flags,false,cep_nearest); + end; + linked:= (fundopo > 0) and items[fundopo-1]^.link; + end; + until not linked; + finally + dec(flock); + end; +end; + +procedure ttextundolist.redo; +var + linked: boolean; +begin + if fundopo >= fcount then begin + exit; + end + else begin + inc(flock); + try + repeat + with items[fundopo]^ do begin + case utype of + ut_setpos: begin + fintf.setedpos(endpos,uf_selected in flags,false,cep_nearest); + end; + ut_inserttext: begin + fintf.inserttext(startpos,text,uf_selected in flags,false); + end; + ut_overwritetext: begin + fintf.deletetext(startpos,endpos); + fintf.inserttext(startpos,text,uf_selected in flags,false); + end; + ut_deletetext: begin + fintf.deletetext(endpos,gridcoordty(textendpoint(pointty(endpos),text))); + end; + end; + if utype <> ut_setpos then begin + fintf.setedpos(endpos,uf_selected in flags,false,cep_nearest); + end; + inc(fundopo); + linked:= (fundopo < fcount) and items[fundopo-1]^.link; + end; + until not linked; + finally + dec(flock); + end; + end; +end; + +function ttextundolist.getcanundo: boolean; +begin + result:= (fundopo > 2); +end; + +function ttextundolist.getcanredo: boolean; +begin + result:= fundopo < fcount; +end; + +procedure ttextundolist.beginlink(linkto: undotypety; forcenew: boolean); +var + po1: pundoinfoty; +begin + if flock = 0 then begin + if (flinked = 0) then begin + if forcenew then begin + include(fstate,dls_forcenew); + end; + if (fundopo > 0) then begin + po1:= items[fundopo-1]; + if (po1^.utype = linkto) then begin + po1^.link:= true; + end; + end; + end; + inc(flinked); + end; +end; + +procedure ttextundolist.endlink(forcenew: boolean); +begin + if flock = 0 then begin + dec(flinked); + if flinked = 0 then begin + if forcenew then begin + include(fstate,dls_forcenew); + end; + if fundopo > 0 then begin + items[fundopo-1]^.link:= false; + end; + end; + end; +end; + +function ttextundolist.getlocked: boolean; +begin + result:= flock <> 0; +end; + +procedure ttextundolist.clear; +begin + fundopo:= 0; + inherited; +end; + +{ tundoinplaceedit } + +constructor tundoinplaceedit.create(aowner: twidget; editintf: iedit; + undointf: iundo; istextedit: boolean); +begin + inherited create(aowner,editintf,istextedit); + include(fstate,ies_cangroupundo); + fundolist:= ttextundolist.create(undointf); +end; + +destructor tundoinplaceedit.destroy; +begin + fundolist.Free; + inherited; +end; + +procedure tundoinplaceedit.enterchars(const chars: msestring); +begin + if insertstate then begin + fundolist.beginlink(ut_inserttext,false); + try + deleteselection; + fundolist.inserttext(makegridcoord(fcurindex,frow), + makegridcoord(fcurindex+length(chars),frow),chars,false,false); + inherited; + finally + fundolist.endlink(false); + end; + end + else begin + fundolist.beginlink(ut_overwritetext,false); + try + deleteselection; + fundolist.overwritetext(makegridcoord(fcurindex,frow),makegridcoord(fcurindex+length(chars),frow), + chars,copy(finfo.text.text,fcurindex+1,length(chars)),false); + inherited; + finally + fundolist.endlink(false); + end; + end; +end; + +procedure tundoinplaceedit.internaldelete(start, len, startindex: integer; selected: boolean); +begin + fundolist.deletetext(makegridcoord(startindex,frow),makegridcoord(start,frow), + copy(finfo.text.text,start+1,len),selected,false); + inherited; +end; + +procedure tundoinplaceedit.deleteback; +begin + fundolist.deletetext(makegridcoord(fcurindex,frow),makegridcoord(fcurindex-1,frow), + finfo.text.text[fcurindex],false,true); + inherited; +end; + +procedure tundoinplaceedit.deletechar; +begin + fundolist.deletetext(makegridcoord(fcurindex,frow),makegridcoord(fcurindex,frow), + finfo.text.text[fcurindex+1],false,false); + inherited; +end; + +procedure tundoinplaceedit.moveindex(newindex: integer; shift: boolean = false; + donotify: boolean = true); +begin + inherited; + fundolist.setpos(makegridcoord(fcurindex,frow),shift); +end; + +function tundoinplaceedit.cuttoclipboard( + const buffer: clipboardbufferty): boolean; +begin + fundolist.beginlink(ut_none,true); + try + result:= inherited cuttoclipboard(buffer); + finally + fundolist.endlink(true); + end; +end; + +function tundoinplaceedit.pastefromclipboard( + const buffer: clipboardbufferty): boolean; +begin + fundolist.beginlink(ut_none,true); + try + result:= inherited pastefromclipboard(buffer); + finally + fundolist.endlink(true); + end; +end; + +procedure tundoinplaceedit.begingroup; +begin + inherited; + fundolist.beginlink(ut_none,true); +end; + +procedure tundoinplaceedit.endgroup; +begin + fundolist.endlink(true); + inherited; +end; + +procedure tundoinplaceedit.redo; +begin + fundolist.redo; +end; + +procedure tundoinplaceedit.undo; +begin + fundolist.undo; +end; + +function tundoinplaceedit.canundo: boolean; +begin + result:= fundolist.canundo; +end; + +function tundoinplaceedit.canredo: boolean; +begin + result:= fundolist.canredo; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msemenuwidgets.pas b/mseide-msegui/lib/common/widgets/msemenuwidgets.pas new file mode 100644 index 0000000..d5dd5a7 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msemenuwidgets.pas @@ -0,0 +1,2483 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msemenuwidgets; + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseapplication,classes,mclasses,msewidgets,mseshapes,msemenus,msegraphutils, + msegraphics, + msetypes,msegui,mseglob,mseguiglob,mseevent,mseclasses,msestrings, + mseassistiveclient; + +const + defaultpopupmenuwidgetoptions = + defaultoptionstoplevelwidget - [ow_tabfocus,ow_arrowfocus,ow_mousefocus]; +type + menucellinfoty = record + buttoninfo: shapeinfoty; +// caption: msestring; + dimouter: rectty; + fontinactive: tfont; + fontactive: tfont; + colorglyphactive: colorty; + // coloractive: colorty; + end; + menucellinfoarty = array of menucellinfoty; + + menulayoutoptionty = (mlo_horz,mlo_keymode,mlo_main,mlo_childreninactive); + //used for popup close by second click); + menulayoutoptionsty = set of menulayoutoptionty; + menulayoutstatety = (mls_valid,mls_updating,mls_assistivelocked); + menulayoutstatesty = set of menulayoutstatety; + + menulayoutinfoty = record + menu: tmenuitem; + state: menulayoutstatesty; + activeitem: integer; + popupdirection: graphicdirectionty; + mousepos: pointty; + options: menulayoutoptionsty; + sizerect: rectty; + frameactivediff: framety; + imagedistactivediff: int32; + imagedist1activediff: int32; + imagedist2activediff: int32; + cells: menucellinfoarty; +// colorglyph: colorty; + itemframetemplate: tframetemplate; + itemface: tcustomface; + itemframetemplateactive: tframetemplate; + itemfaceactive: tcustomface; + separatorframetemplate: tframetemplate; + checkboxframetemplate: tframetemplate; + end; + + ppopupmenuwidget = ^tpopupmenuwidget; + tpopupmenuwidget = class(tpopupwidget) + private + fnextpopup,fprevpopup: tpopupmenuwidget; + fposrect: rectty; + fposition: graphicdirectionty; + factposition: graphicdirectionty; + finstancepo: pobject; + frefpos: pointty; + fselecteditem: tmenuitem; + ftemplates: menutemplatety; + fmenucomp: tcustommenu; + fclickeditem: integer; + fmouseitem: integer; + procedure internalsetactiveitem(const avalue: integer; + const aclicked: boolean; const force: boolean; + const nochildreninactive: boolean); virtual; + function getactiveitem: integer; + procedure setactiveitem(const value: integer); + procedure applicationactivechanged(const avalue: boolean); + protected + flayout: menulayoutinfoty; + flocalframeandface: boolean; + procedure doafteractivate() override; + procedure clientrectchanged; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function transientforwindoworwindow: twindow; + function translatetoscreen(const value: pointty): pointty; virtual; + procedure invalidatelayout(); + procedure updatelayout; virtual; + procedure nextpopupshowing; virtual; + function isinpopuparea(const apos: pointty): boolean; virtual; + function checkprevpopuparea(const apos: pointty): boolean; virtual; + procedure activatemenu( + const keymode,aclicked,nokeymodereset: boolean); virtual; + procedure deactivatemenu; virtual; + procedure selectmenu(const keymode: boolean; + const keyreturn: boolean); virtual; + function rootpopup: tpopupmenuwidget; + procedure closepopupstack(aselecteditem: tmenuitem; + const cancelmodal: boolean = false); + procedure updatepos; virtual; + procedure beginkeymode; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure childdeactivated(const sender: tpopupmenuwidget); virtual; + procedure fontchanged; override; + procedure internalcreateframe; override; + function activateoptionset: boolean; + procedure showhint(const aid: int32; var info: hintinfoty); override; + function trycancelmodal(const newactive: twindow): boolean; override; + + procedure release1(const acancelmodal: boolean); virtual; + class function classskininfo(): skininfoty; override; + function getassistiveflags(): assistiveflagsty override; + function getassistivecaption(): msestring override; + function getassistivetext(): msestring override; + function getassistivehint(): msestring override; + function prevmenuitem(const info: menulayoutinfoty): integer; + function nextmenuitem(const info: menulayoutinfoty): integer; + procedure assistivemenuactivated(); + public + constructor create(instance: ppopupmenuwidget; + const amenu: tmenuitem; const atransientfor: twindow; + const aowner: tcomponent = nil; + const menucomp: tcustommenu = nil); overload; + destructor destroy; override; + procedure paint(const canvas: tcanvas); override; + procedure menuchanged(const sender: tmenuitem); + procedure release(const nomodaldefer: boolean=false); override; + procedure updatetemplates; + procedure assigntemplate(const source: menutemplatety); virtual; + function showmenu(const aposrect: rectty; aposition: graphicdirectionty; + aactivate: boolean): tmenuitem; + //returns selected item, nil if none + property activeitem: integer read getactiveitem write setactiveitem; + published + property optionswidget default defaultpopupmenuwidgetoptions; + end; + + mainmenuwidgetoptionty = (mwo_vertical); + mainmenuwidgetoptionsty = set of mainmenuwidgetoptionty; + mainmenuwidgetstatety = (mws_firstactivated,mws_forced,mws_raised); + mainmenuwidgetstatesty = set of mainmenuwidgetstatety; + + tcustommainmenuwidget = class(tpopupmenuwidget) + private + factivewindowbefore: twindow; +// fstackedoverbefore: twindow; + fstackedunderbefore: twindow; + fstate: mainmenuwidgetstatesty; +// flayoutcalcing: integer; + procedure internalsetactiveitem(const Value: integer; + const aclicked: boolean; const force: boolean; + const nochildreninactive: boolean); override; + procedure checkactivate(const force,noraise: boolean); + protected + foptions: mainmenuwidgetoptionsty; + procedure restorefocus; + function checkprevpopuparea(const apos: pointty): boolean; override; + procedure nextpopupshowing; override; + procedure getautopaintsize(var asize: sizety); override; + procedure updatelayout; override; + procedure updatepos; override; + function isinpopuparea(const apos: pointty): boolean; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + procedure childdeactivated(const sender: tpopupmenuwidget); override; + procedure activatemenu( + const keymode,aclicked,nokeymodereset: boolean); override; + procedure deactivatemenu; override; + procedure selectmenu(const keymode: boolean; + const keyreturn: boolean); override; + procedure internalcreateframe; override; + procedure loaded; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure release1(const acancelmodal: boolean); override; + public + end; + + tframemenuwidget = class(tcustommainmenuwidget) + protected + public + constructor create(const aparent: twidget; + const amenu: tmenuitem); overload; + constructor create(const aparent: twidget; + const amenu: tmainmenu); overload; + procedure loaded; override; + end; + + tmainmenuwidget = class(tcustommainmenuwidget) + private + procedure setmenu(const avalue: twidgetmainmenu); + function getmenu: twidgetmainmenu; + procedure setoptions(const avalue: mainmenuwidgetoptionsty); + protected +// function checkprevpopuparea(const apos: pointty): boolean; override; + procedure objectevent(const sender: tobject; const event: objecteventty); override; + procedure loaded; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure initnewcomponent(const ascale: real); override; + published + property menu: twidgetmainmenu read getmenu write setmenu; + property options: mainmenuwidgetoptionsty read foptions write setoptions default []; + property popupdirection: graphicdirectionty read flayout.popupdirection write + flayout.popupdirection default gd_down; + end; + + mainmenupainterstatety = (mmps_layoutvalid); + mainmenupainterstatesty = set of mainmenupainterstatety; + + setmainmenuinstanceprocty = procedure(const value: tmainmenu) of object; + +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: rectty; const dir: graphicdirectionty; + const menucomp: tcustommenu = nil): tmenuitem; overload; +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: graphicdirectionty; + const menucomp: tcustommenu = nil): tmenuitem; overload; +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: pointty; + const menucomp: tcustommenu = nil): tmenuitem; overload; + { +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + var mouseinfo: mouseeventinfoty): tmenuitem; overload; + } + +var + menuexehandlerdesign: menuitemprocty; + +implementation +uses + msedrawtext,mserichstring,msestockobjects,sysutils,msekeyboard,msebits, + mseact,mseguiintf,msebitmap,msesysutils,mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tmenuitem1 = class(tmenuitem); + tmenuitems1 = class(tmenuitems); + twidget1 = class(twidget); +// tcustomframe1 = class(tcustomframe); + twindow1 = class(twindow); + tmsecomponent1 = class(tmsecomponent); + tframetemplate1 = class(tframetemplate); + tcustomframe1 = class(tcustomframe); + tguiapplication1 = class(tguiapplication); + +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: rectty; const dir: graphicdirectionty; + const menucomp: tcustommenu = nil): tmenuitem; overload; +var + widget: tpopupmenuwidget; + window1: twindow; +begin + if menu.canshow then begin +// tmenuitem1(menu).ftransientfor:= transientfor; + window1:= nil; + if transientfor <> nil then begin + window1:= transientfor.window; + end; + tpopupmenuwidget.create(@widget,menu,window1,nil,menucomp); + try + if window1 <> nil then begin + widget.color:= window1.owner.actualopaquecolor; + end; + result:= widget.showmenu(pos,dir,true); + finally + widget.Free; +// tmenuitem1(menu).ftransientfor:= nil; + end; + end + else begin + result:= nil; + end; +end; + +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: graphicdirectionty; + const menucomp: tcustommenu = nil): tmenuitem; +begin + result:= showpopupmenu(menu,transientfor, + makerect(transientfor.screenpos,transientfor.size),pos,menucomp); +end; + +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: pointty; + const menucomp: tcustommenu = nil): tmenuitem; overload; +begin + result:= showpopupmenu(menu,transientfor, + makerect(translateclientpoint(pos,transientfor,nil),nullsize), + gd_right,menucomp); +end; + +procedure initlayoutinfo(const aowner: tmsecomponent; + var info: menulayoutinfoty; const amenu: tmenuitem; + const aoptions: menulayoutoptionsty{; const acolorglyph: colorty}); +begin + with info do begin + cells:= nil; + fillchar(info,sizeof(info),0); + tmsecomponent1(aowner).getobjectlinker.setlinkedvar(ievent(aowner),amenu,tlinkedpersistent(menu)); + activeitem:= -1; + options:= aoptions; +// colorglyph:= acolorglyph; + end; +end; + +procedure movemenulayout(var layout: menulayoutinfoty; const dist: pointty); +//todo: optimize multiple call by loaded() + +var + int1: integer; +begin + with layout do begin + addpoint1(sizerect.pos,dist); + for int1:= 0 to high(cells) do begin + with cells[int1].buttoninfo.ca.dim.pos do begin + x:= x + dist.x; + y:= y + dist.y; + end; + with cells[int1].dimouter.pos do begin + x:= x + dist.x; + y:= y + dist.y; + end; + end; + end; +end; + +procedure calcmenulayout(var layout: menulayoutinfoty; const canvas: tcanvas; + const maxsize: integer = bigint); + function gettextrect(const acell: menucellinfoty; + const atext: richstringty): sizety; + var + size1: sizety; + begin + with acell do begin + result:= textrect(canvas,atext,[],fontinactive).size; + if fontinactive <> fontactive then begin + size1:= textrect(canvas,atext,[],fontactive).size; + if size1.cx > result.cx then begin + result.cx:= size1.cx; + end; + if size1.cy > result.cy then begin + result.cy:= size1.cy; + end; + end; + end; + end; + +const + shortcutdist = 5; +var + int1,int2: integer; + ay,ax: integer; + sizemax1: integer; + atextsize: sizety; + maxheight: integer; + textwidth: integer; + tabpos1: integer; + ashortcutwidth,shortcutwidth: integer; + item1,item2: tmenuitem1; + hassubmenu: boolean; + hascheckbox: boolean; + shift,regioncount: integer; + amax: integer; + frame1: framety; + frame2: framety; + framewidth,frameheight: integer; +// framehalfwidth: integer; +// framewidth1: integer; + extrasp: integer; + imagedi: integer; + imageditop: integer; + imagedibottom: integer; + ar1: richstringarty; + commonwidth: boolean; + needsmenuarrow: boolean; + parentcolor: colorty; + parentcoloractive: colorty; + noanim1: boolean; + nomouseanim1: boolean; + noclickanim1: boolean; + nofocusanim1: boolean; + checkboxwidth: integer; + checkboxheight: integer; + size1: sizety; + hasnormalitem: boolean; + +label + suppressed; + +begin + ar1:= nil; //compiler warning + with layout,tmenuitem1(menu) do begin + sizerect.pos:= nullpoint; + commonwidth:= (owner <> nil) and (mo_commonwidth in owner.options) and + (mlo_horz in layout.options); +// framehalfwidth:= 0; + needsmenuarrow:= not (mlo_horz in layout.options) or (owner <> nil) and + (mo_mainarrow in owner.options); + checkboxwidth:= menucheckboxwidth; + checkboxheight:= menucheckboxheight; + if checkboxframetemplate <> nil then begin + with checkboxframetemplate do begin + if fso_flat in optionsskin then begin + dec(checkboxwidth,2); + dec(checkboxheight,2); + end; + size1:= innerframedim(); + size1.cx:= size1.cx + frameo_left + frameo_right; + size1.cy:= size1.cy + frameo_top + frameo_bottom; + end; + checkboxwidth:= checkboxwidth + size1.cx; + checkboxheight:= checkboxheight + size1.cy; + end; + imagedistactivediff:= 0; + imagedist1activediff:= 0; + imagedist2activediff:= 0; + if itemframetemplateactive <> nil then begin + with tframetemplate1(itemframetemplateactive) do begin + frame2:= paintframe; + imagedistactivediff:= imagedist; + imagedist1activediff:= imagedist1; + imagedist2activediff:= imagedist2; + end; + end + else begin + frame2:= nullframe; + end; + frameactivediff:= frame2; + if itemframetemplate <> nil then begin + with tframetemplate1(itemframetemplate) do begin + imagedistactivediff:= imagedistactivediff - imagedist; + imagedist1activediff:= imagedist1activediff - imagedist1; + imagedist2activediff:= imagedist2activediff - imagedist2; + frame1:= paintframe; + subframe1(frameactivediff,frame1); + if frame1.left > frame2.left then begin + frame2.left:= frame1.left; + end; + if frame1.top > frame2.top then begin + frame2.top:= frame1.top; + end; + if frame1.right > frame2.right then begin + frame2.right:= frame1.right; + end; + if frame1.bottom > frame2.bottom then begin + frame2.bottom:= frame1.bottom; + end; +// int1:= (abs(levelo) + abs(leveli) + framewidth); +// if int1 > framehalfwidth then begin +// framehalfwidth:= int1; +// end; + frame1:= fi.ba.innerframe; + extrasp:= fi.ba.extraspace; + imagedi:= fi.ba.imagedist; + imageditop:= fi.ba.imagedist1; + imagedibottom:= fi.ba.imagedist2; + noanim1:= fso_noanim in optionsskin; + nomouseanim1:= fso_nomouseanim in optionsskin; + noclickanim1:= fso_noclickanim in optionsskin; + nofocusanim1:= fso_nofocusanim in optionsskin; + end; + end + else begin + frame1:= nullframe; + extrasp:= 0; + imagedi:= 0; + imageditop:= 0; + imagedibottom:= 0; + noanim1:= false; + nomouseanim1:= false; + noclickanim1:= false; + nofocusanim1:= false; + end; + framewidth:= frame2.left + frame2.right + extrasp; + frameheight:= frame2.top + frame2.bottom + extrasp; +// framewidth1:= framehalfwidth * 2; +// framewidth1:= framewidth1 + extrasp; + setlength(cells,count); + maxheight:= 0; +// ay:= framehalfwidth; +// ax:= framehalfwidth; + ay:= frame2.top; + ax:= frame2.left; + textwidth:= 0; + shortcutwidth:= 0; + hassubmenu:= false; + hascheckbox:= false; + parentcolor:= actualcolor; + parentcoloractive:= actualcoloractive; + hasnormalitem:= false; //for separator check + for int1:= 0 to count - 1 do begin + item1:= tmenuitem1(fsubmenu[int1]); + with cells[int1] do begin +// caption:= item1.caption; + fontinactive:= item1.font; + fontactive:= item1.fontactive; + with buttoninfo,ca do begin + actionstatestoshapestates(item1.finfo,state); + captiondist:= defaultshapecaptiondist; + textflags:= [tf_ycentered]; + imagedist:= imagedi; + imagelist:= timagelist(item1.finfo.imagelist); + ar1:= splitrichstring(item1.finfo.caption1,msechar(c_tab)); + atextsize:= gettextrect(cells[int1],ar1[0]); + atextsize.cx:= atextsize.cx + frame1.left + frame1.right; + atextsize.cy:= atextsize.cy + frame1.top + frame1.bottom; + inc(atextsize.cy,2); //for 3D level + if imagelist <> nil then begin + tabpos:= -(imagelist.width+imagedi); + atextsize.cx:= atextsize.cx - tabpos; + int2:= imagelist.height + imageditop + imagedibottom; + if atextsize.cy < int2 then begin + atextsize.cy:= int2; + end; + end + else begin + tabpos:= 0; + end; + exclude(state,shs_suppressed); + if mlo_horz in layout.options then begin + include(state,shs_horz); + end + else begin + exclude(state,shs_horz); + end; + tabpos:= tabpos - frame1.right - frame1.left; + if high(ar1) > 0 then begin + ashortcutwidth:= gettextrect(cells[int1],ar1[1]).cx; + end + else begin + ashortcutwidth:= 0; + end; + if needsmenuarrow and (item1.count > 0) then begin + include(state,shs_menuarrow); + if mlo_horz in layout.options then begin + if (ashortcutwidth = 0) or commonwidth then begin + dec(tabpos,menuarrowwidthhorz); + inc(atextsize.cx,menuarrowwidthhorz); + end + else begin + inc(ashortcutwidth,menuarrowwidthhorz); + end; + end; + end + else begin + exclude(state,shs_menuarrow); + end; + if ashortcutwidth > shortcutwidth then begin + shortcutwidth:= ashortcutwidth; + end; + colorglyph:= item1.actualcolorglyph(); + //finfo.colorglyph; //layout.colorglyph; + colorglyphactive:= item1.actualcolorglyphactive(); + caption:= item1.finfo.caption1; + imagenr:= item1.finfo.imagenr; + imagenrdisabled:= item1.finfo.imagenrdisabled; +// actionstatestoshapestates(item1.finfo,state); + if (item1.color = cl_default) or (item1.color = cl_parent) then begin + color:= parentcolor; + end + else begin + color:= item1.color; + end; + if (item1.coloractive = cl_default) or (item1.coloractive = cl_parent) then begin + coloractive:= parentcoloractive; + end + else begin + if item1.coloractive = cl_normal then begin + coloractive:= color; + end + else begin + coloractive:= item1.coloractive; + end; + end; + if mao_separator in item1.options then begin + exclude(state,shs_flat); + end + else begin + include(state,shs_flat); + end; + updatebit(longword(state),ord(shs_noanimation),noanim1); + updatebit(longword(state),ord(shs_nomouseanimation),nomouseanim1); + updatebit(longword(state),ord(shs_noclickanimation),noclickanim1); + updatebit(longword(state),ord(shs_nofocusanimation),nofocusanim1); + + if not (shs_invisible in state) then begin + if shs_separator in state then begin + if shs_optional in state then begin + include(state,shs_suppressed); + if hasnormalitem then begin + for int2:= int1+1 to count - 1 do begin + item2:= tmenuitem1(fsubmenu[int2]); + if item2.options * [mao_separator,mao_optional] = + [mao_separator] then begin + break; + end; + if not (mao_separator in item2.options) and + not (as_invisible in item2.state) then begin + exclude(state,shs_suppressed); + break; + end; + end; + end; + end; + hasnormalitem:= false; + end + else begin + hasnormalitem:= true; + end; + if shs_suppressed in state then begin + goto suppressed; + end; + hassubmenu:= hassubmenu or (shs_menuarrow in state); + if [shs_checkbox,shs_radiobutton] * state <> [] then begin + hascheckbox:= true; + if checkboxheight > atextsize.cy then begin + atextsize.cy:= checkboxheight; + end; + end; + with dim do begin + if mlo_horz in layout.options then begin //horizontal + if shs_separator in state then begin + if separatorframetemplate <> nil then begin + cx:= separatorframetemplate.innerframedim.cx; + end + else begin + cx:= 2; + end; + end + else begin + if [shs_checkbox,shs_radiobutton] * state <> [] then begin + inc(atextsize.cx,checkboxwidth); + dec(tabpos,checkboxwidth); + end; + cx:= atextsize.cx + 4; + if (ashortcutwidth > 0) then begin + tabpos:= tabpos + atextsize.cx + shortcutdist; + cx:= cx + shortcutdist + ashortcutwidth; + end; + end; + x:= ax; + y:= ay; + if commonwidth then begin + atextsize.cx:= cx; + end; + inc(ax,cx+framewidth); + end + else begin //vertical + y:= ay; + if shs_separator in state then begin + if separatorframetemplate <> nil then begin + cy:= separatorframetemplate.innerframedim.cy; + end + else begin + cy:= 2; + end; + end + else begin + cy:= atextsize.cy; + end; + inc(ay,cy+frameheight); + end; + end; + if atextsize.cy > maxheight then begin + maxheight:= atextsize.cy; + end; + if atextsize.cx > textwidth then begin + textwidth:= atextsize.cx; + end; + end + else begin + dim:= nullrect; + end; +suppressed: + end; //with cells[int1].buttoninfo + end; //with cells[int1] + end; + if (shortcutwidth > 0) and not commonwidth then begin + tabpos1:= textwidth + shortcutdist; + textwidth:= tabpos1 + shortcutwidth; + end + else begin + tabpos1:= 0; + end; + if not (as_invisible in state) then begin + shift:= 0; + regioncount:= 1; + if mlo_horz in layout.options then begin //horizontal + if mao_singleregion in layout.menu.options then begin + amax:= bigint; + end + else begin + amax:= maxsize; + end; + if commonwidth then begin + ax:= frame2.left; + end; + sizemax1:= 0; + for int1:= 0 to count - 1 do begin + with cells[int1].buttoninfo,ca do begin + if state * [shs_invisible,shs_suppressed] = [] then begin + if commonwidth then begin + dim.x:= ax; + if not (shs_separator in state) then begin + dim.cx:= textwidth; + end; + ax:= ax + dim.cx + framewidth; + end; + dim.x:= dim.x + shift; + if (int1 > 0) and + (dim.x + dim.cx + frame2.right > amax) then begin + shift:= shift - dim.x + frame2.left; + dim.x:= frame2.left; + inc(regioncount); + end; + int2:= dim.x + dim.cx + shift; + if int2 > sizemax1 then begin + sizemax1:= int2; + end; + dim.y:= frame2.top + (maxheight+frameheight) * (regioncount - 1); + dim.cy:= maxheight; + end; + end; + end; + sizerect.cx:= sizemax1+frame2.right {- extrasp - frame2.right}; +// sizerect.cx:= ax - extrasp - frame2.right; + sizerect.cy:= regioncount * (maxheight + frameheight) - extrasp; + end + else begin //vertical + if mao_singleregion in layout.menu.options then begin + amax:= bigint; + end + else begin + amax:= maxsize; + end; + ax:= frame2.left; + textwidth:= textwidth + 4; + if hassubmenu then begin + textwidth:= textwidth + menuarrowwidth; + end; + if hascheckbox then begin + textwidth:= textwidth + checkboxwidth; + end; + maxheight:= 0; + for int1:= 0 to count - 1 do begin + with cells[int1].buttoninfo,ca,dim do begin + tabpos:= tabpos + tabpos1; + y:= y + shift; + int2:= y + cy + frameheight; + if (int1 > 0) and (int2 - extrasp > amax) then begin + shift:= shift - y + frame2.top; + y:= frame2.top; + ax:= ax + textwidth + framewidth; + inc(regioncount); + end + else begin + if int2 > maxheight then begin + maxheight:= int2; + end; + end; + x:= ax; + cx:= textwidth; + end; + end; + sizerect.cx:= regioncount * (textwidth + framewidth) - extrasp; + sizerect.cy:= maxheight - frame2.bottom - extrasp; + end; + end + else begin + sizerect.size:= nullsize; + end; + for int1:= 0 to count - 1 do begin + with cells[int1],buttoninfo,ca do begin + dimouter:= inflaterect(dim,frame2); + imagedist1:= imageditop; + imagedist2:= imagedibottom; + end; + end; + end; +end; + +function getcellatpos(const info: menulayoutinfoty; const pos: pointty): integer; +var + int1: integer; +begin + with info do begin + if pointinrect(pos,sizerect) then begin + result:= -2; + for int1:= 0 to high(cells) do begin + with cells[int1].buttoninfo do begin + if (state * + [shs_disabled,shs_invisible,shs_suppressed,shs_separator] = []) and + pointinrect(pos,ca.dim) then begin + result:= int1; + break; + end; + end; + end; + end + else begin + result:= -1; + end; + end; +end; + +procedure drawmenu(const canvas: tcanvas; const layout: menulayoutinfoty); +var + int1: integer; + po1,po2: pframety; + colorglyphbefore: colorty; +begin + with layout do begin + if itemframetemplate <> nil then begin + po1:= @tframetemplate1(itemframetemplate).fi.ba.innerframe; + end + else begin + po1:= nil; + end; + if itemframetemplateactive <> nil then begin + po2:= @tframetemplate1(itemframetemplateactive).fi.ba.innerframe; + end + else begin + po2:= nil; + end; + for int1:= 0 to high(cells) do begin + with cells[int1],buttoninfo do begin + if state * [shs_invisible,shs_suppressed] = [] then begin + colorglyphbefore:= ca.colorglyph; + checkboxframe:= checkboxframetemplate; + if int1 = activeitem then begin + ca.colorglyph:= colorglyphactive; + if itemframetemplateactive <> nil then begin + itemframetemplateactive.paintbackground(canvas,ca.dim, + combineframestateflags(shs_disabled in state,false,false, + shs_clicked in state,false)); + if ca.colorglyph = cl_default then begin + ca.colorglyph:= itemframetemplateactive.colorglyph; + end; + end; + if ca.colorglyph = cl_default then begin + ca.colorglyph:= cl_glyphactive; + end; + face:= itemfaceactive; + ca.font:= fontactive; + state:= state + [shs_focused,shs_active,shs_focusanimation]; + deflaterect1(ca.dim,frameactivediff); + ca.imagedist:= ca.imagedist + imagedistactivediff; + ca.imagedist1:= ca.imagedist1 + imagedist1activediff; + ca.imagedist2:= ca.imagedist2 + imagedist2activediff; + drawmenubutton(canvas,buttoninfo,po2); + if itemframetemplateactive <> nil then begin + itemframetemplateactive.paintoverlay(canvas,ca.dim, + combineframestateflags(false,true,true,shs_clicked in state,false)); + end; + inflaterect1(ca.dim,frameactivediff); + ca.imagedist:= ca.imagedist - imagedistactivediff; + ca.imagedist1:= ca.imagedist1 - imagedist1activediff; + ca.imagedist2:= ca.imagedist2 - imagedist2activediff; + end + else begin + if (shs_separator in state) and (separatorframetemplate <> nil) then begin + separatorframetemplate.paintbackgroundframe(canvas,ca.dim); + if not (fso_flat in separatorframetemplate.optionsskin) then begin + draw3dframe(canvas, + inflaterect(deflaterect(ca.dim,separatorframetemplate.innerframe),1), + -1,defaultframecolors.edges,[]); + end; + separatorframetemplate.paintoverlayframe(canvas,ca.dim); + end + else begin + if itemframetemplate <> nil then begin + itemframetemplate.paintbackground(canvas,ca.dim, + combineframestateflags(shs_disabled in state,false,false, + shs_clicked in state,false)); + if ca.colorglyph = cl_default then begin + ca.colorglyph:= itemframetemplate.colorglyph; + end; + end; + face:= itemface; + ca.font:= fontinactive; + state:= state - [shs_focused,shs_active,shs_focusanimation]; + if ca.colorglyph = cl_default then begin + ca.colorglyph:= cl_glyph; + end; + drawmenubutton(canvas,buttoninfo,po1); + if itemframetemplate <> nil then begin + itemframetemplate.paintoverlay(canvas,ca.dim, + combineframestateflags(shs_disabled in state,false,false, + shs_clicked in state,false)); + end; + end; + end; + ca.colorglyph:= colorglyphbefore; + end; //visible + end; + end; + end; +end; + +function tpopupmenuwidget.prevmenuitem(const info: menulayoutinfoty): integer; +var + dir1: graphicdirectionty; +begin + with info do begin + result:= activeitem; + repeat + dec(result); + if result < 0 then begin + if aso_menunavig in assistiveoptions then begin + result:= activeitem; + if canassistive and active or (mlo_main in info.options) then begin + dir1:= gd_up; + if mlo_horz in info.options then begin + dir1:= gd_left; + end; + assistiveserver.donavigbordertouched(getiassistiveclient,dir1); + end; + break; + end; + result:= menu.count - 1; + end; + until menu[result].canactivate or (result = activeitem); + end; +end; + +function tpopupmenuwidget.nextmenuitem(const info: menulayoutinfoty): integer; +var + dir1: graphicdirectionty; +begin + with info do begin + if menu.count = 0 then begin + result:= -1; + end + else begin + result:= activeitem; + repeat + inc(result); + if result >= menu.count then begin + if aso_menunavig in assistiveoptions then begin + result:= activeitem; + if canassistive and active or (mlo_main in info.options) then begin + dir1:= gd_down; + if mlo_horz in info.options then begin + dir1:= gd_right; + end; + assistiveserver.donavigbordertouched(getiassistiveclient,dir1); + end; + break; + end; + if activeitem = -1 then begin + result:= -1; + break; + end + else begin + result:= 0; + end; + end; + until menu[result].canactivate or (result = activeitem); + end; + end; +end; + +function checkshortcut(const layout: menulayoutinfoty; + var info: keyeventinfoty; out multiple: boolean; + currentindex: integer = -1): integer; + + function getshortcut(currentindex: integer): integer; + var + int1: integer; + begin + result:= -1; + inc(currentindex); + if currentindex >= length(layout.cells) then begin + currentindex:= 0; + end; + int1:= currentindex; + repeat + with layout.cells[currentindex] do begin + if (buttoninfo.state * [shs_disabled,shs_invisible,shs_suppressed] = []) and + msegui.checkshortcut(info, + tmenuitem(tmenuitems1(tmenuitem1(layout.menu).fsubmenu). + fitems[currentindex]).caption,false) then begin + result:= currentindex; + include(info.eventstate,es_processed); + break; + end; + end; + inc(currentindex); + if currentindex >= length(layout.cells) then begin + currentindex:= 0; + end; + until currentindex = int1; + end; + +begin + result:= -1; + multiple:= false; + if length(layout.cells) > 0 then begin + result:= getshortcut(currentindex); + if result >= 0 then begin + exclude(info.eventstate,es_processed); + multiple:= getshortcut(result) <> result; + end; + end; +end; + +{ tpopupmenuwidget } + +constructor tpopupmenuwidget.create(instance: ppopupmenuwidget; const amenu: tmenuitem; + const atransientfor: twindow; + const aowner: tcomponent = nil; const menucomp: tcustommenu = nil); +begin + fclickeditem:= -1; + fmouseitem:= -1; + finstancepo:= pobject(instance); + fmenucomp:= menucomp; + if finstancepo <> nil then begin + instance^:= self; + end; + initlayoutinfo(self,flayout,amenu,[]{,cl_black}); + inherited create(aowner,atransientfor); + optionswidget:= defaultpopupmenuwidgetoptions; + internalcreateframe; + if menucomp <> nil then begin + assigntemplate(menucomp.template); + end + else begin + if (atransientfor <> nil) and (atransientfor.owner is tpopupmenuwidget) then begin + assigntemplate(tpopupmenuwidget(atransientfor.owner).ftemplates); + end; + end; + application.registeronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); +end; + +destructor tpopupmenuwidget.destroy; +begin + application.unregisteronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); + if finstancepo <> nil then begin + finstancepo^:= nil; + end; + if flayout.menu <> nil then begin + flayout.menu.onchange:= nil; + end; + freeandnil(fnextpopup); + inherited; + flayout.itemface.free; + flayout.itemfaceactive.free; +end; + +procedure tpopupmenuwidget.release(const nomodaldefer: boolean=false); +begin + if finstancepo <> nil then begin + finstancepo^:= nil; + end; + finstancepo:= nil; + fprevpopup:= nil; + inherited; +end; + +procedure tpopupmenuwidget.internalcreateframe; +begin + inherited; + tcustomframe1(fframe).fi.levelo:= 1; //do not set localprops +end; + +procedure tpopupmenuwidget.updatetemplates; +begin + with ftemplates do begin + if not flocalframeandface then begin + if frame <> nil then begin + if fframe = nil then begin + internalcreateframe; + end; + fframe.assign(frame); + end + else begin + freeandnil(fframe); //restore original values + internalcreateframe; + end; + if face <> nil then begin + if fface = nil then begin + internalcreateface; + end; + fface.assign(face); + end + else begin + freeandnil(fface); + end; + end; + if itemframe <> nil then begin + flayout.itemframetemplate:= itemframe.template; + end + else begin + flayout.itemframetemplate:= nil; + end; + if itemface <> nil then begin + if flayout.itemface = nil then begin + flayout.itemface:= tcustomface.create(iface(self)); + end; + flayout.itemface.assign(itemface.template); + end + else begin + freeandnil(flayout.itemface); + end; + if itemframeactive <> nil then begin + flayout.itemframetemplateactive:= itemframeactive.template; + end + else begin + flayout.itemframetemplateactive:= nil; + end; + if itemfaceactive <> nil then begin + if flayout.itemfaceactive = nil then begin + flayout.itemfaceactive:= tcustomface.create(iface(self)); + end; + flayout.itemfaceactive.assign(itemfaceactive.template); + end + else begin + freeandnil(flayout.itemfaceactive); + end; + if separatorframe <> nil then begin + flayout.separatorframetemplate:= separatorframe.template; + end + else begin + flayout.separatorframetemplate:= nil; + end; + if checkboxframe <> nil then begin + flayout.checkboxframetemplate:= checkboxframe.template; + end + else begin + flayout.checkboxframetemplate:= nil; + end; + invalidatelayout(); + end; +end; + +procedure tpopupmenuwidget.assigntemplate(const source: menutemplatety); +begin + setlinkedvar(source.frame,tmsecomponent(ftemplates.frame)); + setlinkedvar(source.face,tmsecomponent(ftemplates.face)); + setlinkedvar(source.itemframe,tmsecomponent(ftemplates.itemframe)); + setlinkedvar(source.itemface,tmsecomponent(ftemplates.itemface)); + setlinkedvar(source.itemframeactive,tmsecomponent(ftemplates.itemframeactive)); + setlinkedvar(source.itemfaceactive,tmsecomponent(ftemplates.itemfaceactive)); + setlinkedvar(source.separatorframe,tmsecomponent(ftemplates.separatorframe)); + setlinkedvar(source.checkboxframe,tmsecomponent(ftemplates.checkboxframe)); + updatetemplates; +end; + +function tpopupmenuwidget.translatetoscreen(const value: pointty): pointty; +begin + result:= translateclientpoint(value,self,nil); +end; + +function tpopupmenuwidget.transientforwindoworwindow: twindow; +begin + result:= window.transientfor; + if result = nil then begin + result:= self.window; + end; +end; + +procedure tpopupmenuwidget.updatepos; +var + rect1: rectty; + workarea: rectty; + int1: integer; +begin + rect1.size:= addsize(flayout.sizerect.size,innerclientframewidth); + workarea:= application.workarea(transientforwindoworwindow); + factposition:= fposition; + int1:= 0; + with fposrect do begin + repeat + case factposition of + gd_none: begin + inc(int1); + rect1.x:= x + (cx - rect1.cx) div 2; + rect1.y:= y + (cy - rect1.cy) div 2; + end; + gd_right: begin + rect1.pos:= makepoint(x + cx, y); + with rect1 do begin + if (int1 = 0) and (x + cx > workarea.x + workarea.cx) then begin + factposition:= gd_left; + end + else begin + inc(int1); + end; + end; + end; + gd_up: begin + rect1.pos:= makepoint(x, y-rect1.cy); + with rect1 do begin + if (int1 = 0) and (y < workarea.y) then begin + factposition:= gd_down; + end + else begin + inc(int1); + end; + end; + end; + gd_left: begin + rect1.pos:= makepoint(x-rect1.cx,y); + with rect1 do begin + if (int1 = 0) and (x < workarea.x) then begin + factposition:= gd_right; + end + else begin + inc(int1); + end; + end; + end; + gd_down: begin + rect1.pos:= makepoint(x,y+cy); + with rect1 do begin + if (int1 = 0) and (y + cy > workarea.y + workarea.cy) then begin + factposition:= gd_up; + end + else begin + inc(int1); + end; + end; + end; + end; + inc(int1); + until int1 >= 2; + end; + shiftinrect(rect1,workarea); + setwidgetrect(rect1); +end; + +procedure tpopupmenuwidget.updatelayout(); +begin + if flayout.state * [mls_valid,mls_updating] = [] then begin + include(flayout.state,mls_updating); + try + flayout.popupdirection:= gd_right; + calcmenulayout(flayout,getcanvas, + // application.screenrect(transientforwindoworwindow).cy - + application.workarea(transientforwindoworwindow).cy - + innerclientframewidth.cy); + movemenulayout(flayout,innerclientrect.pos); + updatepos(); + invalidate(); + include(flayout.state,mls_valid); + finally + exclude(flayout.state,mls_updating); + end; + end; +end; + +procedure tpopupmenuwidget.invalidatelayout(); +begin + if (componentstate * [csloading,csdestroying] = []) then begin + exclude(flayout.state,mls_valid); + invalidate(); + if (flayout.menu <> nil) and (flayout.menu.submenu.count > 0) and + ((fwidgetrect.cx <= 0) or (fwidgetrect.cy <= 0)) then begin + updatelayout(); //there will be no paint event + end; + end; +end; + +procedure tpopupmenuwidget.nextpopupshowing; +begin + //dummy; +end; + +function tpopupmenuwidget.showmenu(const aposrect: rectty; + aposition: graphicdirectionty; aactivate: boolean): tmenuitem; +var + transientforwindow: twindow; +begin + result:= nil; + flayout.menu.doupdate; + flayout.menu.onchange:= {$ifdef FPC}@{$endif}menuchanged; + fposrect:= aposrect; + fposition:= aposition; + updatelayout(); + if fprevpopup <> nil then begin + frefpos:= fprevpopup.screenpos; + fprevpopup.window.registermovenotification(ievent(self)); + end; + if fprevpopup <> nil then begin + transientforwindow:= fprevpopup.window; + color:= transientforwindow.owner.actualopaquecolor; + end + else begin + transientforwindow:= application.activewindow; + end; + if aactivate and (flayout.activeitem < 0) then begin + show(); //window must be visible for mouse grab + capturemouse(); + setactiveitem(nextmenuitem(flayout)); +// if flayout.activeitem < 0 then begin +// exit; +// end; + end; + show(aactivate,transientforwindow); + if aactivate then begin + result:= fselecteditem; + if fprevpopup = nil then begin + flayout.menu.owner.checkexec; + end; + end; +end; + +procedure tpopupmenuwidget.menuchanged(const sender: tmenuitem); +begin + invalidatelayout(); +end; + +procedure tpopupmenuwidget.dopaintforeground(const canvas: tcanvas); +begin + inherited; + canvas.move(clientpos); + drawmenu(canvas,flayout); +end; + +function tpopupmenuwidget.isinpopuparea(const apos: pointty): boolean; +begin + result:= pointinrect(apos,fwidgetrect); +end; + +function tpopupmenuwidget.checkprevpopuparea(const apos: pointty): boolean; +begin + result:= false; + if not pointinrect(apos,fwidgetrect) then begin + if fprevpopup <> nil then begin + result:= fprevpopup.isinpopuparea(apos); + end; + if result then begin + deactivatemenu; + end; + end; +end; + +procedure tpopupmenuwidget.mouseevent(var info: mouseeventinfoty); +var + bo1: boolean; + itembefore: integer; +// int1: integer; + pt1: pointty; + + procedure resetmouseflag(); + begin + with flayout do begin + if (fmouseitem >= 0) and (fmouseitem <= high(cells)) then begin + with cells[fmouseitem],buttoninfo do begin + if state * [shs_clicked,shs_mouse] <> [] then begin + state:= state - [shs_clicked,shs_mouse]; + invalidaterect(dimouter); + end; + end; + fmouseitem:= -1; + end; + end; + end; //resetmouseflag + + procedure setmouseitem(const sender: tpopupmenuwidget; const apos: pointty); + var + pt2: pointty; + begin + with sender,flayout do begin + pt2:= subpoint(apos,paintpos); + internalsetactiveitem(getcellatpos(flayout,pt2), + ss_left in info.shiftstate,false,pointinrect(pt2,sizerect)); + if activeitem >= 0 then begin + include(cells[activeitem].buttoninfo.state,shs_mouse); + fmouseitem:= activeitem; + if (itembefore <> activeitem) and + tmenuitem1(menu.items[activeitem]).canshowhint then begin + application.restarthint(self); + end; + end + else begin + resetmouseflag; + end; + end; + end; //setmouseitem + +var + canmousemove1: boolean; + b1: boolean; +begin + if (csdesigning in componentstate) and (ws_iswidget in fwidgetstate) then begin + inherited; + end + else begin + with info,flayout do begin + canmousemove1:= (csdesigning in componentstate) or + not (aso_nomenumousemove in assistiveoptions) or + (eventkind in mouseposevents - [ek_mousemove,ek_mousepark]); + itembefore:= activeitem; + pt1:= translatewidgetpoint(info.pos,self,nil); + if (mlo_keymode in options) and + (eventkind in [ek_mousemove,ek_buttonpress, + ek_buttonrelease,ek_mousepark]) then begin + if (distance(pt1,mousepos) <= 3) and + (eventkind in [ek_mousemove,ek_mousepark]) then begin + exit; + end + else begin + exclude(options,mlo_keymode); + end; + end; + if (fnextpopup <> nil) and + pointinrect(pt1,fnextpopup.fwidgetrect) and + not (mlo_childreninactive in options) then begin + if (eventkind = ek_mousemove) and canmousemove1 or + (eventkind = ek_buttonpress) and + (aso_nomenumousemove in assistiveoptions) and + not(csdesigning in componentstate) then begin + invalidaterect(cells[activeitem].dimouter); + b1:= false; + if eventkind = ek_buttonpress then begin + b1:= not fnextpopup.active(); + setmouseitem(fnextpopup,translatewidgetpoint(pos,self,fnextpopup)); + if fnextpopup.activeitem >= 0 then begin + with fnextpopup,flayout,cells[activeitem],buttoninfo do begin + include(state,shs_clicked); + end; + end; + end; + if b1 then begin + with fnextpopup,flayout do begin + assistiveserver.doitementer( + tmenuitem1(menu).getiassistiveclient(),cells,activeitem); + end; + end; + fnextpopup.activatemenu(false,ss_left in info.shiftstate,true); + exit; + end; + end; + if (eventkind in mouseposevents) and canmousemove1 then begin + if not checkprevpopuparea(pt1) then begin + if pointinrect(pos,paintrect) then begin + setmouseitem(self,pos); + end + else begin + resetmouseflag; + if eventkind = ek_buttonpress then begin + closepopupstack(nil); + exit; + end; + end; + end; + end; + case eventkind of + ek_buttonpress: begin + if (activeitem >= 0) and (button = mb_left) then begin + if (fnextpopup <> nil) and (activeitem = itembefore) then begin + fclickeditem:= activeitem; //prepare for close popupup + end; + if mlo_childreninactive in options then begin + exclude(options,mlo_childreninactive); + activeitem:= -1; + include(state,mls_assistivelocked); + try + mouseevent(info); + finally + exclude(state,mls_assistivelocked); + end; + if (activeitem >= 0) and + tmenuitem1(menu.items[activeitem]).canshowhint then begin + application.hidehint; + end; + exit; + end; + with cells[activeitem],buttoninfo do begin + include(state,shs_clicked); + invalidaterect(dimouter); + end; + end; + end; + ek_buttonrelease: begin + if (activeitem >= 0) and (button = mb_left) then begin + with cells[activeitem],buttoninfo do begin + bo1:= shs_clicked in state; + exclude(state,shs_clicked); + if not (csdesigning in componentstate) or + (aso_nomenumousemove in assistiveoptions) then begin + exclude(state,shs_mouse); + end; + invalidaterect(dimouter); + if bo1 then begin + include(info.eventstate,es_processed); + selectmenu(false,false); + if (mlo_main in options) and (fclickeditem = activeitem) then begin + fclickeditem:= -1; + closepopupstack(nil); + exit; + end; + fclickeditem:= activeitem; + end; + end; + end; + end; + ek_clientmouseleave: begin + resetmouseflag; + if (fnextpopup = nil) then begin + setactiveitem(-1); + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +procedure tpopupmenuwidget.internalsetactiveitem(const avalue: integer; + const aclicked: boolean; const force: boolean; + const nochildreninactive: boolean); +var + value1: integer; + activeitembefore: int32; +begin + with flayout do begin + activeitembefore:= activeitem; + value1:= avalue; + if (value1 < 0) or (menu = nil) then begin + value1:= -1; + end; + if (activeitem <> value1) or force then begin + fclickeditem:= -1; + if (menu <> nil) and (activeitem >= 0) and + (activeitem < menu.submenu.count) then begin + if (fnextpopup <> nil) then begin + fnextpopup.release1(false); + end; + with cells[activeitem],buttoninfo do begin + state:= state - [shs_clicked,{shs_mouse,}shs_active,shs_focused]; + if value1 <> -1 then begin + state:= state - [shs_mouse]; + end; + invalidaterect(dimouter); + end; + end; + activeitem:= value1; + if menu <> nil then begin + tmenuitem1(menu).factiveitem:= value1; //for iassistiveclient + end; + if activeitem >= 0 then begin + if not menu[value1].canactivate then begin + activeitem:= nextmenuitem(flayout); + end; + with cells[activeitem],buttoninfo do begin + state:= state + [shs_focused]; +// state:= state + [shs_mouse]; + if aclicked then begin + include(state,shs_clicked); + end; + invalidaterect(dimouter); + if not (mlo_childreninactive in options) and + (tmenuitem1(menu).fsubmenu[activeitem].count > 0) then begin + tpopupmenuwidget.create(@fnextpopup,tmenuitem1(menu).fsubmenu[activeitem], + fwindow); + fnextpopup.fprevpopup:= self; + nextpopupshowing; + fnextpopup.showmenu(makerect(translatetoscreen(ca.dim.pos),ca.dim.size), + popupdirection,false); + fnextpopup.beginkeymode; + end; + end; + capturemouse; + if canassistive and not (mls_assistivelocked in flayout.state) and + (active or (mlo_main in flayout.options )) then begin + //for mainmenu + if activeitembefore < 0 then begin + assistivemenuactivated(); + end + else begin + assistiveserver.doitementer(tmenuitem1(menu).getiassistiveclient(), + cells,activeitem); + end; + end; + end; + end + else begin + if aclicked and (value1 >= 0) then begin + with cells[activeitem],buttoninfo do begin + if not (shs_clicked in state) then begin + include(state,shs_clicked); + invalidaterect(dimouter); + end; + end; + end; + end; + if (activeitem < 0) and (mlo_main in options) and + not nochildreninactive then begin + include(options,mlo_childreninactive); + releasemouse; + end; + end; +end; + +function tpopupmenuwidget.getactiveitem: integer; +begin + with flayout do begin + if menu = nil then begin + activeitem:= -1; + end; + result:= activeitem; + end; +end; + +procedure tpopupmenuwidget.setactiveitem(const value: integer); +begin + internalsetactiveitem(value,false,false,false); +end; + +procedure tpopupmenuwidget.activatemenu( + const keymode,aclicked,nokeymodereset: boolean); +begin + capturekeyboard; + capturemouse; + if keymode then begin + beginkeymode; + end + else begin + if not nokeymodereset then begin + exclude(flayout.options,mlo_keymode); + end; + end; + if (flayout.menu.count > 0) and (flayout.activeitem < 0) then begin + if keymode then begin + internalsetactiveitem(0,aclicked,true,false); + end; + if (show(true,nil) <> mr_windowdestroyed) and (fprevpopup = nil) then begin +// window.removefocuslock; + flayout.menu.owner.checkexec; + end; + end; +end; + +procedure tpopupmenuwidget.childdeactivated(const sender: tpopupmenuwidget); +begin + capturemouse; + capturekeyboard; +end; + +procedure tpopupmenuwidget.deactivatemenu; +begin + setactiveitem(-1); + window.endmodal; + if fprevpopup <> nil then begin + fprevpopup.childdeactivated(self); + end; +end; + +procedure tpopupmenuwidget.selectmenu(const keymode: boolean; + const keyreturn: boolean); +var + i1: integer; + bo1: boolean; +begin + with flayout do begin + bo1:= not((menu.owner <> nil) and + (csdesigning in menu.owner.componentstate)); + i1:= activeitem; + if mlo_childreninactive in options then begin + exclude(options,mlo_childreninactive); + include(flayout.state,mls_assistivelocked); + try + internalsetactiveitem(i1,false,true,false); + finally + exclude(flayout.state,mls_assistivelocked); + end; + end; + if (fnextpopup <> nil) then begin + if keymode and (bo1 or not keyreturn) then begin + fnextpopup.activatemenu(keymode,false,false); + end + else begin + fnextpopup.window.bringtofront; //win32 workaround + end; + end + else begin + if i1 >= 0 then begin + with menu[i1] do begin + if (mao_asyncexecute in options) then begin + closepopupstack(menu[i1]); + if bo1 then begin + asyncexecute; + end; + end + else begin + releasemouse; + if bo1 then begin + execute; + end; + closepopupstack(menu[i1]); + end; + end; + end; + end; + if not bo1 and assigned(menuexehandlerdesign) and (i1 >= 0) and + (not (mlo_main in options) or (fclickeditem = i1) or + (menu[i1].submenu.count = 0)) then begin + closepopupstack(menu[i1]); + menuexehandlerdesign(menu[i1]); + end; + end; +end; + +function tpopupmenuwidget.rootpopup: tpopupmenuwidget; +begin + result:= self; + while result.fprevpopup <> nil do begin + result:= result.fprevpopup; + end; +end; + +procedure tpopupmenuwidget.beginkeymode; +begin + include(flayout.options,mlo_keymode); + flayout.mousepos:= application.mouse.pos; +end; + +procedure tpopupmenuwidget.paint(const canvas: tcanvas); +begin + if not (mls_valid in flayout.state) then begin + updatelayout(); + end; + inherited; +end; + +procedure tpopupmenuwidget.dokeydown(var info: keyeventinfoty); + + procedure checkshortcut(widget: tpopupmenuwidget); + var + int1: integer; + bo1: boolean; + begin + if widget <> nil then begin + with widget do begin + int1:= msemenuwidgets.checkshortcut(flayout,info,bo1,flayout.activeitem); + if int1 >= 0 then begin + if not bo1 then begin + include(flayout.state,mls_assistivelocked); + end; + try + setactiveitem(int1); + beginkeymode; + finally + exclude(flayout.state,mls_assistivelocked); + end; + if not bo1 then begin + selectmenu(true,false); + end; + end; + end; + end; + end; + + procedure swapkeys; + begin + if mlo_horz in flayout.options then begin + with info do begin + case key of + key_right: key:= key_down; + key_up: key:= key_left; + key_left: key:= key_up; + key_down: key:= key_right; + end; + end; + end; + end; + + function isup(position: graphicdirectionty): boolean; + begin + if mlo_horz in flayout.options then begin + result:= (position = gd_up) xor (info.key = key_right); + end + else begin + result:= (position = gd_left) xor (info.key = key_right); + end; + end; + +var + int1: integer; + intf1: iassistiveclientmenu; + dir1: graphicdirectionty; + b1: boolean; +begin + with info,flayout do begin + if (shiftstate*shiftstatesmask = []) then begin + swapkeys; + include(eventstate,es_processed); + beginkeymode; + case key of + key_return,{key_enter,}key_space: begin + if not (ss_repeat in shiftstate) and + not ((aso_noreturnkeymenuexecute in assistiveoptions) and + (key = key_return)) then begin + selectmenu(true,true); + end; + end; + key_up: begin + setactiveitem(prevmenuitem(flayout)); + end; + key_down: begin + setactiveitem(nextmenuitem(flayout)); + end; + key_left,key_right: begin + if (fnextpopup <> nil) and isup(fnextpopup.factposition) then begin + fnextpopup.activatemenu(true,false,false); + end + else begin + exclude(options,mlo_keymode); + if not isup(factposition) then begin + deactivatemenu; + if (fprevpopup <> nil) and + (fprevpopup.flayout.options * [mlo_main,mlo_horz] = + [mlo_main,mlo_horz]) then begin + exclude(eventstate,es_processed); + end; + end + else begin + b1:= true; + if rootpopup <> self then begin + with rootpopup,flayout do begin + if mlo_main in flayout.options then begin + exclude(eventstate,es_processed); + swapkeys; + int1:= activeitem; + if canassistive and + not (mls_assistivelocked in flayout.state) then begin + //for mainmenu + intf1:= tmenuitem1(menu).getiassistiveclient(); + assistiveserver.domenuactivated(intf1); + end; + dokeydown1(info); + if activeitem = int1 then begin + include(options,mlo_keymode); + self.capturekeyboard; //ignore the key + end; + swapkeys; + include(eventstate,es_processed); + b1:= false; + end; + end; + end; + if b1 and canassistive and + not (mls_assistivelocked in flayout.state) then begin + dir1:= gd_right; + if mlo_horz in options then begin + dir1:= gd_down; + end; + assistiveserver.donavigbordertouched(getiassistiveclient,dir1); + end; + end; + end; + end; + key_escape: begin + beginkeymode; + deactivatemenu; + end + else begin + exclude(eventstate,es_processed); + exclude(flayout.options,mlo_keymode); + checkshortcut(self); //actual popup first + if not (es_processed in eventstate) then begin + checkshortcut(fnextpopup); + end; + end; + end; + swapkeys; + end + else begin + if shiftstate = [ss_alt] then begin //check nextpopup first + checkshortcut(fnextpopup); + if not (es_processed in eventstate) then begin + checkshortcut(self); + end; + end + else begin + if (shiftstate = [ss_shift]) and (key = key_menu) and + (fnextpopup = nil) then begin + include(eventstate,es_processed); + include(flayout.state,mls_assistivelocked); + try + setactiveitem(0); + beginkeymode(); + selectmenu(true,false); + finally + exclude(flayout.state,mls_assistivelocked); + end; + end; + end; + end; + if not (es_processed in eventstate) and (fprevpopup <> nil) then begin + fprevpopup.dokeydown1(info); + end; + end; +end; + +procedure tpopupmenuwidget.closepopupstack(aselecteditem: tmenuitem; + const cancelmodal: boolean = false); +var + widget1: tpopupmenuwidget; +begin + widget1:= self; + while true do begin + with widget1 do begin + if not (mlo_main in flayout.options) then begin + window.endmodal; + end; + end; + if widget1.fprevpopup <> nil then begin + widget1:= widget1.fprevpopup; + end + else begin + break; + end; + end; + widget1.fselecteditem:= aselecteditem; //return value for procedure showmenu + widget1.release1(cancelmodal); +end; + +procedure tpopupmenuwidget.clientrectchanged; +begin + inherited; + if not (mls_updating in flayout.state) then begin + invalidatelayout(); + updatelayout(); + end; +end; + +procedure tpopupmenuwidget.objectevent(const sender: tobject; + const event: objecteventty); +var + po1: pointty; +begin + inherited; + if (event = oe_changed) then begin + if (fprevpopup <> nil) and (sender = fprevpopup.window) then begin + po1:= fprevpopup.screenpos; + addpoint1(fposrect.pos,subpoint(po1,frefpos)); + frefpos:= po1; + updatepos; + end; + if (sender <> nil) and ((sender = ftemplates.frame) or + (sender = ftemplates.face) or + (sender = ftemplates.itemframe) or + (sender = ftemplates.itemface)) then begin + updatetemplates; //refresh +// if not (csloading in componentstate) then begin +// invalidatelayout(); +// end; + end; + end; +end; + +procedure tpopupmenuwidget.fontchanged; +begin + invalidatelayout(); + if fparentwidget <> nil then begin + fparentwidget.dolayout(self); + end; +end; + +procedure tpopupmenuwidget.applicationactivechanged(const avalue: boolean); +begin + if not avalue and not (mlo_main in flayout.options) and visible then begin + closepopupstack(nil); + end; +end; + +procedure tpopupmenuwidget.assistivemenuactivated(); +var + intf1: iassistiveclientmenu; +begin + with flayout do begin + intf1:= tmenuitem1(menu).getiassistiveclient(); + assistiveserver.domenuactivated(intf1); + assistiveserver.doitementer(intf1,cells,activeitem); + end; +end; + +procedure tpopupmenuwidget.doafteractivate(); +begin + inherited; + if canassistive() then begin + assistivemenuactivated(); + end; +end; + +function tpopupmenuwidget.activateoptionset: boolean; +begin + result:= (fmenucomp <> nil) and (mo_activate in fmenucomp.options); +end; + +procedure tpopupmenuwidget.showhint(const aid: int32; var info: hintinfoty); +begin + inherited; + with flayout do begin + if (activeitem >= 0) and + tmenuitem1(menu.items[activeitem]).canshowhint then begin + info.caption:= menu.items[activeitem].hint; + end; + end; +end; + +function tpopupmenuwidget.trycancelmodal(const newactive: twindow): boolean; +var + widget2: tpopupmenuwidget; +// window1: twindow; + int1: integer; +begin + result:= false; + if newactive <> nil then begin + widget2:= self; + int1:= 1; + while (widget2 <> nil) do begin + if widget2.window = newactive then begin + exit; + end; + if widget2.window.modal then begin + inc(int1); + end; + widget2:= widget2.fprevpopup; + end; + if application.modallevel = int1 then begin + result:= true; //no lower modal window, accept new active window +{$ifdef mse_debugwindowfocus} + debugwriteln('closepopupstack '+inttostr(int1)); +{$endif} + closepopupstack(nil,true); + end; + end; +end; + +procedure tpopupmenuwidget.release1(const acancelmodal: boolean); +begin + visible:= false; + release; +end; + +class function tpopupmenuwidget.classskininfo(): skininfoty; +begin + result:= inherited classskininfo(); + result.objectkind:= sok_mainmenuwidget; +end; + +function tpopupmenuwidget.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_menu]; +end; + +function tpopupmenuwidget.getassistivecaption(): msestring; +begin + result:= tmenuitem1(flayout.menu).getassistivecaption(); + if result = '' then begin + result:= inherited getassistivecaption(); + end; +end; + +function tpopupmenuwidget.getassistivetext(): msestring; +begin + result:= tmenuitem1(flayout.menu).getassistivetext(); + if result = '' then begin + result:= inherited getassistivetext(); + end; +end; + +function tpopupmenuwidget.getassistivehint(): msestring; +begin + result:= tmenuitem1(flayout.menu).getassistivehint(); + if result = '' then begin + result:= inherited getassistivehint(); + end; +end; + +{ tcustommainmenuwidget } + +procedure tcustommainmenuwidget.internalcreateframe; +begin + inherited; + tcustomframe1(fframe).fi.levelo:= 0; //do not set localprops +end; + +procedure tcustommainmenuwidget.loaded; +begin + inherited; +// updatelayoutx(); +end; + +procedure tcustommainmenuwidget.updatepos; +begin + //dummy +end; + +procedure tcustommainmenuwidget.getautopaintsize(var asize: sizety); +begin + asize:= addsize(flayout.sizerect.size,innerframewidth); +end; + +procedure tcustommainmenuwidget.updatelayout(); +var + rect1: rectty; + size1: sizety; +begin + if flayout.state * [mls_valid,mls_updating] = [] then begin + include(flayout.state,mls_updating); + try + size1:= innerclientrect.size; + if ow1_autowidth in foptionswidget1 then begin + size1.cx:= bigint; + end; + if ow1_autoheight in foptionswidget1 then begin + size1.cy:= bigint; + end; + if mlo_horz in flayout.options then begin + calcmenulayout(flayout,getcanvas,size1.cx); + end + else begin + calcmenulayout(flayout,getcanvas,size1.cy); + end; + movemenulayout(flayout,innerclientrect.pos); + rect1:= fwidgetrect; + if mlo_horz in flayout.options then begin + rect1.cy:= flayout.sizerect.size.cy + innerclientframewidth.cy; + if an_bottom in fanchors then begin + rect1.y:= rect1.y + fwidgetrect.cy - rect1.cy; + end; + end + else begin + rect1.cx:= flayout.sizerect.size.cx + innerclientframewidth.cx; + if an_right in fanchors then begin + rect1.x:= rect1.x + fwidgetrect.cx - rect1.cx; + end; + end; + widgetrect:= rect1; + include(flayout.state,mls_valid); + invalidate(); + finally + exclude(flayout.state,mls_updating); + end; + end; +end; + +procedure tcustommainmenuwidget.nextpopupshowing; +begin + inherited; + if fmenucomp <> nil then begin + fnextpopup.assigntemplate(tmainmenu(fmenucomp).popuptemplate); + end; +end; + +procedure tcustommainmenuwidget.release1(const acancelmodal: boolean); +begin + if acancelmodal then begin + setlinkedvar(nil,tlinkedobject(factivewindowbefore)); + //do not restore active window + end; + setactiveitem(-1); + releasemouse; +// activeitem:= int1; +end; + +function tcustommainmenuwidget.isinpopuparea(const apos: pointty): boolean; +begin + result:= pointinrect(translatewidgetpoint(apos,nil,parentwidget),fwidgetrect); +end; + +procedure tcustommainmenuwidget.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + inherited; + if not (csdesigning in componentstate) then begin + if not (es_processed in info.eventstate) and + not (es_modal in info.eventstate) and + ((info.shiftstate = [ss_alt]) or + (info.shiftstate = [ss_shift]) and (info.key = key_menu)) then begin + dokeydown1(info); + end; + if not (es_processed in info.eventstate) and (fmenucomp <> nil) then begin + fmenucomp.menu.doshortcut(info); + end; + end; +end; + +procedure tcustommainmenuwidget.childdeactivated(const sender: tpopupmenuwidget); +begin + inherited; + if mlo_keymode in sender.flayout.options then begin + deactivatemenu; + end; +end; + +procedure tcustommainmenuwidget.restorefocus; +var + ar1: winidarty; + ar2: integerarty; +begin + twindow1(window).unlockactivate; + releasekeyboard; + if mws_firstactivated in fstate then begin + if factivewindowbefore <> fwindow then begin + if mws_raised in fstate then begin + if (fstackedunderbefore <> nil) then begin + if fstackedunderbefore.visible then begin + setlength(ar1,2); + ar1[0]:= fstackedunderbefore.winid; + ar1[1]:= fwindow.winid; + gui_getzorder(ar1,ar2); + if ar2[1] > ar2[0] then begin + {$ifdef mse_debugzorder} + debugwindow('**mainmenuwidget.restorefocus',fwindow.winid); + debugwindow(' before ',fstackedunderbefore.winid); + {$endif} + gui_stackunderwindow(fwindow.winid,fstackedunderbefore.winid); + tguiapplication1(application).zorderinvalid; + end; + end; + end + { + if (fstackedoverbefore <> nil) then begin + if fstackedoverbefore.visible then begin + setlength(ar1,2); + ar1[0]:= fstackedoverbefore.winid; + ar1[1]:= fwindow.winid; + gui_getzorder(ar1,ar2); + if ar2[1] > ar2[0] then begin + gui_stackoverwindow(fwindow.winid,fstackedoverbefore.winid); + end; + end; + end + } + else begin +// if activateoptionset then begin +// window.stackover(nil); + window.sendtobacklocal; +// end; + end; + end; + end; + if application.active and not ((fmenucomp = nil) or + (csdesigning in fmenucomp.componentstate)) and + (factivewindowbefore <> nil) and factivewindowbefore.visible then begin + factivewindowbefore.reactivate(); + end; + setlinkedvar(nil,tlinkedobject(factivewindowbefore)); + setlinkedvar(nil,tlinkedobject(fstackedunderbefore)); + end; +end; + +procedure tcustommainmenuwidget.checkactivate(const force,noraise: boolean); +begin + if force then begin + include(fstate,mws_forced); + end; + if not (mws_firstactivated in fstate) or force then begin + if not (mws_firstactivated in fstate) then begin + include(fstate,mws_firstactivated); + setlinkedvar(fwindow.stackedunder(true),tlinkedobject(fstackedunderbefore)); + end; + if force or activateoptionset then begin + capturekeyboard; + if (factivewindowbefore = nil) then begin + setlinkedvar(application.activewindow,tlinkedobject(factivewindowbefore)); + end; + if application.active and (fmenucomp <> nil) and not noraise then begin + window.bringtofrontlocal; + include(fstate,mws_raised); + end; + end; + end; + if mws_forced in fstate then begin + twindow1(window).lockactivate; + capturekeyboard; + end; + if (factivewindowbefore <> nil) then begin + factivewindowbefore.deactivateintermediate(); + end; +end; + +procedure tcustommainmenuwidget.internalsetactiveitem(const Value: integer; + const aclicked: boolean; const force: boolean; + const nochildreninactive: boolean); +begin + if (value >= 0) and not (csdesigning in componentstate) then begin + checkactivate(false,ow_background in window.owner.optionswidget); + end; + inherited; + if value = -1 then begin + restorefocus; + fstate:= []; + end; +end; + +procedure tcustommainmenuwidget.activatemenu( + const keymode,aclicked,nokeymodereset: boolean); +begin + inherited; + flayout.menu.owner.checkexec; +end; + +procedure tcustommainmenuwidget.selectmenu(const keymode: boolean; + const keyreturn: boolean); +begin + checkactivate(true,fnextpopup = nil); + if fnextpopup <> nil then begin + window.activate; + end; + include(fstate,mws_raised); + inherited; + flayout.menu.owner.checkexec; +end; + +procedure tcustommainmenuwidget.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if (activeitem >= 0) and (info.eventkind = ek_buttonpress) then begin + if factivewindowbefore <> nil then begin + twindow1(window).lockactivate; + capturekeyboard; +// factivewindowbefore.deactivateintermediate; + end; + end; +end; + +procedure tcustommainmenuwidget.deactivatemenu; +begin + inherited; + releasemouse; +end; + +function tcustommainmenuwidget.checkprevpopuparea(const apos: pointty): boolean; +var + po1: pointty; +begin + po1:= translatewidgetpoint(apos,nil,parentwidget); + result:= not pointinrect(po1,fwidgetrect) and + pointinrect(apos,rootwidget.widgetrect); + if result then begin + capturemouse; + release1(false); + end; +end; + +{ tframemenuwidget } + +constructor tframemenuwidget.create(const aparent: twidget; + const amenu: tmenuitem); +begin + inherited create(nil,amenu,nil,nil,fmenucomp); + foptionswidget:= foptionswidget-[ow_mousefocus,ow_tabfocus,ow_arrowfocus]; + fwidgetstate:= fwidgetstate - [ws_iswidget]; + setlockedparentwidget(aparent); + flayout.options:= [mlo_horz,mlo_main,mlo_childreninactive]; + flayout.popupdirection:= gd_down; + if not (csloading in aparent.ComponentState) and + not (csloading in componentstate) then begin +// updatelayout(); + visible:= true; + end; +end; + +constructor tframemenuwidget.create(const aparent: twidget; const amenu: tmainmenu); +begin + fmenucomp:= amenu; + create(aparent,amenu.menu); +end; + +procedure tframemenuwidget.loaded; +begin + include(fwidgetstate,ws_visible); + inherited; +end; + +{ tmainmenuwidget } + +constructor tmainmenuwidget.create(aowner: tcomponent); +begin + flocalframeandface:= true; + setlinkedvar(twidgetmainmenu.create(self{nil}),tmsecomponent(fmenucomp)); + fmenucomp.setsubcomponent(true); + inherited create(nil,fmenucomp.menu,nil,aowner,fmenucomp); + if csdesigning in componentstate then begin +{$warnings off} + tmsecomponent1(fmenucomp).setdesigning(true); +{$warnings on} + end; + freeandnil(fframe); + flayout.options:= [mlo_horz,mlo_main,mlo_childreninactive]; + flayout.popupdirection:= gd_down; + if not (csloading in componentstate) then begin +// updatelayout; + end; + visible:= true; +end; + +destructor tmainmenuwidget.destroy; +begin + fmenucomp.free; + inherited; +end; + +procedure tmainmenuwidget.initnewcomponent(const ascale: real); +begin + inherited; + with fmenucomp.menu.submenu do begin + if count = 0 then begin + insert(0,['Item0'],[],[],[]); + end; + end; + bounds_cx:= 100; +end; + +procedure tmainmenuwidget.setmenu(const avalue: twidgetmainmenu); +begin + fmenucomp.assign(avalue); +end; + +function tmainmenuwidget.getmenu: twidgetmainmenu; +begin + result:= twidgetmainmenu(fmenucomp); +end; + +procedure tmainmenuwidget.setoptions(const avalue: mainmenuwidgetoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + if mwo_vertical in foptions then begin + exclude(flayout.options,mlo_horz); + end + else begin + include(flayout.options,mlo_horz); + end; + if not (csloading in componentstate) then begin +// invalidatelayout(); + end; + end; +end; + +procedure tmainmenuwidget.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_changed) and (sender = fmenucomp) and + not (csloading in componentstate) then begin + assigntemplate(fmenucomp.template); +// invalidatelayout(); + end; +end; + +procedure tmainmenuwidget.loaded; +begin + inherited; + assigntemplate(fmenucomp.template); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/mseobjectpicker.pas b/mseide-msegui/lib/common/widgets/mseobjectpicker.pas new file mode 100644 index 0000000..e35fc0c --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseobjectpicker.pas @@ -0,0 +1,733 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit mseobjectpicker; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + mseevent,mseglob,mseguiglob,mseclasses,msegui,msegraphics,msegraphutils, + msepointer,msetypes; + +type + ihintcontroller = interface(inullinterface) + function getwidget: twidget; + end; + + thintcontroller = class + private + fintf: ihintcontroller; + public + constructor create(const intf: ihintcontroller); + procedure mouseevent(var info: mouseeventinfoty); + end; + + tobjectpicker = class; + + iobjectpicker = interface(inullinterface) + function getwidget: twidget; + function getcursorshape(const sender: tobjectpicker; + var ashape: cursorshapety): boolean; + //true if object found + procedure getpickobjects(const sender: tobjectpicker; var objects: integerarty); +// procedure getmouseoverobjects(const sender: tobjectpicker; var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const acanvas: tcanvas); + end; + + objectpickerstatety = (ops_picking,ops_rectselecting, + ops_multiselecting,ops_moving, + ops_xorpicpainted,ops_xorpicremoved, + ops_newwidgetgrab,ops_newwindowgrab); + objectpickerstatesty = set of objectpickerstatety; +const + activestates = [ops_picking,ops_rectselecting,ops_multiselecting,ops_moving]; +type + objectpickeroptionty = (opo_mousemoveobjectquery,opo_rectselect, + opo_multiselect,opo_thumbtrack); + objectpickeroptionsty = set of objectpickeroptionty; + + tobjectpicker = class //todo: area selecting, area deselecting + private + fintf: iobjectpicker; + fmouseoverobjects: integerarty; + fselectobjects: integerarty; + fpickrect: rectty; + fpickoffset: pointty; + fstate: objectpickerstatesty; + forigin: originty; + foptions: objectpickeroptionsty; + fmouseeventinfopo: pmouseeventinfoty; + fkeyeventinfopo: pkeyeventinfoty; + fcursorshape: cursorshapety; + procedure dopaint(const acanvas: tcanvas); + procedure dokeypress(const sender: twidget; var info: keyeventinfoty); + procedure endmoving(const resetflag: boolean); + procedure initxorcanvas(const acanvas: tcanvas); + function getpos: pointty; + function getshiftstate: shiftstatesty; + function getcurrentobjects: integerarty; + function getthumbtrack: boolean; + procedure setthumbtrack(const avalue: boolean); + public + constructor create(const intf: iobjectpicker; aorigin: originty = org_client); + destructor destroy; override; + procedure mouseevent(var info: mouseeventinfoty); + procedure dokeydown(var ainfo: keyeventinfoty); + function removexorpic: boolean; + function paintxorpic: boolean; + procedure dobeforepaint(const acanvas: tcanvas); + procedure doafterpaint(const acanvas: tcanvas); + +// procedure restorexorpic(const canvas: tcanvas); + procedure clear; + function hasselectobjects: boolean; + function hasmouseoverobjects: boolean; + function hascurrentobjects: boolean; + function picking: boolean; + function rectselecting: boolean; + function multiselecting: boolean; + function moving: boolean; + function active: boolean; + + property mouseoverobjects: integerarty read fmouseoverobjects; + property selectobjects: integerarty read fselectobjects; + property currentobjects: integerarty read getcurrentobjects; + //mouseoverobjects or selectobjects dependent on state + property options: objectpickeroptionsty read foptions write foptions; + property thumbtrack: boolean read getthumbtrack write setthumbtrack; + property state: objectpickerstatesty read fstate; + property pickoffset: pointty read fpickoffset; + property pickpos: pointty read fpickrect.pos; + property pickrect: rectty read fpickrect; + property cursor: cursorshapety read fcursorshape; + property mouseeventinfopo: pmouseeventinfoty read fmouseeventinfopo; + property keyeventinfopo: pkeyeventinfoty read fkeyeventinfopo; + property shiftstate: shiftstatesty read getshiftstate; + property pos: pointty read getpos; + end; + +implementation +uses + msekeyboard,msearrayutils; + +type + twidget1 = class(twidget); + +{ tobjectpicker } + +constructor tobjectpicker.create(const intf: iobjectpicker; + aorigin: originty = org_client); +begin + fintf:= intf; + forigin:= aorigin; + fcursorshape:= cr_default; +end; + +destructor tobjectpicker.destroy; +begin + application.unregisteronkeypress({$ifdef FPC}@{$endif}dokeypress); + inherited; +end; + +procedure tobjectpicker.endmoving(const resetflag: boolean); +var + widget1: twidget; +begin + application.unregisteronkeypress({$ifdef FPC}@{$endif}dokeypress); + removexorpic; + widget1:= twidget1(fintf.getwidget); + if ops_newwidgetgrab in fstate then begin + widget1.releasemouse(not (ops_newwindowgrab in fstate)); + end + else begin + if ops_newwindowgrab in fstate then begin + widget1.window.releasemouse; + end; + end; + application.widgetcursorshape:= cr_default; + if resetflag then begin + addpoint1(fpickrect.pos,fpickoffset); + fpickrect.size:= nullsize; + fpickoffset:= nullpoint; + if opo_thumbtrack in foptions then begin + fintf.pickthumbtrack(self); + end; + exclude(fstate,ops_moving); + end; + exclude(fstate,ops_rectselecting); + fpickrect.size:= nullsize; +end; + +procedure tobjectpicker.mouseevent(var info: mouseeventinfoty); +var +// shape: cursorshapety; + widget1: twidget1; + shiftstates1: shiftstatesty; + + procedure domousemovequery(const force: boolean); + var + ar1: integerarty; + po1: pointer; + pt1,pt2: pointty; + begin + if opo_mousemoveobjectquery in foptions then begin + ar1:= copy(fmouseoverobjects); + pt1:= fpickrect.pos; + pt2:= fpickoffset; + fpickrect.pos:= info.pos; + fpickoffset:= nullpoint; + fintf.getpickobjects(self,fmouseoverobjects); + if (force or not isequalarray(ar1,fmouseoverobjects)) and + ((fselectobjects = nil) or (ops_multiselecting in fstate)) then begin + po1:= pointer(fmouseoverobjects); + pointer(fmouseoverobjects):= pointer(ar1); + fpickrect.pos:= pt1; + fpickoffset:= pt2; + removexorpic; + fpickrect.pos:= info.pos; + fpickoffset:= nullpoint; + pointer(fmouseoverobjects):= po1; + if (fmouseoverobjects <> nil) or (fselectobjects <> nil) and + (ops_multiselecting in fstate) then begin + paintxorpic; + end; + end; + end; + end; //domousemovequery + + procedure doend; + var + bo1: boolean; + pt1: pointty; + widget1: twidget; + begin + widget1:= fintf.getwidget; + pt1:= widget1.refpos(forigin); + endmoving(false); + fintf.endpickmove(self); + exclude(fstate,ops_moving); + addpoint1(fpickrect.pos,fpickoffset); + addpoint1(fpickrect.pos,subpoint(pt1,widget1.refpos(forigin))); + fpickrect.size:= nullsize; + fpickoffset:= nullpoint; + + with fintf.getwidget do begin + fcursorshape:= actualcursor(widgetmousepos(info)); + end; + bo1:= fintf.getcursorshape(self,fcursorshape); + application.widgetcursorshape:= fcursorshape; //restore pick cursor + if not bo1 then begin + fcursorshape:= cr_default; + end; + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; +// include(info.eventstate,es_processed); + fmouseoverobjects:= nil; + domousemovequery(true); + end; //doend + + procedure checkcursorshape; + begin + with fintf.getwidget do begin + fcursorshape:= actualcursor(widgetmousepos(info)); + end; + if fintf.getcursorshape(self,fcursorshape) then begin + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; +// include(info.eventstate,es_processed); + end + else begin + fcursorshape:= cr_default; + end; + application.widgetcursorshape:= fcursorshape; + end; //checkcursorshape + + function hasintersection(const ar1: integerarty): boolean; + var + int1,int2: integer; + begin + result:= false; + for int1:= 0 to high(ar1) do begin + for int2:= 0 to high(fselectobjects) do begin //check intersection + if ar1[int1] = fselectobjects[int2] then begin + result:= true; + break; + end; + end; + if result then begin + break; + end; + end; + end; //hasintersection + + procedure removeintersection(const ar1: integerarty); + var + int1: integer; + begin + for int1:= 0 to high(ar1) do begin + removeitem(fselectobjects,ar1[int1]); + end; + end; //removeintersection + + procedure addintersection(const ar1: integerarty); + var + int1,int2,int3: integer; + begin + for int1:= 0 to high(ar1) do begin + int3:= length(fselectobjects); + for int2:= 0 to high(fselectobjects) do begin + if fselectobjects[int2] = ar1[int1] then begin + int3:= -1; + break; //no duplicates; + end; + if fselectobjects[int2] > ar1[int1] then begin + int3:= int2; + break; + end; + end; + if int3 >= 0 then begin + insertitem(fselectobjects,int3,ar1[int1]); + end; + end; + end; //addintersection + +var + ar1: integerarty; + bo1: boolean; + infopobefore: pmouseeventinfoty; +// int1,int2,int3: integer; + +begin + infopobefore:= fmouseeventinfopo; + fmouseeventinfopo:= @info; + try + shiftstates1:= info.shiftstate * shiftstatesmask; + if (opo_multiselect in foptions) and + (shiftstates1*keyshiftstatesmask = [ss_ctrl]) xor + (ops_multiselecting in fstate) then begin + bo1:= removexorpic; + if (shiftstates1*keyshiftstatesmask = [ss_ctrl]) then begin + include(fstate,ops_multiselecting); + end + else begin + exclude(fstate,ops_multiselecting); + end; + if bo1 then begin + paintxorpic; + end; + end; + case info.eventkind of + ek_buttonpress: begin + if info.button = mb_left then begin + removexorpic; + fstate:= fstate - [ops_moving,ops_rectselecting]; + fpickrect.pos:= info.pos; + fpickrect.size:= nullsize; + fpickoffset:= nullpoint; + ar1:= nil; + include(fstate,ops_picking); + try + fintf.getpickobjects(self,ar1); + finally + exclude(fstate,ops_picking); + end; + if shiftstates1 = [ss_left] then begin + fmouseoverobjects:= ar1; + if (ar1 = nil) then begin + if fselectobjects <> nil then begin + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; +// include(info.eventstate,es_processed); + fselectobjects:= nil; + end; + end + else begin + if not hasintersection(ar1) then begin + fselectobjects:= nil; + end; + application.registeronkeypress({$ifdef FPC}@{$endif}dokeypress); + include(fstate,ops_moving); + widget1:= twidget1(fintf.getwidget); + fstate:= fstate - [ops_newwidgetgrab,ops_newwindowgrab]; + if not widget1.window.mousecaptured then begin + include(fstate,ops_newwindowgrab); + end; + if (ws_newmousecapture in widget1.fwidgetstate) or + not widget1.mousecaptured then begin + include(fstate,ops_newwidgetgrab); + end; + widget1.capturemouse(true); + fintf.beginpickmove(self); + widget1.window.update; + paintxorpic; + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; +// include(info.eventstate,es_processed); + checkcursorshape; + end; + end + else begin + if (shiftstates1 = [ss_shift,ss_left]) and + (opo_rectselect in foptions) then begin + application.registeronkeypress({$ifdef FPC}@{$endif}dokeypress); + include(fstate,ops_rectselecting); + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; + //include(info.eventstate,es_processed); + end + else begin + if (shiftstates1 = [ss_ctrl,ss_left]) and + (opo_multiselect in foptions) and (ar1 <> nil) then begin + fmouseoverobjects:= ar1; + if hasintersection(ar1) then begin + removeintersection(ar1); + end + else begin + addintersection(ar1); + end; + paintxorpic; + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; + // include(info.eventstate,es_processed); + checkcursorshape; + end; + end; + end; + end; + end; + ek_buttonrelease: begin + if (info.button = mb_left) then begin + if ops_moving in fstate then begin + doend; + if opo_mousemoveobjectquery in foptions then begin + fintf.getpickobjects(self,fmouseoverobjects); + end; + if hascurrentobjects then begin + paintxorpic; + end; + checkcursorshape; + end + else begin + if ops_rectselecting in fstate then begin + removexorpic; + fpickrect.size:= sizety(subpoint(info.pos,fpickrect.pos)); + ar1:= nil; + bo1:= (fpickrect.cx < 0) or (fpickrect.cy < 0); + normalizerect1(fpickrect); + fintf.getpickobjects(self,ar1); + if (ar1 <> nil) then begin + if bo1 then begin + removeintersection(ar1); + end + else begin + addintersection(ar1); + end; + end; + exclude(fstate,ops_rectselecting); + fpickrect.size:= nullsize; + if fselectobjects <> nil then begin + paintxorpic; + end; + end; + end; + end; + end; + ek_mousemove,ek_mousepark: begin + if ops_moving in fstate then begin + removexorpic; + fpickoffset:= subpoint(info.pos,fpickrect.pos); + if opo_thumbtrack in foptions then begin + fintf.pickthumbtrack(self); + end; + paintxorpic; + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; + // include(info.eventstate,es_processed); + end + else begin + if ops_rectselecting in fstate then begin + removexorpic; + fpickrect.size:= sizety(subpoint(info.pos,fpickrect.pos)); + paintxorpic; + end + else begin + if shiftstate * buttonshiftstatesmask = [] then begin + fpickrect.pos:= info.pos; + fpickoffset:= nullpoint; + checkcursorshape; + domousemovequery(false); + end; + end; + end; + end; + ek_mouseleave,ek_clientmouseleave: begin + if fselectobjects = nil then begin + removexorpic; + end; + fmouseoverobjects:= nil; + end; + end; + finally + fmouseeventinfopo:= infopobefore; + end; +end; + +procedure tobjectpicker.initxorcanvas(const acanvas: tcanvas); +begin + with acanvas do begin + rasterop:= rop_xor; + color:= cl_white; + dashes:= #1#1; + end; +end; + +procedure tobjectpicker.dopaint(const acanvas: tcanvas); +begin + if not (opo_thumbtrack in foptions) then begin + fintf.paintxorpic(self,acanvas); + end; + if ops_rectselecting in fstate then begin + acanvas.dashes:= #3#3; + acanvas.drawrect(fpickrect); + end; +end; + +function tobjectpicker.paintxorpic: boolean; +var + canvas1: tcanvas; + widget1: twidget; +begin + result:= not (ops_xorpicpainted in fstate); + if result then begin + widget1:= fintf.getwidget; +// widget1.update; + canvas1:= widget1.getcanvas(forigin); + initxorcanvas(canvas1); + dopaint(canvas1); + include(fstate,ops_xorpicpainted); + end; +end; + +function tobjectpicker.removexorpic: boolean; +var + canvas1: tcanvas; +begin + result:= ops_xorpicpainted in fstate; + if result then begin + canvas1:= fintf.getwidget.getcanvas(forigin); + initxorcanvas(canvas1); + dopaint(canvas1); + exclude(fstate,ops_xorpicpainted); + end; +end; +{ +procedure tobjectpicker.restorexorpic(const canvas: tcanvas); +var + int1: integer; +begin + if ops_moving in fstate then begin + int1:= canvas.save; + initxorcanvas(canvas); + if not (forigin = org_widget) then begin //todo org_screen + canvas.intersectcliprect(fintf.getwidget.clientrect); + canvas.move(fintf.getwidget.clientwidgetpos); + end; + fintf.paintxorpic(self,canvas); + include(fstate,ops_xorpicpainted); + canvas.restore(int1); + end; +end; +} +procedure tobjectpicker.dokeypress(const sender: twidget; + var info: keyeventinfoty); +begin + case info.key of + key_escape: begin + if (fstate * [ops_moving,ops_rectselecting] <> []) then begin + fkeyeventinfopo:= @info; + try + endmoving(true); + if fselectobjects <> nil then begin + paintxorpic; + end; + include(info.eventstate,es_processed); + fintf.cancelpickmove(self); + finally + fkeyeventinfopo:= nil; + end; + end; + end; + end +end; + +procedure tobjectpicker.dokeydown(var ainfo: keyeventinfoty); +begin + case ainfo.key of + key_escape: begin + if (fstate * [ops_moving,ops_rectselecting] = []) and + (fselectobjects <> nil) and (ainfo.shiftstate*shiftstatesmask = []) then begin + removexorpic; + fselectobjects:= nil; + include(ainfo.eventstate,es_processed); + end; + end; + end; +end; + +function tobjectpicker.getpos: pointty; +begin + result:= addpoint(fpickrect.pos,fpickoffset); +end; + +function tobjectpicker.getshiftstate: shiftstatesty; +begin + result:= []; + if fmouseeventinfopo <> nil then begin + result:= fmouseeventinfopo^.shiftstate; + end + else begin + if fkeyeventinfopo <> nil then begin + result:= fkeyeventinfopo^.shiftstate; + end + end; +end; + +procedure tobjectpicker.clear; +begin + fselectobjects:= nil; + fmouseoverobjects:= nil; +// exclude(fstate,ops_moving); +end; + +function tobjectpicker.hasselectobjects: boolean; +begin + result:= fselectobjects <> nil; +end; + +function tobjectpicker.hasmouseoverobjects: boolean; +begin + result:= fselectobjects <> nil; +end; + +function tobjectpicker.picking: boolean; +begin + result:= ops_picking in fstate; +end; + +function tobjectpicker.rectselecting: boolean; +begin + result:= ops_rectselecting in fstate; +end; + +function tobjectpicker.multiselecting: boolean; +begin + result:= ops_multiselecting in fstate; +end; + +function tobjectpicker.moving: boolean; +begin + result:= ops_moving in fstate; +end; + +function tobjectpicker.active: boolean; +begin + result:= fstate*activestates <> []; +end; + +function tobjectpicker.getcurrentobjects: integerarty; +//var +// int1: integer; +begin +{ + if ops_multiselecting in fstate then begin + result:= fselectobjects; + for int1:= 0 to high(fmouseoverobjects) do begin + if finditem(result,fmouseoverobjects[int1]) < 0 then begin + additem(result,fmouseoverobjects[int1]); + end; + end; + end + else begin +} + if (fselectobjects <> nil) or (ops_multiselecting in fstate) then begin + result:= fselectobjects; + end + else begin + result:= fmouseoverobjects; + end; +// end; +end; + +function tobjectpicker.getthumbtrack: boolean; +begin + result:= opo_thumbtrack in foptions; +end; + +procedure tobjectpicker.setthumbtrack(const avalue: boolean); +begin + if avalue then begin + include(foptions,opo_thumbtrack); + end + else begin + exclude(foptions,opo_thumbtrack); + end; +end; + +function tobjectpicker.hascurrentobjects: boolean; +begin + result:= getcurrentobjects <> nil; +end; + +procedure tobjectpicker.dobeforepaint(const acanvas: tcanvas); +var + int1: integer; +begin + if ops_xorpicpainted in fstate then begin + include(fstate,ops_xorpicremoved); + int1:= acanvas.save; + if not (forigin = org_widget) then begin //todo org_screen + acanvas.intersectcliprect(fintf.getwidget.clientrect); + acanvas.move(fintf.getwidget.clientwidgetpos); + end; + initxorcanvas(acanvas); + dopaint(acanvas); + exclude(fstate,ops_xorpicpainted); + acanvas.restore(int1); + end; +end; + +procedure tobjectpicker.doafterpaint(const acanvas: tcanvas); +var + int1: integer; +begin + if ops_xorpicremoved in fstate then begin + exclude(fstate,ops_xorpicremoved); + int1:= acanvas.save; + if not (forigin = org_widget) then begin //todo org_screen + acanvas.intersectcliprect(fintf.getwidget.clientrect); + acanvas.move(fintf.getwidget.clientwidgetpos); + end; + initxorcanvas(acanvas); + dopaint(acanvas); + include(fstate,ops_xorpicpainted); + acanvas.restore(int1); + end; +end; + +{ thintcontroller } + +constructor thintcontroller.create(const intf: ihintcontroller); +begin + fintf:= intf; +end; + +procedure thintcontroller.mouseevent(var info: mouseeventinfoty); +begin + +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msepickwidget.pas b/mseide-msegui/lib/common/widgets/msepickwidget.pas new file mode 100644 index 0000000..408ae7e --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msepickwidget.pas @@ -0,0 +1,191 @@ +{ MSEgui Copyright (c) 2008-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepickwidget; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses,msesimplewidgets,mseobjectpicker,msegraphutils, + msegui,mseguiglob,msepointer,msetypes,msegraphics,mseevent,msemenus; + +// todo: +// select rect + +type + tcustompickwidget = class; + + getcursorshapeeventty = + procedure (const sender: tcustompickwidget; const picker: tobjectpicker; + var shape: cursorshapety; var found: boolean) of object; + getpickobjectseventty = procedure (const sender: tcustompickwidget; + const picker: tobjectpicker; + var objects: integerarty) of object; + pickmoveeventty = procedure(const sender: tcustompickwidget; + const picker: tobjectpicker) of object; + paintxorpiceventty = procedure(const sender: tcustompickwidget; + const picker: tobjectpicker; + const canvas: tcanvas) of object; + + tcustompickwidget = class(teventwidget,iobjectpicker) + private + fobjectpicker: tobjectpicker; + fongetcursorshape: getcursorshapeeventty; + fongetpickobjects: getpickobjectseventty; + fonbeginpickmove: pickmoveeventty; + fonpickthumbtrack: pickmoveeventty; + fonendpickmove: pickmoveeventty; + fonpaintxorpic: paintxorpiceventty; + foncancelpickmove: pickmoveeventty; + function getoptions: objectpickeroptionsty; + procedure setoptions(const avalue: objectpickeroptionsty); + protected + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property options: objectpickeroptionsty read getoptions + write setoptions default []; + property ongetcursorshape: getcursorshapeeventty read fongetcursorshape + write fongetcursorshape; + property ongetpickobjects: getpickobjectseventty read fongetpickobjects + write fongetpickobjects; + property onbeginpickmove: pickmoveeventty read fonbeginpickmove + write fonbeginpickmove; + property onpickthumbtrack: pickmoveeventty read fonpickthumbtrack + write fonpickthumbtrack; + property onendpickmove: pickmoveeventty read fonendpickmove + write fonendpickmove; + property oncancelpickmove: pickmoveeventty read foncancelpickmove + write foncancelpickmove; + property onpaintxorpic: paintxorpiceventty read fonpaintxorpic + write fonpaintxorpic; + end; + + tpickwidget = class(tcustompickwidget) + published + property options; + property ongetcursorshape; + property ongetpickobjects; + property onbeginpickmove; + property onendpickmove; + property onpaintxorpic; + end; + +implementation + +{ tcustompickpickwidget } + +constructor tcustompickwidget.create(aowner: tcomponent); +begin + fobjectpicker:= tobjectpicker.create(iobjectpicker(self)); + inherited; +end; + +destructor tcustompickwidget.destroy; +begin + inherited; + fobjectpicker.free; +end; + +function tcustompickwidget.getoptions: objectpickeroptionsty; +begin + result:= fobjectpicker.options; +end; + +procedure tcustompickwidget.setoptions(const avalue: objectpickeroptionsty); +begin + fobjectpicker.options:= avalue; +end; + +function tcustompickwidget.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; +var + bo1: boolean; +begin + bo1:= false; + if canevent(tmethod(fongetcursorshape)) then begin + fongetcursorshape(self,sender,shape,bo1); + end; + result:= bo1; +end; + +procedure tcustompickwidget.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +begin + if canevent(tmethod(fongetpickobjects)) then begin + fongetpickobjects(self,sender,objects); + end; +end; + +procedure tcustompickwidget.beginpickmove(const sender: tobjectpicker); +begin + if canevent(tmethod(fonbeginpickmove)) then begin + fonbeginpickmove(self,sender); + end; +end; + +procedure tcustompickwidget.pickthumbtrack(const sender: tobjectpicker); +begin + if canevent(tmethod(fonpickthumbtrack)) then begin + fonpickthumbtrack(self,sender); + end; +end; + +procedure tcustompickwidget.endpickmove(const sender: tobjectpicker); +begin + if canevent(tmethod(fonendpickmove)) then begin + fonendpickmove(self,sender); + end; +end; + +procedure tcustompickwidget.cancelpickmove(const sender: tobjectpicker); +begin + if canevent(tmethod(foncancelpickmove)) then begin + foncancelpickmove(self,sender); + end; +end; + +procedure tcustompickwidget.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); +begin + if canevent(tmethod(fonpaintxorpic)) then begin + fonpaintxorpic(self,sender,canvas); + end; +end; + +procedure tcustompickwidget.clientmouseevent(var info: mouseeventinfoty); +begin + fobjectpicker.mouseevent(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustompickwidget.dokeydown(var ainfo: keyeventinfoty); +begin + if not (es_processed in ainfo.eventstate) then begin + inherited; + end; + if not (es_processed in ainfo.eventstate) then begin + fobjectpicker.dokeydown(ainfo); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msepolygon.pas b/mseide-msegui/lib/common/widgets/msepolygon.pas new file mode 100644 index 0000000..fc3fcd1 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msepolygon.pas @@ -0,0 +1,648 @@ +{ MSEgui Copyright (c) 2008-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msepolygon; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msegui,mseguiglob,msewidgets,msegraphutils,msegraphics,classes,mclasses, + msetypes,msebitmap,msesimplewidgets,msemenus,mseevent; + +type + polygonstatety = (pos_geometryvalid); + polygonstatesty = set of polygonstatety; + + polygoninfoty = record + dim: rectty; + ppmm: real; + edgecount: integer; + edgeradiusmm: real; + edgeradiusvertexcount: integer; + rotation: real; + vertex: pointarty; + color: colorty; + colorline: colorty; + colorlinegap: colorty; + dashes: ansistring; + linewidthmm: real; + joinstyle: joinstylety; + brush: tmaskedbitmap; + brushoffset: pointty; + smooth: boolean; + end; + + projvectty = array[0..1] of real; + projmatrixty = array[0..2] of projvectty; //[row][col] + + tpolygon = class(tpaintbox) + private + finfo: polygoninfoty; + procedure setpoly_edgecount(const avalue: integer); + procedure setpoly_edgeradiusmm(const avalue: real); + procedure setpoly_edgeradiusvertexcount(const avalue: integer); + procedure setpoly_color(const avalue: colorty); + procedure setpoly_colorline(const avalue: colorty); + procedure setpoly_colorlinegap(const avalue: colorty); + procedure setpoly_dashes(const avalue: ansistring); + procedure setpoly_rotation(const avalue: real); + procedure setpoly_linewidthmm(const avalue: real); + procedure setpoly_joinstyle(const avalue: joinstylety); + procedure setpoly_brush(const avalue: tmaskedbitmap); + procedure setpoly_brushoffset_x(const avalue: integer); + procedure setpoly_brushoffset_y(const avalue: integer); + procedure setpolysmooth(const avalue: boolean); + protected + fstate: polygonstatesty; + procedure change; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure checkgeometry(const appmm: real); + procedure clientrectchanged; override; + procedure bitmapchanged(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property poly_edgecount: integer read finfo.edgecount + write setpoly_edgecount default 0; + //0 -> circle + property poly_edgeradiusmm: real read finfo.edgeradiusmm + write setpoly_edgeradiusmm; + property poly_edgeradiusvertexcount: integer read finfo.edgeradiusvertexcount + write setpoly_edgeradiusvertexcount default 2; + property poly_rotation: real read finfo.rotation write setpoly_rotation; + //0..1 -> 0..360° CCW + property poly_color: colorty read finfo.color write setpoly_color + default cl_white; + property poly_colorline: colorty read finfo.colorline write setpoly_colorline + default cl_black; + property poly_colorlinegap: colorty read finfo.colorlinegap + write setpoly_colorlinegap default cl_transparent; + property poly_linewidthmm: real read finfo.linewidthmm + write setpoly_linewidthmm; + property poly_dashes: ansistring read finfo.dashes write setpoly_dashes; + property poly_joinstyle: joinstylety read finfo.joinstyle + write setpoly_joinstyle default js_miter; + property poly_brush: tmaskedbitmap read finfo.brush write setpoly_brush; + property poly_brushoffset_x: integer read finfo.brushoffset.x write + setpoly_brushoffset_x; + property poly_brushoffset_y: integer read finfo.brushoffset.y write + setpoly_brushoffset_y; + property poly_smooth: boolean read finfo.smooth + write setpolysmooth default false; + end; + +const + unityprojmatrix: projmatrixty = ((1,0),(0,1),(0,0)); + +function movepoint(const start: complexty; const angle: real; + const dist: real): complexty; +function angle(const start, stop: complexty): real; +function halfangle(a,b: real): real; +function arcangle(a,b: real): real; + +procedure projtranslate(var matrix: projmatrixty; const tx,ty: real); +procedure projscale(var matrix: projmatrixty; const sx,sy: real); +procedure projrotate(var matrix: projmatrixty; const angle: real); //radiant +procedure projconcat(const a,b: projmatrixty; out dest: projmatrixty); + +procedure project(const matrix: projmatrixty; var point: pointty); overload; +procedure project(const matrix: projmatrixty; var point: complexty); overload; +procedure project(const matrix: projmatrixty; var points: complexarty); overload; +procedure realtointpoints(const source: complexarty; out dest: pointarty); + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + pi2 = 2*pi; + pid2 = pi/2; + pi3d2 = 3*pi/2; + +procedure realtointpoints(const source: complexarty; out dest: pointarty); +var + int1: integer; +begin + setlength(dest,length(source)); + for int1:= 0 to high(dest) do begin + dest[int1].x:= round(source[int1].re); + dest[int1].y:= round(source[int1].im); + end; +end; + +procedure project(const matrix: projmatrixty; var point: pointty); overload; +var + int1,int2: integer; +begin + int1:= round(matrix[0,0]*point.x + matrix[1,0]*point.y + matrix[2,0]); + int2:= round(matrix[0,1]*point.x + matrix[1,1]*point.y + matrix[2,1]); + point.x:= int1; + point.y:= int2; +end; + +procedure project(const matrix: projmatrixty; var point: complexty); overload; +var + rea1,rea2: real; +begin + rea1:= matrix[0,0]*point.re + matrix[1,0]*point.im + matrix[2,0]; + rea2:= matrix[0,1]*point.re + matrix[1,1]*point.im + matrix[2,1]; + point.re:= rea1; + point.im:= rea2; +end; + +procedure project(const matrix: projmatrixty; var points: complexarty); overload; +var + int1: integer; +begin + for int1:= 0 to high(points) do begin + project(matrix,points[int1]); + end; +end; + +procedure projtranslate(var matrix: projmatrixty; const tx,ty: real); +begin + if (tx <> 0) or (ty <> 0) then begin + matrix[2,0]:= matrix[2,0] + tx; + matrix[2,1]:= matrix[2,1] + ty; + end; +end; + +procedure projscale(var matrix: projmatrixty; const sx,sy: real); +var + ma: projmatrixty; +begin + if (sx <> 1) or (sy <> 1) then begin + ma[0,0]:= sx; + ma[0,1]:= 0; + ma[1,0]:= 0; + ma[1,1]:= sy; + ma[2,0]:= 0; + ma[2,1]:= 0; + projconcat(matrix,ma,matrix); + end; +end; + +procedure projrotate(var matrix: projmatrixty; const angle: real); +var + si,co: real; + ma: projmatrixty; +begin + if angle <> 0 then begin + si:= sin(angle); + co:= cos(angle); + ma[0,0]:= co; + ma[0,1]:= -si; //for counterclockwise rotation of screeen coordinates + ma[1,0]:= si; + ma[1,1]:= co; + ma[2,0]:= 0; + ma[2,1]:= 0; + projconcat(matrix,ma,matrix); + end; +end; + +procedure projconcat(const a,b: projmatrixty; out dest: projmatrixty); +var + o00,o01, + o10,o11, + o20,o21: real; + +begin + o00:= a[0,0]*b[0,0] + a[0,1]*b[1,0] {+ a[0,2]*b[2,0]}; + o01:= a[0,0]*b[0,1] + a[0,1]*b[1,1] {+ a[0,2]*b[2,1]}; + o10:= a[1,0]*b[0,0] + a[1,1]*b[1,0] {+ a[1,2]*b[2,0]}; + o11:= a[1,0]*b[0,1] + a[1,1]*b[1,1] {+ a[1,2]*b[2,1]}; + o20:= a[2,0]*b[0,0] + a[2,1]*b[1,0] + {a[2,2]*}b[2,0]; + o21:= a[2,0]*b[0,1] + a[2,1]*b[1,1] + {a[2,2]*}b[2,1]; + dest[0,0]:= o00; + dest[0,1]:= o01; + dest[1,0]:= o10; + dest[1,1]:= o11; + dest[2,0]:= o20; + dest[2,1]:= o21; +end; + +function movepoint(const start: complexty; const angle: real; + const dist: real): complexty; +begin + result.re:= start.re + cos(angle) * dist; + result.im:= start.im + sin(angle) * dist; +end; + +function angle(const start, stop: complexty): real; +var + dx,dy: real; +begin + dx:= stop.re - start.re; + dy:= stop.im - start.im; + if abs(dx) > abs(dy) then begin + result:= arctan(dy/dx); + if dx < 0 then begin + result:= result + pi; + end; + end + else begin + result:= pid2 - arctan(dx/dy); + if dy < 0 then begin + result:= result + pi; + end; + end; + if result < 0 then begin + result:= result+pi2; + end; +end; + +procedure normalizeangle(var angle: real); +begin + angle:= angle-int(angle/pi2)*pi2; //0..2pi + if angle < 0 then begin + angle:= angle + pi2; + end; +end; + +procedure normalizeanglehalf(var angle: real); +begin + angle:= angle-int(angle/pi2)*pi2; //0..2pi + if angle > pi then begin + angle:= angle - pi2; + end; +end; + +function halfangle(a,b: real): real; +begin + normalizeangle(a); + normalizeangle(b); + result:= (a + b)/2; + if b < a then begin + result:= result - pi; + if result < 0 then begin + result:= result + pi2; + end; + end; +end; + +function arcangle(a,b: real): real; +begin + normalizeangle(a); + normalizeangle(b); + result:= b - a; + if result < 0 then begin + result:= result + pi2; + end; +end; + +procedure arc(const center: complexty; const radius: real; + const startang, endang: real; const vertexcount: integer; + const dest: pcomplexaty); +var + step: real; + int1: integer; + rea1: real; +begin + if vertexcount >= 2 then begin + step:= arcangle(startang,endang)/(vertexcount-1); + for int1:= 0 to vertexcount - 1 do begin + rea1:= int1*step + startang; + dest^[int1].re:= radius * cos(rea1) + center.re; + dest^[int1].im:= radius * sin(rea1) + center.im; + end; + end; +end; + +{ tpolygon } + +constructor tpolygon.create(aowner: tcomponent); +begin + with finfo do begin + color:= cl_white; + colorline:= cl_black; + colorlinegap:= cl_transparent; + joinstyle:= js_miter; + edgeradiusvertexcount:= 2; + brush:= tmaskedbitmap.create(bmk_rgb{false}); + brush.onchange:= {$ifdef FPC}@{$endif}bitmapchanged; + end; + inherited; +end; + +destructor tpolygon.destroy; +begin + inherited; + finfo.brush.free; +end; + +procedure tpolygon.change; +begin + exclude(fstate,pos_geometryvalid); + invalidate; +end; + +procedure tpolygon.dopaintforeground(const canvas: tcanvas); +var + rect1: rectty; +begin + inherited; + checkgeometry(canvas.ppmm); + with finfo do begin + canvas.save; + canvas.smooth:= smooth; + canvas.linewidthmm:= linewidthmm; + canvas.dashes:= dashes; + canvas.colorbackground:= colorlinegap; + canvas.joinstyle:= joinstyle; + if (color = cl_brush) and brush.hasimage then begin + canvas.brush:= brush.bitmap; + canvas.adjustbrushorigin(moverect(dim,brushoffset),brush.alignment); + end; + case edgecount of + 0: begin + rect1.pos:= vertex[0]; + rect1.size:= sizety(vertex[1]); + canvas.fillellipse(rect1,color,colorline); + end; + 1: begin + canvas.drawline(vertex[0],vertex[1],colorline); + end; + else begin + canvas.fillpolygon(vertex,color,colorline); + end; + end; + canvas.restore; + end; +end; + +procedure tpolygon.setpoly_edgecount(const avalue: integer); +begin + if finfo.edgecount <> avalue then begin + finfo.edgecount:= avalue; + change; + end; +end; + +procedure tpolygon.setpoly_edgeradiusmm(const avalue: real); +begin + if finfo.edgeradiusmm <> avalue then begin + finfo.edgeradiusmm:= avalue; + change; + end; +end; + +procedure tpolygon.setpoly_edgeradiusvertexcount(const avalue: integer); +begin + if finfo.edgeradiusvertexcount <> avalue then begin + finfo.edgeradiusvertexcount:= avalue; + change; + end; +end; + +procedure tpolygon.setpoly_color(const avalue: colorty); +begin + if avalue <> finfo.color then begin + finfo.color:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpoly_colorline(const avalue: colorty); +begin + if avalue <> finfo.colorline then begin + finfo.colorline:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpoly_colorlinegap(const avalue: colorty); +begin + if avalue <> finfo.colorlinegap then begin + finfo.colorlinegap:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpoly_dashes(const avalue: ansistring); +begin + finfo.dashes:= avalue; + invalidate; +end; + +procedure tpolygon.setpoly_linewidthmm(const avalue: real); +begin + if avalue <> finfo.linewidthmm then begin + finfo.linewidthmm:= avalue; + change; + end; +end; + +procedure tpolygon.setpoly_joinstyle(const avalue: joinstylety); +begin + if avalue <> finfo.joinstyle then begin + finfo.joinstyle:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpoly_rotation(const avalue: real); +begin + if finfo.rotation <> avalue then begin + finfo.rotation:= avalue; + change; + end; +end; + +procedure tpolygon.checkgeometry(const appmm: real); +var +// rect1: rectty; + ar1,ar2: complexarty; + rea1,rea2,rea3: real; + int1,int2: integer; + ma: projmatrixty; + minx,miny,maxx,maxy: real; + si,co: real; + ptpo1,ptpo2,ptpo3: pcomplexty; + ang1,ang2: real; + pt1: complexty; + +begin + if not (pos_geometryvalid in fstate) or (finfo.ppmm <> appmm) then begin + include(fstate,pos_geometryvalid); + with finfo do begin + dim:= innerclientrect; + ppmm:= appmm; + int1:= round(linewidthmm*appmm/2); + if int1 = 0 then begin + int1:= 1; + end; + int2:= 2*int1-1; + dec(dim.cx,int2); + dec(dim.cy,int2); + dec(int1); + inc(dim.x,int1); + inc(dim.y,int1); + case edgecount of + 0: begin + setlength(vertex,2); + with dim do begin + vertex[0].x:= x + cx div 2; //center + vertex[0].y:= y + cy div 2; + vertex[1].x:= cx; //size + vertex[1].y:= cy; + end; + end; + 1,2: begin + setlength(ar1,2); + si:= sin(rotation*pi2); + co:= cos(rotation*pi2); + if abs(si) > abs(co) then begin + rea1:= co/si; //cotan + ar1[0].re:= -1; + ar1[0].im:= -rea1; + ar1[1].re:= 1; + ar1[1].im:= rea1; + end + else begin + rea1:= si/co; //tan + ar1[0].re:= -rea1; + ar1[0].im:= -1; + ar1[1].re:= rea1; + ar1[1].im:= 1; + end; + ma:= unityprojmatrix; + projtranslate(ma,1,1); + projscale(ma,dim.cx/2,dim.cy/2); //scale to destination rect + projtranslate(ma,dim.x,dim.y); //move to destrect + project(ma,ar1); + realtointpoints(ar1,vertex); + end; + else begin + setlength(ar1,edgecount); + rea1:= 2*pi/(edgecount); + rea2:= (pid2+rea1/2); + for int1:= 0 to high(ar1) do begin + rea3:= int1*rea1+rea2; //edge at bottom + ar1[int1].im:= sin(rea3); + ar1[int1].re:= cos(rea3); + end; + ma:= unityprojmatrix; + projrotate(ma,rotation*pi2); + project(ma,ar1); + minx:= 0; + miny:= 0; + maxx:= 0; + maxy:= 0; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if re < minx then begin + minx:= re; + end; + if im < miny then begin + miny:= im; + end; + if re > maxx then begin + maxx:= re; + end; + if im > maxy then begin + maxy:= im; + end; + end; + end; + ma:= unityprojmatrix; + projtranslate(ma,-(minx+maxx)/2,-(miny+maxy)/2); //center polygon + projscale(ma,1/(maxx-minx),1/(maxy-miny)); //norm to 1 + projtranslate(ma,0.5,0.5); //move to first quadrant + projscale(ma,dim.cx,dim.cy); //scale to destination rect + projtranslate(ma,dim.x,dim.y); //move to destrect + project(ma,ar1); + if (edgeradiusmm <> 0) and (edgeradiusvertexcount >= 2) then begin + setlength(ar2,length(ar1)*edgeradiusvertexcount); + rea1:= edgeradiusmm*ppmm; //radius in pixel + for int1:= 0 to high(ar1) do begin + ptpo1:= @ar1[int1]; + ptpo2:= @ar1[(int1+1) mod edgecount]; + ptpo3:= @ar1[(int1+2) mod edgecount]; + ang1:= angle(ptpo2^,ptpo1^); + ang2:= angle(ptpo2^,ptpo3^); + rea2:= halfangle(ang2,ang1); //angle of center -> vertex, center -> tangent + rea3:= arcangle(ang2,ang1)/2; + pt1:= movepoint(ptpo2^,rea2,rea1/sin(rea3)); + arc(pt1,rea1,ang1+pid2,ang2-pid2,edgeradiusvertexcount, + @ar2[int1*edgeradiusvertexcount]); + //center of circle +// ar2[int1*2]:= movepoint(pt1,ang1+pid2,rea1); //tangent +// ar2[int1*2+1]:= movepoint(pt1,ang2-pid2,rea1); //tangent +// ar2[int1*2]:= ptpo2^; +// ar2[int1*2+1]:= ptpo2^; +// ar2[int1*2+1]:= pt1; + end; + end + else begin + ar2:= ar1; + end; + realtointpoints(ar2,vertex); + removeduplicatedpoints(vertex); + end; + end; + end; + end; +end; + +procedure tpolygon.clientrectchanged; +begin + change; + inherited; +end; + +procedure tpolygon.setpoly_brush(const avalue: tmaskedbitmap); +begin + finfo.brush.assign(avalue); +end; + +procedure tpolygon.bitmapchanged(const sender: tobject); +begin + invalidate; +end; + +procedure tpolygon.setpoly_brushoffset_x(const avalue: integer); +begin + if avalue <> finfo.brushoffset.x then begin + finfo.brushoffset.x:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpoly_brushoffset_y(const avalue: integer); +begin + if avalue <> finfo.brushoffset.y then begin + finfo.brushoffset.y:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpolysmooth(const avalue: boolean); +begin + if avalue <> finfo.smooth then begin + finfo.smooth:= avalue; + invalidate; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msesimplewidgets.pas b/mseide-msegui/lib/common/widgets/msesimplewidgets.pas new file mode 100644 index 0000000..9955f52 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msesimplewidgets.pas @@ -0,0 +1,2828 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesimplewidgets; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + msegui,mseglob,mseguiglob,msetypes,msestrings,msegraphics,mseevent, + mseact,msewidgets, + mserichstring,mseshapes,classes,mclasses,mseclasses,msebitmap,msedrawtext, + msedrag,msestockobjects,msegraphutils,msemenus,msetimer; + +const + defaultbuttonwidth = 50; + defaultbuttonheight = 20; + defaultlabeltextflags = [tf_ycentered]; + defaultlabeloptionswidget = (defaultoptionswidget {+ + [ow_fontglyphheight]}) - + [ow_mousefocus,ow_tabfocus,ow_arrowfocus]; + defaultlabeloptionswidget1 = defaultoptionswidget1 + + [ow1_autowidth,ow1_autoheight,ow1_fontglyphheight]; + defaultlabelwidgetwidth = 100; + defaultlabelwidgetheight = 20; + + defaulticonoptionswidget = defaultoptionswidget - + [ow_mousefocus,ow_tabfocus,ow_arrowfocus]; + defaulticonoptionswidget1 = defaultoptionswidget1 + + [ow1_autowidth,ow1_autoheight]; + defaulticonwidgetwidth = 16; + defaulticonwidgetheight = 16; + +type + + teventwidget = class(tcustomeventwidget) + published + property onfocusedwidgetchanged; + property onenter; + property onexit; + property onfocus; + property ondefocus; + + property onmouseevent; + property onchildmouseevent; + property onclientmouseevent; + property onmousewheelevent; + + property onkeydown; + property onkeyup; + property onshortcut; + + property onloaded; + + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property onshow; + property onhide; + property onactivate; + property ondeactivate; + property onresize; + property onmove; + property onclosequery; + + property onasyncevent; + property oncomponentevent; + end; + + tcustombutton = class; + buttoneventty = procedure(const sender: tcustombutton) of object; + + tcustombutton = class(tactionsimplebutton,iactionlink,iimagelistinfo) + private + fmodalresult: modalresultty; + factioninfo: actioninfoty; + fautosize_cx: integer; + fautosize_cy: integer; + fonupdate: buttoneventty; + procedure setcaption(const Value: captionty); + function getframe: tframe; + procedure setframe(const Value: tframe); + function getcaption: captionty; + procedure setonexecute(const value: notifyeventty); + function isonexecutestored: boolean; + procedure setonbeforeexecute(const avalue: accepteventty); + function isonbeforeexecutestored: boolean; + procedure setonafterexecute(const value: notifyeventty); + function isonafterexecutestored: boolean; + procedure setaction(const value: tcustomaction); virtual; + function iscaptionstored: boolean; + function getstate: actionstatesty; + procedure setstate(const value: actionstatesty); virtual; + function isstatestored: boolean; + function getimagelist: timagelist; + procedure setimagelist(const Value: timagelist); + function isimageliststored: Boolean; + procedure setimagenr(const Value: imagenrty); + function isimagenrstored: boolean; + procedure setimagenrdisabled(const avalue: imagenrty); + function isimagenrdisabledstored: Boolean; + procedure setcolorglyph(const avalue: colorty); + function iscolorglyphstored: boolean; + procedure setimagepos(const avalue: imageposty); + procedure setcaptiondist(const avalue: integer); + procedure setautosize_cx(const avalue: integer); + procedure setautosize_cy(const avalue: integer); + procedure setimagedist(const avalue: integer); + procedure setimagedist1(const avalue: integer); + procedure setimagedist2(const avalue: integer); + procedure setshortcut(const avalue: shortcutty); + function isshortcutstored: boolean; + function getshortcut: shortcutty; + function getshortcut1: shortcutty; + procedure setshortcut1(const avalue: shortcutty); + function isshortcut1stored: boolean; + procedure readcaptionpos(reader: treader); + procedure settextflags(const avalue: textflagsty); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + procedure readshortcut(reader: treader); + procedure readshortcut1(reader: treader); + procedure readsc(reader: treader); + procedure writesc(writer: twriter); + procedure readsc1(reader: treader); + procedure writesc1(writer: twriter); + procedure setdisabled(const avalue: boolean); + function isenabledstored(): boolean; + protected + fexeccanceled: boolean; + function getdisabled(): boolean override; + procedure defineproperties(filer: tfiler); override; + procedure fontchanged; override; + procedure setcolor(const avalue: colorty); override; + procedure doidle(var again: boolean); + //iactionlink + function getactioninfopo: pactioninfoty; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty) virtual; + procedure actionchanged; + + procedure setoptions(const avalue: buttonoptionsty); override; + function gethint: msestring; override; + procedure sethint(const Value: msestring); override; + function ishintstored: boolean; override; + //iassistiveclient + function getassistivecaption(): msestring; override; + + procedure setenabled(const avalue: boolean); override; + procedure setvisible(const avalue: boolean); override; + procedure readstate(reader: treader); override; + procedure loaded; override; + procedure clientrectchanged; override; + procedure doexecute; override; + procedure doenter; override; + procedure doexit; override; + procedure dopaintforeground(const canvas: tcanvas); override; + function checkfocusshortcut(var info: keyeventinfoty): boolean; override; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); override; + procedure getautopaintsize(var asize: sizety); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function verticalfontheightdelta: boolean; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure synctofontheight; override; + procedure doupdate; + procedure updatehotkeys() override; + + property bounds_cx default defaultbuttonwidth; + property bounds_cy default defaultbuttonheight; +// property frame: tframe read getframe write setframe; + property font: twidgetfont read getfont write setfont stored isfontstored; + property modalresult: modalresultty read fmodalresult write fmodalresult + default mr_none; + property action: tcustomaction read factioninfo.action write setaction; + property caption: captionty read getcaption write setcaption stored iscaptionstored; + property textflags: textflagsty read finfo.ca.textflags + write settextflags default defaultcaptiontextflags; + property imagepos: imageposty read finfo.ca.imagepos write setimagepos + default ip_center; + property captiondist: integer read finfo.ca.captiondist write setcaptiondist + default defaultshapecaptiondist; + property imagelist: timagelist read getimagelist write setimagelist + stored isimageliststored; + property imagenr: imagenrty read factioninfo.imagenr write setimagenr + stored isimagenrstored default -1; + property imagenrdisabled: imagenrty read factioninfo.imagenrdisabled + write setimagenrdisabled + stored isimagenrdisabledstored default -2; + + property imagedist: integer read finfo.ca.imagedist + write setimagedist default 0; + property imagedist1: integer read finfo.ca.imagedist1 + write setimagedist1 default 0; + property imagedist2: integer read finfo.ca.imagedist2 + write setimagedist2 default 0; + property colorglyph: colorty read factioninfo.colorglyph write setcolorglyph + stored iscolorglyphstored default cl_default; + property shortcut: shortcutty read getshortcut write setshortcut + stored false default 0; + property shortcut1: shortcutty read getshortcut1 write setshortcut1 + stored false default 0; + property shortcuts: shortcutarty read factioninfo.shortcut write setshortcuts; + property shortcuts1: shortcutarty read factioninfo.shortcut1 + write setshortcuts1; + property onupdate: buttoneventty read fonupdate write fonupdate; + property onexecute: notifyeventty read factioninfo.onexecute + write setonexecute stored isonexecutestored; + property onbeforeexecute: accepteventty read factioninfo.onbeforeexecute + write setonbeforeexecute stored isonbeforeexecutestored; + property onafterexecute: notifyeventty read factioninfo.onafterexecute + write setonafterexecute stored isonafterexecutestored; + property autosize_cx: integer read fautosize_cx + write setautosize_cx default 0; + property autosize_cy: integer read fautosize_cy + write setautosize_cy default 0; + property disabled: boolean read getdisabled write setdisabled; + //sets as_disabled + published + property options; //before state! + property visible stored false; + property enabled stored isenabledstored; + property state: actionstatesty read getstate write setstate + stored isstatestored default []; + end; + + tbutton = class(tcustombutton) + published + property autosize_cx; + property autosize_cy; + property action; + property caption; + property textflags; + property shortcut; + property shortcut1; + property imagepos; + property captiondist; + property font; + property modalresult; + property imagelist; + property imagenr; + property imagenrdisabled; + property imagedist; + property imagedist1; + property imagedist2; + property colorglyph; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + + tstockglyphbutton = class(tcustombutton) + private + fglyph: stockglyphty; + procedure setglyph(const avalue: stockglyphty); + procedure setstate(const avalue: actionstatesty); override; + procedure setaction(const avalue: tcustomaction); override; + public + constructor create(aowner: tcomponent); override; + published + property glyph: stockglyphty read fglyph write setglyph default stg_none; + property autosize_cx; + property autosize_cy; + property action; + property caption; + property textflags; + property shortcut; + property shortcut1; + property imagepos; + property captiondist; + property font; + property modalresult; + property colorglyph; + property imagedist; + property imagedist1; + property imagedist2; + property options; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + + tcustomrichbutton = class(tcustombutton,irichstringprop) + private + ffaceactive: tcustomface; + ffacedisabled: tcustomface; + ffacemouse: tcustomface; + ffaceclicked: tcustomface; + fimagenrmouse: imagenrty; + fimagenrclicked: imagenrty; + fcaptionrich: msestring; + function getfaceactive: tcustomface; + procedure setfaceactive(const avalue: tcustomface); + function getfacemouse: tcustomface; + procedure setfacemouse(const avalue: tcustomface); + function getfaceclicked: tcustomface; + procedure setfaceclicked(const avalue: tcustomface); + function getfacedisabled: tcustomface; + procedure setfacedisabled(const avalue: tcustomface); + procedure setimagenrmouse(const avalue: imagenrty); + procedure setimagenrclicked(const avalue: imagenrty); + procedure setcaptionrich(const avalue: msestring); + procedure setrichvalue(const avalue: richstringty); + function getrichvalue(): richstringty; + procedure readrichcaption(reader: treader); + procedure writerichcaption(writer: twriter); + protected + function getactface: tcustomface override; + procedure dopaintforeground(const canvas: tcanvas) override; + procedure objectchanged(const sender: tobject) override; + procedure richcaptionchanged(); + procedure calccaptiontext(var ainfo: actioninfoty) override; + procedure defineproperties(filer: tfiler) override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure createfaceactive; + procedure createfacedisabled; + procedure createfacemouse; + procedure createfaceclicked; + property faceactive: tcustomface read getfaceactive write setfaceactive; + property facemouse: tcustomface read getfacemouse write setfacemouse; + property faceclicked: tcustomface read getfaceclicked write setfaceclicked; + property facedisabled: tcustomface read getfacedisabled write setfacedisabled; + property imagenrmouse: imagenrty read fimagenrmouse + write setimagenrmouse default -1; + property imagenrclicked: imagenrty read fimagenrclicked + write setimagenrclicked default -1; + property captionrich: msestring read fcaptionrich + write setcaptionrich stored false; + property richcaption: richstringty read finfo.ca.caption write setrichvalue; + published + property onmouseevent; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + + trichbutton = class(tcustomrichbutton) + published + property faceactive; + property facemouse; + property faceclicked; + property facedisabled; + property onmouseevent; + property onclientmouseevent; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property autosize_cx; + property autosize_cy; + property action; + property caption; + property captionrich; + property textflags; + property shortcut; + property shortcut1; + property imagepos; + property captiondist; + property font; + property modalresult; + property imagelist; + property imagenr; + property imagenrdisabled; + property imagenrmouse; + property imagenrclicked; + property imagedist; + property imagedist1; + property imagedist2; + property colorglyph; + property options; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + + trichstockglyphbutton = class(tcustomrichbutton) + private + fglyph: stockglyphty; + procedure setglyph(const avalue: stockglyphty); + procedure setstate(const avalue: actionstatesty); override; + procedure setaction(const avalue: tcustomaction); override; + public + constructor create(aowner: tcomponent); override; + published + property glyph: stockglyphty read fglyph write setglyph default stg_none; + property faceactive; + property facemouse; + property faceclicked; + property facedisabled; + property onmouseevent; + property onclientmouseevent; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property autosize_cx; + property autosize_cy; + property action; + property caption; + property captionrich; + property textflags; + property shortcut; + property shortcut1; + property imagepos; + property captiondist; + property font; + property modalresult; + property imagedist; + property imagedist1; + property imagedist2; + property colorglyph; + property options; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + + labeloptionty = (lao_nogray,lao_nounderline); + labeloptionsty = set of labeloptionty; + +type + tcustomlabel = class(tpublishedwidget) + private + frichcaption: richstringty; + fcaption: msestring; + factualtextflags: textflagsty; + ftextflags: textflagsty; + foptions: labeloptionsty; + procedure setcaption(const avalue: msestring); +// function getcaption: msestring; + procedure updatetextflags; + procedure settextflags(const Value: textflagsty); + procedure setoptions(const avalue: labeloptionsty); + protected + procedure dopaintforeground(const canvas: tcanvas); override; + procedure enabledchanged; override; + procedure getautopaintsize(var asize: sizety); override; + procedure fontchanged; override; + procedure clientrectchanged; override; + function verticalfontheightdelta: boolean; override; + function checkfocusshortcut(var info: keyeventinfoty): boolean; override; + public + constructor create(aowner: tcomponent); override; + procedure synctofontheight; override; + procedure updatehotkeys() override; + procedure initnewcomponent(const ascale: real); override; + property caption: msestring read fcaption write setcaption; + property font: twidgetfont read getfont write setfont stored isfontstored; + property fontempty: twidgetfontempty read getfontempty + write setfontempty stored isfontemptystored; + property textflags: textflagsty read ftextflags write settextflags default + defaultlabeltextflags; + property options: labeloptionsty read foptions write setoptions default []; + published + property optionswidget default defaultlabeloptionswidget; + property optionswidget1 default defaultlabeloptionswidget1; + property bounds_cx default defaultlabelwidgetwidth; + property bounds_cy default defaultlabelwidgetheight; + end; + + tlabel = class(tcustomlabel) + published + property options; //first + property caption; + property font; + property textflags; + end; + + animationoptionty = (ano_singleshot,ano_designactive); + animationoptionsty = set of animationoptionty; + + tcustomicon = class(tpublishedwidget) + private + fimagelist: timagelist; + fimagenum: integer; + fcolorglyph: colorty; + fcolorbackground: colorty; + falignment: alignmentsty; + fopacity: colorty; + fimagesize: sizety; + fanim_intervalus: int32; + fanim_count: int32; + fanim_enabled: boolean; + fanim_options: animationoptionsty; + procedure setimagelist(const avalue: timagelist); + procedure setimagenum(const avalue: integer); + procedure setcolorglyph(const avalue: colorty); + procedure setcolorbackground(const avalue: colorty); + procedure setalignment(const avalue: alignmentsty); + procedure setopacity(const avalue: colorty); + procedure readtransparency(reader: treader); + procedure setanim_intervalus(const avalue: int32); + procedure setanim_count(const avalue: int32); + procedure setanim_enabled(const avalue: boolean); + procedure setanim_options(const avalue: animationoptionsty); + procedure setcurrentanimoffset(const avalue: int32); + protected + fanimimagenum: int32; + fcurrentanimoffset: int32; + ftimer: tsimpletimer; + procedure resetanim(); + procedure animtick(const sender: tobject); + procedure updateanim(); + procedure dopaintforeground(const canvas: tcanvas); override; + procedure enabledchanged; override; + procedure getautopaintsize(var asize: sizety); override; + procedure clientrectchanged; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure defineproperties(filer: tfiler); override; + procedure loaded(); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + property imagelist: timagelist read fimagelist write setimagelist; + property imagenum: integer read fimagenum write setimagenum default -1; + property colorglyph: colorty read fcolorglyph + write setcolorglyph default cl_default; + property colorbackground: colorty read fcolorbackground + write setcolorbackground default cl_default; + property opacity: colorty read fopacity + write setopacity default cl_default; + property alignment: alignmentsty read falignment + write setalignment default [al_xcentered,al_ycentered]; + property currentanimoffset: int32 read fcurrentanimoffset + write setcurrentanimoffset; + procedure animrestart(); + property anim_intervalus: int32 read fanim_intervalus + write setanim_intervalus default 0; + //micro seconds, 0 = animation off + property anim_count: int32 read fanim_count write setanim_count default 0; + //starts from imagenum, < 2 -> animation off + property anim_enabled: boolean read fanim_enabled write + setanim_enabled default false; + property anim_options: animationoptionsty read fanim_options write + setanim_options default []; + published + property optionswidget default defaulticonoptionswidget; + property optionswidget1 default defaulticonoptionswidget1; + property bounds_cx default defaulticonwidgetwidth; + property bounds_cy default defaulticonwidgetheight; + end; + + ticon = class(tcustomicon) + published + property imagelist; + property imagenum; + property colorglyph; + property colorbackground; + property opacity; + property alignment; + property anim_intervalus; + property anim_count; + property anim_enabled; + property anim_options; + end; + + tgroupboxframe = class(tcaptionframe) + public + constructor create(const aintf: icaptionframe); + published + property framei_left default 2; + property framei_top default 2; + property framei_right default 2; + property framei_bottom default 2; + property levelo default -1; + property leveli default 1; + property captiondist default 0; + property options + default defaultcaptionframeoptions + [cfo_captionframecentered]; + property captionoffset default 4; + end; + + optionscalety = (osc_expandx,osc_shrinkx,osc_expandy,osc_shrinky, + osc_invisishrinkx,osc_invisishrinky, + osc_expandshrinkx,osc_expandshrinky); + //expand minshrinksize to minscrollsize + optionsscalety = set of optionscalety; +const + defaultoptionsscale = [osc_expandshrinkx,osc_expandshrinky]; +type + tcustomscalingwidget = class(tpublishedwidget) + private + fonfontheightdelta: fontheightdeltaeventty; + fonlayout: notifyeventty; + fscaling: integer; + fonresize: notifyeventty; + fonmove: notifyeventty; + fsizebefore: sizety; + procedure setoptionsscale(const avalue: optionsscalety); + procedure readonchildscaled(reader: treader); + procedure settaborderoverride(const avalue: ttaborderoverride); + protected + foptionsscale: optionsscalety; + ftaborderoverride: ttaborderoverride; + procedure beginscaling; + procedure endscaling; + procedure updateoptionsscale(); + procedure dofontheightdelta(var delta: integer); override; + procedure widgetregionchanged(const sender: twidget); override; + procedure clientrectchanged; override; + procedure poschanged; override; + procedure sizechanged; override; + procedure loaded; override; + procedure visiblepropchanged; override; + function calcminshrinksize(): sizety; override; + function nexttaborderoverride(const sender: twidget; + const down: boolean): twidget override; + procedure defineproperties(filer: tfiler); override; + procedure readstate(reader: treader); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure writestate(writer: twriter); override; + procedure dolayout(const sender: twidget); override; + property onresize: notifyeventty read fonresize write fonresize; + property onmove: notifyeventty read fonmove write fonmove; + published + property taborderoverride: ttaborderoverride read ftaborderoverride + write settaborderoverride; + property optionsscale: optionsscalety read foptionsscale write setoptionsscale + default defaultoptionsscale; + property onfontheightdelta: fontheightdeltaeventty read fonfontheightdelta + write fonfontheightdelta; + property onlayout: notifyeventty read fonlayout write fonlayout; + end; + + tscalingwidget = class(tcustomscalingwidget) + published + property font: twidgetfont read getfont write setfont stored isfontstored; + property optionsscale; + property onfontheightdelta; + property onlayout; + property onresize; + property onmove; + end; + +const + defaultgroupboxoptionswidget = (defaultoptionswidget + + [ow_arrowfocusin,ow_arrowfocusout,ow_parenttabfocus,ow_subfocus])- + [ow_mousefocus]; + +type + tgroupbox = class(tscalingwidget) + private + fonfocusedwidgetchanged: widgetchangeeventty; + protected + procedure internalcreateframe; override; + procedure dofocuschanged(const oldwidget,newwidget: twidget); override; + class function classskininfo: skininfoty; override; + public + constructor create(aowner: tcomponent); override; + procedure initnewcomponent(const ascale: real); override; + published + property optionswidget default defaultgroupboxoptionswidget; + property onfocusedwidgetchanged: widgetchangeeventty + read fonfocusedwidgetchanged write fonfocusedwidgetchanged; + end; + +const + defaultscrollboxoptionsscale = + defaultoptionsscale - [osc_expandshrinkx,osc_expandshrinky]; + defaultscrollboxoptionswidget = defaultoptionswidgetmousewheel + [ow_subfocus]; + +type + tscrollbox = class(tscalingwidget) + private + fonscroll: pointeventty; + fonscrolled: pointeventty; + function getframe: tscrollboxframe; + procedure setframe(const value: tscrollboxframe); + protected + procedure internalcreateframe; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure doscroll(const dist: pointty); override; + procedure doscrolled(const dist: pointty); override; +// procedure setclientpos(const avalue: pointty); + public + constructor create(aowner: tcomponent); override; + procedure clampinview(const arect: rectty; + const bottomright: boolean = false); override; + published + property frame: tscrollboxframe read getframe write setframe; + property onscroll: pointeventty read fonscroll write fonscroll; + property onscrolled: pointeventty read fonscrolled write fonscrolled; + property optionswidget default defaultscrollboxoptionswidget; + property optionsscale default defaultscrollboxoptionsscale; + end; + + tpaintbox = class(tscrollbox) + private + protected + published + property font: twidgetfont read getfont write setfont stored isfontstored; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property onmouseevent; + property onchildmouseevent; + property onclientmouseevent; + property onmousewheelevent; + + property onkeydown; + property onkeyup; + property onshortcut; + + property onresize; + property onmove; + end; + + tstepboxframe = class(tcustomstepframe) + published + property levelo; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient; + property colorbutton; + property colorglyph; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property options; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property buttonface; + property buttonframe; + property buttonsize; + property buttonpos; + property buttonslast; + property buttonsinline; + property buttonsinvisible; + property buttonsvisible; + property localprops; + property localprops1; //before template + property template; + end; + + tstepboxframe1 = class(tstepboxframe) + published + property mousewheel; + end; + + stepdirty = (sd_right,sd_up,sd_left,sd_down); + + stepeventty = procedure (const sender: tobject; const stepkind: stepkindty; + var handled: boolean) of object; + + tcustomstepbox = class(tpublishedwidget,istepbar,idragcontroller) + private + fonstep: stepeventty; + function getframe: tstepboxframe; + procedure setframe(const value: tstepboxframe); + protected + fdragcontroller: tdragcontroller; + procedure internalcreateframe; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure mousewheelevent(var info: mousewheeleventinfoty); override; + function dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property onstep: stepeventty read fonstep write fonstep; + published + property optionswidget default defaultoptionswidgetnofocus; + property frame: tstepboxframe read getframe write setframe; + end; + + tstepbox = class(tcustomstepbox) + published + property onstep; + end; + +implementation +uses + msekeyboard,sysutils,mseactions,msestreaming,mseassistiveserver; +type + tcustomframe1 = class(tcustomframe); + ttaborderoverride1 = class(ttaborderoverride); + +{ tcustombutton } + +constructor tcustombutton.create(aowner: tcomponent); +begin + initcaptioninfo(finfo.ca); + finfo.ca.imagepos:= ip_center; + initactioninfo(factioninfo); + inherited; + include(fwidgetstate1,ws1_nodesignframe); + size:= makesize(defaultbuttonwidth,defaultbuttonheight); +end; + +destructor tcustombutton.destroy; +begin + if bo_updateonidle in foptions then begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + inherited; +end; + +procedure tcustombutton.setoptions(const avalue: buttonoptionsty); +var + delta: buttonoptionsty; +begin + if avalue <> foptions then begin + delta:= buttonoptionsty( + {$ifdef FPC}longword{$else}longword{$endif}(foptions) xor + {$ifdef FPC}longword{$else}longword{$endif}(avalue)); + if bo_updateonidle in delta then begin + if (bo_updateonidle in avalue) and + not (csdesigning in componentstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doidle); + end + else begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + end; + end; + inherited; + if bo_shortcutcaption in avalue then begin + setactionoptions(iactionlink(self),factioninfo.options + [mao_shortcutcaption]); + end + else begin + setactionoptions(iactionlink(self),factioninfo.options - [mao_shortcutcaption]); + end; +end; + +function tcustombutton.verticalfontheightdelta: boolean; +begin + result:= tf_rotate90 in textflags; +end; + +procedure tcustombutton.updatehotkeys(); +begin + inherited; + calccaptiontext(factioninfo); +end; + +procedure tcustombutton.synctofontheight; +begin + inherited; + if tf_rotate90 in textflags then begin + bounds_cx:= font.glyphheight + innerclientframewidth.cx + 6; + end + else begin + bounds_cy:= font.glyphheight + innerclientframewidth.cy + 6; + end; +end; + +procedure tcustombutton.doexecute; +var + b1: boolean; +begin + if (fmodalresult <> mr_none) or + (options * [bo_nocandefocus,bo_candefocuswindow] <> [bo_candefocuswindow]) or + rootwidget.canparentclose then begin + fexeccanceled:= not doactionexecute1( + self,factioninfo,b1,false,(fmodalresult <> mr_none) or + (options * [bo_nocandefocus,bo_candefocuswindow] <> [])); + end + else begin + fexeccanceled:= true; + end; + if fmodalresult <> mr_none then begin + window.modalresult:= fmodalresult; + end; +end; + +procedure tcustombutton.dopaintforeground(const canvas: tcanvas); +begin + finfo.ca.font:= getfont; + inherited; +end; + +function tcustombutton.checkfocusshortcut(var info: keyeventinfoty): boolean; +begin + result:= inherited checkfocusshortcut(info) or + (bo_focusonshortcut in options) and + msegui.checkshortcut(info,factioninfo.captiontext, + bo_altshortcut in options) and canfocus; +end; + +procedure tcustombutton.doshortcut(var info: keyeventinfoty; const sender: twidget); +var + bo1,bo2: boolean; +begin + if not (es_processed in info.eventstate) and + not (csdesigning in componentstate) and + not (shs_disabled in finfo.state) then begin +{ + if checkfocusshortcut(info) then begin + setfocus(); + end; +} + bo1:= doactionshortcut(self,factioninfo,info); + if bo1 then begin + if (bo_focusonactionshortcut in foptions) and canfocus then begin + setfocus(); + end; + if fmodalresult <> mr_none then begin + window.modalresult:= fmodalresult; + end; + end; + if not bo1 and not (es_preview in info.eventstate) then begin +// bo2:= es_processed in info.eventstate; +// exclude(info.eventstate,es_processed); + bo2:= msegui.checkshortcut(info,factioninfo.captiontext, + bo_altshortcut in options); + exclude(info.eventstate,es_processed); + bo1:= (bo_executeonshortcut in options) and bo2 or + ((finfo.state * [shs_invisible,shs_disabled,shs_default] = [shs_default]) and + (info.key = key_return) and + ((info.shiftstate = []) or + (bo_executedefaultonenterkey in options) and + (info.shiftstate = [ss_second]))) and + not (aso_nodefaultbutton in assistiveoptions); + //no default button if assisted + if bo1 then begin + fexeccanceled:= false; + internalexecute(); + if not fexeccanceled then begin + if checkfocusshortcut(info) then begin + setfocus(); + end; + end; + include(info.eventstate,es_processed); + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end + else begin + inherited; + end; +end; + +function tcustombutton.getframe: tframe; +begin + result:= tframe(fframe); +end; + +procedure tcustombutton.setframe(const Value: tframe); +begin + fframe.Assign(value); +end; +{ +procedure tcustombutton.enabledchanged; +begin + inherited; + invalidate; +end; +} +procedure tcustombutton.actionchanged; +begin + finfo.color:= fcolor; + actioninfotoshapeinfo(self,factioninfo,finfo,foptions); + inherited setcolor(finfo.color); + finfo.color:= cl_transparent; +// if csdesigning in componentstate then begin + exclude(finfo.state,shs_invisible); +// end; + checkautosize; +end; + +procedure tcustombutton.readcaptionpos(reader: treader); +begin + imagepos:= readcaptiontoimagepos(reader); +end; + +procedure tcustombutton.readshortcut(reader: treader); +begin + shortcut:= translateshortcut(reader.readinteger); +end; + +procedure tcustombutton.readshortcut1(reader: treader); +begin + shortcut1:= translateshortcut(reader.readinteger); +end; + +procedure tcustombutton.readsc(reader: treader); +begin + shortcuts:= readshortcutarty(reader); +end; + +procedure tcustombutton.writesc(writer: twriter); +begin + writeshortcutarty(writer,factioninfo.shortcut); +end; + +procedure tcustombutton.readsc1(reader: treader); +begin + shortcuts1:= readshortcutarty(reader); +end; + +procedure tcustombutton.writesc1(writer: twriter); +begin + writeshortcutarty(writer,factioninfo.shortcut1); +end; + +procedure tcustombutton.setdisabled(const avalue: boolean); +begin + if avalue then begin + state:= state + [as_disabled]; + end + else begin + state:= state - [as_disabled]; + end; +end; + +function tcustombutton.isenabledstored(): boolean; +begin + result:= bo_noassistivedisabled in foptions; +end; + +procedure tcustombutton.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('captionpos', + {$ifdef FPC}@{$endif}readcaptionpos,nil,false); + filer.defineproperty('shortcut',{$ifdef FPC}@{$endif}readshortcut,nil,false); + filer.defineproperty('shortcut1',{$ifdef FPC}@{$endif}readshortcut1,nil,false); + filer.defineproperty('sc',{$ifdef FPC}@{$endif}readsc, + {$ifdef FPC}@{$endif}writesc, + isactionshortcutstored(factioninfo) and + ((filer.ancestor = nil) and (factioninfo.shortcut <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(factioninfo.shortcut, + tcustombutton(filer.ancestor).shortcuts)))); + filer.defineproperty('sc1',{$ifdef FPC}@{$endif}readsc1, + {$ifdef FPC}@{$endif}writesc1, + isactionshortcut1stored(factioninfo) and + ((filer.ancestor = nil) and (factioninfo.shortcut1 <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(factioninfo.shortcut, + tcustombutton(filer.ancestor).shortcuts)))); +end; + +procedure tcustombutton.fontchanged; +begin + inherited; + checkautosize; +end; + +procedure tcustombutton.setcolor(const avalue: colorty); +begin + if csloading in componentstate then begin + inherited; //no actionchanged + end; + setactioncolor(iactionlink(self),avalue); +end; + +function tcustombutton.getactioninfopo: pactioninfoty; +begin + result:= @factioninfo; +end; + +function tcustombutton.shortcutseparator: msechar; +begin + result:= ' '; +end; + +procedure tcustombutton.calccaptiontext(var ainfo: actioninfoty); +begin + mseactions.calccaptiontext(ainfo,shortcutseparator); +end; + +procedure tcustombutton.setaction(const value: tcustomaction); +begin + linktoaction(iactionlink(self),value,factioninfo); +end; + +procedure tcustombutton.setonexecute(const value: notifyeventty); +begin + setactiononexecute(iactionlink(self),value,csloading in componentstate); +end; + +function tcustombutton.isonexecutestored: boolean; +begin + result:= isactiononexecutestored(factioninfo); +end; + +procedure tcustombutton.setonbeforeexecute(const avalue: accepteventty); +begin + setactiononbeforeexecute(iactionlink(self),avalue,csloading in componentstate); +end; + +function tcustombutton.isonbeforeexecutestored: boolean; +begin + result:= isactiononbeforeexecutestored(factioninfo); +end; + +procedure tcustombutton.setonafterexecute(const value: notifyeventty); +begin + setactiononafterexecute(iactionlink(self),value,csloading in componentstate); +end; + +function tcustombutton.isonafterexecutestored: boolean; +begin + result:= isactiononafterexecutestored(factioninfo); +end; + +function tcustombutton.getcaption: captionty; +begin + result:= factioninfo.captiontext; +end; + +procedure tcustombutton.setcaption(const Value: captionty); +begin + setactioncaption(iactionlink(self),value); +end; + +function tcustombutton.iscaptionstored: boolean; +begin + result:= isactioncaptionstored(factioninfo); +end; + +function tcustombutton.getimagelist: timagelist; +begin + result:= timagelist(factioninfo.imagelist); +end; + +procedure tcustombutton.setimagelist(const Value: timagelist); +begin + setactionimagelist(iactionlink(self),Value); +end; + +function tcustombutton.isimageliststored: Boolean; +begin + result:= isactionimageliststored(factioninfo); +end; + +procedure tcustombutton.setimagenr(const Value: imagenrty); +begin + setactionimagenr(iactionlink(self),Value); +end; + +function tcustombutton.isimagenrstored: Boolean; +begin + result:= isactionimagenrstored(factioninfo); +end; + +procedure tcustombutton.setimagenrdisabled(const avalue: imagenrty); +begin + setactionimagenrdisabled(iactionlink(self),avalue); +end; + +function tcustombutton.isimagenrdisabledstored: Boolean; +begin + result:= isactionimagenrdisabledstored(factioninfo); +end; + +procedure tcustombutton.setcolorglyph(const avalue: colorty); +begin + setactioncolorglyph(iactionlink(self),avalue); +end; + +function tcustombutton.iscolorglyphstored: boolean; +begin + result:= isactioncolorglyphstored(factioninfo); +end; + +function tcustombutton.gethint: msestring; +begin + result:= factioninfo.hint; +end; + +procedure tcustombutton.sethint(const Value: msestring); +begin + setactionhint(iactionlink(self),value); +end; + +function tcustombutton.ishintstored: boolean; +begin + result:= isactionhintstored(factioninfo); +end; + +function tcustombutton.getassistivecaption(): msestring; +begin + result:= factioninfo.captiontext; + if result = '' then begin + result:= inherited getassistivecaption(); + end; +end; + +function tcustombutton.getdisabled(): boolean; +begin + result:= as_disabled in factioninfo.state; +end; + +procedure tcustombutton.setshortcut(const avalue: shortcutty); +begin + setactionshortcut(iactionlink(self),avalue); +end; + +function tcustombutton.isshortcutstored: boolean; +begin + result:= isactionshortcutstored(factioninfo); +end; + +function tcustombutton.getshortcut: shortcutty; +begin + result:= getsimpleshortcut(factioninfo); +end; + +function tcustombutton.getshortcut1: shortcutty; +begin + result:= getsimpleshortcut1(factioninfo); +end; + +procedure tcustombutton.setshortcut1(const avalue: shortcutty); +begin + setactionshortcut1(iactionlink(self),avalue); +end; + +function tcustombutton.isshortcut1stored: boolean; +begin + result:= isactionshortcut1stored(factioninfo); +end; + +function tcustombutton.getstate: actionstatesty; +begin + result:= factioninfo.state; +end; + +procedure tcustombutton.setstate(const value: actionstatesty); +begin + setactionstate(iactionlink(self),value); + visible:= not (as_invisible in factioninfo.state); + if (bo_noassistivedisabled in foptions){ and canassistive()} then begin + if not disabled then begin + enabled:= true; + end; + end + else begin + enabled:= not (as_disabled in factioninfo.state); + end; +end; + +procedure tcustombutton.setenabled(const avalue: boolean); +begin + if not isenabledstored then begin + if avalue then begin + setactionstate(iactionlink(self),state - [as_disabled]); + end + else begin + setactionstate(iactionlink(self),state + [as_disabled]); + end; + end; + inherited; +end; + +procedure tcustombutton.setvisible(const avalue: boolean); +begin + if avalue then begin + setactionstate(iactionlink(self),state - [as_invisible]); + end + else begin + setactionstate(iactionlink(self),state + [as_invisible]); + end; + inherited; +end; + +function tcustombutton.isstatestored: boolean; +begin + result:= isactionstatestored(factioninfo); +end; + +procedure tcustombutton.setimagepos(const avalue: imageposty); +begin + if avalue <> finfo.ca.imagepos then begin +// if avalue in [ip_left,ip_right,ip_top,ip_bottom, +// ip_leftcenter,ip_rightcenter, +// ip_topcenter,ip_bottomcenter] then begin + finfo.ca.imagepos:= avalue; +// end +// else begin +// finfo.ca.imagepos:= ip_center; +// end; + checkautosize; + invalidate; + end; +end; + +procedure tcustombutton.setcaptiondist(const avalue: integer); +begin + if avalue <> finfo.ca.captiondist then begin + finfo.ca.captiondist:= avalue; + checkautosize(); + end; +end; + +procedure tcustombutton.setimagedist(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist then begin + finfo.ca.imagedist:= avalue; + checkautosize(); + end; +end; + +procedure tcustombutton.setimagedist1(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist1 then begin + finfo.ca.imagedist1:= avalue; + checkautosize(); + end; +end; + +procedure tcustombutton.setimagedist2(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist2 then begin + finfo.ca.imagedist2:= avalue; + checkautosize(); + end; +end; + +{ +procedure tcustombutton.setenabled(const Value: boolean); +begin + inherited; + if value then begin + state:= state -[ss_disabled]; + end + else begin + state:= state +[ss_disabled]; + end; +end; + +function tcustombutton.isenabledstored: Boolean; +begin + result:= isactionenabledstored(factioninfo); +end; + + +procedure tcustombutton.setvisible(const Value: boolean); +begin + inherited; + setactionvisible(iactionlink(self),value); +end; + +function tcustombutton.isvisiblestored: Boolean; +begin + result:= isactionvisiblestored(factioninfo); +end; +} +procedure tcustombutton.readstate(reader: treader); +begin + actionbeginload(iactionlink(self)); + inherited; +end; + +procedure tcustombutton.loaded; +begin + inherited; + actionendload(iactionlink(self)); +// actionchanged; +end; +{ +procedure tcustombutton.doidle; +begin + actiondoidle(factioninfo); + inherited; +end; +} +procedure tcustombutton.doenter; +var + int1: integer; + widget1: twidget; +begin + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget1:= fparentwidget.widgets[int1]; + if widget1 is tcustombutton then begin + with tcustombutton(widget1) do begin + if shs_default in finfo.state then begin + exclude(finfo.state,shs_default); + invalidateframestate(); + end; + end; + end; + end; + end; + inherited; +end; + +procedure tcustombutton.doexit; +var + int1: integer; + widget1: twidget; +begin + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget1:= fparentwidget.widgets[int1]; + if widget1 is tcustombutton then begin + with tcustombutton(widget1) do begin + if as_default in factioninfo.state then begin + if not (shs_default in finfo.state) then begin + include(finfo.state,shs_default); + invalidateframestate(); + end; + end; + end; + end; + end; + end; + inherited; +end; + +procedure tcustombutton.getautopaintsize(var asize: sizety); +begin + if fframe <> nil then begin + asize:= calccaptionsize(getcanvas,finfo.ca,@tcustomframe1(fframe).fi.innerframe); + end + else begin + asize:= calccaptionsize(getcanvas,finfo.ca,nil); + end; + inc(asize.cx,8+fautosize_cx); + inc(asize.cy,6+fautosize_cy); + if (fframe <> nil) then begin + if fso_flat in fframe.optionsskin then begin + dec(asize.cx,2); + dec(asize.cy,2); + end; + if fso_noanim in fframe.optionsskin then begin + dec(asize.cx,2); + dec(asize.cy,2); + end; + end; + if not (shs_noinnerrect in finfo.state) then begin + outertopaintsize(asize); +// innertopaintsize(asize); + end; + inherited; //check min/max size +end; + +procedure tcustombutton.clientrectchanged; +begin + inherited; + checkautosize; //for frame.framei +end; + +procedure tcustombutton.setautosize_cx(const avalue: integer); +begin + if fautosize_cx <> avalue then begin + fautosize_cx:= avalue; + checkautosize; + end; +end; + +procedure tcustombutton.setautosize_cy(const avalue: integer); +begin + if fautosize_cy <> avalue then begin + fautosize_cy:= avalue; + checkautosize; + end; +end; + +procedure tcustombutton.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if sender = finfo.ca.imagelist then begin + if (event = oe_changed) then begin + actionchanged; + end; + if (event = oe_destroyed) then begin + finfo.ca.imagelist:= nil; + end; + end; +end; + +procedure tcustombutton.settextflags(const avalue: textflagsty); +begin + if finfo.ca.textflags <> avalue then begin + finfo.ca.textflags:= checktextflags(finfo.ca.textflags,avalue); + invalidate; + checkautosize; + end; +end; + +procedure tcustombutton.setshortcuts(const avalue: shortcutarty); +begin + setactionshortcuts(iactionlink(self),avalue); +end; + +procedure tcustombutton.setshortcuts1(const avalue: shortcutarty); +begin + setactionshortcuts1(iactionlink(self),avalue); +end; + +procedure tcustombutton.doupdate; +begin + if factioninfo.action <> nil then begin + factioninfo.action.doupdate; + end; + if canevent(tmethod(fonupdate)) then begin + fonupdate(self); + end; +end; + +procedure tcustombutton.doidle(var again: boolean); +begin + doupdate; +end; + +{ tcustomrichbutton } + +constructor tcustomrichbutton.create(aowner: tcomponent); +begin + fimagenrmouse:= -1; + fimagenrclicked:= -1; + inherited; +end; + +destructor tcustomrichbutton.destroy; +begin + inherited; + ffaceactive.free; + ffacedisabled.free; + ffacemouse.free; + ffaceclicked.free; +end; + +procedure tcustomrichbutton.setimagenrmouse(const avalue: imagenrty); +begin + if fimagenrmouse <> avalue then begin + fimagenrmouse:= avalue; + invalidate; + end; +end; + +procedure tcustomrichbutton.setimagenrclicked(const avalue: imagenrty); +begin + if fimagenrclicked <> avalue then begin + fimagenrclicked:= avalue; + invalidate; + end; +end; + +procedure tcustomrichbutton.setcaptionrich(const avalue: msestring); +begin + fcaptionrich:= avalue; + factioninfo.caption1.text:= avalue; + if avalue = '' then begin + factioninfo.caption1.format:= nil; + end; + richcaptionchanged(); +end; + +procedure tcustomrichbutton.setrichvalue(const avalue: richstringty); +begin + factioninfo.caption1:= avalue; + fcaptionrich:= avalue.text; + richcaptionchanged(); +end; + +function tcustomrichbutton.getrichvalue(): richstringty; +begin + result:= factioninfo.caption1; +end; + +function tcustomrichbutton.getfaceactive: tcustomface; +begin + getoptionalobject(ffaceactive,{$ifdef FPC}@{$endif}createfaceactive); + result:= ffaceactive; +end; + +procedure tcustomrichbutton.setfaceactive(const avalue: tcustomface); +begin + setoptionalobject(avalue,ffaceactive,{$ifdef FPC}@{$endif}createfaceactive); + invalidate; +end; + +function tcustomrichbutton.getfacemouse: tcustomface; +begin + getoptionalobject(ffacemouse,{$ifdef FPC}@{$endif}createfacemouse); + result:= ffacemouse; +end; + +procedure tcustomrichbutton.setfacemouse(const avalue: tcustomface); +begin + setoptionalobject(avalue,ffacemouse,{$ifdef FPC}@{$endif}createfacemouse); + invalidate; +end; + +function tcustomrichbutton.getfaceclicked: tcustomface; +begin + getoptionalobject(ffaceclicked,{$ifdef FPC}@{$endif}createfaceclicked); + result:= ffaceclicked; +end; + +procedure tcustomrichbutton.setfaceclicked(const avalue: tcustomface); +begin + setoptionalobject(avalue,ffaceclicked,{$ifdef FPC}@{$endif}createfaceclicked); + invalidate; +end; + +function tcustomrichbutton.getfacedisabled: tcustomface; +begin + getoptionalobject(ffacedisabled,{$ifdef FPC}@{$endif}createfacedisabled); + result:= ffacedisabled; +end; + +procedure tcustomrichbutton.setfacedisabled(const avalue: tcustomface); +begin + setoptionalobject(avalue,ffacedisabled,{$ifdef FPC}@{$endif}createfacedisabled); + invalidate; +end; + + +procedure tcustomrichbutton.createfaceactive; +begin + ffaceactive:= tface.create(iface(self)); +end; + +procedure tcustomrichbutton.createfacedisabled; +begin + ffacedisabled:= tface.create(iface(self)); +end; + +procedure tcustomrichbutton.createfacemouse; +begin + ffacemouse:= tface.create(iface(self)); +end; + +procedure tcustomrichbutton.createfaceclicked; +begin + ffaceclicked:= tface.create(iface(self)); +end; + +function tcustomrichbutton.getactface: tcustomface; +begin + result:= inherited getactface; + if active then begin + if ffaceactive <> nil then begin + result:= ffaceactive; + end; + end + else begin + if not isenabled then begin + if ffacedisabled <> nil then begin + result:= ffacedisabled; + end; + end + else begin + if (shs_clicked in finfo.state) and (ffaceclicked <> nil) then begin + result:= ffaceclicked; + end + else begin + if (shs_mouse in finfo.state) and (ffacemouse <> nil) then begin + result:= ffacemouse; + end; + end; + end; + end; +end; + +procedure tcustomrichbutton.dopaintforeground(const canvas: tcanvas); +begin + finfo.ca.imagenr:= factioninfo.imagenr; + if shs_mouse in finfo.state then begin + if fimagenrmouse <> -1 then begin + finfo.ca.imagenr:= fimagenrmouse; + end; + end; + if shs_clicked in finfo.state then begin + if fimagenrclicked <> -1 then begin + finfo.ca.imagenr:= fimagenrclicked; + end; + end; + inherited; +end; + +procedure tcustomrichbutton.objectchanged(const sender: tobject); +begin + inherited; + if ffaceactive <> nil then begin + ffaceactive.checktemplate(sender); + end; + if ffacedisabled <> nil then begin + ffacedisabled.checktemplate(sender); + end; + if ffacemouse <> nil then begin + ffacemouse.checktemplate(sender); + end; + if ffaceclicked <> nil then begin + ffaceclicked.checktemplate(sender); + end; +end; + +procedure tcustomrichbutton.richcaptionchanged(); +begin + if not (csloading in componentstate) then begin + calccaptiontext(factioninfo); + actioninfotoshapeinfo(self,factioninfo,finfo,foptions); + invalidate(); + checkautosize(); + end; +end; + +procedure tcustomrichbutton.calccaptiontext(var ainfo: actioninfoty); +begin + if fcaptionrich = '' then begin //else don't display text of fcaption + inherited; + end; +end; + +procedure tcustomrichbutton.readrichcaption(reader: treader); +begin + richcaption:= readrichstring(reader); +end; + +procedure tcustomrichbutton.writerichcaption(writer: twriter); +begin + writerichstring(writer,finfo.ca.caption); +end; + +procedure tcustomrichbutton.defineproperties(filer: tfiler); +var + b1: boolean; +begin + inherited; + if filer.ancestor <> nil then begin + b1:= isequalrichstring( + tcustomrichbutton(filer.ancestor).factioninfo.caption1, + factioninfo.caption1); + end + else begin + b1:= not isemptyrichstring(factioninfo.caption1); + end; + filer.defineproperty('richcaption',@readrichcaption,@writerichcaption,b1); +end; + +{ +procedure tcustomrichbutton.dobeforepaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonbeforepaint)) then begin + fonbeforepaint(self,canvas); + end; +end; + +procedure tcustomrichbutton.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaintbackground)) then begin + fonpaintbackground(self,canvas); + end; +end; + +procedure tcustomrichbutton.doonpaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaint)) then begin + fonpaint(self,canvas); + end; +end; + +procedure tcustomrichbutton.doafterpaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonafterpaint)) then begin + fonafterpaint(self,canvas); + end; +end; + +procedure tcustomrichbutton.mouseevent(var info: mouseeventinfoty); +begin + if canevent(tmethod(fonmouseevent)) then begin + fonmouseevent(self,info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +} +{ tstockglyphbutton } + +constructor tstockglyphbutton.create(aowner: tcomponent); +begin + inherited; + imagelist:= stockobjects.glyphs; + glyph:= stg_none; +end; + +procedure tstockglyphbutton.setglyph(const avalue: stockglyphty); +begin + fglyph:= avalue; + imagenr:= ord(avalue); +end; + +procedure tstockglyphbutton.setstate(const avalue: actionstatesty); +begin + inherited setstate(avalue + [as_localimagelist,as_localimagenr]); +end; + +procedure tstockglyphbutton.setaction(const avalue: tcustomaction); +begin + inherited; + glyph:= glyph; + imagelist:= stockobjects.glyphs; +end; + +{ trichstockglyphbutton } + +constructor trichstockglyphbutton.create(aowner: tcomponent); +begin + inherited; + imagelist:= stockobjects.glyphs; + glyph:= stg_none; +end; + +procedure trichstockglyphbutton.setglyph(const avalue: stockglyphty); +begin + fglyph:= avalue; + imagenr:= ord(avalue); +end; + +procedure trichstockglyphbutton.setstate(const avalue: actionstatesty); +begin + inherited setstate(avalue + [as_localimagelist,as_localimagenr]); +end; + +procedure trichstockglyphbutton.setaction(const avalue: tcustomaction); +begin + inherited; + glyph:= glyph; + imagelist:= stockobjects.glyphs; +end; + +{ tcustomlabel } + +constructor tcustomlabel.create(aowner: tcomponent); +begin + ftextflags:= defaultlabeltextflags; + inherited; + foptionswidget:= defaultlabeloptionswidget; + foptionswidget1:= defaultlabeloptionswidget1; + fwidgetrect.cx:= defaultlabelwidgetwidth; + fwidgetrect.cy:= defaultlabelwidgetheight; +end; + +procedure tcustomlabel.dopaintforeground(const canvas: tcanvas); +begin + inherited; + drawtext(canvas,frichcaption,innerclientrect,factualtextflags,font); +end; +{ +function tcustomlabel.getcaption: msestring; +begin + if lao_nounderline in foptions then begin + result:= fcaption.text; + end + else begin + result:= richstringtocaption(fcaption); + end; +end; +} +procedure tcustomlabel.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + if lao_nounderline in foptions then begin + frichcaption.text:= avalue; + end + else begin + captiontorichstring(avalue,frichcaption); + end; + checkautosize; + invalidate; +end; + +procedure tcustomlabel.updatehotkeys(); +begin + inherited; + setcaption(fcaption); +end; + +procedure tcustomlabel.settextflags(const Value: textflagsty); +begin + if ftextflags <> value then begin + ftextflags:= Value; + updatetextflags; + checkautosize; + invalidate; + end; +end; + +function tcustomlabel.verticalfontheightdelta: boolean; +begin + result:= tf_rotate90 in textflags +end; + +procedure tcustomlabel.synctofontheight; +begin + syncsinglelinefontheight; +end; + +procedure tcustomlabel.updatetextflags; +begin + if not (csloading in componentstate) then begin + if isenabled or (lao_nogray in foptions) then begin + factualtextflags:= ftextflags; + end + else begin + factualtextflags:= ftextflags + [tf_grayed]; + end; + end; +end; + +procedure tcustomlabel.enabledchanged; +begin + inherited; + updatetextflags; + invalidate; +end; + +procedure tcustomlabel.setoptions(const avalue: labeloptionsty); +var + opt1: labeloptionsty; +begin + if foptions <> avalue then begin + opt1:= foptions >< avalue; + foptions:= avalue; + updatetextflags; + invalidate; + if (lao_nounderline in opt1) and not(csreading in componentstate) then begin + if lao_nounderline in avalue then begin + frichcaption.text:= fcaption; + frichcaption.format:= nil; + end + else begin + captiontorichstring(fcaption,frichcaption); + end; + checkautosize(); + end; + end; +end; + +procedure tcustomlabel.getautopaintsize(var asize: sizety); +begin + asize:= textrect(getcanvas,frichcaption,innerclientrect,ftextflags).size; + innertopaintsize(asize); +end; + +procedure tcustomlabel.fontchanged; +begin + inherited; + checkautosize; +end; + +procedure tcustomlabel.clientrectchanged; +begin + inherited; + checkautosize; //for frame.framei +end; + +procedure tcustomlabel.initnewcomponent(const ascale: real); +begin + inherited; + caption:= msestring(name); +end; + +function tcustomlabel.checkfocusshortcut(var info: keyeventinfoty): boolean; +begin + result:= canfocus and checkshortcut(info,fcaption,true); +end; + +{ tcustomicon } + +constructor tcustomicon.create(aowner: tcomponent); +begin + fimagenum:= -1; + fcolorglyph:= cl_default; + fcolorbackground:= cl_default; + fopacity:= cl_default; + falignment:= [al_xcentered,al_ycentered]; + inherited; + foptionswidget:= defaulticonoptionswidget; + foptionswidget1:= defaulticonoptionswidget1; + fwidgetrect.cx:= defaulticonwidgetwidth; + fwidgetrect.cy:= defaulticonwidgetheight; +end; + +destructor tcustomicon.destroy; +begin + freeandnil(ftimer); + inherited; +end; + +procedure tcustomicon.setimagelist(const avalue: timagelist); +begin + if fimagelist <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + checkautosize; + invalidate; + end; +end; + +procedure tcustomicon.setimagenum(const avalue: integer); +begin + if fimagenum <> avalue then begin + fimagenum:= avalue; + invalidate; + end; +end; + +procedure tcustomicon.dopaintforeground(const canvas: tcanvas); +var + i1: int32; +begin + inherited; + if fimagelist <> nil then begin + i1:= fimagenum; + if ftimer <> nil then begin + i1:= i1 + fcurrentanimoffset; + end; + fimagelist.paint(canvas,i1,innerclientrect,falignment,fcolorglyph, + fcolorbackground,fopacity); + end; +end; + +procedure tcustomicon.enabledchanged; +begin + inherited; + invalidate; +end; + +procedure tcustomicon.getautopaintsize(var asize: sizety); +begin + inherited; + if fimagelist <> nil then begin + if frame <> nil then begin + with tcustomframe1(fframe) do begin + asize.cx:= fimagelist.width + fi.innerframe.left + fi.innerframe.right; + asize.cy:= fimagelist.height + fi.innerframe.top + fi.innerframe.bottom; + end; + end + else begin + asize:= fimagelist.size; + end; + end; +end; + +procedure tcustomicon.clientrectchanged; +begin + inherited; + checkautosize; //for framei +end; + +procedure tcustomicon.setcolorglyph(const avalue: colorty); +begin + if fcolorglyph <> avalue then begin + fcolorglyph:= avalue; + invalidate; + end; +end; + +procedure tcustomicon.setcolorbackground(const avalue: colorty); +begin + if fcolorbackground <> avalue then begin + fcolorbackground:= avalue; + invalidate; + end; +end; + +procedure tcustomicon.setopacity(const avalue: colorty); +begin + if fopacity <> avalue then begin + fopacity:= avalue; + invalidate; + end; +end; + +procedure tcustomicon.setalignment(const avalue: alignmentsty); +begin + if falignment <> avalue then begin + falignment:= avalue; + checkautosize; + invalidate; + end; +end; + +procedure tcustomicon.objectevent(const sender: tobject; + const event: objecteventty); +var + size1: sizety; +begin + inherited; + if (sender = fimagelist) and (event = oe_changed) then begin + size1:= fimagelist.size; + if (size1.cx <> fimagesize.cx) or (size1.cy <> fimagesize.cy) then begin + fimagesize:= size1; + checkautosize; + end; + invalidate; + end; +end; + +procedure tcustomicon.readtransparency(reader: treader); +begin + opacity:= transparencytoopacity(reader.readinteger); +end; + +procedure tcustomicon.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('transparency',@readtransparency,nil,false); +end; + +procedure tcustomicon.setanim_intervalus(const avalue: int32); +begin + if avalue <> fanim_intervalus then begin + fanim_intervalus:= avalue; + updateanim(); + end; +end; + +procedure tcustomicon.setanim_count(const avalue: int32); +begin + if avalue <> fanim_count then begin + fanim_count:= avalue; + updateanim(); + end; +end; + +procedure tcustomicon.setanim_enabled(const avalue: boolean); +begin + if avalue <> fanim_enabled then begin + fanim_enabled:= avalue; + updateanim(); + end; +end; + +procedure tcustomicon.setanim_options(const avalue: animationoptionsty); +begin + if avalue <> fanim_options then begin + fanim_options:= avalue; + updateanim(); + end; +end; + +procedure tcustomicon.animtick(const sender: tobject); +begin + inc(fcurrentanimoffset); + if fcurrentanimoffset >= fanim_count then begin + if ano_singleshot in fanim_options then begin + dec(fcurrentanimoffset); + if ftimer <> nil then begin + ftimer.enabled:= false; + end; + end + else begin + fcurrentanimoffset:= 0; + end; + end; + invalidate(); +end; + +procedure tcustomicon.resetanim(); +begin + fcurrentanimoffset:= -1; + animtick(nil); +end; + +procedure tcustomicon.setcurrentanimoffset(const avalue: int32); +begin + fcurrentanimoffset:= avalue; + invalidate(); +end; + +procedure tcustomicon.updateanim; +begin + if not (csloading in componentstate) then begin + if (fanim_intervalus > 0) and (fanim_count > 1) and + (not (csdesigning in componentstate) or + (ano_designactive in fanim_options)) then begin + if fanim_enabled then begin + if ftimer = nil then begin + resetanim(); + ftimer:= tsimpletimer.create(fanim_intervalus,@animtick,false); + end + else begin + ftimer.interval:= fanim_intervalus; + end; + if ano_singleshot in fanim_options then begin + resetanim(); + end; + ftimer.enabled:= true; + end + else begin + if ftimer <> nil then begin + ftimer.enabled:= false; + end; + end; + end + else begin + freeandnil(ftimer); + end; + end +end; + +procedure tcustomicon.loaded(); +begin + inherited; + updateanim(); +end; + +procedure tcustomicon.animrestart(); +begin + updateanim(); + resetanim(); +end; + +{ tgroupboxframe } + +constructor tgroupboxframe.create(const aintf: icaptionframe); +begin + inherited; + fi.levelo:= -1; + fi.leveli:= 1; + fi.innerframe.left:= 2; + fi.innerframe.top:= 2; + fi.innerframe.right:= 2; + fi.innerframe.bottom:= 2; + fcaptiondist:= 0; + fcaptionoffset:= 4; + include(foptions,cfo_captionframecentered); +end; + +{ tcustomscalingwidget } + +constructor tcustomscalingwidget.create(aowner: tcomponent); +begin + ftaborderoverride:= ttaborderoverride.create(self); + inherited; + foptionsscale:= defaultoptionsscale; +end; + +destructor tcustomscalingwidget.destroy(); +begin + inherited; + ftaborderoverride.free(); +end; + +procedure tcustomscalingwidget.dolayout(const sender: twidget); +begin + if canevent(tmethod(fonlayout)) then begin + fonlayout(self); + end + else begin + inherited; + end; +end; + +procedure tcustomscalingwidget.dofontheightdelta(var delta: integer); +begin + if canevent(tmethod(fonfontheightdelta)) then begin + fonfontheightdelta(self,delta); + end; + inherited; +end; + +procedure tcustomscalingwidget.setoptionsscale(const avalue: optionsscalety); +begin + if foptionsscale <> avalue then begin + foptionsscale:= avalue; + updateoptionsscale; + end; +end; + +procedure tcustomscalingwidget.updateoptionsscale(); +var + size1,size2: sizety; + rect1: rectty; + bo1: boolean; + box,boy: boolean; +begin + if foptionsscale * [osc_expandx,osc_expandy, + osc_shrinkx,osc_shrinky, + osc_invisishrinkx,osc_invisishrinky] <> [] then begin + if (componentstate * [csloading,csdestroying] = []) then begin + if fscaling <> 0 then begin + include(fwidgetstate1,ws1_scaled); + end + else begin + inc(fscaling); + try + exclude(fwidgetstate1,ws1_scaled); + size1:= calcminscrollsize; + bo1:= not isvisible; + size2:= paintsize; + box:= false; + boy:= false; + if (osc_invisishrinkx in foptionsscale) then begin + if bo1 then begin + if fsizebefore.cx = 0 then begin + fsizebefore.cx:= size2.cx; + end; + size1.cx:= paintsize.cx-bounds_cx; + end + else begin + if fsizebefore.cx <> 0 then begin + if foptionsscale * [osc_shrinkx,osc_expandx] <> + [osc_shrinkx,osc_expandx] then begin + size1.cx:= fsizebefore.cx; + end; + fsizebefore.cx:= 0; + box:= true; + end; + end; + end; + if (osc_invisishrinky in foptionsscale) then begin + if bo1 then begin + if fsizebefore.cy = 0 then begin + fsizebefore.cy:= size2.cy; + end; + size1.cy:= paintsize.cy-bounds_cy; + end + else begin + if fsizebefore.cy <> 0 then begin + if foptionsscale * [osc_shrinky,osc_expandy] <> + [osc_shrinky,osc_expandy] then begin + size1.cy:= fsizebefore.cy; + end; + fsizebefore.cy:= 0; + boy:= true; + end; + end; + end; + rect1.cx:= size1.cx - size2.cx; + rect1.cy:= size1.cy - size2.cy; + if not (bo1 and (osc_invisishrinkx in foptionsscale)) then begin + if not (osc_expandx in foptionsscale) and not box then begin + if rect1.cx > 0 then begin + rect1.cx:= 0; + end; + end; + if not (osc_shrinkx in foptionsscale) then begin + if rect1.cx < 0 then begin + rect1.cx:= 0; + end; + end; + end; + if not (bo1 and (osc_invisishrinky in foptionsscale)) then begin + if not (osc_expandy in foptionsscale) and not boy then begin + if rect1.cy > 0 then begin + rect1.cy:= 0; + end; + end; + if not (osc_shrinky in foptionsscale) then begin + if rect1.cy < 0 then begin + rect1.cy:= 0; + end; + end; + end; + rect1.pos:= fwidgetrect.pos; + if fanchors*[an_right,an_left] = [an_right] then begin + dec(rect1.x,rect1.cx); + end; + if fanchors*[an_bottom,an_top] = [an_bottom] then begin + dec(rect1.y,rect1.cy); + end; + addsize1(rect1.size,fwidgetrect.size); + internalsetwidgetrect(rect1,false); + if bo1 then begin + parentwidgetregionchanged(self); + end; + finally + dec(fscaling) + end; + end; + end; + end; +end; + +function tcustomscalingwidget.calcminshrinksize(): sizety; +var + size1: sizety; + box,boy: boolean; +begin + result:= inherited calcminshrinksize; + box:= (fanchors * [an_left,an_right] = [an_left,an_right]) and + (osc_expandshrinkx in foptionsscale) or + (osc_expandx in foptionsscale); + boy:= (fanchors * [an_top,an_bottom] = [an_top,an_bottom]) and + (osc_expandshrinky in foptionsscale) or + (osc_expandy in foptionsscale); + if box or boy then begin + size1:= minscrollsize; + addsize1(size1,framedim); + if box and (result.cx < size1.cx) then begin + result.cx:= size1.cx; + end; + if boy and (result.cy < size1.cy) then begin + result.cy:= size1.cy; + end; + end; +end; + +function tcustomscalingwidget.nexttaborderoverride(const sender: twidget; + const down: boolean): twidget; +begin + result:= ftaborderoverride.nexttaborder(sender,down); + if result = nil then begin + result:= inherited nexttaborderoverride(sender,down); + end; +end; + +procedure tcustomscalingwidget.beginscaling; +begin + if fscaling = 0 then begin + exclude(fwidgetstate1,ws1_scaled); + end; + inc(fscaling); +end; + +procedure tcustomscalingwidget.endscaling; +begin + dec(fscaling); + if (fscaling = 0) and (ws1_scaled in fwidgetstate1) then begin + updateoptionsscale; + end; +end; + +procedure tcustomscalingwidget.widgetregionchanged(const sender: twidget); +begin + inherited; + if not (ws_loadlock in fwidgetstate) then begin + updateoptionsscale; + end; +end; + +procedure tcustomscalingwidget.clientrectchanged; +begin + inherited; + updateoptionsscale; +end; + +procedure tcustomscalingwidget.poschanged; +begin + inherited; + if canevent(tmethod(fonmove)) then begin + fonmove(self); + end; +end; + +procedure tcustomscalingwidget.sizechanged; +begin + inherited; + if canevent(tmethod(fonresize)) then begin + fonresize(self); + end; +end; + +procedure tcustomscalingwidget.visiblepropchanged; +begin + inherited; + if foptionsscale * [osc_invisishrinkx,osc_invisishrinky] <> [] then begin + updateoptionsscale; + end; +end; + +procedure tcustomscalingwidget.writestate(writer: twriter); +begin + if (fframe <> nil) and (fframe is tcustomscrollboxframe) then begin + tcustomscrollboxframe(fframe).showrect(nullrect,false); + end; + inherited; +end; + +procedure tcustomscalingwidget.readonchildscaled(reader: treader); +begin + onlayout:= notifyeventty(readmethod(reader)); +end; + +procedure tcustomscalingwidget.settaborderoverride( + const avalue: ttaborderoverride); +begin + ftaborderoverride.assign(avalue); +end; + +procedure tcustomscalingwidget.readstate(reader: treader); +begin + inherited; + ttaborderoverride1(ftaborderoverride).endread(reader); +end; + +procedure tcustomscalingwidget.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('onchildscaled', + {$ifdef FPC}@{$endif}readonchildscaled,nil,false); +end; + +procedure tcustomscalingwidget.loaded; +begin + inherited; + if canevent(tmethod(fonlayout)) then begin + postchildscaled; + end; +end; + +{ tgroupbox } + +constructor tgroupbox.create(aowner: tcomponent); +begin + inherited; + optionswidget:= defaultgroupboxoptionswidget; +end; + +procedure tgroupbox.initnewcomponent(const ascale: real); +begin + inherited; + internalcreateframe; + fframe.scale(ascale); +end; + +procedure tgroupbox.internalcreateframe; +begin + tgroupboxframe.create(iscrollframe(self)); +end; + +procedure tgroupbox.dofocuschanged(const oldwidget: twidget; + const newwidget: twidget); +begin + inherited; + if canevent(tmethod(fonfocusedwidgetchanged)) and + (checkdescendent(oldwidget) or checkdescendent(newwidget)) then begin + fonfocusedwidgetchanged(oldwidget,newwidget); + end; +end; + +class function tgroupbox.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_groupbox; +end; + +{ tscrollbox } + +constructor tscrollbox.create(aowner: tcomponent); +begin + inherited; + include(fwidgetstate1,ws1_designactive); + foptionswidget:= defaultoptionswidgetmousewheel; + foptionsscale:= defaultscrollboxoptionsscale; + internalcreateframe; +end; + +procedure tscrollbox.internalcreateframe; +begin + tscrollboxframe.create(iscrollframe(self),self); +end; + +function tscrollbox.getframe: tscrollboxframe; +begin + result:= tscrollboxframe(inherited getframe); +end; + +procedure tscrollbox.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info .eventstate) then begin + tscrollboxframe(fframe).mouseevent(info); + end; +end; + +procedure tscrollbox.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + frame.childmouseevent(sender,info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tscrollbox.domousewheelevent(var info: mousewheeleventinfoty); +begin + tscrollboxframe(fframe).domousewheelevent(info,false); + inherited; +end; + +procedure tscrollbox.setframe(const value: tscrollboxframe); +begin + inherited setframe(value); +end; + +procedure tscrollbox.widgetregionchanged(const sender: twidget); +begin + inherited; + if not (ws_loadlock in fwidgetstate) and not (csdestroying in componentstate) then begin + tscrollboxframe(fframe).updateclientrect; + end; +end; + +procedure tscrollbox.doscroll(const dist: pointty); +begin + inherited; + if canevent(tmethod(fonscroll)) then begin + fonscroll(self,dist); + end; +end; + +procedure tscrollbox.doscrolled(const dist: pointty); +begin + inherited; + if canevent(tmethod(fonscrolled)) then begin + fonscrolled(self,dist); + end; +end; + +procedure tscrollbox.clampinview(const arect: rectty; const bottomright: boolean); +begin + frame.showrect(removerect(arect,clientpos),bottomright); +// frame.showrect(removerect(arect,clientwidgetpos)); +// frame.showrect(arect); +end; +{ +procedure tscrollbox.setclientpos(const avalue: pointty); +begin + tscrollboxframe(fframe).setclientpos(avalue); +end; +} +{ tcustomstepbox } + +constructor tcustomstepbox.create(aowner: tcomponent); +begin + inherited; + internalcreateframe; + if fdragcontroller = nil then begin + fdragcontroller:= tdragcontroller.create(idragcontroller(self)); + end; + optionswidget:= defaultoptionswidgetnofocus; +end; + +destructor tcustomstepbox.destroy; +begin + inherited; + fdragcontroller.Free; +end; + +procedure tcustomstepbox.internalcreateframe; +begin + tstepboxframe.create(iscrollframe(self),istepbar(self)); +end; + +procedure tcustomstepbox.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) then begin + fdragcontroller.clientmouseevent(info); + end; +end; + +procedure tcustomstepbox.mouseevent(var info: mouseeventinfoty); +begin + tstepboxframe(fframe).mouseevent(info); + inherited; +end; + +function tcustomstepbox.getframe: tstepboxframe; +begin + result:= tstepboxframe(inherited getframe); +end; + +procedure tcustomstepbox.setframe(const value: tstepboxframe); +begin + inherited setframe(value); +end; + +procedure tcustomstepbox.widgetregionchanged(const sender: twidget); +begin + inherited; + tscrollboxframe(fframe).updateclientrect; +end; + +function tcustomstepbox.dostep(const event: stepkindty; + const adelta: real; ashiftstate: shiftstatesty): boolean; +begin + result:= false; + if canevent(tmethod(fonstep)) then begin + result:= true; + fonstep(self,event,result); + end; +end; + +procedure tcustomstepbox.mousewheelevent(var info: mousewheeleventinfoty); +begin + frame.domousewheelevent(info); + inherited; +end; + +{ tpaintbox } +{ +procedure tpaintbox.dobeforepaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; + if canevent(tmethod(fonbeforepaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonbeforepaint(self,canvas); + canvas.remove(pt1); + end; +end; + +procedure tpaintbox.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaintbackground)) then begin + fonpaintbackground(self,canvas); + end; +end; + +procedure tpaintbox.doonpaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaint)) then begin + fonpaint(self,canvas); + end; +end; + +procedure tpaintbox.doafterpaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; + if canevent(tmethod(fonafterpaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonafterpaint(self,canvas); + canvas.remove(pt1); + end; +end; +} +end. + diff --git a/mseide-msegui/lib/common/widgets/msesizingform.pas b/mseide-msegui/lib/common/widgets/msesizingform.pas new file mode 100644 index 0000000..2e040d5 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msesizingform.pas @@ -0,0 +1,219 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesizingform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseforms,mseclasses,mseobjectpicker,msegui,mseguiglob,msepointer,msetypes, + msegraphics,msegraphutils; + +type + tsizingform = class(tmseform,iobjectpicker) + private + foptionssizing: optionssizingty; + fobjectpicker: tobjectpicker; + procedure setoptionssizing(const avalue: optionssizingty); + protected + fpickedges: optionssizingty; + fpickedgesrect: rectty; + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure mousepreview(const sender: twidget; + var info: mouseeventinfoty); override; + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var ashape: cursorshapety): boolean; + //true if found + procedure getpickobjects(const sender: tobjectpicker; + var aobjects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const acanvas: tcanvas); + public + destructor destroy(); override; + published + property optionssizing: optionssizingty read foptionssizing + write setoptionssizing default []; + end; + + sizingformclassty = class of tsizingform; + +function createsizingform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +implementation +uses + sysutils,mseevent; +type + tmsecomponent1 = class(tmsecomponent); + +function createsizingform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +begin + result:= sizingformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +{ tsizingform } + +destructor tsizingform.destroy(); +begin + fobjectpicker.free; + inherited; +end; + +class function tsizingform.getmoduleclassname: string; +begin + result:= 'tsizingform'; +end; + +class function tsizingform.hasresource: boolean; +begin + result:= self <> tsizingform; +end; + +procedure tsizingform.setoptionssizing(const avalue: optionssizingty); +begin + foptionssizing:= avalue; + if avalue = [] then begin + freeandnil(fobjectpicker); + end + else begin + if fobjectpicker = nil then begin + fobjectpicker:= tobjectpicker.create(iobjectpicker(self),org_widget); + fobjectpicker.thumbtrack:= true; + end; + end; +end; + +procedure tsizingform.mousepreview(const sender: twidget; + var info: mouseeventinfoty); +begin + if (fobjectpicker <> nil) then begin + translatewidgetpoint1(info.pos,sender,self); + fobjectpicker.mouseevent(info); + translatewidgetpoint1(info.pos,self,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; + end + else begin + inherited; + end; +end; + +const + shapes: array[0..15] of cursorshapety = ( + cr_default, // , , , + cr_sizehor, //osi_left, , , + cr_sizever, // ,osi_top, , + cr_topleftcorner, //osi_left,osi_top, , + cr_sizehor, // , ,osi_right, + cr_default, //osi_left, ,osi_right, + cr_toprightcorner, // ,osi_top,osi_right, + cr_default, //osi_left,osi_top,osi_right, + cr_sizever, // , , ,osi_bottom + cr_bottomleftcorner, //osi_left, , ,osi_bottom + cr_default, // ,osi_top, ,osi_bottom + cr_default, //osi_left,osi_top, ,osi_bottom + cr_bottomrightcorner, // , ,osi_right,osi_bottom + cr_default, //osi_left, ,osi_right,osi_bottom + cr_default, // ,osi_top,osi_right,osi_bottom + cr_default //osi_left,osi_top,osi_right,osi_bottom + ); + +function tsizingform.getcursorshape(const sender: tobjectpicker; + var ashape: cursorshapety): boolean; +const + sitol = 2*sizingtol; +var + pt1: pointty; +begin + result:= false; + fpickedges:= []; + pt1:= sender.pickpos; + if (sender.shiftstate * keyshiftstatesmask = []) and + pointinrect(pt1,mr(nullpoint,size)) then begin + if pt1.x < sitol then begin + include(fpickedges,osi_left); + end; + if pt1.y < sitol then begin + include(fpickedges,osi_top); + end; + if pt1.x >= fwidgetrect.cx-sitol then begin + include(fpickedges,osi_right); + end; + if pt1.y >= fwidgetrect.cy-sitol then begin + include(fpickedges,osi_bottom); + end; + fpickedges:= fpickedges * foptionssizing; + result:= fpickedges <> []; + if result then begin + ashape:= shapes[int32(fpickedges)]; + end; + end; +end; + +procedure tsizingform.getpickobjects(const sender: tobjectpicker; + var aobjects: integerarty); +begin + if fpickedges <> [] then begin + setlength(aobjects,1); + end; +end; + +procedure tsizingform.beginpickmove(const sender: tobjectpicker); +begin + fpickedgesrect:= fwidgetrect; + //dummy +end; + +procedure tsizingform.pickthumbtrack(const sender: tobjectpicker); +var + rect1: rectty; +begin + rect1:= fpickedgesrect; + if osi_left in fpickedges then begin + rect1.x:= rect1.x + sender.pickoffset.x; + rect1.cx:= rect1.cx - sender.pickoffset.x; + end; + if osi_top in fpickedges then begin + rect1.y:= rect1.y + sender.pickoffset.y; + rect1.cy:= rect1.cy - sender.pickoffset.y; + end; + if osi_right in fpickedges then begin + rect1.cx:= rect1.cx + sender.pickoffset.x; + end; + if osi_top in fpickedges then begin + rect1.cy:= rect1.cy + sender.pickoffset.y; + end; + widgetrect:= rect1; +end; + +procedure tsizingform.endpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tsizingform.cancelpickmove(const sender: tobjectpicker); +begin + widgetrect:= fpickedgesrect; +end; + +procedure tsizingform.paintxorpic(const sender: tobjectpicker; + const acanvas: tcanvas); +begin + //dummy +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msesplitter.pas b/mseide-msegui/lib/common/widgets/msesplitter.pas new file mode 100644 index 0000000..77bb401 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msesplitter.pas @@ -0,0 +1,2602 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msesplitter; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msegui,msewidgets,mseobjectpicker,classes,mclasses,msegraphutils, + msepointer,msetypes, + msestrings,msegraphics,mseevent,msestat,msestatfile,msestockobjects,mseclasses, + msesimplewidgets,mseguiglob,msemenus; +type + + splitteroptionty = (spo_hmove,spo_hprop,spo_hsizeprop, + spo_vmove,spo_vprop,spo_vsizeprop, + spo_dockleft,spo_docktop,spo_dockright,spo_dockbottom, + spo_hshrinkzero,spo_vshrinkzero, + spo_hrefstart,spo_vrefstart, + spo_thumbtrack); + splitteroptionsty = set of splitteroptionty; + +const + docksplitteroptions = [spo_dockleft,spo_docktop,spo_dockright,spo_dockbottom]; + defaultsplitteroptions = docksplitteroptions; + defaultsplittercolor = cl_light; + defaultsplittercolorgrip = cl_shadow; + defaultsplittergrip = stb_dens25; + updatepropeventtag = 0; + retrypropeventtag = 1; + +type + splitterstatety = (sps_propnotified); + splitterstatesty = set of splitterstatety; + + texpandingwidget = class(tscalingwidget) + public + constructor create(aowner: tcomponent); override; + published + property optionswidget default defaultgroupboxoptionswidget; + end; + + tcustomsplitter = class(tscalingwidget,iobjectpicker,istatfile) + private + fobjectpicker: tobjectpicker; + foptions: splitteroptionsty; + flinktop: twidget; + flinkleft: twidget; + flinkright: twidget; + flinkbottom: twidget; + fhprop,fvprop: real; + fhsizeprop,fvsizeprop: real; + fstatfile: tstatfile; + fstatvarname: msestring; + fcolorgrip: colorty; + fgrip: stockbitmapty; + fonupdatelayout: notifyeventty; + fupdating: integer; + fpropsetting: integer; +// fnotified: integer; + fregionchangedcount: integer; + fregionchangedmark: integer; + frefrect: rectty; + fshrinkpriority: integer; + fpropoffsetrecursion: integer; + fstatpriority: integer; + fwidgetrectbefore: rectty; + fdist_left: integer; + fdist_top: integer; + fdist_right: integer; + fdist_bottom: integer; + procedure setstatfile(const avalue: tstatfile); + procedure setlinkbottom(const avalue: twidget); + procedure setlinkleft(const avalue: twidget); + procedure setlinkright(const avalue: twidget); + procedure setlinktop(const avalue: twidget); + procedure setclippedpickoffset(const aoffset: pointty); + procedure setpickoffset(const aoffset: pointty); + procedure setcolorgrip(const avalue: colorty); + procedure setgrip(const avalue: stockbitmapty); + procedure setoptions(const avalue: splitteroptionsty); + procedure setdist_left(const avalue: integer); + procedure setdist_top(const avalue: integer); + procedure setdist_right(const avalue: integer); + procedure setdist_bottom(const avalue: integer); + protected + fstate: splitterstatesty; + procedure postupdatepropevent; + function clippoint(const aoffset: pointty): pointty; + procedure calcoffset(const refsize: sizety; + out offset,clippedoffset: pointty; out newsize: sizety); + procedure setpropoffset(const aoffset: pointty; const asize: sizety); +// function getminshrinkpos: pointty; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure poschanged1; + procedure poschanged; override; + procedure sizechanged; override; + procedure parentclientrectchanged; override; + procedure doasyncevent(var atag: integer); override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure parentwidgetregionchanged(const sender: twidget); override; + function getshrinkpriority: integer; override; + procedure tryshrink(const aclientsize: sizety); override; + procedure loaded; override; + procedure updatedock; + procedure updatelinkedwidgets(const delta: pointty); + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + class function classskininfo: skininfoty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function actualcolor: colorty; override; + function actualopaquecolor: colorty; override; + + procedure move(const dist: pointty); + + property options: splitteroptionsty read foptions write setoptions + default defaultsplitteroptions; + property shrinkpriority: integer read getshrinkpriority + write fshrinkpriority default 0; + property linkleft: twidget read flinkleft write setlinkleft; + property linktop: twidget read flinktop write setlinktop; + property linkright: twidget read flinkright write setlinkright; + property linkbottom: twidget read flinkbottom write setlinkbottom; + + property dist_left: integer read fdist_left + write setdist_left default 0; + property dist_top: integer read fdist_top + write setdist_top default 0; + property dist_right: integer read fdist_right + write setdist_right default 0; + property dist_bottom: integer read fdist_bottom + write setdist_bottom default 0; + +// property color default defaultsplittercolor; + property grip: stockbitmapty read fgrip write setgrip default stb_default; + property colorgrip: colorty read fcolorgrip write setcolorgrip + default cl_default; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property onupdatelayout: notifyeventty read fonupdatelayout + write fonupdatelayout; + published + property optionswidget default defaultoptionswidgetnofocus; + end; + + tsplitter = class(tcustomsplitter) + published +// property optionswidget; + property options; + property shrinkpriority; + property linkleft; + property linktop; + property linkright; + property linkbottom; + property dist_left; + property dist_top; + property dist_right; + property dist_bottom; + + property color; + property grip; + property colorgrip; + property statfile; + property statvarname; + property statpriority; + property onupdatelayout; + end; + + spaceroptionty = (spao_glueright,spao_gluebottom); + spaceroptionsty = set of spaceroptionty; + + tcustomspacer = class(tscalingwidget) + private + flinkleft: twidget; + flinktop: twidget; + flinkright: twidget; + flinkbottom: twidget; + fupdating: integer; + fdist_left: integer; + fdist_top: integer; + fdist_right: integer; + fdist_bottom: integer; + foptions: spaceroptionsty; + procedure setlinkleft(const avalue: twidget); + procedure setlinktop(const avalue: twidget); + procedure setlinkright(const avalue: twidget); + procedure setlinkbottom(const avalue: twidget); + procedure updatespace; + procedure setdist_left(const avalue: integer); + procedure setdist_top(const avalue: integer); + procedure setdist_right(const avalue: integer); + procedure setdist_bottom(const avalue: integer); + protected + procedure loaded; override; + procedure parentwidgetregionchanged(const sender: twidget); override; + public + constructor create(aowner: tcomponent); override; + property linkleft: twidget read flinkleft write setlinkleft; + property linktop: twidget read flinktop write setlinktop; + property linkright: twidget read flinkright write setlinkright; + property linkbottom: twidget read flinkbottom write setlinkbottom; + property dist_left: integer read fdist_left + write setdist_left default 0; + property dist_top: integer read fdist_top + write setdist_top default 0; + property dist_right: integer read fdist_right + write setdist_right default 0; + property dist_bottom: integer read fdist_bottom + write setdist_bottom default 0; + property options: spaceroptionsty read foptions write foptions default []; + property optionswidget default defaultoptionswidgetnofocus; + published + property visible default false; + end; + + tspacer = class(tcustomspacer) + published + property linkleft; + property linktop; + property linkright; + property linkbottom; + property dist_left; + property dist_top; + property dist_right; + property dist_bottom; + property options; + property optionswidget; + end; + + layoutoptionty = (lao_alignx,lao_placex,lao_aligny,lao_placey, + lao_scaleleft,lao_scaletop, + lao_scalewidth,lao_scaleheight, + lao_scalefont,lao_scalechildfont, + lao_syncmaxautosize, + lao_synccaptiondistx,lao_synccaptiondisty, + lao_syncpaintwidth,lao_syncpaintheight); + layoutoptionsty = set of layoutoptionty; +const + defaultlayoutoptions = []; + +type + placeoptionty = (plo_noinvisible,plo_scalesize, + plo_scalefullref, //use whole innerclientrect as size reference + plo_endmargin,plo_propmargin, + plo_syncmaxautosize, + plo_synccaptiondistx,plo_synccaptiondisty, + plo_syncpaintwidth,plo_syncpaintheight); + placeoptionsty = set of placeoptionty; +const + deprecatedplaceoptions = [plo_syncmaxautosize, + plo_synccaptiondistx,plo_synccaptiondisty, + plo_syncpaintwidth,plo_syncpaintheight]; + invisibleplaceoptions = [ord(plo_syncmaxautosize), + ord(plo_synccaptiondistx),ord(plo_synccaptiondisty), + ord(plo_syncpaintwidth),ord(plo_syncpaintheight)]; +type + widgetlayoutinfoty = record + widget: twidget; + layoutplacingbefore: boolean; + pos: pointty; + size: sizety; + curminsize: sizety; + actpos: pointty; + actsize: sizety; + refsize: sizety; + scalesize: sizety; + actscalesize: sizety; + refscalesize: sizety; + reffontsize: sizety; + fontheight: integer; + actfontheight: integer; + fontxscale: real; + actfontxscale: real; + end; + pwidgetlayoutinfoty = ^widgetlayoutinfoty; + widgetlayoutinfoarty = array of widgetlayoutinfoty; + + layouterstatety = (las_propsizing,las_scalesizerefvalid, + las_scalesizerefset,las_widgetinfoloaded, + las_delayedupdatelayoutpending); + layouterstatesty = set of layouterstatety; + + tcustomlayouter = class; + layoutereventty = procedure(const sender: tcustomlayouter) of object; + + tcustomlayouter = class(tcustomspacer) + private + foptionslayout: layoutoptionsty; + flayoutupdating: integer; + falign_mode: widgetalignmodety; + falign_leader: twidget; + fplace_mindist: integer; + fplace_maxdist: integer; + falign_glue: widgetalignmodety; + fplace_mode: widgetalignmodety; + fplace_options: placeoptionsty; + fwidgetinfos: widgetlayoutinfoarty; + fstate: layouterstatesty; + fscalesizeref: sizety; + fscalesizeextension: sizety; + ffontsizeref: sizety; + ffontheightref: integer; + ffontxscaleref: real; + fonbeforelayout: layoutereventty; + fonafterlayout: layoutereventty; + procedure setoptionslayout(const avalue: layoutoptionsty); + procedure setalign_mode(const avalue: widgetalignmodety); + procedure setalign_leader(const avalue: twidget); + procedure setplace_mindist(const avalue: integer); + procedure setplace_maxdist(const avalue: integer); + procedure setalign_glue(const avalue: widgetalignmodety); + procedure setplace_mode(const avalue: widgetalignmodety); + procedure setplace_options(avalue: placeoptionsty); + protected + procedure scalebasechanged(const sender: twidget); override; + function scalesizeref: sizety; + function childrenleft: integer; + function childrentop: integer; + function childrenright: integer; + function childrenbottom: integer; + function childrenwidth: integer; + function childrenheight: integer; + function childrenminwidth: integer; + function childrenminheight: integer; + procedure scalesizerefchanged; + procedure updatescalesizeref; + procedure delayedupdatelayout(); + procedure checkwidgetinfo(); + procedure updatelayout; + procedure readstate(reader: treader); override; + procedure loaded; override; + procedure fontchanged; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure childclientrectchanged(const sender: twidget); override; + procedure childautosizechanged(const sender: twidget); override; + procedure clientrectchanged; override; + function calcminscrollsize: sizety; override; + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + function widgetinfoindex(const awidget: twidget): integer; + procedure updatewidgetinfo(var ainfo: widgetlayoutinfoty; + const awidget: twidget; const force: boolean = false); + procedure doasyncevent(var atag: integer); override; + public + constructor create(aowner: tcomponent); override; + property optionslayout: layoutoptionsty read foptionslayout write setoptionslayout + default defaultlayoutoptions; + property align_mode: widgetalignmodety read falign_mode write setalign_mode + default wam_center; + property align_leader: twidget read falign_leader write setalign_leader; + property align_glue: widgetalignmodety read falign_glue write setalign_glue + default wam_none; + property place_mindist: integer read fplace_mindist + write setplace_mindist default 0; + property place_maxdist: integer read fplace_maxdist write setplace_maxdist + default bigint; + property place_mode: widgetalignmodety read fplace_mode write setplace_mode + default wam_start; + property place_options: placeoptionsty read fplace_options + write setplace_options default []; + property onbeforelayout: layoutereventty read fonbeforelayout + write fonbeforelayout; + property onafterlayout: layoutereventty read fonafterlayout + write fonafterlayout; + published + property visible default true; + property optionswidget default defaultgroupboxoptionswidget; + end; + + tlayouter = class(tcustomlayouter) + published + property optionslayout; + property align_mode; + property align_leader; + property align_glue; + property place_mindist; + property place_maxdist; + property place_mode; + property place_options; + property onbeforelayout; + property onafterlayout; + + property linkleft; //tspacer + property linktop; + property linkright; + property linkbottom; + property dist_left; + property dist_top; + property dist_right; + property dist_bottom; + property options; + end; + +implementation +uses + msebits,math; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + tcustomframe1 = class(tcustomframe); + ttaborderoverride1 = class(ttaborderoverride); + +{$define useround} + +{ tcustomsplitter } + +constructor tcustomsplitter.create(aowner: tcomponent); +begin +// include(fwidgetstate1,ws1_tryshrink); + foptions:= defaultsplitteroptions; + fcolorgrip:= cl_default; + fgrip:= stb_default; + frefrect.x:= -bigint; + frefrect.y:= -bigint; + frefrect.cx:= -bigint; + frefrect.cy:= -bigint; + include(fwidgetstate1,ws1_framemouse); + inherited; +// color:= defaultsplittercolor; + optionswidget:= defaultoptionswidgetnofocus; + fobjectpicker:= tobjectpicker.create(iobjectpicker(self),org_widget); +end; + +destructor tcustomsplitter.destroy; +begin + fobjectpicker.Free; + inherited; +end; + +procedure tcustomsplitter.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) then begin + fobjectpicker.mouseevent(info); + end; +end; + +function tcustomsplitter.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; +begin + result:= canmouseinteract and + pointinrect(sender.pos,makerect(nullpoint,fwidgetrect.size)); + if result then begin + if spo_hmove in foptions then begin + if spo_vmove in foptions then begin + shape:= cr_sizeall; + end + else begin + shape:= cr_sizehor; + end; + end + else begin + if spo_vmove in foptions then begin + shape:= cr_sizever; + end + else begin + result:= false; + end; + end; + if result and (cursor <> cr_default) then begin + shape:= cursor; + end; + end; +end; + +procedure tcustomsplitter.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +begin + if (foptions * [spo_hmove,spo_vmove] <> []) and canmouseinteract then begin + setlength(objects,1); + end; +end; + +function tcustomsplitter.clippoint(const aoffset: pointty): pointty; +var + int1,i2: integer; + rect1,rect2: rectty; +begin + if fparentwidget <> nil then begin + rect1:= twidget1(fparentwidget).clientwidgetrect; + rect2:= twidget1(fparentwidget).innerwidgetrect; + if not (an_right in fanchors) then begin + rect1.cx:= rect2.x+rect2.cx-rect1.x; + end; + if not (an_bottom in fanchors) then begin + rect1.cy:= rect2.y+rect2.cy-rect1.y; + end; + result:= subpoint( + clipinrect( + makerect(addpoint(aoffset,fwidgetrect.pos),fwidgetrect.size), + rect1).pos,fwidgetrect.pos); + end + else begin + result:= aoffset; + end; + if [spo_hmove,spo_hprop] * foptions = [] then begin + result.x:= 0; + end; + if [spo_vmove,spo_vprop] * foptions = [] then begin + result.y:= 0; + end; + if flinkleft <> flinkright then begin + if (flinkleft <> nil) then begin + with twidget1(flinkleft) do begin + int1:= widgetminsize.cx; + i2:= minshrinksize.cx; + if i2 > int1 then begin + int1:= i2; + end; + if fwidgetrect.cx + result.x < int1 then begin + result.x:= int1 - fwidgetrect.cx; + end; + if bounds_cxmax > 0 then begin + if fwidgetrect.cx + result.x > bounds_cxmax then begin + result.x:= bounds_cxmax - fwidgetrect.cx; + end; + end; + end; + end; + if flinkright <> nil then begin + with twidget1(flinkright) do begin + int1:= widgetminsize.cx; + i2:= minshrinksize.cx; + if i2 > int1 then begin + int1:= i2; + end; + if fwidgetrect.cx - result.x < int1 then begin + result.x:= - (int1 - fwidgetrect.cx); + end; + if bounds_cxmax > 0 then begin + if fwidgetrect.cx - result.x > bounds_cxmax then begin + result.x:= - (bounds_cxmax - fwidgetrect.cx); + end; + end; + end; + end; + end; + if flinktop <> flinkbottom then begin + if (flinktop <> nil) then begin + with twidget1(flinktop) do begin + int1:= widgetminsize.cy; + i2:= minshrinksize.cy; + if i2 > int1 then begin + int1:= i2; + end; + if fwidgetrect.cy + result.y < int1 then begin + result.y:= int1 - fwidgetrect.cy; + end; + if bounds_cymax > 0 then begin + if fwidgetrect.cy + result.y > bounds_cymax then begin + result.y:= bounds_cymax - fwidgetrect.cy; + end; + end; + end; + end; + if flinkbottom <> nil then begin + with twidget1(flinkbottom) do begin + int1:= widgetminsize.cy; + i2:= minshrinksize.cy; + if i2 > int1 then begin + int1:= i2; + end; + if fwidgetrect.cy - result.y < int1 then begin + result.y:= - (int1 - fwidgetrect.cy); + end; + if bounds_cymax > 0 then begin + if fwidgetrect.cy - result.y > bounds_cymax then begin + result.y:= - (bounds_cymax - fwidgetrect.cy); + end; + end; + end; + end; + end; +end; + +procedure tcustomsplitter.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); +begin + if fparentwidget <> nil then begin + canvas.addcliprect(makerect(-fwidgetrect.x,-fwidgetrect.y, + twidget1(fparentwidget).fwidgetrect.cx, + twidget1(fparentwidget).fwidgetrect.cy)); + end; + canvas.drawxorframe(makerect(clippoint(sender.pickoffset),fwidgetrect.size),-4, + stockobjects.bitmaps[stb_dens25]); +end; + +class function tcustomsplitter.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_splitter; +end; + +procedure tcustomsplitter.updatelinkedwidgets(const delta: pointty); +var + rect1: rectty; +begin + inc(fupdating); + try + if flinkleft = flinkright then begin + if flinkright <> nil then begin + flinkright.bounds_x:= flinkright.bounds_x + delta.x; + end; + end + else begin + if flinkleft <> nil then begin + flinkleft.bounds_cx:= flinkleft.bounds_cx + delta.x; + end; + if flinkright <> nil then begin + rect1:= twidget1(flinkright).fwidgetrect; + rect1.x:= rect1.x + delta.x; + rect1.cx:= rect1.cx - delta.x; + flinkright.widgetrect:= rect1; + end; + end; + if flinktop = flinkbottom then begin + if flinkbottom <> nil then begin + flinkbottom.bounds_y:= flinkbottom.bounds_y + delta.y; + end; + end + else begin + if flinktop <> nil then begin + flinktop.bounds_cy:= flinktop.bounds_cy + delta.y; + end; + if flinkbottom <> nil then begin + rect1:= twidget1(flinkbottom).fwidgetrect; + rect1.y:= rect1.y + delta.y; + rect1.cy:= rect1.cy - delta.y; + flinkbottom.widgetrect:= rect1; + end; + end; + if canevent(tmethod(fonupdatelayout)) then begin + fonupdatelayout(self); + end; + finally + dec(fupdating); + end; +end; + +procedure tcustomsplitter.setclippedpickoffset(const aoffset: pointty); +begin + inc(fupdating); + try + self.pos:= addpoint(self.pos,aoffset); + finally + dec(fupdating); + end; + updatelinkedwidgets(aoffset); +end; + +procedure tcustomsplitter.setpickoffset(const aoffset: pointty); +begin + setclippedpickoffset(clippoint(aoffset)); +end; + +procedure tcustomsplitter.move(const dist: pointty); +begin + setpickoffset(dist); +end; + +procedure tcustomsplitter.endpickmove(const sender: tobjectpicker); +begin + setpickoffset(sender.pickoffset); +end; + +procedure tcustomsplitter.cancelpickmove(const sender: tobjectpicker); +begin + widgetrect:= fwidgetrectbefore; +end; + +procedure tcustomsplitter.beginpickmove(const sender: tobjectpicker); +begin + fwidgetrectbefore:= fwidgetrect; +end; + +procedure tcustomsplitter.pickthumbtrack(const sender: tobjectpicker); +begin + setpickoffset(sender.pickoffset); +end; + +procedure tcustomsplitter.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tcustomsplitter.dostatread(const reader: tstatreader); +var + po1,po2: pointty; +begin + if reader.canstate then begin + po1:= parentclientpos; + if spo_hmove in foptions then begin + po2.x:= reader.readinteger('x',po1.x); + end + else begin + po2.x:= po1.x; + end; + if spo_vmove in foptions then begin + po2.y:= reader.readinteger('y',po1.y); + end + else begin + po2.y:= po1.y; + end; + setclippedpickoffset(subpoint(po2,po1)); + if foptions * [spo_hmove,spo_hprop] = [spo_hmove,spo_hprop] then begin + fhprop:= reader.readreal('xprop',fhprop,0,1); + end; + if foptions * [spo_vmove,spo_vprop] = [spo_vmove,spo_vprop] then begin + fvprop:= reader.readreal('yprop',fvprop,0,1); + end; + end; +end; + +procedure tcustomsplitter.dostatwrite(const writer: tstatwriter); +var + po1: pointty; +begin + if writer.canstate then begin + po1:= parentclientpos; + writer.writeinteger('x',po1.x); + writer.writeinteger('y',po1.y); + writer.writereal('xprop',fhprop); + writer.writereal('yprop',fvprop); + end; +end; + +procedure tcustomsplitter.statreading; +begin +{ + if fparentwidget <> nil then begin + postupdatepropevent; + end; +} +end; + +procedure tcustomsplitter.statread; +begin + //dummy +end; + +function tcustomsplitter.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomsplitter.setlinkbottom(const avalue: twidget); +begin +// if flinkbottom <> nil then begin +// twidget1(flinkbottom).fminshrinkposoffset.y:= 0; +// end; + setlinkedvar(avalue,tmsecomponent(flinkbottom)); + updatedock; +end; + +procedure tcustomsplitter.setlinkleft(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinkleft)); + updatedock; +end; + +procedure tcustomsplitter.setlinkright(const avalue: twidget); +begin +// if flinkright <> nil then begin +// twidget1(flinkright).fminshrinkposoffset.x:= 0; +// end; + setlinkedvar(avalue,tmsecomponent(flinkright)); + updatedock; +end; + +procedure tcustomsplitter.setlinktop(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinktop)); + updatedock; +end; + +procedure tcustomsplitter.poschanged1; +var + int1,int2,int3: integer; +begin + int3:= 0; + if not (spo_hrefstart in foptions) then begin + int3:= bounds_cx; + end; + int2:= bounds_x + int3; + if frefrect.x <> int2 then begin + frefrect.x:= int2; + fhprop:= 0; + int1:= fparentwidget.clientsize.cx; + if (int1 > 0) then begin + fhprop:= (parentclientpos.x+int3) / + {$ifdef FPC} real({$endif}int1{$ifdef FPC}){$endif}; + end; + end; + int3:= 0; + if not (spo_vrefstart in foptions) then begin + int3:= bounds_cy; + end; + int2:= bounds_y + int3; + if frefrect.y <> int2 then begin + frefrect.y:= int2; + fvprop:= 0; + int1:= fparentwidget.clientsize.cy; + if (int1 > 0) then begin + fvprop:= (parentclientpos.y+int3) / + {$ifdef FPC} real({$endif}int1{$ifdef FPC}){$endif}; + end; + end; +end; + +procedure tcustomsplitter.poschanged; +begin + inherited; + if (fparentwidget <> nil) then begin + if not (csloading in componentstate) and (fpropsetting = 0) then begin + poschanged1; + end; + end; +end; + +procedure tcustomsplitter.sizechanged; +var + int1: integer; +begin + inherited; + if (fparentwidget <> nil) then begin + if not (csloading in componentstate) and (fpropsetting = 0) then begin + if frefrect.cx <> bounds_cx then begin + frefrect.cx:= bounds_cx; + fhsizeprop:= 0; + int1:= fparentwidget.clientsize.cx; + if (int1 > 0) then begin + fhsizeprop:= fwidgetrect.cx / {$ifdef FPC} real({$endif}int1{$ifdef FPC}){$endif}; + end; + end; + if frefrect.cy <> bounds_cy then begin + frefrect.cy:= bounds_cy; + fvsizeprop:= 0; + int1:= fparentwidget.clientsize.cy; + if (int1 > 0) then begin + fvsizeprop:= fwidgetrect.cy / {$ifdef FPC} real({$endif}int1{$ifdef FPC}){$endif}; + end; + end; + poschanged1; + end; + end; +end; + +procedure tcustomsplitter.calcoffset(const refsize: sizety; + out offset,clippedoffset: pointty; out newsize: sizety); +//var +// size1: sizety; +var + int1: integer; +begin +// size1:= fparentwidget.clientsize; + offset:= nullpoint; + newsize:= size; + if spo_hsizeprop in foptions then begin + newsize.cx:= {$ifdef useround}round{$else}floor{$endif}(refsize.cx * fhsizeprop); + if not(an_right in fanchors) xor (spo_hrefstart in foptions) then begin + offset.x:= bounds_cx - newsize.cx; + end; + end; + if spo_vsizeprop in foptions then begin + newsize.cy:= {$ifdef useround}round{$else}floor{$endif}(refsize.cy * fvsizeprop); + if not(an_bottom in fanchors) xor (spo_vrefstart in foptions) then begin + offset.y:= bounds_cy - newsize.cy; + end; + end; + if spo_hprop in foptions then begin + int1:= 0; + if not (spo_hrefstart in foptions) then begin + int1:= bounds_cx; + end; + offset.x:= offset.x + {$ifdef useround}round{$else}floor{$endif}(fhprop * refsize.cx) - parentclientpos.x - + int1; + end; + if (spo_vprop in foptions) then begin + int1:= 0; + if not (spo_vrefstart in foptions) then begin + int1:= bounds_cy; + end; + offset.y:= offset.y + {$ifdef useround}round{$else}floor{$endif}(fvprop * refsize.cy) - parentclientpos.y - + int1; + end; + clippedoffset:= clippoint(offset); +// pt2:= pt1; +end; + +procedure tcustomsplitter.setpropoffset(const aoffset: pointty; + const asize: sizety); +begin + inc(fpropsetting); + try + size:= asize; + setclippedpickoffset(aoffset); + frefrect:= fwidgetrect; + with frefrect do begin + if not(spo_hrefstart in foptions) then begin + x:= x + cx; + end; + if not(spo_vrefstart in foptions) then begin + y:= y + cy; + end; + end; + finally + dec(fpropsetting); + end; +end; + +function tcustomsplitter.actualcolor: colorty; +begin + if fcolor = cl_default then begin + result:= defaultsplittercolor; + end + else begin + result:= inherited actualcolor(); + end; +end; + +function tcustomsplitter.actualopaquecolor: colorty; +begin + if fcolor = cl_default then begin + result:= defaultsplittercolor; + end + else begin + result:= inherited actualopaquecolor(); + end; +end; + +procedure tcustomsplitter.doasyncevent(var atag: integer); +var + pt1,pt2: pointty; + size2: sizety; + +begin //doasyncevent + inherited; + case atag of + updatepropeventtag,retrypropeventtag: begin + if atag = updatepropeventtag then begin + exclude(fstate,sps_propnotified); + end; + try + if fparentwidget <> nil then begin + calcoffset(fparentwidget.clientsize,pt1,pt2,size2); + if (([spo_hmove,spo_hprop] * foptions <> []) and (pt1.x <> pt2.x) or + ([spo_vmove,spo_vprop] * foptions <> []) and (pt1.y <> pt2.y)) and + (fregionchangedmark <> fregionchangedcount) then begin + fregionchangedmark:= fregionchangedcount; + inc(fupdating); + asyncevent(retrypropeventtag,[peo_local]); + end + else begin + inc(fpropoffsetrecursion); + if fpropoffsetrecursion < 16 then begin + setpropoffset(pt2,size2); + if not(sps_propnotified in fstate) then begin + fpropoffsetrecursion:= 0; + end; + end + else begin + fpropoffsetrecursion:= 0; + end; + end; + end; + finally + if atag = retrypropeventtag then begin + dec(fupdating); + if fupdating = 0 then begin + updatedock; + end; + end; + end; + end; + end; +end; + +procedure tcustomsplitter.tryshrink(const aclientsize: sizety); +var + pt1,pt2: pointty; + size1,size2: sizety; +begin + if fupdating = 0 then begin + if spo_hshrinkzero in foptions then begin + size1.cx:= 0; + end + else begin + size1:= fparentwidget.clientsize; + if size1.cx > aclientsize.cx then begin + size1.cx:= aclientsize.cx; + end; + end; + if spo_vshrinkzero in foptions then begin + size1.cy:= 0; + end + else begin + if size1.cy > aclientsize.cy then begin + size1.cy:= aclientsize.cy; + end; + end; + calcoffset(size1,pt1,pt2,size2); + try + setpropoffset(pt2,size2); + finally + updatedock; + end; + end; +end; + +procedure tcustomsplitter.postupdatepropevent; +begin + if not (sps_propnotified in fstate) then begin + include(fstate,sps_propnotified); + asyncevent(updatepropeventtag,[peo_local,peo_first]); + end; +end; + +procedure tcustomsplitter.parentclientrectchanged; +begin + inherited; + if (componentstate * [csloading{,csdesigning}] = []) and canmouseinteract and + (fparentwidget <> nil) then begin + postupdatepropevent; + end; +end; + +procedure tcustomsplitter.setcolorgrip(const avalue: colorty); +begin + if fcolorgrip <> avalue then begin + fcolorgrip:= avalue; + invalidate; + end; +end; + +procedure tcustomsplitter.setgrip(const avalue: stockbitmapty); +begin + if fgrip <> avalue then begin + fgrip:= avalue; + invalidate; + end; +end; + +procedure tcustomsplitter.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + if fgrip <> stb_none then begin + with acanvas do begin + if fgrip = stb_default then begin + brush:= stockobjects.bitmaps[defaultsplittergrip]; + end + else begin + brush:= stockobjects.bitmaps[fgrip]; + end; + if fcolorgrip = cl_default then begin + color:= defaultsplittercolorgrip; + end + else begin + color:= fcolorgrip; + end; + fillrect(innerclientrect,cl_brushcanvas); + end; + end; +end; + +procedure tcustomsplitter.parentwidgetregionchanged(const sender: twidget); +begin + inc(fregionchangedcount); + inherited; + if (sender <> nil) and ((sender = flinkleft) or (sender = flinktop) or + (sender = flinkright) or (sender = flinkbottom) or + (sender = self)) then begin + updatedock; + end; +end; + +procedure tcustomsplitter.loaded; +begin + inherited; + updatedock; +end; + +procedure tcustomsplitter.updatedock; +var + pt1: pointty; + rect1: rectty; +begin + if (componentstate * [csloading,csdestroying] = []) and + (foptions * docksplitteroptions <> []) and + (fparentwidget <> nil) and (fupdating = 0) then begin + inc(fupdating); + pt1:= addpoint(pos,pointty(size)); + try + if flinkright <> nil then begin + with twidget1(flinkright) do begin +// fminshrinkposoffset.x:= - fwidgetrect.x; + end; + end; + if flinkbottom <> nil then begin + with twidget1(flinkbottom) do begin +// fminshrinkposoffset.y:= - fwidgetrect.y; + end; + end; + if (flinkleft = flinkright) and + (foptions * [spo_dockleft,spo_dockright] = + [spo_dockleft,spo_dockright])then begin + if flinkleft <> nil then begin + flinkleft.widgetrect:= makerect(bounds_x+fdist_left,flinkleft.bounds_y, + bounds_cx-fdist_left-fdist_right,flinkleft.bounds_cy); + end; + end + else begin + if (flinkleft <> nil) and (spo_dockleft in foptions) then begin + flinkleft.bounds_cx:= bounds_x - flinkleft.bounds_x - fdist_left; + end; + if (flinkright <> nil) and (spo_dockright in foptions) then begin + rect1:= flinkright.widgetrect; + rect1.cx:= rect1.cx + (rect1.x - pt1.x) - fdist_right; + rect1.pos.x:= pt1.x + fdist_right; + flinkright.widgetrect:= rect1; + end; + end; + if (flinktop = flinkbottom) and + (foptions * [spo_docktop,spo_dockbottom] = + [spo_docktop,spo_dockbottom]) then begin + if flinktop <> nil then begin + flinktop.widgetrect:= makerect(flinktop.bounds_x,bounds_y+fdist_top, + flinktop.bounds_cx,bounds_cy- + fdist_top-fdist_bottom); + end; + end + else begin + if (flinktop <> nil) and (spo_docktop in foptions) then begin + flinktop.bounds_cy:= bounds_y - flinktop.bounds_y - fdist_top; + end; + if (flinkbottom <> nil) and (spo_dockbottom in foptions) then begin + rect1:= flinkbottom.widgetrect; + rect1.cy:= rect1.cy + (rect1.y - pt1.y) - fdist_bottom; + rect1.pos.y:= pt1.y + fdist_bottom; + flinkbottom.widgetrect:= rect1; + end; + end; + finally + dec(fupdating); + end; + end; +end; +{ +function tcustomsplitter.getminshrinkpos: pointty; +var + int1: integer; +begin + result:= fwidgetrect.pos; + if flinkleft <> nil then begin + result.x:= result.x - flinkleft.bounds_cx + flinkleft.bounds_cxmin; + end + else begin + if spo_hprop in foptions then begin + result.x:= 0; + end; + end; + if flinktop <> nil then begin + result.y:= result.y - flinktop.bounds_cy + flinktop.bounds_cymin; + end + else begin + if spo_vprop in foptions then begin + result.y:= 0; + end; + end; +end; +} +procedure tcustomsplitter.setoptions(const avalue: splitteroptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + if avalue * [spo_hprop,spo_vprop] <> [] then begin + include(fwidgetstate1,ws1_tryshrink); + end + else begin + exclude(fwidgetstate1,ws1_tryshrink); + end; + if spo_thumbtrack in avalue then begin + fobjectpicker.options:= fobjectpicker.options + [opo_thumbtrack]; + end + else begin + fobjectpicker.options:= fobjectpicker.options - [opo_thumbtrack]; + end; + updatedock; + end; +end; + +procedure tcustomsplitter.setdist_left(const avalue: integer); +begin + if fdist_left <> avalue then begin + fdist_left:= avalue; + updatedock(); + end; +end; + +procedure tcustomsplitter.setdist_top(const avalue: integer); +begin + if fdist_top <> avalue then begin + fdist_top:= avalue; + updatedock(); + end; +end; + +procedure tcustomsplitter.setdist_right(const avalue: integer); +begin + if fdist_right <> avalue then begin + fdist_right:= avalue; + updatedock(); + end; +end; + +procedure tcustomsplitter.setdist_bottom(const avalue: integer); +begin + if fdist_bottom <> avalue then begin + fdist_bottom:= avalue; + updatedock(); + end; +end; + +function tcustomsplitter.getshrinkpriority: integer; +begin + result:= fshrinkpriority; +end; + +function tcustomsplitter.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tcustomspacer } + +constructor tcustomspacer.create(aowner: tcomponent); +begin + inherited; + foptionswidget:= defaultoptionswidgetnofocus; + fwidgetstate:= fwidgetstate - (defaultwidgetstates-defaultwidgetstatesinvisible); +end; + +procedure tcustomspacer.setlinkleft(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinkleft)); + updatespace; +end; + +procedure tcustomspacer.setlinktop(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinktop)); + updatespace; +end; + +procedure tcustomspacer.setlinkright(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinkright)); + updatespace; +end; + +procedure tcustomspacer.setlinkbottom(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinkbottom)); + updatespace; +end; + +procedure tcustomspacer.setdist_left(const avalue: integer); +begin + fdist_left:= avalue; + updatespace; +end; + +procedure tcustomspacer.setdist_top(const avalue: integer); +begin + fdist_top:= avalue; + updatespace; +end; + +procedure tcustomspacer.setdist_right(const avalue: integer); +begin + fdist_right:= avalue; + updatespace; +end; + +procedure tcustomspacer.setdist_bottom(const avalue: integer); +begin + fdist_bottom:= avalue; + updatespace; +end; + +function alive(const acomponent: tcomponent): boolean; +begin + result:= (acomponent <> nil) and + not (csdestroying in acomponent.componentstate); +end; + +procedure tcustomspacer.updatespace; +var + rect1: rectty; + pt1: pointty; +begin + if (componentstate * [csloading,csdestroying] = []) and + (fparentwidget <> nil) and (fupdating = 0) then begin + inc(fupdating); + try + rect1:= fwidgetrect; + if spao_glueright in foptions then begin + if alive(flinkright) then begin + if an_left in fanchors then begin + rect1.cx:= flinkright.bounds_x - bounds_x - fdist_right; + end + else begin + rect1.x:= flinkright.bounds_x - bounds_cx - fdist_right; + end; + end; + end + else begin + if alive(flinkleft) then begin + rect1.x:= flinkleft.bounds_x + flinkleft.bounds_cx + fdist_left; + end; + end; + if spao_gluebottom in foptions then begin + if alive(flinkbottom) then begin + if an_top in fanchors then begin + rect1.cy:= flinkbottom.bounds_y - bounds_y - fdist_bottom; + end + else begin + rect1.y:= flinkbottom.bounds_y - bounds_cy - fdist_bottom; + end; + end; + end + else begin + if alive(flinktop) then begin + rect1.y:= flinktop.bounds_y + flinktop.bounds_cy + fdist_top; + end; + end; + widgetrect:= rect1; + pt1:= pos; + addpoint1(pt1,pointty(size)); + pt1.x:= pt1.x + fdist_right; + pt1.y:= pt1.y + fdist_bottom; + if spao_glueright in foptions then begin + if alive(flinkleft) then begin + rect1:= flinkleft.widgetrect; + if an_left in flinkleft.anchors then begin + rect1.cx:= bounds_x - fdist_left - flinkleft.bounds_x; + with twidget1(flinkleft) do begin + fparentclientsize.cx:= twidget1(fparentwidget).minclientsize.cx; + //no change by pending parentclientrectchanged() + end; + end + else begin + rect1.x:= bounds_x - fdist_left - flinkleft.bounds_cx; + end; + flinkleft.widgetrect:= rect1; + end; + end + else begin + if alive(flinkright) then begin + rect1:= flinkright.widgetrect; + if an_right in flinkright.anchors then begin + rect1.cx:= rect1.cx + (rect1.x - pt1.x); + end; + rect1.pos.x:= pt1.x; + flinkright.widgetrect:= rect1; + end; + end; + if spao_gluebottom in foptions then begin + if alive(flinktop) then begin + rect1:= flinktop.widgetrect; + if an_top in flinktop.anchors then begin + rect1.cy:= bounds_y - fdist_top - flinktop.bounds_y; + with twidget1(flinktop) do begin + fparentclientsize.cy:= twidget1(fparentwidget).minclientsize.cy; + //no change by pending parentclientrectchanged() + end; + end + else begin + rect1.y:= bounds_y - fdist_top - flinktop.bounds_cy; + end; + flinktop.widgetrect:= rect1; + end; + end + else begin + if alive(flinkbottom) then begin + rect1:= flinkbottom.widgetrect; + if an_bottom in flinkbottom.anchors then begin + rect1.cy:= rect1.cy + (rect1.y - pt1.y); + end; + rect1.pos.y:= pt1.y; + flinkbottom.widgetrect:= rect1; + end; + end; + finally + dec(fupdating); + end; + end; +end; + +procedure tcustomspacer.loaded; +begin + inherited; + updatespace; +end; + +procedure tcustomspacer.parentwidgetregionchanged(const sender: twidget); +begin + inherited; + if (sender <> nil) and ((sender = flinkleft) or (sender = flinktop) or + (sender = flinkright) or (sender = flinkbottom) or + (sender = self)) then begin + updatespace; + end; +end; + +{ tcustomlayouter } + +constructor tcustomlayouter.create(aowner: tcomponent); +begin + foptionslayout:= defaultlayoutoptions; + falign_mode:= wam_center; +// faligny_mode:= wam_center; + fplace_maxdist:= bigint; + fplace_mode:= wam_start; +// fplacey_maxdist:= bigint; + inherited; + foptionswidget:= defaultgroupboxoptionswidget; + include(fwidgetstate,ws_visible); +end; + +procedure tcustomlayouter.setoptionslayout(const avalue: layoutoptionsty); +const + mask1: layoutoptionsty = [lao_alignx,lao_placex]; + mask2: layoutoptionsty = [lao_aligny,lao_placey]; +var + lao1,lao2: layoutoptionsty; +begin + if avalue <> foptionslayout then begin + lao1:= layoutoptionsty(setsinglebit({$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(foptionslayout), + {$ifdef FPC}longword{$else}word{$endif}(mask1)))*mask1; + lao2:= layoutoptionsty(setsinglebit({$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(foptionslayout), + {$ifdef FPC}longword{$else}word{$endif}(mask2)))*mask2; + foptionslayout:= (avalue - (mask1+mask2)) + lao1 + lao2; + updatelayout; + end; +end; + +function tcustomlayouter.childrenwidth: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + if (not(plo_noinvisible in fplace_options) or isvisible) then begin + result:= result + fwidgetrect.cx; + end; + end; + end; +end; + +function tcustomlayouter.childrenheight: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + if (not(plo_noinvisible in fplace_options) or isvisible) then begin + result:= result + fwidgetrect.cy; + end; + end; + end; +end; + +function tcustomlayouter.childrenminwidth: integer; +var + i1,i2,i3,i5: int32; + variable,space,fix: int32; +begin + variable:= 0; + space:= innerframewidth.cx; + i1:= high(fwidgets); + if i1 > 0 then begin + space:= space + fplace_mindist * i1; + end; + if i1 >= 0 then begin + if plo_propmargin in fplace_options then begin + space:= space + 2 * fplace_mindist; + end; + end; + fix:= space; + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],widget do begin + if not (plo_noinvisible in fplace_options) or isvisible then begin + if (anchors * [an_left,an_right] = [an_left,an_right]) then begin + fix:= fix + minshrinksize.cx;//minscrollsize.cx; + end + else begin + if (plo_scalesize in fplace_options) and + not (osk_nopropwidth in optionsskin) then begin + variable:= variable + bounds_cx; + end + else begin + fix:= fix + bounds_cx; + end; + end; + end; + end; + end; + if plo_scalesize in fplace_options then begin + //(x-extension)*(1/ref)*variable + fix = x + //x = (fix*ref - extension*variable) / (ref - variable) + + result:= 0; + i1:= fix*scalesizeref.cx - fscalesizeextension.cx*variable; + i2:= scalesizeref.cx - variable; + if i2 <> 0 then begin + result:= (i1 + i2 div 2) div i2; //with rounding + end; + i3:= 0; + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],widget do begin + if (not (plo_noinvisible in fplace_options) or isvisible) then begin + if not (osk_nopropwidth in optionsskin) then begin + if scalesize.cx > 0 then begin + i5:= curminsize.cx * refscalesize.cx div scalesize.cx; + if i3 < i5 then begin + i3:= i5; + end; + end; + end; + end; + end; + end; + i3:= i3 + fscalesizeextension.cx; //add not scaling values + if result < i3 then begin + result:= i3; + end; + end + else begin + result:= variable + fix; + end; +end; + +function tcustomlayouter.childrenminheight: integer; +var + i1,i2,i3,i5: int32; + variable,space,fix: int32; +begin + variable:= 0; + space:= innerframewidth.cy; + i1:= high(fwidgets); + if i1 > 0 then begin + space:= space + fplace_mindist * i1; + end; + if i1 >= 0 then begin + if plo_propmargin in fplace_options then begin + space:= space + 2 * fplace_mindist; + end; + end; + fix:= space; + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],widget do begin + if not (plo_noinvisible in fplace_options) or isvisible then begin + if (anchors * [an_top,an_bottom] = [an_top,an_bottom]) then begin + fix:= fix + minshrinksize.cy; //minscrollsize.cy; + end + else begin + if (plo_scalesize in fplace_options) and + not (osk_nopropwidth in optionsskin) then begin + variable:= variable + bounds_cy; + end + else begin + fix:= fix + bounds_cy; + end; + end; + end; + end; + end; + if plo_scalesize in fplace_options then begin + //(y-extension)*(1/ref)*variable + fix = y + //y = (fix*ref - extension*variable) / (ref - variable) + + result:= 0; + i1:= fix*scalesizeref.cy - fscalesizeextension.cy*variable; + i2:= scalesizeref.cy - variable; + if i2 <> 0 then begin + result:= (i1 + i2 div 2) div i2; //with rounding + end; + i3:= 0; + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],widget do begin + if (not (plo_noinvisible in fplace_options) or isvisible) then begin + if not (osk_nopropwidth in optionsskin) then begin + if scalesize.cy > 0 then begin + i5:= curminsize.cy * refscalesize.cy div scalesize.cy; + if i3 < i5 then begin + i3:= i5; + end; + end; + end; + end; + end; + end; + i3:= i3 + fscalesizeextension.cy; //add not scaling values + if result < i3 then begin + result:= i3; + end; + end + else begin + result:= variable + fix; + end; +end; +(* +function tcustomlayouter.childrenminheight: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[int1],widget do begin + if not(plo_noinvisible in fplace_options) or isvisible then begin + if (anchors * [an_top,an_bottom] = [an_top,an_bottom]) or + (plo_scalesize in fplace_options) and + not(osk_nopropheight in optionsskin) then begin +// result:= result + minscrollsize.cy; + result:= result + curminsize.cy; + end + else begin + result:= result + bounds_cy; + end; + end; + end; + end; +end; +*) +function tcustomlayouter.childrenleft: integer; +var + int1: integer; +begin + result:= bigint; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + if (not(plo_noinvisible in fplace_options) or isvisible) and + (fwidgetrect.x < result) and + not (osk_noalignx in optionsskin) then begin + result:= fwidgetrect.x; + end; + end; + end; + if result = bigint then begin + result:= 0; + end; +end; + +function tcustomlayouter.childrenright: integer; +var + int1: integer; + int2: integer; +begin + result:= -bigint; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + int2:= fwidgetrect.x + fwidgetrect.cx; + if (not(plo_noinvisible in fplace_options) or isvisible) and + (int2 > result) and + not (osk_noalignx in optionsskin) then begin + result:= int2; + end; + end; + end; + if result = -bigint then begin + result:= 0; + end; +end; + +function tcustomlayouter.childrentop: integer; +var + int1: integer; +begin + result:= bigint; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + if (not(plo_noinvisible in fplace_options) or isvisible) and + (fwidgetrect.y < result) and + not (osk_noaligny in optionsskin) then begin + result:= fwidgetrect.y; + end; + end; + end; + if result = bigint then begin + result:= 0; + end; +end; + +function tcustomlayouter.childrenbottom: integer; +var + int1: integer; + int2: integer; +begin + result:= -bigint; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + int2:= fwidgetrect.y + fwidgetrect.cy; + if (not (plo_noinvisible in fplace_options) or isvisible) and + (int2 > result) and + not (osk_noaligny in optionsskin) then begin + result:= int2; + end; + end; + end; + if result = -bigint then begin + result:= 0; + end; +end; + +procedure tcustomlayouter.checkwidgetinfo(); +var + i1: integer; +begin + if not (las_widgetinfoloaded in fstate) and + not(csloading in componentstate) then begin + include(fstate,las_widgetinfoloaded); + for i1:= high(fwidgetinfos) downto 0 do begin + updatewidgetinfo(fwidgetinfos[i1],nil,true); + end; + end; +end; + +procedure tcustomlayouter.updatelayout; +var + ar2: integerarty; + space,margin: integer; + + procedure calcarray(const awidgets: widgetarty; const awidth: integer; + const amin,amax: integer); + var + int1,int2: integer; + rea1,rea2: real; + begin + margin:= 0; + if high(awidgets) > 0 then begin + if plo_propmargin in fplace_options then begin + rea1:= awidth / (high(awidgets)+2); + end + else begin + rea1:= awidth / high(awidgets); + end; + if rea1 < amin then begin + rea1:= amin; + end; + if rea1 > amax then begin + rea1:= amax; + end; + if plo_propmargin in fplace_options then begin + margin:= round(rea1); + end; + rea2:= rea1; + setlength(ar2,high(awidgets)); + space:= 0; + for int1:= 0 to high(ar2) do begin + int2:= round(rea2); + space:= space + int2; + ar2[int1]:= int2; + rea2:= rea2 - ar2[int1] + rea1; + end; + end + else begin + space:= 0; + if plo_propmargin in fplace_options then begin + margin:= awidth div 2; + if margin < amin then begin + margin:= amin; + end; + if margin > amax then begin + margin:= amax; + end; + end; + end; + end; //calcarray + + function getalignwidgets(const isx: boolean): widgetarty; + var + int1,int2: integer; + begin + setlength(result,widgetcount); + int2:= 0; + if (falign_leader <> nil) and + (falign_leader.parentwidget = self) then begin + result[0]:= falign_leader; + int2:= 1; + end; + for int1:= 0 to high(result) do begin + if fwidgets[int1] <> falign_leader then begin + if isx and not (osk_noalignx in fwidgets[int1].optionsskin) or + not isx and not (osk_noaligny in fwidgets[int1].optionsskin) then begin + result[int2]:= fwidgets[int1]; + inc(int2); + end; + end; + end; + setlength(result,int2); + end; //getalignwidgets + +var + int1,int2,int3,int4: integer; + ar1: widgetarty; + size1: sizety; +// outerwidth1: int32; +// bo1: boolean; + i1,i2: int32; +begin + if (componentstate * [csloading,csdestroying] = []) and + (flayoutupdating = 0) then begin + for int1:= 0 to high(fwidgets) do begin + if csloading in fwidgets[int1].componentstate then begin + delayedupdatelayout(); + exit; + end; + end; + if canevent(tmethod(fonbeforelayout)) then begin + fonbeforelayout(self); + end; + checkwidgetinfo(); + inc(flayoutupdating); + try + updateoptionsscale; + beginscaling; + if widgetcount > 0 then begin + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],twidget1(widget) do begin + layoutplacingbefore:= ws1_layoutplacing in fwidgetstate1; + include(fwidgetstate1,ws1_layoutplacing); + end; + end; + if (foptionslayout*[lao_placex,lao_placey] <> []) and + (plo_scalesize in fplace_options) then begin + //scale to variable clientsize + size1:= scalesizeref; + if lao_placex in foptionslayout then begin + for int1:= high(fwidgetinfos) downto 0 do begin + with fwidgetinfos[int1] do begin + if not (osk_nopropwidth in widget.optionsskin) and + (refscalesize.cx <> 0) then begin + with twidget1(widget) do begin +// bo1:= ws1_layoutplacing in fwidgetstate1; +// try +// include(fwidgetstate1,ws1_layoutplacing); + i1:= (scalesize.cx * size1.cx) div refscalesize.cx; + i2:= curminsize.cx; + if i1 < i2 then begin + i1:= i2; + end; + widget.width:= i1; + actscalesize.cx:= widget.width; +// finally +// if not bo1 then begin +// exclude(fwidgetstate1,ws1_layoutplacing); +// end; +// end; + end; + end; + end; + end; + end + else begin + for int1:= high(fwidgetinfos) downto 0 do begin + with fwidgetinfos[int1] do begin + if not (osk_nopropheight in widget.optionsskin) and + (refscalesize.cy <> 0) then begin + with twidget1(widget) do begin +// bo1:= ws1_layoutplacing in fwidgetstate1; +// try +// include(fwidgetstate1,ws1_layoutplacing); + i1:= (scalesize.cy * size1.cy) div refscalesize.cy; + i2:= minshrinksize().cy; + if i1 < i2 then begin + i1:= i2; + end; + widget.height:= i1; + actscalesize.cy:= widget.height; +// finally +// if not bo1 then begin +// exclude(fwidgetstate1,ws1_layoutplacing); +// end; +// end; + end; + end; + end; + end; + end; + end; + if lao_syncmaxautosize in foptionslayout then begin + syncmaxautosize(fwidgets); + end; + if lao_syncpaintwidth in foptionslayout then begin + int1:= -1; + if (lao_alignx in foptionslayout) and + (falign_glue in [wam_start,wam_end]) then begin + int1:= innerclientsize.cx; + end; + syncpaintwidth(fwidgets,int1); + end; + if lao_syncpaintheight in foptionslayout then begin + int1:= -1; + if (lao_aligny in foptionslayout) and + (falign_glue in [wam_start,wam_end]) then begin + int1:= innerclientsize.cy; + end; + syncpaintheight(fwidgets); + end; + if lao_synccaptiondistx in foptionslayout then begin + synccaptiondistx(fwidgets); + end; + if lao_synccaptiondisty in foptionslayout then begin + synccaptiondisty(fwidgets); + end; + if lao_alignx in foptionslayout then begin + if (align_mode <> wam_none) or (align_glue <> wam_none) then begin + ar1:= getalignwidgets(true); + int2:= 0; + case falign_glue of + wam_start: begin + int2:= innerclientpos.x; + end; + wam_end: begin + int2:= clientwidth - (innerclientpos.x + innerclientsize.cx); + end; + else begin //wam_center + with innerclientframe do begin + int2:= right-left; + end; + end; + end; + alignx(align_mode,ar1,align_glue,int2); + end; + end; + if lao_aligny in foptionslayout then begin + if (align_mode <> wam_none) or (align_glue <> wam_none) then begin + ar1:= getalignwidgets(false); + int2:= 0; + case falign_glue of + wam_start: begin + int2:= innerclientpos.y; + end; + wam_end: begin + int2:= clientheight - (innerclientpos.y + innerclientsize.cy); + end; + else begin //wam_center + with innerclientframe do begin + int2:= bottom-top; + end; + end; + end; + aligny(align_mode,ar1,align_glue,int2); + end; + end; + if (fplace_mode <> wam_none) and + (foptionslayout * [lao_placex,lao_placey] <> []) then begin + if plo_noinvisible in fplace_options then begin + ar1:= getvisiblewidgets; + end + else begin + ar1:= copy(fwidgets); + end; + if lao_placex in foptionslayout then begin + sortwidgetsxorder(ar1,self); + int4:= childrenwidth; + calcarray(ar1,innerclientsize.cx - int4,fplace_mindist,fplace_maxdist); + if plo_endmargin in fplace_options then begin + placexorder(innerclientpos.x + margin,ar2,ar1, + innerclientframe.right + margin); + end + else begin + case fplace_mode of + wam_start: begin + int3:= innerclientpos.x + margin; + end; + wam_center: begin + int3:= innerclientpos.x + (innerclientsize.cx - int4 - space) div 2; + end; + wam_end: begin + int3:= innerclientpos.x + innerclientsize.cx - int4 - space - margin; + end; + end; + placexorder(int3,ar2,ar1); + end; + end; + if (lao_placey in foptionslayout) and (fplace_mode <> wam_none) then begin + sortwidgetsyorder(ar1,self); + int4:= childrenheight; + calcarray(ar1,innerclientsize.cy - int4,fplace_mindist,fplace_maxdist); + if plo_endmargin in fplace_options then begin + placeyorder(innerclientpos.y + margin,ar2,ar1, + innerclientframe.bottom + margin); + end + else begin + case fplace_mode of + wam_start: begin + int3:= innerclientpos.y + margin; + end; + wam_center: begin + int3:= innerclientpos.y + (innerclientsize.cy - int4 - space) div 2; + end; + wam_end: begin + int3:= innerclientpos.y + innerclientsize.cy - int4 - space - margin; + end; + end; + placeyorder(int3,ar2,ar1); + end; + end; + end; + end; + finally + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],twidget1(widget) do begin + if not layoutplacingbefore then begin + exclude(fwidgetstate1,ws1_layoutplacing); + end; + end; + end; + endscaling; + dec(flayoutupdating); + end; + if canevent(tmethod(fonafterlayout)) then begin + fonafterlayout(self); + end; + end; +end; + +procedure tcustomlayouter.readstate(reader: treader); +begin + inherited; + ttaborderoverride1(ftaborderoverride).endread(reader); +end; + +procedure tcustomlayouter.updatescalesizeref; +var + int1,int3: integer; + sum: sizety; + bo1: boolean; +begin + include(fstate,las_scalesizerefvalid); + if plo_scalesize in fplace_options then begin + if foptionslayout * [lao_placex,lao_placey] <> [] then begin + if las_scalesizerefset in fstate then begin + checkwidgetinfo(); //store initial values set in loaded state + end; + fscalesizeref:= innerclientsize; + sum:= nullsize; + if not (plo_scalefullref in fplace_options) then begin + bo1:= not (plo_noinvisible in fplace_options); + for int1:= 0 to high(fwidgets) do begin + with widgets[int1] do begin + if (bo1 or visible) then begin + if osk_nopropwidth in optionsskin then begin + addsize1(sum,size); + end + else begin +// addsize1(sum,framedim); + end; + end + else begin + end; + end; + end; + if bo1 then begin + int3:= length(fwidgets); + end + else begin + int3:= 0; + for int1:= 0 to high(fwidgets) do begin + if fwidgets[int1].visible then begin + inc(int3); + end; + end; + end; + if not (plo_propmargin in fplace_options) then begin + dec(int3); + end; + subsize1(fscalesizeref,sum); + if int3 > 0 then begin + int3:= int3 * fplace_mindist; + fscalesizeref.cx:= fscalesizeref.cx - int3; + fscalesizeref.cy:= fscalesizeref.cy - int3; + end; + end; + fscalesizeextension.cx:= fwidgetrect.cx - fscalesizeref.cx; + fscalesizeextension.cy:= fwidgetrect.cy - fscalesizeref.cy; + include(fstate,las_scalesizerefset); + checkwidgetinfo(); //store initial values + end; + end; +end; + +function tcustomlayouter.calcminscrollsize: sizety; +var + int1,int2,int3,int4: integer; +begin + result:= inherited calcminscrollsize; + if lao_placex in foptionslayout then begin + result.cx:= childrenminwidth; + end; + if lao_placey in foptionslayout then begin + result.cy:= childrenminheight; + end; + if (high(fwidgets) >= 0) and (align_glue <> wam_none) and + (align_mode <> wam_none)then begin + int2:= -bigint; + int3:= bigint; + if lao_alignx in foptionslayout then begin + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1] do begin + if isvisible or + (ow1_invisibleparentsizeextend in foptionswidget1) then begin + with fwidgetrect do begin + if x < int3 then begin + int3:= x; + end; + int4:= x + cx; + if int4 > int2 then begin + int2:= int4; + end; + end; + end; + end; + end; + if int2 > int3 then begin + int2:= int2-int3; + end + else begin + int2:= 0; + end; + int2:= int2 + innerframewidth.cx; + if int2 < bounds_cxmin then begin + int2:= bounds_cxmin; + end; + result.cx:= int2; + end; + if lao_aligny in foptionslayout then begin + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1] do begin + if isvisible or + (ow1_invisibleparentsizeextend in foptionswidget1) then begin + with fwidgetrect do begin + if y < int3 then begin + int3:= y; + end; + int4:= y + cy; + if int4 > int2 then begin + int2:= int4; + end; + end; + end; + end; + end; + if int2 > int3 then begin + int2:= int2-int3; + end + else begin + int2:= 0; + end; + int2:= int2 + innerframewidth.cy; + if int2 < bounds_cymin then begin + int2:= bounds_cymin; + end; + result.cy:= int2; + end; + end; +end; + +procedure tcustomlayouter.loaded; +begin + inherited; + updatelayout; +end; + +procedure tcustomlayouter.fontchanged; +begin + inherited; + if flayoutupdating = 0 then begin + ffontheightref:= getfont.height; +// if ffontheightref = 0 then begin +// ffontheightref:= font.glyphheight; +// end; + ffontxscaleref:= getfont.xscale; + ffontsizeref:= clientsize; + end; +end; + +procedure tcustomlayouter.childclientrectchanged(const sender: twidget); +var + int1: integer; +begin + inherited; + if not (las_propsizing in fstate) then begin + int1:= widgetinfoindex(sender); + if int1 >= 0 then begin + updatewidgetinfo(fwidgetinfos[int1],sender); + end; + end; +end; + +procedure tcustomlayouter.widgetregionchanged(const sender: twidget); +var + int1: integer; +begin + inherited; + if not (csloading in componentstate) then begin + if not (las_propsizing in fstate) then begin + int1:= widgetinfoindex(sender); + if int1 >= 0 then begin + updatewidgetinfo(fwidgetinfos[int1],sender); + end; + end; + if not (ws_loadedproc in fwidgetstate) then begin + scalesizerefchanged; + if (flayoutupdating = 0) and (plo_scalesize in fplace_options) and + (sender.optionsskin * [osk_nopropwidth,osk_nopropheight] <> []) then begin + scalebasechanged(sender); + end; + updatelayout; + end; + end; +end; + +procedure tcustomlayouter.setalign_mode(const avalue: widgetalignmodety); +begin + if avalue <> falign_mode then begin + falign_mode:= avalue; + updatelayout; + end; +end; + +procedure tcustomlayouter.setalign_glue(const avalue: widgetalignmodety); +begin + if falign_glue <> avalue then begin + falign_glue:= avalue; + updatelayout; + end; +end; + +procedure tcustomlayouter.setalign_leader(const avalue: twidget); +begin + if falign_leader <> avalue then begin + setlinkedvar(avalue,tmsecomponent(falign_leader)); + updatelayout; + end; +end; + +procedure tcustomlayouter.setplace_mindist(const avalue: integer); +begin + if fplace_mindist <> avalue then begin + fplace_mindist:= avalue; + scalebasechanged(nil); + updatelayout; + end; +end; + +procedure tcustomlayouter.setplace_maxdist(const avalue: integer); +begin + if fplace_maxdist <> avalue then begin + fplace_maxdist:= avalue; + updatelayout; + end; +end; + +procedure tcustomlayouter.setplace_mode(const avalue: widgetalignmodety); +begin + if fplace_mode <> avalue then begin + fplace_mode:= avalue; + updatelayout; + end; +end; + +procedure tcustomlayouter.setplace_options(avalue: placeoptionsty); +var + diff1: placeoptionsty; +begin + if (csreading in componentstate) and + (avalue * deprecatedplaceoptions <> []) then begin + optionslayout:= optionslayout + + layoutoptionsty(card32(avalue * deprecatedplaceoptions) shl + (ord(lao_syncmaxautosize) - ord(plo_syncmaxautosize))); + end; + avalue:= avalue - deprecatedplaceoptions; + diff1:= fplace_options >< avalue; + if diff1 <> [] then begin + fplace_options:= avalue; + if diff1 * [plo_scalesize,plo_scalefullref,plo_noinvisible] <> [] then begin + exclude(fstate,las_scalesizerefvalid); + if plo_scalesize in fplace_options then begin + scalebasechanged(nil); + end; + end; + updatelayout(); + end; +end; + +procedure tcustomlayouter.clientrectchanged; +var + refsi: sizety; + pt1: pointty; + size1: sizety; + int1: integer; +begin + inc(flayoutupdating); + try + inherited; + exclude(fstate,las_scalesizerefvalid); + if componentstate * [csloading,csdestroying] = [] then begin + if (foptionslayout * [lao_scalewidth,lao_scaleheight,lao_scalefont, + lao_scalechildfont] <> []) and + not (las_propsizing in fstate) then begin + beginscaling; + include(fstate,las_propsizing); + try + if (lao_scalefont in foptionslayout) and (ffontsizeref.cx <> 0) and + (ffontsizeref.cy <> 0) then begin + font.height:= round((ffontheightref*clientheight)/ffontsizeref.cy); + if clientheight > 0 then begin + font.xscale:= (ffontxscaleref * (clientwidth/ffontsizeref.cx))/ + (clientheight/ffontsizeref.cy); + end; + end; + if foptionslayout * + [lao_scalewidth,lao_scaleheight,lao_scalefont] <> [] then begin + refsi:= innerclientsize; + for int1:= high(fwidgetinfos) downto 0 do begin + with fwidgetinfos[int1] do begin + if (lao_scalechildfont in foptionslayout) and + not (osk_nopropfont in widget.optionsskin) and + (twidget1(widget).ffont <> nil) and + (reffontsize.cx <> 0) and (reffontsize.cy <> 0) and + (refsi.cy > 0) then begin + twidget1(widget).ffont.height:= + round(fontheight * refsi.cy / reffontsize.cy); + twidget1(widget).ffont.xscale:= (fontxscale * (refsi.cx/refsi.cy))/ + (reffontsize.cx/reffontsize.cy); + end; + pt1:= widget.pos; + size1:= widget.clientsize; + if refsize.cx <> 0 then begin + if (lao_scaleleft in foptionslayout) and + not (osk_nopropleft in widget.optionsskin) then begin + pt1.x:= (pos.x * refsi.cx) div refsize.cx; + end; + if (lao_scalewidth in foptionslayout) and + not (osk_nopropwidth in widget.optionsskin) then begin + size1.cx:= (size.cx * refsi.cx) div refsize.cx; + end; + end; + if refsize.cy <> 0 then begin + if (lao_scaletop in foptionslayout) and + not (osk_noproptop in widget.optionsskin) then begin + pt1.y:= (pos.y * refsi.cy) div refsize.cy; + end; + if (lao_scaleheight in foptionslayout) and + not (osk_nopropheight in widget.optionsskin) then begin + size1.cy:= (size.cy * refsi.cy) div refsize.cy; + end; + end; + widget.clientsize:= size1; + widget.pos:= pt1; + end; + end; + end; + finally + exclude(fstate,las_propsizing); + endscaling; + end; + end; + end; + finally + dec(flayoutupdating); + end; + updatelayout; +end; + +procedure tcustomlayouter.childautosizechanged(const sender: twidget); +begin + inherited; + updatelayout; +end; + +procedure tcustomlayouter.registerchildwidget(const child: twidget); +begin + setlength(fwidgetinfos,high(fwidgetinfos)+2); + updatewidgetinfo(fwidgetinfos[high(fwidgetinfos)],child); + inherited; +end; + +procedure tcustomlayouter.unregisterchildwidget(const child: twidget); +var + int1: integer; +begin + if not (csdestroying in componentstate) then begin + int1:= widgetinfoindex(child); + if int1 >= 0 then begin + finalize(fwidgetinfos[int1]); + move(fwidgetinfos[int1+1],fwidgetinfos[int1], + (high(fwidgetinfos)-int1)*sizeof(widgetlayoutinfoty)); + setlength(fwidgetinfos,high(fwidgetinfos)); + end; + end; + inherited; +end; + +function tcustomlayouter.widgetinfoindex(const awidget: twidget): integer; +var + int1: integer; +begin + result:= -1; + for int1:= high(fwidgetinfos) downto 0 do begin + if fwidgetinfos[int1].widget = awidget then begin + result:= int1; + break; + end; + end; +end; + +procedure tcustomlayouter.updatewidgetinfo(var ainfo: widgetlayoutinfoty; + const awidget: twidget; const force: boolean = false); +var + size1,size2: sizety; + int1: integer; + rea1: real; +begin + with ainfo do begin + if awidget <> nil then begin + widget:= awidget; + end; + if not (csloading in componentstate) then begin +// size1:= widget.clientsize; + with twidget1(widget) do begin + curminsize:= minshrinksize(); +// if fframe <> nil then begin +// subsize1(curminsize,fframe.outerframedim); +// end; + end; + size1:= widget.size; + if (flayoutupdating = 0) or force then begin + //synchronize ref values with changed widget values + size2:= self.scalesizeref; + if size1.cx <> actscalesize.cx then begin + refscalesize.cx:= size2.cx; + scalesize.cx:= size1.cx; + actscalesize.cx:= scalesize.cx; + end; + if size1.cy <> actscalesize.cy then begin + refscalesize.cy:= size2.cy; + scalesize.cy:= size1.cy; + actscalesize.cy:= scalesize.cy; + end; + end; + size2:= innerclientsize; + if widget.bounds_x <> actpos.x then begin + refsize.cx:= size2.cx; + pos.x:= widget.bounds_x; + actpos.x:= pos.x; + end; + if widget.bounds_y <> actpos.y then begin + refsize.cy:= size2.cy; + pos.y:= widget.bounds_y; + actpos.y:= pos.y; + end; + if size1.cx <> actsize.cx then begin + refsize.cx:= size2.cx; + size.cx:= size1.cx; + actsize.cx:= size1.cx; + end; + if size1.cy <> actsize.cy then begin + refsize.cy:= size2.cy; + size.cy:= size1.cy; + actsize.cy:= size1.cy; + end; + if twidget1(widget).ffont <> nil then begin + int1:= twidget1(widget).ffont.height; + rea1:= twidget1(widget).ffont.xscale; + if (int1 <> actfontheight) or (rea1 <> actfontxscale) then begin + reffontsize:= size2; + fontheight:= int1; + actfontheight:= int1; + fontxscale:= rea1; + actfontxscale:= rea1; + end; + end; + end; + end; +end; + +function tcustomlayouter.scalesizeref: sizety; +begin + if not (las_scalesizerefvalid in fstate) then begin + updatescalesizeref; + end; + result:= fscalesizeref; +end; + +procedure tcustomlayouter.scalesizerefchanged; +begin + if (componentstate * [csloading,csdestroying] = []) and + (flayoutupdating = 0) then begin + exclude(fstate,las_scalesizerefvalid); + end; +end; + +procedure tcustomlayouter.scalebasechanged(const sender: twidget); +var + int1: integer; + size1: sizety; +begin + if not (csloading in componentstate) then begin + scalesizerefchanged; + size1:= scalesizeref; + for int1:= high(fwidgetinfos) downto 0 do begin + with fwidgetinfos[int1] do begin +// scalesize:= widget.clientsize; + scalesize:= widget.size; + actscalesize:= scalesize; + refscalesize:= size1; + end; + end; + end; +end; + +const + updatelayouttag = 8436026; + +procedure tcustomlayouter.delayedupdatelayout; +begin + if not (las_delayedupdatelayoutpending in fstate) then begin + include(fstate,las_delayedupdatelayoutpending); + asyncevent(updatelayouttag,[peo_local,peo_first]); + //before childscaled events + end; +end; + +procedure tcustomlayouter.doasyncevent(var atag: integer); +begin + inherited; + if atag = updatelayouttag then begin + exclude(fstate,las_delayedupdatelayoutpending); + updatelayout(); + end; +end; + +{ texpandingwidget } + +constructor texpandingwidget.create(aowner: tcomponent); +begin + inherited; + foptionswidget:= defaultgroupboxoptionswidget; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msetabs.pas b/mseide-msegui/lib/common/widgets/msetabs.pas new file mode 100644 index 0000000..22e84a5 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msetabs.pas @@ -0,0 +1,5524 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msetabs; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msetabsglob,msewidgets,mseclasses,msearrayprops,classes,mclasses,mseshapes, + mserichstring,msetypes,msegraphics,msegraphutils,mseevent,mseinterfaces, + mseglob,mseguiglob,msegui,msebitmap,msedragglob, + {mseforms,}rtlconsts,msesimplewidgets,msedrag,mseact, + mseobjectpicker,msepointer,msestat,msestatfile,msestrings,msemenus, + msedrawtext,msetimer; + +const + defaulttaboptionswidget = defaultoptionswidgetmousewheel + + [ow_subfocus{,ow_fontglyphheight}]; + defaulttaboptionsskin = defaultoptionsskin + [osk_colorcaptionframe]; + defaultcaptiondist = 1; + defaultimagedist = 0; + defaulttabshift = -100; //-> 1 + defaultedgelevel = -100; //-> -1 + defaultimagepos = ip_right; + defaulttabpageskinoptions = defaultcontainerskinoptions; + defaultoptionswidgettab = defaultoptionswidgetnofocus; + defaultoptionswidget1tab = [ow1_autoheight]; + defaultcolortab = cl_transparent; + defaultcoloractivetab = cl_active; + +type + tcustomtabbar = class; + tabstatety = (ts_invisible,ts_disabled,ts_active,ts_updating,ts_captionclipped, + ts_noface); + tabstatesty = set of tabstatety; + + ttabfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabfontactive = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttab = class(tindexpersistent,iimagelistinfo) + private + frichcaption: richstringty; + fcaption: msestring; + fhint: msestring; + fstate: tabstatesty; + fcolor: colorty; + fcoloractive: colorty; + fident: integer; + fimagelist: timagelist; + fimagenr: imagenrty; + fimagenrdisabled: imagenrty; +// function getcaption: captionty; + fface: tfacecomp; + ffaceactive: tfacecomp; + procedure setcaption(const avalue: captionty); + procedure changed; + procedure setstate(const Value: tabstatesty); + procedure setcolor(const Value: colorty); + procedure setcoloractive(const Value: colorty); + function getactive: boolean; + procedure setactive(const Value: boolean); + procedure setimagelist(const avalue: timagelist); + procedure setimagenr(const avalue: imagenrty); + procedure setimagenrdisabled(const avalue: imagenrty); + function getimagelist: timagelist; + function getfont: ttabfont; + procedure setfont(const avalue: ttabfont); + function isfontstored: boolean; + function getfontactive: ttabfontactive; + procedure setfontactive(const avalue: ttabfontactive); + function isfontactivestored: boolean; + procedure setface(const avalue: tfacecomp); + procedure setfaceactive(const avalue: tfacecomp); + protected + ftag: integer; + ffont: ttabfont; + ffontactive: ttabfontactive; + procedure fontchanged(const sender: tobject); + procedure execute(const tag: integer; const info: mouseeventinfoty); + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create(const aowner: tcustomtabbar); reintroduce; + destructor destroy; override; + procedure createfont; + procedure createfontactive; + function tabbar: tcustomtabbar; + property ident: integer read fident; + property active: boolean read getactive write setactive; + published + property caption: captionty read fcaption write setcaption; + property state: tabstatesty read fstate write setstate default []; + property color: colorty read fcolor write setcolor default cl_default; + property coloractive: colorty read fcoloractive + write setcoloractive default cl_default; + property face: tfacecomp read fface write setface; + property faceactive: tfacecomp read ffaceactive write setfaceactive; + property font: ttabfont read getfont write setfont stored isfontstored; + property fontactive: ttabfontactive read getfontactive write setfontactive + stored isfontactivestored; + property imagelist: timagelist read fimagelist write setimagelist; + property imagenr: imagenrty read fimagenr write setimagenr default -1; + property imagenrdisabled: imagenrty read fimagenrdisabled + write setimagenrdisabled default -2; + //-2 -> same as imagenr + property tag: integer read ftag write ftag default 0; + property hint: msestring read fhint write fhint; + end; + tabarty = array of ttab; + tabaty = array[0..0] of ttab; + ptabaty = ^tabaty; + + ttabs = class; + + createtabeventty = procedure(const sender: tcustomtabbar; const index: integer; + var tab: ttab) of object; + + ttabframe = class(tframe) + public + constructor create(const aintf: iframe); + published + property framei_left default defaultcaptiondist; + property framei_top default defaultcaptiondist; + property framei_right default defaultcaptiondist; + property framei_bottom default defaultcaptiondist; + property imagedist default defaultimagedist; + end; + + ttabsfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabsfontactive = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabs = class(tindexpersistentarrayprop,iframe) + private + fcolor: colorty; + fcoloractive: colorty; + fimagepos: imageposty; +// fcaptionframe: framety; +// fimagedist: integer; + fframe: ttabframe; + fface: tface; + ffaceactive: tface; + fhint: msestring; + foncreatetab: createtabeventty; + factcellindex: integer; + ftabshift: integer; + fshift: integer; + ftextflags: textflagsty; + fwidth: integer; + fwidthmin: integer; + fwidthmax: integer; + fedge_level: int32; + fedge: edgecolorpairinfoty; + fedge_imagelist: timagelist; + fedge_imageoffset: int32; + fedge_imagepaintshift: int32; + procedure setitems(const index: integer; const Value: ttab); + function getitems(const index: integer): ttab; reintroduce; + function getface: tface; + procedure setface(const avalue: tface); + function getfaceactive: tface; + procedure setfaceactive(const avalue: tface); + procedure setcolor(const avalue: colorty); + procedure setcoloractive(const avalue: colorty); + procedure setimagepos(const avalue: imageposty); + { + procedure setcaptionframe_left(const avalue: integer); + procedure setcaptionframe_top(const avalue: integer); + procedure setcaptionframe_right(const avalue: integer); + procedure setcaptionframe_bottom(const avalue: integer); + procedure setimagedist(const avalue: integer); + } + function getframe: ttabframe; + procedure setframe(const avalue: ttabframe); + procedure setshift(const avalue: integer); + function getfont: ttabsfont; + procedure setfont(const avalue: ttabsfont); + function isfontstored: boolean; + function getfontactive: ttabsfontactive; + procedure setfontactive(const avalue: ttabsfontactive); + function isfontactivestored: boolean; + procedure readcaptionpos(reader: treader); + procedure readcaptionframe_left(reader: treader); + procedure readcaptionframe_top(reader: treader); + procedure readcaptionframe_right(reader: treader); + procedure readcaptionframe_bottom(reader: treader); + procedure readimagedist(reader: treader); + procedure settextflags(const avalue: textflagsty); + procedure setwidth(const avalue: integer); + procedure setwidthmin(const avalue: integer); + procedure setwidthmax(const avalue: integer); + procedure setedge_level(const avalue: int32); + procedure setedge_colordkshadow(const avalue: colorty); + procedure setedge_colorshadow(const avalue: colorty); + procedure setedge_colorlight(const avalue: colorty); + procedure setedge_colorhighlight(const avalue: colorty); + procedure setedge_colordkwidth(const avalue: int32); + procedure setedge_colorhlwidth(const avalue: int32); + procedure setedge_imagelist(const avalue: timagelist); + procedure setedge_imageoffset(const avalue: int32); + procedure setedge_imagepaintshift(const avalue: int32); + protected + fskinupdating: integer; + ffont: ttabsfont; + ffontactive: ttabsfontactive; + procedure defineproperties(filer: tfiler); override; + procedure changed; + procedure fontchanged(const sender: tobject); + procedure createitem(const index: integer; var item: tpersistent); override; + procedure dochange(const index: integer); override; + procedure checktemplate(const sender: tobject); + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function getwidgetrect: rectty; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; const org: originty = org_client; + const noclip: boolean = false); + function getwidget: twidget; + function getframestateflags: framestateflagsty; virtual; + function getedgeshift(): int32; + public + constructor create(const aowner: tcustomtabbar; + aclasstype: indexpersistentclassty); reintroduce; + destructor destroy; override; + class function getitemclasstype: persistentclassty; override; + procedure createfont; + procedure createfontactive; + procedure createframe; + procedure createface; + procedure createfaceactive; + procedure add(const item: ttab); + procedure insert(const item: ttab; const aindex: integer); + procedure additems(const aitems: msestringarty); + function indexof(const item: ttab): integer; + property items[const index: integer]: ttab read getitems write setitems; default; + property oncreatetab: createtabeventty read foncreatetab write foncreatetab; + published + property color: colorty read fcolor + write setcolor default cl_default; + property coloractive: colorty read fcoloractive + write setcoloractive default cl_default; + property font: ttabsfont read getfont write setfont stored isfontstored; + property fontactive: ttabsfontactive read getfontactive write setfontactive + stored isfontactivestored; + + property width: integer read fwidth write setwidth default 0; + property widthmin: integer read fwidthmin write setwidthmin default 0; + property widthmax: integer read fwidthmax write setwidthmax default 0; + property textflags: textflagsty read ftextflags write settextflags + default defaultcaptiontextflags; + property imagepos: imageposty read fimagepos write + setimagepos default defaultimagepos; +{ + property captionframe_left: integer read fcaptionframe.left write + setcaptionframe_left default defaultcaptiondist; + property captionframe_top: integer read fcaptionframe.top write + setcaptionframe_top default defaultcaptiondist; + property captionframe_right: integer read fcaptionframe.right write + setcaptionframe_right default defaultcaptiondist; + property captionframe_bottom: integer read fcaptionframe.bottom write + setcaptionframe_bottom default defaultcaptiondist; + property imagedist: integer read fimagedist write setimagedist + default defaultimagedist; +} + property shift: integer read fshift write setshift default defaulttabshift; + //defaulttabshift (-100) -> 1 + property edge_level: int32 read fedge_level write setedge_level + default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property edge_colordkshadow: colorty read fedge.shadow.effectcolor + write setedge_colordkshadow default cl_default; + property edge_colorshadow: colorty read fedge.shadow.color + write setedge_colorshadow default cl_default; + property edge_colorlight: colorty read fedge.light.color + write setedge_colorlight default cl_default; + property edge_colorhighlight: colorty read fedge.light.effectcolor + write setedge_colorhighlight default cl_default; + property edge_colordkwidth: int32 read fedge.shadow.effectwidth + write setedge_colordkwidth default -1; + //-1 = default + property edge_colorhlwidth: int32 read fedge.light.effectwidth + write setedge_colorhlwidth default -1; + //-1 = default + property edge_imagelist: timagelist read fedge_imagelist + write setedge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property edge_imageoffset: int32 read fedge_imageoffset + write setedge_imageoffset default 0; + property edge_imagepaintshift: int32 read fedge_imagepaintshift + write setedge_imagepaintshift default 0; + + property frame: ttabframe read getframe write setframe; + //frameimage_offset1 active for first tab + property face: tface read getface write setface; + property faceactive: tface read getfaceactive write setfaceactive; + property hint: msestring read fhint write fhint; + end; + + tabbarlayoutinfoty = record + tabs: ttabs; + dim: rectty; + captionframe: framety; + totsize: sizety; + activetab: integer; + focusedtab: integer; + cells: shapeinfoarty; + firsttab: integer; + lasttab: integer; + notfull: boolean; + stepinfo: framestepinfoty; + options: shapestatesty; + end; + + movingeventty = procedure(const sender: tobject; var curindex: integer; + var newindex: integer) of object; + movedeventty = procedure(const sender: tobject; const curindex: integer; + const newindex: integer) of object; + tabschangedeventty = procedure(const synctabindex: boolean) of object; + + tabbarstatety = (tbs_layoutvalid,tbs_designdrag,tbs_shrinktozero, + tbs_updatesizing,tbs_repeatup); + tabbarstatesty = set of tabbarstatety; + + tcustomtabbar = class(tcustomstepbox) + private + flayoutinfo: tabbarlayoutinfoty; + fhintedbutton: integer; + fonactivetabchange: notifyeventty; + fupdating: integer; + finternaltabchange: tabschangedeventty; + fontabmoving: movingeventty; + fontabmoved: movedeventty; + fonclientmouseevent: mouseeventty; + frepeater: trepeater; + procedure settabs(const Value: ttabs); + procedure layoutchanged; + procedure checklayout; + procedure updatelayout(); + function getactivetab: integer; + procedure setactivetab(const Value: integer); + procedure tabschanged(const sender: tarrayprop; const index: integer); + procedure setfirsttab(Value: integer); + procedure setoptions(const avalue: tabbaroptionsty); + function gethintpos(const aindex: integer): rectty; + function getbuttonhint(const aindex: integer): msestring; + procedure repeatproc(const sender: tobject); + procedure startrepeater(const up: boolean); + procedure killrepeater(); + protected + fstate: tabbarstatesty; + foptions: tabbaroptionsty; + class function classskininfo: skininfoty; override; + function dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; override; + procedure doactivetabchanged; + procedure tabchanged(const sender: ttab); + procedure tabclicked(const sender: ttab; const info: mouseeventinfoty); + procedure enabledchanged; override; + procedure loaded; override; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure statechanged; override; + procedure fontchanged; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + procedure clientrectchanged; override; + procedure getautopaintsize(var asize: sizety); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure dokeydown(var info: keyeventinfoty); override; + function upstep(const norotate: boolean): boolean; + function downstep(const norotate: boolean): boolean; + //iassistiveclient + function getassistivecaption(): msestring; override; + function getassistivehint(): msestring; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure synctofontheight; override; + procedure beginupdate; + procedure endupdate; + function tabatpos(const apos: pointty; const enabledonly: boolean = false): integer; + procedure movetab(curindex,newindex: integer); + function activetag: integer; //0 if no activetab, activetab.tag otherwise + procedure dragevent(var info: draginfoty); override; + property activetab: integer read getactivetab write setactivetab; + property tabs: ttabs read flayoutinfo.tabs write settabs; + property firsttab: integer read flayoutinfo.firsttab write setfirsttab default 0; + property onactivetabchange: notifyeventty read fonactivetabchange + write fonactivetabchange; + property font: twidgetfont read getfont write setfont stored isfontstored; + property options: tabbaroptionsty read foptions write setoptions default []; + property ontabmoving: movingeventty read fontabmoving write fontabmoving; + property ontabmoved: movedeventty read fontabmoved write fontabmoved; + property onclientmouseevent: mouseeventty read fonclientmouseevent write fonclientmouseevent; + published + property optionswidget default defaultoptionswidgettab; + property optionswidget1 default defaultoptionswidget1tab; + end; + + tcustomtabbar1 = class(tcustomtabbar) + protected + procedure internalcreateframe; override; + end; + + ttabbar = class(tcustomtabbar,istatfile) + private + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: integer; + procedure setstatfile(const Value: tstatfile); + procedure setdragcontroller(const Value: tdragcontroller); + protected + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + published + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property onstep; + property tabs; + property firsttab; + property onactivetabchange; + property ontabmoving; + property ontabmoved; + property onclientmouseevent; + property font; + property options; + property drag: tdragcontroller read fdragcontroller write setdragcontroller; + end; + + tcustomtabwidget = class; + + itabpage = interface(inullinterface)[miid_itabpage] + procedure settabwidget(const value: tcustomtabwidget); + function gettabwidget: tcustomtabwidget; + function getwidget: twidget; + function getcaption: msestring; + function gettabhint: msestring; + function gettabnoface: boolean; + function getcolortab: colorty; + function getcoloractivetab: colorty; + function getfacetab: tfacecomp; + function getfaceactivetab: tfacecomp; + function getfonttab: tfont; + function getfontactivetab: tfont; + function getimagelist: timagelist; + function getimagenr: imagenrty; + function getimagenrdisabled: imagenrty; + function getinvisible: boolean; + procedure setcolortab(const avalue: colorty); + procedure setcoloractivetab(const avalue: colorty); + procedure setfacetab(const avalue: tfacecomp); + procedure setfaceactivetab(const avalue: tfacecomp); + procedure setfonttab(const avalue: tfont); + procedure setfontactivetab(const avalue: tfont); + procedure doselect; + procedure dodeselect; + end; + + ttabpagefonttab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabpagefontactivetab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabpage = class; + getsubformeventty = procedure(const sender: ttabpage; + var submoduleclass: widgetclassty; + var instancevarpo: pwidget) of object; + initsubformeventty = procedure(const sender: ttabpage; + const asubform: twidget) of object; + + ttabpage = class(tscrollingwidget,itabpage,iimagelistinfo) + private + ftabwidget: tcustomtabwidget; + fcaption: msestring; + ftabhint: msestring; + ftabnoface: boolean; + fimagelist: timagelist; + fimagenr: integer; + fimagenrdisabled: integer; + fcolortab,fcoloractivetab: colorty; + fonselect: notifyeventty; + fondeselect: notifyeventty; + finvisible: boolean; + ffonttab: ttabpagefonttab; + ffontactivetab: ttabpagefontactivetab; + fongetsubform: getsubformeventty; + fsubform: twidget; + fsubforminstancevarpo: pwidget; + foninitsubform: initsubformeventty; + ffacetab: tfacecomp; + ffaceactivetab: tfacecomp; + ftaborderoverride: ttaborderoverride; + function getcaption: captionty; + procedure setcaption(const Value: captionty); + function gettabhint: msestring; + procedure settabhint(const avalue: msestring); + function gettabnoface: boolean; + procedure settabnoface(const avalue: boolean); + function getcolortab: colorty; + procedure setcolortab(const avalue: colorty); + function getcoloractivetab: colorty; + procedure setcoloractivetab(const avalue: colorty); + procedure settabwidget(const value: tcustomtabwidget); + function gettabwidget: tcustomtabwidget; + function gettabindex: integer; + procedure settabindex(const avalue: integer); + function getimagelist: timagelist; + procedure setimagelist(const avalue: timagelist); + function getimagenr: imagenrty; + procedure setimagenr(const avalue: imagenrty); + function getimagenrdisabled: imagenrty; + procedure setimagenrdisabled(const avalue: imagenrty); + function getinvisible: boolean; + procedure setinvisible(const avalue: boolean); + function getfonttab: tfont; + function getfontactivetab: tfont; + function getfonttab1: ttabpagefonttab; + procedure setfonttab1(const avalue: ttabpagefonttab); + procedure setfonttab(const avalue: tfont); + function isfonttabstored: boolean; + function getfontactivetab1: ttabpagefontactivetab; + procedure setfontactivetab1(const avalue: ttabpagefontactivetab); + procedure setfontactivetab(const avalue: tfont); + function isfontactivetabstored: boolean; + procedure setfacetab(const avalue: tfacecomp); + procedure setfaceactivetab(const avalue: tfacecomp); + function getfacetab: tfacecomp; + function getfaceactivetab: tfacecomp; + function isvisiblestored: boolean; + procedure settaborderoverride(const avalue: ttaborderoverride); + protected + class function classskininfo: skininfoty; override; + procedure changed; + procedure fontchanged1(const sender: tobject); + procedure visiblechanged; override; + procedure enabledchanged; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure registerchildwidget(const child: twidget); override; + procedure designselected(const selected: boolean); override; + procedure doselect; virtual; + procedure dodeselect; virtual; + procedure loaded; override; + function getisactivepage: boolean; + procedure setisactivepage(const avalue: boolean); + function nexttaborderoverride(const sender: twidget; + const down: boolean): twidget override; + procedure readstate(reader: treader) override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure initnewcomponent(const ascale: real); override; + procedure createfonttab; + procedure createfontactivetab; + property tabwidget: tcustomtabwidget read ftabwidget; + property tabindex: integer read gettabindex write settabindex; + property isactivepage: boolean read getisactivepage write setisactivepage; + property subform: twidget read fsubform; + published + property invisible: boolean read getinvisible + write setinvisible default false; + property taborderoverride: ttaborderoverride read ftaborderoverride + write settaborderoverride; + + property caption: captionty read getcaption write setcaption; + property tabhint: msestring read gettabhint write settabhint; + property tabnoface: boolean read gettabnoface + write settabnoface default false; + property colortab: colorty read getcolortab + write setcolortab default cl_default; + property coloractivetab: colorty read getcoloractivetab + write setcoloractivetab default cl_default; + property facetab: tfacecomp read getfacetab write setfacetab; + property faceactivetab: tfacecomp read getfaceactivetab + write setfaceactivetab; + property fonttab: ttabpagefonttab read getfonttab1 write setfonttab1 + stored isfonttabstored; + property fontactivetab: ttabpagefontactivetab read getfontactivetab1 + write setfontactivetab1 stored isfontactivetabstored; + property imagelist: timagelist read getimagelist write setimagelist; + property imagenr: imagenrty read getimagenr write setimagenr default -1; + property imagenrdisabled: imagenrty read getimagenrdisabled + write setimagenrdisabled default -2; + //-2 -> same as imagenr + property font: twidgetfont read getfont write setfont stored isfontstored; + property optionswidget default defaulttaboptionswidget; + property onlayout; + property onfontheightdelta; + property onshow; + property onhide; + property onselect: notifyeventty read fonselect write fonselect; + property ondeselect: notifyeventty read fondeselect write fondeselect; + property ongetsubform: getsubformeventty read fongetsubform + write fongetsubform; + property oninitsubform: initsubformeventty read foninitsubform + write foninitsubform; + property visible stored isvisiblestored default false; + property optionsskin default defaulttabpageskinoptions; + end; + + + tpagetab = class(ttab) + private + fpageintf: itabpage; + public + constructor create(const aowner: tcustomtabbar; const apage: itabpage); + function page: twidget; + end; + pagetabaty = array[0..0] of tpagetab; + ppagetabaty = ^pagetabaty; + + ttab_font = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttab_fonttab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttab_fontactivetab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tcustomtabwidget = class(tactionwidget,iobjectpicker,istatfile) + private + fobjectpicker: tobjectpicker; + factivepageindex: integer; + factivepageindex1: integer; + fonactivepagechanged: notifyeventty; + fonpageadded: widgeteventty; + fonpageremoved: widgeteventty; + ftab_size: integer; + ftab_sizemin: integer; + ftab_sizemax: integer; + fstatfile: tstatfile; + fstatvarname: msestring; + fvisiblepage: integer; + fstatpriority: integer; + procedure setstatfile(const value: tstatfile); + function getitems(const index: integer): twidget; + function getitemsintf(const index: integer): itabpage; + function getactivepageindex: integer; + procedure setactivepageindex(value: integer); + procedure setactivepageindex1(const avalue: integer); + function getactivepage: twidget; + function getactivepageintf: itabpage; + procedure setactivepage(const value: twidget); + procedure updatesize(const page: twidget); + function gettab_options: tabbaroptionsty; + procedure settab_options(const avalue: tabbaroptionsty); + function gettab_color: colorty; + procedure settab_color(const avalue: colorty); + function gettab_frame: tstepboxframe1; + procedure settab_frame(const avalue: tstepboxframe1); + function gettab_face: tface; + procedure settab_face(const avalue: tface); + procedure settab_size(const avalue: integer); + procedure settab_sizemin(const avalue: integer); + procedure settab_sizemax(const avalue: integer); + function gettab_colortab: colorty; + procedure settab_colortab(const avalue: colorty); + function gettab_coloractivetab: colorty; + procedure settab_coloractivetab(const avalue: colorty); + function gettab_frametab: ttabframe; + procedure settab_frametab(const avalue: ttabframe); + function gettab_facetab: tface; + procedure settab_facetab(const avalue: tface); + function gettab_faceactivetab: tface; + procedure settab_faceactivetab(const avalue: tface); + function checktabsizingpos(const apos: pointty): boolean; + function getidents: integerarty; + function gettab_imagepos: imageposty; + procedure settab_imagepos(const avalue: imageposty); + { + function gettab_captionframe_left: integer; + procedure settab_captionframe_left(const avalue: integer); + function gettab_captionframe_top: integer; + procedure settab_captionframe_top(const avalue: integer); + function gettab_captionframe_right: integer; + procedure settab_captionframe_right(const avalue: integer); + function gettab_captionframe_bottom: integer; + procedure settab_captionframe_bottom(const avalue: integer); + function gettab_imagedist: integer; + procedure settab_imagedist(const avalue: integer); + } + function gettab_shift: integer; + procedure settab_shift(const avalue: integer); + function gettab_optionswidget: optionswidgetty; + procedure settab_optionswidget(const avalue: optionswidgetty); + function gettab_optionswidget1: optionswidget1ty; + procedure settab_optionswidget1(const avalue: optionswidget1ty); + function gettab_font: ttab_font; + procedure settab_font(const avalue: ttab_font); + function istab_fontstored: boolean; + function gettab_fonttab: ttab_fonttab; + procedure settab_fonttab(const avalue: ttab_fonttab); + function istab_fonttabstored: boolean; + function gettab_fontactivetab: ttab_fontactivetab; + procedure set_tabfontactivetab(const avalue: ttab_fontactivetab); + function istab_fontactivetabstored: boolean; + procedure readtab_captionpos(reader: treader); + procedure readoptions(reader: treader); + procedure readtab_captionframe_left(reader: treader); + procedure readtab_captionframe_top(reader: treader); + procedure readtab_captionframe_right(reader: treader); + procedure readtab_captionframe_bottom(reader: treader); + procedure readtab_imagedist(reader: treader); + function gettab_textflags: textflagsty; + procedure settab_textflags(const avalue: textflagsty); + function gettab_width: integer; + procedure settab_width(const avalue: integer); + function gettab_widthmin: integer; + procedure settab_widthmin(const avalue: integer); + function gettab_widthmax: integer; + procedure settab_widthmax(const avalue: integer); + function gettab_optionsskin: optionsskinty; + procedure settab_optionsskin(const avalue: optionsskinty); + function getedge_level: int32; + procedure setedge_level(const avalue: int32); + function getedge_colordkshadow: colorty; + procedure setedge_colordkshadow(const avalue: colorty); + function getedge_colorshadow: colorty; + procedure setedge_colorshadow(const avalue: colorty); + function getedge_colorlight: colorty; + procedure setedge_colorlight(const avalue: colorty); + function getedge_colorhighlight: colorty; + procedure setedge_colorhighlight(const avalue: colorty); + function getedge_colordkwidth: int32; + procedure setedge_colordkwidth(const avalue: int32); + function getedge_colorhlwidth: int32; + procedure setedge_colorhlwidth(const avalue: int32); + function getedge_imagelist: timagelist; + procedure setedge_imagelist(const avalue: timagelist); + function getedge_imageoffset: int32; + procedure setedge_imageoffset(const avalue: int32); + function getedge_imagepaintshift: int32; + procedure setedge_imagepaintshift(const avalue: int32); + protected + ftabs: tcustomtabbar1; + fupdating: integer; + fpopuptab: integer; + factivepageindexdesign: integer; + procedure defineproperties(filer: tfiler) override; + procedure internaladd(const page: itabpage; aindex: integer); + procedure internalremove(const page: itabpage); + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure pagechanged(const sender: itabpage); + procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; + procedure tabchanged(const synctabindex: boolean); virtual; + procedure loaded; override; + procedure clientrectchanged; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure doactivepagechanged; virtual; + procedure dopageadded(const apage: twidget); virtual; + procedure dopageremoved(const apage: twidget); virtual; + procedure createpagetab(const sender: tcustomtabbar; + const index: integer; var tab: ttab); + procedure dokeydown(var info: keyeventinfoty); override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure dobeforepaint(const canvas: tcanvas); override; + procedure doafterpaint(const canvas: tcanvas); override; +// procedure dofontheightdelta(var delta: integer); override; + procedure doclosepage(const sender: tobject); virtual; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + function checkpickoffset(const aoffset: pointty): pointty; + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + //true if found + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure createtabframe(); + procedure createtabface(); + procedure createtabfont(); + procedure createtabframetab(); + procedure createtabfacetab(); + procedure createtabfonttab(); + procedure createtabfaceactivetab(); + procedure createtabfontactivetab(); + + procedure beginupdate; + procedure endupdate; + procedure synctofontheight; override; + function indexof(const page: twidget): integer; + function count: integer; + procedure clear; + procedure clearorder; //ident order = indexorder + procedure nextpage(newindex: integer; down: boolean); + procedure changepage(step: integer); + procedure movepage(const curindex,newindex: integer); + procedure add(const aitem: itabpage; const aindex: integer = bigint); + function pagebyname(const aname: string): twidget; + //case sensitive! + + property items[const index: integer]: twidget read getitems; default; + property itemsintf[const index: integer]: itabpage read getitemsintf; + property activepage: twidget read getactivepage write setactivepage; + property activepageintf: itabpage read getactivepageintf; + property idents: integerarty read getidents; + property activepageindex: integer read getactivepageindex + write setactivepageindex1 default -1; + property onactivepagechanged: notifyeventty read fonactivepagechanged + write fonactivepagechanged; + property onpageadded: widgeteventty read fonpageadded write fonpageadded; + property onpageremoved: widgeteventty read fonpageremoved + write fonpageremoved; + property optionswidget default defaulttaboptionswidget; + property font: twidgetfont read getfont write setfont stored isfontstored; + property fontempty: twidgetfontempty read getfontempty + write setfontempty stored isfontemptystored; + property tab_options: tabbaroptionsty read gettab_options write + settab_options default []; + property tab_frame: tstepboxframe1 read gettab_frame write settab_frame; + property tab_face: tface read gettab_face write settab_face; + property tab_color: colorty read gettab_color + write settab_color default cl_default; + property tab_colortab: colorty read gettab_colortab + write settab_colortab default cl_default; + property tab_coloractivetab: colorty read gettab_coloractivetab + write settab_coloractivetab default cl_default; + property tab_font: ttab_font read gettab_font write settab_font + stored istab_fontstored; + property tab_fonttab: ttab_fonttab read gettab_fonttab write settab_fonttab + stored istab_fonttabstored; + property tab_fontactivetab: ttab_fontactivetab read gettab_fontactivetab + write set_tabfontactivetab stored istab_fontactivetabstored; + property tab_imagepos: imageposty read gettab_imagepos write + settab_imagepos default defaultimagepos; + property tab_textflags: textflagsty read gettab_textflags write + settab_textflags default defaultcaptiontextflags; + property tab_width: integer read gettab_width write settab_width default 0; + property tab_widthmin: integer read gettab_widthmin + write settab_widthmin default 0; + property tab_widthmax: integer read gettab_widthmax + write settab_widthmax default 0; +{ + property tab_captionframe_left: integer read gettab_captionframe_left write + settab_captionframe_left default defaultcaptiondist; + property tab_captionframe_top: integer read gettab_captionframe_top write + settab_captionframe_top default defaultcaptiondist; + property tab_captionframe_right: integer read gettab_captionframe_right write + settab_captionframe_right default defaultcaptiondist; + property tab_captionframe_bottom: integer read gettab_captionframe_bottom write + settab_captionframe_bottom default defaultcaptiondist; + property tab_imagedist: integer read gettab_imagedist write settab_imagedist + default defaultimagedist; +} + property tab_shift: integer read gettab_shift write settab_shift + default defaulttabshift; + //defaulttabshift (-100) -> 1 + property tab_edge_level: int32 read getedge_level write setedge_level + default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property tab_edge_colordkshadow: colorty read getedge_colordkshadow + write setedge_colordkshadow default cl_default; + property tab_edge_colorshadow: colorty read getedge_colorshadow + write setedge_colorshadow default cl_default; + property tab_edge_colorlight: colorty read getedge_colorlight + write setedge_colorlight default cl_default; + property tab_edge_colorhighlight: colorty read getedge_colorhighlight + write setedge_colorhighlight default cl_default; + property tab_edge_colordkwidth: int32 read getedge_colordkwidth + write setedge_colordkwidth default -1; + //-1 = default + property tab_edge_colorhlwidth: int32 read getedge_colorhlwidth + write setedge_colorhlwidth default -1; + //-1 = default + property tab_edge_imagelist: timagelist read getedge_imagelist + write setedge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property tab_edge_imageoffset: int32 read getedge_imageoffset + write setedge_imageoffset default 0; + property tab_edge_imagepaintshift: int32 read getedge_imagepaintshift + write setedge_imagepaintshift default 0; + + property tab_frametab: ttabframe read gettab_frametab write settab_frametab; + property tab_facetab: tface read gettab_facetab write settab_facetab; + property tab_faceactivetab: tface read gettab_faceactivetab + write settab_faceactivetab; + property tab_size: integer read ftab_size write settab_size; + property tab_sizemin: integer read ftab_sizemin write settab_sizemin + default defaulttabsizemin; + property tab_sizemax: integer read ftab_sizemax write settab_sizemax + default defaulttabsizemax; + property tab_optionswidget: optionswidgetty read gettab_optionswidget + write settab_optionswidget default defaultoptionswidgettab; + property tab_optionsskin: optionsskinty read gettab_optionsskin + write settab_optionsskin default []; + property tab_optionswidget1: optionswidget1ty read gettab_optionswidget1 + write settab_optionswidget1 default defaultoptionswidget1tab; + + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + end; + + ttabwidget = class(tcustomtabwidget) + published + property optionswidget; + property optionswidget1; + property optionsskin default defaulttaboptionsskin; + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property color; + property cursor; + property frame; + property face; + property anchors; + property taborder; + property hint; + property popupmenu; + property onpopup; + property onshowhint; + + property enabled; + property visible; + + property activepageindex; + property onactivepagechanged; + property onpageadded; + property onpageremoved; + property font; + property fontempty; + property tab_options; + property tab_font; + property tab_fonttab; + property tab_fontactivetab; + property tab_frame; + property tab_face; + property tab_color; + property tab_imagepos; + property tab_textflags; + property tab_width; + property tab_widthmin; + property tab_widthmax; + { + property tab_captionframe_left; + property tab_captionframe_top; + property tab_captionframe_right; + property tab_captionframe_bottom; + property tab_imagedist; + } + property tab_shift; + property tab_edge_level; + property tab_edge_colordkshadow; + property tab_edge_colorshadow; + property tab_edge_colorlight; + property tab_edge_colorhighlight; + property tab_edge_colordkwidth; + property tab_edge_colorhlwidth; + property tab_edge_imagelist; + property tab_edge_imageoffset; + property tab_colortab; + property tab_coloractivetab; + property tab_frametab; + property tab_facetab; + property tab_faceactivetab; + property tab_sizemin; + property tab_sizemax; + property tab_size; + property tab_optionswidget; + property tab_optionswidget1; + property tab_optionsskin; + property tab_edge_imagepaintshift; + property statfile; + property statvarname; + property statpriority; + end; + +implementation +uses + sysutils,msearrayutils,msekeyboard,msestockobjects,msebits; + +type + twidget1 = class(twidget); + tmsecomponent1 = class(tmsecomponent); + tcustomstepframe1 = class(tcustomstepframe); + ttabframe1 = class(ttabframe); + ttaborderoverride1 = class(ttaborderoverride); + +procedure calctablayout(var layout: tabbarlayoutinfoty; + const canvas: tcanvas; const focused: boolean); + +var + horzimage: boolean; + vertimage: boolean; + imagedi: int32; + imagedi1: int32; + imagedi2: int32; + + procedure docommon(const tab: ttab; var cell: shapeinfoty; var textrect: rectty); + begin + with tab,cell,ca do begin + caption:= frichcaption; + textflags:= layout.tabs.ftextflags; + imagedist:= imagedi; + imagedist1:= imagedi1; + imagedist2:= imagedi2; + imagepos:= layout.tabs.fimagepos;//captiontoimagepos[layout.tabs.fcaptionpos]; + imagelist:= fimagelist; + imagenr:= fimagenr; + imagenrdisabled:= fimagenrdisabled; + if imagelist <> nil then begin + if not vertimage then begin + inc(textrect.cx,fimagelist.width+imagedist); + end; + if not horzimage then begin + inc(textrect.cy,fimagelist.height+imagedist); + end; + end; + facetemplate:= nil; + if ts_active in fstate then begin + if tab.faceactive <> nil then begin + facetemplate:= tab.faceactive.template; + end; + end + else begin + if tab.face <> nil then begin + facetemplate:= tab.face.template; + end; + end; + end; + end; //docommon + + procedure dofont(const tab: ttab; var cell: shapeinfoty); + begin + with tab,cell,ca do begin + if ts_active in tab.state then begin + font:= tab.fontactive; + end + else begin + font:= tab.font; + end; + end; + end; //dofont + +var + int1,int2: integer; + asize: integer; + aval: integer; + endval: integer; + rect1: rectty; + bo1: boolean; + cxinflate: integer; + cyinflate: integer; + cxsizeinflate: integer; + cysizeinflate: integer; + frame1: framety; + textflags1: textflagsty; + negtabshift1: boolean; + tabshift1: int32; + edgesize: int32; + normpos,normsize: int32; + extraspace1: int32; + extra1: int32; + imageinflate: int32; + i1: int32; + maximagesize: int32; + +begin + with layout do begin + horzimage:= tabs.imagepos in horzimagepos; + vertimage:= tabs.imagepos in vertimagepos; + cells:= nil; + setlength(cells,tabs.count); + if firsttab > high(cells) then begin + firsttab:= 0; + end; + lasttab:= -1; + edgesize:= tabs.getedgeshift(); + textflags1:= tabs.textflags - [tf_ellipseleft,tf_ellipseright]; + tabshift1:= tabs.ftabshift; + negtabshift1:= tabshift1 < 0; + if tabs.fframe <> nil then begin + with tabs.fframe do begin + extraspace1:= extraspace; +// captionframe:= nullframe; + captionframe:= framei; + imagedi:= imagedist; + imagedi1:= imagedist1; + imagedi2:= imagedist2; + end; + end + else begin + extraspace1:= 0; + captionframe.left:= defaultcaptiondist; + captionframe.top:= defaultcaptiondist; + captionframe.right:= defaultcaptiondist; + captionframe.bottom:= defaultcaptiondist; + imagedi:= defaultimagedist; + imagedi1:= 0; + imagedi2:= 0; + end; + cxinflate:= captionframe.left + captionframe.right + 2; //for not flat button + cyinflate:= captionframe.top + captionframe.bottom + 2; //for not flat button + imageinflate:= imagedi1 + imagedi2 + 2; //for not flat button + if tabs.fframe <> nil then begin + with tabs.fframe do begin + frame1:= frameo; + cxinflate:= cxinflate + frame1.left + frame1.right + frameframecx; + cyinflate:= cyinflate + frame1.top + frame1.bottom + frameframecy; + if fso_flat in optionsskin then begin + cxinflate:= cxinflate - 2; + cyinflate:= cyinflate - 2; + imageinflate:= imageinflate - 2; + end; + end; + end; + + cxsizeinflate:= cxinflate; + cysizeinflate:= cyinflate; + if shs_vert in options then begin + cxsizeinflate:= cxsizeinflate + edgesize; + normsize:= dim.cx - edgesize; + normpos:= dim.x; + if negtabshift1 then begin + cxsizeinflate:= cxsizeinflate - tabshift1; + normsize:= normsize + tabshift1; + end; + if shs_opposite in options then begin + normpos:= normpos + edgesize; + end + else begin + if negtabshift1 then begin + normpos:= normpos - tabshift1; + end; + end; + end + else begin + cysizeinflate:= cysizeinflate + edgesize; + normsize:= dim.cy - edgesize; + normpos:= dim.y; + if negtabshift1 then begin + cysizeinflate:= cysizeinflate - tabshift1; + normsize:= normsize + tabshift1; + end; + if shs_opposite in options then begin + normpos:= normpos + edgesize; + end + else begin + if negtabshift1 then begin + normpos:= normpos - tabshift1; + end; + end; + end; + if shs_vert in options then begin + totsize.cx:= 0; + aval:= dim.y; + asize:= aval; + endval:= dim.y + dim.cy; + for int1:= 0 to high(cells) do begin + with tabs[int1],cells[int1],ca do begin + extra1:= 0; + if int1 <> 0 then begin + aval:= aval + extraspace1; + end; + if int1 <> high(cells) then begin + extra1:= extraspace1; + end; + dim.y:= aval; + dofont(tabs[int1],cells[int1]); + rect1:= textrect(canvas,frichcaption, + makerect(normpos,aval,normsize-cxinflate,bigint), + textflags1,font); + docommon(tabs[int1],cells[int1],rect1); + if rect1.cx > totsize.cx then begin + totsize.cx:= rect1.cx; + end; + if rect1.cx <= layout.dim.cx - cxinflate then begin + textflags:= textflags - [tf_ellipseleft,tf_ellipseright]; + exclude(fstate,ts_captionclipped); + end + else begin + include(fstate,ts_captionclipped); + end; + dim.cy:= rect1.cy+cyinflate; + if (imagelist <> nil) and not vertimage and + (imagelist.height+imageinflate > dim.cy) then begin + dim.cy:= imagelist.height+imageinflate; + end; + bo1:= (ts_invisible in fstate) or (int1 < firsttab); + if bo1 or (aval >= endval) then begin + include(state,shs_invisible); + if not bo1 then begin + inc(asize,dim.cy+extra1); + end; + end + else begin + inc(aval,dim.cy); + inc(asize,dim.cy+extra1); + if (aval <= endval) then begin + lasttab:= int1; + end; + end; + if ts_active in fstate then begin + dim.cx:= layout.dim.cx; + if not negtabshift1 then begin + dim.cx:= dim.cx - tabshift1; + if not (shs_opposite in options) then begin + dim.x:= tabshift1; + end; + end; + end + else begin + dim.x:= normpos; + dim.cx:= normsize; + end; + dim.x:= dim.x + layout.dim.x; + end; + end; + totsize.cy:= asize-dim.y; + totsize.cx:= totsize.cx + cxsizeinflate; + end + else begin //horizontal + aval:= dim.x; + asize:= aval; + endval:= dim.x + dim.cx; + totsize.cy:= 0; + maximagesize:= 0; + for int1:= 0 to high(cells) do begin + with tabs[int1],cells[int1],ca do begin + extra1:= 0; + if int1 <> 0 then begin + aval:= aval + extraspace1; + end; + if int1 <> high(cells) then begin + extra1:= extraspace1; + end; + dim.x:= aval; + dofont(tabs[int1],cells[int1]); + rect1:= textrect(canvas,frichcaption, + makerect(aval,normpos,bigint,normsize-cyinflate), + textflags1,font); + docommon(tabs[int1],cells[int1],rect1); + if rect1.cy > totsize.cy then begin + totsize.cy:= rect1.cy; + end; + int2:= rect1.cx; + with layout.tabs do begin + if width <> 0 then begin + int2:= width; + end; + if (widthmax <> 0) and (rect1.cx > widthmax) then begin + int2:= widthmax; + end; + if (widthmin <> 0) and (rect1.cx < widthmin) then begin + int2:= widthmin; + end; + end; + if int2 >= rect1.cx then begin + textflags:= textflags - [tf_ellipseleft,tf_ellipseright]; + exclude(fstate,ts_captionclipped); + end + else begin + include(fstate,ts_captionclipped); + end; + rect1.cx:= int2; + + dim.cx:= rect1.cx + cxinflate; + if (imagelist <> nil) then begin + i1:= imagelist.height; + if not vertimage then begin + i1:= i1 + imageinflate; + if i1 > maximagesize then begin + maximagesize:= i1; + end; + end; + end; + bo1:= (ts_invisible in fstate) or (int1 < firsttab); + if bo1 or (aval >= endval) then begin + include(state,shs_invisible); + if not bo1 then begin + inc(asize,dim.cx+extra1); + end; + end + else begin + inc(aval,dim.cx); + inc(asize,dim.cx+extra1); + if (aval <= endval) then begin + lasttab:= int1; + end; + end; + if ts_active in fstate then begin + dim.cy:= layout.dim.cy; + if not negtabshift1 then begin + dim.cy:= dim.cy - tabshift1; + if not (shs_opposite in options) then begin + dim.y:= tabshift1; + end; + end; + end + else begin + dim.y:= normpos; + dim.cy:= normsize; + end; + dim.y:= dim.y + layout.dim.y; + end; + end; + totsize.cx:= asize-dim.x; + if totsize.cy = 0 then begin + totsize.cy:= twidget1(tabs.fowner).getfont1.glyphheight; + end; + totsize.cy:= totsize.cy + cysizeinflate; + maximagesize:= maximagesize + cysizeinflate - cyinflate; + //space for tabshift and edge + if totsize.cy < maximagesize then begin + totsize.cy:= maximagesize; + end; + end; //horizontal + bo1:= not twidget(tabs.fowner).isenabled; + for int1:= 0 to high(cells) do begin + with tabs[int1],cells[int1],ca do begin + state:= (state + [shs_showfocusrect] + options * [shs_vert,shs_opposite]) - + [shs_focused]; + if ts_active in fstate then begin + include(state,shs_active); + if focused then begin + state:= state + [shs_focused]; + end; + if fcoloractive = cl_default then begin + color:= tabs.fcoloractive; + end + else begin + color:= fcoloractive; + end; + if color = cl_default then begin + color:= defaultcoloractivetab; + end; + coloractive:= color; + face:= tabs.ffaceactive; + end + else begin + exclude(state,shs_active); + if fcolor = cl_default then begin + color:= tabs.fcolor; + end + else begin + color:= fcolor; + end; + if color = cl_default then begin + color:= defaultcolortab; + end; + face:= tabs.face; + end; + if ts_noface in fstate then begin + face:= nil; + end; + if bo1 or (ts_disabled in fstate) then begin + include(state,shs_disabled); + end; + doexecute:= {$ifdef FPC}@{$endif}execute; + end; + end; + with stepinfo do begin + up:= 0; + for int1:= firsttab to high(cells) do begin + if not (shs_invisible in cells[int1].state) and (up = 0) then begin + up:= int1-firsttab; + break; + end; + end; + if up = 0 then begin + up:= 1; + end; + pageup:= lasttab - firsttab + 1; + if firsttab = 0 then begin + pagedown:= 0; + end + else begin + pagedown:= 1; + end; + aval:= 0; + pagelast:= 0; + endval:= 0; + down:= 0; + if shs_vert in options then begin + for int1:= firsttab - 1 downto 0 do begin + with cells[int1].ca do begin + dec(pagedown); + if not (ts_invisible in tabs[int1].fstate) then begin + inc(aval,dim.cy); + if down = 0 then begin + down:= int1-firsttab; + end; + end; + end; + if aval >= dim.cy then begin + break; + end; + if int1 = 0 then begin + dec(pagedown); + end; + end; + for int1:= high(cells) downto 0 do begin + with cells[int1].ca do begin + inc(pagelast); + if not (ts_invisible in tabs[int1].fstate) then begin + inc(endval,dim.cy); + end; + end; + if endval >= dim.cy then begin + break; + end; + end; + if endval > dim.cy then begin + dec(pagelast); + end; + end + else begin + for int1:= firsttab - 1 downto 0 do begin + with cells[int1].ca do begin + dec(pagedown); + if not (ts_invisible in tabs[int1].fstate) then begin + inc(aval,dim.cx); + if down = 0 then begin + down:= int1-firsttab; + end; + end; + end; + if aval >= dim.cx then begin + break; + end; + if int1 = 0 then begin + dec(pagedown); + end; + end; + for int1:= high(cells) downto 0 do begin + with cells[int1].ca do begin + inc(pagelast); + if not (ts_invisible in tabs[int1].fstate) then begin + inc(endval,dim.cx); + end; + end; + if endval >= dim.cx then begin + break; + end; + end; + if endval > dim.cx then begin + dec(pagelast); + end; + end; + if down = 0 then begin + down:= -1; + end; + pagelast:= length(cells)-pagelast-firsttab; + end; + inc(lasttab); + notfull:= lasttab > high(cells); + if notfull then begin + lasttab:= high(cells); + end; + end; +end; + +{ ttabfont } + +class function ttabfont.getinstancepo(owner: tobject): pfont; +begin + result:= @ttab(owner).ffont; +end; + +{ ttabfontactive } + +class function ttabfontactive.getinstancepo(owner: tobject): pfont; +begin + result:= @ttab(owner).ffontactive; +end; + +{ ttab } + +constructor ttab.create(const aowner: tcustomtabbar); +begin + fcolor:= cl_default; + fcoloractive:= cl_default; + fimagenr:= -1; + fimagenrdisabled:= -2; + inherited create(aowner,aowner.flayoutinfo.tabs); +end; + +destructor ttab.destroy; +begin + ffont.free; + ffontactive.free; + inherited; +end; + +procedure ttab.changed; +begin + if not (ts_updating in fstate) then begin + tcustomtabbar(fowner).tabchanged(self); + end; +end; + +procedure ttab.createfont; +begin + if ffont = nil then begin + ffont:= ttabfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function ttab.getfont: ttabfont; +begin + getoptionalobject(ttabbar(fowner).componentstate,ffont, + {$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= ttabfont(pointer(ttabs(prop).getfont)); + end; +end; + +procedure ttab.setfont(const avalue: ttabfont); +begin + if avalue <> ffont then begin + setoptionalobject(ttabbar(fowner).ComponentState,avalue,ffont, + {$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function ttab.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +procedure ttab.createfontactive; +begin + if ffontactive = nil then begin + ffontactive:= ttabfontactive.create; + ffontactive.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function ttab.getfontactive: ttabfontactive; +begin + getoptionalobject(ttabbar(fowner).componentstate,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + if ffontactive <> nil then begin + result:= ffontactive; + end + else begin + result:= ttabfontactive(pointer(ttabs(prop).getfontactive)); + end; +end; + +procedure ttab.setfontactive(const avalue: ttabfontactive); +begin + if avalue <> ffontactive then begin + setoptionalobject(ttabbar(fowner).ComponentState,avalue,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + changed; + end; +end; + +function ttab.isfontactivestored: boolean; +begin + result:= ffontactive <> nil; +end; + +{ +function ttab.getcaption: captionty; +begin + result:= richstringtocaption(fcaption); +end; +} +procedure ttab.setcaption(const avalue: captionty); +begin + fcaption:= avalue; + captiontorichstring(avalue,frichcaption); + changed; +end; + +function ttab.tabbar: tcustomtabbar; +begin + result:= tcustomtabbar(fowner); +end; + +procedure ttab.setstate(const Value: tabstatesty); +begin + if fstate <> value then begin + fstate := Value; + { + if (fstate * [ts_invisible,ts_disabled] <> []) and + not (csdesigning in tcustomtabbar(fowner).componentstate) then begin + exclude(fstate,ts_active); + end; + } + changed; + end; +end; + +procedure ttab.execute(const tag: integer; const info: mouseeventinfoty); +begin + tabbar.tabclicked(self,info); +end; + +procedure ttab.doshortcut(var info: keyeventinfoty; const sender: twidget); +begin + if checkshortcut(info,fcaption,true) then begin + active:= true; + end; +end; + +procedure ttab.setcolor(const Value: colorty); +begin + if fcolor <> value then begin + fcolor := Value; + changed; + end; +end; + +procedure ttab.setcoloractive(const Value: colorty); +begin + if fcoloractive <> value then begin + fcoloractive := Value; + changed; + end; +end; + +procedure ttab.setface(const avalue: tfacecomp); +begin + if fface <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fface)); + changed(); + end; +end; + +procedure ttab.setfaceactive(const avalue: tfacecomp); +begin + if ffaceactive <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffaceactive)); + changed(); + end; +end; + +function ttab.getactive: boolean; +begin + result:= ts_active in fstate; +end; + +procedure ttab.setactive(const Value: boolean); +begin + if value then begin + state:= fstate + [ts_active]; + end + else begin + state:= fstate - [ts_active]; + end; +end; + +procedure ttab.setimagelist(const avalue: timagelist); +begin + if avalue <> fimagelist then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + changed; + end; +end; + +procedure ttab.setimagenr(const avalue: imagenrty); +begin + if fimagenr <> avalue then begin + fimagenr:= avalue; + changed; + end; +end; + +procedure ttab.setimagenrdisabled(const avalue: imagenrty); +begin + if fimagenrdisabled <> avalue then begin + fimagenrdisabled:= avalue; + changed; + end; +end; + +procedure ttab.objectevent(const sender: tobject; const event: objecteventty); +begin + inherited; + if event = oe_destroyed then begin + if sender = fimagelist then begin + fimagelist:= nil; + changed(); + end; + if sender = fface then begin + fface:= nil; + changed(); + end; + if sender = ffaceactive then begin + ffaceactive:= nil; + changed(); + end; + end + else begin + if event = oe_changed then begin + changed; + end; + end; +end; + +function ttab.getimagelist: timagelist; +begin + result:= fimagelist; +end; + +procedure ttab.fontchanged(const sender: tobject); +begin + changed; +end; +{ +procedure ttab.setwidth(const avalue: integer); +begin + if fwidth <> avalue then begin + fwidth:= avalue; + changed; + end; +end; + +procedure ttab.setwidthmin(const avalue: integer); +begin + if fwidthmin <> avalue then begin + fwidthmin:= avalue; + changed; + end; +end; + +procedure ttab.setwidthmax(const avalue: integer); +begin + if fwidthmax <> avalue then begin + fwidthmax:= avalue; + changed; + end; +end; +} +{ ttabframe } + +constructor ttabframe.create(const aintf: iframe); +begin + fi.innerframe.left:= defaultcaptiondist; + fi.innerframe.top:= defaultcaptiondist; + fi.innerframe.right:= defaultcaptiondist; + fi.innerframe.bottom:= defaultcaptiondist; + fi.imagedist:= defaultimagedist; + inherited; + include(fstate,fs_needsmouseinvalidate); +end; + +{ ttabsfont } + +class function ttabsfont.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabs(owner).ffont; +end; + +{ ttabsfontactive } + +class function ttabsfontactive.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabs(owner).ffontactive; +end; + +{ ttabs } + +constructor ttabs.create(const aowner: tcustomtabbar; + aclasstype: indexpersistentclassty); +begin + fcolor:= cl_default; + fcoloractive:= cl_default; + fimagepos:= defaultimagepos; + ftextflags:= defaultcaptiontextflags; + { + fcaptionframe.left:= defaultcaptiondist; + fcaptionframe.top:= defaultcaptiondist; + fcaptionframe.right:= defaultcaptiondist; + fcaptionframe.bottom:= defaultcaptiondist; + fimagedist:= defaultimagedist; + } + fshift:= defaulttabshift; + ftabshift:= 1; + fedge_level:= defaultedgelevel; + initdefaultvalues(fedge); + inherited create(aowner,aclasstype); +end; + +destructor ttabs.destroy; +begin + fface.free; + ffaceactive.free; + fframe.free; + ffont.free; + ffontactive.free; + inherited; +end; + +class function ttabs.getitemclasstype: persistentclassty; +begin + result:= ttab; +end; + +procedure ttabs.readcaptionpos(reader: treader); +begin + imagepos:= readcaptiontoimagepos(reader); +end; + +procedure ttabs.readcaptionframe_left(reader: treader); +begin + createframe(); + ttabframe1(fframe).fi.innerframe.left:= reader.readinteger; +end; + +procedure ttabs.readcaptionframe_top(reader: treader); +begin + createframe(); + ttabframe1(fframe).fi.innerframe.top:= reader.readinteger; +end; + +procedure ttabs.readcaptionframe_right(reader: treader); +begin + createframe(); + ttabframe1(fframe).fi.innerframe.right:= reader.readinteger; +end; + +procedure ttabs.readcaptionframe_bottom(reader: treader); +begin + createframe(); + ttabframe1(fframe).fi.innerframe.bottom:= reader.readinteger; +end; + +procedure ttabs.readimagedist(reader: treader); +begin + createframe(); + ttabframe1(fframe).fi.imagedist:= reader.readinteger; +end; + +procedure ttabs.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('captionpos', @readcaptionpos,nil,false); + filer.defineproperty('captionframe_left', @readcaptionframe_left,nil,false); + filer.defineproperty('captionframe_top', @readcaptionframe_top,nil,false); + filer.defineproperty('captionframe_right', @readcaptionframe_right,nil,false); + filer.defineproperty('captionframe_bottom', @readcaptionframe_bottom,nil,false); + filer.defineproperty('imagedist', @readimagedist,nil,false); +end; + +procedure ttabs.changed; +begin + tcustomtabbar(fowner).layoutchanged; +end; + +procedure ttabs.createface; +begin + if fface = nil then begin + fface:= tface.create(iface(tcustomtabbar(fowner))); + end; +end; + +procedure ttabs.createfaceactive; +begin + if ffaceactive = nil then begin + ffaceactive:= tface.create(iface(tcustomtabbar(fowner))); + end; +end; + +function ttabs.getface: tface; +begin + tcustomtabbar(fowner).getoptionalobject(fface,{$ifdef FPC}@{$endif}createface); + result:= fface; +end; + +procedure ttabs.setface(const avalue: tface); +begin + tcustomtabbar(fowner).setoptionalobject(avalue,fface,{$ifdef FPC}@{$endif}createface); + changed; +end; + +function ttabs.getfaceactive: tface; +begin + tcustomtabbar(fowner).getoptionalobject(ffaceactive, + {$ifdef FPC}@{$endif}createfaceactive); + result:= ffaceactive; +end; + +procedure ttabs.setfaceactive(const avalue: tface); +begin + tcustomtabbar(fowner).setoptionalobject(avalue,ffaceactive, + {$ifdef FPC}@{$endif}createfaceactive); + changed; +end; + +procedure ttabs.setcolor(const avalue: colorty); +begin + if avalue <> fcolor then begin + fcolor:= avalue; + changed; + end; +end; + +procedure ttabs.setcoloractive(const avalue: colorty); +begin + if avalue <> fcoloractive then begin + fcoloractive:= avalue; + changed; + end; +end; + +procedure ttabs.setimagepos(const avalue: imageposty); +begin + if avalue <> fimagepos then begin + fimagepos:= avalue; + changed; + end; +end; + +procedure ttabs.settextflags(const avalue: textflagsty); +begin + if avalue <> ftextflags then begin + ftextflags:= checktextflags(ftextflags,avalue); + changed; + end; +end; + +procedure ttabs.setwidth(const avalue: integer); +begin + if avalue <> fwidth then begin + fwidth:= avalue; + changed; + end; +end; + +procedure ttabs.setwidthmin(const avalue: integer); +begin + if avalue <> fwidthmin then begin + fwidthmin:= avalue; + changed; + end; +end; + +procedure ttabs.setwidthmax(const avalue: integer); +begin + if avalue <> fwidthmax then begin + fwidthmax:= avalue; + changed; + end; +end; + +procedure ttabs.setedge_level(const avalue: int32); +begin + if avalue <> fedge_level then begin + fedge_level:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colordkshadow(const avalue: colorty); +begin + if avalue <> fedge.shadow.effectcolor then begin + fedge.shadow.effectcolor:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colorshadow(const avalue: colorty); +begin + if avalue <> fedge.shadow.color then begin + fedge.shadow.color:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colorlight(const avalue: colorty); +begin + if avalue <> fedge.light.color then begin + fedge.light.color:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colorhighlight(const avalue: colorty); +begin + if avalue <> fedge.light.effectcolor then begin + fedge.light.effectcolor:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colordkwidth(const avalue: int32); +begin + if avalue <> fedge.shadow.effectwidth then begin + fedge.shadow.effectwidth:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colorhlwidth(const avalue: int32); +begin + if avalue <> fedge.light.effectwidth then begin + fedge.light.effectwidth:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_imagelist(const avalue: timagelist); +begin + if avalue <> fedge_imagelist then begin + tcustomtabbar(fowner).setlinkedvar(avalue,tmsecomponent(fedge_imagelist)); + changed(); + end; +end; + +procedure ttabs.setedge_imageoffset(const avalue: int32); +begin + if avalue <> fedge_imageoffset then begin + fedge_imageoffset:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_imagepaintshift(const avalue: int32); +begin + if avalue <> fedge_imagepaintshift then begin + fedge_imagepaintshift:= avalue; + changed(); + end; +end; +{ +procedure ttabs.setcaptionframe_left(const avalue: integer); +begin + if avalue <> fcaptionframe.left then begin + fcaptionframe.left:= avalue; + changed; + end; +end; + +procedure ttabs.setcaptionframe_top(const avalue: integer); +begin + if avalue <> fcaptionframe.top then begin + fcaptionframe.top:= avalue; + changed; + end; +end; + +procedure ttabs.setcaptionframe_right(const avalue: integer); +begin + if avalue <> fcaptionframe.right then begin + fcaptionframe.right:= avalue; + changed; + end; +end; + +procedure ttabs.setcaptionframe_bottom(const avalue: integer); +begin + if avalue <> fcaptionframe.bottom then begin + fcaptionframe.bottom:= avalue; + changed; + end; +end; + +procedure ttabs.setimagedist(const avalue: integer); +begin + if avalue <> fimagedist then begin + fimagedist:= avalue; + changed; + end; +end; +} +procedure ttabs.setshift(const avalue: integer); +begin + if avalue <> fshift then begin + fshift:= avalue; + if avalue = defaulttabshift then begin + ftabshift:= 1; + end + else begin + ftabshift:= avalue; + end; + changed; + end; +end; + +procedure ttabs.add(const item: ttab); +begin + inherited add(item); +end; + +procedure ttabs.insert(const item: ttab; const aindex: integer); +begin + tcustomtabbar(fowner).beginupdate; + try + inherited add(item); + move(count-1,aindex); + finally + tcustomtabbar(fowner).endupdate + end; +end; + +procedure ttabs.additems(const aitems: msestringarty); +var + int1,int2: integer; + +begin + tcustomtabbar(fowner).beginupdate; + try + int1:= count; + count:= count + length(aitems); + for int2:= 0 to high(aitems) do begin + items[int1].caption:= aitems[int2]; + inc(int1); + end; + finally + tcustomtabbar(fowner).endupdate; + end; +end; + +procedure ttabs.createitem(const index: integer; var item: tpersistent); +begin + if item = nil then begin + if assigned(foncreatetab) then begin + foncreatetab(tcustomtabbar(fowner),index,ttab(item)); + end; + if item = nil then begin + item:= ttab.create(tcustomtabbar(fowner)); + end; + end; + ttab(item).findex:= index; +end; + +function ttabs.getitems(const index: integer): ttab; +begin + result:= ttab(inherited items[index]); +end; + +function ttabs.indexof(const item: ttab): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(fitems) do begin + if items[int1] = item then begin + result:= int1; + break; + end; + end; +end; + +procedure ttabs.setitems(const index: integer; const Value: ttab); +begin + inherited items[index].assign(value); +end; + +procedure ttabs.checktemplate(const sender: tobject); +begin + if frame <> nil then begin + fframe.checktemplate(sender); + end; + if fface <> nil then begin + fface.checktemplate(sender); + end; + if ffaceactive <> nil then begin + ffaceactive.checktemplate(sender); + end; +end; + +// iframe + +procedure ttabs.setframeinstance(instance: tcustomframe); +begin + fframe:= ttabframe(instance); +end; + +procedure ttabs.setstaticframe(value: boolean); +begin + //dummy +end; + +function ttabs.getstaticframe: boolean; +begin + result:= false; +end; + +function ttabs.getwidgetrect: rectty; +begin + result:= nullrect; +end; + +function ttabs.getcomponentstate: tcomponentstate; +begin + result:= tcustomtabbar(fowner).componentstate; +end; + +function ttabs.getmsecomponentstate: msecomponentstatesty; +begin + result:= tcustomtabbar(fowner).msecomponentstate; +end; + +procedure ttabs.scrollwidgets(const dist: pointty); +begin + //dummy +end; + +procedure ttabs.clientrectchanged; +begin + changed; +end; + +procedure ttabs.invalidate; +begin + tcustomtabbar(fowner).invalidate; +end; + +procedure ttabs.invalidatewidget; +begin + tcustomtabbar(fowner).invalidatewidget; +end; + +procedure ttabs.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + tcustomtabbar(fowner).invalidaterect(rect,org,noclip); +end; + +function ttabs.getwidget: twidget; +begin + result:= tcustomtabbar(fowner); +end; + +function ttabs.getframestateflags: framestateflagsty; +begin + with tcustomtabbar(fowner).flayoutinfo do begin + result:= shapestatetoframestate(factcellindex,cells); + if factcellindex = firsttab then begin + include(result,fsf_offset1); + end; + end; +end; + +function ttabs.getedgeshift(): int32; +begin + result:= 1; //default + if fedge_imagelist <> nil then begin + if tabo_vertical in tcustomtabbar(fowner).foptions then begin + result:= fedge_imagelist.height; + end + else begin + result:= fedge_imagelist.width; + end; + result:= result + fedge_imagepaintshift; + end + else begin + if fedge_level <> defaultedgelevel then begin + result:= fedge_level; + end; + end; +end; + +procedure ttabs.dochange(const index: integer); +begin + inherited; + if (index < 0) and (fskinupdating = 0) and (count > 0) and + not (csloading in tcustomtabbar(fowner).componentstate) then begin + tcustomtabbar(fowner).updateskin; + //could be a new item which needs skin setup + end; +end; + +function ttabs.getframe: ttabframe; +begin + tcustomtabbar(fowner).getoptionalobject(fframe, + {$ifdef FPC}@{$endif}createframe); + result:= fframe; +end; + +procedure ttabs.setframe(const avalue: ttabframe); +var int1: integer; +begin + tcustomtabbar(fowner).setoptionalobject(avalue,fframe, + {$ifdef FPC}@{$endif}createframe); + if fframe = nil then begin + with tcustomtabbar(fowner).flayoutinfo do begin + for int1:= 0 to high(cells) do begin + with cells[int1] do begin + state:= state - [shs_flat,shs_noanimation]; + end; + end; + end; + end; + changed; +// tcustomtabbar(fowner).invalidatewidget; +end; + +procedure ttabs.createframe; +begin + if fframe = nil then begin + fframe:= ttabframe.create(iframe(self)); + end; +end; + +procedure ttabs.createfont; +begin + if ffont = nil then begin + ffont:= ttabsfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function ttabs.getfont: ttabsfont; +begin + getoptionalobject(ttabbar(fowner).componentstate,ffont, + {$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= ttabsfont(pointer(ttabbar(fowner).getfont)); + end; +end; + +procedure ttabs.setfont(const avalue: ttabsfont); +begin + if avalue <> ffont then begin + setoptionalobject(ttabbar(fowner).ComponentState,avalue,ffont, + {$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function ttabs.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +procedure ttabs.createfontactive; +begin + if ffontactive = nil then begin + ffontactive:= ttabsfontactive.create; + ffontactive.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function ttabs.getfontactive: ttabsfontactive; +begin + getoptionalobject(ttabbar(fowner).componentstate,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + if ffontactive <> nil then begin + result:= ffontactive; + end + else begin + result:= ttabsfontactive(pointer(ttabbar(fowner).getfont)); + end; +end; + +procedure ttabs.setfontactive(const avalue: ttabsfontactive); +begin + if avalue <> ffontactive then begin + setoptionalobject(ttabbar(fowner).ComponentState,avalue,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + changed; + end; +end; + +function ttabs.isfontactivestored: boolean; +begin + result:= ffontactive <> nil; +end; + +procedure ttabs.fontchanged(const sender: tobject); +begin + changed; +end; + +{ tcustomtabbar } + +constructor tcustomtabbar.create(aowner: tcomponent); +begin + flayoutinfo.tabs:= ttabs.create(self,nil); + flayoutinfo.tabs.onchange:= {$ifdef FPC}@{$endif}tabschanged; + flayoutinfo.activetab:= -1; + flayoutinfo.focusedtab:= -1; + flayoutinfo.lasttab:= -1; + fhintedbutton:= -2; + inherited; + fwidgetrect.cy:= font.glyphheight + 4; + foptionswidget1:= defaultoptionswidget1tab; +end; + +destructor tcustomtabbar.destroy; +begin + killrepeater(); + flayoutinfo.tabs.free(); + inherited; +end; + +procedure tcustomtabbar.settabs(const Value: ttabs); +begin + flayoutinfo.tabs.assign(Value); +end; + +procedure tcustomtabbar.updatelayout(); +var + int1,int2,int3: integer; +begin + with flayoutinfo do begin + options:= []; + if tabo_vertical in foptions then begin + include(options,shs_vert); + end; + if tabo_opposite in foptions then begin + include(options,shs_opposite); + end; + if tabo_vertical in foptions then begin + frame.buttonpos:= sbp_top; + frame.buttonslast:= ((tabo_opposite in foptions) xor + (tabo_buttonsoutside in foptions)); + end + else begin + frame.buttonpos:= sbp_right; + frame.buttonslast:= ((tabo_opposite in foptions) xor + (tabo_buttonsoutside in foptions)); + end; + for int3:= 7 downto 0 do begin; + dim:= innerclientrect; + calctablayout(flayoutinfo,getcanvas,focused); + + int2:= tabs.count; + for int1:= int2 - 1 downto 0 do begin + if not (ts_invisible in tabs[int1].fstate) then begin + int2:= int1+1; //count to last visible + break; + end + else begin + if int1 = 0 then begin + int2:= 0; + end; + end; + end; +{ + if shs_vert in options then begin + int4:= dim.size.cy - totsize.cy + tcustomstepframe1(fframe).fdim.cy; + end + else begin + int4:= dim.size.cx - totsize.cx + tcustomstepframe1(fframe).fdim.cx; + end; + notfull:= int4 >= 0; +} + if (firsttab = 0) and notfull then begin + int2:= 0; + end; + frame.updatebuttonstate(firsttab,stepinfo.pageup,int2); + include(fstate,tbs_layoutvalid); + checkautosize; + if sizeisequal(dim.size,innerclientsize) then begin + break; + end; + end; + end; +end; + +procedure tcustomtabbar.checklayout; +begin + if not (tbs_layoutvalid in fstate) then begin + updatelayout; + end; +end; + +procedure tcustomtabbar.layoutchanged; +begin + exclude(fstate,tbs_layoutvalid); + invalidate; + { + if not (csloading in componentstate) and + not (ws_loadedproc in fwidgetstate) and + not ((owner <> nil) and + ([csloading,csdestroying]*owner.ComponentState <> [])) and + not ((fparentwidget <> nil) and + (ws_loadedproc in twidget1(fparentwidget).fwidgetstate)) then begin + //todo: support for cssubcomponent in fpc +// updatelayout; +// checkautosize; + invalidate; + end; + } +end; + +function comptabs(const l,r): integer; +begin + result:= msecomparetext(ttab(l).frichcaption.text,ttab(r).frichcaption.text); +end; + +procedure tcustomtabbar.tabchanged(const sender: ttab); + + procedure updateactivetabindex; + var + int1: integer; + bo1: boolean; + begin + with flayoutinfo do begin + bo1:= false; + for int1:= 0 to tabs.count - 1 do begin + with tabs[int1] do begin + if ts_active in fstate then begin + bo1:= true; + if (activetab <> int1) then begin + if (activetab >= 0) and (activetab <= high(tabs.fitems)) then begin + exclude(tabs.items[activetab].fstate,ts_active); + end; + activetab:= int1; + end; + end; + end; + end; + if not bo1 then begin + activetab:= -1; + end; + end; + end; + +var + int1,int2: integer; + bo1: boolean; + activetabbefore: integer; +begin + if fupdating = 0 then begin + with flayoutinfo do begin + activetabbefore:= activetab; + updateactivetabindex; + bo1:= activetabbefore <> activetab; + if bo1 and assigned(finternaltabchange) then begin + finternaltabchange(false); + end; + if tabo_sorted in foptions then begin + sortarray(pointerarty(flayoutinfo.tabs.fitems), + {$ifdef FPC}@{$endif}comptabs); + updateactivetabindex; + if assigned(finternaltabchange) then begin + finternaltabchange(true); + end; + end; + if bo1 then begin + if (activetab >= 0) and (activetab <= high(cells)) then begin + if (tabo_acttabfirst in foptions) and (activetab <> 0) then begin + flayoutinfo.tabs.move(activetab,0); + updateactivetabindex; + end; + if activetab < firsttab then begin + firsttab:= activetab; + end + else begin + if activetab >= firsttab + stepinfo.pageup then begin + firsttab:= activetab + 1; + int2:= 0; + if shs_vert in options then begin + for int1:= activetab downto 0 do begin + if not (ts_invisible in tabs[int1].fstate) then begin + inc(int2,cells[int1].ca.dim.cy); + if int2 >= dim.cy then begin + break; + end; + dec(firsttab); + end; + end; + end + else begin + for int1:= activetab downto 0 do begin + if not (ts_invisible in tabs[int1].fstate) then begin + inc(int2,cells[int1].ca.dim.cx); + if int2 >= dim.cx then begin + break; + end; + dec(firsttab); + end; + end; + end; + if firsttab > activetab then begin + firsttab:= activetab; + end; + end; + end; + end; + doactivetabchanged; + end; + layoutchanged; + end; + end; +end; + +procedure tcustomtabbar.tabclicked(const sender: ttab; + const info: mouseeventinfoty); +begin + if (tabo_clickedtabfirst in foptions) or + (tabo_dblclickedtabfirst in foptions) and + (ss_double in info.shiftstate) then begin + movetab(sender.findex,0); + end; + sender.active:= true; + checklayout(); + include(flayoutinfo.cells[sender.index].state,shs_mouse); +end; + +procedure tcustomtabbar.tabschanged(const sender: tarrayprop; + const index: integer); +begin + tabchanged(nil); +end; + +procedure tcustomtabbar.loaded; +begin + inherited; +// updatelayout; + doactivetabchanged; +end; + +procedure tcustomtabbar.dopaintforeground(const canvas: tcanvas); +var + int1{,int2,int3}: integer; +// color1: colorty; + rect1: rectty; + size1: sizety; + edgelevel1: int32; + hiddenedges1: edgesty; + actcell1: int32; + po1: pshapeinfoty; +begin + inherited; + checklayout; + with flayoutinfo do begin +// int1:= high(cells); + edgelevel1:= tabs.fedge_level; + if edgelevel1 = defaultedgelevel then begin + edgelevel1:= -1; + end; + actcell1:= -1; + po1:= @cells[firsttab]; + for int1:= firsttab to lasttab do begin + with po1^ do begin + if int1 = activetab then begin + actcell1:= int1; + end + else begin + tabs.factcellindex:= int1; + frame:= tabs.fframe; //todo: move to layoutcalc + if frame <> nil then begin + drawtab(canvas,po1^,nil); + end + else begin + drawtab(canvas,po1^,@captionframe); + end; + end; + end; + inc(po1); + end; + if (tabs.fedge_imagelist <> nil) or (edgelevel1 <> 0) then begin + if shs_vert in options then begin + if shs_opposite in options then begin + int1:= -4; //imagebase + hiddenedges1:= [edg_top,edg_bottom,edg_right]; + end + else begin + int1:= 0; + hiddenedges1:= [edg_left,edg_top,edg_bottom]; + end; + end + else begin + if shs_opposite in options then begin + int1:= -6; + hiddenedges1:= [edg_left,edg_bottom,edg_right]; + end + else begin + int1:= -2; + end; + end; + rect1:= paintsizerect; + size1:= tcustomstepframe1(fframe).fdim.size; //todo: button positions + if shs_vert in options then begin + rect1.y:= rect1.y - size1.cy; + rect1.cy:= rect1.cy + size1.cy; + if shs_opposite in options then begin + hiddenedges1:= [edg_top,edg_bottom,edg_right]; + end + else begin + hiddenedges1:= [edg_left,edg_top,edg_bottom]; + end; + end + else begin + rect1.cx:= rect1.cx + size1.cx; + if shs_opposite in options then begin + hiddenedges1:= [edg_left,edg_bottom,edg_right]; + end + else begin + hiddenedges1:= [edg_left,edg_top,edg_right]; + end; + end; + if edgelevel1 <> 0 then begin + draw3dframe(canvas,rect1,edgelevel1, + tabs.fedge,hiddenedges1); + end; + if tabs.fedge_imagelist <> nil then begin + drawimageframe(canvas,tabs.fedge_imagelist,tabs.fedge_imageoffset+int1, + rect1,hiddenedges1); + end; + end; + if actcell1 >= 0 then begin + tabs.factcellindex:= actcell1; + po1:= @cells[actcell1]; + po1^.frame:= tabs.fframe; //todo: move to layoutcalc + if tabs.fframe = nil then begin + drawtab(canvas,po1^,@captionframe); + end + else begin + drawtab(canvas,po1^,nil); + end; + end; + end; +end; + +function tcustomtabbar.getactivetab: integer; +begin + result:= flayoutinfo.activetab; +end; + +procedure tcustomtabbar.setactivetab(const Value: integer); +var + int1: integer; + +begin + if value < 0 then begin + if activetab >= 0 then begin + flayoutinfo.tabs.items[activetab].state:= + flayoutinfo.tabs.items[activetab].state - [ts_active]; + end; + end + else begin + int1:= value; + if int1 >= tabs.count then begin + int1:= tabs.count - 1 + end; + if int1 >= 0 then begin + flayoutinfo.tabs.items[int1].state:= + flayoutinfo.tabs.items[int1].state + [ts_active]; + end; + end; +end; + +function tcustomtabbar.activetag: integer; + //0 if no activetab, activetab.tag otherwise +begin + with flayoutinfo do begin + if activetab < 0 then begin + result:= 0; + end + else begin + result:= tabs[activetab].ftag; + end; + end; +end; + +procedure tcustomtabbar.clientmouseevent(var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) and + canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,info); + end; + inherited; + if updatemouseshapestate(flayoutinfo.cells,info,self, + flayoutinfo.focusedtab,flayoutinfo.tabs.fframe) and + (not (csdesigning in componentstate) or + (tbs_designdrag in fstate)) then begin + include(info.eventstate,es_processed); + end; + if not (csdesigning in componentstate) or + (ws1_designactive in fwidgetstate1) then begin + with flayoutinfo do begin + checkbuttonhint(self,info,fhintedbutton,cells, + {$ifdef FPC}@{$endif}getbuttonhint, + {$ifdef FPC}@{$endif}gethintpos); + end; + end; +end; + +procedure tcustomtabbar.statechanged; +begin + inherited; + with flayoutinfo do begin + if (activetab >= 0) and (activetab <= high(cells)) then begin + updatewidgetshapestate(flayoutinfo.cells[activetab],self,false,fframe); + end; + end; +end; + +procedure tcustomtabbar.doshortcut(var info: keyeventinfoty; const sender: twidget); +var + int1,int2: integer; +begin + if not (csdesigning in componentstate) then begin + int2:= activetab + 1; + if int2 >= tabs.count then begin + int2:= 0; + end; + for int1:= int2 to tabs.count - 1 do begin + if es_processed in info.eventstate then begin + break; + end; + flayoutinfo.tabs[int1].doshortcut(info,sender); + end; + for int1:= 0 to int2 - 1 do begin + if es_processed in info.eventstate then begin + break; + end; + flayoutinfo.tabs[int1].doshortcut(info,sender); + end; + end; + inherited; +end; + +procedure tcustomtabbar.clientrectchanged; +begin + inherited; + layoutchanged; +end; +{ +procedure tcustomtabbar.dofontheightdelta(var delta: integer); +begin + if not (tabo_vertical in foptions) then begin + inherited; + if delta <> 0 then begin + synctofontheight; + end; + end + else begin + layoutchanged; + end; +end; +} +procedure tcustomtabbar.fontchanged; +begin + inherited; + layoutchanged; +end; + +procedure tcustomtabbar.getautopaintsize(var asize: sizety); +begin + inherited; + checklayout; + asize.cx:= flayoutinfo.totsize.cx; + asize.cy:= flayoutinfo.totsize.cy; + addsize1(asize,innerframewidth); + if tbs_shrinktozero in fstate then begin + if tabo_vertical in foptions then begin + asize.cx:= 0; + end + else begin + asize.cy:= 0; + end; + end; +end; + +procedure tcustomtabbar.synctofontheight; +var + size1: sizety; +begin + inherited; + if not (tabo_vertical in options) then begin + size1:= paintsize; + getautopaintsize(size1); + size1:= addsize(size1,fframe.paintframedim); + bounds_cy:= size1.cy; + end; +end; + +procedure tcustomtabbar.doactivetabchanged; +begin + if canevent(tmethod(fonactivetabchange)) then begin + fonactivetabchange(self); + end; +end; + +procedure tcustomtabbar.beginupdate; +begin + inc(fupdating); +end; + +procedure tcustomtabbar.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + tabchanged(nil); + end; +end; + +function tcustomtabbar.tabatpos(const apos: pointty; const enabledonly: boolean = false): integer; +begin + begin + checklayout; + if enabledonly then begin + result:= findshapeatpos(flayoutinfo.cells,apos,[shs_invisible,shs_disabled]); + end + else begin + result:= findshapeatpos(flayoutinfo.cells,apos,[shs_invisible]); + end; + end; +end; + +procedure tcustomtabbar.movetab(curindex,newindex: integer); +begin + if canevent(tmethod(fontabmoving)) then begin + fontabmoving(self,curindex,newindex); + end; + flayoutinfo.tabs.move(curindex,newindex); + if canevent(tmethod(fontabmoved)) then begin + fontabmoved(self,curindex,newindex); + end; + if csdesigning in componentstate then begin + designchanged; + end; +end; + +function tcustomtabbar.dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; +var + stepinfo1: framestepinfoty; + i1: int32; +begin + result:= false; + if frame.canstep then begin + stepinfo1:= flayoutinfo.stepinfo; + if ss_ctrl in ashiftstate then begin + with stepinfo1 do begin //reverst step height + i1:= pagedown; + pagedown:= down; + down:= i1; + i1:= pageup; + pageup:= up; + up:= i1; + end; + if stepinfo1.pagedown < -1 then begin + stepinfo1.pagedown:= -1; + end; + if stepinfo1.pageup > 1 then begin + stepinfo1.pageup:= 1; + end; + end; + firsttab:= frame.executestepevent(event,stepinfo1,flayoutinfo.firsttab); + result:= true; + end; +end; + +procedure tcustomtabbar.setfirsttab(Value: integer); +begin + with flayoutinfo do begin + if value >= tabs.count - 1 then begin + value:= tabs.count - 1; + end; + if value < 0 then begin + value:= 0; + end; + if firsttab <> value then begin + firsttab:= value; + layoutchanged; + end; + end; +end; + +procedure tcustomtabbar.setoptions(const avalue: tabbaroptionsty); +var + optionsbefore: tabbaroptionsty; + delta: tabbaroptionsty; + ow1: optionswidget1ty; +begin + if avalue <> foptions then begin + optionsbefore:= foptions; + foptions:= avalue; + delta:= avalue >< optionsbefore; + if not (csloading in componentstate) then begin + if (csdesigning in componentstate) and + (delta * [tabo_vertical] <> []) then begin + ow1:= optionswidget1; + if tabo_vertical in avalue then begin + exclude(ow1,ow1_autowidth); + if ow1_autowidth in optionswidget1 then begin + include(ow1,ow1_autoheight); + end + else begin + exclude(ow1,ow1_autoheight); + end; + end + else begin + include(ow1,ow1_autoheight); + if ow1_autoheight in optionswidget1 then begin + include(ow1,ow1_autowidth); + end + else begin + exclude(ow1,ow1_autowidth); + end; + end; + optionswidget1:= ow1; + end; + if (delta * [tabo_sorted,tabo_acttabfirst] <> []) then begin + tabchanged(nil); + end; + end; + if delta * [tabo_vertical,tabo_opposite,tabo_buttonsoutside] <> [] then begin + layoutchanged; + end; + end; +end; + +procedure tcustomtabbar.dragevent(var info: draginfoty); +var + int1: integer; + + function candest: boolean; + begin + with info do begin + if (dragobjectpo^ is ttagdragobject) and (dragobjectpo^.sender = self) and + ((tabo_dragdest in foptions) or (csdesigning in componentstate)) then begin + int1:= tabatpos(pos,(tabo_dragdestenabledonly in foptions) and + not(csdesigning in componentstate)); + result:= (ttagdragobject(dragobjectpo^).tag <> int1) and + ((int1 >= 0) {or (csdesigning in componentstate)}); + end + else begin + result:= false; + end; + end; + end; + +begin + if not fdragcontroller.beforedragevent(info) then begin + int1:= 0; + with info do begin + case eventkind of + dek_begin: begin + if (not (csdesigning in componentstate) or (tbs_designdrag in fstate)) and + (dragobjectpo^ = nil) and not (tabo_sorted in foptions) and + ((tabo_dragsource in foptions) or (csdesigning in componentstate)) then begin + int1:= tabatpos(pos,(tabo_dragsourceenabledonly in foptions) and + not (csdesigning in componentstate)); + if int1 >= 0 then begin + ttagdragobject.create(self,dragobjectpo^,fdragcontroller.pickpos,int1); + end; + end; + end; + dek_check: begin + int1:= tabatpos(pos,false); + with flayoutinfo do begin + if (int1 < 0) or not ((int1 = firsttab) or (int1 = lasttab)) then begin + killrepeater; + end + else begin + if (frepeater = nil) or + (not(int1 = firsttab) xor (tbs_repeatup in fstate)) then begin + startrepeater(int1 <> firsttab); + end; + end; + end; + if candest then begin + accept:= true; + end; + end; + dek_drop: begin + killrepeater(); + if candest then begin + movetab(ttagdragobject(dragobjectpo^).tag,int1); + end; + end; + dek_leavewidget: begin + killrepeater(); + end; + end; + end; + end; + fdragcontroller.afterdragevent(info); + if not info.accept then begin + inherited; + end; +end; + +procedure tcustomtabbar.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if event = oe_changed then begin + flayoutinfo.tabs.checktemplate(sender); + end; +end; + +function tcustomtabbar.gethintpos(const aindex: integer): rectty; +begin + result:= flayoutinfo.cells[aindex].ca.dim; + inc(result.cy,12); +end; + +function tcustomtabbar.getbuttonhint(const aindex: integer): msestring; +begin + result:= ''; + with flayoutinfo.tabs[aindex] do begin + if hint <> '' then begin + result:= hint; + end + else begin + if (ts_captionclipped in fstate) and + (tabo_hintclippedtext in options) then begin + result:= caption; + end; + end; + end; +end; + +procedure tcustomtabbar.enabledchanged; +begin + inherited; + if not (ws_loadedproc in fwidgetstate) then begin + layoutchanged; + end; +end; + +class function tcustomtabbar.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_tabbar; +end; + +function tcustomtabbar.upstep(const norotate: boolean): boolean; +var + int1: integer; +begin + result:= false; + with flayoutinfo do begin + for int1:= activetab + 1 to high(cells) do begin + if tabs[int1].state * [ts_invisible,ts_disabled] = [] then begin + result:= true; + self.activetab:= int1; + exit; + end; + end; + if not norotate then begin + for int1:= 0 to activetab - 1 do begin + if tabs[int1].state * [ts_invisible,ts_disabled] = [] then begin + result:= true; + self.activetab:= int1; + exit; + end; + end; + end; + end; +end; + +function tcustomtabbar.downstep(const norotate: boolean): boolean; +var + int1: integer; +begin + result:= false; + with flayoutinfo do begin + for int1:= activetab -1 downto 0 do begin + if tabs[int1].state * [ts_invisible,ts_disabled] = [] then begin + result:= true; + self.activetab:= int1; + exit; + end; + end; + if not norotate then begin + for int1:= high(cells) downto activetab + 1 do begin + if tabs[int1].state * [ts_invisible,ts_disabled] = [] then begin + result:= true; + self.activetab:= int1; + exit; + end; + end; + end; + end; +end; + +function tcustomtabbar.getassistivecaption(): msestring; +begin + with flayoutinfo do begin + if (focusedtab >= 0) and (focusedtab < tabs.count) then begin + result:= tabs[focusedtab].caption; + end + else begin + result:= inherited getassistivecaption(); + end; + end; +end; + +function tcustomtabbar.getassistivehint(): msestring; +begin + with flayoutinfo do begin + if (focusedtab >= 0) and (focusedtab < tabs.count) then begin + result:= tabs[focusedtab].hint; + end + else begin + result:= inherited getassistivehint(); + end; + end; +end; + +procedure tcustomtabbar.dokeydown(var info: keyeventinfoty); +var + bo1: boolean; +begin + if not (es_processed in info.eventstate) then begin + bo1:= false; + if shs_vert in flayoutinfo.options then begin + case info.key of + key_down: begin + bo1:= upstep(ow_arrowfocusout in optionswidget); + end; + key_up: begin + bo1:= downstep(ow_arrowfocusout in optionswidget); + end; + end; + end + else begin + case info.key of + key_right: begin + bo1:= upstep(ow_arrowfocusout in optionswidget); + end; + key_left: begin + bo1:= downstep(ow_arrowfocusout in optionswidget); + end; + end; + end; + if bo1 then begin + include(info.eventstate,es_processed); + end + else begin + inherited; + end; + end; +end; + +procedure tcustomtabbar.startrepeater(const up: boolean); +begin + killrepeater; + updatebit(longword(fstate),ord(tbs_repeatup),up); + frepeater:= trepeater.create(500000,200000,@repeatproc); +end; + +procedure tcustomtabbar.killrepeater; +begin + freeandnil(frepeater); +end; + +procedure tcustomtabbar.repeatproc(const sender: tobject); +begin + if tbs_repeatup in fstate then begin + checklayout(); + if flayoutinfo.notfull then begin + killrepeater; + end + else begin + firsttab:= firsttab + 1; + end; + end + else begin + firsttab:= firsttab - 1; + end; +end; + +{ ttabbar } + +procedure ttabbar.dostatread(const reader: tstatreader); +begin + flayoutinfo.tabs.dostatread(reader,tabo_dragdest in foptions); + if reader.canstate then begin + activetab:= reader.readinteger('activetab',activetab); + end; +end; + +procedure ttabbar.dostatwrite(const writer: tstatwriter); +begin + flayoutinfo.tabs.dostatwrite(writer,tabo_dragdest in foptions); + if writer.canstate then begin + writer.writeinteger('activetab',activetab); + end; +end; + +function ttabbar.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure ttabbar.setdragcontroller(const Value: tdragcontroller); +begin + fdragcontroller.assign(Value); +end; + +procedure ttabbar.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure ttabbar.statreading; +begin + //dummy +end; + +procedure ttabbar.statread; +begin + //dummy +end; + +function ttabbar.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ ttabpagefonttab } + +class function ttabpagefonttab.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabpage(owner).ffonttab; +end; + +{ ttabpagefontactivetab } + +class function ttabpagefontactivetab.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabpage(owner).ffontactivetab; +end; + +{ ttabpage } + +constructor ttabpage.create(aowner: tcomponent); +begin + ftaborderoverride:= ttaborderoverride.create(self); + inherited; + fcolortab:= cl_default; + fcoloractivetab:= cl_default; + fimagenr:= -1; +// fimagenractive:= -2; + fimagenrdisabled:= -2; + foptionswidget:= defaulttaboptionswidget; + optionsskin:= defaulttabpageskinoptions; + exclude(fwidgetstate,ws_visible); +end; + +destructor ttabpage.destroy; +begin + inherited; + freeandnil(ffonttab); + freeandnil(ffontactivetab); + ftaborderoverride.free(); +end; + +class function ttabpage.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_tabpage; +end; + +procedure ttabpage.loaded; +begin + if fparentwidget is tcustomtabwidget then begin + include(fwidgetstate1,ws1_nodesignvisible); + end; + inherited; +end; + +procedure ttabpage.changed; +begin + if (ftabwidget <> nil) then begin + ftabwidget.pagechanged(itabpage(self)); + end; +end; + +procedure ttabpage.fontchanged1(const sender: tobject); +begin + changed; +end; + +function ttabpage.getcaption: captionty; +begin + result:= fcaption; +end; + +procedure ttabpage.setcaption(const Value: captionty); +begin + fcaption:= value; + changed; +end; + +function ttabpage.gettabhint: msestring; +begin + result:= ftabhint; +end; + +procedure ttabpage.settabhint(const avalue: msestring); +begin + ftabhint:= avalue; + changed; +end; + +function ttabpage.gettabnoface: boolean; +begin + result:= ftabnoface; +end; + +procedure ttabpage.settabnoface(const avalue: boolean); +begin + if ftabnoface <> avalue then begin + ftabnoface:= avalue; + changed; + end; +end; + +function ttabpage.getcolortab: colorty; +begin + result:= fcolortab; +end; + +procedure ttabpage.setcolortab(const avalue: colorty); +begin + if fcolortab <> avalue then begin + fcolortab:= avalue; + changed; + end; +end; + +function ttabpage.getcoloractivetab: colorty; +begin + result:= fcoloractivetab; +end; + +procedure ttabpage.setcoloractivetab(const avalue: colorty); +begin + if fcoloractivetab <> avalue then begin + fcoloractivetab:= avalue; + changed; + end; +end; + +procedure ttabpage.setfacetab(const avalue: tfacecomp); +begin + if ffacetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffacetab)); + changed(); + end; +end; + +procedure ttabpage.setfaceactivetab(const avalue: tfacecomp); +begin + if ffaceactivetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffaceactivetab)); + changed(); + end; +end; + +function ttabpage.getfacetab: tfacecomp; +begin + result:= ffacetab; +end; + +function ttabpage.getfaceactivetab: tfacecomp; +begin + result:= ffaceactivetab; +end; + +function ttabpage.isvisiblestored: boolean; +begin + result:= not (fparentwidget is tcustomtabwidget); +end; + +procedure ttabpage.settaborderoverride(const avalue: ttaborderoverride); +begin + ftaborderoverride.assign(avalue); +end; + +procedure ttabpage.registerchildwidget(const child: twidget); +begin + if child is ttabpage then begin + child.parentwidget:= parentwidget; + end + else begin + inherited; + end; +end; + +function ttabpage.gettabwidget: tcustomtabwidget; +begin + result:= ftabwidget; +end; + +procedure ttabpage.settabwidget(const value: tcustomtabwidget); +begin + ftabwidget:= value; +end; + +procedure ttabpage.visiblechanged; +begin + inherited; + changed; +end; + +procedure ttabpage.enabledchanged; +begin + inherited; + changed; +end; + +procedure ttabpage.designselected(const selected: boolean); +begin + inherited; + if selected then begin + if ftabwidget <> nil then begin + ftabwidget.activepage:= self; + end; + end; +end; + +function ttabpage.getisactivepage: boolean; +begin + result:= (ftabwidget <> nil) and (ftabwidget.activepage = self); +end; + +procedure ttabpage.setisactivepage(const avalue: boolean); +begin + if ftabwidget <> nil then begin + ftabwidget.activepage:= self; + end; +end; + +function ttabpage.nexttaborderoverride(const sender: twidget; + const down: boolean): twidget; +begin + result:= ftaborderoverride.nexttaborder(sender,down); + if result = nil then begin + result:= inherited nexttaborderoverride(sender,down); + end; +end; + +procedure ttabpage.readstate(reader: treader); +begin + inherited; + ttaborderoverride1(ftaborderoverride).endread(reader); +end; + +function ttabpage.gettabindex: integer; +begin + if tabwidget = nil then begin + result:= -1; + end + else begin + result:= tabwidget.indexof(self); + end; +end; + +procedure ttabpage.settabindex(const avalue: integer); +begin + if tabwidget <> nil then begin + tabwidget.movepage(tabindex,avalue); + end; +end; + +procedure ttabpage.doselect; +var + subformclass: widgetclassty; + po1: pwidget; + wi1: twidget; +begin + if assigned(fongetsubform) then begin + if fsubform = nil then begin + subformclass:= nil; + fsubforminstancevarpo:= nil; + fongetsubform(self,subformclass,fsubforminstancevarpo); + if subformclass <> nil then begin + po1:= fsubforminstancevarpo; + if po1 = nil then begin + po1:= @wi1; + end; + mseclasses.createmodule(self,subformclass,po1^); + setlinkedvar(po1^,tmsecomponent(fsubform)); +// setlinkedvar(subformclass.create(self),tmsecomponent(fsubform)); + insertwidget(fsubform,nullpoint); +// if fsubforminstancevarpo <> nil then begin +// fsubforminstancevarpo^:= fsubform; +// end; + if assigned(foninitsubform) then begin + foninitsubform(self,fsubform); + end; + fsubform.visible:= true; + end; + end; + end; + if assigned(fonselect) then begin + fonselect(self); + end; +end; + +procedure ttabpage.dodeselect; +begin + if canevent(tmethod(fondeselect)) then begin + fondeselect(self); + end; + if fsubform <> nil then begin + if fsubform.forceclose then begin + fsubform.free; + end + else begin + tabwidget.activepageindex:= tabindex; //reactivate + end; + end; +end; + +function ttabpage.getimagelist: timagelist; +begin + result:= fimagelist +end; + +procedure ttabpage.setimagelist(const avalue: timagelist); +begin + if fimagelist <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + changed; + end; +end; + +function ttabpage.getimagenr: imagenrty; +begin + result:= fimagenr; +end; + +procedure ttabpage.setimagenr(const avalue: imagenrty); +begin + if fimagenr <> avalue then begin + fimagenr:= avalue; + changed; + end; +end; +{ +function ttabpage.getimagenractive: integer; +begin + result:= fimagenractive; +end; + +procedure ttabpage.setimagenractive(const avalue: integer); +begin + if fimagenractive <> avalue then begin + fimagenractive:= avalue; + changed; + end; +end; +} +function ttabpage.getimagenrdisabled: imagenrty; +begin + result:= fimagenrdisabled; +end; + +procedure ttabpage.setimagenrdisabled(const avalue: imagenrty); +begin + if fimagenrdisabled <> avalue then begin + fimagenrdisabled:= avalue; + changed; + end; +end; + +function ttabpage.getinvisible: boolean; +begin + result:= finvisible; +end; + +procedure ttabpage.setinvisible(const avalue: boolean); +begin + if finvisible <> avalue then begin + finvisible:= avalue; + changed; + end; +end; + +procedure ttabpage.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_destroyed) and (sender = fsubform) then begin + if fsubforminstancevarpo <> nil then begin + fsubforminstancevarpo^:= nil; + end; + end; + if sender = fimagelist then begin + if event = oe_destroyed then begin + fimagelist:= nil; + changed; + end + else begin + if event = oe_changed then begin + changed; + end; + end; + end; +end; + +procedure ttabpage.initnewcomponent(const ascale: real); +begin + inherited; + caption:= 'caption'; +end; + +procedure ttabpage.createfonttab; +begin + if ffonttab = nil then begin + ffonttab:= ttabpagefonttab.create; + ffonttab.onchange:= {$ifdef FPC}@{$endif}fontchanged1; + end; +end; + +procedure ttabpage.createfontactivetab; +begin + if ffontactivetab = nil then begin + ffontactivetab:= ttabpagefontactivetab.create; + ffontactivetab.onchange:= {$ifdef FPC}@{$endif}fontchanged1; + end; +end; + +function ttabpage.getfonttab: tfont; +begin + result:= ffonttab; +end; + +function ttabpage.getfontactivetab: tfont; +begin + result:= ffontactivetab; +end; + +function ttabpage.getfonttab1: ttabpagefonttab; +begin + getoptionalobject(ffonttab, + {$ifdef FPC}@{$endif}createfonttab); + result:= ffonttab; +end; + +procedure ttabpage.setfonttab1(const avalue: ttabpagefonttab); +begin + if avalue <> ffonttab then begin + setoptionalobject(avalue,ffonttab, + {$ifdef FPC}@{$endif}createfonttab); + changed; + end; +end; + +procedure ttabpage.setfonttab(const avalue: tfont); +begin + setfonttab1(ttabpagefonttab(avalue)); +end; + +function ttabpage.isfonttabstored: boolean; +begin + result:= ffonttab <> nil; +end; + +function ttabpage.getfontactivetab1: ttabpagefontactivetab; +begin + getoptionalobject(ffontactivetab, + {$ifdef FPC}@{$endif}createfontactivetab); + result:= ffontactivetab; +end; + +procedure ttabpage.setfontactivetab1(const avalue: ttabpagefontactivetab); +begin + if avalue <> ffontactivetab then begin + setoptionalobject(avalue,ffontactivetab, + {$ifdef FPC}@{$endif}createfontactivetab); + changed; + end; +end; + +procedure ttabpage.setfontactivetab(const avalue: tfont); +begin + setfontactivetab1(ttabpagefontactivetab(avalue)); +end; + +function ttabpage.isfontactivetabstored: boolean; +begin + result:= ffontactivetab <> nil; +end; + + +{ +function ttabpage.gettabwidth: integer; +begin + result:= ftabwidth; +end; + +procedure ttabpage.settabwidth(const avalue: integer); +begin + ftabwidth:= avalue; + changed; +end; + +function ttabpage.gettabwidthmin: integer; +begin + result:= ftabwidthmin; +end; + +procedure ttabpage.settabwidthmin(const avalue: integer); +begin + ftabwidthmin:= avalue; + changed; +end; + +function ttabpage.gettabwidthmax: integer; +begin + result:= ftabwidthmax; +end; + +procedure ttabpage.settabwidthmax(const avalue: integer); +begin + ftabwidthmax:= avalue; + changed; +end; +} +{ ttab_font } + +class function ttab_font.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomtabwidget(owner).ftabs.ffont; +end; + +{ ttab_fonttab } + +class function ttab_fonttab.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomtabwidget(owner).ftabs.tabs.ffont; +end; + +{ ttab_fontactivetab } + +class function ttab_fontactivetab.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomtabwidget(owner).ftabs.tabs.ffontactive; +end; + +{ tcustomtabwidget } + +constructor tcustomtabwidget.create(aowner: tcomponent); +begin + factivepageindex:= -1; + factivepageindexdesign:= -1; + ftab_sizemin:= defaulttabsizemin; + ftab_sizemax:= defaulttabsizemax; + inherited; + foptionswidget:= defaulttaboptionswidget; + optionsskin:= defaulttaboptionsskin; + ftabs:= tcustomtabbar1.create(self,nil,true); + include(ftabs.fwidgetstate1,ws1_designactive); + include(ftabs.fstate,tbs_designdrag); + ftabs.fanchors:= [an_left,an_top,an_right]; + ftab_size:= ftabs.size.cy; + ftabs.SetSubComponent(true); + ftabs.tabs.oncreatetab:= {$ifdef FPC}@{$endif}createpagetab; + exclude(ftabs.fwidgetstate,ws_iswidget); + ftabs.setlockedparentwidget(self); + ftabs.finternaltabchange:= {$ifdef FPC}@{$endif}tabchanged; + fobjectpicker:= tobjectpicker.create(iobjectpicker(self),org_widget); +end; + +destructor tcustomtabwidget.destroy; +begin + fobjectpicker.free; + ftabs.free; + inherited; +end; + +procedure tcustomtabwidget.clear; +begin + beginupdate(); + try + while count > 0 do begin + items[count-1].Free; + end; + finally + endupdate(); + end; +end; + +function tcustomtabwidget.getitems(const index: integer): twidget; +begin + result:= tpagetab(ftabs.tabs[index]).page; +end; + +function tcustomtabwidget.getitemsintf(const index: integer): itabpage; +begin + result:= tpagetab(ftabs.tabs[index]).fpageintf; +end; + +procedure tcustomtabwidget.pagechanged(const sender: itabpage); +var + widget1: twidget1; + int1: integer; + activepageindexbefore: integer; + bo1: boolean; + updatingbefore: boolean; +begin + if not (ws_destroying in fwidgetstate) then begin + widget1:= twidget1(sender.getwidget); + int1:= indexof(widget1); + if widget1.visible then begin + fvisiblepage:= int1; + end; + with ftabs.tabs[int1] do begin + updatingbefore:= ts_updating in fstate; + include(fstate,ts_updating); + if not (csloading in componentstate) and + not (ws_loadedproc in fwidgetstate) and (fupdating <= 0) then begin + activepageindexbefore:= factivepageindex; + caption:= sender.getcaption; + hint:= sender.gettabhint; + color:= sender.getcolortab; + coloractive:= sender.getcoloractivetab; + face:= sender.getfacetab; + faceactive:= sender.getfaceactivetab; + bo1:= sender.gettabnoface; + if bo1 then begin + state:= state + [ts_noface]; + end + else begin + state:= state - [ts_noface]; + end; + font:= ttabfont(sender.getfonttab); + fontactive:= ttabfontactive(sender.getfontactivetab); + imagelist:= sender.getimagelist; + imagenr:= sender.getimagenr; + imagenrdisabled:= sender.getimagenrdisabled; + bo1:= not (csdesigning in componentstate) and sender.getinvisible; + + if not widget1.enabled then begin + state:= state + [ts_disabled]; + end + else begin + state:= state - [ts_disabled]; + end; + if bo1 then begin + state:= state + [ts_invisible] + end + else begin + state:= state - [ts_invisible] + end; + if (not bo1 or (activepageindexbefore <> int1)) and widget1.isvisible and + (widget1.enabled or (csdesigning in widget1.componentstate)) then begin + state:= state - [ts_invisible]; + setactivepageindex(int1); + end + else begin + if (activepageindexbefore = int1) and + not (csdestroying in componentstate) then begin + changepage(1); + if factivepageindex = activepageindexbefore then begin + setactivepageindex(-1); //select none + end + else begin + if (activepage <> nil) and not activepage.entered and + (entered or ((fwindow <> nil) and + (fwindow.focusedwidget = nil))) and activepage.canfocus then begin + //probably page destroyed + activepage.setfocus(active); + end; + end; + end; + end; + if not updatingbefore then begin + exclude(fstate,ts_updating); + changed; + end; + end + else begin + caption:= sender.getcaption; //no updatelayout + if not updatingbefore then begin + exclude(fstate,ts_updating); + end; + end; + end; + end; +end; + +procedure tcustomtabwidget.loaded; +var + int1: integer; + po1: ppagetabaty; +begin + inc(fdesignchangedlock); + if factivepageindexdesign >= count then begin + factivepageindex:= -1; + factivepageindexdesign:= -1; + end; + if not (csdesigning in componentstate) and (factivepageindexdesign >= 0) then begin + factivepageindex:= factivepageindexdesign; + end; + if factivepageindex >= 0 then begin + if (fvisiblepage >= 0) and (fvisiblepage <> factivepageindex) and + (fvisiblepage < count) then begin + items[fvisiblepage].visible:= false; + end; + items[factivepageindex].visible:= true; + end; + inherited; + ftabs.loaded; + updatesize(nil); +// int1:= factivepageindex; + factivepageindex:= -1; +// setactivepageindex(int1); + with ftabs.flayoutinfo.tabs do begin + po1:= pointer(fitems); + for int1:= 0 to high(fitems) do begin + pagechanged(po1^[int1].fpageintf); + end; + end; +// ftabs.loaded; + dec(fdesignchangedlock); +end; + +procedure tcustomtabwidget.updatesize(const page: twidget); +var + rect1: rectty; + + procedure updatepagesize(const apage: twidget); + var + rect2: rectty; + begin + with rect2 do begin + if tabo_vertical in ftabs.options then begin + cx:= rect1.cx - ftabs.bounds_cx; + y:= rect1.y; + cy:= rect1.cy; + if tabo_opposite in ftabs.options then begin + x:= rect1.x; + end + else begin + x:= rect1.x + ftabs.bounds_cx; + end; + end + else begin + cy:= rect1.cy - ftabs.bounds_cy; + x:= rect1.x; + cx:= rect1.cx; + if tabo_opposite in ftabs.options then begin + y:= rect1.y; + end + else begin + y:= rect1.y + ftabs.bounds_cy; + end; + end; + end; + apage.widgetrect:= rect2; + end; + +var + int1: integer; + bo1: boolean; +begin + if not (csloading in componentstate) and + not (tbs_updatesizing in ftabs.fstate) then begin + //recursion lock + include(ftabs.fstate,tbs_updatesizing); + try + rect1:= innerwidgetrect; + if page <> nil then begin + updatepagesize(page); + end + else begin + bo1:= (tabo_notabsdesign in ftabs.options) or + not (csdesigning in componentstate) and + ((tabo_multitabsonly in ftabs.options) and (count < 2) or + (tabo_notabs in ftabs.options)); + if bo1 then begin + include(ftabs.fstate,tbs_shrinktozero); + end + else begin + exclude(ftabs.fstate,tbs_shrinktozero); + end; + if tabo_vertical in ftabs.options then begin + if tabo_opposite in ftabs.options then begin + if bo1 then begin + ftabs.setwidgetrect(makerect(rect1.x+rect1.cx,rect1.y, + 0,rect1.cy)); + end + else begin + ftabs.setwidgetrect(makerect(rect1.x+rect1.cx-ftab_size,rect1.y, + ftab_size,rect1.cy)); + end; + end + else begin + if bo1 then begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y,0,rect1.cy)); + end + else begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y,ftab_size,rect1.cy)); + end; + end; + end + else begin + if tabo_opposite in ftabs.options then begin + if bo1 then begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y+rect1.cy, + rect1.cx,0)); + end + else begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y+rect1.cy-ftab_size, + rect1.cx,ftab_size)); + end; + end + else begin + if bo1 then begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y,rect1.cx,0)); + end + else begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y,rect1.cx,ftab_size)); + end; + end; + end; + for int1:= 0 to ftabs.tabs.count - 1 do begin + updatepagesize(items[int1]); + end; + end; + finally + exclude(ftabs.fstate,tbs_updatesizing); + end; + end; +end; + +procedure tcustomtabwidget.readtab_captionpos(reader: treader); +begin + tab_imagepos:= readcaptiontoimagepos(reader); +end; + +procedure tcustomtabwidget.readoptions(reader: treader); +begin + tab_options:= tabbaroptionsty( + {$ifndef FPC}word(integer({$endif} + readset(reader,typeinfo(tabbaroptionsty)) + {$ifndef FPC})){$endif}); + if tabo_vertical in tab_options then begin + tab_optionswidget1:= []; + end; +end; + +procedure tcustomtabwidget.readtab_captionframe_left(reader: treader); +begin + ftabs.flayoutinfo.tabs.createframe(); + ttabframe1(ftabs.flayoutinfo.tabs.fframe).fi.innerframe.left:= + reader.readinteger(); +end; + +procedure tcustomtabwidget.readtab_captionframe_top(reader: treader); +begin + ftabs.flayoutinfo.tabs.createframe(); + ttabframe1(ftabs.flayoutinfo.tabs.fframe).fi.innerframe.top:= + reader.readinteger(); +end; + +procedure tcustomtabwidget.readtab_captionframe_right(reader: treader); +begin + ftabs.flayoutinfo.tabs.createframe(); + ttabframe1(ftabs.flayoutinfo.tabs.fframe).fi.innerframe.right:= + reader.readinteger(); +end; + +procedure tcustomtabwidget.readtab_captionframe_bottom(reader: treader); +begin + ftabs.flayoutinfo.tabs.createframe(); + ttabframe1(ftabs.flayoutinfo.tabs.fframe).fi.innerframe.bottom:= + reader.readinteger(); +end; + +procedure tcustomtabwidget.readtab_imagedist(reader: treader); +begin + ftabs.flayoutinfo.tabs.createframe(); + ttabframe1(ftabs.flayoutinfo.tabs.fframe).fi.imagedist:= reader.readinteger(); +end; + +procedure tcustomtabwidget.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('tab_captionpos',@readtab_captionpos,nil,false); + filer.defineproperty('options',@readoptions,nil,false); + filer.defineproperty('tab_captionframe_left', + @readtab_captionframe_left,nil,false); + filer.defineproperty('tab_captionframe_top', + @readtab_captionframe_top,nil,false); + filer.defineproperty('tab_captionframe_right', + @readtab_captionframe_right,nil,false); + filer.defineproperty('tab_captionframe_bottom', + @readtab_captionframe_bottom,nil,false); + filer.defineproperty('tab_imagedist', @readtab_imagedist,nil,false); +end; + +procedure tcustomtabwidget.internaladd(const page: itabpage; aindex: integer); +var + tab: tpagetab; + widget1: twidget1; +begin + widget1:= twidget1(page.getwidget); + if indexof(widget1) < 0 then begin + include(widget1.fmsecomponentstate,cs_parentwidgetrect); + if aindex > count then begin + aindex:= count; + end; + widget1.visible:= false; + tab:= tpagetab.create(ftabs,page); + if not (csreading in componentstate) then begin +// if not (csloading in componentstate) then begin + ftabs.tabs.insert(tab,aindex); + with widget1 do begin + parentwidget:= self; + anchors:= [an_bottom,an_top,an_left,an_right]; + end; + updatesize(widget1); + end + else begin + ftabs.tabs.beginupdate; + ftabs.tabs.insert(tab,aindex); + ftabs.tabs.endupdate(true); + end; + include(widget1.fwidgetstate1,ws1_nodesignvisible); + page.settabwidget(self); + pagechanged(page); +// if not (csloading in componentstate) then begin + if not (csreading in componentstate) then begin +// activepageindex:= aindex; + setactivepageindex(aindex); + end; + dopageadded(widget1); + end; +end; + +procedure tcustomtabwidget.internalremove(const page: itabpage); +var + int1: integer; + widget1: twidget1; + activebefore: integer; + + procedure check(var aindex: integer); + begin + if aindex >= 0 then begin + if aindex > int1 then begin + dec(aindex); + end + else begin + if aindex = int1 then begin + aindex:= -1; + end; + end; + end; + end; //check + +begin + if ftabs <> nil then begin + widget1:= twidget1(page.getwidget); + int1:= indexof(widget1); + if int1 >= 0 then begin + exclude(widget1.fmsecomponentstate,cs_parentwidgetrect); + activebefore:= factivepageindex; + check(factivepageindex); + check(factivepageindexdesign); + ftabs.flayoutinfo.activetab:= factivepageindex; + ftabs.tabs.delete(int1); + with widget1 do begin + exclude(fwidgetstate1,ws1_nodesignvisible); + if page.gettabwidget = self then begin + page.settabwidget(nil); + end; + end; + dopageremoved(widget1); + if (activebefore <> factivepageindex) and (factivepageindex = -1) then begin + nextpage(activebefore,true); + if factivepageindex = -1 then begin + doactivepagechanged; + end; + end; + end; + end; +end; + +procedure tcustomtabwidget.registerchildwidget(const child: twidget); +var + intf: itabpage; +begin + inherited; + if twidget1(child).getcorbainterface(typeinfo(itabpage),intf) then begin + internaladd(intf,bigint); + end; +end; + +procedure tcustomtabwidget.add(const aitem: itabpage; + const aindex: integer = bigint); +begin + internaladd(aitem,aindex); +end; + +procedure tcustomtabwidget.unregisterchildwidget(const child: twidget); +var + intf: itabpage; +begin + inherited; + if not (csdestroying in componentstate) and + twidget1(child).getcorbainterface(typeinfo(itabpage),intf) then begin + internalremove(intf); + end; +end; + +function tcustomtabwidget.indexof(const page: twidget): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to count-1 do begin + if items[int1] = page then begin + result:= int1; + break; + end; + end; +end; + +procedure tcustomtabwidget.GetChildren(Proc: TGetChildProc; Root: TComponent); +var + int1: integer; + widget1: twidget1; +begin + for int1:= 0 to high(fwidgets) do begin + exclude(twidget1(fwidgets[int1]).fwidgetstate1,ws1_isstreamed); + end; + for int1:= 0 to count-1 do begin + widget1:= twidget1(items[int1]); + if widget1.owner = root then begin + proc(widget1); + include(widget1.fwidgetstate1,ws1_isstreamed); + end; + end; + for int1:= 0 to widgetcount - 1 do begin + widget1:= twidget1(fwidgets[int1]); + if not (ws1_isstreamed in widget1.fwidgetstate1) and + (widget1.owner = root) and + (ws_iswidget in widget1.fwidgetstate) then begin + proc(widget1); + end; + end; +end; + +procedure tcustomtabwidget.setactivepageindex(Value: integer); +var + int1: integer; + parenttabfocus: boolean; + widget1,widget2: twidget; +begin + if (value <> factivepageindex) or (fupdating > 0) then begin + if csloading in componentstate then begin + factivepageindex:= value; + factivepageindex1:= value; + exit; + end; + if (value >= 0) then begin + ftabs.flayoutinfo.tabs.checkindex(value); + end + else begin + value:= -1; + end; + if fupdating > 0 then begin + factivepageindex1:= value; + end + else begin + parenttabfocus:= ow_parenttabfocus in foptionswidget; + exclude(foptionswidget,ow_parenttabfocus); + try + if factivepageindex >= 0 then begin + widget1:= items[factivepageindex]; + int1:= factivepageindex; + if not (csdestroying in widget1.componentstate) then begin + widget2:= widget1; + if ow1_canclosenil in widget1.optionswidget1 then begin + widget2:= nil; + end; + if not widget1.canparentclose(widget2) then begin + ftabs.tabs[factivepageindex].active:= true; + exit; + end; + factivepageindex:= -1; + if not (csloading in componentstate) then begin + tpagetab(ftabs.tabs[int1]).fpageintf.dodeselect; + if (factivepageindex <> -1) then begin + exit; + end; + end; + items[int1].visible:= false; + if (factivepageindex <> -1) or items[int1].visible then begin + exit; + end; + end; + ftabs.tabs[int1].active:= false; //if items[int1] was already invisible + end; + factivepageindex:= Value; + if value >= 0 then begin + defaultfocuschild:= items[value]; + if not (csloading in componentstate) then begin + tpagetab(ftabs.tabs[value]).fpageintf.doselect; + if factivepageindex <> value then begin + exit; + end; + end; + with items[value] do begin + bringtofront; //needed in design mode where all widgets are visible + inc(fupdating); + try + visible:= true; + finally + dec(fupdating); + end; + if self.entered and canfocus and not ftabs.focused then begin + setfocus(false); + end; + end; + end + else begin + defaultfocuschild:= nil; + end; + if (value = factivepageindex) then begin + doactivepagechanged; + if (value >= 0) and (value = factivepageindex) then begin + ftabs.tabs[value].active:= true + end; + end; + finally + if parenttabfocus then begin + include(foptionswidget,ow_parenttabfocus); + end; + end; + end; + end; +end; + +procedure tcustomtabwidget.tabchanged(const synctabindex: boolean); +begin + if synctabindex and (factivepageindex >= 0) then begin + factivepageindex:= ftabs.activetab; + end + else begin + setactivepageindex(ftabs.activetab); + end; +// activepageindex:= ftabs.activetab; +end; + +function tcustomtabwidget.count: integer; +begin + result:= ftabs.tabs.count; +end; + +function tcustomtabwidget.getactivepage: twidget; +begin + if factivepageindex >= 0 then begin + result:= items[factivepageindex]; + end + else begin + result:= nil; + end; +end; + +function tcustomtabwidget.getactivepageintf: itabpage; +begin + if factivepageindex >= 0 then begin + result:= itemsintf[factivepageindex]; + end + else begin + result:= nil; + end; +end; + +procedure tcustomtabwidget.setactivepage(const value: twidget); +begin + if value = nil then begin + setactivepageindex(-1); + end + else begin + setactivepageindex(indexof(value)); + end; +end; + +procedure tcustomtabwidget.clientrectchanged; +var + size1: sizety; +begin + inherited; + if not (csloading in componentstate) then begin + size1:= innerclientsize; + if tabo_vertical in ftabs.foptions then begin + if size1.cx < tab_size then begin + tab_size:= size1.cx + end + else begin + updatesize(nil); + end; + end + else begin + if size1.cy < tab_size then begin + tab_size:= size1.cy + end + else begin + updatesize(nil); + end; + end; + end; +end; + +procedure tcustomtabwidget.doactivepagechanged; +begin + if canevent(tmethod(fonactivepagechanged)) then begin + fonactivepagechanged(self); + end; +// designchanged; +end; + +procedure tcustomtabwidget.dopageadded(const apage: twidget); +begin + if canevent(tmethod(fonpageadded)) then begin + fonpageadded(self,apage); + end; +end; + +procedure tcustomtabwidget.dopageremoved(const apage: twidget); +begin + if canevent(tmethod(fonpageremoved)) then begin + fonpageremoved(self,apage); + end; +end; + +procedure tcustomtabwidget.nextpage(newindex: integer; down: boolean); +var + int1: integer; +begin + if count > 0 then begin + if (newindex >= count) or (newindex < 0) then begin + if down then begin + newindex:= count - 1; + end + else begin + newindex:= 0; + end; + end; + int1:= newindex; + repeat + if (items[int1].enabled) and not (ts_invisible in ftabs.tabs[int1].state) or + (csdesigning in componentstate) then begin + setactivepageindex(int1); + break; + end + else begin + if down then begin + dec(int1); + if int1 < 0 then begin + int1:= count - 1; + end; + end + else begin + inc(int1); + if int1 >= count then begin + int1:= 0; + end; + end; + end; + until int1 = newindex; + if int1 = factivepageindex then begin + if not ((items[int1].enabled) and not (ts_invisible in ftabs.tabs[int1].state) + or (csdesigning in componentstate)) then begin + setactivepageindex(-1); + end; + end; + end; +end; + +procedure tcustomtabwidget.changepage(step: integer); +begin + nextpage(factivepageindex+step,step < 0); +end; + +procedure tcustomtabwidget.movepage(const curindex,newindex: integer); +begin + ftabs.movetab(curindex,newindex); +end; + +procedure tcustomtabwidget.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if (shiftstate = [ss_ctrl]) or (shiftstate = [ss_shift,ss_ctrl]) then begin + include(eventstate,es_processed); + case key of + key_tab: begin + changepage(1); + end; + key_backtab: begin + changepage(-1); + end + else begin + exclude(eventstate,es_processed); + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +procedure tcustomtabwidget.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) and + not ftabs.fdragcontroller.active and + ((sender = self) or (sender = ftabs) or (sender = activepage)) then begin + translatewidgetpoint1(info.pos,sender,self); + fobjectpicker.mouseevent(info); + translatewidgetpoint1(info.pos,self,sender); + end; +end; + +procedure tcustomtabwidget.dobeforepaint(const canvas: tcanvas); +begin + fobjectpicker.dobeforepaint(canvas); + inherited; +end; + +procedure tcustomtabwidget.doafterpaint(const canvas: tcanvas); +begin + inherited; + fobjectpicker.doafterpaint(canvas); +end; + +procedure tcustomtabwidget.synctofontheight; +begin + inherited; + if not (tabo_vertical in tab_options) then begin + ftabs.synctofontheight; + tab_size:= ftabs.bounds_cy; + end; +end; + +function tcustomtabwidget.checktabsizingpos(const apos: pointty): boolean; +begin + with ftabs,moverect(ftabs.paintrect,ftabs.fwidgetrect.pos) do begin + if tabo_tabsizing in foptions then begin + if tabo_vertical in foptions then begin + if tabo_opposite in foptions then begin + result:= pointinrect(apos,makerect(x-sizingtol,y,sizingwidth,cy)); + end + else begin + result:= pointinrect(apos,makerect(x+cx-sizingtol,y,sizingwidth,cy)); + end; + end + else begin + if tabo_opposite in foptions then begin + result:= pointinrect(apos,makerect(y,y-sizingtol,cx,sizingwidth)); + end + else begin + result:= pointinrect(apos,makerect(y,y+cy-sizingtol,cx,sizingwidth)); + end; + end; + end + else begin + result:= false; + end; + end; +end; + +function tcustomtabwidget.getidents: integerarty; +begin + result:= ftabs.flayoutinfo.tabs.idents; +end; + +procedure tcustomtabwidget.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + + //istatfile +procedure tcustomtabwidget.dostatread(const reader: tstatreader); +begin + ftabs.flayoutinfo.tabs.dostatread(reader,tabo_dragdest in tab_options); + if reader.canstate then begin + if tabo_tabsizing in tab_options then begin + tab_size:= reader.readinteger('tabsize',tab_size); + end; + ftabs.firsttab:= reader.readinteger('firsttab',ftabs.firsttab); + setactivepageindex(reader.readinteger('index',activepageindex,-1,count-1)); + end; +end; + +procedure tcustomtabwidget.dostatwrite(const writer: tstatwriter); +begin + ftabs.flayoutinfo.tabs.dostatwrite(writer,tabo_dragdest in tab_options); + if writer.canstate then begin + if tabo_tabsizing in tab_options then begin + writer.writeinteger('tabsize',tab_size); + end; + writer.writeinteger('firsttab',ftabs.firsttab); + writer.writeinteger('index',activepageindex); + end; +end; + +procedure tcustomtabwidget.statreading; +begin + //dummy; +end; + +procedure tcustomtabwidget.statread; +begin + //dummy; +end; + +function tcustomtabwidget.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + + //iobjectpicker +function tcustomtabwidget.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + //true if found +begin + result:= checktabsizingpos(sender.pos); + if result then begin + if tabo_vertical in ftabs.foptions then begin + shape:= cr_sizehor; + end + else begin + shape:= cr_sizever; + end; + end +end; + +procedure tcustomtabwidget.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +begin + if checktabsizingpos(sender.pos) then begin + setlength(objects,1); + end; +end; + +procedure tcustomtabwidget.beginpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +function tcustomtabwidget.checkpickoffset(const aoffset: pointty): pointty; +begin + result:= aoffset; + with ftabs do begin + if tabo_opposite in foptions then begin + result.x:= -result.x; + result.y:= -result.y; + end; + if tabo_vertical in foptions then begin + if tab_size + result.x > tab_sizemax then begin + result.x:= tab_sizemax - tab_size; + end; + if tab_size + result.x > self.paintrect.cx then begin + result.x:= self.paintrect.cx - tab_size; + end; + if tab_size + result.x < tab_sizemin then begin + result.x:= tab_sizemin - tab_size; + end; + end + else begin + if tab_size + result.y > tab_sizemax then begin + result.y:= tab_sizemax - tab_size; + end; + if tab_size + result.y > self.paintrect.cy then begin + result.y:= self.paintrect.cy - tab_size; + end; + if tab_size + result.y < tab_sizemin then begin + result.y:= tab_sizemin - tab_size; + end; + end; + if tabo_opposite in foptions then begin + result.x:= -result.x; + result.y:= -result.y; + end; + end; +end; + +procedure tcustomtabwidget.endpickmove(const sender: tobjectpicker); +var + offset1: pointty; +begin + offset1:= checkpickoffset(sender.pickoffset); + with ftabs do begin + if tabo_vertical in foptions then begin + if tabo_opposite in foptions then begin + tab_size:= tab_size - offset1.x; + end + else begin + tab_size:= tab_size + offset1.x; + end; + end + else begin + if tabo_opposite in foptions then begin + tab_size:= tab_size - offset1.y; + end + else begin + tab_size:= tab_size + offset1.y; + end; + end; + end; +end; + +procedure tcustomtabwidget.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); +var + offset1: pointty; +begin + offset1:= checkpickoffset(sender.pickoffset); + with ftabs,ftabs.fwidgetrect do begin + if tabo_vertical in options then begin + if tabo_opposite in foptions then begin + canvas.fillxorrect(makepoint(x+offset1.x,y),cy,gd_down,2, + stockobjects.bitmaps[stb_dens50]); + end + else begin + canvas.fillxorrect(makepoint(x+cx+offset1.x,y),cy,gd_down,2, + stockobjects.bitmaps[stb_dens50]); + end; + end + else begin + if tabo_opposite in foptions then begin + canvas.fillxorrect(makepoint(x,y+offset1.y),cx,gd_right,2, + stockobjects.bitmaps[stb_dens50]); + end + else begin + canvas.fillxorrect(makepoint(x,y+cy+offset1.y),cx,gd_right,2, + stockobjects.bitmaps[stb_dens50]); + end; + end; + end; +end; + +function tcustomtabwidget.gettab_options: tabbaroptionsty; +begin + result:= ftabs.options; +end; + +procedure tcustomtabwidget.settab_options(const avalue: tabbaroptionsty); +var + optionsbefore: tabbaroptionsty; +begin + optionsbefore:= ftabs.options; + ftabs.options:= avalue; + if (optionsbefore >< ftabs.options) * + [tabo_vertical,tabo_opposite, + tabo_multitabsonly,tabo_notabs,tabo_notabsdesign] <> [] then begin + if tabo_vertical in avalue then begin + ftabs.anchors:= [an_left,an_top,an_bottom]; + end + else begin + ftabs.anchors:= [an_left,an_top,an_right]; + end; + updatesize(nil); + end; +end; + +function tcustomtabwidget.gettab_color: colorty; +begin + Result := ftabs.color; +end; + +procedure tcustomtabwidget.settab_color(const avalue: colorty); +begin + ftabs.color:= avalue; +end; + +function tcustomtabwidget.gettab_frame: tstepboxframe1; +begin + result:= tstepboxframe1(ftabs.frame); +end; + +procedure tcustomtabwidget.settab_frame(const avalue: tstepboxframe1); +begin + ftabs.frame:= avalue; +end; + +function tcustomtabwidget.gettab_face: tface; +begin + Result:= ftabs.face; +end; + +procedure tcustomtabwidget.settab_face(const avalue: tface); +begin + ftabs.face:= avalue; +end; + +function tcustomtabwidget.gettab_colortab: colorty; +begin + result:= ftabs.tabs.color; +end; + +procedure tcustomtabwidget.settab_colortab(const avalue: colorty); +begin + ftabs.tabs.color:= avalue; +end; + +function tcustomtabwidget.gettab_coloractivetab: colorty; +begin + result:= ftabs.tabs.coloractive; +end; + +procedure tcustomtabwidget.settab_coloractivetab(const avalue: colorty); +begin + ftabs.tabs.coloractive:= avalue; +end; + +function tcustomtabwidget.gettab_frametab: ttabframe; +begin + result:= ftabs.tabs.frame; +end; + +procedure tcustomtabwidget.settab_frametab(const avalue: ttabframe); +begin + ftabs.tabs.frame:= avalue; +end; + +function tcustomtabwidget.gettab_facetab: tface; +begin + result:= ftabs.tabs.face; +end; + +procedure tcustomtabwidget.settab_facetab(const avalue: tface); +begin + ftabs.tabs.face:= avalue; +end; + +function tcustomtabwidget.gettab_faceactivetab: tface; +begin + result:= ftabs.tabs.faceactive; +end; + +procedure tcustomtabwidget.settab_faceactivetab(const avalue: tface); +begin + ftabs.tabs.faceactive:= avalue; +end; + +function tcustomtabwidget.gettab_imagepos: imageposty; +begin + result:= ftabs.tabs.imagepos; +end; + +procedure tcustomtabwidget.settab_imagepos(const avalue: imageposty); +begin + ftabs.tabs.imagepos:= avalue; +end; +{ +function tcustomtabwidget.gettab_captionframe_left: integer; +begin + result:= ftabs.tabs.captionframe_left; +end; + +procedure tcustomtabwidget.settab_captionframe_left(const avalue: integer); +begin + ftabs.tabs.captionframe_left:= avalue; +end; + +function tcustomtabwidget.gettab_captionframe_top: integer; +begin + result:= ftabs.tabs.captionframe_top; +end; + +procedure tcustomtabwidget.settab_captionframe_top(const avalue: integer); +begin + ftabs.tabs.captionframe_top:= avalue; +end; + +function tcustomtabwidget.gettab_captionframe_right: integer; +begin + result:= ftabs.tabs.captionframe_right; +end; + +procedure tcustomtabwidget.settab_captionframe_right(const avalue: integer); +begin + ftabs.tabs.captionframe_right:= avalue; +end; + +function tcustomtabwidget.gettab_captionframe_bottom: integer; +begin + result:= ftabs.tabs.captionframe_bottom; +end; + +procedure tcustomtabwidget.settab_captionframe_bottom(const avalue: integer); +begin + ftabs.tabs.captionframe_bottom:= avalue; +end; + +function tcustomtabwidget.gettab_imagedist: integer; +begin + result:= ftabs.tabs.imagedist; +end; + +procedure tcustomtabwidget.settab_imagedist(const avalue: integer); +begin + ftabs.tabs.imagedist:= avalue; +end; +} +function tcustomtabwidget.gettab_shift: integer; +begin + result:= ftabs.tabs.shift; +end; + +procedure tcustomtabwidget.settab_shift(const avalue: integer); +begin + ftabs.tabs.shift:= avalue; +end; + +procedure tcustomtabwidget.createpagetab(const sender: tcustomtabbar; + const index: integer; var tab: ttab); +begin + tab:= tpagetab.create(sender,nil); +end; + +procedure tcustomtabwidget.settab_size(const avalue: integer); +begin + if ftab_size <> avalue then begin + ftab_size:= avalue; + if ftab_size < ftab_sizemin then begin + ftab_size:= ftab_sizemin; + end + else begin + if ftab_size > ftab_sizemax then begin + ftab_size:= ftab_sizemax; + end; + end; + if not (csloading in componentstate) then begin + updatesize(nil); + end; + end; +end; + +procedure tcustomtabwidget.widgetregionchanged(const sender: twidget); +begin + inherited; + if not (csdestroying in componentstate) and (sender = ftabs) and + not (ws1_updateopaque in twidget1(sender).fwidgetstate1) and + not (tbs_shrinktozero in ftabs.fstate) then begin + if tabo_vertical in ftabs.options then begin + tab_size:= ftabs.bounds_cx; + end + else begin + tab_size:= ftabs.bounds_cy; + end; + end; +end; + + +procedure tcustomtabwidget.settab_sizemin(const avalue: integer); +begin + ftab_sizemin:= avalue; + if avalue > ftab_size then begin + tab_size:= avalue; + end; +end; + +procedure tcustomtabwidget.settab_sizemax(const avalue: integer); +begin + ftab_sizemax:= avalue; + if avalue < ftab_size then begin + tab_size:= avalue; + end; +end; + +function tcustomtabwidget.pagebyname(const aname: string): twidget; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + result:= items[int1]; + if result.name = aname then begin + exit; + end; + end; + raise exception.create('Tabpage '''+aname+''' not found.'); +end; + +procedure tcustomtabwidget.doclosepage(const sender: tobject); +begin + items[fpopuptab].visible:= false; + ftabs.tabs[fpopuptab].state:= ftabs.tabs[fpopuptab].state + [ts_invisible]; +end; + +procedure tcustomtabwidget.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + if (tabo_autopopup in tab_options) then begin + fpopuptab:= ftabs.tabatpos(translateclientpoint(mouseinfo.pos,self,ftabs)); + if fpopuptab >= 0 then begin + tpopupmenu.additems(amenu,self,mouseinfo, + [stockobjects.captions[sc_close_page]], + [],[],[{$ifdef FPC}@{$endif}doclosepage]); + end; + end; + inherited; +end; + +function tcustomtabwidget.gettab_optionswidget: optionswidgetty; +begin + result:= ftabs.optionswidget; +end; + +procedure tcustomtabwidget.settab_optionswidget(const avalue: optionswidgetty); +begin + ftabs.optionswidget:= avalue; +end; + +function tcustomtabwidget.gettab_optionswidget1: optionswidget1ty; +begin + result:= ftabs.optionswidget1; +end; + +procedure tcustomtabwidget.settab_optionswidget1(const avalue: optionswidget1ty); +begin + ftabs.optionswidget1:= avalue; +end; + +function tcustomtabwidget.gettab_optionsskin: optionsskinty; +begin + result:= ftabs.optionsskin; +end; + +procedure tcustomtabwidget.settab_optionsskin(const avalue: optionsskinty); +begin + ftabs.optionsskin:= avalue; +end; + +function tcustomtabwidget.getedge_level: int32; +begin + result:= ftabs.tabs.edge_level; +end; + +procedure tcustomtabwidget.setedge_level(const avalue: int32); +begin + ftabs.tabs.edge_level:= avalue; +end; + +function tcustomtabwidget.getedge_colordkshadow: colorty; +begin + result:= ftabs.tabs.edge_colordkshadow; +end; + +procedure tcustomtabwidget.setedge_colordkshadow(const avalue: colorty); +begin + ftabs.tabs.edge_colordkshadow:= avalue; +end; + +function tcustomtabwidget.getedge_colorshadow: colorty; +begin + result:= ftabs.tabs.edge_colorshadow; +end; + +procedure tcustomtabwidget.setedge_colorshadow(const avalue: colorty); +begin + ftabs.tabs.edge_colorshadow:= avalue; +end; + +function tcustomtabwidget.getedge_colorlight: colorty; +begin + result:= ftabs.tabs.edge_colorlight; +end; + +procedure tcustomtabwidget.setedge_colorlight(const avalue: colorty); +begin + ftabs.tabs.edge_colorlight:= avalue; +end; + +function tcustomtabwidget.getedge_colorhighlight: colorty; +begin + result:= ftabs.tabs.edge_colorhighlight; +end; + +procedure tcustomtabwidget.setedge_colorhighlight(const avalue: colorty); +begin + ftabs.tabs.edge_colorhighlight:= avalue; +end; + +function tcustomtabwidget.getedge_colordkwidth: int32; +begin + result:= ftabs.tabs.edge_colordkwidth; +end; + +procedure tcustomtabwidget.setedge_colordkwidth(const avalue: int32); +begin + ftabs.tabs.edge_colordkwidth:= avalue; +end; + +function tcustomtabwidget.getedge_colorhlwidth: int32; +begin + result:= ftabs.tabs.edge_colorhlwidth; +end; + +procedure tcustomtabwidget.setedge_colorhlwidth(const avalue: int32); +begin + ftabs.tabs.edge_colorhlwidth:= avalue; +end; + +function tcustomtabwidget.getedge_imagelist: timagelist; +begin + result:= ftabs.tabs.edge_imagelist; +end; + +procedure tcustomtabwidget.setedge_imagelist(const avalue: timagelist); +begin + ftabs.tabs.edge_imagelist:= avalue; +end; + +function tcustomtabwidget.getedge_imageoffset: int32; +begin + result:= ftabs.tabs.edge_imageoffset; +end; + +procedure tcustomtabwidget.setedge_imageoffset(const avalue: int32); +begin + ftabs.tabs.edge_imageoffset:= avalue; +end; + +function tcustomtabwidget.getedge_imagepaintshift: int32; +begin + result:= ftabs.tabs.edge_imagepaintshift; +end; + +procedure tcustomtabwidget.setedge_imagepaintshift(const avalue: int32); +begin + ftabs.tabs.edge_imagepaintshift:= avalue; +end; + +function tcustomtabwidget.gettab_font: ttab_font; +begin +{$warnings off} + result:= ttab_font(ftabs.font); +{$warnings on} +end; + +procedure tcustomtabwidget.settab_font(const avalue: ttab_font); +begin +{$warnings off} + ftabs.font:= twidgetfont(avalue); +{$warnings on} +end; + +function tcustomtabwidget.istab_fontstored: boolean; +begin + result:= ftabs.ffont <> nil; +end; + +function tcustomtabwidget.gettab_fonttab: ttab_fonttab; +begin +{$warnings off} + result:= ttab_fonttab(ftabs.tabs.font); +{$warnings on} +end; + +procedure tcustomtabwidget.settab_fonttab(const avalue: ttab_fonttab); +begin +{$warnings off} + ftabs.tabs.font:= ttabsfont(avalue); +{$warnings on} +end; + +function tcustomtabwidget.istab_fonttabstored: boolean; +begin + result:= ftabs.tabs.ffont <> nil; +end; + +function tcustomtabwidget.gettab_fontactivetab: ttab_fontactivetab; +begin +{$warnings off} + result:= ttab_fontactivetab(ftabs.tabs.fontactive); +{$warnings on} +end; + +procedure tcustomtabwidget.set_tabfontactivetab(const avalue: ttab_fontactivetab); +begin +{$warnings off} + ftabs.tabs.fontactive:= ttabsfontactive(avalue); +{$warnings on} +end; + +function tcustomtabwidget.istab_fontactivetabstored: boolean; +begin + result:= ftabs.tabs.ffontactive <> nil; +end; + +function tcustomtabwidget.gettab_textflags: textflagsty; +begin + result:= ftabs.tabs.ftextflags; +end; + +procedure tcustomtabwidget.settab_textflags(const avalue: textflagsty); +begin + ftabs.tabs.textflags:= avalue; +end; + +function tcustomtabwidget.gettab_width: integer; +begin + result:= ftabs.tabs.width; +end; + +procedure tcustomtabwidget.settab_width(const avalue: integer); +begin + ftabs.tabs.width:= avalue; +end; + +function tcustomtabwidget.gettab_widthmin: integer; +begin + result:= ftabs.tabs.widthmin; +end; + +procedure tcustomtabwidget.settab_widthmin(const avalue: integer); +begin + ftabs.tabs.widthmin:= avalue; +end; + +function tcustomtabwidget.gettab_widthmax: integer; +begin + result:= ftabs.tabs.widthmax; +end; + +procedure tcustomtabwidget.settab_widthmax(const avalue: integer); +begin + ftabs.tabs.widthmax:= avalue; +end; + +procedure tcustomtabwidget.pickthumbtrack(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomtabwidget.cancelpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +function tcustomtabwidget.getactivepageindex: integer; +begin + if fupdating > 0 then begin + result:= factivepageindex1; + end + else begin + result:= factivepageindex; + end; + if csdesigning in componentstate then begin + result:= factivepageindexdesign; + end; +end; + +procedure tcustomtabwidget.setactivepageindex1(const avalue: integer); +begin + setactivepageindex(avalue); + factivepageindexdesign:= avalue;//factivepageindex; +end; + +procedure tcustomtabwidget.beginupdate; +begin + if fupdating = 0 then begin + factivepageindex1:= factivepageindex; + end; + inc(fupdating); + ftabs.beginupdate; +end; + +procedure tcustomtabwidget.endupdate; +var + int1: integer; +begin + dec(fupdating); + if fupdating = 0 then begin + if factivepageindex1 < count then begin + activepageindex:= factivepageindex1; + end; + with ftabs.tabs do begin + for int1:= 0 to high(fitems) do begin + with tpagetab(fitems[int1]) do begin + self.pagechanged(fpageintf); + end; + end; + end; + end; + ftabs.endupdate; + if fupdating = 0 then begin + updatesize(nil); + end; +end; + +procedure tcustomtabwidget.clearorder; +begin + ftabs.tabs.clearorder; +end; + +function tcustomtabwidget.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tcustomtabwidget.createtabframe(); +begin + ftabs.createframe(); +end; + +procedure tcustomtabwidget.createtabface(); +begin + ftabs.createface(); +end; + +procedure tcustomtabwidget.createtabfont(); +begin + ftabs.createfont(); +end; + +procedure tcustomtabwidget.createtabframetab(); +begin + ftabs.tabs.createframe(); +end; + +procedure tcustomtabwidget.createtabfacetab(); +begin + ftabs.tabs.createface(); +end; + +procedure tcustomtabwidget.createtabfonttab(); +begin + ftabs.tabs.createfont(); +end; + +procedure tcustomtabwidget.createtabfaceactivetab; +begin + ftabs.tabs.createfaceactive(); +end; + +procedure tcustomtabwidget.createtabfontactivetab; +begin + ftabs.tabs.createfontactive(); +end; + +{ tpagetab } + +constructor tpagetab.create(const aowner: tcustomtabbar; const apage: itabpage); +begin + fpageintf:= apage; + inherited create(aowner); +end; + +function tpagetab.page: twidget; +begin + result:= fpageintf.getwidget; +end; + +{ tcustomtabbar1 } + +procedure tcustomtabbar1.internalcreateframe; +begin + tstepboxframe1.create(iscrollframe(self),istepbar(self)); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msetabsglob.pas b/mseide-msegui/lib/common/widgets/msetabsglob.pas new file mode 100644 index 0000000..fc30f63 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msetabsglob.pas @@ -0,0 +1,30 @@ +{ MSEgui Copyright (c) 1999-2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msetabsglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +const + defaulttabsizemin = 15; + defaulttabsizemax = 200; + +type + tabbaroptionty = (tabo_dragsource,tabo_dragdest, + tabo_dragsourceenabledonly,tabo_dragdestenabledonly, + //no action on disabled pages + tabo_vertical,tabo_opposite, + tabo_multitabsonly,tabo_notabs,tabo_notabsdesign, + tabo_buttonsoutside,tabo_tabsizing, + tabo_acttabfirst,tabo_clickedtabfirst, + tabo_dblclickedtabfirst, + tabo_sorted,tabo_autopopup,tabo_hintclippedtext); + tabbaroptionsty = set of tabbaroptionty; + +implementation +end. diff --git a/mseide-msegui/lib/common/widgets/msetoolbar.pas b/mseide-msegui/lib/common/widgets/msetoolbar.pas new file mode 100644 index 0000000..3bc239d --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msetoolbar.pas @@ -0,0 +1,2013 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msetoolbar; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,classes,mclasses,msewidgets,msearrayprops,mseclasses,msebitmap, + mseact,mseshapes,msemenus,msedragglob, + msegraphutils,msegraphics,mseevent, + mseglob,mseguiglob,msegui,msesimplewidgets, + msestat,msestatfile,msedrag,msestrings; + +type + + tcustomtoolbar = class; + + tcustomtoolbutton = class(tindexpersistent,iactionlink,iimagelistinfo) + private + finfo: actioninfoty; +// fonupdate: actioneventty; + procedure setaction(const Value: tcustomaction); + procedure setimagenr(const Value: imagenrty); + procedure setimagenrdisabled(const Value: imagenrty); + procedure setcolorglyph(const avalue: colorty); + function iscolorglyphstored: boolean; + procedure setcolor(const avalue: colorty); + function iscolorstored: boolean; + procedure setimagecheckedoffset(const Value: integer); + function getstate: actionstatesty; + function isstatestored: Boolean; + procedure setstate(const Value: actionstatesty); + function isimagenrstored: Boolean; + function isimagenrdisabledstored: Boolean; + function isimagecheckedoffsetstored: Boolean; + function isimageliststored: Boolean; virtual; + function getimagelist: timagelist; + procedure setimagelist(const Value: timagelist); virtual; + function isgroupstored: Boolean; + procedure setgroup(const Value: integer); + procedure changed; + function getchecked: boolean; + procedure setchecked(const Value: boolean); + procedure sethint(const Value: msestring); + function ishintstored: Boolean; + procedure setonexecute(const avalue: notifyeventty); + function isonexecutestored: Boolean; + procedure setonbeforeexecute(const avalue: accepteventty); + function isonbeforeexecutestored: Boolean; + procedure setonafterexecute(const avalue: notifyeventty); + function isonafterexecutestored: Boolean; + procedure setoptions(const Value: menuactionoptionsty); + procedure setshortcut(const value: shortcutty); + function isshortcutstored: boolean; + function getshortcut: shortcutty; + function getshortcut1: shortcutty; + procedure setshortcut1(const value: shortcutty); + function isshortcut1stored: boolean; + function getenabled: boolean; + function getvisible: boolean; + procedure setenabled(const avalue: boolean); + procedure setvisible(const avalue: boolean); + procedure readbool(reader: treader); + procedure writebool(writer: twriter); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + protected + ftag: integer; + ftagpo: pointer; + procedure doexecute(const tag: integer; const info: mouseeventinfoty); + procedure objectevent(const sender: tobject; const event: objecteventty); override; + procedure defineproperties(filer: tfiler); override; + //iactionlink + procedure actionchanged; + function getactioninfopo: pactioninfoty; + procedure doshortcut(var info: keyeventinfoty); + function getinstance: tobject; override; + function loading: boolean; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); overload; override; + constructor create(aowner: tcustomtoolbar); reintroduce; overload; + function toolbar: tcustomtoolbar; + function index: integer; + procedure execute; + procedure doupdate; + property checked: boolean read getchecked write setchecked; + property visible: boolean read getvisible write setvisible default true; + property enabled: boolean read getenabled write setenabled default true; + property shortcuts: shortcutarty read finfo.shortcut write setshortcuts; + property shortcuts1: shortcutarty read finfo.shortcut1 write setshortcuts1; + property imagelist: timagelist read getimagelist write setimagelist + stored isimageliststored; + property imagenr: imagenrty read finfo.imagenr write setimagenr + stored isimagenrstored default -1; + property imagenrdisabled: imagenrty read finfo.imagenrdisabled + write setimagenrdisabled + stored isimagenrdisabledstored default -2; + property colorglyph: colorty read finfo.colorglyph write setcolorglyph + stored iscolorglyphstored default cl_default; + property color: colorty read finfo.color write setcolor + stored iscolorstored default cl_default; + property imagecheckedoffset: integer read finfo.imagecheckedoffset + write setimagecheckedoffset + stored isimagecheckedoffsetstored default 0; + property hint: msestring read finfo.hint write sethint stored ishintstored; + property action: tcustomaction read finfo.action write setaction; + property state: actionstatesty read getstate write setstate + stored isstatestored default []; + property shortcut: shortcutty read getshortcut write setshortcut + stored isshortcutstored default 0; + property shortcut1: shortcutty read getshortcut1 write setshortcut1 + stored isshortcut1stored default 0; + property options: menuactionoptionsty read finfo.options + write setoptions default []; + property group: integer read finfo.group write setgroup + stored isgroupstored default 0; + property tag: integer read ftag write ftag default 0; + property tagpo: pointer read ftagpo write ftagpo; + property tagpointer: pointer read ftagpo write ftagpo; + deprecated 'Use tagpo instead'; + property onexecute: notifyeventty read finfo.onexecute write setonexecute + stored isonexecutestored; + property onbeforeexecute: accepteventty read finfo.onbeforeexecute + write setonbeforeexecute stored isonbeforeexecutestored; + property onafterexecute: notifyeventty read finfo.onafterexecute + write setonafterexecute stored isonafterexecutestored; +// property onupdate: actioneventty read fonupdate write fonupdate; + end; + + ttoolbutton = class(tcustomtoolbutton) + published + property imagelist; + property imagenr; + property imagenrdisabled; + property colorglyph; + property color; + property imagecheckedoffset; + property hint; + property action; + property state; + property shortcut; + property shortcut1; + property tag; + property options; + property group; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + ptoolbutton = ^ttoolbutton; + + tcustomstockglyphtoolbutton = class(tcustomtoolbutton) + private + function isimageliststored: boolean; override; + procedure setimagelist(const Value: timagelist); override; + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); overload; override; + end; + + tstockglyphtoolbutton = class(tcustomstockglyphtoolbutton) + published + property imagelist; + property imagenr; + property imagenrdisabled; + property colorglyph; + property color; + property imagecheckedoffset; + property hint; + property action; + property state; + property shortcut; + property shortcut1; + property tag; + property options; + property group; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + +const + defaulttoolbuttonoptionsskin = [fso_flat,fso_nofocusrect,fso_nodefaultrect]; + defaulttoolseparatoroptionsskin = defaulttoolbuttonoptionsskin - [fso_flat]; + +type + ttoolbuttonframe = class(tframe) + public + constructor create(const aintf: iframe); + published + property optionsskin default defaulttoolbuttonoptionsskin; + end; + + ttoolseparatorframe = class(ttoolbuttonframe) + public + constructor create(const aintf: iframe); + published + property optionsskin default defaulttoolseparatoroptionsskin; + end; + + toolbuttonsstatety = (tbs_nocandefocus); + toolbuttonsstatesty = set of toolbuttonsstatety; + toolbuttonclassty = class of tcustomtoolbutton; + + tcustomtoolbuttons = class(tindexpersistentarrayprop) + private + fheight: integer; + fwidth: integer; + fimagelist: timagelist; + fcolorglyph: colorty; + fcolor: colorty; + fface: tface; + ffacechecked: tface; + fframe: ttoolbuttonframe; + fframechecked: ttoolbuttonframe; + fframesephorz: ttoolseparatorframe; + fframesepvert: ttoolseparatorframe; + procedure setitems(const index: integer; const Value: tcustomtoolbutton); + function getitems(const index: integer): tcustomtoolbutton; reintroduce; + procedure setheight(const Value: integer); + procedure setwidth(const Value: integer); + procedure setimagelist(const avalue: timagelist); + procedure setcolorglyph(const avalue: colorty); + procedure setcolor(const avalue: colorty); + function getface: tface; + procedure setface(const avalue: tface); + function getfacechecked: tface; + procedure setfacechecked(const avalue: tface); + function getframe: tframe; + procedure setframe(const avalue: tframe); + function getframechecked: tframe; + procedure setframechecked(const avalue: tframe); + function getframesephorz: tframe; + procedure setframesephorz(const avalue: tframe); + function getframesepvert: tframe; + procedure setframesepvert(const avalue: tframe); + protected + fbuttonstate: toolbuttonsstatesty; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure dochange(const index: integer); override; + procedure objectchanged(const sender: tobject); + class function getbuttonclass: toolbuttonclassty; virtual; + public + constructor create(const aowner: tcustomtoolbar); reintroduce; + destructor destroy(); override; + class function getitemclasstype(): persistentclassty; override; + procedure createface(); + procedure createfacechecked(); + procedure createframe(); + procedure createframechecked(); + procedure createframesephorz(); + procedure createframesepvert(); + procedure doupdate(); + procedure resetradioitems(const group: integer); + function getcheckedradioitem(const group: integer): tcustomtoolbutton; + function add: tcustomtoolbutton; + property items[const index: integer]: tcustomtoolbutton + read getitems write setitems; default; + published + property width: integer read fwidth write setwidth default 0; + property height: integer read fheight write setheight default 0; + property imagelist: timagelist read fimagelist write setimagelist; + property colorglyph: colorty read fcolorglyph + write setcolorglyph default cl_default; + //cl_default -> cl_glyph + property color: colorty read fcolor write setcolor default cl_default; + //cl_default -> cl_transparent + property face: tface read getface write setface; + property facechecked: tface read getfacechecked write setfacechecked; + property frame: tframe read getframe write setframe; + property framechecked: tframe read getframechecked write setframechecked; + property framesephorz: tframe read getframesephorz + write setframesephorz; + property framesepvert: tframe read getframesepvert + write setframesepvert; + end; + + ttoolbuttons = class(tcustomtoolbuttons) + protected + class function getbuttonclass: toolbuttonclassty; override; + published + property width; + property height; + property imagelist; + property colorglyph; + property color; + property face; + property frame; + property framesephorz; + property framesepvert; + end; + + tstockglyphtoolbuttons = class(ttoolbuttons) + protected + class function getbuttonclass: toolbuttonclassty; override; + end; + + toolbaroptionty = (tbo_dragsource,tbo_dragdest, + tbo_dragsourceenabledonly,tbo_dragdestenabledonly, + tbo_nohorz,tbo_novert, + tbo_shortcuthint); + toolbaroptionsty = set of toolbaroptionty; + + toolbarlayoutinfoty = record + vert: boolean; + buttons: ttoolbuttons; + cells: shapeinfoarty; + stepinfo: framestepinfoty; +// maxbuttons: integer; + focusedbutton: integer; + lines: integer; + buttonsize: sizety; + defaultsize: sizety; + end; + + toolbuttoneventty = procedure(const sender: tobject; + const button: tcustomtoolbutton) of object; + + tcustomtoolbar = class(tcustomstepbox,istatfile,iframe) + private + flayoutok: boolean; + foptions: toolbaroptionsty; + fonbuttonchanged: toolbuttoneventty; + fhintedbutton: integer; + fupdating: integer; + ffirstbutton: integer; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: integer; + procedure setbuttons(const Value: ttoolbuttons); + procedure setoptions(const Value: toolbaroptionsty); + function gethintpos(const aindex: integer): rectty; + function getbuttonhint(const aindex: integer): msestring; + procedure setfirstbutton(value: integer); + procedure buttonschanged(const sender: tarrayprop; const index: integer); + procedure setstatfile(const Value: tstatfile); + procedure setdragcontroller(const Value: tdragcontroller); + protected + flayout: toolbarlayoutinfoty; + class function classskininfo: skininfoty; override; + procedure buttonchanged(sender: tcustomtoolbutton); + procedure checkvert(const asize: sizety); + function getseparatorwidth(): integer; + procedure getautopaintsize(var asize: sizety); override; + procedure updatelayout; + procedure clientrectchanged; override; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure showhint(const aid: int32; var info: hintinfoty); override; + function dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; override; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); override; + procedure objectchanged(const sender: tobject); override; + //iassistiveclient + function getassistivehint(): msestring; override; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure dragevent(var info: draginfoty); override; + procedure beginupdate; + procedure endupdate; + function buttonatpos(const apos: pointty; const enabledonly: boolean = false): tcustomtoolbutton; + + property buttons: ttoolbuttons read flayout.buttons write setbuttons; + property firstbutton: integer read ffirstbutton write setfirstbutton default 0; + property options: toolbaroptionsty read foptions write setoptions default []; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + + property onbuttonchanged: toolbuttoneventty read fonbuttonchanged write fonbuttonchanged; + property drag: tdragcontroller read fdragcontroller write setdragcontroller; + + end; + + ttoolbar = class(tcustomtoolbar) + published + property frame; + property onstep; + + property optionswidget default defaultoptionswidgetnofocus; + property buttons; + property firstbutton; + property options; + property statfile; + property statvarname; + property statpriority; + property onbuttonchanged; + property drag; + end; + +implementation +uses + sysutils,msebits,mseactions,msestockobjects; + +const + separatorwidth = 3; +type + tcustomstepframe1 = class(tcustomstepframe); + twidget1 = class(twidget); + +procedure drawtoolbuttons(const canvas: tcanvas; + var layout: toolbarlayoutinfoty); +var + int1: integer; + rect1: rectty; + po1: pshapeinfoty; +begin + with layout do begin + rect1:= canvas.clipbox; + for int1:= 0 to high(cells) do begin + po1:= @cells[int1]; + with po1^ do begin + if testintersectrect(rect1,ca.dim) then begin + if shs_checked in state then begin + face:= buttons.ffacechecked; + end + else begin + face:= buttons.fface; + end; + if shs_separator in state then begin + if vert then begin + frame:= buttons.framesepvert; + end + else begin + frame:= buttons.framesephorz; + end; + end + else begin + if shs_checked in state then begin + frame:= buttons.framechecked; + end + else begin + frame:= buttons.frame; + end; + end; + drawtoolbutton(canvas,po1^); + end; + end; + end; + end; +end; + +{ tcustomtoolbutton } + +constructor tcustomtoolbutton.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + initactioninfo(finfo); + finfo.color:= ttoolbuttons(aprop).color; + finfo.colorglyph:= ttoolbuttons(aprop).colorglyph; + inherited; +end; + +constructor tcustomtoolbutton.create(aowner: tcustomtoolbar); +begin + create(aowner,aowner.buttons); +end; + +procedure tcustomtoolbutton.objectevent(const sender: tobject; const event: objecteventty); +begin + inherited; + if sender = finfo.imagelist then begin + if event = oe_destroyed then begin + finfo.imagelist:= nil; + end; + changed; + end; +end; + +procedure tcustomtoolbutton.actionchanged; +begin + changed; +end; + +function tcustomtoolbutton.getactioninfopo: pactioninfoty; +begin + result:= @finfo; +end; + +function tcustomtoolbutton.toolbar: tcustomtoolbar; +begin + result:= tcustomtoolbar(fowner); +end; + +procedure tcustomtoolbutton.setaction(const Value: tcustomaction); +begin + linktoaction(iactionlink(self),value,finfo); +end; + +function tcustomtoolbutton.getstate: actionstatesty; +begin + result:= finfo.state; +end; + +procedure tcustomtoolbutton.setstate(const Value: actionstatesty); +begin + setactionstate(iactionlink(self),value); +end; + +function tcustomtoolbutton.isstatestored: Boolean; +begin + result:= isactionstatestored(finfo); +end; + +function tcustomtoolbutton.getimagelist: timagelist; +begin + result:= timagelist(finfo.imagelist); +end; + +procedure tcustomtoolbutton.setimagelist(const Value: timagelist); +begin + setactionimagelist(iactionlink(self),value); +end; + +function tcustomtoolbutton.isimageliststored: Boolean; +begin + result:= isactionimageliststored(finfo); +end; + +function tcustomtoolbutton.getshortcut: shortcutty; +begin + result:= getsimpleshortcut(finfo); +end; + +function tcustomtoolbutton.getshortcut1: shortcutty; +begin + result:= getsimpleshortcut1(finfo); +end; + +procedure tcustomtoolbutton.setshortcut(const Value: shortcutty); +begin + setactionshortcut(iactionlink(self),value); +end; + +function tcustomtoolbutton.isshortcutstored: Boolean; +begin + result:= isactionshortcutstored(finfo); +end; + +procedure tcustomtoolbutton.setshortcut1(const Value: shortcutty); +begin + setactionshortcut1(iactionlink(self),value); +end; + +function tcustomtoolbutton.isshortcut1stored: Boolean; +begin + result:= isactionshortcut1stored(finfo); +end; + +procedure tcustomtoolbutton.setimagenr(const Value: imagenrty); +begin + setactionimagenr(iactionlink(self),value); +end; + +procedure tcustomtoolbutton.setimagenrdisabled(const Value: imagenrty); +begin + setactionimagenrdisabled(iactionlink(self),value); +end; + +procedure tcustomtoolbutton.setcolorglyph(const avalue: colorty); +begin + setactioncolorglyph(iactionlink(self),avalue); +end; + +function tcustomtoolbutton.iscolorglyphstored: boolean; +begin + result:= isactioncolorglyphstored(finfo); +end; + +procedure tcustomtoolbutton.setcolor(const avalue: colorty); +begin + setactioncolor(iactionlink(self),avalue); +end; + +function tcustomtoolbutton.iscolorstored: boolean; +begin + result:= isactioncolorstored(finfo); +end; + +procedure tcustomtoolbutton.setimagecheckedoffset(const Value: integer); +begin + setactionimagecheckedoffset(iactionlink(self),value); +end; + +function tcustomtoolbutton.isimagenrstored: Boolean; +begin + result:= isactionimagenrstored(finfo); +end; + +function tcustomtoolbutton.isimagenrdisabledstored: Boolean; +begin + result:= isactionimagenrdisabledstored(finfo); +end; + +function tcustomtoolbutton.isimagecheckedoffsetstored: Boolean; +begin + result:= isactionimagecheckedoffsetstored(finfo); +end; + +procedure tcustomtoolbutton.sethint(const Value: msestring); +begin + setactionhint(iactionlink(self),value); +end; + +function tcustomtoolbutton.ishintstored: Boolean; +begin + result:= isactionhintstored(finfo); +end; + +procedure tcustomtoolbutton.setonexecute(const avalue: notifyeventty); +begin + setactiononexecute(iactionlink(self),avalue, + csloading in toolbar.componentstate); +end; + +function tcustomtoolbutton.isonexecutestored: Boolean; +begin + result:= isactiononexecutestored(finfo); +end; + +procedure tcustomtoolbutton.setonbeforeexecute(const avalue: accepteventty); +begin + setactiononbeforeexecute(iactionlink(self),avalue, + csloading in toolbar.componentstate); +end; + +function tcustomtoolbutton.isonbeforeexecutestored: Boolean; +begin + result:= isactiononbeforeexecutestored(finfo); +end; + +procedure tcustomtoolbutton.setonafterexecute(const avalue: notifyeventty); +begin + setactiononafterexecute(iactionlink(self),avalue, + csloading in toolbar.componentstate); +end; + +function tcustomtoolbutton.isonafterexecutestored: Boolean; +begin + result:= isactiononafterexecutestored(finfo); +end; + +procedure tcustomtoolbutton.setgroup(const Value: integer); +begin + setactiongroup(iactionlink(self),value); +end; + +function tcustomtoolbutton.isgroupstored: Boolean; +begin + result:= isactiongroupstored(finfo); +end; + +procedure tcustomtoolbutton.changed; +begin + tcustomtoolbar(fowner).buttonchanged(self); +end; + +function tcustomtoolbutton.index: integer; +begin + result:= findex; +end; + +function tcustomtoolbutton.getchecked: boolean; +begin + result:= as_checked in finfo.state; +end; + +procedure tcustomtoolbutton.setchecked(const Value: boolean); +begin + if value then begin + state:= state + [as_checked]; + end + else begin + state:= state - [as_checked]; + end; +end; + +procedure tcustomtoolbutton.doexecute(const tag: integer; + const info: mouseeventinfoty); +begin + if doactionexecute(self,finfo,false, + tbs_nocandefocus in ttoolbuttons(prop).fbuttonstate) then begin + changed; + end; +end; + +procedure tcustomtoolbutton.execute; +begin + doexecute(-1,pmouseeventinfoty(nil)^); +end; + +procedure tcustomtoolbutton.setoptions(const Value: menuactionoptionsty); +begin + if finfo.options <> value then begin + finfo.options := Value; + changed; + end; +end; + +procedure tcustomtoolbutton.doshortcut(var info: keyeventinfoty); +begin + if doactionshortcut(self,finfo,info) then begin + changed; + end; +end; + +function tcustomtoolbutton.getenabled: boolean; +begin + result:= not (as_disabled in finfo.state); +end; + +procedure tcustomtoolbutton.setenabled(const avalue: boolean); +begin + if avalue then begin + state:= state - [as_disabled]; + end + else begin + state:= state + [as_disabled]; + end; +end; + +function tcustomtoolbutton.getvisible: boolean; +begin + result:= not (as_invisible in finfo.state); +end; + +procedure tcustomtoolbutton.setvisible(const avalue: boolean); +begin + if avalue then begin + state:= state - [as_invisible]; + end + else begin + state:= state + [as_invisible]; + end; +end; + +function tcustomtoolbutton.getinstance: tobject; +begin + result:= fowner; +end; + +function tcustomtoolbutton.loading: boolean; +begin + result:= (fowner is tcomponent) and + (csloading in tcomponent(fowner).componentstate); +end; + +function tcustomtoolbutton.shortcutseparator: msechar; +begin + result:= ' '; +end; + +procedure tcustomtoolbutton.calccaptiontext(var ainfo: actioninfoty); +begin + mseactions.calccaptiontext(ainfo,shortcutseparator); +end; + +procedure tcustomtoolbutton.readbool(reader: treader); +begin + reader.readboolean; //dummy +end; + +procedure tcustomtoolbutton.writebool(writer: twriter); +begin + //dummy +end; + +procedure tcustomtoolbutton.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('visible',{$ifdef FPC}@{$endif}readbool, + {$ifdef FPC}@{$endif}writebool,false); + filer.defineproperty('enabled',{$ifdef FPC}@{$endif}readbool, + {$ifdef FPC}@{$endif}writebool,false); +end; + +procedure tcustomtoolbutton.setshortcuts(const avalue: shortcutarty); +begin + setactionshortcuts(iactionlink(self),avalue); +end; + +procedure tcustomtoolbutton.setshortcuts1(const avalue: shortcutarty); +begin + setactionshortcuts1(iactionlink(self),avalue); +end; + +procedure tcustomtoolbutton.doupdate; +begin + if finfo.action <> nil then begin + finfo.action.doupdate; + end; +end; + +{ ttoolbuttonframe } + +constructor ttoolbuttonframe.create(const aintf: iframe); +begin + include(fstate,fs_nosetinstance); + inherited; + fi.optionsskin:= defaulttoolbuttonoptionsskin; +end; + +{ ttoolseparatorframe } + +constructor ttoolseparatorframe.create(const aintf: iframe); +begin + inherited; + fi.optionsskin:= defaulttoolseparatoroptionsskin; +end; + +{ tcustomtoolbuttons } + +constructor tcustomtoolbuttons.create(const aowner: tcustomtoolbar); +begin + fcolorglyph:= cl_default; + fcolor:= cl_default; + inherited create(aowner,getbuttonclass); +end; + +destructor tcustomtoolbuttons.destroy; +begin + inherited; + fface.free; + ffacechecked.free; + fframe.free(); + fframechecked.free(); + fframesephorz.free(); + fframesepvert.free(); +end; + +class function tcustomtoolbuttons.getitemclasstype: persistentclassty; +begin + result:= ttoolbutton; +end; + +function tcustomtoolbuttons.add: tcustomtoolbutton; +begin + count:= count + 1; + result:= items[count-1]; +end; + +procedure tcustomtoolbuttons.createitem(const index: integer; var item: tpersistent); +begin + inherited; + if not (csloading in tcustomtoolbar(fowner).componentstate) then begin + with tcustomtoolbutton(item) do begin + if fimagelist <> nil then begin + imagelist:= fimagelist; + end; + if fcolorglyph <> cl_default then begin + colorglyph:= fcolorglyph; + end; + if fcolor <> cl_default then begin + color:= fcolor; + end; +// state:= state - [as_localimagelist,as_localcolorglyph,as_localcolor]; + end; + end; +end; + +procedure tcustomtoolbuttons.dochange(const index: integer); +var + int1: integer; + po1: ptoolbutton; +begin + if index < 0 then begin + po1:= pointer(fitems); + for int1:= 0 to high(fitems) do begin + po1^.findex:= int1; + inc(po1); + end; + end + else begin + tcustomtoolbutton(fitems[index]).findex:= index; + end; + inherited; +end; + +function tcustomtoolbuttons.getcheckedradioitem( + const group: integer): tcustomtoolbutton; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if (finfo.group = group) and + (mao_radiobutton in finfo.options) and (as_checked in finfo.state) then begin + result:= items[int1]; + break; + end; + end; + end; +end; + +procedure tcustomtoolbuttons.resetradioitems(const group: integer); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if (finfo.group = group) and (as_checked in finfo.state) then begin + state:= finfo.state - [as_checked]; + end; + end; + end; +end; + +function tcustomtoolbuttons.getitems(const index: integer): tcustomtoolbutton; +begin + result:= tcustomtoolbutton(inherited items[index]); +end; + +procedure tcustomtoolbuttons.setitems(const index: integer; + const Value: tcustomtoolbutton); +begin + inherited items[index].assign(value); +end; + +procedure tcustomtoolbuttons.setheight(const Value: integer); +begin + if fheight <> value then begin + fheight:= Value; + dochange(-1); + end; +end; + +procedure tcustomtoolbuttons.setwidth(const Value: integer); +begin + if fwidth <> value then begin + fwidth:= Value; + dochange(-1); + end; +end; + +procedure tcustomtoolbuttons.setimagelist(const avalue: timagelist); +var + int1: integer; +begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + if not (csloading in tcomponent(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + items[int1].imagelist:= avalue; + end; + end; +end; + +procedure tcustomtoolbuttons.setcolorglyph(const avalue: colorty); +var + int1: integer; +begin + fcolorglyph:= avalue; + if not (csloading in tcomponent(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + items[int1].colorglyph:= avalue; + end; + end; +end; + +procedure tcustomtoolbuttons.setcolor(const avalue: colorty); +var + int1: integer; +begin + fcolor:= avalue; + if not (csloading in tcomponent(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + items[int1].color:= avalue; + end; + end; +end; + +procedure tcustomtoolbuttons.createface; +begin + if fface = nil then begin + fface:= tface.create(iface(tcustomtoolbar(fowner))); + end; +end; + +procedure tcustomtoolbuttons.createfacechecked(); +begin + if ffacechecked = nil then begin + ffacechecked:= tface.create(iface(tcustomtoolbar(fowner))); + end; +end; + +function tcustomtoolbuttons.getface: tface; +begin + tcustomtoolbar(fowner).getoptionalobject(fface,@createface); + result:= fface; +end; + +procedure tcustomtoolbuttons.setface(const avalue: tface); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,fface,@createface); + tcustomtoolbar(fowner).invalidate; +end; + +function tcustomtoolbuttons.getfacechecked: tface; +begin + tcustomtoolbar(fowner).getoptionalobject(ffacechecked,@createfacechecked); + result:= ffacechecked; +end; + +procedure tcustomtoolbuttons.setfacechecked(const avalue: tface); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,ffacechecked, + @createfacechecked); + tcustomtoolbar(fowner).invalidate; +end; + +function tcustomtoolbuttons.getframe: tframe; +begin + tcustomtoolbar(fowner).getoptionalobject(fframe,@createframe); + result:= fframe; +end; + +procedure tcustomtoolbuttons.setframe(const avalue: tframe); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,fframe,@createframe); + tcustomtoolbar(fowner).clientrectchanged(); +end; + +function tcustomtoolbuttons.getframechecked: tframe; +begin + tcustomtoolbar(fowner).getoptionalobject(fframe,@createframechecked); + result:= fframechecked; +end; + +procedure tcustomtoolbuttons.setframechecked(const avalue: tframe); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,fframechecked, + @createframechecked); + tcustomtoolbar(fowner).clientrectchanged(); +end; + +function tcustomtoolbuttons.getframesephorz: tframe; +begin + tcustomtoolbar(fowner).getoptionalobject(fframesephorz, + @createframesephorz); + result:= fframesephorz; +end; + +procedure tcustomtoolbuttons.setframesephorz(const avalue: tframe); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,fframesephorz, + @createframesephorz); + tcustomtoolbar(fowner).clientrectchanged(); +end; + +function tcustomtoolbuttons.getframesepvert: tframe; +begin + tcustomtoolbar(fowner).getoptionalobject(fframesepvert, + @createframesepvert); + result:= fframesepvert; +end; + +procedure tcustomtoolbuttons.setframesepvert(const avalue: tframe); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,fframesepvert, + @createframesepvert); + tcustomtoolbar(fowner).clientrectchanged(); +end; + +procedure tcustomtoolbuttons.createframe(); +begin + if fframe = nil then begin + fframe:= ttoolbuttonframe.create(iframe(tcustomtoolbar(fowner))); + end; +end; + +procedure tcustomtoolbuttons.createframechecked(); +begin + if fframechecked = nil then begin + fframechecked:= ttoolbuttonframe.create(iframe(tcustomtoolbar(fowner))); + end; +end; + +procedure tcustomtoolbuttons.createframesephorz(); +begin + if fframesephorz = nil then begin + fframesephorz:= ttoolseparatorframe.create(iframe(tcustomtoolbar(fowner))); + end; +end; + +procedure tcustomtoolbuttons.createframesepvert(); +begin + if fframesepvert = nil then begin + fframesepvert:= ttoolseparatorframe.create(iframe(tcustomtoolbar(fowner))); + end; +end; + +procedure tcustomtoolbuttons.objectchanged(const sender: tobject); +begin + if fface <> nil then begin + fface.checktemplate(sender); + end; +end; + +class function tcustomtoolbuttons.getbuttonclass: toolbuttonclassty; +begin + result:= tcustomtoolbutton; +end; + +procedure tcustomtoolbuttons.doupdate; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tcustomtoolbutton(fitems[int1]) do begin + doupdate; + end; + end; +end; + +{ ttoolbuttons } + +class function ttoolbuttons.getbuttonclass: toolbuttonclassty; +begin + result:= ttoolbutton; +end; + +{ tcustomtoolbar } + +constructor tcustomtoolbar.create(aowner: tcomponent); +begin + if flayout.buttons = nil then begin + flayout.buttons:= ttoolbuttons.create(self); + end; + flayout.buttons.onchange:= {$ifdef FPC}@{$endif}buttonschanged; + fhintedbutton:= -2; + inherited; +end; + +destructor tcustomtoolbar.destroy; +begin + inherited; + flayout.buttons.Free; +end; + +procedure tcustomtoolbar.checkvert(const asize: sizety); +var + si1: sizety; +begin + with flayout do begin + si1:= framesize; + vert:= si1.cy > si1.cx; +// vert:= asize.cy > asize.cx; + if (tbo_novert in foptions) then begin + vert:= false; + end; + if (tbo_nohorz in foptions) then begin + vert:= true; + end; + buttonsize:= asize; + if vert then begin + if buttons.fwidth > 0 then begin + buttonsize.cx:= buttons.fwidth; + end; + if buttons.fheight = 0 then begin + buttonsize.cy:= buttonsize.cx; + end + else begin + buttonsize.cy:= buttons.fheight; + end; + end + else begin + if buttons.fheight > 0 then begin + buttonsize.cy:= buttons.fheight; + end; + if buttons.fwidth = 0 then begin + buttonsize.cx:= buttonsize.cy; + end + else begin + buttonsize.cx:= buttons.fwidth; + end; + end; + end; +end; + +procedure tcustomtoolbar.getautopaintsize(var asize: sizety); +var + int1: integer; + size1: sizety; + sepwidth1: integer; +begin + with flayout do begin + if (defaultsize.cx = 0) or (buttons.width = 0) or + (defaultsize.cy = 0) or (buttons.height = 0) then begin + size1:= asize; + if fframe <> nil then begin + size1.cx:= size1.cx - fframe.framei_left - fframe.framei_right; + size1.cy:= size1.cy - fframe.framei_top - fframe.framei_bottom; + end; + checkvert(size1); + sepwidth1:= getseparatorwidth(); + if vert then begin + defaultsize.cx:= buttonsize.cx; + defaultsize.cy:= 0; + for int1:= 0 to buttons.count - 1 do begin + with buttons[int1] do begin + if not (as_invisible in state) then begin + if mao_separator in options then begin + inc(defaultsize.cy,sepwidth1); + end + else begin + inc(defaultsize.cy,buttonsize.cy); + end; + end; + end; + end; + end + else begin + defaultsize.cy:= buttonsize.cy; + defaultsize.cx:= 0; + for int1:= 0 to buttons.count - 1 do begin + with buttons[int1] do begin + if not (as_invisible in state) then begin + if mao_separator in options then begin + inc(defaultsize.cx,sepwidth1); + end + else begin + inc(defaultsize.cx,buttonsize.cx); + end; + end; + end; + end; + end; + if fframe <> nil then begin + defaultsize.cx:= defaultsize.cx + fframe.framei_left + fframe.framei_right; + defaultsize.cy:= defaultsize.cy + fframe.framei_top + fframe.framei_bottom; + end; + end; + asize:= defaultsize; + end; +end; + +procedure tcustomtoolbar.updatelayout; + +var + buttonsizecxy: integer; + sepwidth1: integer; + + function step(const index: integer): integer; + begin + result:= 0; + with flayout,buttons[index] do begin + if not (as_invisible in state)then begin + if mao_separator in options then begin + result:= sepwidth1; + end + else begin + result:= buttonsizecxy; + end; + end; + end; + end; + +var + int1,int2,int3: integer; + i2: int32; + rect1,rect2: rectty; + endxy: integer; +// bu1: stepbuttonposty; + loopcount: integer; + size1: sizety; + pageend: integer; + bo1: boolean; + bu1: stepkindsty; +begin + if fupdating <> 0 then begin + flayoutok:= false; + end + else begin + inc(fupdating); + try + loopcount:= 0; + tcustomstepframe1(fframe).neededbuttons:= []; + repeat + flayoutok:= true; + rect1:= innerclientrect; + rect2:= rect1; + inc(loopcount); + with flayout do begin + defaultsize:= nullsize; + checkvert(rect1.size); + sepwidth1:= getseparatorwidth(); +// bu1:= frame.buttonpos; + if frame.buttonpos in [sbp_top,sbp_right] then begin + if vert then begin + frame.buttonpos:= sbp_top; + end + else begin + frame.buttonpos:= sbp_right; + end; + end + else begin + if vert then begin + frame.buttonpos:= sbp_bottom; + end + else begin + frame.buttonpos:= sbp_left; + end; + end; + rect1.size:= buttonsize; + if vert then begin + if rect1.cx > 0 then begin + lines:= rect2.cx div rect1.cx; + if lines <= 0 then begin + lines:= 1; + end; + end + else begin + lines:= 1; + end; + end + else begin + if rect1.cy > 0 then begin + lines:= rect2.cy div rect1.cy; + if lines <= 0 then begin + lines:= 1; + end; + end + else begin + lines:= 1; + end; + end; + + setlength(cells,buttons.count); + if vert then begin + endxy:= rect2.y + rect2.cy; + end + else begin + endxy:= rect2.x + rect2.cx; + end; + if vert then begin + buttonsizecxy:= rect1.cy; + end + else begin + buttonsizecxy:= rect1.cx; + end; + int3:= lines - 1; +// for int1:= 0 to high(cells) do begin +// actioninfotoshapeinfo(buttons[int1].finfo,cells[int1]); +// end; + with stepinfo do begin + pageend:= buttons.count; + pageup:= pageend; + up:= 0; + if ffirstbutton >= pageend then begin + ffirstbutton:= 0; //count changed + end; + for int1:= ffirstbutton to pageend - 1 do begin + with cells[int1] do begin + color:= cl_parent; + actioninfotoshapeinfo(buttons[int1].finfo,cells[int1]); + if color = cl_default then begin + color:= cl_transparent; + end; + if ca.colorglyph = cl_default then begin + ca.colorglyph:= cl_glyph; + end; + if shs_separator in state then begin + exclude(state,shs_flat); + end + else begin + include(state,shs_flat); + end; + if state * [shs_checkbox,shs_radiobutton] <> [] then begin + include(state,shs_checkbutton); + end; + doexecute:= {$ifdef FPC}@{$endif}buttons[int1].doexecute; + if not (as_invisible in buttons[int1].state) then begin + if vert then begin + rect1.cy:= step(int1); + end + else begin + rect1.cx:= step(int1); + end; + if not (mao_separator in buttons[int1].options) then begin + if up = 0 then begin + up:= int1 - ffirstbutton; + end; + end; + if vert and (rect1.y + rect1.cy > endxy) or + not vert and (rect1.x + rect1.cx > endxy) then begin + i2:= int1; + if i2 = ffirstbutton then begin + inc(i2); + end; + if stepinfo.pageup = buttons.count then begin //first loop + pageup:= i2; + end; + if (int3 > 0) then begin + dec(int3); + if vert then begin + inc(rect1.x,rect1.cx); + rect1.y:= rect2.y; + end + else begin + inc(rect1.y,rect1.cy); + rect1.x:= rect2.x; + end; + end + else begin + pageend:= i2; + break; + end; + end; + ca.dim:= rect1; + if vert then begin + inc(rect1.y,rect1.cy); + end + else begin + inc(rect1.x,rect1.cx); + end; + end + else begin + include(state,shs_invisible); + end; + end; + end; + pagedown:= 0; + down:= 0; + if vert then begin + int2:= rect2.cy; + end + else begin + int2:= rect2.cx; + end; + for int1:= ffirstbutton - 1 downto 0 do begin + include(cells[int1].state,shs_invisible); + if not (as_invisible in buttons[int1].state)then begin + if mao_separator in buttons[int1].options then begin + dec(int2,sepwidth1); + end + else begin + if vert then begin + dec(int2,buttons.fheight); + end + else begin + dec(int2,buttons.fwidth); + end; + if down = 0 then begin + down:= int1 - ffirstbutton; + end; + end; + if int2 < 0 then begin + if int1 = ffirstbutton - 1 then begin + pagedown:= int1; + end + else begin + pagedown:= int1 + 1; + end; + break; + end; + end; + end; + for int1:= pageend to high(cells) do begin + include(cells[int1].state,shs_invisible); + end; + pagelast:= 0; + int3:= lines; + if vert then begin + int2:= rect2.cy; + end + else begin + int2:= rect2.cx; + end; + bo1:= false; + for int1:= high(cells) downto 0 do begin //calc pagelast + dec(int2,step(int1)); + if int2 < 0 then begin + dec(int3); + if int3 = 0 then begin + pagelast:= int1+1; + break; + end; + if vert then begin + int2:= rect2.cy; + end + else begin + int2:= rect2.cx; + end; + if bo1 then begin //at least one button + dec(int2,step(int1)); //move button on next line + bo1:= false; + end; + end + else begin + bo1:= true; + end; + if pagelast > high(cells) then begin + pagelast:= high(cells); + end; + end; + pagelast:= pagelast - ffirstbutton; + pageup:= pageup - ffirstbutton; + pagedown:= pagedown - ffirstbutton; + if up = 0 then begin + up:= 1; + end; + if down = 0 then begin + down:= -1; + end; + bu1:= tcustomstepframe1(fframe).neededbuttons; + frame.updatebuttonstate(ffirstbutton,pageend-ffirstbutton,buttons.count); + flayoutok:= flayoutok and (bu1 = tcustomstepframe1(fframe).neededbuttons); + end; + if flayoutok then begin + size1:= self.size; + checkautosize; + if (size1.cx <> bounds_cx) or (size1.cy <> bounds_cy) then begin + tcustomstepframe1(fframe).neededbuttons:= []; + flayoutok:= false; //try again + end; + end; + end; + until flayoutok or (loopcount > 8); + invalidate; + finally + dec(fupdating); + end; + end; +end; + +class function tcustomtoolbar.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_toolbar; +end; + +procedure tcustomtoolbar.buttonchanged(sender: tcustomtoolbutton); +var + int1: integer; + button1: tcustomtoolbutton; + bo1: boolean; +begin + with flayout do begin + if sender.checked and (mao_radiobutton in sender.options) then begin + for int1:= 0 to buttons.count -1 do begin + button1:= buttons[int1]; + if (button1 <> sender) and (button1.checked) and + (button1.group = sender.group) then begin + button1.checked:= false; + end; + end; + end; + for int1:= 0 to buttons.count - 1 do begin + button1:= buttons[int1]; + if int1 >= length(cells) then begin + break; + end; + if button1 = sender then begin + with cells[int1] do begin + bo1:= (shs_invisible in state) xor (as_invisible in button1.finfo.state) or + ((shs_separator in state) xor (mao_separator in button1.options)) or + ((shs_checkbox in state) xor (mao_checkbox in button1.options)) or + ((shs_radiobutton in state) xor (mao_radiobutton in button1.options)); + actionstatestoshapestates(button1.finfo,state); + ca.imagenr:= buttons[int1].finfo.imagenr; + ca.colorglyph:= buttons[int1].finfo.colorglyph; + if ca.colorglyph = cl_default then begin + ca.colorglyph:= cl_glyph; + end; + color:= buttons[int1].finfo.color; + if color = cl_default then begin + color:= cl_transparent; + end; + ca.imagelist:= timagelist(buttons[int1].finfo.imagelist); + doexecute:= {$ifdef FPC}@{$endif}buttons[int1].doexecute; + invalidaterect(ca.dim); + if bo1 then begin + updatelayout; + end; + end; + break; + end; + end; + end; + if canevent(tmethod(fonbuttonchanged)) then begin + fonbuttonchanged(self,sender); + end; +end; + +procedure tcustomtoolbar.setbuttons(const Value: ttoolbuttons); +begin + flayout.buttons.assign(Value); +end; +{ +procedure ttoolbar.setimagebase(const Value: integer); +begin + if fimagebase <> value then begin + fimagebase:= Value; + invalidate; + end; +end; + +procedure ttoolbar.setimagelist(const Value: timagelist); +begin + setcomponentvar(value,tmsecomponent(fimagelist)); + invalidate; +end; +} +procedure tcustomtoolbar.setoptions(const Value: toolbaroptionsty); +const + mask: toolbaroptionsty = [tbo_nohorz,tbo_novert]; +var + valbefore: toolbaroptionsty; +begin + if foptions <> value then begin + valbefore:= foptions; + foptions:= toolbaroptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(value), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + if ({$ifdef FPC}longword{$else}byte{$endif}(valbefore) xor + {$ifdef FPC}longword{$else}byte{$endif}(foptions)) and + {$ifdef FPC}longword{$else}byte{$endif}(mask) <> 0 then begin + updatelayout; + end; + end; +end; + +procedure tcustomtoolbar.setfirstbutton(value: integer); +begin + if value >= flayout.buttons.count - 1 then begin + value:= flayout.buttons.count - 1; + end; + if value < 0 then begin + value:= 0; + end; + if ffirstbutton <> value then begin + ffirstbutton:= value; + updatelayout; + end; +end; + +procedure tcustomtoolbar.buttonschanged(const sender: tarrayprop; const index: integer); +begin + updatelayout; +end; + +procedure tcustomtoolbar.clientrectchanged; +begin + inherited; + updatelayout; +end; + +procedure tcustomtoolbar.dopaintforeground(const canvas: tcanvas); +begin + inherited; + drawtoolbuttons(canvas,flayout) +end; + +function tcustomtoolbar.gethintpos(const aindex: integer): rectty; +begin + result:= flayout.cells[aindex].ca.dim; + inc(result.cy,12); +end; + +function tcustomtoolbar.getbuttonhint(const aindex: integer): msestring; +begin + with buttons[aindex] do begin + result:= hint; + if (tbo_shortcuthint in self.foptions) and (shortcut <> 0) then begin + if result <> '' then begin + result:= result + ' '; + end; + result:= result + '('+encodeshortcutname(shortcut)+')'; + end; + end; +end; + +procedure tcustomtoolbar.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (csdesigning in componentstate) or + (ws1_designactive in fwidgetstate1) then begin + with flayout do begin + if updatemouseshapestate(cells,info,self,flayout.focusedbutton) then begin + end; + checkbuttonhint(self,info,fhintedbutton,flayout.cells, + {$ifdef FPC}@{$endif}getbuttonhint,{$ifdef FPC}@{$endif}gethintpos); + end; + end; +end; + +procedure tcustomtoolbar.showhint(const aid: int32; var info: hintinfoty); +begin + inherited; +end; + +function tcustomtoolbar.dostep(const event: stepkindty; + const adelta: real;ashiftstate: shiftstatesty): boolean; +begin + result:= false; + if frame.canstep then begin + firstbutton:= frame.executestepevent(event,flayout.stepinfo,ffirstbutton); + result:= true; + end; +end; + +procedure tcustomtoolbar.beginupdate; +begin + inc(fupdating); +end; + +procedure tcustomtoolbar.endupdate; +begin + dec(fupdating); + updatelayout; +end; +{ +procedure tcustomtoolbar.setinvisiblebuttons(const Value: stepkindsty); +begin + inherited; + if not (csloading in componentstate) then begin + updatelayout; + end; +end; +} +function tcustomtoolbar.buttonatpos(const apos: pointty; const enabledonly: boolean = false): tcustomtoolbutton; +var + int1: integer; +begin + begin + if enabledonly then begin + int1:= findshapeatpos(flayout.cells,apos,[shs_invisible,shs_disabled]); + end + else begin + int1:= findshapeatpos(flayout.cells,apos,[shs_invisible]); + end; + if int1 >= 0 then begin + result:= flayout.buttons[int1]; + end + else begin + result:= nil; + end; + end; +end; + +procedure tcustomtoolbar.dragevent(var info: draginfoty); +var + button1: tcustomtoolbutton; + + function candest: boolean; + begin + with info do begin + if (tbo_dragdest in foptions) and (dragobjectpo^.sender = self) and + (dragobjectpo^ is tobjectdragobject) then begin + button1:= buttonatpos(pos,tbo_dragdestenabledonly in foptions); + result:= (button1 <> nil) and (tobjectdragobject(dragobjectpo).data <> button1); + end + else begin + result:= false; + end; + end; + end; + +begin + button1:= nil; + if not fdragcontroller.beforedragevent(info) then begin + with info do begin + case eventkind of + dek_begin: begin + if (dragobjectpo^ = nil) and (tbo_dragsource in foptions) then begin + button1:= buttonatpos(pos,tbo_dragsourceenabledonly in foptions); + if button1 <> nil then begin + tobjectdragobject.create(self,dragobjectpo^,fdragcontroller.pickpos,button1); + end; + end; + end; + dek_check: begin + if candest then begin + accept:= true; + end + else begin + inherited; + end; + end; + dek_drop: begin + if candest then begin + buttons.move(tcustomtoolbutton(tobjectdragobject(dragobjectpo^).data).index,button1.index); + end + else begin + inherited; + end; + end; + end; + end; + end; + fdragcontroller.afterdragevent(info); +end; + +procedure tcustomtoolbar.doshortcut(var info: keyeventinfoty; const sender: twidget); +var + int1: integer; +begin + for int1:= 0 to flayout.buttons.count - 1 do begin + if es_processed in info.eventstate then begin + exit; + end; + flayout.buttons[int1].doshortcut(info); + end; + inherited; +end; + +function tcustomtoolbar.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomtoolbar.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tcustomtoolbar.dostatread(const reader: tstatreader); +begin + flayout.buttons.dostatread(reader,tbo_dragdest in foptions); +end; + +procedure tcustomtoolbar.dostatwrite(const writer: tstatwriter); +begin + flayout.buttons.dostatwrite(writer,tbo_dragdest in foptions); +end; + +procedure tcustomtoolbar.statreading; +begin + //dummy +end; + +procedure tcustomtoolbar.statread; +begin + //dummy +end; + +procedure tcustomtoolbar.setdragcontroller(const Value: tdragcontroller); +begin + fdragcontroller.Assign(Value); +end; + +procedure tcustomtoolbar.objectchanged(const sender: tobject); +begin + inherited; + flayout.buttons.objectchanged(sender); +end; + +function tcustomtoolbar.getassistivehint(): msestring; +begin + if flayout.focusedbutton >= 0 then begin + result:= flayout.buttons[flayout.focusedbutton].hint; + end + else begin + result:= inherited getassistivehint(); + end; +end; + +function tcustomtoolbar.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +function tcustomtoolbar.getseparatorwidth: integer; +begin + if flayout.vert then begin + if flayout.buttons.fframesepvert <> nil then begin + with flayout.buttons.fframesepvert do begin + result:= innerframedim.cy; + if not (fso_flat in optionsskin) then begin + inc(result,separatorwidth); + end; + end; + end + else begin + result:= separatorwidth; + end; + end + else begin + if flayout.buttons.fframesephorz <> nil then begin + with flayout.buttons.fframesephorz do begin + result:= innerframedim.cx; + if not (fso_flat in optionsskin) then begin + inc(result,separatorwidth); + end; + end; + end + else begin + result:= separatorwidth; + end; + end; +end; + +{ tdocktoolbar } +{ +constructor tdocktoolbar.create(aowner: tcomponent); +begin + if fdragcontroller = nil then begin + fdragcontroller:= tdockcontroller.create(idockcontroller(self)); + end; + inherited; +end; + +procedure tdocktoolbar.createframe; +begin + tgripframe.create(iframe(self)); +end; + +function tdocktoolbar.getframe: tgripframe; +begin + result:= tgripframe(inherited getframe); +end; + +procedure tdocktoolbar.setframe(const avalue: tgripframe); +begin + inherited setframe(avalue); +end; + +function tdocktoolbar.getdrag: tdockcontroller; +begin + result:= tdockcontroller(fdragcontroller); +end; + +procedure tdocktoolbar.setdragcontroller(const avalue: tdockcontroller); +begin + inherited setdragcontroller(avalue); +end; + +function tdocktoolbar.checkdock(var info: draginfoty): boolean; +begin + result:= true; +end; + +function tdocktoolbar.gethandlerect: rectty; +begin + if fframe = nil then begin + result:= clientrect; + end + else begin + result:= tgripframe(fframe).handlerect; + end; +end; + +function tdocktoolbar.gethidebuttonrect: rectty; +begin + if fframe = nil then begin + result:= nullrect; + end + else begin + result:= tgripframe(fframe).hidebuttonrect; + end; +end; + +function tdocktoolbar.getplacementrect: rectty; +begin + result:= innerpaintrect; +end; + } + +{ tcustomstockglyphtoolbutton } + +constructor tcustomstockglyphtoolbutton.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + inherited; + finfo.imagelist:= stockobjects.glyphs; +end; + +function tcustomstockglyphtoolbutton.isimageliststored: boolean; +begin + result:= inherited isimageliststored and + (finfo.imagelist <> stockobjects.glyphs); +end; + +procedure tcustomstockglyphtoolbutton.setimagelist(const Value: timagelist); +begin + if value = nil then begin + inherited setimagelist(stockobjects.glyphs); + end + else begin + inherited setimagelist(value); + end; +end; + +{ tstockglyphtoolbuttons } + +class function tstockglyphtoolbuttons.getbuttonclass: toolbuttonclassty; +begin + result:= tstockglyphtoolbutton; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msetraywidget.pas b/mseide-msegui/lib/common/widgets/msetraywidget.pas new file mode 100644 index 0000000..5fc9d29 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msetraywidget.pas @@ -0,0 +1,499 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msetraywidget; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef mswindows} + {$ifndef mse_no_dbus} + {$define mse_usedbus} + {$endif} +{$endif} +interface +uses + msetypes,mseclasses,classes,mclasses,msesimplewidgets,mseguiglob,msebitmap, + msegui, + mseevent,mseglob,msegraphics,msestrings,msetimer,msemenus,msegraphutils + {$ifdef mse_usedbus},msestatusnotifieritem{$endif}; + +const + trayoptionswidget = [ow_appinactivehint]; + +type + traywidgetoptionty = (two_usedbus); + traywidgetoptionsty = set of traywidgetoptionty; + + ttraywidget = class(teventwidget) + private + ficon: tmaskedbitmap; + ficonchanging: integer; + fimagelist: timagelist; + fimagenum: integer; + fmessageid: longword; + ftimer: tsimpletimer; + fcaption: msestring; + foptions: traywidgetoptionsty; + fondbusactivate: notifyeventty; + fondbussecondaryactivate: notifyeventty; + procedure seticon(const avalue: tmaskedbitmap); + procedure setimagelist(const avalue: timagelist); + procedure setimagenum(const avalue: integer); + procedure setcaption(const avalue: msestring); + procedure setoptions(const avalue: traywidgetoptionsty); + protected + {$ifdef mse_usedbus} + fstatusnotifieritem: tstatusnotifieritem; + procedure dbusdocontextmenu(const sender: tstatusnotifieritem; + const apos: pointty); + procedure dbusdoactivate(const sender: tstatusnotifieritem; + const apos: pointty); + procedure dbusdosecondaryactivate(const sender: tstatusnotifieritem; + const apos: pointty); + {$endif} + {$ifdef mswindows} + procedure showhint(const aid: int32; var info: hintinfoty); override; + {$endif} + procedure dotimer(const sender: tobject); + procedure settrayhint; + procedure sethint(const avalue: msestring); override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure iconchanged(const sender: tobject); + {$ifdef mse_usedbus} + function hasdbus: boolean; + {$endif} + function dock: boolean; //true if OK + procedure undock; + procedure setvisible(const avalue: boolean); override; + procedure loaded; override; + procedure updatewindowinfo(var info: windowinfoty) override; + procedure dopopup(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure showmessage(const amessage: msestring; + const timeoutms: integer = 0); + procedure showmessage(const amessage: msestring; const atitle: msestring; + const timeoutms: integer = 0); + //for dbus org.freedesktop.Notifications + procedure cancelmessage(); + published + property icon: tmaskedbitmap read ficon write seticon; + property imagelist: timagelist read fimagelist write setimagelist; + property imagenum: integer read fimagenum write setimagenum default -1; + property caption: msestring read fcaption write setcaption; + property optionswidget default defaultoptionswidget + trayoptionswidget; + property options: traywidgetoptionsty read foptions + write setoptions default []; + property ondbusactivate: notifyeventty read fondbusactivate write + fondbusactivate; + property ondbussecondaryactivate: notifyeventty + read fondbussecondaryactivate write fondbussecondaryactivate; + end; + +implementation +uses + mseguiintf,sysutils,msewidgets; + +{ ttraywidget } + +constructor ttraywidget.create(aowner: tcomponent); +begin +(* + {$ifdef mse_usedbus} + if not (csdesigning in componentstate) then begin + fstatusnotifieritem:= tstatusnotifieritem.create(); + fstatusnotifieritem.oncontextmenu:= @dbusdocontextmenu; + end; + {$endif} +*) + fimagenum:= -1; + ficon:= tcenteredbitmap.create(bmk_rgb{false}); + ficon.onchange:= {$ifdef FPC}@{$endif}iconchanged; + inherited; + foptionswidget:= foptionswidget + trayoptionswidget; +end; + +destructor ttraywidget.destroy; +begin + visible:= false; + undock(); + freeandnil(ftimer); + ficon.free; + inherited; +{$ifdef mse_usedbus} + fstatusnotifieritem.free(); +{$endif} +end; + +procedure ttraywidget.setoptions(const avalue: traywidgetoptionsty); +begin + if avalue <> foptions then begin + foptions:= avalue; + {$ifdef mse_usedbus} + if (two_usedbus in foptions) and (fstatusnotifieritem = nil) then begin + fstatusnotifieritem:= tstatusnotifieritem.create(); + fstatusnotifieritem.oncontextmenu:= @dbusdocontextmenu; + fstatusnotifieritem.onactivate:= @dbusdoactivate; + fstatusnotifieritem.onsecondaryactivate:= @dbusdosecondaryactivate; + end + else begin + freeandnil(fstatusnotifieritem); + end; + {$endif} + end; +end; + +function ttraywidget.dock: boolean; +var + bo1: boolean; +begin + result:= true; +{$ifdef mse_usedbus} + if hasdbus then begin + //nothing to do + end + else begin +{$endif} + if (parentwidget <> nil) or (window.syscontainer <> sywi_tray) then begin + bo1:= visible; + visible:= false; + parentwidget:= nil; + try + window.syscontainer:= sywi_tray; + except + result:= false; + exit; + end; + visible:= bo1; + end; +{$ifdef mse_usedbus} + end; +{$endif} +end; + +procedure ttraywidget.undock; +begin + if ownswindow then begin + window.syscontainer:= sywi_none; + end; +end; + +{$ifdef mse_usedbus} +function ttraywidget.hasdbus(): boolean; +begin + result:= (fstatusnotifieritem <> nil) and + fstatusnotifieritem.checkdesktop(); +end; +{$endif} + +procedure ttraywidget.setvisible(const avalue: boolean); +begin +{$ifdef mse_usedbus} + if (componentstate * [csdesigning,csloading] = []) and + (hasdbus and (avalue <> fstatusnotifieritem.active) or + not hasdbus and (avalue <> visible)) then begin +{$else} + if (componentstate * [csdesigning,csloading] = []) and + (avalue <> visible) then begin +{$endif} + if avalue then begin + if dock() then begin + setcaption(fcaption); + iconchanged(nil); + settrayhint; + {$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.active:= true; + end + else begin + {$endif} + inherited; + {$ifdef mse_usedbus} + end; + {$endif} + end; + end + else begin + cancelmessage(); + {$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.active:= false; + end + else begin + {$endif} + inherited; + {$ifdef mse_usedbus} + end; + {$endif} + undock(); + end; + end + else begin + inherited; + end; +end; + +procedure ttraywidget.loaded; +begin + if not(csdesigning in componentstate) and visible then begin + visible:= false; + inherited; + if dock() then begin + visible:= true; + end; + end + else begin + inherited; + end; +end; + +procedure ttraywidget.updatewindowinfo(var info: windowinfoty); +begin + inherited; + info.options:= info.options + [wo_embedded,wo_noframe]; +end; + +procedure ttraywidget.seticon(const avalue: tmaskedbitmap); +begin + ficon.assign(avalue); +end; + +procedure ttraywidget.settrayhint(); +{$ifdef mse_usedbus} +var + tt1: tooltipinfoty; +{$endif} +begin +{$ifdef mse_usedbus} + if hasdbus then begin + tt1.title:= stringtoutf8(hint); + fstatusnotifieritem.settooltip(tt1); + end + else begin +{$endif} + if ownswindow then begin + gui_settrayhint(windowpo^,hint); + end; +{$ifdef mse_usedbus} + end; +{$endif} +end; + +procedure ttraywidget.iconchanged(const sender: tobject); +var + icon1,mask1: pixmapty; + bmp1: tmaskedbitmap; +begin + if not (csloading in componentstate) then begin + if ficonchanging = 0 then begin + inc(ficonchanging); + bmp1:= tmaskedbitmap.create(bmk_rgb{false}); + try + if (fimagelist = nil) or (fimagenum < 0) or + (fimagenum >= fimagelist.count) then begin + bmp1.assign(ficon); + end + else begin + bmp1.options:= fimagelist.options; + fimagelist.getimage(fimagenum,bmp1); + end; + invalidate; +// bmp1.colormask:= false; + {$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.seticonpixmap(bmp1); + end + else begin + {$endif} + if ownswindow and not (csdesigning in componentstate) then begin + getwindowicon(bmp1,icon1,mask1,true); + gui_settrayicon(windowpo^,icon1,mask1); + end; + {$ifdef mse_usedbus} + end; + {$endif} + finally + dec(ficonchanging); + bmp1.free; + end; + end; + end; +end; + +procedure ttraywidget.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = fimagelist) and (event = oe_changed) then begin + iconchanged(nil); + end; +end; + +procedure ttraywidget.setimagelist(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + iconchanged(nil); +end; + +procedure ttraywidget.setimagenum(const avalue: integer); +begin + if avalue <> fimagenum then begin + fimagenum:= avalue; + iconchanged(nil); + end; +end; + +procedure ttraywidget.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + if (fimagelist <> nil) and (fimagenum >= 0) then begin + fimagelist.paint(acanvas,fimagenum,innerclientrect,ficon.alignment); + end + else begin + if not ficon.isempty then begin + ficon.paint(acanvas,innerclientrect,ficon.alignment); + end; + end; +end; + +procedure ttraywidget.sethint(const avalue: msestring); +begin + inherited; + if not (csloading in componentstate) then begin + settrayhint; + end; +end; + +procedure ttraywidget.dopopup(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + {$ifdef mswindows} + if ownswindow then begin + gui_settrayhint(windowpo^,''); + try + inherited; + finally + gui_settrayhint(windowpo^,hint); + end; + end + else begin + inherited; + end; + {$else} + inherited; + {$endif} +end; + +procedure ttraywidget.showmessage(const amessage: msestring; + const atitle: msestring; const timeoutms: integer = 0); +begin +{$ifdef mse_usedbus} + if visible or hasdbus and fstatusnotifieritem.active then begin +{$else} + if visible then begin +{$endif} + cancelmessage; + if amessage <> '' then begin + {$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.showmessage(amessage,atitle,fmessageid,timeoutms); + end + else begin + {$endif} + gui_traymessage(windowpo^,amessage,fmessageid,timeoutms); + {$ifdef mse_usedbus} + end; + {$endif} + if timeoutms > 0 then begin + ftimer:= tsimpletimer.create(timeoutms*1000,{$ifdef FPC}@{$endif}dotimer, + true,[to_single]); + end; + end; + end; +end; + +procedure ttraywidget.showmessage(const amessage: msestring; + const timeoutms: integer); +begin + showmessage(amessage,'',timeoutms); +end; + +procedure ttraywidget.cancelmessage; +begin + if fmessageid <> 0 then begin + freeandnil(ftimer); + {$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.cancelmessage(fmessageid); + end + else begin + {$endif} + gui_canceltraymessage(windowpo^,fmessageid); + {$ifdef mse_usedbus} + end; + {$endif} + fmessageid:= 0; + end; +end; + +procedure ttraywidget.dotimer(const sender: tobject); +begin + cancelmessage; +end; + +procedure ttraywidget.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + if ownswindow then begin + window.caption:= fcaption; + end; +{$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.settitle(stringtoutf8ansi(avalue)); + end; +{$endif} +end; + +{$ifdef mse_usedbus} +procedure ttraywidget.dbusdocontextmenu(const sender: tstatusnotifieritem; + const apos: pointty); +begin + if popupmenu <> nil then begin + popupmenu.show(nil,apos); + end; +end; + +procedure ttraywidget.dbusdoactivate(const sender: tstatusnotifieritem; + const apos: pointty); +begin + if canevent(tmethod(fondbusactivate)) then begin + fondbusactivate(self); + end; +end; + +procedure ttraywidget.dbusdosecondaryactivate(const sender: tstatusnotifieritem; + const apos: pointty); +begin + if canevent(tmethod(fondbussecondaryactivate)) then begin + fondbussecondaryactivate(self); + end; +end; +{$endif} + +{$ifdef mswindows} +procedure ttraywidget.showhint(const aid: int32; var info: hintinfoty); +begin + //dummy; +end; +{$endif} + +end. diff --git a/mseide-msegui/lib/common/widgets/msewidgets.pas b/mseide-msegui/lib/common/widgets/msewidgets.pas new file mode 100644 index 0000000..ae345d6 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msewidgets.pas @@ -0,0 +1,6475 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msewidgets; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegui,mseguiglob,msetypes,msestrings,msegraphutils, + msegraphics,msesystypes,mseassistiveclient,mselist, + mseevent,msescrollbar,msemenus,mserichstring,msedrawtext,mseglob,mseact, + mseshapes,mseclasses,msebitmap,msetimer; + +type + + sizeeventty = procedure(const sender: tobject; var asize: sizety) of object; + + tframefont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + captionframeoptionty = (cfo_fixleft,cfo_fixright,cfo_fixtop,cfo_fixbottom, + cfo_autowidth,cfo_autoheight, + //paint area as big as possible + cfo_captionnogray, + cfo_captiondistouter,cfo_captionframecentered, + cfo_captionnoclip,cfo_nofocusrect,cfo_forcefocusrect, + cfo_focusrect, //override template fso_nofocusrect + cfo_captionfocus,cfo_framerectfocus + {,cfo_captionbackground}); + captionframeoptionsty = set of captionframeoptionty; + +const + defaultcaptionframeoptions = []; +type + doublewidgetty = record + a,b: twidget; + end; + pdoublewidgetty = ^doublewidgetty; + doublewidgetarty = array of doublewidgetty; + ttaborderoverride = class; + tabordereventty = procedure(const sender: ttaborderoverride; + const current: twidget; const down: boolean; + var next: twidget) of object; + ttaborderoverride = class(tlinkedpersistent) + private + fontaborder: tabordereventty; + procedure readitems(reader: treader); + procedure writeitems(writer: twriter); + protected + fowner: twidget; + fitems: doublewidgetarty; + fwidgetnames: stringarty; + procedure defineproperties(filer: tfiler) override; + procedure objevent(const sender: iobjectlink; + const event: objecteventty) override; + procedure endread(const reader: treader); + public + constructor create(const aowner: twidget); reintroduce; + destructor destroy(); override; + procedure clear(); + function nexttaborder(sender: twidget; const down: boolean): twidget; + procedure add(const aa,ab: twidget); + property owner: twidget read fowner; + published + property ontaborder: tabordereventty read fontaborder write fontaborder; + end; + + tcustomcaptionframe = class(tcustomframe) + private + fcaptionpos: captionposty; + fupdating: integer; + fcaption: msestring; +// function getcaption: msestring; + procedure setcaption(const avalue: msestring); + procedure fontchanged(const sender: tobject); + function isfontstored: Boolean; + procedure setfont(const Value: tframefont); + function getfont: tframefont; + procedure setcaptionpos(const avalue: captionposty); + procedure setcaptiondist(const Value: integer); + function iscaptiondiststored: boolean; + procedure setcaptionoffset(const Value: integer); + function iscaptionoffsetstored: boolean; + procedure readouterframe(reader: treader); + procedure writeouterframe(writer: twriter); + procedure readcaptionnoclip(reader: treader); + procedure readcaptiondistouter(reader: treader); + procedure setoptions(const avalue: captionframeoptionsty); + procedure setcaptiontextflags(const avalue: textflagsty); + protected + ffont: tframefont; + finfo: drawtextinfoty; + fcaptiondist: integer; + fcaptionoffset: integer; + foptions: captionframeoptionsty; + procedure settemplateinfo(const ainfo: frameinfoty); override; + procedure parentfontchanged; override; + procedure fontcanvaschanged; override; + procedure visiblechanged; override; + + function updatetextflags(const aflags: textflagsty): textflagsty; + procedure updaterects; override; + procedure updatehotkeys() override; + procedure dominsize(var asize: sizety); + procedure checkminshrinksize(var asize: sizety) override; + procedure defineproperties(filer: tfiler); override; + procedure setdisabled(const value: boolean); override; + procedure dopaintfocusrect(const canvas: tcanvas; + const rect: rectty); override; + function checkfocusshortcut(var info: keyeventinfoty): boolean; override; + function needsfocuspaint: boolean; override; + function haspaintrectfocus(): boolean; override; //checks caption + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) override; + + //iassistiveclient + function getassistivecaption(): msestring; override; + + public + constructor create(const aintf: icaptionframe); + destructor destroy; override; + procedure scale(const ascale: real); override; + procedure createfont; + function pointincaption(const point: pointty): boolean; override; + //origin = widgetrect + procedure checkwidgetsize(var asize: sizety); override; + //extends to minimal size + + property options: captionframeoptionsty read foptions + write setoptions default defaultcaptionframeoptions; + property caption: msestring read fcaption write setcaption; + property captiontextflags: textflagsty read finfo.flags write + setcaptiontextflags default []; + property captionpos: captionposty read fcaptionpos + write setcaptionpos default cp_topleft; + property captiondist: integer read fcaptiondist write setcaptiondist + stored iscaptiondiststored default 1; + property captionoffset: integer read fcaptionoffset write setcaptionoffset + stored iscaptionoffsetstored default 0 ; + property font: tframefont read getfont + write setfont stored isfontstored; + end; + + tcaptionframe = class(tcustomcaptionframe) + published + property options; + property levelo; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property colorclient; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + timpressedcaptionframe = class(tcaptionframe) + public + constructor create(const aintf: icaptionframe); + published + property levelo default -2; + end; + +const + defaultscrollboxscrollbaroptions = [sbo_thumbtrack,sbo_moveauto,sbo_showauto]; + scrollbarframestates: framestatesty = [fs_sbleft,fs_sbtop,fs_sbright,fs_sbbottom]; + +type + tscrollboxscrollbar = class(tnopagesizescrollbar) + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property options default defaultscrollboxscrollbaroptions; + end; + +const + defaultthumbtrackscrollbaroptions = [sbo_thumbtrack,sbo_showauto]; + +type + tthumbtrackscrollbar = class(tnomoveautoscrollbar) + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property options default defaultthumbtrackscrollbaroptions; + end; + + tthumbtracknopagesizescrollbar = class(tnomoveautonopagesizescrollbar) + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property options default defaultthumbtrackscrollbaroptions; + end; + + framescrollbarclassty = class of tcustomscrollbar; + + optionscrollty = (oscr_drag,oscr_zoomwidth,oscr_zoomheight, + oscr_key,oscr_mousewheel); + optionsscrollty = set of optionscrollty; + +const + defaultoptionsscroll = [oscr_mousewheel]; + defaultdragbuttons = [ss_middle]; + +type + tcustomscrollframe = class(tcustomcaptionframe) + private + fdragbuttons: shiftstatesty; + procedure setsbhorz(const Value: tcustomscrollbar); + procedure setsbvert(const Value: tcustomscrollbar); + procedure setdragbuttons(const avalue: shiftstatesty); + protected + fhorz,fvert: tcustomscrollbar; + foptionsscroll: optionsscrollty; + procedure settemplateinfo(const ainfo: frameinfoty); override; + procedure updatestate; override; + procedure updatevisiblescrollbars; virtual; + procedure updaterects; override; + procedure getpaintframe(var frame: framety); override; + procedure addscrollbarwidth(var asize: sizety) override; + procedure subscrollbarwidth(var asize: sizety) override; + function getscrollbarclass(vert: boolean): framescrollbarclassty; virtual; + procedure activechanged; override; + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) override; + public + constructor create(const aintf: iscrollframe; const scrollintf: iscrollbar); + destructor destroy; override; + procedure checktemplate(const sender: tobject); override; + //true if match + procedure mouseevent(var info: mouseeventinfoty); virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean); virtual; + property optionsscroll: optionsscrollty read foptionsscroll + write foptionsscroll default defaultoptionsscroll; + property dragbuttons: shiftstatesty read fdragbuttons write setdragbuttons + default defaultdragbuttons; + property state: framestatesty read fstate; + property sbhorz: tcustomscrollbar read fhorz write setsbhorz; + property sbvert: tcustomscrollbar read fvert write setsbvert; + end; + + tscrollframe = class(tcustomscrollframe) + private + procedure setsbhorz(const avalue: tscrollbar); + function getsbhorz: tscrollbar; + procedure setsbvert(const avalue: tscrollbar); + function getsbvert: tscrollbar; + protected + function getscrollbarclass(vert: boolean): framescrollbarclassty; override; + published + property options; + property levelo; + property leveli; + property framewidth; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colorhlwidth; + property hiddenedges; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property sbhorz: tscrollbar read getsbhorz write setsbhorz; + property sbvert: tscrollbar read getsbvert write setsbvert; + property colorclient; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + tcustomthumbtrackscrollframe = class(tcustomscrollframe) + protected + function getscrollbarclass(vert: boolean): framescrollbarclassty; override; + end; + + iscrollbox = interface(iscrollbar) + function getscrollsize: sizety; + end; + +type + tcustomscrollboxframe = class(tcustomscrollframe,iscrollbox) + private + fscrolling: integer; + fclientsize: sizety; + fclientsizemin: sizety; + fdragging: boolean; + fpickpos: pointty; + fpickref: pointty; + fzoom: complexty; + fzoomwidthstep: real; + fzoomheightstep: real; + fzoomwheelsensitivity: real; + procedure clientrecttoscrollbar(const rect: rectty); + procedure setclientsize(const avalue: sizety); + procedure setclientheight(const avalue: integer); + procedure setclientwidth(const avalue: integer); + procedure setclientsizemin(const avalue: sizety); + procedure setclientheightmin(const avalue: integer); + procedure setclientwidthmin(const avalue: integer); + procedure calcclientrect(var aclientrect: rectty); + function getwidget: twidget; + procedure setsbhorz(const avalue: tscrollboxscrollbar); + function getsbhorz: tscrollboxscrollbar; + procedure setsbvert(const avalue: tscrollboxscrollbar); + function getsbvert: tscrollboxscrollbar; + procedure setzoom1(const avalue: complexty); + procedure setzoom(const avalue: complexty); + procedure setzoomwidth(const avalue: real); + procedure setzoomheight(const avalue: real); + function getscrollpos_x: integer; + procedure setscrollpos_x(const avalue: integer); + function getscrollpos_y: integer; + procedure setscrollpos_y(const avalue: integer); + procedure readzoomwidthstep(reader: treader); + procedure writezoomwidthstep(writer: twriter); + procedure readzoomheightstep(reader: treader); + procedure writezoomheightstep(writer: twriter); + procedure readzoomwheelsensitivity(reader: treader); + procedure writezoomwheelsensitivity(writer: twriter); + protected + fowner: twidget; + procedure scrollpostoclientpos(var aclientrect: rectty); virtual; + procedure checkminscrollsize(var asize: sizety); override; + procedure checkminclientsize(var asize: sizety); override; + function isdragstart(const sender: twidget; + const info: mouseeventinfoty): boolean; + procedure initinnerframe; virtual; + function getscrollbarclass(vert: boolean): framescrollbarclassty; override; + procedure updatevisiblescrollbars; override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); virtual; + procedure dokeydown(var info: keyeventinfoty); override; + function getclientpos: pointty; + procedure setclientpos(apos: pointty); + procedure setscrollpos(apos: pointty); + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure defineproperties(filer: tfiler); override; + //iscrollbar + function translatecolor(const acolor: colorty): colorty; + procedure invalidaterect(const rect: rectty; const org: originty; + const noclip: boolean = false); + //iscrollbox + function getscrollsize: sizety; + public + constructor create(const aintf: iscrollframe; const owner: twidget); + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean); override; + procedure updateclientrect; override; + procedure showrect(const arect: rectty; const bottomright: boolean); + //origin paintpos + property scrollpos: pointty read getclientpos write setscrollpos; + property scrollpos_x: integer read getscrollpos_x write setscrollpos_x; + property scrollpos_y: integer read getscrollpos_y write setscrollpos_y; + //origin = paintpos + property zoom: complexty read fzoom write setzoom; //default 1,1 + property zoomwidth: real read fzoom.re write setzoomwidth; //default 1 + property zoomheight: real read fzoom.im write setzoomheight; //default 1 + property zoomwidthstep: real read fzoomwidthstep + write fzoomwidthstep stored false; + //default 1 + property zoomheightstep: real read fzoomheightstep + write fzoomheightstep stored false; + //default 1 + property zoomwheelsensitivity: real read fzoomwheelsensitivity + write fzoomwheelsensitivity stored false; + //default 0 + property clientsize: sizety read fclientsize write setclientsize; + property clientwidth: integer read fclientsize.cx + write setclientwidth default 0; + property clientheight: integer read fclientsize.cy + write setclientheight default 0; + property clientsizemin: sizety read fclientsizemin write setclientsizemin; + property clientwidthmin: integer read fclientsizemin.cx + write setclientwidthmin default 0; + property clientheightmin: integer read fclientsizemin.cy + write setclientheightmin default 0; + property framei_left default 2; + property framei_top default 2; + property framei_right default 2; + property framei_bottom default 2; + property sbhorz: tscrollboxscrollbar read getsbhorz write setsbhorz; + property sbvert: tscrollboxscrollbar read getsbvert write setsbvert; + end; + + tscrollboxframe = class(tcustomscrollboxframe) + published + property options; + property optionsscroll; + property dragbuttons; + property clientwidth; + property clientheight; + property clientwidthmin; + property clientheightmin; + property zoomwidthstep; + property zoomheightstep; + property zoomwheelsensitivity; + property levelo; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + property sbhorz; + property sbvert; + end; + + stepkindty = (sk_right,sk_up,sk_left,sk_down,sk_first,sk_last); + stepkindsty = set of stepkindty; +const + allstepkinds = [sk_right,sk_up,sk_left,sk_down,sk_first,sk_last]; +type + istepbar = interface(inullinterface) + function translatecolor(const aclor: colorty): colorty; + procedure invalidaterect(const rect: rectty; const org: originty; + const noclip: boolean = false); + function dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; + //true on action + end; + stepbuttonposty = (sbp_right,sbp_top,sbp_left,sbp_bottom); + + framestepinfoty = record + down,up,pagedown,pageup,pagelast: integer; + end; + +const + defaultstepbuttonsize = 13; + +type + stepframestatety = (sfs_spinedit,sfs_canstep); + stepframestatesty = set of stepframestatety; + + tcustomstepframe = class(tcustomcaptionframe,iframe) + private + fstepintf: istepbar; + fbuttonsize: integer; + fbuttons: shapeinfoarty; + fcolorbutton: colorty; + fbuttonpos: stepbuttonposty; + fbuttonslast: boolean; + fdisabledbuttons: stepkindsty; + fneededbuttons: stepkindsty; + fbuttonsinline: boolean; + fmousewheel: boolean; + frepeater: tsimpletimer; + frepeatedbutton: integer; + fbuttonface: tface; + fbuttonframe: tframe; + factbuttonindex: integer; + fcolorglyph: colorty; + procedure setbuttonsize(const Value: integer); + procedure setbuttonpos(const Value: stepbuttonposty); + procedure setbuttonsinline(const value: boolean); + procedure setbuttonslast(const avalue: boolean); + procedure setcolorbutton(const avalue: colorty); + procedure setdisabledbuttons(const avalue: stepkindsty); + procedure setbuttonsinvisible(const avalue: stepkindsty); + procedure setbuttonsvisible(const avalue: stepkindsty); + procedure setneededbuttons(const avalue: stepkindsty); + function getbuttonface: tface; + procedure setbuttonface(const avalue: tface); + function getbuttonframe: tframe; + procedure setbuttonframe(const avalue: tframe); + procedure setcolorglyph(const avalue: colorty); + protected + fforceinvisiblebuttons: stepkindsty; + fforcevisiblebuttons: stepkindsty; + fstepstate: stepframestatesty; + fdim: rectty; + procedure dorepeat(const sender: tobject); + procedure killrepeater; + procedure layoutchanged; + procedure updaterects; override; + procedure getpaintframe(var frame: framety); override; + procedure updatelayout; + procedure execute(const tag: integer; const info: mouseeventinfoty); + property neededbuttons: stepkindsty read fneededbuttons + write setneededbuttons; + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function getwidgetrect: rectty; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getwidget: twidget; + function getframestateflags: framestateflagsty; virtual; + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) override; + public + constructor create(const aintf: icaptionframe; const stepintf: istepbar); + destructor destroy; override; + procedure createbuttonface; + procedure createbuttonframe; + + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure mouseevent(var info: mouseeventinfoty); virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty); virtual; + procedure checktemplate(const sender: tobject); override; + procedure updatebuttonstate(const first,delta,count: integer); + function canstep: boolean; + function executestepevent(const event: stepkindty; + const stepinfo: framestepinfoty; const aindex: integer): integer; + property buttonsize: integer read fbuttonsize write setbuttonsize + default defaultstepbuttonsize; + property colorbutton: colorty read fcolorbutton + write setcolorbutton default cl_default; + //cl_default maps to widget color + property colorglyph: colorty read fcolorglyph + write setcolorglyph default cl_default; + //cl_default maps to widget color + property buttonface: tface read getbuttonface write setbuttonface; + property buttonframe: tframe read getbuttonframe write setbuttonframe; + + property disabledbuttons: stepkindsty read fdisabledbuttons + write setdisabledbuttons default []; + property buttonsinvisible: stepkindsty read fforceinvisiblebuttons + write setbuttonsinvisible default [sk_first,sk_last]; + property buttonsvisible: stepkindsty read fforcevisiblebuttons + write setbuttonsvisible default []; + property buttonpos: stepbuttonposty read fbuttonpos + write setbuttonpos default sbp_right; + property buttonslast: boolean read fbuttonslast + write setbuttonslast default false; + property buttonsinline: boolean read fbuttonsinline + write setbuttonsinline default false; + property mousewheel: boolean read fmousewheel write fmousewheel default true; + end; + + tstepframe = class(tcustomstepframe) + published + property options; + property levelo; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient; + property colorbutton; + property colorglyph; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + property disabledbuttons; + property buttonface; + property buttonframe; + property buttonsvisible; + property buttonsinvisible; + property buttonsize; + property buttonpos; + property buttonslast; + property buttonsinline; + property mousewheel; + end; + + queryeventty = procedure(const sender: tobject; var answer: boolean) of object; + popupeventty = procedure(const sender: tobject; var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty) of object; + + tactionwidget = class(twidget) + private + fpopupmenu: tpopupmenu; + fonpopup: popupeventty; + fonshowhint: showhinteventty; + fonenter: notifyeventty; + fonexit: notifyeventty; + fonfocus: notifyeventty; + fondefocus: notifyeventty; + fonactivate: notifyeventty; + fondeactivate: notifyeventty; + + fonloaded: notifyeventty; + fonmouseevent: mouseeventty; + fonmousewheelevent: mousewheeleventty; + fonchildmouseevent: mouseeventty; + fonclientmouseevent: mouseeventty; + fonkeyup: keyeventty; + fonkeydown: keyeventty; + fonshortcut: shortcuteventty; + fonpaint: painteventty; + fonbeforepaint: painteventty; + fonafterpaint: painteventty; + fonmove: notifyeventty; + fonresize: notifyeventty; + fonhide: notifyeventty; + fonshow: notifyeventty; + fonclosequery: queryeventty; + fonevent: eventeventty; + fonasyncevent: asynceventeventty; + fonfocusedwidgetchanged: widgetchangeeventty; + fonpaintbackground: painteventty; + + foncomponentevent: componenteventeventty; + procedure setpopupmenu(const Value: tpopupmenu); + function getframe: tcaptionframe; + procedure setframe(const value: tcaptionframe); + function getface: tface; + procedure setface(const Value: tface); + protected + procedure mouseevent(var info: mouseeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + + procedure dobeforepaint(const canvas: tcanvas); override; + procedure doonpaintbackground(const canvas: tcanvas); override; + procedure doonpaint(const canvas: tcanvas); override; + procedure doafterpaint(const canvas: tcanvas); override; + + procedure showhint(const aid: int32; var info: hintinfoty); override; + procedure getpopuppos(var apos: pointty); virtual; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); virtual; + procedure dopopup(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); virtual; + procedure doafterpopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); virtual; + + procedure poschanged; override; + procedure sizechanged; override; + + procedure doloaded; override; + procedure doenter; override; + procedure doexit; override; + procedure dofocus; override; + procedure dodefocus; override; + procedure dofocuschanged(const oldwidget: twidget; + const newwidget: twidget); override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure dohide; override; + procedure doshow; override; + + procedure doonkeydown(var info: keyeventinfoty); + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); override; + procedure receiveevent(const event: tobjectevent); override; + procedure componentevent(const event: tcomponentevent) override; + procedure doasyncevent(var atag: integer); override; + + procedure internalcreateframe; override; + procedure enabledchanged; override; + + property frame: tcaptionframe read getframe write setframe; + property face: tface read getface write setface; + property popupmenu: tpopupmenu read fpopupmenu write setpopupmenu; + property onpopup: popupeventty read fonpopup write fonpopup; + property onshowhint: showhinteventty read fonshowhint write fonshowhint; + property onenter: notifyeventty read fonenter write fonenter; + property onexit: notifyeventty read fonexit write fonexit; + property onfocus: notifyeventty read fonfocus write fonfocus; + property ondefocus: notifyeventty read fondefocus write fondefocus; + property onactivate: notifyeventty read fonactivate write fonactivate; + property ondeactivate: notifyeventty read fondeactivate write fondeactivate; + + property onfocusedwidgetchanged: widgetchangeeventty + read fonfocusedwidgetchanged write fonfocusedwidgetchanged; + + property onmouseevent: mouseeventty read fonmouseevent write fonmouseevent; + property onchildmouseevent: mouseeventty read fonchildmouseevent + write fonchildmouseevent; + property onclientmouseevent: mouseeventty read fonclientmouseevent + write fonclientmouseevent; + property onmousewheelevent: mousewheeleventty read fonmousewheelevent + write fonmousewheelevent; + + property onkeydown: keyeventty read fonkeydown write fonkeydown; + property onkeyup: keyeventty read fonkeyup write fonkeyup; + property onshortcut: shortcuteventty read fonshortcut write fonshortcut; + + property onloaded: notifyeventty read fonloaded write fonloaded; + + property onbeforepaint: painteventty read fonbeforepaint + write fonbeforepaint; + property onpaintbackground: painteventty read fonpaintbackground + write fonpaintbackground; + property onpaint: painteventty read fonpaint write fonpaint; + property onafterpaint: painteventty read fonafterpaint write fonafterpaint; + + property onshow: notifyeventty read fonshow write fonshow; + property onhide: notifyeventty read fonhide write fonhide; + property onresize: notifyeventty read fonresize write fonresize; + property onmove: notifyeventty read fonmove write fonmove; + property onclosequery: queryeventty read fonclosequery write fonclosequery; + + property onevent: eventeventty read fonevent write fonevent; + property oncomponentevent: componenteventeventty read foncomponentevent + write foncomponentevent; + property onasyncevent: asynceventeventty read fonasyncevent write fonasyncevent; + public + function canclose(const newfocus: twidget = nil): boolean; override; + end; + + tactionpublishedwidgetnwr = class(tactionwidget) + published + property optionswidget1; //first! + property optionswidget; + property optionsskin; + property color; + property cursor; + property frame; + property face; + property taborder; + property hint; + property popupmenu; + property onpopup; + property onshowhint; + property onenter; + property onexit; + property onfocus; + property ondefocus; + property onactivate; + property ondeactivate; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + + tactionpublishedwidget = class(tactionpublishedwidgetnwr) + published + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property anchors; + end; + + tpublishedwidgetnwr = class(tactionpublishedwidgetnwr) + published + property enabled; + property visible; + end; + + tpublishedwidget = class(tpublishedwidgetnwr) + published + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property anchors; + end; + + tsimplewidget = class(tpublishedwidget) + public + constructor create(aowner: tcomponent); override; + published + property visible default false; + end; + + tcustomeventwidgetnwr = class(tpublishedwidgetnwr) + (* + private + fonloaded: notifyeventty; + fonmouseevent: mouseeventty; + fonmousewheelevent: mousewheeleventty; + fonchildmouseevent: mouseeventty; + fonclientmouseevent: mouseeventty; + fonkeyup: keyeventty; + fonkeydown: keyeventty; + fonshortcut: keyeventty; + fonpaint: painteventty; + fonbeforepaint: painteventty; + fonafterpaint: painteventty; + fonmove: notifyeventty; + fonresize: notifyeventty; + fonhide: notifyeventty; + fonshow: notifyeventty; + fonclosequery: queryeventty; + fonevent: eventeventty; + fonasyncevent: asynceventeventty; + fonfocusedwidgetchanged: focuschangeeventty; + fonpaintbackground: painteventty; + protected + procedure poschanged; override; + procedure sizechanged; override; + procedure dobeforepaint(const canvas: tcanvas); override; + procedure dopaintbackground(const canvas: tcanvas); override; + procedure doonpaint(const canvas: tcanvas); override; + procedure doafterpaint(const canvas: tcanvas); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); override; + procedure dofocuschanged(const oldwidget,newwidget: twidget); override; + procedure doloaded; override; + procedure dohide; override; + procedure doshow; override; + procedure receiveevent(const event: tobjectevent); override; + procedure doasyncevent(var atag: integer); override; + public + function canclose(const newfocus: twidget): boolean; override; + property onfocusedwidgetchanged: focuschangeeventty + read fonfocusedwidgetchanged write fonfocusedwidgetchanged; + + property onmouseevent: mouseeventty read fonmouseevent write fonmouseevent; + property onchildmouseevent: mouseeventty read fonchildmouseevent + write fonchildmouseevent; + property onclientmouseevent: mouseeventty read fonclientmouseevent + write fonclientmouseevent; + property onmousewheelevent: mousewheeleventty read fonmousewheelevent + write fonmousewheelevent; + + property onkeydown: keyeventty read fonkeydown write fonkeydown; + property onkeyup: keyeventty read fonkeyup write fonkeyup; + property onshortcut: keyeventty read fonshortcut write fonshortcut; + + property onloaded: notifyeventty read fonloaded write fonloaded; + + property onbeforepaint: painteventty read fonbeforepaint write fonbeforepaint; + property onpaintbackground: painteventty read fonpaintbackground write fonpaintbackground; + property onpaint: painteventty read fonpaint write fonpaint; + property onafterpaint: painteventty read fonafterpaint write fonafterpaint; + + property onshow: notifyeventty read fonshow write fonshow; + property onhide: notifyeventty read fonhide write fonhide; +// property onactivate: notifyeventty read fonactivate write fonactivate; +// property ondeactivate: notifyeventty read fondeactivate write fondeactivate; + property onresize: notifyeventty read fonresize write fonresize; + property onmove: notifyeventty read fonmove write fonmove; + property onclosequery: queryeventty read fonclosequery write fonclosequery; + + property onevent: eventeventty read fonevent write fonevent; + property onasyncevent: asynceventeventty read fonasyncevent write fonasyncevent; +*) + end; + + tcustomeventwidget = class(tcustomeventwidgetnwr) + published + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property anchors; + end; + + const + defaultoptionstoplevelwidget = defaultoptionswidget + [ow_subfocus]; + +type + + ttoplevelwidget = class(tcustomeventwidget) + public + constructor create(aowner: tcomponent); override; + property visible default false; + published + property optionswidget default defaultoptionstoplevelwidget; + property optionsskin default defaultcontainerskinoptions; + end; + + tcaptionwidget = class(ttoplevelwidget) + private + fcaption: msestring; + protected + function getcaption: msestring; virtual; + procedure setcaption(const Value: msestring); virtual; + procedure windowcreated; override; + //iassistiveclient + function getassistivecaption(): msestring; override; + public + property caption: msestring read getcaption write setcaption; + end; + + tscrollbarwidget = class(tcustomeventwidget,iscrollbar) + private + function getframe: tscrollframe; + procedure setframe(const Value: tscrollframe); + protected + procedure internalcreateframe; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); virtual; + public + constructor create(aowner: tcomponent); override; + published + property frame: tscrollframe read getframe write setframe; + end; + + iautoscrollframe = interface(inullinterface) + function getscrollrect: rectty; + procedure setscrollrect(const rect: rectty); + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); + end; + + tcustomautoscrollframe = class(tcustomscrollboxframe) + private + function getscrollpos: pointty; + procedure setscrollpos(const avalue: pointty); + function getscrollpos_x: integer; + procedure setscrollpos_x(const avalue: integer); + function getscrollpos_y: integer; + procedure setscrollpos_y(const avalue: integer); + protected + fintf1: iautoscrollframe; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + procedure updaterects; override; + public + constructor create(const aintf: iscrollframe; const owner: twidget; + const autoscrollintf: iautoscrollframe); + procedure updateclientrect; override; + property scrollpos: pointty read getscrollpos write setscrollpos; + property scrollpos_x: integer read getscrollpos_x write setscrollpos_x; + property scrollpos_y: integer read getscrollpos_y write setscrollpos_y; + //origin = paintpos + end; + + fontheightdeltaeventty = procedure (const sender: tobject; + var delta: integer) of object; + + tscrollface = class(tface) + procedure internalpaint(const canvas: tcanvas; const rect: rectty); override; + public + end; + + tscrollingwidgetnwr = class; + calcminscrollsizeeventty = procedure(const sender: tscrollingwidgetnwr; + var asize: sizety) of object; + + tscrollingwidgetnwr = class(tcustomeventwidgetnwr) + private + fonscroll: pointeventty; + fonfontheightdelta: fontheightdeltaeventty; + fonlayout: notifyeventty; + foncalcminscrollsize: calcminscrollsizeeventty; + fminclientsize: sizety; + fonscrolled: pointeventty; + function getframe: tscrollboxframe; + procedure setframe(const Value: tscrollboxframe); +// procedure setclientpos(const avalue: pointty); + procedure readonchildscaled(reader: treader); + protected + fminminclientsize: sizety; //exteded in design mode + procedure widgetregionchanged(const sender: twidget); override; + procedure sizechanged; override; + procedure minscrollsizechanged; + procedure dofontheightdelta(var delta: integer); override; + procedure internalcreateframe; override; + procedure doscroll(const dist: pointty); override; + procedure doscrolled(const dist: pointty); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure internalcreateface; override; + function calcminscrollsize: sizety; override; + procedure setclientsize(const asize: sizety); override; + procedure loaded; override; + //origin paintpos + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + procedure clampinview(const arect: rectty; + const bottomright: boolean = false); override; + function maxclientsize: sizety; override; + procedure writestate(writer: twriter); override; + procedure dolayout(const sender: twidget); override; + property onscroll: pointeventty read fonscroll write fonscroll; + property onscrolled: pointeventty read fonscrolled write fonscrolled; + property onfontheightdelta: fontheightdeltaeventty read fonfontheightdelta + write fonfontheightdelta; + property onlayout: notifyeventty read fonlayout write fonlayout; + property oncalcminscrollsize: calcminscrollsizeeventty + read foncalcminscrollsize write foncalcminscrollsize; +// property scrollpos: pointty read getclientpos write setclientpos; + published + property frame: tscrollboxframe read getframe write setframe; + property optionswidget default defaultoptionswidgetmousewheel; + property optionsskin default defaultcontainerskinoptions; + end; + + tscrollingwidget = class(tscrollingwidgetnwr) + published + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property anchors; + end; + + tpopupwidget = class(ttoplevelwidget) + private + ftransientfor: twindow; + protected + function getassistiveflags(): assistiveflagsty override; + procedure updatewindowinfo(var info: windowinfoty); override; + function internalshow(const modallevel: modallevelty; + const transientfor: pwindow; + const windowevent,transientforshow: boolean): modalresultty; override; + public + constructor create(aowner: tcomponent; + transientfor: twindow); reintroduce; overload; + property transientfor: twindow read ftransientfor; + end; + + const + defaultoptionshintwidget = defaultoptionstoplevelwidget + [ow_top]; + +type + tcustomhintwidget = class(tpopupwidget) + public + constructor create(const aowner: tcomponent; const atransientfor: twindow; + var info: hintinfoty; const sender: tobject); virtual; reintroduce; + published + property optionswidget default defaultoptionshintwidget; + end; + hintwidgetclassty = class of tcustomhintwidget; + + thintwidget = class(tcustomhintwidget) + private + fcaption: captionty; + protected + procedure dopaintforeground(const canvas: tcanvas); override; + public + constructor create(const aowner: tcomponent; const atransientfor: twindow; + var info: hintinfoty; const sender: tobject); override; + end; + + tmessagewidget = class(tcaptionwidget) + private + fpopuptransient: boolean; + fhasaction: boolean; + protected + procedure updatewindowinfo(var info: windowinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + function getcaption: msestring; override; + procedure setcaption(const Value: msestring); override; + procedure internalcreateframe; override; + public + constructor create(const aowner: tcomponent; const apopuptransient: boolean; + const ahasaction: boolean); + reintroduce; + function canclose(const newfocus: twidget): boolean; override; + end; + +type + tactionsimplebutton = class(tactionpublishedwidget) + private + procedure setcolorglyph(const value: colorty); + protected + foptions: buttonoptionsty; + finfo: shapeinfoty; + class function classskininfo: skininfoty; override; + procedure setoptions(const avalue: buttonoptionsty); virtual; + procedure internalexecute(); + procedure doshapeexecute(const atag: integer; const info: mouseeventinfoty); + procedure doexecute; virtual; + procedure doasyncevent(var atag: integer); override; + procedure statechanged; override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure clientrectchanged; override; + function getframestateflags: framestateflagsty; override; + function navigstartrect: rectty; override; + function getassistiveflags(): assistiveflagsty override; + function getdisabled(): boolean virtual; + public + constructor create(aowner: tcomponent); override; + procedure execute; + procedure pressbutton; + function releasebutton(const aexecute: boolean): boolean; + //true if clicked + property options: buttonoptionsty read foptions write setoptions + default defaultbuttonoptions; + property colorglyph: colorty read finfo.ca.colorglyph write setcolorglyph + default cl_black; + property focusrectdist: integer read finfo.focusrectdist + write finfo.focusrectdist default defaultshapefocusrectdist; + published + property optionswidget default defaultoptionswidget - [ow_mousefocus]; + end; + + tsimplebutton = class(tactionsimplebutton) +// published +// property enabled; +// property visible; + end; + +type + messagepositionty = (mepo_default,mepo_screencentered,mepo_windowcentered); + +function readcaptiontoimagepos(const reader: treader): imageposty; + +procedure synccaptiondistx(const awidgets: array of twidget); + //adjusts captiondist for equal distouter + //don't set cfo_captiondistouter! +procedure synccaptiondisty(const awidgets: array of twidget); + //adjusts captiondist for equal distouter + //don't set cfo_captiondistouter! + +function getmaxdropdownheight(const parent: twidget): integer; +procedure getdropdownpos(const parent: twidget; const right: boolean; + var rect: rectty); + + +//following routines are thread safe and run in main thread context +//exttext will be appended for copy to clipboard +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const defaultbutton: modalresultty = mr_cancel; + const noshortcut: modalresultsty = []; + const minwidth: integer = 0; + const exttext: msestring = ''; + const position: messagepositionty = mepo_default): modalresultty; overload; +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const defaultbutton: modalresultty; + const noshortcut: modalresultsty; + const minwidth: integer; + const actions: array of notifyeventty; + const exttext: msestring = ''; + const position: messagepositionty = mepo_default): modalresultty; overload; +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const adest: rectty; const awidget: twidget = nil; + //origin = awidget.clientpos, screen if awidget = nil + const placement: captionposty = cp_bottomleft; + const defaultbutton: modalresultty = mr_cancel; + const noshortcut: modalresultsty = []; + const minwidth: integer = 0; + const exttext: msestring = ''): modalresultty; overload; +function showmessage(const atext: msestring; const caption: msestring = ''; + const minwidth: integer = 0; + const exttext: msestring = ''): modalresultty; overload; +procedure showmessage1(const atext: msestring; const caption: msestring); + //for ps +procedure showerror(const atext: msestring; caption: msestring = 'ERROR'; + const minwidth: integer = 0; + const exttext: msestring = ''; + const async: boolean = false); + //no wait if not in main thread or asnyc = true +function askok(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_ok; + const minwidth: integer = 0): boolean; + //true if ok pressed +function askyesno(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): boolean; + //true if yes pressed +function askconfirmation(const atext: msestring; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): boolean; + //true if yes pressed +function askconfirmationcancel(const atext: msestring; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): modalresultty; +function askyesnocancel(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): modalresultty; +function confirmsavechangedfile(const filename: filenamety; + out modalresult: modalresultty; multiple: boolean = false): boolean; +function showsyserrormessage(const error: syserrorty; + const text: msestring = ''): boolean; + //returns true for sye_ok +function showsyserrormessage(const error: syserrorty; + const sender: tobject; const text: msestring = ''): boolean; + //returns true for sye_ok + +//end threadsave routines + +procedure copytoclipboard(const value: msestring; + const buffer: clipboardbufferty = cbb_clipboard); +function canpastefromclipboard( + const buffer: clipboardbufferty = cbb_clipboard): boolean; +function pastefromclipboard(out value: msestring; + const buffer: clipboardbufferty = cbb_clipboard): boolean; + //false if empty +function placepopuprect(const awindow: twindow; const adest: rectty; //screenorig + const placement: captionposty; const asize: sizety): rectty; + //placement currently only cp_bottomleft and cp_center + //todo +function placepopuprect(const awidget: twidget; + const adest: rectty; //widgetorig + const placement: captionposty; const asize: sizety): rectty; +function placeclientpopuprect(const awidget: twidget; + const adest: rectty; //clientorig + const placement: captionposty; const asize: sizety): rectty; +procedure getwindowicon(const abitmap: tmaskedbitmap; out aicon,amask: pixmapty; + const anodefault: boolean = false); + +procedure buttonoptionstoshapestate(avalue: buttonoptionsty; + var astate: shapestatesty); + +implementation +uses + msebits,mseguiintf,msestockobjects,msekeyboard,sysutils,msemenuwidgets, + mseactions,msepointer,msestreaming,msesys,msearrayutils,mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + captionmargin = 1; //distance focusrect to caption in tcaptionframe + +type + twidget1 = class(twidget); + twindow1 = class(twindow); + tcustomscrollbar1 = class(tcustomscrollbar); + tbitmap1 = class(tbitmap); + tcustomframe1 = class(tcustomframe); + + tmessagebutton = class(tsimplebutton) + private + fcaption: msestring; + procedure setcaption(const avalue: msestring); + protected + modalresult: modalresultty; + procedure doexecute; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + function getassistivecaption(): msestring override; + public + onexecute: notifyeventty; + property caption: msestring read fcaption write setcaption; + end; + + showmessageinfoty = record + atext,caption: msestring; + buttons: array of modalresultty; + defaultbutton: modalresultty; + noshortcut: modalresultsty; + placementrect: prectty; placement: captionposty; + minwidth: integer; actions: array of notifyeventty; + exttext: msestring; + async: boolean; + result: modalresultty; + end; + pshowmessageinfoty = ^showmessageinfoty; + + tshowmessagewidget = class(tmessagewidget) + protected + info: drawtextinfoty; + fexttext: msestring; + finfo: pshowmessageinfoty; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + procedure doidle(var again: boolean); + //iassistiveclient + function getassistivetext(): msestring override; + function getassistiveflags(): assistiveflagsty override; + public + constructor create(const aowner: tcomponent; const apopuptransient: boolean; + const ahasaction: boolean; const exttext: msestring; + const ainfo: pshowmessageinfoty); + destructor destroy(); override; + end; + +procedure buttonoptionstoshapestate(avalue: buttonoptionsty; + var astate: shapestatesty); +begin + if bo_ellipsemouse in avalue then begin + include(astate,shs_ellipsemouse); + end + else begin + exclude(astate,shs_ellipsemouse); + end; + if bo_coloractive in avalue then begin + include(astate,shs_focuscolor); + end + else begin + exclude(astate,shs_focuscolor); + end; +end; + +function readcaptiontoimagepos(const reader: treader): imageposty; +begin + result:= captiontoimagepos[captionposty( + readenum(reader,typeinfo(captionposty)))]; +end; + +procedure synccaptiondistx(const awidgets: array of twidget); + //adjusts captiondist for equal distouter to paintrect + //don't set cfo_captiondistouter +var + int1,int2,int3,int4: integer; +begin + int2:= bigint; + int3:= 0; + for int1:= 0 to high(awidgets) do begin + with twidget1(awidgets[int1]) do begin + if (fframe <> nil) and + (fs_cancaptionsyncx in tcustomframe1(fframe).fstate) then begin + with tcustomcaptionframe(fframe) do begin + checkstate(); + if fcaptiondist < int2 then begin + int2:= fcaptiondist; + end; + int4:= finfo.dest.cx; + if fcaptionpos in rightcaptionpos then begin + int4:= int4 + fwidth.right; + end + else begin + int4:= int4 + fwidth.left; + end; + if int4 > int3 then begin + int3:= int4; + end; + end; + end; + end; + end; + int3:= int3 + int2; //max outer dist + for int1:= 0 to high(awidgets) do begin + with twidget1(awidgets[int1]) do begin + if (fframe <> nil) and + (fs_cancaptionsyncx in tcustomframe1(fframe).fstate) then begin + with tcustomcaptionframe(fframe) do begin + if fcaptionpos in rightcaptionpos then begin + captiondist:= int3 - finfo.dest.cx - fwidth.right; + end + else begin + captiondist:= int3 - finfo.dest.cx - fwidth.left; + end; + end; + end; + end; + end; +end; + +procedure synccaptiondisty(const awidgets: array of twidget); + //adjusts captiondist for equal distouter + //don't set cfo_captiondistouter +var + int1,int2,int3,int4: integer; +begin + int2:= bigint; + int3:= 0; + for int1:= 0 to high(awidgets) do begin + with twidget1(awidgets[int1]) do begin + if (fframe <> nil) and + (fs_cancaptionsyncy in tcustomframe1(fframe).fstate) then begin + with tcustomcaptionframe(fframe) do begin + checkstate(); + if fcaptiondist < int2 then begin + int2:= fcaptiondist; + end; + int4:= finfo.dest.cy; + if fcaptionpos in bottomcaptionpos then begin + int4:= int4 + fwidth.bottom; + end + else begin + int4:= int4 + fwidth.top; + end; + if int4 > int3 then begin + int3:= int4; + end; + end; + end; + end; + end; + int3:= int3 + int2; //max outer dist + for int1:= 0 to high(awidgets) do begin + with twidget1(awidgets[int1]) do begin + if (fframe <> nil) and + (fs_cancaptionsyncy in tcustomframe1(fframe).fstate) then begin + with tcustomcaptionframe(fframe) do begin + if fcaptionpos in bottomcaptionpos then begin + captiondist:= int3 - finfo.dest.cy - fwidth.bottom; + end + else begin + captiondist:= int3 - finfo.dest.cy - fwidth.top; + end; + end; + end; + end; + end; +end; + +procedure copytoclipboard(const value: msestring; + const buffer: clipboardbufferty = cbb_clipboard); +begin + gui_copytoclipboard(value,buffer); +end; + +function canpastefromclipboard( + const buffer: clipboardbufferty = cbb_clipboard): boolean; +begin + result:= gui_canpastefromclipboard(buffer); +end; + +function pastefromclipboard(out value: msestring; + const buffer: clipboardbufferty = cbb_clipboard): boolean; +begin + result:= gui_pastefromclipboard(value,buffer) = gue_ok; +end; + +function confirmsavechangedfile(const filename: filenamety; + out modalresult: modalresultty; multiple: boolean = false): boolean; +begin + with stockobjects do begin + if multiple then begin + modalresult:= showmessage(captions[sc_file]+' '+filename+' '+ + captions[sc_is_modified_save],captions[sc_confirmation], + [mr_yes,mr_all,mr_no,mr_noall,mr_cancel],mr_yes); + end + else begin + modalresult:= showmessage(captions[sc_file]+' '+filename+' '+ + captions[sc_is_modified_save],captions[sc_confirmation], + [mr_yes,mr_no,mr_cancel],mr_yes); + end; + end; +{ + if multiple then begin + modalresult:= showmessage('File '+filename+' is modified. Save?','Confirmation', + [mr_yes,mr_all,mr_no,mr_noall,mr_cancel],mr_yes); + end + else begin + modalresult:= showmessage('File '+filename+' is modified. Save?','Confirmation', + [mr_yes,mr_no,mr_cancel],mr_yes); + end; +} + if modalresult = mr_windowclosed then begin + modalresult:= mr_cancel; + end; + result:= modalresult in [mr_yes,mr_all]; +end; + +function showsyserrormessage(const error: syserrorty; + const text: msestring = ''): boolean; + //returns true for sye_ok +begin + result:= error = sye_ok; + if not result then begin + showerror(buildsyserrormessage(error,text)); + end; +end; + +function showsyserrormessage(const error: syserrorty; + const sender: tobject; const text: msestring = ''): boolean; + //returns true for sye_ok +begin + result:= error = sye_ok; + if not result then begin + showerror(buildsyserrormessage(error,sender,text)); + end; +end; + +function getmaxdropdownheight(const parent: twidget): integer; +var + rect1: rectty; + int1: integer; +begin + rect1:= application.workarea(parent.window); + int1:= translatewidgetpoint(parent.framerect.pos,parent,nil).y; + result:= int1 - rect1.y; + int1:= rect1.y + rect1.cy - (int1 + parent.framerect.cy); + if int1 > result then begin + result:= int1; + end; +end; + +procedure getdropdownpos(const parent: twidget; const right: boolean; + var rect: rectty); +var + int1,int2: integer; + size1: sizety; + workarea: rectty; +begin + size1:= parent.framesize; + rect.pos:= translatewidgetpoint(parent.framerect.pos,parent,nil); + if right then begin + rect.x:= rect.x + size1.cx - rect.cx; + end; + workarea:= application.workarea(parent.window); + inc(rect.y,size1.cy); + int1:= (workarea.y + workarea.cy); + int2:= rect.y + rect.cy; + if (int2 > int1) and (rect.y - rect.cy - workarea.y > int1 - int2) then begin + dec(rect.y,size1.cy); + int1:= rect.y - workarea.y; + if rect.cy > int1 then begin + rect.cy:= int1; + end; + dec(rect.y,rect.cy); //shift above + end + else begin + int1:= workarea.y + workarea.cy - rect.y; + if rect.cy > int1 then begin + rect.cy:= int1; + end; + end; + int1:= (workarea.x + workarea.cx) - (rect.x + rect.cx); + if int1 < 0 then begin + inc(rect.x,int1); + end; + if rect.x < workarea.x then begin + rect.x:= workarea.x; + end; +end; + +function placepopuprect(const awindow: twindow; const adest: rectty; + const placement: captionposty; const asize: sizety): rectty; + //placement currently cp_bottomleft and cp_center only, + //todo + +var + int1: integer; + rect1: rectty; +begin + result.size:= asize; + with adest do begin + if placement = cp_bottomleft then begin + result.x:= x; + result.y:= y + cy; + end + else begin + result.x:= x + (cx - asize.cx) div 2; + result.y:= y + (cy - asize.cy) div 2; + end; + rect1:= application.workarea(awindow); + with result do begin //shift in workarea + int1:= (rect1.x + rect1.cx) - (x + cx); + if int1 < 0 then begin + inc(x,int1); + end; + if x < rect1.x then begin + x:= rect1.x; + end; + if y + cy > rect1.y + rect1.cy then begin + if placement = cp_bottomleft then begin + y:= adest.y - asize.cy; //above destrect + end + else begin + y:= rect1.y + rect1.cy - asize.cy; + end; + if y < rect1.y then begin + y:= rect1.y; + end; + end; + end; + end; +end; + +function placepopuprect(const awidget: twidget; const adest: rectty; //widgetorig + const placement: captionposty; const asize: sizety): rectty; +begin + result:= placepopuprect(awidget.window,moverect(adest, + translatewidgetpoint(nullpoint,awidget,nil)),placement,asize); +end; + +function placeclientpopuprect(const awidget: twidget; + const adest: rectty; //clientorig + const placement: captionposty; const asize: sizety): rectty; +begin + result:= placepopuprect(awidget.window,moverect(adest, + translateclientpoint(nullpoint,awidget,nil)),placement,asize); +end; + +procedure getwindowicon(const abitmap: tmaskedbitmap; out aicon,amask: pixmapty; + const anodefault: boolean = false); +var + bmp: tmaskedbitmap; +begin + aicon:= 0; + amask:= 0; + if abitmap <> nil then begin + if abitmap.source <> nil then begin + bmp:= abitmap.source.bitmap; + end + else begin + bmp:= abitmap; + end; + if not bmp.isempty then begin + if bmp.masked then begin + amask:= bmp.mask.handle; //first because it possibly destroys bmp.handle + end; + aicon:= bmp.handle; + end; + end; + if (aicon = 0) and not anodefault then begin + getwindowicon(stockobjects.mseicon,aicon,amask); + end; +end; + +function messagerect(const position: messagepositionty; + out arect: rectty): prectty; +var + window1: twindow; +begin + application.lockifnotmainthread; + try + result:= nil; + if position <> mepo_screencentered then begin + window1:= application.unreleasedactivewindow; + if (window1 <> nil) and + ((position = mepo_windowcentered) or + (wo_windowcentermessage in window1.options)) then begin + arect:= window1.owner.widgetrect; + result:= @arect; + end + else begin + result:= nil; + end; + end; + finally + application.unlockifnotmainthread; + end; +end; + + +procedure syncshowmessage(const adata: pointer); +const + maxtextwidth = 500; + verttextdist = 10; + horztextdist = 10; + buttondist = 10; +var + buttonheight: integer; + buttonwidth: integer; + widget: tshowmessagewidget; + widget1: twidget; //dummy parent to get invisible canvas + but: array[0..integer(high(modalresultty))] of tmessagebutton; + int1,int2: integer; + rect1{,rect2}: rectty; + acanvas: tcanvas; + textoffset: integer; + transientfor: twindow; + +begin + with pshowmessageinfoty(adata)^ do begin + application.lockifnotmainthread; + try + transientfor:= application.unreleasedactivewindow; + widget1:= twidget.create(nil); + widget1.visible:= false; + //stays invisible, no wm_configured processing on win32 + widget:= tshowmessagewidget.create(nil,(transientfor <> nil) and + (transientfor.ispopup) and transientfor.owner.visible, + high(actions) >= 0,exttext,pshowmessageinfoty(adata)); + widget.name:= '_showmessage'; //debug purpose + widget.parentwidget:= widget1; //do not create window handle of widget + try + acanvas:= widget1.getcanvas; + buttonheight:= acanvas.font.glyphheight + 6; + buttonwidth:= 50; + for int1:= 0 to ord(high(buttons)) do begin + int2:= acanvas.getstringwidth( + stockobjects.modalresulttextnoshortcut[buttons[int1]]) + 10; + if int2 > buttonwidth then begin + buttonwidth:= int2; + end; + end; + widget.caption:= caption; + acanvas.font:= stockobjects.fonts[stf_message]; + rect1:= textrect(acanvas,atext); + if rect1.cx > maxtextwidth then begin + rect1.cx:= maxtextwidth; + rect1.cy:= bigint; + rect1:= textrect(acanvas,atext,rect1,[tf_wordbreak]); + widget.info.flags:= [tf_wordbreak]; + end; + rect1.x:= horztextdist; + rect1.y:= verttextdist; + textoffset:= minwidth - rect1.cx; + if textoffset > 0 then begin + rect1.cx:= minwidth; + end + else begin + textoffset:= 0; + end; + with widget.info do begin + dest:= rect1; + text.text:= atext; + end; + int1:= length(buttons); + if int1 > 0 then begin + int2:= int1 * buttonwidth; + int2:= int2 + buttondist * (int1 - 1); + inc(rect1.cy,buttonheight+verttextdist); + end + else begin + int2:= 0; + end; + if int2 > rect1.cx then begin + rect1.cx:= int2; //width of buttons greater then text width + widget.info.dest.cx:= int2; + end; + + inc(rect1.cx,2*horztextdist); + inc(rect1.cy,2*verttextdist); + + widget.parentwidget:= nil; //remove dummy parent + widget.clientsize:= rect1.size; + if placementrect = nil then begin + widget.window.windowpos:= wp_screencentered; + end + else begin +// rect2:= placementrect^; + { + if placement = cp_bottomleft then begin + dec(rect2.y,8); + inc(rect2.cy,28); //for windowdecoration + end; + } + widget.widgetrect:= placepopuprect(transientfor, + placementrect^,placement,widget.size); + end; + + with widget.info.dest do begin + rect1.x:= x + (cx - int2) div 2; + rect1.y:= y + cy + verttextdist + widget.paintpos.y; + rect1.cx:= buttonwidth; + rect1.cy:= buttonheight; + end; + for int1:= 0 to high(buttons) do begin + but[int1]:= tmessagebutton.create(widget); + with but[int1] do begin + widgetrect:= rect1; + parentwidget:= widget; + if buttons[int1] in noshortcut then begin + caption:= + stockobjects.modalresulttextnoshortcut[buttons[int1]]; +{ + captiontorichstring( + stockobjects.modalresulttextnoshortcut[buttons[int1]], + finfo.ca.caption); +} + end + else begin + caption:= stockobjects.modalresulttext[buttons[int1]]; +{ + captiontorichstring(stockobjects.modalresulttext[buttons[int1]], + finfo.ca.caption); +} + end; + if int1 <= high(actions) then begin + onexecute:= actions[int1]; + end; + modalresult:= buttons[int1]; + end; + if buttons[int1] = defaultbutton then begin + widget.defaultfocuschild:= but[int1]; + end; + inc(rect1.x,buttonwidth + buttondist); + end; + inc(widget.info.dest.x,textoffset div 2); + dec(widget.info.dest.cx,textoffset); + widget.updateskin(true); + { + if placementrect <> nil then begin + widget.visible:= true; + application.processmessages(); //decorate window + widget.window.decoratedwidgetrect:= placepopuprect(transientfor, + placementrect^,placement,widget.window.decoratedsize); + end; + } + result:= widget.show(true,transientfor); + finally + widget1.free; + widget.Free; + end; + finally + application.unlockifnotmainthread; + end; + end; +end; + +function internalshowmessage(const atext_,caption_: msestring; + buttons_: array of modalresultty; + defaultbutton_: modalresultty; + noshortcut_: modalresultsty; + placementrect_: prectty; placement_: captionposty; + minwidth_: integer; actions_: array of notifyeventty; + const exttext_: msestring; + const async_: boolean = false): modalresultty; +var + info: showmessageinfoty; +begin + with info do begin + atext:= atext_; + caption:= caption_; + setlength(buttons,length(buttons_)); + move(buttons_[0],buttons[0],length(buttons)*sizeof(buttons[0])); + defaultbutton:= defaultbutton_; + noshortcut:= noshortcut_; + placementrect:= placementrect_; + placement:= placement_; + minwidth:= minwidth_; + setlength(actions,length(actions_)); + move(actions_[0],actions[0],length(actions)* + sizeof({$ifndef FPC}@{$endif}actions[0])); + exttext:= exttext_; + async:= async_; + end; + if application.ismainthread then begin + syncshowmessage(@info); + end + else begin + application.synchronize(@syncshowmessage,@info); + end; + result:= info.result; +end; + +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const defaultbutton: modalresultty = mr_cancel; + const noshortcut: modalresultsty = []; + const minwidth: integer = 0; + const exttext: msestring = ''; + const position: messagepositionty = mepo_default): modalresultty; +var + rect1: rectty; +begin + result:= internalshowmessage(atext,caption,buttons,defaultbutton, + noshortcut,messagerect(position,rect1),cp_center,minwidth,[],exttext); +end; + +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const defaultbutton: modalresultty; + const noshortcut: modalresultsty; + const minwidth: integer; + const actions: array of notifyeventty; + const exttext: msestring = ''; + const position: messagepositionty = mepo_default): modalresultty; +var + rect1: rectty; +begin + result:= internalshowmessage(atext,caption,buttons,defaultbutton, + noshortcut,messagerect(position,rect1),cp_center, + minwidth,actions,exttext); +end; + +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const adest: rectty; const awidget: twidget = nil; + //origin = awidget.clientpos, screen if awidget = nil + const placement: captionposty = cp_bottomleft; + const defaultbutton: modalresultty = mr_cancel; + const noshortcut: modalresultsty = []; + const minwidth: integer = 0; + const exttext: msestring = ''): modalresultty; overload; +var + rect1: rectty; +begin + if awidget = nil then begin + rect1.pos:= adest.pos; + end + else begin + application.lockifnotmainthread; + try + rect1.pos:= translateclientpoint(adest.pos,awidget,nil); + finally + application.unlockifnotmainthread; + end; + end; + rect1.size:= adest.size; + result:= internalshowmessage(atext,caption,buttons,defaultbutton,noshortcut, + @rect1,placement,minwidth,[],exttext); +end; + +function showmessage(const atext: msestring; const caption: msestring = ''; + const minwidth: integer = 0; + const exttext: msestring = ''): modalresultty; +begin + result:= showmessage(atext,caption,[mr_ok],mr_ok,[],minwidth,exttext); +end; + +procedure showmessage1(const atext: msestring; const caption: msestring); + //for ps +begin + showmessage(atext,caption); +end; + +type + tshowerrormessageevent = class(texecuteevent) + private + ftext: msestring; + fcaption: msestring; + fminwidth: integer; + fexttext: msestring; + protected + procedure execute; override; + public + constructor create(const text: msestring; const caption: msestring; + const minwidth: integer; const exttext: msestring); + end; + +{ tshowerrormessageevent } + +constructor tshowerrormessageevent.create(const text: msestring; + const caption: msestring; const minwidth: integer; + const exttext: msestring); +begin + ftext:= text; + fcaption:= caption; + fminwidth:= minwidth; + fexttext:= exttext; + inherited create; + application.postevent(self); +end; + +procedure tshowerrormessageevent.execute; +var + rect1: rectty; +begin + internalshowmessage(ftext,fcaption,[mr_ok],mr_ok, + [],messagerect(mepo_default,rect1),cp_center,0,[],fexttext,true); +// showmessage(ftext,fcaption,fminwidth,fexttext); +end; + +procedure showerror(const atext: msestring; caption: msestring = 'ERROR'; + const minwidth: integer = 0; + const exttext: msestring = ''; + const async: boolean = false); +begin + if caption = 'ERROR' then begin + caption:= sc(sc_errorupper); + end; + if async or not application.ismainthread then begin + tshowerrormessageevent.create(atext,caption,minwidth,exttext); + end + else begin + showmessage(atext,caption,minwidth,exttext); + end; +end; + +function askok(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_ok; + const minwidth: integer = 0): boolean; + //true if ok pressed +begin + result:= showmessage(atext,caption,[mr_ok,mr_cancel],defaultbutton,[], + minwidth) = mr_ok; +end; + +function askyesno(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): boolean; + //true if yes pressed +begin + result:= showmessage(atext,caption,[mr_yes,mr_no],defaultbutton,[], + minwidth) = mr_yes; +end; + +function askyesnocancel(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0 ): modalresultty; +begin + result:= showmessage(atext,caption,[mr_yes,mr_no,mr_cancel],defaultbutton,[], + minwidth); + if not (result in [mr_yes,mr_no]) then begin + result:= mr_cancel; + end; +end; + +function askconfirmation(const atext: msestring; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): boolean; + //true if yes pressed +begin + result:= showmessage(atext,sc(sc_confirmation),[mr_yes,mr_no],defaultbutton,[], + minwidth) = mr_yes; +end; + +function askconfirmationcancel(const atext: msestring; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): modalresultty; +begin + result:= askyesnocancel(atext,sc(sc_confirmation),defaultbutton,minwidth); +end; + +{ tframefont} + +class function tframefont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomcaptionframe(owner).ffont; +end; + +{ tactionsimplebutton} + +constructor tactionsimplebutton.create(aowner: tcomponent); +begin + foptions:= defaultbuttonoptions; + inherited; + optionswidget:= defaultoptionswidget - [ow_mousefocus]; + initshapeinfo(finfo); + finfo.ca.dim:= innerclientrect; + finfo.color:= cl_transparent; + finfo.ca.colorglyph:= cl_black; + finfo.doexecute:= {$ifdef FPC}@{$endif}doshapeexecute; + finfo.state:= finfo.state+[shs_showfocusrect,shs_showdefaultrect]; +end; +{ +procedure tactionsimplebutton.setoptionswidget(const avalue: optionswidgetty); +begin + if ow_nofocusrect in avalue then begin + exclude(finfo.state,ss_showfocusrect); + end + else begin + include(finfo.state,ss_showfocusrect); + end; + inherited; +end; +} +procedure tactionsimplebutton.clientrectchanged; +begin + inherited; + frameskinoptionstoshapestate(fframe,finfo); + finfo.ca.dim:= clientrect; + if (fframe <> nil) and not(shs_noinnerrect in finfo.state) then begin + //otherwise mouse rect + deflaterect1(finfo.ca.dim,fframe.frameo); + end; +{ + if shs_noinnerrect in finfo.state then begin + finfo.ca.dim:= clientrect; + end + else begin + finfo.ca.dim:= innerclientrect; + end; +} + if shs_flat in finfo.state then begin + exclude(fwidgetstate1,ws1_nodesignframe); + end + else begin + include(fwidgetstate1,ws1_nodesignframe); + end; +end; + +procedure tactionsimplebutton.doexecute; +begin + //dummy +end; + +procedure tactionsimplebutton.doasyncevent(var atag: integer); +begin + if atag = 0 then begin + doexecute; + end; +end; + +procedure tactionsimplebutton.internalexecute(); +begin + if bo_asyncexecute in foptions then begin + asyncevent; + end + else begin + doexecute; + end; +end; + +procedure tactionsimplebutton.doshapeexecute(const atag: integer; + const info: mouseeventinfoty); +begin + internalexecute; +end; + +procedure tactionsimplebutton.dopaintforeground(const canvas: tcanvas); +begin + inherited; + finfo.frame:= fframe; + drawbutton(canvas,finfo); +end; + +procedure tactionsimplebutton.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (csdesigning in componentstate) and + not (es_processed in info.eventstate) then begin + updatemouseshapestate(finfo,info,self,fframe,nil,bo_executeonclick in foptions); + end; +end; + +procedure tactionsimplebutton.execute; +begin + if not (shs_disabled in finfo.state) then begin + internalexecute; + end; +end; + +procedure tactionsimplebutton.pressbutton; +begin + include(finfo.state,shs_clicked); + invalidateframestaterect(finfo.ca.dim,fframe); +end; + +function tactionsimplebutton.releasebutton(const aexecute: boolean): boolean; + //true if clicked +begin + result:= shs_clicked in finfo.state; + exclude(finfo.state,shs_clicked); + if result then begin + invalidateframestaterect(finfo.ca.dim,fframe); + if aexecute then begin + internalexecute; + end; + end; +end; + +procedure tactionsimplebutton.dokeydown(var info: keyeventinfoty); +begin +// inherited; + with info do begin + if not getdisabled() and (shiftstate * shiftstatesrepeatmask = []) and + (bo_executeonkey in foptions) then begin + if (key = key_space) then begin + include(info.eventstate,es_processed); + pressbutton; + end + else begin + if (isenterkey(self,key) or (key = key_period)) and + not (aso_noreturnbutton in assistiveoptions) then begin + //only space key if assisted + include(eventstate,es_processed); + internalexecute; + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tactionsimplebutton.dokeyup(var info: keyeventinfoty); +begin + inherited; + if not getdisabled() and (info.key = key_space) and + releasebutton((info.shiftstate = []) and + (bo_executeonkey in foptions)) then begin + include(info.eventstate,es_processed); + end; +end; + +procedure tactionsimplebutton.statechanged; +begin + inherited; + updatewidgetshapestate(finfo,self,getdisabled(),{false,}fframe); +end; + +procedure tactionsimplebutton.setcolorglyph(const value: colorty); +begin + if finfo.ca.colorglyph <> value then begin + finfo.ca.colorglyph := value; + invalidate; + end; +end; + +class function tactionsimplebutton.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_simplebutton; +end; + +procedure tactionsimplebutton.setoptions(const avalue: buttonoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + buttonoptionstoshapestate(avalue,finfo.state); + invalidate; + end; +end; + +function tactionsimplebutton.getframestateflags: framestateflagsty; +begin + result:= combineframestateflags(not isenabled,focused,active, + shs_mouse in finfo.state,shs_clicked in finfo.state); + if not (bo_nodefaultframeactive in foptions) and + ((shs_default in finfo.state) or focused) then begin + include(result,fsf_offset1); + include(result,fsf_default); + end; +end; + +function tactionsimplebutton.navigstartrect: rectty; +begin + result:= inherited navigstartrect; +// result.x:= result.x + result.cx div 2; +// result. cx:= 0; +end; + +function tactionsimplebutton.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_button]; + if getdisabled() then begin + include(result,asf_disabled); + end; +end; + +function tactionsimplebutton.getdisabled(): boolean; +begin + result:= false; +end; + +{ +function tactionsimplebutton.getframeclicked: boolean; +begin + result:= ss_clicked in finfo.state; +end; + +function tactionsimplebutton.getframemouse: boolean; +begin + result:= ss_mouse in finfo.state; +end; + +function tactionsimplebutton.getframeactive: boolean; +begin + result:= not (bo_nodefaultframeactive in foptions) and + (ss_default in finfo.state) or active; +end; +} +{ tmessagebutton } + +procedure tmessagebutton.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + captiontorichstring(avalue,finfo.ca.caption); + invalidate(); +end; + +procedure tmessagebutton.doexecute; +begin + if assigned(onexecute) then begin + onexecute(self); + end; + window.modalresult:= modalresult; +end; + +procedure tmessagebutton.doshortcut(var info: keyeventinfoty; const sender: twidget); +begin + if checkshortcut(info,caption,bo_altshortcut in options) then begin + include(info.eventstate,es_processed); + internalexecute; + end + else begin + inherited; + end; +end; + +function tmessagebutton.getassistivecaption(): msestring; +//var +// capt1: richstringty; +begin + result:= fcaption; +// captiontorichstring(fcaption,capt1); +// result:= capt1.text; +end; + +{ tshowmessagewidget } + +constructor tshowmessagewidget.create(const aowner: tcomponent; + const apopuptransient: boolean; const ahasaction: boolean; + const exttext: msestring; const ainfo: pshowmessageinfoty); +begin + fexttext:= exttext; + finfo:= ainfo; + inherited create(aowner,apopuptransient,ahasaction); + if finfo^.placementrect <> nil then begin + application.registeronidle(@doidle); + end; +end; + +destructor tshowmessagewidget.destroy(); +begin + application.unregisteronidle(@doidle); + inherited; +end; + +procedure tshowmessagewidget.dopaintforeground(const canvas: tcanvas); +begin + inherited; + canvas.font:= stockobjects.fonts[stf_message]; + drawtext(canvas,info); +end; + +procedure tshowmessagewidget.dokeydown(var ainfo: keyeventinfoty); +begin + if issysshortcut(sho_copy,ainfo) or issysshortcut(sho_cut,ainfo) then begin + copytoclipboard(replacechar(info.text.text+fexttext,#0 ,' ')); + end; + inherited; +end; + +procedure tshowmessagewidget.doidle(var again: boolean); +begin + application.unregisteronidle(@doidle); + if finfo^.placementrect <> nil then begin + window.decoratedwidgetrect:= placepopuprect(window.transientfor, + finfo^.placementrect^,finfo^.placement,window.decoratedsize); + end; +end; + +function tshowmessagewidget.getassistivetext(): msestring; +begin + result:= info.text.text; +end; + +function tshowmessagewidget.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags + [asf_message]; + if finfo^.async then begin + include(result,asf_async); + end; +end; + +{ tcustomcaptionframe } + +constructor tcustomcaptionframe.create(const aintf: icaptionframe); +begin + fcaptionpos:= cp_topleft; + fcaptiondist:= 1; + inherited create(aintf); + if ffont = nil then begin + finfo.font:= icaptionframe(fintf).getframefont; + end; +end; + +destructor tcustomcaptionframe.destroy; +begin + inherited; + ffont.free; +end; +{ +function tcustomcaptionframe.getcaption: msestring; +begin + result:= richstringtocaption(finfo.text); +end; +} +procedure tcustomcaptionframe.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + captiontorichstring(avalue,finfo.text); + internalupdatestate(); +end; + +procedure tcustomcaptionframe.setcaptionpos(const avalue: captionposty); +begin + if (fcaptionpos <> avalue) then begin + { + case avalue of + cp_leftcenter: fcaptionpos:= cp_left; + cp_rightcenter: fcaptionpos:= cp_right; + cp_topcenter: fcaptionpos:= cp_top; + cp_bottomcenter: fcaptionpos:= cp_bottom; + else fcaptionpos:= avalue; + end; + } + fcaptionpos:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomcaptionframe.fontchanged(const sender: tobject); +begin + internalupdatestate; +end; + +procedure tcustomcaptionframe.fontcanvaschanged; +begin + exclude(fstate,fs_rectsvalid); +end; + +function tcustomcaptionframe.haspaintrectfocus(): boolean; +begin + result:= inherited haspaintrectfocus() or (finfo.text.text = ''); +end; + +procedure tcustomcaptionframe.dopaintfocusrect(const canvas: tcanvas; + const rect: rectty); +begin + if haspaintrectfocus then begin + inherited; + end + else begin + drawfocusrect(canvas,inflaterect(finfo.dest,captionmargin)); + end; +end; + +procedure tcustomcaptionframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); +var + reg1: regionty; + flagsbefore: textflagsty; +begin + reg1:= 0; + if not (cfo_captionnoclip in foptions) and (finfo.text.text <> '') then begin + reg1:= canvas.copyclipregion; + canvas.subcliprect(inflaterect(finfo.dest,captionmargin)); + end; + inherited; + if reg1 <> 0 then begin + canvas.clipregion:= reg1; + end; + if finfo.text.text <> '' then begin + flagsbefore:= finfo.flags; + finfo.flags:= updatetextflags(finfo.flags); + drawtext(canvas,finfo); + finfo.flags:= flagsbefore; + end; +end; +{ +procedure tcustomcaptionframe.afterpaint(const canvas: tcanvas); +begin + if finfo.text.text <> '' then begin + drawtext(canvas,finfo); + end; + inherited; +end; +} +procedure tcustomcaptionframe.createfont; +begin + if ffont = nil then begin + ffont:= tframefont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + finfo.font:= ffont; + end; +end; + +function tcustomcaptionframe.getfont: tframefont; +begin +// getoptionalobject(fintf.getcomponentstate,ffont,{$ifdef FPC}@{$endif}createfont); + icaptionframe(fintf).getwidget.getoptionalobject(ffont, + {$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= tframefont(icaptionframe(fintf).getframefont); + end; +end; + +procedure tcustomcaptionframe.setfont(const Value: tframefont); +begin + if value <> ffont then begin + setoptionalobject(fintf.getcomponentstate,value,ffont,{$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + finfo.font:= ffont; + end + else begin + finfo.font:= icaptionframe(fintf).getframefont; + end; + internalupdatestate(); + end; +end; + +function tcustomcaptionframe.isfontstored: Boolean; +begin + result:= ffont <> nil; +end; + +procedure tcustomcaptionframe.parentfontchanged; +begin + inherited; + if ffont = nil then begin + finfo.font:= icaptionframe(fintf).getframefont; + if not (ws_loadedproc in icaptionframe(fintf).getwidget.widgetstate) then begin + internalupdatestate; + end; + end; +end; + +procedure tcustomcaptionframe.visiblechanged; +begin + inherited; + if finfo.text.text <> '' then begin + internalupdatestate; + end; +end; + +function tcustomcaptionframe.updatetextflags( + const aflags: textflagsty): textflagsty; +begin + result:= finfo.flags; + if (fs_disabled in fstate) and not (cfo_captionnogray in foptions) then begin + include(result,tf_grayed); + end; +end; + +procedure tcustomcaptionframe.updaterects; +var + canvas: tcanvas; + fra1: framety; + rect1,rect2: rectty; + bo1,bo2: boolean; + widget1: twidget1; + flagsbefore: textflagsty; +begin + inherited; + fra1:= fouterframe; + fstate:= fstate - [fs_cancaptionsyncx,fs_cancaptionsyncy]; + if finfo.text.text <> '' then begin + flagsbefore:= finfo.flags; + finfo.flags:= updatetextflags(finfo.flags); + canvas:= icaptionframe(fintf).getcanvas; + canvas.font:= getfont; + finfo.dest.size:= icaptionframe(fintf).getwidgetrect.size; + rect1:= deflaterect(makerect(nullpoint,finfo.dest.size),fouterframe); + textrect(canvas,finfo); + finfo.flags:= flagsbefore; +// finfo.flags:= flagsbefore-[tf_xcentered,tf_ycentered,tf_right,tf_bottom]; + finfo.dest:= finfo.res; + bo1:= cfo_captiondistouter in foptions; + bo2:= cfo_captionframecentered in foptions; + rect2:= inflaterect(finfo.dest,captionmargin); + with rect2 do begin + if fcaptionpos = cp_center then begin //precision position for record + x:= (rect1.x + rect1.x + rect1.cx - rect2.cx) div 2 + fcaptiondist; + y:= (rect1.y + rect1.y + rect1.cy - rect2.cy) div 2 + fcaptionoffset; +// finfo.flags:= finfo.flags + [tf_xcentered,tf_ycentered]; + end + else begin + { + if fcaptionpos in [cp_left,cp_right] then begin + include(finfo.flags,tf_ycentered); + end + else begin + if fcaptionpos in [cp_top,cp_bottom] then begin + include(finfo.flags,tf_xcentered); + end; + end; + if fcaptionpos in [cp_left,cp_lefttop,cp_leftbottom] then begin + include(finfo.flags,tf_right); + end + else begin + if fcaptionpos in [cp_top,cp_topleft,cp_topright] then begin + include(finfo.flags,tf_bottom); + end; + end; + } + case fcaptionpos of + cp_lefttop,cp_left,cp_leftbottom: begin + include(fstate,fs_cancaptionsyncx); + x:= rect1.x - fcaptiondist; + if not bo1 then begin + x:= x - cx; + if bo2 then begin + x:= x + (cx + fwidth.left) div 2; + end; + end; + end; + cp_topleft,cp_bottomleft: begin + include(fstate,fs_cancaptionsyncy); + x:= rect1.x + fcaptionoffset; + end; + cp_top,cp_bottom: begin + include(fstate,fs_cancaptionsyncy); + x:= rect1.x + (rect1.cx - cx) div 2 + fcaptionoffset; + end; + cp_topright,cp_bottomright: begin + include(fstate,fs_cancaptionsyncy); + x:= rect1.x + rect1.cx - cx + fcaptionoffset; + end; + cp_righttop,cp_right,cp_rightbottom: begin + include(fstate,fs_cancaptionsyncx); + x:= rect1.x + rect1.cx + fcaptiondist; + if bo1 then begin + x:= x - cx; + end + else begin + if bo2 then begin + x:= x - (fwidth.right + cx) div 2; + end; + end; + end; + end; + case fcaptionpos of + cp_topleft,cp_top,cp_topright: begin + y:= rect1.y - fcaptiondist; + if not bo1 then begin + y:= y - cy; + if bo2 then begin + y:= y + (cy+fwidth.top) div 2; + end; + end; + end; + cp_lefttop,cp_righttop: begin + y:= rect1.y + fcaptionoffset; + end; + cp_left,cp_right: begin + y:= rect1.y + (rect1.cy - cy) div 2 + fcaptionoffset; + end; + cp_leftbottom,cp_rightbottom: begin + y:= rect1.y + rect1.cy - cy + fcaptionoffset; + end; + cp_bottomleft,cp_bottom,cp_bottomright: begin + y:= rect1.y + rect1.cy + fcaptiondist; + if bo1 then begin + y:= y - cy; + end + else begin + if bo2 then begin + y:= y - (cy + fwidth.bottom) div 2; + end; + end; + end; + end; + end; + fouterframe.left:= rect1.x - x; + if fouterframe.left < 0 then begin + fouterframe.left:= 0; + end; + fouterframe.top:= rect1.y - y; + if fouterframe.top < 0 then begin + fouterframe.top:= 0; + end; + fouterframe.right:= x + cx - (rect1.x + rect1.cx); + if fouterframe.right < 0 then begin + fouterframe.right:= 0; + end; + fouterframe.bottom:= y + cy - (rect1.y + rect1.cy); + if fouterframe.bottom < 0 then begin + fouterframe.bottom:= 0; + end; + end; + finfo.dest:= inflaterect(rect2,-captionmargin); + if bo1 then begin + fstate:= fstate - [fs_cancaptionsyncx,fs_cancaptionsyncy]; + //captiondistouter set + end; + end + else begin //caption = '' or invisible + fouterframe:= nullframe; + finfo.dest:= nullrect; + end; + subframe1(fra1,fouterframe); + + widget1:= twidget1(icaptionframe(fintf).getwidget); + + if (cfo_autowidth in foptions) or + (widget1.anchors * [an_left,an_right] = [an_left,an_right]) then begin + if fcaptionpos in [cp_topleft,cp_bottomleft, + cp_top,cp_bottom,cp_center] then begin + fouterframe.right:= 0; + end; + if fcaptionpos in [cp_topright,cp_bottomright, + cp_top,cp_bottom,cp_center] then begin + fouterframe.left:= 0; + end; + end; + if (cfo_autoheight in foptions) or + (widget1.anchors * [an_top,an_bottom] = [an_top,an_bottom]) then begin + if fcaptionpos in [cp_lefttop,cp_righttop, + cp_left,cp_right,cp_center] then begin + fouterframe.bottom:= 0; + end; + if fcaptionpos in [cp_leftbottom,cp_rightbottom, + cp_left,cp_right,cp_center] then begin + fouterframe.top:= 0; + end; + end; + + if not isnullframe(fra1) then begin + if widget1.fwidgetstate1 * + [ws1_anchorsizing,ws1_layoutplacing] = [] then begin + subpoint1(finfo.dest.pos,pointty(fra1.topleft)); + if fupdating < 16 then begin + inc(fupdating); + try + rect1:= icaptionframe(fintf).getwidgetrect; + rect2:= deflaterect(rect1,fra1); + if cfo_fixleft in foptions then begin + rect2.x:= rect1.x; + if cfo_fixright in foptions then begin + rect2.cx:= rect1.cx; + end; + end + else begin + if cfo_fixright in foptions then begin + rect2.x:= rect1.x+rect1.cx-rect2.cx; + end; + end; + if cfo_fixtop in foptions then begin + rect2.y:= rect1.y; + if cfo_fixbottom in foptions then begin + rect2.cy:= rect1.cy; + end; + end + else begin + if cfo_fixbottom in foptions then begin + rect2.y:= rect1.y+rect1.cy-rect2.cy; + end; + end; + if (fupdating = 1) and + rectisequal(icaptionframe(fintf).getwidgetrect,rect2) then begin + if widget1.fparentwidget <> nil then begin + twidget1(widget1.fparentwidget).childautosizechanged(widget1); + end; //activate tlayouter + end + else begin + icaptionframe(fintf).setwidgetrect(rect2); + end; + finally + dec(fupdating); + end; + end; + end; + end; + inherited; +end; + +procedure tcustomcaptionframe.updatehotkeys(); +begin + captiontorichstring(fcaption,finfo.text); + internalupdatestate(); +end; + +procedure tcustomcaptionframe.dominsize(var asize: sizety); +var + si1: sizety; + framesi1: sizety; +begin + framesi1.cx:= fpaintframe.left + fpaintframe.right - + (fouterframe.left + fouterframe.right); + framesi1.cy:= fpaintframe.top + fpaintframe.bottom - + (fouterframe.top + fouterframe.bottom); + if asize.cx < framesi1.cx then begin + asize.cx:= framesi1.cx; + end; + if asize.cy < framesi1.cy then begin + asize.cy:= framesi1.cy; + end; + if finfo.text.text <> '' then begin + checkstate(); + si1.cx:= finfo.dest.size.cx + 2*captionmargin; + si1.cy:= finfo.dest.size.cy + 2*captionmargin; + case captionpos of + cp_center: begin + si1.cx:= si1.cx + abs(fcaptiondist); + si1.cy:= si1.cy + abs(fcaptionoffset); + end; + cp_righttop,cp_right,cp_rightbottom,cp_lefttop,cp_left,cp_leftbottom: begin + si1.cx:= framesi1.cx + si1.cx + abs(fcaptiondist); + if fcaptionoffset > 0 then begin + si1.cy:= si1.cy + fcaptionoffset; + end; + end + else begin + si1.cy:= framesi1.cy + si1.cy + abs(fcaptiondist); + if fcaptionoffset > 0 then begin + si1.cx:= si1.cx + fcaptionoffset; + end; + end; + end; + if asize.cx < si1.cx then begin + asize.cx:= si1.cx; + end; + if asize.cy < si1.cy then begin + asize.cy:= si1.cy; + end; + end; +end; + +procedure tcustomcaptionframe.checkminshrinksize(var asize: sizety); +begin + inherited; + dominsize(asize); +end; + +procedure tcustomcaptionframe.checkwidgetsize(var asize: sizety); +begin //for autosize + dominsize(asize); +end; + +procedure tcustomcaptionframe.setcaptiondist(const Value: integer); +begin + include(flocalprops1,frl1_captiondist); + if fcaptiondist <> value then begin + fcaptiondist := Value; + internalupdatestate; + end; +end; + +function tcustomcaptionframe.iscaptiondiststored: boolean; +begin + result:= (ftemplate = nil) or (frl1_captiondist in flocalprops1); +end; + +procedure tcustomcaptionframe.setcaptionoffset(const Value: integer); +begin + include(flocalprops1,frl1_captionoffset); + if fcaptionoffset <> value then begin + fcaptionoffset:= Value; + internalupdatestate(); + end; +end; + +procedure tcustomcaptionframe.setcaptiontextflags(const avalue: textflagsty); +begin + if finfo.flags <> avalue then begin + finfo.flags:= checktextflags(finfo.flags,avalue); + internalupdatestate(); + end; +end; + + +function tcustomcaptionframe.iscaptionoffsetstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_captionoffset in flocalprops1); +end; + +procedure tcustomcaptionframe.setoptions(const avalue: captionframeoptionsty); +const +// mask1: captionframeoptionsty = [cfo_captiondistouter,cfo_captionframecentered]; + mask2: captionframeoptionsty = [cfo_captiondistouter]; +var + optionsbefore: captionframeoptionsty; + size1: sizety; +begin + if avalue <> foptions then begin + optionsbefore:= foptions; + (* + foptions:= captionframeoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(foptions), + {$ifdef FPC}longword{$else}word{$endif}(mask1))); + *) + foptions:= captionframeoptionsty( + setsinglebit(longword(avalue),longword(foptions), + [longword([cfo_captiondistouter,cfo_captionframecentered]), + longword([cfo_focusrect,cfo_nofocusrect])])); + if (({$ifdef FPC}longword{$else}word{$endif}(optionsbefore) xor + {$ifdef FPC}longword{$else}word{$endif}(foptions)) and + {$ifdef FPC}longword{$else}word{$endif}(mask2) <> 0) and + (fintf.getcomponentstate * [csdesigning,csloading] = [csdesigning]) and + (caption <> '') then begin + size1.cy:= font.glyphheight + 2 * captionmargin; + size1.cx:= icaptionframe(fintf).getcanvas.getstringwidth(caption,getfont) + + 2 * captionmargin; + case captionpos of + cp_center: begin + end; + cp_lefttop,cp_left,cp_leftbottom,cp_rightbottom,cp_right,cp_righttop: begin + if cfo_captiondistouter in foptions then begin + fcaptiondist:= fcaptiondist + size1.cx; + end + else begin + fcaptiondist:= fcaptiondist - size1.cx; + end; + end; + cp_topright,cp_top,cp_topleft,cp_bottomleft,cp_bottom,cp_bottomright: begin + if cfo_captiondistouter in foptions then begin + fcaptiondist:= fcaptiondist + size1.cy; + end + else begin + fcaptiondist:= fcaptiondist - size1.cy; + end; + end; + end; + end; + internalupdatestate; + end; +end; + +(* +function tcustomcaptionframe.getcaptiondistouter: boolean; +begin + result:= fs_captiondistouter in fstate; +end; + +function tcustomcaptionframe.getcaptionframecentered: boolean; +begin + result:= fs_captionframecentered in fstate; +end; + +procedure tcustomcaptionframe.setcaptionframecentered(const avalue: boolean); +begin + if updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_captionframecentered),avalue) then begin + if avalue then begin + exclude(fstate,fs_captiondistouter); + end; + internalupdatestate; + end; +end; + +procedure tcustomcaptionframe.setcaptiondistouter(const Value: boolean); +var + size1: sizety; +begin + if updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_captiondistouter),value) then begin + if value then begin + exclude(fstate,fs_captionframecentered); + end; + if (fintf.getcomponentstate * [csdesigning,csloading] = [csdesigning]) and + (caption <> '') then begin + size1.cy:= font.glyphheight + 2 * captionmargin; + size1.cx:= icaptionframe(fintf).getcanvas.getstringwidth(caption,getfont) + + 2 * captionmargin; + case captionpos of + cp_center: begin + end; + cp_lefttop,cp_left,cp_leftbottom,cp_rightbottom,cp_right,cp_righttop: begin + if fs_captiondistouter in fstate then begin + fcaptiondist:= fcaptiondist + size1.cx; + end + else begin + fcaptiondist:= fcaptiondist - size1.cx; + end; + end; + cp_topright,cp_top,cp_topleft,cp_bottomleft,cp_bottom,cp_bottomright: begin + if fs_captiondistouter in fstate then begin + fcaptiondist:= fcaptiondist + size1.cy; + end + else begin + fcaptiondist:= fcaptiondist - size1.cy; + end; + end; + end; + end; + internalupdatestate; + end; +end; + +function tcustomcaptionframe.getcaptionnoclip: boolean; +begin + result:= fs_captionnoclip in fstate; +end; + +procedure tcustomcaptionframe.setcaptionnoclip(const avalue: boolean); +begin + if updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_captionnoclip),avalue) then begin + internalupdatestate; + end; +end; +*) +procedure tcustomcaptionframe.defineproperties(filer: tfiler); +var + bo1: boolean; +begin + inherited; + if filer.ancestor <> nil then begin + bo1:= not frameisequal(fouterframe,tcustomcaptionframe(filer.ancestor).fouterframe); + end + else begin + bo1:= not isnullframe(fouterframe); + end; + filer.DefineProperty('outerframe',{$ifdef FPC}@{$endif}readouterframe, + {$ifdef FPC}@{$endif}writeouterframe,bo1); + filer.DefineProperty('captiondistouter', //backward compatibility + {$ifdef FPC}@{$endif}readcaptiondistouter,nil,false); + filer.DefineProperty('captionnoclip', //backward compatibility + {$ifdef FPC}@{$endif}readcaptionnoclip,nil,false); +end; + +procedure tcustomcaptionframe.readouterframe(reader: treader); +begin + with fouterframe,reader do begin + readlistbegin; + left:= ReadInteger; + top:= ReadInteger; + right:= ReadInteger; + bottom:= ReadInteger; + readlistend; + end; +end; + +procedure tcustomcaptionframe.writeouterframe(writer: twriter); +begin + with fouterframe,writer do begin + writelistbegin; + writeinteger(left); + writeinteger(top); + writeinteger(right); + writeinteger(bottom); + writelistend; + end; +end; + +procedure tcustomcaptionframe.readcaptionnoclip(reader: treader); +begin + if reader.readboolean then begin + options:= options + [cfo_captionnoclip]; + end + else begin + options:= options - [cfo_captionnoclip]; + end; +end; + +procedure tcustomcaptionframe.readcaptiondistouter(reader: treader); +begin + if reader.readboolean then begin + options:= options + [cfo_captiondistouter]; + end + else begin + options:= options - [cfo_captiondistouter]; + end; +end; + +function tcustomcaptionframe.checkfocusshortcut( + var info: keyeventinfoty): boolean; +begin + result:= msegui.checkshortcut(info,fcaption,true); +end; + +procedure tcustomcaptionframe.setdisabled(const value: boolean); +begin + if (finfo.text.text <> '') and ((fs_disabled in fstate) xor value) then begin + fintf.invalidatewidget; + end; + inherited; +end; + +function tcustomcaptionframe.pointincaption(const point: pointty): boolean; +var + rect1: rectty; + int1: integer; +begin + if finfo.text.text = '' then begin + result:= false; + end + else begin + checkstate; + rect1:= finfo.dest; + with rect1 do begin + case fcaptionpos of + cp_left,cp_lefttop,cp_leftbottom: begin + int1:= fpaintrect.x - (x + cx); + if int1 > 0 then begin + inc(rect1.cx,int1); + end; + end; + cp_top,cp_topleft,cp_topright: begin + int1:= fpaintrect.y - (y + cy); + if int1 > 0 then begin + inc(rect1.cy,int1); + end; + end; + cp_right,cp_righttop,cp_rightbottom: begin + int1:= x - (fpaintrect.x + fpaintrect.cx); + if int1 > 0 then begin + dec(rect1.x,int1); + inc(rect1.cx,int1); + end; + end; + cp_bottom,cp_bottomleft,cp_bottomright: begin + int1:= y - (fpaintrect.y + fpaintrect.cy); + if int1 > 0 then begin + dec(rect1.y,int1); + inc(rect1.cy,int1); + end; + end; + end; + end; + result:= pointinrect(point,rect1); + end; +end; + +procedure tcustomcaptionframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + with twidget1(sender) do begin + if not (ow_mousetransparent in foptionswidget) then begin + if pointincaption(info.pos) then begin + include(fwidgetstate,ws_wantmousebutton); //for twidget.iswidgetclick + if cfo_captionfocus in foptions then begin + include(fwidgetstate,ws_wantmousefocus); + end; + if fs_captionhint in fstate then begin + include(fwidgetstate,ws_wantmousemove); + end; + end; + if (cfo_framerectfocus in foptions) and + pointinrect(info.pos,framerect) then begin + include(fwidgetstate,ws_wantmousefocus); + end; + end; + end; +end; + +function tcustomcaptionframe.getassistivecaption(): msestring; +begin + result:= fcaption; +end; + +procedure tcustomcaptionframe.scale(const ascale: real); +begin + if ffont <> nil then begin + ffont.scale(ascale); + end; + inherited; +end; + +function tcustomcaptionframe.needsfocuspaint: boolean; +begin + result:= (inherited needsfocuspaint or + (ftemplate <> nil) and + (fso_forcefocusrect in ftemplate.template.optionsskin)) and + not (cfo_nofocusrect in foptions) and + ((cfo_focusrect in foptions) or (ftemplate = nil) or + not (fso_nofocusrect in ftemplate.template.optionsskin)); + result:= result or (cfo_forcefocusrect in foptions); + if result then begin + if cfo_captionfocus in foptions then begin + include(fstate,fs_captionfocus); + exclude(fstate,fs_paintrectfocus); + end + else begin + include(fstate,fs_paintrectfocus); + exclude(fstate,fs_captionfocus); + end; + end; +end; + +procedure tcustomcaptionframe.settemplateinfo(const ainfo: frameinfoty); +begin + if not (frl1_font in flocalprops1) and (ainfo.capt.font <> nil) then begin + createfont; + ffont.assign(ainfo.capt.font); + if not (frl1_captiondist in flocalprops1) then begin + fcaptiondist:= ainfo.capt.captiondist; + end; + if not (frl1_captionoffset in flocalprops1) then begin + fcaptionoffset:= ainfo.capt.captionoffset; + end; + end; + inherited; +end; + +{ tcustomscrollframe } + +constructor tcustomscrollframe.create(const aintf: iscrollframe; + const scrollintf: iscrollbar); +begin + aintf.setstaticframe(true); + foptionsscroll:= defaultoptionsscroll; + fdragbuttons:= defaultdragbuttons; + inherited create(aintf); + fhorz:= getscrollbarclass(false).create(scrollintf,org_widget, + {$ifdef FPC}@{$endif}updatestate); + fvert:= getscrollbarclass(true).create(scrollintf,org_widget, + {$ifdef FPC}@{$endif}updatestate); + fvert.tag:= 1; + fvert.direction:= gd_down; +end; + +destructor tcustomscrollframe.destroy; +begin + fhorz.Free; + fvert.free; + inherited; +end; + +procedure tcustomscrollframe.checktemplate(const sender: tobject); + //true if match +begin + inherited; + fhorz.checktemplate(sender); + fvert.checktemplate(sender); +end; + +function tcustomscrollframe.getscrollbarclass(vert: boolean): framescrollbarclassty; +begin + result:= tcustomscrollbar; +end; + +procedure tcustomscrollframe.getpaintframe(var frame: framety); +begin + with frame do begin + if fs_sbleft in fstate then inc(left,fvert.width); + if fs_sbtop in fstate then inc(top,fhorz.width); + if fs_sbright in fstate then inc(right,fvert.width); + if fs_sbbottom in fstate then inc(bottom,fhorz.width); + end; +end; + +procedure tcustomscrollframe.addscrollbarwidth(var asize: sizety); +begin + with asize do begin + if fs_sbleft in fstate then inc(cx,fvert.width); + if fs_sbtop in fstate then inc(cy,fhorz.width); + if fs_sbright in fstate then inc(cx,fvert.width); + if fs_sbbottom in fstate then inc(cy,fhorz.width); + end; +end; + +procedure tcustomscrollframe.subscrollbarwidth(var asize: sizety); +begin + with asize do begin + if fs_sbleft in fstate then inc(cx,fvert.width); + if fs_sbtop in fstate then inc(cy,fhorz.width); + if fs_sbright in fstate then inc(cx,fvert.width); + if fs_sbbottom in fstate then inc(cy,fhorz.width); + end; +end; + +procedure tcustomscrollframe.mouseevent(var info: mouseeventinfoty); +begin + if not (ws_clientmousecaptured in iscrollframe(fintf).widgetstate) then begin + if fs_sbhorzon in fstate then begin + fhorz.mouseevent(info); + end; + if fs_sbverton in fstate then begin + fvert.mouseevent(info); + end; + end; +end; + +procedure tcustomscrollframe.domousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean); +var + scrollbar: tcustomscrollbar; +begin + with info do begin + if not (es_processed in eventstate) then begin + scrollbar:= nil; + if (fs_sbverton in fstate) and pointinrect(info.pos,sbvert.dim) then begin + scrollbar:= sbvert; + end + else begin + if (fs_sbhorzon in fstate) and pointinrect(info.pos,sbhorz.dim) then begin + scrollbar:= sbhorz; + end + else begin + if oscr_mousewheel in foptionsscroll then begin + if (fs_sbverton in fstate) then begin + scrollbar:= sbvert; + end + else begin + if fs_sbhorzon in fstate then begin + scrollbar:= sbhorz; + end + else begin + end; + end; + end; + end; + end; + if scrollbar <> nil then begin + scrollbar.mousewheelevent(info,pagingreversed); + end; + end; + end; +end; + +procedure tcustomscrollframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); +begin + inherited; + if fs_sbverton in fstate then begin + fvert.paint(canvas); + end; + if fs_sbhorzon in fstate then begin + fhorz.paint(canvas); + end; +end; + +procedure tcustomscrollframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + if (fs_sbverton in fstate) and fvert.wantmouseevent(info.pos) or + (fs_sbhorzon in fstate) and fhorz.wantmouseevent(info.pos) then begin + with twidget1(sender) do begin + fwidgetstate:= (fwidgetstate - [ws_mouseinclient]) + + [ws_wantmousebutton,ws_wantmousemove]; + end; + end; +end; + +procedure tcustomscrollframe.updaterects; +var + rect1: rectty; + int1,int2: integer; + + procedure checkvert; + begin + with tcustomscrollbar1(fvert) do begin + if findentstart < 0 then begin + int1:= 0; + end + else begin + if findentstart = 0 then begin + int1:= fpaintframedelta.top; + end + else begin + int1:= findentstart; + end; + end; + if findentend < 0 then begin + int2:= 0; + end + else begin + if findentend = 0 then begin + int2:= fpaintframedelta.bottom; + end + else begin + int2:= findentend; + end; + end; + end; + end; + + procedure checkhorz; + begin + with tcustomscrollbar1(fhorz) do begin + if findentstart < 0 then begin + int1:= 0; + end + else begin + if findentstart = 0 then begin + int1:= fpaintframedelta.left; + end + else begin + int1:= findentstart; + end; + end; + if findentend < 0 then begin + int2:= 0; + end + else begin + if findentend = 0 then begin + int2:= fpaintframedelta.right; + end + else begin + int2:= findentend; + end; + end; + end; + end; + +begin + int1:= 0; + int2:= 0; + fstate:= fstate - [fs_sbleft,fs_sbtop,fs_sbright,fs_sbbottom]; + if fs_sbhorzon in fstate then begin + if fs_sbhorztop in fstate then begin + include(fstate,fs_sbtop); + end + else begin + include(fstate,fs_sbbottom); + end; + end; + if fs_sbverton in fstate then begin + if fs_sbvertleft in fstate then begin + include(fstate,fs_sbleft); + end + else begin + include(fstate,fs_sbright); + end; + end; + inherited; + rect1:= inflaterect(fpaintrect,fpaintframedelta); + with rect1 do begin + if fs_sbleft in fstate then begin + checkvert; + with fvert do begin + dim:= makerect(x,y+int1,width,cy-int1-int2); + end; + end; + if fs_sbright in fstate then begin + checkvert; + with fvert do begin + dim:= makerect(x + cx-width,y+int1,width,cy-int1-int2); + end; + end; + if fs_sbtop in fstate then begin + checkhorz; + with fhorz do begin + dim:= makerect(x+int1,y,cx-int1-int2,width); + end; + end; + if fs_sbbottom in fstate then begin + checkhorz; + with fhorz do begin + dim:= makerect(x+int1,y+cy-width,cx-int1-int2,width); + end; + end; + end; +end; + +procedure tcustomscrollframe.updatevisiblescrollbars; +begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate),ord(fs_sbhorztop), + sbo_opposite in fhorz.options); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate),ord(fs_sbvertleft), + sbo_opposite in fvert.options); + if sbo_show in fhorz.options then begin + include(fstate,fs_sbhorzon); + end + else begin + if not (sbo_showauto in fhorz.options) then begin + exclude(fstate,fs_sbhorzon); + end + else begin + if fhorz.pagesize = 1 then begin + exclude(fstate,fs_sbhorzon); + end + else begin + include(fstate,fs_sbhorzon); + end; + end; + end; + if sbo_show in fvert.options then begin + include(fstate,fs_sbverton); + end + else begin + if not (sbo_showauto in fvert.options) then begin + exclude(fstate,fs_sbverton); + end + else begin + if fvert.pagesize = 1 then begin + exclude(fstate,fs_sbverton); + end + else begin + include(fstate,fs_sbverton); + end; + end; + end; +end; + +procedure tcustomscrollframe.updatestate; +var + statebefore: framestatesty; +begin + statebefore:= fstate; + updatevisiblescrollbars; + inherited; + if ({$ifdef FPC}longword{$else}longword{$endif}(statebefore) xor + {$ifdef FPC}longword{$else}longword{$endif}(fstate)) and + {$ifdef FPC}longword{$else}longword{$endif}(scrollbarframestates) <> 0 then begin + iscrollframe(fintf).getwidget.invalidatewidget; + end; +end; +{ +function tcustomscrollframe.getsbhorz: tcustomscrollbar; +begin + result:= fhorz; +end; +} +procedure tcustomscrollframe.setsbhorz(const Value: tcustomscrollbar); +begin + fhorz.assign(Value); +end; +{ +function tcustomscrollframe.getsbvert: tcustomscrollbar; +begin + result:= fvert; +end; +} +procedure tcustomscrollframe.setsbvert(const Value: tcustomscrollbar); +begin + fvert.assign(Value); +end; + +procedure tcustomscrollframe.setdragbuttons(const avalue: shiftstatesty); +begin + fdragbuttons:= avalue * buttonshiftstatesmask; +end; + +procedure tcustomscrollframe.activechanged; +begin + inherited; + fvert.activechanged; + fhorz.activechanged; +end; + +procedure tcustomscrollframe.settemplateinfo(const ainfo: frameinfoty); +begin + inherited; + if not (frl1_colorglyph in flocalprops1) and + (ainfo.ba.colorglyph <> cl_default) then begin + sbhorz.colorglyph:= ainfo.ba.colorglyph; + sbvert.colorglyph:= ainfo.ba.colorglyph; + end; + if not (frl1_colorpattern in flocalprops1) and + (ainfo.ba.colorpattern <> cl_default) then begin + sbhorz.colorpattern:= ainfo.ba.colorpattern; + sbvert.colorpattern:= ainfo.ba.colorpattern; + end; +end; + +{ tcustomstepframe } + +constructor tcustomstepframe.create(const aintf: icaptionframe; + const stepintf: istepbar); +begin + fstepintf:= stepintf; + fbuttonsize:= defaultstepbuttonsize; + fforceinvisiblebuttons:= [sk_first,sk_last]; + fcolorbutton:= cl_default; + fcolorglyph:= cl_default; + aintf.setstaticframe(true); + fmousewheel:= true; + frepeatedbutton:= -1; + inherited create(aintf); +end; + +destructor tcustomstepframe.destroy; +begin + killrepeater; + inherited; + fbuttonface.free; + fbuttonframe.free; +end; + +procedure tcustomstepframe.killrepeater; +begin + freeandnil(frepeater); + frepeatedbutton:= -1; +end; + +procedure tcustomstepframe.execute(const tag: integer; + const info: mouseeventinfoty); +begin + if @info = nil then begin + fstepintf.dostep(stepkindty(tag),0,application.lastshiftstate); + end + else begin + fstepintf.dostep(stepkindty(tag),0,info.shiftstate); + end; +end; + +procedure tcustomstepframe.getpaintframe(var frame: framety); +begin + case fbuttonpos of + sbp_right: begin + inc(frame.right,fdim.cx); + end; + sbp_top: begin + inc(frame.top,fdim.cy); + end; + sbp_left: begin + inc(frame.left,fdim.cx); + end; + sbp_bottom: begin + inc(frame.bottom,fdim.cy); + end; + end; +end; + +procedure tcustomstepframe.layoutchanged; +var + widget: twidget; +begin + widget:= icaptionframe(fintf).getwidget; + if not (csloading in widget.ComponentState) then begin + updatestate; + widget.invalidaterect(fdim,org_widget); + end; +end; + +procedure tcustomstepframe.dorepeat(const sender: tobject); +begin + with tsimpletimer(sender) do begin +// if interval < 0 then begin + if singleshot then begin + interval:= repeatrepeattime; + enabled:= true; + end; + execute(frepeatedbutton,pmouseeventinfoty(nil)^); + end; +end; + +procedure tcustomstepframe.mouseevent(var info: mouseeventinfoty); +var + int1: integer; + clickedbutton: integer; +begin + clickedbutton:= -1; + for int1:= 0 to high(fbuttons) do begin + if updatemouseshapestate(fbuttons[int1],info,nil,nil) then begin + icaptionframe(fintf).getwidget.invalidaterect( + fbuttons[int1].ca.dim,org_widget); + if info.eventkind in [ek_buttonpress,ek_buttonrelease] then begin + include(info.eventstate,es_processed); + end; + end; + if shs_clicked in fbuttons[int1].state then begin + clickedbutton:= int1; + end; + end; + if frepeatedbutton <> clickedbutton then begin + killrepeater; + if clickedbutton >= 0 then begin + frepeatedbutton:= clickedbutton; + frepeater:= tsimpletimer.create(repeatdelaytime, + {$ifdef FPC}@{$endif}dorepeat,true,[to_single]); + end; + end; +end; + +procedure tcustomstepframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); +var + int1: integer; + po1: pshapeinfoty; +begin + inherited; + for int1:= 0 to high(fbuttons) do begin + factbuttonindex:= int1; //widgetstateflags for button frame + po1:= @fbuttons[int1]; + po1^.face:= fbuttonface; + po1^.frame:= fbuttonframe; + drawtoolbutton(canvas,po1^); + end; +end; + +procedure tcustomstepframe.updatebuttonstate(const first,delta,count: integer); +var + disabled: stepkindsty; +begin + disabled:= []; + if first = 0 then begin + include(disabled,sk_left); + include(disabled,sk_up); + include(disabled,sk_first); + end; + if first+delta >= count then begin + include(disabled,sk_right); + include(disabled,sk_down); + { + if (frepeatedbutton >= 0) and + (stepkindty(frepeatedbutton) in [sk_right,sk_down]) then begin + killrepeater(); + end; + } + end; + disabledbuttons:= disabled; + if (first+delta >= count) and (first <= 0) then begin + neededbuttons:= []; +// invisiblebuttons:= [sk_right,sk_up,sk_left,sk_down]; + end + else begin + neededbuttons:= [sk_right,sk_up,sk_left,sk_down,sk_first,sk_last]; +// invisiblebuttons:= forceinvisiblebuttons; + end; +end; + +function tcustomstepframe.executestepevent(const event: stepkindty; + const stepinfo: framestepinfoty; const aindex: integer): integer; +var + steps: array[stepkindty] of integer; +begin + with stepinfo do begin + steps[sk_first]:= -bigint; + steps[sk_last]:= pagelast; + case fbuttonpos of + sbp_right,sbp_left: begin + steps[sk_right]:= 0; + if not (sk_right in disabledbuttons) then begin + steps[sk_right]:= up; + end; + steps[sk_left]:= down; + steps[sk_up]:= pagedown; + steps[sk_down]:= 0; + if not (sk_down in disabledbuttons) then begin + steps[sk_down]:= pageup; + end; + end; + sbp_top: begin + steps[sk_right]:= 0; + if not (sk_down in disabledbuttons) then begin + steps[sk_right]:= pageup; + end; + steps[sk_left]:= pagedown; + steps[sk_up]:= down; + steps[sk_down]:= 0; + if not (sk_right in disabledbuttons) then begin + steps[sk_down]:= up; + end; + end; + else begin //sbp_bottom + steps[sk_right]:= 0; + if not (sk_down in disabledbuttons) then begin + steps[sk_right]:= pageup; + end; + steps[sk_left]:= pagedown; + steps[sk_up]:= down; + steps[sk_down]:= 0; + if not (sk_right in disabledbuttons) then begin + steps[sk_down]:= up; + end; + end; + end; + end; + result:= aindex + steps[event]; +end; + +procedure tcustomstepframe.setbuttonsize(const Value: integer); +begin + if fbuttonsize <> value then begin + fbuttonsize := Value; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setbuttonpos(const Value: stepbuttonposty); +begin + if fbuttonpos <> value then begin + fbuttonpos := Value; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setbuttonsinline(const Value: boolean); +begin + if fbuttonsinline <> value then begin + fbuttonsinline := Value; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setbuttonslast(const avalue: boolean); +begin + if fbuttonslast <> avalue then begin + fbuttonslast:= avalue; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setcolorbutton(const avalue: colorty); +begin + if fcolorbutton <> avalue then begin + fcolorbutton:= avalue; + updatelayout; + icaptionframe(fintf).getwidget.invalidaterect(fdim,org_widget); + end; +end; + +procedure tcustomstepframe.setcolorglyph(const avalue: colorty); +begin + if fcolorglyph <> avalue then begin + fcolorglyph:= avalue; + updatelayout; + icaptionframe(fintf).getwidget.invalidaterect(fdim,org_widget); + end; +end; + +procedure tcustomstepframe.setdisabledbuttons(const avalue: stepkindsty); +begin + if fdisabledbuttons <> avalue then begin + fdisabledbuttons:= avalue; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setbuttonsinvisible(const avalue: stepkindsty); +begin + if fforceinvisiblebuttons <> avalue then begin + fforceinvisiblebuttons:= avalue; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setbuttonsvisible(const avalue: stepkindsty); +begin + if fforcevisiblebuttons <> avalue then begin + fforcevisiblebuttons:= avalue; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setneededbuttons(const avalue: stepkindsty); +begin + if fneededbuttons <> avalue then begin + fneededbuttons:= avalue; + layoutchanged; + end; +end; + +type + buttonarty = array[stepkindty] of stepkindty; + buttonposarty = array[boolean,stepbuttonposty] of buttonarty; +const + buttonposstep: buttonposarty = + ( + ( //not fbuttonsinline + (sk_left,sk_right,sk_up,sk_down,sk_first,sk_last), //sbp_right + (sk_left,sk_up,sk_right,sk_down,sk_first,sk_last), //sbp_top + (sk_left,sk_right,sk_up,sk_down,sk_first,sk_last), //sbp_left + (sk_up,sk_left,sk_down,sk_right,sk_first,sk_last) //sbp_bottom + ), + ( //fbuttonsinline + (sk_left,sk_right,sk_up,sk_down,sk_first,sk_last), //sbp_right + (sk_up,sk_down,sk_left,sk_right,sk_first,sk_last), //sbp_top + (sk_left,sk_right,sk_up,sk_down,sk_first,sk_last), //sbp_left + (sk_up,sk_down,sk_left,sk_right,sk_first,sk_last) //sbp_bottom + ) + ); + buttonposspin: buttonposarty = + ( + ( //not fbuttonsinline + (sk_left,sk_right,sk_up,sk_last,sk_down,sk_first), //sbp_right + (sk_left,sk_up,sk_right,sk_down,sk_last,sk_first), //sbp_top + (sk_left,sk_right,sk_up,sk_last,sk_down,sk_first), //sbp_left + (sk_up,sk_left,sk_down,sk_right,sk_last,sk_first) //sbp_bottom + ), + ( //fbuttonsinline + (sk_left,sk_right,sk_up,sk_down,sk_last,sk_first), //sbp_right + (sk_up,sk_down,sk_left,sk_right,sk_first,sk_last), //sbp_top + (sk_left,sk_right,sk_up,sk_down,sk_last,sk_first), //sbp_left + (sk_up,sk_down,sk_left,sk_right,sk_first,sk_last) //sbp_bottom + ) + ); + + images: array[stepkindty] of stockglyphty = + ( stg_arrowrightsmall,stg_arrowupsmall,stg_arrowleftsmall,stg_arrowdownsmall, + stg_arrowfirstsmall,stg_arrowlastsmall); + imagesedit: array[stepkindty] of stockglyphty = + ( stg_arrowrightsmall,stg_arrowupsmall,stg_arrowleftsmall,stg_arrowdownsmall, + stg_arrowbottomsmall,stg_arrowtopsmall); + +procedure tcustomstepframe.updatelayout; +var + buttoncount: integer; + acx,acy: integer; + ax,ay: integer; + + procedure checkbutton(button: stepkindty; vert: boolean); + begin + with fbuttons[ord(button)] do begin + if button in fdisabledbuttons then begin + include(state,shs_disabled); + end + else begin + exclude(state,shs_disabled); + end; + if (button in fforcevisiblebuttons) or + not (button in fforceinvisiblebuttons) and (button in fneededbuttons) then begin + inc(buttoncount); + ca.dim.x:= ax; + ca.dim.y:= ay; + if vert then begin + inc(ay,acy); + end + else begin + inc(ax,acx); + end; + end; + end; + end; + +var + a,b: integer; + int1: integer; + akind: stepkindty; + bo1: boolean; + bo2: boolean; + color1: colorty; + buttonpos1: ^buttonposarty; + +begin //updatelayout + if sfs_spinedit in fstepstate then begin + buttonpos1:= @buttonposspin; + end + else begin + buttonpos1:= @buttonposstep; + end; + + setlength(fbuttons,ord(high(stepkindty)) + 1); + buttoncount:= 0; + a:= 0; //compilerwarning + b:= 0; //compilerwarning + for akind:= low(stepkindty) to high(stepkindty) do begin +// if not (akind in finvisiblebuttons) or (akind in fvisiblebuttons) then begin + if (akind in fforcevisiblebuttons) or + not (akind in fforceinvisiblebuttons) and (akind in fneededbuttons) then begin + inc(buttoncount); + exclude(fbuttons[ord(akind)].state,shs_invisible); + end + else begin + include(fbuttons[ord(akind)].state,shs_invisible); + end; + end; + if buttoncount = 0 then begin + fdim.cx:= 0; + fdim.cy:= 0; + end + else begin + if not fbuttonsinline then begin + a:= (buttoncount + 1) div 2; + b:= (buttoncount + a - 1) div a; + bo2:= a > 1; + end + else begin + bo2:= false; + end; + if not bo2 then begin + a:= buttoncount; + b:= 1; + end; + if fbuttonpos in [sbp_left,sbp_right] then begin + acy:= fpaintrect.cy div a; + if acy > fbuttonsize then begin + acy:= fbuttonsize; + end; + if fbuttonslast then begin + ay:= fpaintrect.y + fpaintrect.cy - a * acy; + end + else begin + ay:= fpaintrect.y; + end; + acx:= fbuttonsize; + if fbuttonpos = sbp_left then begin + ax:= fpaintrect.x - acx * b; + end + else begin + ax:= fpaintrect.x + fpaintrect.cx; + end; + end + else begin + acx:= fpaintrect.cx div a; + if acx > fbuttonsize then begin + acx:= fbuttonsize; + end; + if fbuttonslast then begin + ax:= fpaintrect.x; + end + else begin + ax:= fpaintrect.x + fpaintrect.cx - a * acx; + end; + acy:= fbuttonsize; + if fbuttonpos = sbp_top then begin + ay:= fpaintrect.y - acy * b; + end + else begin + ay:= fpaintrect.y + fpaintrect.cy; + end; + end; + color1:= fcolorbutton; + if (color1 = cl_parent) or (color1 = cl_default) then begin + color1:= icaptionframe(fintf).getwidget.actualcolor; + end; + for int1:= 0 to high(fbuttons) do begin + with fbuttons[int1] do begin + ca.imagelist:= stockobjects.glyphs; + if sfs_spinedit in fstepstate then begin + ca.imagenr:= ord(imagesedit[stepkindty(int1)]); + end + else begin + ca.imagenr:= ord(images[stepkindty(int1)]); + end; + imagenrdisabled:= -2; + color:= color1; + ca.colorglyph:= fcolorglyph; + tag:= int1; + doexecute:= {$ifdef FPC}@{$endif}execute; + ca.dim.cx:= acx; + ca.dim.cy:= acy; + end; + end; + fdim.x:= ax; + fdim.y:= ay; + bo1:= fbuttonpos in [sbp_left,sbp_right]; + buttoncount:= 0; + for akind:= low(stepkindty) to high(stepkindty) do begin + if bo2 then begin + if not odd(buttoncount) and (akind <> low(stepkindty)) then begin + if bo1 then begin + ax:= fdim.x; + end + else begin + ay:= fdim.y; + end; + end; + checkbutton(buttonpos1^[fbuttonsinline][fbuttonpos][akind],not odd(buttoncount) xor bo1); + end + else begin + checkbutton(buttonpos1^[fbuttonsinline][fbuttonpos][akind],bo1); + end; + end; + if bo1 then begin //left or right + fdim.cx:= acx * b; + fdim.cy:= acy * a; + end + else begin + fdim.cx:= acx * a; + fdim.cy:= acy * b; + end; + end; + if (buttoncount > 0) or (fneededbuttons <> []) then begin + include(fstepstate,sfs_canstep); + end + else begin + exclude(fstepstate,sfs_canstep); + end; +end; + +procedure tcustomstepframe.updaterects; +begin + updatelayout; + inherited; + updatelayout; +end; + +procedure tcustomstepframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + if pointinrect(info.pos,fdim) then begin + with twidget1(sender) do begin + fwidgetstate:= fwidgetstate + [ws_wantmousebutton,ws_wantmousemove]; + end; + end; +end; + +const + stepdirstep: array[stepbuttonposty,boolean] of stepkindty = + //down //up + ((sk_down, sk_up), //sbp_right + (sk_right, sk_left), //sbp_top + (sk_down, sk_up), //sbp_left + (sk_right, sk_left)); //sbp_bottom + stepdirspin: array[boolean] of stepkindty = (sk_down,sk_up); + +procedure tcustomstepframe.domousewheelevent(var info: mousewheeleventinfoty); +var + sk1: stepkindty; +begin + if fmousewheel and (info.wheel <> mw_none) and + not (es_transientfor in info.eventstate)then begin + if sfs_spinedit in fstepstate then begin + sk1:= stepdirspin[info.wheel = mw_up]; + end + else begin + if fneededbuttons = [] then begin + exit; + end; + sk1:= stepdirstep[fbuttonpos][info.wheel = mw_up] + end; + if canstep and fstepintf.dostep(sk1,info.delta,info.shiftstate) then begin + include(info.eventstate,es_processed); + end; + end; +end; + +procedure tcustomstepframe.createbuttonface; +begin + if fbuttonface = nil then begin + fbuttonface:= tface.create(iface(fintf.getwidget)); + end; +end; + +procedure tcustomstepframe.createbuttonframe; +begin + if fbuttonframe = nil then begin + fbuttonframe:= tframe.create(iframe(self)); + end; +end; + +function tcustomstepframe.getbuttonface: tface; +begin + fintf.getwidget.getoptionalobject(fbuttonface, + {$ifdef FPC}@{$endif}createbuttonface); + result:= fbuttonface; +end; + +procedure tcustomstepframe.setbuttonface(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fbuttonface, + {$ifdef FPC}@{$endif}createbuttonface); + fintf.invalidatewidget; +end; + +function tcustomstepframe.getbuttonframe: tframe; +begin + fintf.getwidget.getoptionalobject(fbuttonframe, + {$ifdef FPC}@{$endif}createbuttonframe); + result:= fbuttonframe; +end; + +procedure tcustomstepframe.setbuttonframe(const avalue: tframe); +var + int1: integer; +begin + fintf.getwidget.setoptionalobject(avalue,fbuttonframe, + {$ifdef FPC}@{$endif}createbuttonframe); + if fbuttonframe = nil then begin + for int1:= 0 to high(fbuttons) do begin + with fbuttons[int1] do begin + state:= state - [shs_flat,shs_noanimation]; + end; + end; + end; + fintf.invalidatewidget; +end; + +procedure tcustomstepframe.checktemplate(const sender: tobject); +begin + inherited; + if fbuttonface <> nil then begin + fbuttonface.checktemplate(sender); + end; + if fbuttonframe <> nil then begin + fbuttonframe.checktemplate(sender); + end; +end; + +procedure tcustomstepframe.setframeinstance(instance: tcustomframe); +begin + fbuttonframe:= tframe(instance); +end; + +procedure tcustomstepframe.setstaticframe(value: boolean); +begin + //dummy +end; + +function tcustomstepframe.getstaticframe: boolean; +begin + result:= false; +end; + +function tcustomstepframe.getwidgetrect: rectty; +begin + result:= nullrect; +end; + +function tcustomstepframe.getcomponentstate: tcomponentstate; +begin + result:= fintf.getwidget.componentstate; +end; + +function tcustomstepframe.getmsecomponentstate: msecomponentstatesty; +begin + result:= fintf.getwidget.msecomponentstate; +end; + +procedure tcustomstepframe.scrollwidgets(const dist: pointty); +begin + //dummy +end; + +procedure tcustomstepframe.clientrectchanged; +begin + fintf.invalidatewidget; +end; + +procedure tcustomstepframe.invalidate; +begin + fintf.getwidget.invalidaterect(fdim,org_widget); +end; + +procedure tcustomstepframe.invalidatewidget; +begin + fintf.invalidatewidget; +end; + +procedure tcustomstepframe.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + fintf.getwidget.invalidaterect(rect,org,noclip); +end; + +function tcustomstepframe.getwidget: twidget; +begin + result:= fintf.getwidget +end; + +function tcustomstepframe.getframestateflags: framestateflagsty; +begin + result:= shapestatetoframestate(factbuttonindex,fbuttons); +end; + +function tcustomstepframe.canstep: boolean; +begin + result:= sfs_canstep in fstepstate; +end; + +{ tscrollboxscrollbar } + +constructor tscrollboxscrollbar.create(intf: iscrollbar; org: originty; + ondimchanged: proceventty); +begin + inherited; + foptions:= defaultscrollboxscrollbaroptions; +end; + +{ tthumbtrackscrollbar } + +constructor tthumbtrackscrollbar.create(intf: iscrollbar; org: originty; + ondimchanged: proceventty); +begin + inherited; + foptions:= defaultthumbtrackscrollbaroptions; +end; + +{ tthumbtracknopagesizescrollbar } + +constructor tthumbtracknopagesizescrollbar.create(intf: iscrollbar; org: originty; + ondimchanged: proceventty); +begin + inherited; + foptions:= defaultthumbtrackscrollbaroptions; +end; + +{ tcustomscrollboxframe } + +constructor tcustomscrollboxframe.create(const aintf: iscrollframe; + const owner: twidget); +begin + fzoom.re:= 1; + fzoom.im:= 1; + fzoomwidthstep:= 1; + fzoomheightstep:= 1; +// fzoomwheelsensitivity:= 1; + fowner:= owner; + inherited create(aintf,iscrollbox(self)); + fstate:= fstate+ [fs_canclientextendx,fs_canclientextendy]; + initinnerframe; + internalupdatestate; +// options:= defaultscrolloptions; +end; + +procedure tcustomscrollboxframe.initinnerframe; +begin + fi.innerframe.left:= 2; + fi.innerframe.top:= 2; + fi.innerframe.right:= 2; + fi.innerframe.bottom:= 2; +end; + +procedure tcustomscrollboxframe.clientrecttoscrollbar(const rect: rectty); +var + int1: integer; +begin + inc(fscrolling); + with rect do begin + if fstate * [fs_sbhorzon,fs_sbhorzfix] = [fs_sbhorzon] then begin + if cx = 0 then begin + fhorz.pagesize:= 1; + end + else begin + fhorz.pagesize:= fpaintrect.cx/cx; + end; + int1:= cx - fpaintrect.cx; + if int1 = 0 then begin + fhorz.value:= 0; + end + else begin + fhorz.value:= ({fpaintrect.x}-x)/int1; + end; + end; + if fstate * [fs_sbverton,fs_sbvertfix] = [fs_sbverton] then begin + if cy = 0 then begin + fvert.pagesize:= 1; + end + else begin + fvert.pagesize:= fpaintrect.cy/cy; + end; + int1:= cy - fpaintrect.cy; + if int1 = 0 then begin + fvert.value:= 0; + end + else begin + fvert.value:= ({fpaintrect.y}-y)/int1; + end; + end; + end; + dec(fscrolling); +end; + +procedure tcustomscrollboxframe.scrollpostoclientpos(var aclientrect: rectty); +begin + with aclientrect do begin + x:= - round(fhorz.value * (cx-fpaintrect.cx)); + y:= - round(fvert.value * (cy-fpaintrect.cy)); +// inc(x,fpaintrect.x); +// inc(y,fpaintrect.y); + end; +end; + +procedure tcustomscrollboxframe.updatevisiblescrollbars; +begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_sbhorztop),sbo_opposite in fhorz.options); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_sbvertleft),sbo_opposite in fvert.options); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_sbhorzon),sbo_show in fhorz.options); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_sbverton),sbo_show in fvert.options); +end; + +function tcustomscrollboxframe.getwidget: twidget; +begin + result:= fowner; +end; + +procedure tcustomscrollboxframe.calcclientrect(var aclientrect: rectty); + +var + asize: sizety; + statebefore: framestatesty; + int1: integer; + +begin + updatevisiblescrollbars; + updaterects; + inc(fscrolling); + int1:= 0; + repeat + statebefore:= fstate; + asize:= twidget1(fowner).calcminscrollsize; + with asize do begin + if fclientsize.cx <> 0 then begin + cx:= fclientsize.cx; + end; + if fclientsize.cy <> 0 then begin + cy:= fclientsize.cy; + end; + if sbo_showauto in fhorz.options then begin + if cx > fpaintrect.cx then begin + include(fstate,fs_sbhorzon); + end + else begin + exclude(fstate,fs_sbhorzon); + fhorz.value:= 0; + end; + end; + if sbo_showauto in fvert.options then begin + if cy > fpaintrect.cy then begin + include(fstate,fs_sbverton); + end + else begin + exclude(fstate,fs_sbverton); + fvert.value:= 0; + end; + end; + end; + if state = statebefore then begin + break; + end; + updaterects; + inc(int1); + until int1 > 16; //emergency brake + dec(fscrolling); + + aclientrect.size:= asize; + with aclientrect.size do begin + if cx < fpaintrect.cx then begin + cx:= fpaintrect.cx; + end; + if cy < fpaintrect.cy then begin + cy:= fpaintrect.cy; + end; + int1:= fpaintrect.cx {+ fpaintrect.x} - aclientrect.cx - aclientrect.x; + if int1 > 0 then begin + inc(aclientrect.x,int1); + end; + int1:= fpaintrect.cy {+ fpaintrect.y} - aclientrect.cy - aclientrect.y; + if int1 > 0 then begin + inc(aclientrect.y,int1); + end; + end; + clientrecttoscrollbar(aclientrect); +end; + +procedure tcustomscrollboxframe.updateclientrect; +var + rect1: rectty; +begin + rect1:= fclientrect; + calcclientrect(fclientrect); + finnerclientrect:= deflaterect(fclientrect,fi.innerframe); + twidget1(fowner).scroll(subpoint(fclientrect.pos,rect1.pos)); + if (rect1.cx <> fclientrect.cx) or (rect1.cy <> fclientrect.cy) then begin + twidget1(fowner).clientrectchanged; + end; +end; + +function tcustomscrollboxframe.getclientpos: pointty; +begin + checkstate; + result:= fclientrect.pos; +end; + +procedure tcustomscrollboxframe.setclientpos(apos: pointty); +var + pt1: pointty; +begin + if apos.x + fclientrect.cx < fpaintrect.cx then begin + apos.x:= fpaintrect.cx-fclientrect.cx; + end; + if apos.y + fclientrect.cy < fpaintrect.cy then begin + apos.y:= fpaintrect.cy-fclientrect.cy; + end; + if apos.x > 0 then begin + apos.x:= 0; + end; + if apos.y > 0 then begin + apos.y:= 0; + end; + pt1:= subpoint(apos,fclientrect.pos); +// twidget1(fowner).scroll(pt1); + fclientrect.pos:= apos; + addpoint1(finnerclientrect.pos,pt1); + twidget1(fowner).scroll(pt1); +end; + +procedure tcustomscrollboxframe.setscrollpos(apos: pointty); +begin + setclientpos(apos); + clientrecttoscrollbar(fclientrect); +end; + +procedure tcustomscrollboxframe.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +var + rect1: rectty; +begin + if fscrolling = 0 then begin + if event = sbe_setvalue{valuechanged} then begin + rect1:= fclientrect; + scrollpostoclientpos(rect1); + setclientpos(rect1.pos); +{ + po1:= fclientrect.pos; + scrollpostoclientpos(fclientrect); + po1:= subpoint(fclientrect.pos,po1); + addpoint1(finnerclientrect.pos,po1); + twidget1(fowner).scroll(po1); +} + end; + end; +end; + +procedure tcustomscrollboxframe.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if (oscr_key in foptionsscroll) and not (es_processed in info.eventstate) and + (((shiftstate * shiftstatesmask) - [ss_ctrl]) = []) then begin + include(eventstate,es_processed); + case key of + key_pageup: begin + if ss_ctrl in shiftstate then begin + fvert.value:= 0; + end + else begin + fvert.pagedown; + end; + end; + key_pagedown: begin + if ss_ctrl in shiftstate then begin + fvert.value:= 1; + end + else begin + fvert.pageup; + end; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + if ss_ctrl in shiftstate then begin + include(eventstate,es_processed); + case key of + key_right: begin + fhorz.stepup; + end; + key_left: begin + fhorz.stepdown; + end; + key_down: begin + fvert.stepup; + end; + key_up: begin + fvert.stepdown; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end; + end; + end; +end; + +function tcustomscrollboxframe.translatecolor(const acolor: colorty): colorty; +begin + result:= fowner.translatecolor(acolor); +end; + +procedure tcustomscrollboxframe.invalidaterect(const rect: rectty; + const org: originty; const noclip: boolean = false); +begin + fowner.invalidaterect(rect,org,noclip); +end; + +function tcustomscrollboxframe.getscrollsize: sizety; +begin + checkstate; + result:= fclientrect.size; +end; + +procedure tcustomscrollboxframe.setclientsize(const avalue: sizety); +begin + if (fclientsize.cx <> avalue.cx) or (fclientsize.cy <> avalue.cy) then begin + fclientsize:= avalue; + if fclientsize.cx < 0 then begin + fclientsize.cx:= 0; + end; + if fclientsize.cy < 0 then begin + fclientsize.cy:= 0; + end; + internalupdatestate; + end; +end; + +procedure tcustomscrollboxframe.setclientwidth(const avalue: integer); +begin + setclientsize(ms(avalue,fclientsize.cy)); +end; + +procedure tcustomscrollboxframe.setclientheight(const avalue: integer); +begin + setclientsize(ms(fclientsize.cx,avalue)); +end; + +procedure tcustomscrollboxframe.setclientsizemin(const avalue: sizety); +begin + if (fclientsizemin.cx <> avalue.cx) or + (fclientsizemin.cy <> avalue.cy) then begin + fclientsizemin:= avalue; + if fclientsizemin.cx < 0 then begin + fclientsizemin.cx:= 0; + end; + if fclientsizemin.cy < 0 then begin + fclientsizemin.cy:= 0; + end; + internalupdatestate; + end; +end; + +procedure tcustomscrollboxframe.setclientwidthmin(const avalue: integer); +begin + setclientsizemin(ms(avalue,fclientsizemin.cy)); +end; + +procedure tcustomscrollboxframe.setclientheightmin(const avalue: integer); +begin + setclientsizemin(ms(fclientsizemin.cx,avalue)); +end; + +procedure tcustomscrollboxframe.showrect(const arect: rectty; + const bottomright: boolean); +var + scrollvalue: pointty; +// po1: pointty; + int1: integer; + + procedure adjuststart; + begin + int1:= fclientrect.x + scrollvalue.x + arect.x; + if int1 < 0 then begin + dec(scrollvalue.x,int1); + end; + int1:= fclientrect.x + scrollvalue.x; + if int1 > 0 then begin + dec(scrollvalue.x,int1); + end; + int1:= fclientrect.y + scrollvalue.y + arect.y; + if int1 < 0 then begin + dec(scrollvalue.y,int1); + end; + int1:= fclientrect.y + scrollvalue.y; + if int1 > 0 then begin + dec(scrollvalue.y,int1); + end; + end; + + procedure adjustend; + begin + int1:= fclientrect.x + scrollvalue.x + arect.x + arect.cx - fpaintrect.cx; + if int1 > 0 then begin + dec(scrollvalue.x,int1); + end; + int1:= fclientrect.x + scrollvalue.x + fclientrect.cx - fpaintrect.cx; + if int1 < 0 then begin + dec(scrollvalue.x,int1); + end; + int1:= fclientrect.y + scrollvalue.y + arect.y + arect.cy - fpaintrect.cy; + if int1 > 0 then begin + dec(scrollvalue.y,int1); + end; + int1:= fclientrect.y + scrollvalue.y + fclientrect.cy - fpaintrect.cy; + if int1 < 0 then begin + dec(scrollvalue.y,int1); + end; + end; + +begin + scrollvalue:= nullpoint; + checkstate; +// po1:= addpoint(fclientrect.pos,arect.pos); + if bottomright then begin + adjuststart; + adjustend; + end + else begin + adjustend; + adjuststart; + end; + if (scrollvalue.y <> 0) or (scrollvalue.x <> 0) then begin + addpoint1(fclientrect.pos,scrollvalue); + addpoint1(finnerclientrect.pos,scrollvalue); + twidget1(fowner).scroll(scrollvalue); + clientrecttoscrollbar(fclientrect); + end; +end; + +function tcustomscrollboxframe.getscrollbarclass( + vert: boolean): framescrollbarclassty; +begin + result:= tscrollboxscrollbar; +end; + +procedure tcustomscrollboxframe.setsbhorz(const avalue: tscrollboxscrollbar); +begin + inherited setsbhorz(avalue); +end; + +function tcustomscrollboxframe.getsbhorz: tscrollboxscrollbar; +begin + result:= tscrollboxscrollbar(inherited sbhorz); +end; + +procedure tcustomscrollboxframe.setsbvert(const avalue: tscrollboxscrollbar); +begin + inherited setsbvert(avalue); +end; + +function tcustomscrollboxframe.getsbvert: tscrollboxscrollbar; +begin + result:= tscrollboxscrollbar(inherited sbvert); +end; + +procedure tcustomscrollboxframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + with twidget1(sender) do begin + if fdragging then begin + fwidgetstate:= fwidgetstate + [ws_wantmousemove,ws_wantmousebutton]; + end + else begin + if (oscr_drag in foptionsscroll) and isdragstart(sender,info) then begin + include(fwidgetstate,ws_wantmousebutton); + end; + end; + end; +end; + +procedure tcustomscrollboxframe.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +var + po1: pointty; +begin + with info do begin + if not (es_processed in eventstate) then begin + po1:= translatewidgetpoint(pos,sender,fowner); + if fdragging then begin + case eventkind of + ek_mouseleave,ek_buttonrelease: begin + application.cursorshape:= cr_default; + fowner.releasemouse; + fdragging:= false; + include(eventstate,es_processed); + end; + ek_mousemove: begin + showrect(makerect(subpoint(subpoint(fpickpos,po1),fpickref), + fclientrect.size),false); + include(eventstate,es_processed); + end; + end; + end + else begin + if isdragstart(sender,info) then begin + fowner.capturemouse; + fpickpos:= po1; + fpickref:= fclientrect.pos; + application.cursorshape:= cr_sizeall; + fdragging:= true; + include(eventstate,es_processed); + end; + end; + end; + end; +end; + +function tcustomscrollboxframe.isdragstart(const sender: twidget; + const info: mouseeventinfoty): boolean; +var + ss1: shiftstatesty; +begin + with info do begin + ss1:= (shiftstate*buttonshiftstatesmask)*fdragbuttons; + result:= (oscr_drag in foptionsscroll) and + (eventkind = ek_buttonpress) and (ss1 <> []) and + pointinrect(translatewidgetpoint(pos,sender,fowner),fpaintrect) and + ((fclientrect.cx <> fpaintrect.cx) or + (fclientrect.cy <> fpaintrect.cy)); + end; + if result and not ((ss1 = [ss_middle]) or (sender = fowner)) then begin + twidget1(sender).updatemousestate(info); + result:= not (ws_wantmousebutton in twidget1(sender).fwidgetstate); + end; +end; + +procedure tcustomscrollboxframe.checkminscrollsize(var asize: sizety); +begin + inherited; + if (clientwidthmin > 0) and (clientwidthmin > asize.cx) then begin + asize.cx:= clientwidthmin; + end; + if (clientheightmin > 0) and (clientheightmin > asize.cy) then begin + asize.cy:= clientheightmin; + end; +end; + +procedure tcustomscrollboxframe.checkminclientsize(var asize: sizety); +begin + if clientwidth <> 0 then begin + asize.cx:= clientwidth; + end; + if clientheight <> 0 then begin + asize.cy:= clientheight; + end; + inherited; +end; + +procedure tcustomscrollboxframe.setzoom1(const avalue: complexty); +var + size1: sizety; +begin + fzoom:= avalue; + if fzoom.re < 1 then begin + fzoom.re:= 1; + end; + if fzoom.im < 1 then begin + fzoom.im:= 1; + end; + checkstate; + size1:= nullsize; + with fpaintframedelta do begin + if avalue.re > 1 then begin + size1.cx:= round((fpaintrect.cx+left+right)*avalue.re); + //do not use scrollbarwidth + end; + if avalue.im > 1 then begin + size1.cy:= round((fpaintrect.cy+top+bottom)*avalue.im); + //do not use scrollbarwidth + end; + end; + fclientsize:= size1; +end; + +procedure tcustomscrollboxframe.setzoom(const avalue: complexty); +begin + setzoom1(avalue); + internalupdatestate; +end; + +procedure tcustomscrollboxframe.setzoomwidth(const avalue: real); +begin + setzoom(makecomplex(avalue,fzoom.im)); +end; + +procedure tcustomscrollboxframe.setzoomheight(const avalue: real); +begin + setzoom(makecomplex(fzoom.re,avalue)); +end; + +function tcustomscrollboxframe.getscrollpos_x: integer; +begin + result:= getclientpos.x; +end; + +procedure tcustomscrollboxframe.setscrollpos_x(const avalue: integer); +begin + setscrollpos(makepoint(avalue,getclientpos.y)); +end; + +function tcustomscrollboxframe.getscrollpos_y: integer; +begin + result:= getclientpos.y; +end; + +procedure tcustomscrollboxframe.setscrollpos_y(const avalue: integer); +begin + setscrollpos(makepoint(getclientpos.x,avalue)); +end; + +procedure tcustomscrollboxframe.domousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean); +var + size1: sizety; + pt1,pt2: pointty; + co1: complexty; + bo1: boolean; + ma1: shiftstatesty; + rea1: real; + fra1: framety; +begin + with info do begin + if not (es_processed in eventstate) then begin + if (oscr_mousewheel in foptionsscroll) and (ss_ctrl in shiftstate) and + (foptionsscroll*[oscr_zoomwidth,oscr_zoomheight] <> []) then begin + ma1:= shiftstatesmask - [ss_ctrl]; + if foptionsscroll*[oscr_zoomwidth,oscr_zoomheight] = + [oscr_zoomwidth,oscr_zoomheight] then begin + ma1:= ma1 - [ss_alt,ss_shift]; + end; + if shiftstate * ma1 = [] then begin + include(eventstate,es_processed); + size1:= fclientrect.size; + co1:= fzoom; + bo1:= false; + rea1:= 1 + (abs(delta) - application.mousewheeldeltamin)* + fzoomwheelsensitivity*application.mousewheeldeltamin; + if (fzoomwidthstep <> 1) and (fzoomwidthstep > 0) and + (oscr_zoomwidth in foptionsscroll) and + not (ss_shift in shiftstate) then begin + bo1:= true; + if wheel = mw_down then begin + co1.re:= zoomwidth / (fzoomwidthstep*rea1); + end + else begin + co1.re:= zoomwidth * (fzoomwidthstep*rea1); + end; + end; + if (fzoomheightstep <> 1) and (fzoomheightstep > 0) and + (oscr_zoomheight in foptionsscroll) and + not (ss_alt in shiftstate) then begin + bo1:= true; + if wheel = mw_down then begin + co1.im:= zoomheight / (fzoomheightstep*rea1); + end + else begin + co1.im:= zoomheight * (fzoomheightstep*rea1); + end; + end; + if bo1 then begin + setzoom1(co1); + pt1:= fclientrect.pos; + fra1:= iscrollframe(fintf).getzoomrefframe; + with fra1 do begin + size1.cx:= size1.cx - left - right; + size1.cy:= size1.cy - top - bottom; + if size1.cx > 0 then begin + pt1.x:= info.pos.x - fpaintrect.x - left - + round((info.pos.x - fpaintrect.x - fclientrect.x - left)* + (fclientsize.cx-left-right)/size1.cx); + end; + if size1.cy > 0 then begin + pt1.y:= info.pos.y - fpaintrect.y - top - + round((info.pos.y - fpaintrect.y - fclientrect.y - top)* + (fclientsize.cy-top-bottom)/size1.cy); + end; + end; + { + pt1:= nullpoint; + with pt2 do begin + x:= info.pos.x-fpaintrect.x; + if x < 0 then begin + x:= 0; + end; + if x > fpaintrect.cx then begin + x:= fpaintrect.cx; + end; + x:= x - fclientrect.x; + y:= info.pos.y-fpaintrect.y; + if y < 0 then begin + y:= 0; + end; + if y > fpaintrect.cy then begin + y:= fpaintrect.cy; + end; + y:= y - fclientrect.y; + end; + if (size1.cx > 0) and (fclientsize.cx > 0) then begin + pt1.x:= -round(pt2.x*((fclientsize.cx/size1.cx)-1.0)); + end; + if (size1.cy > 0) and (fclientsize.cy > 0) then begin + pt1.y:= -round(pt2.y*((fclientsize.cy/size1.cy)-1.0)); + end; +// setscrollpos(addpoint(fclientrect.pos,pt1)); +} + pt2:= fclientrect.pos; + fclientrect.pos:= pt1; + if fclientrect.x > 0 then begin + fclientrect.x:= 0; + end; + if fclientrect.y > 0 then begin + fclientrect.y:= 0; + end; + fowner.scrollwidgets(subpoint(fclientrect.pos,pt2)); + internalupdatestate; + end; + end; + end + else begin + inherited; + end; + end; + end; +end; + +procedure tcustomscrollboxframe.readzoomwidthstep(reader: treader); +begin + zoomwidthstep:= reader.readfloat; +end; + +procedure tcustomscrollboxframe.writezoomwidthstep(writer: twriter); +begin + writer.writefloat(zoomwidthstep); +end; + +procedure tcustomscrollboxframe.readzoomheightstep(reader: treader); +begin + zoomheightstep:= reader.readfloat; +end; + +procedure tcustomscrollboxframe.writezoomheightstep(writer: twriter); +begin + writer.writefloat(zoomheightstep); +end; + +procedure tcustomscrollboxframe.readzoomwheelsensitivity(reader: treader); +begin + zoomwheelsensitivity:= reader.readfloat; +end; + +procedure tcustomscrollboxframe.writezoomwheelsensitivity(writer: twriter); +begin + writer.writefloat(zoomwheelsensitivity); +end; + +procedure tcustomscrollboxframe.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('zoomwidthstep',@readzoomwidthstep,@writezoomwidthstep, + (filer.ancestor = nil) and (fzoomwidthstep <> 1) or + (filer.ancestor <> nil) and + (tcustomscrollboxframe(filer.ancestor).fzoomwidthstep <> fzoomwidthstep)); + filer.defineproperty('zoomheightstep',@readzoomheightstep,@writezoomheightstep, + (filer.ancestor = nil) and (fzoomheightstep <> 1) or + (filer.ancestor <> nil) and + (tcustomscrollboxframe(filer.ancestor).fzoomheightstep <> fzoomheightstep)); + filer.defineproperty('zoomwheelsensitivity', + @readzoomwheelsensitivity,@writezoomwheelsensitivity, + (filer.ancestor = nil) and (fzoomwheelsensitivity <> 0) or + (filer.ancestor <> nil) and + (tcustomscrollboxframe(filer.ancestor).fzoomwheelsensitivity <> + fzoomwheelsensitivity)); +end; + +{ tcustomautoscrollframe } + +constructor tcustomautoscrollframe.create(const aintf: iscrollframe; + const owner: twidget; const autoscrollintf: iautoscrollframe); +begin + fintf1:= autoscrollintf; + inherited create(aintf,owner); +end; + +function tcustomautoscrollframe.getscrollpos: pointty; +begin + result:= fintf1.getscrollrect.pos; +end; + +procedure tcustomautoscrollframe.setscrollpos(const avalue: pointty); +var + rect1: rectty; +begin + rect1:= fintf1.getscrollrect; + if (rect1.x <> avalue.x) or (rect1.y <> avalue.y) then begin + rect1.pos:= avalue; + with rect1 do begin + if x + cx < fpaintrect.cx then begin + x:= fpaintrect.cx - rect1 .cx; + end; + if x > 0{fpaintrect.x} then begin + x:= 0{fpaintrect.x}; + end; + if y + cy < fpaintrect.cy then begin + y:= fpaintrect.cy - cy; + end; + if y > 0{fpaintrect.y} then begin + y:= 0{fpaintrect.y}; + end; + end; + clientrecttoscrollbar(rect1); + fintf1.setscrollrect(rect1); + end; +end; + +function tcustomautoscrollframe.getscrollpos_x: integer; +begin + result:= getscrollpos.x; +end; + +procedure tcustomautoscrollframe.setscrollpos_x(const avalue: integer); +begin + setscrollpos(makepoint(avalue,getscrollpos.y)); +end; + +function tcustomautoscrollframe.getscrollpos_y: integer; +begin + result:= getscrollpos.y; +end; + +procedure tcustomautoscrollframe.setscrollpos_y(const avalue: integer); +begin + setscrollpos(makepoint(getscrollpos.x,avalue)); +end; + +procedure tcustomautoscrollframe.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +var + rect1: rectty; +begin + if fscrolling = 0 then begin + if event = sbe_valuechanged then begin + rect1:= fintf1.getscrollrect; + scrollpostoclientpos(rect1); + fintf1.setscrollrect(rect1); + end + else begin + fintf1.scrollevent(sender,event); + end; + end; +end; + +procedure tcustomautoscrollframe.updaterects; +begin + inherited; + fclientrect.pos:= nullpoint; + fclientrect.size:= fpaintrect.size; + finnerclientrect:= deflaterect(fclientrect,fi.innerframe); +end; + +procedure tcustomautoscrollframe.updateclientrect; +var + rect1: rectty; +begin + rect1:= fintf1.getscrollrect; + calcclientrect(rect1); + fintf1.setscrollrect(rect1); +end; + + +{ tactionwidget } + +procedure tactionwidget.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + if (fpopupmenu <> nil) and not ((es_child in mouseinfo.eventstate) and + (mo_noinsert in fpopupmenu.options)) then begin + tpopupmenu.additems(amenu,self,mouseinfo,fpopupmenu); + amenu.menu.caption:= fpopupmenu.menu.caption; //for tassistivehandler + end; +end; + +procedure tactionwidget.dopopup(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); + procedure doparent(const after: boolean); + var + widget1: twidget; + bo1: boolean; + begin + if (fpopupmenu = nil) or not (mo_stopinsert in fpopupmenu.options) then begin + widget1:= fparentwidget; + while widget1 <> nil do begin + if widget1 is tactionwidget then begin + translateclientpoint1(mouseinfo.pos,self,widget1); + bo1:= not (es_child in mouseinfo.eventstate); + include(mouseinfo.eventstate,es_child); + try + if after then begin + tactionwidget(widget1).doafterpopupmenu(amenu,mouseinfo); + end + else begin + tactionwidget(widget1).dopopup(amenu,mouseinfo); + end; + finally + if bo1 then begin + exclude(mouseinfo.eventstate,es_child); + end; + translateclientpoint1(mouseinfo.pos,widget1,self); + end; + break; + end; + widget1:= twidget1(widget1).fparentwidget; + end; + end; + end; //doparent() + +var + menu1: tpopupmenu; + +begin + menu1:= amenu; + try + updatepopupmenu(amenu,mouseinfo); + if canevent(tmethod(fonpopup)) then begin + fonpopup(self,amenu,mouseinfo); + end; + if not (es_parent in mouseinfo.eventstate) then begin + doparent(false); + if (amenu <> nil) and + (mouseinfo.eventstate * [es_processed,es_child] = []) then begin + amenu.show(self,mouseinfo); + doafterpopupmenu(amenu,mouseinfo); + doparent(true); + end; + end; + finally + if not (es_child in mouseinfo.eventstate) then begin + if amenu <> menu1 then begin + freetransientmenu(tcustommenu(menu1)); //if amenu overwritten + end; + freetransientmenu(tcustommenu(amenu)); + end; + end; +end; + +procedure tactionwidget.mouseevent(var info: mouseeventinfoty); +begin + if canevent(tmethod(fonmouseevent)) then begin + fonmouseevent(self,info); + end; + inherited; +end; + +procedure tactionwidget.clientmouseevent(var info: mouseeventinfoty); +var + dummy: tpopupmenu; + po1: pointty; +begin + if canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,info); + end; + inherited; + with info do begin + if (eventkind = ek_buttonrelease) and (ws_rclicked in fwidgetstate) and + not (csdesigning in componentstate) and + (eventstate * [es_processed,es_child] = []) and + (button = mb_right) then begin + dummy:= nil; + po1:= pos; + dopopup(dummy,info); + pos:= po1; //no mousemove by change of popup pos + end; + end; +end; + +procedure tactionwidget.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + if canevent(tmethod(fonchildmouseevent)) then begin + fonchildmouseevent(sender,info); + end; + inherited; +end; + +procedure tactionwidget.domousewheelevent(var info: mousewheeleventinfoty); +begin + if canevent(tmethod(fonmousewheelevent)) then begin + fonmousewheelevent(self,info); + end; + inherited; +end; + +procedure tactionwidget.dobeforepaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; +// canvas.font:= getfont; + if canevent(tmethod(fonbeforepaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonbeforepaint(self,canvas); + canvas.remove(pt1); + end; +end; + +procedure tactionwidget.doonpaintbackground(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaintbackground)) then begin + fonpaintbackground(self,canvas); + end; +end; + +procedure tactionwidget.doonpaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaint)) then begin + fonpaint(self,canvas); + end; +end; + +procedure tactionwidget.doafterpaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; + if canevent(tmethod(fonafterpaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonafterpaint(self,canvas); + canvas.remove(pt1); + end; +end; + +procedure tactionwidget.doonkeydown(var info: keyeventinfoty); +begin + if not (ws1_onkeydowncalled in fwidgetstate1) then begin + include(fwidgetstate1,ws1_onkeydowncalled); + if canevent(tmethod(fonkeydown)) then begin + fonkeydown(self,info); + end; + end; +end; + +procedure tactionwidget.dokeydown(var info: keyeventinfoty); +var + dummy: tpopupmenu; + mouseinfo: mouseeventinfoty; +begin + if not (es_processed in info.eventstate) then begin + doonkeydown(info); + end; + with info do begin + if (key = key_menu) and (shiftstate = []) and + not(es_processed in eventstate) then begin + dummy:= nil; + fillchar(mouseinfo,sizeof(mouseinfo),0); + with mouseinfo do begin + with application.caret do begin + if active then begin + mouseinfo.pos:= pos; + mouseinfo.pos.y:= mouseinfo.pos.y + height; + end + else begin + mouseinfo.pos:= rectcenter(clippedpaintrect); + end; + end; + getpopuppos(pos); + button:= mb_none; + end; + dummy:= nil; + dopopup(dummy,mouseinfo); + if not (es_processed in mouseinfo.eventstate) then begin + inherited; + end; + end + else begin + inherited; + end; + end; +end; + +procedure tactionwidget.dokeyup(var info: keyeventinfoty); +begin + if not (es_processed in info.eventstate) and canevent(tmethod(fonkeyup)) then begin + fonkeyup(self,info); + end; + inherited; +end; + +procedure tactionwidget.showhint(const aid: int32; var info: hintinfoty); +begin + inherited; + if canevent(tmethod(fonshowhint)) then begin + fonshowhint(self,info); + end; +end; + +procedure tactionwidget.internalcreateframe; +begin + tcaptionframe.create(iscrollframe(self)); +end; + +procedure tactionwidget.enabledchanged; +begin + inherited; + if (fframe <> nil) and + (tcustomcaptionframe(fframe).finfo.text.text <> '') then begin + invalidatewidget; + end; +end; + +function tactionwidget.getframe: tcaptionframe; +begin + result:= tcaptionframe(inherited getframe); +end; + +procedure tactionwidget.setframe(const value: tcaptionframe); +begin + inherited setframe(value); +end; + +function tactionwidget.getface: tface; +begin + result:= tface(inherited getface); +end; + +procedure tactionwidget.setface(const Value: tface); +begin + inherited setface(value); +end; + +procedure tactionwidget.setpopupmenu(const Value: tpopupmenu); +begin + setlinkedvar(value,tmsecomponent(fpopupmenu)); +end; + +procedure tactionwidget.poschanged; +begin + inherited; + if canevent(tmethod(fonmove)) then begin + fonmove(self); + end; +end; + +procedure tactionwidget.sizechanged; +begin + inherited; + if canevent(tmethod(fonresize)) then begin + fonresize(self); + end; +end; + +procedure tactionwidget.doloaded; +begin + inherited; + if canevent(tmethod(fonloaded)) then begin + fonloaded(self); + end; +end; + +procedure tactionwidget.doenter; +begin + inherited; + if canevent(tmethod(fonenter)) then begin + fonenter(self); + end; +end; + +procedure tactionwidget.doexit; +begin + inherited; + if canevent(tmethod(fonexit)) then begin + fonexit(self); + end; +end; + +function tactionwidget.canclose(const newfocus: twidget): boolean; +begin + result:= inherited canclose(newfocus); + if result and assigned(fonclosequery) then begin + fonclosequery(self,result); + end; +end; + +procedure tactionwidget.dofocus; +begin + inherited; + if canevent(tmethod(fonfocus)) then begin + fonfocus(self); + end; +end; + +procedure tactionwidget.dodefocus; +begin + inherited; + if canevent(tmethod(fondefocus)) then begin + fondefocus(self); + end; +end; + +procedure tactionwidget.dofocuschanged(const oldwidget: twidget; + const newwidget: twidget); +begin + inherited; + if canevent(tmethod(fonfocusedwidgetchanged)) and + (checkdescendent(oldwidget) or checkdescendent(newwidget)) then begin + fonfocusedwidgetchanged(oldwidget,newwidget); + end; +end; + +procedure tactionwidget.doactivate; +begin + inherited; + if canevent(tmethod(fonactivate)) and + ((ow1_modalcallonactivate in foptionswidget1) or + not (tws_modalcalling in twindow1(window).fstate)) then begin + fonactivate(self); + end; +end; + +procedure tactionwidget.dodeactivate; +begin + inherited; + if canevent(tmethod(fondeactivate)) and + ((ow1_modalcallondeactivate in foptionswidget1) or + not (tws_modalcalling in twindow1(window).fstate)) then begin + fondeactivate(self); + end; +end; + +procedure tactionwidget.dohide; +begin + if canevent(tmethod(fonhide)) then begin + fonhide(self); + end; + inherited; +// include(fwidgetstate,ws_hidden); +// exclude(fwidgetstate,ws_showed); +end; + +procedure tactionwidget.doshow; +begin +// inherited; + if canevent(tmethod(fonshow)) then begin + fonshow(self); + end; + inherited; +// include(fwidgetstate,ws_showed); +// exclude(fwidgetstate,ws_hidden); +end; + + +procedure tactionwidget.getpopuppos(var apos: pointty); +begin + //dummy +end; + +procedure tactionwidget.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + if not (es_processed in info.eventstate) and canevent(tmethod(fonshortcut)) then begin + fonshortcut(self,info,sender); + end; + if (fpopupmenu <> nil) and (sender <> nil) //no broadcast + and not(csdesigning in componentstate) then begin + fpopupmenu.doshortcut(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tactionwidget.receiveevent(const event: tobjectevent); +begin + if canevent(tmethod(fonevent)) then begin + fonevent(self,event); + end; + inherited; +end; + +procedure tactionwidget.componentevent(const event: tcomponentevent); +begin + if canevent(tmethod(foncomponentevent)) then begin + foncomponentevent(self,event); + end; + inherited; +end; + +procedure tactionwidget.doasyncevent(var atag: integer); +begin + if canevent(tmethod(fonasyncevent)) then begin + fonasyncevent(self,atag); + end; + inherited; +end; + +procedure tactionwidget.doafterpopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + //dummy +end; + +{ ttoplevelwidget } + +constructor ttoplevelwidget.create(aowner: tcomponent); +begin + inherited; + visible:= false; + foptionswidget:= defaultoptionstoplevelwidget; + optionsskin:= defaultcontainerskinoptions; +// fcolor:= cl_background; +end; + +{ tcaptionwidget } + +function tcaptionwidget.getcaption: msestring; +begin + result:= fcaption; +end; + +procedure tcaptionwidget.setcaption(const Value: msestring); +begin + fcaption := Value; + if (fwindow <> nil) and (fwindow.winid <> 0) then begin + gui_setwindowcaption(fwindow.winid,fcaption); + end; +end; + +procedure tcaptionwidget.windowcreated; +begin + inherited; + if fcaption <> '' then begin + caption:= fcaption; //set windowcaption + end; +end; + +function tcaptionwidget.getassistivecaption(): msestring; +begin + result:= getcaption(); +end; + +{ tscrollface } + +procedure tscrollface.internalpaint(const canvas: tcanvas; const rect: rectty); +begin + inherited internalpaint(canvas,fintf.getclientrect); +end; + +{ tscrollingwidgetnwr } + +constructor tscrollingwidgetnwr.create(aowner: tcomponent); +begin + inherited; + include(fwidgetstate1,ws1_designactive); + foptionswidget:= defaultoptionswidgetmousewheel; + optionsskin:= defaultcontainerskinoptions; + internalcreateframe; + setstaticframe(true); +end; + +procedure tscrollingwidgetnwr.internalcreateframe; +begin + tscrollboxframe.create(iscrollframe(self),self); +end; + +function tscrollingwidgetnwr.getframe: tscrollboxframe; +begin + result:= tscrollboxframe(pointer(inherited getframe)); +end; + +procedure tscrollingwidgetnwr.setframe(const Value: tscrollboxframe); +begin + inherited setframe(tcaptionframe(pointer(value))); +end; + +procedure tscrollingwidgetnwr.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) then begin + tscrollframe(fframe).mouseevent(info); + end; +end; + +procedure tscrollingwidgetnwr.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +//var +// po1: pointty; +begin + frame.childmouseevent(sender,info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tscrollingwidgetnwr.domousewheelevent(var info: mousewheeleventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) then begin + tscrollframe(fframe).domousewheelevent(info,false); + end; +end; + +procedure tscrollingwidgetnwr.doscroll(const dist: pointty); +begin + inherited; + if canevent(tmethod(fonscroll)) then begin + fonscroll(self,dist); + end; +end; + +procedure tscrollingwidgetnwr.doscrolled(const dist: pointty); +begin + inherited; + if canevent(tmethod(fonscroll)) then begin + fonscroll(self,dist); + end; +end; + +procedure tscrollingwidgetnwr.widgetregionchanged(const sender: twidget); +begin + inherited; + if ((sender = nil) or + not (ws1_anchorsizing in twidget1(sender).fwidgetstate1)) and + not (ws_destroying in fwidgetstate) and + (componentstate*[csloading,csdestroying] = []) then begin + tcustomscrollboxframe(fframe).updateclientrect; + end; +// else begin +// tscrollboxframe(fframe).updatestate; ww +// end; +end; + +procedure tscrollingwidgetnwr.writestate(writer: twriter); +begin + frame.sbhorz.value:= 0; + frame.sbvert.value:= 0; + inherited; +end; + +procedure tscrollingwidgetnwr.internalcreateface; +begin + tscrollface.create(twidget(self)); +end; + +procedure tscrollingwidgetnwr.sizechanged; +begin + inherited; + tcustomscrollboxframe(fframe).updatestate; +// tcustomscrollboxframe(fframe).updateclientrect; + //set endresult of autosizing +end; + +procedure tscrollingwidgetnwr.minscrollsizechanged; +begin + tcustomscrollboxframe(fframe).updatestate; +end; + +function tscrollingwidgetnwr.calcminscrollsize: sizety; +begin + result:= inherited calcminscrollsize; + if result.cx < fminclientsize.cx then begin + result.cx:= fminclientsize.cx; + end; + if result.cy < fminclientsize.cy then begin + result.cy:= fminclientsize.cy; + end; +// result:= inherited calcminscrollsize; + if checkcanevent(owner,tmethod(foncalcminscrollsize)) then begin + foncalcminscrollsize(self,result); + end; +end; + +procedure tscrollingwidgetnwr.setclientsize(const asize: sizety); +begin + with tcustomscrollboxframe(fframe) do begin + fminclientsize:= fminminclientsize; + if (asize.cx > fclientrect.cx) then begin + fminclientsize.cx:= asize.cx; + end; + if (asize.cy > fclientrect.cy) then begin + fminclientsize.cy:= asize.cy; + end; + if (fminclientsize.cx > 0) or (fminclientsize.cy > 0) then begin + updatestate; + fminclientsize:= fminminclientsize; + end; + end; +end; + +procedure tscrollingwidgetnwr.dolayout(const sender: twidget); +begin + if canevent(tmethod(fonlayout)) then begin + fonlayout(self); + end + else begin + inherited; + end; +end; + +procedure tscrollingwidgetnwr.loaded; +begin + inherited; + if canevent(tmethod(fonlayout)) then begin + postchildscaled; + end; +end; + +procedure tscrollingwidgetnwr.dofontheightdelta(var delta: integer); +begin + if canevent(tmethod(fonfontheightdelta)) then begin + fonfontheightdelta(self,delta); + end; + inherited; +end; + +procedure tscrollingwidgetnwr.clampinview(const arect: rectty; const bottomright: boolean); +begin + updateroot; + frame.showrect(removerect(arect,clientpos),bottomright); + inherited; +// frame.showrect(removerect(arect,clientwidgetpos)); +// frame.showrect(arect); +end; + +function tscrollingwidgetnwr.maxclientsize: sizety; +begin + result:= makesize(bigint,bigint); +end; +{ +procedure tscrollingwidgetnwr.setclientpos(const avalue: pointty); +begin + frame.showrect(makerect(avalue,paintsize),false); +end; +} +procedure tscrollingwidgetnwr.readonchildscaled(reader: treader); +begin + onlayout:= notifyeventty(readmethod(reader)); +end; + +procedure tscrollingwidgetnwr.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('onchildscaled',{$ifdef FPC}@{$endif}readonchildscaled, + nil,false) +end; + +{ tscrollbarwidget } + +constructor tscrollbarwidget.create(aowner: tcomponent); +begin + inherited; + internalcreateframe; +end; + +procedure tscrollbarwidget.internalcreateframe; +begin + tscrollframe.create(self,iscrollbar(self)); +end; + +function tscrollbarwidget.getframe: tscrollframe; +begin + result:= tscrollframe(pointer(inherited getframe)); +end; + +procedure tscrollbarwidget.setframe(const Value: tscrollframe); +begin + inherited setframe(tcaptionframe(pointer(value))); +end; + +procedure tscrollbarwidget.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +begin + //dummy +end; + +procedure tscrollbarwidget.mouseevent(var info: mouseeventinfoty); +begin + tscrollframe(fframe).mouseevent(info); + inherited; +end; + +{ tpopupwidget } + +function tpopupwidget.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags(); + if ownswindow then begin + result:= result + [asf_popup]; + end; +end; + +constructor tpopupwidget.create(aowner: tcomponent; transientfor: twindow); +begin + inherited create(aowner); + if transientfor <> nil then begin + getobjectlinker.setlinkedvar(ievent(self),transientfor,tlinkedobject(ftransientfor)); + end; + window.localshortcuts:= true; +end; + +function tpopupwidget.internalshow(const modallevel: modallevelty; + const transientfor: pwindow; + const windowevent,transientforshow: boolean): modalresultty; +begin + if transientfor^ = nil then begin + result:= inherited internalshow(modallevel,@ftransientfor,windowevent, + transientforshow); + end + else begin + result:= inherited internalshow(modallevel,transientfor,windowevent, + transientforshow); + end; +end; + +procedure tpopupwidget.updatewindowinfo(var info: windowinfoty); +begin + with info do begin + options:= [wo_popup]; + transientfor:= ftransientfor; + end; +end; + +{ tcustomhintwidget } + +constructor tcustomhintwidget.create(const aowner: tcomponent; + const atransientfor: twindow; + var info: hintinfoty; const sender: tobject); +var + rect1,rect2: rectty; +begin + inherited create(aowner,atransientfor); + foptionswidget:= defaultoptionshintwidget; + if atransientfor = nil then begin + include(foptionswidget,ow_ultratop); + end; + internalcreateframe; + fframe.levelo:= 1; + fframe.framei_left:= 1; + fframe.framei_top:= 1; + fframe.framei_right:= 1; + fframe.framei_bottom:= 1; + color:= cl_infobackground; + rect2:= deflaterect(application.workarea(atransientfor),fframe.innerframe); + rect1:= textrect(getcanvas,info.caption,rect2,[tf_wordbreak], + stockobjects.fonts[stf_hint]); + addsize1(rect1.size,fframe.innerframedim); +// inc(rect1.cx,fframe.innerframedim.cx); +// inc(rect1.cy,fframe.innerframedim.cy); + widgetrect:= placepopuprect(atransientfor,info.posrect,info.placement, + rect1.size); +end; + +{ thintwidget} + +constructor thintwidget.create(const aowner: tcomponent; + const atransientfor: twindow; var info: hintinfoty; + const sender: tobject); +begin + fcaption:= info.caption; + inherited; +end; + +procedure thintwidget.dopaintforeground(const canvas: tcanvas); +begin + inherited; + drawtext(canvas,fcaption,innerclientrect,[tf_wordbreak], + stockobjects.fonts[stf_hint]); +end; + +{ tmessagewidget } + +constructor tmessagewidget.create(const aowner: tcomponent; + const apopuptransient: boolean; const ahasaction: boolean); +begin + fpopuptransient:= apopuptransient; + fhasaction:= ahasaction; + inherited create(aowner); + if apopuptransient then begin + color:= cl_active; +//exit; + createframe; + with tcustomcaptionframe(fframe) do begin + colorframe:= cl_black; + framewidth:= 2; + captionpos:= cp_top; + end; + end; +end; + +procedure tmessagewidget.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if not((key = key_escape) and (shiftstate = []) and window.close) then begin + inherited; + end; + end; +end; + +procedure tmessagewidget.updatewindowinfo(var info: windowinfoty); +begin + inherited; + info.options:= [wo_message]; + if fpopuptransient then begin + include(info.options,wo_popup); + end; + window.localshortcuts:= true; +end; + +function tmessagewidget.getcaption: msestring; +begin + if fframe <> nil then begin + result:= tcustomcaptionframe(fframe).caption; + end + else begin + result:= inherited getcaption; + end; +end; + +procedure tmessagewidget.setcaption(const Value: msestring); +begin + if fframe <> nil then begin + tcustomcaptionframe(fframe).caption:= value; + end + else begin + inherited; + end; +end; + +procedure tmessagewidget.internalcreateframe; +begin + tcustomcaptionframe.create(iscrollframe(self)); +end; + +function tmessagewidget.canclose(const newfocus: twidget): boolean; +begin + result:= not fhasaction or (window.modalresult <> mr_windowclosed); +end; + +{ tcustomthumbtrackscrollframe } + +function tcustomthumbtrackscrollframe.getscrollbarclass(vert: boolean): framescrollbarclassty; +begin + result:= tthumbtrackscrollbar; +end; + +{ tscrollframe } + +function tscrollframe.getscrollbarclass(vert: boolean): framescrollbarclassty; +begin + result:= tscrollbar; +end; + +procedure tscrollframe.setsbhorz(const avalue: tscrollbar); +begin + inherited setsbhorz(avalue); +end; + +function tscrollframe.getsbhorz: tscrollbar; +begin + result:= tscrollbar(inherited sbhorz); +end; + +procedure tscrollframe.setsbvert(const avalue: tscrollbar); +begin + inherited setsbvert(avalue); +end; + +function tscrollframe.getsbvert: tscrollbar; +begin + result:= tscrollbar(inherited sbvert); +end; + +{ tsimplewidget } + +constructor tsimplewidget.create(aowner: tcomponent); +begin + inherited; + exclude(fwidgetstate,ws_visible); +end; + +{ timpressedcaptionframe } + +constructor timpressedcaptionframe.create(const aintf: icaptionframe); +begin + inherited; + fi.levelo:= -2; + internalupdatestate(); +end; + +{ ttaborderoverride } + +constructor ttaborderoverride.create(const aowner: twidget); +begin + fowner:= aowner; + inherited create(); +end; + +destructor ttaborderoverride.destroy(); +begin +// clear(); + inherited; +end; + +procedure ttaborderoverride.clear(); +var + p1,pe: pdoublewidgetty; +begin + p1:= pointer(fitems); + if p1 <> nil then begin + pe:= p1 + high(fitems); + while p1 <= pe do begin + setlinkedvar(nil,tmsecomponent(p1^.a)); + setlinkedvar(nil,tmsecomponent(p1^.b)); + inc(p1); + end; + fitems:= nil; + end; +end; + +procedure ttaborderoverride.readitems(reader: treader); +begin + clear(); + fwidgetnames:= nil; + reader.readlistbegin(); + while not reader.endoflist() do begin + additem(fwidgetnames,reader.readstring()); + end; + reader.readlistend(); +end; + +procedure ttaborderoverride.writeitems(writer: twriter); +var + p1,pe: pdoublewidgetty; +begin + writer.writelistbegin(); + p1:= pointer(fitems); + pe:= p1 + length(fitems); + while p1 < pe do begin + writer.writestring(ownernamepath(writer.root,p1^.a)); + writer.writestring(ownernamepath(writer.root,p1^.b)); + inc(p1); + end; + writer.writelistend(); +end; + +procedure ttaborderoverride.defineproperties(filer: tfiler); +var + b1: boolean; + p1,p2,pe: pdoublewidgetty; +begin + inherited; + b1:= fitems <> nil; + if (filer is twriter) and (filer.ancestor <> nil) then begin + with ttaborderoverride(filer.ancestor) do begin + b1:= high(fitems) <> high(self.fitems); + if not b1 then begin + p1:= pointer(fitems); + pe:= p1 + length(fitems); + p2:= pointer(self.fitems); + while p1 < pe do begin + if ((p1^.a = nil) <> (p2^.a = nil)) or + ((p1^.b = nil) <> (p2^.b = nil)) or + (p1^.a <> nil) and (p1^.a.name <> p2^.a.name) or + (p1^.b <> nil) and (p1^.b.name <> p2^.b.name) then begin + //todo: better check for changed owner + b1:= true; + break; + end; + inc(p1); + inc(p2); + end; + end; + end; + end; + filer.defineproperty('items',@readitems,@writeitems,b1); +end; + +procedure ttaborderoverride.objevent(const sender: iobjectlink; + const event: objecteventty); +var + p1,pe: pdoublewidgetty; + w1: tobject; +begin + if event = oe_destroyed then begin + if csdestroying in fowner.componentstate then begin + fitems:= nil; + end + else begin + w1:= sender.getinstance(); + p1:= pointer(fitems); + if p1 <> nil then begin + pe:= p1 + high(fitems); + while p1 <= pe do begin + if p1^.a = w1 then begin + p1^.a:= nil; + end; + if p1^.b = w1 then begin + p1^.b:= nil; + end; + inc(p1); + end; + end; + end; + end; + inherited; +end; + +procedure ttaborderoverride.endread(const reader: treader); +var + p1,pe: pstring; + compa,compb: tcomponent; +begin + if (fwidgetnames <> nil) then begin + clear; + p1:= pointer(fwidgetnames); + pe:= p1+high(fwidgetnames); + while p1 < pe do begin + compa:= findsubcomponentbynamepath(p1^,reader.root); + inc(p1); + compb:= findsubcomponentbynamepath(p1^,reader.root); + inc(p1); + if ((compa = nil) or (compa is twidget)) and + ((compb = nil) or (compb is twidget)) then begin + add(twidget(compa),twidget(compb)); + end; + end; + fwidgetnames:= nil; + end; +end; + +function ttaborderoverride.nexttaborder(sender: twidget; + const down: boolean): twidget; +var + ar1: doublewidgetarty; + p1,pe: pdoublewidgetty; +label + restartlab,endlab; +begin + result:= nil; + if fitems <> nil then begin + ar1:= copy(fitems); + while true do begin +restartlab: + if down then begin + pe:= pointer(ar1); + p1:= pe+high(ar1); + while p1 >= pe do begin + if p1^.b = sender then begin + result:= p1^.a; + if (result <> nil) and not result.canfocus() then begin + p1^.b:= nil; //avoid circles + sender:= result; + goto restartlab; //next try + end + else begin + goto endlab; + end; + end; + dec(p1); + end; + goto endlab; //no match + end + else begin + p1:= pointer(ar1); + pe:= p1+high(ar1); + while p1 <= pe do begin + if p1^.a = sender then begin + result:= p1^.b; + if (result <> nil) and not result.canfocus() then begin + p1^.a:= nil; //avoid circles + sender:= result; + goto restartlab; //next try + end + else begin + goto endlab; + end; + end; + inc(p1); + end; + goto endlab; //no match + end; + end; + end; +endlab: + if (result <> nil) and not result.canfocus() then begin + result:= result.nexttaborder(down) + end; + if fowner.canevent(tmethod(fontaborder)) then begin + fontaborder(self,sender,down,result); + end; +end; + +procedure ttaborderoverride.add(const aa: twidget; const ab: twidget); +begin + if (aa <> nil) or (ab <> nil) then begin + setlength(fitems,high(fitems)+2); + with fitems[high(fitems)] do begin + a:= aa; + b:= ab; + if aa <> nil then begin + getobjectlinker.link(iobjectlink(self),ievent(aa)); + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msewindowwidget.pas b/mseide-msegui/lib/common/widgets/msewindowwidget.pas new file mode 100644 index 0000000..7294428 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msewindowwidget.pas @@ -0,0 +1,568 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + 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. +} +unit msewindowwidget; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses,msegui,msetypes,msegraphutils,mseguiintf,msewidgets, + msegraphics,msesimplewidgets,mseevent,msemenus,mseguiglob,msetimer; + +type + tcustomwindowwidget = class; + + windowwidgeteventty = procedure(const sender: tcustomwindowwidget) of object; + windowwidgetpainteventty = procedure(const sender: tcustomwindowwidget; + const aupdaterect: rectty) of object; + createwinideventty = procedure(const sender: tcustomwindowwidget; + const aparent: winidty; + const awidgetrect: rectty; var aid: winidty) of object; + destroywinideventty = procedure(const sender: tcustomwindowwidget; + const aid: winidty) of object; + clientwindowoptionty = (cwo_trackboundsimmediate,cwo_highrestimer,cwo_noleak); + clientwindowoptionsty = set of clientwindowoptionty; + + tcustomwindowwidget = class(teventwidget) + private + fclientwindow: windowty; + fchildrect: rectty; + fviewport: rectty; + faspect: real; + foncreatewinid: createwinideventty; + fondestroywinid: destroywinideventty; + fonclientpaint: windowwidgetpainteventty; + fonclientrectchanged: windowwidgeteventty; + fondestroy: windowwidgeteventty; + fonloaded: windowwidgeteventty; + fonwindowmouseevent: mouseeventty; + fwindowmouseentered: boolean; + fonwindowmousewheelevent: mousewheeleventty; + frenderstep: real; + frendertimestampus: longword; + frendered: boolean; + frendercount: longword; +// ftimerrendercount: longword; + ftimer: tsimpletimer; + ffpsmax: real; + foptionsclient: clientwindowoptionsty; + function getclientwinid: winidty; + procedure windowscrolled(const sender: tobject); + function getchildrect: rectty; + function getviewport: rectty; + procedure setfpsmax(const avalue: real); + procedure setoptionsclient(const avalue: clientwindowoptionsty); + protected + procedure resetrenderstep; + procedure dotimer(const sender: tobject); + procedure checktimer; + procedure checkwindowrect; + procedure checkclientwinid; + procedure checkclientvisible; + procedure clientrectchanged; override; +// procedure poschanged; override; + procedure visiblechanged; override; + procedure winiddestroyed(const awinid: winidty); + procedure docreatewinid(const aparent: winidty; const awidgetrect: rectty; + var aid: winidty); virtual; + procedure dodestroywinid; virtual; + procedure doclientrectchanged; virtual; + function canclientpaint: boolean; virtual; + procedure doclientpaint(const aupdaterect: rectty); virtual; + procedure doonpaint(const acanvas: tcanvas); override; + procedure doloaded; override; + procedure updateviewport(const arect: rectty); virtual; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + + procedure clienttoviewport(var apoint: pointty; const arect: rectty); + procedure viewporttoclient(var apoint: pointty; const arect: rectty); + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property rendertimestampus: longword read frendertimestampus; //us + property renderstep: real read frenderstep; + //elapsed secods since last paint + function createchildwindow: winidty; + function hasclientwinid: boolean; + procedure invalidateviewpointrect(arect: rectty); + property clientwinid: winidty read getclientwinid; + procedure destroyclientwindow; + property childrect: rectty read getchildrect; + property viewport: rectty read getviewport; + property aspect: real read faspect; + property fpsmax: real read ffpsmax write setfpsmax; //default -1 -> none + //0 -> as fast as possible + property optionsclient: clientwindowoptionsty read foptionsclient + write setoptionsclient default []; + property oncreatewinid: createwinideventty read foncreatewinid + write foncreatewinid; + property ondestroywinid: destroywinideventty read fondestroywinid + write fondestroywinid; + property onclientpaint: windowwidgetpainteventty read fonclientpaint + write fonclientpaint; + property onclientrectchanged: windowwidgeteventty read fonclientrectchanged + write fonclientrectchanged; + property ondestroy: windowwidgeteventty read fondestroy write fondestroy; + property ondloaded: windowwidgeteventty read fonloaded write fonloaded; + property onwindowmouseevent: mouseeventty read fonwindowmouseevent + write fonwindowmouseevent; //origin viewport.pos + property onwindowmousewheelevent: mousewheeleventty read + fonwindowmousewheelevent write fonwindowmousewheelevent; + end; + + twindowwidget = class(tcustomwindowwidget) + published + property optionswidget; + property optionsskin; + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property color; + property cursor; + property frame; + property face; + property anchors; + property taborder; + property hint; + property popupmenu; + property onpopup; + property onshowhint; + property enabled; + property visible; + property fpsmax; + property optionsclient; + property oncreatewinid; + property ondestroywinid; + property onclientpaint; + property onclientrectchanged; + property onwindowmouseevent; + property onwindowmousewheelevent; + property ondestroy; + end; + +implementation +uses + msesysutils; +type + twindow1 = class(twindow); + +{ tcustomwindowwidget } + +constructor tcustomwindowwidget.create(aowner: tcomponent); +begin + ffpsmax:= -1; + application.registeronwiniddestroyed({$ifdef FPC}@{$endif}winiddestroyed); + inherited; + ftimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}dotimer,false,[to_leak]); +end; + +destructor tcustomwindowwidget.destroy; +begin + if fwindow <> nil then begin + fwindow.unregisteronscroll({$ifdef FPC}@{$endif}windowscrolled); + end; + if candestroyevent(tmethod(fondestroy)) then begin + fondestroy(self); + end; + application.unregisteronwiniddestroyed({$ifdef FPC}@{$endif}winiddestroyed); + destroyclientwindow; + inherited; + ftimer.free; +end; + +function tcustomwindowwidget.getclientwinid: winidty; +begin + checkclientwinid; + result:= fclientwindow.id; +end; + +function tcustomwindowwidget.createchildwindow: winidty; +var + options1: internalwindowoptionsty; + rect1: rectty; +begin + rect1:= innerwidgetrect; + addpoint1(rect1.pos,rootpos); + fillchar(options1,sizeof(options1),0); + options1.parent:= window.winid; + guierror(gui_createwindow(rect1,options1,fclientwindow),self); + result:= fclientwindow.id; +end; + +procedure tcustomwindowwidget.checkclientwinid; +var +// options1: internalwindowoptionsty; + rect1: rectty; +begin + if fclientwindow.id = 0 then begin + rect1:= innerwidgetrect; + addpoint1(rect1.pos,rootpos); + docreatewinid(window.winid,rect1,fclientwindow.id); + if fclientwindow.id = 0 then begin + createchildwindow; + end; + if fwindow <> nil then begin + fwindow.registeronscroll({$ifdef FPC}@{$endif}windowscrolled); + end; + checkclientvisible; + end; +end; + +procedure tcustomwindowwidget.destroyclientwindow; +begin + if fclientwindow.id <> 0 then begin + dodestroywinid; + end; + gui_destroywindow(fclientwindow); + fillchar(fclientwindow,sizeof(fclientwindow),0); + fchildrect:= nullrect; +end; + +procedure tcustomwindowwidget.doclientrectchanged; +begin + if canevent(tmethod(fonclientrectchanged)) then begin + fonclientrectchanged(self); + end; +end; + +procedure tcustomwindowwidget.checkwindowrect; +var + rect1,rect2{,rect3}: rectty; + bo1: boolean; +begin + if fclientwindow.id <> 0 then begin + bo1:= false; + rect1:= innerwidgetrect; + rect2:= intersectrect(rect1,clippedpaintrect); + rect1.x:= rect1.x - rect2.x; + rect1.y:= rect2.y + rect2.cy - rect1.y - rect1.cy; + addpoint1(rect2.pos,rootpos); + if not rectisequal(rect2,fchildrect) then begin + bo1:= true; + fchildrect:= rect2; + gui_setembeddedwindowrect(fclientwindow.id,rect2); + end; + if not rectisequal(rect1,fviewport) then begin + bo1:= true; + if rect1.cy = 0 then begin + faspect:= 1; + end + else begin + faspect:= -rect1.cx/rect1.cy; + end; + fviewport:= rect1; + updateviewport(fviewport); + end; + if bo1 then begin + doclientrectchanged; + end; + end; +end; + +procedure tcustomwindowwidget.clientrectchanged; +begin + inherited; + if cwo_trackboundsimmediate in foptionsclient then begin + checkwindowrect; + end; + { + if canevent(tmethod(fonclientrectchanged)) then begin + fonclientrectchanged(self); + end; + } +end; +{ +procedure tcustomwindowwidget.poschanged; +begin +// checkwindowrect; + inherited; +end; +} + +procedure tcustomwindowwidget.resetrenderstep; +begin + frenderstep:= 0; + frendered:= false; + frendercount:= 0; +// ftimerrendercount:= 0; + ftimer.enabled:= false; +end; + +procedure tcustomwindowwidget.visiblechanged; +begin + resetrenderstep; + inherited; + checkclientvisible; + checktimer; +end; + +procedure tcustomwindowwidget.doloaded; +begin + resetrenderstep; + checkclientvisible; + checktimer; + inherited; + if canevent(tmethod(fonloaded)) then begin + fonloaded(self); + end; +end; + +procedure tcustomwindowwidget.checkclientvisible; +begin + if fclientwindow.id <> 0 then begin + if isvisible and parentisvisible then begin + gui_showwindow(fclientwindow.id); + end + else begin + gui_hidewindow(fclientwindow.id); + end; + end; +end; + +procedure tcustomwindowwidget.winiddestroyed(const awinid: winidty); +begin + if awinid = fclientwindow.id then begin + fclientwindow.id:= 0; + end; + if (fwindow <> nil) and (fwindow.haswinid) and + (fwindow.winid = awinid) then begin + destroyclientwindow; + end; +end; + +procedure tcustomwindowwidget.docreatewinid(const aparent: winidty; + const awidgetrect: rectty; var aid: winidty); +begin + resetrenderstep; + checktimer; + if canevent(tmethod(foncreatewinid)) then begin + foncreatewinid(self,aparent,awidgetrect,aid); + end; +end; + +procedure tcustomwindowwidget.dodestroywinid; +begin + resetrenderstep; + if canevent(tmethod(fondestroywinid)) then begin + fondestroywinid(self,fclientwindow.id); + end; +end; + +function tcustomwindowwidget.canclientpaint: boolean; +begin + result:= assigned(fonclientpaint); +end; + +procedure tcustomwindowwidget.doclientpaint(const aupdaterect: rectty); +begin + if canevent(tmethod(fonclientpaint)) then begin + fonclientpaint(self,aupdaterect); + end; +end; + +procedure tcustomwindowwidget.doonpaint(const acanvas: tcanvas); +var + lwo1: longword; + rect1: rectty; +begin + if not (csdesigning in componentstate) and canclientpaint then begin + checkclientwinid; + checkwindowrect; + lwo1:= timestamp; + if frendered then begin + frenderstep:= (lwo1-frendertimestampus)/1000000; + end; + frendertimestampus:= lwo1; + frendered:= true; + inc(frendercount); + if acanvas <> nil then begin + rect1:= acanvas.clipbox; + rect1.y:= rect1.y+rect1.cy; + clienttoviewport(rect1.pos,innerclientrect); + doclientpaint(rect1); + end + else begin + doclientpaint(makerect(nullpoint,fviewport.size)); //called from timer + end; + end; + if acanvas <> nil then begin + ftimer.interval:= ftimer.interval; + inherited; + end; +end; + +function tcustomwindowwidget.hasclientwinid: boolean; +begin + result:= fclientwindow.id <> 0; +end; + +function tcustomwindowwidget.getchildrect: rectty; +begin + checkwindowrect; + result:= fchildrect; +end; + +function tcustomwindowwidget.getviewport: rectty; +begin + checkwindowrect; + result:= fviewport; +end; + +procedure tcustomwindowwidget.updateviewport(const arect: rectty); +begin + //dummy +end; + +procedure tcustomwindowwidget.clienttoviewport(var apoint: pointty; + const arect: rectty); +begin + apoint.x:= apoint.x - arect.x; + apoint.y:= arect.cy - apoint.y + arect.y; +end; + +procedure tcustomwindowwidget.viewporttoclient(var apoint: pointty; + const arect: rectty); +begin + apoint.x:= apoint.x + arect.x; + apoint.y:= arect.cy + arect.y - apoint.y; +end; + + +procedure tcustomwindowwidget.clientmouseevent(var info: mouseeventinfoty); + procedure enterevent(const aenter: boolean); + var + info1: mouseeventinfoty; + begin + if aenter xor fwindowmouseentered then begin + fwindowmouseentered:= aenter; + info1:= info; + if aenter then begin + info1.eventkind:= ek_clientmouseenter; + end + else begin + info1.eventkind:= ek_clientmouseleave; + end; + end; + info1.pos:= nullpoint; + fonwindowmouseevent(self,info1); + end; +var + rect1: rectty; +begin + inherited; + if canevent(tmethod(fonwindowmouseevent)) then begin + if info.eventkind in mouseposevents then begin + checkwindowrect; + rect1:= innerclientrect; + if pointinrect(info.pos,rect1) or + (ws_clientmousecaptured in fwidgetstate) then begin + enterevent(true); + clienttoviewport(info.pos,rect1); + if not (es_processed in info.eventstate) then begin + try + fonwindowmouseevent(self,info); + finally + viewporttoclient(info.pos,rect1); + end; + end; + end + else begin + enterevent(false); + end; + end + else begin + if info.eventkind = ek_clientmouseleave then begin + enterevent(false); + end; + end; + end; +end; + +procedure tcustomwindowwidget.domousewheelevent(var info: mousewheeleventinfoty); +var + rect1: rectty; +begin + if canevent(tmethod(fonwindowmousewheelevent)) then begin + rect1:= innerclientrect; + if pointinrect(info.pos,rect1) then begin + clienttoviewport(info.pos,rect1); + try + fonwindowmousewheelevent(self,info); + finally + viewporttoclient(info.pos,rect1); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomwindowwidget.windowscrolled(const sender: tobject); +begin + checkwindowrect; +end; + +procedure tcustomwindowwidget.setfpsmax(const avalue: real); +begin + ffpsmax:= avalue; + checktimer; +end; + +procedure tcustomwindowwidget.setoptionsclient( + const avalue: clientwindowoptionsty); +begin + if avalue <> foptionsclient then begin + foptionsclient:= avalue; + checktimer(); // check highres + end; +end; + +procedure tcustomwindowwidget.checktimer; +begin + if componentstate * [csloading,csdesigning,csdestroying] <> [] then begin + ftimer.enabled:= false; + end + else begin + ftimer.highres:= cwo_highrestimer in foptionsclient; + ftimer.leak:= not (cwo_noleak in foptionsclient); + if (ffpsmax >= 0) and showing then begin + if ffpsmax = 0 then begin + ftimer.interval:= 0; + end + else begin + ftimer.interval:= round(1000000/ffpsmax); + end; + ftimer.enabled:= true; + end + else begin + ftimer.enabled:= false; + end; + end; +end; + +procedure tcustomwindowwidget.dotimer(const sender: tobject); +begin + doonpaint(nil); +end; + +procedure tcustomwindowwidget.invalidateviewpointrect(arect: rectty); +begin //todo: test + arect.x:= arect.x + fviewport.x; + arect.y:= fviewport.y + fviewport.cy - (arect.y + arect.cy); + invalidaterect(arect,org_inner); +end; + +end. diff --git a/mseide-msegui/msegui.svg b/mseide-msegui/msegui.svg new file mode 100644 index 0000000..b1d5b2b --- /dev/null +++ b/mseide-msegui/msegui.svg @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/msegui_24.png b/mseide-msegui/msegui_24.png new file mode 100644 index 0000000..8852496 Binary files /dev/null and b/mseide-msegui/msegui_24.png differ diff --git a/mseide-msegui/msegui_32.png b/mseide-msegui/msegui_32.png new file mode 100644 index 0000000..79a1efa Binary files /dev/null and b/mseide-msegui/msegui_32.png differ diff --git a/mseide-msegui/msegui_48.png b/mseide-msegui/msegui_48.png new file mode 100644 index 0000000..eac3568 Binary files /dev/null and b/mseide-msegui/msegui_48.png differ diff --git a/mseide-msegui/msegui_64.png b/mseide-msegui/msegui_64.png new file mode 100644 index 0000000..c808ed1 Binary files /dev/null and b/mseide-msegui/msegui_64.png differ diff --git a/mseide-msegui/tools/bmp2pas.pas b/mseide-msegui/tools/bmp2pas.pas new file mode 100644 index 0000000..288dcc1 --- /dev/null +++ b/mseide-msegui/tools/bmp2pas.pas @@ -0,0 +1,112 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program bmp2pas; + +// commandline: bmp2pas -oDESTFILE BITMAPFILE ... +// 'bmp2pas -oregcomps_bmp.pas tcomp1.bmp tcomp2.bmp tcomp3.bmp' +// -> bitmapunit for tcomp1,tcomp2,tcomp3 + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC} +{$APPTYPE CONSOLE} +{$endif} + +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} + mseguiinifini, + SysUtils, + msetypes, + msesysenv, + msestrings, + msefileutils, + msesysutils, + msebitmap, + mseclasses, + mseformdatatools,mseguiintf, + mseformatpngread,mseformatbmpicoread, + msegraphutils; + +type + argty = (arg_dest,arg_names); + +const + arguments: array[argty] of argumentdefty = + ((kind: ak_pararg; name: 'o'; anames: nil; flags: []; initvalue: ''), + (kind: ak_arg; name: ''; anames: nil; flags: []; initvalue: '') + ); + +var + sysenv: tsysenvmanager; + ar1,ar2: msestringarty; + int1: integer; + bmps: array of tbitmapcomp; + str1,str2: msestring; + +begin + try + sysenv:= tsysenvmanager.create(nil); + sysenv.init(arguments); + str1:= sysenv.value[ord(arg_dest)]; + ar1:= sysenv.values[ord(arg_names)]; + try + setlength(bmps,length(ar1)); + try + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> '' then begin + bmps[int1]:= tbitmapcomp.create(nil); + ar2:= nil; + splitstring(ar1[int1],ar2,widechar(',')); + if (length(ar2) < 1) or (length(ar2)>2) then begin + errorhalt('Invalid parameter: '+ar1[int1]); + end; + if length(ar2) > 1 then begin + bmps[int1].name:= ar2[1]; + end + else begin + bmps[int1].name:= removefileext(filename(ar2[0])); + end; + writestdout( + 'Converting file "'+ar2[0]+'" componentname "'+bmps[int1].name+'".',true); + with bmps[int1].bitmap do begin + loadfromfile(ar2[0],'',[]); + if fileext(ar2[0]) = 'png' then begin + transparentcolor:= cl_none; + colormask:= true; + masked:= true; + end; + end; + end; + end; + str2:= removefileext(filename(str1)); + writestdout( + 'Write unitfile "'+str1+'".',true); + componentstoobjsource(componentarty(bmps),str1,'msebitmap',str2); + finally + for int1:= 0 to high(bmps) do begin + bmps[int1].Free; + end; + end; + except + on e: exception do begin + sysenv.destroy(); + errorhalt(e.message); + end; + end; + finally + sysenv.destroy(); + end; +end. diff --git a/mseide-msegui/tools/bmp2pas.prj b/mseide-msegui/tools/bmp2pas.prj new file mode 100644 index 0000000..8f64f82 --- /dev/null +++ b/mseide-msegui/tools/bmp2pas.prj @@ -0,0 +1,967 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/tools +projectfilename=/home/mse/packs/standard/git/mseide-msegui/tools/bmp2pas.prj +mainfile=bmp2pas.pas +targetfile=bmp2pas${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl + -B + -OG2p3 -XX -CX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=0 +newprojectfilesdest=0 +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 65599 + 196671 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=0 +loadprojectfile=0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=1 + 0,0 +bookmarks0=0 +sourcefiles=1 + /home/mse/packs/standard/git/mseide-msegui/tools/bmp2pas.pas +relpaths=1 + bmp2pas.pas +ismoduletexts=1 + 0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=134 +firsttab=0 +index=0 +[layout] +windowlayout=531 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/tools/bmp2pas.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=554 + cx=323 + cy=169 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=276 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=279 + cx=313 + cy=221 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=500 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/tools/data2pas.pas b/mseide-msegui/tools/data2pas.pas new file mode 100644 index 0000000..be63f7f --- /dev/null +++ b/mseide-msegui/tools/data2pas.pas @@ -0,0 +1,75 @@ +{ MSEide Copyright (c) 2017 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program data2pas; + +// commandline: data2pas -oDESTFILE SOURCEFILE +// 'data2pas -odata.pas data.bin +// -> dataunit for data.bin + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC} +{$APPTYPE CONSOLE} +{$endif} + +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} + SysUtils,msesys,msesysutils, + msetypes, + msesysenv, + msestrings, + msefileutils, + mseformdatatools,msestream; + +type + argty = (arg_dest,arg_names); + +const + arguments: array[argty] of argumentdefty = + ((kind: ak_pararg; name: 'o'; anames: nil; flags: [arf_mandatory]; + initvalue: ''), + (kind: ak_arg; name: ''; anames: nil; flags: []; initvalue: '') + ); + +var + sysenv: tsysenvmanager; + s1,s2: msestring; + source1: tmsefilestream; + dest1: ttextstream; + dir1,file1,ext1: filenamety; +begin + source1:= nil; + dest1:= nil; + sysenv:= tsysenvmanager.create(nil); + try + if sysenv.init(arguments) then begin + s1:= sysenv.value[ord(arg_dest)]; + s2:= sysenv.value[ord(arg_names)]; + splitfilepath(s1,dir1,file1,ext1); + if ext1 = '' then begin + ext1:= '.pas'; + end; + s1:= filepath(dir1,file1+ext1); + dest1:= ttextstream.create(s1,fm_create); + source1:= tmsefilestream.create(s2,fm_read); + datatoobjsource(source1,dest1,file1); + end; + finally + sysenv.destroy(); + source1.free(); + dest1.free(); + end; +end. diff --git a/mseide-msegui/tools/data2pas.prj b/mseide-msegui/tools/data2pas.prj new file mode 100644 index 0000000..d755fd0 --- /dev/null +++ b/mseide-msegui/tools/data2pas.prj @@ -0,0 +1,43 @@ +[projectoptions] +mainfile=data2pas.pas +targetfile=data2pas${EXEEXT} +makecommand=${COMPILER} +makedir= +unitdirs=5 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ../../toolsskin + ../lib +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 ${fpcflags} + -gl -O- -gh + -B + -O2 -XX -Xs -CX +reversepathorder=0 +makeoptpurpose=4 + + + + +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=5 + 196671 + 65599 + 65599 + 983103 + 983103 +uid=0 diff --git a/mseide-msegui/tools/dist/copybin.sh b/mseide-msegui/tools/dist/copybin.sh new file mode 100755 index 0000000..8817773 --- /dev/null +++ b/mseide-msegui/tools/dist/copybin.sh @@ -0,0 +1,31 @@ +#!/bin/sh +DESTDIR=/home/mse/proj/mseguidist/bin +MSELINUXDIR=/home/mse/packs/standard/git +MSEWINDOWSDIR=/windows/F/git +MSELINUX64DIR=/opensuse_64/home/mse/packs/standard/git +MSEBSDDIR=/freebsd/home/mse/packs/standard/git +sudo mount -t ufs -o ufstype=ufs2,ro /dev/sda2 /freebsd + +set -e + +#exeext, sourcedir, destdir +docopy(){ +echo DEST: $3 + TMP=$2/mseide-msegui/apps/ide/mseide$1 + echo " Copying $TMP" + cp $TMP ${DESTDIR}/$3 + TMP=$2/mseuniverse/tools/msespice/msespice$1 + echo " Copying $TMP" + cp $TMP ${DESTDIR}/$3 + TMP=$2/mseuniverse/tools/msegit/msegit$1 + echo " Copying $TMP" + cp $TMP ${DESTDIR}/$3 + TMP=$2/mseuniverse/tools/mserun/mserun$1 + echo " Copying $TMP" + cp $TMP ${DESTDIR}/$3 +} + +docopy "" ${MSELINUXDIR} i386-linux +docopy "" ${MSELINUX64DIR} x86_64-linux +docopy "" ${MSEBSDDIR} x86_64-freebsd +docopy ".exe" ${MSEWINDOWSDIR} i386-win32 \ No newline at end of file diff --git a/mseide-msegui/tools/dist/makdist.mrp b/mseide-msegui/tools/dist/makdist.mrp new file mode 100644 index 0000000..d36186d --- /dev/null +++ b/mseide-msegui/tools/dist/makdist.mrp @@ -0,0 +1,315 @@ +[mainmo.projectstat] +savedmemoryfiles=6 + run.sta + macros.sta + memodialog.sta + testedit.sta + edit.sta + groupedit.sta +run.sta=6 + [runfo] + stackedunder= + x=348 + y=198 + cx=897 + cy=460 +macros.sta=9 + [macrosfo] + stackedunder= + x=145 + y=63 + cx=1195 + cy=491 + wsize=0 + active=1 + visible=1 +memodialog.sta=8 + [msememodialogfo] + x=507 + y=359 + cx=481 + cy=255 + wsize=0 + active=1 + visible=1 +testedit.sta=9 + [testeditfo] + stackedunder= + x=632 + y=260 + cx=596 + cy=581 + wsize=0 + active=1 + visible=1 +edit.sta=9 + [groupeditfo] + stackedunder= + x=225 + y=419 + cx=596 + cy=581 + wsize=0 + active=1 + visible=1 +groupedit.sta=9 + [groupeditfo] + stackedunder= + x=225 + y=419 + cx=596 + cy=581 + wsize=0 + active=1 + visible=1 +[tree] +kind=0 +a=0,665,0, +c=1 + ( + kind=1 + a=0,665,4, + c=2 + ( + kind=1 + a=0,665,4,MSEide-MSEgui + c=1 + ( + kind=2 + a=0,648,1,MSEide + teststate=1 + path=apps/ide/mseide.pas + comment= + cc= + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec=0 + cr=0 + ao=0 + ae=0 + aec=0 + ie=0 + ) + teststate=1 + path=${MSEBASEDIR}/mseide-msegui${MAC_IFDEF(DIREXT)}/ + comment= + cc= + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec=0 + cdef= + pdef= + ) + ( + kind=1 + a=0,665,4,MSEuniverse + c=4 + ( + kind=2 + a=0,648,1,MSEgit + teststate=1 + path=msegit/msegit.pas + comment= + cc= + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec= + cr=0 + ao=0 + ae=0 + aec=0 + ie=0 + ) + ( + kind=2 + a=0,648,1,MSEspice + teststate=1 + path=msespice/msespice.pas + comment= + cc= + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec= + cr=0 + ao=0 + ae=0 + aec=0 + ie=0 + ) + ( + kind=2 + a=0,648,1,MSErun + teststate=1 + path=mserun/mserun.pas + comment= + cc= + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec= + cr=0 + ao=0 + ae=0 + aec=0 + ie=0 + ) + ( + kind=2 + a=0,648,1,MSEkicadBOM + teststate=1 + path=kicad/bom/msekicadbom.pas + comment= + cc=${FPC} -Fu${MSEBASEDIR}/mseuniverse/tools/toolsskin -Fu../lib ${FILE} + cd=${file_noname($file)} + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec= + cr=0 + ao= + ae= + aec=0 + ie=0 + ) + teststate=1 + path=${MSEBASEDIR}/mseuniverse${MAC_IFDEF(DIREXT)}/tools/ + comment= + cc=${FPC} -Fu${MSEBASEDIR}/mseuniverse/tools/toolsskin ${FILE} + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec= + cdef= + pdef= + ) + teststate=1 + path= + comment= + cc=${FPC} ${FILE} + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec=0 + cdef= + pdef= + ) +teststate=0 +[options] +[mainmo.stoponfirsterr] +checked=0 +[mainmo.stoponcomperr] +checked=0 +[mainmo.trttistat1] +macronames=10 + FPCINSTDIR + COMPILERBIN + COMPILERBIN + MSEBASEDIR + MSELIBDIR + FPCUNITS + MSEUNITS + COMPILER + FPCFLAGS + FPC +macrovalues=10 + + ppc386 + ppcx64 + /home/mse/packs/standard/git/ + ${FILE_SYS(${MSEBASEDIR}/mseide-msegui${MAC_IFDEF(DIREXT)}/lib/common/)} + -Fu${FILE_SYS(${FPCINSTDIR}/${FPCUNITDIR}/*)} + -Fu${MSELIBDIR}* -Fu${FILE_SYS(${MSELIBDIR}kernel/)}${TARGET} + ${FPCINSTDIR}${FILE_SYS(${COMPILERBIN})} + -n -viwn -Xg -B -O2 -XX -Xs -CX -l -Fcutf8 -dmse_with_deprecated ${MSEUNITS} ${FPCUNITS} ${MAC_IFDEF(OPT)} + ${COMPILER} ${FPCFLAGS} +macroon=10 + 0 + 0 + 0 + 0 + 63 + 63 + 63 + 63 + 63 + 63 +macrogroup=0 +groupcomment=6 + 386 + x64 + + + + +[mainfo] +stackedunder= +x=129 +y=75 +cx=588 +cy=254 +wsize=0 +active=1 +visible=1 +[mainfo.grid] +propcolwidthref=497 +width0=50 +sortdescend0=0 +width1=151 +sortdescend1=0 +width2=294 +sortdescend2=0 +width3=221 +sortdescend3=0 +sortdescend4=0 +rowstate=8 + 0 0 + 0 0 + 0 0 + 0 0 + 0 0 + 0 0 + 0 0 + 0 0 diff --git a/mseide-msegui/tools/dist/makeallfp.sh b/mseide-msegui/tools/dist/makeallfp.sh new file mode 100644 index 0000000..95bbeac --- /dev/null +++ b/mseide-msegui/tools/dist/makeallfp.sh @@ -0,0 +1,8 @@ +#!/bin/sh +BASEDIR=/home/mse/packs/standard/svn/fp/ +FPCDIR=/fixes_3_0 +INSTALLDIR=$BASEDIR/builds/fixes_3_0 +PWDBEFORE=$PWD +cd $BASEDIR/$FPCDIR +make clean all install INSTALL_PREFIX=$INSTALLDIR +cd $PWDBEFORE diff --git a/mseide-msegui/tools/dist/runmake.sh b/mseide-msegui/tools/dist/runmake.sh new file mode 100755 index 0000000..546922b --- /dev/null +++ b/mseide-msegui/tools/dist/runmake.sh @@ -0,0 +1,15 @@ +#!/bin/sh +MSERUN=/home/mse/packs/standard/git/mseuniverse/tools/mserun/mserun +FPCINSTDIR=/home/mse/packs/standard/svn/fp/builds/fixes_3_0/ +# +#FPCUNITDIR=lib/fpc/3.0.1/units/x86_64-linux +#COMPILERBIN=lib/fpc/3.0.1/ppcx64 +#OPT="-Fl/usr/local/lib" +FPCUNITDIR=lib/fpc/3.0.1/units/i386-linux +COMPILERBIN=lib/fpc/3.0.1/ppc386 +OPT="-Fl/usr/local/lib" +# +TARGET=linux +MSEBASEDIR=/home/mse/packs/standard/git/ +echo $OPT +$MSERUN --macrodef=FPCINSTDIR,$FPCINSTDIR --macrodef=COMPILERBIN,$COMPILERBIN --macrodef=MSEBASEDIR,$MSEBASEDIR --macrodef=FPCUNITDIR,$FPCUNITDIR --macrodef=TARGET,$TARGET "--macrodef=OPT,$OPT" makdist.mrp diff --git a/mseide-msegui/tools/doc/README.TXT b/mseide-msegui/tools/doc/README.TXT new file mode 100644 index 0000000..c5938d0 --- /dev/null +++ b/mseide-msegui/tools/doc/README.TXT @@ -0,0 +1,4 @@ +2008-01-07 mse + +doc has been moved to +https://gitlab.com/mseuniverse/mseuniverse/tree/master/attic/msedocumenting/mse/trunk/tools/doc diff --git a/mseide-msegui/tools/form2pas.pas b/mseide-msegui/tools/form2pas.pas new file mode 100644 index 0000000..2afa152 --- /dev/null +++ b/mseide-msegui/tools/form2pas.pas @@ -0,0 +1,91 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program form2pas; + +//convert form files (*.mfm) to pascal files (*_mfm.pas) +//commandline: form2pas FORMFILE[,UNITNAME] ... +//Default UNITNAME is FORMFILE without extension. +// +//'form2pas main.mfm formdesigner.mfm' -> +//convert main.mfm to main_mfm.pas, formdesigner.mfm to formdesigner_mfm.pas + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC} +{$APPTYPE CONSOLE} +{$endif} + +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} + SysUtils, + msetypes, + msesysenv, + msestrings, + msefileutils, + msestream, + msesysutils, + msesys, + mseformdatatools; + +const + arguments: array[0..0] of argumentdefty = + ((kind: ak_arg; name: ''; anames: nil; flags: []; initvalue: '')); + +var + sysenv: tsysenvmanager; + ar1,ar2: msestringarty; + int1: integer; + formname,formclass,unitname: string; + stream: ttextstream; +begin + sysenv:= tsysenvmanager.create(nil); + sysenv.init(arguments); + ar1:= sysenv.values[0]; + try + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> '' then begin + {$ifdef msefp} + setlength(ar2,0); //ar2:= nil -> av! + {$else} + ar2:= nil; + {$endif} + splitstring(ar1[int1],ar2,widechar(',')); + if (length(ar2) < 1) or (length(ar2)>2) then begin + errorhalt('Invalid parameter: '+ar1[int1]); + end; + if length(ar2) > 1 then begin + unitname:= ar2[1]; + end + else begin + unitname:= removefileext(filename(ar2[0])); + end; + stream:= ttextstream.Create(ar2[0],fm_read); + try + getobjforminfo(stream,formname,formclass); + finally + stream.free; + end; + writestdout( + 'Converting file "'+ar2[0]+'" class "'+formclass+'" unit "'+unitname+'"''.',true); + formtexttoobjsource(ar2[0],formclass,unitname); + end; + end; + except + on e: exception do begin + errorhalt(e.message); + end; + end; +end. diff --git a/mseide-msegui/tools/form2pas.prj b/mseide-msegui/tools/form2pas.prj new file mode 100644 index 0000000..0c3e3bb --- /dev/null +++ b/mseide-msegui/tools/form2pas.prj @@ -0,0 +1,953 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/tools +projectfilename=/home/mse/packs/standard/git/mseide-msegui/tools/form2pas.prj +mainfile=form2pas.pas +targetfile=form2pas${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl + -B + -OG2p3 -XX -CX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=0 +newprojectfilesdest=0 +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=8 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Report + Scriptform + Inherited Form +newfonamebases=8 + form + form + form + module + form + report + script + form +newfosources=8 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=8 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 65599 + 196671 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=0 +loadprojectfile=0 +newinheritedforms=8 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=1 + 0,0 +bookmarks0=0 +sourcefiles=1 + /home/mse/packs/standard/git/mseide-msegui/tools/form2pas.pas +relpaths=1 + form2pas.pas +ismoduletexts=1 + 0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=134 +firsttab=0 +index=0 +[layout] +windowlayout=532 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=2 + /home/mse/packs/standard/git/mseide-msegui/tools/form2pas.pas + /home/mse/packs/standard/git/mseide-msegui/tools/bmp2pas.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=554 + cx=323 + cy=169 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=276 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=279 + cx=313 + cy=221 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=500 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/tools/i18n/main.mfm b/mseide-msegui/tools/i18n/main.mfm new file mode 100644 index 0000000..9bc587e --- /dev/null +++ b/mseide-msegui/tools/i18n/main.mfm @@ -0,0 +1,614 @@ +object mainfo: tmainfo + visible = False + bounds_x = 107 + bounds_y = 283 + bounds_cx = 624 + bounds_cy = 390 + container.frame.levelo = 1 + container.frame.localprops = [frl_levelo] + container.frame.sbhorz.facebutton.template = concavex + container.frame.sbhorz.facebutton.dummy = 0 + container.frame.sbhorz.faceendbutton.template = concavex + container.frame.sbhorz.faceendbutton.dummy = 0 + container.frame.sbvert.facebutton.template = concavey + container.frame.sbvert.facebutton.dummy = 0 + container.frame.sbvert.faceendbutton.template = concavey + container.frame.sbvert.faceendbutton.dummy = 0 + container.bounds = ( + 0 + 20 + 624 + 370 + ) + optionswindow = [wo_groupleader] + mainmenu = mainmenu1 + options = [fo_main, fo_terminateonclose, fo_savepos, fo_savezorder, fo_savestate] + statfile = projectfo.projectstat + caption = 'MSEi18n' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + oncreate = tmainfooncreate + onloaded = loadedexe + oneventloopstart = tmainfoonloaded + ondestroy = tmainfoondestroy + onclosequery = mainclosequery + moduleclassname = 'tmseform' + object tgroupbox1: tgroupbox + frame.captiondist = -4 + frame.localprops1 = [frl1_captiondist] + frame.dummy = 0 + face.template = concavex + face.dummy = 0 + bounds_x = 1 + bounds_y = 1 + bounds_cx = 622 + bounds_cy = 24 + anchors = [an_top] + end + object grid: twidgetgrid + frame.sbvert.facebutton.template = concavey + frame.sbvert.facebutton.dummy = 0 + frame.sbvert.faceendbutton.template = concavey + frame.sbvert.faceendbutton.dummy = 0 + frame.sbhorz.facebutton.template = concavex + frame.sbhorz.facebutton.dummy = 0 + frame.sbhorz.faceendbutton.template = concavex + frame.sbhorz.faceendbutton.dummy = 0 + taborder = 5 + bounds_x = 1 + bounds_y = 25 + bounds_cx = 622 + bounds_cy = 344 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_focuscellonenter, og_rowheight, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 39 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + face.template = convexx + face.dummy = 0 + height = 16 + captions.count = 5 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Type' + end + item + caption = 'NT' + end + item + caption = 'Comment' + end + item + caption = 'Value' + end> + end> + datacols.count = 5 + datacols.options = [co_proportional, co_savestate] + datacols.options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + datacols.items = < + item[tree] + width = 195 + options = [co_readonly, co_proportional, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + widgetname = 'tree' + dataclass = ttreeitemeditlist + end + item[typedisp] + options = [co_readonly, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + widgetname = 'typedisp' + dataclass = tgridenumdatalist + end + item[donottranslate] + width = 19 + options = [co_drawfocus, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + widgetname = 'donottranslate' + dataclass = tgridintegerdatalist + end + item[comment] + width = 124 + options = [co_proportional, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + widgetname = 'comment' + dataclass = tgridmsestringdatalist + end + item[value] + width = 102 + options = [co_readonly, co_proportional, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + widgetname = 'value' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = projectfo.projectstat + reffontheight = 14 + object tree: ttreeitemedit + optionswidget1 = [ow1_fontglyphheight] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 195 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_exitoncursor, oe_hintclippedtext] + textflags = [tf_ycentered, tf_clipo, tf_noselect, tf_ellipseleft] + onupdaterowvalues = treeonupdaterowvalues + options = [teo_treecolnavig] + reffontheight = 14 + end + object typedisp: tenumtypeedit + optionswidget1 = [ow1_fontglyphheight] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.button.options = [fbo_invisible, fbo_disabled] + taborder = 2 + visible = False + bounds_x = 196 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_exitoncursor] + dropdown.options = [deo_selectonly, deo_autodropdown, deo_disabled] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = typedisponinit + reffontheight = 14 + end + object donottranslate: tbooleanedit + color = -2147483646 + frame.levelo = 0 + frame.localprops = [frl_levelo] + frame.dummy = 0 + taborder = 3 + bounds_x = 247 + bounds_y = 0 + bounds_cx = 19 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + onsetvalue = donottranslateonsetvalue + end + object comment: tmemodialogedit + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.button.width = 13 + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 4 + visible = False + bounds_x = 267 + bounds_y = 0 + bounds_cx = 124 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + font.height = 12 + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + onsetvalue = commentonsetvalue + reffontheight = 14 + end + object value: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.button.imagenr = 17 + frame.button.options = [fbo_invisible, fbo_disabled] + taborder = 5 + visible = False + bounds_x = 392 + bounds_y = 0 + bounds_cx = 102 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_exitoncursor, oe_hintclippedtext] + reffontheight = 14 + end + end + object flat: tbooleanedit + color = -2147483645 + frame.caption = 'flat' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 19 + 2 + ) + taborder = 1 + bounds_x = 9 + bounds_y = 5 + bounds_cx = 32 + bounds_cy = 16 + statfile = projectfo.projectstat + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + ondataentered = formatchanged + end + object stringonly: tbooleanedit + color = -2147483645 + frame.caption = 'string only' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 59 + 2 + ) + taborder = 2 + bounds_x = 57 + bounds_y = 5 + bounds_cx = 72 + bounds_cy = 16 + statfile = projectfo.projectstat + ondataentered = formatchanged + end + object nont: tbooleanedit + color = -2147483645 + frame.caption = 'no NT' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 36 + 2 + ) + taborder = 3 + bounds_x = 153 + bounds_y = 5 + bounds_cx = 49 + bounds_cy = 16 + statfile = projectfo.projectstat + ondataentered = formatchanged + onsetvalue = nontonsetvalue + end + object ntonly: tbooleanedit + color = -2147483645 + frame.caption = 'NT only' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 44 + 2 + ) + taborder = 4 + bounds_x = 233 + bounds_y = 5 + bounds_cx = 57 + bounds_cy = 16 + statfile = projectfo.projectstat + ondataentered = formatchanged + onsetvalue = ntonlyonsetvalue + end + object coloron: tbooleanedit + color = -2147483645 + frame.caption = 'Show Color' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 67 + 2 + ) + taborder = 6 + bounds_x = 321 + bounds_y = 5 + bounds_cx = 80 + bounds_cy = 16 + statfile = projectfo.projectstat + ondataentered = showcolordataentered + value = True + end + object mainstatfile: tstatfile + filename = 'msei18n.sta' + filedir = '"^/.mseide"' + options = [sfo_createpath, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + onstatupdate = mainupdatestat + left = 16 + top = 96 + end + object mainmenu1: tmainmenu + onupdate = mainmenuupdate + facetemplate = convexx + itemframetemplate = menuitemframe + itemframetemplateactive = menuitemframe + menu.submenu.count = 10 + menu.submenu.items = < + item + caption = '&Open' + name = 'open' + state = [as_localcaption, as_localonexecute] + onexecute = onprojectopen + end + item + caption = '&Save' + name = 'save' + state = [as_localcaption, as_localonexecute] + onexecute = onprojectsave + end + item + caption = 'Save &as' + name = 'saveas' + state = [as_localcaption, as_localonexecute] + onexecute = saveasexecute + end + item + caption = '&New' + name = 'new' + state = [as_localcaption, as_localonexecute] + onexecute = newprojectexe + end + item + caption = '&Edit' + name = 'edit' + state = [as_localcaption, as_localonexecute] + onexecute = onprojectedit + end + item + caption = '&Import' + name = 'import' + state = [as_localcaption, as_localonexecute] + onexecute = importonexecute + end + item + caption = 'Ex&port' + name = 'export' + state = [as_localcaption, as_localonexecute] + onexecute = exportonexecute + end + item + caption = '&Make' + name = 'make' + state = [as_localcaption, as_localonexecute] + onexecute = makeonexecute + end + item + submenu.count = 2 + submenu.items = < + item + caption = '&About' + state = [as_localcaption, as_localonexecute] + onexecute = aboutexe + end + item + caption = '&Configure MSEi18n' + state = [as_localcaption, as_localonexecute] + onexecute = configureonexecute + end> + caption = 'Se&ttings' + name = 'settings' + state = [as_localcaption] + end + item + caption = 'E&xit' + state = [as_localcaption, as_localonexecute] + onexecute = exitexe + end> + left = 256 + top = 160 + end + object projectfiledialog: tfiledialog + statfile = mainstatfile + controller.filterlist.data = ( + ( + 'Translate project' + '*.trp' + ) + ) + controller.defaultext = 'trp' + controller.options = [fdo_checkexist, fdo_chdir] + controller.captionopen = 'Open translate project' + controller.captionsave = 'Save translate project' + left = 120 + top = 156 + end + object threadcomp: tthreadcomp + onexecute = makeexecute + onterminate = maketerminate + left = 209 + top = 115 + end + object convexx: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612732 + -1610612731 + ) + template.fade_direction = gd_up + left = 385 + top = 103 + end + object convexy: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612732 + -1610612731 + ) + template.fade_direction = gd_left + left = 481 + top = 103 + end + object concavex: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612732 + -1610612731 + ) + template.fade_direction = gd_down + left = 385 + top = 135 + end + object concavey: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612732 + -1610612731 + ) + left = 481 + top = 135 + end + object sysenv: tsysenvmanager + left = 24 + top = 160 + end + object c: tstringcontainer + strings.data = ( + 'name' + 'type' + 'notranslate' + 'comment' + 'value' + '' + 'Can not read module' + 'New translate project' + 'Exec error' + 'Making' + 'overwrites itself' + 'ERROR' + 'Finished OK' + 'Configure MSEi18n' + 'Data has changed' + 'Do you wish to save' + 'CONFIRMATION' + 'Close error:' + '' + ) + left = 64 + top = 200 + end + object tskincontroller1: tskincontroller + extenders = 0 + left = 176 + top = 224 + end + object iconbmp: tbitmapcomp + bitmap.origformat = 'png' + bitmap.image = { + 00000000000000001800000018000000AC080000000000000000000000000000 + 0000000000000000000000000000000000000000EBEBEB01EAEAEA01E9E9E901 + E8E8E801E7E7E701E6E6E601E4E4E401E3E3E301DDE0DD01E0D3CC01E3CBC001 + E4C7B901E2C5B701E0C8BD01DECEC901DADADA01D9D9D901D8D8D801D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101EBEBEB01EAEAEA01E9E9E901 + E8E8E801E7E7E701E6E6E601E5DBD701E7C6B60179A65A0164A75201CEA56601 + E4A56A01E3A46901E3A67001C3A66F015FA14B01BCB49201DAD0CC01D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101EBEBEB01EAEAEA01E9E9E901 + BED5BD01B6D1B401E9CCBE01E8B59201E6A76C017EA95401F7FBF70167A03A01 + D69B1801D99B1801A099230180B46701C1E0BF01A89B4E01E0AD8A01DCBFB101 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101EBEBEB01EAEAEA01E9E9E901 + 84BC81019ECC980170A45001BC9C4001DB9C210173A12F01FEFFFE01D6EAD301 + 769E1F01B49D000189BD7401FFFFFF01A2CB9101BB981B01DE9C4701E0A47301 + DDB7A301D4D4D401D3D3D301D2D2D201D1D1D101EBEBEB01EAEAEA01E9E9E901 + B9B88C01B5D5AC01FAFDFA0198C484016DA130017D9A0E01B4D6A801FFFFFF01 + 9ECA8D01669E2001EBF5EA01FFFFFF017BB45D01CE9F0001D59B0501DD9A3701 + DFA26C01BDAE8C0165AB61019ABD9801D1D1D101EBEBEB01EAEAEA01ECCFC101 + EAAE7D0175A84E01FFFFFF02FEFFFE018CC0760152A13401FBFDFB01EFF7EF01 + 50A03201FFFFFF0269A83C016AA537017C9E1E01C49A0001769C380191C08301 + BDDDBA0197BC9601D1D1D101EBEBEB01EBE1DD01EBB89501E4A24D01A19A1101 + A2CA8C01FFFFFF0369AB430180BA6701E2F0E101519F240174B250018BC17901 + 599E220168AF54015E9E26017DB45F01EDF6ED01EFF7EF0168A34F01D2CAC401 + D1D1D101EBEBEB01ECCBBB01E9AA6F01DC9D2201989C0D01609B1E01B7D7AB01 + FFFFFF025FA93D016CC447015EAB350177C02F0120F8DF0151DC88016DA41301 + 68AC4601DFEEDC01FFFFFF01FDFEFD016DA84A01CF9E5E01D9B8A801D1D1D101 + EBEBEB01ECBC9E01E4A24D01D39C000168AA4A01BFDBB401539F2C0193C58001 + 9BCB8B0141CF79010EFFF9014FE6900152E48B010EFFF90129F4CF0169AC4001 + FFFFFF0387BB6F01B09A0701DD9B4601DCAC8E01D1D1D101EDDDD801EBB28701 + DF9D3301D19F00017CA11E016AA83C01579E1F0165A3120162A6160161DF7201 + 15FCED0165D54F015CA901016AD148017ED4440170BB3001A5CF9701FFFFFF01 + A3CE960188A01501CF9F0001D4982E01DEA57A01D5C5C001EDD5CA01C6A66501 + 7D9C2D0174A83F0186BB6C01A8D09B01C2E0C001DAECD90171B65F0188BF0801 + 8DD31C0132980001068000013E9D000131F2BF0113FDF2016ABC400156A22C01 + 60A537017CB1530183B8650180B5640171A14C01ACB48F01EED1C30148973201 + D6EAD501FFFFFF0569B0440127F6CF011DFADE0154B60B011D8E00016AB70001 + 3EEDA60114FDF00166B52B018AC27C01FFFFFF02F9FCF901B5D6AA016DA95601 + B2B18F01EED1C301D8A766017D9A240171AB4A01CEE5C801FFFFFF02A4CF9701 + 70B01D0115FCEB010EFFF9016DE145014FEB7D014EE9860185C615015BB23C01 + 6DAD370155A22D0173AC3F0174AD4701729F2501A8961501DD9F6401D8BBAD01 + EDD5CA01EAAD7701DC9D2201CBA00001869F0F016CA8390157A3350157A63601 + 3C9A250183C5160161C1350167C631010EFFF90256BA4701F7FBF701FFFFFF01 + D4E9D10162A63801A8A30501CFA00001D99A1F01DEA16B01D7BFB401EDDDD801 + EBB28701DF9D3301D19F0001CAA500018CA4100180BA6601F5FAF50153A53701 + 88C27501D2E8D10169B24C016CDA52016DCA390158A83101FCFEFC01FFFFFF02 + FCFEFC018DBF7701859E1C01DB992F01DEA57A01D5C5C001EBEBEB01ECBC9E01 + E4A24D01D49C00019D9E0B018DC07501FFFFFF019AC9880164AC4701FFFFFF02 + C5E1C1016AAB07016DB45D015CAA3E0159A53901EDF6EC01FFFFFF03BAD9AF01 + 8B9C3F01DCAC8E01D1D1D101EBEBEB01ECCBBB01E9AA6F01B49B22017FB56201 + FFFFFF01FAFDFA0159A23301CFE6CB01FFFFFF0284BE6A016DA5020197C98601 + FBFDFB0175B55B01539F2A0179B35A0195C48001B9DAB301D7EBD60197C78F01 + 97AB7701D1D1D101EBEBEB01EBE1DD01DCB48C0172AC5801FAFDFA01D3E9D201 + 76B460015DA23601FFFFFF02C1DEB80153A12B0154A22E0172B15201FFFFFF02 + 6DAC4801C8A60001BB9E0001A69505019799390187A15B01BDC2B001D1D1D101 + EBEBEB01EAEAEA01BABF970166A24A01799D390192980D018F980501ABD19F01 + FFFFFF01A0CB8F016CA11C018CBF75017DB65E016BA42701F6FBF601FFFFFF01 + 85BA6B01C6A00001D49C0001DC993601DFA37201DABDAF01D2D2D201D1D1D101 + EBEBEB01EAEAEA01E9E9E901ECC6B201E8AB7501E19E3B01749D2901E1F0DF01 + 6BA842019FA0090184A01401E0EFDF018DBF7601999F03019EC98D01FFFFFF01 + A9D09C01B2970401DD9A3701DFA26C01DCB6A201D3D3D301D2D2D201D1D1D101 + EBEBEB01EAEAEA01E9E9E901E8E8E801EBC5B101E9AD7C019A9F4201729B2E01 + CD9B0001D19F0001A29B0601A4CE9B016B9F2701CFA000016DA23101FCFEFC01 + C4E1C201A7963601E0A47301DDB7A301D4D4D401D3D3D301D2D2D201D1D1D101 + EBEBEB01EAEAEA01E9E9E901E8E8E801E7E7E701E9CCBE01E8B59201E6A76C01 + E2A04B01DE9C3201D89C20017D982101CA991601DA9B2001B9982C019AC68B01 + B1D4AA01B6A56F01DCBFB101D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101 + EBEBEB01EAEAEA01E9E9E901E8E8E801E7E7E701E6E6E601E5DBD701E7C6B601 + E7B79901E6AD8201E5A87201E4A56A01E3A46901E3A67001E3AA7F0178A55A01 + 66A95B01CBCBBE01D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101 + EBEBEB01EAEAEA01E9E9E901E8E8E801E7E7E701E6E6E601E4E4E401E3E3E301 + E2E2E201E4D4CF01E3CBC001E4C7B901E2C5B701E0C8BD01DECEC901CDD5CD01 + CCD4CC01D8D8D801D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101 + } + left = 296 + top = 224 + end + object menuitemframe: tframecomp + template.levelo = -1 + template.leveli = 1 + left = 256 + top = 192 + end +end diff --git a/mseide-msegui/tools/i18n/main.pas b/mseide-msegui/tools/i18n/main.pas new file mode 100644 index 0000000..97d7a1a --- /dev/null +++ b/mseide-msegui/tools/i18n/main.pas @@ -0,0 +1,1199 @@ +{ MSEtools Copyright (c) 1999-2012 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit main; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msefiledialog,msestat,msestatfile,msesimplewidgets,msegrids, + msewidgetgrid,msegraphics,msegraphutils,mselistbrowser,msedataedits,typinfo, + msedatanodes,msegraphedits,msestream,mseglob,msemenus,classes,mclasses, + msetypes,msestrings,msethreadcomp,mseguiglob,msegui,mseresourceparser, + msedialog,msememodialog,mseobjecttext,mseifiglob,msesysenv,msemacros, + msestringcontainer,mseclasses,mseskin,msebitmap,msejson; + +const + msei18nversiontext = mseguiversiontext; + drcext = '_DRC.rc'; + rstext = '_rst'; + variantshift = 5; + +type + resfilekindty = (rfk_module,rfk_unit,rfk_resource,rfk_resstrings); + + tmainfo = class(tmseform) + mainstatfile: tstatfile; + clear: tbutton; + flat: tbooleanedit; + stringonly: tbooleanedit; + nont: tbooleanedit; + ntonly: tbooleanedit; + grid: twidgetgrid; + convexx: tfacecomp; + convexy: tfacecomp; + concavex: tfacecomp; + concavey: tfacecomp; + tgroupbox1: tgroupbox; + tree: ttreeitemedit; + threadcomp: tthreadcomp; + typedisp: tenumtypeedit; + donottranslate: tbooleanedit; + comment: tmemodialogedit; + value: tmemodialogedit; + scan: tbutton; + mainmenu1: tmainmenu; + projectfiledialog: tfiledialog; + coloron: tbooleanedit; + sysenv: tsysenvmanager; + c: tstringcontainer; + tskincontroller1: tskincontroller; + iconbmp: tbitmapcomp; + menuitemframe: tframecomp; + procedure onprojectopen(const sender: tobject); + procedure onprojectsave(const sender: tobject); + procedure onprojectedit(const sender: tobject); + // procedure readonexecute(const sender: tobject); + // procedure writeonexecute(const sender: tobject); + procedure exportonexecute(const sender: tobject); + procedure importonexecute(const sender: tobject); + procedure clearonexecute(const sender: tobject); + procedure edoninit(const sender: tenumtypeedit); + procedure typedisponinit(const sender: tenumtypeedit); + procedure treeonupdaterowvalues(const sender: tobject; const aindex: integer; + const aitem: tlistitem); + procedure tmainfooncreate(const sender: tobject); + procedure tmainfoonloaded(const sender: tobject); + procedure tmainfoondestroy(const sender: tobject); + procedure formatchanged(const sender: tobject); + procedure nontonsetvalue(const sender: tobject; var avalue: boolean; + var accept: boolean); + procedure ntonlyonsetvalue(const sender: tobject; var avalue: boolean; + var accept: boolean); + procedure donottranslateonsetvalue(const sender: tobject; var avalue: boolean; + var accept: boolean); + procedure commentonsetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); + procedure variantonsetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); + +// procedure scanonexecute(const sender: tobject); + procedure makeonexecute(const sender: tobject); + procedure mainupdatestat(const sender: TObject; const filer: tstatfiler); + procedure configureonexecute(const sender: TObject); + procedure makeexecute(const sender: tthreadcomp); + procedure maketerminate(const sender: tthreadcomp); + procedure mainclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure saveasexecute(const sender: TObject); + procedure newprojectexe(const sender: TObject); + procedure mainmenuupdate(const sender: tcustommenu); + procedure aboutexe(const sender: TObject); + procedure exitexe(const sender: TObject); + procedure beforelangdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure showcolordataentered(const sender: TObject); + procedure loadedexe(const sender: TObject); + private + datastream: ttextdatastream; +// alang: integer; + fdatachanged: boolean; + procedure datachanged; + procedure updatecaption; + procedure updatedata; + procedure refreshnodedata; + procedure writerecord(const sender: ttreenode); + procedure writeexprecord(const sender: ttreenode); + procedure checkitem(const sender: ttreelistitem; var delete: boolean); + function filternode(const anode: ttreenode): boolean; + function readunit(const stream: tmsefilestream): msestring; + function readstringresource(const stream: tmsefilestream; + const fpcformat: boolean): msestring; + function readmodule(const stream: tmsefilestream): msestring; + procedure doread(stream: ttextdatastream; aencoding: charencodingty); + procedure dowrite(stream: ttextdatastream; aencoding: charencodingty); + procedure doimport(stream: ttextdatastream; aencoding: charencodingty); + procedure doexport(stream: ttextdatastream; aencoding: charencodingty); + function getcolumnheaders: msestringarty; + function checksave(cancelonly: boolean = false): boolean; + public + procedure loadproject; + procedure readprojectdata; + procedure writeprojectdata; + end; + +var + mainfo: tmainfo; + rootnode: tpropinfonode; + +implementation +uses + main_mfm,msefileutils,msesystypes,msesys,sysutils,mselist,project, + rtlconsts,mseprocutils,msestockobjects, + msewidgets,mseparser,mseformdatatools,mseresourcetools, + msearrayutils,msesettings,messagesform,mseeditglob,mseformatstr; +type + strinconsts = ( + sc_name, //0 + sc_type, //1 + sc_notranslate, //2 + sc_comment, //3 + sc_value, //4 + sc_noproject, //5 + sc_cannotreadmodule, //6 + sc_newtranslateproject,//7 + sc_execerror, //8 + sc_making, //9 + sc_overwritesitself, //10 + sc_error, //11 + sc_finishedok, //12 + sc_configuremsei18n, //13 + sc_datahaschanged, //14 + sc_doyouwishtosave, //15 + sc_confirmation, //16 + sc_closeerror //17 + ); +const + translateext = 'trans'; + exportext = 'csv'; +type + envvarty = (env_macrodef); +const + sysenvvalues: array[envvarty] of argumentdefty = + ((kind: ak_pararg; name: '-macrodef'; anames: nil; flags: []; initvalue: '') + ); + +type + ttreenode1 = class(ttreenode); + tpropinfonode1 = class(tpropinfonode); + +{ tmainfo } + +const + sn_header = 'header'; + sn_prop = '.prop'; + svn_compclass = 'compclass'; + svn_compname = 'compname'; + svn_name = 'name'; + svn_type = 'type'; + svn_value = 'value'; + +procedure tmainfo.tmainfooncreate(const sender: tobject); +var + wstr1: msestring; +begin + stockobjects.mseicon.assign(iconbmp.bitmap); + iconchanged(nil); +// iconbmp.free; + sysenv.init(sysenvvalues); + wstr1:= filepath(statdirname); + if not finddir(wstr1) then begin + createdir(wstr1); + end; + {$ifdef mswindows} + mainstatfile.filename:= 'msei18nwi.sta'; + {$endif} + {$ifdef linux} + mainstatfile.filename:= 'msei18nli.sta'; + {$endif} + {$ifdef openbsd} + mainstatfile.filename:= 'msei18nobsd.sta'; + {$endif} + {$ifdef bsd} + mainstatfile.filename:= 'msei18nbsd.sta'; + {$endif} + rootnode:= tpropinfonode.Create; + application.createform(tprojectfo, projectfo); + updatecaption; +end; + +procedure tmainfo.tmainfoonloaded(const sender: tobject); +begin + mainstatfile.readstat; + show; +end; + +procedure tmainfo.tmainfoondestroy(const sender: tobject); +begin + freeandnil(rootnode); +end; + +procedure tmainfo.edoninit(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(tvaluetype); +end; + +procedure tmainfo.typedisponinit(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(tvaluetype); +end; + +procedure tmainfo.treeonupdaterowvalues(const sender: tobject; + const aindex: integer; const aitem: tlistitem); +var + int1: integer; +begin + with tpropinfoitem(aitem) do begin + if node <> nil then begin + with node do begin + typedisp[aindex]:= ord(info.valuetype); + donottranslate[aindex]:= info.donottranslate; + comment[aindex]:= info.comment; + value[aindex]:= valuetext; + for int1:= 0 to grid.datacols.count - variantshift - 1 do begin + with tmemodialogedit(grid.datacols[int1+variantshift].editwidget) do begin + if high(info.variants) >= int1 then begin + gridvalue[aindex]:= info.variants[int1]; + end + else begin + gridvalue[aindex]:= ''; + end; + end; + end; + end; + end; + end; +end; + +function tmainfo.filternode(const anode: ttreenode): boolean; +begin + result:= true; + if result and stringonly.value then begin + result:= tpropinfonode(anode).info.valuetype in + [vastring,valstring,vawstring,vautf8string, + vanull,valist,vacollection]; + end; + if result then begin + if nont.value then begin + result:= not tpropinfonode(anode).info.donottranslate; + end + else begin + if ntonly.value then begin + result:= tpropinfonode(anode).info.donottranslate or + (tpropinfonode(anode).info.valuetype in [vanull,valist,vacollection]); + end; + end; + end; +end; + +procedure tmainfo.checkitem(const sender: ttreelistitem; var delete: boolean); +begin + with tpropinfoitem(sender),node,info do begin + delete:= (sender.count = 0) and (valuetype in [vanull,valist,vacollection]) and + (stringonly.value or ntonly.value and not donottranslate); + if not delete and flat.value then begin + sender.caption:= msestring(node.rootstring); + end; + end; +end; + +function tmainfo.getcolumnheaders: msestringarty; +var + int1: integer; +begin + setlength(result,variantshift + projectfo.grid2.rowcount); + result[0]:= c[ord(sc_name)]; + result[1]:= c[ord(sc_type)]; + result[2]:= c[ord(sc_notranslate)]; + result[3]:= c[ord(sc_comment)]; + result[4]:= c[ord(sc_value)]; + for int1:= 0 to projectfo.grid2.rowcount - 1 do begin + result[int1 + variantshift]:= projectfo.lang[int1]; + end; +end; + +procedure tmainfo.updatecaption; +var + mstr1: msestring; +begin + mstr1:= 'MSEi18n ('; + if fdatachanged then begin + mstr1:= mstr1+'*'; + end; + if projectfo.projectstat.filename = '' then begin + mstr1:= mstr1+c[ord(sc_noproject)]; + end + else begin + mstr1:= mstr1+msefileutils.filename(projectfo.projectstat.filename); + end; + caption:= mstr1 + ')'; +end; + +procedure tmainfo.datachanged; +begin + fdatachanged:= true; + updatecaption; +end; + +procedure tmainfo.updatedata; +var + int1: integer; + item: ttreelistedititem; + ar1: msestringarty; + edit1: tmemodialogedit; +begin + ar1:= getcolumnheaders; +// grid.datacols.count:= variantshift; + grid.datacols.count:= length(ar1); + grid.fixrows[-1].captions.count:= length(ar1); + for int1:= variantshift to high(ar1) do begin + grid.fixrows[-1].captions[int1].caption:= getcolumnheaders[int1]; + with grid.datacols[int1] do begin + if editwidget = nil then begin + edit1:= tmemodialogedit.create(self); + edit1.initgridwidget; + edit1.frame.button.width:= 13; + edit1.onsetvalue:= {$ifdef FPC}@{$endif}variantonsetvalue; + edit1.Tag:= int1 - variantshift; + edit1.optionsedit:= (edit1.optionsedit - [oe_savevalue]) + + [oe_hintclippedtext]; + grid.datacols[int1].editwidget:= edit1; + end; + onbeforedrawcell:= @beforelangdrawcell; + end; + end; + grid.beginupdate; + try + item:= rootnode.converttotreelistitem(flat.value,false, + {$ifdef FPC}@{$endif}filternode); + item.checkitems({$ifdef FPC}@{$endif}checkitem); + tree.itemlist.assign(item); + finally + grid.endupdate; + end; +end; + +procedure tmainfo.refreshnodedata; +begin + tree.itemlist.refreshitemvalues; +end; + +function tmainfo.readunit(const stream: tmsefilestream): msestring; +var + scanner: tscanner; + parser: tconstparser; + ar1: constinfoarty; + node,node1: tpropinfonode; + int1: integer; +begin + scanner:= nil; + parser:= nil; + try + scanner:= tscanner.Create; + scanner.source:= stream.readdatastring; + parser:= tconstparser.Create; + parser.scanner:= scanner; + node:= tpropinfonode.Create; + node.info.name:= parser.getconsts(ar1); + result:= msestring(node.info.name); + rootnode.add(node); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if resource then begin + node1:= tpropinfonode.Create; + node1.info.name:= name; + node1.info.msestringvalue:= value; + node1.info.valuetype:= valuetype; + node1.info.coffset:= offset; + node1.info.clen:= len; + node.add(node1); + end; + end; + end; + updatedata; + finally + parser.Free; + scanner.Free; + stream.Free; + end; +end; + +function tmainfo.readstringresource(const stream: tmsefilestream; + const fpcformat: boolean): msestring; +var + scanner: tscanner; + parser: tparser; + ar1: constinfoarty; + node,node1,node2: tpropinfonode; + int1,int2: integer; + str1: string; +// po1: pchar; +begin + scanner:= nil; + parser:= nil; + try + if fpcformat and (fileext(stream.filename) = 'rsj') then begin + ar1:= rsjgetconsts(stream); + end + else begin + if fpcformat then begin + scanner:= tpascalscanner.Create; + scanner.source:= stream.readdatastring; + parser:= tfpcresstringparser.create(nil); + end + else begin + scanner:= tcscanner.Create; + scanner.source:= stream.readdatastring; + parser:= tresstringlistparser.Create(nil); + end; + parser.scanner:= scanner; + if fpcformat then begin + tfpcresstringparser(parser).getconsts(ar1); + end + else begin + tresstringlistparser(parser).getconsts(ar1); + end; + end; + node:= tpropinfonode.Create; + node.info.name:= ansistring(filename(stream.filename)); + result:= msestring(node.info.name); + str1:= ''; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if valuetype = vawstring then begin + if fpcformat then begin + int2:= msestrings.findchar(name,'.'); + end + else begin + int2:= msestrings.findchar(name,'_'); + end; + if int2 > 0 then begin + str1:= copy(name,1,int2-1); + name:= copy(name,int2+1,bigint); + node1:= nil; + for int2:= 0 to node.count - 1 do begin + if node[int2].info.name = str1 then begin + node1:= node[int2]; + break; + end; + end; + if node1 = nil then begin + node1:= tpropinfonode.Create; + node1.info.name:= str1; + node.add(node1); + end; + node2:= tpropinfonode.Create; + node2.info.name:= name; + node2.info.msestringvalue:= value; + node2.info.valuetype:= valuetype; + node2.info.coffset:= offset; + node2.info.clen:= len; + node1.add(node2); + end; + end; + end; + end; + rootnode.add(node); +// updatedata; + finally + parser.Free; + scanner.Free; + stream.Free; + end; +end; + +function tmainfo.readmodule(const stream: tmsefilestream): msestring; +var + memstream: tmemorystream; + node: tpropinfonode; +// int1: integer; +begin + memstream:= tmemorystream.Create; + result:= ''; + try + objecttexttobinarymse(stream,memstream); + memstream.Position:= 0; + node:= tpropinfonode.Create; + readprops(memstream,node); + result:= msestring(node.info.name); + rootnode.add(node); + except + application.handleexception(self,c[ord(sc_cannotreadmodule)]+' '+stream.filename+':'); + end; + memstream.Free; + stream.Free; +end; + +procedure tmainfo.writerecord(const sender: ttreenode); +var + rec: varrecarty; + str1,str2: string; + mstr3: msestring; + int1: integer; +begin + rec:= nil; //compilerwarning + if ttreenode1(sender).fparent <> nil then begin + with tpropinfonode(sender),info do begin + str1:= rootstring(','); + str2:= ansistring(typedisp.enumname(ord(valuetype))); + mstr3:= valuetext; + rec:= mergevarrec([str1,str2,donottranslate,comment,mstr3],[]); + for int1:= 0 to high(variants) do begin + rec:= mergevarrec(rec,[variants[int1]]); + end; + end; + datastream.writerecord(rec); + end; +end; + +procedure tmainfo.donottranslateonsetvalue(const sender: tobject; + var avalue, accept: boolean); +begin + tpropinfoitem(tree.item).node.info.donottranslate:= avalue; + datachanged; + grid.invalidaterow(grid.row); +end; + +procedure tmainfo.commentonsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + tpropinfoitem(tree.item).node.info.comment:= avalue; + datachanged; +end; + +procedure tmainfo.variantonsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + with tpropinfoitem(tree.item).node.info,twidget(sender) do begin + if high(variants) < tag then begin + setlength(variants,tag+1); + end; + variants[tag]:= avalue; + end; + datachanged; +end; + +procedure tmainfo.formatchanged(const sender: tobject); +begin + updatedata; +end; + +procedure tmainfo.doread(stream: ttextdatastream; aencoding: charencodingty); +var + aname: string; + notranslate: boolean; + acomment: msestring; + node: tpropinfonode; + str1: string; + ar1: stringarty; + avariants: msestringarty; + pointers: pointerarty; + int1: integer; +begin + try + stream.encoding:= aencoding; + stream.readln(str1); //header + splitstringquoted(str1,ar1,'"',','); + int1:= length(ar1); + if int1 < variantshift then begin + int1:= variantshift; + end; + setlength(pointers,int1); + str1:= 's bSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS'; + setlength(str1,length(pointers)); + pointers[0]:= @aname; + pointers[2]:= @notranslate; + pointers[3]:= @acomment; + while not stream.eof do begin + aname:= ''; + notranslate:= false; + setlength(avariants,length(pointers) - variantshift); + for int1:= 0 to high(avariants) do begin + avariants[int1]:= ''; + pointers[int1 + variantshift]:= @avariants[int1]; + end; + if stream.readrecord(pointers,str1) then begin + node:= rootnode.findsubnode(','+aname); + if node <> nil then begin + with node.info do begin + donottranslate:= notranslate; + comment:= acomment; + variants:= avariants; + end; + end + else begin + //todo: errorlist + end; + end + else begin + //todo: errormesage + end; + end; + finally + stream.Free; + end; +// refreshnodedata; +// updatedata; +end; + +procedure tmainfo.doimport(stream: ttextdatastream; aencoding: charencodingty); +begin + doread(stream,aencoding); + fdatachanged:= true; + updatecaption; +end; + +procedure tmainfo.importonexecute(const sender: tobject); +var + stream: ttextdatastream; + str1: filenamety; +begin + if checksave and + projectfo.impexpfiledialog.controller.execute(str1,fdk_open) then begin + stream:= ttextdatastream.create(str1,fm_read); + doimport(stream,charencodingty(projectfo.impexpencoding.value)); + updatedata; + end; +end; + +procedure tmainfo.writeexprecord(const sender: ttreenode); +var + bo1,bo2: boolean; + int1: integer; +begin + with tpropinfonode1(sender) do begin + bo2:= not nont.value or not info.donottranslate; + if fparent <> nil then begin + bo1:= not stringonly.value or (info.valuetype in + [vastring,valstring,vawstring,vautf8string]); + if bo1 and bo2 then begin + writerecord(sender); + end; + end; + if bo2 then begin + for int1:= 0 to fcount -1 do begin + writeexprecord(fitems[int1]); + end; + end; + end; +end; + +procedure tmainfo.doexport(stream: ttextdatastream; aencoding: charencodingty); +begin + stream.encoding:= aencoding; + datastream:= stream; + try + datastream.writerecord(getcolumnheaders); + writeexprecord(rootnode); + finally + datastream.Free; + end; +end; + +procedure tmainfo.exportonexecute(const sender: tobject); +var + stream: ttextdatastream; + str1: filenamety; +begin + if projectfo.impexpfiledialog.controller.execute(str1,fdk_save) then begin + stream:= ttextdatastream.create(str1,fm_create); + doexport(stream,charencodingty(projectfo.impexpencoding.value)); + end; +end; + +procedure tmainfo.clearonexecute(const sender: tobject); +begin + rootnode.clear; + updatedata; +end; + +procedure tmainfo.loadproject; +var + int1: integer; + file1: tmsefilestream; + mstr1: msestring; +begin + rootnode.clear; + try + for int1:= 0 to projectfo.grid.rowcount - 1 do begin + file1:= tmsefilestream.create(projectfo.filename[int1]); + case resfilekindty(projectfo.filekind[int1]) of + rfk_module: begin + mstr1:= readmodule(file1); + end; + rfk_unit: begin + mstr1:= readunit(file1); + end; + rfk_resstrings: begin + mstr1:= readstringresource(file1,true); + end; + rfk_resource: begin + mstr1:= readstringresource(file1,false); + end; + end; + projectfo.rootname[int1]:= mstr1; + end; + rootnode.initlang(projectfo.grid2.rowcount); + readprojectdata; + updatedata; + finally + updatecaption; + end; +end; + +procedure tmainfo.readprojectdata; +begin + if projectfo.datafilename.value <> '' then begin + try + doread(ttextdatastream.Create(projectfo.datafilename.value),ce_utf8); + except + application.handleexception(self); + end; + end; +end; + +procedure tmainfo.dowrite(stream: ttextdatastream; aencoding: charencodingty); +begin + stream.encoding:= aencoding; + datastream:= stream; + try + datastream.writerecord(getcolumnheaders); + rootnode.iterate({$ifdef FPC}@{$endif}writerecord); + finally + datastream.Free; + end; +end; + +procedure tmainfo.writeprojectdata; +var + stream: ttextdatastream; +begin + stream:= ttextdatastream.Create(projectfo.datafilename.value,fm_create); + dowrite(stream,ce_utf8); + fdatachanged:= false; + updatecaption; +end; + +procedure tmainfo.onprojectopen(const sender: tobject); +begin + if projectfiledialog.execute = mr_ok then begin + projectfo.projectstat.filename:= projectfiledialog.controller.filename; + projectfo.projectstat.readstat; + end; +end; + +procedure tmainfo.onprojectsave(const sender: tobject); +begin + writeprojectdata; +end; + +procedure tmainfo.newprojectexe(const sender: TObject); +begin + if checksave and (projectfiledialog.controller.execute(fdk_save, + c[ord(sc_newtranslateproject)]) = mr_ok) then begin + projectfo.free; + application.createform(tprojectfo, projectfo); + clearonexecute(nil); + with projectfo.projectstat do begin + filename:= projectfiledialog.controller.filename; + if not fileexists(filename) then begin + projectfo.datafilename.value:= replacefileext(filename,'trd'); + projectfo.impexpfiledialog.controller.clear; + projectfo.impexpfiledialog.controller.filename:= replacefileext(filename,'csv'); + writeprojectdata; + end + else begin + writestat; + end; + end; + updatecaption; + end; +end; + +procedure tmainfo.saveasexecute(const sender: TObject); +begin + if projectfiledialog.controller.execute(fdk_save) = mr_ok then begin + projectfo.projectstat.filename:= projectfiledialog.controller.filename; + projectfo.projectstat.writestat; + writeprojectdata; + end; +end; + +procedure tmainfo.onprojectedit(const sender: tobject); +begin + projectfo.show(true); + projectfo.projectstat.writestat; + projectfo.projectstat.readstat; +end; + +procedure tmainfo.makeexecute(const sender: tthreadcomp); + + procedure addmessage(const amessage: msestring); + begin + application.lock; + messagesfo.messages.addchars(amessage); + application.unlock; + end; + +var + macroar: macroinfoarty; + error: boolean; + + function doproc(const commandstr: msestring): boolean; + var + mstr1: msestring; + int3: integer; + begin + result:= false; + mstr1:= expandmacros(commandstr,macroar); + int3:= messagesfo.messages.execprog(mstr1); + if int3 = invalidprochandle then begin + error:= true; + end + else begin + int3:= messagesfo.messages.waitforprocess; + if int3 <> 0 then begin + addmessage(c[ord(sc_execerror)]+' '+inttostrmse(int3)+'.'); + error:= true; + end + else begin + result:= true; + end; + end; + end; + +var + int1,int2,int3: integer; + stream,stream1: tmsefilestream; + stream2: ttextstream; + node: tpropinfonode; + afilename: filenamety; + modulenames,resourcenames: stringarty; + str1: string; + commandstring: msestring; + mstr1: msestring; +// actdir: filenamety; + dirbefore: filenamety; + basename: filenamety; + +begin +// basename:= filenamebase(projectfo.projectstat.filename); + basename:= projectfo.destname.value; + if basename = '' then begin + basename:= filenamebase(projectfo.datafilename.value); + end; + if basename = '' then begin + basename:= filenamebase(projectfo.projectstat.filename); + end; + commandstring:= expandmacros(projectfo.makecommand.value, + sysenv.getcommandlinemacros(ord(env_macrodef),-1,-1, + getsyssettingsmacros)); + setlength(macroar,2); + macroar[0].name:= 'LIBFILE'; + macroar[1].name:= 'LIBFILEBASE'; + dirbefore:= getcurrentdirmse; + error:= false; + for int1:= 0 to projectfo.grid2.rowcount - 1 do begin + if error then break; + rootnode.transferlang(int1); + try + addmessage(c[ord(sc_making)]+' "'+projectfo.dir[int1]+'".'+lineend); + modulenames:= nil; + resourcenames:= nil; + for int2:= 0 to projectfo.grid.rowcount - 1 do begin + if error then break; + node:= nil; + afilename:= filepath(projectfo.dir[int1],msefileutils.filename(projectfo.filename[int2])); + if issamefilename(afilename,filepath(projectfo.filename[int2])) then begin + addmessage(afilename+' '+c[ord(sc_overwritesitself)]+'.'); + error:= true; + break; + end; + for int3:= 0 to rootnode.count - 1 do begin + if rootnode[int3].info.name = + ansistring(projectfo.rootname[int2]) then begin + node:= rootnode[int3]; + break; + end; + end; + if node <> nil then begin + case resfilekindty(projectfo.filekind[int2]) of + rfk_resource: begin + stream:= tmsefilestream.Create(projectfo.filename[int2],fm_read); + try + stream1:= tmsefilestream.Create(removefileext(afilename)+drcext,fm_create); + try + writeresources(stream,stream1,node); + finally + stream1.Free; + end; + finally + stream.Free; + end; + end; + rfk_resstrings: begin + stream2:= ttextstream.Create(afilename,fm_create); + try + writefpcresourcestrings(stream2,node); + finally + stream2.Free; + end; + str1:= ansistring(filenamebase(afilename))+rstext; + resourcetexttoresourcesource(afilename,str1,true); + additem(resourcenames,str1); + end; + rfk_unit: begin + stream:= tmsefilestream.Create(projectfo.filename[int2],fm_read); + try + stream1:= tmsefilestream.Create(afilename,fm_create); + try + writeconsts(stream,stream1,node); + finally + stream1.Free; + end; + finally + stream.Free; + end; + end; + rfk_module: begin + stream:= tmsefilestream.Create; //memory + try + writeprops(stream,node); + stream.Position:= 0; + stream1:= tmsefilestream.Create(afilename,fm_create); + try + objectbinarytotextmse(stream,stream1); + finally + stream1.Free; + end; + finally + stream.Free; + end; + formtexttoobjsource(afilename,'','',of_default,true); + additem(modulenames,ansistring(filenamebase(afilename))); + end; + end; + end; + end; + if (modulenames <> nil) or (resourcenames <> nil) then begin + with projectfo do begin + macroar[0].value:= basename+'_'+lang[int1]+'.pas'; + macroar[1].value:= filenamebase(macroar[0].value); + createlanglib(dir[int1]+macroar[0].value,modulenames,resourcenames); + if makeon.value then begin + try + setcurrentdirmse(dir[int1]); + if beforemake.value <> '' then begin + if not doproc(beforemake.value) then begin + break; + end; + end; + if doproc(commandstring) then begin + if aftermake.value <> '' then begin + doproc(aftermake.value); + end + else begin + mstr1:= macroar[1].value; + {$ifdef mswindows} + mstr1:= mstr1+'.dll'; + {$else} + mstr1:= 'lib'+mstr1+'.so'; + {$endif} + copyfile(mstr1,'../'+mstr1,true); + end; + end; + finally + setcurrentdirmse(dirbefore); + end; + end; + end; + end; + except + on e: exception do begin + addmessage(msestring(e.message+lineend)); + error:= true; + end; + else begin + error:= true; + end; + end; + end; + if error then begin + addmessage('**** '+c[ord(sc_error)]+' ****'+lineend); + end + else begin + addmessage(c[ord(sc_finishedok)]+lineend); + end; + application.lock; + messagesfo.running:= false; + application.unlock; +end; + +procedure tmainfo.makeonexecute(const sender: tobject); +begin + if checksave(true) then begin + messagesfo.messages.clear; + messagesfo.running:= true; + messagesfo.show; //winid must exist + threadcomp.run; + messagesfo.show(true); + loadproject; + end; +end; + +procedure tmainfo.maketerminate(const sender: tthreadcomp); +begin + messagesfo.running:= false; +end; + +procedure tmainfo.nontonsetvalue(const sender: tobject; var avalue, + accept: boolean); +begin + if avalue then begin + ntonly.value:= false; + end; +end; + +procedure tmainfo.ntonlyonsetvalue(const sender: tobject; var avalue, + accept: boolean); +begin + if avalue then begin + nont.value:= false; + end; +end; + +procedure tmainfo.mainupdatestat(const sender: TObject; const filer: tstatfiler); +var + mstr1: msestring; +begin + updatesettings(filer); + mstr1:= projectfo.projectstat.filename; + filer.updatevalue('projectfile',mstr1); + projectfo.projectstat.filename:= mstr1; + if mstr1 <> '' then begin + try + setcurrentdirmse(filedir(mstr1)); + except + application.handleexception(nil); + end; + end; + if filer.iswriter then begin + projectfo.projectstat.writestat; + end + else begin + projectfo.projectstat.readstat; + end; +end; + +procedure tmainfo.configureonexecute(const sender: TObject); +begin + editsettings(c[ord(sc_configuremsei18n)]); +end; + +function tmainfo.checksave(cancelonly: boolean = false): boolean; +var + mstr1: msestring; +begin + result:= true; + if fdatachanged then begin + mstr1:= c[ord(sc_datahaschanged)]+'.'+lineend+c[ord(sc_doyouwishtosave)]+'?'; + if cancelonly then begin + if askok(mstr1,c[ord(sc_confirmation)]) then begin + writeprojectdata; + end + else begin + result:= false; + end; + end + else begin + case askyesnocancel(mstr1,c[ord(sc_confirmation)]) of + mr_no: begin end; + mr_yes: begin + writeprojectdata; + end; + else begin + result:= false; + end; + end; + end; + end; +end; + +procedure tmainfo.mainclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); +begin + if not checksave then begin + amodalresult:= mr_none; + end + else begin + try + mainstatfile.writestat; + except + on e: exception do begin + if showmessage(c[ord(sc_closeerror)]+lineend+msestring(e.message), + c[ord(sc_error)],[mr_ignore,mr_cancel]) <> mr_ignore then begin + amodalresult:= mr_none; + end; + end; + end; + end; +end; + +procedure tmainfo.mainmenuupdate(const sender: tcustommenu); +var + bo1: boolean; +begin + bo1:= projectfo.projectstat.filename <> ''; + with mainmenu.menu do begin + itembyname('save').enabled:= bo1; + itembyname('saveas').enabled:= bo1; + itembyname('edit').enabled:= bo1; + itembyname('import').enabled:= bo1; + itembyname('export').enabled:= bo1; + itembyname('make').enabled:= bo1; + end; +end; + +procedure tmainfo.aboutexe(const sender: TObject); +begin + showmessage('MSEgui version: '+mseguiversiontext+lineend+ + 'MSEi18n version: ' + msei18nversiontext,'About MSEi18n'); +end; + +procedure tmainfo.exitexe(const sender: TObject); +begin + close; +end; + +procedure tmainfo.beforelangdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); +var + int1: integer; +begin + if coloron.value then begin + with cellinfo.cell do begin + int1:= typedisp[row]; + if ((int1 = ord(vastring)) or (int1 = ord(vawstring))) and + not donottranslate[row] and + (tstringedit(grid.datacols[col].editwidget)[row] = + value[row]) and (value[row] <> '') then begin + cellinfo.color:= cl_ltred; + end; + end; + end; +end; + +procedure tmainfo.showcolordataentered(const sender: TObject); +begin + grid.invalidate; +end; + +procedure tmainfo.loadedexe(const sender: TObject); +begin + iconbmp.free; +end; + +end. diff --git a/mseide-msegui/tools/i18n/main_mfm.pas b/mseide-msegui/tools/i18n/main_mfm.pas new file mode 100644 index 0000000..6be9ee6 --- /dev/null +++ b/mseide-msegui/tools/i18n/main_mfm.pas @@ -0,0 +1,654 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..12734] of byte end = + (size: 12735; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,107,8, + 98,111,117,110,100,115,95,121,3,27,1,9,98,111,117,110,100,115,95,99, + 120,3,112,2,9,98,111,117,110,100,115,95,99,121,3,134,1,22,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,101,118,101,108,111, + 2,1,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,0,42,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,115, + 98,104,111,114,122,46,102,97,99,101,98,117,116,116,111,110,46,116,101,109, + 112,108,97,116,101,7,8,99,111,110,99,97,118,101,120,39,99,111,110,116, + 97,105,110,101,114,46,102,114,97,109,101,46,115,98,104,111,114,122,46,102, + 97,99,101,98,117,116,116,111,110,46,100,117,109,109,121,2,0,45,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,115,98,104,111,114,122, + 46,102,97,99,101,101,110,100,98,117,116,116,111,110,46,116,101,109,112,108, + 97,116,101,7,8,99,111,110,99,97,118,101,120,42,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,115,98,104,111,114,122,46,102,97,99, + 101,101,110,100,98,117,116,116,111,110,46,100,117,109,109,121,2,0,42,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,115,98,118,101,114, + 116,46,102,97,99,101,98,117,116,116,111,110,46,116,101,109,112,108,97,116, + 101,7,8,99,111,110,99,97,118,101,121,39,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,115,98,118,101,114,116,46,102,97,99,101,98, + 117,116,116,111,110,46,100,117,109,109,121,2,0,45,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,115,98,118,101,114,116,46,102,97,99, + 101,101,110,100,98,117,116,116,111,110,46,116,101,109,112,108,97,116,101,7, + 8,99,111,110,99,97,118,101,121,42,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,115,98,118,101,114,116,46,102,97,99,101,101,110,100, + 98,117,116,116,111,110,46,100,117,109,109,121,2,0,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,20,3,112,2,3, + 114,1,0,13,111,112,116,105,111,110,115,119,105,110,100,111,119,11,14,119, + 111,95,103,114,111,117,112,108,101,97,100,101,114,0,8,109,97,105,110,109, + 101,110,117,7,9,109,97,105,110,109,101,110,117,49,7,111,112,116,105,111, + 110,115,11,7,102,111,95,109,97,105,110,19,102,111,95,116,101,114,109,105, + 110,97,116,101,111,110,99,108,111,115,101,10,102,111,95,115,97,118,101,112, + 111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95, + 115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7, + 21,112,114,111,106,101,99,116,102,111,46,112,114,111,106,101,99,116,115,116, + 97,116,7,99,97,112,116,105,111,110,6,7,77,83,69,105,49,56,110,21, + 105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,12,105,99,111,110,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,0,8,111,110,99,114,101,97,116, + 101,7,15,116,109,97,105,110,102,111,111,110,99,114,101,97,116,101,8,111, + 110,108,111,97,100,101,100,7,9,108,111,97,100,101,100,101,120,101,16,111, + 110,101,118,101,110,116,108,111,111,112,115,116,97,114,116,7,15,116,109,97, + 105,110,102,111,111,110,108,111,97,100,101,100,9,111,110,100,101,115,116,114, + 111,121,7,16,116,109,97,105,110,102,111,111,110,100,101,115,116,114,111,121, + 12,111,110,99,108,111,115,101,113,117,101,114,121,7,14,109,97,105,110,99, + 108,111,115,101,113,117,101,114,121,15,109,111,100,117,108,101,99,108,97,115, + 115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,9,116,103,114, + 111,117,112,98,111,120,10,116,103,114,111,117,112,98,111,120,49,17,102,114, + 97,109,101,46,99,97,112,116,105,111,110,100,105,115,116,2,252,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,16,102,114,108, + 49,95,99,97,112,116,105,111,110,100,105,115,116,0,11,102,114,97,109,101, + 46,100,117,109,109,121,2,0,13,102,97,99,101,46,116,101,109,112,108,97, + 116,101,7,8,99,111,110,99,97,118,101,120,10,102,97,99,101,46,100,117, + 109,109,121,2,0,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117, + 110,100,115,95,121,2,1,9,98,111,117,110,100,115,95,99,120,3,110,2, + 9,98,111,117,110,100,115,95,99,121,2,24,7,97,110,99,104,111,114,115, + 11,6,97,110,95,116,111,112,0,0,0,11,116,119,105,100,103,101,116,103, + 114,105,100,4,103,114,105,100,32,102,114,97,109,101,46,115,98,118,101,114, + 116,46,102,97,99,101,98,117,116,116,111,110,46,116,101,109,112,108,97,116, + 101,7,8,99,111,110,99,97,118,101,121,29,102,114,97,109,101,46,115,98, + 118,101,114,116,46,102,97,99,101,98,117,116,116,111,110,46,100,117,109,109, + 121,2,0,35,102,114,97,109,101,46,115,98,118,101,114,116,46,102,97,99, + 101,101,110,100,98,117,116,116,111,110,46,116,101,109,112,108,97,116,101,7, + 8,99,111,110,99,97,118,101,121,32,102,114,97,109,101,46,115,98,118,101, + 114,116,46,102,97,99,101,101,110,100,98,117,116,116,111,110,46,100,117,109, + 109,121,2,0,32,102,114,97,109,101,46,115,98,104,111,114,122,46,102,97, + 99,101,98,117,116,116,111,110,46,116,101,109,112,108,97,116,101,7,8,99, + 111,110,99,97,118,101,120,29,102,114,97,109,101,46,115,98,104,111,114,122, + 46,102,97,99,101,98,117,116,116,111,110,46,100,117,109,109,121,2,0,35, + 102,114,97,109,101,46,115,98,104,111,114,122,46,102,97,99,101,101,110,100, + 98,117,116,116,111,110,46,116,101,109,112,108,97,116,101,7,8,99,111,110, + 99,97,118,101,120,32,102,114,97,109,101,46,115,98,104,111,114,122,46,102, + 97,99,101,101,110,100,98,117,116,116,111,110,46,100,117,109,109,121,2,0, + 8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120, + 2,1,8,98,111,117,110,100,115,95,121,2,25,9,98,111,117,110,100,115, + 95,99,120,3,110,2,9,98,111,117,110,100,115,95,99,121,3,88,1,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95, + 116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95, + 99,111,108,115,105,122,105,110,103,19,111,103,95,102,111,99,117,115,99,101, + 108,108,111,110,101,110,116,101,114,12,111,103,95,114,111,119,104,101,105,103, + 104,116,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98, + 107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117, + 116,111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46,99,111,117, + 110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1, + 5,119,105,100,116,104,2,39,8,110,117,109,115,116,97,114,116,2,1,7, + 110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115,46, + 99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109, + 115,14,1,13,102,97,99,101,46,116,101,109,112,108,97,116,101,7,7,99, + 111,110,118,101,120,120,10,102,97,99,101,46,100,117,109,109,121,2,0,6, + 104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111, + 117,110,116,2,5,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115, + 14,1,7,99,97,112,116,105,111,110,6,4,78,97,109,101,0,1,7,99, + 97,112,116,105,111,110,6,4,84,121,112,101,0,1,7,99,97,112,116,105, + 111,110,6,2,78,84,0,1,7,99,97,112,116,105,111,110,6,7,67,111, + 109,109,101,110,116,0,1,7,99,97,112,116,105,111,110,6,5,86,97,108, + 117,101,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110, + 116,2,5,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115, + 11,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111, + 95,115,97,118,101,115,116,97,116,101,0,17,100,97,116,97,99,111,108,115, + 46,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111, + 110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49,95, + 122,101,98,114,97,99,111,108,111,114,18,99,111,49,95,114,111,119,99,111, + 108,111,114,97,99,116,105,118,101,19,99,111,49,95,114,111,119,99,111,108, + 111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114,101,97, + 100,111,110,108,121,17,99,111,49,95,97,117,116,111,114,111,119,104,101,105, + 103,104,116,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14, + 7,4,116,114,101,101,1,5,119,105,100,116,104,3,195,0,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,15,99,111, + 95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118, + 101,115,116,97,116,101,0,8,111,112,116,105,111,110,115,49,11,11,99,111, + 49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99,111,108, + 111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,18,99,111, + 49,95,114,111,119,99,111,108,111,114,97,99,116,105,118,101,19,99,111,49, + 95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15,99,111,49, + 95,114,111,119,114,101,97,100,111,110,108,121,17,99,111,49,95,97,117,116, + 111,114,111,119,104,101,105,103,104,116,0,10,119,105,100,103,101,116,110,97, + 109,101,6,4,116,114,101,101,9,100,97,116,97,99,108,97,115,115,7,17, + 116,116,114,101,101,105,116,101,109,101,100,105,116,108,105,115,116,0,7,8, + 116,121,112,101,100,105,115,112,1,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,12,99,111,95,115,97,118,101,115,116, + 97,116,101,0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114, + 111,119,102,111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14, + 99,111,49,95,122,101,98,114,97,99,111,108,111,114,18,99,111,49,95,114, + 111,119,99,111,108,111,114,97,99,116,105,118,101,19,99,111,49,95,114,111, + 119,99,111,108,111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111, + 119,114,101,97,100,111,110,108,121,17,99,111,49,95,97,117,116,111,114,111, + 119,104,101,105,103,104,116,0,10,119,105,100,103,101,116,110,97,109,101,6, + 8,116,121,112,101,100,105,115,112,9,100,97,116,97,99,108,97,115,115,7, + 17,116,103,114,105,100,101,110,117,109,100,97,116,97,108,105,115,116,0,7, + 14,100,111,110,111,116,116,114,97,110,115,108,97,116,101,1,5,119,105,100, + 116,104,2,19,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97, + 119,102,111,99,117,115,12,99,111,95,115,97,118,101,115,116,97,116,101,0, + 8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111, + 110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49,95, + 122,101,98,114,97,99,111,108,111,114,18,99,111,49,95,114,111,119,99,111, + 108,111,114,97,99,116,105,118,101,19,99,111,49,95,114,111,119,99,111,108, + 111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114,101,97, + 100,111,110,108,121,17,99,111,49,95,97,117,116,111,114,111,119,104,101,105, + 103,104,116,0,10,119,105,100,103,101,116,110,97,109,101,6,14,100,111,110, + 111,116,116,114,97,110,115,108,97,116,101,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,7,99,111,109,109,101,110,116,1,5,119,105,100,116,104, + 2,124,7,111,112,116,105,111,110,115,11,15,99,111,95,112,114,111,112,111, + 114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102, + 111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49, + 95,122,101,98,114,97,99,111,108,111,114,18,99,111,49,95,114,111,119,99, + 111,108,111,114,97,99,116,105,118,101,19,99,111,49,95,114,111,119,99,111, + 108,111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114,101, + 97,100,111,110,108,121,17,99,111,49,95,97,117,116,111,114,111,119,104,101, + 105,103,104,116,0,10,119,105,100,103,101,116,110,97,109,101,6,7,99,111, + 109,109,101,110,116,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114, + 105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0, + 7,5,118,97,108,117,101,1,5,119,105,100,116,104,2,102,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,15,99,111, + 95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118, + 101,115,116,97,116,101,0,8,111,112,116,105,111,110,115,49,11,11,99,111, + 49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99,111,108, + 111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,18,99,111, + 49,95,114,111,119,99,111,108,111,114,97,99,116,105,118,101,19,99,111,49, + 95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15,99,111,49, + 95,114,111,119,114,101,97,100,111,110,108,121,17,99,111,49,95,97,117,116, + 111,114,111,119,104,101,105,103,104,116,0,10,119,105,100,103,101,116,110,97, + 109,101,6,5,118,97,108,117,101,9,100,97,116,97,99,108,97,115,115,7, + 22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108, + 105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2, + 16,8,115,116,97,116,102,105,108,101,7,21,112,114,111,106,101,99,116,102, + 111,46,112,114,111,106,101,99,116,115,116,97,116,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,13,116,116,114,101,101,105,116,101,109, + 101,100,105,116,4,116,114,101,101,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,5,99,111,108,111,114,4,7,0,0,144,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,195,0,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117, + 14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117, + 110,100,111,111,110,101,115,99,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110, + 116,101,114,101,100,8,116,102,95,99,108,105,112,111,11,116,102,95,110,111, + 115,101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102, + 116,0,17,111,110,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115, + 7,21,116,114,101,101,111,110,117,112,100,97,116,101,114,111,119,118,97,108, + 117,101,115,7,111,112,116,105,111,110,115,11,16,116,101,111,95,116,114,101, + 101,99,111,108,110,97,118,105,103,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,13,116,101,110,117,109,116,121,112,101,101,100, + 105,116,8,116,121,112,101,100,105,115,112,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112, + 104,104,101,105,103,104,116,0,5,99,111,108,111,114,4,7,0,0,144,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,111,112,116, + 105,111,110,115,11,13,102,98,111,95,105,110,118,105,115,105,98,108,101,12, + 102,98,111,95,100,105,115,97,98,108,101,100,0,8,116,97,98,111,114,100, + 101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,3,196,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97, + 117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121, + 101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116, + 101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114, + 101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,0,16,100,114,111,112,100, + 111,119,110,46,111,112,116,105,111,110,115,11,14,100,101,111,95,115,101,108, + 101,99,116,111,110,108,121,16,100,101,111,95,97,117,116,111,100,114,111,112, + 100,111,119,110,12,100,101,111,95,100,105,115,97,98,108,101,100,0,19,100, + 114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1, + 19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115, + 14,1,0,0,6,111,110,105,110,105,116,7,14,116,121,112,101,100,105,115, + 112,111,110,105,110,105,116,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,100, + 111,110,111,116,116,114,97,110,115,108,97,116,101,5,99,111,108,111,114,4, + 2,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,0,11,102,114,97,109,101,46,100,117,109,109, + 121,2,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,3,247,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,19,9,98,111,117,110,100,115,95,99,121,2, + 16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,7,118,105,115,105,98,108,101,8,10,111,110,115,101,116, + 118,97,108,117,101,7,24,100,111,110,111,116,116,114,97,110,115,108,97,116, + 101,111,110,115,101,116,118,97,108,117,101,0,0,15,116,109,101,109,111,100, + 105,97,108,111,103,101,100,105,116,7,99,111,109,109,101,110,116,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,119,105,100,116,104, + 2,13,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,4, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,11, + 1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,124,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18, + 111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,11, + 102,111,110,116,46,104,101,105,103,104,116,2,12,9,102,111,110,116,46,110, + 97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,11,102,111,110, + 116,46,120,115,99,97,108,101,2,1,10,102,111,110,116,46,100,117,109,109, + 121,2,0,10,111,110,115,101,116,118,97,108,117,101,7,17,99,111,109,109, + 101,110,116,111,110,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,15,116,109,101,109,111,100,105,97, + 108,111,103,101,100,105,116,5,118,97,108,117,101,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,0,5,99,111,108,111,114,4,7,0,0, + 144,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105, + 109,97,103,101,110,114,2,17,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,111,112,116,105,111,110,115,11,13,102,98,111,95,105,110,118,105,115, + 105,98,108,101,12,102,98,111,95,100,105,115,97,98,108,101,100,0,8,116, + 97,98,111,114,100,101,114,2,5,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,136,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,102,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111, + 111,110,101,115,99,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,18,111, + 101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,4,102,108,97,116,5,99,111,108,111, + 114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,4,102,108,97,116,11,102,114,97,109,101,46,100,117,109,109,121,2,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,1,2,19,2,2,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,9,8,98,111,117,110,100,115,95,121,2,5, + 9,98,111,117,110,100,115,95,99,120,2,32,9,98,111,117,110,100,115,95, + 99,121,2,16,8,115,116,97,116,102,105,108,101,7,21,112,114,111,106,101, + 99,116,102,111,46,112,114,111,106,101,99,116,115,116,97,116,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,13,102,111,114,109,97,116, + 99,104,97,110,103,101,100,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,10,115,116,114,105,110,103,111,110,108,121,5,99,111,108,111,114,4, + 3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11, + 115,116,114,105,110,103,32,111,110,108,121,11,102,114,97,109,101,46,100,117, + 109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,59,2,2,0,8,116,97,98,111,114,100,101, + 114,2,2,8,98,111,117,110,100,115,95,120,2,57,8,98,111,117,110,100, + 115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2,72,9,98,111, + 117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,21, + 112,114,111,106,101,99,116,102,111,46,112,114,111,106,101,99,116,115,116,97, + 116,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,13,102,111,114, + 109,97,116,99,104,97,110,103,101,100,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,4,110,111,110,116,5,99,111,108,111,114,4,3,0,0, + 128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5,110,111,32, + 78,84,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,36, + 2,2,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,3,153,0,8,98,111,117,110,100,115,95,121,2,5,9,98,111, + 117,110,100,115,95,99,120,2,49,9,98,111,117,110,100,115,95,99,121,2, + 16,8,115,116,97,116,102,105,108,101,7,21,112,114,111,106,101,99,116,102, + 111,46,112,114,111,106,101,99,116,115,116,97,116,13,111,110,100,97,116,97, + 101,110,116,101,114,101,100,7,13,102,111,114,109,97,116,99,104,97,110,103, + 101,100,10,111,110,115,101,116,118,97,108,117,101,7,14,110,111,110,116,111, + 110,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,6,110,116,111,110,108,121,5,99,111,108,111,114,4,3,0, + 0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,7,78,84, + 32,111,110,108,121,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,44,2,2,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111, + 117,110,100,115,95,120,3,233,0,8,98,111,117,110,100,115,95,121,2,5, + 9,98,111,117,110,100,115,95,99,120,2,57,9,98,111,117,110,100,115,95, + 99,121,2,16,8,115,116,97,116,102,105,108,101,7,21,112,114,111,106,101, + 99,116,102,111,46,112,114,111,106,101,99,116,115,116,97,116,13,111,110,100, + 97,116,97,101,110,116,101,114,101,100,7,13,102,111,114,109,97,116,99,104, + 97,110,103,101,100,10,111,110,115,101,116,118,97,108,117,101,7,16,110,116, + 111,110,108,121,111,110,115,101,116,118,97,108,117,101,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,7,99,111,108,111,114,111,110,5,99,111, + 108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,10,83,104,111,119,32,67,111,108,111,114,11,102,114,97,109,101, + 46,100,117,109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,67,2,2,0,8,116,97,98,111, + 114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,65,1,8,98, + 111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2, + 80,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105, + 108,101,7,21,112,114,111,106,101,99,116,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7, + 20,115,104,111,119,99,111,108,111,114,100,97,116,97,101,110,116,101,114,101, + 100,5,118,97,108,117,101,9,0,0,9,116,115,116,97,116,102,105,108,101, + 12,109,97,105,110,115,116,97,116,102,105,108,101,8,102,105,108,101,110,97, + 109,101,6,11,109,115,101,105,49,56,110,46,115,116,97,7,102,105,108,101, + 100,105,114,6,11,34,94,47,46,109,115,101,105,100,101,34,7,111,112,116, + 105,111,110,115,11,14,115,102,111,95,99,114,101,97,116,101,112,97,116,104, + 15,115,102,111,95,116,114,97,110,115,97,99,116,105,111,110,17,115,102,111, + 95,97,99,116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95,97, + 99,116,105,118,97,116,111,114,119,114,105,116,101,0,12,111,110,115,116,97, + 116,117,112,100,97,116,101,7,14,109,97,105,110,117,112,100,97,116,101,115, + 116,97,116,4,108,101,102,116,2,16,3,116,111,112,2,96,0,0,9,116, + 109,97,105,110,109,101,110,117,9,109,97,105,110,109,101,110,117,49,8,111, + 110,117,112,100,97,116,101,7,14,109,97,105,110,109,101,110,117,117,112,100, + 97,116,101,12,102,97,99,101,116,101,109,112,108,97,116,101,7,7,99,111, + 110,118,101,120,120,17,105,116,101,109,102,114,97,109,101,116,101,109,112,108, + 97,116,101,7,13,109,101,110,117,105,116,101,109,102,114,97,109,101,23,105, + 116,101,109,102,114,97,109,101,116,101,109,112,108,97,116,101,97,99,116,105, + 118,101,7,13,109,101,110,117,105,116,101,109,102,114,97,109,101,18,109,101, + 110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,10,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7, + 99,97,112,116,105,111,110,6,5,38,79,112,101,110,4,110,97,109,101,6, + 4,111,112,101,110,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,13,111, + 110,112,114,111,106,101,99,116,111,112,101,110,0,1,7,99,97,112,116,105, + 111,110,6,5,38,83,97,118,101,4,110,97,109,101,6,4,115,97,118,101, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,111,110,101,120,101,99,117,116,101,7,13,111,110,112,114,111,106, + 101,99,116,115,97,118,101,0,1,7,99,97,112,116,105,111,110,6,8,83, + 97,118,101,32,38,97,115,4,110,97,109,101,6,6,115,97,118,101,97,115, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,111,110,101,120,101,99,117,116,101,7,13,115,97,118,101,97,115, + 101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,4,38, + 78,101,119,4,110,97,109,101,6,3,110,101,119,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120, + 101,99,117,116,101,7,13,110,101,119,112,114,111,106,101,99,116,101,120,101, + 0,1,7,99,97,112,116,105,111,110,6,5,38,69,100,105,116,4,110,97, + 109,101,6,4,101,100,105,116,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,13,111,110,112,114,111,106,101,99,116,101,100,105,116,0,1,7,99,97, + 112,116,105,111,110,6,7,38,73,109,112,111,114,116,4,110,97,109,101,6, + 6,105,109,112,111,114,116,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 15,105,109,112,111,114,116,111,110,101,120,101,99,117,116,101,0,1,7,99, + 97,112,116,105,111,110,6,7,69,120,38,112,111,114,116,4,110,97,109,101, + 6,6,101,120,112,111,114,116,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,15,101,120,112,111,114,116,111,110,101,120,101,99,117,116,101,0,1,7, + 99,97,112,116,105,111,110,6,5,38,77,97,107,101,4,110,97,109,101,6, + 4,109,97,107,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,13,109, + 97,107,101,111,110,101,120,101,99,117,116,101,0,1,13,115,117,98,109,101, + 110,117,46,99,111,117,110,116,2,2,13,115,117,98,109,101,110,117,46,105, + 116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,6,38,65,98,111, + 117,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,8,97,98,111,117, + 116,101,120,101,0,1,7,99,97,112,116,105,111,110,6,18,38,67,111,110, + 102,105,103,117,114,101,32,77,83,69,105,49,56,110,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,18,99,111,110,102,105,103,117,114,101,111,110,101, + 120,101,99,117,116,101,0,0,7,99,97,112,116,105,111,110,6,9,83,101, + 38,116,116,105,110,103,115,4,110,97,109,101,6,8,115,101,116,116,105,110, + 103,115,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,5,69,38, + 120,105,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,7,101,120,105, + 116,101,120,101,0,0,4,108,101,102,116,3,0,1,3,116,111,112,3,160, + 0,0,0,11,116,102,105,108,101,100,105,97,108,111,103,17,112,114,111,106, + 101,99,116,102,105,108,101,100,105,97,108,111,103,8,115,116,97,116,102,105, + 108,101,7,12,109,97,105,110,115,116,97,116,102,105,108,101,26,99,111,110, + 116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116,46,100, + 97,116,97,1,1,6,17,84,114,97,110,115,108,97,116,101,32,112,114,111, + 106,101,99,116,6,5,42,46,116,114,112,0,0,21,99,111,110,116,114,111, + 108,108,101,114,46,100,101,102,97,117,108,116,101,120,116,6,3,116,114,112, + 18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11, + 14,102,100,111,95,99,104,101,99,107,101,120,105,115,116,9,102,100,111,95, + 99,104,100,105,114,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97, + 112,116,105,111,110,111,112,101,110,6,22,79,112,101,110,32,116,114,97,110, + 115,108,97,116,101,32,112,114,111,106,101,99,116,22,99,111,110,116,114,111, + 108,108,101,114,46,99,97,112,116,105,111,110,115,97,118,101,6,22,83,97, + 118,101,32,116,114,97,110,115,108,97,116,101,32,112,114,111,106,101,99,116, + 4,108,101,102,116,2,120,3,116,111,112,3,156,0,0,0,11,116,116,104, + 114,101,97,100,99,111,109,112,10,116,104,114,101,97,100,99,111,109,112,9, + 111,110,101,120,101,99,117,116,101,7,11,109,97,107,101,101,120,101,99,117, + 116,101,11,111,110,116,101,114,109,105,110,97,116,101,7,13,109,97,107,101, + 116,101,114,109,105,110,97,116,101,4,108,101,102,116,3,209,0,3,116,111, + 112,2,115,0,0,9,116,102,97,99,101,99,111,109,112,7,99,111,110,118, + 101,120,120,23,116,101,109,112,108,97,116,101,46,102,97,100,101,95,112,111, + 115,46,99,111,117,110,116,2,2,23,116,101,109,112,108,97,116,101,46,102, + 97,100,101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,25, + 116,101,109,112,108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46, + 99,111,117,110,116,2,2,25,116,101,109,112,108,97,116,101,46,102,97,100, + 101,95,99,111,108,111,114,46,105,116,101,109,115,1,4,4,0,0,160,4, + 5,0,0,160,0,23,116,101,109,112,108,97,116,101,46,102,97,100,101,95, + 100,105,114,101,99,116,105,111,110,7,5,103,100,95,117,112,4,108,101,102, + 116,3,129,1,3,116,111,112,2,103,0,0,9,116,102,97,99,101,99,111, + 109,112,7,99,111,110,118,101,120,121,23,116,101,109,112,108,97,116,101,46, + 102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101,109, + 112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115, + 1,2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100,101, + 95,99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112,108, + 97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115, + 1,4,4,0,0,160,4,5,0,0,160,0,23,116,101,109,112,108,97,116, + 101,46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,7,103,100, + 95,108,101,102,116,4,108,101,102,116,3,225,1,3,116,111,112,2,103,0, + 0,9,116,102,97,99,101,99,111,109,112,8,99,111,110,99,97,118,101,120, + 23,116,101,109,112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,99, + 111,117,110,116,2,2,23,116,101,109,112,108,97,116,101,46,102,97,100,101, + 95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,25,116,101,109, + 112,108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,99,111,117, + 110,116,2,2,25,116,101,109,112,108,97,116,101,46,102,97,100,101,95,99, + 111,108,111,114,46,105,116,101,109,115,1,4,4,0,0,160,4,5,0,0, + 160,0,23,116,101,109,112,108,97,116,101,46,102,97,100,101,95,100,105,114, + 101,99,116,105,111,110,7,7,103,100,95,100,111,119,110,4,108,101,102,116, + 3,129,1,3,116,111,112,3,135,0,0,0,9,116,102,97,99,101,99,111, + 109,112,8,99,111,110,99,97,118,101,121,23,116,101,109,112,108,97,116,101, + 46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101, + 109,112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109, + 115,1,2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100, + 101,95,99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112, + 108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109, + 115,1,4,4,0,0,160,4,5,0,0,160,0,4,108,101,102,116,3,225, + 1,3,116,111,112,3,135,0,0,0,14,116,115,121,115,101,110,118,109,97, + 110,97,103,101,114,6,115,121,115,101,110,118,4,108,101,102,116,2,24,3, + 116,111,112,3,160,0,0,0,16,116,115,116,114,105,110,103,99,111,110,116, + 97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97, + 1,6,4,110,97,109,101,6,4,116,121,112,101,6,11,110,111,116,114,97, + 110,115,108,97,116,101,6,7,99,111,109,109,101,110,116,6,5,118,97,108, + 117,101,6,12,60,110,111,32,112,114,111,106,101,99,116,62,6,19,67,97, + 110,32,110,111,116,32,114,101,97,100,32,109,111,100,117,108,101,6,21,78, + 101,119,32,116,114,97,110,115,108,97,116,101,32,112,114,111,106,101,99,116, + 6,10,69,120,101,99,32,101,114,114,111,114,6,6,77,97,107,105,110,103, + 6,17,111,118,101,114,119,114,105,116,101,115,32,105,116,115,101,108,102,6, + 5,69,82,82,79,82,6,11,70,105,110,105,115,104,101,100,32,79,75,6, + 17,67,111,110,102,105,103,117,114,101,32,77,83,69,105,49,56,110,6,16, + 68,97,116,97,32,104,97,115,32,99,104,97,110,103,101,100,6,19,68,111, + 32,121,111,117,32,119,105,115,104,32,116,111,32,115,97,118,101,6,12,67, + 79,78,70,73,82,77,65,84,73,79,78,6,12,67,108,111,115,101,32,101, + 114,114,111,114,58,6,0,0,4,108,101,102,116,2,64,3,116,111,112,3, + 200,0,0,0,15,116,115,107,105,110,99,111,110,116,114,111,108,108,101,114, + 16,116,115,107,105,110,99,111,110,116,114,111,108,108,101,114,49,9,101,120, + 116,101,110,100,101,114,115,2,0,4,108,101,102,116,3,176,0,3,116,111, + 112,3,224,0,0,0,11,116,98,105,116,109,97,112,99,111,109,112,7,105, + 99,111,110,98,109,112,17,98,105,116,109,97,112,46,111,114,105,103,102,111, + 114,109,97,116,6,3,112,110,103,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,224,8,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,172,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,235, + 235,235,1,234,234,234,1,233,233,233,1,232,232,232,1,231,231,231,1,230, + 230,230,1,228,228,228,1,227,227,227,1,221,224,221,1,224,211,204,1,227, + 203,192,1,228,199,185,1,226,197,183,1,224,200,189,1,222,206,201,1,218, + 218,218,1,217,217,217,1,216,216,216,1,214,214,214,1,213,213,213,1,212, + 212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,235,235,235,1,234, + 234,234,1,233,233,233,1,232,232,232,1,231,231,231,1,230,230,230,1,229, + 219,215,1,231,198,182,1,121,166,90,1,100,167,82,1,206,165,102,1,228, + 165,106,1,227,164,105,1,227,166,112,1,195,166,111,1,95,161,75,1,188, + 180,146,1,218,208,204,1,214,214,214,1,213,213,213,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,235,235,235,1,234,234,234,1,233, + 233,233,1,190,213,189,1,182,209,180,1,233,204,190,1,232,181,146,1,230, + 167,108,1,126,169,84,1,247,251,247,1,103,160,58,1,214,155,24,1,217, + 155,24,1,160,153,35,1,128,180,103,1,193,224,191,1,168,155,78,1,224, + 173,138,1,220,191,177,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,235,235,235,1,234,234,234,1,233,233,233,1,132, + 188,129,1,158,204,152,1,112,164,80,1,188,156,64,1,219,156,33,1,115, + 161,47,1,254,255,254,1,214,234,211,1,118,158,31,1,180,157,0,1,137, + 189,116,1,255,255,255,1,162,203,145,1,187,152,27,1,222,156,71,1,224, + 164,115,1,221,183,163,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,235,235,235,1,234,234,234,1,233,233,233,1,185,184,140,1,181, + 213,172,1,250,253,250,1,152,196,132,1,109,161,48,1,125,154,14,1,180, + 214,168,1,255,255,255,1,158,202,141,1,102,158,32,1,235,245,234,1,255, + 255,255,1,123,180,93,1,206,159,0,1,213,155,5,1,221,154,55,1,223, + 162,108,1,189,174,140,1,101,171,97,1,154,189,152,1,209,209,209,1,235, + 235,235,1,234,234,234,1,236,207,193,1,234,174,125,1,117,168,78,1,255, + 255,255,2,254,255,254,1,140,192,118,1,82,161,52,1,251,253,251,1,239, + 247,239,1,80,160,50,1,255,255,255,2,105,168,60,1,106,165,55,1,124, + 158,30,1,196,154,0,1,118,156,56,1,145,192,131,1,189,221,186,1,151, + 188,150,1,209,209,209,1,235,235,235,1,235,225,221,1,235,184,149,1,228, + 162,77,1,161,154,17,1,162,202,140,1,255,255,255,3,105,171,67,1,128, + 186,103,1,226,240,225,1,81,159,36,1,116,178,80,1,139,193,121,1,89, + 158,34,1,104,175,84,1,94,158,38,1,125,180,95,1,237,246,237,1,239, + 247,239,1,104,163,79,1,210,202,196,1,209,209,209,1,235,235,235,1,236, + 203,187,1,233,170,111,1,220,157,34,1,152,156,13,1,96,155,30,1,183, + 215,171,1,255,255,255,2,95,169,61,1,108,196,71,1,94,171,53,1,119, + 192,47,1,32,248,223,1,81,220,136,1,109,164,19,1,104,172,70,1,223, + 238,220,1,255,255,255,1,253,254,253,1,109,168,74,1,207,158,94,1,217, + 184,168,1,209,209,209,1,235,235,235,1,236,188,158,1,228,162,77,1,211, + 156,0,1,104,170,74,1,191,219,180,1,83,159,44,1,147,197,128,1,155, + 203,139,1,65,207,121,1,14,255,249,1,79,230,144,1,82,228,139,1,14, + 255,249,1,41,244,207,1,105,172,64,1,255,255,255,3,135,187,111,1,176, + 154,7,1,221,155,70,1,220,172,142,1,209,209,209,1,237,221,216,1,235, + 178,135,1,223,157,51,1,209,159,0,1,124,161,30,1,106,168,60,1,87, + 158,31,1,101,163,18,1,98,166,22,1,97,223,114,1,21,252,237,1,101, + 213,79,1,92,169,1,1,106,209,72,1,126,212,68,1,112,187,48,1,165, + 207,151,1,255,255,255,1,163,206,150,1,136,160,21,1,207,159,0,1,212, + 152,46,1,222,165,122,1,213,197,192,1,237,213,202,1,198,166,101,1,125, + 156,45,1,116,168,63,1,134,187,108,1,168,208,155,1,194,224,192,1,218, + 236,217,1,113,182,95,1,136,191,8,1,141,211,28,1,50,152,0,1,6, + 128,0,1,62,157,0,1,49,242,191,1,19,253,242,1,106,188,64,1,86, + 162,44,1,96,165,55,1,124,177,83,1,131,184,101,1,128,181,100,1,113, + 161,76,1,172,180,143,1,238,209,195,1,72,151,50,1,214,234,213,1,255, + 255,255,5,105,176,68,1,39,246,207,1,29,250,222,1,84,182,11,1,29, + 142,0,1,106,183,0,1,62,237,166,1,20,253,240,1,102,181,43,1,138, + 194,124,1,255,255,255,2,249,252,249,1,181,214,170,1,109,169,86,1,178, + 177,143,1,238,209,195,1,216,167,102,1,125,154,36,1,113,171,74,1,206, + 229,200,1,255,255,255,2,164,207,151,1,112,176,29,1,21,252,235,1,14, + 255,249,1,109,225,69,1,79,235,125,1,78,233,134,1,133,198,21,1,91, + 178,60,1,109,173,55,1,85,162,45,1,115,172,63,1,116,173,71,1,114, + 159,37,1,168,150,21,1,221,159,100,1,216,187,173,1,237,213,202,1,234, + 173,119,1,220,157,34,1,203,160,0,1,134,159,15,1,108,168,57,1,87, + 163,53,1,87,166,54,1,60,154,37,1,131,197,22,1,97,193,53,1,103, + 198,49,1,14,255,249,2,86,186,71,1,247,251,247,1,255,255,255,1,212, + 233,209,1,98,166,56,1,168,163,5,1,207,160,0,1,217,154,31,1,222, + 161,107,1,215,191,180,1,237,221,216,1,235,178,135,1,223,157,51,1,209, + 159,0,1,202,165,0,1,140,164,16,1,128,186,102,1,245,250,245,1,83, + 165,55,1,136,194,117,1,210,232,209,1,105,178,76,1,108,218,82,1,109, + 202,57,1,88,168,49,1,252,254,252,1,255,255,255,2,252,254,252,1,141, + 191,119,1,133,158,28,1,219,153,47,1,222,165,122,1,213,197,192,1,235, + 235,235,1,236,188,158,1,228,162,77,1,212,156,0,1,157,158,11,1,141, + 192,117,1,255,255,255,1,154,201,136,1,100,172,71,1,255,255,255,2,197, + 225,193,1,106,171,7,1,109,180,93,1,92,170,62,1,89,165,57,1,237, + 246,236,1,255,255,255,3,186,217,175,1,139,156,63,1,220,172,142,1,209, + 209,209,1,235,235,235,1,236,203,187,1,233,170,111,1,180,155,34,1,127, + 181,98,1,255,255,255,1,250,253,250,1,89,162,51,1,207,230,203,1,255, + 255,255,2,132,190,106,1,109,165,2,1,151,201,134,1,251,253,251,1,117, + 181,91,1,83,159,42,1,121,179,90,1,149,196,128,1,185,218,179,1,215, + 235,214,1,151,199,143,1,151,171,119,1,209,209,209,1,235,235,235,1,235, + 225,221,1,220,180,140,1,114,172,88,1,250,253,250,1,211,233,210,1,118, + 180,96,1,93,162,54,1,255,255,255,2,193,222,184,1,83,161,43,1,84, + 162,46,1,114,177,82,1,255,255,255,2,109,172,72,1,200,166,0,1,187, + 158,0,1,166,149,5,1,151,153,57,1,135,161,91,1,189,194,176,1,209, + 209,209,1,235,235,235,1,234,234,234,1,186,191,151,1,102,162,74,1,121, + 157,57,1,146,152,13,1,143,152,5,1,171,209,159,1,255,255,255,1,160, + 203,143,1,108,161,28,1,140,191,117,1,125,182,94,1,107,164,39,1,246, + 251,246,1,255,255,255,1,133,186,107,1,198,160,0,1,212,156,0,1,220, + 153,54,1,223,163,114,1,218,189,175,1,210,210,210,1,209,209,209,1,235, + 235,235,1,234,234,234,1,233,233,233,1,236,198,178,1,232,171,117,1,225, + 158,59,1,116,157,41,1,225,240,223,1,107,168,66,1,159,160,9,1,132, + 160,20,1,224,239,223,1,141,191,118,1,153,159,3,1,158,201,141,1,255, + 255,255,1,169,208,156,1,178,151,4,1,221,154,55,1,223,162,108,1,220, + 182,162,1,211,211,211,1,210,210,210,1,209,209,209,1,235,235,235,1,234, + 234,234,1,233,233,233,1,232,232,232,1,235,197,177,1,233,173,124,1,154, + 159,66,1,114,155,46,1,205,155,0,1,209,159,0,1,162,155,6,1,164, + 206,155,1,107,159,39,1,207,160,0,1,109,162,49,1,252,254,252,1,196, + 225,194,1,167,150,54,1,224,164,115,1,221,183,163,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,235,235,235,1,234,234,234,1,233, + 233,233,1,232,232,232,1,231,231,231,1,233,204,190,1,232,181,146,1,230, + 167,108,1,226,160,75,1,222,156,50,1,216,156,32,1,125,152,33,1,202, + 153,22,1,218,155,32,1,185,152,44,1,154,198,139,1,177,212,170,1,182, + 165,111,1,220,191,177,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,235,235,235,1,234,234,234,1,233,233,233,1,232, + 232,232,1,231,231,231,1,230,230,230,1,229,219,215,1,231,198,182,1,231, + 183,153,1,230,173,130,1,229,168,114,1,228,165,106,1,227,164,105,1,227, + 166,112,1,227,170,127,1,120,165,90,1,102,169,91,1,203,203,190,1,214, + 214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,235,235,235,1,234,234,234,1,233,233,233,1,232,232,232,1,231, + 231,231,1,230,230,230,1,228,228,228,1,227,227,227,1,226,226,226,1,228, + 212,207,1,227,203,192,1,228,199,185,1,226,197,183,1,224,200,189,1,222, + 206,201,1,205,213,205,1,204,212,204,1,216,216,216,1,214,214,214,1,213, + 213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,4, + 108,101,102,116,3,40,1,3,116,111,112,3,224,0,0,0,10,116,102,114, + 97,109,101,99,111,109,112,13,109,101,110,117,105,116,101,109,102,114,97,109, + 101,15,116,101,109,112,108,97,116,101,46,108,101,118,101,108,111,2,255,15, + 116,101,109,112,108,97,116,101,46,108,101,118,101,108,105,2,1,4,108,101, + 102,116,3,0,1,3,116,111,112,3,192,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/tools/i18n/messagesform.mfm b/mseide-msegui/tools/i18n/messagesform.mfm new file mode 100644 index 0000000..78a5523 --- /dev/null +++ b/mseide-msegui/tools/i18n/messagesform.mfm @@ -0,0 +1,51 @@ +object messagesfo: tmessagesfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 298 + bounds_y = 263 + bounds_cx = 421 + bounds_cy = 234 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.bounds = ( + 0 + 0 + 421 + 234 + ) + options = [fo_closeonesc, fo_closeonenter, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + caption = 'Make Language Units' + onclosequery = formclosquery + moduleclassname = 'tmseform' + object twidgetgrid1: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_focusbackonesc, ow_destroywidgets] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 421 + bounds_cy = 234 + anchors = [] + datacols.count = 1 + datacols.options = [co_fill, co_savestate] + datacols.items = < + item[messages] + width = 1024 + options = [co_fill, co_savestate] + widthmin = 1024 + widgetname = 'messages' + dataclass = tgridrichstringdatalist + end> + datarowlinewidth = 0 + datarowheight = 16 + reffontheight = 14 + object messages: tterminal + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 1024 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + options = [teo_readonly] + reffontheight = 14 + end + end +end diff --git a/mseide-msegui/tools/i18n/messagesform.pas b/mseide-msegui/tools/i18n/messagesform.pas new file mode 100644 index 0000000..b52927c --- /dev/null +++ b/mseide-msegui/tools/i18n/messagesform.pas @@ -0,0 +1,31 @@ +unit messagesform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseguiglob,msegui,mseclasses,mseforms,mseterminal,msewidgetgrid,msethreadcomp, + mseglob; + +type + tmessagesfo = class(tmseform) + messages: tterminal; + twidgetgrid1: twidgetgrid; + procedure formclosquery(const sender: tcustommseform; + var amodalresult: modalresultty); + public + running: boolean; + end; +var + messagesfo: tmessagesfo; +implementation +uses + messagesform_mfm; + +procedure tmessagesfo.formclosquery(const sender: tcustommseform; + var amodalresult: modalresultty); +begin + if running then begin + amodalresult:= mr_none; + end; +end; + +end. diff --git a/mseide-msegui/tools/i18n/messagesform_mfm.pas b/mseide-msegui/tools/i18n/messagesform_mfm.pas new file mode 100644 index 0000000..aee1bf0 --- /dev/null +++ b/mseide-msegui/tools/i18n/messagesform_mfm.pas @@ -0,0 +1,74 @@ +unit messagesform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,messagesform; + +const + objdata: record size: integer; data: array[0..1121] of byte end = + (size: 1122; data: ( + 84,80,70,48,11,116,109,101,115,115,97,103,101,115,102,111,10,109,101,115, + 115,97,103,101,115,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,42,1,8,98, + 111,117,110,100,115,95,121,3,7,1,9,98,111,117,110,100,115,95,99,120, + 3,165,1,9,98,111,117,110,100,115,95,99,121,3,234,0,23,99,111,110, + 116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117, + 115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,16,99,111,110,116,97,105,110, + 101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,165,1,3,234,0, + 0,7,111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111, + 110,101,115,99,15,102,111,95,99,108,111,115,101,111,110,101,110,116,101,114, + 15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95, + 97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118, + 101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,7,99, + 97,112,116,105,111,110,6,19,77,97,107,101,32,76,97,110,103,117,97,103, + 101,32,85,110,105,116,115,12,111,110,99,108,111,115,101,113,117,101,114,121, + 7,13,102,111,114,109,99,108,111,115,113,117,101,114,121,15,109,111,100,117, + 108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114, + 109,0,11,116,119,105,100,103,101,116,103,114,105,100,12,116,119,105,100,103, + 101,116,103,114,105,100,49,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,165,1,9,98,111,117,110,100, + 115,95,99,121,3,234,0,7,97,110,99,104,111,114,115,11,0,14,100,97, + 116,97,99,111,108,115,46,99,111,117,110,116,2,1,16,100,97,116,97,99, + 111,108,115,46,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,8,109,101,115,115,97,103,101,115, + 1,5,119,105,100,116,104,3,0,4,7,111,112,116,105,111,110,115,11,7, + 99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,8,119,105,100,116,104,109,105,110,3,0,4,10,119,105,100,103,101,116, + 110,97,109,101,6,8,109,101,115,115,97,103,101,115,9,100,97,116,97,99, + 108,97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,0,16,100,97,116,97,114,111,119,108, + 105,110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104,101, + 105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,9,116,116,101,114,109,105,110,97,108,8,109,101,115,115,97,103, + 101,115,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,0,4,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107, + 118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,7, + 111,112,116,105,111,110,115,11,12,116,101,111,95,114,101,97,100,111,110,108, + 121,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,0) + ); + +initialization + registerobjectdata(@objdata,tmessagesfo,''); +end. diff --git a/mseide-msegui/tools/i18n/msei18n.ico b/mseide-msegui/tools/i18n/msei18n.ico new file mode 100644 index 0000000..4eb945d Binary files /dev/null and b/mseide-msegui/tools/i18n/msei18n.ico differ diff --git a/mseide-msegui/tools/i18n/msei18n.pas b/mseide-msegui/tools/i18n/msei18n.pas new file mode 100644 index 0000000..7f5dffd --- /dev/null +++ b/mseide-msegui/tools/i18n/msei18n.pas @@ -0,0 +1,35 @@ +{ MSEtools Copyright (c) 1999-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program msei18n; +{$ifdef FPC} + {$mode objfpc}{$h+} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +{$ifdef mswindows} + {$R msei18n.res} +{$endif} + +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui, + main,messagesform,project; + +begin + application.createForm(tmainfo,mainfo); + application.createForm(tmessagesfo,messagesfo); + application.run; +end. + diff --git a/mseide-msegui/tools/i18n/msei18n.prj b/mseide-msegui/tools/i18n/msei18n.prj new file mode 100644 index 0000000..2a6f3b8 --- /dev/null +++ b/mseide-msegui/tools/i18n/msei18n.prj @@ -0,0 +1,1076 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +[projectoptions] +projectdir=/D:/mse/packs/standard/git/mseide-msegui/tools/i18n +projectfilename=/D:/mse/packs/standard/git/mseide-msegui/tools/i18n/msei18n.prj +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +codetemplatedirs=1 + ${TEMPLATEDIR} +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +componenthints=1 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +pairmarkcolor=-2147483642 +pairmaxrowcount=100 +editfontantialiased=1 +editmarkbrackets=1 +editmarkpairwords=0 +backupfilecount=2 +encoding=1 +eolstyle=1 +trimtrailingwhitespace=0 +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +fpcgdbworkaround=1 +mainfile=msei18n.pas +targetfile=msei18n${EXEEXT} +makecommand=${COMPILER} +makedir= +unitdirs=4 + + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +reversepathorder=0 +makeoptpurpose=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=4 + 983103 + 65599 + 196671 + 65599 +uid=0 +macroon=0 +macronames=0 +macrovalues=0 +groupcomments=6 + + + + + + +fontalias=0 +fontnames=0 +fontancestors=0 +fontoptions=0 +fontheights=0 +fontwidths=0 +fontxscales=0 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +toolmenus=0 +toolfiles=0 +toolparams=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +settingsfile= +settingsautoload=0 +settingsautosave=0 +settingseditor=0 +settingsdebugger=0 +settingsmake=1 +settingsmacros=0 +settingsfontalias=0 +settingsusercolors=0 +settingsformatmacros=0 +settingstemplates=0 +settingstools=0 +settingsstorage=0 +settingscomponentstore=0 +settingsprojecttree=0 +settingslayout=0 +messageoutputfile= +modulenames=2 + MAINFO + PROJECTFO +moduletypes=2 + TMAINFO + TPROJECTFO +modulefiles=2 + /D:/mse/packs/standard/git/mseide-msegui/tools/i18n/main.mfm + /D:/mse/packs/standard/git/mseide-msegui/tools/i18n/project.mfm +macrogroup=0 +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +units= + ( + a=0,8228,6,Pascal Units + ) +cmodules= + ( + a=0,8228,6,C Modules + ) +files= + ( + a=0,8228,6,Text Files + ) +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +[componentstore] +storedir=/D:/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=2 + 0,0 + 0,-1073741823 +bookmarks0=0 +bookmarks1=0 +sourcefiles=2 + /D:/mse/packs/standard/git/mseide-msegui/tools/i18n/main.pas + /home/mse/packs/standard/git/mseide-msegui/tools/i18n/project.pas +relpaths=2 + main.pas + project.pas +ismoduletexts=2 + 0 + 0 +modules=2 + /D:/mse/packs/standard/git/mseide-msegui/tools/i18n/main.mfm + /D:/mse/packs/standard/git/mseide-msegui/tools/i18n/project.mfm +moduleoptions=2 + 0 + 0 +visiblemodules=2 + -1 + -1 +nomenumodules=2 + 0 + 0 +[sourcefo.tabwidget] +tabsize=118 +firsttab=0 +index=0 +[layout] +windowlayout=589 + [mainfo.openform] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/tools/i18n/project.mfm + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/tools/i18n/project.mfm + filefilterindex=0 + filefilter=*.mfm + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/tools/i18n/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=268582016 + [mainfo] + splitdir=0 + useroptions=838860923 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=8 + y=30 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=805322875 + stackedunder=cpuc86_64fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=805322859 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=268451947 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=805322859 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=332 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=149 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=172 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=268451947 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=805322859 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=805322875 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=18 + + + + + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=116 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=805355627 + parent=mainfo.panel1.container + visible=0 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=675 + rcy=605 + [componentstorefo] + splitdir=0 + useroptions=805331067 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/proj/dist/mseguidist/test/msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/proj/dist/mseguidist/test/msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/proj/dist/mseguidist/test/msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/proj/dist/mseguidist/test/msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=805331051 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=30 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=268460139 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=30 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=805322857 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=605 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpuc86_64fo] + irqoff=0 + splitdir=0 + useroptions=268451947 + stackedunder=watchpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=183 + y=113 + cx=352 + cy=277 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=838893035 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=8 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=838893035 + stackedunder=_mse_projectfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=805322875 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=283 + cx=634 + cy=390 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_projectfo_mse_] + splitdir=0 + useroptions=805322875 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=149 + y=167 + cx=693 + cy=501 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/tools/i18n/msei18n.rc b/mseide-msegui/tools/i18n/msei18n.rc new file mode 100644 index 0000000..9e726a9 --- /dev/null +++ b/mseide-msegui/tools/i18n/msei18n.rc @@ -0,0 +1,24 @@ +MAINICON ICON "msei18n.ico" +1 VERSIONINFO +FILEVERSION 2,8,0,0 +PRODUCTVERSION 2,8,0,0 +FILEFLAGSMASK 0 +FILEOS 0x40000 +FILETYPE 1 +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "CompanyName","" + VALUE "FileDescription","MSEi18n" + VALUE "FileVersion","2.8.0.0" + VALUE "InternalName","msei18n" + VALUE "LegalCopyright","2011 (c) Martin Schreiber" + VALUE "OriginalFilename","MSEi18n" + VALUE "ProductName","MSEi18n" + VALUE "ProductVersion","2.8.0" + } + } +} + diff --git a/mseide-msegui/tools/i18n/msei18n.res b/mseide-msegui/tools/i18n/msei18n.res new file mode 100644 index 0000000..ad8a2e0 Binary files /dev/null and b/mseide-msegui/tools/i18n/msei18n.res differ diff --git a/mseide-msegui/tools/i18n/msei18n.svg b/mseide-msegui/tools/i18n/msei18n.svg new file mode 100644 index 0000000..ab04050 --- /dev/null +++ b/mseide-msegui/tools/i18n/msei18n.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/tools/i18n/msei18n_24.png b/mseide-msegui/tools/i18n/msei18n_24.png new file mode 100644 index 0000000..b356f02 Binary files /dev/null and b/mseide-msegui/tools/i18n/msei18n_24.png differ diff --git a/mseide-msegui/tools/i18n/msei18n_32.png b/mseide-msegui/tools/i18n/msei18n_32.png new file mode 100644 index 0000000..9a3d32c Binary files /dev/null and b/mseide-msegui/tools/i18n/msei18n_32.png differ diff --git a/mseide-msegui/tools/i18n/msei18n_48.png b/mseide-msegui/tools/i18n/msei18n_48.png new file mode 100644 index 0000000..8163514 Binary files /dev/null and b/mseide-msegui/tools/i18n/msei18n_48.png differ diff --git a/mseide-msegui/tools/i18n/msei18n_64.png b/mseide-msegui/tools/i18n/msei18n_64.png new file mode 100644 index 0000000..0bee5d1 Binary files /dev/null and b/mseide-msegui/tools/i18n/msei18n_64.png differ diff --git a/mseide-msegui/tools/i18n/mseresourceparser.pas b/mseide-msegui/tools/i18n/mseresourceparser.pas new file mode 100644 index 0000000..e164c4e --- /dev/null +++ b/mseide-msegui/tools/i18n/mseresourceparser.pas @@ -0,0 +1,885 @@ +{ MSEtools Copyright (c) 1999-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit mseresourceparser; +{$ifdef FPC} + {$mode objfpc}{$h+} +{$endif} + +interface +uses + classes,mclasses,msetypes,mselist,msedatanodes,mselistbrowser,mseparser, + msestrings,msestream,mseclasses; + +type + + propinfoty = record + name: string; + stringvalue: string; + msestringvalue: msestring; + donottranslate: boolean; + comment: msestring; + variants: msestringarty; + case valuetype: tvaluetype of + vastring,valstring,vautf8string,vawstring: + (coffset: integer; clen: integer); //filemarker for const units + vaInt8,vaint16,vaint32: (integervalue: integer); + vaint64: (int64value: int64); + vasingle,vacurrency,vaextended,vadate: (realvalue: real); + vafalse,vatrue: (booleanvalue: boolean); + end; + + tpropinfonode = class; + tpropinfoitem = class; + + tpropinfonode = class(ttreeeditnode) + private + alang: integer; + protected + function getitems(const index: integer): tpropinfonode; + procedure setitems(const index: integer; const Value: tpropinfonode); + function treenodeclass: treenodeclassty; override; + function listitemclass: treelistitemclassty; override; + procedure nodetoitem(const listitem: ttreelistitem); override; + procedure dotransferlang(const sender: ttreenode); + procedure dodeletelang(const sender: ttreenode); + procedure doinitlang(const sender: ttreenode); + public + info: propinfoty; + procedure clear; override; + function newnode: tpropinfonode; + function rootstring(separator: char = '.'; withrootnode: boolean = false): string; + function valuetext: msestring; + procedure transferlang(lang: integer); + procedure deletelang(lang: integer); + procedure initlang(acount: integer); + function findsubnode(const nametree: string): tpropinfonode; + property items[const index: integer]: tpropinfonode read getitems write setitems; default; + end; + + tpropinfoitem = class(ttreelistedititem) + public + node: tpropinfonode; + end; + +const + identmaxlen = 30; + identbucketcount = 256; +type + identstringty = string[identmaxlen+1]; //terminated with #0 + identinfoty = record + name: identstringty; + ident: integer; + end; + pidentinfoty = ^identinfoty; + identinfoarty = array of identinfoty; + +procedure readprops(const stream: tstream; const node: tpropinfonode); +procedure writeprops(const stream: tstream; const node: tpropinfonode); +procedure writeconsts(const instream,outstream: tstream; + const node: tpropinfonode); +procedure writeresources(const instream,outstream: tstream; + const node: tpropinfonode); +procedure writefpcresourcestrings(const outstream: ttextstream; + const node: tpropinfonode); + +implementation +uses + sysutils,mseformatstr,msearrayutils,typinfo,msebits,msewidgets,msejson, + msefileutils,msesys; + +type + treader1 = class(treader); + twriter1 = class(twriter); + {$ifdef FPC} + tbinaryobjectwriter1 = class(tbinaryobjectwriter); + {$endif} + +{ tpropinfonode } + +function tpropinfonode.getitems(const index: integer): tpropinfonode; +begin + result:= tpropinfonode(inherited getitems(index)); +end; + +procedure tpropinfonode.setitems(const index: integer; + const Value: tpropinfonode); +begin + inherited setitems(index,value); +end; + +function tpropinfonode.listitemclass: treelistitemclassty; +begin + result:= tpropinfoitem; +end; + +function tpropinfonode.treenodeclass: treenodeclassty; +begin + result:= tpropinfonode; +end; + +function tpropinfonode.newnode: tpropinfonode; +begin + result:= tpropinfonode.Create; + add(result); +end; + +function tpropinfonode.valuetext: msestring; +begin + case info.valuetype of + vaint8,vaint16,vaint32: begin + result:= inttostrmse(info.integervalue); + end; + vaint64: begin + result:= inttostrmse(info.int64value); + end; + vaSingle,vaCurrency,vaDate,vaExtended: begin + result:= realtostrmse(info.realvalue); + end; +// vaset,vaident,vastring,valstring: begin + vaset,vaident: begin + result:= msestring(info.stringvalue); + end; + vastring,valstring,vawstring,vautf8string: begin + result:= info.msestringvalue; + end; + else begin + result:= ''; + end; + end; +end; + +function tpropinfonode.rootstring(separator: char = '.'; withrootnode: boolean = false): string; +begin + if (fparent <> nil) or withrootnode then begin + result:= info.name; + if fparent <> nil then begin + if (tpropinfonode(fparent).fparent <> nil) or withrootnode then begin + result:= tpropinfonode(fparent).rootstring(separator) + separator + result; + end; + end; + end + else begin + result:= ''; + end; +end; + +function tpropinfonode.findsubnode(const nametree: string): tpropinfonode; +var + ar1: stringarty; + anode,anode1: tpropinfonode; + int1,int2: integer; +begin + ar1:= nil; + splitstring(nametree,ar1,','); + if (high(ar1) >= 0) and (info.name = ar1[0]) then begin + anode:= self; + anode1:= self; + for int1:= 1 to high(ar1) do begin + anode1:= nil; + for int2:= 0 to anode.fcount - 1 do begin + anode1:= tpropinfonode(anode.fitems[int2]); + if anode1.info.name = ar1[int1] then begin + break; + end + else begin + anode1:= nil; + end; + end; + if anode1 = nil then begin + break; + end + else begin + anode:= anode1; + end; + end; + result:= anode1; + end + else begin + result:= nil; + end; +end; + +procedure tpropinfonode.nodetoitem(const listitem: ttreelistitem); +begin + with tpropinfoitem(listitem) do begin + fcaption:= msestring(self.info.name); + node:= self; + end; +end; +{ +procedure tpropinfonode.itemtonode(const listitem: ttreelistitem); +begin + with tpropinfoitem(listitem) do begin + self.info:= info; + end; +end; +} +procedure tpropinfonode.clear; +begin + inherited; + finalize(info); + fillchar(info,sizeof(info),0); +end; + +procedure readprops(const stream: tstream; const node: tpropinfonode); + +var + reader: treader; + + procedure readobj(const node: tpropinfonode); + procedure readpropdat(const node: tpropinfonode); + procedure readpropval(const node: tpropinfonode); + var + str1,str2: string; + int1,int2: integer; + aitem: tpropinfonode; + begin + with treader1(reader) do begin + with node.info do begin + valuetype:= nextvalue; + case valuetype of + vaNull,vanil: begin + readvalue;{ no value field, just an identifier } + end; + vaFalse, vaTrue: begin + readvalue;{ no value field, just an identifier } + booleanvalue:= valuetype = vatrue; + end; + vaBinary: begin + readvalue; + {$ifdef FPC} + stringvalue:= driver.readstring(valstring); + {$else} + Read(int1, SizeOf(int1)); + setlength(stringvalue,int1); + read(pchar(pointer(stringvalue))^,int1); + {$endif} + end; + vaList: begin + readvalue; + int1:= 0; + while not endoflist do begin + aitem:= node.newnode; + aitem.info.name:= inttostr(int1)+':'; + readpropval(aitem); + inc(int1); + end; + readlistend; + end; + vaInt8,vaint16,vaint32: begin + integervalue:= readinteger; + end; + vaInt64: begin + int64value:= readint64; + end; + vaSingle: begin + realvalue:= readsingle; + end; + vaCurrency: begin + realvalue:= readcurrency; + end; + vaDate: begin + realvalue:= readdate; + end; + vaExtended: begin + realvalue:= readfloat; + end; + vaIdent: begin + readvalue; + stringvalue:= {$ifdef FPC}driver.{$endif}readstr; + end; + vastring,valstring,vaWString,vautf8string: begin + msestringvalue:= treader_readmsestring(reader); + end; + vaSet: begin + readvalue; + str1:= ''; + while true do begin + str2:= {$ifdef FPC}driver.{$endif}readstr; + if str2 = '' then begin + break; + end; + str1:= str1 + str2 + ','; + end; + stringvalue:= '['+copy(str1,1,length(str1)-1)+']'; + end; + vaCollection: begin + readvalue; + int2:= 0; + while not EndOfList do begin + aitem:= node.newnode; + aitem.info.valuetype:= valist; + if NextValue in [vaInt8, vaInt16, vaInt32] then begin + int1:= readinteger; + aitem.info.name:= inttostr(int1); + end + else begin + if NextValue in [vaident] then begin + aitem.info.name:= readident; + end + else begin + aitem.info.name:= inttostr(int2)+':'; + end; + end; + readlistbegin; + while not endoflist do begin + readpropdat(aitem.newnode); + end; + readlistend; + inc(int2); + end; + ReadListEnd; + end; + end; + end; + end; + end; + + begin //writepropdat + with treader1(reader) do begin + {$ifdef FPC} + node.info.name:= driver.beginproperty; + {$else} + node.info.name:= readstr; + {$endif} + readpropval(node); + end; + end; + + var + compclass,compname: string; + flags: tfilerflags; + pos: integer; + + begin //writeobj + with treader1(reader) do begin + {$ifdef FPC} + driver.begincomponent(flags,pos,compclass,compname); + {$else} + pos:= 0; + ReadPrefix(flags,pos); + compclass := ReadStr; + compname := ReadStr; + {$endif} + node.info.name:= compname; + node.info.stringvalue:= compclass; + node.info.integervalue:= (pos shl 3) or {$ifdef FPC}longword{$else}byte{$endif}(flags) and $07; + while not endoflist do begin + readpropdat(node.newnode); + end; + ReadListEnd; + while not EndOfList do begin; + readobj(node.newnode); + end; + ReadListEnd; + end; + end; + +begin //readprops + reader:= treader.Create(stream,4096); + try + with treader1(reader) do begin + {$ifdef FPC} + driver.beginrootcomponent; + {$else} + readsignature; + {$endif} + readobj(node); + end; + finally + reader.Free; + end; +end; + +procedure writeprops(const stream: tstream; const node: tpropinfonode); + +var + writer: twritermse; + + procedure writeobj(const node: tpropinfonode); + procedure writepropdat(const node: tpropinfonode); + procedure writepropval(const node: tpropinfonode); + type + setinfoty = record + kind: ttypekind; + namelen: byte; + data: ttypedata; + end; + var + int1,int2: integer; + ar1: stringarty; + str1: string; + {$ifdef FPC} +// setinfo: setinfoty; +// po1: ^setinfoty; +// po2: ^shortstring; +// lwo1: longword; + {$endif} + begin + {$ifdef FPC}{$warnings off}{$endif} + with twriter1(writer) do begin + {$ifdef FPC}{$warnings on}{$endif} + with node.info do begin + case valuetype of + vaNull: begin + writeident('Null'); + end; + vaNil: begin + writeident('nil'); + end; + vaFalse: begin + writeident('False'); + end; + vaTrue: begin + writeident('True'); + end; + vaBinary: begin + {$ifdef FPC} + driver.writebinary(stringvalue[1],length(stringvalue)); + {$else} + writevalue(vabinary); + int1:= length(stringvalue); + write(int1, sizeof(int1)); + if int1 <> 0 then begin + write(stringvalue[1],int1); + end; + {$endif} + end; + vaList: begin + writelistbegin; + for int1:= 0 to node.fcount - 1 do begin + writepropval(node[int1]); + end; + writelistend; + end; + vaInt8,vaint16,vaint32: begin + writeinteger(integervalue); + end; + vaInt64: begin + writeinteger(int64value); + end; + vaSingle: begin + writesingle(realvalue); + end; + vaCurrency: begin + writecurrency(realvalue); + end; + vaDate: begin + writedate(realvalue); + end; + vaExtended: begin + writefloat(realvalue); + end; + vaIdent: begin + writeident(stringvalue); + end; + vaString,vaLString,vaWString,vautf8string: begin + twriter_writemsestring(writer,msestringvalue); + end; + vaSet: begin + ar1:= nil; + str1:= trim(stringvalue); + str1:= copy(stringvalue,2,length(str1)-2); + splitstring(str1,ar1,',',true); + {$ifdef FPC} + with tbinaryobjectwriter1(driver) do begin + writevalue(vaset); + for int1:= 0 to high(ar1) do begin + writestr(ar1[int1]); + end; + writestr(''); + end; + {$else} + writevalue(vaset); + for int1:= 0 to high(ar1) do begin + writestr(ar1[int1]); + end; + writestr(''); + {$endif} + end; + vaCollection: begin + {$ifdef FPC} + driver.begincollection; + {$else} + writevalue(vacollection); + {$endif} + for int1:= 0 to node.fcount - 1 do begin + with node[int1] do begin + if (info.name <> '') then begin + if info.name[1] in ['0'..'9'] then begin + if (info.name[length(info.name)] <> ':') then begin + writeinteger(strtoint(info.name)); + end; + end + else begin + writeident(info.name); + end; + end; + end; + writelistbegin; + for int2:= 0 to node[int1].fcount-1 do begin + writepropdat(node[int1][int2]); + end; + writelistend; + end; + writeListEnd; + end; + end; + end; + end; + end; + + begin //writepropdat + {$ifdef FPC}{$warnings off}{$endif} + with twriter1(writer) do begin + {$ifdef FPC}{$warnings on}{$endif} + {$ifdef FPC} + driver.beginproperty(node.info.name); + {$else} + writestr(node.info.name); + {$endif} + writepropval(node); + end; + end; + + var + compclass,compname: string; + flags: tfilerflags; + pos: integer; + int1: integer; + {$ifdef FPC} + Prefix: Byte; + {$endif} + begin //writeobj + {$ifdef FPC}{$warnings off}{$endif} + with twriter1(writer) do begin + {$ifdef FPC}{$warnings on}{$endif} + compname:= node.info.name; + compclass:= node.info.stringvalue; + flags:= tfilerflags({$ifdef FPC}longword{$else}byte{$endif}(node.info.integervalue and $07)); + pos:= node.info.integervalue shr 3; + {$ifdef FPC} + with tbinaryobjectwriter1(driver) do begin + if not FSignatureWritten then begin + Write(FilerSignature, SizeOf(FilerSignature)); + FSignatureWritten := True; + end; + { Only write the flags if they are needed! } + if Flags <> [] then begin + Prefix := Integer(Flags) or $f0; + Write(Prefix, 1); + if ffChildPos in Flags then begin + WriteInteger(pos); + end; + end; + writestr(compclass); + writestr(compname); + end; + {$else} + writeprefix(flags,pos); + writestr(compclass); + writestr(compname); + {$endif} + int1:= 0; + while int1 < node.fcount do begin + with node[int1] do begin + if info.valuetype = vanull then begin + break; + end; + end; + writepropdat(node[int1]); + inc(int1); + end; + writelistend; + while int1 < node.fcount do begin + writeobj(node[int1]); + inc(int1); + end; + writeListEnd; + end; + end; + +begin //writeprops + writer:= twritermse.Create(stream,4096); + try + {$ifdef FPC}{$warnings off}{$endif} + with twriter1(writer) do begin + {$ifdef FPC}{$warnings on}{$endif} + {$ifdef FPC} +// driver.beginrootcomponent; //signature written by begincomponent + {$else} + writesignature; + {$endif} + writeobj(node); + end; + finally + writer.Free; + end; +end; + +procedure writeconsts(const instream,outstream: tstream; + const node: tpropinfonode); +var + int1: integer; + str1: string; +begin + for int1:= 0 to node.fcount - 1 do begin + with tpropinfonode(node.fitems[int1]).info do begin + case valuetype of +// vaString,vaLString: begin +// str1:= stringtopascalstring(stringvalue); +// end; + vastring,valstring,vaWString,vautf8string: begin + str1:= stringtopascalstring(msestringvalue); + end; + else begin + str1:= ''; + end; + end; + if str1 <> '' then begin + if coffset <> instream.Position then begin + outstream.CopyFrom(instream,coffset-instream.position); + end; + instream.Position:= coffset + clen; + outstream.WriteBuffer(str1[1],length(str1)); + end; + end; + end; + outstream.CopyFrom(instream,instream.Size-instream.position); +end; + +function comppos(const l,r): integer; +begin + result:= tpropinfonode(l).info.coffset - tpropinfonode(r).info.coffset; +end; + +procedure writeresources(const instream,outstream: tstream; + const node: tpropinfonode); +var + int1,int2,int3: integer; + ar1: pointerarty; + str1: string; +begin + int2:= 0; + for int1:= 0 to node.fcount - 1 do begin + inc(int2,tpropinfonode(node.fitems[int1]).fcount); + end; + setlength(ar1,int2); + int2:= 0; + for int1:= 0 to node.fcount - 1 do begin + int3:= tpropinfonode(node.fitems[int1]).fcount; + if int3 > 0 then begin + move(tpropinfonode(node.fitems[int1]).fitems[0],ar1[int2],int3 * sizeof(pointer)); + inc(int2,int3); + end; + end; + sortarray(ar1,{$ifdef FPC}@{$endif}comppos); + for int1:= 0 to high(ar1) do begin + with tpropinfonode(ar1[int1]).info do begin + case valuetype of +// vaString,vaLString: begin +// str1:= stringtocstring(stringvalue); +// end; + vastring,valstring,vaWString,vautf8string: begin + str1:= stringtocstring(msestringvalue); + end; + else begin + str1:= ''; + end; + end; + if str1 <> '' then begin + if coffset <> instream.Position then begin + outstream.CopyFrom(instream,coffset-instream.position); + end; + instream.Position:= coffset + clen; + outstream.WriteBuffer(str1[1],length(str1)); + end; + end; + end; + outstream.CopyFrom(instream,instream.Size-instream.position); +end; + +procedure getjsonresourcestrings(var json: jsonvaluety; + const node: tpropinfonode); +var + node1,node2: tpropinfonode; + mstr1: msestring; + int1: int32; +begin + for int1:= 0 to node.count - 1 do begin + node1:= node[int1]; + with node1.info do begin + if valuetype = vawstring then begin + node2:= tpropinfonode(node1.fparent); + mstr1:= msestring(name); + repeat + mstr1:= msestring(node2.info.name) + '.' + mstr1; + node2:= tpropinfonode(node2.fparent); + until (node2.fparent = nil) or (node2.parent.parent = nil); + jsonadditems(jsonaddvalues(json,[nil])^, + ['hash','name','value'], + [hash(stringtoutf8ansi(msestringvalue)),mstr1, + msestringvalue]); + end + else begin + getjsonresourcestrings(json,node1); + end; + end; + end; +end; + +procedure writefpcresourcestrings(const outstream: ttextstream; + const node: tpropinfonode); +var + int1: integer; + node1,node2: tpropinfonode; + str1,str2: string; + mstr1: msestring; + po1: pmsechar; + i1: int32; + json: jsonvaluety; + pj: pjsonvaluety; +begin + if fileext(outstream.filename) = 'rsj' then begin + jsonvalueinit(json); + try + pj:= jsonadditems(json,['version','strings'],[1,nil]); + getjsonresourcestrings(pj^,node); + syserror(jsonencode(json,outstream)); + finally + jsonvaluefree(json); + end; + end + else begin + for int1:= 0 to node.count - 1 do begin + node1:= node[int1]; + with node1.info do begin + if valuetype = vawstring then begin + node2:= tpropinfonode(node1.fparent); + str1:= name; + repeat + str1:= node2.info.name + '.' + str1; + node2:= tpropinfonode(node2.fparent); + until (node2.fparent = nil) or (node2.parent.parent = nil); + outstream.writeln(''); + outstream.writeln('# hash value = '+ + inttostr(hash(ansistring(msestringvalue)))); + str2:= ansistring(msestringvalue); + setlength(mstr1,length(str2)); + po1:= pmsechar(mstr1); + for i1:= 1 to length(mstr1) do begin + po1^:= msechar(byte(str2[i1])); //use locale encoding + inc(po1); + end; + outstream.writeln(str1+'='+stringtopascalstring(mstr1)); + end + else begin + writefpcresourcestrings(outstream,node1); + end; + end; + end; + end; +end; + +procedure tpropinfonode.dotransferlang(const sender: ttreenode); + + procedure doerror(mess: string); + begin + showmessage(msestring(mess)); + end; + +begin + with tpropinfonode(sender).info do begin + if not donottranslate and (alang <= high(variants)) then begin + case valuetype of +// vaString,vaLString: begin +// stringvalue:= variants[alang]; +// end; + vastring,valstring,vaWString,vautf8string: begin + msestringvalue:= variants[alang]; + end; + vaint8,vaint16,vaint32: begin + if variants[alang] <> '' then begin + try + integervalue:= strtoint(variants[alang]); + except + doerror('Invalid integer'); + end; + end; + end; + vaint64: begin +// result:= inttostr(info.int64value); + end; + vaSingle,vaCurrency,vaDate,vaExtended: begin +// result:= floattostr(info.realvalue); + end; + end; + end; + end; +end; + +procedure tpropinfonode.transferlang(lang: integer); +begin + alang:= lang; + iterate({$ifdef FPC}@{$endif}dotransferlang); +end; + +procedure tpropinfonode.dodeletelang(const sender: ttreenode); +begin + with tpropinfonode(sender).info do begin + if high(variants) >= alang then begin + deleteitem(variants,alang); + end; + end; +end; + +procedure tpropinfonode.deletelang(lang: integer); +begin + alang:= lang; + iterate({$ifdef FPC}@{$endif}dodeletelang); +end; + +procedure tpropinfonode.doinitlang(const sender: ttreenode); +var + int1: integer; +begin + with tpropinfonode(sender).info do begin + case valuetype of +// vaString,vaLString: begin +// setlength(variants,alang); +// for int1:= 0 to alang - 1 do begin +// variants[int1]:= stringvalue; +// end; +// end; + vastring,valstring,vaWString,vautf8string: begin + setlength(variants,alang); + for int1:= 0 to alang - 1 do begin + variants[int1]:= msestringvalue; + end; + end; + end; + end; +end; + +procedure tpropinfonode.initlang(acount: integer); +begin + alang:= acount; + iterate({$ifdef FPC}@{$endif}doinitlang); +end; + + +end. diff --git a/mseide-msegui/tools/i18n/project.mfm b/mseide-msegui/tools/i18n/project.mfm new file mode 100644 index 0000000..3ba5ef2 --- /dev/null +++ b/mseide-msegui/tools/i18n/project.mfm @@ -0,0 +1,452 @@ +object projectfo: tprojectfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 149 + bounds_y = 167 + bounds_cx = 683 + bounds_cy = 501 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = childscaled + container.bounds = ( + 0 + 0 + 683 + 501 + ) + options = [fo_closeonesc, fo_savepos, fo_savestate] + statfile = projectstat + caption = 'Edit Translate Project' + onlayout = childscaled + moduleclassname = 'tmseform' + object impexpencoding: tenumtypeedit + frame.caption = 'Encoding for imp/exp files' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.outerframe = ( + 0 + 0 + 126 + 0 + ) + taborder = 6 + bounds_x = 8 + bounds_y = 476 + bounds_cx = 226 + bounds_cy = 19 + anchors = [an_left, an_bottom] + statfile = projectstat + valuedefault = 1 + min = 0 + max = 2 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = impexpencinit + reffontheight = 13 + end + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_focusbackonesc, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + taborder = 4 + bounds_x = 0 + bounds_y = 264 + bounds_cx = 683 + bounds_cy = 104 + anchors = [an_top] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 15 + captions.count = 3 + captions.items = < + item + caption = 'Rootname' + textflags = [] + end + item + caption = 'File' + textflags = [] + end + item + caption = 'Kind' + textflags = [] + end> + end> + datacols.count = 3 + datacols.items = < + item[rootname] + width = 71 + options = [co_readonly, co_savevalue, co_savestate] + widgetname = 'rootname' + dataclass = tgridmsestringdatalist + end + item[filename] + width = 479 + options = [co_fill, co_savevalue] + widgetname = 'filename' + dataclass = tgridmsestringdatalist + end + item[filekind] + width = 126 + widgetname = 'filekind' + dataclass = tgridenumdatalist + end> + datarowheight = 15 + statfile = projectstat + reffontheight = 13 + object rootname: tstringedit + optionswidget1 = [ow1_fontglyphheight] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 71 + bounds_cy = 15 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 13 + end + object filename: tfilenameedit + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 72 + bounds_y = 0 + bounds_cx = 479 + bounds_cy = 15 + ondataentered = filenamedataentered + controller.historymaxcount = 0 + controller.captionopen = 'Select unit or form file' + reffontheight = 13 + end + object filekind: tenumtypeedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -2147483646 + taborder = 3 + visible = False + bounds_x = 552 + bounds_y = 0 + bounds_cx = 126 + bounds_cy = 15 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = filekindoninit + reffontheight = 13 + end + end + object datafilename: tfilenameedit + frame.caption = 'Datafile' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 16 + 0 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 683 + bounds_cy = 35 + anchors = [an_top] + statfile = projectstat + controller.filterlist.data = ( + ( + 'MSEi18n Data Files' + '*.trd ' + ) + ( + 'All files' + '"*"' + ) + ) + controller.defaultext = 'trd' + controller.historymaxcount = 0 + reffontheight = 13 + end + object grid2: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_focusbackonesc, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + taborder = 5 + bounds_x = 0 + bounds_y = 376 + bounds_cx = 683 + bounds_cy = 90 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 15 + captions.count = 2 + captions.items = < + item + caption = 'Language' + textflags = [] + end + item + caption = 'Directory' + textflags = [] + end> + end> + datacols.count = 2 + datacols.items = < + item[lang] + width = 94 + widgetname = 'lang' + dataclass = tgridmsestringdatalist + end + item[dir] + width = 583 + options = [co_fill, co_savevalue] + widgetname = 'dir' + dataclass = tgridmsestringdatalist + end> + datarowheight = 15 + statfile = projectstat + onrowsdeleted = langdeleted + reffontheight = 13 + object lang: tstringedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 94 + bounds_cy = 15 + reffontheight = 13 + end + object dir: tdirdropdownedit + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -2147483646 + taborder = 2 + visible = False + bounds_x = 95 + bounds_y = 0 + bounds_cx = 583 + bounds_cy = 15 + reffontheight = 13 + end + end + object splitter: tsplitter + color = -1879048189 + taborder = 8 + bounds_x = 0 + bounds_y = 368 + bounds_cx = 683 + bounds_cy = 3 + anchors = [an_top] + options = [spo_vmove, spo_vprop] + linktop = grid + linkbottom = grid2 + end + object makecommand: tmemodialogedit + frame.caption = 'Make command' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 16 + 0 + 0 + ) + taborder = 2 + onshowhint = showhintexe + bounds_x = 0 + bounds_y = 144 + bounds_cx = 644 + bounds_cy = 35 + anchors = [an_left, an_top, an_right] + statfile = projectstat + value = '${COMPILER} -Fu${MSELIBDIR}i18n ${LIBFILE}' + onsetvalue = makecommandsetvalue + reffontheight = 13 + end + object makeon: tbooleanedit + frame.caption = 'on' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 16 + 1 + 0 + ) + taborder = 3 + bounds_x = 656 + bounds_y = 149 + bounds_cx = 14 + bounds_cy = 29 + anchors = [an_top, an_right] + statfile = projectstat + value = True + end + object ok: tbutton + taborder = 7 + bounds_x = 558 + bounds_y = 473 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object cancel: tbutton + bounds_x = 622 + bounds_y = 473 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object destname: tstringedit + frame.caption = 'Destination Basename (empty = Datafile name)' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 16 + 0 + 0 + ) + taborder = 9 + bounds_x = 0 + bounds_y = 56 + bounds_cx = 683 + bounds_cy = 35 + anchors = [an_top] + statfile = projectstat + reffontheight = 13 + end + object beforemake: tmemodialogedit + frame.caption = 'Before make' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 16 + 0 + 0 + ) + taborder = 10 + onshowhint = showhintexe + bounds_x = 0 + bounds_y = 104 + bounds_cx = 683 + bounds_cy = 35 + anchors = [an_top] + statfile = projectstat + reffontheight = 13 + end + object aftermake: tmemodialogedit + frame.caption = 'After make' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 16 + 0 + 0 + ) + taborder = 11 + onshowhint = showhintexe + bounds_x = 0 + bounds_y = 184 + bounds_cx = 683 + bounds_cy = 35 + anchors = [an_top] + statfile = projectstat + reffontheight = 13 + end + object projectstat: tstatfile + onstatupdate = projectstatonupdatestat + onstatbeforewrite = projectstatonbeforewritestat + onstatafterread = projectstatonafterreadstat + left = 128 + top = 56 + end + object impexpfiledialog: tfiledialog + statfile = projectstat + controller.filename = 'default.csv' + controller.filterlist.data = ( + ( + 'Data exchange files' + '*.csv' + ) + ) + controller.defaultext = 'csv' + controller.historymaxcount = 0 + controller.captionopen = 'Open import file' + controller.captionsave = 'Save export file' + left = 240 + top = 56 + end +end diff --git a/mseide-msegui/tools/i18n/project.pas b/mseide-msegui/tools/i18n/project.pas new file mode 100644 index 0000000..7eeba8f --- /dev/null +++ b/mseide-msegui/tools/i18n/project.pas @@ -0,0 +1,158 @@ +{ MSEtools Copyright (c) 1999-2006 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit project; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msewidgetgrid,msefiledialog,msestat,msestatfile,msegraphedits, + msedataedits,msesimplewidgets,msesplitter,msegui,msestrings,msedbedit,msegrids, + msetypes,mseedit,mseglob,mseguiglob,mseifiglob,msemenus,msememodialog; + +type + tprojectfo = class(tmseform) + projectstat: tstatfile; + grid: twidgetgrid; + filename: tfilenameedit; + filekind: tenumtypeedit; + datafilename: tfilenameedit; + impexpfiledialog: tfiledialog; + grid2: twidgetgrid; + lang: tstringedit; + dir: tdirdropdownedit; + rootname: tstringedit; + splitter: tsplitter; + makecommand: tmemodialogedit; + makeon: tbooleanedit; + ok: tbutton; + cancel: tbutton; + impexpencoding: tenumtypeedit; + destname: tstringedit; + beforemake: tmemodialogedit; + aftermake: tmemodialogedit; + procedure projectstatonupdatestat(const sender: TObject; + const filer: tstatfiler); + procedure projectstatonafterreadstat(const sender: tobject); + procedure filekindoninit(const sender: tenumtypeedit); + procedure childscaled(const sender: TObject); + procedure showhintexe(const sender: TObject; var info: hintinfoty); + procedure makecommandsetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); + procedure impexpencinit(const sender: tenumtypeedit); + procedure langdeleted(const sender: tcustomgrid; const aindex: integer; + const acount: integer); + procedure projectstatonbeforewritestat(const sender: TObject); + procedure filenamedataentered(const sender: TObject); + public + // colwidths: integerarty; + end; + +var + projectfo: tprojectfo; + +implementation + +uses + main,project_mfm,msesysenv,msesettings,msestream,msemacros; +const + defaultmakecommand = '${COMPILER} -Fu${MSELIBDIR}i18n -FE.. -FU. ${LIBFILE}'; + +procedure tprojectfo.filekindoninit(const sender: tenumtypeedit); +begin + tenumtypeedit(sender).typeinfopo:= typeinfo(resfilekindty); +end; + +procedure tprojectfo.projectstatonbeforewritestat(const sender: TObject); +//var +// int1: integer; +begin +{ + setlength(colwidths,mainfo.grid.datacols.count - variantshift); + for int1:= 0 to high(colwidths) do begin + colwidths[int1]:= mainfo.grid.datacols[int1+variantshift].width; + end; +} +end; + +procedure tprojectfo.projectstatonupdatestat(const sender: TObject; + const filer: tstatfiler); +var + int1: integer; +begin + int1:= mainfo.grid.datacols.count; + filer.updatevalue('colcount',int1); + mainfo.grid.datacols.count:= int1+variantshift; +end; + +procedure tprojectfo.projectstatonafterreadstat(const sender: tobject); +//var +// int1: integer; +begin + try + mainfo.loadproject; + except + application.handleexception(nil); + end; + { + for int1:= 0 to high(colwidths) do begin + if int1 >= mainfo.grid.datacols.count + variantshift then begin + break; + end; + mainfo.grid.datacols[int1+variantshift].width:= colwidths[int1]; + end; +} +end; + +procedure tprojectfo.childscaled(const sender: TObject); +begin + placeyorder(0,[0,0,2,0,0,0,0,4],[datafilename,destname, + beforemake,makecommand,aftermake, + grid,splitter,grid2,ok],4); + aligny(wam_center,[makecommand,makeon]); + aligny(wam_center,[ok,cancel,impexpencoding]); +end; + +procedure tprojectfo.showhintexe(const sender: TObject; var info: hintinfoty); +begin + info.caption:= expandmacros(makecommand.value,getsyssettingsmacros); +end; + +procedure tprojectfo.makecommandsetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + if avalue = '' then begin + avalue:= defaultmakecommand; + end; +end; + +procedure tprojectfo.impexpencinit(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(charencodingty); +end; + +procedure tprojectfo.langdeleted(const sender: tcustomgrid; const aindex: integer; + const acount: integer); +begin + rootnode.deletelang(aindex); +end; + +procedure tprojectfo.filenamedataentered(const sender: TObject); +begin + rootname.value:= ''; +end; + +end. diff --git a/mseide-msegui/tools/i18n/project_mfm.pas b/mseide-msegui/tools/i18n/project_mfm.pas new file mode 100644 index 0000000..4d4ec07 --- /dev/null +++ b/mseide-msegui/tools/i18n/project_mfm.pas @@ -0,0 +1,396 @@ +unit project_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,project; + +const + objdata: record size: integer; data: array[0..7571] of byte end = + (size: 7572; data: ( + 84,80,70,48,10,116,112,114,111,106,101,99,116,102,111,9,112,114,111,106, + 101,99,116,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117, + 98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,149,0,8,98,111,117, + 110,100,115,95,121,3,167,0,9,98,111,117,110,100,115,95,99,120,3,171, + 2,9,98,111,117,110,100,115,95,99,121,3,245,1,23,99,111,110,116,97, + 105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11, + 111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101, + 116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,18,99,111,110,116,97,105,110,101,114,46, + 111,110,108,97,121,111,117,116,7,11,99,104,105,108,100,115,99,97,108,101, + 100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,171,2,3,245,1,0,7,111,112,116,105,111,110,115,11,13, + 102,111,95,99,108,111,115,101,111,110,101,115,99,10,102,111,95,115,97,118, + 101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115, + 116,97,116,102,105,108,101,7,11,112,114,111,106,101,99,116,115,116,97,116, + 7,99,97,112,116,105,111,110,6,22,69,100,105,116,32,84,114,97,110,115, + 108,97,116,101,32,80,114,111,106,101,99,116,8,111,110,108,97,121,111,117, + 116,7,11,99,104,105,108,100,115,99,97,108,101,100,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109, + 0,13,116,101,110,117,109,116,121,112,101,101,100,105,116,14,105,109,112,101, + 120,112,101,110,99,111,100,105,110,103,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,26,69,110,99,111,100,105,110,103,32,102,111,114,32,105, + 109,112,47,101,120,112,32,102,105,108,101,115,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,102, + 114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0, + 0,128,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,126,2,0,0,8,116,97,98,111,114,100,101,114,2,6, + 8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121, + 3,220,1,9,98,111,117,110,100,115,95,99,120,3,226,0,9,98,111,117, + 110,100,115,95,99,121,2,19,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,8,115,116,97, + 116,102,105,108,101,7,11,112,114,111,106,101,99,116,115,116,97,116,12,118, + 97,108,117,101,100,101,102,97,117,108,116,2,1,3,109,105,110,2,0,3, + 109,97,120,2,2,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46, + 99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,105,116,101,109,115,14,1,0,0,6,111,110,105,110,105,116,7,13, + 105,109,112,101,120,112,101,110,99,105,110,105,116,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,13,0,0,11,116,119,105,100,103,101,116,103, + 114,105,100,4,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115, + 99,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,3,8,1,9,98,111,117,110,100,115, + 95,99,120,3,171,2,9,98,111,117,110,100,115,95,99,121,2,104,7,97, + 110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,11,111,112,116,105, + 111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110, + 103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101, + 121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115, + 101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110, + 103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101, + 114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103, + 95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104, + 97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112, + 99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102,105, + 120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119, + 115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,15,14,99, + 97,112,116,105,111,110,115,46,99,111,117,110,116,2,3,14,99,97,112,116, + 105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110, + 6,8,82,111,111,116,110,97,109,101,9,116,101,120,116,102,108,97,103,115, + 11,0,0,1,7,99,97,112,116,105,111,110,6,4,70,105,108,101,9,116, + 101,120,116,102,108,97,103,115,11,0,0,1,7,99,97,112,116,105,111,110, + 6,4,75,105,110,100,9,116,101,120,116,102,108,97,103,115,11,0,0,0, + 0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,3,14, + 100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,114,111,111, + 116,110,97,109,101,1,5,119,105,100,116,104,2,71,7,111,112,116,105,111, + 110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,115, + 97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116, + 101,0,10,119,105,100,103,101,116,110,97,109,101,6,8,114,111,111,116,110, + 97,109,101,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100, + 109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,8, + 102,105,108,101,110,97,109,101,1,5,119,105,100,116,104,3,223,1,7,111, + 112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95,115, + 97,118,101,118,97,108,117,101,0,10,119,105,100,103,101,116,110,97,109,101, + 6,8,102,105,108,101,110,97,109,101,9,100,97,116,97,99,108,97,115,115, + 7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97, + 108,105,115,116,0,7,8,102,105,108,101,107,105,110,100,1,5,119,105,100, + 116,104,2,126,10,119,105,100,103,101,116,110,97,109,101,6,8,102,105,108, + 101,107,105,110,100,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114, + 105,100,101,110,117,109,100,97,116,97,108,105,115,116,0,0,13,100,97,116, + 97,114,111,119,104,101,105,103,104,116,2,15,8,115,116,97,116,102,105,108, + 101,7,11,112,114,111,106,101,99,116,115,116,97,116,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,13,0,11,116,115,116,114,105,110,103,101, + 100,105,116,8,114,111,111,116,110,97,109,101,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,5,99,111,108,111,114,4,7,0,0,144, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,71,9,98, + 111,117,110,100,115,95,99,121,2,15,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101, + 110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101, + 49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97,118,101, + 115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11, + 111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,13,116, + 102,105,108,101,110,97,109,101,101,100,105,116,8,102,105,108,101,110,97,109, + 101,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128, + 7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8, + 116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,223,1,9,98,111,117,110,100, + 115,95,99,121,2,15,13,111,110,100,97,116,97,101,110,116,101,114,101,100, + 7,19,102,105,108,101,110,97,109,101,100,97,116,97,101,110,116,101,114,101, + 100,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114,121, + 109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111,108,108,101, + 114,46,99,97,112,116,105,111,110,111,112,101,110,6,24,83,101,108,101,99, + 116,32,117,110,105,116,32,111,114,32,102,111,114,109,32,102,105,108,101,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,13,116,101, + 110,117,109,116,121,112,101,101,100,105,116,8,102,105,108,101,107,105,110,100, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114, + 4,2,0,0,128,8,116,97,98,111,114,100,101,114,2,3,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,40,2,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,126, + 9,98,111,117,110,100,115,95,99,121,2,15,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,6,111, + 110,105,110,105,116,7,14,102,105,108,101,107,105,110,100,111,110,105,110,105, + 116,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,0, + 13,116,102,105,108,101,110,97,109,101,101,100,105,116,12,100,97,116,97,102, + 105,108,101,110,97,109,101,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,8,68,97,116,97,102,105,108,101,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114, + 4,2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114, + 97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0, + 128,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101, + 110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,16,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,171,2,9,98,111, + 117,110,100,115,95,99,121,2,35,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,0,8,115,116,97,116,102,105,108,101,7,11,112,114,111, + 106,101,99,116,115,116,97,116,26,99,111,110,116,114,111,108,108,101,114,46, + 102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,18,77, + 83,69,105,49,56,110,32,68,97,116,97,32,70,105,108,101,115,6,6,42, + 46,116,114,100,32,0,1,6,9,65,108,108,32,102,105,108,101,115,6,3, + 34,42,34,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102, + 97,117,108,116,101,120,116,6,3,116,114,100,26,99,111,110,116,114,111,108, + 108,101,114,46,104,105,115,116,111,114,121,109,97,120,99,111,117,110,116,2, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,11, + 116,119,105,100,103,101,116,103,114,105,100,5,103,114,105,100,50,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,17,111,119,95,102,111,99,117, + 115,98,97,99,107,111,110,101,115,99,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,5,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3, + 120,1,9,98,111,117,110,100,115,95,99,120,3,171,2,9,98,111,117,110, + 100,115,95,99,121,2,90,7,97,110,99,104,111,114,115,11,6,97,110,95, + 116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111, + 110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103, + 12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121, + 114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101, + 114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95, + 97,117,116,111,97,112,112,101,110,100,10,111,103,95,119,114,97,112,99,111, + 108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,114, + 111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46, + 105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,15,14,99,97,112, + 116,105,111,110,115,46,99,111,117,110,116,2,2,14,99,97,112,116,105,111, + 110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,8, + 76,97,110,103,117,97,103,101,9,116,101,120,116,102,108,97,103,115,11,0, + 0,1,7,99,97,112,116,105,111,110,6,9,68,105,114,101,99,116,111,114, + 121,9,116,101,120,116,102,108,97,103,115,11,0,0,0,0,0,14,100,97, + 116,97,99,111,108,115,46,99,111,117,110,116,2,2,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,4,108,97,110,103,1,5,119,105, + 100,116,104,2,94,10,119,105,100,103,101,116,110,97,109,101,6,4,108,97, + 110,103,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,3,100, + 105,114,1,5,119,105,100,116,104,3,71,2,7,111,112,116,105,111,110,115, + 11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108, + 117,101,0,10,119,105,100,103,101,116,110,97,109,101,6,3,100,105,114,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97, + 114,111,119,104,101,105,103,104,116,2,15,8,115,116,97,116,102,105,108,101, + 7,11,112,114,111,106,101,99,116,115,116,97,116,13,111,110,114,111,119,115, + 100,101,108,101,116,101,100,7,11,108,97,110,103,100,101,108,101,116,101,100, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,11,116,115, + 116,114,105,110,103,101,100,105,116,4,108,97,110,103,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,2,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,94,9,98,111,117,110,100,115,95,99,121,2, + 15,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,16, + 116,100,105,114,100,114,111,112,100,111,119,110,101,100,105,116,3,100,105,114, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,2,0,0,128,8,116,97,98,111,114,100,101,114,2,2,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,95,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 3,71,2,9,98,111,117,110,100,115,95,99,121,2,15,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,13,0,0,0,9,116,115,112,108,105, + 116,116,101,114,8,115,112,108,105,116,116,101,114,5,99,111,108,111,114,4, + 3,0,0,144,8,116,97,98,111,114,100,101,114,2,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,112,1,9,98, + 111,117,110,100,115,95,99,120,3,171,2,9,98,111,117,110,100,115,95,99, + 121,2,3,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0, + 7,111,112,116,105,111,110,115,11,9,115,112,111,95,118,109,111,118,101,9, + 115,112,111,95,118,112,114,111,112,0,7,108,105,110,107,116,111,112,7,4, + 103,114,105,100,10,108,105,110,107,98,111,116,116,111,109,7,5,103,114,105, + 100,50,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100,105,116, + 11,109,97,107,101,99,111,109,109,97,110,100,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,12,77,97,107,101,32,99,111,109,109,97,110,100, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114,97,109, + 101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,16, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,10,111,110,115, + 104,111,119,104,105,110,116,7,11,115,104,111,119,104,105,110,116,101,120,101, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 3,144,0,9,98,111,117,110,100,115,95,99,120,3,132,2,9,98,111,117, + 110,100,115,95,99,121,2,35,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,8,115,116,97,116,102,105,108,101,7,11,112,114,111,106,101,99,116, + 115,116,97,116,5,118,97,108,117,101,6,42,36,123,67,79,77,80,73,76, + 69,82,125,32,45,70,117,36,123,77,83,69,76,73,66,68,73,82,125,105, + 49,56,110,32,36,123,76,73,66,70,73,76,69,125,10,111,110,115,101,116, + 118,97,108,117,101,7,19,109,97,107,101,99,111,109,109,97,110,100,115,101, + 116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,13,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,109,97, + 107,101,111,110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2, + 111,110,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,16,2,1,2,0,0,8,116,97,98,111,114,100, + 101,114,2,3,8,98,111,117,110,100,115,95,120,3,144,2,8,98,111,117, + 110,100,115,95,121,3,149,0,9,98,111,117,110,100,115,95,99,120,2,14, + 9,98,111,117,110,100,115,95,99,121,2,29,7,97,110,99,104,111,114,115, + 11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,8,115, + 116,97,116,102,105,108,101,7,11,112,114,111,106,101,99,116,115,116,97,116, + 5,118,97,108,117,101,9,0,0,7,116,98,117,116,116,111,110,2,111,107, + 8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120, + 3,46,2,8,98,111,117,110,100,115,95,121,3,217,1,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,7, + 97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110, + 95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97,115,95,100, + 101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117, + 108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7, + 99,97,112,116,105,111,110,6,2,79,75,11,109,111,100,97,108,114,101,115, + 117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117,116,116,111,110, + 6,99,97,110,99,101,108,8,98,111,117,110,100,115,95,120,3,110,2,8, + 98,111,117,110,100,115,95,121,3,217,1,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104, + 111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116, + 116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,6,67,97, + 110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114, + 95,99,97,110,99,101,108,0,0,11,116,115,116,114,105,110,103,101,100,105, + 116,8,100,101,115,116,110,97,109,101,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,44,68,101,115,116,105,110,97,116,105,111,110,32,66,97, + 115,101,110,97,109,101,32,40,101,109,112,116,121,32,61,32,68,97,116,97, + 102,105,108,101,32,110,97,109,101,41,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,16,2,0,2,0,0,8,116,97,98, + 111,114,100,101,114,2,9,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,56,9,98,111,117,110,100,115,95,99,120,3, + 171,2,9,98,111,117,110,100,115,95,99,121,2,35,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,0,8,115,116,97,116,102,105,108,101, + 7,11,112,114,111,106,101,99,116,115,116,97,116,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,13,0,0,15,116,109,101,109,111,100,105,97, + 108,111,103,101,100,105,116,10,98,101,102,111,114,101,109,97,107,101,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,11,66,101,102,111,114,101, + 32,109,97,107,101,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99, + 111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114,2,17,0,0, + 20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110, + 114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,16,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2, + 10,10,111,110,115,104,111,119,104,105,110,116,7,11,115,104,111,119,104,105, + 110,116,101,120,101,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,104,9,98,111,117,110,100,115,95,99,120,3,171,2, + 9,98,111,117,110,100,115,95,99,121,2,35,7,97,110,99,104,111,114,115, + 11,6,97,110,95,116,111,112,0,8,115,116,97,116,102,105,108,101,7,11, + 112,114,111,106,101,99,116,115,116,97,116,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,13,0,0,15,116,109,101,109,111,100,105,97,108,111, + 103,101,100,105,116,9,97,102,116,101,114,109,97,107,101,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,10,65,102,116,101,114,32,109,97,107, + 101,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116, + 2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101, + 109,115,14,1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 16,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,11,10,111,110, + 115,104,111,119,104,105,110,116,7,11,115,104,111,119,104,105,110,116,101,120, + 101,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,3,184,0,9,98,111,117,110,100,115,95,99,120,3,171,2,9,98,111, + 117,110,100,115,95,99,121,2,35,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,0,8,115,116,97,116,102,105,108,101,7,11,112,114,111, + 106,101,99,116,115,116,97,116,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,13,0,0,9,116,115,116,97,116,102,105,108,101,11,112,114,111, + 106,101,99,116,115,116,97,116,12,111,110,115,116,97,116,117,112,100,97,116, + 101,7,23,112,114,111,106,101,99,116,115,116,97,116,111,110,117,112,100,97, + 116,101,115,116,97,116,17,111,110,115,116,97,116,98,101,102,111,114,101,119, + 114,105,116,101,7,28,112,114,111,106,101,99,116,115,116,97,116,111,110,98, + 101,102,111,114,101,119,114,105,116,101,115,116,97,116,15,111,110,115,116,97, + 116,97,102,116,101,114,114,101,97,100,7,26,112,114,111,106,101,99,116,115, + 116,97,116,111,110,97,102,116,101,114,114,101,97,100,115,116,97,116,4,108, + 101,102,116,3,128,0,3,116,111,112,2,56,0,0,11,116,102,105,108,101, + 100,105,97,108,111,103,16,105,109,112,101,120,112,102,105,108,101,100,105,97, + 108,111,103,8,115,116,97,116,102,105,108,101,7,11,112,114,111,106,101,99, + 116,115,116,97,116,19,99,111,110,116,114,111,108,108,101,114,46,102,105,108, + 101,110,97,109,101,6,11,100,101,102,97,117,108,116,46,99,115,118,26,99, + 111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116, + 46,100,97,116,97,1,1,6,19,68,97,116,97,32,101,120,99,104,97,110, + 103,101,32,102,105,108,101,115,6,5,42,46,99,115,118,0,0,21,99,111, + 110,116,114,111,108,108,101,114,46,100,101,102,97,117,108,116,101,120,116,6, + 3,99,115,118,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116, + 111,114,121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111, + 108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,16,79,112, + 101,110,32,105,109,112,111,114,116,32,102,105,108,101,22,99,111,110,116,114, + 111,108,108,101,114,46,99,97,112,116,105,111,110,115,97,118,101,6,16,83, + 97,118,101,32,101,120,112,111,114,116,32,102,105,108,101,4,108,101,102,116, + 3,240,0,3,116,111,112,2,56,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tprojectfo,''); +end. diff --git a/mseide-msegui/tools/msedirclear.cmd b/mseide-msegui/tools/msedirclear.cmd new file mode 100644 index 0000000..6b29c40 --- /dev/null +++ b/mseide-msegui/tools/msedirclear.cmd @@ -0,0 +1,5 @@ +@echo off +if "%1"=="" @echo A directory must be supplied! & exit -1 +dir /ad %1 +if not %errorlevel% equ 0 (@echo %1 must be an existing directory! & exit -1) +for /R %%F in ("%1") do cd %%F && del *.o 2>nul & del *.ppu 2>nul & del *.a 2>nul & for %%M in (*.mfm) do form2pas %%M diff --git a/mseide-msegui/tools/msedirclear.sh b/mseide-msegui/tools/msedirclear.sh new file mode 100755 index 0000000..f85718d --- /dev/null +++ b/mseide-msegui/tools/msedirclear.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +# Assumes that "/usr/local/bin" contains symlinks to: +# {$mse_dir}/tools/form2pas (shouldn't be renamed!) +# {$mse_dir}/tools/msedirclear.sh (this script) + +[ -z $1 ] && { + echo "A directory must be supplied!" + exit -1 +} + +[ -d $1 ] || { + echo "$1 must be an existing directory!" + exit -1 +} + +DIRS=`for d in \`find $1 -iregex '.*\.\(ppu\|o\|a\|mfm\)' 2>/dev/null\`; +do + tmp=\`dirname $d\` + [ -d $tmp ] && echo -e $tmp +done | sort -ru` + +CURDIR=`pwd` + +for d in $DIRS; do + cd $CURDIR && cd $d 2>/dev/null && { + rm -f -- *.a *.o *.ppu *.A *.O *.PPU + for f in `ls -A1 *.mfm *.MFM 2>/dev/null`; do + [ -f $f ] && form2pas $f + done + } +done + +cd $CURDIR +exit 0 diff --git a/mseide-msegui/tools/unitdep/main.mfm b/mseide-msegui/tools/unitdep/main.mfm new file mode 100644 index 0000000..6353629 --- /dev/null +++ b/mseide-msegui/tools/unitdep/main.mfm @@ -0,0 +1,219 @@ +object mainfo: tmainfo + visible = False + bounds_x = 188 + bounds_y = 220 + bounds_cx = 403 + bounds_cy = 280 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 403 + 280 + ) + statfile = tstatfile1 + caption = 'MSEunitdep' + windowopacity = -Inf + moduleclassname = 'tmainform' + object filename: tfilenameedit + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + hint = 'FPC -vu compiler message file' + bounds_x = 1 + bounds_y = 6 + bounds_cx = 344 + anchors = [an_left, an_top, an_right] + statfile = tstatfile1 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + ondataentered = filenamedatentexe + controller.filterlist.data = ( + ( + 'textfiles' + '*.txt' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + object tbutton1: tbutton + taborder = 1 + bounds_x = 349 + bounds_y = 7 + bounds_cx = 50 + bounds_cy = 19 + anchors = [an_top, an_right] + state = [as_localcaption, as_localonexecute] + caption = '&scan' + onexecute = scanexe + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 1 + bounds_y = 31 + bounds_cx = 401 + bounds_cy = 186 + anchors = [an_left, an_top, an_right, an_bottom] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 1 + captions.items = < + item + end> + end> + datacols.count = 1 + datacols.items = < + item[treeedit] + width = 396 + options = [co_readonly, co_fill, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'treeedit' + dataclass = ttreeitemeditlist + end> + datarowlinewidth = 0 + datarowheight = 16 + reffontheight = 14 + object treeedit: ttreeitemedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 396 + bounds_cy = 16 + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_locate] + options = [teo_treecolnavig] + reffontheight = 14 + end + end + object start: tdropdownlistedit + frame.caption = 'Start Unit' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 1 + bounds_y = 218 + bounds_cx = 198 + bounds_cy = 37 + anchors = [an_left, an_bottom] + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly] + ondataentered = pathdatentexe + ifilink = dropdownunits + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_cliphint] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object dest: tdropdownlistedit + frame.caption = 'Dest. Unit' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 202 + bounds_y = 218 + bounds_cx = 201 + bounds_cy = 37 + anchors = [an_left, an_right, an_bottom] + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly] + ondataentered = pathdatentexe + ifilink = dropdownunits + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_cliphint] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object pathdisp: tmemodialogedit + frame.levelo = -1 + frame.colorclient = -1879048184 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + taborder = 5 + bounds_x = 1 + bounds_y = 259 + bounds_cx = 401 + bounds_cy = 18 + anchors = [an_left, an_right, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_readonlydialog, oe1_savevalue, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object tsplitter1: tsplitter + color = -1879048189 + taborder = 6 + visible = False + bounds_x = 199 + bounds_y = 234 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = start + linkright = dest + end + object tstatfile1: tstatfile + filename = 'mseunitdep.sta' + filedir = '"^/.mseide"' + options = [sfo_createpath, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + left = 16 + top = 8 + end + object dropdownunits: tifidropdownlistlinkcomp + controller.optionsvalue = [vco_nosync] + controller.dropdown.cols.count = 1 + controller.dropdown.cols.items = < + item + end> + left = 32 + top = 72 + end +end diff --git a/mseide-msegui/tools/unitdep/main.pas b/mseide-msegui/tools/unitdep/main.pas new file mode 100644 index 0000000..4767c96 --- /dev/null +++ b/mseide-msegui/tools/unitdep/main.pas @@ -0,0 +1,582 @@ +{ MSEide Copyright (c) 2011-2013 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit main; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msestatfile,msebitmap, + msedataedits,msedatanodes,mseedit,msefiledialog,msegrids,mseifiglob, + mselistbrowser,msestrings,msesys,msetypes,msesimplewidgets,msewidgets, + msewidgetgrid,mselist,classes,mclasses,mseificomp,mseificompglob,msedispwidgets, + msesplitter,msevaluenodes,msememodialog; + +type + tdependencylist = class; + tunitdependencynode = class(trecordtreelistedititem) + private +// frecursion: msestring; + flist: tdependencylist; + fsubitemschecked: boolean; + protected + procedure actionnotification(var ainfo: nodeactioninfoty); override; + public + constructor create(const alist: tdependencylist); + end; + + dependencyinfoty = record + name: string; + depend: string; + checked: boolean; + end; + pdependencyinfoty = ^dependencyinfoty; + dependencyinfoaty = array [0..0] of dependencyinfoty; + pdependencyinfoaty = ^dependencyinfoaty; + + tdependencylist = class(trecordmap) + private + fapplication: string; + protected + function comparename(const l,r): integer; + function comparedep(const l,r): integer; + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + procedure resetchecked(); + public + constructor create; + procedure parse(const afilename: filenamety); +// function gettoplevelnodes: treelistedititemarty; + function getnodes(const aname: string): treelistedititemarty; +// function getdependencytree: ttreelistedititem; + function find(const aname: string; out aindex: integer): pdependencyinfoty; + function finddep(const adepend: string; out aindex: integer): pdependencyinfoty; + function getunitnames: msestringarty; + function findpath(const astart,adest: string): msestringarty; + //dest = '' -> find first start + function finddependnames(const aname: string): msestringarty; + end; + + tmainfo = class(tmainform) + tstatfile1: tstatfile; + filename: tfilenameedit; + tbutton1: tbutton; + grid: twidgetgrid; + treeedit: ttreeitemedit; + dropdownunits: tifidropdownlistlinkcomp; + start: tdropdownlistedit; + dest: tdropdownlistedit; + pathdisp: tmemodialogedit; + tsplitter1: tsplitter; + procedure scanexe(const sender: TObject); + procedure pathdatentexe(const sender: TObject); + procedure filenamedatentexe(const sender: TObject); + private + flist: tdependencylist; + protected + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + end; + +var + mainfo: tmainfo; + +implementation + +uses + main_mfm,msestream,strutils,msedatalist,msearrayutils; +type + ttreelistitem1 = class(ttreelistitem); + +constructor tmainfo.create(aowner: tcomponent); +begin + flist:= tdependencylist.create; + inherited; +end; + +destructor tmainfo.destroy; +begin + inherited; + flist.free; +end; + +procedure tmainfo.scanexe(const sender: TObject); +var +// ar1: treelistedititemarty; + str1,str2: msestring; +begin + flist.parse(filename.value); + with treeedit.itemlist do begin + clear; + add(flist.getnodes(flist.fapplication)); + end; + grid.fixrows[-1].captions[0].caption:= msestring(flist.fapplication); + str1:= start.value; + str2:= dest.value; + dropdownunits.controller.dropdown.cols[0].asarray:= flist.getunitnames; + start.value:= str1; + dest.value:= str2; + pathdatentexe(nil); +end; + +procedure tmainfo.pathdatentexe(const sender: TObject); +begin + if (start.value <> '') or (dest.value <> '') then begin + if dest.value = '' then begin + pathdisp.value:= concatstrings( + flist.finddependnames(ansistring(start.value)),':'); + end + else begin + if start.value = '' then begin + pathdisp.value:= concatstrings( + flist.finddependnames(ansistring(dest.value)),':'); + end + else begin + pathdisp.value:= concatstrings(flist.findpath(ansistring(start.value), + ansistring(dest.value)),','); + end; + end; + end + else begin + pathdisp.value:= ''; + end; +end; + +procedure tmainfo.filenamedatentexe(const sender: TObject); +begin + treeedit.itemlist.clear; + pathdisp.value:= ''; +end; + +{ tdependencylist } + +constructor tdependencylist.create; +begin + inherited create(sizeof(dependencyinfoty), + [rels_needsinitialize,rels_needsfinalize,rels_needscopy]); + setcomparefuncs([@comparename,@comparedep]); +end; + +procedure tdependencylist.finalizerecord(var item); +begin + finalize(dependencyinfoty(item)); +end; + +procedure tdependencylist.copyrecord(var item); +begin + with dependencyinfoty(item) do begin + stringaddref(name); + stringaddref(depend); + end; +end; + +procedure tdependencylist.parse(const afilename: filenamety); +var + stream1: ttextstream; + str1: string; + int1,int2: integer; + info1: dependencyinfoty; + name1{,depend1}: string; + b1: boolean; + i1: int32; +begin + stream1:= ttextstream.create(afilename); + try + clear; + while not stream1.eof do begin + stream1.readln(str1); + if str1 <> '' then begin + if str1[1] = '(' then begin + int1:= pos(')',str1); + if int1 > 0 then begin + name1:= struppercase(copy(str1,2,int1-2)); + if (fapplication = '') and + (name1 <> 'PROGRAM') and (name1 <> 'SYSTEM') then begin + b1:= false; + for i1:= 1 to high(name1) do begin + if (name1[i1] < '0') or (name1[i1] > '9') then begin + b1:= true; + break; + end; + end; + if b1 then begin + fapplication:= name1; + end; + end; + if name1 = fapplication then begin + int2:= posex(' Load from ',str1,int1); + if int2 >= int1+1 then begin + info1.name:= name1; + info1.depend:= copy(str1,findlastchar(str1,' ')+1,bigint); + add(info1); + end; + end + else begin + int2:= posex(' Load from ',str1,int1); + if int2 >= int1+1 then begin + info1.name:= name1; + info1.depend:= copy(str1,findlastchar(str1,' ')+1,bigint); + if stringicomp(info1.name,info1.depend) <> 0 then begin + add(info1); + end; + end + else begin + int2:= posex(' depends on ',str1,int1); //FPC 2.6 + if int2 > 0 then begin + info1.name:= name1; + info1.depend:= copy(str1,int2+12,bigint); + add(info1); + end + else begin + int2:= posex(' Add dependency of ',str1,int1); //FPC 2.4 + if int2 > 0 then begin + info1.name:= name1; + info1.depend:= copy(str1,findlastchar(str1,' ')+1,bigint); + add(info1); + end + end; + end; + end; +// } + end; + end; + end; + end; +// sorted:= true; + finally + stream1.free; + end; +end; + +function tdependencylist.comparename(const l; const r): integer; +begin + with dependencyinfoty(l) do begin + result:= stringcomp(name,dependencyinfoty(r).name); + if result = 0 then begin + result:= stringcomp(depend,dependencyinfoty(r).depend); + end; + end; +end; + +function tdependencylist.comparedep(const l; const r): integer; +begin + with dependencyinfoty(l) do begin + result:= stringcomp(depend,dependencyinfoty(r).depend); + if result = 0 then begin + result:= stringcomp(name,dependencyinfoty(r).name); + end; + end; +end; + +(* +function tdependencylist.getdependencytree: ttreelistedititem; +var + pend: pdependencyinfoty; + + procedure loadnode(const aparent: ttreelistedititem; + start: pdependencyinfoty; + out aend: pdependencyinfoty); + var + str1: string; + mstr1: msestring; + n1: ttreelistitem; + n2: tunitdependencynode; + begin + if start <> nil then begin + n2:= tunitdependencynode.create; + str1:= start^.name; + mstr1:= str1; + n2.caption:= mstr1; + aparent.add(n2); + n1:= aparent; + while (n1 <> nil) and ((n1.caption) <> mstr1) do begin + n1:= n1.parent; + end; + if (n1 <> nil) and (n1.parent <> nil) then begin + n2.frecursion:= n1.parent.caption; + end + else begin + while (start < pend) and (start^.name = str1) do begin + loadnode(n2,find(start^.depend),aend); + inc(start); + end; + end; + end; + aend:= start; + end; + +var + po1: pdependencyinfoty; +begin + result:= ttreelistedititem.create; + po1:= datapo; + pend:= dataend; + repeat + loadnode(result,po1,po1); + until po1 >= pend; +end; +*) + +function tdependencylist.find(const aname: string; + out aindex: integer): pdependencyinfoty; +var + info1: dependencyinfoty; +begin + result:= nil; + info1.name:= aname; + internalfind(0,info1,aindex,result); + if (result <> nil) and (result^.name <> aname) then begin + result:= nil; + end; +end; + +function tdependencylist.finddep(const adepend: string; + out aindex: integer): pdependencyinfoty; +var + info1: dependencyinfoty; +begin + result:= nil; + info1.depend:= adepend; + internalfind(1,info1,aindex,result); + if (result <> nil) and (result^.depend <> adepend) then begin + result:= nil; + end; +end; +{ +function tdependencylist.gettoplevelnodes: treelistedititemarty; +var + count1: integer; + po1: pdependencyinfoty; + n1: tunitdependencynode; + ar1: pointerarty; + int1: integer; +begin + result:= nil; + order:= 0; + find(fapplication,int1); + if int1 >= 0 then begin + count1:= 0; + ar1:= findexes[0]; + while (int1 < fcount) do begin + with pdependencyinfoty(ar1[int1])^ do begin + if name <> fapplication then begin + break; + end; + n1:= tunitdependencynode.create(self); + n1.caption:= depend; + additem(pointerarty(result),pointer(n1),count1); + inc(int1); + end; + end; + setlength(result,count1); + end; +end; +} +function tdependencylist.getnodes(const aname: string): treelistedititemarty; +var + count1: integer; +// po1: pdependencyinfoty; + n1: tunitdependencynode; + ar1: pointerarty; + int1: integer; + dep1: string; +begin + result:= nil; + order:= 0; + find(aname,int1); + if int1 >= 0 then begin + count1:= 0; + ar1:= findexes[0]; + dep1:= ''; + while (int1 < fcount) do begin + with pdependencyinfoty(ar1[int1])^ do begin + if name <> aname then begin + break; + end; + if depend <> dep1 then begin + dep1:= depend; + n1:= tunitdependencynode.create(self); + n1.caption:= msestring(depend); + additem(pointerarty(result),pointer(n1),count1); + end; + inc(int1); + end; + end; + setlength(result,count1); + end; +end; + +function tdependencylist.getunitnames: msestringarty; +var + int1,int2: integer; + str1: string; + ar1: pointerarty; +begin + setlength(result,fcount); //max + int2:= 0; + ar1:= findexes[0]; + str1:= ''; + for int1:= 0 to fcount - 1 do begin + if str1 <> pdependencyinfoty(ar1[int1])^.name then begin + str1:= pdependencyinfoty(ar1[int1])^.name; + result[int2]:= msestring(str1); + inc(int2); + end; + end; + setlength(result,int2); +end; + +function tdependencylist.finddependnames(const aname: string): msestringarty; +var + po1,po2: pdependencyinfoty; + i1,i2: int32; + name1: string; + ar1: msestringarty; +begin + result:= nil; + po1:= finddep(aname,i1); + if po1 <> nil then begin + name1:= ''; + while i1 < count do begin + po1:= findexes[1][i1]; + if po1^.depend <> aname then begin + break; + end; + if po1^.name <> name1 then begin + name1:= po1^.name; + resetchecked(); + ar1:= nil; + po2:= po1; + repeat + additem(ar1,msestring(po2^.depend)); + po2^.checked:= true; + po2:= finddep(po2^.name,i2); + until (po2 = nil) or po2^.checked or (po2^.name = fapplication); + if po2 <> nil then begin + additem(result,concatstrings(ar1,',')); + end; + end; + inc(i1); + end; + end; +end; + +procedure tdependencylist.resetchecked(); +var + po1,po2: pdependencyinfoty; +begin + po1:= datapo; + po2:= dataend; + while po1 < po2 do begin + po1^.checked:= false; + inc(po1); + end; +end; + +function tdependencylist.findpath(const astart: string; + const adest: string): msestringarty; +var + destar1: stringarty; + maxlevel: integer; + maxlevelfound: boolean; + + function find1(const aname: string; const alevel: integer): boolean; + var +// po1: pdependencyinfoty; + int1: integer; +// str1: string; + begin + result:= aname = adest; + if not result then begin + if find(aname,int1) <> nil then begin + if alevel > maxlevel then begin + maxlevelfound:= true; + exit; + end; + while int1 < fcount do begin + with pdependencyinfoty(findexes[0][int1])^ do begin + if (name <> aname) or checked then begin + break; + end; + checked:= true; + result:= find1(depend,alevel+1); + if result then begin + break; + end; + inc(int1); + end; + end; + end; + end; + if result then begin + additem(destar1,aname); + end; + end; +var + int1,int2: integer; +begin + result:= nil; + maxlevel:= 0; + repeat + resetchecked(); + maxlevelfound:= false; + if find1(astart,0) then begin + setlength(result,length(destar1)); + int2:= 0; + for int1:= high(destar1) downto 0 do begin + result[int2]:= msestring(destar1[int1]); + inc(int2); + end; + break; + end; + inc(maxlevel); + until not maxlevelfound; +end; + +{ tunitdependencynode } + +constructor tunitdependencynode.create(const alist: tdependencylist); +begin + flist:= alist; + inherited create; + include(fstate,ns_subitems); +end; + +procedure tunitdependencynode.actionnotification(var ainfo: nodeactioninfoty); +var + int1: integer; + n1,n2: ttreelistitem; +begin + if (ainfo.action = na_expand) and not fsubitemschecked then begin + fsubitemschecked:= true; + add(flist.getnodes(ansistring(caption))); + for int1:= 0 to fcount - 1 do begin + n1:= fitems[int1]; + n2:= n1.parent; + while n2 <> nil do begin + if n2.caption = n1.caption then begin + exclude(tunitdependencynode(n1).fstate,ns_subitems); //recursive + break; + end; + n2:= n2.parent; + end; + end; + end; + inherited; +end; + +end. diff --git a/mseide-msegui/tools/unitdep/main_mfm.pas b/mseide-msegui/tools/unitdep/main_mfm.pas new file mode 100644 index 0000000..89cafa9 --- /dev/null +++ b/mseide-msegui/tools/unitdep/main_mfm.pas @@ -0,0 +1,247 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..4585] of byte end = + (size: 4586; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,188,0, + 8,98,111,117,110,100,115,95,121,3,220,0,9,98,111,117,110,100,115,95, + 99,120,3,147,1,9,98,111,117,110,100,115,95,99,121,3,24,1,26,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99,111, + 110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3, + 147,1,3,24,1,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116, + 97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6,10,77,83,69, + 117,110,105,116,100,101,112,13,119,105,110,100,111,119,111,112,97,99,105,116, + 121,5,0,0,0,0,0,0,0,128,255,255,15,109,111,100,117,108,101,99, + 108,97,115,115,110,97,109,101,6,9,116,109,97,105,110,102,111,114,109,0, + 13,116,102,105,108,101,110,97,109,101,101,100,105,116,8,102,105,108,101,110, + 97,109,101,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117, + 110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105, + 116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109, + 97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116, + 111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46, + 98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,4,104,105,110, + 116,6,29,70,80,67,32,45,118,117,32,99,111,109,112,105,108,101,114,32, + 109,101,115,115,97,103,101,32,102,105,108,101,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100, + 115,95,99,120,3,88,1,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116, + 0,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108, + 101,49,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116, + 102,95,101,108,108,105,112,115,101,108,101,102,116,0,13,111,110,100,97,116, + 97,101,110,116,101,114,101,100,7,17,102,105,108,101,110,97,109,101,100,97, + 116,101,110,116,101,120,101,26,99,111,110,116,114,111,108,108,101,114,46,102, + 105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,9,116,101, + 120,116,102,105,108,101,115,6,5,42,46,116,120,116,0,0,18,99,111,110, + 116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,14,102,100,111, + 95,99,104,101,99,107,101,120,105,115,116,15,102,100,111,95,115,97,118,101, + 108,97,115,116,100,105,114,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116, + 111,110,49,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,3,93,1,8,98,111,117,110,100,115,95,121,2,7,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 19,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,5,38, + 115,99,97,110,9,111,110,101,120,101,99,117,116,101,7,7,115,99,97,110, + 101,120,101,0,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114, + 105,100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,31,9,98,111,117,110,100, + 115,95,99,120,3,145,1,9,98,111,117,110,100,115,95,99,121,3,186,0, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116, + 116,111,109,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1, + 13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105, + 103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116, + 2,1,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,0, + 0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1, + 14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,116,114, + 101,101,101,100,105,116,1,5,119,105,100,116,104,3,140,1,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,7,99,111, + 95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,8,116,114,101,101,101,100,105,116,9,100,97,116,97,99,108,97,115, + 115,7,17,116,116,114,101,101,105,116,101,109,101,100,105,116,108,105,115,116, + 0,0,16,100,97,116,97,114,111,119,108,105,110,101,119,105,100,116,104,2, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,13,116,116,114,101,101, + 105,116,101,109,101,100,105,116,8,116,114,101,101,101,100,105,116,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,140, + 1,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110, + 115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100, + 111,110,108,121,9,111,101,95,108,111,99,97,116,101,0,7,111,112,116,105, + 111,110,115,11,16,116,101,111,95,116,114,101,101,99,111,108,110,97,118,105, + 103,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,17,116,100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,5, + 115,116,97,114,116,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 10,83,116,97,114,116,32,85,110,105,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,18,102,114,97,109,101,46,98,117,116, + 116,111,110,46,99,111,108,111,114,4,2,0,0,128,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99, + 111,108,111,114,4,2,0,0,128,0,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116, + 97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,1, + 8,98,111,117,110,100,115,95,121,3,218,0,9,98,111,117,110,100,115,95, + 99,120,3,198,0,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111, + 116,116,111,109,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97, + 116,102,105,108,101,49,11,111,112,116,105,111,110,115,101,100,105,116,11,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,24,111, + 101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118,97, + 108,117,101,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100, + 111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116, + 111,110,114,101,97,100,111,110,108,121,0,13,111,110,100,97,116,97,101,110, + 116,101,114,101,100,7,13,112,97,116,104,100,97,116,101,110,116,101,120,101, + 7,105,102,105,108,105,110,107,7,13,100,114,111,112,100,111,119,110,117,110, + 105,116,115,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115, + 11,14,100,101,111,95,115,101,108,101,99,116,111,110,108,121,16,100,101,111, + 95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101, + 121,100,114,111,112,100,111,119,110,12,100,101,111,95,99,108,105,112,104,105, + 110,116,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111, + 117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46, + 105,116,101,109,115,14,1,0,0,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,17,116,100,114,111,112,100,111,119,110,108,105,115, + 116,101,100,105,116,4,100,101,115,116,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,10,68,101,115,116,46,32,85,110,105,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,102,114,97,109, + 101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,5,99,111,108,111,114,4,2,0,0,128,0,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100, + 115,95,120,3,202,0,8,98,111,117,110,100,115,95,121,3,218,0,9,98, + 111,117,110,100,115,95,99,120,3,201,0,9,98,111,117,110,100,115,95,99, + 121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0, + 8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101, + 49,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,24,111,101,95,102,111,114, + 99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97, + 100,111,110,108,121,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100, + 7,13,112,97,116,104,100,97,116,101,110,116,101,120,101,7,105,102,105,108, + 105,110,107,7,13,100,114,111,112,100,111,119,110,117,110,105,116,115,16,100, + 114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,14,100,101,111, + 95,115,101,108,101,99,116,111,110,108,121,16,100,101,111,95,97,117,116,111, + 100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121,100,114,111,112, + 100,111,119,110,12,100,101,111,95,99,108,105,112,104,105,110,116,0,19,100, + 114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1, + 19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115, + 14,1,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100,105,116,8,112, + 97,116,104,100,105,115,112,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,8,0,0,144,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103, + 101,110,114,2,17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110, + 46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2, + 5,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,3,3,1,9,98,111,117,110,100,115,95,99,120,3,145,1,9,98,111, + 117,110,100,115,95,99,121,2,18,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,18,111,101,49,95,114,101, + 97,100,111,110,108,121,100,105,97,108,111,103,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 27,111,101,49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114, + 115,116,97,116,114,101,97,100,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111,101, + 95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121, + 18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116, + 115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116,101,114,49,5, + 99,111,108,111,114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2, + 6,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3, + 199,0,8,98,111,117,110,100,115,95,121,3,234,0,9,98,111,117,110,100, + 115,95,99,120,2,3,9,98,111,117,110,100,115,95,99,121,2,20,7,111, + 112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111,112,12,115,112, + 111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100,111,99,107,116, + 111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116,14,115,112,111, + 95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110,107,108,101,102, + 116,7,5,115,116,97,114,116,9,108,105,110,107,114,105,103,104,116,7,4, + 100,101,115,116,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116, + 97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,14,109,115, + 101,117,110,105,116,100,101,112,46,115,116,97,7,102,105,108,101,100,105,114, + 6,11,34,94,47,46,109,115,101,105,100,101,34,7,111,112,116,105,111,110, + 115,11,14,115,102,111,95,99,114,101,97,116,101,112,97,116,104,15,115,102, + 111,95,116,114,97,110,115,97,99,116,105,111,110,17,115,102,111,95,97,99, + 116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95,97,99,116,105, + 118,97,116,111,114,119,114,105,116,101,0,4,108,101,102,116,2,16,3,116, + 111,112,2,8,0,0,24,116,105,102,105,100,114,111,112,100,111,119,110,108, + 105,115,116,108,105,110,107,99,111,109,112,13,100,114,111,112,100,111,119,110, + 117,110,105,116,115,23,99,111,110,116,114,111,108,108,101,114,46,111,112,116, + 105,111,110,115,118,97,108,117,101,11,10,118,99,111,95,110,111,115,121,110, + 99,0,30,99,111,110,116,114,111,108,108,101,114,46,100,114,111,112,100,111, + 119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,30,99,111,110,116, + 114,111,108,108,101,114,46,100,114,111,112,100,111,119,110,46,99,111,108,115, + 46,105,116,101,109,115,14,1,0,0,4,108,101,102,116,2,32,3,116,111, + 112,2,72,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/tools/unitdep/mseunitdep.pas b/mseide-msegui/tools/unitdep/mseunitdep.pas new file mode 100644 index 0000000..b4e0f64 --- /dev/null +++ b/mseide-msegui/tools/unitdep/mseunitdep.pas @@ -0,0 +1,28 @@ +{ MSEtools Copyright (c) 2011-2014 by Martin Schreiber + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program mseunitdep; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef FPC} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} + msegui,mseforms,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/tools/unitdep/mseunitdep.prj b/mseide-msegui/tools/unitdep/mseunitdep.prj new file mode 100644 index 0000000..281f9b4 --- /dev/null +++ b/mseide-msegui/tools/unitdep/mseunitdep.prj @@ -0,0 +1,1120 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +[projectoptions] +projectdir=/f:/proj/mseide-msegui/tools/unitdep +projectfilename=/f:/proj/mseide-msegui/tools/unitdep/mseunitdep.prj +options=110 + [projectoptionsfo.toolshortcuts] + dropdowncolwidths=3 + 70 + 70 + 70 + [projectoptionsfo.twidgetgrid3] + propcolwidthref=726 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + width4=97 + sortdescend4=0 + width5=78 + sortdescend5=0 + width6=50 + sortdescend6=0 + width7=50 + sortdescend7=0 + width8=101 + sortdescend8=0 + width9=296 + sortdescend9=0 + [projectoptionsfo.twidgetgrid4] + propcolwidthref=550 + width0=96 + sortdescend0=0 + sortdescend1=0 + width2=73 + sortdescend2=0 + width3=263 + sortdescend3=0 + width4=277 + sortdescend4=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=15 + [projectoptionsfo.newfile] + firsttab=0 + index=0 + [projectoptionsfo.fontaliasgrid] + propcolwidthref=389 + width0=98 + sortdescend0=0 + width1=378 + sortdescend1=0 + width2=50 + sortdescend2=0 + width3=50 + sortdescend3=0 + width4=50 + sortdescend4=0 + width5=50 + sortdescend5=0 + width6=70 + sortdescend6=0 + [projectoptionsfo.macrosplitter] + x=0 + y=121 + xprop=1 + yprop=0.23846153846154 + [projectoptionsfo.macrogrid] + propcolwidthref=533 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + width6=146 + sortdescend6=0 + width7=521 + sortdescend7=0 + [projectoptionsfo.makegroupbox] + firsttab=0 + index=1 + [projectoptionsfo.exceptionsgrid] + propcolwidthref=710 + width0=47 + sortdescend0=0 + width1=704 + sortdescend1=0 + [projectoptionsfo.ttabwidget1] + firsttab=0 + index=0 + [projectoptionsfo.grid] + propcolwidthref=511 + width0=219 + sortdescend0=0 + width1=504 + sortdescend1=0 + [projectoptionsfo.filefiltergrid] + propcolwidthref=618 + width0=112 + sortdescend0=0 + width1=611 + sortdescend1=0 + [projectoptionsfo.ttabwidget2] + firsttab=0 + index=0 + [projectoptionsfo.tabwidget] + firsttab=0 + index=2 + [projectoptionsfo] + stackedunder= + x=19 + y=122 + cx=759 + cy=568 +mainfile=${projectname}.pas +targetfile=${projectname}${exeext} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -gh + -B + -OG2p3 -XX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=1 + MAINFO +moduletypes=1 + TMAINFO +modulefiles=1 + /f:/proj/mseide-msegui/tools/unitdep/main.mfm +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 65599 + 196671 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/f:/proj/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=1 + 0,0 +bookmarks0=0 +sourcefiles=1 + /f:/proj/mseide-msegui/tools/unitdep/main.pas +relpaths=1 + main.pas +ismoduletexts=1 + 0 +modules=1 + /f:/proj/mseide-msegui/tools/unitdep/main.mfm +moduleoptions=1 + 0 +visiblemodules=1 + -1 +nomenumodules=1 + 0 +[sourcefo.tabwidget] +tabsize=134 +firsttab=0 +index=0 +[layout] +windowlayout=552 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=3 + /home/mse/packs/standard/git/mseide-msegui/tools/unitdep/main.pas + /home/mse/packs/standard/git/mseide-msegui/tools/form2pas.pas + /home/mse/packs/standard/git/mseide-msegui/tools/bmp2pas.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=15 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=30 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=16507 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=188 + y=220 + cx=413 + cy=280 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/tools/valgrind/fixes_3_0.supp b/mseide-msegui/tools/valgrind/fixes_3_0.supp new file mode 100644 index 0000000..96b9577 --- /dev/null +++ b/mseide-msegui/tools/valgrind/fixes_3_0.supp @@ -0,0 +1,21 @@ +{ + + Memcheck:Addr4 + fun:SYSUTILS_$$_STRSCAN$PCHAR$CHAR$$PCHAR +} +{ + + Memcheck:Addr4 + fun:SYSTEM_$$_INDEXBYTE$formal$LONGINT$BYTE$$LONGINT +} +{ + + Memcheck:Cond + fun:XcursorImageHash + fun:XcursorNoticePutBitmap + fun:_XNoticePutBitmap + fun:XPutImage + fun:MSEGUIINTF_$$_GUI_IMAGETOPIXMAP$IMAGETY$LONGWORD$LONGWORD$$GDIERRORTY +} + + diff --git a/mseide-msegui/tools/valgrind/fixes_3_0_64.supp b/mseide-msegui/tools/valgrind/fixes_3_0_64.supp new file mode 100644 index 0000000..667da3a --- /dev/null +++ b/mseide-msegui/tools/valgrind/fixes_3_0_64.supp @@ -0,0 +1,20 @@ +{ + + Memcheck:Addr4 + fun:SYSUTILS_$$_STRSCAN$PCHAR$CHAR$$PCHAR +} +{ + + Memcheck:Addr16 + fun:SYSTEM_$$_INDEXBYTE$formal$INT64$BYTE$$INT64 +} +{ + + Memcheck:Cond + fun:XcursorImageHash + fun:XcursorNoticePutBitmap + fun:XPutImage + fun:MSEGUIINTF_$$_GUI_IMAGETOPIXMAP$IMAGETY$QWORD$LONGWORD$$GDIERRORTY +} + + diff --git a/mseide-msegui/tools/xft2gs/README.TXT b/mseide-msegui/tools/xft2gs/README.TXT new file mode 100644 index 0000000..5e2c6fa --- /dev/null +++ b/mseide-msegui/tools/xft2gs/README.TXT @@ -0,0 +1,4 @@ +2008-01-07 mse + +xft2gs has been moved to +https://msedocumenting.svn.sourceforge.net/svnroot/msedocumenting/mse/trunk/tools/xft2gs diff --git a/pacmanxg b/pacmanxg deleted file mode 100755 index 2cd9727..0000000 Binary files a/pacmanxg and /dev/null differ